diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..13c1b4c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,122 @@ +cmake_minimum_required(VERSION 2.8.12) +project(p2pool) + +option(STATIC_LINUX_BINARY "Build static Linux binary" OFF) + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") + +add_subdirectory(external/src/randomx) +set(LIBS randomx) + +include(cmake/flags.cmake) + +set(HEADERS + external/src/cryptonote/crypto-ops.h + external/src/llhttp/llhttp.h + src/block_template.h + src/common.h + src/console_commands.h + src/crypto.h + src/json_parsers.h + src/json_rpc_request.h + src/keccak.h + src/log.h + src/mempool.h + src/p2p_server.h + src/p2pool.h + src/params.h + src/pool_block.h + src/pool_block_parser.inl + src/pow_hash.h + src/side_chain.h + src/stratum_server.h + src/tcp_server.h + src/tcp_server.inl + src/util.h + src/uv_util.h + src/wallet.h + src/zmq_reader.h +) + +set(SOURCES + external/src/cryptonote/crypto-ops-data.c + external/src/cryptonote/crypto-ops.c + external/src/llhttp/api.c + external/src/llhttp/http.c + external/src/llhttp/llhttp.c + src/block_template.cpp + src/console_commands.cpp + src/crypto.cpp + src/json_rpc_request.cpp + src/keccak.cpp + src/log.cpp + src/main.cpp + src/mempool.cpp + src/p2p_server.cpp + src/p2pool.cpp + src/params.cpp + src/pool_block.cpp + src/pow_hash.cpp + src/side_chain.cpp + src/stratum_server.cpp + src/util.cpp + src/wallet.cpp + src/zmq_reader.cpp +) + +include_directories(src) +include_directories(external/src) +include_directories(external/src/cryptonote) +include_directories(external/src/libuv/include) +include_directories(external/src/cppzmq) +include_directories(external/src/libzmq/include) +include_directories(external/src/llhttp) +include_directories(external/src/randomx/src) + +if (WIN32) + set(LIBS ${LIBS} ws2_32 iphlpapi userenv psapi) +else() + set(LIBS ${LIBS} pthread) +endif() + +if (CMAKE_CXX_COMPILER_ID MATCHES MSVC) + find_library(ZMQ_LIBRARY_DEBUG NAMES libzmq-v142-mt-sgd-4_3_5 PATHS "external/lib/libzmq/Debug") + find_library(ZMQ_LIBRARY NAMES libzmq-v142-mt-s-4_3_5 PATHS "external/lib/libzmq/Release") + find_library(UV_LIBRARY_DEBUG NAMES uv_a PATHS "external/lib/libuv/Debug") + find_library(UV_LIBRARY NAMES uv_a PATHS "external/lib/libuv/Release") +elseif (CMAKE_CXX_COMPILER_ID MATCHES GNU) + find_library(ZMQ_LIBRARY_DEBUG NAMES libzmq libzmq.a) + find_library(ZMQ_LIBRARY NAMES libzmq libzmq.a) + find_library(UV_LIBRARY_DEBUG NAMES libuv libuv.a) + find_library(UV_LIBRARY NAMES libuv libuv.a) + set(LIBS ${LIBS} sodium) +endif() + +find_library(PGM_LIBRARY pgm) +find_library(NORM_LIBRARY norm) + +if (PGM_LIBRARY) + set(LIBS ${LIBS} ${PGM_LIBRARY}) +endif() + +if (NORM_LIBRARY) + set(LIBS ${LIBS} ${NORM_LIBRARY}) +endif() + +add_definitions(/DZMQ_STATIC) + +add_executable(${CMAKE_PROJECT_NAME} ${HEADERS} ${SOURCES}) + +if (STATIC_LINUX_BINARY) + add_custom_command(TARGET ${CMAKE_PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_STRIP} ${CMAKE_PROJECT_NAME}) + + target_link_libraries(${CMAKE_PROJECT_NAME} + "${CMAKE_SOURCE_DIR}/external/src/libsodium/src/libsodium/.libs/libsodium.a" + "${CMAKE_SOURCE_DIR}/external/src/libzmq/build/lib/libzmq.a" + "${CMAKE_SOURCE_DIR}/external/src/libuv/build/libuv_a.a" + randomx + pthread + ) +else() + target_link_libraries(${CMAKE_PROJECT_NAME} debug ${ZMQ_LIBRARY_DEBUG} debug ${UV_LIBRARY_DEBUG} optimized ${ZMQ_LIBRARY} optimized ${UV_LIBRARY} ${LIBS}) +endif() diff --git a/README.md b/README.md new file mode 100644 index 0000000..b32c0d4 --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# Monero P2Pool + +Decentralized pool for Monero mining. + +**NOTE** This is a highly experimental and untested software. I did some extensive testing locally, but there's zero guarantee it will work for you! It requires a custom monerod version and a specially configured Monero wallet (for now). No binaries or usage instructions are provided yet. Testing on testnet will start soon! No ETA on the official release date, but hopefully before the end of September 2021. + +## Features + +* Decentralized: no central server that can be shutdown/blocked. P2Pool uses a separate blockchain to merge mine with Monero. Pool admin can't go rogue or be pressured to do an attack on the network because there is no pool admin! +* Permissionless: there is no one to decide who can mine on the pool and who can't. +* Trustless: there is no pool wallet, funds are never in custody. All pool blocks pay out to miners immediately. +* PPLNS payout scheme +* **0% fee** +* **0 XMR payout fee** +* **Less than 0.0005 XMR minimal payout** +* Fast block times, down to 1 second +* Uncle blocks are supported to avoid orphans - all your shares will be accounted for! +* Configurable PPLNS window size and block time +* Advanced mempool picking algorithm, it creates blocks with better reward than what monerod solo mining does +* Password protected private pools + +## How PPLNS works in P2Pool + +First you need to find a pool share. This share will stay in PPLNS window for 2160 pool blocks (6 hours). The moment P2Pool finds a Monero block and you have at least 1 pool share in PPLNS window, you'll get a payout! Monero block reward is split between all miner wallets in PPLNS window. Each miner gets a part of block reward proportional to the total difficulty of his/her shares in PPLNS window. + +**NOTE** If P2Pool doesn't have enough hashrate to find Monero blocks faster than every 6 hours on average (~15 MH/s), not all pool shares will result in a payout. But in the long run, your payouts will average out to what you'd get with regular pool mining. + +## Default P2Pool parameters + +* Block time: 10 seconds +* PPLNS window: 2160 blocks (6 hours) +* Minimum payout = Monero block reward/2160, currently ~0.0004 XMR + +## Build instructions + +SOON + +## Usage + +SOON + +## Donations + +If you'd like to support further development of Monero P2Pool, you're welcome to send any amount of XMR to the following address: + +``` +44MnN1f3Eto8DZYUWuE5XZNUtE3vcRzt2j6PzqWpPau34e6Cf4fAxt6X2MBmrm6F9YMEiMNjN6W4Shn4pLcfNAja621jwyg +``` diff --git a/cmake/flags.cmake b/cmake/flags.cmake new file mode 100644 index 0000000..1b4436f --- /dev/null +++ b/cmake/flags.cmake @@ -0,0 +1,52 @@ +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_STANDARD 14) + +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED ON) + +if (CMAKE_CXX_COMPILER_ID MATCHES GNU) + set(WARNING_FLAGS "-Wall -Wextra -Werror") + set(OPTIMIZATION_FLAGS "-Ofast -s") + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS}") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${WARNING_FLAGS} ${OPTIMIZATION_FLAGS}") + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${WARNING_FLAGS} ${OPTIMIZATION_FLAGS}") + + if (WIN32) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") + else() + if (STATIC_LINUX_BINARY) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") + else() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") + endif() + endif() +elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC) + set(WARNING_FLAGS "/Wall /WX /sdl") + set(SECURITY_FLAGS "/GS /guard:cf") + set(OPTIMIZATION_FLAGS "/O2 /Oi /Ob2 /Ot /DNDEBUG /GL") + + set(CMAKE_C_FLAGS_DEBUG "${WARNING_FLAGS} ${SECURITY_FLAGS} /Od /Ob0 /Zi /MTd /fsanitize=address") + set(CMAKE_CXX_FLAGS_DEBUG "${WARNING_FLAGS} ${SECURITY_FLAGS} /Od /Ob0 /Zi /MTd /fsanitize=address") + + set(CMAKE_C_FLAGS_RELEASE "${WARNING_FLAGS} ${SECURITY_FLAGS} ${OPTIMIZATION_FLAGS} /MT") + set(CMAKE_CXX_FLAGS_RELEASE "${WARNING_FLAGS} ${SECURITY_FLAGS} ${OPTIMIZATION_FLAGS} /MT") + + set(CMAKE_C_FLAGS_RELWITHDEBINFO "${WARNING_FLAGS} ${SECURITY_FLAGS} /Ob1 /Ot /Zi /MT") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${WARNING_FLAGS} ${SECURITY_FLAGS} /Ob1 /Ot /Zi /MT") + +elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang) + set(WARNING_FLAGS "-Wall -Wextra -Werror") + set(OPTIMIZATION_FLAGS "-Ofast -funroll-loops -fmerge-all-constants") + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS}") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${WARNING_FLAGS} ${OPTIMIZATION_FLAGS}") + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${WARNING_FLAGS} ${OPTIMIZATION_FLAGS}") + + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") +endif() diff --git a/config.json b/config.json new file mode 100644 index 0000000..394b7dc --- /dev/null +++ b/config.json @@ -0,0 +1,8 @@ +{ + "name": "default", + "password": "", + "block_time": 10, + "min_diff": 10000, + "pplns_window": 2160, + "uncle_penalty": 20 +} \ No newline at end of file diff --git a/external/lib/libuv/Debug/uv_a.lib b/external/lib/libuv/Debug/uv_a.lib new file mode 100644 index 0000000..21ab7a1 Binary files /dev/null and b/external/lib/libuv/Debug/uv_a.lib differ diff --git a/external/lib/libuv/Debug/uv_a.pdb b/external/lib/libuv/Debug/uv_a.pdb new file mode 100644 index 0000000..892f4a6 Binary files /dev/null and b/external/lib/libuv/Debug/uv_a.pdb differ diff --git a/external/lib/libuv/Release/uv_a.lib b/external/lib/libuv/Release/uv_a.lib new file mode 100644 index 0000000..1636b16 Binary files /dev/null and b/external/lib/libuv/Release/uv_a.lib differ diff --git a/external/lib/libzmq/Debug/libzmq-v142-mt-sgd-4_3_5.lib b/external/lib/libzmq/Debug/libzmq-v142-mt-sgd-4_3_5.lib new file mode 100644 index 0000000..2bf1e2c Binary files /dev/null and b/external/lib/libzmq/Debug/libzmq-v142-mt-sgd-4_3_5.lib differ diff --git a/external/lib/libzmq/Debug/libzmq-v142-mt-sgd-4_3_5.pdb b/external/lib/libzmq/Debug/libzmq-v142-mt-sgd-4_3_5.pdb new file mode 100644 index 0000000..86b91e2 Binary files /dev/null and b/external/lib/libzmq/Debug/libzmq-v142-mt-sgd-4_3_5.pdb differ diff --git a/external/lib/libzmq/Release/libzmq-v142-mt-s-4_3_5.lib b/external/lib/libzmq/Release/libzmq-v142-mt-s-4_3_5.lib new file mode 100644 index 0000000..a88d84a Binary files /dev/null and b/external/lib/libzmq/Release/libzmq-v142-mt-s-4_3_5.lib differ diff --git a/external/src/cppzmq/LICENSE b/external/src/cppzmq/LICENSE new file mode 100644 index 0000000..ae98bd8 --- /dev/null +++ b/external/src/cppzmq/LICENSE @@ -0,0 +1,17 @@ + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. diff --git a/external/src/cppzmq/zmq.hpp b/external/src/cppzmq/zmq.hpp new file mode 100644 index 0000000..39ca13c --- /dev/null +++ b/external/src/cppzmq/zmq.hpp @@ -0,0 +1,2694 @@ +/* + Copyright (c) 2016-2017 ZeroMQ community + Copyright (c) 2009-2011 250bpm s.r.o. + Copyright (c) 2011 Botond Ballo + Copyright (c) 2007-2009 iMatix Corporation + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#ifndef __ZMQ_HPP_INCLUDED__ +#define __ZMQ_HPP_INCLUDED__ + +#ifdef _WIN32 +#ifndef NOMINMAX +#define NOMINMAX +#endif +#endif + +// included here for _HAS_CXX* macros +#include + +#if defined(_MSVC_LANG) +#define CPPZMQ_LANG _MSVC_LANG +#else +#define CPPZMQ_LANG __cplusplus +#endif +// overwrite if specific language macros indicate higher version +#if defined(_HAS_CXX14) && _HAS_CXX14 && CPPZMQ_LANG < 201402L +#undef CPPZMQ_LANG +#define CPPZMQ_LANG 201402L +#endif +#if defined(_HAS_CXX17) && _HAS_CXX17 && CPPZMQ_LANG < 201703L +#undef CPPZMQ_LANG +#define CPPZMQ_LANG 201703L +#endif + +// macros defined if has a specific standard or greater +#if CPPZMQ_LANG >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1900) +#define ZMQ_CPP11 +#endif +#if CPPZMQ_LANG >= 201402L +#define ZMQ_CPP14 +#endif +#if CPPZMQ_LANG >= 201703L +#define ZMQ_CPP17 +#endif + +#if defined(ZMQ_CPP14) && !defined(_MSC_VER) +#define ZMQ_DEPRECATED(msg) [[deprecated(msg)]] +#elif defined(_MSC_VER) +#define ZMQ_DEPRECATED(msg) __declspec(deprecated(msg)) +#elif defined(__GNUC__) +#define ZMQ_DEPRECATED(msg) __attribute__((deprecated(msg))) +#endif + +#if defined(ZMQ_CPP17) +#define ZMQ_NODISCARD [[nodiscard]] +#else +#define ZMQ_NODISCARD +#endif + +#if defined(ZMQ_CPP11) +#define ZMQ_NOTHROW noexcept +#define ZMQ_EXPLICIT explicit +#define ZMQ_OVERRIDE override +#define ZMQ_NULLPTR nullptr +#define ZMQ_CONSTEXPR_FN constexpr +#define ZMQ_CONSTEXPR_VAR constexpr +#define ZMQ_CPP11_DEPRECATED(msg) ZMQ_DEPRECATED(msg) +#else +#define ZMQ_NOTHROW throw() +#define ZMQ_EXPLICIT +#define ZMQ_OVERRIDE +#define ZMQ_NULLPTR 0 +#define ZMQ_CONSTEXPR_FN +#define ZMQ_CONSTEXPR_VAR const +#define ZMQ_CPP11_DEPRECATED(msg) +#endif +#if defined(ZMQ_CPP14) && (!defined(_MSC_VER) || _MSC_VER > 1900) +#define ZMQ_EXTENDED_CONSTEXPR +#endif +#if defined(ZMQ_CPP17) +#define ZMQ_INLINE_VAR inline +#define ZMQ_CONSTEXPR_IF constexpr +#else +#define ZMQ_INLINE_VAR +#define ZMQ_CONSTEXPR_IF +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#ifdef ZMQ_CPP11 +#include +#include +#include +#include +#endif + +#if defined(__has_include) && defined(ZMQ_CPP17) +#define CPPZMQ_HAS_INCLUDE_CPP17(X) __has_include(X) +#else +#define CPPZMQ_HAS_INCLUDE_CPP17(X) 0 +#endif + +#if CPPZMQ_HAS_INCLUDE_CPP17() && !defined(CPPZMQ_HAS_OPTIONAL) +#define CPPZMQ_HAS_OPTIONAL 1 +#endif +#ifndef CPPZMQ_HAS_OPTIONAL +#define CPPZMQ_HAS_OPTIONAL 0 +#elif CPPZMQ_HAS_OPTIONAL +#include +#endif + +#if CPPZMQ_HAS_INCLUDE_CPP17() && !defined(CPPZMQ_HAS_STRING_VIEW) +#define CPPZMQ_HAS_STRING_VIEW 1 +#endif +#ifndef CPPZMQ_HAS_STRING_VIEW +#define CPPZMQ_HAS_STRING_VIEW 0 +#elif CPPZMQ_HAS_STRING_VIEW +#include +#endif + +/* Version macros for compile-time API version detection */ +#define CPPZMQ_VERSION_MAJOR 4 +#define CPPZMQ_VERSION_MINOR 8 +#define CPPZMQ_VERSION_PATCH 0 + +#define CPPZMQ_VERSION \ + ZMQ_MAKE_VERSION(CPPZMQ_VERSION_MAJOR, CPPZMQ_VERSION_MINOR, \ + CPPZMQ_VERSION_PATCH) + +// Detect whether the compiler supports C++11 rvalue references. +#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 2)) \ + && defined(__GXX_EXPERIMENTAL_CXX0X__)) +#define ZMQ_HAS_RVALUE_REFS +#define ZMQ_DELETED_FUNCTION = delete +#elif defined(__clang__) +#if __has_feature(cxx_rvalue_references) +#define ZMQ_HAS_RVALUE_REFS +#endif + +#if __has_feature(cxx_deleted_functions) +#define ZMQ_DELETED_FUNCTION = delete +#else +#define ZMQ_DELETED_FUNCTION +#endif +#elif defined(_MSC_VER) && (_MSC_VER >= 1900) +#define ZMQ_HAS_RVALUE_REFS +#define ZMQ_DELETED_FUNCTION = delete +#elif defined(_MSC_VER) && (_MSC_VER >= 1600) +#define ZMQ_HAS_RVALUE_REFS +#define ZMQ_DELETED_FUNCTION +#else +#define ZMQ_DELETED_FUNCTION +#endif + +#if defined(ZMQ_CPP11) && !defined(__llvm__) && !defined(__INTEL_COMPILER) \ + && defined(__GNUC__) && __GNUC__ < 5 +#define ZMQ_CPP11_PARTIAL +#elif defined(__GLIBCXX__) && __GLIBCXX__ < 20160805 +//the date here is the last date of gcc 4.9.4, which +// effectively means libstdc++ from gcc 5.5 and higher won't trigger this branch +#define ZMQ_CPP11_PARTIAL +#endif + +#ifdef ZMQ_CPP11 +#ifdef ZMQ_CPP11_PARTIAL +#define ZMQ_IS_TRIVIALLY_COPYABLE(T) __has_trivial_copy(T) +#else +#include +#define ZMQ_IS_TRIVIALLY_COPYABLE(T) std::is_trivially_copyable::value +#endif +#endif + +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3, 3, 0) +#define ZMQ_NEW_MONITOR_EVENT_LAYOUT +#endif + +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 1, 0) +#define ZMQ_HAS_PROXY_STEERABLE +/* Socket event data */ +typedef struct +{ + uint16_t event; // id of the event as bitfield + int32_t value; // value is either error code, fd or reconnect interval +} zmq_event_t; +#endif + +// Avoid using deprecated message receive function when possible +#if ZMQ_VERSION < ZMQ_MAKE_VERSION(3, 2, 0) +#define zmq_msg_recv(msg, socket, flags) zmq_recvmsg(socket, msg, flags) +#endif + + +// In order to prevent unused variable warnings when building in non-debug +// mode use this macro to make assertions. +#ifndef NDEBUG +#define ZMQ_ASSERT(expression) assert(expression) +#else +#define ZMQ_ASSERT(expression) (void) (expression) +#endif + +namespace zmq +{ +#ifdef ZMQ_CPP11 +namespace detail +{ +namespace ranges +{ +using std::begin; +using std::end; +template auto begin(T &&r) -> decltype(begin(std::forward(r))) +{ + return begin(std::forward(r)); +} +template auto end(T &&r) -> decltype(end(std::forward(r))) +{ + return end(std::forward(r)); +} +} // namespace ranges + +template using void_t = void; + +template +using iter_value_t = typename std::iterator_traits::value_type; + +template +using range_iter_t = decltype( + ranges::begin(std::declval::type &>())); + +template using range_value_t = iter_value_t>; + +template struct is_range : std::false_type +{ +}; + +template +struct is_range< + T, + void_t::type &>()) + == ranges::end(std::declval::type &>()))>> + : std::true_type +{ +}; + +} // namespace detail +#endif + +typedef zmq_free_fn free_fn; +typedef zmq_pollitem_t pollitem_t; + +// duplicate definition from libzmq 4.3.3 +#if defined _WIN32 +#if defined _WIN64 +typedef unsigned __int64 fd_t; +#else +typedef unsigned int fd_t; +#endif +#else +typedef int fd_t; +#endif + +class error_t : public std::exception +{ + public: + error_t() ZMQ_NOTHROW : errnum(zmq_errno()) {} + explicit error_t(int err) ZMQ_NOTHROW : errnum(err) {} + virtual const char *what() const ZMQ_NOTHROW ZMQ_OVERRIDE + { + return zmq_strerror(errnum); + } + int num() const ZMQ_NOTHROW { return errnum; } + + private: + int errnum; +}; + +inline int poll(zmq_pollitem_t *items_, size_t nitems_, long timeout_ = -1) +{ + int rc = zmq_poll(items_, static_cast(nitems_), timeout_); + if (rc < 0) + throw error_t(); + return rc; +} + +ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items") +inline int poll(zmq_pollitem_t const *items_, size_t nitems_, long timeout_ = -1) +{ + return poll(const_cast(items_), nitems_, timeout_); +} + +#ifdef ZMQ_CPP11 +ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items") +inline int +poll(zmq_pollitem_t const *items, size_t nitems, std::chrono::milliseconds timeout) +{ + return poll(const_cast(items), nitems, + static_cast(timeout.count())); +} + +ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items") +inline int poll(std::vector const &items, + std::chrono::milliseconds timeout) +{ + return poll(const_cast(items.data()), items.size(), + static_cast(timeout.count())); +} + +ZMQ_DEPRECATED("from 4.3.1, use poll taking non-const items") +inline int poll(std::vector const &items, long timeout_ = -1) +{ + return poll(const_cast(items.data()), items.size(), timeout_); +} + +inline int +poll(zmq_pollitem_t *items, size_t nitems, std::chrono::milliseconds timeout) +{ + return poll(items, nitems, static_cast(timeout.count())); +} + +inline int poll(std::vector &items, + std::chrono::milliseconds timeout) +{ + return poll(items.data(), items.size(), static_cast(timeout.count())); +} + +ZMQ_DEPRECATED("from 4.3.1, use poll taking std::chrono instead of long") +inline int poll(std::vector &items, long timeout_ = -1) +{ + return poll(items.data(), items.size(), timeout_); +} + +template +inline int poll(std::array &items, + std::chrono::milliseconds timeout) +{ + return poll(items.data(), items.size(), static_cast(timeout.count())); +} +#endif + + +inline void version(int *major_, int *minor_, int *patch_) +{ + zmq_version(major_, minor_, patch_); +} + +#ifdef ZMQ_CPP11 +inline std::tuple version() +{ + std::tuple v; + zmq_version(&std::get<0>(v), &std::get<1>(v), &std::get<2>(v)); + return v; +} + +#if !defined(ZMQ_CPP11_PARTIAL) +namespace detail +{ +template struct is_char_type +{ + // true if character type for string literals in C++11 + static constexpr bool value = + std::is_same::value || std::is_same::value + || std::is_same::value || std::is_same::value; +}; +} +#endif + +#endif + +class message_t +{ + public: + message_t() ZMQ_NOTHROW + { + int rc = zmq_msg_init(&msg); + ZMQ_ASSERT(rc == 0); + } + + explicit message_t(size_t size_) + { + int rc = zmq_msg_init_size(&msg, size_); + if (rc != 0) + throw error_t(); + } + + template message_t(ForwardIter first, ForwardIter last) + { + typedef typename std::iterator_traits::value_type value_t; + + assert(std::distance(first, last) >= 0); + size_t const size_ = + static_cast(std::distance(first, last)) * sizeof(value_t); + int const rc = zmq_msg_init_size(&msg, size_); + if (rc != 0) + throw error_t(); + std::copy(first, last, data()); + } + + message_t(const void *data_, size_t size_) + { + int rc = zmq_msg_init_size(&msg, size_); + if (rc != 0) + throw error_t(); + if (size_) { + // this constructor allows (nullptr, 0), + // memcpy with a null pointer is UB + memcpy(data(), data_, size_); + } + } + + message_t(void *data_, size_t size_, free_fn *ffn_, void *hint_ = ZMQ_NULLPTR) + { + int rc = zmq_msg_init_data(&msg, data_, size_, ffn_, hint_); + if (rc != 0) + throw error_t(); + } + + // overload set of string-like types and generic containers +#if defined(ZMQ_CPP11) && !defined(ZMQ_CPP11_PARTIAL) + // NOTE this constructor will include the null terminator + // when called with a string literal. + // An overload taking const char* can not be added because + // it would be preferred over this function and break compatiblity. + template< + class Char, + size_t N, + typename = typename std::enable_if::value>::type> + ZMQ_DEPRECATED("from 4.7.0, use constructors taking iterators, (pointer, size) " + "or strings instead") + explicit message_t(const Char (&data)[N]) : + message_t(detail::ranges::begin(data), detail::ranges::end(data)) + { + } + + template::value + && ZMQ_IS_TRIVIALLY_COPYABLE(detail::range_value_t) + && !detail::is_char_type>::value + && !std::is_same::value>::type> + explicit message_t(const Range &rng) : + message_t(detail::ranges::begin(rng), detail::ranges::end(rng)) + { + } + + explicit message_t(const std::string &str) : message_t(str.data(), str.size()) {} + +#if CPPZMQ_HAS_STRING_VIEW + explicit message_t(std::string_view str) : message_t(str.data(), str.size()) {} +#endif + +#endif + +#ifdef ZMQ_HAS_RVALUE_REFS + message_t(message_t &&rhs) ZMQ_NOTHROW : msg(rhs.msg) + { + int rc = zmq_msg_init(&rhs.msg); + ZMQ_ASSERT(rc == 0); + } + + message_t &operator=(message_t &&rhs) ZMQ_NOTHROW + { + std::swap(msg, rhs.msg); + return *this; + } +#endif + + ~message_t() ZMQ_NOTHROW + { + int rc = zmq_msg_close(&msg); + ZMQ_ASSERT(rc == 0); + } + + void rebuild() + { + int rc = zmq_msg_close(&msg); + if (rc != 0) + throw error_t(); + rc = zmq_msg_init(&msg); + ZMQ_ASSERT(rc == 0); + } + + void rebuild(size_t size_) + { + int rc = zmq_msg_close(&msg); + if (rc != 0) + throw error_t(); + rc = zmq_msg_init_size(&msg, size_); + if (rc != 0) + throw error_t(); + } + + void rebuild(const void *data_, size_t size_) + { + int rc = zmq_msg_close(&msg); + if (rc != 0) + throw error_t(); + rc = zmq_msg_init_size(&msg, size_); + if (rc != 0) + throw error_t(); + memcpy(data(), data_, size_); + } + + void rebuild(void *data_, size_t size_, free_fn *ffn_, void *hint_ = ZMQ_NULLPTR) + { + int rc = zmq_msg_close(&msg); + if (rc != 0) + throw error_t(); + rc = zmq_msg_init_data(&msg, data_, size_, ffn_, hint_); + if (rc != 0) + throw error_t(); + } + + ZMQ_DEPRECATED("from 4.3.1, use move taking non-const reference instead") + void move(message_t const *msg_) + { + int rc = zmq_msg_move(&msg, const_cast(msg_->handle())); + if (rc != 0) + throw error_t(); + } + + void move(message_t &msg_) + { + int rc = zmq_msg_move(&msg, msg_.handle()); + if (rc != 0) + throw error_t(); + } + + ZMQ_DEPRECATED("from 4.3.1, use copy taking non-const reference instead") + void copy(message_t const *msg_) + { + int rc = zmq_msg_copy(&msg, const_cast(msg_->handle())); + if (rc != 0) + throw error_t(); + } + + void copy(message_t &msg_) + { + int rc = zmq_msg_copy(&msg, msg_.handle()); + if (rc != 0) + throw error_t(); + } + + bool more() const ZMQ_NOTHROW + { + int rc = zmq_msg_more(const_cast(&msg)); + return rc != 0; + } + + void *data() ZMQ_NOTHROW { return zmq_msg_data(&msg); } + + const void *data() const ZMQ_NOTHROW + { + return zmq_msg_data(const_cast(&msg)); + } + + size_t size() const ZMQ_NOTHROW + { + return zmq_msg_size(const_cast(&msg)); + } + + ZMQ_NODISCARD bool empty() const ZMQ_NOTHROW { return size() == 0u; } + + template T *data() ZMQ_NOTHROW { return static_cast(data()); } + + template T const *data() const ZMQ_NOTHROW + { + return static_cast(data()); + } + + ZMQ_DEPRECATED("from 4.3.0, use operator== instead") + bool equal(const message_t *other) const ZMQ_NOTHROW { return *this == *other; } + + bool operator==(const message_t &other) const ZMQ_NOTHROW + { + const size_t my_size = size(); + return my_size == other.size() && 0 == memcmp(data(), other.data(), my_size); + } + + bool operator!=(const message_t &other) const ZMQ_NOTHROW + { + return !(*this == other); + } + +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(3, 2, 0) + int get(int property_) + { + int value = zmq_msg_get(&msg, property_); + if (value == -1) + throw error_t(); + return value; + } +#endif + +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 1, 0) + const char *gets(const char *property_) + { + const char *value = zmq_msg_gets(&msg, property_); + if (value == ZMQ_NULLPTR) + throw error_t(); + return value; + } +#endif + +#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0) + uint32_t routing_id() const + { + return zmq_msg_routing_id(const_cast(&msg)); + } + + void set_routing_id(uint32_t routing_id) + { + int rc = zmq_msg_set_routing_id(&msg, routing_id); + if (rc != 0) + throw error_t(); + } + + const char *group() const + { + return zmq_msg_group(const_cast(&msg)); + } + + void set_group(const char *group) + { + int rc = zmq_msg_set_group(&msg, group); + if (rc != 0) + throw error_t(); + } +#endif + + // interpret message content as a string + std::string to_string() const + { + return std::string(static_cast(data()), size()); + } +#if CPPZMQ_HAS_STRING_VIEW + // interpret message content as a string + std::string_view to_string_view() const noexcept + { + return std::string_view(static_cast(data()), size()); + } +#endif + + /** Dump content to string for debugging. + * Ascii chars are readable, the rest is printed as hex. + * Probably ridiculously slow. + * Use to_string() or to_string_view() for + * interpreting the message as a string. + */ + std::string str() const + { + // Partly mutuated from the same method in zmq::multipart_t + std::stringstream os; + + const unsigned char *msg_data = this->data(); + unsigned char byte; + size_t size = this->size(); + int is_ascii[2] = {0, 0}; + + os << "zmq::message_t [size " << std::dec << std::setw(3) + << std::setfill('0') << size << "] ("; + // Totally arbitrary + if (size >= 1000) { + os << "... too big to print)"; + } else { + while (size--) { + byte = *msg_data++; + + is_ascii[1] = (byte >= 32 && byte < 127); + if (is_ascii[1] != is_ascii[0]) + os << " "; // Separate text/non text + + if (is_ascii[1]) { + os << byte; + } else { + os << std::hex << std::uppercase << std::setw(2) + << std::setfill('0') << static_cast(byte); + } + is_ascii[0] = is_ascii[1]; + } + os << ")"; + } + return os.str(); + } + + void swap(message_t &other) ZMQ_NOTHROW + { + // this assumes zmq::msg_t from libzmq is trivially relocatable + std::swap(msg, other.msg); + } + + ZMQ_NODISCARD zmq_msg_t *handle() ZMQ_NOTHROW { return &msg; } + ZMQ_NODISCARD const zmq_msg_t *handle() const ZMQ_NOTHROW { return &msg; } + + private: + // The underlying message + zmq_msg_t msg; + + // Disable implicit message copying, so that users won't use shared + // messages (less efficient) without being aware of the fact. + message_t(const message_t &) ZMQ_DELETED_FUNCTION; + void operator=(const message_t &) ZMQ_DELETED_FUNCTION; +}; + +inline void swap(message_t &a, message_t &b) ZMQ_NOTHROW +{ + a.swap(b); +} + +#ifdef ZMQ_CPP11 +enum class ctxopt +{ +#ifdef ZMQ_BLOCKY + blocky = ZMQ_BLOCKY, +#endif +#ifdef ZMQ_IO_THREADS + io_threads = ZMQ_IO_THREADS, +#endif +#ifdef ZMQ_THREAD_SCHED_POLICY + thread_sched_policy = ZMQ_THREAD_SCHED_POLICY, +#endif +#ifdef ZMQ_THREAD_PRIORITY + thread_priority = ZMQ_THREAD_PRIORITY, +#endif +#ifdef ZMQ_THREAD_AFFINITY_CPU_ADD + thread_affinity_cpu_add = ZMQ_THREAD_AFFINITY_CPU_ADD, +#endif +#ifdef ZMQ_THREAD_AFFINITY_CPU_REMOVE + thread_affinity_cpu_remove = ZMQ_THREAD_AFFINITY_CPU_REMOVE, +#endif +#ifdef ZMQ_THREAD_NAME_PREFIX + thread_name_prefix = ZMQ_THREAD_NAME_PREFIX, +#endif +#ifdef ZMQ_MAX_MSGSZ + max_msgsz = ZMQ_MAX_MSGSZ, +#endif +#ifdef ZMQ_ZERO_COPY_RECV + zero_copy_recv = ZMQ_ZERO_COPY_RECV, +#endif +#ifdef ZMQ_MAX_SOCKETS + max_sockets = ZMQ_MAX_SOCKETS, +#endif +#ifdef ZMQ_SOCKET_LIMIT + socket_limit = ZMQ_SOCKET_LIMIT, +#endif +#ifdef ZMQ_IPV6 + ipv6 = ZMQ_IPV6, +#endif +#ifdef ZMQ_MSG_T_SIZE + msg_t_size = ZMQ_MSG_T_SIZE +#endif +}; +#endif + +class context_t +{ + public: + context_t() + { + ptr = zmq_ctx_new(); + if (ptr == ZMQ_NULLPTR) + throw error_t(); + } + + + explicit context_t(int io_threads_, int max_sockets_ = ZMQ_MAX_SOCKETS_DFLT) + { + ptr = zmq_ctx_new(); + if (ptr == ZMQ_NULLPTR) + throw error_t(); + + int rc = zmq_ctx_set(ptr, ZMQ_IO_THREADS, io_threads_); + ZMQ_ASSERT(rc == 0); + + rc = zmq_ctx_set(ptr, ZMQ_MAX_SOCKETS, max_sockets_); + ZMQ_ASSERT(rc == 0); + } + +#ifdef ZMQ_HAS_RVALUE_REFS + context_t(context_t &&rhs) ZMQ_NOTHROW : ptr(rhs.ptr) { rhs.ptr = ZMQ_NULLPTR; } + context_t &operator=(context_t &&rhs) ZMQ_NOTHROW + { + close(); + std::swap(ptr, rhs.ptr); + return *this; + } +#endif + + ~context_t() ZMQ_NOTHROW { close(); } + + ZMQ_CPP11_DEPRECATED("from 4.7.0, use set taking zmq::ctxopt instead") + int setctxopt(int option_, int optval_) + { + int rc = zmq_ctx_set(ptr, option_, optval_); + ZMQ_ASSERT(rc == 0); + return rc; + } + + ZMQ_CPP11_DEPRECATED("from 4.7.0, use get taking zmq::ctxopt instead") + int getctxopt(int option_) { return zmq_ctx_get(ptr, option_); } + +#ifdef ZMQ_CPP11 + void set(ctxopt option, int optval) + { + int rc = zmq_ctx_set(ptr, static_cast(option), optval); + if (rc == -1) + throw error_t(); + } + + ZMQ_NODISCARD int get(ctxopt option) + { + int rc = zmq_ctx_get(ptr, static_cast(option)); + // some options have a default value of -1 + // which is unfortunate, and may result in errors + // that don't make sense + if (rc == -1) + throw error_t(); + return rc; + } +#endif + + // Terminates context (see also shutdown()). + void close() ZMQ_NOTHROW + { + if (ptr == ZMQ_NULLPTR) + return; + + int rc; + do { + rc = zmq_ctx_term(ptr); + } while (rc == -1 && errno == EINTR); + + ZMQ_ASSERT(rc == 0); + ptr = ZMQ_NULLPTR; + } + + // Shutdown context in preparation for termination (close()). + // Causes all blocking socket operations and any further + // socket operations to return with ETERM. + void shutdown() ZMQ_NOTHROW + { + if (ptr == ZMQ_NULLPTR) + return; + int rc = zmq_ctx_shutdown(ptr); + ZMQ_ASSERT(rc == 0); + } + + // Be careful with this, it's probably only useful for + // using the C api together with an existing C++ api. + // Normally you should never need to use this. + ZMQ_EXPLICIT operator void *() ZMQ_NOTHROW { return ptr; } + + ZMQ_EXPLICIT operator void const *() const ZMQ_NOTHROW { return ptr; } + + ZMQ_NODISCARD void *handle() ZMQ_NOTHROW { return ptr; } + + ZMQ_DEPRECATED("from 4.7.0, use handle() != nullptr instead") + operator bool() const ZMQ_NOTHROW { return ptr != ZMQ_NULLPTR; } + + void swap(context_t &other) ZMQ_NOTHROW { std::swap(ptr, other.ptr); } + + private: + void *ptr; + + context_t(const context_t &) ZMQ_DELETED_FUNCTION; + void operator=(const context_t &) ZMQ_DELETED_FUNCTION; +}; + +inline void swap(context_t &a, context_t &b) ZMQ_NOTHROW +{ + a.swap(b); +} + +#ifdef ZMQ_CPP11 + +struct recv_buffer_size +{ + size_t size; // number of bytes written to buffer + size_t untruncated_size; // untruncated message size in bytes + + ZMQ_NODISCARD bool truncated() const noexcept + { + return size != untruncated_size; + } +}; + +#if CPPZMQ_HAS_OPTIONAL + +using send_result_t = std::optional; +using recv_result_t = std::optional; +using recv_buffer_result_t = std::optional; + +#else + +namespace detail +{ +// A C++11 type emulating the most basic +// operations of std::optional for trivial types +template class trivial_optional +{ + public: + static_assert(std::is_trivial::value, "T must be trivial"); + using value_type = T; + + trivial_optional() = default; + trivial_optional(T value) noexcept : _value(value), _has_value(true) {} + + const T *operator->() const noexcept + { + assert(_has_value); + return &_value; + } + T *operator->() noexcept + { + assert(_has_value); + return &_value; + } + + const T &operator*() const noexcept + { + assert(_has_value); + return _value; + } + T &operator*() noexcept + { + assert(_has_value); + return _value; + } + + T &value() + { + if (!_has_value) + throw std::exception(); + return _value; + } + const T &value() const + { + if (!_has_value) + throw std::exception(); + return _value; + } + + explicit operator bool() const noexcept { return _has_value; } + bool has_value() const noexcept { return _has_value; } + + private: + T _value{}; + bool _has_value{false}; +}; +} // namespace detail + +using send_result_t = detail::trivial_optional; +using recv_result_t = detail::trivial_optional; +using recv_buffer_result_t = detail::trivial_optional; + +#endif + +namespace detail +{ +template constexpr T enum_bit_or(T a, T b) noexcept +{ + static_assert(std::is_enum::value, "must be enum"); + using U = typename std::underlying_type::type; + return static_cast(static_cast(a) | static_cast(b)); +} +template constexpr T enum_bit_and(T a, T b) noexcept +{ + static_assert(std::is_enum::value, "must be enum"); + using U = typename std::underlying_type::type; + return static_cast(static_cast(a) & static_cast(b)); +} +template constexpr T enum_bit_xor(T a, T b) noexcept +{ + static_assert(std::is_enum::value, "must be enum"); + using U = typename std::underlying_type::type; + return static_cast(static_cast(a) ^ static_cast(b)); +} +template constexpr T enum_bit_not(T a) noexcept +{ + static_assert(std::is_enum::value, "must be enum"); + using U = typename std::underlying_type::type; + return static_cast(~static_cast(a)); +} +} // namespace detail + +// partially satisfies named requirement BitmaskType +enum class send_flags : int +{ + none = 0, + dontwait = ZMQ_DONTWAIT, + sndmore = ZMQ_SNDMORE +}; + +constexpr send_flags operator|(send_flags a, send_flags b) noexcept +{ + return detail::enum_bit_or(a, b); +} +constexpr send_flags operator&(send_flags a, send_flags b) noexcept +{ + return detail::enum_bit_and(a, b); +} +constexpr send_flags operator^(send_flags a, send_flags b) noexcept +{ + return detail::enum_bit_xor(a, b); +} +constexpr send_flags operator~(send_flags a) noexcept +{ + return detail::enum_bit_not(a); +} + +// partially satisfies named requirement BitmaskType +enum class recv_flags : int +{ + none = 0, + dontwait = ZMQ_DONTWAIT +}; + +constexpr recv_flags operator|(recv_flags a, recv_flags b) noexcept +{ + return detail::enum_bit_or(a, b); +} +constexpr recv_flags operator&(recv_flags a, recv_flags b) noexcept +{ + return detail::enum_bit_and(a, b); +} +constexpr recv_flags operator^(recv_flags a, recv_flags b) noexcept +{ + return detail::enum_bit_xor(a, b); +} +constexpr recv_flags operator~(recv_flags a) noexcept +{ + return detail::enum_bit_not(a); +} + + +// mutable_buffer, const_buffer and buffer are based on +// the Networking TS specification, draft: +// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/n4771.pdf + +class mutable_buffer +{ + public: + constexpr mutable_buffer() noexcept : _data(nullptr), _size(0) {} + constexpr mutable_buffer(void *p, size_t n) noexcept : _data(p), _size(n) + { +#ifdef ZMQ_EXTENDED_CONSTEXPR + assert(p != nullptr || n == 0); +#endif + } + + constexpr void *data() const noexcept { return _data; } + constexpr size_t size() const noexcept { return _size; } + mutable_buffer &operator+=(size_t n) noexcept + { + // (std::min) is a workaround for when a min macro is defined + const auto shift = (std::min)(n, _size); + _data = static_cast(_data) + shift; + _size -= shift; + return *this; + } + + private: + void *_data; + size_t _size; +}; + +inline mutable_buffer operator+(const mutable_buffer &mb, size_t n) noexcept +{ + return mutable_buffer(static_cast(mb.data()) + (std::min)(n, mb.size()), + mb.size() - (std::min)(n, mb.size())); +} +inline mutable_buffer operator+(size_t n, const mutable_buffer &mb) noexcept +{ + return mb + n; +} + +class const_buffer +{ + public: + constexpr const_buffer() noexcept : _data(nullptr), _size(0) {} + constexpr const_buffer(const void *p, size_t n) noexcept : _data(p), _size(n) + { +#ifdef ZMQ_EXTENDED_CONSTEXPR + assert(p != nullptr || n == 0); +#endif + } + constexpr const_buffer(const mutable_buffer &mb) noexcept : + _data(mb.data()), _size(mb.size()) + { + } + + constexpr const void *data() const noexcept { return _data; } + constexpr size_t size() const noexcept { return _size; } + const_buffer &operator+=(size_t n) noexcept + { + const auto shift = (std::min)(n, _size); + _data = static_cast(_data) + shift; + _size -= shift; + return *this; + } + + private: + const void *_data; + size_t _size; +}; + +inline const_buffer operator+(const const_buffer &cb, size_t n) noexcept +{ + return const_buffer(static_cast(cb.data()) + + (std::min)(n, cb.size()), + cb.size() - (std::min)(n, cb.size())); +} +inline const_buffer operator+(size_t n, const const_buffer &cb) noexcept +{ + return cb + n; +} + +// buffer creation + +constexpr mutable_buffer buffer(void *p, size_t n) noexcept +{ + return mutable_buffer(p, n); +} +constexpr const_buffer buffer(const void *p, size_t n) noexcept +{ + return const_buffer(p, n); +} +constexpr mutable_buffer buffer(const mutable_buffer &mb) noexcept +{ + return mb; +} +inline mutable_buffer buffer(const mutable_buffer &mb, size_t n) noexcept +{ + return mutable_buffer(mb.data(), (std::min)(mb.size(), n)); +} +constexpr const_buffer buffer(const const_buffer &cb) noexcept +{ + return cb; +} +inline const_buffer buffer(const const_buffer &cb, size_t n) noexcept +{ + return const_buffer(cb.data(), (std::min)(cb.size(), n)); +} + +namespace detail +{ +template struct is_buffer +{ + static constexpr bool value = + std::is_same::value || std::is_same::value; +}; + +template struct is_pod_like +{ + // NOTE: The networking draft N4771 section 16.11 requires + // T in the buffer functions below to be + // trivially copyable OR standard layout. + // Here we decide to be conservative and require both. + static constexpr bool value = + ZMQ_IS_TRIVIALLY_COPYABLE(T) && std::is_standard_layout::value; +}; + +template constexpr auto seq_size(const C &c) noexcept -> decltype(c.size()) +{ + return c.size(); +} +template +constexpr size_t seq_size(const T (&/*array*/)[N]) noexcept +{ + return N; +} + +template +auto buffer_contiguous_sequence(Seq &&seq) noexcept + -> decltype(buffer(std::addressof(*std::begin(seq)), size_t{})) +{ + using T = typename std::remove_cv< + typename std::remove_reference::type>::type; + static_assert(detail::is_pod_like::value, "T must be POD"); + + const auto size = seq_size(seq); + return buffer(size != 0u ? std::addressof(*std::begin(seq)) : nullptr, + size * sizeof(T)); +} +template +auto buffer_contiguous_sequence(Seq &&seq, size_t n_bytes) noexcept + -> decltype(buffer_contiguous_sequence(seq)) +{ + using T = typename std::remove_cv< + typename std::remove_reference::type>::type; + static_assert(detail::is_pod_like::value, "T must be POD"); + + const auto size = seq_size(seq); + return buffer(size != 0u ? std::addressof(*std::begin(seq)) : nullptr, + (std::min)(size * sizeof(T), n_bytes)); +} + +} // namespace detail + +// C array +template mutable_buffer buffer(T (&data)[N]) noexcept +{ + return detail::buffer_contiguous_sequence(data); +} +template +mutable_buffer buffer(T (&data)[N], size_t n_bytes) noexcept +{ + return detail::buffer_contiguous_sequence(data, n_bytes); +} +template const_buffer buffer(const T (&data)[N]) noexcept +{ + return detail::buffer_contiguous_sequence(data); +} +template +const_buffer buffer(const T (&data)[N], size_t n_bytes) noexcept +{ + return detail::buffer_contiguous_sequence(data, n_bytes); +} +// std::array +template mutable_buffer buffer(std::array &data) noexcept +{ + return detail::buffer_contiguous_sequence(data); +} +template +mutable_buffer buffer(std::array &data, size_t n_bytes) noexcept +{ + return detail::buffer_contiguous_sequence(data, n_bytes); +} +template +const_buffer buffer(std::array &data) noexcept +{ + return detail::buffer_contiguous_sequence(data); +} +template +const_buffer buffer(std::array &data, size_t n_bytes) noexcept +{ + return detail::buffer_contiguous_sequence(data, n_bytes); +} +template +const_buffer buffer(const std::array &data) noexcept +{ + return detail::buffer_contiguous_sequence(data); +} +template +const_buffer buffer(const std::array &data, size_t n_bytes) noexcept +{ + return detail::buffer_contiguous_sequence(data, n_bytes); +} +// std::vector +template +mutable_buffer buffer(std::vector &data) noexcept +{ + return detail::buffer_contiguous_sequence(data); +} +template +mutable_buffer buffer(std::vector &data, size_t n_bytes) noexcept +{ + return detail::buffer_contiguous_sequence(data, n_bytes); +} +template +const_buffer buffer(const std::vector &data) noexcept +{ + return detail::buffer_contiguous_sequence(data); +} +template +const_buffer buffer(const std::vector &data, size_t n_bytes) noexcept +{ + return detail::buffer_contiguous_sequence(data, n_bytes); +} +// std::basic_string +template +mutable_buffer buffer(std::basic_string &data) noexcept +{ + return detail::buffer_contiguous_sequence(data); +} +template +mutable_buffer buffer(std::basic_string &data, + size_t n_bytes) noexcept +{ + return detail::buffer_contiguous_sequence(data, n_bytes); +} +template +const_buffer buffer(const std::basic_string &data) noexcept +{ + return detail::buffer_contiguous_sequence(data); +} +template +const_buffer buffer(const std::basic_string &data, + size_t n_bytes) noexcept +{ + return detail::buffer_contiguous_sequence(data, n_bytes); +} + +#if CPPZMQ_HAS_STRING_VIEW +// std::basic_string_view +template +const_buffer buffer(std::basic_string_view data) noexcept +{ + return detail::buffer_contiguous_sequence(data); +} +template +const_buffer buffer(std::basic_string_view data, size_t n_bytes) noexcept +{ + return detail::buffer_contiguous_sequence(data, n_bytes); +} +#endif + +// Buffer for a string literal (null terminated) +// where the buffer size excludes the terminating character. +// Equivalent to zmq::buffer(std::string_view("...")). +template +constexpr const_buffer str_buffer(const Char (&data)[N]) noexcept +{ + static_assert(detail::is_pod_like::value, "Char must be POD"); +#ifdef ZMQ_EXTENDED_CONSTEXPR + assert(data[N - 1] == Char{0}); +#endif + return const_buffer(static_cast(data), (N - 1) * sizeof(Char)); +} + +namespace literals +{ +constexpr const_buffer operator"" _zbuf(const char *str, size_t len) noexcept +{ + return const_buffer(str, len * sizeof(char)); +} +constexpr const_buffer operator"" _zbuf(const wchar_t *str, size_t len) noexcept +{ + return const_buffer(str, len * sizeof(wchar_t)); +} +constexpr const_buffer operator"" _zbuf(const char16_t *str, size_t len) noexcept +{ + return const_buffer(str, len * sizeof(char16_t)); +} +constexpr const_buffer operator"" _zbuf(const char32_t *str, size_t len) noexcept +{ + return const_buffer(str, len * sizeof(char32_t)); +} +} + +namespace sockopt +{ +// There are two types of options, +// integral type with known compiler time size (int, bool, int64_t, uint64_t) +// and arrays with dynamic size (strings, binary data). + +// BoolUnit: if true accepts values of type bool (but passed as T into libzmq) +template struct integral_option +{ +}; + +// NullTerm: +// 0: binary data +// 1: null-terminated string (`getsockopt` size includes null) +// 2: binary (size 32) or Z85 encoder string of size 41 (null included) +template struct array_option +{ +}; + +#define ZMQ_DEFINE_INTEGRAL_OPT(OPT, NAME, TYPE) \ + using NAME##_t = integral_option; \ + ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME {} +#define ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(OPT, NAME, TYPE) \ + using NAME##_t = integral_option; \ + ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME {} +#define ZMQ_DEFINE_ARRAY_OPT(OPT, NAME) \ + using NAME##_t = array_option; \ + ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME {} +#define ZMQ_DEFINE_ARRAY_OPT_BINARY(OPT, NAME) \ + using NAME##_t = array_option; \ + ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME {} +#define ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(OPT, NAME) \ + using NAME##_t = array_option; \ + ZMQ_INLINE_VAR ZMQ_CONSTEXPR_VAR NAME##_t NAME {} + +// deprecated, use zmq::fd_t +using cppzmq_fd_t = ::zmq::fd_t; + +#ifdef ZMQ_AFFINITY +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_AFFINITY, affinity, uint64_t); +#endif +#ifdef ZMQ_BACKLOG +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_BACKLOG, backlog, int); +#endif +#ifdef ZMQ_BINDTODEVICE +ZMQ_DEFINE_ARRAY_OPT_BINARY(ZMQ_BINDTODEVICE, bindtodevice); +#endif +#ifdef ZMQ_CONFLATE +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_CONFLATE, conflate, int); +#endif +#ifdef ZMQ_CONNECT_ROUTING_ID +ZMQ_DEFINE_ARRAY_OPT(ZMQ_CONNECT_ROUTING_ID, connect_routing_id); +#endif +#ifdef ZMQ_CONNECT_TIMEOUT +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_CONNECT_TIMEOUT, connect_timeout, int); +#endif +#ifdef ZMQ_CURVE_PUBLICKEY +ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(ZMQ_CURVE_PUBLICKEY, curve_publickey); +#endif +#ifdef ZMQ_CURVE_SECRETKEY +ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(ZMQ_CURVE_SECRETKEY, curve_secretkey); +#endif +#ifdef ZMQ_CURVE_SERVER +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_CURVE_SERVER, curve_server, int); +#endif +#ifdef ZMQ_CURVE_SERVERKEY +ZMQ_DEFINE_ARRAY_OPT_BIN_OR_Z85(ZMQ_CURVE_SERVERKEY, curve_serverkey); +#endif +#ifdef ZMQ_EVENTS +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_EVENTS, events, int); +#endif +#ifdef ZMQ_FD +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_FD, fd, ::zmq::fd_t); +#endif +#ifdef ZMQ_GSSAPI_PLAINTEXT +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_GSSAPI_PLAINTEXT, gssapi_plaintext, int); +#endif +#ifdef ZMQ_GSSAPI_SERVER +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_GSSAPI_SERVER, gssapi_server, int); +#endif +#ifdef ZMQ_GSSAPI_SERVICE_PRINCIPAL +ZMQ_DEFINE_ARRAY_OPT(ZMQ_GSSAPI_SERVICE_PRINCIPAL, gssapi_service_principal); +#endif +#ifdef ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_GSSAPI_SERVICE_PRINCIPAL_NAMETYPE, + gssapi_service_principal_nametype, + int); +#endif +#ifdef ZMQ_GSSAPI_PRINCIPAL +ZMQ_DEFINE_ARRAY_OPT(ZMQ_GSSAPI_PRINCIPAL, gssapi_principal); +#endif +#ifdef ZMQ_GSSAPI_PRINCIPAL_NAMETYPE +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_GSSAPI_PRINCIPAL_NAMETYPE, + gssapi_principal_nametype, + int); +#endif +#ifdef ZMQ_HANDSHAKE_IVL +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HANDSHAKE_IVL, handshake_ivl, int); +#endif +#ifdef ZMQ_HEARTBEAT_IVL +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HEARTBEAT_IVL, heartbeat_ivl, int); +#endif +#ifdef ZMQ_HEARTBEAT_TIMEOUT +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HEARTBEAT_TIMEOUT, heartbeat_timeout, int); +#endif +#ifdef ZMQ_HEARTBEAT_TTL +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_HEARTBEAT_TTL, heartbeat_ttl, int); +#endif +#ifdef ZMQ_IMMEDIATE +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_IMMEDIATE, immediate, int); +#endif +#ifdef ZMQ_INVERT_MATCHING +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_INVERT_MATCHING, invert_matching, int); +#endif +#ifdef ZMQ_IPV6 +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_IPV6, ipv6, int); +#endif +#ifdef ZMQ_LAST_ENDPOINT +ZMQ_DEFINE_ARRAY_OPT(ZMQ_LAST_ENDPOINT, last_endpoint); +#endif +#ifdef ZMQ_LINGER +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_LINGER, linger, int); +#endif +#ifdef ZMQ_MAXMSGSIZE +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MAXMSGSIZE, maxmsgsize, int64_t); +#endif +#ifdef ZMQ_MECHANISM +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MECHANISM, mechanism, int); +#endif +#ifdef ZMQ_METADATA +ZMQ_DEFINE_ARRAY_OPT(ZMQ_METADATA, metadata); +#endif +#ifdef ZMQ_MULTICAST_HOPS +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MULTICAST_HOPS, multicast_hops, int); +#endif +#ifdef ZMQ_MULTICAST_LOOP +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_MULTICAST_LOOP, multicast_loop, int); +#endif +#ifdef ZMQ_MULTICAST_MAXTPDU +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_MULTICAST_MAXTPDU, multicast_maxtpdu, int); +#endif +#ifdef ZMQ_PLAIN_SERVER +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_PLAIN_SERVER, plain_server, int); +#endif +#ifdef ZMQ_PLAIN_PASSWORD +ZMQ_DEFINE_ARRAY_OPT(ZMQ_PLAIN_PASSWORD, plain_password); +#endif +#ifdef ZMQ_PLAIN_USERNAME +ZMQ_DEFINE_ARRAY_OPT(ZMQ_PLAIN_USERNAME, plain_username); +#endif +#ifdef ZMQ_USE_FD +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_USE_FD, use_fd, int); +#endif +#ifdef ZMQ_PROBE_ROUTER +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_PROBE_ROUTER, probe_router, int); +#endif +#ifdef ZMQ_RATE +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RATE, rate, int); +#endif +#ifdef ZMQ_RCVBUF +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RCVBUF, rcvbuf, int); +#endif +#ifdef ZMQ_RCVHWM +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RCVHWM, rcvhwm, int); +#endif +#ifdef ZMQ_RCVMORE +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_RCVMORE, rcvmore, int); +#endif +#ifdef ZMQ_RCVTIMEO +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RCVTIMEO, rcvtimeo, int); +#endif +#ifdef ZMQ_RECONNECT_IVL +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECONNECT_IVL, reconnect_ivl, int); +#endif +#ifdef ZMQ_RECONNECT_IVL_MAX +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECONNECT_IVL_MAX, reconnect_ivl_max, int); +#endif +#ifdef ZMQ_RECOVERY_IVL +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_RECOVERY_IVL, recovery_ivl, int); +#endif +#ifdef ZMQ_REQ_CORRELATE +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_REQ_CORRELATE, req_correlate, int); +#endif +#ifdef ZMQ_REQ_RELAXED +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_REQ_RELAXED, req_relaxed, int); +#endif +#ifdef ZMQ_ROUTER_HANDOVER +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ROUTER_HANDOVER, router_handover, int); +#endif +#ifdef ZMQ_ROUTER_MANDATORY +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ROUTER_MANDATORY, router_mandatory, int); +#endif +#ifdef ZMQ_ROUTER_NOTIFY +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_ROUTER_NOTIFY, router_notify, int); +#endif +#ifdef ZMQ_ROUTING_ID +ZMQ_DEFINE_ARRAY_OPT_BINARY(ZMQ_ROUTING_ID, routing_id); +#endif +#ifdef ZMQ_SNDBUF +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_SNDBUF, sndbuf, int); +#endif +#ifdef ZMQ_SNDHWM +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_SNDHWM, sndhwm, int); +#endif +#ifdef ZMQ_SNDTIMEO +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_SNDTIMEO, sndtimeo, int); +#endif +#ifdef ZMQ_SOCKS_PROXY +ZMQ_DEFINE_ARRAY_OPT(ZMQ_SOCKS_PROXY, socks_proxy); +#endif +#ifdef ZMQ_STREAM_NOTIFY +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_STREAM_NOTIFY, stream_notify, int); +#endif +#ifdef ZMQ_SUBSCRIBE +ZMQ_DEFINE_ARRAY_OPT(ZMQ_SUBSCRIBE, subscribe); +#endif +#ifdef ZMQ_TCP_KEEPALIVE +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE, tcp_keepalive, int); +#endif +#ifdef ZMQ_TCP_KEEPALIVE_CNT +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE_CNT, tcp_keepalive_cnt, int); +#endif +#ifdef ZMQ_TCP_KEEPALIVE_IDLE +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE_IDLE, tcp_keepalive_idle, int); +#endif +#ifdef ZMQ_TCP_KEEPALIVE_INTVL +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_KEEPALIVE_INTVL, tcp_keepalive_intvl, int); +#endif +#ifdef ZMQ_TCP_MAXRT +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TCP_MAXRT, tcp_maxrt, int); +#endif +#ifdef ZMQ_THREAD_SAFE +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_THREAD_SAFE, thread_safe, int); +#endif +#ifdef ZMQ_TOS +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TOS, tos, int); +#endif +#ifdef ZMQ_TYPE +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_TYPE, type, int); +#endif +#ifdef ZMQ_UNSUBSCRIBE +ZMQ_DEFINE_ARRAY_OPT(ZMQ_UNSUBSCRIBE, unsubscribe); +#endif +#ifdef ZMQ_VMCI_BUFFER_SIZE +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_BUFFER_SIZE, vmci_buffer_size, uint64_t); +#endif +#ifdef ZMQ_VMCI_BUFFER_MIN_SIZE +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_BUFFER_MIN_SIZE, vmci_buffer_min_size, uint64_t); +#endif +#ifdef ZMQ_VMCI_BUFFER_MAX_SIZE +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_BUFFER_MAX_SIZE, vmci_buffer_max_size, uint64_t); +#endif +#ifdef ZMQ_VMCI_CONNECT_TIMEOUT +ZMQ_DEFINE_INTEGRAL_OPT(ZMQ_VMCI_CONNECT_TIMEOUT, vmci_connect_timeout, int); +#endif +#ifdef ZMQ_XPUB_VERBOSE +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_VERBOSE, xpub_verbose, int); +#endif +#ifdef ZMQ_XPUB_VERBOSER +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_VERBOSER, xpub_verboser, int); +#endif +#ifdef ZMQ_XPUB_MANUAL +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_MANUAL, xpub_manual, int); +#endif +#ifdef ZMQ_XPUB_NODROP +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_XPUB_NODROP, xpub_nodrop, int); +#endif +#ifdef ZMQ_XPUB_WELCOME_MSG +ZMQ_DEFINE_ARRAY_OPT(ZMQ_XPUB_WELCOME_MSG, xpub_welcome_msg); +#endif +#ifdef ZMQ_ZAP_ENFORCE_DOMAIN +ZMQ_DEFINE_INTEGRAL_BOOL_UNIT_OPT(ZMQ_ZAP_ENFORCE_DOMAIN, zap_enforce_domain, int); +#endif +#ifdef ZMQ_ZAP_DOMAIN +ZMQ_DEFINE_ARRAY_OPT(ZMQ_ZAP_DOMAIN, zap_domain); +#endif + +} // namespace sockopt +#endif // ZMQ_CPP11 + + +namespace detail +{ +class socket_base +{ + public: + socket_base() ZMQ_NOTHROW : _handle(ZMQ_NULLPTR) {} + ZMQ_EXPLICIT socket_base(void *handle) ZMQ_NOTHROW : _handle(handle) {} + + template + ZMQ_CPP11_DEPRECATED("from 4.7.0, use `set` taking option from zmq::sockopt") + void setsockopt(int option_, T const &optval) + { + setsockopt(option_, &optval, sizeof(T)); + } + + ZMQ_CPP11_DEPRECATED("from 4.7.0, use `set` taking option from zmq::sockopt") + void setsockopt(int option_, const void *optval_, size_t optvallen_) + { + int rc = zmq_setsockopt(_handle, option_, optval_, optvallen_); + if (rc != 0) + throw error_t(); + } + + ZMQ_CPP11_DEPRECATED("from 4.7.0, use `get` taking option from zmq::sockopt") + void getsockopt(int option_, void *optval_, size_t *optvallen_) const + { + int rc = zmq_getsockopt(_handle, option_, optval_, optvallen_); + if (rc != 0) + throw error_t(); + } + + template + ZMQ_CPP11_DEPRECATED("from 4.7.0, use `get` taking option from zmq::sockopt") + T getsockopt(int option_) const + { + T optval; + size_t optlen = sizeof(T); + getsockopt(option_, &optval, &optlen); + return optval; + } + +#ifdef ZMQ_CPP11 + // Set integral socket option, e.g. + // `socket.set(zmq::sockopt::linger, 0)` + template + void set(sockopt::integral_option, const T &val) + { + static_assert(std::is_integral::value, "T must be integral"); + set_option(Opt, &val, sizeof val); + } + + // Set integral socket option from boolean, e.g. + // `socket.set(zmq::sockopt::immediate, false)` + template + void set(sockopt::integral_option, bool val) + { + static_assert(std::is_integral::value, "T must be integral"); + T rep_val = val; + set_option(Opt, &rep_val, sizeof rep_val); + } + + // Set array socket option, e.g. + // `socket.set(zmq::sockopt::plain_username, "foo123")` + template + void set(sockopt::array_option, const char *buf) + { + set_option(Opt, buf, std::strlen(buf)); + } + + // Set array socket option, e.g. + // `socket.set(zmq::sockopt::routing_id, zmq::buffer(id))` + template + void set(sockopt::array_option, const_buffer buf) + { + set_option(Opt, buf.data(), buf.size()); + } + + // Set array socket option, e.g. + // `socket.set(zmq::sockopt::routing_id, id_str)` + template + void set(sockopt::array_option, const std::string &buf) + { + set_option(Opt, buf.data(), buf.size()); + } + +#if CPPZMQ_HAS_STRING_VIEW + // Set array socket option, e.g. + // `socket.set(zmq::sockopt::routing_id, id_str)` + template + void set(sockopt::array_option, std::string_view buf) + { + set_option(Opt, buf.data(), buf.size()); + } +#endif + + // Get scalar socket option, e.g. + // `auto opt = socket.get(zmq::sockopt::linger)` + template + ZMQ_NODISCARD T get(sockopt::integral_option) const + { + static_assert(std::is_integral::value, "T must be integral"); + T val; + size_t size = sizeof val; + get_option(Opt, &val, &size); + assert(size == sizeof val); + return val; + } + + // Get array socket option, writes to buf, returns option size in bytes, e.g. + // `size_t optsize = socket.get(zmq::sockopt::routing_id, zmq::buffer(id))` + template + ZMQ_NODISCARD size_t get(sockopt::array_option, + mutable_buffer buf) const + { + size_t size = buf.size(); + get_option(Opt, buf.data(), &size); + return size; + } + + // Get array socket option as string (initializes the string buffer size to init_size) e.g. + // `auto s = socket.get(zmq::sockopt::routing_id)` + // Note: removes the null character from null-terminated string options, + // i.e. the string size excludes the null character. + template + ZMQ_NODISCARD std::string get(sockopt::array_option, + size_t init_size = 1024) const + { + if ZMQ_CONSTEXPR_IF (NullTerm == 2) { + if (init_size == 1024) { + init_size = 41; // get as Z85 string + } + } + std::string str(init_size, '\0'); + size_t size = get(sockopt::array_option{}, buffer(str)); + if ZMQ_CONSTEXPR_IF (NullTerm == 1) { + if (size > 0) { + assert(str[size - 1] == '\0'); + --size; + } + } else if ZMQ_CONSTEXPR_IF (NullTerm == 2) { + assert(size == 32 || size == 41); + if (size == 41) { + assert(str[size - 1] == '\0'); + --size; + } + } + str.resize(size); + return str; + } +#endif + + void bind(std::string const &addr) { bind(addr.c_str()); } + + void bind(const char *addr_) + { + int rc = zmq_bind(_handle, addr_); + if (rc != 0) + throw error_t(); + } + + void unbind(std::string const &addr) { unbind(addr.c_str()); } + + void unbind(const char *addr_) + { + int rc = zmq_unbind(_handle, addr_); + if (rc != 0) + throw error_t(); + } + + void connect(std::string const &addr) { connect(addr.c_str()); } + + void connect(const char *addr_) + { + int rc = zmq_connect(_handle, addr_); + if (rc != 0) + throw error_t(); + } + + void disconnect(std::string const &addr) { disconnect(addr.c_str()); } + + void disconnect(const char *addr_) + { + int rc = zmq_disconnect(_handle, addr_); + if (rc != 0) + throw error_t(); + } + + ZMQ_DEPRECATED("from 4.7.1, use handle() != nullptr or operator bool") + bool connected() const ZMQ_NOTHROW { return (_handle != ZMQ_NULLPTR); } + + ZMQ_CPP11_DEPRECATED("from 4.3.1, use send taking a const_buffer and send_flags") + size_t send(const void *buf_, size_t len_, int flags_ = 0) + { + int nbytes = zmq_send(_handle, buf_, len_, flags_); + if (nbytes >= 0) + return static_cast(nbytes); + if (zmq_errno() == EAGAIN) + return 0; + throw error_t(); + } + + ZMQ_CPP11_DEPRECATED("from 4.3.1, use send taking message_t and send_flags") + bool send(message_t &msg_, + int flags_ = 0) // default until removed + { + int nbytes = zmq_msg_send(msg_.handle(), _handle, flags_); + if (nbytes >= 0) + return true; + if (zmq_errno() == EAGAIN) + return false; + throw error_t(); + } + + template + ZMQ_CPP11_DEPRECATED( + "from 4.4.1, use send taking message_t or buffer (for contiguous " + "ranges), and send_flags") + bool send(T first, T last, int flags_ = 0) + { + zmq::message_t msg(first, last); + int nbytes = zmq_msg_send(msg.handle(), _handle, flags_); + if (nbytes >= 0) + return true; + if (zmq_errno() == EAGAIN) + return false; + throw error_t(); + } + +#ifdef ZMQ_HAS_RVALUE_REFS + ZMQ_CPP11_DEPRECATED("from 4.3.1, use send taking message_t and send_flags") + bool send(message_t &&msg_, + int flags_ = 0) // default until removed + { +#ifdef ZMQ_CPP11 + return send(msg_, static_cast(flags_)).has_value(); +#else + return send(msg_, flags_); +#endif + } +#endif + +#ifdef ZMQ_CPP11 + send_result_t send(const_buffer buf, send_flags flags = send_flags::none) + { + const int nbytes = + zmq_send(_handle, buf.data(), buf.size(), static_cast(flags)); + if (nbytes >= 0) + return static_cast(nbytes); + if (zmq_errno() == EAGAIN) + return {}; + throw error_t(); + } + + send_result_t send(message_t &msg, send_flags flags) + { + int nbytes = zmq_msg_send(msg.handle(), _handle, static_cast(flags)); + if (nbytes >= 0) + return static_cast(nbytes); + if (zmq_errno() == EAGAIN) + return {}; + throw error_t(); + } + + send_result_t send(message_t &&msg, send_flags flags) + { + return send(msg, flags); + } +#endif + + ZMQ_CPP11_DEPRECATED( + "from 4.3.1, use recv taking a mutable_buffer and recv_flags") + size_t recv(void *buf_, size_t len_, int flags_ = 0) + { + int nbytes = zmq_recv(_handle, buf_, len_, flags_); + if (nbytes >= 0) + return static_cast(nbytes); + if (zmq_errno() == EAGAIN) + return 0; + throw error_t(); + } + + ZMQ_CPP11_DEPRECATED( + "from 4.3.1, use recv taking a reference to message_t and recv_flags") + bool recv(message_t *msg_, int flags_ = 0) + { + int nbytes = zmq_msg_recv(msg_->handle(), _handle, flags_); + if (nbytes >= 0) + return true; + if (zmq_errno() == EAGAIN) + return false; + throw error_t(); + } + +#ifdef ZMQ_CPP11 + ZMQ_NODISCARD + recv_buffer_result_t recv(mutable_buffer buf, + recv_flags flags = recv_flags::none) + { + const int nbytes = + zmq_recv(_handle, buf.data(), buf.size(), static_cast(flags)); + if (nbytes >= 0) { + return recv_buffer_size{ + (std::min)(static_cast(nbytes), buf.size()), + static_cast(nbytes)}; + } + if (zmq_errno() == EAGAIN) + return {}; + throw error_t(); + } + + ZMQ_NODISCARD + recv_result_t recv(message_t &msg, recv_flags flags = recv_flags::none) + { + const int nbytes = + zmq_msg_recv(msg.handle(), _handle, static_cast(flags)); + if (nbytes >= 0) { + assert(msg.size() == static_cast(nbytes)); + return static_cast(nbytes); + } + if (zmq_errno() == EAGAIN) + return {}; + throw error_t(); + } +#endif + +#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0) + void join(const char *group) + { + int rc = zmq_join(_handle, group); + if (rc != 0) + throw error_t(); + } + + void leave(const char *group) + { + int rc = zmq_leave(_handle, group); + if (rc != 0) + throw error_t(); + } +#endif + + ZMQ_NODISCARD void *handle() ZMQ_NOTHROW { return _handle; } + ZMQ_NODISCARD const void *handle() const ZMQ_NOTHROW { return _handle; } + + ZMQ_EXPLICIT operator bool() const ZMQ_NOTHROW { return _handle != ZMQ_NULLPTR; } + // note: non-const operator bool can be removed once + // operator void* is removed from socket_t + ZMQ_EXPLICIT operator bool() ZMQ_NOTHROW { return _handle != ZMQ_NULLPTR; } + + protected: + void *_handle; + + private: + void set_option(int option_, const void *optval_, size_t optvallen_) + { + int rc = zmq_setsockopt(_handle, option_, optval_, optvallen_); + if (rc != 0) + throw error_t(); + } + + void get_option(int option_, void *optval_, size_t *optvallen_) const + { + int rc = zmq_getsockopt(_handle, option_, optval_, optvallen_); + if (rc != 0) + throw error_t(); + } +}; +} // namespace detail + +#ifdef ZMQ_CPP11 +enum class socket_type : int +{ + req = ZMQ_REQ, + rep = ZMQ_REP, + dealer = ZMQ_DEALER, + router = ZMQ_ROUTER, + pub = ZMQ_PUB, + sub = ZMQ_SUB, + xpub = ZMQ_XPUB, + xsub = ZMQ_XSUB, + push = ZMQ_PUSH, + pull = ZMQ_PULL, +#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 0) + server = ZMQ_SERVER, + client = ZMQ_CLIENT, + radio = ZMQ_RADIO, + dish = ZMQ_DISH, + gather = ZMQ_GATHER, + scatter = ZMQ_SCATTER, + dgram = ZMQ_DGRAM, +#endif +#if defined(ZMQ_BUILD_DRAFT_API) && ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 3, 3) + peer = ZMQ_PEER, + channel = ZMQ_CHANNEL, +#endif +#if ZMQ_VERSION_MAJOR >= 4 + stream = ZMQ_STREAM, +#endif + pair = ZMQ_PAIR +}; +#endif + +struct from_handle_t +{ + struct _private + { + }; // disabling use other than with from_handle + ZMQ_CONSTEXPR_FN ZMQ_EXPLICIT from_handle_t(_private /*p*/) ZMQ_NOTHROW {} +}; + +ZMQ_CONSTEXPR_VAR from_handle_t from_handle = + from_handle_t(from_handle_t::_private()); + +// A non-owning nullable reference to a socket. +// The reference is invalidated on socket close or destruction. +class socket_ref : public detail::socket_base +{ + public: + socket_ref() ZMQ_NOTHROW : detail::socket_base() {} +#ifdef ZMQ_CPP11 + socket_ref(std::nullptr_t) ZMQ_NOTHROW : detail::socket_base() {} +#endif + socket_ref(from_handle_t /*fh*/, void *handle) ZMQ_NOTHROW + : detail::socket_base(handle) + { + } +}; + +#ifdef ZMQ_CPP11 +inline bool operator==(socket_ref sr, std::nullptr_t /*p*/) ZMQ_NOTHROW +{ + return sr.handle() == nullptr; +} +inline bool operator==(std::nullptr_t /*p*/, socket_ref sr) ZMQ_NOTHROW +{ + return sr.handle() == nullptr; +} +inline bool operator!=(socket_ref sr, std::nullptr_t /*p*/) ZMQ_NOTHROW +{ + return !(sr == nullptr); +} +inline bool operator!=(std::nullptr_t /*p*/, socket_ref sr) ZMQ_NOTHROW +{ + return !(sr == nullptr); +} +#endif + +inline bool operator==(const detail::socket_base& a, const detail::socket_base& b) ZMQ_NOTHROW +{ + return std::equal_to()(a.handle(), b.handle()); +} +inline bool operator!=(const detail::socket_base& a, const detail::socket_base& b) ZMQ_NOTHROW +{ + return !(a == b); +} +inline bool operator<(const detail::socket_base& a, const detail::socket_base& b) ZMQ_NOTHROW +{ + return std::less()(a.handle(), b.handle()); +} +inline bool operator>(const detail::socket_base& a, const detail::socket_base& b) ZMQ_NOTHROW +{ + return b < a; +} +inline bool operator<=(const detail::socket_base& a, const detail::socket_base& b) ZMQ_NOTHROW +{ + return !(a > b); +} +inline bool operator>=(const detail::socket_base& a, const detail::socket_base& b) ZMQ_NOTHROW +{ + return !(a < b); +} + +} // namespace zmq + +#ifdef ZMQ_CPP11 +namespace std +{ +template<> struct hash +{ + size_t operator()(zmq::socket_ref sr) const ZMQ_NOTHROW + { + return hash()(sr.handle()); + } +}; +} // namespace std +#endif + +namespace zmq +{ +class socket_t : public detail::socket_base +{ + friend class monitor_t; + + public: + socket_t() ZMQ_NOTHROW : detail::socket_base(ZMQ_NULLPTR), ctxptr(ZMQ_NULLPTR) {} + + socket_t(context_t &context_, int type_) : + detail::socket_base(zmq_socket(context_.handle(), type_)), + ctxptr(context_.handle()) + { + if (_handle == ZMQ_NULLPTR) + throw error_t(); + } + +#ifdef ZMQ_CPP11 + socket_t(context_t &context_, socket_type type_) : + socket_t(context_, static_cast(type_)) + { + } +#endif + +#ifdef ZMQ_HAS_RVALUE_REFS + socket_t(socket_t &&rhs) ZMQ_NOTHROW : detail::socket_base(rhs._handle), + ctxptr(rhs.ctxptr) + { + rhs._handle = ZMQ_NULLPTR; + rhs.ctxptr = ZMQ_NULLPTR; + } + socket_t &operator=(socket_t &&rhs) ZMQ_NOTHROW + { + close(); + std::swap(_handle, rhs._handle); + std::swap(ctxptr, rhs.ctxptr); + return *this; + } +#endif + + ~socket_t() ZMQ_NOTHROW { close(); } + + operator void *() ZMQ_NOTHROW { return _handle; } + + operator void const *() const ZMQ_NOTHROW { return _handle; } + + void close() ZMQ_NOTHROW + { + if (_handle == ZMQ_NULLPTR) + // already closed + return; + int rc = zmq_close(_handle); + ZMQ_ASSERT(rc == 0); + _handle = ZMQ_NULLPTR; + ctxptr = ZMQ_NULLPTR; + } + + void swap(socket_t &other) ZMQ_NOTHROW + { + std::swap(_handle, other._handle); + std::swap(ctxptr, other.ctxptr); + } + + operator socket_ref() ZMQ_NOTHROW { return socket_ref(from_handle, _handle); } + + private: + void *ctxptr; + + socket_t(const socket_t &) ZMQ_DELETED_FUNCTION; + void operator=(const socket_t &) ZMQ_DELETED_FUNCTION; + + // used by monitor_t + socket_t(void *context_, int type_) : + detail::socket_base(zmq_socket(context_, type_)), ctxptr(context_) + { + if (_handle == ZMQ_NULLPTR) + throw error_t(); + if (ctxptr == ZMQ_NULLPTR) + throw error_t(); + } +}; + +inline void swap(socket_t &a, socket_t &b) ZMQ_NOTHROW +{ + a.swap(b); +} + +ZMQ_DEPRECATED("from 4.3.1, use proxy taking socket_t objects") +inline void proxy(void *frontend, void *backend, void *capture) +{ + int rc = zmq_proxy(frontend, backend, capture); + if (rc != 0) + throw error_t(); +} + +inline void +proxy(socket_ref frontend, socket_ref backend, socket_ref capture = socket_ref()) +{ + int rc = zmq_proxy(frontend.handle(), backend.handle(), capture.handle()); + if (rc != 0) + throw error_t(); +} + +#ifdef ZMQ_HAS_PROXY_STEERABLE +ZMQ_DEPRECATED("from 4.3.1, use proxy_steerable taking socket_t objects") +inline void +proxy_steerable(void *frontend, void *backend, void *capture, void *control) +{ + int rc = zmq_proxy_steerable(frontend, backend, capture, control); + if (rc != 0) + throw error_t(); +} + +inline void proxy_steerable(socket_ref frontend, + socket_ref backend, + socket_ref capture, + socket_ref control) +{ + int rc = zmq_proxy_steerable(frontend.handle(), backend.handle(), + capture.handle(), control.handle()); + if (rc != 0) + throw error_t(); +} +#endif + +class monitor_t +{ + public: + monitor_t() : _socket(), _monitor_socket() {} + + virtual ~monitor_t() { close(); } + +#ifdef ZMQ_HAS_RVALUE_REFS + monitor_t(monitor_t &&rhs) ZMQ_NOTHROW : _socket(), _monitor_socket() + { + std::swap(_socket, rhs._socket); + std::swap(_monitor_socket, rhs._monitor_socket); + } + + monitor_t &operator=(monitor_t &&rhs) ZMQ_NOTHROW + { + close(); + _socket = socket_ref(); + std::swap(_socket, rhs._socket); + std::swap(_monitor_socket, rhs._monitor_socket); + return *this; + } +#endif + + + void + monitor(socket_t &socket, std::string const &addr, int events = ZMQ_EVENT_ALL) + { + monitor(socket, addr.c_str(), events); + } + + void monitor(socket_t &socket, const char *addr_, int events = ZMQ_EVENT_ALL) + { + init(socket, addr_, events); + while (true) { + check_event(-1); + } + } + + void init(socket_t &socket, std::string const &addr, int events = ZMQ_EVENT_ALL) + { + init(socket, addr.c_str(), events); + } + + void init(socket_t &socket, const char *addr_, int events = ZMQ_EVENT_ALL) + { + int rc = zmq_socket_monitor(socket.handle(), addr_, events); + if (rc != 0) + throw error_t(); + + _socket = socket; + _monitor_socket = socket_t(socket.ctxptr, ZMQ_PAIR); + _monitor_socket.connect(addr_); + + on_monitor_started(); + } + + bool check_event(int timeout = 0) + { + assert(_monitor_socket); + + zmq::message_t eventMsg; + + zmq::pollitem_t items[] = { + {_monitor_socket.handle(), 0, ZMQ_POLLIN, 0}, + }; + + zmq::poll(&items[0], 1, timeout); + + if (items[0].revents & ZMQ_POLLIN) { + int rc = zmq_msg_recv(eventMsg.handle(), _monitor_socket.handle(), 0); + if (rc == -1 && zmq_errno() == ETERM) + return false; + assert(rc != -1); + + } else { + return false; + } + +#if ZMQ_VERSION_MAJOR >= 4 + const char *data = static_cast(eventMsg.data()); + zmq_event_t msgEvent; + memcpy(&msgEvent.event, data, sizeof(uint16_t)); + data += sizeof(uint16_t); + memcpy(&msgEvent.value, data, sizeof(int32_t)); + zmq_event_t *event = &msgEvent; +#else + zmq_event_t *event = static_cast(eventMsg.data()); +#endif + +#ifdef ZMQ_NEW_MONITOR_EVENT_LAYOUT + zmq::message_t addrMsg; + int rc = zmq_msg_recv(addrMsg.handle(), _monitor_socket.handle(), 0); + if (rc == -1 && zmq_errno() == ETERM) { + return false; + } + + assert(rc != -1); + std::string address = addrMsg.to_string(); +#else + // Bit of a hack, but all events in the zmq_event_t union have the same layout so this will work for all event types. + std::string address = event->data.connected.addr; +#endif + +#ifdef ZMQ_EVENT_MONITOR_STOPPED + if (event->event == ZMQ_EVENT_MONITOR_STOPPED) { + return false; + } + +#endif + + switch (event->event) { + case ZMQ_EVENT_CONNECTED: + on_event_connected(*event, address.c_str()); + break; + case ZMQ_EVENT_CONNECT_DELAYED: + on_event_connect_delayed(*event, address.c_str()); + break; + case ZMQ_EVENT_CONNECT_RETRIED: + on_event_connect_retried(*event, address.c_str()); + break; + case ZMQ_EVENT_LISTENING: + on_event_listening(*event, address.c_str()); + break; + case ZMQ_EVENT_BIND_FAILED: + on_event_bind_failed(*event, address.c_str()); + break; + case ZMQ_EVENT_ACCEPTED: + on_event_accepted(*event, address.c_str()); + break; + case ZMQ_EVENT_ACCEPT_FAILED: + on_event_accept_failed(*event, address.c_str()); + break; + case ZMQ_EVENT_CLOSED: + on_event_closed(*event, address.c_str()); + break; + case ZMQ_EVENT_CLOSE_FAILED: + on_event_close_failed(*event, address.c_str()); + break; + case ZMQ_EVENT_DISCONNECTED: + on_event_disconnected(*event, address.c_str()); + break; +#ifdef ZMQ_BUILD_DRAFT_API +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3) + case ZMQ_EVENT_HANDSHAKE_FAILED_NO_DETAIL: + on_event_handshake_failed_no_detail(*event, address.c_str()); + break; + case ZMQ_EVENT_HANDSHAKE_FAILED_PROTOCOL: + on_event_handshake_failed_protocol(*event, address.c_str()); + break; + case ZMQ_EVENT_HANDSHAKE_FAILED_AUTH: + on_event_handshake_failed_auth(*event, address.c_str()); + break; + case ZMQ_EVENT_HANDSHAKE_SUCCEEDED: + on_event_handshake_succeeded(*event, address.c_str()); + break; +#elif ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 1) + case ZMQ_EVENT_HANDSHAKE_FAILED: + on_event_handshake_failed(*event, address.c_str()); + break; + case ZMQ_EVENT_HANDSHAKE_SUCCEED: + on_event_handshake_succeed(*event, address.c_str()); + break; +#endif +#endif + default: + on_event_unknown(*event, address.c_str()); + break; + } + + return true; + } + +#ifdef ZMQ_EVENT_MONITOR_STOPPED + void abort() + { + if (_socket) + zmq_socket_monitor(_socket.handle(), ZMQ_NULLPTR, 0); + + _socket = socket_ref(); + } +#endif + virtual void on_monitor_started() {} + virtual void on_event_connected(const zmq_event_t &event_, const char *addr_) + { + (void) event_; + (void) addr_; + } + virtual void on_event_connect_delayed(const zmq_event_t &event_, + const char *addr_) + { + (void) event_; + (void) addr_; + } + virtual void on_event_connect_retried(const zmq_event_t &event_, + const char *addr_) + { + (void) event_; + (void) addr_; + } + virtual void on_event_listening(const zmq_event_t &event_, const char *addr_) + { + (void) event_; + (void) addr_; + } + virtual void on_event_bind_failed(const zmq_event_t &event_, const char *addr_) + { + (void) event_; + (void) addr_; + } + virtual void on_event_accepted(const zmq_event_t &event_, const char *addr_) + { + (void) event_; + (void) addr_; + } + virtual void on_event_accept_failed(const zmq_event_t &event_, const char *addr_) + { + (void) event_; + (void) addr_; + } + virtual void on_event_closed(const zmq_event_t &event_, const char *addr_) + { + (void) event_; + (void) addr_; + } + virtual void on_event_close_failed(const zmq_event_t &event_, const char *addr_) + { + (void) event_; + (void) addr_; + } + virtual void on_event_disconnected(const zmq_event_t &event_, const char *addr_) + { + (void) event_; + (void) addr_; + } +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3) + virtual void on_event_handshake_failed_no_detail(const zmq_event_t &event_, + const char *addr_) + { + (void) event_; + (void) addr_; + } + virtual void on_event_handshake_failed_protocol(const zmq_event_t &event_, + const char *addr_) + { + (void) event_; + (void) addr_; + } + virtual void on_event_handshake_failed_auth(const zmq_event_t &event_, + const char *addr_) + { + (void) event_; + (void) addr_; + } + virtual void on_event_handshake_succeeded(const zmq_event_t &event_, + const char *addr_) + { + (void) event_; + (void) addr_; + } +#elif ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 1) + virtual void on_event_handshake_failed(const zmq_event_t &event_, + const char *addr_) + { + (void) event_; + (void) addr_; + } + virtual void on_event_handshake_succeed(const zmq_event_t &event_, + const char *addr_) + { + (void) event_; + (void) addr_; + } +#endif + virtual void on_event_unknown(const zmq_event_t &event_, const char *addr_) + { + (void) event_; + (void) addr_; + } + + private: + monitor_t(const monitor_t &) ZMQ_DELETED_FUNCTION; + void operator=(const monitor_t &) ZMQ_DELETED_FUNCTION; + + socket_ref _socket; + socket_t _monitor_socket; + + void close() ZMQ_NOTHROW + { + if (_socket) + zmq_socket_monitor(_socket.handle(), ZMQ_NULLPTR, 0); + _monitor_socket.close(); + } +}; + +#if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER) + +// polling events +enum class event_flags : short +{ + none = 0, + pollin = ZMQ_POLLIN, + pollout = ZMQ_POLLOUT, + pollerr = ZMQ_POLLERR, + pollpri = ZMQ_POLLPRI +}; + +constexpr event_flags operator|(event_flags a, event_flags b) noexcept +{ + return detail::enum_bit_or(a, b); +} +constexpr event_flags operator&(event_flags a, event_flags b) noexcept +{ + return detail::enum_bit_and(a, b); +} +constexpr event_flags operator^(event_flags a, event_flags b) noexcept +{ + return detail::enum_bit_xor(a, b); +} +constexpr event_flags operator~(event_flags a) noexcept +{ + return detail::enum_bit_not(a); +} + +struct no_user_data; + +// layout compatible with zmq_poller_event_t +template struct poller_event +{ + socket_ref socket; + ::zmq::fd_t fd; + T *user_data; + event_flags events; +}; + +template class poller_t +{ + public: + using event_type = poller_event; + + poller_t() : poller_ptr(zmq_poller_new()) + { + if (!poller_ptr) + throw error_t(); + } + + template< + typename Dummy = void, + typename = + typename std::enable_if::value, Dummy>::type> + void add(zmq::socket_ref socket, event_flags events, T *user_data) + { + add_impl(socket, events, user_data); + } + + void add(zmq::socket_ref socket, event_flags events) + { + add_impl(socket, events, nullptr); + } + + void remove(zmq::socket_ref socket) + { + if (0 != zmq_poller_remove(poller_ptr.get(), socket.handle())) { + throw error_t(); + } + } + + void modify(zmq::socket_ref socket, event_flags events) + { + if (0 + != zmq_poller_modify(poller_ptr.get(), socket.handle(), + static_cast(events))) { + throw error_t(); + } + } + + size_t wait_all(std::vector &poller_events, + const std::chrono::milliseconds timeout) + { + int rc = zmq_poller_wait_all( + poller_ptr.get(), + reinterpret_cast(poller_events.data()), + static_cast(poller_events.size()), + static_cast(timeout.count())); + if (rc > 0) + return static_cast(rc); + +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 2, 3) + if (zmq_errno() == EAGAIN) +#else + if (zmq_errno() == ETIMEDOUT) +#endif + return 0; + + throw error_t(); + } + +#if ZMQ_VERSION >= ZMQ_MAKE_VERSION(4, 3, 3) + size_t size() const noexcept + { + int rc = zmq_poller_size(const_cast(poller_ptr.get())); + ZMQ_ASSERT(rc >= 0); + return static_cast(std::max(rc, 0)); + } +#endif + + private: + struct destroy_poller_t + { + void operator()(void *ptr) noexcept + { + int rc = zmq_poller_destroy(&ptr); + ZMQ_ASSERT(rc == 0); + } + }; + + std::unique_ptr poller_ptr; + + void add_impl(zmq::socket_ref socket, event_flags events, T *user_data) + { + if (0 + != zmq_poller_add(poller_ptr.get(), socket.handle(), user_data, + static_cast(events))) { + throw error_t(); + } + } +}; +#endif // defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER) + +inline std::ostream &operator<<(std::ostream &os, const message_t &msg) +{ + return os << msg.str(); +} + +} // namespace zmq + +#endif // __ZMQ_HPP_INCLUDED__ diff --git a/external/src/cppzmq/zmq_addon.hpp b/external/src/cppzmq/zmq_addon.hpp new file mode 100644 index 0000000..4c36d6e --- /dev/null +++ b/external/src/cppzmq/zmq_addon.hpp @@ -0,0 +1,743 @@ +/* + Copyright (c) 2016-2017 ZeroMQ community + Copyright (c) 2016 VOCA AS / Harald Nøkland + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to + deal in the Software without restriction, including without limitation the + rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + sell copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + IN THE SOFTWARE. +*/ + +#ifndef __ZMQ_ADDON_HPP_INCLUDED__ +#define __ZMQ_ADDON_HPP_INCLUDED__ + +#include "zmq.hpp" + +#include +#include +#include +#include +#ifdef ZMQ_CPP11 +#include +#include +#include +#endif + +namespace zmq +{ +#ifdef ZMQ_CPP11 + +namespace detail +{ +template +recv_result_t +recv_multipart_n(socket_ref s, OutputIt out, size_t n, recv_flags flags) +{ + size_t msg_count = 0; + message_t msg; + while (true) { + if ZMQ_CONSTEXPR_IF (CheckN) { + if (msg_count >= n) + throw std::runtime_error( + "Too many message parts in recv_multipart_n"); + } + if (!s.recv(msg, flags)) { + // zmq ensures atomic delivery of messages + assert(msg_count == 0); + return {}; + } + ++msg_count; + const bool more = msg.more(); + *out++ = std::move(msg); + if (!more) + break; + } + return msg_count; +} + +inline bool is_little_endian() +{ + const uint16_t i = 0x01; + return *reinterpret_cast(&i) == 0x01; +} + +inline void write_network_order(unsigned char *buf, const uint32_t value) +{ + if (is_little_endian()) { + ZMQ_CONSTEXPR_VAR uint32_t mask = std::numeric_limits::max(); + *buf++ = static_cast((value >> 24) & mask); + *buf++ = static_cast((value >> 16) & mask); + *buf++ = static_cast((value >> 8) & mask); + *buf++ = static_cast(value & mask); + } else { + std::memcpy(buf, &value, sizeof(value)); + } +} + +inline uint32_t read_u32_network_order(const unsigned char *buf) +{ + if (is_little_endian()) { + return (static_cast(buf[0]) << 24) + + (static_cast(buf[1]) << 16) + + (static_cast(buf[2]) << 8) + + static_cast(buf[3]); + } else { + uint32_t value; + std::memcpy(&value, buf, sizeof(value)); + return value; + } +} +} // namespace detail + +/* Receive a multipart message. + + Writes the zmq::message_t objects to OutputIterator out. + The out iterator must handle an unspecified number of writes, + e.g. by using std::back_inserter. + + Returns: the number of messages received or nullopt (on EAGAIN). + Throws: if recv throws. Any exceptions thrown + by the out iterator will be propagated and the message + may have been only partially received with pending + message parts. It is adviced to close this socket in that event. +*/ +template +ZMQ_NODISCARD recv_result_t recv_multipart(socket_ref s, + OutputIt out, + recv_flags flags = recv_flags::none) +{ + return detail::recv_multipart_n(s, std::move(out), 0, flags); +} + +/* Receive a multipart message. + + Writes at most n zmq::message_t objects to OutputIterator out. + If the number of message parts of the incoming message exceeds n + then an exception will be thrown. + + Returns: the number of messages received or nullopt (on EAGAIN). + Throws: if recv throws. Throws std::runtime_error if the number + of message parts exceeds n (exactly n messages will have been written + to out). Any exceptions thrown + by the out iterator will be propagated and the message + may have been only partially received with pending + message parts. It is adviced to close this socket in that event. +*/ +template +ZMQ_NODISCARD recv_result_t recv_multipart_n(socket_ref s, + OutputIt out, + size_t n, + recv_flags flags = recv_flags::none) +{ + return detail::recv_multipart_n(s, std::move(out), n, flags); +} + +/* Send a multipart message. + + The range must be a ForwardRange of zmq::message_t, + zmq::const_buffer or zmq::mutable_buffer. + The flags may be zmq::send_flags::sndmore if there are + more message parts to be sent after the call to this function. + + Returns: the number of messages sent (exactly msgs.size()) or nullopt (on EAGAIN). + Throws: if send throws. Any exceptions thrown + by the msgs range will be propagated and the message + may have been only partially sent. It is adviced to close this socket in that event. +*/ +template::value + && (std::is_same, message_t>::value + || detail::is_buffer>::value)>::type +#endif + > +send_result_t +send_multipart(socket_ref s, Range &&msgs, send_flags flags = send_flags::none) +{ + using std::begin; + using std::end; + auto it = begin(msgs); + const auto end_it = end(msgs); + size_t msg_count = 0; + while (it != end_it) { + const auto next = std::next(it); + const auto msg_flags = + flags | (next == end_it ? send_flags::none : send_flags::sndmore); + if (!s.send(*it, msg_flags)) { + // zmq ensures atomic delivery of messages + assert(it == begin(msgs)); + return {}; + } + ++msg_count; + it = next; + } + return msg_count; +} + +/* Encode a multipart message. + + The range must be a ForwardRange of zmq::message_t. A + zmq::multipart_t or STL container may be passed for encoding. + + Returns: a zmq::message_t holding the encoded multipart data. + + Throws: std::range_error is thrown if the size of any single part + can not fit in an unsigned 32 bit integer. + + The encoding is compatible with that used by the CZMQ function + zmsg_encode(), see https://rfc.zeromq.org/spec/50/. + Each part consists of a size followed by the data. + These are placed contiguously into the output message. A part of + size less than 255 bytes will have a single byte size value. + Larger parts will have a five byte size value with the first byte + set to 0xFF and the remaining four bytes holding the size of the + part's data. +*/ +template::value + && (std::is_same, message_t>::value + || detail::is_buffer>::value)>::type +#endif + > +message_t encode(const Range &parts) +{ + size_t mmsg_size = 0; + + // First pass check sizes + for (const auto &part : parts) { + const size_t part_size = part.size(); + if (part_size > std::numeric_limits::max()) { + // Size value must fit into uint32_t. + throw std::range_error("Invalid size, message part too large"); + } + const size_t count_size = + part_size < std::numeric_limits::max() ? 1 : 5; + mmsg_size += part_size + count_size; + } + + message_t encoded(mmsg_size); + unsigned char *buf = encoded.data(); + for (const auto &part : parts) { + const uint32_t part_size = static_cast(part.size()); + const unsigned char *part_data = + static_cast(part.data()); + + if (part_size < std::numeric_limits::max()) { + // small part + *buf++ = (unsigned char) part_size; + } else { + // big part + *buf++ = std::numeric_limits::max(); + detail::write_network_order(buf, part_size); + buf += sizeof(part_size); + } + std::memcpy(buf, part_data, part_size); + buf += part_size; + } + + assert(static_cast(buf - encoded.data()) == mmsg_size); + return encoded; +} + +/* Decode an encoded message to multiple parts. + + The given output iterator must be a ForwardIterator to a container + holding zmq::message_t such as a zmq::multipart_t or various STL + containers. + + Returns the ForwardIterator advanced once past the last decoded + part. + + Throws: a std::out_of_range is thrown if the encoded part sizes + lead to exceeding the message data bounds. + + The decoding assumes the message is encoded in the manner + performed by zmq::encode(), see https://rfc.zeromq.org/spec/50/. + */ +template OutputIt decode(const message_t &encoded, OutputIt out) +{ + const unsigned char *source = encoded.data(); + const unsigned char *const limit = source + encoded.size(); + + while (source < limit) { + size_t part_size = *source++; + if (part_size == std::numeric_limits::max()) { + if (static_cast(limit - source) < sizeof(uint32_t)) { + throw std::out_of_range( + "Malformed encoding, overflow in reading size"); + } + part_size = detail::read_u32_network_order(source); + // the part size is allowed to be less than 0xFF + source += sizeof(uint32_t); + } + + if (static_cast(limit - source) < part_size) { + throw std::out_of_range("Malformed encoding, overflow in reading part"); + } + *out = message_t(source, part_size); + ++out; + source += part_size; + } + + assert(source == limit); + return out; +} + +#endif + + +#ifdef ZMQ_HAS_RVALUE_REFS + +/* + This class handles multipart messaging. It is the C++ equivalent of zmsg.h, + which is part of CZMQ (the high-level C binding). Furthermore, it is a major + improvement compared to zmsg.hpp, which is part of the examples in the ØMQ + Guide. Unnecessary copying is avoided by using move semantics to efficiently + add/remove parts. +*/ +class multipart_t +{ + private: + std::deque m_parts; + + public: + typedef std::deque::value_type value_type; + + typedef std::deque::iterator iterator; + typedef std::deque::const_iterator const_iterator; + + typedef std::deque::reverse_iterator reverse_iterator; + typedef std::deque::const_reverse_iterator const_reverse_iterator; + + // Default constructor + multipart_t() {} + + // Construct from socket receive + multipart_t(socket_ref socket) { recv(socket); } + + // Construct from memory block + multipart_t(const void *src, size_t size) { addmem(src, size); } + + // Construct from string + multipart_t(const std::string &string) { addstr(string); } + + // Construct from message part + multipart_t(message_t &&message) { add(std::move(message)); } + + // Move constructor + multipart_t(multipart_t &&other) { m_parts = std::move(other.m_parts); } + + // Move assignment operator + multipart_t &operator=(multipart_t &&other) + { + m_parts = std::move(other.m_parts); + return *this; + } + + // Destructor + virtual ~multipart_t() { clear(); } + + message_t &operator[](size_t n) { return m_parts[n]; } + + const message_t &operator[](size_t n) const { return m_parts[n]; } + + message_t &at(size_t n) { return m_parts.at(n); } + + const message_t &at(size_t n) const { return m_parts.at(n); } + + iterator begin() { return m_parts.begin(); } + + const_iterator begin() const { return m_parts.begin(); } + + const_iterator cbegin() const { return m_parts.cbegin(); } + + reverse_iterator rbegin() { return m_parts.rbegin(); } + + const_reverse_iterator rbegin() const { return m_parts.rbegin(); } + + iterator end() { return m_parts.end(); } + + const_iterator end() const { return m_parts.end(); } + + const_iterator cend() const { return m_parts.cend(); } + + reverse_iterator rend() { return m_parts.rend(); } + + const_reverse_iterator rend() const { return m_parts.rend(); } + + // Delete all parts + void clear() { m_parts.clear(); } + + // Get number of parts + size_t size() const { return m_parts.size(); } + + // Check if number of parts is zero + bool empty() const { return m_parts.empty(); } + + // Receive multipart message from socket + bool recv(socket_ref socket, int flags = 0) + { + clear(); + bool more = true; + while (more) { + message_t message; +#ifdef ZMQ_CPP11 + if (!socket.recv(message, static_cast(flags))) + return false; +#else + if (!socket.recv(&message, flags)) + return false; +#endif + more = message.more(); + add(std::move(message)); + } + return true; + } + + // Send multipart message to socket + bool send(socket_ref socket, int flags = 0) + { + flags &= ~(ZMQ_SNDMORE); + bool more = size() > 0; + while (more) { + message_t message = pop(); + more = size() > 0; +#ifdef ZMQ_CPP11 + if (!socket.send(message, static_cast( + (more ? ZMQ_SNDMORE : 0) | flags))) + return false; +#else + if (!socket.send(message, (more ? ZMQ_SNDMORE : 0) | flags)) + return false; +#endif + } + clear(); + return true; + } + + // Concatenate other multipart to front + void prepend(multipart_t &&other) + { + while (!other.empty()) + push(other.remove()); + } + + // Concatenate other multipart to back + void append(multipart_t &&other) + { + while (!other.empty()) + add(other.pop()); + } + + // Push memory block to front + void pushmem(const void *src, size_t size) + { + m_parts.push_front(message_t(src, size)); + } + + // Push memory block to back + void addmem(const void *src, size_t size) + { + m_parts.push_back(message_t(src, size)); + } + + // Push string to front + void pushstr(const std::string &string) + { + m_parts.push_front(message_t(string.data(), string.size())); + } + + // Push string to back + void addstr(const std::string &string) + { + m_parts.push_back(message_t(string.data(), string.size())); + } + + // Push type (fixed-size) to front + template void pushtyp(const T &type) + { + static_assert(!std::is_same::value, + "Use pushstr() instead of pushtyp()"); + m_parts.push_front(message_t(&type, sizeof(type))); + } + + // Push type (fixed-size) to back + template void addtyp(const T &type) + { + static_assert(!std::is_same::value, + "Use addstr() instead of addtyp()"); + m_parts.push_back(message_t(&type, sizeof(type))); + } + + // Push message part to front + void push(message_t &&message) { m_parts.push_front(std::move(message)); } + + // Push message part to back + void add(message_t &&message) { m_parts.push_back(std::move(message)); } + + // Alias to allow std::back_inserter() + void push_back(message_t &&message) { m_parts.push_back(std::move(message)); } + + // Pop string from front + std::string popstr() + { + std::string string(m_parts.front().data(), m_parts.front().size()); + m_parts.pop_front(); + return string; + } + + // Pop type (fixed-size) from front + template T poptyp() + { + static_assert(!std::is_same::value, + "Use popstr() instead of poptyp()"); + if (sizeof(T) != m_parts.front().size()) + throw std::runtime_error( + "Invalid type, size does not match the message size"); + T type = *m_parts.front().data(); + m_parts.pop_front(); + return type; + } + + // Pop message part from front + message_t pop() + { + message_t message = std::move(m_parts.front()); + m_parts.pop_front(); + return message; + } + + // Pop message part from back + message_t remove() + { + message_t message = std::move(m_parts.back()); + m_parts.pop_back(); + return message; + } + + // get message part from front + const message_t &front() { return m_parts.front(); } + + // get message part from back + const message_t &back() { return m_parts.back(); } + + // Get pointer to a specific message part + const message_t *peek(size_t index) const { return &m_parts[index]; } + + // Get a string copy of a specific message part + std::string peekstr(size_t index) const + { + std::string string(m_parts[index].data(), m_parts[index].size()); + return string; + } + + // Peek type (fixed-size) from front + template T peektyp(size_t index) const + { + static_assert(!std::is_same::value, + "Use peekstr() instead of peektyp()"); + if (sizeof(T) != m_parts[index].size()) + throw std::runtime_error( + "Invalid type, size does not match the message size"); + T type = *m_parts[index].data(); + return type; + } + + // Create multipart from type (fixed-size) + template static multipart_t create(const T &type) + { + multipart_t multipart; + multipart.addtyp(type); + return multipart; + } + + // Copy multipart + multipart_t clone() const + { + multipart_t multipart; + for (size_t i = 0; i < size(); i++) + multipart.addmem(m_parts[i].data(), m_parts[i].size()); + return multipart; + } + + // Dump content to string + std::string str() const + { + std::stringstream ss; + for (size_t i = 0; i < m_parts.size(); i++) { + const unsigned char *data = m_parts[i].data(); + size_t size = m_parts[i].size(); + + // Dump the message as text or binary + bool isText = true; + for (size_t j = 0; j < size; j++) { + if (data[j] < 32 || data[j] > 127) { + isText = false; + break; + } + } + ss << "\n[" << std::dec << std::setw(3) << std::setfill('0') << size + << "] "; + if (size >= 1000) { + ss << "... (too big to print)"; + continue; + } + for (size_t j = 0; j < size; j++) { + if (isText) + ss << static_cast(data[j]); + else + ss << std::hex << std::setw(2) << std::setfill('0') + << static_cast(data[j]); + } + } + return ss.str(); + } + + // Check if equal to other multipart + bool equal(const multipart_t *other) const + { + if (size() != other->size()) + return false; + for (size_t i = 0; i < size(); i++) + if (*peek(i) != *other->peek(i)) + return false; + return true; + } + +#ifdef ZMQ_CPP11 + + // Return single part message_t encoded from this multipart_t. + message_t encode() const { return zmq::encode(*this); } + + // Decode encoded message into multiple parts and append to self. + void decode_append(const message_t &encoded) + { + zmq::decode(encoded, std::back_inserter(*this)); + } + + // Return a new multipart_t containing the decoded message_t. + static multipart_t decode(const message_t &encoded) + { + multipart_t tmp; + zmq::decode(encoded, std::back_inserter(tmp)); + return tmp; + } + +#endif + + private: + // Disable implicit copying (moving is more efficient) + multipart_t(const multipart_t &other) ZMQ_DELETED_FUNCTION; + void operator=(const multipart_t &other) ZMQ_DELETED_FUNCTION; +}; // class multipart_t + +inline std::ostream &operator<<(std::ostream &os, const multipart_t &msg) +{ + return os << msg.str(); +} + +#endif // ZMQ_HAS_RVALUE_REFS + +#if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER) +class active_poller_t +{ + public: + active_poller_t() = default; + ~active_poller_t() = default; + + active_poller_t(const active_poller_t &) = delete; + active_poller_t &operator=(const active_poller_t &) = delete; + + active_poller_t(active_poller_t &&src) = default; + active_poller_t &operator=(active_poller_t &&src) = default; + + using handler_type = std::function; + + void add(zmq::socket_ref socket, event_flags events, handler_type handler) + { + if (!handler) + throw std::invalid_argument("null handler in active_poller_t::add"); + auto ret = handlers.emplace( + socket, std::make_shared(std::move(handler))); + if (!ret.second) + throw error_t(EINVAL); // already added + try { + base_poller.add(socket, events, ret.first->second.get()); + need_rebuild = true; + } + catch (...) { + // rollback + handlers.erase(socket); + throw; + } + } + + void remove(zmq::socket_ref socket) + { + base_poller.remove(socket); + handlers.erase(socket); + need_rebuild = true; + } + + void modify(zmq::socket_ref socket, event_flags events) + { + base_poller.modify(socket, events); + } + + size_t wait(std::chrono::milliseconds timeout) + { + if (need_rebuild) { + poller_events.resize(handlers.size()); + poller_handlers.clear(); + poller_handlers.reserve(handlers.size()); + for (const auto &handler : handlers) { + poller_handlers.push_back(handler.second); + } + need_rebuild = false; + } + const auto count = base_poller.wait_all(poller_events, timeout); + std::for_each(poller_events.begin(), + poller_events.begin() + static_cast(count), + [](decltype(base_poller)::event_type &event) { + assert(event.user_data != nullptr); + (*event.user_data)(event.events); + }); + return count; + } + + ZMQ_NODISCARD bool empty() const noexcept { return handlers.empty(); } + + size_t size() const noexcept { return handlers.size(); } + + private: + bool need_rebuild{false}; + + poller_t base_poller{}; + std::unordered_map> handlers{}; + std::vector poller_events{}; + std::vector> poller_handlers{}; +}; // class active_poller_t +#endif // defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11) && defined(ZMQ_HAVE_POLLER) + + +} // namespace zmq + +#endif // __ZMQ_ADDON_HPP_INCLUDED__ diff --git a/external/src/cryptonote/LICENSE b/external/src/cryptonote/LICENSE new file mode 100644 index 0000000..72da941 --- /dev/null +++ b/external/src/cryptonote/LICENSE @@ -0,0 +1,41 @@ +Copyright (c) 2014-2021, The Monero Project + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Parts of the project are originally copyright (c) 2012-2013 The Cryptonote +developers + +Parts of the project are originally copyright (c) 2014 The Boolberry +developers, distributed under the MIT licence: + + Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + diff --git a/external/src/cryptonote/crypto-ops-data.c b/external/src/cryptonote/crypto-ops-data.c new file mode 100644 index 0000000..d16fd94 --- /dev/null +++ b/external/src/cryptonote/crypto-ops-data.c @@ -0,0 +1,879 @@ +// Copyright (c) 2014-2020, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +#include + +#include "crypto-ops.h" + +/* sqrt(x) is such an integer y that 0 <= y <= p - 1, y % 2 = 0, and y^2 = x (mod p). */ +/* d = -121665 / 121666 */ +const fe fe_d = {-10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116}; /* d */ +const fe fe_sqrtm1 = {-32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482}; /* sqrt(-1) */ +const fe fe_d2 = {-21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199}; /* 2 * d */ + +/* base[i][j] = (j+1)*256^i*B */ +const ge_precomp ge_base[32][8] = { + { + {{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605}, + {-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378}, + {-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546}}, + {{-12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303}, + {-21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081}, + {26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697}}, + {{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024}, + {16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574}, + {30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357}}, + {{-17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540}, + {23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397}, + {7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325}}, + {{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380}, + {4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306}, + {19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942}}, + {{-15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777}, + {-8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737}, + {-18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652}}, + {{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766}, + {-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701}, + {28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300}}, + {{14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726}, + {-7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955}, + {27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425}} + }, { + {{-13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171}, + {27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510}, + {17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660}}, + {{-10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639}, + {29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963}, + {5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950}}, + {{-27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568}, + {12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335}, + {25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628}}, + {{-26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007}, + {-2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772}, + {-22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653}}, + {{2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567}, + {13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686}, + {21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372}}, + {{-13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887}, + {-23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954}, + {-29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953}}, + {{24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833}, + {-16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532}, + {-22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876}}, + {{2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268}, + {33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214}, + {1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038}} + }, { + {{6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800}, + {4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645}, + {-4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664}}, + {{1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933}, + {-25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182}, + {-17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222}}, + {{-18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991}, + {20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880}, + {9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092}}, + {{-16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295}, + {19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788}, + {8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553}}, + {{-15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026}, + {11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347}, + {-18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033}}, + {{-23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395}, + {-27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278}, + {1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890}}, + {{32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995}, + {-30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596}, + {-11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891}}, + {{31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060}, + {11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608}, + {-20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606}} + }, { + {{7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389}, + {-19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016}, + {-11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341}}, + {{-22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505}, + {14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553}, + {-28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655}}, + {{15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220}, + {12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631}, + {-4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099}}, + {{26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556}, + {14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749}, + {236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930}}, + {{1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391}, + {5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253}, + {20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066}}, + {{24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958}, + {-11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082}, + {-28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383}}, + {{-30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521}, + {-11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807}, + {23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948}}, + {{9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134}, + {-32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455}, + {27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629}} + }, { + {{-8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069}, + {-32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746}, + {24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919}}, + {{11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837}, + {8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906}, + {-28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771}}, + {{-25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817}, + {10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098}, + {10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409}}, + {{-12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504}, + {-26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727}, + {28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420}}, + {{-32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003}, + {-1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605}, + {-30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384}}, + {{-26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701}, + {-23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683}, + {29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708}}, + {{-3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563}, + {-19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260}, + {-5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387}}, + {{-19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672}, + {23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686}, + {-24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665}} + }, { + {{11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182}, + {-31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277}, + {14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628}}, + {{-4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474}, + {-26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539}, + {-25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822}}, + {{-10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970}, + {19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756}, + {-24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508}}, + {{-26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683}, + {-10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655}, + {-20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158}}, + {{-4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125}, + {-15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839}, + {-20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664}}, + {{27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294}, + {-18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899}, + {-11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070}}, + {{3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294}, + {-15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949}, + {-21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083}}, + {{31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420}, + {-5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940}, + {29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396}} + }, { + {{-12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567}, + {20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127}, + {-16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294}}, + {{-12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887}, + {22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964}, + {16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195}}, + {{9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244}, + {24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999}, + {-1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762}}, + {{-18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274}, + {-33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236}, + {-16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605}}, + {{-13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761}, + {-22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884}, + {-6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482}}, + {{-24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638}, + {-11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490}, + {-32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170}}, + {{5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736}, + {10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124}, + {-17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392}}, + {{8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029}, + {6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048}, + {28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958}} + }, { + {{24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593}, + {26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071}, + {-11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692}}, + {{11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687}, + {-160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441}, + {-20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001}}, + {{-938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460}, + {-19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007}, + {-21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762}}, + {{15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005}, + {-9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674}, + {4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035}}, + {{7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590}, + {-2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957}, + {-30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812}}, + {{33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740}, + {-18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122}, + {-27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158}}, + {{8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885}, + {26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140}, + {19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857}}, + {{801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155}, + {19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260}, + {19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483}} + }, { + {{-3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677}, + {32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815}, + {22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751}}, + {{-16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203}, + {-11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208}, + {1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230}}, + {{16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850}, + {-21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389}, + {-9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968}}, + {{-11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689}, + {14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880}, + {5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304}}, + {{30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632}, + {-3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412}, + {20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566}}, + {{-20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038}, + {-26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232}, + {-1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943}}, + {{17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856}, + {23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738}, + {15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971}}, + {{-27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718}, + {-13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697}, + {-11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883}} + }, { + {{5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912}, + {-26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358}, + {3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849}}, + {{29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307}, + {-14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977}, + {-6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335}}, + {{-29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644}, + {-22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616}, + {-27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735}}, + {{-21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099}, + {29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341}, + {-936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336}}, + {{-23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646}, + {31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425}, + {-17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388}}, + {{-31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743}, + {-16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822}, + {-8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462}}, + {{18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985}, + {9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702}, + {-22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797}}, + {{21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293}, + {27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100}, + {19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688}} + }, { + {{12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186}, + {2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610}, + {-2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707}}, + {{7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220}, + {915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025}, + {32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044}}, + {{32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992}, + {-4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027}, + {21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197}}, + {{8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901}, + {31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952}, + {19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878}}, + {{-28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390}, + {32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730}, + {2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730}}, + {{-19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180}, + {-30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272}, + {-15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715}}, + {{-22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970}, + {-31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772}, + {-17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865}}, + {{15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750}, + {20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373}, + {32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348}} + }, { + {{9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144}, + {-22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195}, + {5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086}}, + {{-13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684}, + {-8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518}, + {-2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233}}, + {{-5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793}, + {-2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794}, + {580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435}}, + {{23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921}, + {13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518}, + {2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563}}, + {{14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278}, + {-27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024}, + {4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030}}, + {{10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783}, + {27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717}, + {6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844}}, + {{14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333}, + {16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048}, + {22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760}}, + {{-4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760}, + {-15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757}, + {-2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112}} + }, { + {{-19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468}, + {3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184}, + {10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289}}, + {{15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066}, + {24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882}, + {13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226}}, + {{16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101}, + {29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279}, + {-6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811}}, + {{27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709}, + {20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714}, + {-2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121}}, + {{9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464}, + {12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847}, + {13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400}}, + {{4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414}, + {-15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158}, + {17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045}}, + {{-461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415}, + {-5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459}, + {-31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079}}, + {{21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412}, + {-20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743}, + {-14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836}} + }, { + {{12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022}, + {18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429}, + {-6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065}}, + {{30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861}, + {10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000}, + {-33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101}}, + {{32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815}, + {29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642}, + {10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966}}, + {{25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574}, + {-21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742}, + {-18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689}}, + {{12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020}, + {-10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772}, + {3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982}}, + {{-14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953}, + {-16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218}, + {-17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265}}, + {{29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073}, + {-3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325}, + {-11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798}}, + {{-4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870}, + {-7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863}, + {-13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927}} + }, { + {{-2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267}, + {-9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663}, + {22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862}}, + {{-25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673}, + {15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943}, + {15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020}}, + {{-4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238}, + {11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064}, + {14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795}}, + {{15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052}, + {-10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904}, + {29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531}}, + {{-13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979}, + {-5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841}, + {10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431}}, + {{10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324}, + {-31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940}, + {10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320}}, + {{-15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184}, + {14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114}, + {30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878}}, + {{12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784}, + {-2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091}, + {-16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585}} + }, { + {{-8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208}, + {10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864}, + {17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661}}, + {{7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233}, + {26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212}, + {-12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525}}, + {{-24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068}, + {9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397}, + {-8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988}}, + {{5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889}, + {32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038}, + {14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697}}, + {{20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875}, + {-25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905}, + {-25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656}}, + {{11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818}, + {27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714}, + {10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203}}, + {{20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931}, + {-30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024}, + {-23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084}}, + {{-1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204}, + {20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817}, + {27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667}} + }, { + {{11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504}, + {-12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768}, + {-19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255}}, + {{6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790}, + {1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438}, + {-22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333}}, + {{17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971}, + {31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905}, + {29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409}}, + {{12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409}, + {6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499}, + {-8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363}}, + {{28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664}, + {-11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324}, + {-21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940}}, + {{13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990}, + {-17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914}, + {-25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290}}, + {{24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257}, + {-6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433}, + {-16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236}}, + {{-12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045}, + {11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093}, + {-1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347}} + }, { + {{-28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191}, + {-15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507}, + {-12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906}}, + {{3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018}, + {-16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109}, + {-23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926}}, + {{-24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528}, + {8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625}, + {-32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286}}, + {{2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033}, + {27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866}, + {21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896}}, + {{30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075}, + {26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347}, + {-22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437}}, + {{-5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165}, + {-18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588}, + {-32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193}}, + {{-19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017}, + {-28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883}, + {21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961}}, + {{8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043}, + {29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663}, + {-20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362}} + }, { + {{-33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860}, + {2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466}, + {-24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063}}, + {{-26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997}, + {-1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295}, + {-13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369}}, + {{9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385}, + {18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109}, + {2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906}}, + {{4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424}, + {-19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185}, + {7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962}}, + {{-7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325}, + {10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593}, + {696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404}}, + {{-11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644}, + {17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801}, + {26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804}}, + {{-31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884}, + {-586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577}, + {-9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849}}, + {{32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473}, + {-8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644}, + {-2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319}} + }, { + {{-11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599}, + {-9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768}, + {-27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084}}, + {{-27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328}, + {-15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369}, + {20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920}}, + {{12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815}, + {-32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025}, + {-21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397}}, + {{-20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448}, + {6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981}, + {30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165}}, + {{32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501}, + {17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073}, + {-1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861}}, + {{14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845}, + {-1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211}, + {18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870}}, + {{10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096}, + {33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803}, + {-32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168}}, + {{30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965}, + {-14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505}, + {18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598}} + }, { + {{5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782}, + {5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900}, + {-31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479}}, + {{-12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208}, + {8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232}, + {17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719}}, + {{16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271}, + {-4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326}, + {-8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132}}, + {{14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300}, + {8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570}, + {15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670}}, + {{-2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994}, + {-12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913}, + {31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317}}, + {{-25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730}, + {842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096}, + {-4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078}}, + {{-15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411}, + {-19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905}, + {-9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654}}, + {{-28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870}, + {-23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498}, + {12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579}} + }, { + {{14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677}, + {10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647}, + {-2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743}}, + {{-25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468}, + {21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375}, + {-25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155}}, + {{6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725}, + {-12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612}, + {-10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943}}, + {{-30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944}, + {30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928}, + {9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406}}, + {{22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139}, + {-8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963}, + {-31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693}}, + {{1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734}, + {-448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680}, + {-24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410}}, + {{-9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931}, + {-16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654}, + {22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710}}, + {{29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180}, + {-26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684}, + {-10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895}} + }, { + {{22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501}, + {-11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413}, + {6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880}}, + {{-8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874}, + {22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962}, + {-7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899}}, + {{21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152}, + {9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063}, + {7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080}}, + {{-9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146}, + {-17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183}, + {-19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133}}, + {{-32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421}, + {-3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622}, + {-4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197}}, + {{2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663}, + {31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753}, + {4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755}}, + {{-9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862}, + {-26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118}, + {26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171}}, + {{15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380}, + {16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824}, + {28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270}} + }, { + {{-817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438}, + {-31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584}, + {-594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562}}, + {{30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471}, + {18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610}, + {19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269}}, + {{-30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650}, + {14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369}, + {19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461}}, + {{30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462}, + {-5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793}, + {-2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218}}, + {{-24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226}, + {18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019}, + {-15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037}}, + {{31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171}, + {-17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132}, + {-28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841}}, + {{21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181}, + {-33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210}, + {-1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040}}, + {{3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935}, + {24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105}, + {-28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814}} + }, { + {{793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852}, + {5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581}, + {-4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646}}, + {{10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844}, + {10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025}, + {27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453}}, + {{-23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068}, + {4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192}, + {-17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921}}, + {{-9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259}, + {-12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426}, + {-5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072}}, + {{-17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305}, + {13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832}, + {28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943}}, + {{-16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011}, + {24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447}, + {17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494}}, + {{-28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245}, + {-20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859}, + {28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915}}, + {{16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707}, + {10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848}, + {-11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224}} + }, { + {{-25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391}, + {15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215}, + {-23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101}}, + {{23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713}, + {21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849}, + {-7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930}}, + {{-29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940}, + {-21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031}, + {-17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404}}, + {{-25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243}, + {-23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116}, + {-24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525}}, + {{-23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509}, + {-10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883}, + {15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865}}, + {{-3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660}, + {4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273}, + {-28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138}}, + {{-25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560}, + {-10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135}, + {2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941}}, + {{-4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739}, + {18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756}, + {-30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819}} + }, { + {{-6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347}, + {-27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028}, + {21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075}}, + {{16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799}, + {-2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609}, + {-25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817}}, + {{-23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989}, + {-30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523}, + {4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278}}, + {{31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045}, + {19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377}, + {24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480}}, + {{17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016}, + {510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426}, + {18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525}}, + {{13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396}, + {9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080}, + {12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892}}, + {{15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275}, + {11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074}, + {20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140}}, + {{-16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717}, + {-1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101}, + {24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127}} + }, { + {{-12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632}, + {-26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415}, + {-31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160}}, + {{31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876}, + {22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625}, + {-15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478}}, + {{27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164}, + {26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595}, + {-7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248}}, + {{-16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858}, + {15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193}, + {8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184}}, + {{-18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942}, + {-1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635}, + {21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948}}, + {{11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935}, + {-25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415}, + {-15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416}}, + {{-7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018}, + {4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778}, + {366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659}}, + {{-24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385}, + {18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503}, + {476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329}} + }, { + {{20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056}, + {-13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838}, + {24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948}}, + {{-3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691}, + {-15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118}, + {-23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517}}, + {{-20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269}, + {-6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904}, + {-23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589}}, + {{-28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193}, + {-7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910}, + {-30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930}}, + {{-7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667}, + {25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481}, + {-9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876}}, + {{22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640}, + {-8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278}, + {-21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112}}, + {{26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272}, + {17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012}, + {-10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221}}, + {{30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046}, + {13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345}, + {-19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310}} + }, { + {{19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937}, + {31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636}, + {-9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008}}, + {{-2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429}, + {-15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576}, + {31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066}}, + {{-9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490}, + {-12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104}, + {33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053}}, + {{31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275}, + {-20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511}, + {22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095}}, + {{-28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439}, + {23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939}, + {-23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424}}, + {{2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310}, + {3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608}, + {-32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079}}, + {{-23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101}, + {21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418}, + {18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576}}, + {{30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356}, + {9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996}, + {-26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099}} + }, { + {{-26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728}, + {-13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658}, + {-10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242}}, + {{-21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001}, + {-4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766}, + {18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373}}, + {{26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458}, + {-17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628}, + {-13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657}}, + {{-23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062}, + {25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616}, + {31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014}}, + {{24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383}, + {-25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814}, + {-20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718}}, + {{30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417}, + {2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222}, + {33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444}}, + {{-20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597}, + {23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970}, + {1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799}}, + {{-5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647}, + {13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511}, + {-29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032}} + }, { + {{9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834}, + {-23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461}, + {29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062}}, + {{-25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516}, + {-20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547}, + {-24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240}}, + {{-17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038}, + {-33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741}, + {16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103}}, + {{-19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747}, + {-1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323}, + {31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016}}, + {{-14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373}, + {15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228}, + {-2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141}}, + {{16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399}, + {11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831}, + {-185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376}}, + {{-32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313}, + {-18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958}, + {-6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577}}, + {{-22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743}, + {29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684}, + {-20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476}} + } +}; + +const ge_precomp ge_Bi[8] = { + {{25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605}, + {-12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378}, + {-8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546}}, {{15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024}, + {16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574}, + {30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357}}, {{10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380}, + {4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306}, + {19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942}}, {{5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766}, + {-30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701}, + {28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300}}, {{-22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877}, + {-6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951}, + {4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784}}, {{-25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436}, + {25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918}, + {23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877}}, {{-33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800}, + {-25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305}, + {-13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300}}, {{-3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876}, + {-24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619}, + {-3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683}} +}; + +/* A = 2 * (1 - d) / (1 + d) = 486662 */ +const fe fe_ma2 = {-12721188, -3529, 0, 0, 0, 0, 0, 0, 0, 0}; /* -A^2 */ +const fe fe_ma = {-486662, 0, 0, 0, 0, 0, 0, 0, 0, 0}; /* -A */ +const fe fe_fffb1 = {-31702527, -2466483, -26106795, -12203692, -12169197, -321052, 14850977, -10296299, -16929438, -407568}; /* sqrt(-2 * A * (A + 2)) */ +const fe fe_fffb2 = {8166131, -6741800, -17040804, 3154616, 21461005, 1466302, -30876704, -6368709, 10503587, -13363080}; /* sqrt(2 * A * (A + 2)) */ +const fe fe_fffb3 = {-13620103, 14639558, 4532995, 7679154, 16815101, -15883539, -22863840, -14813421, 13716513, -6477756}; /* sqrt(-sqrt(-1) * A * (A + 2)) */ +const fe fe_fffb4 = {-21786234, -12173074, 21573800, 4524538, -4645904, 16204591, 8012863, -8444712, 3212926, 6885324}; /* sqrt(sqrt(-1) * A * (A + 2)) */ +const ge_p3 ge_p3_identity = { {0}, {1, 0}, {1, 0}, {0} }; +const ge_p3 ge_p3_H = { + {7329926, -15101362, 31411471, 7614783, 27996851, -3197071, -11157635, -6878293, 466949, -7986503}, + {5858699, 5096796, 21321203, -7536921, -5553480, -11439507, -5627669, 15045946, 19977121, 5275251}, + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {23443568, -5110398, -8776029, -4345135, 6889568, -14710814, 7474843, 3279062, 14550766, -7453428} +}; diff --git a/external/src/cryptonote/crypto-ops.c b/external/src/cryptonote/crypto-ops.c new file mode 100644 index 0000000..ad0a793 --- /dev/null +++ b/external/src/cryptonote/crypto-ops.c @@ -0,0 +1,3845 @@ +// Copyright (c) 2014-2020, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +#include +#include + +#include "crypto-ops.h" + +#ifdef _MSC_VER +#pragma warning(disable: 4146 4242 4244 4711 5045) +#endif + +/* Predeclarations */ + +static void fe_mul(fe, const fe, const fe); +static void fe_sq(fe, const fe); +static void ge_madd(ge_p1p1 *, const ge_p3 *, const ge_precomp *); +static void ge_msub(ge_p1p1 *, const ge_p3 *, const ge_precomp *); +static void ge_p2_0(ge_p2 *); +static void ge_p3_dbl(ge_p1p1 *, const ge_p3 *); +static void fe_divpowm1(fe, const fe, const fe); + +/* Common functions */ + +uint64_t load_3(const unsigned char *in) { + uint64_t result; + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + return result; +} + +uint64_t load_4(const unsigned char *in) +{ + uint64_t result; + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + result |= ((uint64_t) in[3]) << 24; + return result; +} + +/* From fe_0.c */ + +/* +h = 0 +*/ + +static void fe_0(fe h) { + h[0] = 0; + h[1] = 0; + h[2] = 0; + h[3] = 0; + h[4] = 0; + h[5] = 0; + h[6] = 0; + h[7] = 0; + h[8] = 0; + h[9] = 0; +} + +/* From fe_1.c */ + +/* +h = 1 +*/ + +static void fe_1(fe h) { + h[0] = 1; + h[1] = 0; + h[2] = 0; + h[3] = 0; + h[4] = 0; + h[5] = 0; + h[6] = 0; + h[7] = 0; + h[8] = 0; + h[9] = 0; +} + +/* From fe_add.c */ + +/* +h = f + g +Can overlap h with f or g. + +Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + +Postconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +*/ + +void fe_add(fe h, const fe f, const fe g) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t h0 = f0 + g0; + int32_t h1 = f1 + g1; + int32_t h2 = f2 + g2; + int32_t h3 = f3 + g3; + int32_t h4 = f4 + g4; + int32_t h5 = f5 + g5; + int32_t h6 = f6 + g6; + int32_t h7 = f7 + g7; + int32_t h8 = f8 + g8; + int32_t h9 = f9 + g9; + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* From fe_cmov.c */ + +/* +Replace (f,g) with (g,g) if b == 1; +replace (f,g) with (f,g) if b == 0. + +Preconditions: b in {0,1}. +*/ + +static void fe_cmov(fe f, const fe g, unsigned int b) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t x0 = f0 ^ g0; + int32_t x1 = f1 ^ g1; + int32_t x2 = f2 ^ g2; + int32_t x3 = f3 ^ g3; + int32_t x4 = f4 ^ g4; + int32_t x5 = f5 ^ g5; + int32_t x6 = f6 ^ g6; + int32_t x7 = f7 ^ g7; + int32_t x8 = f8 ^ g8; + int32_t x9 = f9 ^ g9; + assert((((b - 1) & ~b) | ((b - 2) & ~(b - 1))) == (unsigned int) -1); + b = -b; + x0 &= b; + x1 &= b; + x2 &= b; + x3 &= b; + x4 &= b; + x5 &= b; + x6 &= b; + x7 &= b; + x8 &= b; + x9 &= b; + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; + f[5] = f5 ^ x5; + f[6] = f6 ^ x6; + f[7] = f7 ^ x7; + f[8] = f8 ^ x8; + f[9] = f9 ^ x9; +} + +/* From fe_copy.c */ + +/* +h = f +*/ + +static void fe_copy(fe h, const fe f) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + h[0] = f0; + h[1] = f1; + h[2] = f2; + h[3] = f3; + h[4] = f4; + h[5] = f5; + h[6] = f6; + h[7] = f7; + h[8] = f8; + h[9] = f9; +} + +/* From fe_invert.c */ + +void fe_invert(fe out, const fe z) { + fe t0; + fe t1; + fe t2; + fe t3; + int i; + + fe_sq(t0, z); + fe_sq(t1, t0); + fe_sq(t1, t1); + fe_mul(t1, z, t1); + fe_mul(t0, t0, t1); + fe_sq(t2, t0); + fe_mul(t1, t1, t2); + fe_sq(t2, t1); + for (i = 0; i < 4; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t2, t1); + fe_sq(t2, t1); + for (i = 0; i < 9; ++i) { + fe_sq(t2, t2); + } + fe_mul(t2, t2, t1); + fe_sq(t3, t2); + for (i = 0; i < 19; ++i) { + fe_sq(t3, t3); + } + fe_mul(t2, t3, t2); + fe_sq(t2, t2); + for (i = 0; i < 9; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t2, t1); + fe_sq(t2, t1); + for (i = 0; i < 49; ++i) { + fe_sq(t2, t2); + } + fe_mul(t2, t2, t1); + fe_sq(t3, t2); + for (i = 0; i < 99; ++i) { + fe_sq(t3, t3); + } + fe_mul(t2, t3, t2); + fe_sq(t2, t2); + for (i = 0; i < 49; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t2, t1); + fe_sq(t1, t1); + for (i = 0; i < 4; ++i) { + fe_sq(t1, t1); + } + fe_mul(out, t1, t0); + + return; +} + +/* From fe_isnegative.c */ + +/* +return 1 if f is in {1,3,5,...,q-2} +return 0 if f is in {0,2,4,...,q-1} + +Preconditions: + |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +*/ + +static int fe_isnegative(const fe f) { + unsigned char s[32]; + fe_tobytes(s, f); + return s[0] & 1; +} + +/* From fe_isnonzero.c, modified */ + +static int fe_isnonzero(const fe f) { + unsigned char s[32]; + fe_tobytes(s, f); + return (((int) (s[0] | s[1] | s[2] | s[3] | s[4] | s[5] | s[6] | s[7] | s[8] | + s[9] | s[10] | s[11] | s[12] | s[13] | s[14] | s[15] | s[16] | s[17] | + s[18] | s[19] | s[20] | s[21] | s[22] | s[23] | s[24] | s[25] | s[26] | + s[27] | s[28] | s[29] | s[30] | s[31]) - 1) >> 8) + 1; +} + +/* From fe_mul.c */ + +/* +h = f * g +Can overlap h with f or g. + +Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + +Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. +*/ + +/* +Notes on implementation strategy: + +Using schoolbook multiplication. +Karatsuba would save a little in some cost models. + +Most multiplications by 2 and 19 are 32-bit precomputations; +cheaper than 64-bit postcomputations. + +There is one remaining multiplication by 19 in the carry chain; +one *19 precomputation can be merged into this, +but the resulting data flow is considerably less clean. + +There are 12 carries below. +10 of them are 2-way parallelizable and vectorizable. +Can get away with 11 carries, but then data flow is much deeper. + +With tighter constraints on inputs can squeeze carries into int32. +*/ + +static void fe_mul(fe h, const fe f, const fe g) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */ + int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ + int32_t g3_19 = 19 * g3; + int32_t g4_19 = 19 * g4; + int32_t g5_19 = 19 * g5; + int32_t g6_19 = 19 * g6; + int32_t g7_19 = 19 * g7; + int32_t g8_19 = 19 * g8; + int32_t g9_19 = 19 * g9; + int32_t f1_2 = 2 * f1; + int32_t f3_2 = 2 * f3; + int32_t f5_2 = 2 * f5; + int32_t f7_2 = 2 * f7; + int32_t f9_2 = 2 * f9; + int64_t f0g0 = f0 * (int64_t) g0; + int64_t f0g1 = f0 * (int64_t) g1; + int64_t f0g2 = f0 * (int64_t) g2; + int64_t f0g3 = f0 * (int64_t) g3; + int64_t f0g4 = f0 * (int64_t) g4; + int64_t f0g5 = f0 * (int64_t) g5; + int64_t f0g6 = f0 * (int64_t) g6; + int64_t f0g7 = f0 * (int64_t) g7; + int64_t f0g8 = f0 * (int64_t) g8; + int64_t f0g9 = f0 * (int64_t) g9; + int64_t f1g0 = f1 * (int64_t) g0; + int64_t f1g1_2 = f1_2 * (int64_t) g1; + int64_t f1g2 = f1 * (int64_t) g2; + int64_t f1g3_2 = f1_2 * (int64_t) g3; + int64_t f1g4 = f1 * (int64_t) g4; + int64_t f1g5_2 = f1_2 * (int64_t) g5; + int64_t f1g6 = f1 * (int64_t) g6; + int64_t f1g7_2 = f1_2 * (int64_t) g7; + int64_t f1g8 = f1 * (int64_t) g8; + int64_t f1g9_38 = f1_2 * (int64_t) g9_19; + int64_t f2g0 = f2 * (int64_t) g0; + int64_t f2g1 = f2 * (int64_t) g1; + int64_t f2g2 = f2 * (int64_t) g2; + int64_t f2g3 = f2 * (int64_t) g3; + int64_t f2g4 = f2 * (int64_t) g4; + int64_t f2g5 = f2 * (int64_t) g5; + int64_t f2g6 = f2 * (int64_t) g6; + int64_t f2g7 = f2 * (int64_t) g7; + int64_t f2g8_19 = f2 * (int64_t) g8_19; + int64_t f2g9_19 = f2 * (int64_t) g9_19; + int64_t f3g0 = f3 * (int64_t) g0; + int64_t f3g1_2 = f3_2 * (int64_t) g1; + int64_t f3g2 = f3 * (int64_t) g2; + int64_t f3g3_2 = f3_2 * (int64_t) g3; + int64_t f3g4 = f3 * (int64_t) g4; + int64_t f3g5_2 = f3_2 * (int64_t) g5; + int64_t f3g6 = f3 * (int64_t) g6; + int64_t f3g7_38 = f3_2 * (int64_t) g7_19; + int64_t f3g8_19 = f3 * (int64_t) g8_19; + int64_t f3g9_38 = f3_2 * (int64_t) g9_19; + int64_t f4g0 = f4 * (int64_t) g0; + int64_t f4g1 = f4 * (int64_t) g1; + int64_t f4g2 = f4 * (int64_t) g2; + int64_t f4g3 = f4 * (int64_t) g3; + int64_t f4g4 = f4 * (int64_t) g4; + int64_t f4g5 = f4 * (int64_t) g5; + int64_t f4g6_19 = f4 * (int64_t) g6_19; + int64_t f4g7_19 = f4 * (int64_t) g7_19; + int64_t f4g8_19 = f4 * (int64_t) g8_19; + int64_t f4g9_19 = f4 * (int64_t) g9_19; + int64_t f5g0 = f5 * (int64_t) g0; + int64_t f5g1_2 = f5_2 * (int64_t) g1; + int64_t f5g2 = f5 * (int64_t) g2; + int64_t f5g3_2 = f5_2 * (int64_t) g3; + int64_t f5g4 = f5 * (int64_t) g4; + int64_t f5g5_38 = f5_2 * (int64_t) g5_19; + int64_t f5g6_19 = f5 * (int64_t) g6_19; + int64_t f5g7_38 = f5_2 * (int64_t) g7_19; + int64_t f5g8_19 = f5 * (int64_t) g8_19; + int64_t f5g9_38 = f5_2 * (int64_t) g9_19; + int64_t f6g0 = f6 * (int64_t) g0; + int64_t f6g1 = f6 * (int64_t) g1; + int64_t f6g2 = f6 * (int64_t) g2; + int64_t f6g3 = f6 * (int64_t) g3; + int64_t f6g4_19 = f6 * (int64_t) g4_19; + int64_t f6g5_19 = f6 * (int64_t) g5_19; + int64_t f6g6_19 = f6 * (int64_t) g6_19; + int64_t f6g7_19 = f6 * (int64_t) g7_19; + int64_t f6g8_19 = f6 * (int64_t) g8_19; + int64_t f6g9_19 = f6 * (int64_t) g9_19; + int64_t f7g0 = f7 * (int64_t) g0; + int64_t f7g1_2 = f7_2 * (int64_t) g1; + int64_t f7g2 = f7 * (int64_t) g2; + int64_t f7g3_38 = f7_2 * (int64_t) g3_19; + int64_t f7g4_19 = f7 * (int64_t) g4_19; + int64_t f7g5_38 = f7_2 * (int64_t) g5_19; + int64_t f7g6_19 = f7 * (int64_t) g6_19; + int64_t f7g7_38 = f7_2 * (int64_t) g7_19; + int64_t f7g8_19 = f7 * (int64_t) g8_19; + int64_t f7g9_38 = f7_2 * (int64_t) g9_19; + int64_t f8g0 = f8 * (int64_t) g0; + int64_t f8g1 = f8 * (int64_t) g1; + int64_t f8g2_19 = f8 * (int64_t) g2_19; + int64_t f8g3_19 = f8 * (int64_t) g3_19; + int64_t f8g4_19 = f8 * (int64_t) g4_19; + int64_t f8g5_19 = f8 * (int64_t) g5_19; + int64_t f8g6_19 = f8 * (int64_t) g6_19; + int64_t f8g7_19 = f8 * (int64_t) g7_19; + int64_t f8g8_19 = f8 * (int64_t) g8_19; + int64_t f8g9_19 = f8 * (int64_t) g9_19; + int64_t f9g0 = f9 * (int64_t) g0; + int64_t f9g1_38 = f9_2 * (int64_t) g1_19; + int64_t f9g2_19 = f9 * (int64_t) g2_19; + int64_t f9g3_38 = f9_2 * (int64_t) g3_19; + int64_t f9g4_19 = f9 * (int64_t) g4_19; + int64_t f9g5_38 = f9_2 * (int64_t) g5_19; + int64_t f9g6_19 = f9 * (int64_t) g6_19; + int64_t f9g7_38 = f9_2 * (int64_t) g7_19; + int64_t f9g8_19 = f9 * (int64_t) g8_19; + int64_t f9g9_38 = f9_2 * (int64_t) g9_19; + int64_t h0 = f0g0+f1g9_38+f2g8_19+f3g7_38+f4g6_19+f5g5_38+f6g4_19+f7g3_38+f8g2_19+f9g1_38; + int64_t h1 = f0g1+f1g0 +f2g9_19+f3g8_19+f4g7_19+f5g6_19+f6g5_19+f7g4_19+f8g3_19+f9g2_19; + int64_t h2 = f0g2+f1g1_2 +f2g0 +f3g9_38+f4g8_19+f5g7_38+f6g6_19+f7g5_38+f8g4_19+f9g3_38; + int64_t h3 = f0g3+f1g2 +f2g1 +f3g0 +f4g9_19+f5g8_19+f6g7_19+f7g6_19+f8g5_19+f9g4_19; + int64_t h4 = f0g4+f1g3_2 +f2g2 +f3g1_2 +f4g0 +f5g9_38+f6g8_19+f7g7_38+f8g6_19+f9g5_38; + int64_t h5 = f0g5+f1g4 +f2g3 +f3g2 +f4g1 +f5g0 +f6g9_19+f7g8_19+f8g7_19+f9g6_19; + int64_t h6 = f0g6+f1g5_2 +f2g4 +f3g3_2 +f4g2 +f5g1_2 +f6g0 +f7g9_38+f8g8_19+f9g7_38; + int64_t h7 = f0g7+f1g6 +f2g5 +f3g4 +f4g3 +f5g2 +f6g1 +f7g0 +f8g9_19+f9g8_19; + int64_t h8 = f0g8+f1g7_2 +f2g6 +f3g5_2 +f4g4 +f5g3_2 +f6g2 +f7g1_2 +f8g0 +f9g9_38; + int64_t h9 = f0g9+f1g8 +f2g7 +f3g6 +f4g5 +f5g4 +f6g3 +f7g2 +f8g1 +f9g0 ; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + /* + |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38)) + i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8 + |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19)) + i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 + */ + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + /* |h0| <= 2^25 */ + /* |h4| <= 2^25 */ + /* |h1| <= 1.71*2^59 */ + /* |h5| <= 1.71*2^59 */ + + carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + /* |h1| <= 2^24; from now on fits into int32 */ + /* |h5| <= 2^24; from now on fits into int32 */ + /* |h2| <= 1.41*2^60 */ + /* |h6| <= 1.41*2^60 */ + + carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + /* |h2| <= 2^25; from now on fits into int32 unchanged */ + /* |h6| <= 2^25; from now on fits into int32 unchanged */ + /* |h3| <= 1.71*2^59 */ + /* |h7| <= 1.71*2^59 */ + + carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + /* |h3| <= 2^24; from now on fits into int32 unchanged */ + /* |h7| <= 2^24; from now on fits into int32 unchanged */ + /* |h4| <= 1.72*2^34 */ + /* |h8| <= 1.41*2^60 */ + + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + /* |h4| <= 2^25; from now on fits into int32 unchanged */ + /* |h8| <= 2^25; from now on fits into int32 unchanged */ + /* |h5| <= 1.01*2^24 */ + /* |h9| <= 1.71*2^59 */ + + carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + /* |h9| <= 2^24; from now on fits into int32 unchanged */ + /* |h0| <= 1.1*2^39 */ + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + /* |h0| <= 2^25; from now on fits into int32 unchanged */ + /* |h1| <= 1.01*2^24 */ + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* From fe_neg.c */ + +/* +h = -f + +Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + +Postconditions: + |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. +*/ + +static void fe_neg(fe h, const fe f) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t h0 = -f0; + int32_t h1 = -f1; + int32_t h2 = -f2; + int32_t h3 = -f3; + int32_t h4 = -f4; + int32_t h5 = -f5; + int32_t h6 = -f6; + int32_t h7 = -f7; + int32_t h8 = -f8; + int32_t h9 = -f9; + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* From fe_sq.c */ + +/* +h = f * f +Can overlap h with f. + +Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + +Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. +*/ + +/* +See fe_mul.c for discussion of implementation strategy. +*/ + +static void fe_sq(fe h, const fe f) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; + int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; + int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; + int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; + int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; + int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; + int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; + int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; + int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; + int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + + carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + + carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + + carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* From fe_sq2.c */ + +/* +h = 2 * f * f +Can overlap h with f. + +Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + +Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. +*/ + +/* +See fe_mul.c for discussion of implementation strategy. +*/ + +static void fe_sq2(fe h, const fe f) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + int64_t h0 = f0f0 +f1f9_76+f2f8_38+f3f7_76+f4f6_38+f5f5_38; + int64_t h1 = f0f1_2+f2f9_38+f3f8_38+f4f7_38+f5f6_38; + int64_t h2 = f0f2_2+f1f1_2 +f3f9_76+f4f8_38+f5f7_76+f6f6_19; + int64_t h3 = f0f3_2+f1f2_2 +f4f9_38+f5f8_38+f6f7_38; + int64_t h4 = f0f4_2+f1f3_4 +f2f2 +f5f9_76+f6f8_38+f7f7_38; + int64_t h5 = f0f5_2+f1f4_2 +f2f3_2 +f6f9_38+f7f8_38; + int64_t h6 = f0f6_2+f1f5_4 +f2f4_2 +f3f3_2 +f7f9_76+f8f8_19; + int64_t h7 = f0f7_2+f1f6_2 +f2f5_2 +f3f4_2 +f8f9_38; + int64_t h8 = f0f8_2+f1f7_4 +f2f6_2 +f3f5_4 +f4f4 +f9f9_38; + int64_t h9 = f0f9_2+f1f8_2 +f2f7_2 +f3f6_2 +f4f5_2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + h0 += h0; + h1 += h1; + h2 += h2; + h3 += h3; + h4 += h4; + h5 += h5; + h6 += h6; + h7 += h7; + h8 += h8; + h9 += h9; + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + + carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + + carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + + carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* From fe_sub.c */ + +/* +h = f - g +Can overlap h with f or g. + +Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + +Postconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. +*/ + +static void fe_sub(fe h, const fe f, const fe g) { + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + int32_t h0 = f0 - g0; + int32_t h1 = f1 - g1; + int32_t h2 = f2 - g2; + int32_t h3 = f3 - g3; + int32_t h4 = f4 - g4; + int32_t h5 = f5 - g5; + int32_t h6 = f6 - g6; + int32_t h7 = f7 - g7; + int32_t h8 = f8 - g8; + int32_t h9 = f9 - g9; + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* From fe_tobytes.c */ + +/* +Preconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + +Write p=2^255-19; q=floor(h/p). +Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). + +Proof: + Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. + Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. + + Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). + Then 0> 25; + q = (h0 + q) >> 26; + q = (h1 + q) >> 25; + q = (h2 + q) >> 26; + q = (h3 + q) >> 25; + q = (h4 + q) >> 26; + q = (h5 + q) >> 25; + q = (h6 + q) >> 26; + q = (h7 + q) >> 25; + q = (h8 + q) >> 26; + q = (h9 + q) >> 25; + + /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ + h0 += 19 * q; + /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ + + carry0 = h0 >> 26; h1 += carry0; h0 -= carry0 << 26; + carry1 = h1 >> 25; h2 += carry1; h1 -= carry1 << 25; + carry2 = h2 >> 26; h3 += carry2; h2 -= carry2 << 26; + carry3 = h3 >> 25; h4 += carry3; h3 -= carry3 << 25; + carry4 = h4 >> 26; h5 += carry4; h4 -= carry4 << 26; + carry5 = h5 >> 25; h6 += carry5; h5 -= carry5 << 25; + carry6 = h6 >> 26; h7 += carry6; h6 -= carry6 << 26; + carry7 = h7 >> 25; h8 += carry7; h7 -= carry7 << 25; + carry8 = h8 >> 26; h9 += carry8; h8 -= carry8 << 26; + carry9 = h9 >> 25; h9 -= carry9 << 25; + /* h10 = carry9 */ + + /* + Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + Have h0+...+2^230 h9 between 0 and 2^255-1; + evidently 2^255 h10-2^255 q = 0. + Goal: Output h0+...+2^230 h9. + */ + + s[0] = h0 >> 0; + s[1] = h0 >> 8; + s[2] = h0 >> 16; + s[3] = (h0 >> 24) | (h1 << 2); + s[4] = h1 >> 6; + s[5] = h1 >> 14; + s[6] = (h1 >> 22) | (h2 << 3); + s[7] = h2 >> 5; + s[8] = h2 >> 13; + s[9] = (h2 >> 21) | (h3 << 5); + s[10] = h3 >> 3; + s[11] = h3 >> 11; + s[12] = (h3 >> 19) | (h4 << 6); + s[13] = h4 >> 2; + s[14] = h4 >> 10; + s[15] = h4 >> 18; + s[16] = h5 >> 0; + s[17] = h5 >> 8; + s[18] = h5 >> 16; + s[19] = (h5 >> 24) | (h6 << 1); + s[20] = h6 >> 7; + s[21] = h6 >> 15; + s[22] = (h6 >> 23) | (h7 << 3); + s[23] = h7 >> 5; + s[24] = h7 >> 13; + s[25] = (h7 >> 21) | (h8 << 4); + s[26] = h8 >> 4; + s[27] = h8 >> 12; + s[28] = (h8 >> 20) | (h9 << 6); + s[29] = h9 >> 2; + s[30] = h9 >> 10; + s[31] = h9 >> 18; +} + +/* From ge_add.c */ + +void ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { + fe t0; + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->YplusX); + fe_mul(r->Y, r->Y, q->YminusX); + fe_mul(r->T, q->T2d, p->T); + fe_mul(r->X, p->Z, q->Z); + fe_add(t0, r->X, r->X); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_add(r->Z, t0, r->T); + fe_sub(r->T, t0, r->T); +} + +/* From ge_double_scalarmult.c, modified */ + +static void slide(signed char *r, const unsigned char *a) { + int i; + int b; + int k; + + for (i = 0; i < 256; ++i) { + r[i] = 1 & (a[i >> 3] >> (i & 7)); + } + + for (i = 0; i < 256; ++i) { + if (r[i]) { + for (b = 1; b <= 6 && i + b < 256; ++b) { + if (r[i + b]) { + if (r[i] + (r[i + b] << b) <= 15) { + r[i] += r[i + b] << b; r[i + b] = 0; + } else if (r[i] - (r[i + b] << b) >= -15) { + r[i] -= r[i + b] << b; + for (k = i + b; k < 256; ++k) { + if (!r[k]) { + r[k] = 1; + break; + } + r[k] = 0; + } + } else + break; + } + } + } + } +} + +void ge_dsm_precomp(ge_dsmp r, const ge_p3 *s) { + ge_p1p1 t; + ge_p3 s2, u; + ge_p3_to_cached(&r[0], s); + ge_p3_dbl(&t, s); ge_p1p1_to_p3(&s2, &t); + ge_add(&t, &s2, &r[0]); ge_p1p1_to_p3(&u, &t); ge_p3_to_cached(&r[1], &u); + ge_add(&t, &s2, &r[1]); ge_p1p1_to_p3(&u, &t); ge_p3_to_cached(&r[2], &u); + ge_add(&t, &s2, &r[2]); ge_p1p1_to_p3(&u, &t); ge_p3_to_cached(&r[3], &u); + ge_add(&t, &s2, &r[3]); ge_p1p1_to_p3(&u, &t); ge_p3_to_cached(&r[4], &u); + ge_add(&t, &s2, &r[4]); ge_p1p1_to_p3(&u, &t); ge_p3_to_cached(&r[5], &u); + ge_add(&t, &s2, &r[5]); ge_p1p1_to_p3(&u, &t); ge_p3_to_cached(&r[6], &u); + ge_add(&t, &s2, &r[6]); ge_p1p1_to_p3(&u, &t); ge_p3_to_cached(&r[7], &u); +} + +/* +r = a * A + b * B +where a = a[0]+256*a[1]+...+256^31 a[31]. +and b = b[0]+256*b[1]+...+256^31 b[31]. +B is the Ed25519 base point (x,4/5) with x positive. +*/ + +void ge_double_scalarmult_base_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b) { + signed char aslide[256]; + signed char bslide[256]; + ge_dsmp Ai; /* A, 3A, 5A, 7A, 9A, 11A, 13A, 15A */ + ge_p1p1 t; + ge_p3 u; + int i; + + slide(aslide, a); + slide(bslide, b); + ge_dsm_precomp(Ai, A); + + ge_p2_0(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i]) break; + } + + for (; i >= 0; --i) { + ge_p2_dbl(&t, r); + + if (aslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Ai[aslide[i]/2]); + } else if (aslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Ai[(-aslide[i])/2]); + } + + if (bslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_madd(&t, &u, &ge_Bi[bslide[i]/2]); + } else if (bslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_msub(&t, &u, &ge_Bi[(-bslide[i])/2]); + } + + ge_p1p1_to_p2(r, &t); + } +} + +// Computes aG + bB + cC (G is the fixed basepoint) +void ge_triple_scalarmult_base_vartime(ge_p2 *r, const unsigned char *a, const unsigned char *b, const ge_dsmp Bi, const unsigned char *c, const ge_dsmp Ci) { + signed char aslide[256]; + signed char bslide[256]; + signed char cslide[256]; + ge_p1p1 t; + ge_p3 u; + int i; + + slide(aslide, a); + slide(bslide, b); + slide(cslide, c); + + ge_p2_0(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i] || cslide[i]) break; + } + + for (; i >= 0; --i) { + ge_p2_dbl(&t, r); + + if (aslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_madd(&t, &u, &ge_Bi[aslide[i]/2]); + } else if (aslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_msub(&t, &u, &ge_Bi[(-aslide[i])/2]); + } + + if (bslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Bi[bslide[i]/2]); + } else if (bslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Bi[(-bslide[i])/2]); + } + + if (cslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Ci[cslide[i]/2]); + } else if (cslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Ci[(-cslide[i])/2]); + } + + ge_p1p1_to_p2(r, &t); + } +} + +void ge_double_scalarmult_base_vartime_p3(ge_p3 *r3, const unsigned char *a, const ge_p3 *A, const unsigned char *b) { + signed char aslide[256]; + signed char bslide[256]; + ge_dsmp Ai; /* A, 3A, 5A, 7A, 9A, 11A, 13A, 15A */ + ge_p1p1 t; + ge_p3 u; + ge_p2 r; + int i; + + slide(aslide, a); + slide(bslide, b); + ge_dsm_precomp(Ai, A); + + ge_p2_0(&r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i]) break; + } + + for (; i >= 0; --i) { + ge_p2_dbl(&t, &r); + + if (aslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Ai[aslide[i]/2]); + } else if (aslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Ai[(-aslide[i])/2]); + } + + if (bslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_madd(&t, &u, &ge_Bi[bslide[i]/2]); + } else if (bslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_msub(&t, &u, &ge_Bi[(-bslide[i])/2]); + } + + if (i == 0) + ge_p1p1_to_p3(r3, &t); + else + ge_p1p1_to_p2(&r, &t); + } +} + +/* From ge_frombytes.c, modified */ + +int ge_frombytes_vartime(ge_p3 *h, const unsigned char *s) { + fe u; + fe v; + fe vxx; + fe check; + + /* From fe_frombytes.c */ + + int64_t h0 = load_4(s); + int64_t h1 = load_3(s + 4) << 6; + int64_t h2 = load_3(s + 7) << 5; + int64_t h3 = load_3(s + 10) << 3; + int64_t h4 = load_3(s + 13) << 2; + int64_t h5 = load_4(s + 16); + int64_t h6 = load_3(s + 20) << 7; + int64_t h7 = load_3(s + 23) << 5; + int64_t h8 = load_3(s + 26) << 4; + int64_t h9 = (load_3(s + 29) & 8388607) << 2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + /* Validate the number to be canonical */ + if (h9 == 33554428 && h8 == 268435440 && h7 == 536870880 && h6 == 2147483520 && + h5 == 4294967295 && h4 == 67108860 && h3 == 134217720 && h2 == 536870880 && + h1 == 1073741760 && h0 >= 4294967277) { + return -1; + } + + carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + h->Y[0] = h0; + h->Y[1] = h1; + h->Y[2] = h2; + h->Y[3] = h3; + h->Y[4] = h4; + h->Y[5] = h5; + h->Y[6] = h6; + h->Y[7] = h7; + h->Y[8] = h8; + h->Y[9] = h9; + + /* End fe_frombytes.c */ + + fe_1(h->Z); + fe_sq(u, h->Y); + fe_mul(v, u, fe_d); + fe_sub(u, u, h->Z); /* u = y^2-1 */ + fe_add(v, v, h->Z); /* v = dy^2+1 */ + + fe_divpowm1(h->X, u, v); /* x = uv^3(uv^7)^((q-5)/8) */ + + fe_sq(vxx, h->X); + fe_mul(vxx, vxx, v); + fe_sub(check, vxx, u); /* vx^2-u */ + if (fe_isnonzero(check)) { + fe_add(check, vxx, u); /* vx^2+u */ + if (fe_isnonzero(check)) { + return -1; + } + fe_mul(h->X, h->X, fe_sqrtm1); + } + + if (fe_isnegative(h->X) != (s[31] >> 7)) { + /* If x = 0, the sign must be positive */ + if (!fe_isnonzero(h->X)) { + return -1; + } + fe_neg(h->X, h->X); + } + + fe_mul(h->T, h->X, h->Y); + return 0; +} + +/* From ge_madd.c */ + +/* +r = p + q +*/ + +static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { + fe t0; + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->yplusx); + fe_mul(r->Y, r->Y, q->yminusx); + fe_mul(r->T, q->xy2d, p->T); + fe_add(t0, p->Z, p->Z); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_add(r->Z, t0, r->T); + fe_sub(r->T, t0, r->T); +} + +/* From ge_msub.c */ + +/* +r = p - q +*/ + +static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { + fe t0; + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->yminusx); + fe_mul(r->Y, r->Y, q->yplusx); + fe_mul(r->T, q->xy2d, p->T); + fe_add(t0, p->Z, p->Z); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_sub(r->Z, t0, r->T); + fe_add(r->T, t0, r->T); +} + +/* From ge_p1p1_to_p2.c */ + +/* +r = p +*/ + +void ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) { + fe_mul(r->X, p->X, p->T); + fe_mul(r->Y, p->Y, p->Z); + fe_mul(r->Z, p->Z, p->T); +} + +/* From ge_p1p1_to_p3.c */ + +/* +r = p +*/ + +void ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) { + fe_mul(r->X, p->X, p->T); + fe_mul(r->Y, p->Y, p->Z); + fe_mul(r->Z, p->Z, p->T); + fe_mul(r->T, p->X, p->Y); +} + +/* From ge_p2_0.c */ + +static void ge_p2_0(ge_p2 *h) { + fe_0(h->X); + fe_1(h->Y); + fe_1(h->Z); +} + +/* From ge_p2_dbl.c */ + +/* +r = 2 * p +*/ + +void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) { + fe t0; + fe_sq(r->X, p->X); + fe_sq(r->Z, p->Y); + fe_sq2(r->T, p->Z); + fe_add(r->Y, p->X, p->Y); + fe_sq(t0, r->Y); + fe_add(r->Y, r->Z, r->X); + fe_sub(r->Z, r->Z, r->X); + fe_sub(r->X, t0, r->Y); + fe_sub(r->T, r->T, r->Z); +} + +/* From ge_p3_0.c */ + +static void ge_p3_0(ge_p3 *h) { + fe_0(h->X); + fe_1(h->Y); + fe_1(h->Z); + fe_0(h->T); +} + +/* From ge_p3_dbl.c */ + +/* +r = 2 * p +*/ + +static void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) { + ge_p2 q; + ge_p3_to_p2(&q, p); + ge_p2_dbl(r, &q); +} + +/* From ge_p3_to_cached.c */ + +/* +r = p +*/ + +void ge_p3_to_cached(ge_cached *r, const ge_p3 *p) { + fe_add(r->YplusX, p->Y, p->X); + fe_sub(r->YminusX, p->Y, p->X); + fe_copy(r->Z, p->Z); + fe_mul(r->T2d, p->T, fe_d2); +} + +/* From ge_p3_to_p2.c */ + +/* +r = p +*/ + +void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) { + fe_copy(r->X, p->X); + fe_copy(r->Y, p->Y); + fe_copy(r->Z, p->Z); +} + +/* From ge_p3_tobytes.c */ + +void ge_p3_tobytes(unsigned char *s, const ge_p3 *h) { + fe recip; + fe x; + fe y; + + fe_invert(recip, h->Z); + fe_mul(x, h->X, recip); + fe_mul(y, h->Y, recip); + fe_tobytes(s, y); + s[31] ^= fe_isnegative(x) << 7; +} + +/* From ge_precomp_0.c */ + +static void ge_precomp_0(ge_precomp *h) { + fe_1(h->yplusx); + fe_1(h->yminusx); + fe_0(h->xy2d); +} + +/* From ge_scalarmult_base.c */ + +static unsigned char equal(signed char b, signed char c) { + unsigned char ub = b; + unsigned char uc = c; + unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ + uint32_t y = x; /* 0: yes; 1..255: no */ + y -= 1; /* 4294967295: yes; 0..254: no */ + y >>= 31; /* 1: yes; 0: no */ + return y; +} + +static unsigned char negative(signed char b) { + unsigned long long x = b; /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ + x >>= 63; /* 1: yes; 0: no */ + return x; +} + +static void ge_precomp_cmov(ge_precomp *t, const ge_precomp *u, unsigned char b) { + fe_cmov(t->yplusx, u->yplusx, b); + fe_cmov(t->yminusx, u->yminusx, b); + fe_cmov(t->xy2d, u->xy2d, b); +} + +static void select(ge_precomp *t, int pos, signed char b) { + ge_precomp minust; + unsigned char bnegative = negative(b); + unsigned char babs = b - (((-bnegative) & b) << 1); + + ge_precomp_0(t); + ge_precomp_cmov(t, &ge_base[pos][0], equal(babs, 1)); + ge_precomp_cmov(t, &ge_base[pos][1], equal(babs, 2)); + ge_precomp_cmov(t, &ge_base[pos][2], equal(babs, 3)); + ge_precomp_cmov(t, &ge_base[pos][3], equal(babs, 4)); + ge_precomp_cmov(t, &ge_base[pos][4], equal(babs, 5)); + ge_precomp_cmov(t, &ge_base[pos][5], equal(babs, 6)); + ge_precomp_cmov(t, &ge_base[pos][6], equal(babs, 7)); + ge_precomp_cmov(t, &ge_base[pos][7], equal(babs, 8)); + fe_copy(minust.yplusx, t->yminusx); + fe_copy(minust.yminusx, t->yplusx); + fe_neg(minust.xy2d, t->xy2d); + ge_precomp_cmov(t, &minust, bnegative); +} + +/* +h = a * B +where a = a[0]+256*a[1]+...+256^31 a[31] +B is the Ed25519 base point (x,4/5) with x positive. + +Preconditions: + a[31] <= 127 +*/ + +void ge_scalarmult_base(ge_p3 *h, const unsigned char *a) { + signed char e[64]; + signed char carry; + ge_p1p1 r; + ge_p2 s; + ge_precomp t; + int i; + + for (i = 0; i < 32; ++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + /* each e[i] is between 0 and 15 */ + /* e[63] is between 0 and 7 */ + + carry = 0; + for (i = 0; i < 63; ++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= carry << 4; + } + e[63] += carry; + /* each e[i] is between -8 and 8 */ + + ge_p3_0(h); + for (i = 1; i < 64; i += 2) { + select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); ge_p1p1_to_p3(h, &r); + } + + ge_p3_dbl(&r, h); ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); ge_p1p1_to_p3(h, &r); + + for (i = 0; i < 64; i += 2) { + select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); ge_p1p1_to_p3(h, &r); + } +} + +/* From ge_sub.c */ + +/* +r = p - q +*/ + +void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { + fe t0; + fe_add(r->X, p->Y, p->X); + fe_sub(r->Y, p->Y, p->X); + fe_mul(r->Z, r->X, q->YminusX); + fe_mul(r->Y, r->Y, q->YplusX); + fe_mul(r->T, q->T2d, p->T); + fe_mul(r->X, p->Z, q->Z); + fe_add(t0, r->X, r->X); + fe_sub(r->X, r->Z, r->Y); + fe_add(r->Y, r->Z, r->Y); + fe_sub(r->Z, t0, r->T); + fe_add(r->T, t0, r->T); +} + +/* From ge_tobytes.c */ + +void ge_tobytes(unsigned char *s, const ge_p2 *h) { + fe recip; + fe x; + fe y; + + fe_invert(recip, h->Z); + fe_mul(x, h->X, recip); + fe_mul(y, h->Y, recip); + fe_tobytes(s, y); + s[31] ^= fe_isnegative(x) << 7; +} + +/* From sc_reduce.c */ + +/* +Input: + s[0]+256*s[1]+...+256^63*s[63] = s + +Output: + s[0]+256*s[1]+...+256^31*s[31] = s mod l + where l = 2^252 + 27742317777372353535851937790883648493. + Overwrites s in place. +*/ + +void sc_reduce(unsigned char *s) { + int64_t s0 = 2097151 & load_3(s); + int64_t s1 = 2097151 & (load_4(s + 2) >> 5); + int64_t s2 = 2097151 & (load_3(s + 5) >> 2); + int64_t s3 = 2097151 & (load_4(s + 7) >> 7); + int64_t s4 = 2097151 & (load_4(s + 10) >> 4); + int64_t s5 = 2097151 & (load_3(s + 13) >> 1); + int64_t s6 = 2097151 & (load_4(s + 15) >> 6); + int64_t s7 = 2097151 & (load_3(s + 18) >> 3); + int64_t s8 = 2097151 & load_3(s + 21); + int64_t s9 = 2097151 & (load_4(s + 23) >> 5); + int64_t s10 = 2097151 & (load_3(s + 26) >> 2); + int64_t s11 = 2097151 & (load_4(s + 28) >> 7); + int64_t s12 = 2097151 & (load_4(s + 31) >> 4); + int64_t s13 = 2097151 & (load_3(s + 34) >> 1); + int64_t s14 = 2097151 & (load_4(s + 36) >> 6); + int64_t s15 = 2097151 & (load_3(s + 39) >> 3); + int64_t s16 = 2097151 & load_3(s + 42); + int64_t s17 = 2097151 & (load_4(s + 44) >> 5); + int64_t s18 = 2097151 & (load_3(s + 47) >> 2); + int64_t s19 = 2097151 & (load_4(s + 49) >> 7); + int64_t s20 = 2097151 & (load_4(s + 52) >> 4); + int64_t s21 = 2097151 & (load_3(s + 55) >> 1); + int64_t s22 = 2097151 & (load_4(s + 57) >> 6); + int64_t s23 = (load_4(s + 60) >> 3); + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; + carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; + carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; + + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; + carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + + carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +/* New code */ + +static void fe_divpowm1(fe r, const fe u, const fe v) { + fe v3, uv7, t0, t1, t2; + int i; + + fe_sq(v3, v); + fe_mul(v3, v3, v); /* v3 = v^3 */ + fe_sq(uv7, v3); + fe_mul(uv7, uv7, v); + fe_mul(uv7, uv7, u); /* uv7 = uv^7 */ + + /*fe_pow22523(uv7, uv7);*/ + + /* From fe_pow22523.c */ + + fe_sq(t0, uv7); + fe_sq(t1, t0); + fe_sq(t1, t1); + fe_mul(t1, uv7, t1); + fe_mul(t0, t0, t1); + fe_sq(t0, t0); + fe_mul(t0, t1, t0); + fe_sq(t1, t0); + for (i = 0; i < 4; ++i) { + fe_sq(t1, t1); + } + fe_mul(t0, t1, t0); + fe_sq(t1, t0); + for (i = 0; i < 9; ++i) { + fe_sq(t1, t1); + } + fe_mul(t1, t1, t0); + fe_sq(t2, t1); + for (i = 0; i < 19; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t2, t1); + for (i = 0; i < 10; ++i) { + fe_sq(t1, t1); + } + fe_mul(t0, t1, t0); + fe_sq(t1, t0); + for (i = 0; i < 49; ++i) { + fe_sq(t1, t1); + } + fe_mul(t1, t1, t0); + fe_sq(t2, t1); + for (i = 0; i < 99; ++i) { + fe_sq(t2, t2); + } + fe_mul(t1, t2, t1); + for (i = 0; i < 50; ++i) { + fe_sq(t1, t1); + } + fe_mul(t0, t1, t0); + fe_sq(t0, t0); + fe_sq(t0, t0); + fe_mul(t0, t0, uv7); + + /* End fe_pow22523.c */ + /* t0 = (uv^7)^((q-5)/8) */ + fe_mul(t0, t0, v3); + fe_mul(r, t0, u); /* u^(m+1)v^(-(m+1)) */ +} + +static void ge_cached_0(ge_cached *r) { + fe_1(r->YplusX); + fe_1(r->YminusX); + fe_1(r->Z); + fe_0(r->T2d); +} + +static void ge_cached_cmov(ge_cached *t, const ge_cached *u, unsigned char b) { + fe_cmov(t->YplusX, u->YplusX, b); + fe_cmov(t->YminusX, u->YminusX, b); + fe_cmov(t->Z, u->Z, b); + fe_cmov(t->T2d, u->T2d, b); +} + +/* Assumes that a[31] <= 127 */ +void ge_scalarmult(ge_p2 *r, const unsigned char *a, const ge_p3 *A) { + signed char e[64]; + int carry, carry2, i; + ge_cached Ai[8]; /* 1 * A, 2 * A, ..., 8 * A */ + ge_p1p1 t; + ge_p3 u; + + carry = 0; /* 0..1 */ + for (i = 0; i < 31; i++) { + carry += a[i]; /* 0..256 */ + carry2 = (carry + 8) >> 4; /* 0..16 */ + e[2 * i] = carry - (carry2 << 4); /* -8..7 */ + carry = (carry2 + 8) >> 4; /* 0..1 */ + e[2 * i + 1] = carry2 - (carry << 4); /* -8..7 */ + } + carry += a[31]; /* 0..128 */ + carry2 = (carry + 8) >> 4; /* 0..8 */ + e[62] = carry - (carry2 << 4); /* -8..7 */ + e[63] = carry2; /* 0..8 */ + + ge_p3_to_cached(&Ai[0], A); + for (i = 0; i < 7; i++) { + ge_add(&t, A, &Ai[i]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[i + 1], &u); + } + + ge_p2_0(r); + for (i = 63; i >= 0; i--) { + signed char b = e[i]; + unsigned char bnegative = negative(b); + unsigned char babs = b - (((-bnegative) & b) << 1); + ge_cached cur, minuscur; + ge_p2_dbl(&t, r); + ge_p1p1_to_p2(r, &t); + ge_p2_dbl(&t, r); + ge_p1p1_to_p2(r, &t); + ge_p2_dbl(&t, r); + ge_p1p1_to_p2(r, &t); + ge_p2_dbl(&t, r); + ge_p1p1_to_p3(&u, &t); + ge_cached_0(&cur); + ge_cached_cmov(&cur, &Ai[0], equal(babs, 1)); + ge_cached_cmov(&cur, &Ai[1], equal(babs, 2)); + ge_cached_cmov(&cur, &Ai[2], equal(babs, 3)); + ge_cached_cmov(&cur, &Ai[3], equal(babs, 4)); + ge_cached_cmov(&cur, &Ai[4], equal(babs, 5)); + ge_cached_cmov(&cur, &Ai[5], equal(babs, 6)); + ge_cached_cmov(&cur, &Ai[6], equal(babs, 7)); + ge_cached_cmov(&cur, &Ai[7], equal(babs, 8)); + fe_copy(minuscur.YplusX, cur.YminusX); + fe_copy(minuscur.YminusX, cur.YplusX); + fe_copy(minuscur.Z, cur.Z); + fe_neg(minuscur.T2d, cur.T2d); + ge_cached_cmov(&cur, &minuscur, bnegative); + ge_add(&t, &u, &cur); + ge_p1p1_to_p2(r, &t); + } +} + +void ge_scalarmult_p3(ge_p3 *r3, const unsigned char *a, const ge_p3 *A) { + signed char e[64]; + int carry, carry2, i; + ge_cached Ai[8]; /* 1 * A, 2 * A, ..., 8 * A */ + ge_p1p1 t; + ge_p3 u; + ge_p2 r; + + carry = 0; /* 0..1 */ + for (i = 0; i < 31; i++) { + carry += a[i]; /* 0..256 */ + carry2 = (carry + 8) >> 4; /* 0..16 */ + e[2 * i] = carry - (carry2 << 4); /* -8..7 */ + carry = (carry2 + 8) >> 4; /* 0..1 */ + e[2 * i + 1] = carry2 - (carry << 4); /* -8..7 */ + } + carry += a[31]; /* 0..128 */ + carry2 = (carry + 8) >> 4; /* 0..8 */ + e[62] = carry - (carry2 << 4); /* -8..7 */ + e[63] = carry2; /* 0..8 */ + + ge_p3_to_cached(&Ai[0], A); + for (i = 0; i < 7; i++) { + ge_add(&t, A, &Ai[i]); + ge_p1p1_to_p3(&u, &t); + ge_p3_to_cached(&Ai[i + 1], &u); + } + + ge_p2_0(&r); + for (i = 63; i >= 0; i--) { + signed char b = e[i]; + unsigned char bnegative = negative(b); + unsigned char babs = b - (((-bnegative) & b) << 1); + ge_cached cur, minuscur; + ge_p2_dbl(&t, &r); + ge_p1p1_to_p2(&r, &t); + ge_p2_dbl(&t, &r); + ge_p1p1_to_p2(&r, &t); + ge_p2_dbl(&t, &r); + ge_p1p1_to_p2(&r, &t); + ge_p2_dbl(&t, &r); + ge_p1p1_to_p3(&u, &t); + ge_cached_0(&cur); + ge_cached_cmov(&cur, &Ai[0], equal(babs, 1)); + ge_cached_cmov(&cur, &Ai[1], equal(babs, 2)); + ge_cached_cmov(&cur, &Ai[2], equal(babs, 3)); + ge_cached_cmov(&cur, &Ai[3], equal(babs, 4)); + ge_cached_cmov(&cur, &Ai[4], equal(babs, 5)); + ge_cached_cmov(&cur, &Ai[5], equal(babs, 6)); + ge_cached_cmov(&cur, &Ai[6], equal(babs, 7)); + ge_cached_cmov(&cur, &Ai[7], equal(babs, 8)); + fe_copy(minuscur.YplusX, cur.YminusX); + fe_copy(minuscur.YminusX, cur.YplusX); + fe_copy(minuscur.Z, cur.Z); + fe_neg(minuscur.T2d, cur.T2d); + ge_cached_cmov(&cur, &minuscur, bnegative); + ge_add(&t, &u, &cur); + if (i == 0) + ge_p1p1_to_p3(r3, &t); + else + ge_p1p1_to_p2(&r, &t); + } +} + +void ge_double_scalarmult_precomp_vartime2(ge_p2 *r, const unsigned char *a, const ge_dsmp Ai, const unsigned char *b, const ge_dsmp Bi) { + signed char aslide[256]; + signed char bslide[256]; + ge_p1p1 t; + ge_p3 u; + int i; + + slide(aslide, a); + slide(bslide, b); + + ge_p2_0(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i]) break; + } + + for (; i >= 0; --i) { + ge_p2_dbl(&t, r); + + if (aslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Ai[aslide[i]/2]); + } else if (aslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Ai[(-aslide[i])/2]); + } + + if (bslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Bi[bslide[i]/2]); + } else if (bslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Bi[(-bslide[i])/2]); + } + + ge_p1p1_to_p2(r, &t); + } +} + +// Computes aA + bB + cC (all points require precomputation) +void ge_triple_scalarmult_precomp_vartime(ge_p2 *r, const unsigned char *a, const ge_dsmp Ai, const unsigned char *b, const ge_dsmp Bi, const unsigned char *c, const ge_dsmp Ci) { + signed char aslide[256]; + signed char bslide[256]; + signed char cslide[256]; + ge_p1p1 t; + ge_p3 u; + int i; + + slide(aslide, a); + slide(bslide, b); + slide(cslide, c); + + ge_p2_0(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i] || cslide[i]) break; + } + + for (; i >= 0; --i) { + ge_p2_dbl(&t, r); + + if (aslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Ai[aslide[i]/2]); + } else if (aslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Ai[(-aslide[i])/2]); + } + + if (bslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Bi[bslide[i]/2]); + } else if (bslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Bi[(-bslide[i])/2]); + } + + if (cslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Ci[cslide[i]/2]); + } else if (cslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Ci[(-cslide[i])/2]); + } + + ge_p1p1_to_p2(r, &t); + } +} + +void ge_double_scalarmult_precomp_vartime2_p3(ge_p3 *r3, const unsigned char *a, const ge_dsmp Ai, const unsigned char *b, const ge_dsmp Bi) { + signed char aslide[256]; + signed char bslide[256]; + ge_p1p1 t; + ge_p3 u; + ge_p2 r; + int i; + + slide(aslide, a); + slide(bslide, b); + + ge_p2_0(&r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i]) break; + } + + for (; i >= 0; --i) { + ge_p2_dbl(&t, &r); + + if (aslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Ai[aslide[i]/2]); + } else if (aslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Ai[(-aslide[i])/2]); + } + + if (bslide[i] > 0) { + ge_p1p1_to_p3(&u, &t); + ge_add(&t, &u, &Bi[bslide[i]/2]); + } else if (bslide[i] < 0) { + ge_p1p1_to_p3(&u, &t); + ge_sub(&t, &u, &Bi[(-bslide[i])/2]); + } + + if (i == 0) + ge_p1p1_to_p3(r3, &t); + else + ge_p1p1_to_p2(&r, &t); + } +} + +void ge_double_scalarmult_precomp_vartime(ge_p2 *r, const unsigned char *a, const ge_p3 *A, const unsigned char *b, const ge_dsmp Bi) { + ge_dsmp Ai; /* A, 3A, 5A, 7A, 9A, 11A, 13A, 15A */ + + ge_dsm_precomp(Ai, A); + ge_double_scalarmult_precomp_vartime2(r, a, Ai, b, Bi); +} + +void ge_mul8(ge_p1p1 *r, const ge_p2 *t) { + ge_p2 u; + ge_p2_dbl(r, t); + ge_p1p1_to_p2(&u, r); + ge_p2_dbl(r, &u); + ge_p1p1_to_p2(&u, r); + ge_p2_dbl(r, &u); +} + +void ge_fromfe_frombytes_vartime(ge_p2 *r, const unsigned char *s) { + fe u, v, w, x, y, z; + unsigned char sign; + + /* From fe_frombytes.c */ + + int64_t h0 = load_4(s); + int64_t h1 = load_3(s + 4) << 6; + int64_t h2 = load_3(s + 7) << 5; + int64_t h3 = load_3(s + 10) << 3; + int64_t h4 = load_3(s + 13) << 2; + int64_t h5 = load_4(s + 16); + int64_t h6 = load_3(s + 20) << 7; + int64_t h7 = load_3(s + 23) << 5; + int64_t h8 = load_3(s + 26) << 4; + int64_t h9 = load_3(s + 29) << 2; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry9 = (h9 + (int64_t) (1<<24)) >> 25; h0 += carry9 * 19; h9 -= carry9 << 25; + carry1 = (h1 + (int64_t) (1<<24)) >> 25; h2 += carry1; h1 -= carry1 << 25; + carry3 = (h3 + (int64_t) (1<<24)) >> 25; h4 += carry3; h3 -= carry3 << 25; + carry5 = (h5 + (int64_t) (1<<24)) >> 25; h6 += carry5; h5 -= carry5 << 25; + carry7 = (h7 + (int64_t) (1<<24)) >> 25; h8 += carry7; h7 -= carry7 << 25; + + carry0 = (h0 + (int64_t) (1<<25)) >> 26; h1 += carry0; h0 -= carry0 << 26; + carry2 = (h2 + (int64_t) (1<<25)) >> 26; h3 += carry2; h2 -= carry2 << 26; + carry4 = (h4 + (int64_t) (1<<25)) >> 26; h5 += carry4; h4 -= carry4 << 26; + carry6 = (h6 + (int64_t) (1<<25)) >> 26; h7 += carry6; h6 -= carry6 << 26; + carry8 = (h8 + (int64_t) (1<<25)) >> 26; h9 += carry8; h8 -= carry8 << 26; + + u[0] = h0; + u[1] = h1; + u[2] = h2; + u[3] = h3; + u[4] = h4; + u[5] = h5; + u[6] = h6; + u[7] = h7; + u[8] = h8; + u[9] = h9; + + /* End fe_frombytes.c */ + + fe_sq2(v, u); /* 2 * u^2 */ + fe_1(w); + fe_add(w, v, w); /* w = 2 * u^2 + 1 */ + fe_sq(x, w); /* w^2 */ + fe_mul(y, fe_ma2, v); /* -2 * A^2 * u^2 */ + fe_add(x, x, y); /* x = w^2 - 2 * A^2 * u^2 */ + fe_divpowm1(r->X, w, x); /* (w / x)^(m + 1) */ + fe_sq(y, r->X); + fe_mul(x, y, x); + fe_sub(y, w, x); + fe_copy(z, fe_ma); + if (fe_isnonzero(y)) { + fe_add(y, w, x); + if (fe_isnonzero(y)) { + goto negative; + } else { + fe_mul(r->X, r->X, fe_fffb1); + } + } else { + fe_mul(r->X, r->X, fe_fffb2); + } + fe_mul(r->X, r->X, u); /* u * sqrt(2 * A * (A + 2) * w / x) */ + fe_mul(z, z, v); /* -2 * A * u^2 */ + sign = 0; + goto setsign; +negative: + fe_mul(x, x, fe_sqrtm1); + fe_sub(y, w, x); + if (fe_isnonzero(y)) { + assert((fe_add(y, w, x), !fe_isnonzero(y))); + fe_mul(r->X, r->X, fe_fffb3); + } else { + fe_mul(r->X, r->X, fe_fffb4); + } + /* r->X = sqrt(A * (A + 2) * w / x) */ + /* z = -A */ + sign = 1; +setsign: + if (fe_isnegative(r->X) != sign) { + assert(fe_isnonzero(r->X)); + fe_neg(r->X, r->X); + } + fe_add(r->Z, z, w); + fe_sub(r->Y, z, w); + fe_mul(r->X, r->X, r->Z); +#if !defined(NDEBUG) + { + fe check_x, check_y, check_iz, check_v; + fe_invert(check_iz, r->Z); + fe_mul(check_x, r->X, check_iz); + fe_mul(check_y, r->Y, check_iz); + fe_sq(check_x, check_x); + fe_sq(check_y, check_y); + fe_mul(check_v, check_x, check_y); + fe_mul(check_v, fe_d, check_v); + fe_add(check_v, check_v, check_x); + fe_sub(check_v, check_v, check_y); + fe_1(check_x); + fe_add(check_v, check_v, check_x); + assert(!fe_isnonzero(check_v)); + } +#endif +} + +void sc_0(unsigned char *s) { + int i; + for (i = 0; i < 32; i++) { + s[i] = 0; + } +} + +void sc_reduce32(unsigned char *s) { + int64_t s0 = 2097151 & load_3(s); + int64_t s1 = 2097151 & (load_4(s + 2) >> 5); + int64_t s2 = 2097151 & (load_3(s + 5) >> 2); + int64_t s3 = 2097151 & (load_4(s + 7) >> 7); + int64_t s4 = 2097151 & (load_4(s + 10) >> 4); + int64_t s5 = 2097151 & (load_3(s + 13) >> 1); + int64_t s6 = 2097151 & (load_4(s + 15) >> 6); + int64_t s7 = 2097151 & (load_3(s + 18) >> 3); + int64_t s8 = 2097151 & load_3(s + 21); + int64_t s9 = 2097151 & (load_4(s + 23) >> 5); + int64_t s10 = 2097151 & (load_3(s + 26) >> 2); + int64_t s11 = (load_4(s + 28) >> 7); + int64_t s12 = 0; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + + carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + + carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +void sc_add(unsigned char *s, const unsigned char *a, const unsigned char *b) { + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + int64_t s0 = a0 + b0; + int64_t s1 = a1 + b1; + int64_t s2 = a2 + b2; + int64_t s3 = a3 + b3; + int64_t s4 = a4 + b4; + int64_t s5 = a5 + b5; + int64_t s6 = a6 + b6; + int64_t s7 = a7 + b7; + int64_t s8 = a8 + b8; + int64_t s9 = a9 + b9; + int64_t s10 = a10 + b10; + int64_t s11 = a11 + b11; + int64_t s12 = 0; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + + carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + + carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +void sc_sub(unsigned char *s, const unsigned char *a, const unsigned char *b) { + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + int64_t s0 = a0 - b0; + int64_t s1 = a1 - b1; + int64_t s2 = a2 - b2; + int64_t s3 = a3 - b3; + int64_t s4 = a4 - b4; + int64_t s5 = a5 - b5; + int64_t s6 = a6 - b6; + int64_t s7 = a7 - b7; + int64_t s8 = a8 - b8; + int64_t s9 = a9 - b9; + int64_t s10 = a10 - b10; + int64_t s11 = a11 - b11; + int64_t s12 = 0; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + + carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + + carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +/* +Input: + a[0]+256*a[1]+...+256^31*a[31] = a + b[0]+256*b[1]+...+256^31*b[31] = b + c[0]+256*c[1]+...+256^31*c[31] = c + +Output: + s[0]+256*s[1]+...+256^31*s[31] = (c-ab) mod l + where l = 2^252 + 27742317777372353535851937790883648493. +*/ + +void sc_mulsub(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c) { + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + int64_t c0 = 2097151 & load_3(c); + int64_t c1 = 2097151 & (load_4(c + 2) >> 5); + int64_t c2 = 2097151 & (load_3(c + 5) >> 2); + int64_t c3 = 2097151 & (load_4(c + 7) >> 7); + int64_t c4 = 2097151 & (load_4(c + 10) >> 4); + int64_t c5 = 2097151 & (load_3(c + 13) >> 1); + int64_t c6 = 2097151 & (load_4(c + 15) >> 6); + int64_t c7 = 2097151 & (load_3(c + 18) >> 3); + int64_t c8 = 2097151 & load_3(c + 21); + int64_t c9 = 2097151 & (load_4(c + 23) >> 5); + int64_t c10 = 2097151 & (load_3(c + 26) >> 2); + int64_t c11 = (load_4(c + 28) >> 7); + int64_t s0; + int64_t s1; + int64_t s2; + int64_t s3; + int64_t s4; + int64_t s5; + int64_t s6; + int64_t s7; + int64_t s8; + int64_t s9; + int64_t s10; + int64_t s11; + int64_t s12; + int64_t s13; + int64_t s14; + int64_t s15; + int64_t s16; + int64_t s17; + int64_t s18; + int64_t s19; + int64_t s20; + int64_t s21; + int64_t s22; + int64_t s23; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + int64_t carry17; + int64_t carry18; + int64_t carry19; + int64_t carry20; + int64_t carry21; + int64_t carry22; + + s0 = c0 - a0*b0; + s1 = c1 - (a0*b1 + a1*b0); + s2 = c2 - (a0*b2 + a1*b1 + a2*b0); + s3 = c3 - (a0*b3 + a1*b2 + a2*b1 + a3*b0); + s4 = c4 - (a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0); + s5 = c5 - (a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0); + s6 = c6 - (a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0); + s7 = c7 - (a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0); + s8 = c8 - (a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0); + s9 = c9 - (a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0); + s10 = c10 - (a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0); + s11 = c11 - (a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0); + s12 = -(a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1); + s13 = -(a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2); + s14 = -(a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3); + s15 = -(a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4); + s16 = -(a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5); + s17 = -(a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6); + s18 = -(a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7); + s19 = -(a8*b11 + a9*b10 + a10*b9 + a11*b8); + s20 = -(a9*b11 + a10*b10 + a11*b9); + s21 = -(a10*b11 + a11*b10); + s22 = -a11*b11; + s23 = 0; + + carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; + carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; + carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; + carry18 = (s18 + (1<<20)) >> 21; s19 += carry18; s18 -= carry18 << 21; + carry20 = (s20 + (1<<20)) >> 21; s21 += carry20; s20 -= carry20 << 21; + carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= carry22 << 21; + + carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; + carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; + carry17 = (s17 + (1<<20)) >> 21; s18 += carry17; s17 -= carry17 << 21; + carry19 = (s19 + (1<<20)) >> 21; s20 += carry19; s19 -= carry19 << 21; + carry21 = (s21 + (1<<20)) >> 21; s22 += carry21; s21 -= carry21 << 21; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; + carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; + carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; + + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; + carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + + carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +//copied from above and modified +/* +Input: + a[0]+256*a[1]+...+256^31*a[31] = a + b[0]+256*b[1]+...+256^31*b[31] = b + +Output: + s[0]+256*s[1]+...+256^31*s[31] = (ab) mod l + where l = 2^252 + 27742317777372353535851937790883648493. +*/ +void sc_mul(unsigned char *s, const unsigned char *a, const unsigned char *b) { + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + int64_t s0; + int64_t s1; + int64_t s2; + int64_t s3; + int64_t s4; + int64_t s5; + int64_t s6; + int64_t s7; + int64_t s8; + int64_t s9; + int64_t s10; + int64_t s11; + int64_t s12; + int64_t s13; + int64_t s14; + int64_t s15; + int64_t s16; + int64_t s17; + int64_t s18; + int64_t s19; + int64_t s20; + int64_t s21; + int64_t s22; + int64_t s23; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + int64_t carry17; + int64_t carry18; + int64_t carry19; + int64_t carry20; + int64_t carry21; + int64_t carry22; + + s0 = a0*b0; + s1 = (a0*b1 + a1*b0); + s2 = (a0*b2 + a1*b1 + a2*b0); + s3 = (a0*b3 + a1*b2 + a2*b1 + a3*b0); + s4 = (a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0); + s5 = (a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0); + s6 = (a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0); + s7 = (a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0); + s8 = (a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0); + s9 = (a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0); + s10 = (a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0); + s11 = (a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0); + s12 = (a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1); + s13 = (a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2); + s14 = (a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3); + s15 = (a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4); + s16 = (a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5); + s17 = (a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6); + s18 = (a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7); + s19 = (a8*b11 + a9*b10 + a10*b9 + a11*b8); + s20 = (a9*b11 + a10*b10 + a11*b9); + s21 = (a10*b11 + a11*b10); + s22 = a11*b11; + s23 = 0; + + carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; + carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; + carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; + carry18 = (s18 + (1<<20)) >> 21; s19 += carry18; s18 -= carry18 << 21; + carry20 = (s20 + (1<<20)) >> 21; s21 += carry20; s20 -= carry20 << 21; + carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= carry22 << 21; + + carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; + carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; + carry17 = (s17 + (1<<20)) >> 21; s18 += carry17; s17 -= carry17 << 21; + carry19 = (s19 + (1<<20)) >> 21; s20 += carry19; s19 -= carry19 << 21; + carry21 = (s21 + (1<<20)) >> 21; s22 += carry21; s21 -= carry21 << 21; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; + carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; + carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; + + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; + carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + + carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +//copied from above and modified +/* +Input: + a[0]+256*a[1]+...+256^31*a[31] = a + b[0]+256*b[1]+...+256^31*b[31] = b + c[0]+256*c[1]+...+256^31*c[31] = c + +Output: + s[0]+256*s[1]+...+256^31*s[31] = (c+ab) mod l + where l = 2^252 + 27742317777372353535851937790883648493. +*/ + +void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c) { + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + int64_t c0 = 2097151 & load_3(c); + int64_t c1 = 2097151 & (load_4(c + 2) >> 5); + int64_t c2 = 2097151 & (load_3(c + 5) >> 2); + int64_t c3 = 2097151 & (load_4(c + 7) >> 7); + int64_t c4 = 2097151 & (load_4(c + 10) >> 4); + int64_t c5 = 2097151 & (load_3(c + 13) >> 1); + int64_t c6 = 2097151 & (load_4(c + 15) >> 6); + int64_t c7 = 2097151 & (load_3(c + 18) >> 3); + int64_t c8 = 2097151 & load_3(c + 21); + int64_t c9 = 2097151 & (load_4(c + 23) >> 5); + int64_t c10 = 2097151 & (load_3(c + 26) >> 2); + int64_t c11 = (load_4(c + 28) >> 7); + int64_t s0; + int64_t s1; + int64_t s2; + int64_t s3; + int64_t s4; + int64_t s5; + int64_t s6; + int64_t s7; + int64_t s8; + int64_t s9; + int64_t s10; + int64_t s11; + int64_t s12; + int64_t s13; + int64_t s14; + int64_t s15; + int64_t s16; + int64_t s17; + int64_t s18; + int64_t s19; + int64_t s20; + int64_t s21; + int64_t s22; + int64_t s23; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + int64_t carry17; + int64_t carry18; + int64_t carry19; + int64_t carry20; + int64_t carry21; + int64_t carry22; + + s0 = c0 + a0*b0; + s1 = c1 + (a0*b1 + a1*b0); + s2 = c2 + (a0*b2 + a1*b1 + a2*b0); + s3 = c3 + (a0*b3 + a1*b2 + a2*b1 + a3*b0); + s4 = c4 + (a0*b4 + a1*b3 + a2*b2 + a3*b1 + a4*b0); + s5 = c5 + (a0*b5 + a1*b4 + a2*b3 + a3*b2 + a4*b1 + a5*b0); + s6 = c6 + (a0*b6 + a1*b5 + a2*b4 + a3*b3 + a4*b2 + a5*b1 + a6*b0); + s7 = c7 + (a0*b7 + a1*b6 + a2*b5 + a3*b4 + a4*b3 + a5*b2 + a6*b1 + a7*b0); + s8 = c8 + (a0*b8 + a1*b7 + a2*b6 + a3*b5 + a4*b4 + a5*b3 + a6*b2 + a7*b1 + a8*b0); + s9 = c9 + (a0*b9 + a1*b8 + a2*b7 + a3*b6 + a4*b5 + a5*b4 + a6*b3 + a7*b2 + a8*b1 + a9*b0); + s10 = c10 + (a0*b10 + a1*b9 + a2*b8 + a3*b7 + a4*b6 + a5*b5 + a6*b4 + a7*b3 + a8*b2 + a9*b1 + a10*b0); + s11 = c11 + (a0*b11 + a1*b10 + a2*b9 + a3*b8 + a4*b7 + a5*b6 + a6*b5 + a7*b4 + a8*b3 + a9*b2 + a10*b1 + a11*b0); + s12 = (a1*b11 + a2*b10 + a3*b9 + a4*b8 + a5*b7 + a6*b6 + a7*b5 + a8*b4 + a9*b3 + a10*b2 + a11*b1); + s13 = (a2*b11 + a3*b10 + a4*b9 + a5*b8 + a6*b7 + a7*b6 + a8*b5 + a9*b4 + a10*b3 + a11*b2); + s14 = (a3*b11 + a4*b10 + a5*b9 + a6*b8 + a7*b7 + a8*b6 + a9*b5 + a10*b4 + a11*b3); + s15 = (a4*b11 + a5*b10 + a6*b9 + a7*b8 + a8*b7 + a9*b6 + a10*b5 + a11*b4); + s16 = (a5*b11 + a6*b10 + a7*b9 + a8*b8 + a9*b7 + a10*b6 + a11*b5); + s17 = (a6*b11 + a7*b10 + a8*b9 + a9*b8 + a10*b7 + a11*b6); + s18 = (a7*b11 + a8*b10 + a9*b9 + a10*b8 + a11*b7); + s19 = (a8*b11 + a9*b10 + a10*b9 + a11*b8); + s20 = (a9*b11 + a10*b10 + a11*b9); + s21 = (a10*b11 + a11*b10); + s22 = a11*b11; + s23 = 0; + + carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; + carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; + carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; + carry18 = (s18 + (1<<20)) >> 21; s19 += carry18; s18 -= carry18 << 21; + carry20 = (s20 + (1<<20)) >> 21; s21 += carry20; s20 -= carry20 << 21; + carry22 = (s22 + (1<<20)) >> 21; s23 += carry22; s22 -= carry22 << 21; + + carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; + carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; + carry17 = (s17 + (1<<20)) >> 21; s18 += carry17; s17 -= carry17 << 21; + carry19 = (s19 + (1<<20)) >> 21; s20 += carry19; s19 -= carry19 << 21; + carry21 = (s21 + (1<<20)) >> 21; s22 += carry21; s21 -= carry21 << 21; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + carry12 = (s12 + (1<<20)) >> 21; s13 += carry12; s12 -= carry12 << 21; + carry14 = (s14 + (1<<20)) >> 21; s15 += carry14; s14 -= carry14 << 21; + carry16 = (s16 + (1<<20)) >> 21; s17 += carry16; s16 -= carry16 << 21; + + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + carry13 = (s13 + (1<<20)) >> 21; s14 += carry13; s13 -= carry13 << 21; + carry15 = (s15 + (1<<20)) >> 21; s16 += carry15; s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1<<20)) >> 21; s1 += carry0; s0 -= carry0 << 21; + carry2 = (s2 + (1<<20)) >> 21; s3 += carry2; s2 -= carry2 << 21; + carry4 = (s4 + (1<<20)) >> 21; s5 += carry4; s4 -= carry4 << 21; + carry6 = (s6 + (1<<20)) >> 21; s7 += carry6; s6 -= carry6 << 21; + carry8 = (s8 + (1<<20)) >> 21; s9 += carry8; s8 -= carry8 << 21; + carry10 = (s10 + (1<<20)) >> 21; s11 += carry10; s10 -= carry10 << 21; + + carry1 = (s1 + (1<<20)) >> 21; s2 += carry1; s1 -= carry1 << 21; + carry3 = (s3 + (1<<20)) >> 21; s4 += carry3; s3 -= carry3 << 21; + carry5 = (s5 + (1<<20)) >> 21; s6 += carry5; s5 -= carry5 << 21; + carry7 = (s7 + (1<<20)) >> 21; s8 += carry7; s7 -= carry7 << 21; + carry9 = (s9 + (1<<20)) >> 21; s10 += carry9; s9 -= carry9 << 21; + carry11 = (s11 + (1<<20)) >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + carry11 = s11 >> 21; s12 += carry11; s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + + carry0 = s0 >> 21; s1 += carry0; s0 -= carry0 << 21; + carry1 = s1 >> 21; s2 += carry1; s1 -= carry1 << 21; + carry2 = s2 >> 21; s3 += carry2; s2 -= carry2 << 21; + carry3 = s3 >> 21; s4 += carry3; s3 -= carry3 << 21; + carry4 = s4 >> 21; s5 += carry4; s4 -= carry4 << 21; + carry5 = s5 >> 21; s6 += carry5; s5 -= carry5 << 21; + carry6 = s6 >> 21; s7 += carry6; s6 -= carry6 << 21; + carry7 = s7 >> 21; s8 += carry7; s7 -= carry7 << 21; + carry8 = s8 >> 21; s9 += carry8; s8 -= carry8 << 21; + carry9 = s9 >> 21; s10 += carry9; s9 -= carry9 << 21; + carry10 = s10 >> 21; s11 += carry10; s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +static int64_t signum(int64_t a) { + return a > 0 ? 1 : a < 0 ? -1 : 0; +} + +int sc_check(const unsigned char *s) { + int64_t s0 = load_4(s); + int64_t s1 = load_4(s + 4); + int64_t s2 = load_4(s + 8); + int64_t s3 = load_4(s + 12); + int64_t s4 = load_4(s + 16); + int64_t s5 = load_4(s + 20); + int64_t s6 = load_4(s + 24); + int64_t s7 = load_4(s + 28); + return (signum(1559614444 - s0) + (signum(1477600026 - s1) << 1) + (signum(2734136534 - s2) << 2) + (signum(350157278 - s3) << 3) + (signum(-s4) << 4) + (signum(-s5) << 5) + (signum(-s6) << 6) + (signum(268435456 - s7) << 7)) >> 8; +} + +int sc_isnonzero(const unsigned char *s) { + return (((int) (s[0] | s[1] | s[2] | s[3] | s[4] | s[5] | s[6] | s[7] | s[8] | + s[9] | s[10] | s[11] | s[12] | s[13] | s[14] | s[15] | s[16] | s[17] | + s[18] | s[19] | s[20] | s[21] | s[22] | s[23] | s[24] | s[25] | s[26] | + s[27] | s[28] | s[29] | s[30] | s[31]) - 1) >> 8) + 1; +} + +int ge_p3_is_point_at_infinity(const ge_p3 *p) { + // X = 0 and Y == Z + int n; + for (n = 0; n < 10; ++n) + { + if (p->X[n] | p->T[n]) + return 0; + if (p->Y[n] != p->Z[n]) + return 0; + } + return 1; +} diff --git a/external/src/cryptonote/crypto-ops.h b/external/src/cryptonote/crypto-ops.h new file mode 100644 index 0000000..22f7697 --- /dev/null +++ b/external/src/cryptonote/crypto-ops.h @@ -0,0 +1,165 @@ +// Copyright (c) 2014-2020, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +#pragma once + +/* From fe.h */ + +typedef int32_t fe[10]; + +/* From ge.h */ + +typedef struct { + fe X; + fe Y; + fe Z; +} ge_p2; + +typedef struct { + fe X; + fe Y; + fe Z; + fe T; +} ge_p3; + +typedef struct { + fe X; + fe Y; + fe Z; + fe T; +} ge_p1p1; + +typedef struct { + fe yplusx; + fe yminusx; + fe xy2d; +} ge_precomp; + +typedef struct { + fe YplusX; + fe YminusX; + fe Z; + fe T2d; +} ge_cached; + +/* From ge_add.c */ + +void ge_add(ge_p1p1 *, const ge_p3 *, const ge_cached *); + +/* From ge_double_scalarmult.c, modified */ + +typedef ge_cached ge_dsmp[8]; +extern const ge_precomp ge_Bi[8]; +void ge_dsm_precomp(ge_dsmp r, const ge_p3 *s); +void ge_double_scalarmult_base_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *); +void ge_triple_scalarmult_base_vartime(ge_p2 *, const unsigned char *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp); +void ge_double_scalarmult_base_vartime_p3(ge_p3 *, const unsigned char *, const ge_p3 *, const unsigned char *); + +/* From ge_frombytes.c, modified */ + +extern const fe fe_sqrtm1; +extern const fe fe_d; +int ge_frombytes_vartime(ge_p3 *, const unsigned char *); + +/* From ge_p1p1_to_p2.c */ + +void ge_p1p1_to_p2(ge_p2 *, const ge_p1p1 *); + +/* From ge_p1p1_to_p3.c */ + +void ge_p1p1_to_p3(ge_p3 *, const ge_p1p1 *); + +/* From ge_p2_dbl.c */ + +void ge_p2_dbl(ge_p1p1 *, const ge_p2 *); + +/* From ge_p3_to_cached.c */ + +extern const fe fe_d2; +void ge_p3_to_cached(ge_cached *, const ge_p3 *); + +/* From ge_p3_to_p2.c */ + +void ge_p3_to_p2(ge_p2 *, const ge_p3 *); + +/* From ge_p3_tobytes.c */ + +void ge_p3_tobytes(unsigned char *, const ge_p3 *); + +/* From ge_scalarmult_base.c */ + +extern const ge_precomp ge_base[32][8]; +void ge_scalarmult_base(ge_p3 *, const unsigned char *); + +/* From ge_tobytes.c */ + +void ge_tobytes(unsigned char *, const ge_p2 *); + +/* From sc_reduce.c */ + +void sc_reduce(unsigned char *); + +/* New code */ + +void ge_scalarmult(ge_p2 *, const unsigned char *, const ge_p3 *); +void ge_scalarmult_p3(ge_p3 *, const unsigned char *, const ge_p3 *); +void ge_double_scalarmult_precomp_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *, const ge_dsmp); +void ge_triple_scalarmult_precomp_vartime(ge_p2 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp); +void ge_double_scalarmult_precomp_vartime2(ge_p2 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp); +void ge_double_scalarmult_precomp_vartime2_p3(ge_p3 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp); +void ge_mul8(ge_p1p1 *, const ge_p2 *); +extern const fe fe_ma2; +extern const fe fe_ma; +extern const fe fe_fffb1; +extern const fe fe_fffb2; +extern const fe fe_fffb3; +extern const fe fe_fffb4; +extern const ge_p3 ge_p3_identity; +extern const ge_p3 ge_p3_H; +void ge_fromfe_frombytes_vartime(ge_p2 *, const unsigned char *); +void sc_0(unsigned char *); +void sc_reduce32(unsigned char *); +void sc_add(unsigned char *, const unsigned char *, const unsigned char *); +void sc_sub(unsigned char *, const unsigned char *, const unsigned char *); +void sc_mulsub(unsigned char *, const unsigned char *, const unsigned char *, const unsigned char *); +void sc_mul(unsigned char *, const unsigned char *, const unsigned char *); +void sc_muladd(unsigned char *s, const unsigned char *a, const unsigned char *b, const unsigned char *c); +int sc_check(const unsigned char *); +int sc_isnonzero(const unsigned char *); /* Doesn't normalize */ + +// internal +uint64_t load_3(const unsigned char *in); +uint64_t load_4(const unsigned char *in); +void ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); +void fe_add(fe h, const fe f, const fe g); +void fe_tobytes(unsigned char *, const fe); +void fe_invert(fe out, const fe z); + +int ge_p3_is_point_at_infinity(const ge_p3 *p); diff --git a/external/src/libsodium/.github/workflows/ci.yml b/external/src/libsodium/.github/workflows/ci.yml new file mode 100644 index 0000000..88b5037 --- /dev/null +++ b/external/src/libsodium/.github/workflows/ci.yml @@ -0,0 +1,125 @@ +name: CI + +on: + push: + branches: [master, stable, next] + pull_request: + branches: [master, stable, next] + + workflow_dispatch: + +jobs: + tcc: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Update packages list + run: sudo apt-get update + + - name: Install dependencies + run: sudo apt-get install -y build-essential libtool autoconf automake tcc + + - name: Autogen + run: ./autogen.sh -s + + - name: Compilation with tcc + run: | + env CC=tcc CFLAGS='-w' CPPFLAGS="-DDEV_MODE=1" ./configure --prefix=/tmp --disable-dependency-tracking --disable-shared || cat config.log + make -j $(nproc) && make check && make install + env CC=tcc CPPFLAGS='-I/tmp/include' LDFLAGS='-L/tmp/lib' LD_LIBRARY_PATH='/tmp/lib' ./test/constcheck.sh + make uninstall + make distclean + + regular: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Update packages list + run: sudo apt-get update + + - name: Install dependencies + run: sudo apt-get install -y build-essential libtool autoconf automake + + - name: Autogen + run: ./autogen.sh -s + + - name: C99 compat check + run: | + env CPPFLAGS="-DDEV_MODE=1" ./configure --disable-dependency-tracking + make -j $(nproc) CFLAGS='-g0' > /dev/null && cp src/libsodium/.libs/libsodium.so lib.so && make clean > /dev/null && make CFLAGS='-g0' CPPFLAGS='-DDEV_MODE=1 -DSODIUM_C99\(X\)=' > /dev/null && cp src/libsodium/.libs/libsodium.so lib-oldc.so && cmp lib.so lib-oldc.so && echo No binary changes && make clean > /dev/null + make distcheck + make distclean > /dev/null + + - name: Regular compilation + run: | + env CPPFLAGS="-DDEV_MODE=1" ./configure --disable-dependency-tracking --enable-minimal + make -j $(nproc) + make check + ( echo '#include ' ; echo 'int main(void) { return sodium_init(); }' ) > /tmp/main.c && gcc -DDEV_MODE=1 -Isrc/libsodium/include -Isrc/libsodium/include/sodium $(find src -name '*.c' -o -name '*.S') /tmp/main.c + make distclean > /dev/null + + check-globals: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Update packages list + run: sudo apt-get update + + - name: Install dependencies + run: sudo apt-get install -y build-essential libtool autoconf automake + + - name: Autogen + run: ./autogen.sh -s + + - name: Check globals + run: | + if [ -x test/rename-globals.sh ]; then test/rename-globals.sh; fi + + other-comp: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Update packages list + run: sudo apt-get update + + - name: Install dependencies + run: sudo apt-get install -y build-essential libtool autoconf automake clang + + - name: Autogen + run: ./autogen.sh -s + + - name: Compilation with g++ + run: | + env CC=g++ CPPFLAGS="-DDEV_MODE=1" ./configure --disable-dependency-tracking + make -j $(nproc) check + make clean > /dev/null + + - name: Compilation with clang + run: | + env CC=clang CPPFLAGS="-DDEV_MODE=1" ./configure --disable-dependency-tracking + make -j $(nproc) check + make clean > /dev/null + + other-arch: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Update packages list + run: sudo apt-get update + + - name: Install dependencies + run: sudo apt-get install -y build-essential libtool autoconf automake qemu-user-static gcc-powerpc-linux-gnu + + - name: Autogen + run: ./autogen.sh -s + + - name: Big-Endian PowerPC compilation + run: | + env CPPFLAGS="-DDEV_MODE=1" ./configure --disable-dependency-tracking --host=powerpc-linux-gnu + make -j $(nproc) + make clean > /dev/null diff --git a/external/src/libsodium/.github/workflows/codeql-analysis.yml b/external/src/libsodium/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..bd58e1f --- /dev/null +++ b/external/src/libsodium/.github/workflows/codeql-analysis.yml @@ -0,0 +1,31 @@ +name: "CodeQL scan" + +on: + push: + pull_request: + schedule: + - cron: '0 17 * * 2' + +jobs: + CodeQL-Build: + + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + fetch-depth: 2 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: cpp + + - run: | + ./autogen.sh -s + env CPPFLAGS="-DDEV_MODE=1" ./configure --disable-dependency-tracking + make -j $(nproc) check + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/external/src/libsodium/.github/workflows/dotnet-core.yml b/external/src/libsodium/.github/workflows/dotnet-core.yml new file mode 100644 index 0000000..7cba736 --- /dev/null +++ b/external/src/libsodium/.github/workflows/dotnet-core.yml @@ -0,0 +1,316 @@ +name: .NET Package + +on: + push: + branches: + - stable + - next + +jobs: + + build-windows: + runs-on: windows-latest + steps: + - uses: actions/checkout@v1 + - name: buildbase.bat + run: buildbase.bat ..\vs2019\libsodium.sln 16 + working-directory: builds/msvc/build/ + shell: cmd + - uses: actions/upload-artifact@v2 + with: + name: build-win-x64 + path: bin/x64/Release/v142/dynamic/libsodium.dll + - uses: actions/upload-artifact@v2 + with: + name: build-win-x86 + path: bin/Win32/Release/v142/dynamic/libsodium.dll + + build-linux-glibc: + runs-on: ubuntu-latest + container: + image: ubuntu:20.04 + steps: + - name: Set up build environment + run: | + apt-get update && apt-get install -y build-essential + - uses: actions/checkout@v1 + - name: configure + run: ./configure --disable-debug --prefix=$PWD/.libsodium-build + - name: make + run: make + - name: make check + run: make check + - name: make install + run: make install + - name: strip + run: strip --strip-all .libsodium-build/lib/libsodium.so + - uses: actions/upload-artifact@v2 + with: + name: build-linux-x64 + path: .libsodium-build/lib/libsodium.so + + build-linux-glibc-arm64: + runs-on: ubuntu-latest + steps: + - name: Set up build environment + run: | + export DEBIAN_FRONTEND=noninteractive + + cat <<-EOF | sudo tee /etc/apt/sources.list.d/arm64.list >/dev/null + deb [arch=arm64] http://ports.ubuntu.com/ focal main restricted + deb [arch=arm64] http://ports.ubuntu.com/ focal-updates main restricted + deb [arch=arm64] http://ports.ubuntu.com/ focal universe + deb [arch=arm64] http://ports.ubuntu.com/ focal-updates universe + deb [arch=arm64] http://ports.ubuntu.com/ focal multiverse + deb [arch=arm64] http://ports.ubuntu.com/ focal-updates multiverse + deb [arch=arm64] http://ports.ubuntu.com/ focal-backports main restricted universe multiverse + EOF + + sudo sed -i 's/deb h/deb [arch=amd64] h/g' /etc/apt/sources.list + + sudo dpkg --add-architecture arm64 + + sudo apt-get update && sudo apt-get install -y build-essential qemu-user qemu-user-static gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libstdc++6:arm64 + + - uses: actions/checkout@v1 + - name: configure + run: ./configure --disable-debug --prefix=$PWD/.libsodium-build --host=aarch64-linux-gnu + - name: make + run: make -j $(nproc) + + - name: make check + run: | + make check + + - name: make install + run: make install + + - name: strip + run: aarch64-linux-gnu-strip --strip-all .libsodium-build/lib/libsodium.so + - uses: actions/upload-artifact@v2 + with: + name: build-linux-arm64 + path: .libsodium-build/lib/libsodium.so + + build-linux-glibc-arm: + runs-on: ubuntu-20.04 + steps: + - name: Set up build environment + run: | + export DEBIAN_FRONTEND=noninteractive + + cat <<-EOF | sudo tee /etc/apt/sources.list.d/armhf.list >/dev/null + deb [arch=armhf] http://ports.ubuntu.com/ focal main restricted + deb [arch=armhf] http://ports.ubuntu.com/ focal-updates main restricted + deb [arch=armhf] http://ports.ubuntu.com/ focal universe + deb [arch=armhf] http://ports.ubuntu.com/ focal-updates universe + deb [arch=armhf] http://ports.ubuntu.com/ focal multiverse + deb [arch=armhf] http://ports.ubuntu.com/ focal-updates multiverse + deb [arch=armhf] http://ports.ubuntu.com/ focal-backports main restricted universe multiverse + EOF + + sudo sed -i 's/deb h/deb [arch=amd64] h/g' /etc/apt/sources.list + + sudo dpkg --add-architecture armhf + + sudo apt-get update && sudo apt-get install -y build-essential qemu-user qemu-user-static gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libstdc++6:armhf + + - uses: actions/checkout@v1 + - name: configure + run: ./configure --disable-debug --prefix=$PWD/.libsodium-build --host=arm-linux-gnueabihf + - name: make + run: make -j $(nproc) + + - name: make check + run: | + make check + + - name: make install + run: make install + + - name: strip + run: arm-linux-gnueabihf-strip --strip-all .libsodium-build/lib/libsodium.so + - uses: actions/upload-artifact@v2 + with: + name: build-linux-arm + path: .libsodium-build/lib/libsodium.so + + build-linux-musl: + runs-on: ubuntu-latest + container: + image: alpine:3.13 + steps: + - name: Set up build environment + run: | + apk update + apk add alpine-sdk ca-certificates + - uses: actions/checkout@v1 + - name: configure + run: ./configure --disable-debug --prefix=$PWD/.libsodium-build + - name: make + run: make + - name: make check + run: make check + - name: make install + run: make install + - name: strip + run: strip --strip-all .libsodium-build/lib/libsodium.so + - uses: actions/upload-artifact@v2 + with: + name: build-linux-musl-x64 + path: .libsodium-build/lib/libsodium.so + + build-macos: + runs-on: macos-latest + steps: + - uses: actions/checkout@v1 + - name: configure + run: ./configure --disable-debug --prefix=$PWD/.libsodium-build + - name: make + run: make + - name: make check + run: make check + - name: make install + run: make install + - uses: actions/upload-artifact@v2 + with: + name: build-osx-x64 + path: .libsodium-build/lib/libsodium.dylib + + pack: + runs-on: ubuntu-latest + needs: + - build-windows + - build-linux-glibc + - build-linux-glibc-arm + - build-linux-glibc-arm64 + - build-linux-musl + - build-macos + container: + image: mcr.microsoft.com/dotnet/sdk:5.0 + env: + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: 1 + steps: + - uses: actions/checkout@v1 + - uses: actions/download-artifact@v2 + with: + name: build-win-x64 + path: .libsodium-pack/runtimes/win-x64/native/ + - uses: actions/download-artifact@v2 + with: + name: build-win-x86 + path: .libsodium-pack/runtimes/win-x86/native/ + - uses: actions/download-artifact@v2 + with: + name: build-linux-x64 + path: .libsodium-pack/runtimes/linux-x64/native/ + - uses: actions/download-artifact@v2 + with: + name: build-linux-arm64 + path: .libsodium-pack/runtimes/linux-arm64/native/ + - uses: actions/download-artifact@v2 + with: + name: build-linux-arm + path: .libsodium-pack/runtimes/linux-arm/native/ + - uses: actions/download-artifact@v2 + with: + name: build-linux-musl-x64 + path: .libsodium-pack/runtimes/linux-musl-x64/native/ + - uses: actions/download-artifact@v2 + with: + name: build-osx-x64 + path: .libsodium-pack/runtimes/osx-x64/native/ + - name: Copy files + run: cp AUTHORS ChangeLog LICENSE packaging/dotnet-core/libsodium.pkgproj .libsodium-pack/ + - name: Create NuGet package + run: dotnet pack -c Release .libsodium-pack/libsodium.pkgproj + - uses: actions/upload-artifact@v2 + with: + name: nuget-package + path: .libsodium-pack/bin/Release/*.nupkg + + build-test-binaries: + runs-on: ubuntu-latest + needs: + - pack + container: + image: mcr.microsoft.com/dotnet/sdk:5.0 + env: + DOTNET_CLI_TELEMETRY_OPTOUT: 1 + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1 + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: 1 + steps: + - uses: actions/checkout@v1 + - uses: actions/download-artifact@v2 + with: + name: nuget-package + path: .libsodium-pack/ + - name: dotnet new + run: dotnet new console -n Tests -o .libsodium-test/ + - name: dotnet add package libsodium + run: dotnet add .libsodium-test/Tests.csproj package libsodium -s $PWD/.libsodium-pack + - name: Copy files + run: cp -f packaging/dotnet-core/test.cs .libsodium-test/Program.cs + - name: dotnet publish linux-x64 + run: dotnet publish -c Release -r linux-x64 --self-contained true -p:PublishTrimmed=true + working-directory: .libsodium-test/ + - name: dotnet publish linux-arm + run: dotnet publish -c Release -r linux-arm --self-contained true -p:PublishTrimmed=true + working-directory: .libsodium-test/ + - name: dotnet publish linux-arm64 + run: dotnet publish -c Release -r linux-arm64 --self-contained true -p:PublishTrimmed=true + working-directory: .libsodium-test/ + - name: Move Build Output + run: | + mkdir .libsodium-builds + mv .libsodium-test/bin/Release/net5.0/linux-arm/publish .libsodium-builds/linux-arm + mv .libsodium-test/bin/Release/net5.0/linux-arm64/publish .libsodium-builds/linux-arm64 + mv .libsodium-test/bin/Release/net5.0/linux-x64/publish .libsodium-builds/linux-x64 + - uses: actions/upload-artifact@v2 + with: + name: test-builds + path: .libsodium-builds/* + + run-test-binaries: + runs-on: ubuntu-20.04 + needs: + - build-test-binaries + env: + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: 1 + strategy: + matrix: + arch: [x64, arm, arm64] + steps: + - name: Set up build environment + run: | + export DEBIAN_FRONTEND=noninteractive + + cat <<-EOF | sudo tee /etc/apt/sources.list.d/multiarch.list >/dev/null + deb [arch=armhf,arm64] http://ports.ubuntu.com/ focal main restricted + deb [arch=armhf,arm64] http://ports.ubuntu.com/ focal-updates main restricted + deb [arch=armhf,arm64] http://ports.ubuntu.com/ focal universe + deb [arch=armhf,arm64] http://ports.ubuntu.com/ focal-updates universe + deb [arch=armhf,arm64] http://ports.ubuntu.com/ focal multiverse + deb [arch=armhf,arm64] http://ports.ubuntu.com/ focal-updates multiverse + deb [arch=armhf,arm64] http://ports.ubuntu.com/ focal-backports main restricted universe multiverse + EOF + + sudo sed -i 's/deb h/deb [arch=amd64] h/g' /etc/apt/sources.list + + sudo dpkg --add-architecture armhf + sudo dpkg --add-architecture arm64 + + sudo apt-get update && sudo apt-get install -y qemu-user qemu-user-static libstdc++6:armhf libstdc++6:arm64 + + - uses: actions/download-artifact@v2 + with: + name: test-builds + path: .libsodium-builds/ + + - name: Run ${{ matrix.arch }} + run: | + chmod +x .libsodium-builds/linux-${{ matrix.arch }}/Tests + .libsodium-builds/linux-${{ matrix.arch }}/Tests + diff --git a/external/src/libsodium/.gitignore b/external/src/libsodium/.gitignore new file mode 100644 index 0000000..c842285 --- /dev/null +++ b/external/src/libsodium/.gitignore @@ -0,0 +1,162 @@ +*.bc +*.dSYM +*.done +*.final +*.gcda +*.gcno +*.i +*.la +*.lo +*.log +*.mem +*.nexe +*.o +*.plist +*.scan +*.sdf +*.status +*.tar.* +*.wasm +*.wast +*~ +.DS_Store +.deps +.dirstamp +.done +.libs +/bin/ +/obj/ +Build +INSTALL +Makefile +Makefile.in +Vagrantfile +aclocal.m4 +android-toolchain +android-toolchain-* +autom4te.cache +build +compile +confdefs.h +config.* +configure +configure.lineno +coverage.info +depcomp +install-sh +libsodium-*.tar.bz2 +libsodium-*.tar.gz +libsodium-*.vcproj +libsodium-*.vcproj.filters +libsodium-*.vcxproj +libsodium-*.vcxproj.filters +libsodium-android-* +libsodium-ios +libsodium-js +libsodium-js-* +libsodium-nativeclient +libsodium-nativeclient-* +libsodium-osx +libsodium-uninstalled.pc +libsodium-wasm32-wasi +libsodium-win32 +libsodium-win64 +libsodium.pc +libtool +ltmain.sh +m4/argz.m4 +m4/libtool.m4 +m4/ltoptions.m4 +m4/ltsugar.m4 +m4/ltversion.m4 +m4/lt~obsolete.m4 +man/*.html +man/Makefile.in +missing +src/libsodium/*.def +src/libsodium/include/sodium/version.h +stamp-* +test-driver +test/default/*.asm.js +test/default/*.res +test/default/*.trs +test/default/aead_aes256gcm +test/default/aead_aes256gcm2 +test/default/aead_chacha20poly1305 +test/default/aead_chacha20poly13052 +test/default/aead_xchacha20poly1305 +test/default/auth +test/default/auth2 +test/default/auth3 +test/default/auth5 +test/default/auth6 +test/default/auth7 +test/default/box +test/default/box2 +test/default/box7 +test/default/box8 +test/default/box_easy +test/default/box_easy2 +test/default/box_seal +test/default/box_seed +test/default/browser +test/default/chacha20 +test/default/codecs +test/default/core1 +test/default/core2 +test/default/core3 +test/default/core4 +test/default/core5 +test/default/core6 +test/default/core_ed25519 +test/default/core_ristretto255 +test/default/ed25519_convert +test/default/generichash +test/default/generichash2 +test/default/generichash3 +test/default/hash +test/default/hash3 +test/default/kdf +test/default/keygen +test/default/kx +test/default/metamorphic +test/default/misuse +test/default/onetimeauth +test/default/onetimeauth2 +test/default/onetimeauth7 +test/default/pwhash_argon2i +test/default/pwhash_argon2id +test/default/pwhash_scrypt +test/default/pwhash_scrypt_ll +test/default/randombytes +test/default/scalarmult +test/default/scalarmult2 +test/default/scalarmult5 +test/default/scalarmult6 +test/default/scalarmult7 +test/default/scalarmult8 +test/default/scalarmult_ed25519 +test/default/scalarmult_ristretto255 +test/default/secretbox +test/default/secretbox2 +test/default/secretbox7 +test/default/secretbox8 +test/default/secretbox_easy +test/default/secretbox_easy2 +test/default/secretstream +test/default/shorthash +test/default/sign +test/default/siphashx24 +test/default/sodium_core +test/default/sodium_utils +test/default/sodium_utils2 +test/default/sodium_utils3 +test/default/sodium_version +test/default/stream +test/default/stream2 +test/default/stream3 +test/default/stream4 +test/default/verify1 +test/default/xchacha20 +test/js.done +testing diff --git a/external/src/libsodium/AUTHORS b/external/src/libsodium/AUTHORS new file mode 100644 index 0000000..f4a4b9d --- /dev/null +++ b/external/src/libsodium/AUTHORS @@ -0,0 +1,145 @@ + +Designers +========= + +argon2 Alex Biryukov + Daniel Dinu + Dmitry Khovratovich + +blake2 Jean-Philippe Aumasson + Christian Winnerlein + Samuel Neves + Zooko Wilcox-O'Hearn + +chacha20 Daniel J. Bernstein + +chacha20poly1305 Adam Langley + Yoav Nir + +curve25519 Daniel J. Bernstein + +curve25519xsalsa20poly1305 Daniel J. Bernstein + +ed25519 Daniel J. Bernstein + Bo-Yin Yang + Niels Duif + Peter Schwabe + Tanja Lange + +poly1305 Daniel J. Bernstein + +ristretto Mike Hamburg + Henry de Valence + Jack Grigg + George Tankersley + Filippo Valsorda + Isis Lovecruft + +salsa20 Daniel J. Bernstein + +scrypt Colin Percival + +siphash Jean-Philippe Aumasson + Daniel J. Bernstein + +Implementors +============ + +crypto_aead/aes256gcm/aesni Romain Dolbeau + Frank Denis + +crypto_aead/chacha20poly1305 Frank Denis + +crypto_aead/xchacha20poly1305 Frank Denis + Jason A. Donenfeld + +crypto_auth/hmacsha256 Colin Percival +crypto_auth/hmacsha512 +crypto_auth/hmacsha512256 + +crypto_box/curve25519xsalsa20poly1305 Daniel J. Bernstein + +crypto_box/curve25519xchacha20poly1305 Frank Denis + +crypto_core/ed25519 Daniel J. Bernstein + Adam Langley + Frank Denis + +crypto_core/hchacha20 Frank Denis + +crypto_core/hsalsa20 Daniel J. Bernstein +crypto_core/salsa + +crypto_generichash/blake2b Jean-Philippe Aumasson + Christian Winnerlein + Samuel Neves + Zooko Wilcox-O'Hearn + +crypto_hash/sha256 Colin Percival +crypto_hash/sha512 +crypto_hash/sha512256 + +crypto_kdf Frank Denis + +crypto_kx Frank Denis + +crypto_onetimeauth/poly1305/donna Andrew "floodyberry" Moon +crypto_onetimeauth/poly1305/sse2 + +crypto_pwhash/argon2 Samuel Neves + Dmitry Khovratovich + Jean-Philippe Aumasson + Daniel Dinu + Thomas Pornin + +crypto_pwhash/scryptsalsa208sha256 Colin Percival + Alexander Peslyak + +crypto_scalarmult/curve25519/ref10 Daniel J. Bernstein + +crypto_scalarmult/curve25519/sandy2x Tung Chou + +crypto_scalarmult/ed25519 Frank Denis + +crypto_scalarmult/ristretto255 Frank Denis + +crypto_secretbox/xsalsa20poly1305 Daniel J. Bernstein + +crypto_secretbox/xchacha20poly1305 Frank Denis + +crypto_secretstream/xchacha20poly1305 Frank Denis + +crypto_shorthash/siphash24 Jean-Philippe Aumasson + Daniel J. Bernstein + +crypto_sign/ed25519 Peter Schwabe + Daniel J. Bernstein + Niels Duif + Tanja Lange + Bo-Yin Yang + +crypto_stream/chacha20/ref Daniel J. Bernstein + +crypto_stream/chacha20/dolbeau Romain Dolbeau + Daniel J. Bernstein + +crypto_stream/salsa20/ref Daniel J. Bernstein +crypto_stream/salsa20/xmm6 + +crypto_stream/salsa20/xmm6int Romain Dolbeau + Daniel J. Bernstein + +crypto_stream/salsa2012/ref Daniel J. Bernstein +crypto_stream/salsa2008/ref + +crypto_stream/xchacha20 Frank Denis + +crypto_verify Frank Denis + +sodium/codecs.c Frank Denis + Thomas Pornin + Christian Winnerlein + +sodium/core.c Frank Denis +sodium/runtime.h +sodium/utils.c diff --git a/external/src/libsodium/ChangeLog b/external/src/libsodium/ChangeLog new file mode 100644 index 0000000..9388fd1 --- /dev/null +++ b/external/src/libsodium/ChangeLog @@ -0,0 +1,564 @@ + +* Version 1.0.18 + - Enterprise versions of Visual Studio are now supported. + - Visual Studio 2019 is now supported. + - 32-bit binaries for Visual Studio 2010 are now provided. + - A test designed to trigger an OOM condition didn't work on Linux systems +with memory overcommit turned on. It has been removed in order to fix +Ansible builds. + - Emscripten: `print` and `printErr` functions are overridden to send +errors to the console, if there is one. + - Emscripten: `UTF8ToString()` is now exported since `Pointer_stringify()` +has been deprecated. + - Libsodium version detection has been fixed in the CMake recipe. + - Generic hashing got a 10% speedup on AVX2. + - New target: WebAssembly/WASI (compile with `dist-builds/wasm32-wasi.sh`). + - New functions to map a hash to an edwards25519 point or get a random point: +`core_ed25519_from_hash()` and `core_ed25519_random()`. + - `crypto_core_ed25519_scalar_mul()` has been implemented for +`scalar*scalar (mod L)` multiplication. + - Support for the Ristretto group has been implemented for interoperability +with wasm-crypto. + - Improvements have been made to the test suite. + - Portability improvements have been made. + - `getentropy()` is now used on systems providing this system call. + - `randombytes_salsa20` has been renamed to `randombytes_internal`. + - Support for NativeClient has been removed. + - Most `((nonnull))` attributes have been relaxed to allow 0-length inputs +to be `NULL`. + - The `-ftree-vectorize` and `-ftree-slp-vectorize` compiler switches are +now used, if available, for optimized builds. + +* Version 1.0.17 + - Bug fix: `sodium_pad()` didn't properly support block sizes >= 256 bytes. + - JS/WebAssembly: some old iOS versions can't instantiate the WebAssembly +module; fall back to Javascript on these. + - JS/WebAssembly: compatibility with newer Emscripten versions. + - Bug fix: `crypto_pwhash_scryptsalsa208sha256_str_verify()` and +`crypto_pwhash_scryptsalsa208sha256_str_needs_rehash()` didn't return +`EINVAL` on input strings with a short length, unlike their high-level +counterpart. + - Added a workaround for Visual Studio 2010 bug causing CPU features +not to be detected. + - Portability improvements. + - Test vectors from Project Wycheproof have been added. + - New low-level APIs for arithmetic mod the order of the prime order group: +`crypto_core_ed25519_scalar_random()`, `crypto_core_ed25519_scalar_reduce()`, +`crypto_core_ed25519_scalar_invert()`, `crypto_core_ed25519_scalar_negate()`, +`crypto_core_ed25519_scalar_complement()`, `crypto_core_ed25519_scalar_add()` +and `crypto_core_ed25519_scalar_sub()`. + - New low-level APIs for scalar multiplication without clamping: +`crypto_scalarmult_ed25519_base_noclamp()` and +`crypto_scalarmult_ed25519_noclamp()`. These new APIs are especially useful +for blinding. + - `sodium_sub()` has been implemented. + - Support for WatchOS has been added. + - getrandom(2) is now used on FreeBSD 12+. + - The `nonnull` attribute has been added to all relevant prototypes. + - More reliable AVX512 detection. + - Javascript/Webassembly builds now use dynamic memory growth. + +* Version 1.0.16 + - Signatures computations and verifications are now way faster on +64-bit platforms with compilers supporting 128-bit arithmetic (gcc, +clang, icc). This includes the WebAssembly target. + - New low-level APIs for computations over edwards25519: +`crypto_scalarmult_ed25519()`, `crypto_scalarmult_ed25519_base()`, +`crypto_core_ed25519_is_valid_point()`, `crypto_core_ed25519_add()`, +`crypto_core_ed25519_sub()` and `crypto_core_ed25519_from_uniform()` +(elligator representative to point). + - `crypto_sign_open()`, `crypto_sign_verify_detached() and +`crypto_sign_edwards25519sha512batch_open` now reject public keys in +non-canonical form in addition to low-order points. + - The library can be built with `ED25519_NONDETERMINISTIC` defined in +order to use synthetic nonces for EdDSA. This is disabled by default. + - Webassembly: `crypto_pwhash_*()` functions are now included in +non-sumo builds. + - `sodium_stackzero()` was added to wipe content off the stack. + - Android: support new SDKs where unified headers have become the +default. + - The Salsa20-based PRNG example is now thread-safe on platforms with +support for thread-local storage, optionally mixes bits from RDRAND. + - CMAKE: static library detection on Unix systems has been improved +(thanks to @BurningEnlightenment, @nibua-r, @mellery451) + - Argon2 and scrypt are slightly faster on Linux. + +* Version 1.0.15 + - The default password hashing algorithm is now Argon2id. The +`pwhash_str_verify()` function can still verify Argon2i hashes +without any changes, and `pwhash()` can still compute Argon2i hashes +as well. + - The aes128ctr primitive was removed. It was slow, non-standard, not +authenticated, and didn't seem to be used by any opensource project. + - Argon2id required at least 3 passes like Argon2i, despite a minimum +of `1` as defined by the `OPSLIMIT_MIN` constant. This has been fixed. + - The secretstream construction was slightly changed to be consistent +with forthcoming variants. + - The Javascript and Webassembly versions have been merged, and the +module now returns a `.ready` promise that will resolve after the +Webassembly code is loaded and compiled. + - Note that due to these incompatible changes, the library version +major was bumped up. + +* Version 1.0.14 + - iOS binaries should now be compatible with WatchOS and TVOS. + - WebAssembly is now officially supported. Special thanks to +@facekapow and @pepyakin who helped to make it happen. + - Internal consistency checks failing and primitives used with +dangerous/out-of-bounds/invalid parameters used to call abort(3). +Now, a custom handler *that doesn't return* can be set with the +`set_sodium_misuse()` function. It still aborts by default or if the +handler ever returns. This is not a replacement for non-fatal, +expected runtime errors. This handler will be only called in +unexpected situations due to potential bugs in the library or in +language bindings. + - `*_MESSAGEBYTES_MAX` macros (and the corresponding +`_messagebytes_max()` symbols) have been added to represent the +maximum message size that can be safely handled by a primitive. +Language bindings are encouraged to check user inputs against these +maximum lengths. + - The test suite has been extended to cover more edge cases. + - crypto_sign_ed25519_pk_to_curve25519() now rejects points that are +not on the curve, or not in the main subgroup. + - Further changes have been made to ensure that smart compilers will +not optimize out code that we don't want to be optimized. + - Visual Studio solutions are now included in distribution tarballs. + - The `sodium_runtime_has_*` symbols for CPU features detection are +now defined as weak symbols, i.e. they can be replaced with an +application-defined implementation. This can be useful to disable +AVX* when temperature/power consumption is a concern. + - `crypto_kx_*()` now aborts if called with no non-NULL pointers to +store keys to. + - SSE2 implementations of `crypto_verify_*()` have been added. + - Passwords can be hashed using a specific algorithm with the new +`crypto_pwhash_str_alg()` function. + - Due to popular demand, base64 encoding (`sodium_bin2base64()`) and +decoding (`sodium_base642bin()`) have been implemented. + - A new `crypto_secretstream_*()` API was added to safely encrypt files +and multi-part messages. + - The `sodium_pad()` and `sodium_unpad()` helper functions have been +added in order to add & remove padding. + - An AVX512 optimized implementation of Argon2 has been added (written +by Ondrej MosnáÄek, thanks!) + - The `crypto_pwhash_str_needs_rehash()` function was added to check if +a password hash string matches the given parameters, or if it needs an +update. + - The library can now be compiled with recent versions of +emscripten/binaryen that don't allow multiple variables declarations +using a single `var` statement. + +* Version 1.0.13 + - Javascript: the sumo builds now include all symbols. They were +previously limited to symbols defined in minimal builds. + - The public `crypto_pwhash_argon2i_MEMLIMIT_MAX` constant was +incorrectly defined on 32-bit platforms. This has been fixed. + - Version 1.0.12 didn't compile on OpenBSD/i386 using the base gcc +compiler. This has been fixed. + - The Android compilation scripts have been updated for NDK r14b. + - armv7s-optimized code was re-added to iOS builds. + - An AVX2 optimized implementation of the Argon2 round function was +added. + - The Argon2id variant of Argon2 has been implemented. The +high-level `crypto_pwhash_str_verify()` function automatically detects +the algorithm and can verify both Argon2i and Argon2id hashed passwords. +The default algorithm for newly hashed passwords remains Argon2i in +this version to avoid breaking compatibility with verifiers running +libsodium <= 1.0.12. + - A `crypto_box_curve25519xchacha20poly1305_seal*()` function set was +implemented. + - scrypt was removed from minimal builds. + - libsodium is now available on NuGet. + +* Version 1.0.12 + - Ed25519ph was implemented, adding a multi-part signature API +(`crypto_sign_init()`, `crypto_sign_update()`, `crypto_sign_final_*()`). + - New constants and related accessors have been added for Scrypt and +Argon2. + - XChaCha20 has been implemented. Like XSalsa20, this construction +extends the ChaCha20 cipher to accept a 192-bit nonce. This makes it safe +to use ChaCha20 with random nonces. + - `crypto_secretbox`, `crypto_box` and `crypto_aead` now offer +variants leveraging XChaCha20. + - SHA-2 is about 20% faster, which also gives a speed boost to +signature and signature verification. + - AVX2 implementations of Salsa20 and ChaCha20 have been added. They +are twice as fast as the SSE2 implementations. The speed gain is +even more significant on Windows, that previously didn't use +vectorized implementations. + - New high-level API: `crypto_kdf`, to easily derive one or more +subkeys from a master key. + - Siphash with a 128-bit output has been implemented, and is +available as `crypto_shorthash_siphashx_*`. + - New `*_keygen()` helpers functions have been added to create secret +keys for all constructions. This improves code clarity and can prevent keys +from being partially initialized. + - A new `randombytes_buf_deterministic()` function was added to +deterministically fill a memory region with pseudorandom data. This +function can especially be useful to write reproducible tests. + - A preliminary `crypto_kx_*()` API was added to compute shared session +keys. + - AVX2 detection is more reliable. + - The pthreads library is not required any more when using MingW. + - `contrib/Findsodium.cmake` was added as an example to include +libsodium in a project using cmake. + - Compatibility with gcc 2.x has been restored. + - Minimal builds can be checked using `sodium_library_minimal()`. + - The `--enable-opt` compilation switch has become compatible with more +platforms. + - Android builds are now using clang on platforms where it is +available. + +* Version 1.0.11 + - `sodium_init()` is now thread-safe, and can be safely called multiple +times. + - Android binaries now properly support 64-bit Android, targeting +platform 24, but without breaking compatibility with platforms 16 and +21. + - Better support for old gcc versions. + - On FreeBSD, core dumps are disabled on regions allocated with +sodium allocation functions. + - AVX2 detection was fixed, resulting in faster Blake2b hashing on +platforms where it was not properly detected. + - The Sandy2x Curve25519 implementation was not as fast as expected +on some platforms. This has been fixed. + - The NativeClient target was improved. Most notably, it now supports +optimized implementations, and uses pepper_49 by default. + - The library can be compiled with recent Emscripten versions. +Changes have been made to produce smaller code, and the default heap +size was reduced in the standard version. + - The code can now be compiled on SLES11 service pack 4. + - Decryption functions can now accept a NULL pointer for the output. +This checks the MAC without writing the decrypted message. + - crypto_generichash_final() now returns -1 if called twice. + - Support for Visual Studio 2008 was improved. + +* Version 1.0.10 + - This release only fixes a compilation issue reported with some older +gcc versions. There are no functional changes over the previous release. + +* Version 1.0.9 + - The Javascript target now includes a `--sumo` option to include all +the symbols of the original C library. + - A detached API was added to the ChaCha20-Poly1305 and AES256-GCM +implementations. + - The Argon2i password hashing function was added, and is accessible +directly and through a new, high-level `crypto_pwhash` API. The scrypt +function remains available as well. + - A speed-record AVX2 implementation of BLAKE2b was added (thanks to +Samuel Neves). + - The library can now be compiled using C++Builder (thanks to @jcolli44) + - Countermeasures for Ed25519 signatures malleability have been added +to match the irtf-cfrg-eddsa draft (note that malleability is irrelevant to +the standard definition of signature security). Signatures with a small-order +`R` point are now also rejected. + - Some implementations are now slightly faster when using the Clang +compiler. + - The HChaCha20 core function was implemented (`crypto_core_hchacha20()`). + - No-op stubs were added for all AES256-GCM public functions even when +compiled on non-Intel platforms. + - `crypt_generichash_blake2b_statebytes()` was added. + - New macros were added for the IETF variant of the ChaCha20-Poly1305 +construction. + - The library can now be compiled on Minix. + - HEASLR is now enabled on MinGW builds. + +* Version 1.0.8 + - Handle the case where the CPU supports AVX, but we are running +on an hypervisor with AVX disabled/not supported. + - Faster (2x) scalarmult_base() when using the ref10 implementation. + +* Version 1.0.7 + - More functions whose return value should be checked have been +tagged with `__attribute__ ((warn_unused_result))`: `crypto_box_easy()`, +`crypto_box_detached()`, `crypto_box_beforenm()`, `crypto_box()`, and +`crypto_scalarmult()`. + - Sandy2x, the fastest Curve25519 implementation ever, has been +merged in, and is automatically used on CPUs supporting the AVX +instructions set. + - An SSE2 optimized implementation of Poly1305 was added, and is +twice as fast as the portable one. + - An SSSE3 optimized implementation of ChaCha20 was added, and is +twice as fast as the portable one. + - Faster `sodium_increment()` for common nonce sizes. + - New helper functions have been added: `sodium_is_zero()` and + `sodium_add()`. + - `sodium_runtime_has_aesni()` now properly detects the CPU flag when + compiled using Visual Studio. + +* Version 1.0.6 + - Optimized implementations of Blake2 have been added for modern +Intel platforms. `crypto_generichash()` is now faster than MD5 and SHA1 +implementations while being far more secure. + - Functions for which the return value should be checked have been +tagged with `__attribute__ ((warn_unused_result))`. This will +intentionally break code compiled with `-Werror` that didn't bother +checking critical return values. + - The `crypto_sign_edwards25519sha512batch_*()` functions have been +tagged as deprecated. + - Undocumented symbols that were exported, but were only useful for +internal purposes have been removed or made private: +`sodium_runtime_get_cpu_features()`, the implementation-specific +`crypto_onetimeauth_poly1305_donna()` symbols, +`crypto_onetimeauth_poly1305_set_implementation()`, +`crypto_onetimeauth_poly1305_implementation_name()` and +`crypto_onetimeauth_pick_best_implementation()`. + - `sodium_compare()` now works as documented, and compares numbers +in little-endian format instead of behaving like `memcmp()`. + - The previous changes should not break actual applications, but to be +safe, the library version major was incremented. + - `sodium_runtime_has_ssse3()` and `sodium_runtime_has_sse41()` have +been added. + - The library can now be compiled with the CompCert compiler. + +* Version 1.0.5 + - Compilation issues on some platforms were fixed: missing alignment +directives were added (required at least on RHEL-6/i386), a workaround +for a VRP bug on gcc/armv7 was added, and the library can now be compiled +with the SunPro compiler. + - Javascript target: io.js is not supported any more. Use nodejs. + +* Version 1.0.4 + - Support for AES256-GCM has been added. This requires +a CPU with the aesni and pclmul extensions, and is accessible via the +crypto_aead_aes256gcm_*() functions. + - The Javascript target doesn't use eval() any more, so that the +library can be used in Chrome packaged applications. + - QNX and CloudABI are now supported. + - Support for NaCl has finally been added. + - ChaCha20 with an extended (96 bit) nonce and a 32-bit counter has +been implemented as crypto_stream_chacha20_ietf(), +crypto_stream_chacha20_ietf_xor() and crypto_stream_chacha20_ietf_xor_ic(). +An IETF-compatible version of ChaCha20Poly1305 is available as +crypto_aead_chacha20poly1305_ietf_npubbytes(), +crypto_aead_chacha20poly1305_ietf_encrypt() and +crypto_aead_chacha20poly1305_ietf_decrypt(). + - The sodium_increment() helper function has been added, to increment +an arbitrary large number (such as a nonce). + - The sodium_compare() helper function has been added, to compare +arbitrary large numbers (such as nonces, in order to prevent replay +attacks). + +* Version 1.0.3 + - In addition to sodium_bin2hex(), sodium_hex2bin() is now a +constant-time function. + - crypto_stream_xsalsa20_ic() has been added. + - crypto_generichash_statebytes(), crypto_auth_*_statebytes() and +crypto_hash_*_statebytes() have been added in order to retrieve the +size of structures keeping states from foreign languages. + - The JavaScript target doesn't require /dev/urandom or an external +randombytes() implementation any more. Other minor Emscripten-related +improvements have been made in order to support libsodium.js + - Custom randombytes implementations do not need to provide their own +implementation of randombytes_uniform() any more. randombytes_stir() +and randombytes_close() can also be NULL pointers if they are not +required. + - On Linux, getrandom(2) is being used instead of directly accessing +/dev/urandom, if the kernel supports this system call. + - crypto_box_seal() and crypto_box_seal_open() have been added. + - Visual Studio 2015 is now supported. + +* Version 1.0.2 + - The _easy and _detached APIs now support precalculated keys; +crypto_box_easy_afternm(), crypto_box_open_easy_afternm(), +crypto_box_detached_afternm() and crypto_box_open_detached_afternm() +have been added as an alternative to the NaCl interface. + - Memory allocation functions can now be used on operating systems with +no memory protection. + - crypto_sign_open() and crypto_sign_edwards25519sha512batch_open() +now accept a NULL pointer instead of a pointer to the message size, if +storing this information is not required. + - The close-on-exec flag is now set on the descriptor returned when +opening /dev/urandom. + - A libsodium-uninstalled.pc file to use pkg-config even when +libsodium is not installed, has been added. + - The iOS target now includes armv7s and arm64 optimized code, as well +as i386 and x86_64 code for the iOS simulator. + - sodium_free() can now be called on regions with PROT_NONE protection. + - The Javascript tests can run on Ubuntu, where the node binary was +renamed nodejs. io.js can also be used instead of node. + +* Version 1.0.1 + - DLL_EXPORT was renamed SODIUM_DLL_EXPORT in order to avoid +collisions with similar macros defined by other libraries. + - sodium_bin2hex() is now constant-time. + - crypto_secretbox_detached() now supports overlapping input and output +regions. + - NaCl's donna_c64 implementation of curve25519 was reading an extra byte +past the end of the buffer containing the base point. This has been +fixed. + +* Version 1.0.0 + - The API and ABI are now stable. New features will be added, but +backward-compatibility is guaranteed through all the 1.x.y releases. + - crypto_sign() properly works with overlapping regions again. Thanks +to @pysiak for reporting this regression introduced in version 0.6.1. + - The test suite has been extended. + +* Version 0.7.1 (1.0 RC2) + - This is the second release candidate of Sodium 1.0. Minor +compilation, readability and portability changes have been made and the +test suite was improved, but the API is the same as the previous release +candidate. + +* Version 0.7.0 (1.0 RC1) + - Allocating memory to store sensitive data can now be done using +sodium_malloc() and sodium_allocarray(). These functions add guard +pages around the protected data to make it less likely to be +accessible in a heartbleed-like scenario. In addition, the protection +for memory regions allocated that way can be changed using +sodium_mprotect_noaccess(), sodium_mprotect_readonly() and +sodium_mprotect_readwrite(). + - ed25519 keys can be converted to curve25519 keys with +crypto_sign_ed25519_pk_to_curve25519() and +crypto_sign_ed25519_sk_to_curve25519(). This allows using the same +keys for signature and encryption. + - The seed and the public key can be extracted from an ed25519 key +using crypto_sign_ed25519_sk_to_seed() and crypto_sign_ed25519_sk_to_pk(). + - aes256 was removed. A timing-attack resistant implementation might +be added later, but not before version 1.0 is tagged. + - The crypto_pwhash_scryptxsalsa208sha256_* compatibility layer was +removed. Use crypto_pwhash_scryptsalsa208sha256_*. + - The compatibility layer for implementation-specific functions was +removed. + - Compilation issues with Mingw64 on MSYS (not MSYS2) were fixed. + - crypto_pwhash_scryptsalsa208sha256_STRPREFIX was added: it contains +the prefix produced by crypto_pwhash_scryptsalsa208sha256_str() + +* Version 0.6.1 + - Important bug fix: when crypto_sign_open() was given a signed +message too short to even contain a signature, it was putting an +unlimited amount of zeros into the target buffer instead of +immediately returning -1. The bug was introduced in version 0.5.0. + - New API: crypto_sign_detached() and crypto_sign_verify_detached() +to produce and verify ed25519 signatures without having to duplicate +the message. + - New ./configure switch: --enable-minimal, to create a smaller +library, with only the functions required for the high-level API. +Mainly useful for the JavaScript target and embedded systems. + - All the symbols are now exported by the Emscripten build script. + - The pkg-config .pc file is now always installed even if the +pkg-config tool is not available during the installation. + +* Version 0.6.0 + - The ChaCha20 stream cipher has been added, as crypto_stream_chacha20_* + - The ChaCha20Poly1305 AEAD construction has been implemented, as +crypto_aead_chacha20poly1305_* + - The _easy API does not require any heap allocations any more and +does not have any overhead over the NaCl API. With the password +hashing function being an obvious exception, the library doesn't +allocate and will not allocate heap memory ever. + - crypto_box and crypto_secretbox have a new _detached API to store +the authentication tag and the encrypted message separately. + - crypto_pwhash_scryptxsalsa208sha256*() functions have been renamed +crypto_pwhash_scryptsalsa208sha256*(). + - The low-level crypto_pwhash_scryptsalsa208sha256_ll() function +allows setting individual parameters of the scrypt function. + - New macros and functions for recommended crypto_pwhash_* parameters +have been added. + - Similarly to crypto_sign_seed_keypair(), crypto_box_seed_keypair() +has been introduced to deterministically generate a key pair from a seed. + - crypto_onetimeauth() now provides a streaming interface. + - crypto_stream_chacha20_xor_ic() and crypto_stream_salsa20_xor_ic() +have been added to use a non-zero initial block counter. + - On Windows, CryptGenRandom() was replaced by RtlGenRandom(), which +doesn't require the Crypt API. + - The high bit in curve25519 is masked instead of processing the key as +a 256-bit value. + - The curve25519 ref implementation was replaced by the latest ref10 +implementation from Supercop. + - sodium_mlock() now prevents memory from being included in coredumps +on Linux 3.4+ + +* Version 0.5.0 + - sodium_mlock()/sodium_munlock() have been introduced to lock pages +in memory before storing sensitive data, and to zero them before +unlocking them. + - High-level wrappers for crypto_box and crypto_secretbox +(crypto_box_easy and crypto_secretbox_easy) can be used to avoid +dealing with the specific memory layout regular functions depend on. + - crypto_pwhash_scryptsalsa208sha256* functions have been added +to derive a key from a password, and for password storage. + - Salsa20 and ed25519 implementations now support overlapping +inputs/keys/outputs (changes imported from supercop-20140505). + - New build scripts for Visual Studio, Emscripten, different Android +architectures and msys2 are available. + - The poly1305-53 implementation has been replaced with Floodyberry's +poly1305-donna32 and poly1305-donna64 implementations. + - sodium_hex2bin() has been added to complement sodium_bin2hex(). + - On OpenBSD and Bitrig, arc4random() is used instead of reading +/dev/urandom. + - crypto_auth_hmac_sha512() has been implemented. + - sha256 and sha512 now have a streaming interface. + - hmacsha256, hmacsha512 and hmacsha512256 now support keys of +arbitrary length, and have a streaming interface. + - crypto_verify_64() has been implemented. + - first-class Visual Studio build system, thanks to @evoskuil + - CPU features are now detected at runtime. + +* Version 0.4.5 + - Restore compatibility with OSX <= 10.6 + +* Version 0.4.4 + - Visual Studio is officially supported (VC 2010 & VC 2013) + - mingw64 is now supported + - big-endian architectures are now supported as well + - The donna_c64 implementation of curve25519_donna_c64 now handles +non-canonical points like the ref implementation + - Missing scalarmult_curve25519 and stream_salsa20 constants are now exported + - A crypto_onetimeauth_poly1305_ref() wrapper has been added + +* Version 0.4.3 + - crypto_sign_seedbytes() and crypto_sign_SEEDBYTES were added. + - crypto_onetimeauth_poly1305_implementation_name() was added. + - poly1305-ref has been replaced by a faster implementation, +Floodyberry's poly1305-donna-unrolled. + - Stackmarkings have been added to assembly code, for Hardened Gentoo. + - pkg-config can now be used in order to retrieve compilations flags for +using libsodium. + - crypto_stream_aes256estream_*() can now deal with unaligned input +on platforms that require word alignment. + - portability improvements. + +* Version 0.4.2 + - All NaCl constants are now also exposed as functions. + - The Android and iOS cross-compilation script have been improved. + - libsodium can now be cross-compiled to Windows from Linux. + - libsodium can now be compiled with emscripten. + - New convenience function (prototyped in utils.h): sodium_bin2hex(). + +* Version 0.4.1 + - sodium_version_*() functions were not exported in version 0.4. They +are now visible as intended. + - sodium_init() now calls randombytes_stir(). + - optimized assembly version of salsa20 is now used on amd64. + - further cleanups and enhanced compatibility with non-C99 compilers. + +* Version 0.4 + - Most constants and operations are now available as actual functions +instead of macros, making it easier to use from other languages. + - New operation: crypto_generichash, featuring a variable key size, a +variable output size, and a streaming API. Currently implemented using +Blake2b. + - The package can be compiled in a separate directory. + - aes128ctr functions are exported. + - Optimized versions of curve25519 (curve25519_donna_c64), poly1305 +(poly1305_53) and ed25519 (ed25519_ref10) are available. Optionally calling +sodium_init() once before using the library makes it pick the fastest +implementation. + - New convenience function: sodium_memzero() in order to securely +wipe a memory area. + - A whole bunch of cleanups and portability enhancements. + - On Windows, a .REF file is generated along with the shared library, +for use with Visual Studio. The installation path for these has become +$prefix/bin as expected by MingW. + +* Version 0.3 + - The crypto_shorthash operation has been added, implemented using +SipHash-2-4. + +* Version 0.2 + - crypto_sign_seed_keypair() has been added + +* Version 0.1 + - Initial release. + diff --git a/external/src/libsodium/LICENSE b/external/src/libsodium/LICENSE new file mode 100644 index 0000000..5336e42 --- /dev/null +++ b/external/src/libsodium/LICENSE @@ -0,0 +1,18 @@ +/* + * ISC License + * + * Copyright (c) 2013-2021 + * Frank Denis + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/external/src/libsodium/Makefile.am b/external/src/libsodium/Makefile.am new file mode 100644 index 0000000..1f43ff3 --- /dev/null +++ b/external/src/libsodium/Makefile.am @@ -0,0 +1,24 @@ +ACLOCAL_AMFLAGS = -I m4 + +EXTRA_DIST = \ + autogen.sh \ + libsodium.sln \ + libsodium.vcxproj \ + libsodium.vcxproj.filters \ + LICENSE \ + README.markdown \ + THANKS + +SUBDIRS = \ + builds \ + contrib \ + dist-build \ + msvc-scripts \ + src \ + test + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = @PACKAGE_NAME@.pc + +DISTCLEANFILES = $(pkgconfig_DATA) + diff --git a/external/src/libsodium/README.markdown b/external/src/libsodium/README.markdown new file mode 100644 index 0000000..940c5c0 --- /dev/null +++ b/external/src/libsodium/README.markdown @@ -0,0 +1,48 @@ +[![GitHub CI](https://github.com/jedisct1/libsodium/workflows/CI/badge.svg)](https://github.com/jedisct1/libsodium/actions) +[![Windows build status](https://ci.appveyor.com/api/projects/status/fu8s2elx25il98hj?svg=true)](https://ci.appveyor.com/project/jedisct1/libsodium) +[![Coverity Scan Build Status](https://scan.coverity.com/projects/2397/badge.svg)](https://scan.coverity.com/projects/2397) +[![Azure build status](https://jedisct1.visualstudio.com/Libsodium/_apis/build/status/jedisct1.libsodium?branchName=stable)](https://jedisct1.visualstudio.com/Libsodium/_build/latest?definitionId=3&branchName=stable) +[![CodeQL scan](https://github.com/jedisct1/libsodium/workflows/CodeQL%20scan/badge.svg)](https://github.com/jedisct1/libsodium/actions) + +![libsodium](https://raw.github.com/jedisct1/libsodium/master/logo.png) +============ + +Sodium is a new, easy-to-use software library for encryption, +decryption, signatures, password hashing and more. + +It is a portable, cross-compilable, installable, packageable +fork of [NaCl](http://nacl.cr.yp.to/), with a compatible API, and an +extended API to improve usability even further. + +Its goal is to provide all of the core operations needed to build +higher-level cryptographic tools. + +Sodium supports a variety of compilers and operating systems, +including Windows (with MingW or Visual Studio, x86 and x64), iOS, Android, +as well as Javascript and Webassembly. + +## Documentation + +The documentation is available on Gitbook and built from the [libsodium-doc](https://github.com/jedisct1/libsodium-doc) repository: + +* [libsodium documentation](https://download.libsodium.org/doc/) - +online, requires Javascript. +* [offline documentation](https://www.gitbook.com/book/jedisct1/libsodium/details) +in PDF format. + +## Integrity Checking + +The integrity checking instructions (including the signing key for libsodium) +are available in the [installation](https://download.libsodium.org/doc/installation#integrity-checking) +section of the documentation. + +## Community + +A mailing-list is available to discuss libsodium. + +In order to join, just send a random mail to `sodium-subscribe` {at} +`pureftpd` {dot} `org`. + +## License + +[ISC license](https://en.wikipedia.org/wiki/ISC_license). diff --git a/external/src/libsodium/THANKS b/external/src/libsodium/THANKS new file mode 100644 index 0000000..a4b6e70 --- /dev/null +++ b/external/src/libsodium/THANKS @@ -0,0 +1,92 @@ +Special thanks to people, companies and organizations having written +libsodium bindings for their favorite programming languages: + +@alethia7 +@artemisc +@carblue +@dnaq +@ektrah +@graxrabble +@harleqin +@joshjdevl +@jrmarino +@jshahbazi +@lvh +@neheb + +Adam Caudill (@adamcaudill) +Alexander Ilin (@AlexIljin) +Alexander Morris (@alexpmorris) +Amit Murthy (@amitmurthy) +Andrew Bennett (@potatosalad) +Andrew Lambert (@charonn0) +Bruce Mitchener (@waywardmonkeys) +Bruno Oliveira (@abstractj) +Caolan McMahon (@caolan) +Chris Rebert (@cvrebert) +Christian Hermann (@bitbeans) +Christian Wiese (@morfoh) +Christian Wiese (@morfoh) +Colm MacCárthaigh (@colmmacc) +David Parrish (@dmp1ce) +Donald Stufft (@dstufft) +Douglas Campos (@qmx) +Drew Crawford (@drewcrawford) +Emil Bay (@emilbayes) +Eric Dong (@quantum1423) +Eric Voskuil (@evoskuil) +Farid Hajji (@fhajji) +Frank Siebenlist (@franks42) +Gabriel Handford (@gabriel) +Geo Carncross (@geocar) +Henrik Gassmann (BurningEnlightenment) +Jachym Holecek (@freza) +Jack Wink (@jackwink) +James Ruan (@jamesruan) +Jan de Muijnck-Hughes (@jfdm) +Jason McCampbell (@jasonmccampbell) +Jeroen Habraken (@VeXocide) +Jeroen Ooms (@jeroen) +Jesper Louis Andersen (@jlouis) +Joe Eli McIlvain (@jemc) +Jonathan Stowe (@jonathanstowe) +Joseph Abrahamson (@tel) +Julien Kauffmann (@ereOn) +Kenneth Ballenegger (@kballenegger) +Loic Maury (@loicmaury) +Michael Gorlick (@mgorlick) +Michael Gregorowicz (@mgregoro) +MichaÅ‚ ZieliÅ„ski (@zielmicha) +Omar Ayub (@electricFeel) +Pedro Paixao (@paixaop) +Project ArteMisc (@artemisc) +Rich FitzJohn (@richfitz) +Ruben De Visscher (@rubendv) +Rudolf Von Krugstein (@rudolfvonkrugstein) +Samuel Neves (@sneves) +Scott Arciszewski (@paragonie-scott) +Stanislav Ovsiannikov (@naphaso) +Stefan Marsiske (@stef) +Stephan Touset (@stouset) +Stephen Chavez (@redragonx) +Steve Gibson (@sggrc) +Tony Arcieri (@bascule) +Tony Garnock-Jones (@tonyg) +Y. T. Chung (@zonyitoo) + +Bytecurry Software +Cryptotronix +Facebook +FSF France +MaidSafe +Paragonie Initiative Enterprises +Python Cryptographic Authority + +(this list may not be complete, if you don't see your name, please +submit a pull request!) + +Also thanks to: + +- Coverity, Inc. to provide static analysis. +- FSF France for providing access to their compilation servers. +- Private Internet Access for having sponsored a complete security audit. diff --git a/external/src/libsodium/appveyor.yml b/external/src/libsodium/appveyor.yml new file mode 100644 index 0000000..5fdcdc8 --- /dev/null +++ b/external/src/libsodium/appveyor.yml @@ -0,0 +1,24 @@ +version: 1.0.18.{build} + +os: Visual Studio 2017 + +environment: + matrix: + - platform: Win32 + configuration: Debug + - platform: Win32 + configuration: Release + - platform: x64 + configuration: Debug + - platform: x64 + configuration: Release + +matrix: + fast_finish: false + +init: msbuild /version + +build: + parallel: true + project: libsodium.vcxproj + verbosity: minimal diff --git a/external/src/libsodium/autogen.sh b/external/src/libsodium/autogen.sh new file mode 100644 index 0000000..cb67ea5 --- /dev/null +++ b/external/src/libsodium/autogen.sh @@ -0,0 +1,117 @@ +#! /bin/sh + +args=$(getopt bfos "$@") +if [ $? -ne 0 ]; then + echo "Usage: autogen.sh [-b] [-f] [-o] [-s] [--]" + echo + echo "> -b: do not update the system detection scripts" + echo "> -f: force the recreation of all autoconf scripts" + echo "> -o: overwrite/downgrade system detection scripts" + echo "> -s: setup an environment for developers" + exit 2 +fi + +force=false +update_config=true +overwrite_config=false +dev_setup=false + +eval set -- "$args" + +while [ $# -ne 0 ]; do + case $1 in + -b) + update_config=false + ;; + -f) + force=true + ;; + -o) + overwrite_config=true + ;; + -s) + dev_setup=true + ;; + --) + shift + break + ;; + esac + shift +done + +if [ -s configure ]; then + if [ "$force" != true ]; then + echo "autoconf scripts already exist." >&2 + exit 0 + fi +elif [ "$dev_setup" != true ]; then + echo "A development environment was not created." + exit 0 +fi + +if glibtoolize --version >/dev/null 2>&1; then + LIBTOOLIZE='glibtoolize' +else + LIBTOOLIZE='libtoolize' +fi + +command -v command >/dev/null 2>&1 || { + echo "command is required, but wasn't found on this system" + exit 1 +} + +command -v $LIBTOOLIZE >/dev/null 2>&1 || { + echo "libtool is required, but wasn't found on this system" + exit 1 +} + +command -v autoconf >/dev/null 2>&1 || { + echo "autoconf is required, but wasn't found on this system" + exit 1 +} + +command -v automake >/dev/null 2>&1 || { + echo "automake is required, but wasn't found on this system" + exit 1 +} + +if [ "$overwrite_config" = false ]; then + if [ -f build-aux/config.guess ]; then + mv build-aux/config.guess build-aux/config.guess.stable + fi + if [ -f build-aux/config.sub ]; then + mv build-aux/config.sub build-aux/config.sub.stable + fi +fi +$LIBTOOLIZE --copy --install && + aclocal && + automake --add-missing --copy --force-missing --include-deps && + autoconf && echo Done. +if [ "$overwrite_config" = false ]; then + if [ -f build-aux/config.guess.stable ]; then + mv build-aux/config.guess.stable build-aux/config.guess + fi + if [ -f build-aux/config.sub.stable ]; then + mv build-aux/config.sub.stable build-aux/config.sub + fi +fi + +[ "$update_config" = true ] && [ -z "$DO_NOT_UPDATE_CONFIG_SCRIPTS" ] && + command -v curl >/dev/null 2>&1 && { + echo "Downloading config.guess and config.sub..." + + curl -sSL --fail -o config.guess \ + 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD' && + chmod +x config.guess && + chmod +x build-aux/config.guess + + curl -sSL --fail -o config.sub \ + 'https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD' && + chmod +x build-aux/config.sub && + mv -f config.sub build-aux/config.sub + + echo "Done." +} + +rm -f config.guess config.sub diff --git a/external/src/libsodium/azure-pipelines.yml b/external/src/libsodium/azure-pipelines.yml new file mode 100644 index 0000000..3ce8a1c --- /dev/null +++ b/external/src/libsodium/azure-pipelines.yml @@ -0,0 +1,141 @@ +trigger: + - stable + - next + +pr: none + +jobs: + - job: "wasi" + pool: + vmImage: "ubuntu-20.04" + steps: + - script: | + sudo apt-get install build-essential curl cmake lld + displayName: Install system packages + - script: | + curl https://get.wasmer.io -sSfL | sh + displayName: Install wasmer + - script: | + curl -sL -o - https://ziglang.org/download/0.8.0/zig-linux-x86_64-0.8.0.tar.xz | tar xJ -f - -C /opt/ + sudo mv /opt/zig-* /opt/zig + env PATH=/opt/zig/bin:/opt/zig:$PATH + displayName: Install the Zig SDK + - script: | + env WASMER_DIR=${HOME}/.wasmer PATH=${HOME}/.wasmer/bin:/opt/wasi-sdk/bin:${HOME}/.cargo/bin:$PATH dist-build/wasm32-wasi.sh + displayName: Compile libsodium + - task: PublishBuildArtifacts@1 + condition: not(canceled()) + inputs: + pathToPublish: libsodium-wasm32-wasi + artifactName: libsodium-wasm32-wasi + + - job: "windows" + pool: + vmImage: "windows-2019" + steps: + - powershell: | + cd builds\msvc\build + & .\buildbase.bat ..\vs2019\libsodium.sln 16 + displayName: Compile it all + - powershell: | + mkdir bin\include\sodium + Copy-Item "src\libsodium\include\sodium\*.h" -Destination "bin\include\sodium" -Recurse + Copy-Item "src\libsodium\include\*.h" -Destination "bin\include\" + displayName: Copy header files + - task: PublishBuildArtifacts@1 + condition: not(canceled()) + inputs: + pathToPublish: bin + artifactName: libsodium + + - job: "windows_old" + pool: + vmImage: "vs2017-win2016" + steps: + - powershell: | + cd builds\msvc\build + & .\buildbase.bat ..\vs2017\libsodium.sln 15 + displayName: Compile it all + - task: PublishBuildArtifacts@1 + condition: not(canceled()) + inputs: + pathToPublish: bin + artifactName: libsodium + + - job: mingw64 + pool: + vmImage: "windows-2019" + steps: + - powershell: | + (New-Object Net.WebClient).DownloadFile("https://github.com/msys2/msys2-installer/releases/download/2021-07-25/msys2-base-x86_64-20210725.sfx.exe", "sfx.exe") + .\sfx.exe -y -o\ + del sfx.exe + displayName: Install MSYS2 + - script: | + set PATH=%CD:~0,2%\msys64\usr\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem + %CD:~0,2%\msys64\usr\bin\bash -lc + %CD:~0,2%\msys64\usr\bin\bash -lc "pacman --noconfirm -Sydd filesystem" + %CD:~0,2%\msys64\usr\bin\bash -lc 'pacman --noconfirm -Syuu' + %CD:~0,2%\msys64\usr\bin\bash -lc 'pacman --noconfirm -Syuu' + displayName: Update MSYS2 + - script: | + set PATH=%CD:~0,2%\msys64\usr\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem + %CD:~0,2%\msys64\usr\bin\pacman --noconfirm --needed -S base-devel mingw-w64-x86_64-toolchain + %CD:~0,2%\msys64\usr\bin\pacman --noconfirm -Scc + %CD:~0,2%\msys64\usr\bin\sed -i "s|#CacheDir.*|CacheDir=/c/Users/%USERNAME%/AppData/Local/Temp|g" /etc/pacman.conf + displayName: Install Toolchain + - script: | + set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;%CD:~0,2%\msys64\usr\bin;%CD:~0,2%\msys64\bin + set MSYS2_ROOT=%CD:~0,2%\msys64 + set MSYSTEM=MINGW64 + set CHERE_INVOKING=yes + %MSYS2_ROOT%\cmd\msystem MINGW64 + %CD:~0,2%\msys64\usr\bin\bash -lc dist-build/msys2-win64.sh + env: + CHERE_INVOKING: yes + MSYS2_ARCH: x86_64 + displayName: Compile libsodium + - task: PublishBuildArtifacts@1 + condition: not(canceled()) + inputs: + pathToPublish: libsodium-win64 + artifactName: libsodium-win64 + + - job: mingw32 + pool: + vmImage: "windows-2019" + steps: + - powershell: | + (New-Object Net.WebClient).DownloadFile("https://github.com/msys2/msys2-installer/releases/download/2021-07-25/msys2-base-x86_64-20210725.sfx.exe", "sfx.exe") + .\sfx.exe -y -o\ + del sfx.exe + displayName: Install MSYS2 + - script: | + set PATH=%CD:~0,2%\msys64\usr\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem + %CD:~0,2%\msys64\usr\bin\bash -lc + %CD:~0,2%\msys64\usr\bin\bash -lc "pacman --noconfirm -Sydd filesystem" + %CD:~0,2%\msys64\usr\bin\bash -lc 'pacman --noconfirm -Syuu' + %CD:~0,2%\msys64\usr\bin\bash -lc 'pacman --noconfirm -Syuu' + displayName: Update MSYS2 + - script: | + set PATH=%CD:~0,2%\msys64\usr\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem + %CD:~0,2%\msys64\usr\bin\pacman --noconfirm --needed -S base-devel mingw-w64-i686-toolchain + %CD:~0,2%\msys64\usr\bin\pacman --noconfirm -Scc + %CD:~0,2%\msys64\usr\bin\sed -i "s|#CacheDir.*|CacheDir=/c/Users/%USERNAME%/AppData/Local/Temp|g" /etc/pacman.conf + displayName: Install Toolchain + - script: | + set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;%CD:~0,2%\msys64\usr\bin;%CD:~0,2%\msys64\bin + set MSYS2_ROOT=%CD:~0,2%\msys64 + set MSYSTEM=MINGW32 + set CHERE_INVOKING=yes + %MSYS2_ROOT%\cmd\msystem MINGW32 + %CD:~0,2%\msys64\usr\bin\bash -lc dist-build/msys2-win32.sh + env: + CHERE_INVOKING: yes + MSYS2_ARCH: x86_64 + displayName: Compile libsodium + - task: PublishBuildArtifacts@1 + condition: not(canceled()) + inputs: + pathToPublish: libsodium-win32 + artifactName: libsodium-win32 diff --git a/external/src/libsodium/builds/.gitignore b/external/src/libsodium/builds/.gitignore new file mode 100644 index 0000000..878f1a3 --- /dev/null +++ b/external/src/libsodium/builds/.gitignore @@ -0,0 +1,7 @@ +*.opensdf +*.suo +*.sdf +*.vcxproj.user +*.aps +*.log +!build \ No newline at end of file diff --git a/external/src/libsodium/builds/Makefile.am b/external/src/libsodium/builds/Makefile.am new file mode 100644 index 0000000..23dfe9d --- /dev/null +++ b/external/src/libsodium/builds/Makefile.am @@ -0,0 +1,72 @@ +EXTRA_DIST = \ + msvc/build/buildall.bat \ + msvc/build/buildbase.bat \ + msvc/properties/Common.props \ + msvc/properties/Debug.props \ + msvc/properties/DebugDEXE.props \ + msvc/properties/DebugDLL.props \ + msvc/properties/DebugLEXE.props \ + msvc/properties/DebugLIB.props \ + msvc/properties/DebugLTCG.props \ + msvc/properties/DebugSEXE.props \ + msvc/properties/DLL.props \ + msvc/properties/EXE.props \ + msvc/properties/LIB.props \ + msvc/properties/Link.props \ + msvc/properties/LTCG.props \ + msvc/properties/Messages.props \ + msvc/properties/Output.props \ + msvc/properties/Release.props \ + msvc/properties/ReleaseDEXE.props \ + msvc/properties/ReleaseDLL.props \ + msvc/properties/ReleaseLEXE.props \ + msvc/properties/ReleaseLIB.props \ + msvc/properties/ReleaseLTCG.props \ + msvc/properties/ReleaseSEXE.props \ + msvc/properties/Win32.props \ + msvc/properties/x64.props \ + msvc/resource.h \ + msvc/resource.rc \ + msvc/version.h \ + msvc/vs2010/libsodium/libsodium.props \ + msvc/vs2010/libsodium/libsodium.vcxproj \ + msvc/vs2010/libsodium/libsodium.vcxproj.filters \ + msvc/vs2010/libsodium/libsodium.xml \ + msvc/vs2010/libsodium.import.props \ + msvc/vs2010/libsodium.import.xml \ + msvc/vs2010/libsodium.sln \ + msvc/vs2012/libsodium/libsodium.props \ + msvc/vs2012/libsodium/libsodium.vcxproj \ + msvc/vs2012/libsodium/libsodium.vcxproj.filters \ + msvc/vs2012/libsodium/libsodium.xml \ + msvc/vs2012/libsodium.import.props \ + msvc/vs2012/libsodium.import.xml \ + msvc/vs2012/libsodium.sln \ + msvc/vs2013/libsodium/libsodium.props \ + msvc/vs2013/libsodium/libsodium.vcxproj \ + msvc/vs2013/libsodium/libsodium.vcxproj.filters \ + msvc/vs2013/libsodium/libsodium.xml \ + msvc/vs2013/libsodium.import.props \ + msvc/vs2013/libsodium.import.xml \ + msvc/vs2013/libsodium.sln \ + msvc/vs2015/libsodium/libsodium.props \ + msvc/vs2015/libsodium/libsodium.vcxproj \ + msvc/vs2015/libsodium/libsodium.vcxproj.filters \ + msvc/vs2015/libsodium/libsodium.xml \ + msvc/vs2015/libsodium.import.props \ + msvc/vs2015/libsodium.import.xml \ + msvc/vs2015/libsodium.sln \ + msvc/vs2017/libsodium/libsodium.props \ + msvc/vs2017/libsodium/libsodium.vcxproj \ + msvc/vs2017/libsodium/libsodium.vcxproj.filters \ + msvc/vs2017/libsodium/libsodium.xml \ + msvc/vs2017/libsodium.import.props \ + msvc/vs2017/libsodium.import.xml \ + msvc/vs2017/libsodium.sln \ + msvc/vs2019/libsodium/libsodium.props \ + msvc/vs2019/libsodium/libsodium.vcxproj \ + msvc/vs2019/libsodium/libsodium.vcxproj.filters \ + msvc/vs2019/libsodium/libsodium.xml \ + msvc/vs2019/libsodium.import.props \ + msvc/vs2019/libsodium.import.xml \ + msvc/vs2019/libsodium.sln diff --git a/external/src/libsodium/builds/msvc/build/buildall.bat b/external/src/libsodium/builds/msvc/build/buildall.bat new file mode 100644 index 0000000..4f0b421 --- /dev/null +++ b/external/src/libsodium/builds/msvc/build/buildall.bat @@ -0,0 +1,16 @@ +@ECHO OFF + +CALL buildbase.bat ..\vs2019\libsodium.sln 16 +ECHO. +CALL buildbase.bat ..\vs2017\libsodium.sln 15 +ECHO. +CALL buildbase.bat ..\vs2015\libsodium.sln 14 +ECHO. +CALL buildbase.bat ..\vs2013\libsodium.sln 12 +ECHO. +CALL buildbase.bat ..\vs2012\libsodium.sln 11 +ECHO. +CALL buildbase.bat ..\vs2010\libsodium.sln 10 +ECHO. + +PAUSE diff --git a/external/src/libsodium/builds/msvc/build/buildbase.bat b/external/src/libsodium/builds/msvc/build/buildbase.bat new file mode 100644 index 0000000..b68cd2c --- /dev/null +++ b/external/src/libsodium/builds/msvc/build/buildbase.bat @@ -0,0 +1,96 @@ +@ECHO OFF +REM Usage: [buildbase.bat ..\vs2019\mysolution.sln 16] + +SETLOCAL enabledelayedexpansion + +SET solution=%1 +SET version=%2 +SET log=build_%version%.log +SET tools=Microsoft Visual Studio %version%.0\VC\vcvarsall.bat + +IF %version% == 16 ( + SET tools=Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat + SET environment="%programfiles%\!tools!" + IF NOT EXIST !environment! ( + SET environment="%programfiles(x86)%\!tools!" + IF NOT EXIST !environment! ( + SET tools=Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat + ) + ) +) + +IF %version% == 15 ( + SET tools=Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvarsall.bat + SET environment="%programfiles%\!tools!" + IF NOT EXIST !environment! ( + SET environment="%programfiles(x86)%\!tools!" + IF NOT EXIST !environment! ( + SET tools=Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat + ) + ) +) +SET environment="%programfiles%\!tools!" +IF NOT EXIST !environment! SET environment="%programfiles(x86)%\!tools!" + +ECHO Environment: !environment! + +IF NOT EXIST !environment! GOTO no_tools + +ECHO Building: %solution% + +CALL !environment! x86 > nul +ECHO Platform=x86 + +ECHO Configuration=DynDebug +msbuild /m /v:n /p:Configuration=DynDebug /p:Platform=Win32 %solution% >> %log% +IF errorlevel 1 GOTO error +ECHO Configuration=DynRelease +msbuild /m /v:n /p:Configuration=DynRelease /p:Platform=Win32 %solution% >> %log% +IF errorlevel 1 GOTO error +ECHO Configuration=LtcgDebug +msbuild /m /v:n /p:Configuration=LtcgDebug /p:Platform=Win32 %solution% >> %log% +IF errorlevel 1 GOTO error +ECHO Configuration=LtcgRelease +msbuild /m /v:n /p:Configuration=LtcgRelease /p:Platform=Win32 %solution% >> %log% +IF errorlevel 1 GOTO error +ECHO Configuration=StaticDebug +msbuild /m /v:n /p:Configuration=StaticDebug /p:Platform=Win32 %solution% >> %log% +IF errorlevel 1 GOTO error +ECHO Configuration=StaticRelease +msbuild /m /v:n /p:Configuration=StaticRelease /p:Platform=Win32 %solution% >> %log% +IF errorlevel 1 GOTO error + +CALL !environment! x86_amd64 > nul +ECHO Platform=x64 + +ECHO Configuration=DynDebug +msbuild /m /v:n /p:Configuration=DynDebug /p:Platform=x64 %solution% >> %log% +IF errorlevel 1 GOTO error +ECHO Configuration=DynRelease +msbuild /m /v:n /p:Configuration=DynRelease /p:Platform=x64 %solution% >> %log% +IF errorlevel 1 GOTO error +ECHO Configuration=LtcgDebug +msbuild /m /v:n /p:Configuration=LtcgDebug /p:Platform=x64 %solution% >> %log% +IF errorlevel 1 GOTO error +ECHO Configuration=LtcgRelease +msbuild /m /v:n /p:Configuration=LtcgRelease /p:Platform=x64 %solution% >> %log% +IF errorlevel 1 GOTO error +ECHO Configuration=StaticDebug +msbuild /m /v:n /p:Configuration=StaticDebug /p:Platform=x64 %solution% >> %log% +IF errorlevel 1 GOTO error +ECHO Configuration=StaticRelease +msbuild /m /v:n /p:Configuration=StaticRelease /p:Platform=x64 %solution% >> %log% +IF errorlevel 1 GOTO error + +ECHO Complete: %solution% +GOTO end + +:error +ECHO *** ERROR, build terminated early, see: %log% +GOTO end + +:no_tools +ECHO *** ERROR, build tools not found: !tools! + +:end + diff --git a/external/src/libsodium/builds/msvc/properties/Common.props b/external/src/libsodium/builds/msvc/properties/Common.props new file mode 100644 index 0000000..72588d6 --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/Common.props @@ -0,0 +1,21 @@ + + + + + <_PropertySheetDisplayName>Common Settings + Unicode + + + + + + + + + true + UNICODE;_UNICODE;%(PreprocessorDefinitions) + Level3 + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/DLL.props b/external/src/libsodium/builds/msvc/properties/DLL.props new file mode 100644 index 0000000..b5aa1f0 --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/DLL.props @@ -0,0 +1,16 @@ + + + + + <_PropertySheetDisplayName>Dynamic Library + dynamic + .dll + + + + + _DLL;_WINDLL;%(PreprocessorDefinitions) + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/Debug.props b/external/src/libsodium/builds/msvc/properties/Debug.props new file mode 100644 index 0000000..6fa7419 --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/Debug.props @@ -0,0 +1,29 @@ + + + + + + + + + <_PropertySheetDisplayName>Debug Settings + Debug + + + + + EnableFastChecks + ProgramDatabase + true + Disabled + _DEBUG;%(PreprocessorDefinitions) + + + _DEBUG;%(PreprocessorDefinitions) + + + true + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/DebugDEXE.props b/external/src/libsodium/builds/msvc/properties/DebugDEXE.props new file mode 100644 index 0000000..fe8b577 --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/DebugDEXE.props @@ -0,0 +1,21 @@ + + + + + <_PropertySheetDisplayName>Console Debug Dynamic + dynamic + + + + + + + + + + MultiThreadedDebugDLL + true + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/DebugDLL.props b/external/src/libsodium/builds/msvc/properties/DebugDLL.props new file mode 100644 index 0000000..a451d0b --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/DebugDLL.props @@ -0,0 +1,20 @@ + + + + + <_PropertySheetDisplayName>Dynamic Debug Library + + + + + + + + + + MultiThreadedDebugDLL + true + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/DebugLEXE.props b/external/src/libsodium/builds/msvc/properties/DebugLEXE.props new file mode 100644 index 0000000..7fa92c0 --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/DebugLEXE.props @@ -0,0 +1,20 @@ + + + + + <_PropertySheetDisplayName>Console Debug Link Time Code Generation + + + + + + + + + + + MultiThreadedDebug + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/DebugLIB.props b/external/src/libsodium/builds/msvc/properties/DebugLIB.props new file mode 100644 index 0000000..c5f1012 --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/DebugLIB.props @@ -0,0 +1,21 @@ + + + + + <_PropertySheetDisplayName>Static Debug Library + + + + + + + + + + OldStyle + MultiThreadedDebug + true + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/DebugLTCG.props b/external/src/libsodium/builds/msvc/properties/DebugLTCG.props new file mode 100644 index 0000000..42b22ff --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/DebugLTCG.props @@ -0,0 +1,20 @@ + + + + + <_PropertySheetDisplayName>Static Debug Link Time Code Generation Library + + + + + + + + + + OldStyle + MultiThreadedDebug + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/DebugSEXE.props b/external/src/libsodium/builds/msvc/properties/DebugSEXE.props new file mode 100644 index 0000000..2615ffc --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/DebugSEXE.props @@ -0,0 +1,21 @@ + + + + + <_PropertySheetDisplayName>Console Debug Static + static + + + + + + + + + + MultiThreadedDebug + true + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/EXE.props b/external/src/libsodium/builds/msvc/properties/EXE.props new file mode 100644 index 0000000..3549064 --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/EXE.props @@ -0,0 +1,17 @@ + + + + + <_PropertySheetDisplayName>Console Application + true + + + + + _CONSOLE;%(PreprocessorDefinitions) + + + Console + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/LIB.props b/external/src/libsodium/builds/msvc/properties/LIB.props new file mode 100644 index 0000000..3835777 --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/LIB.props @@ -0,0 +1,16 @@ + + + + + <_PropertySheetDisplayName>Static Library + static + .lib + + + + + _LIB;%(PreprocessorDefinitions) + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/LTCG.props b/external/src/libsodium/builds/msvc/properties/LTCG.props new file mode 100644 index 0000000..0229293 --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/LTCG.props @@ -0,0 +1,13 @@ + + + + + <_PropertySheetDisplayName>Link Time Code Generation Library + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/Link.props b/external/src/libsodium/builds/msvc/properties/Link.props new file mode 100644 index 0000000..db15fbb --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/Link.props @@ -0,0 +1,21 @@ + + + + + <_PropertySheetDisplayName>Link Time Code Generation Settings + ltcg + + + + + true + + + UseLinkTimeCodeGeneration + + + true + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/Messages.props b/external/src/libsodium/builds/msvc/properties/Messages.props new file mode 100644 index 0000000..06a1ab0 --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/Messages.props @@ -0,0 +1,15 @@ + + + + + <_PropertySheetDisplayName>Build Messages + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/Output.props b/external/src/libsodium/builds/msvc/properties/Output.props new file mode 100644 index 0000000..492876c --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/Output.props @@ -0,0 +1,30 @@ + + + + + <_PropertySheetDisplayName>Output Settings + + $(ProjectDir)..\..\ + $(ProjectDir)..\..\..\..\ + $(ProjectDir)..\..\..\..\..\ + $(ProjectDir)..\..\..\..\bin\$(PlatformName)\$(DebugOrRelease)\$(PlatformToolset)\$(DefaultLinkage)\ + $(ProjectDir)..\..\..\..\obj\$(TargetName)\$(PlatformName)\$(DebugOrRelease)\$(PlatformToolset)\$(DefaultLinkage)\ + $(OutDir) + $(TargetName) + $(TargetDir)$(TargetName)$(TargetExt) + + + + + $(OutDir)$(TargetName).lib + + + $(OutDir)$(TargetName).log + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/Release.props b/external/src/libsodium/builds/msvc/properties/Release.props new file mode 100644 index 0000000..1c5415b --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/Release.props @@ -0,0 +1,41 @@ + + + + + + + + + <_PropertySheetDisplayName>Release Settings + Release + false + + + + + /Oy- %(AdditionalOptions) + + true + true + OnlyExplicitInline + false + MaxSpeed + NDEBUG;%(PreprocessorDefinitions) + + + NDEBUG;%(PreprocessorDefinitions) + + + true + + true + + + + + + StreamingSIMDExtensions2 + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/ReleaseDEXE.props b/external/src/libsodium/builds/msvc/properties/ReleaseDEXE.props new file mode 100644 index 0000000..73deeae --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/ReleaseDEXE.props @@ -0,0 +1,20 @@ + + + + + <_PropertySheetDisplayName>Console Release Dynamic + dynamic + + + + + + + + + + MultiThreadedDLL + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/ReleaseDLL.props b/external/src/libsodium/builds/msvc/properties/ReleaseDLL.props new file mode 100644 index 0000000..2071b33 --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/ReleaseDLL.props @@ -0,0 +1,19 @@ + + + + + <_PropertySheetDisplayName>Dynamic Release Library + + + + + + + + + + MultiThreadedDLL + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/ReleaseLEXE.props b/external/src/libsodium/builds/msvc/properties/ReleaseLEXE.props new file mode 100644 index 0000000..beb73ef --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/ReleaseLEXE.props @@ -0,0 +1,20 @@ + + + + + <_PropertySheetDisplayName>Console Release Link Time Code Generation + + + + + + + + + + + MultiThreaded + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/ReleaseLIB.props b/external/src/libsodium/builds/msvc/properties/ReleaseLIB.props new file mode 100644 index 0000000..2b250d5 --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/ReleaseLIB.props @@ -0,0 +1,19 @@ + + + + + <_PropertySheetDisplayName>Static Release Library + + + + + + + + + + MultiThreaded + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/ReleaseLTCG.props b/external/src/libsodium/builds/msvc/properties/ReleaseLTCG.props new file mode 100644 index 0000000..1814c6f --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/ReleaseLTCG.props @@ -0,0 +1,19 @@ + + + + + <_PropertySheetDisplayName>Static Release Link Time Code Generation Library + + + + + + + + + + MultiThreaded + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/ReleaseSEXE.props b/external/src/libsodium/builds/msvc/properties/ReleaseSEXE.props new file mode 100644 index 0000000..2f5600a --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/ReleaseSEXE.props @@ -0,0 +1,20 @@ + + + + + <_PropertySheetDisplayName>Console Release Static + static + + + + + + + + + + MultiThreaded + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/properties/Win32.props b/external/src/libsodium/builds/msvc/properties/Win32.props new file mode 100644 index 0000000..09eb5e4 --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/Win32.props @@ -0,0 +1,23 @@ + + + + + <_PropertySheetDisplayName>x86 Settings + + + + + WIN32;_WIN32;%(PreprocessorDefinitions) + + + Win32;%(PreprocessorDefinitions) + + + MachineX86 + + + /MACHINE:X86 %(AdditionalOptions) + + + + diff --git a/external/src/libsodium/builds/msvc/properties/x64.props b/external/src/libsodium/builds/msvc/properties/x64.props new file mode 100644 index 0000000..c139a2a --- /dev/null +++ b/external/src/libsodium/builds/msvc/properties/x64.props @@ -0,0 +1,26 @@ + + + + + <_PropertySheetDisplayName>x64 Settings + + + + + + WIN32;_WIN32;WIN64;_WIN64;%(PreprocessorDefinitions) + + + x64;%(PreprocessorDefinitions) + + + MachineX64 + + + /MACHINE:X64 %(AdditionalOptions) + + + + diff --git a/external/src/libsodium/builds/msvc/resource.h b/external/src/libsodium/builds/msvc/resource.h new file mode 100644 index 0000000..d42b43e --- /dev/null +++ b/external/src/libsodium/builds/msvc/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Resource.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/external/src/libsodium/builds/msvc/resource.rc b/external/src/libsodium/builds/msvc/resource.rc new file mode 100644 index 0000000..7f007ef --- /dev/null +++ b/external/src/libsodium/builds/msvc/resource.rc @@ -0,0 +1,63 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" +#include "windows.h" + +//specify the version numbers for the dll's +#define LIBSODIUM_VERSION_STRING "1.0.18.0" +#define LIBSODIUM_VERSION_BIN 1,0,18,0 + +//specify the product name for the dlls based on the platform we are compiling for +#if defined(x64) + #define LIBSODIUM_PRODUCT_NAME "libsodium (x64)" +#elif defined(Win32) + #define LIBSODIUM_PRODUCT_NAME "libsodium (x86)" +#else + #define LIBSODIUM_PRODUCT_NAME "libsodium" +#endif + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION LIBSODIUM_VERSION_BIN + PRODUCTVERSION LIBSODIUM_VERSION_BIN + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x7L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "The Sodium crypto library (libsodium) " + VALUE "FileVersion", LIBSODIUM_VERSION_STRING + VALUE "InternalName", "libsodium" + VALUE "LegalCopyright", "Copyright (c) 2013-2019 The libsodium authors." + VALUE "OriginalFilename", "libsodium.dll" + VALUE "ProductName", LIBSODIUM_PRODUCT_NAME + VALUE "ProductVersion", LIBSODIUM_VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// diff --git a/external/src/libsodium/builds/msvc/version.h b/external/src/libsodium/builds/msvc/version.h new file mode 100644 index 0000000..174d992 --- /dev/null +++ b/external/src/libsodium/builds/msvc/version.h @@ -0,0 +1,32 @@ + +#ifndef sodium_version_H +#define sodium_version_H + +#include "export.h" + +#define SODIUM_VERSION_STRING "1.0.18" + +#define SODIUM_LIBRARY_VERSION_MAJOR 10 +#define SODIUM_LIBRARY_VERSION_MINOR 3 + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +const char *sodium_version_string(void); + +SODIUM_EXPORT +int sodium_library_version_major(void); + +SODIUM_EXPORT +int sodium_library_version_minor(void); + +SODIUM_EXPORT +int sodium_library_minimal(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/builds/msvc/vs2010/libsodium.import.props b/external/src/libsodium/builds/msvc/vs2010/libsodium.import.props new file mode 100644 index 0000000..b3d7e4f --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2010/libsodium.import.props @@ -0,0 +1,52 @@ + + + + + <_PropertySheetDisplayName>Libsodium Import Settings + + + + + + + + + + + + + $(ProjectDir)..\..\..\..\..\libsodium\src\libsodium\include;$(ProjectDir)..\..\..\..\..\libsodium\src\libsodium\include\sodium\;%(AdditionalIncludeDirectories) + SODIUM_STATIC;%(PreprocessorDefinitions) + + + advapi32.lib;libsodium.lib;%(AdditionalDependencies) + $(ProjectDir)..\..\..\..\..\libsodium\bin\$(PlatformName)\Debug\$(PlatformToolset)\$(Linkage-libsodium)\;%(AdditionalLibraryDirectories) + $(ProjectDir)..\..\..\..\..\libsodium\bin\$(PlatformName)\Release\$(PlatformToolset)\$(Linkage-libsodium)\;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2010/libsodium.import.xml b/external/src/libsodium/builds/msvc/vs2010/libsodium.import.xml new file mode 100644 index 0000000..dbcf4e5 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2010/libsodium.import.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2010/libsodium.sln b/external/src/libsodium/builds/msvc/vs2010/libsodium.sln new file mode 100644 index 0000000..6a0a970 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2010/libsodium.sln @@ -0,0 +1,50 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsodium", "libsodium\libsodium.vcxproj", "{A185B162-6CB6-4502-B03F-B56F7699A8D9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + DynDebug|Win32 = DynDebug|Win32 + DynDebug|x64 = DynDebug|x64 + DynRelease|Win32 = DynRelease|Win32 + DynRelease|x64 = DynRelease|x64 + LtcgDebug|Win32 = LtcgDebug|Win32 + LtcgDebug|x64 = LtcgDebug|x64 + LtcgRelease|Win32 = LtcgRelease|Win32 + LtcgRelease|x64 = LtcgRelease|x64 + StaticDebug|Win32 = StaticDebug|Win32 + StaticDebug|x64 = StaticDebug|x64 + StaticRelease|Win32 = StaticRelease|Win32 + StaticRelease|x64 = StaticRelease|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|Win32.ActiveCfg = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|Win32.Build.0 = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|x64.ActiveCfg = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|x64.Build.0 = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|Win32.ActiveCfg = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|Win32.Build.0 = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|x64.ActiveCfg = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|x64.Build.0 = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|Win32.ActiveCfg = DebugLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|Win32.Build.0 = DebugLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|x64.ActiveCfg = DebugLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|x64.Build.0 = DebugLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|Win32.ActiveCfg = ReleaseLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|Win32.Build.0 = ReleaseLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|x64.ActiveCfg = ReleaseLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|x64.Build.0 = ReleaseLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|Win32.ActiveCfg = DebugLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|Win32.Build.0 = DebugLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|x64.ActiveCfg = DebugLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|x64.Build.0 = DebugLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|Win32.ActiveCfg = ReleaseLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|Win32.Build.0 = ReleaseLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|x64.ActiveCfg = ReleaseLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|x64.Build.0 = ReleaseLIB|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/external/src/libsodium/builds/msvc/vs2010/libsodium/libsodium.props b/external/src/libsodium/builds/msvc/vs2010/libsodium/libsodium.props new file mode 100644 index 0000000..5a23903 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2010/libsodium/libsodium.props @@ -0,0 +1,48 @@ + + + + + <_PropertySheetDisplayName>Libsodium Common Settings + AllRules.ruleset + false + + + + + + + + + + + + + copy "$(BuildRoot)version.h" "$(RepoRoot)src\libsodium\include\sodium\" + + + $(RepoRoot)src\libsodium\include;$(RepoRoot)src\libsodium\include\sodium\;%(AdditionalIncludeDirectories) + 4146;4244;%(DisableSpecificWarnings) + false + inline=__inline;NATIVE_LITTLE_ENDIAN;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + SODIUM_STATIC;%(PreprocessorDefinitions) + SODIUM_DLL_EXPORT;%(PreprocessorDefinitions) + HAVE_AMD64_ASM;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + advapi32.lib + + + diff --git a/external/src/libsodium/builds/msvc/vs2010/libsodium/libsodium.vcxproj b/external/src/libsodium/builds/msvc/vs2010/libsodium/libsodium.vcxproj new file mode 100644 index 0000000..f29d5ac --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2010/libsodium/libsodium.vcxproj @@ -0,0 +1,325 @@ + + + + {A185B162-6CB6-4502-B03F-B56F7699A8D9} + libsodium + v100 + + + + DebugDLL + Win32 + + + ReleaseDLL + Win32 + + + DebugDLL + x64 + + + ReleaseDLL + x64 + + + DebugLTCG + Win32 + + + ReleaseLTCG + Win32 + + + DebugLTCG + x64 + + + ReleaseLTCG + x64 + + + DebugLIB + Win32 + + + ReleaseLIB + Win32 + + + DebugLIB + x64 + + + ReleaseLIB + x64 + + + + StaticLibrary + DynamicLibrary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/src/libsodium/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters b/external/src/libsodium/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters new file mode 100644 index 0000000..f152794 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters @@ -0,0 +1,992 @@ + + + + + packaging + + + packaging + + + packaging + + + packaging + + + packaging + + + packaging + + + + + + + + crypto_generichash + + + crypto_generichash\blake2b + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_kx + + + crypto_sign + + + crypto_sign\ed25519 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_secretbox + + + crypto_secretbox + + + crypto_secretbox\xsalsa20poly1305 + + + crypto_secretbox\xchacha20poly1305 + + + crypto_pwhash + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256\nosse + + + crypto_pwhash\scryptsalsa208sha256\sse + + + crypto_verify\sodium + + + crypto_auth + + + crypto_auth\hmacsha512 + + + crypto_auth\hmacsha512256 + + + crypto_auth\hmacsha256 + + + crypto_kdf + + + crypto_kdf\blake2b + + + crypto_shorthash + + + crypto_shorthash\siphash24 + + + crypto_shorthash\siphash24 + + + crypto_shorthash\siphash24\ref + + + crypto_shorthash\siphash24\ref + + + crypto_scalarmult + + + crypto_scalarmult\ristretto255\ref10 + + + crypto_scalarmult\ed25519\ref10 + + + crypto_scalarmult\curve25519 + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\ref10 + + + crypto_onetimeauth + + + crypto_onetimeauth\poly1305 + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\sse2 + + + randombytes + + + randombytes\sysrandom + + + randombytes\internal + + + crypto_box + + + crypto_box + + + crypto_box + + + crypto_box\curve25519xsalsa20poly1305 + + + crypto_box\curve25519xchacha20poly1305 + + + crypto_box\curve25519xchacha20poly1305 + + + sodium + + + sodium + + + sodium + + + sodium + + + sodium + + + crypto_stream + + + crypto_stream\xchacha20 + + + crypto_stream\chacha20 + + + crypto_stream\chacha20\ref + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\salsa20 + + + crypto_stream\salsa20\ref + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6 + + + crypto_stream\salsa2012 + + + crypto_stream\salsa2012\ref + + + crypto_stream\salsa208 + + + crypto_stream\salsa208\ref + + + crypto_stream\xsalsa20 + + + crypto_hash + + + crypto_hash\sha512 + + + crypto_hash\sha512\cp + + + crypto_hash\sha256 + + + crypto_hash\sha256\cp + + + crypto_aead\xchacha20poly1305\sodium + + + crypto_aead\aes256gcm\aesni + + + crypto_aead\chacha20poly1305\sodium + + + crypto_secretstream\xchacha20poly1305 + + + crypto_core\salsa\ref + + + crypto_core\hchacha20 + + + crypto_core\hsalsa20 + + + crypto_core\hsalsa20\ref2 + + + crypto_core\ed25519 + + + crypto_core\ed25519 + + + crypto_core\ed25519\ref10 + + + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_sign\ed25519\ref10 + + + include + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_shorthash\siphash24\ref + + + crypto_scalarmult\curve25519 + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\ref10 + + + crypto_onetimeauth\poly1305 + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\sse2 + + + crypto_stream\chacha20 + + + crypto_stream\chacha20\ref + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\salsa20 + + + crypto_stream\salsa20\ref + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + + + {a6837e41-3751-38c9-bb90-dd59d5f4af7b} + + + {3e53394c-b59c-30cc-ae69-a4f46f9edfa3} + + + {7eb51140-a50f-3f50-b379-83677a82496c} + + + {1f4d6dd1-517f-3eeb-b974-2304ada5e67a} + + + {b145288f-68ad-3e79-93cb-e36537b20e26} + + + {3122f223-e6c2-3ab1-ad85-ca289b47419e} + + + {2720c2c8-c517-356e-83ed-c2997ab782c3} + + + {0a3af0f3-56f7-3551-a64e-6284feccc423} + + + {64e89b4f-eec9-38c9-90f2-4881bf5e84c0} + + + {0c0b4001-ae11-3d0f-8e73-75ac9b6e1ae8} + + + {f5065d74-beda-3e1e-819a-f606279c7fe9} + + + {f7aedb93-94a6-3ede-9374-ff41daca4841} + + + {0e7473c9-9c69-36b3-ab6c-d953647a15a6} + + + {d75db64c-eb08-3f10-9b99-1b6e6827f348} + + + {73194d5d-588a-342f-bee6-f28b4486f20b} + + + {7c5e6f81-e4ce-3018-a776-a1f125072d73} + + + {76990c08-d692-367f-b286-c728a8cad6bf} + + + {bf04f786-7862-3bde-aeba-ed82ee59ca22} + + + {98b6126a-3725-3707-a4cc-ff3af657cba0} + + + {8b704d11-af1f-30c0-9981-479da6d88dc3} + + + {342e684b-4e18-311c-953c-8391a544a04f} + + + {c6b8e28c-7c54-3af7-bee3-2948ba7b2082} + + + {4e9a1d6b-ee07-3bbc-ad78-6d0ba0e6d9d3} + + + {eb259fd9-56f0-32db-a903-6bc1549a7326} + + + {e53b6258-fcdd-34c8-96c5-44510a34a390} + + + {8bd3b558-2d08-3c3a-81ca-22677dde943b} + + + {16a8dd41-b0ab-39a7-80c8-3052d8b63811} + + + {d7ec3690-bae7-3653-8c53-66a3142cfcfa} + + + {722ef422-8c03-3008-ba2a-3a7e91c6647c} + + + {8c7d8b62-7b4f-3eb9-85b7-18e8d925be14} + + + {8fb6a906-dbd6-3746-9b0f-f49e7028daec} + + + {f2d6a22b-dd67-3561-90a4-88696169cb7b} + + + {aaf59186-1c0d-33cf-a34d-93e14bb87226} + + + {3d42d2a2-b192-33dd-9162-508916414707} + + + {898b6bd5-1360-3a34-adcd-0fade7561685} + + + {323c0a15-3c1d-39b2-9ec1-299deb299497} + + + {52c2080d-37c0-34c2-864a-c201c728e5d8} + + + {ff618a41-caeb-3a18-ad36-d34b049a8f50} + + + {ffc3712d-dfe0-3b51-8257-f5ffc9c9cea3} + + + {f54b65b6-71cf-3ab3-9c8c-f89c81846836} + + + {1bd97a78-befa-3805-8e9c-80d7c1aff37b} + + + {e785f104-1212-37bf-8511-cc518b9ace66} + + + {447b993f-59fb-3efd-8c59-a1712c97dfe8} + + + {cdb8d233-06b0-3872-a62b-c1ccf4cb4314} + + + {402a1c5a-d499-333a-a2fa-acd0e6a3c2b2} + + + {77f5a2e9-2ef1-3a72-b63c-88e8e4b92678} + + + {6c9c7c30-0808-3fad-8a88-944d7645e5d5} + + + {5d2fb1a2-f063-32db-a81a-41f79e36fd23} + + + {7bec6074-fbc7-330b-9e18-7dc3e868569a} + + + {834d4827-81e4-3de3-baa1-a216763f11d6} + + + {52bf28eb-7ffd-399a-be35-0df3e8e99c15} + + + {39cc576f-4b54-3d71-b14c-27445bc4b138} + + + {b9b02bee-5c1f-36d2-b97d-983f865a4cc6} + + + {41f1f35b-4639-3424-be85-7dfba02f3c5e} + + + {8bf11d29-2f5a-3f10-8ae6-82229d19c5b0} + + + {62f7ae38-4ce6-3976-acc3-47c462db4fbe} + + + {e07a28cd-775a-3798-bfdb-97842d3614d6} + + + {bb073c16-adc8-3cff-80b9-99cf5a28de6c} + + + {63de0ec8-ecde-35e3-8b97-6e9e4da342ee} + + + {29925210-53eb-342c-8527-7ebc173e668f} + + + {b2f989b6-87a6-3388-a35c-2d0d59cb4236} + + + {bc6466a1-57b0-3a35-9973-ad488a4bef8c} + + + {5599d9ab-b5b2-3310-b541-ae0fb70eecf1} + + + {eaedd08a-46f8-3d12-9e8d-bb3ee3ead5f6} + + + {806b6ff3-578b-308a-a359-0f5ed8472ecc} + + + {5a1d852e-67bb-3dc1-9ec5-99ef74b7faca} + + + {33e45d9c-e12a-3e76-9ef2-4f5510244a5b} + + + {048ba2a8-b22b-346c-9886-668b63c88c68} + + + {f08a312f-f8a3-350b-87ab-1f79d33e513f} + + + {c403f690-cd22-3ed4-9cc7-3f46e73081fd} + + + {c34d03f5-cf47-39fe-a5ad-5eb917006203} + + + {4da0c5ca-33d1-34e0-9689-12e69ae2dbd6} + + + {dd6b294c-5871-386c-92ec-aa46fcc411d4} + + + {07aca978-0547-329a-b70b-29aa579cacc5} + + + {f171fa05-35c4-32a0-b035-b5d6680ab714} + + + {ede2279c-1ba7-3d62-8345-733c6c1965e7} + + + {9c15151b-10dc-3dfe-b97b-a7d8c6b58920} + + + {49fb9272-ffe2-3993-b562-b19d5f2c9b40} + + + {80669cf5-3c9c-3c60-b409-9d8fb305bc77} + + + {96da72eb-3aa0-3850-83eb-32788f91e5bd} + + + {56bb40fc-d381-3a9e-925b-681774c48dde} + + + {fde88485-0fe6-3b22-9480-1d2b49fade53} + + + {ef090484-4db4-3dc2-aca7-c59bab1db23b} + + + {14c126fd-bb91-37ea-b807-b60c386be601} + + + {ac56c38f-7e17-3b79-bf47-58e9476b3b89} + + + {5dfc520b-f690-3d5f-a86a-8b667f2e7490} + + + diff --git a/external/src/libsodium/builds/msvc/vs2010/libsodium/libsodium.xml b/external/src/libsodium/builds/msvc/vs2010/libsodium/libsodium.xml new file mode 100644 index 0000000..808ccb9 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2010/libsodium/libsodium.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2012/libsodium.import.props b/external/src/libsodium/builds/msvc/vs2012/libsodium.import.props new file mode 100644 index 0000000..b3d7e4f --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2012/libsodium.import.props @@ -0,0 +1,52 @@ + + + + + <_PropertySheetDisplayName>Libsodium Import Settings + + + + + + + + + + + + + $(ProjectDir)..\..\..\..\..\libsodium\src\libsodium\include;$(ProjectDir)..\..\..\..\..\libsodium\src\libsodium\include\sodium\;%(AdditionalIncludeDirectories) + SODIUM_STATIC;%(PreprocessorDefinitions) + + + advapi32.lib;libsodium.lib;%(AdditionalDependencies) + $(ProjectDir)..\..\..\..\..\libsodium\bin\$(PlatformName)\Debug\$(PlatformToolset)\$(Linkage-libsodium)\;%(AdditionalLibraryDirectories) + $(ProjectDir)..\..\..\..\..\libsodium\bin\$(PlatformName)\Release\$(PlatformToolset)\$(Linkage-libsodium)\;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2012/libsodium.import.xml b/external/src/libsodium/builds/msvc/vs2012/libsodium.import.xml new file mode 100644 index 0000000..dbcf4e5 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2012/libsodium.import.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2012/libsodium.sln b/external/src/libsodium/builds/msvc/vs2012/libsodium.sln new file mode 100644 index 0000000..251421a --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2012/libsodium.sln @@ -0,0 +1,50 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Express 2012 for Windows Desktop +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsodium", "libsodium\libsodium.vcxproj", "{A185B162-6CB6-4502-B03F-B56F7699A8D9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + DynDebug|Win32 = DynDebug|Win32 + DynDebug|x64 = DynDebug|x64 + DynRelease|Win32 = DynRelease|Win32 + DynRelease|x64 = DynRelease|x64 + LtcgDebug|Win32 = LtcgDebug|Win32 + LtcgDebug|x64 = LtcgDebug|x64 + LtcgRelease|Win32 = LtcgRelease|Win32 + LtcgRelease|x64 = LtcgRelease|x64 + StaticDebug|Win32 = StaticDebug|Win32 + StaticDebug|x64 = StaticDebug|x64 + StaticRelease|Win32 = StaticRelease|Win32 + StaticRelease|x64 = StaticRelease|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|Win32.ActiveCfg = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|Win32.Build.0 = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|x64.ActiveCfg = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|x64.Build.0 = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|Win32.ActiveCfg = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|Win32.Build.0 = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|x64.ActiveCfg = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|x64.Build.0 = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|Win32.ActiveCfg = DebugLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|Win32.Build.0 = DebugLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|x64.ActiveCfg = DebugLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|x64.Build.0 = DebugLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|Win32.ActiveCfg = ReleaseLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|Win32.Build.0 = ReleaseLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|x64.ActiveCfg = ReleaseLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|x64.Build.0 = ReleaseLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|Win32.ActiveCfg = DebugLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|Win32.Build.0 = DebugLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|x64.ActiveCfg = DebugLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|x64.Build.0 = DebugLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|Win32.ActiveCfg = ReleaseLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|Win32.Build.0 = ReleaseLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|x64.ActiveCfg = ReleaseLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|x64.Build.0 = ReleaseLIB|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/external/src/libsodium/builds/msvc/vs2012/libsodium/libsodium.props b/external/src/libsodium/builds/msvc/vs2012/libsodium/libsodium.props new file mode 100644 index 0000000..5a23903 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2012/libsodium/libsodium.props @@ -0,0 +1,48 @@ + + + + + <_PropertySheetDisplayName>Libsodium Common Settings + AllRules.ruleset + false + + + + + + + + + + + + + copy "$(BuildRoot)version.h" "$(RepoRoot)src\libsodium\include\sodium\" + + + $(RepoRoot)src\libsodium\include;$(RepoRoot)src\libsodium\include\sodium\;%(AdditionalIncludeDirectories) + 4146;4244;%(DisableSpecificWarnings) + false + inline=__inline;NATIVE_LITTLE_ENDIAN;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + SODIUM_STATIC;%(PreprocessorDefinitions) + SODIUM_DLL_EXPORT;%(PreprocessorDefinitions) + HAVE_AMD64_ASM;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + advapi32.lib + + + diff --git a/external/src/libsodium/builds/msvc/vs2012/libsodium/libsodium.vcxproj b/external/src/libsodium/builds/msvc/vs2012/libsodium/libsodium.vcxproj new file mode 100644 index 0000000..1228a1a --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2012/libsodium/libsodium.vcxproj @@ -0,0 +1,325 @@ + + + + {A185B162-6CB6-4502-B03F-B56F7699A8D9} + libsodium + v110 + + + + DebugDLL + Win32 + + + ReleaseDLL + Win32 + + + DebugDLL + x64 + + + ReleaseDLL + x64 + + + DebugLTCG + Win32 + + + ReleaseLTCG + Win32 + + + DebugLTCG + x64 + + + ReleaseLTCG + x64 + + + DebugLIB + Win32 + + + ReleaseLIB + Win32 + + + DebugLIB + x64 + + + ReleaseLIB + x64 + + + + StaticLibrary + DynamicLibrary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/src/libsodium/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters b/external/src/libsodium/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters new file mode 100644 index 0000000..f152794 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters @@ -0,0 +1,992 @@ + + + + + packaging + + + packaging + + + packaging + + + packaging + + + packaging + + + packaging + + + + + + + + crypto_generichash + + + crypto_generichash\blake2b + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_kx + + + crypto_sign + + + crypto_sign\ed25519 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_secretbox + + + crypto_secretbox + + + crypto_secretbox\xsalsa20poly1305 + + + crypto_secretbox\xchacha20poly1305 + + + crypto_pwhash + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256\nosse + + + crypto_pwhash\scryptsalsa208sha256\sse + + + crypto_verify\sodium + + + crypto_auth + + + crypto_auth\hmacsha512 + + + crypto_auth\hmacsha512256 + + + crypto_auth\hmacsha256 + + + crypto_kdf + + + crypto_kdf\blake2b + + + crypto_shorthash + + + crypto_shorthash\siphash24 + + + crypto_shorthash\siphash24 + + + crypto_shorthash\siphash24\ref + + + crypto_shorthash\siphash24\ref + + + crypto_scalarmult + + + crypto_scalarmult\ristretto255\ref10 + + + crypto_scalarmult\ed25519\ref10 + + + crypto_scalarmult\curve25519 + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\ref10 + + + crypto_onetimeauth + + + crypto_onetimeauth\poly1305 + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\sse2 + + + randombytes + + + randombytes\sysrandom + + + randombytes\internal + + + crypto_box + + + crypto_box + + + crypto_box + + + crypto_box\curve25519xsalsa20poly1305 + + + crypto_box\curve25519xchacha20poly1305 + + + crypto_box\curve25519xchacha20poly1305 + + + sodium + + + sodium + + + sodium + + + sodium + + + sodium + + + crypto_stream + + + crypto_stream\xchacha20 + + + crypto_stream\chacha20 + + + crypto_stream\chacha20\ref + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\salsa20 + + + crypto_stream\salsa20\ref + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6 + + + crypto_stream\salsa2012 + + + crypto_stream\salsa2012\ref + + + crypto_stream\salsa208 + + + crypto_stream\salsa208\ref + + + crypto_stream\xsalsa20 + + + crypto_hash + + + crypto_hash\sha512 + + + crypto_hash\sha512\cp + + + crypto_hash\sha256 + + + crypto_hash\sha256\cp + + + crypto_aead\xchacha20poly1305\sodium + + + crypto_aead\aes256gcm\aesni + + + crypto_aead\chacha20poly1305\sodium + + + crypto_secretstream\xchacha20poly1305 + + + crypto_core\salsa\ref + + + crypto_core\hchacha20 + + + crypto_core\hsalsa20 + + + crypto_core\hsalsa20\ref2 + + + crypto_core\ed25519 + + + crypto_core\ed25519 + + + crypto_core\ed25519\ref10 + + + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_sign\ed25519\ref10 + + + include + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_shorthash\siphash24\ref + + + crypto_scalarmult\curve25519 + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\ref10 + + + crypto_onetimeauth\poly1305 + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\sse2 + + + crypto_stream\chacha20 + + + crypto_stream\chacha20\ref + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\salsa20 + + + crypto_stream\salsa20\ref + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + + + {a6837e41-3751-38c9-bb90-dd59d5f4af7b} + + + {3e53394c-b59c-30cc-ae69-a4f46f9edfa3} + + + {7eb51140-a50f-3f50-b379-83677a82496c} + + + {1f4d6dd1-517f-3eeb-b974-2304ada5e67a} + + + {b145288f-68ad-3e79-93cb-e36537b20e26} + + + {3122f223-e6c2-3ab1-ad85-ca289b47419e} + + + {2720c2c8-c517-356e-83ed-c2997ab782c3} + + + {0a3af0f3-56f7-3551-a64e-6284feccc423} + + + {64e89b4f-eec9-38c9-90f2-4881bf5e84c0} + + + {0c0b4001-ae11-3d0f-8e73-75ac9b6e1ae8} + + + {f5065d74-beda-3e1e-819a-f606279c7fe9} + + + {f7aedb93-94a6-3ede-9374-ff41daca4841} + + + {0e7473c9-9c69-36b3-ab6c-d953647a15a6} + + + {d75db64c-eb08-3f10-9b99-1b6e6827f348} + + + {73194d5d-588a-342f-bee6-f28b4486f20b} + + + {7c5e6f81-e4ce-3018-a776-a1f125072d73} + + + {76990c08-d692-367f-b286-c728a8cad6bf} + + + {bf04f786-7862-3bde-aeba-ed82ee59ca22} + + + {98b6126a-3725-3707-a4cc-ff3af657cba0} + + + {8b704d11-af1f-30c0-9981-479da6d88dc3} + + + {342e684b-4e18-311c-953c-8391a544a04f} + + + {c6b8e28c-7c54-3af7-bee3-2948ba7b2082} + + + {4e9a1d6b-ee07-3bbc-ad78-6d0ba0e6d9d3} + + + {eb259fd9-56f0-32db-a903-6bc1549a7326} + + + {e53b6258-fcdd-34c8-96c5-44510a34a390} + + + {8bd3b558-2d08-3c3a-81ca-22677dde943b} + + + {16a8dd41-b0ab-39a7-80c8-3052d8b63811} + + + {d7ec3690-bae7-3653-8c53-66a3142cfcfa} + + + {722ef422-8c03-3008-ba2a-3a7e91c6647c} + + + {8c7d8b62-7b4f-3eb9-85b7-18e8d925be14} + + + {8fb6a906-dbd6-3746-9b0f-f49e7028daec} + + + {f2d6a22b-dd67-3561-90a4-88696169cb7b} + + + {aaf59186-1c0d-33cf-a34d-93e14bb87226} + + + {3d42d2a2-b192-33dd-9162-508916414707} + + + {898b6bd5-1360-3a34-adcd-0fade7561685} + + + {323c0a15-3c1d-39b2-9ec1-299deb299497} + + + {52c2080d-37c0-34c2-864a-c201c728e5d8} + + + {ff618a41-caeb-3a18-ad36-d34b049a8f50} + + + {ffc3712d-dfe0-3b51-8257-f5ffc9c9cea3} + + + {f54b65b6-71cf-3ab3-9c8c-f89c81846836} + + + {1bd97a78-befa-3805-8e9c-80d7c1aff37b} + + + {e785f104-1212-37bf-8511-cc518b9ace66} + + + {447b993f-59fb-3efd-8c59-a1712c97dfe8} + + + {cdb8d233-06b0-3872-a62b-c1ccf4cb4314} + + + {402a1c5a-d499-333a-a2fa-acd0e6a3c2b2} + + + {77f5a2e9-2ef1-3a72-b63c-88e8e4b92678} + + + {6c9c7c30-0808-3fad-8a88-944d7645e5d5} + + + {5d2fb1a2-f063-32db-a81a-41f79e36fd23} + + + {7bec6074-fbc7-330b-9e18-7dc3e868569a} + + + {834d4827-81e4-3de3-baa1-a216763f11d6} + + + {52bf28eb-7ffd-399a-be35-0df3e8e99c15} + + + {39cc576f-4b54-3d71-b14c-27445bc4b138} + + + {b9b02bee-5c1f-36d2-b97d-983f865a4cc6} + + + {41f1f35b-4639-3424-be85-7dfba02f3c5e} + + + {8bf11d29-2f5a-3f10-8ae6-82229d19c5b0} + + + {62f7ae38-4ce6-3976-acc3-47c462db4fbe} + + + {e07a28cd-775a-3798-bfdb-97842d3614d6} + + + {bb073c16-adc8-3cff-80b9-99cf5a28de6c} + + + {63de0ec8-ecde-35e3-8b97-6e9e4da342ee} + + + {29925210-53eb-342c-8527-7ebc173e668f} + + + {b2f989b6-87a6-3388-a35c-2d0d59cb4236} + + + {bc6466a1-57b0-3a35-9973-ad488a4bef8c} + + + {5599d9ab-b5b2-3310-b541-ae0fb70eecf1} + + + {eaedd08a-46f8-3d12-9e8d-bb3ee3ead5f6} + + + {806b6ff3-578b-308a-a359-0f5ed8472ecc} + + + {5a1d852e-67bb-3dc1-9ec5-99ef74b7faca} + + + {33e45d9c-e12a-3e76-9ef2-4f5510244a5b} + + + {048ba2a8-b22b-346c-9886-668b63c88c68} + + + {f08a312f-f8a3-350b-87ab-1f79d33e513f} + + + {c403f690-cd22-3ed4-9cc7-3f46e73081fd} + + + {c34d03f5-cf47-39fe-a5ad-5eb917006203} + + + {4da0c5ca-33d1-34e0-9689-12e69ae2dbd6} + + + {dd6b294c-5871-386c-92ec-aa46fcc411d4} + + + {07aca978-0547-329a-b70b-29aa579cacc5} + + + {f171fa05-35c4-32a0-b035-b5d6680ab714} + + + {ede2279c-1ba7-3d62-8345-733c6c1965e7} + + + {9c15151b-10dc-3dfe-b97b-a7d8c6b58920} + + + {49fb9272-ffe2-3993-b562-b19d5f2c9b40} + + + {80669cf5-3c9c-3c60-b409-9d8fb305bc77} + + + {96da72eb-3aa0-3850-83eb-32788f91e5bd} + + + {56bb40fc-d381-3a9e-925b-681774c48dde} + + + {fde88485-0fe6-3b22-9480-1d2b49fade53} + + + {ef090484-4db4-3dc2-aca7-c59bab1db23b} + + + {14c126fd-bb91-37ea-b807-b60c386be601} + + + {ac56c38f-7e17-3b79-bf47-58e9476b3b89} + + + {5dfc520b-f690-3d5f-a86a-8b667f2e7490} + + + diff --git a/external/src/libsodium/builds/msvc/vs2012/libsodium/libsodium.xml b/external/src/libsodium/builds/msvc/vs2012/libsodium/libsodium.xml new file mode 100644 index 0000000..808ccb9 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2012/libsodium/libsodium.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2013/libsodium.import.props b/external/src/libsodium/builds/msvc/vs2013/libsodium.import.props new file mode 100644 index 0000000..b3d7e4f --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2013/libsodium.import.props @@ -0,0 +1,52 @@ + + + + + <_PropertySheetDisplayName>Libsodium Import Settings + + + + + + + + + + + + + $(ProjectDir)..\..\..\..\..\libsodium\src\libsodium\include;$(ProjectDir)..\..\..\..\..\libsodium\src\libsodium\include\sodium\;%(AdditionalIncludeDirectories) + SODIUM_STATIC;%(PreprocessorDefinitions) + + + advapi32.lib;libsodium.lib;%(AdditionalDependencies) + $(ProjectDir)..\..\..\..\..\libsodium\bin\$(PlatformName)\Debug\$(PlatformToolset)\$(Linkage-libsodium)\;%(AdditionalLibraryDirectories) + $(ProjectDir)..\..\..\..\..\libsodium\bin\$(PlatformName)\Release\$(PlatformToolset)\$(Linkage-libsodium)\;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2013/libsodium.import.xml b/external/src/libsodium/builds/msvc/vs2013/libsodium.import.xml new file mode 100644 index 0000000..dbcf4e5 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2013/libsodium.import.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2013/libsodium.sln b/external/src/libsodium/builds/msvc/vs2013/libsodium.sln new file mode 100644 index 0000000..28f50ca --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2013/libsodium.sln @@ -0,0 +1,52 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsodium", "libsodium\libsodium.vcxproj", "{A185B162-6CB6-4502-B03F-B56F7699A8D9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + DynDebug|Win32 = DynDebug|Win32 + DynDebug|x64 = DynDebug|x64 + DynRelease|Win32 = DynRelease|Win32 + DynRelease|x64 = DynRelease|x64 + LtcgDebug|Win32 = LtcgDebug|Win32 + LtcgDebug|x64 = LtcgDebug|x64 + LtcgRelease|Win32 = LtcgRelease|Win32 + LtcgRelease|x64 = LtcgRelease|x64 + StaticDebug|Win32 = StaticDebug|Win32 + StaticDebug|x64 = StaticDebug|x64 + StaticRelease|Win32 = StaticRelease|Win32 + StaticRelease|x64 = StaticRelease|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|Win32.ActiveCfg = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|Win32.Build.0 = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|x64.ActiveCfg = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|x64.Build.0 = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|Win32.ActiveCfg = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|Win32.Build.0 = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|x64.ActiveCfg = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|x64.Build.0 = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|Win32.ActiveCfg = DebugLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|Win32.Build.0 = DebugLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|x64.ActiveCfg = DebugLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|x64.Build.0 = DebugLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|Win32.ActiveCfg = ReleaseLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|Win32.Build.0 = ReleaseLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|x64.ActiveCfg = ReleaseLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|x64.Build.0 = ReleaseLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|Win32.ActiveCfg = DebugLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|Win32.Build.0 = DebugLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|x64.ActiveCfg = DebugLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|x64.Build.0 = DebugLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|Win32.ActiveCfg = ReleaseLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|Win32.Build.0 = ReleaseLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|x64.ActiveCfg = ReleaseLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|x64.Build.0 = ReleaseLIB|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/external/src/libsodium/builds/msvc/vs2013/libsodium/libsodium.props b/external/src/libsodium/builds/msvc/vs2013/libsodium/libsodium.props new file mode 100644 index 0000000..5a23903 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2013/libsodium/libsodium.props @@ -0,0 +1,48 @@ + + + + + <_PropertySheetDisplayName>Libsodium Common Settings + AllRules.ruleset + false + + + + + + + + + + + + + copy "$(BuildRoot)version.h" "$(RepoRoot)src\libsodium\include\sodium\" + + + $(RepoRoot)src\libsodium\include;$(RepoRoot)src\libsodium\include\sodium\;%(AdditionalIncludeDirectories) + 4146;4244;%(DisableSpecificWarnings) + false + inline=__inline;NATIVE_LITTLE_ENDIAN;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + SODIUM_STATIC;%(PreprocessorDefinitions) + SODIUM_DLL_EXPORT;%(PreprocessorDefinitions) + HAVE_AMD64_ASM;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + advapi32.lib + + + diff --git a/external/src/libsodium/builds/msvc/vs2013/libsodium/libsodium.vcxproj b/external/src/libsodium/builds/msvc/vs2013/libsodium/libsodium.vcxproj new file mode 100644 index 0000000..9571186 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2013/libsodium/libsodium.vcxproj @@ -0,0 +1,325 @@ + + + + {A185B162-6CB6-4502-B03F-B56F7699A8D9} + libsodium + v120 + + + + DebugDLL + Win32 + + + ReleaseDLL + Win32 + + + DebugDLL + x64 + + + ReleaseDLL + x64 + + + DebugLTCG + Win32 + + + ReleaseLTCG + Win32 + + + DebugLTCG + x64 + + + ReleaseLTCG + x64 + + + DebugLIB + Win32 + + + ReleaseLIB + Win32 + + + DebugLIB + x64 + + + ReleaseLIB + x64 + + + + StaticLibrary + DynamicLibrary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/src/libsodium/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters b/external/src/libsodium/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters new file mode 100644 index 0000000..f152794 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters @@ -0,0 +1,992 @@ + + + + + packaging + + + packaging + + + packaging + + + packaging + + + packaging + + + packaging + + + + + + + + crypto_generichash + + + crypto_generichash\blake2b + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_kx + + + crypto_sign + + + crypto_sign\ed25519 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_secretbox + + + crypto_secretbox + + + crypto_secretbox\xsalsa20poly1305 + + + crypto_secretbox\xchacha20poly1305 + + + crypto_pwhash + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256\nosse + + + crypto_pwhash\scryptsalsa208sha256\sse + + + crypto_verify\sodium + + + crypto_auth + + + crypto_auth\hmacsha512 + + + crypto_auth\hmacsha512256 + + + crypto_auth\hmacsha256 + + + crypto_kdf + + + crypto_kdf\blake2b + + + crypto_shorthash + + + crypto_shorthash\siphash24 + + + crypto_shorthash\siphash24 + + + crypto_shorthash\siphash24\ref + + + crypto_shorthash\siphash24\ref + + + crypto_scalarmult + + + crypto_scalarmult\ristretto255\ref10 + + + crypto_scalarmult\ed25519\ref10 + + + crypto_scalarmult\curve25519 + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\ref10 + + + crypto_onetimeauth + + + crypto_onetimeauth\poly1305 + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\sse2 + + + randombytes + + + randombytes\sysrandom + + + randombytes\internal + + + crypto_box + + + crypto_box + + + crypto_box + + + crypto_box\curve25519xsalsa20poly1305 + + + crypto_box\curve25519xchacha20poly1305 + + + crypto_box\curve25519xchacha20poly1305 + + + sodium + + + sodium + + + sodium + + + sodium + + + sodium + + + crypto_stream + + + crypto_stream\xchacha20 + + + crypto_stream\chacha20 + + + crypto_stream\chacha20\ref + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\salsa20 + + + crypto_stream\salsa20\ref + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6 + + + crypto_stream\salsa2012 + + + crypto_stream\salsa2012\ref + + + crypto_stream\salsa208 + + + crypto_stream\salsa208\ref + + + crypto_stream\xsalsa20 + + + crypto_hash + + + crypto_hash\sha512 + + + crypto_hash\sha512\cp + + + crypto_hash\sha256 + + + crypto_hash\sha256\cp + + + crypto_aead\xchacha20poly1305\sodium + + + crypto_aead\aes256gcm\aesni + + + crypto_aead\chacha20poly1305\sodium + + + crypto_secretstream\xchacha20poly1305 + + + crypto_core\salsa\ref + + + crypto_core\hchacha20 + + + crypto_core\hsalsa20 + + + crypto_core\hsalsa20\ref2 + + + crypto_core\ed25519 + + + crypto_core\ed25519 + + + crypto_core\ed25519\ref10 + + + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_sign\ed25519\ref10 + + + include + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_shorthash\siphash24\ref + + + crypto_scalarmult\curve25519 + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\ref10 + + + crypto_onetimeauth\poly1305 + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\sse2 + + + crypto_stream\chacha20 + + + crypto_stream\chacha20\ref + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\salsa20 + + + crypto_stream\salsa20\ref + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + + + {a6837e41-3751-38c9-bb90-dd59d5f4af7b} + + + {3e53394c-b59c-30cc-ae69-a4f46f9edfa3} + + + {7eb51140-a50f-3f50-b379-83677a82496c} + + + {1f4d6dd1-517f-3eeb-b974-2304ada5e67a} + + + {b145288f-68ad-3e79-93cb-e36537b20e26} + + + {3122f223-e6c2-3ab1-ad85-ca289b47419e} + + + {2720c2c8-c517-356e-83ed-c2997ab782c3} + + + {0a3af0f3-56f7-3551-a64e-6284feccc423} + + + {64e89b4f-eec9-38c9-90f2-4881bf5e84c0} + + + {0c0b4001-ae11-3d0f-8e73-75ac9b6e1ae8} + + + {f5065d74-beda-3e1e-819a-f606279c7fe9} + + + {f7aedb93-94a6-3ede-9374-ff41daca4841} + + + {0e7473c9-9c69-36b3-ab6c-d953647a15a6} + + + {d75db64c-eb08-3f10-9b99-1b6e6827f348} + + + {73194d5d-588a-342f-bee6-f28b4486f20b} + + + {7c5e6f81-e4ce-3018-a776-a1f125072d73} + + + {76990c08-d692-367f-b286-c728a8cad6bf} + + + {bf04f786-7862-3bde-aeba-ed82ee59ca22} + + + {98b6126a-3725-3707-a4cc-ff3af657cba0} + + + {8b704d11-af1f-30c0-9981-479da6d88dc3} + + + {342e684b-4e18-311c-953c-8391a544a04f} + + + {c6b8e28c-7c54-3af7-bee3-2948ba7b2082} + + + {4e9a1d6b-ee07-3bbc-ad78-6d0ba0e6d9d3} + + + {eb259fd9-56f0-32db-a903-6bc1549a7326} + + + {e53b6258-fcdd-34c8-96c5-44510a34a390} + + + {8bd3b558-2d08-3c3a-81ca-22677dde943b} + + + {16a8dd41-b0ab-39a7-80c8-3052d8b63811} + + + {d7ec3690-bae7-3653-8c53-66a3142cfcfa} + + + {722ef422-8c03-3008-ba2a-3a7e91c6647c} + + + {8c7d8b62-7b4f-3eb9-85b7-18e8d925be14} + + + {8fb6a906-dbd6-3746-9b0f-f49e7028daec} + + + {f2d6a22b-dd67-3561-90a4-88696169cb7b} + + + {aaf59186-1c0d-33cf-a34d-93e14bb87226} + + + {3d42d2a2-b192-33dd-9162-508916414707} + + + {898b6bd5-1360-3a34-adcd-0fade7561685} + + + {323c0a15-3c1d-39b2-9ec1-299deb299497} + + + {52c2080d-37c0-34c2-864a-c201c728e5d8} + + + {ff618a41-caeb-3a18-ad36-d34b049a8f50} + + + {ffc3712d-dfe0-3b51-8257-f5ffc9c9cea3} + + + {f54b65b6-71cf-3ab3-9c8c-f89c81846836} + + + {1bd97a78-befa-3805-8e9c-80d7c1aff37b} + + + {e785f104-1212-37bf-8511-cc518b9ace66} + + + {447b993f-59fb-3efd-8c59-a1712c97dfe8} + + + {cdb8d233-06b0-3872-a62b-c1ccf4cb4314} + + + {402a1c5a-d499-333a-a2fa-acd0e6a3c2b2} + + + {77f5a2e9-2ef1-3a72-b63c-88e8e4b92678} + + + {6c9c7c30-0808-3fad-8a88-944d7645e5d5} + + + {5d2fb1a2-f063-32db-a81a-41f79e36fd23} + + + {7bec6074-fbc7-330b-9e18-7dc3e868569a} + + + {834d4827-81e4-3de3-baa1-a216763f11d6} + + + {52bf28eb-7ffd-399a-be35-0df3e8e99c15} + + + {39cc576f-4b54-3d71-b14c-27445bc4b138} + + + {b9b02bee-5c1f-36d2-b97d-983f865a4cc6} + + + {41f1f35b-4639-3424-be85-7dfba02f3c5e} + + + {8bf11d29-2f5a-3f10-8ae6-82229d19c5b0} + + + {62f7ae38-4ce6-3976-acc3-47c462db4fbe} + + + {e07a28cd-775a-3798-bfdb-97842d3614d6} + + + {bb073c16-adc8-3cff-80b9-99cf5a28de6c} + + + {63de0ec8-ecde-35e3-8b97-6e9e4da342ee} + + + {29925210-53eb-342c-8527-7ebc173e668f} + + + {b2f989b6-87a6-3388-a35c-2d0d59cb4236} + + + {bc6466a1-57b0-3a35-9973-ad488a4bef8c} + + + {5599d9ab-b5b2-3310-b541-ae0fb70eecf1} + + + {eaedd08a-46f8-3d12-9e8d-bb3ee3ead5f6} + + + {806b6ff3-578b-308a-a359-0f5ed8472ecc} + + + {5a1d852e-67bb-3dc1-9ec5-99ef74b7faca} + + + {33e45d9c-e12a-3e76-9ef2-4f5510244a5b} + + + {048ba2a8-b22b-346c-9886-668b63c88c68} + + + {f08a312f-f8a3-350b-87ab-1f79d33e513f} + + + {c403f690-cd22-3ed4-9cc7-3f46e73081fd} + + + {c34d03f5-cf47-39fe-a5ad-5eb917006203} + + + {4da0c5ca-33d1-34e0-9689-12e69ae2dbd6} + + + {dd6b294c-5871-386c-92ec-aa46fcc411d4} + + + {07aca978-0547-329a-b70b-29aa579cacc5} + + + {f171fa05-35c4-32a0-b035-b5d6680ab714} + + + {ede2279c-1ba7-3d62-8345-733c6c1965e7} + + + {9c15151b-10dc-3dfe-b97b-a7d8c6b58920} + + + {49fb9272-ffe2-3993-b562-b19d5f2c9b40} + + + {80669cf5-3c9c-3c60-b409-9d8fb305bc77} + + + {96da72eb-3aa0-3850-83eb-32788f91e5bd} + + + {56bb40fc-d381-3a9e-925b-681774c48dde} + + + {fde88485-0fe6-3b22-9480-1d2b49fade53} + + + {ef090484-4db4-3dc2-aca7-c59bab1db23b} + + + {14c126fd-bb91-37ea-b807-b60c386be601} + + + {ac56c38f-7e17-3b79-bf47-58e9476b3b89} + + + {5dfc520b-f690-3d5f-a86a-8b667f2e7490} + + + diff --git a/external/src/libsodium/builds/msvc/vs2013/libsodium/libsodium.xml b/external/src/libsodium/builds/msvc/vs2013/libsodium/libsodium.xml new file mode 100644 index 0000000..808ccb9 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2013/libsodium/libsodium.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2015/libsodium.import.props b/external/src/libsodium/builds/msvc/vs2015/libsodium.import.props new file mode 100644 index 0000000..b3d7e4f --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2015/libsodium.import.props @@ -0,0 +1,52 @@ + + + + + <_PropertySheetDisplayName>Libsodium Import Settings + + + + + + + + + + + + + $(ProjectDir)..\..\..\..\..\libsodium\src\libsodium\include;$(ProjectDir)..\..\..\..\..\libsodium\src\libsodium\include\sodium\;%(AdditionalIncludeDirectories) + SODIUM_STATIC;%(PreprocessorDefinitions) + + + advapi32.lib;libsodium.lib;%(AdditionalDependencies) + $(ProjectDir)..\..\..\..\..\libsodium\bin\$(PlatformName)\Debug\$(PlatformToolset)\$(Linkage-libsodium)\;%(AdditionalLibraryDirectories) + $(ProjectDir)..\..\..\..\..\libsodium\bin\$(PlatformName)\Release\$(PlatformToolset)\$(Linkage-libsodium)\;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2015/libsodium.import.xml b/external/src/libsodium/builds/msvc/vs2015/libsodium.import.xml new file mode 100644 index 0000000..dbcf4e5 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2015/libsodium.import.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2015/libsodium.sln b/external/src/libsodium/builds/msvc/vs2015/libsodium.sln new file mode 100644 index 0000000..af37123 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2015/libsodium.sln @@ -0,0 +1,52 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsodium", "libsodium\libsodium.vcxproj", "{A185B162-6CB6-4502-B03F-B56F7699A8D9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + DynDebug|Win32 = DynDebug|Win32 + DynDebug|x64 = DynDebug|x64 + DynRelease|Win32 = DynRelease|Win32 + DynRelease|x64 = DynRelease|x64 + LtcgDebug|Win32 = LtcgDebug|Win32 + LtcgDebug|x64 = LtcgDebug|x64 + LtcgRelease|Win32 = LtcgRelease|Win32 + LtcgRelease|x64 = LtcgRelease|x64 + StaticDebug|Win32 = StaticDebug|Win32 + StaticDebug|x64 = StaticDebug|x64 + StaticRelease|Win32 = StaticRelease|Win32 + StaticRelease|x64 = StaticRelease|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|Win32.ActiveCfg = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|Win32.Build.0 = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|x64.ActiveCfg = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|x64.Build.0 = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|Win32.ActiveCfg = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|Win32.Build.0 = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|x64.ActiveCfg = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|x64.Build.0 = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|Win32.ActiveCfg = DebugLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|Win32.Build.0 = DebugLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|x64.ActiveCfg = DebugLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|x64.Build.0 = DebugLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|Win32.ActiveCfg = ReleaseLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|Win32.Build.0 = ReleaseLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|x64.ActiveCfg = ReleaseLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|x64.Build.0 = ReleaseLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|Win32.ActiveCfg = DebugLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|Win32.Build.0 = DebugLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|x64.ActiveCfg = DebugLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|x64.Build.0 = DebugLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|Win32.ActiveCfg = ReleaseLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|Win32.Build.0 = ReleaseLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|x64.ActiveCfg = ReleaseLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|x64.Build.0 = ReleaseLIB|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/external/src/libsodium/builds/msvc/vs2015/libsodium/libsodium.props b/external/src/libsodium/builds/msvc/vs2015/libsodium/libsodium.props new file mode 100644 index 0000000..5a23903 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2015/libsodium/libsodium.props @@ -0,0 +1,48 @@ + + + + + <_PropertySheetDisplayName>Libsodium Common Settings + AllRules.ruleset + false + + + + + + + + + + + + + copy "$(BuildRoot)version.h" "$(RepoRoot)src\libsodium\include\sodium\" + + + $(RepoRoot)src\libsodium\include;$(RepoRoot)src\libsodium\include\sodium\;%(AdditionalIncludeDirectories) + 4146;4244;%(DisableSpecificWarnings) + false + inline=__inline;NATIVE_LITTLE_ENDIAN;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + SODIUM_STATIC;%(PreprocessorDefinitions) + SODIUM_DLL_EXPORT;%(PreprocessorDefinitions) + HAVE_AMD64_ASM;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + advapi32.lib + + + diff --git a/external/src/libsodium/builds/msvc/vs2015/libsodium/libsodium.vcxproj b/external/src/libsodium/builds/msvc/vs2015/libsodium/libsodium.vcxproj new file mode 100644 index 0000000..db11acb --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2015/libsodium/libsodium.vcxproj @@ -0,0 +1,325 @@ + + + + {A185B162-6CB6-4502-B03F-B56F7699A8D9} + libsodium + v140 + + + + DebugDLL + Win32 + + + ReleaseDLL + Win32 + + + DebugDLL + x64 + + + ReleaseDLL + x64 + + + DebugLTCG + Win32 + + + ReleaseLTCG + Win32 + + + DebugLTCG + x64 + + + ReleaseLTCG + x64 + + + DebugLIB + Win32 + + + ReleaseLIB + Win32 + + + DebugLIB + x64 + + + ReleaseLIB + x64 + + + + StaticLibrary + DynamicLibrary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/src/libsodium/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters b/external/src/libsodium/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters new file mode 100644 index 0000000..f152794 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters @@ -0,0 +1,992 @@ + + + + + packaging + + + packaging + + + packaging + + + packaging + + + packaging + + + packaging + + + + + + + + crypto_generichash + + + crypto_generichash\blake2b + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_kx + + + crypto_sign + + + crypto_sign\ed25519 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_secretbox + + + crypto_secretbox + + + crypto_secretbox\xsalsa20poly1305 + + + crypto_secretbox\xchacha20poly1305 + + + crypto_pwhash + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256\nosse + + + crypto_pwhash\scryptsalsa208sha256\sse + + + crypto_verify\sodium + + + crypto_auth + + + crypto_auth\hmacsha512 + + + crypto_auth\hmacsha512256 + + + crypto_auth\hmacsha256 + + + crypto_kdf + + + crypto_kdf\blake2b + + + crypto_shorthash + + + crypto_shorthash\siphash24 + + + crypto_shorthash\siphash24 + + + crypto_shorthash\siphash24\ref + + + crypto_shorthash\siphash24\ref + + + crypto_scalarmult + + + crypto_scalarmult\ristretto255\ref10 + + + crypto_scalarmult\ed25519\ref10 + + + crypto_scalarmult\curve25519 + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\ref10 + + + crypto_onetimeauth + + + crypto_onetimeauth\poly1305 + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\sse2 + + + randombytes + + + randombytes\sysrandom + + + randombytes\internal + + + crypto_box + + + crypto_box + + + crypto_box + + + crypto_box\curve25519xsalsa20poly1305 + + + crypto_box\curve25519xchacha20poly1305 + + + crypto_box\curve25519xchacha20poly1305 + + + sodium + + + sodium + + + sodium + + + sodium + + + sodium + + + crypto_stream + + + crypto_stream\xchacha20 + + + crypto_stream\chacha20 + + + crypto_stream\chacha20\ref + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\salsa20 + + + crypto_stream\salsa20\ref + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6 + + + crypto_stream\salsa2012 + + + crypto_stream\salsa2012\ref + + + crypto_stream\salsa208 + + + crypto_stream\salsa208\ref + + + crypto_stream\xsalsa20 + + + crypto_hash + + + crypto_hash\sha512 + + + crypto_hash\sha512\cp + + + crypto_hash\sha256 + + + crypto_hash\sha256\cp + + + crypto_aead\xchacha20poly1305\sodium + + + crypto_aead\aes256gcm\aesni + + + crypto_aead\chacha20poly1305\sodium + + + crypto_secretstream\xchacha20poly1305 + + + crypto_core\salsa\ref + + + crypto_core\hchacha20 + + + crypto_core\hsalsa20 + + + crypto_core\hsalsa20\ref2 + + + crypto_core\ed25519 + + + crypto_core\ed25519 + + + crypto_core\ed25519\ref10 + + + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_sign\ed25519\ref10 + + + include + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_shorthash\siphash24\ref + + + crypto_scalarmult\curve25519 + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\ref10 + + + crypto_onetimeauth\poly1305 + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\sse2 + + + crypto_stream\chacha20 + + + crypto_stream\chacha20\ref + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\salsa20 + + + crypto_stream\salsa20\ref + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + + + {a6837e41-3751-38c9-bb90-dd59d5f4af7b} + + + {3e53394c-b59c-30cc-ae69-a4f46f9edfa3} + + + {7eb51140-a50f-3f50-b379-83677a82496c} + + + {1f4d6dd1-517f-3eeb-b974-2304ada5e67a} + + + {b145288f-68ad-3e79-93cb-e36537b20e26} + + + {3122f223-e6c2-3ab1-ad85-ca289b47419e} + + + {2720c2c8-c517-356e-83ed-c2997ab782c3} + + + {0a3af0f3-56f7-3551-a64e-6284feccc423} + + + {64e89b4f-eec9-38c9-90f2-4881bf5e84c0} + + + {0c0b4001-ae11-3d0f-8e73-75ac9b6e1ae8} + + + {f5065d74-beda-3e1e-819a-f606279c7fe9} + + + {f7aedb93-94a6-3ede-9374-ff41daca4841} + + + {0e7473c9-9c69-36b3-ab6c-d953647a15a6} + + + {d75db64c-eb08-3f10-9b99-1b6e6827f348} + + + {73194d5d-588a-342f-bee6-f28b4486f20b} + + + {7c5e6f81-e4ce-3018-a776-a1f125072d73} + + + {76990c08-d692-367f-b286-c728a8cad6bf} + + + {bf04f786-7862-3bde-aeba-ed82ee59ca22} + + + {98b6126a-3725-3707-a4cc-ff3af657cba0} + + + {8b704d11-af1f-30c0-9981-479da6d88dc3} + + + {342e684b-4e18-311c-953c-8391a544a04f} + + + {c6b8e28c-7c54-3af7-bee3-2948ba7b2082} + + + {4e9a1d6b-ee07-3bbc-ad78-6d0ba0e6d9d3} + + + {eb259fd9-56f0-32db-a903-6bc1549a7326} + + + {e53b6258-fcdd-34c8-96c5-44510a34a390} + + + {8bd3b558-2d08-3c3a-81ca-22677dde943b} + + + {16a8dd41-b0ab-39a7-80c8-3052d8b63811} + + + {d7ec3690-bae7-3653-8c53-66a3142cfcfa} + + + {722ef422-8c03-3008-ba2a-3a7e91c6647c} + + + {8c7d8b62-7b4f-3eb9-85b7-18e8d925be14} + + + {8fb6a906-dbd6-3746-9b0f-f49e7028daec} + + + {f2d6a22b-dd67-3561-90a4-88696169cb7b} + + + {aaf59186-1c0d-33cf-a34d-93e14bb87226} + + + {3d42d2a2-b192-33dd-9162-508916414707} + + + {898b6bd5-1360-3a34-adcd-0fade7561685} + + + {323c0a15-3c1d-39b2-9ec1-299deb299497} + + + {52c2080d-37c0-34c2-864a-c201c728e5d8} + + + {ff618a41-caeb-3a18-ad36-d34b049a8f50} + + + {ffc3712d-dfe0-3b51-8257-f5ffc9c9cea3} + + + {f54b65b6-71cf-3ab3-9c8c-f89c81846836} + + + {1bd97a78-befa-3805-8e9c-80d7c1aff37b} + + + {e785f104-1212-37bf-8511-cc518b9ace66} + + + {447b993f-59fb-3efd-8c59-a1712c97dfe8} + + + {cdb8d233-06b0-3872-a62b-c1ccf4cb4314} + + + {402a1c5a-d499-333a-a2fa-acd0e6a3c2b2} + + + {77f5a2e9-2ef1-3a72-b63c-88e8e4b92678} + + + {6c9c7c30-0808-3fad-8a88-944d7645e5d5} + + + {5d2fb1a2-f063-32db-a81a-41f79e36fd23} + + + {7bec6074-fbc7-330b-9e18-7dc3e868569a} + + + {834d4827-81e4-3de3-baa1-a216763f11d6} + + + {52bf28eb-7ffd-399a-be35-0df3e8e99c15} + + + {39cc576f-4b54-3d71-b14c-27445bc4b138} + + + {b9b02bee-5c1f-36d2-b97d-983f865a4cc6} + + + {41f1f35b-4639-3424-be85-7dfba02f3c5e} + + + {8bf11d29-2f5a-3f10-8ae6-82229d19c5b0} + + + {62f7ae38-4ce6-3976-acc3-47c462db4fbe} + + + {e07a28cd-775a-3798-bfdb-97842d3614d6} + + + {bb073c16-adc8-3cff-80b9-99cf5a28de6c} + + + {63de0ec8-ecde-35e3-8b97-6e9e4da342ee} + + + {29925210-53eb-342c-8527-7ebc173e668f} + + + {b2f989b6-87a6-3388-a35c-2d0d59cb4236} + + + {bc6466a1-57b0-3a35-9973-ad488a4bef8c} + + + {5599d9ab-b5b2-3310-b541-ae0fb70eecf1} + + + {eaedd08a-46f8-3d12-9e8d-bb3ee3ead5f6} + + + {806b6ff3-578b-308a-a359-0f5ed8472ecc} + + + {5a1d852e-67bb-3dc1-9ec5-99ef74b7faca} + + + {33e45d9c-e12a-3e76-9ef2-4f5510244a5b} + + + {048ba2a8-b22b-346c-9886-668b63c88c68} + + + {f08a312f-f8a3-350b-87ab-1f79d33e513f} + + + {c403f690-cd22-3ed4-9cc7-3f46e73081fd} + + + {c34d03f5-cf47-39fe-a5ad-5eb917006203} + + + {4da0c5ca-33d1-34e0-9689-12e69ae2dbd6} + + + {dd6b294c-5871-386c-92ec-aa46fcc411d4} + + + {07aca978-0547-329a-b70b-29aa579cacc5} + + + {f171fa05-35c4-32a0-b035-b5d6680ab714} + + + {ede2279c-1ba7-3d62-8345-733c6c1965e7} + + + {9c15151b-10dc-3dfe-b97b-a7d8c6b58920} + + + {49fb9272-ffe2-3993-b562-b19d5f2c9b40} + + + {80669cf5-3c9c-3c60-b409-9d8fb305bc77} + + + {96da72eb-3aa0-3850-83eb-32788f91e5bd} + + + {56bb40fc-d381-3a9e-925b-681774c48dde} + + + {fde88485-0fe6-3b22-9480-1d2b49fade53} + + + {ef090484-4db4-3dc2-aca7-c59bab1db23b} + + + {14c126fd-bb91-37ea-b807-b60c386be601} + + + {ac56c38f-7e17-3b79-bf47-58e9476b3b89} + + + {5dfc520b-f690-3d5f-a86a-8b667f2e7490} + + + diff --git a/external/src/libsodium/builds/msvc/vs2015/libsodium/libsodium.xml b/external/src/libsodium/builds/msvc/vs2015/libsodium/libsodium.xml new file mode 100644 index 0000000..808ccb9 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2015/libsodium/libsodium.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2017/libsodium.import.props b/external/src/libsodium/builds/msvc/vs2017/libsodium.import.props new file mode 100644 index 0000000..b3d7e4f --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2017/libsodium.import.props @@ -0,0 +1,52 @@ + + + + + <_PropertySheetDisplayName>Libsodium Import Settings + + + + + + + + + + + + + $(ProjectDir)..\..\..\..\..\libsodium\src\libsodium\include;$(ProjectDir)..\..\..\..\..\libsodium\src\libsodium\include\sodium\;%(AdditionalIncludeDirectories) + SODIUM_STATIC;%(PreprocessorDefinitions) + + + advapi32.lib;libsodium.lib;%(AdditionalDependencies) + $(ProjectDir)..\..\..\..\..\libsodium\bin\$(PlatformName)\Debug\$(PlatformToolset)\$(Linkage-libsodium)\;%(AdditionalLibraryDirectories) + $(ProjectDir)..\..\..\..\..\libsodium\bin\$(PlatformName)\Release\$(PlatformToolset)\$(Linkage-libsodium)\;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2017/libsodium.import.xml b/external/src/libsodium/builds/msvc/vs2017/libsodium.import.xml new file mode 100644 index 0000000..dbcf4e5 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2017/libsodium.import.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2017/libsodium.sln b/external/src/libsodium/builds/msvc/vs2017/libsodium.sln new file mode 100644 index 0000000..bdc9a7c --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2017/libsodium.sln @@ -0,0 +1,52 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.4 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsodium", "libsodium\libsodium.vcxproj", "{A185B162-6CB6-4502-B03F-B56F7699A8D9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + DynDebug|Win32 = DynDebug|Win32 + DynDebug|x64 = DynDebug|x64 + DynRelease|Win32 = DynRelease|Win32 + DynRelease|x64 = DynRelease|x64 + LtcgDebug|Win32 = LtcgDebug|Win32 + LtcgDebug|x64 = LtcgDebug|x64 + LtcgRelease|Win32 = LtcgRelease|Win32 + LtcgRelease|x64 = LtcgRelease|x64 + StaticDebug|Win32 = StaticDebug|Win32 + StaticDebug|x64 = StaticDebug|x64 + StaticRelease|Win32 = StaticRelease|Win32 + StaticRelease|x64 = StaticRelease|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|Win32.ActiveCfg = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|Win32.Build.0 = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|x64.ActiveCfg = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|x64.Build.0 = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|Win32.ActiveCfg = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|Win32.Build.0 = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|x64.ActiveCfg = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|x64.Build.0 = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|Win32.ActiveCfg = DebugLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|Win32.Build.0 = DebugLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|x64.ActiveCfg = DebugLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|x64.Build.0 = DebugLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|Win32.ActiveCfg = ReleaseLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|Win32.Build.0 = ReleaseLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|x64.ActiveCfg = ReleaseLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|x64.Build.0 = ReleaseLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|Win32.ActiveCfg = DebugLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|Win32.Build.0 = DebugLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|x64.ActiveCfg = DebugLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|x64.Build.0 = DebugLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|Win32.ActiveCfg = ReleaseLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|Win32.Build.0 = ReleaseLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|x64.ActiveCfg = ReleaseLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|x64.Build.0 = ReleaseLIB|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/external/src/libsodium/builds/msvc/vs2017/libsodium/libsodium.props b/external/src/libsodium/builds/msvc/vs2017/libsodium/libsodium.props new file mode 100644 index 0000000..5a23903 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2017/libsodium/libsodium.props @@ -0,0 +1,48 @@ + + + + + <_PropertySheetDisplayName>Libsodium Common Settings + AllRules.ruleset + false + + + + + + + + + + + + + copy "$(BuildRoot)version.h" "$(RepoRoot)src\libsodium\include\sodium\" + + + $(RepoRoot)src\libsodium\include;$(RepoRoot)src\libsodium\include\sodium\;%(AdditionalIncludeDirectories) + 4146;4244;%(DisableSpecificWarnings) + false + inline=__inline;NATIVE_LITTLE_ENDIAN;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + SODIUM_STATIC;%(PreprocessorDefinitions) + SODIUM_DLL_EXPORT;%(PreprocessorDefinitions) + HAVE_AMD64_ASM;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + advapi32.lib + + + diff --git a/external/src/libsodium/builds/msvc/vs2017/libsodium/libsodium.vcxproj b/external/src/libsodium/builds/msvc/vs2017/libsodium/libsodium.vcxproj new file mode 100644 index 0000000..de3871e --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2017/libsodium/libsodium.vcxproj @@ -0,0 +1,325 @@ + + + + {A185B162-6CB6-4502-B03F-B56F7699A8D9} + libsodium + v141 + + + + DebugDLL + Win32 + + + ReleaseDLL + Win32 + + + DebugDLL + x64 + + + ReleaseDLL + x64 + + + DebugLTCG + Win32 + + + ReleaseLTCG + Win32 + + + DebugLTCG + x64 + + + ReleaseLTCG + x64 + + + DebugLIB + Win32 + + + ReleaseLIB + Win32 + + + DebugLIB + x64 + + + ReleaseLIB + x64 + + + + StaticLibrary + DynamicLibrary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/src/libsodium/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters b/external/src/libsodium/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters new file mode 100644 index 0000000..f152794 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters @@ -0,0 +1,992 @@ + + + + + packaging + + + packaging + + + packaging + + + packaging + + + packaging + + + packaging + + + + + + + + crypto_generichash + + + crypto_generichash\blake2b + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_kx + + + crypto_sign + + + crypto_sign\ed25519 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_secretbox + + + crypto_secretbox + + + crypto_secretbox\xsalsa20poly1305 + + + crypto_secretbox\xchacha20poly1305 + + + crypto_pwhash + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256\nosse + + + crypto_pwhash\scryptsalsa208sha256\sse + + + crypto_verify\sodium + + + crypto_auth + + + crypto_auth\hmacsha512 + + + crypto_auth\hmacsha512256 + + + crypto_auth\hmacsha256 + + + crypto_kdf + + + crypto_kdf\blake2b + + + crypto_shorthash + + + crypto_shorthash\siphash24 + + + crypto_shorthash\siphash24 + + + crypto_shorthash\siphash24\ref + + + crypto_shorthash\siphash24\ref + + + crypto_scalarmult + + + crypto_scalarmult\ristretto255\ref10 + + + crypto_scalarmult\ed25519\ref10 + + + crypto_scalarmult\curve25519 + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\ref10 + + + crypto_onetimeauth + + + crypto_onetimeauth\poly1305 + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\sse2 + + + randombytes + + + randombytes\sysrandom + + + randombytes\internal + + + crypto_box + + + crypto_box + + + crypto_box + + + crypto_box\curve25519xsalsa20poly1305 + + + crypto_box\curve25519xchacha20poly1305 + + + crypto_box\curve25519xchacha20poly1305 + + + sodium + + + sodium + + + sodium + + + sodium + + + sodium + + + crypto_stream + + + crypto_stream\xchacha20 + + + crypto_stream\chacha20 + + + crypto_stream\chacha20\ref + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\salsa20 + + + crypto_stream\salsa20\ref + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6 + + + crypto_stream\salsa2012 + + + crypto_stream\salsa2012\ref + + + crypto_stream\salsa208 + + + crypto_stream\salsa208\ref + + + crypto_stream\xsalsa20 + + + crypto_hash + + + crypto_hash\sha512 + + + crypto_hash\sha512\cp + + + crypto_hash\sha256 + + + crypto_hash\sha256\cp + + + crypto_aead\xchacha20poly1305\sodium + + + crypto_aead\aes256gcm\aesni + + + crypto_aead\chacha20poly1305\sodium + + + crypto_secretstream\xchacha20poly1305 + + + crypto_core\salsa\ref + + + crypto_core\hchacha20 + + + crypto_core\hsalsa20 + + + crypto_core\hsalsa20\ref2 + + + crypto_core\ed25519 + + + crypto_core\ed25519 + + + crypto_core\ed25519\ref10 + + + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_sign\ed25519\ref10 + + + include + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_shorthash\siphash24\ref + + + crypto_scalarmult\curve25519 + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\ref10 + + + crypto_onetimeauth\poly1305 + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\sse2 + + + crypto_stream\chacha20 + + + crypto_stream\chacha20\ref + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\salsa20 + + + crypto_stream\salsa20\ref + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + + + {a6837e41-3751-38c9-bb90-dd59d5f4af7b} + + + {3e53394c-b59c-30cc-ae69-a4f46f9edfa3} + + + {7eb51140-a50f-3f50-b379-83677a82496c} + + + {1f4d6dd1-517f-3eeb-b974-2304ada5e67a} + + + {b145288f-68ad-3e79-93cb-e36537b20e26} + + + {3122f223-e6c2-3ab1-ad85-ca289b47419e} + + + {2720c2c8-c517-356e-83ed-c2997ab782c3} + + + {0a3af0f3-56f7-3551-a64e-6284feccc423} + + + {64e89b4f-eec9-38c9-90f2-4881bf5e84c0} + + + {0c0b4001-ae11-3d0f-8e73-75ac9b6e1ae8} + + + {f5065d74-beda-3e1e-819a-f606279c7fe9} + + + {f7aedb93-94a6-3ede-9374-ff41daca4841} + + + {0e7473c9-9c69-36b3-ab6c-d953647a15a6} + + + {d75db64c-eb08-3f10-9b99-1b6e6827f348} + + + {73194d5d-588a-342f-bee6-f28b4486f20b} + + + {7c5e6f81-e4ce-3018-a776-a1f125072d73} + + + {76990c08-d692-367f-b286-c728a8cad6bf} + + + {bf04f786-7862-3bde-aeba-ed82ee59ca22} + + + {98b6126a-3725-3707-a4cc-ff3af657cba0} + + + {8b704d11-af1f-30c0-9981-479da6d88dc3} + + + {342e684b-4e18-311c-953c-8391a544a04f} + + + {c6b8e28c-7c54-3af7-bee3-2948ba7b2082} + + + {4e9a1d6b-ee07-3bbc-ad78-6d0ba0e6d9d3} + + + {eb259fd9-56f0-32db-a903-6bc1549a7326} + + + {e53b6258-fcdd-34c8-96c5-44510a34a390} + + + {8bd3b558-2d08-3c3a-81ca-22677dde943b} + + + {16a8dd41-b0ab-39a7-80c8-3052d8b63811} + + + {d7ec3690-bae7-3653-8c53-66a3142cfcfa} + + + {722ef422-8c03-3008-ba2a-3a7e91c6647c} + + + {8c7d8b62-7b4f-3eb9-85b7-18e8d925be14} + + + {8fb6a906-dbd6-3746-9b0f-f49e7028daec} + + + {f2d6a22b-dd67-3561-90a4-88696169cb7b} + + + {aaf59186-1c0d-33cf-a34d-93e14bb87226} + + + {3d42d2a2-b192-33dd-9162-508916414707} + + + {898b6bd5-1360-3a34-adcd-0fade7561685} + + + {323c0a15-3c1d-39b2-9ec1-299deb299497} + + + {52c2080d-37c0-34c2-864a-c201c728e5d8} + + + {ff618a41-caeb-3a18-ad36-d34b049a8f50} + + + {ffc3712d-dfe0-3b51-8257-f5ffc9c9cea3} + + + {f54b65b6-71cf-3ab3-9c8c-f89c81846836} + + + {1bd97a78-befa-3805-8e9c-80d7c1aff37b} + + + {e785f104-1212-37bf-8511-cc518b9ace66} + + + {447b993f-59fb-3efd-8c59-a1712c97dfe8} + + + {cdb8d233-06b0-3872-a62b-c1ccf4cb4314} + + + {402a1c5a-d499-333a-a2fa-acd0e6a3c2b2} + + + {77f5a2e9-2ef1-3a72-b63c-88e8e4b92678} + + + {6c9c7c30-0808-3fad-8a88-944d7645e5d5} + + + {5d2fb1a2-f063-32db-a81a-41f79e36fd23} + + + {7bec6074-fbc7-330b-9e18-7dc3e868569a} + + + {834d4827-81e4-3de3-baa1-a216763f11d6} + + + {52bf28eb-7ffd-399a-be35-0df3e8e99c15} + + + {39cc576f-4b54-3d71-b14c-27445bc4b138} + + + {b9b02bee-5c1f-36d2-b97d-983f865a4cc6} + + + {41f1f35b-4639-3424-be85-7dfba02f3c5e} + + + {8bf11d29-2f5a-3f10-8ae6-82229d19c5b0} + + + {62f7ae38-4ce6-3976-acc3-47c462db4fbe} + + + {e07a28cd-775a-3798-bfdb-97842d3614d6} + + + {bb073c16-adc8-3cff-80b9-99cf5a28de6c} + + + {63de0ec8-ecde-35e3-8b97-6e9e4da342ee} + + + {29925210-53eb-342c-8527-7ebc173e668f} + + + {b2f989b6-87a6-3388-a35c-2d0d59cb4236} + + + {bc6466a1-57b0-3a35-9973-ad488a4bef8c} + + + {5599d9ab-b5b2-3310-b541-ae0fb70eecf1} + + + {eaedd08a-46f8-3d12-9e8d-bb3ee3ead5f6} + + + {806b6ff3-578b-308a-a359-0f5ed8472ecc} + + + {5a1d852e-67bb-3dc1-9ec5-99ef74b7faca} + + + {33e45d9c-e12a-3e76-9ef2-4f5510244a5b} + + + {048ba2a8-b22b-346c-9886-668b63c88c68} + + + {f08a312f-f8a3-350b-87ab-1f79d33e513f} + + + {c403f690-cd22-3ed4-9cc7-3f46e73081fd} + + + {c34d03f5-cf47-39fe-a5ad-5eb917006203} + + + {4da0c5ca-33d1-34e0-9689-12e69ae2dbd6} + + + {dd6b294c-5871-386c-92ec-aa46fcc411d4} + + + {07aca978-0547-329a-b70b-29aa579cacc5} + + + {f171fa05-35c4-32a0-b035-b5d6680ab714} + + + {ede2279c-1ba7-3d62-8345-733c6c1965e7} + + + {9c15151b-10dc-3dfe-b97b-a7d8c6b58920} + + + {49fb9272-ffe2-3993-b562-b19d5f2c9b40} + + + {80669cf5-3c9c-3c60-b409-9d8fb305bc77} + + + {96da72eb-3aa0-3850-83eb-32788f91e5bd} + + + {56bb40fc-d381-3a9e-925b-681774c48dde} + + + {fde88485-0fe6-3b22-9480-1d2b49fade53} + + + {ef090484-4db4-3dc2-aca7-c59bab1db23b} + + + {14c126fd-bb91-37ea-b807-b60c386be601} + + + {ac56c38f-7e17-3b79-bf47-58e9476b3b89} + + + {5dfc520b-f690-3d5f-a86a-8b667f2e7490} + + + diff --git a/external/src/libsodium/builds/msvc/vs2017/libsodium/libsodium.xml b/external/src/libsodium/builds/msvc/vs2017/libsodium/libsodium.xml new file mode 100644 index 0000000..808ccb9 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2017/libsodium/libsodium.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2019/libsodium.import.props b/external/src/libsodium/builds/msvc/vs2019/libsodium.import.props new file mode 100644 index 0000000..b3d7e4f --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2019/libsodium.import.props @@ -0,0 +1,52 @@ + + + + + <_PropertySheetDisplayName>Libsodium Import Settings + + + + + + + + + + + + + $(ProjectDir)..\..\..\..\..\libsodium\src\libsodium\include;$(ProjectDir)..\..\..\..\..\libsodium\src\libsodium\include\sodium\;%(AdditionalIncludeDirectories) + SODIUM_STATIC;%(PreprocessorDefinitions) + + + advapi32.lib;libsodium.lib;%(AdditionalDependencies) + $(ProjectDir)..\..\..\..\..\libsodium\bin\$(PlatformName)\Debug\$(PlatformToolset)\$(Linkage-libsodium)\;%(AdditionalLibraryDirectories) + $(ProjectDir)..\..\..\..\..\libsodium\bin\$(PlatformName)\Release\$(PlatformToolset)\$(Linkage-libsodium)\;%(AdditionalLibraryDirectories) + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2019/libsodium.import.xml b/external/src/libsodium/builds/msvc/vs2019/libsodium.import.xml new file mode 100644 index 0000000..dbcf4e5 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2019/libsodium.import.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/builds/msvc/vs2019/libsodium.sln b/external/src/libsodium/builds/msvc/vs2019/libsodium.sln new file mode 100644 index 0000000..bdc9a7c --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2019/libsodium.sln @@ -0,0 +1,52 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26228.4 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsodium", "libsodium\libsodium.vcxproj", "{A185B162-6CB6-4502-B03F-B56F7699A8D9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + DynDebug|Win32 = DynDebug|Win32 + DynDebug|x64 = DynDebug|x64 + DynRelease|Win32 = DynRelease|Win32 + DynRelease|x64 = DynRelease|x64 + LtcgDebug|Win32 = LtcgDebug|Win32 + LtcgDebug|x64 = LtcgDebug|x64 + LtcgRelease|Win32 = LtcgRelease|Win32 + LtcgRelease|x64 = LtcgRelease|x64 + StaticDebug|Win32 = StaticDebug|Win32 + StaticDebug|x64 = StaticDebug|x64 + StaticRelease|Win32 = StaticRelease|Win32 + StaticRelease|x64 = StaticRelease|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|Win32.ActiveCfg = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|Win32.Build.0 = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|x64.ActiveCfg = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynDebug|x64.Build.0 = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|Win32.ActiveCfg = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|Win32.Build.0 = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|x64.ActiveCfg = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DynRelease|x64.Build.0 = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|Win32.ActiveCfg = DebugLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|Win32.Build.0 = DebugLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|x64.ActiveCfg = DebugLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgDebug|x64.Build.0 = DebugLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|Win32.ActiveCfg = ReleaseLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|Win32.Build.0 = ReleaseLTCG|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|x64.ActiveCfg = ReleaseLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.LtcgRelease|x64.Build.0 = ReleaseLTCG|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|Win32.ActiveCfg = DebugLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|Win32.Build.0 = DebugLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|x64.ActiveCfg = DebugLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticDebug|x64.Build.0 = DebugLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|Win32.ActiveCfg = ReleaseLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|Win32.Build.0 = ReleaseLIB|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|x64.ActiveCfg = ReleaseLIB|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.StaticRelease|x64.Build.0 = ReleaseLIB|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/external/src/libsodium/builds/msvc/vs2019/libsodium/libsodium.props b/external/src/libsodium/builds/msvc/vs2019/libsodium/libsodium.props new file mode 100644 index 0000000..5a23903 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2019/libsodium/libsodium.props @@ -0,0 +1,48 @@ + + + + + <_PropertySheetDisplayName>Libsodium Common Settings + AllRules.ruleset + false + + + + + + + + + + + + + copy "$(BuildRoot)version.h" "$(RepoRoot)src\libsodium\include\sodium\" + + + $(RepoRoot)src\libsodium\include;$(RepoRoot)src\libsodium\include\sodium\;%(AdditionalIncludeDirectories) + 4146;4244;%(DisableSpecificWarnings) + false + inline=__inline;NATIVE_LITTLE_ENDIAN;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + SODIUM_STATIC;%(PreprocessorDefinitions) + SODIUM_DLL_EXPORT;%(PreprocessorDefinitions) + HAVE_AMD64_ASM;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + + advapi32.lib + + + diff --git a/external/src/libsodium/builds/msvc/vs2019/libsodium/libsodium.vcxproj b/external/src/libsodium/builds/msvc/vs2019/libsodium/libsodium.vcxproj new file mode 100644 index 0000000..c3b46f4 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2019/libsodium/libsodium.vcxproj @@ -0,0 +1,325 @@ + + + + {A185B162-6CB6-4502-B03F-B56F7699A8D9} + libsodium + v142 + + + + DebugDLL + Win32 + + + ReleaseDLL + Win32 + + + DebugDLL + x64 + + + ReleaseDLL + x64 + + + DebugLTCG + Win32 + + + ReleaseLTCG + Win32 + + + DebugLTCG + x64 + + + ReleaseLTCG + x64 + + + DebugLIB + Win32 + + + ReleaseLIB + Win32 + + + DebugLIB + x64 + + + ReleaseLIB + x64 + + + + StaticLibrary + DynamicLibrary + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/src/libsodium/builds/msvc/vs2019/libsodium/libsodium.vcxproj.filters b/external/src/libsodium/builds/msvc/vs2019/libsodium/libsodium.vcxproj.filters new file mode 100644 index 0000000..f152794 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2019/libsodium/libsodium.vcxproj.filters @@ -0,0 +1,992 @@ + + + + + packaging + + + packaging + + + packaging + + + packaging + + + packaging + + + packaging + + + + + + + + crypto_generichash + + + crypto_generichash\blake2b + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_kx + + + crypto_sign + + + crypto_sign\ed25519 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_sign\ed25519\ref10 + + + crypto_secretbox + + + crypto_secretbox + + + crypto_secretbox\xsalsa20poly1305 + + + crypto_secretbox\xchacha20poly1305 + + + crypto_pwhash + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256\nosse + + + crypto_pwhash\scryptsalsa208sha256\sse + + + crypto_verify\sodium + + + crypto_auth + + + crypto_auth\hmacsha512 + + + crypto_auth\hmacsha512256 + + + crypto_auth\hmacsha256 + + + crypto_kdf + + + crypto_kdf\blake2b + + + crypto_shorthash + + + crypto_shorthash\siphash24 + + + crypto_shorthash\siphash24 + + + crypto_shorthash\siphash24\ref + + + crypto_shorthash\siphash24\ref + + + crypto_scalarmult + + + crypto_scalarmult\ristretto255\ref10 + + + crypto_scalarmult\ed25519\ref10 + + + crypto_scalarmult\curve25519 + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\ref10 + + + crypto_onetimeauth + + + crypto_onetimeauth\poly1305 + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\sse2 + + + randombytes + + + randombytes\sysrandom + + + randombytes\internal + + + crypto_box + + + crypto_box + + + crypto_box + + + crypto_box\curve25519xsalsa20poly1305 + + + crypto_box\curve25519xchacha20poly1305 + + + crypto_box\curve25519xchacha20poly1305 + + + sodium + + + sodium + + + sodium + + + sodium + + + sodium + + + crypto_stream + + + crypto_stream\xchacha20 + + + crypto_stream\chacha20 + + + crypto_stream\chacha20\ref + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\salsa20 + + + crypto_stream\salsa20\ref + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6 + + + crypto_stream\salsa2012 + + + crypto_stream\salsa2012\ref + + + crypto_stream\salsa208 + + + crypto_stream\salsa208\ref + + + crypto_stream\xsalsa20 + + + crypto_hash + + + crypto_hash\sha512 + + + crypto_hash\sha512\cp + + + crypto_hash\sha256 + + + crypto_hash\sha256\cp + + + crypto_aead\xchacha20poly1305\sodium + + + crypto_aead\aes256gcm\aesni + + + crypto_aead\chacha20poly1305\sodium + + + crypto_secretstream\xchacha20poly1305 + + + crypto_core\salsa\ref + + + crypto_core\hchacha20 + + + crypto_core\hsalsa20 + + + crypto_core\hsalsa20\ref2 + + + crypto_core\ed25519 + + + crypto_core\ed25519 + + + crypto_core\ed25519\ref10 + + + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_generichash\blake2b\ref + + + crypto_sign\ed25519\ref10 + + + include + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + include\sodium\private + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\argon2 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_pwhash\scryptsalsa208sha256 + + + crypto_shorthash\siphash24\ref + + + crypto_scalarmult\curve25519 + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\sandy2x + + + crypto_scalarmult\curve25519\ref10 + + + crypto_onetimeauth\poly1305 + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\donna + + + crypto_onetimeauth\poly1305\sse2 + + + crypto_stream\chacha20 + + + crypto_stream\chacha20\ref + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\chacha20\dolbeau + + + crypto_stream\salsa20 + + + crypto_stream\salsa20\ref + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6int + + + crypto_stream\salsa20\xmm6 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_25_5 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + crypto_core\ed25519\ref10\fe_51 + + + + + {a6837e41-3751-38c9-bb90-dd59d5f4af7b} + + + {3e53394c-b59c-30cc-ae69-a4f46f9edfa3} + + + {7eb51140-a50f-3f50-b379-83677a82496c} + + + {1f4d6dd1-517f-3eeb-b974-2304ada5e67a} + + + {b145288f-68ad-3e79-93cb-e36537b20e26} + + + {3122f223-e6c2-3ab1-ad85-ca289b47419e} + + + {2720c2c8-c517-356e-83ed-c2997ab782c3} + + + {0a3af0f3-56f7-3551-a64e-6284feccc423} + + + {64e89b4f-eec9-38c9-90f2-4881bf5e84c0} + + + {0c0b4001-ae11-3d0f-8e73-75ac9b6e1ae8} + + + {f5065d74-beda-3e1e-819a-f606279c7fe9} + + + {f7aedb93-94a6-3ede-9374-ff41daca4841} + + + {0e7473c9-9c69-36b3-ab6c-d953647a15a6} + + + {d75db64c-eb08-3f10-9b99-1b6e6827f348} + + + {73194d5d-588a-342f-bee6-f28b4486f20b} + + + {7c5e6f81-e4ce-3018-a776-a1f125072d73} + + + {76990c08-d692-367f-b286-c728a8cad6bf} + + + {bf04f786-7862-3bde-aeba-ed82ee59ca22} + + + {98b6126a-3725-3707-a4cc-ff3af657cba0} + + + {8b704d11-af1f-30c0-9981-479da6d88dc3} + + + {342e684b-4e18-311c-953c-8391a544a04f} + + + {c6b8e28c-7c54-3af7-bee3-2948ba7b2082} + + + {4e9a1d6b-ee07-3bbc-ad78-6d0ba0e6d9d3} + + + {eb259fd9-56f0-32db-a903-6bc1549a7326} + + + {e53b6258-fcdd-34c8-96c5-44510a34a390} + + + {8bd3b558-2d08-3c3a-81ca-22677dde943b} + + + {16a8dd41-b0ab-39a7-80c8-3052d8b63811} + + + {d7ec3690-bae7-3653-8c53-66a3142cfcfa} + + + {722ef422-8c03-3008-ba2a-3a7e91c6647c} + + + {8c7d8b62-7b4f-3eb9-85b7-18e8d925be14} + + + {8fb6a906-dbd6-3746-9b0f-f49e7028daec} + + + {f2d6a22b-dd67-3561-90a4-88696169cb7b} + + + {aaf59186-1c0d-33cf-a34d-93e14bb87226} + + + {3d42d2a2-b192-33dd-9162-508916414707} + + + {898b6bd5-1360-3a34-adcd-0fade7561685} + + + {323c0a15-3c1d-39b2-9ec1-299deb299497} + + + {52c2080d-37c0-34c2-864a-c201c728e5d8} + + + {ff618a41-caeb-3a18-ad36-d34b049a8f50} + + + {ffc3712d-dfe0-3b51-8257-f5ffc9c9cea3} + + + {f54b65b6-71cf-3ab3-9c8c-f89c81846836} + + + {1bd97a78-befa-3805-8e9c-80d7c1aff37b} + + + {e785f104-1212-37bf-8511-cc518b9ace66} + + + {447b993f-59fb-3efd-8c59-a1712c97dfe8} + + + {cdb8d233-06b0-3872-a62b-c1ccf4cb4314} + + + {402a1c5a-d499-333a-a2fa-acd0e6a3c2b2} + + + {77f5a2e9-2ef1-3a72-b63c-88e8e4b92678} + + + {6c9c7c30-0808-3fad-8a88-944d7645e5d5} + + + {5d2fb1a2-f063-32db-a81a-41f79e36fd23} + + + {7bec6074-fbc7-330b-9e18-7dc3e868569a} + + + {834d4827-81e4-3de3-baa1-a216763f11d6} + + + {52bf28eb-7ffd-399a-be35-0df3e8e99c15} + + + {39cc576f-4b54-3d71-b14c-27445bc4b138} + + + {b9b02bee-5c1f-36d2-b97d-983f865a4cc6} + + + {41f1f35b-4639-3424-be85-7dfba02f3c5e} + + + {8bf11d29-2f5a-3f10-8ae6-82229d19c5b0} + + + {62f7ae38-4ce6-3976-acc3-47c462db4fbe} + + + {e07a28cd-775a-3798-bfdb-97842d3614d6} + + + {bb073c16-adc8-3cff-80b9-99cf5a28de6c} + + + {63de0ec8-ecde-35e3-8b97-6e9e4da342ee} + + + {29925210-53eb-342c-8527-7ebc173e668f} + + + {b2f989b6-87a6-3388-a35c-2d0d59cb4236} + + + {bc6466a1-57b0-3a35-9973-ad488a4bef8c} + + + {5599d9ab-b5b2-3310-b541-ae0fb70eecf1} + + + {eaedd08a-46f8-3d12-9e8d-bb3ee3ead5f6} + + + {806b6ff3-578b-308a-a359-0f5ed8472ecc} + + + {5a1d852e-67bb-3dc1-9ec5-99ef74b7faca} + + + {33e45d9c-e12a-3e76-9ef2-4f5510244a5b} + + + {048ba2a8-b22b-346c-9886-668b63c88c68} + + + {f08a312f-f8a3-350b-87ab-1f79d33e513f} + + + {c403f690-cd22-3ed4-9cc7-3f46e73081fd} + + + {c34d03f5-cf47-39fe-a5ad-5eb917006203} + + + {4da0c5ca-33d1-34e0-9689-12e69ae2dbd6} + + + {dd6b294c-5871-386c-92ec-aa46fcc411d4} + + + {07aca978-0547-329a-b70b-29aa579cacc5} + + + {f171fa05-35c4-32a0-b035-b5d6680ab714} + + + {ede2279c-1ba7-3d62-8345-733c6c1965e7} + + + {9c15151b-10dc-3dfe-b97b-a7d8c6b58920} + + + {49fb9272-ffe2-3993-b562-b19d5f2c9b40} + + + {80669cf5-3c9c-3c60-b409-9d8fb305bc77} + + + {96da72eb-3aa0-3850-83eb-32788f91e5bd} + + + {56bb40fc-d381-3a9e-925b-681774c48dde} + + + {fde88485-0fe6-3b22-9480-1d2b49fade53} + + + {ef090484-4db4-3dc2-aca7-c59bab1db23b} + + + {14c126fd-bb91-37ea-b807-b60c386be601} + + + {ac56c38f-7e17-3b79-bf47-58e9476b3b89} + + + {5dfc520b-f690-3d5f-a86a-8b667f2e7490} + + + diff --git a/external/src/libsodium/builds/msvc/vs2019/libsodium/libsodium.xml b/external/src/libsodium/builds/msvc/vs2019/libsodium/libsodium.xml new file mode 100644 index 0000000..808ccb9 --- /dev/null +++ b/external/src/libsodium/builds/msvc/vs2019/libsodium/libsodium.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/external/src/libsodium/configure.ac b/external/src/libsodium/configure.ac new file mode 100644 index 0000000..b20e511 --- /dev/null +++ b/external/src/libsodium/configure.ac @@ -0,0 +1,917 @@ +AC_PREREQ([2.69]) +AC_INIT([libsodium],[1.0.18],[https://github.com/jedisct1/libsodium/issues],[libsodium],[https://libsodium.org]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_SRCDIR([src/libsodium/sodium/version.c]) +AC_CANONICAL_HOST +AC_CANONICAL_TARGET +AM_INIT_AUTOMAKE([1.11 dist-bzip2 tar-ustar foreign subdir-objects]) +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +AM_MAINTAINER_MODE +AM_DEP_TRACK + +AC_SUBST(VERSION) + +SODIUM_LIBRARY_VERSION_MAJOR=10 +SODIUM_LIBRARY_VERSION_MINOR=3 +DLL_VERSION=24 +SODIUM_LIBRARY_VERSION=26:0:3 +# | | | +# +------+ | +---+ +# | | | +# current:revision:age +# | | | +# | | +- increment if interfaces have been added +# | | set to zero if interfaces have been removed +# | | or changed +# | +- increment if source code has changed +# | set to zero if current is incremented +# +- increment if interfaces have been added, removed or changed +AC_SUBST(SODIUM_LIBRARY_VERSION_MAJOR) +AC_SUBST(SODIUM_LIBRARY_VERSION_MINOR) +AC_SUBST(SODIUM_LIBRARY_VERSION) +AC_SUBST(DLL_VERSION) + +AC_LANG_ASSERT(C) +LX_CFLAGS=${CFLAGS-NONE} +PKGCONFIG_LIBS_PRIVATE="" + +dnl Path check + +AS_IF([pwd | fgrep ' ' > /dev/null 2>&1], + [AC_MSG_ERROR([The build directory contains whitespaces - This can cause tests/installation to fail due to limitations of some libtool versions])] +) + +AC_PROG_CC +AM_PROG_AS +AC_USE_SYSTEM_EXTENSIONS + +dnl Switches + +AC_ARG_ENABLE(ssp, +[AS_HELP_STRING(--disable-ssp,Do not compile with -fstack-protector)], +[ + AS_IF([test "x$enableval" = "xno"], [ + enable_ssp="no" + ], [ + enable_ssp="yes" + ]) +], +[ + enable_ssp="yes" +]) + +AC_ARG_ENABLE(asm, +[AS_HELP_STRING(--disable-asm,[Do not compile assembly code -- As a side effect, this disables CPU-specific implementations on non-Windows platforms. Only for use with targets such as WebAssembly.])], +[ + AS_IF([test "x$enableval" = "xno"], [ + enable_asm="no" + ], [ + enable_asm="yes" + ]) +], +[ + enable_asm="yes" +]) + +AS_IF([test "x$EMSCRIPTEN" != "x"], [ + AX_CHECK_COMPILE_FLAG([-s ASSERTIONS=0], [ + enable_asm="no" + AC_MSG_WARN([compiling to JavaScript - asm implementations disabled]) + ], [ + AC_MSG_WARN([EMSCRIPTEN environment variable defined, but emcc doesn't appear to be used - Assuming compilation to native code]) + CFLAGS="$CFLAGS -U__EMSCRIPTEN__" + unset EMSCRIPTEN + ]) +]) + +AC_ARG_ENABLE(pie, +[AS_HELP_STRING(--disable-pie,Do not produce position independent executables)], + enable_pie=$enableval, enable_pie="maybe") + +AS_CASE([$host_os], [mingw*|cygwin*|msys|eabi*], [enable_pie="no"]) + +AC_ARG_ENABLE(blocking-random, +[AS_HELP_STRING(--enable-blocking-random,Enable this switch only if /dev/urandom is totally broken on the target platform)], +[ + AS_IF([test "x$enableval" = "xyes"], [ + AC_DEFINE([USE_BLOCKING_RANDOM], [1], [/dev/urandom is insecure on the target platform]) + ]) +]) + +AC_ARG_ENABLE(minimal, +[AS_HELP_STRING(--enable-minimal, + [Only compile the minimum set of functions required for the high-level API])], +[ + AS_IF([test "x$enableval" = "xyes"], [ + enable_minimal="yes" + SODIUM_LIBRARY_MINIMAL_DEF="#define SODIUM_LIBRARY_MINIMAL 1" + AC_DEFINE([MINIMAL], [1], [Define for a minimal build, without deprecated functions and functions that high-level APIs depend on]) + ], [ + enable_minimal="no" + ]) +], +[ + enable_minimal="no" +]) +AM_CONDITIONAL([MINIMAL], [test x$enable_minimal = xyes]) +AC_SUBST(SODIUM_LIBRARY_MINIMAL_DEF) + +AC_ARG_WITH(pthreads, AS_HELP_STRING([--with-pthreads], + [use pthreads library, or --without-pthreads to disable threading support.]), + [ ], [withval="yes"]) + +AS_IF([test "x$withval" = "xyes"], [ + AX_PTHREAD([ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + ]], [[ + pthread_mutex_t mutex; + + pthread_mutex_lock(&mutex); + pthread_mutex_unlock(&mutex) + ]] + )], [ + AC_DEFINE([HAVE_PTHREAD], [1], [Define if you have POSIX threads libraries and header files]) + with_threads="yes" + LIBS="$PTHREAD_LIBS $LIBS" + PKGCONFIG_LIBS_PRIVATE="$PTHREAD_LIBS $PTHREAD_CFLAGS $PKGCONFIG_LIBS_PRIVATE" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + CC="$PTHREAD_CC" + ]) + ], + [ AC_MSG_NOTICE(pthread mutexes are not available) ] + ) +], [with_threads="no"]) + +AC_ARG_WITH(safecode, +[AS_HELP_STRING(--with-safecode,For maintainers only - please do not use)], +[AS_IF([test "x$withval" = "xyes"], [ + AC_ARG_VAR([SAFECODE_HOME], [set to the safecode base directory]) + : ${SAFECODE_HOME:=/opt/safecode} + LDFLAGS="$LDFLAGS -L${SAFECODE_HOME}/lib" + LIBS="$LIBS -lsc_dbg_rt -lpoolalloc_bitmap -lstdc++" + CFLAGS="$CFLAGS -fmemsafety" + ]) +]) + +AC_ARG_WITH(ctgrind, +[AS_HELP_STRING(--with-ctgrind,For maintainers only - please do not use)], +[AS_IF([test "x$withval" = "xyes"], [ + AC_CHECK_LIB(ctgrind, ct_poison) + ]) +]) + +AC_ARG_ENABLE(retpoline, +[AS_HELP_STRING(--enable-retpoline,Use return trampolines for indirect calls)], +[AS_IF([test "x$enableval" = "xyes"], [ + AX_CHECK_COMPILE_FLAG([-mindirect-branch=thunk-inline], + [CFLAGS="$CFLAGS -mindirect-branch=thunk-inline"], + [AX_CHECK_COMPILE_FLAG([-mretpoline], [CFLAGS="$CFLAGS -mretpoline"])] + ) + AX_CHECK_COMPILE_FLAG([-mindirect-branch-register]) + ]) +]) + +ENABLE_CWFLAGS=no +AC_ARG_ENABLE(debug, +[AS_HELP_STRING(--enable-debug,For maintainers only - please do not use)], +[ + AS_IF([test "x$enableval" = "xyes"], [ + AS_IF([test "x$LX_CFLAGS" = "xNONE"], [ + nxflags="" + for flag in `echo $CFLAGS`; do + AS_CASE([$flag], + [-O*], [ ], + [-g*], [ ], + [*], [AS_VAR_APPEND([nxflags], [" $flag"])]) + done + CFLAGS="$nxflags -O -g3" + ]) + ENABLE_CWFLAGS=yes + CPPFLAGS="$CPPFLAGS -DDEBUG=1 -U_FORTIFY_SOURCE" + ]) +]) + +AC_ARG_ENABLE(opt, +[AS_HELP_STRING(--enable-opt,Optimize for the native CPU - The resulting library will be faster but not portable)], +[ + AS_IF([test "x$enableval" = "xyes"], [ + AX_CHECK_COMPILE_FLAG([-Ofast], [CFLAGS="$CFLAGS -Ofast"]) + AX_CHECK_COMPILE_FLAG([-ftree-vectorize], [CFLAGS="$CFLAGS -ftree-vectorize"]) + AX_CHECK_COMPILE_FLAG([-ftree-slp-vectorize], [CFLAGS="$CFLAGS -ftree-slp-vectorize"]) + AX_CHECK_COMPILE_FLAG([-fomit-frame-pointer], [CFLAGS="$CFLAGS -fomit-frame-pointer"]) + AX_CHECK_COMPILE_FLAG([-march=native], [CFLAGS="$CFLAGS -march=native"]) + ]) +]) + +AC_SUBST(MAINT) +AC_SUBST(PKGCONFIG_LIBS_PRIVATE) + +AX_VALGRIND_CHECK + +dnl Checks + +AC_C_VARARRAYS + +AC_CHECK_DEFINE([__wasi__], [WASI="yes"], []) + +AS_CASE([$host_os], [linux-gnu], [AX_ADD_FORTIFY_SOURCE], [ ]) + +AX_CHECK_COMPILE_FLAG([-fvisibility=hidden], + [CFLAGS="$CFLAGS -fvisibility=hidden"]) + +AS_CASE([$host_os], [cygwin*|mingw*|msys|pw32*|cegcc*|eabi*], [ ], [ + AX_CHECK_COMPILE_FLAG([-fPIC], [CFLAGS="$CFLAGS -fPIC"]) +]) + +AS_IF([test "$enable_pie" != "no"],[ + AX_CHECK_COMPILE_FLAG([-fPIE], [ + AX_CHECK_LINK_FLAG([-pie], [ + [CFLAGS="$CFLAGS -fPIE" + LDFLAGS="$LDFLAGS -pie"] + ]) + ]) +]) + +AX_CHECK_COMPILE_FLAG([-fno-strict-aliasing], [CFLAGS="$CFLAGS -fno-strict-aliasing"]) +AX_CHECK_COMPILE_FLAG([-fno-strict-overflow], [CFLAGS="$CFLAGS -fno-strict-overflow"], [ + AX_CHECK_COMPILE_FLAG([-fwrapv], [CFLAGS="$CFLAGS -fwrapv"]) +]) + +AS_IF([test "$GCC" = "yes" ], [ + AS_CASE([$host_cpu], + [i?86|amd64|x86_64], [ + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE([ +#if !defined(__clang__) && defined(__GNUC__) && ((__GNUC__ << 8) | __GNUC_MINOR__) < 0x403 +# error old gcc +#endif +int main(void) { return 0; } + ])],,[ + AX_CHECK_COMPILE_FLAG([-flax-vector-conversions], [CFLAGS="$CFLAGS -flax-vector-conversions"]) + ]) + ] + ) + ]) + +LIBTOOL_OLD_FLAGS="$LIBTOOL_EXTRA_FLAGS" +LIBTOOL_EXTRA_FLAGS="$LIBTOOL_EXTRA_FLAGS -version-info $SODIUM_LIBRARY_VERSION" +AC_ARG_ENABLE(soname-versions, + [AS_HELP_STRING([--enable-soname-versions], [enable soname versions (must be disabled for Android) (default: enabled)])], + [ + AS_IF([test "x$enableval" = "xno"], [ + LIBTOOL_EXTRA_FLAGS="$LIBTOOL_OLD_FLAGS -avoid-version" + ]) + ] +) + +AS_CASE([$host_os], + [cygwin*|mingw*|msys|pw32*|cegcc*], [ + AX_CHECK_LINK_FLAG([-Wl,--dynamicbase], [LDFLAGS="$LDFLAGS -Wl,--dynamicbase"]) + AX_CHECK_LINK_FLAG([-Wl,--high-entropy-va], [LDFLAGS="$LDFLAGS -Wl,--high-entropy-va"]) + AX_CHECK_LINK_FLAG([-Wl,--nxcompat], [LDFLAGS="$LDFLAGS -Wl,--nxcompat"]) + ]) + +AS_CASE([$host_os], + [cygwin*|mingw*|msys|pw32*|cegcc*|eabi*], [ + AX_CHECK_COMPILE_FLAG([-fno-asynchronous-unwind-tables], [ + [CFLAGS="$CFLAGS -fno-asynchronous-unwind-tables"] + ]) +]) + +AC_MSG_CHECKING(for a broken Xcode version) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ +#if !defined(__APPLE_CC__) || __APPLE_CC__ != 6000 +#error Not Apple +#endif +#if !defined(__clang_major__) || __clang_major__ != 11 +#error Not Xcode 11 +#endif +]])], + [AC_MSG_RESULT(yes) + AC_MSG_WARN([Using unsupported Xcode version]) + AX_CHECK_COMPILE_FLAG([$CFLAGS -fno-stack-check], + [CFLAGS="$CFLAGS -fno-stack-check"]) + ], + [AC_MSG_RESULT(no) +]) + +AS_IF([test "x$enable_ssp" != "xno"],[ + +AS_CASE([$host_os], + [cygwin*|mingw*|msys|pw32*|cegcc*|haiku|none|eabi*], [ ], + [*], [ + AX_CHECK_COMPILE_FLAG([-fstack-protector], [ + AX_CHECK_LINK_FLAG([-fstack-protector], + [CFLAGS="$CFLAGS -fstack-protector"] + ) + ]) + ]) +]) + +AC_ARG_VAR([CWFLAGS], [define to compilation flags for generating extra warnings]) + +AX_CHECK_COMPILE_FLAG([$CFLAGS -Wall], [CWFLAGS="$CFLAGS -Wall"]) +AX_CHECK_COMPILE_FLAG([$CFLAGS -Wextra], [CWFLAGS="$CFLAGS -Wextra"]) + +AC_MSG_CHECKING(for clang) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ +#ifndef __clang__ +#error Not clang +#endif +]])], + [AC_MSG_RESULT(yes) + AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wno-unknown-warning-option], + [CWFLAGS="$CWFLAGS -Wno-unknown-warning-option"]) + ], + [AC_MSG_RESULT(no) +]) + +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wbad-function-cast], [CWFLAGS="$CWFLAGS -Wbad-function-cast"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wcast-qual], [CWFLAGS="$CWFLAGS -Wcast-qual"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wdiv-by-zero], [CWFLAGS="$CWFLAGS -Wdiv-by-zero"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wduplicated-branches], [CWFLAGS="$CWFLAGS -Wduplicated-branches"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wduplicated-cond], [CWFLAGS="$CWFLAGS -Wduplicated-cond"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wfloat-equal], [CWFLAGS="$CWFLAGS -Wfloat-equal"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wformat=2], [CWFLAGS="$CWFLAGS -Wformat=2"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wlogical-op], [CWFLAGS="$CWFLAGS -Wlogical-op"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wmaybe-uninitialized], [CWFLAGS="$CWFLAGS -Wmaybe-uninitialized"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wmisleading-indentation], [CWFLAGS="$CWFLAGS -Wmisleading-indentation"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wmissing-declarations], [CWFLAGS="$CWFLAGS -Wmissing-declarations"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wmissing-prototypes], [CWFLAGS="$CWFLAGS -Wmissing-prototypes"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wnested-externs], [CWFLAGS="$CWFLAGS -Wnested-externs"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wno-type-limits], [CWFLAGS="$CWFLAGS -Wno-type-limits"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wno-unknown-pragmas], [CWFLAGS="$CWFLAGS -Wno-unknown-pragmas"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wnormalized=id], [CWFLAGS="$CWFLAGS -Wnormalized=id"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wnull-dereference], [CWFLAGS="$CWFLAGS -Wnull-dereference"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wold-style-declaration], [CWFLAGS="$CWFLAGS -Wold-style-declaration"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wpointer-arith], [CWFLAGS="$CWFLAGS -Wpointer-arith"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wredundant-decls], [CWFLAGS="$CWFLAGS -Wredundant-decls"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wrestrict], [CWFLAGS="$CWFLAGS -Wrestrict"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wshorten-64-to-32], [CWFLAGS="$CWFLAGS -Wshorten-64-to-32"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wsometimes-uninitialized], [CWFLAGS="$CWFLAGS -Wsometimes-uninitialized"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wstrict-prototypes], [CWFLAGS="$CWFLAGS -Wstrict-prototypes"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wswitch-enum], [CWFLAGS="$CWFLAGS -Wswitch-enum"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wvariable-decl], [CWFLAGS="$CWFLAGS -Wvariable-decl"]) +AX_CHECK_COMPILE_FLAG([$CWFLAGS -Wwrite-strings], [CWFLAGS="$CWFLAGS -Wwrite-strings"]) + +AS_IF([test "x$EMSCRIPTEN" = "x"], [ + AX_CHECK_LINK_FLAG([-Wl,-z,relro], [LDFLAGS="$LDFLAGS -Wl,-z,relro"]) + AX_CHECK_LINK_FLAG([-Wl,-z,now], [LDFLAGS="$LDFLAGS -Wl,-z,now"]) + AX_CHECK_LINK_FLAG([-Wl,-z,noexecstack], [LDFLAGS="$LDFLAGS -Wl,-z,noexecstack"]) +]) + +AX_CHECK_CATCHABLE_SEGV +AX_CHECK_CATCHABLE_ABRT + +AS_IF([test "x$with_threads" = "xyes"], [ + AX_TLS([AC_MSG_RESULT(thread local storage is supported) + AX_CHECK_COMPILE_FLAG([-ftls-model=local-dynamic], + [CFLAGS="$CFLAGS -ftls-model=local-dynamic"])], + [AC_MSG_RESULT(thread local storage is not supported)]) ]) + +LT_INIT +AC_SUBST(LIBTOOL_DEPS) + +AC_ARG_VAR([AR], [path to the ar utility]) +AC_CHECK_TOOL([AR], [ar], [ar]) + +dnl Checks for headers + +AS_IF([test "x$EMSCRIPTEN" = "x"], [ + + oldcflags="$CFLAGS" + AX_CHECK_COMPILE_FLAG([-mmmx], [CFLAGS="$CFLAGS -mmmx"]) + AC_MSG_CHECKING(for MMX instructions set) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#pragma GCC target("mmx") +#include +]], [[ __m64 x = _mm_setzero_si64(); ]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_MMINTRIN_H], [1], [mmx is available]) + AX_CHECK_COMPILE_FLAG([-mmmx], [CFLAGS_MMX="-mmmx"])], + [AC_MSG_RESULT(no)]) + CFLAGS="$oldcflags" + + oldcflags="$CFLAGS" + AX_CHECK_COMPILE_FLAG([-msse2], [CFLAGS="$CFLAGS -msse2"]) + AC_MSG_CHECKING(for SSE2 instructions set) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#pragma GCC target("sse2") +#ifndef __SSE2__ +# define __SSE2__ +#endif +#include +]], [[ __m128d x = _mm_setzero_pd(); + __m128i z = _mm_srli_epi64(_mm_setzero_si128(), 26); ]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_EMMINTRIN_H], [1], [sse2 is available]) + AX_CHECK_COMPILE_FLAG([-msse2], [CFLAGS_SSE2="-msse2"])], + [AC_MSG_RESULT(no)]) + CFLAGS="$oldcflags" + + oldcflags="$CFLAGS" + AX_CHECK_COMPILE_FLAG([-msse3], [CFLAGS="$CFLAGS -msse3"]) + AC_MSG_CHECKING(for SSE3 instructions set) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#pragma GCC target("sse3") +#include +]], [[ __m128 x = _mm_addsub_ps(_mm_cvtpd_ps(_mm_setzero_pd()), + _mm_cvtpd_ps(_mm_setzero_pd())); ]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_PMMINTRIN_H], [1], [sse3 is available]) + AX_CHECK_COMPILE_FLAG([-msse3], [CFLAGS_SSE3="-msse3"])], + [AC_MSG_RESULT(no)]) + CFLAGS="$oldcflags" + + oldcflags="$CFLAGS" + AX_CHECK_COMPILE_FLAG([-mssse3], [CFLAGS="$CFLAGS -mssse3"]) + AC_MSG_CHECKING(for SSSE3 instructions set) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#pragma GCC target("ssse3") +#include +]], [[ __m64 x = _mm_abs_pi32(_m_from_int(0)); ]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_TMMINTRIN_H], [1], [ssse3 is available]) + AX_CHECK_COMPILE_FLAG([-mssse3], [CFLAGS_SSSE3="-mssse3"])], + [AC_MSG_RESULT(no)]) + CFLAGS="$oldcflags" + + oldcflags="$CFLAGS" + AX_CHECK_COMPILE_FLAG([-msse4.1], [CFLAGS="$CFLAGS -msse4.1"]) + AC_MSG_CHECKING(for SSE4.1 instructions set) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#pragma GCC target("sse4.1") +#include +]], [[ __m128i x = _mm_minpos_epu16(_mm_setzero_si128()); ]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_SMMINTRIN_H], [1], [sse4.1 is available]) + AX_CHECK_COMPILE_FLAG([-msse4.1], [CFLAGS_SSE41="-msse4.1"])], + [AC_MSG_RESULT(no)]) + CFLAGS="$oldcflags" + + oldcflags="$CFLAGS" + AX_CHECK_COMPILE_FLAG([-mavx], [CFLAGS="$CFLAGS -mavx"]) + AC_MSG_CHECKING(for AVX instructions set) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#pragma GCC target("avx") +#include +]], [[ _mm256_zeroall(); ]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_AVXINTRIN_H], [1], [AVX is available]) + AX_CHECK_COMPILE_FLAG([-mavx], [CFLAGS_AVX="-mavx"])], + [AC_MSG_RESULT(no)]) + CFLAGS="$oldcflags" + + oldcflags="$CFLAGS" + AX_CHECK_COMPILE_FLAG([-mavx2], [CFLAGS="$CFLAGS -mavx2"]) + AC_MSG_CHECKING(for AVX2 instructions set) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#pragma GCC target("avx2") +#include +]], [[ +__m256 x = _mm256_set1_ps(3.14); +__m256 y = _mm256_permutevar8x32_ps(x, _mm256_set1_epi32(42)); +return _mm256_movemask_ps(_mm256_cmp_ps(x, y, _CMP_NEQ_OQ)); +]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_AVX2INTRIN_H], [1], [AVX2 is available]) + AX_CHECK_COMPILE_FLAG([-mavx2], [CFLAGS_AVX2="-mavx2"]) + AC_MSG_CHECKING(if _mm256_broadcastsi128_si256 is correctly defined) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#pragma GCC target("avx2") +#include + ]], [[ __m256i y = _mm256_broadcastsi128_si256(_mm_setzero_si128()); ]])], + [AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no) + AC_DEFINE([_mm256_broadcastsi128_si256], [_mm_broadcastsi128_si256], + [Define to the local name of _mm256_broadcastsi128_si256])]) + ], + [AC_MSG_RESULT(no)]) + CFLAGS="$oldcflags" + + oldcflags="$CFLAGS" + AX_CHECK_COMPILE_FLAG([-mavx512f], [CFLAGS="$CFLAGS -mavx512f"]) + AC_MSG_CHECKING(for AVX512F instructions set) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#pragma GCC target("avx512f") +#include +]], [[ + +#ifndef __AVX512F__ +# error No AVX512 support +#elif defined(__clang__) +# if __clang_major__ < 4 +# error Compiler AVX512 support may be broken +# endif +#elif defined(__GNUC__) +# if __GNUC__ < 6 +# error Compiler AVX512 support may be broken +# endif +#endif + +__m512i x = _mm512_setzero_epi32(); +__m512i y = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), x); +]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_AVX512FINTRIN_H], [1], [AVX512F is available]) + AX_CHECK_COMPILE_FLAG([-mavx512f], [CFLAGS_AVX512F="-mavx512f"])], + [AC_MSG_RESULT(no) + AX_CHECK_COMPILE_FLAG([$CFLAGS -mno-avx512f], + [CFLAGS="$CFLAGS -mno-avx512f"]) + ]) + CFLAGS="$oldcflags" + + oldcflags="$CFLAGS" + AX_CHECK_COMPILE_FLAG([-maes], [CFLAGS="$CFLAGS -maes"]) + AX_CHECK_COMPILE_FLAG([-mpclmul], [CFLAGS="$CFLAGS -mpclmul"]) + AC_MSG_CHECKING(for AESNI instructions set and PCLMULQDQ) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#pragma GCC target("aes") +#pragma GCC target("pclmul") +#include +]], [[ __m128i x = _mm_aesimc_si128(_mm_setzero_si128()); + __m128i y = _mm_clmulepi64_si128(_mm_setzero_si128(), _mm_setzero_si128(), 0);]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_WMMINTRIN_H], [1], [aesni is available]) + AX_CHECK_COMPILE_FLAG([-maes], [CFLAGS_AESNI="-maes"]) + AX_CHECK_COMPILE_FLAG([-mpclmul], [CFLAGS_PCLMUL="-mpclmul"]) + ], + [AC_MSG_RESULT(no)]) + CFLAGS="$oldcflags" + + oldcflags="$CFLAGS" + AX_CHECK_COMPILE_FLAG([-mrdrnd], [CFLAGS="$CFLAGS -mrdrnd"]) + AC_MSG_CHECKING(for RDRAND) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#pragma GCC target("rdrnd") +#include +]], [[ unsigned long long x; _rdrand64_step(&x); ]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_RDRAND], [1], [rdrand is available]) + AX_CHECK_COMPILE_FLAG([-mrdrnd], [CFLAGS_RDRAND="-mrdrnd"]) + ], + [AC_MSG_RESULT(no)]) + CFLAGS="$oldcflags" + +]) + +AC_SUBST(CFLAGS_MMX) +AC_SUBST(CFLAGS_SSE2) +AC_SUBST(CFLAGS_SSE3) +AC_SUBST(CFLAGS_SSSE3) +AC_SUBST(CFLAGS_SSE41) +AC_SUBST(CFLAGS_AVX) +AC_SUBST(CFLAGS_AVX2) +AC_SUBST(CFLAGS_AVX512F) +AC_SUBST(CFLAGS_AESNI) +AC_SUBST(CFLAGS_PCLMUL) +AC_SUBST(CFLAGS_RDRAND) + +AC_CHECK_HEADERS([sys/mman.h sys/random.h intrin.h]) + +AC_MSG_CHECKING([if _xgetbv() is available]) +AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[ #include ]], [[ (void) _xgetbv(0) ]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE__XGETBV], [1], [_xgetbv() is available])], + [AC_MSG_RESULT(no)]) + +dnl Checks for typedefs, structures, and compiler characteristics. + +AC_C_INLINE +AS_CASE([$host_cpu], + [i?86|amd64|x86_64], + [ac_cv_c_bigendian=no] +) +AC_C_BIGENDIAN( + AC_DEFINE(NATIVE_BIG_ENDIAN, 1, [machine is bigendian]), + AC_DEFINE(NATIVE_LITTLE_ENDIAN, 1, [machine is littleendian]), + AC_MSG_ERROR([unknown endianness]), + AC_MSG_ERROR([universal endianness is not supported - compile separately and use lipo(1)]) +) + +AC_MSG_CHECKING(whether __STDC_LIMIT_MACROS is required) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +]], [[ +(void) SIZE_MAX; +(void) UINT64_MAX; +]])], + [AC_MSG_RESULT(no)], + [AC_MSG_RESULT(yes) + CPPFLAGS="$CPPFLAGS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS" +]) + +AC_MSG_CHECKING(whether we can use inline asm code) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +]], [[ +int a = 42; +int *pnt = &a; +__asm__ __volatile__ ("" : : "r"(pnt) : "memory"); +]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_INLINE_ASM], [1], [inline asm code can be used])] + [AC_MSG_RESULT(no)] +) + +HAVE_AMD64_ASM_V=0 +AS_IF([test "$enable_asm" != "no"],[ + AC_MSG_CHECKING(whether we can use x86_64 asm code) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + ]], [[ +#if defined(__amd64) || defined(__amd64__) || defined(__x86_64__) +# if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(_WIN32) || defined(_WIN64) +# error Windows x86_64 calling conventions are not supported yet +# endif +/* neat */ +#else +# error !x86_64 +#endif +unsigned char i = 0, o = 0, t; +__asm__ __volatile__ ("pxor %%xmm12, %%xmm6 \n" + "movb (%[i]), %[t] \n" + "addb %[t], (%[o]) \n" + : [t] "=&r"(t) + : [o] "D"(&o), [i] "S"(&i) + : "memory", "flags", "cc"); +]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_AMD64_ASM], [1], [x86_64 asm code can be used]) + HAVE_AMD64_ASM_V=1], + [AC_MSG_RESULT(no)]) +]) +AM_CONDITIONAL([HAVE_AMD64_ASM], [test $HAVE_AMD64_ASM_V = 1]) +AC_SUBST(HAVE_AMD64_ASM_V) + +HAVE_AVX_ASM_V=0 +AS_IF([test "$enable_asm" != "no"],[ + AC_MSG_CHECKING(whether we can assemble AVX opcodes) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + ]], [[ +#if defined(__amd64) || defined(__amd64__) || defined(__x86_64__) +# if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(_WIN32) || defined(_WIN64) +# error Windows x86_64 calling conventions are not supported yet +# endif +/* neat */ +#else +# error !x86_64 +#endif +__asm__ __volatile__ ("vpunpcklqdq %xmm0,%xmm13,%xmm0"); +]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_AVX_ASM], [1], [AVX opcodes are supported]) + HAVE_AVX_ASM_V=1], + [AC_MSG_RESULT(no)]) +]) +AM_CONDITIONAL([HAVE_AVX_ASM], [test $HAVE_AVX_ASM_V = 1]) +AC_SUBST(HAVE_AVX_ASM_V) + +AC_MSG_CHECKING(for 128-bit arithmetic) +HAVE_TI_MODE_V=0 +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#if !defined(__clang__) && !defined(__GNUC__) && !defined(__SIZEOF_INT128__) +# error mode(TI) is a gcc extension, and __int128 is not available +#endif +#if defined(__clang__) && !defined(__x86_64__) && !defined(__aarch64__) +# error clang does not properly handle the 128-bit type on 32-bit systems +#endif +#ifndef NATIVE_LITTLE_ENDIAN +# error libsodium currently expects a little endian CPU for the 128-bit type +#endif +#ifdef __EMSCRIPTEN__ +# error emscripten currently doesn't support some operations on integers larger than 64 bits +#endif +#include +#include +#if defined(__SIZEOF_INT128__) +typedef unsigned __int128 uint128_t; +#else +typedef unsigned uint128_t __attribute__((mode(TI))); +#endif +void fcontract(uint128_t *t) { + *t += 0x8000000000000 - 1; + *t *= *t; + *t >>= 84; +} +]], [[ +(void) fcontract; +]])], +[AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_TI_MODE], [1], [gcc TI mode is available]) + HAVE_TI_MODE_V=1], +[AC_MSG_RESULT(no)]) +AM_CONDITIONAL([HAVE_TI_MODE], [test $HAVE_TI_MODE_V = 1]) +AC_SUBST(HAVE_TI_MODE_V) + +HAVE_CPUID_V=0 +AS_IF([test "$enable_asm" != "no"],[ + AC_MSG_CHECKING(for cpuid instruction) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ ]], [[ +unsigned int cpu_info[4]; +__asm__ __volatile__ ("xchgl %%ebx, %k1; cpuid; xchgl %%ebx, %k1" : + "=a" (cpu_info[0]), "=&r" (cpu_info[1]), + "=c" (cpu_info[2]), "=d" (cpu_info[3]) : + "0" (0U), "2" (0U)); + ]])], + [AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_CPUID], [1], [cpuid instruction is available]) + HAVE_CPUID_V=1], + [AC_MSG_RESULT(no)]) + ]) +AC_SUBST(HAVE_CPUID_V) + +asm_hide_symbol="unsupported" +AS_IF([test "$enable_asm" != "no"],[ + AC_MSG_CHECKING(if the .private_extern asm directive is supported) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ ]], [[ +__asm__ __volatile__ (".private_extern dummy_symbol \n" + ".private_extern _dummy_symbol \n" + ".globl dummy_symbol \n" + ".globl _dummy_symbol \n" + "dummy_symbol: \n" + "_dummy_symbol: \n" + " nop \n" +); + ]])], + [AC_MSG_RESULT(yes) + asm_hide_symbol=".private_extern"], + [AC_MSG_RESULT(no)]) + + AC_MSG_CHECKING(if the .hidden asm directive is supported) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ ]], [[ +__asm__ __volatile__ (".hidden dummy_symbol \n" + ".hidden _dummy_symbol \n" + ".globl dummy_symbol \n" + ".globl _dummy_symbol \n" + "dummy_symbol: \n" + "_dummy_symbol: \n" + " nop \n" +); + ]])], + [AC_MSG_RESULT(yes) + AS_IF([test "$asm_hide_symbol" = "unsupported"], + [asm_hide_symbol=".hidden"], + [AC_MSG_NOTICE([unable to reliably tag symbols as private]) + asm_hide_symbol="unsupported"]) + ], + [AC_MSG_RESULT(no)]) + + AS_IF([test "$asm_hide_symbol" != "unsupported"],[ + AC_DEFINE_UNQUOTED([ASM_HIDE_SYMBOL], [$asm_hide_symbol], [directive to hide symbols]) + ]) +]) + +AC_MSG_CHECKING(if weak symbols are supported) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#if !defined(__ELF__) && !defined(__APPLE_CC__) +# error Support for weak symbols may not be available +#endif +__attribute__((weak)) void __dummy(void *x) { } +void f(void *x) { __dummy(x); } +]], [[ ]] +)], +[AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_WEAK_SYMBOLS], [1], [weak symbols are supported])], +[AC_MSG_RESULT(no)]) + +AC_MSG_CHECKING(if data alignment is required) +aligned_access_required=yes +AS_CASE([$host_cpu], + [i?86|amd64|x86_64|powerpc*|s390*], + [aligned_access_required=no], + [arm*], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#ifndef __ARM_FEATURE_UNALIGNED +# error data alignment is required +#endif + ]], [[]])], [aligned_access_required=no], [])] +) +AS_IF([test "x$aligned_access_required" = "xyes"], + [AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no) + AC_DEFINE([CPU_UNALIGNED_ACCESS], [1], [unaligned memory access is supported])]) + +AC_MSG_CHECKING(if atomic operations are supported) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ ]], [[ +static volatile int _sodium_lock; +__sync_lock_test_and_set(&_sodium_lock, 1); +__sync_lock_release(&_sodium_lock); +]] +)], +[AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_ATOMIC_OPS], [1], [atomic operations are supported])], +[AC_MSG_RESULT(no)]) + +dnl Checks for functions and headers + +AC_FUNC_ALLOCA +AS_IF([test "x$EMSCRIPTEN" = "x"],[ + AC_CHECK_FUNCS([arc4random arc4random_buf]) + AS_IF([test "x$WASI" = "x"],[ + AC_CHECK_FUNCS([mmap mlock madvise mprotect]) + ]) + + AC_MSG_CHECKING(for getrandom with a standard API) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_RANDOM_H +# include +#endif +#ifdef __SANITIZE_ADDRESS__ +# error A recent libasan version on an old system may intercept nonexistent functions +#endif +]], [[ +unsigned char buf; +(void) getrandom((void *) &buf, 1U, 0U); + ]])], + [AC_MSG_RESULT(yes) + AC_CHECK_FUNCS([getrandom])], + [AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING(for getentropy with a standard API) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_RANDOM_H +# include +#endif +#ifdef __SANITIZE_ADDRESS__ +# error A recent libasan version on an old system may intercept nonexistent functions +#endif +]], [[ +unsigned char buf; + +if (&getentropy != NULL) { + (void) getentropy((void *) &buf, 1U); +} + ]])], + [AC_MSG_RESULT(yes) + AC_CHECK_FUNCS([getentropy])], + [AC_MSG_RESULT(no) + ]) +]) + +AS_IF([test "x$WASI" = "x"],[ + AC_CHECK_FUNCS([getpid]) + AC_CHECK_FUNCS([getauxva elf_aux_info]) +]) + +AC_CHECK_FUNCS([posix_memalign nanosleep]) + +AS_IF([test "x$WASI" = "x"],[ + AC_CHECK_FUNCS([memset_s explicit_bzero explicit_memset]) +]) + +AC_SUBST([LIBTOOL_EXTRA_FLAGS]) + +TEST_LDFLAGS='' +AS_IF([test "x$EMSCRIPTEN" != "x"],[ + EXEEXT=.js + TEST_LDFLAGS='--memory-init-file 0 --pre-js pre.js.inc -s RESERVED_FUNCTION_POINTERS=8' +]) +AC_SUBST(TEST_LDFLAGS) +AM_CONDITIONAL([EMSCRIPTEN], [test "x$EMSCRIPTEN" != "x"]) +AM_CONDITIONAL([WASI], [test "x$WASI" != "x"]) + +AC_DEFINE([CONFIGURED], [1], [the build system was properly configured]) + +dnl Libtool. + +LT_INIT([dlopen win32-dll]) +gl_LD_OUTPUT_DEF + +dnl Output. + +AH_VERBATIM([NDEBUG], [/* Always evaluate assert() calls */ +#ifdef NDEBUG +#/**/undef/**/ NDEBUG +#endif]) + +AS_IF([test "x$ENABLE_CWFLAGS" = "xyes"], [ + CFLAGS="$CFLAGS $CWFLAGS" +]) + +AC_CONFIG_FILES([Makefile + builds/Makefile + contrib/Makefile + dist-build/Makefile + libsodium.pc + libsodium-uninstalled.pc + msvc-scripts/Makefile + src/Makefile + src/libsodium/Makefile + src/libsodium/include/Makefile + src/libsodium/include/sodium/version.h + test/default/Makefile + test/Makefile + ]) +AC_OUTPUT diff --git a/external/src/libsodium/contrib/Findsodium.cmake b/external/src/libsodium/contrib/Findsodium.cmake new file mode 100644 index 0000000..076ff37 --- /dev/null +++ b/external/src/libsodium/contrib/Findsodium.cmake @@ -0,0 +1,293 @@ +# Written in 2016 by Henrik Steffen Gaßmann +# +# To the extent possible under law, the author(s) have dedicated all copyright +# and related and neighboring rights to this software to the public domain +# worldwide. This software is distributed without any warranty. +# +# You should have received a copy of the CC0 Public Domain Dedication along with +# this software. If not, see +# +# http://creativecommons.org/publicdomain/zero/1.0/ +# +# ############################################################################## +# Tries to find the local libsodium installation. +# +# On Windows the sodium_DIR environment variable is used as a default hint which +# can be overridden by setting the corresponding cmake variable. +# +# Once done the following variables will be defined: +# +# sodium_FOUND sodium_INCLUDE_DIR sodium_LIBRARY_DEBUG sodium_LIBRARY_RELEASE +# sodium_VERSION_STRING +# +# Furthermore an imported "sodium" target is created. +# + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + set(_GCC_COMPATIBLE 1) +endif() + +# static library option +if(NOT DEFINED sodium_USE_STATIC_LIBS) + option(sodium_USE_STATIC_LIBS "enable to statically link against sodium" OFF) +endif() +if(NOT (sodium_USE_STATIC_LIBS EQUAL sodium_USE_STATIC_LIBS_LAST)) + unset(sodium_LIBRARY CACHE) + unset(sodium_LIBRARY_DEBUG CACHE) + unset(sodium_LIBRARY_RELEASE CACHE) + unset(sodium_DLL_DEBUG CACHE) + unset(sodium_DLL_RELEASE CACHE) + set(sodium_USE_STATIC_LIBS_LAST + ${sodium_USE_STATIC_LIBS} + CACHE INTERNAL "internal change tracking variable") +endif() + +# ############################################################################## +# UNIX +if(UNIX) + # import pkg-config + find_package(PkgConfig QUIET) + if(PKG_CONFIG_FOUND) + pkg_check_modules(sodium_PKG QUIET libsodium) + endif() + + if(sodium_USE_STATIC_LIBS) + if(sodium_PKG_STATIC_LIBRARIES) + foreach(_libname ${sodium_PKG_STATIC_LIBRARIES}) + if(NOT _libname MATCHES "^lib.*\\.a$") # ignore strings already ending + # with .a + list(INSERT sodium_PKG_STATIC_LIBRARIES 0 "lib${_libname}.a") + endif() + endforeach() + list(REMOVE_DUPLICATES sodium_PKG_STATIC_LIBRARIES) + else() + # if pkgconfig for libsodium doesn't provide static lib info, then + # override PKG_STATIC here.. + set(sodium_PKG_STATIC_LIBRARIES libsodium.a) + endif() + + set(XPREFIX sodium_PKG_STATIC) + else() + if(sodium_PKG_LIBRARIES STREQUAL "") + set(sodium_PKG_LIBRARIES sodium) + endif() + + set(XPREFIX sodium_PKG) + endif() + + find_path(sodium_INCLUDE_DIR sodium.h HINTS ${${XPREFIX}_INCLUDE_DIRS}) + find_library(sodium_LIBRARY_DEBUG + NAMES ${${XPREFIX}_LIBRARIES} + HINTS ${${XPREFIX}_LIBRARY_DIRS}) + find_library(sodium_LIBRARY_RELEASE + NAMES ${${XPREFIX}_LIBRARIES} + HINTS ${${XPREFIX}_LIBRARY_DIRS}) + + # ############################################################################ + # Windows +elseif(WIN32) + set(sodium_DIR "$ENV{sodium_DIR}" CACHE FILEPATH "sodium install directory") + mark_as_advanced(sodium_DIR) + + find_path(sodium_INCLUDE_DIR sodium.h + HINTS ${sodium_DIR} + PATH_SUFFIXES include) + + if(MSVC) + # detect target architecture + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/arch.c" [=[ + #if defined _M_IX86 + #error ARCH_VALUE x86_32 + #elif defined _M_X64 + #error ARCH_VALUE x86_64 + #endif + #error ARCH_VALUE unknown + ]=]) + try_compile(_UNUSED_VAR "${CMAKE_CURRENT_BINARY_DIR}" + "${CMAKE_CURRENT_BINARY_DIR}/arch.c" + OUTPUT_VARIABLE _COMPILATION_LOG) + string(REGEX + REPLACE ".*ARCH_VALUE ([a-zA-Z0-9_]+).*" + "\\1" + _TARGET_ARCH + "${_COMPILATION_LOG}") + + # construct library path + if(_TARGET_ARCH STREQUAL "x86_32") + string(APPEND _PLATFORM_PATH "Win32") + elseif(_TARGET_ARCH STREQUAL "x86_64") + string(APPEND _PLATFORM_PATH "x64") + else() + message( + FATAL_ERROR + "the ${_TARGET_ARCH} architecture is not supported by Findsodium.cmake." + ) + endif() + string(APPEND _PLATFORM_PATH "/$$CONFIG$$") + + if(MSVC_VERSION LESS 1900) + math(EXPR _VS_VERSION "${MSVC_VERSION} / 10 - 60") + else() + math(EXPR _VS_VERSION "${MSVC_VERSION} / 10 - 50") + endif() + string(APPEND _PLATFORM_PATH "/v${_VS_VERSION}") + + if(sodium_USE_STATIC_LIBS) + string(APPEND _PLATFORM_PATH "/static") + else() + string(APPEND _PLATFORM_PATH "/dynamic") + endif() + + string(REPLACE "$$CONFIG$$" + "Debug" + _DEBUG_PATH_SUFFIX + "${_PLATFORM_PATH}") + string(REPLACE "$$CONFIG$$" + "Release" + _RELEASE_PATH_SUFFIX + "${_PLATFORM_PATH}") + + find_library(sodium_LIBRARY_DEBUG libsodium.lib + HINTS ${sodium_DIR} + PATH_SUFFIXES ${_DEBUG_PATH_SUFFIX}) + find_library(sodium_LIBRARY_RELEASE libsodium.lib + HINTS ${sodium_DIR} + PATH_SUFFIXES ${_RELEASE_PATH_SUFFIX}) + if(NOT sodium_USE_STATIC_LIBS) + set(CMAKE_FIND_LIBRARY_SUFFIXES_BCK ${CMAKE_FIND_LIBRARY_SUFFIXES}) + set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll") + find_library(sodium_DLL_DEBUG libsodium + HINTS ${sodium_DIR} + PATH_SUFFIXES ${_DEBUG_PATH_SUFFIX}) + find_library(sodium_DLL_RELEASE libsodium + HINTS ${sodium_DIR} + PATH_SUFFIXES ${_RELEASE_PATH_SUFFIX}) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_BCK}) + endif() + + elseif(_GCC_COMPATIBLE) + if(sodium_USE_STATIC_LIBS) + find_library(sodium_LIBRARY_DEBUG libsodium.a + HINTS ${sodium_DIR} + PATH_SUFFIXES lib) + find_library(sodium_LIBRARY_RELEASE libsodium.a + HINTS ${sodium_DIR} + PATH_SUFFIXES lib) + else() + find_library(sodium_LIBRARY_DEBUG libsodium.dll.a + HINTS ${sodium_DIR} + PATH_SUFFIXES lib) + find_library(sodium_LIBRARY_RELEASE libsodium.dll.a + HINTS ${sodium_DIR} + PATH_SUFFIXES lib) + + file(GLOB _DLL + LIST_DIRECTORIES false + RELATIVE "${sodium_DIR}/bin" + "${sodium_DIR}/bin/libsodium*.dll") + find_library(sodium_DLL_DEBUG ${_DLL} libsodium + HINTS ${sodium_DIR} + PATH_SUFFIXES bin) + find_library(sodium_DLL_RELEASE ${_DLL} libsodium + HINTS ${sodium_DIR} + PATH_SUFFIXES bin) + endif() + else() + message(FATAL_ERROR "this platform is not supported by FindSodium.cmake") + endif() + + # ############################################################################ + # unsupported +else() + message(FATAL_ERROR "this platform is not supported by FindSodium.cmake") +endif() + +# ############################################################################## +# common stuff + +# extract sodium version +if(sodium_INCLUDE_DIR) + set(_VERSION_HEADER "${sodium_INCLUDE_DIR}/sodium/version.h") + if(EXISTS "${_VERSION_HEADER}") + file(READ "${_VERSION_HEADER}" _VERSION_HEADER_CONTENT) + string( + REGEX + REPLACE + ".*define[ \t]+SODIUM_VERSION_STRING[^\"]+\"([^\"]+)\".*" + "\\1" + sodium_VERSION_STRING + "${_VERSION_HEADER_CONTENT}") + set(sodium_VERSION_STRING "${sodium_VERSION_STRING}") + endif() +endif() + +# communicate results +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(sodium + REQUIRED_VARS + sodium_LIBRARY_RELEASE + sodium_LIBRARY_DEBUG + sodium_INCLUDE_DIR + VERSION_VAR + sodium_VERSION_STRING) + +# mark file paths as advanced +mark_as_advanced(sodium_INCLUDE_DIR) +mark_as_advanced(sodium_LIBRARY_DEBUG) +mark_as_advanced(sodium_LIBRARY_RELEASE) +if(WIN32) + mark_as_advanced(sodium_DLL_DEBUG) + mark_as_advanced(sodium_DLL_RELEASE) +endif() + +# create imported target +if(sodium_USE_STATIC_LIBS) + set(_LIB_TYPE STATIC) +else() + set(_LIB_TYPE SHARED) +endif() +add_library(sodium ${_LIB_TYPE} IMPORTED) + +set_target_properties(sodium + PROPERTIES INTERFACE_INCLUDE_DIRECTORIES + "${sodium_INCLUDE_DIR}" + IMPORTED_LINK_INTERFACE_LANGUAGES + "C") + +if(sodium_USE_STATIC_LIBS) + set_target_properties(sodium + PROPERTIES INTERFACE_COMPILE_DEFINITIONS + "SODIUM_STATIC" + IMPORTED_LOCATION + "${sodium_LIBRARY_RELEASE}" + IMPORTED_LOCATION_DEBUG + "${sodium_LIBRARY_DEBUG}") +else() + if(UNIX) + set_target_properties(sodium + PROPERTIES IMPORTED_LOCATION + "${sodium_LIBRARY_RELEASE}" + IMPORTED_LOCATION_DEBUG + "${sodium_LIBRARY_DEBUG}") + elseif(WIN32) + set_target_properties(sodium + PROPERTIES IMPORTED_IMPLIB + "${sodium_LIBRARY_RELEASE}" + IMPORTED_IMPLIB_DEBUG + "${sodium_LIBRARY_DEBUG}") + if(NOT (sodium_DLL_DEBUG MATCHES ".*-NOTFOUND")) + set_target_properties(sodium + PROPERTIES IMPORTED_LOCATION_DEBUG + "${sodium_DLL_DEBUG}") + endif() + if(NOT (sodium_DLL_RELEASE MATCHES ".*-NOTFOUND")) + set_target_properties(sodium + PROPERTIES IMPORTED_LOCATION_RELWITHDEBINFO + "${sodium_DLL_RELEASE}" + IMPORTED_LOCATION_MINSIZEREL + "${sodium_DLL_RELEASE}" + IMPORTED_LOCATION_RELEASE + "${sodium_DLL_RELEASE}") + endif() + endif() +endif() diff --git a/external/src/libsodium/contrib/Makefile.am b/external/src/libsodium/contrib/Makefile.am new file mode 100644 index 0000000..2cfe522 --- /dev/null +++ b/external/src/libsodium/contrib/Makefile.am @@ -0,0 +1,3 @@ + +EXTRA_DIST = \ + Findsodium.cmake diff --git a/external/src/libsodium/dist-build/Makefile.am b/external/src/libsodium/dist-build/Makefile.am new file mode 100644 index 0000000..fe7961d --- /dev/null +++ b/external/src/libsodium/dist-build/Makefile.am @@ -0,0 +1,17 @@ + +EXTRA_DIST = \ + android-build.sh \ + android-arm.sh \ + android-armv7-a.sh \ + android-armv8-a.sh \ + android-mips32.sh \ + android-mips64.sh \ + android-x86.sh \ + android-x86_64.sh \ + emscripten.sh \ + ios.sh \ + apple-xcframework.sh \ + msys2-win32.sh \ + msys2-win64.sh \ + watchos.sh \ + wasm32-wasi.sh diff --git a/external/src/libsodium/dist-build/android-arm.sh b/external/src/libsodium/dist-build/android-arm.sh new file mode 100644 index 0000000..eb97828 --- /dev/null +++ b/external/src/libsodium/dist-build/android-arm.sh @@ -0,0 +1,4 @@ +#!/bin/sh +export TARGET_ARCH=armv6 +export CFLAGS="-Os -mthumb -marm -march=${TARGET_ARCH}" +ARCH=arm HOST_COMPILER=arm-linux-androideabi "$(dirname "$0")/android-build.sh" diff --git a/external/src/libsodium/dist-build/android-armv7-a.sh b/external/src/libsodium/dist-build/android-armv7-a.sh new file mode 100644 index 0000000..a872508 --- /dev/null +++ b/external/src/libsodium/dist-build/android-armv7-a.sh @@ -0,0 +1,4 @@ +#!/bin/sh +export TARGET_ARCH=armv7-a +export CFLAGS="-Os -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -marm -march=${TARGET_ARCH}" +ARCH=arm HOST_COMPILER=arm-linux-androideabi "$(dirname "$0")/android-build.sh" diff --git a/external/src/libsodium/dist-build/android-armv8-a.sh b/external/src/libsodium/dist-build/android-armv8-a.sh new file mode 100644 index 0000000..1bf13ae --- /dev/null +++ b/external/src/libsodium/dist-build/android-armv8-a.sh @@ -0,0 +1,4 @@ +#!/bin/sh +export TARGET_ARCH=armv8-a +export CFLAGS="-Os -march=${TARGET_ARCH}" +NDK_PLATFORM=android-21 ARCH=arm64 HOST_COMPILER=aarch64-linux-android "$(dirname "$0")/android-build.sh" diff --git a/external/src/libsodium/dist-build/android-build.sh b/external/src/libsodium/dist-build/android-build.sh new file mode 100644 index 0000000..ece1d01 --- /dev/null +++ b/external/src/libsodium/dist-build/android-build.sh @@ -0,0 +1,98 @@ +#! /bin/sh + +if [ -z "$NDK_PLATFORM" ]; then + export NDK_PLATFORM="android-16" +fi +export NDK_PLATFORM_COMPAT="${NDK_PLATFORM_COMPAT:-${NDK_PLATFORM}}" +export NDK_API_VERSION=$(echo "$NDK_PLATFORM" | sed 's/^android-//') +export NDK_API_VERSION_COMPAT=$(echo "$NDK_PLATFORM_COMPAT" | sed 's/^android-//') + +if [ -z "$ANDROID_NDK_HOME" ]; then + echo "You should probably set ANDROID_NDK_HOME to the directory containing" + echo "the Android NDK" + exit 1 +fi + +if [ ! -f ./configure ]; then + echo "Can't find ./configure. Wrong directory or haven't run autogen.sh?" >&2 + exit 1 +fi + +if [ "x$TARGET_ARCH" = 'x' ] || [ "x$ARCH" = 'x' ] || [ "x$HOST_COMPILER" = 'x' ]; then + echo "You shouldn't use android-build.sh directly, use android-[arch].sh instead" >&2 + exit 1 +fi + +export MAKE_TOOLCHAIN="${ANDROID_NDK_HOME}/build/tools/make_standalone_toolchain.py" + +export PREFIX="$(pwd)/libsodium-android-${TARGET_ARCH}" +export TOOLCHAIN_DIR="$(pwd)/android-toolchain-${TARGET_ARCH}" +export PATH="${PATH}:${TOOLCHAIN_DIR}/bin" + +export CC=${CC:-"${HOST_COMPILER}-clang"} + +rm -rf "${TOOLCHAIN_DIR}" "${PREFIX}" + +echo +echo "Warnings related to headers being present but not usable are due to functions" +echo "that didn't exist in the specified minimum API version level." +echo "They can be safely ignored." +echo + +echo +if [ "$NDK_PLATFORM" != "$NDK_PLATFORM_COMPAT" ]; then + echo "Building for platform [${NDK_PLATFORM}], retaining compatibility with platform [${NDK_PLATFORM_COMPAT}]" +else + echo "Building for platform [${NDK_PLATFORM}]" +fi +echo + +env - PATH="$PATH" \ + "$MAKE_TOOLCHAIN" --force --api="$NDK_API_VERSION_COMPAT" \ + --arch="$ARCH" --install-dir="$TOOLCHAIN_DIR" || exit 1 + +if [ -z "$LIBSODIUM_FULL_BUILD" ]; then + export LIBSODIUM_ENABLE_MINIMAL_FLAG="--enable-minimal" +else + export LIBSODIUM_ENABLE_MINIMAL_FLAG="" +fi + +./configure \ + --disable-soname-versions \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} \ + --host="${HOST_COMPILER}" \ + --prefix="${PREFIX}" \ + --with-sysroot="${TOOLCHAIN_DIR}/sysroot" || exit 1 + +if [ "$NDK_PLATFORM" != "$NDK_PLATFORM_COMPAT" ]; then + egrep '^#define ' config.log | sort -u > config-def-compat.log + echo + echo "Configuring again for platform [${NDK_PLATFORM}]" + echo + env - PATH="$PATH" \ + "$MAKE_TOOLCHAIN" --force --api="$NDK_API_VERSION" \ + --arch="$ARCH" --install-dir="$TOOLCHAIN_DIR" || exit 1 + + ./configure \ + --disable-soname-versions \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} \ + --host="${HOST_COMPILER}" \ + --prefix="${PREFIX}" \ + --with-sysroot="${TOOLCHAIN_DIR}/sysroot" || exit 1 + + egrep '^#define ' config.log | sort -u > config-def.log + if ! cmp config-def.log config-def-compat.log; then + echo "Platform [${NDK_PLATFORM}] is not backwards-compatible with [${NDK_PLATFORM_COMPAT}]" >&2 + diff -u config-def.log config-def-compat.log >&2 + exit 1 + fi + rm -f config-def.log config-def-compat.log +fi + + +NPROCESSORS=$(getconf NPROCESSORS_ONLN 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null) +PROCESSORS=${NPROCESSORS:-3} + +make clean && \ +make -j${PROCESSORS} install && \ +echo "libsodium has been installed into ${PREFIX}" diff --git a/external/src/libsodium/dist-build/android-mips32.sh b/external/src/libsodium/dist-build/android-mips32.sh new file mode 100644 index 0000000..ab5f631 --- /dev/null +++ b/external/src/libsodium/dist-build/android-mips32.sh @@ -0,0 +1,4 @@ +#!/bin/sh +export TARGET_ARCH=mips32 +export CFLAGS="-Os" +ARCH=mips HOST_COMPILER=mipsel-linux-android "$(dirname "$0")/android-build.sh" diff --git a/external/src/libsodium/dist-build/android-mips64.sh b/external/src/libsodium/dist-build/android-mips64.sh new file mode 100644 index 0000000..75dd6ea --- /dev/null +++ b/external/src/libsodium/dist-build/android-mips64.sh @@ -0,0 +1,4 @@ +#!/bin/sh +export TARGET_ARCH=mips64r6 +export CFLAGS="-Os -march=${TARGET_ARCH}" +CC="mips64el-linux-android-gcc" NDK_PLATFORM=android-21 ARCH=mips64 HOST_COMPILER=mips64el-linux-android "$(dirname "$0")/android-build.sh" diff --git a/external/src/libsodium/dist-build/android-x86.sh b/external/src/libsodium/dist-build/android-x86.sh new file mode 100644 index 0000000..f21fe47 --- /dev/null +++ b/external/src/libsodium/dist-build/android-x86.sh @@ -0,0 +1,4 @@ +#!/bin/sh +export TARGET_ARCH=i686 +export CFLAGS="-Os -march=${TARGET_ARCH}" +ARCH=x86 HOST_COMPILER=i686-linux-android "$(dirname "$0")/android-build.sh" diff --git a/external/src/libsodium/dist-build/android-x86_64.sh b/external/src/libsodium/dist-build/android-x86_64.sh new file mode 100644 index 0000000..9f2b4f0 --- /dev/null +++ b/external/src/libsodium/dist-build/android-x86_64.sh @@ -0,0 +1,4 @@ +#!/bin/sh +export TARGET_ARCH=westmere +export CFLAGS="-Os -march=${TARGET_ARCH}" +NDK_PLATFORM=android-21 ARCH=x86_64 HOST_COMPILER=x86_64-linux-android "$(dirname "$0")/android-build.sh" diff --git a/external/src/libsodium/dist-build/apple-xcframework.sh b/external/src/libsodium/dist-build/apple-xcframework.sh new file mode 100644 index 0000000..cf86e08 --- /dev/null +++ b/external/src/libsodium/dist-build/apple-xcframework.sh @@ -0,0 +1,448 @@ +#! /bin/sh + +export PREFIX="$(pwd)/libsodium-apple" +export MACOS_ARM64_PREFIX="${PREFIX}/tmp/macos-arm64" +export MACOS_X86_64_PREFIX="${PREFIX}/tmp/macos-x86_64" +export IOS32_PREFIX="${PREFIX}/tmp/ios32" +export IOS32s_PREFIX="${PREFIX}/tmp/ios32s" +export IOS64_PREFIX="${PREFIX}/tmp/ios64" +export IOS_SIMULATOR_ARM64_PREFIX="${PREFIX}/tmp/ios-simulator-arm64" +export IOS_SIMULATOR_I386_PREFIX="${PREFIX}/tmp/ios-simulator-i386" +export IOS_SIMULATOR_X86_64_PREFIX="${PREFIX}/tmp/ios-simulator-x86_64" +export WATCHOS32_PREFIX="${PREFIX}/tmp/watchos32" +export WATCHOS64_32_PREFIX="${PREFIX}/tmp/watchos64_32" +export WATCHOS_SIMULATOR_ARM64_PREFIX="${PREFIX}/tmp/watchos-simulator-arm64" +export WATCHOS_SIMULATOR_I386_PREFIX="${PREFIX}/tmp/watchos-simulator-i386" +export WATCHOS_SIMULATOR_X86_64_PREFIX="${PREFIX}/tmp/watchos-simulator-x86_64" +export TVOS64_PREFIX="${PREFIX}/tmp/tvos64" +export TVOS_SIMULATOR_ARM64_PREFIX="${PREFIX}/tmp/tvos-simulator-arm64" +export TVOS_SIMULATOR_X86_64_PREFIX="${PREFIX}/tmp/tvos-simulator-x86_64" +export CATALYST_ARM64_PREFIX="${PREFIX}/tmp/catalyst-arm64" +export CATALYST_X86_64_PREFIX="${PREFIX}/tmp/catalyst-x86_64" +export LOG_FILE="${PREFIX}/tmp/build_log" +export XCODEDIR="$(xcode-select -p)" + +export MACOS_VERSION_MIN=${MACOS_VERSION_MIN-"10.10"} +export IOS_SIMULATOR_VERSION_MIN=${IOS_SIMULATOR_VERSION_MIN-"9.0.0"} +export IOS_VERSION_MIN=${IOS_VERSION_MIN-"9.0.0"} +export WATCHOS_SIMULATOR_VERSION_MIN=${WATCHOS_SIMULATOR_VERSION_MIN-"4.0.0"} +export WATCHOS_VERSION_MIN=${WATCHOS_VERSION_MIN-"4.0.0"} +export TVOS_SIMULATOR_VERSION_MIN=${TVOS_SIMULATOR_VERSION_MIN-"9.0.0"} +export TVOS_VERSION_MIN=${TVOS_VERSION_MIN-"9.0.0"} + +echo +echo "Warnings related to headers being present but not usable are due to functions" +echo "that didn't exist in the specified minimum iOS version level." +echo "They can be safely ignored." +echo + +if [ -z "$LIBSODIUM_FULL_BUILD" ]; then + export LIBSODIUM_ENABLE_MINIMAL_FLAG="--enable-minimal" +else + export LIBSODIUM_ENABLE_MINIMAL_FLAG="" +fi + +APPLE_SILICON_SUPPORTED=false +echo 'int main(void){return 0;}' >comptest.c && cc --target=arm64-macos comptest.c 2>/dev/null && APPLE_SILICON_SUPPORTED=true +rm -f comptest.c + +NPROCESSORS=$(getconf NPROCESSORS_ONLN 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null) +PROCESSORS=${NPROCESSORS:-3} + +swift_module_map() { + echo 'module Clibsodium {' + echo ' header "sodium.h"' + echo ' export *' + echo '}' +} + +build_macos() { + export BASEDIR="${XCODEDIR}/Platforms/MacOSX.platform/Developer" + export PATH="${BASEDIR}/usr/bin:$BASEDIR/usr/sbin:$PATH" + + ## macOS arm64 + if [ "$APPLE_SILICON_SUPPORTED" = "true" ]; then + export CFLAGS="-O2 -arch arm64 -mmacosx-version-min=${MACOS_VERSION_MIN}" + export LDFLAGS="-arch arm64 -mmacosx-version-min=${MACOS_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=arm-apple-darwin20 --prefix="$MACOS_ARM64_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 + fi + + ## macOS x86_64 + export CFLAGS="-O2 -arch x86_64 -mmacosx-version-min=${MACOS_VERSION_MIN}" + export LDFLAGS="-arch x86_64 -mmacosx-version-min=${MACOS_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=x86_64-apple-darwin10 --prefix="$MACOS_X86_64_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 +} + +build_ios() { + export BASEDIR="${XCODEDIR}/Platforms/iPhoneOS.platform/Developer" + export PATH="${BASEDIR}/usr/bin:$BASEDIR/usr/sbin:$PATH" + export SDK="${BASEDIR}/SDKs/iPhoneOS.sdk" + + ## 32-bit iOS + export CFLAGS="-fembed-bitcode -O2 -mthumb -arch armv7 -isysroot ${SDK} -mios-version-min=${IOS_VERSION_MIN}" + export LDFLAGS="-fembed-bitcode -mthumb -arch armv7 -isysroot ${SDK} -mios-version-min=${IOS_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=arm-apple-darwin10 --prefix="$IOS32_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 + + ## 32-bit armv7s iOS + export CFLAGS="-fembed-bitcode -O2 -mthumb -arch armv7s -isysroot ${SDK} -mios-version-min=${IOS_VERSION_MIN}" + export LDFLAGS="-fembed-bitcode -mthumb -arch armv7s -isysroot ${SDK} -mios-version-min=${IOS_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=arm-apple-darwin10 --prefix="$IOS32s_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 + + ## 64-bit iOS + export CFLAGS="-fembed-bitcode -O2 -arch arm64 -isysroot ${SDK} -mios-version-min=${IOS_VERSION_MIN}" + export LDFLAGS="-fembed-bitcode -arch arm64 -isysroot ${SDK} -mios-version-min=${IOS_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=arm-apple-darwin10 --prefix="$IOS64_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 +} + +build_ios_simulator() { + export BASEDIR="${XCODEDIR}/Platforms/iPhoneSimulator.platform/Developer" + export PATH="${BASEDIR}/usr/bin:$BASEDIR/usr/sbin:$PATH" + export SDK="${BASEDIR}/SDKs/iPhoneSimulator.sdk" + + ## arm64 simulator + if [ "$APPLE_SILICON_SUPPORTED" = "true" ]; then + export CFLAGS="-fembed-bitcode -O2 -arch arm64 -isysroot ${SDK} -mios-simulator-version-min=${IOS_SIMULATOR_VERSION_MIN}" + export LDFLAGS="-fembed-bitcode -arch arm64 -isysroot ${SDK} -mios-simulator-version-min=${IOS_SIMULATOR_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=arm-apple-darwin20 --prefix="$IOS_SIMULATOR_ARM64_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 + fi + + ## i386 simulator + export CFLAGS="-fembed-bitcode -O2 -arch i386 -isysroot ${SDK} -mios-simulator-version-min=${IOS_SIMULATOR_VERSION_MIN}" + export LDFLAGS="-fembed-bitcode -arch i386 -isysroot ${SDK} -mios-simulator-version-min=${IOS_SIMULATOR_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=i686-apple-darwin10 --prefix="$IOS_SIMULATOR_I386_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 + + ## x86_64 simulator + export CFLAGS="-fembed-bitcode -O2 -arch x86_64 -isysroot ${SDK} -mios-simulator-version-min=${IOS_SIMULATOR_VERSION_MIN}" + export LDFLAGS="-fembed-bitcode -arch x86_64 -isysroot ${SDK} -mios-simulator-version-min=${IOS_SIMULATOR_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=x86_64-apple-darwin10 --prefix="$IOS_SIMULATOR_X86_64_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} + make -j${PROCESSORS} install || exit 1 +} + +build_watchos() { + export BASEDIR="${XCODEDIR}/Platforms/WatchOS.platform/Developer" + export PATH="${BASEDIR}/usr/bin:$BASEDIR/usr/sbin:$PATH" + export SDK="${BASEDIR}/SDKs/WatchOS.sdk" + + # 32-bit watchOS + export CFLAGS="-fembed-bitcode -O2 -mthumb -arch armv7k -isysroot ${SDK} -mwatchos-version-min=${WATCHOS_VERSION_MIN}" + export LDFLAGS="-fembed-bitcode -mthumb -arch armv7k -isysroot ${SDK} -mwatchos-version-min=${WATCHOS_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=arm-apple-darwin10 --prefix="$WATCHOS32_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 + + ## 64-bit arm64_32 watchOS + export CFLAGS="-fembed-bitcode -O2 -mthumb -arch arm64_32 -isysroot ${SDK} -mwatchos-version-min=${WATCHOS_VERSION_MIN}" + export LDFLAGS="-fembed-bitcode -mthumb -arch arm64_32 -isysroot ${SDK} -mwatchos-version-min=${WATCHOS_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=arm-apple-darwin10 --prefix="$WATCHOS64_32_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 +} + +build_watchos_simulator() { + export BASEDIR="${XCODEDIR}/Platforms/WatchSimulator.platform/Developer" + export PATH="${BASEDIR}/usr/bin:$BASEDIR/usr/sbin:$PATH" + export SDK="${BASEDIR}/SDKs/WatchSimulator.sdk" + + ## arm64 simulator + if [ "$APPLE_SILICON_SUPPORTED" = "true" ]; then + export CFLAGS="-fembed-bitcode -O2 -arch arm64 -isysroot ${SDK} -mwatchos-simulator-version-min=${WATCHOS_SIMULATOR_VERSION_MIN}" + export LDFLAGS="-fembed-bitcode -arch arm64 -isysroot ${SDK} -mwatchos-simulator-version-min=${WATCHOS_SIMULATOR_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=arm-apple-darwin20 --prefix="$WATCHOS_SIMULATOR_ARM64_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 + fi + + ## i386 simulator + export CFLAGS="-fembed-bitcode -O2 -arch i386 -isysroot ${SDK} -mwatchos-simulator-version-min=${WATCHOS_SIMULATOR_VERSION_MIN}" + export LDFLAGS="-fembed-bitcode -arch i386 -isysroot ${SDK} -mwatchos-simulator-version-min=${WATCHOS_SIMULATOR_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=i686-apple-darwin10 --prefix="$WATCHOS_SIMULATOR_I386_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 + + ## x86_64 simulator + export CFLAGS="-fembed-bitcode -O2 -arch x86_64 -isysroot ${SDK} -mwatchos-simulator-version-min=${WATCHOS_SIMULATOR_VERSION_MIN}" + export LDFLAGS="-fembed-bitcode -arch x86_64 -isysroot ${SDK} -mwatchos-simulator-version-min=${WATCHOS_SIMULATOR_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=x86_64-apple-darwin10 --prefix="$WATCHOS_SIMULATOR_X86_64_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 +} + +build_tvos() { + export BASEDIR="${XCODEDIR}/Platforms/AppleTVOS.platform/Developer" + export PATH="${BASEDIR}/usr/bin:$BASEDIR/usr/sbin:$PATH" + export SDK="${BASEDIR}/SDKs/AppleTVOS.sdk" + + ## 64-bit tvOS + export CFLAGS="-fembed-bitcode -O2 -arch arm64 -isysroot ${SDK} -mtvos-version-min=${TVOS_VERSION_MIN}" + export LDFLAGS="-fembed-bitcode -arch arm64 -isysroot ${SDK} -mtvos-version-min=${TVOS_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=arm-apple-darwin10 --prefix="$TVOS64_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 +} + +build_tvos_simulator() { + export BASEDIR="${XCODEDIR}/Platforms/AppleTVSimulator.platform/Developer" + export PATH="${BASEDIR}/usr/bin:$BASEDIR/usr/sbin:$PATH" + export SDK="${BASEDIR}/SDKs/AppleTVSimulator.sdk" + + ## arm64 simulator + if [ "$APPLE_SILICON_SUPPORTED" = "true" ]; then + export CFLAGS="-fembed-bitcode -O2 -arch arm64 -isysroot ${SDK} -mtvos-simulator-version-min=${TVOS_SIMULATOR_VERSION_MIN}" + export LDFLAGS="-fembed-bitcode -arch arm64 -isysroot ${SDK} -mtvos-simulator-version-min=${TVOS_SIMULATOR_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=arm-apple-darwin20 --prefix="$TVOS_SIMULATOR_ARM64_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 + fi + + ## x86_64 simulator + export CFLAGS="-fembed-bitcode -O2 -arch x86_64 -isysroot ${SDK} -mtvos-simulator-version-min=${TVOS_SIMULATOR_VERSION_MIN}" + export LDFLAGS="-fembed-bitcode -arch x86_64 -isysroot ${SDK} -mtvos-simulator-version-min=${TVOS_SIMULATOR_VERSION_MIN}" + + make distclean >/dev/null 2>&1 + ./configure --host=x86_64-apple-darwin10 --prefix="$TVOS_SIMULATOR_X86_64_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} + make -j${PROCESSORS} install || exit 1 +} + +build_catalyst() { + export BASEDIR="${XCODEDIR}/Platforms/MacOSX.platform/Developer" + export PATH="${BASEDIR}/usr/bin:$BASEDIR/usr/sbin:$PATH" + export SDK="${BASEDIR}/SDKs/MacOSX.sdk" + + ## arm64 catalyst + if [ "$APPLE_SILICON_SUPPORTED" = "true" ]; then + export CFLAGS="-O2 -arch arm64 -target arm64-apple-ios13.0-macabi -isysroot ${SDK}" + export LDFLAGS="-arch arm64 -target arm64-apple-ios13.0-macabi -isysroot ${SDK}" + + make distclean >/dev/null 2>&1 + ./configure --host=arm-apple-ios --prefix="$CATALYST_ARM64_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 + fi + + ## x86_64 catalyst + export CFLAGS="-O2 -arch x86_64 -target x86_64-apple-ios13.0-macabi -isysroot ${SDK}" + export LDFLAGS="-arch x86_64 -target x86_64-apple-ios13.0-macabi -isysroot ${SDK}" + + make distclean >/dev/null 2>&1 + ./configure --host=x86_64-apple-ios --prefix="$CATALYST_X86_64_PREFIX" \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} || exit 1 + make -j${PROCESSORS} install || exit 1 +} + +mkdir -p "${PREFIX}/tmp" +echo "Building for macOS..." +build_macos >"$LOG_FILE" 2>&1 || exit 1 +echo "Building for iOS..." +build_ios >"$LOG_FILE" 2>&1 || exit 1 +echo "Building for the iOS simulator..." +build_ios_simulator >"$LOG_FILE" 2>&1 || exit 1 +echo "Building for watchOS..." +build_watchos >"$LOG_FILE" 2>&1 || exit 1 +echo "Building for the watchOS simulator..." +build_watchos_simulator >"$LOG_FILE" 2>&1 || exit 1 +echo "Building for tvOS..." +build_tvos >"$LOG_FILE" 2>&1 || exit 1 +echo "Building for the tvOS simulator..." +build_tvos_simulator >"$LOG_FILE" 2>&1 || exit 1 +echo "Building for Catalyst..." +build_catalyst >"$LOG_FILE" 2>&1 || exit 1 + +echo "Adding the Clibsodium module map for Swift..." + +find "$PREFIX" -name "include" -type d -print | while read -r f; do + swift_module_map >"${f}/module.modulemap" +done + +echo "Bundling macOS targets..." + +mkdir -p "${PREFIX}/macos/lib" +cp -a "${MACOS_X86_64_PREFIX}/include" "${PREFIX}/macos/" +for ext in a dylib; do + if [ "$APPLE_SILICON_SUPPORTED" = "true" ]; then + lipo -create \ + "${MACOS_ARM64_PREFIX}/lib/libsodium.${ext}" \ + "${MACOS_X86_64_PREFIX}/lib/libsodium.${ext}" \ + -output "${PREFIX}/macos/lib/libsodium.${ext}" + else + lipo -create \ + "${MACOS_X86_64_PREFIX}/lib/libsodium.${ext}" \ + -output "${PREFIX}/macos/lib/libsodium.${ext}" + fi +done + +echo "Bundling iOS targets..." + +mkdir -p "${PREFIX}/ios/lib" +cp -a "${IOS64_PREFIX}/include" "${PREFIX}/ios/" +for ext in a dylib; do + lipo -create \ + "$IOS32_PREFIX/lib/libsodium.${ext}" \ + "$IOS32s_PREFIX/lib/libsodium.${ext}" \ + "$IOS64_PREFIX/lib/libsodium.${ext}" \ + -output "$PREFIX/ios/lib/libsodium.${ext}" +done + +echo "Bundling iOS simulators..." + +mkdir -p "${PREFIX}/ios-simulators/lib" +cp -a "${IOS_SIMULATOR_X86_64_PREFIX}/include" "${PREFIX}/ios-simulators/" +for ext in a dylib; do + if [ "$APPLE_SILICON_SUPPORTED" = "true" ]; then + lipo -create \ + "${IOS_SIMULATOR_ARM64_PREFIX}/lib/libsodium.${ext}" \ + "${IOS_SIMULATOR_I386_PREFIX}/lib/libsodium.${ext}" \ + "${IOS_SIMULATOR_X86_64_PREFIX}/lib/libsodium.${ext}" \ + -output "${PREFIX}/ios-simulators/lib/libsodium.${ext}" || exit 1 + else + lipo -create \ + "${IOS_SIMULATOR_I386_PREFIX}/lib/libsodium.${ext}" \ + "${IOS_SIMULATOR_X86_64_PREFIX}/lib/libsodium.${ext}" \ + -output "${PREFIX}/ios-simulators/lib/libsodium.${ext}" || exit 1 + fi +done + +echo "Bundling watchOS targets..." + +mkdir -p "${PREFIX}/watchos/lib" +cp -a "${WATCHOS64_32_PREFIX}/include" "${PREFIX}/watchos/" +for ext in a dylib; do + lipo -create \ + "${WATCHOS32_PREFIX}/lib/libsodium.${ext}" \ + "${WATCHOS64_32_PREFIX}/lib/libsodium.${ext}" \ + -output "${PREFIX}/watchos/lib/libsodium.${ext}" +done + +echo "Bundling watchOS simulators..." + +mkdir -p "${PREFIX}/watchos-simulators/lib" +cp -a "${WATCHOS_SIMULATOR_X86_64_PREFIX}/include" "${PREFIX}/watchos-simulators/" +for ext in a dylib; do + if [ "$APPLE_SILICON_SUPPORTED" = "true" ]; then + lipo -create \ + "${WATCHOS_SIMULATOR_ARM64_PREFIX}/lib/libsodium.${ext}" \ + "${WATCHOS_SIMULATOR_I386_PREFIX}/lib/libsodium.${ext}" \ + "${WATCHOS_SIMULATOR_X86_64_PREFIX}/lib/libsodium.${ext}" \ + -output "${PREFIX}/watchos-simulators/lib/libsodium.${ext}" + else + lipo -create \ + "${WATCHOS_SIMULATOR_I386_PREFIX}/lib/libsodium.${ext}" \ + "${WATCHOS_SIMULATOR_X86_64_PREFIX}/lib/libsodium.${ext}" \ + -output "${PREFIX}/watchos-simulators/lib/libsodium.${ext}" + fi +done + +echo "Bundling tvOS targets..." + +mkdir -p "${PREFIX}/tvos/lib" +cp -a "${TVOS64_PREFIX}/include" "${PREFIX}/tvos/" +for ext in a dylib; do + lipo -create \ + "$TVOS64_PREFIX/lib/libsodium.${ext}" \ + -output "$PREFIX/tvos/lib/libsodium.${ext}" +done + +echo "Bundling tvOS simulators..." + +mkdir -p "${PREFIX}/tvos-simulators/lib" +cp -a "${TVOS_SIMULATOR_X86_64_PREFIX}/include" "${PREFIX}/tvos-simulators/" +for ext in a dylib; do + if [ "$APPLE_SILICON_SUPPORTED" = "true" ]; then + lipo -create \ + "${TVOS_SIMULATOR_ARM64_PREFIX}/lib/libsodium.${ext}" \ + "${TVOS_SIMULATOR_X86_64_PREFIX}/lib/libsodium.${ext}" \ + -output "${PREFIX}/tvos-simulators/lib/libsodium.${ext}" || exit 1 + else + lipo -create \ + "${TVOS_SIMULATOR_X86_64_PREFIX}/lib/libsodium.${ext}" \ + -output "${PREFIX}/tvos-simulators/lib/libsodium.${ext}" || exit 1 + fi +done + +echo "Bundling Catalyst targets..." + +mkdir -p "${PREFIX}/catalyst/lib" +cp -a "${CATALYST_X86_64_PREFIX}/include" "${PREFIX}/catalyst/" +for ext in a dylib; do + if [ ! -f "${CATALYST_X86_64_PREFIX}/lib/libsodium.${ext}" ]; then + continue + fi + if [ "$APPLE_SILICON_SUPPORTED" = "true" ]; then + lipo -create \ + "${CATALYST_ARM64_PREFIX}/lib/libsodium.${ext}" \ + "${CATALYST_X86_64_PREFIX}/lib/libsodium.${ext}" \ + -output "${PREFIX}/catalyst/lib/libsodium.${ext}" + else + lipo -create \ + "${CATALYST_X86_64_PREFIX}/lib/libsodium.${ext}" \ + -output "${PREFIX}/catalyst/lib/libsodium.${ext}" + fi +done + +echo "Creating Clibsodium.xcframework..." + +rm -rf "${PREFIX}/Clibsodium.xcframework" + +XCFRAMEWORK_ARGS="" +for f in macos ios ios-simulators watchos watchos-simulators tvos tvos-simulators catalyst; do + XCFRAMEWORK_ARGS="${XCFRAMEWORK_ARGS} -library ${PREFIX}/${f}/lib/libsodium.a" + XCFRAMEWORK_ARGS="${XCFRAMEWORK_ARGS} -headers ${PREFIX}/${f}/include" +done +xcodebuild -create-xcframework \ + ${XCFRAMEWORK_ARGS} \ + -output "${PREFIX}/Clibsodium.xcframework" >/dev/null + +ls -ld -- "$PREFIX" +ls -l -- "$PREFIX" +ls -l -- "$PREFIX/Clibsodium.xcframework" + +echo "Done!" + +# Cleanup +rm -rf -- "$PREFIX/tmp" +make distclean >/dev/null diff --git a/external/src/libsodium/dist-build/emscripten-symbols.def b/external/src/libsodium/dist-build/emscripten-symbols.def new file mode 100644 index 0000000..b1761c5 --- /dev/null +++ b/external/src/libsodium/dist-build/emscripten-symbols.def @@ -0,0 +1,608 @@ +_crypto_aead_aes256gcm_abytes 0 0 +_crypto_aead_aes256gcm_beforenm 0 0 +_crypto_aead_aes256gcm_decrypt 0 0 +_crypto_aead_aes256gcm_decrypt_afternm 0 0 +_crypto_aead_aes256gcm_decrypt_detached 0 0 +_crypto_aead_aes256gcm_decrypt_detached_afternm 0 0 +_crypto_aead_aes256gcm_encrypt 0 0 +_crypto_aead_aes256gcm_encrypt_afternm 0 0 +_crypto_aead_aes256gcm_encrypt_detached 0 0 +_crypto_aead_aes256gcm_encrypt_detached_afternm 0 0 +_crypto_aead_aes256gcm_is_available 0 0 +_crypto_aead_aes256gcm_keybytes 0 0 +_crypto_aead_aes256gcm_keygen 0 0 +_crypto_aead_aes256gcm_messagebytes_max 0 0 +_crypto_aead_aes256gcm_npubbytes 0 0 +_crypto_aead_aes256gcm_nsecbytes 0 0 +_crypto_aead_aes256gcm_statebytes 0 0 +_crypto_aead_chacha20poly1305_abytes 1 1 +_crypto_aead_chacha20poly1305_decrypt 1 1 +_crypto_aead_chacha20poly1305_decrypt_detached 1 1 +_crypto_aead_chacha20poly1305_encrypt 1 1 +_crypto_aead_chacha20poly1305_encrypt_detached 1 1 +_crypto_aead_chacha20poly1305_ietf_abytes 1 1 +_crypto_aead_chacha20poly1305_ietf_decrypt 1 1 +_crypto_aead_chacha20poly1305_ietf_decrypt_detached 1 1 +_crypto_aead_chacha20poly1305_ietf_encrypt 1 1 +_crypto_aead_chacha20poly1305_ietf_encrypt_detached 1 1 +_crypto_aead_chacha20poly1305_ietf_keybytes 1 1 +_crypto_aead_chacha20poly1305_ietf_keygen 1 1 +_crypto_aead_chacha20poly1305_ietf_messagebytes_max 1 1 +_crypto_aead_chacha20poly1305_ietf_npubbytes 1 1 +_crypto_aead_chacha20poly1305_ietf_nsecbytes 1 1 +_crypto_aead_chacha20poly1305_keybytes 1 1 +_crypto_aead_chacha20poly1305_keygen 1 1 +_crypto_aead_chacha20poly1305_messagebytes_max 1 1 +_crypto_aead_chacha20poly1305_npubbytes 1 1 +_crypto_aead_chacha20poly1305_nsecbytes 1 1 +_crypto_aead_xchacha20poly1305_ietf_abytes 1 1 +_crypto_aead_xchacha20poly1305_ietf_decrypt 1 1 +_crypto_aead_xchacha20poly1305_ietf_decrypt_detached 1 1 +_crypto_aead_xchacha20poly1305_ietf_encrypt 1 1 +_crypto_aead_xchacha20poly1305_ietf_encrypt_detached 1 1 +_crypto_aead_xchacha20poly1305_ietf_keybytes 1 1 +_crypto_aead_xchacha20poly1305_ietf_keygen 1 1 +_crypto_aead_xchacha20poly1305_ietf_messagebytes_max 1 1 +_crypto_aead_xchacha20poly1305_ietf_npubbytes 1 1 +_crypto_aead_xchacha20poly1305_ietf_nsecbytes 1 1 +_crypto_auth 1 1 +_crypto_auth_bytes 1 1 +_crypto_auth_hmacsha256 0 1 +_crypto_auth_hmacsha256_bytes 0 1 +_crypto_auth_hmacsha256_final 0 1 +_crypto_auth_hmacsha256_init 0 1 +_crypto_auth_hmacsha256_keybytes 0 1 +_crypto_auth_hmacsha256_keygen 0 1 +_crypto_auth_hmacsha256_statebytes 0 1 +_crypto_auth_hmacsha256_update 0 1 +_crypto_auth_hmacsha256_verify 0 1 +_crypto_auth_hmacsha512 0 1 +_crypto_auth_hmacsha512256 0 1 +_crypto_auth_hmacsha512256_bytes 0 1 +_crypto_auth_hmacsha512256_final 0 1 +_crypto_auth_hmacsha512256_init 0 1 +_crypto_auth_hmacsha512256_keybytes 0 1 +_crypto_auth_hmacsha512256_keygen 0 1 +_crypto_auth_hmacsha512256_statebytes 0 1 +_crypto_auth_hmacsha512256_update 0 1 +_crypto_auth_hmacsha512256_verify 0 1 +_crypto_auth_hmacsha512_bytes 0 1 +_crypto_auth_hmacsha512_final 0 1 +_crypto_auth_hmacsha512_init 0 1 +_crypto_auth_hmacsha512_keybytes 0 1 +_crypto_auth_hmacsha512_keygen 0 1 +_crypto_auth_hmacsha512_statebytes 0 1 +_crypto_auth_hmacsha512_update 0 1 +_crypto_auth_hmacsha512_verify 0 1 +_crypto_auth_keybytes 1 1 +_crypto_auth_keygen 1 1 +_crypto_auth_primitive 0 1 +_crypto_auth_verify 1 1 +_crypto_box 0 1 +_crypto_box_afternm 0 1 +_crypto_box_beforenm 1 1 +_crypto_box_beforenmbytes 1 1 +_crypto_box_boxzerobytes 0 1 +_crypto_box_curve25519xchacha20poly1305_beforenm 0 1 +_crypto_box_curve25519xchacha20poly1305_beforenmbytes 0 1 +_crypto_box_curve25519xchacha20poly1305_detached 0 1 +_crypto_box_curve25519xchacha20poly1305_detached_afternm 0 1 +_crypto_box_curve25519xchacha20poly1305_easy 0 1 +_crypto_box_curve25519xchacha20poly1305_easy_afternm 0 1 +_crypto_box_curve25519xchacha20poly1305_keypair 0 1 +_crypto_box_curve25519xchacha20poly1305_macbytes 0 1 +_crypto_box_curve25519xchacha20poly1305_messagebytes_max 0 1 +_crypto_box_curve25519xchacha20poly1305_noncebytes 0 1 +_crypto_box_curve25519xchacha20poly1305_open_detached 0 1 +_crypto_box_curve25519xchacha20poly1305_open_detached_afternm 0 1 +_crypto_box_curve25519xchacha20poly1305_open_easy 0 1 +_crypto_box_curve25519xchacha20poly1305_open_easy_afternm 0 1 +_crypto_box_curve25519xchacha20poly1305_publickeybytes 0 1 +_crypto_box_curve25519xchacha20poly1305_seal 0 1 +_crypto_box_curve25519xchacha20poly1305_seal_open 0 1 +_crypto_box_curve25519xchacha20poly1305_sealbytes 0 1 +_crypto_box_curve25519xchacha20poly1305_secretkeybytes 0 1 +_crypto_box_curve25519xchacha20poly1305_seed_keypair 0 1 +_crypto_box_curve25519xchacha20poly1305_seedbytes 0 1 +_crypto_box_curve25519xsalsa20poly1305 0 1 +_crypto_box_curve25519xsalsa20poly1305_afternm 0 1 +_crypto_box_curve25519xsalsa20poly1305_beforenm 0 1 +_crypto_box_curve25519xsalsa20poly1305_beforenmbytes 0 1 +_crypto_box_curve25519xsalsa20poly1305_boxzerobytes 0 1 +_crypto_box_curve25519xsalsa20poly1305_keypair 0 1 +_crypto_box_curve25519xsalsa20poly1305_macbytes 0 1 +_crypto_box_curve25519xsalsa20poly1305_messagebytes_max 0 1 +_crypto_box_curve25519xsalsa20poly1305_noncebytes 0 1 +_crypto_box_curve25519xsalsa20poly1305_open 0 1 +_crypto_box_curve25519xsalsa20poly1305_open_afternm 0 1 +_crypto_box_curve25519xsalsa20poly1305_publickeybytes 0 1 +_crypto_box_curve25519xsalsa20poly1305_secretkeybytes 0 1 +_crypto_box_curve25519xsalsa20poly1305_seed_keypair 0 1 +_crypto_box_curve25519xsalsa20poly1305_seedbytes 0 1 +_crypto_box_curve25519xsalsa20poly1305_zerobytes 0 1 +_crypto_box_detached 1 1 +_crypto_box_detached_afternm 1 1 +_crypto_box_easy 1 1 +_crypto_box_easy_afternm 1 1 +_crypto_box_keypair 1 1 +_crypto_box_macbytes 1 1 +_crypto_box_messagebytes_max 1 1 +_crypto_box_noncebytes 1 1 +_crypto_box_open 0 1 +_crypto_box_open_afternm 0 1 +_crypto_box_open_detached 1 1 +_crypto_box_open_detached_afternm 1 1 +_crypto_box_open_easy 1 1 +_crypto_box_open_easy_afternm 1 1 +_crypto_box_primitive 0 1 +_crypto_box_publickeybytes 1 1 +_crypto_box_seal 1 1 +_crypto_box_seal_open 1 1 +_crypto_box_sealbytes 1 1 +_crypto_box_secretkeybytes 1 1 +_crypto_box_seed_keypair 1 1 +_crypto_box_seedbytes 1 1 +_crypto_box_zerobytes 0 1 +_crypto_core_ed25519_add 0 1 +_crypto_core_ed25519_bytes 0 1 +_crypto_core_ed25519_from_hash 0 1 +_crypto_core_ed25519_from_uniform 0 1 +_crypto_core_ed25519_hashbytes 0 1 +_crypto_core_ed25519_is_valid_point 0 1 +_crypto_core_ed25519_nonreducedscalarbytes 0 1 +_crypto_core_ed25519_random 0 1 +_crypto_core_ed25519_scalar_add 0 1 +_crypto_core_ed25519_scalar_complement 0 1 +_crypto_core_ed25519_scalar_invert 0 1 +_crypto_core_ed25519_scalar_mul 0 1 +_crypto_core_ed25519_scalar_negate 0 1 +_crypto_core_ed25519_scalar_random 0 1 +_crypto_core_ed25519_scalar_reduce 0 1 +_crypto_core_ed25519_scalar_sub 0 1 +_crypto_core_ed25519_scalarbytes 0 1 +_crypto_core_ed25519_sub 0 1 +_crypto_core_ed25519_uniformbytes 0 1 +_crypto_core_hchacha20 0 1 +_crypto_core_hchacha20_constbytes 0 1 +_crypto_core_hchacha20_inputbytes 0 1 +_crypto_core_hchacha20_keybytes 0 1 +_crypto_core_hchacha20_outputbytes 0 1 +_crypto_core_hsalsa20 0 1 +_crypto_core_hsalsa20_constbytes 0 1 +_crypto_core_hsalsa20_inputbytes 0 1 +_crypto_core_hsalsa20_keybytes 0 1 +_crypto_core_hsalsa20_outputbytes 0 1 +_crypto_core_ristretto255_add 0 1 +_crypto_core_ristretto255_bytes 0 1 +_crypto_core_ristretto255_from_hash 0 1 +_crypto_core_ristretto255_hashbytes 0 1 +_crypto_core_ristretto255_is_valid_point 0 1 +_crypto_core_ristretto255_nonreducedscalarbytes 0 1 +_crypto_core_ristretto255_random 0 1 +_crypto_core_ristretto255_scalar_add 0 1 +_crypto_core_ristretto255_scalar_complement 0 1 +_crypto_core_ristretto255_scalar_invert 0 1 +_crypto_core_ristretto255_scalar_mul 0 1 +_crypto_core_ristretto255_scalar_negate 0 1 +_crypto_core_ristretto255_scalar_random 0 1 +_crypto_core_ristretto255_scalar_reduce 0 1 +_crypto_core_ristretto255_scalar_sub 0 1 +_crypto_core_ristretto255_scalarbytes 0 1 +_crypto_core_ristretto255_sub 0 1 +_crypto_core_ristretto255_uniformbytes 0 1 +_crypto_core_salsa20 0 1 +_crypto_core_salsa2012 0 1 +_crypto_core_salsa2012_constbytes 0 1 +_crypto_core_salsa2012_inputbytes 0 1 +_crypto_core_salsa2012_keybytes 0 1 +_crypto_core_salsa2012_outputbytes 0 1 +_crypto_core_salsa208 0 1 +_crypto_core_salsa208_constbytes 0 1 +_crypto_core_salsa208_inputbytes 0 1 +_crypto_core_salsa208_keybytes 0 1 +_crypto_core_salsa208_outputbytes 0 1 +_crypto_core_salsa20_constbytes 0 1 +_crypto_core_salsa20_inputbytes 0 1 +_crypto_core_salsa20_keybytes 0 1 +_crypto_core_salsa20_outputbytes 0 1 +_crypto_generichash 1 1 +_crypto_generichash_blake2b 0 1 +_crypto_generichash_blake2b_bytes 0 1 +_crypto_generichash_blake2b_bytes_max 0 1 +_crypto_generichash_blake2b_bytes_min 0 1 +_crypto_generichash_blake2b_final 0 1 +_crypto_generichash_blake2b_init 0 1 +_crypto_generichash_blake2b_init_salt_personal 0 1 +_crypto_generichash_blake2b_keybytes 0 1 +_crypto_generichash_blake2b_keybytes_max 0 1 +_crypto_generichash_blake2b_keybytes_min 0 1 +_crypto_generichash_blake2b_keygen 0 1 +_crypto_generichash_blake2b_personalbytes 0 1 +_crypto_generichash_blake2b_salt_personal 0 1 +_crypto_generichash_blake2b_saltbytes 0 1 +_crypto_generichash_blake2b_statebytes 0 1 +_crypto_generichash_blake2b_update 0 1 +_crypto_generichash_bytes 1 1 +_crypto_generichash_bytes_max 1 1 +_crypto_generichash_bytes_min 1 1 +_crypto_generichash_final 1 1 +_crypto_generichash_init 1 1 +_crypto_generichash_keybytes 1 1 +_crypto_generichash_keybytes_max 1 1 +_crypto_generichash_keybytes_min 1 1 +_crypto_generichash_keygen 1 1 +_crypto_generichash_primitive 0 1 +_crypto_generichash_statebytes 1 1 +_crypto_generichash_update 1 1 +_crypto_hash 1 1 +_crypto_hash_bytes 1 1 +_crypto_hash_primitive 0 1 +_crypto_hash_sha256 0 1 +_crypto_hash_sha256_bytes 0 1 +_crypto_hash_sha256_final 0 1 +_crypto_hash_sha256_init 0 1 +_crypto_hash_sha256_statebytes 0 1 +_crypto_hash_sha256_update 0 1 +_crypto_hash_sha512 0 1 +_crypto_hash_sha512_bytes 0 1 +_crypto_hash_sha512_final 0 1 +_crypto_hash_sha512_init 0 1 +_crypto_hash_sha512_statebytes 0 1 +_crypto_hash_sha512_update 0 1 +_crypto_kdf_blake2b_bytes_max 0 1 +_crypto_kdf_blake2b_bytes_min 0 1 +_crypto_kdf_blake2b_contextbytes 0 1 +_crypto_kdf_blake2b_derive_from_key 0 1 +_crypto_kdf_blake2b_keybytes 0 1 +_crypto_kdf_bytes_max 1 1 +_crypto_kdf_bytes_min 1 1 +_crypto_kdf_contextbytes 1 1 +_crypto_kdf_derive_from_key 1 1 +_crypto_kdf_keybytes 1 1 +_crypto_kdf_keygen 1 1 +_crypto_kdf_primitive 0 1 +_crypto_kx_client_session_keys 1 1 +_crypto_kx_keypair 1 1 +_crypto_kx_primitive 0 1 +_crypto_kx_publickeybytes 1 1 +_crypto_kx_secretkeybytes 1 1 +_crypto_kx_seed_keypair 1 1 +_crypto_kx_seedbytes 1 1 +_crypto_kx_server_session_keys 1 1 +_crypto_kx_sessionkeybytes 1 1 +_crypto_onetimeauth 0 1 +_crypto_onetimeauth_bytes 0 1 +_crypto_onetimeauth_final 0 1 +_crypto_onetimeauth_init 0 1 +_crypto_onetimeauth_keybytes 0 1 +_crypto_onetimeauth_keygen 0 1 +_crypto_onetimeauth_poly1305 0 1 +_crypto_onetimeauth_poly1305_bytes 0 1 +_crypto_onetimeauth_poly1305_final 0 1 +_crypto_onetimeauth_poly1305_init 0 1 +_crypto_onetimeauth_poly1305_keybytes 0 1 +_crypto_onetimeauth_poly1305_keygen 0 1 +_crypto_onetimeauth_poly1305_statebytes 0 1 +_crypto_onetimeauth_poly1305_update 0 1 +_crypto_onetimeauth_poly1305_verify 0 1 +_crypto_onetimeauth_primitive 0 1 +_crypto_onetimeauth_statebytes 0 1 +_crypto_onetimeauth_update 0 1 +_crypto_onetimeauth_verify 0 1 +_crypto_pwhash 1 1 +_crypto_pwhash_alg_argon2i13 1 1 +_crypto_pwhash_alg_argon2id13 1 1 +_crypto_pwhash_alg_default 1 1 +_crypto_pwhash_argon2i 0 1 +_crypto_pwhash_argon2i_alg_argon2i13 0 1 +_crypto_pwhash_argon2i_bytes_max 0 1 +_crypto_pwhash_argon2i_bytes_min 0 1 +_crypto_pwhash_argon2i_memlimit_interactive 0 1 +_crypto_pwhash_argon2i_memlimit_max 0 1 +_crypto_pwhash_argon2i_memlimit_min 0 1 +_crypto_pwhash_argon2i_memlimit_moderate 0 1 +_crypto_pwhash_argon2i_memlimit_sensitive 0 1 +_crypto_pwhash_argon2i_opslimit_interactive 0 1 +_crypto_pwhash_argon2i_opslimit_max 0 1 +_crypto_pwhash_argon2i_opslimit_min 0 1 +_crypto_pwhash_argon2i_opslimit_moderate 0 1 +_crypto_pwhash_argon2i_opslimit_sensitive 0 1 +_crypto_pwhash_argon2i_passwd_max 0 1 +_crypto_pwhash_argon2i_passwd_min 0 1 +_crypto_pwhash_argon2i_saltbytes 0 1 +_crypto_pwhash_argon2i_str 0 1 +_crypto_pwhash_argon2i_str_needs_rehash 0 1 +_crypto_pwhash_argon2i_str_verify 0 1 +_crypto_pwhash_argon2i_strbytes 0 1 +_crypto_pwhash_argon2i_strprefix 0 1 +_crypto_pwhash_argon2id 0 1 +_crypto_pwhash_argon2id_alg_argon2id13 0 1 +_crypto_pwhash_argon2id_bytes_max 0 1 +_crypto_pwhash_argon2id_bytes_min 0 1 +_crypto_pwhash_argon2id_memlimit_interactive 0 1 +_crypto_pwhash_argon2id_memlimit_max 0 1 +_crypto_pwhash_argon2id_memlimit_min 0 1 +_crypto_pwhash_argon2id_memlimit_moderate 0 1 +_crypto_pwhash_argon2id_memlimit_sensitive 0 1 +_crypto_pwhash_argon2id_opslimit_interactive 0 1 +_crypto_pwhash_argon2id_opslimit_max 0 1 +_crypto_pwhash_argon2id_opslimit_min 0 1 +_crypto_pwhash_argon2id_opslimit_moderate 0 1 +_crypto_pwhash_argon2id_opslimit_sensitive 0 1 +_crypto_pwhash_argon2id_passwd_max 0 1 +_crypto_pwhash_argon2id_passwd_min 0 1 +_crypto_pwhash_argon2id_saltbytes 0 1 +_crypto_pwhash_argon2id_str 0 1 +_crypto_pwhash_argon2id_str_needs_rehash 0 1 +_crypto_pwhash_argon2id_str_verify 0 1 +_crypto_pwhash_argon2id_strbytes 0 1 +_crypto_pwhash_argon2id_strprefix 0 1 +_crypto_pwhash_bytes_max 1 1 +_crypto_pwhash_bytes_min 1 1 +_crypto_pwhash_memlimit_interactive 1 1 +_crypto_pwhash_memlimit_max 1 1 +_crypto_pwhash_memlimit_min 1 1 +_crypto_pwhash_memlimit_moderate 1 1 +_crypto_pwhash_memlimit_sensitive 1 1 +_crypto_pwhash_opslimit_interactive 1 1 +_crypto_pwhash_opslimit_max 1 1 +_crypto_pwhash_opslimit_min 1 1 +_crypto_pwhash_opslimit_moderate 1 1 +_crypto_pwhash_opslimit_sensitive 1 1 +_crypto_pwhash_passwd_max 1 1 +_crypto_pwhash_passwd_min 1 1 +_crypto_pwhash_primitive 0 1 +_crypto_pwhash_saltbytes 1 1 +_crypto_pwhash_scryptsalsa208sha256 0 1 +_crypto_pwhash_scryptsalsa208sha256_bytes_max 0 1 +_crypto_pwhash_scryptsalsa208sha256_bytes_min 0 1 +_crypto_pwhash_scryptsalsa208sha256_ll 0 1 +_crypto_pwhash_scryptsalsa208sha256_memlimit_interactive 0 1 +_crypto_pwhash_scryptsalsa208sha256_memlimit_max 0 1 +_crypto_pwhash_scryptsalsa208sha256_memlimit_min 0 1 +_crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive 0 1 +_crypto_pwhash_scryptsalsa208sha256_opslimit_interactive 0 1 +_crypto_pwhash_scryptsalsa208sha256_opslimit_max 0 1 +_crypto_pwhash_scryptsalsa208sha256_opslimit_min 0 1 +_crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive 0 1 +_crypto_pwhash_scryptsalsa208sha256_passwd_max 0 1 +_crypto_pwhash_scryptsalsa208sha256_passwd_min 0 1 +_crypto_pwhash_scryptsalsa208sha256_saltbytes 0 1 +_crypto_pwhash_scryptsalsa208sha256_str 0 1 +_crypto_pwhash_scryptsalsa208sha256_str_needs_rehash 0 1 +_crypto_pwhash_scryptsalsa208sha256_str_verify 0 1 +_crypto_pwhash_scryptsalsa208sha256_strbytes 0 1 +_crypto_pwhash_scryptsalsa208sha256_strprefix 0 1 +_crypto_pwhash_str 1 1 +_crypto_pwhash_str_alg 1 1 +_crypto_pwhash_str_needs_rehash 1 1 +_crypto_pwhash_str_verify 1 1 +_crypto_pwhash_strbytes 1 1 +_crypto_pwhash_strprefix 1 1 +_crypto_scalarmult 1 1 +_crypto_scalarmult_base 1 1 +_crypto_scalarmult_bytes 1 1 +_crypto_scalarmult_curve25519 0 1 +_crypto_scalarmult_curve25519_base 0 1 +_crypto_scalarmult_curve25519_bytes 0 1 +_crypto_scalarmult_curve25519_scalarbytes 0 1 +_crypto_scalarmult_ed25519 0 1 +_crypto_scalarmult_ed25519_base 0 1 +_crypto_scalarmult_ed25519_base_noclamp 0 1 +_crypto_scalarmult_ed25519_bytes 0 1 +_crypto_scalarmult_ed25519_noclamp 0 1 +_crypto_scalarmult_ed25519_scalarbytes 0 1 +_crypto_scalarmult_primitive 0 1 +_crypto_scalarmult_ristretto255 0 1 +_crypto_scalarmult_ristretto255_base 0 1 +_crypto_scalarmult_ristretto255_bytes 0 1 +_crypto_scalarmult_ristretto255_scalarbytes 0 1 +_crypto_scalarmult_scalarbytes 1 1 +_crypto_secretbox 0 1 +_crypto_secretbox_boxzerobytes 0 1 +_crypto_secretbox_detached 1 1 +_crypto_secretbox_easy 1 1 +_crypto_secretbox_keybytes 1 1 +_crypto_secretbox_keygen 1 1 +_crypto_secretbox_macbytes 1 1 +_crypto_secretbox_messagebytes_max 1 1 +_crypto_secretbox_noncebytes 1 1 +_crypto_secretbox_open 0 1 +_crypto_secretbox_open_detached 1 1 +_crypto_secretbox_open_easy 1 1 +_crypto_secretbox_primitive 0 1 +_crypto_secretbox_xchacha20poly1305_detached 0 1 +_crypto_secretbox_xchacha20poly1305_easy 0 1 +_crypto_secretbox_xchacha20poly1305_keybytes 0 1 +_crypto_secretbox_xchacha20poly1305_macbytes 0 1 +_crypto_secretbox_xchacha20poly1305_messagebytes_max 0 1 +_crypto_secretbox_xchacha20poly1305_noncebytes 0 1 +_crypto_secretbox_xchacha20poly1305_open_detached 0 1 +_crypto_secretbox_xchacha20poly1305_open_easy 0 1 +_crypto_secretbox_xsalsa20poly1305 0 1 +_crypto_secretbox_xsalsa20poly1305_boxzerobytes 0 1 +_crypto_secretbox_xsalsa20poly1305_keybytes 0 1 +_crypto_secretbox_xsalsa20poly1305_keygen 0 1 +_crypto_secretbox_xsalsa20poly1305_macbytes 0 1 +_crypto_secretbox_xsalsa20poly1305_messagebytes_max 0 1 +_crypto_secretbox_xsalsa20poly1305_noncebytes 0 1 +_crypto_secretbox_xsalsa20poly1305_open 0 1 +_crypto_secretbox_xsalsa20poly1305_zerobytes 0 1 +_crypto_secretbox_zerobytes 0 1 +_crypto_secretstream_xchacha20poly1305_abytes 1 1 +_crypto_secretstream_xchacha20poly1305_headerbytes 1 1 +_crypto_secretstream_xchacha20poly1305_init_pull 1 1 +_crypto_secretstream_xchacha20poly1305_init_push 1 1 +_crypto_secretstream_xchacha20poly1305_keybytes 1 1 +_crypto_secretstream_xchacha20poly1305_keygen 1 1 +_crypto_secretstream_xchacha20poly1305_messagebytes_max 1 1 +_crypto_secretstream_xchacha20poly1305_pull 1 1 +_crypto_secretstream_xchacha20poly1305_push 1 1 +_crypto_secretstream_xchacha20poly1305_rekey 1 1 +_crypto_secretstream_xchacha20poly1305_statebytes 1 1 +_crypto_secretstream_xchacha20poly1305_tag_final 1 1 +_crypto_secretstream_xchacha20poly1305_tag_message 1 1 +_crypto_secretstream_xchacha20poly1305_tag_push 1 1 +_crypto_secretstream_xchacha20poly1305_tag_rekey 1 1 +_crypto_shorthash 1 1 +_crypto_shorthash_bytes 1 1 +_crypto_shorthash_keybytes 1 1 +_crypto_shorthash_keygen 1 1 +_crypto_shorthash_primitive 0 1 +_crypto_shorthash_siphash24 0 1 +_crypto_shorthash_siphash24_bytes 0 1 +_crypto_shorthash_siphash24_keybytes 0 1 +_crypto_shorthash_siphashx24 0 1 +_crypto_shorthash_siphashx24_bytes 0 1 +_crypto_shorthash_siphashx24_keybytes 0 1 +_crypto_sign 1 1 +_crypto_sign_bytes 1 1 +_crypto_sign_detached 1 1 +_crypto_sign_ed25519 0 1 +_crypto_sign_ed25519_bytes 0 1 +_crypto_sign_ed25519_detached 0 1 +_crypto_sign_ed25519_keypair 0 1 +_crypto_sign_ed25519_messagebytes_max 0 1 +_crypto_sign_ed25519_open 0 1 +_crypto_sign_ed25519_pk_to_curve25519 1 1 +_crypto_sign_ed25519_publickeybytes 0 1 +_crypto_sign_ed25519_secretkeybytes 0 1 +_crypto_sign_ed25519_seed_keypair 0 1 +_crypto_sign_ed25519_seedbytes 0 1 +_crypto_sign_ed25519_sk_to_curve25519 1 1 +_crypto_sign_ed25519_sk_to_pk 0 1 +_crypto_sign_ed25519_sk_to_seed 0 1 +_crypto_sign_ed25519_verify_detached 0 1 +_crypto_sign_ed25519ph_final_create 0 1 +_crypto_sign_ed25519ph_final_verify 0 1 +_crypto_sign_ed25519ph_init 0 1 +_crypto_sign_ed25519ph_statebytes 0 1 +_crypto_sign_ed25519ph_update 0 1 +_crypto_sign_edwards25519sha512batch 0 0 +_crypto_sign_edwards25519sha512batch_keypair 0 0 +_crypto_sign_edwards25519sha512batch_open 0 0 +_crypto_sign_final_create 1 1 +_crypto_sign_final_verify 1 1 +_crypto_sign_init 1 1 +_crypto_sign_keypair 1 1 +_crypto_sign_messagebytes_max 1 1 +_crypto_sign_open 1 1 +_crypto_sign_primitive 0 1 +_crypto_sign_publickeybytes 1 1 +_crypto_sign_secretkeybytes 1 1 +_crypto_sign_seed_keypair 1 1 +_crypto_sign_seedbytes 1 1 +_crypto_sign_statebytes 1 1 +_crypto_sign_update 1 1 +_crypto_sign_verify_detached 1 1 +_crypto_stream 0 1 +_crypto_stream_chacha20 0 1 +_crypto_stream_chacha20_ietf 0 1 +_crypto_stream_chacha20_ietf_keybytes 0 1 +_crypto_stream_chacha20_ietf_keygen 0 1 +_crypto_stream_chacha20_ietf_messagebytes_max 0 1 +_crypto_stream_chacha20_ietf_noncebytes 0 1 +_crypto_stream_chacha20_ietf_xor 0 1 +_crypto_stream_chacha20_ietf_xor_ic 0 1 +_crypto_stream_chacha20_keybytes 0 1 +_crypto_stream_chacha20_keygen 0 1 +_crypto_stream_chacha20_messagebytes_max 0 1 +_crypto_stream_chacha20_noncebytes 0 1 +_crypto_stream_chacha20_xor 0 1 +_crypto_stream_chacha20_xor_ic 0 1 +_crypto_stream_keybytes 0 1 +_crypto_stream_keygen 0 1 +_crypto_stream_messagebytes_max 0 1 +_crypto_stream_noncebytes 0 1 +_crypto_stream_primitive 0 1 +_crypto_stream_salsa20 0 1 +_crypto_stream_salsa2012 0 1 +_crypto_stream_salsa2012_keybytes 0 1 +_crypto_stream_salsa2012_keygen 0 1 +_crypto_stream_salsa2012_messagebytes_max 0 1 +_crypto_stream_salsa2012_noncebytes 0 1 +_crypto_stream_salsa2012_xor 0 1 +_crypto_stream_salsa208 0 1 +_crypto_stream_salsa208_keybytes 0 1 +_crypto_stream_salsa208_keygen 0 1 +_crypto_stream_salsa208_messagebytes_max 0 1 +_crypto_stream_salsa208_noncebytes 0 1 +_crypto_stream_salsa208_xor 0 1 +_crypto_stream_salsa20_keybytes 0 1 +_crypto_stream_salsa20_keygen 0 1 +_crypto_stream_salsa20_messagebytes_max 0 1 +_crypto_stream_salsa20_noncebytes 0 1 +_crypto_stream_salsa20_xor 0 1 +_crypto_stream_salsa20_xor_ic 0 1 +_crypto_stream_xchacha20 0 1 +_crypto_stream_xchacha20_keybytes 0 1 +_crypto_stream_xchacha20_keygen 0 1 +_crypto_stream_xchacha20_messagebytes_max 0 1 +_crypto_stream_xchacha20_noncebytes 0 1 +_crypto_stream_xchacha20_xor 0 1 +_crypto_stream_xchacha20_xor_ic 0 1 +_crypto_stream_xor 0 1 +_crypto_stream_xsalsa20 0 1 +_crypto_stream_xsalsa20_keybytes 0 1 +_crypto_stream_xsalsa20_keygen 0 1 +_crypto_stream_xsalsa20_messagebytes_max 0 1 +_crypto_stream_xsalsa20_noncebytes 0 1 +_crypto_stream_xsalsa20_xor 0 1 +_crypto_stream_xsalsa20_xor_ic 0 1 +_crypto_verify_16 0 1 +_crypto_verify_16_bytes 0 1 +_crypto_verify_32 0 1 +_crypto_verify_32_bytes 0 1 +_crypto_verify_64 0 1 +_crypto_verify_64_bytes 0 1 +_randombytes 1 1 +_randombytes_buf 1 1 +_randombytes_buf_deterministic 1 1 +_randombytes_close 1 1 +_randombytes_implementation_name 0 1 +_randombytes_random 1 1 +_randombytes_seedbytes 1 1 +_randombytes_set_implementation 0 0 +_randombytes_stir 1 1 +_randombytes_uniform 1 1 +_sodium_add 0 0 +_sodium_allocarray 0 0 +_sodium_base642bin 1 1 +_sodium_base64_encoded_len 1 1 +_sodium_bin2base64 1 1 +_sodium_bin2hex 1 1 +_sodium_compare 0 0 +_sodium_free 0 0 +_sodium_hex2bin 1 1 +_sodium_increment 0 0 +_sodium_init 1 1 +_sodium_is_zero 0 0 +_sodium_library_minimal 1 1 +_sodium_library_version_major 1 1 +_sodium_library_version_minor 1 1 +_sodium_malloc 0 0 +_sodium_memcmp 0 0 +_sodium_memzero 0 0 +_sodium_misuse 0 0 +_sodium_mlock 0 0 +_sodium_mprotect_noaccess 0 0 +_sodium_mprotect_readonly 0 0 +_sodium_mprotect_readwrite 0 0 +_sodium_munlock 0 0 +_sodium_pad 1 1 +_sodium_runtime_has_aesni 0 0 +_sodium_runtime_has_avx 0 0 +_sodium_runtime_has_avx2 0 0 +_sodium_runtime_has_avx512f 0 0 +_sodium_runtime_has_neon 0 0 +_sodium_runtime_has_pclmul 0 0 +_sodium_runtime_has_rdrand 0 0 +_sodium_runtime_has_sse2 0 0 +_sodium_runtime_has_sse3 0 0 +_sodium_runtime_has_sse41 0 0 +_sodium_runtime_has_ssse3 0 0 +_sodium_set_misuse_handler 0 0 +_sodium_stackzero 0 0 +_sodium_sub 0 0 +_sodium_unpad 1 1 +_sodium_version_string 1 1 diff --git a/external/src/libsodium/dist-build/emscripten.sh b/external/src/libsodium/dist-build/emscripten.sh new file mode 100644 index 0000000..3f5d8de --- /dev/null +++ b/external/src/libsodium/dist-build/emscripten.sh @@ -0,0 +1,205 @@ +#! /bin/sh + +export MAKE_FLAGS='-j4' +export EXPORTED_FUNCTIONS_STANDARD='["_malloc","_free","_crypto_aead_chacha20poly1305_abytes","_crypto_aead_chacha20poly1305_decrypt","_crypto_aead_chacha20poly1305_decrypt_detached","_crypto_aead_chacha20poly1305_encrypt","_crypto_aead_chacha20poly1305_encrypt_detached","_crypto_aead_chacha20poly1305_ietf_abytes","_crypto_aead_chacha20poly1305_ietf_decrypt","_crypto_aead_chacha20poly1305_ietf_decrypt_detached","_crypto_aead_chacha20poly1305_ietf_encrypt","_crypto_aead_chacha20poly1305_ietf_encrypt_detached","_crypto_aead_chacha20poly1305_ietf_keybytes","_crypto_aead_chacha20poly1305_ietf_keygen","_crypto_aead_chacha20poly1305_ietf_messagebytes_max","_crypto_aead_chacha20poly1305_ietf_npubbytes","_crypto_aead_chacha20poly1305_ietf_nsecbytes","_crypto_aead_chacha20poly1305_keybytes","_crypto_aead_chacha20poly1305_keygen","_crypto_aead_chacha20poly1305_messagebytes_max","_crypto_aead_chacha20poly1305_npubbytes","_crypto_aead_chacha20poly1305_nsecbytes","_crypto_aead_xchacha20poly1305_ietf_abytes","_crypto_aead_xchacha20poly1305_ietf_decrypt","_crypto_aead_xchacha20poly1305_ietf_decrypt_detached","_crypto_aead_xchacha20poly1305_ietf_encrypt","_crypto_aead_xchacha20poly1305_ietf_encrypt_detached","_crypto_aead_xchacha20poly1305_ietf_keybytes","_crypto_aead_xchacha20poly1305_ietf_keygen","_crypto_aead_xchacha20poly1305_ietf_messagebytes_max","_crypto_aead_xchacha20poly1305_ietf_npubbytes","_crypto_aead_xchacha20poly1305_ietf_nsecbytes","_crypto_auth","_crypto_auth_bytes","_crypto_auth_keybytes","_crypto_auth_keygen","_crypto_auth_verify","_crypto_box_beforenm","_crypto_box_beforenmbytes","_crypto_box_detached","_crypto_box_detached_afternm","_crypto_box_easy","_crypto_box_easy_afternm","_crypto_box_keypair","_crypto_box_macbytes","_crypto_box_messagebytes_max","_crypto_box_noncebytes","_crypto_box_open_detached","_crypto_box_open_detached_afternm","_crypto_box_open_easy","_crypto_box_open_easy_afternm","_crypto_box_publickeybytes","_crypto_box_seal","_crypto_box_seal_open","_crypto_box_sealbytes","_crypto_box_secretkeybytes","_crypto_box_seed_keypair","_crypto_box_seedbytes","_crypto_generichash","_crypto_generichash_bytes","_crypto_generichash_bytes_max","_crypto_generichash_bytes_min","_crypto_generichash_final","_crypto_generichash_init","_crypto_generichash_keybytes","_crypto_generichash_keybytes_max","_crypto_generichash_keybytes_min","_crypto_generichash_keygen","_crypto_generichash_statebytes","_crypto_generichash_update","_crypto_hash","_crypto_hash_bytes","_crypto_kdf_bytes_max","_crypto_kdf_bytes_min","_crypto_kdf_contextbytes","_crypto_kdf_derive_from_key","_crypto_kdf_keybytes","_crypto_kdf_keygen","_crypto_kx_client_session_keys","_crypto_kx_keypair","_crypto_kx_publickeybytes","_crypto_kx_secretkeybytes","_crypto_kx_seed_keypair","_crypto_kx_seedbytes","_crypto_kx_server_session_keys","_crypto_kx_sessionkeybytes","_crypto_pwhash","_crypto_pwhash_alg_argon2i13","_crypto_pwhash_alg_argon2id13","_crypto_pwhash_alg_default","_crypto_pwhash_bytes_max","_crypto_pwhash_bytes_min","_crypto_pwhash_memlimit_interactive","_crypto_pwhash_memlimit_max","_crypto_pwhash_memlimit_min","_crypto_pwhash_memlimit_moderate","_crypto_pwhash_memlimit_sensitive","_crypto_pwhash_opslimit_interactive","_crypto_pwhash_opslimit_max","_crypto_pwhash_opslimit_min","_crypto_pwhash_opslimit_moderate","_crypto_pwhash_opslimit_sensitive","_crypto_pwhash_passwd_max","_crypto_pwhash_passwd_min","_crypto_pwhash_saltbytes","_crypto_pwhash_str","_crypto_pwhash_str_alg","_crypto_pwhash_str_needs_rehash","_crypto_pwhash_str_verify","_crypto_pwhash_strbytes","_crypto_pwhash_strprefix","_crypto_scalarmult","_crypto_scalarmult_base","_crypto_scalarmult_bytes","_crypto_scalarmult_scalarbytes","_crypto_secretbox_detached","_crypto_secretbox_easy","_crypto_secretbox_keybytes","_crypto_secretbox_keygen","_crypto_secretbox_macbytes","_crypto_secretbox_messagebytes_max","_crypto_secretbox_noncebytes","_crypto_secretbox_open_detached","_crypto_secretbox_open_easy","_crypto_secretstream_xchacha20poly1305_abytes","_crypto_secretstream_xchacha20poly1305_headerbytes","_crypto_secretstream_xchacha20poly1305_init_pull","_crypto_secretstream_xchacha20poly1305_init_push","_crypto_secretstream_xchacha20poly1305_keybytes","_crypto_secretstream_xchacha20poly1305_keygen","_crypto_secretstream_xchacha20poly1305_messagebytes_max","_crypto_secretstream_xchacha20poly1305_pull","_crypto_secretstream_xchacha20poly1305_push","_crypto_secretstream_xchacha20poly1305_rekey","_crypto_secretstream_xchacha20poly1305_statebytes","_crypto_secretstream_xchacha20poly1305_tag_final","_crypto_secretstream_xchacha20poly1305_tag_message","_crypto_secretstream_xchacha20poly1305_tag_push","_crypto_secretstream_xchacha20poly1305_tag_rekey","_crypto_shorthash","_crypto_shorthash_bytes","_crypto_shorthash_keybytes","_crypto_shorthash_keygen","_crypto_sign","_crypto_sign_bytes","_crypto_sign_detached","_crypto_sign_ed25519_pk_to_curve25519","_crypto_sign_ed25519_sk_to_curve25519","_crypto_sign_final_create","_crypto_sign_final_verify","_crypto_sign_init","_crypto_sign_keypair","_crypto_sign_messagebytes_max","_crypto_sign_open","_crypto_sign_publickeybytes","_crypto_sign_secretkeybytes","_crypto_sign_seed_keypair","_crypto_sign_seedbytes","_crypto_sign_statebytes","_crypto_sign_update","_crypto_sign_verify_detached","_randombytes","_randombytes_buf","_randombytes_buf_deterministic","_randombytes_close","_randombytes_random","_randombytes_seedbytes","_randombytes_stir","_randombytes_uniform","_sodium_base642bin","_sodium_base64_encoded_len","_sodium_bin2base64","_sodium_bin2hex","_sodium_hex2bin","_sodium_init","_sodium_library_minimal","_sodium_library_version_major","_sodium_library_version_minor","_sodium_pad","_sodium_unpad","_sodium_version_string"]' +export EXPORTED_FUNCTIONS_SUMO='["_malloc","_free","_crypto_aead_chacha20poly1305_abytes","_crypto_aead_chacha20poly1305_decrypt","_crypto_aead_chacha20poly1305_decrypt_detached","_crypto_aead_chacha20poly1305_encrypt","_crypto_aead_chacha20poly1305_encrypt_detached","_crypto_aead_chacha20poly1305_ietf_abytes","_crypto_aead_chacha20poly1305_ietf_decrypt","_crypto_aead_chacha20poly1305_ietf_decrypt_detached","_crypto_aead_chacha20poly1305_ietf_encrypt","_crypto_aead_chacha20poly1305_ietf_encrypt_detached","_crypto_aead_chacha20poly1305_ietf_keybytes","_crypto_aead_chacha20poly1305_ietf_keygen","_crypto_aead_chacha20poly1305_ietf_messagebytes_max","_crypto_aead_chacha20poly1305_ietf_npubbytes","_crypto_aead_chacha20poly1305_ietf_nsecbytes","_crypto_aead_chacha20poly1305_keybytes","_crypto_aead_chacha20poly1305_keygen","_crypto_aead_chacha20poly1305_messagebytes_max","_crypto_aead_chacha20poly1305_npubbytes","_crypto_aead_chacha20poly1305_nsecbytes","_crypto_aead_xchacha20poly1305_ietf_abytes","_crypto_aead_xchacha20poly1305_ietf_decrypt","_crypto_aead_xchacha20poly1305_ietf_decrypt_detached","_crypto_aead_xchacha20poly1305_ietf_encrypt","_crypto_aead_xchacha20poly1305_ietf_encrypt_detached","_crypto_aead_xchacha20poly1305_ietf_keybytes","_crypto_aead_xchacha20poly1305_ietf_keygen","_crypto_aead_xchacha20poly1305_ietf_messagebytes_max","_crypto_aead_xchacha20poly1305_ietf_npubbytes","_crypto_aead_xchacha20poly1305_ietf_nsecbytes","_crypto_auth","_crypto_auth_bytes","_crypto_auth_hmacsha256","_crypto_auth_hmacsha256_bytes","_crypto_auth_hmacsha256_final","_crypto_auth_hmacsha256_init","_crypto_auth_hmacsha256_keybytes","_crypto_auth_hmacsha256_keygen","_crypto_auth_hmacsha256_statebytes","_crypto_auth_hmacsha256_update","_crypto_auth_hmacsha256_verify","_crypto_auth_hmacsha512","_crypto_auth_hmacsha512256","_crypto_auth_hmacsha512256_bytes","_crypto_auth_hmacsha512256_final","_crypto_auth_hmacsha512256_init","_crypto_auth_hmacsha512256_keybytes","_crypto_auth_hmacsha512256_keygen","_crypto_auth_hmacsha512256_statebytes","_crypto_auth_hmacsha512256_update","_crypto_auth_hmacsha512256_verify","_crypto_auth_hmacsha512_bytes","_crypto_auth_hmacsha512_final","_crypto_auth_hmacsha512_init","_crypto_auth_hmacsha512_keybytes","_crypto_auth_hmacsha512_keygen","_crypto_auth_hmacsha512_statebytes","_crypto_auth_hmacsha512_update","_crypto_auth_hmacsha512_verify","_crypto_auth_keybytes","_crypto_auth_keygen","_crypto_auth_primitive","_crypto_auth_verify","_crypto_box","_crypto_box_afternm","_crypto_box_beforenm","_crypto_box_beforenmbytes","_crypto_box_boxzerobytes","_crypto_box_curve25519xchacha20poly1305_beforenm","_crypto_box_curve25519xchacha20poly1305_beforenmbytes","_crypto_box_curve25519xchacha20poly1305_detached","_crypto_box_curve25519xchacha20poly1305_detached_afternm","_crypto_box_curve25519xchacha20poly1305_easy","_crypto_box_curve25519xchacha20poly1305_easy_afternm","_crypto_box_curve25519xchacha20poly1305_keypair","_crypto_box_curve25519xchacha20poly1305_macbytes","_crypto_box_curve25519xchacha20poly1305_messagebytes_max","_crypto_box_curve25519xchacha20poly1305_noncebytes","_crypto_box_curve25519xchacha20poly1305_open_detached","_crypto_box_curve25519xchacha20poly1305_open_detached_afternm","_crypto_box_curve25519xchacha20poly1305_open_easy","_crypto_box_curve25519xchacha20poly1305_open_easy_afternm","_crypto_box_curve25519xchacha20poly1305_publickeybytes","_crypto_box_curve25519xchacha20poly1305_seal","_crypto_box_curve25519xchacha20poly1305_seal_open","_crypto_box_curve25519xchacha20poly1305_sealbytes","_crypto_box_curve25519xchacha20poly1305_secretkeybytes","_crypto_box_curve25519xchacha20poly1305_seed_keypair","_crypto_box_curve25519xchacha20poly1305_seedbytes","_crypto_box_curve25519xsalsa20poly1305","_crypto_box_curve25519xsalsa20poly1305_afternm","_crypto_box_curve25519xsalsa20poly1305_beforenm","_crypto_box_curve25519xsalsa20poly1305_beforenmbytes","_crypto_box_curve25519xsalsa20poly1305_boxzerobytes","_crypto_box_curve25519xsalsa20poly1305_keypair","_crypto_box_curve25519xsalsa20poly1305_macbytes","_crypto_box_curve25519xsalsa20poly1305_messagebytes_max","_crypto_box_curve25519xsalsa20poly1305_noncebytes","_crypto_box_curve25519xsalsa20poly1305_open","_crypto_box_curve25519xsalsa20poly1305_open_afternm","_crypto_box_curve25519xsalsa20poly1305_publickeybytes","_crypto_box_curve25519xsalsa20poly1305_secretkeybytes","_crypto_box_curve25519xsalsa20poly1305_seed_keypair","_crypto_box_curve25519xsalsa20poly1305_seedbytes","_crypto_box_curve25519xsalsa20poly1305_zerobytes","_crypto_box_detached","_crypto_box_detached_afternm","_crypto_box_easy","_crypto_box_easy_afternm","_crypto_box_keypair","_crypto_box_macbytes","_crypto_box_messagebytes_max","_crypto_box_noncebytes","_crypto_box_open","_crypto_box_open_afternm","_crypto_box_open_detached","_crypto_box_open_detached_afternm","_crypto_box_open_easy","_crypto_box_open_easy_afternm","_crypto_box_primitive","_crypto_box_publickeybytes","_crypto_box_seal","_crypto_box_seal_open","_crypto_box_sealbytes","_crypto_box_secretkeybytes","_crypto_box_seed_keypair","_crypto_box_seedbytes","_crypto_box_zerobytes","_crypto_core_ed25519_add","_crypto_core_ed25519_bytes","_crypto_core_ed25519_from_hash","_crypto_core_ed25519_from_uniform","_crypto_core_ed25519_hashbytes","_crypto_core_ed25519_is_valid_point","_crypto_core_ed25519_nonreducedscalarbytes","_crypto_core_ed25519_random","_crypto_core_ed25519_scalar_add","_crypto_core_ed25519_scalar_complement","_crypto_core_ed25519_scalar_invert","_crypto_core_ed25519_scalar_mul","_crypto_core_ed25519_scalar_negate","_crypto_core_ed25519_scalar_random","_crypto_core_ed25519_scalar_reduce","_crypto_core_ed25519_scalar_sub","_crypto_core_ed25519_scalarbytes","_crypto_core_ed25519_sub","_crypto_core_ed25519_uniformbytes","_crypto_core_hchacha20","_crypto_core_hchacha20_constbytes","_crypto_core_hchacha20_inputbytes","_crypto_core_hchacha20_keybytes","_crypto_core_hchacha20_outputbytes","_crypto_core_hsalsa20","_crypto_core_hsalsa20_constbytes","_crypto_core_hsalsa20_inputbytes","_crypto_core_hsalsa20_keybytes","_crypto_core_hsalsa20_outputbytes","_crypto_core_ristretto255_add","_crypto_core_ristretto255_bytes","_crypto_core_ristretto255_from_hash","_crypto_core_ristretto255_hashbytes","_crypto_core_ristretto255_is_valid_point","_crypto_core_ristretto255_nonreducedscalarbytes","_crypto_core_ristretto255_random","_crypto_core_ristretto255_scalar_add","_crypto_core_ristretto255_scalar_complement","_crypto_core_ristretto255_scalar_invert","_crypto_core_ristretto255_scalar_mul","_crypto_core_ristretto255_scalar_negate","_crypto_core_ristretto255_scalar_random","_crypto_core_ristretto255_scalar_reduce","_crypto_core_ristretto255_scalar_sub","_crypto_core_ristretto255_scalarbytes","_crypto_core_ristretto255_sub","_crypto_core_salsa20","_crypto_core_salsa2012","_crypto_core_salsa2012_constbytes","_crypto_core_salsa2012_inputbytes","_crypto_core_salsa2012_keybytes","_crypto_core_salsa2012_outputbytes","_crypto_core_salsa208","_crypto_core_salsa208_constbytes","_crypto_core_salsa208_inputbytes","_crypto_core_salsa208_keybytes","_crypto_core_salsa208_outputbytes","_crypto_core_salsa20_constbytes","_crypto_core_salsa20_inputbytes","_crypto_core_salsa20_keybytes","_crypto_core_salsa20_outputbytes","_crypto_generichash","_crypto_generichash_blake2b","_crypto_generichash_blake2b_bytes","_crypto_generichash_blake2b_bytes_max","_crypto_generichash_blake2b_bytes_min","_crypto_generichash_blake2b_final","_crypto_generichash_blake2b_init","_crypto_generichash_blake2b_init_salt_personal","_crypto_generichash_blake2b_keybytes","_crypto_generichash_blake2b_keybytes_max","_crypto_generichash_blake2b_keybytes_min","_crypto_generichash_blake2b_keygen","_crypto_generichash_blake2b_personalbytes","_crypto_generichash_blake2b_salt_personal","_crypto_generichash_blake2b_saltbytes","_crypto_generichash_blake2b_statebytes","_crypto_generichash_blake2b_update","_crypto_generichash_bytes","_crypto_generichash_bytes_max","_crypto_generichash_bytes_min","_crypto_generichash_final","_crypto_generichash_init","_crypto_generichash_keybytes","_crypto_generichash_keybytes_max","_crypto_generichash_keybytes_min","_crypto_generichash_keygen","_crypto_generichash_primitive","_crypto_generichash_statebytes","_crypto_generichash_update","_crypto_hash","_crypto_hash_bytes","_crypto_hash_primitive","_crypto_hash_sha256","_crypto_hash_sha256_bytes","_crypto_hash_sha256_final","_crypto_hash_sha256_init","_crypto_hash_sha256_statebytes","_crypto_hash_sha256_update","_crypto_hash_sha512","_crypto_hash_sha512_bytes","_crypto_hash_sha512_final","_crypto_hash_sha512_init","_crypto_hash_sha512_statebytes","_crypto_hash_sha512_update","_crypto_kdf_blake2b_bytes_max","_crypto_kdf_blake2b_bytes_min","_crypto_kdf_blake2b_contextbytes","_crypto_kdf_blake2b_derive_from_key","_crypto_kdf_blake2b_keybytes","_crypto_kdf_bytes_max","_crypto_kdf_bytes_min","_crypto_kdf_contextbytes","_crypto_kdf_derive_from_key","_crypto_kdf_keybytes","_crypto_kdf_keygen","_crypto_kdf_primitive","_crypto_kx_client_session_keys","_crypto_kx_keypair","_crypto_kx_primitive","_crypto_kx_publickeybytes","_crypto_kx_secretkeybytes","_crypto_kx_seed_keypair","_crypto_kx_seedbytes","_crypto_kx_server_session_keys","_crypto_kx_sessionkeybytes","_crypto_onetimeauth","_crypto_onetimeauth_bytes","_crypto_onetimeauth_final","_crypto_onetimeauth_init","_crypto_onetimeauth_keybytes","_crypto_onetimeauth_keygen","_crypto_onetimeauth_poly1305","_crypto_onetimeauth_poly1305_bytes","_crypto_onetimeauth_poly1305_final","_crypto_onetimeauth_poly1305_init","_crypto_onetimeauth_poly1305_keybytes","_crypto_onetimeauth_poly1305_keygen","_crypto_onetimeauth_poly1305_statebytes","_crypto_onetimeauth_poly1305_update","_crypto_onetimeauth_poly1305_verify","_crypto_onetimeauth_primitive","_crypto_onetimeauth_statebytes","_crypto_onetimeauth_update","_crypto_onetimeauth_verify","_crypto_pwhash","_crypto_pwhash_alg_argon2i13","_crypto_pwhash_alg_argon2id13","_crypto_pwhash_alg_default","_crypto_pwhash_argon2i","_crypto_pwhash_argon2i_alg_argon2i13","_crypto_pwhash_argon2i_bytes_max","_crypto_pwhash_argon2i_bytes_min","_crypto_pwhash_argon2i_memlimit_interactive","_crypto_pwhash_argon2i_memlimit_max","_crypto_pwhash_argon2i_memlimit_min","_crypto_pwhash_argon2i_memlimit_moderate","_crypto_pwhash_argon2i_memlimit_sensitive","_crypto_pwhash_argon2i_opslimit_interactive","_crypto_pwhash_argon2i_opslimit_max","_crypto_pwhash_argon2i_opslimit_min","_crypto_pwhash_argon2i_opslimit_moderate","_crypto_pwhash_argon2i_opslimit_sensitive","_crypto_pwhash_argon2i_passwd_max","_crypto_pwhash_argon2i_passwd_min","_crypto_pwhash_argon2i_saltbytes","_crypto_pwhash_argon2i_str","_crypto_pwhash_argon2i_str_needs_rehash","_crypto_pwhash_argon2i_str_verify","_crypto_pwhash_argon2i_strbytes","_crypto_pwhash_argon2i_strprefix","_crypto_pwhash_argon2id","_crypto_pwhash_argon2id_alg_argon2id13","_crypto_pwhash_argon2id_bytes_max","_crypto_pwhash_argon2id_bytes_min","_crypto_pwhash_argon2id_memlimit_interactive","_crypto_pwhash_argon2id_memlimit_max","_crypto_pwhash_argon2id_memlimit_min","_crypto_pwhash_argon2id_memlimit_moderate","_crypto_pwhash_argon2id_memlimit_sensitive","_crypto_pwhash_argon2id_opslimit_interactive","_crypto_pwhash_argon2id_opslimit_max","_crypto_pwhash_argon2id_opslimit_min","_crypto_pwhash_argon2id_opslimit_moderate","_crypto_pwhash_argon2id_opslimit_sensitive","_crypto_pwhash_argon2id_passwd_max","_crypto_pwhash_argon2id_passwd_min","_crypto_pwhash_argon2id_saltbytes","_crypto_pwhash_argon2id_str","_crypto_pwhash_argon2id_str_needs_rehash","_crypto_pwhash_argon2id_str_verify","_crypto_pwhash_argon2id_strbytes","_crypto_pwhash_argon2id_strprefix","_crypto_pwhash_bytes_max","_crypto_pwhash_bytes_min","_crypto_pwhash_memlimit_interactive","_crypto_pwhash_memlimit_max","_crypto_pwhash_memlimit_min","_crypto_pwhash_memlimit_moderate","_crypto_pwhash_memlimit_sensitive","_crypto_pwhash_opslimit_interactive","_crypto_pwhash_opslimit_max","_crypto_pwhash_opslimit_min","_crypto_pwhash_opslimit_moderate","_crypto_pwhash_opslimit_sensitive","_crypto_pwhash_passwd_max","_crypto_pwhash_passwd_min","_crypto_pwhash_primitive","_crypto_pwhash_saltbytes","_crypto_pwhash_scryptsalsa208sha256","_crypto_pwhash_scryptsalsa208sha256_bytes_max","_crypto_pwhash_scryptsalsa208sha256_bytes_min","_crypto_pwhash_scryptsalsa208sha256_ll","_crypto_pwhash_scryptsalsa208sha256_memlimit_interactive","_crypto_pwhash_scryptsalsa208sha256_memlimit_max","_crypto_pwhash_scryptsalsa208sha256_memlimit_min","_crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive","_crypto_pwhash_scryptsalsa208sha256_opslimit_interactive","_crypto_pwhash_scryptsalsa208sha256_opslimit_max","_crypto_pwhash_scryptsalsa208sha256_opslimit_min","_crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive","_crypto_pwhash_scryptsalsa208sha256_passwd_max","_crypto_pwhash_scryptsalsa208sha256_passwd_min","_crypto_pwhash_scryptsalsa208sha256_saltbytes","_crypto_pwhash_scryptsalsa208sha256_str","_crypto_pwhash_scryptsalsa208sha256_str_needs_rehash","_crypto_pwhash_scryptsalsa208sha256_str_verify","_crypto_pwhash_scryptsalsa208sha256_strbytes","_crypto_pwhash_scryptsalsa208sha256_strprefix","_crypto_pwhash_str","_crypto_pwhash_str_alg","_crypto_pwhash_str_needs_rehash","_crypto_pwhash_str_verify","_crypto_pwhash_strbytes","_crypto_pwhash_strprefix","_crypto_scalarmult","_crypto_scalarmult_base","_crypto_scalarmult_bytes","_crypto_scalarmult_curve25519","_crypto_scalarmult_curve25519_base","_crypto_scalarmult_curve25519_bytes","_crypto_scalarmult_curve25519_scalarbytes","_crypto_scalarmult_ed25519","_crypto_scalarmult_ed25519_base","_crypto_scalarmult_ed25519_base_noclamp","_crypto_scalarmult_ed25519_bytes","_crypto_scalarmult_ed25519_noclamp","_crypto_scalarmult_ed25519_scalarbytes","_crypto_scalarmult_primitive","_crypto_scalarmult_ristretto255","_crypto_scalarmult_ristretto255_base","_crypto_scalarmult_ristretto255_bytes","_crypto_scalarmult_ristretto255_scalarbytes","_crypto_scalarmult_scalarbytes","_crypto_secretbox","_crypto_secretbox_boxzerobytes","_crypto_secretbox_detached","_crypto_secretbox_easy","_crypto_secretbox_keybytes","_crypto_secretbox_keygen","_crypto_secretbox_macbytes","_crypto_secretbox_messagebytes_max","_crypto_secretbox_noncebytes","_crypto_secretbox_open","_crypto_secretbox_open_detached","_crypto_secretbox_open_easy","_crypto_secretbox_primitive","_crypto_secretbox_xchacha20poly1305_detached","_crypto_secretbox_xchacha20poly1305_easy","_crypto_secretbox_xchacha20poly1305_keybytes","_crypto_secretbox_xchacha20poly1305_macbytes","_crypto_secretbox_xchacha20poly1305_messagebytes_max","_crypto_secretbox_xchacha20poly1305_noncebytes","_crypto_secretbox_xchacha20poly1305_open_detached","_crypto_secretbox_xchacha20poly1305_open_easy","_crypto_secretbox_xsalsa20poly1305","_crypto_secretbox_xsalsa20poly1305_boxzerobytes","_crypto_secretbox_xsalsa20poly1305_keybytes","_crypto_secretbox_xsalsa20poly1305_keygen","_crypto_secretbox_xsalsa20poly1305_macbytes","_crypto_secretbox_xsalsa20poly1305_messagebytes_max","_crypto_secretbox_xsalsa20poly1305_noncebytes","_crypto_secretbox_xsalsa20poly1305_open","_crypto_secretbox_xsalsa20poly1305_zerobytes","_crypto_secretbox_zerobytes","_crypto_secretstream_xchacha20poly1305_abytes","_crypto_secretstream_xchacha20poly1305_headerbytes","_crypto_secretstream_xchacha20poly1305_init_pull","_crypto_secretstream_xchacha20poly1305_init_push","_crypto_secretstream_xchacha20poly1305_keybytes","_crypto_secretstream_xchacha20poly1305_keygen","_crypto_secretstream_xchacha20poly1305_messagebytes_max","_crypto_secretstream_xchacha20poly1305_pull","_crypto_secretstream_xchacha20poly1305_push","_crypto_secretstream_xchacha20poly1305_rekey","_crypto_secretstream_xchacha20poly1305_statebytes","_crypto_secretstream_xchacha20poly1305_tag_final","_crypto_secretstream_xchacha20poly1305_tag_message","_crypto_secretstream_xchacha20poly1305_tag_push","_crypto_secretstream_xchacha20poly1305_tag_rekey","_crypto_shorthash","_crypto_shorthash_bytes","_crypto_shorthash_keybytes","_crypto_shorthash_keygen","_crypto_shorthash_primitive","_crypto_shorthash_siphash24","_crypto_shorthash_siphash24_bytes","_crypto_shorthash_siphash24_keybytes","_crypto_shorthash_siphashx24","_crypto_shorthash_siphashx24_bytes","_crypto_shorthash_siphashx24_keybytes","_crypto_sign","_crypto_sign_bytes","_crypto_sign_detached","_crypto_sign_ed25519","_crypto_sign_ed25519_bytes","_crypto_sign_ed25519_detached","_crypto_sign_ed25519_keypair","_crypto_sign_ed25519_messagebytes_max","_crypto_sign_ed25519_open","_crypto_sign_ed25519_pk_to_curve25519","_crypto_sign_ed25519_publickeybytes","_crypto_sign_ed25519_secretkeybytes","_crypto_sign_ed25519_seed_keypair","_crypto_sign_ed25519_seedbytes","_crypto_sign_ed25519_sk_to_curve25519","_crypto_sign_ed25519_sk_to_pk","_crypto_sign_ed25519_sk_to_seed","_crypto_sign_ed25519_verify_detached","_crypto_sign_ed25519ph_final_create","_crypto_sign_ed25519ph_final_verify","_crypto_sign_ed25519ph_init","_crypto_sign_ed25519ph_statebytes","_crypto_sign_ed25519ph_update","_crypto_sign_final_create","_crypto_sign_final_verify","_crypto_sign_init","_crypto_sign_keypair","_crypto_sign_messagebytes_max","_crypto_sign_open","_crypto_sign_primitive","_crypto_sign_publickeybytes","_crypto_sign_secretkeybytes","_crypto_sign_seed_keypair","_crypto_sign_seedbytes","_crypto_sign_statebytes","_crypto_sign_update","_crypto_sign_verify_detached","_crypto_stream","_crypto_stream_chacha20","_crypto_stream_chacha20_ietf","_crypto_stream_chacha20_ietf_keybytes","_crypto_stream_chacha20_ietf_keygen","_crypto_stream_chacha20_ietf_messagebytes_max","_crypto_stream_chacha20_ietf_noncebytes","_crypto_stream_chacha20_ietf_xor","_crypto_stream_chacha20_ietf_xor_ic","_crypto_stream_chacha20_keybytes","_crypto_stream_chacha20_keygen","_crypto_stream_chacha20_messagebytes_max","_crypto_stream_chacha20_noncebytes","_crypto_stream_chacha20_xor","_crypto_stream_chacha20_xor_ic","_crypto_stream_keybytes","_crypto_stream_keygen","_crypto_stream_messagebytes_max","_crypto_stream_noncebytes","_crypto_stream_primitive","_crypto_stream_salsa20","_crypto_stream_salsa2012","_crypto_stream_salsa2012_keybytes","_crypto_stream_salsa2012_keygen","_crypto_stream_salsa2012_messagebytes_max","_crypto_stream_salsa2012_noncebytes","_crypto_stream_salsa2012_xor","_crypto_stream_salsa208","_crypto_stream_salsa208_keybytes","_crypto_stream_salsa208_keygen","_crypto_stream_salsa208_messagebytes_max","_crypto_stream_salsa208_noncebytes","_crypto_stream_salsa208_xor","_crypto_stream_salsa20_keybytes","_crypto_stream_salsa20_keygen","_crypto_stream_salsa20_messagebytes_max","_crypto_stream_salsa20_noncebytes","_crypto_stream_salsa20_xor","_crypto_stream_salsa20_xor_ic","_crypto_stream_xchacha20","_crypto_stream_xchacha20_keybytes","_crypto_stream_xchacha20_keygen","_crypto_stream_xchacha20_messagebytes_max","_crypto_stream_xchacha20_noncebytes","_crypto_stream_xchacha20_xor","_crypto_stream_xchacha20_xor_ic","_crypto_stream_xor","_crypto_stream_xsalsa20","_crypto_stream_xsalsa20_keybytes","_crypto_stream_xsalsa20_keygen","_crypto_stream_xsalsa20_messagebytes_max","_crypto_stream_xsalsa20_noncebytes","_crypto_stream_xsalsa20_xor","_crypto_stream_xsalsa20_xor_ic","_crypto_verify_16","_crypto_verify_16_bytes","_crypto_verify_32","_crypto_verify_32_bytes","_crypto_verify_64","_crypto_verify_64_bytes","_randombytes","_randombytes_buf","_randombytes_buf_deterministic","_randombytes_close","_randombytes_implementation_name","_randombytes_random","_randombytes_seedbytes","_randombytes_stir","_randombytes_uniform","_sodium_base642bin","_sodium_base64_encoded_len","_sodium_bin2base64","_sodium_bin2hex","_sodium_hex2bin","_sodium_init","_sodium_library_minimal","_sodium_library_version_major","_sodium_library_version_minor","_sodium_pad","_sodium_unpad","_sodium_version_string"]' +export EXPORTED_RUNTIME_METHODS='["UTF8ToString","getValue","setValue"]' +export MAX_MEMORY=16777216 +export MAX_MEMORY_SUMO=16777216 +export MAX_MEMORY_TESTS=16777216 +export LDFLAGS="-s RESERVED_FUNCTION_POINTERS=8" +export LDFLAGS="${LDFLAGS} -s ALLOW_MEMORY_GROWTH=1" +export LDFLAGS="${LDFLAGS} -s SINGLE_FILE=1" +export LDFLAGS="${LDFLAGS} -s ASSERTIONS=0" +export LDFLAGS="${LDFLAGS} -s AGGRESSIVE_VARIABLE_ELIMINATION=1 -s ALIASING_FUNCTION_POINTERS=1" +export LDFLAGS="${LDFLAGS} -s DISABLE_EXCEPTION_CATCHING=1" +export LDFLAGS="${LDFLAGS} -s ELIMINATE_DUPLICATE_FUNCTIONS=1" +export LDFLAGS="${LDFLAGS} -s NODEJS_CATCH_EXIT=0" +export LDFLAGS="${LDFLAGS} -s NODEJS_CATCH_REJECTION=0" +export CFLAGS="-Os" + +echo +if [ "x$1" = "x--standard" ]; then + export EXPORTED_FUNCTIONS="$EXPORTED_FUNCTIONS_STANDARD" + export LDFLAGS="${LDFLAGS} ${LDFLAGS_DIST} -s TOTAL_MEMORY=${MAX_MEMORY}" + export PREFIX="$(pwd)/libsodium-js" + export DONE_FILE="$(pwd)/js.done" + export CONFIG_EXTRA="--enable-minimal" + export DIST='yes' + echo "Building a standard distribution in [${PREFIX}]" +elif [ "x$1" = "x--sumo" ]; then + export EXPORTED_FUNCTIONS="$EXPORTED_FUNCTIONS_SUMO" + export LDFLAGS="${LDFLAGS} ${LDFLAGS_DIST} -s TOTAL_MEMORY=${MAX_MEMORY_SUMO}" + export PREFIX="$(pwd)/libsodium-js-sumo" + export DONE_FILE="$(pwd)/js-sumo.done" + export DIST='yes' + echo "Building a sumo distribution in [${PREFIX}]" +elif [ "x$1" = "x--browser-tests" ]; then + export EXPORTED_FUNCTIONS="$EXPORTED_FUNCTIONS_SUMO" + export CPPFLAGS="${CPPFLAGS} -s FORCE_FILESYSTEM=1" + export LDFLAGS="${LDFLAGS} -s TOTAL_MEMORY=${MAX_MEMORY_TESTS}" + export PREFIX="$(pwd)/libsodium-js-tests" + export DONE_FILE="$(pwd)/js-tests-browser.done" + export BROWSER_TESTS='yes' + export DIST='no' + echo "Building tests for web browsers in [${PREFIX}]" +elif [ "x$1" = "x--tests" ]; then + echo "Building for testing" + export EXPORTED_FUNCTIONS="$EXPORTED_FUNCTIONS_SUMO" + export CPPFLAGS="${CPPFLAGS} -s FORCE_FILESYSTEM=1 -DBENCHMARKS -DITERATIONS=10" + export LDFLAGS="${LDFLAGS} -s TOTAL_MEMORY=${MAX_MEMORY_TESTS}" + export PREFIX="$(pwd)/libsodium-js-tests" + export DONE_FILE="$(pwd)/js-tests.done" + export DIST='no' + echo "Building for testing in [${PREFIX}]" +else + echo "Usage: $0 " + echo " := --standard | --sumo | --browser-tests | --tests" + echo + exit 1 +fi +export JS_EXPORTS_FLAGS="-s EXPORTED_FUNCTIONS=${EXPORTED_FUNCTIONS} -s EXTRA_EXPORTED_RUNTIME_METHODS=${EXPORTED_RUNTIME_METHODS}" + +rm -f "$DONE_FILE" + +echo + +emconfigure ./configure $CONFIG_EXTRA --disable-shared --prefix="$PREFIX" \ + --without-pthreads \ + --disable-ssp --disable-asm --disable-pie \ + CFLAGS="$CFLAGS" && \ +emmake make clean +[ $? = 0 ] || exit 1 + +if [ "$DIST" = yes ]; then + emccLibsodium () { + outFile="${1}" + shift + emcc "$CFLAGS" --llvm-lto 1 $CPPFLAGS $LDFLAGS $JS_EXPORTS_FLAGS ${@} \ + "${PREFIX}/lib/libsodium.a" -o "${outFile}" || exit 1 + } + emmake make $MAKE_FLAGS install || exit 1 + emccLibsodium "${PREFIX}/lib/libsodium.asm.tmp.js" -Oz -s WASM=0 + emccLibsodium "${PREFIX}/lib/libsodium.wasm.tmp.js" -O3 -s WASM=1 + + cat > "${PREFIX}/lib/libsodium.js" <<- EOM + var Module; + if (typeof Module === 'undefined') { + Module = {}; + } + var root = Module; + if (typeof root['sodium'] !== 'object') { + if (typeof global === 'object') { + root = global; + } else if (typeof window === 'object') { + root = window; + } + } + if (typeof root['sodium'] === 'object' && typeof root['sodium']['totalMemory'] === 'number') { + Module['TOTAL_MEMORY'] = root['sodium']['totalMemory']; + } + var _Module = Module; + Module.ready = new Promise(function(resolve, reject) { + var Module = _Module; + Module.onAbort = reject; + Module.print = function(what) { + typeof(console) !== 'undefined' && console.log(what); + } + Module.printErr = function(what) { + typeof(console) !== 'undefined' && console.warn(what); + } + Module.onRuntimeInitialized = function() { + try { + /* Test arbitrary wasm function */ + Module._crypto_secretbox_keybytes(); + resolve(); + } catch (err) { + reject(err); + } + }; + Module.useBackupModule = function() { + return new Promise(function(resolve, reject) { + var Module = {}; + Module.onAbort = reject; + + Module.onRuntimeInitialized = function() { + Object.keys(_Module).forEach(function(k) { + if (k !== 'getRandomValue') { + delete _Module[k]; + } + }); + Object.keys(Module).forEach(function(k) { + _Module[k] = Module[k]; + }); + resolve(); + }; + + $(cat "${PREFIX}/lib/libsodium.asm.tmp.js" | sed 's|use asm||g') + }); + }; + $(cat "${PREFIX}/lib/libsodium.wasm.tmp.js") + }).catch(function() { + return _Module.useBackupModule(); + }); +EOM + + rm "${PREFIX}/lib/libsodium.asm.tmp.js" "${PREFIX}/lib/libsodium.wasm.tmp.js" + touch -r "${PREFIX}/lib/libsodium.js" "$DONE_FILE" + ls -l "${PREFIX}/lib/libsodium.js" + exit 0 +fi + +if test "x$NODE" = x; then + for candidate in /usr/local/bin/node /usr/local/bin/nodejs /usr/bin/node /usr/bin/nodejs node nodejs; do + case $($candidate --version 2>&1) in #( + v*) + NODE=$candidate + break ;; + esac + done +fi + +if [ "x$BROWSER_TESTS" != "x" ]; then + echo 'Compiling the test suite for web browsers...' && \ + emmake make $MAKE_FLAGS CPPFLAGS="$CPPFLAGS -DBROWSER_TESTS=1" check > /dev/null 2>&1 +else + if test "x$NODE" = x; then + echo 'node.js not found - test suite skipped' >&2 + exit 1 + fi + echo "Using [${NODE}] as a Javascript runtime" + echo 'Compiling the test suite...' && \ + emmake make $MAKE_FLAGS check > /dev/null 2>&1 +fi + +if [ "x$BROWSER_TESTS" != "x" ]; then + echo 'Creating the test suite for web browsers' + ( + cd test/default && \ + mkdir -p browser && \ + rm -f browser/tests.txt && \ + for file in *.js; do + fgrep -v "#! /usr/bin/env ${NODE}" "$file" > "browser/${file}" + tname=$(echo "$file" | sed 's/.js$//') + cp -f "${tname}.exp" "browser/${tname}.exp" + sed "s/{{tname}}/${tname}/" index.html.tpl > "browser/${tname}.html" + echo "${tname}.html" >> "browser/tests.txt" + done + touch "$DONE_FILE" + ) +else + echo 'Running the test suite' + ( + cd test/default && \ + for file in *.js; do + echo "#! /usr/bin/env ${NODE}" > "${file}.tmp" + fgrep -v "#! /usr/bin/env ${NODE}" "$file" >> "${file}.tmp" + chmod +x "${file}.tmp" + mv -f "${file}.tmp" "$file" + done + ) + make $MAKE_FLAGS check || exit 1 + touch "$DONE_FILE" +fi + +echo 'Done.' diff --git a/external/src/libsodium/dist-build/generate-emscripten-symbols.sh b/external/src/libsodium/dist-build/generate-emscripten-symbols.sh new file mode 100644 index 0000000..873307d --- /dev/null +++ b/external/src/libsodium/dist-build/generate-emscripten-symbols.sh @@ -0,0 +1,57 @@ +#! /bin/sh + +set -e + +symbols() { + { + SUMO="$1" + while read symbol standard sumo; do + found="$standard" + if [ "x$SUMO" = "xsumo" ]; then + found="$sumo" + fi + if [ "$found" = "1" ]; then + eval "defined_${symbol}=yes" + else + eval "defined_${symbol}=no" + fi + done < emscripten-symbols.def + + /usr/bin/nm /usr/local/lib/libsodium.23.dylib | \ + fgrep ' T _' | \ + cut -d' ' -f3 | { + while read symbol; do + eval "found=\$defined_${symbol}" + if [ "$found" = "yes" ]; then + echo "$symbol" + elif [ "$found" != "no" ]; then + echo >&2 + echo "*** [$symbol] was not expected ***" >&2 + echo >&2 + exit 1 + fi + done + } + } | \ + sort | \ + { + out='"_malloc","_free"' + while read symbol ; do + if [ ! -z "$out" ]; then + out="${out}," + fi + out="${out}\"${symbol}\"" + done + echo "[${out}]" + } +} + +out=$(symbols standard) +sed s/EXPORTED_FUNCTIONS_STANDARD=\'.*\'/EXPORTED_FUNCTIONS_STANDARD=\'${out}\'/ < emscripten.sh > emscripten.sh.tmp && \ + mv -f emscripten.sh.tmp emscripten.sh + +out=$(symbols sumo) +sed s/EXPORTED_FUNCTIONS_SUMO=\'.*\'/EXPORTED_FUNCTIONS_SUMO=\'${out}\'/ < emscripten.sh > emscripten.sh.tmp && \ + mv -f emscripten.sh.tmp emscripten.sh + +chmod +x emscripten.sh diff --git a/external/src/libsodium/dist-build/ios.sh b/external/src/libsodium/dist-build/ios.sh new file mode 100644 index 0000000..ef1848f --- /dev/null +++ b/external/src/libsodium/dist-build/ios.sh @@ -0,0 +1,135 @@ +#! /bin/sh +# +# Step 1. +# Configure for base system so simulator is covered +# +# Step 2. +# Make for iOS and iOS simulator +# +# Step 3. +# Merge libs into final version for xcode import + +export PREFIX="$(pwd)/libsodium-ios" +export IOS32_PREFIX="$PREFIX/tmp/ios32" +export IOS32s_PREFIX="$PREFIX/tmp/ios32s" +export IOS64_PREFIX="$PREFIX/tmp/ios64" +export SIMULATOR32_PREFIX="$PREFIX/tmp/simulator32" +export SIMULATOR64_PREFIX="$PREFIX/tmp/simulator64" +export XCODEDIR=$(xcode-select -p) + +export IOS_SIMULATOR_VERSION_MIN=${IOS_SIMULATOR_VERSION_MIN-"6.0.0"} +export IOS_VERSION_MIN=${IOS_VERSION_MIN-"6.0.0"} + +echo +echo "Warnings related to headers being present but not usable are due to functions" +echo "that didn't exist in the specified minimum iOS version level." +echo "They can be safely ignored." +echo + +mkdir -p $SIMULATOR32_PREFIX $SIMULATOR64_PREFIX $IOS32_PREFIX $IOS32s_PREFIX $IOS64_PREFIX || exit 1 + +# Build for the simulator +export BASEDIR="${XCODEDIR}/Platforms/iPhoneSimulator.platform/Developer" +export PATH="${BASEDIR}/usr/bin:$BASEDIR/usr/sbin:$PATH" +export SDK="${BASEDIR}/SDKs/iPhoneSimulator.sdk" + +## i386 simulator +export CFLAGS="-O2 -arch i386 -isysroot ${SDK} -mios-simulator-version-min=${IOS_SIMULATOR_VERSION_MIN}" +export LDFLAGS="-arch i386 -isysroot ${SDK} -mios-simulator-version-min=${IOS_SIMULATOR_VERSION_MIN}" + +make distclean > /dev/null + +if [ -z "$LIBSODIUM_FULL_BUILD" ]; then + export LIBSODIUM_ENABLE_MINIMAL_FLAG="--enable-minimal" +else + export LIBSODIUM_ENABLE_MINIMAL_FLAG="" +fi + +./configure --host=i686-apple-darwin10 \ + --disable-shared \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} \ + --prefix="$SIMULATOR32_PREFIX" || exit 1 + + +NPROCESSORS=$(getconf NPROCESSORS_ONLN 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null) +PROCESSORS=${NPROCESSORS:-3} + +make -j${PROCESSORS} install || exit 1 + +## x86_64 simulator +export CFLAGS="-O2 -arch x86_64 -isysroot ${SDK} -mios-simulator-version-min=${IOS_SIMULATOR_VERSION_MIN}" +export LDFLAGS="-arch x86_64 -isysroot ${SDK} -mios-simulator-version-min=${IOS_SIMULATOR_VERSION_MIN}" + +make distclean > /dev/null + +./configure --host=x86_64-apple-darwin10 \ + --disable-shared \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} \ + --prefix="$SIMULATOR64_PREFIX" + +make -j${PROCESSORS} install || exit 1 + +# Build for iOS +export BASEDIR="${XCODEDIR}/Platforms/iPhoneOS.platform/Developer" +export PATH="${BASEDIR}/usr/bin:$BASEDIR/usr/sbin:$PATH" +export SDK="${BASEDIR}/SDKs/iPhoneOS.sdk" + +## 32-bit iOS +export CFLAGS="-fembed-bitcode -O2 -mthumb -arch armv7 -isysroot ${SDK} -mios-version-min=${IOS_VERSION_MIN}" +export LDFLAGS="-fembed-bitcode -mthumb -arch armv7 -isysroot ${SDK} -mios-version-min=${IOS_VERSION_MIN}" + +make distclean > /dev/null + +./configure --host=arm-apple-darwin10 \ + --disable-shared \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} \ + --prefix="$IOS32_PREFIX" || exit 1 + +make -j${PROCESSORS} install || exit 1 + +## 32-bit armv7s iOS +export CFLAGS="-fembed-bitcode -O2 -mthumb -arch armv7s -isysroot ${SDK} -mios-version-min=${IOS_VERSION_MIN}" +export LDFLAGS="-fembed-bitcode -mthumb -arch armv7s -isysroot ${SDK} -mios-version-min=${IOS_VERSION_MIN}" + +make distclean > /dev/null + +./configure --host=arm-apple-darwin10 \ + --disable-shared \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} \ + --prefix="$IOS32s_PREFIX" || exit 1 + +make -j${PROCESSORS} install || exit 1 + +## 64-bit iOS +export CFLAGS="-fembed-bitcode -O2 -arch arm64 -isysroot ${SDK} -mios-version-min=${IOS_VERSION_MIN}" +export LDFLAGS="-fembed-bitcode -arch arm64 -isysroot ${SDK} -mios-version-min=${IOS_VERSION_MIN}" + +make distclean > /dev/null + +./configure --host=arm-apple-darwin10 \ + --disable-shared \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} \ + --prefix="$IOS64_PREFIX" || exit 1 + +make -j${PROCESSORS} install || exit 1 + +# Create universal binary and include folder +rm -fr -- "$PREFIX/include" "$PREFIX/libsodium.a" 2> /dev/null +mkdir -p -- "$PREFIX/lib" +lipo -create \ + "$SIMULATOR32_PREFIX/lib/libsodium.a" \ + "$SIMULATOR64_PREFIX/lib/libsodium.a" \ + "$IOS32_PREFIX/lib/libsodium.a" \ + "$IOS32s_PREFIX/lib/libsodium.a" \ + "$IOS64_PREFIX/lib/libsodium.a" \ + -output "$PREFIX/lib/libsodium.a" +mv -f -- "$IOS32_PREFIX/include" "$PREFIX/" + +echo +echo "libsodium has been installed into $PREFIX" +echo +file -- "$PREFIX/lib/libsodium.a" + +# Cleanup +rm -rf -- "$PREFIX/tmp" +make distclean > /dev/null diff --git a/external/src/libsodium/dist-build/msys2-win32.sh b/external/src/libsodium/dist-build/msys2-win32.sh new file mode 100644 index 0000000..dcc9ee0 --- /dev/null +++ b/external/src/libsodium/dist-build/msys2-win32.sh @@ -0,0 +1,18 @@ +#! /bin/sh + +export CFLAGS="-Ofast -fomit-frame-pointer -m32 -march=pentium3 -mtune=westmere" +export PREFIX="$(pwd)/libsodium-win32" + +if (i686-w64-mingw32-gcc --version > /dev/null 2>&1) then + echo MinGW found +else + echo Please install mingw-w64-i686-gcc >&2 + exit +fi + +./configure --prefix="$PREFIX" --exec-prefix="$PREFIX" \ + --host=i686-w64-mingw32 && \ +make clean && \ +make && \ +make check && \ +make install diff --git a/external/src/libsodium/dist-build/msys2-win64.sh b/external/src/libsodium/dist-build/msys2-win64.sh new file mode 100644 index 0000000..0b38d6d --- /dev/null +++ b/external/src/libsodium/dist-build/msys2-win64.sh @@ -0,0 +1,18 @@ +#! /bin/sh + +export CFLAGS="-Ofast -fomit-frame-pointer -m64 -mtune=westmere" +export PREFIX="$(pwd)/libsodium-win64" + +if (x86_64-w64-mingw32-gcc --version > /dev/null 2>&1) then + echo MinGW found +else + echo Please install mingw-w64-x86_64-gcc >&2 + exit +fi + +./configure --prefix="$PREFIX" --exec-prefix="$PREFIX" \ + --host=x86_64-w64-mingw32 && \ +make clean && \ +make && \ +make check && \ +make install diff --git a/external/src/libsodium/dist-build/osx.sh b/external/src/libsodium/dist-build/osx.sh new file mode 100644 index 0000000..b7ff1bd --- /dev/null +++ b/external/src/libsodium/dist-build/osx.sh @@ -0,0 +1,26 @@ +#! /bin/sh + +export PREFIX="$(pwd)/libsodium-osx" +export MACOS_VERSION_MIN=${MACOS_VERSION_MIN-"10.10"} + +if [ -z "$LIBSODIUM_FULL_BUILD" ]; then + export LIBSODIUM_ENABLE_MINIMAL_FLAG="--enable-minimal" +else + export LIBSODIUM_ENABLE_MINIMAL_FLAG="" +fi + +NPROCESSORS=$(getconf NPROCESSORS_ONLN 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null) +PROCESSORS=${NPROCESSORS:-3} + +mkdir -p $PREFIX || exit 1 + +export CFLAGS="-mmacosx-version-min=${MACOS_VERSION_MIN} -O2 -g" +export LDFLAGS="-mmacosx-version-min=${MACOS_VERSION_MIN}" + +make distclean >/dev/null +./configure ${LIBSODIUM_ENABLE_MINIMAL_FLAG} \ + --prefix="$PREFIX" || exit 1 +make -j${PROCESSORS} check && make -j${PROCESSORS} install || exit 1 + +# Cleanup +make distclean >/dev/null diff --git a/external/src/libsodium/dist-build/wasm32-wasi.sh b/external/src/libsodium/dist-build/wasm32-wasi.sh new file mode 100644 index 0000000..cab8f34 --- /dev/null +++ b/external/src/libsodium/dist-build/wasm32-wasi.sh @@ -0,0 +1,43 @@ +#! /bin/sh + +export PATH="/opt/zig/bin:/opt/zig:/usr/local/opt/llvm/bin:$PATH" + +export PREFIX="$(pwd)/libsodium-wasm32-wasi" + +mkdir -p $PREFIX || exit 1 + +export CC="zig cc" +export CFLAGS="-DED25519_NONDETERMINISTIC=1 --target=wasm32-wasi -O2" +export LDFLAGS="-s -Wl,--stack-first" +export AR="zig ar" +export RANLIB="zig ranlib" + +make distclean >/dev/null + +if [ "x$1" = "x--bench" ]; then + export BENCHMARKS=1 + export CPPFLAGS="-DBENCHMARKS -DITERATIONS=100" +fi + +if [ -n "$LIBSODIUM_MINIMAL_BUILD" ]; then + export LIBSODIUM_ENABLE_MINIMAL_FLAG="--enable-minimal" +else + export LIBSODIUM_ENABLE_MINIMAL_FLAG="" +fi + +if ! ./configure ${LIBSODIUM_ENABLE_MINIMAL_FLAG} \ + --prefix="$PREFIX" \ + --host=wasm32-wasi \ + --disable-ssp --disable-shared --without-pthreads; then + cat config.log + exit 1 +fi + +NPROCESSORS=$(getconf NPROCESSORS_ONLN 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null) +PROCESSORS=${NPROCESSORS:-3} + +if [ -z "$BENCHMARKS" ]; then + make -j${PROCESSORS} check && make install && make distclean >/dev/null +else + make -j${PROCESSORS} && make check +fi diff --git a/external/src/libsodium/dist-build/watchos.sh b/external/src/libsodium/dist-build/watchos.sh new file mode 100644 index 0000000..60ab4b4 --- /dev/null +++ b/external/src/libsodium/dist-build/watchos.sh @@ -0,0 +1,114 @@ +#! /bin/sh +# +# Step 1. +# Configure for base system so simulator is covered +# +# Step 2. +# Make for watchOS and watchOS simulator +# +# Step 3. +# Merge libs into final version for xcode import + +export PREFIX="$(pwd)/libsodium-watchos" +export WATCHOS32_PREFIX="$PREFIX/tmp/watchos32" +export WATCHOS64_32_PREFIX="$PREFIX/tmp/watchos64_32" +export SIMULATOR32_PREFIX="$PREFIX/tmp/simulator32" +export SIMULATOR64_PREFIX="$PREFIX/tmp/simulator64" +export XCODEDIR=$(xcode-select -p) + +export WATCHOS_SIMULATOR_VERSION_MIN=${WATCHOS_SIMULATOR_VERSION_MIN-"4.0.0"} +export WATCHOS_VERSION_MIN=${WATCHOS_VERSION_MIN-"4.0.0"} + +mkdir -p $SIMULATOR32_PREFIX $SIMULATOR64_PREFIX $WATCHOS32_PREFIX $WATCHOS64_32_PREFIX || exit 1 + +# Build for the simulator +export BASEDIR="${XCODEDIR}/Platforms/WatchSimulator.platform/Developer" +export PATH="${BASEDIR}/usr/bin:$BASEDIR/usr/sbin:$PATH" +export SDK="${BASEDIR}/SDKs/WatchSimulator.sdk" + +## i386 simulator +export CFLAGS="-O2 -arch i386 -isysroot ${SDK} -mwatchos-simulator-version-min=${WATCHOS_SIMULATOR_VERSION_MIN}" +export LDFLAGS="-arch i386 -isysroot ${SDK} -mwatchos-simulator-version-min=${WATCHOS_SIMULATOR_VERSION_MIN}" + +make distclean > /dev/null + +if [ -z "$LIBSODIUM_FULL_BUILD" ]; then + export LIBSODIUM_ENABLE_MINIMAL_FLAG="--enable-minimal" +else + export LIBSODIUM_ENABLE_MINIMAL_FLAG="" +fi + +./configure --host=i686-apple-darwin10 \ + --disable-shared \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} \ + --prefix="$SIMULATOR32_PREFIX" || exit 1 + + +NPROCESSORS=$(getconf NPROCESSORS_ONLN 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null) +PROCESSORS=${NPROCESSORS:-3} + +make -j${PROCESSORS} install || exit 1 + +## x86_64 simulator +export CFLAGS="-O2 -arch x86_64 -isysroot ${SDK} -mwatchos-simulator-version-min=${WATCHOS_SIMULATOR_VERSION_MIN}" +export LDFLAGS="-arch x86_64 -isysroot ${SDK} -mwatchos-simulator-version-min=${WATCHOS_SIMULATOR_VERSION_MIN}" + +make distclean > /dev/null + +./configure --host=x86_64-apple-darwin10 \ + --disable-shared \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} \ + --prefix="$SIMULATOR64_PREFIX" + +make -j${PROCESSORS} install || exit 1 + +# Build for watchOS +export BASEDIR="${XCODEDIR}/Platforms/WatchOS.platform/Developer" +export PATH="${BASEDIR}/usr/bin:$BASEDIR/usr/sbin:$PATH" +export SDK="${BASEDIR}/SDKs/WatchOS.sdk" + +## 32-bit watchOS +export CFLAGS="-fembed-bitcode -O2 -mthumb -arch armv7k -isysroot ${SDK} -mwatchos-version-min=${WATCHOS_VERSION_MIN}" +export LDFLAGS="-fembed-bitcode -mthumb -arch armv7k -isysroot ${SDK} -mwatchos-version-min=${WATCHOS_VERSION_MIN}" + +make distclean > /dev/null + +./configure --host=arm-apple-darwin10 \ + --disable-shared \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} \ + --prefix="$WATCHOS32_PREFIX" || exit 1 + +make -j${PROCESSORS} install || exit 1 + +## 64-bit arm64_32 watchOS +export CFLAGS="-fembed-bitcode -O2 -mthumb -arch arm64_32 -isysroot ${SDK} -mwatchos-version-min=${WATCHOS_VERSION_MIN}" +export LDFLAGS="-fembed-bitcode -mthumb -arch arm64_32 -isysroot ${SDK} -mwatchos-version-min=${WATCHOS_VERSION_MIN}" + +make distclean > /dev/null + +./configure --host=arm-apple-darwin10 \ + --disable-shared \ + ${LIBSODIUM_ENABLE_MINIMAL_FLAG} \ + --prefix="$WATCHOS64_32_PREFIX" || exit 1 + +make -j${PROCESSORS} install || exit 1 + +# Create universal binary and include folder +rm -fr -- "$PREFIX/include" "$PREFIX/libsodium.a" 2> /dev/null +mkdir -p -- "$PREFIX/lib" +lipo -create \ + "$SIMULATOR32_PREFIX/lib/libsodium.a" \ + "$SIMULATOR64_PREFIX/lib/libsodium.a" \ + "$WATCHOS32_PREFIX/lib/libsodium.a" \ + "$WATCHOS64_32_PREFIX/lib/libsodium.a" \ + -output "$PREFIX/lib/libsodium.a" +mv -f -- "$WATCHOS32_PREFIX/include" "$PREFIX/" + +echo +echo "libsodium has been installed into $PREFIX" +echo +file -- "$PREFIX/lib/libsodium.a" + +# Cleanup +rm -rf -- "$PREFIX/tmp" +make distclean > /dev/null diff --git a/external/src/libsodium/lgtm.yml b/external/src/libsodium/lgtm.yml new file mode 100644 index 0000000..5c97238 --- /dev/null +++ b/external/src/libsodium/lgtm.yml @@ -0,0 +1,6 @@ +extraction: + cpp: + configure: + command: + - ./autogen.sh -s + - ./configure diff --git a/external/src/libsodium/libsodium-uninstalled.pc.in b/external/src/libsodium/libsodium-uninstalled.pc.in new file mode 100644 index 0000000..068a9c6 --- /dev/null +++ b/external/src/libsodium/libsodium-uninstalled.pc.in @@ -0,0 +1,7 @@ +Name: @PACKAGE_NAME@ +Version: @PACKAGE_VERSION@ +Description: A modern and easy-to-use crypto library + +Libs: -L${pcfiledir}/src/libsodium -lsodium +Libs.private: @PKGCONFIG_LIBS_PRIVATE@ +Cflags: -I${pcfiledir}/src/libsodium/include -I@top_srcdir@/src/libsodium/include -I@top_srcdir@/src/libsodium/include/sodium diff --git a/external/src/libsodium/libsodium.pc.in b/external/src/libsodium/libsodium.pc.in new file mode 100644 index 0000000..6c2b43a --- /dev/null +++ b/external/src/libsodium/libsodium.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: @PACKAGE_NAME@ +Version: @PACKAGE_VERSION@ +Description: A modern and easy-to-use crypto library + +Libs: -L${libdir} -lsodium +Libs.private: @PKGCONFIG_LIBS_PRIVATE@ +Cflags: -I${includedir} diff --git a/external/src/libsodium/libsodium.sln b/external/src/libsodium/libsodium.sln new file mode 100644 index 0000000..0afec29 --- /dev/null +++ b/external/src/libsodium/libsodium.sln @@ -0,0 +1,40 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsodium", "libsodium.vcxproj", "{A185B162-6CB6-4502-B03F-B56F7699A8D9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + DebugDLL|Win32 = DebugDLL|Win32 + DebugDLL|x64 = DebugDLL|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + ReleaseDLL|Win32 = ReleaseDLL|Win32 + ReleaseDLL|x64 = ReleaseDLL|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|Win32.ActiveCfg = Debug|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|Win32.Build.0 = Debug|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x64.ActiveCfg = Debug|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Debug|x64.Build.0 = Debug|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|x64.ActiveCfg = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.DebugDLL|x64.Build.0 = DebugDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|Win32.ActiveCfg = Release|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|Win32.Build.0 = Release|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x64.ActiveCfg = Release|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.Release|x64.Build.0 = Release|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|Win32.ActiveCfg = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|Win32.Build.0 = ReleaseDLL|Win32 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|x64.ActiveCfg = ReleaseDLL|x64 + {A185B162-6CB6-4502-B03F-B56F7699A8D9}.ReleaseDLL|x64.Build.0 = ReleaseDLL|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/external/src/libsodium/libsodium.vcxproj b/external/src/libsodium/libsodium.vcxproj new file mode 100644 index 0000000..1d4a9d8 --- /dev/null +++ b/external/src/libsodium/libsodium.vcxproj @@ -0,0 +1,563 @@ + + + + + DebugDLL + Win32 + + + DebugDLL + x64 + + + Debug + Win32 + + + Debug + x64 + + + ReleaseDLL + Win32 + + + ReleaseDLL + x64 + + + Release + Win32 + + + Release + x64 + + + + {A185B162-6CB6-4502-B03F-B56F7699A8D9} + Win32Proj + libsodium + + + + StaticLibrary + true + MultiByte + false + v140 + + + DynamicLibrary + true + MultiByte + false + v140 + + + StaticLibrary + true + MultiByte + false + v140 + + + DynamicLibrary + true + MultiByte + false + v140 + + + StaticLibrary + false + true + MultiByte + v140 + + + DynamicLibrary + false + true + MultiByte + v140 + + + StaticLibrary + false + true + MultiByte + v140 + + + DynamicLibrary + false + true + MultiByte + v140 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + true + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + true + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + true + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + false + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + false + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + false + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + false + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + + + + Level3 + Disabled + SODIUM_STATIC;SODIUM_EXPORT=;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDebug + $(SolutionDir);$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include;%(AdditionalIncludeDirectories) + + + Console + true + + + + + + + Level3 + Disabled + SODIUM_EXPORT=__declspec(dllexport);SODIUM_DLL_EXPORT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDebugDLL + $(SolutionDir);$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include;%(AdditionalIncludeDirectories) + + + Console + true + + + + + + + Level3 + Disabled + SODIUM_STATIC;SODIUM_EXPORT=;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDebug + + + Console + true + + + + + + + Level3 + Disabled + SODIUM_EXPORT=__declspec(dllexport);SODIUM_DLL_EXPORT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDebugDLL + + + Console + true + + + + + Level3 + + + Full + true + true + SODIUM_STATIC;SODIUM_EXPORT=;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreaded + Speed + $(SolutionDir);$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + + + Full + true + true + SODIUM_EXPORT=__declspec(dllexport);SODIUM_DLL_EXPORT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDLL + Speed + $(SolutionDir);$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + SODIUM_STATIC;SODIUM_EXPORT=;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreaded + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + SODIUM_EXPORT=__declspec(dllexport);SODIUM_DLL_EXPORT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDLL + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/src/libsodium/libsodium.vcxproj.filters b/external/src/libsodium/libsodium.vcxproj.filters new file mode 100644 index 0000000..473d105 --- /dev/null +++ b/external/src/libsodium/libsodium.vcxproj.filters @@ -0,0 +1,723 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + diff --git a/external/src/libsodium/logo.png b/external/src/libsodium/logo.png new file mode 100644 index 0000000..0f193a1 Binary files /dev/null and b/external/src/libsodium/logo.png differ diff --git a/external/src/libsodium/m4/ax_add_fortify_source.m4 b/external/src/libsodium/m4/ax_add_fortify_source.m4 new file mode 100644 index 0000000..b88d496 --- /dev/null +++ b/external/src/libsodium/m4/ax_add_fortify_source.m4 @@ -0,0 +1,74 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_add_fortify_source.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_ADD_FORTIFY_SOURCE +# +# DESCRIPTION +# +# Check whether -D_FORTIFY_SOURCE=2 can be added to CPPFLAGS without macro +# redefinition warnings or linker errors. Some distributions (such as +# Gentoo Linux) enable _FORTIFY_SOURCE globally in their compilers, +# leading to unnecessary warnings in the form of +# +# :0:0: error: "_FORTIFY_SOURCE" redefined [-Werror] +# : note: this is the location of the previous definition +# +# which is a problem if -Werror is enabled. This macro checks whether +# _FORTIFY_SOURCE is already defined, and if not, adds -D_FORTIFY_SOURCE=2 +# to CPPFLAGS. +# +# Newer mingw-w64 msys2 package comes with a bug in +# headers-git-7.0.0.5546.d200317d-1. It broke -D_FORTIFY_SOURCE +# support, and would need -lssp or -fstack-protector. See +# https://github.com/msys2/MINGW-packages/issues/5803. Try to +# actually link it. +# +# LICENSE +# +# Copyright (c) 2017 David Seifert +# Copyright (c) 2019 Reini Urban +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 3 + +AC_DEFUN([AX_ADD_FORTIFY_SOURCE],[ + AC_MSG_CHECKING([whether to add -D_FORTIFY_SOURCE=2 to CPPFLAGS]) + AC_LINK_IFELSE([ + AC_LANG_PROGRAM([], + [[ + #ifndef _FORTIFY_SOURCE + return 0; + #else + this_is_an_error; + #endif + ]] + )], + AC_LINK_IFELSE([ + AC_LANG_SOURCE([[ + #define _FORTIFY_SOURCE 2 + #include + int main() { + const char *s = " "; + strcpy(s, "x"); + return strlen(s)-1; + } + ]] + )], + [ + AC_MSG_RESULT([yes]) + CPPFLAGS="$CPPFLAGS -D_FORTIFY_SOURCE=2" + ], [ + AC_MSG_RESULT([no]) + ], + ), + [ + AC_MSG_RESULT([no]) + ]) +]) diff --git a/external/src/libsodium/m4/ax_check_catchable_abrt.m4 b/external/src/libsodium/m4/ax_check_catchable_abrt.m4 new file mode 100644 index 0000000..9983262 --- /dev/null +++ b/external/src/libsodium/m4/ax_check_catchable_abrt.m4 @@ -0,0 +1,57 @@ +# SYNOPSIS +# +# AX_CHECK_CATCHABLE_ABRT +# +# DESCRIPTION +# +# Check whether SIGABRT can be caught using signal handlers. + +#serial 1 + +AC_DEFUN([AX_CHECK_CATCHABLE_ABRT], [dnl + AC_PREREQ(2.64) + AS_VAR_PUSHDEF([CACHEVAR], [ax_cv_check_[]_AC_LANG_ABBREV[]CATCHABLE_ABRT])dnl + AC_CACHE_CHECK([whether SIGABRT can be caught], CACHEVAR, [ + AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[ +#include +#include + +#ifndef SIGABRT +# error SIGABRT is not defined +#endif + +static void sigabrt_handler_3(int _) +{ + exit(0); +} + +static void sigabrt_handler_2(int _) +{ + signal(SIGABRT, sigabrt_handler_3); + abort(); + exit(1); +} + +static void sigabrt_handler_1(int _) +{ + signal(SIGABRT, sigabrt_handler_2); + abort(); + exit(1); +} + ]], [[ +signal(SIGABRT, sigabrt_handler_1); +abort(); +exit(1); + ]])], + [AS_VAR_SET(CACHEVAR, [yes])], + [AS_VAR_SET(CACHEVAR, [no])], + [AS_VAR_SET(CACHEVAR, [unknown])] + ) + ]) + AS_VAR_IF(CACHEVAR, yes, + [AC_DEFINE([HAVE_CATCHABLE_ABRT], [1], [Define if SIGABRT can be caught using signal handlers])], + [AC_MSG_WARN([On this platform, SIGABRT cannot be caught using signal handlers.])] + ) + AS_VAR_POPDEF([CACHEVAR])dnl +]) diff --git a/external/src/libsodium/m4/ax_check_catchable_segv.m4 b/external/src/libsodium/m4/ax_check_catchable_segv.m4 new file mode 100644 index 0000000..d8c7b68 --- /dev/null +++ b/external/src/libsodium/m4/ax_check_catchable_segv.m4 @@ -0,0 +1,42 @@ +# SYNOPSIS +# +# AX_CHECK_CATCHABLE_SEGV +# +# DESCRIPTION +# +# Check whether segmentation violations can be caught using signal handlers. + +#serial 1 + +AC_DEFUN([AX_CHECK_CATCHABLE_SEGV], [dnl + AC_PREREQ(2.64) + AS_VAR_PUSHDEF([CACHEVAR], [ax_cv_check_[]_AC_LANG_ABBREV[]CATCHABLE_SEGV])dnl + AC_CACHE_CHECK([whether segmentation violations can be caught], CACHEVAR, [ + AC_RUN_IFELSE([ + AC_LANG_PROGRAM([[ +#include +#include +static void sig(int _) { exit(0); } + ]], [[ +volatile unsigned char * volatile x = (volatile unsigned char *) malloc(8); +size_t i; + +signal(SIGSEGV, sig); +signal(SIGBUS, sig); +#if !defined(__SANITIZE_ADDRESS__) && !defined(__EMSCRIPTEN__) +for (i = 0; i < 10000000; i += 1024) { x[-i] = x[i] = (unsigned char) i; } +#endif +free((void *) x); +exit(1) + ]])], + [AS_VAR_SET(CACHEVAR, [yes])], + [AS_VAR_SET(CACHEVAR, [no])], + [AS_VAR_SET(CACHEVAR, [unknown])] + ) + ]) + AS_VAR_IF(CACHEVAR, yes, + [AC_DEFINE([HAVE_CATCHABLE_SEGV], [1], [Define if segmentation violations can be caught using signal handlers])], + [AC_MSG_WARN([On this platform, segmentation violations cannot be caught using signal handlers. This is expected if you enabled a tool such as Address Sanitizer (-fsanitize=address), but be aware that using Address Sanitizer may also significantly reduce performance.])] + ) + AS_VAR_POPDEF([CACHEVAR])dnl +]) diff --git a/external/src/libsodium/m4/ax_check_compile_flag.m4 b/external/src/libsodium/m4/ax_check_compile_flag.m4 new file mode 100644 index 0000000..b197d06 --- /dev/null +++ b/external/src/libsodium/m4/ax_check_compile_flag.m4 @@ -0,0 +1,55 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 6 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM( +[#include ], [time_t x; int fodder = 0; if (fodder > -1000 && time(&x)) return (int) x] + )])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/external/src/libsodium/m4/ax_check_define.m4 b/external/src/libsodium/m4/ax_check_define.m4 new file mode 100644 index 0000000..20ba808 --- /dev/null +++ b/external/src/libsodium/m4/ax_check_define.m4 @@ -0,0 +1,92 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_define.html +# =========================================================================== +# +# SYNOPSIS +# +# AC_CHECK_DEFINE([symbol], [ACTION-IF-FOUND], [ACTION-IF-NOT]) +# AX_CHECK_DEFINE([includes],[symbol], [ACTION-IF-FOUND], [ACTION-IF-NOT]) +# +# DESCRIPTION +# +# Complements AC_CHECK_FUNC but it does not check for a function but for a +# define to exist. Consider a usage like: +# +# AC_CHECK_DEFINE(__STRICT_ANSI__, CFLAGS="$CFLAGS -D_XOPEN_SOURCE=500") +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 9 + +AU_ALIAS([AC_CHECK_DEFINED], [AC_CHECK_DEFINE]) +AC_DEFUN([AC_CHECK_DEFINE],[ +AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$1])dnl +AC_CACHE_CHECK([for $1 defined], ac_var, +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ + #ifdef $1 + int ok; + #else + choke me + #endif +]])],[AS_VAR_SET(ac_var, yes)],[AS_VAR_SET(ac_var, no)])) +AS_IF([test AS_VAR_GET(ac_var) != "no"], [$2], [$3])dnl +AS_VAR_POPDEF([ac_var])dnl +]) + +AU_ALIAS([AX_CHECK_DEFINED], [AX_CHECK_DEFINE]) +AC_DEFUN([AX_CHECK_DEFINE],[ +AS_VAR_PUSHDEF([ac_var],[ac_cv_defined_$2_$1])dnl +AC_CACHE_CHECK([for $2 defined in $1], ac_var, +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <$1>]], [[ + #ifdef $2 + int ok; + #else + choke me + #endif +]])],[AS_VAR_SET(ac_var, yes)],[AS_VAR_SET(ac_var, no)])) +AS_IF([test AS_VAR_GET(ac_var) != "no"], [$3], [$4])dnl +AS_VAR_POPDEF([ac_var])dnl +]) + +AC_DEFUN([AX_CHECK_FUNC], +[AS_VAR_PUSHDEF([ac_var], [ac_cv_func_$2])dnl +AC_CACHE_CHECK([for $2], ac_var, +dnl AC_LANG_FUNC_LINK_TRY +[AC_LINK_IFELSE([AC_LANG_PROGRAM([$1 + #undef $2 + char $2 ();],[ + char (*f) () = $2; + return f != $2; ])], + [AS_VAR_SET(ac_var, yes)], + [AS_VAR_SET(ac_var, no)])]) +AS_IF([test AS_VAR_GET(ac_var) = yes], [$3], [$4])dnl +AS_VAR_POPDEF([ac_var])dnl +])# AC_CHECK_FUNC diff --git a/external/src/libsodium/m4/ax_check_gnu_make.m4 b/external/src/libsodium/m4/ax_check_gnu_make.m4 new file mode 100644 index 0000000..4c761ea --- /dev/null +++ b/external/src/libsodium/m4/ax_check_gnu_make.m4 @@ -0,0 +1,84 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_gnu_make.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_GNU_MAKE() +# +# DESCRIPTION +# +# This macro searches for a GNU version of make. If a match is found: +# +# * The makefile variable `ifGNUmake' is set to the empty string, otherwise +# it is set to "#". This is useful for including a special features in a +# Makefile, which cannot be handled by other versions of make. +# * The variable `_cv_gnu_make_command` is set to the command to invoke +# GNU make if it exists, the empty string otherwise. +# * The variable `ax_cv_gnu_make_command` is set to the command to invoke +# GNU make by copying `_cv_gnu_make_command`, otherwise it is unset. +# * If GNU Make is found, its version is extracted from the output of +# `make --version` as the last field of a record of space-separated +# columns and saved into the variable `ax_check_gnu_make_version`. +# +# Here is an example of its use: +# +# Makefile.in might contain: +# +# # A failsafe way of putting a dependency rule into a makefile +# $(DEPEND): +# $(CC) -MM $(srcdir)/*.c > $(DEPEND) +# +# @ifGNUmake@ ifeq ($(DEPEND),$(wildcard $(DEPEND))) +# @ifGNUmake@ include $(DEPEND) +# @ifGNUmake@ endif +# +# Then configure.in would normally contain: +# +# AX_CHECK_GNU_MAKE() +# AC_OUTPUT(Makefile) +# +# Then perhaps to cause gnu make to override any other make, we could do +# something like this (note that GNU make always looks for GNUmakefile +# first): +# +# if ! test x$_cv_gnu_make_command = x ; then +# mv Makefile GNUmakefile +# echo .DEFAULT: > Makefile ; +# echo \ $_cv_gnu_make_command \$@ >> Makefile; +# fi +# +# Then, if any (well almost any) other make is called, and GNU make also +# exists, then the other make wraps the GNU make. +# +# LICENSE +# +# Copyright (c) 2008 John Darrington +# Copyright (c) 2015 Enrico M. Crisostomo +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 9 + +AC_DEFUN([AX_CHECK_GNU_MAKE],dnl + [AC_PROG_AWK + AC_CACHE_CHECK([for GNU make],[_cv_gnu_make_command],[dnl + _cv_gnu_make_command="" ; +dnl Search all the common names for GNU make + for a in "$MAKE" make gmake gnumake ; do + if test -z "$a" ; then continue ; fi ; + if "$a" --version 2> /dev/null | grep GNU 2>&1 > /dev/null ; then + _cv_gnu_make_command=$a ; + AX_CHECK_GNU_MAKE_HEADLINE=$("$a" --version 2> /dev/null | grep "GNU Make") + ax_check_gnu_make_version=$(echo ${AX_CHECK_GNU_MAKE_HEADLINE} | ${AWK} -F " " '{ print $(NF); }') + break ; + fi + done ;]) +dnl If there was a GNU version, then set @ifGNUmake@ to the empty string, '#' otherwise + AS_VAR_IF([_cv_gnu_make_command], [""], [AS_VAR_SET([ifGNUmake], ["#"])], [AS_VAR_SET([ifGNUmake], [""])]) + AS_VAR_IF([_cv_gnu_make_command], [""], [AS_UNSET(ax_cv_gnu_make_command)], [AS_VAR_SET([ax_cv_gnu_make_command], [${_cv_gnu_make_command}])]) + AC_SUBST([ifGNUmake]) +]) diff --git a/external/src/libsodium/m4/ax_check_link_flag.m4 b/external/src/libsodium/m4/ax_check_link_flag.m4 new file mode 100644 index 0000000..06af181 --- /dev/null +++ b/external/src/libsodium/m4/ax_check_link_flag.m4 @@ -0,0 +1,75 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the linker or gives an error. +# (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the linker's default flags +# when the check is done. The check is thus made with the flags: "LDFLAGS +# EXTRA-FLAGS FLAG". This can for example be used to force the linker to +# issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_LINK_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 5 + +AC_DEFUN([AX_CHECK_LINK_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl +AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ + ax_check_save_flags=$LDFLAGS + LDFLAGS="$LDFLAGS $4 $1" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[time_t x; int fodder = 0; if (fodder > -1000 && time(&x)) return (int) x]])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + LDFLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_LINK_FLAGS diff --git a/external/src/libsodium/m4/ax_pthread.m4 b/external/src/libsodium/m4/ax_pthread.m4 new file mode 100644 index 0000000..e5858e5 --- /dev/null +++ b/external/src/libsodium/m4/ax_pthread.m4 @@ -0,0 +1,522 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is +# needed for multi-threaded programs (defaults to the value of CC +# respectively CXX otherwise). (This is necessary on e.g. AIX to use the +# special cc_r/CC_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also to link with them as well. For example, you might link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threaded programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# CXX="$PTHREAD_CXX" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to +# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2011 Daniel Richard G. +# Copyright (c) 2019 Marc Stevens +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 30 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_TARGET]) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_PROG_SED]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on Tru64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"]) + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) + AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = "xno"; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items with a "," contain both +# C compiler flags (before ",") and linker flags (after ","). Other items +# starting with a "-" are C compiler flags, and remaining items are +# library names, except for "none" which indicates that we try without +# any flags at all, and "pthread-config" which is a program returning +# the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads and +# -D_REENTRANT too), HP C (must be checked before -lpthread, which +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") +# -mthreads: Mingw32/gcc, Lynx/gcc +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case $target_os in + + freebsd*) + + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + + hpux*) + + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." + + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; + + openedition*) + + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) + + AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], + [ +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + ], + [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) + ;; + + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). + + ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" + ;; +esac + +# Are we compiling with Clang? + +AC_CACHE_CHECK([whether $CC is Clang], + [ax_cv_PTHREAD_CLANG], + [ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) + fi + ]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + + +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) + +# Note that for GCC and Clang -pthread generally implies -lpthread, +# except when -nostdlib is passed. +# This is problematic using libtool to build C++ shared libraries with pthread: +# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 +# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 +# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 +# To solve this, first try -pthread together with -lpthread for GCC + +AS_IF([test "x$GCC" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"]) + +# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first + +AS_IF([test "x$ax_pthread_clang" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread"]) + + +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled + +case $target_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; + + aix*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; + + *) + ax_pthread_check_macro="--" + ;; +esac +AS_IF([test "x$ax_pthread_check_macro" = "x--"], + [ax_pthread_check_cond=0], + [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) + + +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + + case $ax_pthread_try_flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + *,*) + PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` + PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` + AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"]) + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void *some_global = NULL; + static void routine(void *a) + { + /* To avoid any unused-parameter or + unused-but-set-parameter warning. */ + some_global = a; + } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + AC_MSG_RESULT([$ax_pthread_ok]) + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + + +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way + +if test "x$ax_pthread_clang" = "xyes"; then + + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac + +fi # $ax_pthread_clang = yes + + + +# Various other checks: +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_CACHE_CHECK([for joinable pthread attribute], + [ax_cv_PTHREAD_JOINABLE_ATTR], + [ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], + []) + done + ]) + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], + [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], + [$ax_cv_PTHREAD_JOINABLE_ATTR], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) + + AC_CACHE_CHECK([whether more special flags are required for pthreads], + [ax_cv_PTHREAD_SPECIAL_FLAGS], + [ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $target_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + ]) + AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"], + [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes]) + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + [ax_cv_PTHREAD_PRIO_INHERIT], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[int i = PTHREAD_PRIO_INHERIT; + return i;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != "xyes"; then + case $target_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [ + AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"]) + AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])]) + ], + [ + AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC]) + AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])]) + ] + ) + ]) + ;; + esac + fi +fi + +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" +test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" + +AC_SUBST([PTHREAD_LIBS]) +AC_SUBST([PTHREAD_CFLAGS]) +AC_SUBST([PTHREAD_CC]) +AC_SUBST([PTHREAD_CXX]) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test "x$ax_pthread_ok" = "xyes"; then + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/external/src/libsodium/m4/ax_tls.m4 b/external/src/libsodium/m4/ax_tls.m4 new file mode 100644 index 0000000..fb184fe --- /dev/null +++ b/external/src/libsodium/m4/ax_tls.m4 @@ -0,0 +1,71 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_tls.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_TLS([action-if-found], [action-if-not-found]) +# +# DESCRIPTION +# +# Provides a test for the compiler support of thread local storage (TLS) +# extensions. Defines TLS if it is found. Currently knows about C++11, +# GCC/ICC, and MSVC. I think SunPro uses the same as GCC, and Borland +# apparently supports either. +# +# LICENSE +# +# Copyright (c) 2008 Alan Woodland +# Copyright (c) 2010 Diego Elio Petteno` +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 15 + +AC_DEFUN([AX_TLS], [ + AC_MSG_CHECKING([for thread local storage (TLS) class]) + AC_CACHE_VAL([ac_cv_tls], + [for ax_tls_keyword in thread_local _Thread_local __thread '__declspec(thread)' none; do + AS_CASE([$ax_tls_keyword], + [none], [ac_cv_tls=none ; break], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [#include ], + [static $ax_tls_keyword int bar;] + )], + [ac_cv_tls=$ax_tls_keyword ; break], + [ac_cv_tls=none] + )] + ) + done ] + ) + AC_MSG_RESULT([$ac_cv_tls]) + + AS_IF([test "$ac_cv_tls" != "none"], + [AC_DEFINE_UNQUOTED([TLS],[$ac_cv_tls],[If the compiler supports a TLS storage class, define it to that here]) + m4_ifnblank([$1],[$1],[[:]])], + [m4_ifnblank([$2],[$2],[[:]])]) +]) diff --git a/external/src/libsodium/m4/ax_valgrind_check.m4 b/external/src/libsodium/m4/ax_valgrind_check.m4 new file mode 100644 index 0000000..876f887 --- /dev/null +++ b/external/src/libsodium/m4/ax_valgrind_check.m4 @@ -0,0 +1,241 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_VALGRIND_DFLT(memcheck|helgrind|drd|sgcheck, on|off) +# AX_VALGRIND_CHECK() +# +# DESCRIPTION +# +# AX_VALGRIND_CHECK checks whether Valgrind is present and, if so, allows +# running `make check` under a variety of Valgrind tools to check for +# memory and threading errors. +# +# Defines VALGRIND_CHECK_RULES which should be substituted in your +# Makefile; and $enable_valgrind which can be used in subsequent configure +# output. VALGRIND_ENABLED is defined and substituted, and corresponds to +# the value of the --enable-valgrind option, which defaults to being +# enabled if Valgrind is installed and disabled otherwise. Individual +# Valgrind tools can be disabled via --disable-valgrind-, the +# default is configurable via the AX_VALGRIND_DFLT command or is to use +# all commands not disabled via AX_VALGRIND_DFLT. All AX_VALGRIND_DFLT +# calls must be made before the call to AX_VALGRIND_CHECK. +# +# If unit tests are written using a shell script and automake's +# LOG_COMPILER system, the $(VALGRIND) variable can be used within the +# shell scripts to enable Valgrind, as described here: +# +# https://www.gnu.org/software/gnulib/manual/html_node/Running-self_002dtests-under-valgrind.html +# +# Usage example: +# +# configure.ac: +# +# AX_VALGRIND_DFLT([sgcheck], [off]) +# AX_VALGRIND_CHECK +# +# Makefile.am: +# +# @VALGRIND_CHECK_RULES@ +# VALGRIND_SUPPRESSIONS_FILES = my-project.supp +# EXTRA_DIST = my-project.supp +# +# This results in a "check-valgrind" rule being added to any Makefile.am +# which includes "@VALGRIND_CHECK_RULES@" (assuming the module has been +# configured with --enable-valgrind). Running `make check-valgrind` in +# that directory will run the module's test suite (`make check`) once for +# each of the available Valgrind tools (out of memcheck, helgrind and drd) +# while the sgcheck will be skipped unless enabled again on the +# commandline with --enable-valgrind-sgcheck. The results for each check +# will be output to test-suite-$toolname.log. The target will succeed if +# there are zero errors and fail otherwise. +# +# Alternatively, a "check-valgrind-$TOOL" rule will be added, for $TOOL in +# memcheck, helgrind, drd and sgcheck. These are useful because often only +# some of those tools can be ran cleanly on a codebase. +# +# The macro supports running with and without libtool. +# +# LICENSE +# +# Copyright (c) 2014, 2015, 2016 Philip Withnall +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 15 + +dnl Configured tools +m4_define([valgrind_tool_list], [[memcheck], [helgrind], [drd], [sgcheck]]) +m4_set_add_all([valgrind_exp_tool_set], [sgcheck]) +m4_foreach([vgtool], [valgrind_tool_list], + [m4_define([en_dflt_valgrind_]vgtool, [on])]) + +AC_DEFUN([AX_VALGRIND_DFLT],[ + m4_define([en_dflt_valgrind_$1], [$2]) +])dnl + +AC_DEFUN([AX_VALGRIND_CHECK],[ + dnl Check for --enable-valgrind + AC_ARG_ENABLE([valgrind], + [AS_HELP_STRING([--enable-valgrind], [Whether to enable Valgrind on the unit tests (requires GNU make)])], + [enable_valgrind=$enableval],[enable_valgrind=no]) + + AS_IF([test "$enable_valgrind" != "no"],[ + # Check for Valgrind. + AC_CHECK_PROG([VALGRIND],[valgrind],[valgrind]) + AS_IF([test "$VALGRIND" = ""],[ + AS_IF([test "$enable_valgrind" = "yes"],[ + AC_MSG_ERROR([Could not find valgrind; either install it or reconfigure with --disable-valgrind]) + ],[ + enable_valgrind=no + ]) + ],[ + enable_valgrind=yes + ]) + ]) + + AM_CONDITIONAL([VALGRIND_ENABLED],[test "$enable_valgrind" = "yes"]) + AC_SUBST([VALGRIND_ENABLED],[$enable_valgrind]) + + # Check for Valgrind tools we care about. + [valgrind_enabled_tools=] + m4_foreach([vgtool],[valgrind_tool_list],[ + AC_ARG_ENABLE([valgrind-]vgtool, + m4_if(m4_defn([en_dflt_valgrind_]vgtool),[off],dnl +[AS_HELP_STRING([--enable-valgrind-]vgtool, [Whether to use ]vgtool[ during the Valgrind tests])],dnl +[AS_HELP_STRING([--disable-valgrind-]vgtool, [Whether to skip ]vgtool[ during the Valgrind tests])]), + [enable_valgrind_]vgtool[=$enableval], + [enable_valgrind_]vgtool[=]) + AS_IF([test "$enable_valgrind" = "no"],[ + enable_valgrind_]vgtool[=no], + [test "$enable_valgrind_]vgtool[" ]dnl +m4_if(m4_defn([en_dflt_valgrind_]vgtool), [off], [= "yes"], [!= "no"]),[ + AC_CACHE_CHECK([for Valgrind tool ]vgtool, + [ax_cv_valgrind_tool_]vgtool,[ + ax_cv_valgrind_tool_]vgtool[=no + m4_set_contains([valgrind_exp_tool_set],vgtool, + [m4_define([vgtoolx],[exp-]vgtool)], + [m4_define([vgtoolx],vgtool)]) + AS_IF([`$VALGRIND --tool=]vgtoolx[ --help >/dev/null 2>&1`],[ + ax_cv_valgrind_tool_]vgtool[=yes + ]) + ]) + AS_IF([test "$ax_cv_valgrind_tool_]vgtool[" = "no"],[ + AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[ + AC_MSG_ERROR([Valgrind does not support ]vgtool[; reconfigure with --disable-valgrind-]vgtool) + ],[ + enable_valgrind_]vgtool[=no + ]) + ],[ + enable_valgrind_]vgtool[=yes + ]) + ]) + AS_IF([test "$enable_valgrind_]vgtool[" = "yes"],[ + valgrind_enabled_tools="$valgrind_enabled_tools ]m4_bpatsubst(vgtool,[^exp-])[" + ]) + AC_SUBST([ENABLE_VALGRIND_]vgtool,[$enable_valgrind_]vgtool) + ]) + AC_SUBST([valgrind_tools],["]m4_join([ ], valgrind_tool_list)["]) + AC_SUBST([valgrind_enabled_tools],[$valgrind_enabled_tools]) + +[VALGRIND_CHECK_RULES=' +# Valgrind check +# +# Optional: +# - VALGRIND_SUPPRESSIONS_FILES: Space-separated list of Valgrind suppressions +# files to load. (Default: empty) +# - VALGRIND_FLAGS: General flags to pass to all Valgrind tools. +# (Default: --num-callers=30) +# - VALGRIND_$toolname_FLAGS: Flags to pass to Valgrind $toolname (one of: +# memcheck, helgrind, drd, sgcheck). (Default: various) + +# Optional variables +VALGRIND_SUPPRESSIONS ?= $(addprefix --suppressions=,$(VALGRIND_SUPPRESSIONS_FILES)) +VALGRIND_FLAGS ?= --num-callers=30 +VALGRIND_memcheck_FLAGS ?= --leak-check=full --show-reachable=no +VALGRIND_helgrind_FLAGS ?= --history-level=approx +VALGRIND_drd_FLAGS ?= +VALGRIND_sgcheck_FLAGS ?= + +# Internal use +valgrind_log_files = $(addprefix test-suite-,$(addsuffix .log,$(valgrind_tools))) + +valgrind_memcheck_flags = --tool=memcheck $(VALGRIND_memcheck_FLAGS) +valgrind_helgrind_flags = --tool=helgrind $(VALGRIND_helgrind_FLAGS) +valgrind_drd_flags = --tool=drd $(VALGRIND_drd_FLAGS) +valgrind_sgcheck_flags = --tool=exp-sgcheck $(VALGRIND_sgcheck_FLAGS) + +valgrind_quiet = $(valgrind_quiet_$(V)) +valgrind_quiet_ = $(valgrind_quiet_$(AM_DEFAULT_VERBOSITY)) +valgrind_quiet_0 = --quiet +valgrind_v_use = $(valgrind_v_use_$(V)) +valgrind_v_use_ = $(valgrind_v_use_$(AM_DEFAULT_VERBOSITY)) +valgrind_v_use_0 = @echo " USE " $(patsubst check-valgrind-%,%,$''@):; + +# Support running with and without libtool. +ifneq ($(LIBTOOL),) +valgrind_lt = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=execute +else +valgrind_lt = +endif + +# Use recursive makes in order to ignore errors during check +check-valgrind: +ifeq ($(VALGRIND_ENABLED),yes) + $(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k \ + $(foreach tool, $(valgrind_enabled_tools), check-valgrind-$(tool)) +else + @echo "Need to use GNU make and reconfigure with --enable-valgrind" +endif + +# Valgrind running +VALGRIND_TESTS_ENVIRONMENT = \ + $(TESTS_ENVIRONMENT) \ + env VALGRIND=$(VALGRIND) \ + G_SLICE=always-malloc,debug-blocks \ + G_DEBUG=fatal-warnings,fatal-criticals,gc-friendly + +VALGRIND_LOG_COMPILER = \ + $(valgrind_lt) \ + $(VALGRIND) $(VALGRIND_SUPPRESSIONS) --error-exitcode=1 $(VALGRIND_FLAGS) + +define valgrind_tool_rule = +check-valgrind-$(1): +ifeq ($$(VALGRIND_ENABLED)-$$(ENABLE_VALGRIND_$(1)),yes-yes) + $$(valgrind_v_use)$$(MAKE) check-TESTS \ + TESTS_ENVIRONMENT="$$(VALGRIND_TESTS_ENVIRONMENT)" \ + LOG_COMPILER="$$(VALGRIND_LOG_COMPILER)" \ + LOG_FLAGS="$$(valgrind_$(1)_flags)" \ + TEST_SUITE_LOG=test-suite-$(1).log +else ifeq ($$(VALGRIND_ENABLED),yes) + @echo "Need to reconfigure with --enable-valgrind-$(1)" +else + @echo "Need to reconfigure with --enable-valgrind" +endif +endef + +$(foreach tool,$(valgrind_tools),$(eval $(call valgrind_tool_rule,$(tool)))) + +A''M_DISTCHECK_CONFIGURE_FLAGS ?= +A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-valgrind + +MOSTLYCLEANFILES ?= +MOSTLYCLEANFILES += $(valgrind_log_files) + +.PHONY: check-valgrind $(add-prefix check-valgrind-,$(valgrind_tools)) +'] + + AS_IF([test "$enable_valgrind" != "yes"], [ + VALGRIND_CHECK_RULES=' +check-valgrind: + @echo "Need to use GNU make and reconfigure with --enable-valgrind"' + ]) + + AC_SUBST([VALGRIND_CHECK_RULES]) + m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([VALGRIND_CHECK_RULES])]) +]) diff --git a/external/src/libsodium/m4/ld-output-def.m4 b/external/src/libsodium/m4/ld-output-def.m4 new file mode 100644 index 0000000..59895bc --- /dev/null +++ b/external/src/libsodium/m4/ld-output-def.m4 @@ -0,0 +1,29 @@ +# ld-output-def.m4 serial 2 +dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Simon Josefsson + +# gl_LD_OUTPUT_DEF() +# ------------- +# Check if linker supports -Wl,--output-def and define automake +# conditional HAVE_LD_OUTPUT_DEF if it is. +AC_DEFUN([gl_LD_OUTPUT_DEF], +[ + AC_CACHE_CHECK([if gcc/ld supports -Wl,--output-def], + [gl_cv_ld_output_def], + [if test "$enable_shared" = no; then + gl_cv_ld_output_def="not needed, shared libraries are disabled" + else + gl_ldflags_save=$LDFLAGS + LDFLAGS="-Wl,--output-def,conftest.def" + AC_LINK_IFELSE([AC_LANG_PROGRAM([])], + [gl_cv_ld_output_def=yes], + [gl_cv_ld_output_def=no]) + rm -f conftest.def + LDFLAGS="$gl_ldflags_save" + fi]) + AM_CONDITIONAL([HAVE_LD_OUTPUT_DEF], test "x$gl_cv_ld_output_def" = "xyes") +]) diff --git a/external/src/libsodium/msvc-scripts/Makefile.am b/external/src/libsodium/msvc-scripts/Makefile.am new file mode 100644 index 0000000..1648192 --- /dev/null +++ b/external/src/libsodium/msvc-scripts/Makefile.am @@ -0,0 +1,4 @@ +EXTRA_DIST = \ + process.bat \ + rep.vbs \ + sodium.props diff --git a/external/src/libsodium/msvc-scripts/process.bat b/external/src/libsodium/msvc-scripts/process.bat new file mode 100644 index 0000000..291679e --- /dev/null +++ b/external/src/libsodium/msvc-scripts/process.bat @@ -0,0 +1,5 @@ +cscript msvc-scripts/rep.vbs //Nologo s/@VERSION@/1.0.18/ < src\libsodium\include\sodium\version.h.in > tmp +cscript msvc-scripts/rep.vbs //Nologo s/@SODIUM_LIBRARY_VERSION_MAJOR@/10/ < tmp > tmp2 +cscript msvc-scripts/rep.vbs //Nologo s/@SODIUM_LIBRARY_VERSION_MINOR@/3/ < tmp2 > tmp3 +cscript msvc-scripts/rep.vbs //Nologo s/@SODIUM_LIBRARY_MINIMAL_DEF@// < tmp3 > src\libsodium\include\sodium\version.h +del tmp tmp2 tmp3 diff --git a/external/src/libsodium/msvc-scripts/rep.vbs b/external/src/libsodium/msvc-scripts/rep.vbs new file mode 100644 index 0000000..3611f6c --- /dev/null +++ b/external/src/libsodium/msvc-scripts/rep.vbs @@ -0,0 +1,12 @@ +Dim pat, patparts, rxp, inp +pat = WScript.Arguments(0) +patparts = Split(pat, "/") +Set rxp = new RegExp +rxp.Global = True +rxp.Multiline = False +rxp.Pattern = patparts(1) +Do While Not WScript.StdIn.AtEndOfStream + inp = WScript.StdIn.ReadLine() + WScript.Echo rxp.Replace(inp, patparts(2)) +Loop + diff --git a/external/src/libsodium/msvc-scripts/sodium.props b/external/src/libsodium/msvc-scripts/sodium.props new file mode 100644 index 0000000..41e1e47 --- /dev/null +++ b/external/src/libsodium/msvc-scripts/sodium.props @@ -0,0 +1,28 @@ + + + + + + + + $(SolutionDir);$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include;%(AdditionalIncludeDirectories) + true + UNICODE;_UNICODE;%(PreprocessorDefinitions) + NATIVE_LITTLE_ENDIAN=1;%(PreprocessorDefinitions) + inline=__inline;%(PreprocessorDefinitions) + + + "$(SolutionDir)/msvc-scripts/process.bat" + + + Process .in files + + + "$(SolutionDir)/test/default/wintest.bat" $(Configuration) $(Platform) + + + Run the test suite + + + + diff --git a/external/src/libsodium/packaging/dotnet-core/libsodium.pkgproj b/external/src/libsodium/packaging/dotnet-core/libsodium.pkgproj new file mode 100644 index 0000000..ccc0a9e --- /dev/null +++ b/external/src/libsodium/packaging/dotnet-core/libsodium.pkgproj @@ -0,0 +1,37 @@ + + + + netstandard2.0 + true + false + true + + + + libsodium + 1.0.18.1 + Frank Denis + Internal implementation package not meant for direct consumption. Please do not reference directly. + © $([System.DateTime]::UtcNow.ToString(yyyy)) Frank Denis + ISC + true + https://libsodium.org/ + https://github.com/jedisct1/libsodium.git + git + 4.0 + + + + + + + + + + + + + + + + diff --git a/external/src/libsodium/packaging/dotnet-core/test.cs b/external/src/libsodium/packaging/dotnet-core/test.cs new file mode 100644 index 0000000..1ddab23 --- /dev/null +++ b/external/src/libsodium/packaging/dotnet-core/test.cs @@ -0,0 +1,43 @@ +using System; +using System.Runtime.InteropServices; + +internal static class Program +{ + internal static int Main() + { + Console.WriteLine("sodium_version_string: {0}", Marshal.PtrToStringAnsi(sodium_version_string())); + Console.WriteLine("sodium_library_version_major: {0}", sodium_library_version_major()); + Console.WriteLine("sodium_library_version_minor: {0}", sodium_library_version_minor()); + Console.WriteLine("sodium_library_minimal: {0}", sodium_library_minimal()); + int error = sodium_init(); + Console.WriteLine("sodium_init: {0}", error); + if (error == 0) + { + randombytes_buf(out ulong buf, (UIntPtr)sizeof(ulong)); + Console.WriteLine("randombytes_buf: 0x'{0:X8}'", buf); + Console.WriteLine("crypto_aead_aes256gcm_is_available: {0}", crypto_aead_aes256gcm_is_available()); + } + return error == 0 ? 0 : 1; + } + + [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)] + private static extern int crypto_aead_aes256gcm_is_available(); + + [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)] + private static extern void randombytes_buf(out ulong buf, UIntPtr size); + + [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)] + private static extern int sodium_init(); + + [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)] + private static extern int sodium_library_version_major(); + + [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)] + private static extern int sodium_library_minimal(); + + [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)] + private static extern int sodium_library_version_minor(); + + [DllImport("libsodium", CallingConvention = CallingConvention.Cdecl)] + private static extern IntPtr sodium_version_string(); +} diff --git a/external/src/libsodium/packaging/nuget/.gitignore b/external/src/libsodium/packaging/nuget/.gitignore new file mode 100644 index 0000000..d4b1a8c --- /dev/null +++ b/external/src/libsodium/packaging/nuget/.gitignore @@ -0,0 +1,4 @@ +*.nupkg +package.nuspec +package.targets +package.xml diff --git a/external/src/libsodium/packaging/nuget/package.bat b/external/src/libsodium/packaging/nuget/package.bat new file mode 100644 index 0000000..565a96b --- /dev/null +++ b/external/src/libsodium/packaging/nuget/package.bat @@ -0,0 +1,13 @@ +@ECHO OFF +ECHO Started nuget packaging build. +ECHO. +REM https://www.nuget.org/packages/gsl +gsl -q -script:package.gsl package.config +ECHO. +REM https://nuget.codeplex.com/releases +nuget pack package.nuspec -verbosity detailed +ECHO. +ECHO NOTE: Ignore warnings not applicable to native code: "Issue: Assembly outside lib folder." +ECHO. +ECHO Completed nuget packaging build. The package is in the following folder: +CD diff --git a/external/src/libsodium/packaging/nuget/package.config b/external/src/libsodium/packaging/nuget/package.config new file mode 100644 index 0000000..729035f --- /dev/null +++ b/external/src/libsodium/packaging/nuget/package.config @@ -0,0 +1,4 @@ + + + + diff --git a/external/src/libsodium/packaging/nuget/package.gsl b/external/src/libsodium/packaging/nuget/package.gsl new file mode 100644 index 0000000..5b255e5 --- /dev/null +++ b/external/src/libsodium/packaging/nuget/package.gsl @@ -0,0 +1,260 @@ +.# Generate NuGet nuspec file (for subsequent packing). +.# +.# This is a code generator built using the iMatix GSL code generation +.# language. See https://github.com/imatix/gsl for details. This script +.# is licensed under MIT/X11. +.# +.echo "Generating package.nuspec from template." +.output "package.nuspec" + + + + + $(package.id) + $(package.version) + $(package.id) + libsodium contributors + Eric Voskuil + https://raw.github.com/jedisct1/libsodium/master/LICENSE + https://github.com/jedisct1/libsodium + http://upload.wikimedia.org/wikipedia/commons/thumb/7/78/Salt_shaker_on_white_background.jpg/220px-Salt_shaker_on_white_background.jpg + true + false + Sodium is a portable, cross-compilable, installable, packageable fork of NaCl, with a compatible API. + Portable fork of NaCl, packaged for Visual Studio 2013 (v120) and CTP_Nov2013 compilers. + https://raw.github.com/jedisct1/libsodium/master/ChangeLog + (c) 2013-2019, Frank Denis (attribution required) + native, NaCl, salt, sodium, libsodium, C++ + +.for dependency + +.endfor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +.echo "Generating package.targets from template." +.output "package.targets" + + + + + + + + + + + + + $\(MSBuildThisFileDirectory)include\\;%(AdditionalIncludeDirectories) + + + advapi32.lib;crypt32.lib;%(AdditionalDependencies) + $\(MSBuildThisFileDirectory)bin\\;%(AdditionalLibraryDirectories) + + + + + SODIUM_STATIC;%(PreprocessorDefinitions) + + + + + + + $(package.target)-x86-$(package.platformtoolset)-mt-s-$(package.pathversion).lib;%(AdditionalDependencies) + + + + + $(package.target)-x86-$(package.platformtoolset)-mt-sgd-$(package.pathversion).lib;%(AdditionalDependencies) + + + + + $(package.target)-x64-$(package.platformtoolset)-mt-s-$(package.pathversion).lib;%(AdditionalDependencies) + + + + + $(package.target)-x64-$(package.platformtoolset)-mt-sgd-$(package.pathversion).lib;%(AdditionalDependencies) + + + + + + + $(package.target)-x86-$(package.platformtoolset)-mt-s-$(package.pathversion).ltcg.lib;%(AdditionalDependencies) + + + + + $(package.target)-x86-$(package.platformtoolset)-mt-sgd-$(package.pathversion).ltcg.lib;%(AdditionalDependencies) + + + + + $(package.target)-x64-$(package.platformtoolset)-mt-s-$(package.pathversion).ltcg.lib;%(AdditionalDependencies) + + + + + $(package.target)-x64-$(package.platformtoolset)-mt-sgd-$(package.pathversion).ltcg.lib;%(AdditionalDependencies) + + + + + + + $(package.target)-x86-$(package.platformtoolset)-mt-$(package.pathversion).imp.lib;%(AdditionalDependencies) + + + + + $(package.target)-x86-$(package.platformtoolset)-mt-gd-$(package.pathversion).imp.lib;%(AdditionalDependencies) + + + + + $(package.target)-x64-$(package.platformtoolset)-mt-$(package.pathversion).imp.lib;%(AdditionalDependencies) + + + + + $(package.target)-x64-$(package.platformtoolset)-mt-gd-$(package.pathversion).imp.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + +.echo "Generating package.xml (ui extension) from template." +.output "package.xml" + + + + + + + + + + + + + + + + + + diff --git a/external/src/libsodium/regen-msvc/libsodium.vcxproj b/external/src/libsodium/regen-msvc/libsodium.vcxproj new file mode 100644 index 0000000..ecdca90 --- /dev/null +++ b/external/src/libsodium/regen-msvc/libsodium.vcxproj @@ -0,0 +1,326 @@ + + + + + DebugDLL + Win32 + + + DebugDLL + x64 + + + Debug + Win32 + + + Debug + x64 + + + ReleaseDLL + Win32 + + + ReleaseDLL + x64 + + + Release + Win32 + + + Release + x64 + + + + {A185B162-6CB6-4502-B03F-B56F7699A8D9} + Win32Proj + libsodium + + + + StaticLibrary + true + MultiByte + false + v140 + + + DynamicLibrary + true + MultiByte + false + v140 + + + StaticLibrary + true + MultiByte + false + v140 + + + DynamicLibrary + true + MultiByte + false + v140 + + + StaticLibrary + false + true + MultiByte + v140 + + + DynamicLibrary + false + true + MultiByte + v140 + + + StaticLibrary + false + true + MultiByte + v140 + + + DynamicLibrary + false + true + MultiByte + v140 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + true + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + true + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + true + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + false + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + false + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + false + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + false + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + + + + Level3 + Disabled + SODIUM_STATIC;SODIUM_EXPORT=;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDebug + $(SolutionDir);$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include;%(AdditionalIncludeDirectories) + + + Console + true + + + + + + + Level3 + Disabled + SODIUM_EXPORT=__declspec(dllexport);SODIUM_DLL_EXPORT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDebugDLL + $(SolutionDir);$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include;%(AdditionalIncludeDirectories) + + + Console + true + + + + + + + Level3 + Disabled + SODIUM_STATIC;SODIUM_EXPORT=;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDebug + + + Console + true + + + + + + + Level3 + Disabled + SODIUM_EXPORT=__declspec(dllexport);SODIUM_DLL_EXPORT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDebugDLL + + + Console + true + + + + + Level3 + + + Full + true + true + SODIUM_STATIC;SODIUM_EXPORT=;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreaded + Speed + $(SolutionDir);$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + + + Full + true + true + SODIUM_EXPORT=__declspec(dllexport);SODIUM_DLL_EXPORT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDLL + Speed + $(SolutionDir);$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + SODIUM_STATIC;SODIUM_EXPORT=;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreaded + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + SODIUM_EXPORT=__declspec(dllexport);SODIUM_DLL_EXPORT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDLL + + + Console + true + true + true + + + + + + + + + + + + diff --git a/external/src/libsodium/regen-msvc/libsodium.vcxproj.filters b/external/src/libsodium/regen-msvc/libsodium.vcxproj.filters new file mode 100644 index 0000000..1b4637d --- /dev/null +++ b/external/src/libsodium/regen-msvc/libsodium.vcxproj.filters @@ -0,0 +1,23 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + + + + + diff --git a/external/src/libsodium/regen-msvc/libsodium.vcxproj.filters.tpl b/external/src/libsodium/regen-msvc/libsodium.vcxproj.filters.tpl new file mode 100644 index 0000000..abe9247 --- /dev/null +++ b/external/src/libsodium/regen-msvc/libsodium.vcxproj.filters.tpl @@ -0,0 +1,35 @@ + + + + + packaging + + + packaging + + + packaging + + + packaging + + + packaging + + + packaging + + + + + + + {{f1}} + + + {{f2}} + + + {{fd}} + + diff --git a/external/src/libsodium/regen-msvc/libsodium.vcxproj.tpl b/external/src/libsodium/regen-msvc/libsodium.vcxproj.tpl new file mode 100644 index 0000000..179ce26 --- /dev/null +++ b/external/src/libsodium/regen-msvc/libsodium.vcxproj.tpl @@ -0,0 +1,93 @@ + + + + {A185B162-6CB6-4502-B03F-B56F7699A8D9} + libsodium + {{platform}} + + + + DebugDLL + Win32 + + + ReleaseDLL + Win32 + + + DebugDLL + x64 + + + ReleaseDLL + x64 + + + DebugLTCG + Win32 + + + ReleaseLTCG + Win32 + + + DebugLTCG + x64 + + + ReleaseLTCG + x64 + + + DebugLIB + Win32 + + + ReleaseLIB + Win32 + + + DebugLIB + x64 + + + ReleaseLIB + x64 + + + + StaticLibrary + DynamicLibrary + + + + + + + + + + + + + + + + + + + + {{v1}} + + + {{v2}} + + + + + + + + + + diff --git a/external/src/libsodium/regen-msvc/regen-msvc.py b/external/src/libsodium/regen-msvc/regen-msvc.py new file mode 100644 index 0000000..9a2c87a --- /dev/null +++ b/external/src/libsodium/regen-msvc/regen-msvc.py @@ -0,0 +1,185 @@ +#! /usr/bin/env python3 + +import glob +import os +import uuid + +dirs = set() + +tlv1 = "" +for file in glob.iglob("src/libsodium/**/*.c", recursive=True): + file = file.replace("/", "\\") + tlv1 = tlv1 + ' \r\n'.format(file) + +tlv2 = "" +for file in glob.iglob("src/libsodium/**/*.h", recursive=True): + file = file.replace("/", "\\") + tlv2 = tlv2 + ' \r\n'.format(file) + +tlf1 = "" +for file in glob.iglob("src/libsodium/**/*.c", recursive=True): + file = file.replace("/", "\\") + tlf1 = tlf1 + ' \r\n'.format(file) + tlf1 = tlf1 + " Source Files\r\n" + tlf1 = tlf1 + " \r\n" + +tlf2 = "" +for file in glob.iglob("src/libsodium/**/*.h", recursive=True): + file = file.replace("/", "\\") + tlf2 = tlf2 + ' \r\n'.format(file) + tlf2 = tlf2 + " Header Files\r\n" + tlf2 = tlf2 + " \r\n" + +v1 = "" +for file in glob.iglob("src/libsodium/**/*.c", recursive=True): + file = file.replace("/", "\\") + v1 = v1 + ' \r\n'.format(file) + +v2 = "" +for file in glob.iglob("src/libsodium/**/*.h", recursive=True): + file = file.replace("/", "\\") + v2 = v2 + ' \r\n'.format(file) + +f1 = "" +for file in glob.iglob("src/libsodium/**/*.c", recursive=True): + basedir = os.path.dirname(file).replace("src/libsodium/", "") + t = basedir + while t != "": + dirs.add(t) + t = os.path.dirname(t) + basedir = basedir.replace("/", "\\") + file = file.replace("/", "\\") + f1 = f1 + ' \r\n'.format(file) + f1 = f1 + " {}\r\n".format(basedir) + f1 = f1 + " \r\n" + +f2 = "" +for file in glob.iglob("src/libsodium/**/*.h", recursive=True): + basedir = os.path.dirname(file).replace("src/libsodium/", "") + t = basedir + while t != "": + dirs.add(t) + t = os.path.dirname(t) + basedir = basedir.replace("/", "\\") + file = file.replace("/", "\\") + f2 = f2 + ' \r\n'.format(file) + f2 = f2 + " {}\r\n".format(basedir) + f2 = f2 + " \r\n" + +fd = "" +dirs = list(dirs) +dirs.sort() +for dir in dirs: + dir = dir.replace("/", "\\") + uid = uuid.uuid3(uuid.UUID(bytes=b"LibSodiumMSVCUID"), dir) + fd = fd + ' \r\n'.format(dir) + fd = fd + " {{{}}}\r\n".format(uid) + fd = fd + " \r\n" + + +def apply_template(tplfile, outfile, sbox): + tpl = "" + with open(tplfile, "rb") as fd: + tpl = fd.read() + for s in sbox.keys(): + tpl = tpl.replace( + str.encode("{{" + s + "}}", "utf8"), str.encode(str.strip(sbox[s]), "utf8") + ) + + with open(outfile, "wb") as fd: + fd.write(tpl) + + +sbox = { + "tlv1": tlv1, + "tlv2": tlv2, + "tlf1": tlf1, + "tlf2": tlf2, + "v1": v1, + "v2": v2, + "f1": f1, + "f2": f2, + "fd": fd, +} + +sd = os.path.dirname(os.path.realpath(__file__)) + +apply_template( + sd + "/tl_libsodium.vcxproj.filters.tpl", "libsodium.vcxproj.filters", sbox +) + +sbox.update({"platform": "v140"}) +apply_template(sd + "/tl_libsodium.vcxproj.tpl", "libsodium.vcxproj", sbox) + +apply_template( + sd + "/libsodium.vcxproj.filters.tpl", + "builds/msvc/vs2019/libsodium/libsodium.vcxproj.filters", + sbox, +) +apply_template( + sd + "/libsodium.vcxproj.filters.tpl", + "builds/msvc/vs2017/libsodium/libsodium.vcxproj.filters", + sbox, +) +apply_template( + sd + "/libsodium.vcxproj.filters.tpl", + "builds/msvc/vs2015/libsodium/libsodium.vcxproj.filters", + sbox, +) +apply_template( + sd + "/libsodium.vcxproj.filters.tpl", + "builds/msvc/vs2013/libsodium/libsodium.vcxproj.filters", + sbox, +) +apply_template( + sd + "/libsodium.vcxproj.filters.tpl", + "builds/msvc/vs2012/libsodium/libsodium.vcxproj.filters", + sbox, +) +apply_template( + sd + "/libsodium.vcxproj.filters.tpl", + "builds/msvc/vs2010/libsodium/libsodium.vcxproj.filters", + sbox, +) + +sbox.update({"platform": "v142"}) +apply_template( + sd + "/libsodium.vcxproj.tpl", + "builds/msvc/vs2019/libsodium/libsodium.vcxproj", + sbox, +) + +sbox.update({"platform": "v141"}) +apply_template( + sd + "/libsodium.vcxproj.tpl", + "builds/msvc/vs2017/libsodium/libsodium.vcxproj", + sbox, +) + +sbox.update({"platform": "v140"}) +apply_template( + sd + "/libsodium.vcxproj.tpl", + "builds/msvc/vs2015/libsodium/libsodium.vcxproj", + sbox, +) + +sbox.update({"platform": "v120"}) +apply_template( + sd + "/libsodium.vcxproj.tpl", + "builds/msvc/vs2013/libsodium/libsodium.vcxproj", + sbox, +) + +sbox.update({"platform": "v110"}) +apply_template( + sd + "/libsodium.vcxproj.tpl", + "builds/msvc/vs2012/libsodium/libsodium.vcxproj", + sbox, +) + +sbox.update({"platform": "v100"}) +apply_template( + sd + "/libsodium.vcxproj.tpl", + "builds/msvc/vs2010/libsodium/libsodium.vcxproj", + sbox, +) diff --git a/external/src/libsodium/regen-msvc/tl_libsodium.vcxproj.filters.tpl b/external/src/libsodium/regen-msvc/tl_libsodium.vcxproj.filters.tpl new file mode 100644 index 0000000..f024d61 --- /dev/null +++ b/external/src/libsodium/regen-msvc/tl_libsodium.vcxproj.filters.tpl @@ -0,0 +1,23 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + {{tlf1}} + + + {{tlf2}} + + diff --git a/external/src/libsodium/regen-msvc/tl_libsodium.vcxproj.tpl b/external/src/libsodium/regen-msvc/tl_libsodium.vcxproj.tpl new file mode 100644 index 0000000..5319ca0 --- /dev/null +++ b/external/src/libsodium/regen-msvc/tl_libsodium.vcxproj.tpl @@ -0,0 +1,331 @@ + + + + + DebugDLL + Win32 + + + DebugDLL + x64 + + + Debug + Win32 + + + Debug + x64 + + + ReleaseDLL + Win32 + + + ReleaseDLL + x64 + + + Release + Win32 + + + Release + x64 + + + + {A185B162-6CB6-4502-B03F-B56F7699A8D9} + Win32Proj + libsodium + + + + StaticLibrary + true + MultiByte + false + {{platform}} + + + DynamicLibrary + true + MultiByte + false + {{platform}} + + + StaticLibrary + true + MultiByte + false + {{platform}} + + + DynamicLibrary + true + MultiByte + false + {{platform}} + + + StaticLibrary + false + true + MultiByte + {{platform}} + + + DynamicLibrary + false + true + MultiByte + {{platform}} + + + StaticLibrary + false + true + MultiByte + {{platform}} + + + DynamicLibrary + false + true + MultiByte + {{platform}} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + true + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + true + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + true + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + false + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + false + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + false + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + false + $(SolutionDir)Build\$(Configuration)\$(Platform)\ + $(SolutionDir)Build\$(Configuration)\$(Platform)\Intermediate\ + + + + + + Level3 + Disabled + SODIUM_STATIC;SODIUM_EXPORT=;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDebug + $(SolutionDir);$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include;%(AdditionalIncludeDirectories) + + + Console + true + + + + + + + Level3 + Disabled + SODIUM_EXPORT=__declspec(dllexport);SODIUM_DLL_EXPORT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDebugDLL + $(SolutionDir);$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include;%(AdditionalIncludeDirectories) + + + Console + true + + + + + + + Level3 + Disabled + SODIUM_STATIC;SODIUM_EXPORT=;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDebug + + + Console + true + + + + + + + Level3 + Disabled + SODIUM_EXPORT=__declspec(dllexport);SODIUM_DLL_EXPORT;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDebugDLL + + + Console + true + + + + + Level3 + + + Full + true + true + SODIUM_STATIC;SODIUM_EXPORT=;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreaded + Speed + $(SolutionDir);$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + + + Full + true + true + SODIUM_EXPORT=__declspec(dllexport);SODIUM_DLL_EXPORT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDLL + Speed + $(SolutionDir);$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include\sodium;$(SolutionDir)src\libsodium\include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + SODIUM_STATIC;SODIUM_EXPORT=;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreaded + + + Console + true + true + true + + + + + Level3 + + + MaxSpeed + true + true + SODIUM_EXPORT=__declspec(dllexport);SODIUM_DLL_EXPORT;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;%(DisableSpecificWarnings) + MultiThreadedDLL + + + Console + true + true + true + + + + {{tlv1}} + + + {{tlv2}} + + + + + + + + + + diff --git a/external/src/libsodium/src/Makefile.am b/external/src/libsodium/src/Makefile.am new file mode 100644 index 0000000..6444504 --- /dev/null +++ b/external/src/libsodium/src/Makefile.am @@ -0,0 +1,3 @@ + +SUBDIRS = \ + libsodium diff --git a/external/src/libsodium/src/libsodium/Makefile.am b/external/src/libsodium/src/libsodium/Makefile.am new file mode 100644 index 0000000..92de4fd --- /dev/null +++ b/external/src/libsodium/src/libsodium/Makefile.am @@ -0,0 +1,284 @@ +lib_LTLIBRARIES = \ + libsodium.la + +libsodium_la_SOURCES = \ + crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c \ + crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c \ + crypto_auth/crypto_auth.c \ + crypto_auth/hmacsha256/auth_hmacsha256.c \ + crypto_auth/hmacsha512/auth_hmacsha512.c \ + crypto_auth/hmacsha512256/auth_hmacsha512256.c \ + crypto_box/crypto_box.c \ + crypto_box/crypto_box_easy.c \ + crypto_box/crypto_box_seal.c \ + crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305.c \ + crypto_core/ed25519/ref10/ed25519_ref10.c \ + crypto_core/hchacha20/core_hchacha20.c \ + crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.c \ + crypto_core/hsalsa20/core_hsalsa20.c \ + crypto_core/salsa/ref/core_salsa_ref.c \ + crypto_generichash/crypto_generichash.c \ + crypto_generichash/blake2b/generichash_blake2.c \ + crypto_generichash/blake2b/ref/blake2.h \ + crypto_generichash/blake2b/ref/blake2b-compress-ref.c \ + crypto_generichash/blake2b/ref/blake2b-load-sse2.h \ + crypto_generichash/blake2b/ref/blake2b-load-sse41.h \ + crypto_generichash/blake2b/ref/blake2b-load-avx2.h \ + crypto_generichash/blake2b/ref/blake2b-ref.c \ + crypto_generichash/blake2b/ref/generichash_blake2b.c \ + crypto_hash/crypto_hash.c \ + crypto_hash/sha256/hash_sha256.c \ + crypto_hash/sha256/cp/hash_sha256_cp.c \ + crypto_hash/sha512/hash_sha512.c \ + crypto_hash/sha512/cp/hash_sha512_cp.c \ + crypto_kdf/blake2b/kdf_blake2b.c \ + crypto_kdf/crypto_kdf.c \ + crypto_kx/crypto_kx.c \ + crypto_onetimeauth/crypto_onetimeauth.c \ + crypto_onetimeauth/poly1305/onetimeauth_poly1305.c \ + crypto_onetimeauth/poly1305/onetimeauth_poly1305.h \ + crypto_onetimeauth/poly1305/donna/poly1305_donna.h \ + crypto_onetimeauth/poly1305/donna/poly1305_donna32.h \ + crypto_onetimeauth/poly1305/donna/poly1305_donna64.h \ + crypto_onetimeauth/poly1305/donna/poly1305_donna.c \ + crypto_pwhash/argon2/argon2-core.c \ + crypto_pwhash/argon2/argon2-core.h \ + crypto_pwhash/argon2/argon2-encoding.c \ + crypto_pwhash/argon2/argon2-encoding.h \ + crypto_pwhash/argon2/argon2-fill-block-ref.c \ + crypto_pwhash/argon2/argon2.c \ + crypto_pwhash/argon2/argon2.h \ + crypto_pwhash/argon2/blake2b-long.c \ + crypto_pwhash/argon2/blake2b-long.h \ + crypto_pwhash/argon2/blamka-round-ref.h \ + crypto_pwhash/argon2/pwhash_argon2i.c \ + crypto_pwhash/argon2/pwhash_argon2id.c \ + crypto_pwhash/crypto_pwhash.c \ + crypto_scalarmult/crypto_scalarmult.c \ + crypto_scalarmult/curve25519/ref10/x25519_ref10.c \ + crypto_scalarmult/curve25519/ref10/x25519_ref10.h \ + crypto_scalarmult/curve25519/scalarmult_curve25519.c \ + crypto_scalarmult/curve25519/scalarmult_curve25519.h \ + crypto_secretbox/crypto_secretbox.c \ + crypto_secretbox/crypto_secretbox_easy.c \ + crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305.c \ + crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c \ + crypto_shorthash/crypto_shorthash.c \ + crypto_shorthash/siphash24/shorthash_siphash24.c \ + crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c \ + crypto_shorthash/siphash24/ref/shorthash_siphash_ref.h \ + crypto_sign/crypto_sign.c \ + crypto_sign/ed25519/sign_ed25519.c \ + crypto_sign/ed25519/ref10/keypair.c \ + crypto_sign/ed25519/ref10/open.c \ + crypto_sign/ed25519/ref10/sign.c \ + crypto_sign/ed25519/ref10/sign_ed25519_ref10.h \ + crypto_stream/chacha20/stream_chacha20.c \ + crypto_stream/chacha20/stream_chacha20.h \ + crypto_stream/chacha20/ref/chacha20_ref.h \ + crypto_stream/chacha20/ref/chacha20_ref.c \ + crypto_stream/crypto_stream.c \ + crypto_stream/salsa20/stream_salsa20.c \ + crypto_stream/salsa20/stream_salsa20.h \ + crypto_stream/xsalsa20/stream_xsalsa20.c \ + crypto_verify/sodium/verify.c \ + include/sodium/private/chacha20_ietf_ext.h \ + include/sodium/private/common.h \ + include/sodium/private/ed25519_ref10.h \ + include/sodium/private/implementations.h \ + include/sodium/private/mutex.h \ + include/sodium/private/sse2_64_32.h \ + randombytes/randombytes.c \ + sodium/codecs.c \ + sodium/core.c \ + sodium/runtime.c \ + sodium/utils.c \ + sodium/version.c + +if HAVE_TI_MODE +libsodium_la_SOURCES += \ + crypto_core/ed25519/ref10/fe_51/base.h \ + crypto_core/ed25519/ref10/fe_51/base2.h \ + crypto_core/ed25519/ref10/fe_51/constants.h \ + crypto_core/ed25519/ref10/fe_51/fe.h \ + include/sodium/private/ed25519_ref10_fe_51.h +else +libsodium_la_SOURCES += \ + crypto_core/ed25519/ref10/fe_25_5/base.h \ + crypto_core/ed25519/ref10/fe_25_5/base2.h \ + crypto_core/ed25519/ref10/fe_25_5/constants.h \ + crypto_core/ed25519/ref10/fe_25_5/fe.h \ + include/sodium/private/ed25519_ref10_fe_25_5.h +endif + +if HAVE_AMD64_ASM +libsodium_la_SOURCES += \ + crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S \ + crypto_stream/salsa20/xmm6/salsa20_xmm6.c \ + crypto_stream/salsa20/xmm6/salsa20_xmm6.h +else +libsodium_la_SOURCES += \ + crypto_stream/salsa20/ref/salsa20_ref.c \ + crypto_stream/salsa20/ref/salsa20_ref.h +endif + +noinst_HEADERS = \ + crypto_scalarmult/curve25519/sandy2x/consts.S \ + crypto_scalarmult/curve25519/sandy2x/fe51_mul.S \ + crypto_scalarmult/curve25519/sandy2x/fe51_nsquare.S \ + crypto_scalarmult/curve25519/sandy2x/fe51_pack.S \ + crypto_scalarmult/curve25519/sandy2x/ladder.S + +if HAVE_AVX_ASM +libsodium_la_SOURCES += \ + crypto_scalarmult/curve25519/sandy2x/consts_namespace.h \ + crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c \ + crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.h \ + crypto_scalarmult/curve25519/sandy2x/fe.h \ + crypto_scalarmult/curve25519/sandy2x/fe51.h \ + crypto_scalarmult/curve25519/sandy2x/fe51_invert.c \ + crypto_scalarmult/curve25519/sandy2x/fe51_namespace.h \ + crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c \ + crypto_scalarmult/curve25519/sandy2x/ladder.h \ + crypto_scalarmult/curve25519/sandy2x/ladder_namespace.h \ + crypto_scalarmult/curve25519/sandy2x/sandy2x.S +endif + +if !MINIMAL +libsodium_la_SOURCES += \ + crypto_box/curve25519xchacha20poly1305/box_curve25519xchacha20poly1305.c \ + crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c \ + crypto_core/ed25519/core_ed25519.c \ + crypto_core/ed25519/core_ristretto255.c \ + crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c \ + crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h \ + crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c \ + crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c \ + crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h \ + crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c \ + crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c \ + crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c \ + crypto_scalarmult/ristretto255/ref10/scalarmult_ristretto255_ref10.c \ + crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c \ + crypto_shorthash/siphash24/shorthash_siphashx24.c \ + crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c \ + crypto_sign/ed25519/ref10/obsolete.c \ + crypto_stream/salsa2012/ref/stream_salsa2012_ref.c \ + crypto_stream/salsa2012/stream_salsa2012.c \ + crypto_stream/salsa208/ref/stream_salsa208_ref.c \ + crypto_stream/salsa208/stream_salsa208.c \ + crypto_stream/xchacha20/stream_xchacha20.c +endif + +randombytes_internal_randombytes_internal_random_CFLAGS = @CFLAGS_RDRAND@ + +libsodium_la_LDFLAGS = \ + $(AM_LDFLAGS) \ + -export-dynamic \ + -no-undefined \ + $(LIBTOOL_EXTRA_FLAGS) + +libsodium_la_CPPFLAGS = \ + $(LTDLINCL) \ + -I$(srcdir)/include/sodium \ + -I$(builddir)/include/sodium + +if HAVE_LD_OUTPUT_DEF +libsodium_la_LDFLAGS += -Wl,--output-def,libsodium-$(DLL_VERSION).def +defexecdir = $(bindir) +defexec_DATA = libsodium-$(DLL_VERSION).def +CLEANFILES = $(defexec_DATA) +libsodium-$(DLL_VERSION).def: libsodium.la +endif + +SUBDIRS = \ + include + +libsodium_la_LIBADD = libaesni.la libsse2.la libssse3.la libsse41.la libavx2.la libavx512f.la +noinst_LTLIBRARIES = libaesni.la libsse2.la libssse3.la libsse41.la libavx2.la libavx512f.la + +librdrand_la_LDFLAGS = $(libsodium_la_LDFLAGS) +librdrand_la_CPPFLAGS = $(libsodium_la_CPPFLAGS) \ + @CFLAGS_RDRAND@ +librdrand_la_SOURCES = \ + randombytes/internal/randombytes_internal_random.c + +if !EMSCRIPTEN +libsodium_la_LIBADD += librdrand.la +noinst_LTLIBRARIES += librdrand.la + +libsodium_la_SOURCES += \ + randombytes/sysrandom/randombytes_sysrandom.c +endif + +libaesni_la_LDFLAGS = $(libsodium_la_LDFLAGS) +libaesni_la_CPPFLAGS = $(libsodium_la_CPPFLAGS) \ + @CFLAGS_SSE2@ @CFLAGS_SSSE3@ @CFLAGS_AESNI@ @CFLAGS_PCLMUL@ +libaesni_la_SOURCES = \ + crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c + +libsse2_la_LDFLAGS = $(libsodium_la_LDFLAGS) +libsse2_la_CPPFLAGS = $(libsodium_la_CPPFLAGS) \ + @CFLAGS_SSE2@ +libsse2_la_SOURCES = \ + crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c \ + crypto_onetimeauth/poly1305/sse2/poly1305_sse2.h +if !MINIMAL +libsse2_la_SOURCES += \ + crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c +endif + +if !HAVE_AMD64_ASM +libsse2_la_SOURCES += \ + crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c \ + crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.h \ + crypto_stream/salsa20/xmm6int/u0.h \ + crypto_stream/salsa20/xmm6int/u1.h \ + crypto_stream/salsa20/xmm6int/u4.h +endif + +libssse3_la_LDFLAGS = $(libsodium_la_LDFLAGS) +libssse3_la_CPPFLAGS = $(libsodium_la_CPPFLAGS) \ + @CFLAGS_SSE2@ @CFLAGS_SSSE3@ +libssse3_la_SOURCES = \ + crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c \ + crypto_generichash/blake2b/ref/blake2b-compress-ssse3.h \ + crypto_pwhash/argon2/argon2-fill-block-ssse3.c \ + crypto_pwhash/argon2/blamka-round-ssse3.h \ + crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c \ + crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.h \ + crypto_stream/chacha20/dolbeau/u0.h \ + crypto_stream/chacha20/dolbeau/u1.h \ + crypto_stream/chacha20/dolbeau/u4.h + +libsse41_la_LDFLAGS = $(libsodium_la_LDFLAGS) +libsse41_la_CPPFLAGS = $(libsodium_la_CPPFLAGS) \ + @CFLAGS_SSE2@ @CFLAGS_SSSE3@ @CFLAGS_SSE41@ +libsse41_la_SOURCES = \ + crypto_generichash/blake2b/ref/blake2b-compress-sse41.c \ + crypto_generichash/blake2b/ref/blake2b-compress-sse41.h + +libavx2_la_LDFLAGS = $(libsodium_la_LDFLAGS) +libavx2_la_CPPFLAGS = $(libsodium_la_CPPFLAGS) \ + @CFLAGS_SSE2@ @CFLAGS_SSSE3@ @CFLAGS_SSE41@ @CFLAGS_AVX@ @CFLAGS_AVX2@ +libavx2_la_SOURCES = \ + crypto_generichash/blake2b/ref/blake2b-compress-avx2.c \ + crypto_generichash/blake2b/ref/blake2b-compress-avx2.h \ + crypto_pwhash/argon2/argon2-fill-block-avx2.c \ + crypto_pwhash/argon2/blamka-round-avx2.h \ + crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c \ + crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.h \ + crypto_stream/chacha20/dolbeau/u8.h \ + crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c \ + crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.h \ + crypto_stream/salsa20/xmm6int/u0.h \ + crypto_stream/salsa20/xmm6int/u1.h \ + crypto_stream/salsa20/xmm6int/u4.h \ + crypto_stream/salsa20/xmm6int/u8.h + +libavx512f_la_LDFLAGS = $(libsodium_la_LDFLAGS) +libavx512f_la_CPPFLAGS = $(libsodium_la_CPPFLAGS) \ + @CFLAGS_SSE2@ @CFLAGS_SSSE3@ @CFLAGS_SSE41@ @CFLAGS_AVX@ @CFLAGS_AVX2@ @CFLAGS_AVX512F@ +libavx512f_la_SOURCES = \ + crypto_pwhash/argon2/argon2-fill-block-avx512f.c \ + crypto_pwhash/argon2/blamka-round-avx512f.h diff --git a/external/src/libsodium/src/libsodium/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c b/external/src/libsodium/src/libsodium/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c new file mode 100644 index 0000000..fbc6623 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c @@ -0,0 +1,1079 @@ + +/* + * AES256-GCM, based on the "Intel Carry-Less Multiplication Instruction and its Usage for Computing + * the GCM Mode" paper and reference code, using the aggregated reduction method. + * Originally adapted by Romain Dolbeau. + */ + +#include +#include +#include +#include + +#include "core.h" +#include "crypto_aead_aes256gcm.h" +#include "export.h" +#include "private/common.h" +#include "randombytes.h" +#include "runtime.h" +#include "utils.h" + +#if defined(HAVE_TMMINTRIN_H) && defined(HAVE_WMMINTRIN_H) + +#ifdef __GNUC__ +# pragma GCC target("ssse3") +# pragma GCC target("aes") +# pragma GCC target("pclmul") +#endif + +#include +#include +#include "private/sse2_64_32.h" + +#ifndef ENOSYS +# define ENOSYS ENXIO +#endif + +#if defined(__INTEL_COMPILER) || defined(_bswap64) +#elif defined(_MSC_VER) +# define _bswap64(a) _byteswap_uint64(a) +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) +# define _bswap64(a) __builtin_bswap64(a) +#else +static inline uint64_t +_bswap64(const uint64_t x) +{ + return + ((x << 56) & 0xFF00000000000000UL) | ((x << 40) & 0x00FF000000000000UL) | + ((x << 24) & 0x0000FF0000000000UL) | ((x << 8) & 0x000000FF00000000UL) | + ((x >> 8) & 0x00000000FF000000UL) | ((x >> 24) & 0x0000000000FF0000UL) | + ((x >> 40) & 0x000000000000FF00UL) | ((x >> 56) & 0x00000000000000FFUL); +} +#endif + +typedef struct aes256gcm_state { + __m128i rkeys[16]; + unsigned char H[16]; +} aes256gcm_state; + +static inline void +aesni_key256_expand(const unsigned char *key, __m128i * const rkeys) +{ + __m128i X0, X1, X2, X3; + int i = 0; + + X0 = _mm_loadu_si128((const __m128i *) &key[0]); + rkeys[i++] = X0; + + X2 = _mm_loadu_si128((const __m128i *) &key[16]); + rkeys[i++] = X2; + +#define EXPAND_KEY_1(S) do { \ + X1 = _mm_shuffle_epi32(_mm_aeskeygenassist_si128(X2, (S)), 0xff); \ + X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X0), 0x10)); \ + X0 = _mm_xor_si128(X0, X3); \ + X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X0), 0x8c)); \ + X0 = _mm_xor_si128(_mm_xor_si128(X0, X3), X1); \ + rkeys[i++] = X0; \ +} while (0) + +#define EXPAND_KEY_2(S) do { \ + X1 = _mm_shuffle_epi32(_mm_aeskeygenassist_si128(X0, (S)), 0xaa); \ + X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X2), 0x10)); \ + X2 = _mm_xor_si128(X2, X3); \ + X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X2), 0x8c)); \ + X2 = _mm_xor_si128(_mm_xor_si128(X2, X3), X1); \ + rkeys[i++] = X2; \ +} while (0) + + X3 = _mm_setzero_si128(); + EXPAND_KEY_1(0x01); EXPAND_KEY_2(0x01); + EXPAND_KEY_1(0x02); EXPAND_KEY_2(0x02); + EXPAND_KEY_1(0x04); EXPAND_KEY_2(0x04); + EXPAND_KEY_1(0x08); EXPAND_KEY_2(0x08); + EXPAND_KEY_1(0x10); EXPAND_KEY_2(0x10); + EXPAND_KEY_1(0x20); EXPAND_KEY_2(0x20); + EXPAND_KEY_1(0x40); +} + +/** single, by-the-book AES encryption with AES-NI */ +static inline void +aesni_encrypt1(unsigned char *out, __m128i nv, const __m128i *rkeys) +{ + __m128i temp = _mm_xor_si128(nv, rkeys[0]); + + temp = _mm_aesenc_si128(temp, rkeys[1]); + temp = _mm_aesenc_si128(temp, rkeys[2]); + temp = _mm_aesenc_si128(temp, rkeys[3]); + temp = _mm_aesenc_si128(temp, rkeys[4]); + temp = _mm_aesenc_si128(temp, rkeys[5]); + temp = _mm_aesenc_si128(temp, rkeys[6]); + temp = _mm_aesenc_si128(temp, rkeys[7]); + temp = _mm_aesenc_si128(temp, rkeys[8]); + temp = _mm_aesenc_si128(temp, rkeys[9]); + temp = _mm_aesenc_si128(temp, rkeys[10]); + temp = _mm_aesenc_si128(temp, rkeys[11]); + temp = _mm_aesenc_si128(temp, rkeys[12]); + temp = _mm_aesenc_si128(temp, rkeys[13]); + + temp = _mm_aesenclast_si128(temp, rkeys[14]); + _mm_storeu_si128((__m128i *) out, temp); +} + +/** multiple-blocks-at-once AES encryption with AES-NI ; + on Haswell, aesenc has a latency of 7 and a throughput of 1 + so the sequence of aesenc should be bubble-free if you + have at least 8 blocks. Let's build an arbitratry-sized + function */ +/* Step 1 : loading the nonce */ +/* load & increment the n vector (non-vectorized, unused for now) */ +#define NVDECLx(a) \ + __m128i nv##a + +#define NVx(a) \ + nv##a = _mm_shuffle_epi8(_mm_load_si128((const __m128i *) n), pt); \ + n[3]++ + +/* Step 2 : define value in round one (xor with subkey #0, aka key) */ +#define TEMPDECLx(a) \ + __m128i temp##a + +#define TEMPx(a) \ + temp##a = _mm_xor_si128(nv##a, rkeys[0]) + +/* Step 3: one round of AES */ +#define AESENCx(a) \ + temp##a = _mm_aesenc_si128(temp##a, rkeys[roundctr]) + +/* Step 4: last round of AES */ +#define AESENCLASTx(a) \ + temp##a = _mm_aesenclast_si128(temp##a, rkeys[14]) + +/* Step 5: store result */ +#define STOREx(a) \ + _mm_storeu_si128((__m128i *) (out + (a * 16)), temp##a) + +/* all the MAKE* macros are for automatic explicit unrolling */ +#define MAKE4(X) \ + X(0); \ + X(1); \ + X(2); \ + X(3) + +#define MAKE8(X) \ + X(0); \ + X(1); \ + X(2); \ + X(3); \ + X(4); \ + X(5); \ + X(6); \ + X(7) + +#define COUNTER_INC2(N) (N)[3] += 2 + +/* create a function of unrolling N ; the MAKEN is the unrolling + macro, defined above. The N in MAKEN must match N, obviously. */ +#define FUNC(N, MAKEN) \ + static inline void aesni_encrypt##N(unsigned char *out, uint32_t *n, const __m128i *rkeys) \ + { \ + const __m128i pt = _mm_set_epi8(12, 13, 14, 15, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ + int roundctr; \ + MAKEN(NVDECLx); \ + MAKEN(TEMPDECLx); \ + \ + MAKEN(NVx); \ + MAKEN(TEMPx); \ + for (roundctr = 1; roundctr < 14; roundctr++) { \ + MAKEN(AESENCx); \ + } \ + MAKEN(AESENCLASTx); \ + MAKEN(STOREx); \ + } + +FUNC(8, MAKE8) + +/* all GF(2^128) fnctions are by the book, meaning this one: + +*/ + +static inline void +addmul(unsigned char *c, const unsigned char *a, unsigned int xlen, const unsigned char *b) +{ + const __m128i rev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + __m128i A, B, C; + __m128i tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; + __m128i tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18; + __m128i tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27; + __m128i tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36; + + if (xlen >= 16) { + A = _mm_loadu_si128((const __m128i *) a); + } else { + CRYPTO_ALIGN(16) unsigned char padded[16]; + unsigned int i; + + memset(padded, 0, 16); + for (i = 0; i < xlen; i++) { + padded[i] = a[i]; + } + A = _mm_load_si128((const __m128i *) padded); + } + A = _mm_shuffle_epi8(A, rev); + B = _mm_loadu_si128((const __m128i *) b); + C = _mm_loadu_si128((const __m128i *) c); + A = _mm_xor_si128(A, C); + tmp3 = _mm_clmulepi64_si128(A, B, 0x00); + tmp4 = _mm_clmulepi64_si128(A, B, 0x10); + tmp5 = _mm_clmulepi64_si128(A, B, 0x01); + tmp6 = _mm_clmulepi64_si128(A, B, 0x11); + tmp10 = _mm_xor_si128(tmp4, tmp5); + tmp13 = _mm_slli_si128(tmp10, 8); + tmp11 = _mm_srli_si128(tmp10, 8); + tmp15 = _mm_xor_si128(tmp3, tmp13); + tmp17 = _mm_xor_si128(tmp6, tmp11); + tmp7 = _mm_srli_epi32(tmp15, 31); + tmp8 = _mm_srli_epi32(tmp17, 31); + tmp16 = _mm_slli_epi32(tmp15, 1); + tmp18 = _mm_slli_epi32(tmp17, 1); + tmp9 = _mm_srli_si128(tmp7, 12); + tmp22 = _mm_slli_si128(tmp8, 4); + tmp25 = _mm_slli_si128(tmp7, 4); + tmp29 = _mm_or_si128(tmp16, tmp25); + tmp19 = _mm_or_si128(tmp18, tmp22); + tmp20 = _mm_or_si128(tmp19, tmp9); + tmp26 = _mm_slli_epi32(tmp29, 31); + tmp23 = _mm_slli_epi32(tmp29, 30); + tmp32 = _mm_slli_epi32(tmp29, 25); + tmp27 = _mm_xor_si128(tmp26, tmp23); + tmp28 = _mm_xor_si128(tmp27, tmp32); + tmp24 = _mm_srli_si128(tmp28, 4); + tmp33 = _mm_slli_si128(tmp28, 12); + tmp30 = _mm_xor_si128(tmp29, tmp33); + tmp2 = _mm_srli_epi32(tmp30, 1); + tmp12 = _mm_srli_epi32(tmp30, 2); + tmp14 = _mm_srli_epi32(tmp30, 7); + tmp34 = _mm_xor_si128(tmp2, tmp12); + tmp35 = _mm_xor_si128(tmp34, tmp14); + tmp36 = _mm_xor_si128(tmp35, tmp24); + tmp31 = _mm_xor_si128(tmp30, tmp36); + tmp21 = _mm_xor_si128(tmp20, tmp31); + _mm_storeu_si128((__m128i *) c, tmp21); +} + +/* pure multiplication, for pre-computing powers of H */ +static inline __m128i +mulv(__m128i A, __m128i B) +{ + __m128i tmp3 = _mm_clmulepi64_si128(A, B, 0x00); + __m128i tmp4 = _mm_clmulepi64_si128(A, B, 0x10); + __m128i tmp5 = _mm_clmulepi64_si128(A, B, 0x01); + __m128i tmp6 = _mm_clmulepi64_si128(A, B, 0x11); + __m128i tmp10 = _mm_xor_si128(tmp4, tmp5); + __m128i tmp13 = _mm_slli_si128(tmp10, 8); + __m128i tmp11 = _mm_srli_si128(tmp10, 8); + __m128i tmp15 = _mm_xor_si128(tmp3, tmp13); + __m128i tmp17 = _mm_xor_si128(tmp6, tmp11); + __m128i tmp7 = _mm_srli_epi32(tmp15, 31); + __m128i tmp8 = _mm_srli_epi32(tmp17, 31); + __m128i tmp16 = _mm_slli_epi32(tmp15, 1); + __m128i tmp18 = _mm_slli_epi32(tmp17, 1); + __m128i tmp9 = _mm_srli_si128(tmp7, 12); + __m128i tmp22 = _mm_slli_si128(tmp8, 4); + __m128i tmp25 = _mm_slli_si128(tmp7, 4); + __m128i tmp29 = _mm_or_si128(tmp16, tmp25); + __m128i tmp19 = _mm_or_si128(tmp18, tmp22); + __m128i tmp20 = _mm_or_si128(tmp19, tmp9); + __m128i tmp26 = _mm_slli_epi32(tmp29, 31); + __m128i tmp23 = _mm_slli_epi32(tmp29, 30); + __m128i tmp32 = _mm_slli_epi32(tmp29, 25); + __m128i tmp27 = _mm_xor_si128(tmp26, tmp23); + __m128i tmp28 = _mm_xor_si128(tmp27, tmp32); + __m128i tmp24 = _mm_srli_si128(tmp28, 4); + __m128i tmp33 = _mm_slli_si128(tmp28, 12); + __m128i tmp30 = _mm_xor_si128(tmp29, tmp33); + __m128i tmp2 = _mm_srli_epi32(tmp30, 1); + __m128i tmp12 = _mm_srli_epi32(tmp30, 2); + __m128i tmp14 = _mm_srli_epi32(tmp30, 7); + __m128i tmp34 = _mm_xor_si128(tmp2, tmp12); + __m128i tmp35 = _mm_xor_si128(tmp34, tmp14); + __m128i tmp36 = _mm_xor_si128(tmp35, tmp24); + __m128i tmp31 = _mm_xor_si128(tmp30, tmp36); + __m128i C = _mm_xor_si128(tmp20, tmp31); + + return C; +} + +/* 4 multiply-accumulate at once; again + + for the Aggregated Reduction Method & sample code. + Algorithm by Krzysztof Jankowski, Pierre Laurent - Intel */ + +#define RED_DECL(a) __m128i H##a##_X##a##_lo, H##a##_X##a##_hi, tmp##a, tmp##a##B +#define RED_SHUFFLE(a) X##a = _mm_shuffle_epi8(X##a, rev) +#define RED_MUL_LOW(a) H##a##_X##a##_lo = _mm_clmulepi64_si128(H##a, X##a, 0x00) +#define RED_MUL_HIGH(a) H##a##_X##a##_hi = _mm_clmulepi64_si128(H##a, X##a, 0x11) +#define RED_MUL_MID(a) \ + tmp##a = _mm_shuffle_epi32(H##a, 0x4e); \ + tmp##a##B = _mm_shuffle_epi32(X##a, 0x4e); \ + tmp##a = _mm_xor_si128(tmp##a, H##a); \ + tmp##a##B = _mm_xor_si128(tmp##a##B, X##a); \ + tmp##a = _mm_clmulepi64_si128(tmp##a, tmp##a##B, 0x00) + +#define MULREDUCE4(rev, H0_, H1_, H2_, H3_, X0_, X1_, X2_, X3_, accv) \ +do { \ + MAKE4(RED_DECL); \ + __m128i lo, hi; \ + __m128i tmp8, tmp9; \ + __m128i H0 = H0_; \ + __m128i H1 = H1_; \ + __m128i H2 = H2_; \ + __m128i H3 = H3_; \ + __m128i X0 = X0_; \ + __m128i X1 = X1_; \ + __m128i X2 = X2_; \ + __m128i X3 = X3_; \ +\ +/* byte-revert the inputs & xor the first one into the accumulator */ \ +\ + MAKE4(RED_SHUFFLE); \ + X3 = _mm_xor_si128(X3, accv); \ +\ +/* 4 low H*X (x0*h0) */ \ +\ + MAKE4(RED_MUL_LOW); \ + lo = _mm_xor_si128(H0_X0_lo, H1_X1_lo); \ + lo = _mm_xor_si128(lo, H2_X2_lo); \ + lo = _mm_xor_si128(lo, H3_X3_lo); \ +\ +/* 4 high H*X (x1*h1) */ \ +\ + MAKE4(RED_MUL_HIGH); \ + hi = _mm_xor_si128(H0_X0_hi, H1_X1_hi); \ + hi = _mm_xor_si128(hi, H2_X2_hi); \ + hi = _mm_xor_si128(hi, H3_X3_hi); \ +\ +/* 4 middle H*X, using Karatsuba, i.e. \ + x1*h0+x0*h1 =(x1+x0)*(h1+h0)-x1*h1-x0*h0 \ + we already have all x1y1 & x0y0 (accumulated in hi & lo) \ + (0 is low half and 1 is high half) \ + */ \ +/* permute the high and low 64 bits in H1 & X1, \ + so create (h0,h1) from (h1,h0) and (x0,x1) from (x1,x0), \ + then compute (h0+h1,h1+h0) and (x0+x1,x1+x0), \ + and finally multiply \ + */ \ + MAKE4(RED_MUL_MID); \ +\ + /* subtracts x1*h1 and x0*h0 */ \ + tmp0 = _mm_xor_si128(tmp0, lo); \ + tmp0 = _mm_xor_si128(tmp0, hi); \ + tmp0 = _mm_xor_si128(tmp1, tmp0); \ + tmp0 = _mm_xor_si128(tmp2, tmp0); \ + tmp0 = _mm_xor_si128(tmp3, tmp0);\ +\ + /* reduction */ \ + tmp0B = _mm_slli_si128(tmp0, 8); \ + tmp0 = _mm_srli_si128(tmp0, 8); \ + lo = _mm_xor_si128(tmp0B, lo); \ + hi = _mm_xor_si128(tmp0, hi); \ + tmp3 = lo; \ + tmp2B = hi; \ + tmp3B = _mm_srli_epi32(tmp3, 31); \ + tmp8 = _mm_srli_epi32(tmp2B, 31); \ + tmp3 = _mm_slli_epi32(tmp3, 1); \ + tmp2B = _mm_slli_epi32(tmp2B, 1); \ + tmp9 = _mm_srli_si128(tmp3B, 12); \ + tmp8 = _mm_slli_si128(tmp8, 4); \ + tmp3B = _mm_slli_si128(tmp3B, 4); \ + tmp3 = _mm_or_si128(tmp3, tmp3B); \ + tmp2B = _mm_or_si128(tmp2B, tmp8); \ + tmp2B = _mm_or_si128(tmp2B, tmp9); \ + tmp3B = _mm_slli_epi32(tmp3, 31); \ + tmp8 = _mm_slli_epi32(tmp3, 30); \ + tmp9 = _mm_slli_epi32(tmp3, 25); \ + tmp3B = _mm_xor_si128(tmp3B, tmp8); \ + tmp3B = _mm_xor_si128(tmp3B, tmp9); \ + tmp8 = _mm_srli_si128(tmp3B, 4); \ + tmp3B = _mm_slli_si128(tmp3B, 12); \ + tmp3 = _mm_xor_si128(tmp3, tmp3B); \ + tmp2 = _mm_srli_epi32(tmp3, 1); \ + tmp0B = _mm_srli_epi32(tmp3, 2); \ + tmp1B = _mm_srli_epi32(tmp3, 7); \ + tmp2 = _mm_xor_si128(tmp2, tmp0B); \ + tmp2 = _mm_xor_si128(tmp2, tmp1B); \ + tmp2 = _mm_xor_si128(tmp2, tmp8); \ + tmp3 = _mm_xor_si128(tmp3, tmp2); \ + tmp2B = _mm_xor_si128(tmp2B, tmp3); \ +\ + accv = tmp2B; \ +} while(0) + +#define XORx(a) \ + temp##a = _mm_xor_si128(temp##a, \ + _mm_loadu_si128((const __m128i *) (in + a * 16))) + +#define LOADx(a) \ + __m128i in##a = _mm_loadu_si128((const __m128i *) (in + a * 16)) + +/* full encrypt & checksum 8 blocks at once */ +#define aesni_encrypt8full(out_, n_, rkeys, in_, accum, hv_, h2v_, h3v_, h4v_, rev) \ +do { \ + unsigned char *out = out_; \ + uint32_t *n = n_; \ + const unsigned char *in = in_; \ + const __m128i hv = hv_; \ + const __m128i h2v = h2v_; \ + const __m128i h3v = h3v_; \ + const __m128i h4v = h4v_; \ + const __m128i pt = _mm_set_epi8(12, 13, 14, 15, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ + __m128i accv_; \ + int roundctr; \ + \ + MAKE8(NVDECLx); \ + MAKE8(TEMPDECLx); \ + MAKE8(NVx); \ + MAKE8(TEMPx); \ + for (roundctr = 1; roundctr < 14; roundctr++) { \ + MAKE8(AESENCx); \ + } \ + MAKE8(AESENCLASTx); \ + MAKE8(XORx); \ + MAKE8(STOREx); \ + accv_ = _mm_load_si128((const __m128i *) accum); \ + MULREDUCE4(rev, hv, h2v, h3v, h4v, temp3, temp2, temp1, temp0, accv_); \ + MULREDUCE4(rev, hv, h2v, h3v, h4v, temp7, temp6, temp5, temp4, accv_); \ + _mm_store_si128((__m128i *) accum, accv_); \ +} while(0) + +/* checksum 8 blocks at once */ +#define aesni_addmul8full(in_, accum, hv_, h2v_, h3v_, h4v_, rev) \ +do { \ + const unsigned char *in = in_; \ + const __m128i hv = hv_; \ + const __m128i h2v = h2v_; \ + const __m128i h3v = h3v_; \ + const __m128i h4v = h4v_; \ + __m128i accv_; \ + \ + MAKE8(LOADx); \ + accv_ = _mm_load_si128((const __m128i *) accum); \ + MULREDUCE4(rev, hv, h2v, h3v, h4v, in3, in2, in1, in0, accv_); \ + MULREDUCE4(rev, hv, h2v, h3v, h4v, in7, in6, in5, in4, accv_); \ + _mm_store_si128((__m128i *) accum, accv_); \ +} while(0) + +/* decrypt 8 blocks at once */ +#define aesni_decrypt8full(out_, n_, rkeys, in_) \ +do { \ + unsigned char *out = out_; \ + uint32_t *n = n_; \ + const unsigned char *in = in_; \ + const __m128i pt = _mm_set_epi8(12, 13, 14, 15, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ + int roundctr; \ +\ + MAKE8(NVDECLx); \ + MAKE8(TEMPDECLx); \ + MAKE8(NVx); \ + MAKE8(TEMPx); \ + for (roundctr = 1; roundctr < 14; roundctr++) { \ + MAKE8(AESENCx); \ + } \ + MAKE8(AESENCLASTx); \ + MAKE8(XORx); \ + MAKE8(STOREx); \ +} while(0) + +int +crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_, + const unsigned char *k) +{ + aes256gcm_state *ctx = (aes256gcm_state *) (void *) ctx_; + unsigned char *H = ctx->H; + __m128i *rkeys = ctx->rkeys; + __m128i zero = _mm_setzero_si128(); + + COMPILER_ASSERT((sizeof *ctx_) >= (sizeof *ctx)); + aesni_key256_expand(k, rkeys); + aesni_encrypt1(H, zero, rkeys); + + return 0; +} + +int +crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c, + unsigned char *mac, unsigned long long *maclen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + const __m128i rev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + const aes256gcm_state *ctx = (const aes256gcm_state *) (const void *) ctx_; + const __m128i *rkeys = ctx->rkeys; + __m128i Hv, H2v, H3v, H4v, accv; + unsigned long long i, j; + unsigned long long adlen_rnd64 = adlen & ~63ULL; + unsigned long long mlen_rnd128 = mlen & ~127ULL; + CRYPTO_ALIGN(16) uint32_t n2[4]; + CRYPTO_ALIGN(16) unsigned char H[16]; + CRYPTO_ALIGN(16) unsigned char T[16]; + CRYPTO_ALIGN(16) unsigned char accum[16]; + CRYPTO_ALIGN(16) unsigned char fb[16]; + + (void) nsec; + memcpy(H, ctx->H, sizeof H); + if (mlen > crypto_aead_aes256gcm_MESSAGEBYTES_MAX) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + memcpy(&n2[0], npub, 3 * 4); + n2[3] = 0x01000000; + aesni_encrypt1(T, _mm_load_si128((const __m128i *) n2), rkeys); + { + uint64_t x; + x = _bswap64((uint64_t) (8 * adlen)); + memcpy(&fb[0], &x, sizeof x); + x = _bswap64((uint64_t) (8 * mlen)); + memcpy(&fb[8], &x, sizeof x); + } + /* we store H (and it's power) byte-reverted once and for all */ + Hv = _mm_shuffle_epi8(_mm_load_si128((const __m128i *) H), rev); + _mm_store_si128((__m128i *) H, Hv); + H2v = mulv(Hv, Hv); + H3v = mulv(H2v, Hv); + H4v = mulv(H3v, Hv); + + accv = _mm_setzero_si128(); + /* unrolled by 4 GCM (by 8 doesn't improve using MULREDUCE4) */ + for (i = 0; i < adlen_rnd64; i += 64) { + __m128i X4_ = _mm_loadu_si128((const __m128i *) (ad + i + 0)); + __m128i X3_ = _mm_loadu_si128((const __m128i *) (ad + i + 16)); + __m128i X2_ = _mm_loadu_si128((const __m128i *) (ad + i + 32)); + __m128i X1_ = _mm_loadu_si128((const __m128i *) (ad + i + 48)); + MULREDUCE4(rev, Hv, H2v, H3v, H4v, X1_, X2_, X3_, X4_, accv); + } + _mm_store_si128((__m128i *) accum, accv); + + /* GCM remainder loop */ + for (i = adlen_rnd64; i < adlen; i += 16) { + unsigned int blocklen = 16; + + if (i + (unsigned long long) blocklen > adlen) { + blocklen = (unsigned int) (adlen - i); + } + addmul(accum, ad + i, blocklen, H); + } + +/* this only does 8 full blocks, so no fancy bounds checking is necessary*/ +#define LOOPRND128 \ + do { \ + const int iter = 8; \ + const int lb = iter * 16; \ + \ + for (i = 0; i < mlen_rnd128; i += lb) { \ + aesni_encrypt8full(c + i, n2, rkeys, m + i, accum, Hv, H2v, H3v, H4v, rev); \ + } \ + } while(0) + +/* remainder loop, with the slower GCM update to accommodate partial blocks */ +#define LOOPRMD128 \ + do { \ + const int iter = 8; \ + const int lb = iter * 16; \ + \ + for (i = mlen_rnd128; i < mlen; i += lb) { \ + CRYPTO_ALIGN(16) unsigned char outni[8 * 16]; \ + unsigned long long mj = lb; \ + \ + aesni_encrypt8(outni, n2, rkeys); \ + if ((i + mj) >= mlen) { \ + mj = mlen - i; \ + } \ + for (j = 0; j < mj; j++) { \ + c[i + j] = m[i + j] ^ outni[j]; \ + } \ + for (j = 0; j < mj; j += 16) { \ + unsigned int bl = 16; \ + \ + if (j + (unsigned long long) bl >= mj) { \ + bl = (unsigned int) (mj - j); \ + } \ + addmul(accum, c + i + j, bl, H); \ + } \ + } \ + } while(0) + + n2[3] &= 0x00ffffff; + COUNTER_INC2(n2); + LOOPRND128; + LOOPRMD128; + + addmul(accum, fb, 16, H); + + for (i = 0; i < 16; ++i) { + mac[i] = T[i] ^ accum[15 - i]; + } + if (maclen_p != NULL) { + *maclen_p = 16; + } + return 0; +} + +int +crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, unsigned long long *clen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + int ret = crypto_aead_aes256gcm_encrypt_detached_afternm(c, + c + mlen, NULL, + m, mlen, + ad, adlen, + nsec, npub, ctx_); + if (clen_p != NULL) { + *clen_p = mlen + crypto_aead_aes256gcm_ABYTES; + } + return ret; +} + +int +crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + const __m128i rev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); + const aes256gcm_state *ctx = (const aes256gcm_state *) (const void *) ctx_; + const __m128i *rkeys = ctx->rkeys; + __m128i Hv, H2v, H3v, H4v, accv; + unsigned long long i, j; + unsigned long long adlen_rnd64 = adlen & ~63ULL; + unsigned long long mlen; + unsigned long long mlen_rnd128; + CRYPTO_ALIGN(16) uint32_t n2[4]; + CRYPTO_ALIGN(16) unsigned char H[16]; + CRYPTO_ALIGN(16) unsigned char T[16]; + CRYPTO_ALIGN(16) unsigned char accum[16]; + CRYPTO_ALIGN(16) unsigned char fb[16]; + + (void) nsec; + if (clen > crypto_aead_aes256gcm_MESSAGEBYTES_MAX) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + mlen = clen; + + memcpy(&n2[0], npub, 3 * 4); + n2[3] = 0x01000000; + aesni_encrypt1(T, _mm_load_si128((const __m128i *) n2), rkeys); + + { + uint64_t x; + x = _bswap64((uint64_t)(8 * adlen)); + memcpy(&fb[0], &x, sizeof x); + x = _bswap64((uint64_t)(8 * mlen)); + memcpy(&fb[8], &x, sizeof x); + } + + memcpy(H, ctx->H, sizeof H); + Hv = _mm_shuffle_epi8(_mm_load_si128((const __m128i *) H), rev); + _mm_store_si128((__m128i *) H, Hv); + H2v = mulv(Hv, Hv); + H3v = mulv(H2v, Hv); + H4v = mulv(H3v, Hv); + + accv = _mm_setzero_si128(); + for (i = 0; i < adlen_rnd64; i += 64) { + __m128i X4_ = _mm_loadu_si128((const __m128i *) (ad + i + 0)); + __m128i X3_ = _mm_loadu_si128((const __m128i *) (ad + i + 16)); + __m128i X2_ = _mm_loadu_si128((const __m128i *) (ad + i + 32)); + __m128i X1_ = _mm_loadu_si128((const __m128i *) (ad + i + 48)); + MULREDUCE4(rev, Hv, H2v, H3v, H4v, X1_, X2_, X3_, X4_, accv); + } + _mm_store_si128((__m128i *) accum, accv); + + for (i = adlen_rnd64; i < adlen; i += 16) { + unsigned int blocklen = 16; + if (i + (unsigned long long) blocklen > adlen) { + blocklen = (unsigned int) (adlen - i); + } + addmul(accum, ad + i, blocklen, H); + } + + mlen_rnd128 = mlen & ~127ULL; + +#define LOOPACCUMDRND128 \ + do { \ + const int iter = 8; \ + const int lb = iter * 16; \ + for (i = 0; i < mlen_rnd128; i += lb) { \ + aesni_addmul8full(c + i, accum, Hv, H2v, H3v, H4v, rev); \ + } \ + } while(0) + +#define LOOPDRND128 \ + do { \ + const int iter = 8; \ + const int lb = iter * 16; \ + \ + for (i = 0; i < mlen_rnd128; i += lb) { \ + aesni_decrypt8full(m + i, n2, rkeys, c + i); \ + } \ + } while(0) + +#define LOOPACCUMDRMD128 \ + do { \ + const int iter = 8; \ + const int lb = iter * 16; \ + \ + for (i = mlen_rnd128; i < mlen; i += lb) { \ + unsigned long long mj = lb; \ + \ + if ((i + mj) >= mlen) { \ + mj = mlen - i; \ + } \ + for (j = 0; j < mj; j += 16) { \ + unsigned int bl = 16; \ + \ + if (j + (unsigned long long) bl >= mj) { \ + bl = (unsigned int) (mj - j); \ + } \ + addmul(accum, c + i + j, bl, H); \ + } \ + } \ + } while(0) + +#define LOOPDRMD128 \ + do { \ + const int iter = 8; \ + const int lb = iter * 16; \ + \ + for (i = mlen_rnd128; i < mlen; i += lb) { \ + CRYPTO_ALIGN(16) unsigned char outni[8 * 16]; \ + unsigned long long mj = lb; \ + \ + if ((i + mj) >= mlen) { \ + mj = mlen - i; \ + } \ + aesni_encrypt8(outni, n2, rkeys); \ + for (j = 0; j < mj; j++) { \ + m[i + j] = c[i + j] ^ outni[j]; \ + } \ + } \ + } while(0) + + n2[3] &= 0x00ffffff; + + COUNTER_INC2(n2); + LOOPACCUMDRND128; + LOOPACCUMDRMD128; + addmul(accum, fb, 16, H); + { + unsigned char d = 0; + + for (i = 0; i < 16; i++) { + d |= (mac[i] ^ (T[i] ^ accum[15 - i])); + } + if (d != 0) { + if (m != NULL) { + memset(m, 0, mlen); + } + return -1; + } + if (m == NULL) { + return 0; + } + } + n2[3] = 0U; + COUNTER_INC2(n2); + LOOPDRND128; + LOOPDRMD128; + + return 0; +} + +int +crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= crypto_aead_aes256gcm_ABYTES) { + ret = crypto_aead_aes256gcm_decrypt_detached_afternm + (m, nsec, c, clen - crypto_aead_aes256gcm_ABYTES, + c + clen - crypto_aead_aes256gcm_ABYTES, + ad, adlen, npub, ctx_); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - crypto_aead_aes256gcm_ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + +int +crypto_aead_aes256gcm_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx; + + crypto_aead_aes256gcm_beforenm(&ctx, k); + + return crypto_aead_aes256gcm_encrypt_detached_afternm + (c, mac, maclen_p, m, mlen, ad, adlen, nsec, npub, + (const crypto_aead_aes256gcm_state *) &ctx); +} + +int +crypto_aead_aes256gcm_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx; + int ret; + + crypto_aead_aes256gcm_beforenm(&ctx, k); + + ret = crypto_aead_aes256gcm_encrypt_afternm + (c, clen_p, m, mlen, ad, adlen, nsec, npub, + (const crypto_aead_aes256gcm_state *) &ctx); + sodium_memzero(&ctx, sizeof ctx); + + return ret; +} + +int +crypto_aead_aes256gcm_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx; + + crypto_aead_aes256gcm_beforenm(&ctx, k); + + return crypto_aead_aes256gcm_decrypt_detached_afternm + (m, nsec, c, clen, mac, ad, adlen, npub, + (const crypto_aead_aes256gcm_state *) &ctx); +} + +int +crypto_aead_aes256gcm_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx; + int ret; + + crypto_aead_aes256gcm_beforenm(&ctx, k); + + ret = crypto_aead_aes256gcm_decrypt_afternm + (m, mlen_p, nsec, c, clen, ad, adlen, npub, + (const crypto_aead_aes256gcm_state *) &ctx); + sodium_memzero(&ctx, sizeof ctx); + + return ret; +} + +int +crypto_aead_aes256gcm_is_available(void) +{ + return sodium_runtime_has_pclmul() & sodium_runtime_has_aesni(); +} + +#else + +int +crypto_aead_aes256gcm_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_encrypt(unsigned char *c, unsigned long long *clen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, const unsigned char *npub, + const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_decrypt(unsigned char *m, unsigned long long *mlen_p, + unsigned char *nsec, const unsigned char *c, + unsigned long long clen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *npub, + const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_, + const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c, + unsigned char *mac, unsigned long long *maclen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, unsigned long long *clen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_is_available(void) +{ + return 0; +} + +#endif + +size_t +crypto_aead_aes256gcm_keybytes(void) +{ + return crypto_aead_aes256gcm_KEYBYTES; +} + +size_t +crypto_aead_aes256gcm_nsecbytes(void) +{ + return crypto_aead_aes256gcm_NSECBYTES; +} + +size_t +crypto_aead_aes256gcm_npubbytes(void) +{ + return crypto_aead_aes256gcm_NPUBBYTES; +} + +size_t +crypto_aead_aes256gcm_abytes(void) +{ + return crypto_aead_aes256gcm_ABYTES; +} + +size_t +crypto_aead_aes256gcm_statebytes(void) +{ + return (sizeof(crypto_aead_aes256gcm_state) + (size_t) 15U) & ~(size_t) 15U; +} + +size_t +crypto_aead_aes256gcm_messagebytes_max(void) +{ + return crypto_aead_aes256gcm_MESSAGEBYTES_MAX; +} + +void +crypto_aead_aes256gcm_keygen(unsigned char k[crypto_aead_aes256gcm_KEYBYTES]) +{ + randombytes_buf(k, crypto_aead_aes256gcm_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c b/external/src/libsodium/src/libsodium/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c new file mode 100644 index 0000000..c354087 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c @@ -0,0 +1,400 @@ + +#include +#include +#include +#include + +#include "core.h" +#include "crypto_aead_chacha20poly1305.h" +#include "crypto_onetimeauth_poly1305.h" +#include "crypto_stream_chacha20.h" +#include "crypto_verify_16.h" +#include "randombytes.h" +#include "utils.h" + +#include "private/chacha20_ietf_ext.h" +#include "private/common.h" + +static const unsigned char _pad0[16] = { 0 }; + +int +crypto_aead_chacha20poly1305_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + + (void) nsec; + crypto_stream_chacha20(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_stream_chacha20_xor_ic(c, m, mlen, npub, 1U, k); + + crypto_onetimeauth_poly1305_update(&state, c, mlen); + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, mac); + sodium_memzero(&state, sizeof state); + + if (maclen_p != NULL) { + *maclen_p = crypto_aead_chacha20poly1305_ABYTES; + } + return 0; +} + +int +crypto_aead_chacha20poly1305_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long clen = 0ULL; + int ret; + + if (mlen > crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + ret = crypto_aead_chacha20poly1305_encrypt_detached(c, + c + mlen, NULL, + m, mlen, + ad, adlen, + nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + clen = mlen + crypto_aead_chacha20poly1305_ABYTES; + } + *clen_p = clen; + } + return ret; +} + +int +crypto_aead_chacha20poly1305_ietf_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + + (void) nsec; + crypto_stream_chacha20_ietf(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); + + crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, npub, 1U, k); + + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); + + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, mac); + sodium_memzero(&state, sizeof state); + + if (maclen_p != NULL) { + *maclen_p = crypto_aead_chacha20poly1305_ietf_ABYTES; + } + return 0; +} + +int +crypto_aead_chacha20poly1305_ietf_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long clen = 0ULL; + int ret; + + if (mlen > crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + ret = crypto_aead_chacha20poly1305_ietf_encrypt_detached(c, + c + mlen, NULL, + m, mlen, + ad, adlen, + nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + clen = mlen + crypto_aead_chacha20poly1305_ietf_ABYTES; + } + *clen_p = clen; + } + return ret; +} + +int +crypto_aead_chacha20poly1305_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + unsigned char computed_mac[crypto_aead_chacha20poly1305_ABYTES]; + unsigned long long mlen; + int ret; + + (void) nsec; + crypto_stream_chacha20(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + mlen = clen; + crypto_onetimeauth_poly1305_update(&state, c, mlen); + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, computed_mac); + sodium_memzero(&state, sizeof state); + + COMPILER_ASSERT(sizeof computed_mac == 16U); + ret = crypto_verify_16(computed_mac, mac); + sodium_memzero(computed_mac, sizeof computed_mac); + if (m == NULL) { + return ret; + } + if (ret != 0) { + memset(m, 0, mlen); + return -1; + } + crypto_stream_chacha20_xor_ic(m, c, mlen, npub, 1U, k); + + return 0; +} + +int +crypto_aead_chacha20poly1305_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= crypto_aead_chacha20poly1305_ABYTES) { + ret = crypto_aead_chacha20poly1305_decrypt_detached + (m, nsec, + c, clen - crypto_aead_chacha20poly1305_ABYTES, + c + clen - crypto_aead_chacha20poly1305_ABYTES, + ad, adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - crypto_aead_chacha20poly1305_ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + +int +crypto_aead_chacha20poly1305_ietf_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + unsigned char computed_mac[crypto_aead_chacha20poly1305_ietf_ABYTES]; + unsigned long long mlen; + int ret; + + (void) nsec; + crypto_stream_chacha20_ietf(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); + + mlen = clen; + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); + + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, computed_mac); + sodium_memzero(&state, sizeof state); + + COMPILER_ASSERT(sizeof computed_mac == 16U); + ret = crypto_verify_16(computed_mac, mac); + sodium_memzero(computed_mac, sizeof computed_mac); + if (m == NULL) { + return ret; + } + if (ret != 0) { + memset(m, 0, mlen); + return -1; + } + crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, npub, 1U, k); + + return 0; +} + +int +crypto_aead_chacha20poly1305_ietf_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= crypto_aead_chacha20poly1305_ietf_ABYTES) { + ret = crypto_aead_chacha20poly1305_ietf_decrypt_detached + (m, nsec, + c, clen - crypto_aead_chacha20poly1305_ietf_ABYTES, + c + clen - crypto_aead_chacha20poly1305_ietf_ABYTES, + ad, adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - crypto_aead_chacha20poly1305_ietf_ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + +size_t +crypto_aead_chacha20poly1305_ietf_keybytes(void) +{ + return crypto_aead_chacha20poly1305_ietf_KEYBYTES; +} + +size_t +crypto_aead_chacha20poly1305_ietf_npubbytes(void) +{ + return crypto_aead_chacha20poly1305_ietf_NPUBBYTES; +} + +size_t +crypto_aead_chacha20poly1305_ietf_nsecbytes(void) +{ + return crypto_aead_chacha20poly1305_ietf_NSECBYTES; +} + +size_t +crypto_aead_chacha20poly1305_ietf_abytes(void) +{ + return crypto_aead_chacha20poly1305_ietf_ABYTES; +} + +size_t +crypto_aead_chacha20poly1305_ietf_messagebytes_max(void) +{ + return crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX; +} + +void +crypto_aead_chacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_chacha20poly1305_ietf_KEYBYTES]) +{ + randombytes_buf(k, crypto_aead_chacha20poly1305_ietf_KEYBYTES); +} + +size_t +crypto_aead_chacha20poly1305_keybytes(void) +{ + return crypto_aead_chacha20poly1305_KEYBYTES; +} + +size_t +crypto_aead_chacha20poly1305_npubbytes(void) +{ + return crypto_aead_chacha20poly1305_NPUBBYTES; +} + +size_t +crypto_aead_chacha20poly1305_nsecbytes(void) +{ + return crypto_aead_chacha20poly1305_NSECBYTES; +} + +size_t +crypto_aead_chacha20poly1305_abytes(void) +{ + return crypto_aead_chacha20poly1305_ABYTES; +} + +size_t +crypto_aead_chacha20poly1305_messagebytes_max(void) +{ + return crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX; +} + +void +crypto_aead_chacha20poly1305_keygen(unsigned char k[crypto_aead_chacha20poly1305_KEYBYTES]) +{ + randombytes_buf(k, crypto_aead_chacha20poly1305_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c b/external/src/libsodium/src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c new file mode 100644 index 0000000..07e3655 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c @@ -0,0 +1,262 @@ + +#include +#include +#include +#include + +#include "core.h" +#include "crypto_aead_chacha20poly1305.h" +#include "crypto_aead_xchacha20poly1305.h" +#include "crypto_core_hchacha20.h" +#include "crypto_onetimeauth_poly1305.h" +#include "crypto_stream_chacha20.h" +#include "crypto_verify_16.h" +#include "randombytes.h" +#include "utils.h" + +#include "private/chacha20_ietf_ext.h" +#include "private/common.h" + +static const unsigned char _pad0[16] = { 0 }; + +static int +_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + + (void) nsec; + crypto_stream_chacha20_ietf_ext(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); + + crypto_stream_chacha20_ietf_ext_xor_ic(c, m, mlen, npub, 1U, k); + + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); + + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, mac); + sodium_memzero(&state, sizeof state); + + if (maclen_p != NULL) { + *maclen_p = crypto_aead_chacha20poly1305_ietf_ABYTES; + } + return 0; +} + +static int +_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + unsigned char computed_mac[crypto_aead_chacha20poly1305_ietf_ABYTES]; + unsigned long long mlen; + int ret; + + (void) nsec; + crypto_stream_chacha20_ietf_ext(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); + + mlen = clen; + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); + + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, computed_mac); + sodium_memzero(&state, sizeof state); + + COMPILER_ASSERT(sizeof computed_mac == 16U); + ret = crypto_verify_16(computed_mac, mac); + sodium_memzero(computed_mac, sizeof computed_mac); + if (m == NULL) { + return ret; + } + if (ret != 0) { + memset(m, 0, mlen); + return -1; + } + crypto_stream_chacha20_ietf_ext_xor_ic(m, c, mlen, npub, 1U, k); + + return 0; +} + +int +crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; + unsigned char npub2[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0 }; + int ret; + + crypto_core_hchacha20(k2, npub, k, NULL); + memcpy(npub2 + 4, npub + crypto_core_hchacha20_INPUTBYTES, + crypto_aead_chacha20poly1305_ietf_NPUBBYTES - 4); + ret = _encrypt_detached(c, mac, maclen_p, m, mlen, ad, adlen, + nsec, npub2, k2); + sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES); + + return ret; +} + +int +crypto_aead_xchacha20poly1305_ietf_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long clen = 0ULL; + int ret; + + if (mlen > crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + ret = crypto_aead_xchacha20poly1305_ietf_encrypt_detached + (c, c + mlen, NULL, m, mlen, ad, adlen, nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + clen = mlen + crypto_aead_xchacha20poly1305_ietf_ABYTES; + } + *clen_p = clen; + } + return ret; +} + +int +crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; + unsigned char npub2[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0 }; + int ret; + + crypto_core_hchacha20(k2, npub, k, NULL); + memcpy(npub2 + 4, npub + crypto_core_hchacha20_INPUTBYTES, + crypto_aead_chacha20poly1305_ietf_NPUBBYTES - 4); + ret = _decrypt_detached(m, nsec, c, clen, mac, ad, adlen, npub2, k2); + sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES); + + return ret; +} + +int +crypto_aead_xchacha20poly1305_ietf_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= crypto_aead_xchacha20poly1305_ietf_ABYTES) { + ret = crypto_aead_xchacha20poly1305_ietf_decrypt_detached + (m, nsec, + c, clen - crypto_aead_xchacha20poly1305_ietf_ABYTES, + c + clen - crypto_aead_xchacha20poly1305_ietf_ABYTES, + ad, adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - crypto_aead_xchacha20poly1305_ietf_ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_keybytes(void) +{ + return crypto_aead_xchacha20poly1305_ietf_KEYBYTES; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_npubbytes(void) +{ + return crypto_aead_xchacha20poly1305_ietf_NPUBBYTES; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_nsecbytes(void) +{ + return crypto_aead_xchacha20poly1305_ietf_NSECBYTES; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_abytes(void) +{ + return crypto_aead_xchacha20poly1305_ietf_ABYTES; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_messagebytes_max(void) +{ + return crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX; +} + +void +crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES]) +{ + randombytes_buf(k, crypto_aead_xchacha20poly1305_ietf_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_auth/crypto_auth.c b/external/src/libsodium/src/libsodium/crypto_auth/crypto_auth.c new file mode 100644 index 0000000..d061c8c --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_auth/crypto_auth.c @@ -0,0 +1,41 @@ + +#include "crypto_auth.h" +#include "randombytes.h" + +size_t +crypto_auth_bytes(void) +{ + return crypto_auth_BYTES; +} + +size_t +crypto_auth_keybytes(void) +{ + return crypto_auth_KEYBYTES; +} + +const char * +crypto_auth_primitive(void) +{ + return crypto_auth_PRIMITIVE; +} + +int +crypto_auth(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + return crypto_auth_hmacsha512256(out, in, inlen, k); +} + +int +crypto_auth_verify(const unsigned char *h, const unsigned char *in, + unsigned long long inlen,const unsigned char *k) +{ + return crypto_auth_hmacsha512256_verify(h, in, inlen, k); +} + +void +crypto_auth_keygen(unsigned char k[crypto_auth_KEYBYTES]) +{ + randombytes_buf(k, crypto_auth_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_auth/hmacsha256/auth_hmacsha256.c b/external/src/libsodium/src/libsodium/crypto_auth/hmacsha256/auth_hmacsha256.c new file mode 100644 index 0000000..a951e93 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_auth/hmacsha256/auth_hmacsha256.c @@ -0,0 +1,118 @@ + +#include +#include +#include + +#include "crypto_auth_hmacsha256.h" +#include "crypto_hash_sha256.h" +#include "crypto_verify_32.h" +#include "randombytes.h" +#include "utils.h" + +size_t +crypto_auth_hmacsha256_bytes(void) +{ + return crypto_auth_hmacsha256_BYTES; +} + +size_t +crypto_auth_hmacsha256_keybytes(void) +{ + return crypto_auth_hmacsha256_KEYBYTES; +} + +size_t +crypto_auth_hmacsha256_statebytes(void) +{ + return sizeof(crypto_auth_hmacsha256_state); +} + +void +crypto_auth_hmacsha256_keygen(unsigned char k[crypto_auth_hmacsha256_KEYBYTES]) +{ + randombytes_buf(k, crypto_auth_hmacsha256_KEYBYTES); +} + +int +crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state *state, + const unsigned char *key, size_t keylen) +{ + unsigned char pad[64]; + unsigned char khash[32]; + size_t i; + + if (keylen > 64) { + crypto_hash_sha256_init(&state->ictx); + crypto_hash_sha256_update(&state->ictx, key, keylen); + crypto_hash_sha256_final(&state->ictx, khash); + key = khash; + keylen = 32; + } + crypto_hash_sha256_init(&state->ictx); + memset(pad, 0x36, 64); + for (i = 0; i < keylen; i++) { + pad[i] ^= key[i]; + } + crypto_hash_sha256_update(&state->ictx, pad, 64); + + crypto_hash_sha256_init(&state->octx); + memset(pad, 0x5c, 64); + for (i = 0; i < keylen; i++) { + pad[i] ^= key[i]; + } + crypto_hash_sha256_update(&state->octx, pad, 64); + + sodium_memzero((void *) pad, sizeof pad); + sodium_memzero((void *) khash, sizeof khash); + + return 0; +} + +int +crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state, + const unsigned char *in, unsigned long long inlen) +{ + crypto_hash_sha256_update(&state->ictx, in, inlen); + + return 0; +} + +int +crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state, + unsigned char *out) +{ + unsigned char ihash[32]; + + crypto_hash_sha256_final(&state->ictx, ihash); + crypto_hash_sha256_update(&state->octx, ihash, 32); + crypto_hash_sha256_final(&state->octx, out); + + sodium_memzero((void *) ihash, sizeof ihash); + + return 0; +} + +int +crypto_auth_hmacsha256(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + crypto_auth_hmacsha256_state state; + + crypto_auth_hmacsha256_init(&state, k, crypto_auth_hmacsha256_KEYBYTES); + crypto_auth_hmacsha256_update(&state, in, inlen); + crypto_auth_hmacsha256_final(&state, out); + + return 0; +} + +int +crypto_auth_hmacsha256_verify(const unsigned char *h, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + unsigned char correct[32]; + + crypto_auth_hmacsha256(correct, in, inlen, k); + + return crypto_verify_32(h, correct) | (-(h == correct)) | + sodium_memcmp(correct, h, 32); +} diff --git a/external/src/libsodium/src/libsodium/crypto_auth/hmacsha512/auth_hmacsha512.c b/external/src/libsodium/src/libsodium/crypto_auth/hmacsha512/auth_hmacsha512.c new file mode 100644 index 0000000..018d7a4 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_auth/hmacsha512/auth_hmacsha512.c @@ -0,0 +1,118 @@ + +#include +#include +#include + +#include "crypto_auth_hmacsha512.h" +#include "crypto_hash_sha512.h" +#include "crypto_verify_64.h" +#include "randombytes.h" +#include "utils.h" + +size_t +crypto_auth_hmacsha512_bytes(void) +{ + return crypto_auth_hmacsha512_BYTES; +} + +size_t +crypto_auth_hmacsha512_keybytes(void) +{ + return crypto_auth_hmacsha512_KEYBYTES; +} + +size_t +crypto_auth_hmacsha512_statebytes(void) +{ + return sizeof(crypto_auth_hmacsha512_state); +} + +void +crypto_auth_hmacsha512_keygen(unsigned char k[crypto_auth_hmacsha512_KEYBYTES]) +{ + randombytes_buf(k, crypto_auth_hmacsha512_KEYBYTES); +} + +int +crypto_auth_hmacsha512_init(crypto_auth_hmacsha512_state *state, + const unsigned char *key, size_t keylen) +{ + unsigned char pad[128]; + unsigned char khash[64]; + size_t i; + + if (keylen > 128) { + crypto_hash_sha512_init(&state->ictx); + crypto_hash_sha512_update(&state->ictx, key, keylen); + crypto_hash_sha512_final(&state->ictx, khash); + key = khash; + keylen = 64; + } + crypto_hash_sha512_init(&state->ictx); + memset(pad, 0x36, 128); + for (i = 0; i < keylen; i++) { + pad[i] ^= key[i]; + } + crypto_hash_sha512_update(&state->ictx, pad, 128); + + crypto_hash_sha512_init(&state->octx); + memset(pad, 0x5c, 128); + for (i = 0; i < keylen; i++) { + pad[i] ^= key[i]; + } + crypto_hash_sha512_update(&state->octx, pad, 128); + + sodium_memzero((void *) pad, sizeof pad); + sodium_memzero((void *) khash, sizeof khash); + + return 0; +} + +int +crypto_auth_hmacsha512_update(crypto_auth_hmacsha512_state *state, + const unsigned char *in, unsigned long long inlen) +{ + crypto_hash_sha512_update(&state->ictx, in, inlen); + + return 0; +} + +int +crypto_auth_hmacsha512_final(crypto_auth_hmacsha512_state *state, + unsigned char *out) +{ + unsigned char ihash[64]; + + crypto_hash_sha512_final(&state->ictx, ihash); + crypto_hash_sha512_update(&state->octx, ihash, 64); + crypto_hash_sha512_final(&state->octx, out); + + sodium_memzero((void *) ihash, sizeof ihash); + + return 0; +} + +int +crypto_auth_hmacsha512(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + crypto_auth_hmacsha512_state state; + + crypto_auth_hmacsha512_init(&state, k, crypto_auth_hmacsha512_KEYBYTES); + crypto_auth_hmacsha512_update(&state, in, inlen); + crypto_auth_hmacsha512_final(&state, out); + + return 0; +} + +int +crypto_auth_hmacsha512_verify(const unsigned char *h, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + unsigned char correct[64]; + + crypto_auth_hmacsha512(correct, in, inlen, k); + + return crypto_verify_64(h, correct) | (-(h == correct)) | + sodium_memcmp(correct, h, 64); +} diff --git a/external/src/libsodium/src/libsodium/crypto_auth/hmacsha512256/auth_hmacsha512256.c b/external/src/libsodium/src/libsodium/crypto_auth/hmacsha512256/auth_hmacsha512256.c new file mode 100644 index 0000000..432d6db --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_auth/hmacsha512256/auth_hmacsha512256.c @@ -0,0 +1,93 @@ + +#include +#include +#include + +#include "crypto_auth_hmacsha512.h" +#include "crypto_auth_hmacsha512256.h" +#include "crypto_hash_sha512.h" +#include "crypto_verify_32.h" +#include "randombytes.h" +#include "utils.h" + +size_t +crypto_auth_hmacsha512256_bytes(void) +{ + return crypto_auth_hmacsha512256_BYTES; +} + +size_t +crypto_auth_hmacsha512256_keybytes(void) +{ + return crypto_auth_hmacsha512256_KEYBYTES; +} + +size_t +crypto_auth_hmacsha512256_statebytes(void) +{ + return sizeof(crypto_auth_hmacsha512256_state); +} + +void +crypto_auth_hmacsha512256_keygen( + unsigned char k[crypto_auth_hmacsha512256_KEYBYTES]) +{ + randombytes_buf(k, crypto_auth_hmacsha512256_KEYBYTES); +} + +int +crypto_auth_hmacsha512256_init(crypto_auth_hmacsha512256_state *state, + const unsigned char *key, size_t keylen) +{ + return crypto_auth_hmacsha512_init((crypto_auth_hmacsha512_state *) state, + key, keylen); +} + +int +crypto_auth_hmacsha512256_update(crypto_auth_hmacsha512256_state *state, + const unsigned char *in, + unsigned long long inlen) +{ + return crypto_auth_hmacsha512_update((crypto_auth_hmacsha512_state *) state, + in, inlen); +} + +int +crypto_auth_hmacsha512256_final(crypto_auth_hmacsha512256_state *state, + unsigned char *out) +{ + unsigned char out0[64]; + + crypto_auth_hmacsha512_final((crypto_auth_hmacsha512_state *) state, out0); + memcpy(out, out0, 32); + + return 0; +} + +int +crypto_auth_hmacsha512256(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + crypto_auth_hmacsha512256_state state; + + crypto_auth_hmacsha512256_init(&state, k, + crypto_auth_hmacsha512256_KEYBYTES); + crypto_auth_hmacsha512256_update(&state, in, inlen); + crypto_auth_hmacsha512256_final(&state, out); + + return 0; +} + +int +crypto_auth_hmacsha512256_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) +{ + unsigned char correct[32]; + + crypto_auth_hmacsha512256(correct, in, inlen, k); + + return crypto_verify_32(h, correct) | (-(h == correct)) | + sodium_memcmp(correct, h, 32); +} diff --git a/external/src/libsodium/src/libsodium/crypto_box/crypto_box.c b/external/src/libsodium/src/libsodium/crypto_box/crypto_box.c new file mode 100644 index 0000000..7e4f00b --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_box/crypto_box.c @@ -0,0 +1,114 @@ + +#include "crypto_box.h" + +size_t +crypto_box_seedbytes(void) +{ + return crypto_box_SEEDBYTES; +} + +size_t +crypto_box_publickeybytes(void) +{ + return crypto_box_PUBLICKEYBYTES; +} + +size_t +crypto_box_secretkeybytes(void) +{ + return crypto_box_SECRETKEYBYTES; +} + +size_t +crypto_box_beforenmbytes(void) +{ + return crypto_box_BEFORENMBYTES; +} + +size_t +crypto_box_noncebytes(void) +{ + return crypto_box_NONCEBYTES; +} + +size_t +crypto_box_zerobytes(void) +{ + return crypto_box_ZEROBYTES; +} + +size_t +crypto_box_boxzerobytes(void) +{ + return crypto_box_BOXZEROBYTES; +} + +size_t +crypto_box_macbytes(void) +{ + return crypto_box_MACBYTES; +} + +size_t +crypto_box_messagebytes_max(void) +{ + return crypto_box_MESSAGEBYTES_MAX; +} + +const char * +crypto_box_primitive(void) +{ + return crypto_box_PRIMITIVE; +} + +int +crypto_box_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed) +{ + return crypto_box_curve25519xsalsa20poly1305_seed_keypair(pk, sk, seed); +} + +int +crypto_box_keypair(unsigned char *pk, unsigned char *sk) +{ + return crypto_box_curve25519xsalsa20poly1305_keypair(pk, sk); +} + +int +crypto_box_beforenm(unsigned char *k, const unsigned char *pk, + const unsigned char *sk) +{ + return crypto_box_curve25519xsalsa20poly1305_beforenm(k, pk, sk); +} + +int +crypto_box_afternm(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + return crypto_box_curve25519xsalsa20poly1305_afternm(c, m, mlen, n, k); +} + +int +crypto_box_open_afternm(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + return crypto_box_curve25519xsalsa20poly1305_open_afternm(m, c, clen, n, k); +} + +int +crypto_box(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) +{ + return crypto_box_curve25519xsalsa20poly1305(c, m, mlen, n, pk, sk); +} + +int +crypto_box_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) +{ + return crypto_box_curve25519xsalsa20poly1305_open(m, c, clen, n, pk, sk); +} diff --git a/external/src/libsodium/src/libsodium/crypto_box/crypto_box_easy.c b/external/src/libsodium/src/libsodium/crypto_box/crypto_box_easy.c new file mode 100644 index 0000000..deb40b4 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_box/crypto_box_easy.c @@ -0,0 +1,115 @@ + +#include +#include +#include + +#include "core.h" +#include "crypto_box.h" +#include "crypto_secretbox.h" +#include "private/common.h" +#include "utils.h" + +int +crypto_box_detached_afternm(unsigned char *c, unsigned char *mac, + const unsigned char *m, unsigned long long mlen, + const unsigned char *n, const unsigned char *k) +{ + return crypto_secretbox_detached(c, mac, m, mlen, n, k); +} + +int +crypto_box_detached(unsigned char *c, unsigned char *mac, + const unsigned char *m, unsigned long long mlen, + const unsigned char *n, const unsigned char *pk, + const unsigned char *sk) +{ + unsigned char k[crypto_box_BEFORENMBYTES]; + int ret; + + COMPILER_ASSERT(crypto_box_BEFORENMBYTES >= crypto_secretbox_KEYBYTES); + if (crypto_box_beforenm(k, pk, sk) != 0) { + return -1; + } + ret = crypto_box_detached_afternm(c, mac, m, mlen, n, k); + sodium_memzero(k, sizeof k); + + return ret; +} + +int +crypto_box_easy_afternm(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + if (mlen > crypto_box_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return crypto_box_detached_afternm(c + crypto_box_MACBYTES, c, m, mlen, n, + k); +} + +int +crypto_box_easy(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) +{ + if (mlen > crypto_box_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return crypto_box_detached(c + crypto_box_MACBYTES, c, m, mlen, n, + pk, sk); +} + +int +crypto_box_open_detached_afternm(unsigned char *m, const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + return crypto_secretbox_open_detached(m, c, mac, clen, n, k); +} + +int +crypto_box_open_detached(unsigned char *m, const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) +{ + unsigned char k[crypto_box_BEFORENMBYTES]; + int ret; + + if (crypto_box_beforenm(k, pk, sk) != 0) { + return -1; + } + ret = crypto_box_open_detached_afternm(m, c, mac, clen, n, k); + sodium_memzero(k, sizeof k); + + return ret; +} + +int +crypto_box_open_easy_afternm(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + if (clen < crypto_box_MACBYTES) { + return -1; + } + return crypto_box_open_detached_afternm(m, c + crypto_box_MACBYTES, c, + clen - crypto_box_MACBYTES, + n, k); +} + +int +crypto_box_open_easy(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) +{ + if (clen < crypto_box_MACBYTES) { + return -1; + } + return crypto_box_open_detached(m, c + crypto_box_MACBYTES, c, + clen - crypto_box_MACBYTES, + n, pk, sk); +} diff --git a/external/src/libsodium/src/libsodium/crypto_box/crypto_box_seal.c b/external/src/libsodium/src/libsodium/crypto_box/crypto_box_seal.c new file mode 100644 index 0000000..e01d649 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_box/crypto_box_seal.c @@ -0,0 +1,68 @@ + +#include + +#include "crypto_box.h" +#include "crypto_generichash.h" +#include "private/common.h" +#include "utils.h" + +static int +_crypto_box_seal_nonce(unsigned char *nonce, + const unsigned char *pk1, const unsigned char *pk2) +{ + crypto_generichash_state st; + + crypto_generichash_init(&st, NULL, 0U, crypto_box_NONCEBYTES); + crypto_generichash_update(&st, pk1, crypto_box_PUBLICKEYBYTES); + crypto_generichash_update(&st, pk2, crypto_box_PUBLICKEYBYTES); + crypto_generichash_final(&st, nonce, crypto_box_NONCEBYTES); + + return 0; +} + +int +crypto_box_seal(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *pk) +{ + unsigned char nonce[crypto_box_NONCEBYTES]; + unsigned char epk[crypto_box_PUBLICKEYBYTES]; + unsigned char esk[crypto_box_SECRETKEYBYTES]; + int ret; + + if (crypto_box_keypair(epk, esk) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + _crypto_box_seal_nonce(nonce, epk, pk); + ret = crypto_box_easy(c + crypto_box_PUBLICKEYBYTES, m, mlen, + nonce, pk, esk); + memcpy(c, epk, crypto_box_PUBLICKEYBYTES); + sodium_memzero(esk, sizeof esk); + sodium_memzero(epk, sizeof epk); + sodium_memzero(nonce, sizeof nonce); + + return ret; +} + +int +crypto_box_seal_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, + const unsigned char *pk, const unsigned char *sk) +{ + unsigned char nonce[crypto_box_NONCEBYTES]; + + if (clen < crypto_box_SEALBYTES) { + return -1; + } + _crypto_box_seal_nonce(nonce, c, pk); + + COMPILER_ASSERT(crypto_box_PUBLICKEYBYTES < crypto_box_SEALBYTES); + return crypto_box_open_easy(m, c + crypto_box_PUBLICKEYBYTES, + clen - crypto_box_PUBLICKEYBYTES, + nonce, c, sk); +} + +size_t +crypto_box_sealbytes(void) +{ + return crypto_box_SEALBYTES; +} diff --git a/external/src/libsodium/src/libsodium/crypto_box/curve25519xchacha20poly1305/box_curve25519xchacha20poly1305.c b/external/src/libsodium/src/libsodium/crypto_box/curve25519xchacha20poly1305/box_curve25519xchacha20poly1305.c new file mode 100644 index 0000000..5e2532e --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_box/curve25519xchacha20poly1305/box_curve25519xchacha20poly1305.c @@ -0,0 +1,204 @@ + +#include +#include +#include +#include + +#include "core.h" +#include "crypto_box_curve25519xchacha20poly1305.h" +#include "crypto_core_hchacha20.h" +#include "crypto_hash_sha512.h" +#include "crypto_scalarmult_curve25519.h" +#include "crypto_secretbox_xchacha20poly1305.h" +#include "private/common.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_box_curve25519xchacha20poly1305_seed_keypair(unsigned char *pk, + unsigned char *sk, + const unsigned char *seed) +{ + unsigned char hash[64]; + + crypto_hash_sha512(hash, seed, 32); + memcpy(sk, hash, 32); + sodium_memzero(hash, sizeof hash); + + return crypto_scalarmult_curve25519_base(pk, sk); +} + +int +crypto_box_curve25519xchacha20poly1305_keypair(unsigned char *pk, + unsigned char *sk) +{ + randombytes_buf(sk, 32); + + return crypto_scalarmult_curve25519_base(pk, sk); +} + +int +crypto_box_curve25519xchacha20poly1305_beforenm(unsigned char *k, + const unsigned char *pk, + const unsigned char *sk) +{ + static const unsigned char zero[16] = { 0 }; + unsigned char s[32]; + + if (crypto_scalarmult_curve25519(s, sk, pk) != 0) { + return -1; + } + return crypto_core_hchacha20(k, zero, s, NULL); +} + +int +crypto_box_curve25519xchacha20poly1305_detached_afternm( + unsigned char *c, unsigned char *mac, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, const unsigned char *k) +{ + return crypto_secretbox_xchacha20poly1305_detached(c, mac, m, mlen, n, k); +} + +int +crypto_box_curve25519xchacha20poly1305_detached( + unsigned char *c, unsigned char *mac, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, const unsigned char *pk, + const unsigned char *sk) +{ + unsigned char k[crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES]; + int ret; + + COMPILER_ASSERT(crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES >= + crypto_secretbox_xchacha20poly1305_KEYBYTES); + if (crypto_box_curve25519xchacha20poly1305_beforenm(k, pk, sk) != 0) { + return -1; + } + ret = crypto_box_curve25519xchacha20poly1305_detached_afternm(c, mac, m, + mlen, n, k); + sodium_memzero(k, sizeof k); + + return ret; +} + +int +crypto_box_curve25519xchacha20poly1305_easy_afternm(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) +{ + if (mlen > crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return crypto_box_curve25519xchacha20poly1305_detached_afternm( + c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c, m, mlen, n, k); +} + +int +crypto_box_curve25519xchacha20poly1305_easy( + unsigned char *c, const unsigned char *m, unsigned long long mlen, + const unsigned char *n, const unsigned char *pk, const unsigned char *sk) +{ + if (mlen > crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return crypto_box_curve25519xchacha20poly1305_detached( + c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c, m, mlen, n, pk, + sk); +} + +int +crypto_box_curve25519xchacha20poly1305_open_detached_afternm( + unsigned char *m, const unsigned char *c, const unsigned char *mac, + unsigned long long clen, const unsigned char *n, const unsigned char *k) +{ + return crypto_secretbox_xchacha20poly1305_open_detached(m, c, mac, clen, n, + k); +} + +int +crypto_box_curve25519xchacha20poly1305_open_detached( + unsigned char *m, const unsigned char *c, const unsigned char *mac, + unsigned long long clen, const unsigned char *n, const unsigned char *pk, + const unsigned char *sk) +{ + unsigned char k[crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES]; + int ret; + + if (crypto_box_curve25519xchacha20poly1305_beforenm(k, pk, sk) != 0) { + return -1; + } + ret = crypto_box_curve25519xchacha20poly1305_open_detached_afternm( + m, c, mac, clen, n, k); + sodium_memzero(k, sizeof k); + + return ret; +} + +int +crypto_box_curve25519xchacha20poly1305_open_easy_afternm( + unsigned char *m, const unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + if (clen < crypto_box_curve25519xchacha20poly1305_MACBYTES) { + return -1; + } + return crypto_box_curve25519xchacha20poly1305_open_detached_afternm( + m, c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c, + clen - crypto_box_curve25519xchacha20poly1305_MACBYTES, n, k); +} + +int +crypto_box_curve25519xchacha20poly1305_open_easy( + unsigned char *m, const unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *pk, const unsigned char *sk) +{ + if (clen < crypto_box_curve25519xchacha20poly1305_MACBYTES) { + return -1; + } + return crypto_box_curve25519xchacha20poly1305_open_detached( + m, c + crypto_box_curve25519xchacha20poly1305_MACBYTES, c, + clen - crypto_box_curve25519xchacha20poly1305_MACBYTES, n, pk, sk); +} + +size_t +crypto_box_curve25519xchacha20poly1305_seedbytes(void) +{ + return crypto_box_curve25519xchacha20poly1305_SEEDBYTES; +} + +size_t +crypto_box_curve25519xchacha20poly1305_publickeybytes(void) +{ + return crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES; +} + +size_t +crypto_box_curve25519xchacha20poly1305_secretkeybytes(void) +{ + return crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES; +} + +size_t +crypto_box_curve25519xchacha20poly1305_beforenmbytes(void) +{ + return crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES; +} + +size_t +crypto_box_curve25519xchacha20poly1305_noncebytes(void) +{ + return crypto_box_curve25519xchacha20poly1305_NONCEBYTES; +} + +size_t +crypto_box_curve25519xchacha20poly1305_macbytes(void) +{ + return crypto_box_curve25519xchacha20poly1305_MACBYTES; +} + +size_t +crypto_box_curve25519xchacha20poly1305_messagebytes_max(void) +{ + return crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX; +} diff --git a/external/src/libsodium/src/libsodium/crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c b/external/src/libsodium/src/libsodium/crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c new file mode 100644 index 0000000..0240f03 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c @@ -0,0 +1,79 @@ + +#include + +#include "crypto_box_curve25519xchacha20poly1305.h" +#include "crypto_generichash.h" +#include "private/common.h" +#include "utils.h" + +static int +_crypto_box_curve25519xchacha20poly1305_seal_nonce(unsigned char *nonce, + const unsigned char *pk1, + const unsigned char *pk2) +{ + crypto_generichash_state st; + + crypto_generichash_init(&st, NULL, 0U, + crypto_box_curve25519xchacha20poly1305_NONCEBYTES); + crypto_generichash_update(&st, pk1, + crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES); + crypto_generichash_update(&st, pk2, + crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES); + crypto_generichash_final(&st, nonce, + crypto_box_curve25519xchacha20poly1305_NONCEBYTES); + + return 0; +} + +int +crypto_box_curve25519xchacha20poly1305_seal(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk) +{ + unsigned char nonce[crypto_box_curve25519xchacha20poly1305_NONCEBYTES]; + unsigned char epk[crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES]; + unsigned char esk[crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES]; + int ret; + + if (crypto_box_curve25519xchacha20poly1305_keypair(epk, esk) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + _crypto_box_curve25519xchacha20poly1305_seal_nonce(nonce, epk, pk); + ret = crypto_box_curve25519xchacha20poly1305_easy( + c + crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES, m, mlen, + nonce, pk, esk); + memcpy(c, epk, crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES); + sodium_memzero(esk, sizeof esk); + sodium_memzero(epk, sizeof epk); + sodium_memzero(nonce, sizeof nonce); + + return ret; +} + +int +crypto_box_curve25519xchacha20poly1305_seal_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, + const unsigned char *pk, + const unsigned char *sk) +{ + unsigned char nonce[crypto_box_curve25519xchacha20poly1305_NONCEBYTES]; + + if (clen < crypto_box_curve25519xchacha20poly1305_SEALBYTES) { + return -1; + } + _crypto_box_curve25519xchacha20poly1305_seal_nonce(nonce, c, pk); + + COMPILER_ASSERT(crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES < + crypto_box_curve25519xchacha20poly1305_SEALBYTES); + + return crypto_box_curve25519xchacha20poly1305_open_easy( + m, c + crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES, + clen - crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES, + nonce, c, sk); +} + +size_t +crypto_box_curve25519xchacha20poly1305_sealbytes(void) +{ + return crypto_box_curve25519xchacha20poly1305_SEALBYTES; +} diff --git a/external/src/libsodium/src/libsodium/crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305.c b/external/src/libsodium/src/libsodium/crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305.c new file mode 100644 index 0000000..4c1d62e --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_box/curve25519xsalsa20poly1305/box_curve25519xsalsa20poly1305.c @@ -0,0 +1,156 @@ +#include + +#include "crypto_box_curve25519xsalsa20poly1305.h" +#include "crypto_core_hsalsa20.h" +#include "crypto_hash_sha512.h" +#include "crypto_scalarmult_curve25519.h" +#include "crypto_secretbox_xsalsa20poly1305.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_box_curve25519xsalsa20poly1305_seed_keypair(unsigned char *pk, + unsigned char *sk, + const unsigned char *seed) +{ + unsigned char hash[64]; + + crypto_hash_sha512(hash, seed, 32); + memcpy(sk, hash, 32); + sodium_memzero(hash, sizeof hash); + + return crypto_scalarmult_curve25519_base(pk, sk); +} + +int +crypto_box_curve25519xsalsa20poly1305_keypair(unsigned char *pk, + unsigned char *sk) +{ + randombytes_buf(sk, 32); + + return crypto_scalarmult_curve25519_base(pk, sk); +} + +int +crypto_box_curve25519xsalsa20poly1305_beforenm(unsigned char *k, + const unsigned char *pk, + const unsigned char *sk) +{ + static const unsigned char zero[16] = { 0 }; + unsigned char s[32]; + + if (crypto_scalarmult_curve25519(s, sk, pk) != 0) { + return -1; + } + return crypto_core_hsalsa20(k, zero, s, NULL); +} + +int +crypto_box_curve25519xsalsa20poly1305_afternm(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) +{ + return crypto_secretbox_xsalsa20poly1305(c, m, mlen, n, k); +} + +int +crypto_box_curve25519xsalsa20poly1305_open_afternm(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + return crypto_secretbox_xsalsa20poly1305_open(m, c, clen, n, k); +} + +int +crypto_box_curve25519xsalsa20poly1305(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) +{ + unsigned char k[crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES]; + int ret; + + if (crypto_box_curve25519xsalsa20poly1305_beforenm(k, pk, sk) != 0) { + return -1; + } + ret = crypto_box_curve25519xsalsa20poly1305_afternm(c, m, mlen, n, k); + sodium_memzero(k, sizeof k); + + return ret; +} + +int +crypto_box_curve25519xsalsa20poly1305_open( + unsigned char *m, const unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *pk, const unsigned char *sk) +{ + unsigned char k[crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES]; + int ret; + + if (crypto_box_curve25519xsalsa20poly1305_beforenm(k, pk, sk) != 0) { + return -1; + } + ret = crypto_box_curve25519xsalsa20poly1305_open_afternm(m, c, clen, n, k); + sodium_memzero(k, sizeof k); + + return ret; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_seedbytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_SEEDBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_publickeybytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_secretkeybytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_beforenmbytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_noncebytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_NONCEBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_zerobytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_ZEROBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_boxzerobytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_macbytes(void) +{ + return crypto_box_curve25519xsalsa20poly1305_MACBYTES; +} + +size_t +crypto_box_curve25519xsalsa20poly1305_messagebytes_max(void) +{ + return crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX; +} diff --git a/external/src/libsodium/src/libsodium/crypto_core/ed25519/core_ed25519.c b/external/src/libsodium/src/libsodium/crypto_core/ed25519/core_ed25519.c new file mode 100644 index 0000000..bb0bda4 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_core/ed25519/core_ed25519.c @@ -0,0 +1,225 @@ + +#include + +#include "crypto_core_ed25519.h" +#include "private/common.h" +#include "private/ed25519_ref10.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_core_ed25519_is_valid_point(const unsigned char *p) +{ + ge25519_p3 p_p3; + + if (ge25519_is_canonical(p) == 0 || + ge25519_has_small_order(p) != 0 || + ge25519_frombytes(&p_p3, p) != 0 || + ge25519_is_on_curve(&p_p3) == 0 || + ge25519_is_on_main_subgroup(&p_p3) == 0) { + return 0; + } + return 1; +} + +int +crypto_core_ed25519_add(unsigned char *r, + const unsigned char *p, const unsigned char *q) +{ + ge25519_p3 p_p3, q_p3, r_p3; + ge25519_p1p1 r_p1p1; + ge25519_cached q_cached; + + if (ge25519_frombytes(&p_p3, p) != 0 || ge25519_is_on_curve(&p_p3) == 0 || + ge25519_frombytes(&q_p3, q) != 0 || ge25519_is_on_curve(&q_p3) == 0) { + return -1; + } + ge25519_p3_to_cached(&q_cached, &q_p3); + ge25519_add(&r_p1p1, &p_p3, &q_cached); + ge25519_p1p1_to_p3(&r_p3, &r_p1p1); + ge25519_p3_tobytes(r, &r_p3); + + return 0; +} + +int +crypto_core_ed25519_sub(unsigned char *r, + const unsigned char *p, const unsigned char *q) +{ + ge25519_p3 p_p3, q_p3, r_p3; + ge25519_p1p1 r_p1p1; + ge25519_cached q_cached; + + if (ge25519_frombytes(&p_p3, p) != 0 || ge25519_is_on_curve(&p_p3) == 0 || + ge25519_frombytes(&q_p3, q) != 0 || ge25519_is_on_curve(&q_p3) == 0) { + return -1; + } + ge25519_p3_to_cached(&q_cached, &q_p3); + ge25519_sub(&r_p1p1, &p_p3, &q_cached); + ge25519_p1p1_to_p3(&r_p3, &r_p1p1); + ge25519_p3_tobytes(r, &r_p3); + + return 0; +} + +int +crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r) +{ + ge25519_from_uniform(p, r); + + return 0; +} + +int +crypto_core_ed25519_from_hash(unsigned char *p, const unsigned char *h) +{ + ge25519_from_hash(p, h); + + return 0; +} + +void +crypto_core_ed25519_random(unsigned char *p) +{ + unsigned char h[crypto_core_ed25519_UNIFORMBYTES]; + + randombytes_buf(h, sizeof h); + (void) crypto_core_ed25519_from_uniform(p, h); +} + +void +crypto_core_ed25519_scalar_random(unsigned char *r) +{ + do { + randombytes_buf(r, crypto_core_ed25519_SCALARBYTES); + r[crypto_core_ed25519_SCALARBYTES - 1] &= 0x1f; + } while (sc25519_is_canonical(r) == 0 || + sodium_is_zero(r, crypto_core_ed25519_SCALARBYTES)); +} + +int +crypto_core_ed25519_scalar_invert(unsigned char *recip, const unsigned char *s) +{ + sc25519_invert(recip, s); + + return - sodium_is_zero(s, crypto_core_ed25519_SCALARBYTES); +} + +/* 2^252+27742317777372353535851937790883648493 */ +static const unsigned char L[] = { + 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, + 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 +}; + +void +crypto_core_ed25519_scalar_negate(unsigned char *neg, const unsigned char *s) +{ + unsigned char t_[crypto_core_ed25519_NONREDUCEDSCALARBYTES]; + unsigned char s_[crypto_core_ed25519_NONREDUCEDSCALARBYTES]; + + COMPILER_ASSERT(crypto_core_ed25519_NONREDUCEDSCALARBYTES >= + 2 * crypto_core_ed25519_SCALARBYTES); + memset(t_, 0, sizeof t_); + memset(s_, 0, sizeof s_); + memcpy(t_ + crypto_core_ed25519_SCALARBYTES, L, + crypto_core_ed25519_SCALARBYTES); + memcpy(s_, s, crypto_core_ed25519_SCALARBYTES); + sodium_sub(t_, s_, sizeof t_); + sc25519_reduce(t_); + memcpy(neg, t_, crypto_core_ed25519_SCALARBYTES); +} + +void +crypto_core_ed25519_scalar_complement(unsigned char *comp, + const unsigned char *s) +{ + unsigned char t_[crypto_core_ed25519_NONREDUCEDSCALARBYTES]; + unsigned char s_[crypto_core_ed25519_NONREDUCEDSCALARBYTES]; + + COMPILER_ASSERT(crypto_core_ed25519_NONREDUCEDSCALARBYTES >= + 2 * crypto_core_ed25519_SCALARBYTES); + memset(t_, 0, sizeof t_); + memset(s_, 0, sizeof s_); + t_[0]++; + memcpy(t_ + crypto_core_ed25519_SCALARBYTES, L, + crypto_core_ed25519_SCALARBYTES); + memcpy(s_, s, crypto_core_ed25519_SCALARBYTES); + sodium_sub(t_, s_, sizeof t_); + sc25519_reduce(t_); + memcpy(comp, t_, crypto_core_ed25519_SCALARBYTES); +} + +void +crypto_core_ed25519_scalar_add(unsigned char *z, const unsigned char *x, + const unsigned char *y) +{ + unsigned char x_[crypto_core_ed25519_NONREDUCEDSCALARBYTES]; + unsigned char y_[crypto_core_ed25519_NONREDUCEDSCALARBYTES]; + + memset(x_, 0, sizeof x_); + memset(y_, 0, sizeof y_); + memcpy(x_, x, crypto_core_ed25519_SCALARBYTES); + memcpy(y_, y, crypto_core_ed25519_SCALARBYTES); + sodium_add(x_, y_, crypto_core_ed25519_SCALARBYTES); + crypto_core_ed25519_scalar_reduce(z, x_); +} + +void +crypto_core_ed25519_scalar_sub(unsigned char *z, const unsigned char *x, + const unsigned char *y) +{ + unsigned char yn[crypto_core_ed25519_SCALARBYTES]; + + crypto_core_ed25519_scalar_negate(yn, y); + crypto_core_ed25519_scalar_add(z, x, yn); +} + +void +crypto_core_ed25519_scalar_mul(unsigned char *z, const unsigned char *x, + const unsigned char *y) +{ + sc25519_mul(z, x, y); +} + +void +crypto_core_ed25519_scalar_reduce(unsigned char *r, + const unsigned char *s) +{ + unsigned char t[crypto_core_ed25519_NONREDUCEDSCALARBYTES]; + + memcpy(t, s, sizeof t); + sc25519_reduce(t); + memcpy(r, t, crypto_core_ed25519_SCALARBYTES); + sodium_memzero(t, sizeof t); +} + +size_t +crypto_core_ed25519_bytes(void) +{ + return crypto_core_ed25519_BYTES; +} + +size_t +crypto_core_ed25519_nonreducedscalarbytes(void) +{ + return crypto_core_ed25519_NONREDUCEDSCALARBYTES; +} + +size_t +crypto_core_ed25519_uniformbytes(void) +{ + return crypto_core_ed25519_UNIFORMBYTES; +} + +size_t +crypto_core_ed25519_hashbytes(void) +{ + return crypto_core_ed25519_HASHBYTES; +} + +size_t +crypto_core_ed25519_scalarbytes(void) +{ + return crypto_core_ed25519_SCALARBYTES; +} diff --git a/external/src/libsodium/src/libsodium/crypto_core/ed25519/core_ristretto255.c b/external/src/libsodium/src/libsodium/crypto_core/ed25519/core_ristretto255.c new file mode 100644 index 0000000..cad3c80 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_core/ed25519/core_ristretto255.c @@ -0,0 +1,156 @@ + +#include + +#include "crypto_core_ed25519.h" +#include "crypto_core_ristretto255.h" +#include "private/common.h" +#include "private/ed25519_ref10.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_core_ristretto255_is_valid_point(const unsigned char *p) +{ + ge25519_p3 p_p3; + + if (ristretto255_frombytes(&p_p3, p) != 0) { + return 0; + } + return 1; +} + +int +crypto_core_ristretto255_add(unsigned char *r, + const unsigned char *p, const unsigned char *q) +{ + ge25519_p3 p_p3, q_p3, r_p3; + ge25519_p1p1 r_p1p1; + ge25519_cached q_cached; + + if (ristretto255_frombytes(&p_p3, p) != 0 || + ristretto255_frombytes(&q_p3, q) != 0) { + return -1; + } + ge25519_p3_to_cached(&q_cached, &q_p3); + ge25519_add(&r_p1p1, &p_p3, &q_cached); + ge25519_p1p1_to_p3(&r_p3, &r_p1p1); + ristretto255_p3_tobytes(r, &r_p3); + + return 0; +} + +int +crypto_core_ristretto255_sub(unsigned char *r, + const unsigned char *p, const unsigned char *q) +{ + ge25519_p3 p_p3, q_p3, r_p3; + ge25519_p1p1 r_p1p1; + ge25519_cached q_cached; + + if (ristretto255_frombytes(&p_p3, p) != 0 || + ristretto255_frombytes(&q_p3, q) != 0) { + return -1; + } + ge25519_p3_to_cached(&q_cached, &q_p3); + ge25519_sub(&r_p1p1, &p_p3, &q_cached); + ge25519_p1p1_to_p3(&r_p3, &r_p1p1); + ristretto255_p3_tobytes(r, &r_p3); + + return 0; +} + +int +crypto_core_ristretto255_from_hash(unsigned char *p, const unsigned char *r) +{ + ristretto255_from_hash(p, r); + + return 0; +} + +void +crypto_core_ristretto255_random(unsigned char *p) +{ + unsigned char h[crypto_core_ristretto255_HASHBYTES]; + + randombytes_buf(h, sizeof h); + (void) crypto_core_ristretto255_from_hash(p, h); +} + +void +crypto_core_ristretto255_scalar_random(unsigned char *r) +{ + crypto_core_ed25519_scalar_random(r); +} + +int +crypto_core_ristretto255_scalar_invert(unsigned char *recip, + const unsigned char *s) +{ + return crypto_core_ed25519_scalar_invert(recip, s); +} + +void +crypto_core_ristretto255_scalar_negate(unsigned char *neg, + const unsigned char *s) +{ + crypto_core_ed25519_scalar_negate(neg, s); +} + +void +crypto_core_ristretto255_scalar_complement(unsigned char *comp, + const unsigned char *s) +{ + crypto_core_ed25519_scalar_complement(comp, s); +} + +void +crypto_core_ristretto255_scalar_add(unsigned char *z, const unsigned char *x, + const unsigned char *y) +{ + crypto_core_ed25519_scalar_add(z, x, y); +} + +void +crypto_core_ristretto255_scalar_sub(unsigned char *z, const unsigned char *x, + const unsigned char *y) +{ + crypto_core_ed25519_scalar_sub(z, x, y); +} + +void +crypto_core_ristretto255_scalar_mul(unsigned char *z, const unsigned char *x, + const unsigned char *y) +{ + sc25519_mul(z, x, y); +} + +void +crypto_core_ristretto255_scalar_reduce(unsigned char *r, + const unsigned char *s) +{ + crypto_core_ed25519_scalar_reduce(r, s); +} + +size_t +crypto_core_ristretto255_bytes(void) +{ + return crypto_core_ristretto255_BYTES; +} + +size_t +crypto_core_ristretto255_nonreducedscalarbytes(void) +{ + return crypto_core_ristretto255_NONREDUCEDSCALARBYTES; +} + +size_t +crypto_core_ristretto255_hashbytes(void) +{ + return crypto_core_ristretto255_HASHBYTES; +} + +size_t +crypto_core_ristretto255_scalarbytes(void) +{ + return crypto_core_ristretto255_SCALARBYTES; +} diff --git a/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c new file mode 100644 index 0000000..425b550 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/ed25519_ref10.c @@ -0,0 +1,2859 @@ +#include +#include +#include +#include + +#include "crypto_verify_32.h" +#include "private/common.h" +#include "private/ed25519_ref10.h" +#include "utils.h" + +static inline uint64_t +load_3(const unsigned char *in) +{ + uint64_t result; + + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + + return result; +} + +static inline uint64_t +load_4(const unsigned char *in) +{ + uint64_t result; + + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + result |= ((uint64_t) in[3]) << 24; + + return result; +} + +/* + * Field arithmetic: + * Use 5*51 bit limbs on 64-bit systems with support for 128 bit arithmetic, + * and 10*25.5 bit limbs elsewhere. + * + * Functions used elsewhere that are candidates for inlining are defined + * via "private/curve25519_ref10.h". + */ + +#ifdef HAVE_TI_MODE +# include "fe_51/constants.h" +# include "fe_51/fe.h" +#else +# include "fe_25_5/constants.h" +# include "fe_25_5/fe.h" +#endif + +void +fe25519_invert(fe25519 out, const fe25519 z) +{ + fe25519 t0; + fe25519 t1; + fe25519 t2; + fe25519 t3; + int i; + + fe25519_sq(t0, z); + fe25519_sq(t1, t0); + fe25519_sq(t1, t1); + fe25519_mul(t1, z, t1); + fe25519_mul(t0, t0, t1); + fe25519_sq(t2, t0); + fe25519_mul(t1, t1, t2); + fe25519_sq(t2, t1); + for (i = 1; i < 5; ++i) { + fe25519_sq(t2, t2); + } + fe25519_mul(t1, t2, t1); + fe25519_sq(t2, t1); + for (i = 1; i < 10; ++i) { + fe25519_sq(t2, t2); + } + fe25519_mul(t2, t2, t1); + fe25519_sq(t3, t2); + for (i = 1; i < 20; ++i) { + fe25519_sq(t3, t3); + } + fe25519_mul(t2, t3, t2); + for (i = 1; i < 11; ++i) { + fe25519_sq(t2, t2); + } + fe25519_mul(t1, t2, t1); + fe25519_sq(t2, t1); + for (i = 1; i < 50; ++i) { + fe25519_sq(t2, t2); + } + fe25519_mul(t2, t2, t1); + fe25519_sq(t3, t2); + for (i = 1; i < 100; ++i) { + fe25519_sq(t3, t3); + } + fe25519_mul(t2, t3, t2); + for (i = 1; i < 51; ++i) { + fe25519_sq(t2, t2); + } + fe25519_mul(t1, t2, t1); + for (i = 1; i < 6; ++i) { + fe25519_sq(t1, t1); + } + fe25519_mul(out, t1, t0); +} + +static void +fe25519_pow22523(fe25519 out, const fe25519 z) +{ + fe25519 t0; + fe25519 t1; + fe25519 t2; + int i; + + fe25519_sq(t0, z); + fe25519_sq(t1, t0); + fe25519_sq(t1, t1); + fe25519_mul(t1, z, t1); + fe25519_mul(t0, t0, t1); + fe25519_sq(t0, t0); + fe25519_mul(t0, t1, t0); + fe25519_sq(t1, t0); + for (i = 1; i < 5; ++i) { + fe25519_sq(t1, t1); + } + fe25519_mul(t0, t1, t0); + fe25519_sq(t1, t0); + for (i = 1; i < 10; ++i) { + fe25519_sq(t1, t1); + } + fe25519_mul(t1, t1, t0); + fe25519_sq(t2, t1); + for (i = 1; i < 20; ++i) { + fe25519_sq(t2, t2); + } + fe25519_mul(t1, t2, t1); + for (i = 1; i < 11; ++i) { + fe25519_sq(t1, t1); + } + fe25519_mul(t0, t1, t0); + fe25519_sq(t1, t0); + for (i = 1; i < 50; ++i) { + fe25519_sq(t1, t1); + } + fe25519_mul(t1, t1, t0); + fe25519_sq(t2, t1); + for (i = 1; i < 100; ++i) { + fe25519_sq(t2, t2); + } + fe25519_mul(t1, t2, t1); + for (i = 1; i < 51; ++i) { + fe25519_sq(t1, t1); + } + fe25519_mul(t0, t1, t0); + fe25519_sq(t0, t0); + fe25519_sq(t0, t0); + fe25519_mul(out, t0, z); +} + +static inline void +fe25519_cneg(fe25519 h, const fe25519 f, unsigned int b) +{ + fe25519 negf; + + fe25519_neg(negf, f); + fe25519_copy(h, f); + fe25519_cmov(h, negf, b); +} + +static inline void +fe25519_abs(fe25519 h, const fe25519 f) +{ + fe25519_cneg(h, f, fe25519_isnegative(f)); +} + +static inline void +fe25519_sqmul(fe25519 s, const int n, const fe25519 a) +{ + int i; + + for (i = 0; i < n; i++) { + fe25519_sq(s, s); + } + fe25519_mul(s, s, a); +} + +static unsigned int +fe25519_notsquare(const fe25519 x) +{ + fe25519 _10, _11, _1100, _1111, _11110000, _11111111; + fe25519 t, u, v; + unsigned char s[32]; + + /* Jacobi symbol - x^((p-1)/2) */ + fe25519_mul(_10, x, x); + fe25519_mul(_11, x, _10); + fe25519_sq(_1100, _11); + fe25519_sq(_1100, _1100); + fe25519_mul(_1111, _11, _1100); + fe25519_sq(_11110000, _1111); + fe25519_sq(_11110000, _11110000); + fe25519_sq(_11110000, _11110000); + fe25519_sq(_11110000, _11110000); + fe25519_mul(_11111111, _1111, _11110000); + fe25519_copy(t, _11111111); + fe25519_sqmul(t, 2, _11); + fe25519_copy(u, t); + fe25519_sqmul(t, 10, u); + fe25519_sqmul(t, 10, u); + fe25519_copy(v, t); + fe25519_sqmul(t, 30, v); + fe25519_copy(v, t); + fe25519_sqmul(t, 60, v); + fe25519_copy(v, t); + fe25519_sqmul(t, 120, v); + fe25519_sqmul(t, 10, u); + fe25519_sqmul(t, 3, _11); + fe25519_sq(t, t); + + fe25519_tobytes(s, t); + + return s[1] & 1; +} + +/* + r = p + q + */ + +void +ge25519_add(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q) +{ + fe25519 t0; + + fe25519_add(r->X, p->Y, p->X); + fe25519_sub(r->Y, p->Y, p->X); + fe25519_mul(r->Z, r->X, q->YplusX); + fe25519_mul(r->Y, r->Y, q->YminusX); + fe25519_mul(r->T, q->T2d, p->T); + fe25519_mul(r->X, p->Z, q->Z); + fe25519_add(t0, r->X, r->X); + fe25519_sub(r->X, r->Z, r->Y); + fe25519_add(r->Y, r->Z, r->Y); + fe25519_add(r->Z, t0, r->T); + fe25519_sub(r->T, t0, r->T); +} + +static void +slide_vartime(signed char *r, const unsigned char *a) +{ + int i; + int b; + int k; + int ribs; + int cmp; + + for (i = 0; i < 256; ++i) { + r[i] = 1 & (a[i >> 3] >> (i & 7)); + } + for (i = 0; i < 256; ++i) { + if (! r[i]) { + continue; + } + for (b = 1; b <= 6 && i + b < 256; ++b) { + if (! r[i + b]) { + continue; + } + ribs = r[i + b] << b; + cmp = r[i] + ribs; + if (cmp <= 15) { + r[i] = cmp; + r[i + b] = 0; + } else { + cmp = r[i] - ribs; + if (cmp < -15) { + break; + } + r[i] = cmp; + for (k = i + b; k < 256; ++k) { + if (! r[k]) { + r[k] = 1; + break; + } + r[k] = 0; + } + } + } + } +} + +int +ge25519_frombytes(ge25519_p3 *h, const unsigned char *s) +{ + fe25519 u; + fe25519 v; + fe25519 v3; + fe25519 vxx; + fe25519 m_root_check, p_root_check; + fe25519 negx; + fe25519 x_sqrtm1; + int has_m_root, has_p_root; + + fe25519_frombytes(h->Y, s); + fe25519_1(h->Z); + fe25519_sq(u, h->Y); + fe25519_mul(v, u, d); + fe25519_sub(u, u, h->Z); /* u = y^2-1 */ + fe25519_add(v, v, h->Z); /* v = dy^2+1 */ + + fe25519_sq(v3, v); + fe25519_mul(v3, v3, v); /* v3 = v^3 */ + fe25519_sq(h->X, v3); + fe25519_mul(h->X, h->X, v); + fe25519_mul(h->X, h->X, u); /* x = uv^7 */ + + fe25519_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ + fe25519_mul(h->X, h->X, v3); + fe25519_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ + + fe25519_sq(vxx, h->X); + fe25519_mul(vxx, vxx, v); + fe25519_sub(m_root_check, vxx, u); /* vx^2-u */ + fe25519_add(p_root_check, vxx, u); /* vx^2+u */ + has_m_root = fe25519_iszero(m_root_check); + has_p_root = fe25519_iszero(p_root_check); + fe25519_mul(x_sqrtm1, h->X, sqrtm1); /* x*sqrt(-1) */ + fe25519_cmov(h->X, x_sqrtm1, 1 - has_m_root); + + fe25519_neg(negx, h->X); + fe25519_cmov(h->X, negx, fe25519_isnegative(h->X) ^ (s[31] >> 7)); + fe25519_mul(h->T, h->X, h->Y); + + return (has_m_root | has_p_root) - 1; +} + +int +ge25519_frombytes_negate_vartime(ge25519_p3 *h, const unsigned char *s) +{ + fe25519 u; + fe25519 v; + fe25519 v3; + fe25519 vxx; + fe25519 m_root_check, p_root_check; + + fe25519_frombytes(h->Y, s); + fe25519_1(h->Z); + fe25519_sq(u, h->Y); + fe25519_mul(v, u, d); + fe25519_sub(u, u, h->Z); /* u = y^2-1 */ + fe25519_add(v, v, h->Z); /* v = dy^2+1 */ + + fe25519_sq(v3, v); + fe25519_mul(v3, v3, v); /* v3 = v^3 */ + fe25519_sq(h->X, v3); + fe25519_mul(h->X, h->X, v); + fe25519_mul(h->X, h->X, u); /* x = uv^7 */ + + fe25519_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ + fe25519_mul(h->X, h->X, v3); + fe25519_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ + + fe25519_sq(vxx, h->X); + fe25519_mul(vxx, vxx, v); + fe25519_sub(m_root_check, vxx, u); /* vx^2-u */ + if (fe25519_iszero(m_root_check) == 0) { + fe25519_add(p_root_check, vxx, u); /* vx^2+u */ + if (fe25519_iszero(p_root_check) == 0) { + return -1; + } + fe25519_mul(h->X, h->X, sqrtm1); + } + + if (fe25519_isnegative(h->X) == (s[31] >> 7)) { + fe25519_neg(h->X, h->X); + } + fe25519_mul(h->T, h->X, h->Y); + + return 0; +} + +/* + r = p + q + */ + +static void +ge25519_madd(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_precomp *q) +{ + fe25519 t0; + + fe25519_add(r->X, p->Y, p->X); + fe25519_sub(r->Y, p->Y, p->X); + fe25519_mul(r->Z, r->X, q->yplusx); + fe25519_mul(r->Y, r->Y, q->yminusx); + fe25519_mul(r->T, q->xy2d, p->T); + fe25519_add(t0, p->Z, p->Z); + fe25519_sub(r->X, r->Z, r->Y); + fe25519_add(r->Y, r->Z, r->Y); + fe25519_add(r->Z, t0, r->T); + fe25519_sub(r->T, t0, r->T); +} + +/* + r = p - q + */ + +static void +ge25519_msub(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_precomp *q) +{ + fe25519 t0; + + fe25519_add(r->X, p->Y, p->X); + fe25519_sub(r->Y, p->Y, p->X); + fe25519_mul(r->Z, r->X, q->yminusx); + fe25519_mul(r->Y, r->Y, q->yplusx); + fe25519_mul(r->T, q->xy2d, p->T); + fe25519_add(t0, p->Z, p->Z); + fe25519_sub(r->X, r->Z, r->Y); + fe25519_add(r->Y, r->Z, r->Y); + fe25519_sub(r->Z, t0, r->T); + fe25519_add(r->T, t0, r->T); +} + +/* + r = p + */ + +void +ge25519_p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p) +{ + fe25519_mul(r->X, p->X, p->T); + fe25519_mul(r->Y, p->Y, p->Z); + fe25519_mul(r->Z, p->Z, p->T); +} + +/* + r = p + */ + +void +ge25519_p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p) +{ + fe25519_mul(r->X, p->X, p->T); + fe25519_mul(r->Y, p->Y, p->Z); + fe25519_mul(r->Z, p->Z, p->T); + fe25519_mul(r->T, p->X, p->Y); +} + +static void +ge25519_p2_0(ge25519_p2 *h) +{ + fe25519_0(h->X); + fe25519_1(h->Y); + fe25519_1(h->Z); +} + +/* + r = 2 * p + */ + +static void +ge25519_p2_dbl(ge25519_p1p1 *r, const ge25519_p2 *p) +{ + fe25519 t0; + + fe25519_sq(r->X, p->X); + fe25519_sq(r->Z, p->Y); + fe25519_sq2(r->T, p->Z); + fe25519_add(r->Y, p->X, p->Y); + fe25519_sq(t0, r->Y); + fe25519_add(r->Y, r->Z, r->X); + fe25519_sub(r->Z, r->Z, r->X); + fe25519_sub(r->X, t0, r->Y); + fe25519_sub(r->T, r->T, r->Z); +} + +static void +ge25519_p3_0(ge25519_p3 *h) +{ + fe25519_0(h->X); + fe25519_1(h->Y); + fe25519_1(h->Z); + fe25519_0(h->T); +} + +static void +ge25519_cached_0(ge25519_cached *h) +{ + fe25519_1(h->YplusX); + fe25519_1(h->YminusX); + fe25519_1(h->Z); + fe25519_0(h->T2d); +} + +/* + r = p + */ + +void +ge25519_p3_to_cached(ge25519_cached *r, const ge25519_p3 *p) +{ + fe25519_add(r->YplusX, p->Y, p->X); + fe25519_sub(r->YminusX, p->Y, p->X); + fe25519_copy(r->Z, p->Z); + fe25519_mul(r->T2d, p->T, d2); +} + +static void +ge25519_p3_to_precomp(ge25519_precomp *pi, const ge25519_p3 *p) +{ + fe25519 recip; + fe25519 x; + fe25519 y; + fe25519 xy; + + fe25519_invert(recip, p->Z); + fe25519_mul(x, p->X, recip); + fe25519_mul(y, p->Y, recip); + fe25519_add(pi->yplusx, y, x); + fe25519_sub(pi->yminusx, y, x); + fe25519_mul(xy, x, y); + fe25519_mul(pi->xy2d, xy, d2); +} + +/* + r = p + */ + +static void +ge25519_p3_to_p2(ge25519_p2 *r, const ge25519_p3 *p) +{ + fe25519_copy(r->X, p->X); + fe25519_copy(r->Y, p->Y); + fe25519_copy(r->Z, p->Z); +} + +void +ge25519_p3_tobytes(unsigned char *s, const ge25519_p3 *h) +{ + fe25519 recip; + fe25519 x; + fe25519 y; + + fe25519_invert(recip, h->Z); + fe25519_mul(x, h->X, recip); + fe25519_mul(y, h->Y, recip); + fe25519_tobytes(s, y); + s[31] ^= fe25519_isnegative(x) << 7; +} + +/* + r = 2 * p + */ + +static void +ge25519_p3_dbl(ge25519_p1p1 *r, const ge25519_p3 *p) +{ + ge25519_p2 q; + ge25519_p3_to_p2(&q, p); + ge25519_p2_dbl(r, &q); +} + +static void +ge25519_precomp_0(ge25519_precomp *h) +{ + fe25519_1(h->yplusx); + fe25519_1(h->yminusx); + fe25519_0(h->xy2d); +} + +static unsigned char +equal(signed char b, signed char c) +{ + unsigned char ub = b; + unsigned char uc = c; + unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ + uint32_t y = (uint32_t) x; /* 0: yes; 1..255: no */ + + y -= 1; /* 4294967295: yes; 0..254: no */ + y >>= 31; /* 1: yes; 0: no */ + + return y; +} + +static unsigned char +negative(signed char b) +{ + /* 18446744073709551361..18446744073709551615: yes; 0..255: no */ + uint64_t x = b; + + x >>= 63; /* 1: yes; 0: no */ + + return x; +} + +static void +ge25519_cmov(ge25519_precomp *t, const ge25519_precomp *u, unsigned char b) +{ + fe25519_cmov(t->yplusx, u->yplusx, b); + fe25519_cmov(t->yminusx, u->yminusx, b); + fe25519_cmov(t->xy2d, u->xy2d, b); +} + +static void +ge25519_cmov_cached(ge25519_cached *t, const ge25519_cached *u, unsigned char b) +{ + fe25519_cmov(t->YplusX, u->YplusX, b); + fe25519_cmov(t->YminusX, u->YminusX, b); + fe25519_cmov(t->Z, u->Z, b); + fe25519_cmov(t->T2d, u->T2d, b); +} + +static void +ge25519_cmov8(ge25519_precomp *t, const ge25519_precomp precomp[8], const signed char b) +{ + ge25519_precomp minust; + const unsigned char bnegative = negative(b); + const unsigned char babs = b - (((-bnegative) & b) * ((signed char) 1 << 1)); + + ge25519_precomp_0(t); + ge25519_cmov(t, &precomp[0], equal(babs, 1)); + ge25519_cmov(t, &precomp[1], equal(babs, 2)); + ge25519_cmov(t, &precomp[2], equal(babs, 3)); + ge25519_cmov(t, &precomp[3], equal(babs, 4)); + ge25519_cmov(t, &precomp[4], equal(babs, 5)); + ge25519_cmov(t, &precomp[5], equal(babs, 6)); + ge25519_cmov(t, &precomp[6], equal(babs, 7)); + ge25519_cmov(t, &precomp[7], equal(babs, 8)); + fe25519_copy(minust.yplusx, t->yminusx); + fe25519_copy(minust.yminusx, t->yplusx); + fe25519_neg(minust.xy2d, t->xy2d); + ge25519_cmov(t, &minust, bnegative); +} + +static void +ge25519_cmov8_base(ge25519_precomp *t, const int pos, const signed char b) +{ + static const ge25519_precomp base[32][8] = { /* base[i][j] = (j+1)*256^i*B */ +#ifdef HAVE_TI_MODE +# include "fe_51/base.h" +#else +# include "fe_25_5/base.h" +#endif + }; + ge25519_cmov8(t, base[pos], b); +} + +static void +ge25519_cmov8_cached(ge25519_cached *t, const ge25519_cached cached[8], const signed char b) +{ + ge25519_cached minust; + const unsigned char bnegative = negative(b); + const unsigned char babs = b - (((-bnegative) & b) * ((signed char) 1 << 1)); + + ge25519_cached_0(t); + ge25519_cmov_cached(t, &cached[0], equal(babs, 1)); + ge25519_cmov_cached(t, &cached[1], equal(babs, 2)); + ge25519_cmov_cached(t, &cached[2], equal(babs, 3)); + ge25519_cmov_cached(t, &cached[3], equal(babs, 4)); + ge25519_cmov_cached(t, &cached[4], equal(babs, 5)); + ge25519_cmov_cached(t, &cached[5], equal(babs, 6)); + ge25519_cmov_cached(t, &cached[6], equal(babs, 7)); + ge25519_cmov_cached(t, &cached[7], equal(babs, 8)); + fe25519_copy(minust.YplusX, t->YminusX); + fe25519_copy(minust.YminusX, t->YplusX); + fe25519_copy(minust.Z, t->Z); + fe25519_neg(minust.T2d, t->T2d); + ge25519_cmov_cached(t, &minust, bnegative); +} + +/* + r = p - q + */ + +void +ge25519_sub(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q) +{ + fe25519 t0; + + fe25519_add(r->X, p->Y, p->X); + fe25519_sub(r->Y, p->Y, p->X); + fe25519_mul(r->Z, r->X, q->YminusX); + fe25519_mul(r->Y, r->Y, q->YplusX); + fe25519_mul(r->T, q->T2d, p->T); + fe25519_mul(r->X, p->Z, q->Z); + fe25519_add(t0, r->X, r->X); + fe25519_sub(r->X, r->Z, r->Y); + fe25519_add(r->Y, r->Z, r->Y); + fe25519_sub(r->Z, t0, r->T); + fe25519_add(r->T, t0, r->T); +} + +void +ge25519_tobytes(unsigned char *s, const ge25519_p2 *h) +{ + fe25519 recip; + fe25519 x; + fe25519 y; + + fe25519_invert(recip, h->Z); + fe25519_mul(x, h->X, recip); + fe25519_mul(y, h->Y, recip); + fe25519_tobytes(s, y); + s[31] ^= fe25519_isnegative(x) << 7; +} + +/* + r = a * A + b * B + where a = a[0]+256*a[1]+...+256^31 a[31]. + and b = b[0]+256*b[1]+...+256^31 b[31]. + B is the Ed25519 base point (x,4/5) with x positive. + + Only used for signatures verification. + */ + +void +ge25519_double_scalarmult_vartime(ge25519_p2 *r, const unsigned char *a, + const ge25519_p3 *A, const unsigned char *b) +{ + static const ge25519_precomp Bi[8] = { +#ifdef HAVE_TI_MODE +# include "fe_51/base2.h" +#else +# include "fe_25_5/base2.h" +#endif + }; + signed char aslide[256]; + signed char bslide[256]; + ge25519_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ + ge25519_p1p1 t; + ge25519_p3 u; + ge25519_p3 A2; + int i; + + slide_vartime(aslide, a); + slide_vartime(bslide, b); + + ge25519_p3_to_cached(&Ai[0], A); + + ge25519_p3_dbl(&t, A); + ge25519_p1p1_to_p3(&A2, &t); + + ge25519_add(&t, &A2, &Ai[0]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[1], &u); + + ge25519_add(&t, &A2, &Ai[1]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[2], &u); + + ge25519_add(&t, &A2, &Ai[2]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[3], &u); + + ge25519_add(&t, &A2, &Ai[3]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[4], &u); + + ge25519_add(&t, &A2, &Ai[4]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[5], &u); + + ge25519_add(&t, &A2, &Ai[5]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[6], &u); + + ge25519_add(&t, &A2, &Ai[6]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[7], &u); + + ge25519_p2_0(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i]) { + break; + } + } + + for (; i >= 0; --i) { + ge25519_p2_dbl(&t, r); + + if (aslide[i] > 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_add(&t, &u, &Ai[aslide[i] / 2]); + } else if (aslide[i] < 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_sub(&t, &u, &Ai[(-aslide[i]) / 2]); + } + + if (bslide[i] > 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_madd(&t, &u, &Bi[bslide[i] / 2]); + } else if (bslide[i] < 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_msub(&t, &u, &Bi[(-bslide[i]) / 2]); + } + + ge25519_p1p1_to_p2(r, &t); + } +} + +/* + h = a * p + where a = a[0]+256*a[1]+...+256^31 a[31] + + Preconditions: + a[31] <= 127 + + p is public + */ + +void +ge25519_scalarmult(ge25519_p3 *h, const unsigned char *a, const ge25519_p3 *p) +{ + signed char e[64]; + signed char carry; + ge25519_p1p1 r; + ge25519_p2 s; + ge25519_p1p1 t2, t3, t4, t5, t6, t7, t8; + ge25519_p3 p2, p3, p4, p5, p6, p7, p8; + ge25519_cached pi[8]; + ge25519_cached t; + int i; + + ge25519_p3_to_cached(&pi[1 - 1], p); /* p */ + + ge25519_p3_dbl(&t2, p); + ge25519_p1p1_to_p3(&p2, &t2); + ge25519_p3_to_cached(&pi[2 - 1], &p2); /* 2p = 2*p */ + + ge25519_add(&t3, p, &pi[2 - 1]); + ge25519_p1p1_to_p3(&p3, &t3); + ge25519_p3_to_cached(&pi[3 - 1], &p3); /* 3p = 2p+p */ + + ge25519_p3_dbl(&t4, &p2); + ge25519_p1p1_to_p3(&p4, &t4); + ge25519_p3_to_cached(&pi[4 - 1], &p4); /* 4p = 2*2p */ + + ge25519_add(&t5, p, &pi[4 - 1]); + ge25519_p1p1_to_p3(&p5, &t5); + ge25519_p3_to_cached(&pi[5 - 1], &p5); /* 5p = 4p+p */ + + ge25519_p3_dbl(&t6, &p3); + ge25519_p1p1_to_p3(&p6, &t6); + ge25519_p3_to_cached(&pi[6 - 1], &p6); /* 6p = 2*3p */ + + ge25519_add(&t7, p, &pi[6 - 1]); + ge25519_p1p1_to_p3(&p7, &t7); + ge25519_p3_to_cached(&pi[7 - 1], &p7); /* 7p = 6p+p */ + + ge25519_p3_dbl(&t8, &p4); + ge25519_p1p1_to_p3(&p8, &t8); + ge25519_p3_to_cached(&pi[8 - 1], &p8); /* 8p = 2*4p */ + + for (i = 0; i < 32; ++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + /* each e[i] is between 0 and 15 */ + /* e[63] is between 0 and 7 */ + + carry = 0; + for (i = 0; i < 63; ++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= carry * ((signed char) 1 << 4); + } + e[63] += carry; + /* each e[i] is between -8 and 8 */ + + ge25519_p3_0(h); + + for (i = 63; i != 0; i--) { + ge25519_cmov8_cached(&t, pi, e[i]); + ge25519_add(&r, h, &t); + + ge25519_p1p1_to_p2(&s, &r); + ge25519_p2_dbl(&r, &s); + ge25519_p1p1_to_p2(&s, &r); + ge25519_p2_dbl(&r, &s); + ge25519_p1p1_to_p2(&s, &r); + ge25519_p2_dbl(&r, &s); + ge25519_p1p1_to_p2(&s, &r); + ge25519_p2_dbl(&r, &s); + + ge25519_p1p1_to_p3(h, &r); /* *16 */ + } + ge25519_cmov8_cached(&t, pi, e[i]); + ge25519_add(&r, h, &t); + + ge25519_p1p1_to_p3(h, &r); +} + +/* + h = a * B (with precomputation) + where a = a[0]+256*a[1]+...+256^31 a[31] + B is the Ed25519 base point (x,4/5) with x positive + (as bytes: 0x5866666666666666666666666666666666666666666666666666666666666666) + + Preconditions: + a[31] <= 127 + */ + +void +ge25519_scalarmult_base(ge25519_p3 *h, const unsigned char *a) +{ + signed char e[64]; + signed char carry; + ge25519_p1p1 r; + ge25519_p2 s; + ge25519_precomp t; + int i; + + for (i = 0; i < 32; ++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + /* each e[i] is between 0 and 15 */ + /* e[63] is between 0 and 7 */ + + carry = 0; + for (i = 0; i < 63; ++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= carry * ((signed char) 1 << 4); + } + e[63] += carry; + /* each e[i] is between -8 and 8 */ + + ge25519_p3_0(h); + + for (i = 1; i < 64; i += 2) { + ge25519_cmov8_base(&t, i / 2, e[i]); + ge25519_madd(&r, h, &t); + ge25519_p1p1_to_p3(h, &r); + } + + ge25519_p3_dbl(&r, h); + ge25519_p1p1_to_p2(&s, &r); + ge25519_p2_dbl(&r, &s); + ge25519_p1p1_to_p2(&s, &r); + ge25519_p2_dbl(&r, &s); + ge25519_p1p1_to_p2(&s, &r); + ge25519_p2_dbl(&r, &s); + ge25519_p1p1_to_p3(h, &r); + + for (i = 0; i < 64; i += 2) { + ge25519_cmov8_base(&t, i / 2, e[i]); + ge25519_madd(&r, h, &t); + ge25519_p1p1_to_p3(h, &r); + } +} + +/* multiply by the order of the main subgroup l = 2^252+27742317777372353535851937790883648493 */ +static void +ge25519_mul_l(ge25519_p3 *r, const ge25519_p3 *A) +{ + static const signed char aslide[253] = { + 13, 0, 0, 0, 0, -1, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, -13, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 3, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 + }; + ge25519_cached Ai[8]; + ge25519_p1p1 t; + ge25519_p3 u; + ge25519_p3 A2; + int i; + + ge25519_p3_to_cached(&Ai[0], A); + ge25519_p3_dbl(&t, A); + ge25519_p1p1_to_p3(&A2, &t); + ge25519_add(&t, &A2, &Ai[0]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[1], &u); + ge25519_add(&t, &A2, &Ai[1]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[2], &u); + ge25519_add(&t, &A2, &Ai[2]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[3], &u); + ge25519_add(&t, &A2, &Ai[3]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[4], &u); + ge25519_add(&t, &A2, &Ai[4]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[5], &u); + ge25519_add(&t, &A2, &Ai[5]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[6], &u); + ge25519_add(&t, &A2, &Ai[6]); + ge25519_p1p1_to_p3(&u, &t); + ge25519_p3_to_cached(&Ai[7], &u); + + ge25519_p3_0(r); + + for (i = 252; i >= 0; --i) { + ge25519_p3_dbl(&t, r); + + if (aslide[i] > 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_add(&t, &u, &Ai[aslide[i] / 2]); + } else if (aslide[i] < 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_sub(&t, &u, &Ai[(-aslide[i]) / 2]); + } + + ge25519_p1p1_to_p3(r, &t); + } +} + +int +ge25519_is_on_curve(const ge25519_p3 *p) +{ + fe25519 x2; + fe25519 y2; + fe25519 z2; + fe25519 z4; + fe25519 t0; + fe25519 t1; + + fe25519_sq(x2, p->X); + fe25519_sq(y2, p->Y); + fe25519_sq(z2, p->Z); + fe25519_sub(t0, y2, x2); + fe25519_mul(t0, t0, z2); + + fe25519_mul(t1, x2, y2); + fe25519_mul(t1, t1, d); + fe25519_sq(z4, z2); + fe25519_add(t1, t1, z4); + fe25519_sub(t0, t0, t1); + + return fe25519_iszero(t0); +} + +int +ge25519_is_on_main_subgroup(const ge25519_p3 *p) +{ + ge25519_p3 pl; + + ge25519_mul_l(&pl, p); + + return fe25519_iszero(pl.X); +} + +int +ge25519_is_canonical(const unsigned char *s) +{ + unsigned char c; + unsigned char d; + unsigned int i; + + c = (s[31] & 0x7f) ^ 0x7f; + for (i = 30; i > 0; i--) { + c |= s[i] ^ 0xff; + } + c = (((unsigned int) c) - 1U) >> 8; + d = (0xed - 1U - (unsigned int) s[0]) >> 8; + + return 1 - (c & d & 1); +} + +int +ge25519_has_small_order(const unsigned char s[32]) +{ + CRYPTO_ALIGN(16) + static const unsigned char blacklist[][32] = { + /* 0 (order 4) */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + /* 1 (order 1) */ + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + /* 2707385501144840649318225287225658788936804267575313519463743609750303402022 + (order 8) */ + { 0x26, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, + 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, + 0x33, 0x39, 0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x05 }, + /* 55188659117513257062467267217118295137698188065244968500265048394206261417927 + (order 8) */ + { 0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, + 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, + 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0x7a }, + /* p-1 (order 2) */ + { 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, + /* p (=0, order 4) */ + { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, + /* p+1 (=1, order 1) */ + { 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f } + }; + unsigned char c[7] = { 0 }; + unsigned int k; + size_t i, j; + + COMPILER_ASSERT(7 == sizeof blacklist / sizeof blacklist[0]); + for (j = 0; j < 31; j++) { + for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { + c[i] |= s[j] ^ blacklist[i][j]; + } + } + for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { + c[i] |= (s[j] & 0x7f) ^ blacklist[i][j]; + } + k = 0; + for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { + k |= (c[i] - 1); + } + return (int) ((k >> 8) & 1); +} + +/* + Input: + a[0]+256*a[1]+...+256^31*a[31] = a + b[0]+256*b[1]+...+256^31*b[31] = b + * + Output: + s[0]+256*s[1]+...+256^31*s[31] = (ab) mod l + where l = 2^252 + 27742317777372353535851937790883648493. + */ + +void +sc25519_mul(unsigned char s[32], const unsigned char a[32], const unsigned char b[32]) +{ + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + + int64_t s0; + int64_t s1; + int64_t s2; + int64_t s3; + int64_t s4; + int64_t s5; + int64_t s6; + int64_t s7; + int64_t s8; + int64_t s9; + int64_t s10; + int64_t s11; + int64_t s12; + int64_t s13; + int64_t s14; + int64_t s15; + int64_t s16; + int64_t s17; + int64_t s18; + int64_t s19; + int64_t s20; + int64_t s21; + int64_t s22; + int64_t s23; + + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + int64_t carry17; + int64_t carry18; + int64_t carry19; + int64_t carry20; + int64_t carry21; + int64_t carry22; + + s0 = a0 * b0; + s1 = a0 * b1 + a1 * b0; + s2 = a0 * b2 + a1 * b1 + a2 * b0; + s3 = a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; + s4 = a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; + s5 = a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; + s6 = a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; + s7 = a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + + a6 * b1 + a7 * b0; + s8 = a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + + a6 * b2 + a7 * b1 + a8 * b0; + s9 = a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; + s10 = a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; + s11 = a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; + s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; + s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2; + s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + + a9 * b5 + a10 * b4 + a11 * b3; + s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + + a10 * b5 + a11 * b4; + s16 = + a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; + s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; + s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; + s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; + s20 = a9 * b11 + a10 * b10 + a11 * b9; + s21 = a10 * b11 + a11 * b10; + s22 = a11 * b11; + s23 = 0; + + carry0 = (s0 + (int64_t) (1L << 20)) >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry2 = (s2 + (int64_t) (1L << 20)) >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry4 = (s4 + (int64_t) (1L << 20)) >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry6 = (s6 + (int64_t) (1L << 20)) >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry8 = (s8 + (int64_t) (1L << 20)) >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry10 = (s10 + (int64_t) (1L << 20)) >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + carry12 = (s12 + (int64_t) (1L << 20)) >> 21; + s13 += carry12; + s12 -= carry12 * ((uint64_t) 1L << 21); + carry14 = (s14 + (int64_t) (1L << 20)) >> 21; + s15 += carry14; + s14 -= carry14 * ((uint64_t) 1L << 21); + carry16 = (s16 + (int64_t) (1L << 20)) >> 21; + s17 += carry16; + s16 -= carry16 * ((uint64_t) 1L << 21); + carry18 = (s18 + (int64_t) (1L << 20)) >> 21; + s19 += carry18; + s18 -= carry18 * ((uint64_t) 1L << 21); + carry20 = (s20 + (int64_t) (1L << 20)) >> 21; + s21 += carry20; + s20 -= carry20 * ((uint64_t) 1L << 21); + carry22 = (s22 + (int64_t) (1L << 20)) >> 21; + s23 += carry22; + s22 -= carry22 * ((uint64_t) 1L << 21); + + carry1 = (s1 + (int64_t) (1L << 20)) >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry3 = (s3 + (int64_t) (1L << 20)) >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry5 = (s5 + (int64_t) (1L << 20)) >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry7 = (s7 + (int64_t) (1L << 20)) >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry9 = (s9 + (int64_t) (1L << 20)) >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry11 = (s11 + (int64_t) (1L << 20)) >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + carry13 = (s13 + (int64_t) (1L << 20)) >> 21; + s14 += carry13; + s13 -= carry13 * ((uint64_t) 1L << 21); + carry15 = (s15 + (int64_t) (1L << 20)) >> 21; + s16 += carry15; + s15 -= carry15 * ((uint64_t) 1L << 21); + carry17 = (s17 + (int64_t) (1L << 20)) >> 21; + s18 += carry17; + s17 -= carry17 * ((uint64_t) 1L << 21); + carry19 = (s19 + (int64_t) (1L << 20)) >> 21; + s20 += carry19; + s19 -= carry19 * ((uint64_t) 1L << 21); + carry21 = (s21 + (int64_t) (1L << 20)) >> 21; + s22 += carry21; + s21 -= carry21 * ((uint64_t) 1L << 21); + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + + carry6 = (s6 + (int64_t) (1L << 20)) >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry8 = (s8 + (int64_t) (1L << 20)) >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry10 = (s10 + (int64_t) (1L << 20)) >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + carry12 = (s12 + (int64_t) (1L << 20)) >> 21; + s13 += carry12; + s12 -= carry12 * ((uint64_t) 1L << 21); + carry14 = (s14 + (int64_t) (1L << 20)) >> 21; + s15 += carry14; + s14 -= carry14 * ((uint64_t) 1L << 21); + carry16 = (s16 + (int64_t) (1L << 20)) >> 21; + s17 += carry16; + s16 -= carry16 * ((uint64_t) 1L << 21); + + carry7 = (s7 + (int64_t) (1L << 20)) >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry9 = (s9 + (int64_t) (1L << 20)) >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry11 = (s11 + (int64_t) (1L << 20)) >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + carry13 = (s13 + (int64_t) (1L << 20)) >> 21; + s14 += carry13; + s13 -= carry13 * ((uint64_t) 1L << 21); + carry15 = (s15 + (int64_t) (1L << 20)) >> 21; + s16 += carry15; + s15 -= carry15 * ((uint64_t) 1L << 21); + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (int64_t) (1L << 20)) >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry2 = (s2 + (int64_t) (1L << 20)) >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry4 = (s4 + (int64_t) (1L << 20)) >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry6 = (s6 + (int64_t) (1L << 20)) >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry8 = (s8 + (int64_t) (1L << 20)) >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry10 = (s10 + (int64_t) (1L << 20)) >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + + carry1 = (s1 + (int64_t) (1L << 20)) >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry3 = (s3 + (int64_t) (1L << 20)) >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry5 = (s5 + (int64_t) (1L << 20)) >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry7 = (s7 + (int64_t) (1L << 20)) >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry9 = (s9 + (int64_t) (1L << 20)) >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry11 = (s11 + (int64_t) (1L << 20)) >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 * ((uint64_t) 1 << 5)); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 * ((uint64_t) 1 << 2)); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 * ((uint64_t) 1 << 7)); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 * ((uint64_t) 1 << 4)); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 * ((uint64_t) 1 << 1)); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 * ((uint64_t) 1 << 6)); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 * ((uint64_t) 1 << 3)); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 * ((uint64_t) 1 << 5)); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 * ((uint64_t) 1 << 2)); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 * ((uint64_t) 1 << 7)); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +/* + Input: + a[0]+256*a[1]+...+256^31*a[31] = a + b[0]+256*b[1]+...+256^31*b[31] = b + c[0]+256*c[1]+...+256^31*c[31] = c + * + Output: + s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l + where l = 2^252 + 27742317777372353535851937790883648493. + */ + +void +sc25519_muladd(unsigned char s[32], const unsigned char a[32], + const unsigned char b[32], const unsigned char c[32]) +{ + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + + int64_t c0 = 2097151 & load_3(c); + int64_t c1 = 2097151 & (load_4(c + 2) >> 5); + int64_t c2 = 2097151 & (load_3(c + 5) >> 2); + int64_t c3 = 2097151 & (load_4(c + 7) >> 7); + int64_t c4 = 2097151 & (load_4(c + 10) >> 4); + int64_t c5 = 2097151 & (load_3(c + 13) >> 1); + int64_t c6 = 2097151 & (load_4(c + 15) >> 6); + int64_t c7 = 2097151 & (load_3(c + 18) >> 3); + int64_t c8 = 2097151 & load_3(c + 21); + int64_t c9 = 2097151 & (load_4(c + 23) >> 5); + int64_t c10 = 2097151 & (load_3(c + 26) >> 2); + int64_t c11 = (load_4(c + 28) >> 7); + + int64_t s0; + int64_t s1; + int64_t s2; + int64_t s3; + int64_t s4; + int64_t s5; + int64_t s6; + int64_t s7; + int64_t s8; + int64_t s9; + int64_t s10; + int64_t s11; + int64_t s12; + int64_t s13; + int64_t s14; + int64_t s15; + int64_t s16; + int64_t s17; + int64_t s18; + int64_t s19; + int64_t s20; + int64_t s21; + int64_t s22; + int64_t s23; + + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + int64_t carry17; + int64_t carry18; + int64_t carry19; + int64_t carry20; + int64_t carry21; + int64_t carry22; + + s0 = c0 + a0 * b0; + s1 = c1 + a0 * b1 + a1 * b0; + s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; + s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; + s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; + s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; + s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + + a6 * b0; + s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + + a6 * b1 + a7 * b0; + s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + + a6 * b2 + a7 * b1 + a8 * b0; + s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; + s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; + s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; + s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + + a7 * b5 + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; + s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + + a8 * b5 + a9 * b4 + a10 * b3 + a11 * b2; + s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + + a9 * b5 + a10 * b4 + a11 * b3; + s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + + a10 * b5 + a11 * b4; + s16 = + a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; + s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; + s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; + s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; + s20 = a9 * b11 + a10 * b10 + a11 * b9; + s21 = a10 * b11 + a11 * b10; + s22 = a11 * b11; + s23 = 0; + + carry0 = (s0 + (int64_t) (1L << 20)) >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry2 = (s2 + (int64_t) (1L << 20)) >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry4 = (s4 + (int64_t) (1L << 20)) >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry6 = (s6 + (int64_t) (1L << 20)) >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry8 = (s8 + (int64_t) (1L << 20)) >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry10 = (s10 + (int64_t) (1L << 20)) >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + carry12 = (s12 + (int64_t) (1L << 20)) >> 21; + s13 += carry12; + s12 -= carry12 * ((uint64_t) 1L << 21); + carry14 = (s14 + (int64_t) (1L << 20)) >> 21; + s15 += carry14; + s14 -= carry14 * ((uint64_t) 1L << 21); + carry16 = (s16 + (int64_t) (1L << 20)) >> 21; + s17 += carry16; + s16 -= carry16 * ((uint64_t) 1L << 21); + carry18 = (s18 + (int64_t) (1L << 20)) >> 21; + s19 += carry18; + s18 -= carry18 * ((uint64_t) 1L << 21); + carry20 = (s20 + (int64_t) (1L << 20)) >> 21; + s21 += carry20; + s20 -= carry20 * ((uint64_t) 1L << 21); + carry22 = (s22 + (int64_t) (1L << 20)) >> 21; + s23 += carry22; + s22 -= carry22 * ((uint64_t) 1L << 21); + + carry1 = (s1 + (int64_t) (1L << 20)) >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry3 = (s3 + (int64_t) (1L << 20)) >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry5 = (s5 + (int64_t) (1L << 20)) >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry7 = (s7 + (int64_t) (1L << 20)) >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry9 = (s9 + (int64_t) (1L << 20)) >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry11 = (s11 + (int64_t) (1L << 20)) >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + carry13 = (s13 + (int64_t) (1L << 20)) >> 21; + s14 += carry13; + s13 -= carry13 * ((uint64_t) 1L << 21); + carry15 = (s15 + (int64_t) (1L << 20)) >> 21; + s16 += carry15; + s15 -= carry15 * ((uint64_t) 1L << 21); + carry17 = (s17 + (int64_t) (1L << 20)) >> 21; + s18 += carry17; + s17 -= carry17 * ((uint64_t) 1L << 21); + carry19 = (s19 + (int64_t) (1L << 20)) >> 21; + s20 += carry19; + s19 -= carry19 * ((uint64_t) 1L << 21); + carry21 = (s21 + (int64_t) (1L << 20)) >> 21; + s22 += carry21; + s21 -= carry21 * ((uint64_t) 1L << 21); + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + + carry6 = (s6 + (int64_t) (1L << 20)) >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry8 = (s8 + (int64_t) (1L << 20)) >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry10 = (s10 + (int64_t) (1L << 20)) >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + carry12 = (s12 + (int64_t) (1L << 20)) >> 21; + s13 += carry12; + s12 -= carry12 * ((uint64_t) 1L << 21); + carry14 = (s14 + (int64_t) (1L << 20)) >> 21; + s15 += carry14; + s14 -= carry14 * ((uint64_t) 1L << 21); + carry16 = (s16 + (int64_t) (1L << 20)) >> 21; + s17 += carry16; + s16 -= carry16 * ((uint64_t) 1L << 21); + + carry7 = (s7 + (int64_t) (1L << 20)) >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry9 = (s9 + (int64_t) (1L << 20)) >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry11 = (s11 + (int64_t) (1L << 20)) >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + carry13 = (s13 + (int64_t) (1L << 20)) >> 21; + s14 += carry13; + s13 -= carry13 * ((uint64_t) 1L << 21); + carry15 = (s15 + (int64_t) (1L << 20)) >> 21; + s16 += carry15; + s15 -= carry15 * ((uint64_t) 1L << 21); + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (int64_t) (1L << 20)) >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry2 = (s2 + (int64_t) (1L << 20)) >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry4 = (s4 + (int64_t) (1L << 20)) >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry6 = (s6 + (int64_t) (1L << 20)) >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry8 = (s8 + (int64_t) (1L << 20)) >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry10 = (s10 + (int64_t) (1L << 20)) >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + + carry1 = (s1 + (int64_t) (1L << 20)) >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry3 = (s3 + (int64_t) (1L << 20)) >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry5 = (s5 + (int64_t) (1L << 20)) >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry7 = (s7 + (int64_t) (1L << 20)) >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry9 = (s9 + (int64_t) (1L << 20)) >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry11 = (s11 + (int64_t) (1L << 20)) >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 * ((uint64_t) 1 << 5)); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 * ((uint64_t) 1 << 2)); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 * ((uint64_t) 1 << 7)); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 * ((uint64_t) 1 << 4)); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 * ((uint64_t) 1 << 1)); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 * ((uint64_t) 1 << 6)); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 * ((uint64_t) 1 << 3)); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 * ((uint64_t) 1 << 5)); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 * ((uint64_t) 1 << 2)); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 * ((uint64_t) 1 << 7)); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +/* + Input: + a[0]+256*a[1]+...+256^31*a[31] = a + * + Output: + s[0]+256*s[1]+...+256^31*s[31] = a^2 mod l + where l = 2^252 + 27742317777372353535851937790883648493. + */ + +static inline void +sc25519_sq(unsigned char *s, const unsigned char *a) +{ + sc25519_mul(s, a, a); +} + +/* + Input: + s[0]+256*a[1]+...+256^31*a[31] = a + n + * + Output: + s[0]+256*s[1]+...+256^31*s[31] = x * s^(s^n) mod l + where l = 2^252 + 27742317777372353535851937790883648493. + Overwrites s in place. + */ + +static inline void +sc25519_sqmul(unsigned char s[32], const int n, const unsigned char a[32]) +{ + int i; + + for (i = 0; i < n; i++) { + sc25519_sq(s, s); + } + sc25519_mul(s, s, a); +} + +void +sc25519_invert(unsigned char recip[32], const unsigned char s[32]) +{ + unsigned char _10[32], _100[32], _1000[32], _10000[32], _100000[32], + _1000000[32], _10010011[32], _10010111[32], _100110[32], _1010[32], + _1010000[32], _1010011[32], _1011[32], _10110[32], _10111101[32], + _11[32], _1100011[32], _1100111[32], _11010011[32], _1101011[32], + _11100111[32], _11101011[32], _11110101[32]; + + sc25519_sq(_10, s); + sc25519_mul(_11, s, _10); + sc25519_mul(_100, s, _11); + sc25519_sq(_1000, _100); + sc25519_mul(_1010, _10, _1000); + sc25519_mul(_1011, s, _1010); + sc25519_sq(_10000, _1000); + sc25519_sq(_10110, _1011); + sc25519_mul(_100000, _1010, _10110); + sc25519_mul(_100110, _10000, _10110); + sc25519_sq(_1000000, _100000); + sc25519_mul(_1010000, _10000, _1000000); + sc25519_mul(_1010011, _11, _1010000); + sc25519_mul(_1100011, _10000, _1010011); + sc25519_mul(_1100111, _100, _1100011); + sc25519_mul(_1101011, _100, _1100111); + sc25519_mul(_10010011, _1000000, _1010011); + sc25519_mul(_10010111, _100, _10010011); + sc25519_mul(_10111101, _100110, _10010111); + sc25519_mul(_11010011, _10110, _10111101); + sc25519_mul(_11100111, _1010000, _10010111); + sc25519_mul(_11101011, _100, _11100111); + sc25519_mul(_11110101, _1010, _11101011); + + sc25519_mul(recip, _1011, _11110101); + sc25519_sqmul(recip, 126, _1010011); + sc25519_sqmul(recip, 9, _10); + sc25519_mul(recip, recip, _11110101); + sc25519_sqmul(recip, 7, _1100111); + sc25519_sqmul(recip, 9, _11110101); + sc25519_sqmul(recip, 11, _10111101); + sc25519_sqmul(recip, 8, _11100111); + sc25519_sqmul(recip, 9, _1101011); + sc25519_sqmul(recip, 6, _1011); + sc25519_sqmul(recip, 14, _10010011); + sc25519_sqmul(recip, 10, _1100011); + sc25519_sqmul(recip, 9, _10010111); + sc25519_sqmul(recip, 10, _11110101); + sc25519_sqmul(recip, 8, _11010011); + sc25519_sqmul(recip, 8, _11101011); +} + +/* + Input: + s[0]+256*s[1]+...+256^63*s[63] = s + * + Output: + s[0]+256*s[1]+...+256^31*s[31] = s mod l + where l = 2^252 + 27742317777372353535851937790883648493. + Overwrites s in place. + */ + +void +sc25519_reduce(unsigned char s[64]) +{ + int64_t s0 = 2097151 & load_3(s); + int64_t s1 = 2097151 & (load_4(s + 2) >> 5); + int64_t s2 = 2097151 & (load_3(s + 5) >> 2); + int64_t s3 = 2097151 & (load_4(s + 7) >> 7); + int64_t s4 = 2097151 & (load_4(s + 10) >> 4); + int64_t s5 = 2097151 & (load_3(s + 13) >> 1); + int64_t s6 = 2097151 & (load_4(s + 15) >> 6); + int64_t s7 = 2097151 & (load_3(s + 18) >> 3); + int64_t s8 = 2097151 & load_3(s + 21); + int64_t s9 = 2097151 & (load_4(s + 23) >> 5); + int64_t s10 = 2097151 & (load_3(s + 26) >> 2); + int64_t s11 = 2097151 & (load_4(s + 28) >> 7); + int64_t s12 = 2097151 & (load_4(s + 31) >> 4); + int64_t s13 = 2097151 & (load_3(s + 34) >> 1); + int64_t s14 = 2097151 & (load_4(s + 36) >> 6); + int64_t s15 = 2097151 & (load_3(s + 39) >> 3); + int64_t s16 = 2097151 & load_3(s + 42); + int64_t s17 = 2097151 & (load_4(s + 44) >> 5); + int64_t s18 = 2097151 & (load_3(s + 47) >> 2); + int64_t s19 = 2097151 & (load_4(s + 49) >> 7); + int64_t s20 = 2097151 & (load_4(s + 52) >> 4); + int64_t s21 = 2097151 & (load_3(s + 55) >> 1); + int64_t s22 = 2097151 & (load_4(s + 57) >> 6); + int64_t s23 = (load_4(s + 60) >> 3); + + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + + carry6 = (s6 + (int64_t) (1L << 20)) >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry8 = (s8 + (int64_t) (1L << 20)) >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry10 = (s10 + (int64_t) (1L << 20)) >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + carry12 = (s12 + (int64_t) (1L << 20)) >> 21; + s13 += carry12; + s12 -= carry12 * ((uint64_t) 1L << 21); + carry14 = (s14 + (int64_t) (1L << 20)) >> 21; + s15 += carry14; + s14 -= carry14 * ((uint64_t) 1L << 21); + carry16 = (s16 + (int64_t) (1L << 20)) >> 21; + s17 += carry16; + s16 -= carry16 * ((uint64_t) 1L << 21); + + carry7 = (s7 + (int64_t) (1L << 20)) >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry9 = (s9 + (int64_t) (1L << 20)) >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry11 = (s11 + (int64_t) (1L << 20)) >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + carry13 = (s13 + (int64_t) (1L << 20)) >> 21; + s14 += carry13; + s13 -= carry13 * ((uint64_t) 1L << 21); + carry15 = (s15 + (int64_t) (1L << 20)) >> 21; + s16 += carry15; + s15 -= carry15 * ((uint64_t) 1L << 21); + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (int64_t) (1L << 20)) >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry2 = (s2 + (int64_t) (1L << 20)) >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry4 = (s4 + (int64_t) (1L << 20)) >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry6 = (s6 + (int64_t) (1L << 20)) >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry8 = (s8 + (int64_t) (1L << 20)) >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry10 = (s10 + (int64_t) (1L << 20)) >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + + carry1 = (s1 + (int64_t) (1L << 20)) >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry3 = (s3 + (int64_t) (1L << 20)) >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry5 = (s5 + (int64_t) (1L << 20)) >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry7 = (s7 + (int64_t) (1L << 20)) >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry9 = (s9 + (int64_t) (1L << 20)) >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry11 = (s11 + (int64_t) (1L << 20)) >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 * ((uint64_t) 1L << 21); + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 * ((uint64_t) 1L << 21); + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 * ((uint64_t) 1L << 21); + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 * ((uint64_t) 1L << 21); + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 * ((uint64_t) 1L << 21); + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 * ((uint64_t) 1L << 21); + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 * ((uint64_t) 1L << 21); + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 * ((uint64_t) 1L << 21); + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 * ((uint64_t) 1L << 21); + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 * ((uint64_t) 1L << 21); + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 * ((uint64_t) 1L << 21); + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 * ((uint64_t) 1L << 21); + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 * ((uint64_t) 1 << 5)); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 * ((uint64_t) 1 << 2)); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 * ((uint64_t) 1 << 7)); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 * ((uint64_t) 1 << 4)); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 * ((uint64_t) 1 << 1)); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 * ((uint64_t) 1 << 6)); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 * ((uint64_t) 1 << 3)); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 * ((uint64_t) 1 << 5)); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 * ((uint64_t) 1 << 2)); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 * ((uint64_t) 1 << 7)); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +int +sc25519_is_canonical(const unsigned char s[32]) +{ + /* 2^252+27742317777372353535851937790883648493 */ + static const unsigned char L[32] = { + 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, + 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 + }; + unsigned char c = 0; + unsigned char n = 1; + unsigned int i = 32; + + do { + i--; + c |= ((s[i] - L[i]) >> 8) & n; + n &= ((s[i] ^ L[i]) - 1) >> 8; + } while (i != 0); + + return (c != 0); +} + +static void +ge25519_elligator2(unsigned char s[32], const fe25519 r, const unsigned char x_sign) +{ + fe25519 gx; + fe25519 negx; + fe25519 rr2; + fe25519 x, x2, x3; + ge25519_p3 p3; + ge25519_p1p1 p1; + ge25519_p2 p2; + unsigned int notsquare; + + fe25519_sq2(rr2, r); + rr2[0]++; + fe25519_invert(rr2, rr2); + fe25519_mul32(x, rr2, curve25519_A[0]); + fe25519_neg(x, x); + + fe25519_sq(x2, x); + fe25519_mul(x3, x, x2); + fe25519_add(gx, x3, x); + fe25519_mul32(x2, x2, curve25519_A[0]); + fe25519_add(gx, x2, gx); + + notsquare = fe25519_notsquare(gx); + fe25519_neg(negx, x); + fe25519_cmov(x, negx, notsquare); + fe25519_0(x2); + fe25519_cmov(x2, curve25519_A, notsquare); + fe25519_sub(x, x, x2); + + /* yed = (x-1)/(x+1) */ + { + fe25519 one; + fe25519 x_plus_one; + fe25519 x_plus_one_inv; + fe25519 x_minus_one; + fe25519 yed; + + fe25519_1(one); + fe25519_add(x_plus_one, x, one); + fe25519_sub(x_minus_one, x, one); + fe25519_invert(x_plus_one_inv, x_plus_one); + fe25519_mul(yed, x_minus_one, x_plus_one_inv); + fe25519_tobytes(s, yed); + } + + /* recover x */ + s[31] |= x_sign; + if (ge25519_frombytes(&p3, s) != 0) { + abort(); /* LCOV_EXCL_LINE */ + } + + /* multiply by the cofactor */ + ge25519_p3_dbl(&p1, &p3); + ge25519_p1p1_to_p2(&p2, &p1); + ge25519_p2_dbl(&p1, &p2); + ge25519_p1p1_to_p2(&p2, &p1); + ge25519_p2_dbl(&p1, &p2); + ge25519_p1p1_to_p3(&p3, &p1); + + ge25519_p3_tobytes(s, &p3); +} + +void +ge25519_from_uniform(unsigned char s[32], const unsigned char r[32]) +{ + fe25519 r_fe; + unsigned char x_sign; + + memcpy(s, r, 32); + x_sign = s[31] & 0x80; + s[31] &= 0x7f; + fe25519_frombytes(r_fe, s); + ge25519_elligator2(s, r_fe, x_sign); +} + +void +ge25519_from_hash(unsigned char s[32], const unsigned char h[64]) +{ + unsigned char fl[32]; + unsigned char gl[32]; + fe25519 fe_f; + fe25519 fe_g; + size_t i; + unsigned char x_sign; + + x_sign = h[0] & 0x80; + for (i = 0; i < 32; i++) { + fl[i] = h[63 - i]; + gl[i] = h[31 - i]; + } + fl[31] &= 0x7f; + gl[31] &= 0x7f; + fe25519_frombytes(fe_f, fl); + fe25519_frombytes(fe_g, gl); + fe_f[0] += (h[32] >> 7) * 19; + for (i = 0; i < sizeof (fe25519) / sizeof fe_f[0]; i++) { + fe_f[i] += 38 * fe_g[i]; + } + fe25519_reduce(fe_f, fe_f); + ge25519_elligator2(s, fe_f, x_sign); +} + +/* Ristretto group */ + +static int +ristretto255_sqrt_ratio_m1(fe25519 x, const fe25519 u, const fe25519 v) +{ + fe25519 v3; + fe25519 vxx; + fe25519 m_root_check, p_root_check, f_root_check; + fe25519 x_sqrtm1; + int has_m_root, has_p_root, has_f_root; + + fe25519_sq(v3, v); + fe25519_mul(v3, v3, v); /* v3 = v^3 */ + fe25519_sq(x, v3); + fe25519_mul(x, x, v); + fe25519_mul(x, x, u); /* x = uv^7 */ + + fe25519_pow22523(x, x); /* x = (uv^7)^((q-5)/8) */ + fe25519_mul(x, x, v3); + fe25519_mul(x, x, u); /* x = uv^3(uv^7)^((q-5)/8) */ + + fe25519_sq(vxx, x); + fe25519_mul(vxx, vxx, v); /* vx^2 */ + fe25519_sub(m_root_check, vxx, u); /* vx^2-u */ + fe25519_add(p_root_check, vxx, u); /* vx^2+u */ + fe25519_mul(f_root_check, u, sqrtm1); /* u*sqrt(-1) */ + fe25519_add(f_root_check, vxx, f_root_check); /* vx^2+u*sqrt(-1) */ + has_m_root = fe25519_iszero(m_root_check); + has_p_root = fe25519_iszero(p_root_check); + has_f_root = fe25519_iszero(f_root_check); + fe25519_mul(x_sqrtm1, x, sqrtm1); /* x*sqrt(-1) */ + + fe25519_cmov(x, x_sqrtm1, has_p_root | has_f_root); + fe25519_abs(x, x); + + return has_m_root | has_p_root; +} + +static int +ristretto255_is_canonical(const unsigned char *s) +{ + unsigned char c; + unsigned char d; + unsigned char e; + unsigned int i; + + c = (s[31] & 0x7f) ^ 0x7f; + for (i = 30; i > 0; i--) { + c |= s[i] ^ 0xff; + } + c = (((unsigned int) c) - 1U) >> 8; + d = (0xed - 1U - (unsigned int) s[0]) >> 8; + e = s[31] >> 7; + + return 1 - (((c & d) | e | s[0]) & 1); +} + +int +ristretto255_frombytes(ge25519_p3 *h, const unsigned char *s) +{ + fe25519 inv_sqrt; + fe25519 one; + fe25519 s_; + fe25519 ss; + fe25519 u1, u2; + fe25519 u1u1, u2u2; + fe25519 v; + fe25519 v_u2u2; + int was_square; + + if (ristretto255_is_canonical(s) == 0) { + return -1; + } + fe25519_frombytes(s_, s); + fe25519_sq(ss, s_); /* ss = s^2 */ + + fe25519_1(u1); + fe25519_sub(u1, u1, ss); /* u1 = 1-ss */ + fe25519_sq(u1u1, u1); /* u1u1 = u1^2 */ + + fe25519_1(u2); + fe25519_add(u2, u2, ss); /* u2 = 1+ss */ + fe25519_sq(u2u2, u2); /* u2u2 = u2^2 */ + + fe25519_mul(v, d, u1u1); /* v = d*u1^2 */ + fe25519_neg(v, v); /* v = -d*u1^2 */ + fe25519_sub(v, v, u2u2); /* v = -(d*u1^2)-u2^2 */ + + fe25519_mul(v_u2u2, v, u2u2); /* v_u2u2 = v*u2^2 */ + + fe25519_1(one); + was_square = ristretto255_sqrt_ratio_m1(inv_sqrt, one, v_u2u2); + fe25519_mul(h->X, inv_sqrt, u2); + fe25519_mul(h->Y, inv_sqrt, h->X); + fe25519_mul(h->Y, h->Y, v); + + fe25519_mul(h->X, h->X, s_); + fe25519_add(h->X, h->X, h->X); + fe25519_abs(h->X, h->X); + fe25519_mul(h->Y, u1, h->Y); + fe25519_1(h->Z); + fe25519_mul(h->T, h->X, h->Y); + + return - ((1 - was_square) | + fe25519_isnegative(h->T) | fe25519_iszero(h->Y)); +} + +void +ristretto255_p3_tobytes(unsigned char *s, const ge25519_p3 *h) +{ + fe25519 den1, den2; + fe25519 den_inv; + fe25519 eden; + fe25519 inv_sqrt; + fe25519 ix, iy; + fe25519 one; + fe25519 s_; + fe25519 t_z_inv; + fe25519 u1, u2; + fe25519 u1_u2u2; + fe25519 x_, y_; + fe25519 x_z_inv; + fe25519 z_inv; + fe25519 zmy; + int rotate; + + fe25519_add(u1, h->Z, h->Y); /* u1 = Z+Y */ + fe25519_sub(zmy, h->Z, h->Y); /* zmy = Z-Y */ + fe25519_mul(u1, u1, zmy); /* u1 = (Z+Y)*(Z-Y) */ + fe25519_mul(u2, h->X, h->Y); /* u2 = X*Y */ + + fe25519_sq(u1_u2u2, u2); /* u1_u2u2 = u2^2 */ + fe25519_mul(u1_u2u2, u1, u1_u2u2); /* u1_u2u2 = u1*u2^2 */ + + fe25519_1(one); + (void) ristretto255_sqrt_ratio_m1(inv_sqrt, one, u1_u2u2); + fe25519_mul(den1, inv_sqrt, u1); /* den1 = inv_sqrt*u1 */ + fe25519_mul(den2, inv_sqrt, u2); /* den2 = inv_sqrt*u2 */ + fe25519_mul(z_inv, den1, den2); /* z_inv = den1*den2 */ + fe25519_mul(z_inv, z_inv, h->T); /* z_inv = den1*den2*T */ + + fe25519_mul(ix, h->X, sqrtm1); /* ix = X*sqrt(-1) */ + fe25519_mul(iy, h->Y, sqrtm1); /* iy = Y*sqrt(-1) */ + fe25519_mul(eden, den1, invsqrtamd); /* eden = den1/sqrt(a-d) */ + + fe25519_mul(t_z_inv, h->T, z_inv); /* t_z_inv = T*z_inv */ + rotate = fe25519_isnegative(t_z_inv); + + fe25519_copy(x_, h->X); + fe25519_copy(y_, h->Y); + fe25519_copy(den_inv, den2); + + fe25519_cmov(x_, iy, rotate); + fe25519_cmov(y_, ix, rotate); + fe25519_cmov(den_inv, eden, rotate); + + fe25519_mul(x_z_inv, x_, z_inv); + fe25519_cneg(y_, y_, fe25519_isnegative(x_z_inv)); + + fe25519_sub(s_, h->Z, y_); + fe25519_mul(s_, den_inv, s_); + fe25519_abs(s_, s_); + fe25519_tobytes(s, s_); +} + +static void +ristretto255_elligator(ge25519_p3 *p, const fe25519 t) +{ + fe25519 c; + fe25519 n; + fe25519 one; + fe25519 r; + fe25519 rpd; + fe25519 s, s_prime; + fe25519 ss; + fe25519 u, v; + fe25519 w0, w1, w2, w3; + int wasnt_square; + + fe25519_1(one); + fe25519_sq(r, t); /* r = t^2 */ + fe25519_mul(r, sqrtm1, r); /* r = sqrt(-1)*t^2 */ + fe25519_add(u, r, one); /* u = r+1 */ + fe25519_mul(u, u, onemsqd); /* u = (r+1)*(1-d^2) */ + fe25519_1(c); + fe25519_neg(c, c); /* c = -1 */ + fe25519_add(rpd, r, d); /* rpd = r+d */ + fe25519_mul(v, r, d); /* v = r*d */ + fe25519_sub(v, c, v); /* v = c-r*d */ + fe25519_mul(v, v, rpd); /* v = (c-r*d)*(r+d) */ + + wasnt_square = 1 - ristretto255_sqrt_ratio_m1(s, u, v); + fe25519_mul(s_prime, s, t); + fe25519_abs(s_prime, s_prime); + fe25519_neg(s_prime, s_prime); /* s_prime = -|s*t| */ + fe25519_cmov(s, s_prime, wasnt_square); + fe25519_cmov(c, r, wasnt_square); + + fe25519_sub(n, r, one); /* n = r-1 */ + fe25519_mul(n, n, c); /* n = c*(r-1) */ + fe25519_mul(n, n, sqdmone); /* n = c*(r-1)*(d-1)^2 */ + fe25519_sub(n, n, v); /* n = c*(r-1)*(d-1)^2-v */ + + fe25519_add(w0, s, s); /* w0 = 2s */ + fe25519_mul(w0, w0, v); /* w0 = 2s*v */ + fe25519_mul(w1, n, sqrtadm1); /* w1 = n*sqrt(ad-1) */ + fe25519_sq(ss, s); /* ss = s^2 */ + fe25519_sub(w2, one, ss); /* w2 = 1-s^2 */ + fe25519_add(w3, one, ss); /* w3 = 1+s^2 */ + + fe25519_mul(p->X, w0, w3); + fe25519_mul(p->Y, w2, w1); + fe25519_mul(p->Z, w1, w3); + fe25519_mul(p->T, w0, w2); +} + +void +ristretto255_from_hash(unsigned char s[32], const unsigned char h[64]) +{ + fe25519 r0, r1; + ge25519_cached p1_cached; + ge25519_p1p1 p_p1p1; + ge25519_p3 p0, p1; + ge25519_p3 p; + + fe25519_frombytes(r0, h); + fe25519_frombytes(r1, h + 32); + ristretto255_elligator(&p0, r0); + ristretto255_elligator(&p1, r1); + ge25519_p3_to_cached(&p1_cached, &p1); + ge25519_add(&p_p1p1, &p0, &p1_cached); + ge25519_p1p1_to_p3(&p, &p_p1p1); + ristretto255_p3_tobytes(s, &p); +} diff --git a/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/base.h b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/base.h new file mode 100644 index 0000000..e18530b --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/base.h @@ -0,0 +1,1344 @@ +{ /* 0/31 */ + { + { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, + { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, + { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 } + }, + { + { -12815894, -12976347, -21581243, 11784320, -25355658, -2750717, -11717903, -3814571, -358445, -10211303 }, + { -21703237, 6903825, 27185491, 6451973, -29577724, -9554005, -15616551, 11189268, -26829678, -5319081 }, + { 26966642, 11152617, 32442495, 15396054, 14353839, -12752335, -3128826, -9541118, -15472047, -4166697 } + }, + { + { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, + { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, + { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 } + }, + { + { -17036878, 13921892, 10945806, -6033431, 27105052, -16084379, -28926210, 15006023, 3284568, -6276540 }, + { 23599295, -8306047, -11193664, -7687416, 13236774, 10506355, 7464579, 9656445, 13059162, 10374397 }, + { 7798556, 16710257, 3033922, 2874086, 28997861, 2835604, 32406664, -3839045, -641708, -101325 } + }, + { + { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, + { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, + { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 } + }, + { + { -15371964, -12862754, 32573250, 4720197, -26436522, 5875511, -19188627, -15224819, -9818940, -12085777 }, + { -8549212, 109983, 15149363, 2178705, 22900618, 4543417, 3044240, -15689887, 1762328, 14866737 }, + { -18199695, -15951423, -10473290, 1707278, -17185920, 3916101, -28236412, 3959421, 27914454, 4383652 } + }, + { + { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, + { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, + { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 } + }, + { + { 14499471, -2729599, -33191113, -4254652, 28494862, 14271267, 30290735, 10876454, -33154098, 2381726 }, + { -7195431, -2655363, -14730155, 462251, -27724326, 3941372, -6236617, 3696005, -32300832, 15351955 }, + { 27431194, 8222322, 16448760, -3907995, -18707002, 11938355, -32961401, -2970515, 29551813, 10109425 } + } +}, +{ /* 1/31 */ + { + { -13657040, -13155431, -31283750, 11777098, 21447386, 6519384, -2378284, -1627556, 10092783, -4764171 }, + { 27939166, 14210322, 4677035, 16277044, -22964462, -12398139, -32508754, 12005538, -17810127, 12803510 }, + { 17228999, -15661624, -1233527, 300140, -1224870, -11714777, 30364213, -9038194, 18016357, 4397660 } + }, + { + { -10958843, -7690207, 4776341, -14954238, 27850028, -15602212, -26619106, 14544525, -17477504, 982639 }, + { 29253598, 15796703, -2863982, -9908884, 10057023, 3163536, 7332899, -4120128, -21047696, 9934963 }, + { 5793303, 16271923, -24131614, -10116404, 29188560, 1206517, -14747930, 4559895, -30123922, -10897950 } + }, + { + { -27643952, -11493006, 16282657, -11036493, 28414021, -15012264, 24191034, 4541697, -13338309, 5500568 }, + { 12650548, -1497113, 9052871, 11355358, -17680037, -8400164, -17430592, 12264343, 10874051, 13524335 }, + { 25556948, -3045990, 714651, 2510400, 23394682, -10415330, 33119038, 5080568, -22528059, 5376628 } + }, + { + { -26088264, -4011052, -17013699, -3537628, -6726793, 1920897, -22321305, -9447443, 4535768, 1569007 }, + { -2255422, 14606630, -21692440, -8039818, 28430649, 8775819, -30494562, 3044290, 31848280, 12543772 }, + { -22028579, 2943893, -31857513, 6777306, 13784462, -4292203, -27377195, -2062731, 7718482, 14474653 } + }, + { + { 2385315, 2454213, -22631320, 46603, -4437935, -15680415, 656965, -7236665, 24316168, -5253567 }, + { 13741529, 10911568, -33233417, -8603737, -20177830, -1033297, 33040651, -13424532, -20729456, 8321686 }, + { 21060490, -2212744, 15712757, -4336099, 1639040, 10656336, 23845965, -11874838, -9984458, 608372 } + }, + { + { -13672732, -15087586, -10889693, -7557059, -6036909, 11305547, 1123968, -6780577, 27229399, 23887 }, + { -23244140, -294205, -11744728, 14712571, -29465699, -2029617, 12797024, -6440308, -1633405, 16678954 }, + { -29500620, 4770662, -16054387, 14001338, 7830047, 9564805, -1508144, -4795045, -17169265, 4904953 } + }, + { + { 24059557, 14617003, 19037157, -15039908, 19766093, -14906429, 5169211, 16191880, 2128236, -4326833 }, + { -16981152, 4124966, -8540610, -10653797, 30336522, -14105247, -29806336, 916033, -6882542, -2986532 }, + { -22630907, 12419372, -7134229, -7473371, -16478904, 16739175, 285431, 2763829, 15736322, 4143876 } + }, + { + { 2379352, 11839345, -4110402, -5988665, 11274298, 794957, 212801, -14594663, 23527084, -16458268 }, + { 33431127, -11130478, -17838966, -15626900, 8909499, 8376530, -32625340, 4087881, -15188911, -14416214 }, + { 1767683, 7197987, -13205226, -2022635, -13091350, 448826, 5799055, 4357868, -4774191, -16323038 } + } +}, +{ /* 2/31 */ + { + { 6721966, 13833823, -23523388, -1551314, 26354293, -11863321, 23365147, -3949732, 7390890, 2759800 }, + { 4409041, 2052381, 23373853, 10530217, 7676779, -12885954, 21302353, -4264057, 1244380, -12919645 }, + { -4421239, 7169619, 4982368, -2957590, 30256825, -2777540, 14086413, 9208236, 15886429, 16489664 } + }, + { + { 1996075, 10375649, 14346367, 13311202, -6874135, -16438411, -13693198, 398369, -30606455, -712933 }, + { -25307465, 9795880, -2777414, 14878809, -33531835, 14780363, 13348553, 12076947, -30836462, 5113182 }, + { -17770784, 11797796, 31950843, 13929123, -25888302, 12288344, -30341101, -7336386, 13847711, 5387222 } + }, + { + { -18582163, -3416217, 17824843, -2340966, 22744343, -10442611, 8763061, 3617786, -19600662, 10370991 }, + { 20246567, -14369378, 22358229, -543712, 18507283, -10413996, 14554437, -8746092, 32232924, 16763880 }, + { 9648505, 10094563, 26416693, 14745928, -30374318, -6472621, 11094161, 15689506, 3140038, -16510092 } + }, + { + { -16160072, 5472695, 31895588, 4744994, 8823515, 10365685, -27224800, 9448613, -28774454, 366295 }, + { 19153450, 11523972, -11096490, -6503142, -24647631, 5420647, 28344573, 8041113, 719605, 11671788 }, + { 8678025, 2694440, -6808014, 2517372, 4964326, 11152271, -15432916, -15266516, 27000813, -10195553 } + }, + { + { -15157904, 7134312, 8639287, -2814877, -7235688, 10421742, 564065, 5336097, 6750977, -14521026 }, + { 11836410, -3979488, 26297894, 16080799, 23455045, 15735944, 1695823, -8819122, 8169720, 16220347 }, + { -18115838, 8653647, 17578566, -6092619, -8025777, -16012763, -11144307, -2627664, -5990708, -14166033 } + }, + { + { -23308498, -10968312, 15213228, -10081214, -30853605, -11050004, 27884329, 2847284, 2655861, 1738395 }, + { -27537433, -14253021, -25336301, -8002780, -9370762, 8129821, 21651608, -3239336, -19087449, -11005278 }, + { 1533110, 3437855, 23735889, 459276, 29970501, 11335377, 26030092, 5821408, 10478196, 8544890 } + }, + { + { 32173121, -16129311, 24896207, 3921497, 22579056, -3410854, 19270449, 12217473, 17789017, -3395995 }, + { -30552961, -2228401, -15578829, -10147201, 13243889, 517024, 15479401, -3853233, 30460520, 1052596 }, + { -11614875, 13323618, 32618793, 8175907, -15230173, 12596687, 27491595, -4612359, 3179268, -9478891 } + }, + { + { 31947069, -14366651, -4640583, -15339921, -15125977, -6039709, -14756777, -16411740, 19072640, -9511060 }, + { 11685058, 11822410, 3158003, -13952594, 33402194, -4165066, 5977896, -5215017, 473099, 5040608 }, + { -20290863, 8198642, -27410132, 11602123, 1290375, -2799760, 28326862, 1721092, -19558642, -3131606 } + } +}, +{ /* 3/31 */ + { + { 7881532, 10687937, 7578723, 7738378, -18951012, -2553952, 21820786, 8076149, -27868496, 11538389 }, + { -19935666, 3899861, 18283497, -6801568, -15728660, -11249211, 8754525, 7446702, -5676054, 5797016 }, + { -11295600, -3793569, -15782110, -7964573, 12708869, -8456199, 2014099, -9050574, -2369172, -5877341 } + }, + { + { -22472376, -11568741, -27682020, 1146375, 18956691, 16640559, 1192730, -3714199, 15123619, 10811505 }, + { 14352098, -3419715, -18942044, 10822655, 32750596, 4699007, -70363, 15776356, -28886779, -11974553 }, + { -28241164, -8072475, -4978962, -5315317, 29416931, 1847569, -20654173, -16484855, 4714547, -9600655 } + }, + { + { 15200332, 8368572, 19679101, 15970074, -31872674, 1959451, 24611599, -4543832, -11745876, 12340220 }, + { 12876937, -10480056, 33134381, 6590940, -6307776, 14872440, 9613953, 8241152, 15370987, 9608631 }, + { -4143277, -12014408, 8446281, -391603, 4407738, 13629032, -7724868, 15866074, -28210621, -8814099 } + }, + { + { 26660628, -15677655, 8393734, 358047, -7401291, 992988, -23904233, 858697, 20571223, 8420556 }, + { 14620715, 13067227, -15447274, 8264467, 14106269, 15080814, 33531827, 12516406, -21574435, -12476749 }, + { 236881, 10476226, 57258, -14677024, 6472998, 2466984, 17258519, 7256740, 8791136, 15069930 } + }, + { + { 1276410, -9371918, 22949635, -16322807, -23493039, -5702186, 14711875, 4874229, -30663140, -2331391 }, + { 5855666, 4990204, -13711848, 7294284, -7804282, 1924647, -1423175, -7912378, -33069337, 9234253 }, + { 20590503, -9018988, 31529744, -7352666, -2706834, 10650548, 31559055, -11609587, 18979186, 13396066 } + }, + { + { 24474287, 4968103, 22267082, 4407354, 24063882, -8325180, -18816887, 13594782, 33514650, 7021958 }, + { -11566906, -6565505, -21365085, 15928892, -26158305, 4315421, -25948728, -3916677, -21480480, 12868082 }, + { -28635013, 13504661, 19988037, -2132761, 21078225, 6443208, -21446107, 2244500, -12455797, -8089383 } + }, + { + { -30595528, 13793479, -5852820, 319136, -25723172, -6263899, 33086546, 8957937, -15233648, 5540521 }, + { -11630176, -11503902, -8119500, -7643073, 2620056, 1022908, -23710744, -1568984, -16128528, -14962807 }, + { 23152971, 775386, 27395463, 14006635, -9701118, 4649512, 1689819, 892185, -11513277, -15205948 } + }, + { + { 9770129, 9586738, 26496094, 4324120, 1556511, -3550024, 27453819, 4763127, -19179614, 5867134 }, + { -32765025, 1927590, 31726409, -4753295, 23962434, -16019500, 27846559, 5931263, -29749703, -16108455 }, + { 27461885, -2977536, 22380810, 1815854, -23033753, -3031938, 7283490, -15148073, -19526700, 7734629 } + } +}, +{ /* 4/31 */ + { + { -8010264, -9590817, -11120403, 6196038, 29344158, -13430885, 7585295, -3176626, 18549497, 15302069 }, + { -32658337, -6171222, -7672793, -11051681, 6258878, 13504381, 10458790, -6418461, -8872242, 8424746 }, + { 24687205, 8613276, -30667046, -3233545, 1863892, -1830544, 19206234, 7134917, -11284482, -828919 } + }, + { + { 11334899, -9218022, 8025293, 12707519, 17523892, -10476071, 10243738, -14685461, -5066034, 16498837 }, + { 8911542, 6887158, -9584260, -6958590, 11145641, -9543680, 17303925, -14124238, 6536641, 10543906 }, + { -28946384, 15479763, -17466835, 568876, -1497683, 11223454, -2669190, -16625574, -27235709, 8876771 } + }, + { + { -25742899, -12566864, -15649966, -846607, -33026686, -796288, -33481822, 15824474, -604426, -9039817 }, + { 10330056, 70051, 7957388, -9002667, 9764902, 15609756, 27698697, -4890037, 1657394, 3084098 }, + { 10477963, -7470260, 12119566, -13250805, 29016247, -5365589, 31280319, 14396151, -30233575, 15272409 } + }, + { + { -12288309, 3169463, 28813183, 16658753, 25116432, -5630466, -25173957, -12636138, -25014757, 1950504 }, + { -26180358, 9489187, 11053416, -14746161, -31053720, 5825630, -8384306, -8767532, 15341279, 8373727 }, + { 28685821, 7759505, -14378516, -12002860, -31971820, 4079242, 298136, -10232602, -2878207, 15190420 } + }, + { + { -32932876, 13806336, -14337485, -15794431, -24004620, 10940928, 8669718, 2742393, -26033313, -6875003 }, + { -1580388, -11729417, -25979658, -11445023, -17411874, -10912854, 9291594, -16247779, -12154742, 6048605 }, + { -30305315, 14843444, 1539301, 11864366, 20201677, 1900163, 13934231, 5128323, 11213262, 9168384 } + }, + { + { -26280513, 11007847, 19408960, -940758, -18592965, -4328580, -5088060, -11105150, 20470157, -16398701 }, + { -23136053, 9282192, 14855179, -15390078, -7362815, -14408560, -22783952, 14461608, 14042978, 5230683 }, + { 29969567, -2741594, -16711867, -8552442, 9175486, -2468974, 21556951, 3506042, -5933891, -12449708 } + }, + { + { -3144746, 8744661, 19704003, 4581278, -20430686, 6830683, -21284170, 8971513, -28539189, 15326563 }, + { -19464629, 10110288, -17262528, -3503892, -23500387, 1355669, -15523050, 15300988, -20514118, 9168260 }, + { -5353335, 4488613, -23803248, 16314347, 7780487, -15638939, -28948358, 9601605, 33087103, -9011387 } + }, + { + { -19443170, -15512900, -20797467, -12445323, -29824447, 10229461, -27444329, -15000531, -5996870, 15664672 }, + { 23294591, -16632613, -22650781, -8470978, 27844204, 11461195, 13099750, -2460356, 18151676, 13417686 }, + { -24722913, -4176517, -31150679, 5988919, -26858785, 6685065, 1661597, -12551441, 15271676, -15452665 } + } +}, +{ /* 5/31 */ + { + { 11433042, -13228665, 8239631, -5279517, -1985436, -725718, -18698764, 2167544, -6921301, -13440182 }, + { -31436171, 15575146, 30436815, 12192228, -22463353, 9395379, -9917708, -8638997, 12215110, 12028277 }, + { 14098400, 6555944, 23007258, 5757252, -15427832, -12950502, 30123440, 4617780, -16900089, -655628 } + }, + { + { -4026201, -15240835, 11893168, 13718664, -14809462, 1847385, -15819999, 10154009, 23973261, -12684474 }, + { -26531820, -3695990, -1908898, 2534301, -31870557, -16550355, 18341390, -11419951, 32013174, -10103539 }, + { -25479301, 10876443, -11771086, -14625140, -12369567, 1838104, 21911214, 6354752, 4425632, -837822 } + }, + { + { -10433389, -14612966, 22229858, -3091047, -13191166, 776729, -17415375, -12020462, 4725005, 14044970 }, + { 19268650, -7304421, 1555349, 8692754, -21474059, -9910664, 6347390, -1411784, -19522291, -16109756 }, + { -24864089, 12986008, -10898878, -5558584, -11312371, -148526, 19541418, 8180106, 9282262, 10282508 } + }, + { + { -26205082, 4428547, -8661196, -13194263, 4098402, -14165257, 15522535, 8372215, 5542595, -10702683 }, + { -10562541, 14895633, 26814552, -16673850, -17480754, -2489360, -2781891, 6993761, -18093885, 10114655 }, + { -20107055, -929418, 31422704, 10427861, -7110749, 6150669, -29091755, -11529146, 25953725, -106158 } + }, + { + { -4234397, -8039292, -9119125, 3046000, 2101609, -12607294, 19390020, 6094296, -3315279, 12831125 }, + { -15998678, 7578152, 5310217, 14408357, -33548620, -224739, 31575954, 6326196, 7381791, -2421839 }, + { -20902779, 3296811, 24736065, -16328389, 18374254, 7318640, 6295303, 8082724, -15362489, 12339664 } + }, + { + { 27724736, 2291157, 6088201, -14184798, 1792727, 5857634, 13848414, 15768922, 25091167, 14856294 }, + { -18866652, 8331043, 24373479, 8541013, -701998, -9269457, 12927300, -12695493, -22182473, -9012899 }, + { -11423429, -5421590, 11632845, 3405020, 30536730, -11674039, -27260765, 13866390, 30146206, 9142070 } + }, + { + { 3924129, -15307516, -13817122, -10054960, 12291820, -668366, -27702774, 9326384, -8237858, 4171294 }, + { -15921940, 16037937, 6713787, 16606682, -21612135, 2790944, 26396185, 3731949, 345228, -5462949 }, + { -21327538, 13448259, 25284571, 1143661, 20614966, -8849387, 2031539, -12391231, -16253183, -13582083 } + }, + { + { 31016211, -16722429, 26371392, -14451233, -5027349, 14854137, 17477601, 3842657, 28012650, -16405420 }, + { -5075835, 9368966, -8562079, -4600902, -15249953, 6970560, -9189873, 16292057, -8867157, 3507940 }, + { 29439664, 3537914, 23333589, 6997794, -17555561, -11018068, -15209202, -15051267, -9164929, 6580396 } + } +}, +{ /* 6/31 */ + { + { -12185861, -7679788, 16438269, 10826160, -8696817, -6235611, 17860444, -9273846, -2095802, 9304567 }, + { 20714564, -4336911, 29088195, 7406487, 11426967, -5095705, 14792667, -14608617, 5289421, -477127 }, + { -16665533, -10650790, -6160345, -13305760, 9192020, -1802462, 17271490, 12349094, 26939669, -3752294 } + }, + { + { -12889898, 9373458, 31595848, 16374215, 21471720, 13221525, -27283495, -12348559, -3698806, 117887 }, + { 22263325, -6560050, 3984570, -11174646, -15114008, -566785, 28311253, 5358056, -23319780, 541964 }, + { 16259219, 3261970, 2309254, -15534474, -16885711, -4581916, 24134070, -16705829, -13337066, -13552195 } + }, + { + { 9378160, -13140186, -22845982, -12745264, 28198281, -7244098, -2399684, -717351, 690426, 14876244 }, + { 24977353, -314384, -8223969, -13465086, 28432343, -1176353, -13068804, -12297348, -22380984, 6618999 }, + { -1538174, 11685646, 12944378, 13682314, -24389511, -14413193, 8044829, -13817328, 32239829, -5652762 } + }, + { + { -18603066, 4762990, -926250, 8885304, -28412480, -3187315, 9781647, -10350059, 32779359, 5095274 }, + { -33008130, -5214506, -32264887, -3685216, 9460461, -9327423, -24601656, 14506724, 21639561, -2630236 }, + { -16400943, -13112215, 25239338, 15531969, 3987758, -4499318, -1289502, -6863535, 17874574, 558605 } + }, + { + { -13600129, 10240081, 9171883, 16131053, -20869254, 9599700, 33499487, 5080151, 2085892, 5119761 }, + { -22205145, -2519528, -16381601, 414691, -25019550, 2170430, 30634760, -8363614, -31999993, -5759884 }, + { -6845704, 15791202, 8550074, -1312654, 29928809, -12092256, 27534430, -7192145, -22351378, 12961482 } + }, + { + { -24492060, -9570771, 10368194, 11582341, -23397293, -2245287, 16533930, 8206996, -30194652, -5159638 }, + { -11121496, -3382234, 2307366, 6362031, -135455, 8868177, -16835630, 7031275, 7589640, 8945490 }, + { -32152748, 8917967, 6661220, -11677616, -1192060, -15793393, 7251489, -11182180, 24099109, -14456170 } + }, + { + { 5019558, -7907470, 4244127, -14714356, -26933272, 6453165, -19118182, -13289025, -6231896, -10280736 }, + { 10853594, 10721687, 26480089, 5861829, -22995819, 1972175, -1866647, -10557898, -3363451, -6441124 }, + { -17002408, 5906790, 221599, -6563147, 7828208, -13248918, 24362661, -2008168, -13866408, 7421392 } + }, + { + { 8139927, -6546497, 32257646, -5890546, 30375719, 1886181, -21175108, 15441252, 28826358, -4123029 }, + { 6267086, 9695052, 7709135, -16603597, -32869068, -1886135, 14795160, -7840124, 13746021, -1742048 }, + { 28584902, 7787108, -6732942, -15050729, 22846041, -7571236, -3181936, -363524, 4771362, -8419958 } + } +}, +{ /* 7/31 */ + { + { 24949256, 6376279, -27466481, -8174608, -18646154, -9930606, 33543569, -12141695, 3569627, 11342593 }, + { 26514989, 4740088, 27912651, 3697550, 19331575, -11472339, 6809886, 4608608, 7325975, -14801071 }, + { -11618399, -14554430, -24321212, 7655128, -1369274, 5214312, -27400540, 10258390, -17646694, -8186692 } + }, + { + { 11431204, 15823007, 26570245, 14329124, 18029990, 4796082, -31446179, 15580664, 9280358, -3973687 }, + { -160783, -10326257, -22855316, -4304997, -20861367, -13621002, -32810901, -11181622, -15545091, 4387441 }, + { -20799378, 12194512, 3937617, -5805892, -27154820, 9340370, -24513992, 8548137, 20617071, -7482001 } + }, + { + { -938825, -3930586, -8714311, 16124718, 24603125, -6225393, -13775352, -11875822, 24345683, 10325460 }, + { -19855277, -1568885, -22202708, 8714034, 14007766, 6928528, 16318175, -1010689, 4766743, 3552007 }, + { -21751364, -16730916, 1351763, -803421, -4009670, 3950935, 3217514, 14481909, 10988822, -3994762 } + }, + { + { 15564307, -14311570, 3101243, 5684148, 30446780, -8051356, 12677127, -6505343, -8295852, 13296005 }, + { -9442290, 6624296, -30298964, -11913677, -4670981, -2057379, 31521204, 9614054, -30000824, 12074674 }, + { 4771191, -135239, 14290749, -13089852, 27992298, 14998318, -1413936, -1556716, 29832613, -16391035 } + }, + { + { 7064884, -7541174, -19161962, -5067537, -18891269, -2912736, 25825242, 5293297, -27122660, 13101590 }, + { -2298563, 2439670, -7466610, 1719965, -27267541, -16328445, 32512469, -5317593, -30356070, -4190957 }, + { -30006540, 10162316, -33180176, 3981723, -16482138, -13070044, 14413974, 9515896, 19568978, 9628812 } + }, + { + { 33053803, 199357, 15894591, 1583059, 27380243, -4580435, -17838894, -6106839, -6291786, 3437740 }, + { -18978877, 3884493, 19469877, 12726490, 15913552, 13614290, -22961733, 70104, 7463304, 4176122 }, + { -27124001, 10659917, 11482427, -16070381, 12771467, -6635117, -32719404, -5322751, 24216882, 5944158 } + }, + { + { 8894125, 7450974, -2664149, -9765752, -28080517, -12389115, 19345746, 14680796, 11632993, 5847885 }, + { 26942781, -2315317, 9129564, -4906607, 26024105, 11769399, -11518837, 6367194, -9727230, 4782140 }, + { 19916461, -4828410, -22910704, -11414391, 25606324, -5972441, 33253853, 8220911, 6358847, -1873857 } + }, + { + { 801428, -2081702, 16569428, 11065167, 29875704, 96627, 7908388, -4480480, -13538503, 1387155 }, + { 19646058, 5720633, -11416706, 12814209, 11607948, 12749789, 14147075, 15156355, -21866831, 11835260 }, + { 19299512, 1155910, 28703737, 14890794, 2925026, 7269399, 26121523, 15467869, -26560550, 5052483 } + } +}, +{ /* 8/31 */ + { + { -3017432, 10058206, 1980837, 3964243, 22160966, 12322533, -6431123, -12618185, 12228557, -7003677 }, + { 32944382, 14922211, -22844894, 5188528, 21913450, -8719943, 4001465, 13238564, -6114803, 8653815 }, + { 22865569, -4652735, 27603668, -12545395, 14348958, 8234005, 24808405, 5719875, 28483275, 2841751 } + }, + { + { -16420968, -1113305, -327719, -12107856, 21886282, -15552774, -1887966, -315658, 19932058, -12739203 }, + { -11656086, 10087521, -8864888, -5536143, -19278573, -3055912, 3999228, 13239134, -4777469, -13910208 }, + { 1382174, -11694719, 17266790, 9194690, -13324356, 9720081, 20403944, 11284705, -14013818, 3093230 } + }, + { + { 16650921, -11037932, -1064178, 1570629, -8329746, 7352753, -302424, 16271225, -24049421, -6691850 }, + { -21911077, -5927941, -4611316, -5560156, -31744103, -10785293, 24123614, 15193618, -21652117, -16739389 }, + { -9935934, -4289447, -25279823, 4372842, 2087473, 10399484, 31870908, 14690798, 17361620, 11864968 } + }, + { + { -11307610, 6210372, 13206574, 5806320, -29017692, -13967200, -12331205, -7486601, -25578460, -16240689 }, + { 14668462, -12270235, 26039039, 15305210, 25515617, 4542480, 10453892, 6577524, 9145645, -6443880 }, + { 5974874, 3053895, -9433049, -10385191, -31865124, 3225009, -7972642, 3936128, -5652273, -3050304 } + }, + { + { 30625386, -4729400, -25555961, -12792866, -20484575, 7695099, 17097188, -16303496, -27999779, 1803632 }, + { -3553091, 9865099, -5228566, 4272701, -5673832, -16689700, 14911344, 12196514, -21405489, 7047412 }, + { 20093277, 9920966, -11138194, -5343857, 13161587, 12044805, -32856851, 4124601, -32343828, -10257566 } + }, + { + { -20788824, 14084654, -13531713, 7842147, 19119038, -13822605, 4752377, -8714640, -21679658, 2288038 }, + { -26819236, -3283715, 29965059, 3039786, -14473765, 2540457, 29457502, 14625692, -24819617, 12570232 }, + { -1063558, -11551823, 16920318, 12494842, 1278292, -5869109, -21159943, -3498680, -11974704, 4724943 } + }, + { + { 17960970, -11775534, -4140968, -9702530, -8876562, -1410617, -12907383, -8659932, -29576300, 1903856 }, + { 23134274, -14279132, -10681997, -1611936, 20684485, 15770816, -12989750, 3190296, 26955097, 14109738 }, + { 15308788, 5320727, -30113809, -14318877, 22902008, 7767164, 29425325, -11277562, 31960942, 11934971 } + }, + { + { -27395711, 8435796, 4109644, 12222639, -24627868, 14818669, 20638173, 4875028, 10491392, 1379718 }, + { -13159415, 9197841, 3875503, -8936108, -1383712, -5879801, 33518459, 16176658, 21432314, 12180697 }, + { -11787308, 11500838, 13787581, -13832590, -22430679, 10140205, 1465425, 12689540, -10301319, -13872883 } + } +}, +{ /* 9/31 */ + { + { 5414091, -15386041, -21007664, 9643570, 12834970, 1186149, -2622916, -1342231, 26128231, 6032912 }, + { -26337395, -13766162, 32496025, -13653919, 17847801, -12669156, 3604025, 8316894, -25875034, -10437358 }, + { 3296484, 6223048, 24680646, -12246460, -23052020, 5903205, -8862297, -4639164, 12376617, 3188849 } + }, + { + { 29190488, -14659046, 27549113, -1183516, 3520066, -10697301, 32049515, -7309113, -16109234, -9852307 }, + { -14744486, -9309156, 735818, -598978, -20407687, -5057904, 25246078, -15795669, 18640741, -960977 }, + { -6928835, -16430795, 10361374, 5642961, 4910474, 12345252, -31638386, -494430, 10530747, 1053335 } + }, + { + { -29265967, -14186805, -13538216, -12117373, -19457059, -10655384, -31462369, -2948985, 24018831, 15026644 }, + { -22592535, -3145277, -2289276, 5953843, -13440189, 9425631, 25310643, 13003497, -2314791, -15145616 }, + { -27419985, -603321, -8043984, -1669117, -26092265, 13987819, -27297622, 187899, -23166419, -2531735 } + }, + { + { -21744398, -13810475, 1844840, 5021428, -10434399, -15911473, 9716667, 16266922, -5070217, 726099 }, + { 29370922, -6053998, 7334071, -15342259, 9385287, 2247707, -13661962, -4839461, 30007388, -15823341 }, + { -936379, 16086691, 23751945, -543318, -1167538, -5189036, 9137109, 730663, 9835848, 4555336 } + }, + { + { -23376435, 1410446, -22253753, -12899614, 30867635, 15826977, 17693930, 544696, -11985298, 12422646 }, + { 31117226, -12215734, -13502838, 6561947, -9876867, -12757670, -5118685, -4096706, 29120153, 13924425 }, + { -17400879, -14233209, 19675799, -2734756, -11006962, -5858820, -9383939, -11317700, 7240931, -237388 } + }, + { + { -31361739, -11346780, -15007447, -5856218, -22453340, -12152771, 1222336, 4389483, 3293637, -15551743 }, + { -16684801, -14444245, 11038544, 11054958, -13801175, -3338533, -24319580, 7733547, 12796905, -6335822 }, + { -8759414, -10817836, -25418864, 10783769, -30615557, -9746811, -28253339, 3647836, 3222231, -11160462 } + }, + { + { 18606113, 1693100, -25448386, -15170272, 4112353, 10045021, 23603893, -2048234, -7550776, 2484985 }, + { 9255317, -3131197, -12156162, -1004256, 13098013, -9214866, 16377220, -2102812, -19802075, -3034702 }, + { -22729289, 7496160, -5742199, 11329249, 19991973, -3347502, -31718148, 9936966, -30097688, -10618797 } + }, + { + { 21878590, -5001297, 4338336, 13643897, -3036865, 13160960, 19708896, 5415497, -7360503, -4109293 }, + { 27736861, 10103576, 12500508, 8502413, -3413016, -9633558, 10436918, -1550276, -23659143, -8132100 }, + { 19492550, -12104365, -29681976, -852630, -3208171, 12403437, 30066266, 8367329, 13243957, 8709688 } + } +}, +{ /* 10/31 */ + { + { 12015105, 2801261, 28198131, 10151021, 24818120, -4743133, -11194191, -5645734, 5150968, 7274186 }, + { 2831366, -12492146, 1478975, 6122054, 23825128, -12733586, 31097299, 6083058, 31021603, -9793610 }, + { -2529932, -2229646, 445613, 10720828, -13849527, -11505937, -23507731, 16354465, 15067285, -14147707 } + }, + { + { 7840942, 14037873, -33364863, 15934016, -728213, -3642706, 21403988, 1057586, -19379462, -12403220 }, + { 915865, -16469274, 15608285, -8789130, -24357026, 6060030, -17371319, 8410997, -7220461, 16527025 }, + { 32922597, -556987, 20336074, -16184568, 10903705, -5384487, 16957574, 52992, 23834301, 6588044 } + }, + { + { 32752030, 11232950, 3381995, -8714866, 22652988, -10744103, 17159699, 16689107, -20314580, -1305992 }, + { -4689649, 9166776, -25710296, -10847306, 11576752, 12733943, 7924251, -2752281, 1976123, -7249027 }, + { 21251222, 16309901, -2983015, -6783122, 30810597, 12967303, 156041, -3371252, 12331345, -8237197 } + }, + { + { 8651614, -4477032, -16085636, -4996994, 13002507, 2950805, 29054427, -5106970, 10008136, -4667901 }, + { 31486080, 15114593, -14261250, 12951354, 14369431, -7387845, 16347321, -13662089, 8684155, -10532952 }, + { 19443825, 11385320, 24468943, -9659068, -23919258, 2187569, -26263207, -6086921, 31316348, 14219878 } + }, + { + { -28594490, 1193785, 32245219, 11392485, 31092169, 15722801, 27146014, 6992409, 29126555, 9207390 }, + { 32382935, 1110093, 18477781, 11028262, -27411763, -7548111, -4980517, 10843782, -7957600, -14435730 }, + { 2814918, 7836403, 27519878, -7868156, -20894015, -11553689, -21494559, 8550130, 28346258, 1994730 } + }, + { + { -19578299, 8085545, -14000519, -3948622, 2785838, -16231307, -19516951, 7174894, 22628102, 8115180 }, + { -30405132, 955511, -11133838, -15078069, -32447087, -13278079, -25651578, 3317160, -9943017, 930272 }, + { -15303681, -6833769, 28856490, 1357446, 23421993, 1057177, 24091212, -1388970, -22765376, -10650715 } + }, + { + { -22751231, -5303997, -12907607, -12768866, -15811511, -7797053, -14839018, -16554220, -1867018, 8398970 }, + { -31969310, 2106403, -4736360, 1362501, 12813763, 16200670, 22981545, -6291273, 18009408, -15772772 }, + { -17220923, -9545221, -27784654, 14166835, 29815394, 7444469, 29551787, -3727419, 19288549, 1325865 } + }, + { + { 15100157, -15835752, -23923978, -1005098, -26450192, 15509408, 12376730, -3479146, 33166107, -8042750 }, + { 20909231, 13023121, -9209752, 16251778, -5778415, -8094914, 12412151, 10018715, 2213263, -13878373 }, + { 32529814, -11074689, 30361439, -16689753, -9135940, 1513226, 22922121, 6382134, -5766928, 8371348 } + } +}, +{ /* 11/31 */ + { + { 9923462, 11271500, 12616794, 3544722, -29998368, -1721626, 12891687, -8193132, -26442943, 10486144 }, + { -22597207, -7012665, 8587003, -8257861, 4084309, -12970062, 361726, 2610596, -23921530, -11455195 }, + { 5408411, -1136691, -4969122, 10561668, 24145918, 14240566, 31319731, -4235541, 19985175, -3436086 } + }, + { + { -13994457, 16616821, 14549246, 3341099, 32155958, 13648976, -17577068, 8849297, 65030, 8370684 }, + { -8320926, -12049626, 31204563, 5839400, -20627288, -1057277, -19442942, 6922164, 12743482, -9800518 }, + { -2361371, 12678785, 28815050, 4759974, -23893047, 4884717, 23783145, 11038569, 18800704, 255233 } + }, + { + { -5269658, -1773886, 13957886, 7990715, 23132995, 728773, 13393847, 9066957, 19258688, -14753793 }, + { -2936654, -10827535, -10432089, 14516793, -3640786, 4372541, -31934921, 2209390, -1524053, 2055794 }, + { 580882, 16705327, 5468415, -2683018, -30926419, -14696000, -7203346, -8994389, -30021019, 7394435 } + }, + { + { 23838809, 1822728, -15738443, 15242727, 8318092, -3733104, -21672180, -3492205, -4821741, 14799921 }, + { 13345610, 9759151, 3371034, -16137791, 16353039, 8577942, 31129804, 13496856, -9056018, 7402518 }, + { 2286874, -4435931, -20042458, -2008336, -13696227, 5038122, 11006906, -15760352, 8205061, 1607563 } + }, + { + { 14414086, -8002132, 3331830, -3208217, 22249151, -5594188, 18364661, -2906958, 30019587, -9029278 }, + { -27688051, 1585953, -10775053, 931069, -29120221, -11002319, -14410829, 12029093, 9944378, 8024 }, + { 4368715, -3709630, 29874200, -15022983, -20230386, -11410704, -16114594, -999085, -8142388, 5640030 } + }, + { + { 10299610, 13746483, 11661824, 16234854, 7630238, 5998374, 9809887, -16694564, 15219798, -14327783 }, + { 27425505, -5719081, 3055006, 10660664, 23458024, 595578, -15398605, -1173195, -18342183, 9742717 }, + { 6744077, 2427284, 26042789, 2720740, -847906, 1118974, 32324614, 7406442, 12420155, 1994844 } + }, + { + { 14012521, -5024720, -18384453, -9578469, -26485342, -3936439, -13033478, -10909803, 24319929, -6446333 }, + { 16412690, -4507367, 10772641, 15929391, -17068788, -4658621, 10555945, -10484049, -30102368, -4739048 }, + { 22397382, -7767684, -9293161, -12792868, 17166287, -9755136, -27333065, 6199366, 21880021, -12250760 } + }, + { + { -4283307, 5368523, -31117018, 8163389, -30323063, 3209128, 16557151, 8890729, 8840445, 4957760 }, + { -15447727, 709327, -6919446, -10870178, -29777922, 6522332, -21720181, 12130072, -14796503, 5005757 }, + { -2114751, -14308128, 23019042, 15765735, -25269683, 6002752, 10183197, -13239326, -16395286, -2176112 } + } +}, +{ /* 12/31 */ + { + { -19025756, 1632005, 13466291, -7995100, -23640451, 16573537, -32013908, -3057104, 22208662, 2000468 }, + { 3065073, -1412761, -25598674, -361432, -17683065, -5703415, -8164212, 11248527, -3691214, -7414184 }, + { 10379208, -6045554, 8877319, 1473647, -29291284, -12507580, 16690915, 2553332, -3132688, 16400289 } + }, + { + { 15716668, 1254266, -18472690, 7446274, -8448918, 6344164, -22097271, -7285580, 26894937, 9132066 }, + { 24158887, 12938817, 11085297, -8177598, -28063478, -4457083, -30576463, 64452, -6817084, -2692882 }, + { 13488534, 7794716, 22236231, 5989356, 25426474, -12578208, 2350710, -3418511, -4688006, 2364226 } + }, + { + { 16335052, 9132434, 25640582, 6678888, 1725628, 8517937, -11807024, -11697457, 15445875, -7798101 }, + { 29004207, -7867081, 28661402, -640412, -12794003, -7943086, 31863255, -4135540, -278050, -15759279 }, + { -6122061, -14866665, -28614905, 14569919, -10857999, -3591829, 10343412, -6976290, -29828287, -10815811 } + }, + { + { 27081650, 3463984, 14099042, -4517604, 1616303, -6205604, 29542636, 15372179, 17293797, 960709 }, + { 20263915, 11434237, -5765435, 11236810, 13505955, -10857102, -16111345, 6493122, -19384511, 7639714 }, + { -2830798, -14839232, 25403038, -8215196, -8317012, -16173699, 18006287, -16043750, 29994677, -15808121 } + }, + { + { 9769828, 5202651, -24157398, -13631392, -28051003, -11561624, -24613141, -13860782, -31184575, 709464 }, + { 12286395, 13076066, -21775189, -1176622, -25003198, 4057652, -32018128, -8890874, 16102007, 13205847 }, + { 13733362, 5599946, 10557076, 3195751, -5557991, 8536970, -25540170, 8525972, 10151379, 10394400 } + }, + { + { 4024660, -16137551, 22436262, 12276534, -9099015, -2686099, 19698229, 11743039, -33302334, 8934414 }, + { -15879800, -4525240, -8580747, -2934061, 14634845, -698278, -9449077, 3137094, -11536886, 11721158 }, + { 17555939, -5013938, 8268606, 2331751, -22738815, 9761013, 9319229, 8835153, -9205489, -1280045 } + }, + { + { -461409, -7830014, 20614118, 16688288, -7514766, -4807119, 22300304, 505429, 6108462, -6183415 }, + { -5070281, 12367917, -30663534, 3234473, 32617080, -8422642, 29880583, -13483331, -26898490, -7867459 }, + { -31975283, 5726539, 26934134, 10237677, -3173717, -605053, 24199304, 3795095, 7592688, -14992079 } + }, + { + { 21594432, -14964228, 17466408, -4077222, 32537084, 2739898, 6407723, 12018833, -28256052, 4298412 }, + { -20650503, -11961496, -27236275, 570498, 3767144, -1717540, 13891942, -1569194, 13717174, 10805743 }, + { -14676630, -15644296, 15287174, 11927123, 24177847, -8175568, -796431, 14860609, -26938930, -5863836 } + } +}, +{ /* 13/31 */ + { + { 12962541, 5311799, -10060768, 11658280, 18855286, -7954201, 13286263, -12808704, -4381056, 9882022 }, + { 18512079, 11319350, -20123124, 15090309, 18818594, 5271736, -22727904, 3666879, -23967430, -3299429 }, + { -6789020, -3146043, 16192429, 13241070, 15898607, -14206114, -10084880, -6661110, -2403099, 5276065 } + }, + { + { 30169808, -5317648, 26306206, -11750859, 27814964, 7069267, 7152851, 3684982, 1449224, 13082861 }, + { 10342826, 3098505, 2119311, 193222, 25702612, 12233820, 23697382, 15056736, -21016438, -8202000 }, + { -33150110, 3261608, 22745853, 7948688, 19370557, -15177665, -26171976, 6482814, -10300080, -11060101 } + }, + { + { 32869458, -5408545, 25609743, 15678670, -10687769, -15471071, 26112421, 2521008, -22664288, 6904815 }, + { 29506923, 4457497, 3377935, -9796444, -30510046, 12935080, 1561737, 3841096, -29003639, -6657642 }, + { 10340844, -6630377, -18656632, -2278430, 12621151, -13339055, 30878497, -11824370, -25584551, 5181966 } + }, + { + { 25940115, -12658025, 17324188, -10307374, -8671468, 15029094, 24396252, -16450922, -2322852, -12388574 }, + { -21765684, 9916823, -1300409, 4079498, -1028346, 11909559, 1782390, 12641087, 20603771, -6561742 }, + { -18882287, -11673380, 24849422, 11501709, 13161720, -4768874, 1925523, 11914390, 4662781, 7820689 } + }, + { + { 12241050, -425982, 8132691, 9393934, 32846760, -1599620, 29749456, 12172924, 16136752, 15264020 }, + { -10349955, -14680563, -8211979, 2330220, -17662549, -14545780, 10658213, 6671822, 19012087, 3772772 }, + { 3753511, -3421066, 10617074, 2028709, 14841030, -6721664, 28718732, -15762884, 20527771, 12988982 } + }, + { + { -14822485, -5797269, -3707987, 12689773, -898983, -10914866, -24183046, -10564943, 3299665, -12424953 }, + { -16777703, -15253301, -9642417, 4978983, 3308785, 8755439, 6943197, 6461331, -25583147, 8991218 }, + { -17226263, 1816362, -1673288, -6086439, 31783888, -8175991, -32948145, 7417950, -30242287, 1507265 } + }, + { + { 29692663, 6829891, -10498800, 4334896, 20945975, -11906496, -28887608, 8209391, 14606362, -10647073 }, + { -3481570, 8707081, 32188102, 5672294, 22096700, 1711240, -33020695, 9761487, 4170404, -2085325 }, + { -11587470, 14855945, -4127778, -1531857, -26649089, 15084046, 22186522, 16002000, -14276837, -8400798 } + }, + { + { -4811456, 13761029, -31703877, -2483919, -3312471, 7869047, -7113572, -9620092, 13240845, 10965870 }, + { -7742563, -8256762, -14768334, -13656260, -23232383, 12387166, 4498947, 14147411, 29514390, 4302863 }, + { -13413405, -12407859, 20757302, -13801832, 14785143, 8976368, -5061276, -2144373, 17846988, -13971927 } + } +}, +{ /* 14/31 */ + { + { -2244452, -754728, -4597030, -1066309, -6247172, 1455299, -21647728, -9214789, -5222701, 12650267 }, + { -9906797, -16070310, 21134160, 12198166, -27064575, 708126, 387813, 13770293, -19134326, 10958663 }, + { 22470984, 12369526, 23446014, -5441109, -21520802, -9698723, -11772496, -11574455, -25083830, 4271862 } + }, + { + { -25169565, -10053642, -19909332, 15361595, -5984358, 2159192, 75375, -4278529, -32526221, 8469673 }, + { 15854970, 4148314, -8893890, 7259002, 11666551, 13824734, -30531198, 2697372, 24154791, -9460943 }, + { 15446137, -15806644, 29759747, 14019369, 30811221, -9610191, -31582008, 12840104, 24913809, 9815020 } + }, + { + { -4709286, -5614269, -31841498, -12288893, -14443537, 10799414, -9103676, 13438769, 18735128, 9466238 }, + { 11933045, 9281483, 5081055, -5183824, -2628162, -4905629, -7727821, -10896103, -22728655, 16199064 }, + { 14576810, 379472, -26786533, -8317236, -29426508, -10812974, -102766, 1876699, 30801119, 2164795 } + }, + { + { 15995086, 3199873, 13672555, 13712240, -19378835, -4647646, -13081610, -15496269, -13492807, 1268052 }, + { -10290614, -3659039, -3286592, 10948818, 23037027, 3794475, -3470338, -12600221, -17055369, 3565904 }, + { 29210088, -9419337, -5919792, -4952785, 10834811, -13327726, -16512102, -10820713, -27162222, -14030531 } + }, + { + { -13161890, 15508588, 16663704, -8156150, -28349942, 9019123, -29183421, -3769423, 2244111, -14001979 }, + { -5152875, -3800936, -9306475, -6071583, 16243069, 14684434, -25673088, -16180800, 13491506, 4641841 }, + { 10813417, 643330, -19188515, -728916, 30292062, -16600078, 27548447, -7721242, 14476989, -12767431 } + }, + { + { 10292079, 9984945, 6481436, 8279905, -7251514, 7032743, 27282937, -1644259, -27912810, 12651324 }, + { -31185513, -813383, 22271204, 11835308, 10201545, 15351028, 17099662, 3988035, 21721536, -3148940 }, + { 10202177, -6545839, -31373232, -9574638, -32150642, -8119683, -12906320, 3852694, 13216206, 14842320 } + }, + { + { -15815640, -10601066, -6538952, -7258995, -6984659, -6581778, -31500847, 13765824, -27434397, 9900184 }, + { 14465505, -13833331, -32133984, -14738873, -27443187, 12990492, 33046193, 15796406, -7051866, -8040114 }, + { 30924417, -8279620, 6359016, -12816335, 16508377, 9071735, -25488601, 15413635, 9524356, -7018878 } + }, + { + { 12274201, -13175547, 32627641, -1785326, 6736625, 13267305, 5237659, -5109483, 15663516, 4035784 }, + { -2951309, 8903985, 17349946, 601635, -16432815, -4612556, -13732739, -15889334, -22258478, 4659091 }, + { -16916263, -4952973, -30393711, -15158821, 20774812, 15897498, 5736189, 15026997, -2178256, -13455585 } + } +}, +{ /* 15/31 */ + { + { -8858980, -2219056, 28571666, -10155518, -474467, -10105698, -3801496, 278095, 23440562, -290208 }, + { 10226241, -5928702, 15139956, 120818, -14867693, 5218603, 32937275, 11551483, -16571960, -7442864 }, + { 17932739, -12437276, -24039557, 10749060, 11316803, 7535897, 22503767, 5561594, -3646624, 3898661 } + }, + { + { 7749907, -969567, -16339731, -16464, -25018111, 15122143, -1573531, 7152530, 21831162, 1245233 }, + { 26958459, -14658026, 4314586, 8346991, -5677764, 11960072, -32589295, -620035, -30402091, -16716212 }, + { -12165896, 9166947, 33491384, 13673479, 29787085, 13096535, 6280834, 14587357, -22338025, 13987525 } + }, + { + { -24349909, 7778775, 21116000, 15572597, -4833266, -5357778, -4300898, -5124639, -7469781, -2858068 }, + { 9681908, -6737123, -31951644, 13591838, -6883821, 386950, 31622781, 6439245, -14581012, 4091397 }, + { -8426427, 1470727, -28109679, -1596990, 3978627, -5123623, -19622683, 12092163, 29077877, -14741988 } + }, + { + { 5269168, -6859726, -13230211, -8020715, 25932563, 1763552, -5606110, -5505881, -20017847, 2357889 }, + { 32264008, -15407652, -5387735, -1160093, -2091322, -3946900, 23104804, -12869908, 5727338, 189038 }, + { 14609123, -8954470, -6000566, -16622781, -14577387, -7743898, -26745169, 10942115, -25888931, -14884697 } + }, + { + { 20513500, 5557931, -15604613, 7829531, 26413943, -2019404, -21378968, 7471781, 13913677, -5137875 }, + { -25574376, 11967826, 29233242, 12948236, -6754465, 4713227, -8940970, 14059180, 12878652, 8511905 }, + { -25656801, 3393631, -2955415, -7075526, -2250709, 9366908, -30223418, 6812974, 5568676, -3127656 } + }, + { + { 11630004, 12144454, 2116339, 13606037, 27378885, 15676917, -17408753, -13504373, -14395196, 8070818 }, + { 27117696, -10007378, -31282771, -5570088, 1127282, 12772488, -29845906, 10483306, -11552749, -1028714 }, + { 10637467, -5688064, 5674781, 1072708, -26343588, -6982302, -1683975, 9177853, -27493162, 15431203 } + }, + { + { 20525145, 10892566, -12742472, 12779443, -29493034, 16150075, -28240519, 14943142, -15056790, -7935931 }, + { -30024462, 5626926, -551567, -9981087, 753598, 11981191, 25244767, -3239766, -3356550, 9594024 }, + { -23752644, 2636870, -5163910, -10103818, 585134, 7877383, 11345683, -6492290, 13352335, -10977084 } + }, + { + { -1931799, -5407458, 3304649, -12884869, 17015806, -4877091, -29783850, -7752482, -13215537, -319204 }, + { 20239939, 6607058, 6203985, 3483793, -18386976, -779229, -20723742, 15077870, -22750759, 14523817 }, + { 27406042, -6041657, 27423596, -4497394, 4996214, 10002360, -28842031, -4545494, -30172742, -4805667 } + } +}, +{ /* 16/31 */ + { + { 11374242, 12660715, 17861383, -12540833, 10935568, 1099227, -13886076, -9091740, -27727044, 11358504 }, + { -12730809, 10311867, 1510375, 10778093, -2119455, -9145702, 32676003, 11149336, -26123651, 4985768 }, + { -19096303, 341147, -6197485, -239033, 15756973, -8796662, -983043, 13794114, -19414307, -15621255 } + }, + { + { 6490081, 11940286, 25495923, -7726360, 8668373, -8751316, 3367603, 6970005, -1691065, -9004790 }, + { 1656497, 13457317, 15370807, 6364910, 13605745, 8362338, -19174622, -5475723, -16796596, -5031438 }, + { -22273315, -13524424, -64685, -4334223, -18605636, -10921968, -20571065, -7007978, -99853, -10237333 } + }, + { + { 17747465, 10039260, 19368299, -4050591, -20630635, -16041286, 31992683, -15857976, -29260363, -5511971 }, + { 31932027, -4986141, -19612382, 16366580, 22023614, 88450, 11371999, -3744247, 4882242, -10626905 }, + { 29796507, 37186, 19818052, 10115756, -11829032, 3352736, 18551198, 3272828, -5190932, -4162409 } + }, + { + { 12501286, 4044383, -8612957, -13392385, -32430052, 5136599, -19230378, -3529697, 330070, -3659409 }, + { 6384877, 2899513, 17807477, 7663917, -2358888, 12363165, 25366522, -8573892, -271295, 12071499 }, + { -8365515, -4042521, 25133448, -4517355, -6211027, 2265927, -32769618, 1936675, -5159697, 3829363 } + }, + { + { 28425966, -5835433, -577090, -4697198, -14217555, 6870930, 7921550, -6567787, 26333140, 14267664 }, + { -11067219, 11871231, 27385719, -10559544, -4585914, -11189312, 10004786, -8709488, -21761224, 8930324 }, + { -21197785, -16396035, 25654216, -1725397, 12282012, 11008919, 1541940, 4757911, -26491501, -16408940 } + }, + { + { 13537262, -7759490, -20604840, 10961927, -5922820, -13218065, -13156584, 6217254, -15943699, 13814990 }, + { -17422573, 15157790, 18705543, 29619, 24409717, -260476, 27361681, 9257833, -1956526, -1776914 }, + { -25045300, -10191966, 15366585, 15166509, -13105086, 8423556, -29171540, 12361135, -18685978, 4578290 } + }, + { + { 24579768, 3711570, 1342322, -11180126, -27005135, 14124956, -22544529, 14074919, 21964432, 8235257 }, + { -6528613, -2411497, 9442966, -5925588, 12025640, -1487420, -2981514, -1669206, 13006806, 2355433 }, + { -16304899, -13605259, -6632427, -5142349, 16974359, -10911083, 27202044, 1719366, 1141648, -12796236 } + }, + { + { -12863944, -13219986, -8318266, -11018091, -6810145, -4843894, 13475066, -3133972, 32674895, 13715045 }, + { 11423335, -5468059, 32344216, 8962751, 24989809, 9241752, -13265253, 16086212, -28740881, -15642093 }, + { -1409668, 12530728, -6368726, 10847387, 19531186, -14132160, -11709148, 7791794, -27245943, 4383347 } + } +}, +{ /* 17/31 */ + { + { -28970898, 5271447, -1266009, -9736989, -12455236, 16732599, -4862407, -4906449, 27193557, 6245191 }, + { -15193956, 5362278, -1783893, 2695834, 4960227, 12840725, 23061898, 3260492, 22510453, 8577507 }, + { -12632451, 11257346, -32692994, 13548177, -721004, 10879011, 31168030, 13952092, -29571492, -3635906 } + }, + { + { 3877321, -9572739, 32416692, 5405324, -11004407, -13656635, 3759769, 11935320, 5611860, 8164018 }, + { -16275802, 14667797, 15906460, 12155291, -22111149, -9039718, 32003002, -8832289, 5773085, -8422109 }, + { -23788118, -8254300, 1950875, 8937633, 18686727, 16459170, -905725, 12376320, 31632953, 190926 } + }, + { + { -24593607, -16138885, -8423991, 13378746, 14162407, 6901328, -8288749, 4508564, -25341555, -3627528 }, + { 8884438, -5884009, 6023974, 10104341, -6881569, -4941533, 18722941, -14786005, -1672488, 827625 }, + { -32720583, -16289296, -32503547, 7101210, 13354605, 2659080, -1800575, -14108036, -24878478, 1541286 } + }, + { + { 2901347, -1117687, 3880376, -10059388, -17620940, -3612781, -21802117, -3567481, 20456845, -1885033 }, + { 27019610, 12299467, -13658288, -1603234, -12861660, -4861471, -19540150, -5016058, 29439641, 15138866 }, + { 21536104, -6626420, -32447818, -10690208, -22408077, 5175814, -5420040, -16361163, 7779328, 109896 } + }, + { + { 30279744, 14648750, -8044871, 6425558, 13639621, -743509, 28698390, 12180118, 23177719, -554075 }, + { 26572847, 3405927, -31701700, 12890905, -19265668, 5335866, -6493768, 2378492, 4439158, -13279347 }, + { -22716706, 3489070, -9225266, -332753, 18875722, -1140095, 14819434, -12731527, -17717757, -5461437 } + }, + { + { -5056483, 16566551, 15953661, 3767752, -10436499, 15627060, -820954, 2177225, 8550082, -15114165 }, + { -18473302, 16596775, -381660, 15663611, 22860960, 15585581, -27844109, -3582739, -23260460, -8428588 }, + { -32480551, 15707275, -8205912, -5652081, 29464558, 2713815, -22725137, 15860482, -21902570, 1494193 } + }, + { + { -19562091, -14087393, -25583872, -9299552, 13127842, 759709, 21923482, 16529112, 8742704, 12967017 }, + { -28464899, 1553205, 32536856, -10473729, -24691605, -406174, -8914625, -2933896, -29903758, 15553883 }, + { 21877909, 3230008, 9881174, 10539357, -4797115, 2841332, 11543572, 14513274, 19375923, -12647961 } + }, + { + { 8832269, -14495485, 13253511, 5137575, 5037871, 4078777, 24880818, -6222716, 2862653, 9455043 }, + { 29306751, 5123106, 20245049, -14149889, 9592566, 8447059, -2077124, -2990080, 15511449, 4789663 }, + { -20679756, 7004547, 8824831, -9434977, -4045704, -3750736, -5754762, 108893, 23513200, 16652362 } + } +}, +{ /* 18/31 */ + { + { -33256173, 4144782, -4476029, -6579123, 10770039, -7155542, -6650416, -12936300, -18319198, 10212860 }, + { 2756081, 8598110, 7383731, -6859892, 22312759, -1105012, 21179801, 2600940, -9988298, -12506466 }, + { -24645692, 13317462, -30449259, -15653928, 21365574, -10869657, 11344424, 864440, -2499677, -16710063 } + }, + { + { -26432803, 6148329, -17184412, -14474154, 18782929, -275997, -22561534, 211300, 2719757, 4940997 }, + { -1323882, 3911313, -6948744, 14759765, -30027150, 7851207, 21690126, 8518463, 26699843, 5276295 }, + { -13149873, -6429067, 9396249, 365013, 24703301, -10488939, 1321586, 149635, -15452774, 7159369 } + }, + { + { 9987780, -3404759, 17507962, 9505530, 9731535, -2165514, 22356009, 8312176, 22477218, -8403385 }, + { 18155857, -16504990, 19744716, 9006923, 15154154, -10538976, 24256460, -4864995, -22548173, 9334109 }, + { 2986088, -4911893, 10776628, -3473844, 10620590, -7083203, -21413845, 14253545, -22587149, 536906 } + }, + { + { 4377756, 8115836, 24567078, 15495314, 11625074, 13064599, 7390551, 10589625, 10838060, -15420424 }, + { -19342404, 867880, 9277171, -3218459, -14431572, -1986443, 19295826, -15796950, 6378260, 699185 }, + { 7895026, 4057113, -7081772, -13077756, -17886831, -323126, -716039, 15693155, -5045064, -13373962 } + }, + { + { -7737563, -5869402, -14566319, -7406919, 11385654, 13201616, 31730678, -10962840, -3918636, -9669325 }, + { 10188286, -15770834, -7336361, 13427543, 22223443, 14896287, 30743455, 7116568, -21786507, 5427593 }, + { 696102, 13206899, 27047647, -10632082, 15285305, -9853179, 10798490, -4578720, 19236243, 12477404 } + }, + { + { -11229439, 11243796, -17054270, -8040865, -788228, -8167967, -3897669, 11180504, -23169516, 7733644 }, + { 17800790, -14036179, -27000429, -11766671, 23887827, 3149671, 23466177, -10538171, 10322027, 15313801 }, + { 26246234, 11968874, 32263343, -5468728, 6830755, -13323031, -15794704, -101982, -24449242, 10890804 } + }, + { + { -31365647, 10271363, -12660625, -6267268, 16690207, -13062544, -14982212, 16484931, 25180797, -5334884 }, + { -586574, 10376444, -32586414, -11286356, 19801893, 10997610, 2276632, 9482883, 316878, 13820577 }, + { -9882808, -4510367, -2115506, 16457136, -11100081, 11674996, 30756178, -7515054, 30696930, -3712849 } + }, + { + { 32988917, -9603412, 12499366, 7910787, -10617257, -11931514, -7342816, -9985397, -32349517, 7392473 }, + { -8855661, 15927861, 9866406, -3649411, -2396914, -16655781, -30409476, -9134995, 25112947, -2926644 }, + { -2504044, -436966, 25621774, -5678772, 15085042, -5479877, -24884878, -13526194, 5537438, -13914319 } + } +}, +{ /* 19/31 */ + { + { -11225584, 2320285, -9584280, 10149187, -33444663, 5808648, -14876251, -1729667, 31234590, 6090599 }, + { -9633316, 116426, 26083934, 2897444, -6364437, -2688086, 609721, 15878753, -6970405, -9034768 }, + { -27757857, 247744, -15194774, -9002551, 23288161, -10011936, -23869595, 6503646, 20650474, 1804084 } + }, + { + { -27589786, 15456424, 8972517, 8469608, 15640622, 4439847, 3121995, -10329713, 27842616, -202328 }, + { -15306973, 2839644, 22530074, 10026331, 4602058, 5048462, 28248656, 5031932, -11375082, 12714369 }, + { 20807691, -7270825, 29286141, 11421711, -27876523, -13868230, -21227475, 1035546, -19733229, 12796920 } + }, + { + { 12076899, -14301286, -8785001, -11848922, -25012791, 16400684, -17591495, -12899438, 3480665, -15182815 }, + { -32361549, 5457597, 28548107, 7833186, 7303070, -11953545, -24363064, -15921875, -33374054, 2771025 }, + { -21389266, 421932, 26597266, 6860826, 22486084, -6737172, -17137485, -4210226, -24552282, 15673397 } + }, + { + { -20184622, 2338216, 19788685, -9620956, -4001265, -8740893, -20271184, 4733254, 3727144, -12934448 }, + { 6120119, 814863, -11794402, -622716, 6812205, -15747771, 2019594, 7975683, 31123697, -10958981 }, + { 30069250, -11435332, 30434654, 2958439, 18399564, -976289, 12296869, 9204260, -16432438, 9648165 } + }, + { + { 32705432, -1550977, 30705658, 7451065, -11805606, 9631813, 3305266, 5248604, -26008332, -11377501 }, + { 17219865, 2375039, -31570947, -5575615, -19459679, 9219903, 294711, 15298639, 2662509, -16297073 }, + { -1172927, -7558695, -4366770, -4287744, -21346413, -8434326, 32087529, -1222777, 32247248, -14389861 } + }, + { + { 14312628, 1221556, 17395390, -8700143, -4945741, -8684635, -28197744, -9637817, -16027623, -13378845 }, + { -1428825, -9678990, -9235681, 6549687, -7383069, -468664, 23046502, 9803137, 17597934, 2346211 }, + { 18510800, 15337574, 26171504, 981392, -22241552, 7827556, -23491134, -11323352, 3059833, -11782870 } + }, + { + { 10141598, 6082907, 17829293, -1947643, 9830092, 13613136, -25556636, -5544586, -33502212, 3592096 }, + { 33114168, -15889352, -26525686, -13343397, 33076705, 8716171, 1151462, 1521897, -982665, -6837803 }, + { -32939165, -4255815, 23947181, -324178, -33072974, -12305637, -16637686, 3891704, 26353178, 693168 } + }, + { + { 30374239, 1595580, -16884039, 13186931, 4600344, 406904, 9585294, -400668, 31375464, 14369965 }, + { -14370654, -7772529, 1510301, 6434173, -18784789, -6262728, 32732230, -13108839, 17901441, 16011505 }, + { 18171223, -11934626, -12500402, 15197122, -11038147, -15230035, -19172240, -16046376, 8764035, 12309598 } + } +}, +{ /* 20/31 */ + { + { 5975908, -5243188, -19459362, -9681747, -11541277, 14015782, -23665757, 1228319, 17544096, -10593782 }, + { 5811932, -1715293, 3442887, -2269310, -18367348, -8359541, -18044043, -15410127, -5565381, 12348900 }, + { -31399660, 11407555, 25755363, 6891399, -3256938, 14872274, -24849353, 8141295, -10632534, -585479 } + }, + { + { -12675304, 694026, -5076145, 13300344, 14015258, -14451394, -9698672, -11329050, 30944593, 1130208 }, + { 8247766, -6710942, -26562381, -7709309, -14401939, -14648910, 4652152, 2488540, 23550156, -271232 }, + { 17294316, -3788438, 7026748, 15626851, 22990044, 113481, 2267737, -5908146, -408818, -137719 } + }, + { + { 16091085, -16253926, 18599252, 7340678, 2137637, -1221657, -3364161, 14550936, 3260525, -7166271 }, + { -4910104, -13332887, 18550887, 10864893, -16459325, -7291596, -23028869, -13204905, -12748722, 2701326 }, + { -8574695, 16099415, 4629974, -16340524, -20786213, -6005432, -10018363, 9276971, 11329923, 1862132 } + }, + { + { 14763076, -15903608, -30918270, 3689867, 3511892, 10313526, -21951088, 12219231, -9037963, -940300 }, + { 8894987, -3446094, 6150753, 3013931, 301220, 15693451, -31981216, -2909717, -15438168, 11595570 }, + { 15214962, 3537601, -26238722, -14058872, 4418657, -15230761, 13947276, 10730794, -13489462, -4363670 } + }, + { + { -2538306, 7682793, 32759013, 263109, -29984731, -7955452, -22332124, -10188635, 977108, 699994 }, + { -12466472, 4195084, -9211532, 550904, -15565337, 12917920, 19118110, -439841, -30534533, -14337913 }, + { 31788461, -14507657, 4799989, 7372237, 8808585, -14747943, 9408237, -10051775, 12493932, -5409317 } + }, + { + { -25680606, 5260744, -19235809, -6284470, -3695942, 16566087, 27218280, 2607121, 29375955, 6024730 }, + { 842132, -2794693, -4763381, -8722815, 26332018, -12405641, 11831880, 6985184, -9940361, 2854096 }, + { -4847262, -7969331, 2516242, -5847713, 9695691, -7221186, 16512645, 960770, 12121869, 16648078 } + }, + { + { -15218652, 14667096, -13336229, 2013717, 30598287, -464137, -31504922, -7882064, 20237806, 2838411 }, + { -19288047, 4453152, 15298546, -16178388, 22115043, -15972604, 12544294, -13470457, 1068881, -12499905 }, + { -9558883, -16518835, 33238498, 13506958, 30505848, -1114596, -8486907, -2630053, 12521378, 4845654 } + }, + { + { -28198521, 10744108, -2958380, 10199664, 7759311, -13088600, 3409348, -873400, -6482306, -12885870 }, + { -23561822, 6230156, -20382013, 10655314, -24040585, -11621172, 10477734, -1240216, -3113227, 13974498 }, + { 12966261, 15550616, -32038948, -1615346, 21025980, -629444, 5642325, 7188737, 18895762, 12629579 } + } +}, +{ /* 21/31 */ + { + { 14741879, -14946887, 22177208, -11721237, 1279741, 8058600, 11758140, 789443, 32195181, 3895677 }, + { 10758205, 15755439, -4509950, 9243698, -4879422, 6879879, -2204575, -3566119, -8982069, 4429647 }, + { -2453894, 15725973, -20436342, -10410672, -5803908, -11040220, -7135870, -11642895, 18047436, -15281743 } + }, + { + { -25173001, -11307165, 29759956, 11776784, -22262383, -15820455, 10993114, -12850837, -17620701, -9408468 }, + { 21987233, 700364, -24505048, 14972008, -7774265, -5718395, 32155026, 2581431, -29958985, 8773375 }, + { -25568350, 454463, -13211935, 16126715, 25240068, 8594567, 20656846, 12017935, -7874389, -13920155 } + }, + { + { 6028182, 6263078, -31011806, -11301710, -818919, 2461772, -31841174, -5468042, -1721788, -2776725 }, + { -12278994, 16624277, 987579, -5922598, 32908203, 1248608, 7719845, -4166698, 28408820, 6816612 }, + { -10358094, -8237829, 19549651, -12169222, 22082623, 16147817, 20613181, 13982702, -10339570, 5067943 } + }, + { + { -30505967, -3821767, 12074681, 13582412, -19877972, 2443951, -19719286, 12746132, 5331210, -10105944 }, + { 30528811, 3601899, -1957090, 4619785, -27361822, -15436388, 24180793, -12570394, 27679908, -1648928 }, + { 9402404, -13957065, 32834043, 10838634, -26580150, -13237195, 26653274, -8685565, 22611444, -12715406 } + }, + { + { 22190590, 1118029, 22736441, 15130463, -30460692, -5991321, 19189625, -4648942, 4854859, 6622139 }, + { -8310738, -2953450, -8262579, -3388049, -10401731, -271929, 13424426, -3567227, 26404409, 13001963 }, + { -31241838, -15415700, -2994250, 8939346, 11562230, -12840670, -26064365, -11621720, -15405155, 11020693 } + }, + { + { 1866042, -7949489, -7898649, -10301010, 12483315, 13477547, 3175636, -12424163, 28761762, 1406734 }, + { -448555, -1777666, 13018551, 3194501, -9580420, -11161737, 24760585, -4347088, 25577411, -13378680 }, + { -24290378, 4759345, -690653, -1852816, 2066747, 10693769, -29595790, 9884936, -9368926, 4745410 } + }, + { + { -9141284, 6049714, -19531061, -4341411, -31260798, 9944276, -15462008, -11311852, 10931924, -11931931 }, + { -16561513, 14112680, -8012645, 4817318, -8040464, -11414606, -22853429, 10856641, -20470770, 13434654 }, + { 22759489, -10073434, -16766264, -1871422, 13637442, -10168091, 1765144, -12654326, 28445307, -5364710 } + }, + { + { 29875063, 12493613, 2795536, -3786330, 1710620, 15181182, -10195717, -8788675, 9074234, 1167180 }, + { -26205683, 11014233, -9842651, -2635485, -26908120, 7532294, -18716888, -9535498, 3843903, 9367684 }, + { -10969595, -6403711, 9591134, 9582310, 11349256, 108879, 16235123, 8601684, -139197, 4242895 } + } +}, +{ /* 22/31 */ + { + { 22092954, -13191123, -2042793, -11968512, 32186753, -11517388, -6574341, 2470660, -27417366, 16625501 }, + { -11057722, 3042016, 13770083, -9257922, 584236, -544855, -7770857, 2602725, -27351616, 14247413 }, + { 6314175, -10264892, -32772502, 15957557, -10157730, 168750, -8618807, 14290061, 27108877, -1180880 } + }, + { + { -8586597, -7170966, 13241782, 10960156, -32991015, -13794596, 33547976, -11058889, -27148451, 981874 }, + { 22833440, 9293594, -32649448, -13618667, -9136966, 14756819, -22928859, -13970780, -10479804, -16197962 }, + { -7768587, 3326786, -28111797, 10783824, 19178761, 14905060, 22680049, 13906969, -15933690, 3797899 } + }, + { + { 21721356, -4212746, -12206123, 9310182, -3882239, -13653110, 23740224, -2709232, 20491983, -8042152 }, + { 9209270, -15135055, -13256557, -6167798, -731016, 15289673, 25947805, 15286587, 30997318, -6703063 }, + { 7392032, 16618386, 23946583, -8039892, -13265164, -1533858, -14197445, -2321576, 17649998, -250080 } + }, + { + { -9301088, -14193827, 30609526, -3049543, -25175069, -1283752, -15241566, -9525724, -2233253, 7662146 }, + { -17558673, 1763594, -33114336, 15908610, -30040870, -12174295, 7335080, -8472199, -3174674, 3440183 }, + { -19889700, -5977008, -24111293, -9688870, 10799743, -16571957, 40450, -4431835, 4862400, 1133 } + }, + { + { -32856209, -7873957, -5422389, 14860950, -16319031, 7956142, 7258061, 311861, -30594991, -7379421 }, + { -3773428, -1565936, 28985340, 7499440, 24445838, 9325937, 29727763, 16527196, 18278453, 15405622 }, + { -4381906, 8508652, -19898366, -3674424, -5984453, 15149970, -13313598, 843523, -21875062, 13626197 } + }, + { + { 2281448, -13487055, -10915418, -2609910, 1879358, 16164207, -10783882, 3953792, 13340839, 15928663 }, + { 31727126, -7179855, -18437503, -8283652, 2875793, -16390330, -25269894, -7014826, -23452306, 5964753 }, + { 4100420, -5959452, -17179337, 6017714, -18705837, 12227141, -26684835, 11344144, 2538215, -7570755 } + }, + { + { -9433605, 6123113, 11159803, -2156608, 30016280, 14966241, -20474983, 1485421, -629256, -15958862 }, + { -26804558, 4260919, 11851389, 9658551, -32017107, 16367492, -20205425, -13191288, 11659922, -11115118 }, + { 26180396, 10015009, -30844224, -8581293, 5418197, 9480663, 2231568, -10170080, 33100372, -1306171 } + }, + { + { 15121113, -5201871, -10389905, 15427821, -27509937, -15992507, 21670947, 4486675, -5931810, -14466380 }, + { 16166486, -9483733, -11104130, 6023908, -31926798, -1364923, 2340060, -16254968, -10735770, -10039824 }, + { 28042865, -3557089, -12126526, 12259706, -3717498, -6945899, 6766453, -8689599, 18036436, 5803270 } + } +}, +{ /* 23/31 */ + { + { -817581, 6763912, 11803561, 1585585, 10958447, -2671165, 23855391, 4598332, -6159431, -14117438 }, + { -31031306, -14256194, 17332029, -2383520, 31312682, -5967183, 696309, 50292, -20095739, 11763584 }, + { -594563, -2514283, -32234153, 12643980, 12650761, 14811489, 665117, -12613632, -19773211, -10713562 } + }, + { + { 30464590, -11262872, -4127476, -12734478, 19835327, -7105613, -24396175, 2075773, -17020157, 992471 }, + { 18357185, -6994433, 7766382, 16342475, -29324918, 411174, 14578841, 8080033, -11574335, -10601610 }, + { 19598397, 10334610, 12555054, 2555664, 18821899, -10339780, 21873263, 16014234, 26224780, 16452269 } + }, + { + { -30223925, 5145196, 5944548, 16385966, 3976735, 2009897, -11377804, -7618186, -20533829, 3698650 }, + { 14187449, 3448569, -10636236, -10810935, -22663880, -3433596, 7268410, -10890444, 27394301, 12015369 }, + { 19695761, 16087646, 28032085, 12999827, 6817792, 11427614, 20244189, -1312777, -13259127, -3402461 } + }, + { + { 30860103, 12735208, -1888245, -4699734, -16974906, 2256940, -8166013, 12298312, -8550524, -10393462 }, + { -5719826, -11245325, -1910649, 15569035, 26642876, -7587760, -5789354, -15118654, -4976164, 12651793 }, + { -2848395, 9953421, 11531313, -5282879, 26895123, -12697089, -13118820, -16517902, 9768698, -2533218 } + }, + { + { -24719459, 1894651, -287698, -4704085, 15348719, -8156530, 32767513, 12765450, 4940095, 10678226 }, + { 18860224, 15980149, -18987240, -1562570, -26233012, -11071856, -7843882, 13944024, -24372348, 16582019 }, + { -15504260, 4970268, -29893044, 4175593, -20993212, -2199756, -11704054, 15444560, -11003761, 7989037 } + }, + { + { 31490452, 5568061, -2412803, 2182383, -32336847, 4531686, -32078269, 6200206, -19686113, -14800171 }, + { -17308668, -15879940, -31522777, -2831, -32887382, 16375549, 8680158, -16371713, 28550068, -6857132 }, + { -28126887, -5688091, 16837845, -1820458, -6850681, 12700016, -30039981, 4364038, 1155602, 5988841 } + }, + { + { 21890435, -13272907, -12624011, 12154349, -7831873, 15300496, 23148983, -4470481, 24618407, 8283181 }, + { -33136107, -10512751, 9975416, 6841041, -31559793, 16356536, 3070187, -7025928, 1466169, 10740210 }, + { -1509399, -15488185, -13503385, -10655916, 32799044, 909394, -13938903, -5779719, -32164649, -15327040 } + }, + { + { 3960823, -14267803, -28026090, -15918051, -19404858, 13146868, 15567327, 951507, -3260321, -573935 }, + { 24740841, 5052253, -30094131, 8961361, 25877428, 6165135, -24368180, 14397372, -7380369, -6144105 }, + { -28888365, 3510803, -28103278, -1158478, -11238128, -10631454, -15441463, -14453128, -1625486, -6494814 } + } +}, +{ /* 24/31 */ + { + { 793299, -9230478, 8836302, -6235707, -27360908, -2369593, 33152843, -4885251, -9906200, -621852 }, + { 5666233, 525582, 20782575, -8038419, -24538499, 14657740, 16099374, 1468826, -6171428, -15186581 }, + { -4859255, -3779343, -2917758, -6748019, 7778750, 11688288, -30404353, -9871238, -1558923, -9863646 } + }, + { + { 10896332, -7719704, 824275, 472601, -19460308, 3009587, 25248958, 14783338, -30581476, -15757844 }, + { 10566929, 12612572, -31944212, 11118703, -12633376, 12362879, 21752402, 8822496, 24003793, 14264025 }, + { 27713862, -7355973, -11008240, 9227530, 27050101, 2504721, 23886875, -13117525, 13958495, -5732453 } + }, + { + { -23481610, 4867226, -27247128, 3900521, 29838369, -8212291, -31889399, -10041781, 7340521, -15410068 }, + { 4646514, -8011124, -22766023, -11532654, 23184553, 8566613, 31366726, -1381061, -15066784, -10375192 }, + { -17270517, 12723032, -16993061, 14878794, 21619651, -6197576, 27584817, 3093888, -8843694, 3849921 } + }, + { + { -9064912, 2103172, 25561640, -15125738, -5239824, 9582958, 32477045, -9017955, 5002294, -15550259 }, + { -12057553, -11177906, 21115585, -13365155, 8808712, -12030708, 16489530, 13378448, -25845716, 12741426 }, + { -5946367, 10645103, -30911586, 15390284, -3286982, -7118677, 24306472, 15852464, 28834118, -7646072 } + }, + { + { -17335748, -9107057, -24531279, 9434953, -8472084, -583362, -13090771, 455841, 20461858, 5491305 }, + { 13669248, -16095482, -12481974, -10203039, -14569770, -11893198, -24995986, 11293807, -28588204, -9421832 }, + { 28497928, 6272777, -33022994, 14470570, 8906179, -1225630, 18504674, -14165166, 29867745, -8795943 } + }, + { + { -16207023, 13517196, -27799630, -13697798, 24009064, -6373891, -6367600, -13175392, 22853429, -4012011 }, + { 24191378, 16712145, -13931797, 15217831, 14542237, 1646131, 18603514, -11037887, 12876623, -2112447 }, + { 17902668, 4518229, -411702, -2829247, 26878217, 5258055, -12860753, 608397, 16031844, 3723494 } + }, + { + { -28632773, 12763728, -20446446, 7577504, 33001348, -13017745, 17558842, -7872890, 23896954, -4314245 }, + { -20005381, -12011952, 31520464, 605201, 2543521, 5991821, -2945064, 7229064, -9919646, -8826859 }, + { 28816045, 298879, -28165016, -15920938, 19000928, -1665890, -12680833, -2949325, -18051778, -2082915 } + }, + { + { 16000882, -344896, 3493092, -11447198, -29504595, -13159789, 12577740, 16041268, -19715240, 7847707 }, + { 10151868, 10572098, 27312476, 7922682, 14825339, 4723128, -32855931, -6519018, -10020567, 3852848 }, + { -11430470, 15697596, -21121557, -4420647, 5386314, 15063598, 16514493, -15932110, 29330899, -15076224 } + } +}, +{ /* 25/31 */ + { + { -25499735, -4378794, -15222908, -6901211, 16615731, 2051784, 3303702, 15490, -27548796, 12314391 }, + { 15683520, -6003043, 18109120, -9980648, 15337968, -5997823, -16717435, 15921866, 16103996, -3731215 }, + { -23169824, -10781249, 13588192, -1628807, -3798557, -1074929, -19273607, 5402699, -29815713, -9841101 } + }, + { + { 23190676, 2384583, -32714340, 3462154, -29903655, -1529132, -11266856, 8911517, -25205859, 2739713 }, + { 21374101, -3554250, -33524649, 9874411, 15377179, 11831242, -33529904, 6134907, 4931255, 11987849 }, + { -7732, -2978858, -16223486, 7277597, 105524, -322051, -31480539, 13861388, -30076310, 10117930 } + }, + { + { -29501170, -10744872, -26163768, 13051539, -25625564, 5089643, -6325503, 6704079, 12890019, 15728940 }, + { -21972360, -11771379, -951059, -4418840, 14704840, 2695116, 903376, -10428139, 12885167, 8311031 }, + { -17516482, 5352194, 10384213, -13811658, 7506451, 13453191, 26423267, 4384730, 1888765, -5435404 } + }, + { + { -25817338, -3107312, -13494599, -3182506, 30896459, -13921729, -32251644, -12707869, -19464434, -3340243 }, + { -23607977, -2665774, -526091, 4651136, 5765089, 4618330, 6092245, 14845197, 17151279, -9854116 }, + { -24830458, -12733720, -15165978, 10367250, -29530908, -265356, 22825805, -7087279, -16866484, 16176525 } + }, + { + { -23583256, 6564961, 20063689, 3798228, -4740178, 7359225, 2006182, -10363426, -28746253, -10197509 }, + { -10626600, -4486402, -13320562, -5125317, 3432136, -6393229, 23632037, -1940610, 32808310, 1099883 }, + { 15030977, 5768825, -27451236, -2887299, -6427378, -15361371, -15277896, -6809350, 2051441, -15225865 } + }, + { + { -3362323, -7239372, 7517890, 9824992, 23555850, 295369, 5148398, -14154188, -22686354, 16633660 }, + { 4577086, -16752288, 13249841, -15304328, 19958763, -14537274, 18559670, -10759549, 8402478, -9864273 }, + { -28406330, -1051581, -26790155, -907698, -17212414, -11030789, 9453451, -14980072, 17983010, 9967138 } + }, + { + { -25762494, 6524722, 26585488, 9969270, 24709298, 1220360, -1677990, 7806337, 17507396, 3651560 }, + { -10420457, -4118111, 14584639, 15971087, -15768321, 8861010, 26556809, -5574557, -18553322, -11357135 }, + { 2839101, 14284142, 4029895, 3472686, 14402957, 12689363, -26642121, 8459447, -5605463, -7621941 } + }, + { + { -4839289, -3535444, 9744961, 2871048, 25113978, 3187018, -25110813, -849066, 17258084, -7977739 }, + { 18164541, -10595176, -17154882, -1542417, 19237078, -9745295, 23357533, -15217008, 26908270, 12150756 }, + { -30264870, -7647865, 5112249, -7036672, -1499807, -6974257, 43168, -5537701, -32302074, 16215819 } + } +}, +{ /* 26/31 */ + { + { -6898905, 9824394, -12304779, -4401089, -31397141, -6276835, 32574489, 12532905, -7503072, -8675347 }, + { -27343522, -16515468, -27151524, -10722951, 946346, 16291093, 254968, 7168080, 21676107, -1943028 }, + { 21260961, -8424752, -16831886, -11920822, -23677961, 3968121, -3651949, -6215466, -3556191, -7913075 } + }, + { + { 16544754, 13250366, -16804428, 15546242, -4583003, 12757258, -2462308, -8680336, -18907032, -9662799 }, + { -2415239, -15577728, 18312303, 4964443, -15272530, -12653564, 26820651, 16690659, 25459437, -4564609 }, + { -25144690, 11425020, 28423002, -11020557, -6144921, -15826224, 9142795, -2391602, -6432418, -1644817 } + }, + { + { -23104652, 6253476, 16964147, -3768872, -25113972, -12296437, -27457225, -16344658, 6335692, 7249989 }, + { -30333227, 13979675, 7503222, -12368314, -11956721, -4621693, -30272269, 2682242, 25993170, -12478523 }, + { 4364628, 5930691, 32304656, -10044554, -8054781, 15091131, 22857016, -10598955, 31820368, 15075278 } + }, + { + { 31879134, -8918693, 17258761, 90626, -8041836, -4917709, 24162788, -9650886, -17970238, 12833045 }, + { 19073683, 14851414, -24403169, -11860168, 7625278, 11091125, -19619190, 2074449, -9413939, 14905377 }, + { 24483667, -11935567, -2518866, -11547418, -1553130, 15355506, -25282080, 9253129, 27628530, -7555480 } + }, + { + { 17597607, 8340603, 19355617, 552187, 26198470, -3176583, 4593324, -9157582, -14110875, 15297016 }, + { 510886, 14337390, -31785257, 16638632, 6328095, 2713355, -20217417, -11864220, 8683221, 2921426 }, + { 18606791, 11874196, 27155355, -5281482, -24031742, 6265446, -25178240, -1278924, 4674690, 13890525 } + }, + { + { 13609624, 13069022, -27372361, -13055908, 24360586, 9592974, 14977157, 9835105, 4389687, 288396 }, + { 9922506, -519394, 13613107, 5883594, -18758345, -434263, -12304062, 8317628, 23388070, 16052080 }, + { 12720016, 11937594, -31970060, -5028689, 26900120, 8561328, -20155687, -11632979, -14754271, -10812892 } + }, + { + { 15961858, 14150409, 26716931, -665832, -22794328, 13603569, 11829573, 7467844, -28822128, 929275 }, + { 11038231, -11582396, -27310482, -7316562, -10498527, -16307831, -23479533, -9371869, -21393143, 2465074 }, + { 20017163, -4323226, 27915242, 1529148, 12396362, 15675764, 13817261, -9658066, 2463391, -4622140 } + }, + { + { -16358878, -12663911, -12065183, 4996454, -1256422, 1073572, 9583558, 12851107, 4003896, 12673717 }, + { -1731589, -15155870, -3262930, 16143082, 19294135, 13385325, 14741514, -9103726, 7903886, 2348101 }, + { 24536016, -16515207, 12715592, -3862155, 1511293, 10047386, -3842346, -7129159, -28377538, 10048127 } + } +}, +{ /* 27/31 */ + { + { -12622226, -6204820, 30718825, 2591312, -10617028, 12192840, 18873298, -7297090, -32297756, 15221632 }, + { -26478122, -11103864, 11546244, -1852483, 9180880, 7656409, -21343950, 2095755, 29769758, 6593415 }, + { -31994208, -2907461, 4176912, 3264766, 12538965, -868111, 26312345, -6118678, 30958054, 8292160 } + }, + { + { 31429822, -13959116, 29173532, 15632448, 12174511, -2760094, 32808831, 3977186, 26143136, -3148876 }, + { 22648901, 1402143, -22799984, 13746059, 7936347, 365344, -8668633, -1674433, -3758243, -2304625 }, + { -15491917, 8012313, -2514730, -12702462, -23965846, -10254029, -1612713, -1535569, -16664475, 8194478 } + }, + { + { 27338066, -7507420, -7414224, 10140405, -19026427, -6589889, 27277191, 8855376, 28572286, 3005164 }, + { 26287124, 4821776, 25476601, -4145903, -3764513, -15788984, -18008582, 1182479, -26094821, -13079595 }, + { -7171154, 3178080, 23970071, 6201893, -17195577, -4489192, -21876275, -13982627, 32208683, -1198248 } + }, + { + { -16657702, 2817643, -10286362, 14811298, 6024667, 13349505, -27315504, -10497842, -27672585, -11539858 }, + { 15941029, -9405932, -21367050, 8062055, 31876073, -238629, -15278393, -1444429, 15397331, -4130193 }, + { 8934485, -13485467, -23286397, -13423241, -32446090, 14047986, 31170398, -1441021, -27505566, 15087184 } + }, + { + { -18357243, -2156491, 24524913, -16677868, 15520427, -6360776, -15502406, 11461896, 16788528, -5868942 }, + { -1947386, 16013773, 21750665, 3714552, -17401782, -16055433, -3770287, -10323320, 31322514, -11615635 }, + { 21426655, -5650218, -13648287, -5347537, -28812189, -4920970, -18275391, -14621414, 13040862, -12112948 } + }, + { + { 11293895, 12478086, -27136401, 15083750, -29307421, 14748872, 14555558, -13417103, 1613711, 4896935 }, + { -25894883, 15323294, -8489791, -8057900, 25967126, -13425460, 2825960, -4897045, -23971776, -11267415 }, + { -15924766, -5229880, -17443532, 6410664, 3622847, 10243618, 20615400, 12405433, -23753030, -8436416 } + }, + { + { -7091295, 12556208, -20191352, 9025187, -17072479, 4333801, 4378436, 2432030, 23097949, -566018 }, + { 4565804, -16025654, 20084412, -7842817, 1724999, 189254, 24767264, 10103221, -18512313, 2424778 }, + { 366633, -11976806, 8173090, -6890119, 30788634, 5745705, -7168678, 1344109, -3642553, 12412659 } + }, + { + { -24001791, 7690286, 14929416, -168257, -32210835, -13412986, 24162697, -15326504, -3141501, 11179385 }, + { 18289522, -14724954, 8056945, 16430056, -21729724, 7842514, -6001441, -1486897, -18684645, -11443503 }, + { 476239, 6601091, -6152790, -9723375, 17503545, -4863900, 27672959, 13403813, 11052904, 5219329 } + } +}, +{ /* 28/31 */ + { + { 20678546, -8375738, -32671898, 8849123, -5009758, 14574752, 31186971, -3973730, 9014762, -8579056 }, + { -13644050, -10350239, -15962508, 5075808, -1514661, -11534600, -33102500, 9160280, 8473550, -3256838 }, + { 24900749, 14435722, 17209120, -15292541, -22592275, 9878983, -7689309, -16335821, -24568481, 11788948 } + }, + { + { -3118155, -11395194, -13802089, 14797441, 9652448, -6845904, -20037437, 10410733, -24568470, -1458691 }, + { -15659161, 16736706, -22467150, 10215878, -9097177, 7563911, 11871841, -12505194, -18513325, 8464118 }, + { -23400612, 8348507, -14585951, -861714, -3950205, -6373419, 14325289, 8628612, 33313881, -8370517 } + }, + { + { -20186973, -4967935, 22367356, 5271547, -1097117, -4788838, -24805667, -10236854, -8940735, -5818269 }, + { -6948785, -1795212, -32625683, -16021179, 32635414, -7374245, 15989197, -12838188, 28358192, -4253904 }, + { -23561781, -2799059, -32351682, -1661963, -9147719, 10429267, -16637684, 4072016, -5351664, 5596589 } + }, + { + { -28236598, -3390048, 12312896, 6213178, 3117142, 16078565, 29266239, 2557221, 1768301, 15373193 }, + { -7243358, -3246960, -4593467, -7553353, -127927, -912245, -1090902, -4504991, -24660491, 3442910 }, + { -30210571, 5124043, 14181784, 8197961, 18964734, -11939093, 22597931, 7176455, -18585478, 13365930 } + }, + { + { -7877390, -1499958, 8324673, 4690079, 6261860, 890446, 24538107, -8570186, -9689599, -3031667 }, + { 25008904, -10771599, -4305031, -9638010, 16265036, 15721635, 683793, -11823784, 15723479, -15163481 }, + { -9660625, 12374379, -27006999, -7026148, -7724114, -12314514, 11879682, 5400171, 519526, -1235876 } + }, + { + { 22258397, -16332233, -7869817, 14613016, -22520255, -2950923, -20353881, 7315967, 16648397, 7605640 }, + { -8081308, -8464597, -8223311, 9719710, 19259459, -15348212, 23994942, -5281555, -9468848, 4763278 }, + { -21699244, 9220969, -15730624, 1084137, -25476107, -2852390, 31088447, -7764523, -11356529, 728112 } + }, + { + { 26047220, -11751471, -6900323, -16521798, 24092068, 9158119, -4273545, -12555558, -29365436, -5498272 }, + { 17510331, -322857, 5854289, 8403524, 17133918, -3112612, -28111007, 12327945, 10750447, 10014012 }, + { -10312768, 3936952, 9156313, -8897683, 16498692, -994647, -27481051, -666732, 3424691, 7540221 } + }, + { + { 30322361, -6964110, 11361005, -4143317, 7433304, 4989748, -7071422, -16317219, -9244265, 15258046 }, + { 13054562, -2779497, 19155474, 469045, -12482797, 4566042, 5631406, 2711395, 1062915, -5136345 }, + { -19240248, -11254599, -29509029, -7499965, -5835763, 13005411, -6066489, 12194497, 32960380, 1459310 } + } +}, +{ /* 29/31 */ + { + { 19852034, 7027924, 23669353, 10020366, 8586503, -6657907, 394197, -6101885, 18638003, -11174937 }, + { 31395534, 15098109, 26581030, 8030562, -16527914, -5007134, 9012486, -7584354, -6643087, -5442636 }, + { -9192165, -2347377, -1997099, 4529534, 25766844, 607986, -13222, 9677543, -32294889, -6456008 } + }, + { + { -2444496, -149937, 29348902, 8186665, 1873760, 12489863, -30934579, -7839692, -7852844, -8138429 }, + { -15236356, -15433509, 7766470, 746860, 26346930, -10221762, -27333451, 10754588, -9431476, 5203576 }, + { 31834314, 14135496, -770007, 5159118, 20917671, -16768096, -7467973, -7337524, 31809243, 7347066 } + }, + { + { -9606723, -11874240, 20414459, 13033986, 13716524, -11691881, 19797970, -12211255, 15192876, -2087490 }, + { -12663563, -2181719, 1168162, -3804809, 26747877, -14138091, 10609330, 12694420, 33473243, -13382104 }, + { 33184999, 11180355, 15832085, -11385430, -1633671, 225884, 15089336, -11023903, -6135662, 14480053 } + }, + { + { 31308717, -5619998, 31030840, -1897099, 15674547, -6582883, 5496208, 13685227, 27595050, 8737275 }, + { -20318852, -15150239, 10933843, -16178022, 8335352, -7546022, -31008351, -12610604, 26498114, 66511 }, + { 22644454, -8761729, -16671776, 4884562, -3105614, -13559366, 30540766, -4286747, -13327787, -7515095 } + }, + { + { -28017847, 9834845, 18617207, -2681312, -3401956, -13307506, 8205540, 13585437, -17127465, 15115439 }, + { 23711543, -672915, 31206561, -8362711, 6164647, -9709987, -33535882, -1426096, 8236921, 16492939 }, + { -23910559, -13515526, -26299483, -4503841, 25005590, -7687270, 19574902, 10071562, 6708380, -6222424 } + }, + { + { 2101391, -4930054, 19702731, 2367575, -15427167, 1047675, 5301017, 9328700, 29955601, -11678310 }, + { 3096359, 9271816, -21620864, -15521844, -14847996, -7592937, -25892142, -12635595, -9917575, 6216608 }, + { -32615849, 338663, -25195611, 2510422, -29213566, -13820213, 24822830, -6146567, -26767480, 7525079 } + }, + { + { -23066649, -13985623, 16133487, -7896178, -3389565, 778788, -910336, -2782495, -19386633, 11994101 }, + { 21691500, -13624626, -641331, -14367021, 3285881, -3483596, -25064666, 9718258, -7477437, 13381418 }, + { 18445390, -4202236, 14979846, 11622458, -1727110, -3582980, 23111648, -6375247, 28535282, 15779576 } + }, + { + { 30098053, 3089662, -9234387, 16662135, -21306940, 11308411, -14068454, 12021730, 9955285, -16303356 }, + { 9734894, -14576830, -7473633, -9138735, 2060392, 11313496, -18426029, 9924399, 20194861, 13380996 }, + { -26378102, -7965207, -22167821, 15789297, -18055342, -6168792, -1984914, 15707771, 26342023, 10146099 } + } +}, +{ /* 30/31 */ + { + { -26016874, -219943, 21339191, -41388, 19745256, -2878700, -29637280, 2227040, 21612326, -545728 }, + { -13077387, 1184228, 23562814, -5970442, -20351244, -6348714, 25764461, 12243797, -20856566, 11649658 }, + { -10031494, 11262626, 27384172, 2271902, 26947504, -15997771, 39944, 6114064, 33514190, 2333242 } + }, + { + { -21433588, -12421821, 8119782, 7219913, -21830522, -9016134, -6679750, -12670638, 24350578, -13450001 }, + { -4116307, -11271533, -23886186, 4843615, -30088339, 690623, -31536088, -10406836, 8317860, 12352766 }, + { 18200138, -14475911, -33087759, -2696619, -23702521, -9102511, -23552096, -2287550, 20712163, 6719373 } + }, + { + { 26656208, 6075253, -7858556, 1886072, -28344043, 4262326, 11117530, -3763210, 26224235, -3297458 }, + { -17168938, -14854097, -3395676, -16369877, -19954045, 14050420, 21728352, 9493610, 18620611, -16428628 }, + { -13323321, 13325349, 11432106, 5964811, 18609221, 6062965, -5269471, -9725556, -30701573, -16479657 } + }, + { + { -23860538, -11233159, 26961357, 1640861, -32413112, -16737940, 12248509, -5240639, 13735342, 1934062 }, + { 25089769, 6742589, 17081145, -13406266, 21909293, -16067981, -15136294, -3765346, -21277997, 5473616 }, + { 31883677, -7961101, 1083432, -11572403, 22828471, 13290673, -7125085, 12469656, 29111212, -5451014 } + }, + { + { 24244947, -15050407, -26262976, 2791540, -14997599, 16666678, 24367466, 6388839, -10295587, 452383 }, + { -25640782, -3417841, 5217916, 16224624, 19987036, -4082269, -24236251, -5915248, 15766062, 8407814 }, + { -20406999, 13990231, 15495425, 16395525, 5377168, 15166495, -8917023, -4388953, -8067909, 2276718 } + }, + { + { 30157918, 12924066, -17712050, 9245753, 19895028, 3368142, -23827587, 5096219, 22740376, -7303417 }, + { 2041139, -14256350, 7783687, 13876377, -25946985, -13352459, 24051124, 13742383, -15637599, 13295222 }, + { 33338237, -8505733, 12532113, 7977527, 9106186, -1715251, -17720195, -4612972, -4451357, -14669444 } + }, + { + { -20045281, 5454097, -14346548, 6447146, 28862071, 1883651, -2469266, -4141880, 7770569, 9620597 }, + { 23208068, 7979712, 33071466, 8149229, 1758231, -10834995, 30945528, -1694323, -33502340, -14767970 }, + { 1439958, -16270480, -1079989, -793782, 4625402, 10647766, -5043801, 1220118, 30494170, -11440799 } + }, + { + { -5037580, -13028295, -2970559, -3061767, 15640974, -6701666, -26739026, 926050, -1684339, -13333647 }, + { 13908495, -3549272, 30919928, -6273825, -21521863, 7989039, 9021034, 9078865, 3353509, 4033511 }, + { -29663431, -15113610, 32259991, -344482, 24295849, -12912123, 23161163, 8839127, 27485041, 7356032 } + } +}, +{ /* 31/31 */ + { + { 9661027, 705443, 11980065, -5370154, -1628543, 14661173, -6346142, 2625015, 28431036, -16771834 }, + { -23839233, -8311415, -25945511, 7480958, -17681669, -8354183, -22545972, 14150565, 15970762, 4099461 }, + { 29262576, 16756590, 26350592, -8793563, 8529671, -11208050, 13617293, -9937143, 11465739, 8317062 } + }, + { + { -25493081, -6962928, 32500200, -9419051, -23038724, -2302222, 14898637, 3848455, 20969334, -5157516 }, + { -20384450, -14347713, -18336405, 13884722, -33039454, 2842114, -21610826, -3649888, 11177095, 14989547 }, + { -24496721, -11716016, 16959896, 2278463, 12066309, 10137771, 13515641, 2581286, -28487508, 9930240 } + }, + { + { -17751622, -2097826, 16544300, -13009300, -15914807, -14949081, 18345767, -13403753, 16291481, -5314038 }, + { -33229194, 2553288, 32678213, 9875984, 8534129, 6889387, -9676774, 6957617, 4368891, 9788741 }, + { 16660756, 7281060, -10830758, 12911820, 20108584, -8101676, -21722536, -8613148, 16250552, -11111103 } + }, + { + { -19765507, 2390526, -16551031, 14161980, 1905286, 6414907, 4689584, 10604807, -30190403, 4782747 }, + { -1354539, 14736941, -7367442, -13292886, 7710542, -14155590, -9981571, 4383045, 22546403, 437323 }, + { 31665577, -12180464, -16186830, 1491339, -18368625, 3294682, 27343084, 2786261, -30633590, -14097016 } + }, + { + { -14467279, -683715, -33374107, 7448552, 19294360, 14334329, -19690631, 2355319, -19284671, -6114373 }, + { 15121312, -15796162, 6377020, -6031361, -10798111, -12957845, 18952177, 15496498, -29380133, 11754228 }, + { -2637277, -13483075, 8488727, -14303896, 12728761, -1622493, 7141596, 11724556, 22761615, -10134141 } + }, + { + { 16918416, 11729663, -18083579, 3022987, -31015732, -13339659, -28741185, -12227393, 32851222, 11717399 }, + { 11166634, 7338049, -6722523, 4531520, -29468672, -7302055, 31474879, 3483633, -1193175, -4030831 }, + { -185635, 9921305, 31456609, -13536438, -12013818, 13348923, 33142652, 6546660, -19985279, -3948376 } + }, + { + { -32460596, 11266712, -11197107, -7899103, 31703694, 3855903, -8537131, -12833048, -30772034, -15486313 }, + { -18006477, 12709068, 3991746, -6479188, -21491523, -10550425, -31135347, -16049879, 10928917, 3011958 }, + { -6957757, -15594337, 31696059, 334240, 29576716, 14796075, -30831056, -12805180, 18008031, 10258577 } + }, + { + { -22448644, 15655569, 7018479, -4410003, -30314266, -1201591, -1853465, 1367120, 25127874, 6671743 }, + { 29701166, -14373934, -10878120, 9279288, -17568, 13127210, 21382910, 11042292, 25838796, 4642684 }, + { -20430234, 14955537, -24126347, 8124619, -5369288, -5990470, 30468147, -13900640, 18423289, 4177476 } + } +} diff --git a/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/base2.h b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/base2.h new file mode 100644 index 0000000..90a1457 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/base2.h @@ -0,0 +1,40 @@ +{ + { 25967493, -14356035, 29566456, 3660896, -12694345, 4014787, 27544626, -11754271, -6079156, 2047605 }, + { -12545711, 934262, -2722910, 3049990, -727428, 9406986, 12720692, 5043384, 19500929, -15469378 }, + { -8738181, 4489570, 9688441, -14785194, 10184609, -12363380, 29287919, 11864899, -24514362, -4438546 } +}, +{ + { 15636291, -9688557, 24204773, -7912398, 616977, -16685262, 27787600, -14772189, 28944400, -1550024 }, + { 16568933, 4717097, -11556148, -1102322, 15682896, -11807043, 16354577, -11775962, 7689662, 11199574 }, + { 30464156, -5976125, -11779434, -15670865, 23220365, 15915852, 7512774, 10017326, -17749093, -9920357 } +}, +{ + { 10861363, 11473154, 27284546, 1981175, -30064349, 12577861, 32867885, 14515107, -15438304, 10819380 }, + { 4708026, 6336745, 20377586, 9066809, -11272109, 6594696, -25653668, 12483688, -12668491, 5581306 }, + { 19563160, 16186464, -29386857, 4097519, 10237984, -4348115, 28542350, 13850243, -23678021, -15815942 } +}, +{ + { 5153746, 9909285, 1723747, -2777874, 30523605, 5516873, 19480852, 5230134, -23952439, -15175766 }, + { -30269007, -3463509, 7665486, 10083793, 28475525, 1649722, 20654025, 16520125, 30598449, 7715701 }, + { 28881845, 14381568, 9657904, 3680757, -20181635, 7843316, -31400660, 1370708, 29794553, -1409300 } +}, +{ + { -22518993, -6692182, 14201702, -8745502, -23510406, 8844726, 18474211, -1361450, -13062696, 13821877 }, + { -6455177, -7839871, 3374702, -4740862, -27098617, -10571707, 31655028, -7212327, 18853322, -14220951 }, + { 4566830, -12963868, -28974889, -12240689, -7602672, -2830569, -8514358, -10431137, 2207753, -3209784 } +}, +{ + { -25154831, -4185821, 29681144, 7868801, -6854661, -9423865, -12437364, -663000, -31111463, -16132436 }, + { 25576264, -2703214, 7349804, -11814844, 16472782, 9300885, 3844789, 15725684, 171356, 6466918 }, + { 23103977, 13316479, 9739013, -16149481, 817875, -15038942, 8965339, -14088058, -30714912, 16193877 } +}, +{ + { -33521811, 3180713, -2394130, 14003687, -16903474, -16270840, 17238398, 4729455, -18074513, 9256800 }, + { -25182317, -4174131, 32336398, 5036987, -21236817, 11360617, 22616405, 9761698, -19827198, 630305 }, + { -13720693, 2639453, -24237460, -7406481, 9494427, -5774029, -6554551, -15960994, -2449256, -14291300 } +}, +{ + { -3151181, -5046075, 9282714, 6866145, -31907062, -863023, -18940575, 15033784, 25105118, -7894876 }, + { -24326370, 15950226, -31801215, -14592823, -11662737, -5090925, 1573892, -2625887, 2198790, -15804619 }, + { -3099351, 10324967, -2241613, 7453183, -5446979, -2735503, -13812022, -16236442, -32461234, -12290683 } +} diff --git a/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/constants.h b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/constants.h new file mode 100644 index 0000000..dd6da1b --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/constants.h @@ -0,0 +1,40 @@ +/* 37095705934669439343138083508754565189542113879843219016388785533085940283555 */ +static const fe25519 d = { + -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116 +}; + +/* 2 * d = + * 16295367250680780974490674513165176452449235426866156013048779062215315747161 + */ +static const fe25519 d2 = { + -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 }; + +/* sqrt(-1) */ +static const fe25519 sqrtm1 = { + -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 +}; + +/* A = 486662 */ +static const fe25519 curve25519_A = { + 486662, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* sqrt(ad - 1) with a = -1 (mod p) */ +static const fe25519 sqrtadm1 = { + 24849947, -153582, -23613485, 6347715, -21072328, -667138, -25271143, -15367704, -870347, 14525639 +}; + +/* 1 / sqrt(a - d) */ +static const fe25519 invsqrtamd = { + 6111485, 4156064, -27798727, 12243468, -25904040, 120897, 20826367, -7060776, 6093568, -1986012 +}; + +/* 1 - d ^ 2 */ +static const fe25519 onemsqd = { + 6275446, -16617371, -22938544, -3773710, 11667077, 7397348, -27922721, 1766195, -24433858, 672203 +}; + +/* (d - 1) ^ 2 */ +static const fe25519 sqdmone = { + 15551795, -11097455, -13425098, -10125071, -11896535, 10178284, -26634327, 4729244, -5282110, -10116402 +}; diff --git a/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/fe.h b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/fe.h new file mode 100644 index 0000000..f216669 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_25_5/fe.h @@ -0,0 +1,220 @@ +/* + Ignores top bit of h. + */ + +void +fe25519_frombytes(fe25519 h, const unsigned char *s) +{ + int64_t h0 = load_4(s); + int64_t h1 = load_3(s + 4) << 6; + int64_t h2 = load_3(s + 7) << 5; + int64_t h3 = load_3(s + 10) << 3; + int64_t h4 = load_3(s + 13) << 2; + int64_t h5 = load_4(s + 16); + int64_t h6 = load_3(s + 20) << 7; + int64_t h7 = load_3(s + 23) << 5; + int64_t h8 = load_3(s + 26) << 4; + int64_t h9 = (load_3(s + 29) & 8388607) << 2; + + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry9 = (h9 + (int64_t)(1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= carry9 * ((uint64_t) 1L << 25); + carry1 = (h1 + (int64_t)(1L << 24)) >> 25; + h2 += carry1; + h1 -= carry1 * ((uint64_t) 1L << 25); + carry3 = (h3 + (int64_t)(1L << 24)) >> 25; + h4 += carry3; + h3 -= carry3 * ((uint64_t) 1L << 25); + carry5 = (h5 + (int64_t)(1L << 24)) >> 25; + h6 += carry5; + h5 -= carry5 * ((uint64_t) 1L << 25); + carry7 = (h7 + (int64_t)(1L << 24)) >> 25; + h8 += carry7; + h7 -= carry7 * ((uint64_t) 1L << 25); + + carry0 = (h0 + (int64_t)(1L << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((uint64_t) 1L << 26); + carry2 = (h2 + (int64_t)(1L << 25)) >> 26; + h3 += carry2; + h2 -= carry2 * ((uint64_t) 1L << 26); + carry4 = (h4 + (int64_t)(1L << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((uint64_t) 1L << 26); + carry6 = (h6 + (int64_t)(1L << 25)) >> 26; + h7 += carry6; + h6 -= carry6 * ((uint64_t) 1L << 26); + carry8 = (h8 + (int64_t)(1L << 25)) >> 26; + h9 += carry8; + h8 -= carry8 * ((uint64_t) 1L << 26); + + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; +} + +/* + Preconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + + Write p=2^255-19; q=floor(h/p). + Basic claim: q = floor(2^(-255)(h + 19 2^(-25)h9 + 2^(-1))). + + Proof: + Have |h|<=p so |q|<=1 so |19^2 2^(-255) q|<1/4. + Also have |h-2^230 h9|<2^231 so |19 2^(-255)(h-2^230 h9)|<1/4. + + Write y=2^(-1)-19^2 2^(-255)q-19 2^(-255)(h-2^230 h9). + Then 0> 25; + q = (h0 + q) >> 26; + q = (h1 + q) >> 25; + q = (h2 + q) >> 26; + q = (h3 + q) >> 25; + q = (h4 + q) >> 26; + q = (h5 + q) >> 25; + q = (h6 + q) >> 26; + q = (h7 + q) >> 25; + q = (h8 + q) >> 26; + q = (h9 + q) >> 25; + + /* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */ + h0 += 19 * q; + /* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */ + + carry0 = h0 >> 26; + h1 += carry0; + h0 -= carry0 * ((uint32_t) 1L << 26); + carry1 = h1 >> 25; + h2 += carry1; + h1 -= carry1 * ((uint32_t) 1L << 25); + carry2 = h2 >> 26; + h3 += carry2; + h2 -= carry2 * ((uint32_t) 1L << 26); + carry3 = h3 >> 25; + h4 += carry3; + h3 -= carry3 * ((uint32_t) 1L << 25); + carry4 = h4 >> 26; + h5 += carry4; + h4 -= carry4 * ((uint32_t) 1L << 26); + carry5 = h5 >> 25; + h6 += carry5; + h5 -= carry5 * ((uint32_t) 1L << 25); + carry6 = h6 >> 26; + h7 += carry6; + h6 -= carry6 * ((uint32_t) 1L << 26); + carry7 = h7 >> 25; + h8 += carry7; + h7 -= carry7 * ((uint32_t) 1L << 25); + carry8 = h8 >> 26; + h9 += carry8; + h8 -= carry8 * ((uint32_t) 1L << 26); + carry9 = h9 >> 25; + h9 -= carry9 * ((uint32_t) 1L << 25); + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* + Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20. + Have h0+...+2^230 h9 between 0 and 2^255-1; + evidently 2^255 h10-2^255 q = 0. + + Goal: Output h0+...+2^230 h9. + */ + +void +fe25519_tobytes(unsigned char *s, const fe25519 h) +{ + fe25519 t; + + fe25519_reduce(t, h); + s[0] = t[0] >> 0; + s[1] = t[0] >> 8; + s[2] = t[0] >> 16; + s[3] = (t[0] >> 24) | (t[1] * ((uint32_t) 1 << 2)); + s[4] = t[1] >> 6; + s[5] = t[1] >> 14; + s[6] = (t[1] >> 22) | (t[2] * ((uint32_t) 1 << 3)); + s[7] = t[2] >> 5; + s[8] = t[2] >> 13; + s[9] = (t[2] >> 21) | (t[3] * ((uint32_t) 1 << 5)); + s[10] = t[3] >> 3; + s[11] = t[3] >> 11; + s[12] = (t[3] >> 19) | (t[4] * ((uint32_t) 1 << 6)); + s[13] = t[4] >> 2; + s[14] = t[4] >> 10; + s[15] = t[4] >> 18; + s[16] = t[5] >> 0; + s[17] = t[5] >> 8; + s[18] = t[5] >> 16; + s[19] = (t[5] >> 24) | (t[6] * ((uint32_t) 1 << 1)); + s[20] = t[6] >> 7; + s[21] = t[6] >> 15; + s[22] = (t[6] >> 23) | (t[7] * ((uint32_t) 1 << 3)); + s[23] = t[7] >> 5; + s[24] = t[7] >> 13; + s[25] = (t[7] >> 21) | (t[8] * ((uint32_t) 1 << 4)); + s[26] = t[8] >> 4; + s[27] = t[8] >> 12; + s[28] = (t[8] >> 20) | (t[9] * ((uint32_t) 1 << 6)); + s[29] = t[9] >> 2; + s[30] = t[9] >> 10; + s[31] = t[9] >> 18; +} diff --git a/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/base.h b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/base.h new file mode 100644 index 0000000..6b3b833 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/base.h @@ -0,0 +1,1344 @@ +{ /* 0/31 */ + { + { 1288382639258501, 245678601348599, 269427782077623, 1462984067271730, 137412439391563 }, + { 62697248952638, 204681361388450, 631292143396476, 338455783676468, 1213667448819585 }, + { 301289933810280, 1259582250014073, 1422107436869536, 796239922652654, 1953934009299142 } + }, + { + { 1380971894829527, 790832306631236, 2067202295274102, 1995808275510000, 1566530869037010 }, + { 463307831301544, 432984605774163, 1610641361907204, 750899048855000, 1894842303421586 }, + { 748439484463711, 1033211726465151, 1396005112841647, 1611506220286469, 1972177495910992 } + }, + { + { 1601611775252272, 1720807796594148, 1132070835939856, 1260455018889551, 2147779492816911 }, + { 316559037616741, 2177824224946892, 1459442586438991, 1461528397712656, 751590696113597 }, + { 1850748884277385, 1200145853858453, 1068094770532492, 672251375690438, 1586055907191707 } + }, + { + { 934282339813791, 1846903124198670, 1172395437954843, 1007037127761661, 1830588347719256 }, + { 1694390458783935, 1735906047636159, 705069562067493, 648033061693059, 696214010414170 }, + { 1121406372216585, 192876649532226, 190294192191717, 1994165897297032, 2245000007398739 } + }, + { + { 769950342298419, 132954430919746, 844085933195555, 974092374476333, 726076285546016 }, + { 425251763115706, 608463272472562, 442562545713235, 837766094556764, 374555092627893 }, + { 1086255230780037, 274979815921559, 1960002765731872, 929474102396301, 1190409889297339 } + }, + { + { 1388594989461809, 316767091099457, 394298842192982, 1230079486801005, 1440737038838979 }, + { 7380825640100, 146210432690483, 304903576448906, 1198869323871120, 997689833219095 }, + { 1181317918772081, 114573476638901, 262805072233344, 265712217171332, 294181933805782 } + }, + { + { 665000864555967, 2065379846933859, 370231110385876, 350988370788628, 1233371373142985 }, + { 2019367628972465, 676711900706637, 110710997811333, 1108646842542025, 517791959672113 }, + { 965130719900578, 247011430587952, 526356006571389, 91986625355052, 2157223321444601 } + }, + { + { 2068619540119183, 1966274918058806, 957728544705549, 729906502578991, 159834893065166 }, + { 2073601412052185, 31021124762708, 264500969797082, 248034690651703, 1030252227928288 }, + { 551790716293402, 1989538725166328, 801169423371717, 2052451893578887, 678432056995012 } + } +}, +{ /* 1/31 */ + { + { 1368953770187805, 790347636712921, 437508475667162, 2142576377050580, 1932081720066286 }, + { 953638594433374, 1092333936795051, 1419774766716690, 805677984380077, 859228993502513 }, + { 1200766035879111, 20142053207432, 1465634435977050, 1645256912097844, 295121984874596 } + }, + { + { 1735718747031557, 1248237894295956, 1204753118328107, 976066523550493, 65943769534592 }, + { 1060098822528990, 1586825862073490, 212301317240126, 1975302711403555, 666724059764335 }, + { 1091990273418756, 1572899409348578, 80968014455247, 306009358661350, 1520450739132526 } + }, + { + { 1480517209436112, 1511153322193952, 1244343858991172, 304788150493241, 369136856496443 }, + { 2151330273626164, 762045184746182, 1688074332551515, 823046109005759, 907602769079491 }, + { 2047386910586836, 168470092900250, 1552838872594810, 340951180073789, 360819374702533 } + }, + { + { 1982622644432056, 2014393600336956, 128909208804214, 1617792623929191, 105294281913815 }, + { 980234343912898, 1712256739246056, 588935272190264, 204298813091998, 841798321043288 }, + { 197561292938973, 454817274782871, 1963754960082318, 2113372252160468, 971377527342673 } + }, + { + { 164699448829328, 3127451757672, 1199504971548753, 1766155447043652, 1899238924683527 }, + { 732262946680281, 1674412764227063, 2182456405662809, 1350894754474250, 558458873295247 }, + { 2103305098582922, 1960809151316468, 715134605001343, 1454892949167181, 40827143824949 } + }, + { + { 1239289043050212, 1744654158124578, 758702410031698, 1796762995074688, 1603056663766 }, + { 2232056027107988, 987343914584615, 2115594492994461, 1819598072792159, 1119305654014850 }, + { 320153677847348, 939613871605645, 641883205761567, 1930009789398224, 329165806634126 } + }, + { + { 980930490474130, 1242488692177893, 1251446316964684, 1086618677993530, 1961430968465772 }, + { 276821765317453, 1536835591188030, 1305212741412361, 61473904210175, 2051377036983058 }, + { 833449923882501, 1750270368490475, 1123347002068295, 185477424765687, 278090826653186 } + }, + { + { 794524995833413, 1849907304548286, 53348672473145, 1272368559505217, 1147304168324779 }, + { 1504846112759364, 1203096289004681, 562139421471418, 274333017451844, 1284344053775441 }, + { 483048732424432, 2116063063343382, 30120189902313, 292451576741007, 1156379271702225 } + } +}, +{ /* 2/31 */ + { + { 928372153029038, 2147692869914564, 1455665844462196, 1986737809425946, 185207050258089 }, + { 137732961814206, 706670923917341, 1387038086865771, 1965643813686352, 1384777115696347 }, + { 481144981981577, 2053319313589856, 2065402289827512, 617954271490316, 1106602634668125 } + }, + { + { 696298019648792, 893299659040895, 1148636718636009, 26734077349617, 2203955659340681 }, + { 657390353372855, 998499966885562, 991893336905797, 810470207106761, 343139804608786 }, + { 791736669492960, 934767652997115, 824656780392914, 1759463253018643, 361530362383518 } + }, + { + { 2022541353055597, 2094700262587466, 1551008075025686, 242785517418164, 695985404963562 }, + { 1287487199965223, 2215311941380308, 1552928390931986, 1664859529680196, 1125004975265243 }, + { 677434665154918, 989582503122485, 1817429540898386, 1052904935475344, 1143826298169798 } + }, + { + { 367266328308408, 318431188922404, 695629353755355, 634085657580832, 24581612564426 }, + { 773360688841258, 1815381330538070, 363773437667376, 539629987070205, 783280434248437 }, + { 180820816194166, 168937968377394, 748416242794470, 1227281252254508, 1567587861004268 } + }, + { + { 478775558583645, 2062896624554807, 699391259285399, 358099408427873, 1277310261461761 }, + { 1984740906540026, 1079164179400229, 1056021349262661, 1659958556483663, 1088529069025527 }, + { 580736401511151, 1842931091388998, 1177201471228238, 2075460256527244, 1301133425678027 } + }, + { + { 1515728832059182, 1575261009617579, 1510246567196186, 191078022609704, 116661716289141 }, + { 1295295738269652, 1714742313707026, 545583042462581, 2034411676262552, 1513248090013606 }, + { 230710545179830, 30821514358353, 760704303452229, 390668103790604, 573437871383156 } + }, + { + { 1169380107545646, 263167233745614, 2022901299054448, 819900753251120, 2023898464874585 }, + { 2102254323485823, 1570832666216754, 34696906544624, 1993213739807337, 70638552271463 }, + { 894132856735058, 548675863558441, 845349339503395, 1942269668326667, 1615682209874691 } + }, + { + { 1287670217537834, 1222355136884920, 1846481788678694, 1150426571265110, 1613523400722047 }, + { 793388516527298, 1315457083650035, 1972286999342417, 1901825953052455, 338269477222410 }, + { 550201530671806, 778605267108140, 2063911101902983, 115500557286349, 2041641272971022 } + } +}, +{ /* 3/31 */ + { + { 717255318455100, 519313764361315, 2080406977303708, 541981206705521, 774328150311600 }, + { 261715221532238, 1795354330069993, 1496878026850283, 499739720521052, 389031152673770 }, + { 1997217696294013, 1717306351628065, 1684313917746180, 1644426076011410, 1857378133465451 } + }, + { + { 1475434724792648, 76931896285979, 1116729029771667, 2002544139318042, 725547833803938 }, + { 2022306639183567, 726296063571875, 315345054448644, 1058733329149221, 1448201136060677 }, + { 1710065158525665, 1895094923036397, 123988286168546, 1145519900776355, 1607510767693874 } + }, + { + { 561605375422540, 1071733543815037, 131496498800990, 1946868434569999, 828138133964203 }, + { 1548495173745801, 442310529226540, 998072547000384, 553054358385281, 644824326376171 }, + { 1445526537029440, 2225519789662536, 914628859347385, 1064754194555068, 1660295614401091 } + }, + { + { 1199690223111956, 24028135822341, 66638289244341, 57626156285975, 565093967979607 }, + { 876926774220824, 554618976488214, 1012056309841565, 839961821554611, 1414499340307677 }, + { 703047626104145, 1266841406201770, 165556500219173, 486991595001879, 1011325891650656 } + }, + { + { 1622861044480487, 1156394801573634, 1869132565415504, 327103985777730, 2095342781472284 }, + { 334886927423922, 489511099221528, 129160865966726, 1720809113143481, 619700195649254 }, + { 1646545795166119, 1758370782583567, 714746174550637, 1472693650165135, 898994790308209 } + }, + { + { 333403773039279, 295772542452938, 1693106465353610, 912330357530760, 471235657950362 }, + { 1811196219982022, 1068969825533602, 289602974833439, 1988956043611592, 863562343398367 }, + { 906282429780072, 2108672665779781, 432396390473936, 150625823801893, 1708930497638539 } + }, + { + { 925664675702328, 21416848568684, 1831436641861340, 601157008940113, 371818055044496 }, + { 1479786007267725, 1738881859066675, 68646196476567, 2146507056100328, 1247662817535471 }, + { 52035296774456, 939969390708103, 312023458773250, 59873523517659, 1231345905848899 } + }, + { + { 643355106415761, 290186807495774, 2013561737429023, 319648069511546, 393736678496162 }, + { 129358342392716, 1932811617704777, 1176749390799681, 398040349861790, 1170779668090425 }, + { 2051980782668029, 121859921510665, 2048329875753063, 1235229850149665, 519062146124755 } + } +}, +{ /* 4/31 */ + { + { 1608170971973096, 415809060360428, 1350468408164766, 2038620059057678, 1026904485989112 }, + { 1837656083115103, 1510134048812070, 906263674192061, 1821064197805734, 565375124676301 }, + { 578027192365650, 2034800251375322, 2128954087207123, 478816193810521, 2196171989962750 } + }, + { + { 1633188840273139, 852787172373708, 1548762607215796, 1266275218902681, 1107218203325133 }, + { 462189358480054, 1784816734159228, 1611334301651368, 1303938263943540, 707589560319424 }, + { 1038829280972848, 38176604650029, 753193246598573, 1136076426528122, 595709990562434 } + }, + { + { 1408451820859834, 2194984964010833, 2198361797561729, 1061962440055713, 1645147963442934 }, + { 4701053362120, 1647641066302348, 1047553002242085, 1923635013395977, 206970314902065 }, + { 1750479161778571, 1362553355169293, 1891721260220598, 966109370862782, 1024913988299801 } + }, + { + { 212699049131723, 1117950018299775, 1873945661751056, 1403802921984058, 130896082652698 }, + { 636808533673210, 1262201711667560, 390951380330599, 1663420692697294, 561951321757406 }, + { 520731594438141, 1446301499955692, 273753264629267, 1565101517999256, 1019411827004672 } + }, + { + { 926527492029409, 1191853477411379, 734233225181171, 184038887541270, 1790426146325343 }, + { 1464651961852572, 1483737295721717, 1519450561335517, 1161429831763785, 405914998179977 }, + { 996126634382301, 796204125879525, 127517800546509, 344155944689303, 615279846169038 } + }, + { + { 738724080975276, 2188666632415296, 1961313708559162, 1506545807547587, 1151301638969740 }, + { 622917337413835, 1218989177089035, 1284857712846592, 970502061709359, 351025208117090 }, + { 2067814584765580, 1677855129927492, 2086109782475197, 235286517313238, 1416314046739645 } + }, + { + { 586844262630358, 307444381952195, 458399356043426, 602068024507062, 1028548203415243 }, + { 678489922928203, 2016657584724032, 90977383049628, 1026831907234582, 615271492942522 }, + { 301225714012278, 1094837270268560, 1202288391010439, 644352775178361, 1647055902137983 } + }, + { + { 1210746697896478, 1416608304244708, 686487477217856, 1245131191434135, 1051238336855737 }, + { 1135604073198207, 1683322080485474, 769147804376683, 2086688130589414, 900445683120379 }, + { 1971518477615628, 401909519527336, 448627091057375, 1409486868273821, 1214789035034363 } + } +}, +{ /* 5/31 */ + { + { 1364039144731711, 1897497433586190, 2203097701135459, 145461396811251, 1349844460790699 }, + { 1045230323257973, 818206601145807, 630513189076103, 1672046528998132, 807204017562437 }, + { 439961968385997, 386362664488986, 1382706320807688, 309894000125359, 2207801346498567 } + }, + { + { 1229004686397588, 920643968530863, 123975893911178, 681423993215777, 1400559197080973 }, + { 2003766096898049, 170074059235165, 1141124258967971, 1485419893480973, 1573762821028725 }, + { 729905708611432, 1270323270673202, 123353058984288, 426460209632942, 2195574535456672 } + }, + { + { 1271140255321235, 2044363183174497, 52125387634689, 1445120246694705, 942541986339084 }, + { 1761608437466135, 583360847526804, 1586706389685493, 2157056599579261, 1170692369685772 }, + { 871476219910823, 1878769545097794, 2241832391238412, 548957640601001, 690047440233174 } + }, + { + { 297194732135507, 1366347803776820, 1301185512245601, 561849853336294, 1533554921345731 }, + { 999628998628371, 1132836708493400, 2084741674517453, 469343353015612, 678782988708035 }, + { 2189427607417022, 699801937082607, 412764402319267, 1478091893643349, 2244675696854460 } + }, + { + { 1712292055966563, 204413590624874, 1405738637332841, 408981300829763, 861082219276721 }, + { 508561155940631, 966928475686665, 2236717801150132, 424543858577297, 2089272956986143 }, + { 221245220129925, 1156020201681217, 491145634799213, 542422431960839, 828100817819207 } + }, + { + { 153756971240384, 1299874139923977, 393099165260502, 1058234455773022, 996989038681183 }, + { 559086812798481, 573177704212711, 1629737083816402, 1399819713462595, 1646954378266038 }, + { 1887963056288059, 228507035730124, 1468368348640282, 930557653420194, 613513962454686 } + }, + { + { 1224529808187553, 1577022856702685, 2206946542980843, 625883007765001, 279930793512158 }, + { 1076287717051609, 1114455570543035, 187297059715481, 250446884292121, 1885187512550540 }, + { 902497362940219, 76749815795675, 1657927525633846, 1420238379745202, 1340321636548352 } + }, + { + { 1129576631190784, 1281994010027327, 996844254743018, 257876363489249, 1150850742055018 }, + { 628740660038789, 1943038498527841, 467786347793886, 1093341428303375, 235413859513003 }, + { 237425418909360, 469614029179605, 1512389769174935, 1241726368345357, 441602891065214 } + } +}, +{ /* 6/31 */ + { + { 1736417953058555, 726531315520508, 1833335034432527, 1629442561574747, 624418919286085 }, + { 1960754663920689, 497040957888962, 1909832851283095, 1271432136996826, 2219780368020940 }, + { 1537037379417136, 1358865369268262, 2130838645654099, 828733687040705, 1999987652890901 } + }, + { + { 629042105241814, 1098854999137608, 887281544569320, 1423102019874777, 7911258951561 }, + { 1811562332665373, 1501882019007673, 2213763501088999, 359573079719636, 36370565049116 }, + { 218907117361280, 1209298913016966, 1944312619096112, 1130690631451061, 1342327389191701 } + }, + { + { 1369976867854704, 1396479602419169, 1765656654398856, 2203659200586299, 998327836117241 }, + { 2230701885562825, 1348173180338974, 2172856128624598, 1426538746123771, 444193481326151 }, + { 784210426627951, 918204562375674, 1284546780452985, 1324534636134684, 1872449409642708 } + }, + { + { 319638829540294, 596282656808406, 2037902696412608, 1557219121643918, 341938082688094 }, + { 1901860206695915, 2004489122065736, 1625847061568236, 973529743399879, 2075287685312905 }, + { 1371853944110545, 1042332820512553, 1949855697918254, 1791195775521505, 37487364849293 } + }, + { + { 687200189577855, 1082536651125675, 644224940871546, 340923196057951, 343581346747396 }, + { 2082717129583892, 27829425539422, 145655066671970, 1690527209845512, 1865260509673478 }, + { 1059729620568824, 2163709103470266, 1440302280256872, 1769143160546397, 869830310425069 } + }, + { + { 1609516219779025, 777277757338817, 2101121130363987, 550762194946473, 1905542338659364 }, + { 2024821921041576, 426948675450149, 595133284085473, 471860860885970, 600321679413000 }, + { 598474602406721, 1468128276358244, 1191923149557635, 1501376424093216, 1281662691293476 } + }, + { + { 1721138489890707, 1264336102277790, 433064545421287, 1359988423149466, 1561871293409447 }, + { 719520245587143, 393380711632345, 132350400863381, 1543271270810729, 1819543295798660 }, + { 396397949784152, 1811354474471839, 1362679985304303, 2117033964846756, 498041172552279 } + }, + { + { 1812471844975748, 1856491995543149, 126579494584102, 1036244859282620, 1975108050082550 }, + { 650623932407995, 1137551288410575, 2125223403615539, 1725658013221271, 2134892965117796 }, + { 522584000310195, 1241762481390450, 1743702789495384, 2227404127826575, 1686746002148897 } + } +}, +{ /* 7/31 */ + { + { 427904865186312, 1703211129693455, 1585368107547509, 1436984488744336, 761188534613978 }, + { 318101947455002, 248138407995851, 1481904195303927, 309278454311197, 1258516760217879 }, + { 1275068538599310, 513726919533379, 349926553492294, 688428871968420, 1702400196000666 } + }, + { + { 1061864036265233, 961611260325381, 321859632700838, 1045600629959517, 1985130202504038 }, + { 1558816436882417, 1962896332636523, 1337709822062152, 1501413830776938, 294436165831932 }, + { 818359826554971, 1862173000996177, 626821592884859, 573655738872376, 1749691246745455 } + }, + { + { 1988022651432119, 1082111498586040, 1834020786104821, 1454826876423687, 692929915223122 }, + { 2146513703733331, 584788900394667, 464965657279958, 2183973639356127, 238371159456790 }, + { 1129007025494441, 2197883144413266, 265142755578169, 971864464758890, 1983715884903702 } + }, + { + { 1291366624493075, 381456718189114, 1711482489312444, 1815233647702022, 892279782992467 }, + { 444548969917454, 1452286453853356, 2113731441506810, 645188273895859, 810317625309512 }, + { 2242724082797924, 1373354730327868, 1006520110883049, 2147330369940688, 1151816104883620 } + }, + { + { 1745720200383796, 1911723143175317, 2056329390702074, 355227174309849, 879232794371100 }, + { 163723479936298, 115424889803150, 1156016391581227, 1894942220753364, 1970549419986329 }, + { 681981452362484, 267208874112496, 1374683991933094, 638600984916117, 646178654558546 } + }, + { + { 13378654854251, 106237307029567, 1944412051589651, 1841976767925457, 230702819835573 }, + { 260683893467075, 854060306077237, 913639551980112, 4704576840123, 280254810808712 }, + { 715374893080287, 1173334812210491, 1806524662079626, 1894596008000979, 398905715033393 } + }, + { + { 500026409727661, 1596431288195371, 1420380351989370, 985211561521489, 392444930785633 }, + { 2096421546958141, 1922523000950363, 789831022876840, 427295144688779, 320923973161730 }, + { 1927770723575450, 1485792977512719, 1850996108474547, 551696031508956, 2126047405475647 } + }, + { + { 2112099158080148, 742570803909715, 6484558077432, 1951119898618916, 93090382703416 }, + { 383905201636970, 859946997631870, 855623867637644, 1017125780577795, 794250831877809 }, + { 77571826285752, 999304298101753, 487841111777762, 1038031143212339, 339066367948762 } + } +}, +{ /* 8/31 */ + { + { 674994775520533, 266035846330789, 826951213393478, 1405007746162285, 1781791018620876 }, + { 1001412661522686, 348196197067298, 1666614366723946, 888424995032760, 580747687801357 }, + { 1939560076207777, 1409892634407635, 552574736069277, 383854338280405, 190706709864139 } + }, + { + { 2177087163428741, 1439255351721944, 1208070840382793, 2230616362004769, 1396886392021913 }, + { 676962063230039, 1880275537148808, 2046721011602706, 888463247083003, 1318301552024067 }, + { 1466980508178206, 617045217998949, 652303580573628, 757303753529064, 207583137376902 } + }, + { + { 1511056752906902, 105403126891277, 493434892772846, 1091943425335976, 1802717338077427 }, + { 1853982405405128, 1878664056251147, 1528011020803992, 1019626468153565, 1128438412189035 }, + { 1963939888391106, 293456433791664, 697897559513649, 985882796904380, 796244541237972 } + }, + { + { 416770998629779, 389655552427054, 1314476859406756, 1749382513022778, 1161905598739491 }, + { 1428358296490651, 1027115282420478, 304840698058337, 441410174026628, 1819358356278573 }, + { 204943430200135, 1554861433819175, 216426658514651, 264149070665950, 2047097371738319 } + }, + { + { 1934415182909034, 1393285083565062, 516409331772960, 1157690734993892, 121039666594268 }, + { 662035583584445, 286736105093098, 1131773000510616, 818494214211439, 472943792054479 }, + { 665784778135882, 1893179629898606, 808313193813106, 276797254706413, 1563426179676396 } + }, + { + { 945205108984232, 526277562959295, 1324180513733566, 1666970227868664, 153547609289173 }, + { 2031433403516252, 203996615228162, 170487168837083, 981513604791390, 843573964916831 }, + { 1476570093962618, 838514669399805, 1857930577281364, 2017007352225784, 317085545220047 } + }, + { + { 1461557121912842, 1600674043318359, 2157134900399597, 1670641601940616, 127765583803283 }, + { 1293543509393474, 2143624609202546, 1058361566797508, 214097127393994, 946888515472729 }, + { 357067959932916, 1290876214345711, 521245575443703, 1494975468601005, 800942377643885 } + }, + { + { 566116659100033, 820247422481740, 994464017954148, 327157611686365, 92591318111744 }, + { 617256647603209, 1652107761099439, 1857213046645471, 1085597175214970, 817432759830522 }, + { 771808161440705, 1323510426395069, 680497615846440, 851580615547985, 1320806384849017 } + } +}, +{ /* 9/31 */ + { + { 1219260086131915, 647169006596815, 79601124759706, 2161724213426748, 404861897060198 }, + { 1327968293887866, 1335500852943256, 1401587164534264, 558137311952440, 1551360549268902 }, + { 417621685193956, 1429953819744454, 396157358457099, 1940470778873255, 214000046234152 } + }, + { + { 1268047918491973, 2172375426948536, 1533916099229249, 1761293575457130, 1590622667026765 }, + { 1627072914981959, 2211603081280073, 1912369601616504, 1191770436221309, 2187309757525860 }, + { 1149147819689533, 378692712667677, 828475842424202, 2218619146419342, 70688125792186 } + }, + { + { 1299739417079761, 1438616663452759, 1536729078504412, 2053896748919838, 1008421032591246 }, + { 2040723824657366, 399555637875075, 632543375452995, 872649937008051, 1235394727030233 }, + { 2211311599327900, 2139787259888175, 938706616835350, 12609661139114, 2081897930719789 } + }, + { + { 1324994503390450, 336982330582631, 1183998925654177, 1091654665913274, 48727673971319 }, + { 1845522914617879, 1222198248335542, 150841072760134, 1927029069940982, 1189913404498011 }, + { 1079559557592645, 2215338383666441, 1903569501302605, 49033973033940, 305703433934152 } + }, + { + { 94653405416909, 1386121349852999, 1062130477891762, 36553947479274, 833669648948846 }, + { 1432015813136298, 440364795295369, 1395647062821501, 1976874522764578, 934452372723352 }, + { 1296625309219774, 2068273464883862, 1858621048097805, 1492281814208508, 2235868981918946 } + }, + { + { 1490330266465570, 1858795661361448, 1436241134969763, 294573218899647, 1208140011028933 }, + { 1282462923712748, 741885683986255, 2027754642827561, 518989529541027, 1826610009555945 }, + { 1525827120027511, 723686461809551, 1597702369236987, 244802101764964, 1502833890372311 } + }, + { + { 113622036244513, 1233740067745854, 674109952278496, 2114345180342965, 166764512856263 }, + { 2041668749310338, 2184405322203901, 1633400637611036, 2110682505536899, 2048144390084644 }, + { 503058759232932, 760293024620937, 2027152777219493, 666858468148475, 1539184379870952 } + }, + { + { 1916168475367211, 915626432541343, 883217071712575, 363427871374304, 1976029821251593 }, + { 678039535434506, 570587290189340, 1605302676614120, 2147762562875701, 1706063797091704 }, + { 1439489648586438, 2194580753290951, 832380563557396, 561521973970522, 584497280718389 } + } +}, +{ /* 10/31 */ + { + { 187989455492609, 681223515948275, 1933493571072456, 1872921007304880, 488162364135671 }, + { 1413466089534451, 410844090765630, 1397263346404072, 408227143123410, 1594561803147811 }, + { 2102170800973153, 719462588665004, 1479649438510153, 1097529543970028, 1302363283777685 } + }, + { + { 942065717847195, 1069313679352961, 2007341951411051, 70973416446291, 1419433790163706 }, + { 1146565545556377, 1661971299445212, 406681704748893, 564452436406089, 1109109865829139 }, + { 2214421081775077, 1165671861210569, 1890453018796184, 3556249878661, 442116172656317 } + }, + { + { 753830546620811, 1666955059895019, 1530775289309243, 1119987029104146, 2164156153857580 }, + { 615171919212796, 1523849404854568, 854560460547503, 2067097370290715, 1765325848586042 }, + { 1094538949313667, 1796592198908825, 870221004284388, 2025558921863561, 1699010892802384 } + }, + { + { 1951351290725195, 1916457206844795, 198025184438026, 1909076887557595, 1938542290318919 }, + { 1014323197538413, 869150639940606, 1756009942696599, 1334952557375672, 1544945379082874 }, + { 764055910920305, 1603590757375439, 146805246592357, 1843313433854297, 954279890114939 } + }, + { + { 80113526615750, 764536758732259, 1055139345100233, 469252651759390, 617897512431515 }, + { 74497112547268, 740094153192149, 1745254631717581, 727713886503130, 1283034364416928 }, + { 525892105991110, 1723776830270342, 1476444848991936, 573789489857760, 133864092632978 } + }, + { + { 542611720192581, 1986812262899321, 1162535242465837, 481498966143464, 544600533583622 }, + { 64123227344372, 1239927720647794, 1360722983445904, 222610813654661, 62429487187991 }, + { 1793193323953132, 91096687857833, 70945970938921, 2158587638946380, 1537042406482111 } + }, + { + { 1895854577604609, 1394895708949416, 1728548428495944, 1140864900240149, 563645333603061 }, + { 141358280486863, 91435889572504, 1087208572552643, 1829599652522921, 1193307020643647 }, + { 1611230858525381, 950720175540785, 499589887488610, 2001656988495019, 88977313255908 } + }, + { + { 1189080501479658, 2184348804772597, 1040818725742319, 2018318290311834, 1712060030915354 }, + { 873966876953756, 1090638350350440, 1708559325189137, 672344594801910, 1320437969700239 }, + { 1508590048271766, 1131769479776094, 101550868699323, 428297785557897, 561791648661744 } + } +}, +{ /* 11/31 */ + { + { 756417570499462, 237882279232602, 2136263418594016, 1701968045454886, 703713185137472 }, + { 1781187809325462, 1697624151492346, 1381393690939988, 175194132284669, 1483054666415238 }, + { 2175517777364616, 708781536456029, 955668231122942, 1967557500069555, 2021208005604118 } + }, + { + { 1115135966606887, 224217372950782, 915967306279222, 593866251291540, 561747094208006 }, + { 1443163092879439, 391875531646162, 2180847134654632, 464538543018753, 1594098196837178 }, + { 850858855888869, 319436476624586, 327807784938441, 740785849558761, 17128415486016 } + }, + { + { 2132756334090067, 536247820155645, 48907151276867, 608473197600695, 1261689545022784 }, + { 1525176236978354, 974205476721062, 293436255662638, 148269621098039, 137961998433963 }, + { 1121075518299410, 2071745529082111, 1265567917414828, 1648196578317805, 496232102750820 } + }, + { + { 122321229299801, 1022922077493685, 2001275453369484, 2017441881607947, 993205880778002 }, + { 654925550560074, 1168810995576858, 575655959430926, 905758704861388, 496774564663534 }, + { 1954109525779738, 2117022646152485, 338102630417180, 1194140505732026, 107881734943492 } + }, + { + { 1714785840001267, 2036500018681589, 1876380234251966, 2056717182974196, 1645855254384642 }, + { 106431476499341, 62482972120563, 1513446655109411, 807258751769522, 538491469114 }, + { 2002850762893643, 1243624520538135, 1486040410574605, 2184752338181213, 378495998083531 } + }, + { + { 922510868424903, 1089502620807680, 402544072617374, 1131446598479839, 1290278588136533 }, + { 1867998812076769, 715425053580701, 39968586461416, 2173068014586163, 653822651801304 }, + { 162892278589453, 182585796682149, 75093073137630, 497037941226502, 133871727117371 } + }, + { + { 1914596576579670, 1608999621851578, 1987629837704609, 1519655314857977, 1819193753409464 }, + { 1949315551096831, 1069003344994464, 1939165033499916, 1548227205730856, 1933767655861407 }, + { 1730519386931635, 1393284965610134, 1597143735726030, 416032382447158, 1429665248828629 } + }, + { + { 360275475604565, 547835731063078, 215360904187529, 596646739879007, 332709650425085 }, + { 47602113726801, 1522314509708010, 437706261372925, 814035330438027, 335930650933545 }, + { 1291597595523886, 1058020588994081, 402837842324045, 1363323695882781, 2105763393033193 } + } +}, +{ /* 12/31 */ + { + { 109521982566564, 1715257748585139, 1112231216891516, 2046641005101484, 134249157157013 }, + { 2156991030936798, 2227544497153325, 1869050094431622, 754875860479115, 1754242344267058 }, + { 1846089562873800, 98894784984326, 1412430299204844, 171351226625762, 1100604760929008 } + }, + { + { 84172382130492, 499710970700046, 425749630620778, 1762872794206857, 612842602127960 }, + { 868309334532756, 1703010512741873, 1952690008738057, 4325269926064, 2071083554962116 }, + { 523094549451158, 401938899487815, 1407690589076010, 2022387426254453, 158660516411257 } + }, + { + { 612867287630009, 448212612103814, 571629077419196, 1466796750919376, 1728478129663858 }, + { 1723848973783452, 2208822520534681, 1718748322776940, 1974268454121942, 1194212502258141 }, + { 1254114807944608, 977770684047110, 2010756238954993, 1783628927194099, 1525962994408256 } + }, + { + { 232464058235826, 1948628555342434, 1835348780427694, 1031609499437291, 64472106918373 }, + { 767338676040683, 754089548318405, 1523192045639075, 435746025122062, 512692508440385 }, + { 1255955808701983, 1700487367990941, 1166401238800299, 1175121994891534, 1190934801395380 } + }, + { + { 349144008168292, 1337012557669162, 1475912332999108, 1321618454900458, 47611291904320 }, + { 877519947135419, 2172838026132651, 272304391224129, 1655143327559984, 886229406429814 }, + { 375806028254706, 214463229793940, 572906353144089, 572168269875638, 697556386112979 } + }, + { + { 1168827102357844, 823864273033637, 2071538752104697, 788062026895924, 599578340743362 }, + { 1948116082078088, 2054898304487796, 2204939184983900, 210526805152138, 786593586607626 }, + { 1915320147894736, 156481169009469, 655050471180417, 592917090415421, 2165897438660879 } + }, + { + { 1726336468579724, 1119932070398949, 1929199510967666, 33918788322959, 1836837863503150 }, + { 829996854845988, 217061778005138, 1686565909803640, 1346948817219846, 1723823550730181 }, + { 384301494966394, 687038900403062, 2211195391021739, 254684538421383, 1245698430589680 } + }, + { + { 1247567493562688, 1978182094455847, 183871474792955, 806570235643435, 288461518067916 }, + { 1449077384734201, 38285445457996, 2136537659177832, 2146493000841573, 725161151123125 }, + { 1201928866368855, 800415690605445, 1703146756828343, 997278587541744, 1858284414104014 } + } +}, +{ /* 13/31 */ + { + { 356468809648877, 782373916933152, 1718002439402870, 1392222252219254, 663171266061951 }, + { 759628738230460, 1012693474275852, 353780233086498, 246080061387552, 2030378857679162 }, + { 2040672435071076, 888593182036908, 1298443657189359, 1804780278521327, 354070726137060 } + }, + { + { 1894938527423184, 1463213041477277, 474410505497651, 247294963033299, 877975941029128 }, + { 207937160991127, 12966911039119, 820997788283092, 1010440472205286, 1701372890140810 }, + { 218882774543183, 533427444716285, 1233243976733245, 435054256891319, 1509568989549904 } + }, + { + { 1888838535711826, 1052177758340622, 1213553803324135, 169182009127332, 463374268115872 }, + { 299137589460312, 1594371588983567, 868058494039073, 257771590636681, 1805012993142921 }, + { 1806842755664364, 2098896946025095, 1356630998422878, 1458279806348064, 347755825962072 } + }, + { + { 1402334161391744, 1560083671046299, 1008585416617747, 1147797150908892, 1420416683642459 }, + { 665506704253369, 273770475169863, 799236974202630, 848328990077558, 1811448782807931 }, + { 1468412523962641, 771866649897997, 1931766110147832, 799561180078482, 524837559150077 } + }, + { + { 2223212657821850, 630416247363666, 2144451165500328, 816911130947791, 1024351058410032 }, + { 1266603897524861, 156378408858100, 1275649024228779, 447738405888420, 253186462063095 }, + { 2022215964509735, 136144366993649, 1800716593296582, 1193970603800203, 871675847064218 } + }, + { + { 1862751661970328, 851596246739884, 1519315554814041, 1542798466547449, 1417975335901520 }, + { 1228168094547481, 334133883362894, 587567568420081, 433612590281181, 603390400373205 }, + { 121893973206505, 1843345804916664, 1703118377384911, 497810164760654, 101150811654673 } + }, + { + { 458346255946468, 290909935619344, 1452768413850679, 550922875254215, 1537286854336538 }, + { 584322311184395, 380661238802118, 114839394528060, 655082270500073, 2111856026034852 }, + { 996965581008991, 2148998626477022, 1012273164934654, 1073876063914522, 1688031788934939 } + }, + { + { 923487018849600, 2085106799623355, 528082801620136, 1606206360876188, 735907091712524 }, + { 1697697887804317, 1335343703828273, 831288615207040, 949416685250051, 288760277392022 }, + { 1419122478109648, 1325574567803701, 602393874111094, 2107893372601700, 1314159682671307 } + } +}, +{ /* 14/31 */ + { + { 2201150872731804, 2180241023425241, 97663456423163, 1633405770247824, 848945042443986 }, + { 1173339555550611, 818605084277583, 47521504364289, 924108720564965, 735423405754506 }, + { 830104860549448, 1886653193241086, 1600929509383773, 1475051275443631, 286679780900937 } + }, + { + { 1577111294832995, 1030899169768747, 144900916293530, 1964672592979567, 568390100955250 }, + { 278388655910247, 487143369099838, 927762205508727, 181017540174210, 1616886700741287 }, + { 1191033906638969, 940823957346562, 1606870843663445, 861684761499847, 658674867251089 } + }, + { + { 1875032594195546, 1427106132796197, 724736390962158, 901860512044740, 635268497268760 }, + { 622869792298357, 1903919278950367, 1922588621661629, 1520574711600434, 1087100760174640 }, + { 25465949416618, 1693639527318811, 1526153382657203, 125943137857169, 145276964043999 } + }, + { + { 214739857969358, 920212862967915, 1939901550972269, 1211862791775221, 85097515720120 }, + { 2006245852772938, 734762734836159, 254642929763427, 1406213292755966, 239303749517686 }, + { 1619678837192149, 1919424032779215, 1357391272956794, 1525634040073113, 1310226789796241 } + }, + { + { 1040763709762123, 1704449869235352, 605263070456329, 1998838089036355, 1312142911487502 }, + { 1996723311435669, 1844342766567060, 985455700466044, 1165924681400960, 311508689870129 }, + { 43173156290518, 2202883069785309, 1137787467085917, 1733636061944606, 1394992037553852 } + }, + { + { 670078326344559, 555655025059356, 471959386282438, 2141455487356409, 849015953823125 }, + { 2197214573372804, 794254097241315, 1030190060513737, 267632515541902, 2040478049202624 }, + { 1812516004670529, 1609256702920783, 1706897079364493, 258549904773295, 996051247540686 } + }, + { + { 1540374301420584, 1764656898914615, 1810104162020396, 923808779163088, 664390074196579 }, + { 1323460699404750, 1262690757880991, 871777133477900, 1060078894988977, 1712236889662886 }, + { 1696163952057966, 1391710137550823, 608793846867416, 1034391509472039, 1780770894075012 } + }, + { + { 1367603834210841, 2131988646583224, 890353773628144, 1908908219165595, 270836895252891 }, + { 597536315471731, 40375058742586, 1942256403956049, 1185484645495932, 312666282024145 }, + { 1919411405316294, 1234508526402192, 1066863051997083, 1008444703737597, 1348810787701552 } + } +}, +{ /* 15/31 */ + { + { 2102881477513865, 1570274565945361, 1573617900503708, 18662635732583, 2232324307922098 }, + { 1853931367696942, 8107973870707, 350214504129299, 775206934582587, 1752317649166792 }, + { 1417148368003523, 721357181628282, 505725498207811, 373232277872983, 261634707184480 } + }, + { + { 2186733281493267, 2250694917008620, 1014829812957440, 479998161452389, 83566193876474 }, + { 1268116367301224, 560157088142809, 802626839600444, 2210189936605713, 1129993785579988 }, + { 615183387352312, 917611676109240, 878893615973325, 978940963313282, 938686890583575 } + }, + { + { 522024729211672, 1045059315315808, 1892245413707790, 1907891107684253, 2059998109500714 }, + { 1799679152208884, 912132775900387, 25967768040979, 432130448590461, 274568990261996 }, + { 98698809797682, 2144627600856209, 1907959298569602, 811491302610148, 1262481774981493 } + }, + { + { 1791451399743152, 1713538728337276, 118349997257490, 1882306388849954, 158235232210248 }, + { 1217809823321928, 2173947284933160, 1986927836272325, 1388114931125539, 12686131160169 }, + { 1650875518872272, 1136263858253897, 1732115601395988, 734312880662190, 1252904681142109 } + }, + { + { 372986456113865, 525430915458171, 2116279931702135, 501422713587815, 1907002872974925 }, + { 803147181835288, 868941437997146, 316299302989663, 943495589630550, 571224287904572 }, + { 227742695588364, 1776969298667369, 628602552821802, 457210915378118, 2041906378111140 } + }, + { + { 815000523470260, 913085688728307, 1052060118271173, 1345536665214223, 541623413135555 }, + { 1580216071604333, 1877997504342444, 857147161260913, 703522726778478, 2182763974211603 }, + { 1870080310923419, 71988220958492, 1783225432016732, 615915287105016, 1035570475990230 } + }, + { + { 730987750830150, 857613889540280, 1083813157271766, 1002817255970169, 1719228484436074 }, + { 377616581647602, 1581980403078513, 804044118130621, 2034382823044191, 643844048472185 }, + { 176957326463017, 1573744060478586, 528642225008045, 1816109618372371, 1515140189765006 } + }, + { + { 1888911448245718, 1387110895611080, 1924503794066429, 1731539523700949, 2230378382645454 }, + { 443392177002051, 233793396845137, 2199506622312416, 1011858706515937, 974676837063129 }, + { 1846351103143623, 1949984838808427, 671247021915253, 1946756846184401, 1929296930380217 } + } +}, +{ /* 16/31 */ + { + { 849646212452002, 1410198775302919, 73767886183695, 1641663456615812, 762256272452411 }, + { 692017667358279, 723305578826727, 1638042139863265, 748219305990306, 334589200523901 }, + { 22893968530686, 2235758574399251, 1661465835630252, 925707319443452, 1203475116966621 } + }, + { + { 801299035785166, 1733292596726131, 1664508947088596, 467749120991922, 1647498584535623 }, + { 903105258014366, 427141894933047, 561187017169777, 1884330244401954, 1914145708422219 }, + { 1344191060517578, 1960935031767890, 1518838929955259, 1781502350597190, 1564784025565682 } + }, + { + { 673723351748086, 1979969272514923, 1175287312495508, 1187589090978666, 1881897672213940 }, + { 1917185587363432, 1098342571752737, 5935801044414, 2000527662351839, 1538640296181569 }, + { 2495540013192, 678856913479236, 224998292422872, 219635787698590, 1972465269000940 } + }, + { + { 271413961212179, 1353052061471651, 344711291283483, 2014925838520662, 2006221033113941 }, + { 194583029968109, 514316781467765, 829677956235672, 1676415686873082, 810104584395840 }, + { 1980510813313589, 1948645276483975, 152063780665900, 129968026417582, 256984195613935 } + }, + { + { 1860190562533102, 1936576191345085, 461100292705964, 1811043097042830, 957486749306835 }, + { 796664815624365, 1543160838872951, 1500897791837765, 1667315977988401, 599303877030711 }, + { 1151480509533204, 2136010406720455, 738796060240027, 319298003765044, 1150614464349587 } + }, + { + { 1731069268103150, 735642447616087, 1364750481334268, 417232839982871, 927108269127661 }, + { 1017222050227968, 1987716148359, 2234319589635701, 621282683093392, 2132553131763026 }, + { 1567828528453324, 1017807205202360, 565295260895298, 829541698429100, 307243822276582 } + }, + { + { 249079270936248, 1501514259790706, 947909724204848, 944551802437487, 552658763982480 }, + { 2089966982947227, 1854140343916181, 2151980759220007, 2139781292261749, 158070445864917 }, + { 1338766321464554, 1906702607371284, 1519569445519894, 115384726262267, 1393058953390992 } + }, + { + { 1364621558265400, 1512388234908357, 1926731583198686, 2041482526432505, 920401122333774 }, + { 1884844597333588, 601480070269079, 620203503079537, 1079527400117915, 1202076693132015 }, + { 840922919763324, 727955812569642, 1303406629750194, 522898432152867, 294161410441865 } + } +}, +{ /* 17/31 */ + { + { 353760790835310, 1598361541848743, 1122905698202299, 1922533590158905, 419107700666580 }, + { 359856369838236, 180914355488683, 861726472646627, 218807937262986, 575626773232501 }, + { 755467689082474, 909202735047934, 730078068932500, 936309075711518, 2007798262842972 } + }, + { + { 1609384177904073, 362745185608627, 1335318541768201, 800965770436248, 547877979267412 }, + { 984339177776787, 815727786505884, 1645154585713747, 1659074964378553, 1686601651984156 }, + { 1697863093781930, 599794399429786, 1104556219769607, 830560774794755, 12812858601017 } + }, + { + { 1168737550514982, 897832437380552, 463140296333799, 302564600022547, 2008360505135501 }, + { 1856930662813910, 678090852002597, 1920179140755167, 1259527833759868, 55540971895511 }, + { 1158643631044921, 476554103621892, 178447851439725, 1305025542653569, 103433927680625 } + }, + { + { 2176793111709008, 1576725716350391, 2009350167273523, 2012390194631546, 2125297410909580 }, + { 825403285195098, 2144208587560784, 1925552004644643, 1915177840006985, 1015952128947864 }, + { 1807108316634472, 1534392066433717, 347342975407218, 1153820745616376, 7375003497471 } + }, + { + { 983061001799725, 431211889901241, 2201903782961093, 817393911064341, 2214616493042167 }, + { 228567918409756, 865093958780220, 358083886450556, 159617889659320, 1360637926292598 }, + { 234147501399755, 2229469128637390, 2175289352258889, 1397401514549353, 1885288963089922 } + }, + { + { 1111762412951562, 252849572507389, 1048714233823341, 146111095601446, 1237505378776770 }, + { 1113790697840279, 1051167139966244, 1045930658550944, 2011366241542643, 1686166824620755 }, + { 1054097349305049, 1872495070333352, 182121071220717, 1064378906787311, 100273572924182 } + }, + { + { 1306410853171605, 1627717417672447, 50983221088417, 1109249951172250, 870201789081392 }, + { 104233794644221, 1548919791188248, 2224541913267306, 2054909377116478, 1043803389015153 }, + { 216762189468802, 707284285441622, 190678557969733, 973969342604308, 1403009538434867 } + }, + { + { 1279024291038477, 344776835218310, 273722096017199, 1834200436811442, 634517197663804 }, + { 343805853118335, 1302216857414201, 566872543223541, 2051138939539004, 321428858384280 }, + { 470067171324852, 1618629234173951, 2000092177515639, 7307679772789, 1117521120249968 } + } +}, +{ /* 18/31 */ + { + { 278151578291475, 1810282338562947, 1771599529530998, 1383659409671631, 685373414471841 }, + { 577009397403102, 1791440261786291, 2177643735971638, 174546149911960, 1412505077782326 }, + { 893719721537457, 1201282458018197, 1522349501711173, 58011597740583, 1130406465887139 } + }, + { + { 412607348255453, 1280455764199780, 2233277987330768, 14180080401665, 331584698417165 }, + { 262483770854550, 990511055108216, 526885552771698, 571664396646158, 354086190278723 }, + { 1820352417585487, 24495617171480, 1547899057533253, 10041836186225, 480457105094042 } + }, + { + { 2023310314989233, 637905337525881, 2106474638900687, 557820711084072, 1687858215057826 }, + { 1144168702609745, 604444390410187, 1544541121756138, 1925315550126027, 626401428894002 }, + { 1922168257351784, 2018674099908659, 1776454117494445, 956539191509034, 36031129147635 } + }, + { + { 544644538748041, 1039872944430374, 876750409130610, 710657711326551, 1216952687484972 }, + { 58242421545916, 2035812695641843, 2118491866122923, 1191684463816273, 46921517454099 }, + { 272268252444639, 1374166457774292, 2230115177009552, 1053149803909880, 1354288411641016 } + }, + { + { 1857910905368338, 1754729879288912, 885945464109877, 1516096106802166, 1602902393369811 }, + { 1193437069800958, 901107149704790, 999672920611411, 477584824802207, 364239578697845 }, + { 886299989548838, 1538292895758047, 1590564179491896, 1944527126709657, 837344427345298 } + }, + { + { 754558365378305, 1712186480903618, 1703656826337531, 750310918489786, 518996040250900 }, + { 1309847803895382, 1462151862813074, 211370866671570, 1544595152703681, 1027691798954090 }, + { 803217563745370, 1884799722343599, 1357706345069218, 2244955901722095, 730869460037413 } + }, + { + { 689299471295966, 1831210565161071, 1375187341585438, 1106284977546171, 1893781834054269 }, + { 696351368613042, 1494385251239250, 738037133616932, 636385507851544, 927483222611406 }, + { 1949114198209333, 1104419699537997, 783495707664463, 1747473107602770, 2002634765788641 } + }, + { + { 1607325776830197, 530883941415333, 1451089452727895, 1581691157083423, 496100432831154 }, + { 1068900648804224, 2006891997072550, 1134049269345549, 1638760646180091, 2055396084625778 }, + { 2222475519314561, 1870703901472013, 1884051508440561, 1344072275216753, 1318025677799069 } + } +}, +{ /* 19/31 */ + { + { 155711679280656, 681100400509288, 389811735211209, 2135723811340709, 408733211204125 }, + { 7813206966729, 194444201427550, 2071405409526507, 1065605076176312, 1645486789731291 }, + { 16625790644959, 1647648827778410, 1579910185572704, 436452271048548, 121070048451050 } + }, + { + { 1037263028552531, 568385780377829, 297953104144430, 1558584511931211, 2238221839292471 }, + { 190565267697443, 672855706028058, 338796554369226, 337687268493904, 853246848691734 }, + { 1763863028400139, 766498079432444, 1321118624818005, 69494294452268, 858786744165651 } + }, + { + { 1292056768563024, 1456632109855638, 1100631247050184, 1386133165675321, 1232898350193752 }, + { 366253102478259, 525676242508811, 1449610995265438, 1183300845322183, 185960306491545 }, + { 28315355815982, 460422265558930, 1799675876678724, 1969256312504498, 1051823843138725 } + }, + { + { 156914999361983, 1606148405719949, 1665208410108430, 317643278692271, 1383783705665320 }, + { 54684536365732, 2210010038536222, 1194984798155308, 535239027773705, 1516355079301361 }, + { 1484387703771650, 198537510937949, 2186282186359116, 617687444857508, 647477376402122 } + }, + { + { 2147715541830533, 500032538445817, 646380016884826, 352227855331122, 1488268620408052 }, + { 159386186465542, 1877626593362941, 618737197060512, 1026674284330807, 1158121760792685 }, + { 1744544377739822, 1964054180355661, 1685781755873170, 2169740670377448, 1286112621104591 } + }, + { + { 81977249784993, 1667943117713086, 1668983819634866, 1605016835177615, 1353960708075544 }, + { 1602253788689063, 439542044889886, 2220348297664483, 657877410752869, 157451572512238 }, + { 1029287186166717, 65860128430192, 525298368814832, 1491902500801986, 1461064796385400 } + }, + { + { 408216988729246, 2121095722306989, 913562102267595, 1879708920318308, 241061448436731 }, + { 1185483484383269, 1356339572588553, 584932367316448, 102132779946470, 1792922621116791 }, + { 1966196870701923, 2230044620318636, 1425982460745905, 261167817826569, 46517743394330 } + }, + { + { 107077591595359, 884959942172345, 27306869797400, 2224911448949390, 964352058245223 }, + { 1730194207717538, 431790042319772, 1831515233279467, 1372080552768581, 1074513929381760 }, + { 1450880638731607, 1019861580989005, 1229729455116861, 1174945729836143, 826083146840706 } + } +}, +{ /* 20/31 */ + { + { 1899935429242705, 1602068751520477, 940583196550370, 82431069053859, 1540863155745696 }, + { 2136688454840028, 2099509000964294, 1690800495246475, 1217643678575476, 828720645084218 }, + { 765548025667841, 462473984016099, 998061409979798, 546353034089527, 2212508972466858 } + }, + { + { 46575283771160, 892570971573071, 1281983193144090, 1491520128287375, 75847005908304 }, + { 1801436127943107, 1734436817907890, 1268728090345068, 167003097070711, 2233597765834956 }, + { 1997562060465113, 1048700225534011, 7615603985628, 1855310849546841, 2242557647635213 } + }, + { + { 1161017320376250, 492624580169043, 2169815802355237, 976496781732542, 1770879511019629 }, + { 1357044908364776, 729130645262438, 1762469072918979, 1365633616878458, 181282906404941 }, + { 1080413443139865, 1155205815510486, 1848782073549786, 622566975152580, 124965574467971 } + }, + { + { 1184526762066993, 247622751762817, 692129017206356, 820018689412496, 2188697339828085 }, + { 2020536369003019, 202261491735136, 1053169669150884, 2056531979272544, 778165514694311 }, + { 237404399610207, 1308324858405118, 1229680749538400, 720131409105291, 1958958863624906 } + }, + { + { 515583508038846, 17656978857189, 1717918437373989, 1568052070792483, 46975803123923 }, + { 281527309158085, 36970532401524, 866906920877543, 2222282602952734, 1289598729589882 }, + { 1278207464902042, 494742455008756, 1262082121427081, 1577236621659884, 1888786707293291 } + }, + { + { 353042527954210, 1830056151907359, 1111731275799225, 174960955838824, 404312815582675 }, + { 2064251142068628, 1666421603389706, 1419271365315441, 468767774902855, 191535130366583 }, + { 1716987058588002, 1859366439773457, 1767194234188234, 64476199777924, 1117233614485261 } + }, + { + { 984292135520292, 135138246951259, 2220652137473167, 1722843421165029, 190482558012909 }, + { 298845952651262, 1166086588952562, 1179896526238434, 1347812759398693, 1412945390096208 }, + { 1143239552672925, 906436640714209, 2177000572812152, 2075299936108548, 325186347798433 } + }, + { + { 721024854374772, 684487861263316, 1373438744094159, 2193186935276995, 1387043709851261 }, + { 418098668140962, 715065997721283, 1471916138376055, 2168570337288357, 937812682637044 }, + { 1043584187226485, 2143395746619356, 2209558562919611, 482427979307092, 847556718384018 } + } +}, +{ /* 21/31 */ + { + { 1248731221520759, 1465200936117687, 540803492710140, 52978634680892, 261434490176109 }, + { 1057329623869501, 620334067429122, 461700859268034, 2012481616501857, 297268569108938 }, + { 1055352180870759, 1553151421852298, 1510903185371259, 1470458349428097, 1226259419062731 } + }, + { + { 1492988790301668, 790326625573331, 1190107028409745, 1389394752159193, 1620408196604194 }, + { 47000654413729, 1004754424173864, 1868044813557703, 173236934059409, 588771199737015 }, + { 30498470091663, 1082245510489825, 576771653181956, 806509986132686, 1317634017056939 } + }, + { + { 420308055751555, 1493354863316002, 165206721528088, 1884845694919786, 2065456951573059 }, + { 1115636332012334, 1854340990964155, 83792697369514, 1972177451994021, 457455116057587 }, + { 1698968457310898, 1435137169051090, 1083661677032510, 938363267483709, 340103887207182 } + }, + { + { 1995325341336574, 911500251774648, 164010755403692, 855378419194762, 1573601397528842 }, + { 241719380661528, 310028521317150, 1215881323380194, 1408214976493624, 2141142156467363 }, + { 1315157046163473, 727368447885818, 1363466668108618, 1668921439990361, 1398483384337907 } + }, + { + { 75029678299646, 1015388206460473, 1849729037055212, 1939814616452984, 444404230394954 }, + { 2053597130993710, 2024431685856332, 2233550957004860, 2012407275509545, 872546993104440 }, + { 1217269667678610, 599909351968693, 1390077048548598, 1471879360694802, 739586172317596 } + }, + { + { 1718318639380794, 1560510726633958, 904462881159922, 1418028351780052, 94404349451937 }, + { 2132502667405250, 214379346175414, 1502748313768060, 1960071701057800, 1353971822643138 }, + { 319394212043702, 2127459436033571, 717646691535162, 663366796076914, 318459064945314 } + }, + { + { 405989424923593, 1960452633787083, 667349034401665, 1492674260767112, 1451061489880787 }, + { 947085906234007, 323284730494107, 1485778563977200, 728576821512394, 901584347702286 }, + { 1575783124125742, 2126210792434375, 1569430791264065, 1402582372904727, 1891780248341114 } + }, + { + { 838432205560695, 1997703511451664, 1018791879907867, 1662001808174331, 78328132957753 }, + { 739152638255629, 2074935399403557, 505483666745895, 1611883356514088, 628654635394878 }, + { 1822054032121349, 643057948186973, 7306757352712, 577249257962099, 284735863382083 } + } +}, +{ /* 22/31 */ + { + { 1366558556363930, 1448606567552086, 1478881020944768, 165803179355898, 1115718458123498 }, + { 204146226972102, 1630511199034723, 2215235214174763, 174665910283542, 956127674017216 }, + { 1562934578796716, 1070893489712745, 11324610642270, 958989751581897, 2172552325473805 } + }, + { + { 1770564423056027, 735523631664565, 1326060113795289, 1509650369341127, 65892421582684 }, + { 623682558650637, 1337866509471512, 990313350206649, 1314236615762469, 1164772974270275 }, + { 223256821462517, 723690150104139, 1000261663630601, 933280913953265, 254872671543046 } + }, + { + { 1969087237026041, 624795725447124, 1335555107635969, 2069986355593023, 1712100149341902 }, + { 1236103475266979, 1837885883267218, 1026072585230455, 1025865513954973, 1801964901432134 }, + { 1115241013365517, 1712251818829143, 2148864332502771, 2096001471438138, 2235017246626125 } + }, + { + { 1299268198601632, 2047148477845621, 2165648650132450, 1612539282026145, 514197911628890 }, + { 118352772338543, 1067608711804704, 1434796676193498, 1683240170548391, 230866769907437 }, + { 1850689576796636, 1601590730430274, 1139674615958142, 1954384401440257, 76039205311 } + }, + { + { 1723387471374172, 997301467038410, 533927635123657, 20928644693965, 1756575222802513 }, + { 2146711623855116, 503278928021499, 625853062251406, 1109121378393107, 1033853809911861 }, + { 571005965509422, 2005213373292546, 1016697270349626, 56607856974274, 914438579435146 } + }, + { + { 1346698876211176, 2076651707527589, 1084761571110205, 265334478828406, 1068954492309671 }, + { 1769967932677654, 1695893319756416, 1151863389675920, 1781042784397689, 400287774418285 }, + { 1851867764003121, 403841933237558, 820549523771987, 761292590207581, 1743735048551143 } + }, + { + { 410915148140008, 2107072311871739, 1004367461876503, 99684895396761, 1180818713503224 }, + { 285945406881439, 648174397347453, 1098403762631981, 1366547441102991, 1505876883139217 }, + { 672095903120153, 1675918957959872, 636236529315028, 1569297300327696, 2164144194785875 } + }, + { + { 1902708175321798, 1035343530915438, 1178560808893263, 301095684058146, 1280977479761118 }, + { 1615357281742403, 404257611616381, 2160201349780978, 1160947379188955, 1578038619549541 }, + { 2013087639791217, 822734930507457, 1785668418619014, 1668650702946164, 389450875221715 } + } +}, +{ /* 23/31 */ + { + { 453918449698368, 106406819929001, 2072540975937135, 308588860670238, 1304394580755385 }, + { 1295082798350326, 2091844511495996, 1851348972587817, 3375039684596, 789440738712837 }, + { 2083069137186154, 848523102004566, 993982213589257, 1405313299916317, 1532824818698468 } + }, + { + { 1495961298852430, 1397203457344779, 1774950217066942, 139302743555696, 66603584342787 }, + { 1782411379088302, 1096724939964781, 27593390721418, 542241850291353, 1540337798439873 }, + { 693543956581437, 171507720360750, 1557908942697227, 1074697073443438, 1104093109037196 } + }, + { + { 345288228393419, 1099643569747172, 134881908403743, 1740551994106740, 248212179299770 }, + { 231429562203065, 1526290236421172, 2021375064026423, 1520954495658041, 806337791525116 }, + { 1079623667189886, 872403650198613, 766894200588288, 2163700860774109, 2023464507911816 } + }, + { + { 854645372543796, 1936406001954827, 151460662541253, 825325739271555, 1554306377287556 }, + { 1497138821904622, 1044820250515590, 1742593886423484, 1237204112746837, 849047450816987 }, + { 667962773375330, 1897271816877105, 1399712621683474, 1143302161683099, 2081798441209593 } + }, + { + { 127147851567005, 1936114012888110, 1704424366552046, 856674880716312, 716603621335359 }, + { 1072409664800960, 2146937497077528, 1508780108920651, 935767602384853, 1112800433544068 }, + { 333549023751292, 280219272863308, 2104176666454852, 1036466864875785, 536135186520207 } + }, + { + { 373666279883137, 146457241530109, 304116267127857, 416088749147715, 1258577131183391 }, + { 1186115062588401, 2251609796968486, 1098944457878953, 1153112761201374, 1791625503417267 }, + { 1870078460219737, 2129630962183380, 852283639691142, 292865602592851, 401904317342226 } + }, + { + { 1361070124828035, 815664541425524, 1026798897364671, 1951790935390647, 555874891834790 }, + { 1546301003424277, 459094500062839, 1097668518375311, 1780297770129643, 720763293687608 }, + { 1212405311403990, 1536693382542438, 61028431067459, 1863929423417129, 1223219538638038 } + }, + { + { 1294303766540260, 1183557465955093, 882271357233093, 63854569425375, 2213283684565087 }, + { 339050984211414, 601386726509773, 413735232134068, 966191255137228, 1839475899458159 }, + { 235605972169408, 2174055643032978, 1538335001838863, 1281866796917192, 1815940222628465 } + } +}, +{ /* 24/31 */ + { + { 1632352921721536, 1833328609514701, 2092779091951987, 1923956201873226, 2210068022482919 }, + { 35271216625062, 1712350667021807, 983664255668860, 98571260373038, 1232645608559836 }, + { 1998172393429622, 1798947921427073, 784387737563581, 1589352214827263, 1589861734168180 } + }, + { + { 1733739258725305, 31715717059538, 201969945218860, 992093044556990, 1194308773174556 }, + { 846415389605137, 746163495539180, 829658752826080, 592067705956946, 957242537821393 }, + { 1758148849754419, 619249044817679, 168089007997045, 1371497636330523, 1867101418880350 } + }, + { + { 326633984209635, 261759506071016, 1700682323676193, 1577907266349064, 1217647663383016 }, + { 1714182387328607, 1477856482074168, 574895689942184, 2159118410227270, 1555532449716575 }, + { 853828206885131, 998498946036955, 1835887550391235, 207627336608048, 258363815956050 } + }, + { + { 141141474651677, 1236728744905256, 643101419899887, 1646615130509173, 1208239602291765 }, + { 1501663228068911, 1354879465566912, 1444432675498247, 897812463852601, 855062598754348 }, + { 714380763546606, 1032824444965790, 1774073483745338, 1063840874947367, 1738680636537158 } + }, + { + { 1640635546696252, 633168953192112, 2212651044092396, 30590958583852, 368515260889378 }, + { 1171650314802029, 1567085444565577, 1453660792008405, 757914533009261, 1619511342778196 }, + { 420958967093237, 971103481109486, 2169549185607107, 1301191633558497, 1661514101014240 } + }, + { + { 907123651818302, 1332556122804146, 1824055253424487, 1367614217442959, 1982558335973172 }, + { 1121533090144639, 1021251337022187, 110469995947421, 1511059774758394, 2110035908131662 }, + { 303213233384524, 2061932261128138, 352862124777736, 40828818670255, 249879468482660 } + }, + { + { 856559257852200, 508517664949010, 1378193767894916, 1723459126947129, 1962275756614521 }, + { 1445691340537320, 40614383122127, 402104303144865, 485134269878232, 1659439323587426 }, + { 20057458979482, 1183363722525800, 2140003847237215, 2053873950687614, 2112017736174909 } + }, + { + { 2228654250927986, 1483591363415267, 1368661293910956, 1076511285177291, 526650682059608 }, + { 709481497028540, 531682216165724, 316963769431931, 1814315888453765, 258560242424104 }, + { 1053447823660455, 1955135194248683, 1010900954918985, 1182614026976701, 1240051576966610 } + } +}, +{ /* 25/31 */ + { + { 1957943897155497, 1788667368028035, 137692910029106, 1039519607062, 826404763313028 }, + { 1848942433095597, 1582009882530495, 1849292741020143, 1068498323302788, 2001402229799484 }, + { 1528282417624269, 2142492439828191, 2179662545816034, 362568973150328, 1591374675250271 } + }, + { + { 160026679434388, 232341189218716, 2149181472355545, 598041771119831, 183859001910173 }, + { 2013278155187349, 662660471354454, 793981225706267, 411706605985744, 804490933124791 }, + { 2051892037280204, 488391251096321, 2230187337030708, 930221970662692, 679002758255210 } + }, + { + { 1530723630438670, 875873929577927, 341560134269988, 449903119530753, 1055551308214179 }, + { 1461835919309432, 1955256480136428, 180866187813063, 1551979252664528, 557743861963950 }, + { 359179641731115, 1324915145732949, 902828372691474, 294254275669987, 1887036027752957 } + }, + { + { 2043271609454323, 2038225437857464, 1317528426475850, 1398989128982787, 2027639881006861 }, + { 2072902725256516, 312132452743412, 309930885642209, 996244312618453, 1590501300352303 }, + { 1397254305160710, 695734355138021, 2233992044438756, 1776180593969996, 1085588199351115 } + }, + { + { 440567051331029, 254894786356681, 493869224930222, 1556322069683366, 1567456540319218 }, + { 1950722461391320, 1907845598854797, 1822757481635527, 2121567704750244, 73811931471221 }, + { 387139307395758, 2058036430315676, 1220915649965325, 1794832055328951, 1230009312169328 } + }, + { + { 1765973779329517, 659344059446977, 19821901606666, 1301928341311214, 1116266004075885 }, + { 1127572801181483, 1224743760571696, 1276219889847274, 1529738721702581, 1589819666871853 }, + { 2181229378964934, 2190885205260020, 1511536077659137, 1246504208580490, 668883326494241 } + }, + { + { 437866655573314, 669026411194768, 81896997980338, 523874406393178, 245052060935236 }, + { 1975438052228868, 1071801519999806, 594652299224319, 1877697652668809, 1489635366987285 }, + { 958592545673770, 233048016518599, 851568750216589, 567703851596087, 1740300006094761 } + }, + { + { 2014540178270324, 192672779514432, 213877182641530, 2194819933853411, 1716422829364835 }, + { 1540769606609725, 2148289943846077, 1597804156127445, 1230603716683868, 815423458809453 }, + { 1738560251245018, 1779576754536888, 1783765347671392, 1880170990446751, 1088225159617541 } + } +}, +{ /* 26/31 */ + { + { 659303913929492, 1956447718227573, 1830568515922666, 841069049744408, 1669607124206368 }, + { 1143465490433355, 1532194726196059, 1093276745494697, 481041706116088, 2121405433561163 }, + { 1686424298744462, 1451806974487153, 266296068846582, 1834686947542675, 1720762336132256 } + }, + { + { 889217026388959, 1043290623284660, 856125087551909, 1669272323124636, 1603340330827879 }, + { 1206396181488998, 333158148435054, 1402633492821422, 1120091191722026, 1945474114550509 }, + { 766720088232571, 1512222781191002, 1189719893490790, 2091302129467914, 2141418006894941 } + }, + { + { 419663647306612, 1998875112167987, 1426599870253707, 1154928355379510, 486538532138187 }, + { 938160078005954, 1421776319053174, 1941643234741774, 180002183320818, 1414380336750546 }, + { 398001940109652, 1577721237663248, 1012748649830402, 1540516006905144, 1011684812884559 } + }, + { + { 1653276489969630, 6081825167624, 1921777941170836, 1604139841794531, 861211053640641 }, + { 996661541407379, 1455877387952927, 744312806857277, 139213896196746, 1000282908547789 }, + { 1450817495603008, 1476865707053229, 1030490562252053, 620966950353376, 1744760161539058 } + }, + { + { 559728410002599, 37056661641185, 2038622963352006, 1637244893271723, 1026565352238948 }, + { 962165956135846, 1116599660248791, 182090178006815, 1455605467021751, 196053588803284 }, + { 796863823080135, 1897365583584155, 420466939481601, 2165972651724672, 932177357788289 } + }, + { + { 877047233620632, 1375632631944375, 643773611882121, 660022738847877, 19353932331831 }, + { 2216943882299338, 394841323190322, 2222656898319671, 558186553950529, 1077236877025190 }, + { 801118384953213, 1914330175515892, 574541023311511, 1471123787903705, 1526158900256288 } + }, + { + { 949617889087234, 2207116611267331, 912920039141287, 501158539198789, 62362560771472 }, + { 1474518386765335, 1760793622169197, 1157399790472736, 1622864308058898, 165428294422792 }, + { 1961673048027128, 102619413083113, 1051982726768458, 1603657989805485, 1941613251499678 } + }, + { + { 1401939116319266, 335306339903072, 72046196085786, 862423201496006, 850518754531384 }, + { 1234706593321979, 1083343891215917, 898273974314935, 1640859118399498, 157578398571149 }, + { 1143483057726416, 1992614991758919, 674268662140796, 1773370048077526, 674318359920189 } + } +}, +{ /* 27/31 */ + { + { 1835401379538542, 173900035308392, 818247630716732, 1762100412152786, 1021506399448291 }, + { 1506632088156630, 2127481795522179, 513812919490255, 140643715928370, 442476620300318 }, + { 2056683376856736, 219094741662735, 2193541883188309, 1841182310235800, 556477468664293 } + }, + { + { 1315019427910827, 1049075855992603, 2066573052986543, 266904467185534, 2040482348591520 }, + { 94096246544434, 922482381166992, 24517828745563, 2139430508542503, 2097139044231004 }, + { 537697207950515, 1399352016347350, 1563663552106345, 2148749520888918, 549922092988516 } + }, + { + { 1747985413252434, 680511052635695, 1809559829982725, 594274250930054, 201673170745982 }, + { 323583936109569, 1973572998577657, 1192219029966558, 79354804385273, 1374043025560347 }, + { 213277331329947, 416202017849623, 1950535221091783, 1313441578103244, 2171386783823658 } + }, + { + { 189088804229831, 993969372859110, 895870121536987, 1547301535298256, 1477373024911350 }, + { 1620578418245010, 541035331188469, 2235785724453865, 2154865809088198, 1974627268751826 }, + { 1346805451740245, 1350981335690626, 942744349501813, 2155094562545502, 1012483751693409 } + }, + { + { 2107080134091762, 1132567062788208, 1824935377687210, 769194804343737, 1857941799971888 }, + { 1074666112436467, 249279386739593, 1174337926625354, 1559013532006480, 1472287775519121 }, + { 1872620123779532, 1892932666768992, 1921559078394978, 1270573311796160, 1438913646755037 } + }, + { + { 837390187648199, 1012253300223599, 989780015893987, 1351393287739814, 328627746545550 }, + { 1028328827183114, 1711043289969857, 1350832470374933, 1923164689604327, 1495656368846911 }, + { 1900828492104143, 430212361082163, 687437570852799, 832514536673512, 1685641495940794 } + }, + { + { 842632847936398, 605670026766216, 290836444839585, 163210774892356, 2213815011799645 }, + { 1176336383453996, 1725477294339771, 12700622672454, 678015708818208, 162724078519879 }, + { 1448049969043497, 1789411762943521, 385587766217753, 90201620913498, 832999441066823 } + }, + { + { 516086333293313, 2240508292484616, 1351669528166508, 1223255565316488, 750235824427138 }, + { 1263624896582495, 1102602401673328, 526302183714372, 2152015839128799, 1483839308490010 }, + { 442991718646863, 1599275157036458, 1925389027579192, 899514691371390, 350263251085160 } + } +}, +{ /* 28/31 */ + { + { 1689713572022143, 593854559254373, 978095044791970, 1985127338729499, 1676069120347625 }, + { 1557207018622683, 340631692799603, 1477725909476187, 614735951619419, 2033237123746766 }, + { 968764929340557, 1225534776710944, 662967304013036, 1155521416178595, 791142883466590 } + }, + { + { 1487081286167458, 993039441814934, 1792378982844640, 698652444999874, 2153908693179754 }, + { 1123181311102823, 685575944875442, 507605465509927, 1412590462117473, 568017325228626 }, + { 560258797465417, 2193971151466401, 1824086900849026, 579056363542056, 1690063960036441 } + }, + { + { 1918407319222416, 353767553059963, 1930426334528099, 1564816146005724, 1861342381708096 }, + { 2131325168777276, 1176636658428908, 1756922641512981, 1390243617176012, 1966325177038383 }, + { 2063958120364491, 2140267332393533, 699896251574968, 273268351312140, 375580724713232 } + }, + { + { 2024297515263178, 416959329722687, 1079014235017302, 171612225573183, 1031677520051053 }, + { 2033900009388450, 1744902869870788, 2190580087917640, 1949474984254121, 231049754293748 }, + { 343868674606581, 550155864008088, 1450580864229630, 481603765195050, 896972360018042 } + }, + { + { 2151139328380127, 314745882084928, 59756825775204, 1676664391494651, 2048348075599360 }, + { 1528930066340597, 1605003907059576, 1055061081337675, 1458319101947665, 1234195845213142 }, + { 830430507734812, 1780282976102377, 1425386760709037, 362399353095425, 2168861579799910 } + }, + { + { 1155762232730333, 980662895504006, 2053766700883521, 490966214077606, 510405877041357 }, + { 1683750316716132, 652278688286128, 1221798761193539, 1897360681476669, 319658166027343 }, + { 618808732869972, 72755186759744, 2060379135624181, 1730731526741822, 48862757828238 } + }, + { + { 1463171970593505, 1143040711767452, 614590986558883, 1409210575145591, 1882816996436803 }, + { 2230133264691131, 563950955091024, 2042915975426398, 827314356293472, 672028980152815 }, + { 264204366029760, 1654686424479449, 2185050199932931, 2207056159091748, 506015669043634 } + }, + { + { 1784446333136569, 1973746527984364, 334856327359575, 1156769775884610, 1023950124675478 }, + { 2065270940578383, 31477096270353, 306421879113491, 181958643936686, 1907105536686083 }, + { 1496516440779464, 1748485652986458, 872778352227340, 818358834654919, 97932669284220 } + } +}, +{ /* 29/31 */ + { + { 471636015770351, 672455402793577, 1804995246884103, 1842309243470804, 1501862504981682 }, + { 1013216974933691, 538921919682598, 1915776722521558, 1742822441583877, 1886550687916656 }, + { 2094270000643336, 303971879192276, 40801275554748, 649448917027930, 1818544418535447 } + }, + { + { 2241737709499165, 549397817447461, 838180519319392, 1725686958520781, 1705639080897747 }, + { 1216074541925116, 50120933933509, 1565829004133810, 721728156134580, 349206064666188 }, + { 948617110470858, 346222547451945, 1126511960599975, 1759386906004538, 493053284802266 } + }, + { + { 1454933046815146, 874696014266362, 1467170975468588, 1432316382418897, 2111710746366763 }, + { 2105387117364450, 1996463405126433, 1303008614294500, 851908115948209, 1353742049788635 }, + { 750300956351719, 1487736556065813, 15158817002104, 1511998221598392, 971739901354129 } + }, + { + { 1874648163531693, 2124487685930551, 1810030029384882, 918400043048335, 586348627300650 }, + { 1235084464747900, 1166111146432082, 1745394857881591, 1405516473883040, 4463504151617 }, + { 1663810156463827, 327797390285791, 1341846161759410, 1964121122800605, 1747470312055380 } + }, + { + { 660005247548233, 2071860029952887, 1358748199950107, 911703252219107, 1014379923023831 }, + { 2206641276178231, 1690587809721504, 1600173622825126, 2156096097634421, 1106822408548216 }, + { 1344788193552206, 1949552134239140, 1735915881729557, 675891104100469, 1834220014427292 } + }, + { + { 1920949492387964, 158885288387530, 70308263664033, 626038464897817, 1468081726101009 }, + { 622221042073383, 1210146474039168, 1742246422343683, 1403839361379025, 417189490895736 }, + { 22727256592983, 168471543384997, 1324340989803650, 1839310709638189, 504999476432775 } + }, + { + { 1313240518756327, 1721896294296942, 52263574587266, 2065069734239232, 804910473424630 }, + { 1337466662091884, 1287645354669772, 2018019646776184, 652181229374245, 898011753211715 }, + { 1969792547910734, 779969968247557, 2011350094423418, 1823964252907487, 1058949448296945 } + }, + { + { 207343737062002, 1118176942430253, 758894594548164, 806764629546266, 1157700123092949 }, + { 1273565321399022, 1638509681964574, 759235866488935, 666015124346707, 897983460943405 }, + { 1717263794012298, 1059601762860786, 1837819172257618, 1054130665797229, 680893204263559 } + } +}, +{ /* 30/31 */ + { + { 2237039662793603, 2249022333361206, 2058613546633703, 149454094845279, 2215176649164582 }, + { 79472182719605, 1851130257050174, 1825744808933107, 821667333481068, 781795293511946 }, + { 755822026485370, 152464789723500, 1178207602290608, 410307889503239, 156581253571278 } + }, + { + { 1418185496130297, 484520167728613, 1646737281442950, 1401487684670265, 1349185550126961 }, + { 1495380034400429, 325049476417173, 46346894893933, 1553408840354856, 828980101835683 }, + { 1280337889310282, 2070832742866672, 1640940617225222, 2098284908289951, 450929509534434 } + }, + { + { 407703353998781, 126572141483652, 286039827513621, 1999255076709338, 2030511179441770 }, + { 1254958221100483, 1153235960999843, 942907704968834, 637105404087392, 1149293270147267 }, + { 894249020470196, 400291701616810, 406878712230981, 1599128793487393, 1145868722604026 } + }, + { + { 1497955250203334, 110116344653260, 1128535642171976, 1900106496009660, 129792717460909 }, + { 452487513298665, 1352120549024569, 1173495883910956, 1999111705922009, 367328130454226 }, + { 1717539401269642, 1475188995688487, 891921989653942, 836824441505699, 1885988485608364 } + }, + { + { 1241784121422547, 187337051947583, 1118481812236193, 428747751936362, 30358898927325 }, + { 2022432361201842, 1088816090685051, 1977843398539868, 1854834215890724, 564238862029357 }, + { 938868489100585, 1100285072929025, 1017806255688848, 1957262154788833, 152787950560442 } + }, + { + { 867319417678923, 620471962942542, 226032203305716, 342001443957629, 1761675818237336 }, + { 1295072362439987, 931227904689414, 1355731432641687, 922235735834035, 892227229410209 }, + { 1680989767906154, 535362787031440, 2136691276706570, 1942228485381244, 1267350086882274 } + }, + { + { 366018233770527, 432660629755596, 126409707644535, 1973842949591662, 645627343442376 }, + { 535509430575217, 546885533737322, 1524675609547799, 2138095752851703, 1260738089896827 }, + { 1159906385590467, 2198530004321610, 714559485023225, 81880727882151, 1484020820037082 } + }, + { + { 1377485731340769, 2046328105512000, 1802058637158797, 62146136768173, 1356993908853901 }, + { 2013612215646735, 1830770575920375, 536135310219832, 609272325580394, 270684344495013 }, + { 1237542585982777, 2228682050256790, 1385281931622824, 593183794882890, 493654978552689 } + } +}, +{ /* 31/31 */ + { + { 47341488007760, 1891414891220257, 983894663308928, 176161768286818, 1126261115179708 }, + { 1694030170963455, 502038567066200, 1691160065225467, 949628319562187, 275110186693066 }, + { 1124515748676336, 1661673816593408, 1499640319059718, 1584929449166988, 558148594103306 } + }, + { + { 1784525599998356, 1619698033617383, 2097300287550715, 258265458103756, 1905684794832758 }, + { 1288941072872766, 931787902039402, 190731008859042, 2006859954667190, 1005931482221702 }, + { 1465551264822703, 152905080555927, 680334307368453, 173227184634745, 666407097159852 } + }, + { + { 2111017076203943, 1378760485794347, 1248583954016456, 1352289194864422, 1895180776543896 }, + { 171348223915638, 662766099800389, 462338943760497, 466917763340314, 656911292869115 }, + { 488623681976577, 866497561541722, 1708105560937768, 1673781214218839, 1506146329818807 } + }, + { + { 160425464456957, 950394373239689, 430497123340934, 711676555398832, 320964687779005 }, + { 988979367990485, 1359729327576302, 1301834257246029, 294141160829308, 29348272277475 }, + { 1434382743317910, 100082049942065, 221102347892623, 186982837860588, 1305765053501834 } + }, + { + { 2205916462268190, 499863829790820, 961960554686616, 158062762756985, 1841471168298305 }, + { 1191737341426592, 1847042034978363, 1382213545049056, 1039952395710448, 788812858896859 }, + { 1346965964571152, 1291881610839830, 2142916164336056, 786821641205979, 1571709146321039 } + }, + { + { 787164375951248, 202869205373189, 1356590421032140, 1431233331032510, 786341368775957 }, + { 492448143532951, 304105152670757, 1761767168301056, 233782684697790, 1981295323106089 }, + { 665807507761866, 1343384868355425, 895831046139653, 439338948736892, 1986828765695105 } + }, + { + { 756096210874553, 1721699973539149, 258765301727885, 1390588532210645, 1212530909934781 }, + { 852891097972275, 1816988871354562, 1543772755726524, 1174710635522444, 202129090724628 }, + { 1205281565824323, 22430498399418, 992947814485516, 1392458699738672, 688441466734558 } + }, + { + { 1050627428414972, 1955849529137135, 2171162376368357, 91745868298214, 447733118757826 }, + { 1287181461435438, 622722465530711, 880952150571872, 741035693459198, 311565274989772 }, + { 1003649078149734, 545233927396469, 1849786171789880, 1318943684880434, 280345687170552 } + } +} diff --git a/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/base2.h b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/base2.h new file mode 100644 index 0000000..d088241 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/base2.h @@ -0,0 +1,40 @@ +{ + { 1288382639258501, 245678601348599, 269427782077623, 1462984067271730, 137412439391563 }, + { 62697248952638, 204681361388450, 631292143396476, 338455783676468, 1213667448819585 }, + { 301289933810280, 1259582250014073, 1422107436869536, 796239922652654, 1953934009299142 } +}, +{ + { 1601611775252272, 1720807796594148, 1132070835939856, 1260455018889551, 2147779492816911 }, + { 316559037616741, 2177824224946892, 1459442586438991, 1461528397712656, 751590696113597 }, + { 1850748884277385, 1200145853858453, 1068094770532492, 672251375690438, 1586055907191707 } +}, +{ + { 769950342298419, 132954430919746, 844085933195555, 974092374476333, 726076285546016 }, + { 425251763115706, 608463272472562, 442562545713235, 837766094556764, 374555092627893 }, + { 1086255230780037, 274979815921559, 1960002765731872, 929474102396301, 1190409889297339 } +}, +{ + { 665000864555967, 2065379846933859, 370231110385876, 350988370788628, 1233371373142985 }, + { 2019367628972465, 676711900706637, 110710997811333, 1108646842542025, 517791959672113 }, + { 965130719900578, 247011430587952, 526356006571389, 91986625355052, 2157223321444601 } +}, +{ + { 1802695059465007, 1664899123557221, 593559490740857, 2160434469266659, 927570450755031 }, + { 1725674970513508, 1933645953859181, 1542344539275782, 1767788773573747, 1297447965928905 }, + { 1381809363726107, 1430341051343062, 2061843536018959, 1551778050872521, 2036394857967624 } +}, +{ + { 1970894096313054, 528066325833207, 1619374932191227, 2207306624415883, 1169170329061080 }, + { 2070390218572616, 1458919061857835, 624171843017421, 1055332792707765, 433987520732508 }, + { 893653801273833, 1168026499324677, 1242553501121234, 1306366254304474, 1086752658510815 } +}, +{ + { 213454002618221, 939771523987438, 1159882208056014, 317388369627517, 621213314200687 }, + { 1971678598905747, 338026507889165, 762398079972271, 655096486107477, 42299032696322 }, + { 177130678690680, 1754759263300204, 1864311296286618, 1180675631479880, 1292726903152791 } +}, +{ + { 1913163449625248, 460779200291993, 2193883288642314, 1008900146920800, 1721983679009502 }, + { 1070401523076875, 1272492007800961, 1910153608563310, 2075579521696771, 1191169788841221 }, + { 692896803108118, 500174642072499, 2068223309439677, 1162190621851337, 1426986007309901 } +} diff --git a/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/constants.h b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/constants.h new file mode 100644 index 0000000..24e5cb5 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/constants.h @@ -0,0 +1,41 @@ +/* 37095705934669439343138083508754565189542113879843219016388785533085940283555 */ +static const fe25519 d = { + 929955233495203, 466365720129213, 1662059464998953, 2033849074728123, 1442794654840575 +}; + +/* 2 * d = + * 16295367250680780974490674513165176452449235426866156013048779062215315747161 + */ +static const fe25519 d2 = { + 1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, 633789495995903 +}; + +/* sqrt(-1) */ +static const fe25519 sqrtm1 = { + 1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, 765476049583133 +}; + +/* A = 486662 */ +static const fe25519 curve25519_A = { + 486662, 0, 0, 0, 0 +}; + +/* sqrt(ad - 1) with a = -1 (mod p) */ +static const fe25519 sqrtadm1 = { + 2241493124984347, 425987919032274, 2207028919301688, 1220490630685848, 974799131293748 +}; + +/* 1 / sqrt(a - d) */ +static const fe25519 invsqrtamd = { + 278908739862762, 821645201101625, 8113234426968, 1777959178193151, 2118520810568447 +}; + +/* 1 - d ^ 2 */ +static const fe25519 onemsqd = { + 1136626929484150, 1998550399581263, 496427632559748, 118527312129759, 45110755273534 +}; + +/* (d - 1) ^ 2 */ +static const fe25519 sqdmone = { + 1507062230895904, 1572317787530805, 683053064812840, 317374165784489, 1572899562415810 +}; diff --git a/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/fe.h b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/fe.h new file mode 100644 index 0000000..de87626 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_core/ed25519/ref10/fe_51/fe.h @@ -0,0 +1,116 @@ +/* + Ignores top bit of h. + */ + +void +fe25519_frombytes(fe25519 h, const unsigned char *s) +{ + const uint64_t mask = 0x7ffffffffffffULL; + uint64_t h0, h1, h2, h3, h4; + + h0 = (LOAD64_LE(s ) ) & mask; + h1 = (LOAD64_LE(s + 6) >> 3) & mask; + h2 = (LOAD64_LE(s + 12) >> 6) & mask; + h3 = (LOAD64_LE(s + 19) >> 1) & mask; + h4 = (LOAD64_LE(s + 24) >> 12) & mask; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; +} + +static void +fe25519_reduce(fe25519 h, const fe25519 f) +{ + const uint64_t mask = 0x7ffffffffffffULL; + uint128_t t[5]; + + t[0] = f[0]; + t[1] = f[1]; + t[2] = f[2]; + t[3] = f[3]; + t[4] = f[4]; + + t[1] += t[0] >> 51; + t[0] &= mask; + t[2] += t[1] >> 51; + t[1] &= mask; + t[3] += t[2] >> 51; + t[2] &= mask; + t[4] += t[3] >> 51; + t[3] &= mask; + t[0] += 19 * (t[4] >> 51); + t[4] &= mask; + + t[1] += t[0] >> 51; + t[0] &= mask; + t[2] += t[1] >> 51; + t[1] &= mask; + t[3] += t[2] >> 51; + t[2] &= mask; + t[4] += t[3] >> 51; + t[3] &= mask; + t[0] += 19 * (t[4] >> 51); + t[4] &= mask; + + /* now t is between 0 and 2^255-1, properly carried. */ + /* case 1: between 0 and 2^255-20. case 2: between 2^255-19 and 2^255-1. */ + + t[0] += 19ULL; + + t[1] += t[0] >> 51; + t[0] &= mask; + t[2] += t[1] >> 51; + t[1] &= mask; + t[3] += t[2] >> 51; + t[2] &= mask; + t[4] += t[3] >> 51; + t[3] &= mask; + t[0] += 19ULL * (t[4] >> 51); + t[4] &= mask; + + /* now between 19 and 2^255-1 in both cases, and offset by 19. */ + + t[0] += 0x8000000000000 - 19ULL; + t[1] += 0x8000000000000 - 1ULL; + t[2] += 0x8000000000000 - 1ULL; + t[3] += 0x8000000000000 - 1ULL; + t[4] += 0x8000000000000 - 1ULL; + + /* now between 2^255 and 2^256-20, and offset by 2^255. */ + + t[1] += t[0] >> 51; + t[0] &= mask; + t[2] += t[1] >> 51; + t[1] &= mask; + t[3] += t[2] >> 51; + t[2] &= mask; + t[4] += t[3] >> 51; + t[3] &= mask; + t[4] &= mask; + + h[0] = t[0]; + h[1] = t[1]; + h[2] = t[2]; + h[3] = t[3]; + h[4] = t[4]; +} + +void +fe25519_tobytes(unsigned char *s, const fe25519 h) +{ + fe25519 t; + uint64_t t0, t1, t2, t3; + + fe25519_reduce(t, h); + t0 = t[0] | (t[1] << 51); + t1 = (t[1] >> 13) | (t[2] << 38); + t2 = (t[2] >> 26) | (t[3] << 25); + t3 = (t[3] >> 39) | (t[4] << 12); + STORE64_LE(s + 0, t0); + STORE64_LE(s + 8, t1); + STORE64_LE(s + 16, t2); + STORE64_LE(s + 24, t3); +} diff --git a/external/src/libsodium/src/libsodium/crypto_core/hchacha20/core_hchacha20.c b/external/src/libsodium/src/libsodium/crypto_core/hchacha20/core_hchacha20.c new file mode 100644 index 0000000..39ab26a --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_core/hchacha20/core_hchacha20.c @@ -0,0 +1,93 @@ + +#include +#include + +#include "crypto_core_hchacha20.h" +#include "private/common.h" + +#define QUARTERROUND(A, B, C, D) \ + do { \ + A += B; D = ROTL32(D ^ A, 16); \ + C += D; B = ROTL32(B ^ C, 12); \ + A += B; D = ROTL32(D ^ A, 8); \ + C += D; B = ROTL32(B ^ C, 7); \ + } while(0) + +int +crypto_core_hchacha20(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c) +{ + int i; + uint32_t x0, x1, x2, x3, x4, x5, x6, x7; + uint32_t x8, x9, x10, x11, x12, x13, x14, x15; + + if (c == NULL) { + x0 = 0x61707865; + x1 = 0x3320646e; + x2 = 0x79622d32; + x3 = 0x6b206574; + } else { + x0 = LOAD32_LE(c + 0); + x1 = LOAD32_LE(c + 4); + x2 = LOAD32_LE(c + 8); + x3 = LOAD32_LE(c + 12); + } + x4 = LOAD32_LE(k + 0); + x5 = LOAD32_LE(k + 4); + x6 = LOAD32_LE(k + 8); + x7 = LOAD32_LE(k + 12); + x8 = LOAD32_LE(k + 16); + x9 = LOAD32_LE(k + 20); + x10 = LOAD32_LE(k + 24); + x11 = LOAD32_LE(k + 28); + x12 = LOAD32_LE(in + 0); + x13 = LOAD32_LE(in + 4); + x14 = LOAD32_LE(in + 8); + x15 = LOAD32_LE(in + 12); + + for (i = 0; i < 10; i++) { + QUARTERROUND(x0, x4, x8, x12); + QUARTERROUND(x1, x5, x9, x13); + QUARTERROUND(x2, x6, x10, x14); + QUARTERROUND(x3, x7, x11, x15); + QUARTERROUND(x0, x5, x10, x15); + QUARTERROUND(x1, x6, x11, x12); + QUARTERROUND(x2, x7, x8, x13); + QUARTERROUND(x3, x4, x9, x14); + } + + STORE32_LE(out + 0, x0); + STORE32_LE(out + 4, x1); + STORE32_LE(out + 8, x2); + STORE32_LE(out + 12, x3); + STORE32_LE(out + 16, x12); + STORE32_LE(out + 20, x13); + STORE32_LE(out + 24, x14); + STORE32_LE(out + 28, x15); + + return 0; +} + +size_t +crypto_core_hchacha20_outputbytes(void) +{ + return crypto_core_hchacha20_OUTPUTBYTES; +} + +size_t +crypto_core_hchacha20_inputbytes(void) +{ + return crypto_core_hchacha20_INPUTBYTES; +} + +size_t +crypto_core_hchacha20_keybytes(void) +{ + return crypto_core_hchacha20_KEYBYTES; +} + +size_t +crypto_core_hchacha20_constbytes(void) +{ + return crypto_core_hchacha20_CONSTBYTES; +} diff --git a/external/src/libsodium/src/libsodium/crypto_core/hsalsa20/core_hsalsa20.c b/external/src/libsodium/src/libsodium/crypto_core/hsalsa20/core_hsalsa20.c new file mode 100644 index 0000000..37c4923 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_core/hsalsa20/core_hsalsa20.c @@ -0,0 +1,21 @@ +#include "crypto_core_hsalsa20.h" + +size_t +crypto_core_hsalsa20_outputbytes(void) { + return crypto_core_hsalsa20_OUTPUTBYTES; +} + +size_t +crypto_core_hsalsa20_inputbytes(void) { + return crypto_core_hsalsa20_INPUTBYTES; +} + +size_t +crypto_core_hsalsa20_keybytes(void) { + return crypto_core_hsalsa20_KEYBYTES; +} + +size_t +crypto_core_hsalsa20_constbytes(void) { + return crypto_core_hsalsa20_CONSTBYTES; +} diff --git a/external/src/libsodium/src/libsodium/crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.c b/external/src/libsodium/src/libsodium/crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.c new file mode 100644 index 0000000..1d1220f --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_core/hsalsa20/ref2/core_hsalsa20_ref2.c @@ -0,0 +1,95 @@ +/* +version 20080912 +D. J. Bernstein +Public domain. +*/ + +#include +#include + +#include "crypto_core_hsalsa20.h" +#include "private/common.h" + +#define ROUNDS 20 +#define U32C(v) (v##U) + +int +crypto_core_hsalsa20(unsigned char *out, + const unsigned char *in, + const unsigned char *k, + const unsigned char *c) +{ + uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, + x9, x10, x11, x12, x13, x14, x15; + int i; + + if (c == NULL) { + x0 = U32C(0x61707865); + x5 = U32C(0x3320646e); + x10 = U32C(0x79622d32); + x15 = U32C(0x6b206574); + } else { + x0 = LOAD32_LE(c + 0); + x5 = LOAD32_LE(c + 4); + x10 = LOAD32_LE(c + 8); + x15 = LOAD32_LE(c + 12); + } + x1 = LOAD32_LE(k + 0); + x2 = LOAD32_LE(k + 4); + x3 = LOAD32_LE(k + 8); + x4 = LOAD32_LE(k + 12); + x11 = LOAD32_LE(k + 16); + x12 = LOAD32_LE(k + 20); + x13 = LOAD32_LE(k + 24); + x14 = LOAD32_LE(k + 28); + x6 = LOAD32_LE(in + 0); + x7 = LOAD32_LE(in + 4); + x8 = LOAD32_LE(in + 8); + x9 = LOAD32_LE(in + 12); + + for (i = ROUNDS; i > 0; i -= 2) { + x4 ^= ROTL32(x0 + x12, 7); + x8 ^= ROTL32(x4 + x0, 9); + x12 ^= ROTL32(x8 + x4, 13); + x0 ^= ROTL32(x12 + x8, 18); + x9 ^= ROTL32(x5 + x1, 7); + x13 ^= ROTL32(x9 + x5, 9); + x1 ^= ROTL32(x13 + x9, 13); + x5 ^= ROTL32(x1 + x13, 18); + x14 ^= ROTL32(x10 + x6, 7); + x2 ^= ROTL32(x14 + x10, 9); + x6 ^= ROTL32(x2 + x14, 13); + x10 ^= ROTL32(x6 + x2, 18); + x3 ^= ROTL32(x15 + x11, 7); + x7 ^= ROTL32(x3 + x15, 9); + x11 ^= ROTL32(x7 + x3, 13); + x15 ^= ROTL32(x11 + x7, 18); + x1 ^= ROTL32(x0 + x3, 7); + x2 ^= ROTL32(x1 + x0, 9); + x3 ^= ROTL32(x2 + x1, 13); + x0 ^= ROTL32(x3 + x2, 18); + x6 ^= ROTL32(x5 + x4, 7); + x7 ^= ROTL32(x6 + x5, 9); + x4 ^= ROTL32(x7 + x6, 13); + x5 ^= ROTL32(x4 + x7, 18); + x11 ^= ROTL32(x10 + x9, 7); + x8 ^= ROTL32(x11 + x10, 9); + x9 ^= ROTL32(x8 + x11, 13); + x10 ^= ROTL32(x9 + x8, 18); + x12 ^= ROTL32(x15 + x14, 7); + x13 ^= ROTL32(x12 + x15, 9); + x14 ^= ROTL32(x13 + x12, 13); + x15 ^= ROTL32(x14 + x13, 18); + } + + STORE32_LE(out + 0, x0); + STORE32_LE(out + 4, x5); + STORE32_LE(out + 8, x10); + STORE32_LE(out + 12, x15); + STORE32_LE(out + 16, x6); + STORE32_LE(out + 20, x7); + STORE32_LE(out + 24, x8); + STORE32_LE(out + 28, x9); + + return 0; +} diff --git a/external/src/libsodium/src/libsodium/crypto_core/salsa/ref/core_salsa_ref.c b/external/src/libsodium/src/libsodium/crypto_core/salsa/ref/core_salsa_ref.c new file mode 100644 index 0000000..c023378 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_core/salsa/ref/core_salsa_ref.c @@ -0,0 +1,195 @@ + +#include +#include + +#include "crypto_core_salsa20.h" +#include "crypto_core_salsa2012.h" +#include "crypto_core_salsa208.h" +#include "private/common.h" + +static void +crypto_core_salsa(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c, + const int rounds) +{ + uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, + x15; + uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, + j15; + int i; + + j0 = x0 = 0x61707865; + j5 = x5 = 0x3320646e; + j10 = x10 = 0x79622d32; + j15 = x15 = 0x6b206574; + if (c != NULL) { + j0 = x0 = LOAD32_LE(c + 0); + j5 = x5 = LOAD32_LE(c + 4); + j10 = x10 = LOAD32_LE(c + 8); + j15 = x15 = LOAD32_LE(c + 12); + } + j1 = x1 = LOAD32_LE(k + 0); + j2 = x2 = LOAD32_LE(k + 4); + j3 = x3 = LOAD32_LE(k + 8); + j4 = x4 = LOAD32_LE(k + 12); + j11 = x11 = LOAD32_LE(k + 16); + j12 = x12 = LOAD32_LE(k + 20); + j13 = x13 = LOAD32_LE(k + 24); + j14 = x14 = LOAD32_LE(k + 28); + + j6 = x6 = LOAD32_LE(in + 0); + j7 = x7 = LOAD32_LE(in + 4); + j8 = x8 = LOAD32_LE(in + 8); + j9 = x9 = LOAD32_LE(in + 12); + + for (i = 0; i < rounds; i += 2) { + x4 ^= ROTL32(x0 + x12, 7); + x8 ^= ROTL32(x4 + x0, 9); + x12 ^= ROTL32(x8 + x4, 13); + x0 ^= ROTL32(x12 + x8, 18); + x9 ^= ROTL32(x5 + x1, 7); + x13 ^= ROTL32(x9 + x5, 9); + x1 ^= ROTL32(x13 + x9, 13); + x5 ^= ROTL32(x1 + x13, 18); + x14 ^= ROTL32(x10 + x6, 7); + x2 ^= ROTL32(x14 + x10, 9); + x6 ^= ROTL32(x2 + x14, 13); + x10 ^= ROTL32(x6 + x2, 18); + x3 ^= ROTL32(x15 + x11, 7); + x7 ^= ROTL32(x3 + x15, 9); + x11 ^= ROTL32(x7 + x3, 13); + x15 ^= ROTL32(x11 + x7, 18); + x1 ^= ROTL32(x0 + x3, 7); + x2 ^= ROTL32(x1 + x0, 9); + x3 ^= ROTL32(x2 + x1, 13); + x0 ^= ROTL32(x3 + x2, 18); + x6 ^= ROTL32(x5 + x4, 7); + x7 ^= ROTL32(x6 + x5, 9); + x4 ^= ROTL32(x7 + x6, 13); + x5 ^= ROTL32(x4 + x7, 18); + x11 ^= ROTL32(x10 + x9, 7); + x8 ^= ROTL32(x11 + x10, 9); + x9 ^= ROTL32(x8 + x11, 13); + x10 ^= ROTL32(x9 + x8, 18); + x12 ^= ROTL32(x15 + x14, 7); + x13 ^= ROTL32(x12 + x15, 9); + x14 ^= ROTL32(x13 + x12, 13); + x15 ^= ROTL32(x14 + x13, 18); + } + STORE32_LE(out + 0, x0 + j0); + STORE32_LE(out + 4, x1 + j1); + STORE32_LE(out + 8, x2 + j2); + STORE32_LE(out + 12, x3 + j3); + STORE32_LE(out + 16, x4 + j4); + STORE32_LE(out + 20, x5 + j5); + STORE32_LE(out + 24, x6 + j6); + STORE32_LE(out + 28, x7 + j7); + STORE32_LE(out + 32, x8 + j8); + STORE32_LE(out + 36, x9 + j9); + STORE32_LE(out + 40, x10 + j10); + STORE32_LE(out + 44, x11 + j11); + STORE32_LE(out + 48, x12 + j12); + STORE32_LE(out + 52, x13 + j13); + STORE32_LE(out + 56, x14 + j14); + STORE32_LE(out + 60, x15 + j15); +} + +int +crypto_core_salsa20(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c) +{ + crypto_core_salsa(out, in, k, c, 20); + return 0; +} + +size_t +crypto_core_salsa20_outputbytes(void) +{ + return crypto_core_salsa20_OUTPUTBYTES; +} + +size_t +crypto_core_salsa20_inputbytes(void) +{ + return crypto_core_salsa20_INPUTBYTES; +} + +size_t +crypto_core_salsa20_keybytes(void) +{ + return crypto_core_salsa20_KEYBYTES; +} + +size_t +crypto_core_salsa20_constbytes(void) +{ + return crypto_core_salsa20_CONSTBYTES; +} + +#ifndef MINIMAL +/* LCOV_EXCL_START */ +int +crypto_core_salsa2012(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c) +{ + crypto_core_salsa(out, in, k, c, 12); + return 0; +} + +size_t +crypto_core_salsa2012_outputbytes(void) +{ + return crypto_core_salsa2012_OUTPUTBYTES; +} + +size_t +crypto_core_salsa2012_inputbytes(void) +{ + return crypto_core_salsa2012_INPUTBYTES; +} + +size_t +crypto_core_salsa2012_keybytes(void) +{ + return crypto_core_salsa2012_KEYBYTES; +} + +size_t +crypto_core_salsa2012_constbytes(void) +{ + return crypto_core_salsa2012_CONSTBYTES; +} + +int +crypto_core_salsa208(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c) +{ + crypto_core_salsa(out, in, k, c, 8); + return 0; +} + +size_t +crypto_core_salsa208_outputbytes(void) +{ + return crypto_core_salsa208_OUTPUTBYTES; +} + +size_t +crypto_core_salsa208_inputbytes(void) +{ + return crypto_core_salsa208_INPUTBYTES; +} + +size_t +crypto_core_salsa208_keybytes(void) +{ + return crypto_core_salsa208_KEYBYTES; +} + +size_t +crypto_core_salsa208_constbytes(void) +{ + return crypto_core_salsa208_CONSTBYTES; +} +/* LCOV_EXCL_END */ +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/generichash_blake2.c b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/generichash_blake2.c new file mode 100644 index 0000000..781d4c5 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/generichash_blake2.c @@ -0,0 +1,55 @@ +#include "crypto_generichash_blake2b.h" +#include "randombytes.h" + +size_t +crypto_generichash_blake2b_bytes_min(void) { + return crypto_generichash_blake2b_BYTES_MIN; +} + +size_t +crypto_generichash_blake2b_bytes_max(void) { + return crypto_generichash_blake2b_BYTES_MAX; +} + +size_t +crypto_generichash_blake2b_bytes(void) { + return crypto_generichash_blake2b_BYTES; +} + +size_t +crypto_generichash_blake2b_keybytes_min(void) { + return crypto_generichash_blake2b_KEYBYTES_MIN; +} + +size_t +crypto_generichash_blake2b_keybytes_max(void) { + return crypto_generichash_blake2b_KEYBYTES_MAX; +} + +size_t +crypto_generichash_blake2b_keybytes(void) { + return crypto_generichash_blake2b_KEYBYTES; +} + +size_t +crypto_generichash_blake2b_saltbytes(void) { + return crypto_generichash_blake2b_SALTBYTES; +} + +size_t +crypto_generichash_blake2b_personalbytes(void) { + return crypto_generichash_blake2b_PERSONALBYTES; +} + +size_t +crypto_generichash_blake2b_statebytes(void) +{ + return (sizeof(crypto_generichash_blake2b_state) + (size_t) 63U) + & ~(size_t) 63U; +} + +void +crypto_generichash_blake2b_keygen(unsigned char k[crypto_generichash_blake2b_KEYBYTES]) +{ + randombytes_buf(k, crypto_generichash_blake2b_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2.h b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2.h new file mode 100644 index 0000000..edfc99a --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2.h @@ -0,0 +1,106 @@ +/* + BLAKE2 reference source code package - reference C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + All code is triple-licensed under the + [CC0](http://creativecommons.org/publicdomain/zero/1.0), the + [OpenSSL Licence](https://www.openssl.org/source/license.html), or + the [Apache Public License 2.0](http://www.apache.org/licenses/LICENSE-2.0), + at your choosing. + */ + +#ifndef blake2_H +#define blake2_H + +#include +#include + +#include "crypto_generichash_blake2b.h" +#include "export.h" + +enum blake2b_constant { + BLAKE2B_BLOCKBYTES = 128, + BLAKE2B_OUTBYTES = 64, + BLAKE2B_KEYBYTES = 64, + BLAKE2B_SALTBYTES = 16, + BLAKE2B_PERSONALBYTES = 16 +}; + +#ifdef __IBMC__ +# pragma pack(1) +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# pragma pack(1) +#else +# pragma pack(push, 1) +#endif + +typedef struct blake2b_param_ { + uint8_t digest_length; /* 1 */ + uint8_t key_length; /* 2 */ + uint8_t fanout; /* 3 */ + uint8_t depth; /* 4 */ + uint8_t leaf_length[4]; /* 8 */ + uint8_t node_offset[8]; /* 16 */ + uint8_t node_depth; /* 17 */ + uint8_t inner_length; /* 18 */ + uint8_t reserved[14]; /* 32 */ + uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */ + uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */ +} blake2b_param; + +typedef struct blake2b_state { + uint64_t h[8]; + uint64_t t[2]; + uint64_t f[2]; + uint8_t buf[2 * 128]; + size_t buflen; + uint8_t last_node; +} blake2b_state; + +#ifdef __IBMC__ +# pragma pack(pop) +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# pragma pack() +#else +# pragma pack(pop) +#endif + +/* Streaming API */ +int blake2b_init(blake2b_state *S, const uint8_t outlen); +int blake2b_init_salt_personal(blake2b_state *S, const uint8_t outlen, + const void *salt, const void *personal); +int blake2b_init_key(blake2b_state *S, const uint8_t outlen, const void *key, + const uint8_t keylen); +int blake2b_init_key_salt_personal(blake2b_state *S, const uint8_t outlen, + const void *key, const uint8_t keylen, + const void *salt, const void *personal); +int blake2b_init_param(blake2b_state *S, const blake2b_param *P); +int blake2b_update(blake2b_state *S, const uint8_t *in, uint64_t inlen); +int blake2b_final(blake2b_state *S, uint8_t *out, uint8_t outlen); + +/* Simple API */ +int blake2b(uint8_t *out, const void *in, const void *key, const uint8_t outlen, + const uint64_t inlen, uint8_t keylen); +int blake2b_salt_personal(uint8_t *out, const void *in, const void *key, + const uint8_t outlen, const uint64_t inlen, + uint8_t keylen, const void *salt, + const void *personal); + +typedef int (*blake2b_compress_fn)(blake2b_state *S, + const uint8_t block[BLAKE2B_BLOCKBYTES]); +int blake2b_pick_best_implementation(void); +int blake2b_compress_ref(blake2b_state *S, + const uint8_t block[BLAKE2B_BLOCKBYTES]); +int blake2b_compress_ssse3(blake2b_state *S, + const uint8_t block[BLAKE2B_BLOCKBYTES]); +int blake2b_compress_sse41(blake2b_state *S, + const uint8_t block[BLAKE2B_BLOCKBYTES]); +int blake2b_compress_avx2(blake2b_state *S, + const uint8_t block[BLAKE2B_BLOCKBYTES]); + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c new file mode 100644 index 0000000..4945462 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c @@ -0,0 +1,49 @@ + +#define BLAKE2_USE_SSSE3 +#define BLAKE2_USE_SSE41 +#define BLAKE2_USE_AVX2 + +#include +#include + +#include "blake2.h" +#include "private/common.h" + +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# pragma GCC target("sse4.1") +# pragma GCC target("avx2") +# endif + +# include +# include +# include +# include +# include "private/sse2_64_32.h" + +# include "blake2b-compress-avx2.h" + +CRYPTO_ALIGN(64) +static const uint64_t blake2b_IV[8] = { + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +int +blake2b_compress_avx2(blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES]) +{ + __m256i a = LOADU(&S->h[0]); + __m256i b = LOADU(&S->h[4]); + BLAKE2B_COMPRESS_V1(a, b, block, S->t[0], S->t[1], S->f[0], S->f[1]); + STOREU(&S->h[0], a); + STOREU(&S->h[4], b); + + return 0; +} + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-avx2.h b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-avx2.h new file mode 100644 index 0000000..7c11321 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-avx2.h @@ -0,0 +1,142 @@ + +#ifndef blake2b_compress_avx2_H +#define blake2b_compress_avx2_H + +#define LOADU128(p) _mm_loadu_si128((const __m128i *) (p)) +#define STOREU128(p, r) _mm_storeu_si128((__m128i *) (p), r) + +#define LOADU(p) _mm256_loadu_si256((const __m256i *) (p)) +#define STOREU(p, r) _mm256_storeu_si256((__m256i *) (p), r) + +#if defined(__INTEL_COMPILER) || defined(_MSC_VER) || defined(__GNUC__) +# define LOAD(p) _mm256_load_si256((const __m256i *) (p)) +# define STORE(p, r) _mm256_store_si256((__m256i *) (p), r) +#else +# define LOAD(p) LOADU(p) +# define STORE(p, r) STOREU(p, r) +#endif + +static inline uint64_t +LOADU64(const void *p) +{ + uint64_t v; + memcpy(&v, p, sizeof v); + return v; +} + +#define ROTATE16 \ + _mm256_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9, 2, \ + 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9) + +#define ROTATE24 \ + _mm256_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10, 3, \ + 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10) + +#define ADD(a, b) _mm256_add_epi64(a, b) +#define SUB(a, b) _mm256_sub_epi64(a, b) + +#define XOR(a, b) _mm256_xor_si256(a, b) +#define AND(a, b) _mm256_and_si256(a, b) +#define OR(a, b) _mm256_or_si256(a, b) + +#define ROT32(x) _mm256_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) +#define ROT24(x) _mm256_shuffle_epi8((x), ROTATE24) +#define ROT16(x) _mm256_shuffle_epi8((x), ROTATE16) +#define ROT63(x) _mm256_or_si256(_mm256_srli_epi64((x), 63), ADD((x), (x))) + +#define BLAKE2B_G1_V1(a, b, c, d, m) \ + do { \ + a = ADD(a, m); \ + a = ADD(a, b); \ + d = XOR(d, a); \ + d = ROT32(d); \ + c = ADD(c, d); \ + b = XOR(b, c); \ + b = ROT24(b); \ + } while (0) + +#define BLAKE2B_G2_V1(a, b, c, d, m) \ + do { \ + a = ADD(a, m); \ + a = ADD(a, b); \ + d = XOR(d, a); \ + d = ROT16(d); \ + c = ADD(c, d); \ + b = XOR(b, c); \ + b = ROT63(b); \ + } while (0) + +#define BLAKE2B_DIAG_V1(a, b, c, d) \ + do { \ + a = _mm256_permute4x64_epi64(a, _MM_SHUFFLE(2, 1, 0, 3)); \ + d = _mm256_permute4x64_epi64(d, _MM_SHUFFLE(1, 0, 3, 2)); \ + c = _mm256_permute4x64_epi64(c, _MM_SHUFFLE(0, 3, 2, 1)); \ + } while(0) + +#define BLAKE2B_UNDIAG_V1(a, b, c, d) \ + do { \ + a = _mm256_permute4x64_epi64(a, _MM_SHUFFLE(0, 3, 2, 1)); \ + d = _mm256_permute4x64_epi64(d, _MM_SHUFFLE(1, 0, 3, 2)); \ + c = _mm256_permute4x64_epi64(c, _MM_SHUFFLE(2, 1, 0, 3)); \ + } while(0) + +#include "blake2b-load-avx2.h" + +#define BLAKE2B_ROUND_V1(a, b, c, d, r, m) \ + do { \ + __m256i b0; \ + BLAKE2B_LOAD_MSG_##r##_1(b0); \ + BLAKE2B_G1_V1(a, b, c, d, b0); \ + BLAKE2B_LOAD_MSG_##r##_2(b0); \ + BLAKE2B_G2_V1(a, b, c, d, b0); \ + BLAKE2B_DIAG_V1(a, b, c, d); \ + BLAKE2B_LOAD_MSG_##r##_3(b0); \ + BLAKE2B_G1_V1(a, b, c, d, b0); \ + BLAKE2B_LOAD_MSG_##r##_4(b0); \ + BLAKE2B_G2_V1(a, b, c, d, b0); \ + BLAKE2B_UNDIAG_V1(a, b, c, d); \ + } while (0) + +#define BLAKE2B_ROUNDS_V1(a, b, c, d, m) \ + do { \ + BLAKE2B_ROUND_V1(a, b, c, d, 0, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 1, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 2, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 3, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 4, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 5, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 6, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 7, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 8, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 9, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 10, (m)); \ + BLAKE2B_ROUND_V1(a, b, c, d, 11, (m)); \ + } while (0) + +#define DECLARE_MESSAGE_WORDS(m) \ + const __m256i m0 = _mm256_broadcastsi128_si256(LOADU128((m) + 0)); \ + const __m256i m1 = _mm256_broadcastsi128_si256(LOADU128((m) + 16)); \ + const __m256i m2 = _mm256_broadcastsi128_si256(LOADU128((m) + 32)); \ + const __m256i m3 = _mm256_broadcastsi128_si256(LOADU128((m) + 48)); \ + const __m256i m4 = _mm256_broadcastsi128_si256(LOADU128((m) + 64)); \ + const __m256i m5 = _mm256_broadcastsi128_si256(LOADU128((m) + 80)); \ + const __m256i m6 = _mm256_broadcastsi128_si256(LOADU128((m) + 96)); \ + const __m256i m7 = _mm256_broadcastsi128_si256(LOADU128((m) + 112)); \ + __m256i t0, t1; + +#define BLAKE2B_COMPRESS_V1(a, b, m, t0, t1, f0, f1) \ + do { \ + DECLARE_MESSAGE_WORDS(m) \ + const __m256i iv0 = a; \ + const __m256i iv1 = b; \ + __m256i c = LOAD(&blake2b_IV[0]); \ + __m256i d = \ + XOR(LOAD(&blake2b_IV[4]), _mm256_set_epi64x(f1, f0, t1, t0)); \ + BLAKE2B_ROUNDS_V1(a, b, c, d, m); \ + a = XOR(a, c); \ + b = XOR(b, d); \ + a = XOR(a, iv0); \ + b = XOR(b, iv1); \ + } while (0) + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ref.c b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ref.c new file mode 100644 index 0000000..5fb356f --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ref.c @@ -0,0 +1,93 @@ + +#include +#include + +#include "blake2.h" +#include "private/common.h" + +CRYPTO_ALIGN(64) +static const uint64_t blake2b_IV[8] = { + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +static const uint8_t blake2b_sigma[12][16] = { + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }, + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 }, + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 }, + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 }, + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 }, + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 }, + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 }, + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 }, + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 }, + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } +}; + +int +blake2b_compress_ref(blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES]) +{ + uint64_t m[16]; + uint64_t v[16]; + int i; + + for (i = 0; i < 16; ++i) { + m[i] = LOAD64_LE(block + i * sizeof m[i]); + } + for (i = 0; i < 8; ++i) { + v[i] = S->h[i]; + } + v[8] = blake2b_IV[0]; + v[9] = blake2b_IV[1]; + v[10] = blake2b_IV[2]; + v[11] = blake2b_IV[3]; + v[12] = S->t[0] ^ blake2b_IV[4]; + v[13] = S->t[1] ^ blake2b_IV[5]; + v[14] = S->f[0] ^ blake2b_IV[6]; + v[15] = S->f[1] ^ blake2b_IV[7]; +#define G(r, i, a, b, c, d) \ + do { \ + a += b + m[blake2b_sigma[r][2 * i + 0]]; \ + d = ROTR64(d ^ a, 32); \ + c += d; \ + b = ROTR64(b ^ c, 24); \ + a += b + m[blake2b_sigma[r][2 * i + 1]]; \ + d = ROTR64(d ^ a, 16); \ + c += d; \ + b = ROTR64(b ^ c, 63); \ + } while (0) +#define ROUND(r) \ + do { \ + G(r, 0, v[0], v[4], v[8], v[12]); \ + G(r, 1, v[1], v[5], v[9], v[13]); \ + G(r, 2, v[2], v[6], v[10], v[14]); \ + G(r, 3, v[3], v[7], v[11], v[15]); \ + G(r, 4, v[0], v[5], v[10], v[15]); \ + G(r, 5, v[1], v[6], v[11], v[12]); \ + G(r, 6, v[2], v[7], v[8], v[13]); \ + G(r, 7, v[3], v[4], v[9], v[14]); \ + } while (0) + ROUND(0); + ROUND(1); + ROUND(2); + ROUND(3); + ROUND(4); + ROUND(5); + ROUND(6); + ROUND(7); + ROUND(8); + ROUND(9); + ROUND(10); + ROUND(11); + + for (i = 0; i < 8; ++i) { + S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; + } + +#undef G +#undef ROUND + return 0; +} diff --git a/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c new file mode 100644 index 0000000..f085c61 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c @@ -0,0 +1,87 @@ + +#define BLAKE2_USE_SSSE3 +#define BLAKE2_USE_SSE41 + +#include +#include + +#include "blake2.h" +#include "private/common.h" + +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) && \ + defined(HAVE_SMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# pragma GCC target("sse4.1") +# endif + +# include +# include +# include +# include "private/sse2_64_32.h" + +# include "blake2b-compress-sse41.h" + +CRYPTO_ALIGN(64) +static const uint64_t blake2b_IV[8] = { + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +int +blake2b_compress_sse41(blake2b_state *S, + const uint8_t block[BLAKE2B_BLOCKBYTES]) +{ + __m128i row1l, row1h; + __m128i row2l, row2h; + __m128i row3l, row3h; + __m128i row4l, row4h; + __m128i b0, b1; + __m128i t0, t1; + const __m128i r16 = + _mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9); + const __m128i r24 = + _mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10); + const __m128i m0 = LOADU(block + 00); + const __m128i m1 = LOADU(block + 16); + const __m128i m2 = LOADU(block + 32); + const __m128i m3 = LOADU(block + 48); + const __m128i m4 = LOADU(block + 64); + const __m128i m5 = LOADU(block + 80); + const __m128i m6 = LOADU(block + 96); + const __m128i m7 = LOADU(block + 112); + row1l = LOADU(&S->h[0]); + row1h = LOADU(&S->h[2]); + row2l = LOADU(&S->h[4]); + row2h = LOADU(&S->h[6]); + row3l = LOADU(&blake2b_IV[0]); + row3h = LOADU(&blake2b_IV[2]); + row4l = _mm_xor_si128(LOADU(&blake2b_IV[4]), LOADU(&S->t[0])); + row4h = _mm_xor_si128(LOADU(&blake2b_IV[6]), LOADU(&S->f[0])); + ROUND(0); + ROUND(1); + ROUND(2); + ROUND(3); + ROUND(4); + ROUND(5); + ROUND(6); + ROUND(7); + ROUND(8); + ROUND(9); + ROUND(10); + ROUND(11); + row1l = _mm_xor_si128(row3l, row1l); + row1h = _mm_xor_si128(row3h, row1h); + STOREU(&S->h[0], _mm_xor_si128(LOADU(&S->h[0]), row1l)); + STOREU(&S->h[2], _mm_xor_si128(LOADU(&S->h[2]), row1h)); + row2l = _mm_xor_si128(row4l, row2l); + row2h = _mm_xor_si128(row4h, row2h); + STOREU(&S->h[4], _mm_xor_si128(LOADU(&S->h[4]), row2l)); + STOREU(&S->h[6], _mm_xor_si128(LOADU(&S->h[6]), row2h)); + return 0; +} + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-sse41.h b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-sse41.h new file mode 100644 index 0000000..ac78e5b --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-sse41.h @@ -0,0 +1,103 @@ + +#ifndef blake2b_compress_sse41_H +#define blake2b_compress_sse41_H + +#define LOADU(p) _mm_loadu_si128((const __m128i *) (const void *) (p)) +#define STOREU(p, r) _mm_storeu_si128((__m128i *) (void *) (p), r) + +#define _mm_roti_epi64(x, c) \ + (-(c) == 32) \ + ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \ + : (-(c) == 24) \ + ? _mm_shuffle_epi8((x), r24) \ + : (-(c) == 16) \ + ? _mm_shuffle_epi8((x), r16) \ + : (-(c) == 63) \ + ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_add_epi64((x), (x))) \ + : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_slli_epi64((x), 64 - (-(c)))) + +#define G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \ + row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ + row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ + \ + row4l = _mm_xor_si128(row4l, row1l); \ + row4h = _mm_xor_si128(row4h, row1h); \ + \ + row4l = _mm_roti_epi64(row4l, -32); \ + row4h = _mm_roti_epi64(row4h, -32); \ + \ + row3l = _mm_add_epi64(row3l, row4l); \ + row3h = _mm_add_epi64(row3h, row4h); \ + \ + row2l = _mm_xor_si128(row2l, row3l); \ + row2h = _mm_xor_si128(row2h, row3h); \ + \ + row2l = _mm_roti_epi64(row2l, -24); \ + row2h = _mm_roti_epi64(row2h, -24); + +#define G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \ + row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ + row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ + \ + row4l = _mm_xor_si128(row4l, row1l); \ + row4h = _mm_xor_si128(row4h, row1h); \ + \ + row4l = _mm_roti_epi64(row4l, -16); \ + row4h = _mm_roti_epi64(row4h, -16); \ + \ + row3l = _mm_add_epi64(row3l, row4l); \ + row3h = _mm_add_epi64(row3h, row4h); \ + \ + row2l = _mm_xor_si128(row2l, row3l); \ + row2h = _mm_xor_si128(row2h, row3h); \ + \ + row2l = _mm_roti_epi64(row2l, -63); \ + row2h = _mm_roti_epi64(row2h, -63); + +#define DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \ + t0 = _mm_alignr_epi8(row2h, row2l, 8); \ + t1 = _mm_alignr_epi8(row2l, row2h, 8); \ + row2l = t0; \ + row2h = t1; \ + \ + t0 = row3l; \ + row3l = row3h; \ + row3h = t0; \ + \ + t0 = _mm_alignr_epi8(row4h, row4l, 8); \ + t1 = _mm_alignr_epi8(row4l, row4h, 8); \ + row4l = t1; \ + row4h = t0; + +#define UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \ + t0 = _mm_alignr_epi8(row2l, row2h, 8); \ + t1 = _mm_alignr_epi8(row2h, row2l, 8); \ + row2l = t0; \ + row2h = t1; \ + \ + t0 = row3l; \ + row3l = row3h; \ + row3h = t0; \ + \ + t0 = _mm_alignr_epi8(row4l, row4h, 8); \ + t1 = _mm_alignr_epi8(row4h, row4l, 8); \ + row4l = t1; \ + row4h = t0; + +#include "blake2b-load-sse41.h" + +#define ROUND(r) \ + LOAD_MSG_##r##_1(b0, b1); \ + G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + LOAD_MSG_##r##_2(b0, b1); \ + G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \ + LOAD_MSG_##r##_3(b0, b1); \ + G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + LOAD_MSG_##r##_4(b0, b1); \ + G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c new file mode 100644 index 0000000..6372da0 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c @@ -0,0 +1,90 @@ + +#include +#include + +#include "blake2.h" +#include "private/common.h" + +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# endif + +# include +# include +# include "private/sse2_64_32.h" + +# include "blake2b-compress-ssse3.h" + +CRYPTO_ALIGN(64) +static const uint64_t blake2b_IV[8] = { + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +int +blake2b_compress_ssse3(blake2b_state *S, + const uint8_t block[BLAKE2B_BLOCKBYTES]) +{ + __m128i row1l, row1h; + __m128i row2l, row2h; + __m128i row3l, row3h; + __m128i row4l, row4h; + __m128i b0, b1; + __m128i t0, t1; + const __m128i r16 = + _mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9); + const __m128i r24 = + _mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10); + const uint64_t m0 = ((const uint64_t *) block)[0]; + const uint64_t m1 = ((const uint64_t *) block)[1]; + const uint64_t m2 = ((const uint64_t *) block)[2]; + const uint64_t m3 = ((const uint64_t *) block)[3]; + const uint64_t m4 = ((const uint64_t *) block)[4]; + const uint64_t m5 = ((const uint64_t *) block)[5]; + const uint64_t m6 = ((const uint64_t *) block)[6]; + const uint64_t m7 = ((const uint64_t *) block)[7]; + const uint64_t m8 = ((const uint64_t *) block)[8]; + const uint64_t m9 = ((const uint64_t *) block)[9]; + const uint64_t m10 = ((const uint64_t *) block)[10]; + const uint64_t m11 = ((const uint64_t *) block)[11]; + const uint64_t m12 = ((const uint64_t *) block)[12]; + const uint64_t m13 = ((const uint64_t *) block)[13]; + const uint64_t m14 = ((const uint64_t *) block)[14]; + const uint64_t m15 = ((const uint64_t *) block)[15]; + + row1l = LOADU(&S->h[0]); + row1h = LOADU(&S->h[2]); + row2l = LOADU(&S->h[4]); + row2h = LOADU(&S->h[6]); + row3l = LOADU(&blake2b_IV[0]); + row3h = LOADU(&blake2b_IV[2]); + row4l = _mm_xor_si128(LOADU(&blake2b_IV[4]), LOADU(&S->t[0])); + row4h = _mm_xor_si128(LOADU(&blake2b_IV[6]), LOADU(&S->f[0])); + ROUND(0); + ROUND(1); + ROUND(2); + ROUND(3); + ROUND(4); + ROUND(5); + ROUND(6); + ROUND(7); + ROUND(8); + ROUND(9); + ROUND(10); + ROUND(11); + row1l = _mm_xor_si128(row3l, row1l); + row1h = _mm_xor_si128(row3h, row1h); + STOREU(&S->h[0], _mm_xor_si128(LOADU(&S->h[0]), row1l)); + STOREU(&S->h[2], _mm_xor_si128(LOADU(&S->h[2]), row1h)); + row2l = _mm_xor_si128(row4l, row2l); + row2h = _mm_xor_si128(row4h, row2h); + STOREU(&S->h[4], _mm_xor_si128(LOADU(&S->h[4]), row2l)); + STOREU(&S->h[6], _mm_xor_si128(LOADU(&S->h[6]), row2h)); + return 0; +} + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.h b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.h new file mode 100644 index 0000000..9a7164f --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.h @@ -0,0 +1,103 @@ + +#ifndef blake2b_compress_ssse3_H +#define blake2b_compress_ssse3_H + +#define LOADU(p) _mm_loadu_si128((const __m128i *) (const void *) (p)) +#define STOREU(p, r) _mm_storeu_si128((__m128i *) (void *) (p), r) + +#define _mm_roti_epi64(x, c) \ + (-(c) == 32) \ + ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \ + : (-(c) == 24) \ + ? _mm_shuffle_epi8((x), r24) \ + : (-(c) == 16) \ + ? _mm_shuffle_epi8((x), r16) \ + : (-(c) == 63) \ + ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_add_epi64((x), (x))) \ + : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_slli_epi64((x), 64 - (-(c)))) + +#define G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \ + row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ + row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ + \ + row4l = _mm_xor_si128(row4l, row1l); \ + row4h = _mm_xor_si128(row4h, row1h); \ + \ + row4l = _mm_roti_epi64(row4l, -32); \ + row4h = _mm_roti_epi64(row4h, -32); \ + \ + row3l = _mm_add_epi64(row3l, row4l); \ + row3h = _mm_add_epi64(row3h, row4h); \ + \ + row2l = _mm_xor_si128(row2l, row3l); \ + row2h = _mm_xor_si128(row2h, row3h); \ + \ + row2l = _mm_roti_epi64(row2l, -24); \ + row2h = _mm_roti_epi64(row2h, -24); + +#define G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \ + row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ + row1h = _mm_add_epi64(_mm_add_epi64(row1h, b1), row2h); \ + \ + row4l = _mm_xor_si128(row4l, row1l); \ + row4h = _mm_xor_si128(row4h, row1h); \ + \ + row4l = _mm_roti_epi64(row4l, -16); \ + row4h = _mm_roti_epi64(row4h, -16); \ + \ + row3l = _mm_add_epi64(row3l, row4l); \ + row3h = _mm_add_epi64(row3h, row4h); \ + \ + row2l = _mm_xor_si128(row2l, row3l); \ + row2h = _mm_xor_si128(row2h, row3h); \ + \ + row2l = _mm_roti_epi64(row2l, -63); \ + row2h = _mm_roti_epi64(row2h, -63); + +#define DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \ + t0 = _mm_alignr_epi8(row2h, row2l, 8); \ + t1 = _mm_alignr_epi8(row2l, row2h, 8); \ + row2l = t0; \ + row2h = t1; \ + \ + t0 = row3l; \ + row3l = row3h; \ + row3h = t0; \ + \ + t0 = _mm_alignr_epi8(row4h, row4l, 8); \ + t1 = _mm_alignr_epi8(row4l, row4h, 8); \ + row4l = t1; \ + row4h = t0; + +#define UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h) \ + t0 = _mm_alignr_epi8(row2l, row2h, 8); \ + t1 = _mm_alignr_epi8(row2h, row2l, 8); \ + row2l = t0; \ + row2h = t1; \ + \ + t0 = row3l; \ + row3l = row3h; \ + row3h = t0; \ + \ + t0 = _mm_alignr_epi8(row4l, row4h, 8); \ + t1 = _mm_alignr_epi8(row4h, row4l, 8); \ + row4l = t1; \ + row4h = t0; + +#include "blake2b-load-sse2.h" + +#define ROUND(r) \ + LOAD_MSG_##r##_1(b0, b1); \ + G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + LOAD_MSG_##r##_2(b0, b1); \ + G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + DIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); \ + LOAD_MSG_##r##_3(b0, b1); \ + G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + LOAD_MSG_##r##_4(b0, b1); \ + G2(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1); \ + UNDIAGONALIZE(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h); + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-load-avx2.h b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-load-avx2.h new file mode 100644 index 0000000..12a5d18 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-load-avx2.h @@ -0,0 +1,340 @@ +#ifndef blake2b_load_avx2_H +#define blake2b_load_avx2_H + +#define BLAKE2B_LOAD_MSG_0_1(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m0, m1); \ + t1 = _mm256_unpacklo_epi64(m2, m3); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_0_2(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m0, m1); \ + t1 = _mm256_unpackhi_epi64(m2, m3); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_0_3(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m7, m4); \ + t1 = _mm256_unpacklo_epi64(m5, m6); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_0_4(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m7, m4); \ + t1 = _mm256_unpackhi_epi64(m5, m6); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_1_1(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m7, m2); \ + t1 = _mm256_unpackhi_epi64(m4, m6); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_1_2(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m5, m4); \ + t1 = _mm256_alignr_epi8(m3, m7, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_1_3(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m2, m0); \ + t1 = _mm256_blend_epi32(m5, m0, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_1_4(b0) \ + do { \ + t0 = _mm256_alignr_epi8(m6, m1, 8); \ + t1 = _mm256_blend_epi32(m3, m1, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_2_1(b0) \ + do { \ + t0 = _mm256_alignr_epi8(m6, m5, 8); \ + t1 = _mm256_unpackhi_epi64(m2, m7); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_2_2(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m4, m0); \ + t1 = _mm256_blend_epi32(m6, m1, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_2_3(b0) \ + do { \ + t0 = _mm256_alignr_epi8(m5, m4, 8); \ + t1 = _mm256_unpackhi_epi64(m1, m3); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_2_4(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m2, m7); \ + t1 = _mm256_blend_epi32(m0, m3, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_3_1(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m3, m1); \ + t1 = _mm256_unpackhi_epi64(m6, m5); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_3_2(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m4, m0); \ + t1 = _mm256_unpacklo_epi64(m6, m7); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_3_3(b0) \ + do { \ + t0 = _mm256_alignr_epi8(m1, m7, 8); \ + t1 = _mm256_shuffle_epi32(m2, _MM_SHUFFLE(1, 0, 3, 2)); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_3_4(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m4, m3); \ + t1 = _mm256_unpacklo_epi64(m5, m0); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_4_1(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m4, m2); \ + t1 = _mm256_unpacklo_epi64(m1, m5); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_4_2(b0) \ + do { \ + t0 = _mm256_blend_epi32(m3, m0, 0x33); \ + t1 = _mm256_blend_epi32(m7, m2, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_4_3(b0) \ + do { \ + t0 = _mm256_alignr_epi8(m7, m1, 8); \ + t1 = _mm256_alignr_epi8(m3, m5, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_4_4(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m6, m0); \ + t1 = _mm256_unpacklo_epi64(m6, m4); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_5_1(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m1, m3); \ + t1 = _mm256_unpacklo_epi64(m0, m4); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_5_2(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m6, m5); \ + t1 = _mm256_unpackhi_epi64(m5, m1); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_5_3(b0) \ + do { \ + t0 = _mm256_alignr_epi8(m2, m0, 8); \ + t1 = _mm256_unpackhi_epi64(m3, m7); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_5_4(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m4, m6); \ + t1 = _mm256_alignr_epi8(m7, m2, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_6_1(b0) \ + do { \ + t0 = _mm256_blend_epi32(m0, m6, 0x33); \ + t1 = _mm256_unpacklo_epi64(m7, m2); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_6_2(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m2, m7); \ + t1 = _mm256_alignr_epi8(m5, m6, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_6_3(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m4, m0); \ + t1 = _mm256_blend_epi32(m4, m3, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_6_4(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m5, m3); \ + t1 = _mm256_shuffle_epi32(m1, _MM_SHUFFLE(1, 0, 3, 2)); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_7_1(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m6, m3); \ + t1 = _mm256_blend_epi32(m1, m6, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_7_2(b0) \ + do { \ + t0 = _mm256_alignr_epi8(m7, m5, 8); \ + t1 = _mm256_unpackhi_epi64(m0, m4); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_7_3(b0) \ + do { \ + t0 = _mm256_blend_epi32(m2, m1, 0x33); \ + t1 = _mm256_alignr_epi8(m4, m7, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_7_4(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m5, m0); \ + t1 = _mm256_unpacklo_epi64(m2, m3); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_8_1(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m3, m7); \ + t1 = _mm256_alignr_epi8(m0, m5, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_8_2(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m7, m4); \ + t1 = _mm256_alignr_epi8(m4, m1, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_8_3(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m5, m6); \ + t1 = _mm256_unpackhi_epi64(m6, m0); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_8_4(b0) \ + do { \ + t0 = _mm256_alignr_epi8(m1, m2, 8); \ + t1 = _mm256_alignr_epi8(m2, m3, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_9_1(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m5, m4); \ + t1 = _mm256_unpackhi_epi64(m3, m0); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_9_2(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m1, m2); \ + t1 = _mm256_blend_epi32(m2, m3, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_9_3(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m6, m7); \ + t1 = _mm256_unpackhi_epi64(m4, m1); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_9_4(b0) \ + do { \ + t0 = _mm256_blend_epi32(m5, m0, 0x33); \ + t1 = _mm256_unpacklo_epi64(m7, m6); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_10_1(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m0, m1); \ + t1 = _mm256_unpacklo_epi64(m2, m3); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_10_2(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m0, m1); \ + t1 = _mm256_unpackhi_epi64(m2, m3); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_10_3(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m7, m4); \ + t1 = _mm256_unpacklo_epi64(m5, m6); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_10_4(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m7, m4); \ + t1 = _mm256_unpackhi_epi64(m5, m6); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_11_1(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m7, m2); \ + t1 = _mm256_unpackhi_epi64(m4, m6); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_11_2(b0) \ + do { \ + t0 = _mm256_unpacklo_epi64(m5, m4); \ + t1 = _mm256_alignr_epi8(m3, m7, 8); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_11_3(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m2, m0); \ + t1 = _mm256_blend_epi32(m5, m0, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#define BLAKE2B_LOAD_MSG_11_4(b0) \ + do { \ + t0 = _mm256_alignr_epi8(m6, m1, 8); \ + t1 = _mm256_blend_epi32(m3, m1, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-load-sse2.h b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-load-sse2.h new file mode 100644 index 0000000..8e67421 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-load-sse2.h @@ -0,0 +1,164 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along + with + this software. If not, see + . +*/ + +#ifndef blake2b_load_sse2_H +#define blake2b_load_sse2_H + +#define LOAD_MSG_0_1(b0, b1) \ + b0 = _mm_set_epi64x(m2, m0); \ + b1 = _mm_set_epi64x(m6, m4) +#define LOAD_MSG_0_2(b0, b1) \ + b0 = _mm_set_epi64x(m3, m1); \ + b1 = _mm_set_epi64x(m7, m5) +#define LOAD_MSG_0_3(b0, b1) \ + b0 = _mm_set_epi64x(m10, m8); \ + b1 = _mm_set_epi64x(m14, m12) +#define LOAD_MSG_0_4(b0, b1) \ + b0 = _mm_set_epi64x(m11, m9); \ + b1 = _mm_set_epi64x(m15, m13) +#define LOAD_MSG_1_1(b0, b1) \ + b0 = _mm_set_epi64x(m4, m14); \ + b1 = _mm_set_epi64x(m13, m9) +#define LOAD_MSG_1_2(b0, b1) \ + b0 = _mm_set_epi64x(m8, m10); \ + b1 = _mm_set_epi64x(m6, m15) +#define LOAD_MSG_1_3(b0, b1) \ + b0 = _mm_set_epi64x(m0, m1); \ + b1 = _mm_set_epi64x(m5, m11) +#define LOAD_MSG_1_4(b0, b1) \ + b0 = _mm_set_epi64x(m2, m12); \ + b1 = _mm_set_epi64x(m3, m7) +#define LOAD_MSG_2_1(b0, b1) \ + b0 = _mm_set_epi64x(m12, m11); \ + b1 = _mm_set_epi64x(m15, m5) +#define LOAD_MSG_2_2(b0, b1) \ + b0 = _mm_set_epi64x(m0, m8); \ + b1 = _mm_set_epi64x(m13, m2) +#define LOAD_MSG_2_3(b0, b1) \ + b0 = _mm_set_epi64x(m3, m10); \ + b1 = _mm_set_epi64x(m9, m7) +#define LOAD_MSG_2_4(b0, b1) \ + b0 = _mm_set_epi64x(m6, m14); \ + b1 = _mm_set_epi64x(m4, m1) +#define LOAD_MSG_3_1(b0, b1) \ + b0 = _mm_set_epi64x(m3, m7); \ + b1 = _mm_set_epi64x(m11, m13) +#define LOAD_MSG_3_2(b0, b1) \ + b0 = _mm_set_epi64x(m1, m9); \ + b1 = _mm_set_epi64x(m14, m12) +#define LOAD_MSG_3_3(b0, b1) \ + b0 = _mm_set_epi64x(m5, m2); \ + b1 = _mm_set_epi64x(m15, m4) +#define LOAD_MSG_3_4(b0, b1) \ + b0 = _mm_set_epi64x(m10, m6); \ + b1 = _mm_set_epi64x(m8, m0) +#define LOAD_MSG_4_1(b0, b1) \ + b0 = _mm_set_epi64x(m5, m9); \ + b1 = _mm_set_epi64x(m10, m2) +#define LOAD_MSG_4_2(b0, b1) \ + b0 = _mm_set_epi64x(m7, m0); \ + b1 = _mm_set_epi64x(m15, m4) +#define LOAD_MSG_4_3(b0, b1) \ + b0 = _mm_set_epi64x(m11, m14); \ + b1 = _mm_set_epi64x(m3, m6) +#define LOAD_MSG_4_4(b0, b1) \ + b0 = _mm_set_epi64x(m12, m1); \ + b1 = _mm_set_epi64x(m13, m8) +#define LOAD_MSG_5_1(b0, b1) \ + b0 = _mm_set_epi64x(m6, m2); \ + b1 = _mm_set_epi64x(m8, m0) +#define LOAD_MSG_5_2(b0, b1) \ + b0 = _mm_set_epi64x(m10, m12); \ + b1 = _mm_set_epi64x(m3, m11) +#define LOAD_MSG_5_3(b0, b1) \ + b0 = _mm_set_epi64x(m7, m4); \ + b1 = _mm_set_epi64x(m1, m15) +#define LOAD_MSG_5_4(b0, b1) \ + b0 = _mm_set_epi64x(m5, m13); \ + b1 = _mm_set_epi64x(m9, m14) +#define LOAD_MSG_6_1(b0, b1) \ + b0 = _mm_set_epi64x(m1, m12); \ + b1 = _mm_set_epi64x(m4, m14) +#define LOAD_MSG_6_2(b0, b1) \ + b0 = _mm_set_epi64x(m15, m5); \ + b1 = _mm_set_epi64x(m10, m13) +#define LOAD_MSG_6_3(b0, b1) \ + b0 = _mm_set_epi64x(m6, m0); \ + b1 = _mm_set_epi64x(m8, m9) +#define LOAD_MSG_6_4(b0, b1) \ + b0 = _mm_set_epi64x(m3, m7); \ + b1 = _mm_set_epi64x(m11, m2) +#define LOAD_MSG_7_1(b0, b1) \ + b0 = _mm_set_epi64x(m7, m13); \ + b1 = _mm_set_epi64x(m3, m12) +#define LOAD_MSG_7_2(b0, b1) \ + b0 = _mm_set_epi64x(m14, m11); \ + b1 = _mm_set_epi64x(m9, m1) +#define LOAD_MSG_7_3(b0, b1) \ + b0 = _mm_set_epi64x(m15, m5); \ + b1 = _mm_set_epi64x(m2, m8) +#define LOAD_MSG_7_4(b0, b1) \ + b0 = _mm_set_epi64x(m4, m0); \ + b1 = _mm_set_epi64x(m10, m6) +#define LOAD_MSG_8_1(b0, b1) \ + b0 = _mm_set_epi64x(m14, m6); \ + b1 = _mm_set_epi64x(m0, m11) +#define LOAD_MSG_8_2(b0, b1) \ + b0 = _mm_set_epi64x(m9, m15); \ + b1 = _mm_set_epi64x(m8, m3) +#define LOAD_MSG_8_3(b0, b1) \ + b0 = _mm_set_epi64x(m13, m12); \ + b1 = _mm_set_epi64x(m10, m1) +#define LOAD_MSG_8_4(b0, b1) \ + b0 = _mm_set_epi64x(m7, m2); \ + b1 = _mm_set_epi64x(m5, m4) +#define LOAD_MSG_9_1(b0, b1) \ + b0 = _mm_set_epi64x(m8, m10); \ + b1 = _mm_set_epi64x(m1, m7) +#define LOAD_MSG_9_2(b0, b1) \ + b0 = _mm_set_epi64x(m4, m2); \ + b1 = _mm_set_epi64x(m5, m6) +#define LOAD_MSG_9_3(b0, b1) \ + b0 = _mm_set_epi64x(m9, m15); \ + b1 = _mm_set_epi64x(m13, m3) +#define LOAD_MSG_9_4(b0, b1) \ + b0 = _mm_set_epi64x(m14, m11); \ + b1 = _mm_set_epi64x(m0, m12) +#define LOAD_MSG_10_1(b0, b1) \ + b0 = _mm_set_epi64x(m2, m0); \ + b1 = _mm_set_epi64x(m6, m4) +#define LOAD_MSG_10_2(b0, b1) \ + b0 = _mm_set_epi64x(m3, m1); \ + b1 = _mm_set_epi64x(m7, m5) +#define LOAD_MSG_10_3(b0, b1) \ + b0 = _mm_set_epi64x(m10, m8); \ + b1 = _mm_set_epi64x(m14, m12) +#define LOAD_MSG_10_4(b0, b1) \ + b0 = _mm_set_epi64x(m11, m9); \ + b1 = _mm_set_epi64x(m15, m13) +#define LOAD_MSG_11_1(b0, b1) \ + b0 = _mm_set_epi64x(m4, m14); \ + b1 = _mm_set_epi64x(m13, m9) +#define LOAD_MSG_11_2(b0, b1) \ + b0 = _mm_set_epi64x(m8, m10); \ + b1 = _mm_set_epi64x(m6, m15) +#define LOAD_MSG_11_3(b0, b1) \ + b0 = _mm_set_epi64x(m0, m1); \ + b1 = _mm_set_epi64x(m5, m11) +#define LOAD_MSG_11_4(b0, b1) \ + b0 = _mm_set_epi64x(m2, m12); \ + b1 = _mm_set_epi64x(m3, m7) + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-load-sse41.h b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-load-sse41.h new file mode 100644 index 0000000..31745fc --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-load-sse41.h @@ -0,0 +1,307 @@ +/* + BLAKE2 reference source code package - optimized C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along + with + this software. If not, see + . +*/ + +#ifndef blake2b_load_sse41_H +#define blake2b_load_sse41_H + +#define LOAD_MSG_0_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m0, m1); \ + b1 = _mm_unpacklo_epi64(m2, m3); \ + } while (0) + +#define LOAD_MSG_0_2(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m0, m1); \ + b1 = _mm_unpackhi_epi64(m2, m3); \ + } while (0) + +#define LOAD_MSG_0_3(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m4, m5); \ + b1 = _mm_unpacklo_epi64(m6, m7); \ + } while (0) + +#define LOAD_MSG_0_4(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m4, m5); \ + b1 = _mm_unpackhi_epi64(m6, m7); \ + } while (0) + +#define LOAD_MSG_1_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m7, m2); \ + b1 = _mm_unpackhi_epi64(m4, m6); \ + } while (0) + +#define LOAD_MSG_1_2(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m5, m4); \ + b1 = _mm_alignr_epi8(m3, m7, 8); \ + } while (0) + +#define LOAD_MSG_1_3(b0, b1) \ + do { \ + b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1, 0, 3, 2)); \ + b1 = _mm_unpackhi_epi64(m5, m2); \ + } while (0) + +#define LOAD_MSG_1_4(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m6, m1); \ + b1 = _mm_unpackhi_epi64(m3, m1); \ + } while (0) + +#define LOAD_MSG_2_1(b0, b1) \ + do { \ + b0 = _mm_alignr_epi8(m6, m5, 8); \ + b1 = _mm_unpackhi_epi64(m2, m7); \ + } while (0) + +#define LOAD_MSG_2_2(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m4, m0); \ + b1 = _mm_blend_epi16(m1, m6, 0xF0); \ + } while (0) + +#define LOAD_MSG_2_3(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m5, m1, 0xF0); \ + b1 = _mm_unpackhi_epi64(m3, m4); \ + } while (0) + +#define LOAD_MSG_2_4(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m7, m3); \ + b1 = _mm_alignr_epi8(m2, m0, 8); \ + } while (0) + +#define LOAD_MSG_3_1(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m3, m1); \ + b1 = _mm_unpackhi_epi64(m6, m5); \ + } while (0) + +#define LOAD_MSG_3_2(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m4, m0); \ + b1 = _mm_unpacklo_epi64(m6, m7); \ + } while (0) + +#define LOAD_MSG_3_3(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m1, m2, 0xF0); \ + b1 = _mm_blend_epi16(m2, m7, 0xF0); \ + } while (0) + +#define LOAD_MSG_3_4(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m3, m5); \ + b1 = _mm_unpacklo_epi64(m0, m4); \ + } while (0) + +#define LOAD_MSG_4_1(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m4, m2); \ + b1 = _mm_unpacklo_epi64(m1, m5); \ + } while (0) + +#define LOAD_MSG_4_2(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m0, m3, 0xF0); \ + b1 = _mm_blend_epi16(m2, m7, 0xF0); \ + } while (0) + +#define LOAD_MSG_4_3(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m7, m5, 0xF0); \ + b1 = _mm_blend_epi16(m3, m1, 0xF0); \ + } while (0) + +#define LOAD_MSG_4_4(b0, b1) \ + do { \ + b0 = _mm_alignr_epi8(m6, m0, 8); \ + b1 = _mm_blend_epi16(m4, m6, 0xF0); \ + } while (0) + +#define LOAD_MSG_5_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m1, m3); \ + b1 = _mm_unpacklo_epi64(m0, m4); \ + } while (0) + +#define LOAD_MSG_5_2(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m6, m5); \ + b1 = _mm_unpackhi_epi64(m5, m1); \ + } while (0) + +#define LOAD_MSG_5_3(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m2, m3, 0xF0); \ + b1 = _mm_unpackhi_epi64(m7, m0); \ + } while (0) + +#define LOAD_MSG_5_4(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m6, m2); \ + b1 = _mm_blend_epi16(m7, m4, 0xF0); \ + } while (0) + +#define LOAD_MSG_6_1(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m6, m0, 0xF0); \ + b1 = _mm_unpacklo_epi64(m7, m2); \ + } while (0) + +#define LOAD_MSG_6_2(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m2, m7); \ + b1 = _mm_alignr_epi8(m5, m6, 8); \ + } while (0) + +#define LOAD_MSG_6_3(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m0, m3); \ + b1 = _mm_shuffle_epi32(m4, _MM_SHUFFLE(1, 0, 3, 2)); \ + } while (0) + +#define LOAD_MSG_6_4(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m3, m1); \ + b1 = _mm_blend_epi16(m1, m5, 0xF0); \ + } while (0) + +#define LOAD_MSG_7_1(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m6, m3); \ + b1 = _mm_blend_epi16(m6, m1, 0xF0); \ + } while (0) + +#define LOAD_MSG_7_2(b0, b1) \ + do { \ + b0 = _mm_alignr_epi8(m7, m5, 8); \ + b1 = _mm_unpackhi_epi64(m0, m4); \ + } while (0) + +#define LOAD_MSG_7_3(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m2, m7); \ + b1 = _mm_unpacklo_epi64(m4, m1); \ + } while (0) + +#define LOAD_MSG_7_4(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m0, m2); \ + b1 = _mm_unpacklo_epi64(m3, m5); \ + } while (0) + +#define LOAD_MSG_8_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m3, m7); \ + b1 = _mm_alignr_epi8(m0, m5, 8); \ + } while (0) + +#define LOAD_MSG_8_2(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m7, m4); \ + b1 = _mm_alignr_epi8(m4, m1, 8); \ + } while (0) + +#define LOAD_MSG_8_3(b0, b1) \ + do { \ + b0 = m6; \ + b1 = _mm_alignr_epi8(m5, m0, 8); \ + } while (0) + +#define LOAD_MSG_8_4(b0, b1) \ + do { \ + b0 = _mm_blend_epi16(m1, m3, 0xF0); \ + b1 = m2; \ + } while (0) + +#define LOAD_MSG_9_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m5, m4); \ + b1 = _mm_unpackhi_epi64(m3, m0); \ + } while (0) + +#define LOAD_MSG_9_2(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m1, m2); \ + b1 = _mm_blend_epi16(m3, m2, 0xF0); \ + } while (0) + +#define LOAD_MSG_9_3(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m7, m4); \ + b1 = _mm_unpackhi_epi64(m1, m6); \ + } while (0) + +#define LOAD_MSG_9_4(b0, b1) \ + do { \ + b0 = _mm_alignr_epi8(m7, m5, 8); \ + b1 = _mm_unpacklo_epi64(m6, m0); \ + } while (0) + +#define LOAD_MSG_10_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m0, m1); \ + b1 = _mm_unpacklo_epi64(m2, m3); \ + } while (0) + +#define LOAD_MSG_10_2(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m0, m1); \ + b1 = _mm_unpackhi_epi64(m2, m3); \ + } while (0) + +#define LOAD_MSG_10_3(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m4, m5); \ + b1 = _mm_unpacklo_epi64(m6, m7); \ + } while (0) + +#define LOAD_MSG_10_4(b0, b1) \ + do { \ + b0 = _mm_unpackhi_epi64(m4, m5); \ + b1 = _mm_unpackhi_epi64(m6, m7); \ + } while (0) + +#define LOAD_MSG_11_1(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m7, m2); \ + b1 = _mm_unpackhi_epi64(m4, m6); \ + } while (0) + +#define LOAD_MSG_11_2(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m5, m4); \ + b1 = _mm_alignr_epi8(m3, m7, 8); \ + } while (0) + +#define LOAD_MSG_11_3(b0, b1) \ + do { \ + b0 = _mm_shuffle_epi32(m0, _MM_SHUFFLE(1, 0, 3, 2)); \ + b1 = _mm_unpackhi_epi64(m5, m2); \ + } while (0) + +#define LOAD_MSG_11_4(b0, b1) \ + do { \ + b0 = _mm_unpacklo_epi64(m6, m1); \ + b1 = _mm_unpackhi_epi64(m3, m1); \ + } while (0) + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-ref.c b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-ref.c new file mode 100644 index 0000000..a1beacf --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/blake2b-ref.c @@ -0,0 +1,438 @@ +/* + BLAKE2 reference source code package - C implementations + + Written in 2012 by Samuel Neves + + To the extent possible under law, the author(s) have dedicated all copyright + and related and neighboring rights to this software to the public domain + worldwide. This software is distributed without any warranty. + + You should have received a copy of the CC0 Public Domain Dedication along + with + this software. If not, see + . +*/ + +#include +#include +#include +#include +#include + +#include "blake2.h" +#include "core.h" +#include "private/common.h" +#include "runtime.h" +#include "utils.h" + +static blake2b_compress_fn blake2b_compress = blake2b_compress_ref; + +static const uint64_t blake2b_IV[8] = { + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL +}; + +/* LCOV_EXCL_START */ +static inline int +blake2b_set_lastnode(blake2b_state *S) +{ + S->f[1] = -1; + return 0; +} +/* LCOV_EXCL_STOP */ + +static inline int +blake2b_is_lastblock(const blake2b_state *S) +{ + return S->f[0] != 0; +} + +static inline int +blake2b_set_lastblock(blake2b_state *S) +{ + if (S->last_node) { + blake2b_set_lastnode(S); + } + S->f[0] = -1; + return 0; +} + +static inline int +blake2b_increment_counter(blake2b_state *S, const uint64_t inc) +{ +#ifdef HAVE_TI_MODE + uint128_t t = ((uint128_t) S->t[1] << 64) | S->t[0]; + t += inc; + S->t[0] = (uint64_t)(t >> 0); + S->t[1] = (uint64_t)(t >> 64); +#else + S->t[0] += inc; + S->t[1] += (S->t[0] < inc); +#endif + return 0; +} + +/* Parameter-related functions */ +static inline int +blake2b_param_set_salt(blake2b_param *P, const uint8_t salt[BLAKE2B_SALTBYTES]) +{ + memcpy(P->salt, salt, BLAKE2B_SALTBYTES); + return 0; +} + +static inline int +blake2b_param_set_personal(blake2b_param *P, + const uint8_t personal[BLAKE2B_PERSONALBYTES]) +{ + memcpy(P->personal, personal, BLAKE2B_PERSONALBYTES); + return 0; +} + +static inline int +blake2b_init0(blake2b_state *S) +{ + int i; + + for (i = 0; i < 8; i++) { + S->h[i] = blake2b_IV[i]; + } + /* zero everything between .t and .last_node */ + memset((void *) &S->t, 0, + offsetof(blake2b_state, last_node) + sizeof(S->last_node) + - offsetof(blake2b_state, t)); + return 0; +} + +/* init xors IV with input parameter block */ +int +blake2b_init_param(blake2b_state *S, const blake2b_param *P) +{ + size_t i; + const uint8_t *p; + + COMPILER_ASSERT(sizeof *P == 64); + blake2b_init0(S); + p = (const uint8_t *) (P); + + /* IV XOR ParamBlock */ + for (i = 0; i < 8; i++) { + S->h[i] ^= LOAD64_LE(p + sizeof(S->h[i]) * i); + } + return 0; +} + +int +blake2b_init(blake2b_state *S, const uint8_t outlen) +{ + blake2b_param P[1]; + + if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) { + sodium_misuse(); + } + P->digest_length = outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + STORE32_LE(P->leaf_length, 0); + STORE64_LE(P->node_offset, 0); + P->node_depth = 0; + P->inner_length = 0; + memset(P->reserved, 0, sizeof(P->reserved)); + memset(P->salt, 0, sizeof(P->salt)); + memset(P->personal, 0, sizeof(P->personal)); + return blake2b_init_param(S, P); +} + +int +blake2b_init_salt_personal(blake2b_state *S, const uint8_t outlen, + const void *salt, const void *personal) +{ + blake2b_param P[1]; + + if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) { + sodium_misuse(); + } + P->digest_length = outlen; + P->key_length = 0; + P->fanout = 1; + P->depth = 1; + STORE32_LE(P->leaf_length, 0); + STORE64_LE(P->node_offset, 0); + P->node_depth = 0; + P->inner_length = 0; + memset(P->reserved, 0, sizeof(P->reserved)); + if (salt != NULL) { + blake2b_param_set_salt(P, (const uint8_t *) salt); + } else { + memset(P->salt, 0, sizeof(P->salt)); + } + if (personal != NULL) { + blake2b_param_set_personal(P, (const uint8_t *) personal); + } else { + memset(P->personal, 0, sizeof(P->personal)); + } + return blake2b_init_param(S, P); +} + +int +blake2b_init_key(blake2b_state *S, const uint8_t outlen, const void *key, + const uint8_t keylen) +{ + blake2b_param P[1]; + + if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) { + sodium_misuse(); + } + if (!key || !keylen || keylen > BLAKE2B_KEYBYTES) { + sodium_misuse(); /* does not return */ + } + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = 1; + P->depth = 1; + STORE32_LE(P->leaf_length, 0); + STORE64_LE(P->node_offset, 0); + P->node_depth = 0; + P->inner_length = 0; + memset(P->reserved, 0, sizeof(P->reserved)); + memset(P->salt, 0, sizeof(P->salt)); + memset(P->personal, 0, sizeof(P->personal)); + + if (blake2b_init_param(S, P) < 0) { + sodium_misuse(); + } + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset(block, 0, BLAKE2B_BLOCKBYTES); + memcpy(block, key, keylen); /* key and keylen cannot be 0 */ + blake2b_update(S, block, BLAKE2B_BLOCKBYTES); + sodium_memzero(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */ + } + return 0; +} + +int +blake2b_init_key_salt_personal(blake2b_state *S, const uint8_t outlen, + const void *key, const uint8_t keylen, + const void *salt, const void *personal) +{ + blake2b_param P[1]; + + if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) { + sodium_misuse(); + } + if (!key || !keylen || keylen > BLAKE2B_KEYBYTES) { + sodium_misuse(); /* does not return */ + } + P->digest_length = outlen; + P->key_length = keylen; + P->fanout = 1; + P->depth = 1; + STORE32_LE(P->leaf_length, 0); + STORE64_LE(P->node_offset, 0); + P->node_depth = 0; + P->inner_length = 0; + memset(P->reserved, 0, sizeof(P->reserved)); + if (salt != NULL) { + blake2b_param_set_salt(P, (const uint8_t *) salt); + } else { + memset(P->salt, 0, sizeof(P->salt)); + } + if (personal != NULL) { + blake2b_param_set_personal(P, (const uint8_t *) personal); + } else { + memset(P->personal, 0, sizeof(P->personal)); + } + + if (blake2b_init_param(S, P) < 0) { + sodium_misuse(); + } + { + uint8_t block[BLAKE2B_BLOCKBYTES]; + memset(block, 0, BLAKE2B_BLOCKBYTES); + memcpy(block, key, keylen); /* key and keylen cannot be 0 */ + blake2b_update(S, block, BLAKE2B_BLOCKBYTES); + sodium_memzero(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */ + } + return 0; +} + +/* inlen now in bytes */ +int +blake2b_update(blake2b_state *S, const uint8_t *in, uint64_t inlen) +{ + while (inlen > 0) { + size_t left = S->buflen; + size_t fill = 2 * BLAKE2B_BLOCKBYTES - left; + + if (inlen > fill) { + memcpy(S->buf + left, in, fill); /* Fill buffer */ + S->buflen += fill; + blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); + blake2b_compress(S, S->buf); /* Compress */ + memcpy(S->buf, S->buf + BLAKE2B_BLOCKBYTES, + BLAKE2B_BLOCKBYTES); /* Shift buffer left */ + S->buflen -= BLAKE2B_BLOCKBYTES; + in += fill; + inlen -= fill; + } else /* inlen <= fill */ + { + memcpy(S->buf + left, in, inlen); + S->buflen += inlen; /* Be lazy, do not compress */ + in += inlen; + inlen -= inlen; + } + } + + return 0; +} + +int +blake2b_final(blake2b_state *S, uint8_t *out, uint8_t outlen) +{ + unsigned char buffer[BLAKE2B_OUTBYTES]; + + if (!outlen || outlen > BLAKE2B_OUTBYTES) { + sodium_misuse(); + } + if (blake2b_is_lastblock(S)) { + return -1; + } + if (S->buflen > BLAKE2B_BLOCKBYTES) { + blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); + blake2b_compress(S, S->buf); + S->buflen -= BLAKE2B_BLOCKBYTES; + assert(S->buflen <= BLAKE2B_BLOCKBYTES); + memcpy(S->buf, S->buf + BLAKE2B_BLOCKBYTES, S->buflen); + } + + blake2b_increment_counter(S, S->buflen); + blake2b_set_lastblock(S); + memset(S->buf + S->buflen, 0, + 2 * BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */ + blake2b_compress(S, S->buf); + + COMPILER_ASSERT(sizeof buffer == 64U); + STORE64_LE(buffer + 8 * 0, S->h[0]); + STORE64_LE(buffer + 8 * 1, S->h[1]); + STORE64_LE(buffer + 8 * 2, S->h[2]); + STORE64_LE(buffer + 8 * 3, S->h[3]); + STORE64_LE(buffer + 8 * 4, S->h[4]); + STORE64_LE(buffer + 8 * 5, S->h[5]); + STORE64_LE(buffer + 8 * 6, S->h[6]); + STORE64_LE(buffer + 8 * 7, S->h[7]); + memcpy(out, buffer, outlen); /* outlen <= BLAKE2B_OUTBYTES (64) */ + + sodium_memzero(S->h, sizeof S->h); + sodium_memzero(S->buf, sizeof S->buf); + + return 0; +} + +/* inlen, at least, should be uint64_t. Others can be size_t. */ +int +blake2b(uint8_t *out, const void *in, const void *key, const uint8_t outlen, + const uint64_t inlen, uint8_t keylen) +{ + CRYPTO_ALIGN(64) blake2b_state S[1]; + + /* Verify parameters */ + if (NULL == in && inlen > 0) { + sodium_misuse(); + } + if (NULL == out) { + sodium_misuse(); + } + if (!outlen || outlen > BLAKE2B_OUTBYTES) { + sodium_misuse(); + } + if (NULL == key && keylen > 0) { + sodium_misuse(); + } + if (keylen > BLAKE2B_KEYBYTES) { + sodium_misuse(); + } + if (keylen > 0) { + if (blake2b_init_key(S, outlen, key, keylen) < 0) { + sodium_misuse(); + } + } else { + if (blake2b_init(S, outlen) < 0) { + sodium_misuse(); + } + } + + blake2b_update(S, (const uint8_t *) in, inlen); + blake2b_final(S, out, outlen); + return 0; +} + +int +blake2b_salt_personal(uint8_t *out, const void *in, const void *key, + const uint8_t outlen, const uint64_t inlen, + uint8_t keylen, const void *salt, const void *personal) +{ + CRYPTO_ALIGN(64) blake2b_state S[1]; + + /* Verify parameters */ + if (NULL == in && inlen > 0) { + sodium_misuse(); + } + if (NULL == out) { + sodium_misuse(); + } + if (!outlen || outlen > BLAKE2B_OUTBYTES) { + sodium_misuse(); + } + if (NULL == key && keylen > 0) { + sodium_misuse(); + } + if (keylen > BLAKE2B_KEYBYTES) { + sodium_misuse(); + } + if (keylen > 0) { + if (blake2b_init_key_salt_personal(S, outlen, key, keylen, salt, + personal) < 0) { + sodium_misuse(); + } + } else { + if (blake2b_init_salt_personal(S, outlen, salt, personal) < 0) { + sodium_misuse(); + } + } + + blake2b_update(S, (const uint8_t *) in, inlen); + blake2b_final(S, out, outlen); + return 0; +} + +int +blake2b_pick_best_implementation(void) +{ +/* LCOV_EXCL_START */ +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_TMMINTRIN_H) && \ + defined(HAVE_SMMINTRIN_H) + if (sodium_runtime_has_avx2()) { + blake2b_compress = blake2b_compress_avx2; + return 0; + } +#endif +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) && \ + defined(HAVE_SMMINTRIN_H) + if (sodium_runtime_has_sse41()) { + blake2b_compress = blake2b_compress_sse41; + return 0; + } +#endif +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) + if (sodium_runtime_has_ssse3()) { + blake2b_compress = blake2b_compress_ssse3; + return 0; + } +#endif + blake2b_compress = blake2b_compress_ref; + + return 0; + /* LCOV_EXCL_STOP */ +} diff --git a/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/generichash_blake2b.c b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/generichash_blake2b.c new file mode 100644 index 0000000..7a8598c --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_generichash/blake2b/ref/generichash_blake2b.c @@ -0,0 +1,116 @@ + +#include +#include +#include + +#include "blake2.h" +#include "crypto_generichash_blake2b.h" +#include "private/common.h" +#include "private/implementations.h" + +int +crypto_generichash_blake2b(unsigned char *out, size_t outlen, + const unsigned char *in, unsigned long long inlen, + const unsigned char *key, size_t keylen) +{ + if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES || + keylen > BLAKE2B_KEYBYTES || inlen > UINT64_MAX) { + return -1; + } + assert(outlen <= UINT8_MAX); + assert(keylen <= UINT8_MAX); + + return blake2b((uint8_t *) out, in, key, (uint8_t) outlen, (uint64_t) inlen, + (uint8_t) keylen); +} + +int +crypto_generichash_blake2b_salt_personal( + unsigned char *out, size_t outlen, const unsigned char *in, + unsigned long long inlen, const unsigned char *key, size_t keylen, + const unsigned char *salt, const unsigned char *personal) +{ + if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES || + keylen > BLAKE2B_KEYBYTES || inlen > UINT64_MAX) { + return -1; + } + assert(outlen <= UINT8_MAX); + assert(keylen <= UINT8_MAX); + + return blake2b_salt_personal((uint8_t *) out, in, key, (uint8_t) outlen, + (uint64_t) inlen, (uint8_t) keylen, salt, + personal); +} + +int +crypto_generichash_blake2b_init(crypto_generichash_blake2b_state *state, + const unsigned char *key, const size_t keylen, + const size_t outlen) +{ + if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES || + keylen > BLAKE2B_KEYBYTES) { + return -1; + } + assert(outlen <= UINT8_MAX); + assert(keylen <= UINT8_MAX); + COMPILER_ASSERT(sizeof(blake2b_state) <= sizeof *state); + if (key == NULL || keylen <= 0U) { + if (blake2b_init((blake2b_state *) (void *) state, (uint8_t) outlen) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + } else if (blake2b_init_key((blake2b_state *) (void *) state, (uint8_t) outlen, key, + (uint8_t) keylen) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; +} + +int +crypto_generichash_blake2b_init_salt_personal( + crypto_generichash_blake2b_state *state, const unsigned char *key, + const size_t keylen, const size_t outlen, const unsigned char *salt, + const unsigned char *personal) +{ + if (outlen <= 0U || outlen > BLAKE2B_OUTBYTES || + keylen > BLAKE2B_KEYBYTES) { + return -1; + } + assert(outlen <= UINT8_MAX); + assert(keylen <= UINT8_MAX); + if (key == NULL || keylen <= 0U) { + if (blake2b_init_salt_personal((blake2b_state *) (void *) state, + (uint8_t) outlen, salt, personal) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + } else if (blake2b_init_key_salt_personal((blake2b_state *) (void *) state, + (uint8_t) outlen, key, + (uint8_t) keylen, salt, + personal) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; +} + +int +crypto_generichash_blake2b_update(crypto_generichash_blake2b_state *state, + const unsigned char *in, + unsigned long long inlen) +{ + return blake2b_update((blake2b_state *) (void *) state, + (const uint8_t *) in, (uint64_t) inlen); +} + +int +crypto_generichash_blake2b_final(crypto_generichash_blake2b_state *state, + unsigned char *out, const size_t outlen) +{ + assert(outlen <= UINT8_MAX); + return blake2b_final((blake2b_state *) (void *) state, + (uint8_t *) out, (uint8_t) outlen); +} + +int +_crypto_generichash_blake2b_pick_best_implementation(void) +{ + return blake2b_pick_best_implementation(); +} diff --git a/external/src/libsodium/src/libsodium/crypto_generichash/crypto_generichash.c b/external/src/libsodium/src/libsodium/crypto_generichash/crypto_generichash.c new file mode 100644 index 0000000..a9a14e9 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_generichash/crypto_generichash.c @@ -0,0 +1,91 @@ + +#include "crypto_generichash.h" +#include "randombytes.h" + +size_t +crypto_generichash_bytes_min(void) +{ + return crypto_generichash_BYTES_MIN; +} + +size_t +crypto_generichash_bytes_max(void) +{ + return crypto_generichash_BYTES_MAX; +} + +size_t +crypto_generichash_bytes(void) +{ + return crypto_generichash_BYTES; +} + +size_t +crypto_generichash_keybytes_min(void) +{ + return crypto_generichash_KEYBYTES_MIN; +} + +size_t +crypto_generichash_keybytes_max(void) +{ + return crypto_generichash_KEYBYTES_MAX; +} + +size_t +crypto_generichash_keybytes(void) +{ + return crypto_generichash_KEYBYTES; +} + +const char * +crypto_generichash_primitive(void) +{ + return crypto_generichash_PRIMITIVE; +} + +size_t +crypto_generichash_statebytes(void) +{ + return (sizeof(crypto_generichash_state) + (size_t) 63U) & ~(size_t) 63U; +} + +int +crypto_generichash(unsigned char *out, size_t outlen, const unsigned char *in, + unsigned long long inlen, const unsigned char *key, + size_t keylen) +{ + return crypto_generichash_blake2b(out, outlen, in, inlen, key, keylen); +} + +int +crypto_generichash_init(crypto_generichash_state *state, + const unsigned char *key, + const size_t keylen, const size_t outlen) +{ + return crypto_generichash_blake2b_init + ((crypto_generichash_blake2b_state *) state, key, keylen, outlen); +} + +int +crypto_generichash_update(crypto_generichash_state *state, + const unsigned char *in, + unsigned long long inlen) +{ + return crypto_generichash_blake2b_update + ((crypto_generichash_blake2b_state *) state, in, inlen); +} + +int +crypto_generichash_final(crypto_generichash_state *state, + unsigned char *out, const size_t outlen) +{ + return crypto_generichash_blake2b_final + ((crypto_generichash_blake2b_state *) state, out, outlen); +} + +void +crypto_generichash_keygen(unsigned char k[crypto_generichash_KEYBYTES]) +{ + randombytes_buf(k, crypto_generichash_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_hash/crypto_hash.c b/external/src/libsodium/src/libsodium/crypto_hash/crypto_hash.c new file mode 100644 index 0000000..855c560 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_hash/crypto_hash.c @@ -0,0 +1,20 @@ + +#include "crypto_hash.h" + +size_t +crypto_hash_bytes(void) +{ + return crypto_hash_BYTES; +} + +int +crypto_hash(unsigned char *out, const unsigned char *in, + unsigned long long inlen) +{ + return crypto_hash_sha512(out, in, inlen); +} + +const char * +crypto_hash_primitive(void) { + return crypto_hash_PRIMITIVE; +} diff --git a/external/src/libsodium/src/libsodium/crypto_hash/sha256/cp/hash_sha256_cp.c b/external/src/libsodium/src/libsodium/crypto_hash/sha256/cp/hash_sha256_cp.c new file mode 100644 index 0000000..264054f --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_hash/sha256/cp/hash_sha256_cp.c @@ -0,0 +1,254 @@ + +/*- + * Copyright 2005,2007,2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +#include +#include +#include + +#include + +#include "crypto_hash_sha256.h" +#include "private/common.h" +#include "utils.h" + +static void +be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len) +{ + size_t i; + + for (i = 0; i < len / 4; i++) { + STORE32_BE(dst + i * 4, src[i]); + } +} + +static void +be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len) +{ + size_t i; + + for (i = 0; i < len / 4; i++) { + dst[i] = LOAD32_BE(src + i * 4); + } +} + +static const uint32_t Krnd[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, + 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, + 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, + 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, + 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, + 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +#define Ch(x, y, z) ((x & (y ^ z)) ^ z) +#define Maj(x, y, z) ((x & (y | z)) | (y & z)) +#define SHR(x, n) (x >> n) +#define ROTR(x, n) ROTR32(x, n) +#define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) +#define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) +#define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) +#define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) + +#define RND(a, b, c, d, e, f, g, h, k) \ + h += S1(e) + Ch(e, f, g) + k; \ + d += h; \ + h += S0(a) + Maj(a, b, c); + +#define RNDr(S, W, i, ii) \ + RND(S[(64 - i) % 8], S[(65 - i) % 8], S[(66 - i) % 8], S[(67 - i) % 8], \ + S[(68 - i) % 8], S[(69 - i) % 8], S[(70 - i) % 8], S[(71 - i) % 8], \ + W[i + ii] + Krnd[i + ii]) + +#define MSCH(W, ii, i) \ + W[i + ii + 16] = \ + s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii] + +static void +SHA256_Transform(uint32_t state[8], const uint8_t block[64], uint32_t W[64], + uint32_t S[8]) +{ + int i; + + be32dec_vect(W, block, 64); + memcpy(S, state, 32); + for (i = 0; i < 64; i += 16) { + RNDr(S, W, 0, i); + RNDr(S, W, 1, i); + RNDr(S, W, 2, i); + RNDr(S, W, 3, i); + RNDr(S, W, 4, i); + RNDr(S, W, 5, i); + RNDr(S, W, 6, i); + RNDr(S, W, 7, i); + RNDr(S, W, 8, i); + RNDr(S, W, 9, i); + RNDr(S, W, 10, i); + RNDr(S, W, 11, i); + RNDr(S, W, 12, i); + RNDr(S, W, 13, i); + RNDr(S, W, 14, i); + RNDr(S, W, 15, i); + if (i == 48) { + break; + } + MSCH(W, 0, i); + MSCH(W, 1, i); + MSCH(W, 2, i); + MSCH(W, 3, i); + MSCH(W, 4, i); + MSCH(W, 5, i); + MSCH(W, 6, i); + MSCH(W, 7, i); + MSCH(W, 8, i); + MSCH(W, 9, i); + MSCH(W, 10, i); + MSCH(W, 11, i); + MSCH(W, 12, i); + MSCH(W, 13, i); + MSCH(W, 14, i); + MSCH(W, 15, i); + } + for (i = 0; i < 8; i++) { + state[i] += S[i]; + } +} + +static const uint8_t PAD[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +static void +SHA256_Pad(crypto_hash_sha256_state *state, uint32_t tmp32[64 + 8]) +{ + unsigned int r; + unsigned int i; + + r = (unsigned int) ((state->count >> 3) & 0x3f); + if (r < 56) { + for (i = 0; i < 56 - r; i++) { + state->buf[r + i] = PAD[i]; + } + } else { + for (i = 0; i < 64 - r; i++) { + state->buf[r + i] = PAD[i]; + } + SHA256_Transform(state->state, state->buf, &tmp32[0], &tmp32[64]); + memset(&state->buf[0], 0, 56); + } + STORE64_BE(&state->buf[56], state->count); + SHA256_Transform(state->state, state->buf, &tmp32[0], &tmp32[64]); +} + +int +crypto_hash_sha256_init(crypto_hash_sha256_state *state) +{ + static const uint32_t sha256_initial_state[8] = { 0x6a09e667, 0xbb67ae85, + 0x3c6ef372, 0xa54ff53a, + 0x510e527f, 0x9b05688c, + 0x1f83d9ab, 0x5be0cd19 }; + + state->count = (uint64_t) 0U; + memcpy(state->state, sha256_initial_state, sizeof sha256_initial_state); + + return 0; +} + +int +crypto_hash_sha256_update(crypto_hash_sha256_state *state, + const unsigned char *in, unsigned long long inlen) +{ + uint32_t tmp32[64 + 8]; + unsigned long long i; + unsigned long long r; + + if (inlen <= 0U) { + return 0; + } + r = (unsigned long long) ((state->count >> 3) & 0x3f); + + state->count += ((uint64_t) inlen) << 3; + if (inlen < 64 - r) { + for (i = 0; i < inlen; i++) { + state->buf[r + i] = in[i]; + } + return 0; + } + for (i = 0; i < 64 - r; i++) { + state->buf[r + i] = in[i]; + } + SHA256_Transform(state->state, state->buf, &tmp32[0], &tmp32[64]); + in += 64 - r; + inlen -= 64 - r; + + while (inlen >= 64) { + SHA256_Transform(state->state, in, &tmp32[0], &tmp32[64]); + in += 64; + inlen -= 64; + } + inlen &= 63; + for (i = 0; i < inlen; i++) { + state->buf[i] = in[i]; + } + sodium_memzero((void *) tmp32, sizeof tmp32); + + return 0; +} + +int +crypto_hash_sha256_final(crypto_hash_sha256_state *state, unsigned char *out) +{ + uint32_t tmp32[64 + 8]; + + SHA256_Pad(state, tmp32); + be32enc_vect(out, state->state, 32); + sodium_memzero((void *) tmp32, sizeof tmp32); + sodium_memzero((void *) state, sizeof *state); + + return 0; +} + +int +crypto_hash_sha256(unsigned char *out, const unsigned char *in, + unsigned long long inlen) +{ + crypto_hash_sha256_state state; + + crypto_hash_sha256_init(&state); + crypto_hash_sha256_update(&state, in, inlen); + crypto_hash_sha256_final(&state, out); + + return 0; +} diff --git a/external/src/libsodium/src/libsodium/crypto_hash/sha256/hash_sha256.c b/external/src/libsodium/src/libsodium/crypto_hash/sha256/hash_sha256.c new file mode 100644 index 0000000..e729c81 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_hash/sha256/hash_sha256.c @@ -0,0 +1,13 @@ +#include "crypto_hash_sha256.h" + +size_t +crypto_hash_sha256_bytes(void) +{ + return crypto_hash_sha256_BYTES; +} + +size_t +crypto_hash_sha256_statebytes(void) +{ + return sizeof(crypto_hash_sha256_state); +} diff --git a/external/src/libsodium/src/libsodium/crypto_hash/sha512/cp/hash_sha512_cp.c b/external/src/libsodium/src/libsodium/crypto_hash/sha512/cp/hash_sha512_cp.c new file mode 100644 index 0000000..8e0f36f --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_hash/sha512/cp/hash_sha512_cp.c @@ -0,0 +1,282 @@ + +/*- + * Copyright 2005,2007,2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +#include +#include +#include + +#include + +#include "crypto_hash_sha512.h" +#include "private/common.h" +#include "utils.h" + +static void +be64enc_vect(unsigned char *dst, const uint64_t *src, size_t len) +{ + size_t i; + + for (i = 0; i < len / 8; i++) { + STORE64_BE(dst + i * 8, src[i]); + } +} + +static void +be64dec_vect(uint64_t *dst, const unsigned char *src, size_t len) +{ + size_t i; + + for (i = 0; i < len / 8; i++) { + dst[i] = LOAD64_BE(src + i * 8); + } +} + +static const uint64_t Krnd[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, + 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, + 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, + 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, + 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, + 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, + 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, + 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, + 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, + 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, + 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, + 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, + 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, + 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL +}; + +#define Ch(x, y, z) ((x & (y ^ z)) ^ z) +#define Maj(x, y, z) ((x & (y | z)) | (y & z)) +#define SHR(x, n) (x >> n) +#define ROTR(x, n) ROTR64(x, n) +#define S0(x) (ROTR(x, 28) ^ ROTR(x, 34) ^ ROTR(x, 39)) +#define S1(x) (ROTR(x, 14) ^ ROTR(x, 18) ^ ROTR(x, 41)) +#define s0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) +#define s1(x) (ROTR(x, 19) ^ ROTR(x, 61) ^ SHR(x, 6)) + +#define RND(a, b, c, d, e, f, g, h, k) \ + h += S1(e) + Ch(e, f, g) + k; \ + d += h; \ + h += S0(a) + Maj(a, b, c); + +#define RNDr(S, W, i, ii) \ + RND(S[(80 - i) % 8], S[(81 - i) % 8], S[(82 - i) % 8], S[(83 - i) % 8], \ + S[(84 - i) % 8], S[(85 - i) % 8], S[(86 - i) % 8], S[(87 - i) % 8], \ + W[i + ii] + Krnd[i + ii]) + +#define MSCH(W, ii, i) \ + W[i + ii + 16] = \ + s1(W[i + ii + 14]) + W[i + ii + 9] + s0(W[i + ii + 1]) + W[i + ii] + +static void +SHA512_Transform(uint64_t *state, const uint8_t block[128], uint64_t W[80], + uint64_t S[8]) +{ + int i; + + be64dec_vect(W, block, 128); + memcpy(S, state, 64); + for (i = 0; i < 80; i += 16) { + RNDr(S, W, 0, i); + RNDr(S, W, 1, i); + RNDr(S, W, 2, i); + RNDr(S, W, 3, i); + RNDr(S, W, 4, i); + RNDr(S, W, 5, i); + RNDr(S, W, 6, i); + RNDr(S, W, 7, i); + RNDr(S, W, 8, i); + RNDr(S, W, 9, i); + RNDr(S, W, 10, i); + RNDr(S, W, 11, i); + RNDr(S, W, 12, i); + RNDr(S, W, 13, i); + RNDr(S, W, 14, i); + RNDr(S, W, 15, i); + if (i == 64) { + break; + } + MSCH(W, 0, i); + MSCH(W, 1, i); + MSCH(W, 2, i); + MSCH(W, 3, i); + MSCH(W, 4, i); + MSCH(W, 5, i); + MSCH(W, 6, i); + MSCH(W, 7, i); + MSCH(W, 8, i); + MSCH(W, 9, i); + MSCH(W, 10, i); + MSCH(W, 11, i); + MSCH(W, 12, i); + MSCH(W, 13, i); + MSCH(W, 14, i); + MSCH(W, 15, i); + } + for (i = 0; i < 8; i++) { + state[i] += S[i]; + } +} + +static const uint8_t PAD[128] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static void +SHA512_Pad(crypto_hash_sha512_state *state, uint64_t tmp64[80 + 8]) +{ + unsigned int r; + unsigned int i; + + r = (unsigned int) ((state->count[1] >> 3) & 0x7f); + if (r < 112) { + for (i = 0; i < 112 - r; i++) { + state->buf[r + i] = PAD[i]; + } + } else { + for (i = 0; i < 128 - r; i++) { + state->buf[r + i] = PAD[i]; + } + SHA512_Transform(state->state, state->buf, &tmp64[0], &tmp64[80]); + memset(&state->buf[0], 0, 112); + } + be64enc_vect(&state->buf[112], state->count, 16); + SHA512_Transform(state->state, state->buf, &tmp64[0], &tmp64[80]); +} + +int +crypto_hash_sha512_init(crypto_hash_sha512_state *state) +{ + static const uint64_t sha512_initial_state[8] = { + 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL + }; + + state->count[0] = state->count[1] = (uint64_t) 0U; + memcpy(state->state, sha512_initial_state, sizeof sha512_initial_state); + + return 0; +} + +int +crypto_hash_sha512_update(crypto_hash_sha512_state *state, + const unsigned char *in, unsigned long long inlen) +{ + uint64_t tmp64[80 + 8]; + uint64_t bitlen[2]; + unsigned long long i; + unsigned long long r; + + if (inlen <= 0U) { + return 0; + } + r = (unsigned long long) ((state->count[1] >> 3) & 0x7f); + + bitlen[1] = ((uint64_t) inlen) << 3; + bitlen[0] = ((uint64_t) inlen) >> 61; + /* LCOV_EXCL_START */ + if ((state->count[1] += bitlen[1]) < bitlen[1]) { + state->count[0]++; + } + /* LCOV_EXCL_STOP */ + state->count[0] += bitlen[0]; + if (inlen < 128 - r) { + for (i = 0; i < inlen; i++) { + state->buf[r + i] = in[i]; + } + return 0; + } + for (i = 0; i < 128 - r; i++) { + state->buf[r + i] = in[i]; + } + SHA512_Transform(state->state, state->buf, &tmp64[0], &tmp64[80]); + in += 128 - r; + inlen -= 128 - r; + + while (inlen >= 128) { + SHA512_Transform(state->state, in, &tmp64[0], &tmp64[80]); + in += 128; + inlen -= 128; + } + inlen &= 127; + for (i = 0; i < inlen; i++) { + state->buf[i] = in[i]; + } + sodium_memzero((void *) tmp64, sizeof tmp64); + + return 0; +} + +int +crypto_hash_sha512_final(crypto_hash_sha512_state *state, unsigned char *out) +{ + uint64_t tmp64[80 + 8]; + + SHA512_Pad(state, tmp64); + be64enc_vect(out, state->state, 64); + sodium_memzero((void *) tmp64, sizeof tmp64); + sodium_memzero((void *) state, sizeof *state); + + return 0; +} + +int +crypto_hash_sha512(unsigned char *out, const unsigned char *in, + unsigned long long inlen) +{ + crypto_hash_sha512_state state; + + crypto_hash_sha512_init(&state); + crypto_hash_sha512_update(&state, in, inlen); + crypto_hash_sha512_final(&state, out); + + return 0; +} diff --git a/external/src/libsodium/src/libsodium/crypto_hash/sha512/hash_sha512.c b/external/src/libsodium/src/libsodium/crypto_hash/sha512/hash_sha512.c new file mode 100644 index 0000000..ba842b8 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_hash/sha512/hash_sha512.c @@ -0,0 +1,13 @@ +#include "crypto_hash_sha512.h" + +size_t +crypto_hash_sha512_bytes(void) +{ + return crypto_hash_sha512_BYTES; +} + +size_t +crypto_hash_sha512_statebytes(void) +{ + return sizeof(crypto_hash_sha512_state); +} diff --git a/external/src/libsodium/src/libsodium/crypto_kdf/blake2b/kdf_blake2b.c b/external/src/libsodium/src/libsodium/crypto_kdf/blake2b/kdf_blake2b.c new file mode 100644 index 0000000..2a690c9 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_kdf/blake2b/kdf_blake2b.c @@ -0,0 +1,52 @@ +#include + +#include "crypto_kdf_blake2b.h" +#include "crypto_generichash_blake2b.h" +#include "private/common.h" + +size_t +crypto_kdf_blake2b_bytes_min(void) +{ + return crypto_kdf_blake2b_BYTES_MIN; +} + +size_t +crypto_kdf_blake2b_bytes_max(void) +{ + return crypto_kdf_blake2b_BYTES_MAX; +} + +size_t +crypto_kdf_blake2b_contextbytes(void) +{ + return crypto_kdf_blake2b_CONTEXTBYTES; +} + +size_t +crypto_kdf_blake2b_keybytes(void) +{ + return crypto_kdf_blake2b_KEYBYTES; +} + +int crypto_kdf_blake2b_derive_from_key(unsigned char *subkey, size_t subkey_len, + uint64_t subkey_id, + const char ctx[crypto_kdf_blake2b_CONTEXTBYTES], + const unsigned char key[crypto_kdf_blake2b_KEYBYTES]) +{ + unsigned char ctx_padded[crypto_generichash_blake2b_PERSONALBYTES]; + unsigned char salt[crypto_generichash_blake2b_SALTBYTES]; + + memcpy(ctx_padded, ctx, crypto_kdf_blake2b_CONTEXTBYTES); + memset(ctx_padded + crypto_kdf_blake2b_CONTEXTBYTES, 0, sizeof ctx_padded - crypto_kdf_blake2b_CONTEXTBYTES); + STORE64_LE(salt, subkey_id); + memset(salt + 8, 0, (sizeof salt) - 8); + if (subkey_len < crypto_kdf_blake2b_BYTES_MIN || + subkey_len > crypto_kdf_blake2b_BYTES_MAX) { + errno = EINVAL; + return -1; + } + return crypto_generichash_blake2b_salt_personal(subkey, subkey_len, + NULL, 0, + key, crypto_kdf_blake2b_KEYBYTES, + salt, ctx_padded); +} diff --git a/external/src/libsodium/src/libsodium/crypto_kdf/crypto_kdf.c b/external/src/libsodium/src/libsodium/crypto_kdf/crypto_kdf.c new file mode 100644 index 0000000..b215d99 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_kdf/crypto_kdf.c @@ -0,0 +1,49 @@ + +#include "crypto_kdf.h" +#include "randombytes.h" + +const char * +crypto_kdf_primitive(void) +{ + return crypto_kdf_PRIMITIVE; +} + +size_t +crypto_kdf_bytes_min(void) +{ + return crypto_kdf_BYTES_MIN; +} + +size_t +crypto_kdf_bytes_max(void) +{ + return crypto_kdf_BYTES_MAX; +} + +size_t +crypto_kdf_contextbytes(void) +{ + return crypto_kdf_CONTEXTBYTES; +} + +size_t +crypto_kdf_keybytes(void) +{ + return crypto_kdf_KEYBYTES; +} + +int +crypto_kdf_derive_from_key(unsigned char *subkey, size_t subkey_len, + uint64_t subkey_id, + const char ctx[crypto_kdf_CONTEXTBYTES], + const unsigned char key[crypto_kdf_KEYBYTES]) +{ + return crypto_kdf_blake2b_derive_from_key(subkey, subkey_len, + subkey_id, ctx, key); +} + +void +crypto_kdf_keygen(unsigned char k[crypto_kdf_KEYBYTES]) +{ + randombytes_buf(k, crypto_kdf_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_kx/crypto_kx.c b/external/src/libsodium/src/libsodium/crypto_kx/crypto_kx.c new file mode 100644 index 0000000..9f0c3ae --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_kx/crypto_kx.c @@ -0,0 +1,143 @@ + +#include + +#include "core.h" +#include "crypto_generichash.h" +#include "crypto_kx.h" +#include "crypto_scalarmult.h" +#include "private/common.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], + unsigned char sk[crypto_kx_SECRETKEYBYTES], + const unsigned char seed[crypto_kx_SEEDBYTES]) +{ + crypto_generichash(sk, crypto_kx_SECRETKEYBYTES, + seed, crypto_kx_SEEDBYTES, NULL, 0); + return crypto_scalarmult_base(pk, sk); +} + +int +crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], + unsigned char sk[crypto_kx_SECRETKEYBYTES]) +{ + COMPILER_ASSERT(crypto_kx_SECRETKEYBYTES == crypto_scalarmult_SCALARBYTES); + COMPILER_ASSERT(crypto_kx_PUBLICKEYBYTES == crypto_scalarmult_BYTES); + + randombytes_buf(sk, crypto_kx_SECRETKEYBYTES); + return crypto_scalarmult_base(pk, sk); +} + +int +crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], + unsigned char tx[crypto_kx_SESSIONKEYBYTES], + const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES], + const unsigned char client_sk[crypto_kx_SECRETKEYBYTES], + const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES]) +{ + crypto_generichash_state h; + unsigned char q[crypto_scalarmult_BYTES]; + unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES]; + int i; + + if (rx == NULL) { + rx = tx; + } + if (tx == NULL) { + tx = rx; + } + if (rx == NULL) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + if (crypto_scalarmult(q, client_sk, server_pk) != 0) { + return -1; + } + COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX); + crypto_generichash_init(&h, NULL, 0U, sizeof keys); + crypto_generichash_update(&h, q, crypto_scalarmult_BYTES); + sodium_memzero(q, sizeof q); + crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES); + crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES); + crypto_generichash_final(&h, keys, sizeof keys); + sodium_memzero(&h, sizeof h); + for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) { + rx[i] = keys[i]; /* rx cannot be NULL */ + tx[i] = keys[i + crypto_kx_SESSIONKEYBYTES]; /* tx cannot be NULL */ + } + sodium_memzero(keys, sizeof keys); + + return 0; +} + +int +crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], + unsigned char tx[crypto_kx_SESSIONKEYBYTES], + const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES], + const unsigned char server_sk[crypto_kx_SECRETKEYBYTES], + const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES]) +{ + crypto_generichash_state h; + unsigned char q[crypto_scalarmult_BYTES]; + unsigned char keys[2 * crypto_kx_SESSIONKEYBYTES]; + int i; + + if (rx == NULL) { + rx = tx; + } + if (tx == NULL) { + tx = rx; + } + if (rx == NULL) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + if (crypto_scalarmult(q, server_sk, client_pk) != 0) { + return -1; + } + COMPILER_ASSERT(sizeof keys <= crypto_generichash_BYTES_MAX); + crypto_generichash_init(&h, NULL, 0U, sizeof keys); + crypto_generichash_update(&h, q, crypto_scalarmult_BYTES); + sodium_memzero(q, sizeof q); + crypto_generichash_update(&h, client_pk, crypto_kx_PUBLICKEYBYTES); + crypto_generichash_update(&h, server_pk, crypto_kx_PUBLICKEYBYTES); + crypto_generichash_final(&h, keys, sizeof keys); + sodium_memzero(&h, sizeof h); + for (i = 0; i < crypto_kx_SESSIONKEYBYTES; i++) { + tx[i] = keys[i]; + rx[i] = keys[i + crypto_kx_SESSIONKEYBYTES]; + } + sodium_memzero(keys, sizeof keys); + + return 0; +} + +size_t +crypto_kx_publickeybytes(void) +{ + return crypto_kx_PUBLICKEYBYTES; +} + +size_t +crypto_kx_secretkeybytes(void) +{ + return crypto_kx_SECRETKEYBYTES; +} + +size_t +crypto_kx_seedbytes(void) +{ + return crypto_kx_SEEDBYTES; +} + +size_t +crypto_kx_sessionkeybytes(void) +{ + return crypto_kx_SESSIONKEYBYTES; +} + +const char * +crypto_kx_primitive(void) +{ + return crypto_kx_PRIMITIVE; +} diff --git a/external/src/libsodium/src/libsodium/crypto_onetimeauth/crypto_onetimeauth.c b/external/src/libsodium/src/libsodium/crypto_onetimeauth/crypto_onetimeauth.c new file mode 100644 index 0000000..93567aa --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_onetimeauth/crypto_onetimeauth.c @@ -0,0 +1,71 @@ + +#include "crypto_onetimeauth.h" +#include "randombytes.h" + +size_t +crypto_onetimeauth_statebytes(void) +{ + return sizeof(crypto_onetimeauth_state); +} + +size_t +crypto_onetimeauth_bytes(void) +{ + return crypto_onetimeauth_BYTES; +} + +size_t +crypto_onetimeauth_keybytes(void) +{ + return crypto_onetimeauth_KEYBYTES; +} + +int +crypto_onetimeauth(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + return crypto_onetimeauth_poly1305(out, in, inlen, k); +} + +int +crypto_onetimeauth_verify(const unsigned char *h, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + return crypto_onetimeauth_poly1305_verify(h, in, inlen, k); +} + +int +crypto_onetimeauth_init(crypto_onetimeauth_state *state, + const unsigned char *key) +{ + return crypto_onetimeauth_poly1305_init + ((crypto_onetimeauth_poly1305_state *) state, key); +} + +int +crypto_onetimeauth_update(crypto_onetimeauth_state *state, + const unsigned char *in, + unsigned long long inlen) +{ + return crypto_onetimeauth_poly1305_update + ((crypto_onetimeauth_poly1305_state *) state, in, inlen); +} + +int +crypto_onetimeauth_final(crypto_onetimeauth_state *state, + unsigned char *out) +{ + return crypto_onetimeauth_poly1305_final + ((crypto_onetimeauth_poly1305_state *) state, out); +} + +const char * +crypto_onetimeauth_primitive(void) +{ + return crypto_onetimeauth_PRIMITIVE; +} + +void crypto_onetimeauth_keygen(unsigned char k[crypto_onetimeauth_KEYBYTES]) +{ + randombytes_buf(k, crypto_onetimeauth_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna.c b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna.c new file mode 100644 index 0000000..e798072 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna.c @@ -0,0 +1,124 @@ + +#include "poly1305_donna.h" +#include "crypto_verify_16.h" +#include "private/common.h" +#include "utils.h" + +#ifdef HAVE_TI_MODE +#include "poly1305_donna64.h" +#else +#include "poly1305_donna32.h" +#endif +#include "../onetimeauth_poly1305.h" + +static void +poly1305_update(poly1305_state_internal_t *st, const unsigned char *m, + unsigned long long bytes) +{ + unsigned long long i; + + /* handle leftover */ + if (st->leftover) { + unsigned long long want = (poly1305_block_size - st->leftover); + + if (want > bytes) { + want = bytes; + } + for (i = 0; i < want; i++) { + st->buffer[st->leftover + i] = m[i]; + } + bytes -= want; + m += want; + st->leftover += want; + if (st->leftover < poly1305_block_size) { + return; + } + poly1305_blocks(st, st->buffer, poly1305_block_size); + st->leftover = 0; + } + + /* process full blocks */ + if (bytes >= poly1305_block_size) { + unsigned long long want = (bytes & ~(poly1305_block_size - 1)); + + poly1305_blocks(st, m, want); + m += want; + bytes -= want; + } + + /* store leftover */ + if (bytes) { + for (i = 0; i < bytes; i++) { + st->buffer[st->leftover + i] = m[i]; + } + st->leftover += bytes; + } +} + +static int +crypto_onetimeauth_poly1305_donna(unsigned char *out, const unsigned char *m, + unsigned long long inlen, + const unsigned char *key) +{ + CRYPTO_ALIGN(64) poly1305_state_internal_t state; + + poly1305_init(&state, key); + poly1305_update(&state, m, inlen); + poly1305_finish(&state, out); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_donna_init(crypto_onetimeauth_poly1305_state *state, + const unsigned char *key) +{ + COMPILER_ASSERT(sizeof(crypto_onetimeauth_poly1305_state) >= + sizeof(poly1305_state_internal_t)); + poly1305_init((poly1305_state_internal_t *) (void *) state, key); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_donna_update( + crypto_onetimeauth_poly1305_state *state, const unsigned char *in, + unsigned long long inlen) +{ + poly1305_update((poly1305_state_internal_t *) (void *) state, in, inlen); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_donna_final( + crypto_onetimeauth_poly1305_state *state, unsigned char *out) +{ + poly1305_finish((poly1305_state_internal_t *) (void *) state, out); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_donna_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) +{ + unsigned char correct[16]; + + crypto_onetimeauth_poly1305_donna(correct, in, inlen, k); + + return crypto_verify_16(h, correct); +} + +struct crypto_onetimeauth_poly1305_implementation + crypto_onetimeauth_poly1305_donna_implementation = { + SODIUM_C99(.onetimeauth =) crypto_onetimeauth_poly1305_donna, + SODIUM_C99(.onetimeauth_verify =) + crypto_onetimeauth_poly1305_donna_verify, + SODIUM_C99(.onetimeauth_init =) crypto_onetimeauth_poly1305_donna_init, + SODIUM_C99(.onetimeauth_update =) + crypto_onetimeauth_poly1305_donna_update, + SODIUM_C99(.onetimeauth_final =) crypto_onetimeauth_poly1305_donna_final + }; diff --git a/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna.h b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna.h new file mode 100644 index 0000000..d6474b3 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna.h @@ -0,0 +1,12 @@ +#ifndef poly1305_donna_H +#define poly1305_donna_H + +#include + +#include "../onetimeauth_poly1305.h" +#include "crypto_onetimeauth_poly1305.h" + +extern struct crypto_onetimeauth_poly1305_implementation + crypto_onetimeauth_poly1305_donna_implementation; + +#endif /* poly1305_donna_H */ diff --git a/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna32.h b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna32.h new file mode 100644 index 0000000..cef6448 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna32.h @@ -0,0 +1,235 @@ +/* + poly1305 implementation using 32 bit * 32 bit = 64 bit multiplication + and 64 bit addition +*/ + +#if defined(_MSC_VER) +# define POLY1305_NOINLINE __declspec(noinline) +#elif defined(__clang__) || defined(__GNUC__) +# define POLY1305_NOINLINE __attribute__((noinline)) +#else +# define POLY1305_NOINLINE +#endif + +#include "private/common.h" + +#define poly1305_block_size 16 + +/* 17 + sizeof(unsigned long long) + 14*sizeof(unsigned long) */ +typedef struct poly1305_state_internal_t { + unsigned long r[5]; + unsigned long h[5]; + unsigned long pad[4]; + unsigned long long leftover; + unsigned char buffer[poly1305_block_size]; + unsigned char final; +} poly1305_state_internal_t; + +static void +poly1305_init(poly1305_state_internal_t *st, const unsigned char key[32]) +{ + /* r &= 0xffffffc0ffffffc0ffffffc0fffffff - wiped after finalization */ + st->r[0] = (LOAD32_LE(&key[0])) & 0x3ffffff; + st->r[1] = (LOAD32_LE(&key[3]) >> 2) & 0x3ffff03; + st->r[2] = (LOAD32_LE(&key[6]) >> 4) & 0x3ffc0ff; + st->r[3] = (LOAD32_LE(&key[9]) >> 6) & 0x3f03fff; + st->r[4] = (LOAD32_LE(&key[12]) >> 8) & 0x00fffff; + + /* h = 0 */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + st->h[3] = 0; + st->h[4] = 0; + + /* save pad for later */ + st->pad[0] = LOAD32_LE(&key[16]); + st->pad[1] = LOAD32_LE(&key[20]); + st->pad[2] = LOAD32_LE(&key[24]); + st->pad[3] = LOAD32_LE(&key[28]); + + st->leftover = 0; + st->final = 0; +} + +static void +poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, + unsigned long long bytes) +{ + const unsigned long hibit = (st->final) ? 0UL : (1UL << 24); /* 1 << 128 */ + unsigned long r0, r1, r2, r3, r4; + unsigned long s1, s2, s3, s4; + unsigned long h0, h1, h2, h3, h4; + unsigned long long d0, d1, d2, d3, d4; + unsigned long c; + + r0 = st->r[0]; + r1 = st->r[1]; + r2 = st->r[2]; + r3 = st->r[3]; + r4 = st->r[4]; + + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; + + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + while (bytes >= poly1305_block_size) { + /* h += m[i] */ + h0 += (LOAD32_LE(m + 0)) & 0x3ffffff; + h1 += (LOAD32_LE(m + 3) >> 2) & 0x3ffffff; + h2 += (LOAD32_LE(m + 6) >> 4) & 0x3ffffff; + h3 += (LOAD32_LE(m + 9) >> 6) & 0x3ffffff; + h4 += (LOAD32_LE(m + 12) >> 8) | hibit; + + /* h *= r */ + d0 = ((unsigned long long) h0 * r0) + ((unsigned long long) h1 * s4) + + ((unsigned long long) h2 * s3) + ((unsigned long long) h3 * s2) + + ((unsigned long long) h4 * s1); + d1 = ((unsigned long long) h0 * r1) + ((unsigned long long) h1 * r0) + + ((unsigned long long) h2 * s4) + ((unsigned long long) h3 * s3) + + ((unsigned long long) h4 * s2); + d2 = ((unsigned long long) h0 * r2) + ((unsigned long long) h1 * r1) + + ((unsigned long long) h2 * r0) + ((unsigned long long) h3 * s4) + + ((unsigned long long) h4 * s3); + d3 = ((unsigned long long) h0 * r3) + ((unsigned long long) h1 * r2) + + ((unsigned long long) h2 * r1) + ((unsigned long long) h3 * r0) + + ((unsigned long long) h4 * s4); + d4 = ((unsigned long long) h0 * r4) + ((unsigned long long) h1 * r3) + + ((unsigned long long) h2 * r2) + ((unsigned long long) h3 * r1) + + ((unsigned long long) h4 * r0); + + /* (partial) h %= p */ + c = (unsigned long) (d0 >> 26); + h0 = (unsigned long) d0 & 0x3ffffff; + d1 += c; + c = (unsigned long) (d1 >> 26); + h1 = (unsigned long) d1 & 0x3ffffff; + d2 += c; + c = (unsigned long) (d2 >> 26); + h2 = (unsigned long) d2 & 0x3ffffff; + d3 += c; + c = (unsigned long) (d3 >> 26); + h3 = (unsigned long) d3 & 0x3ffffff; + d4 += c; + c = (unsigned long) (d4 >> 26); + h4 = (unsigned long) d4 & 0x3ffffff; + h0 += c * 5; + c = (h0 >> 26); + h0 = h0 & 0x3ffffff; + h1 += c; + + m += poly1305_block_size; + bytes -= poly1305_block_size; + } + + st->h[0] = h0; + st->h[1] = h1; + st->h[2] = h2; + st->h[3] = h3; + st->h[4] = h4; +} + +static POLY1305_NOINLINE void +poly1305_finish(poly1305_state_internal_t *st, unsigned char mac[16]) +{ + unsigned long h0, h1, h2, h3, h4, c; + unsigned long g0, g1, g2, g3, g4; + unsigned long long f; + unsigned long mask; + + /* process the remaining block */ + if (st->leftover) { + unsigned long long i = st->leftover; + + st->buffer[i++] = 1; + for (; i < poly1305_block_size; i++) { + st->buffer[i] = 0; + } + st->final = 1; + poly1305_blocks(st, st->buffer, poly1305_block_size); + } + + /* fully carry h */ + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + h3 = st->h[3]; + h4 = st->h[4]; + + c = h1 >> 26; + h1 = h1 & 0x3ffffff; + h2 += c; + c = h2 >> 26; + h2 = h2 & 0x3ffffff; + h3 += c; + c = h3 >> 26; + h3 = h3 & 0x3ffffff; + h4 += c; + c = h4 >> 26; + h4 = h4 & 0x3ffffff; + h0 += c * 5; + c = h0 >> 26; + h0 = h0 & 0x3ffffff; + h1 += c; + + /* compute h + -p */ + g0 = h0 + 5; + c = g0 >> 26; + g0 &= 0x3ffffff; + g1 = h1 + c; + c = g1 >> 26; + g1 &= 0x3ffffff; + g2 = h2 + c; + c = g2 >> 26; + g2 &= 0x3ffffff; + g3 = h3 + c; + c = g3 >> 26; + g3 &= 0x3ffffff; + g4 = h4 + c - (1UL << 26); + + /* select h if h < p, or h + -p if h >= p */ + mask = (g4 >> ((sizeof(unsigned long) * 8) - 1)) - 1; + g0 &= mask; + g1 &= mask; + g2 &= mask; + g3 &= mask; + g4 &= mask; + mask = ~mask; + + h0 = (h0 & mask) | g0; + h1 = (h1 & mask) | g1; + h2 = (h2 & mask) | g2; + h3 = (h3 & mask) | g3; + h4 = (h4 & mask) | g4; + + /* h = h % (2^128) */ + h0 = ((h0) | (h1 << 26)) & 0xffffffff; + h1 = ((h1 >> 6) | (h2 << 20)) & 0xffffffff; + h2 = ((h2 >> 12) | (h3 << 14)) & 0xffffffff; + h3 = ((h3 >> 18) | (h4 << 8)) & 0xffffffff; + + /* mac = (h + pad) % (2^128) */ + f = (unsigned long long) h0 + st->pad[0]; + h0 = (unsigned long) f; + f = (unsigned long long) h1 + st->pad[1] + (f >> 32); + h1 = (unsigned long) f; + f = (unsigned long long) h2 + st->pad[2] + (f >> 32); + h2 = (unsigned long) f; + f = (unsigned long long) h3 + st->pad[3] + (f >> 32); + h3 = (unsigned long) f; + + STORE32_LE(mac + 0, (uint32_t) h0); + STORE32_LE(mac + 4, (uint32_t) h1); + STORE32_LE(mac + 8, (uint32_t) h2); + STORE32_LE(mac + 12, (uint32_t) h3); + + /* zero out the state */ + sodium_memzero((void *) st, sizeof *st); +} diff --git a/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna64.h b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna64.h new file mode 100644 index 0000000..2475bfa --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/donna/poly1305_donna64.h @@ -0,0 +1,221 @@ +/* + poly1305 implementation using 64 bit * 64 bit = 128 bit multiplication + and 128 bit addition +*/ + +#include "private/common.h" + +#define MUL(out, x, y) out = ((uint128_t) x * y) +#define ADD(out, in) out += in +#define ADDLO(out, in) out += in +#define SHR(in, shift) (unsigned long long) (in >> (shift)) +#define LO(in) (unsigned long long) (in) + +#if defined(_MSC_VER) +# define POLY1305_NOINLINE __declspec(noinline) +#elif defined(__clang__) || defined(__GNUC__) +# define POLY1305_NOINLINE __attribute__((noinline)) +#else +# define POLY1305_NOINLINE +#endif + +#define poly1305_block_size 16 + +/* 17 + sizeof(unsigned long long) + 8*sizeof(unsigned long long) */ +typedef struct poly1305_state_internal_t { + unsigned long long r[3]; + unsigned long long h[3]; + unsigned long long pad[2]; + unsigned long long leftover; + unsigned char buffer[poly1305_block_size]; + unsigned char final; +} poly1305_state_internal_t; + +static void +poly1305_init(poly1305_state_internal_t *st, const unsigned char key[32]) +{ + unsigned long long t0, t1; + + /* r &= 0xffffffc0ffffffc0ffffffc0fffffff */ + t0 = LOAD64_LE(&key[0]); + t1 = LOAD64_LE(&key[8]); + + /* wiped after finalization */ + st->r[0] = (t0) & 0xffc0fffffff; + st->r[1] = ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff; + st->r[2] = ((t1 >> 24)) & 0x00ffffffc0f; + + /* h = 0 */ + st->h[0] = 0; + st->h[1] = 0; + st->h[2] = 0; + + /* save pad for later */ + st->pad[0] = LOAD64_LE(&key[16]); + st->pad[1] = LOAD64_LE(&key[24]); + + st->leftover = 0; + st->final = 0; +} + +static void +poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, + unsigned long long bytes) +{ + const unsigned long long hibit = + (st->final) ? 0ULL : (1ULL << 40); /* 1 << 128 */ + unsigned long long r0, r1, r2; + unsigned long long s1, s2; + unsigned long long h0, h1, h2; + unsigned long long c; + uint128_t d0, d1, d2, d; + + r0 = st->r[0]; + r1 = st->r[1]; + r2 = st->r[2]; + + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + + s1 = r1 * (5 << 2); + s2 = r2 * (5 << 2); + + while (bytes >= poly1305_block_size) { + unsigned long long t0, t1; + + /* h += m[i] */ + t0 = LOAD64_LE(&m[0]); + t1 = LOAD64_LE(&m[8]); + + h0 += t0 & 0xfffffffffff; + h1 += ((t0 >> 44) | (t1 << 20)) & 0xfffffffffff; + h2 += (((t1 >> 24)) & 0x3ffffffffff) | hibit; + + /* h *= r */ + MUL(d0, h0, r0); + MUL(d, h1, s2); + ADD(d0, d); + MUL(d, h2, s1); + ADD(d0, d); + MUL(d1, h0, r1); + MUL(d, h1, r0); + ADD(d1, d); + MUL(d, h2, s2); + ADD(d1, d); + MUL(d2, h0, r2); + MUL(d, h1, r1); + ADD(d2, d); + MUL(d, h2, r0); + ADD(d2, d); + + /* (partial) h %= p */ + c = SHR(d0, 44); + h0 = LO(d0) & 0xfffffffffff; + ADDLO(d1, c); + c = SHR(d1, 44); + h1 = LO(d1) & 0xfffffffffff; + ADDLO(d2, c); + c = SHR(d2, 42); + h2 = LO(d2) & 0x3ffffffffff; + h0 += c * 5; + c = (h0 >> 44); + h0 = h0 & 0xfffffffffff; + h1 += c; + + m += poly1305_block_size; + bytes -= poly1305_block_size; + } + + st->h[0] = h0; + st->h[1] = h1; + st->h[2] = h2; +} + +static POLY1305_NOINLINE void +poly1305_finish(poly1305_state_internal_t *st, unsigned char mac[16]) +{ + unsigned long long h0, h1, h2, c; + unsigned long long g0, g1, g2; + unsigned long long t0, t1; + unsigned long long mask; + + /* process the remaining block */ + if (st->leftover) { + unsigned long long i = st->leftover; + + st->buffer[i] = 1; + + for (i = i + 1; i < poly1305_block_size; i++) { + st->buffer[i] = 0; + } + st->final = 1; + poly1305_blocks(st, st->buffer, poly1305_block_size); + } + + /* fully carry h */ + h0 = st->h[0]; + h1 = st->h[1]; + h2 = st->h[2]; + + c = h1 >> 44; + h1 &= 0xfffffffffff; + h2 += c; + c = h2 >> 42; + h2 &= 0x3ffffffffff; + h0 += c * 5; + c = h0 >> 44; + h0 &= 0xfffffffffff; + h1 += c; + c = h1 >> 44; + h1 &= 0xfffffffffff; + h2 += c; + c = h2 >> 42; + h2 &= 0x3ffffffffff; + h0 += c * 5; + c = h0 >> 44; + h0 &= 0xfffffffffff; + h1 += c; + + /* compute h + -p */ + g0 = h0 + 5; + c = g0 >> 44; + g0 &= 0xfffffffffff; + g1 = h1 + c; + c = g1 >> 44; + g1 &= 0xfffffffffff; + g2 = h2 + c - (1ULL << 42); + + /* select h if h < p, or h + -p if h >= p */ + mask = (g2 >> ((sizeof(unsigned long long) * 8) - 1)) - 1; + g0 &= mask; + g1 &= mask; + g2 &= mask; + mask = ~mask; + h0 = (h0 & mask) | g0; + h1 = (h1 & mask) | g1; + h2 = (h2 & mask) | g2; + + /* h = (h + pad) */ + t0 = st->pad[0]; + t1 = st->pad[1]; + + h0 += ((t0) &0xfffffffffff); + c = (h0 >> 44); + h0 &= 0xfffffffffff; + h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + h2 += (((t1 >> 24)) & 0x3ffffffffff) + c; + h2 &= 0x3ffffffffff; + + /* mac = h % (2^128) */ + h0 = (h0) | (h1 << 44); + h1 = (h1 >> 20) | (h2 << 24); + + STORE64_LE(&mac[0], h0); + STORE64_LE(&mac[8], h1); + + /* zero out the state */ + sodium_memzero((void *) st, sizeof *st); +} diff --git a/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c new file mode 100644 index 0000000..d5e2efa --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/onetimeauth_poly1305.c @@ -0,0 +1,90 @@ + +#include "onetimeauth_poly1305.h" +#include "crypto_onetimeauth_poly1305.h" +#include "private/common.h" +#include "private/implementations.h" +#include "randombytes.h" +#include "runtime.h" + +#include "donna/poly1305_donna.h" +#if defined(HAVE_TI_MODE) && defined(HAVE_EMMINTRIN_H) +# include "sse2/poly1305_sse2.h" +#endif + +static const crypto_onetimeauth_poly1305_implementation *implementation = + &crypto_onetimeauth_poly1305_donna_implementation; + +int +crypto_onetimeauth_poly1305(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + return implementation->onetimeauth(out, in, inlen, k); +} + +int +crypto_onetimeauth_poly1305_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) +{ + return implementation->onetimeauth_verify(h, in, inlen, k); +} + +int +crypto_onetimeauth_poly1305_init(crypto_onetimeauth_poly1305_state *state, + const unsigned char *key) +{ + return implementation->onetimeauth_init(state, key); +} + +int +crypto_onetimeauth_poly1305_update(crypto_onetimeauth_poly1305_state *state, + const unsigned char *in, + unsigned long long inlen) +{ + return implementation->onetimeauth_update(state, in, inlen); +} + +int +crypto_onetimeauth_poly1305_final(crypto_onetimeauth_poly1305_state *state, + unsigned char *out) +{ + return implementation->onetimeauth_final(state, out); +} + +size_t +crypto_onetimeauth_poly1305_bytes(void) +{ + return crypto_onetimeauth_poly1305_BYTES; +} + +size_t +crypto_onetimeauth_poly1305_keybytes(void) +{ + return crypto_onetimeauth_poly1305_KEYBYTES; +} + +size_t +crypto_onetimeauth_poly1305_statebytes(void) +{ + return sizeof(crypto_onetimeauth_poly1305_state); +} + +void +crypto_onetimeauth_poly1305_keygen( + unsigned char k[crypto_onetimeauth_poly1305_KEYBYTES]) +{ + randombytes_buf(k, crypto_onetimeauth_poly1305_KEYBYTES); +} + +int +_crypto_onetimeauth_poly1305_pick_best_implementation(void) +{ + implementation = &crypto_onetimeauth_poly1305_donna_implementation; +#if defined(HAVE_TI_MODE) && defined(HAVE_EMMINTRIN_H) + if (sodium_runtime_has_sse2()) { + implementation = &crypto_onetimeauth_poly1305_sse2_implementation; + } +#endif + return 0; +} diff --git a/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/onetimeauth_poly1305.h b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/onetimeauth_poly1305.h new file mode 100644 index 0000000..243eadd --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/onetimeauth_poly1305.h @@ -0,0 +1,21 @@ + +#ifndef onetimeauth_poly1305_H +#define onetimeauth_poly1305_H + +#include "crypto_onetimeauth_poly1305.h" + +typedef struct crypto_onetimeauth_poly1305_implementation { + int (*onetimeauth)(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k); + int (*onetimeauth_verify)(const unsigned char *h, const unsigned char *in, + unsigned long long inlen, const unsigned char *k); + int (*onetimeauth_init)(crypto_onetimeauth_poly1305_state *state, + const unsigned char * key); + int (*onetimeauth_update)(crypto_onetimeauth_poly1305_state *state, + const unsigned char * in, + unsigned long long inlen); + int (*onetimeauth_final)(crypto_onetimeauth_poly1305_state *state, + unsigned char * out); +} crypto_onetimeauth_poly1305_implementation; + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c new file mode 100644 index 0000000..aa81777 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c @@ -0,0 +1,949 @@ + +#include +#include + +#include "../onetimeauth_poly1305.h" +#include "crypto_verify_16.h" +#include "poly1305_sse2.h" +#include "private/common.h" +#include "utils.h" + +#if defined(HAVE_TI_MODE) && defined(HAVE_EMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# endif + +# include +# include "private/sse2_64_32.h" + +typedef __m128i xmmi; + +# if defined(_MSC_VER) +# define POLY1305_NOINLINE __declspec(noinline) +# elif defined(__clang__) || defined(__GNUC__) +# define POLY1305_NOINLINE __attribute__((noinline)) +# else +# define POLY1305_NOINLINE +# endif + +# define poly1305_block_size 32 + +enum poly1305_state_flags_t { + poly1305_started = 1, + poly1305_final_shift8 = 4, + poly1305_final_shift16 = 8, + poly1305_final_r2_r = 16, /* use [r^2,r] for the final block */ + poly1305_final_r_1 = 32 /* use [r,1] for the final block */ +}; + +typedef struct poly1305_state_internal_t { + union { + uint64_t h[3]; + uint32_t hh[10]; + } H; /* 40 bytes */ + uint32_t R[5]; /* 20 bytes */ + uint32_t R2[5]; /* 20 bytes */ + uint32_t R4[5]; /* 20 bytes */ + uint64_t pad[2]; /* 16 bytes */ + uint64_t flags; /* 8 bytes */ + unsigned long long leftover; /* 8 bytes */ + unsigned char buffer[poly1305_block_size]; /* 32 bytes */ +} poly1305_state_internal_t; /* 164 bytes total */ + +/* + * _mm_loadl_epi64() is turned into a simple MOVQ. So, unaligned accesses are + * totally fine, even though this intrinsic requires a __m128i* input. + * This confuses dynamic analysis, so force alignment, only in debug mode. + */ +# ifdef DEBUG +static xmmi +_fakealign_mm_loadl_epi64(const void *m) +{ + xmmi tmp; + memcpy(&tmp, m, 8); + + return _mm_loadl_epi64(&tmp); +} +# define _mm_loadl_epi64(X) _fakealign_mm_loadl_epi64(X) +#endif + +/* copy 0-31 bytes */ +static inline void +poly1305_block_copy31(unsigned char *dst, const unsigned char *src, + unsigned long long bytes) +{ + if (bytes & 16) { + _mm_store_si128((xmmi *) (void *) dst, + _mm_loadu_si128((const xmmi *) (const void *) src)); + src += 16; + dst += 16; + } + if (bytes & 8) { + memcpy(dst, src, 8); + src += 8; + dst += 8; + } + if (bytes & 4) { + memcpy(dst, src, 4); + src += 4; + dst += 4; + } + if (bytes & 2) { + memcpy(dst, src, 2); + src += 2; + dst += 2; + } + if (bytes & 1) { + *dst = *src; + } +} + +static POLY1305_NOINLINE void +poly1305_init_ext(poly1305_state_internal_t *st, const unsigned char key[32], + unsigned long long bytes) +{ + uint32_t *R; + uint128_t d[3]; + uint64_t r0, r1, r2; + uint64_t rt0, rt1, rt2, st2, c; + uint64_t t0, t1; + unsigned long long i; + + if (!bytes) { + bytes = ~(unsigned long long) 0; + } + /* H = 0 */ + _mm_storeu_si128((xmmi *) (void *) &st->H.hh[0], _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) &st->H.hh[4], _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) &st->H.hh[8], _mm_setzero_si128()); + + /* clamp key */ + memcpy(&t0, key, 8); + memcpy(&t1, key + 8, 8); + r0 = t0 & 0xffc0fffffff; + t0 >>= 44; + t0 |= t1 << 20; + r1 = t0 & 0xfffffc0ffff; + t1 >>= 24; + r2 = t1 & 0x00ffffffc0f; + + /* r^1 */ + R = st->R; + R[0] = (uint32_t)(r0) &0x3ffffff; + R[1] = (uint32_t)((r0 >> 26) | (r1 << 18)) & 0x3ffffff; + R[2] = (uint32_t)((r1 >> 8)) & 0x3ffffff; + R[3] = (uint32_t)((r1 >> 34) | (r2 << 10)) & 0x3ffffff; + R[4] = (uint32_t)((r2 >> 16)); + + /* save pad */ + memcpy(&st->pad[0], key + 16, 8); + memcpy(&st->pad[1], key + 24, 8); + + rt0 = r0; + rt1 = r1; + rt2 = r2; + + /* r^2, r^4 */ + for (i = 0; i < 2; i++) { + if (i == 0) { + R = st->R2; + if (bytes <= 16) { + break; + } + } else if (i == 1) { + R = st->R4; + if (bytes < 96) { + break; + } + } + st2 = rt2 * (5 << 2); + + d[0] = ((uint128_t) rt0 * rt0) + ((uint128_t)(rt1 * 2) * st2); + d[1] = ((uint128_t) rt2 * st2) + ((uint128_t)(rt0 * 2) * rt1); + d[2] = ((uint128_t) rt1 * rt1) + ((uint128_t)(rt2 * 2) * rt0); + + rt0 = (uint64_t) d[0] & 0xfffffffffff; + c = (uint64_t)(d[0] >> 44); + d[1] += c; + + rt1 = (uint64_t) d[1] & 0xfffffffffff; + c = (uint64_t)(d[1] >> 44); + d[2] += c; + + rt2 = (uint64_t) d[2] & 0x3ffffffffff; + c = (uint64_t)(d[2] >> 42); + rt0 += c * 5; + c = (rt0 >> 44); + rt0 = rt0 & 0xfffffffffff; + rt1 += c; + c = (rt1 >> 44); + rt1 = rt1 & 0xfffffffffff; + rt2 += c; /* even if rt2 overflows, it will still fit in rp4 safely, and + is safe to multiply with */ + + R[0] = (uint32_t)(rt0) &0x3ffffff; + R[1] = (uint32_t)((rt0 >> 26) | (rt1 << 18)) & 0x3ffffff; + R[2] = (uint32_t)((rt1 >> 8)) & 0x3ffffff; + R[3] = (uint32_t)((rt1 >> 34) | (rt2 << 10)) & 0x3ffffff; + R[4] = (uint32_t)((rt2 >> 16)); + } + st->flags = 0; + st->leftover = 0U; +} + +static POLY1305_NOINLINE void +poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, + unsigned long long bytes) +{ + CRYPTO_ALIGN(64) + xmmi HIBIT = + _mm_shuffle_epi32(_mm_cvtsi32_si128(1 << 24), _MM_SHUFFLE(1, 0, 1, 0)); + const xmmi MMASK = _mm_shuffle_epi32(_mm_cvtsi32_si128((1 << 26) - 1), + _MM_SHUFFLE(1, 0, 1, 0)); + const xmmi FIVE = + _mm_shuffle_epi32(_mm_cvtsi32_si128(5), _MM_SHUFFLE(1, 0, 1, 0)); + xmmi H0, H1, H2, H3, H4; + xmmi T0, T1, T2, T3, T4, T5, T6, T7, T8; + xmmi M0, M1, M2, M3, M4; + xmmi M5, M6, M7, M8; + xmmi C1, C2; + xmmi R20, R21, R22, R23, R24, S21, S22, S23, S24; + xmmi R40, R41, R42, R43, R44, S41, S42, S43, S44; + + if (st->flags & poly1305_final_shift8) { + HIBIT = _mm_srli_si128(HIBIT, 8); + } + if (st->flags & poly1305_final_shift16) { + HIBIT = _mm_setzero_si128(); + } + if (!(st->flags & poly1305_started)) { + /* H = [Mx,My] */ + T5 = _mm_unpacklo_epi64( + _mm_loadl_epi64((const xmmi *) (const void *) (m + 0)), + _mm_loadl_epi64((const xmmi *) (const void *) (m + 16))); + T6 = _mm_unpacklo_epi64( + _mm_loadl_epi64((const xmmi *) (const void *) (m + 8)), + _mm_loadl_epi64((const xmmi *) (const void *) (m + 24))); + H0 = _mm_and_si128(MMASK, T5); + H1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + H2 = _mm_and_si128(MMASK, T5); + H3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + H4 = _mm_srli_epi64(T6, 40); + H4 = _mm_or_si128(H4, HIBIT); + m += 32; + bytes -= 32; + st->flags |= poly1305_started; + } else { + T0 = _mm_loadu_si128((const xmmi *) (const void *) &st->H.hh[0]); + T1 = _mm_loadu_si128((const xmmi *) (const void *) &st->H.hh[4]); + T2 = _mm_loadu_si128((const xmmi *) (const void *) &st->H.hh[8]); + H0 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(1, 1, 0, 0)); + H1 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(3, 3, 2, 2)); + H2 = _mm_shuffle_epi32(T1, _MM_SHUFFLE(1, 1, 0, 0)); + H3 = _mm_shuffle_epi32(T1, _MM_SHUFFLE(3, 3, 2, 2)); + H4 = _mm_shuffle_epi32(T2, _MM_SHUFFLE(1, 1, 0, 0)); + } + if (st->flags & (poly1305_final_r2_r | poly1305_final_r_1)) { + if (st->flags & poly1305_final_r2_r) { + /* use [r^2, r] */ + T2 = _mm_loadu_si128((const xmmi *) (const void *) &st->R[0]); + T3 = _mm_cvtsi32_si128(st->R[4]); + T0 = _mm_loadu_si128((const xmmi *) (const void *) &st->R2[0]); + T1 = _mm_cvtsi32_si128(st->R2[4]); + T4 = _mm_unpacklo_epi32(T0, T2); + T5 = _mm_unpackhi_epi32(T0, T2); + R24 = _mm_unpacklo_epi64(T1, T3); + } else { + /* use [r^1, 1] */ + T0 = _mm_loadu_si128((const xmmi *) (const void *) &st->R[0]); + T1 = _mm_cvtsi32_si128(st->R[4]); + T2 = _mm_cvtsi32_si128(1); + T4 = _mm_unpacklo_epi32(T0, T2); + T5 = _mm_unpackhi_epi32(T0, T2); + R24 = T1; + } + R20 = _mm_shuffle_epi32(T4, _MM_SHUFFLE(1, 1, 0, 0)); + R21 = _mm_shuffle_epi32(T4, _MM_SHUFFLE(3, 3, 2, 2)); + R22 = _mm_shuffle_epi32(T5, _MM_SHUFFLE(1, 1, 0, 0)); + R23 = _mm_shuffle_epi32(T5, _MM_SHUFFLE(3, 3, 2, 2)); + } else { + /* use [r^2, r^2] */ + T0 = _mm_loadu_si128((const xmmi *) (const void *) &st->R2[0]); + T1 = _mm_cvtsi32_si128(st->R2[4]); + R20 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(0, 0, 0, 0)); + R21 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(1, 1, 1, 1)); + R22 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(2, 2, 2, 2)); + R23 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(3, 3, 3, 3)); + R24 = _mm_shuffle_epi32(T1, _MM_SHUFFLE(0, 0, 0, 0)); + } + S21 = _mm_mul_epu32(R21, FIVE); + S22 = _mm_mul_epu32(R22, FIVE); + S23 = _mm_mul_epu32(R23, FIVE); + S24 = _mm_mul_epu32(R24, FIVE); + + if (bytes >= 64) { + T0 = _mm_loadu_si128((const xmmi *) (const void *) &st->R4[0]); + T1 = _mm_cvtsi32_si128(st->R4[4]); + R40 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(0, 0, 0, 0)); + R41 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(1, 1, 1, 1)); + R42 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(2, 2, 2, 2)); + R43 = _mm_shuffle_epi32(T0, _MM_SHUFFLE(3, 3, 3, 3)); + R44 = _mm_shuffle_epi32(T1, _MM_SHUFFLE(0, 0, 0, 0)); + S41 = _mm_mul_epu32(R41, FIVE); + S42 = _mm_mul_epu32(R42, FIVE); + S43 = _mm_mul_epu32(R43, FIVE); + S44 = _mm_mul_epu32(R44, FIVE); + + while (bytes >= 64) { + xmmi v00, v01, v02, v03, v04; + xmmi v10, v11, v12, v13, v14; + xmmi v20, v21, v22, v23, v24; + xmmi v30, v31, v32, v33, v34; + xmmi v40, v41, v42, v43, v44; + xmmi T14, T15; + + /* H *= [r^4,r^4], preload [Mx,My] */ + T15 = S42; + T0 = H4; + T0 = _mm_mul_epu32(T0, S41); + v01 = H3; + v01 = _mm_mul_epu32(v01, T15); + T14 = S43; + T1 = H4; + T1 = _mm_mul_epu32(T1, T15); + v11 = H3; + v11 = _mm_mul_epu32(v11, T14); + T2 = H4; + T2 = _mm_mul_epu32(T2, T14); + T0 = _mm_add_epi64(T0, v01); + T15 = S44; + v02 = H2; + v02 = _mm_mul_epu32(v02, T14); + T3 = H4; + T3 = _mm_mul_epu32(T3, T15); + T1 = _mm_add_epi64(T1, v11); + v03 = H1; + v03 = _mm_mul_epu32(v03, T15); + v12 = H2; + v12 = _mm_mul_epu32(v12, T15); + T0 = _mm_add_epi64(T0, v02); + T14 = R40; + v21 = H3; + v21 = _mm_mul_epu32(v21, T15); + v31 = H3; + v31 = _mm_mul_epu32(v31, T14); + T0 = _mm_add_epi64(T0, v03); + T4 = H4; + T4 = _mm_mul_epu32(T4, T14); + T1 = _mm_add_epi64(T1, v12); + v04 = H0; + v04 = _mm_mul_epu32(v04, T14); + T2 = _mm_add_epi64(T2, v21); + v13 = H1; + v13 = _mm_mul_epu32(v13, T14); + T3 = _mm_add_epi64(T3, v31); + T15 = R41; + v22 = H2; + v22 = _mm_mul_epu32(v22, T14); + v32 = H2; + v32 = _mm_mul_epu32(v32, T15); + T0 = _mm_add_epi64(T0, v04); + v41 = H3; + v41 = _mm_mul_epu32(v41, T15); + T1 = _mm_add_epi64(T1, v13); + v14 = H0; + v14 = _mm_mul_epu32(v14, T15); + T2 = _mm_add_epi64(T2, v22); + T14 = R42; + T5 = _mm_unpacklo_epi64( + _mm_loadl_epi64((const xmmi *) (const void *) (m + 0)), + _mm_loadl_epi64((const xmmi *) (const void *) (m + 16))); + v23 = H1; + v23 = _mm_mul_epu32(v23, T15); + T3 = _mm_add_epi64(T3, v32); + v33 = H1; + v33 = _mm_mul_epu32(v33, T14); + T4 = _mm_add_epi64(T4, v41); + v42 = H2; + v42 = _mm_mul_epu32(v42, T14); + T1 = _mm_add_epi64(T1, v14); + T15 = R43; + T6 = _mm_unpacklo_epi64( + _mm_loadl_epi64((const xmmi *) (const void *) (m + 8)), + _mm_loadl_epi64((const xmmi *) (const void *) (m + 24))); + v24 = H0; + v24 = _mm_mul_epu32(v24, T14); + T2 = _mm_add_epi64(T2, v23); + v34 = H0; + v34 = _mm_mul_epu32(v34, T15); + T3 = _mm_add_epi64(T3, v33); + M0 = _mm_and_si128(MMASK, T5); + v43 = H1; + v43 = _mm_mul_epu32(v43, T15); + T4 = _mm_add_epi64(T4, v42); + M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + v44 = H0; + v44 = _mm_mul_epu32(v44, R44); + T2 = _mm_add_epi64(T2, v24); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + T3 = _mm_add_epi64(T3, v34); + M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T6, 14)); + T4 = _mm_add_epi64(T4, v43); + M2 = _mm_and_si128(MMASK, T5); + T4 = _mm_add_epi64(T4, v44); + M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); + + /* H += [Mx',My'] */ + T5 = _mm_loadu_si128((const xmmi *) (const void *) (m + 32)); + T6 = _mm_loadu_si128((const xmmi *) (const void *) (m + 48)); + T7 = _mm_unpacklo_epi32(T5, T6); + T8 = _mm_unpackhi_epi32(T5, T6); + M5 = _mm_unpacklo_epi32(T7, _mm_setzero_si128()); + M6 = _mm_unpackhi_epi32(T7, _mm_setzero_si128()); + M7 = _mm_unpacklo_epi32(T8, _mm_setzero_si128()); + M8 = _mm_unpackhi_epi32(T8, _mm_setzero_si128()); + M6 = _mm_slli_epi64(M6, 6); + M7 = _mm_slli_epi64(M7, 12); + M8 = _mm_slli_epi64(M8, 18); + T0 = _mm_add_epi64(T0, M5); + T1 = _mm_add_epi64(T1, M6); + T2 = _mm_add_epi64(T2, M7); + T3 = _mm_add_epi64(T3, M8); + T4 = _mm_add_epi64(T4, HIBIT); + + /* H += [Mx,My]*[r^2,r^2] */ + T15 = S22; + v00 = M4; + v00 = _mm_mul_epu32(v00, S21); + v01 = M3; + v01 = _mm_mul_epu32(v01, T15); + T14 = S23; + v10 = M4; + v10 = _mm_mul_epu32(v10, T15); + v11 = M3; + v11 = _mm_mul_epu32(v11, T14); + T0 = _mm_add_epi64(T0, v00); + v20 = M4; + v20 = _mm_mul_epu32(v20, T14); + T0 = _mm_add_epi64(T0, v01); + T15 = S24; + v02 = M2; + v02 = _mm_mul_epu32(v02, T14); + T1 = _mm_add_epi64(T1, v10); + v30 = M4; + v30 = _mm_mul_epu32(v30, T15); + T1 = _mm_add_epi64(T1, v11); + v03 = M1; + v03 = _mm_mul_epu32(v03, T15); + T2 = _mm_add_epi64(T2, v20); + v12 = M2; + v12 = _mm_mul_epu32(v12, T15); + T0 = _mm_add_epi64(T0, v02); + T14 = R20; + v21 = M3; + v21 = _mm_mul_epu32(v21, T15); + T3 = _mm_add_epi64(T3, v30); + v31 = M3; + v31 = _mm_mul_epu32(v31, T14); + T0 = _mm_add_epi64(T0, v03); + v40 = M4; + v40 = _mm_mul_epu32(v40, T14); + T1 = _mm_add_epi64(T1, v12); + v04 = M0; + v04 = _mm_mul_epu32(v04, T14); + T2 = _mm_add_epi64(T2, v21); + v13 = M1; + v13 = _mm_mul_epu32(v13, T14); + T3 = _mm_add_epi64(T3, v31); + T15 = R21; + v22 = M2; + v22 = _mm_mul_epu32(v22, T14); + T4 = _mm_add_epi64(T4, v40); + v32 = M2; + v32 = _mm_mul_epu32(v32, T15); + T0 = _mm_add_epi64(T0, v04); + v41 = M3; + v41 = _mm_mul_epu32(v41, T15); + T1 = _mm_add_epi64(T1, v13); + v14 = M0; + v14 = _mm_mul_epu32(v14, T15); + T2 = _mm_add_epi64(T2, v22); + T14 = R22; + v23 = M1; + v23 = _mm_mul_epu32(v23, T15); + T3 = _mm_add_epi64(T3, v32); + v33 = M1; + v33 = _mm_mul_epu32(v33, T14); + T4 = _mm_add_epi64(T4, v41); + v42 = M2; + v42 = _mm_mul_epu32(v42, T14); + T1 = _mm_add_epi64(T1, v14); + T15 = R23; + v24 = M0; + v24 = _mm_mul_epu32(v24, T14); + T2 = _mm_add_epi64(T2, v23); + v34 = M0; + v34 = _mm_mul_epu32(v34, T15); + T3 = _mm_add_epi64(T3, v33); + v43 = M1; + v43 = _mm_mul_epu32(v43, T15); + T4 = _mm_add_epi64(T4, v42); + v44 = M0; + v44 = _mm_mul_epu32(v44, R24); + T2 = _mm_add_epi64(T2, v24); + T3 = _mm_add_epi64(T3, v34); + T4 = _mm_add_epi64(T4, v43); + T4 = _mm_add_epi64(T4, v44); + + /* reduce */ + C1 = _mm_srli_epi64(T0, 26); + C2 = _mm_srli_epi64(T3, 26); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_and_si128(T3, MMASK); + T1 = _mm_add_epi64(T1, C1); + T4 = _mm_add_epi64(T4, C2); + C1 = _mm_srli_epi64(T1, 26); + C2 = _mm_srli_epi64(T4, 26); + T1 = _mm_and_si128(T1, MMASK); + T4 = _mm_and_si128(T4, MMASK); + T2 = _mm_add_epi64(T2, C1); + T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE)); + C1 = _mm_srli_epi64(T2, 26); + C2 = _mm_srli_epi64(T0, 26); + T2 = _mm_and_si128(T2, MMASK); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_add_epi64(T3, C1); + T1 = _mm_add_epi64(T1, C2); + C1 = _mm_srli_epi64(T3, 26); + T3 = _mm_and_si128(T3, MMASK); + T4 = _mm_add_epi64(T4, C1); + + /* Final: H = (H*[r^4,r^4] + [Mx,My]*[r^2,r^2] + [Mx',My']) */ + H0 = T0; + H1 = T1; + H2 = T2; + H3 = T3; + H4 = T4; + + m += 64; + bytes -= 64; + } + } + + if (bytes >= 32) { + xmmi v01, v02, v03, v04; + xmmi v11, v12, v13, v14; + xmmi v21, v22, v23, v24; + xmmi v31, v32, v33, v34; + xmmi v41, v42, v43, v44; + xmmi T14, T15; + + /* H *= [r^2,r^2] */ + T15 = S22; + T0 = H4; + T0 = _mm_mul_epu32(T0, S21); + v01 = H3; + v01 = _mm_mul_epu32(v01, T15); + T14 = S23; + T1 = H4; + T1 = _mm_mul_epu32(T1, T15); + v11 = H3; + v11 = _mm_mul_epu32(v11, T14); + T2 = H4; + T2 = _mm_mul_epu32(T2, T14); + T0 = _mm_add_epi64(T0, v01); + T15 = S24; + v02 = H2; + v02 = _mm_mul_epu32(v02, T14); + T3 = H4; + T3 = _mm_mul_epu32(T3, T15); + T1 = _mm_add_epi64(T1, v11); + v03 = H1; + v03 = _mm_mul_epu32(v03, T15); + v12 = H2; + v12 = _mm_mul_epu32(v12, T15); + T0 = _mm_add_epi64(T0, v02); + T14 = R20; + v21 = H3; + v21 = _mm_mul_epu32(v21, T15); + v31 = H3; + v31 = _mm_mul_epu32(v31, T14); + T0 = _mm_add_epi64(T0, v03); + T4 = H4; + T4 = _mm_mul_epu32(T4, T14); + T1 = _mm_add_epi64(T1, v12); + v04 = H0; + v04 = _mm_mul_epu32(v04, T14); + T2 = _mm_add_epi64(T2, v21); + v13 = H1; + v13 = _mm_mul_epu32(v13, T14); + T3 = _mm_add_epi64(T3, v31); + T15 = R21; + v22 = H2; + v22 = _mm_mul_epu32(v22, T14); + v32 = H2; + v32 = _mm_mul_epu32(v32, T15); + T0 = _mm_add_epi64(T0, v04); + v41 = H3; + v41 = _mm_mul_epu32(v41, T15); + T1 = _mm_add_epi64(T1, v13); + v14 = H0; + v14 = _mm_mul_epu32(v14, T15); + T2 = _mm_add_epi64(T2, v22); + T14 = R22; + v23 = H1; + v23 = _mm_mul_epu32(v23, T15); + T3 = _mm_add_epi64(T3, v32); + v33 = H1; + v33 = _mm_mul_epu32(v33, T14); + T4 = _mm_add_epi64(T4, v41); + v42 = H2; + v42 = _mm_mul_epu32(v42, T14); + T1 = _mm_add_epi64(T1, v14); + T15 = R23; + v24 = H0; + v24 = _mm_mul_epu32(v24, T14); + T2 = _mm_add_epi64(T2, v23); + v34 = H0; + v34 = _mm_mul_epu32(v34, T15); + T3 = _mm_add_epi64(T3, v33); + v43 = H1; + v43 = _mm_mul_epu32(v43, T15); + T4 = _mm_add_epi64(T4, v42); + v44 = H0; + v44 = _mm_mul_epu32(v44, R24); + T2 = _mm_add_epi64(T2, v24); + T3 = _mm_add_epi64(T3, v34); + T4 = _mm_add_epi64(T4, v43); + T4 = _mm_add_epi64(T4, v44); + + /* H += [Mx,My] */ + if (m) { + T5 = _mm_loadu_si128((const xmmi *) (const void *) (m + 0)); + T6 = _mm_loadu_si128((const xmmi *) (const void *) (m + 16)); + T7 = _mm_unpacklo_epi32(T5, T6); + T8 = _mm_unpackhi_epi32(T5, T6); + M0 = _mm_unpacklo_epi32(T7, _mm_setzero_si128()); + M1 = _mm_unpackhi_epi32(T7, _mm_setzero_si128()); + M2 = _mm_unpacklo_epi32(T8, _mm_setzero_si128()); + M3 = _mm_unpackhi_epi32(T8, _mm_setzero_si128()); + M1 = _mm_slli_epi64(M1, 6); + M2 = _mm_slli_epi64(M2, 12); + M3 = _mm_slli_epi64(M3, 18); + T0 = _mm_add_epi64(T0, M0); + T1 = _mm_add_epi64(T1, M1); + T2 = _mm_add_epi64(T2, M2); + T3 = _mm_add_epi64(T3, M3); + T4 = _mm_add_epi64(T4, HIBIT); + } + + /* reduce */ + C1 = _mm_srli_epi64(T0, 26); + C2 = _mm_srli_epi64(T3, 26); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_and_si128(T3, MMASK); + T1 = _mm_add_epi64(T1, C1); + T4 = _mm_add_epi64(T4, C2); + C1 = _mm_srli_epi64(T1, 26); + C2 = _mm_srli_epi64(T4, 26); + T1 = _mm_and_si128(T1, MMASK); + T4 = _mm_and_si128(T4, MMASK); + T2 = _mm_add_epi64(T2, C1); + T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE)); + C1 = _mm_srli_epi64(T2, 26); + C2 = _mm_srli_epi64(T0, 26); + T2 = _mm_and_si128(T2, MMASK); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_add_epi64(T3, C1); + T1 = _mm_add_epi64(T1, C2); + C1 = _mm_srli_epi64(T3, 26); + T3 = _mm_and_si128(T3, MMASK); + T4 = _mm_add_epi64(T4, C1); + + /* H = (H*[r^2,r^2] + [Mx,My]) */ + H0 = T0; + H1 = T1; + H2 = T2; + H3 = T3; + H4 = T4; + } + + if (m) { + T0 = _mm_shuffle_epi32(H0, _MM_SHUFFLE(0, 0, 2, 0)); + T1 = _mm_shuffle_epi32(H1, _MM_SHUFFLE(0, 0, 2, 0)); + T2 = _mm_shuffle_epi32(H2, _MM_SHUFFLE(0, 0, 2, 0)); + T3 = _mm_shuffle_epi32(H3, _MM_SHUFFLE(0, 0, 2, 0)); + T4 = _mm_shuffle_epi32(H4, _MM_SHUFFLE(0, 0, 2, 0)); + T0 = _mm_unpacklo_epi64(T0, T1); + T1 = _mm_unpacklo_epi64(T2, T3); + _mm_storeu_si128((xmmi *) (void *) &st->H.hh[0], T0); + _mm_storeu_si128((xmmi *) (void *) &st->H.hh[4], T1); + _mm_storel_epi64((xmmi *) (void *) &st->H.hh[8], T4); + } else { + uint32_t t0, t1, t2, t3, t4, b; + uint64_t h0, h1, h2, g0, g1, g2, c, nc; + + /* H = H[0]+H[1] */ + T0 = H0; + T1 = H1; + T2 = H2; + T3 = H3; + T4 = H4; + + T0 = _mm_add_epi64(T0, _mm_srli_si128(T0, 8)); + T1 = _mm_add_epi64(T1, _mm_srli_si128(T1, 8)); + T2 = _mm_add_epi64(T2, _mm_srli_si128(T2, 8)); + T3 = _mm_add_epi64(T3, _mm_srli_si128(T3, 8)); + T4 = _mm_add_epi64(T4, _mm_srli_si128(T4, 8)); + + t0 = _mm_cvtsi128_si32(T0); + b = (t0 >> 26); + t0 &= 0x3ffffff; + t1 = _mm_cvtsi128_si32(T1) + b; + b = (t1 >> 26); + t1 &= 0x3ffffff; + t2 = _mm_cvtsi128_si32(T2) + b; + b = (t2 >> 26); + t2 &= 0x3ffffff; + t3 = _mm_cvtsi128_si32(T3) + b; + b = (t3 >> 26); + t3 &= 0x3ffffff; + t4 = _mm_cvtsi128_si32(T4) + b; + + /* everything except t4 is in range, so this is all safe */ + h0 = (((uint64_t) t0) | ((uint64_t) t1 << 26)) & 0xfffffffffffull; + h1 = (((uint64_t) t1 >> 18) | ((uint64_t) t2 << 8) | + ((uint64_t) t3 << 34)) & + 0xfffffffffffull; + h2 = (((uint64_t) t3 >> 10) | ((uint64_t) t4 << 16)); + + c = (h2 >> 42); + h2 &= 0x3ffffffffff; + h0 += c * 5; + c = (h0 >> 44); + h0 &= 0xfffffffffff; + h1 += c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + h2 += c; + c = (h2 >> 42); + h2 &= 0x3ffffffffff; + h0 += c * 5; + c = (h0 >> 44); + h0 &= 0xfffffffffff; + h1 += c; + + g0 = h0 + 5; + c = (g0 >> 44); + g0 &= 0xfffffffffff; + g1 = h1 + c; + c = (g1 >> 44); + g1 &= 0xfffffffffff; + g2 = h2 + c - ((uint64_t) 1 << 42); + + c = (g2 >> 63) - 1; + nc = ~c; + h0 = (h0 & nc) | (g0 & c); + h1 = (h1 & nc) | (g1 & c); + h2 = (h2 & nc) | (g2 & c); + + st->H.h[0] = h0; + st->H.h[1] = h1; + st->H.h[2] = h2; + } +} + +static void +poly1305_update(poly1305_state_internal_t *st, const unsigned char *m, + unsigned long long bytes) +{ + unsigned long long i; + + /* handle leftover */ + if (st->leftover) { + unsigned long long want = (poly1305_block_size - st->leftover); + + if (want > bytes) { + want = bytes; + } + for (i = 0; i < want; i++) { + st->buffer[st->leftover + i] = m[i]; + } + bytes -= want; + m += want; + st->leftover += want; + if (st->leftover < poly1305_block_size) { + return; + } + poly1305_blocks(st, st->buffer, poly1305_block_size); + st->leftover = 0; + } + + /* process full blocks */ + if (bytes >= poly1305_block_size) { + unsigned long long want = (bytes & ~(poly1305_block_size - 1)); + + poly1305_blocks(st, m, want); + m += want; + bytes -= want; + } + + /* store leftover */ + if (bytes) { + for (i = 0; i < bytes; i++) { + st->buffer[st->leftover + i] = m[i]; + } + st->leftover += bytes; + } +} + +static POLY1305_NOINLINE void +poly1305_finish_ext(poly1305_state_internal_t *st, const unsigned char *m, + unsigned long long leftover, unsigned char mac[16]) +{ + uint64_t h0, h1, h2; + + if (leftover) { + CRYPTO_ALIGN(16) unsigned char final[32] = { 0 }; + + poly1305_block_copy31(final, m, leftover); + if (leftover != 16) { + final[leftover] = 1; + } + st->flags |= + (leftover >= 16) ? poly1305_final_shift8 : poly1305_final_shift16; + poly1305_blocks(st, final, 32); + } + + if (st->flags & poly1305_started) { + /* finalize, H *= [r^2,r], or H *= [r,1] */ + if (!leftover || (leftover > 16)) { + st->flags |= poly1305_final_r2_r; + } else { + st->flags |= poly1305_final_r_1; + } + poly1305_blocks(st, NULL, 32); + } + + h0 = st->H.h[0]; + h1 = st->H.h[1]; + h2 = st->H.h[2]; + + /* pad */ + h0 = ((h0) | (h1 << 44)); + h1 = ((h1 >> 20) | (h2 << 24)); +#ifdef HAVE_AMD64_ASM + __asm__ __volatile__( + "addq %2, %0 ;\n" + "adcq %3, %1 ;\n" + : "+r"(h0), "+r"(h1) + : "r"(st->pad[0]), "r"(st->pad[1]) + : "flags", "cc"); +#else + { + uint128_t h; + + memcpy(&h, &st->pad[0], 16); + h += ((uint128_t) h1 << 64) | h0; + h0 = (uint64_t) h; + h1 = (uint64_t)(h >> 64); + } +#endif + _mm_storeu_si128((xmmi *) (void *) st + 0, _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) st + 1, _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) st + 2, _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) st + 3, _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) st + 4, _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) st + 5, _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) st + 6, _mm_setzero_si128()); + _mm_storeu_si128((xmmi *) (void *) st + 7, _mm_setzero_si128()); + + memcpy(&mac[0], &h0, 8); + memcpy(&mac[8], &h1, 8); + + sodium_memzero((void *) st, sizeof *st); +} + +static void +poly1305_finish(poly1305_state_internal_t *st, unsigned char mac[16]) +{ + poly1305_finish_ext(st, st->buffer, st->leftover, mac); +} + +static int +crypto_onetimeauth_poly1305_sse2_init(crypto_onetimeauth_poly1305_state *state, + const unsigned char *key) +{ + COMPILER_ASSERT(sizeof(crypto_onetimeauth_poly1305_state) >= + sizeof(poly1305_state_internal_t)); + poly1305_init_ext((poly1305_state_internal_t *) (void *) state, key, 0U); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_sse2_update( + crypto_onetimeauth_poly1305_state *state, const unsigned char *in, + unsigned long long inlen) +{ + poly1305_update((poly1305_state_internal_t *) (void *) state, in, inlen); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_sse2_final(crypto_onetimeauth_poly1305_state *state, + unsigned char *out) +{ + poly1305_finish((poly1305_state_internal_t *) (void *) state, out); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_sse2(unsigned char *out, const unsigned char *m, + unsigned long long inlen, + const unsigned char *key) +{ + CRYPTO_ALIGN(64) poly1305_state_internal_t st; + unsigned long long blocks; + + poly1305_init_ext(&st, key, inlen); + blocks = inlen & ~31; + if (blocks > 0) { + poly1305_blocks(&st, m, blocks); + m += blocks; + inlen -= blocks; + } + poly1305_finish_ext(&st, m, inlen, out); + + return 0; +} + +static int +crypto_onetimeauth_poly1305_sse2_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) +{ + unsigned char correct[16]; + + crypto_onetimeauth_poly1305_sse2(correct, in, inlen, k); + + return crypto_verify_16(h, correct); +} + +struct crypto_onetimeauth_poly1305_implementation + crypto_onetimeauth_poly1305_sse2_implementation = { + SODIUM_C99(.onetimeauth =) crypto_onetimeauth_poly1305_sse2, + SODIUM_C99(.onetimeauth_verify =) + crypto_onetimeauth_poly1305_sse2_verify, + SODIUM_C99(.onetimeauth_init =) crypto_onetimeauth_poly1305_sse2_init, + SODIUM_C99(.onetimeauth_update =) + crypto_onetimeauth_poly1305_sse2_update, + SODIUM_C99(.onetimeauth_final =) crypto_onetimeauth_poly1305_sse2_final + }; + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.h b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.h new file mode 100644 index 0000000..9177cad --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.h @@ -0,0 +1,12 @@ +#ifndef poly1305_sse2_H +#define poly1305_sse2_H + +#include + +#include "../onetimeauth_poly1305.h" +#include "crypto_onetimeauth_poly1305.h" + +extern struct crypto_onetimeauth_poly1305_implementation + crypto_onetimeauth_poly1305_sse2_implementation; + +#endif /* poly1305_sse2_H */ diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-core.c b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-core.c new file mode 100644 index 0000000..2922942 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-core.c @@ -0,0 +1,556 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with + * this software. If not, see + * . + */ + +#include +#include +#include +#include +#include + +#include +#ifdef HAVE_SYS_MMAN_H +# include +#endif + +#include "crypto_generichash_blake2b.h" +#include "private/common.h" +#include "private/implementations.h" +#include "runtime.h" +#include "utils.h" + +#include "argon2-core.h" +#include "blake2b-long.h" + +#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS) +# define MAP_ANON MAP_ANONYMOUS +#endif +#ifndef MAP_NOCORE +# ifdef MAP_CONCEAL +# define MAP_NOCORE MAP_CONCEAL +# else +# define MAP_NOCORE 0 +# endif +#endif +#ifndef MAP_POPULATE +# define MAP_POPULATE 0 +#endif + +static fill_segment_fn fill_segment = argon2_fill_segment_ref; + +static void +load_block(block *dst, const void *input) +{ + unsigned i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + dst->v[i] = LOAD64_LE((const uint8_t *) input + i * sizeof(dst->v[i])); + } +} + +static void +store_block(void *output, const block *src) +{ + unsigned i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + STORE64_LE((uint8_t *) output + i * sizeof(src->v[i]), src->v[i]); + } +} + +/***************Memory allocators*****************/ +/* Allocates memory to the given pointer + * @param memory pointer to the pointer to the memory + * @param m_cost number of blocks to allocate in the memory + * @return ARGON2_OK if @memory is a valid pointer and memory is allocated + */ +static int allocate_memory(block_region **region, uint32_t m_cost); + +static int +allocate_memory(block_region **region, uint32_t m_cost) +{ + void *base; + block *memory; + size_t memory_size; + + if (region == NULL) { + return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */ + } + memory_size = sizeof(block) * m_cost; + if (m_cost == 0 || memory_size / m_cost != sizeof(block)) { + return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */ + } + *region = (block_region *) malloc(sizeof(block_region)); + if (*region == NULL) { + return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */ + } + (*region)->base = (*region)->memory = NULL; + +#if defined(MAP_ANON) && defined(HAVE_MMAP) + if ((base = mmap(NULL, memory_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_NOCORE | MAP_POPULATE, + -1, 0)) == MAP_FAILED) { + base = NULL; /* LCOV_EXCL_LINE */ + } /* LCOV_EXCL_LINE */ + memory = (block *) base; +#elif defined(HAVE_POSIX_MEMALIGN) + if ((errno = posix_memalign((void **) &base, 64, memory_size)) != 0) { + base = NULL; + } + memory = (block *) base; +#else + memory = NULL; + if (memory_size + 63 < memory_size) { + base = NULL; + errno = ENOMEM; + } else if ((base = malloc(memory_size + 63)) != NULL) { + uint8_t *aligned = ((uint8_t *) base) + 63; + aligned -= (uintptr_t) aligned & 63; + memory = (block *) aligned; + } +#endif + if (base == NULL) { + /* LCOV_EXCL_START */ + free(*region); + *region = NULL; + return ARGON2_MEMORY_ALLOCATION_ERROR; + /* LCOV_EXCL_STOP */ + } + (*region)->base = base; + (*region)->memory = memory; + (*region)->size = memory_size; + + return ARGON2_OK; +} + +/*********Memory functions*/ + +/* Clears memory + * @param instance pointer to the current instance + * @param clear_memory indicates if we clear the memory with zeros. + */ +static void clear_memory(argon2_instance_t *instance, int clear); + +static void +clear_memory(argon2_instance_t *instance, int clear) +{ + /* LCOV_EXCL_START */ + if (clear) { + if (instance->region != NULL) { + sodium_memzero(instance->region->memory, + sizeof(block) * instance->memory_blocks); + } + if (instance->pseudo_rands != NULL) { + sodium_memzero(instance->pseudo_rands, + sizeof(uint64_t) * instance->segment_length); + } + } + /* LCOV_EXCL_STOP */ +} + +/* Deallocates memory + * @param memory pointer to the blocks + */ +static void free_memory(block_region *region); + +static void +free_memory(block_region *region) +{ + if (region && region->base) { +#if defined(MAP_ANON) && defined(HAVE_MMAP) + if (munmap(region->base, region->size)) { + return; /* LCOV_EXCL_LINE */ + } +#else + free(region->base); +#endif + } + free(region); +} + +static void +argon2_free_instance(argon2_instance_t *instance, int flags) +{ + /* Clear memory */ + clear_memory(instance, flags & ARGON2_FLAG_CLEAR_MEMORY); + + /* Deallocate the memory */ + free(instance->pseudo_rands); + instance->pseudo_rands = NULL; + free_memory(instance->region); + instance->region = NULL; +} + +void +argon2_finalize(const argon2_context *context, argon2_instance_t *instance) +{ + if (context != NULL && instance != NULL) { + block blockhash; + uint32_t l; + + copy_block(&blockhash, + instance->region->memory + instance->lane_length - 1); + + /* XOR the last blocks */ + for (l = 1; l < instance->lanes; ++l) { + uint32_t last_block_in_lane = + l * instance->lane_length + (instance->lane_length - 1); + xor_block(&blockhash, + instance->region->memory + last_block_in_lane); + } + + /* Hash the result */ + { + uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; + store_block(blockhash_bytes, &blockhash); + blake2b_long(context->out, context->outlen, blockhash_bytes, + ARGON2_BLOCK_SIZE); + sodium_memzero(blockhash.v, + ARGON2_BLOCK_SIZE); /* clear blockhash */ + sodium_memzero(blockhash_bytes, + ARGON2_BLOCK_SIZE); /* clear blockhash_bytes */ + } + + argon2_free_instance(instance, context->flags); + } +} + +void +argon2_fill_memory_blocks(argon2_instance_t *instance, uint32_t pass) +{ + argon2_position_t position; + uint32_t l; + uint32_t s; + + if (instance == NULL || instance->lanes == 0) { + return; /* LCOV_EXCL_LINE */ + } + + position.pass = pass; + for (s = 0; s < ARGON2_SYNC_POINTS; ++s) { + position.slice = (uint8_t) s; + for (l = 0; l < instance->lanes; ++l) { + position.lane = l; + position.index = 0; + fill_segment(instance, position); + } + } +} + +int +argon2_validate_inputs(const argon2_context *context) +{ + /* LCOV_EXCL_START */ + if (NULL == context) { + return ARGON2_INCORRECT_PARAMETER; + } + + if (NULL == context->out) { + return ARGON2_OUTPUT_PTR_NULL; + } + + /* Validate output length */ + if (ARGON2_MIN_OUTLEN > context->outlen) { + return ARGON2_OUTPUT_TOO_SHORT; + } + + if (ARGON2_MAX_OUTLEN < context->outlen) { + return ARGON2_OUTPUT_TOO_LONG; + } + + /* Validate password (required param) */ + if (NULL == context->pwd) { + if (0 != context->pwdlen) { + return ARGON2_PWD_PTR_MISMATCH; + } + } + + if (ARGON2_MIN_PWD_LENGTH > context->pwdlen) { + return ARGON2_PWD_TOO_SHORT; + } + + if (ARGON2_MAX_PWD_LENGTH < context->pwdlen) { + return ARGON2_PWD_TOO_LONG; + } + + /* Validate salt (required param) */ + if (NULL == context->salt) { + if (0 != context->saltlen) { + return ARGON2_SALT_PTR_MISMATCH; + } + } + + if (ARGON2_MIN_SALT_LENGTH > context->saltlen) { + return ARGON2_SALT_TOO_SHORT; + } + + if (ARGON2_MAX_SALT_LENGTH < context->saltlen) { + return ARGON2_SALT_TOO_LONG; + } + + /* Validate secret (optional param) */ + if (NULL == context->secret) { + if (0 != context->secretlen) { + return ARGON2_SECRET_PTR_MISMATCH; + } + } else { + if (ARGON2_MIN_SECRET > context->secretlen) { + return ARGON2_SECRET_TOO_SHORT; + } + + if (ARGON2_MAX_SECRET < context->secretlen) { + return ARGON2_SECRET_TOO_LONG; + } + } + + /* Validate associated data (optional param) */ + if (NULL == context->ad) { + if (0 != context->adlen) { + return ARGON2_AD_PTR_MISMATCH; + } + } else { + if (ARGON2_MIN_AD_LENGTH > context->adlen) { + return ARGON2_AD_TOO_SHORT; + } + + if (ARGON2_MAX_AD_LENGTH < context->adlen) { + return ARGON2_AD_TOO_LONG; + } + } + + /* Validate lanes */ + if (ARGON2_MIN_LANES > context->lanes) { + return ARGON2_LANES_TOO_FEW; + } + + if (ARGON2_MAX_LANES < context->lanes) { + return ARGON2_LANES_TOO_MANY; + } + + /* Validate memory cost */ + if (ARGON2_MIN_MEMORY > context->m_cost) { + return ARGON2_MEMORY_TOO_LITTLE; + } + + if (ARGON2_MAX_MEMORY < context->m_cost) { + return ARGON2_MEMORY_TOO_MUCH; + } + + if (context->m_cost < 8 * context->lanes) { + return ARGON2_MEMORY_TOO_LITTLE; + } + + /* Validate time cost */ + if (ARGON2_MIN_TIME > context->t_cost) { + return ARGON2_TIME_TOO_SMALL; + } + + if (ARGON2_MAX_TIME < context->t_cost) { + return ARGON2_TIME_TOO_LARGE; + } + + /* Validate threads */ + if (ARGON2_MIN_THREADS > context->threads) { + return ARGON2_THREADS_TOO_FEW; + } + + if (ARGON2_MAX_THREADS < context->threads) { + return ARGON2_THREADS_TOO_MANY; + } + /* LCOV_EXCL_STOP */ + + return ARGON2_OK; +} + +static void +argon2_fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) +{ + uint32_t l; + /* Make the first and second block in each lane as G(H0||i||0) or + G(H0||i||1) */ + uint8_t blockhash_bytes[ARGON2_BLOCK_SIZE]; + for (l = 0; l < instance->lanes; ++l) { + STORE32_LE(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 0); + STORE32_LE(blockhash + ARGON2_PREHASH_DIGEST_LENGTH + 4, l); + blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, + ARGON2_PREHASH_SEED_LENGTH); + load_block(&instance->region->memory[l * instance->lane_length + 0], + blockhash_bytes); + + STORE32_LE(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, 1); + blake2b_long(blockhash_bytes, ARGON2_BLOCK_SIZE, blockhash, + ARGON2_PREHASH_SEED_LENGTH); + load_block(&instance->region->memory[l * instance->lane_length + 1], + blockhash_bytes); + } + sodium_memzero(blockhash_bytes, ARGON2_BLOCK_SIZE); +} + +static void +argon2_initial_hash(uint8_t *blockhash, argon2_context *context, + argon2_type type) +{ + crypto_generichash_blake2b_state BlakeHash; + uint8_t value[4U /* sizeof(uint32_t) */]; + + if (NULL == context || NULL == blockhash) { + return; /* LCOV_EXCL_LINE */ + } + + crypto_generichash_blake2b_init(&BlakeHash, NULL, 0U, + ARGON2_PREHASH_DIGEST_LENGTH); + + STORE32_LE(value, context->lanes); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + STORE32_LE(value, context->outlen); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + STORE32_LE(value, context->m_cost); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + STORE32_LE(value, context->t_cost); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + STORE32_LE(value, ARGON2_VERSION_NUMBER); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + STORE32_LE(value, (uint32_t) type); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + STORE32_LE(value, context->pwdlen); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + if (context->pwd != NULL) { + crypto_generichash_blake2b_update( + &BlakeHash, (const uint8_t *) context->pwd, context->pwdlen); + + /* LCOV_EXCL_START */ + if (context->flags & ARGON2_FLAG_CLEAR_PASSWORD) { + sodium_memzero(context->pwd, context->pwdlen); + context->pwdlen = 0; + } + /* LCOV_EXCL_STOP */ + } + + STORE32_LE(value, context->saltlen); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + if (context->salt != NULL) { + crypto_generichash_blake2b_update( + &BlakeHash, (const uint8_t *) context->salt, context->saltlen); + } + + STORE32_LE(value, context->secretlen); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + /* LCOV_EXCL_START */ + if (context->secret != NULL) { + crypto_generichash_blake2b_update( + &BlakeHash, (const uint8_t *) context->secret, context->secretlen); + + if (context->flags & ARGON2_FLAG_CLEAR_SECRET) { + sodium_memzero(context->secret, context->secretlen); + context->secretlen = 0; + } + } + /* LCOV_EXCL_STOP */ + + STORE32_LE(value, context->adlen); + crypto_generichash_blake2b_update(&BlakeHash, value, sizeof(value)); + + /* LCOV_EXCL_START */ + if (context->ad != NULL) { + crypto_generichash_blake2b_update( + &BlakeHash, (const uint8_t *) context->ad, context->adlen); + } + /* LCOV_EXCL_STOP */ + + crypto_generichash_blake2b_final(&BlakeHash, blockhash, + ARGON2_PREHASH_DIGEST_LENGTH); +} + +int +argon2_initialize(argon2_instance_t *instance, argon2_context *context) +{ + uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; + int result = ARGON2_OK; + + if (instance == NULL || context == NULL) { + return ARGON2_INCORRECT_PARAMETER; + } + + /* 1. Memory allocation */ + + if ((instance->pseudo_rands = (uint64_t *) + malloc(sizeof(uint64_t) * instance->segment_length)) == NULL) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + result = allocate_memory(&(instance->region), instance->memory_blocks); + if (ARGON2_OK != result) { + argon2_free_instance(instance, context->flags); + return result; + } + + /* 2. Initial hashing */ + /* H_0 + 8 extra bytes to produce the first blocks */ + /* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */ + /* Hashing all inputs */ + argon2_initial_hash(blockhash, context, instance->type); + /* Zeroing 8 extra bytes */ + sodium_memzero(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, + ARGON2_PREHASH_SEED_LENGTH - ARGON2_PREHASH_DIGEST_LENGTH); + + /* 3. Creating first blocks, we always have at least two blocks in a slice + */ + argon2_fill_first_blocks(blockhash, instance); + /* Clearing the hash */ + sodium_memzero(blockhash, ARGON2_PREHASH_SEED_LENGTH); + + return ARGON2_OK; +} + +static int +argon2_pick_best_implementation(void) +{ +/* LCOV_EXCL_START */ +#if defined(HAVE_AVX512FINTRIN_H) && defined(HAVE_AVX2INTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) && \ + !defined(__APPLE__) + if (sodium_runtime_has_avx512f()) { + fill_segment = argon2_fill_segment_avx512f; + return 0; + } +#endif +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_TMMINTRIN_H) && \ + defined(HAVE_SMMINTRIN_H) + if (sodium_runtime_has_avx2()) { + fill_segment = argon2_fill_segment_avx2; + return 0; + } +#endif +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) + if (sodium_runtime_has_ssse3()) { + fill_segment = argon2_fill_segment_ssse3; + return 0; + } +#endif + fill_segment = argon2_fill_segment_ref; + + return 0; + /* LCOV_EXCL_STOP */ +} + +int +_crypto_pwhash_argon2_pick_best_implementation(void) +{ + return argon2_pick_best_implementation(); +} diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-core.h b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-core.h new file mode 100644 index 0000000..2fd7f41 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-core.h @@ -0,0 +1,271 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with + * this software. If not, see + * . + */ + +#ifndef argon2_core_H +#define argon2_core_H + +#include + +#include "argon2.h" + +/*************************Argon2 internal + * constants**************************************************/ + +enum argon2_ctx_constants { + /* Version of the algorithm */ + ARGON2_VERSION_NUMBER = 0x13, + + /* Memory block size in bytes */ + ARGON2_BLOCK_SIZE = 1024, + ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8, + ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16, + ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32, + ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64, + + /* Number of pseudo-random values generated by one call to Blake in Argon2i + to + generate reference block positions */ + ARGON2_ADDRESSES_IN_BLOCK = 128, + + /* Pre-hashing digest length and its extension*/ + ARGON2_PREHASH_DIGEST_LENGTH = 64, + ARGON2_PREHASH_SEED_LENGTH = 72 +}; + +/*************************Argon2 internal data + * types**************************************************/ + +/* + * Structure for the (1KB) memory block implemented as 128 64-bit words. + * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no + * bounds checking). + */ +typedef struct block_ { + uint64_t v[ARGON2_QWORDS_IN_BLOCK]; +} block; + +typedef struct block_region_ { + void * base; + block *memory; + size_t size; +} block_region; + +/*****************Functions that work with the block******************/ + +/* Initialize each byte of the block with @in */ +static inline void +init_block_value(block *b, uint8_t in) +{ + memset(b->v, in, sizeof(b->v)); +} + +/* Copy block @src to block @dst */ +static inline void +copy_block(block *dst, const block *src) +{ + memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK); +} + +/* XOR @src onto @dst bytewise */ +static inline void +xor_block(block *dst, const block *src) +{ + int i; + for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) { + dst->v[i] ^= src->v[i]; + } +} + +/* + * Argon2 instance: memory pointer, number of passes, amount of memory, type, + * and derived values. + * Used to evaluate the number and location of blocks to construct in each + * thread + */ +typedef struct Argon2_instance_t { + block_region *region; /* Memory region pointer */ + uint64_t *pseudo_rands; + uint32_t passes; /* Number of passes */ + uint32_t current_pass; + uint32_t memory_blocks; /* Number of blocks in memory */ + uint32_t segment_length; + uint32_t lane_length; + uint32_t lanes; + uint32_t threads; + argon2_type type; + int print_internals; /* whether to print the memory blocks */ +} argon2_instance_t; + +/* + * Argon2 position: where we construct the block right now. Used to distribute + * work between threads. + */ +typedef struct Argon2_position_t { + uint32_t pass; + uint32_t lane; + uint8_t slice; + uint32_t index; +} argon2_position_t; + +/*Struct that holds the inputs for thread handling FillSegment*/ +typedef struct Argon2_thread_data { + argon2_instance_t *instance_ptr; + argon2_position_t pos; +} argon2_thread_data; + +/*************************Argon2 core + * functions**************************************************/ + +/* + * Computes absolute position of reference block in the lane following a skewed + * distribution and using a pseudo-random value as input + * @param instance Pointer to the current instance + * @param position Pointer to the current position + * @param pseudo_rand 32-bit pseudo-random value used to determine the position + * @param same_lane Indicates if the block will be taken from the current lane. + * If so we can reference the current segment + * @pre All pointers must be valid + */ +static uint32_t index_alpha(const argon2_instance_t *instance, + const argon2_position_t *position, uint32_t pseudo_rand, + int same_lane) +{ + /* + * Pass 0: + * This lane : all already finished segments plus already constructed + * blocks in this segment + * Other lanes : all already finished segments + * Pass 1+: + * This lane : (SYNC_POINTS - 1) last segments plus already constructed + * blocks in this segment + * Other lanes : (SYNC_POINTS - 1) last segments + */ + uint32_t reference_area_size; + uint64_t relative_position; + uint32_t start_position, absolute_position; + + if (position->pass == 0) { + /* First pass */ + if (position->slice == 0) { + /* First slice */ + reference_area_size = + position->index - 1; /* all but the previous */ + } else { + if (same_lane) { + /* The same lane => add current segment */ + reference_area_size = + position->slice * instance->segment_length + + position->index - 1; + } else { + reference_area_size = + position->slice * instance->segment_length + + ((position->index == 0) ? (-1) : 0); + } + } + } else { + /* Second pass */ + if (same_lane) { + reference_area_size = instance->lane_length - + instance->segment_length + position->index - + 1; + } else { + reference_area_size = instance->lane_length - + instance->segment_length + + ((position->index == 0) ? (-1) : 0); + } + } + + /* 1.2.4. Mapping pseudo_rand to 0.. and produce + * relative position */ + relative_position = pseudo_rand; + relative_position = relative_position * relative_position >> 32; + relative_position = reference_area_size - 1 - + (reference_area_size * relative_position >> 32); + + /* 1.2.5 Computing starting position */ + start_position = 0; + + if (position->pass != 0) { + start_position = (position->slice == ARGON2_SYNC_POINTS - 1) + ? 0 + : (position->slice + 1) * instance->segment_length; + } + + /* 1.2.6. Computing absolute position */ + absolute_position = (start_position + relative_position) % + instance->lane_length; /* absolute position */ + return absolute_position; +} + +/* + * Function that validates all inputs against predefined restrictions and return + * an error code + * @param context Pointer to current Argon2 context + * @return ARGON2_OK if everything is all right, otherwise one of error codes + * (all defined in + */ +int argon2_validate_inputs(const argon2_context *context); + +/* + * Function allocates memory, hashes the inputs with Blake, and creates first + * two blocks. Returns the pointer to the main memory with 2 blocks per lane + * initialized + * @param context Pointer to the Argon2 internal structure containing memory + * pointer, and parameters for time and space requirements. + * @param instance Current Argon2 instance + * @return Zero if successful, -1 if memory failed to allocate. @context->state + * will be modified if successful. + */ +int argon2_initialize(argon2_instance_t *instance, argon2_context *context); + +/* + * XORing the last block of each lane, hashing it, making the tag. Deallocates + * the memory. + * @param context Pointer to current Argon2 context (use only the out parameters + * from it) + * @param instance Pointer to current instance of Argon2 + * @pre instance->state must point to necessary amount of memory + * @pre context->out must point to outlen bytes of memory + * @pre if context->free_cbk is not NULL, it should point to a function that + * deallocates memory + */ +void argon2_finalize(const argon2_context *context, + argon2_instance_t *instance); + +/* + * Function that fills the segment using previous segments also from other + * threads + * @param instance Pointer to the current instance + * @param position Current position + * @pre all block pointers must be valid + */ +typedef void (*fill_segment_fn)(const argon2_instance_t *instance, + argon2_position_t position); +void argon2_fill_segment_avx512f(const argon2_instance_t *instance, + argon2_position_t position); +void argon2_fill_segment_avx2(const argon2_instance_t *instance, + argon2_position_t position); +void argon2_fill_segment_ssse3(const argon2_instance_t *instance, + argon2_position_t position); +void argon2_fill_segment_ref(const argon2_instance_t *instance, + argon2_position_t position); + +/* + * Function that fills the entire memory t_cost times based on the first two + * blocks in each lane + * @param instance Pointer to the current instance + * @return Zero if successful, -1 if memory failed to allocate + */ +void argon2_fill_memory_blocks(argon2_instance_t *instance, uint32_t pass); + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-encoding.c b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-encoding.c new file mode 100644 index 0000000..6a80afe --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-encoding.c @@ -0,0 +1,306 @@ +#include "argon2-encoding.h" +#include "argon2-core.h" +#include "utils.h" +#include +#include +#include +#include + +/* + * Example code for a decoder and encoder of "hash strings", with Argon2 + * parameters. + * + * The code was originally written by Thomas Pornin , + * to whom comments and remarks may be sent. It is released under what + * should amount to Public Domain or its closest equivalent; the + * following mantra is supposed to incarnate that fact with all the + * proper legal rituals: + * + * --------------------------------------------------------------------- + * This file is provided under the terms of Creative Commons CC0 1.0 + * Public Domain Dedication. To the extent possible under law, the + * author (Thomas Pornin) has waived all copyright and related or + * neighboring rights to this file. This work is published from: Canada. + * --------------------------------------------------------------------- + * + * Copyright (c) 2015 Thomas Pornin + */ + +/* ==================================================================== */ + +/* + * Decode decimal integer from 'str'; the value is written in '*v'. + * Returned value is a pointer to the next non-decimal character in the + * string. If there is no digit at all, or the value encoding is not + * minimal (extra leading zeros), or the value does not fit in an + * 'unsigned long', then NULL is returned. + */ +static const char * +decode_decimal(const char *str, unsigned long *v) +{ + const char *orig; + unsigned long acc; + + acc = 0; + for (orig = str;; str++) { + int c; + + c = *str; + if (c < '0' || c > '9') { + break; + } + c -= '0'; + if (acc > (ULONG_MAX / 10)) { + return NULL; + } + acc *= 10; + if ((unsigned long) c > (ULONG_MAX - acc)) { + return NULL; + } + acc += (unsigned long) c; + } + if (str == orig || (*orig == '0' && str != (orig + 1))) { + return NULL; + } + *v = acc; + return str; +} + +/* ==================================================================== */ +/* + * Code specific to Argon2. + * + * The code below applies the following format: + * + * $argon2[$v=]$m=,t=,p=$$ + * + * where is either 'i', is a decimal integer (positive, fits in an + * 'unsigned long') and is Base64-encoded data (no '=' padding characters, + * no newline or whitespace). + * + * The last two binary chunks (encoded in Base64) are, in that order, + * the salt and the output. Both are required. The binary salt length and the + * output length must be in the allowed ranges defined in argon2.h. + * + * The ctx struct must contain buffers large enough to hold the salt and pwd + * when it is fed into argon2_decode_string. + */ + +/* + * Decode an Argon2i hash string into the provided structure 'ctx'. + * Returned value is ARGON2_OK on success. + */ +int +argon2_decode_string(argon2_context *ctx, const char *str, argon2_type type) +{ +/* Prefix checking */ +#define CC(prefix) \ + do { \ + size_t cc_len = strlen(prefix); \ + if (strncmp(str, prefix, cc_len) != 0) { \ + return ARGON2_DECODING_FAIL; \ + } \ + str += cc_len; \ + } while ((void) 0, 0) + +/* Optional prefix checking with supplied code */ +#define CC_opt(prefix, code) \ + do { \ + size_t cc_len = strlen(prefix); \ + if (strncmp(str, prefix, cc_len) == 0) { \ + str += cc_len; \ + { \ + code; \ + } \ + } \ + } while ((void) 0, 0) + +/* Decoding prefix into decimal */ +#define DECIMAL(x) \ + do { \ + unsigned long dec_x; \ + str = decode_decimal(str, &dec_x); \ + if (str == NULL) { \ + return ARGON2_DECODING_FAIL; \ + } \ + (x) = dec_x; \ + } while ((void) 0, 0) + +/* Decoding prefix into uint32_t decimal */ +#define DECIMAL_U32(x) \ + do { \ + unsigned long dec_x; \ + str = decode_decimal(str, &dec_x); \ + if (str == NULL || dec_x > UINT32_MAX) { \ + return ARGON2_DECODING_FAIL; \ + } \ + (x) = (uint32_t)dec_x; \ + } while ((void)0, 0) + +/* Decoding base64 into a binary buffer */ +#define BIN(buf, max_len, len) \ + do { \ + size_t bin_len = (max_len); \ + const char *str_end; \ + if (sodium_base642bin((buf), (max_len), str, strlen(str), NULL, \ + &bin_len, &str_end, \ + sodium_base64_VARIANT_ORIGINAL_NO_PADDING) != 0 || \ + bin_len > UINT32_MAX) { \ + return ARGON2_DECODING_FAIL; \ + } \ + (len) = (uint32_t) bin_len; \ + str = str_end; \ + } while ((void) 0, 0) + + size_t maxsaltlen = ctx->saltlen; + size_t maxoutlen = ctx->outlen; + int validation_result; + uint32_t version = 0; + + ctx->saltlen = 0; + ctx->outlen = 0; + + if (type == Argon2_id) { + CC("$argon2id"); + } else if (type == Argon2_i) { + CC("$argon2i"); + } else { + return ARGON2_INCORRECT_TYPE; + } + CC("$v="); + DECIMAL_U32(version); + if (version != ARGON2_VERSION_NUMBER) { + return ARGON2_INCORRECT_TYPE; + } + CC("$m="); + DECIMAL_U32(ctx->m_cost); + if (ctx->m_cost > UINT32_MAX) { + return ARGON2_INCORRECT_TYPE; + } + CC(",t="); + DECIMAL_U32(ctx->t_cost); + if (ctx->t_cost > UINT32_MAX) { + return ARGON2_INCORRECT_TYPE; + } + CC(",p="); + DECIMAL_U32(ctx->lanes); + if (ctx->lanes > UINT32_MAX) { + return ARGON2_INCORRECT_TYPE; + } + ctx->threads = ctx->lanes; + + CC("$"); + BIN(ctx->salt, maxsaltlen, ctx->saltlen); + CC("$"); + BIN(ctx->out, maxoutlen, ctx->outlen); + validation_result = argon2_validate_inputs(ctx); + if (validation_result != ARGON2_OK) { + return validation_result; + } + if (*str == 0) { + return ARGON2_OK; + } + return ARGON2_DECODING_FAIL; + +#undef CC +#undef CC_opt +#undef DECIMAL +#undef BIN +} + +#define U32_STR_MAXSIZE 11U + +static void +u32_to_string(char *str, uint32_t x) +{ + char tmp[U32_STR_MAXSIZE - 1U]; + size_t i; + + i = sizeof tmp; + do { + tmp[--i] = (x % (uint32_t) 10U) + '0'; + x /= (uint32_t) 10U; + } while (x != 0U && i != 0U); + memcpy(str, &tmp[i], (sizeof tmp) - i); + str[(sizeof tmp) - i] = 0; +} + +/* + * Encode an argon2i hash string into the provided buffer. 'dst_len' + * contains the size, in characters, of the 'dst' buffer; if 'dst_len' + * is less than the number of required characters (including the + * terminating 0), then this function returns 0. + * + * If pp->output_len is 0, then the hash string will be a salt string + * (no output). if pp->salt_len is also 0, then the string will be a + * parameter-only string (no salt and no output). + * + * On success, ARGON2_OK is returned. + */ +int +argon2_encode_string(char *dst, size_t dst_len, argon2_context *ctx, + argon2_type type) +{ +#define SS(str) \ + do { \ + size_t pp_len = strlen(str); \ + if (pp_len >= dst_len) { \ + return ARGON2_ENCODING_FAIL; \ + } \ + memcpy(dst, str, pp_len + 1); \ + dst += pp_len; \ + dst_len -= pp_len; \ + } while ((void) 0, 0) + +#define SX(x) \ + do { \ + char tmp[U32_STR_MAXSIZE]; \ + u32_to_string(tmp, x); \ + SS(tmp); \ + } while ((void) 0, 0) + +#define SB(buf, len) \ + do { \ + size_t sb_len; \ + if (sodium_bin2base64(dst, dst_len, (buf), (len), \ + sodium_base64_VARIANT_ORIGINAL_NO_PADDING) == NULL) { \ + return ARGON2_ENCODING_FAIL; \ + } \ + sb_len = strlen(dst); \ + dst += sb_len; \ + dst_len -= sb_len; \ + } while ((void) 0, 0) + + int validation_result; + + switch (type) { + case Argon2_id: + SS("$argon2id$v="); break; + case Argon2_i: + SS("$argon2i$v="); break; + default: + return ARGON2_ENCODING_FAIL; + } + validation_result = argon2_validate_inputs(ctx); + if (validation_result != ARGON2_OK) { + return validation_result; + } + SX(ARGON2_VERSION_NUMBER); + SS("$m="); + SX(ctx->m_cost); + SS(",t="); + SX(ctx->t_cost); + SS(",p="); + SX(ctx->lanes); + + SS("$"); + SB(ctx->salt, ctx->saltlen); + + SS("$"); + SB(ctx->out, ctx->outlen); + return ARGON2_OK; + +#undef SS +#undef SX +#undef SB +} diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-encoding.h b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-encoding.h new file mode 100644 index 0000000..c35fbf4 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-encoding.h @@ -0,0 +1,34 @@ +#ifndef argon2_encoding_H +#define argon2_encoding_H + +#include "argon2.h" + +/* + * encode an Argon2 hash string into the provided buffer. 'dst_len' + * contains the size, in characters, of the 'dst' buffer; if 'dst_len' + * is less than the number of required characters (including the + * terminating 0), then this function returns 0. + * + * if ctx->outlen is 0, then the hash string will be a salt string + * (no output). if ctx->saltlen is also 0, then the string will be a + * parameter-only string (no salt and no output). + * + * On success, ARGON2_OK is returned. + * + * No other parameters are checked + */ +int argon2_encode_string(char *dst, size_t dst_len, argon2_context *ctx, + argon2_type type); + +/* + * Decodes an Argon2 hash string into the provided structure 'ctx'. + * The fields ctx.saltlen, ctx.adlen, ctx.outlen set the maximal salt, ad, out + * length values + * that are allowed; invalid input string causes an error + * + * Returned value is ARGON2_OK on success. + */ +int argon2_decode_string(argon2_context *ctx, const char *str, + argon2_type type); + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-avx2.c b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-avx2.c new file mode 100644 index 0000000..a35e1f9 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-avx2.c @@ -0,0 +1,239 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with + * this software. If not, see + * . + */ + +#include +#include +#include + +#include "argon2-core.h" +#include "argon2.h" +#include "private/common.h" + +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# pragma GCC target("sse4.1") +# pragma GCC target("avx2") +# endif + +# ifdef _MSC_VER +# include /* for _mm_set_epi64x */ +# endif +# include +# include +# include +# include +# include "private/sse2_64_32.h" + +# include "blamka-round-avx2.h" + +static void +fill_block(__m256i *state, const uint8_t *ref_block, uint8_t *next_block) +{ + __m256i block_XY[ARGON2_HWORDS_IN_BLOCK]; + uint32_t i; + + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + block_XY[i] = state[i] = _mm256_xor_si256( + state[i], _mm256_loadu_si256((__m256i const *) (&ref_block[32 * i]))); + } + + for (i = 0; i < 4; ++i) { + BLAKE2_ROUND_1(state[8 * i + 0], state[8 * i + 4], state[8 * i + 1], state[8 * i + 5], + state[8 * i + 2], state[8 * i + 6], state[8 * i + 3], state[8 * i + 7]); + } + + for (i = 0; i < 4; ++i) { + BLAKE2_ROUND_2(state[ 0 + i], state[ 4 + i], state[ 8 + i], state[12 + i], + state[16 + i], state[20 + i], state[24 + i], state[28 + i]); + } + + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + state[i] = _mm256_xor_si256(state[i], block_XY[i]); + _mm256_storeu_si256((__m256i *) (&next_block[32 * i]), state[i]); + } +} + +static void +fill_block_with_xor(__m256i *state, const uint8_t *ref_block, + uint8_t *next_block) +{ + __m256i block_XY[ARGON2_HWORDS_IN_BLOCK]; + uint32_t i; + + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + state[i] = _mm256_xor_si256( + state[i], _mm256_loadu_si256((__m256i const *) (&ref_block[32 * i]))); + block_XY[i] = _mm256_xor_si256( + state[i], _mm256_loadu_si256((__m256i const *) (&next_block[32 * i]))); + } + + for (i = 0; i < 4; ++i) { + BLAKE2_ROUND_1(state[8 * i + 0], state[8 * i + 4], state[8 * i + 1], state[8 * i + 5], + state[8 * i + 2], state[8 * i + 6], state[8 * i + 3], state[8 * i + 7]); + } + + for (i = 0; i < 4; ++i) { + BLAKE2_ROUND_2(state[ 0 + i], state[ 4 + i], state[ 8 + i], state[12 + i], + state[16 + i], state[20 + i], state[24 + i], state[28 + i]); + } + + for (i = 0; i < ARGON2_HWORDS_IN_BLOCK; i++) { + state[i] = _mm256_xor_si256(state[i], block_XY[i]); + _mm256_storeu_si256((__m256i *) (&next_block[32 * i]), state[i]); + } +} + +static void +generate_addresses(const argon2_instance_t *instance, + const argon2_position_t *position, uint64_t *pseudo_rands) +{ + block address_block, input_block, tmp_block; + uint32_t i; + + init_block_value(&address_block, 0); + init_block_value(&input_block, 0); + + if (instance != NULL && position != NULL) { + input_block.v[0] = position->pass; + input_block.v[1] = position->lane; + input_block.v[2] = position->slice; + input_block.v[3] = instance->memory_blocks; + input_block.v[4] = instance->passes; + input_block.v[5] = instance->type; + + for (i = 0; i < instance->segment_length; ++i) { + if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { + /* Temporary zero-initialized blocks */ + __m256i zero_block[ARGON2_HWORDS_IN_BLOCK]; + __m256i zero2_block[ARGON2_HWORDS_IN_BLOCK]; + + memset(zero_block, 0, sizeof(zero_block)); + memset(zero2_block, 0, sizeof(zero2_block)); + init_block_value(&address_block, 0); + init_block_value(&tmp_block, 0); + /* Increasing index counter */ + input_block.v[6]++; + /* First iteration of G */ + fill_block_with_xor(zero_block, (uint8_t *) &input_block.v, + (uint8_t *) &tmp_block.v); + /* Second iteration of G */ + fill_block_with_xor(zero2_block, (uint8_t *) &tmp_block.v, + (uint8_t *) &address_block.v); + } + + pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; + } + } +} + +void +argon2_fill_segment_avx2(const argon2_instance_t *instance, + argon2_position_t position) +{ + block *ref_block = NULL, *curr_block = NULL; + uint64_t pseudo_rand, ref_index, ref_lane; + uint32_t prev_offset, curr_offset; + uint32_t starting_index, i; + __m256i state[ARGON2_HWORDS_IN_BLOCK]; + int data_independent_addressing = 1; + + /* Pseudo-random values that determine the reference block position */ + uint64_t *pseudo_rands = NULL; + + if (instance == NULL) { + return; + } + + if (instance->type == Argon2_id && + (position.pass != 0 || position.slice >= ARGON2_SYNC_POINTS / 2)) { + data_independent_addressing = 0; + } + + pseudo_rands = instance->pseudo_rands; + + if (data_independent_addressing) { + generate_addresses(instance, &position, pseudo_rands); + } + + starting_index = 0; + + if ((0 == position.pass) && (0 == position.slice)) { + starting_index = 2; /* we have already generated the first two blocks */ + } + + /* Offset of the current block */ + curr_offset = position.lane * instance->lane_length + + position.slice * instance->segment_length + starting_index; + + if (0 == curr_offset % instance->lane_length) { + /* Last block in this lane */ + prev_offset = curr_offset + instance->lane_length - 1; + } else { + /* Previous block */ + prev_offset = curr_offset - 1; + } + + memcpy(state, ((instance->region->memory + prev_offset)->v), + ARGON2_BLOCK_SIZE); + + for (i = starting_index; i < instance->segment_length; + ++i, ++curr_offset, ++prev_offset) { + /*1.1 Rotating prev_offset if needed */ + if (curr_offset % instance->lane_length == 1) { + prev_offset = curr_offset - 1; + } + + /* 1.2 Computing the index of the reference block */ + /* 1.2.1 Taking pseudo-random value from the previous block */ + if (data_independent_addressing) { +#pragma warning(push) +#pragma warning(disable : 6385) + pseudo_rand = pseudo_rands[i]; +#pragma warning(pop) + } else { + pseudo_rand = instance->region->memory[prev_offset].v[0]; + } + + /* 1.2.2 Computing the lane of the reference block */ + ref_lane = ((pseudo_rand >> 32)) % instance->lanes; + + if ((position.pass == 0) && (position.slice == 0)) { + /* Can not reference other lanes yet */ + ref_lane = position.lane; + } + + /* 1.2.3 Computing the number of possible reference block within the + * lane. + */ + position.index = i; + ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, + ref_lane == position.lane); + + /* 2 Creating a new block */ + ref_block = instance->region->memory + + instance->lane_length * ref_lane + ref_index; + curr_block = instance->region->memory + curr_offset; + if (position.pass != 0) { + fill_block_with_xor(state, (uint8_t *) ref_block->v, + (uint8_t *) curr_block->v); + } else { + fill_block(state, (uint8_t *) ref_block->v, + (uint8_t *) curr_block->v); + } + } +} +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-avx512f.c b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-avx512f.c new file mode 100644 index 0000000..6566804 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-avx512f.c @@ -0,0 +1,244 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with + * this software. If not, see + * . + */ + +#include +#include +#include + +#include "argon2-core.h" +#include "argon2.h" +#include "private/common.h" + +#if defined(HAVE_AVX512FINTRIN_H) && defined(HAVE_AVX2INTRIN_H) && \ + defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# pragma GCC target("sse4.1") +# pragma GCC target("avx2") +# pragma GCC target("avx512f") +# endif + +# ifdef _MSC_VER +# include /* for _mm_set_epi64x */ +# endif +# include +# include +# include +# include +# include "private/sse2_64_32.h" + +# include "blamka-round-avx512f.h" + +static void +fill_block(__m512i *state, const uint8_t *ref_block, uint8_t *next_block) +{ + __m512i block_XY[ARGON2_512BIT_WORDS_IN_BLOCK]; + uint32_t i; + + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + block_XY[i] = state[i] = _mm512_xor_si512( + state[i], _mm512_loadu_si512((__m512i const *) (&ref_block[64 * i]))); + } + + for (i = 0; i < 2; ++i) { + BLAKE2_ROUND_1( + state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], state[8 * i + 3], + state[8 * i + 4], state[8 * i + 5], state[8 * i + 6], state[8 * i + 7]); + } + + for (i = 0; i < 2; ++i) { + BLAKE2_ROUND_2( + state[2 * 0 + i], state[2 * 1 + i], state[2 * 2 + i], state[2 * 3 + i], + state[2 * 4 + i], state[2 * 5 + i], state[2 * 6 + i], state[2 * 7 + i]); + } + + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + state[i] = _mm512_xor_si512(state[i], block_XY[i]); + _mm512_storeu_si512((__m512i *) (&next_block[64 * i]), state[i]); + } +} + +static void +fill_block_with_xor(__m512i *state, const uint8_t *ref_block, + uint8_t *next_block) +{ + __m512i block_XY[ARGON2_512BIT_WORDS_IN_BLOCK]; + uint32_t i; + + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + state[i] = _mm512_xor_si512( + state[i], _mm512_loadu_si512((__m512i const *) (&ref_block[64 * i]))); + block_XY[i] = _mm512_xor_si512( + state[i], _mm512_loadu_si512((__m512i const *) (&next_block[64 * i]))); + } + + for (i = 0; i < 2; ++i) { + BLAKE2_ROUND_1( + state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], state[8 * i + 3], + state[8 * i + 4], state[8 * i + 5], state[8 * i + 6], state[8 * i + 7]); + } + + for (i = 0; i < 2; ++i) { + BLAKE2_ROUND_2( + state[2 * 0 + i], state[2 * 1 + i], state[2 * 2 + i], state[2 * 3 + i], + state[2 * 4 + i], state[2 * 5 + i], state[2 * 6 + i], state[2 * 7 + i]); + } + + for (i = 0; i < ARGON2_512BIT_WORDS_IN_BLOCK; i++) { + state[i] = _mm512_xor_si512(state[i], block_XY[i]); + _mm512_storeu_si512((__m512i *) (&next_block[64 * i]), state[i]); + } +} + +static void +generate_addresses(const argon2_instance_t *instance, + const argon2_position_t *position, uint64_t *pseudo_rands) +{ + block address_block, input_block, tmp_block; + uint32_t i; + + init_block_value(&address_block, 0); + init_block_value(&input_block, 0); + + if (instance != NULL && position != NULL) { + input_block.v[0] = position->pass; + input_block.v[1] = position->lane; + input_block.v[2] = position->slice; + input_block.v[3] = instance->memory_blocks; + input_block.v[4] = instance->passes; + input_block.v[5] = instance->type; + + for (i = 0; i < instance->segment_length; ++i) { + if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { + /* Temporary zero-initialized blocks */ + __m512i zero_block[ARGON2_512BIT_WORDS_IN_BLOCK]; + __m512i zero2_block[ARGON2_512BIT_WORDS_IN_BLOCK]; + + memset(zero_block, 0, sizeof(zero_block)); + memset(zero2_block, 0, sizeof(zero2_block)); + init_block_value(&address_block, 0); + init_block_value(&tmp_block, 0); + /* Increasing index counter */ + input_block.v[6]++; + /* First iteration of G */ + fill_block_with_xor(zero_block, (uint8_t *) &input_block.v, + (uint8_t *) &tmp_block.v); + /* Second iteration of G */ + fill_block_with_xor(zero2_block, (uint8_t *) &tmp_block.v, + (uint8_t *) &address_block.v); + } + + pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; + } + } +} + +void +argon2_fill_segment_avx512f(const argon2_instance_t *instance, + argon2_position_t position) +{ + block *ref_block = NULL, *curr_block = NULL; + uint64_t pseudo_rand, ref_index, ref_lane; + uint32_t prev_offset, curr_offset; + uint32_t starting_index, i; + __m512i state[ARGON2_512BIT_WORDS_IN_BLOCK]; + int data_independent_addressing = 1; + + /* Pseudo-random values that determine the reference block position */ + uint64_t *pseudo_rands = NULL; + + if (instance == NULL) { + return; + } + + if (instance->type == Argon2_id && + (position.pass != 0 || position.slice >= ARGON2_SYNC_POINTS / 2)) { + data_independent_addressing = 0; + } + + pseudo_rands = instance->pseudo_rands; + + if (data_independent_addressing) { + generate_addresses(instance, &position, pseudo_rands); + } + + starting_index = 0; + + if ((0 == position.pass) && (0 == position.slice)) { + starting_index = 2; /* we have already generated the first two blocks */ + } + + /* Offset of the current block */ + curr_offset = position.lane * instance->lane_length + + position.slice * instance->segment_length + starting_index; + + if (0 == curr_offset % instance->lane_length) { + /* Last block in this lane */ + prev_offset = curr_offset + instance->lane_length - 1; + } else { + /* Previous block */ + prev_offset = curr_offset - 1; + } + + memcpy(state, ((instance->region->memory + prev_offset)->v), + ARGON2_BLOCK_SIZE); + + for (i = starting_index; i < instance->segment_length; + ++i, ++curr_offset, ++prev_offset) { + /*1.1 Rotating prev_offset if needed */ + if (curr_offset % instance->lane_length == 1) { + prev_offset = curr_offset - 1; + } + + /* 1.2 Computing the index of the reference block */ + /* 1.2.1 Taking pseudo-random value from the previous block */ + if (data_independent_addressing) { +#pragma warning(push) +#pragma warning(disable : 6385) + pseudo_rand = pseudo_rands[i]; +#pragma warning(pop) + } else { + pseudo_rand = instance->region->memory[prev_offset].v[0]; + } + + /* 1.2.2 Computing the lane of the reference block */ + ref_lane = ((pseudo_rand >> 32)) % instance->lanes; + + if ((position.pass == 0) && (position.slice == 0)) { + /* Can not reference other lanes yet */ + ref_lane = position.lane; + } + + /* 1.2.3 Computing the number of possible reference block within the + * lane. + */ + position.index = i; + ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, + ref_lane == position.lane); + + /* 2 Creating a new block */ + ref_block = instance->region->memory + + instance->lane_length * ref_lane + ref_index; + curr_block = instance->region->memory + curr_offset; + if (position.pass != 0) { + fill_block_with_xor(state, (uint8_t *) ref_block->v, + (uint8_t *) curr_block->v); + } else { + fill_block(state, (uint8_t *) ref_block->v, + (uint8_t *) curr_block->v); + } + } +} +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ref.c b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ref.c new file mode 100644 index 0000000..567895d --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ref.c @@ -0,0 +1,234 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with + * this software. If not, see + * . + */ + +#include +#include +#include + +#include "argon2-core.h" +#include "argon2.h" +#include "blamka-round-ref.h" +#include "private/common.h" + +static void +fill_block(const block *prev_block, const block *ref_block, block *next_block) +{ + block blockR, block_tmp; + unsigned i; + + copy_block(&blockR, ref_block); + xor_block(&blockR, prev_block); + copy_block(&block_tmp, &blockR); + /* Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block + Apply Blake2 on columns of 64-bit words: (0,1,...,15), then + (16,17,..31)... finally (112,113,...127) */ + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND_NOMSG( + blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2], + blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5], + blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8], + blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11], + blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14], + blockR.v[16 * i + 15]); + } + + /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then + (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */ + for (i = 0; i < 8; i++) { + BLAKE2_ROUND_NOMSG( + blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16], + blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33], + blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64], + blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81], + blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112], + blockR.v[2 * i + 113]); + } + + copy_block(next_block, &block_tmp); + xor_block(next_block, &blockR); +} + +static void +fill_block_with_xor(const block *prev_block, const block *ref_block, + block *next_block) +{ + block blockR, block_tmp; + unsigned i; + + copy_block(&blockR, ref_block); + xor_block(&blockR, prev_block); + copy_block(&block_tmp, &blockR); + xor_block(&block_tmp, + next_block); /* Saving the next block contents for XOR over */ + /* Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block + * + next_block */ + /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then + (16,17,..31)... finally (112,113,...127) */ + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND_NOMSG( + blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2], + blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5], + blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8], + blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11], + blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14], + blockR.v[16 * i + 15]); + } + + /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then + (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */ + for (i = 0; i < 8; i++) { + BLAKE2_ROUND_NOMSG( + blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16], + blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33], + blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64], + blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81], + blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112], + blockR.v[2 * i + 113]); + } + + copy_block(next_block, &block_tmp); + xor_block(next_block, &blockR); +} + +/* + * Generate pseudo-random values to reference blocks in the segment and puts + * them into the array + * @param instance Pointer to the current instance + * @param position Pointer to the current position + * @param pseudo_rands Pointer to the array of 64-bit values + * @pre pseudo_rands must point to @a instance->segment_length allocated values + */ +static void +generate_addresses(const argon2_instance_t *instance, + const argon2_position_t *position, uint64_t *pseudo_rands) +{ + block zero_block, input_block, address_block, tmp_block; + uint32_t i; + + init_block_value(&zero_block, 0); + init_block_value(&input_block, 0); + + if (instance != NULL && position != NULL) { + input_block.v[0] = position->pass; + input_block.v[1] = position->lane; + input_block.v[2] = position->slice; + input_block.v[3] = instance->memory_blocks; + input_block.v[4] = instance->passes; + input_block.v[5] = instance->type; + + for (i = 0; i < instance->segment_length; ++i) { + if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { + input_block.v[6]++; + init_block_value(&tmp_block, 0); + init_block_value(&address_block, 0); + fill_block_with_xor(&zero_block, &input_block, &tmp_block); + fill_block_with_xor(&zero_block, &tmp_block, &address_block); + } + + pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; + } + } +} + +void +argon2_fill_segment_ref(const argon2_instance_t *instance, + argon2_position_t position) +{ + block *ref_block = NULL, *curr_block = NULL; + /* Pseudo-random values that determine the reference block position */ + uint64_t *pseudo_rands = NULL; + uint64_t pseudo_rand, ref_index, ref_lane; + uint32_t prev_offset, curr_offset; + uint32_t starting_index; + uint32_t i; + int data_independent_addressing = 1; + + if (instance == NULL) { + return; + } + + if (instance->type == Argon2_id && + (position.pass != 0 || position.slice >= ARGON2_SYNC_POINTS / 2)) { + data_independent_addressing = 0; + } + + pseudo_rands = instance->pseudo_rands; + + if (data_independent_addressing) { + generate_addresses(instance, &position, pseudo_rands); + } + + starting_index = 0; + + if ((0 == position.pass) && (0 == position.slice)) { + starting_index = 2; /* we have already generated the first two blocks */ + } + + /* Offset of the current block */ + curr_offset = position.lane * instance->lane_length + + position.slice * instance->segment_length + starting_index; + + if (0 == curr_offset % instance->lane_length) { + /* Last block in this lane */ + prev_offset = curr_offset + instance->lane_length - 1; + } else { + /* Previous block */ + prev_offset = curr_offset - 1; + } + + for (i = starting_index; i < instance->segment_length; + ++i, ++curr_offset, ++prev_offset) { + /*1.1 Rotating prev_offset if needed */ + if (curr_offset % instance->lane_length == 1) { + prev_offset = curr_offset - 1; + } + + /* 1.2 Computing the index of the reference block */ + /* 1.2.1 Taking pseudo-random value from the previous block */ + if (data_independent_addressing) { +#pragma warning(push) +#pragma warning(disable : 6385) + pseudo_rand = pseudo_rands[i]; +#pragma warning(pop) + } else { + pseudo_rand = instance->region->memory[prev_offset].v[0]; + } + + /* 1.2.2 Computing the lane of the reference block */ + ref_lane = ((pseudo_rand >> 32)) % instance->lanes; + + if ((position.pass == 0) && (position.slice == 0)) { + /* Can not reference other lanes yet */ + ref_lane = position.lane; + } + + /* 1.2.3 Computing the number of possible reference block within the + * lane. + */ + position.index = i; + ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, + ref_lane == position.lane); + + /* 2 Creating a new block */ + ref_block = instance->region->memory + + instance->lane_length * ref_lane + ref_index; + curr_block = instance->region->memory + curr_offset; + if (position.pass != 0) { + fill_block_with_xor(instance->region->memory + prev_offset, + ref_block, curr_block); + } else { + fill_block(instance->region->memory + prev_offset, ref_block, + curr_block); + } + } +} diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ssse3.c b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ssse3.c new file mode 100644 index 0000000..fc85a47 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2-fill-block-ssse3.c @@ -0,0 +1,238 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with + * this software. If not, see + * . + */ + +#include +#include +#include + +#include "argon2-core.h" +#include "argon2.h" +#include "private/common.h" + +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# endif + +# ifdef _MSC_VER +# include /* for _mm_set_epi64x */ +# endif +# include +# include +# include "private/sse2_64_32.h" + +# include "blamka-round-ssse3.h" + +static void +fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) +{ + __m128i block_XY[ARGON2_OWORDS_IN_BLOCK]; + uint32_t i; + + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + block_XY[i] = state[i] = _mm_xor_si128( + state[i], _mm_loadu_si128((__m128i const *) (&ref_block[16 * i]))); + } + + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], + state[8 * i + 3], state[8 * i + 4], state[8 * i + 5], + state[8 * i + 6], state[8 * i + 7]); + } + + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i], + state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i], + state[8 * 6 + i], state[8 * 7 + i]); + } + + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + state[i] = _mm_xor_si128(state[i], block_XY[i]); + _mm_storeu_si128((__m128i *) (&next_block[16 * i]), state[i]); + } +} + +static void +fill_block_with_xor(__m128i *state, const uint8_t *ref_block, + uint8_t *next_block) +{ + __m128i block_XY[ARGON2_OWORDS_IN_BLOCK]; + uint32_t i; + + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + state[i] = _mm_xor_si128( + state[i], _mm_loadu_si128((__m128i const *) (&ref_block[16 * i]))); + block_XY[i] = _mm_xor_si128( + state[i], _mm_loadu_si128((__m128i const *) (&next_block[16 * i]))); + } + + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2], + state[8 * i + 3], state[8 * i + 4], state[8 * i + 5], + state[8 * i + 6], state[8 * i + 7]); + } + + for (i = 0; i < 8; ++i) { + BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i], + state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i], + state[8 * 6 + i], state[8 * 7 + i]); + } + + for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) { + state[i] = _mm_xor_si128(state[i], block_XY[i]); + _mm_storeu_si128((__m128i *) (&next_block[16 * i]), state[i]); + } +} + +static void +generate_addresses(const argon2_instance_t *instance, + const argon2_position_t *position, uint64_t *pseudo_rands) +{ + block address_block, input_block, tmp_block; + uint32_t i; + + init_block_value(&address_block, 0); + init_block_value(&input_block, 0); + + if (instance != NULL && position != NULL) { + input_block.v[0] = position->pass; + input_block.v[1] = position->lane; + input_block.v[2] = position->slice; + input_block.v[3] = instance->memory_blocks; + input_block.v[4] = instance->passes; + input_block.v[5] = instance->type; + + for (i = 0; i < instance->segment_length; ++i) { + if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) { + /* Temporary zero-initialized blocks */ + __m128i zero_block[ARGON2_OWORDS_IN_BLOCK]; + __m128i zero2_block[ARGON2_OWORDS_IN_BLOCK]; + + memset(zero_block, 0, sizeof(zero_block)); + memset(zero2_block, 0, sizeof(zero2_block)); + init_block_value(&address_block, 0); + init_block_value(&tmp_block, 0); + /* Increasing index counter */ + input_block.v[6]++; + /* First iteration of G */ + fill_block_with_xor(zero_block, (uint8_t *) &input_block.v, + (uint8_t *) &tmp_block.v); + /* Second iteration of G */ + fill_block_with_xor(zero2_block, (uint8_t *) &tmp_block.v, + (uint8_t *) &address_block.v); + } + + pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK]; + } + } +} + +void +argon2_fill_segment_ssse3(const argon2_instance_t *instance, + argon2_position_t position) +{ + block *ref_block = NULL, *curr_block = NULL; + uint64_t pseudo_rand, ref_index, ref_lane; + uint32_t prev_offset, curr_offset; + uint32_t starting_index, i; + __m128i state[ARGON2_OWORDS_IN_BLOCK]; + int data_independent_addressing = 1; + + /* Pseudo-random values that determine the reference block position */ + uint64_t *pseudo_rands = NULL; + + if (instance == NULL) { + return; + } + + if (instance->type == Argon2_id && + (position.pass != 0 || position.slice >= ARGON2_SYNC_POINTS / 2)) { + data_independent_addressing = 0; + } + + pseudo_rands = instance->pseudo_rands; + + if (data_independent_addressing) { + generate_addresses(instance, &position, pseudo_rands); + } + + starting_index = 0; + + if ((0 == position.pass) && (0 == position.slice)) { + starting_index = 2; /* we have already generated the first two blocks */ + } + + /* Offset of the current block */ + curr_offset = position.lane * instance->lane_length + + position.slice * instance->segment_length + starting_index; + + if (0 == curr_offset % instance->lane_length) { + /* Last block in this lane */ + prev_offset = curr_offset + instance->lane_length - 1; + } else { + /* Previous block */ + prev_offset = curr_offset - 1; + } + + memcpy(state, ((instance->region->memory + prev_offset)->v), + ARGON2_BLOCK_SIZE); + + for (i = starting_index; i < instance->segment_length; + ++i, ++curr_offset, ++prev_offset) { + /*1.1 Rotating prev_offset if needed */ + if (curr_offset % instance->lane_length == 1) { + prev_offset = curr_offset - 1; + } + + /* 1.2 Computing the index of the reference block */ + /* 1.2.1 Taking pseudo-random value from the previous block */ + if (data_independent_addressing) { +#pragma warning(push) +#pragma warning(disable : 6385) + pseudo_rand = pseudo_rands[i]; +#pragma warning(pop) + } else { + pseudo_rand = instance->region->memory[prev_offset].v[0]; + } + + /* 1.2.2 Computing the lane of the reference block */ + ref_lane = ((pseudo_rand >> 32)) % instance->lanes; + + if ((position.pass == 0) && (position.slice == 0)) { + /* Can not reference other lanes yet */ + ref_lane = position.lane; + } + + /* 1.2.3 Computing the number of possible reference block within the + * lane. + */ + position.index = i; + ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF, + ref_lane == position.lane); + + /* 2 Creating a new block */ + ref_block = instance->region->memory + + instance->lane_length * ref_lane + ref_index; + curr_block = instance->region->memory + curr_offset; + if (position.pass != 0) { + fill_block_with_xor(state, (uint8_t *) ref_block->v, + (uint8_t *) curr_block->v); + } else { + fill_block(state, (uint8_t *) ref_block->v, + (uint8_t *) curr_block->v); + } + } +} +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2.c b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2.c new file mode 100644 index 0000000..c6277fc --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2.c @@ -0,0 +1,278 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with + * this software. If not, see + * . + */ + +#include +#include +#include +#include +#include + +#include "utils.h" + +#include "argon2-core.h" +#include "argon2-encoding.h" +#include "argon2.h" + +int +argon2_ctx(argon2_context *context, argon2_type type) +{ + /* 1. Validate all inputs */ + int result = argon2_validate_inputs(context); + uint32_t memory_blocks, segment_length; + uint32_t pass; + argon2_instance_t instance; + + if (ARGON2_OK != result) { + return result; + } + + if (type != Argon2_id && type != Argon2_i) { + return ARGON2_INCORRECT_TYPE; + } + + /* 2. Align memory size */ + /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */ + memory_blocks = context->m_cost; + + if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) { + memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes; + } + + segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS); + /* Ensure that all segments have equal length */ + memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS); + + instance.region = NULL; + instance.passes = context->t_cost; + instance.current_pass = ~ 0U; + instance.memory_blocks = memory_blocks; + instance.segment_length = segment_length; + instance.lane_length = segment_length * ARGON2_SYNC_POINTS; + instance.lanes = context->lanes; + instance.threads = context->threads; + instance.type = type; + + /* 3. Initialization: Hashing inputs, allocating memory, filling first + * blocks + */ + result = argon2_initialize(&instance, context); + + if (ARGON2_OK != result) { + return result; + } + + /* 4. Filling memory */ + for (pass = 0; pass < instance.passes; pass++) { + argon2_fill_memory_blocks(&instance, pass); + } + + /* 5. Finalization */ + argon2_finalize(context, &instance); + + return ARGON2_OK; +} + +int +argon2_hash(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, const size_t pwdlen, + const void *salt, const size_t saltlen, void *hash, + const size_t hashlen, char *encoded, const size_t encodedlen, + argon2_type type) +{ + argon2_context context; + int result; + uint8_t *out; + + if (pwdlen > ARGON2_MAX_PWD_LENGTH) { + return ARGON2_PWD_TOO_LONG; + } + + if (hashlen > ARGON2_MAX_OUTLEN) { + return ARGON2_OUTPUT_TOO_LONG; + } + + if (saltlen > ARGON2_MAX_SALT_LENGTH) { + return ARGON2_SALT_TOO_LONG; + } + + out = (uint8_t *) malloc(hashlen); + if (!out) { + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + context.out = (uint8_t *) out; + context.outlen = (uint32_t) hashlen; + context.pwd = (uint8_t *) pwd; + context.pwdlen = (uint32_t) pwdlen; + context.salt = (uint8_t *) salt; + context.saltlen = (uint32_t) saltlen; + context.secret = NULL; + context.secretlen = 0; + context.ad = NULL; + context.adlen = 0; + context.t_cost = t_cost; + context.m_cost = m_cost; + context.lanes = parallelism; + context.threads = parallelism; + context.flags = ARGON2_DEFAULT_FLAGS; + + result = argon2_ctx(&context, type); + + if (result != ARGON2_OK) { + sodium_memzero(out, hashlen); + free(out); + return result; + } + + /* if encoding requested, write it */ + if (encoded && encodedlen) { + if (argon2_encode_string(encoded, encodedlen, + &context, type) != ARGON2_OK) { + sodium_memzero(out, hashlen); + sodium_memzero(encoded, encodedlen); + free(out); + return ARGON2_ENCODING_FAIL; + } + } + + /* if raw hash requested, write it */ + if (hash) { + memcpy(hash, out, hashlen); + } + + sodium_memzero(out, hashlen); + free(out); + + return ARGON2_OK; +} + +int +argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, char *encoded, + const size_t encodedlen) +{ + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + NULL, hashlen, encoded, encodedlen, Argon2_i); +} + +int +argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, const size_t saltlen, + void *hash, const size_t hashlen) +{ + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + hash, hashlen, NULL, 0, Argon2_i); +} + +int +argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, char *encoded, + const size_t encodedlen) +{ + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + NULL, hashlen, encoded, encodedlen, Argon2_id); +} + +int +argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, const size_t saltlen, + void *hash, const size_t hashlen) +{ + return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen, + hash, hashlen, NULL, 0, Argon2_id); +} + +int +argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, + argon2_type type) +{ + argon2_context ctx; + uint8_t *out; + int decode_result; + int ret; + size_t encoded_len; + + memset(&ctx, 0, sizeof ctx); + + ctx.pwd = NULL; + ctx.pwdlen = 0; + ctx.secret = NULL; + ctx.secretlen = 0; + + /* max values, to be updated in argon2_decode_string */ + encoded_len = strlen(encoded); + if (encoded_len > UINT32_MAX) { + return ARGON2_DECODING_LENGTH_FAIL; + } + ctx.adlen = (uint32_t) encoded_len; + ctx.saltlen = (uint32_t) encoded_len; + ctx.outlen = (uint32_t) encoded_len; + + ctx.ad = (uint8_t *) malloc(ctx.adlen); + ctx.salt = (uint8_t *) malloc(ctx.saltlen); + ctx.out = (uint8_t *) malloc(ctx.outlen); + if (!ctx.out || !ctx.salt || !ctx.ad) { + free(ctx.ad); + free(ctx.salt); + free(ctx.out); + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + out = (uint8_t *) malloc(ctx.outlen); + if (!out) { + free(ctx.ad); + free(ctx.salt); + free(ctx.out); + return ARGON2_MEMORY_ALLOCATION_ERROR; + } + + decode_result = argon2_decode_string(&ctx, encoded, type); + if (decode_result != ARGON2_OK) { + free(ctx.ad); + free(ctx.salt); + free(ctx.out); + free(out); + return decode_result; + } + + ret = argon2_hash(ctx.t_cost, ctx.m_cost, ctx.threads, pwd, pwdlen, + ctx.salt, ctx.saltlen, out, ctx.outlen, NULL, 0, type); + + free(ctx.ad); + free(ctx.salt); + + if (ret != ARGON2_OK || sodium_memcmp(out, ctx.out, ctx.outlen) != 0) { + ret = ARGON2_VERIFY_MISMATCH; + } + free(out); + free(ctx.out); + + return ret; +} + +int +argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) +{ + return argon2_verify(encoded, pwd, pwdlen, Argon2_i); +} + +int +argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) +{ + return argon2_verify(encoded, pwd, pwdlen, Argon2_id); +} diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2.h b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2.h new file mode 100644 index 0000000..3b05daa --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/argon2.h @@ -0,0 +1,305 @@ +/* + * Argon2 source code package + * + * Written by Daniel Dinu and Dmitry Khovratovich, 2015 + * + * This work is licensed under a Creative Commons CC0 1.0 License/Waiver. + * + * You should have received a copy of the CC0 Public Domain Dedication along + * with this software. If not, see + * . + */ +#ifndef argon2_H +#define argon2_H + +#include +#include +#include + +/* + * Argon2 input parameter restrictions + */ + +/* Minimum and maximum number of lanes (degree of parallelism) */ +#define ARGON2_MIN_LANES UINT32_C(1) +#define ARGON2_MAX_LANES UINT32_C(0xFFFFFF) + +/* Minimum and maximum number of threads */ +#define ARGON2_MIN_THREADS UINT32_C(1) +#define ARGON2_MAX_THREADS UINT32_C(0xFFFFFF) + +/* Number of synchronization points between lanes per pass */ +#define ARGON2_SYNC_POINTS UINT32_C(4) + +/* Minimum and maximum digest size in bytes */ +#define ARGON2_MIN_OUTLEN UINT32_C(16) +#define ARGON2_MAX_OUTLEN UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum number of memory blocks (each of BLOCK_SIZE bytes) */ +#define ARGON2_MIN_MEMORY (2 * ARGON2_SYNC_POINTS) /* 2 blocks per slice */ + +#define ARGON2_MIN(a, b) ((a) < (b) ? (a) : (b)) +/* Max memory size is half the addressing space, topping at 2^32 blocks (4 TB) + */ +#define ARGON2_MAX_MEMORY_BITS \ + ARGON2_MIN(UINT32_C(32), (sizeof(void *) * CHAR_BIT - 10 - 1)) +#define ARGON2_MAX_MEMORY \ + ARGON2_MIN(UINT32_C(0xFFFFFFFF), UINT64_C(1) << ARGON2_MAX_MEMORY_BITS) + +/* Minimum and maximum number of passes */ +#define ARGON2_MIN_TIME UINT32_C(1) +#define ARGON2_MAX_TIME UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum password length in bytes */ +#define ARGON2_MIN_PWD_LENGTH UINT32_C(0) +#define ARGON2_MAX_PWD_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum associated data length in bytes */ +#define ARGON2_MIN_AD_LENGTH UINT32_C(0) +#define ARGON2_MAX_AD_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum salt length in bytes */ +#define ARGON2_MIN_SALT_LENGTH UINT32_C(8) +#define ARGON2_MAX_SALT_LENGTH UINT32_C(0xFFFFFFFF) + +/* Minimum and maximum key length in bytes */ +#define ARGON2_MIN_SECRET UINT32_C(0) +#define ARGON2_MAX_SECRET UINT32_C(0xFFFFFFFF) + +#define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0) +#define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1) +#define ARGON2_FLAG_CLEAR_MEMORY (UINT32_C(1) << 2) +#define ARGON2_DEFAULT_FLAGS (UINT32_C(0)) + +/* Error codes */ +typedef enum Argon2_ErrorCodes { + ARGON2_OK = 0, + + ARGON2_OUTPUT_PTR_NULL = -1, + + ARGON2_OUTPUT_TOO_SHORT = -2, + ARGON2_OUTPUT_TOO_LONG = -3, + + ARGON2_PWD_TOO_SHORT = -4, + ARGON2_PWD_TOO_LONG = -5, + + ARGON2_SALT_TOO_SHORT = -6, + ARGON2_SALT_TOO_LONG = -7, + + ARGON2_AD_TOO_SHORT = -8, + ARGON2_AD_TOO_LONG = -9, + + ARGON2_SECRET_TOO_SHORT = -10, + ARGON2_SECRET_TOO_LONG = -11, + + ARGON2_TIME_TOO_SMALL = -12, + ARGON2_TIME_TOO_LARGE = -13, + + ARGON2_MEMORY_TOO_LITTLE = -14, + ARGON2_MEMORY_TOO_MUCH = -15, + + ARGON2_LANES_TOO_FEW = -16, + ARGON2_LANES_TOO_MANY = -17, + + ARGON2_PWD_PTR_MISMATCH = -18, /* NULL ptr with non-zero length */ + ARGON2_SALT_PTR_MISMATCH = -19, /* NULL ptr with non-zero length */ + ARGON2_SECRET_PTR_MISMATCH = -20, /* NULL ptr with non-zero length */ + ARGON2_AD_PTR_MISMATCH = -21, /* NULL ptr with non-zero length */ + + ARGON2_MEMORY_ALLOCATION_ERROR = -22, + + ARGON2_FREE_MEMORY_CBK_NULL = -23, + ARGON2_ALLOCATE_MEMORY_CBK_NULL = -24, + + ARGON2_INCORRECT_PARAMETER = -25, + ARGON2_INCORRECT_TYPE = -26, + + ARGON2_OUT_PTR_MISMATCH = -27, + + ARGON2_THREADS_TOO_FEW = -28, + ARGON2_THREADS_TOO_MANY = -29, + + ARGON2_MISSING_ARGS = -30, + + ARGON2_ENCODING_FAIL = -31, + + ARGON2_DECODING_FAIL = -32, + + ARGON2_THREAD_FAIL = -33, + + ARGON2_DECODING_LENGTH_FAIL = -34, + + ARGON2_VERIFY_MISMATCH = -35 +} argon2_error_codes; + +/* Argon2 external data structures */ + +/* + * Context: structure to hold Argon2 inputs: + * output array and its length, + * password and its length, + * salt and its length, + * secret and its length, + * associated data and its length, + * number of passes, amount of used memory (in KBytes, can be rounded up a bit) + * number of parallel threads that will be run. + * All the parameters above affect the output hash value. + * Additionally, two function pointers can be provided to allocate and + * deallocate the memory (if NULL, memory will be allocated internally). + * Also, three flags indicate whether to erase password, secret as soon as they + * are pre-hashed (and thus not needed anymore), and the entire memory + ***** + * Simplest situation: you have output array out[8], password is stored in + * pwd[32], salt is stored in salt[16], you do not have keys nor associated + *data. + * You need to spend 1 GB of RAM and you run 5 passes of Argon2 with 4 parallel + *lanes. + * You want to erase the password, but you're OK with last pass not being + *erased. + * You want to use the default memory allocator. + * Then you initialize: + * Argon2_Context(out,8,pwd,32,salt,16,NULL,0,NULL,0,5,1<<20,4,4,NULL,NULL,true,false,false,false). + */ +typedef struct Argon2_Context { + uint8_t *out; /* output array */ + uint32_t outlen; /* digest length */ + + uint8_t *pwd; /* password array */ + uint32_t pwdlen; /* password length */ + + uint8_t *salt; /* salt array */ + uint32_t saltlen; /* salt length */ + + uint8_t *secret; /* key array */ + uint32_t secretlen; /* key length */ + + uint8_t *ad; /* associated data array */ + uint32_t adlen; /* associated data length */ + + uint32_t t_cost; /* number of passes */ + uint32_t m_cost; /* amount of memory requested (KB) */ + uint32_t lanes; /* number of lanes */ + uint32_t threads; /* maximum number of threads */ + + uint32_t flags; /* array of bool options */ +} argon2_context; + +/* Argon2 primitive type */ +typedef enum Argon2_type { Argon2_i = 1, Argon2_id = 2 } argon2_type; + +/* + * Function that performs memory-hard hashing with certain degree of parallelism + * @param context Pointer to the Argon2 internal structure + * @return Error code if smth is wrong, ARGON2_OK otherwise + */ +int argon2_ctx(argon2_context *context, argon2_type type); + +/** + * Hashes a password with Argon2i, producing an encoded hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hashlen Desired length of the hash in bytes + * @param encoded Buffer where to write the encoded hash + * @param encodedlen Size of the buffer (thus max size of the encoded hash) + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, + char *encoded, const size_t encodedlen); + +/** + * Hashes a password with Argon2id, producing an encoded hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hashlen Desired length of the hash in bytes + * @param encoded Buffer where to write the encoded hash + * @param encodedlen Size of the buffer (thus max size of the encoded hash) + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +int argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, const size_t hashlen, + char *encoded, const size_t encodedlen); + +/** + * Hashes a password with Argon2i, producing a raw hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hash Buffer where to write the raw hash + * @param hashlen Desired length of the hash in bytes + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, const size_t hashlen); + +/** + * Hashes a password with Argon2id, producing a raw hash + * @param t_cost Number of iterations + * @param m_cost Sets memory usage to m_cost kibibytes + * @param parallelism Number of threads and compute lanes + * @param pwd Pointer to password + * @param pwdlen Password size in bytes + * @param salt Pointer to salt + * @param saltlen Salt size in bytes + * @param hash Buffer where to write the raw hash + * @param hashlen Desired length of the hash in bytes + * @pre Different parallelism levels will give different results + * @pre Returns ARGON2_OK if successful + */ +int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, + const size_t saltlen, void *hash, const size_t hashlen); + +/* generic function underlying the above ones */ +int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, + const uint32_t parallelism, const void *pwd, + const size_t pwdlen, const void *salt, const size_t saltlen, + void *hash, const size_t hashlen, char *encoded, + const size_t encodedlen, argon2_type type); + +/** + * Verifies a password against an encoded string + * Encoded string is restricted as in argon2_validate_inputs() + * @param encoded String encoding parameters, salt, hash + * @param pwd Pointer to password + * @pre Returns ARGON2_OK if successful + */ +int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen); + +/** + * Verifies a password against an encoded string + * Encoded string is restricted as in argon2_validate_inputs() + * @param encoded String encoding parameters, salt, hash + * @param pwd Pointer to password + * @pre Returns ARGON2_OK if successful + */ +int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen); + +/* generic function underlying the above ones */ +int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, + argon2_type type); +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blake2b-long.c b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blake2b-long.c new file mode 100644 index 0000000..f0364ac --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blake2b-long.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include + +#include "crypto_generichash_blake2b.h" +#include "private/common.h" +#include "utils.h" + +#include "blake2b-long.h" + +int +blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) +{ + uint8_t *out = (uint8_t *) pout; + crypto_generichash_blake2b_state blake_state; + uint8_t outlen_bytes[4 /* sizeof(uint32_t) */] = { 0 }; + int ret = -1; + + if (outlen > UINT32_MAX) { + goto fail; /* LCOV_EXCL_LINE */ + } + + /* Ensure little-endian byte order! */ + STORE32_LE(outlen_bytes, (uint32_t) outlen); + +#define TRY(statement) \ + do { \ + ret = statement; \ + if (ret < 0) { \ + goto fail; \ + } \ + } while ((void) 0, 0) + + if (outlen <= crypto_generichash_blake2b_BYTES_MAX) { + TRY(crypto_generichash_blake2b_init(&blake_state, NULL, 0U, outlen)); + TRY(crypto_generichash_blake2b_update(&blake_state, outlen_bytes, + sizeof(outlen_bytes))); + TRY(crypto_generichash_blake2b_update( + &blake_state, (const unsigned char *) in, inlen)); + TRY(crypto_generichash_blake2b_final(&blake_state, out, outlen)); + } else { + uint32_t toproduce; + uint8_t out_buffer[crypto_generichash_blake2b_BYTES_MAX]; + uint8_t in_buffer[crypto_generichash_blake2b_BYTES_MAX]; + TRY(crypto_generichash_blake2b_init( + &blake_state, NULL, 0U, crypto_generichash_blake2b_BYTES_MAX)); + TRY(crypto_generichash_blake2b_update(&blake_state, outlen_bytes, + sizeof(outlen_bytes))); + TRY(crypto_generichash_blake2b_update( + &blake_state, (const unsigned char *) in, inlen)); + TRY(crypto_generichash_blake2b_final( + &blake_state, out_buffer, crypto_generichash_blake2b_BYTES_MAX)); + memcpy(out, out_buffer, crypto_generichash_blake2b_BYTES_MAX / 2); + out += crypto_generichash_blake2b_BYTES_MAX / 2; + toproduce = + (uint32_t) outlen - crypto_generichash_blake2b_BYTES_MAX / 2; + + while (toproduce > crypto_generichash_blake2b_BYTES_MAX) { + memcpy(in_buffer, out_buffer, crypto_generichash_blake2b_BYTES_MAX); + TRY(crypto_generichash_blake2b( + out_buffer, crypto_generichash_blake2b_BYTES_MAX, in_buffer, + crypto_generichash_blake2b_BYTES_MAX, NULL, 0U)); + memcpy(out, out_buffer, crypto_generichash_blake2b_BYTES_MAX / 2); + out += crypto_generichash_blake2b_BYTES_MAX / 2; + toproduce -= crypto_generichash_blake2b_BYTES_MAX / 2; + } + + memcpy(in_buffer, out_buffer, crypto_generichash_blake2b_BYTES_MAX); + TRY(crypto_generichash_blake2b(out_buffer, toproduce, in_buffer, + crypto_generichash_blake2b_BYTES_MAX, + NULL, 0U)); + memcpy(out, out_buffer, toproduce); + } +fail: + sodium_memzero(&blake_state, sizeof(blake_state)); + return ret; +#undef TRY +} diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blake2b-long.h b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blake2b-long.h new file mode 100644 index 0000000..3d6d775 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blake2b-long.h @@ -0,0 +1,8 @@ +#ifndef blake2b_long_H +#define blake2b_long_H + +#include + +int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen); + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blamka-round-avx2.h b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blamka-round-avx2.h new file mode 100644 index 0000000..f3dfa0f --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blamka-round-avx2.h @@ -0,0 +1,150 @@ +#ifndef blamka_round_avx2_H +#define blamka_round_avx2_H + +#include "private/common.h" +#include "private/sse2_64_32.h" + +#define rotr32(x) _mm256_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1)) +#define rotr24(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10, 3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)) +#define rotr16(x) _mm256_shuffle_epi8(x, _mm256_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9, 2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9)) +#define rotr63(x) _mm256_xor_si256(_mm256_srli_epi64((x), 63), _mm256_add_epi64((x), (x))) + +#define G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i ml = _mm256_mul_epu32(A0, B0); \ + ml = _mm256_add_epi64(ml, ml); \ + A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \ + D0 = _mm256_xor_si256(D0, A0); \ + D0 = rotr32(D0); \ + \ + ml = _mm256_mul_epu32(C0, D0); \ + ml = _mm256_add_epi64(ml, ml); \ + C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \ + \ + B0 = _mm256_xor_si256(B0, C0); \ + B0 = rotr24(B0); \ + \ + ml = _mm256_mul_epu32(A1, B1); \ + ml = _mm256_add_epi64(ml, ml); \ + A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \ + D1 = _mm256_xor_si256(D1, A1); \ + D1 = rotr32(D1); \ + \ + ml = _mm256_mul_epu32(C1, D1); \ + ml = _mm256_add_epi64(ml, ml); \ + C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \ + \ + B1 = _mm256_xor_si256(B1, C1); \ + B1 = rotr24(B1); \ + } while((void)0, 0); + +#define G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i ml = _mm256_mul_epu32(A0, B0); \ + ml = _mm256_add_epi64(ml, ml); \ + A0 = _mm256_add_epi64(A0, _mm256_add_epi64(B0, ml)); \ + D0 = _mm256_xor_si256(D0, A0); \ + D0 = rotr16(D0); \ + \ + ml = _mm256_mul_epu32(C0, D0); \ + ml = _mm256_add_epi64(ml, ml); \ + C0 = _mm256_add_epi64(C0, _mm256_add_epi64(D0, ml)); \ + B0 = _mm256_xor_si256(B0, C0); \ + B0 = rotr63(B0); \ + \ + ml = _mm256_mul_epu32(A1, B1); \ + ml = _mm256_add_epi64(ml, ml); \ + A1 = _mm256_add_epi64(A1, _mm256_add_epi64(B1, ml)); \ + D1 = _mm256_xor_si256(D1, A1); \ + D1 = rotr16(D1); \ + \ + ml = _mm256_mul_epu32(C1, D1); \ + ml = _mm256_add_epi64(ml, ml); \ + C1 = _mm256_add_epi64(C1, _mm256_add_epi64(D1, ml)); \ + B1 = _mm256_xor_si256(B1, C1); \ + B1 = rotr63(B1); \ + } while((void)0, 0); + +#define DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \ + C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \ + \ + B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \ + C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ + D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \ + } while((void)0, 0); + +#define DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \ + __m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \ + B1 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + B0 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + \ + tmp1 = C0; \ + C0 = C1; \ + C1 = tmp1; \ + \ + tmp1 = _mm256_blend_epi32(D0, D1, 0xCC); \ + tmp2 = _mm256_blend_epi32(D0, D1, 0x33); \ + D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + } while(0); + +#define UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm256_permute4x64_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \ + C0 = _mm256_permute4x64_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + D0 = _mm256_permute4x64_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \ + \ + B1 = _mm256_permute4x64_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \ + C1 = _mm256_permute4x64_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ + D1 = _mm256_permute4x64_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \ + } while((void)0, 0); + +#define UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + __m256i tmp1 = _mm256_blend_epi32(B0, B1, 0xCC); \ + __m256i tmp2 = _mm256_blend_epi32(B0, B1, 0x33); \ + B0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + B1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + \ + tmp1 = C0; \ + C0 = C1; \ + C1 = tmp1; \ + \ + tmp1 = _mm256_blend_epi32(D0, D1, 0x33); \ + tmp2 = _mm256_blend_epi32(D0, D1, 0xCC); \ + D0 = _mm256_permute4x64_epi64(tmp1, _MM_SHUFFLE(2,3,0,1)); \ + D1 = _mm256_permute4x64_epi64(tmp2, _MM_SHUFFLE(2,3,0,1)); \ + } while((void)0, 0); + +#define BLAKE2_ROUND_1(A0, A1, B0, B1, C0, C1, D0, D1) \ + do{ \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + DIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + UNDIAGONALIZE_1(A0, B0, C0, D0, A1, B1, C1, D1) \ + } while((void)0, 0); + +#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do{ \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + DIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + G1_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + G2_AVX2(A0, A1, B0, B1, C0, C1, D0, D1) \ + \ + UNDIAGONALIZE_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + } while((void)0, 0); + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blamka-round-avx512f.h b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blamka-round-avx512f.h new file mode 100644 index 0000000..9a82240 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blamka-round-avx512f.h @@ -0,0 +1,145 @@ +#ifndef blamka_round_avx512f_H +#define blamka_round_avx512f_H + +#include "private/common.h" +#include "private/sse2_64_32.h" + +#define ror64(x, n) _mm512_ror_epi64((x), (n)) + +static inline __m512i +muladd(__m512i x, __m512i y) +{ + __m512i z = _mm512_mul_epu32(x, y); + + return _mm512_add_epi64(_mm512_add_epi64(x, y), _mm512_add_epi64(z, z)); +} + +#define G1_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = muladd(A0, B0); \ + A1 = muladd(A1, B1); \ + \ + D0 = _mm512_xor_si512(D0, A0); \ + D1 = _mm512_xor_si512(D1, A1); \ + \ + D0 = ror64(D0, 32); \ + D1 = ror64(D1, 32); \ + \ + C0 = muladd(C0, D0); \ + C1 = muladd(C1, D1); \ + \ + B0 = _mm512_xor_si512(B0, C0); \ + B1 = _mm512_xor_si512(B1, C1); \ + \ + B0 = ror64(B0, 24); \ + B1 = ror64(B1, 24); \ + } while ((void)0, 0) + +#define G2_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = muladd(A0, B0); \ + A1 = muladd(A1, B1); \ + \ + D0 = _mm512_xor_si512(D0, A0); \ + D1 = _mm512_xor_si512(D1, A1); \ + \ + D0 = ror64(D0, 16); \ + D1 = ror64(D1, 16); \ + \ + C0 = muladd(C0, D0); \ + C1 = muladd(C1, D1); \ + \ + B0 = _mm512_xor_si512(B0, C0); \ + B1 = _mm512_xor_si512(B1, C1); \ + \ + B0 = ror64(B0, 63); \ + B1 = ror64(B1, 63); \ + } while ((void)0, 0) + +#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(0, 3, 2, 1)); \ + B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(0, 3, 2, 1)); \ + \ + C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ + \ + D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(2, 1, 0, 3)); \ + D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(2, 1, 0, 3)); \ + } while ((void)0, 0) + +#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + B0 = _mm512_permutex_epi64(B0, _MM_SHUFFLE(2, 1, 0, 3)); \ + B1 = _mm512_permutex_epi64(B1, _MM_SHUFFLE(2, 1, 0, 3)); \ + \ + C0 = _mm512_permutex_epi64(C0, _MM_SHUFFLE(1, 0, 3, 2)); \ + C1 = _mm512_permutex_epi64(C1, _MM_SHUFFLE(1, 0, 3, 2)); \ + \ + D0 = _mm512_permutex_epi64(D0, _MM_SHUFFLE(0, 3, 2, 1)); \ + D1 = _mm512_permutex_epi64(D1, _MM_SHUFFLE(0, 3, 2, 1)); \ + } while ((void)0, 0) + +#define BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + G1_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + G1_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2_AVX512F(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + } while ((void)0, 0) + +#define SWAP_HALVES(A0, A1) \ + do { \ + __m512i t0, t1; \ + t0 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(1, 0, 1, 0)); \ + t1 = _mm512_shuffle_i64x2(A0, A1, _MM_SHUFFLE(3, 2, 3, 2)); \ + A0 = t0; \ + A1 = t1; \ + } while((void)0, 0) + +#define SWAP_QUARTERS(A0, A1) \ + do { \ + SWAP_HALVES(A0, A1); \ + A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \ + A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \ + } while((void)0, 0) + +#define UNSWAP_QUARTERS(A0, A1) \ + do { \ + A0 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A0); \ + A1 = _mm512_permutexvar_epi64(_mm512_setr_epi64(0, 1, 4, 5, 2, 3, 6, 7), A1); \ + SWAP_HALVES(A0, A1); \ + } while((void)0, 0) + +#define BLAKE2_ROUND_1(A0, C0, B0, D0, A1, C1, B1, D1) \ + do { \ + SWAP_HALVES(A0, B0); \ + SWAP_HALVES(C0, D0); \ + SWAP_HALVES(A1, B1); \ + SWAP_HALVES(C1, D1); \ + BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \ + SWAP_HALVES(A0, B0); \ + SWAP_HALVES(C0, D0); \ + SWAP_HALVES(A1, B1); \ + SWAP_HALVES(C1, D1); \ + } while ((void)0, 0) + +#define BLAKE2_ROUND_2(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + SWAP_QUARTERS(A0, A1); \ + SWAP_QUARTERS(B0, B1); \ + SWAP_QUARTERS(C0, C1); \ + SWAP_QUARTERS(D0, D1); \ + BLAKE2_ROUND(A0, B0, C0, D0, A1, B1, C1, D1); \ + UNSWAP_QUARTERS(A0, A1); \ + UNSWAP_QUARTERS(B0, B1); \ + UNSWAP_QUARTERS(C0, C1); \ + UNSWAP_QUARTERS(D0, D1); \ + } while ((void)0, 0) + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blamka-round-ref.h b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blamka-round-ref.h new file mode 100644 index 0000000..7a2c6eb --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blamka-round-ref.h @@ -0,0 +1,40 @@ +#ifndef blamka_round_ref_H +#define blamka_round_ref_H + +#include "private/common.h" + +/*designed by the Lyra PHC team */ +static inline uint64_t +fBlaMka(uint64_t x, uint64_t y) +{ + const uint64_t m = UINT64_C(0xFFFFFFFF); + const uint64_t xy = (x & m) * (y & m); + return x + y + 2 * xy; +} + +#define G(a, b, c, d) \ + do { \ + a = fBlaMka(a, b); \ + d = ROTR64(d ^ a, 32); \ + c = fBlaMka(c, d); \ + b = ROTR64(b ^ c, 24); \ + a = fBlaMka(a, b); \ + d = ROTR64(d ^ a, 16); \ + c = fBlaMka(c, d); \ + b = ROTR64(b ^ c, 63); \ + } while ((void) 0, 0) + +#define BLAKE2_ROUND_NOMSG(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, \ + v12, v13, v14, v15) \ + do { \ + G(v0, v4, v8, v12); \ + G(v1, v5, v9, v13); \ + G(v2, v6, v10, v14); \ + G(v3, v7, v11, v15); \ + G(v0, v5, v10, v15); \ + G(v1, v6, v11, v12); \ + G(v2, v7, v8, v13); \ + G(v3, v4, v9, v14); \ + } while ((void) 0, 0) + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blamka-round-ssse3.h b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blamka-round-ssse3.h new file mode 100644 index 0000000..98a47b9 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/blamka-round-ssse3.h @@ -0,0 +1,120 @@ +#ifndef blamka_round_ssse3_H +#define blamka_round_ssse3_H + +#include "private/common.h" +#include "private/sse2_64_32.h" + +#define r16 \ + (_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9)) +#define r24 \ + (_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)) +#define _mm_roti_epi64(x, c) \ + (-(c) == 32) \ + ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \ + : (-(c) == 24) \ + ? _mm_shuffle_epi8((x), r24) \ + : (-(c) == 16) \ + ? _mm_shuffle_epi8((x), r16) \ + : (-(c) == 63) \ + ? _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_add_epi64((x), (x))) \ + : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ + _mm_slli_epi64((x), 64 - (-(c)))) + +static inline __m128i +fBlaMka(__m128i x, __m128i y) +{ + const __m128i z = _mm_mul_epu32(x, y); + return _mm_add_epi64(_mm_add_epi64(x, y), _mm_add_epi64(z, z)); +} + +#define G1(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = fBlaMka(A0, B0); \ + A1 = fBlaMka(A1, B1); \ + \ + D0 = _mm_xor_si128(D0, A0); \ + D1 = _mm_xor_si128(D1, A1); \ + \ + D0 = _mm_roti_epi64(D0, -32); \ + D1 = _mm_roti_epi64(D1, -32); \ + \ + C0 = fBlaMka(C0, D0); \ + C1 = fBlaMka(C1, D1); \ + \ + B0 = _mm_xor_si128(B0, C0); \ + B1 = _mm_xor_si128(B1, C1); \ + \ + B0 = _mm_roti_epi64(B0, -24); \ + B1 = _mm_roti_epi64(B1, -24); \ + } while ((void) 0, 0) + +#define G2(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + A0 = fBlaMka(A0, B0); \ + A1 = fBlaMka(A1, B1); \ + \ + D0 = _mm_xor_si128(D0, A0); \ + D1 = _mm_xor_si128(D1, A1); \ + \ + D0 = _mm_roti_epi64(D0, -16); \ + D1 = _mm_roti_epi64(D1, -16); \ + \ + C0 = fBlaMka(C0, D0); \ + C1 = fBlaMka(C1, D1); \ + \ + B0 = _mm_xor_si128(B0, C0); \ + B1 = _mm_xor_si128(B1, C1); \ + \ + B0 = _mm_roti_epi64(B0, -63); \ + B1 = _mm_roti_epi64(B1, -63); \ + } while ((void) 0, 0) + +#define DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0 = _mm_alignr_epi8(B1, B0, 8); \ + __m128i t1 = _mm_alignr_epi8(B0, B1, 8); \ + B0 = t0; \ + B1 = t1; \ + \ + t0 = C0; \ + C0 = C1; \ + C1 = t0; \ + \ + t0 = _mm_alignr_epi8(D1, D0, 8); \ + t1 = _mm_alignr_epi8(D0, D1, 8); \ + D0 = t1; \ + D1 = t0; \ + } while ((void) 0, 0) + +#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \ + do { \ + __m128i t0 = _mm_alignr_epi8(B0, B1, 8); \ + __m128i t1 = _mm_alignr_epi8(B1, B0, 8); \ + B0 = t0; \ + B1 = t1; \ + \ + t0 = C0; \ + C0 = C1; \ + C1 = t0; \ + \ + t0 = _mm_alignr_epi8(D0, D1, 8); \ + t1 = _mm_alignr_epi8(D1, D0, 8); \ + D0 = t1; \ + D1 = t0; \ + } while ((void) 0, 0) + +#define BLAKE2_ROUND(A0, A1, B0, B1, C0, C1, D0, D1) \ + do { \ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + DIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + G1(A0, B0, C0, D0, A1, B1, C1, D1); \ + G2(A0, B0, C0, D0, A1, B1, C1, D1); \ + \ + UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1); \ + } while ((void) 0, 0) + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c new file mode 100644 index 0000000..f9e9a39 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/pwhash_argon2i.c @@ -0,0 +1,294 @@ + +#include +#include +#include +#include +#include +#include + +#include "argon2-core.h" +#include "argon2-encoding.h" +#include "argon2.h" +#include "crypto_pwhash.h" +#include "crypto_pwhash_argon2i.h" +#include "crypto_pwhash_argon2id.h" +#include "private/common.h" +#include "randombytes.h" +#include "utils.h" + +#define STR_HASHBYTES 32U + +int +crypto_pwhash_argon2i_alg_argon2i13(void) +{ + return crypto_pwhash_argon2i_ALG_ARGON2I13; +} + +size_t +crypto_pwhash_argon2i_bytes_min(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2i_BYTES_MIN >= ARGON2_MIN_OUTLEN); + return crypto_pwhash_argon2i_BYTES_MIN; +} + +size_t +crypto_pwhash_argon2i_bytes_max(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2i_BYTES_MAX <= ARGON2_MAX_OUTLEN); + return crypto_pwhash_argon2i_BYTES_MAX; +} + +size_t +crypto_pwhash_argon2i_passwd_min(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2i_PASSWD_MIN >= ARGON2_MIN_PWD_LENGTH); + return crypto_pwhash_argon2i_PASSWD_MIN; +} + +size_t +crypto_pwhash_argon2i_passwd_max(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2i_PASSWD_MAX <= ARGON2_MAX_PWD_LENGTH); + return crypto_pwhash_argon2i_PASSWD_MAX; +} + +size_t +crypto_pwhash_argon2i_saltbytes(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2i_SALTBYTES >= ARGON2_MIN_SALT_LENGTH); + COMPILER_ASSERT(crypto_pwhash_argon2i_SALTBYTES <= ARGON2_MAX_SALT_LENGTH); + return crypto_pwhash_argon2i_SALTBYTES; +} + +size_t +crypto_pwhash_argon2i_strbytes(void) +{ + return crypto_pwhash_argon2i_STRBYTES; +} + +const char* +crypto_pwhash_argon2i_strprefix(void) +{ + return crypto_pwhash_argon2i_STRPREFIX; +} + +size_t +crypto_pwhash_argon2i_opslimit_min(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2i_OPSLIMIT_MIN >= ARGON2_MIN_TIME); + return crypto_pwhash_argon2i_OPSLIMIT_MIN; +} + +size_t +crypto_pwhash_argon2i_opslimit_max(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2i_OPSLIMIT_MAX <= ARGON2_MAX_TIME); + return crypto_pwhash_argon2i_OPSLIMIT_MAX; +} + +size_t +crypto_pwhash_argon2i_memlimit_min(void) +{ + COMPILER_ASSERT((crypto_pwhash_argon2i_MEMLIMIT_MIN / 1024U) >= ARGON2_MIN_MEMORY); + return crypto_pwhash_argon2i_MEMLIMIT_MIN; +} + +size_t +crypto_pwhash_argon2i_memlimit_max(void) +{ + COMPILER_ASSERT((crypto_pwhash_argon2i_MEMLIMIT_MAX / 1024U) <= ARGON2_MAX_MEMORY); + return crypto_pwhash_argon2i_MEMLIMIT_MAX; +} + +size_t +crypto_pwhash_argon2i_opslimit_interactive(void) +{ + return crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_argon2i_memlimit_interactive(void) +{ + return crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_argon2i_opslimit_moderate(void) +{ + return crypto_pwhash_argon2i_OPSLIMIT_MODERATE; +} + +size_t +crypto_pwhash_argon2i_memlimit_moderate(void) +{ + return crypto_pwhash_argon2i_MEMLIMIT_MODERATE; +} + +size_t +crypto_pwhash_argon2i_opslimit_sensitive(void) +{ + return crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE; +} + +size_t +crypto_pwhash_argon2i_memlimit_sensitive(void) +{ + return crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE; +} + +int +crypto_pwhash_argon2i(unsigned char *const out, unsigned long long outlen, + const char *const passwd, unsigned long long passwdlen, + const unsigned char *const salt, + unsigned long long opslimit, size_t memlimit, int alg) +{ + memset(out, 0, outlen); + if (outlen > crypto_pwhash_argon2i_BYTES_MAX) { + errno = EFBIG; + return -1; + } + if (outlen < crypto_pwhash_argon2i_BYTES_MIN) { + errno = EINVAL; + return -1; + } + if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX || + opslimit > crypto_pwhash_argon2i_OPSLIMIT_MAX || + memlimit > crypto_pwhash_argon2i_MEMLIMIT_MAX) { + errno = EFBIG; + return -1; + } + if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN || + opslimit < crypto_pwhash_argon2i_OPSLIMIT_MIN || + memlimit < crypto_pwhash_argon2i_MEMLIMIT_MIN) { + errno = EINVAL; + return -1; + } + if ((const void *) out == (const void *) passwd) { + errno = EINVAL; + return -1; + } + switch (alg) { + case crypto_pwhash_argon2i_ALG_ARGON2I13: + if (argon2i_hash_raw((uint32_t) opslimit, (uint32_t) (memlimit / 1024U), + (uint32_t) 1U, passwd, (size_t) passwdlen, salt, + (size_t) crypto_pwhash_argon2i_SALTBYTES, out, + (size_t) outlen) != ARGON2_OK) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; + default: + errno = EINVAL; + return -1; + } +} + +int +crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES], + const char *const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) +{ + unsigned char salt[crypto_pwhash_argon2i_SALTBYTES]; + + memset(out, 0, crypto_pwhash_argon2i_STRBYTES); + if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX || + opslimit > crypto_pwhash_argon2i_OPSLIMIT_MAX || + memlimit > crypto_pwhash_argon2i_MEMLIMIT_MAX) { + errno = EFBIG; + return -1; + } + if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN || + opslimit < crypto_pwhash_argon2i_OPSLIMIT_MIN || + memlimit < crypto_pwhash_argon2i_MEMLIMIT_MIN) { + errno = EINVAL; + return -1; + } + randombytes_buf(salt, sizeof salt); + if (argon2i_hash_encoded((uint32_t) opslimit, (uint32_t) (memlimit / 1024U), + (uint32_t) 1U, passwd, (size_t) passwdlen, salt, + sizeof salt, STR_HASHBYTES, out, + crypto_pwhash_argon2i_STRBYTES) != ARGON2_OK) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; +} + +int +crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES], + const char *const passwd, + unsigned long long passwdlen) +{ + int verify_ret; + + if (passwdlen > crypto_pwhash_argon2i_PASSWD_MAX) { + errno = EFBIG; + return -1; + } + /* LCOV_EXCL_START */ + if (passwdlen < crypto_pwhash_argon2i_PASSWD_MIN) { + errno = EINVAL; + return -1; + } + /* LCOV_EXCL_STOP */ + + verify_ret = argon2i_verify(str, passwd, (size_t) passwdlen); + if (verify_ret == ARGON2_OK) { + return 0; + } + if (verify_ret == ARGON2_VERIFY_MISMATCH) { + errno = EINVAL; + } + return -1; +} + +static int +_needs_rehash(const char *str, unsigned long long opslimit, size_t memlimit, + argon2_type type) +{ + unsigned char *fodder; + argon2_context ctx; + size_t fodder_len; + int ret = -1; + + fodder_len = strlen(str); + memlimit /= 1024U; + if (opslimit > UINT32_MAX || memlimit > UINT32_MAX || + fodder_len >= crypto_pwhash_STRBYTES) { + errno = EINVAL; + return -1; + } + memset(&ctx, 0, sizeof ctx); + if ((fodder = (unsigned char *) calloc(fodder_len, 1U)) == NULL) { + return -1; /* LCOV_EXCL_LINE */ + } + ctx.out = ctx.pwd = ctx.salt = fodder; + ctx.outlen = ctx.pwdlen = ctx.saltlen = (uint32_t) fodder_len; + ctx.ad = ctx.secret = NULL; + ctx.adlen = ctx.secretlen = 0U; + if (argon2_decode_string(&ctx, str, type) != 0) { + errno = EINVAL; + ret = -1; + } else if (ctx.t_cost != (uint32_t) opslimit || + ctx.m_cost != (uint32_t) memlimit) { + ret = 1; + } else { + ret = 0; + } + free(fodder); + + return ret; +} + +int +crypto_pwhash_argon2i_str_needs_rehash(const char str[crypto_pwhash_argon2i_STRBYTES], + unsigned long long opslimit, size_t memlimit) +{ + return _needs_rehash(str, opslimit, memlimit, Argon2_i); +} + +int +crypto_pwhash_argon2id_str_needs_rehash(const char str[crypto_pwhash_argon2id_STRBYTES], + unsigned long long opslimit, size_t memlimit) +{ + return _needs_rehash(str, opslimit, memlimit, Argon2_id); +} diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/pwhash_argon2id.c b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/pwhash_argon2id.c new file mode 100644 index 0000000..d641a61 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/argon2/pwhash_argon2id.c @@ -0,0 +1,238 @@ + +#include +#include +#include +#include +#include + +#include "argon2-core.h" +#include "argon2.h" +#include "crypto_pwhash_argon2id.h" +#include "private/common.h" +#include "randombytes.h" +#include "utils.h" + +#define STR_HASHBYTES 32U + +int +crypto_pwhash_argon2id_alg_argon2id13(void) +{ + return crypto_pwhash_argon2id_ALG_ARGON2ID13; +} + +size_t +crypto_pwhash_argon2id_bytes_min(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2id_BYTES_MIN >= ARGON2_MIN_OUTLEN); + return crypto_pwhash_argon2id_BYTES_MIN; +} + +size_t +crypto_pwhash_argon2id_bytes_max(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2id_BYTES_MAX <= ARGON2_MAX_OUTLEN); + return crypto_pwhash_argon2id_BYTES_MAX; +} + +size_t +crypto_pwhash_argon2id_passwd_min(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2id_PASSWD_MIN >= ARGON2_MIN_PWD_LENGTH); + return crypto_pwhash_argon2id_PASSWD_MIN; +} + +size_t +crypto_pwhash_argon2id_passwd_max(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2id_PASSWD_MAX <= ARGON2_MAX_PWD_LENGTH); + return crypto_pwhash_argon2id_PASSWD_MAX; +} + +size_t +crypto_pwhash_argon2id_saltbytes(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2id_SALTBYTES >= ARGON2_MIN_SALT_LENGTH); + COMPILER_ASSERT(crypto_pwhash_argon2id_SALTBYTES <= ARGON2_MAX_SALT_LENGTH); + return crypto_pwhash_argon2id_SALTBYTES; +} + +size_t +crypto_pwhash_argon2id_strbytes(void) +{ + return crypto_pwhash_argon2id_STRBYTES; +} + +const char* +crypto_pwhash_argon2id_strprefix(void) +{ + return crypto_pwhash_argon2id_STRPREFIX; +} + +size_t +crypto_pwhash_argon2id_opslimit_min(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2id_OPSLIMIT_MIN >= ARGON2_MIN_TIME); + return crypto_pwhash_argon2id_OPSLIMIT_MIN; +} + +size_t +crypto_pwhash_argon2id_opslimit_max(void) +{ + COMPILER_ASSERT(crypto_pwhash_argon2id_OPSLIMIT_MAX <= ARGON2_MAX_TIME); + return crypto_pwhash_argon2id_OPSLIMIT_MAX; +} + +size_t +crypto_pwhash_argon2id_memlimit_min(void) +{ + COMPILER_ASSERT((crypto_pwhash_argon2id_MEMLIMIT_MIN / 1024U) >= ARGON2_MIN_MEMORY); + return crypto_pwhash_argon2id_MEMLIMIT_MIN; +} + +size_t +crypto_pwhash_argon2id_memlimit_max(void) +{ + COMPILER_ASSERT((crypto_pwhash_argon2id_MEMLIMIT_MAX / 1024U) <= ARGON2_MAX_MEMORY); + return crypto_pwhash_argon2id_MEMLIMIT_MAX; +} + +size_t +crypto_pwhash_argon2id_opslimit_interactive(void) +{ + return crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_argon2id_memlimit_interactive(void) +{ + return crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_argon2id_opslimit_moderate(void) +{ + return crypto_pwhash_argon2id_OPSLIMIT_MODERATE; +} + +size_t +crypto_pwhash_argon2id_memlimit_moderate(void) +{ + return crypto_pwhash_argon2id_MEMLIMIT_MODERATE; +} + +size_t +crypto_pwhash_argon2id_opslimit_sensitive(void) +{ + return crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE; +} + +size_t +crypto_pwhash_argon2id_memlimit_sensitive(void) +{ + return crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE; +} + +int +crypto_pwhash_argon2id(unsigned char *const out, unsigned long long outlen, + const char *const passwd, unsigned long long passwdlen, + const unsigned char *const salt, + unsigned long long opslimit, size_t memlimit, int alg) +{ + memset(out, 0, outlen); + if (outlen > crypto_pwhash_argon2id_BYTES_MAX) { + errno = EFBIG; + return -1; + } + if (outlen < crypto_pwhash_argon2id_BYTES_MIN) { + errno = EINVAL; + return -1; + } + if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX || + opslimit > crypto_pwhash_argon2id_OPSLIMIT_MAX || + memlimit > crypto_pwhash_argon2id_MEMLIMIT_MAX) { + errno = EFBIG; + return -1; + } + if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN || + opslimit < crypto_pwhash_argon2id_OPSLIMIT_MIN || + memlimit < crypto_pwhash_argon2id_MEMLIMIT_MIN) { + errno = EINVAL; + return -1; + } + if ((const void *) out == (const void *) passwd) { + errno = EINVAL; + return -1; + } + switch (alg) { + case crypto_pwhash_argon2id_ALG_ARGON2ID13: + if (argon2id_hash_raw((uint32_t) opslimit, (uint32_t) (memlimit / 1024U), + (uint32_t) 1U, passwd, (size_t) passwdlen, salt, + (size_t) crypto_pwhash_argon2id_SALTBYTES, out, + (size_t) outlen) != ARGON2_OK) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; + default: + errno = EINVAL; + return -1; + } +} + +int +crypto_pwhash_argon2id_str(char out[crypto_pwhash_argon2id_STRBYTES], + const char *const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) +{ + unsigned char salt[crypto_pwhash_argon2id_SALTBYTES]; + + memset(out, 0, crypto_pwhash_argon2id_STRBYTES); + if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX || + opslimit > crypto_pwhash_argon2id_OPSLIMIT_MAX || + memlimit > crypto_pwhash_argon2id_MEMLIMIT_MAX) { + errno = EFBIG; + return -1; + } + if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN || + opslimit < crypto_pwhash_argon2id_OPSLIMIT_MIN || + memlimit < crypto_pwhash_argon2id_MEMLIMIT_MIN) { + errno = EINVAL; + return -1; + } + randombytes_buf(salt, sizeof salt); + if (argon2id_hash_encoded((uint32_t) opslimit, (uint32_t) (memlimit / 1024U), + (uint32_t) 1U, passwd, (size_t) passwdlen, salt, + sizeof salt, STR_HASHBYTES, out, + crypto_pwhash_argon2id_STRBYTES) != ARGON2_OK) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; +} + +int +crypto_pwhash_argon2id_str_verify(const char str[crypto_pwhash_argon2id_STRBYTES], + const char *const passwd, + unsigned long long passwdlen) +{ + int verify_ret; + + if (passwdlen > crypto_pwhash_argon2id_PASSWD_MAX) { + errno = EFBIG; + return -1; + } + /* LCOV_EXCL_START */ + if (passwdlen < crypto_pwhash_argon2id_PASSWD_MIN) { + errno = EINVAL; + return -1; + } + /* LCOV_EXCL_STOP */ + + verify_ret = argon2id_verify(str, passwd, (size_t) passwdlen); + if (verify_ret == ARGON2_OK) { + return 0; + } + if (verify_ret == ARGON2_VERIFY_MISMATCH) { + errno = EINVAL; + } + return -1; +} diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/crypto_pwhash.c b/external/src/libsodium/src/libsodium/crypto_pwhash/crypto_pwhash.c new file mode 100644 index 0000000..a229b9f --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/crypto_pwhash.c @@ -0,0 +1,212 @@ + +#include +#include + +#include "core.h" +#include "crypto_pwhash.h" + +int +crypto_pwhash_alg_argon2i13(void) +{ + return crypto_pwhash_ALG_ARGON2I13; +} + +int +crypto_pwhash_alg_argon2id13(void) +{ + return crypto_pwhash_ALG_ARGON2ID13; +} + +int +crypto_pwhash_alg_default(void) +{ + return crypto_pwhash_ALG_DEFAULT; +} + +size_t +crypto_pwhash_bytes_min(void) +{ + return crypto_pwhash_BYTES_MIN; +} + +size_t +crypto_pwhash_bytes_max(void) +{ + return crypto_pwhash_BYTES_MAX; +} + +size_t +crypto_pwhash_passwd_min(void) +{ + return crypto_pwhash_PASSWD_MIN; +} + +size_t +crypto_pwhash_passwd_max(void) +{ + return crypto_pwhash_PASSWD_MAX; +} + +size_t +crypto_pwhash_saltbytes(void) +{ + return crypto_pwhash_SALTBYTES; +} + +size_t +crypto_pwhash_strbytes(void) +{ + return crypto_pwhash_STRBYTES; +} + +const char * +crypto_pwhash_strprefix(void) +{ + return crypto_pwhash_STRPREFIX; +} + +size_t +crypto_pwhash_opslimit_min(void) +{ + return crypto_pwhash_OPSLIMIT_MIN; +} + +size_t +crypto_pwhash_opslimit_max(void) +{ + return crypto_pwhash_OPSLIMIT_MAX; +} + +size_t +crypto_pwhash_memlimit_min(void) +{ + return crypto_pwhash_MEMLIMIT_MIN; +} + +size_t +crypto_pwhash_memlimit_max(void) +{ + return crypto_pwhash_MEMLIMIT_MAX; +} + +size_t +crypto_pwhash_opslimit_interactive(void) +{ + return crypto_pwhash_OPSLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_memlimit_interactive(void) +{ + return crypto_pwhash_MEMLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_opslimit_moderate(void) +{ + return crypto_pwhash_OPSLIMIT_MODERATE; +} + +size_t +crypto_pwhash_memlimit_moderate(void) +{ + return crypto_pwhash_MEMLIMIT_MODERATE; +} + +size_t +crypto_pwhash_opslimit_sensitive(void) +{ + return crypto_pwhash_OPSLIMIT_SENSITIVE; +} + +size_t +crypto_pwhash_memlimit_sensitive(void) +{ + return crypto_pwhash_MEMLIMIT_SENSITIVE; +} + +int +crypto_pwhash(unsigned char * const out, unsigned long long outlen, + const char * const passwd, unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, size_t memlimit, int alg) +{ + switch (alg) { + case crypto_pwhash_ALG_ARGON2I13: + return crypto_pwhash_argon2i(out, outlen, passwd, passwdlen, salt, + opslimit, memlimit, alg); + case crypto_pwhash_ALG_ARGON2ID13: + return crypto_pwhash_argon2id(out, outlen, passwd, passwdlen, salt, + opslimit, memlimit, alg); + default: + errno = EINVAL; + return -1; + } +} + +int +crypto_pwhash_str(char out[crypto_pwhash_STRBYTES], + const char * const passwd, unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) +{ + return crypto_pwhash_argon2id_str(out, passwd, passwdlen, + opslimit, memlimit); +} + +int +crypto_pwhash_str_alg(char out[crypto_pwhash_STRBYTES], + const char * const passwd, unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit, int alg) +{ + switch (alg) { + case crypto_pwhash_ALG_ARGON2I13: + return crypto_pwhash_argon2i_str(out, passwd, passwdlen, + opslimit, memlimit); + case crypto_pwhash_ALG_ARGON2ID13: + return crypto_pwhash_argon2id_str(out, passwd, passwdlen, + opslimit, memlimit); + } + sodium_misuse(); + /* NOTREACHED */ + return -1; +} + +int +crypto_pwhash_str_verify(const char str[crypto_pwhash_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) +{ + if (strncmp(str, crypto_pwhash_argon2id_STRPREFIX, + sizeof crypto_pwhash_argon2id_STRPREFIX - 1) == 0) { + return crypto_pwhash_argon2id_str_verify(str, passwd, passwdlen); + } + if (strncmp(str, crypto_pwhash_argon2i_STRPREFIX, + sizeof crypto_pwhash_argon2i_STRPREFIX - 1) == 0) { + return crypto_pwhash_argon2i_str_verify(str, passwd, passwdlen); + } + errno = EINVAL; + + return -1; +} + +int +crypto_pwhash_str_needs_rehash(const char str[crypto_pwhash_STRBYTES], + unsigned long long opslimit, size_t memlimit) +{ + if (strncmp(str, crypto_pwhash_argon2id_STRPREFIX, + sizeof crypto_pwhash_argon2id_STRPREFIX - 1) == 0) { + return crypto_pwhash_argon2id_str_needs_rehash(str, opslimit, memlimit); + } + if (strncmp(str, crypto_pwhash_argon2i_STRPREFIX, + sizeof crypto_pwhash_argon2i_STRPREFIX - 1) == 0) { + return crypto_pwhash_argon2i_str_needs_rehash(str, opslimit, memlimit); + } + errno = EINVAL; + + return -1; +} + +const char * +crypto_pwhash_primitive(void) { + return crypto_pwhash_PRIMITIVE; +} diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c new file mode 100644 index 0000000..c4dd46a --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c @@ -0,0 +1,263 @@ +/*- + * Copyright 2013 Alexander Peslyak + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include "crypto_pwhash_scryptsalsa208sha256.h" +#include "crypto_scrypt.h" +#include "private/common.h" +#include "runtime.h" +#include "utils.h" + +static const char *const itoa64 = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +static uint8_t * +encode64_uint32(uint8_t *dst, size_t dstlen, uint32_t src, uint32_t srcbits) +{ + uint32_t bit; + + for (bit = 0; bit < srcbits; bit += 6) { + if (dstlen < 1) { + return NULL; /* LCOV_EXCL_LINE */ + } + *dst++ = itoa64[src & 0x3f]; + dstlen--; + src >>= 6; + } + return dst; +} + +static uint8_t * +encode64(uint8_t *dst, size_t dstlen, const uint8_t *src, size_t srclen) +{ + size_t i; + + for (i = 0; i < srclen;) { + uint8_t *dnext; + uint32_t value = 0, bits = 0; + + do { + value |= (uint32_t) src[i++] << bits; + bits += 8; + } while (bits < 24 && i < srclen); + + dnext = encode64_uint32(dst, dstlen, value, bits); + if (!dnext) { + return NULL; /* LCOV_EXCL_LINE */ + } + dstlen -= dnext - dst; + dst = dnext; + } + return dst; +} + +static int +decode64_one(uint32_t *dst, uint8_t src) +{ + const char *ptr = strchr(itoa64, src); + + if (ptr) { + *dst = (uint32_t)(ptr - itoa64); + return 0; + } + *dst = 0; + + return -1; +} + +static const uint8_t * +decode64_uint32(uint32_t *dst, uint32_t dstbits, const uint8_t *src) +{ + uint32_t bit; + uint32_t value; + + value = 0; + for (bit = 0; bit < dstbits; bit += 6) { + uint32_t one; + if (decode64_one(&one, *src)) { + *dst = 0; + return NULL; + } + src++; + value |= one << bit; + } + *dst = value; + + return src; +} + +const uint8_t * +escrypt_parse_setting(const uint8_t *setting, + uint32_t *N_log2_p, uint32_t *r_p, uint32_t *p_p) +{ + const uint8_t *src; + + if (setting[0] != '$' || setting[1] != '7' || setting[2] != '$') { + return NULL; + } + src = setting + 3; + + if (decode64_one(N_log2_p, *src)) { + return NULL; + } + src++; + + src = decode64_uint32(r_p, 30, src); + if (!src) { + return NULL; + } + + src = decode64_uint32(p_p, 30, src); + if (!src) { + return NULL; + } + return src; +} + +uint8_t * +escrypt_r(escrypt_local_t *local, const uint8_t *passwd, size_t passwdlen, + const uint8_t *setting, uint8_t *buf, size_t buflen) +{ + uint8_t hash[crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES]; + escrypt_kdf_t escrypt_kdf; + const uint8_t *src; + const uint8_t *salt; + uint8_t *dst; + size_t prefixlen; + size_t saltlen; + size_t need; + uint64_t N; + uint32_t N_log2; + uint32_t r; + uint32_t p; + + src = escrypt_parse_setting(setting, &N_log2, &r, &p); + if (!src) { + return NULL; + } + N = (uint64_t) 1 << N_log2; + prefixlen = src - setting; + + salt = src; + src = (const uint8_t *) strrchr((const char *) salt, '$'); + if (src) { + saltlen = src - salt; + } else { + saltlen = strlen((const char *) salt); + } + need = prefixlen + saltlen + 1 + + crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1; + if (need > buflen || need < saltlen) { + return NULL; + } +#ifdef HAVE_EMMINTRIN_H + escrypt_kdf = + sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse; +#else + escrypt_kdf = escrypt_kdf_nosse; +#endif + if (escrypt_kdf(local, passwd, passwdlen, salt, saltlen, N, r, p, hash, + sizeof(hash))) { + return NULL; + } + dst = buf; + memcpy(dst, setting, prefixlen + saltlen); + dst += prefixlen + saltlen; + *dst++ = '$'; + + dst = encode64(dst, buflen - (dst - buf), hash, sizeof(hash)); + sodium_memzero(hash, sizeof hash); + if (!dst || dst >= buf + buflen) { + return NULL; /* Can't happen LCOV_EXCL_LINE */ + } + *dst = 0; /* NUL termination */ + + return buf; +} + +uint8_t * +escrypt_gensalt_r(uint32_t N_log2, uint32_t r, uint32_t p, const uint8_t *src, + size_t srclen, uint8_t *buf, size_t buflen) +{ + uint8_t *dst; + size_t prefixlen = + (sizeof "$7$" - 1U) + (1U /* N_log2 */) + (5U /* r */) + (5U /* p */); + size_t saltlen = BYTES2CHARS(srclen); + size_t need; + + need = prefixlen + saltlen + 1; + if (need > buflen || need < saltlen || saltlen < srclen) { + return NULL; /* LCOV_EXCL_LINE */ + } + if (N_log2 > 63 || ((uint64_t) r * (uint64_t) p >= (1U << 30))) { + return NULL; /* LCOV_EXCL_LINE */ + } + dst = buf; + *dst++ = '$'; + *dst++ = '7'; + *dst++ = '$'; + + *dst++ = itoa64[N_log2]; + + dst = encode64_uint32(dst, buflen - (dst - buf), r, 30); + if (!dst) { + return NULL; /* Can't happen LCOV_EXCL_LINE */ + } + dst = encode64_uint32(dst, buflen - (dst - buf), p, 30); + if (!dst) { + return NULL; /* Can't happen LCOV_EXCL_LINE */ + } + dst = encode64(dst, buflen - (dst - buf), src, srclen); + if (!dst || dst >= buf + buflen) { + return NULL; /* Can't happen LCOV_EXCL_LINE */ + } + *dst = 0; /* NUL termination */ + + return buf; +} + +int +crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t *passwd, size_t passwdlen, + const uint8_t *salt, size_t saltlen, + uint64_t N, uint32_t r, uint32_t p, + uint8_t *buf, size_t buflen) +{ + escrypt_kdf_t escrypt_kdf; + escrypt_local_t local; + int retval; + + if (escrypt_init_local(&local)) { + return -1; /* LCOV_EXCL_LINE */ + } +#if defined(HAVE_EMMINTRIN_H) + escrypt_kdf = + sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse; +#else + escrypt_kdf = escrypt_kdf_nosse; +#endif + retval = escrypt_kdf(&local, passwd, passwdlen, salt, saltlen, N, r, p, buf, + buflen); + if (escrypt_free_local(&local)) { + return -1; /* LCOV_EXCL_LINE */ + } + return retval; +} diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h new file mode 100644 index 0000000..eee7b8b --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h @@ -0,0 +1,98 @@ +/*- + * Copyright 2009 Colin Percival + * Copyright 2013 Alexander Peslyak + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ +#ifndef crypto_scrypt_H +#define crypto_scrypt_H + +#include +#include +#include + +#if SIZE_MAX > 0xffffffffULL +#define ARCH_BITS 64 +#else +#define ARCH_BITS 32 +#endif + +#define crypto_pwhash_scryptsalsa208sha256_STRPREFIXBYTES 14 +#define crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES 57 +#define crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES 32 +#define crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES_ENCODED 43 +#define crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES 32 +#define crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED 43 + +#define BYTES2CHARS(bytes) ((((bytes) *8) + 5) / 6) + +typedef struct { + void * base, *aligned; + size_t size; +} escrypt_region_t; + +typedef union { + uint64_t d[8]; + uint32_t w[16]; +} escrypt_block_t; + +typedef escrypt_region_t escrypt_local_t; + +int escrypt_init_local(escrypt_local_t *__local); + +int escrypt_free_local(escrypt_local_t *__local); + +void *escrypt_alloc_region(escrypt_region_t *region, size_t size); +int escrypt_free_region(escrypt_region_t *region); + +typedef int (*escrypt_kdf_t)(escrypt_local_t *__local, const uint8_t *__passwd, + size_t __passwdlen, const uint8_t *__salt, + size_t __saltlen, uint64_t __N, uint32_t __r, + uint32_t __p, uint8_t *__buf, size_t __buflen); + +int escrypt_kdf_nosse(escrypt_local_t *__local, const uint8_t *__passwd, + size_t __passwdlen, const uint8_t *__salt, + size_t __saltlen, uint64_t __N, uint32_t __r, + uint32_t __p, uint8_t *__buf, size_t __buflen); + +int escrypt_kdf_sse(escrypt_local_t *__local, const uint8_t *__passwd, + size_t __passwdlen, const uint8_t *__salt, + size_t __saltlen, uint64_t __N, uint32_t __r, + uint32_t __p, uint8_t *__buf, size_t __buflen); + +uint8_t *escrypt_r(escrypt_local_t *__local, const uint8_t *__passwd, + size_t __passwdlen, const uint8_t *__setting, + uint8_t *__buf, size_t __buflen); + +uint8_t *escrypt_gensalt_r(uint32_t __N_log2, uint32_t __r, uint32_t __p, + const uint8_t *__src, size_t __srclen, + uint8_t *__buf, size_t __buflen); + +const uint8_t *escrypt_parse_setting(const uint8_t *setting, + uint32_t *N_log2_p, uint32_t *r_p, + uint32_t *p_p); + +#endif /* !_CRYPTO_SCRYPT_H_ */ diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c new file mode 100644 index 0000000..9f5b9a5 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c @@ -0,0 +1,380 @@ +/*- + * Copyright 2009 Colin Percival + * Copyright 2013 Alexander Peslyak + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ + +#include +#include +#include +#include +#include + +#include "../crypto_scrypt.h" +#include "../pbkdf2-sha256.h" +#include "private/common.h" + +static inline void +blkcpy_64(escrypt_block_t *dest, const escrypt_block_t *src) +{ + int i; + +#if (ARCH_BITS == 32) + for (i = 0; i < 16; ++i) { + dest->w[i] = src->w[i]; + } +#else + for (i = 0; i < 8; ++i) { + dest->d[i] = src->d[i]; + } +#endif +} + +static inline void +blkxor_64(escrypt_block_t *dest, const escrypt_block_t *src) +{ + int i; + +#if (ARCH_BITS == 32) + for (i = 0; i < 16; ++i) { + dest->w[i] ^= src->w[i]; + } +#else + for (i = 0; i < 8; ++i) { + dest->d[i] ^= src->d[i]; + } +#endif +} + +static inline void +blkcpy(escrypt_block_t *dest, const escrypt_block_t *src, size_t len) +{ + size_t i, L; + +#if (ARCH_BITS == 32) + L = (len >> 2); + for (i = 0; i < L; ++i) { + dest->w[i] = src->w[i]; + } +#else + L = (len >> 3); + for (i = 0; i < L; ++i) { + dest->d[i] = src->d[i]; + } +#endif +} + +static inline void +blkxor(escrypt_block_t *dest, const escrypt_block_t *src, size_t len) +{ + size_t i, L; + +#if (ARCH_BITS == 32) + L = (len >> 2); + for (i = 0; i < L; ++i) { + dest->w[i] ^= src->w[i]; + } +#else + L = (len >> 3); + for (i = 0; i < L; ++i) { + dest->d[i] ^= src->d[i]; + } +#endif +} + +/* + * salsa20_8(B): + * Apply the salsa20/8 core to the provided block. + */ +static void +salsa20_8(uint32_t B[16]) +{ + escrypt_block_t X; + uint32_t *x = X.w; + size_t i; + + blkcpy_64(&X, (escrypt_block_t *) B); + for (i = 0; i < 8; i += 2) { +#define R(a, b) (((a) << (b)) | ((a) >> (32 - (b)))) + /* Operate on columns. */ + x[4] ^= R(x[0] + x[12], 7); + x[8] ^= R(x[4] + x[0], 9); + x[12] ^= R(x[8] + x[4], 13); + x[0] ^= R(x[12] + x[8], 18); + + x[9] ^= R(x[5] + x[1], 7); + x[13] ^= R(x[9] + x[5], 9); + x[1] ^= R(x[13] + x[9], 13); + x[5] ^= R(x[1] + x[13], 18); + + x[14] ^= R(x[10] + x[6], 7); + x[2] ^= R(x[14] + x[10], 9); + x[6] ^= R(x[2] + x[14], 13); + x[10] ^= R(x[6] + x[2], 18); + + x[3] ^= R(x[15] + x[11], 7); + x[7] ^= R(x[3] + x[15], 9); + x[11] ^= R(x[7] + x[3], 13); + x[15] ^= R(x[11] + x[7], 18); + + /* Operate on rows. */ + x[1] ^= R(x[0] + x[3], 7); + x[2] ^= R(x[1] + x[0], 9); + x[3] ^= R(x[2] + x[1], 13); + x[0] ^= R(x[3] + x[2], 18); + + x[6] ^= R(x[5] + x[4], 7); + x[7] ^= R(x[6] + x[5], 9); + x[4] ^= R(x[7] + x[6], 13); + x[5] ^= R(x[4] + x[7], 18); + + x[11] ^= R(x[10] + x[9], 7); + x[8] ^= R(x[11] + x[10], 9); + x[9] ^= R(x[8] + x[11], 13); + x[10] ^= R(x[9] + x[8], 18); + + x[12] ^= R(x[15] + x[14], 7); + x[13] ^= R(x[12] + x[15], 9); + x[14] ^= R(x[13] + x[12], 13); + x[15] ^= R(x[14] + x[13], 18); +#undef R + } + for (i = 0; i < 16; i++) { + B[i] += x[i]; + } +} + +/* + * blockmix_salsa8(Bin, Bout, X, r): + * Compute Bout = BlockMix_{salsa20/8, r}(Bin). + * The input Bin must be 128r bytes in length; + * The output Bout must also be the same size. + * The temporary space X must be 64 bytes. + */ +static void +blockmix_salsa8(const uint32_t *Bin, uint32_t *Bout, uint32_t *X, size_t r) +{ + size_t i; + + /* 1: X <-- B_{2r - 1} */ + blkcpy_64((escrypt_block_t *) X, + (const escrypt_block_t *) &Bin[(2 * r - 1) * 16]); + + /* 2: for i = 0 to 2r - 1 do */ + for (i = 0; i < 2 * r; i += 2) { + /* 3: X <-- H(X \xor B_i) */ + blkxor_64((escrypt_block_t *) X, + (const escrypt_block_t *) &Bin[i * 16]); + salsa20_8(X); + + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + blkcpy_64((escrypt_block_t *) &Bout[i * 8], + (const escrypt_block_t *) X); + + /* 3: X <-- H(X \xor B_i) */ + blkxor_64((escrypt_block_t *) X, + (const escrypt_block_t *) &Bin[i * 16 + 16]); + salsa20_8(X); + + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + blkcpy_64((escrypt_block_t *) &Bout[i * 8 + r * 16], + (escrypt_block_t *) X); + } +} + +/* + * integerify(B, r): + * Return the result of parsing B_{2r-1} as a little-endian integer. + */ +static inline uint64_t +integerify(const void *B, size_t r) +{ + const uint32_t *X = ((const uint32_t *) B) + (2 * r - 1) * 16; + + return ((uint64_t) (X[1]) << 32) + X[0]; +} + +/* + * smix(B, r, N, V, XY): + * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; + * the temporary storage V must be 128rN bytes in length; the temporary + * storage XY must be 256r + 64 bytes in length. The value N must be a + * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a + * multiple of 64 bytes. + */ +static void +smix(uint8_t *B, size_t r, uint64_t N, uint32_t *V, uint32_t *XY) +{ + uint32_t *X = XY; + uint32_t *Y = &XY[32 * r]; + uint32_t *Z = &XY[64 * r]; + uint64_t i; + uint64_t j; + size_t k; + + /* 1: X <-- B */ + for (k = 0; k < 32 * r; k++) { + X[k] = LOAD32_LE(&B[4 * k]); + } + /* 2: for i = 0 to N - 1 do */ + for (i = 0; i < N; i += 2) { + /* 3: V_i <-- X */ + blkcpy((escrypt_block_t *) &V[i * (32 * r)], (escrypt_block_t *) X, + 128 * r); + + /* 4: X <-- H(X) */ + blockmix_salsa8(X, Y, Z, r); + + /* 3: V_i <-- X */ + blkcpy((escrypt_block_t *) &V[(i + 1) * (32 * r)], + (escrypt_block_t *) Y, 128 * r); + + /* 4: X <-- H(X) */ + blockmix_salsa8(Y, X, Z, r); + } + + /* 6: for i = 0 to N - 1 do */ + for (i = 0; i < N; i += 2) { + /* 7: j <-- Integerify(X) mod N */ + j = integerify(X, r) & (N - 1); + + /* 8: X <-- H(X \xor V_j) */ + blkxor((escrypt_block_t *) X, (escrypt_block_t *) &V[j * (32 * r)], + 128 * r); + blockmix_salsa8(X, Y, Z, r); + + /* 7: j <-- Integerify(X) mod N */ + j = integerify(Y, r) & (N - 1); + + /* 8: X <-- H(X \xor V_j) */ + blkxor((escrypt_block_t *) Y, (escrypt_block_t *) &V[j * (32 * r)], + 128 * r); + blockmix_salsa8(Y, X, Z, r); + } + /* 10: B' <-- X */ + for (k = 0; k < 32 * r; k++) { + STORE32_LE(&B[4 * k], X[k]); + } +} + +/* + * escrypt_kdf(local, passwd, passwdlen, salt, saltlen, + * N, r, p, buf, buflen): + * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, + * p, buflen) and write the result into buf. The parameters r, p, and buflen + * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N + * must be a power of 2 greater than 1. + * + * Return 0 on success; or -1 on error. + */ +int +escrypt_kdf_nosse(escrypt_local_t *local, const uint8_t *passwd, + size_t passwdlen, const uint8_t *salt, size_t saltlen, + uint64_t N, uint32_t _r, uint32_t _p, uint8_t *buf, + size_t buflen) +{ + size_t B_size, V_size, XY_size, need; + uint8_t * B; + uint32_t *V, *XY; + size_t r = _r, p = _p; + uint32_t i; + +/* Sanity-check parameters. */ +#if SIZE_MAX > UINT32_MAX + if (buflen > (((uint64_t)(1) << 32) - 1) * 32) { + errno = EFBIG; + return -1; + } +#endif + if ((uint64_t)(r) * (uint64_t)(p) >= ((uint64_t) 1 << 30)) { + errno = EFBIG; + return -1; + } + if (N > UINT32_MAX) { + errno = EFBIG; + return -1; + } + if (((N & (N - 1)) != 0) || (N < 2)) { + errno = EINVAL; + return -1; + } + if (r == 0 || p == 0) { + errno = EINVAL; + return -1; + } + if ((r > SIZE_MAX / 128 / p) || +#if SIZE_MAX / 256 <= UINT32_MAX + (r > SIZE_MAX / 256) || +#endif + (N > SIZE_MAX / 128 / r)) { + errno = ENOMEM; + return -1; + } + + /* Allocate memory. */ + B_size = (size_t) 128 * r * p; + V_size = (size_t) 128 * r * (size_t) N; + need = B_size + V_size; + if (need < V_size) { + errno = ENOMEM; + return -1; + } + XY_size = (size_t) 256 * r + 64; + need += XY_size; + if (need < XY_size) { + errno = ENOMEM; + return -1; + } + if (local->size < need) { + if (escrypt_free_region(local)) { + return -1; + } + if (!escrypt_alloc_region(local, need)) { + return -1; + } + } + B = (uint8_t *) local->aligned; + V = (uint32_t *) ((uint8_t *) B + B_size); + XY = (uint32_t *) ((uint8_t *) V + V_size); + + /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ + escrypt_PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size); + + /* 2: for i = 0 to p - 1 do */ + for (i = 0; i < p; i++) { + /* 3: B_i <-- MF(B_i, N) */ + smix(&B[(size_t) 128 * i * r], r, N, V, XY); + } + + /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ + escrypt_PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen); + + /* Success! */ + return 0; +} diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c new file mode 100644 index 0000000..bcf7da5 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c @@ -0,0 +1,96 @@ +/*- + * Copyright 2005,2007,2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include + +#include "core.h" +#include "crypto_auth_hmacsha256.h" +#include "crypto_pwhash_scryptsalsa208sha256.h" +#include "pbkdf2-sha256.h" +#include "private/common.h" +#include "utils.h" + +/** + * escrypt_PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and + * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). + */ +void +escrypt_PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, + const uint8_t *salt, size_t saltlen, uint64_t c, + uint8_t *buf, size_t dkLen) +{ + crypto_auth_hmacsha256_state PShctx, hctx; + size_t i; + uint8_t ivec[4]; + uint8_t U[32]; + uint8_t T[32]; + uint64_t j; + int k; + size_t clen; + +#if SIZE_MAX > 0x1fffffffe0ULL + COMPILER_ASSERT(crypto_pwhash_scryptsalsa208sha256_BYTES_MAX + <= 0x1fffffffe0ULL); + if (dkLen > 0x1fffffffe0ULL) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +#endif + crypto_auth_hmacsha256_init(&PShctx, passwd, passwdlen); + crypto_auth_hmacsha256_update(&PShctx, salt, saltlen); + + for (i = 0; i * 32 < dkLen; i++) { + STORE32_BE(ivec, (uint32_t)(i + 1)); + memcpy(&hctx, &PShctx, sizeof(crypto_auth_hmacsha256_state)); + crypto_auth_hmacsha256_update(&hctx, ivec, 4); + crypto_auth_hmacsha256_final(&hctx, U); + + memcpy(T, U, 32); + /* LCOV_EXCL_START */ + for (j = 2; j <= c; j++) { + crypto_auth_hmacsha256_init(&hctx, passwd, passwdlen); + crypto_auth_hmacsha256_update(&hctx, U, 32); + crypto_auth_hmacsha256_final(&hctx, U); + + for (k = 0; k < 32; k++) { + T[k] ^= U[k]; + } + } + /* LCOV_EXCL_STOP */ + + clen = dkLen - i * 32; + if (clen > 32) { + clen = 32; + } + memcpy(&buf[i * 32], T, clen); + } + sodium_memzero((void *) &PShctx, sizeof PShctx); +} diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h new file mode 100644 index 0000000..962b433 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h @@ -0,0 +1,45 @@ +/*- + * Copyright 2005,2007,2009 Colin Percival + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef pbkdf2_sha256_H +#define pbkdf2_sha256_H + +#include + +#include + +#include "crypto_auth_hmacsha256.h" + +/** + * escrypt_PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and + * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). + */ +void escrypt_PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, + uint64_t, uint8_t *, size_t); + +#endif /* !_SHA256_H_ */ diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c new file mode 100644 index 0000000..6f0cb6b --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c @@ -0,0 +1,300 @@ + +#include +#include +#include +#include +#include + +#include "crypto_pwhash_scryptsalsa208sha256.h" +#include "crypto_scrypt.h" +#include "private/common.h" +#include "randombytes.h" +#include "utils.h" + +#define SETTING_SIZE(saltbytes) \ + ((sizeof "$7$" - 1U) + (1U /* N_log2 */) + (5U /* r */) + (5U /* p */) + \ + BYTES2CHARS(saltbytes)) + +static int +pickparams(unsigned long long opslimit, const size_t memlimit, + uint32_t *const N_log2, uint32_t *const p, uint32_t *const r) +{ + unsigned long long maxN; + unsigned long long maxrp; + + if (opslimit < 32768) { + opslimit = 32768; + } + *r = 8; + if (opslimit < memlimit / 32) { + *p = 1; + maxN = opslimit / (*r * 4); + for (*N_log2 = 1; *N_log2 < 63; *N_log2 += 1) { + if ((uint64_t)(1) << *N_log2 > maxN / 2) { + break; + } + } + } else { + maxN = memlimit / ((size_t) *r * 128); + for (*N_log2 = 1; *N_log2 < 63; *N_log2 += 1) { + if ((uint64_t)(1) << *N_log2 > maxN / 2) { + break; + } + } + maxrp = (opslimit / 4) / ((uint64_t)(1) << *N_log2); + /* LCOV_EXCL_START */ + if (maxrp > 0x3fffffff) { + maxrp = 0x3fffffff; + } + /* LCOV_EXCL_STOP */ + *p = (uint32_t)(maxrp) / *r; + } + return 0; +} + +static size_t +sodium_strnlen(const char *str, size_t maxlen) +{ + size_t i = 0U; + + while (i < maxlen && str[i] != 0) { + i++; + } + return i; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_bytes_min(void) +{ + return crypto_pwhash_scryptsalsa208sha256_BYTES_MIN; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_bytes_max(void) +{ + return crypto_pwhash_scryptsalsa208sha256_BYTES_MAX; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_passwd_min(void) +{ + return crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_passwd_max(void) +{ + return crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_saltbytes(void) +{ + return crypto_pwhash_scryptsalsa208sha256_SALTBYTES; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_strbytes(void) +{ + return crypto_pwhash_scryptsalsa208sha256_STRBYTES; +} + +const char * +crypto_pwhash_scryptsalsa208sha256_strprefix(void) +{ + return crypto_pwhash_scryptsalsa208sha256_STRPREFIX; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_opslimit_min(void) +{ + return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_opslimit_max(void) +{ + return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_memlimit_min(void) +{ + return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_memlimit_max(void) +{ + return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void) +{ + return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void) +{ + return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void) +{ + return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE; +} + +size_t +crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void) +{ + return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE; +} + +int +crypto_pwhash_scryptsalsa208sha256(unsigned char *const out, + unsigned long long outlen, + const char *const passwd, + unsigned long long passwdlen, + const unsigned char *const salt, + unsigned long long opslimit, size_t memlimit) +{ + uint32_t N_log2; + uint32_t p; + uint32_t r; + + memset(out, 0, outlen); + if (passwdlen > crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX || + outlen > crypto_pwhash_scryptsalsa208sha256_BYTES_MAX) { + errno = EFBIG; /* LCOV_EXCL_LINE */ + return -1; /* LCOV_EXCL_LINE */ + } + if (outlen < crypto_pwhash_scryptsalsa208sha256_BYTES_MIN || + pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) { + errno = EINVAL; /* LCOV_EXCL_LINE */ + return -1; /* LCOV_EXCL_LINE */ + } + if ((const void *) out == (const void *) passwd) { + errno = EINVAL; + return -1; + } + return crypto_pwhash_scryptsalsa208sha256_ll( + (const uint8_t *) passwd, (size_t) passwdlen, (const uint8_t *) salt, + crypto_pwhash_scryptsalsa208sha256_SALTBYTES, (uint64_t)(1) << N_log2, + r, p, out, (size_t) outlen); +} + +int +crypto_pwhash_scryptsalsa208sha256_str( + char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + const char *const passwd, unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) +{ + uint8_t salt[crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES]; + char setting[crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U]; + escrypt_local_t escrypt_local; + uint32_t N_log2; + uint32_t p; + uint32_t r; + + memset(out, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES); + if (passwdlen > crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX) { + errno = EFBIG; /* LCOV_EXCL_LINE */ + return -1; /* LCOV_EXCL_LINE */ + } + if (passwdlen < crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN || + pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) { + errno = EINVAL; /* LCOV_EXCL_LINE */ + return -1; /* LCOV_EXCL_LINE */ + } + randombytes_buf(salt, sizeof salt); + if (escrypt_gensalt_r(N_log2, r, p, salt, sizeof salt, (uint8_t *) setting, + sizeof setting) == NULL) { + errno = EINVAL; /* LCOV_EXCL_LINE */ + return -1; /* LCOV_EXCL_LINE */ + } + if (escrypt_init_local(&escrypt_local) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen, + (const uint8_t *) setting, (uint8_t *) out, + crypto_pwhash_scryptsalsa208sha256_STRBYTES) == NULL) { + /* LCOV_EXCL_START */ + escrypt_free_local(&escrypt_local); + errno = EINVAL; + return -1; + /* LCOV_EXCL_STOP */ + } + escrypt_free_local(&escrypt_local); + + COMPILER_ASSERT( + SETTING_SIZE(crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES) == + crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES); + COMPILER_ASSERT( + crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U + + crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1U == + crypto_pwhash_scryptsalsa208sha256_STRBYTES); + + return 0; +} + +int +crypto_pwhash_scryptsalsa208sha256_str_verify( + const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + const char *const passwd, unsigned long long passwdlen) +{ + char wanted[crypto_pwhash_scryptsalsa208sha256_STRBYTES]; + escrypt_local_t escrypt_local; + int ret = -1; + + if (sodium_strnlen(str, crypto_pwhash_scryptsalsa208sha256_STRBYTES) != + crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1U) { + return -1; + } + if (escrypt_init_local(&escrypt_local) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + memset(wanted, 0, sizeof wanted); + if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen, + (const uint8_t *) str, (uint8_t *) wanted, + sizeof wanted) == NULL) { + escrypt_free_local(&escrypt_local); + return -1; + } + escrypt_free_local(&escrypt_local); + ret = sodium_memcmp(wanted, str, sizeof wanted); + sodium_memzero(wanted, sizeof wanted); + + return ret; +} + +int +crypto_pwhash_scryptsalsa208sha256_str_needs_rehash( + const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + unsigned long long opslimit, size_t memlimit) +{ + uint32_t N_log2, N_log2_; + uint32_t p, p_; + uint32_t r, r_; + + if (pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) { + errno = EINVAL; + return -1; + } + if (sodium_strnlen(str, crypto_pwhash_scryptsalsa208sha256_STRBYTES) != + crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1U) { + errno = EINVAL; + return -1; + } + if (escrypt_parse_setting((const uint8_t *) str, + &N_log2_, &r_, &p_) == NULL) { + errno = EINVAL; + return -1; + } + if (N_log2 != N_log2_ || r != r_ || p != p_) { + return 1; + } + return 0; +} diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c new file mode 100644 index 0000000..890517f --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c @@ -0,0 +1,112 @@ +/*- + * Copyright 2013 Alexander Peslyak + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifdef HAVE_SYS_MMAN_H +#include +#endif +#include +#include + +#include "crypto_scrypt.h" +#include "runtime.h" + +#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS) +# define MAP_ANON MAP_ANONYMOUS +#endif +#ifndef MAP_NOCORE +# ifdef MAP_CONCEAL +# define MAP_NOCORE MAP_CONCEAL +# else +# define MAP_NOCORE 0 +# endif +#endif +#ifndef MAP_POPULATE +# define MAP_POPULATE 0 +#endif + +void * +escrypt_alloc_region(escrypt_region_t *region, size_t size) +{ + uint8_t *base, *aligned; +#if defined(MAP_ANON) && defined(HAVE_MMAP) + if ((base = (uint8_t *) mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_NOCORE | MAP_POPULATE, + -1, 0)) == MAP_FAILED) { + base = NULL; /* LCOV_EXCL_LINE */ + } /* LCOV_EXCL_LINE */ + aligned = base; +#elif defined(HAVE_POSIX_MEMALIGN) + if ((errno = posix_memalign((void **) &base, 64, size)) != 0) { + base = NULL; + } + aligned = base; +#else + base = aligned = NULL; + if (size + 63 < size) { + errno = ENOMEM; + } else if ((base = (uint8_t *) malloc(size + 63)) != NULL) { + aligned = base + 63; + aligned -= (uintptr_t) aligned & 63; + } +#endif + region->base = base; + region->aligned = aligned; + region->size = base ? size : 0; + + return aligned; +} + +static inline void +init_region(escrypt_region_t *region) +{ + region->base = region->aligned = NULL; + region->size = 0; +} + +int +escrypt_free_region(escrypt_region_t *region) +{ + if (region->base) { +#if defined(MAP_ANON) && defined(HAVE_MMAP) + if (munmap(region->base, region->size)) { + return -1; /* LCOV_EXCL_LINE */ + } +#else + free(region->base); +#endif + } + init_region(region); + + return 0; +} + +int +escrypt_init_local(escrypt_local_t *local) +{ + init_region(local); + + return 0; +} + +int +escrypt_free_local(escrypt_local_t *local) +{ + return escrypt_free_region(local); +} diff --git a/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c new file mode 100644 index 0000000..73ee402 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c @@ -0,0 +1,398 @@ +/*- + * Copyright 2009 Colin Percival + * Copyright 2012,2013 Alexander Peslyak + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file was originally written by Colin Percival as part of the Tarsnap + * online backup system. + */ + +#include +#include +#include +#include +#include + +#include "private/common.h" + +#ifdef HAVE_EMMINTRIN_H + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# endif +# include +# if defined(__XOP__) && defined(DISABLED) +# include +# endif +# include "private/sse2_64_32.h" + +# include "../crypto_scrypt.h" +# include "../pbkdf2-sha256.h" + +# define ARX(out, in1, in2, s) \ + { \ + __m128i T = _mm_add_epi32(in1, in2); \ + out = _mm_xor_si128(out, _mm_slli_epi32(T, s)); \ + out = _mm_xor_si128(out, _mm_srli_epi32(T, 32 - s)); \ + } + +# define SALSA20_2ROUNDS \ + /* Operate on "columns". */ \ + ARX(X1, X0, X3, 7) \ + ARX(X2, X1, X0, 9) \ + ARX(X3, X2, X1, 13) \ + ARX(X0, X3, X2, 18) \ + \ + /* Rearrange data. */ \ + X1 = _mm_shuffle_epi32(X1, 0x93); \ + X2 = _mm_shuffle_epi32(X2, 0x4E); \ + X3 = _mm_shuffle_epi32(X3, 0x39); \ + \ + /* Operate on "rows". */ \ + ARX(X3, X0, X1, 7) \ + ARX(X2, X3, X0, 9) \ + ARX(X1, X2, X3, 13) \ + ARX(X0, X1, X2, 18) \ + \ + /* Rearrange data. */ \ + X1 = _mm_shuffle_epi32(X1, 0x39); \ + X2 = _mm_shuffle_epi32(X2, 0x4E); \ + X3 = _mm_shuffle_epi32(X3, 0x93); + +/* + * Apply the salsa20/8 core to the block provided in (X0 ... X3) ^ (Z0 ... Z3). + */ +# define SALSA20_8_XOR(in, out) \ + { \ + __m128i Y0 = X0 = _mm_xor_si128(X0, (in)[0]); \ + __m128i Y1 = X1 = _mm_xor_si128(X1, (in)[1]); \ + __m128i Y2 = X2 = _mm_xor_si128(X2, (in)[2]); \ + __m128i Y3 = X3 = _mm_xor_si128(X3, (in)[3]); \ + SALSA20_2ROUNDS \ + SALSA20_2ROUNDS \ + SALSA20_2ROUNDS \ + SALSA20_2ROUNDS(out)[0] = X0 = _mm_add_epi32(X0, Y0); \ + (out)[1] = X1 = _mm_add_epi32(X1, Y1); \ + (out)[2] = X2 = _mm_add_epi32(X2, Y2); \ + (out)[3] = X3 = _mm_add_epi32(X3, Y3); \ + } + +/* + * blockmix_salsa8(Bin, Bout, r): + * Compute Bout = BlockMix_{salsa20/8, r}(Bin). + * The input Bin must be 128r bytes in length; + * the output Bout must also be the same size. + */ +static inline void +blockmix_salsa8(const __m128i *Bin, __m128i *Bout, size_t r) +{ + __m128i X0, X1, X2, X3; + size_t i; + + /* 1: X <-- B_{2r - 1} */ + X0 = Bin[8 * r - 4]; + X1 = Bin[8 * r - 3]; + X2 = Bin[8 * r - 2]; + X3 = Bin[8 * r - 1]; + + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + SALSA20_8_XOR(Bin, Bout) + + /* 2: for i = 0 to 2r - 1 do */ + r--; + for (i = 0; i < r;) { + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + SALSA20_8_XOR(&Bin[i * 8 + 4], &Bout[(r + i) * 4 + 4]) + + i++; + + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + SALSA20_8_XOR(&Bin[i * 8], &Bout[i * 4]) + } + + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + SALSA20_8_XOR(&Bin[i * 8 + 4], &Bout[(r + i) * 4 + 4]) +} + +# define XOR4(in) \ + X0 = _mm_xor_si128(X0, (in)[0]); \ + X1 = _mm_xor_si128(X1, (in)[1]); \ + X2 = _mm_xor_si128(X2, (in)[2]); \ + X3 = _mm_xor_si128(X3, (in)[3]); + +# define XOR4_2(in1, in2) \ + X0 = _mm_xor_si128((in1)[0], (in2)[0]); \ + X1 = _mm_xor_si128((in1)[1], (in2)[1]); \ + X2 = _mm_xor_si128((in1)[2], (in2)[2]); \ + X3 = _mm_xor_si128((in1)[3], (in2)[3]); + +static inline uint32_t +blockmix_salsa8_xor(const __m128i *Bin1, const __m128i *Bin2, __m128i *Bout, + size_t r) +{ + __m128i X0, X1, X2, X3; + size_t i; + + /* 1: X <-- B_{2r - 1} */ + XOR4_2(&Bin1[8 * r - 4], &Bin2[8 * r - 4]) + + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + XOR4(Bin1) + SALSA20_8_XOR(Bin2, Bout) + + /* 2: for i = 0 to 2r - 1 do */ + r--; + for (i = 0; i < r;) { + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + XOR4(&Bin1[i * 8 + 4]) + SALSA20_8_XOR(&Bin2[i * 8 + 4], &Bout[(r + i) * 4 + 4]) + + i++; + + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + XOR4(&Bin1[i * 8]) + SALSA20_8_XOR(&Bin2[i * 8], &Bout[i * 4]) + } + + /* 3: X <-- H(X \xor B_i) */ + /* 4: Y_i <-- X */ + /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ + XOR4(&Bin1[i * 8 + 4]) + SALSA20_8_XOR(&Bin2[i * 8 + 4], &Bout[(r + i) * 4 + 4]) + + return _mm_cvtsi128_si32(X0); +} + +# undef ARX +# undef SALSA20_2ROUNDS +# undef SALSA20_8_XOR +# undef XOR4 +# undef XOR4_2 + +/* + * integerify(B, r): + * Return the result of parsing B_{2r-1} as a little-endian integer. + * Note that B's layout is permuted compared to the generic implementation. + */ +static inline uint64_t +integerify(const void *B, size_t r) +{ + const uint64_t *X = ((const uint64_t *) B) + (2 * r - 1) * 8; + + return *X; +} + +/* + * smix(B, r, N, V, XY): + * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; + * the temporary storage V must be 128rN bytes in length; the temporary + * storage XY must be 256r + 64 bytes in length. The value N must be a + * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a + * multiple of 64 bytes. + */ +static void +smix(uint8_t *B, size_t r, uint64_t N, void *V, void *XY) +{ + size_t s = 128 * r; + __m128i *X = (__m128i *) V, *Y; + uint32_t *X32 = (uint32_t *) V; + uint64_t i, j; + size_t k; + + /* 1: X <-- B */ + /* 3: V_i <-- X */ + for (k = 0; k < 2 * r; k++) { + for (i = 0; i < 16; i++) { + X32[k * 16 + i] = LOAD32_LE(&B[(k * 16 + (i * 5 % 16)) * 4]); + } + } + + /* 2: for i = 0 to N - 1 do */ + for (i = 1; i < N - 1; i += 2) { + /* 4: X <-- H(X) */ + /* 3: V_i <-- X */ + Y = (__m128i *) ((uintptr_t)(V) + i * s); + blockmix_salsa8(X, Y, r); + + /* 4: X <-- H(X) */ + /* 3: V_i <-- X */ + X = (__m128i *) ((uintptr_t)(V) + (i + 1) * s); + blockmix_salsa8(Y, X, r); + } + + /* 4: X <-- H(X) */ + /* 3: V_i <-- X */ + Y = (__m128i *) ((uintptr_t)(V) + i * s); + blockmix_salsa8(X, Y, r); + + /* 4: X <-- H(X) */ + /* 3: V_i <-- X */ + X = (__m128i *) XY; + blockmix_salsa8(Y, X, r); + + X32 = (uint32_t *) XY; + Y = (__m128i *) ((uintptr_t)(XY) + s); + + /* 7: j <-- Integerify(X) mod N */ + j = integerify(X, r) & (N - 1); + + /* 6: for i = 0 to N - 1 do */ + for (i = 0; i < N; i += 2) { + __m128i *V_j = (__m128i *) ((uintptr_t)(V) + j * s); + + /* 8: X <-- H(X \xor V_j) */ + /* 7: j <-- Integerify(X) mod N */ + j = blockmix_salsa8_xor(X, V_j, Y, r) & (N - 1); + V_j = (__m128i *) ((uintptr_t)(V) + j * s); + + /* 8: X <-- H(X \xor V_j) */ + /* 7: j <-- Integerify(X) mod N */ + j = blockmix_salsa8_xor(Y, V_j, X, r) & (N - 1); + } + + /* 10: B' <-- X */ + for (k = 0; k < 2 * r; k++) { + for (i = 0; i < 16; i++) { + STORE32_LE(&B[(k * 16 + (i * 5 % 16)) * 4], X32[k * 16 + i]); + } + } +} + +/* + * escrypt_kdf(local, passwd, passwdlen, salt, saltlen, + * N, r, p, buf, buflen): + * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, + * p, buflen) and write the result into buf. The parameters r, p, and buflen + * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N + * must be a power of 2 greater than 1. + * + * Return 0 on success; or -1 on error. + */ +int +escrypt_kdf_sse(escrypt_local_t *local, const uint8_t *passwd, size_t passwdlen, + const uint8_t *salt, size_t saltlen, uint64_t N, uint32_t _r, + uint32_t _p, uint8_t *buf, size_t buflen) +{ + size_t B_size, V_size, XY_size, need; + uint8_t * B; + uint32_t *V, *XY; + size_t r = _r, p = _p; + uint32_t i; + +/* Sanity-check parameters. */ +# if SIZE_MAX > UINT32_MAX +/* LCOV_EXCL_START */ + if (buflen > (((uint64_t)(1) << 32) - 1) * 32) { + errno = EFBIG; + return -1; + } +/* LCOV_EXCL_END */ +# endif + if ((uint64_t)(r) * (uint64_t)(p) >= ((uint64_t) 1 << 30)) { + errno = EFBIG; + return -1; + } + if (N > UINT32_MAX) { + errno = EFBIG; + return -1; + } + if (((N & (N - 1)) != 0) || (N < 2)) { + errno = EINVAL; + return -1; + } + if (r == 0 || p == 0) { + errno = EINVAL; + return -1; + } +/* LCOV_EXCL_START */ + if ((r > SIZE_MAX / 128 / p) || +# if SIZE_MAX / 256 <= UINT32_MAX + (r > SIZE_MAX / 256) || +# endif + (N > SIZE_MAX / 128 / r)) { + errno = ENOMEM; + return -1; + } +/* LCOV_EXCL_END */ + + /* Allocate memory. */ + B_size = (size_t) 128 * r * p; + V_size = (size_t) 128 * r * N; + need = B_size + V_size; +/* LCOV_EXCL_START */ + if (need < V_size) { + errno = ENOMEM; + return -1; + } +/* LCOV_EXCL_END */ + XY_size = (size_t) 256 * r + 64; + need += XY_size; +/* LCOV_EXCL_START */ + if (need < XY_size) { + errno = ENOMEM; + return -1; + } +/* LCOV_EXCL_END */ + if (local->size < need) { + if (escrypt_free_region(local)) { + return -1; /* LCOV_EXCL_LINE */ + } + if (!escrypt_alloc_region(local, need)) { + return -1; /* LCOV_EXCL_LINE */ + } + } + B = (uint8_t *) local->aligned; + V = (uint32_t *) ((uint8_t *) B + B_size); + XY = (uint32_t *) ((uint8_t *) V + V_size); + + /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ + escrypt_PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size); + + /* 2: for i = 0 to p - 1 do */ + for (i = 0; i < p; i++) { + /* 3: B_i <-- MF(B_i, N) */ + smix(&B[(size_t) 128 * i * r], r, N, V, XY); + } + + /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ + escrypt_PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen); + + /* Success! */ + return 0; +} +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/crypto_scalarmult.c b/external/src/libsodium/src/libsodium/crypto_scalarmult/crypto_scalarmult.c new file mode 100644 index 0000000..9afffce --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/crypto_scalarmult.c @@ -0,0 +1,33 @@ + +#include "crypto_scalarmult.h" + +const char * +crypto_scalarmult_primitive(void) +{ + return crypto_scalarmult_PRIMITIVE; +} + +int +crypto_scalarmult_base(unsigned char *q, const unsigned char *n) +{ + return crypto_scalarmult_curve25519_base(q, n); +} + +int +crypto_scalarmult(unsigned char *q, const unsigned char *n, + const unsigned char *p) +{ + return crypto_scalarmult_curve25519(q, n, p); +} + +size_t +crypto_scalarmult_bytes(void) +{ + return crypto_scalarmult_BYTES; +} + +size_t +crypto_scalarmult_scalarbytes(void) +{ + return crypto_scalarmult_SCALARBYTES; +} diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.c b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.c new file mode 100644 index 0000000..9eaf023 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.c @@ -0,0 +1,180 @@ + +#include +#include + +#include "../scalarmult_curve25519.h" +#include "export.h" +#include "private/ed25519_ref10.h" +#include "utils.h" +#include "x25519_ref10.h" + +/* + * Reject small order points early to mitigate the implications of + * unexpected optimizations that would affect the ref10 code. + * See https://eprint.iacr.org/2017/806.pdf for reference. + */ +static int +has_small_order(const unsigned char s[32]) +{ + CRYPTO_ALIGN(16) + static const unsigned char blacklist[][32] = { + /* 0 (order 4) */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + /* 1 (order 1) */ + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + /* 325606250916557431795983626356110631294008115727848805560023387167927233504 + (order 8) */ + { 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, + 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, + 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 }, + /* 39382357235489614581723060781553021112529911719440698176882885853963445705823 + (order 8) */ + { 0x5f, 0x9c, 0x95, 0xbc, 0xa3, 0x50, 0x8c, 0x24, 0xb1, 0xd0, 0xb1, + 0x55, 0x9c, 0x83, 0xef, 0x5b, 0x04, 0x44, 0x5c, 0xc4, 0x58, 0x1c, + 0x8e, 0x86, 0xd8, 0x22, 0x4e, 0xdd, 0xd0, 0x9f, 0x11, 0x57 }, + /* p-1 (order 2) */ + { 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, + /* p (=0, order 4) */ + { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, + /* p+1 (=1, order 1) */ + { 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f } + }; + unsigned char c[7] = { 0 }; + unsigned int k; + size_t i, j; + + COMPILER_ASSERT(7 == sizeof blacklist / sizeof blacklist[0]); + for (j = 0; j < 31; j++) { + for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { + c[i] |= s[j] ^ blacklist[i][j]; + } + } + for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { + c[i] |= (s[j] & 0x7f) ^ blacklist[i][j]; + } + k = 0; + for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { + k |= (c[i] - 1); + } + return (int) ((k >> 8) & 1); +} + +static int +crypto_scalarmult_curve25519_ref10(unsigned char *q, + const unsigned char *n, + const unsigned char *p) +{ + unsigned char *t = q; + unsigned int i; + fe25519 x1; + fe25519 x2; + fe25519 z2; + fe25519 x3; + fe25519 z3; + fe25519 tmp0; + fe25519 tmp1; + int pos; + unsigned int swap; + unsigned int b; + + if (has_small_order(p)) { + return -1; + } + for (i = 0; i < 32; i++) { + t[i] = n[i]; + } + t[0] &= 248; + t[31] &= 127; + t[31] |= 64; + fe25519_frombytes(x1, p); + fe25519_1(x2); + fe25519_0(z2); + fe25519_copy(x3, x1); + fe25519_1(z3); + + swap = 0; + for (pos = 254; pos >= 0; --pos) { + b = t[pos / 8] >> (pos & 7); + b &= 1; + swap ^= b; + fe25519_cswap(x2, x3, swap); + fe25519_cswap(z2, z3, swap); + swap = b; + fe25519_sub(tmp0, x3, z3); + fe25519_sub(tmp1, x2, z2); + fe25519_add(x2, x2, z2); + fe25519_add(z2, x3, z3); + fe25519_mul(z3, tmp0, x2); + fe25519_mul(z2, z2, tmp1); + fe25519_sq(tmp0, tmp1); + fe25519_sq(tmp1, x2); + fe25519_add(x3, z3, z2); + fe25519_sub(z2, z3, z2); + fe25519_mul(x2, tmp1, tmp0); + fe25519_sub(tmp1, tmp1, tmp0); + fe25519_sq(z2, z2); + fe25519_mul32(z3, tmp1, 121666); + fe25519_sq(x3, x3); + fe25519_add(tmp0, tmp0, z3); + fe25519_mul(z3, x1, z2); + fe25519_mul(z2, tmp1, tmp0); + } + fe25519_cswap(x2, x3, swap); + fe25519_cswap(z2, z3, swap); + + fe25519_invert(z2, z2); + fe25519_mul(x2, x2, z2); + fe25519_tobytes(q, x2); + + return 0; +} + +static void +edwards_to_montgomery(fe25519 montgomeryX, const fe25519 edwardsY, const fe25519 edwardsZ) +{ + fe25519 tempX; + fe25519 tempZ; + + fe25519_add(tempX, edwardsZ, edwardsY); + fe25519_sub(tempZ, edwardsZ, edwardsY); + fe25519_invert(tempZ, tempZ); + fe25519_mul(montgomeryX, tempX, tempZ); +} + +static int +crypto_scalarmult_curve25519_ref10_base(unsigned char *q, + const unsigned char *n) +{ + unsigned char *t = q; + ge25519_p3 A; + fe25519 pk; + unsigned int i; + + for (i = 0; i < 32; i++) { + t[i] = n[i]; + } + t[0] &= 248; + t[31] &= 127; + t[31] |= 64; + ge25519_scalarmult_base(&A, t); + edwards_to_montgomery(pk, A.Y, A.Z); + fe25519_tobytes(q, pk); + + return 0; +} + +struct crypto_scalarmult_curve25519_implementation + crypto_scalarmult_curve25519_ref10_implementation = { + SODIUM_C99(.mult =) crypto_scalarmult_curve25519_ref10, + SODIUM_C99(.mult_base =) crypto_scalarmult_curve25519_ref10_base + }; diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.h b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.h new file mode 100644 index 0000000..ea52a62 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/ref10/x25519_ref10.h @@ -0,0 +1,10 @@ +#ifndef x25519_ref10_H +#define x25519_ref10_H + +#include "crypto_scalarmult_curve25519.h" +#include "../scalarmult_curve25519.h" + +extern struct crypto_scalarmult_curve25519_implementation + crypto_scalarmult_curve25519_ref10_implementation; + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/consts.S b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/consts.S new file mode 100644 index 0000000..67f1f01 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/consts.S @@ -0,0 +1,25 @@ +#ifdef IN_SANDY2X + +/* + REDMASK51 is from amd64-51/consts.s. +*/ + +#include "consts_namespace.h" +.data +.p2align 4 +v0_0: .quad 0, 0 +v1_0: .quad 1, 0 +v2_1: .quad 2, 1 +v9_0: .quad 9, 0 +v9_9: .quad 9, 9 +v19_19: .quad 19, 19 +v38_1: .quad 38, 1 +v38_38: .quad 38, 38 +v121666_121666: .quad 121666, 121666 +m25: .quad 33554431, 33554431 +m26: .quad 67108863, 67108863 +subc0: .quad 0x07FFFFDA, 0x03FFFFFE +subc2: .quad 0x07FFFFFE, 0x03FFFFFE +REDMASK51: .quad 0x0007FFFFFFFFFFFF + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/consts_namespace.h b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/consts_namespace.h new file mode 100644 index 0000000..9f81fa6 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/consts_namespace.h @@ -0,0 +1,20 @@ +#ifndef consts_namespace_H +#define consts_namespace_H + +#define v0_0 crypto_scalarmult_curve25519_sandy2x_v0_0 +#define v1_0 crypto_scalarmult_curve25519_sandy2x_v1_0 +#define v2_1 crypto_scalarmult_curve25519_sandy2x_v2_1 +#define v9_0 crypto_scalarmult_curve25519_sandy2x_v9_0 +#define v9_9 crypto_scalarmult_curve25519_sandy2x_v9_9 +#define v19_19 crypto_scalarmult_curve25519_sandy2x_v19_19 +#define v38_1 crypto_scalarmult_curve25519_sandy2x_v38_1 +#define v38_38 crypto_scalarmult_curve25519_sandy2x_v38_38 +#define v121666_121666 crypto_scalarmult_curve25519_sandy2x_v121666_121666 +#define m25 crypto_scalarmult_curve25519_sandy2x_m25 +#define m26 crypto_scalarmult_curve25519_sandy2x_m26 +#define subc0 crypto_scalarmult_curve25519_sandy2x_subc0 +#define subc2 crypto_scalarmult_curve25519_sandy2x_subc2 +#define REDMASK51 crypto_scalarmult_curve25519_sandy2x_REDMASK51 + +#endif /* ifndef consts_namespace_H */ + diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c new file mode 100644 index 0000000..0f8f8b1 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c @@ -0,0 +1,69 @@ +/* + This file is adapted from ref10/scalarmult.c: + The code for Mongomery ladder is replace by the ladder assembly function; + Inversion is done in the same way as amd64-51/. + (fe is first converted into fe51 after Mongomery ladder) +*/ + +#include + +#ifdef HAVE_AVX_ASM + +#include "utils.h" +#include "curve25519_sandy2x.h" +#include "../scalarmult_curve25519.h" +#include "fe.h" +#include "fe51.h" +#include "ladder.h" + +#define x1 var[0] +#define x2 var[1] +#define z2 var[2] + +static int +crypto_scalarmult_curve25519_sandy2x(unsigned char *q, const unsigned char *n, + const unsigned char *p) +{ + unsigned char *t = q; + fe var[3]; + fe51 x_51; + fe51 z_51; + unsigned int i; + + for (i = 0; i < 32; i++) { + t[i] = n[i]; + } + t[0] &= 248; + t[31] &= 127; + t[31] |= 64; + + fe_frombytes(x1, p); + + ladder(var, t); + + z_51.v[0] = (z2[1] << 26) + z2[0]; + z_51.v[1] = (z2[3] << 26) + z2[2]; + z_51.v[2] = (z2[5] << 26) + z2[4]; + z_51.v[3] = (z2[7] << 26) + z2[6]; + z_51.v[4] = (z2[9] << 26) + z2[8]; + + x_51.v[0] = (x2[1] << 26) + x2[0]; + x_51.v[1] = (x2[3] << 26) + x2[2]; + x_51.v[2] = (x2[5] << 26) + x2[4]; + x_51.v[3] = (x2[7] << 26) + x2[6]; + x_51.v[4] = (x2[9] << 26) + x2[8]; + + fe51_invert(&z_51, &z_51); + fe51_mul(&x_51, &x_51, &z_51); + fe51_pack(q, &x_51); + + return 0; +} + +struct crypto_scalarmult_curve25519_implementation +crypto_scalarmult_curve25519_sandy2x_implementation = { + SODIUM_C99(.mult = ) crypto_scalarmult_curve25519_sandy2x, + SODIUM_C99(.mult_base = ) NULL +}; + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.h b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.h new file mode 100644 index 0000000..f02d980 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.h @@ -0,0 +1,9 @@ +#ifndef curve25519_sandy2x_H +#define curve25519_sandy2x_H + +#include "crypto_scalarmult_curve25519.h" + +extern struct crypto_scalarmult_curve25519_implementation + crypto_scalarmult_curve25519_sandy2x_implementation; + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe.h b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe.h new file mode 100644 index 0000000..b1115f8 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe.h @@ -0,0 +1,26 @@ +/* + This file is adapted from ref10/fe.h: + All the redundant functions are removed. +*/ + +#ifndef fe_H +#define fe_H + +#include +#include + +typedef uint64_t fe[10]; + +/* +fe means field element. +Here the field is \Z/(2^255-19). +An element t, entries t[0]...t[9], represents the integer +t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. +Bounds on each t[i] vary depending on context. +*/ + +#define fe_frombytes crypto_scalarmult_curve25519_sandy2x_fe_frombytes + +extern void fe_frombytes(fe, const unsigned char *); + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51.h b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51.h new file mode 100644 index 0000000..8e3f199 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51.h @@ -0,0 +1,35 @@ +/* + This file is adapted from amd64-51/fe25519.h: + 'fe25519' is renamed as 'fe51'; + All the redundant functions are removed; + New function fe51_nsquare is introduced. +*/ + +#ifndef fe51_H +#define fe51_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "fe51_namespace.h" + +typedef struct +{ + uint64_t v[5]; +} +fe51; + +extern void fe51_pack(unsigned char *, const fe51 *); +extern void fe51_mul(fe51 *, const fe51 *, const fe51 *); +extern void fe51_nsquare(fe51 *, const fe51 *, int); +extern void fe51_invert(fe51 *, const fe51 *); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_invert.c b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_invert.c new file mode 100644 index 0000000..ec9bb1a --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_invert.c @@ -0,0 +1,58 @@ +/* + This file is adapted from amd64-51/fe25519_invert.c: + Loops of squares are replaced by nsquares for better performance. +*/ + +#include "fe51.h" + +#ifdef HAVE_AVX_ASM + +#define fe51_square(x, y) fe51_nsquare(x, y, 1) + +void +fe51_invert(fe51 *r, const fe51 *x) +{ + fe51 z2; + fe51 z9; + fe51 z11; + fe51 z2_5_0; + fe51 z2_10_0; + fe51 z2_20_0; + fe51 z2_50_0; + fe51 z2_100_0; + fe51 t; + + /* 2 */ fe51_square(&z2,x); + /* 4 */ fe51_square(&t,&z2); + /* 8 */ fe51_square(&t,&t); + /* 9 */ fe51_mul(&z9,&t,x); + /* 11 */ fe51_mul(&z11,&z9,&z2); + /* 22 */ fe51_square(&t,&z11); + /* 2^5 - 2^0 = 31 */ fe51_mul(&z2_5_0,&t,&z9); + + /* 2^10 - 2^5 */ fe51_nsquare(&t,&z2_5_0, 5); + /* 2^10 - 2^0 */ fe51_mul(&z2_10_0,&t,&z2_5_0); + + /* 2^20 - 2^10 */ fe51_nsquare(&t,&z2_10_0, 10); + /* 2^20 - 2^0 */ fe51_mul(&z2_20_0,&t,&z2_10_0); + + /* 2^40 - 2^20 */ fe51_nsquare(&t,&z2_20_0, 20); + /* 2^40 - 2^0 */ fe51_mul(&t,&t,&z2_20_0); + + /* 2^50 - 2^10 */ fe51_nsquare(&t,&t,10); + /* 2^50 - 2^0 */ fe51_mul(&z2_50_0,&t,&z2_10_0); + + /* 2^100 - 2^50 */ fe51_nsquare(&t,&z2_50_0, 50); + /* 2^100 - 2^0 */ fe51_mul(&z2_100_0,&t,&z2_50_0); + + /* 2^200 - 2^100 */ fe51_nsquare(&t,&z2_100_0, 100); + /* 2^200 - 2^0 */ fe51_mul(&t,&t,&z2_100_0); + + /* 2^250 - 2^50 */ fe51_nsquare(&t,&t, 50); + /* 2^250 - 2^0 */ fe51_mul(&t,&t,&z2_50_0); + + /* 2^255 - 2^5 */ fe51_nsquare(&t,&t,5); + /* 2^255 - 21 */ fe51_mul(r,&t,&z11); +} + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_mul.S b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_mul.S new file mode 100644 index 0000000..83501b0 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_mul.S @@ -0,0 +1,197 @@ +#ifdef IN_SANDY2X + +/* + This file is basically amd64-51/fe25519_mul.s. +*/ +#include "fe51_namespace.h" +#include "consts_namespace.h" +.text +.p2align 5 +#ifdef ASM_HIDE_SYMBOL +ASM_HIDE_SYMBOL fe51_mul +ASM_HIDE_SYMBOL _fe51_mul +#endif +.globl fe51_mul +.globl _fe51_mul +#ifdef __ELF__ +.type fe51_mul, @function +.type _fe51_mul, @function +#endif +fe51_mul: +_fe51_mul: +mov %rsp,%r11 +and $31,%r11 +add $96,%r11 +sub %r11,%rsp +movq %r11,0(%rsp) +movq %r12,8(%rsp) +movq %r13,16(%rsp) +movq %r14,24(%rsp) +movq %r15,32(%rsp) +movq %rbx,40(%rsp) +movq %rbp,48(%rsp) +movq %rdi,56(%rsp) +mov %rdx,%rcx +movq 24(%rsi),%rdx +imulq $19,%rdx,%rax +movq %rax,64(%rsp) +mulq 16(%rcx) +mov %rax,%r8 +mov %rdx,%r9 +movq 32(%rsi),%rdx +imulq $19,%rdx,%rax +movq %rax,72(%rsp) +mulq 8(%rcx) +add %rax,%r8 +adc %rdx,%r9 +movq 0(%rsi),%rax +mulq 0(%rcx) +add %rax,%r8 +adc %rdx,%r9 +movq 0(%rsi),%rax +mulq 8(%rcx) +mov %rax,%r10 +mov %rdx,%r11 +movq 0(%rsi),%rax +mulq 16(%rcx) +mov %rax,%r12 +mov %rdx,%r13 +movq 0(%rsi),%rax +mulq 24(%rcx) +mov %rax,%r14 +mov %rdx,%r15 +movq 0(%rsi),%rax +mulq 32(%rcx) +mov %rax,%rbx +mov %rdx,%rbp +movq 8(%rsi),%rax +mulq 0(%rcx) +add %rax,%r10 +adc %rdx,%r11 +movq 8(%rsi),%rax +mulq 8(%rcx) +add %rax,%r12 +adc %rdx,%r13 +movq 8(%rsi),%rax +mulq 16(%rcx) +add %rax,%r14 +adc %rdx,%r15 +movq 8(%rsi),%rax +mulq 24(%rcx) +add %rax,%rbx +adc %rdx,%rbp +movq 8(%rsi),%rdx +imulq $19,%rdx,%rax +mulq 32(%rcx) +add %rax,%r8 +adc %rdx,%r9 +movq 16(%rsi),%rax +mulq 0(%rcx) +add %rax,%r12 +adc %rdx,%r13 +movq 16(%rsi),%rax +mulq 8(%rcx) +add %rax,%r14 +adc %rdx,%r15 +movq 16(%rsi),%rax +mulq 16(%rcx) +add %rax,%rbx +adc %rdx,%rbp +movq 16(%rsi),%rdx +imulq $19,%rdx,%rax +mulq 24(%rcx) +add %rax,%r8 +adc %rdx,%r9 +movq 16(%rsi),%rdx +imulq $19,%rdx,%rax +mulq 32(%rcx) +add %rax,%r10 +adc %rdx,%r11 +movq 24(%rsi),%rax +mulq 0(%rcx) +add %rax,%r14 +adc %rdx,%r15 +movq 24(%rsi),%rax +mulq 8(%rcx) +add %rax,%rbx +adc %rdx,%rbp +movq 64(%rsp),%rax +mulq 24(%rcx) +add %rax,%r10 +adc %rdx,%r11 +movq 64(%rsp),%rax +mulq 32(%rcx) +add %rax,%r12 +adc %rdx,%r13 +movq 32(%rsi),%rax +mulq 0(%rcx) +add %rax,%rbx +adc %rdx,%rbp +movq 72(%rsp),%rax +mulq 16(%rcx) +add %rax,%r10 +adc %rdx,%r11 +movq 72(%rsp),%rax +mulq 24(%rcx) +add %rax,%r12 +adc %rdx,%r13 +movq 72(%rsp),%rax +mulq 32(%rcx) +add %rax,%r14 +adc %rdx,%r15 +movq REDMASK51(%rip),%rsi +shld $13,%r8,%r9 +and %rsi,%r8 +shld $13,%r10,%r11 +and %rsi,%r10 +add %r9,%r10 +shld $13,%r12,%r13 +and %rsi,%r12 +add %r11,%r12 +shld $13,%r14,%r15 +and %rsi,%r14 +add %r13,%r14 +shld $13,%rbx,%rbp +and %rsi,%rbx +add %r15,%rbx +imulq $19,%rbp,%rdx +add %rdx,%r8 +mov %r8,%rdx +shr $51,%rdx +add %r10,%rdx +mov %rdx,%rcx +shr $51,%rdx +and %rsi,%r8 +add %r12,%rdx +mov %rdx,%r9 +shr $51,%rdx +and %rsi,%rcx +add %r14,%rdx +mov %rdx,%rax +shr $51,%rdx +and %rsi,%r9 +add %rbx,%rdx +mov %rdx,%r10 +shr $51,%rdx +and %rsi,%rax +imulq $19,%rdx,%rdx +add %rdx,%r8 +and %rsi,%r10 +movq %r8,0(%rdi) +movq %rcx,8(%rdi) +movq %r9,16(%rdi) +movq %rax,24(%rdi) +movq %r10,32(%rdi) +movq 0(%rsp),%r11 +movq 8(%rsp),%r12 +movq 16(%rsp),%r13 +movq 24(%rsp),%r14 +movq 32(%rsp),%r15 +movq 40(%rsp),%rbx +movq 48(%rsp),%rbp +add %r11,%rsp +mov %rdi,%rax +mov %rsi,%rdx +ret + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_namespace.h b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_namespace.h new file mode 100644 index 0000000..057f242 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_namespace.h @@ -0,0 +1,16 @@ +#ifndef fe51_namespace_H +#define fe51_namespace_H + +#define fe51 crypto_scalarmult_curve25519_sandy2x_fe51 +#define _fe51 _crypto_scalarmult_curve25519_sandy2x_fe51 +#define fe51_pack crypto_scalarmult_curve25519_sandy2x_fe51_pack +#define _fe51_pack _crypto_scalarmult_curve25519_sandy2x_fe51_pack +#define fe51_mul crypto_scalarmult_curve25519_sandy2x_fe51_mul +#define _fe51_mul _crypto_scalarmult_curve25519_sandy2x_fe51_mul +#define fe51_nsquare crypto_scalarmult_curve25519_sandy2x_fe51_nsquare +#define _fe51_nsquare _crypto_scalarmult_curve25519_sandy2x_fe51_nsquare + +#define fe51_invert crypto_scalarmult_curve25519_sandy2x_fe51_invert + +#endif /* ifndef fe51_namespace_H */ + diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_nsquare.S b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_nsquare.S new file mode 100644 index 0000000..41c3054 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_nsquare.S @@ -0,0 +1,172 @@ +#ifdef IN_SANDY2X + +/* + This file is adapted from amd64-51/fe25519_square.s: + Adding loop to perform n squares. +*/ +#include "fe51_namespace.h" +#include "consts_namespace.h" +.p2align 5 + +#ifdef ASM_HIDE_SYMBOL +ASM_HIDE_SYMBOL fe51_nsquare +ASM_HIDE_SYMBOL _fe51_nsquare +#endif +.globl fe51_nsquare +.globl _fe51_nsquare +#ifdef __ELF__ +.type fe51_nsquare, @function +.type _fe51_nsquare, @function +#endif +fe51_nsquare: +_fe51_nsquare: + +mov %rsp,%r11 +and $31,%r11 +add $64,%r11 +sub %r11,%rsp +movq %r11,0(%rsp) +movq %r12,8(%rsp) +movq %r13,16(%rsp) +movq %r14,24(%rsp) +movq %r15,32(%rsp) +movq %rbx,40(%rsp) +movq %rbp,48(%rsp) +movq 0(%rsi),%rcx +movq 8(%rsi),%r8 +movq 16(%rsi),%r9 +movq 24(%rsi),%rax +movq 32(%rsi),%rsi +movq %r9,16(%rdi) +movq %rax,24(%rdi) +movq %rsi,32(%rdi) +mov %rdx,%rsi + +.p2align 4 +._loop: +sub $1,%rsi +mov %rcx,%rax +mul %rcx +add %rcx,%rcx +mov %rax,%r9 +mov %rdx,%r10 +mov %rcx,%rax +mul %r8 +mov %rax,%r11 +mov %rdx,%r12 +mov %rcx,%rax +mulq 16(%rdi) +mov %rax,%r13 +mov %rdx,%r14 +mov %rcx,%rax +mulq 24(%rdi) +mov %rax,%r15 +mov %rdx,%rbx +mov %rcx,%rax +mulq 32(%rdi) +mov %rax,%rcx +mov %rdx,%rbp +mov %r8,%rax +mul %r8 +add %r8,%r8 +add %rax,%r13 +adc %rdx,%r14 +mov %r8,%rax +mulq 16(%rdi) +add %rax,%r15 +adc %rdx,%rbx +mov %r8,%rax +imulq $19, %r8,%r8 +mulq 24(%rdi) +add %rax,%rcx +adc %rdx,%rbp +mov %r8,%rax +mulq 32(%rdi) +add %rax,%r9 +adc %rdx,%r10 +movq 16(%rdi),%rax +mulq 16(%rdi) +add %rax,%rcx +adc %rdx,%rbp +shld $13,%rcx,%rbp +movq 16(%rdi),%rax +imulq $38, %rax,%rax +mulq 24(%rdi) +add %rax,%r9 +adc %rdx,%r10 +shld $13,%r9,%r10 +movq 16(%rdi),%rax +imulq $38, %rax,%rax +mulq 32(%rdi) +add %rax,%r11 +adc %rdx,%r12 +movq 24(%rdi),%rax +imulq $19, %rax,%rax +mulq 24(%rdi) +add %rax,%r11 +adc %rdx,%r12 +shld $13,%r11,%r12 +movq 24(%rdi),%rax +imulq $38, %rax,%rax +mulq 32(%rdi) +add %rax,%r13 +adc %rdx,%r14 +shld $13,%r13,%r14 +movq 32(%rdi),%rax +imulq $19, %rax,%rax +mulq 32(%rdi) +add %rax,%r15 +adc %rdx,%rbx +shld $13,%r15,%rbx +movq REDMASK51(%rip),%rdx +and %rdx,%rcx +add %rbx,%rcx +and %rdx,%r9 +and %rdx,%r11 +add %r10,%r11 +and %rdx,%r13 +add %r12,%r13 +and %rdx,%r15 +add %r14,%r15 +imulq $19, %rbp,%rbp +lea (%r9,%rbp),%r9 +mov %r9,%rax +shr $51,%r9 +add %r11,%r9 +and %rdx,%rax +mov %r9,%r8 +shr $51,%r9 +add %r13,%r9 +and %rdx,%r8 +mov %r9,%r10 +shr $51,%r9 +add %r15,%r9 +and %rdx,%r10 +movq %r10,16(%rdi) +mov %r9,%r10 +shr $51,%r9 +add %rcx,%r9 +and %rdx,%r10 +movq %r10,24(%rdi) +mov %r9,%r10 +shr $51,%r9 +imulq $19, %r9,%r9 +lea (%rax,%r9),%rcx +and %rdx,%r10 +movq %r10,32(%rdi) +cmp $0,%rsi +jne ._loop + +movq %rcx,0(%rdi) +movq %r8,8(%rdi) +movq 0(%rsp),%r11 +movq 8(%rsp),%r12 +movq 16(%rsp),%r13 +movq 24(%rsp),%r14 +movq 32(%rsp),%r15 +movq 40(%rsp),%rbx +movq 48(%rsp),%rbp +add %r11,%rsp +ret + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_pack.S b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_pack.S new file mode 100644 index 0000000..500c858 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe51_pack.S @@ -0,0 +1,226 @@ +#ifdef IN_SANDY2X + +/* + This file is the result of merging + amd64-51/fe25519_pack.c and amd64-51/fe25519_freeze.s. +*/ +#include "fe51_namespace.h" +#include "consts_namespace.h" +.p2align 5 + +#ifdef ASM_HIDE_SYMBOL +ASM_HIDE_SYMBOL fe51_pack +ASM_HIDE_SYMBOL _fe51_pack +#endif +.globl fe51_pack +.globl _fe51_pack +#ifdef __ELF__ +.type fe51_pack, @function +.type _fe51_pack, @function +#endif +fe51_pack: +_fe51_pack: + +mov %rsp,%r11 +and $31,%r11 +add $32,%r11 +sub %r11,%rsp +movq %r11,0(%rsp) +movq %r12,8(%rsp) +movq 0(%rsi),%rdx +movq 8(%rsi),%rcx +movq 16(%rsi),%r8 +movq 24(%rsi),%r9 +movq 32(%rsi),%rsi +movq REDMASK51(%rip),%rax +lea -18(%rax),%r10 +mov $3,%r11 + +.p2align 4 +._reduceloop: +mov %rdx,%r12 +shr $51,%r12 +and %rax,%rdx +add %r12,%rcx +mov %rcx,%r12 +shr $51,%r12 +and %rax,%rcx +add %r12,%r8 +mov %r8,%r12 +shr $51,%r12 +and %rax,%r8 +add %r12,%r9 +mov %r9,%r12 +shr $51,%r12 +and %rax,%r9 +add %r12,%rsi +mov %rsi,%r12 +shr $51,%r12 +and %rax,%rsi +imulq $19, %r12,%r12 +add %r12,%rdx +sub $1,%r11 +ja ._reduceloop + +mov $1,%r12 +cmp %r10,%rdx +cmovl %r11,%r12 +cmp %rax,%rcx +cmovne %r11,%r12 +cmp %rax,%r8 +cmovne %r11,%r12 +cmp %rax,%r9 +cmovne %r11,%r12 +cmp %rax,%rsi +cmovne %r11,%r12 +neg %r12 +and %r12,%rax +and %r12,%r10 +sub %r10,%rdx +sub %rax,%rcx +sub %rax,%r8 +sub %rax,%r9 +sub %rax,%rsi +mov %rdx,%rax +and $0xFF,%eax +movb %al,0(%rdi) +mov %rdx,%rax +shr $8,%rax +and $0xFF,%eax +movb %al,1(%rdi) +mov %rdx,%rax +shr $16,%rax +and $0xFF,%eax +movb %al,2(%rdi) +mov %rdx,%rax +shr $24,%rax +and $0xFF,%eax +movb %al,3(%rdi) +mov %rdx,%rax +shr $32,%rax +and $0xFF,%eax +movb %al,4(%rdi) +mov %rdx,%rax +shr $40,%rax +and $0xFF,%eax +movb %al,5(%rdi) +mov %rdx,%rdx +shr $48,%rdx +mov %rcx,%rax +shl $3,%rax +and $0xF8,%eax +xor %rdx,%rax +movb %al,6(%rdi) +mov %rcx,%rdx +shr $5,%rdx +and $0xFF,%edx +movb %dl,7(%rdi) +mov %rcx,%rdx +shr $13,%rdx +and $0xFF,%edx +movb %dl,8(%rdi) +mov %rcx,%rdx +shr $21,%rdx +and $0xFF,%edx +movb %dl,9(%rdi) +mov %rcx,%rdx +shr $29,%rdx +and $0xFF,%edx +movb %dl,10(%rdi) +mov %rcx,%rdx +shr $37,%rdx +and $0xFF,%edx +movb %dl,11(%rdi) +mov %rcx,%rdx +shr $45,%rdx +mov %r8,%rcx +shl $6,%rcx +and $0xC0,%ecx +xor %rdx,%rcx +movb %cl,12(%rdi) +mov %r8,%rdx +shr $2,%rdx +and $0xFF,%edx +movb %dl,13(%rdi) +mov %r8,%rdx +shr $10,%rdx +and $0xFF,%edx +movb %dl,14(%rdi) +mov %r8,%rdx +shr $18,%rdx +and $0xFF,%edx +movb %dl,15(%rdi) +mov %r8,%rdx +shr $26,%rdx +and $0xFF,%edx +movb %dl,16(%rdi) +mov %r8,%rdx +shr $34,%rdx +and $0xFF,%edx +movb %dl,17(%rdi) +mov %r8,%rdx +shr $42,%rdx +movb %dl,18(%rdi) +mov %r8,%rdx +shr $50,%rdx +mov %r9,%rcx +shl $1,%rcx +and $0xFE,%ecx +xor %rdx,%rcx +movb %cl,19(%rdi) +mov %r9,%rdx +shr $7,%rdx +and $0xFF,%edx +movb %dl,20(%rdi) +mov %r9,%rdx +shr $15,%rdx +and $0xFF,%edx +movb %dl,21(%rdi) +mov %r9,%rdx +shr $23,%rdx +and $0xFF,%edx +movb %dl,22(%rdi) +mov %r9,%rdx +shr $31,%rdx +and $0xFF,%edx +movb %dl,23(%rdi) +mov %r9,%rdx +shr $39,%rdx +and $0xFF,%edx +movb %dl,24(%rdi) +mov %r9,%rdx +shr $47,%rdx +mov %rsi,%rcx +shl $4,%rcx +and $0xF0,%ecx +xor %rdx,%rcx +movb %cl,25(%rdi) +mov %rsi,%rdx +shr $4,%rdx +and $0xFF,%edx +movb %dl,26(%rdi) +mov %rsi,%rdx +shr $12,%rdx +and $0xFF,%edx +movb %dl,27(%rdi) +mov %rsi,%rdx +shr $20,%rdx +and $0xFF,%edx +movb %dl,28(%rdi) +mov %rsi,%rdx +shr $28,%rdx +and $0xFF,%edx +movb %dl,29(%rdi) +mov %rsi,%rdx +shr $36,%rdx +and $0xFF,%edx +movb %dl,30(%rdi) +mov %rsi,%rsi +shr $44,%rsi +movb %sil,31(%rdi) +movq 0(%rsp),%r11 +movq 8(%rsp),%r12 +add %r11,%rsp +ret + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c new file mode 100644 index 0000000..2fe081e --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c @@ -0,0 +1,78 @@ +/* + This file is basically ref10/fe_frombytes.h. +*/ + +#include "fe.h" + +#ifdef HAVE_AVX_ASM + +static uint64_t +load_3(const unsigned char *in) +{ + uint64_t result; + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + return result; +} + +static uint64_t +load_4(const unsigned char *in) +{ + uint64_t result; + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + result |= ((uint64_t) in[3]) << 24; + return result; +} + +void +fe_frombytes(fe h, const unsigned char *s) +{ + uint64_t h0 = load_4(s); + uint64_t h1 = load_3(s + 4) << 6; + uint64_t h2 = load_3(s + 7) << 5; + uint64_t h3 = load_3(s + 10) << 3; + uint64_t h4 = load_3(s + 13) << 2; + uint64_t h5 = load_4(s + 16); + uint64_t h6 = load_3(s + 20) << 7; + uint64_t h7 = load_3(s + 23) << 5; + uint64_t h8 = load_3(s + 26) << 4; + uint64_t h9 = (load_3(s + 29) & 8388607) << 2; + uint64_t carry0; + uint64_t carry1; + uint64_t carry2; + uint64_t carry3; + uint64_t carry4; + uint64_t carry5; + uint64_t carry6; + uint64_t carry7; + uint64_t carry8; + uint64_t carry9; + + carry9 = h9 >> 25; h0 += carry9 * 19; h9 &= 0x1FFFFFF; + carry1 = h1 >> 25; h2 += carry1; h1 &= 0x1FFFFFF; + carry3 = h3 >> 25; h4 += carry3; h3 &= 0x1FFFFFF; + carry5 = h5 >> 25; h6 += carry5; h5 &= 0x1FFFFFF; + carry7 = h7 >> 25; h8 += carry7; h7 &= 0x1FFFFFF; + + carry0 = h0 >> 26; h1 += carry0; h0 &= 0x3FFFFFF; + carry2 = h2 >> 26; h3 += carry2; h2 &= 0x3FFFFFF; + carry4 = h4 >> 26; h5 += carry4; h4 &= 0x3FFFFFF; + carry6 = h6 >> 26; h7 += carry6; h6 &= 0x3FFFFFF; + carry8 = h8 >> 26; h9 += carry8; h8 &= 0x3FFFFFF; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/ladder.S b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/ladder.S new file mode 100644 index 0000000..c5c0602 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/ladder.S @@ -0,0 +1,1440 @@ +#ifdef IN_SANDY2X + +#include "ladder_namespace.h" +#include "consts_namespace.h" +.p2align 5 + +#ifdef ASM_HIDE_SYMBOL +ASM_HIDE_SYMBOL ladder +ASM_HIDE_SYMBOL _ladder +#endif +.globl ladder +.globl _ladder +#ifdef __ELF__ +.type ladder, @function +.type _ladder, @function +#endif +ladder: +_ladder: + +mov %rsp,%r11 +and $31,%r11 +add $1856,%r11 +sub %r11,%rsp +movq %r11,1824(%rsp) +movq %r12,1832(%rsp) +movq %r13,1840(%rsp) +movq %r14,1848(%rsp) +vmovdqa v0_0(%rip),%xmm0 +vmovdqa v1_0(%rip),%xmm1 +vmovdqu 0(%rdi),%xmm2 +vmovdqa %xmm2,0(%rsp) +vmovdqu 16(%rdi),%xmm2 +vmovdqa %xmm2,16(%rsp) +vmovdqu 32(%rdi),%xmm2 +vmovdqa %xmm2,32(%rsp) +vmovdqu 48(%rdi),%xmm2 +vmovdqa %xmm2,48(%rsp) +vmovdqu 64(%rdi),%xmm2 +vmovdqa %xmm2,64(%rsp) +vmovdqa %xmm1,80(%rsp) +vmovdqa %xmm0,96(%rsp) +vmovdqa %xmm0,112(%rsp) +vmovdqa %xmm0,128(%rsp) +vmovdqa %xmm0,144(%rsp) +vmovdqa %xmm1,%xmm0 +vpxor %xmm1,%xmm1,%xmm1 +vpxor %xmm2,%xmm2,%xmm2 +vpxor %xmm3,%xmm3,%xmm3 +vpxor %xmm4,%xmm4,%xmm4 +vpxor %xmm5,%xmm5,%xmm5 +vpxor %xmm6,%xmm6,%xmm6 +vpxor %xmm7,%xmm7,%xmm7 +vpxor %xmm8,%xmm8,%xmm8 +vpxor %xmm9,%xmm9,%xmm9 +vmovdqu 0(%rdi),%xmm10 +vmovdqa %xmm10,160(%rsp) +vmovdqu 16(%rdi),%xmm10 +vmovdqa %xmm10,176(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,192(%rsp) +vmovdqu 32(%rdi),%xmm10 +vmovdqa %xmm10,208(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,224(%rsp) +vmovdqu 48(%rdi),%xmm10 +vmovdqa %xmm10,240(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,256(%rsp) +vmovdqu 64(%rdi),%xmm10 +vmovdqa %xmm10,272(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,288(%rsp) +vmovdqu 8(%rdi),%xmm10 +vpmuludq v2_1(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,304(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,320(%rsp) +vmovdqu 24(%rdi),%xmm10 +vpmuludq v2_1(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,336(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,352(%rsp) +vmovdqu 40(%rdi),%xmm10 +vpmuludq v2_1(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,368(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,384(%rsp) +vmovdqu 56(%rdi),%xmm10 +vpmuludq v2_1(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,400(%rsp) +vpmuludq v19_19(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,416(%rsp) +vmovdqu 0(%rdi),%xmm10 +vmovdqu 64(%rdi),%xmm11 +vblendps $12, %xmm11, %xmm10, %xmm10 +vpshufd $2,%xmm10,%xmm10 +vpmuludq v38_1(%rip),%xmm10,%xmm10 +vmovdqa %xmm10,432(%rsp) +movq 0(%rsi),%rdx +movq 8(%rsi),%rcx +movq 16(%rsi),%r8 +movq 24(%rsi),%r9 +shrd $1,%rcx,%rdx +shrd $1,%r8,%rcx +shrd $1,%r9,%r8 +shr $1,%r9 +xorq 0(%rsi),%rdx +xorq 8(%rsi),%rcx +xorq 16(%rsi),%r8 +xorq 24(%rsi),%r9 +leaq 800(%rsp),%rsi +mov $64,%rax + +.p2align 4 +._ladder_small_loop: +mov %rdx,%r10 +mov %rcx,%r11 +mov %r8,%r12 +mov %r9,%r13 +shr $1,%rdx +shr $1,%rcx +shr $1,%r8 +shr $1,%r9 +and $1,%r10d +and $1,%r11d +and $1,%r12d +and $1,%r13d +neg %r10 +neg %r11 +neg %r12 +neg %r13 +movl %r10d,0(%rsi) +movl %r11d,256(%rsi) +movl %r12d,512(%rsi) +movl %r13d,768(%rsi) +add $4,%rsi +sub $1,%rax +jne ._ladder_small_loop +mov $255,%rdx +add $760,%rsi + +.p2align 4 +._ladder_loop: +sub $1,%rdx +vbroadcastss 0(%rsi),%xmm10 +sub $4,%rsi +vmovdqa 0(%rsp),%xmm11 +vmovdqa 80(%rsp),%xmm12 +vpxor %xmm11,%xmm0,%xmm13 +vpand %xmm10,%xmm13,%xmm13 +vpxor %xmm13,%xmm0,%xmm0 +vpxor %xmm13,%xmm11,%xmm11 +vpxor %xmm12,%xmm1,%xmm13 +vpand %xmm10,%xmm13,%xmm13 +vpxor %xmm13,%xmm1,%xmm1 +vpxor %xmm13,%xmm12,%xmm12 +vmovdqa 16(%rsp),%xmm13 +vmovdqa 96(%rsp),%xmm14 +vpxor %xmm13,%xmm2,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm2,%xmm2 +vpxor %xmm15,%xmm13,%xmm13 +vpxor %xmm14,%xmm3,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm3,%xmm3 +vpxor %xmm15,%xmm14,%xmm14 +vmovdqa %xmm13,0(%rsp) +vmovdqa %xmm14,16(%rsp) +vmovdqa 32(%rsp),%xmm13 +vmovdqa 112(%rsp),%xmm14 +vpxor %xmm13,%xmm4,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm4,%xmm4 +vpxor %xmm15,%xmm13,%xmm13 +vpxor %xmm14,%xmm5,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm5,%xmm5 +vpxor %xmm15,%xmm14,%xmm14 +vmovdqa %xmm13,32(%rsp) +vmovdqa %xmm14,80(%rsp) +vmovdqa 48(%rsp),%xmm13 +vmovdqa 128(%rsp),%xmm14 +vpxor %xmm13,%xmm6,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm6,%xmm6 +vpxor %xmm15,%xmm13,%xmm13 +vpxor %xmm14,%xmm7,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm7,%xmm7 +vpxor %xmm15,%xmm14,%xmm14 +vmovdqa %xmm13,48(%rsp) +vmovdqa %xmm14,96(%rsp) +vmovdqa 64(%rsp),%xmm13 +vmovdqa 144(%rsp),%xmm14 +vpxor %xmm13,%xmm8,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm8,%xmm8 +vpxor %xmm15,%xmm13,%xmm13 +vpxor %xmm14,%xmm9,%xmm15 +vpand %xmm10,%xmm15,%xmm15 +vpxor %xmm15,%xmm9,%xmm9 +vpxor %xmm15,%xmm14,%xmm14 +vmovdqa %xmm13,64(%rsp) +vmovdqa %xmm14,112(%rsp) +vpaddq subc0(%rip),%xmm11,%xmm10 +vpsubq %xmm12,%xmm10,%xmm10 +vpaddq %xmm12,%xmm11,%xmm11 +vpunpckhqdq %xmm10,%xmm11,%xmm12 +vpunpcklqdq %xmm10,%xmm11,%xmm10 +vpaddq %xmm1,%xmm0,%xmm11 +vpaddq subc0(%rip),%xmm0,%xmm0 +vpsubq %xmm1,%xmm0,%xmm0 +vpunpckhqdq %xmm11,%xmm0,%xmm1 +vpunpcklqdq %xmm11,%xmm0,%xmm0 +vpmuludq %xmm0,%xmm10,%xmm11 +vpmuludq %xmm1,%xmm10,%xmm13 +vmovdqa %xmm1,128(%rsp) +vpaddq %xmm1,%xmm1,%xmm1 +vpmuludq %xmm0,%xmm12,%xmm14 +vmovdqa %xmm0,144(%rsp) +vpaddq %xmm14,%xmm13,%xmm13 +vpmuludq %xmm1,%xmm12,%xmm0 +vmovdqa %xmm1,448(%rsp) +vpaddq %xmm3,%xmm2,%xmm1 +vpaddq subc2(%rip),%xmm2,%xmm2 +vpsubq %xmm3,%xmm2,%xmm2 +vpunpckhqdq %xmm1,%xmm2,%xmm3 +vpunpcklqdq %xmm1,%xmm2,%xmm1 +vpmuludq %xmm1,%xmm10,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vpmuludq %xmm3,%xmm10,%xmm2 +vmovdqa %xmm3,464(%rsp) +vpaddq %xmm3,%xmm3,%xmm3 +vpmuludq %xmm1,%xmm12,%xmm14 +vmovdqa %xmm1,480(%rsp) +vpaddq %xmm14,%xmm2,%xmm2 +vpmuludq %xmm3,%xmm12,%xmm1 +vmovdqa %xmm3,496(%rsp) +vpaddq %xmm5,%xmm4,%xmm3 +vpaddq subc2(%rip),%xmm4,%xmm4 +vpsubq %xmm5,%xmm4,%xmm4 +vpunpckhqdq %xmm3,%xmm4,%xmm5 +vpunpcklqdq %xmm3,%xmm4,%xmm3 +vpmuludq %xmm3,%xmm10,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vpmuludq %xmm5,%xmm10,%xmm4 +vmovdqa %xmm5,512(%rsp) +vpaddq %xmm5,%xmm5,%xmm5 +vpmuludq %xmm3,%xmm12,%xmm14 +vmovdqa %xmm3,528(%rsp) +vpaddq %xmm14,%xmm4,%xmm4 +vpaddq %xmm7,%xmm6,%xmm3 +vpaddq subc2(%rip),%xmm6,%xmm6 +vpsubq %xmm7,%xmm6,%xmm6 +vpunpckhqdq %xmm3,%xmm6,%xmm7 +vpunpcklqdq %xmm3,%xmm6,%xmm3 +vpmuludq %xmm3,%xmm10,%xmm6 +vpmuludq %xmm5,%xmm12,%xmm14 +vmovdqa %xmm5,544(%rsp) +vpmuludq v19_19(%rip),%xmm5,%xmm5 +vmovdqa %xmm5,560(%rsp) +vpaddq %xmm14,%xmm6,%xmm6 +vpmuludq %xmm7,%xmm10,%xmm5 +vmovdqa %xmm7,576(%rsp) +vpaddq %xmm7,%xmm7,%xmm7 +vpmuludq %xmm3,%xmm12,%xmm14 +vmovdqa %xmm3,592(%rsp) +vpaddq %xmm14,%xmm5,%xmm5 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vmovdqa %xmm3,608(%rsp) +vpaddq %xmm9,%xmm8,%xmm3 +vpaddq subc2(%rip),%xmm8,%xmm8 +vpsubq %xmm9,%xmm8,%xmm8 +vpunpckhqdq %xmm3,%xmm8,%xmm9 +vpunpcklqdq %xmm3,%xmm8,%xmm3 +vmovdqa %xmm3,624(%rsp) +vpmuludq %xmm7,%xmm12,%xmm8 +vmovdqa %xmm7,640(%rsp) +vpmuludq v19_19(%rip),%xmm7,%xmm7 +vmovdqa %xmm7,656(%rsp) +vpmuludq %xmm3,%xmm10,%xmm7 +vpaddq %xmm7,%xmm8,%xmm8 +vpmuludq %xmm9,%xmm10,%xmm7 +vmovdqa %xmm9,672(%rsp) +vpaddq %xmm9,%xmm9,%xmm9 +vpmuludq %xmm3,%xmm12,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vmovdqa %xmm3,688(%rsp) +vpmuludq v19_19(%rip),%xmm12,%xmm12 +vpmuludq %xmm9,%xmm12,%xmm3 +vmovdqa %xmm9,704(%rsp) +vpaddq %xmm3,%xmm11,%xmm11 +vmovdqa 0(%rsp),%xmm3 +vmovdqa 16(%rsp),%xmm9 +vpaddq subc2(%rip),%xmm3,%xmm10 +vpsubq %xmm9,%xmm10,%xmm10 +vpaddq %xmm9,%xmm3,%xmm3 +vpunpckhqdq %xmm10,%xmm3,%xmm9 +vpunpcklqdq %xmm10,%xmm3,%xmm3 +vpmuludq 144(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm0,%xmm0 +vpmuludq 128(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm2,%xmm2 +vpmuludq 480(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpmuludq 464(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm4,%xmm4 +vpmuludq 528(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm6,%xmm6 +vpmuludq 512(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm5,%xmm5 +vpmuludq 592(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpmuludq 576(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vpmuludq 624(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm11,%xmm11 +vpmuludq 672(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 144(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 448(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm1,%xmm1 +vpmuludq 480(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 496(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 528(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 544(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm8,%xmm8 +vpmuludq 592(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm9,%xmm9 +vpmuludq 640(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 624(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 704(%rsp),%xmm9,%xmm9 +vpaddq %xmm9,%xmm0,%xmm0 +vmovdqa 32(%rsp),%xmm3 +vmovdqa 80(%rsp),%xmm9 +vpaddq subc2(%rip),%xmm3,%xmm10 +vpsubq %xmm9,%xmm10,%xmm10 +vpaddq %xmm9,%xmm3,%xmm3 +vpunpckhqdq %xmm10,%xmm3,%xmm9 +vpunpcklqdq %xmm10,%xmm3,%xmm3 +vpmuludq 144(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpmuludq 128(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm4,%xmm4 +vpmuludq 480(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm6,%xmm6 +vpmuludq 464(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm5,%xmm5 +vpmuludq 528(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpmuludq 512(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vpmuludq 592(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm11,%xmm11 +vpmuludq 576(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm13,%xmm13 +vpmuludq 624(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm0,%xmm0 +vpmuludq 672(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 144(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 448(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 480(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 496(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm8,%xmm8 +vpmuludq 528(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm9,%xmm9 +vpmuludq 544(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 592(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 640(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm0,%xmm0 +vpmuludq 624(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 704(%rsp),%xmm9,%xmm9 +vpaddq %xmm9,%xmm1,%xmm1 +vmovdqa 48(%rsp),%xmm3 +vmovdqa 96(%rsp),%xmm9 +vpaddq subc2(%rip),%xmm3,%xmm10 +vpsubq %xmm9,%xmm10,%xmm10 +vpaddq %xmm9,%xmm3,%xmm3 +vpunpckhqdq %xmm10,%xmm3,%xmm9 +vpunpcklqdq %xmm10,%xmm3,%xmm3 +vpmuludq 144(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm6,%xmm6 +vpmuludq 128(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm5,%xmm5 +vpmuludq 480(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpmuludq 464(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vpmuludq 528(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm11,%xmm11 +vpmuludq 512(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm13,%xmm13 +vpmuludq 592(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm0,%xmm0 +vpmuludq 576(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm2,%xmm2 +vpmuludq 624(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpmuludq 672(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 144(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 448(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm8,%xmm8 +vpmuludq 480(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm9,%xmm9 +vpmuludq 496(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 528(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 544(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm0,%xmm0 +vpmuludq 592(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 640(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm1,%xmm1 +vpmuludq 624(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 704(%rsp),%xmm9,%xmm9 +vpaddq %xmm9,%xmm6,%xmm6 +vmovdqa 64(%rsp),%xmm3 +vmovdqa 112(%rsp),%xmm9 +vpaddq subc2(%rip),%xmm3,%xmm10 +vpsubq %xmm9,%xmm10,%xmm10 +vpaddq %xmm9,%xmm3,%xmm3 +vpunpckhqdq %xmm10,%xmm3,%xmm9 +vpunpcklqdq %xmm10,%xmm3,%xmm3 +vpmuludq 144(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpmuludq 128(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm3,%xmm3 +vpmuludq 480(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm11,%xmm11 +vpmuludq 464(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm13,%xmm13 +vpmuludq 528(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm0,%xmm0 +vpmuludq 512(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm2,%xmm2 +vpmuludq 592(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpmuludq 576(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm4,%xmm4 +vpmuludq 624(%rsp),%xmm3,%xmm10 +vpaddq %xmm10,%xmm6,%xmm6 +vpmuludq 672(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 144(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq v19_19(%rip),%xmm9,%xmm9 +vpmuludq 448(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 480(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 496(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm0,%xmm0 +vpmuludq 528(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 544(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm1,%xmm1 +vpmuludq 592(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 640(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 624(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 704(%rsp),%xmm9,%xmm9 +vpaddq %xmm9,%xmm8,%xmm8 +vpsrlq $25,%xmm4,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpand m25(%rip),%xmm4,%xmm4 +vpsrlq $26,%xmm11,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpand m26(%rip),%xmm11,%xmm11 +vpsrlq $26,%xmm6,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpand m26(%rip),%xmm6,%xmm6 +vpsrlq $25,%xmm13,%xmm3 +vpaddq %xmm3,%xmm0,%xmm0 +vpand m25(%rip),%xmm13,%xmm13 +vpsrlq $25,%xmm5,%xmm3 +vpaddq %xmm3,%xmm8,%xmm8 +vpand m25(%rip),%xmm5,%xmm5 +vpsrlq $26,%xmm0,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpand m26(%rip),%xmm0,%xmm0 +vpsrlq $26,%xmm8,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpand m26(%rip),%xmm8,%xmm8 +vpsrlq $25,%xmm2,%xmm3 +vpaddq %xmm3,%xmm1,%xmm1 +vpand m25(%rip),%xmm2,%xmm2 +vpsrlq $25,%xmm7,%xmm3 +vpsllq $4,%xmm3,%xmm9 +vpaddq %xmm3,%xmm11,%xmm11 +vpsllq $1,%xmm3,%xmm3 +vpaddq %xmm3,%xmm9,%xmm9 +vpaddq %xmm9,%xmm11,%xmm11 +vpand m25(%rip),%xmm7,%xmm7 +vpsrlq $26,%xmm1,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpand m26(%rip),%xmm1,%xmm1 +vpsrlq $26,%xmm11,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpand m26(%rip),%xmm11,%xmm11 +vpsrlq $25,%xmm4,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpand m25(%rip),%xmm4,%xmm4 +vpunpcklqdq %xmm13,%xmm11,%xmm3 +vpunpckhqdq %xmm13,%xmm11,%xmm9 +vpaddq subc0(%rip),%xmm9,%xmm10 +vpsubq %xmm3,%xmm10,%xmm10 +vpaddq %xmm9,%xmm3,%xmm3 +vpunpckhqdq %xmm3,%xmm10,%xmm9 +vpunpcklqdq %xmm3,%xmm10,%xmm10 +vpmuludq %xmm10,%xmm10,%xmm3 +vpaddq %xmm10,%xmm10,%xmm10 +vpmuludq %xmm9,%xmm10,%xmm11 +vpunpcklqdq %xmm2,%xmm0,%xmm12 +vpunpckhqdq %xmm2,%xmm0,%xmm0 +vpaddq subc2(%rip),%xmm0,%xmm2 +vpsubq %xmm12,%xmm2,%xmm2 +vpaddq %xmm0,%xmm12,%xmm12 +vpunpckhqdq %xmm12,%xmm2,%xmm0 +vpunpcklqdq %xmm12,%xmm2,%xmm2 +vpmuludq %xmm2,%xmm10,%xmm12 +vpaddq %xmm9,%xmm9,%xmm13 +vpmuludq %xmm13,%xmm9,%xmm9 +vpaddq %xmm9,%xmm12,%xmm12 +vpmuludq %xmm0,%xmm10,%xmm9 +vpmuludq %xmm2,%xmm13,%xmm14 +vpaddq %xmm14,%xmm9,%xmm9 +vpunpcklqdq %xmm4,%xmm1,%xmm14 +vpunpckhqdq %xmm4,%xmm1,%xmm1 +vpaddq subc2(%rip),%xmm1,%xmm4 +vpsubq %xmm14,%xmm4,%xmm4 +vpaddq %xmm1,%xmm14,%xmm14 +vpunpckhqdq %xmm14,%xmm4,%xmm1 +vpunpcklqdq %xmm14,%xmm4,%xmm4 +vmovdqa %xmm1,0(%rsp) +vpaddq %xmm1,%xmm1,%xmm1 +vmovdqa %xmm1,16(%rsp) +vpmuludq v19_19(%rip),%xmm1,%xmm1 +vmovdqa %xmm1,32(%rsp) +vpmuludq %xmm4,%xmm10,%xmm1 +vpmuludq %xmm2,%xmm2,%xmm14 +vpaddq %xmm14,%xmm1,%xmm1 +vpmuludq 0(%rsp),%xmm10,%xmm14 +vpmuludq %xmm4,%xmm13,%xmm15 +vpaddq %xmm15,%xmm14,%xmm14 +vpunpcklqdq %xmm5,%xmm6,%xmm15 +vpunpckhqdq %xmm5,%xmm6,%xmm5 +vpaddq subc2(%rip),%xmm5,%xmm6 +vpsubq %xmm15,%xmm6,%xmm6 +vpaddq %xmm5,%xmm15,%xmm15 +vpunpckhqdq %xmm15,%xmm6,%xmm5 +vpunpcklqdq %xmm15,%xmm6,%xmm6 +vmovdqa %xmm6,48(%rsp) +vpmuludq v19_19(%rip),%xmm6,%xmm6 +vmovdqa %xmm6,64(%rsp) +vmovdqa %xmm5,80(%rsp) +vpmuludq v38_38(%rip),%xmm5,%xmm5 +vmovdqa %xmm5,96(%rsp) +vpmuludq 48(%rsp),%xmm10,%xmm5 +vpaddq %xmm0,%xmm0,%xmm6 +vpmuludq %xmm6,%xmm0,%xmm0 +vpaddq %xmm0,%xmm5,%xmm5 +vpmuludq 80(%rsp),%xmm10,%xmm0 +vpmuludq %xmm4,%xmm6,%xmm15 +vpaddq %xmm15,%xmm0,%xmm0 +vpmuludq %xmm6,%xmm13,%xmm15 +vpaddq %xmm15,%xmm1,%xmm1 +vpmuludq %xmm6,%xmm2,%xmm15 +vpaddq %xmm15,%xmm14,%xmm14 +vpunpcklqdq %xmm7,%xmm8,%xmm15 +vpunpckhqdq %xmm7,%xmm8,%xmm7 +vpaddq subc2(%rip),%xmm7,%xmm8 +vpsubq %xmm15,%xmm8,%xmm8 +vpaddq %xmm7,%xmm15,%xmm15 +vpunpckhqdq %xmm15,%xmm8,%xmm7 +vpunpcklqdq %xmm15,%xmm8,%xmm8 +vmovdqa %xmm8,112(%rsp) +vpmuludq v19_19(%rip),%xmm8,%xmm8 +vmovdqa %xmm8,448(%rsp) +vpmuludq 112(%rsp),%xmm10,%xmm8 +vpmuludq %xmm7,%xmm10,%xmm10 +vpmuludq v38_38(%rip),%xmm7,%xmm15 +vpmuludq %xmm15,%xmm7,%xmm7 +vpaddq %xmm7,%xmm8,%xmm8 +vpmuludq %xmm15,%xmm13,%xmm7 +vpaddq %xmm7,%xmm3,%xmm3 +vpmuludq %xmm15,%xmm2,%xmm7 +vpaddq %xmm7,%xmm11,%xmm11 +vpmuludq 80(%rsp),%xmm13,%xmm7 +vpaddq %xmm7,%xmm7,%xmm7 +vpaddq %xmm7,%xmm8,%xmm8 +vpmuludq 16(%rsp),%xmm13,%xmm7 +vpaddq %xmm7,%xmm5,%xmm5 +vpmuludq 48(%rsp),%xmm13,%xmm7 +vpaddq %xmm7,%xmm0,%xmm0 +vpmuludq 112(%rsp),%xmm13,%xmm7 +vpaddq %xmm7,%xmm10,%xmm10 +vpmuludq %xmm15,%xmm6,%xmm7 +vpaddq %xmm7,%xmm12,%xmm12 +vpmuludq %xmm15,%xmm4,%xmm7 +vpaddq %xmm7,%xmm9,%xmm9 +vpaddq %xmm2,%xmm2,%xmm2 +vpmuludq %xmm4,%xmm2,%xmm7 +vpaddq %xmm7,%xmm5,%xmm5 +vpmuludq 448(%rsp),%xmm2,%xmm7 +vpaddq %xmm7,%xmm3,%xmm3 +vpmuludq 448(%rsp),%xmm6,%xmm7 +vpaddq %xmm7,%xmm11,%xmm11 +vpmuludq 0(%rsp),%xmm2,%xmm7 +vpaddq %xmm7,%xmm0,%xmm0 +vpmuludq 48(%rsp),%xmm2,%xmm7 +vpaddq %xmm7,%xmm8,%xmm8 +vpmuludq 80(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 96(%rsp),%xmm4,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpmuludq %xmm4,%xmm4,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpaddq %xmm4,%xmm4,%xmm2 +vpmuludq 448(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm12,%xmm12 +vpmuludq 16(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vpmuludq 48(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm14,%xmm14 +vpmuludq 96(%rsp),%xmm6,%xmm4 +vpaddq %xmm4,%xmm3,%xmm3 +vmovdqa 16(%rsp),%xmm4 +vpmuludq 448(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm9,%xmm9 +vpmuludq 16(%rsp),%xmm6,%xmm4 +vpaddq %xmm4,%xmm8,%xmm8 +vpmuludq 48(%rsp),%xmm6,%xmm4 +vpaddq %xmm4,%xmm10,%xmm10 +vpmuludq 80(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm4,%xmm4 +vpaddq %xmm4,%xmm5,%xmm5 +vpmuludq 112(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm0,%xmm0 +vmovdqa 48(%rsp),%xmm4 +vpaddq %xmm4,%xmm4,%xmm4 +vpmuludq 448(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vmovdqa 80(%rsp),%xmm4 +vpaddq %xmm4,%xmm4,%xmm4 +vpmuludq 448(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm14,%xmm14 +vpmuludq 64(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm3,%xmm3 +vmovdqa 16(%rsp),%xmm4 +vpmuludq 64(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm11,%xmm11 +vmovdqa 16(%rsp),%xmm4 +vpmuludq 96(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm12,%xmm12 +vmovdqa 48(%rsp),%xmm4 +vpmuludq 96(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm9,%xmm9 +vpmuludq 0(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vmovdqa 32(%rsp),%xmm2 +vpmuludq 0(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm3,%xmm3 +vmovdqa 64(%rsp),%xmm2 +vpmuludq 48(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vmovdqa 96(%rsp),%xmm2 +vpmuludq 80(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm1,%xmm1 +vmovdqa 448(%rsp),%xmm2 +vpmuludq 112(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpsrlq $26,%xmm3,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpand m26(%rip),%xmm3,%xmm3 +vpsrlq $25,%xmm14,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpand m25(%rip),%xmm14,%xmm14 +vpsrlq $25,%xmm11,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpand m25(%rip),%xmm11,%xmm11 +vpsrlq $26,%xmm5,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vpand m26(%rip),%xmm5,%xmm5 +vpsrlq $26,%xmm12,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpand m26(%rip),%xmm12,%xmm12 +vpsrlq $25,%xmm0,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpand m25(%rip),%xmm0,%xmm0 +vpsrlq $25,%xmm9,%xmm2 +vpaddq %xmm2,%xmm1,%xmm1 +vpand m25(%rip),%xmm9,%xmm9 +vpsrlq $26,%xmm8,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpand m26(%rip),%xmm8,%xmm8 +vpsrlq $26,%xmm1,%xmm2 +vpaddq %xmm2,%xmm14,%xmm14 +vpand m26(%rip),%xmm1,%xmm1 +vpsrlq $25,%xmm10,%xmm2 +vpsllq $4,%xmm2,%xmm4 +vpaddq %xmm2,%xmm3,%xmm3 +vpsllq $1,%xmm2,%xmm2 +vpaddq %xmm2,%xmm4,%xmm4 +vpaddq %xmm4,%xmm3,%xmm3 +vpand m25(%rip),%xmm10,%xmm10 +vpsrlq $25,%xmm14,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpand m25(%rip),%xmm14,%xmm14 +vpsrlq $26,%xmm3,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpand m26(%rip),%xmm3,%xmm3 +vpunpckhqdq %xmm11,%xmm3,%xmm2 +vmovdqa %xmm2,0(%rsp) +vpshufd $0,%xmm3,%xmm2 +vpshufd $0,%xmm11,%xmm3 +vpmuludq 160(%rsp),%xmm2,%xmm4 +vpmuludq 432(%rsp),%xmm3,%xmm6 +vpaddq %xmm6,%xmm4,%xmm4 +vpmuludq 176(%rsp),%xmm2,%xmm6 +vpmuludq 304(%rsp),%xmm3,%xmm7 +vpaddq %xmm7,%xmm6,%xmm6 +vpmuludq 208(%rsp),%xmm2,%xmm7 +vpmuludq 336(%rsp),%xmm3,%xmm11 +vpaddq %xmm11,%xmm7,%xmm7 +vpmuludq 240(%rsp),%xmm2,%xmm11 +vpmuludq 368(%rsp),%xmm3,%xmm13 +vpaddq %xmm13,%xmm11,%xmm11 +vpmuludq 272(%rsp),%xmm2,%xmm2 +vpmuludq 400(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpunpckhqdq %xmm9,%xmm12,%xmm3 +vmovdqa %xmm3,16(%rsp) +vpshufd $0,%xmm12,%xmm3 +vpshufd $0,%xmm9,%xmm9 +vpmuludq 288(%rsp),%xmm3,%xmm12 +vpaddq %xmm12,%xmm4,%xmm4 +vpmuludq 416(%rsp),%xmm9,%xmm12 +vpaddq %xmm12,%xmm4,%xmm4 +vpmuludq 160(%rsp),%xmm3,%xmm12 +vpaddq %xmm12,%xmm6,%xmm6 +vpmuludq 432(%rsp),%xmm9,%xmm12 +vpaddq %xmm12,%xmm6,%xmm6 +vpmuludq 176(%rsp),%xmm3,%xmm12 +vpaddq %xmm12,%xmm7,%xmm7 +vpmuludq 304(%rsp),%xmm9,%xmm12 +vpaddq %xmm12,%xmm7,%xmm7 +vpmuludq 208(%rsp),%xmm3,%xmm12 +vpaddq %xmm12,%xmm11,%xmm11 +vpmuludq 336(%rsp),%xmm9,%xmm12 +vpaddq %xmm12,%xmm11,%xmm11 +vpmuludq 240(%rsp),%xmm3,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpmuludq 368(%rsp),%xmm9,%xmm3 +vpaddq %xmm3,%xmm2,%xmm2 +vpunpckhqdq %xmm14,%xmm1,%xmm3 +vmovdqa %xmm3,32(%rsp) +vpshufd $0,%xmm1,%xmm1 +vpshufd $0,%xmm14,%xmm3 +vpmuludq 256(%rsp),%xmm1,%xmm9 +vpaddq %xmm9,%xmm4,%xmm4 +vpmuludq 384(%rsp),%xmm3,%xmm9 +vpaddq %xmm9,%xmm4,%xmm4 +vpmuludq 288(%rsp),%xmm1,%xmm9 +vpaddq %xmm9,%xmm6,%xmm6 +vpmuludq 416(%rsp),%xmm3,%xmm9 +vpaddq %xmm9,%xmm6,%xmm6 +vpmuludq 160(%rsp),%xmm1,%xmm9 +vpaddq %xmm9,%xmm7,%xmm7 +vpmuludq 432(%rsp),%xmm3,%xmm9 +vpaddq %xmm9,%xmm7,%xmm7 +vpmuludq 176(%rsp),%xmm1,%xmm9 +vpaddq %xmm9,%xmm11,%xmm11 +vpmuludq 304(%rsp),%xmm3,%xmm9 +vpaddq %xmm9,%xmm11,%xmm11 +vpmuludq 208(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm2,%xmm2 +vpmuludq 336(%rsp),%xmm3,%xmm1 +vpaddq %xmm1,%xmm2,%xmm2 +vpunpckhqdq %xmm0,%xmm5,%xmm1 +vmovdqa %xmm1,48(%rsp) +vpshufd $0,%xmm5,%xmm1 +vpshufd $0,%xmm0,%xmm0 +vpmuludq 224(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 352(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 256(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 384(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 288(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq 416(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq 160(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 432(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 176(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm2,%xmm2 +vpmuludq 304(%rsp),%xmm0,%xmm0 +vpaddq %xmm0,%xmm2,%xmm2 +vpunpckhqdq %xmm10,%xmm8,%xmm0 +vmovdqa %xmm0,64(%rsp) +vpshufd $0,%xmm8,%xmm0 +vpshufd $0,%xmm10,%xmm1 +vpmuludq 192(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 320(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm4,%xmm4 +vpmuludq 224(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 352(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 256(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq 384(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq 288(%rsp),%xmm0,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 416(%rsp),%xmm1,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 160(%rsp),%xmm0,%xmm0 +vpaddq %xmm0,%xmm2,%xmm2 +vpmuludq 432(%rsp),%xmm1,%xmm0 +vpaddq %xmm0,%xmm2,%xmm2 +vmovdqa %xmm4,80(%rsp) +vmovdqa %xmm6,96(%rsp) +vmovdqa %xmm7,112(%rsp) +vmovdqa %xmm11,448(%rsp) +vmovdqa %xmm2,496(%rsp) +vmovdqa 144(%rsp),%xmm0 +vpmuludq %xmm0,%xmm0,%xmm1 +vpaddq %xmm0,%xmm0,%xmm0 +vmovdqa 128(%rsp),%xmm2 +vpmuludq %xmm2,%xmm0,%xmm3 +vmovdqa 480(%rsp),%xmm4 +vpmuludq %xmm4,%xmm0,%xmm5 +vmovdqa 464(%rsp),%xmm6 +vpmuludq %xmm6,%xmm0,%xmm7 +vmovdqa 528(%rsp),%xmm8 +vpmuludq %xmm8,%xmm0,%xmm9 +vpmuludq 512(%rsp),%xmm0,%xmm10 +vpmuludq 592(%rsp),%xmm0,%xmm11 +vpmuludq 576(%rsp),%xmm0,%xmm12 +vpmuludq 624(%rsp),%xmm0,%xmm13 +vmovdqa 672(%rsp),%xmm14 +vpmuludq %xmm14,%xmm0,%xmm0 +vpmuludq v38_38(%rip),%xmm14,%xmm15 +vpmuludq %xmm15,%xmm14,%xmm14 +vpaddq %xmm14,%xmm13,%xmm13 +vpaddq %xmm6,%xmm6,%xmm14 +vpmuludq %xmm14,%xmm6,%xmm6 +vpaddq %xmm6,%xmm11,%xmm11 +vpaddq %xmm2,%xmm2,%xmm6 +vpmuludq %xmm6,%xmm2,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpmuludq %xmm15,%xmm6,%xmm2 +vpaddq %xmm2,%xmm1,%xmm1 +vpmuludq %xmm15,%xmm4,%xmm2 +vpaddq %xmm2,%xmm3,%xmm3 +vpmuludq 544(%rsp),%xmm6,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpmuludq 592(%rsp),%xmm6,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 640(%rsp),%xmm6,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpmuludq 624(%rsp),%xmm6,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vpmuludq %xmm4,%xmm6,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpmuludq %xmm14,%xmm6,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpmuludq %xmm8,%xmm6,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq %xmm15,%xmm14,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpmuludq %xmm15,%xmm8,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpmuludq %xmm4,%xmm4,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpmuludq %xmm14,%xmm4,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpaddq %xmm4,%xmm4,%xmm2 +vpmuludq %xmm8,%xmm2,%xmm4 +vpaddq %xmm4,%xmm11,%xmm11 +vpmuludq 688(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vpmuludq 688(%rsp),%xmm14,%xmm4 +vpaddq %xmm4,%xmm3,%xmm3 +vpmuludq 512(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm12,%xmm12 +vpmuludq 592(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm13,%xmm13 +vpmuludq 576(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vpmuludq 656(%rsp),%xmm8,%xmm2 +vpaddq %xmm2,%xmm3,%xmm3 +vpmuludq %xmm8,%xmm14,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq %xmm8,%xmm8,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpaddq %xmm8,%xmm8,%xmm2 +vpmuludq 688(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm5,%xmm5 +vpmuludq 544(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm9,%xmm9 +vpmuludq 592(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm10,%xmm10 +vpmuludq 656(%rsp),%xmm14,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vmovdqa 544(%rsp),%xmm4 +vpmuludq 688(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm7,%xmm7 +vpmuludq 544(%rsp),%xmm14,%xmm4 +vpaddq %xmm4,%xmm13,%xmm13 +vpmuludq 592(%rsp),%xmm14,%xmm4 +vpaddq %xmm4,%xmm0,%xmm0 +vpmuludq 640(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm11,%xmm11 +vpmuludq 624(%rsp),%xmm15,%xmm4 +vpaddq %xmm4,%xmm12,%xmm12 +vmovdqa 592(%rsp),%xmm4 +vpaddq %xmm4,%xmm4,%xmm4 +vpmuludq 688(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm9,%xmm9 +vpmuludq 608(%rsp),%xmm2,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vmovdqa 544(%rsp),%xmm4 +vpmuludq 608(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm3,%xmm3 +vmovdqa 544(%rsp),%xmm4 +vpmuludq 656(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm5,%xmm5 +vmovdqa 592(%rsp),%xmm4 +vpmuludq 656(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm7,%xmm7 +vmovdqa 640(%rsp),%xmm4 +vpmuludq 688(%rsp),%xmm4,%xmm4 +vpaddq %xmm4,%xmm10,%xmm10 +vpmuludq 512(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vmovdqa 560(%rsp),%xmm2 +vpmuludq 512(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm1,%xmm1 +vmovdqa 608(%rsp),%xmm2 +vpmuludq 592(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vmovdqa 656(%rsp),%xmm2 +vpmuludq 576(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vmovdqa 688(%rsp),%xmm2 +vpmuludq 624(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpsrlq $26,%xmm1,%xmm2 +vpaddq %xmm2,%xmm3,%xmm3 +vpand m26(%rip),%xmm1,%xmm1 +vpsrlq $25,%xmm10,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpand m25(%rip),%xmm10,%xmm10 +vpsrlq $25,%xmm3,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpand m25(%rip),%xmm3,%xmm3 +vpsrlq $26,%xmm11,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpand m26(%rip),%xmm11,%xmm11 +vpsrlq $26,%xmm5,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpand m26(%rip),%xmm5,%xmm5 +vpsrlq $25,%xmm12,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpand m25(%rip),%xmm12,%xmm12 +vpsrlq $25,%xmm7,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpand m25(%rip),%xmm7,%xmm7 +vpsrlq $26,%xmm13,%xmm2 +vpaddq %xmm2,%xmm0,%xmm0 +vpand m26(%rip),%xmm13,%xmm13 +vpsrlq $26,%xmm9,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpand m26(%rip),%xmm9,%xmm9 +vpsrlq $25,%xmm0,%xmm2 +vpsllq $4,%xmm2,%xmm4 +vpaddq %xmm2,%xmm1,%xmm1 +vpsllq $1,%xmm2,%xmm2 +vpaddq %xmm2,%xmm4,%xmm4 +vpaddq %xmm4,%xmm1,%xmm1 +vpand m25(%rip),%xmm0,%xmm0 +vpsrlq $25,%xmm10,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpand m25(%rip),%xmm10,%xmm10 +vpsrlq $26,%xmm1,%xmm2 +vpaddq %xmm2,%xmm3,%xmm3 +vpand m26(%rip),%xmm1,%xmm1 +vpunpckhqdq %xmm3,%xmm1,%xmm2 +vpunpcklqdq %xmm3,%xmm1,%xmm1 +vmovdqa %xmm1,464(%rsp) +vpaddq subc0(%rip),%xmm2,%xmm3 +vpsubq %xmm1,%xmm3,%xmm3 +vpunpckhqdq %xmm3,%xmm2,%xmm1 +vpunpcklqdq %xmm3,%xmm2,%xmm2 +vmovdqa %xmm2,480(%rsp) +vmovdqa %xmm1,512(%rsp) +vpsllq $1,%xmm1,%xmm1 +vmovdqa %xmm1,528(%rsp) +vpmuludq v121666_121666(%rip),%xmm3,%xmm3 +vmovdqa 80(%rsp),%xmm1 +vpunpcklqdq %xmm1,%xmm3,%xmm2 +vpunpckhqdq %xmm1,%xmm3,%xmm1 +vpunpckhqdq %xmm7,%xmm5,%xmm3 +vpunpcklqdq %xmm7,%xmm5,%xmm4 +vmovdqa %xmm4,544(%rsp) +vpaddq subc2(%rip),%xmm3,%xmm5 +vpsubq %xmm4,%xmm5,%xmm5 +vpunpckhqdq %xmm5,%xmm3,%xmm4 +vpunpcklqdq %xmm5,%xmm3,%xmm3 +vmovdqa %xmm3,560(%rsp) +vmovdqa %xmm4,576(%rsp) +vpsllq $1,%xmm4,%xmm4 +vmovdqa %xmm4,592(%rsp) +vpmuludq v121666_121666(%rip),%xmm5,%xmm5 +vmovdqa 96(%rsp),%xmm3 +vpunpcklqdq %xmm3,%xmm5,%xmm4 +vpunpckhqdq %xmm3,%xmm5,%xmm3 +vpunpckhqdq %xmm10,%xmm9,%xmm5 +vpunpcklqdq %xmm10,%xmm9,%xmm6 +vmovdqa %xmm6,608(%rsp) +vpaddq subc2(%rip),%xmm5,%xmm7 +vpsubq %xmm6,%xmm7,%xmm7 +vpunpckhqdq %xmm7,%xmm5,%xmm6 +vpunpcklqdq %xmm7,%xmm5,%xmm5 +vmovdqa %xmm5,624(%rsp) +vmovdqa %xmm6,640(%rsp) +vpsllq $1,%xmm6,%xmm6 +vmovdqa %xmm6,656(%rsp) +vpmuludq v121666_121666(%rip),%xmm7,%xmm7 +vmovdqa 112(%rsp),%xmm5 +vpunpcklqdq %xmm5,%xmm7,%xmm6 +vpunpckhqdq %xmm5,%xmm7,%xmm5 +vpunpckhqdq %xmm12,%xmm11,%xmm7 +vpunpcklqdq %xmm12,%xmm11,%xmm8 +vmovdqa %xmm8,672(%rsp) +vpaddq subc2(%rip),%xmm7,%xmm9 +vpsubq %xmm8,%xmm9,%xmm9 +vpunpckhqdq %xmm9,%xmm7,%xmm8 +vpunpcklqdq %xmm9,%xmm7,%xmm7 +vmovdqa %xmm7,688(%rsp) +vmovdqa %xmm8,704(%rsp) +vpsllq $1,%xmm8,%xmm8 +vmovdqa %xmm8,720(%rsp) +vpmuludq v121666_121666(%rip),%xmm9,%xmm9 +vmovdqa 448(%rsp),%xmm7 +vpunpcklqdq %xmm7,%xmm9,%xmm8 +vpunpckhqdq %xmm7,%xmm9,%xmm7 +vpunpckhqdq %xmm0,%xmm13,%xmm9 +vpunpcklqdq %xmm0,%xmm13,%xmm0 +vmovdqa %xmm0,448(%rsp) +vpaddq subc2(%rip),%xmm9,%xmm10 +vpsubq %xmm0,%xmm10,%xmm10 +vpunpckhqdq %xmm10,%xmm9,%xmm0 +vpunpcklqdq %xmm10,%xmm9,%xmm9 +vmovdqa %xmm9,736(%rsp) +vmovdqa %xmm0,752(%rsp) +vpsllq $1,%xmm0,%xmm0 +vmovdqa %xmm0,768(%rsp) +vpmuludq v121666_121666(%rip),%xmm10,%xmm10 +vmovdqa 496(%rsp),%xmm0 +vpunpcklqdq %xmm0,%xmm10,%xmm9 +vpunpckhqdq %xmm0,%xmm10,%xmm0 +vpsrlq $26,%xmm2,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpand m26(%rip),%xmm2,%xmm2 +vpsrlq $25,%xmm5,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpand m25(%rip),%xmm5,%xmm5 +vpsrlq $25,%xmm1,%xmm10 +vpaddq %xmm10,%xmm4,%xmm4 +vpand m25(%rip),%xmm1,%xmm1 +vpsrlq $26,%xmm8,%xmm10 +vpaddq %xmm10,%xmm7,%xmm7 +vpand m26(%rip),%xmm8,%xmm8 +vpsrlq $26,%xmm4,%xmm10 +vpaddq %xmm10,%xmm3,%xmm3 +vpand m26(%rip),%xmm4,%xmm4 +vpsrlq $25,%xmm7,%xmm10 +vpaddq %xmm10,%xmm9,%xmm9 +vpand m25(%rip),%xmm7,%xmm7 +vpsrlq $25,%xmm3,%xmm10 +vpaddq %xmm10,%xmm6,%xmm6 +vpand m25(%rip),%xmm3,%xmm3 +vpsrlq $26,%xmm9,%xmm10 +vpaddq %xmm10,%xmm0,%xmm0 +vpand m26(%rip),%xmm9,%xmm9 +vpsrlq $26,%xmm6,%xmm10 +vpaddq %xmm10,%xmm5,%xmm5 +vpand m26(%rip),%xmm6,%xmm6 +vpsrlq $25,%xmm0,%xmm10 +vpsllq $4,%xmm10,%xmm11 +vpaddq %xmm10,%xmm2,%xmm2 +vpsllq $1,%xmm10,%xmm10 +vpaddq %xmm10,%xmm11,%xmm11 +vpaddq %xmm11,%xmm2,%xmm2 +vpand m25(%rip),%xmm0,%xmm0 +vpsrlq $25,%xmm5,%xmm10 +vpaddq %xmm10,%xmm8,%xmm8 +vpand m25(%rip),%xmm5,%xmm5 +vpsrlq $26,%xmm2,%xmm10 +vpaddq %xmm10,%xmm1,%xmm1 +vpand m26(%rip),%xmm2,%xmm2 +vpunpckhqdq %xmm1,%xmm2,%xmm10 +vmovdqa %xmm10,80(%rsp) +vpunpcklqdq %xmm1,%xmm2,%xmm1 +vpunpckhqdq %xmm3,%xmm4,%xmm2 +vmovdqa %xmm2,96(%rsp) +vpunpcklqdq %xmm3,%xmm4,%xmm2 +vpunpckhqdq %xmm5,%xmm6,%xmm3 +vmovdqa %xmm3,112(%rsp) +vpunpcklqdq %xmm5,%xmm6,%xmm3 +vpunpckhqdq %xmm7,%xmm8,%xmm4 +vmovdqa %xmm4,128(%rsp) +vpunpcklqdq %xmm7,%xmm8,%xmm4 +vpunpckhqdq %xmm0,%xmm9,%xmm5 +vmovdqa %xmm5,144(%rsp) +vpunpcklqdq %xmm0,%xmm9,%xmm0 +vmovdqa 464(%rsp),%xmm5 +vpaddq %xmm5,%xmm1,%xmm1 +vpunpcklqdq %xmm1,%xmm5,%xmm6 +vpunpckhqdq %xmm1,%xmm5,%xmm1 +vpmuludq 512(%rsp),%xmm6,%xmm5 +vpmuludq 480(%rsp),%xmm1,%xmm7 +vpaddq %xmm7,%xmm5,%xmm5 +vpmuludq 560(%rsp),%xmm6,%xmm7 +vpmuludq 528(%rsp),%xmm1,%xmm8 +vpaddq %xmm8,%xmm7,%xmm7 +vpmuludq 576(%rsp),%xmm6,%xmm8 +vpmuludq 560(%rsp),%xmm1,%xmm9 +vpaddq %xmm9,%xmm8,%xmm8 +vpmuludq 624(%rsp),%xmm6,%xmm9 +vpmuludq 592(%rsp),%xmm1,%xmm10 +vpaddq %xmm10,%xmm9,%xmm9 +vpmuludq 640(%rsp),%xmm6,%xmm10 +vpmuludq 624(%rsp),%xmm1,%xmm11 +vpaddq %xmm11,%xmm10,%xmm10 +vpmuludq 688(%rsp),%xmm6,%xmm11 +vpmuludq 656(%rsp),%xmm1,%xmm12 +vpaddq %xmm12,%xmm11,%xmm11 +vpmuludq 704(%rsp),%xmm6,%xmm12 +vpmuludq 688(%rsp),%xmm1,%xmm13 +vpaddq %xmm13,%xmm12,%xmm12 +vpmuludq 736(%rsp),%xmm6,%xmm13 +vpmuludq 720(%rsp),%xmm1,%xmm14 +vpaddq %xmm14,%xmm13,%xmm13 +vpmuludq 752(%rsp),%xmm6,%xmm14 +vpmuludq 736(%rsp),%xmm1,%xmm15 +vpaddq %xmm15,%xmm14,%xmm14 +vpmuludq 480(%rsp),%xmm6,%xmm6 +vpmuludq v19_19(%rip),%xmm1,%xmm1 +vpmuludq 768(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm6,%xmm6 +vmovdqa 544(%rsp),%xmm1 +vpaddq %xmm1,%xmm2,%xmm2 +vpunpcklqdq %xmm2,%xmm1,%xmm15 +vpunpckhqdq %xmm2,%xmm1,%xmm1 +vpmuludq 480(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpmuludq 512(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpmuludq 560(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpmuludq 576(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 624(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpmuludq 640(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 688(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpmuludq 704(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm15,%xmm15 +vpmuludq 736(%rsp),%xmm15,%xmm2 +vpaddq %xmm2,%xmm6,%xmm6 +vpmuludq 752(%rsp),%xmm15,%xmm15 +vpaddq %xmm15,%xmm5,%xmm5 +vpmuludq 480(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpmuludq 528(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpmuludq 560(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 592(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpmuludq 624(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 656(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpmuludq 688(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm1,%xmm1 +vpmuludq 720(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm6,%xmm6 +vpmuludq 736(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpmuludq 768(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm7,%xmm7 +vmovdqa 608(%rsp),%xmm1 +vpaddq %xmm1,%xmm3,%xmm3 +vpunpcklqdq %xmm3,%xmm1,%xmm2 +vpunpckhqdq %xmm3,%xmm1,%xmm1 +vpmuludq 480(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm9,%xmm9 +vpmuludq 512(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm10,%xmm10 +vpmuludq 560(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 576(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm12,%xmm12 +vpmuludq 624(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 640(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm2,%xmm2 +vpmuludq 688(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 704(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 736(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq 752(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpmuludq 480(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 528(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm11,%xmm11 +vpmuludq 560(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 592(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpmuludq 624(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm1,%xmm1 +vpmuludq 656(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm6,%xmm6 +vpmuludq 688(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpmuludq 720(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpmuludq 736(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpmuludq 768(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm9,%xmm9 +vmovdqa 672(%rsp),%xmm1 +vpaddq %xmm1,%xmm4,%xmm4 +vpunpcklqdq %xmm4,%xmm1,%xmm2 +vpunpckhqdq %xmm4,%xmm1,%xmm1 +vpmuludq 480(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm11,%xmm11 +vpmuludq 512(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm12,%xmm12 +vpmuludq 560(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm13,%xmm13 +vpmuludq 576(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm2,%xmm2 +vpmuludq 624(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm6,%xmm6 +vpmuludq 640(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm5,%xmm5 +vpmuludq 688(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm7,%xmm7 +vpmuludq 704(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm8,%xmm8 +vpmuludq 736(%rsp),%xmm2,%xmm3 +vpaddq %xmm3,%xmm9,%xmm9 +vpmuludq 752(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 480(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 528(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm13,%xmm13 +vpmuludq 560(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm1,%xmm1 +vpmuludq 592(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm6,%xmm6 +vpmuludq 624(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm5,%xmm5 +vpmuludq 656(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm7,%xmm7 +vpmuludq 688(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm8,%xmm8 +vpmuludq 720(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm9,%xmm9 +vpmuludq 736(%rsp),%xmm1,%xmm2 +vpaddq %xmm2,%xmm10,%xmm10 +vpmuludq 768(%rsp),%xmm1,%xmm1 +vpaddq %xmm1,%xmm11,%xmm11 +vmovdqa 448(%rsp),%xmm1 +vpaddq %xmm1,%xmm0,%xmm0 +vpunpcklqdq %xmm0,%xmm1,%xmm2 +vpunpckhqdq %xmm0,%xmm1,%xmm0 +vpmuludq 480(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm13,%xmm13 +vpmuludq 512(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm2,%xmm2 +vpmuludq 560(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm6,%xmm6 +vpmuludq 576(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm5,%xmm5 +vpmuludq 624(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm7,%xmm7 +vpmuludq 640(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm8,%xmm8 +vpmuludq 688(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm9,%xmm9 +vpmuludq 704(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm10,%xmm10 +vpmuludq 736(%rsp),%xmm2,%xmm1 +vpaddq %xmm1,%xmm11,%xmm11 +vpmuludq 752(%rsp),%xmm2,%xmm2 +vpaddq %xmm2,%xmm12,%xmm12 +vpmuludq 480(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm14,%xmm14 +vpmuludq v19_19(%rip),%xmm0,%xmm0 +vpmuludq 528(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm6,%xmm6 +vpmuludq 560(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm5,%xmm5 +vpmuludq 592(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm7,%xmm7 +vpmuludq 624(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm8,%xmm8 +vpmuludq 656(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm9,%xmm9 +vpmuludq 688(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm10,%xmm10 +vpmuludq 720(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm11,%xmm11 +vpmuludq 736(%rsp),%xmm0,%xmm1 +vpaddq %xmm1,%xmm12,%xmm12 +vpmuludq 768(%rsp),%xmm0,%xmm0 +vpaddq %xmm0,%xmm13,%xmm13 +vpsrlq $26,%xmm6,%xmm0 +vpaddq %xmm0,%xmm5,%xmm5 +vpand m26(%rip),%xmm6,%xmm6 +vpsrlq $25,%xmm10,%xmm0 +vpaddq %xmm0,%xmm11,%xmm11 +vpand m25(%rip),%xmm10,%xmm10 +vpsrlq $25,%xmm5,%xmm0 +vpaddq %xmm0,%xmm7,%xmm7 +vpand m25(%rip),%xmm5,%xmm5 +vpsrlq $26,%xmm11,%xmm0 +vpaddq %xmm0,%xmm12,%xmm12 +vpand m26(%rip),%xmm11,%xmm11 +vpsrlq $26,%xmm7,%xmm0 +vpaddq %xmm0,%xmm8,%xmm8 +vpand m26(%rip),%xmm7,%xmm7 +vpsrlq $25,%xmm12,%xmm0 +vpaddq %xmm0,%xmm13,%xmm13 +vpand m25(%rip),%xmm12,%xmm12 +vpsrlq $25,%xmm8,%xmm0 +vpaddq %xmm0,%xmm9,%xmm9 +vpand m25(%rip),%xmm8,%xmm8 +vpsrlq $26,%xmm13,%xmm0 +vpaddq %xmm0,%xmm14,%xmm14 +vpand m26(%rip),%xmm13,%xmm13 +vpsrlq $26,%xmm9,%xmm0 +vpaddq %xmm0,%xmm10,%xmm10 +vpand m26(%rip),%xmm9,%xmm9 +vpsrlq $25,%xmm14,%xmm0 +vpsllq $4,%xmm0,%xmm1 +vpaddq %xmm0,%xmm6,%xmm6 +vpsllq $1,%xmm0,%xmm0 +vpaddq %xmm0,%xmm1,%xmm1 +vpaddq %xmm1,%xmm6,%xmm6 +vpand m25(%rip),%xmm14,%xmm14 +vpsrlq $25,%xmm10,%xmm0 +vpaddq %xmm0,%xmm11,%xmm11 +vpand m25(%rip),%xmm10,%xmm10 +vpsrlq $26,%xmm6,%xmm0 +vpaddq %xmm0,%xmm5,%xmm5 +vpand m26(%rip),%xmm6,%xmm6 +vpunpckhqdq %xmm5,%xmm6,%xmm1 +vpunpcklqdq %xmm5,%xmm6,%xmm0 +vpunpckhqdq %xmm8,%xmm7,%xmm3 +vpunpcklqdq %xmm8,%xmm7,%xmm2 +vpunpckhqdq %xmm10,%xmm9,%xmm5 +vpunpcklqdq %xmm10,%xmm9,%xmm4 +vpunpckhqdq %xmm12,%xmm11,%xmm7 +vpunpcklqdq %xmm12,%xmm11,%xmm6 +vpunpckhqdq %xmm14,%xmm13,%xmm9 +vpunpcklqdq %xmm14,%xmm13,%xmm8 +cmp $0,%rdx +jne ._ladder_loop +vmovdqu %xmm1,160(%rdi) +vmovdqu %xmm0,80(%rdi) +vmovdqu %xmm3,176(%rdi) +vmovdqu %xmm2,96(%rdi) +vmovdqu %xmm5,192(%rdi) +vmovdqu %xmm4,112(%rdi) +vmovdqu %xmm7,208(%rdi) +vmovdqu %xmm6,128(%rdi) +vmovdqu %xmm9,224(%rdi) +vmovdqu %xmm8,144(%rdi) +movq 1824(%rsp),%r11 +movq 1832(%rsp),%r12 +movq 1840(%rsp),%r13 +movq 1848(%rsp),%r14 +add %r11,%rsp +ret + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/ladder.h b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/ladder.h new file mode 100644 index 0000000..ccf4eca --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/ladder.h @@ -0,0 +1,18 @@ +#ifndef ladder_H +#define ladder_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "fe.h" +#include "ladder_namespace.h" + +extern void ladder(fe *, const unsigned char *); + +#ifdef __cplusplus +} +#endif + +#endif /* ifndef ladder_H */ + diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/ladder_namespace.h b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/ladder_namespace.h new file mode 100644 index 0000000..6637074 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/ladder_namespace.h @@ -0,0 +1,8 @@ +#ifndef ladder_namespace_H +#define ladder_namespace_H + +#define ladder crypto_scalarmult_curve25519_sandy2x_ladder +#define _ladder _crypto_scalarmult_curve25519_sandy2x_ladder + +#endif /* ifndef ladder_namespace_H */ + diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/sandy2x.S b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/sandy2x.S new file mode 100644 index 0000000..585804f --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/sandy2x/sandy2x.S @@ -0,0 +1,16 @@ + +#ifdef HAVE_AVX_ASM + +#define IN_SANDY2X + +#include "consts.S" +#include "fe51_mul.S" +#include "fe51_nsquare.S" +#include "fe51_pack.S" +#include "ladder.S" + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/scalarmult_curve25519.c b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/scalarmult_curve25519.c new file mode 100644 index 0000000..c55e45e --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/scalarmult_curve25519.c @@ -0,0 +1,60 @@ + +#include "crypto_scalarmult_curve25519.h" +#include "private/implementations.h" +#include "scalarmult_curve25519.h" +#include "runtime.h" + +#ifdef HAVE_AVX_ASM +# include "sandy2x/curve25519_sandy2x.h" +#endif +#include "ref10/x25519_ref10.h" +static const crypto_scalarmult_curve25519_implementation *implementation = + &crypto_scalarmult_curve25519_ref10_implementation; + +int +crypto_scalarmult_curve25519(unsigned char *q, const unsigned char *n, + const unsigned char *p) +{ + size_t i; + volatile unsigned char d = 0; + + if (implementation->mult(q, n, p) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + for (i = 0; i < crypto_scalarmult_curve25519_BYTES; i++) { + d |= q[i]; + } + return -(1 & ((d - 1) >> 8)); +} + +int +crypto_scalarmult_curve25519_base(unsigned char *q, const unsigned char *n) +{ + return crypto_scalarmult_curve25519_ref10_implementation + .mult_base(q, n); +} + +size_t +crypto_scalarmult_curve25519_bytes(void) +{ + return crypto_scalarmult_curve25519_BYTES; +} + +size_t +crypto_scalarmult_curve25519_scalarbytes(void) +{ + return crypto_scalarmult_curve25519_SCALARBYTES; +} + +int +_crypto_scalarmult_curve25519_pick_best_implementation(void) +{ + implementation = &crypto_scalarmult_curve25519_ref10_implementation; + +#ifdef HAVE_AVX_ASM + if (sodium_runtime_has_avx()) { + implementation = &crypto_scalarmult_curve25519_sandy2x_implementation; + } +#endif + return 0; +} diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/scalarmult_curve25519.h b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/scalarmult_curve25519.h new file mode 100644 index 0000000..66edbf6 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/curve25519/scalarmult_curve25519.h @@ -0,0 +1,11 @@ + +#ifndef scalarmult_poly1305_H +#define scalarmult_poly1305_H + +typedef struct crypto_scalarmult_curve25519_implementation { + int (*mult)(unsigned char *q, const unsigned char *n, + const unsigned char *p); + int (*mult_base)(unsigned char *q, const unsigned char *n); +} crypto_scalarmult_curve25519_implementation; + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c b/external/src/libsodium/src/libsodium/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c new file mode 100644 index 0000000..7c98089 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c @@ -0,0 +1,121 @@ + +#include + +#include "crypto_scalarmult_ed25519.h" +#include "private/ed25519_ref10.h" +#include "utils.h" + +static int +_crypto_scalarmult_ed25519_is_inf(const unsigned char s[32]) +{ + unsigned char c; + unsigned int i; + + c = s[0] ^ 0x01; + for (i = 1; i < 31; i++) { + c |= s[i]; + } + c |= s[31] & 0x7f; + + return ((((unsigned int) c) - 1U) >> 8) & 1; +} + +static inline void +_crypto_scalarmult_ed25519_clamp(unsigned char k[32]) +{ + k[0] &= 248; + k[31] |= 64; +} + +static int +_crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n, + const unsigned char *p, const int clamp) +{ + unsigned char *t = q; + ge25519_p3 Q; + ge25519_p3 P; + unsigned int i; + + if (ge25519_is_canonical(p) == 0 || ge25519_has_small_order(p) != 0 || + ge25519_frombytes(&P, p) != 0 || ge25519_is_on_main_subgroup(&P) == 0) { + return -1; + } + for (i = 0; i < 32; ++i) { + t[i] = n[i]; + } + if (clamp != 0) { + _crypto_scalarmult_ed25519_clamp(t); + } + t[31] &= 127; + + ge25519_scalarmult(&Q, t, &P); + ge25519_p3_tobytes(q, &Q); + if (_crypto_scalarmult_ed25519_is_inf(q) != 0 || sodium_is_zero(n, 32)) { + return -1; + } + return 0; +} + +int +crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n, + const unsigned char *p) +{ + return _crypto_scalarmult_ed25519(q, n, p, 1); +} + +int +crypto_scalarmult_ed25519_noclamp(unsigned char *q, const unsigned char *n, + const unsigned char *p) +{ + return _crypto_scalarmult_ed25519(q, n, p, 0); +} + +static int +_crypto_scalarmult_ed25519_base(unsigned char *q, + const unsigned char *n, const int clamp) +{ + unsigned char *t = q; + ge25519_p3 Q; + unsigned int i; + + for (i = 0; i < 32; ++i) { + t[i] = n[i]; + } + if (clamp != 0) { + _crypto_scalarmult_ed25519_clamp(t); + } + t[31] &= 127; + + ge25519_scalarmult_base(&Q, t); + ge25519_p3_tobytes(q, &Q); + if (_crypto_scalarmult_ed25519_is_inf(q) != 0 || sodium_is_zero(n, 32)) { + return -1; + } + return 0; +} + +int +crypto_scalarmult_ed25519_base(unsigned char *q, + const unsigned char *n) +{ + return _crypto_scalarmult_ed25519_base(q, n, 1); +} + +int +crypto_scalarmult_ed25519_base_noclamp(unsigned char *q, + const unsigned char *n) +{ + return _crypto_scalarmult_ed25519_base(q, n, 0); +} + +size_t +crypto_scalarmult_ed25519_bytes(void) +{ + return crypto_scalarmult_ed25519_BYTES; +} + +size_t +crypto_scalarmult_ed25519_scalarbytes(void) +{ + return crypto_scalarmult_ed25519_SCALARBYTES; +} diff --git a/external/src/libsodium/src/libsodium/crypto_scalarmult/ristretto255/ref10/scalarmult_ristretto255_ref10.c b/external/src/libsodium/src/libsodium/crypto_scalarmult/ristretto255/ref10/scalarmult_ristretto255_ref10.c new file mode 100644 index 0000000..433a9a2 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_scalarmult/ristretto255/ref10/scalarmult_ristretto255_ref10.c @@ -0,0 +1,63 @@ + +#include + +#include "crypto_scalarmult_ed25519.h" +#include "crypto_scalarmult_ristretto255.h" +#include "private/ed25519_ref10.h" +#include "utils.h" + +int +crypto_scalarmult_ristretto255(unsigned char *q, const unsigned char *n, + const unsigned char *p) +{ + unsigned char *t = q; + ge25519_p3 Q; + ge25519_p3 P; + unsigned int i; + + if (ristretto255_frombytes(&P, p) != 0) { + return -1; + } + for (i = 0; i < 32; ++i) { + t[i] = n[i]; + } + t[31] &= 127; + ge25519_scalarmult(&Q, t, &P); + ristretto255_p3_tobytes(q, &Q); + if (sodium_is_zero(q, 32)) { + return -1; + } + return 0; +} + +int +crypto_scalarmult_ristretto255_base(unsigned char *q, + const unsigned char *n) +{ + unsigned char *t = q; + ge25519_p3 Q; + unsigned int i; + + for (i = 0; i < 32; ++i) { + t[i] = n[i]; + } + t[31] &= 127; + ge25519_scalarmult_base(&Q, t); + ristretto255_p3_tobytes(q, &Q); + if (sodium_is_zero(q, 32)) { + return -1; + } + return 0; +} + +size_t +crypto_scalarmult_ristretto255_bytes(void) +{ + return crypto_scalarmult_ristretto255_BYTES; +} + +size_t +crypto_scalarmult_ristretto255_scalarbytes(void) +{ + return crypto_scalarmult_ristretto255_SCALARBYTES; +} diff --git a/external/src/libsodium/src/libsodium/crypto_secretbox/crypto_secretbox.c b/external/src/libsodium/src/libsodium/crypto_secretbox/crypto_secretbox.c new file mode 100644 index 0000000..45f678e --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_secretbox/crypto_secretbox.c @@ -0,0 +1,67 @@ + +#include "crypto_secretbox.h" +#include "randombytes.h" + +size_t +crypto_secretbox_keybytes(void) +{ + return crypto_secretbox_KEYBYTES; +} + +size_t +crypto_secretbox_noncebytes(void) +{ + return crypto_secretbox_NONCEBYTES; +} + +size_t +crypto_secretbox_zerobytes(void) +{ + return crypto_secretbox_ZEROBYTES; +} + +size_t +crypto_secretbox_boxzerobytes(void) +{ + return crypto_secretbox_BOXZEROBYTES; +} + +size_t +crypto_secretbox_macbytes(void) +{ + return crypto_secretbox_MACBYTES; +} + +size_t +crypto_secretbox_messagebytes_max(void) +{ + return crypto_secretbox_MESSAGEBYTES_MAX; +} + +const char * +crypto_secretbox_primitive(void) +{ + return crypto_secretbox_PRIMITIVE; +} + +int +crypto_secretbox(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + return crypto_secretbox_xsalsa20poly1305(c, m, mlen, n, k); +} + +int +crypto_secretbox_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + return crypto_secretbox_xsalsa20poly1305_open(m, c, clen, n, k); +} + +void +crypto_secretbox_keygen(unsigned char k[crypto_secretbox_KEYBYTES]) +{ + randombytes_buf(k, crypto_secretbox_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_secretbox/crypto_secretbox_easy.c b/external/src/libsodium/src/libsodium/crypto_secretbox/crypto_secretbox_easy.c new file mode 100644 index 0000000..12132a2 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_secretbox/crypto_secretbox_easy.c @@ -0,0 +1,144 @@ + +#include +#include +#include +#include +#include + +#include "core.h" +#include "crypto_core_hsalsa20.h" +#include "crypto_onetimeauth_poly1305.h" +#include "crypto_secretbox.h" +#include "crypto_stream_salsa20.h" +#include "private/common.h" +#include "utils.h" + +int +crypto_secretbox_detached(unsigned char *c, unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char subkey[crypto_stream_salsa20_KEYBYTES]; + unsigned long long i; + unsigned long long mlen0; + + crypto_core_hsalsa20(subkey, n, k, NULL); + + if (((uintptr_t) c > (uintptr_t) m && + (uintptr_t) c - (uintptr_t) m < mlen) || + ((uintptr_t) m > (uintptr_t) c && + (uintptr_t) m - (uintptr_t) c < mlen)) { /* LCOV_EXCL_LINE */ + memmove(c, m, mlen); + m = c; + } + memset(block0, 0U, crypto_secretbox_ZEROBYTES); + COMPILER_ASSERT(64U >= crypto_secretbox_ZEROBYTES); + mlen0 = mlen; + if (mlen0 > 64U - crypto_secretbox_ZEROBYTES) { + mlen0 = 64U - crypto_secretbox_ZEROBYTES; + } + for (i = 0U; i < mlen0; i++) { + block0[i + crypto_secretbox_ZEROBYTES] = m[i]; + } + crypto_stream_salsa20_xor(block0, block0, + mlen0 + crypto_secretbox_ZEROBYTES, + n + 16, subkey); + COMPILER_ASSERT(crypto_secretbox_ZEROBYTES >= + crypto_onetimeauth_poly1305_KEYBYTES); + crypto_onetimeauth_poly1305_init(&state, block0); + + for (i = 0U; i < mlen0; i++) { + c[i] = block0[crypto_secretbox_ZEROBYTES + i]; + } + sodium_memzero(block0, sizeof block0); + if (mlen > mlen0) { + crypto_stream_salsa20_xor_ic(c + mlen0, m + mlen0, mlen - mlen0, + n + 16, 1U, subkey); + } + sodium_memzero(subkey, sizeof subkey); + + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_final(&state, mac); + sodium_memzero(&state, sizeof state); + + return 0; +} + +int +crypto_secretbox_easy(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + if (mlen > crypto_secretbox_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return crypto_secretbox_detached(c + crypto_secretbox_MACBYTES, + c, m, mlen, n, k); +} + +int +crypto_secretbox_open_detached(unsigned char *m, const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + unsigned char block0[64U]; + unsigned char subkey[crypto_stream_salsa20_KEYBYTES]; + unsigned long long i; + unsigned long long mlen0; + + crypto_core_hsalsa20(subkey, n, k, NULL); + crypto_stream_salsa20(block0, crypto_stream_salsa20_KEYBYTES, + n + 16, subkey); + if (crypto_onetimeauth_poly1305_verify(mac, c, clen, block0) != 0) { + sodium_memzero(subkey, sizeof subkey); + return -1; + } + if (m == NULL) { + return 0; + } + if (((uintptr_t) c > (uintptr_t) m && + (uintptr_t) c - (uintptr_t) m < clen) || + ((uintptr_t) m > (uintptr_t) c && + (uintptr_t) m - (uintptr_t) c < clen)) { /* LCOV_EXCL_LINE */ + memmove(m, c, clen); + c = m; + } + mlen0 = clen; + if (mlen0 > 64U - crypto_secretbox_ZEROBYTES) { + mlen0 = 64U - crypto_secretbox_ZEROBYTES; + } + for (i = 0U; i < mlen0; i++) { + block0[crypto_secretbox_ZEROBYTES + i] = c[i]; + } + crypto_stream_salsa20_xor(block0, block0, + crypto_secretbox_ZEROBYTES + mlen0, + n + 16, subkey); + for (i = 0U; i < mlen0; i++) { + m[i] = block0[i + crypto_secretbox_ZEROBYTES]; + } + if (clen > mlen0) { + crypto_stream_salsa20_xor_ic(m + mlen0, c + mlen0, clen - mlen0, + n + 16, 1U, subkey); + } + sodium_memzero(subkey, sizeof subkey); + + return 0; +} + +int +crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + if (clen < crypto_secretbox_MACBYTES) { + return -1; + } + return crypto_secretbox_open_detached(m, c + crypto_secretbox_MACBYTES, c, + clen - crypto_secretbox_MACBYTES, + n, k); +} diff --git a/external/src/libsodium/src/libsodium/crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c b/external/src/libsodium/src/libsodium/crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c new file mode 100644 index 0000000..d012b13 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c @@ -0,0 +1,177 @@ + +#include +#include +#include +#include +#include + +#include "core.h" +#include "crypto_core_hchacha20.h" +#include "crypto_onetimeauth_poly1305.h" +#include "crypto_secretbox_xchacha20poly1305.h" +#include "crypto_stream_chacha20.h" +#include "private/common.h" +#include "utils.h" + +#define crypto_secretbox_xchacha20poly1305_ZEROBYTES 32U + +int +crypto_secretbox_xchacha20poly1305_detached(unsigned char *c, + unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char subkey[crypto_stream_chacha20_KEYBYTES]; + unsigned long long i; + unsigned long long mlen0; + + crypto_core_hchacha20(subkey, n, k, NULL); + + if (((uintptr_t) c > (uintptr_t) m && + (uintptr_t) c - (uintptr_t) m < mlen) || + ((uintptr_t) m > (uintptr_t) c && + (uintptr_t) m - (uintptr_t) c < mlen)) { /* LCOV_EXCL_LINE */ + memmove(c, m, mlen); + m = c; + } + memset(block0, 0U, crypto_secretbox_xchacha20poly1305_ZEROBYTES); + COMPILER_ASSERT(64U >= crypto_secretbox_xchacha20poly1305_ZEROBYTES); + mlen0 = mlen; + if (mlen0 > 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES) { + mlen0 = 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES; + } + for (i = 0U; i < mlen0; i++) { + block0[i + crypto_secretbox_xchacha20poly1305_ZEROBYTES] = m[i]; + } + crypto_stream_chacha20_xor(block0, block0, + mlen0 + crypto_secretbox_xchacha20poly1305_ZEROBYTES, + n + 16, subkey); + COMPILER_ASSERT(crypto_secretbox_xchacha20poly1305_ZEROBYTES >= + crypto_onetimeauth_poly1305_KEYBYTES); + crypto_onetimeauth_poly1305_init(&state, block0); + + for (i = 0U; i < mlen0; i++) { + c[i] = block0[crypto_secretbox_xchacha20poly1305_ZEROBYTES + i]; + } + sodium_memzero(block0, sizeof block0); + if (mlen > mlen0) { + crypto_stream_chacha20_xor_ic(c + mlen0, m + mlen0, mlen - mlen0, + n + 16, 1U, subkey); + } + sodium_memzero(subkey, sizeof subkey); + + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_final(&state, mac); + sodium_memzero(&state, sizeof state); + + return 0; +} + +int +crypto_secretbox_xchacha20poly1305_easy(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) +{ + if (mlen > crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return crypto_secretbox_xchacha20poly1305_detached + (c + crypto_secretbox_xchacha20poly1305_MACBYTES, c, m, mlen, n, k); +} + +int +crypto_secretbox_xchacha20poly1305_open_detached(unsigned char *m, + const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + unsigned char block0[64U]; + unsigned char subkey[crypto_stream_chacha20_KEYBYTES]; + unsigned long long i; + unsigned long long mlen0; + + crypto_core_hchacha20(subkey, n, k, NULL); + crypto_stream_chacha20(block0, crypto_stream_chacha20_KEYBYTES, + n + 16, subkey); + if (crypto_onetimeauth_poly1305_verify(mac, c, clen, block0) != 0) { + sodium_memzero(subkey, sizeof subkey); + return -1; + } + if (m == NULL) { + return 0; + } + if (((uintptr_t) c > (uintptr_t) m && + (uintptr_t) c - (uintptr_t) m < clen) || + ((uintptr_t) m > (uintptr_t) c && + (uintptr_t) m - (uintptr_t) c < clen)) { /* LCOV_EXCL_LINE */ + memmove(m, c, clen); + c = m; + } + mlen0 = clen; + if (mlen0 > 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES) { + mlen0 = 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES; + } + for (i = 0U; i < mlen0; i++) { + block0[crypto_secretbox_xchacha20poly1305_ZEROBYTES + i] = c[i]; + } + crypto_stream_chacha20_xor(block0, block0, + crypto_secretbox_xchacha20poly1305_ZEROBYTES + mlen0, + n + 16, subkey); + for (i = 0U; i < mlen0; i++) { + m[i] = block0[i + crypto_secretbox_xchacha20poly1305_ZEROBYTES]; + } + if (clen > mlen0) { + crypto_stream_chacha20_xor_ic(m + mlen0, c + mlen0, clen - mlen0, + n + 16, 1U, subkey); + } + sodium_memzero(subkey, sizeof subkey); + + return 0; +} + +int +crypto_secretbox_xchacha20poly1305_open_easy(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + if (clen < crypto_secretbox_xchacha20poly1305_MACBYTES) { + return -1; + } + return crypto_secretbox_xchacha20poly1305_open_detached + (m, c + crypto_secretbox_xchacha20poly1305_MACBYTES, c, + clen - crypto_secretbox_xchacha20poly1305_MACBYTES, n, k); +} + +size_t +crypto_secretbox_xchacha20poly1305_keybytes(void) +{ + return crypto_secretbox_xchacha20poly1305_KEYBYTES; +} + +size_t +crypto_secretbox_xchacha20poly1305_noncebytes(void) +{ + return crypto_secretbox_xchacha20poly1305_NONCEBYTES; +} + +size_t +crypto_secretbox_xchacha20poly1305_macbytes(void) +{ + return crypto_secretbox_xchacha20poly1305_MACBYTES; +} + +size_t +crypto_secretbox_xchacha20poly1305_messagebytes_max(void) +{ + return crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX; +} diff --git a/external/src/libsodium/src/libsodium/crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305.c b/external/src/libsodium/src/libsodium/crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305.c new file mode 100644 index 0000000..7240050 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_secretbox/xsalsa20poly1305/secretbox_xsalsa20poly1305.c @@ -0,0 +1,89 @@ +#include "crypto_onetimeauth_poly1305.h" +#include "crypto_secretbox_xsalsa20poly1305.h" +#include "crypto_stream_xsalsa20.h" +#include "randombytes.h" + +int +crypto_secretbox_xsalsa20poly1305(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) +{ + int i; + + if (mlen < 32) { + return -1; + } + crypto_stream_xsalsa20_xor(c, m, mlen, n, k); + crypto_onetimeauth_poly1305(c + 16, c + 32, mlen - 32, c); + for (i = 0; i < 16; ++i) { + c[i] = 0; + } + return 0; +} + +int +crypto_secretbox_xsalsa20poly1305_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) +{ + unsigned char subkey[32]; + int i; + + if (clen < 32) { + return -1; + } + crypto_stream_xsalsa20(subkey, 32, n, k); + if (crypto_onetimeauth_poly1305_verify(c + 16, c + 32, + clen - 32, subkey) != 0) { + return -1; + } + crypto_stream_xsalsa20_xor(m, c, clen, n, k); + for (i = 0; i < 32; ++i) { + m[i] = 0; + } + return 0; +} + +size_t +crypto_secretbox_xsalsa20poly1305_keybytes(void) +{ + return crypto_secretbox_xsalsa20poly1305_KEYBYTES; +} + +size_t +crypto_secretbox_xsalsa20poly1305_noncebytes(void) +{ + return crypto_secretbox_xsalsa20poly1305_NONCEBYTES; +} + +size_t +crypto_secretbox_xsalsa20poly1305_zerobytes(void) +{ + return crypto_secretbox_xsalsa20poly1305_ZEROBYTES; +} + +size_t +crypto_secretbox_xsalsa20poly1305_boxzerobytes(void) +{ + return crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES; +} + +size_t +crypto_secretbox_xsalsa20poly1305_macbytes(void) +{ + return crypto_secretbox_xsalsa20poly1305_MACBYTES; +} + +size_t +crypto_secretbox_xsalsa20poly1305_messagebytes_max(void) +{ + return crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX; +} + +void +crypto_secretbox_xsalsa20poly1305_keygen(unsigned char k[crypto_secretbox_xsalsa20poly1305_KEYBYTES]) +{ + randombytes_buf(k, crypto_secretbox_xsalsa20poly1305_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c b/external/src/libsodium/src/libsodium/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c new file mode 100644 index 0000000..2754a91 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c @@ -0,0 +1,313 @@ +#include +#include +#include +#include + +#include "core.h" +#include "crypto_aead_chacha20poly1305.h" +#include "crypto_aead_xchacha20poly1305.h" +#include "crypto_core_hchacha20.h" +#include "crypto_onetimeauth_poly1305.h" +#include "crypto_secretstream_xchacha20poly1305.h" +#include "randombytes.h" +#include "utils.h" + +#include "private/common.h" + +#define crypto_secretstream_xchacha20poly1305_COUNTERBYTES 4U +#define crypto_secretstream_xchacha20poly1305_INONCEBYTES 8U + +#define STATE_COUNTER(STATE) ((STATE)->nonce) +#define STATE_INONCE(STATE) ((STATE)->nonce + \ + crypto_secretstream_xchacha20poly1305_COUNTERBYTES) + +static const unsigned char _pad0[16] = { 0 }; + +static inline void +_crypto_secretstream_xchacha20poly1305_counter_reset + (crypto_secretstream_xchacha20poly1305_state *state) +{ + memset(STATE_COUNTER(state), 0, + crypto_secretstream_xchacha20poly1305_COUNTERBYTES); + STATE_COUNTER(state)[0] = 1; +} + +void +crypto_secretstream_xchacha20poly1305_keygen + (unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]) +{ + randombytes_buf(k, crypto_secretstream_xchacha20poly1305_KEYBYTES); +} + +int +crypto_secretstream_xchacha20poly1305_init_push + (crypto_secretstream_xchacha20poly1305_state *state, + unsigned char out[crypto_secretstream_xchacha20poly1305_HEADERBYTES], + const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]) +{ + COMPILER_ASSERT(crypto_secretstream_xchacha20poly1305_HEADERBYTES == + crypto_core_hchacha20_INPUTBYTES + + crypto_secretstream_xchacha20poly1305_INONCEBYTES); + COMPILER_ASSERT(crypto_secretstream_xchacha20poly1305_HEADERBYTES == + crypto_aead_xchacha20poly1305_ietf_NPUBBYTES); + COMPILER_ASSERT(sizeof state->nonce == + crypto_secretstream_xchacha20poly1305_INONCEBYTES + + crypto_secretstream_xchacha20poly1305_COUNTERBYTES); + + randombytes_buf(out, crypto_secretstream_xchacha20poly1305_HEADERBYTES); + crypto_core_hchacha20(state->k, out, k, NULL); + _crypto_secretstream_xchacha20poly1305_counter_reset(state); + memcpy(STATE_INONCE(state), out + crypto_core_hchacha20_INPUTBYTES, + crypto_secretstream_xchacha20poly1305_INONCEBYTES); + memset(state->_pad, 0, sizeof state->_pad); + + return 0; +} + +int +crypto_secretstream_xchacha20poly1305_init_pull + (crypto_secretstream_xchacha20poly1305_state *state, + const unsigned char in[crypto_secretstream_xchacha20poly1305_HEADERBYTES], + const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]) +{ + crypto_core_hchacha20(state->k, in, k, NULL); + _crypto_secretstream_xchacha20poly1305_counter_reset(state); + memcpy(STATE_INONCE(state), in + crypto_core_hchacha20_INPUTBYTES, + crypto_secretstream_xchacha20poly1305_INONCEBYTES); + memset(state->_pad, 0, sizeof state->_pad); + + return 0; +} + +void +crypto_secretstream_xchacha20poly1305_rekey + (crypto_secretstream_xchacha20poly1305_state *state) +{ + unsigned char new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + + crypto_secretstream_xchacha20poly1305_INONCEBYTES]; + size_t i; + + for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { + new_key_and_inonce[i] = state->k[i]; + } + for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { + new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i] = + STATE_INONCE(state)[i]; + } + crypto_stream_chacha20_ietf_xor(new_key_and_inonce, new_key_and_inonce, + sizeof new_key_and_inonce, + state->nonce, state->k); + for (i = 0U; i < crypto_stream_chacha20_ietf_KEYBYTES; i++) { + state->k[i] = new_key_and_inonce[i]; + } + for (i = 0U; i < crypto_secretstream_xchacha20poly1305_INONCEBYTES; i++) { + STATE_INONCE(state)[i] = + new_key_and_inonce[crypto_stream_chacha20_ietf_KEYBYTES + i]; + } + _crypto_secretstream_xchacha20poly1305_counter_reset(state); +} + +int +crypto_secretstream_xchacha20poly1305_push + (crypto_secretstream_xchacha20poly1305_state *state, + unsigned char *out, unsigned long long *outlen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, unsigned char tag) +{ + crypto_onetimeauth_poly1305_state poly1305_state; + unsigned char block[64U]; + unsigned char slen[8U]; + unsigned char *c; + unsigned char *mac; + + if (outlen_p != NULL) { + *outlen_p = 0U; + } + COMPILER_ASSERT(crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX + <= crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX); + if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); + crypto_onetimeauth_poly1305_init(&poly1305_state, block); + sodium_memzero(block, sizeof block); + + crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); + crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, + (0x10 - adlen) & 0xf); + memset(block, 0, sizeof block); + block[0] = tag; + + crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, + state->nonce, 1U, state->k); + crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); + out[0] = block[0]; + + c = out + (sizeof tag); + crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, state->nonce, 2U, state->k); + crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); + crypto_onetimeauth_poly1305_update + (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); + + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); + STORE64_LE(slen, (sizeof block) + mlen); + crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); + + mac = c + mlen; + crypto_onetimeauth_poly1305_final(&poly1305_state, mac); + sodium_memzero(&poly1305_state, sizeof poly1305_state); + + COMPILER_ASSERT(crypto_onetimeauth_poly1305_BYTES >= + crypto_secretstream_xchacha20poly1305_INONCEBYTES); + XOR_BUF(STATE_INONCE(state), mac, + crypto_secretstream_xchacha20poly1305_INONCEBYTES); + sodium_increment(STATE_COUNTER(state), + crypto_secretstream_xchacha20poly1305_COUNTERBYTES); + if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || + sodium_is_zero(STATE_COUNTER(state), + crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { + crypto_secretstream_xchacha20poly1305_rekey(state); + } + if (outlen_p != NULL) { + *outlen_p = crypto_secretstream_xchacha20poly1305_ABYTES + mlen; + } + return 0; +} + +int +crypto_secretstream_xchacha20poly1305_pull + (crypto_secretstream_xchacha20poly1305_state *state, + unsigned char *m, unsigned long long *mlen_p, unsigned char *tag_p, + const unsigned char *in, unsigned long long inlen, + const unsigned char *ad, unsigned long long adlen) +{ + crypto_onetimeauth_poly1305_state poly1305_state; + unsigned char block[64U]; + unsigned char slen[8U]; + unsigned char mac[crypto_onetimeauth_poly1305_BYTES]; + const unsigned char *c; + const unsigned char *stored_mac; + unsigned long long mlen; + unsigned char tag; + + if (mlen_p != NULL) { + *mlen_p = 0U; + } + if (tag_p != NULL) { + *tag_p = 0xff; + } + if (inlen < crypto_secretstream_xchacha20poly1305_ABYTES) { + return -1; + } + mlen = inlen - crypto_secretstream_xchacha20poly1305_ABYTES; + if (mlen > crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + crypto_stream_chacha20_ietf(block, sizeof block, state->nonce, state->k); + crypto_onetimeauth_poly1305_init(&poly1305_state, block); + sodium_memzero(block, sizeof block); + + crypto_onetimeauth_poly1305_update(&poly1305_state, ad, adlen); + crypto_onetimeauth_poly1305_update(&poly1305_state, _pad0, + (0x10 - adlen) & 0xf); + + memset(block, 0, sizeof block); + block[0] = in[0]; + crypto_stream_chacha20_ietf_xor_ic(block, block, sizeof block, + state->nonce, 1U, state->k); + tag = block[0]; + block[0] = in[0]; + crypto_onetimeauth_poly1305_update(&poly1305_state, block, sizeof block); + + c = in + (sizeof tag); + crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); + crypto_onetimeauth_poly1305_update + (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); + + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); + STORE64_LE(slen, (sizeof block) + mlen); + crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&poly1305_state, mac); + sodium_memzero(&poly1305_state, sizeof poly1305_state); + + stored_mac = c + mlen; + if (sodium_memcmp(mac, stored_mac, sizeof mac) != 0) { + sodium_memzero(mac, sizeof mac); + return -1; + } + + crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, state->nonce, 2U, state->k); + XOR_BUF(STATE_INONCE(state), mac, + crypto_secretstream_xchacha20poly1305_INONCEBYTES); + sodium_increment(STATE_COUNTER(state), + crypto_secretstream_xchacha20poly1305_COUNTERBYTES); + if ((tag & crypto_secretstream_xchacha20poly1305_TAG_REKEY) != 0 || + sodium_is_zero(STATE_COUNTER(state), + crypto_secretstream_xchacha20poly1305_COUNTERBYTES)) { + crypto_secretstream_xchacha20poly1305_rekey(state); + } + if (mlen_p != NULL) { + *mlen_p = mlen; + } + if (tag_p != NULL) { + *tag_p = tag; + } + return 0; +} + +size_t +crypto_secretstream_xchacha20poly1305_statebytes(void) +{ + return sizeof(crypto_secretstream_xchacha20poly1305_state); +} + +size_t +crypto_secretstream_xchacha20poly1305_abytes(void) +{ + return crypto_secretstream_xchacha20poly1305_ABYTES; +} + +size_t +crypto_secretstream_xchacha20poly1305_headerbytes(void) +{ + return crypto_secretstream_xchacha20poly1305_HEADERBYTES; +} + +size_t +crypto_secretstream_xchacha20poly1305_keybytes(void) +{ + return crypto_secretstream_xchacha20poly1305_KEYBYTES; +} + +size_t +crypto_secretstream_xchacha20poly1305_messagebytes_max(void) +{ + return crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX; +} + +unsigned char +crypto_secretstream_xchacha20poly1305_tag_message(void) +{ + return crypto_secretstream_xchacha20poly1305_TAG_MESSAGE; +} + +unsigned char +crypto_secretstream_xchacha20poly1305_tag_push(void) +{ + return crypto_secretstream_xchacha20poly1305_TAG_PUSH; +} + +unsigned char +crypto_secretstream_xchacha20poly1305_tag_rekey(void) +{ + return crypto_secretstream_xchacha20poly1305_TAG_REKEY; +} + +unsigned char +crypto_secretstream_xchacha20poly1305_tag_final(void) +{ + return crypto_secretstream_xchacha20poly1305_TAG_FINAL; +} diff --git a/external/src/libsodium/src/libsodium/crypto_shorthash/crypto_shorthash.c b/external/src/libsodium/src/libsodium/crypto_shorthash/crypto_shorthash.c new file mode 100644 index 0000000..95f52f8 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_shorthash/crypto_shorthash.c @@ -0,0 +1,34 @@ + +#include "crypto_shorthash.h" +#include "randombytes.h" + +size_t +crypto_shorthash_bytes(void) +{ + return crypto_shorthash_BYTES; +} + +size_t +crypto_shorthash_keybytes(void) +{ + return crypto_shorthash_KEYBYTES; +} + +const char * +crypto_shorthash_primitive(void) +{ + return crypto_shorthash_PRIMITIVE; +} + +int +crypto_shorthash(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + return crypto_shorthash_siphash24(out, in, inlen, k); +} + +void +crypto_shorthash_keygen(unsigned char k[crypto_shorthash_KEYBYTES]) +{ + randombytes_buf(k, crypto_shorthash_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c b/external/src/libsodium/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c new file mode 100644 index 0000000..5487745 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphash24_ref.c @@ -0,0 +1,71 @@ +#include "crypto_shorthash_siphash24.h" +#include "private/common.h" +#include "shorthash_siphash_ref.h" + +int +crypto_shorthash_siphash24(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + /* "somepseudorandomlygeneratedbytes" */ + uint64_t v0 = 0x736f6d6570736575ULL; + uint64_t v1 = 0x646f72616e646f6dULL; + uint64_t v2 = 0x6c7967656e657261ULL; + uint64_t v3 = 0x7465646279746573ULL; + uint64_t b; + uint64_t k0 = LOAD64_LE(k); + uint64_t k1 = LOAD64_LE(k + 8); + uint64_t m; + const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t)); + const int left = inlen & 7; + + b = ((uint64_t) inlen) << 56; + v3 ^= k1; + v2 ^= k0; + v1 ^= k1; + v0 ^= k0; + for (; in != end; in += 8) { + m = LOAD64_LE(in); + v3 ^= m; + SIPROUND; + SIPROUND; + v0 ^= m; + } + switch (left) { + case 7: + b |= ((uint64_t) in[6]) << 48; + /* FALLTHRU */ + case 6: + b |= ((uint64_t) in[5]) << 40; + /* FALLTHRU */ + case 5: + b |= ((uint64_t) in[4]) << 32; + /* FALLTHRU */ + case 4: + b |= ((uint64_t) in[3]) << 24; + /* FALLTHRU */ + case 3: + b |= ((uint64_t) in[2]) << 16; + /* FALLTHRU */ + case 2: + b |= ((uint64_t) in[1]) << 8; + /* FALLTHRU */ + case 1: + b |= ((uint64_t) in[0]); + break; + case 0: + break; + } + v3 ^= b; + SIPROUND; + SIPROUND; + v0 ^= b; + v2 ^= 0xff; + SIPROUND; + SIPROUND; + SIPROUND; + SIPROUND; + b = v0 ^ v1 ^ v2 ^ v3; + STORE64_LE(out, b); + + return 0; +} diff --git a/external/src/libsodium/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphash_ref.h b/external/src/libsodium/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphash_ref.h new file mode 100644 index 0000000..3f9a38b --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphash_ref.h @@ -0,0 +1,24 @@ +#ifndef shorthash_siphash_H +#define shorthash_siphash_H + +#include "private/common.h" + +#define SIPROUND \ + do { \ + v0 += v1; \ + v1 = ROTL64(v1, 13); \ + v1 ^= v0; \ + v0 = ROTL64(v0, 32); \ + v2 += v3; \ + v3 = ROTL64(v3, 16); \ + v3 ^= v2; \ + v0 += v3; \ + v3 = ROTL64(v3, 21); \ + v3 ^= v0; \ + v2 += v1; \ + v1 = ROTL64(v1, 17); \ + v1 ^= v2; \ + v2 = ROTL64(v2, 32); \ + } while (0) + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c b/external/src/libsodium/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c new file mode 100644 index 0000000..be984ee --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_shorthash/siphash24/ref/shorthash_siphashx24_ref.c @@ -0,0 +1,77 @@ +#include "crypto_shorthash_siphash24.h" +#include "private/common.h" +#include "shorthash_siphash_ref.h" + +int +crypto_shorthash_siphashx24(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) +{ + uint64_t v0 = 0x736f6d6570736575ULL; + uint64_t v1 = 0x646f72616e646f83ULL; + uint64_t v2 = 0x6c7967656e657261ULL; + uint64_t v3 = 0x7465646279746573ULL; + uint64_t b; + uint64_t k0 = LOAD64_LE(k); + uint64_t k1 = LOAD64_LE(k + 8); + uint64_t m; + const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t)); + const int left = inlen & 7; + + b = ((uint64_t) inlen) << 56; + v3 ^= k1; + v2 ^= k0; + v1 ^= k1; + v0 ^= k0; + for (; in != end; in += 8) { + m = LOAD64_LE(in); + v3 ^= m; + SIPROUND; + SIPROUND; + v0 ^= m; + } + switch (left) { + case 7: + b |= ((uint64_t) in[6]) << 48; + /* FALLTHRU */ + case 6: + b |= ((uint64_t) in[5]) << 40; + /* FALLTHRU */ + case 5: + b |= ((uint64_t) in[4]) << 32; + /* FALLTHRU */ + case 4: + b |= ((uint64_t) in[3]) << 24; + /* FALLTHRU */ + case 3: + b |= ((uint64_t) in[2]) << 16; + /* FALLTHRU */ + case 2: + b |= ((uint64_t) in[1]) << 8; + /* FALLTHRU */ + case 1: + b |= ((uint64_t) in[0]); + break; + case 0: + break; + } + v3 ^= b; + SIPROUND; + SIPROUND; + v0 ^= b; + v2 ^= 0xee; + SIPROUND; + SIPROUND; + SIPROUND; + SIPROUND; + b = v0 ^ v1 ^ v2 ^ v3; + STORE64_LE(out, b); + v1 ^= 0xdd; + SIPROUND; + SIPROUND; + SIPROUND; + SIPROUND; + b = v0 ^ v1 ^ v2 ^ v3; + STORE64_LE(out + 8, b); + + return 0; +} diff --git a/external/src/libsodium/src/libsodium/crypto_shorthash/siphash24/shorthash_siphash24.c b/external/src/libsodium/src/libsodium/crypto_shorthash/siphash24/shorthash_siphash24.c new file mode 100644 index 0000000..e2cea77 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_shorthash/siphash24/shorthash_siphash24.c @@ -0,0 +1,11 @@ +#include "crypto_shorthash_siphash24.h" + +size_t +crypto_shorthash_siphash24_bytes(void) { + return crypto_shorthash_siphash24_BYTES; +} + +size_t +crypto_shorthash_siphash24_keybytes(void) { + return crypto_shorthash_siphash24_KEYBYTES; +} diff --git a/external/src/libsodium/src/libsodium/crypto_shorthash/siphash24/shorthash_siphashx24.c b/external/src/libsodium/src/libsodium/crypto_shorthash/siphash24/shorthash_siphashx24.c new file mode 100644 index 0000000..2d487db --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_shorthash/siphash24/shorthash_siphashx24.c @@ -0,0 +1,11 @@ +#include "crypto_shorthash_siphash24.h" + +size_t +crypto_shorthash_siphashx24_bytes(void) { + return crypto_shorthash_siphashx24_BYTES; +} + +size_t +crypto_shorthash_siphashx24_keybytes(void) { + return crypto_shorthash_siphashx24_KEYBYTES; +} diff --git a/external/src/libsodium/src/libsodium/crypto_sign/crypto_sign.c b/external/src/libsodium/src/libsodium/crypto_sign/crypto_sign.c new file mode 100644 index 0000000..d723ff8 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_sign/crypto_sign.c @@ -0,0 +1,115 @@ + +#include "crypto_sign.h" + +size_t +crypto_sign_statebytes(void) +{ + return sizeof(crypto_sign_state); +} + +size_t +crypto_sign_bytes(void) +{ + return crypto_sign_BYTES; +} + +size_t +crypto_sign_seedbytes(void) +{ + return crypto_sign_SEEDBYTES; +} + +size_t +crypto_sign_publickeybytes(void) +{ + return crypto_sign_PUBLICKEYBYTES; +} + +size_t +crypto_sign_secretkeybytes(void) +{ + return crypto_sign_SECRETKEYBYTES; +} + +size_t +crypto_sign_messagebytes_max(void) +{ + return crypto_sign_MESSAGEBYTES_MAX; +} + +const char * +crypto_sign_primitive(void) +{ + return crypto_sign_PRIMITIVE; +} + +int +crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed) +{ + return crypto_sign_ed25519_seed_keypair(pk, sk, seed); +} + +int +crypto_sign_keypair(unsigned char *pk, unsigned char *sk) +{ + return crypto_sign_ed25519_keypair(pk, sk); +} + +int +crypto_sign(unsigned char *sm, unsigned long long *smlen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) +{ + return crypto_sign_ed25519(sm, smlen_p, m, mlen, sk); +} + +int +crypto_sign_open(unsigned char *m, unsigned long long *mlen_p, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) +{ + return crypto_sign_ed25519_open(m, mlen_p, sm, smlen, pk); +} + +int +crypto_sign_detached(unsigned char *sig, unsigned long long *siglen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) +{ + return crypto_sign_ed25519_detached(sig, siglen_p, m, mlen, sk); +} + +int +crypto_sign_verify_detached(const unsigned char *sig, const unsigned char *m, + unsigned long long mlen, const unsigned char *pk) +{ + return crypto_sign_ed25519_verify_detached(sig, m, mlen, pk); +} + +int +crypto_sign_init(crypto_sign_state *state) +{ + return crypto_sign_ed25519ph_init(state); +} + +int +crypto_sign_update(crypto_sign_state *state, const unsigned char *m, + unsigned long long mlen) +{ + return crypto_sign_ed25519ph_update(state, m, mlen); +} + +int +crypto_sign_final_create(crypto_sign_state *state, unsigned char *sig, + unsigned long long *siglen_p, const unsigned char *sk) +{ + return crypto_sign_ed25519ph_final_create(state, sig, siglen_p, sk); +} + +int +crypto_sign_final_verify(crypto_sign_state *state, const unsigned char *sig, + const unsigned char *pk) +{ + return crypto_sign_ed25519ph_final_verify(state, sig, pk); +} diff --git a/external/src/libsodium/src/libsodium/crypto_sign/ed25519/ref10/keypair.c b/external/src/libsodium/src/libsodium/crypto_sign/ed25519/ref10/keypair.c new file mode 100644 index 0000000..e8e4015 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_sign/ed25519/ref10/keypair.c @@ -0,0 +1,83 @@ + +#include + +#include "crypto_hash_sha512.h" +#include "crypto_scalarmult_curve25519.h" +#include "crypto_sign_ed25519.h" +#include "sign_ed25519_ref10.h" +#include "private/ed25519_ref10.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_sign_ed25519_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed) +{ + ge25519_p3 A; + + crypto_hash_sha512(sk, seed, 32); + sk[0] &= 248; + sk[31] &= 127; + sk[31] |= 64; + + ge25519_scalarmult_base(&A, sk); + ge25519_p3_tobytes(pk, &A); + + memmove(sk, seed, 32); + memmove(sk + 32, pk, 32); + + return 0; +} + +int +crypto_sign_ed25519_keypair(unsigned char *pk, unsigned char *sk) +{ + unsigned char seed[32]; + int ret; + + randombytes_buf(seed, sizeof seed); + ret = crypto_sign_ed25519_seed_keypair(pk, sk, seed); + sodium_memzero(seed, sizeof seed); + + return ret; +} + +int +crypto_sign_ed25519_pk_to_curve25519(unsigned char *curve25519_pk, + const unsigned char *ed25519_pk) +{ + ge25519_p3 A; + fe25519 x; + fe25519 one_minus_y; + + if (ge25519_has_small_order(ed25519_pk) != 0 || + ge25519_frombytes_negate_vartime(&A, ed25519_pk) != 0 || + ge25519_is_on_main_subgroup(&A) == 0) { + return -1; + } + fe25519_1(one_minus_y); + fe25519_sub(one_minus_y, one_minus_y, A.Y); + fe25519_1(x); + fe25519_add(x, x, A.Y); + fe25519_invert(one_minus_y, one_minus_y); + fe25519_mul(x, x, one_minus_y); + fe25519_tobytes(curve25519_pk, x); + + return 0; +} + +int +crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk, + const unsigned char *ed25519_sk) +{ + unsigned char h[crypto_hash_sha512_BYTES]; + + crypto_hash_sha512(h, ed25519_sk, 32); + h[0] &= 248; + h[31] &= 127; + h[31] |= 64; + memcpy(curve25519_sk, h, crypto_scalarmult_curve25519_BYTES); + sodium_memzero(h, sizeof h); + + return 0; +} diff --git a/external/src/libsodium/src/libsodium/crypto_sign/ed25519/ref10/obsolete.c b/external/src/libsodium/src/libsodium/crypto_sign/ed25519/ref10/obsolete.c new file mode 100644 index 0000000..64ded79 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_sign/ed25519/ref10/obsolete.c @@ -0,0 +1,118 @@ + +#include +#include +#include + +#include "crypto_hash_sha512.h" +#include "crypto_sign_edwards25519sha512batch.h" +#include "crypto_verify_32.h" +#include "private/ed25519_ref10.h" +#include "randombytes.h" +#include "utils.h" + +/* LCOV_EXCL_START */ +int +crypto_sign_edwards25519sha512batch_keypair(unsigned char *pk, + unsigned char *sk) +{ + ge25519_p3 A; + + randombytes_buf(sk, 32); + crypto_hash_sha512(sk, sk, 32); + sk[0] &= 248; + sk[31] &= 127; + sk[31] |= 64; + ge25519_scalarmult_base(&A, sk); + ge25519_p3_tobytes(pk, &A); + + return 0; +} + +int +crypto_sign_edwards25519sha512batch(unsigned char *sm, + unsigned long long *smlen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *sk) +{ + crypto_hash_sha512_state hs; + unsigned char nonce[64]; + unsigned char hram[64]; + unsigned char sig[64]; + ge25519_p3 A; + ge25519_p3 R; + + crypto_hash_sha512_init(&hs); + crypto_hash_sha512_update(&hs, sk + 32, 32); + crypto_hash_sha512_update(&hs, m, mlen); + crypto_hash_sha512_final(&hs, nonce); + ge25519_scalarmult_base(&A, sk); + ge25519_p3_tobytes(sig + 32, &A); + sc25519_reduce(nonce); + ge25519_scalarmult_base(&R, nonce); + ge25519_p3_tobytes(sig, &R); + crypto_hash_sha512_init(&hs); + crypto_hash_sha512_update(&hs, sig, 32); + crypto_hash_sha512_update(&hs, m, mlen); + crypto_hash_sha512_final(&hs, hram); + sc25519_reduce(hram); + sc25519_muladd(sig + 32, hram, nonce, sk); + sodium_memzero(hram, sizeof hram); + memmove(sm + 32, m, (size_t) mlen); + memcpy(sm, sig, 32); + memcpy(sm + 32 + mlen, sig + 32, 32); + *smlen_p = mlen + 64U; + + return 0; +} + +int +crypto_sign_edwards25519sha512batch_open(unsigned char *m, + unsigned long long *mlen_p, + const unsigned char *sm, + unsigned long long smlen, + const unsigned char *pk) +{ + unsigned char h[64]; + unsigned char t1[32], t2[32]; + unsigned long long mlen; + ge25519_cached Ai; + ge25519_p1p1 csa; + ge25519_p2 cs; + ge25519_p3 A; + ge25519_p3 R; + ge25519_p3 cs3; + + *mlen_p = 0; + if (smlen < 64 || smlen - 64 > crypto_sign_edwards25519sha512batch_MESSAGEBYTES_MAX) { + return -1; + } + mlen = smlen - 64; + if (sm[smlen - 1] & 224) { + return -1; + } + if (ge25519_has_small_order(pk) != 0 || + ge25519_frombytes_negate_vartime(&A, pk) != 0 || + ge25519_has_small_order(sm) != 0 || + ge25519_frombytes_negate_vartime(&R, sm) != 0) { + return -1; + } + ge25519_p3_to_cached(&Ai, &A); + crypto_hash_sha512(h, sm, mlen + 32); + sc25519_reduce(h); + ge25519_scalarmult(&cs3, h, &R); + ge25519_add(&csa, &cs3, &Ai); + ge25519_p1p1_to_p2(&cs, &csa); + ge25519_tobytes(t1, &cs); + t1[31] ^= 1 << 7; + ge25519_scalarmult_base(&R, sm + 32 + mlen); + ge25519_p3_tobytes(t2, &R); + if (crypto_verify_32(t1, t2) != 0) { + return -1; + } + *mlen_p = mlen; + memmove(m, sm + 32, mlen); + + return 0; +} +/* LCOV_EXCL_END */ diff --git a/external/src/libsodium/src/libsodium/crypto_sign/ed25519/ref10/open.c b/external/src/libsodium/src/libsodium/crypto_sign/ed25519/ref10/open.c new file mode 100644 index 0000000..26476b3 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_sign/ed25519/ref10/open.c @@ -0,0 +1,96 @@ + +#include +#include +#include + +#include "crypto_hash_sha512.h" +#include "crypto_sign_ed25519.h" +#include "crypto_verify_32.h" +#include "sign_ed25519_ref10.h" +#include "private/ed25519_ref10.h" +#include "utils.h" + +int +_crypto_sign_ed25519_verify_detached(const unsigned char *sig, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk, + int prehashed) +{ + crypto_hash_sha512_state hs; + unsigned char h[64]; + unsigned char rcheck[32]; + ge25519_p3 A; + ge25519_p2 R; + +#ifdef ED25519_COMPAT + if (sig[63] & 224) { + return -1; + } +#else + if (sc25519_is_canonical(sig + 32) == 0 || + ge25519_has_small_order(sig) != 0) { + return -1; + } + if (ge25519_is_canonical(pk) == 0 || + ge25519_has_small_order(pk) != 0) { + return -1; + } +#endif + if (ge25519_frombytes_negate_vartime(&A, pk) != 0) { + return -1; + } + _crypto_sign_ed25519_ref10_hinit(&hs, prehashed); + crypto_hash_sha512_update(&hs, sig, 32); + crypto_hash_sha512_update(&hs, pk, 32); + crypto_hash_sha512_update(&hs, m, mlen); + crypto_hash_sha512_final(&hs, h); + sc25519_reduce(h); + + ge25519_double_scalarmult_vartime(&R, h, &A, sig + 32); + ge25519_tobytes(rcheck, &R); + + return crypto_verify_32(rcheck, sig) | (-(rcheck == sig)) | + sodium_memcmp(sig, rcheck, 32); +} + +int +crypto_sign_ed25519_verify_detached(const unsigned char *sig, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk) +{ + return _crypto_sign_ed25519_verify_detached(sig, m, mlen, pk, 0); +} + +int +crypto_sign_ed25519_open(unsigned char *m, unsigned long long *mlen_p, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) +{ + unsigned long long mlen; + + if (smlen < 64 || smlen - 64 > crypto_sign_ed25519_MESSAGEBYTES_MAX) { + goto badsig; + } + mlen = smlen - 64; + if (crypto_sign_ed25519_verify_detached(sm, sm + 64, mlen, pk) != 0) { + if (m != NULL) { + memset(m, 0, mlen); + } + goto badsig; + } + if (mlen_p != NULL) { + *mlen_p = mlen; + } + if (m != NULL) { + memmove(m, sm + 64, mlen); + } + return 0; + +badsig: + if (mlen_p != NULL) { + *mlen_p = 0; + } + return -1; +} diff --git a/external/src/libsodium/src/libsodium/crypto_sign/ed25519/ref10/sign.c b/external/src/libsodium/src/libsodium/crypto_sign/ed25519/ref10/sign.c new file mode 100644 index 0000000..bbdd8f7 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_sign/ed25519/ref10/sign.c @@ -0,0 +1,143 @@ + +#include + +#include "crypto_hash_sha512.h" +#include "crypto_sign_ed25519.h" +#include "sign_ed25519_ref10.h" +#include "private/ed25519_ref10.h" +#include "randombytes.h" +#include "utils.h" + +void +_crypto_sign_ed25519_ref10_hinit(crypto_hash_sha512_state *hs, int prehashed) +{ + static const unsigned char DOM2PREFIX[32 + 2] = { + 'S', 'i', 'g', 'E', 'd', '2', '5', '5', '1', '9', ' ', + 'n', 'o', ' ', + 'E', 'd', '2', '5', '5', '1', '9', ' ', + 'c', 'o', 'l', 'l', 'i', 's', 'i', 'o', 'n', 's', 1, 0 + }; + + crypto_hash_sha512_init(hs); + if (prehashed) { + crypto_hash_sha512_update(hs, DOM2PREFIX, sizeof DOM2PREFIX); + } +} + +static inline void +_crypto_sign_ed25519_clamp(unsigned char k[32]) +{ + k[0] &= 248; + k[31] &= 127; + k[31] |= 64; +} + +#ifdef ED25519_NONDETERMINISTIC +/* r = hash(B || empty_labelset || Z || pad1 || k || pad2 || empty_labelset || K || extra || M) (mod q) */ +static void +_crypto_sign_ed25519_synthetic_r_hv(crypto_hash_sha512_state *hs, + unsigned char Z[32], + const unsigned char sk[64]) +{ + static const unsigned char B[32] = { + 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + }; + static const unsigned char zeros[128] = { 0x00 }; + static const unsigned char empty_labelset[3] = { 0x02, 0x00, 0x00 }; + + crypto_hash_sha512_update(hs, B, 32); + crypto_hash_sha512_update(hs, empty_labelset, 3); + randombytes_buf(Z, 32); + crypto_hash_sha512_update(hs, Z, 32); + crypto_hash_sha512_update(hs, zeros, 128 - (32 + 3 + 32) % 128); + crypto_hash_sha512_update(hs, sk, 32); + crypto_hash_sha512_update(hs, zeros, 128 - 32 % 128); + crypto_hash_sha512_update(hs, empty_labelset, 3); + crypto_hash_sha512_update(hs, sk + 32, 32); + /* empty extra */ +} +#endif + +int +_crypto_sign_ed25519_detached(unsigned char *sig, unsigned long long *siglen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk, int prehashed) +{ + crypto_hash_sha512_state hs; + unsigned char az[64]; + unsigned char nonce[64]; + unsigned char hram[64]; + ge25519_p3 R; + + _crypto_sign_ed25519_ref10_hinit(&hs, prehashed); + + crypto_hash_sha512(az, sk, 32); +#ifdef ED25519_NONDETERMINISTIC + _crypto_sign_ed25519_synthetic_r_hv(&hs, nonce /* Z */, az); +#else + crypto_hash_sha512_update(&hs, az + 32, 32); +#endif + + crypto_hash_sha512_update(&hs, m, mlen); + crypto_hash_sha512_final(&hs, nonce); + + memmove(sig + 32, sk + 32, 32); + + sc25519_reduce(nonce); + ge25519_scalarmult_base(&R, nonce); + ge25519_p3_tobytes(sig, &R); + + _crypto_sign_ed25519_ref10_hinit(&hs, prehashed); + crypto_hash_sha512_update(&hs, sig, 64); + crypto_hash_sha512_update(&hs, m, mlen); + crypto_hash_sha512_final(&hs, hram); + + sc25519_reduce(hram); + _crypto_sign_ed25519_clamp(az); + sc25519_muladd(sig + 32, hram, az, nonce); + + sodium_memzero(az, sizeof az); + sodium_memzero(nonce, sizeof nonce); + + if (siglen_p != NULL) { + *siglen_p = 64U; + } + return 0; +} + +int +crypto_sign_ed25519_detached(unsigned char *sig, unsigned long long *siglen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) +{ + return _crypto_sign_ed25519_detached(sig, siglen_p, m, mlen, sk, 0); +} + +int +crypto_sign_ed25519(unsigned char *sm, unsigned long long *smlen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) +{ + unsigned long long siglen; + + memmove(sm + crypto_sign_ed25519_BYTES, m, mlen); + /* LCOV_EXCL_START */ + if (crypto_sign_ed25519_detached( + sm, &siglen, sm + crypto_sign_ed25519_BYTES, mlen, sk) != 0 || + siglen != crypto_sign_ed25519_BYTES) { + if (smlen_p != NULL) { + *smlen_p = 0; + } + memset(sm, 0, mlen + crypto_sign_ed25519_BYTES); + return -1; + } + /* LCOV_EXCL_STOP */ + + if (smlen_p != NULL) { + *smlen_p = mlen + siglen; + } + return 0; +} diff --git a/external/src/libsodium/src/libsodium/crypto_sign/ed25519/ref10/sign_ed25519_ref10.h b/external/src/libsodium/src/libsodium/crypto_sign/ed25519/ref10/sign_ed25519_ref10.h new file mode 100644 index 0000000..29f45a8 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_sign/ed25519/ref10/sign_ed25519_ref10.h @@ -0,0 +1,18 @@ +#ifndef sign_ed25519_ref10_H +#define sign_ed25519_ref10_H + +void _crypto_sign_ed25519_ref10_hinit(crypto_hash_sha512_state *hs, + int prehashed); + +int _crypto_sign_ed25519_detached(unsigned char *sig, + unsigned long long *siglen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *sk, int prehashed); + +int _crypto_sign_ed25519_verify_detached(const unsigned char *sig, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk, + int prehashed); +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_sign/ed25519/sign_ed25519.c b/external/src/libsodium/src/libsodium/crypto_sign/ed25519/sign_ed25519.c new file mode 100644 index 0000000..9b90249 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_sign/ed25519/sign_ed25519.c @@ -0,0 +1,97 @@ + +#include + +#include "crypto_hash_sha512.h" +#include "crypto_sign_ed25519.h" +#include "ref10/sign_ed25519_ref10.h" + +size_t +crypto_sign_ed25519ph_statebytes(void) +{ + return sizeof(crypto_sign_ed25519ph_state); +} + +size_t +crypto_sign_ed25519_bytes(void) +{ + return crypto_sign_ed25519_BYTES; +} + +size_t +crypto_sign_ed25519_seedbytes(void) +{ + return crypto_sign_ed25519_SEEDBYTES; +} + +size_t +crypto_sign_ed25519_publickeybytes(void) +{ + return crypto_sign_ed25519_PUBLICKEYBYTES; +} + +size_t +crypto_sign_ed25519_secretkeybytes(void) +{ + return crypto_sign_ed25519_SECRETKEYBYTES; +} + +size_t +crypto_sign_ed25519_messagebytes_max(void) +{ + return crypto_sign_ed25519_MESSAGEBYTES_MAX; +} + +int +crypto_sign_ed25519_sk_to_seed(unsigned char *seed, const unsigned char *sk) +{ + memmove(seed, sk, crypto_sign_ed25519_SEEDBYTES); + + return 0; +} + +int +crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk) +{ + memmove(pk, sk + crypto_sign_ed25519_SEEDBYTES, + crypto_sign_ed25519_PUBLICKEYBYTES); + return 0; +} + +int +crypto_sign_ed25519ph_init(crypto_sign_ed25519ph_state *state) +{ + crypto_hash_sha512_init(&state->hs); + return 0; +} + +int +crypto_sign_ed25519ph_update(crypto_sign_ed25519ph_state *state, + const unsigned char *m, unsigned long long mlen) +{ + return crypto_hash_sha512_update(&state->hs, m, mlen); +} + +int +crypto_sign_ed25519ph_final_create(crypto_sign_ed25519ph_state *state, + unsigned char *sig, + unsigned long long *siglen_p, + const unsigned char *sk) +{ + unsigned char ph[crypto_hash_sha512_BYTES]; + + crypto_hash_sha512_final(&state->hs, ph); + + return _crypto_sign_ed25519_detached(sig, siglen_p, ph, sizeof ph, sk, 1); +} + +int +crypto_sign_ed25519ph_final_verify(crypto_sign_ed25519ph_state *state, + const unsigned char *sig, + const unsigned char *pk) +{ + unsigned char ph[crypto_hash_sha512_BYTES]; + + crypto_hash_sha512_final(&state->hs, ph); + + return _crypto_sign_ed25519_verify_detached(sig, ph, sizeof ph, pk, 1); +} diff --git a/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c new file mode 100644 index 0000000..6100050 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c @@ -0,0 +1,177 @@ + +#include +#include +#include + +#include "core.h" +#include "crypto_stream_chacha20.h" +#include "private/common.h" +#include "utils.h" + +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# pragma GCC target("sse4.1") +# pragma GCC target("avx2") +# endif + +# include +# include +# include +# include +# include "private/sse2_64_32.h" + +# include "../stream_chacha20.h" +# include "chacha20_dolbeau-avx2.h" + +# define ROUNDS 20 + +typedef struct chacha_ctx { + uint32_t input[16]; +} chacha_ctx; + +static void +chacha_keysetup(chacha_ctx *ctx, const uint8_t *k) +{ + ctx->input[0] = 0x61707865; + ctx->input[1] = 0x3320646e; + ctx->input[2] = 0x79622d32; + ctx->input[3] = 0x6b206574; + ctx->input[4] = LOAD32_LE(k + 0); + ctx->input[5] = LOAD32_LE(k + 4); + ctx->input[6] = LOAD32_LE(k + 8); + ctx->input[7] = LOAD32_LE(k + 12); + ctx->input[8] = LOAD32_LE(k + 16); + ctx->input[9] = LOAD32_LE(k + 20); + ctx->input[10] = LOAD32_LE(k + 24); + ctx->input[11] = LOAD32_LE(k + 28); +} + +static void +chacha_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter + 0); + ctx->input[13] = counter == NULL ? 0 : LOAD32_LE(counter + 4); + ctx->input[14] = LOAD32_LE(iv + 0); + ctx->input[15] = LOAD32_LE(iv + 4); +} + +static void +chacha_ietf_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter); + ctx->input[13] = LOAD32_LE(iv + 0); + ctx->input[14] = LOAD32_LE(iv + 4); + ctx->input[15] = LOAD32_LE(iv + 8); +} + +static void +chacha20_encrypt_bytes(chacha_ctx *ctx, const uint8_t *m, uint8_t *c, + unsigned long long bytes) +{ + uint32_t * const x = &ctx->input[0]; + + if (!bytes) { + return; /* LCOV_EXCL_LINE */ + } +# include "u8.h" +# include "u4.h" +# include "u1.h" +# include "u0.h" +} + +static int +stream_ref(unsigned char *c, unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + struct chacha_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8); + chacha_keysetup(&ctx, k); + chacha_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + chacha20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ietf_ext_ref(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + struct chacha_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8); + chacha_keysetup(&ctx, k); + chacha_ietf_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + chacha20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + struct chacha_ctx ctx; + uint8_t ic_bytes[8]; + uint32_t ic_high; + uint32_t ic_low; + + if (!mlen) { + return 0; + } + ic_high = (uint32_t) (ic >> 32); + ic_low = (uint32_t) ic; + STORE32_LE(&ic_bytes[0], ic_low); + STORE32_LE(&ic_bytes[4], ic_high); + chacha_keysetup(&ctx, k); + chacha_ivsetup(&ctx, n, ic_bytes); + chacha20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ietf_ext_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + uint32_t ic, const unsigned char *k) +{ + struct chacha_ctx ctx; + uint8_t ic_bytes[4]; + + if (!mlen) { + return 0; + } + STORE32_LE(ic_bytes, ic); + chacha_keysetup(&ctx, k); + chacha_ietf_ivsetup(&ctx, n, ic_bytes); + chacha20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +struct crypto_stream_chacha20_implementation + crypto_stream_chacha20_dolbeau_avx2_implementation = { + SODIUM_C99(.stream =) stream_ref, + SODIUM_C99(.stream_ietf_ext =) stream_ietf_ext_ref, + SODIUM_C99(.stream_xor_ic =) stream_ref_xor_ic, + SODIUM_C99(.stream_ietf_ext_xor_ic =) stream_ietf_ext_ref_xor_ic + }; + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.h b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.h new file mode 100644 index 0000000..45eb98d --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.h @@ -0,0 +1,8 @@ + +#include + +#include "../stream_chacha20.h" +#include "crypto_stream_chacha20.h" + +extern struct crypto_stream_chacha20_implementation + crypto_stream_chacha20_dolbeau_avx2_implementation; diff --git a/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c new file mode 100644 index 0000000..ad13c3a --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c @@ -0,0 +1,171 @@ + +#include +#include +#include + +#include "core.h" +#include "crypto_stream_chacha20.h" +#include "private/common.h" +#include "utils.h" + +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# endif + +# include +# include +# include "private/sse2_64_32.h" + +# include "../stream_chacha20.h" +# include "chacha20_dolbeau-ssse3.h" + +# define ROUNDS 20 + +typedef struct chacha_ctx { + uint32_t input[16]; +} chacha_ctx; + +static void +chacha_keysetup(chacha_ctx *ctx, const uint8_t *k) +{ + ctx->input[0] = 0x61707865; + ctx->input[1] = 0x3320646e; + ctx->input[2] = 0x79622d32; + ctx->input[3] = 0x6b206574; + ctx->input[4] = LOAD32_LE(k + 0); + ctx->input[5] = LOAD32_LE(k + 4); + ctx->input[6] = LOAD32_LE(k + 8); + ctx->input[7] = LOAD32_LE(k + 12); + ctx->input[8] = LOAD32_LE(k + 16); + ctx->input[9] = LOAD32_LE(k + 20); + ctx->input[10] = LOAD32_LE(k + 24); + ctx->input[11] = LOAD32_LE(k + 28); +} + +static void +chacha_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter + 0); + ctx->input[13] = counter == NULL ? 0 : LOAD32_LE(counter + 4); + ctx->input[14] = LOAD32_LE(iv + 0); + ctx->input[15] = LOAD32_LE(iv + 4); +} + +static void +chacha_ietf_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter); + ctx->input[13] = LOAD32_LE(iv + 0); + ctx->input[14] = LOAD32_LE(iv + 4); + ctx->input[15] = LOAD32_LE(iv + 8); +} + +static void +chacha20_encrypt_bytes(chacha_ctx *ctx, const uint8_t *m, uint8_t *c, + unsigned long long bytes) +{ + uint32_t * const x = &ctx->input[0]; + + if (!bytes) { + return; /* LCOV_EXCL_LINE */ + } +# include "u4.h" +# include "u1.h" +# include "u0.h" +} + +static int +stream_ref(unsigned char *c, unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + struct chacha_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8); + chacha_keysetup(&ctx, k); + chacha_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + chacha20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ietf_ext_ref(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + struct chacha_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8); + chacha_keysetup(&ctx, k); + chacha_ietf_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + chacha20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + struct chacha_ctx ctx; + uint8_t ic_bytes[8]; + uint32_t ic_high; + uint32_t ic_low; + + if (!mlen) { + return 0; + } + ic_high = (uint32_t) (ic >> 32); + ic_low = (uint32_t) ic; + STORE32_LE(&ic_bytes[0], ic_low); + STORE32_LE(&ic_bytes[4], ic_high); + chacha_keysetup(&ctx, k); + chacha_ivsetup(&ctx, n, ic_bytes); + chacha20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ietf_ext_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + uint32_t ic, const unsigned char *k) +{ + struct chacha_ctx ctx; + uint8_t ic_bytes[4]; + + if (!mlen) { + return 0; + } + STORE32_LE(ic_bytes, ic); + chacha_keysetup(&ctx, k); + chacha_ietf_ivsetup(&ctx, n, ic_bytes); + chacha20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +struct crypto_stream_chacha20_implementation + crypto_stream_chacha20_dolbeau_ssse3_implementation = { + SODIUM_C99(.stream =) stream_ref, + SODIUM_C99(.stream_ietf_ext =) stream_ietf_ext_ref, + SODIUM_C99(.stream_xor_ic =) stream_ref_xor_ic, + SODIUM_C99(.stream_ietf_ext_xor_ic =) stream_ietf_ext_ref_xor_ic + }; + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.h b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.h new file mode 100644 index 0000000..d67630f --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.h @@ -0,0 +1,8 @@ + +#include + +#include "../stream_chacha20.h" +#include "crypto_stream_chacha20.h" + +extern struct crypto_stream_chacha20_implementation + crypto_stream_chacha20_dolbeau_ssse3_implementation; diff --git a/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/u0.h b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/u0.h new file mode 100644 index 0000000..c05dfd7 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/u0.h @@ -0,0 +1,86 @@ +if (bytes > 0) { + __m128i x_0, x_1, x_2, x_3; + __m128i t_1; + const __m128i rot16 = + _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2); + const __m128i rot8 = + _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3); + uint8_t partialblock[64]; + + unsigned int i; + + x_0 = _mm_loadu_si128((const __m128i*) (x + 0)); + x_1 = _mm_loadu_si128((const __m128i*) (x + 4)); + x_2 = _mm_loadu_si128((const __m128i*) (x + 8)); + x_3 = _mm_loadu_si128((const __m128i*) (x + 12)); + + for (i = 0; i < ROUNDS; i += 2) { + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_3 = _mm_shuffle_epi8(x_3, rot16); + + x_2 = _mm_add_epi32(x_2, x_3); + x_1 = _mm_xor_si128(x_1, x_2); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 12); + t_1 = _mm_srli_epi32(t_1, 20); + x_1 = _mm_xor_si128(x_1, t_1); + + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_0 = _mm_shuffle_epi32(x_0, 0x93); + x_3 = _mm_shuffle_epi8(x_3, rot8); + + x_2 = _mm_add_epi32(x_2, x_3); + x_3 = _mm_shuffle_epi32(x_3, 0x4e); + x_1 = _mm_xor_si128(x_1, x_2); + x_2 = _mm_shuffle_epi32(x_2, 0x39); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 7); + t_1 = _mm_srli_epi32(t_1, 25); + x_1 = _mm_xor_si128(x_1, t_1); + + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_3 = _mm_shuffle_epi8(x_3, rot16); + + x_2 = _mm_add_epi32(x_2, x_3); + x_1 = _mm_xor_si128(x_1, x_2); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 12); + t_1 = _mm_srli_epi32(t_1, 20); + x_1 = _mm_xor_si128(x_1, t_1); + + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_0 = _mm_shuffle_epi32(x_0, 0x39); + x_3 = _mm_shuffle_epi8(x_3, rot8); + + x_2 = _mm_add_epi32(x_2, x_3); + x_3 = _mm_shuffle_epi32(x_3, 0x4e); + x_1 = _mm_xor_si128(x_1, x_2); + x_2 = _mm_shuffle_epi32(x_2, 0x93); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 7); + t_1 = _mm_srli_epi32(t_1, 25); + x_1 = _mm_xor_si128(x_1, t_1); + } + x_0 = _mm_add_epi32(x_0, _mm_loadu_si128((const __m128i*) (x + 0))); + x_1 = _mm_add_epi32(x_1, _mm_loadu_si128((const __m128i*) (x + 4))); + x_2 = _mm_add_epi32(x_2, _mm_loadu_si128((const __m128i*) (x + 8))); + x_3 = _mm_add_epi32(x_3, _mm_loadu_si128((const __m128i*) (x + 12))); + _mm_storeu_si128((__m128i*) (partialblock + 0), x_0); + _mm_storeu_si128((__m128i*) (partialblock + 16), x_1); + _mm_storeu_si128((__m128i*) (partialblock + 32), x_2); + _mm_storeu_si128((__m128i*) (partialblock + 48), x_3); + + for (i = 0; i < bytes; i++) { + c[i] = m[i] ^ partialblock[i]; + } + + sodium_memzero(partialblock, sizeof partialblock); +} diff --git a/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/u1.h b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/u1.h new file mode 100644 index 0000000..f93fffe --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/u1.h @@ -0,0 +1,98 @@ +while (bytes >= 64) { + __m128i x_0, x_1, x_2, x_3; + __m128i t_1; + const __m128i rot16 = + _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2); + const __m128i rot8 = + _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3); + + uint32_t in12; + uint32_t in13; + int i; + + x_0 = _mm_loadu_si128((const __m128i*) (x + 0)); + x_1 = _mm_loadu_si128((const __m128i*) (x + 4)); + x_2 = _mm_loadu_si128((const __m128i*) (x + 8)); + x_3 = _mm_loadu_si128((const __m128i*) (x + 12)); + + for (i = 0; i < ROUNDS; i += 2) { + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_3 = _mm_shuffle_epi8(x_3, rot16); + + x_2 = _mm_add_epi32(x_2, x_3); + x_1 = _mm_xor_si128(x_1, x_2); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 12); + t_1 = _mm_srli_epi32(t_1, 20); + x_1 = _mm_xor_si128(x_1, t_1); + + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_0 = _mm_shuffle_epi32(x_0, 0x93); + x_3 = _mm_shuffle_epi8(x_3, rot8); + + x_2 = _mm_add_epi32(x_2, x_3); + x_3 = _mm_shuffle_epi32(x_3, 0x4e); + x_1 = _mm_xor_si128(x_1, x_2); + x_2 = _mm_shuffle_epi32(x_2, 0x39); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 7); + t_1 = _mm_srli_epi32(t_1, 25); + x_1 = _mm_xor_si128(x_1, t_1); + + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_3 = _mm_shuffle_epi8(x_3, rot16); + + x_2 = _mm_add_epi32(x_2, x_3); + x_1 = _mm_xor_si128(x_1, x_2); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 12); + t_1 = _mm_srli_epi32(t_1, 20); + x_1 = _mm_xor_si128(x_1, t_1); + + x_0 = _mm_add_epi32(x_0, x_1); + x_3 = _mm_xor_si128(x_3, x_0); + x_0 = _mm_shuffle_epi32(x_0, 0x39); + x_3 = _mm_shuffle_epi8(x_3, rot8); + + x_2 = _mm_add_epi32(x_2, x_3); + x_3 = _mm_shuffle_epi32(x_3, 0x4e); + x_1 = _mm_xor_si128(x_1, x_2); + x_2 = _mm_shuffle_epi32(x_2, 0x93); + + t_1 = x_1; + x_1 = _mm_slli_epi32(x_1, 7); + t_1 = _mm_srli_epi32(t_1, 25); + x_1 = _mm_xor_si128(x_1, t_1); + } + x_0 = _mm_add_epi32(x_0, _mm_loadu_si128((const __m128i*) (x + 0))); + x_1 = _mm_add_epi32(x_1, _mm_loadu_si128((const __m128i*) (x + 4))); + x_2 = _mm_add_epi32(x_2, _mm_loadu_si128((const __m128i*) (x + 8))); + x_3 = _mm_add_epi32(x_3, _mm_loadu_si128((const __m128i*) (x + 12))); + x_0 = _mm_xor_si128(x_0, _mm_loadu_si128((const __m128i*) (m + 0))); + x_1 = _mm_xor_si128(x_1, _mm_loadu_si128((const __m128i*) (m + 16))); + x_2 = _mm_xor_si128(x_2, _mm_loadu_si128((const __m128i*) (m + 32))); + x_3 = _mm_xor_si128(x_3, _mm_loadu_si128((const __m128i*) (m + 48))); + _mm_storeu_si128((__m128i*) (c + 0), x_0); + _mm_storeu_si128((__m128i*) (c + 16), x_1); + _mm_storeu_si128((__m128i*) (c + 32), x_2); + _mm_storeu_si128((__m128i*) (c + 48), x_3); + + in12 = x[12]; + in13 = x[13]; + in12++; + if (in12 == 0) { + in13++; + } + x[12] = in12; + x[13] = in13; + + bytes -= 64; + c += 64; + m += 64; +} diff --git a/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/u4.h b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/u4.h new file mode 100644 index 0000000..4ab295d --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/u4.h @@ -0,0 +1,177 @@ + +#define VEC4_ROT(A, IMM) \ + _mm_or_si128(_mm_slli_epi32(A, IMM), _mm_srli_epi32(A, (32 - IMM))) + +/* same, but replace 2 of the shift/shift/or "rotation" by byte shuffles (8 & + * 16) (better) */ +#define VEC4_QUARTERROUND_SHUFFLE(A, B, C, D) \ + x_##A = _mm_add_epi32(x_##A, x_##B); \ + t_##A = _mm_xor_si128(x_##D, x_##A); \ + x_##D = _mm_shuffle_epi8(t_##A, rot16); \ + x_##C = _mm_add_epi32(x_##C, x_##D); \ + t_##C = _mm_xor_si128(x_##B, x_##C); \ + x_##B = VEC4_ROT(t_##C, 12); \ + x_##A = _mm_add_epi32(x_##A, x_##B); \ + t_##A = _mm_xor_si128(x_##D, x_##A); \ + x_##D = _mm_shuffle_epi8(t_##A, rot8); \ + x_##C = _mm_add_epi32(x_##C, x_##D); \ + t_##C = _mm_xor_si128(x_##B, x_##C); \ + x_##B = VEC4_ROT(t_##C, 7) + +#define VEC4_QUARTERROUND(A, B, C, D) VEC4_QUARTERROUND_SHUFFLE(A, B, C, D) + +if (bytes >= 256) { + /* constant for shuffling bytes (replacing multiple-of-8 rotates) */ + __m128i rot16 = + _mm_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2); + __m128i rot8 = + _mm_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3); + + __m128i x_0 = _mm_set1_epi32(x[0]); + __m128i x_1 = _mm_set1_epi32(x[1]); + __m128i x_2 = _mm_set1_epi32(x[2]); + __m128i x_3 = _mm_set1_epi32(x[3]); + __m128i x_4 = _mm_set1_epi32(x[4]); + __m128i x_5 = _mm_set1_epi32(x[5]); + __m128i x_6 = _mm_set1_epi32(x[6]); + __m128i x_7 = _mm_set1_epi32(x[7]); + __m128i x_8 = _mm_set1_epi32(x[8]); + __m128i x_9 = _mm_set1_epi32(x[9]); + __m128i x_10 = _mm_set1_epi32(x[10]); + __m128i x_11 = _mm_set1_epi32(x[11]); + __m128i x_12; + __m128i x_13; + __m128i x_14 = _mm_set1_epi32(x[14]); + __m128i x_15 = _mm_set1_epi32(x[15]); + __m128i orig0 = x_0; + __m128i orig1 = x_1; + __m128i orig2 = x_2; + __m128i orig3 = x_3; + __m128i orig4 = x_4; + __m128i orig5 = x_5; + __m128i orig6 = x_6; + __m128i orig7 = x_7; + __m128i orig8 = x_8; + __m128i orig9 = x_9; + __m128i orig10 = x_10; + __m128i orig11 = x_11; + __m128i orig12; + __m128i orig13; + __m128i orig14 = x_14; + __m128i orig15 = x_15; + __m128i t_0, t_1, t_2, t_3, t_4, t_5, t_6, t_7, t_8, t_9, t_10, t_11, t_12, + t_13, t_14, t_15; + + uint32_t in12, in13; + int i; + + while (bytes >= 256) { + const __m128i addv12 = _mm_set_epi64x(1, 0); + const __m128i addv13 = _mm_set_epi64x(3, 2); + __m128i t12, t13; + uint64_t in1213; + + x_0 = orig0; + x_1 = orig1; + x_2 = orig2; + x_3 = orig3; + x_4 = orig4; + x_5 = orig5; + x_6 = orig6; + x_7 = orig7; + x_8 = orig8; + x_9 = orig9; + x_10 = orig10; + x_11 = orig11; + x_14 = orig14; + x_15 = orig15; + + in12 = x[12]; + in13 = x[13]; + in1213 = ((uint64_t) in12) | (((uint64_t) in13) << 32); + t12 = _mm_set1_epi64x(in1213); + t13 = _mm_set1_epi64x(in1213); + + x_12 = _mm_add_epi64(addv12, t12); + x_13 = _mm_add_epi64(addv13, t13); + + t12 = _mm_unpacklo_epi32(x_12, x_13); + t13 = _mm_unpackhi_epi32(x_12, x_13); + + x_12 = _mm_unpacklo_epi32(t12, t13); + x_13 = _mm_unpackhi_epi32(t12, t13); + + orig12 = x_12; + orig13 = x_13; + + in1213 += 4; + + x[12] = in1213 & 0xFFFFFFFF; + x[13] = (in1213 >> 32) & 0xFFFFFFFF; + + for (i = 0; i < ROUNDS; i += 2) { + VEC4_QUARTERROUND(0, 4, 8, 12); + VEC4_QUARTERROUND(1, 5, 9, 13); + VEC4_QUARTERROUND(2, 6, 10, 14); + VEC4_QUARTERROUND(3, 7, 11, 15); + VEC4_QUARTERROUND(0, 5, 10, 15); + VEC4_QUARTERROUND(1, 6, 11, 12); + VEC4_QUARTERROUND(2, 7, 8, 13); + VEC4_QUARTERROUND(3, 4, 9, 14); + } + +#define ONEQUAD_TRANSPOSE(A, B, C, D) \ + { \ + __m128i t0, t1, t2, t3; \ + \ + x_##A = _mm_add_epi32(x_##A, orig##A); \ + x_##B = _mm_add_epi32(x_##B, orig##B); \ + x_##C = _mm_add_epi32(x_##C, orig##C); \ + x_##D = _mm_add_epi32(x_##D, orig##D); \ + t_##A = _mm_unpacklo_epi32(x_##A, x_##B); \ + t_##B = _mm_unpacklo_epi32(x_##C, x_##D); \ + t_##C = _mm_unpackhi_epi32(x_##A, x_##B); \ + t_##D = _mm_unpackhi_epi32(x_##C, x_##D); \ + x_##A = _mm_unpacklo_epi64(t_##A, t_##B); \ + x_##B = _mm_unpackhi_epi64(t_##A, t_##B); \ + x_##C = _mm_unpacklo_epi64(t_##C, t_##D); \ + x_##D = _mm_unpackhi_epi64(t_##C, t_##D); \ + \ + t0 = _mm_xor_si128(x_##A, _mm_loadu_si128((const __m128i*) (m + 0))); \ + _mm_storeu_si128((__m128i*) (c + 0), t0); \ + t1 = _mm_xor_si128(x_##B, _mm_loadu_si128((const __m128i*) (m + 64))); \ + _mm_storeu_si128((__m128i*) (c + 64), t1); \ + t2 = \ + _mm_xor_si128(x_##C, _mm_loadu_si128((const __m128i*) (m + 128))); \ + _mm_storeu_si128((__m128i*) (c + 128), t2); \ + t3 = \ + _mm_xor_si128(x_##D, _mm_loadu_si128((const __m128i*) (m + 192))); \ + _mm_storeu_si128((__m128i*) (c + 192), t3); \ + } + +#define ONEQUAD(A, B, C, D) ONEQUAD_TRANSPOSE(A, B, C, D) + + ONEQUAD(0, 1, 2, 3); + m += 16; + c += 16; + ONEQUAD(4, 5, 6, 7); + m += 16; + c += 16; + ONEQUAD(8, 9, 10, 11); + m += 16; + c += 16; + ONEQUAD(12, 13, 14, 15); + m -= 48; + c -= 48; + +#undef ONEQUAD +#undef ONEQUAD_TRANSPOSE + + bytes -= 256; + c += 256; + m += 256; + } +} +#undef VEC4_ROT +#undef VEC4_QUARTERROUND +#undef VEC4_QUARTERROUND_SHUFFLE diff --git a/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/u8.h b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/u8.h new file mode 100644 index 0000000..f212f67 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/dolbeau/u8.h @@ -0,0 +1,326 @@ + +#define VEC8_ROT(A, IMM) \ + _mm256_or_si256(_mm256_slli_epi32(A, IMM), _mm256_srli_epi32(A, (32 - IMM))) + +/* same, but replace 2 of the shift/shift/or "rotation" by byte shuffles (8 & + * 16) (better) */ +#define VEC8_QUARTERROUND_SHUFFLE(A, B, C, D) \ + x_##A = _mm256_add_epi32(x_##A, x_##B); \ + t_##A = _mm256_xor_si256(x_##D, x_##A); \ + x_##D = _mm256_shuffle_epi8(t_##A, rot16); \ + x_##C = _mm256_add_epi32(x_##C, x_##D); \ + t_##C = _mm256_xor_si256(x_##B, x_##C); \ + x_##B = VEC8_ROT(t_##C, 12); \ + x_##A = _mm256_add_epi32(x_##A, x_##B); \ + t_##A = _mm256_xor_si256(x_##D, x_##A); \ + x_##D = _mm256_shuffle_epi8(t_##A, rot8); \ + x_##C = _mm256_add_epi32(x_##C, x_##D); \ + t_##C = _mm256_xor_si256(x_##B, x_##C); \ + x_##B = VEC8_ROT(t_##C, 7) + +#define VEC8_QUARTERROUND(A, B, C, D) VEC8_QUARTERROUND_SHUFFLE(A, B, C, D) + +#define VEC8_LINE1(A, B, C, D) \ + x_##A = _mm256_add_epi32(x_##A, x_##B); \ + x_##D = _mm256_shuffle_epi8(_mm256_xor_si256(x_##D, x_##A), rot16) +#define VEC8_LINE2(A, B, C, D) \ + x_##C = _mm256_add_epi32(x_##C, x_##D); \ + x_##B = VEC8_ROT(_mm256_xor_si256(x_##B, x_##C), 12) +#define VEC8_LINE3(A, B, C, D) \ + x_##A = _mm256_add_epi32(x_##A, x_##B); \ + x_##D = _mm256_shuffle_epi8(_mm256_xor_si256(x_##D, x_##A), rot8) +#define VEC8_LINE4(A, B, C, D) \ + x_##C = _mm256_add_epi32(x_##C, x_##D); \ + x_##B = VEC8_ROT(_mm256_xor_si256(x_##B, x_##C), 7) + +#define VEC8_ROUND_SEQ(A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, A4, B4, \ + C4, D4) \ + VEC8_LINE1(A1, B1, C1, D1); \ + VEC8_LINE1(A2, B2, C2, D2); \ + VEC8_LINE1(A3, B3, C3, D3); \ + VEC8_LINE1(A4, B4, C4, D4); \ + VEC8_LINE2(A1, B1, C1, D1); \ + VEC8_LINE2(A2, B2, C2, D2); \ + VEC8_LINE2(A3, B3, C3, D3); \ + VEC8_LINE2(A4, B4, C4, D4); \ + VEC8_LINE3(A1, B1, C1, D1); \ + VEC8_LINE3(A2, B2, C2, D2); \ + VEC8_LINE3(A3, B3, C3, D3); \ + VEC8_LINE3(A4, B4, C4, D4); \ + VEC8_LINE4(A1, B1, C1, D1); \ + VEC8_LINE4(A2, B2, C2, D2); \ + VEC8_LINE4(A3, B3, C3, D3); \ + VEC8_LINE4(A4, B4, C4, D4) + +#define VEC8_ROUND_HALF(A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, A4, \ + B4, C4, D4) \ + VEC8_LINE1(A1, B1, C1, D1); \ + VEC8_LINE1(A2, B2, C2, D2); \ + VEC8_LINE2(A1, B1, C1, D1); \ + VEC8_LINE2(A2, B2, C2, D2); \ + VEC8_LINE3(A1, B1, C1, D1); \ + VEC8_LINE3(A2, B2, C2, D2); \ + VEC8_LINE4(A1, B1, C1, D1); \ + VEC8_LINE4(A2, B2, C2, D2); \ + VEC8_LINE1(A3, B3, C3, D3); \ + VEC8_LINE1(A4, B4, C4, D4); \ + VEC8_LINE2(A3, B3, C3, D3); \ + VEC8_LINE2(A4, B4, C4, D4); \ + VEC8_LINE3(A3, B3, C3, D3); \ + VEC8_LINE3(A4, B4, C4, D4); \ + VEC8_LINE4(A3, B3, C3, D3); \ + VEC8_LINE4(A4, B4, C4, D4) + +#define VEC8_ROUND_HALFANDHALF(A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, \ + A4, B4, C4, D4) \ + VEC8_LINE1(A1, B1, C1, D1); \ + VEC8_LINE1(A2, B2, C2, D2); \ + VEC8_LINE2(A1, B1, C1, D1); \ + VEC8_LINE2(A2, B2, C2, D2); \ + VEC8_LINE1(A3, B3, C3, D3); \ + VEC8_LINE1(A4, B4, C4, D4); \ + VEC8_LINE2(A3, B3, C3, D3); \ + VEC8_LINE2(A4, B4, C4, D4); \ + VEC8_LINE3(A1, B1, C1, D1); \ + VEC8_LINE3(A2, B2, C2, D2); \ + VEC8_LINE4(A1, B1, C1, D1); \ + VEC8_LINE4(A2, B2, C2, D2); \ + VEC8_LINE3(A3, B3, C3, D3); \ + VEC8_LINE3(A4, B4, C4, D4); \ + VEC8_LINE4(A3, B3, C3, D3); \ + VEC8_LINE4(A4, B4, C4, D4) + +#define VEC8_ROUND(A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, A4, B4, C4, \ + D4) \ + VEC8_ROUND_SEQ(A1, B1, C1, D1, A2, B2, C2, D2, A3, B3, C3, D3, A4, B4, C4, \ + D4) + +if (bytes >= 512) { + /* constant for shuffling bytes (replacing multiple-of-8 rotates) */ + __m256i rot16 = + _mm256_set_epi8(13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2, + 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2); + __m256i rot8 = + _mm256_set_epi8(14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3, + 14, 13, 12, 15, 10, 9, 8, 11, 6, 5, 4, 7, 2, 1, 0, 3); + uint32_t in12, in13; + + /* the naive way seems as fast (if not a bit faster) than the vector way */ + __m256i x_0 = _mm256_set1_epi32(x[0]); + __m256i x_1 = _mm256_set1_epi32(x[1]); + __m256i x_2 = _mm256_set1_epi32(x[2]); + __m256i x_3 = _mm256_set1_epi32(x[3]); + __m256i x_4 = _mm256_set1_epi32(x[4]); + __m256i x_5 = _mm256_set1_epi32(x[5]); + __m256i x_6 = _mm256_set1_epi32(x[6]); + __m256i x_7 = _mm256_set1_epi32(x[7]); + __m256i x_8 = _mm256_set1_epi32(x[8]); + __m256i x_9 = _mm256_set1_epi32(x[9]); + __m256i x_10 = _mm256_set1_epi32(x[10]); + __m256i x_11 = _mm256_set1_epi32(x[11]); + __m256i x_12; + __m256i x_13; + __m256i x_14 = _mm256_set1_epi32(x[14]); + __m256i x_15 = _mm256_set1_epi32(x[15]); + + __m256i orig0 = x_0; + __m256i orig1 = x_1; + __m256i orig2 = x_2; + __m256i orig3 = x_3; + __m256i orig4 = x_4; + __m256i orig5 = x_5; + __m256i orig6 = x_6; + __m256i orig7 = x_7; + __m256i orig8 = x_8; + __m256i orig9 = x_9; + __m256i orig10 = x_10; + __m256i orig11 = x_11; + __m256i orig12; + __m256i orig13; + __m256i orig14 = x_14; + __m256i orig15 = x_15; + __m256i t_0, t_1, t_2, t_3, t_4, t_5, t_6, t_7, t_8, t_9, t_10, t_11, t_12, + t_13, t_14, t_15; + + while (bytes >= 512) { + const __m256i addv12 = _mm256_set_epi64x(3, 2, 1, 0); + const __m256i addv13 = _mm256_set_epi64x(7, 6, 5, 4); + const __m256i permute = _mm256_set_epi32(7, 6, 3, 2, 5, 4, 1, 0); + __m256i t12, t13; + + uint64_t in1213; + int i; + + x_0 = orig0; + x_1 = orig1; + x_2 = orig2; + x_3 = orig3; + x_4 = orig4; + x_5 = orig5; + x_6 = orig6; + x_7 = orig7; + x_8 = orig8; + x_9 = orig9; + x_10 = orig10; + x_11 = orig11; + x_14 = orig14; + x_15 = orig15; + + in12 = x[12]; + in13 = x[13]; + in1213 = ((uint64_t) in12) | (((uint64_t) in13) << 32); + x_12 = x_13 = _mm256_broadcastq_epi64(_mm_cvtsi64_si128(in1213)); + + t12 = _mm256_add_epi64(addv12, x_12); + t13 = _mm256_add_epi64(addv13, x_13); + + x_12 = _mm256_unpacklo_epi32(t12, t13); + x_13 = _mm256_unpackhi_epi32(t12, t13); + + t12 = _mm256_unpacklo_epi32(x_12, x_13); + t13 = _mm256_unpackhi_epi32(x_12, x_13); + + /* required because unpack* are intra-lane */ + x_12 = _mm256_permutevar8x32_epi32(t12, permute); + x_13 = _mm256_permutevar8x32_epi32(t13, permute); + + orig12 = x_12; + orig13 = x_13; + + in1213 += 8; + + x[12] = in1213 & 0xFFFFFFFF; + x[13] = (in1213 >> 32) & 0xFFFFFFFF; + + for (i = 0; i < ROUNDS; i += 2) { + VEC8_ROUND(0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15); + VEC8_ROUND(0, 5, 10, 15, 1, 6, 11, 12, 2, 7, 8, 13, 3, 4, 9, 14); + } + +#define ONEQUAD_TRANSPOSE(A, B, C, D) \ + { \ + __m128i t0, t1, t2, t3; \ + x_##A = _mm256_add_epi32(x_##A, orig##A); \ + x_##B = _mm256_add_epi32(x_##B, orig##B); \ + x_##C = _mm256_add_epi32(x_##C, orig##C); \ + x_##D = _mm256_add_epi32(x_##D, orig##D); \ + t_##A = _mm256_unpacklo_epi32(x_##A, x_##B); \ + t_##B = _mm256_unpacklo_epi32(x_##C, x_##D); \ + t_##C = _mm256_unpackhi_epi32(x_##A, x_##B); \ + t_##D = _mm256_unpackhi_epi32(x_##C, x_##D); \ + x_##A = _mm256_unpacklo_epi64(t_##A, t_##B); \ + x_##B = _mm256_unpackhi_epi64(t_##A, t_##B); \ + x_##C = _mm256_unpacklo_epi64(t_##C, t_##D); \ + x_##D = _mm256_unpackhi_epi64(t_##C, t_##D); \ + t0 = _mm_xor_si128(_mm256_extracti128_si256(x_##A, 0), \ + _mm_loadu_si128((const __m128i*) (m + 0))); \ + _mm_storeu_si128((__m128i*) (c + 0), t0); \ + t1 = _mm_xor_si128(_mm256_extracti128_si256(x_##B, 0), \ + _mm_loadu_si128((const __m128i*) (m + 64))); \ + _mm_storeu_si128((__m128i*) (c + 64), t1); \ + t2 = _mm_xor_si128(_mm256_extracti128_si256(x_##C, 0), \ + _mm_loadu_si128((const __m128i*) (m + 128))); \ + _mm_storeu_si128((__m128i*) (c + 128), t2); \ + t3 = _mm_xor_si128(_mm256_extracti128_si256(x_##D, 0), \ + _mm_loadu_si128((const __m128i*) (m + 192))); \ + _mm_storeu_si128((__m128i*) (c + 192), t3); \ + t0 = _mm_xor_si128(_mm256_extracti128_si256(x_##A, 1), \ + _mm_loadu_si128((const __m128i*) (m + 256))); \ + _mm_storeu_si128((__m128i*) (c + 256), t0); \ + t1 = _mm_xor_si128(_mm256_extracti128_si256(x_##B, 1), \ + _mm_loadu_si128((const __m128i*) (m + 320))); \ + _mm_storeu_si128((__m128i*) (c + 320), t1); \ + t2 = _mm_xor_si128(_mm256_extracti128_si256(x_##C, 1), \ + _mm_loadu_si128((const __m128i*) (m + 384))); \ + _mm_storeu_si128((__m128i*) (c + 384), t2); \ + t3 = _mm_xor_si128(_mm256_extracti128_si256(x_##D, 1), \ + _mm_loadu_si128((const __m128i*) (m + 448))); \ + _mm_storeu_si128((__m128i*) (c + 448), t3); \ + } + +#define ONEQUAD(A, B, C, D) ONEQUAD_TRANSPOSE(A, B, C, D) + +#define ONEQUAD_UNPCK(A, B, C, D) \ + { \ + x_##A = _mm256_add_epi32(x_##A, orig##A); \ + x_##B = _mm256_add_epi32(x_##B, orig##B); \ + x_##C = _mm256_add_epi32(x_##C, orig##C); \ + x_##D = _mm256_add_epi32(x_##D, orig##D); \ + t_##A = _mm256_unpacklo_epi32(x_##A, x_##B); \ + t_##B = _mm256_unpacklo_epi32(x_##C, x_##D); \ + t_##C = _mm256_unpackhi_epi32(x_##A, x_##B); \ + t_##D = _mm256_unpackhi_epi32(x_##C, x_##D); \ + x_##A = _mm256_unpacklo_epi64(t_##A, t_##B); \ + x_##B = _mm256_unpackhi_epi64(t_##A, t_##B); \ + x_##C = _mm256_unpacklo_epi64(t_##C, t_##D); \ + x_##D = _mm256_unpackhi_epi64(t_##C, t_##D); \ + } + +#define ONEOCTO(A, B, C, D, A2, B2, C2, D2) \ + { \ + ONEQUAD_UNPCK(A, B, C, D); \ + ONEQUAD_UNPCK(A2, B2, C2, D2); \ + t_##A = _mm256_permute2x128_si256(x_##A, x_##A2, 0x20); \ + t_##A2 = _mm256_permute2x128_si256(x_##A, x_##A2, 0x31); \ + t_##B = _mm256_permute2x128_si256(x_##B, x_##B2, 0x20); \ + t_##B2 = _mm256_permute2x128_si256(x_##B, x_##B2, 0x31); \ + t_##C = _mm256_permute2x128_si256(x_##C, x_##C2, 0x20); \ + t_##C2 = _mm256_permute2x128_si256(x_##C, x_##C2, 0x31); \ + t_##D = _mm256_permute2x128_si256(x_##D, x_##D2, 0x20); \ + t_##D2 = _mm256_permute2x128_si256(x_##D, x_##D2, 0x31); \ + t_##A = _mm256_xor_si256( \ + t_##A, _mm256_loadu_si256((const __m256i*) (m + 0))); \ + t_##B = _mm256_xor_si256( \ + t_##B, _mm256_loadu_si256((const __m256i*) (m + 64))); \ + t_##C = _mm256_xor_si256( \ + t_##C, _mm256_loadu_si256((const __m256i*) (m + 128))); \ + t_##D = _mm256_xor_si256( \ + t_##D, _mm256_loadu_si256((const __m256i*) (m + 192))); \ + t_##A2 = _mm256_xor_si256( \ + t_##A2, _mm256_loadu_si256((const __m256i*) (m + 256))); \ + t_##B2 = _mm256_xor_si256( \ + t_##B2, _mm256_loadu_si256((const __m256i*) (m + 320))); \ + t_##C2 = _mm256_xor_si256( \ + t_##C2, _mm256_loadu_si256((const __m256i*) (m + 384))); \ + t_##D2 = _mm256_xor_si256( \ + t_##D2, _mm256_loadu_si256((const __m256i*) (m + 448))); \ + _mm256_storeu_si256((__m256i*) (c + 0), t_##A); \ + _mm256_storeu_si256((__m256i*) (c + 64), t_##B); \ + _mm256_storeu_si256((__m256i*) (c + 128), t_##C); \ + _mm256_storeu_si256((__m256i*) (c + 192), t_##D); \ + _mm256_storeu_si256((__m256i*) (c + 256), t_##A2); \ + _mm256_storeu_si256((__m256i*) (c + 320), t_##B2); \ + _mm256_storeu_si256((__m256i*) (c + 384), t_##C2); \ + _mm256_storeu_si256((__m256i*) (c + 448), t_##D2); \ + } + + ONEOCTO(0, 1, 2, 3, 4, 5, 6, 7); + m += 32; + c += 32; + ONEOCTO(8, 9, 10, 11, 12, 13, 14, 15); + m -= 32; + c -= 32; + +#undef ONEQUAD +#undef ONEQUAD_TRANSPOSE +#undef ONEQUAD_UNPCK +#undef ONEOCTO + + bytes -= 512; + c += 512; + m += 512; + } +} +#undef VEC8_ROT +#undef VEC8_QUARTERROUND +#undef VEC8_QUARTERROUND_NAIVE +#undef VEC8_QUARTERROUND_SHUFFLE +#undef VEC8_QUARTERROUND_SHUFFLE2 +#undef VEC8_LINE1 +#undef VEC8_LINE2 +#undef VEC8_LINE3 +#undef VEC8_LINE4 +#undef VEC8_ROUND +#undef VEC8_ROUND_SEQ +#undef VEC8_ROUND_HALF +#undef VEC8_ROUND_HALFANDHALF diff --git a/external/src/libsodium/src/libsodium/crypto_stream/chacha20/ref/chacha20_ref.c b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/ref/chacha20_ref.c new file mode 100644 index 0000000..40cccbf --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/ref/chacha20_ref.c @@ -0,0 +1,312 @@ + +/* + chacha-merged.c version 20080118 + D. J. Bernstein + Public domain. + */ + +#include +#include +#include + +#include "core.h" +#include "crypto_stream_chacha20.h" +#include "private/common.h" +#include "utils.h" + +#include "../stream_chacha20.h" +#include "chacha20_ref.h" + +struct chacha_ctx { + uint32_t input[16]; +}; + +typedef struct chacha_ctx chacha_ctx; + +#define U32C(v) (v##U) + +#define U32V(v) ((uint32_t)(v) &U32C(0xFFFFFFFF)) + +#define ROTATE(v, c) (ROTL32(v, c)) +#define XOR(v, w) ((v) ^ (w)) +#define PLUS(v, w) (U32V((v) + (w))) +#define PLUSONE(v) (PLUS((v), 1)) + +#define QUARTERROUND(a, b, c, d) \ + a = PLUS(a, b); \ + d = ROTATE(XOR(d, a), 16); \ + c = PLUS(c, d); \ + b = ROTATE(XOR(b, c), 12); \ + a = PLUS(a, b); \ + d = ROTATE(XOR(d, a), 8); \ + c = PLUS(c, d); \ + b = ROTATE(XOR(b, c), 7); + +static void +chacha_keysetup(chacha_ctx *ctx, const uint8_t *k) +{ + ctx->input[0] = U32C(0x61707865); + ctx->input[1] = U32C(0x3320646e); + ctx->input[2] = U32C(0x79622d32); + ctx->input[3] = U32C(0x6b206574); + ctx->input[4] = LOAD32_LE(k + 0); + ctx->input[5] = LOAD32_LE(k + 4); + ctx->input[6] = LOAD32_LE(k + 8); + ctx->input[7] = LOAD32_LE(k + 12); + ctx->input[8] = LOAD32_LE(k + 16); + ctx->input[9] = LOAD32_LE(k + 20); + ctx->input[10] = LOAD32_LE(k + 24); + ctx->input[11] = LOAD32_LE(k + 28); +} + +static void +chacha_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter + 0); + ctx->input[13] = counter == NULL ? 0 : LOAD32_LE(counter + 4); + ctx->input[14] = LOAD32_LE(iv + 0); + ctx->input[15] = LOAD32_LE(iv + 4); +} + +static void +chacha_ietf_ivsetup(chacha_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[12] = counter == NULL ? 0 : LOAD32_LE(counter); + ctx->input[13] = LOAD32_LE(iv + 0); + ctx->input[14] = LOAD32_LE(iv + 4); + ctx->input[15] = LOAD32_LE(iv + 8); +} + +static void +chacha20_encrypt_bytes(chacha_ctx *ctx, const uint8_t *m, uint8_t *c, + unsigned long long bytes) +{ + uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, + x15; + uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, + j15; + uint8_t *ctarget = NULL; + uint8_t tmp[64]; + unsigned int i; + + if (!bytes) { + return; /* LCOV_EXCL_LINE */ + } + j0 = ctx->input[0]; + j1 = ctx->input[1]; + j2 = ctx->input[2]; + j3 = ctx->input[3]; + j4 = ctx->input[4]; + j5 = ctx->input[5]; + j6 = ctx->input[6]; + j7 = ctx->input[7]; + j8 = ctx->input[8]; + j9 = ctx->input[9]; + j10 = ctx->input[10]; + j11 = ctx->input[11]; + j12 = ctx->input[12]; + j13 = ctx->input[13]; + j14 = ctx->input[14]; + j15 = ctx->input[15]; + + for (;;) { + if (bytes < 64) { + memset(tmp, 0, 64); + for (i = 0; i < bytes; ++i) { + tmp[i] = m[i]; + } + m = tmp; + ctarget = c; + c = tmp; + } + x0 = j0; + x1 = j1; + x2 = j2; + x3 = j3; + x4 = j4; + x5 = j5; + x6 = j6; + x7 = j7; + x8 = j8; + x9 = j9; + x10 = j10; + x11 = j11; + x12 = j12; + x13 = j13; + x14 = j14; + x15 = j15; + for (i = 20; i > 0; i -= 2) { + QUARTERROUND(x0, x4, x8, x12) + QUARTERROUND(x1, x5, x9, x13) + QUARTERROUND(x2, x6, x10, x14) + QUARTERROUND(x3, x7, x11, x15) + QUARTERROUND(x0, x5, x10, x15) + QUARTERROUND(x1, x6, x11, x12) + QUARTERROUND(x2, x7, x8, x13) + QUARTERROUND(x3, x4, x9, x14) + } + x0 = PLUS(x0, j0); + x1 = PLUS(x1, j1); + x2 = PLUS(x2, j2); + x3 = PLUS(x3, j3); + x4 = PLUS(x4, j4); + x5 = PLUS(x5, j5); + x6 = PLUS(x6, j6); + x7 = PLUS(x7, j7); + x8 = PLUS(x8, j8); + x9 = PLUS(x9, j9); + x10 = PLUS(x10, j10); + x11 = PLUS(x11, j11); + x12 = PLUS(x12, j12); + x13 = PLUS(x13, j13); + x14 = PLUS(x14, j14); + x15 = PLUS(x15, j15); + + x0 = XOR(x0, LOAD32_LE(m + 0)); + x1 = XOR(x1, LOAD32_LE(m + 4)); + x2 = XOR(x2, LOAD32_LE(m + 8)); + x3 = XOR(x3, LOAD32_LE(m + 12)); + x4 = XOR(x4, LOAD32_LE(m + 16)); + x5 = XOR(x5, LOAD32_LE(m + 20)); + x6 = XOR(x6, LOAD32_LE(m + 24)); + x7 = XOR(x7, LOAD32_LE(m + 28)); + x8 = XOR(x8, LOAD32_LE(m + 32)); + x9 = XOR(x9, LOAD32_LE(m + 36)); + x10 = XOR(x10, LOAD32_LE(m + 40)); + x11 = XOR(x11, LOAD32_LE(m + 44)); + x12 = XOR(x12, LOAD32_LE(m + 48)); + x13 = XOR(x13, LOAD32_LE(m + 52)); + x14 = XOR(x14, LOAD32_LE(m + 56)); + x15 = XOR(x15, LOAD32_LE(m + 60)); + + j12 = PLUSONE(j12); + /* LCOV_EXCL_START */ + if (!j12) { + j13 = PLUSONE(j13); + } + /* LCOV_EXCL_STOP */ + + STORE32_LE(c + 0, x0); + STORE32_LE(c + 4, x1); + STORE32_LE(c + 8, x2); + STORE32_LE(c + 12, x3); + STORE32_LE(c + 16, x4); + STORE32_LE(c + 20, x5); + STORE32_LE(c + 24, x6); + STORE32_LE(c + 28, x7); + STORE32_LE(c + 32, x8); + STORE32_LE(c + 36, x9); + STORE32_LE(c + 40, x10); + STORE32_LE(c + 44, x11); + STORE32_LE(c + 48, x12); + STORE32_LE(c + 52, x13); + STORE32_LE(c + 56, x14); + STORE32_LE(c + 60, x15); + + if (bytes <= 64) { + if (bytes < 64) { + for (i = 0; i < (unsigned int) bytes; ++i) { + ctarget[i] = c[i]; /* ctarget cannot be NULL */ + } + } + ctx->input[12] = j12; + ctx->input[13] = j13; + + return; + } + bytes -= 64; + c += 64; + m += 64; + } +} + +static int +stream_ref(unsigned char *c, unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + struct chacha_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8); + chacha_keysetup(&ctx, k); + chacha_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + chacha20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ietf_ext_ref(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + struct chacha_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES == 256 / 8); + chacha_keysetup(&ctx, k); + chacha_ietf_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + chacha20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + struct chacha_ctx ctx; + uint8_t ic_bytes[8]; + uint32_t ic_high; + uint32_t ic_low; + + if (!mlen) { + return 0; + } + ic_high = U32V(ic >> 32); + ic_low = U32V(ic); + STORE32_LE(&ic_bytes[0], ic_low); + STORE32_LE(&ic_bytes[4], ic_high); + chacha_keysetup(&ctx, k); + chacha_ivsetup(&ctx, n, ic_bytes); + chacha20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_ietf_ext_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + uint32_t ic, const unsigned char *k) +{ + struct chacha_ctx ctx; + uint8_t ic_bytes[4]; + + if (!mlen) { + return 0; + } + STORE32_LE(ic_bytes, ic); + chacha_keysetup(&ctx, k); + chacha_ietf_ivsetup(&ctx, n, ic_bytes); + chacha20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +struct crypto_stream_chacha20_implementation + crypto_stream_chacha20_ref_implementation = { + SODIUM_C99(.stream =) stream_ref, + SODIUM_C99(.stream_ietf_ext =) stream_ietf_ext_ref, + SODIUM_C99(.stream_xor_ic =) stream_ref_xor_ic, + SODIUM_C99(.stream_ietf_ext_xor_ic =) stream_ietf_ext_ref_xor_ic + }; diff --git a/external/src/libsodium/src/libsodium/crypto_stream/chacha20/ref/chacha20_ref.h b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/ref/chacha20_ref.h new file mode 100644 index 0000000..6ac4807 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/ref/chacha20_ref.h @@ -0,0 +1,8 @@ + +#include + +#include "../stream_chacha20.h" +#include "crypto_stream_chacha20.h" + +extern struct crypto_stream_chacha20_implementation + crypto_stream_chacha20_ref_implementation; diff --git a/external/src/libsodium/src/libsodium/crypto_stream/chacha20/stream_chacha20.c b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/stream_chacha20.c new file mode 100644 index 0000000..427c3fb --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/stream_chacha20.c @@ -0,0 +1,184 @@ +#include "crypto_stream_chacha20.h" +#include "core.h" +#include "private/chacha20_ietf_ext.h" +#include "private/common.h" +#include "private/implementations.h" +#include "randombytes.h" +#include "runtime.h" +#include "stream_chacha20.h" + +#include "ref/chacha20_ref.h" +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) +# include "dolbeau/chacha20_dolbeau-avx2.h" +#endif +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) +# include "dolbeau/chacha20_dolbeau-ssse3.h" +#endif + +static const crypto_stream_chacha20_implementation *implementation = + &crypto_stream_chacha20_ref_implementation; + +size_t +crypto_stream_chacha20_keybytes(void) { + return crypto_stream_chacha20_KEYBYTES; +} + +size_t +crypto_stream_chacha20_noncebytes(void) { + return crypto_stream_chacha20_NONCEBYTES; +} + +size_t +crypto_stream_chacha20_messagebytes_max(void) +{ + return crypto_stream_chacha20_MESSAGEBYTES_MAX; +} + +size_t +crypto_stream_chacha20_ietf_keybytes(void) { + return crypto_stream_chacha20_ietf_KEYBYTES; +} + +size_t +crypto_stream_chacha20_ietf_noncebytes(void) { + return crypto_stream_chacha20_ietf_NONCEBYTES; +} + +size_t +crypto_stream_chacha20_ietf_messagebytes_max(void) +{ + return crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX; +} + +int +crypto_stream_chacha20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + if (clen > crypto_stream_chacha20_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return implementation->stream(c, clen, n, k); +} + +int +crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + if (mlen > crypto_stream_chacha20_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return implementation->stream_xor_ic(c, m, mlen, n, ic, k); +} + +int +crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + if (mlen > crypto_stream_chacha20_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return implementation->stream_xor_ic(c, m, mlen, n, 0U, k); +} + +int +crypto_stream_chacha20_ietf_ext(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + if (clen > crypto_stream_chacha20_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return implementation->stream_ietf_ext(c, clen, n, k); +} + +int +crypto_stream_chacha20_ietf_ext_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint32_t ic, + const unsigned char *k) +{ + if (mlen > crypto_stream_chacha20_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return implementation->stream_ietf_ext_xor_ic(c, m, mlen, n, ic, k); +} + +static int +crypto_stream_chacha20_ietf_ext_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + if (mlen > crypto_stream_chacha20_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return implementation->stream_ietf_ext_xor_ic(c, m, mlen, n, 0U, k); +} + +int +crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + if (clen > crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return crypto_stream_chacha20_ietf_ext(c, clen, n, k); +} + +int +crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint32_t ic, + const unsigned char *k) +{ + if ((unsigned long long) ic > + (64ULL * (1ULL << 32)) / 64ULL - (mlen + 63ULL) / 64ULL) { + sodium_misuse(); + } + return crypto_stream_chacha20_ietf_ext_xor_ic(c, m, mlen, n, ic, k); +} + +int +crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + if (mlen > crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return crypto_stream_chacha20_ietf_ext_xor(c, m, mlen, n, k); +} + +void +crypto_stream_chacha20_ietf_keygen(unsigned char k[crypto_stream_chacha20_ietf_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_chacha20_ietf_KEYBYTES); +} + +void +crypto_stream_chacha20_keygen(unsigned char k[crypto_stream_chacha20_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_chacha20_KEYBYTES); +} + +int +_crypto_stream_chacha20_pick_best_implementation(void) +{ + implementation = &crypto_stream_chacha20_ref_implementation; +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) + if (sodium_runtime_has_avx2()) { + implementation = &crypto_stream_chacha20_dolbeau_avx2_implementation; + return 0; + } +#endif +#if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) + if (sodium_runtime_has_ssse3()) { + implementation = &crypto_stream_chacha20_dolbeau_ssse3_implementation; + return 0; + } +#endif + return 0; +} diff --git a/external/src/libsodium/src/libsodium/crypto_stream/chacha20/stream_chacha20.h b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/stream_chacha20.h new file mode 100644 index 0000000..40f782f --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/chacha20/stream_chacha20.h @@ -0,0 +1,22 @@ + +#ifndef stream_chacha20_H +#define stream_chacha20_H + +#include + +typedef struct crypto_stream_chacha20_implementation { + int (*stream)(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + int (*stream_ietf_ext)(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + int (*stream_xor_ic)(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k); + int (*stream_ietf_ext_xor_ic)(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint32_t ic, + const unsigned char *k); +} crypto_stream_chacha20_implementation; + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_stream/crypto_stream.c b/external/src/libsodium/src/libsodium/crypto_stream/crypto_stream.c new file mode 100644 index 0000000..58d2538 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/crypto_stream.c @@ -0,0 +1,49 @@ + +#include "crypto_stream.h" +#include "randombytes.h" + +size_t +crypto_stream_keybytes(void) +{ + return crypto_stream_KEYBYTES; +} + +size_t +crypto_stream_noncebytes(void) +{ + return crypto_stream_NONCEBYTES; +} + +size_t +crypto_stream_messagebytes_max(void) +{ + return crypto_stream_MESSAGEBYTES_MAX; +} + +const char * +crypto_stream_primitive(void) +{ + return crypto_stream_PRIMITIVE; +} + +int +crypto_stream(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + return crypto_stream_xsalsa20(c, clen, n, k); +} + + +int +crypto_stream_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + return crypto_stream_xsalsa20_xor(c, m, mlen, n, k); +} + +void +crypto_stream_keygen(unsigned char k[crypto_stream_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa20/ref/salsa20_ref.c b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/ref/salsa20_ref.c new file mode 100644 index 0000000..f0854eb --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/ref/salsa20_ref.c @@ -0,0 +1,120 @@ +/* +version 20140420 +D. J. Bernstein +Public domain. +*/ + +#include + +#include "crypto_core_salsa20.h" +#include "crypto_stream_salsa20.h" +#include "utils.h" + +#include "../stream_salsa20.h" +#include "salsa20_ref.h" + +#ifndef HAVE_AMD64_ASM + +static int +stream_ref(unsigned char *c, unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + unsigned char in[16]; + unsigned char block[64]; + unsigned char kcopy[32]; + unsigned int i; + unsigned int u; + + if (!clen) { + return 0; + } + for (i = 0; i < 32; i++) { + kcopy[i] = k[i]; + } + for (i = 0; i < 8; i++) { + in[i] = n[i]; + } + for (i = 8; i < 16; i++) { + in[i] = 0; + } + while (clen >= 64) { + crypto_core_salsa20(c, in, kcopy, NULL); + u = 1; + for (i = 8; i < 16; i++) { + u += (unsigned int) in[i]; + in[i] = u; + u >>= 8; + } + clen -= 64; + c += 64; + } + if (clen) { + crypto_core_salsa20(block, in, kcopy, NULL); + for (i = 0; i < (unsigned int) clen; i++) { + c[i] = block[i]; + } + } + sodium_memzero(block, sizeof block); + sodium_memzero(kcopy, sizeof kcopy); + + return 0; +} + +static int +stream_ref_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + unsigned char in[16]; + unsigned char block[64]; + unsigned char kcopy[32]; + unsigned int i; + unsigned int u; + + if (!mlen) { + return 0; + } + for (i = 0; i < 32; i++) { + kcopy[i] = k[i]; + } + for (i = 0; i < 8; i++) { + in[i] = n[i]; + } + for (i = 8; i < 16; i++) { + in[i] = (unsigned char) (ic & 0xff); + ic >>= 8; + } + while (mlen >= 64) { + crypto_core_salsa20(block, in, kcopy, NULL); + for (i = 0; i < 64; i++) { + c[i] = m[i] ^ block[i]; + } + u = 1; + for (i = 8; i < 16; i++) { + u += (unsigned int) in[i]; + in[i] = u; + u >>= 8; + } + mlen -= 64; + c += 64; + m += 64; + } + if (mlen) { + crypto_core_salsa20(block, in, kcopy, NULL); + for (i = 0; i < (unsigned int) mlen; i++) { + c[i] = m[i] ^ block[i]; + } + } + sodium_memzero(block, sizeof block); + sodium_memzero(kcopy, sizeof kcopy); + + return 0; +} + +struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_ref_implementation = { + SODIUM_C99(.stream =) stream_ref, + SODIUM_C99(.stream_xor_ic =) stream_ref_xor_ic, + }; + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa20/ref/salsa20_ref.h b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/ref/salsa20_ref.h new file mode 100644 index 0000000..8716cb4 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/ref/salsa20_ref.h @@ -0,0 +1,8 @@ + +#include + +#include "../stream_salsa20.h" +#include "crypto_stream_salsa20.h" + +extern struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_ref_implementation; diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa20/stream_salsa20.c b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/stream_salsa20.c new file mode 100644 index 0000000..4529850 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/stream_salsa20.c @@ -0,0 +1,100 @@ +#include "crypto_stream_salsa20.h" +#include "private/common.h" +#include "private/implementations.h" +#include "randombytes.h" +#include "runtime.h" +#include "stream_salsa20.h" + +#ifdef HAVE_AMD64_ASM +# include "xmm6/salsa20_xmm6.h" +#else +# include "ref/salsa20_ref.h" +#endif +#if !defined(HAVE_AMD64_ASM) && defined(HAVE_EMMINTRIN_H) +# include "xmm6int/salsa20_xmm6int-sse2.h" +#endif +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) +# include "xmm6int/salsa20_xmm6int-avx2.h" +#endif + +#if HAVE_AMD64_ASM +static const crypto_stream_salsa20_implementation *implementation = + &crypto_stream_salsa20_xmm6_implementation; +#else +static const crypto_stream_salsa20_implementation *implementation = + &crypto_stream_salsa20_ref_implementation; +#endif + +size_t +crypto_stream_salsa20_keybytes(void) +{ + return crypto_stream_salsa20_KEYBYTES; +} + +size_t +crypto_stream_salsa20_noncebytes(void) +{ + return crypto_stream_salsa20_NONCEBYTES; +} + +size_t +crypto_stream_salsa20_messagebytes_max(void) +{ + return crypto_stream_salsa20_MESSAGEBYTES_MAX; +} + +int +crypto_stream_salsa20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + return implementation->stream(c, clen, n, k); +} + +int +crypto_stream_salsa20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + return implementation->stream_xor_ic(c, m, mlen, n, ic, k); +} + +int +crypto_stream_salsa20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + return implementation->stream_xor_ic(c, m, mlen, n, 0U, k); +} + +void +crypto_stream_salsa20_keygen(unsigned char k[crypto_stream_salsa20_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_salsa20_KEYBYTES); +} + +int +_crypto_stream_salsa20_pick_best_implementation(void) +{ +#ifdef HAVE_AMD64_ASM + implementation = &crypto_stream_salsa20_xmm6_implementation; +#else + implementation = &crypto_stream_salsa20_ref_implementation; +#endif + +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) + if (sodium_runtime_has_avx2()) { + implementation = &crypto_stream_salsa20_xmm6int_avx2_implementation; + return 0; + } +#endif +#if !defined(HAVE_AMD64_ASM) && defined(HAVE_EMMINTRIN_H) + if (sodium_runtime_has_sse2()) { + implementation = &crypto_stream_salsa20_xmm6int_sse2_implementation; + return 0; + } +#endif + return 0; /* LCOV_EXCL_LINE */ +} diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa20/stream_salsa20.h b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/stream_salsa20.h new file mode 100644 index 0000000..1949d38 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/stream_salsa20.h @@ -0,0 +1,16 @@ + +#ifndef stream_salsa20_H +#define stream_salsa20_H + +#include + +typedef struct crypto_stream_salsa20_implementation { + int (*stream)(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + int (*stream_xor_ic)(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k); +} crypto_stream_salsa20_implementation; + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S new file mode 100644 index 0000000..6d9f354 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S @@ -0,0 +1,960 @@ +#ifdef HAVE_AMD64_ASM + +.text +.p2align 5 + +#ifdef ASM_HIDE_SYMBOL +ASM_HIDE_SYMBOL stream_salsa20_xmm6 +ASM_HIDE_SYMBOL _stream_salsa20_xmm6 +#endif +.globl stream_salsa20_xmm6 +.globl _stream_salsa20_xmm6 +#ifdef __ELF__ +.type stream_salsa20_xmm6, @function +.type _stream_salsa20_xmm6, @function +#endif +stream_salsa20_xmm6: +_stream_salsa20_xmm6: +mov %rsp,%r11 +and $31,%r11 +add $512,%r11 +sub %r11,%rsp +movq %r11,416(%rsp) +movq %r12,424(%rsp) +movq %r13,432(%rsp) +movq %r14,440(%rsp) +movq %r15,448(%rsp) +movq %rbx,456(%rsp) +movq %rbp,464(%rsp) +mov %rsi,%r9 +mov %rdi,%rdi +mov %rdi,%rsi +mov %rdx,%rdx +mov %rcx,%r10 +cmp $0,%r9 +jbe ._done +mov $0,%rax +mov %r9,%rcx +rep stosb +sub %r9,%rdi +movq $0,472(%rsp) +jmp ._start + +.text +.p2align 5 + +#ifdef ASM_HIDE_SYMBOL +ASM_HIDE_SYMBOL stream_salsa20_xmm6_xor_ic +ASM_HIDE_SYMBOL _stream_salsa20_xmm6_xor_ic +#endif +.globl stream_salsa20_xmm6_xor_ic +.globl _stream_salsa20_xmm6_xor_ic +#ifdef __ELF__ +.type stream_salsa20_xmm6_xor_ic, @function +.type _stream_salsa20_xmm6_xor_ic, @function +#endif +stream_salsa20_xmm6_xor_ic: +_stream_salsa20_xmm6_xor_ic: + +mov %rsp,%r11 +and $31,%r11 +add $512,%r11 +sub %r11,%rsp +movq %r11,416(%rsp) +movq %r12,424(%rsp) +movq %r13,432(%rsp) +movq %r14,440(%rsp) +movq %r15,448(%rsp) +movq %rbx,456(%rsp) +movq %rbp,464(%rsp) +mov %rdi,%rdi +mov %rsi,%rsi +mov %r9,%r10 +movq %r8,472(%rsp) +mov %rdx,%r9 +mov %rcx,%rdx +cmp $0,%r9 +jbe ._done + +._start: +movl 20(%r10),%ecx +movl 0(%r10),%r8d +movl 0(%rdx),%eax +movl 16(%r10),%r11d +movl %ecx,64(%rsp) +movl %r8d,4+64(%rsp) +movl %eax,8+64(%rsp) +movl %r11d,12+64(%rsp) +movl 24(%r10),%r8d +movl 4(%r10),%eax +movl 4(%rdx),%edx +movq 472(%rsp),%rcx +movl %ecx,80(%rsp) +movl %r8d,4+80(%rsp) +movl %eax,8+80(%rsp) +movl %edx,12+80(%rsp) +movl 12(%r10),%edx +shr $32,%rcx +movl 28(%r10),%r8d +movl 8(%r10),%eax +movl %edx,96(%rsp) +movl %ecx,4+96(%rsp) +movl %r8d,8+96(%rsp) +movl %eax,12+96(%rsp) +mov $1634760805,%rdx +mov $857760878,%rcx +mov $2036477234,%r8 +mov $1797285236,%rax +movl %edx,112(%rsp) +movl %ecx,4+112(%rsp) +movl %r8d,8+112(%rsp) +movl %eax,12+112(%rsp) +cmp $256,%r9 +jb ._bytesbetween1and255 +movdqa 112(%rsp),%xmm0 +pshufd $0x55,%xmm0,%xmm1 +pshufd $0xaa,%xmm0,%xmm2 +pshufd $0xff,%xmm0,%xmm3 +pshufd $0x00,%xmm0,%xmm0 +movdqa %xmm1,128(%rsp) +movdqa %xmm2,144(%rsp) +movdqa %xmm3,160(%rsp) +movdqa %xmm0,176(%rsp) +movdqa 64(%rsp),%xmm0 +pshufd $0xaa,%xmm0,%xmm1 +pshufd $0xff,%xmm0,%xmm2 +pshufd $0x00,%xmm0,%xmm3 +pshufd $0x55,%xmm0,%xmm0 +movdqa %xmm1,192(%rsp) +movdqa %xmm2,208(%rsp) +movdqa %xmm3,224(%rsp) +movdqa %xmm0,240(%rsp) +movdqa 80(%rsp),%xmm0 +pshufd $0xff,%xmm0,%xmm1 +pshufd $0x55,%xmm0,%xmm2 +pshufd $0xaa,%xmm0,%xmm0 +movdqa %xmm1,256(%rsp) +movdqa %xmm2,272(%rsp) +movdqa %xmm0,288(%rsp) +movdqa 96(%rsp),%xmm0 +pshufd $0x00,%xmm0,%xmm1 +pshufd $0xaa,%xmm0,%xmm2 +pshufd $0xff,%xmm0,%xmm0 +movdqa %xmm1,304(%rsp) +movdqa %xmm2,320(%rsp) +movdqa %xmm0,336(%rsp) + +.p2align 4 +._bytesatleast256: +movq 472(%rsp),%rdx +mov %rdx,%rcx +shr $32,%rcx +movl %edx,352(%rsp) +movl %ecx,368(%rsp) +add $1,%rdx +mov %rdx,%rcx +shr $32,%rcx +movl %edx,4+352(%rsp) +movl %ecx,4+368(%rsp) +add $1,%rdx +mov %rdx,%rcx +shr $32,%rcx +movl %edx,8+352(%rsp) +movl %ecx,8+368(%rsp) +add $1,%rdx +mov %rdx,%rcx +shr $32,%rcx +movl %edx,12+352(%rsp) +movl %ecx,12+368(%rsp) +add $1,%rdx +mov %rdx,%rcx +shr $32,%rcx +movl %edx,80(%rsp) +movl %ecx,4+96(%rsp) +movq %rdx,472(%rsp) +movq %r9,480(%rsp) +mov $20,%rdx +movdqa 128(%rsp),%xmm0 +movdqa 144(%rsp),%xmm1 +movdqa 160(%rsp),%xmm2 +movdqa 320(%rsp),%xmm3 +movdqa 336(%rsp),%xmm4 +movdqa 192(%rsp),%xmm5 +movdqa 208(%rsp),%xmm6 +movdqa 240(%rsp),%xmm7 +movdqa 256(%rsp),%xmm8 +movdqa 272(%rsp),%xmm9 +movdqa 288(%rsp),%xmm10 +movdqa 368(%rsp),%xmm11 +movdqa 176(%rsp),%xmm12 +movdqa 224(%rsp),%xmm13 +movdqa 304(%rsp),%xmm14 +movdqa 352(%rsp),%xmm15 + +.p2align 4 +._mainloop1: +movdqa %xmm1,384(%rsp) +movdqa %xmm2,400(%rsp) +movdqa %xmm13,%xmm1 +paddd %xmm12,%xmm1 +movdqa %xmm1,%xmm2 +pslld $7,%xmm1 +pxor %xmm1,%xmm14 +psrld $25,%xmm2 +pxor %xmm2,%xmm14 +movdqa %xmm7,%xmm1 +paddd %xmm0,%xmm1 +movdqa %xmm1,%xmm2 +pslld $7,%xmm1 +pxor %xmm1,%xmm11 +psrld $25,%xmm2 +pxor %xmm2,%xmm11 +movdqa %xmm12,%xmm1 +paddd %xmm14,%xmm1 +movdqa %xmm1,%xmm2 +pslld $9,%xmm1 +pxor %xmm1,%xmm15 +psrld $23,%xmm2 +pxor %xmm2,%xmm15 +movdqa %xmm0,%xmm1 +paddd %xmm11,%xmm1 +movdqa %xmm1,%xmm2 +pslld $9,%xmm1 +pxor %xmm1,%xmm9 +psrld $23,%xmm2 +pxor %xmm2,%xmm9 +movdqa %xmm14,%xmm1 +paddd %xmm15,%xmm1 +movdqa %xmm1,%xmm2 +pslld $13,%xmm1 +pxor %xmm1,%xmm13 +psrld $19,%xmm2 +pxor %xmm2,%xmm13 +movdqa %xmm11,%xmm1 +paddd %xmm9,%xmm1 +movdqa %xmm1,%xmm2 +pslld $13,%xmm1 +pxor %xmm1,%xmm7 +psrld $19,%xmm2 +pxor %xmm2,%xmm7 +movdqa %xmm15,%xmm1 +paddd %xmm13,%xmm1 +movdqa %xmm1,%xmm2 +pslld $18,%xmm1 +pxor %xmm1,%xmm12 +psrld $14,%xmm2 +pxor %xmm2,%xmm12 +movdqa 384(%rsp),%xmm1 +movdqa %xmm12,384(%rsp) +movdqa %xmm9,%xmm2 +paddd %xmm7,%xmm2 +movdqa %xmm2,%xmm12 +pslld $18,%xmm2 +pxor %xmm2,%xmm0 +psrld $14,%xmm12 +pxor %xmm12,%xmm0 +movdqa %xmm5,%xmm2 +paddd %xmm1,%xmm2 +movdqa %xmm2,%xmm12 +pslld $7,%xmm2 +pxor %xmm2,%xmm3 +psrld $25,%xmm12 +pxor %xmm12,%xmm3 +movdqa 400(%rsp),%xmm2 +movdqa %xmm0,400(%rsp) +movdqa %xmm6,%xmm0 +paddd %xmm2,%xmm0 +movdqa %xmm0,%xmm12 +pslld $7,%xmm0 +pxor %xmm0,%xmm4 +psrld $25,%xmm12 +pxor %xmm12,%xmm4 +movdqa %xmm1,%xmm0 +paddd %xmm3,%xmm0 +movdqa %xmm0,%xmm12 +pslld $9,%xmm0 +pxor %xmm0,%xmm10 +psrld $23,%xmm12 +pxor %xmm12,%xmm10 +movdqa %xmm2,%xmm0 +paddd %xmm4,%xmm0 +movdqa %xmm0,%xmm12 +pslld $9,%xmm0 +pxor %xmm0,%xmm8 +psrld $23,%xmm12 +pxor %xmm12,%xmm8 +movdqa %xmm3,%xmm0 +paddd %xmm10,%xmm0 +movdqa %xmm0,%xmm12 +pslld $13,%xmm0 +pxor %xmm0,%xmm5 +psrld $19,%xmm12 +pxor %xmm12,%xmm5 +movdqa %xmm4,%xmm0 +paddd %xmm8,%xmm0 +movdqa %xmm0,%xmm12 +pslld $13,%xmm0 +pxor %xmm0,%xmm6 +psrld $19,%xmm12 +pxor %xmm12,%xmm6 +movdqa %xmm10,%xmm0 +paddd %xmm5,%xmm0 +movdqa %xmm0,%xmm12 +pslld $18,%xmm0 +pxor %xmm0,%xmm1 +psrld $14,%xmm12 +pxor %xmm12,%xmm1 +movdqa 384(%rsp),%xmm0 +movdqa %xmm1,384(%rsp) +movdqa %xmm4,%xmm1 +paddd %xmm0,%xmm1 +movdqa %xmm1,%xmm12 +pslld $7,%xmm1 +pxor %xmm1,%xmm7 +psrld $25,%xmm12 +pxor %xmm12,%xmm7 +movdqa %xmm8,%xmm1 +paddd %xmm6,%xmm1 +movdqa %xmm1,%xmm12 +pslld $18,%xmm1 +pxor %xmm1,%xmm2 +psrld $14,%xmm12 +pxor %xmm12,%xmm2 +movdqa 400(%rsp),%xmm12 +movdqa %xmm2,400(%rsp) +movdqa %xmm14,%xmm1 +paddd %xmm12,%xmm1 +movdqa %xmm1,%xmm2 +pslld $7,%xmm1 +pxor %xmm1,%xmm5 +psrld $25,%xmm2 +pxor %xmm2,%xmm5 +movdqa %xmm0,%xmm1 +paddd %xmm7,%xmm1 +movdqa %xmm1,%xmm2 +pslld $9,%xmm1 +pxor %xmm1,%xmm10 +psrld $23,%xmm2 +pxor %xmm2,%xmm10 +movdqa %xmm12,%xmm1 +paddd %xmm5,%xmm1 +movdqa %xmm1,%xmm2 +pslld $9,%xmm1 +pxor %xmm1,%xmm8 +psrld $23,%xmm2 +pxor %xmm2,%xmm8 +movdqa %xmm7,%xmm1 +paddd %xmm10,%xmm1 +movdqa %xmm1,%xmm2 +pslld $13,%xmm1 +pxor %xmm1,%xmm4 +psrld $19,%xmm2 +pxor %xmm2,%xmm4 +movdqa %xmm5,%xmm1 +paddd %xmm8,%xmm1 +movdqa %xmm1,%xmm2 +pslld $13,%xmm1 +pxor %xmm1,%xmm14 +psrld $19,%xmm2 +pxor %xmm2,%xmm14 +movdqa %xmm10,%xmm1 +paddd %xmm4,%xmm1 +movdqa %xmm1,%xmm2 +pslld $18,%xmm1 +pxor %xmm1,%xmm0 +psrld $14,%xmm2 +pxor %xmm2,%xmm0 +movdqa 384(%rsp),%xmm1 +movdqa %xmm0,384(%rsp) +movdqa %xmm8,%xmm0 +paddd %xmm14,%xmm0 +movdqa %xmm0,%xmm2 +pslld $18,%xmm0 +pxor %xmm0,%xmm12 +psrld $14,%xmm2 +pxor %xmm2,%xmm12 +movdqa %xmm11,%xmm0 +paddd %xmm1,%xmm0 +movdqa %xmm0,%xmm2 +pslld $7,%xmm0 +pxor %xmm0,%xmm6 +psrld $25,%xmm2 +pxor %xmm2,%xmm6 +movdqa 400(%rsp),%xmm2 +movdqa %xmm12,400(%rsp) +movdqa %xmm3,%xmm0 +paddd %xmm2,%xmm0 +movdqa %xmm0,%xmm12 +pslld $7,%xmm0 +pxor %xmm0,%xmm13 +psrld $25,%xmm12 +pxor %xmm12,%xmm13 +movdqa %xmm1,%xmm0 +paddd %xmm6,%xmm0 +movdqa %xmm0,%xmm12 +pslld $9,%xmm0 +pxor %xmm0,%xmm15 +psrld $23,%xmm12 +pxor %xmm12,%xmm15 +movdqa %xmm2,%xmm0 +paddd %xmm13,%xmm0 +movdqa %xmm0,%xmm12 +pslld $9,%xmm0 +pxor %xmm0,%xmm9 +psrld $23,%xmm12 +pxor %xmm12,%xmm9 +movdqa %xmm6,%xmm0 +paddd %xmm15,%xmm0 +movdqa %xmm0,%xmm12 +pslld $13,%xmm0 +pxor %xmm0,%xmm11 +psrld $19,%xmm12 +pxor %xmm12,%xmm11 +movdqa %xmm13,%xmm0 +paddd %xmm9,%xmm0 +movdqa %xmm0,%xmm12 +pslld $13,%xmm0 +pxor %xmm0,%xmm3 +psrld $19,%xmm12 +pxor %xmm12,%xmm3 +movdqa %xmm15,%xmm0 +paddd %xmm11,%xmm0 +movdqa %xmm0,%xmm12 +pslld $18,%xmm0 +pxor %xmm0,%xmm1 +psrld $14,%xmm12 +pxor %xmm12,%xmm1 +movdqa %xmm9,%xmm0 +paddd %xmm3,%xmm0 +movdqa %xmm0,%xmm12 +pslld $18,%xmm0 +pxor %xmm0,%xmm2 +psrld $14,%xmm12 +pxor %xmm12,%xmm2 +movdqa 384(%rsp),%xmm12 +movdqa 400(%rsp),%xmm0 +sub $2,%rdx +ja ._mainloop1 + +paddd 176(%rsp),%xmm12 +paddd 240(%rsp),%xmm7 +paddd 288(%rsp),%xmm10 +paddd 336(%rsp),%xmm4 +movd %xmm12,%rdx +movd %xmm7,%rcx +movd %xmm10,%r8 +movd %xmm4,%r9 +pshufd $0x39,%xmm12,%xmm12 +pshufd $0x39,%xmm7,%xmm7 +pshufd $0x39,%xmm10,%xmm10 +pshufd $0x39,%xmm4,%xmm4 +xorl 0(%rsi),%edx +xorl 4(%rsi),%ecx +xorl 8(%rsi),%r8d +xorl 12(%rsi),%r9d +movl %edx,0(%rdi) +movl %ecx,4(%rdi) +movl %r8d,8(%rdi) +movl %r9d,12(%rdi) +movd %xmm12,%rdx +movd %xmm7,%rcx +movd %xmm10,%r8 +movd %xmm4,%r9 +pshufd $0x39,%xmm12,%xmm12 +pshufd $0x39,%xmm7,%xmm7 +pshufd $0x39,%xmm10,%xmm10 +pshufd $0x39,%xmm4,%xmm4 +xorl 64(%rsi),%edx +xorl 68(%rsi),%ecx +xorl 72(%rsi),%r8d +xorl 76(%rsi),%r9d +movl %edx,64(%rdi) +movl %ecx,68(%rdi) +movl %r8d,72(%rdi) +movl %r9d,76(%rdi) +movd %xmm12,%rdx +movd %xmm7,%rcx +movd %xmm10,%r8 +movd %xmm4,%r9 +pshufd $0x39,%xmm12,%xmm12 +pshufd $0x39,%xmm7,%xmm7 +pshufd $0x39,%xmm10,%xmm10 +pshufd $0x39,%xmm4,%xmm4 +xorl 128(%rsi),%edx +xorl 132(%rsi),%ecx +xorl 136(%rsi),%r8d +xorl 140(%rsi),%r9d +movl %edx,128(%rdi) +movl %ecx,132(%rdi) +movl %r8d,136(%rdi) +movl %r9d,140(%rdi) +movd %xmm12,%rdx +movd %xmm7,%rcx +movd %xmm10,%r8 +movd %xmm4,%r9 +xorl 192(%rsi),%edx +xorl 196(%rsi),%ecx +xorl 200(%rsi),%r8d +xorl 204(%rsi),%r9d +movl %edx,192(%rdi) +movl %ecx,196(%rdi) +movl %r8d,200(%rdi) +movl %r9d,204(%rdi) +paddd 304(%rsp),%xmm14 +paddd 128(%rsp),%xmm0 +paddd 192(%rsp),%xmm5 +paddd 256(%rsp),%xmm8 +movd %xmm14,%rdx +movd %xmm0,%rcx +movd %xmm5,%r8 +movd %xmm8,%r9 +pshufd $0x39,%xmm14,%xmm14 +pshufd $0x39,%xmm0,%xmm0 +pshufd $0x39,%xmm5,%xmm5 +pshufd $0x39,%xmm8,%xmm8 +xorl 16(%rsi),%edx +xorl 20(%rsi),%ecx +xorl 24(%rsi),%r8d +xorl 28(%rsi),%r9d +movl %edx,16(%rdi) +movl %ecx,20(%rdi) +movl %r8d,24(%rdi) +movl %r9d,28(%rdi) +movd %xmm14,%rdx +movd %xmm0,%rcx +movd %xmm5,%r8 +movd %xmm8,%r9 +pshufd $0x39,%xmm14,%xmm14 +pshufd $0x39,%xmm0,%xmm0 +pshufd $0x39,%xmm5,%xmm5 +pshufd $0x39,%xmm8,%xmm8 +xorl 80(%rsi),%edx +xorl 84(%rsi),%ecx +xorl 88(%rsi),%r8d +xorl 92(%rsi),%r9d +movl %edx,80(%rdi) +movl %ecx,84(%rdi) +movl %r8d,88(%rdi) +movl %r9d,92(%rdi) +movd %xmm14,%rdx +movd %xmm0,%rcx +movd %xmm5,%r8 +movd %xmm8,%r9 +pshufd $0x39,%xmm14,%xmm14 +pshufd $0x39,%xmm0,%xmm0 +pshufd $0x39,%xmm5,%xmm5 +pshufd $0x39,%xmm8,%xmm8 +xorl 144(%rsi),%edx +xorl 148(%rsi),%ecx +xorl 152(%rsi),%r8d +xorl 156(%rsi),%r9d +movl %edx,144(%rdi) +movl %ecx,148(%rdi) +movl %r8d,152(%rdi) +movl %r9d,156(%rdi) +movd %xmm14,%rdx +movd %xmm0,%rcx +movd %xmm5,%r8 +movd %xmm8,%r9 +xorl 208(%rsi),%edx +xorl 212(%rsi),%ecx +xorl 216(%rsi),%r8d +xorl 220(%rsi),%r9d +movl %edx,208(%rdi) +movl %ecx,212(%rdi) +movl %r8d,216(%rdi) +movl %r9d,220(%rdi) +paddd 352(%rsp),%xmm15 +paddd 368(%rsp),%xmm11 +paddd 144(%rsp),%xmm1 +paddd 208(%rsp),%xmm6 +movd %xmm15,%rdx +movd %xmm11,%rcx +movd %xmm1,%r8 +movd %xmm6,%r9 +pshufd $0x39,%xmm15,%xmm15 +pshufd $0x39,%xmm11,%xmm11 +pshufd $0x39,%xmm1,%xmm1 +pshufd $0x39,%xmm6,%xmm6 +xorl 32(%rsi),%edx +xorl 36(%rsi),%ecx +xorl 40(%rsi),%r8d +xorl 44(%rsi),%r9d +movl %edx,32(%rdi) +movl %ecx,36(%rdi) +movl %r8d,40(%rdi) +movl %r9d,44(%rdi) +movd %xmm15,%rdx +movd %xmm11,%rcx +movd %xmm1,%r8 +movd %xmm6,%r9 +pshufd $0x39,%xmm15,%xmm15 +pshufd $0x39,%xmm11,%xmm11 +pshufd $0x39,%xmm1,%xmm1 +pshufd $0x39,%xmm6,%xmm6 +xorl 96(%rsi),%edx +xorl 100(%rsi),%ecx +xorl 104(%rsi),%r8d +xorl 108(%rsi),%r9d +movl %edx,96(%rdi) +movl %ecx,100(%rdi) +movl %r8d,104(%rdi) +movl %r9d,108(%rdi) +movd %xmm15,%rdx +movd %xmm11,%rcx +movd %xmm1,%r8 +movd %xmm6,%r9 +pshufd $0x39,%xmm15,%xmm15 +pshufd $0x39,%xmm11,%xmm11 +pshufd $0x39,%xmm1,%xmm1 +pshufd $0x39,%xmm6,%xmm6 +xorl 160(%rsi),%edx +xorl 164(%rsi),%ecx +xorl 168(%rsi),%r8d +xorl 172(%rsi),%r9d +movl %edx,160(%rdi) +movl %ecx,164(%rdi) +movl %r8d,168(%rdi) +movl %r9d,172(%rdi) +movd %xmm15,%rdx +movd %xmm11,%rcx +movd %xmm1,%r8 +movd %xmm6,%r9 +xorl 224(%rsi),%edx +xorl 228(%rsi),%ecx +xorl 232(%rsi),%r8d +xorl 236(%rsi),%r9d +movl %edx,224(%rdi) +movl %ecx,228(%rdi) +movl %r8d,232(%rdi) +movl %r9d,236(%rdi) +paddd 224(%rsp),%xmm13 +paddd 272(%rsp),%xmm9 +paddd 320(%rsp),%xmm3 +paddd 160(%rsp),%xmm2 +movd %xmm13,%rdx +movd %xmm9,%rcx +movd %xmm3,%r8 +movd %xmm2,%r9 +pshufd $0x39,%xmm13,%xmm13 +pshufd $0x39,%xmm9,%xmm9 +pshufd $0x39,%xmm3,%xmm3 +pshufd $0x39,%xmm2,%xmm2 +xorl 48(%rsi),%edx +xorl 52(%rsi),%ecx +xorl 56(%rsi),%r8d +xorl 60(%rsi),%r9d +movl %edx,48(%rdi) +movl %ecx,52(%rdi) +movl %r8d,56(%rdi) +movl %r9d,60(%rdi) +movd %xmm13,%rdx +movd %xmm9,%rcx +movd %xmm3,%r8 +movd %xmm2,%r9 +pshufd $0x39,%xmm13,%xmm13 +pshufd $0x39,%xmm9,%xmm9 +pshufd $0x39,%xmm3,%xmm3 +pshufd $0x39,%xmm2,%xmm2 +xorl 112(%rsi),%edx +xorl 116(%rsi),%ecx +xorl 120(%rsi),%r8d +xorl 124(%rsi),%r9d +movl %edx,112(%rdi) +movl %ecx,116(%rdi) +movl %r8d,120(%rdi) +movl %r9d,124(%rdi) +movd %xmm13,%rdx +movd %xmm9,%rcx +movd %xmm3,%r8 +movd %xmm2,%r9 +pshufd $0x39,%xmm13,%xmm13 +pshufd $0x39,%xmm9,%xmm9 +pshufd $0x39,%xmm3,%xmm3 +pshufd $0x39,%xmm2,%xmm2 +xorl 176(%rsi),%edx +xorl 180(%rsi),%ecx +xorl 184(%rsi),%r8d +xorl 188(%rsi),%r9d +movl %edx,176(%rdi) +movl %ecx,180(%rdi) +movl %r8d,184(%rdi) +movl %r9d,188(%rdi) +movd %xmm13,%rdx +movd %xmm9,%rcx +movd %xmm3,%r8 +movd %xmm2,%r9 +xorl 240(%rsi),%edx +xorl 244(%rsi),%ecx +xorl 248(%rsi),%r8d +xorl 252(%rsi),%r9d +movl %edx,240(%rdi) +movl %ecx,244(%rdi) +movl %r8d,248(%rdi) +movl %r9d,252(%rdi) +movq 480(%rsp),%r9 +sub $256,%r9 +add $256,%rsi +add $256,%rdi +cmp $256,%r9 +jae ._bytesatleast256 + +cmp $0,%r9 +jbe ._done + +._bytesbetween1and255: +cmp $64,%r9 +jae ._nocopy + +mov %rdi,%rdx +leaq 0(%rsp),%rdi +mov %r9,%rcx +rep movsb +leaq 0(%rsp),%rdi +leaq 0(%rsp),%rsi + +._nocopy: +movq %r9,480(%rsp) +movdqa 112(%rsp),%xmm0 +movdqa 64(%rsp),%xmm1 +movdqa 80(%rsp),%xmm2 +movdqa 96(%rsp),%xmm3 +movdqa %xmm1,%xmm4 +mov $20,%rcx + +.p2align 4 +._mainloop2: +paddd %xmm0,%xmm4 +movdqa %xmm0,%xmm5 +movdqa %xmm4,%xmm6 +pslld $7,%xmm4 +psrld $25,%xmm6 +pxor %xmm4,%xmm3 +pxor %xmm6,%xmm3 +paddd %xmm3,%xmm5 +movdqa %xmm3,%xmm4 +movdqa %xmm5,%xmm6 +pslld $9,%xmm5 +psrld $23,%xmm6 +pxor %xmm5,%xmm2 +pshufd $0x93,%xmm3,%xmm3 +pxor %xmm6,%xmm2 +paddd %xmm2,%xmm4 +movdqa %xmm2,%xmm5 +movdqa %xmm4,%xmm6 +pslld $13,%xmm4 +psrld $19,%xmm6 +pxor %xmm4,%xmm1 +pshufd $0x4e,%xmm2,%xmm2 +pxor %xmm6,%xmm1 +paddd %xmm1,%xmm5 +movdqa %xmm3,%xmm4 +movdqa %xmm5,%xmm6 +pslld $18,%xmm5 +psrld $14,%xmm6 +pxor %xmm5,%xmm0 +pshufd $0x39,%xmm1,%xmm1 +pxor %xmm6,%xmm0 +paddd %xmm0,%xmm4 +movdqa %xmm0,%xmm5 +movdqa %xmm4,%xmm6 +pslld $7,%xmm4 +psrld $25,%xmm6 +pxor %xmm4,%xmm1 +pxor %xmm6,%xmm1 +paddd %xmm1,%xmm5 +movdqa %xmm1,%xmm4 +movdqa %xmm5,%xmm6 +pslld $9,%xmm5 +psrld $23,%xmm6 +pxor %xmm5,%xmm2 +pshufd $0x93,%xmm1,%xmm1 +pxor %xmm6,%xmm2 +paddd %xmm2,%xmm4 +movdqa %xmm2,%xmm5 +movdqa %xmm4,%xmm6 +pslld $13,%xmm4 +psrld $19,%xmm6 +pxor %xmm4,%xmm3 +pshufd $0x4e,%xmm2,%xmm2 +pxor %xmm6,%xmm3 +paddd %xmm3,%xmm5 +movdqa %xmm1,%xmm4 +movdqa %xmm5,%xmm6 +pslld $18,%xmm5 +psrld $14,%xmm6 +pxor %xmm5,%xmm0 +pshufd $0x39,%xmm3,%xmm3 +pxor %xmm6,%xmm0 +paddd %xmm0,%xmm4 +movdqa %xmm0,%xmm5 +movdqa %xmm4,%xmm6 +pslld $7,%xmm4 +psrld $25,%xmm6 +pxor %xmm4,%xmm3 +pxor %xmm6,%xmm3 +paddd %xmm3,%xmm5 +movdqa %xmm3,%xmm4 +movdqa %xmm5,%xmm6 +pslld $9,%xmm5 +psrld $23,%xmm6 +pxor %xmm5,%xmm2 +pshufd $0x93,%xmm3,%xmm3 +pxor %xmm6,%xmm2 +paddd %xmm2,%xmm4 +movdqa %xmm2,%xmm5 +movdqa %xmm4,%xmm6 +pslld $13,%xmm4 +psrld $19,%xmm6 +pxor %xmm4,%xmm1 +pshufd $0x4e,%xmm2,%xmm2 +pxor %xmm6,%xmm1 +paddd %xmm1,%xmm5 +movdqa %xmm3,%xmm4 +movdqa %xmm5,%xmm6 +pslld $18,%xmm5 +psrld $14,%xmm6 +pxor %xmm5,%xmm0 +pshufd $0x39,%xmm1,%xmm1 +pxor %xmm6,%xmm0 +paddd %xmm0,%xmm4 +movdqa %xmm0,%xmm5 +movdqa %xmm4,%xmm6 +pslld $7,%xmm4 +psrld $25,%xmm6 +pxor %xmm4,%xmm1 +pxor %xmm6,%xmm1 +paddd %xmm1,%xmm5 +movdqa %xmm1,%xmm4 +movdqa %xmm5,%xmm6 +pslld $9,%xmm5 +psrld $23,%xmm6 +pxor %xmm5,%xmm2 +pshufd $0x93,%xmm1,%xmm1 +pxor %xmm6,%xmm2 +paddd %xmm2,%xmm4 +movdqa %xmm2,%xmm5 +movdqa %xmm4,%xmm6 +pslld $13,%xmm4 +psrld $19,%xmm6 +pxor %xmm4,%xmm3 +pshufd $0x4e,%xmm2,%xmm2 +pxor %xmm6,%xmm3 +sub $4,%rcx +paddd %xmm3,%xmm5 +movdqa %xmm1,%xmm4 +movdqa %xmm5,%xmm6 +pslld $18,%xmm5 +pxor %xmm7,%xmm7 +psrld $14,%xmm6 +pxor %xmm5,%xmm0 +pshufd $0x39,%xmm3,%xmm3 +pxor %xmm6,%xmm0 +ja ._mainloop2 + +paddd 112(%rsp),%xmm0 +paddd 64(%rsp),%xmm1 +paddd 80(%rsp),%xmm2 +paddd 96(%rsp),%xmm3 +movd %xmm0,%rcx +movd %xmm1,%r8 +movd %xmm2,%r9 +movd %xmm3,%rax +pshufd $0x39,%xmm0,%xmm0 +pshufd $0x39,%xmm1,%xmm1 +pshufd $0x39,%xmm2,%xmm2 +pshufd $0x39,%xmm3,%xmm3 +xorl 0(%rsi),%ecx +xorl 48(%rsi),%r8d +xorl 32(%rsi),%r9d +xorl 16(%rsi),%eax +movl %ecx,0(%rdi) +movl %r8d,48(%rdi) +movl %r9d,32(%rdi) +movl %eax,16(%rdi) +movd %xmm0,%rcx +movd %xmm1,%r8 +movd %xmm2,%r9 +movd %xmm3,%rax +pshufd $0x39,%xmm0,%xmm0 +pshufd $0x39,%xmm1,%xmm1 +pshufd $0x39,%xmm2,%xmm2 +pshufd $0x39,%xmm3,%xmm3 +xorl 20(%rsi),%ecx +xorl 4(%rsi),%r8d +xorl 52(%rsi),%r9d +xorl 36(%rsi),%eax +movl %ecx,20(%rdi) +movl %r8d,4(%rdi) +movl %r9d,52(%rdi) +movl %eax,36(%rdi) +movd %xmm0,%rcx +movd %xmm1,%r8 +movd %xmm2,%r9 +movd %xmm3,%rax +pshufd $0x39,%xmm0,%xmm0 +pshufd $0x39,%xmm1,%xmm1 +pshufd $0x39,%xmm2,%xmm2 +pshufd $0x39,%xmm3,%xmm3 +xorl 40(%rsi),%ecx +xorl 24(%rsi),%r8d +xorl 8(%rsi),%r9d +xorl 56(%rsi),%eax +movl %ecx,40(%rdi) +movl %r8d,24(%rdi) +movl %r9d,8(%rdi) +movl %eax,56(%rdi) +movd %xmm0,%rcx +movd %xmm1,%r8 +movd %xmm2,%r9 +movd %xmm3,%rax +xorl 60(%rsi),%ecx +xorl 44(%rsi),%r8d +xorl 28(%rsi),%r9d +xorl 12(%rsi),%eax +movl %ecx,60(%rdi) +movl %r8d,44(%rdi) +movl %r9d,28(%rdi) +movl %eax,12(%rdi) +movq 480(%rsp),%r9 +movq 472(%rsp),%rcx +add $1,%rcx +mov %rcx,%r8 +shr $32,%r8 +movl %ecx,80(%rsp) +movl %r8d,4+96(%rsp) +movq %rcx,472(%rsp) +cmp $64,%r9 +ja ._bytesatleast65 +jae ._bytesatleast64 + +mov %rdi,%rsi +mov %rdx,%rdi +mov %r9,%rcx +rep movsb + +._bytesatleast64: +._done: +movq 416(%rsp),%r11 +movq 424(%rsp),%r12 +movq 432(%rsp),%r13 +movq 440(%rsp),%r14 +movq 448(%rsp),%r15 +movq 456(%rsp),%rbx +movq 464(%rsp),%rbp +add %r11,%rsp +xor %rax,%rax +mov %rsi,%rdx +ret + +._bytesatleast65: +sub $64,%r9 +add $64,%rdi +add $64,%rsi +jmp ._bytesbetween1and255 + +#endif + +#if defined(__linux__) && defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6/salsa20_xmm6.c b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6/salsa20_xmm6.c new file mode 100644 index 0000000..0a6fee0 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6/salsa20_xmm6.c @@ -0,0 +1,31 @@ + +#include + +#include "utils.h" + +#include "../stream_salsa20.h" +#include "salsa20_xmm6.h" + +#ifdef HAVE_AMD64_ASM + +#ifdef __cplusplus +extern "C" { +#endif +extern int stream_salsa20_xmm6(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +extern int stream_salsa20_xmm6_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + uint64_t ic, const unsigned char *k); +#ifdef __cplusplus +} +#endif + +struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_xmm6_implementation = { + SODIUM_C99(.stream =) stream_salsa20_xmm6, + SODIUM_C99(.stream_xor_ic =) stream_salsa20_xmm6_xor_ic, + }; + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6/salsa20_xmm6.h b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6/salsa20_xmm6.h new file mode 100644 index 0000000..d38473a --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6/salsa20_xmm6.h @@ -0,0 +1,8 @@ + +#include + +#include "../stream_salsa20.h" +#include "crypto_stream_salsa20.h" + +extern struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_xmm6_implementation; diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c new file mode 100644 index 0000000..507d7fe --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c @@ -0,0 +1,131 @@ + +#include +#include +#include + +#include "crypto_stream_salsa20.h" +#include "private/common.h" +#include "utils.h" + +#if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ + defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# pragma GCC target("ssse3") +# pragma GCC target("sse4.1") +# pragma GCC target("avx2") +# endif + +#include +#include +#include +#include +#include "private/sse2_64_32.h" + +# include "../stream_salsa20.h" +# include "salsa20_xmm6int-avx2.h" + +# define ROUNDS 20 + +typedef struct salsa_ctx { + uint32_t input[16]; +} salsa_ctx; + +static const int TR[16] = { + 0, 5, 10, 15, 12, 1, 6, 11, 8, 13, 2, 7, 4, 9, 14, 3 +}; + +static void +salsa_keysetup(salsa_ctx *ctx, const uint8_t *k) +{ + ctx->input[TR[1]] = LOAD32_LE(k + 0); + ctx->input[TR[2]] = LOAD32_LE(k + 4); + ctx->input[TR[3]] = LOAD32_LE(k + 8); + ctx->input[TR[4]] = LOAD32_LE(k + 12); + ctx->input[TR[11]] = LOAD32_LE(k + 16); + ctx->input[TR[12]] = LOAD32_LE(k + 20); + ctx->input[TR[13]] = LOAD32_LE(k + 24); + ctx->input[TR[14]] = LOAD32_LE(k + 28); + ctx->input[TR[0]] = 0x61707865; + ctx->input[TR[5]] = 0x3320646e; + ctx->input[TR[10]] = 0x79622d32; + ctx->input[TR[15]] = 0x6b206574; +} + +static void +salsa_ivsetup(salsa_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[TR[6]] = LOAD32_LE(iv + 0); + ctx->input[TR[7]] = LOAD32_LE(iv + 4); + ctx->input[TR[8]] = counter == NULL ? 0 : LOAD32_LE(counter + 0); + ctx->input[TR[9]] = counter == NULL ? 0 : LOAD32_LE(counter + 4); +} + +static void +salsa20_encrypt_bytes(salsa_ctx *ctx, const uint8_t *m, uint8_t *c, + unsigned long long bytes) +{ + uint32_t * const x = &ctx->input[0]; + + if (!bytes) { + return; /* LCOV_EXCL_LINE */ + } + +#include "u8.h" +#include "u4.h" +#include "u1.h" +#include "u0.h" +} + +static int +stream_avx2(unsigned char *c, unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + struct salsa_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_salsa20_KEYBYTES == 256 / 8); + salsa_keysetup(&ctx, k); + salsa_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + salsa20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_avx2_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + struct salsa_ctx ctx; + uint8_t ic_bytes[8]; + uint32_t ic_high; + uint32_t ic_low; + + if (!mlen) { + return 0; + } + ic_high = (uint32_t) (ic >> 32); + ic_low = (uint32_t) ic; + STORE32_LE(&ic_bytes[0], ic_low); + STORE32_LE(&ic_bytes[4], ic_high); + salsa_keysetup(&ctx, k); + salsa_ivsetup(&ctx, n, ic_bytes); + salsa20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_xmm6int_avx2_implementation = { + SODIUM_C99(.stream =) stream_avx2, + SODIUM_C99(.stream_xor_ic =) stream_avx2_xor_ic + }; + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.h b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.h new file mode 100644 index 0000000..0924e9b --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.h @@ -0,0 +1,8 @@ + +#include + +#include "../stream_salsa20.h" +#include "crypto_stream_salsa20.h" + +extern struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_xmm6int_avx2_implementation; diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c new file mode 100644 index 0000000..16cca0d --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c @@ -0,0 +1,122 @@ + +#include +#include +#include + +#include "crypto_stream_salsa20.h" +#include "private/common.h" +#include "utils.h" + +#ifdef HAVE_EMMINTRIN_H + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# endif +# include +# include "private/sse2_64_32.h" + +# include "../stream_salsa20.h" +# include "salsa20_xmm6int-sse2.h" + +# define ROUNDS 20 + +typedef struct salsa_ctx { + uint32_t input[16]; +} salsa_ctx; + +static const int TR[16] = { + 0, 5, 10, 15, 12, 1, 6, 11, 8, 13, 2, 7, 4, 9, 14, 3 +}; + +static void +salsa_keysetup(salsa_ctx *ctx, const uint8_t *k) +{ + ctx->input[TR[1]] = LOAD32_LE(k + 0); + ctx->input[TR[2]] = LOAD32_LE(k + 4); + ctx->input[TR[3]] = LOAD32_LE(k + 8); + ctx->input[TR[4]] = LOAD32_LE(k + 12); + ctx->input[TR[11]] = LOAD32_LE(k + 16); + ctx->input[TR[12]] = LOAD32_LE(k + 20); + ctx->input[TR[13]] = LOAD32_LE(k + 24); + ctx->input[TR[14]] = LOAD32_LE(k + 28); + ctx->input[TR[0]] = 0x61707865; + ctx->input[TR[5]] = 0x3320646e; + ctx->input[TR[10]] = 0x79622d32; + ctx->input[TR[15]] = 0x6b206574; +} + +static void +salsa_ivsetup(salsa_ctx *ctx, const uint8_t *iv, const uint8_t *counter) +{ + ctx->input[TR[6]] = LOAD32_LE(iv + 0); + ctx->input[TR[7]] = LOAD32_LE(iv + 4); + ctx->input[TR[8]] = counter == NULL ? 0 : LOAD32_LE(counter + 0); + ctx->input[TR[9]] = counter == NULL ? 0 : LOAD32_LE(counter + 4); +} + +static void +salsa20_encrypt_bytes(salsa_ctx *ctx, const uint8_t *m, uint8_t *c, + unsigned long long bytes) +{ + uint32_t * const x = &ctx->input[0]; + + if (!bytes) { + return; /* LCOV_EXCL_LINE */ + } + +#include "u4.h" +#include "u1.h" +#include "u0.h" +} + +static int +stream_sse2(unsigned char *c, unsigned long long clen, const unsigned char *n, + const unsigned char *k) +{ + struct salsa_ctx ctx; + + if (!clen) { + return 0; + } + COMPILER_ASSERT(crypto_stream_salsa20_KEYBYTES == 256 / 8); + salsa_keysetup(&ctx, k); + salsa_ivsetup(&ctx, n, NULL); + memset(c, 0, clen); + salsa20_encrypt_bytes(&ctx, c, c, clen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +static int +stream_sse2_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, uint64_t ic, + const unsigned char *k) +{ + struct salsa_ctx ctx; + uint8_t ic_bytes[8]; + uint32_t ic_high; + uint32_t ic_low; + + if (!mlen) { + return 0; + } + ic_high = (uint32_t) (ic >> 32); + ic_low = (uint32_t) (ic); + STORE32_LE(&ic_bytes[0], ic_low); + STORE32_LE(&ic_bytes[4], ic_high); + salsa_keysetup(&ctx, k); + salsa_ivsetup(&ctx, n, ic_bytes); + salsa20_encrypt_bytes(&ctx, m, c, mlen); + sodium_memzero(&ctx, sizeof ctx); + + return 0; +} + +struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_xmm6int_sse2_implementation = { + SODIUM_C99(.stream =) stream_sse2, + SODIUM_C99(.stream_xor_ic =) stream_sse2_xor_ic + }; + +#endif diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.h b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.h new file mode 100644 index 0000000..ed52a8b --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.h @@ -0,0 +1,8 @@ + +#include + +#include "../stream_salsa20.h" +#include "crypto_stream_salsa20.h" + +extern struct crypto_stream_salsa20_implementation + crypto_stream_salsa20_xmm6int_sse2_implementation; diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/u0.h b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/u0.h new file mode 100644 index 0000000..830f70e --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/u0.h @@ -0,0 +1,195 @@ +if (bytes > 0) { + __m128i diag0 = _mm_loadu_si128((const __m128i *) (x + 0)); + __m128i diag1 = _mm_loadu_si128((const __m128i *) (x + 4)); + __m128i diag2 = _mm_loadu_si128((const __m128i *) (x + 8)); + __m128i diag3 = _mm_loadu_si128((const __m128i *) (x + 12)); + __m128i a0, a1, a2, a3, a4, a5, a6, a7; + __m128i b0, b1, b2, b3, b4, b5, b6, b7; + uint8_t partialblock[64]; + + unsigned int i; + + a0 = diag1; + for (i = 0; i < ROUNDS; i += 4) { + a0 = _mm_add_epi32(a0, diag0); + a1 = diag0; + b0 = a0; + a0 = _mm_slli_epi32(a0, 7); + b0 = _mm_srli_epi32(b0, 25); + diag3 = _mm_xor_si128(diag3, a0); + + diag3 = _mm_xor_si128(diag3, b0); + + a1 = _mm_add_epi32(a1, diag3); + a2 = diag3; + b1 = a1; + a1 = _mm_slli_epi32(a1, 9); + b1 = _mm_srli_epi32(b1, 23); + diag2 = _mm_xor_si128(diag2, a1); + diag3 = _mm_shuffle_epi32(diag3, 0x93); + diag2 = _mm_xor_si128(diag2, b1); + + a2 = _mm_add_epi32(a2, diag2); + a3 = diag2; + b2 = a2; + a2 = _mm_slli_epi32(a2, 13); + b2 = _mm_srli_epi32(b2, 19); + diag1 = _mm_xor_si128(diag1, a2); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag1 = _mm_xor_si128(diag1, b2); + + a3 = _mm_add_epi32(a3, diag1); + a4 = diag3; + b3 = a3; + a3 = _mm_slli_epi32(a3, 18); + b3 = _mm_srli_epi32(b3, 14); + diag0 = _mm_xor_si128(diag0, a3); + diag1 = _mm_shuffle_epi32(diag1, 0x39); + diag0 = _mm_xor_si128(diag0, b3); + + a4 = _mm_add_epi32(a4, diag0); + a5 = diag0; + b4 = a4; + a4 = _mm_slli_epi32(a4, 7); + b4 = _mm_srli_epi32(b4, 25); + diag1 = _mm_xor_si128(diag1, a4); + + diag1 = _mm_xor_si128(diag1, b4); + + a5 = _mm_add_epi32(a5, diag1); + a6 = diag1; + b5 = a5; + a5 = _mm_slli_epi32(a5, 9); + b5 = _mm_srli_epi32(b5, 23); + diag2 = _mm_xor_si128(diag2, a5); + diag1 = _mm_shuffle_epi32(diag1, 0x93); + diag2 = _mm_xor_si128(diag2, b5); + + a6 = _mm_add_epi32(a6, diag2); + a7 = diag2; + b6 = a6; + a6 = _mm_slli_epi32(a6, 13); + b6 = _mm_srli_epi32(b6, 19); + diag3 = _mm_xor_si128(diag3, a6); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag3 = _mm_xor_si128(diag3, b6); + + a7 = _mm_add_epi32(a7, diag3); + a0 = diag1; + b7 = a7; + a7 = _mm_slli_epi32(a7, 18); + b7 = _mm_srli_epi32(b7, 14); + diag0 = _mm_xor_si128(diag0, a7); + diag3 = _mm_shuffle_epi32(diag3, 0x39); + diag0 = _mm_xor_si128(diag0, b7); + + a0 = _mm_add_epi32(a0, diag0); + a1 = diag0; + b0 = a0; + a0 = _mm_slli_epi32(a0, 7); + b0 = _mm_srli_epi32(b0, 25); + diag3 = _mm_xor_si128(diag3, a0); + + diag3 = _mm_xor_si128(diag3, b0); + + a1 = _mm_add_epi32(a1, diag3); + a2 = diag3; + b1 = a1; + a1 = _mm_slli_epi32(a1, 9); + b1 = _mm_srli_epi32(b1, 23); + diag2 = _mm_xor_si128(diag2, a1); + diag3 = _mm_shuffle_epi32(diag3, 0x93); + diag2 = _mm_xor_si128(diag2, b1); + + a2 = _mm_add_epi32(a2, diag2); + a3 = diag2; + b2 = a2; + a2 = _mm_slli_epi32(a2, 13); + b2 = _mm_srli_epi32(b2, 19); + diag1 = _mm_xor_si128(diag1, a2); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag1 = _mm_xor_si128(diag1, b2); + + a3 = _mm_add_epi32(a3, diag1); + a4 = diag3; + b3 = a3; + a3 = _mm_slli_epi32(a3, 18); + b3 = _mm_srli_epi32(b3, 14); + diag0 = _mm_xor_si128(diag0, a3); + diag1 = _mm_shuffle_epi32(diag1, 0x39); + diag0 = _mm_xor_si128(diag0, b3); + + a4 = _mm_add_epi32(a4, diag0); + a5 = diag0; + b4 = a4; + a4 = _mm_slli_epi32(a4, 7); + b4 = _mm_srli_epi32(b4, 25); + diag1 = _mm_xor_si128(diag1, a4); + + diag1 = _mm_xor_si128(diag1, b4); + + a5 = _mm_add_epi32(a5, diag1); + a6 = diag1; + b5 = a5; + a5 = _mm_slli_epi32(a5, 9); + b5 = _mm_srli_epi32(b5, 23); + diag2 = _mm_xor_si128(diag2, a5); + diag1 = _mm_shuffle_epi32(diag1, 0x93); + diag2 = _mm_xor_si128(diag2, b5); + + a6 = _mm_add_epi32(a6, diag2); + a7 = diag2; + b6 = a6; + a6 = _mm_slli_epi32(a6, 13); + b6 = _mm_srli_epi32(b6, 19); + diag3 = _mm_xor_si128(diag3, a6); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag3 = _mm_xor_si128(diag3, b6); + + a7 = _mm_add_epi32(a7, diag3); + a0 = diag1; + b7 = a7; + a7 = _mm_slli_epi32(a7, 18); + b7 = _mm_srli_epi32(b7, 14); + diag0 = _mm_xor_si128(diag0, a7); + diag3 = _mm_shuffle_epi32(diag3, 0x39); + diag0 = _mm_xor_si128(diag0, b7); + } + + diag0 = _mm_add_epi32(diag0, _mm_loadu_si128((const __m128i *) (x + 0))); + diag1 = _mm_add_epi32(diag1, _mm_loadu_si128((const __m128i *) (x + 4))); + diag2 = _mm_add_epi32(diag2, _mm_loadu_si128((const __m128i *) (x + 8))); + diag3 = _mm_add_epi32(diag3, _mm_loadu_si128((const __m128i *) (x + 12))); + +#define ONEQUAD_SHUFFLE(A, B, C, D) \ + do { \ + uint32_t in##A = _mm_cvtsi128_si32(diag0); \ + uint32_t in##B = _mm_cvtsi128_si32(diag1); \ + uint32_t in##C = _mm_cvtsi128_si32(diag2); \ + uint32_t in##D = _mm_cvtsi128_si32(diag3); \ + diag0 = _mm_shuffle_epi32(diag0, 0x39); \ + diag1 = _mm_shuffle_epi32(diag1, 0x39); \ + diag2 = _mm_shuffle_epi32(diag2, 0x39); \ + diag3 = _mm_shuffle_epi32(diag3, 0x39); \ + *(uint32_t *) (partialblock + (A * 4)) = in##A; \ + *(uint32_t *) (partialblock + (B * 4)) = in##B; \ + *(uint32_t *) (partialblock + (C * 4)) = in##C; \ + *(uint32_t *) (partialblock + (D * 4)) = in##D; \ + } while (0) + +#define ONEQUAD(A, B, C, D) ONEQUAD_SHUFFLE(A, B, C, D) + + ONEQUAD(0, 12, 8, 4); + ONEQUAD(5, 1, 13, 9); + ONEQUAD(10, 6, 2, 14); + ONEQUAD(15, 11, 7, 3); + +#undef ONEQUAD +#undef ONEQUAD_SHUFFLE + + for (i = 0; i < bytes; i++) { + c[i] = m[i] ^ partialblock[i]; + } + + sodium_memzero(partialblock, sizeof partialblock); +} diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/u1.h b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/u1.h new file mode 100644 index 0000000..e82521c --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/u1.h @@ -0,0 +1,207 @@ +while (bytes >= 64) { + __m128i diag0 = _mm_loadu_si128((const __m128i *) (x + 0)); + __m128i diag1 = _mm_loadu_si128((const __m128i *) (x + 4)); + __m128i diag2 = _mm_loadu_si128((const __m128i *) (x + 8)); + __m128i diag3 = _mm_loadu_si128((const __m128i *) (x + 12)); + __m128i a0, a1, a2, a3, a4, a5, a6, a7; + __m128i b0, b1, b2, b3, b4, b5, b6, b7; + + uint32_t in8; + uint32_t in9; + int i; + + a0 = diag1; + for (i = 0; i < ROUNDS; i += 4) { + a0 = _mm_add_epi32(a0, diag0); + a1 = diag0; + b0 = a0; + a0 = _mm_slli_epi32(a0, 7); + b0 = _mm_srli_epi32(b0, 25); + diag3 = _mm_xor_si128(diag3, a0); + + diag3 = _mm_xor_si128(diag3, b0); + + a1 = _mm_add_epi32(a1, diag3); + a2 = diag3; + b1 = a1; + a1 = _mm_slli_epi32(a1, 9); + b1 = _mm_srli_epi32(b1, 23); + diag2 = _mm_xor_si128(diag2, a1); + diag3 = _mm_shuffle_epi32(diag3, 0x93); + diag2 = _mm_xor_si128(diag2, b1); + + a2 = _mm_add_epi32(a2, diag2); + a3 = diag2; + b2 = a2; + a2 = _mm_slli_epi32(a2, 13); + b2 = _mm_srli_epi32(b2, 19); + diag1 = _mm_xor_si128(diag1, a2); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag1 = _mm_xor_si128(diag1, b2); + + a3 = _mm_add_epi32(a3, diag1); + a4 = diag3; + b3 = a3; + a3 = _mm_slli_epi32(a3, 18); + b3 = _mm_srli_epi32(b3, 14); + diag0 = _mm_xor_si128(diag0, a3); + diag1 = _mm_shuffle_epi32(diag1, 0x39); + diag0 = _mm_xor_si128(diag0, b3); + + a4 = _mm_add_epi32(a4, diag0); + a5 = diag0; + b4 = a4; + a4 = _mm_slli_epi32(a4, 7); + b4 = _mm_srli_epi32(b4, 25); + diag1 = _mm_xor_si128(diag1, a4); + + diag1 = _mm_xor_si128(diag1, b4); + + a5 = _mm_add_epi32(a5, diag1); + a6 = diag1; + b5 = a5; + a5 = _mm_slli_epi32(a5, 9); + b5 = _mm_srli_epi32(b5, 23); + diag2 = _mm_xor_si128(diag2, a5); + diag1 = _mm_shuffle_epi32(diag1, 0x93); + diag2 = _mm_xor_si128(diag2, b5); + + a6 = _mm_add_epi32(a6, diag2); + a7 = diag2; + b6 = a6; + a6 = _mm_slli_epi32(a6, 13); + b6 = _mm_srli_epi32(b6, 19); + diag3 = _mm_xor_si128(diag3, a6); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag3 = _mm_xor_si128(diag3, b6); + + a7 = _mm_add_epi32(a7, diag3); + a0 = diag1; + b7 = a7; + a7 = _mm_slli_epi32(a7, 18); + b7 = _mm_srli_epi32(b7, 14); + diag0 = _mm_xor_si128(diag0, a7); + diag3 = _mm_shuffle_epi32(diag3, 0x39); + diag0 = _mm_xor_si128(diag0, b7); + + a0 = _mm_add_epi32(a0, diag0); + a1 = diag0; + b0 = a0; + a0 = _mm_slli_epi32(a0, 7); + b0 = _mm_srli_epi32(b0, 25); + diag3 = _mm_xor_si128(diag3, a0); + + diag3 = _mm_xor_si128(diag3, b0); + + a1 = _mm_add_epi32(a1, diag3); + a2 = diag3; + b1 = a1; + a1 = _mm_slli_epi32(a1, 9); + b1 = _mm_srli_epi32(b1, 23); + diag2 = _mm_xor_si128(diag2, a1); + diag3 = _mm_shuffle_epi32(diag3, 0x93); + diag2 = _mm_xor_si128(diag2, b1); + + a2 = _mm_add_epi32(a2, diag2); + a3 = diag2; + b2 = a2; + a2 = _mm_slli_epi32(a2, 13); + b2 = _mm_srli_epi32(b2, 19); + diag1 = _mm_xor_si128(diag1, a2); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag1 = _mm_xor_si128(diag1, b2); + + a3 = _mm_add_epi32(a3, diag1); + a4 = diag3; + b3 = a3; + a3 = _mm_slli_epi32(a3, 18); + b3 = _mm_srli_epi32(b3, 14); + diag0 = _mm_xor_si128(diag0, a3); + diag1 = _mm_shuffle_epi32(diag1, 0x39); + diag0 = _mm_xor_si128(diag0, b3); + + a4 = _mm_add_epi32(a4, diag0); + a5 = diag0; + b4 = a4; + a4 = _mm_slli_epi32(a4, 7); + b4 = _mm_srli_epi32(b4, 25); + diag1 = _mm_xor_si128(diag1, a4); + + diag1 = _mm_xor_si128(diag1, b4); + + a5 = _mm_add_epi32(a5, diag1); + a6 = diag1; + b5 = a5; + a5 = _mm_slli_epi32(a5, 9); + b5 = _mm_srli_epi32(b5, 23); + diag2 = _mm_xor_si128(diag2, a5); + diag1 = _mm_shuffle_epi32(diag1, 0x93); + diag2 = _mm_xor_si128(diag2, b5); + + a6 = _mm_add_epi32(a6, diag2); + a7 = diag2; + b6 = a6; + a6 = _mm_slli_epi32(a6, 13); + b6 = _mm_srli_epi32(b6, 19); + diag3 = _mm_xor_si128(diag3, a6); + diag2 = _mm_shuffle_epi32(diag2, 0x4e); + diag3 = _mm_xor_si128(diag3, b6); + + a7 = _mm_add_epi32(a7, diag3); + a0 = diag1; + b7 = a7; + a7 = _mm_slli_epi32(a7, 18); + b7 = _mm_srli_epi32(b7, 14); + diag0 = _mm_xor_si128(diag0, a7); + diag3 = _mm_shuffle_epi32(diag3, 0x39); + diag0 = _mm_xor_si128(diag0, b7); + } + + diag0 = _mm_add_epi32(diag0, _mm_loadu_si128((const __m128i *) (x + 0))); + diag1 = _mm_add_epi32(diag1, _mm_loadu_si128((const __m128i *) (x + 4))); + diag2 = _mm_add_epi32(diag2, _mm_loadu_si128((const __m128i *) (x + 8))); + diag3 = _mm_add_epi32(diag3, _mm_loadu_si128((const __m128i *) (x + 12))); + +#define ONEQUAD_SHUFFLE(A, B, C, D) \ + do { \ + uint32_t in##A = _mm_cvtsi128_si32(diag0); \ + uint32_t in##B = _mm_cvtsi128_si32(diag1); \ + uint32_t in##C = _mm_cvtsi128_si32(diag2); \ + uint32_t in##D = _mm_cvtsi128_si32(diag3); \ + diag0 = _mm_shuffle_epi32(diag0, 0x39); \ + diag1 = _mm_shuffle_epi32(diag1, 0x39); \ + diag2 = _mm_shuffle_epi32(diag2, 0x39); \ + diag3 = _mm_shuffle_epi32(diag3, 0x39); \ + in##A ^= *(const uint32_t *) (m + (A * 4)); \ + in##B ^= *(const uint32_t *) (m + (B * 4)); \ + in##C ^= *(const uint32_t *) (m + (C * 4)); \ + in##D ^= *(const uint32_t *) (m + (D * 4)); \ + *(uint32_t *) (c + (A * 4)) = in##A; \ + *(uint32_t *) (c + (B * 4)) = in##B; \ + *(uint32_t *) (c + (C * 4)) = in##C; \ + *(uint32_t *) (c + (D * 4)) = in##D; \ + } while (0) + +#define ONEQUAD(A, B, C, D) ONEQUAD_SHUFFLE(A, B, C, D) + + ONEQUAD(0, 12, 8, 4); + ONEQUAD(5, 1, 13, 9); + ONEQUAD(10, 6, 2, 14); + ONEQUAD(15, 11, 7, 3); + +#undef ONEQUAD +#undef ONEQUAD_SHUFFLE + + in8 = x[8]; + in9 = x[13]; + in8++; + if (in8 == 0) { + in9++; + } + x[8] = in8; + x[13] = in9; + + c += 64; + m += 64; + bytes -= 64; +} diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/u4.h b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/u4.h new file mode 100644 index 0000000..474f486 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/u4.h @@ -0,0 +1,547 @@ +if (bytes >= 256) { + __m128i y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11, y12, y13, y14, + y15; + __m128i z0, z1, z2, z3, z4, z5, z6, z7, z8, z9, z10, z11, z12, z13, z14, + z15; + __m128i orig0, orig1, orig2, orig3, orig4, orig5, orig6, orig7, orig8, + orig9, orig10, orig11, orig12, orig13, orig14, orig15; + + uint32_t in8; + uint32_t in9; + int i; + + /* element broadcast immediate for _mm_shuffle_epi32 are in order: + 0x00, 0x55, 0xaa, 0xff */ + z0 = _mm_loadu_si128((const __m128i *) (x + 0)); + z5 = _mm_shuffle_epi32(z0, 0x55); + z10 = _mm_shuffle_epi32(z0, 0xaa); + z15 = _mm_shuffle_epi32(z0, 0xff); + z0 = _mm_shuffle_epi32(z0, 0x00); + z1 = _mm_loadu_si128((const __m128i *) (x + 4)); + z6 = _mm_shuffle_epi32(z1, 0xaa); + z11 = _mm_shuffle_epi32(z1, 0xff); + z12 = _mm_shuffle_epi32(z1, 0x00); + z1 = _mm_shuffle_epi32(z1, 0x55); + z2 = _mm_loadu_si128((const __m128i *) (x + 8)); + z7 = _mm_shuffle_epi32(z2, 0xff); + z13 = _mm_shuffle_epi32(z2, 0x55); + z2 = _mm_shuffle_epi32(z2, 0xaa); + /* no z8 -> first half of the nonce, will fill later */ + z3 = _mm_loadu_si128((const __m128i *) (x + 12)); + z4 = _mm_shuffle_epi32(z3, 0x00); + z14 = _mm_shuffle_epi32(z3, 0xaa); + z3 = _mm_shuffle_epi32(z3, 0xff); + /* no z9 -> second half of the nonce, will fill later */ + orig0 = z0; + orig1 = z1; + orig2 = z2; + orig3 = z3; + orig4 = z4; + orig5 = z5; + orig6 = z6; + orig7 = z7; + orig10 = z10; + orig11 = z11; + orig12 = z12; + orig13 = z13; + orig14 = z14; + orig15 = z15; + + while (bytes >= 256) { + /* vector implementation for z8 and z9 */ + /* not sure if it helps for only 4 blocks */ + const __m128i addv8 = _mm_set_epi64x(1, 0); + const __m128i addv9 = _mm_set_epi64x(3, 2); + __m128i t8, t9; + uint64_t in89; + + in8 = x[8]; + in9 = x[13]; + in89 = ((uint64_t) in8) | (((uint64_t) in9) << 32); + t8 = _mm_set1_epi64x(in89); + t9 = _mm_set1_epi64x(in89); + + z8 = _mm_add_epi64(addv8, t8); + z9 = _mm_add_epi64(addv9, t9); + + t8 = _mm_unpacklo_epi32(z8, z9); + t9 = _mm_unpackhi_epi32(z8, z9); + + z8 = _mm_unpacklo_epi32(t8, t9); + z9 = _mm_unpackhi_epi32(t8, t9); + + orig8 = z8; + orig9 = z9; + + in89 += 4; + + x[8] = in89 & 0xFFFFFFFF; + x[13] = (in89 >> 32) & 0xFFFFFFFF; + + z5 = orig5; + z10 = orig10; + z15 = orig15; + z14 = orig14; + z3 = orig3; + z6 = orig6; + z11 = orig11; + z1 = orig1; + + z7 = orig7; + z13 = orig13; + z2 = orig2; + z9 = orig9; + z0 = orig0; + z12 = orig12; + z4 = orig4; + z8 = orig8; + + for (i = 0; i < ROUNDS; i += 2) { + /* the inner loop is a direct translation (regexp search/replace) + * from the amd64-xmm6 ASM */ + __m128i r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, + r14, r15; + + y4 = z12; + y4 = _mm_add_epi32(y4, z0); + r4 = y4; + y4 = _mm_slli_epi32(y4, 7); + z4 = _mm_xor_si128(z4, y4); + r4 = _mm_srli_epi32(r4, 25); + z4 = _mm_xor_si128(z4, r4); + + y9 = z1; + y9 = _mm_add_epi32(y9, z5); + r9 = y9; + y9 = _mm_slli_epi32(y9, 7); + z9 = _mm_xor_si128(z9, y9); + r9 = _mm_srli_epi32(r9, 25); + z9 = _mm_xor_si128(z9, r9); + + y8 = z0; + y8 = _mm_add_epi32(y8, z4); + r8 = y8; + y8 = _mm_slli_epi32(y8, 9); + z8 = _mm_xor_si128(z8, y8); + r8 = _mm_srli_epi32(r8, 23); + z8 = _mm_xor_si128(z8, r8); + + y13 = z5; + y13 = _mm_add_epi32(y13, z9); + r13 = y13; + y13 = _mm_slli_epi32(y13, 9); + z13 = _mm_xor_si128(z13, y13); + r13 = _mm_srli_epi32(r13, 23); + z13 = _mm_xor_si128(z13, r13); + + y12 = z4; + y12 = _mm_add_epi32(y12, z8); + r12 = y12; + y12 = _mm_slli_epi32(y12, 13); + z12 = _mm_xor_si128(z12, y12); + r12 = _mm_srli_epi32(r12, 19); + z12 = _mm_xor_si128(z12, r12); + + y1 = z9; + y1 = _mm_add_epi32(y1, z13); + r1 = y1; + y1 = _mm_slli_epi32(y1, 13); + z1 = _mm_xor_si128(z1, y1); + r1 = _mm_srli_epi32(r1, 19); + z1 = _mm_xor_si128(z1, r1); + + y0 = z8; + y0 = _mm_add_epi32(y0, z12); + r0 = y0; + y0 = _mm_slli_epi32(y0, 18); + z0 = _mm_xor_si128(z0, y0); + r0 = _mm_srli_epi32(r0, 14); + z0 = _mm_xor_si128(z0, r0); + + y5 = z13; + y5 = _mm_add_epi32(y5, z1); + r5 = y5; + y5 = _mm_slli_epi32(y5, 18); + z5 = _mm_xor_si128(z5, y5); + r5 = _mm_srli_epi32(r5, 14); + z5 = _mm_xor_si128(z5, r5); + + y14 = z6; + y14 = _mm_add_epi32(y14, z10); + r14 = y14; + y14 = _mm_slli_epi32(y14, 7); + z14 = _mm_xor_si128(z14, y14); + r14 = _mm_srli_epi32(r14, 25); + z14 = _mm_xor_si128(z14, r14); + + y3 = z11; + y3 = _mm_add_epi32(y3, z15); + r3 = y3; + y3 = _mm_slli_epi32(y3, 7); + z3 = _mm_xor_si128(z3, y3); + r3 = _mm_srli_epi32(r3, 25); + z3 = _mm_xor_si128(z3, r3); + + y2 = z10; + y2 = _mm_add_epi32(y2, z14); + r2 = y2; + y2 = _mm_slli_epi32(y2, 9); + z2 = _mm_xor_si128(z2, y2); + r2 = _mm_srli_epi32(r2, 23); + z2 = _mm_xor_si128(z2, r2); + + y7 = z15; + y7 = _mm_add_epi32(y7, z3); + r7 = y7; + y7 = _mm_slli_epi32(y7, 9); + z7 = _mm_xor_si128(z7, y7); + r7 = _mm_srli_epi32(r7, 23); + z7 = _mm_xor_si128(z7, r7); + + y6 = z14; + y6 = _mm_add_epi32(y6, z2); + r6 = y6; + y6 = _mm_slli_epi32(y6, 13); + z6 = _mm_xor_si128(z6, y6); + r6 = _mm_srli_epi32(r6, 19); + z6 = _mm_xor_si128(z6, r6); + + y11 = z3; + y11 = _mm_add_epi32(y11, z7); + r11 = y11; + y11 = _mm_slli_epi32(y11, 13); + z11 = _mm_xor_si128(z11, y11); + r11 = _mm_srli_epi32(r11, 19); + z11 = _mm_xor_si128(z11, r11); + + y10 = z2; + y10 = _mm_add_epi32(y10, z6); + r10 = y10; + y10 = _mm_slli_epi32(y10, 18); + z10 = _mm_xor_si128(z10, y10); + r10 = _mm_srli_epi32(r10, 14); + z10 = _mm_xor_si128(z10, r10); + + y1 = z3; + y1 = _mm_add_epi32(y1, z0); + r1 = y1; + y1 = _mm_slli_epi32(y1, 7); + z1 = _mm_xor_si128(z1, y1); + r1 = _mm_srli_epi32(r1, 25); + z1 = _mm_xor_si128(z1, r1); + + y15 = z7; + y15 = _mm_add_epi32(y15, z11); + r15 = y15; + y15 = _mm_slli_epi32(y15, 18); + z15 = _mm_xor_si128(z15, y15); + r15 = _mm_srli_epi32(r15, 14); + z15 = _mm_xor_si128(z15, r15); + + y6 = z4; + y6 = _mm_add_epi32(y6, z5); + r6 = y6; + y6 = _mm_slli_epi32(y6, 7); + z6 = _mm_xor_si128(z6, y6); + r6 = _mm_srli_epi32(r6, 25); + z6 = _mm_xor_si128(z6, r6); + + y2 = z0; + y2 = _mm_add_epi32(y2, z1); + r2 = y2; + y2 = _mm_slli_epi32(y2, 9); + z2 = _mm_xor_si128(z2, y2); + r2 = _mm_srli_epi32(r2, 23); + z2 = _mm_xor_si128(z2, r2); + + y7 = z5; + y7 = _mm_add_epi32(y7, z6); + r7 = y7; + y7 = _mm_slli_epi32(y7, 9); + z7 = _mm_xor_si128(z7, y7); + r7 = _mm_srli_epi32(r7, 23); + z7 = _mm_xor_si128(z7, r7); + + y3 = z1; + y3 = _mm_add_epi32(y3, z2); + r3 = y3; + y3 = _mm_slli_epi32(y3, 13); + z3 = _mm_xor_si128(z3, y3); + r3 = _mm_srli_epi32(r3, 19); + z3 = _mm_xor_si128(z3, r3); + + y4 = z6; + y4 = _mm_add_epi32(y4, z7); + r4 = y4; + y4 = _mm_slli_epi32(y4, 13); + z4 = _mm_xor_si128(z4, y4); + r4 = _mm_srli_epi32(r4, 19); + z4 = _mm_xor_si128(z4, r4); + + y0 = z2; + y0 = _mm_add_epi32(y0, z3); + r0 = y0; + y0 = _mm_slli_epi32(y0, 18); + z0 = _mm_xor_si128(z0, y0); + r0 = _mm_srli_epi32(r0, 14); + z0 = _mm_xor_si128(z0, r0); + + y5 = z7; + y5 = _mm_add_epi32(y5, z4); + r5 = y5; + y5 = _mm_slli_epi32(y5, 18); + z5 = _mm_xor_si128(z5, y5); + r5 = _mm_srli_epi32(r5, 14); + z5 = _mm_xor_si128(z5, r5); + + y11 = z9; + y11 = _mm_add_epi32(y11, z10); + r11 = y11; + y11 = _mm_slli_epi32(y11, 7); + z11 = _mm_xor_si128(z11, y11); + r11 = _mm_srli_epi32(r11, 25); + z11 = _mm_xor_si128(z11, r11); + + y12 = z14; + y12 = _mm_add_epi32(y12, z15); + r12 = y12; + y12 = _mm_slli_epi32(y12, 7); + z12 = _mm_xor_si128(z12, y12); + r12 = _mm_srli_epi32(r12, 25); + z12 = _mm_xor_si128(z12, r12); + + y8 = z10; + y8 = _mm_add_epi32(y8, z11); + r8 = y8; + y8 = _mm_slli_epi32(y8, 9); + z8 = _mm_xor_si128(z8, y8); + r8 = _mm_srli_epi32(r8, 23); + z8 = _mm_xor_si128(z8, r8); + + y13 = z15; + y13 = _mm_add_epi32(y13, z12); + r13 = y13; + y13 = _mm_slli_epi32(y13, 9); + z13 = _mm_xor_si128(z13, y13); + r13 = _mm_srli_epi32(r13, 23); + z13 = _mm_xor_si128(z13, r13); + + y9 = z11; + y9 = _mm_add_epi32(y9, z8); + r9 = y9; + y9 = _mm_slli_epi32(y9, 13); + z9 = _mm_xor_si128(z9, y9); + r9 = _mm_srli_epi32(r9, 19); + z9 = _mm_xor_si128(z9, r9); + + y14 = z12; + y14 = _mm_add_epi32(y14, z13); + r14 = y14; + y14 = _mm_slli_epi32(y14, 13); + z14 = _mm_xor_si128(z14, y14); + r14 = _mm_srli_epi32(r14, 19); + z14 = _mm_xor_si128(z14, r14); + + y10 = z8; + y10 = _mm_add_epi32(y10, z9); + r10 = y10; + y10 = _mm_slli_epi32(y10, 18); + z10 = _mm_xor_si128(z10, y10); + r10 = _mm_srli_epi32(r10, 14); + z10 = _mm_xor_si128(z10, r10); + + y15 = z13; + y15 = _mm_add_epi32(y15, z14); + r15 = y15; + y15 = _mm_slli_epi32(y15, 18); + z15 = _mm_xor_si128(z15, y15); + r15 = _mm_srli_epi32(r15, 14); + z15 = _mm_xor_si128(z15, r15); + } + +/* store data ; this macro replicates the original amd64-xmm6 code */ +#define ONEQUAD_SHUFFLE(A, B, C, D) \ + z##A = _mm_add_epi32(z##A, orig##A); \ + z##B = _mm_add_epi32(z##B, orig##B); \ + z##C = _mm_add_epi32(z##C, orig##C); \ + z##D = _mm_add_epi32(z##D, orig##D); \ + in##A = _mm_cvtsi128_si32(z##A); \ + in##B = _mm_cvtsi128_si32(z##B); \ + in##C = _mm_cvtsi128_si32(z##C); \ + in##D = _mm_cvtsi128_si32(z##D); \ + z##A = _mm_shuffle_epi32(z##A, 0x39); \ + z##B = _mm_shuffle_epi32(z##B, 0x39); \ + z##C = _mm_shuffle_epi32(z##C, 0x39); \ + z##D = _mm_shuffle_epi32(z##D, 0x39); \ + \ + in##A ^= *(uint32_t *) (m + 0); \ + in##B ^= *(uint32_t *) (m + 4); \ + in##C ^= *(uint32_t *) (m + 8); \ + in##D ^= *(uint32_t *) (m + 12); \ + \ + *(uint32_t *) (c + 0) = in##A; \ + *(uint32_t *) (c + 4) = in##B; \ + *(uint32_t *) (c + 8) = in##C; \ + *(uint32_t *) (c + 12) = in##D; \ + \ + in##A = _mm_cvtsi128_si32(z##A); \ + in##B = _mm_cvtsi128_si32(z##B); \ + in##C = _mm_cvtsi128_si32(z##C); \ + in##D = _mm_cvtsi128_si32(z##D); \ + z##A = _mm_shuffle_epi32(z##A, 0x39); \ + z##B = _mm_shuffle_epi32(z##B, 0x39); \ + z##C = _mm_shuffle_epi32(z##C, 0x39); \ + z##D = _mm_shuffle_epi32(z##D, 0x39); \ + \ + in##A ^= *(uint32_t *) (m + 64); \ + in##B ^= *(uint32_t *) (m + 68); \ + in##C ^= *(uint32_t *) (m + 72); \ + in##D ^= *(uint32_t *) (m + 76); \ + *(uint32_t *) (c + 64) = in##A; \ + *(uint32_t *) (c + 68) = in##B; \ + *(uint32_t *) (c + 72) = in##C; \ + *(uint32_t *) (c + 76) = in##D; \ + \ + in##A = _mm_cvtsi128_si32(z##A); \ + in##B = _mm_cvtsi128_si32(z##B); \ + in##C = _mm_cvtsi128_si32(z##C); \ + in##D = _mm_cvtsi128_si32(z##D); \ + z##A = _mm_shuffle_epi32(z##A, 0x39); \ + z##B = _mm_shuffle_epi32(z##B, 0x39); \ + z##C = _mm_shuffle_epi32(z##C, 0x39); \ + z##D = _mm_shuffle_epi32(z##D, 0x39); \ + \ + in##A ^= *(uint32_t *) (m + 128); \ + in##B ^= *(uint32_t *) (m + 132); \ + in##C ^= *(uint32_t *) (m + 136); \ + in##D ^= *(uint32_t *) (m + 140); \ + *(uint32_t *) (c + 128) = in##A; \ + *(uint32_t *) (c + 132) = in##B; \ + *(uint32_t *) (c + 136) = in##C; \ + *(uint32_t *) (c + 140) = in##D; \ + \ + in##A = _mm_cvtsi128_si32(z##A); \ + in##B = _mm_cvtsi128_si32(z##B); \ + in##C = _mm_cvtsi128_si32(z##C); \ + in##D = _mm_cvtsi128_si32(z##D); \ + \ + in##A ^= *(uint32_t *) (m + 192); \ + in##B ^= *(uint32_t *) (m + 196); \ + in##C ^= *(uint32_t *) (m + 200); \ + in##D ^= *(uint32_t *) (m + 204); \ + *(uint32_t *) (c + 192) = in##A; \ + *(uint32_t *) (c + 196) = in##B; \ + *(uint32_t *) (c + 200) = in##C; \ + *(uint32_t *) (c + 204) = in##D + +/* store data ; this macro replaces shuffle+mov by a direct extract; not much + * difference */ +#define ONEQUAD_EXTRACT(A, B, C, D) \ + z##A = _mm_add_epi32(z##A, orig##A); \ + z##B = _mm_add_epi32(z##B, orig##B); \ + z##C = _mm_add_epi32(z##C, orig##C); \ + z##D = _mm_add_epi32(z##D, orig##D); \ + in##A = _mm_cvtsi128_si32(z##A); \ + in##B = _mm_cvtsi128_si32(z##B); \ + in##C = _mm_cvtsi128_si32(z##C); \ + in##D = _mm_cvtsi128_si32(z##D); \ + in##A ^= *(uint32_t *) (m + 0); \ + in##B ^= *(uint32_t *) (m + 4); \ + in##C ^= *(uint32_t *) (m + 8); \ + in##D ^= *(uint32_t *) (m + 12); \ + *(uint32_t *) (c + 0) = in##A; \ + *(uint32_t *) (c + 4) = in##B; \ + *(uint32_t *) (c + 8) = in##C; \ + *(uint32_t *) (c + 12) = in##D; \ + \ + in##A = _mm_extract_epi32(z##A, 1); \ + in##B = _mm_extract_epi32(z##B, 1); \ + in##C = _mm_extract_epi32(z##C, 1); \ + in##D = _mm_extract_epi32(z##D, 1); \ + \ + in##A ^= *(uint32_t *) (m + 64); \ + in##B ^= *(uint32_t *) (m + 68); \ + in##C ^= *(uint32_t *) (m + 72); \ + in##D ^= *(uint32_t *) (m + 76); \ + *(uint32_t *) (c + 64) = in##A; \ + *(uint32_t *) (c + 68) = in##B; \ + *(uint32_t *) (c + 72) = in##C; \ + *(uint32_t *) (c + 76) = in##D; \ + \ + in##A = _mm_extract_epi32(z##A, 2); \ + in##B = _mm_extract_epi32(z##B, 2); \ + in##C = _mm_extract_epi32(z##C, 2); \ + in##D = _mm_extract_epi32(z##D, 2); \ + \ + in##A ^= *(uint32_t *) (m + 128); \ + in##B ^= *(uint32_t *) (m + 132); \ + in##C ^= *(uint32_t *) (m + 136); \ + in##D ^= *(uint32_t *) (m + 140); \ + *(uint32_t *) (c + 128) = in##A; \ + *(uint32_t *) (c + 132) = in##B; \ + *(uint32_t *) (c + 136) = in##C; \ + *(uint32_t *) (c + 140) = in##D; \ + \ + in##A = _mm_extract_epi32(z##A, 3); \ + in##B = _mm_extract_epi32(z##B, 3); \ + in##C = _mm_extract_epi32(z##C, 3); \ + in##D = _mm_extract_epi32(z##D, 3); \ + \ + in##A ^= *(uint32_t *) (m + 192); \ + in##B ^= *(uint32_t *) (m + 196); \ + in##C ^= *(uint32_t *) (m + 200); \ + in##D ^= *(uint32_t *) (m + 204); \ + *(uint32_t *) (c + 192) = in##A; \ + *(uint32_t *) (c + 196) = in##B; \ + *(uint32_t *) (c + 200) = in##C; \ + *(uint32_t *) (c + 204) = in##D + +/* store data ; this macro first transpose data in-registers, and then store + * them in memory. much faster with icc. */ +#define ONEQUAD_TRANSPOSE(A, B, C, D) \ + z##A = _mm_add_epi32(z##A, orig##A); \ + z##B = _mm_add_epi32(z##B, orig##B); \ + z##C = _mm_add_epi32(z##C, orig##C); \ + z##D = _mm_add_epi32(z##D, orig##D); \ + y##A = _mm_unpacklo_epi32(z##A, z##B); \ + y##B = _mm_unpacklo_epi32(z##C, z##D); \ + y##C = _mm_unpackhi_epi32(z##A, z##B); \ + y##D = _mm_unpackhi_epi32(z##C, z##D); \ + z##A = _mm_unpacklo_epi64(y##A, y##B); \ + z##B = _mm_unpackhi_epi64(y##A, y##B); \ + z##C = _mm_unpacklo_epi64(y##C, y##D); \ + z##D = _mm_unpackhi_epi64(y##C, y##D); \ + y##A = _mm_xor_si128(z##A, _mm_loadu_si128((const __m128i *) (m + 0))); \ + _mm_storeu_si128((__m128i *) (c + 0), y##A); \ + y##B = _mm_xor_si128(z##B, _mm_loadu_si128((const __m128i *) (m + 64))); \ + _mm_storeu_si128((__m128i *) (c + 64), y##B); \ + y##C = _mm_xor_si128(z##C, _mm_loadu_si128((const __m128i *) (m + 128))); \ + _mm_storeu_si128((__m128i *) (c + 128), y##C); \ + y##D = _mm_xor_si128(z##D, _mm_loadu_si128((const __m128i *) (m + 192))); \ + _mm_storeu_si128((__m128i *) (c + 192), y##D) + +#define ONEQUAD(A, B, C, D) ONEQUAD_TRANSPOSE(A, B, C, D) + + ONEQUAD(0, 1, 2, 3); + m += 16; + c += 16; + ONEQUAD(4, 5, 6, 7); + m += 16; + c += 16; + ONEQUAD(8, 9, 10, 11); + m += 16; + c += 16; + ONEQUAD(12, 13, 14, 15); + m -= 48; + c -= 48; + +#undef ONEQUAD +#undef ONEQUAD_TRANSPOSE +#undef ONEQUAD_EXTRACT +#undef ONEQUAD_SHUFFLE + + bytes -= 256; + c += 256; + m += 256; + } +} diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/u8.h b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/u8.h new file mode 100644 index 0000000..581b22c --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa20/xmm6int/u8.h @@ -0,0 +1,477 @@ +if (bytes >= 512) { + __m256i y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, y10, y11, y12, y13, y14, + y15; + + /* the naive way seems as fast (if not a bit faster) than the vector way */ + __m256i z0 = _mm256_set1_epi32(x[0]); + __m256i z5 = _mm256_set1_epi32(x[1]); + __m256i z10 = _mm256_set1_epi32(x[2]); + __m256i z15 = _mm256_set1_epi32(x[3]); + __m256i z12 = _mm256_set1_epi32(x[4]); + __m256i z1 = _mm256_set1_epi32(x[5]); + __m256i z6 = _mm256_set1_epi32(x[6]); + __m256i z11 = _mm256_set1_epi32(x[7]); + __m256i z8; /* useless */ + __m256i z13 = _mm256_set1_epi32(x[9]); + __m256i z2 = _mm256_set1_epi32(x[10]); + __m256i z7 = _mm256_set1_epi32(x[11]); + __m256i z4 = _mm256_set1_epi32(x[12]); + __m256i z9; /* useless */ + __m256i z14 = _mm256_set1_epi32(x[14]); + __m256i z3 = _mm256_set1_epi32(x[15]); + + __m256i orig0 = z0; + __m256i orig1 = z1; + __m256i orig2 = z2; + __m256i orig3 = z3; + __m256i orig4 = z4; + __m256i orig5 = z5; + __m256i orig6 = z6; + __m256i orig7 = z7; + __m256i orig8; + __m256i orig9; + __m256i orig10 = z10; + __m256i orig11 = z11; + __m256i orig12 = z12; + __m256i orig13 = z13; + __m256i orig14 = z14; + __m256i orig15 = z15; + + uint32_t in8; + uint32_t in9; + int i; + + while (bytes >= 512) { + /* vector implementation for z8 and z9 */ + /* faster than the naive version for 8 blocks */ + const __m256i addv8 = _mm256_set_epi64x(3, 2, 1, 0); + const __m256i addv9 = _mm256_set_epi64x(7, 6, 5, 4); + const __m256i permute = _mm256_set_epi32(7, 6, 3, 2, 5, 4, 1, 0); + + __m256i t8, t9; + uint64_t in89; + + in8 = x[8]; + in9 = x[13]; /* see arrays above for the address translation */ + in89 = ((uint64_t) in8) | (((uint64_t) in9) << 32); + + z8 = z9 = _mm256_broadcastq_epi64(_mm_cvtsi64_si128(in89)); + + t8 = _mm256_add_epi64(addv8, z8); + t9 = _mm256_add_epi64(addv9, z9); + + z8 = _mm256_unpacklo_epi32(t8, t9); + z9 = _mm256_unpackhi_epi32(t8, t9); + + t8 = _mm256_unpacklo_epi32(z8, z9); + t9 = _mm256_unpackhi_epi32(z8, z9); + + /* required because unpack* are intra-lane */ + z8 = _mm256_permutevar8x32_epi32(t8, permute); + z9 = _mm256_permutevar8x32_epi32(t9, permute); + + orig8 = z8; + orig9 = z9; + + in89 += 8; + + x[8] = in89 & 0xFFFFFFFF; + x[13] = (in89 >> 32) & 0xFFFFFFFF; + + z5 = orig5; + z10 = orig10; + z15 = orig15; + z14 = orig14; + z3 = orig3; + z6 = orig6; + z11 = orig11; + z1 = orig1; + + z7 = orig7; + z13 = orig13; + z2 = orig2; + z9 = orig9; + z0 = orig0; + z12 = orig12; + z4 = orig4; + z8 = orig8; + + for (i = 0; i < ROUNDS; i += 2) { + /* the inner loop is a direct translation (regexp search/replace) + * from the amd64-xmm6 ASM */ + __m256i r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, + r14, r15; + + y4 = z12; + y4 = _mm256_add_epi32(y4, z0); + r4 = y4; + y4 = _mm256_slli_epi32(y4, 7); + z4 = _mm256_xor_si256(z4, y4); + r4 = _mm256_srli_epi32(r4, 25); + z4 = _mm256_xor_si256(z4, r4); + + y9 = z1; + y9 = _mm256_add_epi32(y9, z5); + r9 = y9; + y9 = _mm256_slli_epi32(y9, 7); + z9 = _mm256_xor_si256(z9, y9); + r9 = _mm256_srli_epi32(r9, 25); + z9 = _mm256_xor_si256(z9, r9); + + y8 = z0; + y8 = _mm256_add_epi32(y8, z4); + r8 = y8; + y8 = _mm256_slli_epi32(y8, 9); + z8 = _mm256_xor_si256(z8, y8); + r8 = _mm256_srli_epi32(r8, 23); + z8 = _mm256_xor_si256(z8, r8); + + y13 = z5; + y13 = _mm256_add_epi32(y13, z9); + r13 = y13; + y13 = _mm256_slli_epi32(y13, 9); + z13 = _mm256_xor_si256(z13, y13); + r13 = _mm256_srli_epi32(r13, 23); + z13 = _mm256_xor_si256(z13, r13); + + y12 = z4; + y12 = _mm256_add_epi32(y12, z8); + r12 = y12; + y12 = _mm256_slli_epi32(y12, 13); + z12 = _mm256_xor_si256(z12, y12); + r12 = _mm256_srli_epi32(r12, 19); + z12 = _mm256_xor_si256(z12, r12); + + y1 = z9; + y1 = _mm256_add_epi32(y1, z13); + r1 = y1; + y1 = _mm256_slli_epi32(y1, 13); + z1 = _mm256_xor_si256(z1, y1); + r1 = _mm256_srli_epi32(r1, 19); + z1 = _mm256_xor_si256(z1, r1); + + y0 = z8; + y0 = _mm256_add_epi32(y0, z12); + r0 = y0; + y0 = _mm256_slli_epi32(y0, 18); + z0 = _mm256_xor_si256(z0, y0); + r0 = _mm256_srli_epi32(r0, 14); + z0 = _mm256_xor_si256(z0, r0); + + y5 = z13; + y5 = _mm256_add_epi32(y5, z1); + r5 = y5; + y5 = _mm256_slli_epi32(y5, 18); + z5 = _mm256_xor_si256(z5, y5); + r5 = _mm256_srli_epi32(r5, 14); + z5 = _mm256_xor_si256(z5, r5); + + y14 = z6; + y14 = _mm256_add_epi32(y14, z10); + r14 = y14; + y14 = _mm256_slli_epi32(y14, 7); + z14 = _mm256_xor_si256(z14, y14); + r14 = _mm256_srli_epi32(r14, 25); + z14 = _mm256_xor_si256(z14, r14); + + y3 = z11; + y3 = _mm256_add_epi32(y3, z15); + r3 = y3; + y3 = _mm256_slli_epi32(y3, 7); + z3 = _mm256_xor_si256(z3, y3); + r3 = _mm256_srli_epi32(r3, 25); + z3 = _mm256_xor_si256(z3, r3); + + y2 = z10; + y2 = _mm256_add_epi32(y2, z14); + r2 = y2; + y2 = _mm256_slli_epi32(y2, 9); + z2 = _mm256_xor_si256(z2, y2); + r2 = _mm256_srli_epi32(r2, 23); + z2 = _mm256_xor_si256(z2, r2); + + y7 = z15; + y7 = _mm256_add_epi32(y7, z3); + r7 = y7; + y7 = _mm256_slli_epi32(y7, 9); + z7 = _mm256_xor_si256(z7, y7); + r7 = _mm256_srli_epi32(r7, 23); + z7 = _mm256_xor_si256(z7, r7); + + y6 = z14; + y6 = _mm256_add_epi32(y6, z2); + r6 = y6; + y6 = _mm256_slli_epi32(y6, 13); + z6 = _mm256_xor_si256(z6, y6); + r6 = _mm256_srli_epi32(r6, 19); + z6 = _mm256_xor_si256(z6, r6); + + y11 = z3; + y11 = _mm256_add_epi32(y11, z7); + r11 = y11; + y11 = _mm256_slli_epi32(y11, 13); + z11 = _mm256_xor_si256(z11, y11); + r11 = _mm256_srli_epi32(r11, 19); + z11 = _mm256_xor_si256(z11, r11); + + y10 = z2; + y10 = _mm256_add_epi32(y10, z6); + r10 = y10; + y10 = _mm256_slli_epi32(y10, 18); + z10 = _mm256_xor_si256(z10, y10); + r10 = _mm256_srli_epi32(r10, 14); + z10 = _mm256_xor_si256(z10, r10); + + y1 = z3; + y1 = _mm256_add_epi32(y1, z0); + r1 = y1; + y1 = _mm256_slli_epi32(y1, 7); + z1 = _mm256_xor_si256(z1, y1); + r1 = _mm256_srli_epi32(r1, 25); + z1 = _mm256_xor_si256(z1, r1); + + y15 = z7; + y15 = _mm256_add_epi32(y15, z11); + r15 = y15; + y15 = _mm256_slli_epi32(y15, 18); + z15 = _mm256_xor_si256(z15, y15); + r15 = _mm256_srli_epi32(r15, 14); + z15 = _mm256_xor_si256(z15, r15); + + y6 = z4; + y6 = _mm256_add_epi32(y6, z5); + r6 = y6; + y6 = _mm256_slli_epi32(y6, 7); + z6 = _mm256_xor_si256(z6, y6); + r6 = _mm256_srli_epi32(r6, 25); + z6 = _mm256_xor_si256(z6, r6); + + y2 = z0; + y2 = _mm256_add_epi32(y2, z1); + r2 = y2; + y2 = _mm256_slli_epi32(y2, 9); + z2 = _mm256_xor_si256(z2, y2); + r2 = _mm256_srli_epi32(r2, 23); + z2 = _mm256_xor_si256(z2, r2); + + y7 = z5; + y7 = _mm256_add_epi32(y7, z6); + r7 = y7; + y7 = _mm256_slli_epi32(y7, 9); + z7 = _mm256_xor_si256(z7, y7); + r7 = _mm256_srli_epi32(r7, 23); + z7 = _mm256_xor_si256(z7, r7); + + y3 = z1; + y3 = _mm256_add_epi32(y3, z2); + r3 = y3; + y3 = _mm256_slli_epi32(y3, 13); + z3 = _mm256_xor_si256(z3, y3); + r3 = _mm256_srli_epi32(r3, 19); + z3 = _mm256_xor_si256(z3, r3); + + y4 = z6; + y4 = _mm256_add_epi32(y4, z7); + r4 = y4; + y4 = _mm256_slli_epi32(y4, 13); + z4 = _mm256_xor_si256(z4, y4); + r4 = _mm256_srli_epi32(r4, 19); + z4 = _mm256_xor_si256(z4, r4); + + y0 = z2; + y0 = _mm256_add_epi32(y0, z3); + r0 = y0; + y0 = _mm256_slli_epi32(y0, 18); + z0 = _mm256_xor_si256(z0, y0); + r0 = _mm256_srli_epi32(r0, 14); + z0 = _mm256_xor_si256(z0, r0); + + y5 = z7; + y5 = _mm256_add_epi32(y5, z4); + r5 = y5; + y5 = _mm256_slli_epi32(y5, 18); + z5 = _mm256_xor_si256(z5, y5); + r5 = _mm256_srli_epi32(r5, 14); + z5 = _mm256_xor_si256(z5, r5); + + y11 = z9; + y11 = _mm256_add_epi32(y11, z10); + r11 = y11; + y11 = _mm256_slli_epi32(y11, 7); + z11 = _mm256_xor_si256(z11, y11); + r11 = _mm256_srli_epi32(r11, 25); + z11 = _mm256_xor_si256(z11, r11); + + y12 = z14; + y12 = _mm256_add_epi32(y12, z15); + r12 = y12; + y12 = _mm256_slli_epi32(y12, 7); + z12 = _mm256_xor_si256(z12, y12); + r12 = _mm256_srli_epi32(r12, 25); + z12 = _mm256_xor_si256(z12, r12); + + y8 = z10; + y8 = _mm256_add_epi32(y8, z11); + r8 = y8; + y8 = _mm256_slli_epi32(y8, 9); + z8 = _mm256_xor_si256(z8, y8); + r8 = _mm256_srli_epi32(r8, 23); + z8 = _mm256_xor_si256(z8, r8); + + y13 = z15; + y13 = _mm256_add_epi32(y13, z12); + r13 = y13; + y13 = _mm256_slli_epi32(y13, 9); + z13 = _mm256_xor_si256(z13, y13); + r13 = _mm256_srli_epi32(r13, 23); + z13 = _mm256_xor_si256(z13, r13); + + y9 = z11; + y9 = _mm256_add_epi32(y9, z8); + r9 = y9; + y9 = _mm256_slli_epi32(y9, 13); + z9 = _mm256_xor_si256(z9, y9); + r9 = _mm256_srli_epi32(r9, 19); + z9 = _mm256_xor_si256(z9, r9); + + y14 = z12; + y14 = _mm256_add_epi32(y14, z13); + r14 = y14; + y14 = _mm256_slli_epi32(y14, 13); + z14 = _mm256_xor_si256(z14, y14); + r14 = _mm256_srli_epi32(r14, 19); + z14 = _mm256_xor_si256(z14, r14); + + y10 = z8; + y10 = _mm256_add_epi32(y10, z9); + r10 = y10; + y10 = _mm256_slli_epi32(y10, 18); + z10 = _mm256_xor_si256(z10, y10); + r10 = _mm256_srli_epi32(r10, 14); + z10 = _mm256_xor_si256(z10, r10); + + y15 = z13; + y15 = _mm256_add_epi32(y15, z14); + r15 = y15; + y15 = _mm256_slli_epi32(y15, 18); + z15 = _mm256_xor_si256(z15, y15); + r15 = _mm256_srli_epi32(r15, 14); + z15 = _mm256_xor_si256(z15, r15); + } + +/* store data ; this macro first transpose data in-registers, and then store + * them in memory. much faster with icc. */ +#define ONEQUAD_TRANSPOSE(A, B, C, D) \ + { \ + __m128i t0, t1, t2, t3; \ + z##A = _mm256_add_epi32(z##A, orig##A); \ + z##B = _mm256_add_epi32(z##B, orig##B); \ + z##C = _mm256_add_epi32(z##C, orig##C); \ + z##D = _mm256_add_epi32(z##D, orig##D); \ + y##A = _mm256_unpacklo_epi32(z##A, z##B); \ + y##B = _mm256_unpacklo_epi32(z##C, z##D); \ + y##C = _mm256_unpackhi_epi32(z##A, z##B); \ + y##D = _mm256_unpackhi_epi32(z##C, z##D); \ + z##A = _mm256_unpacklo_epi64(y##A, y##B); \ + z##B = _mm256_unpackhi_epi64(y##A, y##B); \ + z##C = _mm256_unpacklo_epi64(y##C, y##D); \ + z##D = _mm256_unpackhi_epi64(y##C, y##D); \ + t0 = _mm_xor_si128(_mm256_extracti128_si256(z##A, 0), \ + _mm_loadu_si128((const __m128i*) (m + 0))); \ + _mm_storeu_si128((__m128i*) (c + 0), t0); \ + t1 = _mm_xor_si128(_mm256_extracti128_si256(z##B, 0), \ + _mm_loadu_si128((const __m128i*) (m + 64))); \ + _mm_storeu_si128((__m128i*) (c + 64), t1); \ + t2 = _mm_xor_si128(_mm256_extracti128_si256(z##C, 0), \ + _mm_loadu_si128((const __m128i*) (m + 128))); \ + _mm_storeu_si128((__m128i*) (c + 128), t2); \ + t3 = _mm_xor_si128(_mm256_extracti128_si256(z##D, 0), \ + _mm_loadu_si128((const __m128i*) (m + 192))); \ + _mm_storeu_si128((__m128i*) (c + 192), t3); \ + t0 = _mm_xor_si128(_mm256_extracti128_si256(z##A, 1), \ + _mm_loadu_si128((const __m128i*) (m + 256))); \ + _mm_storeu_si128((__m128i*) (c + 256), t0); \ + t1 = _mm_xor_si128(_mm256_extracti128_si256(z##B, 1), \ + _mm_loadu_si128((const __m128i*) (m + 320))); \ + _mm_storeu_si128((__m128i*) (c + 320), t1); \ + t2 = _mm_xor_si128(_mm256_extracti128_si256(z##C, 1), \ + _mm_loadu_si128((const __m128i*) (m + 384))); \ + _mm_storeu_si128((__m128i*) (c + 384), t2); \ + t3 = _mm_xor_si128(_mm256_extracti128_si256(z##D, 1), \ + _mm_loadu_si128((const __m128i*) (m + 448))); \ + _mm_storeu_si128((__m128i*) (c + 448), t3); \ + } + +#define ONEQUAD(A, B, C, D) ONEQUAD_TRANSPOSE(A, B, C, D) + +#define ONEQUAD_UNPCK(A, B, C, D) \ + { \ + z##A = _mm256_add_epi32(z##A, orig##A); \ + z##B = _mm256_add_epi32(z##B, orig##B); \ + z##C = _mm256_add_epi32(z##C, orig##C); \ + z##D = _mm256_add_epi32(z##D, orig##D); \ + y##A = _mm256_unpacklo_epi32(z##A, z##B); \ + y##B = _mm256_unpacklo_epi32(z##C, z##D); \ + y##C = _mm256_unpackhi_epi32(z##A, z##B); \ + y##D = _mm256_unpackhi_epi32(z##C, z##D); \ + z##A = _mm256_unpacklo_epi64(y##A, y##B); \ + z##B = _mm256_unpackhi_epi64(y##A, y##B); \ + z##C = _mm256_unpacklo_epi64(y##C, y##D); \ + z##D = _mm256_unpackhi_epi64(y##C, y##D); \ + } + +#define ONEOCTO(A, B, C, D, A2, B2, C2, D2) \ + { \ + ONEQUAD_UNPCK(A, B, C, D); \ + ONEQUAD_UNPCK(A2, B2, C2, D2); \ + y##A = _mm256_permute2x128_si256(z##A, z##A2, 0x20); \ + y##A2 = _mm256_permute2x128_si256(z##A, z##A2, 0x31); \ + y##B = _mm256_permute2x128_si256(z##B, z##B2, 0x20); \ + y##B2 = _mm256_permute2x128_si256(z##B, z##B2, 0x31); \ + y##C = _mm256_permute2x128_si256(z##C, z##C2, 0x20); \ + y##C2 = _mm256_permute2x128_si256(z##C, z##C2, 0x31); \ + y##D = _mm256_permute2x128_si256(z##D, z##D2, 0x20); \ + y##D2 = _mm256_permute2x128_si256(z##D, z##D2, 0x31); \ + y##A = _mm256_xor_si256(y##A, \ + _mm256_loadu_si256((const __m256i*) (m + 0))); \ + y##B = _mm256_xor_si256( \ + y##B, _mm256_loadu_si256((const __m256i*) (m + 64))); \ + y##C = _mm256_xor_si256( \ + y##C, _mm256_loadu_si256((const __m256i*) (m + 128))); \ + y##D = _mm256_xor_si256( \ + y##D, _mm256_loadu_si256((const __m256i*) (m + 192))); \ + y##A2 = _mm256_xor_si256( \ + y##A2, _mm256_loadu_si256((const __m256i*) (m + 256))); \ + y##B2 = _mm256_xor_si256( \ + y##B2, _mm256_loadu_si256((const __m256i*) (m + 320))); \ + y##C2 = _mm256_xor_si256( \ + y##C2, _mm256_loadu_si256((const __m256i*) (m + 384))); \ + y##D2 = _mm256_xor_si256( \ + y##D2, _mm256_loadu_si256((const __m256i*) (m + 448))); \ + _mm256_storeu_si256((__m256i*) (c + 0), y##A); \ + _mm256_storeu_si256((__m256i*) (c + 64), y##B); \ + _mm256_storeu_si256((__m256i*) (c + 128), y##C); \ + _mm256_storeu_si256((__m256i*) (c + 192), y##D); \ + _mm256_storeu_si256((__m256i*) (c + 256), y##A2); \ + _mm256_storeu_si256((__m256i*) (c + 320), y##B2); \ + _mm256_storeu_si256((__m256i*) (c + 384), y##C2); \ + _mm256_storeu_si256((__m256i*) (c + 448), y##D2); \ + } + + ONEOCTO(0, 1, 2, 3, 4, 5, 6, 7); + m += 32; + c += 32; + ONEOCTO(8, 9, 10, 11, 12, 13, 14, 15); + m -= 32; + c -= 32; + +#undef ONEQUAD +#undef ONEQUAD_TRANSPOSE +#undef ONEQUAD_UNPCK +#undef ONEOCTO + + bytes -= 512; + c += 512; + m += 512; + } +} diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa2012/ref/stream_salsa2012_ref.c b/external/src/libsodium/src/libsodium/crypto_stream/salsa2012/ref/stream_salsa2012_ref.c new file mode 100644 index 0000000..bfdfeed --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa2012/ref/stream_salsa2012_ref.c @@ -0,0 +1,106 @@ +/* +version 20140420 +D. J. Bernstein +Public domain. +*/ + +#include + +#include "crypto_core_salsa2012.h" +#include "crypto_stream_salsa2012.h" +#include "utils.h" + +int +crypto_stream_salsa2012(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + unsigned char in[16]; + unsigned char block[64]; + unsigned char kcopy[32]; + unsigned int i; + unsigned int u; + + if (!clen) { + return 0; + } + for (i = 0; i < 32; ++i) { + kcopy[i] = k[i]; + } + for (i = 0; i < 8; ++i) { + in[i] = n[i]; + } + for (i = 8; i < 16; ++i) { + in[i] = 0; + } + while (clen >= 64) { + crypto_core_salsa2012(c, in, kcopy, NULL); + u = 1; + for (i = 8; i < 16; ++i) { + u += (unsigned int)in[i]; + in[i] = u; + u >>= 8; + } + clen -= 64; + c += 64; + } + if (clen) { + crypto_core_salsa2012(block, in, kcopy, NULL); + for (i = 0; i < (unsigned int)clen; ++i) { + c[i] = block[i]; + } + } + sodium_memzero(block, sizeof block); + sodium_memzero(kcopy, sizeof kcopy); + + return 0; +} + +int +crypto_stream_salsa2012_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + unsigned char in[16]; + unsigned char block[64]; + unsigned char kcopy[32]; + unsigned int i; + unsigned int u; + + if (!mlen) { + return 0; + } + for (i = 0; i < 32; ++i) { + kcopy[i] = k[i]; + } + for (i = 0; i < 8; ++i) { + in[i] = n[i]; + } + for (i = 8; i < 16; ++i) { + in[i] = 0; + } + while (mlen >= 64) { + crypto_core_salsa2012(block, in, kcopy, NULL); + for (i = 0; i < 64; ++i) { + c[i] = m[i] ^ block[i]; + } + u = 1; + for (i = 8; i < 16; ++i) { + u += (unsigned int)in[i]; + in[i] = u; + u >>= 8; + } + mlen -= 64; + c += 64; + m += 64; + } + if (mlen) { + crypto_core_salsa2012(block, in, kcopy, NULL); + for (i = 0; i < (unsigned int)mlen; ++i) { + c[i] = m[i] ^ block[i]; + } + } + sodium_memzero(block, sizeof block); + sodium_memzero(kcopy, sizeof kcopy); + + return 0; +} diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa2012/stream_salsa2012.c b/external/src/libsodium/src/libsodium/crypto_stream/salsa2012/stream_salsa2012.c new file mode 100644 index 0000000..d0cc0f6 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa2012/stream_salsa2012.c @@ -0,0 +1,26 @@ +#include "crypto_stream_salsa2012.h" +#include "randombytes.h" + +size_t +crypto_stream_salsa2012_keybytes(void) +{ + return crypto_stream_salsa2012_KEYBYTES; +} + +size_t +crypto_stream_salsa2012_noncebytes(void) +{ + return crypto_stream_salsa2012_NONCEBYTES; +} + +size_t +crypto_stream_salsa2012_messagebytes_max(void) +{ + return crypto_stream_salsa2012_MESSAGEBYTES_MAX; +} + +void +crypto_stream_salsa2012_keygen(unsigned char k[crypto_stream_salsa2012_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_salsa2012_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa208/ref/stream_salsa208_ref.c b/external/src/libsodium/src/libsodium/crypto_stream/salsa208/ref/stream_salsa208_ref.c new file mode 100644 index 0000000..7ec0c4e --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa208/ref/stream_salsa208_ref.c @@ -0,0 +1,106 @@ +/* +version 20140420 +D. J. Bernstein +Public domain. +*/ + +#include + +#include "crypto_core_salsa208.h" +#include "crypto_stream_salsa208.h" +#include "utils.h" + +int +crypto_stream_salsa208(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + unsigned char in[16]; + unsigned char block[64]; + unsigned char kcopy[32]; + unsigned int i; + unsigned int u; + + if (!clen) { + return 0; + } + for (i = 0; i < 32; ++i) { + kcopy[i] = k[i]; + } + for (i = 0; i < 8; ++i) { + in[i] = n[i]; + } + for (i = 8; i < 16; ++i) { + in[i] = 0; + } + while (clen >= 64) { + crypto_core_salsa208(c, in, kcopy, NULL); + u = 1; + for (i = 8; i < 16; ++i) { + u += (unsigned int)in[i]; + in[i] = u; + u >>= 8; + } + clen -= 64; + c += 64; + } + if (clen) { + crypto_core_salsa208(block, in, kcopy, NULL); + for (i = 0; i < (unsigned int)clen; ++i) { + c[i] = block[i]; + } + } + sodium_memzero(block, sizeof block); + sodium_memzero(kcopy, sizeof kcopy); + + return 0; +} + +int +crypto_stream_salsa208_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + unsigned char in[16]; + unsigned char block[64]; + unsigned char kcopy[32]; + unsigned int i; + unsigned int u; + + if (!mlen) { + return 0; + } + for (i = 0; i < 32; ++i) { + kcopy[i] = k[i]; + } + for (i = 0; i < 8; ++i) { + in[i] = n[i]; + } + for (i = 8; i < 16; ++i) { + in[i] = 0; + } + while (mlen >= 64) { + crypto_core_salsa208(block, in, kcopy, NULL); + for (i = 0; i < 64; ++i) { + c[i] = m[i] ^ block[i]; + } + u = 1; + for (i = 8; i < 16; ++i) { + u += (unsigned int)in[i]; + in[i] = u; + u >>= 8; + } + mlen -= 64; + c += 64; + m += 64; + } + if (mlen) { + crypto_core_salsa208(block, in, kcopy, NULL); + for (i = 0; i < (unsigned int)mlen; ++i) { + c[i] = m[i] ^ block[i]; + } + } + sodium_memzero(block, sizeof block); + sodium_memzero(kcopy, sizeof kcopy); + + return 0; +} diff --git a/external/src/libsodium/src/libsodium/crypto_stream/salsa208/stream_salsa208.c b/external/src/libsodium/src/libsodium/crypto_stream/salsa208/stream_salsa208.c new file mode 100644 index 0000000..b79bda5 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/salsa208/stream_salsa208.c @@ -0,0 +1,26 @@ +#include "crypto_stream_salsa208.h" +#include "randombytes.h" + +size_t +crypto_stream_salsa208_keybytes(void) +{ + return crypto_stream_salsa208_KEYBYTES; +} + +size_t +crypto_stream_salsa208_noncebytes(void) +{ + return crypto_stream_salsa208_NONCEBYTES; +} + +size_t +crypto_stream_salsa208_messagebytes_max(void) +{ + return crypto_stream_salsa208_MESSAGEBYTES_MAX; +} + +void +crypto_stream_salsa208_keygen(unsigned char k[crypto_stream_salsa208_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_salsa208_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_stream/xchacha20/stream_xchacha20.c b/external/src/libsodium/src/libsodium/crypto_stream/xchacha20/stream_xchacha20.c new file mode 100644 index 0000000..8b1bc09 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/xchacha20/stream_xchacha20.c @@ -0,0 +1,69 @@ + +#include + +#include "crypto_core_hchacha20.h" +#include "crypto_stream_chacha20.h" +#include "crypto_stream_xchacha20.h" +#include "private/common.h" +#include "randombytes.h" + +size_t +crypto_stream_xchacha20_keybytes(void) +{ + return crypto_stream_xchacha20_KEYBYTES; +} + +size_t +crypto_stream_xchacha20_noncebytes(void) +{ + return crypto_stream_xchacha20_NONCEBYTES; +} + +size_t +crypto_stream_xchacha20_messagebytes_max(void) +{ + return crypto_stream_xchacha20_MESSAGEBYTES_MAX; +} + +int +crypto_stream_xchacha20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; + + crypto_core_hchacha20(k2, n, k, NULL); + COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES <= sizeof k2); + COMPILER_ASSERT(crypto_stream_chacha20_NONCEBYTES == + crypto_stream_xchacha20_NONCEBYTES - + crypto_core_hchacha20_INPUTBYTES); + + return crypto_stream_chacha20(c, clen, n + crypto_core_hchacha20_INPUTBYTES, + k2); +} + +int +crypto_stream_xchacha20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + uint64_t ic, const unsigned char *k) +{ + unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; + + crypto_core_hchacha20(k2, n, k, NULL); + return crypto_stream_chacha20_xor_ic( + c, m, mlen, n + crypto_core_hchacha20_INPUTBYTES, ic, k2); +} + +int +crypto_stream_xchacha20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + return crypto_stream_xchacha20_xor_ic(c, m, mlen, n, 0U, k); +} + +void +crypto_stream_xchacha20_keygen( + unsigned char k[crypto_stream_xchacha20_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_xchacha20_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_stream/xsalsa20/stream_xsalsa20.c b/external/src/libsodium/src/libsodium/crypto_stream/xsalsa20/stream_xsalsa20.c new file mode 100644 index 0000000..dc831a9 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_stream/xsalsa20/stream_xsalsa20.c @@ -0,0 +1,66 @@ +#include "crypto_core_hsalsa20.h" +#include "crypto_stream_salsa20.h" +#include "crypto_stream_xsalsa20.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_stream_xsalsa20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) +{ + unsigned char subkey[32]; + int ret; + + crypto_core_hsalsa20(subkey, n, k, NULL); + ret = crypto_stream_salsa20(c, clen, n + 16, subkey); + sodium_memzero(subkey, sizeof subkey); + + return ret; +} + +int +crypto_stream_xsalsa20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + uint64_t ic, const unsigned char *k) +{ + unsigned char subkey[32]; + int ret; + + crypto_core_hsalsa20(subkey, n, k, NULL); + ret = crypto_stream_salsa20_xor_ic(c, m, mlen, n + 16, ic, subkey); + sodium_memzero(subkey, sizeof subkey); + + return ret; +} + +int +crypto_stream_xsalsa20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) +{ + return crypto_stream_xsalsa20_xor_ic(c, m, mlen, n, 0ULL, k); +} + +size_t +crypto_stream_xsalsa20_keybytes(void) +{ + return crypto_stream_xsalsa20_KEYBYTES; +} + +size_t +crypto_stream_xsalsa20_noncebytes(void) +{ + return crypto_stream_xsalsa20_NONCEBYTES; +} + +size_t +crypto_stream_xsalsa20_messagebytes_max(void) +{ + return crypto_stream_xsalsa20_MESSAGEBYTES_MAX; +} + +void +crypto_stream_xsalsa20_keygen(unsigned char k[crypto_stream_xsalsa20_KEYBYTES]) +{ + randombytes_buf(k, crypto_stream_xsalsa20_KEYBYTES); +} diff --git a/external/src/libsodium/src/libsodium/crypto_verify/sodium/verify.c b/external/src/libsodium/src/libsodium/crypto_verify/sodium/verify.c new file mode 100644 index 0000000..ffebf22 --- /dev/null +++ b/external/src/libsodium/src/libsodium/crypto_verify/sodium/verify.c @@ -0,0 +1,98 @@ + +#include +#include + +#include "crypto_verify_16.h" +#include "crypto_verify_32.h" +#include "crypto_verify_64.h" + +size_t +crypto_verify_16_bytes(void) +{ + return crypto_verify_16_BYTES; +} + +size_t +crypto_verify_32_bytes(void) +{ + return crypto_verify_32_BYTES; +} + +size_t +crypto_verify_64_bytes(void) +{ + return crypto_verify_64_BYTES; +} + +#if defined(HAVE_EMMINTRIN_H) && defined(__SSE2__) + +# ifdef __GNUC__ +# pragma GCC target("sse2") +# endif +# include + +static inline int +crypto_verify_n(const unsigned char *x_, const unsigned char *y_, + const int n) +{ + const __m128i zero = _mm_setzero_si128(); + volatile __m128i v1, v2, z; + volatile int m; + int i; + + const volatile __m128i *volatile x = + (const volatile __m128i *volatile) (const void *) x_; + const volatile __m128i *volatile y = + (const volatile __m128i *volatile) (const void *) y_; + v1 = _mm_loadu_si128((const __m128i *) &x[0]); + v2 = _mm_loadu_si128((const __m128i *) &y[0]); + z = _mm_xor_si128(v1, v2); + for (i = 1; i < n / 16; i++) { + v1 = _mm_loadu_si128((const __m128i *) &x[i]); + v2 = _mm_loadu_si128((const __m128i *) &y[i]); + z = _mm_or_si128(z, _mm_xor_si128(v1, v2)); + } + m = _mm_movemask_epi8(_mm_cmpeq_epi32(z, zero)); + v1 = zero; v2 = zero; z = zero; + + return (int) (((uint32_t) m + 1U) >> 16) - 1; +} + +#else + +static inline int +crypto_verify_n(const unsigned char *x_, const unsigned char *y_, + const int n) +{ + const volatile unsigned char *volatile x = + (const volatile unsigned char *volatile) x_; + const volatile unsigned char *volatile y = + (const volatile unsigned char *volatile) y_; + volatile uint_fast16_t d = 0U; + int i; + + for (i = 0; i < n; i++) { + d |= x[i] ^ y[i]; + } + return (1 & ((d - 1) >> 8)) - 1; +} + +#endif + +int +crypto_verify_16(const unsigned char *x, const unsigned char *y) +{ + return crypto_verify_n(x, y, crypto_verify_16_BYTES); +} + +int +crypto_verify_32(const unsigned char *x, const unsigned char *y) +{ + return crypto_verify_n(x, y, crypto_verify_32_BYTES); +} + +int +crypto_verify_64(const unsigned char *x, const unsigned char *y) +{ + return crypto_verify_n(x, y, crypto_verify_64_BYTES); +} diff --git a/external/src/libsodium/src/libsodium/include/Makefile.am b/external/src/libsodium/src/libsodium/include/Makefile.am new file mode 100644 index 0000000..7476bd9 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/Makefile.am @@ -0,0 +1,72 @@ + +SODIUM_EXPORT = \ + sodium.h \ + sodium/core.h \ + sodium/crypto_aead_aes256gcm.h \ + sodium/crypto_aead_chacha20poly1305.h \ + sodium/crypto_aead_xchacha20poly1305.h \ + sodium/crypto_auth.h \ + sodium/crypto_auth_hmacsha256.h \ + sodium/crypto_auth_hmacsha512.h \ + sodium/crypto_auth_hmacsha512256.h \ + sodium/crypto_box.h \ + sodium/crypto_box_curve25519xchacha20poly1305.h \ + sodium/crypto_box_curve25519xsalsa20poly1305.h \ + sodium/crypto_core_ed25519.h \ + sodium/crypto_core_ristretto255.h \ + sodium/crypto_core_hchacha20.h \ + sodium/crypto_core_hsalsa20.h \ + sodium/crypto_core_salsa20.h \ + sodium/crypto_core_salsa2012.h \ + sodium/crypto_core_salsa208.h \ + sodium/crypto_generichash.h \ + sodium/crypto_generichash_blake2b.h \ + sodium/crypto_hash.h \ + sodium/crypto_hash_sha256.h \ + sodium/crypto_hash_sha512.h \ + sodium/crypto_kdf.h \ + sodium/crypto_kdf_blake2b.h \ + sodium/crypto_kx.h \ + sodium/crypto_onetimeauth.h \ + sodium/crypto_onetimeauth_poly1305.h \ + sodium/crypto_pwhash.h \ + sodium/crypto_pwhash_argon2i.h \ + sodium/crypto_pwhash_argon2id.h \ + sodium/crypto_pwhash_scryptsalsa208sha256.h \ + sodium/crypto_scalarmult.h \ + sodium/crypto_scalarmult_curve25519.h \ + sodium/crypto_scalarmult_ed25519.h \ + sodium/crypto_scalarmult_ristretto255.h \ + sodium/crypto_secretbox.h \ + sodium/crypto_secretbox_xchacha20poly1305.h \ + sodium/crypto_secretbox_xsalsa20poly1305.h \ + sodium/crypto_secretstream_xchacha20poly1305.h \ + sodium/crypto_shorthash.h \ + sodium/crypto_shorthash_siphash24.h \ + sodium/crypto_sign.h \ + sodium/crypto_sign_ed25519.h \ + sodium/crypto_sign_edwards25519sha512batch.h \ + sodium/crypto_stream.h \ + sodium/crypto_stream_chacha20.h \ + sodium/crypto_stream_salsa20.h \ + sodium/crypto_stream_salsa2012.h \ + sodium/crypto_stream_salsa208.h \ + sodium/crypto_stream_xchacha20.h \ + sodium/crypto_stream_xsalsa20.h \ + sodium/crypto_verify_16.h \ + sodium/crypto_verify_32.h \ + sodium/crypto_verify_64.h \ + sodium/export.h \ + sodium/randombytes.h \ + sodium/randombytes_internal_random.h \ + sodium/randombytes_sysrandom.h \ + sodium/runtime.h \ + sodium/utils.h + +EXTRA_SRC = $(SODIUM_EXPORT) \ + sodium/version.h.in + +nobase_include_HEADERS = $(SODIUM_EXPORT) + +nobase_nodist_include_HEADERS = \ + sodium/version.h diff --git a/external/src/libsodium/src/libsodium/include/sodium.h b/external/src/libsodium/src/libsodium/include/sodium.h new file mode 100644 index 0000000..295f911 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium.h @@ -0,0 +1,69 @@ + +#ifndef sodium_H +#define sodium_H + +#include "sodium/version.h" + +#include "sodium/core.h" +#include "sodium/crypto_aead_aes256gcm.h" +#include "sodium/crypto_aead_chacha20poly1305.h" +#include "sodium/crypto_aead_xchacha20poly1305.h" +#include "sodium/crypto_auth.h" +#include "sodium/crypto_auth_hmacsha256.h" +#include "sodium/crypto_auth_hmacsha512.h" +#include "sodium/crypto_auth_hmacsha512256.h" +#include "sodium/crypto_box.h" +#include "sodium/crypto_box_curve25519xsalsa20poly1305.h" +#include "sodium/crypto_core_hsalsa20.h" +#include "sodium/crypto_core_hchacha20.h" +#include "sodium/crypto_core_salsa20.h" +#include "sodium/crypto_core_salsa2012.h" +#include "sodium/crypto_core_salsa208.h" +#include "sodium/crypto_generichash.h" +#include "sodium/crypto_generichash_blake2b.h" +#include "sodium/crypto_hash.h" +#include "sodium/crypto_hash_sha256.h" +#include "sodium/crypto_hash_sha512.h" +#include "sodium/crypto_kdf.h" +#include "sodium/crypto_kdf_blake2b.h" +#include "sodium/crypto_kx.h" +#include "sodium/crypto_onetimeauth.h" +#include "sodium/crypto_onetimeauth_poly1305.h" +#include "sodium/crypto_pwhash.h" +#include "sodium/crypto_pwhash_argon2i.h" +#include "sodium/crypto_scalarmult.h" +#include "sodium/crypto_scalarmult_curve25519.h" +#include "sodium/crypto_secretbox.h" +#include "sodium/crypto_secretbox_xsalsa20poly1305.h" +#include "sodium/crypto_secretstream_xchacha20poly1305.h" +#include "sodium/crypto_shorthash.h" +#include "sodium/crypto_shorthash_siphash24.h" +#include "sodium/crypto_sign.h" +#include "sodium/crypto_sign_ed25519.h" +#include "sodium/crypto_stream.h" +#include "sodium/crypto_stream_chacha20.h" +#include "sodium/crypto_stream_salsa20.h" +#include "sodium/crypto_stream_xsalsa20.h" +#include "sodium/crypto_verify_16.h" +#include "sodium/crypto_verify_32.h" +#include "sodium/crypto_verify_64.h" +#include "sodium/randombytes.h" +#include "sodium/randombytes_internal_random.h" +#include "sodium/randombytes_sysrandom.h" +#include "sodium/runtime.h" +#include "sodium/utils.h" + +#ifndef SODIUM_LIBRARY_MINIMAL +# include "sodium/crypto_box_curve25519xchacha20poly1305.h" +# include "sodium/crypto_core_ed25519.h" +# include "sodium/crypto_core_ristretto255.h" +# include "sodium/crypto_scalarmult_ed25519.h" +# include "sodium/crypto_scalarmult_ristretto255.h" +# include "sodium/crypto_secretbox_xchacha20poly1305.h" +# include "sodium/crypto_pwhash_scryptsalsa208sha256.h" +# include "sodium/crypto_stream_salsa2012.h" +# include "sodium/crypto_stream_salsa208.h" +# include "sodium/crypto_stream_xchacha20.h" +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/core.h b/external/src/libsodium/src/libsodium/include/sodium/core.h new file mode 100644 index 0000000..dd088d2 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/core.h @@ -0,0 +1,28 @@ + +#ifndef sodium_core_H +#define sodium_core_H + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +int sodium_init(void) + __attribute__ ((warn_unused_result)); + +/* ---- */ + +SODIUM_EXPORT +int sodium_set_misuse_handler(void (*handler)(void)); + +SODIUM_EXPORT +void sodium_misuse(void) + __attribute__ ((noreturn)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_aead_aes256gcm.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_aead_aes256gcm.h new file mode 100644 index 0000000..9baeb3f --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_aead_aes256gcm.h @@ -0,0 +1,179 @@ +#ifndef crypto_aead_aes256gcm_H +#define crypto_aead_aes256gcm_H + +/* + * WARNING: Despite being the most popular AEAD construction due to its + * use in TLS, safely using AES-GCM in a different context is tricky. + * + * No more than ~ 350 GB of input data should be encrypted with a given key. + * This is for ~ 16 KB messages -- Actual figures vary according to + * message sizes. + * + * In addition, nonces are short and repeated nonces would totally destroy + * the security of this scheme. + * + * Nonces should thus come from atomic counters, which can be difficult to + * set up in a distributed environment. + * + * Unless you absolutely need AES-GCM, use crypto_aead_xchacha20poly1305_ietf_*() + * instead. It doesn't have any of these limitations. + * Or, if you don't need to authenticate additional data, just stick to + * crypto_secretbox(). + */ + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +SODIUM_EXPORT +int crypto_aead_aes256gcm_is_available(void); + +#define crypto_aead_aes256gcm_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_keybytes(void); + +#define crypto_aead_aes256gcm_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_nsecbytes(void); + +#define crypto_aead_aes256gcm_NPUBBYTES 12U +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_npubbytes(void); + +#define crypto_aead_aes256gcm_ABYTES 16U +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_abytes(void); + +#define crypto_aead_aes256gcm_MESSAGEBYTES_MAX \ + SODIUM_MIN(SODIUM_SIZE_MAX - crypto_aead_aes256gcm_ABYTES, \ + (16ULL * ((1ULL << 32) - 2ULL))) +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_messagebytes_max(void); + +typedef struct CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state_ { + unsigned char opaque[512]; +} crypto_aead_aes256gcm_state; + +SODIUM_EXPORT +size_t crypto_aead_aes256gcm_statebytes(void); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((nonnull(1, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(4, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((nonnull(1, 2, 9, 10))); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 5, 8, 9))); + +/* -- Precomputation interface -- */ + +SODIUM_EXPORT +int crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_, + const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) + __attribute__ ((nonnull(1, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(4, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) + __attribute__ ((nonnull(1, 2, 9, 10))); + +SODIUM_EXPORT +int crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *ctx_) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 5, 8, 9))); + +SODIUM_EXPORT +void crypto_aead_aes256gcm_keygen(unsigned char k[crypto_aead_aes256gcm_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_aead_chacha20poly1305.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_aead_chacha20poly1305.h new file mode 100644 index 0000000..5d671df --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_aead_chacha20poly1305.h @@ -0,0 +1,180 @@ +#ifndef crypto_aead_chacha20poly1305_H +#define crypto_aead_chacha20poly1305_H + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +/* -- IETF ChaCha20-Poly1305 construction with a 96-bit nonce and a 32-bit internal counter -- */ + +#define crypto_aead_chacha20poly1305_ietf_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_ietf_keybytes(void); + +#define crypto_aead_chacha20poly1305_ietf_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_ietf_nsecbytes(void); + +#define crypto_aead_chacha20poly1305_ietf_NPUBBYTES 12U + +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_ietf_npubbytes(void); + +#define crypto_aead_chacha20poly1305_ietf_ABYTES 16U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_ietf_abytes(void); + +#define crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX \ + SODIUM_MIN(SODIUM_SIZE_MAX - crypto_aead_chacha20poly1305_ietf_ABYTES, \ + (64ULL * ((1ULL << 32) - 1ULL))) +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_ietf_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_ietf_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((nonnull(1, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_ietf_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(4, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_ietf_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((nonnull(1, 2, 9, 10))); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_ietf_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 5, 8, 9))); + +SODIUM_EXPORT +void crypto_aead_chacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_chacha20poly1305_ietf_KEYBYTES]) + __attribute__ ((nonnull)); + +/* -- Original ChaCha20-Poly1305 construction with a 64-bit nonce and a 64-bit internal counter -- */ + +#define crypto_aead_chacha20poly1305_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_keybytes(void); + +#define crypto_aead_chacha20poly1305_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_nsecbytes(void); + +#define crypto_aead_chacha20poly1305_NPUBBYTES 8U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_npubbytes(void); + +#define crypto_aead_chacha20poly1305_ABYTES 16U +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_abytes(void); + +#define crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX \ + (SODIUM_SIZE_MAX - crypto_aead_chacha20poly1305_ABYTES) +SODIUM_EXPORT +size_t crypto_aead_chacha20poly1305_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((nonnull(1, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(4, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((nonnull(1, 2, 9, 10))); + +SODIUM_EXPORT +int crypto_aead_chacha20poly1305_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 5, 8, 9))); + +SODIUM_EXPORT +void crypto_aead_chacha20poly1305_keygen(unsigned char k[crypto_aead_chacha20poly1305_KEYBYTES]) + __attribute__ ((nonnull)); + +/* Aliases */ + +#define crypto_aead_chacha20poly1305_IETF_KEYBYTES crypto_aead_chacha20poly1305_ietf_KEYBYTES +#define crypto_aead_chacha20poly1305_IETF_NSECBYTES crypto_aead_chacha20poly1305_ietf_NSECBYTES +#define crypto_aead_chacha20poly1305_IETF_NPUBBYTES crypto_aead_chacha20poly1305_ietf_NPUBBYTES +#define crypto_aead_chacha20poly1305_IETF_ABYTES crypto_aead_chacha20poly1305_ietf_ABYTES +#define crypto_aead_chacha20poly1305_IETF_MESSAGEBYTES_MAX crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_aead_xchacha20poly1305.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_aead_xchacha20poly1305.h new file mode 100644 index 0000000..6643b0c --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_aead_xchacha20poly1305.h @@ -0,0 +1,100 @@ +#ifndef crypto_aead_xchacha20poly1305_H +#define crypto_aead_xchacha20poly1305_H + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_aead_xchacha20poly1305_ietf_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_keybytes(void); + +#define crypto_aead_xchacha20poly1305_ietf_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_nsecbytes(void); + +#define crypto_aead_xchacha20poly1305_ietf_NPUBBYTES 24U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_npubbytes(void); + +#define crypto_aead_xchacha20poly1305_ietf_ABYTES 16U +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_abytes(void); + +#define crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX \ + (SODIUM_SIZE_MAX - crypto_aead_xchacha20poly1305_ietf_ABYTES) +SODIUM_EXPORT +size_t crypto_aead_xchacha20poly1305_ietf_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_ietf_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((nonnull(1, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_ietf_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(4, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((nonnull(1, 2, 9, 10))); + +SODIUM_EXPORT +int crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 5, 8, 9))); + +SODIUM_EXPORT +void crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES]) + __attribute__ ((nonnull)); + +/* Aliases */ + +#define crypto_aead_xchacha20poly1305_IETF_KEYBYTES crypto_aead_xchacha20poly1305_ietf_KEYBYTES +#define crypto_aead_xchacha20poly1305_IETF_NSECBYTES crypto_aead_xchacha20poly1305_ietf_NSECBYTES +#define crypto_aead_xchacha20poly1305_IETF_NPUBBYTES crypto_aead_xchacha20poly1305_ietf_NPUBBYTES +#define crypto_aead_xchacha20poly1305_IETF_ABYTES crypto_aead_xchacha20poly1305_ietf_ABYTES +#define crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_auth.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_auth.h new file mode 100644 index 0000000..540aee0 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_auth.h @@ -0,0 +1,46 @@ +#ifndef crypto_auth_H +#define crypto_auth_H + +#include + +#include "crypto_auth_hmacsha512256.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_auth_BYTES crypto_auth_hmacsha512256_BYTES +SODIUM_EXPORT +size_t crypto_auth_bytes(void); + +#define crypto_auth_KEYBYTES crypto_auth_hmacsha512256_KEYBYTES +SODIUM_EXPORT +size_t crypto_auth_keybytes(void); + +#define crypto_auth_PRIMITIVE "hmacsha512256" +SODIUM_EXPORT +const char *crypto_auth_primitive(void); + +SODIUM_EXPORT +int crypto_auth(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) + __attribute__ ((nonnull(1, 4))); + +SODIUM_EXPORT +int crypto_auth_verify(const unsigned char *h, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); + +SODIUM_EXPORT +void crypto_auth_keygen(unsigned char k[crypto_auth_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_auth_hmacsha256.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_auth_hmacsha256.h new file mode 100644 index 0000000..3da864c --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_auth_hmacsha256.h @@ -0,0 +1,70 @@ +#ifndef crypto_auth_hmacsha256_H +#define crypto_auth_hmacsha256_H + +#include +#include "crypto_hash_sha256.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_auth_hmacsha256_BYTES 32U +SODIUM_EXPORT +size_t crypto_auth_hmacsha256_bytes(void); + +#define crypto_auth_hmacsha256_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_auth_hmacsha256_keybytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha256(unsigned char *out, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) __attribute__ ((nonnull(1, 4))); + +SODIUM_EXPORT +int crypto_auth_hmacsha256_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); + +/* ------------------------------------------------------------------------- */ + +typedef struct crypto_auth_hmacsha256_state { + crypto_hash_sha256_state ictx; + crypto_hash_sha256_state octx; +} crypto_auth_hmacsha256_state; + +SODIUM_EXPORT +size_t crypto_auth_hmacsha256_statebytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha256_init(crypto_auth_hmacsha256_state *state, + const unsigned char *key, + size_t keylen) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state, + const unsigned char *in, + unsigned long long inlen) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state, + unsigned char *out) __attribute__ ((nonnull)); + + +SODIUM_EXPORT +void crypto_auth_hmacsha256_keygen(unsigned char k[crypto_auth_hmacsha256_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_auth_hmacsha512.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_auth_hmacsha512.h new file mode 100644 index 0000000..d992cb8 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_auth_hmacsha512.h @@ -0,0 +1,68 @@ +#ifndef crypto_auth_hmacsha512_H +#define crypto_auth_hmacsha512_H + +#include +#include "crypto_hash_sha512.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_auth_hmacsha512_BYTES 64U +SODIUM_EXPORT +size_t crypto_auth_hmacsha512_bytes(void); + +#define crypto_auth_hmacsha512_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_auth_hmacsha512_keybytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha512(unsigned char *out, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) __attribute__ ((nonnull(1, 4))); + +SODIUM_EXPORT +int crypto_auth_hmacsha512_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); + +/* ------------------------------------------------------------------------- */ + +typedef struct crypto_auth_hmacsha512_state { + crypto_hash_sha512_state ictx; + crypto_hash_sha512_state octx; +} crypto_auth_hmacsha512_state; + +SODIUM_EXPORT +size_t crypto_auth_hmacsha512_statebytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha512_init(crypto_auth_hmacsha512_state *state, + const unsigned char *key, + size_t keylen) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_auth_hmacsha512_update(crypto_auth_hmacsha512_state *state, + const unsigned char *in, + unsigned long long inlen) __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_auth_hmacsha512_final(crypto_auth_hmacsha512_state *state, + unsigned char *out) __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_auth_hmacsha512_keygen(unsigned char k[crypto_auth_hmacsha512_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_auth_hmacsha512256.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_auth_hmacsha512256.h new file mode 100644 index 0000000..3fb5263 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_auth_hmacsha512256.h @@ -0,0 +1,65 @@ +#ifndef crypto_auth_hmacsha512256_H +#define crypto_auth_hmacsha512256_H + +#include +#include "crypto_auth_hmacsha512.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_auth_hmacsha512256_BYTES 32U +SODIUM_EXPORT +size_t crypto_auth_hmacsha512256_bytes(void); + +#define crypto_auth_hmacsha512256_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_auth_hmacsha512256_keybytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha512256(unsigned char *out, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) __attribute__ ((nonnull(1, 4))); + +SODIUM_EXPORT +int crypto_auth_hmacsha512256_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); + +/* ------------------------------------------------------------------------- */ + +typedef crypto_auth_hmacsha512_state crypto_auth_hmacsha512256_state; + +SODIUM_EXPORT +size_t crypto_auth_hmacsha512256_statebytes(void); + +SODIUM_EXPORT +int crypto_auth_hmacsha512256_init(crypto_auth_hmacsha512256_state *state, + const unsigned char *key, + size_t keylen) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_auth_hmacsha512256_update(crypto_auth_hmacsha512256_state *state, + const unsigned char *in, + unsigned long long inlen) __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_auth_hmacsha512256_final(crypto_auth_hmacsha512256_state *state, + unsigned char *out) __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_auth_hmacsha512256_keygen(unsigned char k[crypto_auth_hmacsha512256_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_box.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_box.h new file mode 100644 index 0000000..e060dd2 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_box.h @@ -0,0 +1,177 @@ +#ifndef crypto_box_H +#define crypto_box_H + +/* + * THREAD SAFETY: crypto_box_keypair() is thread-safe, + * provided that sodium_init() was called before. + * + * Other functions are always thread-safe. + */ + +#include + +#include "crypto_box_curve25519xsalsa20poly1305.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_box_SEEDBYTES crypto_box_curve25519xsalsa20poly1305_SEEDBYTES +SODIUM_EXPORT +size_t crypto_box_seedbytes(void); + +#define crypto_box_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES +SODIUM_EXPORT +size_t crypto_box_publickeybytes(void); + +#define crypto_box_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES +SODIUM_EXPORT +size_t crypto_box_secretkeybytes(void); + +#define crypto_box_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES +SODIUM_EXPORT +size_t crypto_box_noncebytes(void); + +#define crypto_box_MACBYTES crypto_box_curve25519xsalsa20poly1305_MACBYTES +SODIUM_EXPORT +size_t crypto_box_macbytes(void); + +#define crypto_box_MESSAGEBYTES_MAX crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX +SODIUM_EXPORT +size_t crypto_box_messagebytes_max(void); + +#define crypto_box_PRIMITIVE "curve25519xsalsa20poly1305" +SODIUM_EXPORT +const char *crypto_box_primitive(void); + +SODIUM_EXPORT +int crypto_box_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_box_keypair(unsigned char *pk, unsigned char *sk) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_box_easy(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4, 5, 6))); + +SODIUM_EXPORT +int crypto_box_open_easy(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5, 6))); + +SODIUM_EXPORT +int crypto_box_detached(unsigned char *c, unsigned char *mac, + const unsigned char *m, unsigned long long mlen, + const unsigned char *n, const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 2, 5, 6, 7))); + +SODIUM_EXPORT +int crypto_box_open_detached(unsigned char *m, const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 3, 5, 6, 7))); + +/* -- Precomputation interface -- */ + +#define crypto_box_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES +SODIUM_EXPORT +size_t crypto_box_beforenmbytes(void); + +SODIUM_EXPORT +int crypto_box_beforenm(unsigned char *k, const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_box_easy_afternm(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) __attribute__ ((nonnull(1, 4, 5))); + +SODIUM_EXPORT +int crypto_box_open_easy_afternm(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); + +SODIUM_EXPORT +int crypto_box_detached_afternm(unsigned char *c, unsigned char *mac, + const unsigned char *m, unsigned long long mlen, + const unsigned char *n, const unsigned char *k) + __attribute__ ((nonnull(1, 2, 5, 6))); + +SODIUM_EXPORT +int crypto_box_open_detached_afternm(unsigned char *m, const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 3, 5, 6))); + +/* -- Ephemeral SK interface -- */ + +#define crypto_box_SEALBYTES (crypto_box_PUBLICKEYBYTES + crypto_box_MACBYTES) +SODIUM_EXPORT +size_t crypto_box_sealbytes(void); + +SODIUM_EXPORT +int crypto_box_seal(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *pk) + __attribute__ ((nonnull(1, 4))); + +SODIUM_EXPORT +int crypto_box_seal_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, + const unsigned char *pk, const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); + +/* -- NaCl compatibility interface ; Requires padding -- */ + +#define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES +SODIUM_EXPORT +size_t crypto_box_zerobytes(void); + +#define crypto_box_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES +SODIUM_EXPORT +size_t crypto_box_boxzerobytes(void); + +SODIUM_EXPORT +int crypto_box(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4, 5, 6))); + +SODIUM_EXPORT +int crypto_box_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *pk, const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5, 6))); + +SODIUM_EXPORT +int crypto_box_afternm(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) __attribute__ ((nonnull(1, 4, 5))); + +SODIUM_EXPORT +int crypto_box_open_afternm(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_box_curve25519xchacha20poly1305.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_box_curve25519xchacha20poly1305.h new file mode 100644 index 0000000..26a3d31 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_box_curve25519xchacha20poly1305.h @@ -0,0 +1,164 @@ + +#ifndef crypto_box_curve25519xchacha20poly1305_H +#define crypto_box_curve25519xchacha20poly1305_H + +#include +#include "crypto_stream_xchacha20.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_box_curve25519xchacha20poly1305_SEEDBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_seedbytes(void); + +#define crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_publickeybytes(void); + +#define crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_secretkeybytes(void); + +#define crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_beforenmbytes(void); + +#define crypto_box_curve25519xchacha20poly1305_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_noncebytes(void); + +#define crypto_box_curve25519xchacha20poly1305_MACBYTES 16U +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_macbytes(void); + +#define crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX \ + (crypto_stream_xchacha20_MESSAGEBYTES_MAX - crypto_box_curve25519xchacha20poly1305_MACBYTES) +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_seed_keypair(unsigned char *pk, + unsigned char *sk, + const unsigned char *seed) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_keypair(unsigned char *pk, + unsigned char *sk) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_easy(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4, 5, 6))); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_open_easy(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5, 6))); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_detached(unsigned char *c, + unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 2, 5, 6, 7))); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_open_detached(unsigned char *m, + const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 3, 5, 6, 7))); + +/* -- Precomputation interface -- */ + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_beforenm(unsigned char *k, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_easy_afternm(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((nonnull(1, 4, 5))); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_open_easy_afternm(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_detached_afternm(unsigned char *c, + unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((nonnull(1, 2, 5, 6))); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_open_detached_afternm(unsigned char *m, + const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 3, 5, 6))); + +/* -- Ephemeral SK interface -- */ + +#define crypto_box_curve25519xchacha20poly1305_SEALBYTES \ + (crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES + \ + crypto_box_curve25519xchacha20poly1305_MACBYTES) + +SODIUM_EXPORT +size_t crypto_box_curve25519xchacha20poly1305_sealbytes(void); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_seal(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk) + __attribute__ ((nonnull(1, 4))); + +SODIUM_EXPORT +int crypto_box_curve25519xchacha20poly1305_seal_open(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_box_curve25519xsalsa20poly1305.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_box_curve25519xsalsa20poly1305.h new file mode 100644 index 0000000..e733f49 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_box_curve25519xsalsa20poly1305.h @@ -0,0 +1,112 @@ +#ifndef crypto_box_curve25519xsalsa20poly1305_H +#define crypto_box_curve25519xsalsa20poly1305_H + +#include +#include "crypto_stream_xsalsa20.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_box_curve25519xsalsa20poly1305_SEEDBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_seedbytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_publickeybytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_secretkeybytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES 32U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_beforenmbytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_noncebytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_MACBYTES 16U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_macbytes(void); + +/* Only for the libsodium API - The NaCl compatibility API would require BOXZEROBYTES extra bytes */ +#define crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX \ + (crypto_stream_xsalsa20_MESSAGEBYTES_MAX - crypto_box_curve25519xsalsa20poly1305_MACBYTES) +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_seed_keypair(unsigned char *pk, + unsigned char *sk, + const unsigned char *seed) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_keypair(unsigned char *pk, + unsigned char *sk) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_beforenm(unsigned char *k, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +/* -- NaCl compatibility interface ; Requires padding -- */ + +#define crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES 16U +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_boxzerobytes(void); + +#define crypto_box_curve25519xsalsa20poly1305_ZEROBYTES \ + (crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES + \ + crypto_box_curve25519xsalsa20poly1305_MACBYTES) +SODIUM_EXPORT +size_t crypto_box_curve25519xsalsa20poly1305_zerobytes(void); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4, 5, 6))); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_open(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *pk, + const unsigned char *sk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5, 6))); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_afternm(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((nonnull(1, 4, 5))); + +SODIUM_EXPORT +int crypto_box_curve25519xsalsa20poly1305_open_afternm(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_core_ed25519.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_core_ed25519.h new file mode 100644 index 0000000..dcc46a6 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_core_ed25519.h @@ -0,0 +1,100 @@ +#ifndef crypto_core_ed25519_H +#define crypto_core_ed25519_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_ed25519_BYTES 32 +SODIUM_EXPORT +size_t crypto_core_ed25519_bytes(void); + +#define crypto_core_ed25519_UNIFORMBYTES 32 +SODIUM_EXPORT +size_t crypto_core_ed25519_uniformbytes(void); + +#define crypto_core_ed25519_HASHBYTES 64 +SODIUM_EXPORT +size_t crypto_core_ed25519_hashbytes(void); + +#define crypto_core_ed25519_SCALARBYTES 32 +SODIUM_EXPORT +size_t crypto_core_ed25519_scalarbytes(void); + +#define crypto_core_ed25519_NONREDUCEDSCALARBYTES 64 +SODIUM_EXPORT +size_t crypto_core_ed25519_nonreducedscalarbytes(void); + +SODIUM_EXPORT +int crypto_core_ed25519_is_valid_point(const unsigned char *p) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ed25519_add(unsigned char *r, + const unsigned char *p, const unsigned char *q) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ed25519_sub(unsigned char *r, + const unsigned char *p, const unsigned char *q) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ed25519_from_hash(unsigned char *p, const unsigned char *h) + __attribute__ ((nonnull)) __attribute__ ((deprecated)); + +SODIUM_EXPORT +void crypto_core_ed25519_random(unsigned char *p) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ed25519_scalar_random(unsigned char *r) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ed25519_scalar_invert(unsigned char *recip, const unsigned char *s) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ed25519_scalar_negate(unsigned char *neg, const unsigned char *s) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ed25519_scalar_complement(unsigned char *comp, const unsigned char *s) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ed25519_scalar_add(unsigned char *z, const unsigned char *x, + const unsigned char *y) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ed25519_scalar_sub(unsigned char *z, const unsigned char *x, + const unsigned char *y) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ed25519_scalar_mul(unsigned char *z, const unsigned char *x, + const unsigned char *y) + __attribute__ ((nonnull)); + +/* + * The interval `s` is sampled from should be at least 317 bits to ensure almost + * uniformity of `r` over `L`. + */ +SODIUM_EXPORT +void crypto_core_ed25519_scalar_reduce(unsigned char *r, const unsigned char *s) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_core_hchacha20.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_core_hchacha20.h new file mode 100644 index 0000000..ece141b --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_core_hchacha20.h @@ -0,0 +1,36 @@ +#ifndef crypto_core_hchacha20_H +#define crypto_core_hchacha20_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_hchacha20_OUTPUTBYTES 32U +SODIUM_EXPORT +size_t crypto_core_hchacha20_outputbytes(void); + +#define crypto_core_hchacha20_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_hchacha20_inputbytes(void); + +#define crypto_core_hchacha20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_hchacha20_keybytes(void); + +#define crypto_core_hchacha20_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_hchacha20_constbytes(void); + +SODIUM_EXPORT +int crypto_core_hchacha20(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c) + __attribute__ ((nonnull(1, 2, 3))); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_core_hsalsa20.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_core_hsalsa20.h new file mode 100644 index 0000000..4bf7a48 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_core_hsalsa20.h @@ -0,0 +1,36 @@ +#ifndef crypto_core_hsalsa20_H +#define crypto_core_hsalsa20_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_hsalsa20_OUTPUTBYTES 32U +SODIUM_EXPORT +size_t crypto_core_hsalsa20_outputbytes(void); + +#define crypto_core_hsalsa20_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_hsalsa20_inputbytes(void); + +#define crypto_core_hsalsa20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_hsalsa20_keybytes(void); + +#define crypto_core_hsalsa20_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_hsalsa20_constbytes(void); + +SODIUM_EXPORT +int crypto_core_hsalsa20(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c) + __attribute__ ((nonnull(1, 2, 3))); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_core_ristretto255.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_core_ristretto255.h new file mode 100644 index 0000000..f2820e5 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_core_ristretto255.h @@ -0,0 +1,100 @@ +#ifndef crypto_core_ristretto255_H +#define crypto_core_ristretto255_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_ristretto255_BYTES 32 +SODIUM_EXPORT +size_t crypto_core_ristretto255_bytes(void); + +#define crypto_core_ristretto255_HASHBYTES 64 +SODIUM_EXPORT +size_t crypto_core_ristretto255_hashbytes(void); + +#define crypto_core_ristretto255_SCALARBYTES 32 +SODIUM_EXPORT +size_t crypto_core_ristretto255_scalarbytes(void); + +#define crypto_core_ristretto255_NONREDUCEDSCALARBYTES 64 +SODIUM_EXPORT +size_t crypto_core_ristretto255_nonreducedscalarbytes(void); + +SODIUM_EXPORT +int crypto_core_ristretto255_is_valid_point(const unsigned char *p) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ristretto255_add(unsigned char *r, + const unsigned char *p, const unsigned char *q) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ristretto255_sub(unsigned char *r, + const unsigned char *p, const unsigned char *q) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ristretto255_from_hash(unsigned char *p, + const unsigned char *r) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_random(unsigned char *p) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_random(unsigned char *r) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ristretto255_scalar_invert(unsigned char *recip, + const unsigned char *s) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_negate(unsigned char *neg, + const unsigned char *s) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_complement(unsigned char *comp, + const unsigned char *s) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_add(unsigned char *z, + const unsigned char *x, + const unsigned char *y) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_sub(unsigned char *z, + const unsigned char *x, + const unsigned char *y) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_mul(unsigned char *z, + const unsigned char *x, + const unsigned char *y) + __attribute__ ((nonnull)); + +/* + * The interval `s` is sampled from should be at least 317 bits to ensure almost + * uniformity of `r` over `L`. + */ +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_reduce(unsigned char *r, + const unsigned char *s) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_core_salsa20.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_core_salsa20.h new file mode 100644 index 0000000..bd79fd9 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_core_salsa20.h @@ -0,0 +1,36 @@ +#ifndef crypto_core_salsa20_H +#define crypto_core_salsa20_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_salsa20_OUTPUTBYTES 64U +SODIUM_EXPORT +size_t crypto_core_salsa20_outputbytes(void); + +#define crypto_core_salsa20_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa20_inputbytes(void); + +#define crypto_core_salsa20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_salsa20_keybytes(void); + +#define crypto_core_salsa20_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa20_constbytes(void); + +SODIUM_EXPORT +int crypto_core_salsa20(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c) + __attribute__ ((nonnull(1, 2, 3))); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_core_salsa2012.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_core_salsa2012.h new file mode 100644 index 0000000..0595759 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_core_salsa2012.h @@ -0,0 +1,36 @@ +#ifndef crypto_core_salsa2012_H +#define crypto_core_salsa2012_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_salsa2012_OUTPUTBYTES 64U +SODIUM_EXPORT +size_t crypto_core_salsa2012_outputbytes(void); + +#define crypto_core_salsa2012_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa2012_inputbytes(void); + +#define crypto_core_salsa2012_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_salsa2012_keybytes(void); + +#define crypto_core_salsa2012_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa2012_constbytes(void); + +SODIUM_EXPORT +int crypto_core_salsa2012(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c) + __attribute__ ((nonnull(1, 2, 3))); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_core_salsa208.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_core_salsa208.h new file mode 100644 index 0000000..d2f216a --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_core_salsa208.h @@ -0,0 +1,40 @@ +#ifndef crypto_core_salsa208_H +#define crypto_core_salsa208_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_salsa208_OUTPUTBYTES 64U +SODIUM_EXPORT +size_t crypto_core_salsa208_outputbytes(void) + __attribute__ ((deprecated)); + +#define crypto_core_salsa208_INPUTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa208_inputbytes(void) + __attribute__ ((deprecated)); + +#define crypto_core_salsa208_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_core_salsa208_keybytes(void) + __attribute__ ((deprecated)); + +#define crypto_core_salsa208_CONSTBYTES 16U +SODIUM_EXPORT +size_t crypto_core_salsa208_constbytes(void) + __attribute__ ((deprecated)); + +SODIUM_EXPORT +int crypto_core_salsa208(unsigned char *out, const unsigned char *in, + const unsigned char *k, const unsigned char *c) + __attribute__ ((nonnull(1, 2, 3))); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_generichash.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_generichash.h new file mode 100644 index 0000000..d897e5d --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_generichash.h @@ -0,0 +1,84 @@ +#ifndef crypto_generichash_H +#define crypto_generichash_H + +#include + +#include "crypto_generichash_blake2b.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_generichash_BYTES_MIN crypto_generichash_blake2b_BYTES_MIN +SODIUM_EXPORT +size_t crypto_generichash_bytes_min(void); + +#define crypto_generichash_BYTES_MAX crypto_generichash_blake2b_BYTES_MAX +SODIUM_EXPORT +size_t crypto_generichash_bytes_max(void); + +#define crypto_generichash_BYTES crypto_generichash_blake2b_BYTES +SODIUM_EXPORT +size_t crypto_generichash_bytes(void); + +#define crypto_generichash_KEYBYTES_MIN crypto_generichash_blake2b_KEYBYTES_MIN +SODIUM_EXPORT +size_t crypto_generichash_keybytes_min(void); + +#define crypto_generichash_KEYBYTES_MAX crypto_generichash_blake2b_KEYBYTES_MAX +SODIUM_EXPORT +size_t crypto_generichash_keybytes_max(void); + +#define crypto_generichash_KEYBYTES crypto_generichash_blake2b_KEYBYTES +SODIUM_EXPORT +size_t crypto_generichash_keybytes(void); + +#define crypto_generichash_PRIMITIVE "blake2b" +SODIUM_EXPORT +const char *crypto_generichash_primitive(void); + +/* + * Important when writing bindings for other programming languages: + * the state address should be 64-bytes aligned. + */ +typedef crypto_generichash_blake2b_state crypto_generichash_state; + +SODIUM_EXPORT +size_t crypto_generichash_statebytes(void); + +SODIUM_EXPORT +int crypto_generichash(unsigned char *out, size_t outlen, + const unsigned char *in, unsigned long long inlen, + const unsigned char *key, size_t keylen) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_generichash_init(crypto_generichash_state *state, + const unsigned char *key, + const size_t keylen, const size_t outlen) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_generichash_update(crypto_generichash_state *state, + const unsigned char *in, + unsigned long long inlen) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_generichash_final(crypto_generichash_state *state, + unsigned char *out, const size_t outlen) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_generichash_keygen(unsigned char k[crypto_generichash_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_generichash_blake2b.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_generichash_blake2b.h new file mode 100644 index 0000000..ae3b52f --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_generichash_blake2b.h @@ -0,0 +1,122 @@ +#ifndef crypto_generichash_blake2b_H +#define crypto_generichash_blake2b_H + +#include +#include +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#ifdef __IBMC__ +# pragma pack(1) +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# pragma pack(1) +#else +# pragma pack(push, 1) +#endif + +typedef struct CRYPTO_ALIGN(64) crypto_generichash_blake2b_state { + unsigned char opaque[384]; +} crypto_generichash_blake2b_state; + +#ifdef __IBMC__ +# pragma pack(pop) +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# pragma pack() +#else +# pragma pack(pop) +#endif + +#define crypto_generichash_blake2b_BYTES_MIN 16U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_bytes_min(void); + +#define crypto_generichash_blake2b_BYTES_MAX 64U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_bytes_max(void); + +#define crypto_generichash_blake2b_BYTES 32U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_bytes(void); + +#define crypto_generichash_blake2b_KEYBYTES_MIN 16U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_keybytes_min(void); + +#define crypto_generichash_blake2b_KEYBYTES_MAX 64U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_keybytes_max(void); + +#define crypto_generichash_blake2b_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_keybytes(void); + +#define crypto_generichash_blake2b_SALTBYTES 16U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_saltbytes(void); + +#define crypto_generichash_blake2b_PERSONALBYTES 16U +SODIUM_EXPORT +size_t crypto_generichash_blake2b_personalbytes(void); + +SODIUM_EXPORT +size_t crypto_generichash_blake2b_statebytes(void); + +SODIUM_EXPORT +int crypto_generichash_blake2b(unsigned char *out, size_t outlen, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *key, size_t keylen) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_generichash_blake2b_salt_personal(unsigned char *out, size_t outlen, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *key, + size_t keylen, + const unsigned char *salt, + const unsigned char *personal) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_generichash_blake2b_init(crypto_generichash_blake2b_state *state, + const unsigned char *key, + const size_t keylen, const size_t outlen) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_generichash_blake2b_init_salt_personal(crypto_generichash_blake2b_state *state, + const unsigned char *key, + const size_t keylen, const size_t outlen, + const unsigned char *salt, + const unsigned char *personal) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_generichash_blake2b_update(crypto_generichash_blake2b_state *state, + const unsigned char *in, + unsigned long long inlen) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_generichash_blake2b_final(crypto_generichash_blake2b_state *state, + unsigned char *out, + const size_t outlen) __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_generichash_blake2b_keygen(unsigned char k[crypto_generichash_blake2b_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_hash.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_hash.h new file mode 100644 index 0000000..767d548 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_hash.h @@ -0,0 +1,40 @@ +#ifndef crypto_hash_H +#define crypto_hash_H + +/* + * WARNING: Unless you absolutely need to use SHA512 for interoperability, + * purposes, you might want to consider crypto_generichash() instead. + * Unlike SHA512, crypto_generichash() is not vulnerable to length + * extension attacks. + */ + +#include + +#include "crypto_hash_sha512.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_hash_BYTES crypto_hash_sha512_BYTES +SODIUM_EXPORT +size_t crypto_hash_bytes(void); + +SODIUM_EXPORT +int crypto_hash(unsigned char *out, const unsigned char *in, + unsigned long long inlen) __attribute__ ((nonnull(1))); + +#define crypto_hash_PRIMITIVE "sha512" +SODIUM_EXPORT +const char *crypto_hash_primitive(void) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_hash_sha256.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_hash_sha256.h new file mode 100644 index 0000000..c47982a --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_hash_sha256.h @@ -0,0 +1,60 @@ +#ifndef crypto_hash_sha256_H +#define crypto_hash_sha256_H + +/* + * WARNING: Unless you absolutely need to use SHA256 for interoperability, + * purposes, you might want to consider crypto_generichash() instead. + * Unlike SHA256, crypto_generichash() is not vulnerable to length + * extension attacks. + */ + +#include +#include +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef struct crypto_hash_sha256_state { + uint32_t state[8]; + uint64_t count; + uint8_t buf[64]; +} crypto_hash_sha256_state; + +SODIUM_EXPORT +size_t crypto_hash_sha256_statebytes(void); + +#define crypto_hash_sha256_BYTES 32U +SODIUM_EXPORT +size_t crypto_hash_sha256_bytes(void); + +SODIUM_EXPORT +int crypto_hash_sha256(unsigned char *out, const unsigned char *in, + unsigned long long inlen) __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_hash_sha256_init(crypto_hash_sha256_state *state) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_hash_sha256_update(crypto_hash_sha256_state *state, + const unsigned char *in, + unsigned long long inlen) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_hash_sha256_final(crypto_hash_sha256_state *state, + unsigned char *out) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_hash_sha512.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_hash_sha512.h new file mode 100644 index 0000000..5b690fb --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_hash_sha512.h @@ -0,0 +1,60 @@ +#ifndef crypto_hash_sha512_H +#define crypto_hash_sha512_H + +/* + * WARNING: Unless you absolutely need to use SHA512 for interoperability, + * purposes, you might want to consider crypto_generichash() instead. + * Unlike SHA512, crypto_generichash() is not vulnerable to length + * extension attacks. + */ + +#include +#include +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef struct crypto_hash_sha512_state { + uint64_t state[8]; + uint64_t count[2]; + uint8_t buf[128]; +} crypto_hash_sha512_state; + +SODIUM_EXPORT +size_t crypto_hash_sha512_statebytes(void); + +#define crypto_hash_sha512_BYTES 64U +SODIUM_EXPORT +size_t crypto_hash_sha512_bytes(void); + +SODIUM_EXPORT +int crypto_hash_sha512(unsigned char *out, const unsigned char *in, + unsigned long long inlen) __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_hash_sha512_init(crypto_hash_sha512_state *state) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_hash_sha512_update(crypto_hash_sha512_state *state, + const unsigned char *in, + unsigned long long inlen) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_hash_sha512_final(crypto_hash_sha512_state *state, + unsigned char *out) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_kdf.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_kdf.h new file mode 100644 index 0000000..ac2fc61 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_kdf.h @@ -0,0 +1,53 @@ +#ifndef crypto_kdf_H +#define crypto_kdf_H + +#include +#include + +#include "crypto_kdf_blake2b.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_kdf_BYTES_MIN crypto_kdf_blake2b_BYTES_MIN +SODIUM_EXPORT +size_t crypto_kdf_bytes_min(void); + +#define crypto_kdf_BYTES_MAX crypto_kdf_blake2b_BYTES_MAX +SODIUM_EXPORT +size_t crypto_kdf_bytes_max(void); + +#define crypto_kdf_CONTEXTBYTES crypto_kdf_blake2b_CONTEXTBYTES +SODIUM_EXPORT +size_t crypto_kdf_contextbytes(void); + +#define crypto_kdf_KEYBYTES crypto_kdf_blake2b_KEYBYTES +SODIUM_EXPORT +size_t crypto_kdf_keybytes(void); + +#define crypto_kdf_PRIMITIVE "blake2b" +SODIUM_EXPORT +const char *crypto_kdf_primitive(void) + __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int crypto_kdf_derive_from_key(unsigned char *subkey, size_t subkey_len, + uint64_t subkey_id, + const char ctx[crypto_kdf_CONTEXTBYTES], + const unsigned char key[crypto_kdf_KEYBYTES]) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_kdf_keygen(unsigned char k[crypto_kdf_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_kdf_blake2b.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_kdf_blake2b.h new file mode 100644 index 0000000..489c7c2 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_kdf_blake2b.h @@ -0,0 +1,44 @@ +#ifndef crypto_kdf_blake2b_H +#define crypto_kdf_blake2b_H + +#include +#include +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_kdf_blake2b_BYTES_MIN 16 +SODIUM_EXPORT +size_t crypto_kdf_blake2b_bytes_min(void); + +#define crypto_kdf_blake2b_BYTES_MAX 64 +SODIUM_EXPORT +size_t crypto_kdf_blake2b_bytes_max(void); + +#define crypto_kdf_blake2b_CONTEXTBYTES 8 +SODIUM_EXPORT +size_t crypto_kdf_blake2b_contextbytes(void); + +#define crypto_kdf_blake2b_KEYBYTES 32 +SODIUM_EXPORT +size_t crypto_kdf_blake2b_keybytes(void); + +SODIUM_EXPORT +int crypto_kdf_blake2b_derive_from_key(unsigned char *subkey, size_t subkey_len, + uint64_t subkey_id, + const char ctx[crypto_kdf_blake2b_CONTEXTBYTES], + const unsigned char key[crypto_kdf_blake2b_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_kx.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_kx.h new file mode 100644 index 0000000..347132c --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_kx.h @@ -0,0 +1,66 @@ +#ifndef crypto_kx_H +#define crypto_kx_H + +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_kx_PUBLICKEYBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_publickeybytes(void); + +#define crypto_kx_SECRETKEYBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_secretkeybytes(void); + +#define crypto_kx_SEEDBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_seedbytes(void); + +#define crypto_kx_SESSIONKEYBYTES 32 +SODIUM_EXPORT +size_t crypto_kx_sessionkeybytes(void); + +#define crypto_kx_PRIMITIVE "x25519blake2b" +SODIUM_EXPORT +const char *crypto_kx_primitive(void); + +SODIUM_EXPORT +int crypto_kx_seed_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], + unsigned char sk[crypto_kx_SECRETKEYBYTES], + const unsigned char seed[crypto_kx_SEEDBYTES]) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], + unsigned char sk[crypto_kx_SECRETKEYBYTES]) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_kx_client_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], + unsigned char tx[crypto_kx_SESSIONKEYBYTES], + const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES], + const unsigned char client_sk[crypto_kx_SECRETKEYBYTES], + const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES]) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 4, 5))); + +SODIUM_EXPORT +int crypto_kx_server_session_keys(unsigned char rx[crypto_kx_SESSIONKEYBYTES], + unsigned char tx[crypto_kx_SESSIONKEYBYTES], + const unsigned char server_pk[crypto_kx_PUBLICKEYBYTES], + const unsigned char server_sk[crypto_kx_SECRETKEYBYTES], + const unsigned char client_pk[crypto_kx_PUBLICKEYBYTES]) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 4, 5))); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_onetimeauth.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_onetimeauth.h new file mode 100644 index 0000000..7cd7b07 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_onetimeauth.h @@ -0,0 +1,65 @@ +#ifndef crypto_onetimeauth_H +#define crypto_onetimeauth_H + +#include + +#include "crypto_onetimeauth_poly1305.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef crypto_onetimeauth_poly1305_state crypto_onetimeauth_state; + +SODIUM_EXPORT +size_t crypto_onetimeauth_statebytes(void); + +#define crypto_onetimeauth_BYTES crypto_onetimeauth_poly1305_BYTES +SODIUM_EXPORT +size_t crypto_onetimeauth_bytes(void); + +#define crypto_onetimeauth_KEYBYTES crypto_onetimeauth_poly1305_KEYBYTES +SODIUM_EXPORT +size_t crypto_onetimeauth_keybytes(void); + +#define crypto_onetimeauth_PRIMITIVE "poly1305" +SODIUM_EXPORT +const char *crypto_onetimeauth_primitive(void); + +SODIUM_EXPORT +int crypto_onetimeauth(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) + __attribute__ ((nonnull(1, 4))); + +SODIUM_EXPORT +int crypto_onetimeauth_verify(const unsigned char *h, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); + +SODIUM_EXPORT +int crypto_onetimeauth_init(crypto_onetimeauth_state *state, + const unsigned char *key) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_onetimeauth_update(crypto_onetimeauth_state *state, + const unsigned char *in, + unsigned long long inlen) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_onetimeauth_final(crypto_onetimeauth_state *state, + unsigned char *out) __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_onetimeauth_keygen(unsigned char k[crypto_onetimeauth_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_onetimeauth_poly1305.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_onetimeauth_poly1305.h new file mode 100644 index 0000000..f3e34d8 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_onetimeauth_poly1305.h @@ -0,0 +1,72 @@ +#ifndef crypto_onetimeauth_poly1305_H +#define crypto_onetimeauth_poly1305_H + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#include +#include +#include + +#include + +#include "export.h" + +typedef struct CRYPTO_ALIGN(16) crypto_onetimeauth_poly1305_state { + unsigned char opaque[256]; +} crypto_onetimeauth_poly1305_state; + +SODIUM_EXPORT +size_t crypto_onetimeauth_poly1305_statebytes(void); + +#define crypto_onetimeauth_poly1305_BYTES 16U +SODIUM_EXPORT +size_t crypto_onetimeauth_poly1305_bytes(void); + +#define crypto_onetimeauth_poly1305_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_onetimeauth_poly1305_keybytes(void); + +SODIUM_EXPORT +int crypto_onetimeauth_poly1305(unsigned char *out, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) + __attribute__ ((nonnull(1, 4))); + +SODIUM_EXPORT +int crypto_onetimeauth_poly1305_verify(const unsigned char *h, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); + +SODIUM_EXPORT +int crypto_onetimeauth_poly1305_init(crypto_onetimeauth_poly1305_state *state, + const unsigned char *key) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_onetimeauth_poly1305_update(crypto_onetimeauth_poly1305_state *state, + const unsigned char *in, + unsigned long long inlen) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_onetimeauth_poly1305_final(crypto_onetimeauth_poly1305_state *state, + unsigned char *out) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_onetimeauth_poly1305_keygen(unsigned char k[crypto_onetimeauth_poly1305_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_pwhash.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_pwhash.h new file mode 100644 index 0000000..585a993 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_pwhash.h @@ -0,0 +1,147 @@ +#ifndef crypto_pwhash_H +#define crypto_pwhash_H + +#include + +#include "crypto_pwhash_argon2i.h" +#include "crypto_pwhash_argon2id.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_pwhash_ALG_ARGON2I13 crypto_pwhash_argon2i_ALG_ARGON2I13 +SODIUM_EXPORT +int crypto_pwhash_alg_argon2i13(void); + +#define crypto_pwhash_ALG_ARGON2ID13 crypto_pwhash_argon2id_ALG_ARGON2ID13 +SODIUM_EXPORT +int crypto_pwhash_alg_argon2id13(void); + +#define crypto_pwhash_ALG_DEFAULT crypto_pwhash_ALG_ARGON2ID13 +SODIUM_EXPORT +int crypto_pwhash_alg_default(void); + +#define crypto_pwhash_BYTES_MIN crypto_pwhash_argon2id_BYTES_MIN +SODIUM_EXPORT +size_t crypto_pwhash_bytes_min(void); + +#define crypto_pwhash_BYTES_MAX crypto_pwhash_argon2id_BYTES_MAX +SODIUM_EXPORT +size_t crypto_pwhash_bytes_max(void); + +#define crypto_pwhash_PASSWD_MIN crypto_pwhash_argon2id_PASSWD_MIN +SODIUM_EXPORT +size_t crypto_pwhash_passwd_min(void); + +#define crypto_pwhash_PASSWD_MAX crypto_pwhash_argon2id_PASSWD_MAX +SODIUM_EXPORT +size_t crypto_pwhash_passwd_max(void); + +#define crypto_pwhash_SALTBYTES crypto_pwhash_argon2id_SALTBYTES +SODIUM_EXPORT +size_t crypto_pwhash_saltbytes(void); + +#define crypto_pwhash_STRBYTES crypto_pwhash_argon2id_STRBYTES +SODIUM_EXPORT +size_t crypto_pwhash_strbytes(void); + +#define crypto_pwhash_STRPREFIX crypto_pwhash_argon2id_STRPREFIX +SODIUM_EXPORT +const char *crypto_pwhash_strprefix(void); + +#define crypto_pwhash_OPSLIMIT_MIN crypto_pwhash_argon2id_OPSLIMIT_MIN +SODIUM_EXPORT +size_t crypto_pwhash_opslimit_min(void); + +#define crypto_pwhash_OPSLIMIT_MAX crypto_pwhash_argon2id_OPSLIMIT_MAX +SODIUM_EXPORT +size_t crypto_pwhash_opslimit_max(void); + +#define crypto_pwhash_MEMLIMIT_MIN crypto_pwhash_argon2id_MEMLIMIT_MIN +SODIUM_EXPORT +size_t crypto_pwhash_memlimit_min(void); + +#define crypto_pwhash_MEMLIMIT_MAX crypto_pwhash_argon2id_MEMLIMIT_MAX +SODIUM_EXPORT +size_t crypto_pwhash_memlimit_max(void); + +#define crypto_pwhash_OPSLIMIT_INTERACTIVE crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE +SODIUM_EXPORT +size_t crypto_pwhash_opslimit_interactive(void); + +#define crypto_pwhash_MEMLIMIT_INTERACTIVE crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE +SODIUM_EXPORT +size_t crypto_pwhash_memlimit_interactive(void); + +#define crypto_pwhash_OPSLIMIT_MODERATE crypto_pwhash_argon2id_OPSLIMIT_MODERATE +SODIUM_EXPORT +size_t crypto_pwhash_opslimit_moderate(void); + +#define crypto_pwhash_MEMLIMIT_MODERATE crypto_pwhash_argon2id_MEMLIMIT_MODERATE +SODIUM_EXPORT +size_t crypto_pwhash_memlimit_moderate(void); + +#define crypto_pwhash_OPSLIMIT_SENSITIVE crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE +SODIUM_EXPORT +size_t crypto_pwhash_opslimit_sensitive(void); + +#define crypto_pwhash_MEMLIMIT_SENSITIVE crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE +SODIUM_EXPORT +size_t crypto_pwhash_memlimit_sensitive(void); + +/* + * With this function, do not forget to store all parameters, including the + * algorithm identifier in order to produce deterministic output. + * The crypto_pwhash_* definitions, including crypto_pwhash_ALG_DEFAULT, + * may change. + */ +SODIUM_EXPORT +int crypto_pwhash(unsigned char * const out, unsigned long long outlen, + const char * const passwd, unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, size_t memlimit, int alg) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +/* + * The output string already includes all the required parameters, including + * the algorithm identifier. The string is all that has to be stored in + * order to verify a password. + */ +SODIUM_EXPORT +int crypto_pwhash_str(char out[crypto_pwhash_STRBYTES], + const char * const passwd, unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_pwhash_str_alg(char out[crypto_pwhash_STRBYTES], + const char * const passwd, unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit, int alg) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_pwhash_str_verify(const char str[crypto_pwhash_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_pwhash_str_needs_rehash(const char str[crypto_pwhash_STRBYTES], + unsigned long long opslimit, size_t memlimit) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +#define crypto_pwhash_PRIMITIVE "argon2i" +SODIUM_EXPORT +const char *crypto_pwhash_primitive(void) + __attribute__ ((warn_unused_result)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_pwhash_argon2i.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_pwhash_argon2i.h new file mode 100644 index 0000000..88ff622 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_pwhash_argon2i.h @@ -0,0 +1,122 @@ +#ifndef crypto_pwhash_argon2i_H +#define crypto_pwhash_argon2i_H + +#include +#include +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_pwhash_argon2i_ALG_ARGON2I13 1 +SODIUM_EXPORT +int crypto_pwhash_argon2i_alg_argon2i13(void); + +#define crypto_pwhash_argon2i_BYTES_MIN 16U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_bytes_min(void); + +#define crypto_pwhash_argon2i_BYTES_MAX SODIUM_MIN(SODIUM_SIZE_MAX, 4294967295U) +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_bytes_max(void); + +#define crypto_pwhash_argon2i_PASSWD_MIN 0U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_passwd_min(void); + +#define crypto_pwhash_argon2i_PASSWD_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_passwd_max(void); + +#define crypto_pwhash_argon2i_SALTBYTES 16U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_saltbytes(void); + +#define crypto_pwhash_argon2i_STRBYTES 128U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_strbytes(void); + +#define crypto_pwhash_argon2i_STRPREFIX "$argon2i$" +SODIUM_EXPORT +const char *crypto_pwhash_argon2i_strprefix(void); + +#define crypto_pwhash_argon2i_OPSLIMIT_MIN 3U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_opslimit_min(void); + +#define crypto_pwhash_argon2i_OPSLIMIT_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_opslimit_max(void); + +#define crypto_pwhash_argon2i_MEMLIMIT_MIN 8192U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_memlimit_min(void); + +#define crypto_pwhash_argon2i_MEMLIMIT_MAX \ + ((SIZE_MAX >= 4398046510080U) ? 4398046510080U : (SIZE_MAX >= 2147483648U) ? 2147483648U : 32768U) +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_memlimit_max(void); + +#define crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE 4U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_opslimit_interactive(void); + +#define crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE 33554432U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_memlimit_interactive(void); + +#define crypto_pwhash_argon2i_OPSLIMIT_MODERATE 6U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_opslimit_moderate(void); + +#define crypto_pwhash_argon2i_MEMLIMIT_MODERATE 134217728U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_memlimit_moderate(void); + +#define crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE 8U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_opslimit_sensitive(void); + +#define crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE 536870912U +SODIUM_EXPORT +size_t crypto_pwhash_argon2i_memlimit_sensitive(void); + +SODIUM_EXPORT +int crypto_pwhash_argon2i(unsigned char * const out, + unsigned long long outlen, + const char * const passwd, + unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, size_t memlimit, + int alg) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES], + const char * const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_pwhash_argon2i_str_needs_rehash(const char str[crypto_pwhash_argon2i_STRBYTES], + unsigned long long opslimit, size_t memlimit) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_pwhash_argon2id.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_pwhash_argon2id.h new file mode 100644 index 0000000..7183abd --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_pwhash_argon2id.h @@ -0,0 +1,122 @@ +#ifndef crypto_pwhash_argon2id_H +#define crypto_pwhash_argon2id_H + +#include +#include +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_pwhash_argon2id_ALG_ARGON2ID13 2 +SODIUM_EXPORT +int crypto_pwhash_argon2id_alg_argon2id13(void); + +#define crypto_pwhash_argon2id_BYTES_MIN 16U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_bytes_min(void); + +#define crypto_pwhash_argon2id_BYTES_MAX SODIUM_MIN(SODIUM_SIZE_MAX, 4294967295U) +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_bytes_max(void); + +#define crypto_pwhash_argon2id_PASSWD_MIN 0U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_passwd_min(void); + +#define crypto_pwhash_argon2id_PASSWD_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_passwd_max(void); + +#define crypto_pwhash_argon2id_SALTBYTES 16U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_saltbytes(void); + +#define crypto_pwhash_argon2id_STRBYTES 128U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_strbytes(void); + +#define crypto_pwhash_argon2id_STRPREFIX "$argon2id$" +SODIUM_EXPORT +const char *crypto_pwhash_argon2id_strprefix(void); + +#define crypto_pwhash_argon2id_OPSLIMIT_MIN 1U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_opslimit_min(void); + +#define crypto_pwhash_argon2id_OPSLIMIT_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_opslimit_max(void); + +#define crypto_pwhash_argon2id_MEMLIMIT_MIN 8192U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_memlimit_min(void); + +#define crypto_pwhash_argon2id_MEMLIMIT_MAX \ + ((SIZE_MAX >= 4398046510080U) ? 4398046510080U : (SIZE_MAX >= 2147483648U) ? 2147483648U : 32768U) +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_memlimit_max(void); + +#define crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE 2U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_opslimit_interactive(void); + +#define crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE 67108864U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_memlimit_interactive(void); + +#define crypto_pwhash_argon2id_OPSLIMIT_MODERATE 3U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_opslimit_moderate(void); + +#define crypto_pwhash_argon2id_MEMLIMIT_MODERATE 268435456U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_memlimit_moderate(void); + +#define crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE 4U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_opslimit_sensitive(void); + +#define crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE 1073741824U +SODIUM_EXPORT +size_t crypto_pwhash_argon2id_memlimit_sensitive(void); + +SODIUM_EXPORT +int crypto_pwhash_argon2id(unsigned char * const out, + unsigned long long outlen, + const char * const passwd, + unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, size_t memlimit, + int alg) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_pwhash_argon2id_str(char out[crypto_pwhash_argon2id_STRBYTES], + const char * const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, size_t memlimit) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_pwhash_argon2id_str_verify(const char str[crypto_pwhash_argon2id_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_pwhash_argon2id_str_needs_rehash(const char str[crypto_pwhash_argon2id_STRBYTES], + unsigned long long opslimit, size_t memlimit) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_pwhash_scryptsalsa208sha256.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_pwhash_scryptsalsa208sha256.h new file mode 100644 index 0000000..5c0bf7d --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_pwhash_scryptsalsa208sha256.h @@ -0,0 +1,120 @@ +#ifndef crypto_pwhash_scryptsalsa208sha256_H +#define crypto_pwhash_scryptsalsa208sha256_H + +#include +#include +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_pwhash_scryptsalsa208sha256_BYTES_MIN 16U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_bytes_min(void); + +#define crypto_pwhash_scryptsalsa208sha256_BYTES_MAX \ + SODIUM_MIN(SODIUM_SIZE_MAX, 0x1fffffffe0ULL) +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_bytes_max(void); + +#define crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN 0U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_passwd_min(void); + +#define crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX SODIUM_SIZE_MAX +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_passwd_max(void); + +#define crypto_pwhash_scryptsalsa208sha256_SALTBYTES 32U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_saltbytes(void); + +#define crypto_pwhash_scryptsalsa208sha256_STRBYTES 102U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_strbytes(void); + +#define crypto_pwhash_scryptsalsa208sha256_STRPREFIX "$7$" +SODIUM_EXPORT +const char *crypto_pwhash_scryptsalsa208sha256_strprefix(void); + +#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN 32768U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_opslimit_min(void); + +#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX 4294967295U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_opslimit_max(void); + +#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN 16777216U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_memlimit_min(void); + +#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX \ + SODIUM_MIN(SIZE_MAX, 68719476736ULL) +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_memlimit_max(void); + +#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE 524288U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void); + +#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE 16777216U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void); + +#define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE 33554432U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void); + +#define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE 1073741824U +SODIUM_EXPORT +size_t crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive(void); + +SODIUM_EXPORT +int crypto_pwhash_scryptsalsa208sha256(unsigned char * const out, + unsigned long long outlen, + const char * const passwd, + unsigned long long passwdlen, + const unsigned char * const salt, + unsigned long long opslimit, + size_t memlimit) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + const char * const passwd, + unsigned long long passwdlen, + unsigned long long opslimit, + size_t memlimit) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + const char * const passwd, + unsigned long long passwdlen) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t * passwd, size_t passwdlen, + const uint8_t * salt, size_t saltlen, + uint64_t N, uint32_t r, uint32_t p, + uint8_t * buf, size_t buflen) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_pwhash_scryptsalsa208sha256_str_needs_rehash(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + unsigned long long opslimit, + size_t memlimit) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_scalarmult.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_scalarmult.h new file mode 100644 index 0000000..1c68585 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_scalarmult.h @@ -0,0 +1,46 @@ +#ifndef crypto_scalarmult_H +#define crypto_scalarmult_H + +#include + +#include "crypto_scalarmult_curve25519.h" +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES +SODIUM_EXPORT +size_t crypto_scalarmult_bytes(void); + +#define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES +SODIUM_EXPORT +size_t crypto_scalarmult_scalarbytes(void); + +#define crypto_scalarmult_PRIMITIVE "curve25519" +SODIUM_EXPORT +const char *crypto_scalarmult_primitive(void); + +SODIUM_EXPORT +int crypto_scalarmult_base(unsigned char *q, const unsigned char *n) + __attribute__ ((nonnull)); + +/* + * NOTE: Do not use the result of this function directly for key exchange. + * + * Hash the result with the public keys in order to compute a shared + * secret key: H(q || client_pk || server_pk) + * + * Or unless this is not an option, use the crypto_kx() API instead. + */ +SODIUM_EXPORT +int crypto_scalarmult(unsigned char *q, const unsigned char *n, + const unsigned char *p) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_scalarmult_curve25519.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_scalarmult_curve25519.h new file mode 100644 index 0000000..60e9d0c --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_scalarmult_curve25519.h @@ -0,0 +1,42 @@ +#ifndef crypto_scalarmult_curve25519_H +#define crypto_scalarmult_curve25519_H + +#include + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_scalarmult_curve25519_BYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_curve25519_bytes(void); + +#define crypto_scalarmult_curve25519_SCALARBYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_curve25519_scalarbytes(void); + +/* + * NOTE: Do not use the result of this function directly for key exchange. + * + * Hash the result with the public keys in order to compute a shared + * secret key: H(q || client_pk || server_pk) + * + * Or unless this is not an option, use the crypto_kx() API instead. + */ +SODIUM_EXPORT +int crypto_scalarmult_curve25519(unsigned char *q, const unsigned char *n, + const unsigned char *p) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_scalarmult_curve25519_base(unsigned char *q, + const unsigned char *n) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_scalarmult_ed25519.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_scalarmult_ed25519.h new file mode 100644 index 0000000..2dfa4d7 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_scalarmult_ed25519.h @@ -0,0 +1,51 @@ + +#ifndef crypto_scalarmult_ed25519_H +#define crypto_scalarmult_ed25519_H + +#include + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_scalarmult_ed25519_BYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_ed25519_bytes(void); + +#define crypto_scalarmult_ed25519_SCALARBYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_ed25519_scalarbytes(void); + +/* + * NOTE: Do not use the result of this function directly for key exchange. + * + * Hash the result with the public keys in order to compute a shared + * secret key: H(q || client_pk || server_pk) + * + * Or unless this is not an option, use the crypto_kx() API instead. + */ +SODIUM_EXPORT +int crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n, + const unsigned char *p) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_scalarmult_ed25519_noclamp(unsigned char *q, const unsigned char *n, + const unsigned char *p) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_scalarmult_ed25519_base(unsigned char *q, const unsigned char *n) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_scalarmult_ed25519_base_noclamp(unsigned char *q, const unsigned char *n) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_scalarmult_ristretto255.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_scalarmult_ristretto255.h new file mode 100644 index 0000000..40a45cc --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_scalarmult_ristretto255.h @@ -0,0 +1,43 @@ + +#ifndef crypto_scalarmult_ristretto255_H +#define crypto_scalarmult_ristretto255_H + +#include + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_scalarmult_ristretto255_BYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_ristretto255_bytes(void); + +#define crypto_scalarmult_ristretto255_SCALARBYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_ristretto255_scalarbytes(void); + +/* + * NOTE: Do not use the result of this function directly for key exchange. + * + * Hash the result with the public keys in order to compute a shared + * secret key: H(q || client_pk || server_pk) + * + * Or unless this is not an option, use the crypto_kx() API instead. + */ +SODIUM_EXPORT +int crypto_scalarmult_ristretto255(unsigned char *q, const unsigned char *n, + const unsigned char *p) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_scalarmult_ristretto255_base(unsigned char *q, + const unsigned char *n) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_secretbox.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_secretbox.h new file mode 100644 index 0000000..1d3709d --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_secretbox.h @@ -0,0 +1,93 @@ +#ifndef crypto_secretbox_H +#define crypto_secretbox_H + +#include + +#include "crypto_secretbox_xsalsa20poly1305.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_secretbox_KEYBYTES crypto_secretbox_xsalsa20poly1305_KEYBYTES +SODIUM_EXPORT +size_t crypto_secretbox_keybytes(void); + +#define crypto_secretbox_NONCEBYTES crypto_secretbox_xsalsa20poly1305_NONCEBYTES +SODIUM_EXPORT +size_t crypto_secretbox_noncebytes(void); + +#define crypto_secretbox_MACBYTES crypto_secretbox_xsalsa20poly1305_MACBYTES +SODIUM_EXPORT +size_t crypto_secretbox_macbytes(void); + +#define crypto_secretbox_PRIMITIVE "xsalsa20poly1305" +SODIUM_EXPORT +const char *crypto_secretbox_primitive(void); + +#define crypto_secretbox_MESSAGEBYTES_MAX crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX +SODIUM_EXPORT +size_t crypto_secretbox_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_secretbox_easy(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) __attribute__ ((nonnull(1, 4, 5))); + +SODIUM_EXPORT +int crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); + +SODIUM_EXPORT +int crypto_secretbox_detached(unsigned char *c, unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((nonnull(1, 2, 5, 6))); + +SODIUM_EXPORT +int crypto_secretbox_open_detached(unsigned char *m, + const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 3, 5, 6))); + +SODIUM_EXPORT +void crypto_secretbox_keygen(unsigned char k[crypto_secretbox_KEYBYTES]) + __attribute__ ((nonnull)); + +/* -- NaCl compatibility interface ; Requires padding -- */ + +#define crypto_secretbox_ZEROBYTES crypto_secretbox_xsalsa20poly1305_ZEROBYTES +SODIUM_EXPORT +size_t crypto_secretbox_zerobytes(void); + +#define crypto_secretbox_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES +SODIUM_EXPORT +size_t crypto_secretbox_boxzerobytes(void); + +SODIUM_EXPORT +int crypto_secretbox(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) __attribute__ ((nonnull(1, 4, 5))); + +SODIUM_EXPORT +int crypto_secretbox_open(unsigned char *m, const unsigned char *c, + unsigned long long clen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_secretbox_xchacha20poly1305.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_secretbox_xchacha20poly1305.h new file mode 100644 index 0000000..6ec674e --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_secretbox_xchacha20poly1305.h @@ -0,0 +1,70 @@ +#ifndef crypto_secretbox_xchacha20poly1305_H +#define crypto_secretbox_xchacha20poly1305_H + +#include +#include "crypto_stream_xchacha20.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_secretbox_xchacha20poly1305_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_secretbox_xchacha20poly1305_keybytes(void); + +#define crypto_secretbox_xchacha20poly1305_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_secretbox_xchacha20poly1305_noncebytes(void); + +#define crypto_secretbox_xchacha20poly1305_MACBYTES 16U +SODIUM_EXPORT +size_t crypto_secretbox_xchacha20poly1305_macbytes(void); + +#define crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX \ + (crypto_stream_xchacha20_MESSAGEBYTES_MAX - crypto_secretbox_xchacha20poly1305_MACBYTES) +SODIUM_EXPORT +size_t crypto_secretbox_xchacha20poly1305_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_secretbox_xchacha20poly1305_easy(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((nonnull(1, 4, 5))); + +SODIUM_EXPORT +int crypto_secretbox_xchacha20poly1305_open_easy(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); + +SODIUM_EXPORT +int crypto_secretbox_xchacha20poly1305_detached(unsigned char *c, + unsigned char *mac, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((nonnull(1, 2, 5, 6))); + +SODIUM_EXPORT +int crypto_secretbox_xchacha20poly1305_open_detached(unsigned char *m, + const unsigned char *c, + const unsigned char *mac, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 3, 5, 6))); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_secretbox_xsalsa20poly1305.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_secretbox_xsalsa20poly1305.h new file mode 100644 index 0000000..be0874c --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_secretbox_xsalsa20poly1305.h @@ -0,0 +1,69 @@ +#ifndef crypto_secretbox_xsalsa20poly1305_H +#define crypto_secretbox_xsalsa20poly1305_H + +#include +#include "crypto_stream_xsalsa20.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_secretbox_xsalsa20poly1305_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_keybytes(void); + +#define crypto_secretbox_xsalsa20poly1305_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_noncebytes(void); + +#define crypto_secretbox_xsalsa20poly1305_MACBYTES 16U +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_macbytes(void); + +/* Only for the libsodium API - The NaCl compatibility API would require BOXZEROBYTES extra bytes */ +#define crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX \ + (crypto_stream_xsalsa20_MESSAGEBYTES_MAX - crypto_secretbox_xsalsa20poly1305_MACBYTES) +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_secretbox_xsalsa20poly1305(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((nonnull(1, 4, 5))); + +SODIUM_EXPORT +int crypto_secretbox_xsalsa20poly1305_open(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); + +SODIUM_EXPORT +void crypto_secretbox_xsalsa20poly1305_keygen(unsigned char k[crypto_secretbox_xsalsa20poly1305_KEYBYTES]) + __attribute__ ((nonnull)); + +/* -- NaCl compatibility interface ; Requires padding -- */ + +#define crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES 16U +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_boxzerobytes(void); + +#define crypto_secretbox_xsalsa20poly1305_ZEROBYTES \ + (crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES + \ + crypto_secretbox_xsalsa20poly1305_MACBYTES) +SODIUM_EXPORT +size_t crypto_secretbox_xsalsa20poly1305_zerobytes(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_secretstream_xchacha20poly1305.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_secretstream_xchacha20poly1305.h new file mode 100644 index 0000000..b22e4e9 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_secretstream_xchacha20poly1305.h @@ -0,0 +1,108 @@ +#ifndef crypto_secretstream_xchacha20poly1305_H +#define crypto_secretstream_xchacha20poly1305_H + +#include + +#include "crypto_aead_xchacha20poly1305.h" +#include "crypto_stream_chacha20.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_secretstream_xchacha20poly1305_ABYTES \ + (1U + crypto_aead_xchacha20poly1305_ietf_ABYTES) +SODIUM_EXPORT +size_t crypto_secretstream_xchacha20poly1305_abytes(void); + +#define crypto_secretstream_xchacha20poly1305_HEADERBYTES \ + crypto_aead_xchacha20poly1305_ietf_NPUBBYTES +SODIUM_EXPORT +size_t crypto_secretstream_xchacha20poly1305_headerbytes(void); + +#define crypto_secretstream_xchacha20poly1305_KEYBYTES \ + crypto_aead_xchacha20poly1305_ietf_KEYBYTES +SODIUM_EXPORT +size_t crypto_secretstream_xchacha20poly1305_keybytes(void); + +#define crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX \ + SODIUM_MIN(SODIUM_SIZE_MAX - crypto_secretstream_xchacha20poly1305_ABYTES, \ + (64ULL * ((1ULL << 32) - 2ULL))) +SODIUM_EXPORT +size_t crypto_secretstream_xchacha20poly1305_messagebytes_max(void); + +#define crypto_secretstream_xchacha20poly1305_TAG_MESSAGE 0x00 +SODIUM_EXPORT +unsigned char crypto_secretstream_xchacha20poly1305_tag_message(void); + +#define crypto_secretstream_xchacha20poly1305_TAG_PUSH 0x01 +SODIUM_EXPORT +unsigned char crypto_secretstream_xchacha20poly1305_tag_push(void); + +#define crypto_secretstream_xchacha20poly1305_TAG_REKEY 0x02 +SODIUM_EXPORT +unsigned char crypto_secretstream_xchacha20poly1305_tag_rekey(void); + +#define crypto_secretstream_xchacha20poly1305_TAG_FINAL \ + (crypto_secretstream_xchacha20poly1305_TAG_PUSH | \ + crypto_secretstream_xchacha20poly1305_TAG_REKEY) +SODIUM_EXPORT +unsigned char crypto_secretstream_xchacha20poly1305_tag_final(void); + +typedef struct crypto_secretstream_xchacha20poly1305_state { + unsigned char k[crypto_stream_chacha20_ietf_KEYBYTES]; + unsigned char nonce[crypto_stream_chacha20_ietf_NONCEBYTES]; + unsigned char _pad[8]; +} crypto_secretstream_xchacha20poly1305_state; + +SODIUM_EXPORT +size_t crypto_secretstream_xchacha20poly1305_statebytes(void); + +SODIUM_EXPORT +void crypto_secretstream_xchacha20poly1305_keygen + (unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_secretstream_xchacha20poly1305_init_push + (crypto_secretstream_xchacha20poly1305_state *state, + unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES], + const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_secretstream_xchacha20poly1305_push + (crypto_secretstream_xchacha20poly1305_state *state, + unsigned char *c, unsigned long long *clen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, unsigned char tag) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_secretstream_xchacha20poly1305_init_pull + (crypto_secretstream_xchacha20poly1305_state *state, + const unsigned char header[crypto_secretstream_xchacha20poly1305_HEADERBYTES], + const unsigned char k[crypto_secretstream_xchacha20poly1305_KEYBYTES]) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_secretstream_xchacha20poly1305_pull + (crypto_secretstream_xchacha20poly1305_state *state, + unsigned char *m, unsigned long long *mlen_p, unsigned char *tag_p, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +void crypto_secretstream_xchacha20poly1305_rekey + (crypto_secretstream_xchacha20poly1305_state *state); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_shorthash.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_shorthash.h new file mode 100644 index 0000000..fecaa88 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_shorthash.h @@ -0,0 +1,41 @@ +#ifndef crypto_shorthash_H +#define crypto_shorthash_H + +#include + +#include "crypto_shorthash_siphash24.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_shorthash_BYTES crypto_shorthash_siphash24_BYTES +SODIUM_EXPORT +size_t crypto_shorthash_bytes(void); + +#define crypto_shorthash_KEYBYTES crypto_shorthash_siphash24_KEYBYTES +SODIUM_EXPORT +size_t crypto_shorthash_keybytes(void); + +#define crypto_shorthash_PRIMITIVE "siphash24" +SODIUM_EXPORT +const char *crypto_shorthash_primitive(void); + +SODIUM_EXPORT +int crypto_shorthash(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) + __attribute__ ((nonnull(1, 4))); + +SODIUM_EXPORT +void crypto_shorthash_keygen(unsigned char k[crypto_shorthash_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_shorthash_siphash24.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_shorthash_siphash24.h new file mode 100644 index 0000000..1e6f72a --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_shorthash_siphash24.h @@ -0,0 +1,50 @@ +#ifndef crypto_shorthash_siphash24_H +#define crypto_shorthash_siphash24_H + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +/* -- 64-bit output -- */ + +#define crypto_shorthash_siphash24_BYTES 8U +SODIUM_EXPORT +size_t crypto_shorthash_siphash24_bytes(void); + +#define crypto_shorthash_siphash24_KEYBYTES 16U +SODIUM_EXPORT +size_t crypto_shorthash_siphash24_keybytes(void); + +SODIUM_EXPORT +int crypto_shorthash_siphash24(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) + __attribute__ ((nonnull(1, 4))); + +#ifndef SODIUM_LIBRARY_MINIMAL +/* -- 128-bit output -- */ + +#define crypto_shorthash_siphashx24_BYTES 16U +SODIUM_EXPORT +size_t crypto_shorthash_siphashx24_bytes(void); + +#define crypto_shorthash_siphashx24_KEYBYTES 16U +SODIUM_EXPORT +size_t crypto_shorthash_siphashx24_keybytes(void); + +SODIUM_EXPORT +int crypto_shorthash_siphashx24(unsigned char *out, const unsigned char *in, + unsigned long long inlen, const unsigned char *k) + __attribute__ ((nonnull(1, 4))); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_sign.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_sign.h new file mode 100644 index 0000000..f5fafb1 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_sign.h @@ -0,0 +1,107 @@ +#ifndef crypto_sign_H +#define crypto_sign_H + +/* + * THREAD SAFETY: crypto_sign_keypair() is thread-safe, + * provided that sodium_init() was called before. + * + * Other functions, including crypto_sign_seed_keypair() are always thread-safe. + */ + +#include + +#include "crypto_sign_ed25519.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef crypto_sign_ed25519ph_state crypto_sign_state; + +SODIUM_EXPORT +size_t crypto_sign_statebytes(void); + +#define crypto_sign_BYTES crypto_sign_ed25519_BYTES +SODIUM_EXPORT +size_t crypto_sign_bytes(void); + +#define crypto_sign_SEEDBYTES crypto_sign_ed25519_SEEDBYTES +SODIUM_EXPORT +size_t crypto_sign_seedbytes(void); + +#define crypto_sign_PUBLICKEYBYTES crypto_sign_ed25519_PUBLICKEYBYTES +SODIUM_EXPORT +size_t crypto_sign_publickeybytes(void); + +#define crypto_sign_SECRETKEYBYTES crypto_sign_ed25519_SECRETKEYBYTES +SODIUM_EXPORT +size_t crypto_sign_secretkeybytes(void); + +#define crypto_sign_MESSAGEBYTES_MAX crypto_sign_ed25519_MESSAGEBYTES_MAX +SODIUM_EXPORT +size_t crypto_sign_messagebytes_max(void); + +#define crypto_sign_PRIMITIVE "ed25519" +SODIUM_EXPORT +const char *crypto_sign_primitive(void); + +SODIUM_EXPORT +int crypto_sign_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_sign_keypair(unsigned char *pk, unsigned char *sk) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_sign(unsigned char *sm, unsigned long long *smlen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) __attribute__ ((nonnull(1, 5))); + +SODIUM_EXPORT +int crypto_sign_open(unsigned char *m, unsigned long long *mlen_p, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 5))); + +SODIUM_EXPORT +int crypto_sign_detached(unsigned char *sig, unsigned long long *siglen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) __attribute__ ((nonnull(1, 5))); + +SODIUM_EXPORT +int crypto_sign_verify_detached(const unsigned char *sig, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); + +SODIUM_EXPORT +int crypto_sign_init(crypto_sign_state *state); + +SODIUM_EXPORT +int crypto_sign_update(crypto_sign_state *state, + const unsigned char *m, unsigned long long mlen) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_sign_final_create(crypto_sign_state *state, unsigned char *sig, + unsigned long long *siglen_p, + const unsigned char *sk) + __attribute__ ((nonnull(1, 2, 4))); + +SODIUM_EXPORT +int crypto_sign_final_verify(crypto_sign_state *state, const unsigned char *sig, + const unsigned char *pk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_sign_ed25519.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_sign_ed25519.h new file mode 100644 index 0000000..0fdac42 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_sign_ed25519.h @@ -0,0 +1,124 @@ +#ifndef crypto_sign_ed25519_H +#define crypto_sign_ed25519_H + +#include +#include "crypto_hash_sha512.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef struct crypto_sign_ed25519ph_state { + crypto_hash_sha512_state hs; +} crypto_sign_ed25519ph_state; + +SODIUM_EXPORT +size_t crypto_sign_ed25519ph_statebytes(void); + +#define crypto_sign_ed25519_BYTES 64U +SODIUM_EXPORT +size_t crypto_sign_ed25519_bytes(void); + +#define crypto_sign_ed25519_SEEDBYTES 32U +SODIUM_EXPORT +size_t crypto_sign_ed25519_seedbytes(void); + +#define crypto_sign_ed25519_PUBLICKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_sign_ed25519_publickeybytes(void); + +#define crypto_sign_ed25519_SECRETKEYBYTES (32U + 32U) +SODIUM_EXPORT +size_t crypto_sign_ed25519_secretkeybytes(void); + +#define crypto_sign_ed25519_MESSAGEBYTES_MAX (SODIUM_SIZE_MAX - crypto_sign_ed25519_BYTES) +SODIUM_EXPORT +size_t crypto_sign_ed25519_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_sign_ed25519(unsigned char *sm, unsigned long long *smlen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) + __attribute__ ((nonnull(1, 5))); + +SODIUM_EXPORT +int crypto_sign_ed25519_open(unsigned char *m, unsigned long long *mlen_p, + const unsigned char *sm, unsigned long long smlen, + const unsigned char *pk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 5))); + +SODIUM_EXPORT +int crypto_sign_ed25519_detached(unsigned char *sig, + unsigned long long *siglen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *sk) + __attribute__ ((nonnull(1, 5))); + +SODIUM_EXPORT +int crypto_sign_ed25519_verify_detached(const unsigned char *sig, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *pk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); + +SODIUM_EXPORT +int crypto_sign_ed25519_keypair(unsigned char *pk, unsigned char *sk) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_sign_ed25519_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_sign_ed25519_pk_to_curve25519(unsigned char *curve25519_pk, + const unsigned char *ed25519_pk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_sign_ed25519_sk_to_curve25519(unsigned char *curve25519_sk, + const unsigned char *ed25519_sk) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_sign_ed25519_sk_to_seed(unsigned char *seed, + const unsigned char *sk) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_sign_ed25519ph_init(crypto_sign_ed25519ph_state *state) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_sign_ed25519ph_update(crypto_sign_ed25519ph_state *state, + const unsigned char *m, + unsigned long long mlen) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_sign_ed25519ph_final_create(crypto_sign_ed25519ph_state *state, + unsigned char *sig, + unsigned long long *siglen_p, + const unsigned char *sk) + __attribute__ ((nonnull(1, 2, 4))); + +SODIUM_EXPORT +int crypto_sign_ed25519ph_final_verify(crypto_sign_ed25519ph_state *state, + const unsigned char *sig, + const unsigned char *pk) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_sign_edwards25519sha512batch.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_sign_edwards25519sha512batch.h new file mode 100644 index 0000000..eed158a --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_sign_edwards25519sha512batch.h @@ -0,0 +1,55 @@ +#ifndef crypto_sign_edwards25519sha512batch_H +#define crypto_sign_edwards25519sha512batch_H + +/* + * WARNING: This construction was a prototype, which should not be used + * any more in new projects. + * + * crypto_sign_edwards25519sha512batch is provided for applications + * initially built with NaCl, but as recommended by the author of this + * construction, new applications should use ed25519 instead. + * + * In Sodium, you should use the high-level crypto_sign_*() functions instead. + */ + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_sign_edwards25519sha512batch_BYTES 64U +#define crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES 32U +#define crypto_sign_edwards25519sha512batch_SECRETKEYBYTES (32U + 32U) +#define crypto_sign_edwards25519sha512batch_MESSAGEBYTES_MAX (SODIUM_SIZE_MAX - crypto_sign_edwards25519sha512batch_BYTES) + +SODIUM_EXPORT +int crypto_sign_edwards25519sha512batch(unsigned char *sm, + unsigned long long *smlen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *sk) + __attribute__ ((deprecated)) __attribute__ ((nonnull(1, 5))); + +SODIUM_EXPORT +int crypto_sign_edwards25519sha512batch_open(unsigned char *m, + unsigned long long *mlen_p, + const unsigned char *sm, + unsigned long long smlen, + const unsigned char *pk) + __attribute__ ((deprecated)) __attribute__ ((nonnull(3, 5))); + +SODIUM_EXPORT +int crypto_sign_edwards25519sha512batch_keypair(unsigned char *pk, + unsigned char *sk) + __attribute__ ((deprecated)) __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_stream.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_stream.h new file mode 100644 index 0000000..88dab5f --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_stream.h @@ -0,0 +1,59 @@ +#ifndef crypto_stream_H +#define crypto_stream_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include + +#include "crypto_stream_xsalsa20.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_KEYBYTES crypto_stream_xsalsa20_KEYBYTES +SODIUM_EXPORT +size_t crypto_stream_keybytes(void); + +#define crypto_stream_NONCEBYTES crypto_stream_xsalsa20_NONCEBYTES +SODIUM_EXPORT +size_t crypto_stream_noncebytes(void); + +#define crypto_stream_MESSAGEBYTES_MAX crypto_stream_xsalsa20_MESSAGEBYTES_MAX +SODIUM_EXPORT +size_t crypto_stream_messagebytes_max(void); + +#define crypto_stream_PRIMITIVE "xsalsa20" +SODIUM_EXPORT +const char *crypto_stream_primitive(void); + +SODIUM_EXPORT +int crypto_stream(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_stream_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_stream_keygen(unsigned char k[crypto_stream_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_chacha20.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_chacha20.h new file mode 100644 index 0000000..4088975 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_chacha20.h @@ -0,0 +1,106 @@ +#ifndef crypto_stream_chacha20_H +#define crypto_stream_chacha20_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_chacha20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_chacha20_keybytes(void); + +#define crypto_stream_chacha20_NONCEBYTES 8U +SODIUM_EXPORT +size_t crypto_stream_chacha20_noncebytes(void); + +#define crypto_stream_chacha20_MESSAGEBYTES_MAX SODIUM_SIZE_MAX +SODIUM_EXPORT +size_t crypto_stream_chacha20_messagebytes_max(void); + +/* ChaCha20 with a 64-bit nonce and a 64-bit counter, as originally designed */ + +SODIUM_EXPORT +int crypto_stream_chacha20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_stream_chacha20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_stream_chacha20_keygen(unsigned char k[crypto_stream_chacha20_KEYBYTES]) + __attribute__ ((nonnull)); + +/* ChaCha20 with a 96-bit nonce and a 32-bit counter (IETF) */ + +#define crypto_stream_chacha20_ietf_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_chacha20_ietf_keybytes(void); + +#define crypto_stream_chacha20_ietf_NONCEBYTES 12U +SODIUM_EXPORT +size_t crypto_stream_chacha20_ietf_noncebytes(void); + +#define crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX \ + SODIUM_MIN(SODIUM_SIZE_MAX, 64ULL * (1ULL << 32)) +SODIUM_EXPORT +size_t crypto_stream_chacha20_ietf_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_stream_chacha20_ietf(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint32_t ic, + const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_stream_chacha20_ietf_keygen(unsigned char k[crypto_stream_chacha20_ietf_KEYBYTES]) + __attribute__ ((nonnull)); + +/* Aliases */ + +#define crypto_stream_chacha20_IETF_KEYBYTES crypto_stream_chacha20_ietf_KEYBYTES +#define crypto_stream_chacha20_IETF_NONCEBYTES crypto_stream_chacha20_ietf_NONCEBYTES +#define crypto_stream_chacha20_IETF_MESSAGEBYTES_MAX crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_salsa20.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_salsa20.h new file mode 100644 index 0000000..45b3b3e --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_salsa20.h @@ -0,0 +1,61 @@ +#ifndef crypto_stream_salsa20_H +#define crypto_stream_salsa20_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_salsa20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_salsa20_keybytes(void); + +#define crypto_stream_salsa20_NONCEBYTES 8U +SODIUM_EXPORT +size_t crypto_stream_salsa20_noncebytes(void); + +#define crypto_stream_salsa20_MESSAGEBYTES_MAX SODIUM_SIZE_MAX +SODIUM_EXPORT +size_t crypto_stream_salsa20_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_stream_salsa20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_stream_salsa20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_stream_salsa20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_stream_salsa20_keygen(unsigned char k[crypto_stream_salsa20_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_salsa2012.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_salsa2012.h new file mode 100644 index 0000000..6c5d303 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_salsa2012.h @@ -0,0 +1,53 @@ +#ifndef crypto_stream_salsa2012_H +#define crypto_stream_salsa2012_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_salsa2012_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_salsa2012_keybytes(void); + +#define crypto_stream_salsa2012_NONCEBYTES 8U +SODIUM_EXPORT +size_t crypto_stream_salsa2012_noncebytes(void); + +#define crypto_stream_salsa2012_MESSAGEBYTES_MAX SODIUM_SIZE_MAX +SODIUM_EXPORT +size_t crypto_stream_salsa2012_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_stream_salsa2012(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_stream_salsa2012_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_stream_salsa2012_keygen(unsigned char k[crypto_stream_salsa2012_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_salsa208.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_salsa208.h new file mode 100644 index 0000000..d574f30 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_salsa208.h @@ -0,0 +1,56 @@ +#ifndef crypto_stream_salsa208_H +#define crypto_stream_salsa208_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_salsa208_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_salsa208_keybytes(void) + __attribute__ ((deprecated)); + +#define crypto_stream_salsa208_NONCEBYTES 8U +SODIUM_EXPORT +size_t crypto_stream_salsa208_noncebytes(void) + __attribute__ ((deprecated)); + +#define crypto_stream_salsa208_MESSAGEBYTES_MAX SODIUM_SIZE_MAX + SODIUM_EXPORT +size_t crypto_stream_salsa208_messagebytes_max(void) + __attribute__ ((deprecated)); + +SODIUM_EXPORT +int crypto_stream_salsa208(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) + __attribute__ ((deprecated)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_stream_salsa208_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((deprecated)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_stream_salsa208_keygen(unsigned char k[crypto_stream_salsa208_KEYBYTES]) + __attribute__ ((deprecated)) __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_xchacha20.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_xchacha20.h new file mode 100644 index 0000000..c4002db --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_xchacha20.h @@ -0,0 +1,61 @@ +#ifndef crypto_stream_xchacha20_H +#define crypto_stream_xchacha20_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_xchacha20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_xchacha20_keybytes(void); + +#define crypto_stream_xchacha20_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_stream_xchacha20_noncebytes(void); + +#define crypto_stream_xchacha20_MESSAGEBYTES_MAX SODIUM_SIZE_MAX +SODIUM_EXPORT +size_t crypto_stream_xchacha20_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_stream_xchacha20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_stream_xchacha20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_stream_xchacha20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_stream_xchacha20_keygen(unsigned char k[crypto_stream_xchacha20_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_xsalsa20.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_xsalsa20.h new file mode 100644 index 0000000..20034e3 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_stream_xsalsa20.h @@ -0,0 +1,61 @@ +#ifndef crypto_stream_xsalsa20_H +#define crypto_stream_xsalsa20_H + +/* + * WARNING: This is just a stream cipher. It is NOT authenticated encryption. + * While it provides some protection against eavesdropping, it does NOT + * provide any security against active attacks. + * Unless you know what you're doing, what you are looking for is probably + * the crypto_box functions. + */ + +#include +#include +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_stream_xsalsa20_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_stream_xsalsa20_keybytes(void); + +#define crypto_stream_xsalsa20_NONCEBYTES 24U +SODIUM_EXPORT +size_t crypto_stream_xsalsa20_noncebytes(void); + +#define crypto_stream_xsalsa20_MESSAGEBYTES_MAX SODIUM_SIZE_MAX +SODIUM_EXPORT +size_t crypto_stream_xsalsa20_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_stream_xsalsa20(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_stream_xsalsa20_xor(unsigned char *c, const unsigned char *m, + unsigned long long mlen, const unsigned char *n, + const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_stream_xsalsa20_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint64_t ic, + const unsigned char *k) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_stream_xsalsa20_keygen(unsigned char k[crypto_stream_xsalsa20_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_verify_16.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_verify_16.h new file mode 100644 index 0000000..7b9c807 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_verify_16.h @@ -0,0 +1,23 @@ +#ifndef crypto_verify_16_H +#define crypto_verify_16_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_verify_16_BYTES 16U +SODIUM_EXPORT +size_t crypto_verify_16_bytes(void); + +SODIUM_EXPORT +int crypto_verify_16(const unsigned char *x, const unsigned char *y) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_verify_32.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_verify_32.h new file mode 100644 index 0000000..9b0f452 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_verify_32.h @@ -0,0 +1,23 @@ +#ifndef crypto_verify_32_H +#define crypto_verify_32_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_verify_32_BYTES 32U +SODIUM_EXPORT +size_t crypto_verify_32_bytes(void); + +SODIUM_EXPORT +int crypto_verify_32(const unsigned char *x, const unsigned char *y) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/crypto_verify_64.h b/external/src/libsodium/src/libsodium/include/sodium/crypto_verify_64.h new file mode 100644 index 0000000..c83b730 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/crypto_verify_64.h @@ -0,0 +1,23 @@ +#ifndef crypto_verify_64_H +#define crypto_verify_64_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_verify_64_BYTES 64U +SODIUM_EXPORT +size_t crypto_verify_64_bytes(void); + +SODIUM_EXPORT +int crypto_verify_64(const unsigned char *x, const unsigned char *y) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/export.h b/external/src/libsodium/src/libsodium/include/sodium/export.h new file mode 100644 index 0000000..a0074fc --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/export.h @@ -0,0 +1,57 @@ + +#ifndef sodium_export_H +#define sodium_export_H + +#include +#include +#include + +#if !defined(__clang__) && !defined(__GNUC__) +# ifdef __attribute__ +# undef __attribute__ +# endif +# define __attribute__(a) +#endif + +#ifdef SODIUM_STATIC +# define SODIUM_EXPORT +# define SODIUM_EXPORT_WEAK +#else +# if defined(_MSC_VER) +# ifdef SODIUM_DLL_EXPORT +# define SODIUM_EXPORT __declspec(dllexport) +# else +# define SODIUM_EXPORT __declspec(dllimport) +# endif +# else +# if defined(__SUNPRO_C) +# ifndef __GNU_C__ +# define SODIUM_EXPORT __attribute__ (visibility(__global)) +# else +# define SODIUM_EXPORT __attribute__ __global +# endif +# elif defined(_MSG_VER) +# define SODIUM_EXPORT extern __declspec(dllexport) +# else +# define SODIUM_EXPORT __attribute__ ((visibility ("default"))) +# endif +# endif +# if defined(__ELF__) && !defined(SODIUM_DISABLE_WEAK_FUNCTIONS) +# define SODIUM_EXPORT_WEAK SODIUM_EXPORT __attribute__((weak)) +# else +# define SODIUM_EXPORT_WEAK SODIUM_EXPORT +# endif +#endif + +#ifndef CRYPTO_ALIGN +# if defined(__INTEL_COMPILER) || defined(_MSC_VER) +# define CRYPTO_ALIGN(x) __declspec(align(x)) +# else +# define CRYPTO_ALIGN(x) __attribute__ ((aligned(x))) +# endif +#endif + +#define SODIUM_MIN(A, B) ((A) < (B) ? (A) : (B)) +#define SODIUM_SIZE_MAX SODIUM_MIN(UINT64_MAX, SIZE_MAX) + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/private/chacha20_ietf_ext.h b/external/src/libsodium/src/libsodium/include/sodium/private/chacha20_ietf_ext.h new file mode 100644 index 0000000..2c80b96 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/private/chacha20_ietf_ext.h @@ -0,0 +1,16 @@ +#ifndef chacha20_ietf_ext_H +#define chacha20_ietf_ext_H + +#include + +/* The ietf_ext variant allows the internal counter to overflow into the IV */ + +int crypto_stream_chacha20_ietf_ext(unsigned char *c, unsigned long long clen, + const unsigned char *n, const unsigned char *k); + +int crypto_stream_chacha20_ietf_ext_xor_ic(unsigned char *c, const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, uint32_t ic, + const unsigned char *k); +#endif + diff --git a/external/src/libsodium/src/libsodium/include/sodium/private/common.h b/external/src/libsodium/src/libsodium/include/sodium/private/common.h new file mode 100644 index 0000000..339e725 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/private/common.h @@ -0,0 +1,261 @@ +#ifndef common_H +#define common_H 1 + +#if !defined(_MSC_VER) && !defined(DEV_MODE) && 0 +# warning *** This is unstable, untested, development code. +# warning It might not compile. It might not work as expected. +# warning It might be totally insecure. +# warning Do not use this except if you are planning to contribute code. +# warning Use releases available at https://download.libsodium.org/libsodium/releases/ instead. +# warning Alternatively, use the "stable" branch in the git repository. +#endif + +#if !defined(_MSC_VER) && (!defined(CONFIGURED) || CONFIGURED != 1) +# warning *** The library is being compiled using an undocumented method. +# warning This is not supported. It has not been tested, it might not +# warning work as expected, and performance is likely to be suboptimal. +#endif + +#include +#include +#include + +#define COMPILER_ASSERT(X) (void) sizeof(char[(X) ? 1 : -1]) + +#ifdef HAVE_TI_MODE +# if defined(__SIZEOF_INT128__) +typedef unsigned __int128 uint128_t; +# else +typedef unsigned uint128_t __attribute__((mode(TI))); +# endif +#endif + +#define ROTL32(X, B) rotl32((X), (B)) +static inline uint32_t +rotl32(const uint32_t x, const int b) +{ + return (x << b) | (x >> (32 - b)); +} + +#define ROTL64(X, B) rotl64((X), (B)) +static inline uint64_t +rotl64(const uint64_t x, const int b) +{ + return (x << b) | (x >> (64 - b)); +} + +#define ROTR32(X, B) rotr32((X), (B)) +static inline uint32_t +rotr32(const uint32_t x, const int b) +{ + return (x >> b) | (x << (32 - b)); +} + +#define ROTR64(X, B) rotr64((X), (B)) +static inline uint64_t +rotr64(const uint64_t x, const int b) +{ + return (x >> b) | (x << (64 - b)); +} + +#define LOAD64_LE(SRC) load64_le(SRC) +static inline uint64_t +load64_le(const uint8_t src[8]) +{ +#ifdef NATIVE_LITTLE_ENDIAN + uint64_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint64_t w = (uint64_t) src[0]; + w |= (uint64_t) src[1] << 8; + w |= (uint64_t) src[2] << 16; + w |= (uint64_t) src[3] << 24; + w |= (uint64_t) src[4] << 32; + w |= (uint64_t) src[5] << 40; + w |= (uint64_t) src[6] << 48; + w |= (uint64_t) src[7] << 56; + return w; +#endif +} + +#define STORE64_LE(DST, W) store64_le((DST), (W)) +static inline void +store64_le(uint8_t dst[8], uint64_t w) +{ +#ifdef NATIVE_LITTLE_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[0] = (uint8_t) w; w >>= 8; + dst[1] = (uint8_t) w; w >>= 8; + dst[2] = (uint8_t) w; w >>= 8; + dst[3] = (uint8_t) w; w >>= 8; + dst[4] = (uint8_t) w; w >>= 8; + dst[5] = (uint8_t) w; w >>= 8; + dst[6] = (uint8_t) w; w >>= 8; + dst[7] = (uint8_t) w; +#endif +} + +#define LOAD32_LE(SRC) load32_le(SRC) +static inline uint32_t +load32_le(const uint8_t src[4]) +{ +#ifdef NATIVE_LITTLE_ENDIAN + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint32_t w = (uint32_t) src[0]; + w |= (uint32_t) src[1] << 8; + w |= (uint32_t) src[2] << 16; + w |= (uint32_t) src[3] << 24; + return w; +#endif +} + +#define STORE32_LE(DST, W) store32_le((DST), (W)) +static inline void +store32_le(uint8_t dst[4], uint32_t w) +{ +#ifdef NATIVE_LITTLE_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[0] = (uint8_t) w; w >>= 8; + dst[1] = (uint8_t) w; w >>= 8; + dst[2] = (uint8_t) w; w >>= 8; + dst[3] = (uint8_t) w; +#endif +} + +/* ----- */ + +#define LOAD64_BE(SRC) load64_be(SRC) +static inline uint64_t +load64_be(const uint8_t src[8]) +{ +#ifdef NATIVE_BIG_ENDIAN + uint64_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint64_t w = (uint64_t) src[7]; + w |= (uint64_t) src[6] << 8; + w |= (uint64_t) src[5] << 16; + w |= (uint64_t) src[4] << 24; + w |= (uint64_t) src[3] << 32; + w |= (uint64_t) src[2] << 40; + w |= (uint64_t) src[1] << 48; + w |= (uint64_t) src[0] << 56; + return w; +#endif +} + +#define STORE64_BE(DST, W) store64_be((DST), (W)) +static inline void +store64_be(uint8_t dst[8], uint64_t w) +{ +#ifdef NATIVE_BIG_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[7] = (uint8_t) w; w >>= 8; + dst[6] = (uint8_t) w; w >>= 8; + dst[5] = (uint8_t) w; w >>= 8; + dst[4] = (uint8_t) w; w >>= 8; + dst[3] = (uint8_t) w; w >>= 8; + dst[2] = (uint8_t) w; w >>= 8; + dst[1] = (uint8_t) w; w >>= 8; + dst[0] = (uint8_t) w; +#endif +} + +#define LOAD32_BE(SRC) load32_be(SRC) +static inline uint32_t +load32_be(const uint8_t src[4]) +{ +#ifdef NATIVE_BIG_ENDIAN + uint32_t w; + memcpy(&w, src, sizeof w); + return w; +#else + uint32_t w = (uint32_t) src[3]; + w |= (uint32_t) src[2] << 8; + w |= (uint32_t) src[1] << 16; + w |= (uint32_t) src[0] << 24; + return w; +#endif +} + +#define STORE32_BE(DST, W) store32_be((DST), (W)) +static inline void +store32_be(uint8_t dst[4], uint32_t w) +{ +#ifdef NATIVE_BIG_ENDIAN + memcpy(dst, &w, sizeof w); +#else + dst[3] = (uint8_t) w; w >>= 8; + dst[2] = (uint8_t) w; w >>= 8; + dst[1] = (uint8_t) w; w >>= 8; + dst[0] = (uint8_t) w; +#endif +} + +#define XOR_BUF(OUT, IN, N) xor_buf((OUT), (IN), (N)) +static inline void +xor_buf(unsigned char *out, const unsigned char *in, size_t n) +{ + size_t i; + + for (i = 0; i < n; i++) { + out[i] ^= in[i]; + } +} + +#if !defined(__clang__) && !defined(__GNUC__) +# ifdef __attribute__ +# undef __attribute__ +# endif +# define __attribute__(a) +#endif + +#ifndef CRYPTO_ALIGN +# if defined(__INTEL_COMPILER) || defined(_MSC_VER) +# define CRYPTO_ALIGN(x) __declspec(align(x)) +# else +# define CRYPTO_ALIGN(x) __attribute__ ((aligned(x))) +# endif +#endif + +#if defined(_MSC_VER) && \ + (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86)) + +# include + +# define HAVE_INTRIN_H 1 +# define HAVE_MMINTRIN_H 1 +# define HAVE_EMMINTRIN_H 1 +# define HAVE_PMMINTRIN_H 1 +# define HAVE_TMMINTRIN_H 1 +# define HAVE_SMMINTRIN_H 1 +# define HAVE_AVXINTRIN_H 1 +# if _MSC_VER >= 1600 +# define HAVE_WMMINTRIN_H 1 +# endif +# if _MSC_VER >= 1700 && defined(_M_X64) +# define HAVE_AVX2INTRIN_H 1 +# endif +#elif defined(HAVE_INTRIN_H) +# include +#endif + +#ifdef HAVE_LIBCTGRIND +extern void ct_poison (const void *, size_t); +extern void ct_unpoison(const void *, size_t); +# define POISON(X, L) ct_poison((X), (L)) +# define UNPOISON(X, L) ct_unpoison((X), (L)) +#else +# define POISON(X, L) (void) 0 +# define UNPOISON(X, L) (void) 0 +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/private/ed25519_ref10.h b/external/src/libsodium/src/libsodium/include/sodium/private/ed25519_ref10.h new file mode 100644 index 0000000..3f4c45c --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/private/ed25519_ref10.h @@ -0,0 +1,142 @@ +#ifndef ed25519_ref10_H +#define ed25519_ref10_H + +#include +#include + +/* + fe means field element. + Here the field is \Z/(2^255-19). + */ + +#ifdef HAVE_TI_MODE +typedef uint64_t fe25519[5]; +#else +typedef int32_t fe25519[10]; +#endif + +void fe25519_invert(fe25519 out, const fe25519 z); +void fe25519_frombytes(fe25519 h, const unsigned char *s); +void fe25519_tobytes(unsigned char *s, const fe25519 h); + +#ifdef HAVE_TI_MODE +# include "ed25519_ref10_fe_51.h" +#else +# include "ed25519_ref10_fe_25_5.h" +#endif + + +/* + ge means group element. + + Here the group is the set of pairs (x,y) of field elements + satisfying -x^2 + y^2 = 1 + d x^2y^2 + where d = -121665/121666. + + Representations: + ge25519_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z + ge25519_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT + ge25519_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T + ge25519_precomp (Duif): (y+x,y-x,2dxy) + */ + +typedef struct { + fe25519 X; + fe25519 Y; + fe25519 Z; +} ge25519_p2; + +typedef struct { + fe25519 X; + fe25519 Y; + fe25519 Z; + fe25519 T; +} ge25519_p3; + +typedef struct { + fe25519 X; + fe25519 Y; + fe25519 Z; + fe25519 T; +} ge25519_p1p1; + +typedef struct { + fe25519 yplusx; + fe25519 yminusx; + fe25519 xy2d; +} ge25519_precomp; + +typedef struct { + fe25519 YplusX; + fe25519 YminusX; + fe25519 Z; + fe25519 T2d; +} ge25519_cached; + +void ge25519_tobytes(unsigned char *s, const ge25519_p2 *h); + +void ge25519_p3_tobytes(unsigned char *s, const ge25519_p3 *h); + +int ge25519_frombytes(ge25519_p3 *h, const unsigned char *s); + +int ge25519_frombytes_negate_vartime(ge25519_p3 *h, const unsigned char *s); + +void ge25519_p3_to_cached(ge25519_cached *r, const ge25519_p3 *p); + +void ge25519_p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p); + +void ge25519_p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p); + +void ge25519_add(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q); + +void ge25519_sub(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q); + +void ge25519_scalarmult_base(ge25519_p3 *h, const unsigned char *a); + +void ge25519_double_scalarmult_vartime(ge25519_p2 *r, const unsigned char *a, + const ge25519_p3 *A, + const unsigned char *b); + +void ge25519_scalarmult(ge25519_p3 *h, const unsigned char *a, + const ge25519_p3 *p); + +int ge25519_is_canonical(const unsigned char *s); + +int ge25519_is_on_curve(const ge25519_p3 *p); + +int ge25519_is_on_main_subgroup(const ge25519_p3 *p); + +int ge25519_has_small_order(const unsigned char s[32]); + +void ge25519_from_uniform(unsigned char s[32], const unsigned char r[32]); + +void ge25519_from_hash(unsigned char s[32], const unsigned char h[64]); + +/* + Ristretto group + */ + +int ristretto255_frombytes(ge25519_p3 *h, const unsigned char *s); + +void ristretto255_p3_tobytes(unsigned char *s, const ge25519_p3 *h); + +void ristretto255_from_hash(unsigned char s[32], const unsigned char h[64]); + +/* + The set of scalars is \Z/l + where l = 2^252 + 27742317777372353535851937790883648493. + */ + +void sc25519_invert(unsigned char recip[32], const unsigned char s[32]); + +void sc25519_reduce(unsigned char s[64]); + +void sc25519_mul(unsigned char s[32], const unsigned char a[32], + const unsigned char b[32]); + +void sc25519_muladd(unsigned char s[32], const unsigned char a[32], + const unsigned char b[32], const unsigned char c[32]); + +int sc25519_is_canonical(const unsigned char s[32]); + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/private/ed25519_ref10_fe_25_5.h b/external/src/libsodium/src/libsodium/include/sodium/private/ed25519_ref10_fe_25_5.h new file mode 100644 index 0000000..f2782d9 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/private/ed25519_ref10_fe_25_5.h @@ -0,0 +1,1050 @@ +#include + +#include "private/common.h" +#include "utils.h" + +/* + h = 0 + */ + +static inline void +fe25519_0(fe25519 h) +{ + memset(&h[0], 0, 10 * sizeof h[0]); +} + +/* + h = 1 + */ + +static inline void +fe25519_1(fe25519 h) +{ + h[0] = 1; + h[1] = 0; + memset(&h[2], 0, 8 * sizeof h[0]); +} + +/* + h = f + g + Can overlap h with f or g. + * + Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * + Postconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + */ + +static inline void +fe25519_add(fe25519 h, const fe25519 f, const fe25519 g) +{ + int32_t h0 = f[0] + g[0]; + int32_t h1 = f[1] + g[1]; + int32_t h2 = f[2] + g[2]; + int32_t h3 = f[3] + g[3]; + int32_t h4 = f[4] + g[4]; + int32_t h5 = f[5] + g[5]; + int32_t h6 = f[6] + g[6]; + int32_t h7 = f[7] + g[7]; + int32_t h8 = f[8] + g[8]; + int32_t h9 = f[9] + g[9]; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* + h = f - g + Can overlap h with f or g. + * + Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + |g| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * + Postconditions: + |h| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + */ + +static void +fe25519_sub(fe25519 h, const fe25519 f, const fe25519 g) +{ + int32_t h0 = f[0] - g[0]; + int32_t h1 = f[1] - g[1]; + int32_t h2 = f[2] - g[2]; + int32_t h3 = f[3] - g[3]; + int32_t h4 = f[4] - g[4]; + int32_t h5 = f[5] - g[5]; + int32_t h6 = f[6] - g[6]; + int32_t h7 = f[7] - g[7]; + int32_t h8 = f[8] - g[8]; + int32_t h9 = f[9] - g[9]; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* + h = -f + * + Preconditions: + |f| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + * + Postconditions: + |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. + */ + +static inline void +fe25519_neg(fe25519 h, const fe25519 f) +{ + int32_t h0 = -f[0]; + int32_t h1 = -f[1]; + int32_t h2 = -f[2]; + int32_t h3 = -f[3]; + int32_t h4 = -f[4]; + int32_t h5 = -f[5]; + int32_t h6 = -f[6]; + int32_t h7 = -f[7]; + int32_t h8 = -f[8]; + int32_t h9 = -f[9]; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; +} + +/* + Replace (f,g) with (g,g) if b == 1; + replace (f,g) with (f,g) if b == 0. + * + Preconditions: b in {0,1}. + */ + +static void +fe25519_cmov(fe25519 f, const fe25519 g, unsigned int b) +{ + const uint32_t mask = (uint32_t) (-(int32_t) b); + + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + + int32_t x0 = f0 ^ g[0]; + int32_t x1 = f1 ^ g[1]; + int32_t x2 = f2 ^ g[2]; + int32_t x3 = f3 ^ g[3]; + int32_t x4 = f4 ^ g[4]; + int32_t x5 = f5 ^ g[5]; + int32_t x6 = f6 ^ g[6]; + int32_t x7 = f7 ^ g[7]; + int32_t x8 = f8 ^ g[8]; + int32_t x9 = f9 ^ g[9]; + + x0 &= mask; + x1 &= mask; + x2 &= mask; + x3 &= mask; + x4 &= mask; + x5 &= mask; + x6 &= mask; + x7 &= mask; + x8 &= mask; + x9 &= mask; + + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; + f[5] = f5 ^ x5; + f[6] = f6 ^ x6; + f[7] = f7 ^ x7; + f[8] = f8 ^ x8; + f[9] = f9 ^ x9; +} + +static void +fe25519_cswap(fe25519 f, fe25519 g, unsigned int b) +{ + const uint32_t mask = (uint32_t) (-(int64_t) b); + + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + + int32_t x0 = f0 ^ g0; + int32_t x1 = f1 ^ g1; + int32_t x2 = f2 ^ g2; + int32_t x3 = f3 ^ g3; + int32_t x4 = f4 ^ g4; + int32_t x5 = f5 ^ g5; + int32_t x6 = f6 ^ g6; + int32_t x7 = f7 ^ g7; + int32_t x8 = f8 ^ g8; + int32_t x9 = f9 ^ g9; + + x0 &= mask; + x1 &= mask; + x2 &= mask; + x3 &= mask; + x4 &= mask; + x5 &= mask; + x6 &= mask; + x7 &= mask; + x8 &= mask; + x9 &= mask; + + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; + f[5] = f5 ^ x5; + f[6] = f6 ^ x6; + f[7] = f7 ^ x7; + f[8] = f8 ^ x8; + f[9] = f9 ^ x9; + + g[0] = g0 ^ x0; + g[1] = g1 ^ x1; + g[2] = g2 ^ x2; + g[3] = g3 ^ x3; + g[4] = g4 ^ x4; + g[5] = g5 ^ x5; + g[6] = g6 ^ x6; + g[7] = g7 ^ x7; + g[8] = g8 ^ x8; + g[9] = g9 ^ x9; +} + +/* + h = f + */ + +static inline void +fe25519_copy(fe25519 h, const fe25519 f) +{ + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + + h[0] = f0; + h[1] = f1; + h[2] = f2; + h[3] = f3; + h[4] = f4; + h[5] = f5; + h[6] = f6; + h[7] = f7; + h[8] = f8; + h[9] = f9; +} + +/* + return 1 if f is in {1,3,5,...,q-2} + return 0 if f is in {0,2,4,...,q-1} + + Preconditions: + |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + */ + +static inline int +fe25519_isnegative(const fe25519 f) +{ + unsigned char s[32]; + + fe25519_tobytes(s, f); + + return s[0] & 1; +} + +/* + return 1 if f == 0 + return 0 if f != 0 + + Preconditions: + |f| bounded by 1.1*2^26,1.1*2^25,1.1*2^26,1.1*2^25,etc. + */ + +static inline int +fe25519_iszero(const fe25519 f) +{ + unsigned char s[32]; + + fe25519_tobytes(s, f); + + return sodium_is_zero(s, 32); +} + +/* + h = f * g + Can overlap h with f or g. + * + Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + |g| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + * + Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. + */ + +/* + Notes on implementation strategy: + * + Using schoolbook multiplication. + Karatsuba would save a little in some cost models. + * + Most multiplications by 2 and 19 are 32-bit precomputations; + cheaper than 64-bit postcomputations. + * + There is one remaining multiplication by 19 in the carry chain; + one *19 precomputation can be merged into this, + but the resulting data flow is considerably less clean. + * + There are 12 carries below. + 10 of them are 2-way parallelizable and vectorizable. + Can get away with 11 carries, but then data flow is much deeper. + * + With tighter constraints on inputs can squeeze carries into int32. + */ + +static void +fe25519_mul(fe25519 h, const fe25519 f, const fe25519 g) +{ + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + + int32_t g0 = g[0]; + int32_t g1 = g[1]; + int32_t g2 = g[2]; + int32_t g3 = g[3]; + int32_t g4 = g[4]; + int32_t g5 = g[5]; + int32_t g6 = g[6]; + int32_t g7 = g[7]; + int32_t g8 = g[8]; + int32_t g9 = g[9]; + + int32_t g1_19 = 19 * g1; /* 1.959375*2^29 */ + int32_t g2_19 = 19 * g2; /* 1.959375*2^30; still ok */ + int32_t g3_19 = 19 * g3; + int32_t g4_19 = 19 * g4; + int32_t g5_19 = 19 * g5; + int32_t g6_19 = 19 * g6; + int32_t g7_19 = 19 * g7; + int32_t g8_19 = 19 * g8; + int32_t g9_19 = 19 * g9; + int32_t f1_2 = 2 * f1; + int32_t f3_2 = 2 * f3; + int32_t f5_2 = 2 * f5; + int32_t f7_2 = 2 * f7; + int32_t f9_2 = 2 * f9; + + int64_t f0g0 = f0 * (int64_t) g0; + int64_t f0g1 = f0 * (int64_t) g1; + int64_t f0g2 = f0 * (int64_t) g2; + int64_t f0g3 = f0 * (int64_t) g3; + int64_t f0g4 = f0 * (int64_t) g4; + int64_t f0g5 = f0 * (int64_t) g5; + int64_t f0g6 = f0 * (int64_t) g6; + int64_t f0g7 = f0 * (int64_t) g7; + int64_t f0g8 = f0 * (int64_t) g8; + int64_t f0g9 = f0 * (int64_t) g9; + int64_t f1g0 = f1 * (int64_t) g0; + int64_t f1g1_2 = f1_2 * (int64_t) g1; + int64_t f1g2 = f1 * (int64_t) g2; + int64_t f1g3_2 = f1_2 * (int64_t) g3; + int64_t f1g4 = f1 * (int64_t) g4; + int64_t f1g5_2 = f1_2 * (int64_t) g5; + int64_t f1g6 = f1 * (int64_t) g6; + int64_t f1g7_2 = f1_2 * (int64_t) g7; + int64_t f1g8 = f1 * (int64_t) g8; + int64_t f1g9_38 = f1_2 * (int64_t) g9_19; + int64_t f2g0 = f2 * (int64_t) g0; + int64_t f2g1 = f2 * (int64_t) g1; + int64_t f2g2 = f2 * (int64_t) g2; + int64_t f2g3 = f2 * (int64_t) g3; + int64_t f2g4 = f2 * (int64_t) g4; + int64_t f2g5 = f2 * (int64_t) g5; + int64_t f2g6 = f2 * (int64_t) g6; + int64_t f2g7 = f2 * (int64_t) g7; + int64_t f2g8_19 = f2 * (int64_t) g8_19; + int64_t f2g9_19 = f2 * (int64_t) g9_19; + int64_t f3g0 = f3 * (int64_t) g0; + int64_t f3g1_2 = f3_2 * (int64_t) g1; + int64_t f3g2 = f3 * (int64_t) g2; + int64_t f3g3_2 = f3_2 * (int64_t) g3; + int64_t f3g4 = f3 * (int64_t) g4; + int64_t f3g5_2 = f3_2 * (int64_t) g5; + int64_t f3g6 = f3 * (int64_t) g6; + int64_t f3g7_38 = f3_2 * (int64_t) g7_19; + int64_t f3g8_19 = f3 * (int64_t) g8_19; + int64_t f3g9_38 = f3_2 * (int64_t) g9_19; + int64_t f4g0 = f4 * (int64_t) g0; + int64_t f4g1 = f4 * (int64_t) g1; + int64_t f4g2 = f4 * (int64_t) g2; + int64_t f4g3 = f4 * (int64_t) g3; + int64_t f4g4 = f4 * (int64_t) g4; + int64_t f4g5 = f4 * (int64_t) g5; + int64_t f4g6_19 = f4 * (int64_t) g6_19; + int64_t f4g7_19 = f4 * (int64_t) g7_19; + int64_t f4g8_19 = f4 * (int64_t) g8_19; + int64_t f4g9_19 = f4 * (int64_t) g9_19; + int64_t f5g0 = f5 * (int64_t) g0; + int64_t f5g1_2 = f5_2 * (int64_t) g1; + int64_t f5g2 = f5 * (int64_t) g2; + int64_t f5g3_2 = f5_2 * (int64_t) g3; + int64_t f5g4 = f5 * (int64_t) g4; + int64_t f5g5_38 = f5_2 * (int64_t) g5_19; + int64_t f5g6_19 = f5 * (int64_t) g6_19; + int64_t f5g7_38 = f5_2 * (int64_t) g7_19; + int64_t f5g8_19 = f5 * (int64_t) g8_19; + int64_t f5g9_38 = f5_2 * (int64_t) g9_19; + int64_t f6g0 = f6 * (int64_t) g0; + int64_t f6g1 = f6 * (int64_t) g1; + int64_t f6g2 = f6 * (int64_t) g2; + int64_t f6g3 = f6 * (int64_t) g3; + int64_t f6g4_19 = f6 * (int64_t) g4_19; + int64_t f6g5_19 = f6 * (int64_t) g5_19; + int64_t f6g6_19 = f6 * (int64_t) g6_19; + int64_t f6g7_19 = f6 * (int64_t) g7_19; + int64_t f6g8_19 = f6 * (int64_t) g8_19; + int64_t f6g9_19 = f6 * (int64_t) g9_19; + int64_t f7g0 = f7 * (int64_t) g0; + int64_t f7g1_2 = f7_2 * (int64_t) g1; + int64_t f7g2 = f7 * (int64_t) g2; + int64_t f7g3_38 = f7_2 * (int64_t) g3_19; + int64_t f7g4_19 = f7 * (int64_t) g4_19; + int64_t f7g5_38 = f7_2 * (int64_t) g5_19; + int64_t f7g6_19 = f7 * (int64_t) g6_19; + int64_t f7g7_38 = f7_2 * (int64_t) g7_19; + int64_t f7g8_19 = f7 * (int64_t) g8_19; + int64_t f7g9_38 = f7_2 * (int64_t) g9_19; + int64_t f8g0 = f8 * (int64_t) g0; + int64_t f8g1 = f8 * (int64_t) g1; + int64_t f8g2_19 = f8 * (int64_t) g2_19; + int64_t f8g3_19 = f8 * (int64_t) g3_19; + int64_t f8g4_19 = f8 * (int64_t) g4_19; + int64_t f8g5_19 = f8 * (int64_t) g5_19; + int64_t f8g6_19 = f8 * (int64_t) g6_19; + int64_t f8g7_19 = f8 * (int64_t) g7_19; + int64_t f8g8_19 = f8 * (int64_t) g8_19; + int64_t f8g9_19 = f8 * (int64_t) g9_19; + int64_t f9g0 = f9 * (int64_t) g0; + int64_t f9g1_38 = f9_2 * (int64_t) g1_19; + int64_t f9g2_19 = f9 * (int64_t) g2_19; + int64_t f9g3_38 = f9_2 * (int64_t) g3_19; + int64_t f9g4_19 = f9 * (int64_t) g4_19; + int64_t f9g5_38 = f9_2 * (int64_t) g5_19; + int64_t f9g6_19 = f9 * (int64_t) g6_19; + int64_t f9g7_38 = f9_2 * (int64_t) g7_19; + int64_t f9g8_19 = f9 * (int64_t) g8_19; + int64_t f9g9_38 = f9_2 * (int64_t) g9_19; + + int64_t h0 = f0g0 + f1g9_38 + f2g8_19 + f3g7_38 + f4g6_19 + f5g5_38 + + f6g4_19 + f7g3_38 + f8g2_19 + f9g1_38; + int64_t h1 = f0g1 + f1g0 + f2g9_19 + f3g8_19 + f4g7_19 + f5g6_19 + f6g5_19 + + f7g4_19 + f8g3_19 + f9g2_19; + int64_t h2 = f0g2 + f1g1_2 + f2g0 + f3g9_38 + f4g8_19 + f5g7_38 + f6g6_19 + + f7g5_38 + f8g4_19 + f9g3_38; + int64_t h3 = f0g3 + f1g2 + f2g1 + f3g0 + f4g9_19 + f5g8_19 + f6g7_19 + + f7g6_19 + f8g5_19 + f9g4_19; + int64_t h4 = f0g4 + f1g3_2 + f2g2 + f3g1_2 + f4g0 + f5g9_38 + f6g8_19 + + f7g7_38 + f8g6_19 + f9g5_38; + int64_t h5 = f0g5 + f1g4 + f2g3 + f3g2 + f4g1 + f5g0 + f6g9_19 + f7g8_19 + + f8g7_19 + f9g6_19; + int64_t h6 = f0g6 + f1g5_2 + f2g4 + f3g3_2 + f4g2 + f5g1_2 + f6g0 + + f7g9_38 + f8g8_19 + f9g7_38; + int64_t h7 = f0g7 + f1g6 + f2g5 + f3g4 + f4g3 + f5g2 + f6g1 + f7g0 + + f8g9_19 + f9g8_19; + int64_t h8 = f0g8 + f1g7_2 + f2g6 + f3g5_2 + f4g4 + f5g3_2 + f6g2 + f7g1_2 + + f8g0 + f9g9_38; + int64_t h9 = + f0g9 + f1g8 + f2g7 + f3g6 + f4g5 + f5g4 + f6g3 + f7g2 + f8g1 + f9g0; + + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + /* + |h0| <= (1.65*1.65*2^52*(1+19+19+19+19)+1.65*1.65*2^50*(38+38+38+38+38)) + i.e. |h0| <= 1.4*2^60; narrower ranges for h2, h4, h6, h8 + |h1| <= (1.65*1.65*2^51*(1+1+19+19+19+19+19+19+19+19)) + i.e. |h1| <= 1.7*2^59; narrower ranges for h3, h5, h7, h9 + */ + + carry0 = (h0 + (int64_t)(1L << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((uint64_t) 1L << 26); + carry4 = (h4 + (int64_t)(1L << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((uint64_t) 1L << 26); + /* |h0| <= 2^25 */ + /* |h4| <= 2^25 */ + /* |h1| <= 1.71*2^59 */ + /* |h5| <= 1.71*2^59 */ + + carry1 = (h1 + (int64_t)(1L << 24)) >> 25; + h2 += carry1; + h1 -= carry1 * ((uint64_t) 1L << 25); + carry5 = (h5 + (int64_t)(1L << 24)) >> 25; + h6 += carry5; + h5 -= carry5 * ((uint64_t) 1L << 25); + /* |h1| <= 2^24; from now on fits into int32 */ + /* |h5| <= 2^24; from now on fits into int32 */ + /* |h2| <= 1.41*2^60 */ + /* |h6| <= 1.41*2^60 */ + + carry2 = (h2 + (int64_t)(1L << 25)) >> 26; + h3 += carry2; + h2 -= carry2 * ((uint64_t) 1L << 26); + carry6 = (h6 + (int64_t)(1L << 25)) >> 26; + h7 += carry6; + h6 -= carry6 * ((uint64_t) 1L << 26); + /* |h2| <= 2^25; from now on fits into int32 unchanged */ + /* |h6| <= 2^25; from now on fits into int32 unchanged */ + /* |h3| <= 1.71*2^59 */ + /* |h7| <= 1.71*2^59 */ + + carry3 = (h3 + (int64_t)(1L << 24)) >> 25; + h4 += carry3; + h3 -= carry3 * ((uint64_t) 1L << 25); + carry7 = (h7 + (int64_t)(1L << 24)) >> 25; + h8 += carry7; + h7 -= carry7 * ((uint64_t) 1L << 25); + /* |h3| <= 2^24; from now on fits into int32 unchanged */ + /* |h7| <= 2^24; from now on fits into int32 unchanged */ + /* |h4| <= 1.72*2^34 */ + /* |h8| <= 1.41*2^60 */ + + carry4 = (h4 + (int64_t)(1L << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((uint64_t) 1L << 26); + carry8 = (h8 + (int64_t)(1L << 25)) >> 26; + h9 += carry8; + h8 -= carry8 * ((uint64_t) 1L << 26); + /* |h4| <= 2^25; from now on fits into int32 unchanged */ + /* |h8| <= 2^25; from now on fits into int32 unchanged */ + /* |h5| <= 1.01*2^24 */ + /* |h9| <= 1.71*2^59 */ + + carry9 = (h9 + (int64_t)(1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= carry9 * ((uint64_t) 1L << 25); + /* |h9| <= 2^24; from now on fits into int32 unchanged */ + /* |h0| <= 1.1*2^39 */ + + carry0 = (h0 + (int64_t)(1L << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((uint64_t) 1L << 26); + /* |h0| <= 2^25; from now on fits into int32 unchanged */ + /* |h1| <= 1.01*2^24 */ + + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; +} + +/* + h = f * f + Can overlap h with f. + * + Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + * + Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. + */ + +static void +fe25519_sq(fe25519 h, const fe25519 f) +{ + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + + int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; + int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; + int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; + int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; + int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; + int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; + int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; + int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; + int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; + int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; + + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + carry0 = (h0 + (int64_t)(1L << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((uint64_t) 1L << 26); + carry4 = (h4 + (int64_t)(1L << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((uint64_t) 1L << 26); + + carry1 = (h1 + (int64_t)(1L << 24)) >> 25; + h2 += carry1; + h1 -= carry1 * ((uint64_t) 1L << 25); + carry5 = (h5 + (int64_t)(1L << 24)) >> 25; + h6 += carry5; + h5 -= carry5 * ((uint64_t) 1L << 25); + + carry2 = (h2 + (int64_t)(1L << 25)) >> 26; + h3 += carry2; + h2 -= carry2 * ((uint64_t) 1L << 26); + carry6 = (h6 + (int64_t)(1L << 25)) >> 26; + h7 += carry6; + h6 -= carry6 * ((uint64_t) 1L << 26); + + carry3 = (h3 + (int64_t)(1L << 24)) >> 25; + h4 += carry3; + h3 -= carry3 * ((uint64_t) 1L << 25); + carry7 = (h7 + (int64_t)(1L << 24)) >> 25; + h8 += carry7; + h7 -= carry7 * ((uint64_t) 1L << 25); + + carry4 = (h4 + (int64_t)(1L << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((uint64_t) 1L << 26); + carry8 = (h8 + (int64_t)(1L << 25)) >> 26; + h9 += carry8; + h8 -= carry8 * ((uint64_t) 1L << 26); + + carry9 = (h9 + (int64_t)(1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= carry9 * ((uint64_t) 1L << 25); + + carry0 = (h0 + (int64_t)(1L << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((uint64_t) 1L << 26); + + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; +} + +/* + h = 2 * f * f + Can overlap h with f. + * + Preconditions: + |f| bounded by 1.65*2^26,1.65*2^25,1.65*2^26,1.65*2^25,etc. + * + Postconditions: + |h| bounded by 1.01*2^25,1.01*2^24,1.01*2^25,1.01*2^24,etc. + */ + +static void +fe25519_sq2(fe25519 h, const fe25519 f) +{ + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + + int32_t f0_2 = 2 * f0; + int32_t f1_2 = 2 * f1; + int32_t f2_2 = 2 * f2; + int32_t f3_2 = 2 * f3; + int32_t f4_2 = 2 * f4; + int32_t f5_2 = 2 * f5; + int32_t f6_2 = 2 * f6; + int32_t f7_2 = 2 * f7; + int32_t f5_38 = 38 * f5; /* 1.959375*2^30 */ + int32_t f6_19 = 19 * f6; /* 1.959375*2^30 */ + int32_t f7_38 = 38 * f7; /* 1.959375*2^30 */ + int32_t f8_19 = 19 * f8; /* 1.959375*2^30 */ + int32_t f9_38 = 38 * f9; /* 1.959375*2^30 */ + + int64_t f0f0 = f0 * (int64_t) f0; + int64_t f0f1_2 = f0_2 * (int64_t) f1; + int64_t f0f2_2 = f0_2 * (int64_t) f2; + int64_t f0f3_2 = f0_2 * (int64_t) f3; + int64_t f0f4_2 = f0_2 * (int64_t) f4; + int64_t f0f5_2 = f0_2 * (int64_t) f5; + int64_t f0f6_2 = f0_2 * (int64_t) f6; + int64_t f0f7_2 = f0_2 * (int64_t) f7; + int64_t f0f8_2 = f0_2 * (int64_t) f8; + int64_t f0f9_2 = f0_2 * (int64_t) f9; + int64_t f1f1_2 = f1_2 * (int64_t) f1; + int64_t f1f2_2 = f1_2 * (int64_t) f2; + int64_t f1f3_4 = f1_2 * (int64_t) f3_2; + int64_t f1f4_2 = f1_2 * (int64_t) f4; + int64_t f1f5_4 = f1_2 * (int64_t) f5_2; + int64_t f1f6_2 = f1_2 * (int64_t) f6; + int64_t f1f7_4 = f1_2 * (int64_t) f7_2; + int64_t f1f8_2 = f1_2 * (int64_t) f8; + int64_t f1f9_76 = f1_2 * (int64_t) f9_38; + int64_t f2f2 = f2 * (int64_t) f2; + int64_t f2f3_2 = f2_2 * (int64_t) f3; + int64_t f2f4_2 = f2_2 * (int64_t) f4; + int64_t f2f5_2 = f2_2 * (int64_t) f5; + int64_t f2f6_2 = f2_2 * (int64_t) f6; + int64_t f2f7_2 = f2_2 * (int64_t) f7; + int64_t f2f8_38 = f2_2 * (int64_t) f8_19; + int64_t f2f9_38 = f2 * (int64_t) f9_38; + int64_t f3f3_2 = f3_2 * (int64_t) f3; + int64_t f3f4_2 = f3_2 * (int64_t) f4; + int64_t f3f5_4 = f3_2 * (int64_t) f5_2; + int64_t f3f6_2 = f3_2 * (int64_t) f6; + int64_t f3f7_76 = f3_2 * (int64_t) f7_38; + int64_t f3f8_38 = f3_2 * (int64_t) f8_19; + int64_t f3f9_76 = f3_2 * (int64_t) f9_38; + int64_t f4f4 = f4 * (int64_t) f4; + int64_t f4f5_2 = f4_2 * (int64_t) f5; + int64_t f4f6_38 = f4_2 * (int64_t) f6_19; + int64_t f4f7_38 = f4 * (int64_t) f7_38; + int64_t f4f8_38 = f4_2 * (int64_t) f8_19; + int64_t f4f9_38 = f4 * (int64_t) f9_38; + int64_t f5f5_38 = f5 * (int64_t) f5_38; + int64_t f5f6_38 = f5_2 * (int64_t) f6_19; + int64_t f5f7_76 = f5_2 * (int64_t) f7_38; + int64_t f5f8_38 = f5_2 * (int64_t) f8_19; + int64_t f5f9_76 = f5_2 * (int64_t) f9_38; + int64_t f6f6_19 = f6 * (int64_t) f6_19; + int64_t f6f7_38 = f6 * (int64_t) f7_38; + int64_t f6f8_38 = f6_2 * (int64_t) f8_19; + int64_t f6f9_38 = f6 * (int64_t) f9_38; + int64_t f7f7_38 = f7 * (int64_t) f7_38; + int64_t f7f8_38 = f7_2 * (int64_t) f8_19; + int64_t f7f9_76 = f7_2 * (int64_t) f9_38; + int64_t f8f8_19 = f8 * (int64_t) f8_19; + int64_t f8f9_38 = f8 * (int64_t) f9_38; + int64_t f9f9_38 = f9 * (int64_t) f9_38; + + int64_t h0 = f0f0 + f1f9_76 + f2f8_38 + f3f7_76 + f4f6_38 + f5f5_38; + int64_t h1 = f0f1_2 + f2f9_38 + f3f8_38 + f4f7_38 + f5f6_38; + int64_t h2 = f0f2_2 + f1f1_2 + f3f9_76 + f4f8_38 + f5f7_76 + f6f6_19; + int64_t h3 = f0f3_2 + f1f2_2 + f4f9_38 + f5f8_38 + f6f7_38; + int64_t h4 = f0f4_2 + f1f3_4 + f2f2 + f5f9_76 + f6f8_38 + f7f7_38; + int64_t h5 = f0f5_2 + f1f4_2 + f2f3_2 + f6f9_38 + f7f8_38; + int64_t h6 = f0f6_2 + f1f5_4 + f2f4_2 + f3f3_2 + f7f9_76 + f8f8_19; + int64_t h7 = f0f7_2 + f1f6_2 + f2f5_2 + f3f4_2 + f8f9_38; + int64_t h8 = f0f8_2 + f1f7_4 + f2f6_2 + f3f5_4 + f4f4 + f9f9_38; + int64_t h9 = f0f9_2 + f1f8_2 + f2f7_2 + f3f6_2 + f4f5_2; + + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + + h0 += h0; + h1 += h1; + h2 += h2; + h3 += h3; + h4 += h4; + h5 += h5; + h6 += h6; + h7 += h7; + h8 += h8; + h9 += h9; + + carry0 = (h0 + (int64_t)(1L << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((uint64_t) 1L << 26); + carry4 = (h4 + (int64_t)(1L << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((uint64_t) 1L << 26); + + carry1 = (h1 + (int64_t)(1L << 24)) >> 25; + h2 += carry1; + h1 -= carry1 * ((uint64_t) 1L << 25); + carry5 = (h5 + (int64_t)(1L << 24)) >> 25; + h6 += carry5; + h5 -= carry5 * ((uint64_t) 1L << 25); + + carry2 = (h2 + (int64_t)(1L << 25)) >> 26; + h3 += carry2; + h2 -= carry2 * ((uint64_t) 1L << 26); + carry6 = (h6 + (int64_t)(1L << 25)) >> 26; + h7 += carry6; + h6 -= carry6 * ((uint64_t) 1L << 26); + + carry3 = (h3 + (int64_t)(1L << 24)) >> 25; + h4 += carry3; + h3 -= carry3 * ((uint64_t) 1L << 25); + carry7 = (h7 + (int64_t)(1L << 24)) >> 25; + h8 += carry7; + h7 -= carry7 * ((uint64_t) 1L << 25); + + carry4 = (h4 + (int64_t)(1L << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((uint64_t) 1L << 26); + carry8 = (h8 + (int64_t)(1L << 25)) >> 26; + h9 += carry8; + h8 -= carry8 * ((uint64_t) 1L << 26); + + carry9 = (h9 + (int64_t)(1L << 24)) >> 25; + h0 += carry9 * 19; + h9 -= carry9 * ((uint64_t) 1L << 25); + + carry0 = (h0 + (int64_t)(1L << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((uint64_t) 1L << 26); + + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; +} + +static void +fe25519_mul32(fe25519 h, const fe25519 f, uint32_t n) +{ + int64_t sn = (int64_t) n; + int32_t f0 = f[0]; + int32_t f1 = f[1]; + int32_t f2 = f[2]; + int32_t f3 = f[3]; + int32_t f4 = f[4]; + int32_t f5 = f[5]; + int32_t f6 = f[6]; + int32_t f7 = f[7]; + int32_t f8 = f[8]; + int32_t f9 = f[9]; + int64_t h0 = f0 * sn; + int64_t h1 = f1 * sn; + int64_t h2 = f2 * sn; + int64_t h3 = f3 * sn; + int64_t h4 = f4 * sn; + int64_t h5 = f5 * sn; + int64_t h6 = f6 * sn; + int64_t h7 = f7 * sn; + int64_t h8 = f8 * sn; + int64_t h9 = f9 * sn; + int64_t carry0, carry1, carry2, carry3, carry4, carry5, carry6, carry7, + carry8, carry9; + + carry9 = (h9 + ((int64_t) 1 << 24)) >> 25; + h0 += carry9 * 19; + h9 -= carry9 * ((int64_t) 1 << 25); + carry1 = (h1 + ((int64_t) 1 << 24)) >> 25; + h2 += carry1; + h1 -= carry1 * ((int64_t) 1 << 25); + carry3 = (h3 + ((int64_t) 1 << 24)) >> 25; + h4 += carry3; + h3 -= carry3 * ((int64_t) 1 << 25); + carry5 = (h5 + ((int64_t) 1 << 24)) >> 25; + h6 += carry5; + h5 -= carry5 * ((int64_t) 1 << 25); + carry7 = (h7 + ((int64_t) 1 << 24)) >> 25; + h8 += carry7; + h7 -= carry7 * ((int64_t) 1 << 25); + + carry0 = (h0 + ((int64_t) 1 << 25)) >> 26; + h1 += carry0; + h0 -= carry0 * ((int64_t) 1 << 26); + carry2 = (h2 + ((int64_t) 1 << 25)) >> 26; + h3 += carry2; + h2 -= carry2 * ((int64_t) 1 << 26); + carry4 = (h4 + ((int64_t) 1 << 25)) >> 26; + h5 += carry4; + h4 -= carry4 * ((int64_t) 1 << 26); + carry6 = (h6 + ((int64_t) 1 << 25)) >> 26; + h7 += carry6; + h6 -= carry6 * ((int64_t) 1 << 26); + carry8 = (h8 + ((int64_t) 1 << 25)) >> 26; + h9 += carry8; + h8 -= carry8 * ((int64_t) 1 << 26); + + h[0] = (int32_t) h0; + h[1] = (int32_t) h1; + h[2] = (int32_t) h2; + h[3] = (int32_t) h3; + h[4] = (int32_t) h4; + h[5] = (int32_t) h5; + h[6] = (int32_t) h6; + h[7] = (int32_t) h7; + h[8] = (int32_t) h8; + h[9] = (int32_t) h9; +} diff --git a/external/src/libsodium/src/libsodium/include/sodium/private/ed25519_ref10_fe_51.h b/external/src/libsodium/src/libsodium/include/sodium/private/ed25519_ref10_fe_51.h new file mode 100644 index 0000000..6c0d775 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/private/ed25519_ref10_fe_51.h @@ -0,0 +1,518 @@ +#include + +#include "private/common.h" +#include "utils.h" + +/* + h = 0 + */ + +static inline void +fe25519_0(fe25519 h) +{ + memset(&h[0], 0, 5 * sizeof h[0]); +} + +/* + h = 1 + */ + +static inline void +fe25519_1(fe25519 h) +{ + h[0] = 1; + memset(&h[1], 0, 4 * sizeof h[0]); +} + +/* + h = f + g + Can overlap h with f or g. + */ + +static inline void +fe25519_add(fe25519 h, const fe25519 f, const fe25519 g) +{ + uint64_t h0 = f[0] + g[0]; + uint64_t h1 = f[1] + g[1]; + uint64_t h2 = f[2] + g[2]; + uint64_t h3 = f[3] + g[3]; + uint64_t h4 = f[4] + g[4]; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; +} + +/* + h = f - g + */ + +static void +fe25519_sub(fe25519 h, const fe25519 f, const fe25519 g) +{ + const uint64_t mask = 0x7ffffffffffffULL; + uint64_t h0, h1, h2, h3, h4; + + h0 = g[0]; + h1 = g[1]; + h2 = g[2]; + h3 = g[3]; + h4 = g[4]; + + h1 += h0 >> 51; + h0 &= mask; + h2 += h1 >> 51; + h1 &= mask; + h3 += h2 >> 51; + h2 &= mask; + h4 += h3 >> 51; + h3 &= mask; + h0 += 19ULL * (h4 >> 51); + h4 &= mask; + + h0 = (f[0] + 0xfffffffffffdaULL) - h0; + h1 = (f[1] + 0xffffffffffffeULL) - h1; + h2 = (f[2] + 0xffffffffffffeULL) - h2; + h3 = (f[3] + 0xffffffffffffeULL) - h3; + h4 = (f[4] + 0xffffffffffffeULL) - h4; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; +} + +/* + h = -f + */ + +static inline void +fe25519_neg(fe25519 h, const fe25519 f) +{ + fe25519 zero; + + fe25519_0(zero); + fe25519_sub(h, zero, f); +} + +/* + Replace (f,g) with (g,g) if b == 1; + replace (f,g) with (f,g) if b == 0. + * + Preconditions: b in {0,1}. + */ + +static void +fe25519_cmov(fe25519 f, const fe25519 g, unsigned int b) +{ + const uint64_t mask = (uint64_t) (-(int64_t) b); + + uint64_t f0 = f[0]; + uint64_t f1 = f[1]; + uint64_t f2 = f[2]; + uint64_t f3 = f[3]; + uint64_t f4 = f[4]; + + uint64_t x0 = f0 ^ g[0]; + uint64_t x1 = f1 ^ g[1]; + uint64_t x2 = f2 ^ g[2]; + uint64_t x3 = f3 ^ g[3]; + uint64_t x4 = f4 ^ g[4]; + + x0 &= mask; + x1 &= mask; + x2 &= mask; + x3 &= mask; + x4 &= mask; + + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; +} + +/* +Replace (f,g) with (g,f) if b == 1; +replace (f,g) with (f,g) if b == 0. + +Preconditions: b in {0,1}. +*/ + +static void +fe25519_cswap(fe25519 f, fe25519 g, unsigned int b) +{ + const uint64_t mask = (uint64_t) (-(int64_t) b); + + uint64_t f0 = f[0]; + uint64_t f1 = f[1]; + uint64_t f2 = f[2]; + uint64_t f3 = f[3]; + uint64_t f4 = f[4]; + + uint64_t g0 = g[0]; + uint64_t g1 = g[1]; + uint64_t g2 = g[2]; + uint64_t g3 = g[3]; + uint64_t g4 = g[4]; + + uint64_t x0 = f0 ^ g0; + uint64_t x1 = f1 ^ g1; + uint64_t x2 = f2 ^ g2; + uint64_t x3 = f3 ^ g3; + uint64_t x4 = f4 ^ g4; + + x0 &= mask; + x1 &= mask; + x2 &= mask; + x3 &= mask; + x4 &= mask; + + f[0] = f0 ^ x0; + f[1] = f1 ^ x1; + f[2] = f2 ^ x2; + f[3] = f3 ^ x3; + f[4] = f4 ^ x4; + + g[0] = g0 ^ x0; + g[1] = g1 ^ x1; + g[2] = g2 ^ x2; + g[3] = g3 ^ x3; + g[4] = g4 ^ x4; +} + +/* + h = f + */ + +static inline void +fe25519_copy(fe25519 h, const fe25519 f) +{ + uint64_t f0 = f[0]; + uint64_t f1 = f[1]; + uint64_t f2 = f[2]; + uint64_t f3 = f[3]; + uint64_t f4 = f[4]; + + h[0] = f0; + h[1] = f1; + h[2] = f2; + h[3] = f3; + h[4] = f4; +} + +/* + return 1 if f is in {1,3,5,...,q-2} + return 0 if f is in {0,2,4,...,q-1} + */ + +static inline int +fe25519_isnegative(const fe25519 f) +{ + unsigned char s[32]; + + fe25519_tobytes(s, f); + + return s[0] & 1; +} + +/* + return 1 if f == 0 + return 0 if f != 0 + */ + +static inline int +fe25519_iszero(const fe25519 f) +{ + unsigned char s[32]; + + fe25519_tobytes(s, f); + + return sodium_is_zero(s, 32); +} + +/* + h = f * g + Can overlap h with f or g. + */ + +static void +fe25519_mul(fe25519 h, const fe25519 f, const fe25519 g) +{ + const uint64_t mask = 0x7ffffffffffffULL; + uint128_t r0, r1, r2, r3, r4, carry; + uint64_t f0, f1, f2, f3, f4; + uint64_t f1_19, f2_19, f3_19, f4_19; + uint64_t g0, g1, g2, g3, g4; + uint64_t r00, r01, r02, r03, r04; + + f0 = f[0]; + f1 = f[1]; + f2 = f[2]; + f3 = f[3]; + f4 = f[4]; + + g0 = g[0]; + g1 = g[1]; + g2 = g[2]; + g3 = g[3]; + g4 = g[4]; + + f1_19 = 19ULL * f1; + f2_19 = 19ULL * f2; + f3_19 = 19ULL * f3; + f4_19 = 19ULL * f4; + + r0 = ((uint128_t) f0 ) * ((uint128_t) g0); + r0 += ((uint128_t) f1_19) * ((uint128_t) g4); + r0 += ((uint128_t) f2_19) * ((uint128_t) g3); + r0 += ((uint128_t) f3_19) * ((uint128_t) g2); + r0 += ((uint128_t) f4_19) * ((uint128_t) g1); + + r1 = ((uint128_t) f0 ) * ((uint128_t) g1); + r1 += ((uint128_t) f1 ) * ((uint128_t) g0); + r1 += ((uint128_t) f2_19) * ((uint128_t) g4); + r1 += ((uint128_t) f3_19) * ((uint128_t) g3); + r1 += ((uint128_t) f4_19) * ((uint128_t) g2); + + r2 = ((uint128_t) f0 ) * ((uint128_t) g2); + r2 += ((uint128_t) f1 ) * ((uint128_t) g1); + r2 += ((uint128_t) f2 ) * ((uint128_t) g0); + r2 += ((uint128_t) f3_19) * ((uint128_t) g4); + r2 += ((uint128_t) f4_19) * ((uint128_t) g3); + + r3 = ((uint128_t) f0 ) * ((uint128_t) g3); + r3 += ((uint128_t) f1 ) * ((uint128_t) g2); + r3 += ((uint128_t) f2 ) * ((uint128_t) g1); + r3 += ((uint128_t) f3 ) * ((uint128_t) g0); + r3 += ((uint128_t) f4_19) * ((uint128_t) g4); + + r4 = ((uint128_t) f0 ) * ((uint128_t) g4); + r4 += ((uint128_t) f1 ) * ((uint128_t) g3); + r4 += ((uint128_t) f2 ) * ((uint128_t) g2); + r4 += ((uint128_t) f3 ) * ((uint128_t) g1); + r4 += ((uint128_t) f4 ) * ((uint128_t) g0); + + r00 = ((uint64_t) r0) & mask; + carry = r0 >> 51; + r1 += carry; + r01 = ((uint64_t) r1) & mask; + carry = r1 >> 51; + r2 += carry; + r02 = ((uint64_t) r2) & mask; + carry = r2 >> 51; + r3 += carry; + r03 = ((uint64_t) r3) & mask; + carry = r3 >> 51; + r4 += carry; + r04 = ((uint64_t) r4) & mask; + carry = r4 >> 51; + r00 += 19ULL * (uint64_t) carry; + carry = r00 >> 51; + r00 &= mask; + r01 += (uint64_t) carry; + carry = r01 >> 51; + r01 &= mask; + r02 += (uint64_t) carry; + + h[0] = r00; + h[1] = r01; + h[2] = r02; + h[3] = r03; + h[4] = r04; +} + +/* + h = f * f + Can overlap h with f. + */ + +static void +fe25519_sq(fe25519 h, const fe25519 f) +{ + const uint64_t mask = 0x7ffffffffffffULL; + uint128_t r0, r1, r2, r3, r4, carry; + uint64_t f0, f1, f2, f3, f4; + uint64_t f0_2, f1_2, f1_38, f2_38, f3_38, f3_19, f4_19; + uint64_t r00, r01, r02, r03, r04; + + f0 = f[0]; + f1 = f[1]; + f2 = f[2]; + f3 = f[3]; + f4 = f[4]; + + f0_2 = f0 << 1; + f1_2 = f1 << 1; + + f1_38 = 38ULL * f1; + f2_38 = 38ULL * f2; + f3_38 = 38ULL * f3; + + f3_19 = 19ULL * f3; + f4_19 = 19ULL * f4; + + r0 = ((uint128_t) f0 ) * ((uint128_t) f0); + r0 += ((uint128_t) f1_38) * ((uint128_t) f4); + r0 += ((uint128_t) f2_38) * ((uint128_t) f3); + + r1 = ((uint128_t) f0_2 ) * ((uint128_t) f1); + r1 += ((uint128_t) f2_38) * ((uint128_t) f4); + r1 += ((uint128_t) f3_19) * ((uint128_t) f3); + + r2 = ((uint128_t) f0_2 ) * ((uint128_t) f2); + r2 += ((uint128_t) f1 ) * ((uint128_t) f1); + r2 += ((uint128_t) f3_38) * ((uint128_t) f4); + + r3 = ((uint128_t) f0_2 ) * ((uint128_t) f3); + r3 += ((uint128_t) f1_2 ) * ((uint128_t) f2); + r3 += ((uint128_t) f4_19) * ((uint128_t) f4); + + r4 = ((uint128_t) f0_2 ) * ((uint128_t) f4); + r4 += ((uint128_t) f1_2 ) * ((uint128_t) f3); + r4 += ((uint128_t) f2 ) * ((uint128_t) f2); + + r00 = ((uint64_t) r0) & mask; + carry = r0 >> 51; + r1 += carry; + r01 = ((uint64_t) r1) & mask; + carry = r1 >> 51; + r2 += carry; + r02 = ((uint64_t) r2) & mask; + carry = r2 >> 51; + r3 += carry; + r03 = ((uint64_t) r3) & mask; + carry = r3 >> 51; + r4 += carry; + r04 = ((uint64_t) r4) & mask; + carry = r4 >> 51; + r00 += 19ULL * (uint64_t) carry; + carry = r00 >> 51; + r00 &= mask; + r01 += (uint64_t) carry; + carry = r01 >> 51; + r01 &= mask; + r02 += (uint64_t) carry; + + h[0] = r00; + h[1] = r01; + h[2] = r02; + h[3] = r03; + h[4] = r04; +} + +/* + h = 2 * f * f + Can overlap h with f. +*/ + +static void +fe25519_sq2(fe25519 h, const fe25519 f) +{ + const uint64_t mask = 0x7ffffffffffffULL; + uint128_t r0, r1, r2, r3, r4, carry; + uint64_t f0, f1, f2, f3, f4; + uint64_t f0_2, f1_2, f1_38, f2_38, f3_38, f3_19, f4_19; + uint64_t r00, r01, r02, r03, r04; + + f0 = f[0]; + f1 = f[1]; + f2 = f[2]; + f3 = f[3]; + f4 = f[4]; + + f0_2 = f0 << 1; + f1_2 = f1 << 1; + + f1_38 = 38ULL * f1; + f2_38 = 38ULL * f2; + f3_38 = 38ULL * f3; + + f3_19 = 19ULL * f3; + f4_19 = 19ULL * f4; + + r0 = ((uint128_t) f0 ) * ((uint128_t) f0); + r0 += ((uint128_t) f1_38) * ((uint128_t) f4); + r0 += ((uint128_t) f2_38) * ((uint128_t) f3); + + r1 = ((uint128_t) f0_2 ) * ((uint128_t) f1); + r1 += ((uint128_t) f2_38) * ((uint128_t) f4); + r1 += ((uint128_t) f3_19) * ((uint128_t) f3); + + r2 = ((uint128_t) f0_2 ) * ((uint128_t) f2); + r2 += ((uint128_t) f1 ) * ((uint128_t) f1); + r2 += ((uint128_t) f3_38) * ((uint128_t) f4); + + r3 = ((uint128_t) f0_2 ) * ((uint128_t) f3); + r3 += ((uint128_t) f1_2 ) * ((uint128_t) f2); + r3 += ((uint128_t) f4_19) * ((uint128_t) f4); + + r4 = ((uint128_t) f0_2 ) * ((uint128_t) f4); + r4 += ((uint128_t) f1_2 ) * ((uint128_t) f3); + r4 += ((uint128_t) f2 ) * ((uint128_t) f2); + + r0 <<= 1; + r1 <<= 1; + r2 <<= 1; + r3 <<= 1; + r4 <<= 1; + + r00 = ((uint64_t) r0) & mask; + carry = r0 >> 51; + r1 += carry; + r01 = ((uint64_t) r1) & mask; + carry = r1 >> 51; + r2 += carry; + r02 = ((uint64_t) r2) & mask; + carry = r2 >> 51; + r3 += carry; + r03 = ((uint64_t) r3) & mask; + carry = r3 >> 51; + r4 += carry; + r04 = ((uint64_t) r4) & mask; + carry = r4 >> 51; + r00 += 19ULL * (uint64_t) carry; + carry = r00 >> 51; + r00 &= mask; + r01 += (uint64_t) carry; + carry = r01 >> 51; + r01 &= mask; + r02 += (uint64_t) carry; + + h[0] = r00; + h[1] = r01; + h[2] = r02; + h[3] = r03; + h[4] = r04; +} + +static void +fe25519_mul32(fe25519 h, const fe25519 f, uint32_t n) +{ + const uint64_t mask = 0x7ffffffffffffULL; + uint128_t a; + uint128_t sn = (uint128_t) n; + uint64_t h0, h1, h2, h3, h4; + + a = f[0] * sn; + h0 = ((uint64_t) a) & mask; + a = f[1] * sn + ((uint64_t) (a >> 51)); + h1 = ((uint64_t) a) & mask; + a = f[2] * sn + ((uint64_t) (a >> 51)); + h2 = ((uint64_t) a) & mask; + a = f[3] * sn + ((uint64_t) (a >> 51)); + h3 = ((uint64_t) a) & mask; + a = f[4] * sn + ((uint64_t) (a >> 51)); + h4 = ((uint64_t) a) & mask; + + h0 += (a >> 51) * 19ULL; + + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; +} diff --git a/external/src/libsodium/src/libsodium/include/sodium/private/implementations.h b/external/src/libsodium/src/libsodium/include/sodium/private/implementations.h new file mode 100644 index 0000000..c7237f8 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/private/implementations.h @@ -0,0 +1,11 @@ +#ifndef implementations_H +#define implementations_H + +int _crypto_generichash_blake2b_pick_best_implementation(void); +int _crypto_onetimeauth_poly1305_pick_best_implementation(void); +int _crypto_pwhash_argon2_pick_best_implementation(void); +int _crypto_scalarmult_curve25519_pick_best_implementation(void); +int _crypto_stream_chacha20_pick_best_implementation(void); +int _crypto_stream_salsa20_pick_best_implementation(void); + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/private/mutex.h b/external/src/libsodium/src/libsodium/include/sodium/private/mutex.h new file mode 100644 index 0000000..322b674 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/private/mutex.h @@ -0,0 +1,7 @@ +#ifndef mutex_H +#define mutex_H 1 + +extern int sodium_crit_enter(void); +extern int sodium_crit_leave(void); + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/private/sse2_64_32.h b/external/src/libsodium/src/libsodium/include/sodium/private/sse2_64_32.h new file mode 100644 index 0000000..fc994bd --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/private/sse2_64_32.h @@ -0,0 +1,50 @@ +#ifndef sse2_64_32_H +#define sse2_64_32_H 1 + +#include "private/common.h" + +#ifdef HAVE_INTRIN_H +# include +#endif + +#if defined(HAVE_EMMINTRIN_H) && \ + !(defined(__amd64) || defined(__amd64__) || defined(__x86_64__) || \ + defined(_M_X64) || defined(_M_AMD64)) + +# include +# include + +# ifndef _mm_set_epi64x +# define _mm_set_epi64x(Q0, Q1) sodium__mm_set_epi64x((Q0), (Q1)) +static inline __m128i +sodium__mm_set_epi64x(int64_t q1, int64_t q0) +{ + union { int64_t as64; int32_t as32[2]; } x0, x1; + x0.as64 = q0; x1.as64 = q1; + return _mm_set_epi32(x1.as32[1], x1.as32[0], x0.as32[1], x0.as32[0]); +} +# endif + +# ifndef _mm_set1_epi64x +# define _mm_set1_epi64x(Q) sodium__mm_set1_epi64x(Q) +static inline __m128i +sodium__mm_set1_epi64x(int64_t q) +{ + return _mm_set_epi64x(q, q); +} +# endif + +# ifndef _mm_cvtsi64_si128 +# define _mm_cvtsi64_si128(Q) sodium__mm_cvtsi64_si128(Q) +static inline __m128i +sodium__mm_cvtsi64_si128(int64_t q) +{ + union { int64_t as64; int32_t as32[2]; } x; + x.as64 = q; + return _mm_setr_epi32(x.as32[0], x.as32[1], 0, 0); +} +# endif + +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/randombytes.h b/external/src/libsodium/src/libsodium/include/sodium/randombytes.h new file mode 100644 index 0000000..a03cc65 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/randombytes.h @@ -0,0 +1,72 @@ + +#ifndef randombytes_H +#define randombytes_H + +#include +#include + +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +typedef struct randombytes_implementation { + const char *(*implementation_name)(void); /* required */ + uint32_t (*random)(void); /* required */ + void (*stir)(void); /* optional */ + uint32_t (*uniform)(const uint32_t upper_bound); /* optional, a default implementation will be used if NULL */ + void (*buf)(void * const buf, const size_t size); /* required */ + int (*close)(void); /* optional */ +} randombytes_implementation; + +#define randombytes_BYTES_MAX SODIUM_MIN(SODIUM_SIZE_MAX, 0xffffffffUL) + +#define randombytes_SEEDBYTES 32U +SODIUM_EXPORT +size_t randombytes_seedbytes(void); + +SODIUM_EXPORT +void randombytes_buf(void * const buf, const size_t size) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void randombytes_buf_deterministic(void * const buf, const size_t size, + const unsigned char seed[randombytes_SEEDBYTES]) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +uint32_t randombytes_random(void); + +SODIUM_EXPORT +uint32_t randombytes_uniform(const uint32_t upper_bound); + +SODIUM_EXPORT +void randombytes_stir(void); + +SODIUM_EXPORT +int randombytes_close(void); + +SODIUM_EXPORT +int randombytes_set_implementation(randombytes_implementation *impl) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +const char *randombytes_implementation_name(void); + +/* -- NaCl compatibility interface -- */ + +SODIUM_EXPORT +void randombytes(unsigned char * const buf, const unsigned long long buf_len) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/randombytes_internal_random.h b/external/src/libsodium/src/libsodium/include/sodium/randombytes_internal_random.h new file mode 100644 index 0000000..2b2b7d6 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/randombytes_internal_random.h @@ -0,0 +1,22 @@ + +#ifndef randombytes_internal_random_H +#define randombytes_internal_random_H + +#include "export.h" +#include "randombytes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +extern struct randombytes_implementation randombytes_internal_implementation; + +/* Backwards compatibility with libsodium < 1.0.18 */ +#define randombytes_salsa20_implementation randombytes_internal_implementation + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/randombytes_sysrandom.h b/external/src/libsodium/src/libsodium/include/sodium/randombytes_sysrandom.h new file mode 100644 index 0000000..9e27b67 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/randombytes_sysrandom.h @@ -0,0 +1,19 @@ + +#ifndef randombytes_sysrandom_H +#define randombytes_sysrandom_H + +#include "export.h" +#include "randombytes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +extern struct randombytes_implementation randombytes_sysrandom_implementation; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/runtime.h b/external/src/libsodium/src/libsodium/include/sodium/runtime.h new file mode 100644 index 0000000..7f15d58 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/runtime.h @@ -0,0 +1,52 @@ + +#ifndef sodium_runtime_H +#define sodium_runtime_H + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_neon(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_sse2(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_sse3(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_ssse3(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_sse41(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_avx(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_avx2(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_avx512f(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_pclmul(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_aesni(void); + +SODIUM_EXPORT_WEAK +int sodium_runtime_has_rdrand(void); + +/* ------------------------------------------------------------------------- */ + +int _sodium_runtime_get_cpu_features(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/utils.h b/external/src/libsodium/src/libsodium/include/sodium/utils.h new file mode 100644 index 0000000..f9b3697 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/utils.h @@ -0,0 +1,179 @@ + +#ifndef sodium_utils_H +#define sodium_utils_H + +#include + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef SODIUM_C99 +# if defined(__cplusplus) || !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L +# define SODIUM_C99(X) +# else +# define SODIUM_C99(X) X +# endif +#endif + +SODIUM_EXPORT +void sodium_memzero(void * const pnt, const size_t len); + +SODIUM_EXPORT +void sodium_stackzero(const size_t len); + +/* + * WARNING: sodium_memcmp() must be used to verify if two secret keys + * are equal, in constant time. + * It returns 0 if the keys are equal, and -1 if they differ. + * This function is not designed for lexicographical comparisons. + */ +SODIUM_EXPORT +int sodium_memcmp(const void * const b1_, const void * const b2_, size_t len) + __attribute__ ((warn_unused_result)); + +/* + * sodium_compare() returns -1 if b1_ < b2_, 1 if b1_ > b2_ and 0 if b1_ == b2_ + * It is suitable for lexicographical comparisons, or to compare nonces + * and counters stored in little-endian format. + * However, it is slower than sodium_memcmp(). + */ +SODIUM_EXPORT +int sodium_compare(const unsigned char *b1_, const unsigned char *b2_, + size_t len) __attribute__ ((warn_unused_result)); + +SODIUM_EXPORT +int sodium_is_zero(const unsigned char *n, const size_t nlen); + +SODIUM_EXPORT +void sodium_increment(unsigned char *n, const size_t nlen); + +SODIUM_EXPORT +void sodium_add(unsigned char *a, const unsigned char *b, const size_t len); + +SODIUM_EXPORT +void sodium_sub(unsigned char *a, const unsigned char *b, const size_t len); + +SODIUM_EXPORT +char *sodium_bin2hex(char * const hex, const size_t hex_maxlen, + const unsigned char * const bin, const size_t bin_len) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int sodium_hex2bin(unsigned char * const bin, const size_t bin_maxlen, + const char * const hex, const size_t hex_len, + const char * const ignore, size_t * const bin_len, + const char ** const hex_end) + __attribute__ ((nonnull(1))); + +#define sodium_base64_VARIANT_ORIGINAL 1 +#define sodium_base64_VARIANT_ORIGINAL_NO_PADDING 3 +#define sodium_base64_VARIANT_URLSAFE 5 +#define sodium_base64_VARIANT_URLSAFE_NO_PADDING 7 + +/* + * Computes the required length to encode BIN_LEN bytes as a base64 string + * using the given variant. The computed length includes a trailing \0. + */ +#define sodium_base64_ENCODED_LEN(BIN_LEN, VARIANT) \ + (((BIN_LEN) / 3U) * 4U + \ + ((((BIN_LEN) - ((BIN_LEN) / 3U) * 3U) | (((BIN_LEN) - ((BIN_LEN) / 3U) * 3U) >> 1)) & 1U) * \ + (4U - (~((((VARIANT) & 2U) >> 1) - 1U) & (3U - ((BIN_LEN) - ((BIN_LEN) / 3U) * 3U)))) + 1U) + +SODIUM_EXPORT +size_t sodium_base64_encoded_len(const size_t bin_len, const int variant); + +SODIUM_EXPORT +char *sodium_bin2base64(char * const b64, const size_t b64_maxlen, + const unsigned char * const bin, const size_t bin_len, + const int variant) __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int sodium_base642bin(unsigned char * const bin, const size_t bin_maxlen, + const char * const b64, const size_t b64_len, + const char * const ignore, size_t * const bin_len, + const char ** const b64_end, const int variant) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int sodium_mlock(void * const addr, const size_t len) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int sodium_munlock(void * const addr, const size_t len) + __attribute__ ((nonnull)); + +/* WARNING: sodium_malloc() and sodium_allocarray() are not general-purpose + * allocation functions. + * + * They return a pointer to a region filled with 0xd0 bytes, immediately + * followed by a guard page. + * As a result, accessing a single byte after the requested allocation size + * will intentionally trigger a segmentation fault. + * + * A canary and an additional guard page placed before the beginning of the + * region may also kill the process if a buffer underflow is detected. + * + * The memory layout is: + * [unprotected region size (read only)][guard page (no access)][unprotected pages (read/write)][guard page (no access)] + * With the layout of the unprotected pages being: + * [optional padding][16-bytes canary][user region] + * + * However: + * - These functions are significantly slower than standard functions + * - Each allocation requires 3 or 4 additional pages + * - The returned address will not be aligned if the allocation size is not + * a multiple of the required alignment. For this reason, these functions + * are designed to store data, such as secret keys and messages. + * + * sodium_malloc() can be used to allocate any libsodium data structure. + * + * The crypto_generichash_state structure is packed and its length is + * either 357 or 361 bytes. For this reason, when using sodium_malloc() to + * allocate a crypto_generichash_state structure, padding must be added in + * order to ensure proper alignment. crypto_generichash_statebytes() + * returns the rounded up structure size, and should be preferred to sizeof(): + * state = sodium_malloc(crypto_generichash_statebytes()); + */ + +SODIUM_EXPORT +void *sodium_malloc(const size_t size) + __attribute__ ((malloc)); + +SODIUM_EXPORT +void *sodium_allocarray(size_t count, size_t size) + __attribute__ ((malloc)); + +SODIUM_EXPORT +void sodium_free(void *ptr); + +SODIUM_EXPORT +int sodium_mprotect_noaccess(void *ptr) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int sodium_mprotect_readonly(void *ptr) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int sodium_mprotect_readwrite(void *ptr) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int sodium_pad(size_t *padded_buflen_p, unsigned char *buf, + size_t unpadded_buflen, size_t blocksize, size_t max_buflen) + __attribute__ ((nonnull(2))); + +SODIUM_EXPORT +int sodium_unpad(size_t *unpadded_buflen_p, const unsigned char *buf, + size_t padded_buflen, size_t blocksize) + __attribute__ ((nonnull(2))); + +/* -------- */ + +int _sodium_alloc_init(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/include/sodium/version.h.in b/external/src/libsodium/src/libsodium/include/sodium/version.h.in new file mode 100644 index 0000000..8a72044 --- /dev/null +++ b/external/src/libsodium/src/libsodium/include/sodium/version.h.in @@ -0,0 +1,33 @@ + +#ifndef sodium_version_H +#define sodium_version_H + +#include "export.h" + +#define SODIUM_VERSION_STRING "@VERSION@" + +#define SODIUM_LIBRARY_VERSION_MAJOR @SODIUM_LIBRARY_VERSION_MAJOR@ +#define SODIUM_LIBRARY_VERSION_MINOR @SODIUM_LIBRARY_VERSION_MINOR@ +@SODIUM_LIBRARY_MINIMAL_DEF@ + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +const char *sodium_version_string(void); + +SODIUM_EXPORT +int sodium_library_version_major(void); + +SODIUM_EXPORT +int sodium_library_version_minor(void); + +SODIUM_EXPORT +int sodium_library_minimal(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/external/src/libsodium/src/libsodium/randombytes/internal/randombytes_internal_random.c b/external/src/libsodium/src/libsodium/randombytes/internal/randombytes_internal_random.c new file mode 100644 index 0000000..f0794f8 --- /dev/null +++ b/external/src/libsodium/src/libsodium/randombytes/internal/randombytes_internal_random.c @@ -0,0 +1,631 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(_MSC_VER) && !defined(__BORLANDC__) +# include +#endif + +#include +#ifndef _WIN32 +# include +# include +#endif +#ifdef __linux__ +# define _LINUX_SOURCE +#endif +#ifdef HAVE_SYS_RANDOM_H +# include +#endif +#ifdef __linux__ +# ifdef HAVE_GETRANDOM +# define HAVE_LINUX_COMPATIBLE_GETRANDOM +# else +# include +# if defined(SYS_getrandom) && defined(__NR_getrandom) +# define getrandom(B, S, F) syscall(SYS_getrandom, (B), (int) (S), (F)) +# define HAVE_LINUX_COMPATIBLE_GETRANDOM +# endif +# endif +#elif defined(__FreeBSD__) +# include +# if defined(__FreeBSD_version) && __FreeBSD_version >= 1200000 +# define HAVE_LINUX_COMPATIBLE_GETRANDOM +# endif +#endif +#if !defined(NO_BLOCKING_RANDOM_POLL) && defined(__linux__) +# define BLOCK_ON_DEV_RANDOM +#endif +#ifdef BLOCK_ON_DEV_RANDOM +# include +#endif +#ifdef HAVE_RDRAND +# pragma GCC target("rdrnd") +# include +#endif + +#include "core.h" +#include "crypto_core_hchacha20.h" +#include "crypto_stream_chacha20.h" +#include "private/common.h" +#include "randombytes.h" +#include "randombytes_internal_random.h" +#include "runtime.h" +#include "utils.h" + +#ifdef _WIN32 +# include +# include +# define RtlGenRandom SystemFunction036 +# if defined(__cplusplus) +extern "C" +# endif +BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); +# pragma comment(lib, "advapi32.lib") +# ifdef __BORLANDC__ +# define _ftime ftime +# define _timeb timeb +# endif +#endif + +#define INTERNAL_RANDOM_BLOCK_SIZE crypto_core_hchacha20_OUTPUTBYTES + +#if defined(__OpenBSD__) || defined(__CloudABI__) || defined(__wasi__) +# define HAVE_SAFE_ARC4RANDOM 1 +#endif +#if defined(__CloudABI__) || defined(__wasm__) +# define NONEXISTENT_DEV_RANDOM 1 +#endif + +#ifndef SSIZE_MAX +# define SSIZE_MAX (SIZE_MAX / 2 - 1) +#endif +#ifndef S_ISNAM +# ifdef __COMPCERT__ +# define S_ISNAM(X) 1 +# else +# define S_ISNAM(X) 0 +# endif +#endif + +#ifndef TLS +# ifdef _WIN32 +# define TLS __declspec(thread) +# else +# define TLS +# endif +#endif + +typedef struct InternalRandomGlobal_ { + int initialized; + int random_data_source_fd; + int getentropy_available; + int getrandom_available; + int rdrand_available; +#ifdef HAVE_GETPID + pid_t pid; +#endif +} InternalRandomGlobal; + +typedef struct InternalRandom_ { + int initialized; + size_t rnd32_outleft; + unsigned char key[crypto_stream_chacha20_KEYBYTES]; + unsigned char rnd32[16U * INTERNAL_RANDOM_BLOCK_SIZE]; + uint64_t nonce; +} InternalRandom; + +static InternalRandomGlobal global = { + SODIUM_C99(.initialized =) 0, + SODIUM_C99(.random_data_source_fd =) -1 +}; + +static TLS InternalRandom stream = { + SODIUM_C99(.initialized =) 0, + SODIUM_C99(.rnd32_outleft =) (size_t) 0U +}; + + +/* + * Get a high-resolution timestamp, as a uint64_t value + */ + +#ifdef _WIN32 +static uint64_t +sodium_hrtime(void) +{ + struct _timeb tb; +# pragma warning(push) +# pragma warning(disable: 4996) + _ftime(&tb); +# pragma warning(pop) + return ((uint64_t) tb.time) * 1000000U + ((uint64_t) tb.millitm) * 1000U; +} + +#else /* _WIN32 */ + +static uint64_t +sodium_hrtime(void) +{ + struct timeval tv; + + if (gettimeofday(&tv, NULL) != 0) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + return ((uint64_t) tv.tv_sec) * 1000000U + (uint64_t) tv.tv_usec; +} +#endif /* _WIN32 */ + +/* + * Initialize the entropy source + */ + +#ifdef _WIN32 + +static void +randombytes_internal_random_init(void) +{ + global.rdrand_available = sodium_runtime_has_rdrand(); +} + +#else /* _WIN32 */ + +# ifdef HAVE_GETENTROPY +static int +_randombytes_getentropy(void * const buf, const size_t size) +{ + assert(size <= 256U); + if (getentropy(buf, size) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; +} + +static int +randombytes_getentropy(void * const buf_, size_t size) +{ + unsigned char *buf = (unsigned char *) buf_; + size_t chunk_size = 256U; + + do { + if (size < chunk_size) { + chunk_size = size; + assert(chunk_size > (size_t) 0U); + } + if (_randombytes_getentropy(buf, chunk_size) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + size -= chunk_size; + buf += chunk_size; + } while (size > (size_t) 0U); + + return 0; +} + +# elif defined(HAVE_LINUX_COMPATIBLE_GETRANDOM) + +static int +_randombytes_linux_getrandom(void * const buf, const size_t size) +{ + int readnb; + + assert(size <= 256U); + do { + readnb = getrandom(buf, size, 0); + } while (readnb < 0 && (errno == EINTR || errno == EAGAIN)); + + return (readnb == (int) size) - 1; +} + +static int +randombytes_linux_getrandom(void * const buf_, size_t size) +{ + unsigned char *buf = (unsigned char *) buf_; + size_t chunk_size = 256U; + + do { + if (size < chunk_size) { + chunk_size = size; + assert(chunk_size > (size_t) 0U); + } + if (_randombytes_linux_getrandom(buf, chunk_size) != 0) { + return -1; + } + size -= chunk_size; + buf += chunk_size; + } while (size > (size_t) 0U); + + return 0; +} +# endif + +# ifndef NONEXISTENT_DEV_RANDOM + +# ifdef BLOCK_ON_DEV_RANDOM +static int +randombytes_block_on_dev_random(void) +{ + struct pollfd pfd; + int fd; + int pret; + + fd = open("/dev/random", O_RDONLY); + if (fd == -1) { + return 0; + } + pfd.fd = fd; + pfd.events = POLLIN; + pfd.revents = 0; + do { + pret = poll(&pfd, 1, -1); + } while (pret < 0 && (errno == EINTR || errno == EAGAIN)); + if (pret != 1) { + (void) close(fd); + errno = EIO; + return -1; + } + return close(fd); +} +# endif + +/* LCOV_EXCL_START */ +static int +randombytes_internal_random_random_dev_open(void) +{ + struct stat st; + static const char *devices[] = { +# ifndef USE_BLOCKING_RANDOM + "/dev/urandom", +# endif + "/dev/random", NULL + }; + const char **device = devices; + int fd; + +# ifdef BLOCK_ON_DEV_RANDOM + if (randombytes_block_on_dev_random() != 0) { + return -1; + } +# endif + do { + fd = open(*device, O_RDONLY); + if (fd != -1) { + if (fstat(fd, &st) == 0 && (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode))) { +# if defined(F_SETFD) && defined(FD_CLOEXEC) + (void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); +# endif + return fd; + } + (void) close(fd); + } else if (errno == EINTR) { + continue; + } + device++; + } while (*device != NULL); + + errno = EIO; + return -1; +} +/* LCOV_EXCL_STOP */ + +static ssize_t +safe_read(const int fd, void * const buf_, size_t size) +{ + unsigned char *buf = (unsigned char *) buf_; + ssize_t readnb; + + assert(size > (size_t) 0U); + assert(size <= SSIZE_MAX); + do { + while ((readnb = read(fd, buf, size)) < (ssize_t) 0 && + (errno == EINTR || errno == EAGAIN)); /* LCOV_EXCL_LINE */ + if (readnb < (ssize_t) 0) { + return readnb; /* LCOV_EXCL_LINE */ + } + if (readnb == (ssize_t) 0) { + break; /* LCOV_EXCL_LINE */ + } + size -= (size_t) readnb; + buf += readnb; + } while (size > (ssize_t) 0); + + return (ssize_t) (buf - (unsigned char *) buf_); +} + +# endif /* !NONEXISTENT_DEV_RANDOM */ + +static void +randombytes_internal_random_init(void) +{ + const int errno_save = errno; + + global.rdrand_available = sodium_runtime_has_rdrand(); + global.getentropy_available = 0; + global.getrandom_available = 0; + +# ifdef HAVE_GETENTROPY + { + unsigned char fodder[16]; + + if (randombytes_getentropy(fodder, sizeof fodder) == 0) { + global.getentropy_available = 1; + errno = errno_save; + return; + } + } +# elif defined(HAVE_LINUX_COMPATIBLE_GETRANDOM) + { + unsigned char fodder[16]; + + if (randombytes_linux_getrandom(fodder, sizeof fodder) == 0) { + global.getrandom_available = 1; + errno = errno_save; + return; + } + } +# endif +/* LCOV_EXCL_START */ +# if !defined(NONEXISTENT_DEV_RANDOM) + assert((global.getentropy_available | global.getrandom_available) == 0); + if ((global.random_data_source_fd = + randombytes_internal_random_random_dev_open()) == -1) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + errno = errno_save; + return; +# endif +/* LCOV_EXCL_STOP */ +# ifndef HAVE_SAFE_ARC4RANDOM + sodium_misuse(); +# endif +} + +#endif /* _WIN32 */ + +/* + * (Re)seed the generator using the entropy source + */ + +static void +randombytes_internal_random_stir(void) +{ + stream.nonce = sodium_hrtime(); + assert(stream.nonce != (uint64_t) 0U); + memset(stream.rnd32, 0, sizeof stream.rnd32); + stream.rnd32_outleft = (size_t) 0U; + if (global.initialized == 0) { + randombytes_internal_random_init(); + global.initialized = 1; + } +#ifdef HAVE_GETPID + global.pid = getpid(); +#endif + +#ifndef _WIN32 + +# ifdef HAVE_GETENTROPY + if (global.getentropy_available != 0) { + if (randombytes_getentropy(stream.key, sizeof stream.key) != 0) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + } +# elif defined(HAVE_LINUX_COMPATIBLE_GETRANDOM) + if (global.getrandom_available != 0) { + if (randombytes_linux_getrandom(stream.key, sizeof stream.key) != 0) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + } +# elif defined(NONEXISTENT_DEV_RANDOM) && defined(HAVE_SAFE_ARC4RANDOM) + arc4random_buf(stream.key, sizeof stream.key); +# elif !defined(NONEXISTENT_DEV_RANDOM) + if (global.random_data_source_fd == -1 || + safe_read(global.random_data_source_fd, stream.key, + sizeof stream.key) != (ssize_t) sizeof stream.key) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +# else + sodium_misuse(); +# endif + +#else /* _WIN32 */ + if (! RtlGenRandom((PVOID) stream.key, (ULONG) sizeof stream.key)) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +#endif + + stream.initialized = 1; +} + +/* + * Reseed the generator if it hasn't been initialized yet + */ + +static void +randombytes_internal_random_stir_if_needed(void) +{ +#ifdef HAVE_GETPID + if (stream.initialized == 0) { + randombytes_internal_random_stir(); + } else if (global.pid != getpid()) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +#else + if (stream.initialized == 0) { + randombytes_internal_random_stir(); + } +#endif +} + +/* + * Close the stream, free global resources + */ + +#ifdef _WIN32 +static int +randombytes_internal_random_close(void) +{ + int ret = -1; + + if (global.initialized != 0) { + global.initialized = 0; + ret = 0; + } + sodium_memzero(&stream, sizeof stream); + + return ret; +} +#else +static int +randombytes_internal_random_close(void) +{ + int ret = -1; + +# ifdef HAVE_GETENTROPY + if (global.getentropy_available != 0) { + ret = 0; + } +# elif defined(HAVE_LINUX_COMPATIBLE_GETRANDOM) + if (global.getrandom_available != 0) { + ret = 0; + } +# elif !defined(NONEXISTENT_DEV_RANDOM) && defined(HAVE_SAFE_ARC4RANDOM) + ret = 0; +# else + if (global.random_data_source_fd != -1 && + close(global.random_data_source_fd) == 0) { + global.random_data_source_fd = -1; + global.initialized = 0; +# ifdef HAVE_GETPID + global.pid = (pid_t) 0; +# endif + ret = 0; + } +# endif + + sodium_memzero(&stream, sizeof stream); + + return ret; +} +#endif + +/* + * RDRAND is only used to mitigate prediction if a key is compromised + */ + +static void +randombytes_internal_random_xorhwrand(void) +{ +/* LCOV_EXCL_START */ +#ifdef HAVE_RDRAND + unsigned int r; + + if (global.rdrand_available == 0) { + return; + } + (void) _rdrand32_step(&r); + * (uint32_t *) (void *) + &stream.key[crypto_stream_chacha20_KEYBYTES - 4] ^= (uint32_t) r; +#endif +/* LCOV_EXCL_STOP */ +} + +/* + * XOR the key with another same-length secret + */ + +static inline void +randombytes_internal_random_xorkey(const unsigned char * const mix) +{ + unsigned char *key = stream.key; + size_t i; + + for (i = (size_t) 0U; i < sizeof stream.key; i++) { + key[i] ^= mix[i]; + } +} + +/* + * Put `size` random bytes into `buf` and overwrite the key + */ + +static void +randombytes_internal_random_buf(void * const buf, const size_t size) +{ + size_t i; + int ret; + + randombytes_internal_random_stir_if_needed(); + COMPILER_ASSERT(sizeof stream.nonce == crypto_stream_chacha20_NONCEBYTES); +#if defined(ULLONG_MAX) && defined(SIZE_MAX) +# if SIZE_MAX > ULLONG_MAX + /* coverity[result_independent_of_operands] */ + assert(size <= ULLONG_MAX); +# endif +#endif + ret = crypto_stream_chacha20((unsigned char *) buf, (unsigned long long) size, + (unsigned char *) &stream.nonce, stream.key); + assert(ret == 0); + for (i = 0U; i < sizeof size; i++) { + stream.key[i] ^= ((const unsigned char *) (const void *) &size)[i]; + } + randombytes_internal_random_xorhwrand(); + stream.nonce++; + crypto_stream_chacha20_xor(stream.key, stream.key, sizeof stream.key, + (unsigned char *) &stream.nonce, stream.key); +} + +/* + * Pop a 32-bit value from the random pool + * + * Overwrite the key after the pool gets refilled. + */ + +static uint32_t +randombytes_internal_random(void) +{ + uint32_t val; + int ret; + + COMPILER_ASSERT(sizeof stream.rnd32 >= (sizeof stream.key) + (sizeof val)); + COMPILER_ASSERT(((sizeof stream.rnd32) - (sizeof stream.key)) + % sizeof val == (size_t) 0U); + if (stream.rnd32_outleft <= (size_t) 0U) { + randombytes_internal_random_stir_if_needed(); + COMPILER_ASSERT(sizeof stream.nonce == crypto_stream_chacha20_NONCEBYTES); + ret = crypto_stream_chacha20((unsigned char *) stream.rnd32, + (unsigned long long) sizeof stream.rnd32, + (unsigned char *) &stream.nonce, + stream.key); + assert(ret == 0); + stream.rnd32_outleft = (sizeof stream.rnd32) - (sizeof stream.key); + randombytes_internal_random_xorhwrand(); + randombytes_internal_random_xorkey(&stream.rnd32[stream.rnd32_outleft]); + memset(&stream.rnd32[stream.rnd32_outleft], 0, sizeof stream.key); + stream.nonce++; + } + stream.rnd32_outleft -= sizeof val; + memcpy(&val, &stream.rnd32[stream.rnd32_outleft], sizeof val); + memset(&stream.rnd32[stream.rnd32_outleft], 0, sizeof val); + + return val; +} + +static const char * +randombytes_internal_implementation_name(void) +{ + return "internal"; +} + +struct randombytes_implementation randombytes_internal_implementation = { + SODIUM_C99(.implementation_name =) randombytes_internal_implementation_name, + SODIUM_C99(.random =) randombytes_internal_random, + SODIUM_C99(.stir =) randombytes_internal_random_stir, + SODIUM_C99(.uniform =) NULL, + SODIUM_C99(.buf =) randombytes_internal_random_buf, + SODIUM_C99(.close =) randombytes_internal_random_close +}; diff --git a/external/src/libsodium/src/libsodium/randombytes/randombytes.c b/external/src/libsodium/src/libsodium/randombytes/randombytes.c new file mode 100644 index 0000000..8ac085f --- /dev/null +++ b/external/src/libsodium/src/libsodium/randombytes/randombytes.c @@ -0,0 +1,199 @@ + +#include +#include +#include +#include + +#include + +#ifdef __EMSCRIPTEN__ +# include +#endif + +#include "core.h" +#include "crypto_stream_chacha20.h" +#include "randombytes.h" +#ifndef RANDOMBYTES_CUSTOM_IMPLEMENTATION +# ifdef RANDOMBYTES_DEFAULT_IMPLEMENTATION +# include "randombytes_internal.h" +# endif +# include "randombytes_sysrandom.h" +#endif +#include "private/common.h" + +/* C++Builder defines a "random" macro */ +#undef random + +static const randombytes_implementation *implementation; + +#ifndef RANDOMBYTES_DEFAULT_IMPLEMENTATION +# ifdef __EMSCRIPTEN__ +# define RANDOMBYTES_DEFAULT_IMPLEMENTATION NULL +# else +# define RANDOMBYTES_DEFAULT_IMPLEMENTATION &randombytes_sysrandom_implementation; +# endif +#endif + +static void +randombytes_init_if_needed(void) +{ + if (implementation == NULL) { + implementation = RANDOMBYTES_DEFAULT_IMPLEMENTATION; + randombytes_stir(); + } +} + +int +randombytes_set_implementation(randombytes_implementation *impl) +{ + implementation = impl; + + return 0; +} + +const char * +randombytes_implementation_name(void) +{ +#ifndef __EMSCRIPTEN__ + randombytes_init_if_needed(); + return implementation->implementation_name(); +#else + return "js"; +#endif +} + +uint32_t +randombytes_random(void) +{ +#ifndef __EMSCRIPTEN__ + randombytes_init_if_needed(); + return implementation->random(); +#else + return EM_ASM_INT_V({ + return Module.getRandomValue(); + }); +#endif +} + +void +randombytes_stir(void) +{ +#ifndef __EMSCRIPTEN__ + randombytes_init_if_needed(); + if (implementation->stir != NULL) { + implementation->stir(); + } +#else + EM_ASM({ + if (Module.getRandomValue === undefined) { + try { + var window_ = 'object' === typeof window ? window : self; + var crypto_ = typeof window_.crypto !== 'undefined' ? window_.crypto : window_.msCrypto; + var randomValuesStandard = function() { + var buf = new Uint32Array(1); + crypto_.getRandomValues(buf); + return buf[0] >>> 0; + }; + randomValuesStandard(); + Module.getRandomValue = randomValuesStandard; + } catch (e) { + try { + var crypto = require('crypto'); + var randomValueNodeJS = function() { + var buf = crypto['randomBytes'](4); + return (buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]) >>> 0; + }; + randomValueNodeJS(); + Module.getRandomValue = randomValueNodeJS; + } catch (e) { + throw 'No secure random number generator found'; + } + } + } + }); +#endif +} + +uint32_t +randombytes_uniform(const uint32_t upper_bound) +{ + uint32_t min; + uint32_t r; + +#ifndef __EMSCRIPTEN__ + randombytes_init_if_needed(); + if (implementation->uniform != NULL) { + return implementation->uniform(upper_bound); + } +#endif + if (upper_bound < 2) { + return 0; + } + min = (1U + ~upper_bound) % upper_bound; /* = 2**32 mod upper_bound */ + do { + r = randombytes_random(); + } while (r < min); + /* r is now clamped to a set whose size mod upper_bound == 0 + * the worst case (2**31+1) requires ~ 2 attempts */ + + return r % upper_bound; +} + +void +randombytes_buf(void * const buf, const size_t size) +{ +#ifndef __EMSCRIPTEN__ + randombytes_init_if_needed(); + if (size > (size_t) 0U) { + implementation->buf(buf, size); + } +#else + unsigned char *p = (unsigned char *) buf; + size_t i; + + for (i = (size_t) 0U; i < size; i++) { + p[i] = (unsigned char) randombytes_random(); + } +#endif +} + +void +randombytes_buf_deterministic(void * const buf, const size_t size, + const unsigned char seed[randombytes_SEEDBYTES]) +{ + static const unsigned char nonce[crypto_stream_chacha20_ietf_NONCEBYTES] = { + 'L', 'i', 'b', 's', 'o', 'd', 'i', 'u', 'm', 'D', 'R', 'G' + }; + + COMPILER_ASSERT(randombytes_SEEDBYTES == crypto_stream_chacha20_ietf_KEYBYTES); +#if SIZE_MAX > 0x4000000000ULL + COMPILER_ASSERT(randombytes_BYTES_MAX <= 0x4000000000ULL); + if (size > 0x4000000000ULL) { + sodium_misuse(); + } +#endif + crypto_stream_chacha20_ietf((unsigned char *) buf, (unsigned long long) size, + nonce, seed); +} + +size_t +randombytes_seedbytes(void) +{ + return randombytes_SEEDBYTES; +} + +int +randombytes_close(void) +{ + if (implementation != NULL && implementation->close != NULL) { + return implementation->close(); + } + return 0; +} + +void +randombytes(unsigned char * const buf, const unsigned long long buf_len) +{ + assert(buf_len <= SIZE_MAX); + randombytes_buf(buf, (size_t) buf_len); +} diff --git a/external/src/libsodium/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c b/external/src/libsodium/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c new file mode 100644 index 0000000..38f04f0 --- /dev/null +++ b/external/src/libsodium/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c @@ -0,0 +1,397 @@ + +#include +#include +#include +#include +#include +#include +#ifndef _WIN32 +# include +#endif +#include + +#include +#ifndef _WIN32 +# include +# include +#endif +#ifdef __linux__ +# define _LINUX_SOURCE +#endif +#ifdef HAVE_SYS_RANDOM_H +# include +#endif +#ifdef __linux__ +# ifdef HAVE_GETRANDOM +# define HAVE_LINUX_COMPATIBLE_GETRANDOM +# else +# include +# if defined(SYS_getrandom) && defined(__NR_getrandom) +# define getrandom(B, S, F) syscall(SYS_getrandom, (B), (int) (S), (F)) +# define HAVE_LINUX_COMPATIBLE_GETRANDOM +# endif +# endif +#elif defined(__FreeBSD__) || defined(__DragonFly__) +# include +# if (defined(__FreeBSD_version) && __FreeBSD_version >= 1200000) || \ + (defined(__DragonFly_version) && __DragonFly_version >= 500700) +# define HAVE_LINUX_COMPATIBLE_GETRANDOM +# endif +#endif +#if !defined(NO_BLOCKING_RANDOM_POLL) && defined(__linux__) +# define BLOCK_ON_DEV_RANDOM +#endif +#ifdef BLOCK_ON_DEV_RANDOM +# include +#endif + +#include "core.h" +#include "private/common.h" +#include "randombytes.h" +#include "randombytes_sysrandom.h" +#include "utils.h" + +#ifdef _WIN32 +/* `RtlGenRandom` is used over `CryptGenRandom` on Microsoft Windows based systems: + * - `CryptGenRandom` requires pulling in `CryptoAPI` which causes unnecessary + * memory overhead if this API is not being used for other purposes + * - `RtlGenRandom` is thus called directly instead. A detailed explanation + * can be found here: https://blogs.msdn.microsoft.com/michael_howard/2005/01/14/cryptographically-secure-random-number-on-windows-without-using-cryptoapi/ + * + * In spite of the disclaimer on the `RtlGenRandom` documentation page that was + * written back in the Windows XP days, this function is here to stay. The CRT + * function `rand_s()` directly depends on it, so touching it would break many + * applications released since Windows XP. + * + * Also note that Rust, Firefox and BoringSSL (thus, Google Chrome and everything + * based on Chromium) also depend on it, and that libsodium allows the RNG to be + * replaced without patching nor recompiling the library. + */ +# include +# define RtlGenRandom SystemFunction036 +# if defined(__cplusplus) +extern "C" +# endif +BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); +# pragma comment(lib, "advapi32.lib") +#endif + +#if defined(__OpenBSD__) || defined(__CloudABI__) || defined(__wasi__) +# define HAVE_SAFE_ARC4RANDOM 1 +#endif + +#ifndef SSIZE_MAX +# define SSIZE_MAX (SIZE_MAX / 2 - 1) +#endif + +#ifdef HAVE_SAFE_ARC4RANDOM + +static uint32_t +randombytes_sysrandom(void) +{ + return arc4random(); +} + +static void +randombytes_sysrandom_stir(void) +{ +} + +static void +randombytes_sysrandom_buf(void * const buf, const size_t size) +{ + arc4random_buf(buf, size); +} + +static int +randombytes_sysrandom_close(void) +{ + return 0; +} + +#else /* HAVE_SAFE_ARC4RANDOM */ + +typedef struct SysRandom_ { + int random_data_source_fd; + int initialized; + int getrandom_available; +} SysRandom; + +static SysRandom stream = { + SODIUM_C99(.random_data_source_fd =) -1, + SODIUM_C99(.initialized =) 0, + SODIUM_C99(.getrandom_available =) 0 +}; + +# ifndef _WIN32 +static ssize_t +safe_read(const int fd, void * const buf_, size_t size) +{ + unsigned char *buf = (unsigned char *) buf_; + ssize_t readnb; + + assert(size > (size_t) 0U); + assert(size <= SSIZE_MAX); + do { + while ((readnb = read(fd, buf, size)) < (ssize_t) 0 && + (errno == EINTR || errno == EAGAIN)); /* LCOV_EXCL_LINE */ + if (readnb < (ssize_t) 0) { + return readnb; /* LCOV_EXCL_LINE */ + } + if (readnb == (ssize_t) 0) { + break; /* LCOV_EXCL_LINE */ + } + size -= (size_t) readnb; + buf += readnb; + } while (size > (ssize_t) 0); + + return (ssize_t) (buf - (unsigned char *) buf_); +} + +# ifdef BLOCK_ON_DEV_RANDOM +static int +randombytes_block_on_dev_random(void) +{ + struct pollfd pfd; + int fd; + int pret; + + fd = open("/dev/random", O_RDONLY); + if (fd == -1) { + return 0; + } + pfd.fd = fd; + pfd.events = POLLIN; + pfd.revents = 0; + do { + pret = poll(&pfd, 1, -1); + } while (pret < 0 && (errno == EINTR || errno == EAGAIN)); + if (pret != 1) { + (void) close(fd); + errno = EIO; + return -1; + } + return close(fd); +} +# endif /* BLOCK_ON_DEV_RANDOM */ + +static int +randombytes_sysrandom_random_dev_open(void) +{ +/* LCOV_EXCL_START */ + struct stat st; + static const char *devices[] = { +# ifndef USE_BLOCKING_RANDOM + "/dev/urandom", +# endif + "/dev/random", NULL + }; + const char **device = devices; + int fd; + +# ifdef BLOCK_ON_DEV_RANDOM + if (randombytes_block_on_dev_random() != 0) { + return -1; + } +# endif + do { + fd = open(*device, O_RDONLY); + if (fd != -1) { + if (fstat(fd, &st) == 0 && +# ifdef __COMPCERT__ + 1 +# elif defined(S_ISNAM) + (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode)) +# else + S_ISCHR(st.st_mode) +# endif + ) { +# if defined(F_SETFD) && defined(FD_CLOEXEC) + (void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); +# endif + return fd; + } + (void) close(fd); + } else if (errno == EINTR) { + continue; + } + device++; + } while (*device != NULL); + + errno = EIO; + return -1; +/* LCOV_EXCL_STOP */ +} + +# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM +static int +_randombytes_linux_getrandom(void * const buf, const size_t size) +{ + int readnb; + + assert(size <= 256U); + do { + readnb = getrandom(buf, size, 0); + } while (readnb < 0 && (errno == EINTR || errno == EAGAIN)); + + return (readnb == (int) size) - 1; +} + +static int +randombytes_linux_getrandom(void * const buf_, size_t size) +{ + unsigned char *buf = (unsigned char *) buf_; + size_t chunk_size = 256U; + + do { + if (size < chunk_size) { + chunk_size = size; + assert(chunk_size > (size_t) 0U); + } + if (_randombytes_linux_getrandom(buf, chunk_size) != 0) { + return -1; + } + size -= chunk_size; + buf += chunk_size; + } while (size > (size_t) 0U); + + return 0; +} +# endif /* HAVE_LINUX_COMPATIBLE_GETRANDOM */ + +static void +randombytes_sysrandom_init(void) +{ + const int errno_save = errno; + +# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM + { + unsigned char fodder[16]; + + if (randombytes_linux_getrandom(fodder, sizeof fodder) == 0) { + stream.getrandom_available = 1; + errno = errno_save; + return; + } + stream.getrandom_available = 0; + } +# endif + + if ((stream.random_data_source_fd = + randombytes_sysrandom_random_dev_open()) == -1) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + errno = errno_save; +} + +# else /* _WIN32 */ + +static void +randombytes_sysrandom_init(void) +{ +} +# endif /* _WIN32 */ + +static void +randombytes_sysrandom_stir(void) +{ + if (stream.initialized == 0) { + randombytes_sysrandom_init(); + stream.initialized = 1; + } +} + +static void +randombytes_sysrandom_stir_if_needed(void) +{ + if (stream.initialized == 0) { + randombytes_sysrandom_stir(); + } +} + +static int +randombytes_sysrandom_close(void) +{ + int ret = -1; + +# ifndef _WIN32 + if (stream.random_data_source_fd != -1 && + close(stream.random_data_source_fd) == 0) { + stream.random_data_source_fd = -1; + stream.initialized = 0; + ret = 0; + } +# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM + if (stream.getrandom_available != 0) { + ret = 0; + } +# endif +# else /* _WIN32 */ + if (stream.initialized != 0) { + stream.initialized = 0; + ret = 0; + } +# endif /* _WIN32 */ + return ret; +} + +static void +randombytes_sysrandom_buf(void * const buf, const size_t size) +{ + randombytes_sysrandom_stir_if_needed(); +# if defined(ULLONG_MAX) && defined(SIZE_MAX) +# if SIZE_MAX > ULLONG_MAX + /* coverity[result_independent_of_operands] */ + assert(size <= ULLONG_MAX); +# endif +# endif +# ifndef _WIN32 +# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM + if (stream.getrandom_available != 0) { + if (randombytes_linux_getrandom(buf, size) != 0) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + return; + } +# endif + if (stream.random_data_source_fd == -1 || + safe_read(stream.random_data_source_fd, buf, size) != (ssize_t) size) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +# else /* _WIN32 */ + COMPILER_ASSERT(randombytes_BYTES_MAX <= 0xffffffffUL); + if (size > (size_t) 0xffffffffUL) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + if (! RtlGenRandom((PVOID) buf, (ULONG) size)) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +# endif /* _WIN32 */ +} + +static uint32_t +randombytes_sysrandom(void) +{ + uint32_t r; + + randombytes_sysrandom_buf(&r, sizeof r); + + return r; +} + +#endif /* HAVE_SAFE_ARC4RANDOM */ + +static const char * +randombytes_sysrandom_implementation_name(void) +{ + return "sysrandom"; +} + +struct randombytes_implementation randombytes_sysrandom_implementation = { + SODIUM_C99(.implementation_name =) randombytes_sysrandom_implementation_name, + SODIUM_C99(.random =) randombytes_sysrandom, + SODIUM_C99(.stir =) randombytes_sysrandom_stir, + SODIUM_C99(.uniform =) NULL, + SODIUM_C99(.buf =) randombytes_sysrandom_buf, + SODIUM_C99(.close =) randombytes_sysrandom_close +}; diff --git a/external/src/libsodium/src/libsodium/sodium/codecs.c b/external/src/libsodium/src/libsodium/sodium/codecs.c new file mode 100644 index 0000000..77fa464 --- /dev/null +++ b/external/src/libsodium/src/libsodium/sodium/codecs.c @@ -0,0 +1,333 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "core.h" +#include "utils.h" + +/* Derived from original code by CodesInChaos */ +char * +sodium_bin2hex(char *const hex, const size_t hex_maxlen, + const unsigned char *const bin, const size_t bin_len) +{ + size_t i = (size_t) 0U; + unsigned int x; + int b; + int c; + + if (bin_len >= SIZE_MAX / 2 || hex_maxlen <= bin_len * 2U) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + while (i < bin_len) { + c = bin[i] & 0xf; + b = bin[i] >> 4; + x = (unsigned char) (87U + c + (((c - 10U) >> 8) & ~38U)) << 8 | + (unsigned char) (87U + b + (((b - 10U) >> 8) & ~38U)); + hex[i * 2U] = (char) x; + x >>= 8; + hex[i * 2U + 1U] = (char) x; + i++; + } + hex[i * 2U] = 0U; + + return hex; +} + +int +sodium_hex2bin(unsigned char *const bin, const size_t bin_maxlen, + const char *const hex, const size_t hex_len, + const char *const ignore, size_t *const bin_len, + const char **const hex_end) +{ + size_t bin_pos = (size_t) 0U; + size_t hex_pos = (size_t) 0U; + int ret = 0; + unsigned char c; + unsigned char c_acc = 0U; + unsigned char c_alpha0, c_alpha; + unsigned char c_num0, c_num; + unsigned char c_val; + unsigned char state = 0U; + + while (hex_pos < hex_len) { + c = (unsigned char) hex[hex_pos]; + c_num = c ^ 48U; + c_num0 = (c_num - 10U) >> 8; + c_alpha = (c & ~32U) - 55U; + c_alpha0 = ((c_alpha - 10U) ^ (c_alpha - 16U)) >> 8; + if ((c_num0 | c_alpha0) == 0U) { + if (ignore != NULL && state == 0U && strchr(ignore, c) != NULL) { + hex_pos++; + continue; + } + break; + } + c_val = (c_num0 & c_num) | (c_alpha0 & c_alpha); + if (bin_pos >= bin_maxlen) { + ret = -1; + errno = ERANGE; + break; + } + if (state == 0U) { + c_acc = c_val * 16U; + } else { + bin[bin_pos++] = c_acc | c_val; + } + state = ~state; + hex_pos++; + } + if (state != 0U) { + hex_pos--; + errno = EINVAL; + ret = -1; + } + if (ret != 0) { + bin_pos = (size_t) 0U; + } + if (hex_end != NULL) { + *hex_end = &hex[hex_pos]; + } else if (hex_pos != hex_len) { + errno = EINVAL; + ret = -1; + } + if (bin_len != NULL) { + *bin_len = bin_pos; + } + return ret; +} + +/* + * Some macros for constant-time comparisons. These work over values in + * the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true". + * + * Original code by Thomas Pornin. + */ +#define EQ(x, y) \ + ((((0U - ((unsigned int) (x) ^ (unsigned int) (y))) >> 8) & 0xFF) ^ 0xFF) +#define GT(x, y) ((((unsigned int) (y) - (unsigned int) (x)) >> 8) & 0xFF) +#define GE(x, y) (GT(y, x) ^ 0xFF) +#define LT(x, y) GT(y, x) +#define LE(x, y) GE(y, x) + +static int +b64_byte_to_char(unsigned int x) +{ + return (LT(x, 26) & (x + 'A')) | + (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) | + (GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') | + (EQ(x, 63) & '/'); +} + +static unsigned int +b64_char_to_byte(int c) +{ + const unsigned int x = + (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) | + (GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) | + (GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '+') & 62) | + (EQ(c, '/') & 63); + + return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF)); +} + +static int +b64_byte_to_urlsafe_char(unsigned int x) +{ + return (LT(x, 26) & (x + 'A')) | + (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) | + (GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '-') | + (EQ(x, 63) & '_'); +} + +static unsigned int +b64_urlsafe_char_to_byte(int c) +{ + const unsigned x = + (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) | + (GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) | + (GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '-') & 62) | + (EQ(c, '_') & 63); + + return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF)); +} + + +#define VARIANT_NO_PADDING_MASK 0x2U +#define VARIANT_URLSAFE_MASK 0x4U + +static void +sodium_base64_check_variant(const int variant) +{ + if ((((unsigned int) variant) & ~ 0x6U) != 0x1U) { + sodium_misuse(); + } +} + +size_t +sodium_base64_encoded_len(const size_t bin_len, const int variant) +{ + sodium_base64_check_variant(variant); + + return sodium_base64_ENCODED_LEN(bin_len, variant); +} + +char * +sodium_bin2base64(char * const b64, const size_t b64_maxlen, + const unsigned char * const bin, const size_t bin_len, + const int variant) +{ + size_t acc_len = (size_t) 0; + size_t b64_len; + size_t b64_pos = (size_t) 0; + size_t bin_pos = (size_t) 0; + size_t nibbles; + size_t remainder; + unsigned int acc = 0U; + + sodium_base64_check_variant(variant); + nibbles = bin_len / 3; + remainder = bin_len - 3 * nibbles; + b64_len = nibbles * 4; + if (remainder != 0) { + if ((((unsigned int) variant) & VARIANT_NO_PADDING_MASK) == 0U) { + b64_len += 4; + } else { + b64_len += 2 + (remainder >> 1); + } + } + if (b64_maxlen <= b64_len) { + sodium_misuse(); + } + if ((((unsigned int) variant) & VARIANT_URLSAFE_MASK) != 0U) { + while (bin_pos < bin_len) { + acc = (acc << 8) + bin[bin_pos++]; + acc_len += 8; + while (acc_len >= 6) { + acc_len -= 6; + b64[b64_pos++] = (char) b64_byte_to_urlsafe_char((acc >> acc_len) & 0x3F); + } + } + if (acc_len > 0) { + b64[b64_pos++] = (char) b64_byte_to_urlsafe_char((acc << (6 - acc_len)) & 0x3F); + } + } else { + while (bin_pos < bin_len) { + acc = (acc << 8) + bin[bin_pos++]; + acc_len += 8; + while (acc_len >= 6) { + acc_len -= 6; + b64[b64_pos++] = (char) b64_byte_to_char((acc >> acc_len) & 0x3F); + } + } + if (acc_len > 0) { + b64[b64_pos++] = (char) b64_byte_to_char((acc << (6 - acc_len)) & 0x3F); + } + } + assert(b64_pos <= b64_len); + while (b64_pos < b64_len) { + b64[b64_pos++] = '='; + } + do { + b64[b64_pos++] = 0U; + } while (b64_pos < b64_maxlen); + + return b64; +} + +static int +_sodium_base642bin_skip_padding(const char * const b64, const size_t b64_len, + size_t * const b64_pos_p, + const char * const ignore, size_t padding_len) +{ + int c; + + while (padding_len > 0) { + if (*b64_pos_p >= b64_len) { + errno = ERANGE; + return -1; + } + c = b64[*b64_pos_p]; + if (c == '=') { + padding_len--; + } else if (ignore == NULL || strchr(ignore, c) == NULL) { + errno = EINVAL; + return -1; + } + (*b64_pos_p)++; + } + return 0; +} + +int +sodium_base642bin(unsigned char * const bin, const size_t bin_maxlen, + const char * const b64, const size_t b64_len, + const char * const ignore, size_t * const bin_len, + const char ** const b64_end, const int variant) +{ + size_t acc_len = (size_t) 0; + size_t b64_pos = (size_t) 0; + size_t bin_pos = (size_t) 0; + int is_urlsafe; + int ret = 0; + unsigned int acc = 0U; + unsigned int d; + char c; + + sodium_base64_check_variant(variant); + is_urlsafe = ((unsigned int) variant) & VARIANT_URLSAFE_MASK; + while (b64_pos < b64_len) { + c = b64[b64_pos]; + if (is_urlsafe) { + d = b64_urlsafe_char_to_byte(c); + } else { + d = b64_char_to_byte(c); + } + if (d == 0xFF) { + if (ignore != NULL && strchr(ignore, c) != NULL) { + b64_pos++; + continue; + } + break; + } + acc = (acc << 6) + d; + acc_len += 6; + if (acc_len >= 8) { + acc_len -= 8; + if (bin_pos >= bin_maxlen) { + errno = ERANGE; + ret = -1; + break; + } + bin[bin_pos++] = (acc >> acc_len) & 0xFF; + } + b64_pos++; + } + if (acc_len > 4U || (acc & ((1U << acc_len) - 1U)) != 0U) { + ret = -1; + } else if (ret == 0 && + (((unsigned int) variant) & VARIANT_NO_PADDING_MASK) == 0U) { + ret = _sodium_base642bin_skip_padding(b64, b64_len, &b64_pos, ignore, + acc_len / 2); + } + if (ret != 0) { + bin_pos = (size_t) 0U; + } else if (ignore != NULL) { + while (b64_pos < b64_len && strchr(ignore, b64[b64_pos]) != NULL) { + b64_pos++; + } + } + if (b64_end != NULL) { + *b64_end = &b64[b64_pos]; + } else if (b64_pos != b64_len) { + errno = EINVAL; + ret = -1; + } + if (bin_len != NULL) { + *bin_len = bin_pos; + } + return ret; +} diff --git a/external/src/libsodium/src/libsodium/sodium/core.c b/external/src/libsodium/src/libsodium/sodium/core.c new file mode 100644 index 0000000..bad3217 --- /dev/null +++ b/external/src/libsodium/src/libsodium/sodium/core.c @@ -0,0 +1,214 @@ + +#include +#include +#include +#include +#ifdef _WIN32 +# include +#elif defined(HAVE_PTHREAD) +# include +#endif + +#include "core.h" +#include "crypto_generichash.h" +#include "crypto_onetimeauth.h" +#include "crypto_scalarmult.h" +#include "crypto_stream_chacha20.h" +#include "crypto_stream_salsa20.h" +#include "randombytes.h" +#include "runtime.h" +#include "utils.h" +#include "private/implementations.h" +#include "private/mutex.h" + +static volatile int initialized; +static volatile int locked; + +int +sodium_init(void) +{ + if (sodium_crit_enter() != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + if (initialized != 0) { + if (sodium_crit_leave() != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + return 1; + } + _sodium_runtime_get_cpu_features(); + randombytes_stir(); + _sodium_alloc_init(); + _crypto_pwhash_argon2_pick_best_implementation(); + _crypto_generichash_blake2b_pick_best_implementation(); + _crypto_onetimeauth_poly1305_pick_best_implementation(); + _crypto_scalarmult_curve25519_pick_best_implementation(); + _crypto_stream_chacha20_pick_best_implementation(); + _crypto_stream_salsa20_pick_best_implementation(); + initialized = 1; + if (sodium_crit_leave() != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; +} + +#ifdef _WIN32 + +static CRITICAL_SECTION _sodium_lock; +static volatile LONG _sodium_lock_initialized; + +static int +_sodium_crit_init(void) +{ + LONG status = 0L; + + while ((status = InterlockedCompareExchange(&_sodium_lock_initialized, + 1L, 0L)) == 1L) { + Sleep(0); + } + + switch (status) { + case 0L: + InitializeCriticalSection(&_sodium_lock); + return InterlockedExchange(&_sodium_lock_initialized, 2L) == 1L ? 0 : -1; + case 2L: + return 0; + default: /* should never be reached */ + return -1; + } +} + +int +sodium_crit_enter(void) +{ + if (_sodium_crit_init() != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + EnterCriticalSection(&_sodium_lock); + assert(locked == 0); + locked = 1; + + return 0; +} + +int +sodium_crit_leave(void) +{ + if (locked == 0) { +# ifdef EPERM + errno = EPERM; +# endif + return -1; + } + locked = 0; + LeaveCriticalSection(&_sodium_lock); + + return 0; +} + +#elif defined(HAVE_PTHREAD) && !defined(__EMSCRIPTEN__) + +static pthread_mutex_t _sodium_lock = PTHREAD_MUTEX_INITIALIZER; + +int +sodium_crit_enter(void) +{ + int ret; + + if ((ret = pthread_mutex_lock(&_sodium_lock)) == 0) { + assert(locked == 0); + locked = 1; + } + return ret; +} + +int +sodium_crit_leave(void) +{ + if (locked == 0) { +# ifdef EPERM + errno = EPERM; +# endif + return -1; + } + locked = 0; + + return pthread_mutex_unlock(&_sodium_lock); +} + +#elif defined(HAVE_ATOMIC_OPS) && !defined(__EMSCRIPTEN__) + +static volatile int _sodium_lock; + +int +sodium_crit_enter(void) +{ +# ifdef HAVE_NANOSLEEP + struct timespec q; + memset(&q, 0, sizeof q); +# endif + while (__sync_lock_test_and_set(&_sodium_lock, 1) != 0) { +# ifdef HAVE_NANOSLEEP + (void) nanosleep(&q, NULL); +# elif defined(__x86_64__) || defined(__i386__) + __asm__ __volatile__ ("pause"); +# endif + } + return 0; +} + +int +sodium_crit_leave(void) +{ + __sync_lock_release(&_sodium_lock); + + return 0; +} + +#else + +int +sodium_crit_enter(void) +{ + return 0; +} + +int +sodium_crit_leave(void) +{ + return 0; +} + +#endif + +static void (*_misuse_handler)(void); + +void +sodium_misuse(void) +{ + void (*handler)(void); + + (void) sodium_crit_leave(); + if (sodium_crit_enter() == 0) { + handler = _misuse_handler; + if (handler != NULL) { + handler(); + } + } +/* LCOV_EXCL_START */ + abort(); +} +/* LCOV_EXCL_STOP */ + +int +sodium_set_misuse_handler(void (*handler)(void)) +{ + if (sodium_crit_enter() != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + _misuse_handler = handler; + if (sodium_crit_leave() != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; +} diff --git a/external/src/libsodium/src/libsodium/sodium/runtime.c b/external/src/libsodium/src/libsodium/sodium/runtime.c new file mode 100644 index 0000000..9dfe54f --- /dev/null +++ b/external/src/libsodium/src/libsodium/sodium/runtime.c @@ -0,0 +1,309 @@ +#include +#include +#ifdef HAVE_ANDROID_GETCPUFEATURES +# include +#endif + +#include "private/common.h" +#include "runtime.h" + +typedef struct CPUFeatures_ { + int initialized; + int has_neon; + int has_sse2; + int has_sse3; + int has_ssse3; + int has_sse41; + int has_avx; + int has_avx2; + int has_avx512f; + int has_pclmul; + int has_aesni; + int has_rdrand; +} CPUFeatures; + +static CPUFeatures _cpu_features; + +#define CPUID_EBX_AVX2 0x00000020 +#define CPUID_EBX_AVX512F 0x00010000 + +#define CPUID_ECX_SSE3 0x00000001 +#define CPUID_ECX_PCLMUL 0x00000002 +#define CPUID_ECX_SSSE3 0x00000200 +#define CPUID_ECX_SSE41 0x00080000 +#define CPUID_ECX_AESNI 0x02000000 +#define CPUID_ECX_XSAVE 0x04000000 +#define CPUID_ECX_OSXSAVE 0x08000000 +#define CPUID_ECX_AVX 0x10000000 +#define CPUID_ECX_RDRAND 0x40000000 + +#define CPUID_EDX_SSE2 0x04000000 + +#define XCR0_SSE 0x00000002 +#define XCR0_AVX 0x00000004 +#define XCR0_OPMASK 0x00000020 +#define XCR0_ZMM_HI256 0x00000040 +#define XCR0_HI16_ZMM 0x00000080 + +static int +_sodium_runtime_arm_cpu_features(CPUFeatures * const cpu_features) +{ +#ifndef __arm__ + cpu_features->has_neon = 0; + return -1; +#else +# ifdef __APPLE__ +# ifdef __ARM_NEON__ + cpu_features->has_neon = 1; +# else + cpu_features->has_neon = 0; +# endif +# elif defined(HAVE_ANDROID_GETCPUFEATURES) && \ + defined(ANDROID_CPU_ARM_FEATURE_NEON) + cpu_features->has_neon = + (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0x0; +# else + cpu_features->has_neon = 0; +# endif + return 0; +#endif +} + +static void +_cpuid(unsigned int cpu_info[4U], const unsigned int cpu_info_type) +{ +#if defined(_MSC_VER) && \ + (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86)) + __cpuid((int *) cpu_info, cpu_info_type); +#elif defined(HAVE_CPUID) + cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0; +# ifdef __i386__ + __asm__ __volatile__( + "pushfl; pushfl; " + "popl %0; " + "movl %0, %1; xorl %2, %0; " + "pushl %0; " + "popfl; pushfl; popl %0; popfl" + : "=&r"(cpu_info[0]), "=&r"(cpu_info[1]) + : "i"(0x200000)); + if (((cpu_info[0] ^ cpu_info[1]) & 0x200000) == 0x0) { + return; /* LCOV_EXCL_LINE */ + } +# endif +# ifdef __i386__ + __asm__ __volatile__("xchgl %%ebx, %k1; cpuid; xchgl %%ebx, %k1" + : "=a"(cpu_info[0]), "=&r"(cpu_info[1]), + "=c"(cpu_info[2]), "=d"(cpu_info[3]) + : "0"(cpu_info_type), "2"(0U)); +# elif defined(__x86_64__) + __asm__ __volatile__("xchgq %%rbx, %q1; cpuid; xchgq %%rbx, %q1" + : "=a"(cpu_info[0]), "=&r"(cpu_info[1]), + "=c"(cpu_info[2]), "=d"(cpu_info[3]) + : "0"(cpu_info_type), "2"(0U)); +# else + __asm__ __volatile__("cpuid" + : "=a"(cpu_info[0]), "=b"(cpu_info[1]), + "=c"(cpu_info[2]), "=d"(cpu_info[3]) + : "0"(cpu_info_type), "2"(0U)); +# endif +#else + (void) cpu_info_type; + cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0; +#endif +} + +static int +_sodium_runtime_intel_cpu_features(CPUFeatures * const cpu_features) +{ + unsigned int cpu_info[4]; + unsigned int id; + uint32_t xcr0 = 0U; + + _cpuid(cpu_info, 0x0); + if ((id = cpu_info[0]) == 0U) { + return -1; /* LCOV_EXCL_LINE */ + } + _cpuid(cpu_info, 0x00000001); +#ifdef HAVE_EMMINTRIN_H + cpu_features->has_sse2 = ((cpu_info[3] & CPUID_EDX_SSE2) != 0x0); +#else + cpu_features->has_sse2 = 0; +#endif + +#ifdef HAVE_PMMINTRIN_H + cpu_features->has_sse3 = ((cpu_info[2] & CPUID_ECX_SSE3) != 0x0); +#else + cpu_features->has_sse3 = 0; +#endif + +#ifdef HAVE_TMMINTRIN_H + cpu_features->has_ssse3 = ((cpu_info[2] & CPUID_ECX_SSSE3) != 0x0); +#else + cpu_features->has_ssse3 = 0; +#endif + +#ifdef HAVE_SMMINTRIN_H + cpu_features->has_sse41 = ((cpu_info[2] & CPUID_ECX_SSE41) != 0x0); +#else + cpu_features->has_sse41 = 0; +#endif + + cpu_features->has_avx = 0; + + (void) xcr0; +#ifdef HAVE_AVXINTRIN_H + if ((cpu_info[2] & (CPUID_ECX_AVX | CPUID_ECX_XSAVE | CPUID_ECX_OSXSAVE)) == + (CPUID_ECX_AVX | CPUID_ECX_XSAVE | CPUID_ECX_OSXSAVE)) { + xcr0 = 0U; +# if defined(HAVE__XGETBV) || \ + (defined(_MSC_VER) && defined(_XCR_XFEATURE_ENABLED_MASK) && _MSC_FULL_VER >= 160040219) + xcr0 = (uint32_t) _xgetbv(0); +# elif defined(_MSC_VER) && defined(_M_IX86) + /* + * Visual Studio documentation states that eax/ecx/edx don't need to + * be preserved in inline assembly code. But that doesn't seem to + * always hold true on Visual Studio 2010. + */ + __asm { + push eax + push ecx + push edx + xor ecx, ecx + _asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0 + mov xcr0, eax + pop edx + pop ecx + pop eax + } +# elif defined(HAVE_AVX_ASM) + __asm__ __volatile__(".byte 0x0f, 0x01, 0xd0" /* XGETBV */ + : "=a"(xcr0) + : "c"((uint32_t) 0U) + : "%edx"); +# endif + if ((xcr0 & (XCR0_SSE | XCR0_AVX)) == (XCR0_SSE | XCR0_AVX)) { + cpu_features->has_avx = 1; + } + } +#endif + + cpu_features->has_avx2 = 0; +#ifdef HAVE_AVX2INTRIN_H + if (cpu_features->has_avx) { + unsigned int cpu_info7[4]; + + _cpuid(cpu_info7, 0x00000007); + cpu_features->has_avx2 = ((cpu_info7[1] & CPUID_EBX_AVX2) != 0x0); + } +#endif + + cpu_features->has_avx512f = 0; +#ifdef HAVE_AVX512FINTRIN_H + if (cpu_features->has_avx2) { + unsigned int cpu_info7[4]; + + _cpuid(cpu_info7, 0x00000007); + /* LCOV_EXCL_START */ + if ((cpu_info7[1] & CPUID_EBX_AVX512F) == CPUID_EBX_AVX512F && + (xcr0 & (XCR0_OPMASK | XCR0_ZMM_HI256 | XCR0_HI16_ZMM)) + == (XCR0_OPMASK | XCR0_ZMM_HI256 | XCR0_HI16_ZMM)) { + cpu_features->has_avx512f = 1; + } + /* LCOV_EXCL_STOP */ + } +#endif + +#ifdef HAVE_WMMINTRIN_H + cpu_features->has_pclmul = ((cpu_info[2] & CPUID_ECX_PCLMUL) != 0x0); + cpu_features->has_aesni = ((cpu_info[2] & CPUID_ECX_AESNI) != 0x0); +#else + cpu_features->has_pclmul = 0; + cpu_features->has_aesni = 0; +#endif + +#ifdef HAVE_RDRAND + cpu_features->has_rdrand = ((cpu_info[2] & CPUID_ECX_RDRAND) != 0x0); +#else + cpu_features->has_rdrand = 0; +#endif + + return 0; +} + +int +_sodium_runtime_get_cpu_features(void) +{ + int ret = -1; + + ret &= _sodium_runtime_arm_cpu_features(&_cpu_features); + ret &= _sodium_runtime_intel_cpu_features(&_cpu_features); + _cpu_features.initialized = 1; + + return ret; +} + +int +sodium_runtime_has_neon(void) +{ + return _cpu_features.has_neon; +} + +int +sodium_runtime_has_sse2(void) +{ + return _cpu_features.has_sse2; +} + +int +sodium_runtime_has_sse3(void) +{ + return _cpu_features.has_sse3; +} + +int +sodium_runtime_has_ssse3(void) +{ + return _cpu_features.has_ssse3; +} + +int +sodium_runtime_has_sse41(void) +{ + return _cpu_features.has_sse41; +} + +int +sodium_runtime_has_avx(void) +{ + return _cpu_features.has_avx; +} + +int +sodium_runtime_has_avx2(void) +{ + return _cpu_features.has_avx2; +} + +int +sodium_runtime_has_avx512f(void) +{ + return _cpu_features.has_avx512f; +} + +int +sodium_runtime_has_pclmul(void) +{ + return _cpu_features.has_pclmul; +} + +int +sodium_runtime_has_aesni(void) +{ + return _cpu_features.has_aesni; +} + +int +sodium_runtime_has_rdrand(void) +{ + return _cpu_features.has_rdrand; +} diff --git a/external/src/libsodium/src/libsodium/sodium/utils.c b/external/src/libsodium/src/libsodium/sodium/utils.c new file mode 100644 index 0000000..cdaff9d --- /dev/null +++ b/external/src/libsodium/src/libsodium/sodium/utils.c @@ -0,0 +1,800 @@ +#ifndef __STDC_WANT_LIB_EXT1__ +# define __STDC_WANT_LIB_EXT1__ 1 +#endif +#include +#include +#include +#include +#include +#include +#include + +#ifndef __wasm__ +# include +#endif + +#ifdef HAVE_SYS_MMAN_H +# include +#endif + +#ifdef _WIN32 +# include +# include +#else +# include +#endif + +#ifndef HAVE_C_VARARRAYS +# ifdef HAVE_ALLOCA_H +# include +# elif !defined(alloca) +# if defined(__clang__) || defined(__GNUC__) +# define alloca __builtin_alloca +# elif defined _AIX +# define alloca __alloca +# elif defined _MSC_VER +# include +# define alloca _alloca +# else +# include +# ifdef __cplusplus +extern "C" +# endif +void *alloca (size_t); +# endif +# endif +#endif + +#include "core.h" +#include "randombytes.h" +#include "utils.h" + +#ifndef ENOSYS +# define ENOSYS ENXIO +#endif + +#if defined(_WIN32) && \ + (!defined(WINAPI_FAMILY) || WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) +# define WINAPI_DESKTOP +#endif + +#define CANARY_SIZE 16U +#define GARBAGE_VALUE 0xdb + +#ifndef MAP_NOCORE +# ifdef MAP_CONCEAL +# define MAP_NOCORE MAP_CONCEAL +# else +# define MAP_NOCORE 0 +# endif +#endif +#if !defined(MAP_ANON) && defined(MAP_ANONYMOUS) +# define MAP_ANON MAP_ANONYMOUS +#endif +#if defined(WINAPI_DESKTOP) || (defined(MAP_ANON) && defined(HAVE_MMAP)) || \ + defined(HAVE_POSIX_MEMALIGN) +# define HAVE_ALIGNED_MALLOC +#endif +#if defined(HAVE_MPROTECT) && \ + !(defined(PROT_NONE) && defined(PROT_READ) && defined(PROT_WRITE)) +# undef HAVE_MPROTECT +#endif +#if defined(HAVE_ALIGNED_MALLOC) && \ + (defined(WINAPI_DESKTOP) || defined(HAVE_MPROTECT)) +# define HAVE_PAGE_PROTECTION +#endif +#if !defined(MADV_DODUMP) && defined(MADV_CORE) +# define MADV_DODUMP MADV_CORE +# define MADV_DONTDUMP MADV_NOCORE +#endif + +#ifndef DEFAULT_PAGE_SIZE +# ifdef PAGE_SIZE +# define DEFAULT_PAGE_SIZE PAGE_SIZE +# else +# define DEFAULT_PAGE_SIZE 0x10000 +# endif +#endif + +static size_t page_size = DEFAULT_PAGE_SIZE; +static unsigned char canary[CANARY_SIZE]; + +/* LCOV_EXCL_START */ +#ifdef HAVE_WEAK_SYMBOLS +__attribute__((weak)) void +_sodium_dummy_symbol_to_prevent_memzero_lto(void *const pnt, + const size_t len); +__attribute__((weak)) void +_sodium_dummy_symbol_to_prevent_memzero_lto(void *const pnt, + const size_t len) +{ + (void) pnt; /* LCOV_EXCL_LINE */ + (void) len; /* LCOV_EXCL_LINE */ +} +#endif +/* LCOV_EXCL_STOP */ + +void +sodium_memzero(void * const pnt, const size_t len) +{ +#ifdef _WIN32 + SecureZeroMemory(pnt, len); +#elif defined(HAVE_MEMSET_S) + if (len > 0U && memset_s(pnt, (rsize_t) len, 0, (rsize_t) len) != 0) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +#elif defined(HAVE_EXPLICIT_BZERO) + explicit_bzero(pnt, len); +#elif defined(HAVE_EXPLICIT_MEMSET) + explicit_memset(pnt, 0, len); +#elif HAVE_WEAK_SYMBOLS + if (len > 0U) { + memset(pnt, 0, len); + _sodium_dummy_symbol_to_prevent_memzero_lto(pnt, len); + } +# ifdef HAVE_INLINE_ASM + __asm__ __volatile__ ("" : : "r"(pnt) : "memory"); +# endif +#else + volatile unsigned char *volatile pnt_ = + (volatile unsigned char *volatile) pnt; + size_t i = (size_t) 0U; + + while (i < len) { + pnt_[i++] = 0U; + } +#endif +} + +void +sodium_stackzero(const size_t len) +{ +#ifdef HAVE_C_VARARRAYS + unsigned char fodder[len]; + sodium_memzero(fodder, len); +#elif HAVE_ALLOCA + sodium_memzero(alloca(len), len); +#endif +} + +#ifdef HAVE_WEAK_SYMBOLS +__attribute__((weak)) void +_sodium_dummy_symbol_to_prevent_memcmp_lto(const unsigned char *b1, + const unsigned char *b2, + const size_t len); +__attribute__((weak)) void +_sodium_dummy_symbol_to_prevent_memcmp_lto(const unsigned char *b1, + const unsigned char *b2, + const size_t len) +{ + (void) b1; + (void) b2; + (void) len; +} +#endif + +int +sodium_memcmp(const void *const b1_, const void *const b2_, size_t len) +{ +#ifdef HAVE_WEAK_SYMBOLS + const unsigned char *b1 = (const unsigned char *) b1_; + const unsigned char *b2 = (const unsigned char *) b2_; +#else + const volatile unsigned char *volatile b1 = + (const volatile unsigned char *volatile) b1_; + const volatile unsigned char *volatile b2 = + (const volatile unsigned char *volatile) b2_; +#endif + size_t i; + volatile unsigned char d = 0U; + +#if HAVE_WEAK_SYMBOLS + _sodium_dummy_symbol_to_prevent_memcmp_lto(b1, b2, len); +#endif + for (i = 0U; i < len; i++) { + d |= b1[i] ^ b2[i]; + } + return (1 & ((d - 1) >> 8)) - 1; +} + +#ifdef HAVE_WEAK_SYMBOLS +__attribute__((weak)) void +_sodium_dummy_symbol_to_prevent_compare_lto(const unsigned char *b1, + const unsigned char *b2, + const size_t len); +__attribute__((weak)) void +_sodium_dummy_symbol_to_prevent_compare_lto(const unsigned char *b1, + const unsigned char *b2, + const size_t len) +{ + (void) b1; + (void) b2; + (void) len; +} +#endif + +int +sodium_compare(const unsigned char *b1_, const unsigned char *b2_, size_t len) +{ +#ifdef HAVE_WEAK_SYMBOLS + const unsigned char *b1 = b1_; + const unsigned char *b2 = b2_; +#else + const volatile unsigned char *volatile b1 = + (const volatile unsigned char *volatile) b1_; + const volatile unsigned char *volatile b2 = + (const volatile unsigned char *volatile) b2_; +#endif + size_t i; + volatile unsigned char gt = 0U; + volatile unsigned char eq = 1U; + uint16_t x1, x2; + +#if HAVE_WEAK_SYMBOLS + _sodium_dummy_symbol_to_prevent_compare_lto(b1, b2, len); +#endif + i = len; + while (i != 0U) { + i--; + x1 = b1[i]; + x2 = b2[i]; + gt |= ((x2 - x1) >> 8) & eq; + eq &= ((x2 ^ x1) - 1) >> 8; + } + return (int) (gt + gt + eq) - 1; +} + +int +sodium_is_zero(const unsigned char *n, const size_t nlen) +{ + size_t i; + volatile unsigned char d = 0U; + + for (i = 0U; i < nlen; i++) { + d |= n[i]; + } + return 1 & ((d - 1) >> 8); +} + +void +sodium_increment(unsigned char *n, const size_t nlen) +{ + size_t i = 0U; + uint_fast16_t c = 1U; + +#ifdef HAVE_AMD64_ASM + uint64_t t64, t64_2; + uint32_t t32; + + if (nlen == 12U) { + __asm__ __volatile__( + "xorq %[t64], %[t64] \n" + "xorl %[t32], %[t32] \n" + "stc \n" + "adcq %[t64], (%[out]) \n" + "adcl %[t32], 8(%[out]) \n" + : [t64] "=&r"(t64), [t32] "=&r"(t32) + : [out] "D"(n) + : "memory", "flags", "cc"); + return; + } else if (nlen == 24U) { + __asm__ __volatile__( + "movq $1, %[t64] \n" + "xorq %[t64_2], %[t64_2] \n" + "addq %[t64], (%[out]) \n" + "adcq %[t64_2], 8(%[out]) \n" + "adcq %[t64_2], 16(%[out]) \n" + : [t64] "=&r"(t64), [t64_2] "=&r"(t64_2) + : [out] "D"(n) + : "memory", "flags", "cc"); + return; + } else if (nlen == 8U) { + __asm__ __volatile__("incq (%[out]) \n" + : + : [out] "D"(n) + : "memory", "flags", "cc"); + return; + } +#endif + for (; i < nlen; i++) { + c += (uint_fast16_t) n[i]; + n[i] = (unsigned char) c; + c >>= 8; + } +} + +void +sodium_add(unsigned char *a, const unsigned char *b, const size_t len) +{ + size_t i; + uint_fast16_t c = 0U; + +#ifdef HAVE_AMD64_ASM + uint64_t t64, t64_2, t64_3; + uint32_t t32; + + if (len == 12U) { + __asm__ __volatile__( + "movq (%[in]), %[t64] \n" + "movl 8(%[in]), %[t32] \n" + "addq %[t64], (%[out]) \n" + "adcl %[t32], 8(%[out]) \n" + : [t64] "=&r"(t64), [t32] "=&r"(t32) + : [in] "S"(b), [out] "D"(a) + : "memory", "flags", "cc"); + return; + } else if (len == 24U) { + __asm__ __volatile__( + "movq (%[in]), %[t64] \n" + "movq 8(%[in]), %[t64_2] \n" + "movq 16(%[in]), %[t64_3] \n" + "addq %[t64], (%[out]) \n" + "adcq %[t64_2], 8(%[out]) \n" + "adcq %[t64_3], 16(%[out]) \n" + : [t64] "=&r"(t64), [t64_2] "=&r"(t64_2), [t64_3] "=&r"(t64_3) + : [in] "S"(b), [out] "D"(a) + : "memory", "flags", "cc"); + return; + } else if (len == 8U) { + __asm__ __volatile__( + "movq (%[in]), %[t64] \n" + "addq %[t64], (%[out]) \n" + : [t64] "=&r"(t64) + : [in] "S"(b), [out] "D"(a) + : "memory", "flags", "cc"); + return; + } +#endif + for (i = 0U; i < len; i++) { + c += (uint_fast16_t) a[i] + (uint_fast16_t) b[i]; + a[i] = (unsigned char) c; + c >>= 8; + } +} + +void +sodium_sub(unsigned char *a, const unsigned char *b, const size_t len) +{ + uint_fast16_t c = 0U; + size_t i; + +#ifdef HAVE_AMD64_ASM + uint64_t t64_1, t64_2, t64_3, t64_4; + uint64_t t64_5, t64_6, t64_7, t64_8; + uint32_t t32; + + if (len == 64U) { + __asm__ __volatile__( + "movq (%[in]), %[t64_1] \n" + "movq 8(%[in]), %[t64_2] \n" + "movq 16(%[in]), %[t64_3] \n" + "movq 24(%[in]), %[t64_4] \n" + "movq 32(%[in]), %[t64_5] \n" + "movq 40(%[in]), %[t64_6] \n" + "movq 48(%[in]), %[t64_7] \n" + "movq 56(%[in]), %[t64_8] \n" + "subq %[t64_1], (%[out]) \n" + "sbbq %[t64_2], 8(%[out]) \n" + "sbbq %[t64_3], 16(%[out]) \n" + "sbbq %[t64_4], 24(%[out]) \n" + "sbbq %[t64_5], 32(%[out]) \n" + "sbbq %[t64_6], 40(%[out]) \n" + "sbbq %[t64_7], 48(%[out]) \n" + "sbbq %[t64_8], 56(%[out]) \n" + : [t64_1] "=&r"(t64_1), [t64_2] "=&r"(t64_2), [t64_3] "=&r"(t64_3), [t64_4] "=&r"(t64_4), + [t64_5] "=&r"(t64_5), [t64_6] "=&r"(t64_6), [t64_7] "=&r"(t64_7), [t64_8] "=&r"(t64_8) + : [in] "S"(b), [out] "D"(a) + : "memory", "flags", "cc"); + return; + } +#endif + for (i = 0U; i < len; i++) { + c = (uint_fast16_t) a[i] - (uint_fast16_t) b[i] - c; + a[i] = (unsigned char) c; + c = (c >> 8) & 1U; + } +} + +int +_sodium_alloc_init(void) +{ +#ifdef HAVE_ALIGNED_MALLOC +# if defined(_SC_PAGESIZE) + long page_size_ = sysconf(_SC_PAGESIZE); + if (page_size_ > 0L) { + page_size = (size_t) page_size_; + } +# elif defined(WINAPI_DESKTOP) + SYSTEM_INFO si; + GetSystemInfo(&si); + page_size = (size_t) si.dwPageSize; +# else +# warning Unknown page size +# endif + if (page_size < CANARY_SIZE || page_size < sizeof(size_t)) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +#endif + randombytes_buf(canary, sizeof canary); + + return 0; +} + +int +sodium_mlock(void *const addr, const size_t len) +{ +#if defined(MADV_DONTDUMP) && defined(HAVE_MADVISE) + (void) madvise(addr, len, MADV_DONTDUMP); +#endif +#ifdef HAVE_MLOCK + return mlock(addr, len); +#elif defined(WINAPI_DESKTOP) + return -(VirtualLock(addr, len) == 0); +#else + errno = ENOSYS; + return -1; +#endif +} + +int +sodium_munlock(void *const addr, const size_t len) +{ + sodium_memzero(addr, len); +#if defined(MADV_DODUMP) && defined(HAVE_MADVISE) + (void) madvise(addr, len, MADV_DODUMP); +#endif +#ifdef HAVE_MLOCK + return munlock(addr, len); +#elif defined(WINAPI_DESKTOP) + return -(VirtualUnlock(addr, len) == 0); +#else + errno = ENOSYS; + return -1; +#endif +} + +static int +_mprotect_noaccess(void *ptr, size_t size) +{ +#ifdef HAVE_MPROTECT + return mprotect(ptr, size, PROT_NONE); +#elif defined(WINAPI_DESKTOP) + DWORD old; + return -(VirtualProtect(ptr, size, PAGE_NOACCESS, &old) == 0); +#else + errno = ENOSYS; + return -1; +#endif +} + +static int +_mprotect_readonly(void *ptr, size_t size) +{ +#ifdef HAVE_MPROTECT + return mprotect(ptr, size, PROT_READ); +#elif defined(WINAPI_DESKTOP) + DWORD old; + return -(VirtualProtect(ptr, size, PAGE_READONLY, &old) == 0); +#else + errno = ENOSYS; + return -1; +#endif +} + +static int +_mprotect_readwrite(void *ptr, size_t size) +{ +#ifdef HAVE_MPROTECT + return mprotect(ptr, size, PROT_READ | PROT_WRITE); +#elif defined(WINAPI_DESKTOP) + DWORD old; + return -(VirtualProtect(ptr, size, PAGE_READWRITE, &old) == 0); +#else + errno = ENOSYS; + return -1; +#endif +} + +#ifdef HAVE_ALIGNED_MALLOC + +__attribute__((noreturn)) static void +_out_of_bounds(void) +{ +# ifndef __wasm__ +# ifdef SIGSEGV + raise(SIGSEGV); +# elif defined(SIGKILL) + raise(SIGKILL); +# endif +# endif + abort(); /* not something we want any higher-level API to catch */ +} /* LCOV_EXCL_LINE */ + +static inline size_t +_page_round(const size_t size) +{ + const size_t page_mask = page_size - 1U; + + return (size + page_mask) & ~page_mask; +} + +static __attribute__((malloc)) unsigned char * +_alloc_aligned(const size_t size) +{ + void *ptr; + +# if defined(MAP_ANON) && defined(HAVE_MMAP) + if ((ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE | MAP_NOCORE, -1, 0)) == + MAP_FAILED) { + ptr = NULL; /* LCOV_EXCL_LINE */ + } /* LCOV_EXCL_LINE */ +# elif defined(HAVE_POSIX_MEMALIGN) + if (posix_memalign(&ptr, page_size, size) != 0) { + ptr = NULL; /* LCOV_EXCL_LINE */ + } /* LCOV_EXCL_LINE */ +# elif defined(WINAPI_DESKTOP) + ptr = VirtualAlloc(NULL, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); +# else +# error Bug +# endif + return (unsigned char *) ptr; +} + +static void +_free_aligned(unsigned char *const ptr, const size_t size) +{ +# if defined(MAP_ANON) && defined(HAVE_MMAP) + (void) munmap(ptr, size); +# elif defined(HAVE_POSIX_MEMALIGN) + free(ptr); +# elif defined(WINAPI_DESKTOP) + VirtualFree(ptr, 0U, MEM_RELEASE); +# else +# error Bug +#endif +} + +static unsigned char * +_unprotected_ptr_from_user_ptr(void *const ptr) +{ + uintptr_t unprotected_ptr_u; + unsigned char *canary_ptr; + size_t page_mask; + + canary_ptr = ((unsigned char *) ptr) - sizeof canary; + page_mask = page_size - 1U; + unprotected_ptr_u = ((uintptr_t) canary_ptr & (uintptr_t) ~page_mask); + if (unprotected_ptr_u <= page_size * 2U) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + return (unsigned char *) unprotected_ptr_u; +} + +#endif /* HAVE_ALIGNED_MALLOC */ + +#ifndef HAVE_ALIGNED_MALLOC +static __attribute__((malloc)) void * +_sodium_malloc(const size_t size) +{ + return malloc(size > (size_t) 0U ? size : (size_t) 1U); +} +#else +static __attribute__((malloc)) void * +_sodium_malloc(const size_t size) +{ + void *user_ptr; + unsigned char *base_ptr; + unsigned char *canary_ptr; + unsigned char *unprotected_ptr; + size_t size_with_canary; + size_t total_size; + size_t unprotected_size; + + if (size >= (size_t) SIZE_MAX - page_size * 4U) { + errno = ENOMEM; + return NULL; + } + if (page_size <= sizeof canary || page_size < sizeof unprotected_size) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + size_with_canary = (sizeof canary) + size; + unprotected_size = _page_round(size_with_canary); + total_size = page_size + page_size + unprotected_size + page_size; + if ((base_ptr = _alloc_aligned(total_size)) == NULL) { + return NULL; /* LCOV_EXCL_LINE */ + } + unprotected_ptr = base_ptr + page_size * 2U; + _mprotect_noaccess(base_ptr + page_size, page_size); +# ifndef HAVE_PAGE_PROTECTION + memcpy(unprotected_ptr + unprotected_size, canary, sizeof canary); +# endif + _mprotect_noaccess(unprotected_ptr + unprotected_size, page_size); + sodium_mlock(unprotected_ptr, unprotected_size); + canary_ptr = + unprotected_ptr + _page_round(size_with_canary) - size_with_canary; + user_ptr = canary_ptr + sizeof canary; + memcpy(canary_ptr, canary, sizeof canary); + memcpy(base_ptr, &unprotected_size, sizeof unprotected_size); + _mprotect_readonly(base_ptr, page_size); + assert(_unprotected_ptr_from_user_ptr(user_ptr) == unprotected_ptr); + + return user_ptr; +} +#endif /* !HAVE_ALIGNED_MALLOC */ + +__attribute__((malloc)) void * +sodium_malloc(const size_t size) +{ + void *ptr; + + if ((ptr = _sodium_malloc(size)) == NULL) { + return NULL; + } + memset(ptr, (int) GARBAGE_VALUE, size); + + return ptr; +} + +__attribute__((malloc)) void * +sodium_allocarray(size_t count, size_t size) +{ + if (count > (size_t) 0U && size >= (size_t) SIZE_MAX / count) { + errno = ENOMEM; + return NULL; + } + return sodium_malloc(count * size); +} + +#ifndef HAVE_ALIGNED_MALLOC +void +sodium_free(void *ptr) +{ + free(ptr); +} +#else +void +sodium_free(void *ptr) +{ + unsigned char *base_ptr; + unsigned char *canary_ptr; + unsigned char *unprotected_ptr; + size_t total_size; + size_t unprotected_size; + + if (ptr == NULL) { + return; + } + canary_ptr = ((unsigned char *) ptr) - sizeof canary; + unprotected_ptr = _unprotected_ptr_from_user_ptr(ptr); + base_ptr = unprotected_ptr - page_size * 2U; + memcpy(&unprotected_size, base_ptr, sizeof unprotected_size); + total_size = page_size + page_size + unprotected_size + page_size; + _mprotect_readwrite(base_ptr, total_size); + if (sodium_memcmp(canary_ptr, canary, sizeof canary) != 0) { + _out_of_bounds(); + } +# ifndef HAVE_PAGE_PROTECTION + if (sodium_memcmp(unprotected_ptr + unprotected_size, canary, + sizeof canary) != 0) { + _out_of_bounds(); + } +# endif + sodium_munlock(unprotected_ptr, unprotected_size); + _free_aligned(base_ptr, total_size); +} +#endif /* HAVE_ALIGNED_MALLOC */ + +#ifndef HAVE_PAGE_PROTECTION +static int +_sodium_mprotect(void *ptr, int (*cb)(void *ptr, size_t size)) +{ + (void) ptr; + (void) cb; + errno = ENOSYS; + return -1; +} +#else +static int +_sodium_mprotect(void *ptr, int (*cb)(void *ptr, size_t size)) +{ + unsigned char *base_ptr; + unsigned char *unprotected_ptr; + size_t unprotected_size; + + unprotected_ptr = _unprotected_ptr_from_user_ptr(ptr); + base_ptr = unprotected_ptr - page_size * 2U; + memcpy(&unprotected_size, base_ptr, sizeof unprotected_size); + + return cb(unprotected_ptr, unprotected_size); +} +#endif + +int +sodium_mprotect_noaccess(void *ptr) +{ + return _sodium_mprotect(ptr, _mprotect_noaccess); +} + +int +sodium_mprotect_readonly(void *ptr) +{ + return _sodium_mprotect(ptr, _mprotect_readonly); +} + +int +sodium_mprotect_readwrite(void *ptr) +{ + return _sodium_mprotect(ptr, _mprotect_readwrite); +} + +int +sodium_pad(size_t *padded_buflen_p, unsigned char *buf, + size_t unpadded_buflen, size_t blocksize, size_t max_buflen) +{ + unsigned char *tail; + size_t i; + size_t xpadlen; + size_t xpadded_len; + volatile unsigned char mask; + unsigned char barrier_mask; + + if (blocksize <= 0U) { + return -1; + } + xpadlen = blocksize - 1U; + if ((blocksize & (blocksize - 1U)) == 0U) { + xpadlen -= unpadded_buflen & (blocksize - 1U); + } else { + xpadlen -= unpadded_buflen % blocksize; + } + if ((size_t) SIZE_MAX - unpadded_buflen <= xpadlen) { + sodium_misuse(); + } + xpadded_len = unpadded_buflen + xpadlen; + if (xpadded_len >= max_buflen) { + return -1; + } + tail = &buf[xpadded_len]; + if (padded_buflen_p != NULL) { + *padded_buflen_p = xpadded_len + 1U; + } + mask = 0U; + for (i = 0; i < blocksize; i++) { + barrier_mask = (unsigned char) (((i ^ xpadlen) - 1U) + >> ((sizeof(size_t) - 1) * CHAR_BIT)); + *(tail - i) = ((*(tail - i)) & mask) | (0x80 & barrier_mask); + mask |= barrier_mask; + } + return 0; +} + +int +sodium_unpad(size_t *unpadded_buflen_p, const unsigned char *buf, + size_t padded_buflen, size_t blocksize) +{ + const unsigned char *tail; + unsigned char acc = 0U; + unsigned char c; + unsigned char valid = 0U; + volatile size_t pad_len = 0U; + size_t i; + size_t is_barrier; + + if (padded_buflen < blocksize || blocksize <= 0U) { + return -1; + } + tail = &buf[padded_buflen - 1U]; + + for (i = 0U; i < blocksize; i++) { + c = *(tail - i); + is_barrier = + (( (acc - 1U) & (pad_len - 1U) & ((c ^ 0x80) - 1U) ) >> 8) & 1U; + acc |= c; + pad_len |= i & (1U + ~is_barrier); + valid |= (unsigned char) is_barrier; + } + *unpadded_buflen_p = padded_buflen - 1U - pad_len; + + return (int) (valid - 1U); +} diff --git a/external/src/libsodium/src/libsodium/sodium/version.c b/external/src/libsodium/src/libsodium/sodium/version.c new file mode 100644 index 0000000..4e584a6 --- /dev/null +++ b/external/src/libsodium/src/libsodium/sodium/version.c @@ -0,0 +1,30 @@ + +#include "version.h" + +const char * +sodium_version_string(void) +{ + return SODIUM_VERSION_STRING; +} + +int +sodium_library_version_major(void) +{ + return SODIUM_LIBRARY_VERSION_MAJOR; +} + +int +sodium_library_version_minor(void) +{ + return SODIUM_LIBRARY_VERSION_MINOR; +} + +int +sodium_library_minimal(void) +{ +#ifdef SODIUM_LIBRARY_MINIMAL + return 1; +#else + return 0; +#endif +} diff --git a/external/src/libsodium/test/Makefile.am b/external/src/libsodium/test/Makefile.am new file mode 100644 index 0000000..f9894bb --- /dev/null +++ b/external/src/libsodium/test/Makefile.am @@ -0,0 +1,5 @@ +SUBDIRS = \ + default + +EXTRA_DIST = \ + quirks/quirks.h diff --git a/external/src/libsodium/test/constcheck.sh b/external/src/libsodium/test/constcheck.sh new file mode 100644 index 0000000..994c164 --- /dev/null +++ b/external/src/libsodium/test/constcheck.sh @@ -0,0 +1,20 @@ +#! /bin/sh + +CT='ct.c' + +echo '#include ' > "$CT" +echo '#include ' >> "$CT" +echo 'int main(void) {' >> "$CT" +for macro in $(egrep -r '#define crypto_.*BYTES(_[A-Z]+)? ' src/libsodium/include | \ + cut -d: -f2- | cut -d' ' -f2 | \ + fgrep -v edwards25519sha512batch | sort -u); do + func=$(echo "$macro" | tr A-Z a-z) + echo " assert($func() == $macro);" >> "$CT" +done +echo "return 0; }" >> "$CT" + +CPPFLAGS="${CPPFLAGS} -Wno-deprecated-declarations" +${CC:-cc} "$CT" $CPPFLAGS $CFLAGS $LDFLAGS -lsodium || exit 1 +./a.out || exit 1 +rm -f a.out "$CT" + diff --git a/external/src/libsodium/test/default/Makefile.am b/external/src/libsodium/test/default/Makefile.am new file mode 100644 index 0000000..12aa7eb --- /dev/null +++ b/external/src/libsodium/test/default/Makefile.am @@ -0,0 +1,506 @@ + +EXTRA_DIST = \ + cmptest.h \ + wasi-test-wrapper.sh \ + wintest.bat \ + pre.js.inc \ + aead_aes256gcm.exp \ + aead_aes256gcm2.exp \ + aead_chacha20poly1305.exp \ + aead_chacha20poly13052.exp \ + aead_xchacha20poly1305.exp \ + auth.exp \ + auth2.exp \ + auth3.exp \ + auth5.exp \ + auth6.exp \ + auth7.exp \ + box.exp \ + box2.exp \ + box7.exp \ + box8.exp \ + box_easy.exp \ + box_easy2.exp \ + box_seal.exp \ + box_seed.exp \ + chacha20.exp \ + codecs.exp \ + core_ed25519.exp \ + core_ristretto255.exp \ + core1.exp \ + core2.exp \ + core3.exp \ + core4.exp \ + core5.exp \ + core6.exp \ + ed25519_convert.exp \ + generichash.exp \ + generichash2.exp \ + generichash3.exp \ + hash.exp \ + hash3.exp \ + kdf.exp \ + keygen.exp \ + kx.exp \ + metamorphic.exp \ + misuse.exp \ + onetimeauth.exp \ + onetimeauth2.exp \ + onetimeauth7.exp \ + pwhash_argon2i.exp \ + pwhash_argon2id.exp \ + pwhash_scrypt.exp \ + pwhash_scrypt_ll.exp \ + randombytes.exp \ + scalarmult.exp \ + scalarmult_ed25519.exp \ + scalarmult_ristretto255.exp \ + scalarmult2.exp \ + scalarmult5.exp \ + scalarmult6.exp \ + scalarmult7.exp \ + scalarmult8.exp \ + secretbox.exp \ + secretbox2.exp \ + secretbox7.exp \ + secretbox8.exp \ + secretbox_easy.exp \ + secretbox_easy2.exp \ + secretstream.exp \ + shorthash.exp \ + sign.exp \ + siphashx24.exp \ + sodium_core.exp \ + sodium_utils.exp \ + sodium_utils2.exp \ + sodium_utils3.exp \ + sodium_version.exp \ + stream.exp \ + stream2.exp \ + stream3.exp \ + stream4.exp \ + verify1.exp \ + xchacha20.exp + +DISTCLEANFILES = \ + aead_aes256gcm.res \ + aead_aes256gcm2.res \ + aead_chacha20poly1305.res \ + aead_chacha20poly13052.res \ + aead_xchacha20poly1305.res \ + auth.res \ + auth2.res \ + auth3.res \ + auth5.res \ + auth6.res \ + auth7.res \ + box.res \ + box2.res \ + box7.res \ + box8.res \ + box_easy.res \ + box_easy2.res \ + box_seal.res \ + box_seed.res \ + chacha20.res \ + codecs.res \ + core_ed25519.res \ + core_ristretto255.res \ + core1.res \ + core2.res \ + core3.res \ + core4.res \ + core5.res \ + core6.res \ + ed25519_convert.res \ + generichash.res \ + generichash2.res \ + generichash3.res \ + hash.res \ + hash2.res \ + hash3.res \ + kdf.res \ + keygen.res \ + kx.res \ + metamorphic.res \ + misuse.res \ + onetimeauth.res \ + onetimeauth2.res \ + onetimeauth7.res \ + pwhash_argon2i.res \ + pwhash_argon2id.res \ + pwhash_scrypt.res \ + pwhash_scrypt_ll.res \ + randombytes.res \ + scalarmult.res \ + scalarmult_ed25519.res \ + scalarmult_ristretto255.res \ + scalarmult2.res \ + scalarmult5.res \ + scalarmult6.res \ + scalarmult7.res \ + scalarmult8.res \ + secretbox.res \ + secretbox2.res \ + secretbox7.res \ + secretbox8.res \ + secretbox_easy.res \ + secretbox_easy2.res \ + secretstream.res \ + shorthash.res \ + sign.res \ + siphashx24.res \ + sodium_core.res \ + sodium_utils.res \ + sodium_utils2.res \ + sodium_utils3.res \ + sodium_version.res \ + stream.res \ + stream2.res \ + stream3.res \ + stream4.res \ + verify1.res \ + xchacha20.res + +AM_CPPFLAGS = \ + -DTEST_SRCDIR=\"@srcdir@\" \ + -I$(top_srcdir)/src/libsodium/include \ + -I$(top_srcdir)/src/libsodium/include/sodium \ + -I$(top_builddir)/src/libsodium/include \ + -I$(top_builddir)/src/libsodium/include/sodium \ + -I$(top_srcdir)/test/quirks + +AM_LDFLAGS = @TEST_LDFLAGS@ + +TESTS_TARGETS = \ + aead_aes256gcm \ + aead_aes256gcm2 \ + aead_chacha20poly1305 \ + aead_chacha20poly13052 \ + aead_xchacha20poly1305 \ + auth \ + auth2 \ + auth3 \ + auth5 \ + auth6 \ + auth7 \ + box \ + box2 \ + box7 \ + box8 \ + box_easy \ + box_easy2 \ + box_seal \ + box_seed \ + chacha20 \ + codecs \ + core1 \ + core2 \ + core3 \ + core4 \ + core5 \ + core6 \ + ed25519_convert \ + generichash \ + generichash2 \ + generichash3 \ + hash \ + hash3 \ + kdf \ + keygen \ + kx \ + metamorphic \ + misuse \ + onetimeauth \ + onetimeauth2 \ + onetimeauth7 \ + pwhash_argon2i \ + pwhash_argon2id \ + randombytes \ + scalarmult \ + scalarmult2 \ + scalarmult5 \ + scalarmult6 \ + scalarmult7 \ + scalarmult8 \ + secretbox \ + secretbox2 \ + secretbox7 \ + secretbox8 \ + secretbox_easy \ + secretbox_easy2 \ + secretstream \ + shorthash \ + sign \ + sodium_core \ + sodium_utils \ + sodium_version \ + stream \ + stream2 \ + stream3 \ + stream4 \ + verify1 + +if !EMSCRIPTEN +TESTS_TARGETS += \ + sodium_utils2 \ + sodium_utils3 +endif + +check_PROGRAMS = $(TESTS_TARGETS) + +TESTS = $(TESTS_TARGETS) + +TESTS_LDADD = \ + ${top_builddir}/src/libsodium/libsodium.la + +aead_aes256gcm_SOURCE = cmptest.h aead_aes256gcm.c +aead_aes256gcm_LDADD = $(TESTS_LDADD) + +aead_aes256gcm2_SOURCE = cmptest.h aead_aes256gcm2.c +aead_aes256gcm2_LDADD = $(TESTS_LDADD) + +aead_chacha20poly1305_SOURCE = cmptest.h aead_chacha20poly1305.c +aead_chacha20poly1305_LDADD = $(TESTS_LDADD) + +aead_chacha20poly13052_SOURCE = cmptest.h aead_chacha20poly13052.c +aead_chacha20poly13052_LDADD = $(TESTS_LDADD) + +aead_xchacha20poly1305_SOURCE = cmptest.h aead_xchacha20poly1305.c +aead_xchacha20poly1305_LDADD = $(TESTS_LDADD) + +auth_SOURCE = cmptest.h auth.c +auth_LDADD = $(TESTS_LDADD) + +auth2_SOURCE = cmptest.h auth2.c +auth2_LDADD = $(TESTS_LDADD) + +auth3_SOURCE = cmptest.h auth3.c +auth3_LDADD = $(TESTS_LDADD) + +auth5_SOURCE = cmptest.h auth5.c quirks.h +auth5_LDADD = $(TESTS_LDADD) + +auth6_SOURCE = cmptest.h auth6.c quirks.h +auth6_LDADD = $(TESTS_LDADD) + +auth7_SOURCE = cmptest.h auth7.c quirks.h +auth7_LDADD = $(TESTS_LDADD) + +box_SOURCE = cmptest.h box.c +box_LDADD = $(TESTS_LDADD) + +box2_SOURCE = cmptest.h box2.c +box2_LDADD = $(TESTS_LDADD) + +box7_SOURCE = cmptest.h box7.c +box7_LDADD = $(TESTS_LDADD) + +box8_SOURCE = cmptest.h box8.c +box8_LDADD = $(TESTS_LDADD) + +box_easy_SOURCE = cmptest.h box_easy.c +box_easy_LDADD = $(TESTS_LDADD) + +box_easy2_SOURCE = cmptest.h box_easy2.c +box_easy2_LDADD = $(TESTS_LDADD) + +box_seal_SOURCE = cmptest.h box_seal.c +box_seal_LDADD = $(TESTS_LDADD) + +box_seed_SOURCE = cmptest.h box_seed.c +box_seed_LDADD = $(TESTS_LDADD) + +chacha20_SOURCE = cmptest.h chacha20.c +chacha20_LDADD = $(TESTS_LDADD) + +codecs_SOURCE = cmptest.h codecs.c +codecs_LDADD = $(TESTS_LDADD) + +core_ed25519_SOURCE = cmptest.h core_ed25519.c +core_ed25519_LDADD = $(TESTS_LDADD) + +core_ristretto255_SOURCE = cmptest.h core_ristretto255.c +core_ristretto255_LDADD = $(TESTS_LDADD) + +core1_SOURCE = cmptest.h core1.c +core1_LDADD = $(TESTS_LDADD) + +core2_SOURCE = cmptest.h core2.c +core2_LDADD = $(TESTS_LDADD) + +core3_SOURCE = cmptest.h core3.c +core3_LDADD = $(TESTS_LDADD) + +core4_SOURCE = cmptest.h core4.c +core4_LDADD = $(TESTS_LDADD) + +core5_SOURCE = cmptest.h core5.c +core5_LDADD = $(TESTS_LDADD) + +core6_SOURCE = cmptest.h core6.c +core6_LDADD = $(TESTS_LDADD) + +ed25519_convert_SOURCE = cmptest.h ed25519_convert.c +ed25519_convert_LDADD = $(TESTS_LDADD) + +generichash_SOURCE = cmptest.h generichash.c +generichash_LDADD = $(TESTS_LDADD) + +generichash2_SOURCE = cmptest.h generichash2.c +generichash2_LDADD = $(TESTS_LDADD) + +generichash3_SOURCE = cmptest.h generichash3.c +generichash3_LDADD = $(TESTS_LDADD) + +hash_SOURCE = cmptest.h hash.c +hash_LDADD = $(TESTS_LDADD) + +hash3_SOURCE = cmptest.h hash3.c +hash3_LDADD = $(TESTS_LDADD) + +kdf_SOURCE = cmptest.h kdf.c +kdf_LDADD = $(TESTS_LDADD) + +keygen_SOURCE = cmptest.h keygen.c +keygen_LDADD = $(TESTS_LDADD) + +kx_SOURCE = cmptest.h kx.c +kx_LDADD = $(TESTS_LDADD) + +metamorphic_SOURCE = cmptest.h metamorphic.c +metamorphic_LDADD = $(TESTS_LDADD) + +misuse_SOURCE = cmptest.h misuse.c +misuse_LDADD = $(TESTS_LDADD) + +onetimeauth_SOURCE = cmptest.h onetimeauth.c +onetimeauth_LDADD = $(TESTS_LDADD) + +onetimeauth2_SOURCE = cmptest.h onetimeauth2.c +onetimeauth2_LDADD = $(TESTS_LDADD) + +onetimeauth7_SOURCE = cmptest.h onetimeauth7.c +onetimeauth7_LDADD = $(TESTS_LDADD) + +pwhash_argon2i_SOURCE = cmptest.h pwhash_argon2i.c +pwhash_argon2i_LDADD = $(TESTS_LDADD) + +pwhash_argon2id_SOURCE = cmptest.h pwhash_argon2id.c +pwhash_argon2id_LDADD = $(TESTS_LDADD) + +pwhash_scrypt_SOURCE = cmptest.h pwhash_scrypt.c +pwhash_scrypt_LDADD = $(TESTS_LDADD) + +pwhash_scrypt_ll_SOURCE = cmptest.h pwhash_scrypt_ll.c +pwhash_scrypt_ll_LDADD = $(TESTS_LDADD) + +randombytes_SOURCE = cmptest.h randombytes.c +randombytes_LDADD = $(TESTS_LDADD) + +scalarmult_SOURCE = cmptest.h scalarmult.c +scalarmult_LDADD = $(TESTS_LDADD) + +scalarmult_ed25519_SOURCE = cmptest.h scalarmult_ed25519.c +scalarmult_ed25519_LDADD = $(TESTS_LDADD) + +scalarmult_ristretto255_SOURCE = cmptest.h scalarmult_ristretto255.c +scalarmult_ristretto255_LDADD = $(TESTS_LDADD) + +scalarmult2_SOURCE = cmptest.h scalarmult2.c +scalarmult2_LDADD = $(TESTS_LDADD) + +scalarmult5_SOURCE = cmptest.h scalarmult5.c +scalarmult5_LDADD = $(TESTS_LDADD) + +scalarmult6_SOURCE = cmptest.h scalarmult6.c +scalarmult6_LDADD = $(TESTS_LDADD) + +scalarmult7_SOURCE = cmptest.h scalarmult7.c +scalarmult7_LDADD = $(TESTS_LDADD) + +scalarmult8_SOURCE = cmptest.h scalarmult8.c +scalarmult8_LDADD = $(TESTS_LDADD) + +secretbox_SOURCE = cmptest.h secretbox.c +secretbox_LDADD = $(TESTS_LDADD) + +secretbox2_SOURCE = cmptest.h secretbox2.c +secretbox2_LDADD = $(TESTS_LDADD) + +secretbox7_SOURCE = cmptest.h secretbox7.c +secretbox7_LDADD = $(TESTS_LDADD) + +secretbox8_SOURCE = cmptest.h secretbox8.c +secretbox8_LDADD = $(TESTS_LDADD) + +secretbox_easy_SOURCE = cmptest.h secretbox_easy.c +secretbox_easy_LDADD = $(TESTS_LDADD) + +secretbox_easy2_SOURCE = cmptest.h secretbox_easy2.c +secretbox_easy2_LDADD = $(TESTS_LDADD) + +secretstream_SOURCE = cmptest.h secretstream.c +secretstream_LDADD = $(TESTS_LDADD) + +shorthash_SOURCE = cmptest.h shorthash.c +shorthash_LDADD = $(TESTS_LDADD) + +sign_SOURCE = cmptest.h sign.c +sign_LDADD = $(TESTS_LDADD) + +siphashx24_SOURCE = cmptest.h siphashx24.c +siphashx24_LDADD = $(TESTS_LDADD) + +sodium_core_SOURCE = cmptest.h sodium_core.c +sodium_core_LDADD = $(TESTS_LDADD) + +sodium_utils_SOURCE = cmptest.h sodium_utils.c +sodium_utils_LDADD = $(TESTS_LDADD) + +sodium_utils2_SOURCE = cmptest.h sodium_utils2.c +sodium_utils2_LDADD = $(TESTS_LDADD) + +sodium_utils3_SOURCE = cmptest.h sodium_utils3.c +sodium_utils3_LDADD = $(TESTS_LDADD) + +sodium_version_SOURCE = cmptest.h sodium_version.c +sodium_version_LDADD = $(TESTS_LDADD) + +stream_SOURCE = cmptest.h stream.c +stream_LDADD = $(TESTS_LDADD) + +stream2_SOURCE = cmptest.h stream2.c +stream2_LDADD = $(TESTS_LDADD) + +stream3_SOURCE = cmptest.h stream3.c +stream3_LDADD = $(TESTS_LDADD) + +stream4_SOURCE = cmptest.h stream4.c +stream4_LDADD = $(TESTS_LDADD) + +verify1_SOURCE = cmptest.h verify1.c +verify1_LDADD = $(TESTS_LDADD) + +xchacha20_SOURCE = cmptest.h xchacha20.c +xchacha20_LDADD = $(TESTS_LDADD) + +if !MINIMAL +TESTS_TARGETS += \ + core_ed25519 \ + core_ristretto255 \ + pwhash_scrypt \ + pwhash_scrypt_ll \ + scalarmult_ed25519 \ + scalarmult_ristretto255 \ + siphashx24 \ + xchacha20 +endif + +if WASI +LOG_COMPILER = ./wasi-test-wrapper.sh +endif + +verify: check + +@VALGRIND_CHECK_RULES@ diff --git a/external/src/libsodium/test/default/aead_aes256gcm.c b/external/src/libsodium/test/default/aead_aes256gcm.c new file mode 100644 index 0000000..1f83fdc --- /dev/null +++ b/external/src/libsodium/test/default/aead_aes256gcm.c @@ -0,0 +1,3243 @@ + +#define TEST_NAME "aead_aes256gcm" +#include "cmptest.h" + +static struct { + const char *key_hex; + const char *nonce_hex; + const char *message_hex; + const char *ad_hex; + const char *ciphertext_hex; + const char *mac_hex; +} tests[] = { + { + "b52c505a37d78eda5dd34f20c22540ea1b58963cf8e5bf8ffa85f9f2492505b4", + "516c33929df5a3284ff463d7", + "", + "", + "", + "bdc1ac884d332457a1d2664f168c76f0", + }, + { + "5fe0861cdc2690ce69b3658c7f26f8458eec1c9243c5ba0845305d897e96ca0f", + "770ac1a5a3d476d5d96944a1", + "", + "", + "", + "196d691e1047093ca4b3d2ef4baba216", + }, + { + "7620b79b17b21b06d97019aa70e1ca105e1c03d2a0cf8b20b5a0ce5c3903e548", + "60f56eb7a4b38d4f03395511", + "", + "", + "", + "f570c38202d94564bab39f75617bc87a", + }, + { + "7e2db00321189476d144c5f27e787087302a48b5f7786cd91e93641628c2328b", + "ea9d525bf01de7b2234b606a", + "", + "", + "", + "db9df5f14f6c9f2ae81fd421412ddbbb", + }, + { + "a23dfb84b5976b46b1830d93bcf61941cae5e409e4f5551dc684bdcef9876480", + "5aa345908048de10a2bd3d32", + "", + "", + "", + "f28217649230bd7a40a9a4ddabc67c43", + }, + { + "dfe928f86430b78add7bb7696023e6153d76977e56103b180253490affb9431c", + "1dd0785af9f58979a10bd62d", + "", + "", + "", + "a55eb09e9edef58d9f671d72207f8b3c", + }, + { + "34048db81591ee68224956bd6989e1630fcf068d7ff726ae81e5b29f548cfcfb", + "1621d34cff2a5b250c7b76fc", + "", + "", + "", + "4992ec3d57cccfa58fd8916c59b70b11", + }, + { + "a1114f8749c72b8cef62e7503f1ad921d33eeede32b0b5b8e0d6807aa233d0ad", + "a190ed3ff2e238be56f90bd6", + "", + "", + "", + "c8464d95d540fb191156fbbc1608842a", + }, + { + "ddbb99dc3102d31102c0e14b238518605766c5b23d9bea52c7c5a771042c85a0", + "95d15ed75c6a109aac1b1d86", + "", + "", + "", + "813d1da3775cacd78e96d86f036cff96", + }, + { + "1faa506b8f13a2e6660af78d92915adf333658f748f4e48fa20135a29e9abe5f", + "e50f278d3662c99d750f60d3", + "", + "", + "", + "aec7ece66b7344afd6f6cc7419cf6027", + }, + { + "f30b5942faf57d4c13e7a82495aedf1b4e603539b2e1599317cc6e53225a2493", + "336c388e18e6abf92bb739a9", + "", + "", + "", + "ddaf8ef4cb2f8a6d401f3be5ff0baf6a", + }, + { + "daf4d9c12c5d29fc3fa936532c96196e56ae842e47063a4b29bfff2a35ed9280", + "5381f21197e093b96cdac4fa", + "", + "", + "", + "7f1832c7f7cd7812a004b79c3d399473", + }, + { + "6b524754149c81401d29a4b8a6f4a47833372806b2d4083ff17f2db3bfc17bca", + "ac7d3d618ab690555ec24408", + "", + "", + "", + "db07a885e2bd39da74116d06c316a5c9", + }, + { + "cff083303ff40a1f66c4aed1ac7f50628fe7e9311f5d037ebf49f4a4b9f0223f", + "45d46e1baadcfbc8f0e922ff", + "", + "", + "", + "1687c6d459ea481bf88e4b2263227906", + }, + { + "3954f60cddbb39d2d8b058adf545d5b82490c8ae9283afa5278689041d415a3a", + "8fb3d98ef24fba03746ac84f", + "", + "", + "", + "7fb130855dfe7a373313361f33f55237", + }, + { + "78dc4e0aaf52d935c3c01eea57428f00ca1fd475f5da86a49c8dd73d68c8e223", + "d79cf22d504cc793c3fb6c8a", + "", + "b96baa8c1c75a671bfb2d08d06be5f36", + "", + "3e5d486aa2e30b22e040b85723a06e76", + }, + { + "4457ff33683cca6ca493878bdc00373893a9763412eef8cddb54f91318e0da88", + "699d1f29d7b8c55300bb1fd2", + "", + "6749daeea367d0e9809e2dc2f309e6e3", + "", + "d60c74d2517fde4a74e0cd4709ed43a9", + }, + { + "4d01c96ef9d98d4fb4e9b61be5efa772c9788545b3eac39eb1cacb997a5f0792", + "32124a4d9e576aea2589f238", + "", + "d72bad0c38495eda50d55811945ee205", + "", + "6d6397c9e2030f5b8053bfe510f3f2cf", + }, + { + "8378193a4ce64180814bd60591d1054a04dbc4da02afde453799cd6888ee0c6c", + "bd8b4e352c7f69878a475435", + "", + "1c6b343c4d045cbba562bae3e5ff1b18", + "", + "0833967a6a53ba24e75c0372a6a17bda", + }, + { + "22fc82db5b606998ad45099b7978b5b4f9dd4ea6017e57370ac56141caaabd12", + "880d05c5ee599e5f151e302f", + "", + "3e3eb5747e390f7bc80e748233484ffc", + "", + "2e122a478e64463286f8b489dcdd09c8", + }, + { + "fc00960ddd698d35728c5ac607596b51b3f89741d14c25b8badac91976120d99", + "a424a32a237f0df530f05e30", + "", + "cfb7e05e3157f0c90549d5c786506311", + "", + "dcdcb9e4004b852a0da12bdf255b4ddd", + }, + { + "69749943092f5605bf971e185c191c618261b2c7cc1693cda1080ca2fd8d5111", + "bd0d62c02ee682069bd1e128", + "", + "6967dce878f03b643bf5cdba596a7af3", + "", + "378f796ae543e1b29115cc18acd193f4", + }, + { + "fc4875db84819834b1cb43828d2f0ae3473aa380111c2737e82a9ab11fea1f19", + "da6a684d3ff63a2d109decd6", + "", + "91b6fa2ab4de44282ffc86c8cde6e7f5", + "", + "504e81d2e7877e4dad6f31cdeb07bdbd", + }, + { + "9f9fe7d2a26dcf59d684f1c0945b5ffafe0a4746845ed317d35f3ed76c93044d", + "13b59971cd4dd36b19ac7104", + "", + "190a6934f45f89c90067c2f62e04c53b", + "", + "4f636a294bfbf51fc0e131d694d5c222", + }, + { + "ab9155d7d81ba6f33193695cf4566a9b6e97a3e409f57159ae6ca49655cca071", + "26a9f8d665d163ddb92d035d", + "", + "4a203ac26b951a1f673c6605653ec02d", + "", + "437ea77a3879f010691e288d6269a996", + }, + { + "0f1c62dd80b4a6d09ee9d787b1b04327aa361529ffa3407560414ac47b7ef7bc", + "c87613a3b70d2a048f32cb9a", + "", + "8f23d404be2d9e888d219f1b40aa29e8", + "", + "36d8a309acbb8716c9c08c7f5de4911e", + }, + { + "f3e954a38956df890255f01709e457b33f4bfe7ecb36d0ee50f2500471eebcde", + "9799abd3c52110c704b0f36a", + "", + "ddb70173f44157755b6c9b7058f40cb7", + "", + "b323ae3abcb415c7f420876c980f4858", + }, + { + "0625316534fbd82fe8fdea50fa573c462022c42f79e8b21360e5a6dce66dde28", + "da64a674907cd6cf248f5fbb", + "", + "f24d48e04f5a0d987ba7c745b73b0364", + "", + "df360b810f27e794673a8bb2dc0d68b0", + }, + { + "28f045ac7c4fe5d4b01a9dcd5f1ad3efff1c4f170fc8ab8758d97292868d5828", + "5d85de95b0bdc44514143919", + "", + "601d2158f17ab3c7b4dcb6950fbdcdde", + "", + "42c3f527418cf2c3f5d5010ccba8f271", + }, + { + "19310eed5f5f44eb47075c105eb31e36bbfd1310f741b9baa66a81138d357242", + "a1247120138fa4f0e96c992c", + "", + "29d746414333e0f72b4c3f44ec6bfe42", + "", + "d5997e2f956df3fa2c2388e20f30c480", + }, + { + "886cff5f3e6b8d0e1ad0a38fcdb26de97e8acbe79f6bed66959a598fa5047d65", + "3a8efa1cd74bbab5448f9945", + "", + "519fee519d25c7a304d6c6aa1897ee1eb8c59655", + "", + "f6d47505ec96c98a42dc3ae719877b87", + }, + { + "6937a57d35fe6dc3fc420b123bccdce874bd4c18f2e7c01ce2faf33d3944fd9d", + "a87247797b758467b96310f3", + "", + "ead961939a33dd578f8e93db8b28a1c85362905f", + "", + "599de3ecf22cb867f03f7f6d9fd7428a", + }, + { + "e65a331776c9dcdf5eba6c59e05ec079d97473bcdce84daf836be323456263a0", + "ca731f768da01d02eb8e727e", + "", + "d7274586517bf1d8da866f4a47ad0bcf2948a862", + "", + "a8abe7a8085f25130a7206d37a8aaf6d", + }, + { + "77bb1b6ef898683c981b2fc899319ffbb6000edca22566b634db3a3c804059e5", + "354a19283769b3b991b05a4c", + "", + "b5566251a8a8bec212dc08113229ff8590168800", + "", + "e5c2dccf8fc7f296cac95d7071cb8d7d", + }, + { + "2a43308d520a59ed51e47a3a915e1dbf20a91f0886506e481ad3de65d50975b4", + "bcbf99733d8ec90cb23e6ce6", + "", + "eb88288729289d26fe0e757a99ad8eec96106053", + "", + "01b0196933aa49123eab4e1571250383", + }, + { + "2379b35f85102db4e7aecc52b705bc695d4768d412e2d7bebe999236783972ff", + "918998c4801037b1cd102faa", + "", + "b3722309e0f066225e8d1659084ebb07a93b435d", + "", + "dfb18aee99d1f67f5748d4b4843cb649", + }, + { + "98b3cb7537167e6d14a2a8b2310fe94b715c729fdf85216568150b556d0797ba", + "bca5e2e5a6b30f18d263c6b2", + "", + "260d3d72db70d677a4e3e1f3e11431217a2e4713", + "", + "d6b7560f8ac2f0a90bad42a6a07204bc", + }, + { + "30341ae0f199b10a15175d00913d5029526ab7f761c0b936a7dd5f1b1583429d", + "dbe109a8ce5f7b241e99f7af", + "", + "fe4bdee5ca9c4806fa024715fbf66ab845285fa7", + "", + "ae91daed658e26c0d126575147af9899", + }, + { + "8232b6a1d2e367e9ce1ea8d42fcfc83a4bc8bdec465c6ba326e353ad9255f207", + "cd2fb5ff9cf0f39868ad8685", + "", + "02418b3dde54924a9628de06004c0882ae4ec3bb", + "", + "d5308f63708675ced19b2710afd2db49", + }, + { + "f9a132a50a508145ffd8294e68944ea436ce0f9a97e181f5e0d6c5d272311fc1", + "892991b54e94b9d57442ccaf", + "", + "4e0fbd3799da250fa27911b7e68d7623bfe60a53", + "", + "89881d5f786e6d53e0d19c3b4e6887d8", + }, + { + "0e3746e5064633ea9311b2b8427c536af92717de20eeb6260db1333c3d8a8114", + "f84c3a1c94533f7f25cec0ac", + "", + "8c0d41e6135338c8d3e63e2a5fa0a9667ec9a580", + "", + "479ccfe9241de2c474f2edebbb385c09", + }, + { + "b997e9b0746abaaed6e64b63bdf64882526ad92e24a2f5649df055c9ec0f1daa", + "f141d8d71b033755022f0a7d", + "", + "681d6583f527b1a92f66caae9b1d4d028e2e631e", + "", + "b30442a6395ec13246c48b21ffc65509", + }, + { + "87660ec1700d4e9f88a323a49f0b871e6aaf434a2d8448d04d4a22f6561028e0", + "2a07b42593cd24f0a6fe406c", + "", + "1dd239b57185b7e457ced73ebba043057f049edd", + "", + "df7a501049b37a534098cb45cb9c21b7", + }, + { + "ea4792e1f1717b77a00de4d109e627549b165c82af35f33ca7e1a6b8ed62f14f", + "7453cc8b46fe4b93bcc48381", + "", + "46d98970a636e7cd7b76fc362ae88298436f834f", + "", + "518dbacd36be6fba5c12871678a55516", + }, + { + "34892cdd1d48ca166f7ba73182cb97336c2c754ac160a3e37183d6fb5078cec3", + "ed3198c5861b78c71a6a4eec", + "", + "a6fa6d0dd1e0b95b4609951bbbe714de0ae0ccfa", + "", + "c6387795096b348ecf1d1f6caaa3c813", + }, + { + "f4069bb739d07d0cafdcbc609ca01597f985c43db63bbaaa0debbb04d384e49c", + "d25ff30fdc3d464fe173e805", + "", + "3e1449c4837f0892f9d55127c75c4b25d69be334baf5f19394d2d8bb460cbf2120e14736d0f634aa792feca20e455f11", + "", + "805ec2931c2181e5bfb74fa0a975f0cf", + }, + { + "62189dcc4beb97462d6c0927d8a270d39a1b07d72d0ad28840badd4f68cf9c8b", + "859fda5247c888823a4b8032", + "", + "b28d1621ee110f4c9d709fad764bba2dd6d291bc003748faac6d901937120d41c1b7ce67633763e99e05c71363fceca8", + "", + "27330907d0002880bbb4c1a1d23c0be2", + }, + { + "59012d85a1b90aeb0359e6384c9991e7be219319f5b891c92c384ade2f371816", + "3c9cde00c23912cff9689c7c", + "", + "e5daf473a470860b55210a483c0d1a978d8add843c2c097f73a3cda49ac4a614c8e887d94e6692309d2ed97ebe1eaf5d", + "", + "048239e4e5c2c8b33890a7c950cda852", + }, + { + "4be09b408ad68b890f94be5efa7fe9c917362712a3480c57cd3844935f35acb7", + "8f350bd3b8eea173fc7370bc", + "", + "2819d65aec942198ca97d4435efd9dd4d4393b96cf5ba44f09bce4ba135fc8636e8275dcb515414b8befd32f91fc4822", + "", + "a133cb7a7d0471dbac61fb41589a2efe", + }, + { + "13cb965a4d9d1a36efad9f6ca1ba76386a5bb160d80b0917277102357ac7afc8", + "f313adec42a66d13c3958180", + "", + "717b48358898e5ccfea4289049adcc1bb0db3b3ebd1767ac24fb2b7d37dc80ea2316c17f14fb51b5e18cd5bb09afe414", + "", + "81b4ef7a84dc4a0b1fddbefe37f53852", + }, + { + "d27f1bebbbdef0edca393a6261b0338abbc491262eab0737f55246458f6668cc", + "fc062f857886e278f3a567d2", + "", + "2bae92dea64aa99189de8ea4c046745306002e02cfb46a41444ce8bfcc329bd4205963d9ab5357b026a4a34b1a861771", + "", + "5c5a6c4613f1e522596330d45f243fdd", + }, + { + "7b4d19cd3569f74c7b5df61ab78379ee6bfa15105d21b10bf6096699539006d0", + "fbed5695c4a739eded97b1e3", + "", + "c6f2e5d663bfaf668d014550ef2e66bf89978799a785f1f2c79a2cb3eb3f2fd4076207d5f7e1c284b4af5cffc4e46198", + "", + "7101b434fb90c7f95b9b7a0deeeb5c81", + }, + { + "d3431488d8f048590bd76ec66e71421ef09f655d7cf8043bf32f75b4b2e7efcc", + "cc766e98b40a81519fa46392", + "", + "93320179fdb40cbc1ccf00b872a3b4a5f6c70b56e43a84fcac5eb454a0a19a747d452042611bf3bbaafd925e806ffe8e", + "", + "3afcc336ce8b7191eab04ad679163c2a", + }, + { + "a440948c0378561c3956813c031f81573208c7ffa815114ef2eee1eb642e74c6", + "c1f4ffe54b8680832eed8819", + "", + "253438f132b18e8483074561898c5652b43a82cc941e8b4ae37e792a8ed6ec5ce2bcec9f1ffcf4216e46696307bb774a", + "", + "129445f0a3c979a112a3afb10a24e245", + }, + { + "798706b651033d9e9bf2ce064fb12be7df7308cf45df44776588cd391c49ff85", + "5a43368a39e7ffb775edfaf4", + "", + "926b74fe6381ebd35757e42e8e557601f2287bfc133a13fd86d61c01aa84f39713bf99a8dc07b812f0274c9d3280a138", + "", + "89fe481a3d95c03a0a9d4ee3e3f0ed4a", + }, + { + "c3aa2a39a9fef4a466618d1288bb62f8da7b1cb760ccc8f1be3e99e076f08eff", + "9965ba5e23d9453d7267ca5b", + "", + "93efb6a2affc304cb25dfd49aa3e3ccdb25ceac3d3cea90dd99e38976978217ad5f2b990d10b91725c7fd2035ecc6a30", + "", + "00a94c18a4572dcf4f9e2226a03d4c07", + }, + { + "14e06858008f7e77186a2b3a7928a0c7fcee22136bc36f53553f20fa5c37edcd", + "32ebe0dc9ada849b5eda7b48", + "", + "6c0152abfa485b8cd67c154a5f0411f22121379774d745f40ee577b028fd0e188297581561ae972223d75a24b488aed7", + "", + "2625b0ba6ee02b58bc529e43e2eb471b", + }, + { + "fbb56b11c51a093ce169a6990399c4d741f62b3cc61f9e8a609a1b6ae8e7e965", + "9c5a953247e91aceceb9defb", + "", + "46cb5c4f617916a9b1b2e03272cb0590ce716498533047d73c81e4cbe9278a3686116f5632753ea2df52efb3551aea2d", + "", + "4f3b82e6be4f08756071f2c46c31fedf", + }, + { + "b303bf02f6a8dbb5bc4baccab0800db5ee06de648e2fae299b95f135c9b107cc", + "906495b67ef4ce00b44422fa", + "", + "872c6c370926535c3fa1baec031e31e7c6c82808c8a060742dbef114961c314f1986b2131a9d91f30f53067ec012c6b7", + "", + "64dde37169082d181a69107f60c5c6bb", + }, + { + "29f5f8075903063cb6d7050669b1f74e08a3f79ef566292dfdef1c06a408e1ab", + "35f25c48b4b5355e78b9fb3a", + "", + "107e2e23159fc5c0748ca7a077e5cc053fa5c682ff5269d350ee817f8b5de4d3972041d107b1e2f2e54ca93b72cd0408", + "", + "fee5a9baebb5be0165deaa867e967a9e", + }, + { + "03ccb7dbc7b8425465c2c3fc39ed0593929ffd02a45ff583bd89b79c6f646fe9", + "fd119985533bd5520b301d12", + "", + "98e68c10bf4b5ae62d434928fc6405147c6301417303ef3a703dcfd2c0c339a4d0a89bd29fe61fecf1066ab06d7a5c31a48ffbfed22f749b17e9bd0dc1c6f8fbd6fd4587184db964d5456132106d782338c3f117ec05229b0899", + "", + "cf54e7141349b66f248154427810c87a", + }, + { + "57e112cd45f2c57ddb819ea651c206763163ef016ceead5c4eae40f2bbe0e4b4", + "188022c2125d2b1fcf9e4769", + "", + "09c8f445ce5b71465695f838c4bb2b00624a1c9185a3d552546d9d2ee4870007aaf3007008f8ae9affb7588b88d09a90e58b457f88f1e3752e3fb949ce378670b67a95f8cf7f5c7ceb650efd735dbc652cae06e546a5dbd861bd", + "", + "9efcddfa0be21582a05749f4050d29fe", + }, + { + "a4ddf3cab7453aaefad616fd65d63d13005e9459c17d3173cd6ed7f2a86c921f", + "06177b24c58f3be4f3dd4920", + "", + "f95b046d80485e411c56b834209d3abd5a8a9ddf72b1b916679adfdde893044315a5f4967fd0405ec297aa332f676ff0fa5bd795eb609b2e4f088db1cdf37ccff0735a5e53c4c12173a0026aea42388a7d7153a8830b8a901cf9", + "", + "9d1bd8ecb3276906138d0b03fcb8c1bb", + }, + { + "24a92b24e85903cd4aaabfe07c310df5a4f8f459e03a63cbd1b47855b09c0be8", + "22e756dc898d4cf122080612", + "", + "2e01b2536dbe376be144296f5c38fb099e008f962b9f0e896334b6408393bff1020a0e442477abfdb1727213b6ccc577f5e16cb057c8945a07e307264b65979aed96b5995f40250ffbaaa1a1f0eccf394015f6290f5e64dfe5ca", + "", + "0d7f1aed4708a03b0c80b2a18785c96d", + }, + { + "15276fc64438578e0ec53366b90a0e23d93910fec10dc3003d9b3f3fa72db702", + "c5e931946d5caebc227656d2", + "", + "3f967c83ba02e77c14e9d41185eb87f172250e93edb0f82b6742c124298ab69418358eddefa39fedc3cade9d80f036d864a59ead37c87727c56c701a8cd9634469ff31c704f5ee39354157e6558467b92824da36b1c071bedfe9", + "", + "a0ffa19adcf31d061cd0dd46d24015ef", + }, + { + "ec09804a048bb854c71618b5a3a1c590910fc8a68455139b719486d2280ea59a", + "d0b1247e7121a9276ac18ca3", + "", + "66b1d39d414596308e866b04476e053b71acd1cd07ce80939577ebbeace0430f7e4c0c185fe1d97ac7569950c83db40bbed0f1d173e1aa0dc28b4773705032d97551f7fcef7f55e4b69f88df650032dfc5232c156641104b5397", + "", + "8440e6d864ab778f9be478f203162d86", + }, + { + "4adf86bfa547725e4b80365a5a327c107040facfff007dc35102066bd6a995c4", + "b1018cc331911255a55a0795", + "", + "053ca4428c990b4456d3c1895d5d52deff675896de9faa53d8cf241255f4a31dc3399f15d83be380256616e5af043abfb37552655adf4f2e68dda24bc3736951134f359d9c0e288bb798b6c3ea46239231a3cb280066db9862e7", + "", + "c7424f38084930bfc5edc1fcf1e7608d", + }, + { + "3c92e0d1e39a3c766573c4646c768c402ccff48a56682a93433512abf0456e00", + "d57f319e590191841d2b98bd", + "", + "840d9394aa240e52ba152151c12acd1cd44881e8549dc832b71a45da7efcc74fb7e844d9fec25e5d497b8fb8f47f328c8d99045a19e366e6ce5e19dc26f67a81a94fa6c97c314d886e7b56eff144c09f6fa519db6308bc73422e", + "", + "cb4ef72dbda4914d7434f9686f823e2f", + }, + { + "b66ba39733888a9e0a2e30452844161dc33cb383c02ce16c4efad5452509b5b5", + "937cb665e37059b2e40359f2", + "", + "dbcd9694a8834860034e8ede3a5bd419fcf91c005ad99f488aa623f581622093f9d41e6a68e20fd202f302bcfc4417ca89090bfcd4d5224e8ff4eb5bbae4ecb27baa239f59c2f99cd47c0a269c497906b41a8f320a3dd2dc2de2", + "", + "bdc8249302d9d666cf7168317c118743", + }, + { + "2f9fcd1043455695638c991a1b1d35ad57c18ef0727322747b7991abc3d787f3", + "d06cf548f62869f4bed7a318", + "", + "432023c12cf1f614e1005112a17dbe6c5d54022a95cf6335a5bc55004c75f09a5699739ecf928e1c78d03dad5096a17a084afe1cc22041bbdfb5985bd08b0dcc59d2b08cd86b7aad597c4cd7b4ba6d6a7370b83995a6511a1f9e", + "", + "322eb84fb6884f10cfb766c2e3ec779e", + }, + { + "21c5839a63e1230c06b086341c96ab74585e69bced94332caeb1fa77d510c24f", + "5ab6e5ed6ee733be7250858c", + "", + "c92f08e30f67d42516133c48e97b65cc9e124365e110aba5e7b2cbe83debcc99edf4eb0007af052bda22d85900271b1897af4fd9ace6a2d09d984ac3de79d05de0b105a81b12542b2c48e27d409fd6992dd062d6055d6fc66842", + "", + "53b0e450309d146459f2a1e46c9d9e23", + }, + { + "25a144f0fdba184125d81a87e7ed82fad33c701a094a67a81fe4692dc69afa31", + "8bf575c5c2b45b4efc6746e4", + "", + "2a367cb0d3b7c5b8320b3cf95e82b6ba0bba1d09a2055885dedd9ef5641623682212103238b8f775cce42ddfd4f66382f2c3a5e8d6dff9163ced83580a75705574026b55db90f75f8abb3014c9a707021dedc075da38bebbf0a0", + "", + "0e2ce9cac8dfcedb0572ec6cab621efd", + }, + { + "42bc841b3b03a807cd366a35ecec8a6aebef7c4cba0ec8cb8da0da41df8ccef1", + "1bd46f85df5f4b3a126ee315", + "", + "ede3dcddbdc7d8e5d034c01661332ec349cb4e7a9fbaaf7abe2c647587db86cd427ce66908e070bc49ef838747e06b45ac486dfbea6f8698b4625e21e69db8327ec05cfd74accbe67ab644948cdb554af179a1e264e08fe16641", + "", + "633ab6aaf5b32b53a794f6be6262fc5f", + }, + { + "c25b8500be73210596fc4a9fb4d84d1a3379a91e3f0a6cc4177d996046627679", + "b56c48c0c4cd318b20437002", + "", + "bcd14dd043fdc8c327957e1c1428698543ec8602521a7c74788d296d37d4828f10f90656883d2531c702ebda2dc0a68dab00154577454455fad986ff8e0973098dbf370ff703ed98222b945726ed9be7909210ddbc672e99fdd9", + "", + "8171d4ff60fe7ef6de0288326aa73223", + }, + { + "dd95259bc8eefa3e493cb1a6ba1d8ee2b341d5230d50363094a2cc3433b3d9b9", + "a1a6ced084f4f13990750a9e", + "", + "d46db90e13684b26149cb3b7f776e228a0538fa1892c418aaad07aa08d3076f4a52bee8f130ff560db2b8d1009e9260fa6233fc22733e050c9e4f7cc699062765e261dffff1159e9060b26c8065dfab04055b58c82c340d987c9", + "", + "9e120b01899fe2cb3e3a0b0c05045940", + }, + { + "31bdadd96698c204aa9ce1448ea94ae1fb4a9a0b3c9d773b51bb1822666b8f22", + "0d18e06c7c725ac9e362e1ce", + "2db5168e932556f8089a0622981d017d", + "", + "fa4362189661d163fcd6a56d8bf0405a", + "d636ac1bbedd5cc3ee727dc2ab4a9489", + }, + { + "460fc864972261c2560e1eb88761ff1c992b982497bd2ac36c04071cbb8e5d99", + "8a4a16b9e210eb68bcb6f58d", + "99e4e926ffe927f691893fb79a96b067", + "", + "133fc15751621b5f325c7ff71ce08324", + "ec4e87e0cf74a13618d0b68636ba9fa7", + }, + { + "f78a2ba3c5bd164de134a030ca09e99463ea7e967b92c4b0a0870796480297e5", + "2bb92fcb726c278a2fa35a88", + "f562509ed139a6bbe7ab545ac616250c", + "", + "e2f787996e37d3b47294bf7ebba5ee25", + "00f613eee9bdad6c9ee7765db1cb45c0", + }, + { + "48e6af212da1386500454c94a201640c2151b28079240e40d72d2a5fd7d54234", + "ef0ff062220eb817dc2ece94", + "c7afeecec1408ad155b177c2dc7138b0", + "", + "9432a620e6a22307e06a321d66846fd4", + "e3ea499192f2cd8d3ab3edfc55897415", + }, + { + "79cd8d750fc8ea62a2714edcd9b32867c7c4da906c56e23a644552f5b812e75a", + "9bbfdb81015d2b57dead2de5", + "f980ad8c55ebd31ee6f98f44e92bff55", + "", + "41a34d1e759c859e91b8cf5d3ded1970", + "68cd98406d5b322571e750c30aa49834", + }, + { + "130ae450c18efb851057aaa79575a0a090194be8b2c95469a0e8e380a8f48f42", + "b269115396f81b39e0c38f47", + "036cf36280dee8355c82abc4c1fdb778", + "", + "09f7568fd8181652e556f0dda5a49ed5", + "d10b61947cae275b7034f5259ba6fc28", + }, + { + "9c7121289aefc67090cabed53ad11658be72a5372761b9d735e81d2bfc0e3267", + "ade1702d2051b8dd203b5419", + "b95bcaa2b31403d76859a4c301c50b56", + "", + "628285e6489090dde1b9a60674785003", + "9f516af3f3b93d610edbc5ba6e2d115f", + }, + { + "0400b42897011fc20fd2280a52ef905d6ebf1b055b48c97067bd786d678ec4ea", + "0abfb0a41496b453358409d9", + "20c8230191e35f4e9b269d59cf5521f6", + "", + "dd8c38087daffbbb3ebb57ebf5ee5f78", + "bfb07aa5049ee350ec6fb1397f37087b", + }, + { + "56690798978c154ff250ba78e463765f2f0ce69709a4551bd8cb3addeda087b6", + "cf37c286c18ad4ea3d0ba6a0", + "2d328124a8d58d56d0775eed93de1a88", + "", + "3b0a0267f6ecde3a78b30903ebd4ca6e", + "1fd2006409fc636379f3d4067eca0988", + }, + { + "8a02a33bdf87e7845d7a8ae3c8727e704f4fd08c1f2083282d8cb3a5d3cedee9", + "599f5896851c968ed808323b", + "4ade8b32d56723fb8f65ce40825e27c9", + "", + "cb9133796b9075657840421a46022b63", + "a79e453c6fad8a5a4c2a8e87821c7f88", + }, + { + "23aaa78a5915b14f00cf285f38ee275a2db97cb4ab14d1aac8b9a73ff1e66467", + "4a675ec9be1aab9632dd9f59", + "56659c06a00a2e8ed1ac60572eee3ef7", + "", + "e6c01723bfbfa398d9c9aac8c683bb12", + "4a2f78a9975d4a1b5f503a4a2cb71553", + }, + { + "fe647f72e95c469027f4d7778429a2e8e90d090268d4fa7df44f65c0af84190a", + "4f40ae2a83a9b480e4686c90", + "31fd6cce3f0d2b0d18e0af01c4b5609e", + "", + "54c769fd542f0d3022f1335a7c410b61", + "106cb7cbcd967da6cad646039c753474", + }, + { + "fce205515f0551b1797128a2132d8e002ea5ab1beb99c5e7e8329398cf478e10", + "20209a0d4a3b9bfddeef39a0", + "7d663e31a2f6ffef17e536684dae2e87", + "", + "6529712030fb659dc11ab719f6a4c402", + "58699464d062aba505508c576c4e07dd", + }, + { + "cd33003ff18f6f3369dd9a35381261ba660ce0a769864475152e677066540337", + "20bffe9064ce76d275204138", + "acaf53d4dd2fe12cd44450b0d9adcc92", + "", + "a669fda0444b180165f90815dc992b33", + "6e31f5a56c4790cedcc2368c51d0639b", + }, + { + "381873b5f9579d8241f0c61f0d9e327bb9f678691714aaa48ea7d92678d43fe7", + "3fc8bec23603158e012d65e5", + "7b622e9b408fe91f6fa800ecef838d36", + "", + "8ca4de5b4e2ab22431a009f3ddd01bae", + "b3a7f80e3edf322622731550164cd747", + }, + { + "92e11dcdaa866f5ce790fd24501f92509aacf4cb8b1339d50c9c1240935dd08b", + "ac93a1a6145299bde902f21a", + "2d71bcfa914e4ac045b2aa60955fad24", + "1e0889016f67601c8ebea4943bc23ad6", + "8995ae2e6df3dbf96fac7b7137bae67f", + "eca5aa77d51d4a0a14d9c51e1da474ab", + }, + { + "7da3bccaffb3464178ca7c722379836db50ce0bfb47640b9572163865332e486", + "c04fd2e701c3dc62b68738b3", + "fd671cab1ee21f0df6bb610bf94f0e69", + "fec0311013202e4ffdc4204926ae0ddf", + "6be61b17b7f7d494a7cdf270562f37ba", + "5e702a38323fe1160b780d17adad3e96", + }, + { + "a359b9584beec189527f8842dda6b6d4c6a5db2f889635715fa3bcd7967c0a71", + "8616c4cde11b34a944caba32", + "33a46b7539d64c6e1bdb91ba221e3007", + "e1796fca20cb3d3ab0ade69b2a18891e", + "b0d316e95f3f3390ba10d0274965c62b", + "aeaedcf8a012cc32ef25a62790e9334c", + }, + { + "8c83238e7b3b58278200b54940d779d0a0750673aab0bf2f5808dd15dc1a8c49", + "70f8f4ebe408f61a35077956", + "6e57f8572dd5b2247410f0d4c7424186", + "e1cbf83924f1b8d1014b97db56c25a15", + "4a11acb9611251df01f79f16f8201ffb", + "9732be4ad0569586753d90fabb06f62c", + }, + { + "fe21919bb320af8744c9e862b5b7cf8b81ad3ad1fb0e7d7d710a688d3eed154b", + "38bc3917aa1925f40850c082", + "aea53b1ea79a71c3a4b83c92a0c979f1", + "f24102fa7e6b819bb3ff47f90844db9c", + "2fb8b697bf8f7a2eea25fe702a3ae0a9", + "5be77e827737ad7c4f79e0e343fe010d", + }, + { + "499e8a3f39ac4abc62dd4e1a6133042e74785972b6b501bfaffefc8bb29fd312", + "5c728dbbef9dcc0ff483e891", + "b44014c7fc6b3f15d126a881fbe2bd2b", + "82300dab592f840ae991efa3623a6203", + "578fe5e1aef7619f392c027c838a239e", + "49fdc724f05eb56ea9e3fd14b61ad567", + }, + { + "2775d3e7a8fc665bb9a59edc22eb136add194824ed8f2adb449177404c739716", + "73f16c054e166696df679a2e", + "c9f3bce40310b6c0a3fd62742e4f3617", + "23199a1c9b7244913952ca4f7e7444f4", + "72c85c10756266d00a9a4340b2cb3137", + "5881e4565b42394e62d5daf0d1ebc593", + }, + { + "425a341c67e6d873870f54e2cc5a2984c734e81729c0dbaaeee050309f1ce674", + "0c09b7b4e9e097317b791433", + "76dda644b3faca509b37def0319f30cc", + "4300a721547846761e4bf8df2b6ec1d6", + "1dd80daa0fc9e47e43897c64a6663f5e", + "5d69b34d8c3b12f783faaea7e93685db", + }, + { + "dd5c48988a6e9f9f60be801ba5c090f224a1b53d6601ec5858eab7b7784a8d5e", + "43562d48cd4110a66d9ca64e", + "2cda2761fd0be2b03f9714fce8d0e303", + "55e568309fc6cb0fb0e0e7d2511d4116", + "f2cfb6f5446e7aa172adfcd66b92a98d", + "e099c64d2966e780ce7d2eaae97f47d8", + }, + { + "2bdad9c3e5de6e4e101b7f16e727c690db95eacf4b0ccbdec7aab6fb9fc80486", + "a5cf3967d244074d2153c576", + "84c867ec36cc6fe3487f5192fdfd390b", + "6bdae72b5ed0e4d1f10064ebd02cf85c", + "53c8fa437c1b5fa91abbd6508b3878ce", + "7859593d127324be8b9cf1d43ead4d82", + }, + { + "01e92afdb5d956be12d38b09252966c5728d26f3c72e54bb62bbc55ae590e716", + "886e55364eeb90e87ac79bbe", + "6c6570385f3d6d937e54a3a2e95bc9eb", + "c76aabb7f44b942a81feb50249d2131a", + "423b749a507f437b431114962180d352", + "54d859320a49281368297da7d4e37326", + }, + { + "46921319217598cb64256fe49abca1f18a9d1dbca360f8630afb5c6137cb42b5", + "290827cf981415760ec3b37a", + "480d32b191c2e201aed03680f93ea2da", + "535ee80b12f581baaf8027e6e3900e31", + "89ace4f73583fb1ac260dea99b54055e", + "7b8b8358363c175a66e6fb48d1bc2222", + }, + { + "e18cd9b01b59bc0de1502efb74c3642997fe7dfb8d80c8a73caffe7726807d33", + "bd087b384c40841b3839ba02", + "62f7f3a12b8c5f6747fcfe192d850b19", + "fe69f837961b1d83f27fbf68e6791a1c", + "bacfccf6397424e96caf761e71dd3e3a", + "9c9a5b65420f83e766c7c051680e8e58", + }, + { + "68ee463b3153d9a042e5e3685def6f90f7659a203441de337fb94831cbeae9b2", + "9c4a9254c485236cf838de7e", + "73731054514f3fb0102c7a1df809f212", + "d55820e7acbb27d23c7df32938cf7d42", + "13b7823cac37f40eb811e3c966d16a67", + "76288c33a66ff6451e2cec6c4ba4935e", + }, + { + "64bd594daf279e3172f9aa713b35b7fce8f43083792bc7d1f10919131f400a7b", + "339a2c40e9d9507c34228649", + "2b794cb4c98450463a3e225ab33f3f30", + "2b9544807b362ebfd88146e2b02c9270", + "434d703b8d1069ad8036288b7c2d1ae6", + "7d31e397c0c943cbb16cfb9539a6a17d", + }, + { + "83688deb4af8007f9b713b47cfa6c73e35ea7a3aa4ecdb414dded03bf7a0fd3a", + "0b459724904e010a46901cf3", + "33d893a2114ce06fc15d55e454cf90c3", + "794a14ccd178c8ebfd1379dc704c5e208f9d8424", + "cc66bee423e3fcd4c0865715e9586696", + "0fb291bd3dba94a1dfd8b286cfb97ac5", + }, + { + "013f549af9ecc2ee0259d5fc2311059cb6f10f6cd6ced3b543babe7438a88251", + "e45e759a3bfe4b652dc66d5b", + "79490d4d233ba594ece1142e310a9857", + "b5fe530a5bafce7ae79b3c15471fa68334ab378e", + "619443034e4437b893a45a4c89fad851", + "6da8a991b690ff6a442087a356f8e9e3", + }, + { + "4b2815c531d2fceab303ec8bca739a97abca9373b7d415ad9d6c6fa9782518cc", + "47d647a72b3b5fe19f5d80f7", + "d3f6a645779e07517bd0688872e0a49b", + "20fd79bd0ee538f42b7264a5d098af9a30959bf5", + "00be3b295899c455110a0ae833140c4d", + "d054e3997c0085e87055b79829ec3629", + }, + { + "2503b909a569f618f7eb186e4c4b81dbfe974c553e2a16a29aea6846293e1a51", + "e4fa3dc131a910c75f61a38b", + "188d542f8a815695c48c3a882158958c", + "f80edf9b51f8fd66f57ce9af5967ec028245eb6e", + "4d39b5494ca12b770099a8eb0c178aca", + "adda54ad0c7f848c1c72758406b49355", + }, + { + "6c8f34f14569f625aad7b232f59fa8b187ab24fadcdbaf7d8eb45da8f914e673", + "6e2f886dd97be0e4c5bd488b", + "ac8aa71cfbf1e968ef5515531576e314", + "772ec23e49dbe1d923b1018fc2bef4b579e46241", + "cb0ce70345e950b429e710c47d9c8d9b", + "9dceea98c438b1d9c154e5386180966d", + }, + { + "182fe560614e1c6adfd1566ac44856df723dcb7e171a7c5796b6d3f83ef3d233", + "8484abca6877a8622bfd2e3c", + "92ca46b40f2c75755a28943a68a8d81c", + "2618c0f7fe97772a0c97638cca238a967987c5e5", + "ed1941b330f4275d05899f8677d73637", + "3fe93f1f5ffa4844963de1dc964d1996", + }, + { + "65a290b2fabe7cd5fb2f6d627e9f1f79c2c714bffb4fb86e9df3e5eab28320ed", + "5a5ed4d5592a189f0737cf47", + "662dda0f9c8f92bc906e90288100501c", + "ad1c7f7a7fb7f8fef4819c1dd1a67e007c99a87b", + "8eb7cb5f0418da43f7e051c588776186", + "2b15399ee23690bbf5252fb26a01ae34", + }, + { + "7b720d31cd62966dd4d002c9ea41bcfc419e6d285dfab0023ba21b34e754cb2f", + "e1fb1f9229b451b72f89c333", + "1aa2948ed804f24e5d783b1bc959e086", + "7fdae42d0cf6a13873d3092c41dd3a19a9ea90f9", + "8631d3c6b6647866b868421b6a3a548a", + "a31febbe169d8d6f391a5e60ef6243a0", + }, + { + "a2aec8f3438ab4d6d9ae566a2cf9101ad3a3cc20f83674c2e208e8ca5abac2bb", + "815c020686c52ae5ddc81680", + "a5ccf8b4eac22f0e1aac10b8d62cdc69", + "86120ce3aa81445a86d971fdb7b3b33c07b25bd6", + "364c9ade7097e75f99187e5571ec2e52", + "64c322ae7a8dbf3d2407b12601e50942", + }, + { + "e5104cfcbfa30e56915d9cf79efcf064a1d4ce1919b8c20de47eab0c106d67c1", + "d1a5ec793597745c7a31b605", + "7b6b303381441f3fdf9a0cf79ee2e9e0", + "9931678430ff3aa765b871b703dfcc43fb1b8594", + "425d48a76001bed9da270636be1f770b", + "76ff43a157a6748250a3fdee7446ed22", + }, + { + "f461d1b75a72d942aa096384dc20cf8514a9ad9a9720660add3f318284ca3014", + "d0495f25874e5714a1149e94", + "d9e4b967fdca8c8bae838a5da95d7cce", + "1133f372e3db22456e7ea92f29dff7f1d92864d3", + "1df711e6fbcba22b0564c6e36051a3f7", + "f0563b7494d5159289b644afc4e8e397", + }, + { + "a9a98ef5076ceb45c4b60a93aeba102507f977bc9b70ded1ad7d422108cdaa65", + "54a1bc67e3a8a3e44deec232", + "ede93dd1eaa7c9859a0f709f86a48776", + "10cfef05e2cd1edd30db5c028bd936a03df03bdc", + "3d3b61f553ab59a9f093cac45afa5ac0", + "7814cfc873b3398d997d8bb38ead58ef", + }, + { + "d9e17c9882600dd4d2edbeae9a224d8588ff5aa210bd902d1080a6911010c5c5", + "817f3501e977a45a9e110fd4", + "d74d968ea80121aea0d7a2a45cd5388c", + "d216284811321b7591528f0af5a3f2768429e4e8", + "1587c8b00e2c197f32a21019feeee99a", + "63ea43c03d00f8ae5724589cb6f64480", + }, + { + "ec251b45cb70259846db530aff11b63be00a951827020e9d746659bef2b1fd6f", + "e41652e57b624abd84fe173a", + "75023f51ba81b680b44ea352c43f700c", + "92dd2b00b9dc6c613011e5dee477e10a6e52389c", + "29274599a95d63f054ae0c9b9df3e68d", + "eb19983b9f90a0e9f556213d7c4df0f9", + }, + { + "61f71fdbe29f56bb0fdf8a9da80cef695c969a2776a88e62cb3d39fca47b18e3", + "77f1d75ab0e3a0ed9bf2b981", + "110a5c09703482ef1343396d0c3852d3", + "c882691811d3de6c927d1c9f2a0f15f782d55c21", + "7e9daa4983283facd29a93037eb70bb0", + "244930965913ebe0fa7a0eb547b159fb", + }, + { + "e4fed339c7b0cd267305d11ab0d5c3273632e8872d35bdc367a1363438239a35", + "0365882cf75432cfd23cbd42", + "fff39a087de39a03919fbd2f2fa5f513", + "8a97d2af5d41160ac2ff7dd8ba098e7aa4d618f0f455957d6a6d0801796747ba57c32dfbaaaf15176528fe3a0e4550c9", + "8d9e68f03f7e5f4a0ffaa7650d026d08", + "3554542c478c0635285a61d1b51f6afa", + }, + { + "bd93c7bfc850b33c86484e04859ed374beaee9d613bdca6f072d1d182aeebd04", + "6414c7749effb9af7e5c4762", + "b6de1699931f2252efc98d491d22ee12", + "76f43d5664c7ac1b4de43f2e2c4bc71f6918e0762f40e5dd5597ef4ff215855a4fd26d3ea6ccbd4e10789948fa692433", + "a6c7e52f2018b823506e48064ffe6ee4", + "175e653c9036f66835f10cf1c82d1741", + }, + { + "df0125a826c7fe49243d89cbdd7562aafd2103fa2783cf901976b5f5d481cdcb", + "f63c1461b2964929d035d9bf", + "cc27ff68f981e4d6fb1918427c3d6b9e", + "0bf602ec47593e44ac1b88244455fa04359e338057b0a0ba057cb506d546d4d6d8538640fe7dd3d5864bd33b5a33d768", + "b8fa150af93078574ac7c4615f88647d", + "4584553ac3ccdf8b0efae517652d3a18", + }, + { + "d33ea320cec0e43dfc1e3d1d8ccca2dd7e30ad3ea18ad7141cc83645d18771ae", + "540009f321f41d00202e473b", + "e56cdd522d526d8d0cd18131a19ee4fd", + "a41162e1fe875a81fbb5667f73c5d4cbbb9c3956002f7867047edec15bdcac1206e519ee9c238c371a38a485c710da60", + "8b624b6f5483f42f36c85dc7cf3e9609", + "2651e978d9eaa6c5f4db52391ac9bc7c", + }, + { + "7f35f5979b23321e6449f0f5ef99f2e7b796d52d560cc77aabfb621dbf3a6530", + "cf0f6f3eed4cf374da714c77", + "4e9f53affdb5b1e91bf423d29c54401a", + "a676d35d93e12bfe0603f6aef2c3dd892a9b1ad22d476c3509d313256d4e98e4dda4e46e93b54cf59c2b90608a8fb3ad", + "1714d55ef83df2927ee95ff22f1d90e6", + "4962a91d1071dd2c05934968d21eb43c", + }, + { + "06ecc134993506cf539b1e797a519fe1d9f34321fe6a0b05f1936285c35c93a4", + "f2190861d1140bd080d79906", + "519c1fc45a628ec16c515427796711f7", + "a04f2723c2521181437ad63f7910481d5de98f3e2561cec3a177bdbcb5048619738852e0fb212a3caa741a353e4e89a8", + "b36c793224ce3bb1b54144398fbdedb6", + "0030e6e84f6f8eb474ce8e071c2953dd", + }, + { + "734fa8b423b91e0ecccc7f554480eef57a82423a9f92b28d464320fba405a71c", + "a6b5c78bb5791f4d121390ce", + "b496a99b39e0e94bb5829cfc3d7b3856", + "9ce25ff9b55dfa04e4271999a47cba8af8e83a390b090d1c4306b40ce8882624b662ff5867896396789295c19ec80d07", + "904081a40484bb6454fc52cb6674e737", + "6a0787cf3921a71c35b5054954527823", + }, + { + "d106280b84f25b294f71c261f66a65c2efd9680e19f50316d237975052796392", + "cfc6aa2aeba468c66bf4553f", + "57e937f8b9b814e965bb569fcf63aaac", + "012a43f9903a3808bf34fd6f77d831d9154205ded589964cae60d2e49c856b7a4100a55c8cd02f5e476f62e988dcbd2b", + "c835f5d4fd30fe9b2edb4aff24803c60", + "e88426bb4619807f18a9cc9839754777", + }, + { + "81eb63bc47aba313d964a5335cfb039051520b3112fa54cab368e5243947d450", + "18cc5dd875753ff51cc6f441", + "45f51399dff6a0dcd43f35256616d6be", + "24f766c56777312494245a4e6c7dbebbae4026e0907eadbc20a488982678161de7b924473c0a81ee59a0fa6905952b33", + "a2fc7b0784ec4233142f9cde12ab9e98", + "4e60b8561cacfe7133740cd2bddefaa0", + }, + { + "0a997863786a4e97332224ed484ffca508b166f0603687200d99fd6accd45d83", + "7a9acabd4b8d3e1036293a07", + "9d2c9ff39f57c96ecce287c68c5cd6eb", + "525fc5ac7fe93c183a3ef7c75e3fbd52dce956855aff385966f4d79966bdb3ec2019c466584d21bfee74511a77d82adb", + "238441c65b2a1c41b302da0f52d40770", + "c351d93ab9491cdfb7fa15e7a251de22", + }, + { + "acbfeb7c595b704960c1097e93d3906534c23444c8acc1f8e969ce6c3fe8a46b", + "28922ecac3013806c11660e6", + "e0d8c52d60c6ed6980abd4348f3f96f1", + "b1fe886107013ebdeb19315a9d096ed81803951a508f56f68202a7df00bebae0742dd1128c200952a049ef0cd7cfe4e6", + "56fe1cf2c1d193b9b33badbf846f52cc", + "1cb4c14f50a54a64813ffc810f31f9f8", + }, + { + "f6e768475c33269596da1f5a5a38547a885006bebb9134e21274d8456e9f5529", + "3579e5ac51d1f1b82ea352ca", + "0aa481f856f8b96547672e5ae5370f9e", + "6929b6053ba148304366164f79b1b9f592c9cb9bce65094cec5cb8b0fc63e20d86b17c8bf5a7b089a63c5eac1824ee93", + "b2f4edf5f0b0bfc590fead6239b0f2fb", + "2540ceb5ef247c95d63df84c46468533", + }, + { + "2ca76112300bed65b87ba6ec887cd514f4633c1c96565fec8e3e69ae2ba88401", + "964864510a8c957dcfb97d2f", + "0aff24b4c5aa45b81ce08ec2439be446", + "5aebdfd153a18763f36ecc9e8e9a01cb7b3f21e435b35b0da937c67e87c9ec058d08060a95e1eda0a5ab6546cca45094", + "03da1f5a1403dbdd9f75a26113608ec0", + "a1c215d0c552a6061aa2b60afc3667a6", + }, + { + "c0ff018b6c337dde685c8279cf6de59d7ce4b288032b819e074b671e72abbc91", + "f12e6b1e85f87ef4c9ccbb7b", + "f7512bbfa2d40d14be71b70f70701c99", + "0577e8d28c0e9e5cde3c8b2a1a2aa8e2fc3ec8e96768405fcfbd623be7fc4e2e395c59b5b3a8ea117ef211320bc1f857", + "0187b4c2d52486b4417e5a013d553e5e", + "dba451e7339be8ebed3ea9683d1b4552", + }, + { + "d90c6948ac2353867e943069196a2c4d0c4d51e34e2505661b1d76f3e5f17ac5", + "07e5623f474e2f0fe9f4c7d2", + "8a9fb1b384c0d1728099a4f7cb002f07", + "0de97574ae1bc6d3ef06c6ce03513ca47dff4728803e0aacc50564ee32b775fd535f5c8c30186550d99bff6f384af2dd", + "4234a3a9fb199c3b293357983e8ac30b", + "d51e6f071dbab126f5fc9732967108ef", + }, + { + "80d755e24d129e68a5259ec2cf618e39317074a83c8961d3768ceb2ed8d5c3d7", + "7598c07ba7b16cd12cf50813", + "5e7fd1298c4f15aa0f1c1e47217aa7a9", + "0e94f4c48fd0c9690c853ad2a5e197c5de262137b69ed0cdfa28d8d12413e4ffff15374e1cccb0423e8ed829a954a335ed705a272ad7f9abd1057c849bb0d54b768e9d79879ec552461cc04adb6ca0040c5dd5bc733d21a93702", + "5762a38cf3f2fdf3645d2f6696a7eead", + "8a6708e69468915c5367573924fe1ae3", + }, + { + "dda7977efa1be95a0e41ed8bcd2aa648621945c95a9e28b63919e1d92d269fc3", + "053f6e1be42af8894a6e86a0", + "6fa9b08176e9963927afba1e5f969a42", + "cb5114a001989339657427eb88329d6ce9c69694dc91a69b7557d62184e57832ec76d162fc9c47490bb3d78e5899445cecf85d36cb1f07fed5a3d82aaf7e9590f3ed74ad13b13c8adbfc7f29d7b151448d6f29d11d0bd3d03b76", + "d4adbff3ec8edade29b9a1b748c31b54", + "3b331733c753858c22d309ceb0f9488c", + }, + { + "d7da934ad057dc06bd1ec234fcc4efdc5119037a440b5827de25915f22dd47e5", + "1b54c4ea37d2395ef70dcc72", + "86d5567658361198348207ede7a46da6", + "735de4596a80e64e38a12ab24ef73881d6ed3b533cb2c101025c3615acd2114150feeca84ade4e563bc4a300eb4a0cd97a184a293f0ac063e4f3c61e7fcdb331bcc6459fafaf0e2dda881f34eb717f4ee8c4b6890d3ef59721f3", + "70a1c1d7c200ba5ae1b6f29917bb19f2", + "a25d51cccb198bed33de0b98df249c2d", + }, + { + "930ebb4b9b9c35094be374cc0b700c437b3c46b45d489a716c30f93cd5f986c9", + "7a21e5febd82ec9b97bfbe83", + "980086665d08a365f6bbe20ae51116f7", + "9f2ed5f6cf9e2d6505d3c99a8f81a7dfc5658dd085eba966c8b3206230973a086ec36fe948573baee108fca941bce53dad73180877cd497976209c1adf8a9861f0215560df064caf0ef2f99445c11816f5b8deeafedd682b5fb2", + "05baaefdeb0c33674a8064a2e9951aaf", + "2ec7efd2564d4e09a6ab852f3af49939", + }, + { + "70213d8949a65f463d13206071fab1b4c6b614fd3cee0d340d2d806de6714a93", + "f8529d3e4f155cbb1ffb3d0a", + "47d47a5fd32a2a416f921cc7f00c0f81", + "112360db39b867dabaaa1d777bd881df2104b69fba15a4f37a832f5da38ad8a8c7c46db93e5b4eadf8b9a5a75508ad1457994c133c5ac85509eedfb13b90a2cf6c56a3c778582939362008608b08f9c4866a0e38744572114598", + "b220b69bd851a17fbc5b725fb912f11e", + "4c3436943d58501c0826ae5827bc063e", + }, + { + "7a5834230ebbbf616630f2edb3ad4320182433c0546ac1e34bc9fd046e4a0ed9", + "d27dd6212b6defdcbbc701bb", + "b4def1251427ade064a9614e353dda3f", + "3bc12f3bb88ea4f8a2184959bb9cd68911a78458b27e9b528ccecafe7f13f303dc714722875f26b136d18a3acfe82b53ad5e13c71f3f6db4b0fd59fffd9cd4422c73f2c31ac97010e5edf5950dc908e8df3d7e1cbf7c34a8521e", + "88f94965b4350750e11a2dc139ccaef1", + "8a61f0166e70c9bfdd198403e53a68a5", + }, + { + "c3f10586f246aacadcce3701441770c03cfec940afe1908c4c537df4e01c50a0", + "4f52faa1fa67a0e5f4196452", + "79d97ea3a2edd65045821ea745a44742", + "46f9a22b4e52e1526513a952dbee3b91f69595501e0177d50ff364638588c08d92fab8c58a969bdcc84c468d8498c4f06392b99ed5e0c484507fc48dc18d87c40e2ed848b43150be9d36f14cf2cef1310ba4a745adcc7bdc41f6", + "560cf716e56190e9397c2f103629eb1f", + "ff7c9124879644e80555687d273c55d8", + }, + { + "ad70ebcf889e88b867ded0e4838ca66d6991499046a5671d99e91ed463ae78b1", + "561e13b335718fcbee364100", + "82d5568872a4cef12238c0feb14f0fb4", + "e037bd7306eec185b9cb4e3bf295232da19005957086d62e6fb342284f05feaa0e81d6c95071e7e4d7b6aad7b00f7e7863dd0fc16303a8304bb8855305f28067f4be71eed95ff90e046382116229f0fd3d2c3ef2e87e0d0e7950", + "771c6d091f8190ddbdb8886d9ce2ebd5", + "5009abd1ebeb26dab852346ea6d8aee3", + }, + { + "a452fa24b381e7165ee90f3371c2b0db2176f848a0354c78e92f2f1f89bbc511", + "4bd904dfe18241eb5455d912", + "3f43df23ea940f3680a4b679b56db579", + "64f1a9d21deb183cff84f1aef5be83dbfc72e275f229eb5d59ace143605e8901dfa8f4724be24c86b5429bc84b629971fe1f9663b7537427b45dfb67d5f04506df4ee2c33d7f15af9f6e86058b131b7e6042b43a55bf6915f048", + "c054974c4562f8536aef2734f10e09fc", + "2c5cafaf7b1f7581c5ec13080994e33c", + }, + { + "209ea3c4dd0420a4d63dbb72099a0202c9b0709f3b1221565f890511eef8005b", + "43775083e4008816129f5d40", + "b4967f8c4fb1b34b6ff43a22d34fae5c", + "9abc653a2347fc6e5a8cb9bdc251dff7c56109797c387494c0ed55570330961eb5b11087603e08ad293d0dd55571008e62d1163f67cf829e28d27beba65553bd11d8838f8a7a5f1fe05500befbaf97839801e99ecf998882c707", + "a8d22a6e25232938d3f8600a66be80da", + "2ef93cc03c17bbfb6626144697fd2422", + }, + { + "dabd63ac5274b26842c2695c9850d7accc1693ee2aeee1e2e1338bbbc5b80f87", + "fd6790d620f12870b1d99b31", + "4a28048f5683679a557630a661f030e2", + "e4a06b9b205a7faadb21dc7fea8a0de0e013d717b61b24ec42f81afc8cdbc055573e971375da2fa5103a091317eab13b6a110ea211af257feabf52abafec23fd5b114b013d5c052199020573f8b7b7ae6958f733e87efa0426c2", + "196d0345df259b47665bc233b798ebba", + "b0729d8b427ad048a7396cedf2257338", + }, + { + "b238df5e52e649d4b0a05e53020ac59e7d5bf49b8d04f8c30c356ed62dba9ed1", + "f153f093c9a3479f999eda04", + "d48e779766afa73d7e04fc6fc3fa825e", + "45b5df0c15140e5ce7a19f4e02834e6027971e3e0e719626c29081a6301e95c71214345afac1908bb75ff2d3281261e6c5f41dc4e4796f054174a64f8e177f3f33321edfbd263e204135699428a09f34eb344211bfb9fac9afba", + "b1989eb510843d8f35205dc3f949522f", + "616089990729228f673099514824d9b4", + }, + { + "f3dc2456d3b8947591a2d82b7319226b0f346cd4361bcc13b56da43e072a2774", + "7a8acb5a84d7d01e3c00499e", + "ad075da908231ff9aae30daa6b847143", + "5e6be069effee27d34a8087c0d193f9f13e6440dc9fabfe24f6c867f831d06789d0dce92b2e3ff3ab9fe14202a8b42f384c25e3f3753dd503ec907a9b877f1707d64e4ac42909a7dee00c87c4a09d04de331515460ed101f5187", + "9f224f2a1a1fbaade8b87b748971c0ac", + "cb5089d9dfaebf98e4b36ebc5f9a1a50", + }, + { + "f5a56b69a1562c77e8edebc327a20295c2eba7d406d899a622c53539626c9d72", + "a395b8aca4508a6a5f3cb4d8", + "7de4638701bd2b600d7f8d26da7a75bc", + "2e4fca2b163e4403971716015386cd81bdd1e57f00f2936da408098341011f2644a38ddad799f70eaa54f6e430d4853ff2b9c44a35123670879a83120bd555c76b95b70de0c8054f9d08539a5795e70a2446d7b9fab3f7887c6b", + "6508be2698ba9889b4e445b99190a5c5", + "3394106f257c2e15c815430f60bc24ba", + }, + { + "376371a780947256c52f07d80bb25a4d7e919ca8bd693b1a0ccbca748d2ce620", + "27d7170f6f70f2fc40dfca78", + "7a279f9f8568b7c307490549b259226c", + "272c3559398ad774fa4b6895afc92870b2b92d310fa0debf0b7960e1fe38bfda64acd2fef26d6b177d8ab11d8afceee77374c6c18ad405d5ae323ad65fb6b04f0c809319133712f47636c5e042f15ed02f37ee7a10c643d7b178", + "32284379d8c40ec18ee5774085d7d870", + "dcdee1a757f9758c944d296b1dabe7b2", + }, + { + "82c4f12eeec3b2d3d157b0f992d292b237478d2cecc1d5f161389b97f999057a", + "7b40b20f5f397177990ef2d1", + "982a296ee1cd7086afad976945", + "", + "ec8e05a0471d6b43a59ca5335f", + "113ddeafc62373cac2f5951bb9165249", + }, + { + "db4340af2f835a6c6d7ea0ca9d83ca81ba02c29b7410f221cb6071114e393240", + "40e438357dd80a85cac3349e", + "8ddb3397bd42853193cb0f80c9", + "", + "b694118c85c41abf69e229cb0f", + "c07f1b8aafbd152f697eb67f2a85fe45", + }, + { + "acad4a3588a7c5ec67832baee242b007c8f42ed7425d5a7e57b1070b7be2677e", + "b11704ba368abadf8b0c2b98", + "2656b5fbec8a3666cad5f460b7", + "", + "35c7114cabe39203df19413a99", + "16f4c7e5becf00db1223476a14c43ebc", + }, + { + "e5a0eb92cc2b064e1bc80891faf1fab5e9a17a9c3a984e25416720e30e6c2b21", + "4742357c335913153ff0eb0f", + "8499893e16b0ba8b007d54665a", + "", + "eb8e6175f1fe38eb1acf95fd51", + "88a8b74bb74fda553e91020a23deed45", + }, + { + "e78c477053f5dae5c02941061d397bc38dda5de3c9c8660a19de66c56c57fd22", + "4f52c67c2bb748d192a5a4e2", + "91593e21e1f883af5c32d9be07", + "", + "e37fbc56b0af200a7aa1bbe34e", + "29fe54eaaccf5e382601a15603c9f28c", + }, + { + "d0b13482037639aa797471a52b60f353b42e0ed271daa4f38a9293191cb78b72", + "40fb7cae46adf3771bf3756a", + "938f40ac8e0e3b956aac5e9184", + "", + "7dca05a1abe81928ccfb2164dd", + "5ea53ee170d9ab5f6cc047854e47cf60", + }, + { + "46da5ec688feead76a1ddcd60befb45074a2ef2254d7be26abdfd84629dbbc32", + "9fb3b2b03925f476fc9a35f3", + "a41adc9fb4e25a8adef1180ec8", + "", + "f55d4cbe9b14cea051fe7a2477", + "824753da0113d21186699dbb366c0589", + }, + { + "de3adf89f2fe246c07b0ce035f4af73cf2f65e5034dcfecfe9d7690ae1bdbd96", + "a94aa4df0d8451644a5056c0", + "96825f6d6301db14a8d78fc2f4", + "", + "784c6c3c24a022637cbc907c48", + "1eeaeddcdb4c72c4e8966950a319a4ef", + }, + { + "03c362288883327f6289bc1824e1c329ce485e0ce0e8d3405245283cf0f2eae2", + "5de9f882c915c72729b2245c", + "f5c1c8d41de01d9c08d9f47ece", + "", + "61af621953a126a2d1de559e92", + "fbdeb761238f2b70c5fb3dde0a7978f3", + }, + { + "e9ead7c59100b768aa6367d80c04a49bcd19fa8cc2e158dc8edeec3ea39b657d", + "e81854665d2e0a97150fbab3", + "f8ccf69c52a873695367a42940", + "", + "af2a7199602ee9ed2020c7b4cd", + "29715945ab1c034ecfcd91a466fc822e", + }, + { + "bc3e5b0fe423205904c32f870b9adec9d736a1616624043e819533fa97ed9b79", + "335fe5180135673ce1a75144", + "295df9665eef999204f92acf24", + "", + "3ac2a8a1b505a84677adfdb396", + "21f20aa0bb77d46d7290bc9c97a7a7bd", + }, + { + "ce889c73e0d64e272aba4bf9777afc7ee6457ddc9626ad931708ed7530d71b99", + "fe61a6cda62fecd4e3b0c562", + "e2ae40ba5b4103b1a3066c1b57", + "", + "185aa3508a37e6712b28191ec2", + "9ec1d567585aa467730cce92e536728e", + }, + { + "41e0cb1aed2fe53e0b688acb042a0c710a3c3ae3205b07c0af5191073abdfba9", + "2f56e35216d88d34d08f6872", + "6482df0e4150e73dac51dc3220", + "", + "9cb09b9927dfbe0f228e0a4307", + "fe7e87a596d63e2ab2aae46b64d466e8", + }, + { + "52a7662954d525cb00602b1ff5e937d41065ac4b921e284ffac73c04cfd462a0", + "baffe73856ab1a47fb1feebf", + "9d0b5ca712f97caa1875d3ad87", + "", + "fd01165380aedd6be226a66af3", + "35a492e39952c26456850b0172d723d1", + }, + { + "c4badb9766986faeb888b1db33060a9cd1f02e1afe7aaaea072d905750cb7352", + "cc6966e9d81a298a561416d4", + "de68fb51731b45e7c2c5063923", + "", + "f5be41f2c8c32e01098d433057", + "c82b1b012916ab6ed851d59829dad8ab", + }, + { + "dad89d9be9bba138cdcf8752c45b579d7e27c3dbb40f53e771dd8cfd500aa2d5", + "cfb2aec82cfa6c7d89ee72ff", + "b526ba1050177d05b0f72f8d67", + "6e43784a91851a77667a02198e28dc32", + "8b29e66e924ecae84f6d8f7d68", + "1e365805c8f28b2ed8a5cadfd9079158", + }, + { + "0d35d3dbd99cd5e088caf686b1cead9defe0c6001463e92e6d9fcdc2b0dcbaf6", + "f9139eb9368d69ac48479d1f", + "5e2103eb3e739298c9f5c6ba0e", + "825cc713bb41c789c1ace0f2d0dd3377", + "8ff3870eec0176d9f0c6c1b1a2", + "344234475538dc78c01f249f673e0862", + }, + { + "d35d64f1872bdcb422228f0d63f8e48977ed68d143f648ae2cd852f944b0e6dd", + "0b2184aadbe8b515924dda5e", + "c8f999aa1a08871d74db490cf3", + "888f328d9e9eebbb9cb2704b5b880d66", + "ad0d5e7c1065a34b27a256d144", + "8c8e7076950f7f2aeba62e1e761650d5", + }, + { + "9484b7ce3c118a8a2d556c2f7ba41fca34f60c9ea1070171459c9e7487c9537e", + "87bc033522ae84d2abe863c5", + "14d8004793190563825e273dda", + "07ee18737b9bf8223979a01c59a90eb4", + "43034a2c57ccacc367796d766a", + "4c981ca8b6e9e52092f5435e7ef55fbb", + }, + { + "4f4539e4a80ec01a14d6bb1bae0010f8a8b3f2cd0ac01adf239a9b2b755f0614", + "2b6f00ce1570432bf52fdcac", + "820cc9389e7e74ca1cbb5a5fe6", + "0d72a13effe40544c57cc18005b998cb", + "99553fdf3e777e2a4b3b6a5538", + "3cbf51640a3a93c3662c738e98fb36a2", + }, + { + "2f5e93ee24a8cd2fc6d3765f12d2179ddb8397783e136af9e0ac75f16fca451e", + "0dc3c70a191f3722641fd701", + "4e96463793cdeda403668c4aee", + "ebab30cbcc99905354e4ee6f07c7db87", + "ab03f8ca7b1b150bdc26d4e691", + "020546afff4290c4c8ef7fc38035ebfd", + }, + { + "a902e15d06ef5ad334d0ec6502e936ee53ef3f3608f7708848b11cefa92983d1", + "b9f3e966efa43ab4aca1f2d8", + "393ff3dfe51cd43543e4e29fcc", + "2eaa35c00bf1cf8a81919bd04b43fd97", + "7e8928b450c622ac8efe29d5a0", + "5a285de95990aef171629350bbcaf46e", + }, + { + "96657976da7692004e271b594e8304f77db9c9e77859246bb30a16239ba76a53", + "79226100afea30644876e79a", + "2b0833a065c3853ee27c8968d0", + "ede7a9072a0086b9a1e55d900747cf76", + "19373168f1a4052a57c6b8146f", + "debbf044325384b90a0c442d95455fb9", + }, + { + "630ea13eb5f52378b976ba2662f824dc622920759a15d2e341c446b03ea7bd5c", + "0f9ebe47682f93d44c4db314", + "5c734964878a4250a3bf61fdd6", + "5ad8e9cffe622e9f35bdb185473868e5", + "67cb6d943340d002d3323fcc4e", + "f5dc0f88f236560c4e2a6d6c15d3c0de", + }, + { + "c64f8a3ac230dce61b53d7b584f2309384274d4b32d404bc0c491f129781e52d", + "7f4b3bcf763f9e2d08516a6d", + "fe581128ae9832d27ec58bd7ac", + "89ed6945547ee5998de1bb2d2f0bef1e", + "81d7a8fdaf42b5716b892199c9", + "8183aaff4c0973fe56c02c2e0c7e4457", + }, + { + "dd73670fb221f7ee185f5818065e22dda3780fc900fc02ef00232c661d7bffce", + "c33de65344cfbf228e1652bd", + "ada4d98147b30e5a901229952a", + "e1a5e52427f1c5b887575a6f2c445429", + "6ed4e4bd1f953d47c5288c48f4", + "404e3a9b9f5ddab9ee169a7c7c2cf7af", + }, + { + "f6c5d9562b7dbdd0bf628ddc9d660c27841b06a638f56601f408f23aa2f66f4e", + "67280bcb945ba6eda1c6c80a", + "f4caead242d180fbd2e6d32d0c", + "5b33716567b6c67b78ea5cd9349bcaaf", + "fdfa39517d89ea47e6ccb0f831", + "91f9b540ca90e310a1f5c12c03d8c25e", + }, + { + "ce1d242f13de7638b870e0aa85843ea43a9255a4fa4d32057347f38e0267daeb", + "86562be4621b4d5eb1983075", + "d20e59a8ef1a7de9096c3e6746", + "d48a9490a0b7deb023460608b7db79ce", + "35ce69fb15d01159c52266537c", + "dc48f7b8d3feeeb26fcf63c0d2a889ec", + }, + { + "512753cea7c8a6165f2ebbd3768cc7b951029bd527b126233cf0841aff7568c7", + "b79221802d8d97978041fe84", + "c63d6c1006b615275c085730b1", + "22fa0605b955a33468f3e60160b907f2", + "bdb5d7f24732bdba1d2a429108", + "fca923d2941a6fd9d596b86c3afb0ad9", + }, + { + "e7b18429e3edded2d992ca27afab99e438b8aff25fc8460201fabe08e7d48ec2", + "9db9b7320aaac68538e37bf7", + "c4713bc67a59928eee50039901", + "283e12a26e1646087b5b9d8c123dde1f", + "a5932f92bda107d28f2a8aaa74", + "9a1357fd8ed21fe14d1ca2e597c3ef17", + }, + { + "69b458f2644af9020463b40ee503cdf083d693815e2659051ae0d039e606a970", + "8d1da8ab5f91ccd09205944b", + "f3e0e09224256bf21a83a5de8d", + "036ad5e5494ef817a8af2f5828784a4bfedd1653", + "c0a62d77e6031bfdc6b13ae217", + "a794a9aaee48cd92e47761bf1baff0af", + }, + { + "97431e565e8370a4879de962746a2fd67eca868b1c8e51eece2c1f94f74af407", + "17fb63066e2726d282ecc610", + "e21629cc973fbe40176e621d9d", + "78e7374da7c77be5938de8dd76cf0308618306a9", + "80dbd469de480389ba6c2fca52", + "4e284abb8b4f9f13c7497ae56df05fa5", + }, + { + "2b14ad68f442f7f92a72c7ba909bcf995c827b439d39a02f77c9bf8f84ab04dc", + "4c847ea59f83d82b0ac0bc37", + "b3c4b26ebbfc717f51e874587d", + "8eb650f662be23191e88f1cd0422e57453090e21", + "3e288478688e60178920090814", + "a928dc026986823062f37ec825c67b95", + }, + { + "11f41bf7d4b9ac7b0035ce54481ed1502ff05cfae02ffba9e502f61bfe785351", + "06f5cf8c12c236e094c32014", + "bee374a32293cad5e1b28419b3", + "d15cbde6290b7723625c99ffa82a9c4c03ed214d", + "3f8122deb6dbe0ff596441203d", + "60ef7f3723710b9ab744f8eea00267f7", + }, + { + "18ca572da055a2ebb479be6d6d7164e78f592b159cdea76e9fe208062d7b3fa1", + "1b041e534ae20748262f3929", + "cda2fa0015361ecf684c6ba7d1", + "e8a925d7ce18dd456b071cb4c46655940efbe991", + "740d8d578e2e7522c31019f471", + "f2eeb5af1bfedd10570a137fe2566c3f", + }, + { + "0de2ac5bfec9e8a859c3b6b86dde0537029cdca2d0844bf3e1d98f370e199be1", + "1778e308e0221288f1eb4c5a", + "575d93a3416763cbd371b5a671", + "1362264f5655f71986aa788efd48f6fc13bb6ab4", + "8f8df7ca83bf876b63c78e2c9a", + "16c74e315aab97efafbe95c9dcaa2d0c", + }, + { + "b381535a085bc4808fa7a139c7204e8a87c7145dfc8f3900df1fa9a9844fab35", + "21ddc54d3c633f4a344a0e42", + "e4d958cee583010bbfd3a53021", + "7ac3ba600e08363ddb57c45a8670bb4abb869db0", + "c42c81a312759cdb032aafe852", + "0c472591db3df8a7c67164591542dcc9", + }, + { + "29f21e5029ea4964b96dc6f4c34b2df4cce02f2fcf0f168ffd470e7858e0a0ad", + "63a1c1ccc328280a90ff96fe", + "dc12113764c13c21432ca1ba33", + "454f447433f0948581956c4be1b19d932e89b492", + "1cb45aac5def93daef806b781e", + "f4b0723c89607b66c392049ba042db63", + }, + { + "2733d3aa52a9d70a9fbd6ce2364bb5f9004902aa5eeb17446e08f2bdcc41db15", + "196c4addb84a58beb3674a7a", + "cbc50cafda2544bcd291e8a025", + "c9826fe31f29b55b9d0f9da9795869a1a98befe5", + "7a89cc58ccb97ad3e54ca4a9c8", + "3990d9aba210182996fdbd91c2ae4801", + }, + { + "0c4b9005b407415c19672bcd0ebe169f66fe404f22529baf55568e0901e94922", + "e51381e959a1f5688c938576", + "c6179bd3451d9299b727e8bd0a", + "0b512faeb4da740dcc1e30d3c7ea61035e8570b7", + "4d3fe086c990f16020b4c5eed6", + "9ff2297845814719f851ab0943117efb", + }, + { + "fee442ba37c351ec094a48794216a51d208c6a5ba0e5bdb8f3c0f0dfc1e4ed63", + "a666f2f0d42214dbaa6a2658", + "a2cf3ea0e43e435261cb663a3b", + "7198c12810345403862c5374092cc79b669baecc", + "713d4050f8c7fd63c0c1bf2ad9", + "250a35e2b45ba6b0fe24512f8213d8cb", + }, + { + "77f754d0cf7dbdaf75cfe965ab131e8cd39087ee6d986dec4ad2ff08ebd7f14b", + "e28a14f3107ca190d824ed5f", + "54a97a74889e55d8043451c796", + "1decf0cbc50a9da6dad4a785a941e4b95ce5aaa8", + "eedbf8dd81eb19184589dcb157", + "7749edd752fab7e50dbc3b0b47678bf6", + }, + { + "0523f232001e68bd65a79837bbaf70ec2e20851301d8e12fddb5926acb2100cb", + "2bb8d5cb3ceb15107582e1fa", + "6b4cdc9f9c5082d86a1d2e68fe", + "1f55bba71cb63df431ef8832c77499ee3c502067", + "079fe90ef517ed2f614a3cd8ce", + "539c30590a2527f1d52dfae92920794c", + }, + { + "54c56ee869ebb112a408717eb40af6937fe51eb061b42277a10537e7db346b6a", + "5bfb63e2f3e5b2e1b4343480", + "75f9496b8d0ca96ed3af02dcab", + "740ab07b9c5de2afa37f0788ae5230535c18203d", + "827902e58c4c8b7af976f61842", + "036ee6473c2138f2a2c2841438cb0edc", + }, + { + "d968ffdbed6ffc259b4310e2e97e42d877ef5d86d2169928c51031983779a485", + "633d0d8d3613c83b40df99dd", + "08cfc65fea9b07f0c01d29dfdf", + "9aadc8d8975ec0a3f5c960ce72aaec8ef0b42034", + "7b450f162bdedc301b96a3ac36", + "970d97344b1451f3f969aeb972d352e6", + }, + { + "5f671466378f470ba5f5160e2209f3d95a48b7e560625d5a08654414de23aee2", + "6b3c08a663d04132243dd96c", + "c428592d9f8a7f107ec4d0df05", + "12965559c31d538f937bda6eee9c93b0387318dc5d9496fb1c3a0b9b978dbfebff2a5823974ee9d679834dbe59f7ec51", + "1d8d7fe4357080c817303ce19c", + "e88d6b566fdc7b4fd62106bd2eb806ec", + }, + { + "fbcc2e7faa4295080e40b141bef829ba9d34e0691231ad6c62b5109009d74b5e", + "7f35d9ec651c5b0966573e2f", + "cdd251d449551fec080425d565", + "6330d16002a8fd51762043f2df06ecc9c535c96ebe33526d8faf767c2c2af3cd01f4e02fa102f15ce0236d9c9cef26de", + "514c5523024dd4c7d59bd73b15", + "d3a399843e5776aa348e3e5e56482fff", + }, + { + "04ef660ec041f5c0c24209f959ccf1a2a7cdb0dba22b134ea9f75e6f1efdae4a", + "0f5f6fbca29358217c8a6b67", + "0835b312191f30f931e65aa05f", + "505e205d13ec945391c7d6516af86255e82f38433f40404d4f1e42d23b33eb9e6dea5820dad60622d3a825fc8f01a5d2", + "5ddc0f5963f0290c1a0fb65be7", + "106d1f8d26abe4b4b1e590cd5d85e737", + }, + { + "42d3ff74284395fb9db9b8c7a444fa400f7fc6b985a7fec2478667c7f17cf3ba", + "89230fbed59d1226a093ad28", + "d8339e3618ba57a243a27c85d6", + "60342f97310446266b2e47b18e008979d07fc181151ac0939b495e7f31de1d0e74042532840ab91686efd7a402d27a94", + "9bb6fa36fa167016109d521ac0", + "600909ef32ca62951ecbdc811caa7778", + }, + { + "e115c6468606a5f9b8e9a7c220d7d7684d686c9210a669770b6e4bf24447cd17", + "029c7c9ee2d3ab26843e8b41", + "7abf84842f9867cfc5eabc7032", + "1befd9f97f99fc096deafde5e158ac86716c0ba32454988fe48ba4737684361849a221c03fc0948cb25b5f29d6a0cb2a", + "851c7047fb09646fbddb824531", + "d0ac4110c8d768f0a804ecda387cfa30", + }, + { + "56552f0cef34673a4c958ff55ad0b32c6ababa06cb3ae90178ab1c9a1f29c0e5", + "b34d24935407e8592247ffff", + "dbd6cc358b28ab66a69f5238d4", + "b199437da189486a8fd1c2fa1fe3ebbb116f0ef41415bb7c8065272fb0b2fe8edca9cd0d4255d467e77f2834be557474", + "76dc8d035e5ca4001e4e3fcb18", + "49c01f735da1131cd42b01b746fd38de", + }, + { + "d4f405ba556e6fe74b7e6dbdd7a8eae36376d1ca7a98d567d108729aeae5c326", + "df6637c98a6592843e0b81ef", + "abe87641e9a5169f90179d3099", + "a5328cbabdfe6c3c1d4f5152189072dade71e2bacd857d3ce37ee9e3161eb0f20de5a29b7999fd9c7c60cdc03751bd1b", + "06f9cf9677745e78c6c02bf06b", + "5a3a76da0703c24a9588afb2ac1a9e13", + }, + { + "4f667f65ea4569264456e25de498579036d6a604c18baf770bb626d8a1c68e4f", + "43e27d275abefdd45137c8ff", + "eaa2498ce27e5658489381b6ec", + "264b807b4631d7c87ee9f1507082f5af9218f531b4630141f3c94939aa7cf81c71ea540783995560bf7e6e02d196227f", + "bac018bf2e7090e7f217ab3365", + "13e5a16a9ce7a88cda640de2c4fdc07e", + }, + { + "f5624a166759ef0b8168af6565649f7797fa92476e008c407458101e75831312", + "521ca79ffc8930349abfc052", + "1fab3def2ea13e815f8746093b", + "6e2771ecd637361cb6b947148910f7d9206d6af176c510bb5dd5bc9b97ac015fb05537affbc1756625715374172fb456", + "ca72ff15a7eb62a2839bcf0c43", + "475fff6d9e2382583c9614020844b92a", + }, + { + "ac1383a3c783d3d0667e944cbe1a6159647b96afa922557eb1cb6407546b98ca", + "70366112dbe1bd905b900e3a", + "b8dd871f9d866867efbe551c3b", + "b7c1865927737bee802415277cf1a25b7380774a9d27b6a3253f077d36e9c4142df2bbbf3c03414ac09161626ce9367c", + "ba181874380841791f64881534", + "c5641edf42c446873372bbbde1146642", + }, + { + "f37499d9b6ad2e7618e30a23082673008f3ae1938b9397c02a4da2453fb7e403", + "18e112ea6a998d6f9705f7e0", + "31560b2114a248ffe0696fa130", + "736f1a71fb259f46c6519bb87451f238f47d80c74a016604499b02568f1c7bedf70f9597d7b62c1698c4f2631f4e9706", + "0163f558be0142ebabde29a7bc", + "45579ce07ee64cdac3a7a42109ff44e7", + }, + { + "50b7f5118ef7ee22b107d93ceab9881ef9658931e80385d1ae92501b95e47d62", + "d5113665039169978b7dc4db", + "9ba4cd5e600277f4c786ce827e", + "68ff6c63e94cb7dd2b8413662a56c88dc130b79b8b2e2388c1089b61fa51ea37819109b5ef64da1250f5d6b5d74cc392", + "67842199482b28be56f7570d11", + "79e03841843fe32337b7c7409a2153bc", + }, + { + "d396941c9c59e6a7bc7d71bd56daf6eabe4bfb943151cdb9895103384b8f38b4", + "f408f8c21f3825d7a87643ed", + "dc8ad6a50812b25f1b0af70bee", + "947bd9a904e03fdd2c91d038d26d48ac6e32afcad908eacd42a25f6240964656d5a493242d3f8a19119a4cd9957d9c42", + "57e6d821079bb8a79027f30e25", + "de8c26d5a3da6be24b3f6ea1e2a0f0c6", + }, + { + "eca22b3a29761fd40031b5c27d60adbcfac3a8e87feb9380c429cfbcda27bd06", + "4e6fe3d1f989d2efb8293168", + "44d6a6af7d90be17aac02049a4", + "29beb1f0bb6b568268b9c7383991a09fd03da7e1639488169e4f58ec6451cad6d4c62086eee59df64e52a36527733d8c", + "9aaa295bb3db7f6335a4c8cf2f", + "55f7577163a130c0dbcde243ef216885", + }, + { + "fa3ce8b099f3a392624bc433b5265235b65c0952cfc54817be2a8003d057903c", + "3168b4e50efe96b3d3aed600", + "84ed3ccd428d3783ecea180b3b", + "d451fa64d73b7d7eee8f8143c40bab8e3f7a58ee018acda23224974f64ac7e1e389f5058ec08664bf56492b932d15f42", + "ee2bd527568a4e7537c8f939b6", + "f4615f7dfdffec8a2d52c992456210ad", + }, + { + "ff9506b4d46ba54128876fadfcc673a4c927c618ea7d95cfcaa508cbc8f7fc66", + "3742ad2208a0484345eee1be", + "7fd0d6cadc92cad27bb2d7d8c8", + "f1360a27fdc244be8739d85af6491c762a693aafe668c449515fdeeedb6a90aeee3891bbc8b69adc6a6426cb12fcdebc32c9f58c5259d128b91efa28620a3a9a0168b0ff5e76951cb41647ba4aa1f87fac0d97ac580e42cffc7e", + "bdb8346b28eb4d7226493611a6", + "7484d827b767647f44c7f94a39f8175c", + }, + { + "b65b7e27d552395f5f444f031d5118fb4fb226deb0ac4e82784b901accd43c51", + "2493026855dd1c1da3af7b7e", + "8adb36d2c2358e505b5d214ad0", + "b78e31b1793c2b758494e9c8ae7d3cee6e3697d40ffba04d3c6cbe25e12eeea365d5a2e7b46c4245771b7b2eb2062a640e6090d9f81caf63207865bb4f2c4cf6af81898560e3aeaa521dcd2c336e0ec57faffef58683a72710b9", + "e9f19548d66ef3c16b711b89e2", + "e7efc91bbf2026c3519010d65628e85f", + }, + { + "8e4f8859bc838f6a2e7deb1849c27b78878285e00caad67507d5e79105669674", + "e71d0ebb691a4c31fdd9879c", + "bd1713d8d276df4367bf3cbb81", + "47ca6cef3ca77997ef1b04e3721469be440ad6812aa3674ae92ca016b391d202e29932edfa83029eccae90bd8dbe4b434e7304b28fe249b380b2c3c49324fd5b3e469e3e135abc1c9fd77828b409c7482e6a63461c0597b14e5c", + "eecbfb74e314628b0e3f827881", + "c9ea890294d7e10f38b88e7c7493c5f8", + }, + { + "2530cdcb2a789000822588a31bdc87c09234838da2d6ae1259c7049186525f11", + "0c509faa257dbb0e743a53ac", + "a8edc524930ce4c20897c66f75", + "92a92cb8c1984ede806028cc45ac95574167ee83f03a707cc4b0fb8ad70907e0016e38b650f4a75bc83a625e3c670701d43bfb0326d1c4fe7c68410733c0c874c920389d164bf67a9032e2e837f5e9e324b97932d1f917ba7dca", + "1f658c7a1f41152b22999ed1b7", + "cf3e4fef775d9c6ff3695be2602a90d8", + }, + { + "54c31fb2fb4aab6a82ce188e6afa71a3354811099d1203fe1f991746f7342f90", + "f0fe974bdbe1694dc3b06cc6", + "fbb7b3730f0cd7b1052a5298ee", + "2879e05e0f8dd4402425eabb0dc184dcd07d46d54d775d7c2b76b0f76b3eed5f7ca93c6ae71bf509c270490269ea869ed6603fdf7113aa625648ab8ed88210f8b30ec9c94bca5757ca3d77491f64109101165636b068e3095cb4", + "3a5a2a8aa93c462cfb80f1f728", + "59ef9d54ee01fb6cd54bd0e08f74096f", + }, + { + "8084061d0f7858a65c3a3557215ed46f1590278ca97a45dcb095d2a0979f2e3f", + "6973898b1a8f72856415675b", + "200d0445cb09eb52f54d2f74c6", + "8b543e294546848c3308ccea302f0238b7dffc1706d03657c190ea745cc75bcd5a437993e787828ea7fe42fea1d5c6f7229a72ea65f0d0c190989a590ab49c54726633282c689eef8cf852af263b5edf63e449fd5440730003ca", + "ec242c358193ca6187c89aa7a5", + "967428ac6956525ba81d5901ed259407", + }, + { + "2aad7db82df4a0d2ec85218da9d61ade98f65feeb8532d8eb728ef8aac220da6", + "029ac2e9f5dc3d76b0d1f9df", + "ba363912f6207c54aecd26b627", + "d6f4b6232d17b1bc307912a15f39ccd185a465ee860279e98eb9551498d7b078271ebabdda7211e6b4ab187043171bc5e4bf9ffcf89a778430e735df29410a45ca354b0003433c6bc8593ee82e7c096a32eac76d11daa7d64150", + "bfcad32611da275a0f0821517c", + "9ea37bdcaafad69caf06d67fb18dd001", + }, + { + "f70bb950ab56f12f1efc2376d32a59d16ef3ef5969e0106ab40cc314c9b0c7e8", + "3b3b29ba422c2bacafeeb8b3", + "029929277043dc0379f152a484", + "464ac0c84b9ff17a0e7c39a65f89682a89b8787553a6275f0d55effaabef2114072c739f9831a5d5a5133ae4de14eb51346b318b255a1bff57e50c433e1e69a00fe1a8b6f6b621d515d670d89e148f6b65d6eb4c54878cb819ce", + "c0b97d6d1a95d708d6dc7d2b95", + "322eb4395bf4d4dd070b8f9f6195f8ee", + }, + { + "f4950f01cb11fdd9afb297f7aa852facfac354ff96557befa5f657678de6cefb", + "aba7d864f29cbc449cd93e33", + "e6daf59ef54ac7405984fc4c4e", + "852f624cea7a8c20e189e0c79f578c0d770c4bf7c4e691649eba992f6de89d7bf2078aff94803a3dc62628e02a80a01957722e2a931fc56283d84ab68ce11ae867835c2d9700df130048ea8eaaca41f1a9059be2acaea6e0f7f2", + "d01d36ff8009b4082279abb906", + "d9a36c8008493bd95c09049299cbd075", + }, + { + "714261ef4f02fb4efb0e6b5aed96d7b3ceac6551a57cf679da179c01aac5ee0e", + "3b7d15c7fd877461a789255a", + "815de8b0382fe60cb0d3782ee9", + "7621e58152336ee415f037f2e11581fe4da545c18d6e80177d5ab5dda89a25e8057d6fccec3757759a6e86e631080c0b17baa8be0b8fe579d3bfa97937ee242b6faacfc09425853df4dc26bc263ed1083a73ffc978c9265f8069", + "29c566ea47752a31a380fd0e7c", + "b279340a384dbbae721c54e9183b3966", + }, + { + "53459ba5a2e49d1a7c2fb6ad9e6961b4dbe5158cb9266eff425d6dcccaaf8073", + "3c97dc635a75fbe2c33c9a41", + "03fbfe5842ed781990ca8be728", + "7fe308afe58a927680bee3368301f4dc7c47811fc09f1b9922a092a497b9c6b67c857fdcc32da1011acb110b3c1475bef303f1a609479485cc400ee8f38381c45d078708ad49f226f95dd9c81478d1ee2b53c3b906d96f8ddd76", + "5865e5a1ec711732a4ee871bff", + "856a653ec214178096bed423e30a36e9", + }, + { + "f0501583c226d2519ed23fcc6f2cffd2f013eb91aa07b3a5a2073d6e2bd10cef", + "29a922ad9bdeddc2e298b99f", + "035eb6922345c02a81435d9e77", + "d84f54bac09ea92afe0a7335cb0bb5f68425490fd2fb6c3b99218f49856ed427ec902e510b899d54951fe84cdbfd112608d1e999f64ecc9cd4be3a0114c1c34875dbf35a1b0be421659f99d69b32e968cebfca6f95837e3edeb4", + "095971f99af467805a62bfb882", + "d5ff2b7beac260e517ea3eca13ff1e77", + }, + { + "78e6789b596c71cb3becc833cf823d2ebb18ca2e26c27e26a55ef95df7353971", + "65da9c7a9f17b11246bcf8db", + "003e82a147df3c953400f87ab5", + "d49aee7ffd31e7c8d831d97ae894a00473adbc5071f6099d567caaef85c295d5143a1316ff82753cc35d3efc60f7e5101ddd811336b404d598f6c439cce6b47fcbebb15d1c342e4151b355025a03b4397260b4a7e6444fa57b5b", + "abcceced40209fc30a5590fee8", + "0a203973b81375949ebd932597efd495", + }, + { + "816b3e6ca31d59688c20bcd1fa4285197735d8734289ca19a4730e56f1631ccf", + "4c191ac994f86985c180ccd4", + "b2060dd86bc307133b7d365830", + "b3dcd643c68ccce186570c63288c8722b8a13dfaf9e71f44f1eeb454a44dddf5f955540cd46c9f3b6f820588f71936d7a8c54c7b7bc43f58bb48e6416149feae7a3f8d8198a970811627489266a871e8cb87878cdb3a48be65f5", + "53e65880ad0012a75f1188996f", + "9ca8a71a45eb4402a6b03106bae330d1", + }, + { + "a07ba57478061bd7abddd762971cf2e47141891f76c3d1c150b53eee5704557d", + "5adfb85b2d9e239c5146501d", + "67c8824c1837cfdec6edcd719c", + "937b3ed73e67ca0b02f9eb736a668362d4d0447c15f6083099a7f90c7c49318dd72f6baa74da22ff53b56c24fb9a1b1d6c4e29f4ac4d917220ebe3c8d760999da7be9e1e8f6a171133640c9196f9ee3cdb76a5a342a95a05c8c4", + "1eb85c6682850e849eb37927e5", + "8079f705cf551a5484132cd0f0c5297c", + }, + { + "268ed1b5d7c9c7304f9cae5fc437b4cd3aebe2ec65f0d85c3918d3d3b5bba89b", + "9ed9d8180564e0e945f5e5d4", + "fe29a40d8ebf57262bdb87191d01843f4ca4b2de97d88273154a0b7d9e2fdb80", + "", + "791a4a026f16f3a5ea06274bf02baab469860abde5e645f3dd473a5acddeecfc", + "05b2b74db0662550435ef1900e136b15", + }, + { + "c772a8d5e9f3384f16be2c34bf9afd9ebf86b69e6f610cd195a9db169e9be17e", + "9b8e079f9971d7352e6810a3", + "7f13fcaf0db79d792823a9271b1213a98d116eff7e8e3c86ddeb6a0a03f13afa", + "", + "d29e2bf3518668a14f17a3e4e76e1b43685734b801118d33a23238f34d18aa40", + "8e02b0b7d172cf5e2578f5b30fac2e7a", + }, + { + "d5924b31676e2354fe7dafffaf529749598ea1bf5e4c44f5b60240e09d8036aa", + "5d847784f0bcd79cb84fcf1d", + "6fd80c8f0d4de081a93c16b84dec697a1e4f9d80a6af497c561572645eac0d63", + "", + "282cc9d2308a443019cfdc4d79854accc7731ee36902bafe3ffaca6484327b82", + "4dc5e0f2ab91bdfd31f2bdcf06af9667", + }, + { + "b328c6d7946221a08c4f0509b52992a139890cdd8eae1956851f110c49602cb5", + "1a433c33ca12ce26cf3dffff", + "217bdc314a4d335c72b5267b424fc8e31f4bb118e6cfaeacf5548f4ba8f51980", + "", + "a322944e07bf84ab424ffa75fd0309e8691c9036b08f344ba76ce0774f43b351", + "14dd6b1c2b224533ccc9fee8d2881358", + }, + { + "c2080965d21d229c0d0d6c56cbce83880120c21a48172a64560b90dc4ce1ffbe", + "928d6c0195f5f0974f38730b", + "864397271e1b242aa1dff38e78aa89353e1554ba907318a0aaad44f26fcd567d", + "", + "7de4f941f44bd0f268b2a47b9c4927cc10537bbed739d52ab099fde4033041d1", + "b51a59931817257619e7be1091128c49", + }, + { + "dd6b7e2584edf1f1e6c2c0dd1f72161a92d2cba99856554f820de1256d48c099", + "fe9d553c75067e8dbae1ab67", + "f9f86f7762859f11d6e7ef56178657ddcded532843446f86a23eac35aa2dd3c0", + "", + "f7aaa1711c8092783b05b4e5e6c9c6944e991bd59c94b9d0356df00a66e2db5b", + "c61edd176c8322a01d8c5f3df09252e9", + }, + { + "37f39137416bafde6f75022a7a527cc593b6000a83ff51ec04871a0ff5360e4e", + "a291484c3de8bec6b47f525f", + "fafd94cede8b5a0730394bec68a8e77dba288d6ccaa8e1563a81d6e7ccc7fc97", + "", + "44dc868006b21d49284016565ffb3979cc4271d967628bf7cdaf86db888e92e5", + "01a2b578aa2f41ec6379a44a31cc019c", + }, + { + "a2ef619054164073c06a191b6431c4c0bc2690508dcb6e88a8396a1391291483", + "16c6d20224b556a8ad7e6007", + "949a9f85966f4a317cf592e70c5fb59c4cacbd08140c8169ba10b2e8791ae57b", + "", + "b5054a392e5f0672e7922ac243b93b432e8c58274ff4a6d3aa8cb654e494e2f2", + "cf2bbdb740369c140e93e251e6f5c875", + }, + { + "76f386bc8b93831903901b5eda1f7795af8adcecffa8aef004b754a353c62d8e", + "96618b357c41f41a2c48343b", + "36108edad5de3bfb0258df7709fbbb1a157c36321f8de72eb8320e9aa1794933", + "", + "b2093a4fc8ff0daefc1c786b6b04324a80d77941a88e0a7a6ef0a62beb8ed283", + "e55ea0456af9cdff2cad4eebbf00da1b", + }, + { + "6fb2d130bbad1924cab37d071553b12169e978a805bf74cb4c23d5ccd393d7bb", + "76826741225a391fdce4d3b6", + "c49b80080e2efeb5724b9e5b53ba0c302e97bd16f1a6bbec01e1ca6c35a42a3c", + "", + "62fbe5466a7ff83ff719f4927e00e9319e1bb7e835c5d6b4e9d4bc5a8d6e2beb", + "df72da7a66cb5257836f3c19ecadcd55", + }, + { + "402e8113970257d9437807620098370243536a105cca4fbc81a1ff2d48874f48", + "c924c19c4d14905a2bdf63bf", + "917b9585f65e59bf4d242bb0802966045dd29fbc66911277baecdfcc818c3c35", + "", + "5b6594edcddbb338f4e813687f4f23a75a64c21e3cf5d2e7c9af0f7e3ee3e616", + "f1cccd93a4411247c8b6830addd72c6f", + }, + { + "2aac499cb0eb72b4598acff4330df6cd764978997d5ace51da88e0c18671bde9", + "fd16cdc39d7f0b92e1f95c97", + "e7b75bfa35c9a004d0b68265623a9b06b6d4493ea0ad4f6c777ba5add8c7bbbb", + "", + "c3d0a0f7ce9720c95aac86151aad634884ddfa62df58f18394537f6504d9a8aa", + "76749a1ec70236b267fc340d5fbb6da3", + }, + { + "a2a502d6bb19089351e228d5cbff203e54fc31f2772253df08557875d964c231", + "0ebb5af4a462a1e6ded7164a", + "bbecc89450c07b8de631155e5d7cc7a9d26376bb57d7458d49b4c36e140490f3", + "", + "fd09c950890441fcaaa8809a8998079abb88741c6672abae12383ffd724f8299", + "22fac246058bf142c5f26812a635b480", + }, + { + "ce2d289e20c76f75c135c8118d5cbf5f2828026f0b639588a3eb4ad752cea548", + "bb08526dd8bd1c3bb58d0999", + "56f5db1e796a0c4633a8d570182c39e3c8451e7ba485b98d38a2c926a1b92a46", + "", + "a41005df18734d4f3f99f19ef8fc43b16ef431207cb0466341bf164b58e23533", + "a45c2a1ef6aec75cc22d71807dab3c27", + }, + { + "66e418d0ec97b420b1b5365d1b6d5cd7c5ac1a5653739120d4aec3c94c93c287", + "989f94480266e3652488184e", + "e5052b19d7f827fd60f45c8925809fd2217ec4d16aa89bbf95c86a1c1e42bd36", + "", + "f341630574ee92942cf4c5ecd3721ae74b32c557379dfe8351bd1c6661a240da", + "e85fb655ef432e19580e0426dd405a3e", + }, + { + "37ccdba1d929d6436c16bba5b5ff34deec88ed7df3d15d0f4ddf80c0c731ee1f", + "5c1b21c8998ed6299006d3f9", + "ad4260e3cdc76bcc10c7b2c06b80b3be948258e5ef20c508a81f51e96a518388", + "22ed235946235a85a45bc5fad7140bfa", + "3b335f8b08d33ccdcad228a74700f1007542a4d1e7fc1ebe3f447fe71af29816", + "1fbf49cc46f458bf6e88f6370975e6d4", + }, + { + "2c11470e6f136bec73351619288f819fb2bbba451857aadfb78384074612778a", + "4e6cc2bcc15a46d51e88958d", + "3b3186a02475f536d80d8bd326ecc8b33dd04f66f8ba1d20917952410b05c2ed", + "05d29369922fdac1a7b37f07953fe175", + "6380945a08977e87b294b9e412a26aebeeb8960c512439bac36636763cd91c0c", + "1029a3c4be1d90123c1b404513efde53", + }, + { + "df25ea377c784d743846555a10cfaa044936535649e94da21811bad9cea957b5", + "35f5f8e950c1f57ad3dfb1fa", + "98941a807ac8f16eef0b3d3c7bbdfd55d01736c5b3360d92b4358a5a8919380b", + "28eb4677110ccb6edc8d2013dc8f46ec", + "24a07532e981aaf3106eab8dfbb2d2078342e2eaee027e148f06aca68f6a1c50", + "131373ed4a0e3f584ae978d42daa6f3a", + }, + { + "106168ea651f22c54196a06f1a10bcf4e620d93e4dc0824d798f44f9219c6177", + "4064dcbd631cf20b05ae22de", + "b0d3da2b96b8889c92e445abbea4c6d0d5d44d7fbcc7dade4c92f6bcddbf06e1", + "a36e2fb9cd96a8ca9ae2b193aa498efd", + "f55a6d8a6965ea451637bec7548cfb1ffe59fc0ce6ea6a937cb5dd32b3d45d5f", + "8d1bf2715041f817f11631fc9910c629", + }, + { + "272d1649a3dd804de0962d3e07064a7054c00a6234ab1b0cdcf685ab394837e5", + "955b5897f6b9806bbec5c33e", + "36e57c29c08c51ad7fa91c0416f976cfd011780eb44cc5abd34c7b431b093b8d", + "33e618ecbbe5eb0566df21c3c34b7e25", + "cd6aeb345081dc0bb2c8b4d19b280658fb87c0f2bd0f4c9da694dc1feeb32f4e", + "dd37eac6bd6a4d3618241738779735d7", + }, + { + "3dab6a51bb7af334dd4b79a7d139550c88f0778d43c21fc4ad33f983a13515cb", + "362eaa67cab3d1ed48e9f388", + "3eb7f5f0a4ca9aa7000497602c6124433a60a8fcd91b20175b4ee87e6b10a2d7", + "52852150786e6547a2618e15c77110b6", + "cc3316041b88733839249b756ffa00bbec6211942f604f26c4a35ed32e6eeaff", + "5936c5500240d50c0da0fcdc248f176e", + }, + { + "0ea606521b935d5b4b66df89fb372d35c4d6d2c03767367e38de0d4c27761d56", + "0d3168318a4f76392699640b", + "f450b36d6c49411897bce39001d73ff01b5e8566179e36dacac7064cab5c6270", + "3bd8849070cf034c4298f40f33b0b839", + "3b15fad18726c4eaa70502b3f3b32c5092d1d92835e6460665fc50dda953a191", + "11fd3fddf61e010c17fbedd4bd5fb012", + }, + { + "c8c4f9e0bd289ef1bd16104a8074fb073dd9035ab937ab076fb5801e2295aa2f", + "be699d9d98ec1f724da8bd0f", + "49fe9407a719d41e658587809cfed7a5b49941c2d6378f3c0afe612f54f058a1", + "a985c7489732038c3190cb52be23737c", + "17a9aaa6a3c68ba1f6cb26fdd6536c207e3c9ce58f43e4ecfd38d3387a798a0f", + "d832cb4814142562fedfe45b36126cb8", + }, + { + "52d0f20b0ca7a6f9e5c5b8549d5910f1b5b344fc6852392f983558e3c593be24", + "d5c618a940a5a5d9cc813f27", + "a9fed8a29355685321f978e59c40135309306cd41b25349fe671dc7990951c68", + "61823f7e39ed76143ca7249d149bdf57", + "509c540e558d0bf0a3b776cddfbfddc15486748a7f9952b17c1cbd6869c263f4", + "42e35ee3f7119f87fb52b5d75b8ab8ec", + }, + { + "5d291a8f1a6433a41076702d9d8a8c196e464550ed900ce8c2a36f4d10483954", + "c4ba743ee692e5d00b5ae2c6", + "605d519b26182458fea68dddd86033390fc545f843ae817850a2a4574add015d", + "878fa6720ab30e0287f6903acd2dca19", + "1c2f153f2374d3945cca9757dc18d9a15a93276526285a6e316ee32a72092c34", + "e7905e856c88c6ece4bb47781becf923", + }, + { + "09e2724d4017cd57e967000e4da2cd5c5c18ccfb06c33b7ce62a7641e4bb0b73", + "9ea18b420a10177289ab370b", + "6f5dfa86d5df4febd752265c56390049e7cda60c2644c84ab413932faad15b15", + "a8e77939423d5894d307fd60278d162a", + "35e37a9b913eb58b72262e92d7584d44bf9a8442f1b2f3da3a5d05ec6a2a31e2", + "1a95023b1a4a3e885520ec79e1a3aef9", + }, + { + "8544a9f4f6c0efdff3da90cfa3ee53fbe1f8de159d29537c803e1651da153718", + "be406029a1d0c25d09af94cf", + "7e88a65646ed138b7c749366d16e41dbafd9987ad2373bb9d0b6ce0c1a4d6661", + "599dbb73897d045a1bd87385e60323a2", + "38ffbf9ffff8d6a92090584e6dace1c6a47d3d5709a25e470557d5c8f5dd1851", + "d5b2e83c47df404de9a7cd95d3cbe7ab", + }, + { + "35b9d2a5db3b06e7720cec794dae615029a491c417f235498e0496cd8183d1bf", + "b382987916e19752dd9ecc0c", + "76b290496901c5824ad167433dbb6d6b5856d41913ee97ec81e70cf6a170e35c", + "e0aa3a1f1df601366c59a390f4f06c3b", + "78347400d6799e77e11e76c0ecfd311becf31f74f14b3a71e6d526ce57015c8b", + "bf8dec2feac7cfe9f330bdfc92737b33", + }, + { + "d707eab3c167b73efeb08c50e12b1569a275487ea136f52736c0f3ce66b69fa3", + "11116f34182e52428642e747", + "a0c4818362035b16b50de445d558ea5cf8844bf5c84b96232999a2279806cc45", + "ae9f90331800c358716c92667f79f748", + "91c77404b20028ef0fd4dd7f8b65b6594af94a1e7fc79cfbdb108265354fc71b", + "6c3410d4b915dbad745715202c04e9a4", + }, + { + "405d13ee48d3b9fc26bcfca776b2af6c745d8fc34171622f8c6c4be5a54b8b65", + "add1524abb1b846f0f6577da", + "e06475990d6e3990266de1bd025c3b1910c0736c81050885f2bfc13ec78e9d96", + "0b1c4c3ba877bca5846b2c1f2b0e2105", + "6399f7e6d6c680fc41bac8bee3836b9a4241403d5a19e4919f396ce37b238d38", + "e754f400d76c76e03c63ea88cf64ccba", + }, + { + "5853c020946b35f2c58ec427152b840420c40029636adcbb027471378cfdde0f", + "eec313dd07cc1b3e6b068a47", + "ce7458e56aef9061cb0c42ec2315565e6168f5a6249ffd31610b6d17ab64935e", + "1389b522c24a774181700553f0246bbabdd38d6f", + "eadc3b8766a77ded1a58cb727eca2a9790496c298654cda78febf0da16b6903b", + "3d49a5b32fde7eafcce90079217ffb57", + }, + { + "5019ac0617fea10517a2a2714e6cd369c681be340c2a24611306edcd9d5c3928", + "fd1fa6b5cab9aa8d56418abb", + "4349221f6647a906a47e64b5a7a1deb2f7caf5c3fef16f0b968d625bca363dca", + "953bcbd731a139c5de3a2b75e9ffa4f48018266a", + "dbce650508dab5f499767651ee734692f7b157341977692d2ca879799e8f54aa", + "20239e97e2db4985f07e271ba545bbbf", + }, + { + "c8cee90a8b9ad6094d469e5d1edc30d667608e89b26200cac77efd7e52af36fd", + "5a1aa9c8e635281ee1fb9df7", + "728d9221891bd75c8e60b7dd6f53edcfd1ab1cebc63a6ce54be220b5b362233b", + "0538b3b64da72aac591bc59991a140eff206b3f7", + "b753eb6b87f0c8778c3ea3a74fba3b31ced6d2da94d43d482ab0431806a80d75", + "b21d29cf6fd04571ffcaf317d384df11", + }, + { + "b4b77710f86ffd463fc14bb9eaa4424b2b3a581778e5511a094a08fb204cab59", + "3e4b12bf55633bf48d104620", + "6f44a8df11dce27df075ea10ddeb7566ca6c988a334cf56e8540f71166d7c0d1", + "3e3b4c9369266266098326217b5677a40297cb87", + "31f82f5cb1cd5c4b4819b61aa9377abebe8fca76978b1199178462c7c1c4e2b2", + "1b3a535768e8480d75ec91b2e7b55efd", + }, + { + "0a8fb75498a139223c763d52bbe3d42f813de370fa36b81edc4553d4219d2d5d", + "7d6cb675fded3efef908a11a", + "81b69ca354de3b04d76ee62334cb981e55f0210f1174d391655d0f6712921a0e", + "2314ad86b248f1ed2878e7c562b533bf2dda5a29", + "6a23d30737f4a72b1e07ba23d17fde43a4498e2e60d3e1b0c8e6ea26a2bb331a", + "7fcac442fb657910c62a74b1d0638902", + }, + { + "a84315058849690c2b88062aef81134d338526baa7090e865fcaad94bbf51ca5", + "a487cfa701447b495aab41e0", + "18074e14dc0a14d4439f1d710927ed8c200154c8492f77f10f653e0bf6070ca6", + "7c4416b0cf13ac76bec6687a6840dc703e91bb86", + "80f40b7e335d40fc5859e87f385e14798a253818e8ad73b1799c1419638246a4", + "b4c7c76d8863e784eb6029cd160ef6de", + }, + { + "82833bcaaec56f6abbb3378f7d65daf6e6f6f2a0d1e858c7219f53a7840f4e00", + "4bc9b028a00be8feb5232978", + "d9b2383123a27a93bce85add8392b938093b40e82f182e484bf4f84fa3bfb3f0", + "76fc8ed57154cd8a9b3d02c87061edd2a8157811", + "383efe971438cd2b2cbb399d74a3fb3eedd394f1862addc58e9fdd4c421402d2", + "fd803c4fa917f7ff649a6aac013a96b1", + }, + { + "ee4634c49c5672c660968a42862698f6c1b2c7b79efd1605c24af8ff9ff8366c", + "877912b2f35888d2810612cc", + "9512a5268a0cb3fbd916ddb820dce77f1e0dbb52c8ffc7a74be077119e9245e4", + "93bd669db4f1354ef6c8addb0cf729e46d5c3846", + "69af0ac954e0d69043851d89f1538ebcb42769857eba27dbe4ad4fd60fd75537", + "3ee443873e2f7f7ea601fe3d7e5211e2", + }, + { + "442f4bbc468433411e49486a15c5eed577f5007380ff126d9974f3bd3fe4e3c4", + "1e7133aaa8af826dc646ec62", + "7f8069e5c356ece135d98bb563c8b411ea90ea3b673dfd92e1ba9c459efae61f", + "577662f611446b5b31814930029edb949a30dcb9", + "b962952750eb2bce313e1a85a72e3c9cc2ea7e58c353ea37df2c9f0723995ca7", + "e633fe9f10cedf0f0d02aa2ddcf47d86", + }, + { + "3a29aec009f44fdd2b1bc07cb7836f29d8589774bd0d74089a68d9e67827d6d8", + "a42c5fb61573c72688ac31d8", + "d36eb81506c0a0e4ebcac9b4b1acebb38b94b8f2ce3d6f85a8f705fa40cb987a", + "2ee2582d544e1663f1d7a0b5033bcb0fce13b3e5", + "179ef449daaacb961f88c39b4457d6638f304762bd695924ca9ebd01a3e99b9f", + "1fee176c7a5d214748e1d47b77f4bcc8", + }, + { + "ed47660054294f3c913c97b869317cbddc395d757bef7d29b8ccbdd2c54e99d3", + "770a00642c67eff93c9f1f56", + "034193397cbd0eb414459273a88808db2d0711e46f80d7883212c443d9e31b54", + "06210fca2018d2357256c09197730e9777caea96", + "6a250ebd3390229d46b691142743dba1c432c0feaa0f0dd19d0ce4e6a8918d80", + "a5f6e975592b472907c34b93bfc69dde", + }, + { + "9539844493362dc3f913308f7e12a2a0e02afdbd8869877b30ce0397fb0349dc", + "eadda3132079195a54fde2c1", + "62349a0b1e40a9f31eadf27073682da15f0a05cf4566ee718b28325f7d8eaba0", + "0ae4a90cb292c4e519b525755af6c720b3145a1e", + "ad6c9521bf78d1d95673edd150f2b8dd28f10625d67fa25f1fb42d132ba7fcfa", + "916242a9cb80dffcb6d3ae05c278819a", + }, + { + "3b4eb08d27ae0b77605ae628a1b54a5402026550679fab0a20752bee510d3d92", + "28a20c40f49a00493da3488a", + "c8a47edcf84872f53f96ef41ce05ca37cbc3854b556d6e606f0a8a32d0861907", + "0591390e2d14ebe62aeb1741c26448ce55b28cab", + "a3e8cbf84df8529838f79315c7f1a0b7bb3ad4c4d036ec317b1810b274ee3080", + "0a8f66daeb7f0a88756909c4e93fcd36", + }, + { + "0cccea8f1f6ce141690e246cf4cb9f35b66baf6e6986b8e0b4cfdd13fcdbc8c3", + "929f07be5aa7bae7607bae3c", + "9fa5214c599523c695d37937b02f78837f6406960b2a03bf9a6db34bd35e3dc7", + "b851e610be70a994808b34ca73f45f1ea973de65", + "917ecc8b00b53f7fb0732d66848a106e91f60acf2dcf180832a74d5993c658da", + "2959e20746bbb6ab66dfd29b9477799a", + }, + { + "ecbfaef2345b34f31fbf6d68efb385e5833df8b6e6ae621ede02baf9735d2dba", + "50c3527b1a35ccb318b446de", + "634f6dd60783d1f952353fd1d359b9ee4f4afa53cc13e81c5adfe24b46baf08f", + "f8981548bde6ee6c1745f947de191bf29997fadf", + "705e5f67ab889ba238118e3fd9b90b68be801995ae307378d93b50977cf90588", + "12d14468ac18cc9936bd565f8ad42d0d", + }, + { + "dc776f0156c15d032623854b625c61868e5db84b7b6f9fbd3672f12f0025e0f6", + "67130951c4a57f6ae7f13241", + "9378a727a5119595ad631b12a5a6bc8a91756ef09c8d6eaa2b718fe86876da20", + "fd0920faeb7b212932280a009bac969145e5c316cf3922622c3705c3457c4e9f124b2076994323fbcfb523f8ed16d241", + "6d958c20870d401a3c1f7a0ac092c97774d451c09f7aae992a8841ff0ab9d60d", + "b876831b4ecd7242963b040aa45c4114", + }, + { + "07b3b8735d67a05632c557076ac41293f52540bac0521573e8c0414ec36f7220", + "0046420eee8d56de35e2f7d5", + "4835d489828325a0cb38a59fc29cfeedccae25f2e9c399281d9b7641fb609765", + "d51cedf9a30e476de37c90b2f60882193630c7497a921ab01590a26bce8cb247e3b5590e7b07b955956ca89c7a041988", + "46eb31cd98b6cc3ecafe1cd1fc2d45fa693667cbd3a7d2c5f8c10296827ea83c", + "36cd4e76dd0679887477bfb96cf1c5f6", + }, + { + "0219f14b9ca6506c1388177c4ae6ee64ad2ac0256ebbf8c219b40df6e8571d70", + "3420a87c4b9b23ba81eb221e", + "348f7a4ca944f252e4562c66dacf01fb10d70a3c8f5b280a2829567a2a94e47e", + "54dc2277b8d1aae660ffcc326e2c5d9e16b8ca17288601aacd02b3eea8bc5cc60718639aa189506b7b333b87da86e940", + "58c92119bfb6ad53e387cac6728ce73b82e18f6e5bfbfca5f5acc370cd8c76a4", + "e7f9e3e3dae6d0a3470d8f597291180c", + }, + { + "87440ee7f6febf3e14ef0a917a87c5d61260fefc979eeaeac0a64662c98cb4f7", + "7c48bc75e58f21cc9989d691", + "f8e40a6a985f424898a7996307a077c487406c5312eefe055ea5b17a4b22087b", + "e0c66e5db1c7665a015ba7e21e08ff3de5b4a5fcd5d35e41db7e97ccd0c3df657ae803c3529d375420ad75ac9621cea0", + "5a118fc3dbdaf6bc9490d372b7623af76da7841bf9820a9c6624a15eff6a69c2", + "0ddc2ae087d9b8ca2249ea5aa3dbd4c7", + }, + { + "b12425796f63bf5435740f9039fa66367fc7702d675c61b2dec4435feeea07f8", + "f26727053e6d67c2d2bf1e69", + "9df079d98a6e4dbe277a8545f4f6c19fe130f4a84bdd6b760a049fba21d4e99a", + "e50fca2e5a81ae56ca07f34c4b5da140d368cceab08494f5e28f746cbfefdc285b79b33cf4969fe618b77ab7baafe271", + "845f00202e2e894516d8f4a4021430e531967098c9a94024c7113c9a1b91c8cd", + "3566c75967ae00198e39ebe9f0ac697f", + }, + { + "674dfb625b8b0ce1dadbbbcbf7e151c5b2cecf0a1bc4e07f4734f3a6792350cd", + "99e7b76e6686449616ad36c7", + "0a744a72e536a0484db47091609228d803bcfa9a8daf579e3039e3645f7688e2", + "2ab1573e5a94ca2997590840bd9c62e6add55e4d3eac12c895d2ec637791caa41d46ed91e6064db627e1fbef71d31d01", + "e550ee77069709f5199be3c618f2a4178e4d719ab73df41cbfe32c52777138ff", + "134ac3fa8bd4af7ee836f4a3421d9e99", + }, + { + "10c1de5f741560dae5be23e15649f0114db52949560bb6cdf2d4883247392ee1", + "7cf73c1472cd60d8d35fde51", + "05becd366aebaa2e609f507dd2dd4433b2aba0634b0eb9a5bf7ded4cc8fbed72", + "d3fa8b6f607a20a18dd7eac85eabef69d4fb5a074d8e7d1bf15d07732ed80e020163b475f209c4b0cbfa00d65d1e82ef", + "280f0c306e1a3aab8ff9ab3e4a9adc2e9ae4e4e1a06f190d11b3b4dc4280e4f3", + "3bc8be845bf5ff844c07337c2cfd5f80", + }, + { + "e8d6ab5e514645dd7e051b028f5bfe624c72f44f30279577365aea65d4a8a819", + "30b0d654ee5b79c2cfb24100", + "19be7e0feedd402bf4b05995a38e5f423c033de016e3ae83ea8c3c1cba658e1e", + "082e534bf860d0061ec2dad34d6b0db8cba1c651f2c705356ff271e47365b0b18f8ddb3a3c2269b437fb0703c9ad367a", + "8573800c737d2480b2885ce714ac6a15f23287b1d12949a3d76effbe82b593bd", + "50110884292151f51213ccb2fe934d88", + }, + { + "2d1eaf5e62ca80fd1515a811c0e4c045aba8c769df03d57f7493eb623ed8b941", + "abf190b05df2e6556cb34b47", + "9c7cd522ed5c0af3e57da08d2653ef77eb973734f360572bbcb15a2a6cbd60b9", + "75ab9bd39c24e498a54d85a8b76a4126dc1879f2a30270a42609763e045a4021785b6134f283fd81c195c3188e78752d", + "5fdfdaccb105e5408c375af8ca63a67afaba7ccbcd591acca9a86d92f92fd0f7", + "49940b7610618b3a5cb3912339e06b3c", + }, + { + "b6020677e098c59e19eacf26732473d843aafd6bf999c707bb08ab896406918d", + "807167ef2b84b32d1df4a94c", + "3199d6b95d133ba5b7eadc420080a0b249c84f4960bd369d6bf9e313627cf670", + "06225d410ada3e04157da7e5481d7d9f2285845824aac0c0e033244ed4c1b19615354c224ba8b7093c5651d10ef952fe", + "4618adbfa5ea4ee260e310140b385232b7c3ad46887aa2107f7dafffd85cda22", + "2d76307bf55826dfeb58a171b6fa80e4", + }, + { + "f75456c4918d0bea72f546a9a1e2db0b6ab9bcd9782b5eb1c2700e729921d666", + "c75b83134e7b9188e5800ffe", + "f9a23abbd0f2b367ce16c2a0613cd293ac7e66cbe020eaeb5deb09d5031fd992", + "5ef46c9eb5865cab2c8a35f9c4c434614a6c9f1b5c479739f7434d3326cff1e70b0d2877c084a71c7a9d33d258d304bb", + "56e4efe6c0944153b65ed4909845219842b9b88f54d8d8394051132afb95d391", + "255e2c8c43f8979c440c3581bff6cf65", + }, + { + "9831c5c12e53e8a961642e93ddb2e13a38506acd0cf422e6ad9fbaeabce7b3f2", + "bff29de3d6869e5fa75b96f9", + "b1edbed58ed34e99f718db0608e54dd31883baec1c8a0799c4ff8a5dad468de4", + "67ebeecb74cc81fdfee8065f8b1c1f5012bf788953bec9525e896611b827084a8e6baa0ce40ee70bc699b152bc6ed903", + "13845db7e33bab1f5766a7fadfb942748e779753d97f143e645ccfcbd7c23b23", + "10dbe8a3e1901c8b88b0ab1441664d32", + }, + { + "a02c2d4a43f0f7f1db57c07f13f07f588edfe069a9d83c9b76e9511946c4fc48", + "84677438592dcaf683d08a67", + "ad5a884dad20ffa88794c4fca39f2ca01c6f67657ab38e5cf86ac5597318ef07", + "d5dea0cd6080af49a1c6b4d69ace674a622f84f9f190b2db8a22e084a66500b52ff20a8d04f62a7aeaedb67e2258598c", + "83da16ae07ee0e885484c1330a6255a6e7ac22915c63cbefaabc6f9f059dd69d", + "42c4a270705493d85ad7bbcfda86dffb", + }, + { + "feba412b641bc762bfa79ef17c3ea16e5630605470db096e36ffd33813641ace", + "e3633f21e7c63a459d5d1670", + "9326572bd33551322ca42fcfb7cef8be41d78725f392c34907ecd1fe5572bff1", + "b7ee0233863b0e185b2f46181eb5fc0718832e1e76e7d4115a4c1f7e998c41319ccef44f5db89e8c5f077bd553d7bf42", + "5019ea98cc9dc9368432c6d58f9e144f55446e763c0a8b4d8a6ce26f3dd95260", + "1010beb9cd6e9b611280a5395f08bca9", + }, + { + "21bd5691f7af1ce765f099e3c5c09786936982834efd81dd5527c7c322f90e83", + "36a59e523df04bc7feb74944", + "77e539dfdab4cfb9309a75c2ee9f9e9aa1b4651568b05390d73da19f12ccbe78", + "48aef5872f67f524b54598781c3b28f9cbcf353066c3670370fca44e132761203100b5e6c7352a930f7e9cbf28a8e1ce", + "c21483731f7fe1b8a17d6e133eda16db7d73ddd7e34b47eec2f99b3bbc9669aa", + "15f9265bc523298cefb20337f878b283", + }, + { + "26bf255bee60ef0f653769e7034db95b8c791752754e575c761059e9ee8dcf78", + "cecd97ab07ce57c1612744f5", + "96983917a036650763aca2b4e927d95ffc74339519ed40c4336dba91edfbf9ad", + "afebbe9f260f8c118e52b84d8880a34622675faef334cdb41be9385b7d059b79c0f8a432d25f8b71e781b177fce4d4c57ac5734543e85d7513f96382ff4b2d4b95b2f1fdbaf9e78bbd1db13a7dd26e8a4ac83a3e8ab42d1d545f", + "e34b1540a769f7913331d66796e00bdc3ee0f258cf244eb7663375cc5ad6c658", + "3841f02beb7a7fca7e578922d0a2f80c", + }, + { + "74ce3121c18bbff4756ad10d0f293bb1ea3f93490daad0249cd3b05e223c9747", + "81107afb4c264f65ae0002b1", + "7a133385ead593c3907806bec12240943f00a8c3c1b0ac73b8b81af2d3192c6f", + "f00847f848d758494afd90b6c49375e0e76e26dcba284e9a608eae33b87ad2deac28ccf40d2db154bbe10dc0fd69b09c9b8920f0f74ea62dd68df275074e288e76a290336b3bf6b485c0159525c362092408f51167c8e59e218f", + "64bd17f3e8f71a4844b970d4ebc119961812efb9015b818e8d88b906d5efbd76", + "46d0e42aa046237efee17eab6d9cfb75", + }, + { + "4c669a1969c97d56da30a46236c15407e06aada686205eed3bd7796b02c97a4b", + "0a07758d5ad44766e051da6c", + "cd59bb307be76f11304f69ac8b151e1628ac61dec81086e7f24fd5bd83df8856", + "0b8277114cbf7ee16c9bbda1ab40419a02e469ebb295883f0a833c3cb755ded44a3c410034a201f7d91b43519fbabb55b974834be5d5afc7aea7c84b44a14e8e16dd68a3e8cc79ad2bf76d0ceb33d58ddb6378b45681ceaa0f2f", + "bc62ce0b23cf4aa8e16b4450c8ab8c629a53949f01e68b875ecc5c45ff6d3ab0", + "5ffeda728914031006f271c3d9986f2d", + }, + { + "a23296632913051e438114deb782fb955b75acc35e86e7e9fdaf4e9025b87f12", + "ad50db40f80f15214e43ffd7", + "b71116cc27b5a5844d9b51a4a720cb3f06d55d6aaeaeaf921236424db8617204", + "a6f96f5a89bfd8c8f34cd07045270d80e58ea62f1f0b10f2506a954f272af0bc71df96ad3fa8eed52c45e0b868091dc4f75d9e0eaf15a0a858a71bf7036c5607110cbfe47ad9b6d02e942fcfae88d4c792a1f824e60e3cf98a37", + "8e9e4b0ac93ab8e73688d6b4723d8c5ef399ead72246c7aa7a0783a8bfe29936", + "b7dea91e4b357ce805edeea3f91392d2", + }, + { + "4036a07bdd4e10eb545f3d9124c9f766d2d0c8c59fc0d5835ac55dcfaebfc3a1", + "815828fbb964497cdadccaad", + "717f22faff8066182e46d32dbac7831ec24272871c45c7c12ca779f868e7739a", + "0bc0e3931388bcb091463bae2989a93bde103bc14fc5d39f9448ca90367e86336b188f73218b2b0ab72a9a564ad5ff32544c5afeacecadfa55d2fb66925a88299dbf58f425cf49e31f42ac4edace743fdf9680d20ec845afc278", + "e8c3b0342964c7a71f084d44ba2f93742bccd9821b30087d11b53bbe8b085808", + "86ddd9c469849cb6b100c339ca62717d", + }, + { + "714bc3ba3839ac6707863a40aa3db5a2eebcb38dc6ec6d22b083cef244fb09f7", + "2cfe1c51d894e5ef2f5a2c3c", + "0cc4a18bbfea87de0ac3446c777be38ca843d16f93be2c12c790fda4de94c9bf", + "84e3d46af2ecb717a39024d62bbc24d119f5aff57569dfef94e7db71ad5aff864abacdc5f8554e18ed5129cfb3366d349c52b3d1a111b867e8772140749e7f33e2e64259968486e32f047d21120da73c77757c4595ccac1b5713", + "0857c8fb93412fde69bad287b43deea36506d7ee061d6844d00a7e77418f702f", + "24a9e5290957074807d55ad705adaa89", + }, + { + "2f93b5a37be1a43853bf1fd578061d0744e6bd89337cde20177d1e95a2b642c4", + "52b6d91557ae15aa792ce4b7", + "0fcaa316a135d81052509dd85f688aed2e5fd4261e174f435cf1c4115aa6f354", + "992ba9efa287a5c3e5177bd4931af498982a1728b56b3d7c4b28476905e29f83326c4f3223a28844fc9b9d84d4f6cd859074aff647a35dde28e1ee889faab3bb9c09a4c3fbf2a16460d48a40dc53378d4673f4325e6aa3992a71", + "f99774cef3c15af33cda3cb449cd335ffe4f27435edf83aff4a4f4c2d2df6647", + "c5e09b83b1c2cc81e48a1f7c62b7bb35", + }, + { + "531ca845af7bf731c49c3136407322b1c0f6b32b8eaebf03744b2edc1202d096", + "baf13b85202bbfc899fc73f7", + "d4e9783f537c738200e7ba7526605f359a98c9f10cafaa2f433c40f3e5081a36", + "e2ba9cf548b4f6fb206f224250d85af327fde8d08916686ae770203dc29c694f8902b02222fd287f28ce6091006368c3949bea2937ff0bdedb7dbbd013ccf0a15ee0af8c56fe211b7c311e182f27707f59e09492b3604e80c6c5", + "642f544929202128a783b985d36f60964c7d78e1d41f5d1bfe27de3ae0180df3", + "e333528c59ee1909750ed72fd1309ee1", + }, + { + "3add17568daa9d441aa7a89bf88fa4e6998a921d57e494a254080445bc9b6f35", + "b290f4a52496380218c3dcf5", + "2c6908cb34215f89a3f3a3c892e8887f2efa496a15ab913fc7d34cc70c0dff79", + "0bc9cc13eb2890aa60515c2297a99f092f6e516236c0dec9f986ea98b8a180680f2c6c20bd4354c33433a4c6f6a25e632f90ebef3a383c3592268b483eebf5f5db006929e7987edbcac4755d3afd1cdf9b02954ebd4fef53d5f6", + "2cf3beae94fd5e6a4126a8ec8a7166b0aacb8b8bbce45d6106b78d3456d05149", + "ce1509b1bd5c47a593702618b0d79f6c", + }, + { + "1c1dcfd4c4cc4beb71d6e368f739d8e681dfe48fbae39728386c9dfc08825743", + "0deceb69ce0dc776a3a71b4c", + "b12700258ace7b16e40f4e86886892837168b256a170937a3b89063a9a0d68f7", + "a3af2db672292431fa8ee1fa5b197593b13e58a68c4129401d0942474d5f4cbe62093aaa5453f6d355d2f4b6dc8abde58ce863d1be5f9ecf39730a49565b3b6882a0a641c0b5d156a4107309dd150fd1f1634ea4e5100b3d4f88", + "3ea7f1c0d613323e095558ddde53247420fa0eef17997a1e9c5ba93d5f24c46f", + "70534a87c258905d35806f4439f6906e", + }, + { + "f2724153aac9d50f350878d3c498bc3dd782d90cce5cce4ae14126c0e1fbb3cf", + "1c07b61c5316659bad65cca9", + "067ccbd0206f1f05d2872210dc5717a0585e8195d72afd0c77da11b9b3710e44", + "e69db7fcd3b590a6d32052612034036d5c8bffa5e5e9b742ffe75a9fbba89dd576dec08154cf4e6d36f0fdd4419bdf50adc1974a80ea313421c926dffa87565b4bd0c1e84f2ff305af91877f830f145bb13dfa7efa5e3aa682e6", + "9aba433eef383466a1291bd486c3ce5e0ed126010e0a77bf037c5eaed2c72460", + "f30a155e35400bb0540883e8e09b4afd", + }, + { + "a2544eb2047c97cfcaf0ec1427c5df395472285233a93ffccda8fee660aced56", + "a751bea3c769bb5db25ab109", + "b9514cc01a357605918f9cc19123dcc8db328c605ca0eb9d69d871afeea1dcfb", + "eb9e09884de1454d6aeb0d6c82375f2428992031ea6cabf6a29aa6a4de49a353e4ffae043dad18ae651b20b7bca13f5c327ca9f132014bfa86e716d4724e05a1ef675521a6607a536756e6a8c16bb885b64815f1eb5ec282ce8e", + "cb442b17088f6ac5f24c7a04f0050559386f3a57131b92a54142c7a556fdb935", + "5f80c5c0cdf0c7890bfd1fbd58c33081", + }, + { + "ceb057782efb1e85d805448af946a9b4d4128bf09a12473cce1e8ef8bfd2869d", + "406f9730e9b1e421e428439b", + "0815723d5367b1328cac632fa26e23f2b814a1d59a2971d94d02ebd7ecf5c14a", + "0772ae00e1ca05d096cf533fd3de2818ac783edfca0eee7686a6290f3357481e883fb2f895b9a4f4004c56b8a1265242cfdf1fb4af7edc41ed78c5f4ffe9c4080d4a17318f9c56ecdb3a06f3c748535387d56a096943a76d46f6", + "9d82355d8e460896201be15fd95fed48a8524666d987ab078550883034d0253c", + "a0bee8ac0e636d64d3b1eb33fd6f21d4", + }, + { + "7dbdbdfe36d4936940ad6d6f76c67c2851a0477f0aa7d6797bfdf2b7878ef7e0", + "bc672b224b4b6b91fc3fd697", + "dfea463d35f0fa20487b606d6ccfd422a5b707f16527b422bf1d68a77db67e9c", + "faacb84ec7cfadd731de2f7c0892d7e38cbfb782b48412331af0b3eab602a722cad1069dea0052beb5ca70e2ee476c340c6193bcc60f939aabe446bf3ce958fe11a2ffc90241f0a7e4e274f0c1441def795893895bd848bf0f0e", + "0ddc2281b1fcb904864a43657bc72357cf73fc1f16520caad7cddde10f846bd9", + "9d96699450aa9707695e5de56597101b", + }, + { + "187214df6e2d80ee8e9aae1fc569acd41589e952ddcbe8da018550d103767122", + "56db334422b6c5e93460d013", + "53355283186719a9146c7305e3d1959a11ccf197570b855a43cbc7563a053c73", + "cbedb7ccfbf56dfd72e530bfe16b4f5aac48a90204bcb7a8cae1046010882cfc8b526e7562a7880914e61b60cbd605165242737d85eeed583c98cab3443874e5989ec9cde001adf7de9c9967de5178f75b8412b0c4d6fec5af72", + "c2262585966bc9c23dc7cc1059d060211e86f3b3161d38b153635fbea4a28c05", + "a94297c584dfcd10ee5df19a2ee5c3d2", + }, + { + "1fded32d5999de4a76e0f8082108823aef60417e1896cf4218a2fa90f632ec8a", + "1f3afa4711e9474f32e70462", + "06b2c75853df9aeb17befd33cea81c630b0fc53667ff45199c629c8e15dce41e530aa792f796b8138eeab2e86c7b7bee1d40b0", + "", + "91fbd061ddc5a7fcc9513fcdfdc9c3a7c5d4d64cedf6a9c24ab8a77c36eefbf1c5dc00bc50121b96456c8cd8b6ff1f8b3e480f", + "30096d340f3d5c42d82a6f475def23eb", + }, + { + "b405ac89724f8b555bfee1eaa369cd854003e9fae415f28c5a199d4d6efc83d6", + "cec71a13b14c4d9bd024ef29", + "ab4fd35bef66addfd2856b3881ff2c74fdc09c82abe339f49736d69b2bd0a71a6b4fe8fc53f50f8b7d6d6d6138ab442c7f653f", + "", + "69a079bca9a6a26707bbfa7fd83d5d091edc88a7f7ff08bd8656d8f2c92144ff23400fcb5c370b596ad6711f386e18f2629e76", + "6d2b7861a3c59ba5a3e3a11c92bb2b14", + }, + { + "fad40c82264dc9b8d9a42c10a234138344b0133a708d8899da934bfee2bdd6b8", + "0dade2c95a9b85a8d2bc13ef", + "664ea95d511b2cfdb9e5fb87efdd41cbfb88f3ff47a7d2b8830967e39071a89b948754ffb0ed34c357ed6d4b4b2f8a76615c03", + "", + "ea94dcbf52b22226dda91d9bfc96fb382730b213b66e30960b0d20d2417036cbaa9e359984eea947232526e175f49739095e69", + "5ca8905d469fffec6fba7435ebdffdaf", + }, + { + "aa5fca688cc83283ecf39454679948f4d30aa8cb43db7cc4da4eff1669d6c52f", + "4b2d7b699a5259f9b541fa49", + "c691f3b8f3917efb76825108c0e37dc33e7a8342764ce68a62a2dc1a5c940594961fcd5c0df05394a5c0fff66c254c6b26a549", + "", + "2cd380ebd6b2cf1b80831cff3d6dc2b6770778ad0d0a91d03eb8553696800f84311d337302519d1036feaab8c8eb845882c5f0", + "5de4ef67bf8896fbe82c01dca041d590", + }, + { + "1c7690d5d845fceabba227b11ca221f4d6d302233641016d9cd3a158c3e36017", + "93bca8de6b11a4830c5f5f64", + "3c79a39878a605f3ac63a256f68c8a66369cc3cd7af680d19692b485a7ba58ce1d536707c55eda5b256c8b29bbf0b4cbeb4fc4", + "", + "c9e48684df13afccdb1d9ceaa483759022e59c3111188c1eceb02eaf308035b0428db826de862d925a3c55af0b61fd8f09a74d", + "8f577e8730c19858cad8e0124f311dd9", + }, + { + "dbdb5132f126e62ce5b74bf85a2ac33b276588a3fc91d1bb5c7405a1bf68418b", + "64f9e16489995e1a99568118", + "b2740a3d5647aa5aaeb98a2e7bbf31edaea1ebacd63ad96b4e2688f1ff08af8ee4071bf26941c517d74523668ca1f9dfdbcaab", + "", + "e5fec362d26a1286b7fd2ec0fa876017437c7bce242293ff03d72c2f321d9e39316a6aa7404a65ccd84890c2f527c1232b58d5", + "dfa591ee2372699758d2cc43bfcbd2ba", + }, + { + "8433a85f16c7c921476c83d042cb713eb11a83fc0cffe31dde97907f060b4ee9", + "55ffc85ffd1cdea8b8c48382", + "23bc3983ba5b3be91c8a6aa148a99995241ee9e82ce44e1184beb742affbe48f545c9a980480cf1fab758a46e4711ea9267466", + "", + "2f4bdc7b8b8cec1863e3145871554778c43963b527f8413bb9779935c138a34d86d7c76a9e6af689902f316191e12f34126a42", + "7dc63156b12c9868e6b9a5843df2d79e", + }, + { + "5d7bf55457929c65e4f2a97cbdcc9b432405b1352451ccc958bceebce557491d", + "f45ae70c264ed6e1cc132978", + "ba5ac2a16d84b0df5a6e40f097d9d44bf21de1fcec06e4c7857463963e5c65c936d37d78867f253ce25690811bf39463e5702a", + "", + "47c16f87ebf00ba3e50416b44b99976c2db579423c3a3420479c477cd5ef57621c9c0cee7520acb55e739cc5435bc8665a2a0c", + "456054ecb55cf7e75f9543def2c6e98c", + }, + { + "595f259c55abe00ae07535ca5d9b09d6efb9f7e9abb64605c337acbd6b14fc7e", + "92f258071d79af3e63672285", + "a6fee33eb110a2d769bbc52b0f36969c287874f665681477a25fc4c48015c541fbe2394133ba490a34ee2dd67b898177849a91", + "", + "bbca4a9e09ae9690c0f6f8d405e53dccd666aa9c5fa13c8758bc30abe1ddd1bcce0d36a1eaaaaffef20cd3c5970b9673f8a65c", + "26ccecb9976fd6ac9c2c0f372c52c821", + }, + { + "251227f72c481a7e064cbbaa5489bc85d740c1e6edea2282154507877ed56819", + "db7193d9cd7aeced99062a1c", + "cccffd58fded7e589481da18beec51562481f4b28c2944819c37f7125d56dceca0ef0bb6f7d7eeb5b7a2bd6b551254e9edff3a", + "", + "1cc08d75a03d32ee9a7ae88e0071406dbee1c306383cf41731f3c547f3377b92f7cc28b3c1066601f54753fbd689af5dbc5448", + "a0c7b7444229a8cfef24a31ee2de9961", + }, + { + "f256504fc78fff7139c42ed1510edf9ac5de27da706401aa9c67fd982d435911", + "8adcf2d678abcef9dd45e8f9", + "d1b6db2b2c81751170d9e1a39997539e3e926ca4a43298cdd3eb6fe8678b508cdb90a8a94171abe2673894405eda5977694d7a", + "", + "76205d63b9c5144e5daa8ac7e51f19fa96e71a3106ab779b67a8358ab5d60ef77197706266e2c214138334a3ed66ceccb5a6cd", + "c1fe53cf85fbcbff932c6e1d026ea1d5", + }, + { + "21d296335f58515a90537a6ca3a38536eba1f899a2927447a3be3f0add70bea5", + "2be3ad164fcbcf8ee6708535", + "ad278650092883d348be63e991231ef857641e5efc0cab9bb28f360becc3c103d2794785024f187beaf9665b986380c92946a7", + "", + "b852aeba704e9d89448ba180a0bfde9e975a21cc073d0c02701215872ed7469f00fe349294ba2d72bf3c7780b72c76101ba148", + "bdd6d708b45ae54cd8482e4c5480a3c1", + }, + { + "d42380580e3491ddfbc0ec32424e3a281cbe71aa7505ff5ab8d24e64fbe47518", + "fbed88de61d605a7137ffeb2", + "4887a6ef947888bf80e4c40d9769650506eb4f4a5fd241b42c9046e3a2cf119db002f89a9eba1d11b7a378be6b27d6f8fc86c9", + "", + "87aa27f96187ce27e26caf71ba5ba4e37705fd86ca9291ea68d6c6f9030291cdbff58bff1e6741590b268367e1f1b8c4b94cd4", + "d1690a6fe403c4754fd3773d89395ecd", + }, + { + "5511727ecd92acec510d5d8c0c49b3caacd2140431cf51e09437ebd8ca82e2ce", + "ae80d03696e23464c881ccff", + "184b086646ef95111ccb3d319f3124f4d4d241f9d731ce26662ea39e43457e30b0bd739b5d5dbceb353ce0c3647a3a4c87e3b0", + "", + "aa28cb257698963dfc3e3fe86368d881ac066eb8ee215a7c0ed72e4d081db0b940071e2e64ff6204960da8e3464daf4cb7f37b", + "c1578aa6e3325ee4b5e9fb9ee62a7028", + }, + { + "d48f3072bbd535a2df0a2864feb33b488596cd523ad1623b1cefe7b8cbefcf4a", + "bbf2a537d285444d94f5e944", + "060c585bd51539afdd8ff871440db36bfdce33b7f039321b0a63273a318bd25375a2d9615b236cfe63d627c6c561535ddfb6bd", + "", + "993d5d692c218570d294ab90d5f7aa683dc0e470efac279a776040f3b49386813f68b0db6a7aef59025cc38520fb318a1eac55", + "8cd808438a8f5b6a69ff3ae255bf2cb2", + }, + { + "5fe01c4baf01cbe07796d5aaef6ec1f45193a98a223594ae4f0ef4952e82e330", + "bd587321566c7f1a5dd8652d", + "881dc6c7a5d4509f3c4bd2daab08f165ddc204489aa8134562a4eac3d0bcad7965847b102733bb63d1e5c598ece0c3e5dadddd", + "9013617817dda947e135ee6dd3653382", + "16e375b4973b339d3f746c1c5a568bc7526e909ddff1e19c95c94a6ccff210c9a4a40679de5760c396ac0e2ceb1234f9f5fe26", + "abd3d26d65a6275f7a4f56b422acab49", + }, + { + "885a9b124137e40bd0f697771317e401ce36327e61a8f9d0b80f4798f30a731d", + "beebc2f5a26fd2cab1e9c395", + "427ec568ad8367c202f5d9999240f9994cc113500154f7f49e9ca27cc8154143b855238bca5c7bd6d9852b4eebd41e4eb98f16", + "2e8bdde32258a5fcd8cd21037d0545eb", + "a1d83aab6864db463d9d7c22419462bde0740355c1147c62b4c4f23ceeaf65b16b873b1cc7e698dff6e3d19cf9da33e8cbcba7", + "4fdbfd5210afa3556ec0fdc48b98e1eb", + }, + { + "21c190e2b52e27b107f7a24b913a34bd5b7022060c5a4dec9ab289ff8ae67e2d", + "b28a61e6c1dfa7f76d086063", + "4e1b9528cf46b1dd889858d3904d41d3174dcb225923f923d80adbfe6eec144b1d4eb3690d0b8519c99beaee25bb50fd2d148f", + "d80657377ddbbed1f9b8d824b3c4d876", + "7126fa807aa6b61a60958fe4cc8682bb256e5bbdc499d04a6caa81b23f9e67d3da4cf1994b5a8ecc7bce641864d0519a6509cd", + "d3e96568f2cd1a48771ee4f67ad042c1", + }, + { + "11c33ae37680130c51ed11bfaf0fcb6ed4fc7d903ff432b811763d2c7ef83a33", + "0f224d26dbf632cebdce3b8b", + "f8a2affe5a7e67f2c62622e4a56804b48e529d1faf9096f94409224129921ce46aed898dd5391746e8170e05f91e0524166625", + "dee803732ff662cba9f861227f8b67cf", + "3856558375c363b25e8f9e9e2eb63cf0e76a1c6e228893c7b22da4a69b682528b4a4ca2b99e7a537390e2d1e05a68f3e39c4e9", + "9b12691b2002ca9227035c68ea941ef3", + }, + { + "3b291794fbb9152c3e4f4de4608a9137d277bd651f97e738afaa548d97b4ec60", + "4d1c69c6da96c085d31422ba", + "21b3ca1f47a0c7f6ebd097eda69d9e5b5fbf5c24d781658003cfd443ae7096be19e1cd3c14fe9738efb00847697fccb466ae1b", + "f3a5fa61a4e987413a8fab4aa51d895d", + "6c1439cd2cb564e7944fd52f316e84aeffc3fd8024df5a7d95a87c4d31a0f8ea17f21442c709a83b326d067d5f8e3005ebe22a", + "e58048f2c1f806e09552c2e5cdf1b9d9", + }, + { + "8e7a8e7b129326e5410c8ae67fbd318de1909caba1d2b79210793c6b2c6e61c7", + "8e48513fdd971861ef7b5dc3", + "ef6b4145910139293631db87a0d7782a1d95db568e857598128582e8914b4fa7c03c1b83e5624a2eb4c340c8ad7e6736a3e700", + "80bb66a4727095b6c201fb3d82b0fcf5", + "e302687c0548973897a27c31911fc87ee93d8758c4ded68d6bd6415eaaf86bcc45fa6a1ef8a6ae068820549b170405b3fc0925", + "ff5c193952558e5a120e672f566be411", + }, + { + "d687e0262f7af2768570df90b698094e03b668ce6183b6c6b6ca385dcd622729", + "50f6904f2d8466daa33c2461", + "79e3067d94464e019a7c8af10b53adf5b09426d35f2257c3cbaffe1ff720565c07e77aeef06f9d03a2353053992073a4ed1fc8", + "e8fa99432929d66f10205ad3e9592151", + "18f6e6aeecc8dc5a3d0b63a2a8b7bfaf695bd9c49a7392dbfa8ed44771eebe27f94589d8a430da4cf03a8693bc7525e1fcac82", + "3c864eaa1b0ae44a7f0ad9ba287ba800", + }, + { + "26dc5ce74b4d64d1dc2221cdd6a63d7a9226134708299cd719a68f636b6b5ebd", + "0294c54ff4ed30782222c834", + "ae4c7f040d3a5ff108e29381e7a0830221d5378b13b87ef0703c327686d30af004902d4ddb59d5787fecea4731eaa8042443d5", + "2a9fb326f98bbe2d2cf57bae9ecbeff7", + "9601aec6bc6e8a09d054a01e500a4e4cdcc7c2cf83122656be7c26fc7dc1a773a40be7e8a049a6cdf059e93a23ca441ef1ca96", + "b620a8a0c8fe6117f22735c0ca29434c", + }, + { + "7fa0644efc7f2e8df4b311f54ba8b8c975b2c2aa97962f8ca8a322541bedaa9d", + "5e774e45a07eeb9721734412", + "84d1c75455e4c57419a9d78a90efc232c179517fe94aff53a4b8f7575db5af627f3d008006f216ecfc49ab8da8927ff5dc3959", + "6ad673daa8c412bf280ea39ba0d9b6d4", + "e2f00b5a86b3dec2b77e54db328c8d954d4b716f9735e5798b05d65c512674d56e88bda0d486685a45d5c249719884329e3297", + "0ce8eb54d5ad35dd2cb3fa75e7b70e33", + }, + { + "91d0429f2c45cf8ab01d50b9f04daaaccbe0503c9f115f9457c83a043dc83b23", + "34401d8d922eebac1829f22e", + "d600d82a3c20c94792362959de440c93119a718ac749fa88aa606fc99cb02b4ca9ba958d28dc85f0523c99d82f43f58c5f979b", + "1b29de9321aebc3ff9d1c2507aee80e9", + "84cbc9936eb7270080bb7024780113d064eccb63d3da0bd6bce4f8737d28304bfb6102f3ae9c394cc6452633fc551582bbfe1d", + "e132dc8a31d21f24ea0e69dfb6b26557", + }, + { + "44e6411b9fbfcef387d0ca07b719181c7567e27dba59e8e1c3cc1763cfeaca04", + "25a1cfd97bd8e63de5d65974", + "db28a592b1f3603c287991a69cc64eacdd62046445a8ba4067575f12553de155d06a9b40ddf58fec56c8171687b9cb54b1f346", + "4b1751b074ab649d27fd3f2c4d7ee33a", + "36bf6bb761b2248fe71a620e34e9d18e12a74ca42c9a9a21d30345995a83eb44bcae3c67c020730cd8d5e51a741694cc396469", + "e69ebf80a88d6eca41ae87cdcab4e1f2", + }, + { + "a94bfcefae90f9078860db80ccc50819eadf7cce29df3279f94f5eea97009ef2", + "f481bcb7f5da296e9454ff78", + "97d0c7dfcab32a386f51d92e89333ec84eecd552e68d14cf48b75067bf0e1946ad03a5d063b852ca053c929088af45d0884a88", + "9f80d845577818df9ba984ee552ae203", + "18a1c9bfe1b1dfdd06e465df347c1e942b37b3e48cb0c905841a593b5b0d0330feb3b8970dbc9429252a897f0f8e12860ea39a", + "10cf4d335b8d8e7e8bbaf49222a1cd66", + }, + { + "a50a60e568ff35a610ef9479c08bbc7bb64c373fc853f37fa6b350250a26f232", + "5ada1d4aca883d7bd6fa869f", + "9ea44e72a1d21395cd81d20db05816441010efd8f811b75bb143ab47f55eefce4eec5f606fa5d98b260d7e5df4a7474cbd8599", + "cc7a7a541be7a6d1b846354cb6a571e6", + "4165b135187faeb395d4531c062738e0d47df8bed91982eb32e391a6b3711f117b6fae0afde791de3e72fcf96d2b53ff1a621a", + "e2cbfea2100585b2cbe5107da17ff77a", + }, + { + "5ff3311461d247ceb1eaf591292fcba54308dd3484fd1851e09a12b8f6663fc1", + "61af2e6aec183129cf053c2b", + "920df8b2888a74022ede6919ed0bf48ccf51e395fe5bfa69a6209ff9a46674024eaa4f43ae2c933730b9fdc8ad216130447cc8", + "5eafed6674f2ae83397df923e059db49", + "0e35e1208168b639e012df398bc8bf2b19b08d46af0353cd78f6d1b7ae14e6224c1da6fdc9433b171f1cd2b512d5f1acd84f03", + "5bc77eb02e4d51e2019446b468498d0e", + }, + { + "42e93547eee7e18ec9620dd3dc0e2b1cf3e5d448198a902ded3f935da9d35b33", + "e02e12ba92a6046af11adf0e", + "6c3704b32527ace3d5236687c4a98a1ad5a4f83c04af2f62c9e87e7f3d0469327919d810bb6c44fd3c9b146852583a44ed2f3c", + "ac3d536981e3cabc81211646e14f2f92", + "8b6506af703ae3158eb61e2f9c2b63de403b2ebc6b1e6759ceb99c08aa66cb07d1d913ac4acd7af9b9e03b3af602bcaf2bb65e", + "a6ce2ccb236fc99e87b76cc412a79031", + }, + { + "24501ad384e473963d476edcfe08205237acfd49b5b8f33857f8114e863fec7f", + "9ff18563b978ec281b3f2794", + "27f348f9cdc0c5bd5e66b1ccb63ad920ff2219d14e8d631b3872265cf117ee86757accb158bd9abb3868fdc0d0b074b5f01b2c", + "adb5ec720ccf9898500028bf34afccbcaca126ef", + "eb7cb754c824e8d96f7c6d9b76c7d26fb874ffbf1d65c6f64a698d839b0b06145dae82057ad55994cf59ad7f67c0fa5e85fab8", + "bc95c532fecc594c36d1550286a7a3f0", + }, + { + "fb43f5ab4a1738a30c1e053d484a94254125d55dccee1ad67c368bc1a985d235", + "9fbb5f8252db0bca21f1c230", + "34b797bb82250e23c5e796db2c37e488b3b99d1b981cea5e5b0c61a0b39adb6bd6ef1f50722e2e4f81115cfcf53f842e2a6c08", + "98f8ae1735c39f732e2cbee1156dabeb854ec7a2", + "871cd53d95a8b806bd4821e6c4456204d27fd704ba3d07ce25872dc604ea5c5ea13322186b7489db4fa060c1fd4159692612c8", + "07b48e4a32fac47e115d7ac7445d8330", + }, + { + "9f953b9f2f3bb4103a4b34d8ca2ec3720df7fedf8c69cac900bd75338beababe", + "eb731ae04e39f3eb88cc77fa", + "3b80d5ac12ba9dad9d9ff30a73732674e11c9edf9bb057fd1c6adc97cf6c5fa3ee8690ad4c51b10b3bd5da9a28e6275cbe28cb", + "d44a07d869ac0d89b15262a1e8e1aa74f09bcb82", + "1533ce8e2fc6ab485aef6fcfb08ded83ae549a7111fce2a1d8a3f691f35182ce46fce6204d7dafb8d3206c4e4b645bc3f5afd1", + "f09265c21f90ef79b309a93db73d9290", + }, + { + "2426e2d1cd9545ec2fb7ab9137ad852734333925bfc5674763d6ee906e81c091", + "49a094a71d393b36daa4a591", + "7cbe7982d365a55d147c954583f9760a09948ab73ebbe1b2c1d69ed58e092a347392192cfe8bce18ca43ee19af7652331bd92c", + "177309cfc913e3f5c093e8b1319ba81826d43ce5", + "cab992e17cf6ec69fd3c67ea0424bcd67475a7f1f16e6733c4419d1b5a755f78d6eda8e368360d403800a08f0d52b4bc0aa0ab", + "b125f8caee9e54b9f9414b1c09021ed8", + }, + { + "8dc1b24bcbbee3cb8e14b344166d461d00c7490041edc9fa07e19cc82a3ed9c4", + "31768ad18c971b188d947019", + "84e4f79dbb7209cbaf70e4fefe137c494786c899602783e9c034296978d7f0c571f7ea9d80ed0cc4723124872d7326890300c1", + "eb3673b64560cca7bda76a1de7ae1014ee1acaee", + "2402acd865d4b731bc9395eae0e57d38fdf5ce847ac7aef75791a52c7573ea9b3a296e62cb1ed97c4bd34be50ee7f3d75747cf", + "665abb725498ede2b0df655fc1765a2b", + }, + { + "bc898f643a5f2cd864c10b507b4b803b4ff4ace61fadcc7bcd98af394731b791", + "cc447d83c0a6734a79778c64", + "124eb963cdb56fa49c70a9b1aa682445c55065f26859f1d16eef7cfe491587533eedd7e23deabddfc5550c2fa6a08b17822699", + "e932bd2e0e6c550d136f725e14c53d27ffb20f6a", + "45d8908ef9eef369e78b7ea0b7d023a92c63648271927efe9b0220eb09ed96f3b635c6ec8bfc68b4c228b712494bb37f4c7f1a", + "47899857494bac28d2176a9c923026b2", + }, + { + "8e82a85466ee024eb1ae10c4982d6a95e6dbe5582299ab37fe89a9db80ab51a6", + "04cfd489e18eeb7a4a8ab36b", + "3aa2e4eaed18c4602715ae77379e9083708af9f9b49031324d41abca61440319c8c8e6dbcc20006a825b12ced00b2286848a94", + "7bb54b1a6ed0ca387268a146430c0bfa2602a8fd", + "674b1391937074642408eeae9b748ca629da9fd00281824f5a108f6078ee78f98749392bb6e29b53e53e4b11739ac53a8e653b", + "e320a873a9c2e8ef455698c37ea59a6d", + }, + { + "f1f2c5503ebf35ac1373c29e2305e963f89f6ed015a181b70fb549429805d5d9", + "2fb5c6a24f406872755db05c", + "b4a2809198035c277637bb1c2927fb5c60b49ef9087c800012d8663d997983fcb78d51a054114a24e1e1b5214b58e7dee47195", + "92c1f3489aed90aedafb55562a34b3f4be29e101", + "f051a3a968278a46630b2894a0d386c18fa034960d8ddd14e88e1071afbbca5baf02967c2270117b4fb2bd4cfd032174505f99", + "6f1db5293660b6904f7f008e409bdc06", + }, + { + "f0338d26d74bd1768da5bb79c59fab2b4abe1966324048790c44bc98a6b34b6c", + "c8269e4406fa0be1cf057b2f", + "323c373e4d85a1fd21f387fdd8c7e6aeebd5aae893d7af286cb214600cba8b9eb06df085a2dc5aed870259f7f3cc81d3eb53bd", + "13fb0edcba095cef9c4343a0629fd5020f03729d", + "08572b9cf9bcfd21d4403a1218d94476b9ee8c3b94c56625c21ccaf4c0efa34cf22a532389210793699c9de1ab14f8c4c52928", + "29968c9fb610940cee9fd5b2f7c8ba21", + }, + { + "a67648285b65b9196060aaa02af279170164353e38fb77c3968c403cfa9acdc8", + "0822d6b3e91eccb7e14245fd", + "b5d271768c12ccabf89eb2d58cbde840c26d1c9b3692581f90c8b0d7b2cff31ae9192d284f5448de7d924a7b08f115edae75aa", + "0d9a5af7ac27438d92534d97ff4378274790e59f", + "b59041eed7abc2ff507d1932b5c55ac52728e5ac6648dcc74b38870db6181b1989f95a0144f0db368ec50414cfda0b977141e3", + "1d12ce89e1261d73470f3ae36ab87288", + }, + { + "51162b2435f3cf43471f4cc0ffac98b438501ee9b887843a66e9951ca35b8767", + "dcb902eaa837ed22bf5fa636", + "3edf43358f5109a4dfb4a02987170a67cdd170f6028f7708bdd7726f476b882b9640270f2270f7babfa384181c8e58c15d04c4", + "4d459905ff89aed07dcda43a3d191a3da9309faa", + "046a2313d36cbc43b6d0787e5ef37d153090a31d0f6656004034be72b9b07ace3a8abe8614362282d87da40c29c60a1a9f5c40", + "c7410b5cb94d2877c189983791cee82e", + }, + { + "2fa2beb1cde2226f28fb42a5fb0af3fc58fbb76bf14aa436e6535d466456a0f4", + "50190514a3740b3c0b1df576", + "a5e0b4837dfca263ba286abf7940b6e70fabb55d8dee5028617c1190fbd327f79b79d2f34db6076ab07cecff7114b15ca02a33", + "25142928c1ae9c7b850309e07df359389db539fc", + "850fd22bd0897b98ce40bc6c1345a9d59abf796b1b8c34ee8b377e54ee7d59dec05c022ecae96ffdfa1311bdd4e7a9d35aac47", + "4b5ab89b4f627ca32d12a1791c286870", + }, + { + "a92a797ce2b2f382030b77a1abe94c8076eee88de2dc4929350b244dbdaddd30", + "716f577401a7893c42c91710", + "9d26ff79a89720fab6e4cda85887e3c0c3f86a4670d065c8ea68042b6f9f16dd2c5b31acb36331f5b1e50f08c492dc12eebd9e", + "8642681f1839b88990c2a939f00c9b90766dadac", + "3080bcf3604cf81f5f2c6edc80dfe5d877168a9903598a700a0bbae188fadc7a8b76a04b40400f9252d7f9437fa8f024a3bdeb", + "8fc56f6bf48efb00476886b2a03ecb89", + }, + { + "89d0723e5a087456b7b709b8b21be380b463ba3dc9b79170e9947526798fe91c", + "68e2f307b7d49d4d9c041755", + "7fe2afb710e8fd49cca1c2ba8fd0814594fba4d667017630e170a8a379fa5837bf370ca1cd4c98bd8c4f13eb7068ffa71ab07c", + "b34805b30703a62b6d37c93f2443e1a33154b5fb", + "b841012752bbf1dfa7b59366dbf353bf98b61ff2e6e7a13d64d9dcb58b771003c8842ac002aac1fa8ca00a21eaf101ab44f380", + "73a93e2722db63c2bbf470d5193b2230", + }, + { + "329a6e94b1cce693e445694650d62b8c2c9ab03a09e6d4eca05c48291e576b89", + "78f471bc32f8637a213e87ac", + "65264d75e1a176a7e966e59109cd074ac5d54740eb0c58084af023e5599eb611846199579d95ba94b6d25ee4d9074b9714f231", + "c00c465524e2e2f8a55c0793ed9af851be45a70e", + "964d665d1e3c1018dfd883e217cfe4c856cc844f7644b53bb68fbe66f8541fa43ac54e92a2b194d6d8929fe031e94b3e70eca0", + "fd511385711236f2e99e6da5042007b7", + }, + { + "463b412911767d57a0b33969e674ffe7845d313b88c6fe312f3d724be68e1fca", + "611ce6f9a6880750de7da6cb", + "e7d1dcf668e2876861940e012fe52a98dacbd78ab63c08842cc9801ea581682ad54af0c34d0d7f6f59e8ee0bf4900e0fd85042", + "0a682fbc6192e1b47a5e0868787ffdafe5a50cead3575849990cdd2ea9b3597749403efb4a56684f0c6bde352d4aeec5", + "8886e196010cb3849d9c1a182abe1eeab0a5f3ca423c3669a4a8703c0f146e8e956fb122e0d721b869d2b6fcd4216d7d4d3758", + "2469cecd70fd98fec9264f71df1aee9a", + }, + { + "55f9171a03c21e09e3a5fd771e56bffb775ebb190319f3dc214c4b19f72e5482", + "14f3bf95a08e8f52eb46fbf9", + "af6b17fd67bc1173b063fc6f0941483cee9cbbbbed3a4dcff55a74b0c9535b977efa640e5b1a30faa859fd3daa8dd780cc94a0", + "bac1ddefd111d471e75f0efb0f8127b4da923ecc788a5c91e3e2f65e2943e4caf42f54896604af19ed0b4d8697d45ab9", + "3ae8678089522371fe4bd4da99ffd83a32988e0728aa3a4970ded1fe73bc30c2eb1fe24c0ff5ab549ac7e567d7036628fd718d", + "cf59603e05f4ed1d2da04e19399b8512", + }, + { + "54601d1538e5f04dc3fe95e483e40dec0aaa58375dc868da167c9a599ed345d9", + "c5150872e45c341c2b99c69a", + "ae87c08c7610a125e7aa6f93fac0f80472530b2ce4d7194f5f4cb8ac025323c6c43a806788ef50c5028764ec32f2839005c813", + "93cd7ee8648a64c59d54cdac455b05ffdfc2effe8b19b50babd8c1a8c21f5dc8dc6050e2347f4cd28701594b9f8d4de5", + "d5f005dc67bdc9738407ce2401977f59c9c83520e262d0c8db7fe47ae0eada30d674694f008e222f9733a6e63d81499e247567", + "3470155144c74929980134db6995dd88", + }, + { + "e966c470cbecc819260640d5404c84382e6e649da96d29cad2d4412e671ed802", + "b3a92d6f49fe2cb9c144d339", + "7adf6fcb41d59b8d2b663010c3d4cf5f5f0b95cf754f76f8626c4428467e5c6684e77e7857b1cc755762e9ea9117e3bb077040", + "dfa62a3a4b5b3af6770cfd3cef3bbb4cce3f64925782a9a8a6e15fe3744d8f9310400dd04e8d7966c03850539e440aa5", + "5f5b09486e6cd2a854e5622b4988e2408fddaca42c21d946c5cd789fe5a1306ef33c8cd44467ad7aa4c8152bce656a20367284", + "2b388109afdada6473435230d747b4eb", + }, + { + "4a8a12c0575ec65ae1c5784d2829bc7b04818eb00bd4c90a0d032ea281076e27", + "959f113b705397fb738018b0", + "0c5571195586e4fc7096fb86cfcd6684081446f3d7adc33a897f03ac4ff6c3cc2019b67bd3184c86070764f6deaa8a10d0d81f", + "adb8bc96142a1025122dc22f826957197af33dcdcf6b7ab56bc1a5e17e8534e48b8daf685faf9543bb343614bdf6737f", + "84212d5991231d35c4e8621163e5b370a0105a05856866e74df72c0808c062981570d32d274ea732fa4d29f9cfa7839cadbe6a", + "39cee3b8fa0bf92605666ccd9eb19840", + }, + { + "6197a4fa7cfcedeff223f69ea68b4ddf54b683350c20875be353077e9bbce346", + "1a69ecabd42c53c0ec64fcd0", + "40a487b4daf866c20f3c4911a0586709c3344aa988dc9c464bcf36cc4e3d92701e611e60cf69f3edbf76cd27ff6ba935026d7f", + "b20a7ca5b5b603f661587e01f7ef171823ef463c187ded77a3d616400cc1d2b0b688ac9e927498341560cbc8eb9a4198", + "06420fa038ee62db30cc05bfe34c8d2c39a9d439653907c512ed606511921fe76110913a5bfb6b6c7b23d7f8883f5ab65f4b14", + "4d3097c9919002cd1da83f29820312ed", + }, + { + "c9dbe185023ecaa78be9bfac1b91b9da6bd7c11349feb69e6b0be83a838e77b2", + "8940fa7c6afd3f7a09ec93b6", + "075be0d61273e6975978d0b88b3fa38fc398d4d0f22a342a8afa5562af0e7c8fa548f0d8faec898a20c97e851754992c1ed4a3", + "f17bd357608365e66b98e49191cdc2a3813bba5a1b7988aa8aaaaad4b86d0ef4e2698cad799d63fcd2a5e87c0e3e929a", + "615c1097d577363a77bfc7dd57179acb68166e78021b3397d7029ce33cbc848f036b9c07989eeb9f42aeaeebe8542f103b1d32", + "a22ab25fd8a6127469e8ce9ff686d575", + }, + { + "e6cdcf497a6e119009bf43ac183d2dd4d4e967964ef92811f69eb18d92923305", + "3e88459a76e1dcc890788297", + "72a3dfb555ba0029fc3d1c85b836f76135bd1858189efdde2db29045f2c26e6a65627d81a0b85ca42e8269d432a41154e929ac", + "a359f86ec918537d80a84da7b66bca700c1ff9ec7f8695a30808d484da218d15ae89c5f943e71778445130191f779001", + "9ae3f8ccae0bb5789b1105118760c406e41175a76612435cb0c8be225ea6b368c9d08c9d9a24b512d1458e94af79e3060ab69e", + "ac3bbc8fd6a7097df6f298411c23e385", + }, + { + "de5531b50888b61d63af2210ee23f46d91a5e60312bd578584af586bf22ea756", + "0fde8689b0348bbcfaa89fec", + "80621e54eef1c92afb1f64ed860e39311eea7e2cca6f5624008c1d2e581d7112b7ee0b559fc3db575b7b7c42ee4f2a20442dc0", + "22db97cd5f359f12aec66c51c7da79ba629db4c8c7e5501be2ec1e4cc3f3944b6e3057d093bc68b735b5156950f91804", + "933018419a32b7bf65f9777c44889a44b32d61ceddbb46839366ce2ca2ffeb1833f46559e59c93bb07f622d9633f13932cf7f1", + "25023a4ee9bdbf525cfef888e2480f86", + }, + { + "bc0c6368a9bb2622f6d5ba12de581f003336c298adac34499bf26b11e630f891", + "2aa8f30b567cf1edd818e42d", + "1dcc1a3167fba55c00d3383e26d386eaa0449154599992da7f7f6598f41b3eb8e4d0a9143dfcab963f5c390a6ae2010fbcf6ec", + "0e28ebf87eb757e83031fb836f7b049a46bd740b0a39c9b798d2407e1150da86dfe84121c7c98449559453ad7558e779", + "78d00a6e3302369817b9cf1f24ea13c41751382e3fea74403d094737e32fb507184cfebce48d10b4ce8db12ef961e4df2c8e95", + "c0aff3594f86b58e229c7ad05c2b84f0", + }, + { + "5d98a0c7ad6f9c0b116613ca5082250356a6a9bca55fe1a4a2962b733214dac4", + "8b2d8e8d83bdd6a3125dd997", + "4f3685c2cfbc856379d1fd00f9611fe4c0a4b9c4013fe1bee144449709a6a7e31ff6fb0da74ed464b066b03b50f19cd7f5f9bc", + "2f20636d46ce37e9bb0ca0c41d819e3eabcedacbd1ca3ced112d3ad620bbd3b2effe80d3ec8760706e8f14db83139a70", + "8e178c0e3e5d22b3be897e0b8879b0d53fef2efb9946ccff6d717b001e3033f2cc22d01d9551e9c0749de704fbe3189328cbb0", + "541b7db823e37b5ed323626b9c6748f6", + }, + { + "d80a2703e982de1a2fe706ffe6e389f351ab356ccf056df045e2941b42ef21a4", + "1521ab8f7242cba05427f429", + "6f9fde28e85776a49cfbad1459d94611757a3cd996aa6e2d702d0483a4d88d532131ebd405b351226b16d19d30d32807a1d511", + "5395de90d6bec7c159ab9d6cfa663bdc6295d025e1fcc8b760b9ba42d785eda218dabc6fa7c0f733ad77f61682bff2db", + "1e72a8495ceadaf0d31b28ba7cb7c37ccb117761d38fe7dd98eb230ff4ea0b400401e9b5311a7be9b2a533523ad469e2fdb233", + "bb174b7624c935ff75b3b77ff7068a98", + }, + { + "6d5c69d7135c0b5b7fef512c127fa788092f1a908358ab658b8f23e463409aa5", + "b36cccad38cd6148a384a026", + "b4e74f5c56f2ea056d9ff931525944dfad207e063ba226c354e0320a50449967e964580d9b57028c14005aba6865f8bc6a3ef8", + "b19f4616bb1452251a2a7dbf78f920194f139e0424d27683621d1ee1e865737c2466e058439c8e122e582a7b63607ce9", + "1ce12cd5502efa9ea259584ae9b3c7dbd9444380d4b77a2c787f9b2257019b23ee183dffebb3106a26b18d8a23445626a578e2", + "62945e31bae3181855b69c37898ac5bf", + }, + { + "e6afe3c4db2c1d13edb1c5931b2b4b515ec0fd6201139ee1ea55cec92263830e", + "358bd9ea64177d1e23a41726", + "710bb3394b094ee7d053bc6599b26dafd337e8a61c580d0446c3bf195e77ca5132c8ec3a47a61579dce38360bba7c65e4d5634", + "7e0f841cddd7eeebd1ec7b7b8d0e2f71656e5e9ff3cfa739c0b9d0ec4941a0b3f3b396690dbe5f5082d6fb6dd701c68d", + "4574a8db515b41c14c2a962dff34e2161a7195c491b11b79889aff93c5b79a6455df9fe8ef5c5b9edb5da1aa9fe66058b9065f", + "7c928d7f5cbac9bb4b5928fe727899eb", + }, + { + "5cb962278d79417b7795499e8b92befe4228f3ba5f31992201aa356a6d139a67", + "76f7e7608f09a05f336994cf", + "2e12cbd468086aa70e2ecd1ddef561e85c225dd083e5956f5c67503344b0ea982bb5044dafbcc02a5b9be1e9b988902d80172b", + "032de3fdec273fc8446c2bf767e201f2c7c190acf9d6d321a24a0462cbc3356e798fe23d6c1b4fe83be9c95d71c05504", + "c959344a46aa5216d2b37c832436eb72a4a363a6df5642cfbbfd640dea1d64c80bd97eabc1aab192969ee0b799e592a13d2351", + "51b227eaf7228a4419f2f3b79b53463a", + }, + { + "148579a3cbca86d5520d66c0ec71ca5f7e41ba78e56dc6eebd566fed547fe691", + "b08a5ea1927499c6ecbfd4e0", + "9d0b15fdf1bd595f91f8b3abc0f7dec927dfd4799935a1795d9ce00c9b879434420fe42c275a7cd7b39d638fb81ca52b49dc41", + "e4f963f015ffbb99ee3349bbaf7e8e8e6c2a71c230a48f9d59860a29091d2747e01a5ca572347e247d25f56ba7ae8e05cde2be3c97931292c02370208ecd097ef692687fecf2f419d3200162a6480a57dad408a0dfeb492e2c5d", + "2097e372950a5e9383c675e89eea1c314f999159f5611344b298cda45e62843716f215f82ee663919c64002a5c198d7878fd3f", + "adbecdb0d5c2224d804d2886ff9a5760", + }, + { + "e49af19182faef0ebeeba9f2d3be044e77b1212358366e4ef59e008aebcd9788", + "e7f37d79a6a487a5a703edbb", + "461cd0caf7427a3d44408d825ed719237272ecd503b9094d1f62c97d63ed83a0b50bdc804ffdd7991da7a5b6dcf48d4bcd2cbc", + "19a9a1cfc647346781bef51ed9070d05f99a0e0192a223c5cd2522dbdf97d9739dd39fb178ade3339e68774b058aa03e9a20a9a205bc05f32381df4d63396ef691fefd5a71b49a2ad82d5ea428778ca47ee1398792762413cff4", + "32ca3588e3e56eb4c8301b009d8b84b8a900b2b88ca3c21944205e9dd7311757b51394ae90d8bb3807b471677614f4198af909", + "3e403d035c71d88f1be1a256c89ba6ad", + }, + { + "c277df045d0a1a3956958f271055c229d2634427b1d73e99d54920da69f72e01", + "79e24f84bc77a21a6cb14ee2", + "5ca68d858cc30b1cb0514c4e9de98e1a1a835df401f69e9ec6f1bcb1158f09114dff551683b3827457f77e17a7097b1ea69eac", + "ca09282238d492029afbd30ea9b4aa9d448d77b4b41a791c35ebe3f8e5034ac71210117a843fae647cea020712c27e5c8f85acf933d5e28430c7770862d8dbb197cbbcfe49dd63f6aa05fbd13e32c459342698dfee5935c7c321", + "5c5223c8eda59a8dc28b08e6c21482a46e5d84d32c7050bf144fc57f4e8094de133198da7b4b8398b167204aff837da15d9ab2", + "378885950a4491bee3cd681d3c957b9a", + }, + { + "4d07f78d19e6d8bb32bf209f138307890f0f1ae39362779ff2bf1f9b734fe653", + "d983a5d5af78a3b1cd5fbd58", + "94f0bbc4340d97d854e25cc7ce85ea1e781e68bf6f639e0a981bb03e3c209cbf5127171cb0fff65bc3ecac92774d10146d1ac5", + "a3dc9ff9210bc4b3276909883db2c2aa0762cd22b46901a248c0372d073e7778b9c1d8469b26bb42406e484ef7747f71dea785fc0020a2eac17e0ac3fbe0453629efd68d5678fbecc10af8ffbe7828f826defb638763f4ecfe82", + "6543b4d97fccd273b36436fef719ac31bf0e5c4c058ea71aea2a0e5b60e329be6ea81ce386e6e9fe4480e58363c3b2036865ac", + "924cf7c0770f228a4b92e9b2a11fc70b", + }, + { + "9572b9c57abdf1caae3bebc0e4bbf9e556b5cbacca2c4756050fefd10a666155", + "de292a9858caaccdcab6a433", + "6f420a32708ccd4df0d3149e8c1d88dceba66ee4546f38db07046ebf30f47627f7fdda1dd79783adabe5f6b6853857b99b864c", + "a042d97a9b8f6caf51c5f24522d7ed83e2c5d8ec6b37ef2598134a30e57319300c3fdf92fb1d9797f5ef00971f662aae768f69f9ca0455bd6d1059d5f85b8ecb977006b833f90ac2d5bbf4498c83f4d1a42584c0dfc4a2e2453c", + "a9af961d61ab578cc1348eb6f729603f481c5d9bf9bee3a13eda022bd09c03a4f207c21c45c0232a9742ae8f0c54b4278a3a63", + "eff9bb26156ec76f0060cd93a959e055", + }, + { + "3cc8671c4d25c3cbc887f4dcbd64e531e91cf6252f6ee9c29d9988d20ab6747f", + "f960a09c0b5067280926a9c3", + "5b58717b0b32076566b58bf37c6133e61468b2be67715fb0007fe390c4b5578decf55502a4e3c12e7bdf0ba98784d126e4753a", + "79d73a7ff86698e6114a0f465373fbee029e042424c439b22e3ad37b36b9e02bab82e16844114e99e39c169f462fe61b87c4627c394384acc9531680706e4e56491a304c6075cca37c64db24468c1fb9519605c83f0ee3e0316a", + "1d0be097470c1ac30619f63c3961152ab27db88ce694b7bba4db185cb31803cc7bab890e931c90766621bfe5d887eb0cd6995d", + "dbd57ea091ff16fc7dbc5435030cc74e", + }, + { + "882068be4552d7ad224fc8fa2af00d6abf76ccf1a7689d75f6f0e9bd82c1215e", + "890a5315992f12674d1c8018", + "8464c03e0280cb1f63c054a24a050e980f60cc7313f09f2092c45d77bbe9ad2a8c1f6cdca2acd8c57c87e887edadb66bcb66c4", + "916721df816b1cad531dee8e4a8e634d43ed87db99609bcc986d16bfac2cff577d536d749a5c3625de53c5351825c228911f0a64be1fc9738a26394efe5332c0762bf59b65d3f1c5aafa9ca2e63eccd59568e6c0269950911a71", + "020e297d907177dba12dde4bfe1b0ff9b6a9d9db0695193e4181449e157137b59b488616ba151b06d889f8498ce373d2396ab9", + "e48537ecb27460b477a6e7c3463dbcb0", + }, + { + "4deadcf0f7e19231f8afcb6fb902b105bef23f2fa9323a51833ff8368ccb4f91", + "6d4d01abd587ed110e512ed2", + "75686e0fdd3fd96f3e6dfafd7a2a907f9f375d93943cb2229bd72b032bf624af4fc72071289386e3dccc45959e47ab42b261a2", + "31a2797318104b2dc9977e599435b041c56bafe5e7d901a58614c2d3fb9d220e3fd3e2828cef69e0604ed73340cb1e21967294dcd874893942442200b2a5b860ee8cf91e1d8eb3d364d0e43e84f6379f434a1ae17c236b216842", + "8feaf9a089599812117a67aed2f4bf3431ff1f6cfd64ea5ff475287abb4ff1ab6b3e4f8a55d1c6b3f08594f403e771ec7e9956", + "5040407621712e053591179e1689698e", + }, + { + "80f1c515f10d79cdbee275213aa9ac0845e2cf42874f7e695081cb103abf1a27", + "399d5f9b218b62ff60c267bd", + "9e95221873f65282dd1ec75494d2500e62a2b6edda5a6f33b3d4dd7516ef25cf4154472e61c6aed2749c5a7d86637052b00f54", + "d2a8fff8ae24a6a5efc75764549a765222df317e323a798cbb8a23d1af8fdf8a3b767f55703b1c0feba3912d4234441978191262f1999c69caa4e9a3e0454c143af0022cd6e44cec14149f9e9964a1f2c5e5a6e3e768bd870060", + "4f996562e23ebbfd4fe26523aee9525b13d6e134e72d21bdc7f195c6403501fd8300b6e597b668f199f93591ba742a91b54454", + "2da1c7325f58575d275abf96c7fa9e51", + }, + { + "c2c6e9be5a480a4a56bfcd0e268faa2276093bd1f7e8ce61e746d003decc761e", + "c1541eb25721d4856df8f928", + "87d22e0318fbbb420b86b0585bd12c14645ff2c742e5639b3a114cc96c5f738edfbe2055116f259e3d6c14cb6d8fca45708289", + "f34e79e5fe437eda03ccfef2f1d6319df51a71c9891863e4b98a7298bd64490460354db5a28b0fadcb815024ea17f3b84810e27954afb1fdf44f0defb930b1793684a781310b9af95b4bcf0a727a2cb0ac529b805811b3721d98", + "b5d6e57c7aa0240e0b6e332d3b3323b525a3d8a553ad041ba599e909188da537c3293d1687fb967882d16a5615b84e95f9dd77", + "1cce334cec4b51216cac0fc620cdadf9", + }, + { + "ea0d6184a71456e27f9ac82dfc7f6694c898f7c0d19d1cb0db4e575dd0094bb6", + "5018fb816d515511bfb939d5", + "083147d0c80f134f7393855c8a95bf6e6abd6f9a7b1fca584e8bfc6b5dc13a8edbfd473e232c041d9be9ee7709dc86b3aa320a", + "8bc6bd0a263212bd7281fd1a45e512fca104f859358eae9293a297c529a0abaffd8a77507b9069040f2b3141a7620691e110a8b593b956d8e3e71694506b89018a03861c1ba6082687adce15a874c73477430cef075eba077a93", + "f0a5c4941782e2f2941dd05acee29b65341773f2e8d51935a3f4fa6f268ff030c880976cf1ee858f6571abd8411b695a2fadf0", + "067d8cc2d38c30697272daa00c7f70cf", + }, + { + "c624feb6cb0d78d634b627134c692f0bf5debf84d8639e22ff27ce2ace49d438", + "a54f4f1204255f6b312222cd", + "ec34f45c1b70fd56518cc5c404cc13330ab7d51c10f4d2cfeb26b097ae76897191ec1b3953b0086e425c7da221d29f65d5ccf3", + "d9099ba6be50dca77e0b9803766ad993132479fbab43b8f4126a7f9ef673ac0caf2de235e1e84ad9fe505c43d1ac779f5072c025c14ea0d930ce39db8c5930baada23b3e4654470e559fcb6eb1c133a77318b87cc7913e12d404", + "713d28a5123d65e82cca6e7fd919e1e5e3bdaab12ae715cf8b7c974eb5f62be8c3b42637074c6b891f6c6033eb4b7e61db9f0b", + "01ededff6e4d1dce4ac790218e208ebe", + }, + { + "1afc68b32596198ae0f3a8612751c2413322e8054ff2ac6bede3d4a1ee20ee62", + "356860e76e794492de6a68f3", + "293041038f9e8edee23d2f18bce87b522380f1fa18b3021830a54ab891da8548095228ed9860176152e27945d66254f0db8590", + "205e44009e0ef963838aff615b35c9f1271d487cf719677d956718bce8ab676cceb636ad381432c5c790c26b07051b661a2fec4e607f9644f84993c8335db21ae36b6008bab2883ad7541809bf5f49272295c1c1f1cf8c678553", + "e06109680d5fefd345665ec9a5b2e7bf3ece3af1b62841a95c453e7753b5a1d6d8a10b3c6c42df1f23832b74e74871821f1c0b", + "953d8d04f70e2af055ac902a455235b2", + }, + { + "f61b723359e798fefecc26b10b168dc331c639079598f1f651166cc58c671ee1", + "b07e9407b592d4fd95509343", + "2724f1ad6b5b409a59c7f2ff649eb24b4a33a03d7a0426e29a6ea3aa91b4f00699fbed75bb7189964303e2e9fe3a7e5f74b7a1", + "1429c6f27828cb94ad5e62451da10fd574660cec2b8f279a19bbb8a167a630d3ac60db04e8faa02204792e49aed4501844a419d3ecdff0d03799866fee81a91187b08a44d5bb617ff3b2cef79cd48750ea20903e1d3627a17730", + "362bad8de943dce8f53edf682d02e1d893c23c5272b13fd35b492f8477083a8c34027db32b6131931f03555ac5fbc6dbb13801", + "a51775606343755691f125019b44fdfc", + }, + { + "6be7f4d18ff0fbdd9b3b3cacaba4629a0c617387079add62f6ce1584b33faad1", + "fda568c9cb13d9c176bcef03", + "4df668e99d5068604a48bcca5baa8245435928558a83d68d7b0b081861224e9bd39ea8f2d55a635949e66c6f6a7ff5cc34dd94", + "11ebeb97dd4a9925c1fbe2b9af77392058d2d971e42db15da39f090d7bc132573c34bf7d92a2d72dc66ee6840c3ff07985b8976ee8d8f36bf47ae330b899fdc60652dd5a23c45f3680f11951f019e0697c8acfcaa95f01b9c7dd", + "488b40ad594e1845ccdd9e9467fc5e1afbbfde34e57d45bfcd30b61cc326d57fe8e3f31a39cdebf00f60bbd2c3cdf69f756eff", + "3bf3fbab9b48486fd08a5552604df639", + }, + { + "83C093B58DE7FFE1C0DA926AC43FB3609AC1C80FEE1B624497EF942E2F79A823", + "7CFDE9F9E33724C68932D612", + "", + "84C5D513D2AAF6E5BBD2727788E523008932D6127CFDE9F9E33724C608000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F0005", + "", + "6EE160E8FAECA4B36C86B234920CA975" + }, + { + "4C973DBC7364621674F8B5B89E5C15511FCED9216490FB1C1A2CAA0FFE0407E5", + "7AE8E2CA4EC500012E58495C", + "08000F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748490008", + "68F2E77696CE7AE8E2CA4EC588E54D002E58495C", + "BA8AE31BC506486D6873E4FCE460E7DC57591FF00611F31C3834FE1C04AD80B66803AFCF5B27E6333FA67C99DA47C2F0CED68D531BD741A943CFF7A6713BD0", + "2611CD7DAA01D61C5C886DC1A8170107" + }, + { + "0000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000", + "", + "d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad", + "", + "f4c58f80a3a1a9cd52755214bdbb6ad0" + }, + { + "0000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "", + "cea7403d4d606b6e074ec5d3baf39d18726003ca37a62a74d1a2f58e7506358edd4ab1284d4ae17b41e85924470c36f7", + "0eb41c52b074ecacb213f6de062f7897" + }, + { + "0000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "", + "cea7403d4d606b6e074ec5d3baf39d18726003ca37a62a74d1a2f58e7506358edd4ab1284d4ae17b41e85924470c36f74741cbe181bb7f30617c1de3ab0c3a1fd0c48f7321a82d376095ace0419167a0bcaf49b0c0cea62de6bc1c66545e1dadabfa77cd6e85da245fb0bdc5e52cfc29ba0ae1ab2837e0f36387b70e93176012", + "ae1753b346fd6971d20cb69a2d6148bc" + }, + { + "0000000000000000000000000000000000000000000000000000000000000000", + "ffffffff0000000000000000", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "", + "ee2491af7588cbd4ccccaea18a6118cdf00222178a0b53be8a7a0ef9806991a81c70151316ef97ffea3d83e8905d933c253b56a63f115a2cd4005281bfbdd9a07a1b19d7e07caf3f90a11228785d7bf749449598214a4222c3c476ea5df9d60250b8d66787b568762a5cb70149e2957c1cc5ef636113b1e1752096ec404fe2b6", + "0c23c9176aedc5bacbca56f777324aa4" + }, + { + "0000000000000000000000000000000000000000000000000000000000000000", + "ffffffffffffffffffffffff", + "010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002", + "0102030405060708090a0b0c0d", + "d3b089dead85b8b6874327390d0fff1575051e2a96243ab8ca0927447f58d7053d99918491eeeee470cd929077ccb404ef140354241e12e2e36e3aea89a06e79c064479d7cdd711220dff6059ab913a1ea3ba7bcdb2d5b8746a990ec54cf2aab55c11c9c849ab552fc03cc4425db4e54b13d334e9ef145805c73680d7899b64bab", + "c9ee768b5473f678ac00203affa6a34e" + }, + { + "843ffcf5d2b72694d19ed01d01249412d5cb4a08f134d246513633e84d006bbb", + "dbcca32ebf9b804617c3aa9e", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f", + "00000000000000000000000000000000101112131415161718191a1b1c1d1e1f", + "3847bb9e60181f62ba36beae09cc3cfeb5958a16e37c72e87add8be814ee6dbbb98c0727709c84d26a6adf5e7b4e17cdfd84977b328d3eda489a30ff8d1875b530239d4abaf15a5903f516cac0c91b3a", + "39fa8fc1c78405e86326c97d428cd1c6" + } +}; + +static int +tv(void) +{ + unsigned char *ad; + unsigned char *ciphertext; + unsigned char *decrypted; + unsigned char *detached_ciphertext; + unsigned char *expected_ciphertext; + unsigned char *key; + unsigned char *message; + unsigned char *mac; + unsigned char *nonce; + char *hex; + unsigned long long found_ciphertext_len; + unsigned long long found_mac_len; + unsigned long long found_message_len; + size_t ad_len; + size_t ciphertext_len; + size_t detached_ciphertext_len; + size_t i = 0U; + size_t message_len; + + key = (unsigned char *) sodium_malloc(crypto_aead_aes256gcm_KEYBYTES); + nonce = (unsigned char *) sodium_malloc(crypto_aead_aes256gcm_NPUBBYTES); + mac = (unsigned char *) sodium_malloc(crypto_aead_aes256gcm_ABYTES); + + do { + assert(strlen(tests[i].key_hex) == 2 * crypto_aead_aes256gcm_KEYBYTES); + sodium_hex2bin(key, crypto_aead_aes256gcm_KEYBYTES, + tests[i].key_hex, strlen(tests[i].key_hex), + NULL, NULL, NULL); + assert(strlen(tests[i].nonce_hex) == 2 * crypto_aead_aes256gcm_NPUBBYTES); + sodium_hex2bin(nonce, crypto_aead_aes256gcm_NPUBBYTES, + tests[i].nonce_hex, strlen(tests[i].nonce_hex), + NULL, NULL, NULL); + message_len = strlen(tests[i].message_hex) / 2; + message = (unsigned char *) sodium_malloc(message_len); + sodium_hex2bin(message, message_len, + tests[i].message_hex, strlen(tests[i].message_hex), + NULL, NULL, NULL); + ad_len = strlen(tests[i].ad_hex) / 2; + ad = (unsigned char *) sodium_malloc(ad_len); + sodium_hex2bin(ad, ad_len, + tests[i].ad_hex, strlen(tests[i].ad_hex), + NULL, NULL, NULL); + ciphertext_len = message_len + crypto_aead_aes256gcm_ABYTES; + detached_ciphertext_len = message_len; + expected_ciphertext = (unsigned char *) sodium_malloc(ciphertext_len); + assert(strlen(tests[i].ciphertext_hex) == 2 * message_len); + sodium_hex2bin(expected_ciphertext, message_len, + tests[i].ciphertext_hex, strlen(tests[i].ciphertext_hex), + NULL, NULL, NULL); + assert(strlen(tests[i].mac_hex) == 2 * crypto_aead_aes256gcm_ABYTES); + sodium_hex2bin(expected_ciphertext + message_len, crypto_aead_aes256gcm_ABYTES, + tests[i].mac_hex, strlen(tests[i].mac_hex), + NULL, NULL, NULL); + ciphertext = (unsigned char *) sodium_malloc(ciphertext_len); + detached_ciphertext = (unsigned char *) sodium_malloc(detached_ciphertext_len); + + crypto_aead_aes256gcm_encrypt_detached(detached_ciphertext, mac, + &found_mac_len, + message, message_len, + ad, ad_len, NULL, nonce, key); + assert(found_mac_len == crypto_aead_aes256gcm_ABYTES); + if (memcmp(detached_ciphertext, expected_ciphertext, + detached_ciphertext_len) != 0 || + memcmp(mac, expected_ciphertext + message_len, + crypto_aead_aes256gcm_ABYTES) != 0) { + printf("Detached encryption of test vector #%u failed\n", (unsigned int) i); + hex = (char *) sodium_malloc((size_t) ciphertext_len * 2 + 1); + sodium_bin2hex(hex, (size_t) ciphertext_len * 2 + 1, + ciphertext, ciphertext_len); + printf("Computed: [%s]\n", hex); + sodium_free(hex); + } + + crypto_aead_aes256gcm_encrypt(ciphertext, &found_ciphertext_len, + message, message_len, + ad, ad_len, NULL, nonce, key); + + assert((size_t) found_ciphertext_len == ciphertext_len); + if (memcmp(ciphertext, expected_ciphertext, ciphertext_len) != 0) { + printf("Encryption of test vector #%u failed\n", (unsigned int) i); + hex = (char *) sodium_malloc((size_t) found_ciphertext_len * 2 + 1); + sodium_bin2hex(hex, (size_t) found_ciphertext_len * 2 + 1, + ciphertext, ciphertext_len); + printf("Computed: [%s]\n", hex); + sodium_free(hex); + } + + decrypted = (unsigned char *) sodium_malloc(message_len); + found_message_len = 1; + if (crypto_aead_aes256gcm_decrypt(decrypted, &found_message_len, + NULL, ciphertext, + randombytes_uniform((uint32_t) ciphertext_len), + ad, ad_len, nonce, key) != -1) { + printf("Verification of test vector #%u after truncation succeeded\n", + (unsigned int) i); + } + if (found_message_len != 0) { + printf("Message length should have been set to zero after a failure\n"); + } + if (crypto_aead_aes256gcm_decrypt(decrypted, &found_message_len, + NULL, guard_page, + randombytes_uniform(crypto_aead_aes256gcm_ABYTES), + ad, ad_len, nonce, key) != -1) { + printf("Verification of test vector #%u with a truncated tag failed\n", + (unsigned int) i); + } + if (i == 0 && crypto_aead_aes256gcm_decrypt(NULL, NULL, + NULL, ciphertext, ciphertext_len, + ad, ad_len, nonce, key) != 0) { + printf("Verification of test vector #%u's tag failed\n", (unsigned int) i); + } + if (crypto_aead_aes256gcm_decrypt(decrypted, &found_message_len, + NULL, ciphertext, ciphertext_len, + ad, ad_len, nonce, key) != 0) { + printf("Verification of test vector #%u failed\n", (unsigned int) i); + } + assert((size_t) found_message_len == message_len); + if (memcmp(decrypted, message, message_len) != 0) { + printf("Incorrect decryption of test vector #%u\n", (unsigned int) i); + } + memset(decrypted, 0xd0, message_len); + if (crypto_aead_aes256gcm_decrypt_detached(decrypted, + NULL, detached_ciphertext, + detached_ciphertext_len, + mac, ad, ad_len, nonce, key) != 0) { + printf("Detached verification of test vector #%u failed\n", (unsigned int) i); + } + if (memcmp(decrypted, message, message_len) != 0) { + printf("Incorrect decryption of test vector #%u\n", (unsigned int) i); + } + + sodium_free(message); + sodium_free(ad); + sodium_free(expected_ciphertext); + sodium_free(ciphertext); + sodium_free(decrypted); + sodium_free(detached_ciphertext); + } while (++i < (sizeof tests) / (sizeof tests[0])); + + sodium_free(key); + sodium_free(mac); + sodium_free(nonce); + + return 0; +} + +int +main(void) +{ + if (crypto_aead_aes256gcm_is_available()) { + tv(); + } + assert(crypto_aead_aes256gcm_keybytes() == crypto_aead_aes256gcm_KEYBYTES); + assert(crypto_aead_aes256gcm_nsecbytes() == crypto_aead_aes256gcm_NSECBYTES); + assert(crypto_aead_aes256gcm_npubbytes() == crypto_aead_aes256gcm_NPUBBYTES); + assert(crypto_aead_aes256gcm_abytes() == crypto_aead_aes256gcm_ABYTES); + assert(crypto_aead_aes256gcm_statebytes() >= sizeof(crypto_aead_aes256gcm_state)); + assert(crypto_aead_aes256gcm_messagebytes_max() == crypto_aead_aes256gcm_MESSAGEBYTES_MAX); + printf("OK\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/aead_aes256gcm.exp b/external/src/libsodium/test/default/aead_aes256gcm.exp new file mode 100644 index 0000000..d86bac9 --- /dev/null +++ b/external/src/libsodium/test/default/aead_aes256gcm.exp @@ -0,0 +1 @@ +OK diff --git a/external/src/libsodium/test/default/aead_aes256gcm2.c b/external/src/libsodium/test/default/aead_aes256gcm2.c new file mode 100644 index 0000000..43170b5 --- /dev/null +++ b/external/src/libsodium/test/default/aead_aes256gcm2.c @@ -0,0 +1,276 @@ + +#define TEST_NAME "aead_aes256gcm2" +#include "cmptest.h" + +static struct { + const char *key_hex; + const char nonce_hex[crypto_aead_aes256gcm_NPUBBYTES * 2 + 1]; + const char *ad_hex; + const char *message_hex; + const char *detached_ciphertext_hex; + const char mac_hex[crypto_aead_aes256gcm_ABYTES * 2 + 1]; + const char *outcome; +} tests[] = { + { "92ace3e348cd821092cd921aa3546374299ab46209691bc28b8752d17f123c20", + "00112233445566778899aabb", "00000000ffffffff", "00010203040506070809", + "e27abdd2d2a53d2f136b", "9a4a2579529301bcfb71c78d4060f52c", "valid" }, + { "29d3a44f8723dc640239100c365423a312934ac80239212ac3df3421a2098123", + "00112233445566778899aabb", "aabbccddeeff", "", "", + "2a7d77fa526b8250cb296078926b5020", "valid" }, + { "cc56b680552eb75008f5484b4cb803fa5063ebd6eab91f6ab6aef4916a766273", + "99e23ec48985bccdeeab60f1", "", "2a", "06", + "633c1e9703ef744ffffb40edf9d14355", "valid" }, + { "51e4bf2bad92b7aff1a4bc05550ba81df4b96fabf41c12c7b00e60e48db7e152", + "4f07afedfdc3b6c2361823d3", "", "be3308f72a2c6aed", "cf332a12fdee800b", + "602e8d7c4799d62c140c9bb834876b09", "valid" }, + { "67119627bd988eda906219e08c0d0d779a07d208ce8a4fe0709af755eeec6dcb", + "68ab7fdbf61901dad461d23c", "", "51f8c1f731ea14acdb210a6d973e07", + "43fc101bff4b32bfadd3daf57a590e", "ec04aacb7148a8b8be44cb7eaf4efa69", + "valid" }, + { "59d4eafb4de0cfc7d3db99a8f54b15d7b39f0acc8da69763b019c1699f87674a", + "2fcb1b38a99e71b84740ad9b", "", "549b365af913f3b081131ccb6b825588", + "f58c16690122d75356907fd96b570fca", "28752c20153092818faba2a334640d6e", + "valid" }, + { "3b2458d8176e1621c0cc24c0c0e24c1e80d72f7ee9149a4b166176629616d011", + "45aaa3e5d16d2d42dc03445d", "", "3ff1514b1c503915918f0c0c31094a6e1f", + "73a6b6f45f6ccc5131e07f2caa1f2e2f56", "2d7379ec1db5952d4e95d30c340b1b1d", + "valid" }, + { "0212a8de5007ed87b33f1a7090b6114f9e08cefd9607f2c276bdcfdbc5ce9cd7", + "e6b1adf2fd58a8762c65f31b", "", + "10f1ecf9c60584665d9ae5efe279e7f7377eea6916d2b111", + "0843fff52d934fc7a071ea62c0bd351ce85678cde3ea2c9e", + "7355fde599006715053813ce696237a8", "valid" }, + { "b279f57e19c8f53f2f963f5f2519fdb7c1779be2ca2b3ae8e1128b7d6c627fc4", + "98bc2c7438d5cd7665d76f6e", "c0", + "fcc515b294408c8645c9183e3f4ecee5127846d1", + "eb5500e3825952866d911253f8de860c00831c81", + "ecb660e1fb0541ec41e8d68a64141b3a", "valid" }, + { "cdccfe3f46d782ef47df4e72f0c02d9c7f774def970d23486f11a57f54247f17", + "376187894605a8d45e30de51", "956846a209e087ed", + "e28e0e9f9d22463ac0e42639b530f42102fded75", + "feca44952447015b5df1f456df8ca4bb4eee2ce2", + "082e91924deeb77880e1b1c84f9b8d30", "valid" }, + { "f32364b1d339d82e4f132d8f4a0ec1ff7e746517fa07ef1a7f422f4e25a48194", + "5a86a50a0e8a179c734b996d", "ab2ac7c44c60bdf8228c7884adb20184", + "43891bccb522b1e72a6b53cf31c074e9d6c2df8e", + "43dda832e942e286da314daa99bef5071d9d2c78", + "c3922583476ced575404ddb85dd8cd44", "valid" }, + { "ff0089ee870a4a39f645b0a5da774f7a5911e9696fc9cad646452c2aa8595a12", + "bc2a7757d0ce2d8b1f14ccd9", + "972ab4e06390caae8f99dd6e2187be6c7ff2c08a24be16ef", + "748b28031621d95ee61812b4b4f47d04c6fc2ff3", + "a929ee7e67c7a2f91bbcec6389a3caf43ab49305", + "ebec6774b955e789591c822dab739e12", "valid" }, + { "00112233445566778899aabbccddeeff102132435465768798a9bacbdcedfe0f", + "000000000000000000000000", "", "561008fa07a68f5c61285cd013464eaf", + "23293e9b07ca7d1b0cae7cc489a973b3", "ffffffffffffffffffffffffffffffff", + "valid" }, + { "00112233445566778899aabbccddeeff102132435465768798a9bacbdcedfe0f", + "ffffffffffffffffffffffff", "", "c6152244cea1978d3e0bc274cf8c0b3b", + "7cb6fc7c6abc009efe9551a99f36a421", "00000000000000000000000000000000", + "valid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9de8fef6d8ab1bf1bf887232eab590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ee8fef6d8ab1bf1bf887232eab590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "1ce8fef6d8ab1bf1bf887232eab590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce9fef6d8ab1bf1bf887232eab590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fe76d8ab1bf1bf887232eab590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fef6d9ab1bf1bf887232eab590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fef6daab1bf1bf887232eab590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fef6d8ab1b71bf887232eab590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fef6d8ab1bf1be887232eab590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fef6d8ab1bf13f887232eab590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fef6d8ab1bf1bfa87232eab590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fef6d8ab1bf1bf887332eab590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fef6d8ab1bf1bf887232ebb590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fef6d8ab1bf1bf887232e8b590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fef6d8ab1bf1bf8872326ab590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fef6d8ab1bf1bf887232eab590dc", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fef6d8ab1bf1bf887232eab590df", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fef6d8ab1bf1bf887232eab5909d", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fef6d8ab1bf1bf887232eab5905d", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9de8fef6d8ab1bf1be887232eab590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fe76d8ab1b71bf887232eab590dd", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9ce8fef6d8ab1b71bf887232eab5905d", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "631701092754e40e40778dcd154a6f22", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "00000000000000000000000000000000", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "ffffffffffffffffffffffffffffffff", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "1c687e76582b9b713f08f2b26a35105d", + "invalid" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "505152535455565758595a5b", "", "202122232425262728292a2b2c2d2e2f", + "b2061457c0759fc1749f174ee1ccadfa", "9de9fff7d9aa1af0be897333ebb491dc", + "invalid" } +}; + +static int +tv(void) +{ + unsigned char *ad; + unsigned char *decrypted; + unsigned char *detached_ciphertext; + unsigned char *key; + unsigned char *message; + unsigned char *mac; + unsigned char *nonce; + size_t ad_len; + size_t detached_ciphertext_len; + size_t message_len; + unsigned int i; + + key = (unsigned char *) sodium_malloc(crypto_aead_aes256gcm_KEYBYTES); + nonce = (unsigned char *) sodium_malloc(crypto_aead_aes256gcm_NPUBBYTES); + mac = (unsigned char *) sodium_malloc(crypto_aead_aes256gcm_ABYTES); + + for (i = 0U; i < (sizeof tests) / (sizeof tests[0]); i++) { + assert(strlen(tests[i].key_hex) == 2 * crypto_aead_aes256gcm_KEYBYTES); + sodium_hex2bin(key, crypto_aead_aes256gcm_KEYBYTES, tests[i].key_hex, + strlen(tests[i].key_hex), NULL, NULL, NULL); + + assert(strlen(tests[i].nonce_hex) == + 2 * crypto_aead_aes256gcm_NPUBBYTES); + sodium_hex2bin(nonce, crypto_aead_aes256gcm_NPUBBYTES, + tests[i].nonce_hex, strlen(tests[i].nonce_hex), NULL, + NULL, NULL); + + message_len = strlen(tests[i].message_hex) / 2; + message = (unsigned char *) sodium_malloc(message_len); + sodium_hex2bin(message, message_len, tests[i].message_hex, + strlen(tests[i].message_hex), NULL, NULL, NULL); + + ad_len = strlen(tests[i].ad_hex) / 2; + ad = (unsigned char *) sodium_malloc(ad_len); + sodium_hex2bin(ad, ad_len, tests[i].ad_hex, strlen(tests[i].ad_hex), + NULL, NULL, NULL); + + detached_ciphertext_len = message_len; + assert(strlen(tests[i].detached_ciphertext_hex) == 2 * message_len); + assert(strlen(tests[i].mac_hex) == 2 * crypto_aead_aes256gcm_ABYTES); + sodium_hex2bin(mac, crypto_aead_aes256gcm_ABYTES, tests[i].mac_hex, + strlen(tests[i].mac_hex), NULL, NULL, NULL); + + detached_ciphertext = + (unsigned char *) sodium_malloc(detached_ciphertext_len); + sodium_hex2bin(detached_ciphertext, detached_ciphertext_len, + tests[i].detached_ciphertext_hex, + strlen(tests[i].detached_ciphertext_hex), NULL, NULL, + NULL); + + decrypted = (unsigned char *) sodium_malloc(message_len); + if (crypto_aead_aes256gcm_decrypt_detached( + decrypted, NULL, detached_ciphertext, detached_ciphertext_len, + mac, ad, ad_len, nonce, key) == 0) { + if (strcmp(tests[i].outcome, "valid") != 0) { + printf("*** test case %u succeeded, was supposed to be %s\n", i, + tests[i].outcome); + } + if (memcmp(decrypted, message, message_len) != 0) { + printf("Incorrect decryption of test vector #%u\n", + (unsigned int) i); + } + } else { + if (strcmp(tests[i].outcome, "invalid") != 0) { + printf("*** test case %u failed, was supposed to be %s\n", i, + tests[i].outcome); + } + } + + sodium_free(message); + sodium_free(ad); + sodium_free(decrypted); + sodium_free(detached_ciphertext); + } + + sodium_free(key); + sodium_free(mac); + sodium_free(nonce); + + return 0; +} + +int +main(void) +{ + if (crypto_aead_aes256gcm_is_available()) { + tv(); + } + printf("OK\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/aead_aes256gcm2.exp b/external/src/libsodium/test/default/aead_aes256gcm2.exp new file mode 100644 index 0000000..d86bac9 --- /dev/null +++ b/external/src/libsodium/test/default/aead_aes256gcm2.exp @@ -0,0 +1 @@ +OK diff --git a/external/src/libsodium/test/default/aead_chacha20poly1305.c b/external/src/libsodium/test/default/aead_chacha20poly1305.c new file mode 100644 index 0000000..0a01afe --- /dev/null +++ b/external/src/libsodium/test/default/aead_chacha20poly1305.c @@ -0,0 +1,372 @@ + +#define TEST_NAME "aead_chacha20poly1305" +#include "cmptest.h" + +static int +tv(void) +{ +#undef MLEN +#define MLEN 10U +#undef ADLEN +#define ADLEN 10U +#undef CLEN +#define CLEN (MLEN + crypto_aead_chacha20poly1305_ABYTES) + static const unsigned char firstkey[crypto_aead_chacha20poly1305_KEYBYTES] + = { 0x42, 0x90, 0xbc, 0xb1, 0x54, 0x17, 0x35, 0x31, 0xf3, 0x14, 0xaf, + 0x57, 0xf3, 0xbe, 0x3b, 0x50, 0x06, 0xda, 0x37, 0x1e, 0xce, 0x27, + 0x2a, 0xfa, 0x1b, 0x5d, 0xbd, 0xd1, 0x10, 0x0a, 0x10, 0x07 }; + static const unsigned char m[MLEN] + = { 0x86, 0xd0, 0x99, 0x74, 0x84, 0x0b, 0xde, 0xd2, 0xa5, 0xca }; + static const unsigned char nonce[crypto_aead_chacha20poly1305_NPUBBYTES] + = { 0xcd, 0x7c, 0xf6, 0x7b, 0xe3, 0x9c, 0x79, 0x4a }; + static const unsigned char ad[ADLEN] + = { 0x87, 0xe2, 0x29, 0xd4, 0x50, 0x08, 0x45, 0xa0, 0x79, 0xc0 }; + unsigned char *c = (unsigned char *) sodium_malloc(CLEN); + unsigned char *detached_c = (unsigned char *) sodium_malloc(MLEN); + unsigned char *mac = (unsigned char *) sodium_malloc(crypto_aead_chacha20poly1305_ABYTES); + unsigned char *m2 = (unsigned char *) sodium_malloc(MLEN); + unsigned long long found_clen; + unsigned long long found_maclen; + unsigned long long m2len; + size_t i; + + crypto_aead_chacha20poly1305_encrypt(c, &found_clen, m, MLEN, + ad, ADLEN, + NULL, nonce, firstkey); + if (found_clen != CLEN) { + printf("found_clen is not properly set\n"); + } + for (i = 0U; i < CLEN; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + printf("\n"); + crypto_aead_chacha20poly1305_encrypt_detached(detached_c, + mac, &found_maclen, + m, MLEN, ad, ADLEN, + NULL, nonce, firstkey); + if (found_maclen != crypto_aead_chacha20poly1305_abytes()) { + printf("found_maclen is not properly set\n"); + } + if (memcmp(detached_c, c, MLEN) != 0) { + printf("detached ciphertext is bogus\n"); + } + + if (crypto_aead_chacha20poly1305_decrypt(m2, &m2len, NULL, c, CLEN, + ad, ADLEN, + nonce, firstkey) != 0) { + printf("crypto_aead_chacha20poly1305_decrypt() failed\n"); + } + if (m2len != MLEN) { + printf("m2len is not properly set\n"); + } + if (memcmp(m, m2, MLEN) != 0) { + printf("m != m2\n"); + } + memset(m2, 0, m2len); + assert(crypto_aead_chacha20poly1305_decrypt_detached(NULL, NULL, + c, MLEN, mac, + ad, ADLEN, + nonce, firstkey) == 0); + if (crypto_aead_chacha20poly1305_decrypt_detached(m2, NULL, + c, MLEN, mac, + ad, ADLEN, + nonce, firstkey) != 0) { + printf("crypto_aead_chacha20poly1305_decrypt_detached() failed\n"); + } + if (memcmp(m, m2, MLEN) != 0) { + printf("detached m != m2\n"); + } + + for (i = 0U; i < CLEN; i++) { + c[i] ^= (i + 1U); + if (crypto_aead_chacha20poly1305_decrypt(m2, NULL, NULL, c, CLEN, + ad, ADLEN, nonce, firstkey) + == 0 || memcmp(m, m2, MLEN) == 0) { + printf("message can be forged\n"); + } + c[i] ^= (i + 1U); + } + + crypto_aead_chacha20poly1305_encrypt(c, &found_clen, m, MLEN, + NULL, 0U, NULL, nonce, firstkey); + if (found_clen != CLEN) { + printf("found_clen is not properly set (adlen=0)\n"); + } + for (i = 0U; i < CLEN; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + printf("\n"); + + if (crypto_aead_chacha20poly1305_decrypt(m2, &m2len, NULL, c, CLEN, + NULL, 0U, nonce, firstkey) != 0) { + printf("crypto_aead_chacha20poly1305_decrypt() failed (adlen=0)\n"); + } + if (m2len != MLEN) { + printf("m2len is not properly set (adlen=0)\n"); + } + if (memcmp(m, m2, MLEN) != 0) { + printf("m != m2 (adlen=0)\n"); + } + m2len = 1; + if (crypto_aead_chacha20poly1305_decrypt( + m2, &m2len, NULL, guard_page, + randombytes_uniform(crypto_aead_chacha20poly1305_ABYTES), + NULL, 0U, nonce, firstkey) != -1) { + printf("crypto_aead_chacha20poly1305_decrypt() worked with a short " + "ciphertext\n"); + } + if (m2len != 0) { + printf("Message length should have been set to zero after a failure\n"); + } + m2len = 1; + if (crypto_aead_chacha20poly1305_decrypt(m2, &m2len, NULL, c, 0U, NULL, 0U, + nonce, firstkey) != -1) { + printf("crypto_aead_chacha20poly1305_decrypt() worked with an empty " + "ciphertext\n"); + } + if (m2len != 0) { + printf("Message length should have been set to zero after a failure\n"); + } + + memcpy(c, m, MLEN); + crypto_aead_chacha20poly1305_encrypt(c, &found_clen, c, MLEN, + NULL, 0U, NULL, nonce, firstkey); + if (found_clen != CLEN) { + printf("found_clen is not properly set (adlen=0)\n"); + } + for (i = 0U; i < CLEN; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + printf("\n"); + + if (crypto_aead_chacha20poly1305_decrypt(c, &m2len, NULL, c, CLEN, + NULL, 0U, nonce, firstkey) != 0) { + printf("crypto_aead_chacha20poly1305_decrypt() failed (adlen=0)\n"); + } + if (m2len != MLEN) { + printf("m2len is not properly set (adlen=0)\n"); + } + if (memcmp(m, c, MLEN) != 0) { + printf("m != c (adlen=0)\n"); + } + + sodium_free(c); + sodium_free(detached_c); + sodium_free(mac); + sodium_free(m2); + + assert(crypto_aead_chacha20poly1305_keybytes() > 0U); + assert(crypto_aead_chacha20poly1305_npubbytes() > 0U); + assert(crypto_aead_chacha20poly1305_nsecbytes() == 0U); + assert(crypto_aead_chacha20poly1305_messagebytes_max() > 0U); + assert(crypto_aead_chacha20poly1305_messagebytes_max() == crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX); + assert(crypto_aead_chacha20poly1305_keybytes() == crypto_aead_chacha20poly1305_KEYBYTES); + assert(crypto_aead_chacha20poly1305_nsecbytes() == crypto_aead_chacha20poly1305_NSECBYTES); + assert(crypto_aead_chacha20poly1305_npubbytes() == crypto_aead_chacha20poly1305_NPUBBYTES); + assert(crypto_aead_chacha20poly1305_abytes() == crypto_aead_chacha20poly1305_ABYTES); + + return 0; +} + +static int +tv_ietf(void) +{ +#undef MLEN +#define MLEN 114U +#undef ADLEN +#define ADLEN 12U +#undef CLEN +#define CLEN (MLEN + crypto_aead_chacha20poly1305_ietf_ABYTES) + static const unsigned char firstkey[crypto_aead_chacha20poly1305_ietf_KEYBYTES] + = { + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f + }; +#undef MESSAGE +#define MESSAGE "Ladies and Gentlemen of the class of '99: If I could offer you " \ +"only one tip for the future, sunscreen would be it." + unsigned char *m = (unsigned char *) sodium_malloc(MLEN); + static const unsigned char nonce[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] + = { 0x07, 0x00, 0x00, 0x00, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47 }; + static const unsigned char ad[ADLEN] + = { 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 }; + unsigned char *c = (unsigned char *) sodium_malloc(CLEN); + unsigned char *detached_c = (unsigned char *) sodium_malloc(MLEN); + unsigned char *mac = (unsigned char *) sodium_malloc(crypto_aead_chacha20poly1305_ietf_ABYTES); + unsigned char *m2 = (unsigned char *) sodium_malloc(MLEN); + unsigned long long found_clen; + unsigned long long found_maclen; + unsigned long long m2len; + size_t i; + + assert(sizeof MESSAGE - 1U == MLEN); + memcpy(m, MESSAGE, MLEN); + crypto_aead_chacha20poly1305_ietf_encrypt(c, &found_clen, m, MLEN, + ad, ADLEN, + NULL, nonce, firstkey); + if (found_clen != MLEN + crypto_aead_chacha20poly1305_ietf_abytes()) { + printf("found_clen is not properly set\n"); + } + for (i = 0U; i < CLEN; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + printf("\n"); + crypto_aead_chacha20poly1305_ietf_encrypt_detached(detached_c, + mac, &found_maclen, + m, MLEN, + ad, ADLEN, + NULL, nonce, firstkey); + if (found_maclen != crypto_aead_chacha20poly1305_ietf_abytes()) { + printf("found_maclen is not properly set\n"); + } + if (memcmp(detached_c, c, MLEN) != 0) { + printf("detached ciphertext is bogus\n"); + } + + if (crypto_aead_chacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, CLEN, ad, + ADLEN, nonce, firstkey) != 0) { + printf("crypto_aead_chacha20poly1305_ietf_decrypt() failed\n"); + } + if (m2len != MLEN) { + printf("m2len is not properly set\n"); + } + if (memcmp(m, m2, MLEN) != 0) { + printf("m != m2\n"); + } + memset(m2, 0, m2len); + assert(crypto_aead_chacha20poly1305_ietf_decrypt_detached(NULL, NULL, + c, MLEN, mac, + ad, ADLEN, + nonce, firstkey) == 0); + if (crypto_aead_chacha20poly1305_ietf_decrypt_detached(m2, NULL, + c, MLEN, mac, + ad, ADLEN, + nonce, firstkey) != 0) { + printf("crypto_aead_chacha20poly1305_ietf_decrypt_detached() failed\n"); + } + if (memcmp(m, m2, MLEN) != 0) { + printf("detached m != m2\n"); + } + + for (i = 0U; i < CLEN; i++) { + c[i] ^= (i + 1U); + if (crypto_aead_chacha20poly1305_ietf_decrypt(m2, NULL, NULL, c, CLEN, + ad, ADLEN, nonce, firstkey) + == 0 || memcmp(m, m2, MLEN) == 0) { + printf("message can be forged\n"); + } + c[i] ^= (i + 1U); + } + crypto_aead_chacha20poly1305_ietf_encrypt(c, &found_clen, m, MLEN, + NULL, 0U, NULL, nonce, firstkey); + if (found_clen != CLEN) { + printf("clen is not properly set (adlen=0)\n"); + } + for (i = 0U; i < CLEN; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + printf("\n"); + if (crypto_aead_chacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, CLEN, + NULL, 0U, nonce, firstkey) != 0) { + printf("crypto_aead_chacha20poly1305_ietf_decrypt() failed (adlen=0)\n"); + } + if (m2len != MLEN) { + printf("m2len is not properly set (adlen=0)\n"); + } + if (memcmp(m, m2, MLEN) != 0) { + printf("m != m2 (adlen=0)\n"); + } + m2len = 1; + if (crypto_aead_chacha20poly1305_ietf_decrypt( + m2, &m2len, NULL, guard_page, + randombytes_uniform(crypto_aead_chacha20poly1305_ietf_ABYTES), + NULL, 0U, nonce, firstkey) != -1) { + printf("crypto_aead_chacha20poly1305_ietf_decrypt() worked with a short " + "ciphertext\n"); + } + if (m2len != 0) { + printf("Message length should have been set to zero after a failure\n"); + } + m2len = 1; + if (crypto_aead_chacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, 0U, NULL, 0U, + nonce, firstkey) != -1) { + printf("crypto_aead_chacha20poly1305_ietf_decrypt() worked with an empty " + "ciphertext\n"); + } + if (m2len != 0) { + printf("Message length should have been set to zero after a failure\n"); + } + + memcpy(c, m, MLEN); + crypto_aead_chacha20poly1305_ietf_encrypt(c, &found_clen, c, MLEN, + NULL, 0U, NULL, nonce, firstkey); + if (found_clen != CLEN) { + printf("clen is not properly set (adlen=0)\n"); + } + for (i = 0U; i < CLEN; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + printf("\n"); + + if (crypto_aead_chacha20poly1305_ietf_decrypt(c, &m2len, NULL, c, CLEN, + NULL, 0U, nonce, firstkey) != 0) { + printf("crypto_aead_chacha20poly1305_ietf_decrypt() failed (adlen=0)\n"); + } + if (m2len != MLEN) { + printf("m2len is not properly set (adlen=0)\n"); + } + if (memcmp(m, c, MLEN) != 0) { + printf("m != c (adlen=0)\n"); + } + + sodium_free(c); + sodium_free(detached_c); + sodium_free(mac); + sodium_free(m2); + sodium_free(m); + + assert(crypto_aead_chacha20poly1305_ietf_keybytes() > 0U); + assert(crypto_aead_chacha20poly1305_ietf_keybytes() == crypto_aead_chacha20poly1305_keybytes()); + assert(crypto_aead_chacha20poly1305_ietf_npubbytes() > 0U); + assert(crypto_aead_chacha20poly1305_ietf_npubbytes() > crypto_aead_chacha20poly1305_npubbytes()); + assert(crypto_aead_chacha20poly1305_ietf_nsecbytes() == 0U); + assert(crypto_aead_chacha20poly1305_ietf_nsecbytes() == crypto_aead_chacha20poly1305_nsecbytes()); + assert(crypto_aead_chacha20poly1305_ietf_messagebytes_max() == crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX); + assert(crypto_aead_chacha20poly1305_IETF_KEYBYTES == crypto_aead_chacha20poly1305_ietf_KEYBYTES); + assert(crypto_aead_chacha20poly1305_IETF_NSECBYTES == crypto_aead_chacha20poly1305_ietf_NSECBYTES); + assert(crypto_aead_chacha20poly1305_IETF_NPUBBYTES == crypto_aead_chacha20poly1305_ietf_NPUBBYTES); + assert(crypto_aead_chacha20poly1305_IETF_ABYTES == crypto_aead_chacha20poly1305_ietf_ABYTES); + assert(crypto_aead_chacha20poly1305_IETF_MESSAGEBYTES_MAX == crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX); + + return 0; +} + +int +main(void) +{ + tv(); + tv_ietf(); + + return 0; +} diff --git a/external/src/libsodium/test/default/aead_chacha20poly1305.exp b/external/src/libsodium/test/default/aead_chacha20poly1305.exp new file mode 100644 index 0000000..1c6131f --- /dev/null +++ b/external/src/libsodium/test/default/aead_chacha20poly1305.exp @@ -0,0 +1,63 @@ +,0xe3,0xe4,0x46,0xf7,0xed,0xe9,0xa1,0x9b +,0x62,0xa4,0x67,0x7d,0xab,0xf4,0xe3,0xd2 +,0x4b,0x87,0x6b,0xb2,0x84,0x75,0x38,0x96 +,0xe1,0xd6 +,0xe3,0xe4,0x46,0xf7,0xed,0xe9,0xa1,0x9b +,0x62,0xa4,0x69,0xe7,0x78,0x9b,0xcd,0x95 +,0x4e,0x65,0x8e,0xd3,0x84,0x23,0xe2,0x31 +,0x61,0xdc +,0xe3,0xe4,0x46,0xf7,0xed,0xe9,0xa1,0x9b +,0x62,0xa4,0x69,0xe7,0x78,0x9b,0xcd,0x95 +,0x4e,0x65,0x8e,0xd3,0x84,0x23,0xe2,0x31 +,0x61,0xdc +,0xd3,0x1a,0x8d,0x34,0x64,0x8e,0x60,0xdb +,0x7b,0x86,0xaf,0xbc,0x53,0xef,0x7e,0xc2 +,0xa4,0xad,0xed,0x51,0x29,0x6e,0x08,0xfe +,0xa9,0xe2,0xb5,0xa7,0x36,0xee,0x62,0xd6 +,0x3d,0xbe,0xa4,0x5e,0x8c,0xa9,0x67,0x12 +,0x82,0xfa,0xfb,0x69,0xda,0x92,0x72,0x8b +,0x1a,0x71,0xde,0x0a,0x9e,0x06,0x0b,0x29 +,0x05,0xd6,0xa5,0xb6,0x7e,0xcd,0x3b,0x36 +,0x92,0xdd,0xbd,0x7f,0x2d,0x77,0x8b,0x8c +,0x98,0x03,0xae,0xe3,0x28,0x09,0x1b,0x58 +,0xfa,0xb3,0x24,0xe4,0xfa,0xd6,0x75,0x94 +,0x55,0x85,0x80,0x8b,0x48,0x31,0xd7,0xbc +,0x3f,0xf4,0xde,0xf0,0x8e,0x4b,0x7a,0x9d +,0xe5,0x76,0xd2,0x65,0x86,0xce,0xc6,0x4b +,0x61,0x16,0x1a,0xe1,0x0b,0x59,0x4f,0x09 +,0xe2,0x6a,0x7e,0x90,0x2e,0xcb,0xd0,0x60 +,0x06,0x91 +,0xd3,0x1a,0x8d,0x34,0x64,0x8e,0x60,0xdb +,0x7b,0x86,0xaf,0xbc,0x53,0xef,0x7e,0xc2 +,0xa4,0xad,0xed,0x51,0x29,0x6e,0x08,0xfe +,0xa9,0xe2,0xb5,0xa7,0x36,0xee,0x62,0xd6 +,0x3d,0xbe,0xa4,0x5e,0x8c,0xa9,0x67,0x12 +,0x82,0xfa,0xfb,0x69,0xda,0x92,0x72,0x8b +,0x1a,0x71,0xde,0x0a,0x9e,0x06,0x0b,0x29 +,0x05,0xd6,0xa5,0xb6,0x7e,0xcd,0x3b,0x36 +,0x92,0xdd,0xbd,0x7f,0x2d,0x77,0x8b,0x8c +,0x98,0x03,0xae,0xe3,0x28,0x09,0x1b,0x58 +,0xfa,0xb3,0x24,0xe4,0xfa,0xd6,0x75,0x94 +,0x55,0x85,0x80,0x8b,0x48,0x31,0xd7,0xbc +,0x3f,0xf4,0xde,0xf0,0x8e,0x4b,0x7a,0x9d +,0xe5,0x76,0xd2,0x65,0x86,0xce,0xc6,0x4b +,0x61,0x16,0x6a,0x23,0xa4,0x68,0x1f,0xd5 +,0x94,0x56,0xae,0xa1,0xd2,0x9f,0x82,0x47 +,0x72,0x16 +,0xd3,0x1a,0x8d,0x34,0x64,0x8e,0x60,0xdb +,0x7b,0x86,0xaf,0xbc,0x53,0xef,0x7e,0xc2 +,0xa4,0xad,0xed,0x51,0x29,0x6e,0x08,0xfe +,0xa9,0xe2,0xb5,0xa7,0x36,0xee,0x62,0xd6 +,0x3d,0xbe,0xa4,0x5e,0x8c,0xa9,0x67,0x12 +,0x82,0xfa,0xfb,0x69,0xda,0x92,0x72,0x8b +,0x1a,0x71,0xde,0x0a,0x9e,0x06,0x0b,0x29 +,0x05,0xd6,0xa5,0xb6,0x7e,0xcd,0x3b,0x36 +,0x92,0xdd,0xbd,0x7f,0x2d,0x77,0x8b,0x8c +,0x98,0x03,0xae,0xe3,0x28,0x09,0x1b,0x58 +,0xfa,0xb3,0x24,0xe4,0xfa,0xd6,0x75,0x94 +,0x55,0x85,0x80,0x8b,0x48,0x31,0xd7,0xbc +,0x3f,0xf4,0xde,0xf0,0x8e,0x4b,0x7a,0x9d +,0xe5,0x76,0xd2,0x65,0x86,0xce,0xc6,0x4b +,0x61,0x16,0x6a,0x23,0xa4,0x68,0x1f,0xd5 +,0x94,0x56,0xae,0xa1,0xd2,0x9f,0x82,0x47 +,0x72,0x16 diff --git a/external/src/libsodium/test/default/aead_chacha20poly13052.c b/external/src/libsodium/test/default/aead_chacha20poly13052.c new file mode 100644 index 0000000..8c59eca --- /dev/null +++ b/external/src/libsodium/test/default/aead_chacha20poly13052.c @@ -0,0 +1,1046 @@ + +#define TEST_NAME "aead_chacha20poly13052" +#include "cmptest.h" + +static struct { + const char *key_hex; + const char nonce_hex[crypto_aead_chacha20poly1305_ietf_NPUBBYTES * 2 + 1]; + const char *ad_hex; + const char *message_hex; + const char *detached_ciphertext_hex; + const char mac_hex[crypto_aead_chacha20poly1305_ietf_ABYTES * 2 + 1]; + const char *outcome; +} tests[] = { + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "070000004041424344454647", "50515253c0c1c2c3c4c5c6c7", + "4c616469657320616e642047656e746c656d656e206f662074686520636c617373206f66" + "202739393a204966204920636f756c64206f6666657220796f75206f6e6c79206f6e6520" + "74697020666f7220746865206675747572652c2073756e73637265656e20776f756c6420" + "62652069742e", + "d31a8d34648e60db7b86afbc53ef7ec2a4aded51296e08fea9e2b5a736ee62d63dbea45e" + "8ca9671282fafb69da92728b1a71de0a9e060b2905d6a5b67ecd3b3692ddbd7f2d778b8c" + "9803aee328091b58fab324e4fad675945585808b4831d7bc3ff4def08e4b7a9de576d265" + "86cec64b6116", + "1ae10b594f09e26a7e902ecbd0600691", "valid" }, + { "80ba3192c803ce965ea371d5ff073cf0f43b6a2ab576b208426e11409c09b9b0", + "4da5bf8dfd5852c1ea12379d", "", "", "", + "76acb342cf3166a5b63c0c0ea1383c8d", "valid" }, + { "7a4cd759172e02eb204db2c3f5c746227df584fc1345196391dbb9577a250742", + "a92ef0ac991dd516a3c6f689", "bd506764f2d2c410", "", "", + "906fa6284b52f87b7359cbaa7563c709", "valid" }, + { "cc56b680552eb75008f5484b4cb803fa5063ebd6eab91f6ab6aef4916a766273", + "99e23ec48985bccdeeab60f1", "", "2a", "3a", + "cac27dec0968801e9f6eded69d807522", "valid" }, + { "46f0254965f769d52bdb4a70b443199f8ef207520d1220c55e4b70f0fda620ee", + "ab0dca716ee051d2782f4403", "91ca6c592cbcca53", "51", "c4", + "168310ca45b1f7c66cad4e99e43f72b9", "valid" }, + { "2f7f7e4f592bb389194989743507bf3ee9cbde1786b6695fe6c025fd9ba4c100", + "461af122e9f2e0347e03f2db", "", "5c60", "4d13", + "91e8b61efb39c122195453077b22e5e2", "valid" }, + { "c8833dce5ea9f248aa2030eacfe72bffe69a620caf793344e5718fe0d7ab1a58", + "61546ba5f1720590b6040ac6", "88364fc8060518bf", "ddf2", "b60d", + "ead0fd4697ec2e5558237719d02437a2", "valid" }, + { "55568158d3a6483f1f7021eab69b703f614251cadc1af5d34a374fdbfc5adac7", + "3c4e654d663fa4596dc55bb7", "", "ab85e9c1571731", "5dfe3440dbb3c3", + "ed7a434e2602d394281e0afa9fb7aa42", "valid" }, + { "e3c09e7fab1aefb516da6a33022a1dd4eb272c80d540c5da52a730f34d840d7f", + "58389375c69ee398de948396", "84e46be8c0919053", "4ee5cda20d4290", + "4bd47212941ce3", "185f1408ee7fbf18f5abad6e2253a1ba", "valid" }, + { "51e4bf2bad92b7aff1a4bc05550ba81df4b96fabf41c12c7b00e60e48db7e152", + "4f07afedfdc3b6c2361823d3", "", "be3308f72a2c6aed", "8e9439a56eeec817", + "fbe8a6ed8fabb1937539dd6c00e90021", "valid" }, + { "1131c1418577a054de7a4ac551950f1a053f9ae46e5b75fe4abd5608d7cddadd", + "b4ea666ee119563366484a78", "66c0ae70076cb14d", "a4c9c2801b71f7df", + "b9b910433af052b0", "4530f51aeee024e0a445a6328fa67a18", "valid" }, + { "99b62bd5afbe3fb015bde93f0abf483957a1c3eb3ca59cb50b39f7f8a9cc51be", + "9a59fce26df0005e07538656", "", "42baae5978feaf5c368d14e0", + "ff7dc203b26c467a6b50db33", "578c0f2758c2e14e36d4fc106dcb29b4", "valid" }, + { "85f35b6282cff440bc1020c8136ff27031110fa63ec16f1e825118b006b91257", + "58dbd4ad2c4ad35dd906e9ce", "a506e1a5c69093f9", + "fdc85b94a4b2a6b759b1a0da", "9f8816de0994e938d9e53f95", + "d086fc6c9d8fa915fd8423a7cf05072f", "valid" }, + { "67119627bd988eda906219e08c0d0d779a07d208ce8a4fe0709af755eeec6dcb", + "68ab7fdbf61901dad461d23c", "", "51f8c1f731ea14acdb210a6d973e07", + "0b29638e1fbdd6df53970be2210042", "2a9134087d67a46e79178d0a93f5e1d2", + "valid" }, + { "e6f1118d41e4b43fb58221b7ed79673834e0d8ac5c4fa60bbc8bc4893a58894d", + "d95b3243afaef714c5035b6a", "6453a53384632212", + "97469da667d6110f9cbda1d1a20673", "32db66c4a3819d81557455e5980fed", + "feae30dec94e6ad3a9eea06a0d703917", "valid" }, + { "59d4eafb4de0cfc7d3db99a8f54b15d7b39f0acc8da69763b019c1699f87674a", + "2fcb1b38a99e71b84740ad9b", "", "549b365af913f3b081131ccb6b825588", + "e9110e9f56ab3ca483500ceabab67a13", "836ccabf15a6a22a51c1071cfa68fa0c", + "valid" }, + { "b907a45075513fe8a8019edee3f2591487b2a030b03c6e1d771c862571d2ea1e", + "118a6964c2d3e380071f5266", "034585621af8d7ff", + "55a465644f5b650928cbee7c063214d6", "e4b113cb775945f3d3a8ae9ec141c00c", + "7c43f16ce096d0dc27c95849dc383b7d", "valid" }, + { "3b2458d8176e1621c0cc24c0c0e24c1e80d72f7ee9149a4b166176629616d011", + "45aaa3e5d16d2d42dc03445d", "", "3ff1514b1c503915918f0c0c31094a6e1f", + "02cc3acb5ee1fcdd12a03bb857976474d3", "d83b7463a2c3800fe958c28eaa290813", + "valid" }, + { "f60c6a1b625725f76c7037b48fe3577fa7f7b87b1bd5a982176d182306ffb870", + "f0384fb876121410633d993d", "9aaf299eeea78f79", + "63858ca3e2ce69887b578a3c167b421c9c", + "35766488d2bc7c2b8d17cbbb9abfad9e6d", "1f391e657b2738dda08448cba2811ceb", + "valid" }, + { "0212a8de5007ed87b33f1a7090b6114f9e08cefd9607f2c276bdcfdbc5ce9cd7", + "e6b1adf2fd58a8762c65f31b", "", + "10f1ecf9c60584665d9ae5efe279e7f7377eea6916d2b111", + "42f26c56cb4be21d9d8d0c80fc99dde00d75f38074bfe764", + "54aa7e13d48fff7d7557039457040a3a", "valid" }, + { "c5bc09565646e7edda954f1f739223dada20b95c44ab033d0fae4b0283d18be3", + "6b282ebecc541bcd7834ed55", "3e8bc5ade182ff08", + "9222f9018e54fd6de1200806a9ee8e4cc904d29f25cba193", + "123032437b4bfd6920e8f7e7e0087ae4889ebe7a0ad0e900", + "3cf68f179550da63d3b96c2d55411865", "valid" }, + { "2eb51c469aa8eb9e6c54a8349bae50a20f0e382711bba1152c424f03b6671d71", + "04a9be03508a5f31371a6fd2", "", + "b053999286a2824f42cc8c203ab24e2c97a685adcc2ad32662558e55a5c729", + "45c7d6b53acad4abb68876a6e96a48fb59524d2c92c9d8a189c9fd2db91746", + "566d3ca10e311b695f3eae1551652493", "valid" }, + { "7f5b74c07ed1b40fd14358fe2ff2a740c116c7706510e6a437f19ea49911cec4", + "470a339ecb3219b8b81a1f8b", "374618a06ea98a48", + "f45206abc25552b2abc9ab7fa243035fedaaddc3b2293956f1ea6e7156e7eb", + "46a80c4187024720084627580080dde5a3f4a11093a7076ed6f3d326bc7b70", + "534d4aa2835a52e72d14df0e4f47f25f", "valid" }, + { "e1731d5854e1b70cb3ffe8b786a2b3ebf0994370954757b9dc8c7bc5354634a3", + "72cfd90ef3026ca22b7e6e6a", "", + "b9c554cbc36ac18ae897df7beecac1dbeb4eafa156bb60ce2e5d48f05715e678", + "ea29afa49d36e8760f5fe19723b9811ed5d519934a440f5081ac430b953b0e21", + "222541af46b86533c6b68d2ff108a7ea", "valid" }, + { "27d860631b0485a410702fea61bc873f3442260caded4abde25b786a2d97f145", + "262880d475f3dac5340dd1b8", "2333e5ce0f93b059", + "6b2604996cd30c14a13a5257ed6cffd3bc5e29d6b97eb1799eb335e281ea451e", + "6dad637897544d8bf6be9507ed4d1bb2e954bc427e5de729daf50762846ff2f4", + "7b997d93c982189d7095dc794c746232", "valid" }, + { "cf0d40a4644e5f51815165d5301b22631f4544c49a1878e3a0a5e8e1aae0f264", + "e74a515e7e2102b90bef55d2", "", + "973d0c753826bae466cf9abb3493152e9de7819e2bd0c71171346b4d2cebf8041aa3cedc" + "0dfd7b467e26228bc86c9a", + "fba78ae4f9d808a62e3da40be2cb7700c3613d9eb2c529c652e76a432c658d27095f0eb8" + "f940c324981ea935e507f9", + "8f046956db3a512908bd7afc8f2ab0a9", "valid" }, + { "6cbfd71c645d184cf5d23c402bdb0d25ec54898c8a0273d42eb5be109fdcb2ac", + "d4d807341683825b31cd4d95", "b3e4064683b02d84", + "a98995504df16f748bfb7785ff91eeb3b660ea9ed3450c3d5e7b0e79ef653659a9978d75" + "542ef91c456762215640b9", + "a1ffed80761829ecce242e0e88b138049016bca018da2b6e19986b3e318cae8d806198fb" + "4c527cc39350ebddeac573", + "c4cbf0befda0b70242c640d7cd02d7a3", "valid" }, + { "5b1d1035c0b17ee0b0444767f80a25b8c1b741f4b50a4d3052226baa1c6fb701", + "d61040a313ed492823cc065b", "", + "d096803181beef9e008ff85d5ddc38ddacf0f09ee5f7e07f1e4079cb64d0dc8f5e6711cd" + "4921a7887de76e2678fdc67618f1185586bfea9d4c685d50e4bb9a82", + "9a4ef22b181677b5755c08f747c0f8d8e8d4c18a9cc2405c12bb51bb1872c8e8b877678b" + "ec442cfcbb0ff464a64b74332cf072898c7e0eddf6232ea6e27efe50", + "9ff3427a0f32fa566d9ca0a78aefc013", "valid" }, + { "97d635c4f47574d9998a90875da1d3a284b755b2d39297a5725235190e10a97e", + "d31c21aba175b70de4ebb19c", "7193f623663321a2", + "94ee166d6d6ecf8832437136b4ae805d428864359586d9193a25016293edba443c58e07e" + "7b7195ec5bd84582a9d56c8d4a108c7d7ce34e6c6f8ea1bec0567317", + "5fbbdecc34be201614f636031eeb42f1cace3c79a12cffd871ee8e73820c829749f1abb4" + "294367849fb6c2aa56bda8a3078f723d7c1c852024b017b58973fb1e", + "09263da7b4cb921452f97dca40f580ec", "valid" }, + { "fe6e55bdaed1f7284ca5fc0f8c5f2b8df56dc0f49e8ca66a41995e783351f901", + "17c86a8abbb7e003acde2799", "", + "b429eb80fb8fe8baeda0c85b9c333458e7c2992e558475069d12d45c2221756412158803" + "2297eff56783742a5fc22d7410ffb29d66098661d76f126c3c27689e43b37267cac5a3a6" + "d3ab49e391da29cd3054a5692e2807e4c3ea46c8761d50f592", + "d0102f6c258bf49742cec34cf2d0fedf23d105fb4c84cf98515e1bc9a64f8ad5be8f0721" + "bde50645d00083c3a263a31053b760245f52ae2866a5ec83b19f61be1d30d5c5d9fecc4c" + "bbe08fd385813a2aa39a00ff9c10f7f23702add1e4b2ffa31c", + "41865fc71de12b19612127ce49993bb0", "valid" }, + { "aabc063474e65c4c3e9bdc480dea97b45110c8618846ff6b15bdd2a4a5682c4e", + "46362f45d6379e63e5229460", "a11c40b603767330", + "ceb534ce50dc23ff638ace3ef63ab2cc2973eeada80785fc165d06c2f5100ff5e8ab2882" + "c475afcd05ccd49f2e7d8f55ef3a72e3dc51d6852b8e6b9e7aece57be6556b0b6d9413e3" + "3fc5fc24a9a205ad59574bb39d944a92dc47970d84a6ad3176", + "7545391b51de01d5c53dfaca777909063e58edee4bb1227e7110ac4d2620c2aec2f848f5" + "6deeb037a8dced75afa8a6c890e2dee42f950bb33d9e2424d08a505d899563973ed38870" + "f3de6ee2adc7fe072c366c14e2cf7ca62fb3d36bee11685461", + "b70d44ef8c66c5c7bbf10dcadd7facf6", "valid" }, + { "7d00b48095adfa3272050607b264185002ba99957c498be022770f2ce2f3143c", + "87345f1055fd9e2102d50656", "02", "e5ccaa441bc814688f8f6e8f28b500b2", + "7e72f5a185af16a611921b438f749f0b", "1242c670732334029adfe1c5001651e4", + "valid" }, + { "6432717f1db85e41ac7836bce25185a080d5762b9e2b18444b6ec72c3bd8e4dc", + "87a3163ec0598ad95b3aa713", "b648", "02cde168fba3f544bbd0332f7adeada8", + "85f29a719557cdd14d1f8fffab6d9e60", "732ca32becd515a1ed353f542e999858", + "valid" }, + { "8e34cf73d245a1082a920b86364eb896c4946467bcb3d58929fcb36690e6394f", + "6f573aa86baa492ba46596df", "bd4cd02fc7502bbdbdf6c9a3cbe8f0", + "16ddd23ff53f3d23c06334487040eb47", "c1b295936d56fadac03e5f742bff73a1", + "39c457dbab66382babb3b55800cda5b8", "valid" }, + { "cb5575f5c7c45c91cf320b139fb594237560d0a3e6f865a67d4f633f2c08f016", + "1a6518f02ede1da6809266d9", "89cce9fb47441d07e0245a66fe8b778b", + "623b7850c321e2cf0c6fbcc8dfd1aff2", "c84c9bb7c61c1bcb17772a1c500c5095", + "dbadf7a5138ca03459a2cd65831e092f", "valid" }, + { "a5569e729a69b24ba6e0ff15c4627897436824c941e9d00b2e93fddc4ba77657", + "564dee49ab00d240fc1068c3", "d19f2d989095f7ab03a5fde84416e00c0e", + "87b3a4d7b26d8d3203a0de1d64ef82e3", "94bc80621ed1e71b1fd2b5c3a15e3568", + "333511861796978401598b963722f5b3", "valid" }, + { "56207465b4e48e6d04630f4a42f35cfc163ab289c22a2b4784f6f9290330bee0", + "df8713e87ec3dbcfad14d53e", + "5e6470facd99c1d81e37cd44015fe19480a2a4d3352a4ff560c0640fdbda", + "e601b38557797da2f8a4106a089d1da6", "299b5d3f3d03c087209a16e285143111", + "4b454ed198de117e83ec49fa8d8508d6", "valid" }, + { "3937986af86dafc1ba0c4672d8abc46c207062682d9c264ab06d6c5807205130", + "8df4b15a888c33286a7b7651", + "ba446f6f9a0ced22450feb10737d9007fd69abc19b1d4d9049a5551e86ec2b37", + "dc9e9eaf11e314182df6a4eba17aec9c", "605bbf90aeb974f6602bc778056f0dca", + "38ea23d99054b46b42ffe004129d2204", "valid" }, + { "36372abcdb78e0279646ac3d176b9674e9154eecf0d5469c651ec7e16b4c1199", + "be40e5f1a11817a0a8fa8949", + "d41a828d5e71829247021905402ea257dccbc3b80fcd5675056b68bb59e62e8873", + "81ce84ede9b35859cc8c49a8f6be7dc6", "7b7ce0d824809a70de32562ccf2c2bbd", + "15d44a00ce0d19b4231f921e22bc0a43", "valid" }, + { "9f1479ed097d7fe529c11f2f5add9aaff4a1ca0b68997a2cb7f79749bd90aaf4", + "84c87dae4eee27730ec35d12", + "3f2dd49bbf09d69a78a3d80ea2566614fc379474196c1aae84583da73d7ff85c6f42ca42" + "056a9792cc1b9fb3c7d261", + "a66747c89e857af3a18e2c79500087ed", "ca82bff3e2f310ccc976672c4415e69b", + "57638c62a5d85ded774f913c813ea032", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "00000000000000000000000000000000", + "256d40888094178355d304846443fee8df99470303fb3b7b80e030beebd329be", + "0000000000000000000000000000000000000000000000000000000000000000", + "e6d3d7324a1cbba777bbb0ecdda37807", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "00000000000000000000000000000000", + "256d40888094178355d304846443fee8df99470303fb3b7b80e030beebd329bee3bcdb5b" + "1edefcfe8bcda1b6a15c8c2b0869ffd2ec5e26e553b7b227fe87fdbd", + "000000000000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000", + "062de6795f274fd2a305d76980bc9cce", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "00000000000000000000000000000000", + "256d40888094178355d304846443fee8df99470303fb3b7b80e030beebd329bee3bcdb5b" + "1edefcfe8bcda1b6a15c8c2b0869ffd2ec5e26e553b7b227fe87fdbd7ada44424269bffa" + "5527f270acf68502b74c5ae2e60c0580981a4938459392c49bb2f284b646efc7f3f0b136" + "1dc348ed77d30bc57692ed38fbac0188380488c7", + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000", + "d8b47902baaeafb34203051529af282e", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "ffffffffffffffffffffffffffffffff", + "da92bf777f6be87caa2cfb7b9bbc01172066b8fcfc04c4847f1fcf41142cd641", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "b3891c849cb52c27747edfcf31213bb6", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "ffffffffffffffffffffffffffffffff", + "da92bf777f6be87caa2cfb7b9bbc01172066b8fcfc04c4847f1fcf41142cd6411c4324a4" + "e121030174325e495ea373d4f796002d13a1d91aac484dd801780242", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "f0c12d26ef03029b62c008da27c5dc68", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "ffffffffffffffffffffffffffffffff", + "da92bf777f6be87caa2cfb7b9bbc01172066b8fcfc04c4847f1fcf41142cd6411c4324a4" + "e121030174325e495ea373d4f796002d13a1d91aac484dd8017802428525bbbdbd964005" + "aad80d8f53097afd48b3a51d19f3fa7f67e5b6c7ba6c6d3b644d0d7b49b910380c0f4ec9" + "e23cb712882cf43a896d12c70453fe77c7fb7738", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffff", + "ee65783001c25691fa28d0f5f1c1d762", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "00000080000000800000008000000080", + "256d40088094170355d304046443fe68df99478303fb3bfb80e0303eebd3293e", + "0000008000000080000000800000008000000080000000800000008000000080", + "79ba7a29f5a7bb75797af87a610129a4", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "00000080000000800000008000000080", + "256d40088094170355d304046443fe68df99478303fb3bfb80e0303eebd3293ee3bcdbdb" + "1edefc7e8bcda136a15c8cab0869ff52ec5e266553b7b2a7fe87fd3d", + "000000800000008000000080000000800000008000000080000000800000008000000080" + "00000080000000800000008000000080000000800000008000000080", + "36b1743819e1b9ba1551e8ed922a959a", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "00000080000000800000008000000080", + "256d40088094170355d304046443fe68df99478303fb3bfb80e0303eebd3293ee3bcdbdb" + "1edefc7e8bcda136a15c8cab0869ff52ec5e266553b7b2a7fe87fd3d7ada44c24269bf7a" + "5527f2f0acf68582b74c5a62e60c0500981a49b8459392449bb2f204b646ef47f3f0b1b6" + "1dc3486d77d30b457692edb8fbac010838048847", + "000000800000008000000080000000800000008000000080000000800000008000000080" + "000000800000008000000080000000800000008000000080000000800000008000000080" + "000000800000008000000080000000800000008000000080000000800000008000000080" + "0000008000000080000000800000008000000080", + "feac4955554e806f3a1902e24432c08a", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "ffffff7fffffff7fffffff7fffffff7f", + "da92bff77f6be8fcaa2cfbfb9bbc01972066b87cfc04c4047f1fcfc1142cd6c1", + "ffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7f", + "20a3798df1292c5972bf9741aec38a19", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "ffffff7fffffff7fffffff7fffffff7f", + "da92bff77f6be8fcaa2cfbfb9bbc01972066b87cfc04c4047f1fcfc1142cd6c11c432424" + "e121038174325ec95ea37354f79600ad13a1d99aac484d58017802c2", + "ffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7f" + "ffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7f", + "c03d9f67354a97b2f074f7551557e49c", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "ffffff7fffffff7fffffff7fffffff7f", + "da92bff77f6be8fcaa2cfbfb9bbc01972066b87cfc04c4047f1fcfc1142cd6c11c432424" + "e121038174325ec95ea37354f79600ad13a1d99aac484d58017802c28525bb3dbd964085" + "aad80d0f53097a7d48b3a59d19f3faff67e5b647ba6c6dbb644d0dfb49b910b80c0f4e49" + "e23cb792882cf4ba896d12470453fef7c7fb77b8", + "ffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7f" + "ffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7f" + "ffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7f" + "ffffff7fffffff7fffffff7fffffff7fffffff7f", + "c86da8dd652286d50213d328d63e4006", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "7fffffff7fffffff7fffffff7fffffff", + "5a92bf77ff6be87c2a2cfb7b1bbc0117a066b8fc7c04c484ff1fcf41942cd641", + "7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff", + "bede9083ceb36ddfe5fa811f95471c67", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "7fffffff7fffffff7fffffff7fffffff", + "5a92bf77ff6be87c2a2cfb7b1bbc0117a066b8fc7c04c484ff1fcf41942cd6419c4324a4" + "61210301f4325e49dea373d47796002d93a1d91a2c484dd881780242", + "7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff" + "7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff", + "300874bb0692b689dead9ae15b067390", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "7fffffff7fffffff7fffffff7fffffff", + "5a92bf77ff6be87c2a2cfb7b1bbc0117a066b8fc7c04c484ff1fcf41942cd6419c4324a4" + "61210301f4325e49dea373d47796002d93a1d91a2c484dd8817802420525bbbd3d964005" + "2ad80d8fd3097afdc8b3a51d99f3fa7fe7e5b6c73a6c6d3be44d0d7bc9b910388c0f4ec9" + "623cb712082cf43a096d12c78453fe7747fb7738", + "7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff" + "7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff" + "7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff7fffffff" + "7fffffff7fffffff7fffffff7fffffff7fffffff", + "99cad85f45ca40942d0d4d5e950ade22", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "00000000ffffffff00000000ffffffff", + "256d40887f6be87c55d304849bbc0117df994703fc04c48480e030be142cd641", + "00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff", + "8bbe145272e7c2d9a1891a3ab0983d9d", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "00000000ffffffff00000000ffffffff", + "256d40887f6be87c55d304849bbc0117df994703fc04c48480e030be142cd641e3bcdb5b" + "e12103018bcda1b65ea373d40869ffd213a1d91a53b7b22701780242", + "00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000" + "ffffffff00000000ffffffff00000000ffffffff00000000ffffffff", + "3b41861913a8f6de7f61e225631bc382", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "00000000ffffffff00000000ffffffff", + "256d40887f6be87c55d304849bbc0117df994703fc04c48480e030be142cd641e3bcdb5b" + "e12103018bcda1b65ea373d40869ffd213a1d91a53b7b227017802427ada4442bd964005" + "5527f27053097afdb74c5ae219f3fa7f981a4938ba6c6d3b9bb2f28449b91038f3f0b136" + "e23cb71277d30bc5896d12c7fbac0188c7fb7738", + "00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000" + "ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff" + "00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000" + "ffffffff00000000ffffffff00000000ffffffff", + "8428bcf023ec6bf31fd9efb203ff0871", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "ffffffff00000000ffffffff00000000", + "da92bf7780941783aa2cfb7b6443fee82066b8fc03fb3b7b7f1fcf41ebd329be", + "ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000", + "139fdf6474ea24f549b075825f2c7620", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "ffffffff00000000ffffffff00000000", + "da92bf7780941783aa2cfb7b6443fee82066b8fc03fb3b7b7f1fcf41ebd329be1c4324a4" + "1edefcfe74325e49a15c8c2bf796002dec5e26e5ac484dd8fe87fdbd", + "ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff" + "00000000ffffffff00000000ffffffff00000000ffffffff00000000", + "bbad8d863b835a8e8664fd1d4566b6b4", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000000000000000001ee3200", "ffffffff00000000ffffffff00000000", + "da92bf7780941783aa2cfb7b6443fee82066b8fc03fb3b7b7f1fcf41ebd329be1c4324a4" + "1edefcfe74325e49a15c8c2bf796002dec5e26e5ac484dd8fe87fdbd8525bbbd4269bffa" + "aad80d8facf6850248b3a51de60c058067e5b6c7459392c4644d0d7bb646efc70c0f4ec9" + "1dc348ed882cf43a7692ed380453fe77380488c7", + "ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff" + "00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000" + "ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff" + "00000000ffffffff00000000ffffffff00000000", + "42f2354297849a511d53e5571772f71f", "valid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a2e3fdf9fba6861b5ad2607f40b7f447", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a1e3fdf9fba6861b5ad2607f40b7f447", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "23e3fdf9fba6861b5ad2607f40b7f447", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a3e2fdf9fba6861b5ad2607f40b7f447", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a3e3fd79fba6861b5ad2607f40b7f447", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a3e3fdf9faa6861b5ad2607f40b7f447", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a3e3fdf9f9a6861b5ad2607f40b7f447", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a3e3fdf9fba6869b5ad2607f40b7f447", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a3e3fdf9fba6861b5bd2607f40b7f447", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a3e3fdf9fba6861b5af2607f40b7f447", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a3e3fdf9fba6861b5ad2617f40b7f447", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a3e3fdf9fba6861b5ad2607f41b7f447", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a3e3fdf9fba6861b5ad2607f42b7f447", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a3e3fdf9fba6861b5ad2607f40b7f446", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a3e3fdf9fba6861b5ad2607f40b7f445", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a3e3fdf9fba6861b5ad2607f40b7f407", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a3e3fdf9fba6861b5ad2607f40b7f4c7", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "a3e3fdf9fba6869b5ad2607f40b7f4c7", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "00000000000000000000000000000000", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "", "", + "ffffffffffffffffffffffffffffffff", "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "26da374f17b7f1b23844a5490bfc4001", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "25da374f17b7f1b23844a5490bfc4001", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "a7da374f17b7f1b23844a5490bfc4001", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "27db374f17b7f1b23844a5490bfc4001", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "27da37cf17b7f1b23844a5490bfc4001", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "27da374f16b7f1b23844a5490bfc4001", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "27da374f15b7f1b23844a5490bfc4001", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "27da374f17b7f1323844a5490bfc4001", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "27da374f17b7f1b23944a5490bfc4001", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "27da374f17b7f1b23864a5490bfc4001", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "27da374f17b7f1b23844a4490bfc4001", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "27da374f17b7f1b23844a5490afc4001", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "27da374f17b7f1b23844a54909fc4001", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "27da374f17b7f1b23844a5490bfc4000", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "27da374f17b7f1b23844a5490bfc4003", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "27da374f17b7f1b23844a5490bfc4041", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "27da374f17b7f1b23844a5490bfc4081", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "27da374f17b7f1323844a5490bfc4081", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "00000000000000000000000000000000", + "invalid" }, + { "00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff", + "000102030405060708090a0b", "616164", "00000000000000000000000000000000", + "2cf8ae525fc86025268a4e1d88bead19", "ffffffffffffffffffffffffffffffff", + "invalid" }, + { "3030303030303030303030303030303030303030303030303030303030303030", + "30303030303030300002506e", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "d4500bf009493551c380adf52c573a69df7e8b762463330facc16a5726be7190c63c5a1c" + "926584a096756828dcdc64acdf963d931bf1dae238f3f157224ac4b542d785b0dd84db6b" + "e3bc5a3663e84149ffbed09e54f78f16a8223b24cb019f58b21b0e551e7aa07327629551" + "376ccbc3937671a0629bd95c9915c78555771e7a", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffff", + "0b300d8da56c2185755279553c4c82ca", "valid" }, + { "3030303030303030303030303030303030303030303030303030303030303030", + "3030303030303030000318a5", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "7de87f6729945275d0655da4c7fde4569e16f111b5eb26c22d859e3ff822eced3a6dd9a6" + "0f22957f7b7c857e8822eb9fe0b8d7022141f2d0b48f4b5612d322a88dd0fe0b4d917932" + "4f7c6c9e990efbd80e5ed6775826498b1efe0f71a0f3ec5b29cb28c2540a7dcd51b7daae" + "e0ff4a7f3ac1ee54c29ee4c170de408f66692194", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffff", + "c578e2aa44d309b7b6a5193bdc6118f5", "valid" }, + { "3030303030303030303030303030303030303030303030303030303030303030", + "00000000000000000007b4f0", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "1b996f9a3ccc6785de22ff5b8add9502ce03a0faf5992a09522cdd1206d220b8f8bd07d1" + "f1f5a1bd9a71d11c7f579b855818c08d4de036393183b7f590b335aed8de5b57b13c5fed" + "e2441c3e184aa9d46e61598506b3e11c43c62cbcaceced33190875b012218b1930fb7c38" + "ec45ac11c353d0cf938dccb9efad8fedbe46daa5", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffff", + "4b0bda8ad043830d8319ab82c50c7663", "valid" }, + { "3030303030303030303030303030303030303030303030303030303030303030", + "00000000000000000020fb66", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "86cbacae4d3f74ae01213e0551cc15160ea1be8408e3d5d74f01464995a69e6176cb9e02" + "b2247ed299892f9182a45caf4c69405611766edfafdc285519ea30480c44f05e781eacf8" + "fcecc7090abb28fa5fd585ac8cda7e8772e594e4ce6c883281932e0f89f877a1f04d9c32" + "b06cf90b0e762b430c4d517c97107068f498ef7f", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffff", + "4bc98f72c494c2a43c2b15a1043f1cfa", "valid" }, + { "3030303030303030303030303030303030303030303030303030303030303030", + "00000000000000000038bb90", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fab1cddf4fe198ef63add881d6ead6c57637bbe92018ca7c0b96fba0871e932db1fbf907" + "61be25df8dfaf931ce5757e617b3d7a9f0bf0ffe5d591a33c143b8f53fd0b5a19609fd62" + "e5c251a4281a200cfdc34f281710406f4e37625446ff6ef224913deb0d89af337128e3d1" + "55d16d3ec3246041432143e9ab3a6d2ccc2f4d62", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffff", + "f7e9e151b02533c74658bfc7737c680d", "valid" }, + { "3030303030303030303030303030303030303030303030303030303030303030", + "00000000000000000070484a", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "227202be7f3515e9d1c02eea2f1950b6481b048a4c91506cb40d504e6c949f82d197c25a" + "d17dc721651125782ac7a71247feaef32f1f250ce4bb8f79acaa179d45a7b0545f092432" + "5efa87d5e441d28478c61f2223ee67c3b41f4394535e2a24369a2e16613c459490c14fb1" + "d755fe53fbe1ee45b1b21f7162e2fcaa742abefd", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffff", + "795bcff647c553c2e4eb6e0eafd9e04e", "valid" }, + { "3030303030303030303030303030303030303030303030303030303030303030", + "000000000000000000932f40", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "fae58345c16cb0f5cc537f2b1b3469c969463b3ea71bcf6b98d669a8e60e04fc08d5fd06" + "9c362638e3400ef4cb242e27e2245e68cb9ec583da5340b12edf423b7326ad20feeb57da" + "ca2e0467a32899b42df8e56d84e006bc8a7acc731e7c1f6becb5719f7077f0d4f4c61ab1" + "1ebac1001801ce33c4e4a77d831d3ce34e8410e1", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffff", + "1946d653960f947a74d3e8093cf48502", "valid" }, + { "3030303030303030303030303030303030303030303030303030303030303030", + "000000000000000000e29335", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ebb216ddd7ca709215f503df9ce63c5cd2194e7d9099e8a90b2afaad5eba35069925a603" + "fdbc341aaed41505b10941fa3856a7e247b1040709746cfc2096caa631b2fff41c250506" + "d889c1c90671ade853ee6394c19192a5cf3710d1073099e5bc946582fc0fab9f543c716a" + "e2486a8683fdca39d2e14f23d00a582664f4ecb1", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffff", + "36c3002985dd21baf895d633573f12c0", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000000ef7d5", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "408ae6ef1c7ef0fb2c2d610816fc7849efa58f78273f5f166ea65f81b575747d035b3040" + "fede1eb9459788669788408e00413b3e376d152d204aa2b7a83558fcd48a0ef7a26b1cd6" + "d35d23b3f5dfe0ca77a4ce32b94abf83da2aefcaf068380879e89fb0a3829595cf44c385" + "2ae2cc662b689f9355d9c183801f6acc313f8907", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffff", + "6514518e0a264142e0b7351f967fc2ae", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000003dfce4", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0a0a24499bcade58cf1576c312aca984718cb4cc7e0153f5a9015810859644dfc021174e" + "0b060a397448de8b484a8603be680a6934c0906f30dd17eae2d4c5faa777f8ca53370e08" + "331b88c342bac959787bbb33930e3b56be86da7f2a6eb1f94089d1d181074d4302f8e055" + "2d0de1fab306a21b42d4c3ba6e6f0cbcc81e877a", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffff", + "4c194da6a99fd65b40e9cad798f44b19", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000018486a8", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "4a0aaff8494729188691701340f3ce2b8a78eed3a0f065994b72484e7991d25c29aa075e" + "b1fc16de93fe069058112ab284a3ed18780326d1258a47222fa633d8b29f3bd9150b239b" + "1546c2bb9b9f410febead396000ee477701532c3d0f5fbf895d280196d2f737c5e9fec50" + "d92bb0df5d7e513be5b8ea971310d5bf16ba7aee", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffff", + "c8ae7788cd2874abc138541e11fd0587", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ff9428d079351f665cd001354319875c783d35f613e6d9093d38e975c38fe3b89f7aed35" + "cb5a2fcaa0346efb936554649cf6378171eae4396ea15dc240d1abf4472d9096524fa1b2" + "b023b8b288222773d4d206616f9293f65b45dbbc74e7c2edfbcbbf1cfb679bb739a5862d" + "e2bcb937f74d5bf8671c5a8a5092f61d54c9aa5b", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffff", + "933a5163c7f62368327b3fbc1036c943", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000102030405060708090a0b", + "85ffffffffffffffffffffffffffffffa6902fcbc883bbc180b256ae34ad7f00", + "9a49c40f8b48d7c66d1db4e53f20f2dd4aaa241ddab26b5bc0e218b72c3390f2df3ebd01" + "76704419972bcdbc6bbcb3e4e74a71528ef51263ce24e0d575e0e44d", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "000102030405060708090a0b0c0d0e0f", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000102030405060708090a0b", + "ffffffffffffffffffffffffffffffff247e50642a1c0a2f8f77219609dba958", + "9a49c40f8b48d7c66d1db4e53f20f2dd4aaa241ddab26b5bc0e218b72c3390f2df3ebd01" + "76704419972bcdbc6bbcb3e4e74a71528ef51263ce24e0d575e0e44d", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "00000000000000000000000000000000", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000102030405060708090a0b", + "7cffffffffffffffffffffffffffffffd9e72c064ac8961f3fa585e0e2abd600", + "9a49c40f8b48d7c66d1db4e53f20f2dd4aaa241ddab26b5bc0e218b72c3390f2df3ebd01" + "76704419972bcdbc6bbcb3e4e74a71528ef51263ce24e0d575e0e44d", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffff", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000102030405060708090a0b", + "65ffffffffffffffffffffffffffffff95af0f4d0b686eaeccca4307d596f502", + "9a49c40f8b48d7c66d1db4e53f20f2dd4aaa241ddab26b5bc0e218b72c3390f2df3ebd01" + "76704419972bcdbc6bbcb3e4e74a71528ef51263ce24e0d575e0e44d", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "00000080000000800000008000000080", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000102030405060708090a0b", + "ffffffffffffffffffffffffffffffff8540b464357707be3a39d55c34f8bcb3", + "9a49c40f8b48d7c66d1db4e53f20f2dd4aaa241ddab26b5bc0e218b72c3390f2df3ebd01" + "76704419972bcdbc6bbcb3e4e74a71528ef51263ce24e0d575e0e44d", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffff7fffffff7fffffff7fffffff7f", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000102030405060708090a0b", + "4fffffffffffffffffffffffffffffff6623d990b898d830d212af2383330701", + "9a49c40f8b48d7c66d1db4e53f20f2dd4aaa241ddab26b5bc0e218b72c3390f2df3ebd01" + "76704419972bcdbc6bbcb3e4e74a71528ef51263ce24e0d575e0e44d", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "01000000010000000100000001000000", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000102030405060708090a0b", + "83ffffffffffffffffffffffffffffff5f16d09f17787211b7d484e024f89701", + "9a49c40f8b48d7c66d1db4e53f20f2dd4aaa241ddab26b5bc0e218b72c3390f2df3ebd01" + "76704419972bcdbc6bbcb3e4e74a71528ef51263ce24e0d575e0e44d", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffffff000000000000000000000000", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "005235d2a919f28d3db7664a34ae6b444d3d35f613e6d9093d38e975c38fe3b85b8b9450" + "9e2b74a36d346e33d572659ba9f6378171eae4396ea15dc240d1abf483dce9f3073efadb" + "7d23b87ace35168c", + "0039e2fd2fd312149e989880884813e7caffffffffffffffffffffffffffffff3b0e869a" + "aa8ea49632ffff37b9e8ce00caffffffffffffffffffffffffffffff3b0e869aaa8ea496" + "32ffff37b9e8ce00", + "a519ac1a35b4a57787510af78d8d200a", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "d39428d079351f665cd001354319875ce5da78766fa19290c031f75208506745ae7aed35" + "cb5a2fcaa0346efb93655464496ddeb05509c6efffab75eb2df4ab09762d9096524fa1b2" + "b023b8b2882227730149ef504b71b120ca4ff39519c2c210", + "d3ffffffffffffffffffffffffffffff6218b27f83b8b46602f6e1d834207b02ceffffff" + "ffffffffffffffffffffffff2a6416cedb1cdd296ef5d7d692daff02ceffffffffffffff" + "ffffffffffffffff2a6416cedb1cdd296ef5d7d692daff02", + "302fe82ab0a09af64400d015ae83d9cc", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "e99428d079351f665cd001354319875c6df1394edc539b5b3a0957be0fb85946807aed35" + "cb5a2fcaa0346efb93655464d1769fe806bbfeb6f590950f2eac9e0a582d9096524fa1b2" + "b023b8b2882227739952ae0818c38979c07413711a9af713", + "e9ffffffffffffffffffffffffffffffea33f347304abdadf8ce413433c84501e0ffffff" + "ffffffffffffffffffffffffb27f579688aee57064ce37329182ca01e0ffffffffffffff" + "ffffffffffffffffb27f579688aee57064ce37329182ca01", + "98a7e836e0ee4d023500d0557ec2cbe0", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "ff9428d079351f665cd001354319875c64f90f5b2692b860d4596ff4b3402c5c00b9bb53" + "707aa667d356fe50c7199694033561e7caca6d941dc3cd6914ad6904", + "ffffffffffffffffffffffffffffffffe33bc552ca8b9e96169e797e8f30301b603ca999" + "44df76528c9d6f54ab833d0f603ca99944df76528c9d6f54ab833d0f", + "6ab8dce2c59da4737130b0252f68a8d8", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "689428d079351f665cd001354319875cb08f25675b9bcbf6e38407de2ec75a479f7aed35" + "cb5a2fcaa0346efb936554642d2af7cd6b080501d31ba54fb2eb7596472d9096524fa1b2" + "b023b8b288222773650ec62d757072cee6ff233186dd1c8f", + "68ffffffffffffffffffffffffffffff374def6eb782ed002143115412b74600ffffffff" + "ffffffffffffffffffffffff4e233fb3e51d1ec7424507720dc5219dffffffffffffffff" + "ffffffffffffffff4e233fb3e51d1ec7424507720dc5219d", + "044dea608880412bfdffcf35579e9b26", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "6d9428d079351f665cd001354319875ca161b5ab040900629efeff78d7d86b459f7aed35" + "cb5a2fcaa0346efb93655464c6f8078cc8ef12a0ff657d6d08db10b8472d9096524fa1b2" + "b023b8b2882227738edc366cd697656fca81fb133ced79a1", + "6dffffffffffffffffffffffffffffff26a37fa2e81026945c39e9f2eba87702ffffffff" + "ffffffffffffffffffffffffa5f1cff246fa09666e3bdf50b7f544b3ffffffffffffffff" + "ffffffffffffffffa5f1cff246fa09666e3bdf50b7f544b3", + "1e6bea6314542e2ef9ffcf450b2e982b", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "ff9428d079351f665cd001354319875cfc01b891e5f0f9128d7d1c579192b69863414415" + "b69968959a7291b7a5af134860cd9ea10c29a36654e7a28e761becd8", + "ffffffffffffffffffffffffffffffff7bc3729809e9dfe44fba0addade2aadf03c456df" + "823cb8a0c5b900b3c935b8d303c456df823cb8a0c5b900b3c935b8d3", + "ed2017c8dba4775629049d786e3bceb1", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "ff9428d079351f665cd001354319875c6b6dc9d21a819e70b577f44137d3d6bd1335f5eb" + "44494077b26449a54b6c7c7510b92f5ffef98b847cf17a9c98d883e5", + "ffffffffffffffffffffffffffffffffecaf03dbf698b88677b0e2cb0ba3cafa73b0e721" + "70ec9042edafd8a127f6d7ee73b0e72170ec9042edafd8a127f6d7ee", + "073f17cb6778645925049d8822cbcab6", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "ffcb2b1106f8234c5e99d4db4c7048de323d35f613e6d9093d38e975c38fe3b816e9884a" + "114f0e9266cea3885fe36b9fd6f6378171eae4396ea15dc240d1abf4cebef5e9885a80ea" + "76d975c144a41888", + "ffa0fc3e8032c3d5fdb62a11f096307db5ffffffffffffffffffffffffffffff766c9a80" + "25eadea73905328c3379c004b5ffffffffffffffffffffffffffffff766c9a8025eadea7" + "3905328c3379c004", + "8b9bb4b4861289658c696a8340150405", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "6f9e70ed3b8baca026e46a5a0943158d213d35f613e6d9093d38e975c38fe3b80c612c5e" + "8d89a873dbcaad5b7346429bc5f6378171eae4396ea15dc240d1abf4d43651fd149c260b" + "cbdd7b126801318c", + "6ff5a7c2bd414c3985cb9490b5a56d2ea6ffffffffffffffffffffffffffffff6ce43e94" + "b92c784684013c5f1fdce900a6ffffffffffffffffffffffffffffff6ce43e94b92c7846" + "84013c5f1fdce900", + "8b3bbd51644459568d81ca1fa72ce404", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "412b080a3e19c10d44a1af1eabdeb4ce353d35f613e6d9093d38e975c38fe3b86b839433" + "0921486ca11d291c3e97ee9ad1f6378171eae4396ea15dc240d1abf4b3d4e9909034c614" + "b10aff5525d09d8d", + "4140df25b8d32194e78e51d41738cc6db2ffffffffffffffffffffffffffffff0b0686f9" + "3d849859fed6b818520d4501b2ffffffffffffffffffffffffffffff0b0686f93d849859" + "fed6b818520d4501", + "86fbab2b4a94f47aa56f0aea65d11008", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "b247a74723491aacacaad709c91e932b313d35f613e6d9093d38e975c38fe3b89ade04e7" + "5bb701d9660601b34765de98d5f6378171eae4396ea15dc240d1abf442897944c2a28fa1" + "7611d7fa5c22ad8f", + "b22c7068a583fa350f8529c375f8eb88b6fffffffffffffffffffffffffffffffa5b162d" + "6f12d1ec39cd90b72bff7503b6fffffffffffffffffffffffffffffffa5b162d6f12d1ec" + "39cd90b72bff7503", + "a019ac2ed667e17da16f0afa19610d0d", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "740f9e49f610efa585b659ca6ed8b4992d3d35f613e6d9093d38e975c38fe3b8412d96af" + "be80ec3e79d451b00a2db29ac9f6378171eae4396ea15dc240d1abf4997aeb0c27956246" + "69c387f9116ac18d", + "7464496670da0f3c2699a700d23ecc3aaaffffffffffffffffffffffffffffff21a88465" + "8a253c0b261fc0b466b71901aaffffffffffffffffffffffffffffff21a884658a253c0b" + "261fc0b466b71901", + "736e18181696a5889c3159faabab20fd", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "adba5d105bc8aa062c2336cb889ddbd5373d35f613e6d9093d38e975c38fe3b8177c5ffe" + "2875f468f6c2965748f3599ad3f6378171eae4396ea15dc240d1abf4cf2b225db1607a10" + "e6d5401e53b42a8d", + "add18a3fdd024a9f8f0cc801347ba376b0ffffffffffffffffffffffffffffff77f94d34" + "1cd0245da90907532469f201b0ffffffffffffffffffffffffffffff77f94d341cd0245d" + "a90907532469f201", + "bad58f10a91e6a889aba32fd17d8331a", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "fe9428d079351f665cd001354319875cc001edc5da442e719bce9abe273af144b47aed35" + "cb5a2fcaa0346efb9365546448025f41fa4e336c786957a2a7c4930a6c2d9096524fa1b2" + "b023b8b28822277300266ea1e43644a34d8dd1dc93f2fa13", + "feffffffffffffffffffffffffffffff47c327cc365d088759098c341b4aed03d4ffffff" + "ffffffffffffffffffffffff2b0b973f745b28aae937f59f18eac701d4ffffffffffffff" + "ffffffffffffffff2b0b973f745b28aae937f59f18eac701", + "d68ce174079add028dd05cf814630488", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "b513b06ab9ac14435acb8aa3a37afdb6543d35f613e6d9093d38e975c38fe3b861950193" + "b1bf0311ff117989aed9a999b0f6378171eae4396ea15dc240d1abf4b9c27c3028aa8d69" + "ef06afc0b59eda8e", + "b57867453f66f4daf9e474691f9c8515d3ffffffffffffffffffffffffffffff01101359" + "851ad324a0dae88dc2430202d3ffffffffffffffffffffffffffffff01101359851ad324" + "a0dae88dc2430202", + "aa48a3887d4b059699c2fdf9c6787e0a", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "ff9428d079351f665cd001354319875cd4f109e814cea85a08c011d850dd1dcbcf7aed35" + "cb5a2fcaa0346efb936554645340b85a9aa08296b77a5fc3961f660f172d9096524fa1b2" + "b023b8b2882227731b6489ba84d8f559829ed9bda2290f16", + "ffffffffffffffffffffffffffffffff5333c3e1f8d78eacca0707526cad018cafffffff" + "ffffffffffffffffffffffff3049702414b599502624fdfe29313204afffffffffffffff" + "ffffffffffffffff3049702414b599502624fdfe29313204", + "b936a817f2211af129e2cf160fd42bcb", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "ff9428d079351f665cd001354319875cdf4c62032d4119b588477e99925a56d9d67aed35" + "cb5a2fcaa0346efb93655464fa84f0645536421b2bb9246ec219ed0b0e2d9096524fa1b2" + "b023b8b288222773b2a0c1844b4e35d41e5da210f62f8412", + "ffffffffffffffffffffffffffffffff588ea80ac1583f434a806813ae2a4a9eb6ffffff" + "ffffffffffffffffffffffff998d381adb2359ddbae786537d37b900b6ffffffffffffff" + "ffffffffffffffff998d381adb2359ddbae786537d37b900", + "9f7ac4351f6b91e63097a713115d05be", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "ff9428d079351f665cd001354319875c13f80a006dc1bbdad639a92fc7eca655f77aed35" + "cb5a2fcaa0346efb936554646348b8fd29bf96d563a517e27d7bfc0f2f2d9096524fa1b2" + "b023b8b2882227732b6c891d37c7e11a5641919c494d9516", + "ffffffffffffffffffffffffffffffff943ac00981d89d2c14febfa5fb9cba1297ffffff" + "ffffffffffffffffffffffff00417083a7aa8d13f2fbb5dfc255a80497ffffffffffffff" + "ffffffffffffffff00417083a7aa8d13f2fbb5dfc255a804", + "9a18a828070269f44700d009e7171cc9", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "ff9428d079351f665cd001354319875c82e59b4582915038f933811e652dc66afc7aed35" + "cb5a2fcaa0346efb93655464b671c8cac270c265a0ac2f535799880a242d9096524fa1b2" + "b023b8b288222773fe55f92adc08b5aa9548a92d63afe113", + "ffffffffffffffffffffffffffffffff0527514c6e8876ce3bf49794595dda2d9cffffff" + "ffffffffffffffffffffffffd57800b44c65d9a331f28d6ee8b7dc019cffffffffffffff" + "ffffffffffffffffd57800b44c65d9a331f28d6ee8b7dc01", + "b436a82b93d555f74300d0199ba718ce", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "ff9428d079351f665cd001354319875cf1d12887b7216986a12d79098b6de60fc07aed35" + "cb5a2fcaa0346efb93655464a7c75899f3e60af1fcb6c7307d87590f182d9096524fa1b2" + "b023b8b288222773efe36979ed9e7d3ec952414e49b13016", + "ffffffffffffffffffffffffffffffff7613e28e5b384f7063ea6f83b71dfa48a0ffffff" + "ffffffffffffffffffffffffc4ce90e77df311376de8650dc2a90d04a0ffffffffffffff" + "ffffffffffffffffc4ce90e77df311376de8650dc2a90d04", + "ce54a82e1fa942fa3f00d0294f3715d3", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "cbf1da9e0ba9377374e69e1c0e600cfc343d35f613e6d9093d38e975c38fe3b8be3fa66b" + "6ce7808aa3e45949f944649fd0f6378171eae4396ea15dc240d1abf46668dbc8f5f20ef2" + "b3f38f00e2031788", + "cb9a0db18d63d7ead7c960d6b286745fb3ffffffffffffffffffffffffffffffdebab4a1" + "584250bffc2fc84d95decf04b3ffffffffffffffffffffffffffffffdebab4a1584250bf" + "fc2fc84d95decf04", + "2383ab0b799205699b510aa709bf31f1", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "8f278694c4e9daebd58d3e5b966e8b68423d35f613e6d9093d38e975c38fe3b80653e7a3" + "31718833acc3b9adff1c3198a6f6378171eae4396ea15dc240d1abf4de049a00a864064b" + "bcd46fe4e45b428f", + "8f4c51bb42233a7276a2c0912a88f3cbc5ffffffffffffffffffffffffffffff66d6f569" + "05d45806f30828a993869a03c5ffffffffffffffffffffffffffffff66d6f56905d45806" + "f30828a993869a03", + "8bfbab17a9e0b8748b510ae7d9fd2305", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "d59428d079351f665cd001354319875c9a22d70a48e24fddcdd4419de64c8f44fc7aed35" + "cb5a2fcaa0346efb9365546477b5c907d9c9e1ea51851a204aad9f0a242d9096524fa1b2" + "b023b8b2882227733f91f8e7c7b1962564619c5e7e9bf613", + "d5ffffffffffffffffffffffffffffff1de01d03a4fb692b0f135717da3c93039cffffff" + "ffffffffffffffffffffffff14bc017957dcfa2cc0dbb81df583cb019cffffffffffffff" + "ffffffffffffffff14bc017957dcfa2cc0dbb81df583cb01", + "49bc6e9fc51c4d503036644d842773d2", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "db9428d079351f665cd001354319875c75d5643aa5af934d8cce392cc3eedb47c07aed35" + "cb5a2fcaa0346efb93655464601b5ad2067f28066a8f3281715ba808182d9096524fa1b2" + "b023b8b288222773283f6b3218075fc95f6bb4ff456dc111", + "dbfffffffffffffffffffffffffffffff217ae3349b6b5bb4e092fa6ff9ec700a0ffffff" + "ffffffffffffffffffffffff031292ac886a33c0fbd190bcce75fc03a0ffffffffffffff" + "ffffffffffffffff031292ac886a33c0fbd190bcce75fc03", + "63da6ea251f039532c36645d38b76fd7", "valid" }, + { "808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "0000000000000000064c2d52", "ffffffff", + "939428d079351f665cd001354319875c624839604216e403ebcc6af559ec8b43977aed35" + "cb5a2fcaa0346efb93655464d8c8c3fa1a9e474abe52d02c8187e90f4f2d9096524fa1b2" + "b023b8b28822277390ecf21a04e630858bb65652b5b18016", + "93ffffffffffffffffffffffffffffffe58af369ae0fc2f5290b7c7f659c9704f7ffffff" + "ffffffffffffffffffffffffbbc10b84948b5c8c2f0c72113ea9bd04f7ffffffffffffff" + "ffffffffffffffffbbc10b84948b5c8c2f0c72113ea9bd04", + "73eb2724b5c405f04d00d0f15840a1c1", "valid" } +}; + +static int +tv(void) +{ + unsigned char *ad; + unsigned char *decrypted; + unsigned char *detached_ciphertext; + unsigned char *key; + unsigned char *message; + unsigned char *mac; + unsigned char *nonce; + size_t ad_len; + size_t detached_ciphertext_len; + size_t message_len; + unsigned int i; + + key = (unsigned char *) sodium_malloc( + crypto_aead_chacha20poly1305_ietf_KEYBYTES); + nonce = (unsigned char *) sodium_malloc( + crypto_aead_chacha20poly1305_ietf_NPUBBYTES); + mac = (unsigned char *) sodium_malloc( + crypto_aead_chacha20poly1305_ietf_ABYTES); + + for (i = 0U; i < (sizeof tests) / (sizeof tests[0]); i++) { + assert(strlen(tests[i].key_hex) == + 2 * crypto_aead_chacha20poly1305_ietf_KEYBYTES); + sodium_hex2bin(key, crypto_aead_chacha20poly1305_ietf_KEYBYTES, + tests[i].key_hex, strlen(tests[i].key_hex), NULL, NULL, + NULL); + + assert(strlen(tests[i].nonce_hex) == + 2 * crypto_aead_chacha20poly1305_ietf_NPUBBYTES); + sodium_hex2bin(nonce, crypto_aead_chacha20poly1305_ietf_NPUBBYTES, + tests[i].nonce_hex, strlen(tests[i].nonce_hex), NULL, + NULL, NULL); + + message_len = strlen(tests[i].message_hex) / 2; + message = (unsigned char *) sodium_malloc(message_len); + sodium_hex2bin(message, message_len, tests[i].message_hex, + strlen(tests[i].message_hex), NULL, NULL, NULL); + + ad_len = strlen(tests[i].ad_hex) / 2; + ad = (unsigned char *) sodium_malloc(ad_len); + sodium_hex2bin(ad, ad_len, tests[i].ad_hex, strlen(tests[i].ad_hex), + NULL, NULL, NULL); + + detached_ciphertext_len = message_len; + assert(strlen(tests[i].detached_ciphertext_hex) == 2 * message_len); + assert(strlen(tests[i].mac_hex) == + 2 * crypto_aead_chacha20poly1305_ietf_ABYTES); + sodium_hex2bin(mac, crypto_aead_chacha20poly1305_ietf_ABYTES, + tests[i].mac_hex, strlen(tests[i].mac_hex), NULL, NULL, + NULL); + + detached_ciphertext = + (unsigned char *) sodium_malloc(detached_ciphertext_len); + sodium_hex2bin(detached_ciphertext, detached_ciphertext_len, + tests[i].detached_ciphertext_hex, + strlen(tests[i].detached_ciphertext_hex), NULL, NULL, + NULL); + + decrypted = (unsigned char *) sodium_malloc(message_len); + if (crypto_aead_chacha20poly1305_ietf_decrypt_detached( + decrypted, NULL, detached_ciphertext, detached_ciphertext_len, + mac, ad, ad_len, nonce, key) == 0) { + if (strcmp(tests[i].outcome, "valid") != 0) { + printf("*** test case %u succeeded, was supposed to be %s\n", i, + tests[i].outcome); + } + if (memcmp(decrypted, message, message_len) != 0) { + printf("Incorrect decryption of test vector #%u\n", + (unsigned int) i); + } + } else { + if (strcmp(tests[i].outcome, "invalid") != 0) { + printf("*** test case %u failed, was supposed to be %s\n", i, + tests[i].outcome); + } + } + + sodium_free(message); + sodium_free(ad); + sodium_free(decrypted); + sodium_free(detached_ciphertext); + } + + sodium_free(key); + sodium_free(mac); + sodium_free(nonce); + + return 0; +} + +int +main(void) +{ + tv(); + printf("OK\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/aead_chacha20poly13052.exp b/external/src/libsodium/test/default/aead_chacha20poly13052.exp new file mode 100644 index 0000000..d86bac9 --- /dev/null +++ b/external/src/libsodium/test/default/aead_chacha20poly13052.exp @@ -0,0 +1 @@ +OK diff --git a/external/src/libsodium/test/default/aead_xchacha20poly1305.c b/external/src/libsodium/test/default/aead_xchacha20poly1305.c new file mode 100644 index 0000000..12059b6 --- /dev/null +++ b/external/src/libsodium/test/default/aead_xchacha20poly1305.c @@ -0,0 +1,203 @@ + +#define TEST_NAME "aead_xchacha20poly1305" +#include "cmptest.h" + +static int +tv(void) +{ +#undef MLEN +#define MLEN 114U +#undef ADLEN +#define ADLEN 12U +#undef CLEN +#define CLEN (MLEN + crypto_aead_xchacha20poly1305_ietf_ABYTES) + static const unsigned char firstkey[crypto_aead_xchacha20poly1305_ietf_KEYBYTES] + = { + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f + }; +#undef MESSAGE +#define MESSAGE "Ladies and Gentlemen of the class of '99: If I could offer you " \ + "only one tip for the future, sunscreen would be it." + unsigned char *m = (unsigned char *) sodium_malloc(MLEN); + static const unsigned char nonce[crypto_aead_xchacha20poly1305_ietf_NPUBBYTES] + = { 0x07, 0x00, 0x00, 0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53 }; + static const unsigned char ad[ADLEN] + = { 0x50, 0x51, 0x52, 0x53, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7 }; + unsigned char *c = (unsigned char *) sodium_malloc(CLEN); + unsigned char *detached_c = (unsigned char *) sodium_malloc(MLEN); + unsigned char *key2 = (unsigned char *) sodium_malloc(crypto_aead_xchacha20poly1305_ietf_KEYBYTES); + unsigned char *mac = (unsigned char *) sodium_malloc(crypto_aead_xchacha20poly1305_ietf_ABYTES); + unsigned char *m2 = (unsigned char *) sodium_malloc(MLEN); + unsigned long long found_clen; + unsigned long long found_maclen; + unsigned long long m2len; + size_t i; + + assert(sizeof MESSAGE - 1U == MLEN); + memcpy(m, MESSAGE, MLEN); + crypto_aead_xchacha20poly1305_ietf_encrypt(c, &found_clen, m, MLEN, + ad, ADLEN, + NULL, nonce, firstkey); + if (found_clen != MLEN + crypto_aead_xchacha20poly1305_ietf_abytes()) { + printf("found_clen is not properly set\n"); + } + for (i = 0U; i < CLEN; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + printf("\n"); + crypto_aead_xchacha20poly1305_ietf_encrypt_detached(detached_c, + mac, &found_maclen, + m, MLEN, + ad, ADLEN, + NULL, nonce, firstkey); + if (found_maclen != crypto_aead_xchacha20poly1305_ietf_abytes()) { + printf("found_maclen is not properly set\n"); + } + if (memcmp(detached_c, c, MLEN) != 0) { + printf("detached ciphertext is bogus\n"); + } + + if (crypto_aead_xchacha20poly1305_ietf_decrypt(NULL, 0, NULL, c, CLEN, ad, + ADLEN, nonce, firstkey) != 0) { + printf("crypto_aead_xchacha20poly1305_ietf_decrypt() tag-only verification failed\n"); + } + if (crypto_aead_xchacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, CLEN, ad, + ADLEN, nonce, firstkey) != 0) { + printf("crypto_aead_xchacha20poly1305_ietf_decrypt() failed\n"); + } + if (m2len != MLEN) { + printf("m2len is not properly set\n"); + } + if (memcmp(m, m2, MLEN) != 0) { + printf("m != m2\n"); + } + memset(m2, 0, m2len); + if (crypto_aead_xchacha20poly1305_ietf_decrypt_detached(m2, NULL, + c, MLEN, mac, + ad, ADLEN, + nonce, firstkey) != 0) { + printf("crypto_aead_xchacha20poly1305_ietf_decrypt_detached() failed\n"); + } + if (memcmp(m, m2, MLEN) != 0) { + printf("detached m != m2\n"); + } + + for (i = 0U; i < CLEN; i++) { + c[i] ^= (i + 1U); + if (crypto_aead_xchacha20poly1305_ietf_decrypt(m2, NULL, NULL, c, CLEN, + ad, ADLEN, nonce, firstkey) + == 0 || memcmp(m, m2, MLEN) == 0) { + printf("message can be forged\n"); + } + c[i] ^= (i + 1U); + } + crypto_aead_xchacha20poly1305_ietf_encrypt(c, &found_clen, m, MLEN, + NULL, 0U, NULL, nonce, firstkey); + if (found_clen != CLEN) { + printf("clen is not properly set (adlen=0)\n"); + } + for (i = 0U; i < CLEN; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + printf("\n"); + if (crypto_aead_xchacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, CLEN, + NULL, 0U, nonce, firstkey) != 0) { + printf("crypto_aead_xchacha20poly1305_ietf_decrypt() failed (adlen=0)\n"); + } + if (m2len != MLEN) { + printf("m2len is not properly set (adlen=0)\n"); + } + if (memcmp(m, m2, MLEN) != 0) { + printf("m != m2 (adlen=0)\n"); + } + m2len = 1; + if (crypto_aead_xchacha20poly1305_ietf_decrypt( + m2, &m2len, NULL, guard_page, + randombytes_uniform(crypto_aead_xchacha20poly1305_ietf_ABYTES), + NULL, 0U, nonce, firstkey) != -1) { + printf("crypto_aead_xchacha20poly1305_ietf_decrypt() worked with a short " + "ciphertext\n"); + } + if (m2len != 0) { + printf("Message length should have been set to zero after a failure\n"); + } + m2len = 1; + if (crypto_aead_xchacha20poly1305_ietf_decrypt(m2, &m2len, NULL, c, 0U, NULL, 0U, + nonce, firstkey) != -1) { + printf("crypto_aead_xchacha20poly1305_ietf_decrypt() worked with an empty " + "ciphertext\n"); + } + if (m2len != 0) { + printf("Message length should have been set to zero after a failure\n"); + } + + memcpy(c, m, MLEN); + crypto_aead_xchacha20poly1305_ietf_encrypt(c, &found_clen, c, MLEN, + NULL, 0U, NULL, nonce, firstkey); + if (found_clen != CLEN) { + printf("clen is not properly set (adlen=0)\n"); + } + for (i = 0U; i < CLEN; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + printf("\n"); + + if (crypto_aead_xchacha20poly1305_ietf_decrypt(c, &m2len, NULL, c, CLEN, + NULL, 0U, nonce, firstkey) != 0) { + printf("crypto_aead_xchacha20poly1305_ietf_decrypt() failed (adlen=0)\n"); + } + if (m2len != MLEN) { + printf("m2len is not properly set (adlen=0)\n"); + } + if (memcmp(m, c, MLEN) != 0) { + printf("m != c (adlen=0)\n"); + } + + crypto_aead_xchacha20poly1305_ietf_keygen(key2); + if (crypto_aead_xchacha20poly1305_ietf_decrypt(c, &m2len, NULL, c, CLEN, + NULL, 0U, nonce, key2) == 0) { + printf("crypto_aead_xchacha20poly1305_ietf_decrypt() with a wrong key should have failed\n"); + } + + sodium_free(c); + sodium_free(detached_c); + sodium_free(key2); + sodium_free(mac); + sodium_free(m2); + sodium_free(m); + + assert(crypto_aead_xchacha20poly1305_ietf_abytes() == crypto_aead_xchacha20poly1305_ietf_ABYTES); + assert(crypto_aead_xchacha20poly1305_ietf_keybytes() == crypto_aead_xchacha20poly1305_ietf_KEYBYTES); + assert(crypto_aead_xchacha20poly1305_ietf_npubbytes() == crypto_aead_xchacha20poly1305_ietf_NPUBBYTES); + assert(crypto_aead_xchacha20poly1305_ietf_nsecbytes() == 0U); + assert(crypto_aead_xchacha20poly1305_ietf_nsecbytes() == crypto_aead_xchacha20poly1305_ietf_NSECBYTES); + assert(crypto_aead_xchacha20poly1305_ietf_messagebytes_max() == crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX); + assert(crypto_aead_xchacha20poly1305_IETF_KEYBYTES == crypto_aead_xchacha20poly1305_ietf_KEYBYTES); + assert(crypto_aead_xchacha20poly1305_IETF_NSECBYTES == crypto_aead_xchacha20poly1305_ietf_NSECBYTES); + assert(crypto_aead_xchacha20poly1305_IETF_NPUBBYTES == crypto_aead_xchacha20poly1305_ietf_NPUBBYTES); + assert(crypto_aead_xchacha20poly1305_IETF_ABYTES == crypto_aead_xchacha20poly1305_ietf_ABYTES); + assert(crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX == crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX); + + return 0; +} + +int +main(void) +{ + tv(); + + return 0; +} diff --git a/external/src/libsodium/test/default/aead_xchacha20poly1305.exp b/external/src/libsodium/test/default/aead_xchacha20poly1305.exp new file mode 100644 index 0000000..d17ee7a --- /dev/null +++ b/external/src/libsodium/test/default/aead_xchacha20poly1305.exp @@ -0,0 +1,51 @@ +,0xf8,0xeb,0xea,0x48,0x75,0x04,0x40,0x66 +,0xfc,0x16,0x2a,0x06,0x04,0xe1,0x71,0xfe +,0xec,0xfb,0x3d,0x20,0x42,0x52,0x48,0x56 +,0x3b,0xcf,0xd5,0xa1,0x55,0xdc,0xc4,0x7b +,0xbd,0xa7,0x0b,0x86,0xe5,0xab,0x9b,0x55 +,0x00,0x2b,0xd1,0x27,0x4c,0x02,0xdb,0x35 +,0x32,0x1a,0xcd,0x7a,0xf8,0xb2,0xe2,0xd2 +,0x50,0x15,0xe1,0x36,0xb7,0x67,0x94,0x58 +,0xe9,0xf4,0x32,0x43,0xbf,0x71,0x9d,0x63 +,0x9b,0xad,0xb5,0xfe,0xac,0x03,0xf8,0x0a +,0x19,0xa9,0x6e,0xf1,0x0c,0xb1,0xd1,0x53 +,0x33,0xa8,0x37,0xb9,0x09,0x46,0xba,0x38 +,0x54,0xee,0x74,0xda,0x3f,0x25,0x85,0xef +,0xc7,0xe1,0xe1,0x70,0xe1,0x7e,0x15,0xe5 +,0x63,0xe7,0x76,0x01,0xf4,0xf8,0x5c,0xaf +,0xa8,0xe5,0x87,0x76,0x14,0xe1,0x43,0xe6 +,0x84,0x20 +,0xf8,0xeb,0xea,0x48,0x75,0x04,0x40,0x66 +,0xfc,0x16,0x2a,0x06,0x04,0xe1,0x71,0xfe +,0xec,0xfb,0x3d,0x20,0x42,0x52,0x48,0x56 +,0x3b,0xcf,0xd5,0xa1,0x55,0xdc,0xc4,0x7b +,0xbd,0xa7,0x0b,0x86,0xe5,0xab,0x9b,0x55 +,0x00,0x2b,0xd1,0x27,0x4c,0x02,0xdb,0x35 +,0x32,0x1a,0xcd,0x7a,0xf8,0xb2,0xe2,0xd2 +,0x50,0x15,0xe1,0x36,0xb7,0x67,0x94,0x58 +,0xe9,0xf4,0x32,0x43,0xbf,0x71,0x9d,0x63 +,0x9b,0xad,0xb5,0xfe,0xac,0x03,0xf8,0x0a +,0x19,0xa9,0x6e,0xf1,0x0c,0xb1,0xd1,0x53 +,0x33,0xa8,0x37,0xb9,0x09,0x46,0xba,0x38 +,0x54,0xee,0x74,0xda,0x3f,0x25,0x85,0xef +,0xc7,0xe1,0xe1,0x70,0xe1,0x7e,0x15,0xe5 +,0x63,0xe7,0xe0,0x96,0xe0,0x33,0xd9,0x1b +,0x63,0xf7,0xac,0x92,0xe9,0x97,0x2e,0x0d +,0x43,0xe5 +,0xf8,0xeb,0xea,0x48,0x75,0x04,0x40,0x66 +,0xfc,0x16,0x2a,0x06,0x04,0xe1,0x71,0xfe +,0xec,0xfb,0x3d,0x20,0x42,0x52,0x48,0x56 +,0x3b,0xcf,0xd5,0xa1,0x55,0xdc,0xc4,0x7b +,0xbd,0xa7,0x0b,0x86,0xe5,0xab,0x9b,0x55 +,0x00,0x2b,0xd1,0x27,0x4c,0x02,0xdb,0x35 +,0x32,0x1a,0xcd,0x7a,0xf8,0xb2,0xe2,0xd2 +,0x50,0x15,0xe1,0x36,0xb7,0x67,0x94,0x58 +,0xe9,0xf4,0x32,0x43,0xbf,0x71,0x9d,0x63 +,0x9b,0xad,0xb5,0xfe,0xac,0x03,0xf8,0x0a +,0x19,0xa9,0x6e,0xf1,0x0c,0xb1,0xd1,0x53 +,0x33,0xa8,0x37,0xb9,0x09,0x46,0xba,0x38 +,0x54,0xee,0x74,0xda,0x3f,0x25,0x85,0xef +,0xc7,0xe1,0xe1,0x70,0xe1,0x7e,0x15,0xe5 +,0x63,0xe7,0xe0,0x96,0xe0,0x33,0xd9,0x1b +,0x63,0xf7,0xac,0x92,0xe9,0x97,0x2e,0x0d +,0x43,0xe5 diff --git a/external/src/libsodium/test/default/auth.c b/external/src/libsodium/test/default/auth.c new file mode 100644 index 0000000..23ac927 --- /dev/null +++ b/external/src/libsodium/test/default/auth.c @@ -0,0 +1,141 @@ + +#define TEST_NAME "auth" +#include "cmptest.h" + +/* "Test Case 2" from RFC 4231 */ +static unsigned char key[32] = "Jefe"; +static unsigned char c[] = "what do ya want for nothing?"; + +/* Hacker manifesto */ +static unsigned char key2[] = + "Another one got caught today, it's all over the papers. \"Teenager " + "Arrested in Computer Crime Scandal\", \"Hacker Arrested after Bank " + "Tampering\"... Damn kids. They're all alike."; + +static unsigned char a[crypto_auth_BYTES]; +static unsigned char a2[crypto_auth_hmacsha512_BYTES]; +static unsigned char a3[crypto_auth_hmacsha512_BYTES]; + +int +main(void) +{ + crypto_auth_hmacsha512_state st; + crypto_auth_hmacsha256_state st256; + crypto_auth_hmacsha512256_state st512_256; + size_t i; + + assert(crypto_auth_hmacsha512_statebytes() == + sizeof(crypto_auth_hmacsha512_state)); + crypto_auth(a, c, sizeof c - 1U, key); + for (i = 0; i < sizeof a; ++i) { + printf(",0x%02x", (unsigned int) a[i]); + if (i % 8 == 7) + printf("\n"); + } + printf("\n"); + + crypto_auth_hmacsha512_init(&st, key, sizeof key); + crypto_auth_hmacsha512_update(&st, c, 1U); + crypto_auth_hmacsha512_update(&st, c, sizeof c - 2U); + crypto_auth_hmacsha512_final(&st, a2); + for (i = 0; i < sizeof a2; ++i) { + printf(",0x%02x", (unsigned int) a2[i]); + if (i % 8 == 7) + printf("\n"); + } + printf("\n"); + + crypto_auth_hmacsha512_init(&st, key2, sizeof key2); + crypto_auth_hmacsha512_update(&st, c, 1U); + crypto_auth_hmacsha512_update(&st, c, sizeof c - 2U); + crypto_auth_hmacsha512_final(&st, a2); + for (i = 0; i < sizeof a2; ++i) { + printf(",0x%02x", (unsigned int) a2[i]); + if (i % 8 == 7) + printf("\n"); + } + + memset(a2, 0, sizeof a2); + crypto_auth_hmacsha256_init(&st256, key2, sizeof key2); + crypto_auth_hmacsha256_update(&st256, guard_page, 0U); + crypto_auth_hmacsha256_update(&st256, c, 1U); + crypto_auth_hmacsha256_update(&st256, c, sizeof c - 2U); + crypto_auth_hmacsha256_final(&st256, a2); + for (i = 0; i < sizeof a2; ++i) { + printf(",0x%02x", (unsigned int) a2[i]); + if (i % 8 == 7) + printf("\n"); + } + + /* Empty message tests: HMAC-SHA512 */ + memset(a2, 0, sizeof a2); + crypto_auth_hmacsha512_init(&st, key, sizeof key); + crypto_auth_hmacsha512_final(&st, a2); + + memset(a3, 0, sizeof a3); + crypto_auth_hmacsha512_init(&st, key, sizeof key); + crypto_auth_hmacsha512_update(&st, a2, 0U); + crypto_auth_hmacsha512_final(&st, a3); + assert(sodium_memcmp(a2, a3, sizeof a2) == 0); + + memset(a3, 0, sizeof a3); + crypto_auth_hmacsha512_init(&st, key, sizeof key); + crypto_auth_hmacsha512_update(&st, guard_page, 0U); + crypto_auth_hmacsha512_final(&st, a3); + assert(sodium_memcmp(a2, a3, sizeof a2) == 0); + + /* Empty message tests: HMAC-SHA512-256 */ + memset(a2, 0, sizeof a2); + crypto_auth_hmacsha512256_init(&st512_256, key, sizeof key); + crypto_auth_hmacsha512256_final(&st512_256, a2); + + memset(a3, 0, sizeof a3); + crypto_auth_hmacsha512256_init(&st512_256, key, sizeof key); + crypto_auth_hmacsha512256_update(&st512_256, a2, 0U); + crypto_auth_hmacsha512256_final(&st512_256, a3); + assert(sodium_memcmp(a2, a3, sizeof a2) == 0); + + memset(a3, 0, sizeof a3); + crypto_auth_hmacsha512256_init(&st512_256, key, sizeof key); + crypto_auth_hmacsha512256_update(&st512_256, guard_page, 0U); + crypto_auth_hmacsha512256_final(&st512_256, a3); + assert(sodium_memcmp(a2, a3, sizeof a2) == 0); + + /* Empty message tests: HMAC-SHA256 */ + + memset(a2, 0, sizeof a2); + crypto_auth_hmacsha256_init(&st256, key, sizeof key); + crypto_auth_hmacsha256_final(&st256, a2); + + memset(a3, 0, sizeof a3); + crypto_auth_hmacsha256_init(&st256, key, sizeof key); + crypto_auth_hmacsha256_update(&st256, a2, 0U); + crypto_auth_hmacsha256_final(&st256, a3); + assert(sodium_memcmp(a2, a3, sizeof a2) == 0); + + memset(a3, 0, sizeof a3); + crypto_auth_hmacsha256_init(&st256, key, sizeof key); + crypto_auth_hmacsha256_update(&st256, guard_page, 0U); + crypto_auth_hmacsha256_final(&st256, a3); + assert(sodium_memcmp(a2, a3, sizeof a2) == 0); + + /* --- */ + + assert(crypto_auth_bytes() > 0U); + assert(crypto_auth_keybytes() > 0U); + assert(strcmp(crypto_auth_primitive(), "hmacsha512256") == 0); + assert(crypto_auth_hmacsha256_bytes() > 0U); + assert(crypto_auth_hmacsha256_keybytes() > 0U); + assert(crypto_auth_hmacsha512_bytes() > 0U); + assert(crypto_auth_hmacsha512_keybytes() > 0U); + assert(crypto_auth_hmacsha512256_bytes() == crypto_auth_bytes()); + assert(crypto_auth_hmacsha512256_keybytes() == crypto_auth_keybytes()); + assert(crypto_auth_hmacsha512256_statebytes() >= + crypto_auth_hmacsha512256_keybytes()); + assert(crypto_auth_hmacsha256_statebytes() == + sizeof(crypto_auth_hmacsha256_state)); + assert(crypto_auth_hmacsha512_statebytes() == + sizeof(crypto_auth_hmacsha512_state)); + + return 0; +} diff --git a/external/src/libsodium/test/default/auth.exp b/external/src/libsodium/test/default/auth.exp new file mode 100644 index 0000000..03b57d6 --- /dev/null +++ b/external/src/libsodium/test/default/auth.exp @@ -0,0 +1,30 @@ +,0x16,0x4b,0x7a,0x7b,0xfc,0xf8,0x19,0xe2 +,0xe3,0x95,0xfb,0xe7,0x3b,0x56,0xe0,0xa3 +,0x87,0xbd,0x64,0x22,0x2e,0x83,0x1f,0xd6 +,0x10,0x27,0x0c,0xd7,0xea,0x25,0x05,0x54 + +,0x7b,0x9d,0x83,0x38,0xeb,0x1e,0x3d,0xdd +,0xba,0x8a,0x9a,0x35,0x08,0xd0,0x34,0xa1 +,0xec,0xbe,0x75,0x11,0x37,0xfa,0x1b,0xcb +,0xa0,0xf9,0x2a,0x3e,0x6d,0xfc,0x79,0x80 +,0xb8,0x81,0xa8,0x64,0x5f,0x92,0x67,0x22 +,0x74,0x37,0x96,0x4b,0xf3,0x07,0x0b,0xe2 +,0xb3,0x36,0xb3,0xa3,0x20,0xf8,0x25,0xce +,0xc9,0x87,0x2d,0xb2,0x50,0x4b,0xf3,0x6d + +,0x73,0xe0,0x0d,0xcb,0xf4,0xf8,0xa3,0x33 +,0x30,0xac,0x52,0xed,0x2c,0xc9,0xd1,0xb2 +,0xef,0xb1,0x77,0x13,0xd3,0xec,0xe3,0x96 +,0x14,0x9f,0x37,0x65,0x3c,0xfe,0x70,0xe7 +,0x1f,0x2c,0x6f,0x9a,0x62,0xc3,0xc5,0x3a +,0x31,0x8a,0x9a,0x0b,0x3b,0x78,0x60,0xa4 +,0x31,0x6f,0x72,0x9b,0x8d,0x30,0x0f,0x15 +,0x9b,0x2f,0x60,0x93,0xa8,0x60,0xc1,0xed +,0x62,0x27,0xe4,0xce,0x7c,0x7f,0xe7,0xa4 +,0xba,0x9e,0x2a,0xc3,0x42,0xc3,0x5d,0x24 +,0x03,0x3e,0x38,0x8c,0x9b,0xdc,0x29,0x9b +,0x4a,0x50,0x50,0xf6,0x71,0x70,0xf4,0x83 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 diff --git a/external/src/libsodium/test/default/auth2.c b/external/src/libsodium/test/default/auth2.c new file mode 100644 index 0000000..583a2d4 --- /dev/null +++ b/external/src/libsodium/test/default/auth2.c @@ -0,0 +1,34 @@ +/* "Test Case AUTH256-4" from RFC 4868 */ + +#define TEST_NAME "auth2" +#include "cmptest.h" + +static unsigned char key[32] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20 +}; + +static unsigned char c[50] = { 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd }; + +static unsigned char a[32]; + +int +main(void) +{ + int i; + + crypto_auth_hmacsha256(a, c, sizeof c, key); + for (i = 0; i < 32; ++i) { + printf(",0x%02x", (unsigned int) a[i]); + if (i % 8 == 7) + printf("\n"); + } + return 0; +} diff --git a/external/src/libsodium/test/default/auth2.exp b/external/src/libsodium/test/default/auth2.exp new file mode 100644 index 0000000..955951a --- /dev/null +++ b/external/src/libsodium/test/default/auth2.exp @@ -0,0 +1,4 @@ +,0x37,0x2e,0xfc,0xf9,0xb4,0x0b,0x35,0xc2 +,0x11,0x5b,0x13,0x46,0x90,0x3d,0x2e,0xf4 +,0x2f,0xce,0xd4,0x6f,0x08,0x46,0xe7,0x25 +,0x7b,0xb1,0x56,0xd3,0xd7,0xb3,0x0d,0x3f diff --git a/external/src/libsodium/test/default/auth3.c b/external/src/libsodium/test/default/auth3.c new file mode 100644 index 0000000..ca90aa7 --- /dev/null +++ b/external/src/libsodium/test/default/auth3.c @@ -0,0 +1,36 @@ +/* "Test Case AUTH256-4" from RFC 4868 */ + +#define TEST_NAME "auth3" +#include "cmptest.h" + +static unsigned char key[32] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20 +}; + +static unsigned char c[50] = { 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, + 0xcd, 0xcd }; + +static unsigned char a[32] = { 0x37, 0x2e, 0xfc, 0xf9, 0xb4, 0x0b, 0x35, 0xc2, + 0x11, 0x5b, 0x13, 0x46, 0x90, 0x3d, 0x2e, 0xf4, + 0x2f, 0xce, 0xd4, 0x6f, 0x08, 0x46, 0xe7, 0x25, + 0x7b, 0xb1, 0x56, 0xd3, 0xd7, 0xb3, 0x0d, 0x3f }; + +int +main(void) +{ + static unsigned char a2[crypto_auth_hmacsha256_BYTES]; + + printf("%d\n", crypto_auth_hmacsha256_verify(a, c, sizeof c, key)); + + crypto_auth_hmacsha256(a2, guard_page, 0U, key); + assert(crypto_auth_hmacsha256_verify(a2, guard_page, 0U, key) == 0); + + return 0; +} diff --git a/external/src/libsodium/test/default/auth3.exp b/external/src/libsodium/test/default/auth3.exp new file mode 100644 index 0000000..573541a --- /dev/null +++ b/external/src/libsodium/test/default/auth3.exp @@ -0,0 +1 @@ +0 diff --git a/external/src/libsodium/test/default/auth5.c b/external/src/libsodium/test/default/auth5.c new file mode 100644 index 0000000..955c9cf --- /dev/null +++ b/external/src/libsodium/test/default/auth5.c @@ -0,0 +1,41 @@ + +#define TEST_NAME "auth5" +#include "cmptest.h" + +static unsigned char key[32]; +static unsigned char c[1000]; +static unsigned char a[32]; + +int +main(void) +{ + size_t clen; + + for (clen = 0; clen < 1000; ++clen) { + crypto_auth_keygen(key); + randombytes_buf(c, clen); + crypto_auth(a, c, clen, key); + if (crypto_auth_verify(a, c, clen, key) != 0) { + printf("fail %u\n", (unsigned int) clen); + return 100; + } + if (clen > 0) { + c[rand() % clen] += 1 + (rand() % 255); + if (crypto_auth_verify(a, c, clen, key) == 0) { + printf("forgery %u\n", (unsigned int) clen); + return 100; + } + a[rand() % sizeof a] += 1 + (rand() % 255); + if (crypto_auth_verify(a, c, clen, key) == 0) { + printf("forgery %u\n", (unsigned int) clen); + return 100; + } + } + } + + crypto_auth_keygen(key); + crypto_auth(a, guard_page, 0U, key); + assert(crypto_auth_verify(a, guard_page, 0U, key) == 0); + + return 0; +} diff --git a/external/src/libsodium/test/default/auth5.exp b/external/src/libsodium/test/default/auth5.exp new file mode 100644 index 0000000..e69de29 diff --git a/external/src/libsodium/test/default/auth6.c b/external/src/libsodium/test/default/auth6.c new file mode 100644 index 0000000..f397a05 --- /dev/null +++ b/external/src/libsodium/test/default/auth6.c @@ -0,0 +1,23 @@ + +#define TEST_NAME "auth6" +#include "cmptest.h" + +/* "Test Case 2" from RFC 4231 */ +static unsigned char key[32] = "Jefe"; +static unsigned char c[] = "what do ya want for nothing?"; + +static unsigned char a[64]; + +int +main(void) +{ + int i; + + crypto_auth_hmacsha512(a, c, sizeof c - 1U, key); + for (i = 0; i < 64; ++i) { + printf(",0x%02x", (unsigned int) a[i]); + if (i % 8 == 7) + printf("\n"); + } + return 0; +} diff --git a/external/src/libsodium/test/default/auth6.exp b/external/src/libsodium/test/default/auth6.exp new file mode 100644 index 0000000..da0c528 --- /dev/null +++ b/external/src/libsodium/test/default/auth6.exp @@ -0,0 +1,8 @@ +,0x16,0x4b,0x7a,0x7b,0xfc,0xf8,0x19,0xe2 +,0xe3,0x95,0xfb,0xe7,0x3b,0x56,0xe0,0xa3 +,0x87,0xbd,0x64,0x22,0x2e,0x83,0x1f,0xd6 +,0x10,0x27,0x0c,0xd7,0xea,0x25,0x05,0x54 +,0x97,0x58,0xbf,0x75,0xc0,0x5a,0x99,0x4a +,0x6d,0x03,0x4f,0x65,0xf8,0xf0,0xe6,0xfd +,0xca,0xea,0xb1,0xa3,0x4d,0x4a,0x6b,0x4b +,0x63,0x6e,0x07,0x0a,0x38,0xbc,0xe7,0x37 diff --git a/external/src/libsodium/test/default/auth7.c b/external/src/libsodium/test/default/auth7.c new file mode 100644 index 0000000..3d087f8 --- /dev/null +++ b/external/src/libsodium/test/default/auth7.c @@ -0,0 +1,41 @@ + +#define TEST_NAME "auth7" +#include "cmptest.h" + +static unsigned char key[32]; +static unsigned char c[600]; +static unsigned char a[64]; + +int +main(void) +{ + size_t clen; + + for (clen = 0; clen < sizeof c; ++clen) { + crypto_auth_keygen(key); + randombytes_buf(c, clen); + crypto_auth_hmacsha512(a, c, clen, key); + if (crypto_auth_hmacsha512_verify(a, c, clen, key) != 0) { + printf("fail %u\n", (unsigned int) clen); + return 100; + } + if (clen > 0) { + c[(size_t) rand() % clen] += 1 + (rand() % 255); + if (crypto_auth_hmacsha512_verify(a, c, clen, key) == 0) { + printf("forgery %u\n", (unsigned int) clen); + return 100; + } + a[rand() % sizeof a] += 1 + (rand() % 255); + if (crypto_auth_hmacsha512_verify(a, c, clen, key) == 0) { + printf("forgery %u\n", (unsigned int) clen); + return 100; + } + } + } + + crypto_auth_keygen(key); + crypto_auth_hmacsha512(a, guard_page, 0U, key); + assert(crypto_auth_hmacsha512_verify(a, guard_page, 0U, key) == 0); + + return 0; +} diff --git a/external/src/libsodium/test/default/auth7.exp b/external/src/libsodium/test/default/auth7.exp new file mode 100644 index 0000000..e69de29 diff --git a/external/src/libsodium/test/default/box.c b/external/src/libsodium/test/default/box.c new file mode 100644 index 0000000..228aca7 --- /dev/null +++ b/external/src/libsodium/test/default/box.c @@ -0,0 +1,112 @@ + +#define TEST_NAME "box" +#include "cmptest.h" + +static const unsigned char alicesk[32] = { + 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16, 0xc1, + 0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, + 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a +}; + +static const unsigned char bobpk[32] = { + 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 0xd3, 0x5b, 0x61, + 0xc2, 0xec, 0xe4, 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, + 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f +}; + +static const unsigned char small_order_p[crypto_box_PUBLICKEYBYTES] = { + 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, + 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, + 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 +}; + +static const unsigned char nonce[24] = { 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, + 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8, + 0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, + 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 }; + +/* API requires first 32 bytes to be 0 */ +static const unsigned char m[163] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0xbe, 0x07, 0x5f, 0xc5, + 0x3c, 0x81, 0xf2, 0xd5, 0xcf, 0x14, 0x13, 0x16, 0xeb, 0xeb, 0x0c, 0x7b, + 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4, 0x4b, 0x66, 0x84, 0x9b, + 0x64, 0x24, 0x4f, 0xfc, 0xe5, 0xec, 0xba, 0xaf, 0x33, 0xbd, 0x75, 0x1a, + 0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29, 0x6c, 0xdc, 0x3c, 0x01, + 0x23, 0x35, 0x61, 0xf4, 0x1d, 0xb6, 0x6c, 0xce, 0x31, 0x4a, 0xdb, 0x31, + 0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d, 0xce, 0xea, 0x3a, 0x7f, + 0xa1, 0x34, 0x80, 0x57, 0xe2, 0xf6, 0x55, 0x6a, 0xd6, 0xb1, 0x31, 0x8a, + 0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde, 0x04, 0x89, 0x77, 0xeb, + 0x48, 0xf5, 0x9f, 0xfd, 0x49, 0x24, 0xca, 0x1c, 0x60, 0x90, 0x2e, 0x52, + 0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40, 0xe0, 0x82, 0xf9, 0x37, + 0x76, 0x38, 0x48, 0x64, 0x5e, 0x07, 0x05 +}; + +static unsigned char c[163]; + +int +main(void) +{ + unsigned char k[crypto_box_BEFORENMBYTES]; + int i; + int ret; + + ret = crypto_box(c, m, 163, nonce, bobpk, alicesk); + assert(ret == 0); + for (i = 16; i < 163; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + if (i % 8 == 7) + printf("\n"); + } + printf("\n"); + + ret = crypto_box(c, m, 163, nonce, small_order_p, alicesk); + assert(ret == -1); + + memset(c, 0, sizeof c); + + ret = crypto_box_beforenm(k, bobpk, alicesk); + assert(ret == 0); + crypto_box_afternm(c, m, 163, nonce, k); + for (i = 16; i < 163; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + if (i % 8 == 7) + printf("\n"); + } + printf("\n"); + + ret = crypto_box_beforenm(k, small_order_p, alicesk); + assert(ret == -1); + + assert(crypto_box_seedbytes() > 0U); + assert(crypto_box_publickeybytes() > 0U); + assert(crypto_box_secretkeybytes() > 0U); + assert(crypto_box_beforenmbytes() > 0U); + assert(crypto_box_noncebytes() > 0U); + assert(crypto_box_zerobytes() > 0U); + assert(crypto_box_boxzerobytes() > 0U); + assert(crypto_box_macbytes() > 0U); + assert(crypto_box_messagebytes_max() > 0U); + assert(strcmp(crypto_box_primitive(), "curve25519xsalsa20poly1305") == 0); + assert(crypto_box_curve25519xsalsa20poly1305_seedbytes() == + crypto_box_seedbytes()); + assert(crypto_box_curve25519xsalsa20poly1305_publickeybytes() == + crypto_box_publickeybytes()); + assert(crypto_box_curve25519xsalsa20poly1305_secretkeybytes() == + crypto_box_secretkeybytes()); + assert(crypto_box_curve25519xsalsa20poly1305_beforenmbytes() == + crypto_box_beforenmbytes()); + assert(crypto_box_curve25519xsalsa20poly1305_noncebytes() == + crypto_box_noncebytes()); + assert(crypto_box_curve25519xsalsa20poly1305_zerobytes() == + crypto_box_zerobytes()); + assert(crypto_box_curve25519xsalsa20poly1305_boxzerobytes() == + crypto_box_boxzerobytes()); + assert(crypto_box_curve25519xsalsa20poly1305_macbytes() == + crypto_box_macbytes()); + assert(crypto_box_curve25519xsalsa20poly1305_messagebytes_max() == + crypto_box_messagebytes_max()); + + return 0; +} diff --git a/external/src/libsodium/test/default/box.exp b/external/src/libsodium/test/default/box.exp new file mode 100644 index 0000000..25db669 --- /dev/null +++ b/external/src/libsodium/test/default/box.exp @@ -0,0 +1,38 @@ +,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5 +,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9 +,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73 +,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce +,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4 +,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a +,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b +,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72 +,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2 +,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38 +,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a +,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae +,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea +,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda +,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde +,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3 +,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6 +,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74 +,0xe3,0x55,0xa5 +,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5 +,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9 +,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73 +,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce +,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4 +,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a +,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b +,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72 +,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2 +,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38 +,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a +,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae +,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea +,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda +,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde +,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3 +,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6 +,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74 +,0xe3,0x55,0xa5 diff --git a/external/src/libsodium/test/default/box2.c b/external/src/libsodium/test/default/box2.c new file mode 100644 index 0000000..3e46fda --- /dev/null +++ b/external/src/libsodium/test/default/box2.c @@ -0,0 +1,80 @@ + +#define TEST_NAME "box2" +#include "cmptest.h" + +static unsigned char bobsk[32] = { 0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, + 0x4b, 0x79, 0xe1, 0x7f, 0x8b, 0x83, 0x80, + 0x0e, 0xe6, 0x6f, 0x3b, 0xb1, 0x29, 0x26, + 0x18, 0xb6, 0xfd, 0x1c, 0x2f, 0x8b, 0x27, + 0xff, 0x88, 0xe0, 0xeb }; + +static unsigned char alicepk[32] = { 0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, + 0x54, 0x74, 0x8b, 0x7d, 0xdc, 0xb4, 0x3e, + 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d, 0x26, + 0x38, 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e, + 0xaa, 0x9b, 0x4e, 0x6a }; + +static const unsigned char small_order_p[crypto_box_PUBLICKEYBYTES] = { + 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, + 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, + 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 +}; + +static unsigned char nonce[24] = { 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, + 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8, + 0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, + 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 }; + +/* API requires first 16 bytes to be 0 */ +static unsigned char c[163] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5, + 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9, 0x8e, 0x99, 0x3b, 0x9f, + 0x48, 0x68, 0x12, 0x73, 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce, + 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4, 0x47, 0x6f, 0xb8, 0xc5, + 0x31, 0xa1, 0x18, 0x6a, 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b, + 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72, 0x71, 0xd2, 0xc2, 0x0f, + 0x9b, 0x92, 0x8f, 0xe2, 0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38, + 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a, 0xb9, 0x32, 0x16, 0x45, + 0x48, 0xe5, 0x26, 0xae, 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea, + 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda, 0x99, 0x83, 0x2b, 0x61, + 0xca, 0x01, 0xb6, 0xde, 0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3, + 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6, 0x59, 0x9b, 0x1f, 0x65, + 0x4c, 0xb4, 0x5a, 0x74, 0xe3, 0x55, 0xa5 +}; + +static unsigned char m[163]; + +int +main(void) +{ + unsigned char k[crypto_box_BEFORENMBYTES]; + int i; + int ret; + + if (crypto_box_open(m, c, 163, nonce, alicepk, bobsk) == 0) { + for (i = 32; i < 163; ++i) { + printf(",0x%02x", (unsigned int) m[i]); + if (i % 8 == 7) + printf("\n"); + } + printf("\n"); + } + ret = crypto_box_open(m, c, 163, nonce, small_order_p, bobsk); + assert(ret == -1); + + memset(m, 0, sizeof m); + ret = crypto_box_beforenm(k, small_order_p, bobsk); + assert(ret == -1); + ret = crypto_box_beforenm(k, alicepk, bobsk); + assert(ret == 0); + if (crypto_box_open_afternm(m, c, 163, nonce, k) == 0) { + for (i = 32; i < 163; ++i) { + printf(",0x%02x", (unsigned int) m[i]); + if (i % 8 == 7) + printf("\n"); + } + printf("\n"); + } + return 0; +} diff --git a/external/src/libsodium/test/default/box2.exp b/external/src/libsodium/test/default/box2.exp new file mode 100644 index 0000000..51deccd --- /dev/null +++ b/external/src/libsodium/test/default/box2.exp @@ -0,0 +1,34 @@ +,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5 +,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b +,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4 +,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc +,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a +,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29 +,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4 +,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31 +,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d +,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57 +,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a +,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde +,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd +,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52 +,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40 +,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64 +,0x5e,0x07,0x05 +,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5 +,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b +,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4 +,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc +,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a +,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29 +,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4 +,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31 +,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d +,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57 +,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a +,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde +,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd +,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52 +,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40 +,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64 +,0x5e,0x07,0x05 diff --git a/external/src/libsodium/test/default/box7.c b/external/src/libsodium/test/default/box7.c new file mode 100644 index 0000000..a58ea30 --- /dev/null +++ b/external/src/libsodium/test/default/box7.c @@ -0,0 +1,50 @@ + +#define TEST_NAME "box7" +#include "cmptest.h" + +static unsigned char alicesk[crypto_box_SECRETKEYBYTES]; +static unsigned char alicepk[crypto_box_PUBLICKEYBYTES]; +static unsigned char bobsk[crypto_box_SECRETKEYBYTES]; +static unsigned char bobpk[crypto_box_PUBLICKEYBYTES]; +static unsigned char n[crypto_box_NONCEBYTES]; + +int +main(void) +{ + unsigned char *m; + unsigned char *c; + unsigned char *m2; + size_t mlen; + size_t mlen_max = 1000; + size_t i; + int ret; + + m = (unsigned char *) sodium_malloc(mlen_max); + c = (unsigned char *) sodium_malloc(mlen_max); + m2 = (unsigned char *) sodium_malloc(mlen_max); + memset(m, 0, crypto_box_ZEROBYTES); + crypto_box_keypair(alicepk, alicesk); + crypto_box_keypair(bobpk, bobsk); + for (mlen = 0; mlen + crypto_box_ZEROBYTES <= mlen_max; mlen++) { + randombytes_buf(n, crypto_box_NONCEBYTES); + randombytes_buf(m + crypto_box_ZEROBYTES, mlen); + ret = crypto_box(c, m, mlen + crypto_box_ZEROBYTES, n, bobpk, alicesk); + assert(ret == 0); + if (crypto_box_open(m2, c, mlen + crypto_box_ZEROBYTES, n, alicepk, + bobsk) == 0) { + for (i = 0; i < mlen + crypto_box_ZEROBYTES; ++i) { + if (m2[i] != m[i]) { + printf("bad decryption\n"); + break; + } + } + } else { + printf("ciphertext fails verification\n"); + } + } + sodium_free(m); + sodium_free(c); + sodium_free(m2); + + return 0; +} diff --git a/external/src/libsodium/test/default/box7.exp b/external/src/libsodium/test/default/box7.exp new file mode 100644 index 0000000..e69de29 diff --git a/external/src/libsodium/test/default/box8.c b/external/src/libsodium/test/default/box8.c new file mode 100644 index 0000000..4d27f33 --- /dev/null +++ b/external/src/libsodium/test/default/box8.c @@ -0,0 +1,58 @@ + +#define TEST_NAME "box8" +#include "cmptest.h" + +static unsigned char alicesk[crypto_box_SECRETKEYBYTES]; +static unsigned char alicepk[crypto_box_PUBLICKEYBYTES]; +static unsigned char bobsk[crypto_box_SECRETKEYBYTES]; +static unsigned char bobpk[crypto_box_PUBLICKEYBYTES]; +static unsigned char n[crypto_box_NONCEBYTES]; + +int +main(void) +{ + unsigned char *m; + unsigned char *c; + unsigned char *m2; + size_t mlen; + size_t mlen_max = 1000; + size_t i; + int faults; + int ret; + + m = (unsigned char *) sodium_malloc(mlen_max); + c = (unsigned char *) sodium_malloc(mlen_max); + m2 = (unsigned char *) sodium_malloc(mlen_max); + crypto_box_keypair(alicepk, alicesk); + crypto_box_keypair(bobpk, bobsk); + for (mlen = 0; mlen + crypto_box_ZEROBYTES <= mlen_max; mlen++) { + randombytes_buf(n, crypto_box_NONCEBYTES); + randombytes_buf(m + crypto_box_ZEROBYTES, mlen); + ret = crypto_box(c, m, mlen + crypto_box_ZEROBYTES, n, bobpk, alicesk); + assert(ret == 0); +#ifdef BROWSER_TESTS + faults = 1; +#else + faults = 5; +#endif + while (faults > 0) { + c[rand() % (mlen + crypto_box_ZEROBYTES)] = rand(); + if (crypto_box_open(m2, c, mlen + crypto_box_ZEROBYTES, n, alicepk, + bobsk) == 0) { + for (i = 0; i < mlen + crypto_box_ZEROBYTES; ++i) { + if (m2[i] != m[i]) { + printf("forgery\n"); + return 100; + } + } + } else { + faults--; + } + } + } + sodium_free(m); + sodium_free(c); + sodium_free(m2); + + return 0; +} diff --git a/external/src/libsodium/test/default/box8.exp b/external/src/libsodium/test/default/box8.exp new file mode 100644 index 0000000..e69de29 diff --git a/external/src/libsodium/test/default/box_easy.c b/external/src/libsodium/test/default/box_easy.c new file mode 100644 index 0000000..2e6a20f --- /dev/null +++ b/external/src/libsodium/test/default/box_easy.c @@ -0,0 +1,72 @@ + +#define TEST_NAME "box_easy" +#include "cmptest.h" + +static unsigned char alicesk[32] = { 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, + 0x7d, 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, + 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, + 0xc0, 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, + 0x1d, 0xb9, 0x2c, 0x2a }; + +static unsigned char bobpk[32] = { 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, + 0xb4, 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, + 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8, 0x5b, + 0x78, 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, + 0x6f, 0x88, 0x2b, 0x4f }; + +static unsigned char nonce[24] = { 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, + 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8, + 0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, + 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 }; + +static unsigned char m[131] = { + 0xbe, 0x07, 0x5f, 0xc5, 0x3c, 0x81, 0xf2, 0xd5, 0xcf, 0x14, 0x13, 0x16, + 0xeb, 0xeb, 0x0c, 0x7b, 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4, + 0x4b, 0x66, 0x84, 0x9b, 0x64, 0x24, 0x4f, 0xfc, 0xe5, 0xec, 0xba, 0xaf, + 0x33, 0xbd, 0x75, 0x1a, 0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29, + 0x6c, 0xdc, 0x3c, 0x01, 0x23, 0x35, 0x61, 0xf4, 0x1d, 0xb6, 0x6c, 0xce, + 0x31, 0x4a, 0xdb, 0x31, 0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d, + 0xce, 0xea, 0x3a, 0x7f, 0xa1, 0x34, 0x80, 0x57, 0xe2, 0xf6, 0x55, 0x6a, + 0xd6, 0xb1, 0x31, 0x8a, 0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde, + 0x04, 0x89, 0x77, 0xeb, 0x48, 0xf5, 0x9f, 0xfd, 0x49, 0x24, 0xca, 0x1c, + 0x60, 0x90, 0x2e, 0x52, 0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40, + 0xe0, 0x82, 0xf9, 0x37, 0x76, 0x38, 0x48, 0x64, 0x5e, 0x07, 0x05 +}; + +static unsigned char c[147 + crypto_box_MACBYTES]; + +int +main(void) +{ + size_t i; + int ret; + + ret = crypto_box_easy(c, m, 131, nonce, bobpk, alicesk); + assert(ret == 0); + for (i = 0; i < 131 + crypto_box_MACBYTES; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + } + printf("\n"); + + /* Null message */ + + ret = crypto_box_easy(c, guard_page, 0, nonce, bobpk, alicesk); + assert(ret == 0); + for (i = 0; i < 1 + crypto_box_MACBYTES; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + } + printf("\n"); + + ret = + crypto_box_open_easy(c, c, crypto_box_MACBYTES, nonce, bobpk, alicesk); + assert(ret == 0); + for (i = 0; i < 1 + crypto_box_MACBYTES; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + } + printf("\n"); + c[randombytes_uniform(crypto_box_MACBYTES)]++; + ret = crypto_box_open_easy(c, c, crypto_box_MACBYTES, nonce, bobpk, alicesk); + assert(ret == -1); + + return 0; +} diff --git a/external/src/libsodium/test/default/box_easy.exp b/external/src/libsodium/test/default/box_easy.exp new file mode 100644 index 0000000..f13afd0 --- /dev/null +++ b/external/src/libsodium/test/default/box_easy.exp @@ -0,0 +1,3 @@ +,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74,0xe3,0x55,0xa5 +,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80,0x8e +,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80,0x8e diff --git a/external/src/libsodium/test/default/box_easy2.c b/external/src/libsodium/test/default/box_easy2.c new file mode 100644 index 0000000..05cb099 --- /dev/null +++ b/external/src/libsodium/test/default/box_easy2.c @@ -0,0 +1,149 @@ + +#define TEST_NAME "box_easy2" +#include "cmptest.h" + +static const unsigned char small_order_p[crypto_box_PUBLICKEYBYTES] = { + 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, + 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, + 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 +}; + +int +main(void) +{ + unsigned char *alicepk; + unsigned char *alicesk; + unsigned char *bobpk; + unsigned char *bobsk; + unsigned char *mac; + unsigned char *nonce; + unsigned char *k1; + unsigned char *k2; + unsigned char *m; + unsigned char *m2; + unsigned char *c; + size_t mlen; + size_t i; + size_t m_size; + size_t m2_size; + size_t c_size; + int ret; + + m2_size = m_size = 7U + randombytes_uniform(1000); + c_size = crypto_box_MACBYTES + m_size; + m = (unsigned char *) sodium_malloc(m_size); + m2 = (unsigned char *) sodium_malloc(m2_size); + c = (unsigned char *) sodium_malloc(c_size); + alicepk = (unsigned char *) sodium_malloc(crypto_box_PUBLICKEYBYTES); + alicesk = (unsigned char *) sodium_malloc(crypto_box_SECRETKEYBYTES); + bobpk = (unsigned char *) sodium_malloc(crypto_box_PUBLICKEYBYTES); + bobsk = (unsigned char *) sodium_malloc(crypto_box_SECRETKEYBYTES); + mac = (unsigned char *) sodium_malloc(crypto_box_MACBYTES); + nonce = (unsigned char *) sodium_malloc(crypto_box_NONCEBYTES); + k1 = (unsigned char *) sodium_malloc(crypto_box_BEFORENMBYTES); + k2 = (unsigned char *) sodium_malloc(crypto_box_BEFORENMBYTES); + crypto_box_keypair(alicepk, alicesk); + crypto_box_keypair(bobpk, bobsk); + mlen = (size_t) randombytes_uniform((uint32_t) m_size) + 1U; + randombytes_buf(m, mlen); + randombytes_buf(nonce, crypto_box_NONCEBYTES); + ret = crypto_box_easy(c, m, mlen, nonce, bobpk, alicesk); + assert(ret == 0); + if (crypto_box_open_easy(m2, c, + (unsigned long long) mlen + crypto_box_MACBYTES, + nonce, alicepk, bobsk) != 0) { + printf("open() failed"); + return 1; + } + printf("%d\n", memcmp(m, m2, mlen)); + + for (i = 0; i < mlen + crypto_box_MACBYTES - 1; i++) { + if (crypto_box_open_easy(m2, c, (unsigned long long) i, nonce, alicepk, + bobsk) == 0) { + printf("short open() should have failed"); + return 1; + } + } + memcpy(c, m, mlen); + ret = + crypto_box_easy(c, c, (unsigned long long) mlen, nonce, bobpk, alicesk); + assert(ret == 0); + printf("%d\n", memcmp(m, c, mlen) == 0); + printf("%d\n", memcmp(m, c + crypto_box_MACBYTES, mlen) == 0); + if (crypto_box_open_easy(c, c, + (unsigned long long) mlen + crypto_box_MACBYTES, + nonce, alicepk, bobsk) != 0) { + printf("crypto_box_open_easy() failed\n"); + } + + ret = crypto_box_beforenm(k1, small_order_p, bobsk); + assert(ret == -1); + ret = crypto_box_beforenm(k2, small_order_p, alicesk); + assert(ret == -1); + + ret = crypto_box_beforenm(k1, alicepk, bobsk); + assert(ret == 0); + ret = crypto_box_beforenm(k2, bobpk, alicesk); + assert(ret == 0); + + memset(m2, 0, m2_size); + + if (crypto_box_easy_afternm(c, m, 0, nonce, k1) != 0) { + printf( + "crypto_box_easy_afternm() with a null ciphertext should have " + "worked\n"); + } + crypto_box_easy_afternm(c, m, (unsigned long long) mlen, nonce, k1); + if (crypto_box_open_easy_afternm( + m2, c, (unsigned long long) mlen + crypto_box_MACBYTES, nonce, + k2) != 0) { + printf("crypto_box_open_easy_afternm() failed\n"); + } + printf("%d\n", memcmp(m, m2, mlen)); + if (crypto_box_open_easy_afternm(m2, c, crypto_box_MACBYTES - 1U, nonce, + k2) == 0) { + printf( + "crypto_box_open_easy_afternm() with a huge ciphertext should have " + "failed\n"); + } + memset(m2, 0, m2_size); + ret = crypto_box_detached(c, mac, m, (unsigned long long) mlen, nonce, + small_order_p, bobsk); + assert(ret == -1); + ret = crypto_box_detached(c, mac, m, (unsigned long long) mlen, nonce, + alicepk, bobsk); + assert(ret == 0); + if (crypto_box_open_detached(m2, c, mac, (unsigned long long) mlen, nonce, + small_order_p, alicesk) != -1) { + printf("crypto_box_open_detached() with a weak key passed\n"); + } + if (crypto_box_open_detached(m2, c, mac, (unsigned long long) mlen, nonce, + bobpk, alicesk) != 0) { + printf("crypto_box_open_detached() failed\n"); + } + printf("%d\n", memcmp(m, m2, mlen)); + + memset(m2, 0, m2_size); + crypto_box_detached_afternm(c, mac, m, (unsigned long long) mlen, nonce, + k1); + if (crypto_box_open_detached_afternm(m2, c, mac, (unsigned long long) mlen, + nonce, k2) != 0) { + printf("crypto_box_open_detached_afternm() failed\n"); + } + printf("%d\n", memcmp(m, m2, mlen)); + + sodium_free(alicepk); + sodium_free(alicesk); + sodium_free(bobpk); + sodium_free(bobsk); + sodium_free(mac); + sodium_free(nonce); + sodium_free(k1); + sodium_free(k2); + sodium_free(m); + sodium_free(m2); + sodium_free(c); + printf("OK\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/box_easy2.exp b/external/src/libsodium/test/default/box_easy2.exp new file mode 100644 index 0000000..9a8dd6c --- /dev/null +++ b/external/src/libsodium/test/default/box_easy2.exp @@ -0,0 +1,7 @@ +0 +0 +0 +0 +0 +0 +OK diff --git a/external/src/libsodium/test/default/box_seal.c b/external/src/libsodium/test/default/box_seal.c new file mode 100644 index 0000000..f28c041 --- /dev/null +++ b/external/src/libsodium/test/default/box_seal.c @@ -0,0 +1,165 @@ + +#define TEST_NAME "box_seal" +#include "cmptest.h" + +static +void tv1(void) +{ + unsigned char pk[crypto_box_PUBLICKEYBYTES]; + unsigned char sk[crypto_box_SECRETKEYBYTES]; + unsigned char *c; + unsigned char *m; + unsigned char *m2; + size_t m_len; + size_t c_len; + + crypto_box_keypair(pk, sk); + m_len = (size_t) randombytes_uniform(1000); + c_len = crypto_box_SEALBYTES + m_len; + m = (unsigned char *) sodium_malloc(m_len); + m2 = (unsigned char *) sodium_malloc(m_len); + c = (unsigned char *) sodium_malloc(c_len); + randombytes_buf(m, m_len); + if (crypto_box_seal(c, m, m_len, pk) != 0) { + printf("crypto_box_seal() failure\n"); + return; + } + if (crypto_box_seal_open(m2, c, c_len, pk, sk) != 0) { + printf("crypto_box_seal_open() failure\n"); + return; + } + printf("%d\n", memcmp(m, m2, m_len)); + + printf("%d\n", crypto_box_seal_open(m, c, 0U, pk, sk)); + printf("%d\n", crypto_box_seal_open(m, c, c_len - 1U, pk, sk)); + printf("%d\n", crypto_box_seal_open(m, c, c_len, sk, pk)); + + sodium_free(c); + sodium_free(m); + sodium_free(m2); + + assert(crypto_box_sealbytes() == crypto_box_SEALBYTES); +} + +static +void tv2(void) +{ + unsigned char pk[crypto_box_PUBLICKEYBYTES]; + unsigned char sk[crypto_box_SECRETKEYBYTES]; + unsigned char *cm; + unsigned char *m2; + size_t m_len; + size_t cm_len; + + crypto_box_keypair(pk, sk); + m_len = (size_t) randombytes_uniform(1000); + cm_len = crypto_box_SEALBYTES + m_len; + m2 = (unsigned char *) sodium_malloc(m_len); + cm = (unsigned char *) sodium_malloc(cm_len); + randombytes_buf(cm, m_len); + if (crypto_box_seal(cm, cm, m_len, pk) != 0) { + printf("crypto_box_seal() failure\n"); + return; + } + if (crypto_box_seal_open(m2, cm, cm_len, pk, sk) != 0) { + printf("crypto_box_seal_open() failure\n"); + return; + } + assert(m_len == 0 || memcmp(cm, m2, m_len) != 0); + sodium_free(cm); + sodium_free(m2); +} + +#ifndef SODIUM_LIBRARY_MINIMAL +static +void tv3(void) +{ + unsigned char pk[crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES]; + unsigned char sk[crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES]; + unsigned char *c; + unsigned char *m; + unsigned char *m2; + size_t m_len; + size_t c_len; + + crypto_box_curve25519xchacha20poly1305_keypair(pk, sk); + m_len = (size_t) randombytes_uniform(1000); + c_len = crypto_box_curve25519xchacha20poly1305_SEALBYTES + m_len; + m = (unsigned char *) sodium_malloc(m_len); + m2 = (unsigned char *) sodium_malloc(m_len); + c = (unsigned char *) sodium_malloc(c_len); + randombytes_buf(m, m_len); + if (crypto_box_curve25519xchacha20poly1305_seal(c, m, m_len, pk) != 0) { + printf("crypto_box_curve25519xchacha20poly1305_seal() failure\n"); + return; + } + if (crypto_box_curve25519xchacha20poly1305_seal_open(m2, c, c_len, pk, sk) != 0) { + printf("crypto_box_curve25519xchacha20poly1305_seal_open() failure\n"); + return; + } + printf("%d\n", memcmp(m, m2, m_len)); + + printf("%d\n", crypto_box_curve25519xchacha20poly1305_seal_open(m, c, 0U, pk, sk)); + printf("%d\n", crypto_box_curve25519xchacha20poly1305_seal_open(m, c, c_len - 1U, pk, sk)); + printf("%d\n", crypto_box_curve25519xchacha20poly1305_seal_open(m, c, c_len, sk, pk)); + + sodium_free(c); + sodium_free(m); + sodium_free(m2); + + assert(crypto_box_curve25519xchacha20poly1305_sealbytes() == + crypto_box_curve25519xchacha20poly1305_SEALBYTES); +} + +static +void tv4(void) +{ + unsigned char pk[crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES]; + unsigned char sk[crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES]; + unsigned char *cm; + unsigned char *m2; + size_t m_len; + size_t cm_len; + + crypto_box_curve25519xchacha20poly1305_keypair(pk, sk); + m_len = (size_t) randombytes_uniform(1000); + cm_len = crypto_box_curve25519xchacha20poly1305_SEALBYTES + m_len; + m2 = (unsigned char *) sodium_malloc(m_len); + cm = (unsigned char *) sodium_malloc(cm_len); + randombytes_buf(cm, m_len); + if (crypto_box_curve25519xchacha20poly1305_seal(cm, cm, m_len, pk) != 0) { + printf("crypto_box_curve25519xchacha20poly1305_seal() failure\n"); + return; + } + if (crypto_box_curve25519xchacha20poly1305_seal_open(m2, cm, cm_len, pk, sk) != 0) { + printf("crypto_box_curve25519xchacha20poly1305_seal_open() failure\n"); + return; + } + assert(m_len == 0 || memcmp(cm, m2, m_len) != 0); + sodium_free(cm); + sodium_free(m2); +} + +#else + +static +void tv3(void) +{ + printf("0\n-1\n-1\n-1\n"); +} + +static +void tv4(void) +{ } +#endif + +int +main(void) +{ + tv1(); + tv2(); + tv3(); + tv4(); + + return 0; +} diff --git a/external/src/libsodium/test/default/box_seal.exp b/external/src/libsodium/test/default/box_seal.exp new file mode 100644 index 0000000..ded7a43 --- /dev/null +++ b/external/src/libsodium/test/default/box_seal.exp @@ -0,0 +1,8 @@ +0 +-1 +-1 +-1 +0 +-1 +-1 +-1 diff --git a/external/src/libsodium/test/default/box_seed.c b/external/src/libsodium/test/default/box_seed.c new file mode 100644 index 0000000..95930d3 --- /dev/null +++ b/external/src/libsodium/test/default/box_seed.c @@ -0,0 +1,30 @@ + +#define TEST_NAME "box_seed" +#include "cmptest.h" + +static unsigned char seed[32] = { 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, + 0x7d, 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, + 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, + 0xc0, 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, + 0x1d, 0xb9, 0x2c, 0x2a }; + +int +main(void) +{ + int i; + unsigned char sk[32]; + unsigned char pk[32]; + + crypto_box_seed_keypair(pk, sk, seed); + for (i = 0; i < 32; ++i) { + printf(",0x%02x", (unsigned int) pk[i]); + if (i % 8 == 7) + printf("\n"); + } + for (i = 0; i < 32; ++i) { + printf(",0x%02x", (unsigned int) sk[i]); + if (i % 8 == 7) + printf("\n"); + } + return 0; +} diff --git a/external/src/libsodium/test/default/box_seed.exp b/external/src/libsodium/test/default/box_seed.exp new file mode 100644 index 0000000..20e6806 --- /dev/null +++ b/external/src/libsodium/test/default/box_seed.exp @@ -0,0 +1,8 @@ +,0xed,0x77,0x49,0xb4,0xd9,0x89,0xf6,0x95 +,0x7f,0x3b,0xfd,0xe6,0xc5,0x67,0x67,0xe9 +,0x88,0xe2,0x1c,0x9f,0x87,0x84,0xd9,0x1d +,0x61,0x00,0x11,0xcd,0x55,0x3f,0x9b,0x06 +,0xac,0xcd,0x44,0xeb,0x8e,0x93,0x31,0x9c +,0x05,0x70,0xbc,0x11,0x00,0x5c,0x0e,0x01 +,0x89,0xd3,0x4f,0xf0,0x2f,0x6c,0x17,0x77 +,0x34,0x11,0xad,0x19,0x12,0x93,0xc9,0x8f diff --git a/external/src/libsodium/test/default/chacha20.c b/external/src/libsodium/test/default/chacha20.c new file mode 100644 index 0000000..8b88745 --- /dev/null +++ b/external/src/libsodium/test/default/chacha20.c @@ -0,0 +1,186 @@ + +#define TEST_NAME "chacha20" +#include "cmptest.h" + +static +void tv(void) +{ + static struct { + const char *key_hex; + const char *nonce_hex; + } tests[] + = { { "0000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000" }, + { "0000000000000000000000000000000000000000000000000000000000000001", + "0000000000000000" }, + { "0000000000000000000000000000000000000000000000000000000000000000", + "0000000000000001" }, + { "0000000000000000000000000000000000000000000000000000000000000000", + "0100000000000000" }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "0001020304050607" } }; + unsigned char key[crypto_stream_chacha20_KEYBYTES]; + unsigned char nonce[crypto_stream_chacha20_NONCEBYTES]; + unsigned char *part; + unsigned char out[160]; + unsigned char zero[160]; + char out_hex[160 * 2 + 1]; + size_t i = 0U; + size_t plen; + + memset(zero, 0, sizeof zero); + do { + sodium_hex2bin((unsigned char *)key, sizeof key, tests[i].key_hex, + strlen(tests[i].key_hex), NULL, NULL, NULL); + sodium_hex2bin(nonce, sizeof nonce, tests[i].nonce_hex, + strlen(tests[i].nonce_hex), NULL, NULL, NULL); + crypto_stream_chacha20(out, sizeof out, nonce, key); + sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out); + printf("[%s]\n", out_hex); + for (plen = 1U; plen < sizeof out; plen++) { + part = (unsigned char *) sodium_malloc(plen); + crypto_stream_chacha20_xor(part, out, plen, nonce, key); + if (memcmp(part, zero, plen) != 0) { + printf("Failed with length %lu\n", (unsigned long) plen); + } + sodium_free(part); + } + } while (++i < (sizeof tests) / (sizeof tests[0])); + assert(66 <= sizeof out); + for (plen = 1U; plen < 66; plen += 3) { + memset(out, (int) (plen & 0xff), sizeof out); + crypto_stream_chacha20(out, plen, nonce, key); + sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out); + printf("[%s]\n", out_hex); + } + randombytes_buf(out, sizeof out); + crypto_stream_chacha20(out, sizeof out, nonce, key); + sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out); + printf("[%s]\n", out_hex); + + assert(crypto_stream_chacha20(out, 0U, nonce, key) == 0); + assert(crypto_stream_chacha20_xor(out, out, 0U, nonce, key) == 0); + assert(crypto_stream_chacha20_xor(out, out, 0U, nonce, key) == 0); + assert(crypto_stream_chacha20_xor_ic(out, out, 0U, nonce, 1U, key) == 0); + + memset(out, 0x42, sizeof out); + crypto_stream_chacha20_xor(out, out, sizeof out, nonce, key); + sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out); + printf("[%s]\n", out_hex); + + crypto_stream_chacha20_xor_ic(out, out, sizeof out, nonce, 0U, key); + sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out); + printf("[%s]\n", out_hex); + + crypto_stream_chacha20_xor_ic(out, out, sizeof out, nonce, 1U, key); + sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out); + printf("[%s]\n", out_hex); +} + +static +void tv_ietf(void) +{ + static struct { + const char *key_hex; + const char *nonce_hex; + uint32_t ic; + } tests[] + = { { "0000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000", + 0U }, + { "0000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000", + 1U }, + { "0000000000000000000000000000000000000000000000000000000000000001", + "000000000000000000000000", + 1U }, + { "00ff000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000", + 2U }, + { "0000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000002", + 0U }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "000000090000004a00000000", + 1U }, + { "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "000000090000004a00000000", + 0xfeffffff }}; + unsigned char key[crypto_stream_chacha20_KEYBYTES]; + unsigned char nonce[crypto_stream_chacha20_IETF_NONCEBYTES]; + unsigned char *part; + unsigned char out[160]; + unsigned char zero[160]; + char out_hex[160 * 2 + 1]; + size_t i = 0U; + size_t plen; + + memset(zero, 0, sizeof zero); + do { + sodium_hex2bin((unsigned char *)key, sizeof key, tests[i].key_hex, + strlen(tests[i].key_hex), ": ", NULL, NULL); + sodium_hex2bin(nonce, sizeof nonce, tests[i].nonce_hex, + strlen(tests[i].nonce_hex), ": ", NULL, NULL); + memset(out, 0, sizeof out); + crypto_stream_chacha20_ietf_xor_ic(out, out, sizeof out, nonce, tests[i].ic, key); + sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out); + printf("[%s]\n", out_hex); + for (plen = 1U; plen < sizeof out; plen++) { + part = (unsigned char *) sodium_malloc(plen); + crypto_stream_chacha20_ietf_xor_ic(part, out, plen, nonce, tests[i].ic, key); + if (memcmp(part, zero, plen) != 0) { + printf("Failed with length %lu\n", (unsigned long) plen); + } + sodium_free(part); + } + } while (++i < (sizeof tests) / (sizeof tests[0])); + assert(66 <= sizeof out); + for (plen = 1U; plen < 66; plen += 3) { + memset(out, (int) (plen & 0xff), sizeof out); + crypto_stream_chacha20_ietf(out, plen, nonce, key); + sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out); + printf("[%s]\n", out_hex); + } + randombytes_buf(out, sizeof out); + crypto_stream_chacha20_ietf(out, sizeof out, nonce, key); + sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out); + printf("[%s]\n", out_hex); + + assert(crypto_stream_chacha20_ietf(out, 0U, nonce, key) == 0); + assert(crypto_stream_chacha20_ietf_xor(out, out, 0U, nonce, key) == 0); + assert(crypto_stream_chacha20_ietf_xor(out, out, 0U, nonce, key) == 0); + assert(crypto_stream_chacha20_ietf_xor_ic(out, out, 0U, nonce, 1U, key) == 0); + + memset(out, 0x42, sizeof out); + crypto_stream_chacha20_ietf_xor(out, out, sizeof out, nonce, key); + sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out); + printf("[%s]\n", out_hex); + + crypto_stream_chacha20_ietf_xor_ic(out, out, sizeof out, nonce, 0U, key); + sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out); + printf("[%s]\n", out_hex); + + crypto_stream_chacha20_ietf_xor_ic(out, out, sizeof out, nonce, 1U, key); + sodium_bin2hex(out_hex, sizeof out_hex, out, sizeof out); + printf("[%s]\n", out_hex); +} + +int +main(void) +{ + tv(); + tv_ietf(); + + assert(crypto_stream_chacha20_keybytes() > 0U); + assert(crypto_stream_chacha20_keybytes() == crypto_stream_chacha20_KEYBYTES); + assert(crypto_stream_chacha20_noncebytes() > 0U); + assert(crypto_stream_chacha20_noncebytes() == crypto_stream_chacha20_NONCEBYTES); + assert(crypto_stream_chacha20_messagebytes_max() == crypto_stream_chacha20_MESSAGEBYTES_MAX); + assert(crypto_stream_chacha20_ietf_keybytes() > 0U); + assert(crypto_stream_chacha20_ietf_keybytes() == crypto_stream_chacha20_ietf_KEYBYTES); + assert(crypto_stream_chacha20_ietf_noncebytes() > 0U); + assert(crypto_stream_chacha20_ietf_noncebytes() == crypto_stream_chacha20_ietf_NONCEBYTES); + assert(crypto_stream_chacha20_ietf_messagebytes_max() == crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX); + + return 0; +} diff --git a/external/src/libsodium/test/default/chacha20.exp b/external/src/libsodium/test/default/chacha20.exp new file mode 100644 index 0000000..aafaf29 --- /dev/null +++ b/external/src/libsodium/test/default/chacha20.exp @@ -0,0 +1,64 @@ +[76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee65869f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed29b721769ce64e43d57133b074d839d531ed1f28510afb45ace10a1f4b794d6f2d09a0e663266ce1ae7ed1081968a0758e718e997bd362c6b0c34634a9a0b35d] +[4540f05a9f1fb296d7736e7b208e3c96eb4fe1834688d2604f450952ed432d41bbe2a0b6ea7566d2a5d1e7e20d42af2c53d792b1c43fea817e9ad275ae5469633aeb5224ecf849929b9d828db1ced4dd832025e8018b8160b82284f3c949aa5a8eca00bbb4a73bdad192b5c42f73f2fd4e273644c8b36125a64addeb006c13a096d68b9ff7b57e7090f880392effd5b297a83bbaf2fbe8cf5d4618965e3dc776] +[de9cba7bf3d69ef5e786dc63973f653a0b49e015adbff7134fcb7df137821031e85a050278a7084527214f73efc7fa5b5277062eb7a0433e445f41e31afab757283547e3d3d30ee0371c1e6025ff4c91b794a291cf7568d48ff84b37329e2730b12738a072a2b2c7169e326fe4893a7b2421bb910b79599a7ce4fbaee86be427c5ee0e8225eb6f48231fd504939d59eac8bd106cc138779b893c54da8758f62a] +[ef3fdfd6c61578fbf5cf35bd3dd33b8009631634d21e42ac33960bd138e50d32111e4caf237ee53ca8ad6426194a88545ddc497a0b466e7d6bbdb0041b2f586b5305e5e44aff19b235936144675efbe4409eb7e8e5f1430f5f5836aeb49bb5328b017c4b9dc11f8a03863fa803dc71d5726b2b6b31aa32708afe5af1d6b690584d58792b271e5fdb92c486051c48b79a4d48a109bb2d0477956e74c25e93c3c2] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025] +[f7010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101] +[f798a189040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404] +[f798a189f195e6070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707] +[f798a189f195e66982100a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a] +[f798a189f195e66982105ffb640d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d] +[f798a189f195e66982105ffb640bb775101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010] +[f798a189f195e66982105ffb640bb7757f579d131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313] +[f798a189f195e66982105ffb640bb7757f579da31602161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac561c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac31f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b73252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b4641282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c92b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c94400492e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f159163a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2b3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040] +[f798a189f195e66982105ffb640bb7757f579da31602fc93ec01ac56f85ac3c134a4547b733b46413042c9440049176905d3be59ea1c53f15916155c2be8241a38008b9a26bc35941e2444177c8ade6689de95264986d95889fb60e84629c9bd9a5acb1cc118be563eb9b3a4a472f82e09a7e778492b562ef7130e88dfe031c79db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025] +[b5dae3cbb3d7a42bc0521db92649f5373d15dfe15440bed1ae43ee14ba18818376e616393179040372008b06420b552b4791fc1ba85e11b31b54571e69aa66587a42c9d864fe77d65c6606553ec89c24cb9cd7640bc49b1acbb922aa046b8bffd818895e835afc147cfbf1e6e630ba6c4be5a53a0b69146cb5514cca9da27385dffb96b585eadb5759d8051270f47d81c7661da216a19f18d5e7b734bc440267] +[42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242] +[7a42c9d864fe77d65c6606553ec89c24cb9cd7640bc49b1acbb922aa046b8bffd818895e835afc147cfbf1e6e630ba6c4be5a53a0b69146cb5514cca9da27385dffb96b585eadb5759d8051270f47d81c7661da216a19f18d5e7b734bc440267918c466e1428f08745f37a99c77c7f2b1b244bd4162e8b86e4a8bf85358202954ced04b52fef7b3ba787744e715554285ecb0ed6e133c528d69d346abc0ce8b0] +[76b8e0ada0f13d90405d6ae55386bd28bdd219b8a08ded1aa836efcc8b770dc7da41597c5157488d7724e03fb8d84a376a43b8f41518a11cc387b669b2ee65869f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed29b721769ce64e43d57133b074d839d531ed1f28510afb45ace10a1f4b794d6f2d09a0e663266ce1ae7ed1081968a0758e718e997bd362c6b0c34634a9a0b35d] +[9f07e7be5551387a98ba977c732d080dcb0f29a048e3656912c6533e32ee7aed29b721769ce64e43d57133b074d839d531ed1f28510afb45ace10a1f4b794d6f2d09a0e663266ce1ae7ed1081968a0758e718e997bd362c6b0c34634a9a0b35d012737681f7b5d0f281e3afde458bc1e73d2d313c9cf94c05ff3716240a248f21320a058d7b3566bd520daaa3ed2bf0ac5b8b120fb852773c3639734b45c91a4] +[3aeb5224ecf849929b9d828db1ced4dd832025e8018b8160b82284f3c949aa5a8eca00bbb4a73bdad192b5c42f73f2fd4e273644c8b36125a64addeb006c13a096d68b9ff7b57e7090f880392effd5b297a83bbaf2fbe8cf5d4618965e3dc776cd430d9b4e7eda8a767fb0e860319aadb5fd96a855de1fbfc92cb0489190cfdd87da6dbf1f736a2d499941ca097e5170bd685578611323120cebf296181ed4f5] +[72d54dfbf12ec44b362692df94137f328fea8da73990265ec1bbbea1ae9af0ca13b25aa26cb4a648cb9b9d1be65b2c0924a66c54d545ec1b7374f4872e99f096bf74dbd52cc4fc95ceb6097fe5e65358c9dbc0a5ecbf7894a132a9a54ae3e951f2e9f209aa9c3d9a877ac9dab62433d2961a17d103e455dfb7337c90f6857aad233065955a212b5c7a8eab4dc8a629e5b6b8ba914afd06de7177054b33d21c96] +[c2c64d378cd536374ae204b9ef933fcd1a8b2288b3dfa49672ab765b54ee27c78a970e0e955c14f3a88e741b97c286f75f8fc299e8148362fa198a39531bed6d1a91288c874ec254f322c2a197340c55bb3e9b3998f7de2309486a0bb494abd20c9c5ef99c1370d61e77f408ac5514f49202bcc6828d45409d2d1416f8ae106b06ebd2541256264fa415bd54cb12e1d4449ed85299a1b7a249b75ff6c89b2e3f] +[10f1e7e4d13b5915500fdd1fa32071c4c7d1f4c733c068030422aa9ac3d46c4ed2826446079faa0914c2d705d98b02a2b5129cd1de164eb9cbd083e8a2503c4e0a88837739d7bf4ef8ccacb0ea2bb9d69d56c394aa351dfda5bf459f0a2e9fe8e721f89255f9c486bf21679c683d4f9c5cf2fa27865526005b06ca374c86af3bdcbfbdcb83be65862ed5c20eae5a43241d6a92da6dca9a156be25297f51c2718] +[75924bad7831b25662dbac54b46827990b6168ae990e7bd7e1fd2ad282bf23ef052c7d1a0a6c1ef862070943a0d4da24705fbc006dfb85e2af18c0a264d772a44c70fbedac9d6a6867ff6be0a32826507f2c784101583211c9e2453d4cc8b283d5e86682bd4bf511271b91dbd351415f5a009d1f78b64085a9a4341be7d42e2679d57e2747097f0129950e2c9e9ca1356022d45da252af71ac37f351a2e77911] +[8a010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101] +[8adc91fd040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404] +[8adc91fd9ff4f0070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707] +[8adc91fd9ff4f0f51b0f0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a] +[8adc91fd9ff4f0f51b0fad50ff0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d] +[8adc91fd9ff4f0f51b0fad50ff15d637101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efd131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616161616] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919191919] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a742001c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c151f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd98222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525252525] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d5282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828282828] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f492e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f490ee69c313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313131] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f490ee69ca34c1f343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434343434] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f490ee69ca34c1ff9e939373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737373737] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f490ee69ca34c1ff9e939a755843a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f490ee69ca34c1ff9e939a75584c52d693d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d3d] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f490ee69ca34c1ff9e939a75584c52d690a35d4404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040] +[8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f490ee69ca34c1ff9e939a75584c52d690a35d410f1e7e4d13b5915500fdd1fa32071c4c7d1f4c733c068030422aa9ac3d46c4ed2826446079faa0914c2d705d98b02a2b5129cd1de164eb9cbd083e8a2503c4e0a88837739d7bf4ef8ccacb0ea2bb9d69d56c394aa351dfda5bf459f0a2e9fe8] +[c89ed3bfddb6b2b7594def12bd579475a64cbfe0448e1085c1e50042127e57c08fda71743f4816973f7edcdbcd0b4ca4dee10e5dbbab7be517c6876f2b48779652b3a5a693791b57124d9f5de16233868593b68571822a414660e8d881962e0c90c0260445dde84b568095479bc940e0f750de939c540cfb8992c1aae0127e0c48cac1357b95fd0cba8eeef2a869fb94df1481d6e8775fbfe7fd07dd486cddaa] +[42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242] +[52b3a5a693791b57124d9f5de16233868593b68571822a414660e8d881962e0c90c0260445dde84b568095479bc940e0f750de939c540cfb8992c1aae0127e0c48cac1357b95fd0cba8eeef2a869fb94df1481d6e8775fbfe7fd07dd486cddaaa563bad017bb86c4fd6325de2a7f0dde1eb0b865c4176442194488750ec4ed799efdff89c1fc27c46c97804cec1801665f28d0982f88d85729a010d5b75e655a] diff --git a/external/src/libsodium/test/default/cmptest.h b/external/src/libsodium/test/default/cmptest.h new file mode 100644 index 0000000..b1261bd --- /dev/null +++ b/external/src/libsodium/test/default/cmptest.h @@ -0,0 +1,231 @@ + +#ifndef __CMPTEST_H__ +#define __CMPTEST_H__ + +#ifdef NDEBUG +#/**/undef/**/ NDEBUG +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include "sodium.h" +#include "quirks.h" + +#ifdef __EMSCRIPTEN__ +# undef TEST_SRCDIR +# define TEST_SRCDIR "/test-data" +#endif +#ifndef TEST_SRCDIR +# define TEST_SRCDIR "." +#endif + +#define TEST_NAME_RES TEST_NAME ".res" +#define TEST_NAME_OUT TEST_SRCDIR "/" TEST_NAME ".exp" + +#ifdef HAVE_ARC4RANDOM +# undef rand +# define rand(X) arc4random(X) +#endif + +int xmain(void); + +static unsigned char *guard_page; + +#ifdef BENCHMARKS + +# include + +# ifndef ITERATIONS +# define ITERATIONS 128 +# endif + +struct { + void *pnt; + size_t size; +} mempool[1024]; + +static size_t mempool_idx; + +static __attribute__((malloc)) void *mempool_alloc(size_t size) +{ + size_t i; + if (size >= (size_t) 0x80000000 - (size_t) 0x00000fff) { + return NULL; + } + size = (size + (size_t) 0x00000fff) & ~ (size_t) 0x00000fff; + for (i = 0U; i < mempool_idx; i++) { + if (mempool[i].size >= (size | (size_t) 0x80000000)) { + mempool[i].size &= ~ (size_t) 0x80000000; + return mempool[i].pnt; + } + } + if (mempool_idx >= sizeof mempool / sizeof mempool[0]) { + return NULL; + } + mempool[mempool_idx].size = size; + return (mempool[mempool_idx++].pnt = (void *) malloc(size)); +} + +static void mempool_free(void *pnt) +{ + size_t i; + for (i = 0U; i < mempool_idx; i++) { + if (mempool[i].pnt == pnt) { + if ((mempool[i].size & (size_t) 0x80000000) != (size_t) 0x0) { + break; + } + mempool[i].size |= (size_t) 0x80000000; + return; + } + } + abort(); +} + +static __attribute__((malloc)) void *mempool_allocarray(size_t count, size_t size) +{ + if (count > (size_t) 0U && size >= (size_t) SIZE_MAX / count) { + return NULL; + } + return mempool_alloc(count * size); +} + +static int mempool_free_all(void) +{ + size_t i; + int ret = 0; + + for (i = 0U; i < mempool_idx; i++) { + if ((mempool[i].size & (size_t) 0x80000000) == (size_t) 0x0) { + ret = -1; + } + free(mempool[i].pnt); + mempool[i].pnt = NULL; + } + mempool_idx = (size_t) 0U; + + return ret; +} + +#define sodium_malloc(X) mempool_alloc(X) +#define sodium_free(X) mempool_free(X) +#define sodium_allocarray(X, Y) mempool_allocarray((X), (Y)) + +static unsigned long long now(void) +{ + struct timeval tp; + unsigned long long now; + + if (gettimeofday(&tp, NULL) != 0) { + abort(); + } + now = ((unsigned long long) tp.tv_sec * 1000000ULL) + + (unsigned long long) tp.tv_usec; + + return now; +} + +int main(void) +{ + unsigned long long ts_start; + unsigned long long ts_end; + unsigned int i; + + if (sodium_init() != 0) { + return 99; + } + +#ifndef __EMSCRIPTEN__ + randombytes_set_implementation(&randombytes_salsa20_implementation); +#endif + ts_start = now(); + for (i = 0; i < ITERATIONS; i++) { + if (xmain() != 0) { + abort(); + } + } + ts_end = now(); + printf("%llu\n", 1000000ULL * (ts_end - ts_start) / ITERATIONS); + if (mempool_free_all() != 0) { + fprintf(stderr, "** memory leaks detected **\n"); + return 99; + } + return 0; +} + +#undef printf +#define printf(...) do { } while(0) + +#elif !defined(BROWSER_TESTS) + +static FILE *fp_res; + +int main(void) +{ + FILE *fp_out; + unsigned char *_guard_page; + int c; + + if ((fp_res = fopen(TEST_NAME_RES, "w+")) == NULL) { + perror("fopen(" TEST_NAME_RES ")"); + return 99; + } + if (sodium_init() != 0) { + return 99; + } +# if defined(__EMSCRIPTEN__) || defined(__SANITIZE_ADDRESS__) + guard_page = _guard_page = NULL; +#else + if ((_guard_page = (unsigned char *) sodium_malloc(0)) == NULL) { + perror("sodium_malloc()"); + return 99; + } + guard_page = _guard_page + 1; +#endif + if (xmain() != 0) { + return 99; + } + fflush(fp_res); + rewind(fp_res); + if ((fp_out = fopen(TEST_NAME_OUT, "r")) == NULL) { + perror("fopen(" TEST_NAME_OUT ")"); + return 99; + } + do { + if ((c = fgetc(fp_res)) != fgetc(fp_out)) { + return 99; + } + } while (c != EOF); + sodium_free(_guard_page); + + return 0; +} + +#undef printf +#define printf(...) fprintf(fp_res, __VA_ARGS__) + +#else + +int main(void) +{ + if (sodium_init() != 0) { + return 99; + } + if (xmain() != 0) { + return 99; + } + printf("--- SUCCESS ---\n"); + + return 0; +} + +#endif + +#define main xmain + +#endif diff --git a/external/src/libsodium/test/default/codecs.c b/external/src/libsodium/test/default/codecs.c new file mode 100644 index 0000000..3c98d73 --- /dev/null +++ b/external/src/libsodium/test/default/codecs.c @@ -0,0 +1,251 @@ +#define TEST_NAME "codecs" +#include "cmptest.h" + +int +main(void) +{ + unsigned char buf1[1000]; + char buf3[33]; + unsigned char buf4[4]; + const char *b64; + char *b64_; + const char *b64_end; + unsigned char *bin; + const char *hex; + const char *hex_end; + size_t b64_len; + size_t bin_len; + unsigned int i; + + printf("%s\n", + sodium_bin2hex(buf3, 33U, (const unsigned char *) "0123456789ABCDEF", + 16U)); + printf("bin2hex(..., guard_page, 0):%s\n", + sodium_bin2hex(buf3, sizeof buf3, guard_page, 0U)); + printf("bin2hex(..., \"\", 0):%s\n", + sodium_bin2hex(buf3, sizeof buf3, (const unsigned char *) "", 0U)); + + hex = "Cafe : 6942"; + sodium_hex2bin(buf4, sizeof buf4, hex, strlen(hex), ": ", &bin_len, + &hex_end); + printf("%lu:%02x%02x%02x%02x\n", (unsigned long) bin_len, + buf4[0], buf4[1], buf4[2], buf4[3]); + printf("dt1: %ld\n", (long) (hex_end - hex)); + + hex = "Cafe : 6942"; + sodium_hex2bin(buf4, sizeof buf4, hex, strlen(hex), ": ", &bin_len, NULL); + printf("%lu:%02x%02x%02x%02x\n", (unsigned long) bin_len, + buf4[0], buf4[1], buf4[2], buf4[3]); + + hex = "deadbeef"; + if (sodium_hex2bin(buf1, 1U, hex, 8U, NULL, &bin_len, &hex_end) != -1) { + printf("sodium_hex2bin() overflow not detected\n"); + } + printf("dt2: %ld\n", (long) (hex_end - hex)); + + hex = "de:ad:be:eff"; + if (sodium_hex2bin(buf1, 4U, hex, 12U, ":", &bin_len, &hex_end) != -1) { + printf( + "sodium_hex2bin() with an odd input length and a short output " + "buffer\n"); + } + printf("dt3: %ld\n", (long) (hex_end - hex)); + + hex = "de:ad:be:eff"; + if (sodium_hex2bin(buf1, sizeof buf1, hex, 12U, ":", + &bin_len, &hex_end) != -1) { + printf("sodium_hex2bin() with an odd input length\n"); + } + printf("dt4: %ld\n", (long) (hex_end - hex)); + + hex = "de:ad:be:eff"; + if (sodium_hex2bin(buf1, sizeof buf1, hex, 13U, ":", + &bin_len, &hex_end) != -1) { + printf("sodium_hex2bin() with an odd input length (2)\n"); + } + printf("dt5: %ld\n", (long) (hex_end - hex)); + + hex = "de:ad:be:eff"; + if (sodium_hex2bin(buf1, sizeof buf1, hex, 12U, ":", + &bin_len, NULL) != -1) { + printf("sodium_hex2bin() with an odd input length and no end pointer\n"); + } + + hex = "de:ad:be:ef*"; + if (sodium_hex2bin(buf1, sizeof buf1, hex, 12U, ":", + &bin_len, &hex_end) != 0) { + printf("sodium_hex2bin() with an extra character and an end pointer\n"); + } + printf("dt6: %ld\n", (long) (hex_end - hex)); + + hex = "de:ad:be:ef*"; + if (sodium_hex2bin(buf1, sizeof buf1, hex, 12U, ":", + &bin_len, NULL) != -1) { + printf("sodium_hex2bin() with an extra character and no end pointer\n"); + } + + assert(sodium_hex2bin(buf4, sizeof buf4, (const char *) guard_page, 0U, + NULL, &bin_len, NULL) == 0); + assert(bin_len == 0); + + assert(sodium_hex2bin(buf4, sizeof buf4, "", 0U, NULL, &bin_len, NULL) == 0); + assert(bin_len == 0); + + printf("%s\n", + sodium_bin2base64(buf3, 31U, (const unsigned char *) "\xfb\xf0\xf1" "0123456789ABCDEFab", + 21U, sodium_base64_VARIANT_ORIGINAL)); + printf("%s\n", + sodium_bin2base64(buf3, 33U, (const unsigned char *) "\xfb\xf0\xf1" "0123456789ABCDEFabc", + 22U, sodium_base64_VARIANT_ORIGINAL_NO_PADDING)); + printf("%s\n", + sodium_bin2base64(buf3, 31U, (const unsigned char *) "\xfb\xf0\xf1" "0123456789ABCDEFab", + 21U, sodium_base64_VARIANT_URLSAFE)); + printf("%s\n", + sodium_bin2base64(buf3, 33U, (const unsigned char *) "\xfb\xf0\xf1" "0123456789ABCDEFabc", + 22U, sodium_base64_VARIANT_URLSAFE_NO_PADDING)); + printf("%s\n", + sodium_bin2base64(buf3, 1U, guard_page, + 0U, sodium_base64_VARIANT_ORIGINAL)); + printf("%s\n", + sodium_bin2base64(buf3, 5U, (const unsigned char *) "a", + 1U, sodium_base64_VARIANT_ORIGINAL)); + printf("%s\n", + sodium_bin2base64(buf3, 5U, (const unsigned char *) "ab", + 2U, sodium_base64_VARIANT_ORIGINAL)); + printf("%s\n", + sodium_bin2base64(buf3, 5U, (const unsigned char *) "abc", + 3U, sodium_base64_VARIANT_ORIGINAL)); + printf("%s\n", + sodium_bin2base64(buf3, 1U, guard_page, + 0U, sodium_base64_VARIANT_ORIGINAL_NO_PADDING)); + printf("%s\n", + sodium_bin2base64(buf3, 3U, (const unsigned char *) "a", + 1U, sodium_base64_VARIANT_ORIGINAL_NO_PADDING)); + printf("%s\n", + sodium_bin2base64(buf3, 4U, (const unsigned char *) "ab", + 2U, sodium_base64_VARIANT_ORIGINAL_NO_PADDING)); + printf("%s\n", + sodium_bin2base64(buf3, 5U, (const unsigned char *) "abc", + 3U, sodium_base64_VARIANT_ORIGINAL_NO_PADDING)); + + b64 = "VGhpcyBpcyBhIGpvdXJu" "\n" "ZXkgaW50by" " " "Bzb3VuZA=="; + memset(buf4, '*', sizeof buf4); + assert(sodium_base642bin(buf4, sizeof buf4, b64, strlen(b64), "\n\r ", &bin_len, + &b64_end, sodium_base64_VARIANT_ORIGINAL) == -1); + buf4[bin_len] = 0; + printf("[%s]\n", (const char *) buf4); + printf("[%s]\n", b64_end); + + memset(buf1, '*', sizeof buf1); + assert(sodium_base642bin(buf1, sizeof buf1, b64, strlen(b64), "\n\r ", &bin_len, + &b64_end, sodium_base64_VARIANT_ORIGINAL) == 0); + buf1[bin_len] = 0; + printf("[%s]\n", (const char *) buf1); + assert(*b64_end == 0); + + memset(buf1, '*', sizeof buf1); + assert(sodium_base642bin(buf1, sizeof buf1, b64, strlen(b64), NULL, &bin_len, + &b64_end, sodium_base64_VARIANT_ORIGINAL) == 0); + buf1[bin_len] = 0; + printf("[%s]\n", (const char *) buf1); + printf("[%s]\n", b64_end); + + assert(sodium_base642bin(buf1, sizeof buf1, b64, strlen(b64), NULL, NULL, + &b64_end, sodium_base64_VARIANT_ORIGINAL) == 0); + assert(sodium_base642bin(buf1, sizeof buf1, b64, strlen(b64), NULL, NULL, + &b64_end, sodium_base64_VARIANT_ORIGINAL_NO_PADDING) == 0); + assert(sodium_base642bin(buf1, sizeof buf1, b64, strlen(b64), " \r\n", NULL, + &b64_end, sodium_base64_VARIANT_ORIGINAL_NO_PADDING) == 0); + assert(sodium_base642bin(buf1, sizeof buf1, b64, strlen(b64), NULL, NULL, + &b64_end, sodium_base64_VARIANT_URLSAFE_NO_PADDING) == 0); + assert(sodium_base642bin(buf1, sizeof buf1, b64, strlen(b64), " \r\n", NULL, + &b64_end, sodium_base64_VARIANT_URLSAFE_NO_PADDING) == 0); + + assert(sodium_base642bin(buf1, sizeof buf1, b64, strlen(b64), NULL, NULL, + NULL, sodium_base64_VARIANT_ORIGINAL) == -1); + assert(sodium_base642bin(buf1, sizeof buf1, b64, strlen(b64), NULL, NULL, + NULL, sodium_base64_VARIANT_ORIGINAL_NO_PADDING) == -1); + assert(sodium_base642bin(buf1, sizeof buf1, b64, strlen(b64), " \r\n", NULL, + NULL, sodium_base64_VARIANT_ORIGINAL_NO_PADDING) == -1); + assert(sodium_base642bin(buf1, sizeof buf1, b64, strlen(b64), NULL, NULL, + NULL, sodium_base64_VARIANT_URLSAFE_NO_PADDING) == -1); + assert(sodium_base642bin(buf1, sizeof buf1, b64, strlen(b64), " \r\n", NULL, + NULL, sodium_base64_VARIANT_URLSAFE_NO_PADDING) == -1); + + assert(sodium_base642bin(guard_page, (size_t) 10U, "a=", (size_t) 2U, NULL, NULL, NULL, + sodium_base64_VARIANT_URLSAFE) == -1); + assert(sodium_base642bin(guard_page, (size_t) 10U, "a*", (size_t) 2U, NULL, NULL, NULL, + sodium_base64_VARIANT_URLSAFE) == -1); + assert(sodium_base642bin(guard_page, (size_t) 10U, "a*", (size_t) 2U, "~", NULL, NULL, + sodium_base64_VARIANT_URLSAFE) == -1); + assert(sodium_base642bin(guard_page, (size_t) 10U, "a*", (size_t) 2U, "*", NULL, NULL, + sodium_base64_VARIANT_URLSAFE) == -1); + assert(sodium_base642bin(guard_page, (size_t) 10U, "a==", (size_t) 3U, NULL, NULL, NULL, + sodium_base64_VARIANT_URLSAFE) == -1); + assert(sodium_base642bin(guard_page, (size_t) 10U, "a=*", (size_t) 3U, NULL, NULL, NULL, + sodium_base64_VARIANT_URLSAFE) == -1); + assert(sodium_base642bin(guard_page, (size_t) 10U, "a=*", (size_t) 3U, "~", NULL, NULL, + sodium_base64_VARIANT_URLSAFE) == -1); + assert(sodium_base642bin(guard_page, (size_t) 10U, "a=*", (size_t) 3U, "*", NULL, NULL, + sodium_base64_VARIANT_URLSAFE) == -1); + + assert(sodium_base642bin(buf1, sizeof buf1, "O1R", (size_t) 3U, NULL, NULL, NULL, + sodium_base64_VARIANT_ORIGINAL_NO_PADDING) == -1); + assert(sodium_base642bin(buf1, sizeof buf1, "O1Q", (size_t) 3U, NULL, NULL, NULL, + sodium_base64_VARIANT_ORIGINAL_NO_PADDING) == 0); + assert(sodium_base642bin(buf1, sizeof buf1, "O1", (size_t) 2U, NULL, NULL, NULL, + sodium_base64_VARIANT_ORIGINAL_NO_PADDING) == -1); + assert(sodium_base642bin(buf1, sizeof buf1, "Ow", (size_t) 2U, NULL, NULL, NULL, + sodium_base64_VARIANT_ORIGINAL_NO_PADDING) == 0); + assert(sodium_base642bin(buf1, sizeof buf1, "O", (size_t) 1U, NULL, NULL, NULL, + sodium_base64_VARIANT_ORIGINAL_NO_PADDING) == -1); + + assert(sodium_base642bin(buf1, sizeof buf1, "", (size_t) 0U, NULL, NULL, NULL, + sodium_base64_VARIANT_ORIGINAL) == 0); + assert(sodium_base642bin(buf1, sizeof buf1, "A", (size_t) 1U, NULL, NULL, NULL, + sodium_base64_VARIANT_ORIGINAL) == -1); + assert(sodium_base642bin(buf1, sizeof buf1, "AA", (size_t) 2U, NULL, NULL, NULL, + sodium_base64_VARIANT_ORIGINAL) == -1); + assert(sodium_base642bin(buf1, sizeof buf1, "kaw", (size_t) 3U, NULL, NULL, NULL, + sodium_base64_VARIANT_ORIGINAL) == -1); + assert(sodium_base642bin(buf1, sizeof buf1, "kQ*", (size_t) 3U, "@", NULL, NULL, + sodium_base64_VARIANT_ORIGINAL) == -1); + assert(sodium_base642bin(buf1, sizeof buf1, "kQ*", (size_t) 3U, "*", NULL, NULL, + sodium_base64_VARIANT_ORIGINAL) == -1); + assert(sodium_base642bin(buf1, sizeof buf1, "kaw=**", (size_t) 6U, "*", NULL, NULL, + sodium_base64_VARIANT_ORIGINAL) == 0); + assert(sodium_base642bin(buf1, sizeof buf1, "kaw*=*", (size_t) 6U, "~*", NULL, NULL, + sodium_base64_VARIANT_ORIGINAL) == 0); + assert(sodium_base642bin(buf1, sizeof buf1, "ka*w*=*", (size_t) 7U, "*~", NULL, NULL, + sodium_base64_VARIANT_ORIGINAL) == 0); + + assert(sodium_base642bin(buf1, sizeof buf1, (const char *) guard_page, 0U, + NULL, &bin_len, NULL, sodium_base64_VARIANT_ORIGINAL) == 0); + assert(bin_len == 0); + + assert(sodium_base642bin(buf1, sizeof buf1, "", 0U, NULL, &bin_len, NULL, + sodium_base64_VARIANT_ORIGINAL) == 0); + assert(bin_len == 0); + + for (i = 0; i < 1000; i++) { + assert(sizeof buf1 >= 100); + bin_len = (size_t) randombytes_uniform(100); + bin = (unsigned char *) sodium_malloc(bin_len); + b64_len = (bin_len + 2U) / 3U * 4U + 1U; + assert(b64_len == sodium_base64_encoded_len(bin_len, sodium_base64_VARIANT_URLSAFE)); + b64_ = (char *) sodium_malloc(b64_len); + randombytes_buf(bin, bin_len); + memcpy(buf1, bin, bin_len); + b64 = sodium_bin2base64(b64_, b64_len, bin, bin_len, + sodium_base64_VARIANT_URLSAFE); + assert(b64 != NULL); + assert(sodium_base642bin(bin, bin_len + 10, b64, b64_len, + NULL, NULL, &b64_end, + sodium_base64_VARIANT_URLSAFE) == 0); + assert(b64_end == &b64[b64_len - 1]); + assert(memcmp(bin, buf1, bin_len) == 0); + sodium_free(bin); + sodium_free(b64_); + } + return 0; +} diff --git a/external/src/libsodium/test/default/codecs.exp b/external/src/libsodium/test/default/codecs.exp new file mode 100644 index 0000000..171834e --- /dev/null +++ b/external/src/libsodium/test/default/codecs.exp @@ -0,0 +1,30 @@ +30313233343536373839414243444546 +bin2hex(..., guard_page, 0): +bin2hex(..., "", 0): +4:cafe6942 +dt1: 11 +4:cafe6942 +dt2: 2 +dt3: 11 +dt4: 11 +dt5: 11 +dt6: 11 ++/DxMDEyMzQ1Njc4OUFCQ0RFRmFi ++/DxMDEyMzQ1Njc4OUFCQ0RFRmFiYw +-_DxMDEyMzQ1Njc4OUFCQ0RFRmFi +-_DxMDEyMzQ1Njc4OUFCQ0RFRmFiYw + +YQ== +YWI= +YWJj + +YQ +YWI +YWJj +[] +[BpcyBhIGpvdXJu +ZXkgaW50by Bzb3VuZA==] +[This is a journey into sound] +[This is a journ] +[ +ZXkgaW50by Bzb3VuZA==] diff --git a/external/src/libsodium/test/default/core1.c b/external/src/libsodium/test/default/core1.c new file mode 100644 index 0000000..f1d7b0b --- /dev/null +++ b/external/src/libsodium/test/default/core1.c @@ -0,0 +1,41 @@ + +#define TEST_NAME "core1" +#include "cmptest.h" + +static unsigned char shared[32] = { 0x4a, 0x5d, 0x9d, 0x5b, 0xa4, 0xce, 0x2d, + 0xe1, 0x72, 0x8e, 0x3b, 0xf4, 0x80, 0x35, + 0x0f, 0x25, 0xe0, 0x7e, 0x21, 0xc9, 0x47, + 0xd1, 0x9e, 0x33, 0x76, 0xf0, 0x9b, 0x3c, + 0x1e, 0x16, 0x17, 0x42 }; + +static unsigned char zero[32]; + +static unsigned char c[16] = { 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x20, 0x33, + 0x32, 0x2d, 0x62, 0x79, 0x74, 0x65, 0x20, 0x6b }; + +static unsigned char firstkey[32]; + +int +main(void) +{ + int i; + + crypto_core_hsalsa20(firstkey, zero, shared, c); + for (i = 0; i < 32; ++i) { + if (i > 0) { + printf(","); + } else { + printf(" "); + } + printf("0x%02x", (unsigned int) firstkey[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + assert(crypto_core_hsalsa20_outputbytes() > 0U); + assert(crypto_core_hsalsa20_inputbytes() > 0U); + assert(crypto_core_hsalsa20_keybytes() > 0U); + assert(crypto_core_hsalsa20_constbytes() > 0U); + + return 0; +} diff --git a/external/src/libsodium/test/default/core1.exp b/external/src/libsodium/test/default/core1.exp new file mode 100644 index 0000000..715a489 --- /dev/null +++ b/external/src/libsodium/test/default/core1.exp @@ -0,0 +1,4 @@ + 0x1b,0x27,0x55,0x64,0x73,0xe9,0x85,0xd4 +,0x62,0xcd,0x51,0x19,0x7a,0x9a,0x46,0xc7 +,0x60,0x09,0x54,0x9e,0xac,0x64,0x74,0xf2 +,0x06,0xc4,0xee,0x08,0x44,0xf6,0x83,0x89 diff --git a/external/src/libsodium/test/default/core2.c b/external/src/libsodium/test/default/core2.c new file mode 100644 index 0000000..7e2dd7e --- /dev/null +++ b/external/src/libsodium/test/default/core2.c @@ -0,0 +1,38 @@ + +#define TEST_NAME "core2" +#include "cmptest.h" + +static unsigned char firstkey[32] = { 0x1b, 0x27, 0x55, 0x64, 0x73, 0xe9, 0x85, + 0xd4, 0x62, 0xcd, 0x51, 0x19, 0x7a, 0x9a, + 0x46, 0xc7, 0x60, 0x09, 0x54, 0x9e, 0xac, + 0x64, 0x74, 0xf2, 0x06, 0xc4, 0xee, 0x08, + 0x44, 0xf6, 0x83, 0x89 }; + +static unsigned char nonceprefix[16] = { 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, + 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8, + 0x75, 0xfc, 0x73, 0xd6 }; + +static unsigned char c[16] = { 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x20, 0x33, + 0x32, 0x2d, 0x62, 0x79, 0x74, 0x65, 0x20, 0x6b }; + +static unsigned char secondkey[32]; + +int +main(void) +{ + int i; + + crypto_core_hsalsa20(secondkey, nonceprefix, firstkey, c); + for (i = 0; i < 32; ++i) { + if (i > 0) { + printf(","); + } else { + printf(" "); + } + printf("0x%02x", (unsigned int) secondkey[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + return 0; +} diff --git a/external/src/libsodium/test/default/core2.exp b/external/src/libsodium/test/default/core2.exp new file mode 100644 index 0000000..f4682af --- /dev/null +++ b/external/src/libsodium/test/default/core2.exp @@ -0,0 +1,4 @@ + 0xdc,0x90,0x8d,0xda,0x0b,0x93,0x44,0xa9 +,0x53,0x62,0x9b,0x73,0x38,0x20,0x77,0x88 +,0x80,0xf3,0xce,0xb4,0x21,0xbb,0x61,0xb9 +,0x1c,0xbd,0x4c,0x3e,0x66,0x25,0x6c,0xe4 diff --git a/external/src/libsodium/test/default/core3.c b/external/src/libsodium/test/default/core3.c new file mode 100644 index 0000000..09f2473 --- /dev/null +++ b/external/src/libsodium/test/default/core3.c @@ -0,0 +1,115 @@ + +#define TEST_NAME "core3" +#include "cmptest.h" + +static unsigned char SECONDKEY[32] = { 0xdc, 0x90, 0x8d, 0xda, 0x0b, 0x93, 0x44, + 0xa9, 0x53, 0x62, 0x9b, 0x73, 0x38, 0x20, + 0x77, 0x88, 0x80, 0xf3, 0xce, 0xb4, 0x21, + 0xbb, 0x61, 0xb9, 0x1c, 0xbd, 0x4c, 0x3e, + 0x66, 0x25, 0x6c, 0xe4 }; + +static unsigned char NONCESUFFIX[8] = { 0x82, 0x19, 0xe0, 0x03, + 0x6b, 0x7a, 0x0b, 0x37 }; + +static unsigned char C[16] = { 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x20, 0x33, + 0x32, 0x2d, 0x62, 0x79, 0x74, 0x65, 0x20, 0x6b }; + +int +main(void) +{ + unsigned char *secondkey; + unsigned char *c; + unsigned char *noncesuffix; + unsigned char *in; + unsigned char *output; + unsigned char *h; + size_t output_len = 64 * 256 * 256; + size_t pos = 0; + int i; + + pos = 0; + secondkey = (unsigned char *) sodium_malloc(32); + memcpy(secondkey, SECONDKEY, 32); + noncesuffix = (unsigned char *) sodium_malloc(8); + memcpy(noncesuffix, NONCESUFFIX, 8); + c = (unsigned char *) sodium_malloc(16); + memcpy(c, C, 16); + in = (unsigned char *) sodium_malloc(16); + output = (unsigned char *) sodium_malloc(output_len); + h = (unsigned char *) sodium_malloc(32); + + for (i = 0; i < 8; i++) { + in[i] = noncesuffix[i]; + } + for (; i < 16; i++) { + in[i] = 0; + } + do { + do { + crypto_core_salsa20(output + pos, in, secondkey, c); + pos += 64; + in[8]++; + } while (in[8] != 0); + in[9]++; + } while (in[9] != 0); + + crypto_hash_sha256(h, output, output_len); + + for (i = 0; i < 32; ++i) { + printf("%02x", h[i]); + } + printf("\n"); + +#ifndef SODIUM_LIBRARY_MINIMAL + pos = 0; + do { + do { + crypto_core_salsa2012(output + pos, in, secondkey, c); + pos += 64; + in[8]++; + } while (in[8] != 0); + in[9]++; + } while (in[9] != 0); + + crypto_hash_sha256(h, output, output_len); + + for (i = 0; i < 32; ++i) { + printf("%02x", h[i]); + } + printf("\n"); + + pos = 0; + do { + do { + crypto_core_salsa208(output + pos, in, secondkey, c); + pos += 64; + in[8]++; + } while (in[8] != 0); + in[9]++; + } while (in[9] != 0); + + crypto_hash_sha256(h, output, output_len); + + for (i = 0; i < 32; ++i) { + printf("%02x", h[i]); + } + printf("\n"); +#else + printf("a4e3147dddd2ba7775939b50208a22eb3277d4e4bad8a1cfbc999c6bd392b638\n" + "017421baa9959cbe894bd003ec87938254f47c1e757eb66cf89c353d0c2b68de\n"); +#endif + + sodium_free(h); + sodium_free(output); + sodium_free(in); + sodium_free(c); + sodium_free(noncesuffix); + sodium_free(secondkey); + + assert(crypto_core_salsa20_outputbytes() == crypto_core_salsa20_OUTPUTBYTES); + assert(crypto_core_salsa20_inputbytes() == crypto_core_salsa20_INPUTBYTES); + assert(crypto_core_salsa20_keybytes() == crypto_core_salsa20_KEYBYTES); + assert(crypto_core_salsa20_constbytes() == crypto_core_salsa20_CONSTBYTES); + + return 0; +} diff --git a/external/src/libsodium/test/default/core3.exp b/external/src/libsodium/test/default/core3.exp new file mode 100644 index 0000000..e6bc102 --- /dev/null +++ b/external/src/libsodium/test/default/core3.exp @@ -0,0 +1,3 @@ +662b9d0e3463029156069b12f918691a98f7dfb2ca0393c96bbfc6b1fbd630a2 +a4e3147dddd2ba7775939b50208a22eb3277d4e4bad8a1cfbc999c6bd392b638 +017421baa9959cbe894bd003ec87938254f47c1e757eb66cf89c353d0c2b68de diff --git a/external/src/libsodium/test/default/core4.c b/external/src/libsodium/test/default/core4.c new file mode 100644 index 0000000..cb174ab --- /dev/null +++ b/external/src/libsodium/test/default/core4.c @@ -0,0 +1,36 @@ + +#define TEST_NAME "core4" +#include "cmptest.h" + +static unsigned char k[32] = { 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216 }; + +static unsigned char in[16] = { 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116 }; + +static unsigned char c[16] = { 101, 120, 112, 97, 110, 100, 32, 51, + 50, 45, 98, 121, 116, 101, 32, 107 }; + +static unsigned char out[64]; + +int +main(void) +{ + int i; + + crypto_core_salsa20(out, in, k, c); + for (i = 0; i < 64; ++i) { + if (i > 0) { + printf(","); + } else { + printf(" "); + } + printf("%3u", (unsigned int) out[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + return 0; +} diff --git a/external/src/libsodium/test/default/core4.exp b/external/src/libsodium/test/default/core4.exp new file mode 100644 index 0000000..d04e5b5 --- /dev/null +++ b/external/src/libsodium/test/default/core4.exp @@ -0,0 +1,8 @@ + 69, 37, 68, 39, 41, 15,107,193 +,255,139,122, 6,170,233,217, 98 +, 89,144,182,106, 21, 51,200, 65 +,239, 49,222, 34,215,114, 40,126 +,104,197, 7,225,197,153, 31, 2 +,102, 78, 76,176, 84,245,246,184 +,177,160,133,130, 6, 72,149,119 +,192,195,132,236,234,103,246, 74 diff --git a/external/src/libsodium/test/default/core5.c b/external/src/libsodium/test/default/core5.c new file mode 100644 index 0000000..02b0fd9 --- /dev/null +++ b/external/src/libsodium/test/default/core5.c @@ -0,0 +1,33 @@ + +#define TEST_NAME "core5" +#include "cmptest.h" + +static unsigned char k[32] = { 0xee, 0x30, 0x4f, 0xca, 0x27, 0x00, 0x8d, 0x8c, + 0x12, 0x6f, 0x90, 0x02, 0x79, 0x01, 0xd8, 0x0f, + 0x7f, 0x1d, 0x8b, 0x8d, 0xc9, 0x36, 0xcf, 0x3b, + 0x9f, 0x81, 0x96, 0x92, 0x82, 0x7e, 0x57, 0x77 }; + +static unsigned char in[16] = { + 0x81, 0x91, 0x8e, 0xf2, 0xa5, 0xe0, 0xda, 0x9b, + 0x3e, 0x90, 0x60, 0x52, 0x1e, 0x4b, 0xb3, 0x52 +}; + +static unsigned char c[16] = { 101, 120, 112, 97, 110, 100, 32, 51, + 50, 45, 98, 121, 116, 101, 32, 107 }; + +unsigned char out[32]; + +int +main(void) +{ + int i; + + crypto_core_hsalsa20(out, in, k, c); + for (i = 0; i < 32; ++i) { + printf(",0x%02x", (unsigned int) out[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + return 0; +} diff --git a/external/src/libsodium/test/default/core5.exp b/external/src/libsodium/test/default/core5.exp new file mode 100644 index 0000000..562cf71 --- /dev/null +++ b/external/src/libsodium/test/default/core5.exp @@ -0,0 +1,4 @@ +,0xbc,0x1b,0x30,0xfc,0x07,0x2c,0xc1,0x40 +,0x75,0xe4,0xba,0xa7,0x31,0xb5,0xa8,0x45 +,0xea,0x9b,0x11,0xe9,0xa5,0x19,0x1f,0x94 +,0xe1,0x8c,0xba,0x8f,0xd8,0x21,0xa7,0xcd diff --git a/external/src/libsodium/test/default/core6.c b/external/src/libsodium/test/default/core6.c new file mode 100644 index 0000000..f10c0d6 --- /dev/null +++ b/external/src/libsodium/test/default/core6.c @@ -0,0 +1,52 @@ + +#define TEST_NAME "core6" +#include "cmptest.h" + +static unsigned char k[32] = { 0xee, 0x30, 0x4f, 0xca, 0x27, 0x00, 0x8d, 0x8c, + 0x12, 0x6f, 0x90, 0x02, 0x79, 0x01, 0xd8, 0x0f, + 0x7f, 0x1d, 0x8b, 0x8d, 0xc9, 0x36, 0xcf, 0x3b, + 0x9f, 0x81, 0x96, 0x92, 0x82, 0x7e, 0x57, 0x77 }; + +static unsigned char in[16] = { + 0x81, 0x91, 0x8e, 0xf2, 0xa5, 0xe0, 0xda, 0x9b, + 0x3e, 0x90, 0x60, 0x52, 0x1e, 0x4b, 0xb3, 0x52 +}; + +static unsigned char c[16] = { 101, 120, 112, 97, 110, 100, 32, 51, + 50, 45, 98, 121, 116, 101, 32, 107 }; + +static unsigned char out[64]; + +static void +print(unsigned char *x, unsigned char *y) +{ + int i; + unsigned int borrow = 0; + + for (i = 0; i < 4; ++i) { + unsigned int xi = x[i]; + unsigned int yi = y[i]; + printf(",0x%02x", 255 & (xi - yi - borrow)); + borrow = (xi < yi + borrow); + } +} + +int +main(void) +{ + crypto_core_salsa20(out, in, k, c); + print(out, c); + print(out + 20, c + 4); + printf("\n"); + print(out + 40, c + 8); + print(out + 60, c + 12); + printf("\n"); + print(out + 24, in); + print(out + 28, in + 4); + printf("\n"); + print(out + 32, in + 8); + print(out + 36, in + 12); + printf("\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/core6.exp b/external/src/libsodium/test/default/core6.exp new file mode 100644 index 0000000..562cf71 --- /dev/null +++ b/external/src/libsodium/test/default/core6.exp @@ -0,0 +1,4 @@ +,0xbc,0x1b,0x30,0xfc,0x07,0x2c,0xc1,0x40 +,0x75,0xe4,0xba,0xa7,0x31,0xb5,0xa8,0x45 +,0xea,0x9b,0x11,0xe9,0xa5,0x19,0x1f,0x94 +,0xe1,0x8c,0xba,0x8f,0xd8,0x21,0xa7,0xcd diff --git a/external/src/libsodium/test/default/core_ed25519.c b/external/src/libsodium/test/default/core_ed25519.c new file mode 100644 index 0000000..5340f9e --- /dev/null +++ b/external/src/libsodium/test/default/core_ed25519.c @@ -0,0 +1,529 @@ +#define TEST_NAME "core_ed25519" +#include "cmptest.h" + +static const unsigned char non_canonical_p[32] = { + 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f +}; +static const unsigned char non_canonical_invalid_p[32] = { + 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f +}; +static const unsigned char max_canonical_p[32] = { + 0xe4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f +}; +static const unsigned char L_p1[32] = { + 0xee, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 +}; +static const unsigned char L[32] = { + 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 +}; +static const unsigned char L_1[32] = { + 0xec, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 +}; +static const unsigned char sc_8[32] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +static const unsigned char sc_highbit[32] = { + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 +}; + +static void +add_P(unsigned char * const S) +{ + static const unsigned char P[32] = { + 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f + }; + + sodium_add(S, P, sizeof P); +} + +static void +add_l64(unsigned char * const S) +{ + static const unsigned char l[crypto_core_ed25519_NONREDUCEDSCALARBYTES] = + { 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, + 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + sodium_add(S, l, sizeof l); +} + +int +main(void) +{ + unsigned char *r; + unsigned char *p, *p2, *p3; + unsigned char *sc, *sc2, *sc3; + unsigned char *sc64; + char *hex; + unsigned int i, j; + + r = (unsigned char *) sodium_malloc(crypto_core_ed25519_UNIFORMBYTES); + p = (unsigned char *) sodium_malloc(crypto_core_ed25519_BYTES); + for (i = 0; i < 500; i++) { + randombytes_buf(r, crypto_core_ed25519_UNIFORMBYTES); + if (crypto_core_ed25519_from_uniform(p, r) != 0) { + printf("crypto_core_ed25519_from_uniform() failed\n"); + } + if (crypto_core_ed25519_is_valid_point(p) == 0) { + printf("crypto_core_ed25519_from_uniform() returned an invalid point\n"); + } + + crypto_core_ed25519_random(p); + if (crypto_core_ed25519_is_valid_point(p) == 0) { + printf("crypto_core_ed25519_random() returned an invalid point\n"); + } + } + + p2 = (unsigned char *) sodium_malloc(crypto_core_ed25519_BYTES); + p3 = (unsigned char *) sodium_malloc(crypto_core_ed25519_BYTES); + + crypto_core_ed25519_random(p2); + + j = 1 + (unsigned int) randombytes_uniform(100); + memcpy(p3, p, crypto_core_ed25519_BYTES); + for (i = 0; i < j; i++) { + crypto_core_ed25519_add(p, p, p2); + if (crypto_core_ed25519_is_valid_point(p) != 1) { + printf("crypto_core_add() returned an invalid point\n"); + } + } + if (memcmp(p, p3, crypto_core_ed25519_BYTES) == 0) { + printf("crypto_core_add() failed\n"); + } + for (i = 0; i < j; i++) { + crypto_core_ed25519_sub(p, p, p2); + } + if (memcmp(p, p3, crypto_core_ed25519_BYTES) != 0) { + printf("crypto_core_add() or crypto_core_sub() failed\n"); + } + sc = (unsigned char *) sodium_malloc(crypto_scalarmult_ed25519_SCALARBYTES); + memset(sc, 0, crypto_scalarmult_ed25519_SCALARBYTES); + sc[0] = 8; + memcpy(p2, p, crypto_core_ed25519_BYTES); + memcpy(p3, p, crypto_core_ed25519_BYTES); + + for (i = 0; i < 254; i++) { + crypto_core_ed25519_add(p2, p2, p2); + } + for (i = 0; i < 8; i++) { + crypto_core_ed25519_add(p2, p2, p); + } + if (crypto_scalarmult_ed25519(p3, sc, p) != 0) { + printf("crypto_scalarmult_ed25519() failed\n"); + } + if (memcmp(p2, p3, crypto_core_ed25519_BYTES) != 0) { + printf("crypto_scalarmult_ed25519() is inconsistent with crypto_core_ed25519_add()\n"); + } + + assert(crypto_core_ed25519_is_valid_point(p) == 1); + + memset(p, 0, crypto_core_ed25519_BYTES); + assert(crypto_core_ed25519_is_valid_point(p) == 0); + + p[0] = 1; + assert(crypto_core_ed25519_is_valid_point(p) == 0); + + p[0] = 2; + assert(crypto_core_ed25519_is_valid_point(p) == 0); + + p[0] = 9; + assert(crypto_core_ed25519_is_valid_point(p) == 1); + + assert(crypto_core_ed25519_is_valid_point(max_canonical_p) == 1); + assert(crypto_core_ed25519_is_valid_point(non_canonical_invalid_p) == 0); + assert(crypto_core_ed25519_is_valid_point(non_canonical_p) == 0); + + memcpy(p2, p, crypto_core_ed25519_BYTES); + add_P(p2); + crypto_core_ed25519_add(p3, p2, p2); + crypto_core_ed25519_sub(p3, p3, p2); + assert(memcmp(p2, p, crypto_core_ed25519_BYTES) != 0); + assert(memcmp(p3, p, crypto_core_ed25519_BYTES) == 0); + + p[0] = 2; + assert(crypto_core_ed25519_add(p3, p2, p) == -1); + assert(crypto_core_ed25519_add(p3, p2, non_canonical_p) == 0); + assert(crypto_core_ed25519_add(p3, p2, non_canonical_invalid_p) == -1); + assert(crypto_core_ed25519_add(p3, p, p3) == -1); + assert(crypto_core_ed25519_add(p3, non_canonical_p, p3) == 0); + assert(crypto_core_ed25519_add(p3, non_canonical_invalid_p, p3) == -1); + + assert(crypto_core_ed25519_sub(p3, p2, p) == -1); + assert(crypto_core_ed25519_sub(p3, p2, non_canonical_p) == 0); + assert(crypto_core_ed25519_sub(p3, p2, non_canonical_invalid_p) == -1); + assert(crypto_core_ed25519_sub(p3, p, p3) == -1); + assert(crypto_core_ed25519_sub(p3, non_canonical_p, p3) == 0); + assert(crypto_core_ed25519_sub(p3, non_canonical_invalid_p, p3) == -1); + + for (i = 0; i < 1000; i++) { + crypto_core_ed25519_random(p); + do { + crypto_core_ed25519_scalar_random(sc); + } while (sodium_is_zero(sc, crypto_core_ed25519_SCALARBYTES)); + if (crypto_scalarmult_ed25519_noclamp(p2, sc, p) != 0) { + printf("crypto_scalarmult_ed25519_noclamp() failed\n"); + } + assert(crypto_core_ed25519_is_valid_point(p2)); + if (crypto_core_ed25519_scalar_invert(sc, sc) != 0) { + printf("crypto_core_ed25519_scalar_invert() failed\n"); + } + if (crypto_scalarmult_ed25519_noclamp(p3, sc, p2) != 0) { + printf("crypto_scalarmult_ed25519_noclamp() failed\n"); + } + assert(memcmp(p3, p, crypto_core_ed25519_BYTES) == 0); + } + + sc64 = (unsigned char *) sodium_malloc(64); + crypto_core_ed25519_scalar_random(sc); + memcpy(sc64, sc, crypto_core_ed25519_BYTES); + memset(sc64 + crypto_core_ed25519_BYTES, 0, + 64 - crypto_core_ed25519_BYTES); + i = (unsigned int) randombytes_uniform(100); + do { + add_l64(sc64); + } while (i-- > 0); + crypto_core_ed25519_scalar_reduce(sc64, sc64); + if (memcmp(sc64, sc, crypto_core_ed25519_BYTES) != 0) { + printf("crypto_core_ed25519_scalar_reduce() failed\n"); + } + + randombytes_buf(r, crypto_core_ed25519_UNIFORMBYTES); + crypto_core_ed25519_from_uniform(p, r); + memcpy(p2, p, crypto_core_ed25519_BYTES); + crypto_core_ed25519_scalar_random(sc); + if (crypto_scalarmult_ed25519_noclamp(p, sc, p) != 0) { + printf("crypto_scalarmult_ed25519_noclamp() failed (1)\n"); + } + crypto_core_ed25519_scalar_complement(sc, sc); + if (crypto_scalarmult_ed25519_noclamp(p2, sc, p2) != 0) { + printf("crypto_scalarmult_ed25519_noclamp() failed (2)\n"); + } + crypto_core_ed25519_add(p3, p, p2); + crypto_core_ed25519_from_uniform(p, r); + crypto_core_ed25519_sub(p, p, p3); + assert(p[0] == 0x01); + for (i = 1; i < crypto_core_ed25519_BYTES; i++) { + assert(p[i] == 0); + } + + crypto_core_ed25519_random(p); + memcpy(p2, p, crypto_core_ed25519_BYTES); + crypto_core_ed25519_scalar_random(sc); + if (crypto_scalarmult_ed25519_noclamp(p, sc, p) != 0) { + printf("crypto_scalarmult_ed25519_noclamp() failed (3)\n"); + } + crypto_core_ed25519_scalar_negate(sc, sc); + if (crypto_scalarmult_ed25519_noclamp(p2, sc, p2) != 0) { + printf("crypto_scalarmult_ed25519_noclamp() failed (4)\n"); + } + crypto_core_ed25519_add(p, p, p2); + assert(p[0] == 0x01); + for (i = 1; i < crypto_core_ed25519_BYTES; i++) { + assert(p[i] == 0); + } + + hex = (char *) sodium_malloc(crypto_core_ed25519_SCALARBYTES * 2 + 1); + + for (i = 0; i < crypto_core_ed25519_SCALARBYTES; i++) { + sc[i] = 255 - i; + } + if (crypto_core_ed25519_scalar_invert(sc, sc) != 0) { + printf("crypto_core_ed25519_scalar_invert() failed\n"); + } + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("inv1: %s\n", hex); + if (crypto_core_ed25519_scalar_invert(sc, sc) != 0) { + printf("crypto_core_ed25519_scalar_invert() failed\n"); + } + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("inv2: %s\n", hex); + for (i = 0; i < crypto_core_ed25519_SCALARBYTES; i++) { + sc[i] = 32 - i; + } + if (crypto_core_ed25519_scalar_invert(sc, sc) != 0) { + printf("crypto_core_ed25519_scalar_invert() failed\n"); + } + + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("inv3: %s\n", hex); + if (crypto_core_ed25519_scalar_invert(sc, sc) != 0) { + printf("crypto_core_ed25519_scalar_invert() failed\n"); + } + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("inv4: %s\n", hex); + + for (i = 0; i < crypto_core_ed25519_SCALARBYTES; i++) { + sc[i] = 255 - i; + } + crypto_core_ed25519_scalar_negate(sc, sc); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("neg1: %s\n", hex); + crypto_core_ed25519_scalar_negate(sc, sc); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("neg2: %s\n", hex); + for (i = 0; i < crypto_core_ed25519_SCALARBYTES; i++) { + sc[i] = 32 - i; + } + crypto_core_ed25519_scalar_negate(sc, sc); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("neg3: %s\n", hex); + crypto_core_ed25519_scalar_negate(sc, sc); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("neg4: %s\n", hex); + + for (i = 0; i < crypto_core_ed25519_SCALARBYTES; i++) { + sc[i] = 255 - i; + } + crypto_core_ed25519_scalar_complement(sc, sc); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("comp1: %s\n", hex); + crypto_core_ed25519_scalar_complement(sc, sc); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("comp2: %s\n", hex); + for (i = 0; i < crypto_core_ed25519_SCALARBYTES; i++) { + sc[i] = 32 - i; + } + crypto_core_ed25519_scalar_complement(sc, sc); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("comp3: %s\n", hex); + crypto_core_ed25519_scalar_complement(sc, sc); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("comp4: %s\n", hex); + + sc2 = (unsigned char *) sodium_malloc(crypto_core_ed25519_SCALARBYTES); + sc3 = (unsigned char *) sodium_malloc(crypto_core_ed25519_SCALARBYTES); + for (i = 0; i < 1000; i++) { + randombytes_buf(sc, crypto_core_ed25519_SCALARBYTES); + randombytes_buf(sc2, crypto_core_ed25519_SCALARBYTES); + sc[crypto_core_ed25519_SCALARBYTES - 1] &= 0x7f; + sc2[crypto_core_ed25519_SCALARBYTES - 1] &= 0x7f; + crypto_core_ed25519_scalar_add(sc3, sc, sc2); + assert(!sodium_is_zero(sc, crypto_core_ed25519_SCALARBYTES)); + crypto_core_ed25519_scalar_sub(sc3, sc3, sc2); + assert(!sodium_is_zero(sc, crypto_core_ed25519_SCALARBYTES)); + crypto_core_ed25519_scalar_sub(sc3, sc3, sc); + assert(sodium_is_zero(sc3, crypto_core_ed25519_SCALARBYTES)); + } + + memset(sc, 0x69, crypto_core_ed25519_SCALARBYTES); + memset(sc2, 0x42, crypto_core_ed25519_SCALARBYTES); + crypto_core_ed25519_scalar_add(sc, sc, sc2); + crypto_core_ed25519_scalar_add(sc, sc2, sc); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("add1: %s\n", hex); + + crypto_core_ed25519_scalar_sub(sc, sc2, sc); + crypto_core_ed25519_scalar_sub(sc, sc, sc2); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("sub1: %s\n", hex); + + memset(sc, 0xcd, crypto_core_ed25519_SCALARBYTES); + memset(sc2, 0x42, crypto_core_ed25519_SCALARBYTES); + crypto_core_ed25519_scalar_add(sc, sc, sc2); + crypto_core_ed25519_scalar_add(sc, sc2, sc); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("add2: %s\n", hex); + + crypto_core_ed25519_scalar_sub(sc, sc2, sc); + crypto_core_ed25519_scalar_sub(sc, sc, sc2); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("sub2: %s\n", hex); + + memset(sc, 0x69, crypto_core_ed25519_SCALARBYTES); + memset(sc2, 0x42, crypto_core_ed25519_SCALARBYTES); + for (i = 0; i < 100; i++) { + crypto_core_ed25519_scalar_mul(sc, sc, sc2); + crypto_core_ed25519_scalar_mul(sc2, sc, sc2); + } + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc2, crypto_core_ed25519_SCALARBYTES); + printf("mul: %s\n", hex); + for (i = 0; i < 1000; i++) { + crypto_core_ed25519_scalar_random(sc); + memset(sc2, 0, crypto_core_ed25519_SCALARBYTES); + crypto_core_ed25519_scalar_mul(sc3, sc, sc2); + assert(sodium_is_zero(sc3, crypto_core_ed25519_SCALARBYTES)); + + sc2[0]++; + crypto_core_ed25519_scalar_mul(sc3, sc, sc2); + assert(memcmp(sc3, sc, crypto_core_ed25519_SCALARBYTES) == 0); + + sc2[0]++; + crypto_core_ed25519_scalar_mul(sc3, sc, sc2); + crypto_core_ed25519_scalar_sub(sc3, sc3, sc); + crypto_core_ed25519_scalar_sub(sc3, sc3, sc); + assert(sodium_is_zero(sc3, crypto_core_ed25519_SCALARBYTES)); + + do { + crypto_core_ed25519_scalar_random(sc2); + } while (sodium_is_zero(sc2, crypto_core_ed25519_SCALARBYTES)); + crypto_core_ed25519_scalar_mul(sc3, sc, sc2); + crypto_core_ed25519_scalar_invert(sc2, sc2); + crypto_core_ed25519_scalar_mul(sc3, sc3, sc2); + assert(memcmp(sc3, sc, crypto_core_ed25519_SCALARBYTES) == 0); + + sc[31] |= 0x11; + memset(sc2, 0, crypto_core_ed25519_SCALARBYTES); + sc2[0] = 1; + crypto_core_ed25519_scalar_mul(sc3, sc, sc2); + assert(memcmp(sc3, sc, crypto_core_ed25519_SCALARBYTES) != 0); + } + + crypto_core_ed25519_scalar_mul(sc, L_1, sc_8); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("(L-1)*8: %s\n", hex); + crypto_core_ed25519_scalar_mul(sc, sc_8, L_1); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("8(L-1): %s\n", hex); + crypto_core_ed25519_scalar_mul(sc, L_1, L_1); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("(L-1)^2: %s\n", hex); + crypto_core_ed25519_scalar_mul(sc, L, sc_8); + + crypto_core_ed25519_scalar_mul(sc, L_p1, sc_8); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("(L+1)*8: %s\n", hex); + crypto_core_ed25519_scalar_mul(sc, sc_8, L_p1); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("8(L+1): %s\n", hex); + crypto_core_ed25519_scalar_mul(sc, L_p1, L_p1); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("(L+1)^2: %s\n", hex); + + crypto_core_ed25519_scalar_mul(sc, L_1, sc_highbit); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("(L-1)h: %s\n", hex); + crypto_core_ed25519_scalar_mul(sc, sc_highbit, L_1); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("h(L-1): %s\n", hex); + crypto_core_ed25519_scalar_mul(sc, L_p1, sc_highbit); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("(L+1)h: %s\n", hex); + crypto_core_ed25519_scalar_mul(sc, sc_highbit, L_p1); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("h(L+1): %s\n", hex); + crypto_core_ed25519_scalar_mul(sc, sc_highbit, sc_highbit); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("h^2: %s\n", hex); + + crypto_core_ed25519_scalar_mul(sc, L, sc_8); + assert(sodium_is_zero(sc, crypto_core_ed25519_SCALARBYTES)); + crypto_core_ed25519_scalar_mul(sc, sc_8, L); + assert(sodium_is_zero(sc, crypto_core_ed25519_SCALARBYTES)); + crypto_core_ed25519_scalar_mul(sc, L, L); + assert(sodium_is_zero(sc, crypto_core_ed25519_SCALARBYTES)); + crypto_core_ed25519_scalar_mul(sc, L, L_1); + assert(sodium_is_zero(sc, crypto_core_ed25519_SCALARBYTES)); + crypto_core_ed25519_scalar_mul(sc, L_1, L); + assert(sodium_is_zero(sc, crypto_core_ed25519_SCALARBYTES)); + + crypto_core_ed25519_scalar_add(sc, L_1, sc_8); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("(L-1)+8: %s\n", hex); + crypto_core_ed25519_scalar_add(sc, sc_8, L_1); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("8+(L-1): %s\n", hex); + crypto_core_ed25519_scalar_add(sc, L_1, L_1); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("(L-1)*2: %s\n", hex); + crypto_core_ed25519_scalar_add(sc, L, sc_8); + + crypto_core_ed25519_scalar_add(sc, L_p1, sc_8); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("(L+1)+8: %s\n", hex); + crypto_core_ed25519_scalar_add(sc, sc_8, L_p1); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("8+(L+1): %s\n", hex); + crypto_core_ed25519_scalar_add(sc, L_p1, L_p1); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("(L+1)*2: %s\n", hex); + + crypto_core_ed25519_scalar_add(sc, L_1, sc_highbit); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("(L-1)+h: %s\n", hex); + crypto_core_ed25519_scalar_add(sc, sc_highbit, L_1); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("h+(L-1): %s\n", hex); + crypto_core_ed25519_scalar_add(sc, L_p1, sc_highbit); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("(L+1)+h: %s\n", hex); + crypto_core_ed25519_scalar_add(sc, sc_highbit, L_p1); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("h+(L+1): %s\n", hex); + crypto_core_ed25519_scalar_add(sc, sc_highbit, sc_highbit); + sodium_bin2hex(hex, crypto_core_ed25519_SCALARBYTES * 2 + 1, + sc, crypto_core_ed25519_SCALARBYTES); + printf("h*2: %s\n", hex); + + sodium_free(hex); + sodium_free(sc64); + sodium_free(sc3); + sodium_free(sc2); + sodium_free(sc); + sodium_free(p3); + sodium_free(p2); + sodium_free(p); + sodium_free(r); + + assert(crypto_core_ed25519_BYTES == crypto_core_ed25519_bytes()); + assert(crypto_core_ed25519_SCALARBYTES == crypto_core_ed25519_scalarbytes()); + assert(crypto_core_ed25519_NONREDUCEDSCALARBYTES == crypto_core_ed25519_nonreducedscalarbytes()); + assert(crypto_core_ed25519_NONREDUCEDSCALARBYTES >= crypto_core_ed25519_SCALARBYTES); + assert(crypto_core_ed25519_UNIFORMBYTES == crypto_core_ed25519_uniformbytes()); + assert(crypto_core_ed25519_UNIFORMBYTES >= crypto_core_ed25519_BYTES); + + printf("OK\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/core_ed25519.exp b/external/src/libsodium/test/default/core_ed25519.exp new file mode 100644 index 0000000..0fea102 --- /dev/null +++ b/external/src/libsodium/test/default/core_ed25519.exp @@ -0,0 +1,40 @@ +inv1: 5858cdec40a044b1548b3bb08f8ce0d71103d1f887df84ebc502643dac4df40b +inv2: 09688ce78a8ff8273f636b0bc748c0cceeeeedecebeae9e8e7e6e5e4e3e2e100 +inv3: f70b4f272b47bd6a1015a511fb3c9fc1b9c21ca4ca2e17d5a225b4c410b9b60d +inv4: 201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a090807060504030201 +neg1: e46b69758fd3193097398c9717b11e48111112131415161718191a1b1c1d1e0f +neg2: 09688ce78a8ff8273f636b0bc748c0cceeeeedecebeae9e8e7e6e5e4e3e2e100 +neg3: cdb4d73ffe47f83ebe85e18dcae6cc03f0f0f1f2f3f4f5f6f7f8f9fafbfcfd0e +neg4: 201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a090807060504030201 +comp1: e56b69758fd3193097398c9717b11e48111112131415161718191a1b1c1d1e0f +comp2: 09688ce78a8ff8273f636b0bc748c0cceeeeedecebeae9e8e7e6e5e4e3e2e100 +comp3: ceb4d73ffe47f83ebe85e18dcae6cc03f0f0f1f2f3f4f5f6f7f8f9fafbfcfd0e +comp4: 201f1e1d1c1b1a191817161514131211100f0e0d0c0b0a090807060504030201 +add1: f7567cd87c82ec1c355a6304c143bcc9ecedededededededededededededed0d +sub1: f67c79849de0253ba142949e1db6224b13121212121212121212121212121202 +add2: b02e8581ce62f69922427c23f970f7e951525252525252525252525252525202 +sub2: 3da570db4b001cbeb35a7b7fe588e72aaeadadadadadadadadadadadadadad0d +mul: 4453ef38408c06677c1b810e4bf8b1991f01c88716fbfa2f075a518b77da400b +(L-1)*8: e5d3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010 +8(L-1): e5d3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010 +(L-1)^2: 0100000000000000000000000000000000000000000000000000000000000000 +(L+1)*8: 0800000000000000000000000000000000000000000000000000000000000000 +8(L+1): 0800000000000000000000000000000000000000000000000000000000000000 +(L+1)^2: 0100000000000000000000000000000000000000000000000000000000000000 +(L-1)h: 609faee7d21893c0b2e6bc17f5cef7a600000000000000000000000000000000 +h(L-1): 609faee7d21893c0b2e6bc17f5cef7a600000000000000000000000000000000 +(L+1)h: 8d344775474a7f9723b63a8be92ae76dffffffffffffffffffffffffffffff0f +h(L+1): 8d344775474a7f9723b63a8be92ae76dffffffffffffffffffffffffffffff0f +h^2: 726cf51b9ec1dda146af8c58ffd22d148f6ffd85f41cbb738f260cdf4650e60c +(L-1)+8: 0700000000000000000000000000000000000000000000000000000000000000 +8+(L-1): 0700000000000000000000000000000000000000000000000000000000000000 +(L-1)*2: ebd3f55c1a631258d69cf7a2def9de1400000000000000000000000000000010 +(L+1)+8: 0900000000000000000000000000000000000000000000000000000000000000 +8+(L+1): 0900000000000000000000000000000000000000000000000000000000000000 +(L+1)*2: 0200000000000000000000000000000000000000000000000000000000000000 +(L-1)+h: 8c344775474a7f9723b63a8be92ae76dffffffffffffffffffffffffffffff0f +h+(L-1): 8c344775474a7f9723b63a8be92ae76dffffffffffffffffffffffffffffff0f +(L+1)+h: 8e344775474a7f9723b63a8be92ae76dffffffffffffffffffffffffffffff0f +h+(L+1): 8e344775474a7f9723b63a8be92ae76dffffffffffffffffffffffffffffff0f +h*2: 1000000000000000000000000000000000000000000000000000000000000000 +OK diff --git a/external/src/libsodium/test/default/core_ristretto255.c b/external/src/libsodium/test/default/core_ristretto255.c new file mode 100644 index 0000000..0d247c4 --- /dev/null +++ b/external/src/libsodium/test/default/core_ristretto255.c @@ -0,0 +1,271 @@ +#define TEST_NAME "core_ristretto255" +#include "cmptest.h" + +static void +tv1(void) +{ + static const char *bad_encodings_hex[] = { + /* Non-canonical field encodings */ + "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "0100000000000000000000000000000000000000000000000000000000000080", + + /* Negative field elements */ + "0100000000000000000000000000000000000000000000000000000000000000", + "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "ed57ffd8c914fb201471d1c3d245ce3c746fcbe63a3679d51b6a516ebebe0e20", + "c34c4e1826e5d403b78e246e88aa051c36ccf0aafebffe137d148a2bf9104562", + "c940e5a4404157cfb1628b108db051a8d439e1a421394ec4ebccb9ec92a8ac78", + "47cfc5497c53dc8e61c91d17fd626ffb1c49e2bca94eed052281b510b1117a24", + "f1c6165d33367351b0da8f6e4511010c68174a03b6581212c71c0e1d026c3c72", + "87260f7a2f12495118360f02c26a470f450dadf34a413d21042b43b9d93e1309", + + /* Non-square x^2 */ + "26948d35ca62e643e26a83177332e6b6afeb9d08e4268b650f1f5bbd8d81d371", + "4eac077a713c57b4f4397629a4145982c661f48044dd3f96427d40b147d9742f", + "de6a7b00deadc788eb6b6c8d20c0ae96c2f2019078fa604fee5b87d6e989ad7b", + "bcab477be20861e01e4a0e295284146a510150d9817763caf1a6f4b422d67042", + "2a292df7e32cababbd9de088d1d1abec9fc0440f637ed2fba145094dc14bea08", + "f4a9e534fc0d216c44b218fa0c42d99635a0127ee2e53c712f70609649fdff22", + "8268436f8c4126196cf64b3c7ddbda90746a378625f9813dd9b8457077256731", + "2810e5cbc2cc4d4eece54f61c6f69758e289aa7ab440b3cbeaa21995c2f4232b", + + /* Negative xy value */ + "3eb858e78f5a7254d8c9731174a94f76755fd3941c0ac93735c07ba14579630e", + "a45fdc55c76448c049a1ab33f17023edfb2be3581e9c7aade8a6125215e04220", + "d483fe813c6ba647ebbfd3ec41adca1c6130c2beeee9d9bf065c8d151c5f396e", + "8a2e1d30050198c65a54483123960ccc38aef6848e1ec8f5f780e8523769ba32", + "32888462f8b486c68ad7dd9610be5192bbeaf3b443951ac1a8118419d9fa097b", + "227142501b9d4355ccba290404bde41575b037693cef1f438c47f8fbf35d1165", + "5c37cc491da847cfeb9281d407efc41e15144c876e0170b499a96a22ed31e01e", + "445425117cb8c90edcbc7c1cc0e74f747f2c1efa5630a967c64f287792a48a4b", + + /* s = -1, which causes y = 0 */ + "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f" + }; + unsigned char *s; + size_t i; + + s = (unsigned char *) sodium_malloc(crypto_core_ristretto255_BYTES); + for (i = 0; i < sizeof bad_encodings_hex / sizeof bad_encodings_hex[0]; i++) { + sodium_hex2bin(s, crypto_core_ristretto255_BYTES, bad_encodings_hex[i], + crypto_core_ristretto255_BYTES * 2 + 1, + NULL, NULL, NULL); + if (crypto_core_ristretto255_is_valid_point(s)) { + printf("[%s] was not rejected\n", bad_encodings_hex[i]); + } + } + sodium_free(s); +}; + +static void +tv2(void) +{ + static const char *hash_hex[] = { + "5d1be09e3d0c82fc538112490e35701979d99e06ca3e2b5b54bffe8b4dc772c1" + "4d98b696a1bbfb5ca32c436cc61c16563790306c79eaca7705668b47dffe5bb6", + + "f116b34b8f17ceb56e8732a60d913dd10cce47a6d53bee9204be8b44f6678b27" + "0102a56902e2488c46120e9276cfe54638286b9e4b3cdb470b542d46c2068d38", + + "8422e1bbdaab52938b81fd602effb6f89110e1e57208ad12d9ad767e2e25510c" + "27140775f9337088b982d83d7fcf0b2fa1edffe51952cbe7365e95c86eaf325c", + + "ac22415129b61427bf464e17baee8db65940c233b98afce8d17c57beeb7876c2" + "150d15af1cb1fb824bbd14955f2b57d08d388aab431a391cfc33d5bafb5dbbaf", + + "165d697a1ef3d5cf3c38565beefcf88c0f282b8e7dbd28544c483432f1cec767" + "5debea8ebb4e5fe7d6f6e5db15f15587ac4d4d4a1de7191e0c1ca6664abcc413", + + "a836e6c9a9ca9f1e8d486273ad56a78c70cf18f0ce10abb1c7172ddd605d7fd2" + "979854f47ae1ccf204a33102095b4200e5befc0465accc263175485f0e17ea5c", + + "2cdc11eaeb95daf01189417cdddbf95952993aa9cb9c640eb5058d09702c7462" + "2c9965a697a3b345ec24ee56335b556e677b30e6f90ac77d781064f866a3c982" + }; + unsigned char *s; + unsigned char *u; + char *hex; + size_t i; + + s = (unsigned char *) sodium_malloc(crypto_core_ristretto255_BYTES); + u = (unsigned char *) sodium_malloc(crypto_core_ristretto255_HASHBYTES); + hex = (char *) sodium_malloc(crypto_core_ristretto255_BYTES * 2 + 1); + for (i = 0; i < sizeof hash_hex / sizeof hash_hex[0]; i++) { + sodium_hex2bin(u, crypto_core_ristretto255_HASHBYTES, hash_hex[i], + crypto_core_ristretto255_HASHBYTES * 2 + 1, + NULL, NULL, NULL); + crypto_core_ristretto255_from_hash(s, u); + sodium_bin2hex(hex, crypto_core_ristretto255_BYTES * 2 + 1, + s, crypto_core_ristretto255_BYTES); + printf("%s\n", hex); + } + sodium_free(hex); + sodium_free(u); + sodium_free(s); +} + +static void +tv3(void) +{ + static const unsigned char l[crypto_core_ed25519_BYTES] = + { 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, + 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 }; + + unsigned char *r = + (unsigned char *) sodium_malloc(crypto_core_ristretto255_SCALARBYTES); + unsigned char *r_inv = + (unsigned char *) sodium_malloc(crypto_core_ristretto255_SCALARBYTES); + unsigned char *ru = + (unsigned char *) sodium_malloc(crypto_core_ristretto255_HASHBYTES); + unsigned char *s = + (unsigned char *) sodium_malloc(crypto_core_ristretto255_BYTES); + unsigned char *s_ = + (unsigned char *) sodium_malloc(crypto_core_ristretto255_BYTES); + unsigned char *s2 = + (unsigned char *) sodium_malloc(crypto_core_ristretto255_BYTES); + int i; + + for (i = 0; i < 1000; i++) { + crypto_core_ristretto255_scalar_random(r); + if (crypto_scalarmult_ristretto255_base(s, r) != 0 || + crypto_core_ristretto255_is_valid_point(s) != 1) { + printf("crypto_scalarmult_ristretto255_base() failed\n"); + } + crypto_core_ristretto255_random(s); + if (crypto_core_ristretto255_is_valid_point(s) != 1) { + printf("crypto_core_ristretto255_random() failed\n"); + } + if (crypto_scalarmult_ristretto255(s, l, s) == 0) { + printf("s*l != inf (1)\n"); + } + randombytes_buf(ru, crypto_core_ristretto255_HASHBYTES); + if (crypto_core_ristretto255_from_hash(s, ru) != 0 || + crypto_core_ristretto255_is_valid_point(s) != 1) { + printf("crypto_core_ristretto255_from_hash() failed\n"); + } + if (crypto_scalarmult_ristretto255(s2, l, s) == 0) { + printf("s*l != inf (2)\n"); + } + if (crypto_scalarmult_ristretto255(s2, r, s) != 0 || + crypto_core_ristretto255_is_valid_point(s2) != 1) { + printf("crypto_scalarmult_ristretto255() failed\n"); + } + if (crypto_core_ristretto255_scalar_invert(r_inv, r) != 0) { + printf("crypto_core_ristretto255_scalar_invert() failed\n"); + } + if (crypto_scalarmult_ristretto255(s_, r_inv, s2) != 0 || + crypto_core_ristretto255_is_valid_point(s_) != 1) { + printf("crypto_scalarmult_ristretto255() failed\n"); + } + if (memcmp(s, s_, crypto_core_ristretto255_BYTES) != 0) { + printf("inversion failed\n"); + } + if (crypto_scalarmult_ristretto255(s2, l, s2) == 0) { + printf("s*l != inf (3)\n"); + } + if (crypto_core_ristretto255_add(s2, s, s_) != 0) { + printf("addition failed"); + } + if (crypto_core_ristretto255_sub(s2, s2, s_) != 0) { + printf("subtraction failed"); + } + if (crypto_core_ristretto255_is_valid_point(s2) == 0) { + printf("invalid point"); + } + if (memcmp(s, s2, crypto_core_ristretto255_BYTES) != 0) { + printf("s2 + s - s_ != s\n"); + } + if (crypto_core_ristretto255_sub(s2, s2, s) != 0) { + printf("subtraction failed"); + } + if (crypto_core_ristretto255_is_valid_point(s2) == -1) { + printf("s + s' - s - s' != 0"); + } + } + + crypto_core_ristretto255_random(s); + memset(s_, 0xfe, crypto_core_ristretto255_BYTES); + assert(crypto_core_ristretto255_add(s2, s_, s) == -1); + assert(crypto_core_ristretto255_add(s2, s, s_) == -1); + assert(crypto_core_ristretto255_add(s2, s_, s_) == -1); + assert(crypto_core_ristretto255_add(s2, s, s) == 0); + assert(crypto_core_ristretto255_sub(s2, s_, s) == -1); + assert(crypto_core_ristretto255_sub(s2, s, s_) == -1); + assert(crypto_core_ristretto255_sub(s2, s_, s_) == -1); + assert(crypto_core_ristretto255_sub(s2, s, s) == 0); + + sodium_free(s2); + sodium_free(s_); + sodium_free(s); + sodium_free(ru); + sodium_free(r_inv); + sodium_free(r); +} + +static void +tv4(void) +{ + unsigned char *r; + unsigned char *s1; + unsigned char *s2; + unsigned char *s3; + unsigned char *s4; + + r = (unsigned char *) sodium_malloc(crypto_core_ristretto255_NONREDUCEDSCALARBYTES); + s1 = (unsigned char *) sodium_malloc(crypto_core_ristretto255_SCALARBYTES); + s2 = (unsigned char *) sodium_malloc(crypto_core_ristretto255_SCALARBYTES); + s3 = (unsigned char *) sodium_malloc(crypto_core_ristretto255_SCALARBYTES); + s4 = (unsigned char *) sodium_malloc(crypto_core_ristretto255_SCALARBYTES); + + crypto_core_ristretto255_scalar_random(s1); + randombytes_buf(r, crypto_core_ristretto255_NONREDUCEDSCALARBYTES); + crypto_core_ristretto255_scalar_reduce(s2, r); + memcpy(s4, s1, crypto_core_ristretto255_SCALARBYTES); + crypto_core_ristretto255_scalar_add(s3, s1, s2); + crypto_core_ristretto255_scalar_sub(s4, s1, s2); + crypto_core_ristretto255_scalar_add(s2, s3, s4); + crypto_core_ristretto255_scalar_sub(s2, s2, s1); + crypto_core_ristretto255_scalar_mul(s2, s3, s2); + crypto_core_ristretto255_scalar_invert(s4, s3); + crypto_core_ristretto255_scalar_mul(s2, s2, s4); + crypto_core_ristretto255_scalar_negate(s1, s1); + crypto_core_ristretto255_scalar_add(s2, s2, s1); + crypto_core_ristretto255_scalar_complement(s1, s2); + s1[0]--; + assert(sodium_is_zero(s1, crypto_core_ristretto255_SCALARBYTES)); + + sodium_free(s1); + sodium_free(s2); + sodium_free(s3); + sodium_free(s4); + sodium_free(r); +} + +int +main(void) +{ + tv1(); + tv2(); + tv3(); + tv4(); + + assert(crypto_core_ristretto255_BYTES == crypto_core_ristretto255_bytes()); + assert(crypto_core_ristretto255_SCALARBYTES == crypto_core_ristretto255_scalarbytes()); + assert(crypto_core_ristretto255_NONREDUCEDSCALARBYTES == crypto_core_ristretto255_nonreducedscalarbytes()); + assert(crypto_core_ristretto255_NONREDUCEDSCALARBYTES >= crypto_core_ristretto255_SCALARBYTES); + assert(crypto_core_ristretto255_HASHBYTES == crypto_core_ristretto255_hashbytes()); + assert(crypto_core_ristretto255_HASHBYTES >= crypto_core_ristretto255_BYTES); + assert(crypto_core_ristretto255_BYTES == crypto_core_ed25519_BYTES); + assert(crypto_core_ristretto255_SCALARBYTES == crypto_core_ed25519_SCALARBYTES); + assert(crypto_core_ristretto255_NONREDUCEDSCALARBYTES == crypto_core_ed25519_NONREDUCEDSCALARBYTES); + assert(crypto_core_ristretto255_HASHBYTES >= 2 * crypto_core_ed25519_UNIFORMBYTES); + + printf("OK\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/core_ristretto255.exp b/external/src/libsodium/test/default/core_ristretto255.exp new file mode 100644 index 0000000..8618d89 --- /dev/null +++ b/external/src/libsodium/test/default/core_ristretto255.exp @@ -0,0 +1,8 @@ +3066f82a1a747d45120d1740f14358531a8f04bbffe6a819f86dfe50f44a0a46 +f26e5b6f7d362d2d2a94c5d0e7602cb4773c95a2e5c31a64f133189fa76ed61b +006ccd2a9e6867e6a2c5cea83d3302cc9de128dd2a9a57dd8ee7b9d7ffe02826 +f8f0c87cf237953c5890aec3998169005dae3eca1fbb04548c635953c817f92a +ae81e7dedf20a497e10c304a765c1767a42d6e06029758d2d7e8ef7cc4c41179 +e2705652ff9f5e44d3e841bf1c251cf7dddb77d140870d1ab2ed64f1a9ce8628 +80bd07262511cdde4863f8a7434cef696750681cb9510eea557088f76d9e5065 +OK diff --git a/external/src/libsodium/test/default/ed25519_convert.c b/external/src/libsodium/test/default/ed25519_convert.c new file mode 100644 index 0000000..d067547 --- /dev/null +++ b/external/src/libsodium/test/default/ed25519_convert.c @@ -0,0 +1,70 @@ + +#define TEST_NAME "ed25519_convert" +#include "cmptest.h" + +static const unsigned char keypair_seed[crypto_sign_ed25519_SEEDBYTES] = { + 0x42, 0x11, 0x51, 0xa4, 0x59, 0xfa, 0xea, 0xde, 0x3d, 0x24, 0x71, + 0x15, 0xf9, 0x4a, 0xed, 0xae, 0x42, 0x31, 0x81, 0x24, 0x09, 0x5a, + 0xfa, 0xbe, 0x4d, 0x14, 0x51, 0xa5, 0x59, 0xfa, 0xed, 0xee +}; + +int +main(void) +{ + unsigned char ed25519_pk[crypto_sign_ed25519_PUBLICKEYBYTES]; + unsigned char ed25519_skpk[crypto_sign_ed25519_SECRETKEYBYTES]; + unsigned char curve25519_pk[crypto_scalarmult_curve25519_BYTES]; + unsigned char curve25519_pk2[crypto_scalarmult_curve25519_BYTES]; + unsigned char curve25519_sk[crypto_scalarmult_curve25519_BYTES]; + char curve25519_pk_hex[crypto_scalarmult_curve25519_BYTES * 2 + 1]; + char curve25519_sk_hex[crypto_scalarmult_curve25519_BYTES * 2 + 1]; + unsigned int i; + + assert(crypto_sign_ed25519_SEEDBYTES <= crypto_hash_sha512_BYTES); + crypto_sign_ed25519_seed_keypair(ed25519_pk, ed25519_skpk, keypair_seed); + + if (crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk) != 0) { + printf("conversion failed\n"); + } + crypto_sign_ed25519_sk_to_curve25519(curve25519_sk, ed25519_skpk); + sodium_bin2hex(curve25519_pk_hex, sizeof curve25519_pk_hex, curve25519_pk, + sizeof curve25519_pk); + sodium_bin2hex(curve25519_sk_hex, sizeof curve25519_sk_hex, curve25519_sk, + sizeof curve25519_sk); + + printf("curve25519 pk: [%s]\n", curve25519_pk_hex); + printf("curve25519 sk: [%s]\n", curve25519_sk_hex); + + for (i = 0U; i < 500U; i++) { + crypto_sign_ed25519_keypair(ed25519_pk, ed25519_skpk); + if (crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk) != + 0) { + printf("conversion failed\n"); + } + crypto_sign_ed25519_sk_to_curve25519(curve25519_sk, ed25519_skpk); + crypto_scalarmult_curve25519_base(curve25519_pk2, curve25519_sk); + if (memcmp(curve25519_pk, curve25519_pk2, sizeof curve25519_pk) != 0) { + printf("conversion failed\n"); + } + } + + sodium_hex2bin(ed25519_pk, crypto_sign_ed25519_PUBLICKEYBYTES, + "0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000", + 64, NULL, NULL, NULL); + assert(crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk) == -1); + sodium_hex2bin(ed25519_pk, crypto_sign_ed25519_PUBLICKEYBYTES, + "0200000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000", + 64, NULL, NULL, NULL); + assert(crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk) == -1); + sodium_hex2bin(ed25519_pk, crypto_sign_ed25519_PUBLICKEYBYTES, + "0500000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000000", + 64, NULL, NULL, NULL); + assert(crypto_sign_ed25519_pk_to_curve25519(curve25519_pk, ed25519_pk) == -1); + + printf("ok\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/ed25519_convert.exp b/external/src/libsodium/test/default/ed25519_convert.exp new file mode 100644 index 0000000..cba2b7b --- /dev/null +++ b/external/src/libsodium/test/default/ed25519_convert.exp @@ -0,0 +1,3 @@ +curve25519 pk: [f1814f0e8ff1043d8a44d25babff3cedcae6c22c3edaa48f857ae70de2baae50] +curve25519 sk: [8052030376d47112be7f73ed7a019293dd12ad910b654455798b4667d73de166] +ok diff --git a/external/src/libsodium/test/default/generichash.c b/external/src/libsodium/test/default/generichash.c new file mode 100644 index 0000000..2da877d --- /dev/null +++ b/external/src/libsodium/test/default/generichash.c @@ -0,0 +1,1406 @@ + +#define TEST_NAME "generichash" +#include "cmptest.h" + +#define MAXLEN 64 + +static struct { + const char *in_hex; + const char *key_hex; + const char *out_hex; +} tests[] = { + { + "", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "10ebb67700b1868efb4417987acf4690ae9d972fb7a590c2f02871799aaa4786b5e996e8f0f4eb981fc214b005f42d2ff4233499391653df7aefcbc13fc51568" + }, + { + "00", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "961f6dd1e4dd30f63901690c512e78e4b45e4742ed197c3c5e45c549fd25f2e4187b0bc9fe30492b16b0d0bc4ef9b0f34c7003fac09a5ef1532e69430234cebd" + }, + { + "0001", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "da2cfbe2d8409a0f38026113884f84b50156371ae304c4430173d08a99d9fb1b983164a3770706d537f49e0c916d9f32b95cc37a95b99d857436f0232c88a965" + }, + { + "000102", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "33d0825dddf7ada99b0e7e307104ad07ca9cfd9692214f1561356315e784f3e5a17e364ae9dbb14cb2036df932b77f4b292761365fb328de7afdc6d8998f5fc1" + }, + { + "00010203", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "beaa5a3d08f3807143cf621d95cd690514d0b49efff9c91d24b59241ec0eefa5f60196d407048bba8d2146828ebcb0488d8842fd56bb4f6df8e19c4b4daab8ac" + }, + { + "0001020304", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "098084b51fd13deae5f4320de94a688ee07baea2800486689a8636117b46c1f4c1f6af7f74ae7c857600456a58a3af251dc4723a64cc7c0a5ab6d9cac91c20bb" + }, + { + "000102030405", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "6044540d560853eb1c57df0077dd381094781cdb9073e5b1b3d3f6c7829e12066bbaca96d989a690de72ca3133a83652ba284a6d62942b271ffa2620c9e75b1f" + }, + { + "00010203040506", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "7a8cfe9b90f75f7ecb3acc053aaed6193112b6f6a4aeeb3f65d3de541942deb9e2228152a3c4bbbe72fc3b12629528cfbb09fe630f0474339f54abf453e2ed52" + }, + { + "0001020304050607", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "380beaf6ea7cc9365e270ef0e6f3a64fb902acae51dd5512f84259ad2c91f4bc4108db73192a5bbfb0cbcf71e46c3e21aee1c5e860dc96e8eb0b7b8426e6abe9" + }, + { + "000102030405060708", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "60fe3c4535e1b59d9a61ea8500bfac41a69dffb1ceadd9aca323e9a625b64da5763bad7226da02b9c8c4f1a5de140ac5a6c1124e4f718ce0b28ea47393aa6637" + }, + { + "00010203040506070809", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "4fe181f54ad63a2983feaaf77d1e7235c2beb17fa328b6d9505bda327df19fc37f02c4b6f0368ce23147313a8e5738b5fa2a95b29de1c7f8264eb77b69f585cd" + }, + { + "000102030405060708090a", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "f228773ce3f3a42b5f144d63237a72d99693adb8837d0e112a8a0f8ffff2c362857ac49c11ec740d1500749dac9b1f4548108bf3155794dcc9e4082849e2b85b" + }, + { + "000102030405060708090a0b", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "962452a8455cc56c8511317e3b1f3b2c37df75f588e94325fdd77070359cf63a9ae6e930936fdf8e1e08ffca440cfb72c28f06d89a2151d1c46cd5b268ef8563" + }, + { + "000102030405060708090a0b0c", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "43d44bfa18768c59896bf7ed1765cb2d14af8c260266039099b25a603e4ddc5039d6ef3a91847d1088d401c0c7e847781a8a590d33a3c6cb4df0fab1c2f22355" + }, + { + "000102030405060708090a0b0c0d", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "dcffa9d58c2a4ca2cdbb0c7aa4c4c1d45165190089f4e983bb1c2cab4aaeff1fa2b5ee516fecd780540240bf37e56c8bcca7fab980e1e61c9400d8a9a5b14ac6" + }, + { + "000102030405060708090a0b0c0d0e", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "6fbf31b45ab0c0b8dad1c0f5f4061379912dde5aa922099a030b725c73346c524291adef89d2f6fd8dfcda6d07dad811a9314536c2915ed45da34947e83de34e" + }, + { + "000102030405060708090a0b0c0d0e0f", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "a0c65bddde8adef57282b04b11e7bc8aab105b99231b750c021f4a735cb1bcfab87553bba3abb0c3e64a0b6955285185a0bd35fb8cfde557329bebb1f629ee93" + }, + { + "000102030405060708090a0b0c0d0e0f10", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "f99d815550558e81eca2f96718aed10d86f3f1cfb675cce06b0eff02f617c5a42c5aa760270f2679da2677c5aeb94f1142277f21c7f79f3c4f0cce4ed8ee62b1" + }, + { + "000102030405060708090a0b0c0d0e0f1011", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "95391da8fc7b917a2044b3d6f5374e1ca072b41454d572c7356c05fd4bc1e0f40b8bb8b4a9f6bce9be2c4623c399b0dca0dab05cb7281b71a21b0ebcd9e55670" + }, + { + "000102030405060708090a0b0c0d0e0f101112", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "04b9cd3d20d221c09ac86913d3dc63041989a9a1e694f1e639a3ba7e451840f750c2fc191d56ad61f2e7936bc0ac8e094b60caeed878c18799045402d61ceaf9" + }, + { + "000102030405060708090a0b0c0d0e0f10111213", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "ec0e0ef707e4ed6c0c66f9e089e4954b058030d2dd86398fe84059631f9ee591d9d77375355149178c0cf8f8e7c49ed2a5e4f95488a2247067c208510fadc44c" + }, + { + "000102030405060708090a0b0c0d0e0f1011121314", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "9a37cce273b79c09913677510eaf7688e89b3314d3532fd2764c39de022a2945b5710d13517af8ddc0316624e73bec1ce67df15228302036f330ab0cb4d218dd" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "4cf9bb8fb3d4de8b38b2f262d3c40f46dfe747e8fc0a414c193d9fcf753106ce47a18f172f12e8a2f1c26726545358e5ee28c9e2213a8787aafbc516d2343152" + }, + { + "000102030405060708090a0b0c0d0e0f10111213141516", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "64e0c63af9c808fd893137129867fd91939d53f2af04be4fa268006100069b2d69daa5c5d8ed7fddcb2a70eeecdf2b105dd46a1e3b7311728f639ab489326bc9" + }, + { + "000102030405060708090a0b0c0d0e0f1011121314151617", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "5e9c93158d659b2def06b0c3c7565045542662d6eee8a96a89b78ade09fe8b3dcc096d4fe48815d88d8f82620156602af541955e1f6ca30dce14e254c326b88f" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "7775dff889458dd11aef417276853e21335eb88e4dec9cfb4e9edb49820088551a2ca60339f12066101169f0dfe84b098fddb148d9da6b3d613df263889ad64b" + }, + { + "000102030405060708090a0b0c0d0e0f10111213141516171819", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "f0d2805afbb91f743951351a6d024f9353a23c7ce1fc2b051b3a8b968c233f46f50f806ecb1568ffaa0b60661e334b21dde04f8fa155ac740eeb42e20b60d764" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "86a2af316e7d7754201b942e275364ac12ea8962ab5bd8d7fb276dc5fbffc8f9a28cae4e4867df6780d9b72524160927c855da5b6078e0b554aa91e31cb9ca1d" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "10bdf0caa0802705e706369baf8a3f79d72c0a03a80675a7bbb00be3a45e516424d1ee88efb56f6d5777545ae6e27765c3a8f5e493fc308915638933a1dfee55" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "b01781092b1748459e2e4ec178696627bf4ebafebba774ecf018b79a68aeb84917bf0b84bb79d17b743151144cd66b7b33a4b9e52c76c4e112050ff5385b7f0b" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c6dbc61dec6eaeac81e3d5f755203c8e220551534a0b2fd105a91889945a638550204f44093dd998c076205dffad703a0e5cd3c7f438a7e634cd59fededb539e" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "eba51acffb4cea31db4b8d87e9bf7dd48fe97b0253ae67aa580f9ac4a9d941f2bea518ee286818cc9f633f2a3b9fb68e594b48cdd6d515bf1d52ba6c85a203a7" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "86221f3ada52037b72224f105d7999231c5e5534d03da9d9c0a12acb68460cd375daf8e24386286f9668f72326dbf99ba094392437d398e95bb8161d717f8991" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "5595e05c13a7ec4dc8f41fb70cb50a71bce17c024ff6de7af618d0cc4e9c32d9570d6d3ea45b86525491030c0d8f2b1836d5778c1ce735c17707df364d054347" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "ce0f4f6aca89590a37fe034dd74dd5fa65eb1cbd0a41508aaddc09351a3cea6d18cb2189c54b700c009f4cbf0521c7ea01be61c5ae09cb54f27bc1b44d658c82" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "7ee80b06a215a3bca970c77cda8761822bc103d44fa4b33f4d07dcb997e36d55298bceae12241b3fa07fa63be5576068da387b8d5859aeab701369848b176d42" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "940a84b6a84d109aab208c024c6ce9647676ba0aaa11f86dbb7018f9fd2220a6d901a9027f9abcf935372727cbf09ebd61a2a2eeb87653e8ecad1bab85dc8327" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "2020b78264a82d9f4151141adba8d44bf20c5ec062eee9b595a11f9e84901bf148f298e0c9f8777dcdbc7cc4670aac356cc2ad8ccb1629f16f6a76bcefbee760" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "d1b897b0e075ba68ab572adf9d9c436663e43eb3d8e62d92fc49c9be214e6f27873fe215a65170e6bea902408a25b49506f47babd07cecf7113ec10c5dd31252" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "b14d0c62abfa469a357177e594c10c194243ed2025ab8aa5ad2fa41ad318e0ff48cd5e60bec07b13634a711d2326e488a985f31e31153399e73088efc86a5c55" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324252627", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "4169c5cc808d2697dc2a82430dc23e3cd356dc70a94566810502b8d655b39abf9e7f902fe717e0389219859e1945df1af6ada42e4ccda55a197b7100a30c30a1" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "258a4edb113d66c839c8b1c91f15f35ade609f11cd7f8681a4045b9fef7b0b24c82cda06a5f2067b368825e3914e53d6948ede92efd6e8387fa2e537239b5bee" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20212223242526272829", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "79d2d8696d30f30fb34657761171a11e6c3f1e64cbe7bebee159cb95bfaf812b4f411e2f26d9c421dc2c284a3342d823ec293849e42d1e46b0a4ac1e3c86abaa" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "8b9436010dc5dee992ae38aea97f2cd63b946d94fedd2ec9671dcde3bd4ce9564d555c66c15bb2b900df72edb6b891ebcadfeff63c9ea4036a998be7973981e7" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c8f68e696ed28242bf997f5b3b34959508e42d613810f1e2a435c96ed2ff560c7022f361a9234b9837feee90bf47922ee0fd5f8ddf823718d86d1e16c6090071" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "b02d3eee4860d5868b2c39ce39bfe81011290564dd678c85e8783f29302dfc1399ba95b6b53cd9ebbf400cca1db0ab67e19a325f2d115812d25d00978ad1bca4" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "7693ea73af3ac4dad21ca0d8da85b3118a7d1c6024cfaf557699868217bc0c2f44a199bc6c0edd519798ba05bd5b1b4484346a47c2cadf6bf30b785cc88b2baf" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "a0e5c1c0031c02e48b7f09a5e896ee9aef2f17fc9e18e997d7f6cac7ae316422c2b1e77984e5f3a73cb45deed5d3f84600105e6ee38f2d090c7d0442ea34c46d" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "41daa6adcfdb69f1440c37b596440165c15ada596813e2e22f060fcd551f24dee8e04ba6890387886ceec4a7a0d7fc6b44506392ec3822c0d8c1acfc7d5aebe8" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "14d4d40d5984d84c5cf7523b7798b254e275a3a8cc0a1bd06ebc0bee726856acc3cbf516ff667cda2058ad5c3412254460a82c92187041363cc77a4dc215e487" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "d0e7a1e2b9a447fee83e2277e9ff8010c2f375ae12fa7aaa8ca5a6317868a26a367a0b69fbc1cf32a55d34eb370663016f3d2110230eba754028a56f54acf57c" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "e771aa8db5a3e043e8178f39a0857ba04a3f18e4aa05743cf8d222b0b095825350ba422f63382a23d92e4149074e816a36c1cd28284d146267940b31f8818ea2" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "feb4fd6f9e87a56bef398b3284d2bda5b5b0e166583a66b61e538457ff0584872c21a32962b9928ffab58de4af2edd4e15d8b35570523207ff4e2a5aa7754caa" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "462f17bf005fb1c1b9e671779f665209ec2873e3e411f98dabf240a1d5ec3f95ce6796b6fc23fe171903b502023467dec7273ff74879b92967a2a43a5a183d33" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "d3338193b64553dbd38d144bea71c5915bb110e2d88180dbc5db364fd6171df317fc7268831b5aef75e4342b2fad8797ba39eddcef80e6ec08159350b1ad696d" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "e1590d585a3d39f7cb599abd479070966409a6846d4377acf4471d065d5db94129cc9be92573b05ed226be1e9b7cb0cabe87918589f80dadd4ef5ef25a93d28e" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "f8f3726ac5a26cc80132493a6fedcb0e60760c09cfc84cad178175986819665e76842d7b9fedf76dddebf5d3f56faaad4477587af21606d396ae570d8e719af2" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "30186055c07949948183c850e9a756cc09937e247d9d928e869e20bafc3cd9721719d34e04a0899b92c736084550186886efba2e790d8be6ebf040b209c439a4" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30313233343536373839", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "f3c4276cb863637712c241c444c5cc1e3554e0fddb174d035819dd83eb700b4ce88df3ab3841ba02085e1a99b4e17310c5341075c0458ba376c95a6818fbb3e2" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "0aa007c4dd9d5832393040a1583c930bca7dc5e77ea53add7e2b3f7c8e231368043520d4a3ef53c969b6bbfd025946f632bd7f765d53c21003b8f983f75e2a6a" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "08e9464720533b23a04ec24f7ae8c103145f765387d738777d3d343477fd1c58db052142cab754ea674378e18766c53542f71970171cc4f81694246b717d7564" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "d37ff7ad297993e7ec21e0f1b4b5ae719cdc83c5db687527f27516cbffa822888a6810ee5c1ca7bfe3321119be1ab7bfa0a502671c8329494df7ad6f522d440f" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "dd9042f6e464dcf86b1262f6accfafbd8cfd902ed3ed89abf78ffa482dbdeeb6969842394c9a1168ae3d481a017842f660002d42447c6b22f7b72f21aae021c9" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "bd965bf31e87d70327536f2a341cebc4768eca275fa05ef98f7f1b71a0351298de006fba73fe6733ed01d75801b4a928e54231b38e38c562b2e33ea1284992fa" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "65676d800617972fbd87e4b9514e1c67402b7a331096d3bfac22f1abb95374abc942f16e9ab0ead33b87c91968a6e509e119ff07787b3ef483e1dcdccf6e3022" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "939fa189699c5d2c81ddd1ffc1fa207c970b6a3685bb29ce1d3e99d42f2f7442da53e95a72907314f4588399a3ff5b0a92beb3f6be2694f9f86ecf2952d5b41c" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c516541701863f91005f314108ceece3c643e04fc8c42fd2ff556220e616aaa6a48aeb97a84bad74782e8dff96a1a2fa949339d722edcaa32b57067041df88cc" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "987fd6e0d6857c553eaebb3d34970a2c2f6e89a3548f492521722b80a1c21a153892346d2cba6444212d56da9a26e324dccbc0dcde85d4d2ee4399eec5a64e8f" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "ae56deb1c2328d9c4017706bce6e99d41349053ba9d336d677c4c27d9fd50ae6aee17e853154e1f4fe7672346da2eaa31eea53fcf24a22804f11d03da6abfc2b" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "49d6a608c9bde4491870498572ac31aac3fa40938b38a7818f72383eb040ad39532bc06571e13d767e6945ab77c0bdc3b0284253343f9f6c1244ebf2ff0df866" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "da582ad8c5370b4469af862aa6467a2293b2b28bd80ae0e91f425ad3d47249fdf98825cc86f14028c3308c9804c78bfeeeee461444ce243687e1a50522456a1d" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243444546", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "d5266aa3331194aef852eed86d7b5b2633a0af1c735906f2e13279f14931a9fc3b0eac5ce9245273bd1aa92905abe16278ef7efd47694789a7283b77da3c70f8" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f4041424344454647", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "2962734c28252186a9a1111c732ad4de4506d4b4480916303eb7991d659ccda07a9911914bc75c418ab7a4541757ad054796e26797feaf36e9f6ad43f14b35a4" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "e8b79ec5d06e111bdfafd71e9f5760f00ac8ac5d8bf768f9ff6f08b8f026096b1cc3a4c973333019f1e3553e77da3f98cb9f542e0a90e5f8a940cc58e59844b3" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f40414243444546474849", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "dfb320c44f9d41d1efdcc015f08dd5539e526e39c87d509ae6812a969e5431bf4fa7d91ffd03b981e0d544cf72d7b1c0374f8801482e6dea2ef903877eba675e" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "d88675118fdb55a5fb365ac2af1d217bf526ce1ee9c94b2f0090b2c58a06ca58187d7fe57c7bed9d26fca067b4110eefcd9a0a345de872abe20de368001b0745" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "b893f2fc41f7b0dd6e2f6aa2e0370c0cff7df09e3acfcc0e920b6e6fad0ef747c40668417d342b80d2351e8c175f20897a062e9765e6c67b539b6ba8b9170545" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "6c67ec5697accd235c59b486d7b70baeedcbd4aa64ebd4eef3c7eac189561a726250aec4d48cadcafbbe2ce3c16ce2d691a8cce06e8879556d4483ed7165c063" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "f1aa2b044f8f0c638a3f362e677b5d891d6fd2ab0765f6ee1e4987de057ead357883d9b405b9d609eea1b869d97fb16d9b51017c553f3b93c0a1e0f1296fedcd" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "cbaa259572d4aebfc1917acddc582b9f8dfaa928a198ca7acd0f2aa76a134a90252e6298a65b08186a350d5b7626699f8cb721a3ea5921b753ae3a2dce24ba3a" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "fa1549c9796cd4d303dcf452c1fbd5744fd9b9b47003d920b92de34839d07ef2a29ded68f6fc9e6c45e071a2e48bd50c5084e96b657dd0404045a1ddefe282ed" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "5cf2ac897ab444dcb5c8d87c495dbdb34e1838b6b629427caa51702ad0f9688525f13bec503a3c3a2c80a65e0b5715e8afab00ffa56ec455a49a1ad30aa24fcd" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f5051", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "9aaf80207bace17bb7ab145757d5696bde32406ef22b44292ef65d4519c3bb2ad41a59b62cc3e94b6fa96d32a7faadae28af7d35097219aa3fd8cda31e40c275" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "af88b163402c86745cb650c2988fb95211b94b03ef290eed9662034241fd51cf398f8073e369354c43eae1052f9b63b08191caa138aa54fea889cc7024236897" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "48fa7d64e1ceee27b9864db5ada4b53d00c9bc7626555813d3cd6730ab3cc06ff342d727905e33171bde6e8476e77fb1720861e94b73a2c538d254746285f430" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f5051525354", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "0e6fd97a85e904f87bfe85bbeb34f69e1f18105cf4ed4f87aec36c6e8b5f68bd2a6f3dc8a9ecb2b61db4eedb6b2ea10bf9cb0251fb0f8b344abf7f366b6de5ab" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "06622da5787176287fdc8fed440bad187d830099c94e6d04c8e9c954cda70c8bb9e1fc4a6d0baa831b9b78ef6648681a4867a11da93ee36e5e6a37d87fc63f6f" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253545556", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "1da6772b58fabf9c61f68d412c82f182c0236d7d575ef0b58dd22458d643cd1dfc93b03871c316d8430d312995d4197f0874c99172ba004a01ee295abac24e46" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f5051525354555657", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "3cd2d9320b7b1d5fb9aab951a76023fa667be14a9124e394513918a3f44096ae4904ba0ffc150b63bc7ab1eeb9a6e257e5c8f000a70394a5afd842715de15f29" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "04cdc14f7434e0b4be70cb41db4c779a88eaef6accebcb41f2d42fffe7f32a8e281b5c103a27021d0d08362250753cdf70292195a53a48728ceb5844c2d98bab" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f50515253545556575859", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "9071b7a8a075d0095b8fb3ae5113785735ab98e2b52faf91d5b89e44aac5b5d4ebbf91223b0ff4c71905da55342e64655d6ef8c89a4768c3f93a6dc0366b5bc8" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "ebb30240dd96c7bc8d0abe49aa4edcbb4afdc51ff9aaf720d3f9e7fbb0f9c6d6571350501769fc4ebd0b2141247ff400d4fd4be414edf37757bb90a32ac5c65a" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "8532c58bf3c8015d9d1cbe00eef1f5082f8f3632fbe9f1ed4f9dfb1fa79e8283066d77c44c4af943d76b300364aecbd0648c8a8939bd204123f4b56260422dec" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "fe9846d64f7c7708696f840e2d76cb4408b6595c2f81ec6a28a7f2f20cb88cfe6ac0b9e9b8244f08bd7095c350c1d0842f64fb01bb7f532dfcd47371b0aeeb79" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "28f17ea6fb6c42092dc264257e29746321fb5bdaea9873c2a7fa9d8f53818e899e161bc77dfe8090afd82bf2266c5c1bc930a8d1547624439e662ef695f26f24" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "ec6b7d7f030d4850acae3cb615c21dd25206d63e84d1db8d957370737ba0e98467ea0ce274c66199901eaec18a08525715f53bfdb0aacb613d342ebdceeddc3b" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "b403d3691c03b0d3418df327d5860d34bbfcc4519bfbce36bf33b208385fadb9186bc78a76c489d89fd57e7dc75412d23bcd1dae8470ce9274754bb8585b13c5" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "31fc79738b8772b3f55cd8178813b3b52d0db5a419d30ba9495c4b9da0219fac6df8e7c23a811551a62b827f256ecdb8124ac8a6792ccfecc3b3012722e94463" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "bb2039ec287091bcc9642fc90049e73732e02e577e2862b32216ae9bedcd730c4c284ef3968c368b7d37584f97bd4b4dc6ef6127acfe2e6ae2509124e66c8af4" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "f53d68d13f45edfcb9bd415e2831e938350d5380d3432278fc1c0c381fcb7c65c82dafe051d8c8b0d44e0974a0e59ec7bf7ed0459f86e96f329fc79752510fd3" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60616263", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "8d568c7984f0ecdf7640fbc483b5d8c9f86634f6f43291841b309a350ab9c1137d24066b09da9944bac54d5bb6580d836047aac74ab724b887ebf93d4b32eca9" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061626364", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c0b65ce5a96ff774c456cac3b5f2c4cd359b4ff53ef93a3da0778be4900d1e8da1601e769e8f1b02d2a2f8c5b9fa10b44f1c186985468feeb008730283a6657d" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "4900bba6f5fb103ece8ec96ada13a5c3c85488e05551da6b6b33d988e611ec0fe2e3c2aa48ea6ae8986a3a231b223c5d27cec2eadde91ce07981ee652862d1e4" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60616263646566", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c7f5c37c7285f927f76443414d4357ff789647d7a005a5a787e03c346b57f49f21b64fa9cf4b7e45573e23049017567121a9c3d4b2b73ec5e9413577525db45a" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f6061626364656667", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "ec7096330736fdb2d64b5653e7475da746c23a4613a82687a28062d3236364284ac01720ffb406cfe265c0df626a188c9e5963ace5d3d5bb363e32c38c2190a6" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "82e744c75f4649ec52b80771a77d475a3bc091989556960e276a5f9ead92a03f718742cdcfeaee5cb85c44af198adc43a4a428f5f0c2ddb0be36059f06d7df73" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f60616263646566676869", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "2834b7a7170f1f5b68559ab78c1050ec21c919740b784a9072f6e5d69f828d70c919c5039fb148e39e2c8a52118378b064ca8d5001cd10a5478387b966715ed6" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "16b4ada883f72f853bb7ef253efcab0c3e2161687ad61543a0d2824f91c1f81347d86be709b16996e17f2dd486927b0288ad38d13063c4a9672c39397d3789b6" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "78d048f3a69d8b54ae0ed63a573ae350d89f7c6cf1f3688930de899afa037697629b314e5cd303aa62feea72a25bf42b304b6c6bcb27fae21c16d925e1fbdac3" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "0f746a48749287ada77a82961f05a4da4abdb7d77b1220f836d09ec814359c0ec0239b8c7b9ff9e02f569d1b301ef67c4612d1de4f730f81c12c40cc063c5caa" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "f0fc859d3bd195fbdc2d591e4cdac15179ec0f1dc821c11df1f0c1d26e6260aaa65b79fafacafd7d3ad61e600f250905f5878c87452897647a35b995bcadc3a3" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "2620f687e8625f6a412460b42e2cef67634208ce10a0cbd4dff7044a41b7880077e9f8dc3b8d1216d3376a21e015b58fb279b521d83f9388c7382c8505590b9b" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "227e3aed8d2cb10b918fcb04f9de3e6d0a57e08476d93759cd7b2ed54a1cbf0239c528fb04bbf288253e601d3bc38b21794afef90b17094a182cac557745e75f" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "1a929901b09c25f27d6b35be7b2f1c4745131fdebca7f3e2451926720434e0db6e74fd693ad29b777dc3355c592a361c4873b01133a57c2e3b7075cbdb86f4fc" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f7071", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "5fd7968bc2fe34f220b5e3dc5af9571742d73b7d60819f2888b629072b96a9d8ab2d91b82d0a9aaba61bbd39958132fcc4257023d1eca591b3054e2dc81c8200" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "dfcce8cf32870cc6a503eadafc87fd6f78918b9b4d0737db6810be996b5497e7e5cc80e312f61e71ff3e9624436073156403f735f56b0b01845c18f6caf772e6" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717273", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "02f7ef3a9ce0fff960f67032b296efca3061f4934d690749f2d01c35c81c14f39a67fa350bc8a0359bf1724bffc3bca6d7c7bba4791fd522a3ad353c02ec5aa8" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f7071727374", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "64be5c6aba65d594844ae78bb022e5bebe127fd6b6ffa5a13703855ab63b624dcd1a363f99203f632ec386f3ea767fc992e8ed9686586aa27555a8599d5b808f" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "f78585505c4eaa54a8b5be70a61e735e0ff97af944ddb3001e35d86c4e2199d976104b6ae31750a36a726ed285064f5981b503889fef822fcdc2898dddb7889a" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717273747576", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "e4b5566033869572edfd87479a5bb73c80e8759b91232879d96b1dda36c012076ee5a2ed7ae2de63ef8406a06aea82c188031b560beafb583fb3de9e57952a7e" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f7071727374757677", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "e1b3e7ed867f6c9484a2a97f7715f25e25294e992e41f6a7c161ffc2adc6daaeb7113102d5e6090287fe6ad94ce5d6b739c6ca240b05c76fb73f25dd024bf935" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "85fd085fdc12a080983df07bd7012b0d402a0f4043fcb2775adf0bad174f9b08d1676e476985785c0a5dcc41dbff6d95ef4d66a3fbdc4a74b82ba52da0512b74" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f70717273747576777879", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "aed8fa764b0fbff821e05233d2f7b0900ec44d826f95e93c343c1bc3ba5a24374b1d616e7e7aba453a0ada5e4fab5382409e0d42ce9c2bc7fb39a99c340c20f0" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "7ba3b2e297233522eeb343bd3ebcfd835a04007735e87f0ca300cbee6d416565162171581e4020ff4cf176450f1291ea2285cb9ebffe4c56660627685145051c" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "de748bcf89ec88084721e16b85f30adb1a6134d664b5843569babc5bbd1a15ca9b61803c901a4fef32965a1749c9f3a4e243e173939dc5a8dc495c671ab52145" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "aaf4d2bdf200a919706d9842dce16c98140d34bc433df320aba9bd429e549aa7a3397652a4d768277786cf993cde2338673ed2e6b66c961fefb82cd20c93338f" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c408218968b788bf864f0997e6bc4c3dba68b276e2125a4843296052ff93bf5767b8cdce7131f0876430c1165fec6c4f47adaa4fd8bcfacef463b5d3d0fa61a0" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "76d2d819c92bce55fa8e092ab1bf9b9eab237a25267986cacf2b8ee14d214d730dc9a5aa2d7b596e86a1fd8fa0804c77402d2fcd45083688b218b1cdfa0dcbcb" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "72065ee4dd91c2d8509fa1fc28a37c7fc9fa7d5b3f8ad3d0d7a25626b57b1b44788d4caf806290425f9890a3a2a35a905ab4b37acfd0da6e4517b2525c9651e4" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "64475dfe7600d7171bea0b394e27c9b00d8e74dd1e416a79473682ad3dfdbb706631558055cfc8a40e07bd015a4540dcdea15883cbbf31412df1de1cd4152b91" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "12cd1674a4488a5d7c2b3160d2e2c4b58371bedad793418d6f19c6ee385d70b3e06739369d4df910edb0b0a54cbff43d54544cd37ab3a06cfa0a3ddac8b66c89" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "60756966479dedc6dd4bcff8ea7d1d4ce4d4af2e7b097e32e3763518441147cc12b3c0ee6d2ecabf1198cec92e86a3616fba4f4e872f5825330adbb4c1dee444" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818283", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "a7803bcb71bc1d0f4383dde1e0612e04f872b715ad30815c2249cf34abb8b024915cb2fc9f4e7cc4c8cfd45be2d5a91eab0941c7d270e2da4ca4a9f7ac68663a" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081828384", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "b84ef6a7229a34a750d9a98ee2529871816b87fbe3bc45b45fa5ae82d5141540211165c3c5d7a7476ba5a4aa06d66476f0d9dc49a3f1ee72c3acabd498967414" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "fae4b6d8efc3f8c8e64d001dabec3a21f544e82714745251b2b4b393f2f43e0da3d403c64db95a2cb6e23ebb7b9e94cdd5ddac54f07c4a61bd3cb10aa6f93b49" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818283848586", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "34f7286605a122369540141ded79b8957255da2d4155abbf5a8dbb89c8eb7ede8eeef1daa46dc29d751d045dc3b1d658bb64b80ff8589eddb3824b13da235a6b" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f8081828384858687", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "3b3b48434be27b9eababba43bf6b35f14b30f6a88dc2e750c358470d6b3aa3c18e47db4017fa55106d8252f016371a00f5f8b070b74ba5f23cffc5511c9f09f0" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "ba289ebd6562c48c3e10a8ad6ce02e73433d1e93d7c9279d4d60a7e879ee11f441a000f48ed9f7c4ed87a45136d7dccdca482109c78a51062b3ba4044ada2469" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f80818283848586878889", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "022939e2386c5a37049856c850a2bb10a13dfea4212b4c732a8840a9ffa5faf54875c5448816b2785a007da8a8d2bc7d71a54e4e6571f10b600cbdb25d13ede3" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "e6fec19d89ce8717b1a087024670fe026f6c7cbda11caef959bb2d351bf856f8055d1c0ebdaaa9d1b17886fc2c562b5e99642fc064710c0d3488a02b5ed7f6fd" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "94c96f02a8f576aca32ba61c2b206f907285d9299b83ac175c209a8d43d53bfe683dd1d83e7549cb906c28f59ab7c46f8751366a28c39dd5fe2693c9019666c8" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "31a0cd215ebd2cb61de5b9edc91e6195e31c59a5648d5c9f737e125b2605708f2e325ab3381c8dce1a3e958886f1ecdc60318f882cfe20a24191352e617b0f21" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "91ab504a522dce78779f4c6c6ba2e6b6db5565c76d3e7e7c920caf7f757ef9db7c8fcf10e57f03379ea9bf75eb59895d96e149800b6aae01db778bb90afbc989" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "d85cabc6bd5b1a01a5afd8c6734740da9fd1c1acc6db29bfc8a2e5b668b028b6b3154bfb8703fa3180251d589ad38040ceb707c4bad1b5343cb426b61eaa49c1" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "d62efbec2ca9c1f8bd66ce8b3f6a898cb3f7566ba6568c618ad1feb2b65b76c3ce1dd20f7395372faf28427f61c9278049cf0140df434f5633048c86b81e0399" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "7c8fdc6175439e2c3db15bafa7fb06143a6a23bc90f449e79deef73c3d492a671715c193b6fea9f036050b946069856b897e08c00768f5ee5ddcf70b7cd6d0e0" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f9091", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "58602ee7468e6bc9df21bd51b23c005f72d6cb013f0a1b48cbec5eca299299f97f09f54a9a01483eaeb315a6478bad37ba47ca1347c7c8fc9e6695592c91d723" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "27f5b79ed256b050993d793496edf4807c1d85a7b0a67c9c4fa99860750b0ae66989670a8ffd7856d7ce411599e58c4d77b232a62bef64d15275be46a68235ff" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90919293", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "3957a976b9f1887bf004a8dca942c92d2b37ea52600f25e0c9bc5707d0279c00c6e85a839b0d2d8eb59c51d94788ebe62474a791cadf52cccf20f5070b6573fc" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f9091929394", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "eaa2376d55380bf772ecca9cb0aa4668c95c707162fa86d518c8ce0ca9bf7362b9f2a0adc3ff59922df921b94567e81e452f6c1a07fc817cebe99604b3505d38" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c1e2c78b6b2734e2480ec550434cb5d613111adcc21d475545c3b1b7e6ff12444476e5c055132e2229dc0f807044bb919b1a5662dd38a9ee65e243a3911aed1a" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90919293949596", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "8ab48713389dd0fcf9f965d3ce66b1e559a1f8c58741d67683cd971354f452e62d0207a65e436c5d5d8f8ee71c6abfe50e669004c302b31a7ea8311d4a916051" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f9091929394959697", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "24ce0addaa4c65038bd1b1c0f1452a0b128777aabc94a29df2fd6c7e2f85f8ab9ac7eff516b0e0a825c84a24cfe492eaad0a6308e46dd42fe8333ab971bb30ca" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "5154f929ee03045b6b0c0004fa778edee1d139893267cc84825ad7b36c63de32798e4a166d24686561354f63b00709a1364b3c241de3febf0754045897467cd4" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f90919293949596979899", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "e74e907920fd87bd5ad636dd11085e50ee70459c443e1ce5809af2bc2eba39f9e6d7128e0e3712c316da06f4705d78a4838e28121d4344a2c79c5e0db307a677" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "bf91a22334bac20f3fd80663b3cd06c4e8802f30e6b59f90d3035cc9798a217ed5a31abbda7fa6842827bdf2a7a1c21f6fcfccbb54c6c52926f32da816269be1" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "d9d5c74be5121b0bd742f26bffb8c89f89171f3f934913492b0903c271bbe2b3395ef259669bef43b57f7fcc3027db01823f6baee66e4f9fead4d6726c741fce" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "50c8b8cf34cd879f80e2faab3230b0c0e1cc3e9dcadeb1b9d97ab923415dd9a1fe38addd5c11756c67990b256e95ad6d8f9fedce10bf1c90679cde0ecf1be347" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "0a386e7cd5dd9b77a035e09fe6fee2c8ce61b5383c87ea43205059c5e4cd4f4408319bb0a82360f6a58e6c9ce3f487c446063bf813bc6ba535e17fc1826cfc91" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "1f1459cb6b61cbac5f0efe8fc487538f42548987fcd56221cfa7beb22504769e792c45adfb1d6b3d60d7b749c8a75b0bdf14e8ea721b95dca538ca6e25711209" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9f", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "e58b3836b7d8fedbb50ca5725c6571e74c0785e97821dab8b6298c10e4c079d4a6cdf22f0fedb55032925c16748115f01a105e77e00cee3d07924dc0d8f90659" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "b929cc6505f020158672deda56d0db081a2ee34c00c1100029bdf8ea98034fa4bf3e8655ec697fe36f40553c5bb46801644a627d3342f4fc92b61f03290fb381" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "72d353994b49d3e03153929a1e4d4f188ee58ab9e72ee8e512f29bc773913819ce057ddd7002c0433ee0a16114e3d156dd2c4a7e80ee53378b8670f23e33ef56" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c70ef9bfd775d408176737a0736d68517ce1aaad7e81a93c8c1ed967ea214f56c8a377b1763e676615b60f3988241eae6eab9685a5124929d28188f29eab06f7" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c230f0802679cb33822ef8b3b21bf7a9a28942092901d7dac3760300831026cf354c9232df3e084d9903130c601f63c1f4a4a4b8106e468cd443bbe5a734f45f" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "6f43094cafb5ebf1f7a4937ec50f56a4c9da303cbb55ac1f27f1f1976cd96beda9464f0e7b9c54620b8a9fba983164b8be3578425a024f5fe199c36356b88972" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "3745273f4c38225db2337381871a0c6aafd3af9b018c88aa02025850a5dc3a42a1a3e03e56cbf1b0876d63a441f1d2856a39b8801eb5af325201c415d65e97fe" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c50c44cca3ec3edaae779a7e179450ebdda2f97067c690aa6c5a4ac7c30139bb27c0df4db3220e63cb110d64f37ffe078db72653e2daacf93ae3f0a2d1a7eb2e" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "8aef263e385cbc61e19b28914243262af5afe8726af3ce39a79c27028cf3ecd3f8d2dfd9cfc9ad91b58f6f20778fd5f02894a3d91c7d57d1e4b866a7f364b6be" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "28696141de6e2d9bcb3235578a66166c1448d3e905a1b482d423be4bc5369bc8c74dae0acc9cc123e1d8ddce9f97917e8c019c552da32d39d2219b9abf0fa8c8" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "2fb9eb2085830181903a9dafe3db428ee15be7662224efd643371fb25646aee716e531eca69b2bdc8233f1a8081fa43da1500302975a77f42fa592136710e9dc" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aa", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "66f9a7143f7a3314a669bf2e24bbb35014261d639f495b6c9c1f104fe8e320aca60d4550d69d52edbd5a3cdeb4014ae65b1d87aa770b69ae5c15f4330b0b0ad8" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaab", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "f4c4dd1d594c3565e3e25ca43dad82f62abea4835ed4cd811bcd975e46279828d44d4c62c3679f1b7f7b9dd4571d7b49557347b8c5460cbdc1bef690fb2a08c0" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabac", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "8f1dc9649c3a84551f8f6e91cac68242a43b1f8f328ee92280257387fa7559aa6db12e4aeadc2d26099178749c6864b357f3f83b2fb3efa8d2a8db056bed6bcc" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacad", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "3139c1a7f97afd1675d460ebbc07f2728aa150df849624511ee04b743ba0a833092f18c12dc91b4dd243f333402f59fe28abdbbbae301e7b659c7a26d5c0f979" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadae", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "06f94a2996158a819fe34c40de3cf0379fd9fb85b3e363ba3926a0e7d960e3f4c2e0c70c7ce0ccb2a64fc29869f6e7ab12bd4d3f14fce943279027e785fb5c29" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c29c399ef3eee8961e87565c1ce263925fc3d0ce267d13e48dd9e732ee67b0f69fad56401b0f10fcaac119201046cca28c5b14abdea3212ae65562f7f138db3d" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "4cec4c9df52eef05c3f6faaa9791bc7445937183224ecc37a1e58d0132d35617531d7e795f52af7b1eb9d147de1292d345fe341823f8e6bc1e5badca5c656108" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "898bfbae93b3e18d00697eab7d9704fa36ec339d076131cefdf30edbe8d9cc81c3a80b129659b163a323bab9793d4feed92d54dae966c77529764a09be88db45" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "ee9bd0469d3aaf4f14035be48a2c3b84d9b4b1fff1d945e1f1c1d38980a951be197b25fe22c731f20aeacc930ba9c4a1f4762227617ad350fdabb4e80273a0f4" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "3d4d3113300581cd96acbf091c3d0f3c310138cd6979e6026cde623e2dd1b24d4a8638bed1073344783ad0649cc6305ccec04beb49f31c633088a99b65130267" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "95c0591ad91f921ac7be6d9ce37e0663ed8011c1cfd6d0162a5572e94368bac02024485e6a39854aa46fe38e97d6c6b1947cd272d86b06bb5b2f78b9b68d559d" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "227b79ded368153bf46c0a3ca978bfdbef31f3024a5665842468490b0ff748ae04e7832ed4c9f49de9b1706709d623e5c8c15e3caecae8d5e433430ff72f20eb" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "5d34f3952f0105eef88ae8b64c6ce95ebfade0e02c69b08762a8712d2e4911ad3f941fc4034dc9b2e479fdbcd279b902faf5d838bb2e0c6495d372b5b7029813" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "7f939bf8353abce49e77f14f3750af20b7b03902e1a1e7fb6aaf76d0259cd401a83190f15640e74f3e6c5a90e839c7821f6474757f75c7bf9002084ddc7a62dc" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "062b61a2f9a33a71d7d0a06119644c70b0716a504de7e5e1be49bd7b86e7ed6817714f9f0fc313d06129597e9a2235ec8521de36f7290a90ccfc1ffa6d0aee29" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "f29e01eeae64311eb7f1c6422f946bf7bea36379523e7b2bbaba7d1d34a22d5ea5f1c5a09d5ce1fe682cced9a4798d1a05b46cd72dff5c1b355440b2a2d476bc" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9ba", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "ec38cd3bbab3ef35d7cb6d5c914298351d8a9dc97fcee051a8a02f58e3ed6184d0b7810a5615411ab1b95209c3c810114fdeb22452084e77f3f847c6dbaafe16" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babb", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c2aef5e0ca43e82641565b8cb943aa8ba53550caef793b6532fafad94b816082f0113a3ea2f63608ab40437ecc0f0229cb8fa224dcf1c478a67d9b64162b92d1" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbc", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "15f534efff7105cd1c254d074e27d5898b89313b7d366dc2d7d87113fa7d53aae13f6dba487ad8103d5e854c91fdb6e1e74b2ef6d1431769c30767dde067a35c" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbd", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "89acbca0b169897a0a2714c2df8c95b5b79cb69390142b7d6018bb3e3076b099b79a964152a9d912b1b86412b7e372e9cecad7f25d4cbab8a317be36492a67d7" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbe", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "e3c0739190ed849c9c962fd9dbb55e207e624fcac1eb417691515499eea8d8267b7e8f1287a63633af5011fde8c4ddf55bfdf722edf88831414f2cfaed59cb9a" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "8d6cf87c08380d2d1506eee46fd4222d21d8c04e585fbfd08269c98f702833a156326a0724656400ee09351d57b440175e2a5de93cc5f80db6daf83576cf75fa" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "da24bede383666d563eeed37f6319baf20d5c75d1635a6ba5ef4cfa1ac95487e96f8c08af600aab87c986ebad49fc70a58b4890b9c876e091016daf49e1d322e" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "f9d1d1b1e87ea7ae753a029750cc1cf3d0157d41805e245c5617bb934e732f0ae3180b78e05bfe76c7c3051e3e3ac78b9b50c05142657e1e03215d6ec7bfd0fc" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "11b7bc1668032048aa43343de476395e814bbbc223678db951a1b03a021efac948cfbe215f97fe9a72a2f6bc039e3956bfa417c1a9f10d6d7ba5d3d32ff323e5" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "b8d9000e4fc2b066edb91afee8e7eb0f24e3a201db8b6793c0608581e628ed0bcc4e5aa6787992a4bcc44e288093e63ee83abd0bc3ec6d0934a674a4da13838a" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "ce325e294f9b6719d6b61278276ae06a2564c03bb0b783fafe785bdf89c7d5acd83e78756d301b445699024eaeb77b54d477336ec2a4f332f2b3f88765ddb0c3" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "29acc30e9603ae2fccf90bf97e6cc463ebe28c1b2f9b4b765e70537c25c702a29dcbfbf14c99c54345ba2b51f17b77b5f15db92bbad8fa95c471f5d070a137cc" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "3379cbaae562a87b4c0425550ffdd6bfe1203f0d666cc7ea095be407a5dfe61ee91441cd5154b3e53b4f5fb31ad4c7a9ad5c7af4ae679aa51a54003a54ca6b2d" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "3095a349d245708c7cf550118703d7302c27b60af5d4e67fc978f8a4e60953c7a04f92fcf41aee64321ccb707a895851552b1e37b00bc5e6b72fa5bcef9e3fff" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "07262d738b09321f4dbccec4bb26f48cb0f0ed246ce0b31b9a6e7bc683049f1f3e5545f28ce932dd985c5ab0f43bd6de0770560af329065ed2e49d34624c2cbb" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "b6405eca8ee3316c87061cc6ec18dba53e6c250c63ba1f3bae9e55dd3498036af08cd272aa24d713c6020d77ab2f3919af1a32f307420618ab97e73953994fb4" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9ca", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "7ee682f63148ee45f6e5315da81e5c6e557c2c34641fc509c7a5701088c38a74756168e2cd8d351e88fd1a451f360a01f5b2580f9b5a2e8cfc138f3dd59a3ffc" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacb", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "1d263c179d6b268f6fa016f3a4f29e943891125ed8593c81256059f5a7b44af2dcb2030d175c00e62ecaf7ee96682aa07ab20a611024a28532b1c25b86657902" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcc", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "106d132cbdb4cd2597812846e2bc1bf732fec5f0a5f65dbb39ec4e6dc64ab2ce6d24630d0f15a805c3540025d84afa98e36703c3dbee713e72dde8465bc1be7e" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccd", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "0e79968226650667a8d862ea8da4891af56a4e3a8b6d1750e394f0dea76d640d85077bcec2cc86886e506751b4f6a5838f7f0b5fef765d9dc90dcdcbaf079f08" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdce", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "521156a82ab0c4e566e5844d5e31ad9aaf144bbd5a464fdca34dbd5717e8ff711d3ffebbfa085d67fe996a34f6d3e4e60b1396bf4b1610c263bdbb834d560816" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecf", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "1aba88befc55bc25efbce02db8b9933e46f57661baeabeb21cc2574d2a518a3cba5dc5a38e49713440b25f9c744e75f6b85c9d8f4681f676160f6105357b8406" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "5a9949fcb2c473cda968ac1b5d08566dc2d816d960f57e63b898fa701cf8ebd3f59b124d95bfbbedc5f1cf0e17d5eaed0c02c50b69d8a402cabcca4433b51fd4" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "b0cead09807c672af2eb2b0f06dde46cf5370e15a4096b1a7d7cbb36ec31c205fbefca00b7a4162fa89fb4fb3eb78d79770c23f44e7206664ce3cd931c291e5d" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "bb6664931ec97044e45b2ae420ae1c551a8874bc937d08e969399c3964ebdba8346cdd5d09caafe4c28ba7ec788191ceca65ddd6f95f18583e040d0f30d0364d" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "65bc770a5faa3792369803683e844b0be7ee96f29f6d6a35568006bd5590f9a4ef639b7a8061c7b0424b66b60ac34af3119905f33a9d8c3ae18382ca9b689900" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "ea9b4dca333336aaf839a45c6eaa48b8cb4c7ddabffea4f643d6357ea6628a480a5b45f2b052c1b07d1fedca918b6f1139d80f74c24510dcbaa4be70eacc1b06" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "e6342fb4a780ad975d0e24bce149989b91d360557e87994f6b457b895575cc02d0c15bad3ce7577f4c63927ff13f3e381ff7e72bdbe745324844a9d27e3f1c01" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "3e209c9b33e8e461178ab46b1c64b49a07fb745f1c8bc95fbfb94c6b87c69516651b264ef980937fad41238b91ddc011a5dd777c7efd4494b4b6ecd3a9c22ac0" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "fd6a3d5b1875d80486d6e69694a56dbb04a99a4d051f15db2689776ba1c4882e6d462a603b7015dc9f4b7450f05394303b8652cfb404a266962c41bae6e18a94" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "951e27517e6bad9e4195fc8671dee3e7e9be69cee1422cb9fecfce0dba875f7b310b93ee3a3d558f941f635f668ff832d2c1d033c5e2f0997e4c66f147344e02" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "8eba2f874f1ae84041903c7c4253c82292530fc8509550bfdc34c95c7e2889d5650b0ad8cb988e5c4894cb87fbfbb19612ea93ccc4c5cad17158b9763464b492" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9da", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "16f712eaa1b7c6354719a8e7dbdfaf55e4063a4d277d947550019b38dfb564830911057d50506136e2394c3b28945cc964967d54e3000c2181626cfb9b73efd2" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadb", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c39639e7d5c7fb8cdd0fd3e6a52096039437122f21c78f1679cea9d78a734c56ecbeb28654b4f18e342c331f6f7229ec4b4bc281b2d80a6eb50043f31796c88c" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdc", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "72d081af99f8a173dcc9a0ac4eb3557405639a29084b54a40172912a2f8a395129d5536f0918e902f9e8fa6000995f4168ddc5f893011be6a0dbc9b8a1a3f5bb" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdd", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c11aa81e5efd24d5fc27ee586cfd8847fbb0e27601ccece5ecca0198e3c7765393bb74457c7e7a27eb9170350e1fb53857177506be3e762cc0f14d8c3afe9077" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcddde", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c28f2150b452e6c0c424bcde6f8d72007f9310fed7f2f87de0dbb64f4479d6c1441ba66f44b2accee61609177ed340128b407ecec7c64bbe50d63d22d8627727" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedf", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "f63d88122877ec30b8c8b00d22e89000a966426112bd44166e2f525b769ccbe9b286d437a0129130dde1a86c43e04bedb594e671d98283afe64ce331de9828fd" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "348b0532880b88a6614a8d7408c3f913357fbb60e995c60205be9139e74998aede7f4581e42f6b52698f7fa1219708c14498067fd1e09502de83a77dd281150c" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "5133dc8bef725359dff59792d85eaf75b7e1dcd1978b01c35b1b85fcebc63388ad99a17b6346a217dc1a9622ebd122ecf6913c4d31a6b52a695b86af00d741a0" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "2753c4c0e98ecad806e88780ec27fccd0f5c1ab547f9e4bf1659d192c23aa2cc971b58b6802580baef8adc3b776ef7086b2545c2987f348ee3719cdef258c403" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "b1663573ce4b9d8caefc865012f3e39714b9898a5da6ce17c25a6a47931a9ddb9bbe98adaa553beed436e89578455416c2a52a525cf2862b8d1d49a2531b7391" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "64f58bd6bfc856f5e873b2a2956ea0eda0d6db0da39c8c7fc67c9f9feefcff3072cdf9e6ea37f69a44f0c61aa0da3693c2db5b54960c0281a088151db42b11e8" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "0764c7be28125d9065c4b98a69d60aede703547c66a12e17e1c618994132f5ef82482c1e3fe3146cc65376cc109f0138ed9a80e49f1f3c7d610d2f2432f20605" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "f748784398a2ff03ebeb07e155e66116a839741a336e32da71ec696001f0ad1b25cd48c69cfca7265eca1dd71904a0ce748ac4124f3571076dfa7116a9cf00e9" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "3f0dbc0186bceb6b785ba78d2a2a013c910be157bdaffae81bb6663b1a73722f7f1228795f3ecada87cf6ef0078474af73f31eca0cc200ed975b6893f761cb6d" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "d4762cd4599876ca75b2b8fe249944dbd27ace741fdab93616cbc6e425460feb51d4e7adcc38180e7fc47c89024a7f56191adb878dfde4ead62223f5a2610efe" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "cd36b3d5b4c91b90fcbba79513cfee1907d8645a162afd0cd4cf4192d4a5f4c892183a8eacdb2b6b6a9d9aa8c11ac1b261b380dbee24ca468f1bfd043c58eefe" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9ea", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "98593452281661a53c48a9d8cd790826c1a1ce567738053d0bee4a91a3d5bd92eefdbabebe3204f2031ca5f781bda99ef5d8ae56e5b04a9e1ecd21b0eb05d3e1" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaeb", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "771f57dd2775ccdab55921d3e8e30ccf484d61fe1c1b9c2ae819d0fb2a12fab9be70c4a7a138da84e8280435daade5bbe66af0836a154f817fb17f3397e725a3" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebec", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "c60897c6f828e21f16fbb5f15b323f87b6c8955eabf1d38061f707f608abdd993fac3070633e286cf8339ce295dd352df4b4b40b2f29da1dd50b3a05d079e6bb" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebeced", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "8210cd2c2d3b135c2cf07fa0d1433cd771f325d075c6469d9c7f1ba0943cd4ab09808cabf4acb9ce5bb88b498929b4b847f681ad2c490d042db2aec94214b06b" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedee", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "1d4edfffd8fd80f7e4107840fa3aa31e32598491e4af7013c197a65b7f36dd3ac4b478456111cd4309d9243510782fa31b7c4c95fa951520d020eb7e5c36e4ef" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeef", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "af8e6e91fab46ce4873e1a50a8ef448cc29121f7f74deef34a71ef89cc00d9274bc6c2454bbb3230d8b2ec94c62b1dec85f3593bfa30ea6f7a44d7c09465a253" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "29fd384ed4906f2d13aa9fe7af905990938bed807f1832454a372ab412eea1f5625a1fcc9ac8343b7c67c5aba6e0b1cc4644654913692c6b39eb9187ceacd3ec" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "a268c7885d9874a51c44dffed8ea53e94f78456e0b2ed99ff5a3924760813826d960a15edbedbb5de5226ba4b074e71b05c55b9756bb79e55c02754c2c7b6c8a" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "0cf8545488d56a86817cd7ecb10f7116b7ea530a45b6ea497b6c72c997e09e3d0da8698f46bb006fc977c2cd3d1177463ac9057fdd1662c85d0c126443c10473" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "b39614268fdd8781515e2cfebf89b4d5402bab10c226e6344e6b9ae000fb0d6c79cb2f3ec80e80eaeb1980d2f8698916bd2e9f747236655116649cd3ca23a837" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "74bef092fc6f1e5dba3663a3fb003b2a5ba257496536d99f62b9d73f8f9eb3ce9ff3eec709eb883655ec9eb896b9128f2afc89cf7d1ab58a72f4a3bf034d2b4a" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "3a988d38d75611f3ef38b8774980b33e573b6c57bee0469ba5eed9b44f29945e7347967fba2c162e1c3be7f310f2f75ee2381e7bfd6b3f0baea8d95dfb1dafb1" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "58aedfce6f67ddc85a28c992f1c0bd0969f041e66f1ee88020a125cbfcfebcd61709c9c4eba192c15e69f020d462486019fa8dea0cd7a42921a19d2fe546d43d" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "9347bd291473e6b4e368437b8e561e065f649a6d8ada479ad09b1999a8f26b91cf6120fd3bfe014e83f23acfa4c0ad7b3712b2c3c0733270663112ccd9285cd9" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "b32163e7c5dbb5f51fdc11d2eac875efbbcb7e7699090a7e7ff8a8d50795af5d74d9ff98543ef8cdf89ac13d0485278756e0ef00c817745661e1d59fe38e7537" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "1085d78307b1c4b008c57a2e7e5b234658a0a82e4ff1e4aaac72b312fda0fe27d233bc5b10e9cc17fdc7697b540c7d95eb215a19a1a0e20e1abfa126efd568c7" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fa", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "4e5c734c7dde011d83eac2b7347b373594f92d7091b9ca34cb9c6f39bdf5a8d2f134379e16d822f6522170ccf2ddd55c84b9e6c64fc927ac4cf8dfb2a17701f2" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafb", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "695d83bd990a1117b3d0ce06cc888027d12a054c2677fd82f0d4fbfc93575523e7991a5e35a3752e9b70ce62992e268a877744cdd435f5f130869c9a2074b338" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfc", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "a6213743568e3b3158b9184301f3690847554c68457cb40fc9a4b8cfd8d4a118c301a07737aeda0f929c68913c5f51c80394f53bff1c3e83b2e40ca97eba9e15" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfd", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "d444bfa2362a96df213d070e33fa841f51334e4e76866b8139e8af3bb3398be2dfaddcbc56b9146de9f68118dc5829e74b0c28d7711907b121f9161cb92b69a9" + }, + { + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfe", + "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f", + "142709d62e28fcccd0af97fad0f8465b971e82201dc51070faa0372aa43e92484be1c1e73ba10906d5d1853db6a4106e0a7bf9800d373d6dee2d46d62ef2a461" + } +}; + +static int +tv(void) +{ + unsigned char *expected_out; + unsigned char *in; + unsigned char *key; + unsigned char *out; + size_t i = 0U; + size_t in_len; + + key = (unsigned char *) sodium_malloc(crypto_generichash_KEYBYTES_MAX); + out = (unsigned char *) sodium_malloc(crypto_generichash_BYTES_MAX); + expected_out = (unsigned char *) sodium_malloc(crypto_generichash_BYTES_MAX); + do { + assert(strlen(tests[i].key_hex) == 2 * crypto_generichash_KEYBYTES_MAX); + sodium_hex2bin(key, crypto_generichash_KEYBYTES_MAX, + tests[i].key_hex, strlen(tests[i].key_hex), + NULL, NULL, NULL); + assert(strlen(tests[i].out_hex) == 2 * crypto_generichash_BYTES_MAX); + sodium_hex2bin(expected_out, crypto_generichash_BYTES_MAX, + tests[i].out_hex, strlen(tests[i].out_hex), + NULL, NULL, NULL); + in_len = strlen(tests[i].in_hex) / 2; + in = (unsigned char *) sodium_malloc(in_len); + sodium_hex2bin(in, in_len, tests[i].in_hex, strlen(tests[i].in_hex), + NULL, NULL, NULL); + crypto_generichash(out, crypto_generichash_BYTES_MAX, + in, (unsigned long long) in_len, + key, crypto_generichash_KEYBYTES_MAX); + if (memcmp(out, expected_out, crypto_generichash_BYTES_MAX) != 0) { + printf("Test vector #%u failed\n", (unsigned int) i); + } + sodium_free(in); + } while (++i < (sizeof tests) / (sizeof tests[0])); + sodium_free(key); + sodium_free(out); + sodium_free(expected_out); + + return 0; +} + +int +main(void) +{ + unsigned char in[MAXLEN]; + unsigned char out[crypto_generichash_BYTES_MAX]; + unsigned char k[crypto_generichash_KEYBYTES_MAX]; + size_t h; + size_t i; + size_t j; + + tv(); + + for (h = 0; h < crypto_generichash_KEYBYTES_MAX; ++h) { + k[h] = (unsigned char) h; + } + + for (i = 0; i < MAXLEN; ++i) { + in[i] = (unsigned char) i; + crypto_generichash(out, 1 + i % crypto_generichash_BYTES_MAX, in, + (unsigned long long) i, k, + 1 + i % crypto_generichash_KEYBYTES_MAX); + for (j = 0; j < 1 + i % crypto_generichash_BYTES_MAX; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + } + + memset(out, 0, sizeof out); + crypto_generichash(out, crypto_generichash_BYTES_MAX, in, + (unsigned long long) i, k, 0U); + for (j = 0; j < crypto_generichash_BYTES_MAX; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + + assert(crypto_generichash(guard_page, 0, + in, (unsigned long long) sizeof in, + k, sizeof k) == -1); + assert(crypto_generichash(guard_page, crypto_generichash_BYTES_MAX + 1, + in, (unsigned long long) sizeof in, + k, sizeof k) == -1); + assert(crypto_generichash(guard_page, (unsigned long long) sizeof in, + in, (unsigned long long) sizeof in, + k, crypto_generichash_KEYBYTES_MAX + 1) == -1); + + assert(crypto_generichash_bytes_min() > 0U); + assert(crypto_generichash_bytes_max() > 0U); + assert(crypto_generichash_bytes() > 0U); + assert(crypto_generichash_bytes() >= crypto_generichash_bytes_min()); + assert(crypto_generichash_bytes() <= crypto_generichash_bytes_max()); + assert(crypto_generichash_keybytes_min() > 0U); + assert(crypto_generichash_keybytes_max() > 0U); + assert(crypto_generichash_keybytes() > 0U); + assert(crypto_generichash_keybytes() >= crypto_generichash_keybytes_min()); + assert(crypto_generichash_keybytes() <= crypto_generichash_keybytes_max()); + assert(strcmp(crypto_generichash_primitive(), "blake2b") == 0); + assert(crypto_generichash_bytes_min() + == crypto_generichash_blake2b_bytes_min()); + assert(crypto_generichash_bytes_max() + == crypto_generichash_blake2b_bytes_max()); + assert(crypto_generichash_bytes() == crypto_generichash_blake2b_bytes()); + assert(crypto_generichash_keybytes_min() + == crypto_generichash_blake2b_keybytes_min()); + assert(crypto_generichash_keybytes_max() + == crypto_generichash_blake2b_keybytes_max()); + assert(crypto_generichash_keybytes() + == crypto_generichash_blake2b_keybytes()); + assert(crypto_generichash_blake2b_saltbytes() > 0U); + assert(crypto_generichash_blake2b_personalbytes() > 0U); + + return 0; +} diff --git a/external/src/libsodium/test/default/generichash.exp b/external/src/libsodium/test/default/generichash.exp new file mode 100644 index 0000000..ac46f32 --- /dev/null +++ b/external/src/libsodium/test/default/generichash.exp @@ -0,0 +1,65 @@ +05 +5d8c +22221b +d4974470 +be8492fb36 +edc178279907 +26848f2ae0c2e6 +045cf1235112b9f6 +5110bad569356dfa6c +1339d95145bc8a33d3aa +3dbb39b4d57c5566808a88 +22378260939cee01022686a2 +e18b37abcead6cc520e6504dac +3cbb356604cf862e62ad2f534323 +44c41ba227b191961b475ec5875057 +0c7c9c3922d41a7b2b3b20f92685d560 +8508c01d19709bdd881866aa1f8c63ca06 +f6b2dddfbece6d7d52e114c7e5a97772e18d +d36b5af9591d0cd3747254e26bc6e1de5b6081 +f7f7ce69149418d7ec33327bd86e14bcca4b8ed7 +2c9aba9a56de21165753c4f3cee9310a9c8fe546b9 +ee5e08cee5fbbcb51900341bb30db6695920faecda6a +fe9ffb56dc5716b91bc7d77ce7b05e7cc39c31683bec91 +c500ae0f5bff0f1106ce104ae9c291add7207e0d8ebcb1ed +68e23d12000b387158afd6458d3bcef9c26936ca68b5c0f3d6 +220efa2c09f67dbb02aa623bbc0cb92107a30f53b633e78d4b44 +54df984b47e4bcd489d9c045c488743fac91c9b3e0cbcc37495fac +b4852cf66c6ce164c002bbb62ded0faeb4a39c39fdffb372ff14dd31 +d79cafb5565e7775616e1c9b09100d61fb71efaf25affcf2d480d2c980 +ae557883145e374adef583ba0550429d5cdd86b254c33bf52d02e070efda +9f53d28c0df7b327c2eb4c8a12c742829225b7f30fda7baf64135098fdb01b +a9f51bb7f6a3e9cdb96ce652c07d177962a348a9cced1b92f948187e59b44463 +f2960cf5fd57fc92f549cd5a2803147964f60e7703e1b8897c088cded74c7bd39f +89981acbb690eb03ed2a67510d1d85a1b4f9d496fdfe134550ae14146bb05fd5fedd +6d8245383fd7c418b46511339e711b9d4a0d1f5fdf6de45fdd3d0664164b7bf878a124 +1f0b6b083d524e0741710ddef499ce88f51083bb3ad80a1815cc57acf006436e9b6ad72b +fc35bfe34c915020bb8b44fa0a19933774eaaf61919780fd55564e085bc31646dfc1d426e9 +117d58f1f8cb2c036102686035975be90550795e5a0e3469a8f7a2cba9bc88961852b18c8ae3 +c679c950818729c799bb7f39cef2d89fa80a147817f379a073ef1ccafea5d369815c70373bf5be +d487ad2143024ee8c645a066c035b74abe3a11f1c9fcd738b154b8ca37134d74fb78c40d1a2274cf +2d3ee00828b0ccea6812b40f214fab6d4f23f7e74ae228115bcb208ced2d5e1cb9cdff41de912af7a8 +a697b26d4c4475e312288b98ae2ec4954d3c74c8e144c0ab518616ff9f52918a946fd765af75e761178c +f647bcba2a711f431d6d453aa7d75dcf5bb9ab6f8b83f89117230f633e7580f27c71c4f4c211cadd04f587 +1fc1d6a4db753e2f4fd1456b2b709dd70ad58547eeda9d5a55762b5cd4097a7a1bd73cc633ec27168ee65631 +1cfe0f63ab155379b4a1b5bf694a33635097b8e4b6dbd3b983d62454d36d7bf4550bece301abdd27b2dd76ca9f +73dee8a0a558e7b6f6eefe411280e253b05ef006d499849fea5d6a95f9141ee160322fff3a3f70e10c84025e02ce +edf9e706f4acae4f4bed72404f14458ba075d2b9d9a4a1ed46d1f1c5e23113a74cce9f7735432a922a3d8097f22c7a +95d5cd54c6722ac4335fa0ab38d388c9fd0baea48a9078605e400534ef38f13abb1d770da84b90b0256e1c1b64f54ba9 +fe6b85ee8b5eb7da035264ed46e6dcd948571018d1f6976de4102fcb4bb5f1422e7df1b5aaa5b6b56c5961966db29ead6e +499ab83c01e4bf74ea5036392f9f810eae8a066fff49e316e4288baccb2001efa24f64cef7bfae70c90f139b198e53ad87f1 +eac6c9d97264241a8adba22ee925438ed9787a547018608a10676a7594bc51c60294bd9159fbcada9022b44880a37c5b07c1b4 +0771e3ae24bbfe424800d4bae776fef3da1607990019e7c4b30bc8140061ebf0b64aad7b018a878d579caa67154b98a04402735e +d569e5f5fe197387451441911a2be2effa606dad39820af44cea056bd9d1499dde41fa1c6c3a0459d5866c944bec2ac83328953726 +68e523ded865c4d8318d61c312189a59597bbc3995e312e85137611af761a5f73508ac79e359edf729d4508830fc642b432f09185914 +601af664ae596166707244adbb4f704593b355c6a659c844d853c6647fb265cdbcea26ed43657251dec37f2d6453fa0ace55f22d303cb0 +703d8e552236b2090143444545f0a61a809d8ef9843bcf6883f61671fb31c8d6ac9fd373e7f9f79a0c72fa6a37dc655ba1fb01a5f41e36d1 +03896f594afd1bf97acb862106eb05a1d8b54ec08d184812a79f4dc7b287a7486e60927b6c23e5f51fcbc94798648b28fd13438300567bec95 +cc66a891768e95a2717b040c111996f14942f10f2475c33aa5f1c97476e6f8386733d6b21c16102d01ff1f715475f01099e1f19aa763238a38a9 +007aac8eae29e5bf2be1b54857f5fe80c324424a3273b46e55482fbc4ae1033df4a97016b60c81a5344abd6366f56d8cee2c2e94619418293990de +50c81e92605a6111ea4c7c602acfb3945d4c2631c8c08fa4b594134577f5c2ffcca90d48604162cfdb2a0bb40416ff9134a275461b829ff1b875f995 +661b7a1c70170aa7559aa82639fa65c1bdcfb5e336cb23b40a9edf5b4f6eeca1a176a9844da705cafb990dd94b9dc6194eb6b2de3eca9dbd255bb267a1 +9ff11c233aaf5e0242b0dbe6e110a42e58b86141ad0ef130fd2bb895700019782de66d435bf0a8d6f5eda5d7d1105e7a6f3ef17a9da8f9c16fc21075431a +bdd3d0fafe8ba2b29d1ac0b79aa46e249cc9d3a82d0f772d690637bbdd353722356658d00436ff5dd5239ab747979329345eb8c7ed11b7331456ae87350fcf +bd965bf31e87d70327536f2a341cebc4768eca275fa05ef98f7f1b71a0351298de006fba73fe6733ed01d75801b4a928e54231b38e38c562b2e33ea1284992fa +2fc6e69fa26a89a5ed269092cb9b2a449a4409a7a44011eecad13d7c4b0456602d402fa5844f1a7a758136ce3d5d8d0e8b86921ffff4f692dd95bdc8e5ff0052 diff --git a/external/src/libsodium/test/default/generichash2.c b/external/src/libsodium/test/default/generichash2.c new file mode 100644 index 0000000..b7e33e6 --- /dev/null +++ b/external/src/libsodium/test/default/generichash2.c @@ -0,0 +1,62 @@ + +#define TEST_NAME "generichash2" +#include "cmptest.h" + +int +main(void) +{ +#define MAXLEN 64 + crypto_generichash_state *st; + unsigned char in[MAXLEN]; + unsigned char out[crypto_generichash_BYTES_MAX]; + unsigned char k[crypto_generichash_KEYBYTES_MAX]; + size_t h, i, j; + + assert(crypto_generichash_statebytes() >= sizeof *st); + st = (crypto_generichash_state *) + sodium_malloc(crypto_generichash_statebytes()); + for (h = 0; h < crypto_generichash_KEYBYTES_MAX; ++h) { + k[h] = (unsigned char) h; + } + for (i = 0; i < MAXLEN; ++i) { + in[i] = (unsigned char) i; + if (crypto_generichash_init(st, k, + 1 + i % crypto_generichash_KEYBYTES_MAX, + 1 + i % crypto_generichash_BYTES_MAX) != 0) { + printf("crypto_generichash_init()\n"); + return 1; + } + crypto_generichash_update(st, in, i); + crypto_generichash_update(st, in, i); + crypto_generichash_update(st, in, i); + if (crypto_generichash_final(st, out, + 1 + i % crypto_generichash_BYTES_MAX) != 0) { + printf("crypto_generichash_final() should have returned 0\n"); + } + for (j = 0; j < 1 + i % crypto_generichash_BYTES_MAX; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + if (crypto_generichash_final(st, out, + 1 + i % crypto_generichash_BYTES_MAX) != -1) { + printf("crypto_generichash_final() should have returned -1\n"); + } + } + + assert(crypto_generichash_init(st, k, sizeof k, 0U) == -1); + assert(crypto_generichash_init(st, k, sizeof k, + crypto_generichash_BYTES_MAX + 1U) == -1); + assert(crypto_generichash_init(st, k, crypto_generichash_KEYBYTES_MAX + 1U, + sizeof out) == -1); + assert(crypto_generichash_init(st, k, 0U, sizeof out) == 0); + assert(crypto_generichash_init(st, k, 1U, sizeof out) == 0); + assert(crypto_generichash_init(st, NULL, 1U, 0U) == -1); + assert(crypto_generichash_init(st, NULL, crypto_generichash_KEYBYTES, + 1U) == 0); + assert(crypto_generichash_init(st, NULL, crypto_generichash_KEYBYTES, + 0U) == -1); + + sodium_free(st); + + return 0; +} diff --git a/external/src/libsodium/test/default/generichash2.exp b/external/src/libsodium/test/default/generichash2.exp new file mode 100644 index 0000000..5ee6f60 --- /dev/null +++ b/external/src/libsodium/test/default/generichash2.exp @@ -0,0 +1,64 @@ +05 +22a8 +287a9d +d8eeab1c +d4ce34973f +584f7ac46f0c +32c848bb67545b +8438e21361bca125 +27a6faae998b4fabb4 +508c05a4f2daee150bad +68c886c97dce370e8c72fa +d41e90824ace31ba7bf512ac +6e0d7a1e2b92a68e45ea867895 +1fc5ee8715312db38da9066152a5 +3138504ba58fcd56c62752bc98a6d2 +b689ecd5357cb5276007627fbdf4082e +afe251881beb8b9dfa3d4f76aafc7b2995 +980eaa215cb0911027c5564db809bb8ac0a1 +56048436883efdfc8feaa239d960fa5ce24d42 +fce905b6d57fd841f58899a77887a4988e6aa2d1 +6f7afd81d24ccf4d98188b71bdbb7e6c637620879b +50406b4c37b48621505942b35dff30a75f7d2868146b +32c21792e18e7a79a4a20ef291721d7eab4e4cf99fbe79 +4b9d9ac5dbfb825acd87588667e6683e0fde4cdcd0a532f9 +2b55a3ebb461623e5de4fbacfb8b26819cfa8adeb094c8c13b +4c7d261780b25a864a008352ad64d1ae7fc21d608317813cf63f +f0ca06b8e12c48f1511d0991ba562f06dbe6ba6d5e18280224cc6a +838a5f7056bfbca65a245796dd3510cb07ff1614b44989d91ac650b2 +a58a8da276577160441f8b9e9c52a041b7caf7cd316acc506f620ab0e1 +e03940a7231049ff2b86c47a28e4951f105d2a3aa3421190fe0ed6aa4ad6 +a7af977c0b34294b1a03d0cc2dcf6eb72f9a32721c3f70128384aeb1f56047 +0e5625d74ada70b8a3b23ca76894e9a0f9dee88f5e3e370e27ad25061ea9dd6f +775fd9257b265997a16557a445985091798af60e68d06e3ae8e2e886d23ed12f6e +852e8d4208166a990e215ed06b86c708f491e014584ac9b08f97f24d9f08a84c8e83 +fbdca0db9a933fcffcce2ae694d7e16e7571b100564fcb3d69cec82ea42f254a493a32 +50530ae5eb9780f3fafc5d179f7b363a0d69314a8545d68588b5fec28c8e8d1a011857f6 +5eb71553ff1ac4aba3f84faeb70281c738e3428aae68edc9842ebf55ffd7184a015e323445 +39b279c6d9cca89f8052f953abf71041faf3491b2b965cef503d715e8bf339e02a58fd0e0fba +e315bef5f4918e881dc8d39d3c6b3948c2ea8e21ac00ee7c7ab875a53e194add0c3d9b8bcba5b2 +4e950f0e1da3111d054136fbdf10b4b88b20de6ad0c6bd5024a5e0a8b4cd7059685c0b663a00cbfa +b1ed8d99fd62a4f504ecdd58a01759a85932a7783f88f314cdca5019e05063dcc1fcb3c39b8c07758e +e4d78e734b0cb5bbd83e22bc67f97bbc8a3644f789f6c26a3ec2fe72c75b4d48a3bc000e6f2f2f0726fe +162e01beb796433a2771eab54611fc93677ed12c73a93ea4d75e148bec7ab14b3e31ab7f395456fb2b47ab +759c30631fd52e80a22f0614125dcd136287db65079908b75fb5b03be1cdf6dd0a1c9de0cc759cdd82c33758 +af2992acdaf0908f03a2025854de6446123c919b1e24db711df6cb070091343b4e6f5b2716c20c2547f50f1fde +b833064955778a611fe41a9f1a2de730a16fb4e61a7e2fb67425ce199101d4e71dd7b0c731ea4188e9cc30e9bc52 +e546ee327168d9b4e0d73d9a043f9ef03f880bc8aee91b0923704eb7361ac916b00f5c71c872e2f911a77ef76704b5 +83d86f056729fa1a6e1d3fe8c3d2ebe42b327025747f2e6ba923d2b7b893e31571839937222852033844e585b17d462f +5d70402524fbef569552a3ff6854087e090ff9ac9ea03aba92cf9f33a28845fa6a1631090dca10e05cdd3341b391a15fcf +64f4d3ebf0717900f7c04512d1e18f9985975991d4254d76c4e2ee02c0edd6f912f715991984731b808b8370be1f201e53bf +7d45eae6626dfc9ec3591764b8c39c72ca67e6c1893ab590963a75922719937d1d0ff188a510ffbdf9c777a4d565b3683cbf38 +68e007db5067874548c0d12a9ca709221f9bd352e3eb9847fde6c5de4a8550f4b85b67fe4e5aad70626ebb27d71e5b528effb2e6 +b0dc4dc0bd0d41a8ccfa45a127542079bc4e6f63a63863a9ce21f44481d23eff1060ea03851759b9317209405d5b7cc4387cc2759b +adf6a9df484e93eb3a6113c3fd68a49b2166878fc652833c9cbef3fd8dd281d385ad0374bc25bc865b216ca395e21c30b9eda1d58a8d +f1df9bc169323da338daa8a94867db96a1a2a6feb26569198fb4591ae602ba6f766a879e745d71e93b6cb8886b914f2bf4aa55d4c48045 +0c7446078a5077f33bba1ebfad60bbf1b1df47aab2eb3f3f3274ce56ead7800cf095af8208b6d570c4c832fe33227bbbc0842a13e1e82ad9 +accd0b4682e56698ecc55a60a8db8b3f950b6bffc5a1d160daf6ca25e13e3b4983ced5903df0bdc21f70c2ec5adb1a2ec9617df645cdd17ac9 +b787bae190ff2608eb383e0299cc10d6b7232de67ab74285e7bfa933d79f91226066537d74a9d40140d7b1683c2d42cd1935f6430cc554db2b69 +d09b717a0c80f581c07b8813e0ae79cec2188f77122f7477954610655a20420f13eb1b68cacde8c1fdf7a9a398efa72f40c85f0122812eaa33aba0 +87fff156d9895917468e92848fdcfacc134ca3bfc7fce484bd6db41c682ee2ee47151df0fa863d5641633d908c0328e6cbe080e80d8293530ffd2c4f +1b17b2c0e7afcd224ec9bbe9ce9a13a00bd0a336b863f1b4d5304043778244323bd23fb6154a2e1e94aa48f6ff0e12787a50ca09e9e72ece9e038f6218 +23ac1ccd5e7df51b65b284650158d662e7ef51ebae01b879f39cec484b688c792f8e854bd8ca31ffe8796d28f10e49ab402dab47878a21cb95556dc32b0a +f8f5323ebcc28bf927e72d342b5b70d80ba67794afb4c28debad21b0dae24c7a9252e862eb4b83bea6d9c0bb7c108983c987f13d73f250c7f14483f0454a24 +55b97ca594d68ccf69a0a93fe7fa4004c7e2947a8cac4ca4a44e17ac6876f472e3f221b341a28004cd35a79cfad7fabb9378ce5af03e4c0445ebbe9540943bbd diff --git a/external/src/libsodium/test/default/generichash3.c b/external/src/libsodium/test/default/generichash3.c new file mode 100644 index 0000000..ec86b35 --- /dev/null +++ b/external/src/libsodium/test/default/generichash3.c @@ -0,0 +1,176 @@ + +#define TEST_NAME "generichash3" +#include "cmptest.h" + +int +main(void) +{ +#define MAXLEN 64 + crypto_generichash_blake2b_state st; + unsigned char salt[crypto_generichash_blake2b_SALTBYTES] + = { '5', 'b', '6', 'b', '4', '1', 'e', 'd', + '9', 'b', '3', '4', '3', 'f', 'e', '0' }; + unsigned char personal[crypto_generichash_blake2b_PERSONALBYTES] + = { '5', '1', '2', '6', 'f', 'b', '2', 'a', + '3', '7', '4', '0', '0', 'd', '2', 'a' }; + unsigned char in[MAXLEN]; + unsigned char out[crypto_generichash_blake2b_BYTES_MAX]; + unsigned char k[crypto_generichash_blake2b_KEYBYTES_MAX]; + size_t h; + size_t i; + size_t j; + + assert(crypto_generichash_blake2b_statebytes() >= sizeof st); + for (h = 0; h < crypto_generichash_blake2b_KEYBYTES_MAX; ++h) { + k[h] = (unsigned char) h; + } + + for (i = 0; i < MAXLEN; ++i) { + in[i] = (unsigned char) i; + crypto_generichash_blake2b_init_salt_personal( + &st, k, 1 + i % crypto_generichash_blake2b_KEYBYTES_MAX, + 1 + i % crypto_generichash_blake2b_BYTES_MAX, salt, personal); + crypto_generichash_blake2b_update(&st, in, (unsigned long long) i); + crypto_generichash_blake2b_final( + &st, out, 1 + i % crypto_generichash_blake2b_BYTES_MAX); + for (j = 0; j < 1 + i % crypto_generichash_blake2b_BYTES_MAX; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + } + + memset(out, 0, sizeof out); + crypto_generichash_blake2b_init_salt_personal( + &st, k, 0U, crypto_generichash_blake2b_BYTES_MAX, salt, personal); + crypto_generichash_blake2b_update(&st, in, MAXLEN); + crypto_generichash_blake2b_final(&st, out, + crypto_generichash_blake2b_BYTES_MAX); + for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + + memset(out, 0, sizeof out); + crypto_generichash_blake2b_init_salt_personal( + &st, NULL, 1U, crypto_generichash_blake2b_BYTES_MAX, salt, personal); + crypto_generichash_blake2b_update(&st, in, MAXLEN); + crypto_generichash_blake2b_final(&st, out, + crypto_generichash_blake2b_BYTES_MAX); + for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + + memset(out, 0, sizeof out); + crypto_generichash_blake2b_init_salt_personal( + &st, k, crypto_generichash_blake2b_KEYBYTES_MAX, + crypto_generichash_blake2b_BYTES_MAX, NULL, personal); + crypto_generichash_blake2b_update(&st, in, MAXLEN); + crypto_generichash_blake2b_final(&st, out, + crypto_generichash_blake2b_BYTES_MAX); + for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + + memset(out, 0, sizeof out); + crypto_generichash_blake2b_init_salt_personal( + &st, k, crypto_generichash_blake2b_KEYBYTES_MAX, + crypto_generichash_blake2b_BYTES_MAX, salt, NULL); + crypto_generichash_blake2b_update(&st, in, MAXLEN); + crypto_generichash_blake2b_final( + &st, out, crypto_generichash_blake2b_BYTES_MAX); + for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + + memset(out, 0, sizeof out); + crypto_generichash_blake2b_salt_personal( + out, crypto_generichash_blake2b_BYTES_MAX, in, MAXLEN, + k, 0U, salt, personal); + for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + + memset(out, 0, sizeof out); + crypto_generichash_blake2b_salt_personal( + out, crypto_generichash_blake2b_BYTES_MAX, in, MAXLEN, + NULL, 0U, salt, personal); + for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + + memset(out, 0, sizeof out); + crypto_generichash_blake2b_salt_personal( + out, crypto_generichash_blake2b_BYTES_MAX, in, MAXLEN, + k, crypto_generichash_blake2b_KEYBYTES_MAX, salt, personal); + for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + + memset(out, 0, sizeof out); + crypto_generichash_blake2b_salt_personal( + out, crypto_generichash_blake2b_BYTES_MAX, in, MAXLEN, + k, crypto_generichash_blake2b_KEYBYTES_MAX, NULL, personal); + for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + + memset(out, 0, sizeof out); + crypto_generichash_blake2b_salt_personal( + out, crypto_generichash_blake2b_BYTES_MAX, in, MAXLEN, + k, crypto_generichash_blake2b_KEYBYTES_MAX, salt, NULL); + for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + + assert(crypto_generichash_blake2b_salt_personal + (guard_page, 0, + in, (unsigned long long) sizeof in, + k, sizeof k, NULL, NULL) == -1); + assert(crypto_generichash_blake2b_salt_personal + (guard_page, crypto_generichash_BYTES_MAX + 1, + in, (unsigned long long) sizeof in, + k, sizeof k, NULL, NULL) == -1); + assert(crypto_generichash_blake2b_salt_personal + (guard_page, (unsigned long long) sizeof in, + in, (unsigned long long) sizeof in, + k, crypto_generichash_KEYBYTES_MAX + 1, NULL, NULL) == -1); + + crypto_generichash_blake2b_init_salt_personal(&st, NULL, 0U, crypto_generichash_BYTES, + NULL, personal); + crypto_generichash_blake2b_update(&st, in, MAXLEN); + crypto_generichash_blake2b_final(&st, out, crypto_generichash_blake2b_BYTES_MAX); + for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + + crypto_generichash_blake2b_init_salt_personal(&st, NULL, 0U, crypto_generichash_BYTES, + salt, NULL); + crypto_generichash_blake2b_update(&st, in, MAXLEN); + crypto_generichash_blake2b_final(&st, out, crypto_generichash_blake2b_BYTES_MAX); + for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + + assert(crypto_generichash_blake2b_init_salt_personal + (&st, k, sizeof k, 0, NULL, NULL) == -1); + assert(crypto_generichash_blake2b_init_salt_personal + (&st, k, sizeof k, crypto_generichash_blake2b_BYTES_MAX + 1, NULL, NULL) == -1); + assert(crypto_generichash_blake2b_init_salt_personal + (&st, k, crypto_generichash_blake2b_KEYBYTES_MAX + 1, sizeof out, NULL, NULL) == -1); + + assert(crypto_generichash_blake2b_init_salt_personal(&st, k, sizeof k, crypto_generichash_BYTES, + NULL, personal) == 0); + assert(crypto_generichash_blake2b_init_salt_personal(&st, k, sizeof k, crypto_generichash_BYTES, + salt, NULL) == 0); + return 0; +} diff --git a/external/src/libsodium/test/default/generichash3.exp b/external/src/libsodium/test/default/generichash3.exp new file mode 100644 index 0000000..75a62d4 --- /dev/null +++ b/external/src/libsodium/test/default/generichash3.exp @@ -0,0 +1,75 @@ +ba +6139 +3a1666 +5797e9d0 +834a26efe6 +d7e9e862bbce +40d8b84c374750 +276789189244cf04 +16f73ffe0673cc9992 +b3835bfaf6eb71d94078 +8c624e844d34f4a59f34cc +e0a394962413ad09975df3cf +47f043c3aacb501f97e0458ae3 +b4a11f2fb72a7e6f96fdacf98d49 +f434079e9adeb244047cb6855f9854 +5fbe885c4b2d4e0d78dc5905622a277a +e262ba3e2ab76efdf83513108e3b987d1b +add93dde78d32e77bc039c34a49043f19d26 +093842ac10e2eb1237ddc9ca9e7990cf397772 +09e7f6a0e2ea4888f1dbf6562effd1561c65029c +bd33a9ec914f5b81864a49184338e4062d6c6b2b2e +8dc46295235d94f5881d429a5ad47f9db9e35cf8c6b3 +ba5df554dca7ac1cba4889fa88adf3070fbf4ab5d187b5 +1ff84715e71c66214d271d421395fb6166db97b1d47ed697 +75a0d227c70549f5b0c933b7b21f151355bd47e04b6085c91f +a32a5c9439a0fa771dcbe7f338b5dcef62a754edc4952614d6f0 +53a87de519cdcc7f64730d58bce6baaf7b44c5c428a4611a208ad4 +5e5ad8f0c4f083f9b7a5154d9c0dfd0f3d2fce94cf54fc215450314a +9c76b9e63c77e6564b1e5111c2fb140046e1e5a4f900a7cfc2bac3fcfa +bb919251ca310eb9b994e5d7883bc9fa2144b59b8d5d940677b7130ac777 +faa492a66f08ef0c7adb868fcb7b523aedd35b8ff1414bd1d554794f144474 +9b273ebe335540b87be899abe169389ed61ed262c3a0a16e4998bbf752f0bee3 +1e0070b92429c151b33bdd1bb4430a0e650a3dfc94d404054e93c8568330ecc505 +e3b64149f1b76231686d592d1d4af984ce2826ba03c2224a92f95f9526130ce4eb40 +5f8e378120b73db9eefa65ddcdcdcb4acd8046c31a5e47f298caa400937d5623f1394b +74c757a4165a1782c933e587353a9fd8f6d7bf26b7f51b52c542747030bfb3d560c2e5c2 +2d5ee85cc238b923806dd98db18919d1924f2340ec88917d4ce1799cbfd5f2cb9df99db2e1 +c93ff727e6f9822efec0a77eed0025c0eff19127bf8746b7c71c2a098f57cef02febb86a1e6c +adfb6d7ba13779a5dd1bbf268e400f4156f0f5c9d5b670ff539e1d9c1a63373416f3001f338407 +3a6900e58a448887d77c5911e4bdde620e64f25b2d71723fa60f7cb3efa7c320b6153bdbc3287949 +413eb0fd379b32dd88e82242a87cc58ce3e64c72352387a4c70f92ee5c8d23fa7ecd86f6df170a32d2 +92d0d3cacc3e25628caf6f2c4cd50d25d154ac45098f531d690230b859f37cfe089eb169f76bba72a3ff +92f6ccc11a9a3bee520b17e0cddc4550c0e9cf47ddd9a6161284259ffb161c1d0675b505cb1066872768e8 +a3cd675804e6be7f120138a9eaadcd56bb7763d1c046e87fe0d358c8276b0d24621f46c60b46e397933b75b4 +304a1af53cbdd6486b8419d1ebd5e9528c540d8dc46a10be49067f46a0617229577015d776783f702b2954df43 +d8a6358970446453ac0c82c758644ab68989b5b4f06f9768807ce0c5f2a0dbac1e8450f4e3a02deecf7b54b6a45d +1264b8dee9ac4aa8de69a43ada95cc95f20230f33836d4a1db8c2466ab38361686e5ac282025ccc2e0f6a1cd98a4dd +7eed787abaa7f4e8b8aa3090f0676201cfbaaf350899661cdd5216ac0b5cd874443f5c0688ffd7ca1ccbfe1ca7e1a3f5 +8907f0218585167962a8e8213559a643dd03c2bf1a7a5ad3e3bc5f88c0ff1532ee8cd29880e7e0e68da22a5798aef27cc5 +12dea17b0733e5060751b1115e10c3d4b2f4583bcd009d9f1f42ec23d4a6a0df1185d3abbdbe86de08569e70583d6de1c1fe +8ff75e91f1de547dc3a25472db2f51f5910a290c449603da54207b5e39bd735d240ec913b52df90709b5d29357971d6c341452 +4a3b16b12400f38e74778efc3a4caa52ec6fdf6b0180a5bfac9189e52e162c10e8911a54ab33e2b389ee1949e58edaa119e2b2b9 +c9943e7186fdc9bbfa1d7087fa7086babe6fcf95a6196d1772187854071304e2f1fff39e6e6f48f76addb16d5c00249e0523aac91f +0297f16fdd34add9cc87b4adf816525b590ba08ac733c43f8d225d194df4f9c83b4dce617be51e25b5f6c80dff249f27c707de20e422 +576bb891eab9930998e2e73b5d0498e3c5f040f8dec9397a8c7a622c17de01fee7cc936e3bd4de1f7fd8b31dea9e70c65462bbb5dc7b50 +9416a57ae7c8c51c6e008f940fe06d8ebc02c350c19a2f71583a6d260b085670d73a95248fef0f4cae5292ba7db1189a7cd9c51122ba7913 +ea644b9051cca5eee8868a553e3f0f4e14739e1555474151156e10578256b288a233870dd43a380765400ea446df7f452c1e03a9e5b6731256 +f99cc1603de221abc1ecb1a7eb4bbf06e99561d1cc5541d8d601bae2b1dd3cbe448ac276667f26de5e269183a09f7deaf35d33174b3cc8ad4aa2 +ee2be1ec57fdac23f89402a534177eca0f4b982a4ed2c2e900b6a79e1f47a2d023eff2e647baf4f4c0da3a28d08a44bc780516974074e2523e6651 +9cda001868949a2bad96c5b3950a8315e6e5214d0b54dcd596280565d351806ef22cf3053f63623da72fcad9afa3896641658632334c9ec4f644c984 +c6d6722a916651a8671383d8260873347d9c248696b4cb3dac4dea9ba57ed971127cb18e44211d7e14177ace248b3c6e0785356ee261ebdc6ef0faf143 +5dd258a3e7505bc6b9776b0df25676a1c19e2c8258c7b5f2e361423523d96299eb6827bc7c27e7bca2d2b59d717c2ebcb05e6dcaa32289d96fae9a4077ef +19c14de35fe19c92cc0e624280e4136355d4cfa9a0a98b090c4b06f5665021920725852ff1f566b0c8c37157b25fb9f947a2e70b40577a17860a0732c170ac +5fcdcc02be7714a0dbc77df498bf999ea9225d564adca1c121c9af03af92cac8177b9b4a86bcc47c79aa32aac58a3fef967b2132e9352d4613fe890beed2571b +1afc8ec818bef0a479d2b4cac81d40a52cafa27f6d80c42fc23cbaf4141882ab59ab1101922fcb6e707ef2f61efd07cce5d09094e6bee420b1b96998c7cee96d +1afc8ec818bef0a479d2b4cac81d40a52cafa27f6d80c42fc23cbaf4141882ab59ab1101922fcb6e707ef2f61efd07cce5d09094e6bee420b1b96998c7cee96d +5789f474edd5206ededaccfc35e7dd3ed730748125b5395abf802b2601126b19b109a1db67556945bc79bb25e1ab59610599d155070e0e04354f11a6a5d6f3ac +e78efc663a5547c089f2b3b08973c974c4bfd365eac18b80c68bdb3b1ba4554b54d6b8465a68a3b9aa0bc020621f16efd5b8dd8c7c01ed9ee3ec5544aae465ff +1afc8ec818bef0a479d2b4cac81d40a52cafa27f6d80c42fc23cbaf4141882ab59ab1101922fcb6e707ef2f61efd07cce5d09094e6bee420b1b96998c7cee96d +1afc8ec818bef0a479d2b4cac81d40a52cafa27f6d80c42fc23cbaf4141882ab59ab1101922fcb6e707ef2f61efd07cce5d09094e6bee420b1b96998c7cee96d +fb4e2ad6b7fe6afd2ba06d5c1d79379c5bf10e336a35c89a1aaf408a805171716e0635a5b1d18190131e15b6888510bcb3e3752b050f892a09dbbde60b051495 +5789f474edd5206ededaccfc35e7dd3ed730748125b5395abf802b2601126b19b109a1db67556945bc79bb25e1ab59610599d155070e0e04354f11a6a5d6f3ac +e78efc663a5547c089f2b3b08973c974c4bfd365eac18b80c68bdb3b1ba4554b54d6b8465a68a3b9aa0bc020621f16efd5b8dd8c7c01ed9ee3ec5544aae465ff +4f9875a42ba0da8ae3448d2d62b1ff51be672eb1b8a1b0fa5bcd5334c861eff06b5903d672d318fd04e0ef94ddd37eca6d4ad2051a36a0236dc4cc09a5a44358 +ec9f272db92d1fa99324115f34cda8b4690ad029c1df36986cf9e1f844d8fdeca8e8e8311620ad24cbbfa12eccb676b979565405c8e2e20a2e4f18fb27c93d76 diff --git a/external/src/libsodium/test/default/hash.c b/external/src/libsodium/test/default/hash.c new file mode 100644 index 0000000..60d3527 --- /dev/null +++ b/external/src/libsodium/test/default/hash.c @@ -0,0 +1,47 @@ + +#define TEST_NAME "hash" +#include "cmptest.h" + +static unsigned char x[] = "testing\n"; +static unsigned char x2[] = + "The Conscience of a Hacker is a small essay written January 8, 1986 by a " + "computer security hacker who went by the handle of The Mentor, who " + "belonged to the 2nd generation of Legion of Doom."; +static unsigned char h[crypto_hash_BYTES]; + +int +main(void) +{ + size_t i; + + crypto_hash(h, x, sizeof x - 1U); + for (i = 0; i < crypto_hash_BYTES; ++i) { + printf("%02x", (unsigned int) h[i]); + } + printf("\n"); + crypto_hash(h, x2, sizeof x2 - 1U); + for (i = 0; i < crypto_hash_BYTES; ++i) { + printf("%02x", (unsigned int) h[i]); + } + printf("\n"); + crypto_hash_sha256(h, x, sizeof x - 1U); + for (i = 0; i < crypto_hash_sha256_BYTES; ++i) { + printf("%02x", (unsigned int) h[i]); + } + printf("\n"); + crypto_hash_sha256(h, x2, sizeof x2 - 1U); + for (i = 0; i < crypto_hash_sha256_BYTES; ++i) { + printf("%02x", (unsigned int) h[i]); + } + printf("\n"); + + assert(crypto_hash_bytes() > 0U); + assert(strcmp(crypto_hash_primitive(), "sha512") == 0); + assert(crypto_hash_sha256_bytes() > 0U); + assert(crypto_hash_sha512_bytes() >= crypto_hash_sha256_bytes()); + assert(crypto_hash_sha512_bytes() == crypto_hash_bytes()); + assert(crypto_hash_sha256_statebytes() == sizeof(crypto_hash_sha256_state)); + assert(crypto_hash_sha512_statebytes() == sizeof(crypto_hash_sha512_state)); + + return 0; +} diff --git a/external/src/libsodium/test/default/hash.exp b/external/src/libsodium/test/default/hash.exp new file mode 100644 index 0000000..f26c0b0 --- /dev/null +++ b/external/src/libsodium/test/default/hash.exp @@ -0,0 +1,4 @@ +24f950aac7b9ea9b3cb728228a0c82b67c39e96b4b344798870d5daee93e3ae5931baae8c7cacfea4b629452c38026a81d138bc7aad1af3ef7bfd5ec646d6c28 +a77abe1ccf8f5497e228fbc0acd73a521ededb21b89726684a6ebbc3baa32361aca5a244daa84f24bf19c68baf78e6907625a659b15479eb7bd426fc62aafa73 +12a61f4e173fb3a11c05d6471f74728f76231b4a5fcd9667cef3af87a3ae4dc2 +71cc8123fef8c236e451d3c3ddf1adae9aa6cd9521e7041769d737024900a03a diff --git a/external/src/libsodium/test/default/hash3.c b/external/src/libsodium/test/default/hash3.c new file mode 100644 index 0000000..cfcb989 --- /dev/null +++ b/external/src/libsodium/test/default/hash3.c @@ -0,0 +1,20 @@ + +#define TEST_NAME "hash3" +#include "cmptest.h" + +static unsigned char x[] = "testing\n"; +static unsigned char h[crypto_hash_BYTES]; + +int +main(void) +{ + size_t i; + + crypto_hash(h, x, sizeof x - 1U); + for (i = 0; i < crypto_hash_BYTES; ++i) { + printf("%02x", (unsigned int) h[i]); + } + printf("\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/hash3.exp b/external/src/libsodium/test/default/hash3.exp new file mode 100644 index 0000000..df58217 --- /dev/null +++ b/external/src/libsodium/test/default/hash3.exp @@ -0,0 +1 @@ +24f950aac7b9ea9b3cb728228a0c82b67c39e96b4b344798870d5daee93e3ae5931baae8c7cacfea4b629452c38026a81d138bc7aad1af3ef7bfd5ec646d6c28 diff --git a/external/src/libsodium/test/default/index.html.tpl b/external/src/libsodium/test/default/index.html.tpl new file mode 100644 index 0000000..cb7cb00 --- /dev/null +++ b/external/src/libsodium/test/default/index.html.tpl @@ -0,0 +1,98 @@ + + + + + + + +

+
+ + + diff --git a/external/src/libsodium/test/default/kdf.c b/external/src/libsodium/test/default/kdf.c new file mode 100644 index 0000000..f10f034 --- /dev/null +++ b/external/src/libsodium/test/default/kdf.c @@ -0,0 +1,71 @@ + +#define TEST_NAME "kdf" +#include "cmptest.h" + +static void +tv_kdf(void) +{ + unsigned char *master_key; + unsigned char *subkey; + char *context; + char hex[crypto_kdf_BYTES_MAX * 2 + 1]; + uint64_t i; + int ret; + + context = (char *) sodium_malloc(crypto_kdf_CONTEXTBYTES); + master_key = (unsigned char *) sodium_malloc(crypto_kdf_KEYBYTES); + + memcpy(context, "KDF test", sizeof "KDF test" -1U); + for (i = 0; i < crypto_kdf_KEYBYTES; i++) { + master_key[i] = i; + } + subkey = (unsigned char *) sodium_malloc(crypto_kdf_BYTES_MAX); + for (i = 0; i < 10; i++) { + ret = crypto_kdf_derive_from_key(subkey, crypto_kdf_BYTES_MAX, + i, context, master_key); + assert(ret == 0); + sodium_bin2hex(hex, sizeof hex, subkey, crypto_kdf_BYTES_MAX); + printf("%s\n", hex); + } + sodium_free(subkey); + + for (i = 0; i < crypto_kdf_BYTES_MAX + 2; i++) { + subkey = (unsigned char *) sodium_malloc(crypto_kdf_BYTES_MAX); + if (crypto_kdf_derive_from_key(subkey, (size_t) i, + i, context, master_key) == 0) { + sodium_bin2hex(hex, sizeof hex, subkey, (size_t) i); + printf("%s\n", hex); + } else { + printf("Failure -- probably expected for output length=%u\n", + (unsigned int) i); + } + sodium_free(subkey); + } + + sodium_free(master_key); + sodium_free(context); + + assert(strcmp(crypto_kdf_primitive(), crypto_kdf_PRIMITIVE) == 0); + assert(crypto_kdf_BYTES_MAX > 0); + assert(crypto_kdf_BYTES_MIN <= crypto_kdf_BYTES_MAX); + assert(crypto_kdf_bytes_min() == crypto_kdf_BYTES_MIN); + assert(crypto_kdf_bytes_max() == crypto_kdf_BYTES_MAX); + assert(crypto_kdf_CONTEXTBYTES > 0); + assert(crypto_kdf_contextbytes() == crypto_kdf_CONTEXTBYTES); + assert(crypto_kdf_KEYBYTES >= 16); + assert(crypto_kdf_keybytes() == crypto_kdf_KEYBYTES); + assert(crypto_kdf_bytes_min() == crypto_kdf_blake2b_bytes_min()); + assert(crypto_kdf_bytes_max() == crypto_kdf_blake2b_bytes_max()); + assert(crypto_kdf_contextbytes() == crypto_kdf_blake2b_contextbytes()); + assert(crypto_kdf_keybytes() == crypto_kdf_blake2b_keybytes()); + + printf("tv_kdf: ok\n"); +} + +int +main(void) +{ + tv_kdf(); + + return 0; +} diff --git a/external/src/libsodium/test/default/kdf.exp b/external/src/libsodium/test/default/kdf.exp new file mode 100644 index 0000000..4aa7694 --- /dev/null +++ b/external/src/libsodium/test/default/kdf.exp @@ -0,0 +1,77 @@ +a0c724404728c8bb95e5433eb6a9716171144d61efb23e74b873fcbeda51d8071b5d70aae12066dfc94ce943f145aa176c055040c3dd73b0a15e36254d450614 +02507f144fa9bf19010bf7c70b235b4c2663cc00e074f929602a5e2c10a780757d2a3993d06debc378a90efdac196dd841817b977d67b786804f6d3cd585bab5 +1944da61ff18dc2028c3578ac85be904931b83860896598f62468f1cb5471c6a344c945dbc62c9aaf70feb62472d17775ea5db6ed5494c68b7a9a59761f39614 +131c0ca1633ed074986215b264f6e0474f362c52b029effc7b0f75977ee89cc95d85c3db87f7e399197a25411592beeeb7e5128a74646a460ecd6deb4994b71e +a7023a0bf9be245d078aed26bcde0465ff0cc0961196a5482a0ff4ff8b4015971e13611f50529cb408f5776b14a90e7c3dd9160a22211db64ff4b5c0b9953680 +50f49313f3a05b2e565c13feedb44daa675cafd42c2b2cf9edbce9c949fbfc3f175dcb738671509ae2ea66fb85e552394d479afa7fa3affe8791744796b94176 +13b58d6d69780089293862cd59a1a8a4ef79bb850e3f3ba41fb22446a7dd1dc4da4667d37b33bf1225dcf8173c4c349a5d911c5bd2db9c5905ed70c11e809e3b +15d44b4b44ffa006eeceeb508c98a970aaa573d65905687b9e15854dec6d49c612757e149f78268f727660dedf9abce22a9691feb20a01b0525f4b47a3cf19db +9aebba11c5428ae8225716369e30a48943be39159a899f804e9963ef78822e186c21fe95bb0b85e60ef03a6f58d0b9d06e91f79d0ab998450b8810c73ca935b4 +70f9b83e463fb441e7a4c43275125cd5b19d8e2e4a5d179a39f5db10bbce745a199104563d308cf8d4c6b27bbb759ded232f5bdb7c367dd632a9677320dfe416 +Failure -- probably expected for output length=0 +Failure -- probably expected for output length=1 +Failure -- probably expected for output length=2 +Failure -- probably expected for output length=3 +Failure -- probably expected for output length=4 +Failure -- probably expected for output length=5 +Failure -- probably expected for output length=6 +Failure -- probably expected for output length=7 +Failure -- probably expected for output length=8 +Failure -- probably expected for output length=9 +Failure -- probably expected for output length=10 +Failure -- probably expected for output length=11 +Failure -- probably expected for output length=12 +Failure -- probably expected for output length=13 +Failure -- probably expected for output length=14 +Failure -- probably expected for output length=15 +a529216624ef9161e4cf117272aafff2 +068bd6940b80c6cc2530a68c31d9f4e323 +0acf4f6c74a590c8a1c0997ec9a1a3f48b2a +ac17a37ce74c0efece75f9337de20795dbadcc +268214dc9477a2e3c1022829f934ab992a5a3d84 +33b76197b4531665e494760909eda1cc570e7da9bb +3d4efbc569ca7f858ad4f49c56b820986a406e6eebbc +983fea27520f507c40231f9557908f07c095bdf4a4ce5d +94d678717625e011995c7355f2092267dee47bf0722dd380 +198901896c4f51e74ffa8b2805415c6eaba5accfc85a6e6b34 +4ffabb81d49021f85ef5d2a713ab02ae86bc2e7d1522f5e077fe +eebc3d55b3f4fc8b64d2474063254da7db98e7398dfdd510e28075 +22c134b9d664e1bdb14dc309a936bf1512b19e4f5175642efb1a0df7 +4b179762bfc8e27a9e575113faa76247b9c046d6f22d5a02e2910a299b +abc45eb2b031307b8822c7e59a43f4108850c34a7445936bc848422251c4 +d6565bd3265b6373f4f6a6b6458e981006da5e9d532ce94ca4737e188995e9 +154b291f11196737f8b7f491e4ca11764e0227d34f94295408a869f007aa8618 +e9dd395570e09ebb523ffc6ba098a38b17bc4944f14bd3725bdd7edbd8bcff54fb +7248294d37159e85bacde68c7762a673794c91b811e05f4e3b9e3ecc82bfcf63a2cd +d060ee4d93f8de6d9ae60fca9596413455183a1f83c7a2381227cec8f7a217e4072f85 +20790290347b9b0f413a954f40e52e270b3b45417e96c8733161672188701c08dd76cc3d +7674188112a1ab8d3926d468be8e51d788ce4144bb20ff842034e4d1ddab3929a4f1a13a74 +a2ab1f980a47472d8a539f20410cc9bf143d941331ab2259ea73684c0608939c5b23e9cbcb3d +f4cfbe3050f15ebbaf8d2f3bf3a678c01fc21ee1f4be07d0744c7fbf4835ea9d9472a3d785c24c +66efa5dfe3efd4cc8ca25f2d622c97a20a192d7add965f26b002b7eb81aae4203c0e5f07fd945845 +ad5d8031055c96dc9db10285206d7edc38d3af85736df8a3b5fdd30a318e80c28d9b26c95a60fa3e68 +9107c8a57a2c9ca40158f33ca0bfb64c095d2f21ca98bb7138477599330a36cdfc2ae5751e370d0e024e +b0c190177358b955ebebc5e0b86ec91dde3b6f1982ea4d68ec5ec3bdd6527c362e5275600b263601c98452 +31bfaaad4adde0f87d87372e398c42cb7befe065ab2957ebb91ef9dc534b410783899b2e1e84221286f3bab4 +2258dd1f3e516cb8e3d1f6c45808573c365192f073698939721af8961a02a8bdd002a31fd239b9498663a01f27 +7c7a88016610493bb44a9432a88b50f97e2e94383972ff95da826692d96c52d82f86899b3561ec9c95a8b1bf3213 +3929dc7473be4c633be9e08801a8abd284dc0c6154c5c81a4c18259699dd86753c5e14fbd723be46ebb04f4ab3058c +30b720220015fa60daa69c83f9754d772b1b2dd12ab6baaa2f4edab458d4d251c1cddb8c4a554f3eb13969316b890fbd +33fa2412a5c3294d49e964419e96d043a2099a72b3351e3bed0f07e12255c95b509ea9bf2963a4c0fe9cc2314dbc44f673 +ca891d2c82a6a8f833dc1a05f190bab6de221307eab1dd2c88341d4d2537a2fc0056b0d04d8104fd3fe89e1ea20877893e81 +fd78ac89a64d03672ad99d663f2613d15277cda1636e334a1706b7211ff1f3a3b3d2e671e391c75e3d242c482ce7e1b8b427ed +36a6072743d3aafd3ee89344b9ef92cb58a2853ae92b20283520439fcb55afffd3d4b5e4e8c92a85d3cf74497bdcf68bbf1fcf93 +a90afcfaffec1105ad05fdaa9473fb5daf1bf8fb376b7326db46ef4c120c553188c69131933371d409eb56d66d5adca618e1dac65b +9b990d1fcddbdb5e5c7a48a6a2a666e02e7d4d4a814ece40660d99e1c02d5f023c56ae82526fc6dc8c933d0add92fc376efcddd55a42 +ec545dcf456d1b0907c07418a42bf2b3d668b4797ba6874bf0d563f5f429a820f02177dd4d05e639a06807c9619fee54ffe07712493543 +b0106957626894586682a275f69ed4533e2f94334cc0430394b68d82679aca00dd579e712bdd2d7f5bbce9a050269739bd8427b75b06027f +05751bfeebb480c9bca0d25d8197e2673845f405d7fb9793e29169ac19956c525f6e637f3d5ea50597b04342afed4ca16f988b4f21a34f1902 +7b4e4294d3f64085b5c09be73548f1f5cb5c6f04e57ce6cdd3077e2fb37640bf1ca0c6393b87d48a6b7e3e42628bd30fca132ded03ce51f71d9d +082d248862cbfd71a634769a4b1cf52a4af47ace5b9ea4d583ca52207efc7234a6d321788130cbdec122579ad03afe00bc68c9fb3f68dd0532a96f +a2b39b4428d981013e8a9c0e41b3eed504983fc18dc4b60332b1ab28b9705228147bdb95cc17889d5f0f9cfb7fd16f9d414b1a829346a8922e945b40 +efbf0f8bda1b9ef24fe389f1cf0c0c8a08bca03fc95badabb79a487d8ce1351683f59183aa6229f880d69ad60114ac128f69b2be250109972ab1f3fc3b +dfe0ba2a6de25fa06b47375e9d9cf6c6fa1493a8a2a81c28d6e09bc161057b445659db76e92e349ff44f34a2a9e3bcaa6b84b21bae56f1499c170ab81af0 +02f9cbdb10759314515b01379c474ad74a1b575137bd3949776dbcfc3e18060cb13ee1f6dcf86035768fc7be63e01de321cacbfade209900dd94273fd8e176 +06ae14308eeeda62a00cb6d5edf18d1707029515db98f472bbf0617419301b1d4f4f2ab65849446be46f87e1d31c6c74283897b9976f70d8a16253ac927e0d9f +Failure -- probably expected for output length=65 +tv_kdf: ok diff --git a/external/src/libsodium/test/default/keygen.c b/external/src/libsodium/test/default/keygen.c new file mode 100644 index 0000000..a53d818 --- /dev/null +++ b/external/src/libsodium/test/default/keygen.c @@ -0,0 +1,67 @@ + +#define TEST_NAME "keygen" +#include "cmptest.h" + +typedef struct KeygenTV_ { + void (*fn)(unsigned char *k); + size_t key_len; +} KeygenTV; + +static void +tv_keygen(void) +{ + static const KeygenTV tvs[] = { + { crypto_auth_keygen, crypto_auth_KEYBYTES }, + { crypto_auth_hmacsha256_keygen, crypto_auth_hmacsha256_KEYBYTES }, + { crypto_aead_aes256gcm_keygen, crypto_aead_aes256gcm_KEYBYTES }, + { crypto_auth_hmacsha512_keygen, crypto_auth_hmacsha512_KEYBYTES }, + { crypto_auth_hmacsha512256_keygen, crypto_auth_hmacsha512256_KEYBYTES }, + { crypto_generichash_keygen, crypto_generichash_KEYBYTES }, + { crypto_generichash_blake2b_keygen, crypto_generichash_blake2b_KEYBYTES }, + { crypto_kdf_keygen, crypto_kdf_KEYBYTES }, + { crypto_onetimeauth_keygen, crypto_onetimeauth_KEYBYTES }, + { crypto_onetimeauth_poly1305_keygen, crypto_onetimeauth_poly1305_KEYBYTES }, + { crypto_aead_chacha20poly1305_ietf_keygen, crypto_aead_chacha20poly1305_ietf_KEYBYTES }, + { crypto_aead_chacha20poly1305_keygen, crypto_aead_chacha20poly1305_KEYBYTES }, + { crypto_aead_chacha20poly1305_ietf_keygen, crypto_aead_chacha20poly1305_ietf_KEYBYTES }, + { crypto_aead_xchacha20poly1305_ietf_keygen, crypto_aead_xchacha20poly1305_ietf_KEYBYTES }, + { crypto_secretbox_xsalsa20poly1305_keygen, crypto_secretbox_xsalsa20poly1305_KEYBYTES }, + { crypto_secretbox_keygen, crypto_secretbox_KEYBYTES }, + { crypto_secretstream_xchacha20poly1305_keygen, crypto_secretstream_xchacha20poly1305_KEYBYTES }, + { crypto_shorthash_keygen, crypto_shorthash_KEYBYTES }, + { crypto_stream_keygen, crypto_stream_KEYBYTES }, + { crypto_stream_chacha20_keygen, crypto_stream_chacha20_KEYBYTES }, + { crypto_stream_chacha20_ietf_keygen, crypto_stream_chacha20_ietf_KEYBYTES }, + { crypto_stream_salsa20_keygen, crypto_stream_salsa20_KEYBYTES }, + { crypto_stream_xsalsa20_keygen, crypto_stream_xsalsa20_KEYBYTES } + }; + const KeygenTV *tv; + unsigned char *key; + size_t i; + int j; + + for (i = 0; i < (sizeof tvs) / (sizeof tvs[0]); i++) { + tv = &tvs[i]; + key = (unsigned char *) sodium_malloc(tv->key_len); + key[tv->key_len - 1U] = 0; + for (j = 0; j < 10000; j++) { + tv->fn(key); + if (key[tv->key_len - 1U] != 0) { + break; + } + } + sodium_free(key); + if (j >= 10000) { + printf("Buffer underflow with test vector %u\n", (unsigned int) i); + } + } + printf("tv_keygen: ok\n"); +} + +int +main(void) +{ + tv_keygen(); + + return 0; +} diff --git a/external/src/libsodium/test/default/keygen.exp b/external/src/libsodium/test/default/keygen.exp new file mode 100644 index 0000000..4d10017 --- /dev/null +++ b/external/src/libsodium/test/default/keygen.exp @@ -0,0 +1 @@ +tv_keygen: ok diff --git a/external/src/libsodium/test/default/kx.c b/external/src/libsodium/test/default/kx.c new file mode 100644 index 0000000..e03f2d0 --- /dev/null +++ b/external/src/libsodium/test/default/kx.c @@ -0,0 +1,149 @@ + +#define TEST_NAME "kx" +#include "cmptest.h" + +static const unsigned char small_order_p[crypto_scalarmult_BYTES] = { + 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, + 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, + 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 +}; + +static void +tv_kx(void) +{ + unsigned char *seed; + unsigned char *client_pk, *client_sk; + unsigned char *client_rx, *client_tx; + unsigned char *server_pk, *server_sk; + unsigned char *server_rx, *server_tx; + char hex[65]; + int i; + + seed = (unsigned char *) sodium_malloc(crypto_kx_SEEDBYTES); + for (i = 0; i < crypto_kx_SEEDBYTES; i++) { + seed[i] = (unsigned char) i; + } + client_pk = (unsigned char *) sodium_malloc(crypto_kx_PUBLICKEYBYTES); + client_sk = (unsigned char *) sodium_malloc(crypto_kx_SECRETKEYBYTES); + crypto_kx_seed_keypair(client_pk, client_sk, seed); + + sodium_bin2hex(hex, sizeof hex, client_pk, crypto_kx_PUBLICKEYBYTES); + printf("client_pk: [%s]\n", hex); + sodium_bin2hex(hex, sizeof hex, client_sk, crypto_kx_SECRETKEYBYTES); + printf("client_sk: [%s]\n", hex); + + server_pk = (unsigned char *) sodium_malloc(crypto_kx_PUBLICKEYBYTES); + server_sk = (unsigned char *) sodium_malloc(crypto_kx_SECRETKEYBYTES); + crypto_kx_keypair(server_pk, server_sk); + + client_rx = (unsigned char *) sodium_malloc(crypto_kx_SESSIONKEYBYTES); + client_tx = (unsigned char *) sodium_malloc(crypto_kx_SESSIONKEYBYTES); + + assert(crypto_kx_client_session_keys(client_rx, client_tx, + client_pk, client_sk, + small_order_p) == -1); + if (crypto_kx_client_session_keys(client_rx, client_tx, + client_pk, client_sk, server_pk) != 0) { + printf("crypto_kx_client_session_keys() failed\n"); + } + + server_rx = (unsigned char *) sodium_malloc(crypto_kx_SESSIONKEYBYTES); + server_tx = (unsigned char *) sodium_malloc(crypto_kx_SESSIONKEYBYTES); + + assert(crypto_kx_server_session_keys(server_rx, server_tx, + server_pk, server_sk, + small_order_p) == -1); + if (crypto_kx_server_session_keys(server_rx, server_tx, + server_pk, server_sk, client_pk) != 0) { + printf("crypto_kx_server_session_keys() failed\n"); + } + if (memcmp(server_rx, client_tx, crypto_kx_SESSIONKEYBYTES) != 0 || + memcmp(server_tx, client_rx, crypto_kx_SESSIONKEYBYTES) != 0) { + printf("client session keys != server session keys\n"); + } + + sodium_increment(client_pk, crypto_kx_PUBLICKEYBYTES); + if (crypto_kx_server_session_keys(server_rx, server_tx, + server_pk, server_sk, client_pk) != 0) { + printf("crypto_kx_server_session_keys() failed\n"); + } + if (memcmp(server_rx, client_tx, crypto_kx_SESSIONKEYBYTES) == 0 && + memcmp(server_tx, client_rx, crypto_kx_SESSIONKEYBYTES) == 0) { + printf("peer's public key is ignored\n"); + } + + crypto_kx_keypair(client_pk, client_sk); + if (crypto_kx_server_session_keys(server_rx, server_tx, + server_pk, server_sk, client_pk) != 0) { + printf("crypto_kx_server_session_keys() failed\n"); + } + if (memcmp(server_rx, client_tx, crypto_kx_SESSIONKEYBYTES) == 0 || + memcmp(server_tx, client_rx, crypto_kx_SESSIONKEYBYTES) == 0) { + printf("session keys are constant\n"); + } + + crypto_kx_seed_keypair(client_pk, client_sk, seed); + sodium_increment(seed, crypto_kx_SEEDBYTES); + crypto_kx_seed_keypair(server_pk, server_sk, seed); + if (crypto_kx_server_session_keys(server_rx, server_tx, + server_pk, server_sk, client_pk) != 0) { + printf("crypto_kx_server_session_keys() failed\n"); + } + sodium_bin2hex(hex, sizeof hex, server_rx, crypto_kx_SESSIONKEYBYTES); + printf("server_rx: [%s]\n", hex); + sodium_bin2hex(hex, sizeof hex, server_tx, crypto_kx_SESSIONKEYBYTES); + printf("server_tx: [%s]\n", hex); + + if (crypto_kx_client_session_keys(client_rx, client_tx, + client_pk, client_sk, server_pk) != 0) { + printf("crypto_kx_client_session_keys() failed\n"); + } + sodium_bin2hex(hex, sizeof hex, client_rx, crypto_kx_SESSIONKEYBYTES); + printf("client_rx: [%s]\n", hex); + sodium_bin2hex(hex, sizeof hex, client_tx, crypto_kx_SESSIONKEYBYTES); + printf("client_tx: [%s]\n", hex); + + randombytes_buf(client_rx, crypto_kx_SESSIONKEYBYTES); + randombytes_buf(client_tx, crypto_kx_SESSIONKEYBYTES); + randombytes_buf(server_rx, crypto_kx_SESSIONKEYBYTES); + randombytes_buf(server_tx, crypto_kx_SESSIONKEYBYTES); + if (crypto_kx_client_session_keys(client_rx, NULL, + client_pk, client_sk, server_pk) != 0 || + crypto_kx_client_session_keys(NULL, client_tx, + client_pk, client_sk, server_pk) != 0 || + crypto_kx_server_session_keys(server_rx, NULL, + server_pk, server_sk, client_pk) != 0 || + crypto_kx_server_session_keys(NULL, server_tx, + server_pk, server_sk, client_pk) != 0) { + printf("failure when one of the pointers happens to be NULL"); + } + assert(memcmp(client_rx, client_tx, crypto_kx_SESSIONKEYBYTES) == 0); + assert(memcmp(client_tx, server_rx, crypto_kx_SESSIONKEYBYTES) == 0); + assert(memcmp(server_rx, server_tx, crypto_kx_SESSIONKEYBYTES) == 0); + + sodium_free(client_rx); + sodium_free(client_tx); + sodium_free(server_rx); + sodium_free(server_tx); + sodium_free(server_sk); + sodium_free(server_pk); + sodium_free(client_sk); + sodium_free(client_pk); + sodium_free(seed); + + assert(strcmp(crypto_kx_primitive(), crypto_kx_PRIMITIVE) == 0); + assert(crypto_kx_publickeybytes() == crypto_kx_PUBLICKEYBYTES); + assert(crypto_kx_secretkeybytes() == crypto_kx_SECRETKEYBYTES); + assert(crypto_kx_seedbytes() == crypto_kx_SEEDBYTES); + assert(crypto_kx_sessionkeybytes() == crypto_kx_SESSIONKEYBYTES); + + printf("tv_kx: ok\n"); +} + +int +main(void) +{ + tv_kx(); + + return 0; +} diff --git a/external/src/libsodium/test/default/kx.exp b/external/src/libsodium/test/default/kx.exp new file mode 100644 index 0000000..b9db6d5 --- /dev/null +++ b/external/src/libsodium/test/default/kx.exp @@ -0,0 +1,7 @@ +client_pk: [0e0216223f147143d32615a91189c288c1728cba3cc5f9f621b1026e03d83129] +client_sk: [cb2f5160fc1f7e05a55ef49d340b48da2e5a78099d53393351cd579dd42503d6] +server_rx: [62c8f4fa81800abd0577d99918d129b65deb789af8c8351f391feb0cbf238604] +server_tx: [749519c68059bce69f7cfcc7b387a3de1a1e8237d110991323bf62870115731a] +client_rx: [749519c68059bce69f7cfcc7b387a3de1a1e8237d110991323bf62870115731a] +client_tx: [62c8f4fa81800abd0577d99918d129b65deb789af8c8351f391feb0cbf238604] +tv_kx: ok diff --git a/external/src/libsodium/test/default/metamorphic.c b/external/src/libsodium/test/default/metamorphic.c new file mode 100644 index 0000000..fc883c7 --- /dev/null +++ b/external/src/libsodium/test/default/metamorphic.c @@ -0,0 +1,187 @@ + +#define TEST_NAME "metamorphic" +#include "cmptest.h" + +#define MAXLEN 512 +#define MAX_ITER 1000 + +static void +mm_generichash(void) +{ + crypto_generichash_state st; + unsigned char *h, *h2; + unsigned char *k; + unsigned char *m; + size_t hlen; + size_t klen; + size_t mlen; + size_t l1, l2; + int i; + + for (i = 0; i < MAX_ITER; i++) { + mlen = randombytes_uniform(MAXLEN); + m = (unsigned char *) sodium_malloc(mlen); + klen = randombytes_uniform(crypto_generichash_KEYBYTES_MAX - + crypto_generichash_KEYBYTES_MIN + 1U) + + crypto_generichash_KEYBYTES_MIN; + k = (unsigned char *) sodium_malloc(klen); + hlen = randombytes_uniform(crypto_generichash_BYTES_MAX - + crypto_generichash_BYTES_MIN + 1U) + + crypto_generichash_BYTES_MIN; + h = (unsigned char *) sodium_malloc(hlen); + h2 = (unsigned char *) sodium_malloc(hlen); + + randombytes_buf(k, klen); + randombytes_buf(m, mlen); + + crypto_generichash_init(&st, k, klen, hlen); + l1 = randombytes_uniform((uint32_t) mlen); + l2 = randombytes_uniform((uint32_t) (mlen - l1)); + crypto_generichash_update(&st, m, l1); + crypto_generichash_update(&st, m + l1, l2); + crypto_generichash_update(&st, m + l1 + l2, mlen - l1 - l2); + crypto_generichash_final(&st, h, hlen); + + crypto_generichash(h2, hlen, m, mlen, k, klen); + + assert(memcmp(h, h2, hlen) == 0); + + sodium_free(h2); + sodium_free(h); + sodium_free(k); + sodium_free(m); + } +} + +static void +mm_onetimeauth(void) +{ + crypto_onetimeauth_state st; + unsigned char *h, *h2; + unsigned char *k; + unsigned char *m; + size_t mlen; + size_t l1, l2; + int i; + + for (i = 0; i < MAX_ITER; i++) { + mlen = randombytes_uniform(MAXLEN); + m = (unsigned char *) sodium_malloc(mlen); + k = (unsigned char *) sodium_malloc(crypto_onetimeauth_KEYBYTES); + h = (unsigned char *) sodium_malloc(crypto_onetimeauth_BYTES); + h2 = (unsigned char *) sodium_malloc(crypto_onetimeauth_BYTES); + + crypto_onetimeauth_keygen(k); + randombytes_buf(m, mlen); + + crypto_onetimeauth_init(&st, k); + l1 = randombytes_uniform((uint32_t) mlen); + l2 = randombytes_uniform((uint32_t) (mlen - l1)); + crypto_onetimeauth_update(&st, m, l1); + crypto_onetimeauth_update(&st, m + l1, l2); + crypto_onetimeauth_update(&st, m + l1 + l2, mlen - l1 - l2); + crypto_onetimeauth_final(&st, h); + + crypto_onetimeauth(h2, m, mlen, k); + + assert(memcmp(h, h2, crypto_onetimeauth_BYTES) == 0); + + sodium_free(h2); + sodium_free(h); + sodium_free(k); + sodium_free(m); + } +} + +static void +mm_hmacsha256(void) +{ + crypto_auth_hmacsha256_state st; + unsigned char *h, *h2; + unsigned char *k; + unsigned char *m; + size_t mlen; + size_t l1, l2; + int i; + + for (i = 0; i < MAX_ITER; i++) { + mlen = randombytes_uniform(MAXLEN); + m = (unsigned char *) sodium_malloc(mlen); + k = (unsigned char *) sodium_malloc(crypto_auth_hmacsha256_KEYBYTES); + h = (unsigned char *) sodium_malloc(crypto_auth_hmacsha256_BYTES); + h2 = (unsigned char *) sodium_malloc(crypto_auth_hmacsha256_BYTES); + + crypto_auth_hmacsha256_keygen(k); + randombytes_buf(m, mlen); + + crypto_auth_hmacsha256_init(&st, k, crypto_auth_hmacsha256_KEYBYTES); + l1 = randombytes_uniform((uint32_t) mlen); + l2 = randombytes_uniform((uint32_t) (mlen - l1)); + crypto_auth_hmacsha256_update(&st, m, l1); + crypto_auth_hmacsha256_update(&st, m + l1, l2); + crypto_auth_hmacsha256_update(&st, m + l1 + l2, mlen - l1 - l2); + crypto_auth_hmacsha256_final(&st, h); + + crypto_auth_hmacsha256(h2, m, mlen, k); + + assert(memcmp(h, h2, crypto_auth_hmacsha256_BYTES) == 0); + + sodium_free(h2); + sodium_free(h); + sodium_free(k); + sodium_free(m); + } +} + +static void +mm_hmacsha512(void) +{ + crypto_auth_hmacsha512_state st; + unsigned char *h, *h2; + unsigned char *k; + unsigned char *m; + size_t mlen; + size_t l1, l2; + int i; + + for (i = 0; i < MAX_ITER; i++) { + mlen = randombytes_uniform(MAXLEN); + m = (unsigned char *) sodium_malloc(mlen); + k = (unsigned char *) sodium_malloc(crypto_auth_hmacsha512_KEYBYTES); + h = (unsigned char *) sodium_malloc(crypto_auth_hmacsha512_BYTES); + h2 = (unsigned char *) sodium_malloc(crypto_auth_hmacsha512_BYTES); + + crypto_auth_hmacsha512_keygen(k); + randombytes_buf(m, mlen); + + crypto_auth_hmacsha512_init(&st, k, crypto_auth_hmacsha512_KEYBYTES); + l1 = randombytes_uniform((uint32_t) mlen); + l2 = randombytes_uniform((uint32_t) (mlen - l1)); + crypto_auth_hmacsha512_update(&st, m, l1); + crypto_auth_hmacsha512_update(&st, m + l1, l2); + crypto_auth_hmacsha512_update(&st, m + l1 + l2, mlen - l1 - l2); + crypto_auth_hmacsha512_final(&st, h); + + crypto_auth_hmacsha512(h2, m, mlen, k); + + assert(memcmp(h, h2, crypto_auth_hmacsha512_BYTES) == 0); + + sodium_free(h2); + sodium_free(h); + sodium_free(k); + sodium_free(m); + } +} + +int +main(void) +{ + mm_generichash(); + mm_onetimeauth(); + mm_hmacsha256(); + mm_hmacsha512(); + + printf("OK\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/metamorphic.exp b/external/src/libsodium/test/default/metamorphic.exp new file mode 100644 index 0000000..d86bac9 --- /dev/null +++ b/external/src/libsodium/test/default/metamorphic.exp @@ -0,0 +1 @@ +OK diff --git a/external/src/libsodium/test/default/misuse.c b/external/src/libsodium/test/default/misuse.c new file mode 100644 index 0000000..407d526 --- /dev/null +++ b/external/src/libsodium/test/default/misuse.c @@ -0,0 +1,184 @@ + +#define TEST_NAME "misuse" +#include "cmptest.h" + +#ifdef HAVE_CATCHABLE_ABRT +# include + +static void +sigabrt_handler_15(int sig) +{ + (void) sig; + exit(0); +} + +# ifndef SODIUM_LIBRARY_MINIMAL +static void +sigabrt_handler_14(int sig) +{ + (void) sig; + signal(SIGABRT, sigabrt_handler_15); + assert(crypto_box_curve25519xchacha20poly1305_easy + (guard_page, guard_page, crypto_stream_xchacha20_MESSAGEBYTES_MAX - 1, + guard_page, guard_page, guard_page) == -1); + exit(1); +} + +static void +sigabrt_handler_13(int sig) +{ + (void) sig; + signal(SIGABRT, sigabrt_handler_14); + assert(crypto_box_curve25519xchacha20poly1305_easy_afternm + (guard_page, guard_page, crypto_stream_xchacha20_MESSAGEBYTES_MAX - 1, + guard_page, guard_page) == -1); + exit(1); +} +# endif + +static void +sigabrt_handler_12(int sig) +{ + (void) sig; +# ifdef SODIUM_LIBRARY_MINIMAL + signal(SIGABRT, sigabrt_handler_15); +# else + signal(SIGABRT, sigabrt_handler_13); +# endif + assert(crypto_pwhash_str_alg((char *) guard_page, + "", 0U, 1U, 1U, -1) == -1); + exit(1); +} + +static void +sigabrt_handler_11(int sig) +{ + (void) sig; + signal(SIGABRT, sigabrt_handler_12); + assert(crypto_box_easy(guard_page, guard_page, + crypto_stream_xsalsa20_MESSAGEBYTES_MAX, + guard_page, guard_page, guard_page) == -1); + exit(1); +} + +static void +sigabrt_handler_10(int sig) +{ + (void) sig; + signal(SIGABRT, sigabrt_handler_11); + assert(crypto_box_easy_afternm(guard_page, guard_page, + crypto_stream_xsalsa20_MESSAGEBYTES_MAX, + guard_page, guard_page) == -1); + exit(1); +} + +static void +sigabrt_handler_9(int sig) +{ + (void) sig; + signal(SIGABRT, sigabrt_handler_10); + assert(sodium_base642bin(guard_page, 1, (const char *) guard_page, 1, + NULL, NULL, NULL, -1) == -1); + exit(1); +} + +static void +sigabrt_handler_8(int sig) +{ + (void) sig; + signal(SIGABRT, sigabrt_handler_9); + assert(sodium_bin2base64((char *) guard_page, 1, guard_page, 1, + sodium_base64_VARIANT_ORIGINAL) == NULL); + exit(1); +} + +static void +sigabrt_handler_7(int sig) +{ + (void) sig; + signal(SIGABRT, sigabrt_handler_8); + assert(sodium_bin2base64((char *) guard_page, 1, + guard_page, 1, -1) == NULL); + exit(1); +} + +static void +sigabrt_handler_6(int sig) +{ + (void) sig; + signal(SIGABRT, sigabrt_handler_7); + assert(sodium_pad(NULL, guard_page, SIZE_MAX, 16, 1) == -1); + exit(1); +} + +static void +sigabrt_handler_5(int sig) +{ + (void) sig; + signal(SIGABRT, sigabrt_handler_6); + assert(crypto_aead_xchacha20poly1305_ietf_encrypt(guard_page, NULL, NULL, UINT64_MAX, + NULL, 0, NULL, + guard_page, guard_page) == -1); + exit(1); +} + +static void +sigabrt_handler_4(int sig) +{ + (void) sig; + signal(SIGABRT, sigabrt_handler_5); + assert(crypto_aead_chacha20poly1305_ietf_encrypt(guard_page, NULL, NULL, UINT64_MAX, + NULL, 0, NULL, + guard_page, guard_page) == -1); + exit(1); +} + +static void +sigabrt_handler_3(int sig) +{ + (void) sig; + signal(SIGABRT, sigabrt_handler_4); + assert(crypto_aead_chacha20poly1305_encrypt(guard_page, NULL, NULL, UINT64_MAX, + NULL, 0, NULL, + guard_page, guard_page) == -1); + exit(1); +} + +static void +sigabrt_handler_2(int sig) +{ + (void) sig; + signal(SIGABRT, sigabrt_handler_3); +#if SIZE_MAX > 0x4000000000ULL + randombytes_buf_deterministic(guard_page, 0x4000000001ULL, guard_page); +#else + abort(); +#endif + exit(1); +} + +static void +sigabrt_handler_1(int sig) +{ + (void) sig; + signal(SIGABRT, sigabrt_handler_2); + assert(crypto_kx_server_session_keys(NULL, NULL, guard_page, guard_page, + guard_page) == -1); + exit(1); +} + +int +main(void) +{ + signal(SIGABRT, sigabrt_handler_1); + assert(crypto_kx_client_session_keys(NULL, NULL, guard_page, guard_page, + guard_page) == -1); + return 1; +} +#else +int +main(void) +{ + return 0; +} +#endif diff --git a/external/src/libsodium/test/default/misuse.exp b/external/src/libsodium/test/default/misuse.exp new file mode 100644 index 0000000..e69de29 diff --git a/external/src/libsodium/test/default/onetimeauth.c b/external/src/libsodium/test/default/onetimeauth.c new file mode 100644 index 0000000..7a4931b --- /dev/null +++ b/external/src/libsodium/test/default/onetimeauth.c @@ -0,0 +1,63 @@ + +#define TEST_NAME "onetimeauth" +#include "cmptest.h" + +static unsigned char rs[32] = { + 0xee, 0xa6, 0xa7, 0x25, 0x1c, 0x1e, 0x72, 0x91, 0x6d, 0x11, 0xc2, + 0xcb, 0x21, 0x4d, 0x3c, 0x25, 0x25, 0x39, 0x12, 0x1d, 0x8e, 0x23, + 0x4e, 0x65, 0x2d, 0x65, 0x1f, 0xa4, 0xc8, 0xcf, 0xf8, 0x80 +}; + +static unsigned char c[131] = { + 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73, 0xc2, 0x96, 0x50, 0xba, + 0x32, 0xfc, 0x76, 0xce, 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4, + 0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a, 0xc0, 0xdf, 0xc1, 0x7c, + 0x98, 0xdc, 0xe8, 0x7b, 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72, + 0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2, 0x27, 0x0d, 0x6f, 0xb8, + 0x63, 0xd5, 0x17, 0x38, 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a, + 0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae, 0x90, 0x22, 0x43, 0x68, + 0x51, 0x7a, 0xcf, 0xea, 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda, + 0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde, 0x56, 0x24, 0x4a, 0x9e, + 0x88, 0xd5, 0xf9, 0xb3, 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6, + 0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74, 0xe3, 0x55, 0xa5 +}; + +static unsigned char a[16]; + +int +main(void) +{ + crypto_onetimeauth_state st; + int i; + + assert(crypto_onetimeauth_statebytes() == sizeof st); + crypto_onetimeauth(a, c, 131, rs); + for (i = 0; i < 16; ++i) { + printf(",0x%02x", (unsigned int) a[i]); + if (i % 8 == 7) + printf("\n"); + } + + memset(a, 0, sizeof a); + crypto_onetimeauth_init(&st, rs); + crypto_onetimeauth_update(&st, c, 100); + crypto_onetimeauth_update(&st, c, 0); + crypto_onetimeauth_update(&st, c + 100, 31); + crypto_onetimeauth_final(&st, a); + for (i = 0; i < 16; ++i) { + printf(",0x%02x", (unsigned int) a[i]); + if (i % 8 == 7) + printf("\n"); + } + + assert(crypto_onetimeauth_bytes() > 0U); + assert(crypto_onetimeauth_keybytes() > 0U); + assert(strcmp(crypto_onetimeauth_primitive(), "poly1305") == 0); + assert(crypto_onetimeauth_poly1305_bytes() == crypto_onetimeauth_bytes()); + assert(crypto_onetimeauth_poly1305_keybytes() == + crypto_onetimeauth_keybytes()); + assert(crypto_onetimeauth_statebytes() > 0); + assert(crypto_onetimeauth_statebytes() == crypto_onetimeauth_poly1305_statebytes()); + + return 0; +} diff --git a/external/src/libsodium/test/default/onetimeauth.exp b/external/src/libsodium/test/default/onetimeauth.exp new file mode 100644 index 0000000..33973bd --- /dev/null +++ b/external/src/libsodium/test/default/onetimeauth.exp @@ -0,0 +1,4 @@ +,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5 +,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9 +,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5 +,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9 diff --git a/external/src/libsodium/test/default/onetimeauth2.c b/external/src/libsodium/test/default/onetimeauth2.c new file mode 100644 index 0000000..e429ce0 --- /dev/null +++ b/external/src/libsodium/test/default/onetimeauth2.c @@ -0,0 +1,33 @@ + +#define TEST_NAME "onetimeauth2" +#include "cmptest.h" + +static unsigned char rs[32] = { + 0xee, 0xa6, 0xa7, 0x25, 0x1c, 0x1e, 0x72, 0x91, 0x6d, 0x11, 0xc2, + 0xcb, 0x21, 0x4d, 0x3c, 0x25, 0x25, 0x39, 0x12, 0x1d, 0x8e, 0x23, + 0x4e, 0x65, 0x2d, 0x65, 0x1f, 0xa4, 0xc8, 0xcf, 0xf8, 0x80 +}; + +static unsigned char c[131] = { + 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73, 0xc2, 0x96, 0x50, 0xba, + 0x32, 0xfc, 0x76, 0xce, 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4, + 0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a, 0xc0, 0xdf, 0xc1, 0x7c, + 0x98, 0xdc, 0xe8, 0x7b, 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72, + 0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2, 0x27, 0x0d, 0x6f, 0xb8, + 0x63, 0xd5, 0x17, 0x38, 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a, + 0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae, 0x90, 0x22, 0x43, 0x68, + 0x51, 0x7a, 0xcf, 0xea, 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda, + 0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde, 0x56, 0x24, 0x4a, 0x9e, + 0x88, 0xd5, 0xf9, 0xb3, 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6, + 0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74, 0xe3, 0x55, 0xa5 +}; + +static unsigned char a[16] = { 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5, + 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9 }; + +int +main(void) +{ + printf("%d\n", crypto_onetimeauth_verify(a, c, 131, rs)); + return 0; +} diff --git a/external/src/libsodium/test/default/onetimeauth2.exp b/external/src/libsodium/test/default/onetimeauth2.exp new file mode 100644 index 0000000..573541a --- /dev/null +++ b/external/src/libsodium/test/default/onetimeauth2.exp @@ -0,0 +1 @@ +0 diff --git a/external/src/libsodium/test/default/onetimeauth7.c b/external/src/libsodium/test/default/onetimeauth7.c new file mode 100644 index 0000000..7a77339 --- /dev/null +++ b/external/src/libsodium/test/default/onetimeauth7.c @@ -0,0 +1,36 @@ + +#define TEST_NAME "onetimeauth7" +#include "cmptest.h" + +static unsigned char key[32]; +static unsigned char c[1000]; +static unsigned char a[16]; + +int +main(void) +{ + int clen; + + for (clen = 0; clen < 1000; ++clen) { + crypto_onetimeauth_keygen(key); + randombytes_buf(c, clen); + crypto_onetimeauth(a, c, clen, key); + if (crypto_onetimeauth_verify(a, c, clen, key) != 0) { + printf("fail %d\n", clen); + return 100; + } + if (clen > 0) { + c[rand() % clen] += 1 + (rand() % 255); + if (crypto_onetimeauth_verify(a, c, clen, key) == 0) { + printf("forgery %d\n", clen); + return 100; + } + a[rand() % sizeof a] += 1 + (rand() % 255); + if (crypto_onetimeauth_verify(a, c, clen, key) == 0) { + printf("forgery %d\n", clen); + return 100; + } + } + } + return 0; +} diff --git a/external/src/libsodium/test/default/onetimeauth7.exp b/external/src/libsodium/test/default/onetimeauth7.exp new file mode 100644 index 0000000..e69de29 diff --git a/external/src/libsodium/test/default/pre.js.inc b/external/src/libsodium/test/default/pre.js.inc new file mode 100644 index 0000000..8b8d589 --- /dev/null +++ b/external/src/libsodium/test/default/pre.js.inc @@ -0,0 +1,22 @@ +try { + this['Module'] = Module; + Module.test; +} catch(e) { + this['Module'] = Module = {}; +} +if (typeof process === 'object') { + if (typeof(FS) === 'object') { + Module['preRun'] = Module['preRun'] || []; + Module['preRun'].push(function() { + FS.init(); + FS.mkdir('/test-data'); + FS.mount(NODEFS, { root: '.' }, '/test-data'); + }); + } +} else { + Module['print'] = function(x) { + var event = new Event('test-output'); + event.data = x; + window.dispatchEvent(event); + }; +} diff --git a/external/src/libsodium/test/default/pwhash_argon2i.c b/external/src/libsodium/test/default/pwhash_argon2i.c new file mode 100644 index 0000000..3e1195e --- /dev/null +++ b/external/src/libsodium/test/default/pwhash_argon2i.c @@ -0,0 +1,453 @@ + +#define TEST_NAME "pwhash_argon2i" +#include "cmptest.h" + +#define OUT_LEN 128 +#define OPSLIMIT 3 +#define MEMLIMIT 5000000 + +static void +tv(void) +{ + static struct { + const char * passwd_hex; + size_t passwd_len; + const char * salt_hex; + size_t outlen; + unsigned long long opslimit; + size_t memlimit; + unsigned int lanes; + } tests[] = { + { "a347ae92bce9f80f6f595a4480fc9c2fe7e7d7148d371e9487d75f5c23008ffae0" + "65577a928febd9b1973a5a95073acdbeb6a030cfc0d79caa2dc5cd011cef02c08d" + "a232d76d52dfbca38ca8dcbd665b17d1665f7cf5fe59772ec909733b24de97d6f5" + "8d220b20c60d7c07ec1fd93c52c31020300c6c1facd77937a597c7a6", + 127, + "5541fbc995d5c197ba290346d2c559dedf405cf97e5f95482143202f9e74f5c2", + 155, 5, 7256678, 1 }, + { "e125cee61c8cb7778d9e5ad0a6f5d978ce9f84de213a8556d9ffe202020ab4a6ed" + "9074a4eb3416f9b168f137510f3a30b70b96cbfa219ff99f6c6eaffb15c06b60e0" + "0cc2890277f0fd3c622115772f7048adaebed86e", + 86, + "f1192dd5dc2368b9cd421338b22433455ee0a3699f9379a08b9650ea2c126f0d", + 250, 4, 7849083, 1 }, + { "92263cbf6ac376499f68a4289d3bb59e5a22335eba63a32e6410249155b956b6a3" + "b48d4a44906b18b897127300b375b8f834f1ceffc70880a885f47c33876717e392" + "be57f7da3ae58da4fd1f43daa7e44bb82d3717af4319349c24cd31e46d295856b0" + "441b6b289992a11ced1cc3bf3011604590244a3eb737ff221129215e4e4347f491" + "5d41292b5173d196eb9add693be5319fdadc242906178bb6c0286c9b6ca6012746" + "711f58c8c392016b2fdfc09c64f0f6b6ab7b", + 183, + "3b840e20e9555e9fb031c4ba1f1747ce25cc1d0ff664be676b9b4a90641ff194", + 249, 3, 7994791, 1 }, + { "027b6d8e8c8c474e9b69c7d9ed4f9971e8e1ce2f6ba95048414c3970f0f09b70e3" + "b6c5ae05872b3d8678705b7d381829c351a5a9c88c233569b35d6b0b809df44b64" + "51a9c273f1150e2ef8a0b5437eb701e373474cd44b97ef0248ebce2ca0400e1b53" + "f3d86221eca3f18eb45b702b9172440f774a82cbf1f6f525df30a6e293c873cce6" + "9bb078ed1f0d31e7f9b8062409f37f19f8550aae", + 152, + "eb2a3056a09ad2d7d7f975bcd707598f24cd32518cde3069f2e403b34bfee8a5", 5, + 4, 1397645, 1 }, + { "4a857e2ee8aa9b6056f2424e84d24a72473378906ee04a46cb05311502d5250b82" + "ad86b83c8f20a23dbb74f6da60b0b6ecffd67134d45946ac8ebfb3064294bc097d" + "43ced68642bfb8bbbdd0f50b30118f5e", + 82, + "39d82eef32010b8b79cc5ba88ed539fbaba741100f2edbeca7cc171ffeabf258", + 190, 3, 1432947, 1 }, + { "c7b09aec680e7b42fedd7fc792e78b2f6c1bea8f4a884320b648f81e8cf515e8ba" + "9dcfb11d43c4aae114c1734aa69ca82d44998365db9c93744fa28b63fd16000e82" + "61cbbe083e7e2da1e5f696bde0834fe53146d7e0e35e7de9920d041f5a5621aabe" + "02da3e2b09b405b77937efef3197bd5772e41fdb73fb5294478e45208063b5f58e" + "089dbeb6d6342a909c1307b3fff5fe2cf4da56bdae50848f", + 156, + "039c056d933b475032777edbaffac50f143f64c123329ed9cf59e3b65d3f43b6", + 178, 3, 4886999, 1 }, + { "b540beb016a5366524d4605156493f9874514a5aa58818cd0c6dfffaa9e90205f1" + "7b", + 34, + "44071f6d181561670bda728d43fb79b443bb805afdebaf98622b5165e01b15fb", + 231, 1, 1631659, 1 }, + { "a14975c26c088755a8b715ff2528d647cd343987fcf4aa25e7194a8417fb2b4b3f" + "7268da9f3182b4cfb22d138b2749d673a47ecc7525dd15a0a3c66046971784bb63" + "d7eae24cc84f2631712075a10e10a96b0e0ee67c43e01c423cb9c44e5371017e9c" + "496956b632158da3fe12addecb88912e6759bc37f9af2f45af72c5cae3b179ffb6" + "76a697de6ebe45cd4c16d4a9d642d29ddc0186a0a48cb6cd62bfc3dd229d313b30" + "1560971e740e2cf1f99a9a090a5b283f35475057e96d7064e2e0fc81984591068d" + "55a3b4169f22cccb0745a2689407ea1901a0a766eb99", + 220, + "3d968b2752b8838431165059319f3ff8910b7b8ecb54ea01d3f54769e9d98daf", + 167, 3, 1784128, 1 }, + }; + char passwd[256]; + unsigned char salt[crypto_pwhash_SALTBYTES]; + unsigned char out[256]; + char out_hex[256 * 2 + 1]; + size_t i = 0U; + + do { + sodium_hex2bin((unsigned char *) passwd, sizeof passwd, + tests[i].passwd_hex, strlen(tests[i].passwd_hex), NULL, + NULL, NULL); + sodium_hex2bin(salt, sizeof salt, tests[i].salt_hex, + strlen(tests[i].salt_hex), NULL, NULL, NULL); + if (crypto_pwhash(out, (unsigned long long) tests[i].outlen, passwd, + tests[i].passwd_len, (const unsigned char *) salt, + tests[i].opslimit, tests[i].memlimit, + crypto_pwhash_alg_argon2i13()) != 0) { + printf("[tv] pwhash failure (maybe intentional): [%u]\n", + (unsigned int) i); + continue; + } + sodium_bin2hex(out_hex, sizeof out_hex, out, tests[i].outlen); + printf("%s\n", out_hex); + } while (++i < (sizeof tests) / (sizeof tests[0])); +} + +static void +tv2(void) +{ + static struct { + const char * passwd_hex; + size_t passwd_len; + const char * salt_hex; + size_t outlen; + unsigned long long opslimit; + size_t memlimit; + unsigned int lanes; + } tests[] = { + { "a347ae92bce9f80f6f595a4480fc9c2fe7e7d7148d371e9487d75f5c23008ffae0" + "65577a928febd9b1973a5a95073acdbeb6a030cfc0d79caa2dc5cd011cef02c08d" + "a232d76d52dfbca38ca8dcbd665b17d1665f7cf5fe59772ec909733b24de97d6f5" + "8d220b20c60d7c07ec1fd93c52c31020300c6c1facd77937a597c7a6", + 127, + "5541fbc995d5c197ba290346d2c559dedf405cf97e5f95482143202f9e74f5c2", + 155, 4, 397645, 1 }, + { "a347ae92bce9f80f6f595a4480fc9c2fe7e7d7148d371e9487d75f5c23008ffae0" + "65577a928febd9b1973a5a95073acdbeb6a030cfc0d79caa2dc5cd011cef02c08d" + "a232d76d52dfbca38ca8dcbd665b17d1665f7cf5fe59772ec909733b24de97d6f5" + "8d220b20c60d7c07ec1fd93c52c31020300c6c1facd77937a597c7a6", + 127, + "5541fbc995d5c197ba290346d2c559dedf405cf97e5f95482143202f9e74f5c2", + 155, 3, 397645, 1 }, + }; + char passwd[256]; + unsigned char salt[crypto_pwhash_SALTBYTES]; + unsigned char out[256]; + char out_hex[256 * 2 + 1]; + size_t i = 0U; + + do { + sodium_hex2bin((unsigned char *) passwd, sizeof passwd, + tests[i].passwd_hex, strlen(tests[i].passwd_hex), NULL, + NULL, NULL); + sodium_hex2bin(salt, sizeof salt, tests[i].salt_hex, + strlen(tests[i].salt_hex), NULL, NULL, NULL); + if (crypto_pwhash(out, (unsigned long long) tests[i].outlen, passwd, + tests[i].passwd_len, (const unsigned char *) salt, + tests[i].opslimit, tests[i].memlimit, + crypto_pwhash_alg_argon2i13()) != 0) { + printf("[tv2] pwhash failure: [%u]\n", (unsigned int) i); + continue; + } + sodium_bin2hex(out_hex, sizeof out_hex, out, tests[i].outlen); + printf("%s\n", out_hex); + } while (++i < (sizeof tests) / (sizeof tests[0])); + + if (crypto_pwhash(out, sizeof out, "password", strlen("password"), salt, 3, + 1ULL << 12, 0) != -1) { + printf("[tv2] pwhash should have failed (0)\n"); + } + if (crypto_pwhash_argon2i(out, sizeof out, "password", strlen("password"), salt, 3, + 1ULL << 12, 0) != -1) { + printf("[tv2] pwhash should have failed (0')\n"); + } + if (crypto_pwhash(out, sizeof out, "password", strlen("password"), salt, 3, + 1, crypto_pwhash_alg_argon2i13()) != -1) { + printf("[tv2] pwhash should have failed (1)\n"); + } + if (crypto_pwhash(out, sizeof out, "password", strlen("password"), salt, 3, + 1ULL << 12, crypto_pwhash_alg_argon2i13()) != -1) { + printf("[tv2] pwhash should have failed (2)\n"); + } + if (crypto_pwhash(out, sizeof out, "password", strlen("password"), salt, 2, + 1ULL << 12, crypto_pwhash_alg_argon2i13()) != -1) { + printf("[tv2] pwhash should have failed (3)\n"); + } + if (crypto_pwhash(out, 15, "password", strlen("password"), salt, 3, + 1ULL << 12, crypto_pwhash_alg_argon2i13()) != -1) { + printf("[tv2] pwhash with a short output length should have failed\n"); + } + if (crypto_pwhash(out, sizeof out, "password", 0x100000000ULL, salt, 3, + 1ULL << 12, crypto_pwhash_alg_argon2i13()) != -1) { + printf("[tv2] pwhash with a long password length should have failed\n"); + } + assert(crypto_pwhash_argon2i(out, sizeof out, "password", strlen("password"), salt, + OPSLIMIT, MEMLIMIT, crypto_pwhash_alg_argon2id13()) == -1); +} + +static void +tv3(void) +{ + static struct { + const char *passwd; + const char *out; + } tests[] = { + { "", + "$argon2i$v=19$m=4096,t=1,p=1$X1NhbHQAAAAAAAAAAAAAAA$bWh++" + "MKN1OiFHKgIWTLvIi1iHicmHH7+Fv3K88ifFfI" }, + { "", + "$argon2i$v=19$m=2048,t=4,p=1$SWkxaUhpY21ISDcrRnYzSw$Mbg/" + "Eck1kpZir5T9io7C64cpffdTBaORgyriLQFgQj8" }, + { "^T5H$JYt39n%K*j:W]!1s?vg!:jGi]Ax?..l7[p0v:1jHTpla9;]bUN;?bWyCbtqg ", + "$argon2i$v=19$m=4096,t=3,p=2$X1NhbHQAAAAAAAAAAAAAAA$z/QMiU4lQxGsYNc/" + "+K/bizwsA1P11UG2dj/7+aILJ4I" }, + { "K3S=KyH#)36_?]LxeR8QNKw6X=gFbxai$C%29V*", + "$argon2i$v=19$m=4096,t=3,p=1$X1NhbHQAAAAAAAAAAAAAAA$fu2Wsecyt+" + "yPnBvSvYN16oP5ozRmkp0ixJ1YL19V3Uo" } + }; + char *out; + char *passwd; + size_t i = 0U; + int ret; + + do { + out = (char *) sodium_malloc(strlen(tests[i].out) + 1U); + assert(out != NULL); + memcpy(out, tests[i].out, strlen(tests[i].out) + 1U); + passwd = (char *) sodium_malloc(strlen(tests[i].passwd) + 1U); + assert(passwd != NULL); + memcpy(passwd, tests[i].passwd, strlen(tests[i].passwd) + 1U); + ret = crypto_pwhash_str_verify(out, passwd, strlen(passwd)); + sodium_free(out); + sodium_free(passwd); + if (ret != 0) { + printf("[tv3] pwhash_str failure (maybe intentional): [%u]\n", + (unsigned int) i); + } + } while (++i < (sizeof tests) / (sizeof tests[0])); +} + +static void +str_tests(void) +{ + char *str_out; + char *str_out2; + char *salt; + const char *passwd = "Correct Horse Battery Staple"; + + salt = (char *) sodium_malloc(crypto_pwhash_SALTBYTES); + str_out = (char *) sodium_malloc(crypto_pwhash_STRBYTES); + str_out2 = (char *) sodium_malloc(crypto_pwhash_STRBYTES); + memcpy(salt, ">A 16-bytes salt", crypto_pwhash_SALTBYTES); + if (crypto_pwhash_argon2i_str(str_out, passwd, strlen(passwd), OPSLIMIT, + MEMLIMIT) != 0) { + printf("pwhash_argon2i_str failure\n"); + } + if (crypto_pwhash_argon2i_str(str_out2, passwd, strlen(passwd), OPSLIMIT, + MEMLIMIT) != 0) { + printf("pwhash_argon2i_str(2) failure\n"); + } + if (strcmp(str_out, str_out2) == 0) { + printf("pwhash_argon2i_str() doesn't generate different salts\n"); + } + if (crypto_pwhash_argon2i_str_needs_rehash(str_out, OPSLIMIT, MEMLIMIT) != 0) { + printf("needs_rehash() false positive\n"); + } + if (crypto_pwhash_argon2i_str_needs_rehash(str_out, OPSLIMIT, MEMLIMIT / 2) != 1 || + crypto_pwhash_argon2i_str_needs_rehash(str_out, OPSLIMIT / 2, MEMLIMIT) != 1 || + crypto_pwhash_argon2i_str_needs_rehash(str_out, OPSLIMIT, MEMLIMIT * 2) != 1 || + crypto_pwhash_argon2i_str_needs_rehash(str_out, OPSLIMIT * 2, MEMLIMIT) != 1) { + printf("needs_rehash() false negative\n"); + } + if (crypto_pwhash_str_needs_rehash(str_out, OPSLIMIT, MEMLIMIT / 2) != 1) { + printf("pwhash_str_needs_rehash() didn't handle argon2i\n"); + } + if (crypto_pwhash_str_needs_rehash(str_out + 1, OPSLIMIT, MEMLIMIT) != -1 || + crypto_pwhash_argon2i_str_needs_rehash(str_out + 1, OPSLIMIT, MEMLIMIT) != -1) { + printf("needs_rehash() didn't fail with an invalid hash string\n"); + } + if (sodium_is_zero((const unsigned char *) str_out + strlen(str_out), + crypto_pwhash_STRBYTES - strlen(str_out)) != 1 || + sodium_is_zero((const unsigned char *) str_out2 + strlen(str_out2), + crypto_pwhash_STRBYTES - strlen(str_out2)) != 1) { + printf("pwhash_str() doesn't properly pad with zeros\n"); + } + if (crypto_pwhash_argon2i_str_verify(str_out, passwd, strlen(passwd)) != 0) { + printf("pwhash_str_verify(1) failure\n"); + } + str_out[14]++; + if (crypto_pwhash_argon2i_str_verify(str_out, passwd, strlen(passwd)) != -1) { + printf("pwhash_str_verify(2) failure\n"); + } + str_out[14]--; + assert(str_out[crypto_pwhash_STRBYTES - 1U] == 0); + + if (crypto_pwhash_argon2i_str(str_out2, passwd, 0x100000000ULL, OPSLIMIT, + MEMLIMIT) != -1) { + printf("pwhash_str() with a large password should have failed\n"); + } + if (crypto_pwhash_argon2i_str(str_out2, passwd, strlen(passwd), 1, MEMLIMIT) != + -1) { + printf("pwhash_str() with a small opslimit should have failed\n"); + } + if (crypto_pwhash_argon2i_str_verify("$argon2i$m=65536,t=2,p=1c29tZXNhbHQ" + "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", + "password", 0x100000000ULL) != -1) { + printf("pwhash_str_verify(invalid(0)) failure\n"); + } + if (crypto_pwhash_argon2i_str_verify("$argon2i$m=65536,t=2,p=1c29tZXNhbHQ" + "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", + "password", strlen("password")) != -1) { + printf("pwhash_str_verify(invalid(1)) failure %d\n", errno); + } + if (crypto_pwhash_argon2i_str_verify("$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ" + "9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", + "password", strlen("password")) != -1) { + printf("pwhash_str_verify(invalid(2)) failure\n"); + } + if (crypto_pwhash_str_verify("$argon2i$m=65536,t=2,p=1$c29tZXNhbHQ" + "$b2G3seW+uPzerwQQC+/E1K50CLLO7YXy0JRcaTuswRo", + "password", strlen("password")) != -1) { + printf("pwhash_str_verify(invalid(3)) failure\n"); + } + if (crypto_pwhash_str_verify("$argon2i$v=19$m=65536,t=2,p=1c29tZXNhbHQ" + "$wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA", + "password", strlen("password")) != -1) { + printf("pwhash_str_verify(invalid(4)) failure\n"); + } + if (crypto_pwhash_str_verify("$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" + "wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA", + "password", strlen("password")) != -1) { + printf("pwhash_str_verify(invalid(5)) failure\n"); + } + if (crypto_pwhash_str_verify("$argon2i$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" + "$8iIuixkI73Js3G1uMbezQXD0b8LG4SXGsOwoQkdAQIM", + "password", strlen("password")) != -1) { + printf("pwhash_str_verify(invalid(6)) failure\n"); + } + if (crypto_pwhash_str_verify( + "$argon2i$v=19$m=4096,t=3,p=2$b2RpZHVlamRpc29kaXNrdw" + "$TNnWIwlu1061JHrnCqIAmjs3huSxYIU+0jWipu7Kc9M", + "password", strlen("password")) != 0) { + printf("pwhash_str_verify(valid(7)) failure\n"); + } + if (crypto_pwhash_str_verify( + "$argon2i$v=19$m=4096,t=3,p=2$b2RpZHVlamRpc29kaXNrdw" + "$TNnWIwlu1061JHrnCqIAmjs3huSxYIU+0jWipu7Kc9M", + "passwore", strlen("passwore")) != -1 || errno != EINVAL) { + printf("pwhash_str_verify(invalid(7)) failure\n"); + } + if (crypto_pwhash_str_verify( + "$Argon2i$v=19$m=4096,t=3,p=2$b2RpZHVlamRpc29kaXNrdw" + "$TNnWIwlu1061JHrnCqIAmjs3huSxYIU+0jWipu7Kc9M", + "password", strlen("password")) != -1 || errno != EINVAL) { + printf("pwhash_str_verify(invalid(8)) failure\n"); + } + if (crypto_pwhash_str_verify( + "$argon2i$v=1$m=4096,t=3,p=2$b2RpZHVlamRpc29kaXNrdw" + "$TNnWIwlu1061JHrnCqIAmjs3huSxYIU+0jWipu7Kc9M", + "password", strlen("password")) != -1 || errno != EINVAL) { + printf("pwhash_str_verify(invalid(9)) failure\n"); + } + if (crypto_pwhash_str_verify( + "$argon2i$v=1$m=4096,t=3,p=2$b2RpZHVla~=mRpc29kaXNrdw" + "$TNnWIwlu1061JHrnCqIAmjs3huSxYIU+0jWipu7Kc9M", + "password", strlen("password")) != -1 || errno != EINVAL) { + printf("pwhash_str_verify(invalid(10)) failure\n"); + } + if (crypto_pwhash_str_verify( + "$argon2i$v=1$m=4096,t=3,p=2$b2RpZHVlamRpc29kaXNrdw" + "$TNnWIwlu1061JHrnCqIAmjs3huSxYI~=U+0jWipu7Kc9M", + "password", strlen("password")) != -1 || errno != EINVAL) { + printf("pwhash_str_verify(invalid(11)) failure\n"); + } + assert(crypto_pwhash_str_alg(str_out, "test", 4, OPSLIMIT, MEMLIMIT, + crypto_pwhash_ALG_ARGON2I13) == 0); + assert(crypto_pwhash_argon2i_str_verify(str_out, "test", 4) == 0); + assert(crypto_pwhash_argon2i_str_needs_rehash(str_out, + OPSLIMIT, MEMLIMIT) == 0); + assert(crypto_pwhash_argon2i_str_needs_rehash(str_out, + OPSLIMIT / 2, MEMLIMIT) == 1); + assert(crypto_pwhash_argon2i_str_needs_rehash(str_out, + OPSLIMIT, MEMLIMIT / 2) == 1); + assert(crypto_pwhash_argon2i_str_needs_rehash(str_out, 0, 0) == 1); + assert(crypto_pwhash_argon2id_str_needs_rehash(str_out, 0, 0) == -1); + assert(crypto_pwhash_argon2i_str_needs_rehash(str_out + 1, + OPSLIMIT, MEMLIMIT) == -1); + assert(crypto_pwhash_argon2id_str_needs_rehash(str_out, 0, 0) == -1); + assert(crypto_pwhash_argon2id_str_needs_rehash("", OPSLIMIT, MEMLIMIT) == -1); + assert(crypto_pwhash_str_alg(str_out, "test", 4, OPSLIMIT, MEMLIMIT, + crypto_pwhash_ALG_ARGON2ID13) == 0); + assert(crypto_pwhash_argon2id_str_verify(str_out, "test", 4) == 0); + assert(crypto_pwhash_argon2id_str_needs_rehash(str_out, + OPSLIMIT, MEMLIMIT) == 0); + assert(crypto_pwhash_argon2id_str_needs_rehash(str_out, + OPSLIMIT / 2, MEMLIMIT) == 1); + assert(crypto_pwhash_argon2id_str_needs_rehash(str_out, + OPSLIMIT, MEMLIMIT / 2) == 1); + assert(crypto_pwhash_argon2id_str_needs_rehash(str_out, 0, 0) == 1); + assert(crypto_pwhash_argon2i_str_needs_rehash(str_out, 0, 0) == -1); + assert(crypto_pwhash_argon2id_str_needs_rehash("", OPSLIMIT, MEMLIMIT) == -1); + assert(crypto_pwhash_argon2id_str_needs_rehash(str_out + 1, + OPSLIMIT, MEMLIMIT) == -1); + sodium_free(salt); + sodium_free(str_out); + sodium_free(str_out2); +} + +int +main(void) +{ + tv(); + tv2(); + tv3(); + str_tests(); + + assert(crypto_pwhash_argon2i_bytes_min() > 0U); + assert(crypto_pwhash_argon2i_bytes_max() > crypto_pwhash_argon2i_bytes_min()); + assert(crypto_pwhash_argon2i_passwd_max() > crypto_pwhash_argon2i_passwd_min()); + assert(crypto_pwhash_argon2i_saltbytes() > 0U); + assert(crypto_pwhash_argon2i_strbytes() > 1U); + assert(crypto_pwhash_argon2i_strbytes() > strlen(crypto_pwhash_argon2i_strprefix())); + + assert(crypto_pwhash_argon2i_opslimit_min() > 0U); + assert(crypto_pwhash_argon2i_opslimit_max() > 0U); + assert(crypto_pwhash_argon2i_memlimit_min() > 0U); + assert(crypto_pwhash_argon2i_memlimit_max() > 0U); + assert(crypto_pwhash_argon2i_opslimit_interactive() > 0U); + assert(crypto_pwhash_argon2i_memlimit_interactive() > 0U); + assert(crypto_pwhash_argon2i_opslimit_moderate() > 0U); + assert(crypto_pwhash_argon2i_memlimit_moderate() > 0U); + assert(crypto_pwhash_argon2i_opslimit_sensitive() > 0U); + assert(crypto_pwhash_argon2i_memlimit_sensitive() > 0U); + + assert(crypto_pwhash_argon2i_bytes_min() == crypto_pwhash_argon2i_BYTES_MIN); + assert(crypto_pwhash_argon2i_bytes_max() == crypto_pwhash_argon2i_BYTES_MAX); + assert(crypto_pwhash_argon2i_passwd_min() == crypto_pwhash_argon2i_PASSWD_MIN); + assert(crypto_pwhash_argon2i_passwd_max() == crypto_pwhash_argon2i_PASSWD_MAX); + assert(crypto_pwhash_argon2i_saltbytes() == crypto_pwhash_argon2i_SALTBYTES); + assert(crypto_pwhash_argon2i_strbytes() == crypto_pwhash_argon2i_STRBYTES); + + assert(crypto_pwhash_argon2i_opslimit_min() == crypto_pwhash_argon2i_OPSLIMIT_MIN); + assert(crypto_pwhash_argon2i_opslimit_max() == crypto_pwhash_argon2i_OPSLIMIT_MAX); + assert(crypto_pwhash_argon2i_memlimit_min() == crypto_pwhash_argon2i_MEMLIMIT_MIN); + assert(crypto_pwhash_argon2i_memlimit_max() == crypto_pwhash_argon2i_MEMLIMIT_MAX); + assert(crypto_pwhash_argon2i_opslimit_interactive() == + crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE); + assert(crypto_pwhash_argon2i_memlimit_interactive() == + crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE); + assert(crypto_pwhash_argon2i_opslimit_moderate() == + crypto_pwhash_argon2i_OPSLIMIT_MODERATE); + assert(crypto_pwhash_argon2i_memlimit_moderate() == + crypto_pwhash_argon2i_MEMLIMIT_MODERATE); + assert(crypto_pwhash_argon2i_opslimit_sensitive() == + crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE); + assert(crypto_pwhash_argon2i_memlimit_sensitive() == + crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE); + + assert(crypto_pwhash_argon2i_alg_argon2i13() == crypto_pwhash_argon2i_ALG_ARGON2I13); + + printf("OK\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/pwhash_argon2i.exp b/external/src/libsodium/test/default/pwhash_argon2i.exp new file mode 100644 index 0000000..0140ba8 --- /dev/null +++ b/external/src/libsodium/test/default/pwhash_argon2i.exp @@ -0,0 +1,11 @@ +23b803c84eaa25f4b44634cc1e5e37792c53fcd9b1eb20f865329c68e09cbfa9f1968757901b383fce221afe27713f97914a041395bbe1fb70e079e5bed2c7145b1f6154046f5958e9b1b29055454e264d1f2231c316f26be2e3738e83a80315e9a0951ce4b137b52e7d5ee7b37f7d936dcee51362bcf792595e3c896ad5042734fc90c92cae572ce63ff659a2f7974a3bd730d04d525d253ccc38 +0bb3769b064b9c43a9460476ab38c4a9a2470d55d4c992c6e723af895e4c07c09af41f22f90eab583a0c362d177f4677f212482fd145bfb9ac6211635e48461122bb49097b5fb0739d2cd22a39bf03d268e7495d4fd8d710aa156202f0a06e932ff513e6e7c76a4e98b6df5cf922f124791b1076ad904e6897271f5d7d24c5929e2a3b836d0f2f2697c2d758ee79bf1264f3fae65f3744e0f6d7d07ef6e8b35b70c0f88e9036325bfb24ac7f550351486da87aef10d6b0cb77d1cf6e31cf98399c6f241c605c6530dffb4764784f6c0b0bf601d4e4431e8b18dabdc3079c6e264302ade79f61cbd5497c95486340bb891a737223100be0429650 +e9aa073b0b872f15c083d1d7ce52c09f493b827ca78f13a06c1721b45b1e17b24c04e19fe869333135360197a7eb55994fee3e8d9680aedfdf7674f3ad7b84d59d7eab03579ffc10c7093093bc48ec84252aa1b30f40f5e838f1443e15e2772a39f4e774eb052097e8881e94f15457b779fa2af2bbc9a993687657c7704ac8a37c25c1df4289eb4c70da45f2fd46bc0f78259767d3dd478a7c369cf866758bc36d9bd8e2e3c9fb0cf7fd6073ebf630c1f67fa7d303c07da40b36749d157ea37965fef810f2ea05ae6fc7d96a8f3470d73e15b22b42e8d6986dbfe5303256b2b3560372c4452ffb2a04fb7c6691489f70cb46831be0679117f7 +[tv] pwhash failure (maybe intentional): [3] +c121209f0ba70aed93d49200e5dc82cce013cef25ea31e160bf8db3cf448a59d1a56f6c19259e18ea020553cb75781761d112b2d949a297584c65e60df95ad89c4109825a3171dc6f20b1fd6b0cdfd194861bc2b414295bee5c6c52619e544abce7d520659c3d51de2c60e89948d830695ab38dcb75dd7ab06a4770dd4bc7c8f335519e04b038416b1a7dbd25c026786a8105c5ffe7a0931364f0376ae5772be39b51d91d3281464e0f3a128e7155a68e87cf79626ffca0b2a3022fc8420 +91c337ce8918a5805a59b00bd1819d3eb4356807cbd2a80b271c4b482dce03f5b02ae4eb831ff668cbb327b93c300b41da4852e5547bea8342d518dd9311aaeb5f90eccf66d548f9275631f0b1fd4b299cec5d2e86a59e55dc7b3afab6204447b21d1ef1da824abaf31a25a0d6135c4fe81d34a06816c8a6eab19141f5687108500f3719a862af8c5fee36e130c69921e11ce83dfc72c5ec3b862c1bccc5fd63ad57f432fbcca6f9e18d5a59015950cdf053 +[tv] pwhash failure (maybe intentional): [6] +e942951dfbc2d508294b10f9e97b47d0cd04e668a043cb95679cc1139df7c27cd54367688725be9d069f5704c12223e7e4ca181fbd0bed18bb4634795e545a6c04a7306933a41a794baedbb628d41bc285e0b9084055ae136f6b63624c874f5a1e1d8be7b0b7227a171d2d7ed578d88bfdcf18323198962d0dcad4126fd3f21adeb1e11d66252ea0c58c91696e91031bfdcc2a9dc0e028d17b9705ba2d7bcdcd1e3ba75b4b1fea +fd329873387429cb79faaec4f65c35649f65de0aabc1f092ca9dee20029d8ae6c3a97e9940763e1703a7fef5a20eb7f210123fc8c6d3f1745d19d5e3c1eb392ab4a6070c8a6b9ecbeabae0711326e81530099541a882d4bd7733c4a7477ae72b6928c46cd07264172a9d2cfb7d649594f877f8b447d9c01b17996b85db5a71f733f8cc5fd0436540a5b7a1d79de09e20c3abe6515501b3156cd51e +bbbc4c7963593601d4d685ed9d89682374f8e6b3ce92ce8ccc702728ec8bf839fd7cb8e37ddb09be8c18c7e0ed099949665227a00fb33e1f63ca830dbeb13b29d987b445b3e081cd8428bdb2f9e003e12bea98230fd30842fa193af9169171b550322072c88330ea464cbe02b6ee044374d3f3d174c23617b707159a11926c56601123dcc30508ec84fdb0797b7ab23a77eeefb2a0be2ef45e903c +OK diff --git a/external/src/libsodium/test/default/pwhash_argon2id.c b/external/src/libsodium/test/default/pwhash_argon2id.c new file mode 100644 index 0000000..9546349 --- /dev/null +++ b/external/src/libsodium/test/default/pwhash_argon2id.c @@ -0,0 +1,503 @@ + +#define TEST_NAME "pwhash_argon2id" +#include "cmptest.h" + +#define OUT_LEN 128 +#define OPSLIMIT 3 +#define MEMLIMIT 5000000 + +static void +tv(void) +{ + static struct { + const char * passwd_hex; + size_t passwd_len; + const char * salt_hex; + size_t outlen; + unsigned long long opslimit; + size_t memlimit; + unsigned int lanes; + } tests[] = { + { "a347ae92bce9f80f6f595a4480fc9c2fe7e7d7148d371e9487d75f5c23008ffae0" + "65577a928febd9b1973a5a95073acdbeb6a030cfc0d79caa2dc5cd011cef02c08d" + "a232d76d52dfbca38ca8dcbd665b17d1665f7cf5fe59772ec909733b24de97d6f5" + "8d220b20c60d7c07ec1fd93c52c31020300c6c1facd77937a597c7a6", + 127, + "5541fbc995d5c197ba290346d2c559dedf405cf97e5f95482143202f9e74f5c2", + 155, 5, 7256678, 1 }, + { "e125cee61c8cb7778d9e5ad0a6f5d978ce9f84de213a8556d9ffe202020ab4a6ed" + "9074a4eb3416f9b168f137510f3a30b70b96cbfa219ff99f6c6eaffb15c06b60e0" + "0cc2890277f0fd3c622115772f7048adaebed86e", + 86, + "f1192dd5dc2368b9cd421338b22433455ee0a3699f9379a08b9650ea2c126f0d", + 250, 4, 7849083, 1 }, + { "92263cbf6ac376499f68a4289d3bb59e5a22335eba63a32e6410249155b956b6a3" + "b48d4a44906b18b897127300b375b8f834f1ceffc70880a885f47c33876717e392" + "be57f7da3ae58da4fd1f43daa7e44bb82d3717af4319349c24cd31e46d295856b0" + "441b6b289992a11ced1cc3bf3011604590244a3eb737ff221129215e4e4347f491" + "5d41292b5173d196eb9add693be5319fdadc242906178bb6c0286c9b6ca6012746" + "711f58c8c392016b2fdfc09c64f0f6b6ab7b", + 183, + "3b840e20e9555e9fb031c4ba1f1747ce25cc1d0ff664be676b9b4a90641ff194", + 249, 3, 7994791, 1 }, + { "027b6d8e8c8c474e9b69c7d9ed4f9971e8e1ce2f6ba95048414c3970f0f09b70e3" + "b6c5ae05872b3d8678705b7d381829c351a5a9c88c233569b35d6b0b809df44b64" + "51a9c273f1150e2ef8a0b5437eb701e373474cd44b97ef0248ebce2ca0400e1b53" + "f3d86221eca3f18eb45b702b9172440f774a82cbf1f6f525df30a6e293c873cce6" + "9bb078ed1f0d31e7f9b8062409f37f19f8550aae", + 152, + "eb2a3056a09ad2d7d7f975bcd707598f24cd32518cde3069f2e403b34bfee8a5", 5, + 4, 1397645, 1 }, + { "4a857e2ee8aa9b6056f2424e84d24a72473378906ee04a46cb05311502d5250b82" + "ad86b83c8f20a23dbb74f6da60b0b6ecffd67134d45946ac8ebfb3064294bc097d" + "43ced68642bfb8bbbdd0f50b30118f5e", + 82, + "39d82eef32010b8b79cc5ba88ed539fbaba741100f2edbeca7cc171ffeabf258", + 190, 3, 1432947, 1 }, + { "c7b09aec680e7b42fedd7fc792e78b2f6c1bea8f4a884320b648f81e8cf515e8ba" + "9dcfb11d43c4aae114c1734aa69ca82d44998365db9c93744fa28b63fd16000e82" + "61cbbe083e7e2da1e5f696bde0834fe53146d7e0e35e7de9920d041f5a5621aabe" + "02da3e2b09b405b77937efef3197bd5772e41fdb73fb5294478e45208063b5f58e" + "089dbeb6d6342a909c1307b3fff5fe2cf4da56bdae50848f", + 156, + "039c056d933b475032777edbaffac50f143f64c123329ed9cf59e3b65d3f43b6", + 178, 3, 4886999, 1 }, + { "b540beb016a5366524d4605156493f9874514a5aa58818cd0c6dfffaa9e90205f1" + "7b", + 34, + "44071f6d181561670bda728d43fb79b443bb805afdebaf98622b5165e01b15fb", + 231, 1, 1631659, 1 }, + { "a14975c26c088755a8b715ff2528d647cd343987fcf4aa25e7194a8417fb2b4b3f" + "7268da9f3182b4cfb22d138b2749d673a47ecc7525dd15a0a3c66046971784bb63" + "d7eae24cc84f2631712075a10e10a96b0e0ee67c43e01c423cb9c44e5371017e9c" + "496956b632158da3fe12addecb88912e6759bc37f9af2f45af72c5cae3b179ffb6" + "76a697de6ebe45cd4c16d4a9d642d29ddc0186a0a48cb6cd62bfc3dd229d313b30" + "1560971e740e2cf1f99a9a090a5b283f35475057e96d7064e2e0fc81984591068d" + "55a3b4169f22cccb0745a2689407ea1901a0a766eb99", + 220, + "3d968b2752b8838431165059319f3ff8910b7b8ecb54ea01d3f54769e9d98daf", + 167, 3, 1784128, 1 }, + }; + char passwd[256]; + unsigned char salt[crypto_pwhash_SALTBYTES]; + unsigned char out[256]; + char out_hex[256 * 2 + 1]; + size_t i = 0U; + + do { + sodium_hex2bin((unsigned char *) passwd, sizeof passwd, + tests[i].passwd_hex, strlen(tests[i].passwd_hex), NULL, + NULL, NULL); + sodium_hex2bin(salt, sizeof salt, tests[i].salt_hex, + strlen(tests[i].salt_hex), NULL, NULL, NULL); + if (crypto_pwhash(out, (unsigned long long) tests[i].outlen, passwd, + tests[i].passwd_len, (const unsigned char *) salt, + tests[i].opslimit, tests[i].memlimit, + crypto_pwhash_alg_default()) != 0) { + printf("[tv] pwhash failure (maybe intentional): [%u]\n", + (unsigned int) i); + continue; + } + sodium_bin2hex(out_hex, sizeof out_hex, out, tests[i].outlen); + printf("%s\n", out_hex); + } while (++i < (sizeof tests) / (sizeof tests[0])); +} + +static void +tv2(void) +{ + static struct { + const char * passwd_hex; + size_t passwd_len; + const char * salt_hex; + size_t outlen; + unsigned long long opslimit; + size_t memlimit; + unsigned int lanes; + } tests[] = { + { "a347ae92bce9f80f6f595a4480fc9c2fe7e7d7148d371e9487d75f5c23008ffae0" + "65577a928febd9b1973a5a95073acdbeb6a030cfc0d79caa2dc5cd011cef02c08d" + "a232d76d52dfbca38ca8dcbd665b17d1665f7cf5fe59772ec909733b24de97d6f5" + "8d220b20c60d7c07ec1fd93c52c31020300c6c1facd77937a597c7a6", + 127, + "5541fbc995d5c197ba290346d2c559dedf405cf97e5f95482143202f9e74f5c2", + 155, 4, 397645, 1 }, + { "a347ae92bce9f80f6f595a4480fc9c2fe7e7d7148d371e9487d75f5c23008ffae0" + "65577a928febd9b1973a5a95073acdbeb6a030cfc0d79caa2dc5cd011cef02c08d" + "a232d76d52dfbca38ca8dcbd665b17d1665f7cf5fe59772ec909733b24de97d6f5" + "8d220b20c60d7c07ec1fd93c52c31020300c6c1facd77937a597c7a6", + 127, + "5541fbc995d5c197ba290346d2c559dedf405cf97e5f95482143202f9e74f5c2", + 155, 3, 397645, 1 }, + }; + char passwd[256]; + unsigned char salt[crypto_pwhash_SALTBYTES]; + unsigned char out[256]; + char out_hex[256 * 2 + 1]; + size_t i = 0U; + + do { + sodium_hex2bin((unsigned char *) passwd, sizeof passwd, + tests[i].passwd_hex, strlen(tests[i].passwd_hex), NULL, + NULL, NULL); + sodium_hex2bin(salt, sizeof salt, tests[i].salt_hex, + strlen(tests[i].salt_hex), NULL, NULL, NULL); + if (crypto_pwhash(out, (unsigned long long) tests[i].outlen, passwd, + tests[i].passwd_len, (const unsigned char *) salt, + tests[i].opslimit, tests[i].memlimit, + crypto_pwhash_alg_default()) != 0) { + printf("[tv2] pwhash failure: [%u]\n", (unsigned int) i); + continue; + } + sodium_bin2hex(out_hex, sizeof out_hex, out, tests[i].outlen); + printf("%s\n", out_hex); + } while (++i < (sizeof tests) / (sizeof tests[0])); + + if (crypto_pwhash_argon2id(out, sizeof out, "password", strlen("password"), salt, 3, + 1ULL << 12, 0) != -1) { + printf("[tv2] pwhash should have failed (0)\n"); + } + if (crypto_pwhash_argon2id(out, sizeof out, "password", strlen("password"), salt, 3, + 1, crypto_pwhash_argon2id_alg_argon2id13()) != -1) { + printf("[tv2] pwhash should have failed (1)\n"); + } + if (crypto_pwhash_argon2id(out, sizeof out, "password", strlen("password"), salt, 3, + 1ULL << 12, crypto_pwhash_argon2id_alg_argon2id13()) != -1) { + printf("[tv2] pwhash should have failed (2)\n"); + } + if (crypto_pwhash_argon2id(out, sizeof out, "password", strlen("password"), salt, 2, + 1ULL << 12, crypto_pwhash_argon2id_alg_argon2id13()) != -1) { + printf("[tv2] pwhash should have failed (3)\n"); + } + if (crypto_pwhash_argon2id(out, 15, "password", strlen("password"), salt, 3, + 1ULL << 12, crypto_pwhash_argon2id_alg_argon2id13()) != -1) { + printf("[tv2] pwhash with a short output length should have failed\n"); + } + if (crypto_pwhash_argon2id(out, sizeof out, "password", 0x100000000ULL, salt, 3, + 1ULL << 12, crypto_pwhash_argon2id_alg_argon2id13()) != -1) { + printf("[tv2] pwhash with a long password length should have failed\n"); + } + assert(crypto_pwhash_argon2id(out, sizeof out, "password", strlen("password"), salt, + OPSLIMIT, MEMLIMIT, crypto_pwhash_alg_argon2i13()) == -1); +} + +static void +tv3(void) +{ + static struct { + const char *passwd; + const char *out; + } tests[] = { + { "", + "$argon2id$v=19$m=4096,t=0,p=1$X1NhbHQAAAAAAAAAAAAAAA$bWh++MKN1OiFHKgIWTLvIi1iHicmHH7+Fv3K88ifFfI" }, + { "", + "$argon2id$v=19$m=2048,t=4,p=1$SWkxaUhpY21ISDcrRnYzSw$Mbg/Eck1kpZir5T9io7C64cpffdTBaORgyriLQFgQj8" }, + { "", + "$argon2id$v=19$m=4882,t=2,p=1$bA81arsiXysd3WbTRzmEOw$Nm8QBM+7RH1DXo9rvp5cwKEOOOfD2g6JuxlXihoNcpE" }, + { "^T5H$JYt39n%K*j:W]!1s?vg!:jGi]Ax?..l7[p0v:1jHTpla9;]bUN;?bWyCbtqg ", + "$argon2id$v=19$m=4096,t=0,p=1$PkEgMTYtYnl0ZXMgc2FsdA$ltB/ue1kPtBMBGfsysMpPigE6hiNEKZ9vs8vLNVDQGA" }, + { "^T5H$JYt39n%K*j:W]!1s?vg!:jGi]Ax?..l7[p0v:1jHTpla9;]bUN;?bWyCbtqg ", + "$argon2id$v=19$m=4096,t=19,p=1$PkEgMTYtYnl0ZXMgc2FsdA$ltB/ue1kPtBMBGfsysMpPigE6hiNEKZ9vs8vLNVDQGA" }, + { "K3S=KyH#)36_?]LxeR8QNKw6X=gFbxai$C%29V*", + "$argon2id$v=19$m=4096,t=1,p=3$PkEgcHJldHR5IGxvbmcgc2FsdA$HUqx5Z1b/ZypnUrvvJ5UC2Q+T6Q1WwASK/Kr9dRbGA0" } + }; + char *out; + char *passwd; + size_t i = 0U; + int ret; + + do { + out = (char *) sodium_malloc(strlen(tests[i].out) + 1U); + assert(out != NULL); + memcpy(out, tests[i].out, strlen(tests[i].out) + 1U); + passwd = (char *) sodium_malloc(strlen(tests[i].passwd) + 1U); + assert(passwd != NULL); + memcpy(passwd, tests[i].passwd, strlen(tests[i].passwd) + 1U); + ret = crypto_pwhash_str_verify(out, passwd, strlen(passwd)); + sodium_free(out); + sodium_free(passwd); + if (ret != 0) { + printf("[tv3] pwhash_argon2id_str failure (maybe intentional): [%u]\n", + (unsigned int) i); + } + } while (++i < (sizeof tests) / (sizeof tests[0])); +} + +static void +str_tests(void) +{ + char *str_out; + char *str_out2; + char *salt; + const char *passwd = "Correct Horse Battery Staple"; + + salt = (char *) sodium_malloc(crypto_pwhash_argon2id_SALTBYTES); + str_out = (char *) sodium_malloc(crypto_pwhash_argon2id_STRBYTES); + str_out2 = (char *) sodium_malloc(crypto_pwhash_argon2id_STRBYTES); + memcpy(salt, ">A 16-bytes salt", crypto_pwhash_argon2id_SALTBYTES); + if (crypto_pwhash_str(str_out, passwd, strlen(passwd), OPSLIMIT, + MEMLIMIT) != 0) { + printf("pwhash_str failure\n"); + } + if (crypto_pwhash_str(str_out2, passwd, strlen(passwd), OPSLIMIT, + MEMLIMIT) != 0) { + printf("pwhash_str(2) failure\n"); + } + if (strcmp(str_out, str_out2) == 0) { + printf("pwhash_str() doesn't generate different salts\n"); + } + if (crypto_pwhash_str_needs_rehash(str_out, OPSLIMIT, MEMLIMIT) != 0 || + crypto_pwhash_str_needs_rehash(str_out, OPSLIMIT, MEMLIMIT) != 0) { + printf("needs_rehash() false positive\n"); + } + if (crypto_pwhash_str_needs_rehash(str_out, OPSLIMIT, MEMLIMIT / 2) != 1 || + crypto_pwhash_str_needs_rehash(str_out, OPSLIMIT - 1, MEMLIMIT) != 1 || + crypto_pwhash_str_needs_rehash(str_out, OPSLIMIT, MEMLIMIT * 2) != 1 || + crypto_pwhash_str_needs_rehash(str_out, OPSLIMIT + 1, MEMLIMIT) != 1) { + printf("needs_rehash() false negative (0)\n"); + } + if (crypto_pwhash_argon2id_str_needs_rehash(str_out, OPSLIMIT, MEMLIMIT / 2) != 1 || + crypto_pwhash_argon2id_str_needs_rehash(str_out, OPSLIMIT - 1, MEMLIMIT) != 1 || + crypto_pwhash_argon2id_str_needs_rehash(str_out, OPSLIMIT, MEMLIMIT * 2) != 1 || + crypto_pwhash_argon2id_str_needs_rehash(str_out, OPSLIMIT + 1, MEMLIMIT) != 1) { + printf("needs_rehash() false negative (1)\n"); + } + if (crypto_pwhash_argon2i_str_needs_rehash(str_out, OPSLIMIT, MEMLIMIT / 2) != -1 || + crypto_pwhash_argon2i_str_needs_rehash(str_out, OPSLIMIT - 1, MEMLIMIT) != -1 || + crypto_pwhash_argon2i_str_needs_rehash(str_out, OPSLIMIT, MEMLIMIT * 2) != -1 || + crypto_pwhash_argon2i_str_needs_rehash(str_out, OPSLIMIT + 1, MEMLIMIT) != -1) { + printf("needs_rehash() false negative (2)\n"); + } + if (crypto_pwhash_str_needs_rehash(str_out, OPSLIMIT, MEMLIMIT / 2) != 1) { + printf("pwhash_str_needs_rehash() didn't handle argon2id\n"); + } + if (crypto_pwhash_str_needs_rehash(str_out + 1, OPSLIMIT, MEMLIMIT) != -1 || + crypto_pwhash_argon2id_str_needs_rehash(str_out + 1, OPSLIMIT, MEMLIMIT) != -1) { + printf("needs_rehash() didn't fail with an invalid hash string\n"); + } + if (sodium_is_zero((const unsigned char *) str_out + strlen(str_out), + crypto_pwhash_STRBYTES - strlen(str_out)) != 1 || + sodium_is_zero((const unsigned char *) str_out2 + strlen(str_out2), + crypto_pwhash_STRBYTES - strlen(str_out2)) != 1) { + printf("pwhash_argon2id_str() doesn't properly pad with zeros\n"); + } + if (crypto_pwhash_argon2id_str_verify(str_out, passwd, strlen(passwd)) != 0) { + printf("pwhash_argon2id_str_verify(1) failure\n"); + } + if (crypto_pwhash_str_verify(str_out, passwd, strlen(passwd)) != 0) { + printf("pwhash_str_verify(1') failure\n"); + } + str_out[14]++; + if (crypto_pwhash_str_verify(str_out, passwd, strlen(passwd)) != -1) { + printf("pwhash_argon2id_str_verify(2) failure\n"); + } + str_out[14]--; + assert(str_out[crypto_pwhash_argon2id_STRBYTES - 1U] == 0); + + if (crypto_pwhash_str(str_out2, passwd, 0x100000000ULL, OPSLIMIT, + MEMLIMIT) != -1) { + printf("pwhash_str() with a large password should have failed\n"); + } + if (crypto_pwhash_str(str_out2, passwd, strlen(passwd), 1, MEMLIMIT) != 0) { + printf("pwhash_str() with a small opslimit should not have failed\n"); + } + if (crypto_pwhash_str(str_out2, passwd, strlen(passwd), 0, MEMLIMIT) != -1) { + printf("pwhash_argon2id_str() with a null opslimit should have failed\n"); + } + if (crypto_pwhash_str_verify("$argon2id$m=65536,t=2,p=1c29tZXNhbHQ" + "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", + "password", 0x100000000ULL) != -1) { + printf("pwhash_str_verify(invalid(0)) failure\n"); + } + if (crypto_pwhash_str_verify("$argon2id$m=65536,t=2,p=1c29tZXNhbHQ" + "$9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", + "password", strlen("password")) != -1) { + printf("pwhash_str_verify(invalid(1)) failure %d\n", errno); + } + if (crypto_pwhash_str_verify("$argon2id$m=65536,t=2,p=1$c29tZXNhbHQ" + "9sTbSlTio3Biev89thdrlKKiCaYsjjYVJxGAL3swxpQ", + "password", strlen("password")) != -1) { + printf("pwhash_str_verify(invalid(2)) failure\n"); + } + if (crypto_pwhash_str_verify("$argon2id$m=65536,t=2,p=1$c29tZXNhbHQ" + "$b2G3seW+uPzerwQQC+/E1K50CLLO7YXy0JRcaTuswRo", + "password", strlen("password")) != -1) { + printf("pwhash_str_verify(invalid(3)) failure\n"); + } + if (crypto_pwhash_str_verify("$argon2id$v=19$m=65536,t=2,p=1c29tZXNhbHQ" + "$wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA", + "password", strlen("password")) != -1) { + printf("pwhash_str_verify(invalid(4)) failure\n"); + } + if (crypto_pwhash_str_verify("$argon2id$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" + "wWKIMhR9lyDFvRz9YTZweHKfbftvj+qf+YFY4NeBbtA", + "password", strlen("password")) != -1) { + printf("pwhash_str_verify(invalid(5)) failure\n"); + } + if (crypto_pwhash_str_verify("$argon2id$v=19$m=65536,t=2,p=1$c29tZXNhbHQ" + "$8iIuixkI73Js3G1uMbezQXD0b8LG4SXGsOwoQkdAQIM", + "password", strlen("password")) != -1) { + printf("pwhash_str_verify(invalid(6)) failure\n"); + } + if (crypto_pwhash_str_verify("$argon2id$v=19$m=256,t=3,p=1$MDEyMzQ1Njc" + "$G5ajKFCoUzaXRLdz7UJb5wGkb2Xt+X5/GQjUYtS2+TE", + "password", strlen("password")) != 0) { + printf("pwhash_str_verify(valid(7)) failure\n"); + } + if (crypto_pwhash_str_verify("$argon2id$v=19$m=256,t=3,p=1$MDEyMzQ1Njc" + "$G5ajKFCoUzaXRLdz7UJb5wGkb2Xt+X5/GQjUYtS2+TE", + "passwore", strlen("passwore")) != -1 || errno != EINVAL) { + printf("pwhash_str_verify(invalid(7)) failure\n"); + } + if (crypto_pwhash_str_verify("$Argon2id$v=19$m=256,t=3,p=1$MDEyMzQ1Njc" + "$G5ajKFCoUzaXRLdz7UJb5wGkb2Xt+X5/GQjUYtS2+TE", + "password", strlen("password")) != -1 || errno != EINVAL) { + printf("pwhash_str_verify(invalid(8)) failure\n"); + } + if (crypto_pwhash_str_verify("$argon2id$v=19$m=256,t=3,p=2$MDEyMzQ1Njc" + "$G5ajKFCoUzaXRLdz7UJb5wGkb2Xt+X5/GQjUYtS2+TE", + "password", strlen("password")) != -1 || errno != EINVAL) { + printf("pwhash_str_verify(invalid(9)) failure\n"); + } + assert(crypto_pwhash_str_alg(str_out, "test", 4, OPSLIMIT, MEMLIMIT, + crypto_pwhash_ALG_ARGON2ID13) == 0); + assert(crypto_pwhash_argon2id_str_verify(str_out, "test", 4) == 0); + assert(crypto_pwhash_argon2id_str_needs_rehash(str_out, + OPSLIMIT, MEMLIMIT) == 0); + assert(crypto_pwhash_argon2id_str_needs_rehash(str_out, + OPSLIMIT / 2, MEMLIMIT) == 1); + assert(crypto_pwhash_argon2id_str_needs_rehash(str_out, + OPSLIMIT, MEMLIMIT / 2) == 1); + assert(crypto_pwhash_argon2id_str_needs_rehash(str_out, 0, 0) == 1); + assert(crypto_pwhash_argon2i_str_needs_rehash(str_out, 0, 0) == -1); + assert(crypto_pwhash_argon2id_str_needs_rehash(str_out + 1, + OPSLIMIT, MEMLIMIT) == -1); + assert(crypto_pwhash_argon2i_str_needs_rehash(str_out, 0, 0) == -1); + assert(crypto_pwhash_argon2i_str_needs_rehash("", OPSLIMIT, MEMLIMIT) == -1); + assert(crypto_pwhash_str_alg(str_out, "test", 4, OPSLIMIT, MEMLIMIT, + crypto_pwhash_ALG_ARGON2I13) == 0); + assert(crypto_pwhash_argon2i_str_verify(str_out, "test", 4) == 0); + assert(crypto_pwhash_argon2i_str_needs_rehash(str_out, + OPSLIMIT, MEMLIMIT) == 0); + assert(crypto_pwhash_argon2i_str_needs_rehash(str_out, + OPSLIMIT / 2, MEMLIMIT) == 1); + assert(crypto_pwhash_argon2i_str_needs_rehash(str_out, + OPSLIMIT, MEMLIMIT / 2) == 1); + assert(crypto_pwhash_argon2i_str_needs_rehash(str_out, 0, 0) == 1); + assert(crypto_pwhash_argon2id_str_needs_rehash(str_out, 0, 0) == -1); + assert(crypto_pwhash_argon2i_str_needs_rehash("", OPSLIMIT, MEMLIMIT) == -1); + assert(crypto_pwhash_argon2i_str_needs_rehash(str_out + 1, + OPSLIMIT, MEMLIMIT) == -1); + sodium_free(salt); + sodium_free(str_out); + sodium_free(str_out2); +} + +int +main(void) +{ + tv(); + tv2(); + tv3(); + str_tests(); + + assert(crypto_pwhash_bytes_min() > 0U); + assert(crypto_pwhash_bytes_max() > crypto_pwhash_bytes_min()); + assert(crypto_pwhash_passwd_max() > crypto_pwhash_passwd_min()); + assert(crypto_pwhash_saltbytes() > 0U); + assert(crypto_pwhash_strbytes() > 1U); + assert(crypto_pwhash_strbytes() > strlen(crypto_pwhash_strprefix())); + + assert(crypto_pwhash_opslimit_min() > 0U); + assert(crypto_pwhash_opslimit_max() > 0U); + assert(crypto_pwhash_memlimit_min() > 0U); + assert(crypto_pwhash_memlimit_max() > 0U); + assert(crypto_pwhash_opslimit_interactive() > 0U); + assert(crypto_pwhash_memlimit_interactive() > 0U); + assert(crypto_pwhash_opslimit_moderate() > 0U); + assert(crypto_pwhash_memlimit_moderate() > 0U); + assert(crypto_pwhash_opslimit_sensitive() > 0U); + assert(crypto_pwhash_memlimit_sensitive() > 0U); + assert(strcmp(crypto_pwhash_primitive(), "argon2i") == 0); + + assert(crypto_pwhash_bytes_min() == crypto_pwhash_BYTES_MIN); + assert(crypto_pwhash_bytes_max() == crypto_pwhash_BYTES_MAX); + assert(crypto_pwhash_passwd_min() == crypto_pwhash_PASSWD_MIN); + assert(crypto_pwhash_passwd_max() == crypto_pwhash_PASSWD_MAX); + assert(crypto_pwhash_saltbytes() == crypto_pwhash_SALTBYTES); + assert(crypto_pwhash_strbytes() == crypto_pwhash_STRBYTES); + + assert(crypto_pwhash_opslimit_min() == crypto_pwhash_OPSLIMIT_MIN); + assert(crypto_pwhash_opslimit_max() == crypto_pwhash_OPSLIMIT_MAX); + assert(crypto_pwhash_memlimit_min() == crypto_pwhash_MEMLIMIT_MIN); + assert(crypto_pwhash_memlimit_max() == crypto_pwhash_MEMLIMIT_MAX); + assert(crypto_pwhash_opslimit_interactive() == + crypto_pwhash_OPSLIMIT_INTERACTIVE); + assert(crypto_pwhash_memlimit_interactive() == + crypto_pwhash_MEMLIMIT_INTERACTIVE); + assert(crypto_pwhash_opslimit_moderate() == + crypto_pwhash_OPSLIMIT_MODERATE); + assert(crypto_pwhash_memlimit_moderate() == + crypto_pwhash_MEMLIMIT_MODERATE); + assert(crypto_pwhash_opslimit_sensitive() == + crypto_pwhash_OPSLIMIT_SENSITIVE); + assert(crypto_pwhash_memlimit_sensitive() == + crypto_pwhash_MEMLIMIT_SENSITIVE); + + assert(crypto_pwhash_argon2id_bytes_min() == crypto_pwhash_bytes_min()); + assert(crypto_pwhash_argon2id_bytes_max() == crypto_pwhash_bytes_max()); + assert(crypto_pwhash_argon2id_passwd_min() == crypto_pwhash_passwd_min()); + assert(crypto_pwhash_argon2id_passwd_max() == crypto_pwhash_passwd_max()); + assert(crypto_pwhash_argon2id_saltbytes() == crypto_pwhash_saltbytes()); + assert(crypto_pwhash_argon2id_strbytes() == crypto_pwhash_strbytes()); + assert(strcmp(crypto_pwhash_argon2id_strprefix(), + crypto_pwhash_strprefix()) == 0); + assert(crypto_pwhash_argon2id_opslimit_min() == + crypto_pwhash_opslimit_min()); + assert(crypto_pwhash_argon2id_opslimit_max() == + crypto_pwhash_opslimit_max()); + assert(crypto_pwhash_argon2id_memlimit_min() == + crypto_pwhash_memlimit_min()); + assert(crypto_pwhash_argon2id_memlimit_max() == + crypto_pwhash_memlimit_max()); + assert(crypto_pwhash_argon2id_opslimit_interactive() == + crypto_pwhash_opslimit_interactive()); + assert(crypto_pwhash_argon2id_opslimit_moderate() == + crypto_pwhash_opslimit_moderate()); + assert(crypto_pwhash_argon2id_opslimit_sensitive() == + crypto_pwhash_opslimit_sensitive()); + assert(crypto_pwhash_argon2id_memlimit_interactive() == + crypto_pwhash_memlimit_interactive()); + assert(crypto_pwhash_argon2id_memlimit_moderate() == + crypto_pwhash_memlimit_moderate()); + assert(crypto_pwhash_argon2id_memlimit_sensitive() == + crypto_pwhash_memlimit_sensitive()); + assert(crypto_pwhash_alg_argon2id13() == + crypto_pwhash_argon2id_alg_argon2id13()); + assert(crypto_pwhash_alg_argon2i13() == crypto_pwhash_ALG_ARGON2I13); + assert(crypto_pwhash_alg_argon2i13() != crypto_pwhash_alg_default()); + assert(crypto_pwhash_alg_argon2id13() == crypto_pwhash_ALG_ARGON2ID13); + assert(crypto_pwhash_alg_argon2id13() != crypto_pwhash_alg_argon2i13()); + assert(crypto_pwhash_alg_argon2id13() == crypto_pwhash_alg_default()); + + assert(crypto_pwhash_argon2id(guard_page, 0, (const char *) guard_page, 0, guard_page, + crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE, + crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE, + 0) == -1); + assert(crypto_pwhash_argon2id(guard_page, 0, (const char *) guard_page, 0, guard_page, + crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE, + crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE, + crypto_pwhash_ALG_ARGON2I13) == -1); + assert(crypto_pwhash_argon2i(guard_page, 0, (const char *) guard_page, 0, guard_page, + crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE, + crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE, + 0) == -1); + assert(crypto_pwhash_argon2i(guard_page, 0, (const char *) guard_page, 0, guard_page, + crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE, + crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE, + crypto_pwhash_ALG_ARGON2ID13) == -1); + + printf("OK\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/pwhash_argon2id.exp b/external/src/libsodium/test/default/pwhash_argon2id.exp new file mode 100644 index 0000000..a259827 --- /dev/null +++ b/external/src/libsodium/test/default/pwhash_argon2id.exp @@ -0,0 +1,14 @@ +18acec5d6507739f203d1f5d9f1d862f7c2cdac4f19d2bdff64487e60d969e3ced615337b9eec6ac4461c6ca07f0939741e57c24d0005c7ea171a0ee1e7348249d135b38f222e4dad7b9a033ed83f5ca27277393e316582033c74affe2566a2bea47f91f0fd9fe49ece7e1f79f3ad6e9b23e0277c8ecc4b313225748dd2a80f5679534a0700e246a79a49b3f74eb89ec6205fe1eeb941c73b1fcf1 +26bab5f101560e48c711da4f05e81f5a3802b7a93d5155b9cab153069cc42b8e9f910bfead747652a0708d70e4de0bada37218bd203a1201c36b42f9a269b675b1f30cfc36f35a3030e9c7f57dfba0d341a974c1886f708c3e8297efbfe411bb9d51375264bd7c70d57a8a56fc9de2c1c97c08776803ec2cd0140bba8e61dc0f4ad3d3d1a89b4b710af81bfe35a0eea193e18a6da0f5ec05542c9eefc4584458e1da715611ba09617384748bd43b9bf1f3a6df4ecd091d0875e08d6e2fd8a5c7ce08904b5160cd38167b76ec76ef2d310049055a564da23d4ebd2b87e421cc33c401e12d5cd8d936c9baf75ebdfb557d342d2858fc781da31860 +6eb45e668582d63788ca8f6e930ca60b045a795fca987344f9a7a135aa3b5132b50a34a3864c26581f1f56dd0bcbfafbfa92cd9bff6b24a734cfe88f854aef4bda0a7983120f44936e8ff31d29728ac08ccce6f3f916b3c63962755c23a1fa9bb4e8823fc867bfd18f28980d94bc5874423ab7f96cc0ab78d8fa21fbd00cd3a1d96a73fa439ccc3fc4eab1590677b06cc78b0f674dfb680f23022fb902022dd8620803229c6ddf79a8156ccfce48bbd76c05ab670634f206e5b2e896230baa74a856964dbd8511acb71d75a1506766a125d8ce037f1db72086ebc3bccaefbd8cd9380167c2530386544ebfbeadbe237784d102bb92a10fd242 +[tv] pwhash failure (maybe intentional): [3] +08d8cd330c57e1b4643241d05bb468ba4ee4e932cd0858816be9ef15360b27bbd06a87130ee92222be267a29b81f5ae8fe8613324cfc4832dc49387fd0602f1c57b4d0f3855db94fb7e12eb05f9a484aed4a4307abf586cd3d55c809bc081541e00b682772fb2066504ff935b8ebc551a2083882f874bc0fae68e56848ae34c91097c3bf0cca8e75c0797eef3efde3f75e005815018db3cf7c109a812264c4de69dcb22322dbbcfa447f5b00ecd1b04a7be1569c8e556adb7bba48adf81d +d6e9d6cabd42fb9ba7162fe9b8e41d59d3c7034756cb460c9affe393308bd0225ce0371f2e6c3ca32aca2002bf2d3909c6b6e7dfc4a00e850ff4f570f8f749d4bb6f0091e554be67a9095ae1eefaa1a933316cbec3c2fd4a14a5b6941bda9b7eabd821d79abde2475a53af1a8571c7ee46460be415882e0b393f48c12f740a6a72cba9773000602e13b40d3dfa6ac1d4ec43a838b7e3e165fecad4b2498389e60a3ff9f0f8f4b9fca1126e64f49501e38690 +7fb72409b0987f8190c3729710e98c3f80c5a8727d425fdcde7f3644d467fe973f5b5fee683bd3fce812cb9ae5e9921a2d06c2f1905e4e839692f2b934b682f11a2fe2b90482ea5dd234863516dba6f52dc0702d324ec77d860c2e181f84472bd7104fedce071ffa93c5309494ad51623d214447a7b2b1462dc7d5d55a1f6fd5b54ce024118d86f0c6489d16545aaa87b6689dad9f2fb47fda9894f8e12b87d978b483ccd4cc5fd9595cdc7a818452f915ce2f7df95ec12b1c72e3788d473441d884f9748eb14703c21b45d82fd667b85f5b2d98c13303b3fe76285531a826b6fc0fe8e3dddecf +4e702bc5f891df884c6ddaa243aa846ce3c087fe930fef0f36b3c2be34164ccc295db509254743f18f947159c813bcd5dd8d94a3aec93bbe57605d1fad1aef1112687c3d4ef1cb329d21f1632f626818d766915d886e8d819e4b0b9c9307f4b6afc081e13b0cf31db382ff1bf05a16aac7af696336d75e99f82163e0f371e1d25c4add808e215697ad3f779a51a462f8bf52610af21fc69dba6b072606f2dabca7d4ae1d91d919 +20e7ba6faa2c0a4b07f3ff38e15e252a069c2c62bac3f2785d311764d73e67fd713be342ee938e6df4de6af1a89a44b8589838864457bcfe3cf0f2d329b800ab9f5810b6325588eb4e0c56f99192b2cc76dc8194dc1097fe5ed12ac4214481c03c3597131ba164a56e7187e2da565a8cd529668e9a37faa58a1701c49a14edf7a50dec4143b456cba6d14c957bb655e99ce96bc506961216ef887a +8fb6ed1862cdd2a399e10956c60dc9b2670338ea59c3414d0443216925ba24c6e89a17f3e56c12893dcbc9bc498e8308aea9627d9c9e47912d6342b631008719edfa2db364b97e60cf47a97ad9aa3b7f139d80ddda44f1ef2af881ce027a15644218cac6cc74751469ae56be0469fbc760825882b3e8abca55daaae5753575106cf867cd69932602c63ec880ad8811d9aa4870a9e0b39fef47c92e +[tv3] pwhash_argon2id_str failure (maybe intentional): [0] +[tv3] pwhash_argon2id_str failure (maybe intentional): [1] +[tv3] pwhash_argon2id_str failure (maybe intentional): [3] +OK diff --git a/external/src/libsodium/test/default/pwhash_scrypt.c b/external/src/libsodium/test/default/pwhash_scrypt.c new file mode 100644 index 0000000..5afe963 --- /dev/null +++ b/external/src/libsodium/test/default/pwhash_scrypt.c @@ -0,0 +1,393 @@ + +#define TEST_NAME "pwhash_scrypt" +#include "cmptest.h" + +#define OUT_LEN 128 +#define OPSLIMIT 1000000 +#define MEMLIMIT 10000000 + +static void +tv(void) +{ + static struct { + const char *passwd_hex; + size_t passwdlen; + const char *salt_hex; + size_t outlen; + unsigned long long opslimit; + size_t memlimit; + } tests[] = { + { "a347ae92bce9f80f6f595a4480fc9c2fe7e7d7148d371e9487d75f5c23008ffae0" + "65577a928febd9b1973a5a95073acdbeb6a030cfc0d79caa2dc5cd011cef02c08d" + "a232d76d52dfbca38ca8dcbd665b17d1665f7cf5fe59772ec909733b24de97d6f5" + "8d220b20c60d7c07ec1fd93c52c31020300c6c1facd77937a597c7a6", + 127, + "5541fbc995d5c197ba290346d2c559dedf405cf97e5f95482143202f9e74f5c2", + 155, 481326, 7256678 }, + { "e125cee61c8cb7778d9e5ad0a6f5d978ce9f84de213a8556d9ffe202020ab4a6ed" + "9074a4eb3416f9b168f137510f3a30b70b96cbfa219ff99f6c6eaffb15c06b60e0" + "0cc2890277f0fd3c622115772f7048adaebed86e", + 86, + "f1192dd5dc2368b9cd421338b22433455ee0a3699f9379a08b9650ea2c126f0d", + 250, 535778, 7849083 }, + { "92263cbf6ac376499f68a4289d3bb59e5a22335eba63a32e6410249155b956b6a3" + "b48d4a44906b18b897127300b375b8f834f1ceffc70880a885f47c33876717e392" + "be57f7da3ae58da4fd1f43daa7e44bb82d3717af4319349c24cd31e46d295856b0" + "441b6b289992a11ced1cc3bf3011604590244a3eb737ff221129215e4e4347f491" + "5d41292b5173d196eb9add693be5319fdadc242906178bb6c0286c9b6ca6012746" + "711f58c8c392016b2fdfc09c64f0f6b6ab7b", + 183, + "3b840e20e9555e9fb031c4ba1f1747ce25cc1d0ff664be676b9b4a90641ff194", + 249, 311757, 7994791 }, + { "027b6d8e8c8c474e9b69c7d9ed4f9971e8e1ce2f6ba95048414c3970f0f09b70e3" + "b6c5ae05872b3d8678705b7d381829c351a5a9c88c233569b35d6b0b809df44b64" + "51a9c273f1150e2ef8a0b5437eb701e373474cd44b97ef0248ebce2ca0400e1b53" + "f3d86221eca3f18eb45b702b9172440f774a82cbf1f6f525df30a6e293c873cce6" + "9bb078ed1f0d31e7f9b8062409f37f19f8550aae", + 152, + "eb2a3056a09ad2d7d7f975bcd707598f24cd32518cde3069f2e403b34bfee8a5", 5, + 643464, 1397645 }, + { "4a857e2ee8aa9b6056f2424e84d24a72473378906ee04a46cb05311502d5250b82" + "ad86b83c8f20a23dbb74f6da60b0b6ecffd67134d45946ac8ebfb3064294bc097d" + "43ced68642bfb8bbbdd0f50b30118f5e", + 82, + "39d82eef32010b8b79cc5ba88ed539fbaba741100f2edbeca7cc171ffeabf258", + 190, 758010, 5432947 }, + { "1845e375479537e9dd4f4486d5c91ac72775d66605eeb11a787b78a7745f1fd005" + "2d526c67235dbae1b2a4d575a74cb551c8e9096c593a497aee74ba3047d911358e" + "de57bc27c9ea1829824348daaab606217cc931dcb6627787bd6e4e5854f0e8", + 97, + "3ee91a805aa62cfbe8dce29a2d9a44373a5006f4a4ce24022aca9cecb29d1473", + 212, 233177, 13101817 }, + { "c7b09aec680e7b42fedd7fc792e78b2f6c1bea8f4a884320b648f81e8cf515e8ba" + "9dcfb11d43c4aae114c1734aa69ca82d44998365db9c93744fa28b63fd16000e82" + "61cbbe083e7e2da1e5f696bde0834fe53146d7e0e35e7de9920d041f5a5621aabe" + "02da3e2b09b405b77937efef3197bd5772e41fdb73fb5294478e45208063b5f58e" + "089dbeb6d6342a909c1307b3fff5fe2cf4da56bdae50848f", + 156, + "039c056d933b475032777edbaffac50f143f64c123329ed9cf59e3b65d3f43b6", + 178, 234753, 4886999 }, + { "8f3a06e2fd8711350a517bb12e31f3d3423e8dc0bb14aac8240fca0995938d59bb" + "37bd0a7dfc9c9cc0705684b46612e8c8b1d6655fb0f9887562bb9899791a0250d1" + "320f945eda48cdc20c233f40a5bb0a7e3ac5ad7250ce684f68fc0b8c9633bfd75a" + "ad116525af7bdcdbbdb4e00ab163fd4df08f243f12557e", + 122, + "90631f686a8c3dbc0703ffa353bc1fdf35774568ac62406f98a13ed8f47595fd", + 55, 695191, 15738350 }, + { "b540beb016a5366524d4605156493f9874514a5aa58818cd0c6dfffaa9e90205f1" + "7b", + 34, + "44071f6d181561670bda728d43fb79b443bb805afdebaf98622b5165e01b15fb", + 231, 78652, 6631659 }, + { "a14975c26c088755a8b715ff2528d647cd343987fcf4aa25e7194a8417fb2b4b3f" + "7268da9f3182b4cfb22d138b2749d673a47ecc7525dd15a0a3c66046971784bb63" + "d7eae24cc84f2631712075a10e10a96b0e0ee67c43e01c423cb9c44e5371017e9c" + "496956b632158da3fe12addecb88912e6759bc37f9af2f45af72c5cae3b179ffb6" + "76a697de6ebe45cd4c16d4a9d642d29ddc0186a0a48cb6cd62bfc3dd229d313b30" + "1560971e740e2cf1f99a9a090a5b283f35475057e96d7064e2e0fc81984591068d" + "55a3b4169f22cccb0745a2689407ea1901a0a766eb99", + 220, + "3d968b2752b8838431165059319f3ff8910b7b8ecb54ea01d3f54769e9d98daf", + 167, 717248, 10784179 }, + }; + char passwd[256]; + unsigned char salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; + unsigned char out[256]; + char out_hex[256 * 2 + 1]; + size_t i = 0U; + + do { + sodium_hex2bin((unsigned char *) passwd, sizeof passwd, + tests[i].passwd_hex, strlen(tests[i].passwd_hex), NULL, + NULL, NULL); + sodium_hex2bin(salt, sizeof salt, tests[i].salt_hex, + strlen(tests[i].salt_hex), NULL, NULL, NULL); + if (crypto_pwhash_scryptsalsa208sha256( + out, (unsigned long long) tests[i].outlen, passwd, + tests[i].passwdlen, (const unsigned char *) salt, + tests[i].opslimit, tests[i].memlimit) != 0) { + printf("pwhash failure\n"); + } + sodium_bin2hex(out_hex, sizeof out_hex, out, tests[i].outlen); + printf("%s\n", out_hex); + } while (++i < (sizeof tests) / (sizeof tests[0])); +} + +static void +tv2(void) +{ + static struct { + const char *passwd_hex; + size_t passwdlen; + const char *salt_hex; + size_t outlen; + unsigned long long opslimit; + size_t memlimit; + } tests[] = { + { "a347ae92bce9f80f6f595a4480fc9c2fe7e7d7148d371e9487d75f5c23008ffae0" + "65577a928febd9b1973a5a95073acdbeb6a030cfc0d79caa2dc5cd011cef02c08d" + "a232d76d52dfbca38ca8dcbd665b17d1665f7cf5fe59772ec909733b24de97d6f5" + "8d220b20c60d7c07ec1fd93c52c31020300c6c1facd77937a597c7a6", + 127, + "5541fbc995d5c197ba290346d2c559dedf405cf97e5f95482143202f9e74f5c2", + 155, 64, 1397645 }, + { "a347ae92bce9f80f6f595a4480fc9c2fe7e7d7148d371e9487d75f5c23008ffae0" + "65577a928febd9b1973a5a95073acdbeb6a030cfc0d79caa2dc5cd011cef02c08d" + "a232d76d52dfbca38ca8dcbd665b17d1665f7cf5fe59772ec909733b24de97d6f5" + "8d220b20c60d7c07ec1fd93c52c31020300c6c1facd77937a597c7a6", + 127, + "5541fbc995d5c197ba290346d2c559dedf405cf97e5f95482143202f9e74f5c2", + 155, 32768, 1397645 }, + }; + char passwd[256]; + unsigned char salt[crypto_pwhash_scryptsalsa208sha256_SALTBYTES]; + unsigned char out[256]; + char out_hex[256 * 2 + 1]; + size_t i = 0U; + + do { + sodium_hex2bin((unsigned char *) passwd, sizeof passwd, + tests[i].passwd_hex, strlen(tests[i].passwd_hex), NULL, + NULL, NULL); + sodium_hex2bin(salt, sizeof salt, tests[i].salt_hex, + strlen(tests[i].salt_hex), NULL, NULL, NULL); + if (crypto_pwhash_scryptsalsa208sha256( + out, (unsigned long long) tests[i].outlen, passwd, + tests[i].passwdlen, (const unsigned char *) salt, + tests[i].opslimit, tests[i].memlimit) != 0) { + printf("pwhash failure\n"); + } + sodium_bin2hex(out_hex, sizeof out_hex, out, tests[i].outlen); + printf("%s\n", out_hex); + } while (++i < (sizeof tests) / (sizeof tests[0])); +} + +static void +tv3(void) +{ + static struct { + const char *passwd; + const char *out; + } tests[] = { + { "^T5H$JYt39n%K*j:W]!1s?vg!:jGi]Ax?..l7[p0v:1jHTpla9;]bUN;?bWyCbtqg " + "nrDFal+Jxl3,2`#^tFSu%v_+7iYse8-cCkNf!tD=KrW)", + "$7$B6....1....75gBMAGwfFWZqBdyF3WdTQnWdUsuTiWjG1fF9c1jiSD$tc8RoB3." + "Em3/zNgMLWo2u00oGIoTyJv4fl3Fl8Tix72" }, + { "bl72h6#y<':MFRZ>B IA1=NRkCKS%W8`1I.2uQxJN0g)N N aTt^4K!Iw5r " + "H6;crDsv^a55j9tsk'/GqweZn;cdk6+F_St6:#*=?ZCD_lw>.", + "$7$A6....3....Iahc6qM0.UQJHVgE4h9oa1/" + "4OWlWLm9CCtfguvz6bQD$QnXCo3M7nIqtry2WKsUZ5gQ.mY0wAlJu." + "WUhtE8vF66" }, + { "Py " + ">e.5b+tLo@rL`dC2k@eJ&4eVl!W=JJ4+k&mAt@gt',FS1JjqKW3aq21:]^kna`" + "mde7kVkN5NrpKUptu)@4*b&?BE_sJMG1=&@`3GBCV]Wg7xwgo7x3El", + "$7$96..../....f6bEusKt79kK4wdYN0ki2nw4bJQ7P3rN6k3BSigsK/" + "D$Dsvuw7vXj5xijmrb/NOhdgoyK/OiSIYv88cEtl9Cik7" }, + { "2vj;Um]FKOL27oam(:Uo8+UmSTvb1FD*h?jk_,S=;RDgF-$Fjk?]9yvfxe@fN^!NN(" + "Cuml?+2Raa", + "$7$86....I....7XwIxLtCx4VphmFeUa6OGuGJrFaIaYzDiLNu/" + "tyUPhD$U3q5GCEqCWxMwh.YQHDJrlg7FIZgViv9pcXE3h1vg61" }, + { "CT=[9uUoGav,J`kU+348tA50ue#sL:ABZ3QgF+r[#vh:tTOiL>s8tv%,Jeo]jH/" + "_4^i(*jD-_ku[9Ko[=86 06V", + "$7$A6....2....R3.bjH6YS9wz9z8Jsj.3weGQ3J80ZZElGw2oVux1TP6$" + "i5u6lFzXDHaIgYEICinLD6WNaovbiXP8SnLrDRdKgA9" }, + { "J#wNn`hDgOpTHNI.w^1a70%f,.9V_m038H_JIJQln`vdWnn/" + "rmILR?9H5g(+`;@H(2VosN9Fgk[WEjaBr'yB9Q19-imNa04[Mk5kvGcSn-TV", + "$7$B6....1....Dj1y.4mF1J9XmT/6IDskYdCLaPFJTq9xcCwXQ1DpT92$92/" + "hYfZLRq1nTLyIz.uc/dC6wLqwnsoqpkadrCXusm6" }, + { "j4BS38Asa;p)[K+9TY!3YDjQw+!qJb]>pP :_.9`dxM9k [eR7Y!yL-3)sNs[R,j_/^ " + "TH=5ny'15>6UXWcQW^6D%XCsO[vN[%ReA-`tV1vW(Nt*0KVK#]45P_A", + "$7$B6....1....D/" + "eyk8N5y6Z8YVQEsw521cTx.9zzLuK7YDs1KMMh.o4$alfW8ZbsUWnXc." + "vqon2zoljVk24Tt1.IsCuo2KurvS2" }, + { "K3S=KyH#)36_?]LxeR8QNKw6X=gFb'ai$C%29V* " + "tyh^Wo$TN-#Q4qkmtTCf0LLb.^E$0uykkP", + "$7$B6....1....CuBuU97xgAage8whp/" + "JNKobo0TFbsORGVbfcQIefyP8$aqalP." + "XofGViB8EPLONqHma8vs1xc9uTIMYh9CgE.S8" }, + { "Y0!?iQa9M%5ekffW(`", + "$7$A6....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$" + "a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5" }, + + /* Invalid pwhash strings */ + + { "Y0!?iQa9M%5ekffW(`", + "$7$A6....1....$TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4" + "a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5" }, + { "Y0!?iQa9M%5ekffW(`", + "$7$.6....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$" + "a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5" }, + { "Y0!?iQa9M%5ekffW(`", + "$7$A.....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$" + "a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5" }, + { "Y0!?iQa9M%5ekffW(`", + "$7$A6.........TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$" + "a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5" }, + { "Y0!?iQa9M%5ekffW(`", + "$7$A6....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i44269$" + "a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AH" }, + { "Y0!?iQa9M%5ekffW(`", + "$7$A6....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$" + "a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx54269" }, + { "Y0!?iQa9M%5ekffW(`", + "$7^A6....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$" + "a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5" }, + { "Y0!?iQa9M%5ekffW(`", + "$7$!6....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$" + "a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5" }, + { "Y0!?iQa9M%5ekffW(`", + "$7$A!....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$" + "a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5" }, + { "Y0!?iQa9M%5ekffW(`", + "$7$A6....!....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$" + "a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5" }, + { "", + "$7$A6....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$" + "a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5" }, + { "Y0!?iQa9M%5ekffW(`", + "$7fA6....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4#" + "a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5" }, + { "Y0!?iQa9M%5ekffW(`", + "$7$AX....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$" + "a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5" }, + { "Y0!?iQa9M%5ekffW(`", + "$7$A6....1!...TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$" + "a4ik5hGDN7foMuHOW.cp.CtX01UyCeO0.JAG.AHPpx5" }, + { "Y0!?iQa9M%5ekffW(`", "$7$A6....1" }, + { "Y0!?iQa9M%5ekffW(`", "$7$" }, + { "Y0!?iQa9M%5ekffW(`", "" }, + { "Y0!?iQa9M%5ekffW(`", + "$7$A6....1....TrXs5Zk6s8sWHpQgWDIXTR8kUU3s6Jc3s.DtdS8M2i4$" }, + { "test", + "$7$.6..../.....lgPchkGHqbeONR/xtuXyjCrt9kUSg6NlKFQO0OSxo/$.DbajbPYH9T7sg3fOtcgxvJzzfIgJBIxMkeQ8b24YQ." }, + { "test", + "$7$z6..../.....lgPchkGHqbeONR/xtuXyjCrt9kUSg6NlKFQO0OSxo/$.DbajbPYH9T7sg3fOtcgxvJzzfIgJBIxMkeQ8b24YQ." }, + { "test", + "$7$8zzzzzzzzzz.lgPchkGHqbeONR/xtuXyjCrt9kUSg6NlKFQO0OSxo/$.DbajbPYH9T7sg3fOtcgxvJzzfIgJBIxMkeQ8b24YQ." }, + { "test", + "$7$8.....zzzzz.lgPchkGHqbeONR/xtuXyjCrt9kUSg6NlKFQO0OSxo/$.DbajbPYH9T7sg3fOtcgxvJzzfIgJBIxMkeQ8b24YQ." }, + { "test", + "$7$86..../..../lgPchkGHqbeONR/xtuXyjCrt9kUSg6NlKFQO0OSxo/$.DbajbPYH9T7sg3fOtcgxvJzzfIgJBIxMkeQ8b24YQ." } + }; + char * out; + char * passwd; + size_t i = 0U; + + do { + out = (char *) sodium_malloc(strlen(tests[i].out) + 1U); + assert(out != NULL); + memcpy(out, tests[i].out, strlen(tests[i].out) + 1U); + passwd = (char *) sodium_malloc(strlen(tests[i].passwd) + 1U); + assert(passwd != NULL); + memcpy(passwd, tests[i].passwd, strlen(tests[i].passwd) + 1U); + if (crypto_pwhash_scryptsalsa208sha256_str_verify( + out, passwd, strlen(passwd)) != 0) { + printf("pwhash_str failure: [%u]\n", (unsigned int) i); + } + sodium_free(out); + sodium_free(passwd); + } while (++i < (sizeof tests) / (sizeof tests[0])); +} + +static void +str_tests(void) +{ + char *str_out; + char *str_out2; + const char *passwd = "Correct Horse Battery Staple"; + + str_out = + (char *) sodium_malloc(crypto_pwhash_scryptsalsa208sha256_STRBYTES); + str_out2 = + (char *) sodium_malloc(crypto_pwhash_scryptsalsa208sha256_STRBYTES); + if (crypto_pwhash_scryptsalsa208sha256_str(str_out, passwd, strlen(passwd), + OPSLIMIT, MEMLIMIT) != 0) { + printf("pwhash_str failure\n"); + } + if (crypto_pwhash_scryptsalsa208sha256_str(str_out2, passwd, strlen(passwd), + OPSLIMIT, MEMLIMIT) != 0) { + printf("pwhash_str(2) failure\n"); + } + if (strcmp(str_out, str_out2) == 0) { + printf("pwhash_str doesn't generate different salts\n"); + } + if (crypto_pwhash_scryptsalsa208sha256_str_needs_rehash + (str_out, OPSLIMIT, MEMLIMIT) != 0) { + printf("needs_rehash() false positive\n"); + } + if (crypto_pwhash_scryptsalsa208sha256_str_needs_rehash + (str_out, OPSLIMIT, MEMLIMIT / 2) != 1 || + crypto_pwhash_scryptsalsa208sha256_str_needs_rehash + (str_out, OPSLIMIT / 2, MEMLIMIT) != 1 || + crypto_pwhash_scryptsalsa208sha256_str_needs_rehash + (str_out, OPSLIMIT, MEMLIMIT * 2) != 1 || + crypto_pwhash_scryptsalsa208sha256_str_needs_rehash + (str_out, OPSLIMIT * 2, MEMLIMIT) != 1) { + printf("needs_rehash() false negative\n"); + } + if (crypto_pwhash_scryptsalsa208sha256_str_needs_rehash + (str_out + 1, OPSLIMIT, MEMLIMIT) != -1) { + printf("needs_rehash() didn't fail with an invalid hash string\n"); + } + if (crypto_pwhash_scryptsalsa208sha256_str_verify(str_out, passwd, + strlen(passwd)) != 0) { + printf("pwhash_str_verify failure\n"); + } + if (crypto_pwhash_scryptsalsa208sha256_str_verify(str_out, passwd, + strlen(passwd)) != 0) { + printf("pwhash_str_verify failure\n"); + } + str_out[14]++; + if (crypto_pwhash_scryptsalsa208sha256_str_verify(str_out, passwd, + strlen(passwd)) == 0) { + printf("pwhash_str_verify(2) failure\n"); + } + str_out[14]--; + + assert(str_out[crypto_pwhash_scryptsalsa208sha256_STRBYTES - 1U] == 0); + + assert(crypto_pwhash_scryptsalsa208sha256_str_needs_rehash + (str_out, 0, 0) == 1); + assert(crypto_pwhash_str_needs_rehash(str_out, 0, 0) == -1); + assert(crypto_pwhash_str_needs_rehash(str_out, OPSLIMIT, MEMLIMIT) == -1); + assert(crypto_pwhash_scryptsalsa208sha256_str_needs_rehash + ("", OPSLIMIT, MEMLIMIT) == -1); + + sodium_free(str_out); + sodium_free(str_out2); +} + +int +main(void) +{ + tv(); + tv2(); + tv3(); + str_tests(); + + assert(crypto_pwhash_scryptsalsa208sha256_bytes_min() > 0U); + assert(crypto_pwhash_scryptsalsa208sha256_bytes_max() > + crypto_pwhash_scryptsalsa208sha256_bytes_min()); + assert(crypto_pwhash_scryptsalsa208sha256_passwd_max() > + crypto_pwhash_scryptsalsa208sha256_passwd_min()); + assert(crypto_pwhash_scryptsalsa208sha256_saltbytes() > 0U); + assert(crypto_pwhash_scryptsalsa208sha256_strbytes() > 1U); + assert(crypto_pwhash_scryptsalsa208sha256_strbytes() > + strlen(crypto_pwhash_scryptsalsa208sha256_strprefix())); + + assert(crypto_pwhash_scryptsalsa208sha256_opslimit_min() > 0U); + assert(crypto_pwhash_scryptsalsa208sha256_opslimit_max() > 0U); + assert(crypto_pwhash_scryptsalsa208sha256_memlimit_min() > 0U); + assert(crypto_pwhash_scryptsalsa208sha256_memlimit_max() > 0U); + assert(crypto_pwhash_scryptsalsa208sha256_opslimit_interactive() > 0U); + assert(crypto_pwhash_scryptsalsa208sha256_memlimit_interactive() > 0U); + assert(crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive() > 0U); + assert(crypto_pwhash_scryptsalsa208sha256_memlimit_sensitive() > 0U); + + printf("OK\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/pwhash_scrypt.exp b/external/src/libsodium/test/default/pwhash_scrypt.exp new file mode 100644 index 0000000..2f98d0e --- /dev/null +++ b/external/src/libsodium/test/default/pwhash_scrypt.exp @@ -0,0 +1,37 @@ +8d40f5f8c6a1791204f03e19a98cd74f918b6e331b39cfc2415e5014d7738b7bb0a83551fb14a035e07fdd4dc0c60c1a6822ac253918979f6324ff0c87cba75d3b91f88f41ca5414a0f152bdc4d636f42ab2250afd058c19ec31a3374d1bd7133289bf21513ff67cbf8482e626aee9864c58fd05f9ea02e508a10182b7d838157119866f072004987ef6c56683ed207705923921af9d76444a331a +d985d4c278343a46d82af0c4268b7ae6b6d1d2dd289675ef45bfb6d0648bffe5bab8c91228f3a31b091154a9c1142670a07b92e70a298333066de07db9300e046fd7cacc99780804683df7babdfc9d019047178400b2875bde0a1ad824dda7a422d9ed48475af9a3876378dd3a2f206e34984e223afb82c0c1e4644c9a458f4666379fdd3e2d9206d87e3c32c3977f35826a27590baaa1ec1a3bd7d15a92bc84c95dcfc56c14fca7c4c9810162dfdf9dc08a191e79fe40250b7e07d3a9317d9a5cb56e1062c419a6cd6a9b73128e8ad79ab7efffbb3cc52c1f49f86d2ebb46e6e4846aecdb14c2d046f5380517ff8cc794e4a772a58b93083dad +ee7e9e1369267ec555981f0ea088ff6f93953abfcb767d88ec3c46393d24cfbaba5e4e26e0f35b5d5259647748476d65cd8881c96f8cda049d9c877b2d33d932e67f4c0df2cb434b4b4900e0c49c3f8ba9663795420577e65d0b456201ad9162fbc485c7b44f2b34e6673aa3692c123021ee3b624c3bb22b808b89613d8ecc7b87da47f57152eb3f7b10ad206f6b09cb6935b347b5e42bc3b8c9c9bcd8d7b7c44929b367fc279dec48ea78e6ee3e2620d7459700bd0aedb1c9aa5a323ca94403927f5e5c2b73bda7c5c3287b62fe51874cfeb1dc3151cd886b26d83ece68833229d2d432798c602d85b0505947207d8430febbe901164b12ce +pwhash failure +0000000000 +bcc5c2fd785e4781d1201ed43d84925537e2a540d3de55f5812f29e9dd0a4a00451a5c8ddbb4862c03d45c75bf91b7fb49265feb667ad5c899fdbf2ca19eac67aa5e48595d5b02f8183ab07f71b1ce0d76e5df54919f63810ad0893ded7d1ca18fc956ec06ffd4c3d1f77a00ed53608947b25eea5df6bea02272be15815f974c321a2a9208674fdf59d1d798c2a12f1889df68b0c222b37ee9ef0d6391fc160b0281ec53073cb3a3706ce1d71c3af2f5237a1b3d8545d99012eecc0b4abb +82765c040c58c1810f8c053ef5c248556299385476bde44bdd91a0d9a239f24e9b1717fd8b23209ffa45b7aa7937296c601b79e77da99e8d2fda0ea4459be2d0900f5bc5a269b5488d873d4632d1baf75965e509ee24b12501a9ce3bbbd8b7d759987d545a1c221a363195e5802d768b3b9e00ebe5ac0ed8ad2362c1c4157b910a40f94adf2561a2b0d3e65dbb06f244e5ac44d362103df54c9b9175777b3db1cdadb03e977ab8a79baf1e1e18ec9f5d0f25c487ddc53d7e81910f83576b44e9caeece26e2eb376569ad3a8cdccbde8bc355210e +ca9216d4127e2e4a6ee3584b49be106217bb61cc807016d46d0cfbb1fd722e2bbac33541386bdfeac41a299ead22790993fcaa8e1d23bd1c8426afa5ff4c08e731dc476ef834f142c32dfb2c1be12b9978802e63b2cd6f226b1a8df59f0c79154d7ef4296a68ec654538d987104f9a11aca1b7c83ab2ed8fd69da6b88f0bcbd27d3fea01329cecf10c57ec3ba163d57b38801bd6c3b31ce527b33717bb56a46f78fb96be9f2424a21b3284232388cbba6a74 +2732a7566023c8db90a5fdd08dbe6c1b5e70c046d50c5735c8d86a589ba177f69db12d6cc3596319fa27c9e063ed05b8a31970a07dc905 +d7b1ef464be03ce9050b5108e25f0b8e821299986fe0ff89e17fbae65ba9fad167fbd265866ac03efc86ab0b50d46d6740a59adf5949b44f7f9f3ac3f3d4cc9f128966db9099deb1b6b78505242b2401a193820408eb0780b27162ebafb7c505b0e7c32ce66c6efc0be487008c1201454680498a2fc06e00b454e0b20933906bbb0e43b399b9ee46d882f107df1ebdd1e7cd867c9cdba6015b7e80064ae8b3417d969524bec046e782a13b125f058cd36b5d1ae65886ae7caab45a6d98651ada435b8ee11d5c1224232f5f515df974138dd6cf347b730481d4b073af8ff0394fe9f0b8cdfd99f5 +1839be14287053bfcd4ea60db82777fad1a6e9535c388b770743e61235449e668717199defd516c438b3ebd79b3529eb32482ef414525292ea1bbec09da10790a2330a4399f2fe6dd63d80954e3c547a5f1c619db5a30bde495b23f2214b4fa7572851d75246f2817775f0b521acc6efbc7832c9a76de7465e3c65cade88e86c973f85a882bb54f92b983977c6e937c88f083ba68c70fb49497065b158e2e789809b1d4cc9ec2d +d54916748076b9d9f72198c8fbef563462dc8c706e1ad38abd1fac570016721acd0a7659ab49a47299a996b43597690c0c947143069f35d83e606273dbf2d622321393949b8ed5a68315362c4f84804384d05e0e0e86bc00e3641233f9f975ab46b60ba185c5e5fe47f78efd207e69fd8f6390730828b93b9b3763ea1283caa03bc36726763715de811915681dd214524f5ad4dd386608cac6c7f2 +d54916748076b9d9f72198c8fbef563462dc8c706e1ad38abd1fac570016721acd0a7659ab49a47299a996b43597690c0c947143069f35d83e606273dbf2d622321393949b8ed5a68315362c4f84804384d05e0e0e86bc00e3641233f9f975ab46b60ba185c5e5fe47f78efd207e69fd8f6390730828b93b9b3763ea1283caa03bc36726763715de811915681dd214524f5ad4dd386608cac6c7f2 +pwhash_str failure: [10] +pwhash_str failure: [11] +pwhash_str failure: [12] +pwhash_str failure: [13] +pwhash_str failure: [14] +pwhash_str failure: [15] +pwhash_str failure: [16] +pwhash_str failure: [17] +pwhash_str failure: [18] +pwhash_str failure: [19] +pwhash_str failure: [20] +pwhash_str failure: [21] +pwhash_str failure: [22] +pwhash_str failure: [23] +pwhash_str failure: [24] +pwhash_str failure: [25] +pwhash_str failure: [26] +pwhash_str failure: [27] +pwhash_str failure: [28] +pwhash_str failure: [29] +pwhash_str failure: [30] +pwhash_str failure: [31] +pwhash_str failure: [32] +OK diff --git a/external/src/libsodium/test/default/pwhash_scrypt_ll.c b/external/src/libsodium/test/default/pwhash_scrypt_ll.c new file mode 100644 index 0000000..c2b3f3c --- /dev/null +++ b/external/src/libsodium/test/default/pwhash_scrypt_ll.c @@ -0,0 +1,59 @@ + +#define TEST_NAME "pwhash_scrypt_ll" +#include "cmptest.h" + +static const char * passwd1 = ""; +static const char * salt1 = ""; +static const uint64_t N1 = 16U; +static const uint32_t r1 = 1U; +static const uint32_t p1 = 1U; + +static const char * passwd2 = "password"; +static const char * salt2 = "NaCl"; +static const uint64_t N2 = 1024U; +static const uint32_t r2 = 8U; +static const uint32_t p2 = 16U; + +static const char * passwd3 = "pleaseletmein"; +static const char * salt3 = "SodiumChloride"; +static const uint64_t N3 = 16384U; +static const uint32_t r3 = 8U; +static const uint32_t p3 = 1U; + +static void +tv(const char *passwd, const char *salt, uint64_t N, uint32_t r, uint32_t p) +{ + uint8_t data[64]; + size_t i; + size_t olen = (sizeof data / sizeof data[0]); + size_t passwd_len = strlen(passwd); + size_t salt_len = strlen(salt); + int line_items = 0; + + if (crypto_pwhash_scryptsalsa208sha256_ll( + (const uint8_t *) passwd, passwd_len, (const uint8_t *) salt, + salt_len, N, r, p, data, olen) != 0) { + printf("pwhash_scryptsalsa208sha256_ll([%s],[%s]) failure\n", passwd, + salt); + return; + } + + printf("scrypt('%s', '%s', %lu, %lu, %lu, %lu) =\n", passwd, salt, + (unsigned long) N, (unsigned long) r, (unsigned long) p, + (unsigned long) olen); + + for (i = 0; i < olen; i++) { + printf("%02x%c", data[i], line_items < 15 ? ' ' : '\n'); + line_items = line_items < 15 ? line_items + 1 : 0; + } +} + +int +main(void) +{ + tv(passwd1, salt1, N1, r1, p1); + tv(passwd2, salt2, N2, r2, p2); + tv(passwd3, salt3, N3, r3, p3); + + return 0; +} diff --git a/external/src/libsodium/test/default/pwhash_scrypt_ll.exp b/external/src/libsodium/test/default/pwhash_scrypt_ll.exp new file mode 100644 index 0000000..9b7f6a7 --- /dev/null +++ b/external/src/libsodium/test/default/pwhash_scrypt_ll.exp @@ -0,0 +1,15 @@ +scrypt('', '', 16, 1, 1, 64) = +77 d6 57 62 38 65 7b 20 3b 19 ca 42 c1 8a 04 97 +f1 6b 48 44 e3 07 4a e8 df df fa 3f ed e2 14 42 +fc d0 06 9d ed 09 48 f8 32 6a 75 3a 0f c8 1f 17 +e8 d3 e0 fb 2e 0d 36 28 cf 35 e2 0c 38 d1 89 06 +scrypt('password', 'NaCl', 1024, 8, 16, 64) = +fd ba be 1c 9d 34 72 00 78 56 e7 19 0d 01 e9 fe +7c 6a d7 cb c8 23 78 30 e7 73 76 63 4b 37 31 62 +2e af 30 d9 2e 22 a3 88 6f f1 09 27 9d 98 30 da +c7 27 af b9 4a 83 ee 6d 83 60 cb df a2 cc 06 40 +scrypt('pleaseletmein', 'SodiumChloride', 16384, 8, 1, 64) = +70 23 bd cb 3a fd 73 48 46 1c 06 cd 81 fd 38 eb +fd a8 fb ba 90 4f 8e 3e a9 b5 43 f6 54 5d a1 f2 +d5 43 29 55 61 3f 0f cf 62 d4 97 05 24 2a 9a f9 +e6 1e 85 dc 0d 65 1e 40 df cf 01 7b 45 57 58 87 diff --git a/external/src/libsodium/test/default/randombytes.c b/external/src/libsodium/test/default/randombytes.c new file mode 100644 index 0000000..d08066e --- /dev/null +++ b/external/src/libsodium/test/default/randombytes.c @@ -0,0 +1,164 @@ + +#define TEST_NAME "randombytes" +#include "cmptest.h" + +static unsigned char x[65536]; +static unsigned long long freq[256]; + +static int +compat_tests(void) +{ + size_t i; + + memset(x, 0, sizeof x); + randombytes(x, sizeof x); + for (i = 0; i < 256; ++i) { + freq[i] = 0; + } + for (i = 0; i < sizeof x; ++i) { + ++freq[255 & (int) x[i]]; + } + for (i = 0; i < 256; ++i) { + if (!freq[i]) { + printf("nacl_tests failed\n"); + } + } + return 0; +} + +static int +randombytes_tests(void) +{ + static const unsigned char seed[randombytes_SEEDBYTES] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f + }; + unsigned char out[100]; + unsigned int f = 0U; + unsigned int i; + uint32_t n; + +#ifndef BENCHMARKS +# ifdef __EMSCRIPTEN__ + assert(strcmp(randombytes_implementation_name(), "js") == 0); +# else + assert(strcmp(randombytes_implementation_name(), "sysrandom") == 0); +# endif +#endif + randombytes(x, 1U); + do { + n = randombytes_random(); + f |= ((n >> 24) > 1); + f |= ((n >> 16) > 1) << 1; + f |= ((n >> 8) > 1) << 2; + f |= ((n) > 1) << 3; + f |= (n > 0x7fffffff) << 4; + } while (f != 0x1f); + randombytes_close(); + + for (i = 0; i < 256; ++i) { + freq[i] = 0; + } + for (i = 0; i < 65536; ++i) { + ++freq[randombytes_uniform(256)]; + } + for (i = 0; i < 256; ++i) { + if (!freq[i]) { + printf("randombytes_uniform() test failed\n"); + } + } + assert(randombytes_uniform(1U) == 0U); + randombytes_close(); +#ifndef __EMSCRIPTEN__ + assert(&randombytes_internal_implementation == &randombytes_salsa20_implementation); + randombytes_set_implementation(&randombytes_internal_implementation); + assert(strcmp(randombytes_implementation_name(), "internal") == 0); +#endif + randombytes_stir(); + for (i = 0; i < 256; ++i) { + freq[i] = 0; + } + for (i = 0; i < 65536; ++i) { + ++freq[randombytes_uniform(256)]; + } + for (i = 0; i < 256; ++i) { + if (!freq[i]) { + printf("randombytes_uniform() test failed\n"); + } + } + memset(x, 0, sizeof x); + randombytes_buf(x, sizeof x); + for (i = 0; i < 256; ++i) { + freq[i] = 0; + } + for (i = 0; i < sizeof x; ++i) { + ++freq[255 & (int) x[i]]; + } + for (i = 0; i < 256; ++i) { + if (!freq[i]) { + printf("randombytes_buf() test failed\n"); + } + } + assert(randombytes_uniform(1U) == 0U); + + randombytes_buf_deterministic(out, sizeof out, seed); + for (i = 0; i < sizeof out; ++i) { + printf("%02x", out[i]); + } + printf(" (deterministic)\n"); + + randombytes_close(); + + randombytes(x, 1U); + randombytes_close(); + + assert(randombytes_SEEDBYTES > 0); + assert(randombytes_seedbytes() == randombytes_SEEDBYTES); + + return 0; +} + +static uint32_t +randombytes_uniform_impl(const uint32_t upper_bound) +{ + return upper_bound; +} + +static int +impl_tests(void) +{ + randombytes_implementation impl = randombytes_sysrandom_implementation; + uint32_t v = randombytes_random(); + + impl.uniform = randombytes_uniform_impl; + randombytes_close(); + randombytes_set_implementation(&impl); + assert(randombytes_uniform(1) == 1); + assert(randombytes_uniform(v) == v); + assert(randombytes_uniform(v) == v); + assert(randombytes_uniform(v) == v); + assert(randombytes_uniform(v) == v); + randombytes_close(); + impl.close = NULL; + randombytes_close(); + + return 0; +} + +int +main(void) +{ + compat_tests(); + randombytes_tests(); +#ifndef __EMSCRIPTEN__ + impl_tests(); +#endif + printf("OK\n"); + +#ifndef __EMSCRIPTEN__ + randombytes_set_implementation(&randombytes_salsa20_implementation); +#endif + + return 0; +} diff --git a/external/src/libsodium/test/default/randombytes.exp b/external/src/libsodium/test/default/randombytes.exp new file mode 100644 index 0000000..cf955ee --- /dev/null +++ b/external/src/libsodium/test/default/randombytes.exp @@ -0,0 +1,2 @@ +0d8e6cc68715648926732e7ea73250cfaf2d58422083904c841a8ba33b986111f346ba50723a68ae283524a6bded09f83be6b80595856f72e25b86918e8b114bafb94bc8abedd73daab454576b7c5833eb0bf982a1bb4587a5c970ff0810ca3b791d7e12 (deterministic) +OK diff --git a/external/src/libsodium/test/default/scalarmult.c b/external/src/libsodium/test/default/scalarmult.c new file mode 100644 index 0000000..b410fcd --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult.c @@ -0,0 +1,77 @@ + +#define TEST_NAME "scalarmult" +#include "cmptest.h" + +static const unsigned char alicesk[crypto_scalarmult_BYTES] = { + 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16, 0xc1, + 0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, + 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a +}; + +static const unsigned char bobsk[crypto_scalarmult_BYTES] = { + 0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, 0x4b, 0x79, 0xe1, 0x7f, + 0x8b, 0x83, 0x80, 0x0e, 0xe6, 0x6f, 0x3b, 0xb1, 0x29, 0x26, 0x18, + 0xb6, 0xfd, 0x1c, 0x2f, 0x8b, 0x27, 0xff, 0x88, 0xe0, 0xeb +}; + +static const unsigned char small_order_p[crypto_scalarmult_BYTES] = { + 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, + 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, + 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 +}; + +static char hex[crypto_scalarmult_BYTES * 2 + 1]; + +int +main(void) +{ + unsigned char *alicepk = + (unsigned char *) sodium_malloc(crypto_scalarmult_BYTES); + unsigned char *bobpk = + (unsigned char *) sodium_malloc(crypto_scalarmult_BYTES); + unsigned char *k = (unsigned char *) sodium_malloc(crypto_scalarmult_BYTES); + int ret; + + assert(alicepk != NULL && bobpk != NULL && k != NULL); + + crypto_scalarmult_base(alicepk, alicesk); + sodium_bin2hex(hex, sizeof hex, alicepk, crypto_scalarmult_BYTES); + printf("%s\n", hex); + + crypto_scalarmult_base(bobpk, bobsk); + sodium_bin2hex(hex, sizeof hex, bobpk, crypto_scalarmult_BYTES); + printf("%s\n", hex); + + ret = crypto_scalarmult(k, alicesk, bobpk); + assert(ret == 0); + sodium_bin2hex(hex, sizeof hex, k, crypto_scalarmult_BYTES); + printf("%s\n", hex); + + ret = crypto_scalarmult(k, bobsk, alicepk); + assert(ret == 0); + sodium_bin2hex(hex, sizeof hex, k, crypto_scalarmult_BYTES); + printf("%s\n", hex); + + alicepk[31] ^= 0x80; + ret = crypto_scalarmult(k, bobsk, alicepk); + assert(ret == 0); + sodium_bin2hex(hex, sizeof hex, k, crypto_scalarmult_BYTES); + printf("%s\n", hex); + + ret = crypto_scalarmult(k, bobsk, small_order_p); + assert(ret == -1); + + sodium_free(bobpk); + sodium_free(alicepk); + sodium_free(k); + + assert(crypto_scalarmult_bytes() > 0U); + assert(crypto_scalarmult_scalarbytes() > 0U); + assert(strcmp(crypto_scalarmult_primitive(), "curve25519") == 0); + assert(crypto_scalarmult_bytes() == crypto_scalarmult_curve25519_bytes()); + assert(crypto_scalarmult_scalarbytes() == + crypto_scalarmult_curve25519_scalarbytes()); + assert(crypto_scalarmult_bytes() == crypto_scalarmult_scalarbytes()); + + return 0; +} diff --git a/external/src/libsodium/test/default/scalarmult.exp b/external/src/libsodium/test/default/scalarmult.exp new file mode 100644 index 0000000..df1d273 --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult.exp @@ -0,0 +1,5 @@ +8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a +de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f +4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742 +4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742 +4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742 diff --git a/external/src/libsodium/test/default/scalarmult2.c b/external/src/libsodium/test/default/scalarmult2.c new file mode 100644 index 0000000..d1bb83d --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult2.c @@ -0,0 +1,23 @@ + +#define TEST_NAME "scalarmult2" +#include "cmptest.h" + +static unsigned char bobsk[32] = { 0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, + 0x4b, 0x79, 0xe1, 0x7f, 0x8b, 0x83, 0x80, + 0x0e, 0xe6, 0x6f, 0x3b, 0xb1, 0x29, 0x26, + 0x18, 0xb6, 0xfd, 0x1c, 0x2f, 0x8b, 0x27, + 0xff, 0x88, 0xe0, 0xeb }; + +int +main(void) +{ + unsigned char bobpk[32]; + char hex[65]; + int i; + + crypto_scalarmult_base(bobpk, bobsk); + sodium_bin2hex(hex, sizeof hex, bobpk, sizeof bobpk); + printf("%s\n", hex); + + return 0; +} diff --git a/external/src/libsodium/test/default/scalarmult2.exp b/external/src/libsodium/test/default/scalarmult2.exp new file mode 100644 index 0000000..9804b11 --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult2.exp @@ -0,0 +1 @@ +de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f diff --git a/external/src/libsodium/test/default/scalarmult5.c b/external/src/libsodium/test/default/scalarmult5.c new file mode 100644 index 0000000..adeda87 --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult5.c @@ -0,0 +1,31 @@ + +#define TEST_NAME "scalarmult5" +#include "cmptest.h" + +static unsigned char alicesk[32] = { 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, + 0x7d, 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, + 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87, 0xeb, + 0xc0, 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, + 0x1d, 0xb9, 0x2c, 0x2a }; + +static unsigned char bobpk[32] = { 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, + 0xb4, 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, + 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8, 0x5b, + 0x78, 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, + 0x6f, 0x88, 0x2b, 0x4f }; + +int +main(void) +{ + unsigned char k[32]; + char hex[65]; + int i; + int ret; + + ret = crypto_scalarmult(k, alicesk, bobpk); + assert(ret == 0); + sodium_bin2hex(hex, sizeof hex, k, sizeof k); + printf("%s\n", hex); + + return 0; +} diff --git a/external/src/libsodium/test/default/scalarmult5.exp b/external/src/libsodium/test/default/scalarmult5.exp new file mode 100644 index 0000000..e66cca1 --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult5.exp @@ -0,0 +1 @@ +4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742 diff --git a/external/src/libsodium/test/default/scalarmult6.c b/external/src/libsodium/test/default/scalarmult6.c new file mode 100644 index 0000000..f8f0784 --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult6.c @@ -0,0 +1,54 @@ + +#define TEST_NAME "scalarmult6" +#include "cmptest.h" + +static unsigned char bobsk_[crypto_scalarmult_SCALARBYTES] = { + 0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, 0x4b, 0x79, 0xe1, 0x7f, + 0x8b, 0x83, 0x80, 0x0e, 0xe6, 0x6f, 0x3b, 0xb1, 0x29, 0x26, 0x18, + 0xb6, 0xfd, 0x1c, 0x2f, 0x8b, 0x27, 0xff, 0x88, 0xe0, 0xeb +}; + +static unsigned char alicepk_[crypto_scalarmult_SCALARBYTES] = { + 0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 0x74, 0x8b, 0x7d, + 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d, 0x26, 0x38, + 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b, 0x4e, 0x6a +}; + +int +main(void) +{ + unsigned char *k; + unsigned char *bobsk; + unsigned char *alicepk; + int i; + int ret; + + k = (unsigned char *) sodium_malloc(crypto_scalarmult_BYTES); + bobsk = (unsigned char *) sodium_malloc(crypto_scalarmult_SCALARBYTES); + alicepk = (unsigned char *) sodium_malloc(crypto_scalarmult_SCALARBYTES); + assert(k != NULL && bobsk != NULL && alicepk != NULL); + + memcpy(bobsk, bobsk_, crypto_scalarmult_SCALARBYTES); + memcpy(alicepk, alicepk_, crypto_scalarmult_SCALARBYTES); + + ret = crypto_scalarmult(k, bobsk, alicepk); + assert(ret == 0); + + sodium_free(alicepk); + sodium_free(bobsk); + + for (i = 0; i < 32; ++i) { + if (i > 0) { + printf(","); + } else { + printf(" "); + } + printf("0x%02x", (unsigned int) k[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + sodium_free(k); + + return 0; +} diff --git a/external/src/libsodium/test/default/scalarmult6.exp b/external/src/libsodium/test/default/scalarmult6.exp new file mode 100644 index 0000000..bec2113 --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult6.exp @@ -0,0 +1,4 @@ + 0x4a,0x5d,0x9d,0x5b,0xa4,0xce,0x2d,0xe1 +,0x72,0x8e,0x3b,0xf4,0x80,0x35,0x0f,0x25 +,0xe0,0x7e,0x21,0xc9,0x47,0xd1,0x9e,0x33 +,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42 diff --git a/external/src/libsodium/test/default/scalarmult7.c b/external/src/libsodium/test/default/scalarmult7.c new file mode 100644 index 0000000..54f64c2 --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult7.c @@ -0,0 +1,34 @@ + +#define TEST_NAME "scalarmult7" +#include "cmptest.h" + +static unsigned char p1[32] = { + 0x72, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 0x74, 0x8b, 0x7d, + 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d, 0x26, 0x38, + 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b, 0x4e, 0xea +}; + +static unsigned char p2[32] = { + 0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 0x74, 0x8b, 0x7d, + 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d, 0x26, 0x38, + 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b, 0x4e, 0x6a +}; + +static unsigned char scalar[32]; +static unsigned char out1[32]; +static unsigned char out2[32]; + +int +main(void) +{ + int ret; + + scalar[0] = 1U; + ret = crypto_scalarmult_curve25519(out1, scalar, p1); + assert(ret == 0); + ret = crypto_scalarmult_curve25519(out2, scalar, p2); + assert(ret == 0); + printf("%d\n", !!memcmp(out1, out2, 32)); + + return 0; +} diff --git a/external/src/libsodium/test/default/scalarmult7.exp b/external/src/libsodium/test/default/scalarmult7.exp new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult7.exp @@ -0,0 +1 @@ +1 diff --git a/external/src/libsodium/test/default/scalarmult8.c b/external/src/libsodium/test/default/scalarmult8.c new file mode 100644 index 0000000..25a541d --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult8.c @@ -0,0 +1,580 @@ + +#define TEST_NAME "scalarmult8" +#include "cmptest.h" + +typedef struct TestData_ { + const char pk_hex[crypto_scalarmult_BYTES * 2 + 1]; + const char sk_hex[crypto_scalarmult_SCALARBYTES * 2 + 1]; + const char shared_hex[crypto_scalarmult_BYTES * 2 + 1]; + const char *outcome; +} TestData; + +static TestData test_data[] = { + { + "9c647d9ae589b9f58fdc3ca4947efbc915c4b2e08e744a0edf469dac59c8f85a", + "4852834d9d6b77dadeabaaf2e11dca66d19fe74993a7bec36c6e16a0983feaba", + "87b7f212b627f7a54ca5e0bcdaddd5389d9de6156cdbcf8ebe14ffbcfb436551", + "valid" + }, + { + "9c647d9ae589b9f58fdc3ca4947efbc915c4b2e08e744a0edf469dac59c8f85a", + "1064a67da639a8f6df4fbea2d63358b65bca80a770712e14ea8a72df5a3313ae", + "4b82bd8650ea9b81a42181840926a4ffa16434d1bf298de1db87efb5b0a9e34e", + "valid" + }, + { + "63aa40c6e38346c5caf23a6df0a5e6c80889a08647e551b3563449befcfc9733", + "588c061a50804ac488ad774ac716c3f5ba714b2712e048491379a500211998a8", + "b1a707519495ffffb298ff941716b06dfab87cf8d91123fe2be9a233dda22212", + "acceptable" + }, + { + "0f83c36fded9d32fadf4efa3ae93a90bb5cfa66893bc412c43fa7287dbb99779", + "b05bfd32e55325d9fd648cb302848039000b390e44d521e58aab3b29a6960ba8", + "67dd4a6e165533534c0e3f172e4ab8576bca923a5f07b2c069b4c310ff2e935b", + "acceptable" + }, + { + "0b8211a2b6049097f6871c6c052d3c5fc1ba17da9e32ae458403b05bb283092a", + "70e34bcbe1f47fbc0fddfd7c1e1aa53d57bfe0f66d243067b424bb6210bed19c", + "4a0638cfaa9ef1933b47f8939296a6b25be541ef7f70e844c0bcc00b134de64a", + "acceptable" + }, + { + "343ac20a3b9c6a27b1008176509ad30735856ec1c8d8fcae13912d08d152f46c", + "68c1f3a653a4cdb1d37bba94738f8b957a57beb24d646e994dc29a276aad458d", + "399491fce8dfab73b4f9f611de8ea0b27b28f85994250b0f475d585d042ac207", + "acceptable" + }, + { + "fa695fc7be8d1be5bf704898f388c452bafdd3b8eae805f8681a8d15c2d4e142", + "d877b26d06dff9d9f7fd4c5b3769f8cdd5b30516a5ab806be324ff3eb69ea0b2", + "2c4fe11d490a53861776b13b4354abd4cf5a97699db6e6c68c1626d07662f758", + "acceptable" + }, + { + "0000000000000000000000000000000000000000000000000000000000000000", + "207494038f2bb811d47805bcdf04a2ac585ada7f2f23389bfd4658f9ddd4debc", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "0100000000000000000000000000000000000000000000000000000000000000", + "202e8972b61c7e61930eb9450b5070eae1c670475685541f0476217e4818cfab", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "0200000000000000000000000000000000000000000000000000000000000000", + "38dde9f3e7b799045f9ac3793d4a9277dadeadc41bec0290f81f744f73775f84", + "9a2cfe84ff9c4a9739625cae4a3b82a906877a441946f8d7b3d795fe8f5d1639", + "acceptable" + }, + { + "0300000000000000000000000000000000000000000000000000000000000000", + "9857a914e3c29036fd9a442ba526b5cdcdf28216153e636c10677acab6bd6aa5", + "4da4e0aa072c232ee2f0fa4e519ae50b52c1edd08a534d4ef346c2e106d21d60", + "acceptable" + }, + { + "ffffff030000f8ffff1f0000c0ffffff000000feffff070000f0ffff3f000000", + "48e2130d723305ed05e6e5894d398a5e33367a8c6aac8fcdf0a88e4b42820db7", + "9ed10c53747f647f82f45125d3de15a1e6b824496ab40410ffcc3cfe95760f3b", + "acceptable" + }, + { + "000000fcffff070000e0ffff3f000000ffffff010000f8ffff0f0000c0ffff7f", + "28f41011691851b3a62b641553b30d0dfddcb8fffcf53700a7be2f6a872e9fb0", + "cf72b4aa6aa1c9f894f4165b86109aa468517648e1f0cc70e1ab08460176506b", + "acceptable" + }, + { + "00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffff7f", + "18a93b6499b9f6b3225ca02fef410e0adec23532321d2d8ef1a6d602a8c65b83", + "5d50b62836bb69579410386cf7bb811c14bf85b1c7b17e5924c7ffea91ef9e12", + "acceptable" + }, + { + "eaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "c01d1305a1338a1fcac2ba7e2e032b427e0b04903165aca957d8d0553d8717b0", + "19230eb148d5d67c3c22ab1daeff80a57eae4265ce2872657b2c8099fc698e50", + "acceptable" + }, + { + "0400000000000000000000000000000000000000000000000000000000000000", + "386f7f16c50731d64f82e6a170b142a4e34f31fd7768fcb8902925e7d1e21abe", + "0fcab5d842a078d7a71fc59b57bfb4ca0be6873b49dcdb9f44e14ae8fbdfa542", + "valid" + }, + { + "ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000", + "e023a289bd5e90fa2804ddc019a05ef3e79d434bb6ea2f522ecb643a75296e95", + "54ce8f2275c077e3b1306a3939c5e03eef6bbb88060544758d9fef59b0bc3e4f", + "valid" + }, + { + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03", + "68f010d62ee8d926053a361c3a75c6ea4ebdc8606ab285003a6f8f4076b01e83", + "f136775c5beb0af8110af10b20372332043cab752419678775a223df57c9d30d", + "valid" + }, + { + "fffffffbfffffbffffdfffffdffffffffefffffefffff7fffff7ffffbfffff3f", + "58ebcb35b0f8845caf1ec630f96576b62c4b7b6c36b29deb2cb0084651755c96", + "bf9affd06b844085586460962ef2146ff3d4533d9444aab006eb88cc3054407d", + "valid" + }, + { + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "188c4bc5b9c44b38bb658b9b2ae82d5b01015e093184b17cb7863503a783e1bb", + "d480de04f699cb3be0684a9cc2e31281ea0bc5a9dcc157d3d20158d46ca5246d", + "valid" + }, + { + "fffffffffeffff7ffffffffffeffff7ffffffffffeffff7ffffffffffeffff7f", + "e06c11bb2e13ce3dc7673f67f5482242909423a9ae95ee986a988d98faee23a2", + "4c4401cce6b51e4cb18f2790246c9bf914db667750a1cb89069092af07292276", + "valid" + }, + { + "ebffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "c0658c46dde18129293877535b1162b6f9f5414a23cf4d2cbc140a4d99da2b8f", + "578ba8cc2dbdc575afcf9df2b3ee6189f5337d6854c79b4ce165ea12293b3a0f", + "valid" + }, + { + "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800", + "10255c9230a97a30a458ca284a629669293a31890cda9d147febc7d1e22d6bb1", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157", + "78f1e8edf14481b389448dac8f59c70b038e7cf92ef2c7eff57a72466e115296", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "a0a05a3e8f9f44204d5f8059a94ac7dfc39a49ac016dd743dbfa43c5d671fd88", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "d0dbb3ed1906663f15420af31f4eaf6509d9a9949723500605ad7c1c6e7450a9", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "c0b1d0eb22b244fe3291140072cdd9d989b5f0ecd96c100feb5bca241c1d9f8f", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "0000000000000000000000000000000000000000000000000000000000000080", + "480bf45f594942a8bc0f3353c6e8b8853d77f351f1c2ca6c2d1abf8a00b4229c", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "0100000000000000000000000000000000000000000000000000000000000080", + "30f993fcf8514fc89bd8db14cd43ba0d4b2530e73c4276a05e1b145d420cedb4", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b880", + "c04974b758380e2a5b5df6eb09bb2f6b3434f982722a8e676d3da251d1b3de83", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f11d7", + "502a31373db32446842fe5add3e024022ea54f274182afc3d9f1bb3d39534eb5", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "90fa6417b0e37030fd6e43eff2abaef14c6793117a039cf621318ba90f4e98be", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "78ad3f26027f1c9fdd975a1613b947779bad2cf2b741ade01840885a30bb979c", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "98e23de7b1e0926ed9c87e7b14baf55f497a1d7096f93977680e44dc1c7b7b8b", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "0000000000000000000000000000000000000000000000000000000000000000", + "1064a67da639a8f6df4fbea2d63358b65bca80a770712e14ea8a72df5a3313ae", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "0100000000000000000000000000000000000000000000000000000000000000", + "1064a67da639a8f6df4fbea2d63358b65bca80a770712e14ea8a72df5a3313ae", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "1064a67da639a8f6df4fbea2d63358b65bca80a770712e14ea8a72df5a3313ae", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f1157", + "1064a67da639a8f6df4fbea2d63358b65bca80a770712e14ea8a72df5a3313ae", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800", + "1064a67da639a8f6df4fbea2d63358b65bca80a770712e14ea8a72df5a3313ae", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "1064a67da639a8f6df4fbea2d63358b65bca80a770712e14ea8a72df5a3313ae", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "1064a67da639a8f6df4fbea2d63358b65bca80a770712e14ea8a72df5a3313ae", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "0000000000000000000000000000000000000000000000000000000000000080", + "1064a67da639a8f6df4fbea2d63358b65bca80a770712e14ea8a72df5a3313ae", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "0100000000000000000000000000000000000000000000000000000000000080", + "1064a67da639a8f6df4fbea2d63358b65bca80a770712e14ea8a72df5a3313ae", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "ecffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "1064a67da639a8f6df4fbea2d63358b65bca80a770712e14ea8a72df5a3313ae", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "5f9c95bca3508c24b1d0b1559c83ef5b04445cc4581c8e86d8224eddd09f11d7", + "1064a67da639a8f6df4fbea2d63358b65bca80a770712e14ea8a72df5a3313ae", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "e0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b880", + "1064a67da639a8f6df4fbea2d63358b65bca80a770712e14ea8a72df5a3313ae", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "edffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "1064a67da639a8f6df4fbea2d63358b65bca80a770712e14ea8a72df5a3313ae", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "eeffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "1064a67da639a8f6df4fbea2d63358b65bca80a770712e14ea8a72df5a3313ae", + "0000000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "f01e48dafac9d7bcf589cbc382c878d18bda3550589ffb5d50b523bebe329dae", + "bd36a0790eb883098c988b21786773de0b3a4df162282cf110de18dd484ce74b", + "acceptable" + }, + { + "f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "288796bc5aff4b81a37501757bc0753a3c21964790d38699308debc17a6eaf8d", + "b4e0dd76da7b071728b61f856771aa356e57eda78a5b1655cc3820fb5f854c5c", + "acceptable" + }, + { + "f1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "98df845f6651bf1138221f119041f72b6dbc3c4ace7143d99fd55ad867480da8", + "6fdf6c37611dbd5304dc0f2eb7c9517eb3c50e12fd050ac6dec27071d4bfc034", + "acceptable" + }, + { + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "f09498e46f02f878829e78b803d316a2ed695d0498a08abdf8276930e24edcb0", + "4c8fc4b1c6ab88fb21f18f6d4c810240d4e94651ba44f7a2c863cec7dc56602d", + "acceptable" + }, + { + "0200000000000000000000000000000000000000000000000000000000000080", + "1813c10a5c7f21f96e17f288c0cc37607c04c5f5aea2db134f9e2ffc66bd9db8", + "1cd0b28267dc541c642d6d7dca44a8b38a63736eef5c4e6501ffbbb1780c033c", + "acceptable" + }, + { + "0300000000000000000000000000000000000000000000000000000000000080", + "7857fb808653645a0beb138a64f5f4d733a45ea84c3cda11a9c06f7e7139149e", + "8755be01c60a7e825cff3e0e78cb3aa4333861516aa59b1c51a8b2a543dfa822", + "acceptable" + }, + { + "0400000000000000000000000000000000000000000000000000000000000080", + "e03aa842e2abc56e81e87b8b9f417b2a1e5913c723eed28d752f8d47a59f498f", + "54c9a1ed95e546d27822a360931dda60a1df049da6f904253c0612bbdc087476", + "acceptable" + }, + { + "daffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "f8f707b7999b18cb0d6b96124f2045972ca274bfc154ad0c87038c24c6d0d4b2", + "cc1f40d743cdc2230e1043daba8b75e810f1fbab7f255269bd9ebb29e6bf494f", + "acceptable" + }, + { + "dbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "a034f684fa631e1a348118c1ce4c98231f2d9eec9ba5365b4a05d69a785b0796", + "54998ee43a5b007bf499f078e736524400a8b5c7e9b9b43771748c7cdf880412", + "acceptable" + }, + { + "dcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "30b6c6a0f2ffa680768f992ba89e152d5bc9893d38c9119be4f767bfab6e0ca5", + "ead9b38efdd723637934e55ab717a7ae09eb86a21dc36a3feeb88b759e391e09", + "acceptable" + }, + { + "eaffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "901b9dcf881e01e027575035d40b43bdc1c5242e030847495b0c7286469b6591", + "602ff40789b54b41805915fe2a6221f07a50ffc2c3fc94cf61f13d7904e88e0e", + "acceptable" + }, + { + "ebffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "8046677c28fd82c9a1bdb71a1a1a34faba1225e2507fe3f54d10bd5b0d865f8e", + "e00ae8b143471247ba24f12c885536c3cb981b58e1e56b2baf35c12ae1f79c26", + "acceptable" + }, + { + "efffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "602f7e2f68a846b82cc269b1d48e939886ae54fd636c1fe074d710127d472491", + "98cb9b50dd3fc2b0d4f2d2bf7c5cfdd10c8fcd31fc40af1ad44f47c131376362", + "acceptable" + }, + { + "f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "60887b3dc72443026ebedbbbb70665f42b87add1440e7768fbd7e8e2ce5f639d", + "38d6304c4a7e6d9f7959334fb5245bd2c754525d4c91db950206926234c1f633", + "acceptable" + }, + { + "f1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "78d31dfa854497d72d8def8a1b7fb006cec2d8c4924647c93814ae56faeda495", + "786cd54996f014a5a031ec14db812ed08355061fdb5de680a800ac521f318e23", + "acceptable" + }, + { + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "c04c5baefa8302ddded6a4bb957761b4eb97aefa4fc3b8043085f96a5659b3a5", + "29ae8bc73e9b10a08b4f681c43c3e0ac1a171d31b38f1a48efba29ae639ea134", + "acceptable" + }, + { + "e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c", + "a046e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449a44", + "c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552", + "valid" + }, + { + "e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a413", + "4866e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba4d", + "95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957", + "valid" + }, + { + "0ab4e76380d84dde4f6833c58f2a9fb8f83bb0169b172be4b6e0592887741a36", + "a0a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a976bf63", + "0200000000000000000000000000000000000000000000000000000000000000", + "acceptable" + }, + { + "89e10d5701b4337d2d032181538b1064bd4084401ceca1fd12663a1959388000", + "a0a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a976bf63", + "0900000000000000000000000000000000000000000000000000000000000000", + "valid" + }, + { + "2b55d3aa4a8f80c8c0b2ae5f933e85af49beac36c2fa7394bab76c8933f8f81d", + "a0a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a976bf63", + "1000000000000000000000000000000000000000000000000000000000000000", + "valid" + }, + { + "63e5b1fe9601fe84385d8866b0421262f78fbfa5aff9585e626679b18547d959", + "a0a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a976bf63", + "feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "acceptable" + }, + { + "e428f3dac17809f827a522ce32355058d07369364aa78902ee10139b9f9dd653", + "a0a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a976bf63", + "fcffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "valid" + }, + { + "b3b50e3ed3a407b95de942ef74575b5ab8a10c09ee103544d60bdfed8138ab2b", + "a0a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a976bf63", + "f9ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "acceptable" + }, + { + "213fffe93d5ea8cd242e462844029922c43c77c9e3e42f562f485d24c501a20b", + "a0a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a976bf63", + "f3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f", + "valid" + }, + { + "91b232a178b3cd530932441e6139418f72172292f1da4c1834fc5ebfefb51e3f", + "a0a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a976bf63", + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03", + "valid" + }, + { + "045c6e11c5d332556c7822fe94ebf89b56a3878dc27ca079103058849fabcb4f", + "a0a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a976bf63", + "e5ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "acceptable" + }, + { + "1ca2190b71163539063c35773bda0c9c928e9136f0620aeb093f099197b7f74e", + "a0a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a976bf63", + "e3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "acceptable" + }, + { + "f76e9010ac33c5043b2d3b76a842171000c4916222e9e85897a0aec7f6350b3c", + "a0a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a976bf63", + "ddffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "valid" + }, + { + "bb72688d8f8aa7a39cd6060cd5c8093cdec6fe341937c3886a99346cd07faa55", + "a0a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a976bf63", + "dbffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f", + "acceptable" + }, + { + "88fddea193391c6a5933ef9b71901549447205aae9da928a6b91a352ba10f41f", + "a0a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a976bf63", + "0000000000000000000000000000000000000000000000000000000000000002", + "acceptable" + }, + { + "303b392f153116cad9cc682a00ccc44c95ff0d3bbe568beb6c4e739bafdc2c68", + "a0a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a976bf63", + "0000000000000000000000000000000000000000000000000000000000008000", + "acceptable" + }, + { + "fd300aeb40e1fa582518412b49b208a7842b1e1f056a040178ea4141534f652d", + "c81724704000b26d31703cc97e3a378d56fad8219361c88cca8bd7c5719b12b2", + "b734105dc257585d73b566ccb76f062795ccbec89128e52b02f3e59639f13c46", + "valid" + }, + { + "c8ef79b514d7682677bc7931e06ee5c27c9b392b4ae9484473f554e6678ecc2e", + "c81724704000b26d31703cc97e3a378d56fad8219361c88cca8bd7c5719b12b2", + "647a46b6fc3f40d62141ee3cee706b4d7a9271593a7b143e8e2e2279883e4550", + "valid" + }, + { + "64aeac2504144861532b7bbcb6c87d67dd4c1f07ebc2e06effb95aecc6170b2c", + "c81724704000b26d31703cc97e3a378d56fad8219361c88cca8bd7c5719b12b2", + "4ff03d5fb43cd8657a3cf37c138cadcecce509e4eba089d0ef40b4e4fb946155", + "valid" + }, + { + "bf68e35e9bdb7eee1b50570221860f5dcdad8acbab031b14974cc49013c49831", + "c81724704000b26d31703cc97e3a378d56fad8219361c88cca8bd7c5719b12b2", + "21cee52efdbc812e1d021a4af1e1d8bc4db3c400e4d2a2c56a3926db4d99c65b", + "valid" + }, + { + "5347c491331a64b43ddc683034e677f53dc32b52a52a577c15a83bf298e99f19", + "c81724704000b26d31703cc97e3a378d56fad8219361c88cca8bd7c5719b12b2", + "18cb89e4e20c0c2bd324305245266c9327690bbe79acb88f5b8fb3f74eca3e52", + "valid" + }, + { + "258e04523b8d253ee65719fc6906c657192d80717edc828fa0af21686e2faa75", + "a023cdd083ef5bb82f10d62e59e15a6800000000000000000000000000000050", + "258e04523b8d253ee65719fc6906c657192d80717edc828fa0af21686e2faa75", + "valid" + }, + { + "2eae5ec3dd494e9f2d37d258f873a8e6e9d0dbd1e383ef64d98bb91b3e0be035", + "58083dd261ad91eff952322ec824c682ffffffffffffffffffffffffffffff5f", + "2eae5ec3dd494e9f2d37d258f873a8e6e9d0dbd1e383ef64d98bb91b3e0be035", + "acceptable" + } +}; + +int +main(void) +{ + unsigned char sk[crypto_scalarmult_SCALARBYTES]; + unsigned char pk[crypto_scalarmult_BYTES]; + unsigned char shared[crypto_scalarmult_BYTES]; + unsigned char shared2[crypto_scalarmult_BYTES]; + unsigned int i; + int res; + + for (i = 0U; i < (sizeof test_data) / (sizeof test_data[0]); i++) { + sodium_hex2bin(sk, crypto_scalarmult_SCALARBYTES, test_data[i].sk_hex, + crypto_scalarmult_SCALARBYTES * 2, NULL, NULL, NULL); + sodium_hex2bin(pk, crypto_scalarmult_BYTES, test_data[i].pk_hex, + crypto_scalarmult_BYTES * 2, NULL, NULL, NULL); + sodium_hex2bin(shared, crypto_scalarmult_BYTES, test_data[i].shared_hex, + crypto_scalarmult_BYTES * 2, NULL, NULL, NULL); + randombytes_buf(shared2, crypto_scalarmult_BYTES); + res = crypto_scalarmult(shared2, sk, pk); + if (res == 0) { + if (strcmp(test_data[i].outcome, "acceptable") == 0) { + printf("test case %u succeeded (%s)\n", i, + test_data[i].outcome); + } else if (strcmp(test_data[i].outcome, "valid") != 0) { + printf("*** test case %u succeeded, was supposed to be %s\n", i, + test_data[i].outcome); + } + if (memcmp(shared, shared2, crypto_scalarmult_BYTES) != 0) { + printf("*** test case %u succeeded, but shared key is not %s\n", + i, test_data[i].outcome); + } + } else { + if (strcmp(test_data[i].outcome, "acceptable") == 0) { + printf("test case %u failed (%s)\n", i, test_data[i].outcome); + } else if (strcmp(test_data[i].outcome, "valid") == 0) { + printf("*** test case %u failed, was supposed to be %s\n", i, + test_data[i].outcome); + } + } + } + printf("OK\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/scalarmult8.exp b/external/src/libsodium/test/default/scalarmult8.exp new file mode 100644 index 0000000..320ff64 --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult8.exp @@ -0,0 +1,65 @@ +test case 2 succeeded (acceptable) +test case 3 succeeded (acceptable) +test case 4 succeeded (acceptable) +test case 5 succeeded (acceptable) +test case 6 succeeded (acceptable) +test case 7 failed (acceptable) +test case 8 failed (acceptable) +test case 9 succeeded (acceptable) +test case 10 succeeded (acceptable) +test case 11 succeeded (acceptable) +test case 12 succeeded (acceptable) +test case 13 succeeded (acceptable) +test case 14 succeeded (acceptable) +test case 22 failed (acceptable) +test case 23 failed (acceptable) +test case 24 failed (acceptable) +test case 25 failed (acceptable) +test case 26 failed (acceptable) +test case 27 failed (acceptable) +test case 28 failed (acceptable) +test case 29 failed (acceptable) +test case 30 failed (acceptable) +test case 31 failed (acceptable) +test case 32 failed (acceptable) +test case 33 failed (acceptable) +test case 34 failed (acceptable) +test case 35 failed (acceptable) +test case 36 failed (acceptable) +test case 37 failed (acceptable) +test case 38 failed (acceptable) +test case 39 failed (acceptable) +test case 40 failed (acceptable) +test case 41 failed (acceptable) +test case 42 failed (acceptable) +test case 43 failed (acceptable) +test case 44 failed (acceptable) +test case 45 failed (acceptable) +test case 46 failed (acceptable) +test case 47 failed (acceptable) +test case 48 succeeded (acceptable) +test case 49 succeeded (acceptable) +test case 50 succeeded (acceptable) +test case 51 succeeded (acceptable) +test case 52 succeeded (acceptable) +test case 53 succeeded (acceptable) +test case 54 succeeded (acceptable) +test case 55 succeeded (acceptable) +test case 56 succeeded (acceptable) +test case 57 succeeded (acceptable) +test case 58 succeeded (acceptable) +test case 59 succeeded (acceptable) +test case 60 succeeded (acceptable) +test case 61 succeeded (acceptable) +test case 62 succeeded (acceptable) +test case 63 succeeded (acceptable) +test case 66 succeeded (acceptable) +test case 69 succeeded (acceptable) +test case 71 succeeded (acceptable) +test case 74 succeeded (acceptable) +test case 75 succeeded (acceptable) +test case 77 succeeded (acceptable) +test case 78 succeeded (acceptable) +test case 79 succeeded (acceptable) +test case 86 succeeded (acceptable) +OK diff --git a/external/src/libsodium/test/default/scalarmult_ed25519.c b/external/src/libsodium/test/default/scalarmult_ed25519.c new file mode 100644 index 0000000..795647b --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult_ed25519.c @@ -0,0 +1,134 @@ +#define TEST_NAME "scalarmult_ed25519" +#include "cmptest.h" + +static const unsigned char non_canonical_p[32] = { + 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f +}; +static const unsigned char non_canonical_invalid_p[32] = { + 0xf5, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f +}; +static const unsigned char max_canonical_p[32] = { + 0xe4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f +}; + +static const unsigned char B[32] = { + 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66 +}; + +int +main(void) +{ + unsigned char *n, *p, *q, *q2; + + n = (unsigned char *) sodium_malloc(crypto_scalarmult_ed25519_SCALARBYTES); + p = (unsigned char *) sodium_malloc(crypto_scalarmult_ed25519_BYTES); + q = (unsigned char *) sodium_malloc(crypto_scalarmult_ed25519_BYTES); + q2 = (unsigned char *) sodium_malloc(crypto_scalarmult_ed25519_BYTES); + + randombytes_buf(n, crypto_scalarmult_ed25519_SCALARBYTES); + if (crypto_scalarmult_ed25519_base(q, n) != 0) { + printf("crypto_scalarmult_ed25519_base() failed\n"); + } + memcpy(p, B, crypto_scalarmult_ed25519_BYTES); + if (crypto_scalarmult_ed25519(q2, n, p) != 0) { + printf("crypto_scalarmult_ed25519() failed\n"); + } + if (memcmp(q, q2, crypto_scalarmult_ed25519_BYTES) != 0) { + printf("crypto_scalarmult_ed25519_base(n) != crypto_scalarmult_ed25519(n, 9)\n"); + } + + memset(n, 0, crypto_scalarmult_ed25519_SCALARBYTES); + if (crypto_scalarmult_ed25519_base(q, n) != -1) { + printf("crypto_scalarmult_ed25519_base(0) passed\n"); + } + if (crypto_scalarmult_ed25519(q2, n, p) != -1) { + printf("crypto_scalarmult_ed25519(0) passed\n"); + } + if (crypto_scalarmult_ed25519_noclamp(q2, n, p) != -1) { + printf("crypto_scalarmult_ed25519_noclamp(0) passed\n"); + } + + n[0] = 1; + if (crypto_scalarmult_ed25519_base(q, n) != 0) { + printf("crypto_scalarmult_ed25519_base() failed\n"); + } + if (crypto_scalarmult_ed25519(q2, n, p) != 0) { + printf("crypto_scalarmult_ed25519() failed\n"); + } + if (crypto_scalarmult_ed25519_noclamp(q2, n, p) != 0) { + printf("crypto_scalarmult_ed25519_noclamp() failed\n"); + } + + if (crypto_scalarmult_ed25519(q, n, non_canonical_p) != -1) { + printf("crypto_scalarmult_ed25519() didn't fail\n"); + } + if (crypto_scalarmult_ed25519(q, n, non_canonical_invalid_p) != -1) { + printf("crypto_scalarmult_ed25519() didn't fail\n"); + } + if (crypto_scalarmult_ed25519(q, n, max_canonical_p) != 0) { + printf("crypto_scalarmult_ed25519() failed\n"); + } + + n[0] = 9; + if (crypto_scalarmult_ed25519(q, n, p) != 0) { + printf("crypto_scalarmult_ed25519() failed\n"); + } + if (crypto_scalarmult_ed25519_noclamp(q2, n, p) != 0) { + printf("crypto_scalarmult_ed25519_noclamp() failed\n"); + } + if (memcmp(q, q2, crypto_scalarmult_ed25519_BYTES) == 0) { + printf("clamping not applied\n"); + } + + n[0] = 9; + if (crypto_scalarmult_ed25519_base(q, n) != 0) { + printf("crypto_scalarmult_ed25519_base() failed\n"); + } + if (crypto_scalarmult_ed25519_base_noclamp(q2, n) != 0) { + printf("crypto_scalarmult_ed25519_base_noclamp() failed\n"); + } + if (memcmp(q, q2, crypto_scalarmult_ed25519_BYTES) == 0) { + printf("clamping not applied\n"); + } + + n[0] = 8; + n[31] = 64; + if (crypto_scalarmult_ed25519_noclamp(q2, n, p) != 0) { + printf("crypto_scalarmult_ed25519_noclamp() failed\n"); + } + if (memcmp(q, q2, crypto_scalarmult_ed25519_BYTES) != 0) { + printf("inconsistent clamping\n"); + } + + memset(p, 0, crypto_scalarmult_ed25519_BYTES); + if (crypto_scalarmult_ed25519(q, n, p) != -1) { + printf("crypto_scalarmult_ed25519() didn't fail\n"); + } + if (crypto_scalarmult_ed25519_noclamp(q, n, p) != -1) { + printf("crypto_scalarmult_ed25519_noclamp() didn't fail\n"); + } + + n[0] = 8; + if (crypto_scalarmult_ed25519(q, n, p) != -1) { + printf("crypto_scalarmult_ed25519() didn't fail\n"); + } + if (crypto_scalarmult_ed25519_noclamp(q, n, p) != -1) { + printf("crypto_scalarmult_ed25519_noclamp() didn't fail\n"); + } + + sodium_free(q2); + sodium_free(q); + sodium_free(p); + sodium_free(n); + + assert(crypto_scalarmult_ed25519_BYTES == crypto_scalarmult_ed25519_bytes()); + assert(crypto_scalarmult_ed25519_SCALARBYTES == crypto_scalarmult_ed25519_scalarbytes()); + + printf("OK\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/scalarmult_ed25519.exp b/external/src/libsodium/test/default/scalarmult_ed25519.exp new file mode 100644 index 0000000..d86bac9 --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult_ed25519.exp @@ -0,0 +1 @@ +OK diff --git a/external/src/libsodium/test/default/scalarmult_ristretto255.c b/external/src/libsodium/test/default/scalarmult_ristretto255.c new file mode 100644 index 0000000..1acd121 --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult_ristretto255.c @@ -0,0 +1,51 @@ +#define TEST_NAME "scalarmult_ristretto255" +#include "cmptest.h" + +#define B_HEX "e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76" + +int +main(void) +{ + unsigned char *b = + (unsigned char *) sodium_malloc(crypto_scalarmult_ristretto255_BYTES); + unsigned char *n = + (unsigned char *) sodium_malloc(crypto_scalarmult_ristretto255_SCALARBYTES); + unsigned char *p = + (unsigned char *) sodium_malloc(crypto_scalarmult_ristretto255_BYTES); + unsigned char *p2 = + (unsigned char *) sodium_malloc(crypto_scalarmult_ristretto255_BYTES); + char *hex = + (char *) sodium_malloc(2 * crypto_scalarmult_ristretto255_BYTES + 1); + int i; + + sodium_hex2bin(b, crypto_scalarmult_ristretto255_BYTES, + B_HEX, sizeof B_HEX - (size_t) 1U, NULL, NULL, NULL); + memset(n, 0, crypto_scalarmult_ristretto255_SCALARBYTES); + for (i = 0; i < 16; i++) { + crypto_scalarmult_ristretto255_base(p, n); + if (crypto_scalarmult_ristretto255(p2, n, b) != 0) { + printf("crypto_scalarmult_ristretto255(%d) != 0\n", i); + } + sodium_bin2hex(hex, 2 * crypto_scalarmult_ristretto255_BYTES + 1, + p, crypto_scalarmult_ristretto255_BYTES); + printf("%s\n", hex); + assert(memcmp(p, p2, crypto_scalarmult_ristretto255_BYTES) == 0); + sodium_increment(n, crypto_scalarmult_ristretto255_SCALARBYTES); + } + + memset(p, 0xfe, crypto_scalarmult_ristretto255_BYTES); + assert(crypto_scalarmult_ristretto255(guard_page, n, p) == -1); + + sodium_free(hex); + sodium_free(p2); + sodium_free(p); + sodium_free(n); + sodium_free(b); + + assert(crypto_scalarmult_ristretto255_BYTES == crypto_scalarmult_ristretto255_bytes()); + assert(crypto_scalarmult_ristretto255_SCALARBYTES == crypto_scalarmult_ristretto255_scalarbytes()); + + printf("OK\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/scalarmult_ristretto255.exp b/external/src/libsodium/test/default/scalarmult_ristretto255.exp new file mode 100644 index 0000000..919a762 --- /dev/null +++ b/external/src/libsodium/test/default/scalarmult_ristretto255.exp @@ -0,0 +1,18 @@ +crypto_scalarmult_ristretto255(0) != 0 +0000000000000000000000000000000000000000000000000000000000000000 +e2f2ae0a6abc4e71a884a961c500515f58e30b6aa582dd8db6a65945e08d2d76 +6a493210f7499cd17fecb510ae0cea23a110e8d5b901f8acadd3095c73a3b919 +94741f5d5d52755ece4f23f044ee27d5d1ea1e2bd196b462166b16152a9d0259 +da80862773358b466ffadfe0b3293ab3d9fd53c5ea6c955358f568322daf6a57 +e882b131016b52c1d3337080187cf768423efccbb517bb495ab812c4160ff44e +f64746d3c92b13050ed8d80236a7f0007c3b3f962f5ba793d19a601ebb1df403 +44f53520926ec81fbd5a387845beb7df85a96a24ece18738bdcfa6a7822a176d +903293d8f2287ebe10e2374dc1a53e0bc887e592699f02d077d5263cdd55601c +02622ace8f7303a31cafc63f8fc48fdc16e1c8c8d234b2f0d6685282a9076031 +20706fd788b2720a1ed2a5dad4952b01f413bcf0e7564de8cdc816689e2db95f +bce83f8ba5dd2fa572864c24ba1810f9522bc6004afe95877ac73241cafdab42 +e4549ee16b9aa03099ca208c67adafcafa4c3f3e4e5303de6026e3ca8ff84460 +aa52e000df2e16f55fb1032fc33bc42742dad6bd5a8fc0be0167436c5948501f +46376b80f409b29dc2b5f6f0c52591990896e5716f41477cd30085ab7f10301e +e0c418f7c8d9c4cdd7395b93ea124f3ad99021bb681dfc3302a9d99a2e53e64e +OK diff --git a/external/src/libsodium/test/default/secretbox.c b/external/src/libsodium/test/default/secretbox.c new file mode 100644 index 0000000..df1d62f --- /dev/null +++ b/external/src/libsodium/test/default/secretbox.c @@ -0,0 +1,84 @@ + +#define TEST_NAME "secretbox" +#include "cmptest.h" + +static unsigned char firstkey[32] = { 0x1b, 0x27, 0x55, 0x64, 0x73, 0xe9, 0x85, + 0xd4, 0x62, 0xcd, 0x51, 0x19, 0x7a, 0x9a, + 0x46, 0xc7, 0x60, 0x09, 0x54, 0x9e, 0xac, + 0x64, 0x74, 0xf2, 0x06, 0xc4, 0xee, 0x08, + 0x44, 0xf6, 0x83, 0x89 }; + +static unsigned char nonce[24] = { 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, + 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8, + 0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, + 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 }; + +/* API requires first 32 bytes to be 0 */ +static unsigned char m[163] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0xbe, 0x07, 0x5f, 0xc5, + 0x3c, 0x81, 0xf2, 0xd5, 0xcf, 0x14, 0x13, 0x16, 0xeb, 0xeb, 0x0c, 0x7b, + 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4, 0x4b, 0x66, 0x84, 0x9b, + 0x64, 0x24, 0x4f, 0xfc, 0xe5, 0xec, 0xba, 0xaf, 0x33, 0xbd, 0x75, 0x1a, + 0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29, 0x6c, 0xdc, 0x3c, 0x01, + 0x23, 0x35, 0x61, 0xf4, 0x1d, 0xb6, 0x6c, 0xce, 0x31, 0x4a, 0xdb, 0x31, + 0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d, 0xce, 0xea, 0x3a, 0x7f, + 0xa1, 0x34, 0x80, 0x57, 0xe2, 0xf6, 0x55, 0x6a, 0xd6, 0xb1, 0x31, 0x8a, + 0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde, 0x04, 0x89, 0x77, 0xeb, + 0x48, 0xf5, 0x9f, 0xfd, 0x49, 0x24, 0xca, 0x1c, 0x60, 0x90, 0x2e, 0x52, + 0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40, 0xe0, 0x82, 0xf9, 0x37, + 0x76, 0x38, 0x48, 0x64, 0x5e, 0x07, 0x05 +}; + +static unsigned char c[163]; + +int +main(void) +{ + int i; + + crypto_secretbox(c, m, 163, nonce, firstkey); + for (i = 16; i < 163; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + if (i % 8 == 7) + printf("\n"); + } + printf("\n"); + + memcpy(c, m, 163); + crypto_secretbox(c, c, 163, nonce, firstkey); + for (i = 16; i < 163; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + if (i % 8 == 7) + printf("\n"); + } + printf("\n"); + + assert(crypto_secretbox(c, c, 31, nonce, firstkey) == -1); + assert(crypto_secretbox(c, c, 12, nonce, firstkey) == -1); + assert(crypto_secretbox(c, c, 1, nonce, firstkey) == -1); + assert(crypto_secretbox(c, c, 0, nonce, firstkey) == -1); + + assert(crypto_secretbox_keybytes() > 0U); + assert(crypto_secretbox_noncebytes() > 0U); + assert(crypto_secretbox_zerobytes() > 0U); + assert(crypto_secretbox_boxzerobytes() > 0U); + assert(crypto_secretbox_macbytes() > 0U); + assert(crypto_secretbox_messagebytes_max() > 0U); + assert(strcmp(crypto_secretbox_primitive(), "xsalsa20poly1305") == 0); + assert(crypto_secretbox_keybytes() == + crypto_secretbox_xsalsa20poly1305_keybytes()); + assert(crypto_secretbox_noncebytes() == + crypto_secretbox_xsalsa20poly1305_noncebytes()); + assert(crypto_secretbox_zerobytes() == + crypto_secretbox_xsalsa20poly1305_zerobytes()); + assert(crypto_secretbox_boxzerobytes() == + crypto_secretbox_xsalsa20poly1305_boxzerobytes()); + assert(crypto_secretbox_macbytes() == + crypto_secretbox_xsalsa20poly1305_macbytes()); + assert(crypto_secretbox_messagebytes_max() == + crypto_secretbox_xsalsa20poly1305_messagebytes_max()); + + return 0; +} diff --git a/external/src/libsodium/test/default/secretbox.exp b/external/src/libsodium/test/default/secretbox.exp new file mode 100644 index 0000000..25db669 --- /dev/null +++ b/external/src/libsodium/test/default/secretbox.exp @@ -0,0 +1,38 @@ +,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5 +,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9 +,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73 +,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce +,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4 +,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a +,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b +,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72 +,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2 +,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38 +,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a +,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae +,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea +,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda +,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde +,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3 +,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6 +,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74 +,0xe3,0x55,0xa5 +,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5 +,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9 +,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73 +,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce +,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4 +,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a +,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b +,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72 +,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2 +,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38 +,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a +,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae +,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea +,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda +,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde +,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3 +,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6 +,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74 +,0xe3,0x55,0xa5 diff --git a/external/src/libsodium/test/default/secretbox2.c b/external/src/libsodium/test/default/secretbox2.c new file mode 100644 index 0000000..e6320b7 --- /dev/null +++ b/external/src/libsodium/test/default/secretbox2.c @@ -0,0 +1,55 @@ + +#define TEST_NAME "secretbox2" +#include "cmptest.h" + +static unsigned char firstkey[32] = { 0x1b, 0x27, 0x55, 0x64, 0x73, 0xe9, 0x85, + 0xd4, 0x62, 0xcd, 0x51, 0x19, 0x7a, 0x9a, + 0x46, 0xc7, 0x60, 0x09, 0x54, 0x9e, 0xac, + 0x64, 0x74, 0xf2, 0x06, 0xc4, 0xee, 0x08, + 0x44, 0xf6, 0x83, 0x89 }; + +static unsigned char nonce[24] = { 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, + 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8, + 0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, + 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 }; + +/* API requires first 16 bytes to be 0 */ +static unsigned char c[163] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5, + 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9, 0x8e, 0x99, 0x3b, 0x9f, + 0x48, 0x68, 0x12, 0x73, 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce, + 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4, 0x47, 0x6f, 0xb8, 0xc5, + 0x31, 0xa1, 0x18, 0x6a, 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b, + 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72, 0x71, 0xd2, 0xc2, 0x0f, + 0x9b, 0x92, 0x8f, 0xe2, 0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38, + 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a, 0xb9, 0x32, 0x16, 0x45, + 0x48, 0xe5, 0x26, 0xae, 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea, + 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda, 0x99, 0x83, 0x2b, 0x61, + 0xca, 0x01, 0xb6, 0xde, 0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3, + 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6, 0x59, 0x9b, 0x1f, 0x65, + 0x4c, 0xb4, 0x5a, 0x74, 0xe3, 0x55, 0xa5 +}; + +static unsigned char m[163]; + +int +main(void) +{ + int i; + + if (crypto_secretbox_open(m, c, 163, nonce, firstkey) == 0) { + for (i = 32; i < 163; ++i) { + printf(",0x%02x", (unsigned int) m[i]); + if (i % 8 == 7) + printf("\n"); + } + printf("\n"); + } + assert(crypto_secretbox_open(m, c, 31, nonce, firstkey) == -1); + assert(crypto_secretbox_open(m, c, 16, nonce, firstkey) == -1); + assert(crypto_secretbox_open(m, c, 1, nonce, firstkey) == -1); + assert(crypto_secretbox_open(m, c, 0, nonce, firstkey) == -1); + + return 0; +} diff --git a/external/src/libsodium/test/default/secretbox2.exp b/external/src/libsodium/test/default/secretbox2.exp new file mode 100644 index 0000000..c61d455 --- /dev/null +++ b/external/src/libsodium/test/default/secretbox2.exp @@ -0,0 +1,17 @@ +,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5 +,0xcf,0x14,0x13,0x16,0xeb,0xeb,0x0c,0x7b +,0x52,0x28,0xc5,0x2a,0x4c,0x62,0xcb,0xd4 +,0x4b,0x66,0x84,0x9b,0x64,0x24,0x4f,0xfc +,0xe5,0xec,0xba,0xaf,0x33,0xbd,0x75,0x1a +,0x1a,0xc7,0x28,0xd4,0x5e,0x6c,0x61,0x29 +,0x6c,0xdc,0x3c,0x01,0x23,0x35,0x61,0xf4 +,0x1d,0xb6,0x6c,0xce,0x31,0x4a,0xdb,0x31 +,0x0e,0x3b,0xe8,0x25,0x0c,0x46,0xf0,0x6d +,0xce,0xea,0x3a,0x7f,0xa1,0x34,0x80,0x57 +,0xe2,0xf6,0x55,0x6a,0xd6,0xb1,0x31,0x8a +,0x02,0x4a,0x83,0x8f,0x21,0xaf,0x1f,0xde +,0x04,0x89,0x77,0xeb,0x48,0xf5,0x9f,0xfd +,0x49,0x24,0xca,0x1c,0x60,0x90,0x2e,0x52 +,0xf0,0xa0,0x89,0xbc,0x76,0x89,0x70,0x40 +,0xe0,0x82,0xf9,0x37,0x76,0x38,0x48,0x64 +,0x5e,0x07,0x05 diff --git a/external/src/libsodium/test/default/secretbox7.c b/external/src/libsodium/test/default/secretbox7.c new file mode 100644 index 0000000..389943d --- /dev/null +++ b/external/src/libsodium/test/default/secretbox7.c @@ -0,0 +1,36 @@ + +#define TEST_NAME "secretbox7" +#include "cmptest.h" + +static unsigned char k[crypto_secretbox_KEYBYTES]; +static unsigned char n[crypto_secretbox_NONCEBYTES]; +static unsigned char m[10000]; +static unsigned char c[10000]; +static unsigned char m2[10000]; + +int +main(void) +{ + size_t mlen; + size_t i; + + for (mlen = 0; mlen < 1000 && mlen + crypto_secretbox_ZEROBYTES < sizeof m; + ++mlen) { + crypto_secretbox_keygen(k); + randombytes_buf(n, crypto_secretbox_NONCEBYTES); + randombytes_buf(m + crypto_secretbox_ZEROBYTES, mlen); + crypto_secretbox(c, m, mlen + crypto_secretbox_ZEROBYTES, n, k); + if (crypto_secretbox_open(m2, c, mlen + crypto_secretbox_ZEROBYTES, n, + k) == 0) { + for (i = 0; i < mlen + crypto_secretbox_ZEROBYTES; ++i) { + if (m2[i] != m[i]) { + printf("bad decryption\n"); + break; + } + } + } else { + printf("ciphertext fails verification\n"); + } + } + return 0; +} diff --git a/external/src/libsodium/test/default/secretbox7.exp b/external/src/libsodium/test/default/secretbox7.exp new file mode 100644 index 0000000..e69de29 diff --git a/external/src/libsodium/test/default/secretbox8.c b/external/src/libsodium/test/default/secretbox8.c new file mode 100644 index 0000000..acba5f0 --- /dev/null +++ b/external/src/libsodium/test/default/secretbox8.c @@ -0,0 +1,41 @@ + +#define TEST_NAME "secretbox8" +#include "cmptest.h" + +static unsigned char k[crypto_secretbox_KEYBYTES]; +static unsigned char n[crypto_secretbox_NONCEBYTES]; +static unsigned char m[10000]; +static unsigned char c[10000]; +static unsigned char m2[10000]; + +int +main(void) +{ + size_t mlen; + size_t i; + int caught; + + for (mlen = 0; mlen < 1000 && mlen + crypto_secretbox_ZEROBYTES < sizeof m; + ++mlen) { + crypto_secretbox_keygen(k); + randombytes_buf(n, crypto_secretbox_NONCEBYTES); + randombytes_buf(m + crypto_secretbox_ZEROBYTES, mlen); + crypto_secretbox(c, m, mlen + crypto_secretbox_ZEROBYTES, n, k); + caught = 0; + while (caught < 10) { + c[rand() % (mlen + crypto_secretbox_ZEROBYTES)] = rand(); + if (crypto_secretbox_open(m2, c, mlen + crypto_secretbox_ZEROBYTES, + n, k) == 0) { + for (i = 0; i < mlen + crypto_secretbox_ZEROBYTES; ++i) { + if (m2[i] != m[i]) { + printf("forgery\n"); + return 100; + } + } + } else { + ++caught; + } + } + } + return 0; +} diff --git a/external/src/libsodium/test/default/secretbox8.exp b/external/src/libsodium/test/default/secretbox8.exp new file mode 100644 index 0000000..e69de29 diff --git a/external/src/libsodium/test/default/secretbox_easy.c b/external/src/libsodium/test/default/secretbox_easy.c new file mode 100644 index 0000000..4542bbd --- /dev/null +++ b/external/src/libsodium/test/default/secretbox_easy.c @@ -0,0 +1,124 @@ + +#define TEST_NAME "secretbox_easy" +#include "cmptest.h" + +static unsigned char firstkey[32] = { 0x1b, 0x27, 0x55, 0x64, 0x73, 0xe9, 0x85, + 0xd4, 0x62, 0xcd, 0x51, 0x19, 0x7a, 0x9a, + 0x46, 0xc7, 0x60, 0x09, 0x54, 0x9e, 0xac, + 0x64, 0x74, 0xf2, 0x06, 0xc4, 0xee, 0x08, + 0x44, 0xf6, 0x83, 0x89 }; + +static unsigned char nonce[24] = { 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, + 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8, + 0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, + 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 }; + +static unsigned char m[131] = { + 0xbe, 0x07, 0x5f, 0xc5, 0x3c, 0x81, 0xf2, 0xd5, 0xcf, 0x14, 0x13, 0x16, + 0xeb, 0xeb, 0x0c, 0x7b, 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4, + 0x4b, 0x66, 0x84, 0x9b, 0x64, 0x24, 0x4f, 0xfc, 0xe5, 0xec, 0xba, 0xaf, + 0x33, 0xbd, 0x75, 0x1a, 0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29, + 0x6c, 0xdc, 0x3c, 0x01, 0x23, 0x35, 0x61, 0xf4, 0x1d, 0xb6, 0x6c, 0xce, + 0x31, 0x4a, 0xdb, 0x31, 0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d, + 0xce, 0xea, 0x3a, 0x7f, 0xa1, 0x34, 0x80, 0x57, 0xe2, 0xf6, 0x55, 0x6a, + 0xd6, 0xb1, 0x31, 0x8a, 0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde, + 0x04, 0x89, 0x77, 0xeb, 0x48, 0xf5, 0x9f, 0xfd, 0x49, 0x24, 0xca, 0x1c, + 0x60, 0x90, 0x2e, 0x52, 0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40, + 0xe0, 0x82, 0xf9, 0x37, 0x76, 0x38, 0x48, 0x64, 0x5e, 0x07, 0x05 +}; + +int +main(void) +{ + unsigned char *c; + unsigned char *mac; + size_t i; + + c = (unsigned char *) sodium_malloc(131 + crypto_secretbox_MACBYTES + 1); + mac = (unsigned char *) sodium_malloc(crypto_secretbox_MACBYTES); + assert(c != NULL && mac != NULL); + + crypto_secretbox_easy(c, m, 131, nonce, firstkey); + for (i = 0; i < 131 + crypto_secretbox_MACBYTES; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + } + printf("\n"); + + crypto_secretbox_detached(c, mac, m, 131, nonce, firstkey); + for (i = 0; i < crypto_secretbox_MACBYTES; ++i) { + printf(",0x%02x", (unsigned int) mac[i]); + } + for (i = 0; i < 131; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + } + printf("\n"); + + /* Same test, with c and m overlapping */ + + memcpy(c + 1, m, 131); + crypto_secretbox_easy(c, c + 1, 131, nonce, firstkey); + for (i = 0; i < 131 + crypto_secretbox_MACBYTES; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + } + printf("\n"); + + memcpy(c, m, 131); + crypto_secretbox_easy(c + 1, c, 131, nonce, firstkey); + for (i = 0; i < 131 + crypto_secretbox_MACBYTES; ++i) { + printf(",0x%02x", (unsigned int) c[i + 1]); + } + printf("\n"); + + memcpy(c, m, 131); + crypto_secretbox_easy(c, c, 131, nonce, firstkey); + for (i = 0; i < 131 + crypto_secretbox_MACBYTES; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + } + printf("\n"); + + assert(crypto_secretbox_easy(c, m, 0, nonce, firstkey) == 0); + + /* Null message */ + + crypto_secretbox_easy(c, c, 0, nonce, firstkey); + for (i = 0; i < crypto_secretbox_MACBYTES + 1; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + } + printf("\n"); + if (crypto_secretbox_open_easy(c, c, crypto_secretbox_MACBYTES, nonce, + firstkey) != 0) { + printf("Null crypto_secretbox_open_easy() failed\n"); + } + for (i = 0; i < crypto_secretbox_MACBYTES + 1; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + } + printf("\n"); + c[randombytes_uniform(crypto_secretbox_MACBYTES)]++; + if (crypto_secretbox_open_easy(c, c, crypto_secretbox_MACBYTES, nonce, + firstkey) != -1) { + printf("Null tampered crypto_secretbox_open_easy() failed\n"); + } + + /* No overlap, but buffers are next to each other */ + + memset(c, 0, 131 + crypto_secretbox_MACBYTES + 1); + memcpy(c, m, 20); + crypto_secretbox_easy(c, c + 10, 10, nonce, firstkey); + for (i = 0; i < 10 + crypto_secretbox_MACBYTES; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + } + printf("\n"); + + memset(c, 0, 131 + crypto_secretbox_MACBYTES + 1); + memcpy(c, m, 20); + crypto_secretbox_easy(c + 10, c, 10, nonce, firstkey); + for (i = 0; i < 10 + crypto_secretbox_MACBYTES; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + } + printf("\n"); + + sodium_free(mac); + sodium_free(c); + + return 0; +} diff --git a/external/src/libsodium/test/default/secretbox_easy.exp b/external/src/libsodium/test/default/secretbox_easy.exp new file mode 100644 index 0000000..3cffae8 --- /dev/null +++ b/external/src/libsodium/test/default/secretbox_easy.exp @@ -0,0 +1,9 @@ +,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74,0xe3,0x55,0xa5 +,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74,0xe3,0x55,0xa5 +,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74,0xe3,0x55,0xa5 +,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74,0xe3,0x55,0xa5 +,0xf3,0xff,0xc7,0x70,0x3f,0x94,0x00,0xe5,0x2a,0x7d,0xfb,0x4b,0x3d,0x33,0x05,0xd9,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74,0xe3,0x55,0xa5 +,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80,0x8e +,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80,0x8e +,0x8c,0xf3,0x90,0x57,0xc9,0xbc,0xf2,0xba,0x98,0x87,0xfb,0x15,0x9f,0x21,0x0c,0xd8,0x23,0x88,0x8f,0xb1,0x78,0x92,0xb2,0x8e,0xc8,0xa8 +,0xbe,0x07,0x5f,0xc5,0x3c,0x81,0xf2,0xd5,0xcf,0x14,0xd2,0xe8,0xe8,0x1a,0xac,0xd2,0xba,0x1b,0xaa,0x60,0x99,0xe3,0xd9,0x63,0x56,0x18 diff --git a/external/src/libsodium/test/default/secretbox_easy2.c b/external/src/libsodium/test/default/secretbox_easy2.c new file mode 100644 index 0000000..7cacbd7 --- /dev/null +++ b/external/src/libsodium/test/default/secretbox_easy2.c @@ -0,0 +1,72 @@ + +#define TEST_NAME "secretbox_easy2" +#include "cmptest.h" + +int +main(void) +{ + unsigned char *m; + unsigned char *m2; + unsigned char *c; + unsigned char *nonce; + unsigned char *k; + unsigned char *mac; + size_t mlen; + size_t i; + + mlen = (size_t) randombytes_uniform((uint32_t) 10000) + 1U; + m = (unsigned char *) sodium_malloc(mlen); + m2 = (unsigned char *) sodium_malloc(mlen); + c = (unsigned char *) sodium_malloc(crypto_secretbox_MACBYTES + mlen); + nonce = (unsigned char *) sodium_malloc(crypto_secretbox_NONCEBYTES); + k = (unsigned char *) sodium_malloc(crypto_secretbox_KEYBYTES); + mac = (unsigned char *) sodium_malloc(crypto_secretbox_MACBYTES); + crypto_secretbox_keygen(k); + randombytes_buf(m, mlen); + randombytes_buf(nonce, crypto_secretbox_NONCEBYTES); + crypto_secretbox_easy(c, m, (unsigned long long) mlen, nonce, k); + if (crypto_secretbox_open_easy( + m2, c, (unsigned long long) mlen + crypto_secretbox_MACBYTES, nonce, + k) != 0) { + printf("crypto_secretbox_open_easy() failed\n"); + } + printf("%d\n", memcmp(m, m2, mlen)); + + for (i = 0; i < mlen + crypto_secretbox_MACBYTES - 1; i++) { + if (crypto_secretbox_open_easy(m2, c, (unsigned long long) i, nonce, + k) == 0) { + printf("short open() should have failed\n"); + return 1; + } + } + crypto_secretbox_detached(c, mac, m, (unsigned long long) mlen, nonce, k); + if (crypto_secretbox_open_detached(NULL, c, mac, (unsigned long long) mlen, + nonce, k) != 0) { + printf("crypto_secretbox_open_detached() with a NULL message pointer failed\n"); + } + if (crypto_secretbox_open_detached(m2, c, mac, (unsigned long long) mlen, + nonce, k) != 0) { + printf("crypto_secretbox_open_detached() failed\n"); + } + printf("%d\n", memcmp(m, m2, mlen)); + + memcpy(c, m, mlen); + crypto_secretbox_easy(c, c, (unsigned long long) mlen, nonce, k); + printf("%d\n", memcmp(m, c, mlen) == 0); + printf("%d\n", memcmp(m, c + crypto_secretbox_MACBYTES, mlen) == 0); + if (crypto_secretbox_open_easy( + c, c, (unsigned long long) mlen + crypto_secretbox_MACBYTES, nonce, + k) != 0) { + printf("crypto_secretbox_open_easy() failed\n"); + } + printf("%d\n", memcmp(m, c, mlen)); + + sodium_free(m); + sodium_free(m2); + sodium_free(c); + sodium_free(nonce); + sodium_free(k); + sodium_free(mac); + + return 0; +} diff --git a/external/src/libsodium/test/default/secretbox_easy2.exp b/external/src/libsodium/test/default/secretbox_easy2.exp new file mode 100644 index 0000000..229972f --- /dev/null +++ b/external/src/libsodium/test/default/secretbox_easy2.exp @@ -0,0 +1,5 @@ +0 +0 +0 +0 +0 diff --git a/external/src/libsodium/test/default/secretstream.c b/external/src/libsodium/test/default/secretstream.c new file mode 100644 index 0000000..63c6443 --- /dev/null +++ b/external/src/libsodium/test/default/secretstream.c @@ -0,0 +1,329 @@ + +#define TEST_NAME "secretstream" +#include "cmptest.h" + +int +main(void) +{ + crypto_secretstream_xchacha20poly1305_state *state, *statesave; + crypto_secretstream_xchacha20poly1305_state state_copy; + unsigned char *ad; + unsigned char *header; + unsigned char *k; + unsigned char *c1, *c2, *c3, *csave; + unsigned char *m1, *m2, *m3; + unsigned char *m1_, *m2_, *m3_; + unsigned long long res_len; + size_t ad_len; + size_t m1_len, m2_len, m3_len; + int ret; + unsigned char tag; + + state = (crypto_secretstream_xchacha20poly1305_state *) + sodium_malloc(crypto_secretstream_xchacha20poly1305_statebytes()); + statesave = (crypto_secretstream_xchacha20poly1305_state *) + sodium_malloc(crypto_secretstream_xchacha20poly1305_statebytes()); + header = (unsigned char *) + sodium_malloc(crypto_secretstream_xchacha20poly1305_HEADERBYTES); + + ad_len = randombytes_uniform(100); + m1_len = randombytes_uniform(1000); + m2_len = randombytes_uniform(1000); + m3_len = randombytes_uniform(1000); + + c1 = (unsigned char *) + sodium_malloc(m1_len + crypto_secretstream_xchacha20poly1305_ABYTES); + c2 = (unsigned char *) + sodium_malloc(m2_len + crypto_secretstream_xchacha20poly1305_ABYTES); + c3 = (unsigned char *) + sodium_malloc(m3_len + crypto_secretstream_xchacha20poly1305_ABYTES); + csave = (unsigned char *) + sodium_malloc((m1_len | m2_len | m3_len) + crypto_secretstream_xchacha20poly1305_ABYTES); + + ad = (unsigned char *) sodium_malloc(ad_len); + m1 = (unsigned char *) sodium_malloc(m1_len); + m2 = (unsigned char *) sodium_malloc(m2_len); + m3 = (unsigned char *) sodium_malloc(m3_len); + m1_ = (unsigned char *) sodium_malloc(m1_len); + m2_ = (unsigned char *) sodium_malloc(m2_len); + m3_ = (unsigned char *) sodium_malloc(m3_len); + + randombytes_buf(ad, ad_len); + + randombytes_buf(m1, m1_len); + memcpy(m1_, m1, m1_len); + randombytes_buf(m2, m2_len); + memcpy(m2_, m2, m2_len); + randombytes_buf(m3, m3_len); + memcpy(m3_, m3, m3_len); + + k = (unsigned char *) + sodium_malloc(crypto_secretstream_xchacha20poly1305_KEYBYTES); + crypto_secretstream_xchacha20poly1305_keygen(k); + + /* push */ + + ret = crypto_secretstream_xchacha20poly1305_init_push(state, header, k); + assert(ret == 0); + + ret = crypto_secretstream_xchacha20poly1305_push + (state, c1, &res_len, m1, m1_len, NULL, 0, 0); + assert(ret == 0); + assert(res_len == m1_len + crypto_secretstream_xchacha20poly1305_ABYTES); + + ret = crypto_secretstream_xchacha20poly1305_push + (state, c2, NULL, m2, m2_len, ad, 0, 0); + assert(ret == 0); + + ret = crypto_secretstream_xchacha20poly1305_push + (state, c3, NULL, m3, m3_len, ad, ad_len, + crypto_secretstream_xchacha20poly1305_TAG_FINAL); + assert(ret == 0); + + /* pull */ + + ret = crypto_secretstream_xchacha20poly1305_init_pull(state, header, k); + assert(ret == 0); + + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m1, &res_len, &tag, + c1, m1_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); + assert(ret == 0); + assert(tag == 0); + assert(memcmp(m1, m1_, m1_len) == 0); + assert(res_len == m1_len); + + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m2, NULL, &tag, + c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); + assert(ret == 0); + assert(tag == 0); + assert(memcmp(m2, m2_, m2_len) == 0); + + if (ad_len > 0) { + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m3, NULL, &tag, + c3, m3_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); + assert(ret == -1); + } + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m3, NULL, &tag, + c3, m3_len + crypto_secretstream_xchacha20poly1305_ABYTES, ad, ad_len); + assert(ret == 0); + assert(tag == crypto_secretstream_xchacha20poly1305_TAG_FINAL); + assert(memcmp(m3, m3_, m3_len) == 0); + + /* previous with FINAL tag */ + + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m3, NULL, &tag, + c3, m3_len + crypto_secretstream_xchacha20poly1305_ABYTES, ad, ad_len); + assert(ret == -1); + + /* previous without a tag */ + + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m2, NULL, &tag, + c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); + assert(ret == -1); + + /* short ciphertext */ + + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m2, NULL, &tag, c2, + randombytes_uniform(crypto_secretstream_xchacha20poly1305_ABYTES), + NULL, 0); + assert(ret == -1); + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m2, NULL, &tag, c2, 0, NULL, 0); + assert(ret == -1); + + /* empty ciphertext */ + + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m2, NULL, &tag, c2, + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); + assert(ret == -1); + + /* without explicit rekeying */ + + ret = crypto_secretstream_xchacha20poly1305_init_push(state, header, k); + assert(ret == 0); + ret = crypto_secretstream_xchacha20poly1305_push + (state, c1, NULL, m1, m1_len, NULL, 0, 0); + assert(ret == 0); + ret = crypto_secretstream_xchacha20poly1305_push + (state, c2, NULL, m2, m2_len, NULL, 0, 0); + assert(ret == 0); + + ret = crypto_secretstream_xchacha20poly1305_init_pull(state, header, k); + assert(ret == 0); + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m1, NULL, &tag, + c1, m1_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); + assert(ret == 0); + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m2, NULL, &tag, + c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); + assert(ret == 0); + + /* with explicit rekeying */ + + ret = crypto_secretstream_xchacha20poly1305_init_push(state, header, k); + assert(ret == 0); + ret = crypto_secretstream_xchacha20poly1305_push + (state, c1, NULL, m1, m1_len, NULL, 0, 0); + assert(ret == 0); + + crypto_secretstream_xchacha20poly1305_rekey(state); + + ret = crypto_secretstream_xchacha20poly1305_push + (state, c2, NULL, m2, m2_len, NULL, 0, 0); + assert(ret == 0); + + ret = crypto_secretstream_xchacha20poly1305_init_pull(state, header, k); + assert(ret == 0); + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m1, NULL, &tag, + c1, m1_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); + assert(ret == 0); + + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m2, NULL, &tag, + c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); + assert(ret == -1); + + crypto_secretstream_xchacha20poly1305_rekey(state); + + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m2, NULL, &tag, + c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); + assert(ret == 0); + + /* with explicit rekeying using TAG_REKEY */ + + ret = crypto_secretstream_xchacha20poly1305_init_push(state, header, k); + assert(ret == 0); + + memcpy(statesave, state, sizeof *state); + + ret = crypto_secretstream_xchacha20poly1305_push + (state, c1, NULL, m1, m1_len, NULL, 0, crypto_secretstream_xchacha20poly1305_TAG_REKEY); + assert(ret == 0); + + ret = crypto_secretstream_xchacha20poly1305_push + (state, c2, NULL, m2, m2_len, NULL, 0, 0); + assert(ret == 0); + + memcpy(csave, c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES); + + ret = crypto_secretstream_xchacha20poly1305_init_pull(state, header, k); + assert(ret == 0); + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m1, NULL, &tag, + c1, m1_len + crypto_secretstream_xchacha20poly1305_ABYTES, &tag, 0); + assert(ret == 0); + assert(tag == crypto_secretstream_xchacha20poly1305_TAG_REKEY); + + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m2, NULL, &tag, + c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES, &tag, 0); + assert(ret == 0); + assert(tag == 0); + + memcpy(state, statesave, sizeof *state); + + ret = crypto_secretstream_xchacha20poly1305_push + (state, c1, NULL, m1, m1_len, NULL, 0, 0); + assert(ret == 0); + + ret = crypto_secretstream_xchacha20poly1305_push + (state, c2, NULL, m2, m2_len, NULL, 0, 0); + assert(ret == 0); + + assert(memcmp(csave, c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES) != 0); + + /* New stream */ + + ret = crypto_secretstream_xchacha20poly1305_init_push(state, header, k); + assert(ret == 0); + + ret = crypto_secretstream_xchacha20poly1305_push + (state, c1, &res_len, m1, m1_len, NULL, 0, + crypto_secretstream_xchacha20poly1305_TAG_PUSH); + assert(ret == 0); + assert(res_len == m1_len + crypto_secretstream_xchacha20poly1305_ABYTES); + + /* Force a counter overflow, check that the key has been updated + * even though the tag was not changed to REKEY */ + + memset(state->nonce, 0xff, 4U); + state_copy = *state; + + ret = crypto_secretstream_xchacha20poly1305_push + (state, c2, NULL, m2, m2_len, ad, 0, 0); + assert(ret == 0); + + assert(memcmp(state_copy.k, state->k, sizeof state->k) != 0); + assert(memcmp(state_copy.nonce, state->nonce, sizeof state->nonce) != 0); + assert(state->nonce[0] == 1U); + assert(sodium_is_zero(state->nonce + 1, 3U)); + + ret = crypto_secretstream_xchacha20poly1305_init_pull(state, header, k); + assert(ret == 0); + + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m1, &res_len, &tag, + c1, m1_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); + assert(ret == 0); + assert(tag == crypto_secretstream_xchacha20poly1305_TAG_PUSH); + assert(memcmp(m1, m1_, m1_len) == 0); + assert(res_len == m1_len); + + memset(state->nonce, 0xff, 4U); + + ret = crypto_secretstream_xchacha20poly1305_pull + (state, m2, NULL, &tag, + c2, m2_len + crypto_secretstream_xchacha20poly1305_ABYTES, NULL, 0); + assert(ret == 0); + assert(tag == 0); + assert(memcmp(m2, m2_, m2_len) == 0); + + sodium_free(m3_); + sodium_free(m2_); + sodium_free(m1_); + sodium_free(m3); + sodium_free(m2); + sodium_free(m1); + sodium_free(ad); + sodium_free(csave); + sodium_free(c3); + sodium_free(c2); + sodium_free(c1); + sodium_free(k); + sodium_free(header); + sodium_free(statesave); + sodium_free(state); + + assert(crypto_secretstream_xchacha20poly1305_abytes() == + crypto_secretstream_xchacha20poly1305_ABYTES); + assert(crypto_secretstream_xchacha20poly1305_headerbytes() == + crypto_secretstream_xchacha20poly1305_HEADERBYTES); + assert(crypto_secretstream_xchacha20poly1305_keybytes() == + crypto_secretstream_xchacha20poly1305_KEYBYTES); + assert(crypto_secretstream_xchacha20poly1305_messagebytes_max() == + crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX); + + assert(crypto_secretstream_xchacha20poly1305_tag_message() == + crypto_secretstream_xchacha20poly1305_TAG_MESSAGE); + assert(crypto_secretstream_xchacha20poly1305_tag_push() == + crypto_secretstream_xchacha20poly1305_TAG_PUSH); + assert(crypto_secretstream_xchacha20poly1305_tag_rekey() == + crypto_secretstream_xchacha20poly1305_TAG_REKEY); + assert(crypto_secretstream_xchacha20poly1305_tag_final() == + crypto_secretstream_xchacha20poly1305_TAG_FINAL); + + printf("OK\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/secretstream.exp b/external/src/libsodium/test/default/secretstream.exp new file mode 100644 index 0000000..d86bac9 --- /dev/null +++ b/external/src/libsodium/test/default/secretstream.exp @@ -0,0 +1 @@ +OK diff --git a/external/src/libsodium/test/default/shorthash.c b/external/src/libsodium/test/default/shorthash.c new file mode 100644 index 0000000..e8fadec --- /dev/null +++ b/external/src/libsodium/test/default/shorthash.c @@ -0,0 +1,35 @@ + +#define TEST_NAME "shorthash" +#include "cmptest.h" + +#define MAXLEN 64 + +int +main(void) +{ + unsigned char in[MAXLEN]; + unsigned char out[crypto_shorthash_BYTES]; + unsigned char k[crypto_shorthash_KEYBYTES]; + size_t i; + size_t j; + + for (i = 0; i < crypto_shorthash_KEYBYTES; ++i) { + k[i] = (unsigned char) i; + } + for (i = 0; i < MAXLEN; ++i) { + in[i] = (unsigned char) i; + crypto_shorthash(out, in, (unsigned long long) i, k); + for (j = 0; j < crypto_shorthash_BYTES; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + } + assert(crypto_shorthash_bytes() > 0); + assert(crypto_shorthash_keybytes() > 0); + assert(strcmp(crypto_shorthash_primitive(), "siphash24") == 0); + assert(crypto_shorthash_bytes() == crypto_shorthash_siphash24_bytes()); + assert(crypto_shorthash_keybytes() == + crypto_shorthash_siphash24_keybytes()); + + return 0; +} diff --git a/external/src/libsodium/test/default/shorthash.exp b/external/src/libsodium/test/default/shorthash.exp new file mode 100644 index 0000000..6ec8684 --- /dev/null +++ b/external/src/libsodium/test/default/shorthash.exp @@ -0,0 +1,64 @@ +310e0edd47db6f72 +fd67dc93c539f874 +5a4fa9d909806c0d +2d7efbd796666785 +b7877127e09427cf +8da699cd64557618 +cee3fe586e46c9cb +37d1018bf50002ab +6224939a79f5f593 +b0e4a90bdf82009e +f3b9dd94c5bb5d7a +a7ad6b22462fb3f4 +fbe50e86bc8f1e75 +903d84c02756ea14 +eef27a8e90ca23f7 +e545be4961ca29a1 +db9bc2577fcc2a3f +9447be2cf5e99a69 +9cd38d96f0b3c14b +bd6179a71dc96dbb +98eea21af25cd6be +c7673b2eb0cbf2d0 +883ea3e395675393 +c8ce5ccd8c030ca8 +94af49f6c650adb8 +eab8858ade92e1bc +f315bb5bb835d817 +adcf6b0763612e2f +a5c91da7acaa4dde +716595876650a2a6 +28ef495c53a387ad +42c341d8fa92d832 +ce7cf2722f512771 +e37859f94623f3a7 +381205bb1ab0e012 +ae97a10fd434e015 +b4a31508beff4d31 +81396229f0907902 +4d0cf49ee5d4dcca +5c73336a76d8bf9a +d0a704536ba93e0e +925958fcd6420cad +a915c29bc8067318 +952b79f3bc0aa6d4 +f21df2e41d4535f9 +87577519048f53a9 +10a56cf5dfcd9adb +eb75095ccd986cd0 +51a9cb9ecba312e6 +96afadfc2ce666c7 +72fe52975a4364ee +5a1645b276d592a1 +b274cb8ebf87870a +6f9bb4203de7b381 +eaecb2a30b22a87f +9924a43cc1315724 +bd838d3aafbf8db7 +0b1a2a3265d51aea +135079a3231ce660 +932b2846e4d70666 +e1915f5cb1eca46c +f325965ca16d629f +575ff28e60381be5 +724506eb4c328a95 diff --git a/external/src/libsodium/test/default/sign.c b/external/src/libsodium/test/default/sign.c new file mode 100644 index 0000000..30a2882 --- /dev/null +++ b/external/src/libsodium/test/default/sign.c @@ -0,0 +1,1324 @@ + +#define TEST_NAME "sign" +#include "cmptest.h" + +static const unsigned char keypair_seed[] + = { 0x42, 0x11, 0x51, 0xa4, 0x59, 0xfa, 0xea, 0xde, 0x3d, 0x24, 0x71, + 0x15, 0xf9, 0x4a, 0xed, 0xae, 0x42, 0x31, 0x81, 0x24, 0x09, 0x5a, + 0xfa, 0xbe, 0x4d, 0x14, 0x51, 0xa5, 0x59, 0xfa, 0xed, 0xee }; + +typedef struct TestData_ { + const unsigned char sk[crypto_sign_SEEDBYTES]; + const unsigned char pk[crypto_sign_PUBLICKEYBYTES]; + const unsigned char sig[crypto_sign_BYTES]; + const char *m; +} TestData; + +static TestData test_data[] = { +{{0x9d,0x61,0xb1,0x9d,0xef,0xfd,0x5a,0x60,0xba,0x84,0x4a,0xf4,0x92,0xec,0x2c,0xc4,0x44,0x49,0xc5,0x69,0x7b,0x32,0x69,0x19,0x70,0x3b,0xac,0x03,0x1c,0xae,0x7f,0x60,},{0xd7,0x5a,0x98,0x01,0x82,0xb1,0x0a,0xb7,0xd5,0x4b,0xfe,0xd3,0xc9,0x64,0x07,0x3a,0x0e,0xe1,0x72,0xf3,0xda,0xa6,0x23,0x25,0xaf,0x02,0x1a,0x68,0xf7,0x07,0x51,0x1a,},{0xe5,0x56,0x43,0x00,0xc3,0x60,0xac,0x72,0x90,0x86,0xe2,0xcc,0x80,0x6e,0x82,0x8a,0x84,0x87,0x7f,0x1e,0xb8,0xe5,0xd9,0x74,0xd8,0x73,0xe0,0x65,0x22,0x49,0x01,0x55,0x5f,0xb8,0x82,0x15,0x90,0xa3,0x3b,0xac,0xc6,0x1e,0x39,0x70,0x1c,0xf9,0xb4,0x6b,0xd2,0x5b,0xf5,0xf0,0x59,0x5b,0xbe,0x24,0x65,0x51,0x41,0x43,0x8e,0x7a,0x10,0x0b,},""}, +{{0x4c,0xcd,0x08,0x9b,0x28,0xff,0x96,0xda,0x9d,0xb6,0xc3,0x46,0xec,0x11,0x4e,0x0f,0x5b,0x8a,0x31,0x9f,0x35,0xab,0xa6,0x24,0xda,0x8c,0xf6,0xed,0x4f,0xb8,0xa6,0xfb,},{0x3d,0x40,0x17,0xc3,0xe8,0x43,0x89,0x5a,0x92,0xb7,0x0a,0xa7,0x4d,0x1b,0x7e,0xbc,0x9c,0x98,0x2c,0xcf,0x2e,0xc4,0x96,0x8c,0xc0,0xcd,0x55,0xf1,0x2a,0xf4,0x66,0x0c,},{0x92,0xa0,0x09,0xa9,0xf0,0xd4,0xca,0xb8,0x72,0x0e,0x82,0x0b,0x5f,0x64,0x25,0x40,0xa2,0xb2,0x7b,0x54,0x16,0x50,0x3f,0x8f,0xb3,0x76,0x22,0x23,0xeb,0xdb,0x69,0xda,0x08,0x5a,0xc1,0xe4,0x3e,0x15,0x99,0x6e,0x45,0x8f,0x36,0x13,0xd0,0xf1,0x1d,0x8c,0x38,0x7b,0x2e,0xae,0xb4,0x30,0x2a,0xee,0xb0,0x0d,0x29,0x16,0x12,0xbb,0x0c,0x00,},"\x72"}, +{{0xc5,0xaa,0x8d,0xf4,0x3f,0x9f,0x83,0x7b,0xed,0xb7,0x44,0x2f,0x31,0xdc,0xb7,0xb1,0x66,0xd3,0x85,0x35,0x07,0x6f,0x09,0x4b,0x85,0xce,0x3a,0x2e,0x0b,0x44,0x58,0xf7,},{0xfc,0x51,0xcd,0x8e,0x62,0x18,0xa1,0xa3,0x8d,0xa4,0x7e,0xd0,0x02,0x30,0xf0,0x58,0x08,0x16,0xed,0x13,0xba,0x33,0x03,0xac,0x5d,0xeb,0x91,0x15,0x48,0x90,0x80,0x25,},{0x62,0x91,0xd6,0x57,0xde,0xec,0x24,0x02,0x48,0x27,0xe6,0x9c,0x3a,0xbe,0x01,0xa3,0x0c,0xe5,0x48,0xa2,0x84,0x74,0x3a,0x44,0x5e,0x36,0x80,0xd7,0xdb,0x5a,0xc3,0xac,0x18,0xff,0x9b,0x53,0x8d,0x16,0xf2,0x90,0xae,0x67,0xf7,0x60,0x98,0x4d,0xc6,0x59,0x4a,0x7c,0x15,0xe9,0x71,0x6e,0xd2,0x8d,0xc0,0x27,0xbe,0xce,0xea,0x1e,0xc4,0x0a,},"\xaf\x82"}, +{{0x0d,0x4a,0x05,0xb0,0x73,0x52,0xa5,0x43,0x6e,0x18,0x03,0x56,0xda,0x0a,0xe6,0xef,0xa0,0x34,0x5f,0xf7,0xfb,0x15,0x72,0x57,0x57,0x72,0xe8,0x00,0x5e,0xd9,0x78,0xe9,},{0xe6,0x1a,0x18,0x5b,0xce,0xf2,0x61,0x3a,0x6c,0x7c,0xb7,0x97,0x63,0xce,0x94,0x5d,0x3b,0x24,0x5d,0x76,0x11,0x4d,0xd4,0x40,0xbc,0xf5,0xf2,0xdc,0x1a,0xa5,0x70,0x57,},{0xd9,0x86,0x8d,0x52,0xc2,0xbe,0xbc,0xe5,0xf3,0xfa,0x5a,0x79,0x89,0x19,0x70,0xf3,0x09,0xcb,0x65,0x91,0xe3,0xe1,0x70,0x2a,0x70,0x27,0x6f,0xa9,0x7c,0x24,0xb3,0xa8,0xe5,0x86,0x06,0xc3,0x8c,0x97,0x58,0x52,0x9d,0xa5,0x0e,0xe3,0x1b,0x82,0x19,0xcb,0xa4,0x52,0x71,0xc6,0x89,0xaf,0xa6,0x0b,0x0e,0xa2,0x6c,0x99,0xdb,0x19,0xb0,0x0c,},"\xcb\xc7\x7b"}, +{{0x6d,0xf9,0x34,0x0c,0x13,0x8c,0xc1,0x88,0xb5,0xfe,0x44,0x64,0xeb,0xaa,0x3f,0x7f,0xc2,0x06,0xa2,0xd5,0x5c,0x34,0x34,0x70,0x7e,0x74,0xc9,0xfc,0x04,0xe2,0x0e,0xbb,},{0xc0,0xda,0xc1,0x02,0xc4,0x53,0x31,0x86,0xe2,0x5d,0xc4,0x31,0x28,0x47,0x23,0x53,0xea,0xab,0xdb,0x87,0x8b,0x15,0x2a,0xeb,0x8e,0x00,0x1f,0x92,0xd9,0x02,0x33,0xa7,},{0x12,0x4f,0x6f,0xc6,0xb0,0xd1,0x00,0x84,0x27,0x69,0xe7,0x1b,0xd5,0x30,0x66,0x4d,0x88,0x8d,0xf8,0x50,0x7d,0xf6,0xc5,0x6d,0xed,0xfd,0xb5,0x09,0xae,0xb9,0x34,0x16,0xe2,0x6b,0x91,0x8d,0x38,0xaa,0x06,0x30,0x5d,0xf3,0x09,0x56,0x97,0xc1,0x8b,0x2a,0xa8,0x32,0xea,0xa5,0x2e,0xdc,0x0a,0xe4,0x9f,0xba,0xe5,0xa8,0x5e,0x15,0x0c,0x07,},"\x5f\x4c\x89\x89"}, +{{0xb7,0x80,0x38,0x1a,0x65,0xed,0xf8,0xb7,0x8f,0x69,0x45,0xe8,0xdb,0xec,0x79,0x41,0xac,0x04,0x9f,0xd4,0xc6,0x10,0x40,0xcf,0x0c,0x32,0x43,0x57,0x97,0x5a,0x29,0x3c,},{0xe2,0x53,0xaf,0x07,0x66,0x80,0x4b,0x86,0x9b,0xb1,0x59,0x5b,0xe9,0x76,0x5b,0x53,0x48,0x86,0xbb,0xaa,0xb8,0x30,0x5b,0xf5,0x0d,0xbc,0x7f,0x89,0x9b,0xfb,0x5f,0x01,},{0xb2,0xfc,0x46,0xad,0x47,0xaf,0x46,0x44,0x78,0xc1,0x99,0xe1,0xf8,0xbe,0x16,0x9f,0x1b,0xe6,0x32,0x7c,0x7f,0x9a,0x0a,0x66,0x89,0x37,0x1c,0xa9,0x4c,0xaf,0x04,0x06,0x4a,0x01,0xb2,0x2a,0xff,0x15,0x20,0xab,0xd5,0x89,0x51,0x34,0x16,0x03,0xfa,0xed,0x76,0x8c,0xf7,0x8c,0xe9,0x7a,0xe7,0xb0,0x38,0xab,0xfe,0x45,0x6a,0xa1,0x7c,0x09,},"\x18\xb6\xbe\xc0\x97"}, +{{0x78,0xae,0x9e,0xff,0xe6,0xf2,0x45,0xe9,0x24,0xa7,0xbe,0x63,0x04,0x11,0x46,0xeb,0xc6,0x70,0xdb,0xd3,0x06,0x0c,0xba,0x67,0xfb,0xc6,0x21,0x6f,0xeb,0xc4,0x45,0x46,},{0xfb,0xcf,0xbf,0xa4,0x05,0x05,0xd7,0xf2,0xbe,0x44,0x4a,0x33,0xd1,0x85,0xcc,0x54,0xe1,0x6d,0x61,0x52,0x60,0xe1,0x64,0x0b,0x2b,0x50,0x87,0xb8,0x3e,0xe3,0x64,0x3d,},{0x6e,0xd6,0x29,0xfc,0x1d,0x9c,0xe9,0xe1,0x46,0x87,0x55,0xff,0x63,0x6d,0x5a,0x3f,0x40,0xa5,0xd9,0xc9,0x1a,0xfd,0x93,0xb7,0x9d,0x24,0x18,0x30,0xf7,0xe5,0xfa,0x29,0x85,0x4b,0x8f,0x20,0xcc,0x6e,0xec,0xbb,0x24,0x8d,0xbd,0x8d,0x16,0xd1,0x4e,0x99,0x75,0x21,0x94,0xe4,0x90,0x4d,0x09,0xc7,0x4d,0x63,0x95,0x18,0x83,0x9d,0x23,0x00,},"\x89\x01\x0d\x85\x59\x72"}, +{{0x69,0x18,0x65,0xbf,0xc8,0x2a,0x1e,0x4b,0x57,0x4e,0xec,0xde,0x4c,0x75,0x19,0x09,0x3f,0xaf,0x0c,0xf8,0x67,0x38,0x02,0x34,0xe3,0x66,0x46,0x45,0xc6,0x1c,0x5f,0x79,},{0x98,0xa5,0xe3,0xa3,0x6e,0x67,0xaa,0xba,0x89,0x88,0x8b,0xf0,0x93,0xde,0x1a,0xd9,0x63,0xe7,0x74,0x01,0x3b,0x39,0x02,0xbf,0xab,0x35,0x6d,0x8b,0x90,0x17,0x8a,0x63,},{0x6e,0x0a,0xf2,0xfe,0x55,0xae,0x37,0x7a,0x6b,0x7a,0x72,0x78,0xed,0xfb,0x41,0x9b,0xd3,0x21,0xe0,0x6d,0x0d,0xf5,0xe2,0x70,0x37,0xdb,0x88,0x12,0xe7,0xe3,0x52,0x98,0x10,0xfa,0x55,0x52,0xf6,0xc0,0x02,0x09,0x85,0xca,0x17,0xa0,0xe0,0x2e,0x03,0x6d,0x7b,0x22,0x2a,0x24,0xf9,0x9b,0x77,0xb7,0x5f,0xdd,0x16,0xcb,0x05,0x56,0x81,0x07,},"\xb4\xa8\xf3\x81\xe7\x0e\x7a"}, +{{0x3b,0x26,0x51,0x6f,0xb3,0xdc,0x88,0xeb,0x18,0x1b,0x9e,0xd7,0x3f,0x0b,0xcd,0x52,0xbc,0xd6,0xb4,0xc7,0x88,0xe4,0xbc,0xaf,0x46,0x05,0x7f,0xd0,0x78,0xbe,0xe0,0x73,},{0xf8,0x1f,0xb5,0x4a,0x82,0x5f,0xce,0xd9,0x5e,0xb0,0x33,0xaf,0xcd,0x64,0x31,0x40,0x75,0xab,0xfb,0x0a,0xbd,0x20,0xa9,0x70,0x89,0x25,0x03,0x43,0x6f,0x34,0xb8,0x63,},{0xd6,0xad,0xde,0xc5,0xaf,0xb0,0x52,0x8a,0xc1,0x7b,0xb1,0x78,0xd3,0xe7,0xf2,0x88,0x7f,0x9a,0xdb,0xb1,0xad,0x16,0xe1,0x10,0x54,0x5e,0xf3,0xbc,0x57,0xf9,0xde,0x23,0x14,0xa5,0xc8,0x38,0x8f,0x72,0x3b,0x89,0x07,0xbe,0x0f,0x3a,0xc9,0x0c,0x62,0x59,0xbb,0xe8,0x85,0xec,0xc1,0x76,0x45,0xdf,0x3d,0xb7,0xd4,0x88,0xf8,0x05,0xfa,0x08,},"\x42\x84\xab\xc5\x1b\xb6\x72\x35"}, +{{0xed,0xc6,0xf5,0xfb,0xdd,0x1c,0xee,0x4d,0x10,0x1c,0x06,0x35,0x30,0xa3,0x04,0x90,0xb2,0x21,0xbe,0x68,0xc0,0x36,0xf5,0xb0,0x7d,0x0f,0x95,0x3b,0x74,0x5d,0xf1,0x92,},{0xc1,0xa4,0x9c,0x66,0xe6,0x17,0xf9,0xef,0x5e,0xc6,0x6b,0xc4,0xc6,0x56,0x4c,0xa3,0x3d,0xe2,0xa5,0xfb,0x5e,0x14,0x64,0x06,0x2e,0x6d,0x6c,0x62,0x19,0x15,0x5e,0xfd,},{0x2c,0x76,0xa0,0x4a,0xf2,0x39,0x1c,0x14,0x70,0x82,0xe3,0x3f,0xaa,0xcd,0xbe,0x56,0x64,0x2a,0x1e,0x13,0x4b,0xd3,0x88,0x62,0x0b,0x85,0x2b,0x90,0x1a,0x6b,0xc1,0x6f,0xf6,0xc9,0xcc,0x94,0x04,0xc4,0x1d,0xea,0x12,0xed,0x28,0x1d,0xa0,0x67,0xa1,0x51,0x38,0x66,0xf9,0xd9,0x64,0xf8,0xbd,0xd2,0x49,0x53,0x85,0x6c,0x50,0x04,0x29,0x01,},"\x67\x2b\xf8\x96\x5d\x04\xbc\x51\x46"}, +{{0x4e,0x7d,0x21,0xfb,0x3b,0x18,0x97,0x57,0x1a,0x44,0x58,0x33,0xbe,0x0f,0x9f,0xd4,0x1c,0xd6,0x2b,0xe3,0xaa,0x04,0x04,0x0f,0x89,0x34,0xe1,0xfc,0xbd,0xca,0xcd,0x45,},{0x31,0xb2,0x52,0x4b,0x83,0x48,0xf7,0xab,0x1d,0xfa,0xfa,0x67,0x5c,0xc5,0x38,0xe9,0xa8,0x4e,0x3f,0xe5,0x81,0x9e,0x27,0xc1,0x2a,0xd8,0xbb,0xc1,0xa3,0x6e,0x4d,0xff,},{0x28,0xe4,0x59,0x8c,0x41,0x5a,0xe9,0xde,0x01,0xf0,0x3f,0x9f,0x3f,0xab,0x4e,0x91,0x9e,0x8b,0xf5,0x37,0xdd,0x2b,0x0c,0xdf,0x6e,0x79,0xb9,0xe6,0x55,0x9c,0x94,0x09,0xd9,0x15,0x1a,0x4c,0x40,0xf0,0x83,0x19,0x39,0x37,0x62,0x7c,0x36,0x94,0x88,0x25,0x9e,0x99,0xda,0x5a,0x9f,0x0a,0x87,0x49,0x7f,0xa6,0x69,0x6a,0x5d,0xd6,0xce,0x08,},"\x33\xd7\xa7\x86\xad\xed\x8c\x1b\xf6\x91"}, +{{0xa9,0x80,0xf8,0x92,0xdb,0x13,0xc9,0x9a,0x3e,0x89,0x71,0xe9,0x65,0xb2,0xff,0x3d,0x41,0xea,0xfd,0x54,0x09,0x3b,0xc9,0xf3,0x4d,0x1f,0xd2,0x2d,0x84,0x11,0x5b,0xb6,},{0x44,0xb5,0x7e,0xe3,0x0c,0xdb,0x55,0x82,0x9d,0x0a,0x5d,0x4f,0x04,0x6b,0xae,0xf0,0x78,0xf1,0xe9,0x7a,0x7f,0x21,0xb6,0x2d,0x75,0xf8,0xe9,0x6e,0xa1,0x39,0xc3,0x5f,},{0x77,0xd3,0x89,0xe5,0x99,0x63,0x0d,0x93,0x40,0x76,0x32,0x95,0x83,0xcd,0x41,0x05,0xa6,0x49,0xa9,0x29,0x2a,0xbc,0x44,0xcd,0x28,0xc4,0x00,0x00,0xc8,0xe2,0xf5,0xac,0x76,0x60,0xa8,0x1c,0x85,0xb7,0x2a,0xf8,0x45,0x2d,0x7d,0x25,0xc0,0x70,0x86,0x1d,0xae,0x91,0x60,0x1c,0x78,0x03,0xd6,0x56,0x53,0x16,0x50,0xdd,0x4e,0x5c,0x41,0x00,},"\x34\x86\xf6\x88\x48\xa6\x5a\x0e\xb5\x50\x7d"}, +{{0x5b,0x5a,0x61,0x9f,0x8c,0xe1,0xc6,0x6d,0x7c,0xe2,0x6e,0x5a,0x2a,0xe7,0xb0,0xc0,0x4f,0xeb,0xcd,0x34,0x6d,0x28,0x6c,0x92,0x9e,0x19,0xd0,0xd5,0x97,0x3b,0xfe,0xf9,},{0x6f,0xe8,0x36,0x93,0xd0,0x11,0xd1,0x11,0x13,0x1c,0x4f,0x3f,0xba,0xaa,0x40,0xa9,0xd3,0xd7,0x6b,0x30,0x01,0x2f,0xf7,0x3b,0xb0,0xe3,0x9e,0xc2,0x7a,0xb1,0x82,0x57,},{0x0f,0x9a,0xd9,0x79,0x30,0x33,0xa2,0xfa,0x06,0x61,0x4b,0x27,0x7d,0x37,0x38,0x1e,0x6d,0x94,0xf6,0x5a,0xc2,0xa5,0xa9,0x45,0x58,0xd0,0x9e,0xd6,0xce,0x92,0x22,0x58,0xc1,0xa5,0x67,0x95,0x2e,0x86,0x3a,0xc9,0x42,0x97,0xae,0xc3,0xc0,0xd0,0xc8,0xdd,0xf7,0x10,0x84,0xe5,0x04,0x86,0x0b,0xb6,0xba,0x27,0x44,0x9b,0x55,0xad,0xc4,0x0e,},"\x5a\x8d\x9d\x0a\x22\x35\x7e\x66\x55\xf9\xc7\x85"}, +{{0x94,0x0c,0x89,0xfe,0x40,0xa8,0x1d,0xaf,0xbd,0xb2,0x41,0x6d,0x14,0xae,0x46,0x91,0x19,0x86,0x97,0x44,0x41,0x0c,0x33,0x03,0xbf,0xaa,0x02,0x41,0xda,0xc5,0x78,0x00,},{0xa2,0xeb,0x8c,0x05,0x01,0xe3,0x0b,0xae,0x0c,0xf8,0x42,0xd2,0xbd,0xe8,0xde,0xc7,0x38,0x6f,0x6b,0x7f,0xc3,0x98,0x1b,0x8c,0x57,0xc9,0x79,0x2b,0xb9,0x4c,0xf2,0xdd,},{0xd8,0xbb,0x64,0xaa,0xd8,0xc9,0x95,0x5a,0x11,0x5a,0x79,0x3a,0xdd,0xd2,0x4f,0x7f,0x2b,0x07,0x76,0x48,0x71,0x4f,0x49,0xc4,0x69,0x4e,0xc9,0x95,0xb3,0x30,0xd0,0x9d,0x64,0x0d,0xf3,0x10,0xf4,0x47,0xfd,0x7b,0x6c,0xb5,0xc1,0x4f,0x9f,0xe9,0xf4,0x90,0xbc,0xf8,0xcf,0xad,0xbf,0xd2,0x16,0x9c,0x8a,0xc2,0x0d,0x3b,0x8a,0xf4,0x9a,0x0c,},"\xb8\x7d\x38\x13\xe0\x3f\x58\xcf\x19\xfd\x0b\x63\x95"}, +{{0x9a,0xca,0xd9,0x59,0xd2,0x16,0x21,0x2d,0x78,0x9a,0x11,0x92,0x52,0xeb,0xfe,0x0c,0x96,0x51,0x2a,0x23,0xc7,0x3b,0xd9,0xf3,0xb2,0x02,0x29,0x2d,0x69,0x16,0xa7,0x38,},{0xcf,0x3a,0xf8,0x98,0x46,0x7a,0x5b,0x7a,0x52,0xd3,0x3d,0x53,0xbc,0x03,0x7e,0x26,0x42,0xa8,0xda,0x99,0x69,0x03,0xfc,0x25,0x22,0x17,0xe9,0xc0,0x33,0xe2,0xf2,0x91,},{0x6e,0xe3,0xfe,0x81,0xe2,0x3c,0x60,0xeb,0x23,0x12,0xb2,0x00,0x6b,0x3b,0x25,0xe6,0x83,0x8e,0x02,0x10,0x66,0x23,0xf8,0x44,0xc4,0x4e,0xdb,0x8d,0xaf,0xd6,0x6a,0xb0,0x67,0x10,0x87,0xfd,0x19,0x5d,0xf5,0xb8,0xf5,0x8a,0x1d,0x6e,0x52,0xaf,0x42,0x90,0x80,0x53,0xd5,0x5c,0x73,0x21,0x01,0x00,0x92,0x74,0x87,0x95,0xef,0x94,0xcf,0x06,},"\x55\xc7\xfa\x43\x4f\x5e\xd8\xcd\xec\x2b\x7a\xea\xc1\x73"}, +{{0xd5,0xae,0xee,0x41,0xee,0xb0,0xe9,0xd1,0xbf,0x83,0x37,0xf9,0x39,0x58,0x7e,0xbe,0x29,0x61,0x61,0xe6,0xbf,0x52,0x09,0xf5,0x91,0xec,0x93,0x9e,0x14,0x40,0xc3,0x00,},{0xfd,0x2a,0x56,0x57,0x23,0x16,0x3e,0x29,0xf5,0x3c,0x9d,0xe3,0xd5,0xe8,0xfb,0xe3,0x6a,0x7a,0xb6,0x6e,0x14,0x39,0xec,0x4e,0xae,0x9c,0x0a,0x60,0x4a,0xf2,0x91,0xa5,},{0xf6,0x8d,0x04,0x84,0x7e,0x5b,0x24,0x97,0x37,0x89,0x9c,0x01,0x4d,0x31,0xc8,0x05,0xc5,0x00,0x7a,0x62,0xc0,0xa1,0x0d,0x50,0xbb,0x15,0x38,0xc5,0xf3,0x55,0x03,0x95,0x1f,0xbc,0x1e,0x08,0x68,0x2f,0x2c,0xc0,0xc9,0x2e,0xfe,0x8f,0x49,0x85,0xde,0xc6,0x1d,0xcb,0xd5,0x4d,0x4b,0x94,0xa2,0x25,0x47,0xd2,0x44,0x51,0x27,0x1c,0x8b,0x00,},"\x0a\x68\x8e\x79\xbe\x24\xf8\x66\x28\x6d\x46\x46\xb5\xd8\x1c"}, +{{0x0a,0x47,0xd1,0x04,0x52,0xae,0x2f,0xeb,0xec,0x51,0x8a,0x1c,0x7c,0x36,0x28,0x90,0xc3,0xfc,0x1a,0x49,0xd3,0x4b,0x03,0xb6,0x46,0x7d,0x35,0xc9,0x04,0xa8,0x36,0x2d,},{0x34,0xe5,0xa8,0x50,0x8c,0x47,0x43,0x74,0x69,0x62,0xc0,0x66,0xe4,0xba,0xde,0xa2,0x20,0x1b,0x8a,0xb4,0x84,0xde,0x5c,0x4f,0x94,0x47,0x6c,0xcd,0x21,0x43,0x95,0x5b,},{0x2a,0x3d,0x27,0xdc,0x40,0xd0,0xa8,0x12,0x79,0x49,0xa3,0xb7,0xf9,0x08,0xb3,0x68,0x8f,0x63,0xb7,0xf1,0x4f,0x65,0x1a,0xac,0xd7,0x15,0x94,0x0b,0xdb,0xe2,0x7a,0x08,0x09,0xaa,0xc1,0x42,0xf4,0x7a,0xb0,0xe1,0xe4,0x4f,0xa4,0x90,0xba,0x87,0xce,0x53,0x92,0xf3,0x3a,0x89,0x15,0x39,0xca,0xf1,0xef,0x4c,0x36,0x7c,0xae,0x54,0x50,0x0c,},"\xc9\x42\xfa\x7a\xc6\xb2\x3a\xb7\xff\x61\x2f\xdc\x8e\x68\xef\x39"}, +{{0xf8,0x14,0x8f,0x75,0x06,0xb7,0x75,0xef,0x46,0xfd,0xc8,0xe8,0xc7,0x56,0x51,0x68,0x12,0xd4,0x7d,0x6c,0xfb,0xfa,0x31,0x8c,0x27,0xc9,0xa2,0x26,0x41,0xe5,0x6f,0x17,},{0x04,0x45,0xe4,0x56,0xda,0xcc,0x7d,0x5b,0x0b,0xbe,0xd2,0x3c,0x82,0x00,0xcd,0xb7,0x4b,0xdc,0xb0,0x3e,0x4c,0x7b,0x73,0xf0,0xa2,0xb9,0xb4,0x6e,0xac,0x5d,0x43,0x72,},{0x36,0x53,0xcc,0xb2,0x12,0x19,0x20,0x2b,0x84,0x36,0xfb,0x41,0xa3,0x2b,0xa2,0x61,0x8c,0x4a,0x13,0x34,0x31,0xe6,0xe6,0x34,0x63,0xce,0xb3,0xb6,0x10,0x6c,0x4d,0x56,0xe1,0xd2,0xba,0x16,0x5b,0xa7,0x6e,0xaa,0xd3,0xdc,0x39,0xbf,0xfb,0x13,0x0f,0x1d,0xe3,0xd8,0xe6,0x42,0x7d,0xb5,0xb7,0x19,0x38,0xdb,0x4e,0x27,0x2b,0xc3,0xe2,0x0b,},"\x73\x68\x72\x4a\x5b\x0e\xfb\x57\xd2\x8d\x97\x62\x2d\xbd\xe7\x25\xaf"}, +{{0x77,0xf8,0x86,0x91,0xc4,0xef,0xf2,0x3e,0xbb,0x73,0x64,0x94,0x70,0x92,0x95,0x1a,0x5f,0xf3,0xf1,0x07,0x85,0xb4,0x17,0xe9,0x18,0x82,0x3a,0x55,0x2d,0xab,0x7c,0x75,},{0x74,0xd2,0x91,0x27,0xf1,0x99,0xd8,0x6a,0x86,0x76,0xae,0xc3,0x3b,0x4c,0xe3,0xf2,0x25,0xcc,0xb1,0x91,0xf5,0x2c,0x19,0x1c,0xcd,0x1e,0x8c,0xca,0x65,0x21,0x3a,0x6b,},{0xfb,0xe9,0x29,0xd7,0x43,0xa0,0x3c,0x17,0x91,0x05,0x75,0x49,0x2f,0x30,0x92,0xee,0x2a,0x2b,0xf1,0x4a,0x60,0xa3,0xfc,0xac,0xec,0x74,0xa5,0x8c,0x73,0x34,0x51,0x0f,0xc2,0x62,0xdb,0x58,0x27,0x91,0x32,0x2d,0x6c,0x8c,0x41,0xf1,0x70,0x0a,0xdb,0x80,0x02,0x7e,0xca,0xbc,0x14,0x27,0x0b,0x70,0x34,0x44,0xae,0x3e,0xe7,0x62,0x3e,0x0a,},"\xbd\x8e\x05\x03\x3f\x3a\x8b\xcd\xcb\xf4\xbe\xce\xb7\x09\x01\xc8\x2e\x31"}, +{{0xab,0x6f,0x7a,0xee,0x6a,0x08,0x37,0xb3,0x34,0xba,0x5e,0xb1,0xb2,0xad,0x7f,0xce,0xcf,0xab,0x7e,0x32,0x3c,0xab,0x18,0x7f,0xe2,0xe0,0xa9,0x5d,0x80,0xef,0xf1,0x32,},{0x5b,0x96,0xdc,0xa4,0x97,0x87,0x5b,0xf9,0x66,0x4c,0x5e,0x75,0xfa,0xcf,0x3f,0x9b,0xc5,0x4b,0xae,0x91,0x3d,0x66,0xca,0x15,0xee,0x85,0xf1,0x49,0x1c,0xa2,0x4d,0x2c,},{0x73,0xbc,0xa6,0x4e,0x9d,0xd0,0xdb,0x88,0x13,0x8e,0xed,0xfa,0xfc,0xea,0x8f,0x54,0x36,0xcf,0xb7,0x4b,0xfb,0x0e,0x77,0x33,0xcf,0x34,0x9b,0xaa,0x0c,0x49,0x77,0x5c,0x56,0xd5,0x93,0x4e,0x1d,0x38,0xe3,0x6f,0x39,0xb7,0xc5,0xbe,0xb0,0xa8,0x36,0x51,0x0c,0x45,0x12,0x6f,0x8e,0xc4,0xb6,0x81,0x05,0x19,0x90,0x5b,0x0c,0xa0,0x7c,0x09,},"\x81\x71\x45\x6f\x8b\x90\x71\x89\xb1\xd7\x79\xe2\x6b\xc5\xaf\xbb\x08\xc6\x7a"}, +{{0x8d,0x13,0x5d,0xe7,0xc8,0x41,0x1b,0xbd,0xbd,0x1b,0x31,0xe5,0xdc,0x67,0x8f,0x2a,0xc7,0x10,0x9e,0x79,0x2b,0x60,0xf3,0x8c,0xd2,0x49,0x36,0xe8,0xa8,0x98,0xc3,0x2d,},{0x1c,0xa2,0x81,0x93,0x85,0x29,0x89,0x65,0x35,0xa7,0x71,0x4e,0x35,0x84,0x08,0x5b,0x86,0xef,0x9f,0xec,0x72,0x3f,0x42,0x81,0x9f,0xc8,0xdd,0x5d,0x8c,0x00,0x81,0x7f,},{0xa1,0xad,0xc2,0xbc,0x6a,0x2d,0x98,0x06,0x62,0x67,0x7e,0x7f,0xdf,0xf6,0x42,0x4d,0xe7,0xdb,0xa5,0x0f,0x57,0x95,0xca,0x90,0xfd,0xf3,0xe9,0x6e,0x25,0x6f,0x32,0x85,0xca,0xc7,0x1d,0x33,0x60,0x48,0x2e,0x99,0x3d,0x02,0x94,0xba,0x4e,0xc7,0x44,0x0c,0x61,0xaf,0xfd,0xf3,0x5f,0xe8,0x3e,0x6e,0x04,0x26,0x39,0x37,0xdb,0x93,0xf1,0x05,},"\x8b\xa6\xa4\xc9\xa1\x5a\x24\x4a\x9c\x26\xbb\x2a\x59\xb1\x02\x6f\x21\x34\x8b\x49"}, +{{0x0e,0x76,0x5d,0x72,0x0e,0x70,0x5f,0x93,0x66,0xc1,0xab,0x8c,0x3f,0xa8,0x4c,0x9a,0x44,0x37,0x0c,0x06,0x96,0x9f,0x80,0x32,0x96,0x88,0x4b,0x28,0x46,0xa6,0x52,0xa4,},{0x7f,0xae,0x45,0xdd,0x0a,0x05,0x97,0x10,0x26,0xd4,0x10,0xbc,0x49,0x7a,0xf5,0xbe,0x7d,0x08,0x27,0xa8,0x2a,0x14,0x5c,0x20,0x3f,0x62,0x5d,0xfc,0xb8,0xb0,0x3b,0xa8,},{0xbb,0x61,0xcf,0x84,0xde,0x61,0x86,0x22,0x07,0xc6,0xa4,0x55,0x25,0x8b,0xc4,0xdb,0x4e,0x15,0xee,0xa0,0x31,0x7f,0xf8,0x87,0x18,0xb8,0x82,0xa0,0x6b,0x5c,0xf6,0xec,0x6f,0xd2,0x0c,0x5a,0x26,0x9e,0x5d,0x5c,0x80,0x5b,0xaf,0xbc,0xc5,0x79,0xe2,0x59,0x0a,0xf4,0x14,0xc7,0xc2,0x27,0x27,0x3c,0x10,0x2a,0x10,0x07,0x0c,0xdf,0xe8,0x0f,},"\x1d\x56\x6a\x62\x32\xbb\xaa\xb3\xe6\xd8\x80\x4b\xb5\x18\xa4\x98\xed\x0f\x90\x49\x86"}, +{{0xdb,0x36,0xe3,0x26,0xd6,0x76,0xc2,0xd1,0x9c,0xc8,0xfe,0x0c,0x14,0xb7,0x09,0x20,0x2e,0xcf,0xc7,0x61,0xd2,0x70,0x89,0xeb,0x6e,0xa4,0xb1,0xbb,0x02,0x1e,0xcf,0xa7,},{0x48,0x35,0x9b,0x85,0x0d,0x23,0xf0,0x71,0x5d,0x94,0xbb,0x8b,0xb7,0x5e,0x7e,0x14,0x32,0x2e,0xaf,0x14,0xf0,0x6f,0x28,0xa8,0x05,0x40,0x3f,0xbd,0xa0,0x02,0xfc,0x85,},{0xb6,0xdc,0xd0,0x99,0x89,0xdf,0xba,0xc5,0x43,0x22,0xa3,0xce,0x87,0x87,0x6e,0x1d,0x62,0x13,0x4d,0xa9,0x98,0xc7,0x9d,0x24,0xb5,0x0b,0xd7,0xa6,0xa7,0x97,0xd8,0x6a,0x0e,0x14,0xdc,0x9d,0x74,0x91,0xd6,0xc1,0x4a,0x67,0x3c,0x65,0x2c,0xfb,0xec,0x9f,0x96,0x2a,0x38,0xc9,0x45,0xda,0x3b,0x2f,0x08,0x79,0xd0,0xb6,0x8a,0x92,0x13,0x00,},"\x1b\x0a\xfb\x0a\xc4\xba\x9a\xb7\xb7\x17\x2c\xdd\xc9\xeb\x42\xbb\xa1\xa6\x4b\xce\x47\xd4"}, +{{0xc8,0x99,0x55,0xe0,0xf7,0x74,0x1d,0x90,0x5d,0xf0,0x73,0x0b,0x3d,0xc2,0xb0,0xce,0x1a,0x13,0x13,0x4e,0x44,0xfe,0xf3,0xd4,0x0d,0x60,0xc0,0x20,0xef,0x19,0xdf,0x77,},{0xfd,0xb3,0x06,0x73,0x40,0x2f,0xaf,0x1c,0x80,0x33,0x71,0x4f,0x35,0x17,0xe4,0x7c,0xc0,0xf9,0x1f,0xe7,0x0c,0xf3,0x83,0x6d,0x6c,0x23,0x63,0x6e,0x3f,0xd2,0x28,0x7c,},{0x7e,0xf6,0x6e,0x5e,0x86,0xf2,0x36,0x08,0x48,0xe0,0x01,0x4e,0x94,0x88,0x0a,0xe2,0x92,0x0a,0xd8,0xa3,0x18,0x5a,0x46,0xb3,0x5d,0x1e,0x07,0xde,0xa8,0xfa,0x8a,0xe4,0xf6,0xb8,0x43,0xba,0x17,0x4d,0x99,0xfa,0x79,0x86,0x65,0x4a,0x08,0x91,0xc1,0x2a,0x79,0x44,0x55,0x66,0x93,0x75,0xbf,0x92,0xaf,0x4c,0xc2,0x77,0x0b,0x57,0x9e,0x0c,},"\x50\x7c\x94\xc8\x82\x0d\x2a\x57\x93\xcb\xf3\x44\x2b\x3d\x71\x93\x6f\x35\xfe\x3a\xfe\xf3\x16"}, +{{0x4e,0x62,0x62,0x7f,0xc2,0x21,0x14,0x24,0x78,0xae,0xe7,0xf0,0x07,0x81,0xf8,0x17,0xf6,0x62,0xe3,0xb7,0x5d,0xb2,0x9b,0xb1,0x4a,0xb4,0x7c,0xf8,0xe8,0x41,0x04,0xd6,},{0xb1,0xd3,0x98,0x01,0x89,0x20,0x27,0xd5,0x8a,0x8c,0x64,0x33,0x51,0x63,0x19,0x58,0x93,0xbf,0xc1,0xb6,0x1d,0xbe,0xca,0x32,0x60,0x49,0x7e,0x1f,0x30,0x37,0x11,0x07,},{0x83,0x6a,0xfa,0x76,0x4d,0x9c,0x48,0xaa,0x47,0x70,0xa4,0x38,0x8b,0x65,0x4e,0x97,0xb3,0xc1,0x6f,0x08,0x29,0x67,0xfe,0xbc,0xa2,0x7f,0x2f,0xc4,0x7d,0xdf,0xd9,0x24,0x4b,0x03,0xcf,0xc7,0x29,0x69,0x8a,0xcf,0x51,0x09,0x70,0x43,0x46,0xb6,0x0b,0x23,0x0f,0x25,0x54,0x30,0x08,0x9d,0xdc,0x56,0x91,0x23,0x99,0xd1,0x12,0x2d,0xe7,0x0a,},"\xd3\xd6\x15\xa8\x47\x2d\x99\x62\xbb\x70\xc5\xb5\x46\x6a\x3d\x98\x3a\x48\x11\x04\x6e\x2a\x0e\xf5"}, +{{0x6b,0x83,0xd7,0xda,0x89,0x08,0xc3,0xe7,0x20,0x5b,0x39,0x86,0x4b,0x56,0xe5,0xf3,0xe1,0x71,0x96,0xa3,0xfc,0x9c,0x2f,0x58,0x05,0xaa,0xd0,0xf5,0x55,0x4c,0x14,0x2d,},{0xd0,0xc8,0x46,0xf9,0x7f,0xe2,0x85,0x85,0xc0,0xee,0x15,0x90,0x15,0xd6,0x4c,0x56,0x31,0x1c,0x88,0x6e,0xdd,0xcc,0x18,0x5d,0x29,0x6d,0xbb,0x16,0x5d,0x26,0x25,0xd6,},{0x16,0xe4,0x62,0xa2,0x9a,0x6d,0xd4,0x98,0x68,0x5a,0x37,0x18,0xb3,0xee,0xd0,0x0c,0xc1,0x59,0x86,0x01,0xee,0x47,0x82,0x04,0x86,0x03,0x2d,0x6b,0x9a,0xcc,0x9b,0xf8,0x9f,0x57,0x68,0x4e,0x08,0xd8,0xc0,0xf0,0x55,0x89,0xcd,0xa2,0x88,0x2a,0x05,0xdc,0x4c,0x63,0xf9,0xd0,0x43,0x1d,0x65,0x52,0x71,0x08,0x12,0x43,0x30,0x03,0xbc,0x08,},"\x6a\xda\x80\xb6\xfa\x84\xf7\x03\x49\x20\x78\x9e\x85\x36\xb8\x2d\x5e\x46\x78\x05\x9a\xed\x27\xf7\x1c"}, +{{0x19,0xa9,0x1f,0xe2,0x3a,0x4e,0x9e,0x33,0xec,0xc4,0x74,0x87,0x8f,0x57,0xc6,0x4c,0xf1,0x54,0xb3,0x94,0x20,0x34,0x87,0xa7,0x03,0x5e,0x1a,0xd9,0xcd,0x69,0x7b,0x0d,},{0x2b,0xf3,0x2b,0xa1,0x42,0xba,0x46,0x22,0xd8,0xf3,0xe2,0x9e,0xcd,0x85,0xee,0xa0,0x7b,0x9c,0x47,0xbe,0x9d,0x64,0x41,0x2c,0x9b,0x51,0x0b,0x27,0xdd,0x21,0x8b,0x23,},{0x88,0x1f,0x5b,0x8c,0x5a,0x03,0x0d,0xf0,0xf7,0x5b,0x66,0x34,0xb0,0x70,0xdd,0x27,0xbd,0x1e,0xe3,0xc0,0x87,0x38,0xae,0x34,0x93,0x38,0xb3,0xee,0x64,0x69,0xbb,0xf9,0x76,0x0b,0x13,0x57,0x8a,0x23,0x7d,0x51,0x82,0x53,0x5e,0xde,0x12,0x12,0x83,0x02,0x7a,0x90,0xb5,0xf8,0x65,0xd6,0x3a,0x65,0x37,0xdc,0xa0,0x7b,0x44,0x04,0x9a,0x0f,},"\x82\xcb\x53\xc4\xd5\xa0\x13\xba\xe5\x07\x07\x59\xec\x06\xc3\xc6\x95\x5a\xb7\xa4\x05\x09\x58\xec\x32\x8c"}, +{{0x1d,0x5b,0x8c,0xb6,0x21,0x5c,0x18,0x14,0x16,0x66,0xba,0xee,0xfc,0xf5,0xd6,0x9d,0xad,0x5b,0xea,0x9a,0x34,0x93,0xdd,0xda,0xa3,0x57,0xa4,0x39,0x7a,0x13,0xd4,0xde,},{0x94,0xd2,0x3d,0x97,0x7c,0x33,0xe4,0x9e,0x5e,0x49,0x92,0xc6,0x8f,0x25,0xec,0x99,0xa2,0x7c,0x41,0xce,0x6b,0x91,0xf2,0xbf,0xa0,0xcd,0x82,0x92,0xfe,0x96,0x28,0x35,},{0x3a,0xcd,0x39,0xbe,0xc8,0xc3,0xcd,0x2b,0x44,0x29,0x97,0x22,0xb5,0x85,0x0a,0x04,0x00,0xc1,0x44,0x35,0x90,0xfd,0x48,0x61,0xd5,0x9a,0xae,0x74,0x96,0xac,0xb3,0xdf,0x73,0xfc,0x3f,0xdf,0x79,0x69,0xae,0x5f,0x50,0xba,0x47,0xdd,0xdc,0x43,0x52,0x46,0xe5,0xfd,0x37,0x6f,0x6b,0x89,0x1c,0xd4,0xc2,0xca,0xf5,0xd6,0x14,0xb6,0x17,0x0c,},"\xa9\xa8\xcb\xb0\xad\x58\x51\x24\xe5\x22\xab\xbf\xb4\x05\x33\xbd\xd6\xf4\x93\x47\xb5\x5b\x18\xe8\x55\x8c\xb0"}, +{{0x6a,0x91,0xb3,0x22,0x7c,0x47,0x22,0x99,0x08,0x9b,0xdc,0xe9,0x35,0x6e,0x72,0x6a,0x40,0xef,0xd8,0x40,0xf1,0x10,0x02,0x70,0x8b,0x7e,0xe5,0x5b,0x64,0x10,0x5a,0xc2,},{0x9d,0x08,0x4a,0xa8,0xb9,0x7a,0x6b,0x9b,0xaf,0xa4,0x96,0xdb,0xc6,0xf7,0x6f,0x33,0x06,0xa1,0x16,0xc9,0xd9,0x17,0xe6,0x81,0x52,0x0a,0x0f,0x91,0x43,0x69,0x42,0x7e,},{0xf5,0x87,0x54,0x23,0x78,0x1b,0x66,0x21,0x6c,0xb5,0xe8,0x99,0x8d,0xe5,0xd9,0xff,0xc2,0x9d,0x1d,0x67,0x10,0x70,0x54,0xac,0xe3,0x37,0x45,0x03,0xa9,0xc3,0xef,0x81,0x15,0x77,0xf2,0x69,0xde,0x81,0x29,0x67,0x44,0xbd,0x70,0x6f,0x1a,0xc4,0x78,0xca,0xf0,0x9b,0x54,0xcd,0xf8,0x71,0xb3,0xf8,0x02,0xbd,0x57,0xf9,0xa6,0xcb,0x91,0x01,},"\x5c\xb6\xf9\xaa\x59\xb8\x0e\xca\x14\xf6\xa6\x8f\xb4\x0c\xf0\x7b\x79\x4e\x75\x17\x1f\xba\x96\x26\x2c\x1c\x6a\xdc"}, +{{0x93,0xea,0xa8,0x54,0xd7,0x91,0xf0,0x53,0x72,0xce,0x72,0xb9,0x4f,0xc6,0x50,0x3b,0x2f,0xf8,0xae,0x68,0x19,0xe6,0xa2,0x1a,0xfe,0x82,0x5e,0x27,0xad,0xa9,0xe4,0xfb,},{0x16,0xce,0xe8,0xa3,0xf2,0x63,0x18,0x34,0xc8,0x8b,0x67,0x08,0x97,0xff,0x0b,0x08,0xce,0x90,0xcc,0x14,0x7b,0x45,0x93,0xb3,0xf1,0xf4,0x03,0x72,0x7f,0x7e,0x7a,0xd5,},{0xd8,0x34,0x19,0x7c,0x1a,0x30,0x80,0x61,0x4e,0x0a,0x5f,0xa0,0xaa,0xaa,0x80,0x88,0x24,0xf2,0x1c,0x38,0xd6,0x92,0xe6,0xff,0xbd,0x20,0x0f,0x7d,0xfb,0x3c,0x8f,0x44,0x40,0x2a,0x73,0x82,0x18,0x0b,0x98,0xad,0x0a,0xfc,0x8e,0xec,0x1a,0x02,0xac,0xec,0xf3,0xcb,0x7f,0xde,0x62,0x7b,0x9f,0x18,0x11,0x1f,0x26,0x0a,0xb1,0xdb,0x9a,0x07,},"\x32\xfe\x27\x99\x41\x24\x20\x21\x53\xb5\xc7\x0d\x38\x13\xfd\xee\x9c\x2a\xa6\xe7\xdc\x74\x3d\x4d\x53\x5f\x18\x40\xa5"}, +{{0x94,0x1c,0xac,0x69,0xfb,0x7b,0x18,0x15,0xc5,0x7b,0xb9,0x87,0xc4,0xd6,0xc2,0xad,0x2c,0x35,0xd5,0xf9,0xa3,0x18,0x2a,0x79,0xd4,0xba,0x13,0xea,0xb2,0x53,0xa8,0xad,},{0x23,0xbe,0x32,0x3c,0x56,0x2d,0xfd,0x71,0xce,0x65,0xf5,0xbb,0xa5,0x6a,0x74,0xa3,0xa6,0xdf,0xc3,0x6b,0x57,0x3d,0x2f,0x94,0xf6,0x35,0xc7,0xf9,0xb4,0xfd,0x5a,0x5b,},{0x0f,0x8f,0xad,0x1e,0x6b,0xde,0x77,0x1b,0x4f,0x54,0x20,0xea,0xc7,0x5c,0x37,0x8b,0xae,0x6d,0xb5,0xac,0x66,0x50,0xcd,0x2b,0xc2,0x10,0xc1,0x82,0x3b,0x43,0x2b,0x48,0xe0,0x16,0xb1,0x05,0x95,0x45,0x8f,0xfa,0xb9,0x2f,0x7a,0x89,0x89,0xb2,0x93,0xce,0xb8,0xdf,0xed,0x6c,0x24,0x3a,0x20,0x38,0xfc,0x06,0x65,0x2a,0xaa,0xf1,0x6f,0x02,},"\xbb\x31\x72\x79\x57\x10\xfe\x00\x05\x4d\x3b\x5d\xfe\xf8\xa1\x16\x23\x58\x2d\xa6\x8b\xf8\xe4\x6d\x72\xd2\x7c\xec\xe2\xaa"}, +{{0x1a,0xcd,0xbb,0x79,0x3b,0x03,0x84,0x93,0x46,0x27,0x47,0x0d,0x79,0x5c,0x3d,0x1d,0xd4,0xd7,0x9c,0xea,0x59,0xef,0x98,0x3f,0x29,0x5b,0x9b,0x59,0x17,0x9c,0xbb,0x28,},{0x3f,0x60,0xc7,0x54,0x1a,0xfa,0x76,0xc0,0x19,0xcf,0x5a,0xa8,0x2d,0xcd,0xb0,0x88,0xed,0x9e,0x4e,0xd9,0x78,0x05,0x14,0xae,0xfb,0x37,0x9d,0xab,0xc8,0x44,0xf3,0x1a,},{0xbe,0x71,0xef,0x48,0x06,0xcb,0x04,0x1d,0x88,0x5e,0xff,0xd9,0xe6,0xb0,0xfb,0xb7,0x3d,0x65,0xd7,0xcd,0xec,0x47,0xa8,0x9c,0x8a,0x99,0x48,0x92,0xf4,0xe5,0x5a,0x56,0x8c,0x4c,0xc7,0x8d,0x61,0xf9,0x01,0xe8,0x0d,0xbb,0x62,0x8b,0x86,0xa2,0x3c,0xcd,0x59,0x4e,0x71,0x2b,0x57,0xfa,0x94,0xc2,0xd6,0x7e,0xc2,0x66,0x34,0x87,0x85,0x07,},"\x7c\xf3\x4f\x75\xc3\xda\xc9\xa8\x04\xd0\xfc\xd0\x9e\xba\x9b\x29\xc9\x48\x4e\x8a\x01\x8f\xa9\xe0\x73\x04\x2d\xf8\x8e\x3c\x56"}, +{{0x8e,0xd7,0xa7,0x97,0xb9,0xce,0xa8,0xa8,0x37,0x0d,0x41,0x91,0x36,0xbc,0xdf,0x68,0x3b,0x75,0x9d,0x2e,0x3c,0x69,0x47,0xf1,0x7e,0x13,0xe2,0x48,0x5a,0xa9,0xd4,0x20,},{0xb4,0x9f,0x3a,0x78,0xb1,0xc6,0xa7,0xfc,0xa8,0xf3,0x46,0x6f,0x33,0xbc,0x0e,0x92,0x9f,0x01,0xfb,0xa0,0x43,0x06,0xc2,0xa7,0x46,0x5f,0x46,0xc3,0x75,0x93,0x16,0xd9,},{0x04,0x26,0x6c,0x03,0x3b,0x91,0xc1,0x32,0x2c,0xeb,0x34,0x46,0xc9,0x01,0xff,0xcf,0x3c,0xc4,0x0c,0x40,0x34,0xe8,0x87,0xc9,0x59,0x7c,0xa1,0x89,0x3b,0xa7,0x33,0x0b,0xec,0xbb,0xd8,0xb4,0x81,0x42,0xef,0x35,0xc0,0x12,0xc6,0xba,0x51,0xa6,0x6d,0xf9,0x30,0x8c,0xb6,0x26,0x8a,0xd6,0xb1,0xe4,0xb0,0x3e,0x70,0x10,0x24,0x95,0x79,0x0b,},"\xa7\x50\xc2\x32\x93\x3d\xc1\x4b\x11\x84\xd8\x6d\x8b\x4c\xe7\x2e\x16\xd6\x97\x44\xba\x69\x81\x8b\x6a\xc3\x3b\x1d\x82\x3b\xb2\xc3"}, +{{0xf2,0xab,0x39,0x6f,0xe8,0x90,0x6e,0x3e,0x56,0x33,0xe9,0x9c,0xab,0xcd,0x5b,0x09,0xdf,0x08,0x59,0xb5,0x16,0x23,0x0b,0x1e,0x04,0x50,0xb5,0x80,0xb6,0x5f,0x61,0x6c,},{0x8e,0xa0,0x74,0x24,0x51,0x59,0xa1,0x16,0xaa,0x71,0x22,0xa2,0x5e,0xc1,0x6b,0x89,0x1d,0x62,0x5a,0x68,0xf3,0x36,0x60,0x42,0x39,0x08,0xf6,0xbd,0xc4,0x4f,0x8c,0x1b,},{0xa0,0x6a,0x23,0xd9,0x82,0xd8,0x1a,0xb8,0x83,0xaa,0xe2,0x30,0xad,0xbc,0x36,0x8a,0x6a,0x99,0x77,0xf0,0x03,0xce,0xbb,0x00,0xd4,0xc2,0xe4,0x01,0x84,0x90,0x19,0x1a,0x84,0xd3,0xa2,0x82,0xfd,0xbf,0xb2,0xfc,0x88,0x04,0x6e,0x62,0xde,0x43,0xe1,0x5f,0xb5,0x75,0x33,0x6b,0x3c,0x8b,0x77,0xd1,0x9c,0xe6,0xa0,0x09,0xce,0x51,0xf5,0x0c,},"\x5a\x44\xe3\x4b\x74\x6c\x5f\xd1\x89\x8d\x55\x2a\xb3\x54\xd2\x8f\xb4\x71\x38\x56\xd7\x69\x7d\xd6\x3e\xb9\xbd\x6b\x99\xc2\x80\xe1\x87"}, +{{0x55,0x0a,0x41,0xc0,0x13,0xf7,0x9b,0xab,0x8f,0x06,0xe4,0x3a,0xd1,0x83,0x6d,0x51,0x31,0x27,0x36,0xa9,0x71,0x38,0x06,0xfa,0xfe,0x66,0x45,0x21,0x9e,0xaa,0x1f,0x9d,},{0xaf,0x6b,0x71,0x45,0x47,0x4d,0xc9,0x95,0x4b,0x9a,0xf9,0x3a,0x9c,0xdb,0x34,0x44,0x9d,0x5b,0x7c,0x65,0x1c,0x82,0x4d,0x24,0xe2,0x30,0xb9,0x00,0x33,0xce,0x59,0xc0,},{0x16,0xdc,0x1e,0x2b,0x9f,0xa9,0x09,0xee,0xfd,0xc2,0x77,0xba,0x16,0xeb,0xe2,0x07,0xb8,0xda,0x5e,0x91,0x14,0x3c,0xde,0x78,0xc5,0x04,0x7a,0x89,0xf6,0x81,0xc3,0x3c,0x4e,0x4e,0x34,0x28,0xd5,0xc9,0x28,0x09,0x59,0x03,0xa8,0x11,0xec,0x00,0x2d,0x52,0xa3,0x9e,0xd7,0xf8,0xb3,0xfe,0x19,0x27,0x20,0x0c,0x6d,0xd0,0xb9,0xab,0x3e,0x04,},"\x8b\xc4\x18\x5e\x50\xe5\x7d\x5f\x87\xf4\x75\x15\xfe\x2b\x18\x37\xd5\x85\xf0\xaa\xe9\xe1\xca\x38\x3b\x3e\xc9\x08\x88\x4b\xb9\x00\xff\x27"}, +{{0x19,0xac,0x3e,0x27,0x24,0x38,0xc7,0x2d,0xdf,0x7b,0x88,0x19,0x64,0x86,0x7c,0xb3,0xb3,0x1f,0xf4,0xc7,0x93,0xbb,0x7e,0xa1,0x54,0x61,0x3c,0x1d,0xb0,0x68,0xcb,0x7e,},{0xf8,0x5b,0x80,0xe0,0x50,0xa1,0xb9,0x62,0x0d,0xb1,0x38,0xbf,0xc9,0xe1,0x00,0x32,0x7e,0x25,0xc2,0x57,0xc5,0x92,0x17,0xb6,0x01,0xf1,0xf6,0xac,0x9a,0x41,0x3d,0x3f,},{0xea,0x85,0x5d,0x78,0x1c,0xbe,0xa4,0x68,0x2e,0x35,0x01,0x73,0xcb,0x89,0xe8,0x61,0x9c,0xcf,0xdd,0xb9,0x7c,0xdc,0xe1,0x6f,0x9a,0x2f,0x6f,0x68,0x92,0xf4,0x6d,0xbe,0x68,0xe0,0x4b,0x12,0xb8,0xd8,0x86,0x89,0xa7,0xa3,0x16,0x70,0xcd,0xff,0x40,0x9a,0xf9,0x8a,0x93,0xb4,0x9a,0x34,0x53,0x7b,0x6a,0xa0,0x09,0xd2,0xeb,0x8b,0x47,0x01,},"\x95\x87\x2d\x5f\x78\x9f\x95\x48\x4e\x30\xcb\xb0\xe1\x14\x02\x89\x53\xb1\x6f\x5c\x6a\x8d\x9f\x65\xc0\x03\xa8\x35\x43\xbe\xaa\x46\xb3\x86\x45"}, +{{0xca,0x26,0x7d,0xe9,0x6c,0x93,0xc2,0x38,0xfa,0xfb,0x12,0x79,0x81,0x20,0x59,0xab,0x93,0xac,0x03,0x05,0x96,0x57,0xfd,0x99,0x4f,0x8f,0xa5,0xa0,0x92,0x39,0xc8,0x21,},{0x01,0x73,0x70,0xc8,0x79,0x09,0x0a,0x81,0xc7,0xf2,0x72,0xc2,0xfc,0x80,0xe3,0xaa,0xc2,0xbc,0x60,0x3f,0xcb,0x37,0x9a,0xfc,0x98,0x69,0x11,0x60,0xab,0x74,0x5b,0x26,},{0xac,0x95,0x7f,0x82,0x33,0x5a,0xa7,0x14,0x1e,0x96,0xb5,0x9d,0x63,0xe3,0xcc,0xee,0x95,0xc3,0xa2,0xc4,0x7d,0x02,0x65,0x40,0xc2,0xaf,0x42,0xdc,0x95,0x33,0xd5,0xfd,0x81,0x82,0x7d,0x16,0x79,0xad,0x18,0x7a,0xea,0xf3,0x78,0x34,0x91,0x5e,0x75,0xb1,0x47,0xa9,0x28,0x68,0x06,0xc8,0x01,0x75,0x16,0xba,0x43,0xdd,0x05,0x1a,0x5e,0x0c,},"\xe0\x5f\x71\xe4\xe4\x9a\x72\xec\x55\x0c\x44\xa3\xb8\x5a\xca\x8f\x20\xff\x26\xc3\xee\x94\xa8\x0f\x1b\x43\x1c\x7d\x15\x4e\xc9\x60\x3e\xe0\x25\x31"}, +{{0x3d,0xff,0x5e,0x89,0x94,0x75,0xe7,0xe9,0x1d,0xd2,0x61,0x32,0x2f,0xab,0x09,0x98,0x0c,0x52,0x97,0x0d,0xe1,0xda,0x6e,0x2e,0x20,0x16,0x60,0xcc,0x4f,0xce,0x70,0x32,},{0xf3,0x01,0x62,0xba,0xc9,0x84,0x47,0xc4,0x04,0x2f,0xac,0x05,0xda,0x44,0x80,0x34,0x62,0x9b,0xe2,0xc6,0xa5,0x8d,0x30,0xdf,0xd5,0x78,0xba,0x9f,0xb5,0xe3,0x93,0x0b,},{0x5e,0xfe,0x7a,0x92,0xff,0x96,0x23,0x08,0x9b,0x3e,0x3b,0x78,0xf3,0x52,0x11,0x53,0x66,0xe2,0x6b,0xa3,0xfb,0x1a,0x41,0x62,0x09,0xbc,0x02,0x9e,0x9c,0xad,0xcc,0xd9,0xf4,0xaf,0xfa,0x33,0x35,0x55,0xa8,0xf3,0xa3,0x5a,0x9d,0x0f,0x7c,0x34,0xb2,0x92,0xca,0xe7,0x7e,0xc9,0x6f,0xa3,0xad,0xfc,0xaa,0xde,0xe2,0xd9,0xce,0xd8,0xf8,0x05,},"\x93\x8f\x0e\x77\x62\x1b\xf3\xea\x52\xc7\xc4\x91\x1c\x51\x57\xc2\xd8\xa2\xa8\x58\x09\x3e\xf1\x6a\xa9\xb1\x07\xe6\x9d\x98\x03\x7b\xa1\x39\xa3\xc3\x82"}, +{{0x9a,0x6b,0x84,0x78,0x64,0xe7,0x0c,0xfe,0x8b,0xa6,0xab,0x22,0xfa,0x0c,0xa3,0x08,0xc0,0xcc,0x8b,0xec,0x71,0x41,0xfb,0xca,0xa3,0xb8,0x1f,0x5d,0x1e,0x1c,0xfc,0xfc,},{0x34,0xad,0x0f,0xbd,0xb2,0x56,0x65,0x07,0xa8,0x1c,0x2b,0x1f,0x8a,0xa8,0xf5,0x3d,0xcc,0xaa,0x64,0xcc,0x87,0xad,0xa9,0x1b,0x90,0x3e,0x90,0x0d,0x07,0xee,0xe9,0x30,},{0x2a,0xb2,0x55,0x16,0x9c,0x48,0x9c,0x54,0xc7,0x32,0x23,0x2e,0x37,0xc8,0x73,0x49,0xd4,0x86,0xb1,0xeb,0xa2,0x05,0x09,0xdb,0xab,0xe7,0xfe,0xd3,0x29,0xef,0x08,0xfd,0x75,0xba,0x1c,0xd1,0x45,0xe6,0x7b,0x2e,0xa2,0x6c,0xb5,0xcc,0x51,0xca,0xb3,0x43,0xee,0xb0,0x85,0xfe,0x1f,0xd7,0xb0,0xec,0x4c,0x6a,0xfc,0xd9,0xb9,0x79,0xf9,0x05,},"\x83\x83\x67\x47\x11\x83\xc7\x1f\x7e\x71\x77\x24\xf8\x9d\x40\x1c\x3a\xd9\x86\x3f\xd9\xcc\x7a\xa3\xcf\x33\xd3\xc5\x29\x86\x0c\xb5\x81\xf3\x09\x3d\x87\xda"}, +{{0x57,0x5b,0xe0,0x7a,0xfc,0xa5,0xd0,0x63,0xc2,0x38,0xcd,0x9b,0x80,0x28,0x77,0x2c,0xc4,0x9c,0xda,0x34,0x47,0x14,0x32,0xa2,0xe1,0x66,0xe0,0x96,0xe2,0x21,0x9e,0xfc,},{0x94,0xe5,0xeb,0x4d,0x50,0x24,0xf4,0x9d,0x7e,0xbf,0x79,0x81,0x7c,0x8d,0xe1,0x14,0x97,0xdc,0x2b,0x55,0x62,0x2a,0x51,0xae,0x12,0x3f,0xfc,0x74,0x9d,0xbb,0x16,0xe0,},{0x58,0x27,0x1d,0x44,0x23,0x6f,0x3b,0x98,0xc5,0x8f,0xd7,0xae,0x0d,0x2f,0x49,0xef,0x2b,0x6e,0x3a,0xff,0xdb,0x22,0x5a,0xa3,0xba,0x55,0x5f,0x0e,0x11,0xcc,0x53,0xc2,0x3a,0xd1,0x9b,0xaf,0x24,0x34,0x65,0x90,0xd0,0x5d,0x7d,0x53,0x90,0x58,0x20,0x82,0xcf,0x94,0xd3,0x9c,0xad,0x65,0x30,0xab,0x93,0xd1,0x3e,0xfb,0x39,0x27,0x95,0x06,},"\x33\xe5\x91\x8b\x66\xd3\x3d\x55\xfe\x71\x7c\xa3\x43\x83\xea\xe7\x8f\x0a\xf8\x28\x89\xca\xf6\x69\x6e\x1a\xc9\xd9\x5d\x1f\xfb\x32\xcb\xa7\x55\xf9\xe3\x50\x3e"}, +{{0x15,0xff,0xb4,0x55,0x14,0xd4,0x34,0x44,0xd6,0x1f,0xcb,0x10,0x5e,0x30,0xe1,0x35,0xfd,0x26,0x85,0x23,0xdd,0xa2,0x0b,0x82,0x75,0x8b,0x17,0x94,0x23,0x11,0x04,0x41,},{0x17,0x72,0xc5,0xab,0xc2,0xd2,0x3f,0xd2,0xf9,0xd1,0xc3,0x25,0x7b,0xe7,0xbc,0x3c,0x1c,0xd7,0x9c,0xee,0x40,0x84,0x4b,0x74,0x9b,0x3a,0x77,0x43,0xd2,0xf9,0x64,0xb8,},{0x68,0x28,0xcd,0x76,0x24,0xe7,0x93,0xb8,0xa4,0xce,0xb9,0x6d,0x3c,0x2a,0x97,0x5b,0xf7,0x73,0xe5,0xff,0x66,0x45,0xf3,0x53,0x61,0x40,0x58,0x62,0x1e,0x58,0x83,0x52,0x89,0xe7,0xf3,0x1f,0x42,0xdf,0xe6,0xaf,0x6d,0x73,0x6f,0x26,0x44,0x51,0x1e,0x32,0x0c,0x0f,0xa6,0x98,0x58,0x2a,0x79,0x77,0x8d,0x18,0x73,0x0e,0xd3,0xe8,0xcb,0x08,},"\xda\x9c\x55\x59\xd0\xea\x51\xd2\x55\xb6\xbd\x9d\x76\x38\xb8\x76\x47\x2f\x94\x2b\x33\x0f\xc0\xe2\xb3\x0a\xea\x68\xd7\x73\x68\xfc\xe4\x94\x82\x72\x99\x1d\x25\x7e"}, +{{0xfe,0x05,0x68,0x64,0x29,0x43,0xb2,0xe1,0xaf,0xbf,0xd1,0xf1,0x0f,0xe8,0xdf,0x87,0xa4,0x23,0x6b,0xea,0x40,0xdc,0xe7,0x42,0x07,0x2c,0xb2,0x18,0x86,0xee,0xc1,0xfa,},{0x29,0x9e,0xbd,0x1f,0x13,0x17,0x7d,0xbd,0xb6,0x6a,0x91,0x2b,0xbf,0x71,0x20,0x38,0xfd,0xf7,0x3b,0x06,0xc3,0xac,0x02,0x0c,0x7b,0x19,0x12,0x67,0x55,0xd4,0x7f,0x61,},{0xd5,0x9e,0x6d,0xfc,0xc6,0xd7,0xe3,0xe2,0xc5,0x8d,0xec,0x81,0xe9,0x85,0xd2,0x45,0xe6,0x81,0xac,0xf6,0x59,0x4a,0x23,0xc5,0x92,0x14,0xf7,0xbe,0xd8,0x01,0x5d,0x81,0x3c,0x76,0x82,0xb6,0x0b,0x35,0x83,0x44,0x03,0x11,0xe7,0x2a,0x86,0x65,0xba,0x2c,0x96,0xde,0xc2,0x3c,0xe8,0x26,0xe1,0x60,0x12,0x7e,0x18,0x13,0x2b,0x03,0x04,0x04,},"\xc5\x9d\x08\x62\xec\x1c\x97\x46\xab\xcc\x3c\xf8\x3c\x9e\xeb\xa2\xc7\x08\x2a\x03\x6a\x8c\xb5\x7c\xe4\x87\xe7\x63\x49\x27\x96\xd4\x7e\x6e\x06\x3a\x0c\x1f\xec\xcc\x2d"}, +{{0x5e,0xcb,0x16,0xc2,0xdf,0x27,0xc8,0xcf,0x58,0xe4,0x36,0xa9,0xd3,0xaf,0xfb,0xd5,0x8e,0x95,0x38,0xa9,0x26,0x59,0xa0,0xf9,0x7c,0x4c,0x4f,0x99,0x46,0x35,0xa8,0xca,},{0xda,0x76,0x8b,0x20,0xc4,0x37,0xdd,0x3a,0xa5,0xf8,0x4b,0xb6,0xa0,0x77,0xff,0xa3,0x4a,0xb6,0x85,0x01,0xc5,0x35,0x2b,0x5c,0xc3,0xfd,0xce,0x7f,0xe6,0xc2,0x39,0x8d,},{0x1c,0x72,0x3a,0x20,0xc6,0x77,0x24,0x26,0xa6,0x70,0xe4,0xd5,0xc4,0xa9,0x7c,0x6e,0xbe,0x91,0x47,0xf7,0x1b,0xb0,0xa4,0x15,0x63,0x1e,0x44,0x40,0x6e,0x29,0x03,0x22,0xe4,0xca,0x97,0x7d,0x34,0x8f,0xe7,0x85,0x6a,0x8e,0xdc,0x23,0x5d,0x0f,0xe9,0x5f,0x7e,0xd9,0x1a,0xef,0xdd,0xf2,0x8a,0x77,0xe2,0xc7,0xdb,0xfd,0x8f,0x55,0x2f,0x0a,},"\x56\xf1\x32\x9d\x9a\x6b\xe2\x5a\x61\x59\xc7\x2f\x12\x68\x8d\xc8\x31\x4e\x85\xdd\x9e\x7e\x4d\xc0\x5b\xbe\xcb\x77\x29\xe0\x23\xc8\x6f\x8e\x09\x37\x35\x3f\x27\xc7\xed\xe9"}, +{{0xd5,0x99,0xd6,0x37,0xb3,0xc3,0x0a,0x82,0xa9,0x98,0x4e,0x2f,0x75,0x84,0x97,0xd1,0x44,0xde,0x6f,0x06,0xb9,0xfb,0xa0,0x4d,0xd4,0x0f,0xd9,0x49,0x03,0x9d,0x7c,0x84,},{0x67,0x91,0xd8,0xce,0x50,0xa4,0x46,0x89,0xfc,0x17,0x87,0x27,0xc5,0xc3,0xa1,0xc9,0x59,0xfb,0xee,0xd7,0x4e,0xf7,0xd8,0xe7,0xbd,0x3c,0x1a,0xb4,0xda,0x31,0xc5,0x1f,},{0xeb,0xf1,0x0d,0x9a,0xc7,0xc9,0x61,0x08,0x14,0x0e,0x7d,0xef,0x6f,0xe9,0x53,0x3d,0x72,0x76,0x46,0xff,0x5b,0x3a,0xf2,0x73,0xc1,0xdf,0x95,0x76,0x2a,0x66,0xf3,0x2b,0x65,0xa0,0x96,0x34,0xd0,0x13,0xf5,0x4b,0x5d,0xd6,0x01,0x1f,0x91,0xbc,0x33,0x6c,0xa8,0xb3,0x55,0xce,0x33,0xf8,0xcf,0xbe,0xc2,0x53,0x5a,0x4c,0x42,0x7f,0x82,0x05,},"\xa7\xc0\x4e\x8b\xa7\x5d\x0a\x03\xd8\xb1\x66\xad\x7a\x1d\x77\xe1\xb9\x1c\x7a\xaf\x7b\xef\xdd\x99\x31\x1f\xc3\xc5\x4a\x68\x4d\xdd\x97\x1d\x5b\x32\x11\xc3\xee\xaf\xf1\xe5\x4e"}, +{{0x30,0xab,0x82,0x32,0xfa,0x70,0x18,0xf0,0xce,0x6c,0x39,0xbd,0x8f,0x78,0x2f,0xe2,0xe1,0x59,0x75,0x8b,0xb0,0xf2,0xf4,0x38,0x6c,0x7f,0x28,0xcf,0xd2,0xc8,0x58,0x98,},{0xec,0xfb,0x6a,0x2b,0xd4,0x2f,0x31,0xb6,0x12,0x50,0xba,0x5d,0xe7,0xe4,0x6b,0x47,0x19,0xaf,0xdf,0xbc,0x66,0x0d,0xb7,0x1a,0x7b,0xd1,0xdf,0x7b,0x0a,0x3a,0xbe,0x37,},{0x9a,0xf8,0x85,0x34,0x4c,0xc7,0x23,0x94,0x98,0xf7,0x12,0xdf,0x80,0xbc,0x01,0xb8,0x06,0x38,0x29,0x1e,0xd4,0xa1,0xd2,0x8b,0xaa,0x55,0x45,0x01,0x7a,0x72,0xe2,0xf6,0x56,0x49,0xcc,0xf9,0x60,0x3d,0xa6,0xeb,0x5b,0xfa,0xb9,0xf5,0x54,0x3a,0x6c,0xa4,0xa7,0xaf,0x38,0x66,0x15,0x3c,0x76,0xbf,0x66,0xbf,0x95,0xde,0xf6,0x15,0xb0,0x0c,},"\x63\xb8\x0b\x79\x56\xac\xbe\xcf\x0c\x35\xe9\xab\x06\xb9\x14\xb0\xc7\x01\x4f\xe1\xa4\xbb\xc0\x21\x72\x40\xc1\xa3\x30\x95\xd7\x07\x95\x3e\xd7\x7b\x15\xd2\x11\xad\xaf\x9b\x97\xdc"}, +{{0x0d,0xdc,0xdc,0x87,0x2c,0x7b,0x74,0x8d,0x40,0xef,0xe9,0x6c,0x28,0x81,0xae,0x18,0x9d,0x87,0xf5,0x61,0x48,0xed,0x8a,0xf3,0xeb,0xbb,0xc8,0x03,0x24,0xe3,0x8b,0xdd,},{0x58,0x8d,0xda,0xdc,0xbc,0xed,0xf4,0x0d,0xf0,0xe9,0x69,0x7d,0x8b,0xb2,0x77,0xc7,0xbb,0x14,0x98,0xfa,0x1d,0x26,0xce,0x0a,0x83,0x5a,0x76,0x0b,0x92,0xca,0x7c,0x85,},{0xc1,0x79,0xc0,0x94,0x56,0xe2,0x35,0xfe,0x24,0x10,0x5a,0xfa,0x6e,0x8e,0xc0,0x46,0x37,0xf8,0xf9,0x43,0x81,0x7c,0xd0,0x98,0xba,0x95,0x38,0x7f,0x96,0x53,0xb2,0xad,0xd1,0x81,0xa3,0x14,0x47,0xd9,0x2d,0x1a,0x1d,0xdf,0x1c,0xeb,0x0d,0xb6,0x21,0x18,0xde,0x9d,0xff,0xb7,0xdc,0xd2,0x42,0x40,0x57,0xcb,0xdf,0xf5,0xd4,0x1d,0x04,0x03,},"\x65\x64\x1c\xd4\x02\xad\xd8\xbf\x3d\x1d\x67\xdb\xeb\x6d\x41\xde\xbf\xbe\xf6\x7e\x43\x17\xc3\x5b\x0a\x6d\x5b\xbb\xae\x0e\x03\x4d\xe7\xd6\x70\xba\x14\x13\xd0\x56\xf2\xd6\xf1\xde\x12"}, +{{0x89,0xf0,0xd6,0x82,0x99,0xba,0x0a,0x5a,0x83,0xf2,0x48,0xae,0x0c,0x16,0x9f,0x8e,0x38,0x49,0xa9,0xb4,0x7b,0xd4,0x54,0x98,0x84,0x30,0x5c,0x99,0x12,0xb4,0x66,0x03,},{0xab,0xa3,0xe7,0x95,0xaa,0xb2,0x01,0x2a,0xcc,0xea,0xdd,0x7b,0x3b,0xd9,0xda,0xee,0xed,0x6f,0xf5,0x25,0x8b,0xdc,0xd7,0xc9,0x36,0x99,0xc2,0xa3,0x83,0x6e,0x38,0x32,},{0x2c,0x69,0x1f,0xa8,0xd4,0x87,0xce,0x20,0xd5,0xd2,0xfa,0x41,0x55,0x91,0x16,0xe0,0xbb,0xf4,0x39,0x7c,0xf5,0x24,0x0e,0x15,0x25,0x56,0x18,0x35,0x41,0xd6,0x6c,0xf7,0x53,0x58,0x24,0x01,0xa4,0x38,0x8d,0x39,0x03,0x39,0xdb,0xef,0x4d,0x38,0x47,0x43,0xca,0xa3,0x46,0xf5,0x5f,0x8d,0xab,0xa6,0x8b,0xa7,0xb9,0x13,0x1a,0x8a,0x6e,0x0b,},"\x4f\x18\x46\xdd\x7a\xd5\x0e\x54\x5d\x4c\xfb\xff\xbb\x1d\xc2\xff\x14\x5d\xc1\x23\x75\x4d\x08\xaf\x4e\x44\xec\xc0\xbc\x8c\x91\x41\x13\x88\xbc\x76\x53\xe2\xd8\x93\xd1\xea\xc2\x10\x7d\x05"}, +{{0x0a,0x3c,0x18,0x44,0xe2,0xdb,0x07,0x0f,0xb2,0x4e,0x3c,0x95,0xcb,0x1c,0xc6,0x71,0x4e,0xf8,0x4e,0x2c,0xcd,0x2b,0x9d,0xd2,0xf1,0x46,0x0e,0xbf,0x7e,0xcf,0x13,0xb1,},{0x72,0xe4,0x09,0x93,0x7e,0x06,0x10,0xeb,0x5c,0x20,0xb3,0x26,0xdc,0x6e,0xa1,0xbb,0xbc,0x04,0x06,0x70,0x1c,0x5c,0xd6,0x7d,0x1f,0xbd,0xe0,0x91,0x92,0xb0,0x7c,0x01,},{0x87,0xf7,0xfd,0xf4,0x60,0x95,0x20,0x1e,0x87,0x7a,0x58,0x8f,0xe3,0xe5,0xaa,0xf4,0x76,0xbd,0x63,0x13,0x8d,0x8a,0x87,0x8b,0x89,0xd6,0xac,0x60,0x63,0x1b,0x34,0x58,0xb9,0xd4,0x1a,0x3c,0x61,0xa5,0x88,0xe1,0xdb,0x8d,0x29,0xa5,0x96,0x89,0x81,0xb0,0x18,0x77,0x6c,0x58,0x87,0x80,0x92,0x2f,0x5a,0xa7,0x32,0xba,0x63,0x79,0xdd,0x05,},"\x4c\x82\x74\xd0\xed\x1f\x74\xe2\xc8\x6c\x08\xd9\x55\xbd\xe5\x5b\x2d\x54\x32\x7e\x82\x06\x2a\x1f\x71\xf7\x0d\x53\x6f\xdc\x87\x22\xcd\xea\xd7\xd2\x2a\xae\xad\x2b\xfa\xa1\xad\x00\xb8\x29\x57"}, +{{0xc8,0xd7,0xa8,0x81,0x8b,0x98,0xdf,0xdb,0x20,0x83,0x9c,0x87,0x1c,0xb5,0xc4,0x8e,0x9e,0x94,0x70,0xca,0x3a,0xd3,0x5b,0xa2,0x61,0x3a,0x5d,0x31,0x99,0xc8,0xab,0x23,},{0x90,0xd2,0xef,0xbb,0xa4,0xd4,0x3e,0x6b,0x2b,0x99,0x2c,0xa1,0x60,0x83,0xdb,0xcf,0xa2,0xb3,0x22,0x38,0x39,0x07,0xb0,0xee,0x75,0xf3,0xe9,0x58,0x45,0xd3,0xc4,0x7f,},{0xfa,0x2e,0x99,0x44,0x21,0xae,0xf1,0xd5,0x85,0x66,0x74,0x81,0x3d,0x05,0xcb,0xd2,0xcf,0x84,0xef,0x5e,0xb4,0x24,0xaf,0x6e,0xcd,0x0d,0xc6,0xfd,0xbd,0xc2,0xfe,0x60,0x5f,0xe9,0x85,0x88,0x33,0x12,0xec,0xf3,0x4f,0x59,0xbf,0xb2,0xf1,0xc9,0x14,0x9e,0x5b,0x9c,0xc9,0xec,0xda,0x05,0xb2,0x73,0x11,0x30,0xf3,0xed,0x28,0xdd,0xae,0x0b,},"\x78\x3e\x33\xc3\xac\xbd\xbb\x36\xe8\x19\xf5\x44\xa7\x78\x1d\x83\xfc\x28\x3d\x33\x09\xf5\xd3\xd1\x2c\x8d\xcd\x6b\x0b\x3d\x0e\x89\xe3\x8c\xfd\x3b\x4d\x08\x85\x66\x1c\xa5\x47\xfb\x97\x64\xab\xff"}, +{{0xb4,0x82,0x70,0x36,0x12,0xd0,0xc5,0x86,0xf7,0x6c,0xfc,0xb2,0x1c,0xfd,0x21,0x03,0xc9,0x57,0x25,0x15,0x04,0xa8,0xc0,0xac,0x4c,0x86,0xc9,0xc6,0xf3,0xe4,0x29,0xff,},{0xfd,0x71,0x1d,0xc7,0xdd,0x3b,0x1d,0xfb,0x9d,0xf9,0x70,0x4b,0xe3,0xe6,0xb2,0x6f,0x58,0x7f,0xe7,0xdd,0x7b,0xa4,0x56,0xa9,0x1b,0xa4,0x3f,0xe5,0x1a,0xec,0x09,0xad,},{0x58,0x83,0x2b,0xde,0xb2,0x6f,0xea,0xfc,0x31,0xb4,0x62,0x77,0xcf,0x3f,0xb5,0xd7,0xa1,0x7d,0xfb,0x7c,0xcd,0x9b,0x1f,0x58,0xec,0xbe,0x6f,0xeb,0x97,0x96,0x66,0x82,0x8f,0x23,0x9b,0xa4,0xd7,0x52,0x19,0x26,0x0e,0xca,0xc0,0xac,0xf4,0x0f,0x0e,0x5e,0x25,0x90,0xf4,0xca,0xa1,0x6b,0xbb,0xcd,0x8a,0x15,0x5d,0x34,0x79,0x67,0xa6,0x07,},"\x29\xd7\x7a\xcf\xd9\x9c\x7a\x00\x70\xa8\x8f\xeb\x62\x47\xa2\xbc\xe9\x98\x4f\xe3\xe6\xfb\xf1\x9d\x40\x45\x04\x2a\x21\xab\x26\xcb\xd7\x71\xe1\x84\xa9\xa7\x5f\x31\x6b\x64\x8c\x69\x20\xdb\x92\xb8\x7b"}, +{{0x84,0xe5,0x0d,0xd9,0xa0,0xf1,0x97,0xe3,0x89,0x3c,0x38,0xdb,0xd9,0x1f,0xaf,0xc3,0x44,0xc1,0x77,0x6d,0x3a,0x40,0x0e,0x2f,0x0f,0x0e,0xe7,0xaa,0x82,0x9e,0xb8,0xa2,},{0x2c,0x50,0xf8,0x70,0xee,0x48,0xb3,0x6b,0x0a,0xc2,0xf8,0xa5,0xf3,0x36,0xfb,0x09,0x0b,0x11,0x30,0x50,0xdb,0xcc,0x25,0xe0,0x78,0x20,0x0a,0x6e,0x16,0x15,0x3e,0xea,},{0x69,0xe6,0xa4,0x49,0x1a,0x63,0x83,0x73,0x16,0xe8,0x6a,0x5f,0x4b,0xa7,0xcd,0x0d,0x73,0x1e,0xcc,0x58,0xf1,0xd0,0xa2,0x64,0xc6,0x7c,0x89,0xbe,0xfd,0xd8,0xd3,0x82,0x9d,0x8d,0xe1,0x3b,0x33,0xcc,0x0b,0xf5,0x13,0x93,0x17,0x15,0xc7,0x80,0x96,0x57,0xe2,0xbf,0xb9,0x60,0xe5,0xc7,0x64,0xc9,0x71,0xd7,0x33,0x74,0x60,0x93,0xe5,0x00,},"\xf3\x99\x2c\xde\x64\x93\xe6\x71\xf1\xe1\x29\xdd\xca\x80\x38\xb0\xab\xdb\x77\xbb\x90\x35\xf9\xf8\xbe\x54\xbd\x5d\x68\xc1\xae\xff\x72\x4f\xf4\x7d\x29\x34\x43\x91\xdc\x53\x61\x66\xb8\x67\x1c\xbb\xf1\x23"}, +{{0xb3,0x22,0xd4,0x65,0x77,0xa2,0xa9,0x91,0xa4,0xd1,0x69,0x82,0x87,0x83,0x2a,0x39,0xc4,0x87,0xef,0x77,0x6b,0x4b,0xff,0x03,0x7a,0x05,0xc7,0xf1,0x81,0x2b,0xde,0xec,},{0xeb,0x2b,0xca,0xdf,0xd3,0xee,0xc2,0x98,0x6b,0xaf,0xf3,0x2b,0x98,0xe7,0xc4,0xdb,0xf0,0x3f,0xf9,0x5d,0x8a,0xd5,0xff,0x9a,0xa9,0x50,0x6e,0x54,0x72,0xff,0x84,0x5f,},{0xc7,0xb5,0x51,0x37,0x31,0x7c,0xa2,0x1e,0x33,0x48,0x9f,0xf6,0xa9,0xbf,0xab,0x97,0xc8,0x55,0xdc,0x6f,0x85,0x68,0x4a,0x70,0xa9,0x12,0x5a,0x26,0x1b,0x56,0xd5,0xe6,0xf1,0x49,0xc5,0x77,0x4d,0x73,0x4f,0x2d,0x8d,0xeb,0xfc,0x77,0xb7,0x21,0x89,0x6a,0x82,0x67,0xc2,0x37,0x68,0xe9,0xba,0xdb,0x91,0x0e,0xef,0x83,0xec,0x25,0x88,0x02,},"\x19\xf1\xbf\x5d\xcf\x17\x50\xc6\x11\xf1\xc4\xa2\x86\x52\x00\x50\x4d\x82\x29\x8e\xdd\x72\x67\x1f\x62\xa7\xb1\x47\x1a\xc3\xd4\xa3\x0f\x7d\xe9\xe5\xda\x41\x08\xc5\x2a\x4c\xe7\x0a\x3e\x11\x4a\x52\xa3\xb3\xc5"}, +{{0x96,0x0c,0xab,0x50,0x34,0xb9,0x83,0x8d,0x09,0x8d,0x2d,0xcb,0xf4,0x36,0x4b,0xec,0x16,0xd3,0x88,0xf6,0x37,0x6d,0x73,0xa6,0x27,0x3b,0x70,0xf8,0x2b,0xbc,0x98,0xc0,},{0x5e,0x3c,0x19,0xf2,0x41,0x5a,0xcf,0x72,0x9f,0x82,0x9a,0x4e,0xbd,0x5c,0x40,0xe1,0xa6,0xbc,0x9f,0xbc,0xa9,0x57,0x03,0xa9,0x37,0x60,0x87,0xed,0x09,0x37,0xe5,0x1a,},{0x27,0xd4,0xc3,0xa1,0x81,0x1e,0xf9,0xd4,0x36,0x0b,0x3b,0xdd,0x13,0x3c,0x2c,0xcc,0x30,0xd0,0x2c,0x2f,0x24,0x82,0x15,0x77,0x6c,0xb0,0x7e,0xe4,0x17,0x7f,0x9b,0x13,0xfc,0x42,0xdd,0x70,0xa6,0xc2,0xfe,0xd8,0xf2,0x25,0xc7,0x66,0x3c,0x7f,0x18,0x2e,0x7e,0xe8,0xec,0xcf,0xf2,0x0d,0xc7,0xb0,0xe1,0xd5,0x83,0x4e,0xc5,0xb1,0xea,0x01,},"\xf8\xb2\x19\x62\x44\x7b\x0a\x8f\x2e\x42\x79\xde\x41\x1b\xea\x12\x8e\x0b\xe4\x4b\x69\x15\xe6\xcd\xa8\x83\x41\xa6\x8a\x0d\x81\x83\x57\xdb\x93\x8e\xac\x73\xe0\xaf\x6d\x31\x20\x6b\x39\x48\xf8\xc4\x8a\x44\x73\x08"}, +{{0xeb,0x77,0xb2,0x63,0x8f,0x23,0xee,0xbc,0x82,0xef,0xe4,0x5e,0xe9,0xe5,0xa0,0x32,0x66,0x37,0x40,0x1e,0x66,0x3e,0xd0,0x29,0x69,0x9b,0x21,0xe6,0x44,0x3f,0xb4,0x8e,},{0x9e,0xf2,0x76,0x08,0x96,0x1a,0xc7,0x11,0xde,0x71,0xa6,0xe2,0xd4,0xd4,0x66,0x3e,0xa3,0xec,0xd4,0x2f,0xb7,0xe4,0xe8,0x62,0x7c,0x39,0x62,0x2d,0xf4,0xaf,0x0b,0xbc,},{0x18,0xdc,0x56,0xd7,0xbd,0x9a,0xcd,0x4f,0x4d,0xaa,0x78,0x54,0x0b,0x4a,0xc8,0xff,0x7a,0xa9,0x81,0x5f,0x45,0xa0,0xbb,0xa3,0x70,0x73,0x1a,0x14,0xea,0xab,0xe9,0x6d,0xf8,0xb5,0xf3,0x7d,0xbf,0x8e,0xae,0x4c,0xb1,0x5a,0x64,0xb2,0x44,0x65,0x1e,0x59,0xd6,0xa3,0xd6,0x76,0x1d,0x9e,0x3c,0x50,0xf2,0xd0,0xcb,0xb0,0x9c,0x05,0xec,0x06,},"\x99\xe3\xd0\x09\x34\x00\x3e\xba\xfc\x3e\x9f\xdb\x68\x7b\x0f\x5f\xf9\xd5\x78\x2a\x4b\x1f\x56\xb9\x70\x00\x46\xc0\x77\x91\x56\x02\xc3\x13\x4e\x22\xfc\x90\xed\x7e\x69\x0f\xdd\xd4\x43\x3e\x20\x34\xdc\xb2\xdc\x99\xab"}, +{{0xb6,0x25,0xaa,0x89,0xd3,0xf7,0x30,0x87,0x15,0x42,0x7b,0x6c,0x39,0xbb,0xac,0x58,0xef,0xfd,0x3a,0x0f,0xb7,0x31,0x6f,0x7a,0x22,0xb9,0x9e,0xe5,0x92,0x2f,0x2d,0xc9,},{0x65,0xa9,0x9c,0x3e,0x16,0xfe,0xa8,0x94,0xec,0x33,0xc6,0xb2,0x0d,0x91,0x05,0xe2,0xa0,0x4e,0x27,0x64,0xa4,0x76,0x9d,0x9b,0xbd,0x4d,0x8b,0xac,0xfe,0xab,0x4a,0x2e,},{0x01,0xbb,0x90,0x1d,0x83,0xb8,0xb6,0x82,0xd3,0x61,0x4a,0xf4,0x6a,0x80,0x7b,0xa2,0x69,0x13,0x58,0xfe,0xb7,0x75,0x32,0x5d,0x34,0x23,0xf5,0x49,0xff,0x0a,0xa5,0x75,0x7e,0x4e,0x1a,0x74,0xe9,0xc7,0x0f,0x97,0x21,0xd8,0xf3,0x54,0xb3,0x19,0xd4,0xf4,0xa1,0xd9,0x14,0x45,0xc8,0x70,0xfd,0x0f,0xfb,0x94,0xfe,0xd6,0x46,0x64,0x73,0x0d,},"\xe0\x72\x41\xdb\xd3\xad\xbe\x61\x0b\xbe\x4d\x00\x5d\xd4\x67\x32\xa4\xc2\x50\x86\xec\xb8\xec\x29\xcd\x7b\xca\x11\x6e\x1b\xf9\xf5\x3b\xfb\xf3\xe1\x1f\xa4\x90\x18\xd3\x9f\xf1\x15\x4a\x06\x66\x8e\xf7\xdf\x5c\x67\x8e\x6a"}, +{{0xb1,0xc9,0xf8,0xbd,0x03,0xfe,0x82,0xe7,0x8f,0x5c,0x0f,0xb0,0x64,0x50,0xf2,0x7d,0xac,0xdf,0x71,0x64,0x34,0xdb,0x26,0x82,0x75,0xdf,0x3e,0x1d,0xc1,0x77,0xaf,0x42,},{0x7f,0xc8,0x8b,0x1f,0x7b,0x3f,0x11,0xc6,0x29,0xbe,0x67,0x1c,0x21,0x62,0x1f,0x5c,0x10,0x67,0x2f,0xaf,0xc8,0x49,0x2d,0xa8,0x85,0x74,0x20,0x59,0xee,0x67,0x74,0xcf,},{0x4b,0x22,0x99,0x51,0xef,0x26,0x2f,0x16,0x97,0x8f,0x79,0x14,0xbc,0x67,0x2e,0x72,0x26,0xc5,0xf8,0x37,0x9d,0x27,0x78,0xc5,0xa2,0xdc,0x0a,0x26,0x50,0x86,0x9f,0x7a,0xcf,0xbd,0x0b,0xcd,0x30,0xfd,0xb0,0x61,0x9b,0xb4,0x4f,0xc1,0xae,0x59,0x39,0xb8,0x7c,0xc3,0x18,0x13,0x30,0x09,0xc2,0x03,0x95,0xb6,0xc7,0xeb,0x98,0x10,0x77,0x01,},"\x33\x1d\xa7\xa9\xc1\xf8\x7b\x2a\xc9\x1e\xe3\xb8\x6d\x06\xc2\x91\x63\xc0\x5e\xd6\xf8\xd8\xa9\x72\x5b\x47\x1b\x7d\xb0\xd6\xac\xec\x7f\x0f\x70\x24\x87\x16\x3f\x5e\xda\x02\x0c\xa5\xb4\x93\xf3\x99\xe1\xc8\xd3\x08\xc3\xc0\xc2"}, +{{0x6d,0x8c,0xdb,0x2e,0x07,0x5f,0x3a,0x2f,0x86,0x13,0x72,0x14,0xcb,0x23,0x6c,0xeb,0x89,0xa6,0x72,0x8b,0xb4,0xa2,0x00,0x80,0x6b,0xf3,0x55,0x7f,0xb7,0x8f,0xac,0x69,},{0x57,0xa0,0x4c,0x7a,0x51,0x13,0xcd,0xdf,0xe4,0x9a,0x4c,0x12,0x46,0x91,0xd4,0x6c,0x1f,0x9c,0xdc,0x8f,0x34,0x3f,0x9d,0xcb,0x72,0xa1,0x33,0x0a,0xec,0xa7,0x1f,0xda,},{0xa6,0xcb,0xc9,0x47,0xf9,0xc8,0x7d,0x14,0x55,0xcf,0x1a,0x70,0x85,0x28,0xc0,0x90,0xf1,0x1e,0xce,0xe4,0x85,0x5d,0x1d,0xba,0xad,0xf4,0x74,0x54,0xa4,0xde,0x55,0xfa,0x4c,0xe8,0x4b,0x36,0xd7,0x3a,0x5b,0x5f,0x8f,0x59,0x29,0x8c,0xcf,0x21,0x99,0x2d,0xf4,0x92,0xef,0x34,0x16,0x3d,0x87,0x75,0x3b,0x7e,0x9d,0x32,0xf2,0xc3,0x66,0x0b,},"\x7f\x31\x8d\xbd\x12\x1c\x08\xbf\xdd\xfe\xff\x4f\x6a\xff\x4e\x45\x79\x32\x51\xf8\xab\xf6\x58\x40\x33\x58\x23\x89\x84\x36\x00\x54\xf2\xa8\x62\xc5\xbb\x83\xed\x89\x02\x5d\x20\x14\xa7\xa0\xce\xe5\x0d\xa3\xcb\x0e\x76\xbb\xb6\xbf"}, +{{0x47,0xad,0xc6,0xd6,0xbf,0x57,0x1e,0xe9,0x57,0x0c,0xa0,0xf7,0x5b,0x60,0x4a,0xc4,0x3e,0x30,0x3e,0x4a,0xb3,0x39,0xca,0x9b,0x53,0xca,0xcc,0x5b,0xe4,0x5b,0x2c,0xcb,},{0xa3,0xf5,0x27,0xa1,0xc1,0xf1,0x7d,0xfe,0xed,0x92,0x27,0x73,0x47,0xc9,0xf9,0x8a,0xb4,0x75,0xde,0x17,0x55,0xb0,0xab,0x54,0x6b,0x8a,0x15,0xd0,0x1b,0x9b,0xd0,0xbe,},{0x4e,0x8c,0x31,0x83,0x43,0xc3,0x06,0xad,0xbb,0xa6,0x0c,0x92,0xb7,0x5c,0xb0,0x56,0x9b,0x92,0x19,0xd8,0xa8,0x6e,0x5d,0x57,0x75,0x2e,0xd2,0x35,0xfc,0x10,0x9a,0x43,0xc2,0xcf,0x4e,0x94,0x2c,0xac,0xf2,0x97,0x27,0x9f,0xbb,0x28,0x67,0x53,0x47,0xe0,0x80,0x27,0x72,0x2a,0x4e,0xb7,0x39,0x5e,0x00,0xa1,0x74,0x95,0xd3,0x2e,0xdf,0x0b,},"\xce\x49\x7c\x5f\xf5\xa7\x79\x90\xb7\xd8\xf8\x69\x9e\xb1\xf5\xd8\xc0\x58\x2f\x70\xcb\x7a\xc5\xc5\x4d\x9d\x92\x49\x13\x27\x8b\xc6\x54\xd3\x7e\xa2\x27\x59\x0e\x15\x20\x22\x17\xfc\x98\xda\xc4\xc0\xf3\xbe\x21\x83\xd1\x33\x31\x57\x39"}, +{{0x3c,0x19,0xb5,0x0b,0x0f,0xe4,0x79,0x61,0x71,0x9c,0x38,0x1d,0x0d,0x8d,0xa9,0xb9,0x86,0x9d,0x31,0x2f,0x13,0xe3,0x29,0x8b,0x97,0xfb,0x22,0xf0,0xaf,0x29,0xcb,0xbe,},{0x0f,0x7e,0xda,0x09,0x14,0x99,0x62,0x5e,0x2b,0xae,0x85,0x36,0xea,0x35,0xcd,0xa5,0x48,0x3b,0xd1,0x6a,0x9c,0x7e,0x41,0x6b,0x34,0x1d,0x6f,0x2c,0x83,0x34,0x36,0x12,},{0xef,0xbd,0x41,0xf2,0x6a,0x5d,0x62,0x68,0x55,0x16,0xf8,0x82,0xb6,0xec,0x74,0xe0,0xd5,0xa7,0x18,0x30,0xd2,0x03,0xc2,0x31,0x24,0x8f,0x26,0xe9,0x9a,0x9c,0x65,0x78,0xec,0x90,0x0d,0x68,0xcd,0xb8,0xfa,0x72,0x16,0xad,0x0d,0x24,0xf9,0xec,0xbc,0x9f,0xfa,0x65,0x53,0x51,0x66,0x65,0x82,0xf6,0x26,0x64,0x53,0x95,0xa3,0x1f,0xa7,0x04,},"\x8d\xdc\xd6\x30\x43\xf5\x5e\xc3\xbf\xc8\x3d\xce\xae\x69\xd8\xf8\xb3\x2f\x4c\xdb\x6e\x2a\xeb\xd9\x4b\x43\x14\xf8\xfe\x72\x87\xdc\xb6\x27\x32\xc9\x05\x2e\x75\x57\xfe\x63\x53\x43\x38\xef\xb5\xb6\x25\x4c\x5d\x41\xd2\x69\x0c\xf5\x14\x4f"}, +{{0x34,0xe1,0xe9,0xd5,0x39,0x10,0x7e,0xb8,0x6b,0x39,0x3a,0x5c,0xce,0xa1,0x49,0x6d,0x35,0xbc,0x7d,0x5e,0x9a,0x8c,0x51,0x59,0xd9,0x57,0xe4,0xe5,0x85,0x2b,0x3e,0xb0,},{0x0e,0xcb,0x26,0x01,0xd5,0xf7,0x04,0x74,0x28,0xe9,0xf9,0x09,0x88,0x3a,0x12,0x42,0x00,0x85,0xf0,0x4e,0xe2,0xa8,0x8b,0x6d,0x95,0xd3,0xd7,0xf2,0xc9,0x32,0xbd,0x76,},{0x32,0xd2,0x29,0x04,0xd3,0xe7,0x01,0x2d,0x6f,0x5a,0x44,0x1b,0x0b,0x42,0x28,0x06,0x4a,0x5c,0xf9,0x5b,0x72,0x3a,0x66,0xb0,0x48,0xa0,0x87,0xec,0xd5,0x59,0x20,0xc3,0x1c,0x20,0x4c,0x3f,0x20,0x06,0x89,0x1a,0x85,0xdd,0x19,0x32,0xe3,0xf1,0xd6,0x14,0xcf,0xd6,0x33,0xb5,0xe6,0x32,0x91,0xc6,0xd8,0x16,0x6f,0x30,0x11,0x43,0x1e,0x09,},"\xa6\xd4\xd0\x54\x2c\xfe\x0d\x24\x0a\x90\x50\x7d\xeb\xac\xab\xce\x7c\xbb\xd4\x87\x32\x35\x3f\x4f\xad\x82\xc7\xbb\x7d\xbd\x9d\xf8\xe7\xd9\xa1\x69\x80\xa4\x51\x86\xd8\x78\x6c\x5e\xf6\x54\x45\xbc\xc5\xb2\xad\x5f\x66\x0f\xfc\x7c\x8e\xaa\xc0"}, +{{0x49,0xdd,0x47,0x3e,0xde,0x6a,0xa3,0xc8,0x66,0x82,0x4a,0x40,0xad,0xa4,0x99,0x6c,0x23,0x9a,0x20,0xd8,0x4c,0x93,0x65,0xe4,0xf0,0xa4,0x55,0x4f,0x80,0x31,0xb9,0xcf,},{0x78,0x8d,0xe5,0x40,0x54,0x4d,0x3f,0xeb,0x0c,0x91,0x92,0x40,0xb3,0x90,0x72,0x9b,0xe4,0x87,0xe9,0x4b,0x64,0xad,0x97,0x3e,0xb6,0x5b,0x46,0x69,0xec,0xf2,0x35,0x01,},{0xd2,0xfd,0xe0,0x27,0x91,0xe7,0x20,0x85,0x25,0x07,0xfa,0xa7,0xc3,0x78,0x90,0x40,0xd9,0xef,0x86,0x64,0x63,0x21,0xf3,0x13,0xac,0x55,0x7f,0x40,0x02,0x49,0x15,0x42,0xdd,0x67,0xd0,0x5c,0x69,0x90,0xcd,0xb0,0xd4,0x95,0x50,0x1f,0xbc,0x5d,0x51,0x88,0xbf,0xbb,0x84,0xdc,0x1b,0xf6,0x09,0x8b,0xee,0x06,0x03,0xa4,0x7f,0xc2,0x69,0x0f,},"\x3a\x53\x59\x4f\x3f\xba\x03\x02\x93\x18\xf5\x12\xb0\x84\xa0\x71\xeb\xd6\x0b\xae\xc7\xf5\x5b\x02\x8d\xc7\x3b\xfc\x9c\x74\xe0\xca\x49\x6b\xf8\x19\xdd\x92\xab\x61\xcd\x8b\x74\xbe\x3c\x0d\x6d\xcd\x12\x8e\xfc\x5e\xd3\x34\x2c\xba\x12\x4f\x72\x6c"}, +{{0x33,0x1c,0x64,0xda,0x48,0x2b,0x6b,0x55,0x13,0x73,0xc3,0x64,0x81,0xa0,0x2d,0x81,0x36,0xec,0xad,0xbb,0x01,0xab,0x11,0x4b,0x44,0x70,0xbf,0x41,0x60,0x7a,0xc5,0x71,},{0x52,0xa0,0x0d,0x96,0xa3,0x14,0x8b,0x47,0x26,0x69,0x2d,0x9e,0xff,0x89,0x16,0x0e,0xa9,0xf9,0x9a,0x5c,0xc4,0x38,0x9f,0x36,0x1f,0xed,0x0b,0xb1,0x6a,0x42,0xd5,0x21,},{0x22,0xc9,0x9a,0xa9,0x46,0xea,0xd3,0x9a,0xc7,0x99,0x75,0x62,0x81,0x0c,0x01,0xc2,0x0b,0x46,0xbd,0x61,0x06,0x45,0xbd,0x2d,0x56,0xdc,0xdc,0xba,0xac,0xc5,0x45,0x2c,0x74,0xfb,0xf4,0xb8,0xb1,0x81,0x3b,0x0e,0x94,0xc3,0x0d,0x80,0x8c,0xe5,0x49,0x8e,0x61,0xd4,0xf7,0xcc,0xbb,0x4c,0xc5,0xf0,0x4d,0xfc,0x61,0x40,0x82,0x5a,0x96,0x00,},"\x20\xe1\xd0\x5a\x0d\x5b\x32\xcc\x81\x50\xb8\x11\x6c\xef\x39\x65\x9d\xd5\xfb\x44\x3a\xb1\x56\x00\xf7\x8e\x5b\x49\xc4\x53\x26\xd9\x32\x3f\x28\x50\xa6\x3c\x38\x08\x85\x94\x95\xae\x27\x3f\x58\xa5\x1e\x9d\xe9\xa1\x45\xd7\x74\xb4\x0b\xa9\xd7\x53\xd3"}, +{{0x5c,0x0b,0x96,0xf2,0xaf,0x87,0x12,0x12,0x2c,0xf7,0x43,0xc8,0xf8,0xdc,0x77,0xb6,0xcd,0x55,0x70,0xa7,0xde,0x13,0x29,0x7b,0xb3,0xdd,0xe1,0x88,0x62,0x13,0xcc,0xe2,},{0x05,0x10,0xea,0xf5,0x7d,0x73,0x01,0xb0,0xe1,0xd5,0x27,0x03,0x9b,0xf4,0xc6,0xe2,0x92,0x30,0x0a,0x3a,0x61,0xb4,0x76,0x54,0x34,0xf3,0x20,0x3c,0x10,0x03,0x51,0xb1,},{0x06,0xe5,0xd8,0x43,0x6a,0xc7,0x70,0x5b,0x3a,0x90,0xf1,0x63,0x1c,0xdd,0x38,0xec,0x1a,0x3f,0xa4,0x97,0x78,0xa9,0xb9,0xf2,0xfa,0x5e,0xbe,0xa4,0xe7,0xd5,0x60,0xad,0xa7,0xdd,0x26,0xff,0x42,0xfa,0xfa,0x8b,0xa4,0x20,0x32,0x37,0x42,0x76,0x1a,0xca,0x69,0x04,0x94,0x0d,0xc2,0x1b,0xbe,0xf6,0x3f,0xf7,0x2d,0xaa,0xb4,0x5d,0x43,0x0b,},"\x54\xe0\xca\xa8\xe6\x39\x19\xca\x61\x4b\x2b\xfd\x30\x8c\xcf\xe5\x0c\x9e\xa8\x88\xe1\xee\x44\x46\xd6\x82\xcb\x50\x34\x62\x7f\x97\xb0\x53\x92\xc0\x4e\x83\x55\x56\xc3\x1c\x52\x81\x6a\x48\xe4\xfb\x19\x66\x93\x20\x6b\x8a\xfb\x44\x08\x66\x2b\x3c\xb5\x75"}, +{{0xde,0x84,0xf2,0x43,0x5f,0x78,0xde,0xdb,0x87,0xda,0x18,0x19,0x4f,0xf6,0xa3,0x36,0xf0,0x81,0x11,0x15,0x0d,0xef,0x90,0x1c,0x1a,0xc4,0x18,0x14,0x6e,0xb7,0xb5,0x4a,},{0xd3,0xa9,0x2b,0xba,0xa4,0xd6,0x3a,0xf7,0x9c,0x22,0x26,0xa7,0x23,0x6e,0x64,0x27,0x42,0x8d,0xf8,0xb3,0x62,0x42,0x7f,0x87,0x30,0x23,0xb2,0x2d,0x2f,0x5e,0x03,0xf2,},{0x47,0x1e,0xbc,0x97,0x3c,0xfd,0xac,0xee,0xc0,0x72,0x79,0x30,0x73,0x68,0xb7,0x3b,0xe3,0x5b,0xc6,0xf8,0xd8,0x31,0x2b,0x70,0x15,0x05,0x67,0x36,0x90,0x96,0x70,0x6d,0xc4,0x71,0x12,0x6c,0x35,0x76,0xf9,0xf0,0xeb,0x55,0x0d,0xf5,0xac,0x6a,0x52,0x51,0x81,0x11,0x00,0x29,0xdd,0x1f,0xc1,0x11,0x74,0xd1,0xaa,0xce,0xd4,0x8d,0x63,0x0f,},"\x20\x51\x35\xec\x7f\x41\x7c\x85\x80\x72\xd5\x23\x3f\xb3\x64\x82\xd4\x90\x6a\xbd\x60\xa7\x4a\x49\x8c\x34\x7f\xf2\x48\xdf\xa2\x72\x2c\xa7\x4e\x87\x9d\xe3\x31\x69\xfa\xdc\x7c\xd4\x4d\x6c\x94\xa1\x7d\x16\xe1\xe6\x30\x82\x4b\xa3\xe0\xdf\x22\xed\x68\xea\xab"}, +{{0xba,0x4d,0x6e,0x67,0xb2,0xce,0x67,0xa1,0xe4,0x43,0x26,0x49,0x40,0x44,0xf3,0x7a,0x44,0x2f,0x3b,0x81,0x72,0x5b,0xc1,0xf9,0x34,0x14,0x62,0x71,0x8b,0x55,0xee,0x20,},{0xf7,0x3f,0xa0,0x76,0xf8,0x4b,0x6d,0xb6,0x75,0xa5,0xfd,0xa5,0xad,0x67,0xe3,0x51,0xa4,0x1e,0x8e,0x7f,0x29,0xad,0xd1,0x68,0x09,0xca,0x01,0x03,0x87,0xe9,0xc6,0xcc,},{0x57,0xb9,0xd2,0xa7,0x11,0x20,0x7f,0x83,0x74,0x21,0xba,0xe7,0xdd,0x48,0xea,0xa1,0x8e,0xab,0x1a,0x9a,0x70,0xa0,0xf1,0x30,0x58,0x06,0xfe,0xe1,0x7b,0x45,0x8f,0x3a,0x09,0x64,0xb3,0x02,0xd1,0x83,0x4d,0x3e,0x0a,0xc9,0xe8,0x49,0x6f,0x00,0x0b,0x77,0xf0,0x08,0x3b,0x41,0xf8,0xa9,0x57,0xe6,0x32,0xfb,0xc7,0x84,0x0e,0xee,0x6a,0x06,},"\x4b\xaf\xda\xc9\x09\x9d\x40\x57\xed\x6d\xd0\x8b\xca\xee\x87\x56\xe9\xa4\x0f\x2c\xb9\x59\x80\x20\xeb\x95\x01\x95\x28\x40\x9b\xbe\xa3\x8b\x38\x4a\x59\xf1\x19\xf5\x72\x97\xbf\xb2\xfa\x14\x2f\xc7\xbb\x1d\x90\xdb\xdd\xde\x77\x2b\xcd\xe4\x8c\x56\x70\xd5\xfa\x13"}, +{{0x0d,0x13,0x1c,0x45,0xae,0xa6,0xf3,0xa4,0xe1,0xb9,0xa2,0xcf,0x60,0xc5,0x51,0x04,0x58,0x7e,0xfa,0xa8,0x46,0xb2,0x22,0xbf,0x0a,0x7b,0x74,0xce,0x7a,0x3f,0x63,0xb6,},{0x3c,0x67,0x29,0xdb,0xe9,0x3b,0x49,0x9c,0x4e,0x61,0x4a,0x2f,0x21,0xbe,0xb7,0x29,0x43,0x8d,0x49,0x8e,0x1a,0xc8,0xd1,0x4c,0xba,0xd9,0x71,0x7a,0x5d,0xbd,0x97,0xcd,},{0xa9,0xc5,0xee,0x86,0xfb,0x06,0xd9,0xe4,0x6b,0x37,0x9c,0x32,0xdd,0xa7,0xc9,0x2c,0x9c,0x13,0xdb,0x27,0x4d,0xc2,0x41,0x16,0xfb,0xdd,0x87,0x86,0x96,0x04,0x54,0x88,0xcc,0x75,0xa5,0x2f,0xff,0x67,0xd1,0xa5,0x11,0x3d,0x06,0xe3,0x33,0xac,0x67,0xff,0x66,0x4b,0x3f,0x2a,0x40,0x5f,0xa1,0xd1,0x4d,0xd5,0xbb,0xb9,0x74,0x09,0xb6,0x06,},"\xb4\x29\x1d\x08\xb8\x8f\xb2\xf7\xb8\xf9\x9d\x0d\xce\x40\x07\x9f\xcb\xab\x71\x8b\xbd\x8f\x4e\x8e\xab\xc3\xc1\x42\x8b\x6a\x07\x1f\xb2\xa3\xc8\xeb\xa1\xca\xcc\xcf\xa8\x71\xb3\x65\xc7\x08\xbe\xf2\x68\x5b\xc1\x3e\x6b\x80\xbc\x14\xa5\xf2\x49\x17\x0f\xfc\x56\xd0\x14"}, +{{0xa7,0x5e,0x3b,0x6b,0x41,0x70,0xe4,0x44,0x78,0x1b,0xe4,0xee,0xac,0x3e,0x0f,0xda,0xa4,0xb4,0x35,0x6f,0x70,0x54,0x86,0xbc,0xb0,0x71,0xa3,0x25,0xae,0x07,0x1f,0xba,},{0x99,0x3d,0x38,0xa7,0xd7,0x2f,0x0a,0xee,0x15,0xff,0x6f,0x4f,0xdc,0x37,0xca,0x77,0x24,0xfd,0x13,0x73,0xa3,0x76,0x6b,0x27,0x5d,0xbc,0x77,0xe6,0x47,0x98,0x0e,0x0a,},{0xa5,0xdb,0x4d,0x3d,0x33,0x29,0xab,0xe3,0x69,0x79,0x59,0xe6,0xb5,0x94,0x7e,0xa8,0x60,0x1b,0x03,0xef,0x8e,0x1d,0x6f,0xe2,0x02,0x14,0x49,0x31,0x27,0x2c,0xa0,0xa0,0x9b,0x5e,0xb0,0xf3,0x90,0x57,0x2e,0xa7,0xef,0x03,0xc6,0x13,0x1e,0x9d,0xe5,0xf1,0x6b,0xf0,0xb0,0x34,0x24,0x4f,0x7e,0x10,0x4f,0xf5,0x31,0x1b,0xbf,0x66,0x3a,0x0d,},"\x40\x37\x86\x6f\x65\x48\xb0\x1c\xc6\xbc\xf3\xa9\x40\xe3\x94\x5a\xa2\xd1\x88\xb4\xb7\xf1\x82\xaa\x77\xec\x4d\x6b\x04\x28\xab\x5b\x84\xd8\x5d\xf1\x92\xa5\xa3\x8a\xda\x08\x9d\x76\xfa\x26\xbf\x67\x73\x6a\x70\x41\xa5\xeb\x8f\x0c\x57\x19\xeb\x39\x66\x93\xc4\x51\x60\xf8"}, +{{0xbc,0xbc,0xf5,0x61,0xec,0xc0,0x5a,0x41,0xc7,0xd7,0xe5,0x5e,0x69,0x6d,0x32,0xce,0x39,0xb4,0xd0,0x3c,0x1f,0x5f,0x3f,0x3a,0x89,0x27,0xfe,0x5e,0x62,0xe8,0x44,0xb2,},{0x4d,0xdf,0x53,0xfa,0xd6,0xa7,0xa9,0xed,0x30,0xf3,0xaf,0xec,0xca,0x13,0x6f,0xd7,0x84,0x3b,0x72,0xc2,0x43,0x09,0x08,0x91,0xae,0x40,0x21,0xa3,0x2c,0xad,0xff,0x1a,},{0x9f,0xf1,0x51,0x15,0xf6,0x66,0x1f,0x32,0x11,0xd7,0xa4,0x07,0x64,0x96,0x76,0x29,0xba,0x6a,0x52,0x63,0x95,0x1b,0xdc,0x3c,0x6a,0x4c,0x90,0xd0,0x70,0xf7,0xbe,0x00,0x02,0x4b,0x80,0xd8,0x3b,0x6b,0xc2,0x75,0x87,0xfc,0xff,0x5f,0x5c,0xcc,0x0e,0xb3,0xcd,0xe1,0x49,0x7c,0xf5,0x68,0x95,0x14,0x7a,0x06,0x3f,0x61,0xf0,0x8a,0xdf,0x0b,},"\x6f\x67\x16\xb6\x78\x47\x40\x98\x0a\xeb\xc3\x24\x88\x07\xe3\x1c\x12\x86\xac\x7b\x68\x1c\x00\xb6\x6c\x88\xff\x7a\x33\x6d\x44\x1f\xa5\xc3\xeb\x25\x6d\x20\xcf\x6d\x1a\xc9\x2c\xcf\xe4\xbe\x6d\xcc\x41\xb1\xaf\xf8\x46\xd3\x60\xc2\x43\x00\x1c\xab\xdf\xbf\x1a\x9b\x24\x04\x55"}, +{{0x21,0x05,0x32,0x80,0x5f,0xa9,0xcc,0x9b,0xe9,0x16,0xd2,0x13,0xca,0xc3,0x74,0xe3,0xcd,0x6f,0xc2,0x60,0x2a,0x54,0x4d,0x0c,0x1c,0xe2,0x9d,0x30,0x10,0x5d,0x69,0xab,},{0x10,0x69,0x9e,0x49,0x9b,0xe9,0x9e,0x2b,0x11,0xb9,0x8f,0x6f,0x86,0xb6,0x7c,0xdc,0x4c,0xcf,0x69,0xf3,0xc5,0x3c,0xe0,0x94,0x87,0x56,0x47,0xd2,0xd0,0xd0,0xec,0xc5,},{0x4c,0x2d,0x31,0xd5,0xbb,0xc4,0x2e,0x02,0x6d,0xc1,0xe0,0x79,0xec,0xc4,0xdd,0x07,0x2c,0x5d,0x2c,0xce,0x65,0xe3,0xdb,0x8d,0x8a,0x1d,0xd9,0x05,0x7f,0xaa,0x03,0x71,0x72,0x7f,0x72,0x72,0x31,0xa0,0xf0,0x60,0xfa,0x27,0x09,0x75,0x33,0xb6,0xdb,0x3b,0x8f,0x62,0x52,0xf2,0x79,0x3d,0x75,0x66,0x2c,0xaa,0xdf,0x5f,0x0f,0xcc,0x71,0x0e,},"\x9f\xc4\xd2\x8c\xfd\x25\xe6\xc0\xc5\xe7\x24\xe1\x9c\xa3\x9d\x71\xe5\x3b\xf4\xaa\x27\x96\xc5\x4c\x33\x51\xf1\x08\xfc\x70\xf2\x61\x1a\x62\xe0\xab\x90\xaf\x6a\xde\x52\x16\x78\x8e\x9e\xb2\xa8\x73\x05\x9b\x1e\x79\xd7\xd5\x9d\xeb\xd6\x8f\x2d\x4d\x80\xff\xe3\x1b\xf7\x4b\x92\x8c"}, +{{0x18,0x5d,0x64,0xb6,0x94,0x79,0xe0,0xba,0x0a,0x58,0x44,0xa1,0x0a,0xd8,0x41,0x25,0xba,0x11,0xc4,0xb4,0x0d,0x63,0xed,0xa2,0xc5,0x7a,0xfc,0x7e,0x01,0x9c,0x8e,0x0c,},{0xa5,0x76,0x4f,0x63,0x98,0xa5,0xae,0x22,0x66,0xa3,0x8f,0x97,0x14,0x53,0x3c,0x4b,0xbd,0x8d,0x07,0x82,0x6f,0x63,0xe2,0x04,0xcb,0xac,0x37,0x4b,0x0a,0xce,0xf1,0xbd,},{0x43,0xe0,0x38,0x7d,0xa5,0xba,0x09,0xa1,0x90,0xf6,0xe7,0xb2,0x68,0x05,0x78,0xd8,0x89,0x76,0x9b,0xcc,0x44,0x5e,0x5e,0xf5,0x71,0xb4,0x92,0x87,0x1c,0x15,0x5c,0x5b,0x9f,0x62,0x0b,0xfa,0xcf,0xbf,0x2d,0xf1,0xfd,0x87,0x44,0x46,0x04,0xb7,0x1b,0x2e,0x23,0x7b,0xaa,0xa7,0xee,0x20,0x93,0xed,0xe4,0xa6,0x01,0xed,0xf8,0x83,0xe3,0x07,},"\x4a\x08\x24\xfe\x70\xd4\x31\x54\x13\xd0\xa0\xca\xfb\xf4\xf5\xfe\x11\x7d\x5e\x07\xe1\xc3\xa4\xef\xfb\x9d\x0a\xe9\x14\x90\x23\x48\x78\xcc\xf6\x79\x2a\x91\xf6\x8c\x6a\x52\x0d\xe1\x60\x71\xf0\x8a\xbe\x35\xdc\x5e\xa4\x28\xf1\x95\x7b\x66\x33\x71\xce\x24\xc6\x09\xdd\x55\xb8\xf4\x93"}, +{{0xcf,0xa9,0xd9,0x16,0x4b,0x3c,0x4f,0x6f,0x72,0x26,0x35,0xd2,0x06,0x6c,0xd7,0xea,0x5e,0x55,0x33,0xd2,0xc7,0x4f,0x8a,0xdd,0x66,0x9c,0x37,0x1f,0xaa,0x47,0x64,0x26,},{0x41,0x16,0x9a,0x66,0xf9,0xa6,0x3f,0x28,0x57,0x82,0xa6,0xc2,0xdb,0x81,0xcc,0x3f,0x70,0xb3,0xad,0xa2,0x1a,0x68,0xc8,0x47,0x45,0xc8,0x8a,0x74,0xc3,0xb0,0xa2,0xde,},{0x01,0xd7,0xc9,0xb5,0x70,0x1a,0xf7,0x1e,0x2f,0x48,0x77,0xff,0xc9,0xb7,0xb5,0x30,0x5f,0x52,0x81,0x6d,0x44,0x58,0xe3,0x7e,0x41,0xc7,0x71,0x9f,0xac,0x1d,0x76,0xa0,0x1f,0xff,0x3f,0x50,0xfe,0x1a,0x58,0x75,0xcc,0xc3,0xfb,0x70,0x00,0x1c,0x94,0x7a,0x33,0xfc,0x8b,0x20,0x7d,0xe1,0x35,0x72,0xcc,0xdb,0x8b,0xa9,0x89,0x33,0xab,0x01,},"\x75\x76\x21\xb1\x67\x5d\xb7\xca\xce\xf7\xf2\x78\x25\x87\xff\x3a\xf5\x1a\x3e\xf2\xf4\xbc\xf9\x27\x9c\x4c\xe9\x40\x02\xe1\xf0\x04\x24\xbf\x0e\xb6\x21\x98\x2c\xc8\x5c\xb4\xd1\x71\xe5\x64\xa0\xc2\xf6\xe3\x56\x7a\x1a\xae\x2c\xdd\xb7\xe9\xb2\x5f\x47\xdc\x20\xa5\x10\x50\x54\x29\x69\xca"}, +{{0x1a,0xcb,0x4a,0x25,0x6c,0x2f,0x89,0x93,0xca,0x24,0xde,0x1e,0x00,0x14,0x60,0x6d,0x66,0x8b,0x5e,0x75,0x60,0x32,0xd2,0x69,0xf1,0xd2,0x4d,0x35,0x1c,0x8e,0xea,0x4a,},{0xcb,0xbd,0xcd,0x8c,0xbc,0x88,0x5a,0xb4,0x3a,0x05,0x7e,0x5f,0x95,0x79,0xf1,0x16,0x19,0x54,0x15,0x9e,0x7b,0x56,0x2e,0xa2,0x6c,0xd9,0xa4,0x3c,0x88,0xd3,0xf9,0x6d,},{0x05,0xaa,0x76,0xf7,0xfe,0x51,0x89,0x23,0x03,0xd7,0x89,0x14,0x71,0x59,0x95,0xe7,0xd7,0x68,0xff,0x77,0x14,0xce,0x27,0x0f,0x17,0x5e,0x56,0xaf,0x17,0xae,0x01,0x8d,0x3f,0xa9,0x39,0xf5,0xf6,0x20,0xde,0x82,0xbc,0xd1,0x54,0x96,0x87,0xb2,0x05,0xc7,0x87,0x12,0x03,0xe6,0x24,0x23,0x8c,0x4e,0x30,0x9f,0xab,0x7f,0x92,0xfb,0xaa,0x05,},"\xc4\x6a\x6d\x61\xaa\x0a\xed\x1c\x1d\x85\x47\xa7\x0b\x89\xb7\x19\x64\x75\xd5\xa4\x87\x08\x81\xb1\xec\xd0\xf0\xcb\x9c\x74\x5f\x8a\x2a\xdc\x80\x24\xe2\xdc\x55\xb5\x3a\xa5\xd3\x83\xa8\x1a\xab\xc1\xa4\x7e\x8d\x07\xd0\x0b\x7f\x0b\x56\xce\xdd\xbf\xb1\xf4\x24\xbb\x5c\x02\x18\x46\x78\xa6\x66"}, +{{0xac,0xe3,0xc4,0x64,0x24,0x82,0x36,0x22,0x97,0x9f,0xc3,0xa8,0x4a,0x7d,0xa6,0x9c,0x1d,0x52,0x7d,0x83,0x12,0xe8,0xfb,0x01,0x83,0x75,0xbd,0x3a,0x96,0xc2,0x9c,0x18,},{0x93,0x7c,0xf3,0x41,0x36,0xd9,0xe1,0xcc,0xe0,0xde,0x11,0xb1,0x2c,0x70,0xcb,0xfb,0x74,0x55,0x44,0x84,0x21,0xe9,0x2c,0x82,0xe7,0xc4,0x09,0x34,0xbf,0xf8,0xc6,0x76,},{0xfe,0xb8,0x89,0x6d,0xd3,0xfe,0x60,0x01,0xff,0xea,0x17,0x1b,0x37,0xb7,0x88,0xa6,0x9f,0x7f,0x85,0x01,0x93,0xa6,0x34,0x06,0xf5,0x63,0x76,0xdd,0x26,0x3d,0x09,0x9a,0xef,0x80,0xec,0xe6,0x7e,0x2c,0x43,0xf4,0x0e,0xca,0x46,0x2c,0x6b,0x71,0xe7,0x94,0x06,0xb1,0x8d,0xb7,0x4a,0xe5,0xd4,0x98,0x44,0xe3,0xb1,0x32,0xbc,0x2a,0x13,0x07,},"\xa9\xf1\x37\xbc\x90\x21\xbf\x10\x5a\xee\x25\xbe\x21\xcd\x9e\xe5\xb3\x54\x7c\xf1\x0c\xc5\xf9\x84\x76\xfb\x58\x8b\xd7\x0e\x2d\x6d\x6b\x08\x34\xe8\x42\xe4\xee\x94\x30\x3c\xf9\x6b\x09\xc1\x71\x53\x81\xb3\x6e\x14\xa4\x91\xb8\x0f\x89\x5e\xa4\x21\xb8\xec\x2b\x1d\x3c\x18\x7e\x02\x93\x5c\x55\x26"}, +{{0x88,0xf6,0x81,0x93,0x4e,0x33,0xc3,0x5c,0x07,0xdc,0x6e,0x5a,0x83,0x29,0x42,0xae,0x3d,0x59,0x90,0x3c,0xcd,0xe2,0xf7,0x6c,0xcb,0x75,0x87,0xce,0xa7,0xec,0x41,0xb6,},{0x6a,0x4e,0x8a,0xa5,0xad,0xb6,0x3d,0x22,0xfd,0x7b,0x14,0xa2,0x6f,0xdb,0x03,0xb7,0xc8,0xaa,0x6c,0xcd,0x5a,0x19,0x6f,0x2c,0x54,0xb0,0x46,0x5a,0xdb,0x50,0x92,0xe1,},{0x45,0xb2,0x7b,0xf1,0xb9,0xea,0xc0,0x6b,0x62,0xb6,0x86,0xf6,0xd5,0x46,0x56,0x3b,0x2d,0xfe,0x5b,0x17,0x5d,0xbe,0xf3,0x2b,0xf7,0x8c,0x35,0xa1,0x6c,0x95,0x8a,0x9d,0x4f,0x26,0xd2,0x91,0xde,0x9b,0xb2,0x06,0x6c,0x0a,0x28,0x61,0x13,0xcc,0x09,0x17,0x2d,0x40,0xa3,0x6d,0x4c,0xbd,0x95,0x17,0x08,0x86,0x02,0x26,0xeb,0x30,0xcd,0x05,},"\x6e\x8b\xac\x1f\x85\x3b\x81\xfe\xf9\x47\x07\xe1\x8c\xc6\x1c\x6f\x0a\x9c\xbc\x2a\x41\xd0\x78\xdc\xc8\x3f\xc0\x22\x9c\x7f\x8d\xbe\x6d\xbd\xd9\x08\x54\xb1\xf1\xae\x2b\x9f\x2b\x12\x0b\x86\xa8\x78\x6b\x4e\x78\xce\x23\xab\x86\xba\xaf\x88\x75\x4a\xf0\xf3\xd8\x88\x81\xda\xe0\xbc\x52\x61\xbf\xd0\x38"}, +{{0x48,0x05,0x0a,0x6e,0x01,0x58,0xf6,0xad,0x25,0x34,0x12,0xe4,0x49,0x7c,0xff,0x62,0xd5,0xee,0x55,0x5e,0xdf,0xfe,0x59,0xe4,0xdc,0x40,0x15,0x22,0x81,0x32,0x95,0xce,},{0x97,0x5e,0x01,0x0a,0xbb,0x9a,0x3e,0x56,0x65,0x91,0x37,0xb0,0x50,0x60,0x57,0xf2,0x83,0x98,0x2f,0x88,0x6c,0xa1,0x72,0xc7,0xbc,0x2c,0x50,0x0e,0xd9,0xbd,0x26,0xc1,},{0x72,0x16,0xab,0x60,0xc3,0x51,0x68,0x18,0x7d,0x0f,0xce,0x47,0x53,0xc8,0x6e,0x80,0x05,0x8d,0x54,0x0b,0x76,0xbf,0x95,0x84,0x3a,0x58,0x98,0x84,0x10,0x60,0xa9,0x9a,0x44,0xde,0x6f,0x43,0x96,0x25,0xa3,0xf6,0x36,0x5f,0x59,0xc3,0x77,0xbf,0x45,0x90,0x9b,0xbf,0xef,0x5c,0x50,0xb2,0x5f,0x31,0x94,0xe5,0xfb,0xd3,0x4e,0xa5,0xe7,0x06,},"\xed\x6e\xec\x29\xfb\x70\x49\xdf\xf7\x07\xf0\xa4\x42\x6e\xbc\x8f\x5b\x35\x0e\x95\x87\x0b\x9d\x61\x98\xc8\x13\x9e\x9c\x3e\x1e\x40\x99\x37\xd1\xa8\x58\xa0\xde\xa4\x82\xa5\xcb\x1a\x85\x4e\xd3\xb5\xa9\x39\x7a\xcb\x63\xbf\xf6\xb6\x40\x39\xef\x2e\xb1\x15\x9e\x99\x85\x83\x10\xbb\xbd\x86\x12\x5c\x3e\x0e"}, +{{0x18,0xd1,0x3d,0x0c,0x00,0xe8,0xe3,0x38,0x6a,0x5c,0xfb,0x30,0xa9,0xe7,0x9f,0xe8,0x8b,0x18,0x61,0xed,0x2d,0x12,0x01,0xeb,0x17,0x00,0x38,0xe1,0x94,0x77,0x04,0x03,},{0xa4,0xaf,0xc8,0x33,0x40,0x18,0x76,0x09,0x0d,0x9b,0x88,0x0c,0x41,0x26,0x7d,0x68,0xcb,0xbe,0xea,0xa3,0x8a,0xfb,0x20,0x88,0x4e,0x27,0x32,0x8f,0x3b,0x7f,0x53,0x5e,},{0x03,0x39,0x88,0x15,0x4c,0x5d,0x79,0xd2,0x51,0x0b,0xe8,0x3e,0x77,0x80,0x15,0xdf,0xe2,0xfb,0x85,0xb8,0x11,0x1f,0x7e,0xc1,0x39,0x91,0x8b,0x54,0x00,0xe3,0xd6,0x56,0xee,0x80,0xa9,0xf5,0xc9,0x07,0x2b,0x5b,0x46,0x7a,0x5c,0xc5,0xa5,0x7c,0xc8,0xad,0x10,0x62,0xb5,0xbf,0xf1,0x08,0x62,0xd9,0xd3,0x69,0xdd,0xe2,0xcc,0x96,0x67,0x01,},"\x91\x0f\x6c\x27\x2d\xd9\x79\x31\xac\x47\x31\x0d\x24\x4c\xad\xb4\x32\x51\x36\x5e\x02\xba\x9f\x6a\x5b\x3c\x32\x26\xbe\x9d\x7d\x3a\x74\xa2\xba\x49\x06\xe8\xe7\x1a\x4b\xf3\xd3\x55\x6e\xbd\xfc\x66\x6c\xd6\xb1\x2f\x20\xc4\xa0\x08\x34\xb8\x8f\xbb\x24\x45\x75\x19\x92\x86\xb0\xb9\x34\x4c\xf3\x34\xaf\xf0\x07"}, +{{0x4a,0xdc,0x8c,0x28,0x64,0x6a,0x93,0xa8,0x17,0x29,0x3a,0x14,0xd2,0x9b,0x48,0xe2,0xc6,0xd7,0x12,0xa6,0x89,0x93,0x54,0x7a,0x5c,0x5e,0x4d,0x14,0x52,0xac,0xbc,0x3a,},{0x7f,0x40,0x47,0x36,0x28,0xf2,0x3f,0xc0,0xdf,0xf0,0x02,0x1a,0xfd,0x48,0x77,0x40,0xd4,0x91,0x6a,0x91,0x22,0xe6,0xc9,0x7d,0x36,0x43,0x3e,0x5e,0xbf,0x04,0xf8,0x8c,},{0x6d,0x3b,0x4e,0x90,0xec,0x40,0x83,0x11,0xf9,0xb1,0x5b,0x92,0x53,0xd3,0xd9,0x5c,0x5d,0x15,0x26,0x20,0xc2,0x60,0xd5,0x63,0x02,0x55,0x5a,0x88,0x04,0xa5,0x10,0x4b,0xa5,0xe8,0xd2,0x9e,0xe1,0x08,0xe7,0x64,0xa6,0x42,0x19,0x29,0x72,0x98,0xab,0x76,0x74,0xbb,0xca,0x78,0x4d,0xee,0x28,0x77,0x3b,0x34,0xe1,0x85,0xa3,0x86,0xc2,0x08,},"\x09\xfb\x55\x01\xf1\x68\x8f\x80\xa0\xab\x9e\x22\xd7\x78\xae\x13\x0a\xca\xf7\x4d\x7f\x51\x85\xb4\xda\x19\x8c\x6b\x9e\xda\xc4\x30\x2e\x2b\x75\x3e\x57\x87\x66\xe1\x7d\x40\x56\xdc\x40\xd9\x5c\xf4\xca\x8b\xcc\x65\x65\x79\x5e\x97\xd6\x8b\xcd\xa7\x9f\xa7\x7c\x49\x33\x97\x71\x63\x56\x16\x4c\xaa\xb5\xd1\x9c\xfd"}, +{{0xf2,0x6e,0x1c,0x84,0x69,0x7a,0x49,0x08,0x15,0x1b,0x44,0x7d,0xcf,0x6c,0x7c,0x7a,0x38,0xb0,0x40,0x81,0xdb,0x9e,0x7c,0x77,0x38,0xe6,0xfe,0xc9,0x00,0xbe,0xd0,0xc1,},{0xa8,0x6e,0x14,0x22,0xc1,0x23,0x5f,0xf8,0xe1,0xaa,0x08,0x34,0x70,0xd5,0xe4,0x22,0x88,0xcb,0x00,0x7a,0xb5,0x0e,0x79,0x5d,0xd0,0xb4,0xff,0x87,0x39,0x49,0x66,0xc4,},{0x44,0xf3,0x34,0x4b,0x95,0x66,0xc9,0xdf,0xd2,0x2d,0x61,0x98,0xe1,0xcb,0xf9,0x5d,0x9e,0x28,0xf2,0x98,0x2f,0xc7,0xf1,0x66,0xab,0x25,0xdd,0xa3,0x0c,0x46,0xf7,0x68,0xc5,0x58,0xe0,0x39,0x4f,0xb9,0xab,0x3e,0x1d,0x4d,0xb4,0xcf,0x48,0x7c,0x17,0x64,0x1a,0x13,0xf3,0xf4,0x89,0x39,0xe0,0xc6,0x48,0x27,0xa7,0x51,0x03,0xc5,0x74,0x06,},"\x54\xed\x47\x60\x6a\x14\x87\xc2\xf9\x00\xce\xfb\x6e\x89\x9d\xba\xf6\xc3\x1c\xc8\x8e\xbe\x35\x58\xb8\x3b\x93\xf6\xd4\x22\xc3\x1e\x88\x8e\x48\xe5\x20\xee\xae\xdd\x7e\x55\x4a\x9c\xd4\x0c\x2c\x51\x9d\x53\x3b\x61\x44\xce\xe4\x84\xc3\x89\xe9\x76\xb1\xe4\x02\x2b\x50\xe7\xdb\xb8\x7e\xad\x7e\x54\x1a\x20\x04\xda\xf7"}, +{{0xcc,0x0c,0x33,0xf3,0xa8,0x6f,0x5a,0x17,0xd3,0x0c,0x18,0x6c,0xe0,0xf3,0xb7,0x40,0xba,0xfa,0x5f,0xe3,0xc7,0x09,0x0f,0x14,0x35,0x41,0xe2,0xb2,0xc1,0xe5,0x34,0xbc,},{0x96,0x7a,0x71,0xc7,0xcf,0x9b,0x82,0xcc,0x78,0xcb,0xe1,0x09,0x10,0x4d,0x8b,0x43,0x8a,0x8d,0x1f,0xd7,0x1d,0x26,0x0d,0x02,0x90,0x46,0xa9,0xa4,0x52,0x68,0x66,0xff,},{0xe2,0x77,0xb3,0xdd,0x65,0x5c,0x33,0xff,0x75,0xfa,0x92,0x0a,0xf1,0xfc,0xc8,0x59,0x40,0x1e,0x6c,0x7a,0x6e,0xf4,0xc6,0xbf,0xbf,0xac,0x50,0x69,0x63,0x8f,0x19,0xca,0x11,0x5b,0xaf,0x13,0xc0,0x9c,0x82,0xaf,0x79,0x3f,0xac,0xb6,0xab,0xd0,0xcd,0x58,0xe8,0x48,0x1b,0x08,0xc1,0xb6,0x8a,0xd7,0xa2,0x66,0x5c,0x4a,0x61,0x4a,0x28,0x06,},"\x19\x44\xe5\xe1\x55\xd7\x5e\x0d\x0b\xe9\x2e\x1b\xe1\x4c\xec\x37\x0a\xd1\x37\x91\xf2\xbf\xd4\x0f\x27\x12\x14\xe9\x4f\xcf\x21\x3c\x71\xbc\x20\xd7\xce\x0c\x75\x84\x42\x1a\xc4\xef\xc4\x51\x88\x3c\xc3\xf4\x95\x6f\x21\xf7\x3a\x42\x16\x72\x04\x38\xbc\x38\xff\x2c\xfd\xf3\x70\x99\x05\xa5\x0a\x9d\x94\xb1\xd9\xe7\x93\x2b"}, +{{0xf0,0xbc,0x97,0x93,0x75,0xa7,0x07,0x30,0x68,0xdb,0xa7,0xf6,0xc0,0x94,0xdb,0x65,0x98,0xb4,0xe4,0x5d,0xf7,0xd5,0x49,0x58,0x3c,0x22,0xfd,0xed,0x80,0x48,0xfa,0x2e,},{0xb4,0x2b,0x6c,0x57,0xa7,0x8f,0x1d,0x90,0x09,0x0a,0x71,0x81,0xab,0x2a,0xe0,0x9f,0x42,0x6c,0xbc,0x2b,0xe9,0x6e,0xb2,0xcf,0x27,0xab,0xc7,0x0d,0x7d,0x32,0xa4,0xb3,},{0x19,0xdb,0xc3,0x02,0x7f,0x9f,0xae,0x70,0x7d,0xeb,0x76,0xf5,0x88,0xf9,0xfd,0x07,0xaa,0x8e,0xae,0x29,0xbd,0x4e,0x1d,0x04,0xc2,0xc9,0x84,0x38,0x82,0x86,0xb3,0xb1,0x22,0x24,0x8a,0x6c,0x03,0xed,0x67,0xec,0xa3,0x5d,0xf4,0xdb,0x3d,0xc1,0xe4,0x23,0x7f,0x26,0x78,0x92,0x51,0x84,0x97,0xd9,0x55,0x2a,0x21,0xde,0x19,0xb5,0x14,0x0f,},"\x27\xab\x30\x49\xb5\xc6\x35\x1f\x6c\xfe\x38\xb1\x3a\x05\x9f\x50\x37\x25\x7e\xe3\xd6\x5d\x60\x79\x65\x68\x56\xed\xc8\x76\xea\x08\x1f\xd8\xa9\x48\x04\x66\xf8\x83\x94\x78\x08\x84\x66\xf5\x1e\xcb\xfa\xf2\xd6\x5d\xef\x25\xf0\xc4\xdd\x8d\x08\x58\x82\x02\x81\x22\x32\xf5\x79\x45\xdf\x8a\x6f\xa1\x61\xed\x8c\x03\x43\xb5\x83"}, +{{0x30,0x22,0x97,0x5f,0x29,0x8c,0x0a,0xd5,0xdd,0xbe,0x90,0x95,0x4f,0x20,0xe6,0x3a,0xe0,0xc0,0xd2,0x70,0x4c,0xf1,0x3c,0x22,0x1f,0x5b,0x37,0x20,0xaf,0x4d,0xba,0x32,},{0xb8,0x45,0xbc,0xe3,0x8e,0x26,0xab,0x02,0x7b,0x82,0x47,0x46,0x3d,0x43,0x7a,0x71,0xbb,0xdd,0xca,0x2a,0x23,0x81,0xd8,0x1f,0xad,0x4c,0x29,0x7d,0xf9,0x14,0x0b,0xd5,},{0xae,0x14,0xa8,0x60,0xfa,0xd0,0x05,0x1b,0x3e,0xb7,0x2b,0x37,0x21,0xa8,0x2f,0x7b,0x95,0x46,0xb2,0x86,0x72,0x61,0xe2,0xb7,0xb6,0x38,0x97,0x9e,0x25,0x61,0xbd,0xeb,0x89,0xb6,0x00,0x76,0x8f,0x82,0x45,0x0a,0x66,0xc8,0xb0,0x48,0x12,0x83,0xfa,0x21,0xcb,0x6c,0x53,0xbd,0xe3,0x50,0xef,0xfb,0x68,0xa7,0xd1,0x11,0x4b,0xfd,0xb2,0x03,},"\x9a\xa1\x9a\x59\x5d\x98\x93\x78\xcd\xc0\x68\x91\x88\x7e\xf5\xf9\xc2\x46\xe5\xf8\x3c\x0b\x65\x87\x10\x67\x3e\x4e\x7d\xb7\x60\xc7\x63\x54\xc4\xf5\xd1\xe9\x0d\xb0\x4a\x23\xb4\xfb\x43\x4c\x69\x38\x45\x93\xd0\x10\xe3\x12\xb1\x1d\x29\x9c\x9f\x97\x48\x2d\xe8\x87\xce\xcf\xe8\x2e\xa7\x23\xbc\xa7\x9a\x1b\xd6\x4d\x03\xef\x19\xee"}, +{{0x0f,0x71,0x0b,0x6c,0x48,0x1f,0x71,0x44,0x95,0x89,0x75,0x33,0x12,0xef,0x64,0x93,0x2b,0x46,0x52,0xeb,0xe0,0xe0,0x75,0x97,0xf7,0xda,0x1c,0x4f,0x3d,0xcf,0xfb,0x80,},{0x69,0x73,0xff,0x29,0x32,0xcc,0xdd,0xfc,0x1d,0x16,0xc4,0xc0,0xda,0x50,0xc8,0xb2,0x9f,0xe6,0x45,0x2d,0x1e,0xe8,0x4d,0x52,0x06,0x4e,0xbf,0x3d,0x62,0x8d,0x40,0x3e,},{0x02,0xa8,0xd2,0x6a,0xee,0x11,0x42,0x0f,0xb4,0xf0,0x9d,0x11,0x63,0xe1,0x4b,0x86,0x7d,0xf7,0xc6,0xf6,0xc8,0xf8,0xdc,0x7a,0x78,0x03,0x46,0x59,0xf0,0x40,0x1c,0xad,0x0a,0xa9,0x03,0x97,0xef,0xdd,0x07,0x04,0xb7,0x98,0xdb,0x19,0x36,0x50,0x30,0x26,0xe2,0xa1,0xad,0xc2,0x97,0xe2,0x79,0x74,0xd4,0xbe,0x31,0x2a,0x37,0x53,0xf8,0x04,},"\x85\xd8\x57\x44\xad\x55\xe9\xef\x9a\x65\xca\x91\xe8\x5c\x8a\x4f\x80\xe4\xc5\x8f\x8e\x4e\x93\x54\xe8\x33\x98\x60\x98\xb7\xd9\xfe\x9f\xdc\x0d\xed\xb0\xd7\x5d\x25\x39\xfb\xa0\x00\x34\xfc\x0c\x2e\x84\x34\x4d\x1e\xda\xa0\x9d\x4f\x63\xd5\x54\x6d\x67\x80\x3d\xd6\xb5\x4d\xdc\xc0\xb1\xd3\xf2\x58\x2d\xd7\x52\x89\xe3\x1d\xe4\x2e\x69"}, +{{0x7a,0x05,0xf1,0x21,0xf6,0x01,0x12,0xdd,0x16,0xfe,0xe8,0xc9,0x1b,0xc2,0xa1,0x14,0x79,0xf4,0xb6,0x7e,0xe3,0x34,0x56,0x04,0x2c,0x8d,0xe1,0x67,0xfc,0x58,0x80,0x17,},{0xb3,0xb0,0x5b,0xe9,0x89,0xce,0xa7,0x19,0x75,0x05,0xd4,0xb5,0x43,0x35,0xe5,0xe1,0xd7,0x7a,0x4b,0x52,0xba,0x72,0x82,0x60,0x4b,0xbc,0x1c,0xf6,0xc4,0xe8,0x7a,0x6c,},{0xd3,0x0c,0xe8,0xa3,0x22,0xb4,0x50,0xa2,0xfb,0x1a,0xfd,0x32,0x9c,0xec,0x85,0x59,0xcc,0xf1,0x12,0xbd,0x83,0x96,0x5f,0x9e,0xc4,0x73,0x62,0x70,0xa0,0x91,0x4e,0x06,0x11,0x96,0xbf,0x52,0x09,0x77,0x8c,0x9f,0x8c,0xcf,0x39,0xc4,0x66,0x8b,0xbf,0x0e,0x13,0x63,0xf8,0x1a,0xfe,0x45,0xdd,0x74,0xe8,0x0d,0x58,0x75,0xdd,0xbf,0x6f,0x01,},"\xd9\xc5\x9e\x8c\xc4\xed\xe5\x37\xbe\x21\x22\xab\x49\x2a\x5b\x91\x5a\x9b\x0a\x11\x4b\x2a\xde\x35\x6f\xc0\x45\x7e\xf9\x87\x22\xd5\xf5\x67\xb8\x62\x11\xe2\x83\x69\xd1\x41\x68\xec\x4a\x3c\x80\x40\x76\xe1\x54\xad\xc7\x0a\x66\x8c\xf6\x4a\x20\xd1\x3c\xf1\x90\xd1\x15\xcd\x68\x8d\x03\x6e\x46\x93\x82\x51\xdf\x49\x64\xdc\x35\x17\xb1\x0c"}, +{{0xbf,0x38,0x1f,0x8d,0xfb,0x5d,0x0c,0x6d,0x64,0xe4,0x16,0xac,0x23,0xe0,0xd0,0xfc,0xb8,0x6e,0xbb,0x89,0x9b,0x1d,0x14,0x6a,0xbd,0x91,0x1b,0x92,0xa7,0x80,0x8e,0xb6,},{0x86,0x3f,0xad,0x8d,0x1f,0x1b,0xc6,0x30,0xa1,0x5f,0x6f,0xe8,0xec,0xef,0xe6,0xb4,0x49,0x7b,0x60,0xb2,0x1a,0xe8,0x83,0x0d,0xa4,0x67,0x42,0x04,0x5f,0xef,0x15,0x6f,},{0x99,0xb7,0x53,0x78,0x73,0x8f,0xca,0xc8,0x06,0x76,0x69,0xe8,0x50,0x9b,0x5d,0x26,0x07,0xe1,0xef,0x76,0xaf,0x90,0x04,0xe1,0x3f,0xe5,0xd3,0x93,0x2d,0xf6,0x0b,0x16,0x82,0x16,0xf5,0x85,0x65,0x34,0x0f,0xa4,0xd6,0x38,0x05,0x5a,0x89,0x04,0x4e,0xe7,0xd4,0x5e,0x2b,0xd0,0x82,0xa5,0x33,0x82,0x28,0x9a,0x34,0x70,0x06,0x48,0x98,0x0e,},"\x86\x54\xf2\xf5\xc6\xdc\xd2\xcf\xcb\xb6\xed\x8d\x2b\xc5\xfb\x5f\xec\x53\xe3\xef\xfb\x0d\xe6\x5a\xac\x50\x7f\xa5\x6c\x89\x77\x32\x39\x5a\xa0\x99\x46\xd3\xb6\x58\x6a\x92\xed\xd6\xdc\x99\x31\x5e\x1b\xa7\x4c\x6a\x02\x47\xc4\xba\x77\x60\xb9\x48\xeb\x3c\x09\x32\xd9\xfe\x1f\x0e\x9f\xea\x6e\xb6\x1a\x54\x8a\x9a\xb4\x8f\xfd\xf1\x54\x73\x29"}, +{{0x36,0x98,0x32,0x41,0xa0,0xa8,0xe6,0x0c,0xe0,0x2a,0x61,0xb3,0xfa,0xfa,0xb1,0x5a,0x73,0x13,0xa5,0xa2,0x70,0xd0,0x15,0xb9,0xc9,0xec,0x07,0x0d,0xc4,0x2d,0xee,0xda,},{0x66,0x47,0x98,0x4d,0x42,0xb9,0xa5,0xb3,0xb1,0xaf,0xa3,0xb7,0xf8,0xf4,0x9d,0x4c,0x2b,0x05,0xe3,0x89,0x84,0xe9,0x9c,0xea,0x8f,0xd6,0x82,0x35,0xd2,0xae,0x46,0x27,},{0xee,0x37,0xdf,0x8a,0xf4,0x22,0xf9,0x1f,0x85,0xdf,0xe4,0x3e,0xfe,0x79,0xf6,0x23,0x78,0x06,0x8c,0xcd,0xba,0xf3,0x91,0x6e,0xec,0xbc,0x3a,0xdf,0xed,0x05,0x08,0xbd,0xeb,0xaf,0x5c,0xe0,0x6b,0x3b,0xc2,0x79,0xf7,0x80,0x87,0xf0,0xdb,0x8d,0xb3,0xc6,0x82,0x3e,0xdf,0xb3,0x2c,0x12,0x21,0x78,0x30,0xbe,0x72,0x3d,0x88,0x72,0xb3,0x0c,},"\xce\xbb\x9e\x40\x44\x51\x81\x82\x53\xc0\x39\x2a\x45\x54\xee\x73\x23\xc5\xd5\xb8\xb2\x26\x77\x57\x00\xb8\x06\xed\x5b\x91\x33\x79\x16\xea\x7e\xcb\xc3\xd4\x10\x3f\xc6\x5e\x53\x72\xae\x7e\x5f\x9b\xa2\xd8\xf5\xae\xe2\x4c\xcf\x6e\x63\x1a\xe2\x0c\x4a\xf9\xb5\xf7\x28\xcd\xf8\x9e\x81\x89\xde\xf1\xa5\xb3\xd3\x53\x47\xaa\x20\x35\x25\xea\x1d\x2e"}, +{{0xd0,0x68,0x99,0xf9,0x3a,0x40,0x8d,0xac,0xb4,0x1c,0x96,0x97,0x18,0x34,0x6f,0x1e,0x28,0x9b,0xb5,0xea,0x65,0xe2,0x83,0xff,0x79,0xc7,0x05,0xa0,0x74,0x51,0x7c,0x35,},{0x46,0xbf,0x2a,0x08,0xa0,0x76,0xc4,0x7d,0x7f,0x11,0xb7,0x33,0xf8,0x14,0x1c,0x35,0x53,0x63,0xed,0x85,0xd7,0xde,0xf2,0x6b,0xa6,0xa0,0xce,0x15,0xac,0x5f,0x2b,0xe8,},{0x6f,0x89,0xde,0x92,0xa6,0x6b,0xc5,0xf4,0x14,0x43,0x39,0x12,0x49,0x50,0xbd,0xf5,0x88,0x14,0x4c,0xb3,0x72,0xf6,0x73,0x62,0x45,0x35,0x1c,0x94,0x76,0xbe,0xcc,0x59,0xa2,0x58,0xf9,0xa9,0x33,0xff,0xff,0x2b,0xef,0x4b,0x46,0xcd,0x10,0x57,0x39,0x52,0x25,0x79,0x9f,0xd0,0x9d,0xed,0xe6,0x82,0x3d,0xb0,0xe3,0x25,0xdb,0xc8,0x14,0x0d,},"\x08\x64\xc3\x9a\xc4\xfd\xa8\xeb\x90\x48\x59\x7b\xd4\x0b\xe0\x40\x10\x21\xfd\x2d\xd3\xa3\x39\x0a\x8f\xac\xce\x98\x4b\x26\x0a\x13\xfa\x2c\x7c\xfc\x00\xd1\x92\xfa\xdf\x13\x4a\x0a\xd5\xa1\x81\xee\x89\xef\xf0\xc7\x95\xea\xa0\xfb\xfe\x2f\x3b\x26\x11\x5d\x07\x16\x8d\xb4\x2e\xd2\x1a\x51\x30\x3b\x19\x58\xe4\xa4\x2d\xc0\x65\xb2\x2c\xe4\x8f\x17\xa6"}, +{{0xee,0xbc,0xa7,0x96,0x69,0x70,0xee,0x9f,0x2c,0xc4,0xd7,0x4c,0x6f,0x1d,0x8e,0x0e,0xbf,0xf7,0xc4,0x5a,0xeb,0xad,0x34,0x9f,0xb9,0xf8,0x6d,0xf6,0x28,0xdf,0xff,0x0e,},{0x89,0x10,0x1e,0x03,0x09,0xf7,0x67,0xe6,0x4a,0xe9,0xc9,0x8c,0x4a,0x5d,0x8d,0x23,0x28,0xfb,0x3e,0xf2,0x62,0xd0,0x82,0xf4,0x9b,0x64,0xca,0x20,0x9e,0x19,0x90,0xf6,},{0x7d,0x44,0x7e,0xe5,0x32,0x8c,0x9f,0xe7,0xf1,0x19,0x36,0xcc,0x42,0x99,0x87,0x54,0xa5,0x6c,0xd1,0xd2,0xa6,0x95,0x1a,0xf4,0xfe,0xe7,0xc4,0xa8,0xeb,0x31,0x9d,0x49,0x23,0x70,0x7c,0x79,0x3c,0x55,0xd7,0x90,0x67,0xf8,0x22,0xd5,0xb1,0x6b,0xb5,0x77,0x6e,0x38,0xdf,0xfa,0xbc,0x67,0x23,0x7a,0x91,0x6a,0x81,0xa6,0x33,0x39,0xb0,0x03,},"\x0f\xac\x79\x0a\xdb\x9f\x59\xe5\xcb\x0d\xdc\xb2\xb6\x67\x17\x2f\x2a\x21\x03\x4d\x93\xbc\xad\xdf\x18\x86\x06\xfa\x9e\x77\x6d\xb3\x3a\x8f\xcc\x6b\xd7\xf5\x56\x78\x83\xfc\x0d\xe3\x51\xaa\x9a\xfa\xa3\x6d\x20\x75\xb1\xba\x85\x3b\xad\xa8\x49\xb8\x66\x1d\x5c\x81\x54\xe7\xb0\xaf\xea\x65\x6d\xd1\x5e\x01\xa9\xc5\xba\x21\x58\x9b\x02\xf8\xfc\x54\x81\xc2"}, +{{0x38,0x20,0xb6,0xb1,0x59,0x39,0xd0,0xaf,0xe1,0x8c,0x9c,0xb3,0xd9,0xa2,0xa0,0x8f,0x16,0x7d,0xd4,0x58,0xeb,0x6c,0x7e,0x3f,0x15,0x58,0xb0,0xc6,0xdb,0x4c,0x68,0x90,},{0x80,0xb8,0x5c,0x65,0x59,0xfe,0xa8,0xb4,0x00,0xe1,0x99,0x9c,0xc5,0xbf,0xed,0x50,0x7a,0xd7,0xfc,0x29,0x4c,0xd9,0xba,0x0c,0xe2,0xdd,0x25,0x84,0xa9,0x10,0x89,0xb0,},{0x82,0x3e,0xe2,0xc0,0xc8,0xd8,0x7f,0xaa,0x0e,0xc0,0x14,0x1e,0x9c,0xe0,0x8b,0x51,0xe5,0x7c,0x83,0x97,0x92,0xd1,0xfb,0xd9,0x7a,0x96,0x72,0x07,0xfd,0x41,0x58,0x49,0xeb,0xfb,0x5d,0xad,0xb5,0xa1,0xdc,0x2c,0x0a,0x8b,0x7f,0xc6,0x3f,0xc3,0x54,0x85,0x7b,0x8c,0x90,0xc4,0x47,0x20,0xe1,0x3f,0x45,0xcd,0x01,0xe7,0xaa,0x23,0x14,0x0c,},"\x3e\x5a\xd9\x2d\x44\xb4\x0e\x86\x14\xd8\x08\x7c\x9c\x74\x3d\xe0\xc0\x86\x1a\x07\xf1\xf5\x14\x6d\x71\xca\xc2\xf3\x74\x00\x24\xe8\x41\xcc\x2d\x46\x02\x7c\xf5\xd2\x61\xd3\xee\x7c\x18\x75\xb3\x95\x51\x01\x7b\x5f\xb1\x46\x81\x14\xfc\x3e\x09\x8a\x89\x9c\xdb\xd5\x58\xb3\x9f\x09\x8e\x15\x6b\x6e\x98\x01\xeb\xcd\xd6\x5f\xed\x56\xdb\xfc\xaf\x2c\x8c\x78\x7b"}, +{{0x0d,0x20,0xfa,0x4a,0x37,0xff,0x30,0xc4,0xdc,0xc3,0xe4,0x4e,0xa7,0xac,0x50,0x11,0x37,0xe5,0x80,0x7e,0x97,0x81,0x33,0x0a,0xc3,0x10,0x98,0x2c,0xc3,0xd3,0x9d,0xbd,},{0x67,0xbb,0x0a,0x01,0xbc,0x86,0x17,0xb4,0x91,0xef,0xf1,0xa3,0x26,0xc1,0xc7,0x0f,0x7d,0x0c,0x5b,0x95,0xa5,0xad,0x48,0x24,0x1a,0xed,0xce,0x1c,0x6f,0x08,0x83,0xcf,},{0xde,0xab,0x12,0xed,0x82,0xba,0x94,0xb4,0x69,0xca,0x98,0xb6,0x6f,0xa2,0x04,0x44,0xb4,0xb7,0x88,0x1c,0x4f,0x0f,0x85,0x34,0x09,0xc9,0xa1,0x50,0x4a,0x5b,0x2b,0x6d,0x78,0x60,0xf2,0x6a,0xda,0x6b,0xf7,0x34,0x59,0xb9,0xcd,0xb5,0x73,0xc8,0x01,0x71,0x21,0x33,0x8e,0xfa,0x60,0xf4,0x14,0x80,0x86,0xd7,0xa3,0xa8,0xed,0x59,0xbb,0x07,},"\x35\xe0\xf4\xb4\xa5\x17\xf9\xc7\xaa\x45\x14\xf0\x3e\x6d\x65\xf1\x9b\x27\xc6\x2c\xc0\x69\xf6\xbf\x07\xdd\x63\x78\xbd\x6a\xfe\x2b\x76\x65\x60\x00\x6c\xbd\x57\x30\xa0\x09\x19\xed\x11\x19\x1f\xb0\xc8\xda\xc5\x6e\x15\x3f\xc1\xce\xa4\xbd\xce\x50\x46\xcc\xcb\x71\x77\x59\xa4\x08\x3e\x1c\x16\xf7\x40\x76\x32\x64\xcc\x80\x4d\xe0\xd0\xe1\xa4\xb5\xa2\x30\x67\xaf"}, +{{0xbe,0xe1,0x61,0x88,0x1d,0x81,0x9b,0x37,0x0d,0x24,0x0d,0x50,0x9b,0xa4,0x6b,0x06,0xfb,0x82,0x8e,0x20,0x31,0x0d,0x9f,0x6b,0x30,0x97,0x80,0x70,0x3e,0x98,0x92,0x7b,},{0x10,0x85,0x43,0x80,0xde,0x89,0x16,0x2b,0xfb,0x9f,0x78,0x35,0xa2,0x71,0x6a,0x3a,0x6e,0x02,0x65,0x67,0x1b,0x25,0x0b,0x38,0x9d,0x01,0xc3,0xbc,0xc0,0x37,0x36,0xb8,},{0xb0,0x7d,0x07,0x2e,0xb3,0x83,0x1f,0xae,0x8a,0x06,0xef,0xfa,0x92,0x01,0x79,0x74,0x96,0xdc,0xe1,0x26,0xb8,0xe1,0x1f,0xef,0x2f,0xa0,0x7f,0x66,0x4d,0xc5,0xcf,0x3d,0x4b,0xf9,0xc3,0x8a,0x8b,0x3c,0x09,0xfb,0x5f,0x14,0xfa,0x2d,0xeb,0x21,0x9e,0x7d,0x85,0x2f,0xdd,0x27,0xc7,0xba,0x32,0xd3,0x09,0x94,0x2f,0x27,0x46,0xdf,0xe4,0x04,},"\x5a\x6f\xe5\x99\xb6\xb0\x9b\x05\xc0\xba\x6a\x62\x2d\xf3\xa9\x2b\x3d\x37\x6d\x24\xd0\x4e\xa8\x5e\xbe\x76\x7b\xc2\xec\x4d\x14\xe8\x3e\x69\x37\xdc\x0b\x91\x4b\x48\x09\xfd\xb6\x07\x90\x68\x41\xa6\xfd\x1d\xcd\xf6\x1a\xae\xa8\xf9\xbb\x81\xb2\xcc\xaa\x32\xdf\x41\x29\x89\xae\x53\x64\x66\x80\xa7\x1a\x21\x1c\x84\x40\xea\xb0\xf1\xae\xc5\xe4\xfc\x00\xe6\xa2\xc9\x6d"}, +{{0x70,0x15,0x0e,0x95,0x16,0x16,0x4a,0x3d,0x7b,0x7e,0x8b,0x6f,0x25,0x5b,0x65,0xca,0xc9,0xf0,0x74,0x59,0xb3,0x2d,0x11,0xbb,0x94,0xb3,0xd2,0x77,0x20,0x8a,0xbc,0x99,},{0x23,0x28,0xbe,0xc8,0xe4,0x03,0x51,0x04,0x78,0x82,0xe8,0xb4,0x3b,0xc1,0xab,0x08,0x53,0x86,0xfa,0x47,0x98,0x7e,0x46,0xea,0x87,0x60,0x88,0x14,0xc5,0xda,0x71,0x3c,},{0xed,0xa3,0xf5,0x03,0x3e,0xa7,0x95,0x3a,0x0d,0x58,0x3c,0x64,0x57,0x52,0x2e,0x84,0xad,0x78,0x44,0x53,0x04,0xd4,0x8e,0x57,0x7d,0x4d,0x69,0xe8,0x64,0x1f,0xeb,0xe1,0x52,0x48,0xd8,0xd9,0x0c,0xe0,0x94,0x4a,0x8f,0x80,0x1d,0x39,0x09,0x9b,0xc7,0x74,0x94,0xba,0xc4,0xce,0x2a,0x20,0xb3,0x83,0x69,0xc6,0xad,0xfb,0x71,0xe0,0x3d,0x0f,},"\x77\xbe\x8e\xce\xaa\xb4\x31\xa1\x3c\x2a\x28\xd0\xd1\x55\x64\x89\xd8\xc3\x92\xfd\x7a\xe4\x11\x57\xf7\xca\xf0\x82\xcb\x54\xe4\x5f\x08\x62\x6b\xe0\x07\x6b\xe8\x44\xd3\x8f\xde\x90\x1a\x5e\xab\x0e\x88\x32\xd6\x9d\xac\x22\xfb\x85\x07\xfb\x8e\xc4\xfa\xf7\xc8\x8f\xd2\x6d\xa3\x08\x46\x1a\xfe\x38\x59\x87\x97\x2b\x5e\x76\x0a\x34\xa5\xe1\x8b\x9a\x82\xb4\xaa\xa5\x29\xb7"}, +{{0x3f,0x87,0xfc,0xfd,0xb4,0x21,0x42,0x2a,0x9c,0x5f,0xb9,0x82,0x68,0x31,0x3c,0x15,0x12,0x8c,0x78,0x84,0x4e,0xf9,0xeb,0x3b,0x37,0x13,0xfa,0x77,0xb6,0x71,0x89,0x03,},{0x53,0x3e,0xc5,0x92,0x28,0x37,0x4b,0xd0,0x3a,0x46,0x99,0xe3,0xa8,0x89,0x6b,0x86,0x18,0x2f,0xcf,0x8f,0xc3,0x08,0x5f,0xdb,0x8f,0x5c,0x46,0x71,0x52,0x4d,0x6f,0xe0,},{0xf6,0x51,0x9d,0x7e,0xdb,0x61,0x34,0x11,0x19,0x74,0x03,0x3f,0x03,0xb8,0xd8,0x9e,0x9c,0x76,0xca,0xec,0x89,0x65,0xa8,0xe1,0x7c,0xd4,0x5f,0xff,0x19,0xde,0x26,0x15,0xd7,0x3e,0xcc,0xdb,0x4a,0x66,0x64,0xa8,0xf0,0xe2,0x3a,0xdf,0x98,0x98,0x8e,0x96,0x25,0x1b,0xf2,0x6e,0xb7,0xa4,0xcc,0xaa,0xc1,0x07,0x9f,0x0a,0x77,0x2f,0x9b,0x05,},"\xc0\x0f\xed\x2d\x68\x94\x68\xbc\xba\xcc\xcd\x44\x6e\x8d\x8f\x29\x9e\x2a\x86\x92\x5e\x62\xe5\x97\x09\xaf\xaf\x48\x57\x46\x9f\xf1\xe0\x06\xd0\x0f\xa3\xe1\x8a\x36\x15\xf8\xf0\x6b\x6e\xbd\xff\x78\x5d\xde\x58\x85\x1d\x2c\x23\x90\x38\xa0\xc3\x44\xdc\xe9\x85\xbd\x1f\xc8\xde\xb4\x77\x9a\xe5\xf8\x93\x2e\x2f\x9e\xd5\x99\x0b\x64\x72\xdb\xe4\xe6\xfe\xf6\x91\x76\x57\xe0\xb5"}, +{{0x44,0xce,0xef,0x04,0x4f,0xf9,0x98,0xd4,0xab,0xea,0xaf,0x37,0x4e,0xb4,0x1d,0x08,0x67,0x18,0xb6,0x30,0x97,0xb1,0xe3,0x5f,0x89,0x63,0x4c,0x14,0x89,0x71,0x32,0xea,},{0xe8,0x3c,0x86,0x67,0x7d,0x03,0xed,0x3a,0x5e,0x8c,0x95,0xf4,0x1f,0x0b,0x32,0x5f,0xf4,0x33,0x37,0x02,0xf2,0xff,0x69,0x36,0xf5,0x7f,0xf3,0x0a,0xa3,0x14,0x85,0xc7,},{0x55,0x45,0x52,0xd6,0xb7,0x90,0xd4,0x21,0xd0,0x6b,0x0a,0x67,0xf8,0xe0,0x02,0xad,0x7a,0x1e,0xd0,0x1c,0x06,0xcf,0x00,0xcb,0xea,0xec,0x2a,0x26,0x8b,0xda,0x29,0xf1,0x18,0x3f,0x0c,0xea,0xfc,0x62,0x5f,0xa5,0xfd,0xb8,0x47,0xdc,0x86,0xfa,0xe1,0xa2,0x04,0x06,0xe4,0x59,0xd4,0xa0,0x17,0x7c,0xb5,0x15,0x22,0x0a,0x56,0x8e,0x08,0x00,},"\x8d\x3e\x2d\xec\x46\x44\xc7\xb5\x16\x33\xb1\x3e\x63\x75\xca\x42\xff\x91\x38\x46\x5f\x43\xd7\x80\x0c\x73\x13\x19\x9f\x67\xc9\xcf\x1b\x52\x0b\x18\x20\xbd\x63\x0e\xcf\x1c\x99\x2e\x27\x67\xb3\x8e\xb5\xbb\xc4\x41\xa4\xab\x8d\x31\x7d\xb4\x41\xdb\x35\xa0\xfe\x3a\xbe\x7a\x9e\x45\x41\x88\x1c\x2d\x7b\x1a\x26\x12\x30\x69\x59\x81\x5d\x1d\xa4\x12\x67\xd9\x64\x9d\xd4\x49\x4a\xce"}, +{{0x98,0xef,0x2a,0x44,0xd4,0xc8,0x47,0x6d,0xff,0x05,0xaa,0x78,0xdc,0xf9,0xc6,0xdc,0x08,0x6c,0xb2,0xf6,0x22,0xa0,0x67,0x45,0xd6,0x0c,0xbf,0x22,0x3f,0xaa,0xba,0x66,},{0x42,0xfd,0xb1,0xda,0xa3,0x9f,0x01,0x59,0x11,0x9b,0xee,0xc1,0xbe,0xdf,0x6f,0x03,0x94,0xb2,0x6a,0x2a,0x29,0xbd,0x1f,0xde,0x08,0x1e,0xcc,0xda,0xde,0xcc,0x22,0x6a,},{0xab,0x5e,0x87,0x24,0xa3,0xe6,0xff,0x76,0x05,0x8c,0xfb,0x21,0x4d,0x57,0x4e,0x04,0xd0,0x55,0x74,0xec,0xdd,0x4f,0xfe,0x8c,0x07,0xc7,0xaf,0x39,0x6e,0x88,0x26,0x87,0xc5,0xd7,0x9e,0xf1,0xe6,0x2f,0xbb,0x4c,0x5f,0x1b,0xd0,0x6b,0x9b,0xd8,0x97,0x82,0x6e,0xdd,0xe0,0xd1,0x11,0xd9,0x18,0xe8,0xef,0x96,0x1f,0xf2,0xa0,0x0d,0x77,0x00,},"\xc8\xb5\xfc\xfc\x3c\x18\xc7\xd9\x59\x57\xb6\x68\xe9\x1c\x73\x1d\x50\xc7\xfc\xea\x4f\x95\x75\xbb\xf7\x84\x62\x58\x70\xe2\x38\xdf\x54\x6e\x2c\xb1\xa1\x9d\x28\x08\xdd\x5b\x23\x0d\x38\x71\xfd\xec\x16\x10\x0e\xe1\xfb\xf9\xb7\x22\xfa\x37\x44\xa7\x50\xa3\xb3\x96\xb0\x5f\x9c\x21\xb8\xc0\xf6\x1e\xad\x57\xa7\x8c\x5e\xcf\x72\xb5\x79\xcf\xe8\x8a\x3f\x40\x4c\x8a\xcf\x52\x4f\x9a\xb9"}, +{{0x93,0xa8,0xc7,0x92,0xa2,0x39,0xc9,0x31,0x91,0x7c,0x11,0x48,0x24,0xa0,0x17,0x4f,0x8b,0xc4,0xeb,0xbf,0x98,0xaf,0x8c,0x7e,0x32,0x1e,0x0f,0x5b,0xea,0x40,0x15,0xec,},{0x9b,0x2e,0xaa,0x8a,0x9c,0x2c,0x25,0xff,0x4f,0x6e,0x13,0xbb,0x12,0xba,0xe5,0xd0,0x6f,0xda,0x0e,0xb1,0x10,0x5f,0xaf,0xae,0x58,0x80,0xff,0x16,0x87,0x40,0xbb,0x74,},{0xcf,0xe3,0x2c,0x44,0x35,0xd9,0x11,0xd7,0x72,0xdc,0x07,0x27,0xe7,0x8d,0x68,0x9d,0x01,0x64,0xc5,0x06,0x95,0x97,0xcb,0x44,0x1b,0x22,0xc1,0xd2,0x62,0x36,0x47,0x9f,0x1a,0xfd,0x70,0x89,0x12,0x1b,0x9a,0xb4,0xf6,0x1b,0xbb,0x1f,0xae,0x1a,0xb4,0x2f,0x76,0x35,0xa9,0x2a,0x53,0x78,0x4d,0x71,0x70,0x91,0x6b,0x70,0x3a,0xa5,0xcc,0x09,},"\x90\x1b\xf4\xe0\x41\xca\xf1\x6e\x04\xf2\xff\xde\x8d\x6f\xe9\x7e\x93\xd0\x90\x0f\x6b\xc0\xfc\x09\xa9\xa0\x17\x9d\x13\x7b\x4b\x77\x88\xe5\x7e\xb9\x27\x66\xa9\xc6\x34\xf3\x5a\xdb\x5c\x29\x88\xaf\x1e\x86\x20\x8f\x46\x19\x98\xf5\x9c\xfe\xc9\x92\x04\xb4\x84\xfb\xca\xd3\x95\x1e\x7e\xe4\x40\x55\x23\x70\x5d\x97\x39\xb4\x43\x07\xdb\x03\xf7\x13\xfd\xa7\x8d\xb4\x21\xef\x31\x21\xb3\xba"}, +{{0x70,0x01,0xfa,0x0c,0x44,0x04,0xc2,0x8a,0xa5,0xb5,0xfc,0xff,0x30,0xa9,0x61,0xf2,0x1a,0x22,0xf5,0xb8,0x5a,0x9e,0x38,0x2e,0x07,0xae,0xa8,0xa8,0x92,0x4d,0x0e,0xc1,},{0xda,0xeb,0xb6,0x3c,0x4d,0x8f,0x40,0xce,0xba,0x8e,0xc3,0x5e,0x3d,0xd9,0x46,0xa6,0xb7,0x5b,0xc7,0x4f,0xcb,0x29,0xad,0xe7,0xb5,0x5e,0xee,0x3c,0xc3,0xae,0xa5,0xca,},{0x64,0xea,0xc9,0xce,0x87,0x46,0x06,0x18,0x63,0x6b,0x41,0xfd,0x2d,0xec,0xc1,0x67,0x3b,0xfc,0x48,0xc5,0xf4,0x79,0xdf,0xac,0xb5,0x1e,0x86,0x68,0x64,0x07,0x37,0x4b,0x1d,0x10,0xbf,0x65,0xd6,0xd7,0x47,0x42,0x14,0xd7,0x77,0x0c,0x9e,0x5c,0x7f,0x80,0x6c,0x80,0xd5,0x3d,0x48,0xb7,0x20,0x87,0x0e,0x5e,0x78,0xf3,0x2e,0x3a,0x7e,0x05,},"\x44\xf4\x8c\xfb\x02\xf0\x87\x77\xa5\x78\x73\x85\x5f\x96\xbe\x4c\x02\x91\x32\x3f\x27\x39\xb2\x75\xd9\x07\x57\xa1\x54\x72\xe5\x75\x04\x36\xe0\x10\x74\x08\xfe\x30\x26\xc0\x06\x25\x68\x99\x83\xf9\x90\xeb\xa9\xbe\xcb\xfc\xe4\x03\xcc\xd5\x63\x56\xad\x27\x41\xfd\x21\x44\x5d\xfb\x23\xd7\x61\x12\xe5\x78\xb3\x39\x5c\xf9\xd9\x60\x95\x5f\x1d\xa8\xf3\x99\xca\x28\x6f\x21\x39\x0e\x25\xa5\x9a"}, +{{0x3a,0xdc,0xe3,0xa3,0xd3,0xfb,0xc9,0x77,0xdd,0x4b,0x30,0x0a,0x74,0x74,0x9f,0x13,0xa3,0xb0,0x4a,0x5d,0x73,0xa2,0xcd,0x75,0xa9,0x94,0xe3,0x19,0x5e,0xfe,0xbd,0xac,},{0x6f,0xf1,0x9b,0x1f,0x18,0xd6,0x48,0x51,0xd5,0xc7,0x48,0x45,0xc6,0x40,0x7f,0x0b,0xf5,0x96,0xa5,0x2e,0x38,0x5e,0x02,0x01,0x27,0xe8,0x3e,0x54,0xcf,0xf5,0xac,0x19,},{0x7d,0xda,0x89,0xf8,0x5b,0x40,0x53,0x9f,0x5a,0xd8,0xc6,0xde,0x49,0x53,0xf7,0x09,0x4a,0x71,0x5b,0x63,0xdd,0xa3,0x0e,0xc7,0xcf,0x65,0xa7,0x85,0xce,0xae,0x5f,0xc6,0x88,0x70,0x7e,0xe0,0x0b,0xe6,0x82,0xce,0xcb,0xe7,0xee,0x37,0xd8,0xfc,0x39,0xee,0x6d,0x83,0xc6,0x44,0x09,0x68,0x17,0x08,0xa0,0x89,0x8a,0x18,0x3b,0x28,0x8a,0x06,},"\xfe\x6c\x1a\x31\x06\x8e\x33\x2d\x12\xaa\xb3\x7d\x99\x40\x65\x68\xde\xaa\x36\xbd\xb2\x77\xce\xe5\x53\x04\x63\x3b\xd0\xa2\x67\xa8\x50\xe2\x03\xbb\x3f\xab\xe5\x11\x0b\xcc\x1c\xa4\x31\x66\x98\xab\x1c\xf0\x0f\x0b\x0f\x1d\x97\xef\x21\x80\x88\x7f\x0e\xc0\x99\x1e\x8c\x11\x11\xf0\xc0\xe1\xd2\xb7\x12\x43\x3a\xd2\xb3\x07\x1b\xd6\x6e\x1d\x81\xf7\xfa\x47\xbb\x4b\xb3\x1a\xc0\xf0\x59\xbb\x3c\xb8"}, +{{0x14,0x80,0x3c,0x1f,0x23,0xa4,0x7f,0xcd,0xd3,0x5e,0x5d,0x14,0x6e,0x20,0xca,0x63,0x0c,0xd7,0x12,0xc0,0x47,0xd5,0x33,0x0b,0x65,0x2e,0x31,0x85,0x7a,0xcb,0xc9,0xe8,},{0x36,0xf2,0xd5,0xbd,0x6d,0x83,0x24,0xfa,0x6e,0x9d,0xb7,0xf7,0xd8,0x54,0xeb,0xe4,0x8c,0x0e,0x62,0x99,0x99,0x81,0x22,0xe9,0xd4,0x4b,0x8a,0xdb,0xef,0x54,0xf0,0x93,},{0x07,0xa7,0xde,0x6c,0xe9,0x76,0x64,0xb3,0xea,0x09,0x28,0xe1,0x38,0x5c,0x33,0x09,0xbe,0x08,0xa4,0x7c,0xbf,0x4d,0xaa,0x91,0x86,0xa1,0xb9,0x48,0xc8,0x6f,0xbb,0xa3,0x9c,0x4e,0xfc,0xfc,0xb7,0xa0,0xa3,0x86,0x6b,0xc9,0x4c,0x67,0x88,0xff,0xe6,0xbe,0x0d,0x49,0x72,0xe5,0x6d,0x0c,0x32,0x92,0xd1,0xcc,0x6e,0x25,0x44,0x7b,0x99,0x04,},"\x55\x59\x83\x67\x9d\x02\x6e\x53\x54\xb4\xcc\x05\x5a\xe1\xbc\x14\x65\x3c\x72\x81\xec\x72\x23\x72\xf3\xfe\xb7\x78\xe8\x41\xda\x82\x1b\x3d\x0b\x8e\xe7\xa9\xa9\x12\x9e\xa0\x68\x24\xbe\x83\x79\xfb\xbd\xcb\x07\x48\xf4\x23\x72\x1c\xcb\x17\x2a\x1b\xaf\xa1\xd5\xae\x9f\xc1\xc5\x1e\x93\xd4\x1d\xd5\x51\xc3\x08\x60\x79\xb6\x20\x28\x6c\x1c\x40\xc1\x22\x3b\xbc\xbb\x76\x72\x2e\x92\xca\x21\xd8\x41\x0a"}, +{{0x1a,0x61,0x15,0x4d,0x34,0x72,0xcd,0x96,0xb3,0x28,0xee,0x67,0x4b,0xeb,0x4f,0xc8,0x67,0x63,0xa9,0x69,0xfb,0x41,0x04,0x94,0xe0,0x67,0x84,0x14,0xe3,0x1a,0x46,0xa6,},{0x75,0x76,0xd9,0x3a,0xc8,0x5d,0x0f,0xc6,0x1f,0x25,0x8c,0x55,0xcf,0x90,0xbd,0x87,0xa6,0x35,0x09,0x9c,0x0e,0x81,0x0e,0xd0,0xb9,0x37,0x25,0x8d,0x13,0xb4,0x25,0x59,},{0xad,0xa1,0x66,0x6c,0x9c,0x3b,0x82,0x84,0xb8,0xa2,0x1c,0x4f,0x26,0x18,0xef,0x08,0x08,0xa6,0x46,0xf3,0xf1,0x09,0x41,0xe4,0x70,0xf7,0x38,0xe1,0x78,0x5e,0x2d,0xe9,0xfd,0xd9,0xc8,0xcb,0x52,0x6f,0x94,0x5c,0x7a,0x8c,0x69,0x94,0xf1,0x51,0xb7,0xd0,0x66,0x58,0x1b,0x1d,0x75,0x53,0x07,0x94,0x7c,0x62,0xbe,0xfc,0x8a,0xb7,0x07,0x0f,},"\x64\xc5\x65\xef\xbc\xb8\xb9\x52\x8e\xd4\x72\x53\xf3\xc6\xa4\x03\x5d\xb7\x81\xd6\xf0\x97\x6b\x5e\x5b\xa8\x44\x7d\x4e\xd5\x4b\x04\x10\x52\x93\xef\x4c\x00\x0d\x8b\x2e\x1b\x5b\x75\xe7\x27\xe5\xd2\xa0\x77\x74\x3b\x50\xd1\x83\xb4\x91\x76\x48\x01\xa2\x50\x4d\x16\xee\x6d\x7d\x8a\xc4\xfe\x40\xe6\xbf\xc2\xa8\x12\x9c\x72\x85\xa5\xac\x69\x1c\x35\xe6\x42\xed\x16\x2c\xf7\xfb\xc6\x45\x16\x73\x3a\x23\xb3"}, +{{0xf2,0x15,0xd3,0x4f,0xe2,0xd7,0x57,0xcf,0xf9,0xcf,0x5c,0x05,0x43,0x09,0x94,0xde,0x58,0x79,0x87,0xce,0x45,0xcb,0x04,0x59,0xf6,0x1e,0xc6,0xc8,0x25,0xc6,0x22,0x59,},{0x1e,0xd5,0x06,0x48,0x5b,0x09,0xa6,0x45,0x0b,0xe7,0xc9,0x33,0x7d,0x9f,0xe8,0x7e,0xf9,0x9c,0x96,0xf8,0xbd,0x11,0xcd,0x63,0x1c,0xa1,0x60,0xd0,0xfd,0x73,0x06,0x7e,},{0xcb,0xef,0x65,0xb6,0xf3,0xfd,0x58,0x09,0x69,0xfc,0x33,0x40,0xcf,0xae,0x4f,0x7c,0x99,0xdf,0x13,0x40,0xcc,0xe5,0x46,0x26,0x18,0x31,0x44,0xef,0x46,0x88,0x71,0x63,0x4b,0x0a,0x5c,0x00,0x33,0x53,0x41,0x08,0xe1,0xc6,0x7c,0x0d,0xc9,0x9d,0x30,0x14,0xf0,0x10,0x84,0xe9,0x8c,0x95,0xe1,0x01,0x4b,0x30,0x9b,0x1d,0xbb,0x2e,0x67,0x04,},"\xfb\xed\x2a\x7d\xf4\x18\xec\x0e\x80\x36\x31\x2e\xc2\x39\xfc\xee\x6e\xf9\x7d\xc8\xc2\xdf\x1f\x2e\x14\xad\xee\x28\x78\x08\xb7\x88\xa6\x07\x21\x43\xb8\x51\xd9\x75\xc8\xe8\xa0\x29\x9d\xf8\x46\xb1\x91\x13\xe3\x8c\xee\x83\xda\x71\xea\x8e\x9b\xd6\xf5\x7b\xdc\xd3\x55\x75\x23\xf4\xfe\xb6\x16\xca\xa5\x95\xae\xa0\x1e\xb0\xb3\xd4\x90\xb9\x9b\x52\x5e\xa4\xfb\xb9\x25\x8b\xc7\xfb\xb0\xde\xea\x8f\x56\x8c\xb2"}, +{{0x8c,0x9f,0x95,0x08,0x30,0x75,0xa4,0x3f,0xe4,0x26,0xd1,0x9f,0x1e,0x87,0x71,0x9b,0x40,0x04,0x3d,0xe8,0x8e,0xb0,0xee,0x97,0x1f,0x70,0xe1,0x0c,0x76,0x94,0xce,0x4e,},{0xe9,0x1d,0x16,0x7a,0xa3,0xeb,0xc2,0x3e,0x70,0xaa,0xb4,0x5d,0xab,0xe9,0x05,0xe4,0x16,0x26,0x2f,0x91,0x0e,0x2a,0x95,0x5d,0xd8,0x61,0x9e,0xfc,0x74,0xc2,0x4e,0x85,},{0xca,0xc5,0x55,0x22,0x2d,0xaf,0xec,0x76,0xa0,0xb4,0x7b,0x9d,0x2c,0x58,0x6b,0x3b,0x3b,0x9b,0x3b,0x9c,0x83,0x64,0xbe,0xb3,0xca,0xe1,0xe8,0xdd,0x7f,0x1a,0xe9,0xdd,0x74,0xf2,0x2b,0x8d,0xd4,0xad,0x2b,0x29,0x0f,0x81,0x35,0x1a,0x41,0x5a,0x99,0xf0,0x30,0xf1,0x07,0x78,0xbe,0x4c,0xda,0x85,0xd1,0xd3,0x53,0x33,0x1e,0x70,0xf1,0x09,},"\xb6\x9d\x70\xe8\x60\xf5\x5c\x42\x7e\xf2\xa7\x1d\xf3\x6e\x05\xbb\xc4\x3b\xb2\xe0\x64\x63\xaa\x5d\xe3\x44\x19\xc6\xa6\x14\xee\xa6\x69\x53\x35\xa8\x75\x26\xc1\x22\x64\x88\xd8\x42\x89\x1d\x05\x74\xdf\x34\x3c\x9c\x1e\x17\xae\xd6\x95\x8e\xce\xe8\x74\x74\x22\x1e\xb7\x7a\x59\x9e\xcb\x05\x93\x44\xc0\xd0\x52\xc0\x00\x2a\x66\xe5\xa6\x01\x31\x85\xaf\x69\xa0\x1b\xa5\xdb\xc6\x60\xd3\x6c\xae\x23\x5f\x67\xfe\x0e"}, +{{0xd7,0xeb,0x1f,0xba,0x42,0x4f,0xee,0xd1,0x00,0x77,0x7e,0xed,0xb4,0x87,0x4b,0xf2,0x08,0x10,0xad,0x68,0x6b,0x67,0xe3,0x1d,0x27,0xec,0xf6,0x10,0x60,0x9a,0x33,0xf5,},{0xa2,0x5a,0xcb,0x11,0xa6,0xc8,0x25,0x71,0x3a,0x08,0x5f,0xa7,0x54,0x69,0x28,0x86,0xa8,0x7d,0x07,0xfb,0x9b,0xe1,0xa5,0x3e,0xb9,0x61,0x72,0x8b,0xb6,0x6c,0x90,0x60,},{0x2b,0xf7,0x19,0x68,0x2b,0x07,0xcc,0x5e,0xcc,0x04,0x80,0xf3,0x7e,0x9d,0x12,0x3f,0xf6,0xf4,0x4c,0x26,0xe6,0x95,0x8e,0x59,0xf0,0x80,0x46,0x6f,0x9c,0xd3,0x73,0xa1,0x65,0x00,0xda,0xf1,0x23,0xdc,0x3f,0x13,0x34,0x77,0x4b,0xfc,0x9f,0xa8,0x45,0x03,0xb1,0x6d,0xbf,0x21,0xa8,0x15,0xc1,0xad,0xa6,0xeb,0xef,0x49,0x20,0x46,0x17,0x02,},"\xa1\xd0\xf8\x1e\x3d\x59\x08\x9c\xc2\xb1\x9e\x07\xd2\xfc\xe4\x3d\xb4\xcf\x17\x1f\xaa\x64\x2f\x3b\x0b\xbd\xe7\x7a\xe3\xd5\x3a\xf5\xc0\x2b\xf8\xfc\x12\xff\xb4\xe5\x7f\x7c\x8a\x01\x5d\x6c\x2d\x17\x89\x44\xfa\xe9\xf7\xc8\xfc\x96\x9d\x4b\x77\xbe\xa5\x18\x76\xae\x99\xd5\x9e\x94\xad\x24\x56\xe0\xed\x72\xc5\x2c\xf4\xe5\x34\x0d\xa1\x7c\x44\xdb\xff\x86\x45\x7a\x51\x9b\x6f\xff\xe2\x69\x06\x62\x90\xd6\x29\xfe\x69"}, +{{0x4f,0x6a,0xeb,0x35,0xfc,0xe1,0x4f,0xbc,0xbb,0x9a,0xa8,0xa4,0xf6,0x45,0x1b,0xf9,0x5b,0x98,0xdf,0x04,0x7f,0xa8,0xc4,0x3f,0x1e,0xad,0x3b,0x40,0x4d,0x3f,0x92,0x8f,},{0xbf,0x66,0xa9,0xed,0xd0,0x94,0x81,0xdb,0x84,0x44,0xa1,0x76,0xc8,0xce,0x05,0x78,0xd2,0x93,0x4f,0x0c,0xdc,0x97,0x34,0xe8,0x6f,0xca,0xac,0x05,0xbf,0x33,0x30,0xf1,},{0x6a,0xdb,0x07,0xe3,0x64,0xf2,0xa4,0x55,0xcb,0x05,0x86,0x7a,0xbc,0x51,0x1a,0xcd,0x9d,0x65,0x89,0x77,0xf0,0xca,0xca,0xfc,0x92,0x82,0x8e,0x7b,0x72,0x4f,0x6b,0xbf,0x98,0xbf,0x0b,0xfb,0x29,0xf4,0xe5,0xe6,0xc7,0x47,0x38,0xd4,0xfd,0xd8,0x16,0xd9,0x25,0x24,0x07,0xae,0x4f,0x3a,0xfc,0x57,0x4c,0x4f,0x00,0x61,0x48,0x24,0xe2,0x03,},"\x2d\xfb\xb3\xf5\x9e\x19\xea\x17\xd4\x4a\x5b\xde\x4a\xd2\x27\xa1\xa3\x51\xdd\xa1\x7a\xf8\x40\xee\x0a\x75\xda\x21\xa5\xcc\xa8\x9b\x6d\x1c\x56\x7c\x33\x3e\x9c\xc9\x10\xe2\x15\x7e\x05\xe8\x6a\xd5\xd9\x31\x14\x50\x64\x59\x4c\x47\xba\xee\xa8\x66\x3a\x34\x64\x9c\x43\xe9\x0e\xb9\x5c\xa1\x0f\x7d\x51\x59\x7b\x37\x8a\x72\x2f\x1f\x70\x4a\xdf\x9f\x22\xe9\xf8\x85\xb8\x9d\x1f\x93\x80\x06\xa2\xef\xcd\xb4\x2a\xaf\xf5\xe3"}, +{{0xef,0x4a,0x67,0x62,0xb4,0x00,0x97,0x52,0x04,0xcc,0xc1,0x3a,0xbb,0x47,0x34,0x40,0x15,0x45,0x49,0x06,0x85,0x0f,0xf1,0x49,0x40,0xcb,0xb8,0x3a,0xa2,0x24,0x14,0xae,},{0xea,0xca,0x45,0x09,0x96,0xf5,0x0c,0xfa,0xf2,0xbd,0x7f,0x9d,0x7f,0xa7,0x08,0x7f,0x09,0xad,0x49,0x66,0x42,0x06,0xa8,0x0b,0xc2,0xe5,0xbb,0xbb,0x85,0xbb,0x66,0x8e,},{0x02,0x69,0x7d,0x44,0xca,0xd8,0x62,0xf1,0xda,0xf5,0x70,0x82,0x05,0xf4,0x50,0xd4,0x08,0x52,0x5b,0x10,0xc0,0x1f,0xfd,0x06,0xcf,0xee,0x80,0x37,0x4f,0x3d,0xb1,0x6f,0xa9,0xa4,0x9c,0x19,0xa9,0x84,0x4b,0x34,0x5f,0x2f,0x95,0x59,0xea,0x74,0xaa,0xb1,0x73,0xba,0xa0,0x78,0xc5,0x43,0x70,0xa5,0x16,0x67,0x00,0xc6,0xda,0xfb,0x78,0x0a,},"\xa4\xb6\x3e\xae\xd5\xa6\x4a\x94\xf2\xca\xd2\x12\xce\x2a\xe7\x10\x92\xfd\x3e\xa7\x44\xf5\xbd\x89\x56\x2b\x2f\xc2\xa6\xc9\xe4\xd7\xaa\x27\xad\xd5\x62\x64\xa5\xa5\x50\x16\x61\x0b\xe6\xc1\x9f\xf7\xd4\x98\x9e\x95\x04\x74\x08\x53\x01\x27\x15\xa7\x9e\xce\x9e\x12\xc3\x01\xb3\x31\x7c\x7d\x9b\x67\x30\xdb\x86\x2a\x4a\x1d\x28\x05\x8e\x0f\x8b\x5d\xdd\x97\x38\xc7\xc6\x2e\xa5\x72\xcf\xe5\x9e\xae\x08\xe2\xb8\xb6\x59\x3b\x58"}, +{{0x55,0x01,0x7e,0x5f,0x61,0xf0,0xc5,0xba,0xfb,0xcd,0xe6,0xf8,0x49,0xf4,0x2a,0x31,0xe5,0xe7,0xa8,0x78,0xc1,0xd3,0xf9,0x12,0x6f,0xc5,0x69,0xfd,0x41,0x7e,0xa9,0xf2,},{0x66,0x91,0x4f,0x74,0xed,0x93,0x2f,0xc8,0x81,0xff,0x01,0x66,0x68,0x3f,0x67,0x5a,0x7c,0x28,0xa9,0x26,0xfd,0xdd,0x64,0x69,0xcd,0xb3,0xf2,0x8e,0x6d,0xec,0x42,0xcc,},{0xb1,0xa5,0xe7,0xc4,0x9b,0x8f,0xc6,0xb4,0x33,0x1e,0x04,0x16,0xce,0x7e,0x4e,0xd5,0x9e,0xdd,0x56,0x30,0x0b,0x80,0x2e,0x0d,0x72,0xab,0xca,0x4a,0x6f,0xcb,0x87,0x6c,0x03,0xbf,0x33,0x15,0x79,0x12,0x4a,0xe0,0xd3,0xfe,0x43,0xf7,0x89,0x8b,0xc8,0x7e,0x93,0xfc,0x2d,0xa3,0x97,0x0f,0xc8,0x63,0x89,0x57,0xd1,0x8c,0x66,0x13,0xc8,0x08,},"\x2f\xc8\x4a\x09\x98\xfa\x6e\x16\x8a\x86\x64\x10\xbb\x68\x10\x5d\xf2\x49\xa2\x8c\xfc\x76\x60\x4b\xe9\x4f\xd7\xdf\xff\xf2\xfc\x1d\xed\xd2\x20\x19\x94\x65\x57\x5e\x8d\xf8\x60\x19\x0f\x16\xac\xa4\x08\x41\x69\xbe\x16\xc6\xba\x32\xeb\x67\x04\x2f\xfd\x4f\x23\x03\x16\xa2\x6b\x26\x24\xa4\x2f\x8f\x90\xad\x57\xf6\x91\x64\x86\xfa\x91\xfd\x94\xed\x68\xad\xed\x4e\x63\x24\x30\xef\x71\x94\x46\x97\x9b\xfa\xf3\x45\x40\x9c\x38\x7f"}, +{{0x05,0x53,0xfb,0xa8,0x66,0x94,0x23,0x41,0x21,0x7c,0xf2,0x78,0xac,0x57,0xcb,0x21,0xac,0xd0,0x9d,0x99,0x16,0xcc,0x6a,0xf0,0xac,0x46,0x94,0x1e,0xa1,0x39,0xd5,0x45,},{0x84,0x0c,0x66,0xe5,0x7c,0x2d,0x4f,0x52,0xa4,0xa2,0x79,0x6d,0x2a,0x53,0xc5,0x70,0x9b,0x96,0xa6,0x28,0xc2,0xe0,0x63,0xfe,0x6e,0xfd,0x47,0xf2,0x83,0xef,0x5e,0x82,},{0xbc,0x33,0x64,0xc1,0x52,0xee,0x5c,0x80,0x8a,0xc3,0x40,0xf4,0x9e,0xa2,0xcc,0x40,0x4e,0x93,0x51,0x71,0x21,0x22,0x0c,0xce,0x6f,0x7c,0x30,0xa2,0x25,0x00,0xe4,0x1b,0xcd,0xb6,0xe8,0x20,0x48,0x0f,0x8f,0xcc,0xdd,0x22,0xff,0x9a,0xd9,0x6d,0xa5,0x32,0x80,0x2f,0x43,0x1e,0x94,0x24,0x0f,0xb8,0x3d,0x4b,0xce,0xaa,0x09,0xb9,0x2b,0x0d,},"\xc1\xfa\xe6\x26\x2a\x0e\x98\xa6\xb1\x23\x5f\xcb\x62\x28\x3b\x7f\x0a\x09\x7f\x9d\x00\x24\x16\xd3\x18\xfe\xfc\x60\xc5\xa1\x58\x4f\x90\x0a\xd0\xab\x26\xcc\xfa\xe0\xd6\xd8\x4a\xa9\xaa\x2d\xf1\x6d\x4c\x11\x7e\xa2\x72\x46\x76\xcb\x86\x6d\x48\x70\xa8\x72\xfc\x82\x9a\x7c\x2a\x5d\x21\xba\x83\x34\x0a\xdb\x33\x9a\x34\xc5\x18\x4c\x7f\x5e\xad\x0f\x07\x72\x89\xb3\x36\x77\xed\x6a\x1b\xa3\x4b\xe1\x99\x4e\x25\x76\x3b\xd1\xd9\xfa\xec"}, +{{0x7a,0x5a,0xc6,0x02,0xde,0x19,0xf3,0xc2,0x10,0x40,0xbc,0xdd,0xbf,0xf4,0x2f,0x6a,0xee,0x6f,0x95,0xc1,0xb0,0x93,0x86,0x8f,0x48,0xe5,0x04,0x82,0xdb,0xf4,0xf9,0xc7,},{0xfb,0xb6,0xc7,0x53,0x1c,0xda,0x21,0xe7,0xd1,0x7e,0xa9,0x03,0xc4,0xd1,0x4b,0xe6,0xc6,0x8b,0x4c,0xa8,0x03,0xa1,0x6b,0xd8,0x71,0x20,0xf5,0xaa,0xf7,0xdc,0xe1,0xd4,},{0x84,0x10,0x1d,0xd4,0xb5,0xe8,0xca,0x3e,0xd9,0x8c,0x1e,0x8a,0x06,0xe1,0x1d,0x7e,0x42,0x4b,0x0d,0x12,0xca,0x71,0x4e,0xe7,0x37,0x4b,0x64,0xc2,0x9d,0x51,0xa2,0x02,0x1c,0xc7,0x7a,0xc7,0x53,0x89,0xd9,0xb0,0xa6,0x46,0xa4,0x47,0x62,0x3d,0x7d,0x04,0xd1,0x24,0x18,0x66,0xb0,0xca,0x6e,0xdd,0x1b,0x7a,0xc0,0x15,0x66,0x6b,0x70,0x0d,},"\xbd\x16\x85\x41\x92\x79\xeb\x81\xe4\xcf\x3c\x90\x90\x31\xf0\xf0\x9c\x5f\xfa\xe7\xe2\xce\x6b\xa9\xd9\x6c\x2b\xce\x87\xb8\xba\x0d\xd7\x63\x23\x10\x01\xe5\x32\xc7\xdd\xd6\x21\x03\xab\xf7\x01\x28\x8e\x19\xdd\x8f\x53\x02\xe8\xf5\xd3\x1b\x64\xcc\x33\x9b\xd8\xb7\xa9\x55\x50\xc8\xa1\x16\xfd\x48\x69\x48\x77\x2b\xd5\xaf\x8d\xfd\x46\x00\x1c\x59\x76\x7b\x0d\x6b\xdc\xe3\x83\xa7\x07\x89\x92\xd1\x02\x2f\xbc\xaf\x90\x71\x06\x87\xb9\xaa"}, +{{0x50,0x41,0x4c,0xf5,0x49,0xbc,0xc5,0x5b,0x5b,0x6b,0x75,0xea,0x37,0x82,0xb2,0xea,0x7c,0x08,0x7b,0x6a,0x01,0x06,0x17,0x5e,0x46,0x9c,0xa2,0xcc,0x76,0x4a,0xeb,0x01,},{0xd0,0xf3,0x0c,0x12,0xe9,0x97,0xf9,0x6e,0x7a,0xee,0xcd,0x1b,0xff,0x6a,0x01,0x2e,0xc3,0x88,0xeb,0xf8,0xf3,0xf4,0xaf,0x66,0x48,0x04,0xd1,0x63,0x8e,0x4c,0x34,0x6a,},{0xb3,0x09,0x80,0x01,0x60,0xde,0x43,0xa6,0x3a,0x89,0xa0,0xac,0xb8,0xa6,0x05,0x00,0x59,0x58,0x9b,0x3e,0xae,0xca,0xc2,0x0b,0x25,0x6f,0xec,0xe4,0x38,0x04,0x2f,0x69,0x41,0x5d,0x8a,0x56,0x88,0x3e,0xe3,0x83,0x6d,0x31,0x34,0xa7,0xfc,0x1d,0xe6,0x4f,0xa8,0xc8,0xce,0xcc,0x3c,0xe2,0x75,0x89,0xf6,0x06,0x05,0x88,0x20,0x85,0x7a,0x0c,},"\x75\xad\x77\xe8\xc5\x4b\x0b\x05\xfb\x2d\x16\x2e\x7c\xad\xb8\xa7\x52\x80\x81\xb8\x63\xf7\x6a\x44\x1b\x37\x44\x69\x41\x3e\x57\x14\xed\xf5\x4f\x80\x04\x96\xaf\x01\x57\xc1\x7e\x42\x55\x83\x41\x4d\x43\x61\xf2\x13\x41\x71\xc0\xb8\x7c\x22\xce\x68\x20\xa4\x85\x0a\xb4\x9d\x99\xa9\xba\xdc\xe9\xe3\x61\x10\xe7\xf3\x06\x01\x18\xb3\x59\x0f\x82\xb4\x37\x71\xe9\xfb\xb0\x81\xaf\xe6\x22\x27\xe0\x24\xd9\x8d\xe6\xcd\xec\x02\x8d\x7c\x49\x49\x0d"}, +{{0x93,0xcb,0x00,0xd8,0xfe,0x9c,0x97,0x77,0xa6,0x83,0x63,0x1f,0x39,0xba,0x0f,0x48,0x76,0x14,0x82,0xcf,0x1c,0x36,0x6b,0xd8,0x63,0xcf,0x71,0x51,0x01,0x53,0x25,0x55,},{0x87,0xe9,0x4a,0x1e,0xa5,0x25,0x8d,0x61,0x18,0x0c,0xb8,0x28,0x59,0x0f,0xf1,0x41,0x8a,0x87,0xd0,0x1e,0x70,0x26,0x86,0xba,0x8a,0xbc,0x26,0x92,0xc8,0xdc,0x3c,0x91,},{0x09,0x82,0x4f,0xa2,0xdf,0xbc,0x4d,0x6e,0xf7,0x6a,0x9e,0x41,0x45,0x96,0x11,0x16,0x76,0x91,0x30,0x55,0x3b,0x3e,0xdf,0xfa,0x50,0xd0,0x4f,0x39,0xb8,0xb7,0x9f,0xac,0xbd,0x23,0x7a,0xcf,0x71,0x35,0x4a,0x53,0xa6,0xe5,0xfe,0xe7,0x54,0xe8,0x23,0xb0,0xb2,0x90,0xf9,0x61,0x93,0x20,0xa1,0x3d,0x56,0x12,0x69,0xa2,0x21,0x63,0x9f,0x03,},"\x88\xd8\x53\x8d\x31\x86\x78\x13\xd8\x8f\xef\x72\x28\xd4\x9a\x7e\x95\x0d\x73\x83\x96\xf1\x16\xdd\xa1\x02\x5f\x79\x13\x54\x7c\x5d\x1d\xc5\x67\x7a\x6d\xe4\xb4\xa5\x88\x05\x07\xb3\x61\x78\x0b\x61\xb4\x3f\x77\x95\x26\x3d\xb2\x2f\xf3\x41\x64\x5f\x2f\x59\x14\xfd\x60\x88\xc2\x81\x12\x11\xed\x47\x56\xac\x01\x9a\x60\x35\xd6\x6e\x31\x70\xc1\xd8\x2b\xfa\xa3\x05\x96\xb3\x96\xb3\x26\x0c\xc1\xd1\x0d\x41\x3d\xd4\x7e\xbe\x6d\xaa\x0c\x30\xdc\x42"}, +{{0x2b,0x4c,0xae,0x38,0x0e,0x95,0xce,0x69,0x4c,0x26,0xac,0x79,0x57,0x44,0x73,0x47,0xf9,0x8e,0x31,0xb4,0xbf,0x02,0xd7,0x44,0xe1,0x31,0x52,0x90,0x71,0xe2,0x30,0x1d,},{0xe6,0xfc,0x70,0x5a,0x79,0xc9,0x8e,0x11,0x5b,0x4e,0x28,0xd3,0xaa,0x15,0x06,0xb7,0x4e,0xe7,0x42,0x76,0xc5,0xfc,0x11,0x09,0xa7,0xf4,0xd8,0x9c,0x6f,0xaf,0xb8,0x89,},{0x55,0x5e,0x45,0x65,0x6b,0xa9,0xcf,0xbf,0x51,0x55,0xd0,0xe5,0x25,0x76,0xe5,0x19,0x7a,0xbb,0xbc,0x9d,0xd2,0x33,0x99,0x3e,0xec,0x2a,0x1e,0xe7,0xf6,0xa8,0x64,0x09,0xc0,0xb7,0x1b,0x0a,0x66,0x19,0x78,0xff,0x5e,0x0a,0xcd,0xc9,0x46,0x3d,0xc4,0x49,0x90,0x6f,0x47,0x4f,0x8e,0x79,0xbb,0x86,0x16,0x8b,0xf7,0x07,0x41,0xe3,0x4b,0x02,},"\xe0\xb8\x25\x0e\x27\xb7\xc0\x29\x1d\xbc\x47\xa6\xda\x6f\x12\x68\x98\x7a\xfd\xf0\xa1\xe9\x0b\xe6\x9b\xcb\xc4\x37\x08\x65\x21\x78\x30\xd5\x20\x86\x93\xbe\x7b\x70\x45\x09\x9a\x22\xea\x27\xf9\x52\xeb\x3f\x79\xa9\xa0\xf1\xb5\xa8\x7b\x19\x36\x77\x90\x78\x8d\x34\xc2\x19\xc2\xe2\xa6\xb8\x34\x02\x0f\xb4\xfd\x14\x9d\xc5\x6b\x54\x4f\xdd\xbb\x42\x07\x1a\x16\x2f\xc7\xcb\x33\xc1\x46\xca\xc0\x5a\x31\xb1\x83\xe9\xda\xad\xc6\x16\xf3\xaf\x44\x9b\x17"}, +{{0xb5,0x64,0x91,0xe5,0x49,0x99,0xbb,0x5a,0x17,0x15,0xeb,0xfa,0x2f,0xeb,0x14,0xa5,0x45,0xa3,0xa4,0x3c,0x2f,0xdf,0xd4,0xbe,0x0c,0x95,0xfc,0x11,0x81,0x9a,0xd6,0x95,},{0xcd,0x42,0xbf,0x41,0x4f,0x9b,0xfc,0x72,0xec,0x06,0x98,0x82,0xa8,0x00,0x55,0x7c,0xdf,0x31,0xbc,0x34,0x64,0xfb,0x10,0x2c,0x31,0x0e,0x6d,0xbd,0x3a,0xe2,0x08,0x63,},{0xe3,0xbe,0x3e,0x71,0xa8,0x98,0x52,0xdf,0x3c,0xff,0xd7,0x2d,0x68,0x20,0x78,0x69,0xdd,0x3e,0xce,0xb4,0x9b,0x1f,0x02,0x94,0x93,0xec,0xcb,0xb9,0x32,0x44,0x4e,0xbe,0x8c,0x8c,0x6d,0xb5,0xf0,0xa5,0xa6,0x7e,0x21,0x94,0x40,0x8d,0xf9,0x84,0x19,0x13,0xa5,0xac,0x1a,0x60,0x68,0x96,0x41,0x9a,0x66,0x8f,0x4f,0x47,0xc5,0x6c,0x2b,0x08,},"\xeb\x44\x18\xba\x30\x68\x3e\xc7\x95\x9b\xdb\x1e\xc7\xb2\x63\xf8\x3e\x81\xf0\x54\xdd\xcd\xbe\x0a\x67\x38\xca\x77\x63\xe2\x46\x93\x5b\xac\x41\x90\x26\xc2\x2b\xfb\xdd\x12\x36\x33\x6c\xc1\x61\x07\xc5\x35\x13\xe3\xdd\xf3\x4e\x12\x08\x46\x96\x2c\x3b\xdd\x54\xf5\xad\x57\x49\x59\x72\x08\xf1\x5a\x8b\xb5\x66\x67\xba\xa8\x95\xf0\x83\x40\xdb\x89\xb8\x5c\x43\x5e\x77\x09\x31\x92\x8d\x8a\xbc\x99\x26\x2f\x83\x9a\xed\xd9\xbe\x2a\xa1\x38\xc9\x25\x9a\xdf"}, +{{0x65,0x79,0xc2,0x47,0xdd,0x2c,0xd0,0x2b,0xa2,0xf7,0xd7,0xa9,0x50,0xa3,0x30,0x75,0x26,0x81,0xe9,0x2c,0x0d,0xc6,0x29,0x84,0xbb,0xea,0x27,0x9e,0xa5,0x21,0xc3,0x81,},{0x0b,0x08,0x7b,0xea,0x1a,0x1b,0x3d,0x15,0x80,0x5c,0xb6,0x04,0xf4,0xbb,0x8d,0x68,0xed,0xde,0x27,0x4f,0xaf,0x52,0x1f,0xe6,0xdf,0x50,0xc5,0x5f,0x8a,0xd4,0xa7,0x0d,},{0xec,0xca,0xf8,0x01,0xae,0x0a,0x91,0x2e,0x21,0xc6,0xb8,0x3a,0x5f,0x0e,0x4e,0x88,0xd4,0xb2,0x71,0x34,0x59,0xff,0x93,0x44,0x9f,0xc0,0xb2,0x1a,0x9f,0x41,0x60,0x50,0x11,0x3c,0xba,0xe4,0xe8,0x14,0xd2,0x0c,0x0a,0x79,0x8f,0x76,0xd2,0xf9,0xd3,0x26,0xed,0x83,0x95,0x9e,0xa0,0x2a,0xbd,0xc1,0xab,0x35,0x0a,0x46,0x71,0x23,0xf7,0x09,},"\xdf\x7c\x55\x2f\xfc\x89\x37\x4b\x95\x71\xa6\x02\x4a\x8d\x04\x71\xd7\xeb\x6b\xe8\xdf\xca\x6f\x41\x66\xb5\x81\xb6\x54\x79\x01\x5a\x05\x68\x12\x90\x74\xcc\x04\xd6\x34\x2c\x75\x8c\xa1\x8f\x79\x87\xde\xc5\x36\xb7\x03\x3d\x5f\x96\x81\x50\x43\x40\xe2\x09\x86\xf0\x27\xb8\xcf\x1f\x26\x3b\xe7\x6d\xb3\x52\x5d\x17\x34\x22\x95\x0e\xa8\xdc\xed\xdc\x58\x56\x40\x91\x8a\xa9\xd2\x5c\xa8\x9c\xba\x70\x1c\x20\x20\x15\x38\x73\xf4\x61\x08\xc7\x72\xcb\x38\x8d\x55"}, +{{0x18,0xfb,0xa6,0x0c,0x50,0x26,0xf3,0xc9,0xdd,0x7a,0xed,0xc0,0x42,0x09,0xd5,0x26,0x03,0x61,0xde,0x40,0x0e,0x19,0x0a,0xeb,0x60,0x16,0x9e,0x05,0xa3,0x36,0x7c,0x9f,},{0xdf,0xff,0x34,0x7f,0x3d,0xd2,0x55,0x53,0x0b,0xf7,0xfb,0x34,0xd0,0x2b,0xa4,0x86,0xd1,0x12,0xbb,0x46,0xe9,0x50,0xe2,0xef,0x80,0xe5,0x17,0x01,0x4c,0xc9,0x57,0x34,},{0x4b,0xc0,0x11,0xe4,0x0f,0x0f,0x59,0xc6,0x18,0xf6,0xbb,0xe2,0x30,0xb6,0xf7,0xbc,0x2f,0x50,0xe3,0x61,0x7c,0x7f,0xaa,0xb7,0xf4,0xc2,0x1c,0xb8,0x4f,0x77,0xeb,0xa9,0x94,0xcb,0x7c,0x2a,0x1b,0xf1,0x0b,0x01,0xbb,0x20,0x08,0x44,0x97,0xfd,0xf0,0xa6,0xab,0x5d,0x9b,0xcd,0x22,0xc4,0xa2,0xc5,0xa7,0x8f,0x79,0x92,0x68,0x25,0x94,0x0f,},"\x34\xf0\x8a\x80\x4d\x78\x29\xcc\x39\x14\xf0\x00\xce\x1a\x32\x88\xac\xce\x21\x49\xc8\xa0\x20\x86\xb9\xf6\x7a\xfc\xcd\x83\xa1\x78\xb0\xbc\xfd\x49\x70\xc0\x56\x99\x7d\xa7\xdc\x3d\x47\x56\x2f\x16\x66\x3c\xed\xc5\x2f\x82\xd7\x10\x85\x0c\xf4\x05\x03\x79\xef\xda\xc2\x3b\xee\x17\xc3\x30\xa3\x83\xad\x13\x7f\x78\x84\x73\xb2\xb0\x72\x36\x03\xb6\xde\xb1\xfd\xbf\x6c\x52\x3f\xc9\x48\xa0\xcc\xc4\xff\x10\x0f\xb9\x46\xd8\x74\xc1\xf9\x90\x43\x6a\xe8\xc4\xf3\xb2"}, +{{0x07,0x3c,0xc1,0x5b,0x05,0x36,0x28,0x59,0x33,0xb2,0xbe,0x39,0x25,0x3c,0xf4,0xfd,0x69,0x6b,0x81,0x61,0x0f,0x5d,0xd3,0xad,0xac,0x2e,0x9c,0xbf,0x33,0x8e,0xf2,0xf6,},{0x00,0xb5,0x51,0xd3,0x71,0x54,0x43,0x75,0xda,0xc5,0xc4,0xe9,0x6c,0xd1,0xf0,0x21,0x52,0x07,0xe8,0xe1,0x66,0xa1,0xfe,0x49,0xd5,0xb0,0xa5,0x1a,0xc1,0x84,0x43,0xec,},{0x3a,0xa5,0x2a,0x83,0x06,0x2a,0x8f,0x28,0xa5,0xd6,0xb7,0x60,0x7f,0x48,0x4b,0x66,0xcc,0x37,0x48,0x96,0xb7,0x66,0x12,0x31,0x26,0x33,0x3c,0x57,0x95,0x81,0x31,0x6c,0x74,0x28,0x06,0xf6,0x27,0xb5,0xbc,0x55,0xca,0xd7,0x05,0xcc,0x1d,0x47,0x82,0xb0,0x44,0x08,0x0c,0x8a,0xc8,0x40,0xf3,0x8c,0x0c,0x50,0xd3,0x5e,0x34,0x5c,0x78,0x03,},"\xc2\x85\x36\x2b\xc8\xef\x62\x8f\x7a\xed\xf6\x54\x23\x1e\xe5\x1a\xcd\xf2\xcf\x69\xa8\x86\xb9\x42\xbb\x9b\xfe\xd8\x15\x51\x05\xd9\x20\x9d\xed\x2a\xf2\x4f\x16\x9a\xd5\xfc\xd4\x51\x37\x0f\x58\x27\xa8\x51\x11\xc7\xa5\x2e\x03\x2c\x50\x38\x61\x7c\x0c\x01\x70\xe2\xa6\xc2\x31\xdc\x40\x1d\x12\x06\x2e\xdb\x18\x60\x36\x11\x4e\x38\x79\x3b\x79\x08\x90\x77\x58\x1b\x97\x83\xf4\x00\x07\x10\x3e\xf1\x74\x72\x49\x1c\x00\xe7\x13\x8a\xec\xc5\x08\x4d\x3c\x85\x01\x04\x70"}, +{{0xfd,0x89,0x4a,0x1e,0x82,0x32,0x20,0x3b,0x28,0x95,0x05,0xd5,0xc6,0x8c,0x68,0x79,0x1f,0xfc,0x0e,0x54,0xf2,0xa8,0x75,0x30,0xfb,0xba,0x5b,0x3a,0x3f,0x2c,0xaf,0x00,},{0xe9,0x5a,0xb5,0x65,0x94,0x5c,0x7a,0xe5,0xd5,0x33,0xdf,0x5d,0x0c,0xcc,0xc7,0xe9,0xab,0xbc,0x83,0x8e,0x20,0xa0,0xb6,0x1c,0x93,0x0f,0x5d,0x41,0xd8,0x1a,0x6f,0xe7,},{0xf5,0x11,0x02,0x21,0x9e,0x88,0x04,0xbe,0x71,0x3e,0x55,0x6d,0xf4,0xe4,0xaf,0xa2,0xf8,0x86,0x6f,0xe8,0x65,0x41,0xa1,0xc2,0xa0,0x93,0x4d,0x24,0xc3,0xc9,0xbe,0xb2,0x80,0xa7,0x0d,0xd8,0xd5,0x27,0xfe,0x8b,0x7e,0x0b,0x94,0x82,0x14,0xd5,0xf2,0xf9,0x63,0x86,0x19,0x91,0x4b,0x72,0xd5,0x5d,0xc1,0x98,0xb0,0x22,0x9a,0x84,0x87,0x08,},"\x26\x69\x62\x4a\x94\xf2\xc4\x4a\x05\xb7\xdc\x3e\xbf\x93\xe5\x8a\x4b\xf3\xa0\x1c\x27\x36\x57\xe7\xe7\x87\x89\x76\xf6\xb6\xea\x73\x7f\xa3\xf2\x2c\xc8\x36\x5b\x8b\x22\x0c\x00\x7d\x5b\x64\x27\x26\xa4\x08\xfe\x2f\xab\x69\xeb\xb3\xbd\x07\x2b\x34\x9f\x4d\xc3\x37\x7e\xe7\xcc\x75\x29\x34\x25\x42\x15\xd2\x39\x89\xbd\x3c\xd0\x2c\xe9\x99\xad\xec\x97\x84\x99\x3f\x4c\x19\x94\x08\x15\xf3\x9c\x9e\x22\x92\x47\xf5\x20\x5c\x36\xcb\xa4\x4e\x71\x42\x66\x36\x92\x89\xb4\xa7"}, +{{0x18,0xef,0x46,0x4e,0x28,0xf8,0x7f,0xfc,0xfa,0x4d,0x3a,0x9c,0x09,0xa2,0x29,0x10,0x95,0x1b,0x8c,0x71,0x9f,0xda,0xcd,0xb5,0x6d,0xe6,0x2c,0x4b,0x40,0x6d,0xf0,0x0c,},{0xc5,0x06,0x4c,0x9d,0x43,0xee,0x2d,0xa7,0x5b,0x06,0xbb,0x09,0xc7,0x72,0x67,0xdb,0xd0,0xd3,0x91,0x28,0xf1,0xcd,0xc6,0xbf,0xa4,0x51,0xa0,0x3e,0x93,0xaf,0x4a,0x70,},{0xd1,0xe7,0xf1,0x6e,0x8e,0x59,0x7d,0x42,0x8a,0xde,0xa6,0x55,0x91,0xd5,0x51,0xb5,0x4b,0x66,0x7a,0xff,0x20,0x20,0xc4,0x64,0xf7,0xf4,0xe5,0x3c,0x47,0x73,0xf7,0x04,0x33,0x24,0x9a,0x3c,0x71,0xb4,0xd1,0x1c,0x89,0xc3,0xfa,0xa8,0x92,0x80,0x92,0x27,0xb9,0xf2,0x9e,0xf4,0xf7,0xf5,0xd0,0x20,0xd4,0x67,0x4d,0x40,0x21,0x35,0x94,0x05,},"\x9c\x82\x57\x07\xd9\x35\x83\x65\xab\x9d\x38\xf7\xe7\x28\xd6\x28\xaa\x72\x2a\x4f\x1a\x20\xa3\x8e\x47\xc9\x99\xff\xf8\xfc\x32\x41\x7f\xbe\x07\x2f\x96\xeb\x6a\x0e\x11\xe4\xda\x9b\x6d\xe9\x61\x54\x45\x28\x0e\x93\xc7\x7a\x36\x34\xd3\xd2\xc6\x87\x98\x56\xc2\x48\xf9\x80\x0f\x60\xa0\xd3\x8d\xc1\xce\xa8\xb7\xf3\x1f\x28\x6c\xb0\x37\x48\x27\xb4\xc6\xba\x14\x4a\x66\x94\xf2\xb9\x08\xea\xd6\x8d\x18\x34\x01\x24\xcb\x59\xcf\x17\x01\x86\x3b\xd4\xf3\xef\xc7\x09\xf3\x62\x7a"}, +{{0xc9,0x11,0xbd,0xf2,0xf9,0xe7,0xcc,0x5f,0xff,0x35,0xc9,0x6e,0x15,0xcc,0x12,0xea,0xfd,0x05,0xab,0x0d,0xb3,0x1f,0x64,0x9f,0x74,0x08,0xac,0xd0,0xca,0xda,0x76,0xe0,},{0xde,0x44,0x69,0x6c,0xd6,0xbd,0x2c,0xbe,0x9b,0x11,0xa0,0xef,0x18,0xb8,0x81,0x64,0x80,0x1a,0x96,0x9d,0x5e,0x06,0xed,0x45,0x3e,0xb4,0x00,0x8c,0xce,0x9a,0x57,0x25,},{0xd5,0x84,0xb5,0xda,0x37,0x1a,0xe4,0xf5,0xc9,0x85,0x9b,0x25,0xf7,0x0d,0xc5,0x6c,0x1b,0x7b,0x4e,0x02,0xd1,0xae,0x66,0x36,0x28,0x3b,0x1b,0x7b,0x11,0x21,0x7a,0xfd,0xcd,0xf6,0x5d,0x1b,0x49,0xca,0x2c,0x8e,0xf1,0x79,0x66,0xe9,0xbc,0x65,0xf1,0x0c,0x31,0x0b,0x77,0xbb,0x5d,0xf7,0xaf,0xf5,0xec,0x1b,0x37,0x9a,0x2c,0xe5,0x5d,0x0d,},"\x76\xc4\x71\x24\x1d\x17\x19\x29\x84\xb0\x03\x62\x69\x6e\x4d\x9d\x4d\x2b\x7f\x83\x9c\x20\x64\x11\x7e\x50\xa1\x59\x8f\x3a\x11\x72\xb1\x6c\x55\xe5\x39\x68\x66\x08\x47\x52\x02\x4f\x3a\x7e\xb6\x8b\xb3\xff\xdb\x80\x97\x9a\x0a\xf6\xd0\xf6\xaf\x26\xb6\xf0\xbc\x0c\x03\x84\x43\x3b\xcf\xd4\x4c\x75\xeb\x65\x4a\x8a\x82\x25\xcb\x9c\x4a\x7f\xb3\xc8\x24\xc3\xaf\x61\x25\xfd\x46\xdb\x28\x7e\x70\x49\x2d\x15\x46\x32\xcb\x8f\x62\x43\x26\x59\xd9\x58\xd6\x28\x1d\x04\xa5\x4f\x5f\x5f"}, +{{0xd3,0x70,0x32,0x99,0xc4,0x1d,0xb3,0x6d,0x77,0xdd,0x3a,0x49,0x54,0x1f,0x3f,0xb2,0x1d,0x0b,0x2b,0xad,0x1f,0x6e,0x07,0x4a,0xff,0xd9,0x6f,0x1c,0x40,0xd0,0xf9,0x27,},{0x86,0x2c,0x5e,0xf6,0x16,0xa5,0xf0,0x66,0xfd,0x87,0x75,0x8a,0x56,0xab,0x45,0x05,0x6f,0xea,0x4b,0xd3,0x3f,0x00,0x8b,0xe2,0x4f,0x7b,0x54,0x0e,0x09,0x5e,0x14,0x8e,},{0xdf,0x28,0x27,0x71,0x21,0xea,0xc4,0x46,0x30,0x08,0x4c,0xce,0x75,0x91,0x7a,0xe9,0xf6,0xbe,0xc6,0x5a,0xf5,0x57,0x2d,0xc3,0x07,0x19,0xbd,0xe6,0x61,0xcf,0x69,0x6b,0x85,0xb8,0x67,0x2d,0xd4,0x98,0x3c,0xab,0x30,0xbd,0x05,0xcc,0x3a,0x11,0x9d,0x7d,0xb9,0xba,0xbd,0x52,0x2d,0x7b,0x3a,0x6b,0xcf,0x38,0x86,0xec,0xd2,0x5e,0x08,0x0f,},"\xac\x92\xed\xbe\x22\x25\x7b\xb0\x6d\x94\xaa\x95\x0e\x62\xd1\x8c\xa2\xac\x0a\x8f\xc1\x06\x00\x0d\x22\x31\xf8\xa1\x3b\x8d\x7a\x20\x9c\xcd\x8c\xc4\x9a\x6c\xd6\x8a\x7f\x36\xc0\x2f\xb8\xf7\x28\xd1\x55\x95\x16\x7f\x0b\xa8\xcf\xe9\x5c\x8a\x1e\x43\x5f\x32\x75\x13\x01\x4a\xc4\x28\xb7\x5d\x4f\x72\xe7\xc8\x34\xdd\x70\xe1\xa4\x48\xf1\x84\x7d\x34\x98\x47\x5f\x74\xe3\xd9\x33\x4d\xc7\xdc\xc4\xfe\xd7\x2b\xf6\xc7\xfe\x3b\x1d\x4f\x53\xd4\x29\x61\x6f\x1d\xf4\x4f\x19\x73\x31\x58\xb6"}, +{{0xd4,0x11,0xcd,0x33,0x57,0x6d,0x0e,0xfe,0x9e,0xc4,0x13,0xcc,0xda,0xab,0xd4,0xfc,0xba,0xfe,0xc0,0x1a,0x3a,0xf4,0xb3,0xcb,0xe3,0x4f,0x8b,0x05,0xef,0x8b,0x59,0xba,},{0xe8,0x70,0x34,0x4d,0xf9,0x8d,0xd3,0xa8,0x70,0x2c,0x45,0x19,0xbf,0x9e,0x8b,0x35,0xa9,0xd1,0x89,0xe7,0x46,0xf7,0x20,0x3d,0xbb,0xf9,0xbb,0xfa,0xb2,0x2d,0x6f,0x63,},{0x83,0x46,0x0d,0x15,0x46,0x1d,0x67,0x17,0x71,0x0b,0xaf,0xd6,0xa4,0x7a,0x1e,0xaa,0x90,0x0a,0x80,0xf2,0xbf,0x8b,0x8a,0xae,0x24,0x68,0x77,0x36,0x14,0xee,0x84,0xbd,0x62,0x8c,0x97,0x17,0x47,0x63,0x68,0xef,0x36,0x40,0xcf,0x76,0x0a,0xca,0xc8,0x3a,0xd6,0x02,0x32,0xa7,0x69,0x63,0xb7,0xd5,0x25,0x88,0xb1,0x1d,0xc0,0x04,0xd7,0x0d,},"\x11\xd2\xc2\xa7\xf0\x19\x09\x88\x12\x66\x96\x43\x1b\x4b\xbc\xd9\x0a\xb7\xb5\x6a\x32\xda\x64\x04\xae\x44\x6a\xa7\x62\xa4\xdd\xc6\x60\x94\x97\x15\x38\xee\xb8\x5b\xde\x04\x70\xa5\x10\xbe\x0d\x6d\x85\x78\x0e\xe7\x30\xa9\x85\x41\x38\x72\x8a\xe6\x81\x61\x62\x26\x8d\xa8\x52\x85\x8e\xae\xd4\xec\x74\xc7\xac\x62\xe6\xe7\x09\x6d\xc0\x02\xdf\x0b\xdf\x5f\xa4\x0d\xa5\x65\xb4\x1d\x18\x1a\x3f\x0a\xd0\xc5\xe0\xb9\x76\x74\x3e\x31\x5d\x9d\xb8\xed\x41\x60\xab\xe6\x9c\x13\xa2\xb3\xf0\x9a"}, +{{0xe1,0x0a,0x2f,0x13,0x80,0xc3,0xe4,0x72,0x0e,0x8a,0x87,0x07,0xa9,0xbc,0xb2,0x5a,0x0f,0x58,0x27,0x0d,0x70,0x59,0xcd,0x76,0x26,0xc7,0x15,0x34,0x47,0xed,0xfb,0x87,},{0xa3,0xc7,0x17,0xac,0xab,0x36,0x6a,0x40,0xb5,0x11,0x87,0xbb,0xf3,0x5b,0x2d,0x15,0xe9,0x7c,0xfe,0xac,0xd7,0x34,0x9c,0x06,0xef,0x1c,0x91,0xac,0x93,0xe9,0x06,0x56,},{0x09,0x4b,0xf6,0xf9,0x53,0xca,0x0e,0xb7,0x7d,0xf4,0x51,0x29,0xb7,0xbf,0x10,0xd1,0x92,0xcf,0x6d,0xde,0xae,0x94,0xad,0x62,0x02,0xb8,0xea,0xcf,0xbe,0xc1,0x19,0xe5,0x29,0x15,0x78,0xfe,0x64,0xa0,0x84,0xae,0x60,0x0f,0xe0,0x7e,0xfd,0xb8,0xa7,0x82,0x61,0x0d,0xbd,0xb0,0xb4,0x9e,0xb5,0xf2,0xa4,0x6c,0x43,0x23,0x55,0x55,0x2f,0x01,},"\x13\x52\x12\xa9\xcf\x00\xd0\xa0\x52\x20\xbe\x73\x23\xbf\xa4\xa5\xba\x7f\xc5\x46\x55\x14\x00\x77\x02\x12\x1a\x9c\x92\xe4\x6b\xd4\x73\x06\x2f\x00\x84\x1a\xf8\x3c\xb7\xbc\x4b\x2c\xd5\x8d\xc4\xd5\xb1\x51\x24\x4c\xc8\x29\x3e\x79\x57\x96\x83\x5e\xd3\x68\x22\xc6\xe0\x98\x93\xec\x99\x1b\x38\xad\xa4\xb2\x1a\x06\xe6\x91\xaf\xa8\x87\xdb\x4e\x9d\x7b\x1d\x2a\xfc\x65\xba\x8d\x2f\x5e\x69\x26\xff\x53\xd2\xd4\x4d\x55\xfa\x09\x5f\x3f\xad\x62\x54\x5c\x71\x4f\x0f\x3f\x59\xe4\xbf\xe9\x1a\xf8"}, +{{0xb2,0xe6,0x97,0xb3,0xd3,0xef,0xec,0x97,0x6e,0xf3,0x36,0x95,0x30,0xc7,0x92,0x71,0x7b,0xdb,0xb4,0x28,0xd9,0xed,0x0c,0x11,0xec,0x0e,0xa9,0xb2,0xe5,0xf3,0x9f,0x82,},{0xc4,0xd2,0xe4,0xb3,0xc2,0x36,0xd6,0xc9,0xb8,0xc7,0x4f,0xa3,0x84,0x61,0x2c,0x47,0x10,0xd8,0x3a,0xa1,0x6a,0xd7,0xef,0x01,0xfb,0xb7,0x42,0x1d,0x4f,0xb3,0xf0,0xf6,},{0x50,0x47,0xfa,0x38,0x19,0x7b,0x83,0x28,0xe7,0x8d,0xd8,0xa1,0x0e,0x96,0x6a,0xfb,0x7b,0xd3,0xd4,0x36,0x08,0x28,0x0f,0x1c,0x25,0x7d,0x25,0xca,0x43,0xbc,0x1c,0x06,0xe9,0x4a,0x57,0x47,0xab,0x62,0x15,0xec,0xe5,0x4c,0xde,0xff,0x8c,0x56,0x56,0x7d,0x70,0xd2,0xf9,0x1f,0x9e,0xc8,0xc2,0x60,0xaa,0x10,0x80,0xa6,0xab,0x5a,0x7a,0x02,},"\x7b\x43\x62\x32\xac\x21\x11\xa8\x40\x59\x51\x0c\x48\x36\x25\x88\xfc\xb7\x38\x34\x26\xbe\x5e\x6f\x62\xf3\x72\xe4\xf7\xcc\xa8\x3c\x81\xc2\x35\x7f\x9b\x54\xf4\xa1\x52\x91\x06\x5b\x6d\x41\xaa\xd1\xea\x93\xcf\xfa\x77\x6b\x9a\xca\xa5\x8a\xfe\x2b\x51\x64\x4b\x97\xaf\x9a\x3e\x53\xf8\x4e\x40\xaa\x6d\x86\x05\x1e\x69\x14\xcd\x03\x9d\x41\x70\xa9\xa5\x26\xdd\x69\x95\x5f\xf5\x07\xc3\x3f\x74\xe2\x17\x65\x91\xfb\x0b\x3c\xd7\xf0\x0e\xe4\x18\xf2\xc2\x58\xa9\x98\x1c\xcc\xee\x72\xf0\x1c\x84\x30"}, +{{0x19,0xa6,0x79,0xa7,0xa9,0x05,0xa1,0xe2,0xb3,0x03,0x8e,0x6e,0x41,0x8b,0x3d,0xa9,0x7c,0x30,0x89,0xc7,0xcd,0x35,0x1e,0xa0,0x7b,0xc8,0xd1,0xaf,0x64,0xea,0xcc,0x46,},{0x19,0xf0,0x83,0x61,0xf4,0x69,0xb4,0xae,0x1e,0x0c,0xeb,0x94,0xf4,0x7a,0x7d,0xe7,0x31,0x74,0x10,0xa9,0x2d,0xd0,0x13,0xb1,0x6a,0xe0,0xd0,0x53,0x2f,0xa4,0xb3,0xef,},{0x43,0x47,0xb7,0xb4,0xf7,0xc3,0xc4,0xdd,0x31,0x5b,0x83,0x84,0xa0,0xb0,0xca,0xee,0xd8,0x4b,0xda,0xbe,0x24,0xb2,0x91,0x5f,0x12,0x51,0x2d,0xfd,0x04,0x77,0x0f,0xc9,0x96,0xa1,0xbf,0xb7,0x29,0xaf,0xef,0x9e,0xdd,0x61,0x14,0x47,0x08,0x1a,0x53,0x30,0x61,0x7e,0xae,0xa1,0xc1,0xda,0xb1,0xbf,0x13,0xce,0xa8,0x99,0x72,0x04,0x91,0x0c,},"\x98\x0c\x7b\x4d\x29\x39\x06\x1a\xc7\xb9\xba\x44\x11\x17\xa1\x94\x85\x66\x17\x81\xa4\x08\x30\x67\xc5\x5a\xcf\x93\x02\x6c\x08\x2a\x93\xcc\x12\x4f\x09\x5e\x1b\x4f\x2c\x3f\x6c\x13\x54\x12\xa5\x09\x62\x28\xe8\xa0\x71\xe8\xb4\xb6\x68\xba\x9d\x96\x44\xea\x9f\x4d\xab\xfc\x54\xa9\x85\x6c\x3e\x96\x5e\x63\x63\x39\x5a\xb7\x09\x03\x7d\xda\x22\x9b\xaf\x92\x7c\xd0\x1f\x9a\xf5\xe0\x39\xaf\xc4\x2f\x3c\xec\x63\x4f\x5d\x83\x2d\x2a\xb7\xc7\xca\xd3\xad\x7b\x8c\xf2\x7e\xbd\xac\x69\x84\x31\xad\x82\x36"}, +{{0xf0,0x3b,0x83,0x63,0xee,0x5b,0x0e,0xef,0x70,0x18,0xa4,0x9b,0xc0,0x2a,0xdf,0x73,0x1d,0xa5,0x4e,0xe5,0x0a,0x7f,0x03,0xb8,0x8a,0x29,0xa2,0x08,0x2b,0x18,0x9c,0x43,},{0x31,0x28,0x7e,0xf5,0xa2,0xe6,0x41,0x04,0xab,0x77,0x90,0xb3,0x12,0xf3,0x5c,0x7a,0xd4,0xaf,0x6b,0xeb,0x0d,0x7c,0xeb,0x8a,0x58,0xf3,0x6a,0x54,0xce,0x27,0x2c,0x3e,},{0xe8,0xfa,0x96,0x7e,0x6a,0xfa,0xdf,0x6a,0x87,0x7d,0x87,0xe5,0xf5,0xc5,0x2b,0xb6,0x34,0xb7,0x5a,0x78,0x04,0x19,0x9a,0x2b,0xc9,0xd0,0x27,0xb6,0x3a,0x35,0x65,0x4d,0x9d,0xdd,0x06,0x83,0x04,0x55,0x64,0x1d,0xbf,0xb4,0x9e,0xdc,0xe4,0x2e,0x20,0xe7,0xd4,0x10,0x4a,0x07,0x1c,0x2c,0xbb,0xec,0x23,0x01,0x8c,0x29,0x7c,0xed,0x99,0x08,},"\x24\x19\x1b\x54\x64\xb3\x5a\xc7\xbc\xf4\xa3\x75\xf0\x33\xef\xba\x89\x43\xb0\x9b\x9f\xf0\xfc\x40\x3c\xa7\xaa\xe7\x02\xa3\xcb\xf3\x96\xc5\x13\x1b\xc0\x08\x13\x2c\xf5\xf1\x29\x10\xd5\x86\xdc\x1d\xb9\xc0\x84\x57\x4a\x96\xba\xbe\xe9\x56\x42\xf9\x22\x37\x1c\x03\x82\xec\x04\x02\xa2\x6f\xeb\x14\x2e\x41\x46\xbb\xd3\x36\x0c\x2b\x36\x83\x4f\xe4\x5a\xf5\xe2\x86\x8d\x4d\x56\xfd\xd5\x04\xce\xbf\x0c\x2d\x7f\x57\x91\xb4\x42\x94\x17\xc8\xb6\x5a\x98\xe0\xb1\x5c\x46\x6c\x13\x7f\x41\x05\x24\xfc\xe7\x37"}, +{{0x11,0x08,0x6b,0x0d,0x11,0xe4,0x15,0xab,0x1c,0xe0,0x2a,0xaf,0x8f,0x06,0x21,0xb5,0x44,0x30,0xf6,0xfb,0x13,0x5c,0x74,0xf4,0x0d,0x38,0xe8,0xc6,0x47,0x37,0x06,0x4b,},{0x71,0x66,0xdf,0xbc,0x69,0x1e,0xb8,0xc2,0x01,0x11,0x4b,0xa0,0xd1,0xa2,0xc7,0xb8,0x7f,0x7a,0x1f,0xd8,0xd0,0xb3,0x60,0x58,0xb0,0xd7,0xdc,0xab,0xe1,0xae,0x30,0xda,},{0xe9,0x07,0x45,0x9d,0x5a,0xdc,0xd0,0xd0,0xc3,0x64,0x18,0x58,0x1f,0x19,0xd0,0xee,0xbd,0xa7,0x13,0x8e,0xbd,0x9f,0xaa,0x0b,0x26,0x22,0x01,0xf4,0x58,0xc8,0x56,0x31,0x0b,0xb7,0x7f,0x4c,0x7d,0xe9,0x22,0x49,0x5d,0xcf,0xe8,0xb2,0x48,0xed,0xa2,0xad,0x0d,0xf6,0xa7,0x3f,0x47,0xbb,0xfb,0x89,0x4b,0xaa,0x7d,0x88,0x69,0x87,0x58,0x02,},"\x4b\x5b\x29\x36\xc5\xe3\x60\xa3\x84\x55\x50\x37\x21\x07\x8f\x8a\xdb\x40\x4a\x7e\xe7\xec\xc1\x48\x01\xdc\x87\xa6\x7a\x15\x2b\x76\x95\x69\xfb\xea\xc0\xaf\xa2\x5a\x20\x70\xa1\x68\x6b\x90\x0a\xc1\x63\x3d\x49\x98\x08\xcd\xb2\xe8\x1c\xe3\x91\x6d\x5a\x3c\x04\xd1\x9c\x5b\xb2\x69\x9a\x66\x2b\x8a\xba\x4a\xf9\x4d\x39\x0b\xac\x7c\xcc\x8e\xc9\x10\xed\x2a\xcd\xf8\x6e\xbb\x71\xad\xb6\x01\x87\x78\x85\xee\xf3\xc9\x16\x62\xfc\x30\x73\x8e\x35\x2c\xc7\x43\x53\xcc\xf8\xd8\xed\xee\xfa\xcc\x04\x2c\x10\xa0\xe5"}, +{{0xef,0xce,0x76,0x67,0xa8,0xef,0x91,0x22,0x8c,0xae,0xd1,0x4e,0xb4,0x77,0xa3,0x45,0xe5,0xe8,0x23,0x92,0x34,0x08,0x08,0x48,0x76,0x0e,0xd0,0x97,0x07,0x13,0xfa,0x86,},{0x91,0x93,0x05,0x5a,0x84,0xdf,0x1e,0xac,0xca,0x28,0xce,0x2a,0x08,0xc2,0xa0,0x7a,0x50,0xf0,0x4c,0x02,0x4e,0xcf,0x1f,0xe4,0xa4,0x7d,0x2e,0xfb,0xaf,0x63,0xed,0x58,},{0xe5,0xa6,0x31,0x24,0xdb,0x16,0x96,0xb6,0x41,0x40,0xb6,0xe9,0x61,0x2f,0xa9,0x58,0x7b,0x3e,0xef,0x71,0x01,0x09,0x39,0x8d,0x44,0xba,0x0c,0xa6,0x3c,0x0e,0xba,0xd0,0x6f,0x0a,0x6c,0x89,0x94,0xea,0x34,0xb3,0xa2,0xaf,0x91,0xa8,0x9b,0xf4,0x1a,0xe6,0x14,0xd7,0x72,0x7d,0x71,0x6f,0xd4,0x2f,0x8b,0x92,0xe1,0xac,0x64,0xfd,0xbf,0x03,},"\xaa\x1b\xc8\x0d\x7b\xcc\x1d\x94\xa2\x3a\x57\xce\xdf\x50\x27\x48\x24\x77\xdc\x46\xb8\x68\x90\xbc\x0e\x5a\xc2\x9a\xe6\xc9\x1b\xbc\x43\x13\x03\x48\x79\x73\x05\xf7\x55\x43\x58\x0a\x8a\x06\x9b\x34\x8a\x7b\xd8\xfc\x3e\x01\x52\x30\xb7\xc1\x94\x0c\x7f\x80\xa8\x2b\x12\x90\x09\x10\xdb\xcf\x06\x30\xda\x03\xf0\x81\xd4\x4c\x7f\x95\x5d\x4a\x11\x72\xf5\x6e\xcc\x7c\x5a\xc6\x46\x69\x6b\xff\xdf\x4e\xb6\xd8\x8b\xdd\x9c\xc3\x84\x35\x28\xb7\x25\x83\xab\xb3\xba\xd0\x2e\x56\xef\x76\x46\xee\xd5\x13\x95\x51\xcd\xeb"}, +{{0x88,0xfc,0xca,0xa9,0x6a,0xd8,0x84,0xd1,0x16,0x5b,0xe7,0x1d,0xd0,0xc4,0xf5,0xf8,0xf4,0x42,0x1c,0x60,0xfb,0xfa,0x49,0x8b,0xfe,0xe9,0xb9,0x67,0x46,0x24,0x43,0xbd,},{0xc7,0x5c,0xb0,0xe0,0x23,0x7b,0x45,0xb8,0x65,0x6e,0xea,0x9f,0x3d,0x1a,0x9d,0x4a,0xcd,0x01,0xa1,0x03,0xaa,0x26,0x9b,0xb2,0x4f,0xd5,0x41,0x22,0xfd,0x81,0xf2,0xac,},{0x27,0xd3,0xa1,0x97,0xcc,0x99,0x94,0x21,0x20,0x63,0xbc,0xe8,0xd7,0x99,0xe7,0x7b,0x68,0x53,0xb7,0x35,0x5e,0xbe,0x36,0x9b,0xcf,0x18,0x89,0xa4,0x18,0xa8,0x2c,0xaa,0x3a,0x79,0x87,0xa6,0x63,0xf6,0x21,0xde,0xfe,0x86,0xb3,0xac,0x4a,0xd4,0x4f,0xae,0xed,0x16,0xc9,0x11,0x6a,0xce,0x28,0xfc,0xcf,0x91,0x55,0x57,0xfa,0x77,0x99,0x03,},"\x9d\x0e\xac\x98\x55\x6b\xfa\x86\x72\xc3\x57\x05\xd1\xd6\x1a\xc4\xd0\xfc\xa1\x9d\xc0\xd9\x93\x01\x58\x77\x85\x7d\x27\xfd\x80\xf7\x4a\xca\xce\x66\x6c\x56\x34\x85\xd8\x1e\x53\x60\x3a\x6a\xef\x40\x87\x5f\xa5\x51\xcc\x10\x5f\x2c\xc1\x0b\x39\x69\x46\x79\xcd\xf4\xa6\xb0\x73\xbc\x88\x64\x5f\xc5\x1a\x36\xda\x17\x9d\x3d\x1e\x3c\x77\x22\x45\x4c\x5e\x73\x57\x7c\x61\xaa\x7d\x14\x8c\x4b\xa5\x0e\xa4\x6c\x56\xa1\xc3\xb3\xb3\xc4\x70\xf9\x31\x00\x49\x4e\x08\xbc\x55\x14\xac\x76\x3a\x85\x48\x3c\x42\xc7\xcd\xc2\x7c"}, +{{0x67,0x0b,0x30,0x62,0x6f,0xe3,0x67,0xd8,0xb4,0x5f,0x43,0x73,0x3d,0x6f,0x25,0xb3,0x7e,0xcc,0xbc,0xb5,0x51,0x96,0x3f,0x0a,0xc8,0xb6,0x66,0xb4,0x80,0x41,0xc7,0x2d,},{0x65,0xaa,0x4c,0x6d,0x4b,0xa0,0xab,0x34,0xbc,0x75,0xb3,0x9f,0x09,0x52,0x7c,0xa6,0xf2,0x42,0x5f,0x52,0x41,0x5c,0xdf,0xfd,0xf2,0xdf,0xf2,0x73,0xf8,0xea,0x61,0x2c,},{0x1b,0x6b,0x43,0x77,0xd2,0xb9,0x8e,0x0f,0x9d,0x24,0xae,0x8d,0xfe,0x30,0xe2,0x39,0x6e,0x20,0x04,0x38,0x0d,0x34,0x31,0x48,0x8e,0x58,0x43,0xcf,0x8d,0x2d,0x7a,0x00,0x70,0xab,0x21,0xf8,0xa3,0xb5,0x1c,0xe8,0x4d,0x2f,0x4b,0xa2,0x09,0xf7,0x39,0xf9,0x22,0xbe,0xbf,0x79,0x80,0x96,0x69,0x3f,0x56,0x22,0x87,0x3d,0x79,0xae,0x6f,0x04,},"\xd0\x0b\xcc\xa7\xe1\x84\xd1\x0e\x1f\x1f\xe4\x20\xb5\x06\x39\xe1\xd5\xde\xba\x52\xa7\x51\x23\x6e\x68\xc5\x9b\xb4\xbf\xf9\x80\x2f\x5f\xc1\x65\xed\x42\xfd\x6d\x53\x46\x70\xa7\xc6\xfb\x60\xe4\x30\x7d\x94\x79\x15\xa2\x48\xbf\x2f\x93\x46\x5c\x2c\xb4\x4d\x8f\x45\x3d\x2c\x01\x5a\xfb\xc8\xed\x58\x81\x8e\xa5\x17\x26\xa2\x51\x77\x93\x0e\x9e\xa1\x92\xef\x45\x14\xf4\xbb\x0e\xb4\xe0\xf5\xd4\xae\x3c\x46\xe3\x57\xc8\x11\x87\xf7\xed\x17\x47\x33\xff\xf9\x59\xc3\xf9\xfa\xe6\x48\x6c\xfa\x13\x56\xa9\x56\x99\x21\x1d\xe5"}, +{{0x81,0x3c,0x4d,0xae,0xd6,0x7a,0x19,0x0d,0x68,0xbb,0x63,0x5d,0x73,0xaf,0x6d,0xa7,0x4f,0x32,0xfd,0xf7,0xc4,0x8c,0xca,0x6e,0x59,0x26,0x29,0x46,0xb8,0xe8,0xc7,0x1f,},{0xa2,0x09,0x54,0x57,0xd7,0x69,0x70,0x20,0xe2,0xb8,0x84,0xd9,0x5a,0x96,0x57,0x8c,0x2a,0x90,0x0a,0x76,0x66,0xac,0x0d,0xc7,0xbd,0x38,0xf1,0x93,0x1d,0x79,0x45,0xd8,},{0xb4,0x46,0x57,0x4f,0xf6,0xa4,0xbd,0x2b,0x57,0x2e,0x48,0x7c,0x4a,0xb4,0x43,0xca,0x64,0x10,0x75,0x16,0x8a,0xa4,0xe1,0x09,0x2f,0x71,0xf3,0x0b,0xdb,0x06,0x8c,0xe4,0x6a,0x39,0x5e,0xfe,0xe1,0xee,0x66,0x0b,0x9f,0xac,0x26,0xd5,0x41,0x09,0x72,0x2c,0x15,0xcd,0xb7,0x91,0xbf,0xb8,0x7f,0xff,0x63,0xc6,0x59,0x6a,0xd4,0xf2,0x27,0x0c,},"\xce\x54\xcb\x04\x50\xe6\x89\xa0\xdb\xef\x78\x53\x08\xb3\x17\x74\x72\xfc\xd6\xd3\x82\x03\xe5\x8a\x05\x90\xb3\x1f\xa2\x53\xf9\xea\x59\x0b\xe5\x36\x8a\x92\x2d\xe8\x8b\x63\x45\x01\x02\x68\x44\x43\xfb\x81\x89\xe6\x01\x28\x20\x03\x32\x3b\x89\xc8\x1e\x92\xea\xef\x2b\x5d\xdc\x4a\x55\xc5\x3f\xa3\xcf\xad\x41\x60\x24\x8b\x3c\x28\x6f\xf8\x0d\x31\xd1\x61\xb7\xb8\xde\xe7\x13\x55\x2b\x56\xf1\x50\x7f\xb7\x2e\xad\xfa\x89\x05\x4e\x9d\x16\x00\xac\x87\x4c\x4b\x0a\x96\x10\x04\xeb\x6d\x0d\x4b\xfd\x2e\xcb\x9c\x73\x4f\x00\xba"}, +{{0x84,0x00,0x96,0x2b,0xb7,0x69,0xf6,0x38,0x68,0xca,0xe5,0xa3,0xfe,0xc8,0xdb,0x6a,0x9c,0x8d,0x3f,0x1c,0x84,0x6c,0x8d,0xce,0xeb,0x64,0x2b,0x69,0x46,0xef,0xa8,0xe3,},{0x98,0xbe,0x21,0x00,0x19,0x93,0xa7,0xeb,0x1a,0x12,0x77,0xff,0x74,0xc1,0x55,0x04,0x18,0x3d,0x25,0xfd,0xfc,0xc0,0x5f,0x0d,0x4d,0xea,0x89,0x2f,0x6e,0x30,0x18,0x90,},{0x0a,0xd7,0x1b,0x00,0x25,0xf3,0xd9,0xa5,0x0d,0xb3,0x38,0x41,0x4d,0x6d,0x67,0x0e,0x77,0x99,0xb7,0x27,0x0a,0x84,0x44,0xf6,0xae,0x7f,0x12,0xae,0x7e,0xb7,0x1b,0xd0,0x3f,0xfd,0x3c,0x4f,0x36,0x63,0x1f,0x69,0xfd,0xcc,0x40,0x61,0x46,0x8f,0xf5,0x82,0xed,0xe4,0x95,0x24,0x3e,0xf1,0x36,0x1a,0x3b,0x32,0x95,0xfa,0x81,0x3b,0xa2,0x05,},"\xf7\xe6\x7d\x98\x2a\x2f\xf9\x3e\xcd\xa4\x08\x71\x52\xb4\x86\x4c\x94\x3b\x1b\xa7\x02\x1f\x54\x07\x04\x3c\xcb\x42\x53\xd3\x48\xc2\x7b\x92\x83\xac\xb2\x6c\x19\x4f\xd1\xcb\xb7\x9e\x6a\xfc\x32\xff\x68\x6b\x55\xb0\xb3\x61\x72\x18\xdc\xf3\x93\x16\xb4\xb6\x6b\x3c\x8c\x0d\x67\x26\x7a\x86\xdb\x8a\xdf\x37\x50\x80\x1b\xcf\x93\x27\xd4\xc2\x54\x41\xb9\x61\x97\x83\x2b\x4c\xde\x0e\xac\x3f\xf2\x28\x92\xa2\xf0\xbc\x17\xc2\xc2\x13\xc0\x23\x77\xa3\x33\xe3\x08\xed\x27\x16\x58\x04\x93\x83\xb7\xe2\xe5\x7b\x6b\x8b\x12\x55\x12\xe0"}, +{{0x62,0x88,0x72,0x20,0x35,0xd1,0xea,0x69,0x9b,0xc7,0xcf,0xdf,0x18,0xd8,0x96,0x25,0x42,0x31,0x80,0xb6,0x83,0xfa,0x74,0x63,0x9f,0x4f,0x30,0xf1,0x53,0x59,0xcc,0x85,},{0xe1,0x7f,0xaa,0x01,0x95,0x72,0x86,0x1a,0x06,0x4e,0x1b,0xc5,0x71,0x25,0x6d,0xea,0x14,0x68,0xf3,0xa4,0x85,0x90,0xa8,0x91,0x38,0xaa,0xa8,0x59,0x25,0x08,0x0c,0xd7,},{0x9d,0xec,0x92,0xb6,0xe8,0x9a,0xdb,0xe8,0xf4,0xe1,0xb5,0xe9,0x3a,0xc4,0xfc,0xf9,0x57,0xde,0x7d,0x19,0x70,0xa2,0x26,0x77,0x0e,0xc4,0xed,0xa6,0x47,0xc8,0xe3,0xb3,0xdf,0xfb,0x27,0x31,0xa3,0x9e,0x16,0xe4,0xa0,0x11,0x9d,0x36,0x62,0xa9,0x37,0xe5,0x60,0x52,0x24,0x91,0xec,0x7a,0x16,0x96,0xbe,0x04,0xc0,0x76,0xb1,0x2e,0x35,0x01,},"\x8b\x6c\xaa\xca\xc5\x1d\x89\x49\xfb\x86\xac\xbc\xb1\xb9\x9d\x85\x9f\xf6\x7c\x64\x14\x7b\xc1\x21\x69\x09\xdc\xab\x07\xee\x6e\xf0\x9f\x40\x38\x63\x32\x73\x94\x68\x9d\xc3\x4a\xbc\x77\x8f\xcb\x5c\x1f\x50\x91\xac\xf5\xa0\x8f\x9d\x84\x22\x11\xd1\xae\x2e\xb4\x0b\xe9\xbb\x8d\x66\x79\x07\x74\x71\x54\x7a\x6c\x71\xff\x77\xb5\x19\xd4\xb7\x10\x8e\x32\xbc\x46\x25\x1c\x60\xde\xe8\xe3\x32\xb6\x22\x93\x16\xe6\xd5\x7c\x22\xab\x82\x6f\xf1\xbc\x33\xf2\xb0\x21\x38\x07\xc1\x92\x80\xaf\x11\x0f\xd2\x6e\xe2\x74\x68\x20\x1c\xff\x49\xcb"}, +{{0x13,0x03,0x8a,0x3a,0x65,0xef,0x32,0x75,0x9a,0x9c,0xd9,0x03,0xac,0xb5,0x54,0xb2,0x52,0xde,0x00,0xe7,0xcd,0xb7,0x7b,0xbe,0xd1,0x97,0x0b,0x20,0x68,0x0e,0xe1,0x7b,},{0xb6,0xa3,0x08,0xe6,0x7f,0x9b,0x46,0xc6,0x64,0x99,0x45,0x6a,0xb5,0xcd,0x13,0x5c,0xb2,0xfe,0x84,0xa3,0x2e,0xb0,0x45,0x35,0x86,0x26,0x60,0x4d,0xa4,0x12,0x2c,0x8f,},{0x52,0x61,0x55,0x8e,0xcc,0x3c,0x98,0xff,0x36,0x35,0x1f,0x42,0xf5,0x04,0xca,0xd4,0xa3,0x2f,0xfd,0xa5,0xa7,0x44,0x56,0x09,0x60,0xb4,0xc1,0x06,0xe4,0x49,0x2f,0x02,0xe2,0x04,0x78,0x88,0x7a,0xfe,0xe4,0xf7,0x70,0xf0,0x55,0x97,0xa7,0xe3,0x88,0xca,0xce,0xae,0x80,0x5a,0xe3,0x51,0xe0,0xe4,0x5e,0x8e,0x57,0x8e,0x6a,0x6f,0xf2,0x0c,},"\xdd\xf0\x0b\x40\x33\xa2\xa0\x88\x02\x2d\xab\xe9\x33\x56\x43\x2f\x50\xdd\xc6\xc6\xe1\xa6\x59\xdc\x1a\x93\x12\x4a\x4c\x2f\xff\xfd\x18\x27\x65\xa2\xf5\x6c\x43\xea\x0b\xfd\x8d\xe8\x01\x50\x60\x88\x9a\xe6\x94\x1c\x3f\x3e\x25\x5d\x44\x21\xa1\xc3\x62\x01\xbe\x84\x6a\x27\x38\xa7\x1f\x12\x0c\xad\x59\x8c\xa8\x52\x7d\x70\xff\x8d\x5a\x09\x93\xb5\x5c\xb5\x15\x35\x17\x11\x0a\x41\x96\x2d\xaf\xf4\x22\x50\x15\x8f\x20\x96\xd1\xdd\xaf\x71\x86\xe5\x02\x98\xcb\xe5\x1f\xcb\x42\x9c\xbe\xa4\x11\x29\x3f\x8a\x7b\xd9\xcf\x06\x9f\xa2\x37\xe4"}, +{{0xb9,0xde,0x5b,0x06,0x3d,0x3c,0xa3,0xa7,0x73,0xf1,0x14,0x94,0x1b,0x2e,0x42,0x27,0xc0,0x75,0x11,0xc0,0xf5,0xc0,0x60,0x17,0xb9,0xc8,0x84,0x50,0x18,0xf2,0x34,0x32,},{0x52,0x95,0x24,0x3c,0x86,0x46,0xe0,0x96,0x67,0x4d,0xda,0x15,0x97,0x9b,0x32,0x2b,0x9d,0xd0,0xfa,0xf2,0x7d,0x02,0x4a,0x0e,0xd5,0x77,0x13,0x34,0xe1,0x17,0x9e,0xd2,},{0x92,0xba,0x76,0x0d,0x14,0xd1,0x41,0x5c,0xfa,0xf2,0x18,0xca,0x84,0x70,0x14,0x08,0x8a,0xe5,0x1a,0xd8,0x21,0x11,0x3a,0x6f,0x86,0x30,0x35,0x6f,0x7b,0xa8,0x5c,0x00,0x5e,0x23,0x30,0xf1,0x06,0x6d,0x0d,0xf4,0x64,0x80,0x60,0x52,0xa4,0x17,0x46,0x10,0x05,0x04,0x62,0xf3,0xe0,0x13,0xd7,0x02,0xe7,0xc7,0x71,0x85,0xa0,0x32,0x58,0x0b,},"\x94\x93\xcc\x23\x89\x6b\x84\x09\x60\x46\xae\x10\x53\xaf\xe3\x94\x99\xe9\x42\x42\x54\xb3\x66\xfe\x14\x3f\x4d\xa3\x21\xe2\xdc\x9e\x47\x84\x20\x8e\x12\xa5\x42\xd8\x99\x82\x8d\xde\x7e\xff\x62\x5a\x7f\x12\x41\x69\x90\xc2\x84\x1f\xfb\x09\x5b\xf9\x4c\x0c\x61\x0e\x5a\x66\x39\x18\xb6\x89\x03\x1c\xcd\x6b\x51\x93\x49\xd0\x4d\xe1\xc2\x12\xca\x2a\x9d\x7a\xbf\x52\xe1\xb4\xfd\x46\x7b\xb6\x65\xb6\x91\x9e\xf8\xf9\x16\x17\xe2\x05\x56\x5b\xf5\x66\x47\xe5\xf8\xd5\x08\xea\x20\x0a\x84\x46\x7f\x8f\xa1\x22\xe7\x4b\xc3\xb9\x97\x9f\x11\x74\xe5"}, +{{0x8f,0xf0,0x29,0x7c,0xc0,0x88,0x42,0xb5,0xe6,0x75,0x52,0xec,0x28,0x43,0xe0,0x43,0x53,0xa3,0x4d,0x74,0xef,0x89,0xb8,0x56,0x5d,0x97,0x20,0x5b,0x74,0xca,0x13,0x3a,},{0x0f,0x7e,0xf9,0x8c,0x5b,0xa4,0xaf,0x98,0x4d,0xfb,0x77,0xbc,0x4e,0x53,0x7b,0x2b,0x39,0xe6,0x27,0x3b,0xb3,0xe7,0xb9,0x5f,0xe1,0xb7,0xe6,0x78,0x19,0x52,0xbd,0x4a,},{0x07,0x83,0x73,0x7f,0x70,0x6e,0x6f,0xf3,0x66,0x14,0xf8,0x50,0x07,0x4f,0xca,0x1f,0x48,0x5f,0x24,0xfc,0xde,0x2a,0x28,0xaf,0x54,0x4f,0x37,0xab,0xd6,0x9b,0x7a,0x58,0x1d,0xef,0xd8,0xc7,0x71,0xb0,0x31,0xe1,0x08,0xd1,0x9d,0x78,0x8c,0x74,0xc5,0xf2,0x0b,0xb3,0xf1,0xc2,0x1c,0xd9,0x2b,0xe3,0x17,0xba,0xcd,0x8f,0x65,0x0b,0x49,0x05,},"\x2b\xdc\x3a\x48\x6c\x5e\x4e\xa6\x2d\xcf\xec\x8a\x9d\x4f\xcf\x9e\xa9\x49\x0d\xbc\xc7\x15\x61\x5d\x58\x49\x0a\x72\xce\x83\x3f\xa2\x23\x87\xca\x50\xa0\x05\x25\x08\xcf\x0a\xff\x1c\xa7\x27\xf0\xfe\xd4\x6f\xfa\x7d\x3c\x8e\x23\xc5\xbb\x01\xd4\x7e\x90\xff\x06\xd3\x85\x8a\x55\x7d\x99\x26\x48\x15\x79\xda\xf4\x38\x4a\xea\x50\xe9\x6e\xc6\x15\xd2\xa3\xbf\x3c\x11\x22\xf1\xf2\x4d\xd6\xed\x98\xa5\xde\x42\x18\x83\x58\x9c\x21\x39\x98\xca\x54\x32\x37\x3e\x68\xbb\xbe\x89\x42\x8c\xa9\x88\x5d\x05\x93\xd5\xe6\x21\x51\x16\xb8\x26\x63\x86\x45\x2b"}, +{{0x05,0x0d,0x55,0x3d,0x28,0x2d,0xca,0x32,0x69,0xc8,0x3c,0x18,0x17,0x68,0xec,0x06,0x7b,0x81,0xc9,0xfe,0x0c,0x94,0xf2,0xa0,0xeb,0xbb,0x0c,0x94,0x2d,0x0f,0xcd,0x7c,},{0x63,0xe2,0x30,0xb0,0x03,0xc5,0x3a,0x56,0x72,0xe8,0x32,0xff,0x7f,0x24,0x43,0x0b,0xe2,0x23,0xe4,0x97,0xde,0x84,0x02,0x33,0xf5,0x95,0xa3,0xe2,0x00,0xc7,0x12,0x7e,},{0x3f,0x0e,0x83,0x76,0x5b,0x31,0xbb,0xe8,0xe1,0xfb,0x92,0xe9,0x67,0x8d,0x6c,0xde,0x57,0x1a,0x03,0xba,0x7f,0x1d,0xcc,0x11,0x28,0x46,0x1f,0x70,0x85,0x25,0x45,0x7f,0x4e,0x0e,0x23,0x53,0xaa,0x2b,0x59,0x8c,0x06,0x3f,0xf1,0xbf,0xfd,0xac,0x91,0x6b,0x5a,0x22,0x00,0x65,0x51,0x56,0x90,0x4b,0x05,0x85,0x57,0x7a,0x16,0x28,0x56,0x0d,},"\x15\xe1\x3b\x8c\x01\x00\x4f\x6a\xa5\xb2\x36\xdb\xb2\x81\x67\x7f\x74\x6d\x81\xe5\x48\xe0\xaa\x80\xf0\xe4\x14\x52\x15\x21\xd8\x56\xcd\x69\x4e\x7c\x91\x52\xbb\x5e\x43\x77\x6b\x60\xf6\xb5\x60\xed\x1a\xd3\xe4\xb3\x90\xdb\xf3\xe4\x6e\xf9\x25\x74\x43\xf3\x9c\x14\x9e\x02\x40\xa0\x2d\x02\x1e\x1e\x3d\x7d\x04\x6b\x26\xfd\x00\x4e\xee\x7c\xa1\x6a\x80\x59\xe1\x26\xc7\x4c\xb3\xf2\x19\x4d\xb4\x7b\xf6\x04\x65\xec\xef\x5c\x70\x4d\x2e\x2c\x75\xe2\xe5\x00\x60\xea\x2a\x31\xcb\x72\xb7\xb3\xc6\xb1\xb5\xec\x72\xab\x38\x00\x40\x85\x28\x1a\x22\xfe\x86"}, +{{0x69,0x49,0x7c,0xd7,0xb4,0xe8,0x68,0xcf,0xa0,0x32,0x8d,0x92,0xbd,0x60,0x52,0xd7,0x72,0xb2,0x76,0x73,0x95,0xc1,0x45,0x95,0xb2,0x79,0x85,0x1a,0x9c,0xdd,0x31,0xaa,},{0x5d,0x27,0x6d,0x62,0x6e,0x23,0x0d,0x18,0xe7,0xbc,0xd6,0x11,0x41,0xcb,0x93,0xc9,0x0e,0xf0,0xf7,0x9e,0x01,0x32,0x12,0x12,0xd8,0x38,0xec,0x71,0x45,0x7b,0x1a,0xac,},{0xbe,0xaf,0xa5,0x83,0x40,0x96,0x09,0x08,0xe8,0xd8,0x6e,0x40,0x32,0x9e,0x3a,0x45,0x23,0xfc,0x7b,0xe7,0x70,0xad,0xdb,0x86,0xe3,0x4c,0x37,0x72,0xf8,0x4c,0xd9,0xfb,0x33,0x8d,0x1f,0x3b,0x65,0xbf,0xcd,0xb0,0x9f,0x35,0xc6,0xda,0x36,0xd1,0xa3,0xad,0xf8,0xf9,0x1f,0x1f,0xfd,0x57,0x82,0xcc,0x83,0x02,0x06,0x43,0x3a,0x08,0x41,0x0d,},"\x53\xcd\x08\x0a\x0c\x61\xf1\xa0\x93\xd3\xb3\xa7\x45\x71\xc2\x96\x30\x3f\x36\x3b\x41\x07\xed\xbe\x88\x0b\x7a\xa9\xdf\xe4\x4a\xb5\xd5\xdc\x5f\x74\xbe\x9c\x8d\x87\x6f\x04\xd7\x54\x65\x34\x91\xab\x51\xb1\x35\xfc\x95\x3f\x71\x28\x7b\x62\xff\x41\xb6\x7c\x74\x2b\xd3\x44\x56\x71\xa9\xd4\xf2\xdc\x17\x4c\xa1\xb0\x33\x5f\x78\x62\x7a\x0d\xd4\xb3\x06\x50\x50\x41\x78\x03\x9e\x73\x93\x63\x85\x10\xff\xe8\x40\x91\xb5\x72\x98\xd3\xac\x90\x01\xc3\x67\xc1\x45\x2f\xbc\xb3\x3d\xc5\x4a\x5d\xc3\x16\xfb\x2a\x52\x70\x76\x4a\x2a\xc8\x20\xa0\xb6\x3f\xbd\xc6"}, +{{0x21,0x65,0xa4,0x86,0xb6,0x12,0xbb,0xff,0x52,0x9c,0xd0,0x03,0x46,0x96,0x4a,0x3c,0xb8,0xcd,0xcf,0xfa,0x51,0xdc,0x3d,0x52,0x4d,0xd5,0xad,0xc5,0xac,0x93,0x6d,0x68,},{0x7e,0xbc,0x83,0x9a,0x46,0x5e,0x14,0xf5,0x89,0x24,0x76,0xe4,0xa1,0x3b,0x39,0x88,0xf8,0x3b,0x3c,0xd2,0x7e,0xf7,0x9e,0x19,0x3f,0x86,0xfa,0x16,0xf3,0x4a,0x1c,0xe1,},{0x7e,0xc6,0xfb,0xa5,0x6b,0xa5,0x24,0x60,0xa1,0xb4,0xf2,0x73,0x86,0x89,0xc1,0x88,0x3d,0xda,0x9a,0xaf,0xfc,0x8b,0xde,0x17,0xcb,0x60,0x29,0xbd,0xce,0x3a,0x0e,0xbe,0x2f,0xff,0xda,0x55,0x93,0x9b,0x70,0xbb,0xd0,0x7f,0xdb,0xf6,0xfc,0x5c,0xda,0x87,0xfe,0xd8,0xba,0x58,0x57,0x5f,0x89,0x4a,0x36,0x6e,0x45,0xe5,0x70,0x5e,0xea,0x09,},"\xb7\x28\xda\x7a\x36\x16\x7c\x60\x85\xbd\x2d\x96\x2c\xf6\x39\x59\xfa\xcd\x95\xc9\xad\x45\x42\x02\x8a\xfb\xa9\x0e\xc9\xc6\xc0\x76\x0b\xda\xe9\x35\x42\x9c\x3f\xeb\x39\x33\xe2\xf0\x00\x42\xc6\x72\xad\x2c\xd7\x34\x8d\x92\xbc\x33\xf8\x17\x51\xe2\x94\xae\x91\x71\xb9\x45\xb1\x93\x14\x4e\xf8\xac\xb9\xa1\xbd\x9a\xbf\x04\x75\xce\x0d\x0a\xc7\x89\xb2\x00\xc3\x2e\x9c\x9a\x27\x36\xb1\x68\x36\x9c\xe5\xf9\x7b\x1e\x8d\x2e\x79\x00\xe1\xa7\x59\x17\x84\x41\xf1\xfc\x43\x05\x64\xae\x12\x9b\xae\x78\x57\x74\x05\x11\xa6\x68\xf3\x2c\x0a\x3b\x07\x7a\x9d\x8b\x19"}, +{{0x1c,0x64,0xad,0x63,0xdd,0x14,0x70,0x34,0x59,0x8e,0x12,0x8f,0x74,0x06,0xec,0x05,0x30,0x74,0x6e,0xa1,0xc5,0xb7,0x2e,0xcf,0x79,0xe8,0x88,0x06,0x54,0x86,0xfa,0x1b,},{0xba,0xa6,0xbc,0xc1,0xc3,0xd8,0xd3,0xb1,0x1f,0xfc,0x15,0x87,0xad,0xdd,0xc5,0x8b,0xfd,0x96,0xc2,0xb9,0x92,0xb6,0xc6,0xf5,0x9f,0xcc,0x50,0xcc,0xbc,0xdd,0x0e,0xb9,},{0x74,0x77,0xe5,0x41,0x58,0xf1,0x3b,0x71,0x28,0xc0,0xa1,0x10,0xca,0x6b,0x65,0xf4,0x25,0x14,0xfb,0x70,0xcd,0x5c,0xf2,0x8a,0x8b,0x1c,0xc6,0x11,0x0e,0xa0,0x6f,0xcf,0x94,0x29,0x0d,0xa1,0x3f,0x85,0xa1,0x1c,0x23,0x51,0xd3,0xbb,0xcc,0xbb,0x4c,0x64,0xe0,0x21,0x5d,0x6d,0x0f,0x00,0x99,0xe7,0xf2,0x7b,0xc9,0x4e,0x94,0x9b,0x15,0x0b,},"\x9e\xbd\x8e\x33\x78\x93\xbb\x05\x3e\xf2\xb9\xe3\x26\x9d\xf5\x48\x48\x49\x4f\x03\xcd\x63\x57\x6b\x33\xe6\x4b\x10\x80\xbe\x4b\xe0\x15\x26\x4a\x40\x3f\xb9\x60\x2b\xbf\x90\xca\x19\xb2\x41\xa9\xb6\x68\x63\x90\x9b\x90\x08\xce\x1b\x2f\xfc\xf2\x36\xef\xa4\xc2\x66\x8f\x0f\x47\xdb\x9f\xf5\xfa\x15\x7d\x9c\xb6\x05\x41\x2b\xe7\xdd\x8b\x07\xea\x87\x8c\xcc\xae\x6b\xf5\x0f\x93\x5b\x86\xd1\x9e\x1b\x64\x8b\x69\xe5\x28\x55\x3a\x56\xd8\xaf\xb7\x82\x21\xad\x53\x30\x7b\x7a\x4e\xc8\xd2\xfd\x48\x61\xb5\x5d\xc5\xda\xe8\xe9\x3e\xf3\x87\xfb\xbe\x0b\x4c\xe7\xf7\x88"}, +{{0x55,0xab,0xbc,0x5d,0xac,0x41,0x28,0x13,0x4d,0xc8,0xc6,0x01,0x8a,0x21,0x3e,0xd4,0xb6,0x0f,0xcc,0x8e,0x90,0xcb,0xd4,0x1d,0xb2,0xd2,0x1e,0xda,0x53,0x73,0xe9,0x36,},{0x25,0x1a,0xfa,0xa2,0x64,0x69,0x26,0xb2,0xa3,0x71,0xf2,0xa0,0x9d,0x58,0x65,0xb9,0x8c,0x9a,0x5e,0xb6,0xca,0x04,0x7c,0xd0,0xd8,0xee,0x36,0xe5,0xe0,0x41,0x69,0x74,},{0xf6,0xa6,0x1c,0x2e,0x66,0x1a,0x9e,0xb7,0xbd,0xe1,0x82,0xe3,0x8e,0xc9,0x9a,0xf9,0x85,0xf6,0x16,0x98,0xa5,0xd7,0xfa,0x43,0x0d,0x16,0xe3,0xf1,0xa9,0x37,0x09,0xb7,0x55,0x22,0x32,0x0d,0xe4,0x8a,0xfc,0xc5,0x95,0xab,0x20,0x91,0x22,0xae,0x0c,0xe1,0x32,0xcd,0xf4,0xb0,0x39,0x17,0x46,0xe7,0xff,0x34,0x11,0x77,0x57,0x0c,0x81,0x08,},"\x47\x01\x0e\x13\x98\xad\x55\xfa\xbe\x37\x1d\xd8\x64\x8f\x76\x8d\x90\xdf\x4b\x96\x5a\x3b\x39\x61\x00\xb3\x03\xb4\x0a\x17\x51\x8b\xed\x6d\x86\xb0\x9f\x73\x4a\xb7\xc1\x0b\x5f\x3a\x01\xb5\x3d\xee\xc5\xf8\x53\x4b\x70\xc7\x9f\x3f\x29\xb2\x84\xfd\xec\x48\x6f\x22\xf4\x4c\x22\xcc\xd5\xc6\x46\x35\x94\x41\x52\x67\xba\xa6\x11\xf7\x0b\x1b\x31\x6c\xaa\x1b\x68\xb5\xe0\xe9\x9b\x31\xc5\xbb\x0c\xe1\x36\x79\xa2\x3c\x31\xa6\x39\x99\x69\x81\x64\xcb\xf3\x7d\x10\x3b\xa9\x24\x90\x18\x8b\xe5\x99\x37\xf1\x23\x04\x3e\xc7\x86\xef\xe3\xd4\x11\xf9\xb0\x62\x3a\x6a\xd9\x72"}, +{{0xf2,0xdc,0xf4,0xa1,0xa0,0xd4,0x6d,0xdb,0x2d,0x72,0xf8,0xfd,0xd8,0x0b,0xbe,0xc5,0xb7,0xde,0xa5,0x91,0x3d,0xa4,0x96,0x6c,0x2f,0x4d,0x12,0xc2,0x61,0xf0,0xbf,0x98,},{0xd3,0x95,0x70,0xa2,0x5c,0xa5,0x9f,0x22,0x57,0xf9,0x3f,0x96,0x60,0x0d,0xf4,0xf6,0x3e,0x68,0x4b,0xf6,0x3a,0xe8,0xdf,0xfd,0x91,0x4e,0x46,0x29,0xc3,0xd5,0x09,0x5f,},{0x42,0x88,0x2a,0x81,0x1d,0xad,0x2d,0x85,0x18,0x85,0xe4,0xcb,0xe9,0x04,0x47,0x08,0xd9,0x1a,0x86,0xf1,0x5d,0xfa,0x1d,0x66,0xc3,0xeb,0x30,0x43,0x14,0x53,0x1f,0x30,0x15,0x20,0x8c,0x71,0x1b,0x9b,0xdb,0xc5,0xfb,0x23,0x39,0x51,0xe5,0x69,0xb5,0x9d,0x34,0xe4,0x15,0xee,0xc4,0xb3,0x7f,0xfd,0x37,0x4d,0x41,0x2c,0x9a,0x36,0x0d,0x0c,},"\x3b\x00\xe8\x08\xfc\xa4\xc1\x16\x51\xd8\x53\xd6\xb9\x0f\x95\x2c\xcf\x56\x47\xe1\x02\xd4\xee\x0a\xd7\xa5\xd1\x81\xd5\xb4\x25\x8c\x52\x3c\xd3\x9e\x3d\x98\x25\x29\x8d\x84\xc8\xcb\xa0\x9f\x43\xdb\xba\x11\x99\x88\x22\x2c\x76\x05\x9c\xaf\x17\xb4\xbf\x99\x31\xc4\x5e\x61\x74\x48\xae\xad\xe1\x51\x18\x14\x97\xb2\x45\x52\x36\x7e\x52\xbc\x45\xac\x79\x08\x88\x06\xd3\x36\x82\x07\xaa\xfe\xfd\x30\x57\x84\x5d\xce\x81\x9d\x5a\xaa\xa7\x7b\x21\x8e\x2a\xed\x3d\xa7\x6d\x40\xc1\xf0\x76\x99\xf8\x17\x2e\x4a\x5c\x80\x3f\x7a\x2a\xce\xb9\xa4\x7a\x89\x52\xe1\xb2\xf0\x53\xf2"}, +{{0x22,0x46,0xbf,0xb0,0x61,0x55,0x85,0x9e,0x10,0xa7,0x48,0xff,0x8f,0x59,0x19,0xad,0x5d,0x1d,0xaa,0xb7,0x56,0xf0,0x10,0x57,0xb7,0x90,0xd0,0x74,0x74,0x77,0x5f,0x4f,},{0xfa,0x63,0x49,0xb6,0x2d,0xc8,0xc6,0xa2,0xfe,0xee,0xf6,0xff,0xc3,0x3a,0xe0,0x85,0xc6,0x49,0x79,0x5c,0x1c,0x9d,0x98,0x98,0xe7,0x5c,0x13,0xae,0x16,0x25,0xdb,0x34,},{0x2b,0xe4,0x91,0x5a,0x35,0x2f,0x77,0x85,0x48,0x30,0x46,0xd8,0xae,0x96,0x25,0xb8,0xb6,0x32,0x57,0xaf,0x57,0xc0,0x73,0x69,0x12,0x56,0xee,0x07,0x6d,0x6e,0x1b,0x97,0x2a,0x10,0x1f,0x55,0x1c,0x70,0x5d,0x3f,0x96,0x15,0x7c,0x33,0xb5,0x6e,0xa0,0x49,0xbe,0x4a,0xf4,0xdc,0x56,0x1c,0xbe,0x3c,0x1e,0xc5,0x07,0x2d,0x7f,0x13,0x4e,0x07,},"\x63\xee\x1c\x7b\xbb\x15\xce\xbe\x1c\x22\x53\x2d\x48\x16\x82\x75\x4b\xda\xf5\x8b\x8b\xc9\x97\xae\x30\xa3\x4c\x9d\x23\xc3\x3f\x16\x90\xc3\x46\xab\x0a\x73\x65\xff\x62\x45\x74\x24\xb6\x10\x5f\x84\x21\xec\xa0\xce\x3c\x63\x0a\xcf\xeb\x9a\x1c\xc4\x16\x39\x0e\xdf\x49\x20\xe2\x2b\x23\x67\xe9\xfb\x5d\x2a\xb2\x5b\xee\x56\xda\x03\xea\x55\xe3\xf5\x78\x82\xd4\x8b\x89\x22\x93\x14\xd7\x34\xcb\x83\xc7\x9f\x4e\x17\xee\x64\xba\xe6\xf7\xad\xdb\xe9\xb5\x25\xfc\xd0\x3a\x91\x40\x9a\x2d\xde\x90\x77\x51\xdb\x8c\xc9\x7e\x08\xd0\xea\x89\xc4\xd1\x87\x18\xd2\x6d\x0b\x89\x7b\x64"}, +{{0xc0,0x88,0xa3,0xdd,0x2c,0xb8,0xbd,0x5d,0x68,0x4d,0xb8,0x53,0x8d,0xc2,0x24,0x73,0xb6,0xf0,0x14,0xf6,0x4f,0xe8,0x6a,0xf1,0x68,0xb4,0xbb,0x01,0xb9,0x0a,0x1d,0xd0,},{0xaa,0xd6,0x15,0xa9,0xc2,0x87,0x59,0xf0,0x3d,0x37,0x3a,0xbe,0x66,0x66,0x91,0xde,0xad,0x8b,0x84,0xf9,0xb8,0xb5,0x0a,0x67,0xf8,0xf0,0xaa,0x4a,0x70,0x15,0x80,0xd1,},{0x3b,0xb4,0x59,0xd1,0xac,0x57,0x5a,0x18,0x0c,0x17,0x28,0xd8,0xb8,0x92,0x49,0x70,0x49,0x2a,0x0c,0x8d,0x2a,0x37,0x8c,0x29,0xd1,0xd4,0x17,0x85,0xc8,0x37,0x9a,0x58,0xe2,0xba,0x36,0x06,0x78,0x5e,0x1c,0x5d,0xa2,0x9e,0x55,0x27,0x55,0x2b,0xc6,0xdc,0x89,0xa2,0xb6,0x9c,0x27,0xfe,0x51,0xed,0x25,0x3a,0x9f,0x3b,0x56,0x5b,0x27,0x00,},"\x74\x90\x6a\xe0\x5a\x5a\xf8\xe9\x96\x8b\x6f\xeb\x49\x85\x69\xd6\x34\x5a\x24\xf9\x71\x1b\xef\xb1\x36\xe6\xc3\xb5\xed\x49\x33\x9e\x59\xa7\x93\x8b\x4b\xa1\xa1\x18\xf1\x69\xb9\xac\xe0\xf7\x84\x2a\x26\xa6\x45\xf1\x4c\x0a\xd2\x2e\xbb\xcd\xa9\x3e\x67\xe4\xc3\x48\xef\xc3\xd9\xec\xbb\x14\x19\xe6\x26\x2d\x04\x36\xa5\x8e\xa8\x2c\x22\x02\x38\x90\x65\xcc\xf6\x7c\x4f\x55\x0e\x45\xb5\xf6\xa1\x2a\x6c\x01\x1b\x2e\x0a\x30\x10\x1d\x5c\x62\x32\x8b\xbf\x99\xc8\xc9\x55\x63\xa6\xe3\x3b\xdd\x9c\xce\x72\xb1\xf7\x20\x13\x9c\x2f\xd3\xe0\x49\x13\x14\x6a\xe5\xba\xc5\x28\x8e\x0e\x3e"}, +{{0x45,0x66,0x7d,0x1e,0x7b,0x59,0x10,0x97,0x9c,0x4a,0x32,0x83,0x17,0x96,0x83,0x71,0xc8,0x64,0xd5,0x64,0xa6,0x61,0xc5,0xcc,0xe5,0x57,0xc9,0xec,0xc6,0x1b,0xab,0x9e,},{0xed,0xcd,0xf5,0xe1,0xa1,0x70,0xe0,0x0c,0x8c,0x68,0x7e,0x7e,0x9c,0x18,0xf9,0x89,0x3b,0x5f,0xe4,0x95,0xcd,0x29,0x77,0xce,0xb7,0xf4,0x46,0xc0,0x14,0x9a,0xa9,0xd3,},{0x6d,0xe6,0x68,0xf1,0xca,0x6f,0x29,0x28,0x14,0x62,0x52,0x89,0xa0,0x80,0x80,0x20,0xc8,0x7c,0x89,0xac,0x94,0xf5,0xb0,0x50,0x8e,0x55,0x7b,0xdf,0x80,0x00,0xa5,0xca,0x80,0x8f,0x02,0x1c,0x96,0x79,0xb5,0x0e,0xe2,0xf3,0x20,0x06,0x4c,0x95,0xa4,0x64,0xa8,0x43,0x93,0x79,0x82,0x8c,0x3b,0x76,0xcf,0xa7,0x66,0x45,0x5e,0x12,0x8c,0x0b,},"\xcd\x66\xce\xc4\x76\xc8\x7c\x8d\xbf\x47\xec\x91\xda\xc4\x8f\xb5\xb4\x2d\xb1\x28\x2a\x57\x3e\x0a\x5c\xf0\xb9\x17\x68\x98\x66\x08\xe1\xd7\xeb\xd0\x5f\x52\x51\xbc\xf8\xb4\x7a\x17\x09\x32\x29\xac\xef\xbd\x44\xbe\xb2\x1c\x0c\x0c\x92\x8d\xd3\xcd\x3f\x89\x66\xec\xce\x69\x10\x33\x1c\x50\x8e\xa7\x6b\xaf\x90\x4d\x8c\x21\xf6\xc1\x7c\x2c\x58\xd0\x0a\xfd\x32\x59\xb8\xbf\x79\x4c\x14\x6b\x12\xb9\x95\xcd\xdd\x1c\x42\x89\xc5\xbe\x31\x68\xeb\xd6\x16\xb3\x84\xc2\x81\xce\x1b\x38\xa1\x0e\x18\x07\x80\x88\x53\xc6\x81\xa6\x40\xa0\x09\xb4\xd2\xac\xd7\x93\x4f\x8c\x6d\x07\x57\x81\x61"}, +{{0x24,0x89,0x74,0x28,0xae,0x65,0x46,0xd8,0x5b,0x31,0x90,0xeb,0xe3,0xf1,0xf7,0xbf,0x7c,0x71,0x25,0x28,0xac,0x85,0x1a,0x58,0x8b,0x07,0xd5,0xc8,0xf9,0x4e,0xec,0xd1,},{0x5f,0x34,0x8f,0xe3,0xea,0x5b,0x2c,0x02,0x3d,0x0a,0xf7,0xed,0xe6,0x0e,0x55,0xf9,0x1a,0xa5,0x51,0x99,0x69,0x9d,0xa1,0x5a,0x11,0xc3,0x79,0x1d,0x68,0xd7,0x10,0xbd,},{0x1b,0x5e,0x75,0xde,0xf4,0x9f,0x51,0xd6,0xb2,0xde,0x00,0x8c,0x71,0xfc,0x1a,0x90,0x9b,0xd4,0x2c,0xa8,0x13,0x29,0x8d,0xce,0x4e,0xee,0xf7,0x17,0x81,0x5d,0x7a,0x6c,0x07,0x8c,0x2f,0x3d,0x9a,0x3f,0xce,0x1a,0xb5,0xb3,0xad,0x8e,0xf8,0xd4,0x5c,0xdf,0x2e,0xb4,0x90,0x1c,0x32,0xee,0xa2,0xd5,0xe0,0x18,0xdc,0xf2,0x83,0x3c,0xad,0x0c,},"\x52\x01\xd9\x72\x5f\x1d\xff\xa1\x86\x3f\xa4\xd8\x4c\x30\x18\x61\x14\x1a\xcd\xfb\x64\xbe\x1f\xbf\xdd\x5b\x93\x86\xdb\x20\xef\x39\x40\x99\xee\xbc\xfd\xfe\xcc\x62\xc6\x26\x86\x07\xa8\x4d\x55\xc5\x5c\xd0\xef\xdc\x37\x2e\xcf\x30\x67\x34\x3e\x7b\x07\x31\xc2\x68\x54\x61\xe2\x4b\x95\x3f\x99\x94\x9e\x59\xba\x3e\x67\xed\x0f\x08\x48\x31\x37\x93\x96\x2a\x29\x2c\x45\x98\x14\xc5\xe2\x86\x90\xec\x1f\x45\x17\x1f\x1a\xba\xb8\x6f\xdd\x14\x56\x8b\x00\xca\xf4\x85\x81\x11\x5e\xe5\xea\x83\xb0\x00\x28\x2f\xbb\xf0\xc0\xb2\xa1\x11\x60\x39\xa3\x5c\xfa\x3f\x20\x14\x22\x20\x7a\x3d\x49\x48"}, +{{0x7b,0x04,0xac,0xa7,0xcf,0x92,0x62,0x16,0xcb,0x96,0x0a,0x38,0x90,0x78,0x63,0x39,0xd0,0xa6,0x15,0x96,0x76,0x80,0x19,0x01,0x23,0xfd,0xa3,0xb6,0x0c,0x6a,0xeb,0x11,},{0xcd,0xbc,0x3e,0x70,0xe4,0xe8,0xfd,0x13,0xd0,0xcc,0xe2,0x85,0x2a,0x3b,0x93,0x72,0xc3,0xa6,0x16,0x0c,0xd6,0xde,0xab,0xa9,0x0f,0x9b,0x30,0x22,0xf7,0x0c,0x91,0xf9,},{0x25,0xd2,0xd3,0x61,0x75,0x1d,0x52,0xb4,0xfe,0x66,0xea,0x18,0xe4,0xb9,0x86,0x6b,0xde,0x3d,0x12,0x1a,0x73,0x12,0xfd,0x9e,0x28,0xa1,0xe2,0x95,0xe0,0x87,0xe3,0x17,0x6c,0x94,0xc8,0x74,0xa2,0xe8,0x16,0x00,0xf2,0x4c,0x46,0x54,0xf4,0x3d,0x1b,0x67,0xd4,0x7b,0x64,0x82,0x26,0x48,0x59,0x0c,0xe5,0xce,0x44,0xf3,0xb5,0xdd,0xc5,0x02,},"\x1c\xb0\x96\x24\xb1\xf1\x4a\x02\x60\xc7\xf5\x6d\x8c\x60\xb5\xfe\x45\x83\x71\x14\x23\x25\x51\xef\x59\x66\x38\x6e\x0c\x2b\x44\x1b\x75\xcf\xdb\x8d\xf2\x18\x57\x85\xd2\x2c\xf5\x26\xfa\x9d\xf7\xfd\x45\xd9\xd8\x38\x81\xb6\x6c\x1f\xee\xe0\x91\x3e\x23\x81\x21\xee\xdb\xb7\xab\x50\x4d\xa0\xbe\xe8\x99\x80\x16\x68\x45\x35\x03\x19\x91\xf1\x1b\xfc\xd9\xb9\x56\x90\xaa\xd2\xd1\x9b\xd6\xa9\xde\x18\x44\xed\x13\x62\x30\x2d\xf4\x21\x72\x30\xb2\x5c\x05\x52\xce\x27\x75\x34\xc6\x50\xca\xe5\x26\x57\x7f\x25\xd8\xb1\xfe\x9f\x9f\xeb\xca\x2c\x81\x46\x70\xd4\x80\x5b\x21\xad\xef\x85\x2d\xaf\x94"}, +{{0xea,0x73,0xbf,0x64,0xa1,0xa9,0x78,0x77,0xc3,0xc3,0xe7,0xca,0x46,0x44,0xb7,0x1a,0xaa,0x66,0x31,0x4c,0x8f,0x1b,0x66,0xba,0xfa,0xeb,0xd5,0xed,0xfb,0x88,0x8b,0xcd,},{0xca,0xac,0x93,0x90,0x2e,0x57,0x64,0xad,0xe4,0x72,0x94,0xed,0xd5,0x1f,0xaa,0x14,0x62,0x09,0x40,0xc6,0x68,0xb5,0xc1,0xc3,0x92,0xa6,0x92,0x83,0x25,0xd4,0xc3,0xfd,},{0xbd,0x86,0xcb,0x9c,0x70,0xa0,0x55,0x27,0x9a,0x86,0xa9,0xe6,0x48,0x70,0x98,0x8b,0x8a,0x73,0x45,0xc3,0xcd,0x29,0x48,0xa0,0xfa,0xbc,0xfb,0x38,0xab,0xce,0x3c,0x42,0x0b,0x4d,0x55,0x21,0x61,0x8e,0x11,0xd2,0xde,0x82,0x7d,0x9d,0xe5,0x69,0xf6,0xbc,0x3b,0xe6,0x6a,0xad,0x40,0x63,0x6c,0xda,0xa6,0x47,0x60,0xde,0xd3,0xb7,0xc2,0x09,},"\x36\x2e\xec\x68\xb9\x12\x85\x27\x86\xbb\x4f\x9a\xff\xf9\xec\xf7\xcb\x28\xc9\xde\x6b\x18\x42\x2a\x8c\xa9\x40\xb0\xd7\xe6\xdc\xb8\x3a\xa4\x4b\xe0\xaf\xb5\xf1\x80\x6d\x43\xf0\xe3\x1d\x71\xf9\x22\xf8\x53\x61\x5a\x26\xe2\x87\xa2\x7f\x08\xa0\x4f\xbc\xe3\xd4\x5a\x0c\x6c\x31\x1d\x4b\x7c\xb1\x7e\x42\x5b\xbe\xb0\xa6\xb4\x10\xb5\xd6\xdb\xb7\xac\x11\xdf\x98\x50\xa1\x31\xa6\x91\xe3\xb6\x0b\x0b\x21\x4e\xbe\x04\x41\x06\xe9\x82\x43\x32\x87\x59\x52\x67\xb0\x31\xb5\xd4\xa0\x92\x62\xde\xd8\x93\x4f\xdf\xdf\x96\x4d\x86\x8e\xf9\xa2\xc8\x42\xf8\x04\xea\xfd\xde\xfc\xb7\x1d\x9f\x16\xa5\x9b\xf8"}, +{{0xb8,0x12,0x3c,0x11,0x6b,0x33,0xba,0xd0,0xdc,0xbc,0x2c,0x4d,0xc0,0x6a,0x3d,0x66,0x85,0x0d,0xab,0x36,0x0c,0xdb,0x5a,0x03,0x3c,0x14,0x89,0x5c,0x4e,0xe3,0x1b,0xfb,},{0xbd,0xca,0x15,0x1b,0xa3,0x2c,0x6b,0xb3,0x15,0x31,0xb0,0x5f,0xdf,0x86,0xc6,0xd7,0x8c,0x8c,0xd1,0x93,0x56,0x11,0xd5,0xff,0x11,0x1a,0x0f,0x00,0x63,0x5b,0x18,0x85,},{0x9c,0xf1,0x3e,0xba,0x3d,0xcc,0x37,0xb8,0xfc,0x70,0xcc,0xb2,0x32,0x74,0x36,0xb9,0xf0,0x88,0x55,0xe7,0x26,0xaa,0x7e,0xd8,0x2b,0xd5,0xcb,0x7d,0xf4,0x5f,0xdf,0x9e,0xc1,0xf9,0x6a,0xfa,0xd1,0x93,0xf4,0x75,0x72,0xd7,0x70,0x44,0x4b,0x65,0xb7,0x4a,0x37,0xcc,0x03,0x4f,0xc5,0x14,0xcb,0x3f,0x91,0xb2,0xd8,0xad,0xa5,0xb0,0x20,0x06,},"\x79\x70\xf6\x66\x66\x34\x54\x8c\x84\x8b\xb5\x23\x38\x81\x7b\x26\xa4\xd0\xca\x68\xdf\x3d\x28\xaf\xff\x20\x7c\x2d\x02\x80\x67\xa1\x8e\x4c\x95\x43\x02\x5f\x5b\x02\x28\xaa\x69\x1e\x50\x88\x51\x31\x51\xa9\x44\x94\xe1\x5d\x1f\x54\x21\x03\x28\xe0\xdf\x15\x9b\x35\x2c\x30\xaa\xa7\xa8\x44\xf1\x8a\x9f\x4c\x39\x5d\xcb\xb3\xfb\x9f\xcf\xbe\xd1\x10\x3e\x07\x06\xfb\xf9\xc3\x5f\xe2\x66\x68\x48\xfa\x35\xdc\x2c\xf5\x22\x7e\xbe\xe8\x9e\x7d\x3b\xcf\xae\x27\x21\xb2\x5f\xde\xc3\xd3\x17\x4e\xa7\xce\x26\x7a\x55\xdd\x61\xd5\x82\x01\xe9\x6b\xda\x30\x3c\xf4\x18\xed\xf6\xe3\x2f\xb9\x2f\x5d\xc1\xa0\xb1"}, +{{0xb1,0x8e,0x1d,0x00,0x45,0x99,0x5e,0xc3,0xd0,0x10,0xc3,0x87,0xcc,0xfe,0xb9,0x84,0xd7,0x83,0xaf,0x8f,0xbb,0x0f,0x40,0xfa,0x7d,0xb1,0x26,0xd8,0x89,0xf6,0xda,0xdd,},{0x77,0xf4,0x8b,0x59,0xca,0xed,0xa7,0x77,0x51,0xed,0x13,0x8b,0x0e,0xc6,0x67,0xff,0x50,0xf8,0x76,0x8c,0x25,0xd4,0x83,0x09,0xa8,0xf3,0x86,0xa2,0xba,0xd1,0x87,0xfb,},{0x6b,0xd7,0x10,0xa3,0x68,0xc1,0x24,0x99,0x23,0xfc,0x7a,0x16,0x10,0x74,0x74,0x03,0x04,0x0f,0x0c,0xc3,0x08,0x15,0xa0,0x0f,0x9f,0xf5,0x48,0xa8,0x96,0xbb,0xda,0x0b,0x4e,0xb2,0xca,0x19,0xeb,0xcf,0x91,0x7f,0x0f,0x34,0x20,0x0a,0x9e,0xdb,0xad,0x39,0x01,0xb6,0x4a,0xb0,0x9c,0xc5,0xef,0x7b,0x9b,0xcc,0x3c,0x40,0xc0,0xff,0x75,0x09,},"\x91\x6c\x7d\x1d\x26\x8f\xc0\xe7\x7c\x1b\xef\x23\x84\x32\x57\x3c\x39\xbe\x57\x7b\xbe\xa0\x99\x89\x36\xad\xd2\xb5\x0a\x65\x31\x71\xce\x18\xa5\x42\xb0\xb7\xf9\x6c\x16\x91\xa3\xbe\x60\x31\x52\x28\x94\xa8\x63\x41\x83\xed\xa3\x87\x98\xa0\xc5\xd5\xd7\x9f\xbd\x01\xdd\x04\xa8\x64\x6d\x71\x87\x3b\x77\xb2\x21\x99\x8a\x81\x92\x2d\x81\x05\xf8\x92\x31\x63\x69\xd5\x22\x4c\x99\x83\x37\x2d\x23\x13\xc6\xb1\xf4\x55\x6e\xa2\x6b\xa4\x9d\x46\xe8\xb5\x61\xe0\xfc\x76\x63\x3a\xc9\x76\x6e\x68\xe2\x1f\xba\x7e\xdc\xa9\x3c\x4c\x74\x60\x37\x6d\x7f\x3a\xc2\x2f\xf3\x72\xc1\x8f\x61\x3f\x2a\xe2\xe8\x56\xaf\x40"}, +{{0x93,0x64,0x9c,0x63,0x91,0x0b,0x35,0x71,0x8e,0x48,0xc5,0x90,0xd2,0x61,0xc4,0x8e,0x4e,0xf8,0x33,0x66,0x13,0xf6,0xaa,0x07,0x7b,0x46,0x26,0x76,0xb3,0xba,0x88,0x29,},{0x06,0xa6,0x85,0x89,0x8b,0x85,0x52,0x12,0xeb,0xc2,0x89,0x91,0x5d,0x10,0x5a,0x43,0x20,0xd6,0x20,0xd8,0x57,0x71,0xb8,0xc6,0xb1,0x5b,0xf1,0x0a,0x1b,0xe6,0xe9,0xb8,},{0x62,0x74,0xf2,0xd4,0xf4,0x31,0xd5,0xaf,0xfe,0xfa,0x35,0xe7,0xcf,0x58,0x4a,0x59,0x90,0x17,0x19,0x3d,0xa9,0x90,0x94,0xca,0x90,0x8b,0x75,0xac,0xb6,0x08,0xd1,0xbf,0x98,0x18,0x57,0xbe,0x93,0xa7,0xda,0xfb,0x0f,0xad,0xb3,0xff,0x09,0x06,0xf4,0x8a,0x5e,0xe9,0x50,0x45,0x6f,0x78,0x2c,0x2d,0x60,0x5b,0x14,0x09,0x5b,0xa0,0xff,0x0f,},"\x2c\xd1\xa9\x51\x05\x6c\x9e\xba\xe1\x39\x9b\x6b\xd2\xd8\x2c\x0a\xe2\x77\x85\x62\x90\xd0\x69\x20\xac\x56\xca\xc8\xfb\x42\x43\x51\x01\xc7\x2a\xa9\xc0\x8d\xd2\xd1\x24\x26\x32\x55\x62\xc2\xf0\xa4\x9c\xd8\x21\xb1\x1b\x93\x9a\xaf\xa5\x93\xb4\x09\x5c\x02\x1b\xcb\x48\x27\xb1\x07\xb9\x66\x4d\x68\x28\x28\x88\xbc\x4a\x44\xaf\x3e\x3b\xdc\x86\x1b\xe6\xaf\x30\x90\x44\xc3\xda\xab\x57\xb7\x70\x23\xdc\x90\x2d\x47\xeb\xc3\x26\xf9\xbd\xd0\x2d\xbc\x02\xcd\x54\x0f\xf8\x1b\x2d\xdf\x7c\xf6\x79\xa4\x11\x93\xdf\xe5\xf8\xc8\xca\x1a\xae\xfc\x41\xef\x74\x02\x80\xd9\x82\x3e\x30\xa3\x54\x71\x7c\x84\x31\xf5\xd8"}, +{{0x1c,0x15,0xcb,0xeb,0x89,0x36,0x2d,0x69,0x47,0x6a,0x2a,0xa4,0xa5,0xf3,0xef,0x20,0x89,0xcf,0x87,0x28,0x63,0x49,0xe0,0xdf,0xe0,0xe7,0x2d,0x9e,0x3e,0x5a,0x66,0xc7,},{0x13,0xa8,0x82,0xa1,0x06,0x41,0x82,0x58,0x2c,0x21,0x18,0x47,0xe1,0x9b,0x4d,0xac,0x59,0x72,0x2c,0x9f,0xfd,0x34,0x82,0x6d,0x96,0xf3,0x31,0x13,0x40,0x0f,0xac,0x7a,},{0x59,0x98,0xb2,0x80,0x8a,0xdf,0xde,0xea,0xeb,0xe2,0xc3,0xea,0xc0,0x26,0xd3,0xf8,0x25,0xf9,0xc7,0xf2,0xaf,0x97,0xca,0x32,0x4f,0xbd,0x57,0xaa,0xc1,0xbe,0xdf,0xf7,0x8a,0x8e,0xe6,0x21,0xd0,0x37,0xee,0x3a,0xd2,0xa7,0x12,0xe9,0xa0,0x09,0xc5,0x8e,0xa3,0xe6,0xf2,0xa8,0x28,0xf7,0x4b,0x86,0xda,0x27,0x5a,0x44,0xa4,0xb1,0xe5,0x0b,},"\x09\x1c\x9b\x9b\x11\x6a\xe8\x3d\x23\xd0\x1a\x62\x95\x21\x17\x85\xd4\x46\xb6\x22\x8d\xd6\x87\xdd\xf7\x9b\xd0\xd5\xa4\xda\xa8\xc7\x9d\x2c\xbf\xc3\x73\x65\xf1\xf2\x85\xe3\x61\x73\x81\x23\xe3\x4e\x2b\xcb\xfc\x66\x4c\xe1\x25\x3a\x11\xd9\xe4\xa7\x98\x2e\x58\xcf\x94\x68\xe1\x01\x7e\xa1\x4d\x2c\xc6\xd0\x86\x5d\x40\xfd\xe8\xcb\x56\x02\x41\xe9\x6a\xc1\x61\x7c\x79\x1f\x0c\xa7\xc6\x41\x0c\xad\xf3\x28\x61\x1b\x18\xae\xf3\x33\xd8\x35\x0a\xc4\x97\xf0\xa4\xae\x2d\x03\xfd\xf0\xe2\x3e\x42\x6d\x34\xf4\x51\x47\x80\xd1\x47\x4e\x11\x35\x83\x54\x1f\x3c\x04\x36\x72\x05\x71\x72\x61\x8c\xb2\x05\x9e\xaa\xed\x56"}, +{{0x11,0x24,0x1f,0xfd,0xf3,0x4a,0xe8,0xab,0x87,0x54,0x75,0xe9,0x4c,0x6c,0xc3,0x29,0x1f,0x0b,0x88,0x20,0xdc,0x85,0xe2,0x0f,0x32,0xfc,0x53,0xb2,0x4a,0xe6,0x89,0x78,},{0x09,0xc0,0x45,0xe4,0xbd,0x51,0x37,0x31,0x4c,0x0e,0xc1,0xd0,0x31,0xfa,0xf9,0x14,0x91,0x0c,0x45,0xa4,0x67,0x6f,0x5a,0x3c,0xd8,0xf5,0x81,0xbc,0xcc,0xb0,0x3c,0x97,},{0x72,0xce,0x9f,0x91,0xbe,0x2e,0x66,0xcf,0xc9,0x0f,0x95,0x25,0x95,0x94,0x6f,0xfc,0x90,0xbf,0xce,0x53,0x08,0x7d,0x49,0xe5,0xdd,0x7c,0x08,0x7f,0x3f,0xaa,0x8f,0x18,0xf2,0x35,0x6d,0xe9,0x71,0xe4,0x42,0x9d,0x98,0x5a,0x99,0x19,0x4b,0x4f,0x92,0xce,0xd3,0xef,0x47,0xcd,0x71,0x14,0x37,0x9e,0x0b,0x32,0x67,0xa9,0xf8,0xb1,0xe7,0x06,},"\x3b\x89\xde\xcc\xb7\x02\x3e\x4b\x2b\x7a\xff\x2c\x39\x51\x87\x0a\xf4\x13\xa9\xb0\x4d\xd8\x6a\xc7\x8b\x7c\x8f\xd8\x87\x49\x2d\x8d\xde\x49\xd8\xfd\xa1\x49\xed\xd5\x47\x81\xae\x2b\x50\x80\x30\xd1\x44\x16\xa9\xa3\x8b\xed\x2b\x9a\xeb\xbb\xb2\x02\x50\xb3\xc9\x31\xac\xd4\xe3\x2f\xbe\xee\xc5\xa2\x65\x01\xbe\xab\x72\x68\xd1\x44\xfc\xe8\x95\x1a\x10\x1c\x4b\x51\x78\x16\x6f\xbb\x59\x27\xb1\xdf\xb1\xe1\xce\x90\xd1\xd1\x23\x06\x8e\x3f\x47\x2c\x88\x8f\xdb\x01\xfd\xf7\x0e\x7f\x8d\xe9\xb0\xad\xb2\x84\xb7\x11\x9f\x55\x35\x43\x16\xf8\x4e\xd0\x90\x03\x0f\x9c\x26\x62\x06\x1c\xa4\x84\x47\xcc\x0a\xef\x96\x41\x26"}, +{{0x3b,0xdb,0x16,0x24,0x65,0xea,0xce,0xff,0x98,0xd6,0x9c,0x86,0xf7,0x00,0x39,0xc5,0x17,0xd1,0x68,0xae,0xfe,0x6b,0xb1,0x01,0xb4,0xf7,0x69,0xa8,0x6b,0x17,0xc9,0x72,},{0xd7,0x6c,0xb7,0xbe,0x74,0x32,0x82,0x89,0xfd,0x1c,0x64,0xbe,0x74,0x7c,0xca,0x5b,0xb3,0x02,0x95,0xdf,0xac,0xcd,0x0f,0x2e,0x43,0xf5,0x17,0x03,0xfd,0x5d,0x36,0x83,},{0x6f,0x13,0x62,0xa4,0x02,0x06,0x37,0x91,0xf9,0x50,0x98,0x4f,0x54,0x49,0x28,0xe6,0x16,0xa4,0xef,0x79,0xbb,0xeb,0x68,0x54,0xe9,0x61,0x5a,0xab,0x9c,0xdb,0xae,0xc4,0x83,0xfb,0x9a,0x04,0xbf,0x22,0xde,0x5d,0x97,0xa1,0x5b,0xda,0x2d,0x39,0x04,0x83,0xc7,0xf6,0x1d,0xbe,0xe0,0x7b,0xb5,0x14,0x1f,0xc1,0x73,0xb1,0xaa,0x47,0x65,0x0d,},"\xfb\xf3\x68\xfe\xae\xba\x87\x91\x8b\x1b\x8c\x7b\x8a\x26\x83\x2b\xe6\xe7\xfc\x1c\xbd\xb8\x90\x25\x19\x28\x1a\x06\x54\xec\x73\xde\x0b\xb0\x71\x01\xa9\xd6\x03\xf7\x45\xd4\xec\x23\x57\xae\xe9\x87\x0c\xb1\x9a\x56\xcb\x44\xfb\xd9\xc9\x1f\xc3\x47\x52\x61\x2f\xbd\x83\xd6\xfc\x1a\x16\xbf\x8a\x85\xa2\x15\xd0\x14\x8e\x4a\xf3\x7d\x29\x84\x67\xe5\xcc\x48\x6b\x13\x13\x52\xce\x09\x21\x82\xce\x82\x84\x15\x9a\x38\x12\xb3\x0b\xac\xbf\xf5\x95\x86\x38\x11\xbf\x9a\x30\xa9\xda\x49\x45\x65\xc3\xac\x18\x14\x43\x00\x18\xea\x0e\xee\xd3\x9c\xdb\xca\x27\xf9\x31\x40\xe4\x69\x49\xdb\x57\x0b\xfa\x2e\xd4\xf4\x07\x3f\x88\x33"}, +{{0xd5,0xef,0xe5,0x1d,0x5c,0xd8,0xe1,0x08,0xbd,0x92,0x2f,0xc0,0xea,0x12,0x61,0x90,0xa9,0x46,0x28,0xff,0xa5,0x3c,0x43,0x3a,0x51,0x80,0x22,0x79,0x2d,0xdc,0x78,0xef,},{0x42,0x6b,0x01,0xcc,0x61,0xff,0x5e,0x0e,0x72,0x4d,0xa1,0xd3,0xb2,0x97,0xf5,0x32,0x5c,0x18,0xc6,0x2f,0x64,0xd5,0xeb,0x48,0xd4,0xa5,0x21,0x6a,0x8e,0x9a,0x40,0x73,},{0x23,0x06,0xf5,0x8f,0xcd,0x4c,0xff,0x22,0x22,0xd8,0x1b,0x05,0xa4,0x75,0x53,0x2b,0x8b,0x19,0xdc,0x67,0xe6,0xd7,0x8d,0xdb,0x42,0x05,0xa3,0xb7,0x62,0x1c,0xc5,0xae,0xf0,0xb3,0x93,0xd5,0xd2,0x4d,0xd9,0x6c,0x88,0xcc,0xbc,0x53,0xa3,0x20,0x8d,0xa3,0x23,0xbe,0x45,0x87,0xd5,0xec,0x06,0x7c,0x82,0x0f,0x07,0x23,0xaa,0x44,0xe9,0x0e,},"\x9d\x17\xbc\xfe\x2d\xfc\x74\x2f\x41\x1c\xb5\x3a\x94\xf3\x59\xc0\x01\xab\xf0\x96\xc7\x41\xf3\x4a\xf4\x86\x79\xf2\x81\xe7\xce\x6b\xbd\x9e\x87\x70\x9f\xc0\x72\x8a\x56\x3d\xb2\xb9\xcf\x8e\xa4\xfb\xdc\xc3\x44\xc1\x84\x8e\x65\x3c\xe9\x70\xc6\xce\x29\xde\x2c\xcd\x52\x03\x00\x64\x9a\xdc\xdd\xfc\x75\x39\x71\xf8\x46\xaa\xc1\xba\x42\xae\x45\x28\x95\x2d\x94\x98\x0a\xa7\xc6\xcf\xa2\x14\x29\x07\x64\x7f\x89\x4a\xe9\x74\xa7\x4d\x59\x03\x5a\x73\xef\x56\xa1\x0b\x66\x12\x62\x48\x09\x52\x01\x90\xac\xe6\x61\xc3\xa4\x70\x95\xe0\x32\x2e\xfd\x78\x1d\x50\xd1\x16\x35\x98\xf2\xda\x32\xf3\x1b\xc9\xc4\xf9\x13\xd1\xb1\x48\x61"}, +{{0x18,0xaf,0x89,0x02,0x5e,0xbf,0xa7,0x6b,0xd5,0x57,0xcf,0xb2,0xdf,0xf1,0x48,0x24,0x52,0x14,0x64,0x1f,0xd5,0xbd,0xa1,0x59,0xf7,0x3d,0xa0,0x4b,0x08,0xe8,0x7c,0x88,},{0x0c,0x58,0x44,0x59,0xb9,0xeb,0xcc,0xca,0xd5,0x87,0xb2,0x72,0x16,0x0b,0xc6,0x0b,0x27,0xf4,0xf7,0x72,0xb4,0x32,0x1d,0xe7,0x72,0x3a,0xfe,0xf5,0x77,0xed,0xc7,0xb4,},{0x26,0xbb,0x08,0x82,0x29,0x7c,0x2c,0x08,0xa7,0x52,0xd3,0x98,0x11,0x45,0xdc,0xde,0x55,0x89,0x3a,0x11,0xdf,0x77,0xf8,0xaa,0x4c,0x19,0xd0,0xb9,0xed,0x6e,0x52,0x20,0xed,0x12,0xe9,0xfa,0xc3,0xaf,0x13,0xd0,0xf0,0xc7,0x15,0x68,0xf4,0xa5,0x47,0xd3,0x01,0x14,0xa6,0x59,0x9a,0x23,0x68,0x06,0xc4,0xbe,0xee,0x67,0x65,0x28,0x44,0x08,},"\xe8\x2f\x46\x65\x2a\xb9\x14\xaf\x53\x5d\x8f\xb7\x20\xb5\x57\xac\x95\x01\x8d\x9f\x2a\x3f\xcc\xe8\x57\x71\xbb\x40\xab\x14\xcb\x9a\x98\x6e\x09\x6f\x3a\xfe\x5b\xee\x82\x9d\xfd\x8b\x97\x33\x5c\x53\x6a\xc9\x71\xa2\x16\x55\xaf\x16\xa2\xf8\xfd\xba\x18\x3a\x4e\x18\x56\x4c\x21\x49\x29\x56\x53\x7a\x41\x9a\xbb\xbb\xb0\x2a\x4b\xbd\xc0\x14\x81\xf5\xc6\xe6\x58\xec\xf3\xc3\x4f\x01\x1a\xd8\x46\xf5\xed\xcd\x49\x39\x19\x5d\xf8\x5e\x41\x30\x3f\xb9\xa8\x8f\xdf\xbd\x70\x43\x96\xf7\x55\x9a\x32\x73\x18\xb9\x52\xb3\xe6\x0c\xe8\xdd\xde\x56\x37\x85\x79\x23\x2f\xaf\x95\x0c\x78\xe7\xf0\xb1\x7c\x3b\x8d\xec\xe3\x6b\x78\x8a\x84\x73"}, +{{0x0c,0x93,0xd9,0x98,0x15,0xff,0xf8,0xfe,0x22,0xb9,0xe4,0x5a,0xa0,0x2b,0x3e,0x64,0x45,0xce,0x1d,0x6b,0xf5,0xa6,0x5d,0xce,0x3d,0xa1,0x07,0xaa,0x10,0x55,0x94,0x0e,},{0x4d,0x27,0xa4,0x7b,0x0f,0xc8,0x08,0x00,0xd8,0x4d,0x24,0x4e,0xeb,0xb1,0xde,0xb4,0x43,0x6d,0x97,0x63,0x3a,0x83,0xe6,0x71,0x25,0xad,0x52,0xea,0x01,0x68,0x50,0x57,},{0x7d,0xc4,0x46,0x7a,0xbc,0xf6,0x43,0x1a,0xdb,0x7c,0xcf,0xe8,0x68,0xea,0xc8,0xcd,0x8a,0x61,0x5a,0x0f,0xf6,0x5f,0x6a,0x9e,0x33,0x83,0x75,0xb1,0xaa,0xe3,0xc4,0x9a,0x12,0x6c,0x9e,0xba,0x79,0x42,0x6d,0x16,0x41,0xc6,0xb9,0x7c,0x3e,0x92,0xc1,0x94,0xe5,0xee,0x44,0x31,0xef,0xa2,0x43,0x9f,0xd4,0x50,0xf2,0xcd,0x01,0x8c,0x87,0x00,},"\x11\xe8\x77\xde\x58\xc1\x34\xea\xf4\xc9\xf1\xb5\x3c\x3d\xc4\x51\xd3\xc0\x55\xf1\x6b\x09\x62\x27\x25\xb2\x79\x76\x85\x12\xfe\x10\xa7\xad\xb0\x76\x5b\x68\x9e\xc2\x1d\x5b\x6e\xfa\xa1\x9f\x1b\x9d\x36\x25\x4d\xf0\xa9\x36\x7f\x44\x1b\x26\xbd\xb9\x0b\x28\xcb\xc4\x03\xe5\x07\x40\x82\xfa\x1f\xed\x58\xe1\x40\xda\xc9\x7a\xea\xf4\x83\xe2\xc1\x3f\x3c\xc5\x60\xab\xff\xab\xa0\x5b\x76\x3f\xee\xdb\x51\xe6\x06\x98\x15\x1c\xf5\x6e\xfd\xf1\xd3\x7d\x6c\xe0\x56\x44\x86\x21\x0f\x05\x2e\x93\x7f\x2e\xa2\x6f\x63\xef\xa5\xd2\x47\xff\x18\x83\x29\xbb\x1a\xa8\x3c\xe3\xf4\xf3\x5a\x3d\x7d\xec\x14\x59\x9e\x5f\xeb\x7b\x6d\x5f\xe4\x29\x6a"}, +{{0x98,0x9e,0x99,0x94,0x56,0x35,0x19,0x2c,0x02,0x3c,0xc5,0x18,0x6f,0xc2,0x5b,0xba,0xef,0x47,0x24,0x07,0x75,0xd1,0x5a,0x56,0x19,0x5d,0x88,0xcd,0x07,0xc3,0x74,0x8e,},{0xca,0x0b,0xea,0xfd,0xf7,0x31,0xd8,0x93,0x01,0xf7,0x72,0x3c,0x5b,0xb7,0xe5,0xa1,0xc3,0xff,0x3e,0xab,0x27,0xc9,0x7d,0x71,0x1b,0xcd,0x76,0xe4,0x20,0x54,0xbe,0xe4,},{0xae,0xf7,0x56,0xbf,0xb8,0xa7,0x26,0x6e,0x17,0xd1,0x5f,0x3f,0x11,0xee,0x50,0xed,0x25,0xbe,0x42,0x0e,0x95,0xa0,0x74,0x22,0x71,0xeb,0xd1,0x22,0x94,0xe2,0xcb,0x96,0xea,0xd0,0x83,0xb8,0xff,0x0b,0x82,0x9d,0x2e,0xde,0xb1,0x4d,0xa8,0x6e,0x40,0x2e,0xf2,0x5e,0x6d,0x4a,0x5a,0x79,0x58,0xc1,0x84,0xed,0x10,0xc1,0x76,0xcb,0x57,0x0b,},"\xc4\x84\x14\xf5\xc7\x57\xd0\x3c\x52\x3e\xf3\xf3\xb8\x51\x07\x71\xb0\xff\x3b\x4b\x97\xde\x27\x96\x25\xd3\x49\xec\x18\x5a\x29\x92\x7a\x66\xb9\x59\x3b\xa1\x93\x38\xc2\xf5\xe4\x13\x1f\x1a\xc0\x7e\xa4\x6d\x2c\x1b\x6e\x4a\xb5\x22\x92\x80\xb2\xe2\xbb\x9d\x14\x0d\x1e\xf7\xaf\x7b\x16\x92\xbf\x2d\x09\x7b\x80\xf8\x11\xad\xcf\xa9\x5d\x5c\xbf\x9e\xee\x92\xa1\x64\x1c\x55\x2b\x4b\xe4\xa0\xd7\x34\xf0\xaf\xd4\x70\xb9\xd7\xf4\xe4\x57\x78\x95\x1e\x21\xfc\x53\x4f\x20\x0a\x12\x8b\x96\xad\xb8\x37\x3f\x10\xce\xce\xc2\xda\xc2\x99\x6a\x06\x2f\xb3\xc2\x94\x31\x59\x65\xa9\xd5\xd7\xb0\x77\xc4\xb0\x13\xc6\x4a\x38\x42\x97\x69\xd2\x3e\xab"}, +{{0x6b,0xdb,0xbe,0x06,0xd9,0xf4,0x21,0x9e,0xea,0x64,0x03,0xa3,0x57,0xb2,0x5e,0x56,0x19,0x92,0xfa,0xe0,0xf0,0xf6,0x14,0x56,0x1d,0xd8,0x6d,0x23,0xde,0x41,0x5a,0x43,},{0xed,0x52,0xdd,0x1c,0xce,0x32,0xd9,0xb4,0x85,0xe0,0x94,0x07,0x46,0x42,0x1d,0x36,0xb9,0xfd,0xe6,0xcd,0xf0,0x21,0x15,0x45,0xb6,0x34,0x04,0x4d,0x4b,0x3c,0xb8,0xf1,},{0x95,0x02,0x06,0x60,0x5b,0x0f,0x41,0x7c,0x90,0x84,0x3e,0x2c,0x8d,0x8e,0x66,0xc8,0x28,0xbb,0x10,0xb9,0x9b,0x36,0xee,0xee,0xe8,0xca,0xf2,0xe0,0xe5,0x48,0x4d,0x93,0xfe,0x02,0xbf,0x53,0x34,0x05,0xf4,0xbb,0x74,0xa5,0x0e,0x55,0x85,0xfa,0x0d,0xae,0xf4,0x82,0x1f,0x03,0x01,0xd0,0x1b,0x46,0x32,0x1b,0xaa,0x31,0xe1,0xf0,0x8d,0x03,},"\x58\x2a\xda\x13\xd6\x92\x93\xe4\x9b\xbd\x46\x10\x32\xdf\xea\x1c\xa2\x02\x5b\x52\xe0\x13\xa3\x3a\x03\x87\xfc\xfc\x5f\x7c\x0b\x8e\xc9\x55\x98\x26\x07\xfc\x90\x1e\x1b\x7f\x63\x6a\x9d\x37\x1e\x1f\x91\xfe\x47\x6b\xdd\x44\x85\x6e\x27\x5d\x67\xef\xa1\x42\x38\x16\x43\x54\xc2\x31\x12\x4c\x84\xde\x8f\x5b\x89\xd5\xa5\x8e\xa6\x74\x4b\x4d\x3b\x3d\x79\x06\x90\x52\x33\xcc\xe6\x94\xa6\x4d\x69\x6f\x5a\x70\x24\xfc\x90\x33\xb1\xce\x39\x08\x99\xa3\xb4\x41\xa4\x8e\x53\xc7\xc9\xb3\x0b\xa1\x2e\x7d\x61\xf3\x5f\x15\xe6\x58\xc7\xcc\x44\x07\xe2\xf6\x89\xea\x8a\x55\xd0\x1b\xf5\xdb\xac\xb1\x19\x54\x75\x4f\x92\x0f\x09\xdb\xd4\x84\x09\xbb\xb5"}, +{{0xd7,0x61,0xc8,0xc5,0xa9,0x60,0x1b,0x91,0x45,0xb7,0xd0,0x51,0x24,0x9b,0x00,0x41,0x07,0xe4,0x52,0xe5,0x63,0x10,0x0c,0x6c,0x78,0x80,0x38,0xc9,0xee,0x8a,0xda,0xd7,},{0xe6,0x48,0x87,0x75,0xd6,0x40,0x7e,0xfc,0x7b,0x2b,0xca,0x89,0x0a,0x7f,0xc6,0x22,0x66,0xfc,0x54,0xcd,0xac,0x89,0x33,0x43,0xb4,0xf5,0x9a,0x19,0x6d,0x94,0x88,0x98,},{0x7a,0xb7,0x8b,0x64,0xe6,0xdb,0x35,0x9a,0x2d,0xc8,0x30,0x2e,0x10,0x92,0xed,0x66,0xfa,0x73,0x6b,0x53,0x62,0x53,0xa1,0xcd,0x90,0xfd,0xb8,0xc1,0x0e,0xfd,0x78,0x30,0x02,0x25,0xe1,0x91,0x96,0x35,0x99,0xba,0x54,0x9c,0xc8,0x59,0x20,0x9d,0xf0,0xff,0x61,0xcd,0x06,0x9b,0x03,0xd2,0x54,0xe6,0xe7,0xd7,0x6c,0x79,0x84,0x40,0xf9,0x07,},"\x84\xea\xd5\xea\xbd\x2f\xd4\xb7\xc7\x9a\x9a\x92\x8a\xb8\xee\x0a\x16\xa5\xfd\x66\x7a\x05\x7f\x8a\x25\x46\x63\xd5\x6d\xaa\xe1\x56\xd1\xa4\x9a\xff\xb2\x99\x61\x37\xb9\xd8\xb3\x40\xe6\x35\x73\x2f\x9d\x2b\x4c\x60\x21\x84\x42\x54\x1e\x72\xd2\xb0\x0e\x1e\xe7\xa7\x3c\x3f\x67\xca\xa4\x99\xfa\x9d\x07\x0b\x57\xd0\x76\xdc\xde\x96\xb0\x76\x47\x23\xc3\xc6\x59\xc7\xa0\x0c\x1b\x78\xb1\x5c\xcc\x22\x23\x89\x0b\x51\x06\x7f\xc8\x1e\x23\xe9\x45\x8a\xb0\x68\x3b\xa6\x26\xa5\x3d\x0c\x37\x93\xa5\x8a\x98\x57\xbb\x44\xb3\xbd\x85\xbb\x6c\xe5\x3a\x85\x69\x4e\x7f\x53\xcc\x1b\xd4\x6d\x50\xed\xa3\x7d\x81\xf5\x38\x1b\x51\x3d\x1f\x38\x33\x9d\x29\x1b"}, +{{0xc5,0xe0,0xc7,0xa7,0xbb,0x8b,0x7c,0xa0,0x7b,0xf0,0xa0,0x5e,0xa6,0x7e,0xff,0x6d,0xee,0xbf,0xe3,0x71,0x4e,0xe3,0xe1,0xa2,0x27,0xf4,0xdc,0x8e,0x24,0x2a,0x2f,0xa0,},{0x51,0x35,0xef,0xcd,0x90,0x52,0xbe,0xc5,0x7a,0x44,0x31,0xca,0xab,0xe8,0x26,0x80,0xee,0xc0,0xa3,0x3a,0xfd,0x59,0xb3,0x02,0x03,0xb2,0x80,0xba,0x12,0xbe,0x48,0x5c,},{0x2e,0x7f,0xde,0xb3,0x48,0x4d,0x0a,0x5e,0x8d,0xce,0x94,0x44,0x89,0x79,0x49,0x6b,0x06,0x42,0xca,0xbc,0x37,0x33,0xa5,0x1f,0x8c,0x3c,0x5c,0x51,0xc1,0x9a,0xe3,0x19,0x01,0x8d,0xa9,0x10,0x91,0xc2,0x38,0x5f,0x2f,0x4e,0x9a,0x59,0xed,0xbc,0xa2,0xab,0xd0,0xd0,0x85,0xee,0x40,0xd3,0xf0,0xd4,0x20,0x61,0xa5,0xa9,0x83,0x2a,0x37,0x0c,},"\x37\x70\xa6\x78\x66\x52\xc4\xb7\x8a\x04\x3e\xdc\xe0\x7f\x3e\x20\x4d\x81\x99\x7c\x42\xaf\xc2\x23\x31\xf7\x5a\x54\x94\xa8\x26\xd7\xcb\x69\xab\x43\x14\xa4\x73\x72\x10\x58\xa1\x83\x99\x81\xd5\xb7\x02\x2d\x0c\xd8\x67\x03\x77\xda\xf3\x32\x04\x76\xd2\x5b\x9f\x55\x95\x61\xd6\x6e\xe0\xa7\x09\xfe\x17\x36\x1e\x2a\x52\x89\x8f\x57\x53\xc4\xfb\x43\xbd\x0c\x98\xb3\x68\xf5\x12\xad\xc0\x9c\xd9\x27\xc6\x62\x26\x76\x92\x6d\x8c\x2d\x91\xa1\x4a\xca\x32\xf2\x26\xf7\x00\x36\xc1\xc8\x58\xbc\xff\xc2\xb5\x9f\x54\xc1\xc3\x7b\xf8\x1e\xb5\x2e\xcb\x3f\x00\xda\x60\x2c\x94\x36\x1b\x52\xa5\xaf\xdd\xbf\xd7\xe0\x50\x36\xe3\x77\x50\x30\x50\x33\x3b\xe5\x12"}, +{{0x11,0xbb,0x47,0x48,0xd2,0x54,0x7e,0x61,0x96,0xbe,0x82,0x3c,0x9b,0xe7,0xaa,0x18,0x15,0x0c,0x20,0x4b,0x12,0xca,0x8d,0x73,0xc1,0xbd,0x46,0xb1,0x1a,0x54,0xb4,0x75,},{0xef,0xeb,0x42,0xda,0x28,0xd7,0x64,0x96,0x64,0x03,0xdd,0x30,0x0d,0x9f,0x94,0x51,0xb2,0x58,0xab,0x1c,0x80,0xdf,0x06,0xfe,0x59,0x43,0x15,0x3f,0x53,0x01,0xcc,0xcb,},{0x44,0xc5,0x8d,0xa4,0x9d,0x23,0x65,0xd2,0x70,0x29,0xd1,0xee,0xbb,0x3b,0xeb,0xf7,0xc0,0x32,0xd8,0x58,0xaa,0x07,0xe0,0x75,0x6b,0x1c,0x26,0xa5,0x41,0x2d,0x22,0x69,0x11,0x76,0x03,0x13,0x41,0xad,0x37,0xd7,0xbb,0x78,0x43,0x28,0x9e,0xb3,0x9d,0xb4,0x91,0x58,0x4c,0x1b,0x2a,0x1d,0xa2,0xe4,0xa2,0x64,0x9c,0x22,0x93,0x82,0x66,0x06,},"\xf4\xb7\x65\xb2\x58\xba\x35\xb4\x27\x52\x5c\x7f\x10\xa4\x6f\x0b\xcc\xd3\x57\xec\x1a\xd5\x2a\x5b\x13\x94\x17\xa9\xd3\x89\x4c\x51\x2d\x89\xeb\x88\xe6\x81\xb1\xf3\x0a\xac\x4c\x11\x5c\xcf\x36\x54\x5e\x83\xf3\x78\x34\xc8\x2e\x83\x00\xcc\x1e\xb2\x89\xaf\x43\x75\x96\x8c\x29\xc0\xff\xef\xb4\x0e\x15\x6c\x20\xc0\x43\x26\x69\xac\x8d\xc0\xa8\x3c\x13\xb1\xe8\x55\xa8\x4a\xd0\x13\x3c\x40\xc8\x2c\x87\xee\x1e\x7d\xd4\x08\x4d\x74\x1c\x80\xde\x8a\x7a\x9f\x77\x59\xe8\x43\xa5\x62\x09\x9c\x4d\x7d\xf8\x75\x35\x20\x39\xff\x4d\x38\x24\x65\x13\x86\xc9\x77\x59\xff\x7d\xba\x52\x06\x4e\x6d\x31\x12\xe0\x80\x81\x9a\xee\x8c\xe7\x23\xa1\xa2\xaa\x46\x4d\x8a"}, +{{0x74,0x52,0xa0,0x01,0x56,0xd7,0x94,0xed,0xeb,0xff,0x4a,0xdb,0x1f,0x7a,0x7e,0xec,0x26,0x21,0x7f,0xef,0x67,0xc3,0xd2,0x68,0x35,0x2b,0x2b,0x54,0x60,0xa7,0xdc,0x25,},{0x5f,0x4d,0xc3,0x38,0xcf,0xbd,0x38,0x4b,0x5f,0x1c,0x14,0xc2,0x26,0x70,0x14,0x46,0xb5,0x2b,0x1e,0x3e,0x2a,0x3c,0xba,0x1a,0x40,0xee,0x28,0x25,0x08,0x0d,0x1d,0xe6,},{0xa8,0xf9,0xfa,0x24,0xa3,0xde,0xa1,0x02,0x2e,0x73,0xf0,0xd8,0x8b,0x1c,0x37,0xd0,0x6d,0x0f,0x0b,0x20,0xbb,0xff,0x0e,0xcd,0xb4,0xa4,0x0c,0x86,0xd7,0xe4,0x75,0x61,0x7c,0x03,0x57,0x0a,0x74,0x19,0xd7,0x4b,0xa0,0xf1,0x32,0x70,0x96,0xbf,0x19,0xf0,0xd0,0xcf,0x9f,0x51,0xd4,0x83,0x11,0x2f,0x26,0x92,0x23,0x78,0x68,0x2f,0x48,0x07,},"\x8c\x4e\xe2\x86\x76\x56\xe3\x3f\x52\x69\x41\x4d\x77\xb4\x2d\x8e\x47\x50\xdb\xa9\x3c\x41\x8b\xac\xca\x10\x93\x8c\xc3\xb5\x70\xc6\x60\x3d\x52\xc2\x34\x44\x88\x60\x7b\x2f\x93\x4f\x6d\x26\x9f\xcb\x2a\xd9\x66\x21\x9b\x1a\xb1\x14\x72\xf4\x2c\x67\x2c\xe2\x05\x92\x49\x0e\xc5\xba\xf6\xa2\xd2\xfc\x8a\x3e\xe3\x53\x74\xb1\x90\x2f\xde\xfc\x78\x70\xb1\xb6\x26\xfa\x46\xb1\x2b\x6c\xee\x24\x1f\x60\x1a\x9b\x3f\xe4\xc5\x08\x12\xe5\x73\xe6\x75\x2c\xe2\xc7\x64\x4e\x33\x67\xa6\xa6\xb7\x77\x58\xd8\xe4\x93\x4b\x58\xaf\x23\xab\xae\x8f\xec\xac\x25\xed\xd7\x34\x03\x0e\xe7\xcf\x39\x90\x7e\x3e\xed\x81\x86\xa1\x9a\x80\x71\x03\xa9\xfc\x49\xd3\x8f\x4c\x84\x60"}, +{{0x88,0x0e,0xf1,0x06,0x73,0x3f,0x04,0xe7,0x61,0x95,0xeb,0xa2,0x80,0xb3,0xfa,0xdd,0xa0,0xf2,0x5d,0xcf,0x96,0xa6,0xa9,0x9c,0x8c,0xcf,0x84,0x2c,0x68,0xaf,0xda,0xe5,},{0x70,0xce,0xe3,0x3d,0x41,0xc7,0x28,0xce,0x7b,0x14,0x19,0x31,0xe6,0xe8,0x52,0x45,0x67,0xd7,0x60,0x1e,0xb7,0x9f,0x67,0xfd,0xcd,0x07,0xb9,0xd6,0x82,0xc6,0x50,0xf0,},{0xff,0x6c,0xae,0xdd,0x8a,0x46,0x8a,0xa0,0x7d,0x4c,0x6e,0x71,0x31,0xbb,0xda,0x76,0x18,0x2b,0xa9,0x58,0x64,0x93,0x76,0xe7,0x11,0xf4,0x4c,0x7b,0xba,0xcb,0xa6,0x07,0x7b,0xea,0x87,0x8b,0xa5,0x94,0x9c,0xde,0xee,0xf0,0x5c,0xfd,0x49,0x83,0xb0,0x05,0x7d,0x27,0x5e,0xa3,0xe1,0x8c,0x32,0x65,0x94,0x68,0xc3,0x0c,0x47,0xac,0x8f,0x0b,},"\xf4\xf3\x8d\x07\x7f\x2b\x03\xda\x82\x1b\xd3\x6f\xde\x67\x3d\x66\x6e\x52\xf4\x83\x2e\x1c\x0d\xcf\xee\xf0\x49\x32\x8a\xcb\x7b\xd7\x1a\xd2\xbf\xc4\x9c\x12\x35\x16\xe1\x96\xc4\x70\xdf\x08\x47\xb3\x84\x8a\x45\xa2\xc6\x9b\xea\x03\xe2\xaf\xa7\xe5\x82\x05\xb6\x3b\x52\x38\x14\xfc\x8e\x24\x2f\x05\x9c\x69\xff\x7e\x40\xf9\x7b\xe8\x12\x5b\x70\xa5\x4f\xda\xf3\x5a\xea\xfa\xc7\x91\x14\xa7\xb4\x19\xe6\xbb\x9e\x70\xbf\x07\xad\xb5\x59\x81\x96\x00\xdc\x25\xe5\x1b\x4b\x70\x0d\x27\xca\x54\x72\xa0\xe7\xcb\xbf\xd1\x4e\x09\x9f\xaa\x3a\x72\x00\x2d\xa5\x38\xcb\xe4\x5d\x62\x1e\xf0\xd5\x25\x2b\xa2\x9d\x83\xf8\xb3\xec\x83\x89\xc9\xce\xb6\xc6\xb2\xe8\xd8\xa2\x0f"}, +{{0xa2,0xd8,0x8f,0x37,0xec,0xc2,0xb2,0xc0,0x5d,0xd6,0xcb,0x31,0x59,0x96,0x2c,0x5f,0x64,0x6a,0x98,0x15,0xb2,0xfb,0x37,0x79,0x1f,0xc7,0xb6,0x06,0xe2,0x91,0x3e,0xd5,},{0x58,0xdd,0x67,0xd7,0xa1,0x5d,0x4c,0xa0,0x34,0x1a,0x4c,0x86,0x95,0x66,0xca,0xd8,0xc4,0xee,0x16,0xe5,0x83,0xa1,0x0b,0x48,0x24,0x17,0x3b,0x08,0x29,0x0d,0x92,0xd1,},{0xcc,0xf2,0x40,0x0c,0xd6,0x73,0xe1,0xef,0xfd,0x20,0x16,0x1d,0x7b,0x68,0xa5,0xfb,0x87,0xc1,0xe9,0x9d,0x36,0x35,0xd7,0x8c,0x2d,0xa1,0xb5,0x09,0xfa,0xc3,0x33,0x46,0xc0,0x69,0x16,0x3a,0x6c,0x46,0xc7,0x82,0x6a,0x48,0xbb,0xbd,0x03,0xb0,0x5e,0x6e,0x23,0x51,0xfa,0x62,0xbf,0x89,0xbf,0x7c,0xcf,0x9a,0x90,0x24,0xbd,0x15,0x7d,0x07,},"\xd1\xb8\x7e\x9e\x88\x6d\xfb\xbd\xc8\xca\x8a\xb9\x01\x0e\xcf\x9b\xba\xf2\x3f\x72\xab\x3c\xbe\x76\x9d\xb1\xd4\x3c\x2a\x47\x4a\x81\x65\x1c\x46\x4e\x9f\xb9\x27\x34\x63\x46\x41\xc9\x48\x5a\x02\x39\xb3\x11\x07\x71\xe7\xf7\x5e\x05\x25\x2e\x4d\x8f\x4c\x0a\xa1\xba\x08\x62\x6d\x7e\x96\x31\x7c\x20\xac\xde\x2a\xd9\x9b\x23\xbd\xad\xfd\x6f\x17\x46\x8e\xb4\x02\xec\x5e\xef\xa5\x7b\x47\xca\xf9\x72\xb3\xdd\x21\xd8\x9f\x0e\x29\x89\xff\x87\xd5\x1e\xd2\xe2\xd6\x39\xc1\x64\x4e\x69\x8c\xbe\x02\x21\xb8\xe1\x79\xf3\xcf\xb0\x4a\x20\xcb\x24\x70\x21\x6a\x68\x82\xfb\x4f\xf7\x99\xe1\x15\x36\xcf\x64\x21\x9f\x0c\x07\x51\x76\xbc\x7c\xf0\xf6\xc5\xb7\x92\x5f\xcd\x61\x55"}, +{{0x42,0xaa,0xfd,0x0a,0xe2,0x6d,0xf1,0xe7,0xaa,0x02,0x76,0x86,0x0d,0x75,0x27,0x83,0xaf,0x97,0x28,0x04,0x39,0xbb,0x23,0xea,0xe4,0x6e,0x3f,0x84,0xca,0xac,0x78,0xde,},{0xda,0xa2,0x35,0x0a,0xdb,0x55,0xdb,0xa9,0xdf,0x7d,0x7a,0xf5,0x10,0x19,0x98,0xfe,0x51,0x5d,0x31,0x1c,0x3c,0xba,0x3e,0xea,0xb9,0x13,0x82,0x33,0x19,0x0c,0x3b,0x4e,},{0x11,0x61,0x43,0x65,0x0b,0x6c,0x13,0x3d,0x61,0x78,0x59,0xdb,0x24,0x29,0xc2,0x91,0x35,0x79,0x79,0x0b,0x21,0x97,0xd7,0xb7,0xb1,0xb4,0x96,0x2b,0x32,0x87,0x21,0x03,0x2c,0xee,0xca,0x58,0xb2,0xd5,0x64,0x39,0xe2,0x33,0xbb,0x84,0xdc,0x52,0x5e,0x28,0x4f,0xf8,0xdf,0x2b,0xde,0x1d,0xb4,0x98,0x6f,0xaf,0xd2,0x1b,0x3d,0x7d,0x6a,0x0a,},"\x72\x13\x1b\x80\xad\x59\x9b\x6f\x5f\xf6\x98\x54\x7d\x16\xe7\x49\x9d\x71\x27\x5e\x4e\x9b\x30\x52\x6a\x5a\xac\x0b\x0c\x8b\x14\xfa\x4a\x54\x0c\xfb\x11\x45\xfc\x00\x44\x18\xbc\xd3\x18\xc1\xa7\x0e\x62\x69\xa3\xfb\x69\xba\xed\x86\xf3\x63\xf5\xb8\xf9\x7f\x56\x9c\x20\xd4\xf4\x99\x0e\x7b\xb4\xd0\xc3\x99\x21\x26\x8d\x63\x6e\xd0\x55\x4b\xd6\x2a\xcf\xca\xcd\x3b\x8e\x03\x02\x17\xaa\xfa\xc3\x04\x4c\x03\x7e\x0f\x94\xda\x18\xc6\xb9\xa0\x93\x2c\x3c\x58\x75\xd3\xa9\x3f\xbd\xad\xcf\x67\x96\x4e\xec\x9e\xc2\xbe\x69\xb4\x8f\x02\x0f\x6c\x98\x74\xde\x5f\x8a\x51\x67\xb5\xee\x02\x4a\x2c\x2e\xfd\x0c\xdc\xd2\xac\xd8\xc1\xf7\x87\x81\x41\x41\xe3\x0b\x38\xb1\x63\x17\x5b"}, +{{0xb6,0x9c,0x33,0xb1,0x1b,0xa6,0x78,0x41,0xc3,0xd4,0xe6,0xf9,0x23,0x4e,0x35,0x37,0x0a,0x28,0xb4,0x76,0x62,0xac,0x56,0x0b,0x27,0xc0,0x78,0xb6,0x6a,0xb1,0xb0,0x21,},{0x9d,0xf6,0x8e,0x9a,0xcf,0x67,0x37,0x92,0x61,0x74,0x4d,0xb5,0xd1,0xe3,0x77,0x89,0x2f,0x2b,0x69,0x2e,0xd5,0xa3,0x8b,0x37,0x07,0x3c,0x04,0xde,0x5d,0x22,0x67,0x37,},{0x24,0x36,0x8f,0xee,0x5b,0xd8,0x48,0xb4,0xc6,0x61,0xa3,0xbe,0x4f,0x31,0x0c,0xfc,0x43,0x6e,0x79,0xec,0x4a,0x78,0x50,0x1b,0x81,0x09,0x5f,0xe5,0x16,0x14,0x23,0x1b,0x6c,0xa1,0xab,0x12,0x69,0x99,0x6a,0xd2,0xe9,0x8e,0x29,0x97,0x81,0xaf,0x8e,0x29,0x80,0x4b,0x24,0xfe,0x56,0x79,0xca,0x3b,0xa6,0x50,0xc5,0xc4,0xcc,0x58,0xce,0x01,},"\xf9\xea\x12\x6d\x3a\xb2\x19\x61\xaa\x24\x33\x90\x0a\x39\x82\xb8\x3e\x0e\xf8\x6d\x52\xd1\x34\x40\xaf\xa4\x81\x7f\x9b\x82\x2f\xb5\x82\xcc\x39\x32\xbf\x45\x0d\x46\x77\xc9\x18\x81\x81\xfe\x75\x26\xad\x6f\xe5\xab\xc6\x1d\x0a\xe7\x59\xf2\x15\x01\x3c\x0b\x2b\x41\x06\x4c\xb6\x27\x8b\xa7\xe3\x9e\x2f\x4c\x10\xd6\xcc\x96\x05\xb3\x86\x9e\x16\x9d\x7d\xa4\x2e\x88\xeb\x85\x78\x70\xfe\x61\x18\xbb\x02\xbc\x08\xc8\x05\x5f\x0c\x18\x9b\x62\xf7\x9f\xb1\x46\xb4\xc5\x43\xaa\x30\xcc\x0c\xd5\x7f\x03\x7e\x9e\xf7\xa6\x37\x11\xf6\x6e\x6f\x28\x78\x93\x17\x02\x20\x27\x02\x61\x42\x77\xd5\x13\xf0\x85\x0b\x75\x85\x49\x33\x6b\x30\xcf\x40\xab\x8b\xd4\x60\xe6\x0e\x12\xde\xed\x04"}, +{{0x7b,0x63,0x61,0x3f,0x6d,0xae,0x01,0xcd,0xcd,0x5e,0x6b,0x37,0x68,0x69,0x71,0xcd,0x8d,0x8a,0x99,0x54,0x2f,0x63,0x29,0xa1,0x28,0x54,0xa9,0xd8,0xff,0x81,0x05,0xac,},{0x72,0xec,0x43,0xfa,0xf3,0x4d,0x87,0x30,0x17,0x7d,0x1f,0x07,0x43,0xc7,0x4c,0x20,0xbf,0x72,0xc2,0x39,0x4b,0x8a,0x7d,0x47,0x1f,0xfe,0x2a,0x04,0xab,0x00,0x81,0x1c,},{0x76,0xf5,0x0b,0x2b,0x9c,0x2a,0xd9,0x7b,0xfb,0x94,0x99,0xee,0x41,0x92,0x8a,0xc0,0x72,0xda,0x5e,0x8b,0xc7,0x1d,0x02,0x12,0x55,0x09,0x42,0x33,0x2b,0x62,0xe7,0x0c,0x8b,0xfe,0x1c,0x72,0x25,0x42,0x39,0x46,0x88,0xde,0xcd,0x91,0x7a,0xec,0x8f,0x95,0x35,0x3e,0x1d,0x72,0x62,0x4b,0x70,0xeb,0xed,0x5d,0x17,0xf6,0xc5,0x49,0x77,0x02,},"\x18\x16\x48\x8f\x1f\xc8\x3e\x1e\xd5\x91\x16\x37\xdd\x42\xba\x20\x77\x65\x7d\xfe\x1a\xe4\x22\xad\x0a\xee\x59\xdf\x9d\xd5\x6a\x27\x63\xc2\xdd\x0e\xf6\x1a\x12\xbb\x82\x5b\x0d\xac\x1e\xda\x5f\xbb\x69\x1c\x5e\xd5\x8f\x3f\xb3\x25\x05\x0b\x45\x63\xa4\x04\x20\x99\x98\x2f\xff\xa5\xd6\xed\x74\x2d\x95\x82\x3d\xa8\xe1\x78\x7c\xf7\x46\xef\x63\xb3\xfb\xb0\xe8\x8a\x6c\x0b\xea\xe4\xf7\x31\x83\x66\x93\x6b\x49\x17\xf5\x07\x33\x60\x68\xb1\x94\x68\x09\x00\xa7\xbf\x4a\x6f\xb6\x9a\x5c\x38\x7b\x97\xe3\x1b\xc7\xf9\xbe\x53\xc2\xa8\x9e\x36\x51\xce\x1d\xe4\x1b\x10\xe9\x21\xb2\x06\xeb\xf3\x2e\x56\x21\xef\x80\x81\x61\x6d\xcd\x7a\x20\x59\x43\x7e\xfa\xd0\x14\xbb\x8e\x2c\x82\x21"}, +{{0x35,0x58,0xd3,0xa7,0x43,0x95,0xbd,0xcb,0xa5,0x60,0xe2,0xc4,0x5a,0x91,0x96,0x0c,0xec,0x6c,0xb3,0xed,0xbc,0xd3,0x0e,0x72,0x2f,0x7f,0x05,0x52,0x10,0xf3,0x7b,0x51,},{0x53,0x4f,0x43,0xeb,0xa4,0x03,0xa8,0x4f,0x25,0x96,0x7c,0x15,0x2d,0x93,0xa0,0x17,0x5e,0xc8,0x29,0x3e,0x6f,0x43,0x75,0x31,0x9e,0xad,0xf9,0x57,0x40,0x1f,0xbb,0xd2,},{0xb3,0x65,0xb5,0x56,0x1a,0x13,0xa5,0x45,0x17,0xcf,0x90,0xd8,0x8b,0x35,0xeb,0x09,0x67,0xd6,0xd5,0x84,0x14,0xb8,0xc1,0x54,0x7e,0x69,0x31,0x59,0xe0,0x13,0x78,0x56,0x36,0x54,0xc5,0x0f,0xb4,0x23,0x23,0xf0,0x9d,0xd7,0x8f,0xfe,0x28,0x05,0x6d,0xdf,0xa5,0x4f,0xeb,0xf4,0x48,0x91,0xe8,0xa7,0x41,0xb6,0xa1,0x68,0x7d,0x72,0x86,0x05,},"\xbe\x75\x44\x4f\x9c\xe6\xbe\x1d\x83\xaf\x62\x2a\x8c\x47\x8d\x51\x01\x27\xdb\x56\xf1\xde\x6e\xb8\xa5\x12\x65\x22\xb0\x9f\xdc\x6c\xa0\x86\x2c\xec\x0b\x8b\x2a\xaf\xa3\x1c\x17\xa2\xcc\x47\x7d\xa5\x33\xd2\x76\xa1\xae\x4f\x8e\x07\x59\xd6\xaf\xa0\xb1\x74\x11\xb5\x17\x0b\x52\xf2\x05\x47\xc7\x2f\x3e\x88\xd4\x8c\xb4\x56\xfe\x62\x5b\x62\xfe\xb0\xf8\x13\x17\xed\xf1\xec\x09\xec\xe5\x34\xb9\xf5\x00\xd4\xe1\xb1\xbd\xa2\xdb\x21\x98\x2a\xa9\x50\x94\x22\x6e\xe9\xf5\xb0\xa6\x5d\xa8\x3f\x91\x12\x1c\x96\xb3\xb4\x01\x0a\xe7\x82\x6c\x9e\x80\x63\x6c\xba\x00\xf7\x0c\x3c\x8a\x27\x9b\x01\xb9\x52\x94\xcb\x85\x0f\x91\x70\x9f\x43\x76\x66\x2a\x58\x0b\x15\xac\x29\x81\xaf\xe9\xf8\x54"}, +{{0xa3,0x5b,0x92,0xf2,0x44,0x06,0x3a,0x19,0xbb,0x5e,0x3e,0xd4,0xd6,0x99,0xed,0x20,0x69,0x60,0x71,0x16,0xd2,0xbd,0x08,0x11,0x3f,0x0d,0x83,0x73,0x61,0x3f,0x35,0xb7,},{0x7e,0xc9,0x36,0x01,0x86,0x4e,0xe4,0x99,0x5a,0x4f,0x7a,0xbc,0xd3,0xdf,0xc1,0x01,0xe9,0xe7,0xf3,0x69,0xe6,0x3d,0xe1,0xae,0x68,0xa0,0x7a,0xa7,0xf0,0x75,0xb3,0x29,},{0xa2,0x3d,0xbe,0x37,0x57,0xe4,0x78,0xdb,0xc8,0x4d,0x3d,0xb3,0xa9,0x33,0xb0,0x42,0x8c,0xed,0xb6,0xb0,0x1b,0x86,0xd8,0xd7,0x3f,0x39,0x59,0x87,0x8d,0xae,0x6f,0x05,0x88,0xf5,0x05,0xcd,0x4d,0x39,0xf2,0xab,0x46,0x77,0xb6,0x48,0x05,0xd6,0x29,0x65,0x2a,0x22,0x52,0x98,0x25,0xc3,0xa9,0x1d,0x04,0x37,0x49,0xfc,0x71,0xf0,0x37,0x06,},"\x65\xcd\x36\xda\xe0\x16\x8d\x69\x97\x4f\x95\xf0\x9d\xd9\xa5\x9d\xb7\x99\xf9\x11\xe1\xa1\x5b\x85\xa0\x08\x93\xb8\xc9\xa3\xd4\x8a\x2f\x58\xac\x12\x6b\xfa\xa0\xa6\x06\xc0\x5d\x94\x70\x1d\x27\x3a\xbf\x7d\x68\x81\x7f\x2c\x71\xb1\xc5\x41\x79\x5c\x4f\x60\x95\xe2\x6c\x9d\xff\x80\x3f\x03\x2f\x75\x66\x3f\xd1\x69\x8e\xdd\x97\xff\x3a\x0e\x72\xe1\xb7\xc9\x94\x8b\x08\xba\xcb\x5f\x7d\xe5\x02\xb2\xfe\xa6\x7c\xa2\xfe\xf1\x90\xd6\x0e\xae\x92\xd1\x51\x58\xda\x44\x4a\x49\xd2\xe9\xd5\xa5\x73\xe8\xe1\x77\xe8\xbb\xf7\xe6\xc4\x9f\x90\x71\x36\xe7\x1d\x2a\x66\xcb\x07\x63\x6d\x48\x76\x8f\xf4\x17\xc8\xbe\xcc\xf4\x32\x31\x81\xfe\xfb\x31\x24\xe4\x34\x04\x9e\xa4\x5d\xd5\x01\x9e\x40\xb4"}, +{{0x72,0xd4,0xa5,0x64,0xca,0x15,0x49,0x9b,0x5e,0x4e,0x75,0xd8,0xac,0x0f,0x28,0x21,0x7d,0x32,0x11,0x4a,0x0c,0x64,0x9a,0x7c,0x8e,0xaa,0xdd,0x0c,0xc7,0x8c,0x52,0x0b,},{0xc7,0x66,0xbd,0x73,0x83,0x7c,0x4f,0xaa,0x52,0x15,0x50,0x2f,0x1e,0xfc,0x90,0xc0,0x03,0xf7,0x11,0xbb,0xef,0x55,0x17,0x00,0x91,0x02,0x8a,0x34,0x49,0x34,0x08,0xa9,},{0x8f,0xc4,0xf1,0x79,0x33,0x0b,0x64,0x2d,0xd8,0x6c,0xa9,0x36,0x26,0x51,0xb8,0x3b,0x00,0x6d,0x83,0x75,0xcc,0xef,0x81,0x1d,0x3c,0x67,0x06,0xf9,0x15,0x94,0x65,0x1d,0xf2,0x76,0x99,0x53,0x72,0x30,0x46,0xcc,0xb9,0xbf,0xe6,0x6a,0x66,0x7e,0x0d,0x11,0xfc,0x3e,0xa2,0xd8,0x22,0x62,0x34,0xfd,0xd5,0x16,0x47,0x65,0x26,0x0f,0x7b,0x05,},"\x6c\x7e\x7b\x62\xeb\x24\x4a\x45\xd7\x84\x36\xe2\x97\x0d\xcd\x6c\x0f\x7d\xb8\x22\x97\xa8\x61\x40\xea\x58\xdd\x22\xc2\x19\x5a\xdb\xc9\x56\xd4\xc4\xec\x05\x35\x4b\x21\xef\xe2\x4c\xfc\xfe\x10\xe1\x76\x22\x36\x88\x48\x18\x0d\x2c\x46\x80\xcc\x21\x5e\x8c\xee\xa6\xcc\xe2\x22\x16\x1f\x1e\x09\x22\x39\x25\x3b\x97\x46\xf7\x88\x7d\xf2\x42\x5a\xb5\xa8\x80\xbd\xba\x98\x15\x3b\xe7\x86\xdc\x83\x8c\xbe\xca\x01\x6b\x1d\x06\x52\x4b\xd6\xbf\xba\x80\x9a\x8b\xb3\x7a\xda\xb1\x5d\x42\x41\x5f\x86\xec\x03\x58\x36\x5e\xa8\x7b\x81\x50\xb0\x54\x41\xd9\xd4\x98\x46\x87\x14\x85\xca\xae\x6d\xe3\x59\x73\x6c\x27\x18\x97\x36\xd8\xf1\x76\x5f\x3e\x5c\x5f\x6b\x92\x16\x83\x96\x39\x0b\xee\x94\xcf\xbd"}, +{{0x2e,0x5a,0xaa,0xb2,0x98,0xe6,0x6c,0x2d,0xc1,0xd7,0x7e,0xa7,0x42,0x1f,0xf8,0x95,0x25,0x5f,0x9d,0x90,0x0d,0xb0,0x45,0x0d,0x63,0xf9,0xf7,0x9c,0x1a,0x70,0x13,0xcf,},{0x03,0x81,0xf3,0xf1,0x90,0x45,0x71,0x9b,0x9e,0x8c,0xeb,0x56,0x2f,0x0e,0x96,0x5d,0xc0,0x7b,0x09,0xf3,0x71,0xa9,0x63,0xa2,0x81,0xc7,0x49,0xc2,0x53,0x2f,0x65,0x4a,},{0x7c,0x74,0x30,0x30,0x5b,0x36,0x1a,0x9e,0x35,0xb2,0x78,0x0c,0x4d,0x44,0x08,0x07,0x1b,0x21,0x30,0x93,0x1d,0x39,0x83,0x0e,0xc8,0xd3,0x13,0xaa,0xfb,0xc8,0x3a,0x65,0xda,0xe1,0x9c,0xb7,0x47,0xd9,0xd1,0xc4,0xce,0x3f,0x35,0x9c,0xc8,0x24,0xea,0x8c,0x92,0xf6,0x6a,0x42,0xb8,0x61,0x4e,0x78,0x48,0xb8,0x84,0xac,0x8a,0xa4,0xae,0x02,},"\x3d\xf0\xe5\x4c\x71\x1e\x31\x32\xd7\xae\x95\x3d\xeb\x7b\x66\x86\x9e\xe5\x31\xee\x40\xb6\x3c\xe6\x93\x20\x6c\xdb\x2f\x4b\xda\x0a\x25\x69\xe9\x13\xac\x3e\x65\x32\xc5\xd9\x64\x8e\xfd\x46\x27\x78\x0f\xb8\xa3\x1d\x10\x7e\x03\x3f\x05\x4d\x19\xed\x8b\x7c\x49\xdc\x40\x7d\x2e\x94\x9d\xe2\x5f\x99\x30\x72\x21\xd3\x58\x43\xf6\xd5\xeb\x7d\xe5\xcd\xf4\x1b\x91\xdb\xbf\x34\xcb\x6c\x9c\x53\x00\x21\x01\x4b\x56\xab\xc4\x4a\xc2\x30\x03\x13\x61\x56\x08\xa7\xb4\xa2\x35\xe9\x9c\x14\xce\xf8\x05\x08\x87\x03\x22\x09\x48\x8b\x9e\xae\xaa\x82\xc0\x94\x05\xfc\x75\xbe\xc9\x4d\xd4\x2d\x6f\xf1\xb5\x99\xa6\x3e\xe5\x74\x2f\x33\x64\x09\x3a\xc9\x2c\xab\xab\x30\x35\x82\x2a\xa8\x67\xae\x56\xdc\xc9\x9d"}, +{{0xb6,0x36,0xa0,0x24,0x48,0x00,0x35,0x43,0xdb,0x86,0x4b,0x40,0xb5,0xd8,0xd6,0xdd,0x9a,0xd6,0x11,0x62,0x4c,0x9b,0x0f,0xc6,0x89,0x0c,0x51,0xea,0x55,0x92,0xc7,0x90,},{0x1e,0xf3,0x60,0x49,0x59,0x68,0xe5,0x6e,0x6d,0x3f,0xe7,0x40,0xb1,0xc8,0x4c,0x4e,0x44,0x90,0xed,0x68,0x2d,0xeb,0x43,0x05,0xaf,0xd5,0x96,0xef,0xb2,0x80,0x22,0x3b,},{0xd4,0xba,0x80,0x30,0x0d,0x5c,0xb5,0x13,0x53,0xc0,0x3f,0x28,0xc4,0x4f,0xd0,0xa4,0x24,0xff,0xe1,0xe4,0x0d,0x78,0xed,0x7b,0xb1,0x13,0x3e,0x8f,0xe4,0xe1,0x87,0x50,0x52,0x93,0xb2,0x0a,0x39,0x1d,0xa9,0x62,0xc6,0xa8,0xac,0x0a,0xce,0xc9,0xc6,0x72,0x26,0xaf,0x3b,0x61,0x95,0xda,0xbe,0x39,0xb3,0x66,0x22,0x94,0xda,0x3e,0x0e,0x09,},"\x4a\xa8\x5a\xac\x25\x03\x4f\x61\x4e\xd4\x4f\x7a\xdc\xdb\xee\xec\x25\xfc\xc2\xa9\xee\xa3\x2a\xb6\xa8\x69\x95\x06\xf7\xa1\xca\xd3\xbc\x89\x2e\x9d\xce\x93\x4e\x75\xb0\xa8\xcd\x14\x64\x2b\x77\x85\x99\x28\x6c\xfd\x8f\x50\xa9\xe4\xf2\xed\xf9\xf9\xd6\x29\x1a\x2e\x29\x79\xcf\x18\x06\xb9\x3e\xd8\xc9\xa7\x8f\xae\x19\x9b\x28\x54\xa0\x3e\xc4\x06\xab\x3f\x72\x08\x35\xee\x26\x3f\xbb\xc9\x1c\xb4\xef\x07\x58\xd7\x75\xfc\x78\x4c\x7d\x5b\x25\x1a\xc8\x93\x79\x19\xa9\xe6\x7b\xe8\x8c\x9e\x44\xcf\x2e\xc7\xf5\x60\x26\x9a\xa0\xf1\x11\x3d\x91\xb8\x44\x01\xdb\x15\xa3\xc4\x8c\x7d\xac\xff\x49\x39\xee\x01\xba\xbb\x98\x2f\xb9\x56\x25\xc6\xc3\xad\x78\x74\x90\x60\x55\x1b\xfd\xe8\xcc\xe4\xfb\x8a\x29"}, +{{0x5c,0xa0,0x54,0x3c,0x71,0xf5,0x68,0xa0,0x0e,0xed,0xf5,0x0a,0x95,0x20,0xf4,0xc1,0x5b,0x52,0x6e,0x3f,0xb0,0xda,0x81,0x6c,0x29,0xea,0x3d,0x50,0xb2,0xf6,0x2a,0x12,},{0xd4,0xa2,0x93,0x3c,0xe1,0x94,0x54,0xe3,0x31,0xb5,0x28,0x01,0x00,0x20,0x9a,0x6c,0xe8,0xe5,0x69,0xf9,0x93,0xc2,0xac,0xab,0x51,0xdb,0xe8,0x64,0xc5,0xcb,0x25,0x63,},{0x43,0x68,0x23,0xee,0xff,0x3e,0xdc,0xe5,0xd8,0x58,0x7d,0x68,0xe5,0x47,0x3e,0xf3,0xd8,0xdc,0x94,0x65,0xb5,0x58,0xb6,0xe8,0xe7,0xcd,0x31,0x37,0xec,0xcc,0x80,0xb4,0xc4,0xe8,0x06,0xed,0xf1,0x36,0x19,0xd8,0xe7,0x17,0xe6,0x9f,0x48,0xd7,0x06,0x1b,0x68,0xde,0x02,0xc8,0x20,0x9b,0xe1,0xf7,0xac,0x26,0xba,0x8e,0xdf,0x60,0x6d,0x02,},"\x4e\xf8\x49\x69\x78\xd2\x8c\x10\xab\xd5\x4a\x26\x35\x6e\xe5\x59\x21\xce\xb3\x50\xdd\x4b\x74\x2c\x41\x61\xfb\xeb\xa8\xa1\x60\x1f\x8a\xd0\x48\x4b\x21\xa8\xcf\x5a\x29\x4f\xac\x00\xec\x8a\x6f\x59\xe3\x36\x2e\x47\xbf\xae\x1e\x28\xa2\xe6\xd0\x17\xc5\xca\xa7\x5f\xb0\xf4\x84\x82\x80\x80\x37\xca\x21\x47\x69\x54\xd7\x78\xff\x1a\x05\x86\xda\x3e\xf6\x9d\x6c\xef\x6d\x2d\x8d\xf4\xae\x7a\x85\x44\x2a\x1e\x46\xc9\x98\xcf\x40\x7a\x6a\xd4\xc5\x46\x3a\x43\xc2\x48\xf3\xb6\x93\x7f\xdb\xc8\x45\xb6\x0c\x6d\x85\xe0\x56\x3c\xc1\x6b\xa9\x67\x5d\x36\x4f\x52\x5f\x66\x9a\xaa\xc9\x5f\x42\x8b\xb5\x82\x05\x09\x9f\x9e\x4a\x6d\xbb\xd0\x15\x1f\xb6\x5b\xab\xe1\x23\xe5\x39\x3a\xd6\x40\x26\x93\x5c\xb4\x88\xaa"}, +{{0x5f,0x87,0x11,0x7d,0xa9,0xbb,0xb6,0x09,0x1c,0x94,0xda,0x6b,0x23,0x0b,0x7d,0x8f,0x6d,0xe0,0xed,0x2a,0x07,0x64,0x13,0xb9,0x2e,0xac,0xdc,0x43,0xab,0xbc,0x68,0x97,},{0xaa,0x78,0x6a,0x14,0x62,0x26,0x83,0x2a,0xa7,0x3c,0x43,0x4b,0x0e,0xdc,0x2d,0x41,0xd2,0x55,0x8f,0x82,0x0a,0xb8,0xf8,0x7e,0x09,0xe6,0xcd,0xa9,0x10,0x72,0xb9,0xb6,},{0x0f,0x19,0xe6,0xea,0x0c,0x05,0xf3,0x81,0x85,0xc0,0x1c,0x2d,0x64,0x77,0x99,0x5d,0xaf,0x50,0x65,0xba,0x9d,0x80,0x17,0x3f,0xa6,0xbb,0x23,0xa7,0x74,0xdc,0x88,0xb3,0xaa,0xe8,0x79,0xd8,0xa6,0x24,0x71,0xd2,0xd3,0x04,0xcc,0x3d,0xc6,0x62,0x78,0xa7,0xab,0xcb,0x0b,0xb0,0x77,0x1c,0xd2,0x78,0xe1,0x1e,0x7b,0x93,0x2e,0x9f,0x9b,0x0f,},"\x22\x97\xc4\x0a\x2e\x83\x65\xba\xe4\xc5\xf0\x63\x0c\x50\xb1\x3b\xdd\x9a\xd9\x77\x0a\x5d\x9a\x94\x51\xd0\x08\x74\xb0\x23\xd2\x5e\xcd\x46\x8b\x96\x57\x1b\x2f\x16\xdc\xb1\xb0\xd3\xd7\x56\xc1\xf0\x44\xfc\xdd\xd1\xc5\x1f\x27\x72\x7a\x03\x69\xc9\xcf\x25\xbd\x6a\xa5\x95\x51\xb5\xb0\x7c\xf8\xf8\x07\xd9\x2b\x15\x91\x98\x63\x97\x04\x74\x0f\xe6\xed\xa0\xf2\x6d\xba\x7e\x75\xd4\x53\x0b\x28\x00\xf0\x3f\xb6\xaa\x67\x7d\x84\xdf\x75\xd6\x8d\x4f\xbb\x64\xad\x21\x00\x1e\x3f\xc8\x7b\x60\x9b\x9c\x25\x1e\x8c\xcb\x12\xbb\xca\x92\x74\x47\xe2\x05\x4e\x07\x68\x8e\xb8\xa2\x05\x21\xa5\x22\x49\xe7\xb9\x43\xbe\xd6\x0e\x6a\x93\xc0\x1e\x3e\xb6\x21\xf0\x46\x0c\x18\xa6\x90\xb6\xf6\xb6\x6e\xdc\x6e\x87\x43\xa6"}, +{{0xb5,0x3a,0x64,0x4c,0x92,0xba,0x2d,0xc7,0x10,0x8b,0x16,0x83,0x3f,0x09,0xad,0x59,0x17,0x84,0x64,0x37,0x22,0x5a,0x77,0x3d,0x32,0xd7,0x9c,0x97,0x73,0x3c,0x0a,0x58,},{0x51,0x58,0x18,0xc6,0x9c,0x0e,0x0a,0x17,0x06,0xb0,0x41,0x43,0x84,0x2f,0x3e,0x9e,0x27,0x14,0x48,0xfb,0xaf,0x3a,0x89,0x91,0x19,0xc3,0x2f,0x42,0x56,0x6f,0xfd,0x33,},{0x13,0xd2,0xcb,0xac,0x79,0x76,0xad,0x27,0xf0,0xbf,0x66,0x9a,0xd5,0x88,0xef,0xb2,0xc9,0x1b,0xab,0x85,0x07,0xd5,0x7f,0xb1,0x6b,0xfe,0xa9,0xca,0xff,0x2b,0x09,0x64,0xe7,0x56,0x25,0xc4,0xd8,0x08,0xd7,0xbb,0xb7,0x8c,0x5b,0x46,0x4e,0xdf,0xfe,0x49,0x49,0xec,0xfb,0xc8,0xb9,0x5f,0xf6,0xfd,0xb1,0xbd,0xca,0x27,0x42,0x06,0x81,0x00,},"\x13\x03\x6d\xaa\xee\x45\xfc\xfd\xe0\xc5\x3e\x06\xd0\x5a\xa9\xc0\x1e\xa9\x4a\x67\xe8\x6c\x6c\x53\x8c\xcb\x28\x3b\x36\x8d\xaf\x70\x78\xd3\xfb\xab\x58\x0c\x76\xec\xf8\x2b\x4e\x96\x60\xf0\x68\xdc\xbb\x50\x0b\x80\x59\x50\x17\xc5\xbe\x3c\x44\x8f\xbd\x8a\x17\xd9\x7c\x56\x43\x19\x78\x90\xe1\x67\xb3\x53\x45\xbf\x65\xe7\x5b\x82\xc8\xd6\x52\x29\xf2\xf6\x0a\xae\x27\x72\x58\x1b\xc9\x9c\x49\xd4\x16\xbc\x3d\x78\x74\x6e\xf8\x30\xf1\xaf\x94\x4f\x4a\x67\x15\xab\x4f\xfb\x01\x59\x1b\xac\x28\x57\xf1\xa9\xc9\xd1\x70\x08\x88\x78\x00\x06\xa3\x16\x07\x33\x8f\x7a\xf7\xbe\xdf\x6e\xfe\x0b\x57\x29\x9a\xc9\x15\x52\x6f\xe5\xe1\xe1\x01\x29\x87\x08\xc6\xe6\x1b\x84\x22\x0a\xfe\x95\xb5\x3f\x89\x59\x87\x45\x61\x52"}, +{{0xd2,0x7c,0x9e,0xaf,0xcf,0x88,0x15,0x19,0x90,0xbb,0x5b,0x2f,0xa8,0x44,0x3e,0x70,0x9b,0x5f,0xd8,0xd7,0x8d,0x23,0x38,0x03,0x32,0x2d,0xc8,0x6d,0x93,0xd9,0x32,0x95,},{0x08,0xe0,0xef,0xf5,0x29,0x77,0x67,0x14,0x68,0x61,0x96,0xd8,0x17,0xfd,0xf7,0x1e,0xb5,0xb6,0xe8,0x32,0x65,0x16,0xef,0x48,0x9b,0xfe,0x18,0x6a,0xc5,0xc5,0xbf,0x6d,},{0xc2,0x54,0xe3,0x71,0x44,0x56,0x33,0x13,0x74,0x42,0xee,0xfe,0x40,0xad,0x4a,0x82,0xe6,0x9b,0x1e,0xbf,0x48,0xa6,0x85,0xa2,0xbc,0x6f,0xfb,0xac,0x12,0x6d,0x22,0x84,0x87,0xb2,0xe3,0x53,0x7c,0x97,0xef,0x74,0x10,0x34,0x20,0x91,0x96,0x2e,0x50,0xc0,0xcb,0x85,0xde,0x7b,0x39,0xce,0xb4,0x1a,0xc4,0x07,0x8d,0x40,0xf3,0x40,0x71,0x06,},"\x77\xc3\x5b\xda\x32\xa5\x96\x7d\x8b\x30\x2f\xa7\xa4\x75\x83\xce\xab\x89\xc9\xa6\x09\xa6\x67\xb7\x53\x15\x5f\xa6\x99\x6f\x86\x31\xd0\xeb\xed\xfe\x0a\xc3\x64\xc7\x7e\x85\xba\x37\x31\x1f\x0d\xe5\x7a\x0d\xc2\xc1\xe9\xe4\x00\xd5\x8b\x42\x4a\x32\x2e\x1d\x57\x71\xe0\xa9\xfd\x95\x02\xad\x02\x32\xce\x54\x4f\x07\xd8\xc6\x6e\x7c\x31\x47\xf8\x60\x7a\xc6\x18\x9b\xb6\x90\x66\xf2\xfa\xd6\x31\x18\x5f\x45\x7f\x46\x7e\xba\x33\x22\x8e\xcc\x40\xe8\x94\xa7\x7b\x57\x16\x98\xa9\xbf\xac\x84\x1a\x54\xea\xc5\x21\x9d\xa9\x9c\x6a\x91\x25\xc4\x69\xa2\x2f\xe8\x1f\x3b\x95\x14\x33\x89\x6f\x19\xce\x39\xb3\x73\xfd\x7e\x5c\x7b\x65\x0a\x5e\xf2\x36\x5a\xe7\x51\x0b\x0d\xa5\xe4\x9d\x7c\x07\x07\x3c\xf1\x66\xa9\x83\x87\xe8"}, +{{0x70,0x21,0x3d,0x3a,0x79,0xc6,0x5d,0x6d,0xbb,0xa5,0x42,0xa3,0x67,0x96,0x35,0x00,0x3a,0x68,0x2a,0xf5,0xfa,0x58,0xde,0x6b,0x0d,0x65,0xbf,0xa2,0x41,0x84,0x90,0x1c,},{0x44,0x02,0xfb,0x92,0xcc,0x12,0x49,0xdd,0x1a,0xe1,0x69,0x0f,0x03,0xb3,0xec,0x4f,0x1e,0x9b,0xda,0xb0,0xde,0x5b,0xfd,0x28,0x9f,0x10,0x29,0x68,0x30,0xfd,0x40,0x3e,},{0x5b,0x6c,0xe2,0x77,0x4d,0x40,0x0e,0xce,0xa8,0xa8,0x08,0xf5,0xfd,0x0a,0x79,0x7f,0xfc,0x61,0x16,0x75,0x23,0x76,0xcd,0x7b,0xfa,0x3b,0x2c,0xca,0x3a,0x84,0xd5,0x59,0x3f,0x5c,0x03,0xad,0x3e,0xec,0x1d,0x89,0x53,0x22,0x75,0xc4,0x7b,0x7c,0xe2,0xa0,0xe9,0xc5,0x9c,0xc4,0x02,0x8a,0x8a,0x65,0xe5,0xbb,0x90,0x97,0xea,0x71,0xc2,0x08,},"\xcd\x6e\x1c\xd9\xc9\x0f\x56\x6d\xe0\x43\xd7\x5d\x72\x44\xec\xfd\xb3\x8e\x8b\xde\x2f\x9a\x6c\xd5\xa4\xfd\xac\x72\xb5\xed\xe6\xaf\x62\xd9\x81\x91\x8c\x5e\x61\x0a\x38\x78\x92\x74\xfa\x10\xe5\x27\xf8\x5f\xad\x20\x9b\x76\xca\x1c\x28\x1a\xd5\x89\x0f\x9c\x96\xd3\x5d\xe5\x22\xf1\xdd\xcc\xb5\x39\xb8\x79\x8a\x00\x67\xac\xdd\x45\xb6\xe3\x44\xa5\xd9\xa9\x77\x31\xf5\x45\xff\xa4\xb1\x7b\x87\x5c\x67\xb4\x8e\x9d\x4c\x4b\xa7\x2c\x98\xa4\x50\x55\x83\xfd\xbf\x1e\x12\xf2\x2b\x5a\x7a\x49\x47\x46\xcc\x9b\x6c\x1b\x57\x19\x06\xc6\x7f\xcc\x88\x3a\x9c\x15\xa3\x80\x68\x75\xb6\x59\xe5\x81\x6b\x42\x76\xc3\x19\x0e\x25\xcc\x1a\xc3\xde\x47\xbf\x99\xc4\x99\x65\x38\x8f\x54\xf3\xef\x8e\xb5\x69\x90\x6c\x60\x08\xe5\xfb\xbd"}, +{{0x5d,0x54,0x0b,0x3b,0x14,0xf0,0xc0,0x17,0x5c,0x04,0x7e,0xaf,0x02,0x6c,0x90,0x70,0x65,0x9e,0xf1,0x3e,0x9d,0x28,0xe0,0xc5,0xc5,0x16,0xa4,0x28,0x26,0x9b,0x14,0xeb,},{0x1d,0x2d,0x4d,0x55,0x1a,0x57,0xc6,0xfb,0x2b,0x04,0x18,0x10,0x49,0xd4,0x03,0x9d,0x57,0x5c,0xf8,0x0c,0x0b,0xc6,0xec,0x70,0x33,0x06,0x7f,0x27,0x30,0x93,0x44,0xde,},{0x32,0x52,0x7d,0xa7,0x55,0x31,0x28,0x89,0x93,0x5d,0xd5,0xee,0x91,0xb1,0xbb,0x11,0x7a,0x5d,0x37,0x7d,0xd2,0x3e,0xf5,0xb7,0xe1,0x5b,0xaf,0xfa,0xe9,0xa5,0x43,0x91,0xa3,0xfd,0x23,0x4b,0xdc,0xe0,0x73,0xe0,0x98,0xc5,0x8d,0x05,0xbf,0x19,0x5b,0x4c,0x3c,0xc6,0x39,0x72,0x38,0x3b,0xa4,0xb5,0x10,0x72,0x97,0x1a,0xeb,0xcb,0x62,0x0d,},"\xe4\xc9\xe8\x70\x68\x98\xca\xd4\xac\x68\xd7\x3c\x13\x0e\xfa\x04\xa5\x4f\x8c\xa2\x59\x19\xea\x6b\xfa\xa5\x4c\x8c\x72\x0c\xed\x85\x4c\x5e\x95\x09\x10\x2c\x7b\x88\x5a\xed\xdf\xfb\xd1\xb7\xf2\xc5\x92\x25\x83\x67\x7a\xc9\xee\xa9\xa1\x08\xc7\xe8\x3e\x88\x71\xae\xd5\xa0\x84\xf5\x44\x0b\x0f\x39\x1a\xd7\xff\xc6\xba\xb4\x57\x4a\xf1\xb9\x67\x70\xf4\x37\x0e\x8e\x98\x8e\x85\xec\xb1\xa8\xd6\x03\x4f\xc3\xd7\xf4\x9f\x74\x22\x02\x3b\x9d\xab\x5d\x0c\x16\xbe\xab\x5f\x5d\x37\xb0\xa4\xd7\xde\x19\x7a\xd8\x7c\xd4\xff\x8c\xe7\x8e\xb1\x2e\x1d\xaf\x73\x9d\x8b\x47\xab\x38\x0a\xbe\x90\x93\x35\x6d\xb5\xb5\x97\x17\x75\x1a\x49\xe1\x94\x84\x72\xfd\xac\xc2\x59\xff\xff\xc8\xc1\xdb\xae\x59\x26\x07\xd4\xec\x71\xcc\x6a\x8f\x6b"}, +{{0xca,0x41,0x76,0x9c,0xaf,0x17,0x17,0xb4,0xe4,0x5c,0x93,0xc1,0x21,0xdc,0x82,0xa5,0x34,0xfb,0xc6,0xec,0x09,0x86,0x66,0x2c,0x32,0x22,0xd7,0x14,0x92,0xbd,0x11,0x76,},{0xaf,0x3f,0x89,0xf6,0x18,0x7d,0xbc,0xf9,0x21,0x77,0x50,0xc6,0x7e,0xf8,0x9e,0xd4,0x7b,0x03,0x9f,0x9e,0xb0,0x62,0xff,0xec,0x9d,0xf6,0x4a,0xb5,0x2b,0x0b,0x45,0xcb,},{0x5c,0xda,0x87,0x2f,0x7e,0xd6,0xd7,0xc9,0x02,0x18,0xac,0x10,0xbe,0xe8,0xe2,0x14,0xf3,0xb3,0x4d,0x15,0xd2,0x5c,0x39,0x25,0x5e,0xc9,0xe6,0xb0,0x17,0x7a,0xa3,0xcb,0x73,0x68,0xd1,0x1c,0xb8,0xed,0x6f,0xf5,0xcf,0x0c,0x04,0x28,0x1d,0x06,0xbc,0x42,0x72,0xb8,0xbc,0x09,0xc2,0x3f,0x6f,0x4c,0xd5,0xa8,0x10,0xdd,0xc7,0xb9,0xc1,0x03,},"\x9d\xe8\x47\x6c\x58\x13\x84\x8a\xb1\x45\x15\x37\x84\x1c\xc1\x78\x00\x21\x81\xa2\x18\x2a\xf3\x05\xb1\x2e\x5f\x7c\x3b\x1d\x56\xb2\x2c\xf4\x6a\xe6\x27\x6d\x18\x26\xec\x0a\x8c\x9a\x7d\x9f\x68\x08\x3b\x72\x25\xbb\xfa\xef\xce\x82\xb3\xb6\x45\x94\x05\x2a\x77\x00\xf3\x09\x23\x3a\x79\xff\xfd\xfc\xcc\x5c\x21\x40\x0c\x91\xcc\x0e\x41\x8d\x51\x41\xd4\x86\xb5\x21\x99\x01\xd6\xdd\x24\x47\xc1\xf7\xb7\xcf\x5a\x08\x79\xe7\x0e\x1d\xd6\x58\xd0\xf2\xec\xf3\x1e\xbe\xee\x11\xa5\xc7\x44\x40\xc6\x3b\x9d\x8b\x45\x31\x8c\x34\x65\xd7\xff\x03\x36\x5e\xdd\x03\x85\xed\xf8\x0d\x4f\xde\xd5\x1f\x0f\x75\x33\xee\x40\x99\xf1\x9e\x93\xbc\x9d\x08\xda\xdc\xd1\x34\x85\xdb\x23\x95\x22\xff\xc8\x1e\x2c\x05\x1f\x87\x96\xd6\x2e\x97\x9f\xcf"}, +{{0xfe,0xdd,0x63,0xff,0xd4,0xcf,0xbf,0x61,0x88,0x94,0x96,0x2e,0x12,0x1a,0x90,0x25,0xee,0xa3,0x18,0xa8,0x0a,0x1a,0xdf,0x16,0x9d,0x64,0x90,0x44,0x5d,0x2e,0x02,0xa0,},{0x54,0x2f,0x22,0x44,0xbd,0xb7,0xd8,0x4b,0x87,0xe6,0x28,0xa8,0xe6,0xa1,0x2f,0x17,0xbf,0x74,0xa9,0xa6,0xd0,0xea,0x46,0xc5,0x95,0xdb,0xfd,0xc6,0x80,0xc0,0x4b,0x26,},{0xed,0x59,0xd9,0xe2,0x3d,0xec,0x34,0x94,0xb0,0xfb,0xc5,0xd1,0x0c,0xd0,0x2b,0xab,0x86,0xb3,0xeb,0x35,0xab,0xbf,0x9e,0x4d,0x4a,0x92,0x64,0x79,0xf1,0x34,0x58,0x3a,0x44,0xce,0x72,0xdc,0x41,0x22,0xac,0xa3,0x77,0xa4,0x07,0x2b,0x71,0x56,0x46,0x2b,0x74,0xe8,0xdf,0x46,0xb6,0x86,0x69,0x86,0x36,0x83,0x6e,0xf2,0x03,0x17,0x9c,0x07,},"\x2e\x2a\xe5\x84\x64\x1b\xe0\x3d\xd4\x8f\x9c\x61\x80\x77\xae\xaa\x18\x21\x2a\x42\x41\xf0\xc0\x19\x4e\xd2\x3e\x37\x0d\x74\x1a\x3a\xe1\x1a\x5f\xec\x3b\x04\x0c\x16\xea\xfa\x4a\xc8\xd1\x8a\xba\xa7\xce\x8f\x28\x69\x67\x33\x71\x89\xf0\x49\x5f\xfd\xd6\x19\x95\xcd\xe3\x1d\xd8\xdf\xc3\xdf\x57\x00\xb5\x7a\x7a\x29\x98\x0e\x9c\x82\x3f\xee\x85\xd6\x14\x51\x17\x67\x29\xe7\x27\x87\xc6\x10\x9b\x47\x35\x9b\x93\xdf\xd6\x2e\x1e\x5a\x2d\x64\x2c\x05\x72\x42\xda\xe5\x00\xa9\x4c\xa1\xa9\x3b\xc5\x7b\xe1\xad\xe7\x6f\xe4\x50\x1c\x0f\x63\x77\xed\x0e\x92\x46\x17\x9a\xec\xdd\x99\x46\xb6\x71\xe8\x19\x0e\x1e\xd2\x3f\x96\x6e\x96\x40\x9b\x94\x82\x22\xd8\xea\x58\x39\xde\x90\x4f\xc5\x13\x48\x07\x3b\x8f\x40\xed\xbd\x9b\x4a\x4b\x22\x75"}, +{{0x38,0xf2,0x18,0x4e,0xaa,0x55,0x36,0x56,0xee,0x29,0x02,0x70,0x6b,0xce,0xc4,0xac,0xb5,0xaf,0x25,0x15,0x7c,0xa0,0xf6,0xa2,0xd4,0x8d,0xe8,0x52,0x85,0xfa,0x3b,0xc0,},{0x7f,0xf0,0x3f,0xb4,0xc8,0x2e,0x9c,0x15,0xd6,0x59,0xdf,0x42,0x4b,0x3e,0x73,0xed,0x1d,0x78,0x00,0x6f,0x3e,0x0b,0x79,0xeb,0x64,0xd9,0x8c,0x13,0xae,0xc6,0xba,0x37,},{0x4a,0x64,0x13,0xc2,0xc8,0x7f,0x2b,0x38,0x56,0xa8,0xde,0xcb,0xce,0x49,0x3a,0xde,0xae,0x0c,0x69,0xc9,0x41,0x34,0x70,0x7f,0xb0,0xf1,0x8f,0x30,0x49,0xfd,0x3e,0x3d,0x05,0x1a,0xbd,0xb9,0xd4,0xbe,0xe2,0x53,0xc6,0x10,0x7c,0x02,0xd5,0x7a,0xd7,0xcc,0x9f,0x31,0x01,0xdb,0x66,0x0a,0xfa,0xc2,0xb7,0x98,0x19,0x38,0xe9,0x56,0x4f,0x01,},"\xc2\xdf\x77\xc9\xe4\x79\xf6\x19\x83\xb6\xc7\x48\x3e\xf9\x3f\xb8\x5a\x10\x3b\x21\x39\x23\x92\x65\x23\x06\x5e\xbf\xf2\x25\x7e\x85\x42\x7e\x05\xcd\xc2\x75\x82\xef\x6c\x16\xbe\x35\x3a\x3b\x25\x03\x72\xd6\x37\x0e\xec\xb6\xc8\x96\x29\x17\xeb\x65\x6f\x26\x41\x69\x01\x89\xd1\x72\xa1\x11\x05\x15\x57\xab\xc2\x49\x4e\x32\xca\xb6\x5e\xd0\x63\x3a\xff\xe9\x24\x08\xb5\x5c\x4e\xd8\xaf\x65\xe2\xc5\xe7\xaa\xb8\x87\xa3\xcc\x8d\x28\xc5\x2e\x9e\x13\x36\xd0\xb7\xbb\x3f\xe2\xcd\x84\x3e\x7f\xa1\x68\x03\x42\xf8\xa4\xaa\xfa\x02\xc4\xab\x25\x2f\x08\xc3\xd4\x6d\x5f\x00\xfd\x01\x48\x42\x63\xee\x63\x52\x84\xf6\xdb\x26\xd6\x29\x8d\xe5\xb0\xdd\x23\x8d\xa4\x0a\x8d\x2a\x93\x37\x6d\xa0\x30\x27\x83\xa0\xe3\xbe\x23\xd9\xe7\xf9\x90\xd2\x5b"}, +{{0x8b,0xfc,0xa4,0x84,0x62,0xd2,0x53,0x6f,0x74,0xb8,0x4f,0x6a,0xf5,0x9f,0x5d,0x85,0x82,0xff,0x8f,0x7e,0xc2,0x87,0x45,0xd6,0x72,0xe7,0x2e,0xb7,0x2e,0x79,0xd3,0xe9,},{0x9d,0x10,0xd2,0x75,0xc3,0xd3,0xfe,0x45,0x9f,0x7f,0xe2,0x90,0x1b,0xce,0x38,0x91,0x91,0xcc,0x84,0x83,0xc0,0xf5,0x11,0x40,0xd9,0xc6,0x2b,0x08,0xfa,0xde,0x81,0xbb,},{0x44,0xd7,0x7e,0x43,0x9e,0xf6,0xca,0x5e,0xb9,0x40,0xc6,0x0f,0xf8,0x73,0x2d,0xdc,0x16,0x26,0x9e,0xa0,0x23,0xbb,0x26,0x13,0xbd,0x44,0x7e,0xba,0x7f,0xd6,0x98,0x51,0x22,0x6c,0x48,0x19,0xce,0x8d,0x44,0x98,0x5a,0x49,0xf3,0xf4,0x1a,0xc7,0xaf,0x33,0xc4,0x7f,0xfe,0x5f,0x89,0x30,0x4a,0x32,0x56,0xe4,0x45,0xf8,0xd6,0x86,0xe3,0x07,},"\x81\xee\x4c\xb9\xc4\x5d\xa6\x91\xda\xcd\x7d\xd0\x9a\xff\x59\x73\x72\x67\xbb\x55\xc3\xad\xe1\xba\x32\xc1\x7b\x7d\x0d\x2d\x0c\x60\x79\xc3\x9d\x5f\xd5\xb2\x9b\xa5\xf9\xc1\x76\x20\x97\x70\x98\x43\xee\xe5\x61\x2b\xd2\x0b\xc8\x18\x5b\xf6\x4d\x5c\x93\x41\x84\xe1\x36\x24\xe6\xf8\x77\xa2\xa5\xdd\xa1\x5c\x0d\xf6\x2a\xfb\xb9\x70\x57\xcc\x91\xca\xc9\xa1\x84\x06\xa0\xe0\x10\x9c\xc3\x9b\x2e\x3f\x81\x2e\x22\x7a\x40\x62\xd5\xef\x81\xc9\x2c\x22\xa7\xdc\x79\x7c\x84\x5d\x71\xeb\x6e\xa9\xe4\x2e\xc8\x41\x7f\xba\x90\xa9\x6d\x2b\xb1\x43\x94\x18\x33\x0b\x4b\xb2\xf9\x9c\x6d\x63\xd3\x04\xa0\xe5\x06\xdc\xa9\x65\x3e\x5d\xe0\xdd\x56\xe3\x09\xdb\x1a\x76\xa0\xfa\xab\xab\x16\x37\x74\xf0\x00\x08\x8c\xef\x3d\x1b\x7a\x6c\xf6\x61\xd2\xe1\xd9"}, +{{0xd7,0x48,0x0d,0x42,0x72,0xbc,0xb1,0x55,0x7b,0x1b,0xbe,0xe0,0x49,0x15,0xc1,0x26,0xa5,0x2c,0xa6,0xd6,0xa8,0xbb,0x53,0x14,0xa0,0xe1,0xa5,0x2b,0x59,0xbf,0xc9,0x9c,},{0x99,0xc8,0x39,0xd3,0x6d,0x8f,0x5b,0x86,0x52,0x61,0x8e,0xd7,0xb0,0xfe,0x9e,0xc3,0xd9,0x4e,0xff,0xf4,0xc4,0x53,0xc5,0x40,0x63,0x14,0x76,0xa5,0x97,0x9b,0xbb,0xe0,},{0xe0,0x4d,0xc8,0x44,0x2d,0x35,0x21,0x73,0xe9,0x31,0x81,0x8e,0x29,0x08,0x58,0xde,0x85,0x68,0x8a,0x46,0x49,0xea,0x3e,0x3c,0x3a,0xe7,0x4e,0xda,0xa5,0x4a,0xd0,0x1b,0x64,0x62,0x2a,0xd8,0xa0,0x90,0xb6,0xad,0x60,0xad,0xfd,0x01,0x88,0x18,0x82,0x82,0x8d,0x39,0x07,0x8b,0xb5,0xb2,0x71,0x4f,0xd3,0xea,0x83,0x97,0xa3,0x42,0xfd,0x04,},"\x61\x5c\xc1\x9f\x94\x20\x17\x36\x5b\xa8\xbf\xa2\x56\xce\xcc\xc8\x5e\xe2\x89\xa1\xc3\x4b\xb1\x44\x2a\xcc\x07\x16\xc7\xfc\x2c\xae\xb7\x6a\x9d\xe1\x9a\xde\xc1\x06\x37\x1e\x47\xa3\x0d\x2e\x12\x39\xce\x1f\x7d\xca\x25\x52\x6d\x60\x4b\xdd\x64\x76\x59\xd9\x42\xbc\xba\xc3\x68\x91\x13\x49\xc3\xb9\x46\xa9\x7d\xa1\x0a\x42\xdb\xcf\x3c\x73\x41\x6d\x2e\x6b\xa2\x2b\xd2\x9d\x9f\x70\x56\x72\xe9\xe3\x38\x94\x4c\xef\x01\xad\x21\xf0\x09\x74\x2e\x07\xbc\xd8\x88\xca\x31\xe1\xee\x95\x3e\x8c\x1b\x1f\xd9\x54\xb7\xdc\xf1\xa0\xb1\xd5\xa0\x69\x06\x5a\x66\xcb\x72\x1a\xdc\x02\x0f\x4e\xfe\x1a\xbd\xd1\x67\x42\x74\x69\x39\x28\x57\x80\xd7\x53\x13\x7a\xe0\x14\x0b\xb4\x10\xfb\x6c\xe3\x36\x76\xc2\x7a\xee\xc5\x93\xa8\x8c\xbc\x73\xaf\xd9\xf4\x05\x11"}, +{{0x3c,0x2d,0x36,0x50,0x73,0x5b,0x41,0xef,0x90,0x06,0xbb,0x45,0xe4,0xbe,0x2e,0x0a,0xa5,0xcd,0xe8,0x51,0xae,0xac,0x42,0x1e,0xe9,0xc1,0xb4,0x92,0xd8,0x7a,0xa1,0x8a,},{0x3e,0x46,0xdd,0xce,0x29,0x88,0x44,0xfc,0xaf,0xa0,0x0a,0x1b,0x47,0xea,0xf3,0xde,0x70,0x59,0x6d,0xf1,0xbb,0xee,0x3c,0x80,0x9d,0x1b,0xe7,0xdd,0x94,0x08,0x0e,0x34,},{0x3f,0x2a,0xf0,0x1a,0xd5,0x37,0x7a,0xc3,0x90,0x40,0xd4,0x1a,0x41,0xe3,0x6e,0x7b,0x93,0xfa,0x72,0x35,0xb8,0x41,0x79,0x1f,0x43,0x2e,0xcd,0x7f,0x91,0xa3,0xb2,0x1a,0xb7,0x19,0x6c,0x88,0x3a,0xd5,0xa7,0xdb,0x44,0x6f,0x6c,0x06,0x67,0x24,0x60,0xf3,0xf6,0x3e,0xf8,0x63,0xd9,0x43,0x2b,0xe9,0xca,0xea,0xbb,0x79,0xe8,0x7e,0x22,0x08,},"\x14\x25\xd8\xd2\x18\xda\x1a\x10\xa8\x0b\x6a\x9c\x3c\x27\x50\xef\xe4\x16\x57\x98\x4a\xbd\x51\x00\xf4\x51\xba\x94\x9d\xb0\x10\x46\xb7\x12\x6b\xe8\x40\x23\x34\xed\x57\x52\x8b\xac\x05\x62\x25\x53\xa8\x6b\x72\x67\x22\x69\x5a\x8f\xb3\x31\xd8\x56\x54\x17\xc4\xff\x0f\x25\x1a\x32\x0a\xd0\x6d\xed\xbb\x75\x0d\xef\x35\xd5\x21\xc3\xc4\xcd\x57\x1a\x45\xad\xa8\x45\x06\x53\xd5\xe8\x1f\xe0\xbe\xb5\x3a\xaa\xe7\x87\xb3\xeb\x65\x3c\x23\x81\xed\x55\xaa\xf2\x59\x0e\xe5\xed\x8b\x66\x26\xf1\xc4\xb0\x43\x0a\x54\xf3\x96\x58\x62\x4e\x66\x35\xfe\xfc\x98\xfe\xe8\xfc\x3e\x1c\xc7\xff\x3d\xd4\x20\xde\x9d\xa1\x1a\x62\xfc\xae\x0e\x0c\xb4\x54\xfc\x6f\x7d\xf0\x39\x54\x29\x1d\x26\x20\x2f\x1b\x18\x8b\x65\x7b\x3b\xae\x07\x38\x94\x49\xb7\x5e\x67\x42\x2f"}, +{{0x74,0x96,0x59,0x96,0x26,0x8c,0xdc,0x4c,0x09,0x22,0x0b,0xd3,0x1c,0xe0,0x7b,0x21,0x7a,0x03,0x82,0x6e,0xe9,0x81,0xfa,0x89,0xf3,0xa2,0x35,0x9c,0xed,0x09,0x5e,0xf1,},{0x40,0x96,0xd0,0x27,0xc1,0xc5,0xee,0x4c,0xbf,0xc0,0x4b,0x9d,0x53,0x41,0x74,0x02,0x9f,0xdb,0x50,0xcf,0x56,0x10,0xd3,0x02,0x1e,0xf9,0x33,0xb4,0xca,0xf3,0x39,0x85,},{0x8c,0x66,0x28,0x34,0x43,0x17,0xa6,0x3a,0xca,0x6f,0x78,0xcf,0xae,0xa9,0x65,0xb3,0xaa,0x55,0x22,0xce,0x91,0x41,0x95,0x14,0x1c,0x08,0x87,0x0a,0x1b,0x8d,0xac,0xf3,0x4b,0x79,0xc7,0xab,0xc6,0x93,0xcd,0x9e,0x5e,0xbe,0x1a,0x2e,0x86,0xf0,0x33,0x2d,0x20,0x48,0xdb,0x3c,0xbd,0xef,0x01,0x68,0x79,0x62,0xd6,0xdf,0x24,0x9e,0x38,0x00,},"\x45\xb2\xf0\x64\x61\x5b\xf7\x74\xfc\xe9\x7f\x51\xc4\x64\x68\x5d\x7b\x3e\x4f\xef\xff\x92\x31\x24\x0a\x71\x9b\x3b\x06\x21\xcd\x4a\xd8\x33\x05\x67\x5c\xd6\xea\xae\xbf\xf7\x91\x00\x0b\x0b\x1f\xa3\x1d\x82\xd8\x18\x1b\x7f\xe5\x7c\x5e\x00\xce\xc5\x6f\xf9\x02\x2e\x9c\xe8\xdb\x66\x35\x6e\x40\x8e\x3e\xe2\x62\xfe\x62\x77\x89\xe6\x55\x35\xef\x1a\x63\xe8\xfe\xc9\x33\xbe\x3d\xee\x34\xd2\xfa\xcd\xb8\x92\x8c\xc4\x56\xab\xf2\xf3\xe8\xca\xb4\x7e\xff\x1c\xa4\x2e\x8b\x0e\x48\xd2\xc7\x3e\x7b\xcc\x5d\xe3\xf1\x05\x6f\xc5\x23\xdf\xef\x6b\x00\x23\xf3\x28\x89\xed\x39\x4e\xed\xa0\x32\xab\xf6\xbc\xaa\xda\xa7\xf3\xee\x74\x11\x87\x60\xab\x6d\x91\xdf\x52\x8b\xdc\x58\x07\x97\x2c\x85\xfa\x7c\xb5\x6e\x38\x7d\x73\x32\xe7\x79\xe5\x2d\x0d\xd7\xdb\x0c\xfb"}, +{{0x0a,0xbf,0x06,0x9c,0x08,0xb2,0x69,0x1c,0x3a,0x26,0xf7,0x9d,0xc8,0xed,0x05,0xcb,0x71,0xd2,0x20,0xff,0x78,0xf3,0xa5,0xc5,0x78,0x0a,0xe9,0xda,0x18,0xe4,0x56,0x43,},{0x9e,0xf3,0xb5,0xcc,0x01,0x6c,0xc8,0x2d,0xbd,0xda,0x70,0x57,0x66,0xaa,0x44,0x8b,0xd6,0x1f,0xa1,0xaa,0xf1,0x17,0x0e,0xfe,0x91,0x49,0xda,0xa9,0xfe,0x64,0xa1,0xae,},{0xc7,0x56,0x6f,0xb3,0xb4,0xd8,0xde,0xf6,0x67,0xe0,0x40,0xf2,0x76,0xd3,0xed,0x98,0xd3,0x6d,0xff,0x46,0x01,0x26,0xa7,0x5b,0x4c,0xc2,0x10,0x03,0x86,0xbb,0x01,0xc6,0x42,0xf6,0xd8,0xde,0x7e,0x64,0x9b,0xe6,0xe0,0x81,0x8b,0x08,0xd7,0x7c,0xe6,0x0f,0x4e,0xe5,0xe7,0x71,0x7a,0x50,0x88,0x4b,0xde,0xe0,0x20,0x34,0xec,0xf1,0xcd,0x0c,},"\x0d\x05\x52\x91\xb2\xe8\x61\xea\xe1\x9e\xa0\xfb\x20\x69\xd8\xc9\xee\xf4\xf1\x34\x7f\x35\x76\xd7\x84\x11\xae\x7c\x0b\x1c\x1c\xaf\x31\xfd\xe7\x36\xdc\x8a\xcc\xac\xb6\x62\xdf\x76\xb6\x20\xb6\x2c\xe9\x0b\x9f\x92\xc8\x33\x09\x12\x86\x21\xd0\x57\xcf\x84\x58\x05\x94\x90\x88\xe9\x38\xdd\xbc\x3d\x41\xc5\xe5\x54\x1f\xec\x82\x98\x68\x7a\xd2\xf7\x9a\xcd\xa0\x1a\xa2\x15\xd2\x58\x21\x43\x6e\xac\x9d\x26\x87\x16\xd4\xcd\x60\x50\x26\x0c\xb4\xef\x6a\xad\xa4\x83\x5e\x07\x3a\x84\x58\x21\xff\x21\x1a\xe2\xba\xad\xce\xb6\xe5\x7f\x06\xf8\x83\x45\xed\xbf\x93\xbf\xdf\x54\xfb\x74\x12\x3b\x57\xc0\xfb\x4a\x79\x60\x8d\x8d\xb6\x74\x08\x89\xe1\x57\x33\x50\x77\x99\xf7\xa1\xfd\x30\x17\xbc\xd7\x7b\x28\xa2\xbb\x6c\x91\xec\xd1\x54\xe9\xc5\xa5\xff\xa0\xeb\x62"}, +{{0xf3,0xfd,0x5e,0xc5,0xe2,0x30,0xb6,0xda,0xd1,0xac,0x3d,0x3a,0xeb,0xad,0xc7,0x86,0x3f,0xf8,0x9d,0xe2,0xa1,0x31,0x7f,0x42,0x4d,0x15,0x98,0x9a,0x3e,0xfb,0x0a,0xfd,},{0xf9,0x9e,0x5d,0x5e,0xee,0xae,0xd1,0x20,0x5c,0xfb,0x5c,0x2c,0xc4,0xe5,0xe9,0xf6,0xb4,0xe7,0xf6,0x41,0x29,0xf8,0x60,0x10,0x4c,0xa6,0x24,0x4e,0xb9,0xfe,0xb5,0x64,},{0x44,0xb0,0x12,0x46,0x63,0xad,0xb0,0xc7,0x3a,0xed,0x49,0xf7,0x34,0x03,0x46,0x1f,0xcb,0x19,0x11,0x1b,0x0b,0xa1,0x7a,0xa9,0x96,0x56,0x6f,0x47,0x7e,0x37,0xd5,0x24,0xb0,0xe1,0xf1,0x07,0x61,0x2f,0xc5,0x2a,0x7c,0x76,0x7b,0x18,0x1f,0xbf,0x4d,0x62,0x9b,0xdd,0xc0,0x8f,0x30,0x58,0x4d,0xec,0x61,0x24,0xc5,0xd3,0x9d,0x42,0x31,0x02,},"\x71\xf2\x89\x73\xed\x3d\xf0\x59\x45\xfa\x0b\xdb\x23\xe9\xbe\xca\x65\x1d\x3e\xe6\xbf\x9f\xa4\x5f\xfd\xc6\x06\x1e\x42\xfa\x2e\x8d\x76\x23\x5f\x0e\x9e\x2d\xaa\x65\xe5\x26\x31\xfc\x3b\xea\xd3\x3d\xa0\x55\xbb\x49\x2e\x47\x58\xe5\x98\xa0\x30\xa3\x3b\x3c\x40\xb3\x43\x71\x45\x9b\x23\x3c\xcc\x04\x3c\xcc\xc3\xa3\xcb\xce\x54\x9e\x20\xe0\xb2\xb4\x33\x05\xb6\x4a\xec\x66\x1a\xad\xba\x65\x56\xb1\x7d\x76\xe3\xbb\xed\x62\xc4\xa4\xea\xc4\xf8\x86\x03\x99\x67\x52\xd2\x36\x3c\x8d\x4a\x27\x89\xd1\x28\xf6\xe9\x59\x94\x5c\x68\xc3\x01\x46\xd1\x94\xcc\xb6\x83\x9e\xc6\x53\x44\x60\x16\x52\xc1\x8b\x00\x74\xe2\xbc\x76\x68\x31\x16\x97\xd9\x60\xc7\x06\x65\x97\x92\x4d\x70\x4d\x02\xa0\x19\x3f\xaf\xbf\xdf\x57\x1e\xe0\xdf\xe4\x14\xdc\x2f\x52\x89\x69\x12\xbc\x32"}, +{{0x73,0x8f,0x13,0x10,0xa4,0xe0,0x8f,0x91,0x7a,0x0a,0x5c,0x1f,0xba,0xf4,0xef,0x72,0xf9,0x5e,0xe6,0x2f,0xcd,0xed,0x50,0x86,0x8a,0x3d,0xaf,0x98,0x85,0x6a,0x44,0x8d,},{0x42,0x27,0x2c,0x2c,0x8b,0x08,0x47,0x0e,0xe5,0xdd,0x8a,0xf8,0x84,0x9c,0x01,0xb7,0x50,0x8d,0x3a,0x3c,0x65,0xb0,0x33,0x0e,0x69,0x5c,0x84,0x1d,0x5d,0xcc,0xb2,0xf5,},{0xce,0x1e,0x35,0x77,0xb6,0xa2,0x10,0x16,0xb9,0xdd,0x0b,0x51,0x7b,0xaa,0x0c,0xcb,0x10,0x7b,0xc1,0x99,0xb8,0xbb,0xae,0xf6,0x8f,0x95,0x0c,0x8e,0xd5,0x80,0x13,0xc8,0x53,0xb4,0xd3,0x38,0xee,0xdc,0x67,0x50,0x79,0xab,0x13,0x90,0x46,0x2f,0xfe,0xfa,0x6a,0x95,0x9b,0x04,0x3f,0x8b,0x56,0x51,0xc6,0xca,0x37,0x5c,0xe0,0xb4,0xa4,0x03,},"\xf0\xe7\xef\x67\x82\xd0\x4c\x69\x43\xb1\x9e\xb6\x6f\xf6\x22\x6b\x73\x6e\x3b\x09\x40\xc0\x9b\xb1\x26\xbf\xc4\xc4\xca\x7a\x5e\x70\x16\xc2\x86\xb7\xbf\xd7\x3a\xa6\xa7\x9a\x96\x03\x1b\xc8\x1c\xb5\xda\x68\xce\xc7\x1a\x6a\x0d\x39\x78\x0c\xbe\x6a\x0c\xd4\x77\x4d\x3a\xa0\x6a\x88\x16\x10\x44\x4a\x8c\x9d\x19\x10\x22\x94\xe5\xf6\x35\x18\x7a\xa6\xf4\x8d\x11\x91\x2c\x70\x94\xb3\x88\x33\x02\x8d\x57\x0c\xb1\x10\xdb\x60\x62\x5b\xb1\xbd\xc3\x7a\xff\xa2\x5e\xa3\xc8\xf8\xdb\xfc\x25\x14\xf4\x36\x5c\x62\xb2\x98\x9a\x66\xd2\x7c\x80\x38\x4e\x74\xae\x5f\xba\x8c\x1c\x2a\xf9\xc7\x2c\x49\x71\xe6\x4f\xa6\xa1\xdc\x25\x17\xb3\x1e\xa5\x7c\xcb\x08\x15\xa7\xfe\x2d\xa0\xf1\x46\xca\xa0\x84\x31\xd2\x5d\x15\x16\x62\xd9\xd2\x6e\x95\x22\x9d\x0c\x62\x82\x36\x64\x12\x3c"}, +{{0x88,0x41,0xd2,0x2a,0xde,0xd6,0x9c,0x13,0x1e,0xf5,0xee,0x0a,0x10,0xab,0x0a,0x9b,0x77,0xcb,0x75,0x4e,0xde,0x8d,0x25,0x7a,0x53,0x72,0x72,0x6e,0x2b,0x49,0x9c,0x6e,},{0x71,0x5e,0xcc,0xa6,0x36,0x81,0xbc,0x6e,0x9e,0x31,0xd1,0x88,0x48,0x90,0x2f,0x4d,0x96,0xfe,0xaf,0x43,0xb9,0x5d,0x00,0x86,0x42,0x90,0x3b,0x17,0x63,0xbc,0x9f,0xb8,},{0xbb,0x2b,0xab,0x70,0x03,0xf1,0x31,0x1b,0xe9,0xb8,0xc8,0x83,0xfc,0x4f,0xd5,0x28,0xad,0xfd,0x51,0xa9,0xc9,0x9d,0xb3,0xdc,0xa8,0xda,0x0f,0xca,0x95,0x8d,0xa1,0x9a,0x10,0xeb,0x22,0x33,0x26,0x67,0xb1,0xa0,0x06,0x5d,0x3d,0xbc,0x0d,0x06,0x26,0x9a,0x12,0x59,0xb6,0xa8,0x90,0x48,0x4a,0xa2,0x14,0x3a,0x52,0x69,0x5f,0x14,0x5b,0x0a,},"\x08\x7c\xa6\xbe\x2a\x95\x0c\x02\x4b\x3e\x74\x67\xfe\x00\xa7\xd3\x64\x55\x5d\x5d\xc6\x77\x0f\x5e\xbd\x26\x06\x42\x52\x5b\xd3\xc0\xf9\x65\xdb\x36\xd7\xb2\x29\xa5\x74\x21\xee\xc6\x4e\x4d\x99\x1c\xdd\xe5\x91\x23\x03\x44\x70\x55\x3f\x4e\xb0\xbe\x81\xad\x29\x36\xc8\xca\x26\xbc\xab\x4e\x5d\x79\x04\x0e\x29\x79\x87\x28\x60\x16\x84\xa4\x68\x32\x3c\xf3\xba\xae\x4d\x94\x8d\x0a\x1f\xd9\x05\xef\xfe\x16\xdc\x44\x64\x20\x88\xdf\x53\xf6\x38\x8b\xc4\x80\xed\xf4\xaa\x20\x7d\x0e\xd1\x61\xed\xa3\x45\x71\x2b\x4c\x00\xcb\x05\xfc\xf6\x35\xec\x25\x88\x78\x5b\xfb\x8a\x27\xcd\xc2\x89\x96\xa1\xdb\x3e\x67\x87\x02\x33\x93\xc0\x75\xd8\x3c\x90\x38\xfe\xd7\x89\x9c\x55\xfe\xc3\x07\xde\x32\x49\xc1\x4b\xda\x49\xe8\xb8\x95\x86\x09\x42\xc3\x6d\x64\x0b\xb8\x93\x77\x91\x42"}, +{{0xc0,0x21,0x35,0xe7,0xb6,0x5a,0xac,0x72,0xf6,0x3c,0x32,0xbf,0x5b,0xef,0x5b,0x68,0xc7,0xf3,0xb8,0xed,0x56,0x20,0x8e,0x59,0xe4,0x75,0x20,0x70,0xe9,0xd0,0x70,0x95,},{0xdc,0xf6,0x00,0xf2,0x44,0x03,0x7a,0x75,0x20,0x3a,0xe1,0x1a,0xc3,0x16,0xe8,0xdb,0xe9,0x98,0x6f,0x0d,0xce,0x23,0x47,0x39,0x39,0x33,0x4b,0xf5,0xce,0xa4,0x8b,0x0d,},{0xdd,0x5c,0xba,0xe4,0x79,0xeb,0x5e,0x22,0x95,0x74,0xc2,0x1e,0xc3,0xbe,0xd9,0x11,0x11,0x3a,0x57,0xa1,0x91,0x6d,0x33,0x13,0x45,0x75,0x15,0xd5,0x5c,0xc5,0xb6,0xe6,0xeb,0xc5,0x2c,0x93,0xf8,0x21,0xd1,0x39,0x88,0xdb,0xba,0x8d,0xf5,0x09,0x6d,0x55,0xff,0x9c,0x39,0xe7,0xf9,0xd5,0x61,0xcb,0x58,0x93,0x0c,0x96,0xa7,0xa5,0xd6,0x0b,},"\x86\xd9\x49\x13\x50\xd2\x56\x6e\x70\x8e\xd3\x56\x18\x5d\x61\x0c\x73\x46\x5b\x2a\x5c\x70\x12\x91\x99\x58\xaf\x2c\xf7\x6a\xf9\x95\x23\x0d\x36\x0d\xe4\x00\xb7\x13\x71\x70\xdd\x08\x35\xf1\x0f\xcb\xec\x22\x4e\xe4\xe4\x2c\x7d\x1c\xeb\xb7\xf5\x80\xfe\xa8\xed\x62\x23\x16\x3b\xac\xdd\x19\x23\xa5\x72\xcb\xb6\xdc\x26\xca\x8b\x17\xad\xe6\x8c\x6d\x28\x08\xc4\xca\x1e\xca\x28\xea\xe9\xa1\x45\xf6\x8d\x40\x79\xd8\xd5\x9d\x14\x0e\x95\x82\x28\xe7\xe9\x95\x20\xe3\x42\xdb\xd7\x45\x7a\x91\x59\x74\x0f\x48\xbd\xc2\x7b\x93\xbd\xab\xeb\xa4\x65\xcb\xf0\xc8\xdf\x5e\xf2\xc0\xf9\x38\x6e\xeb\xe6\x56\xf5\xd7\x49\xd5\xf9\x14\x7f\x52\x52\x66\x91\x0d\x7b\x80\x39\x6a\x90\xbe\x5c\xc1\x88\xa9\xa9\x45\xf9\x3e\x75\x3f\xc9\x9b\xaf\xa1\x8e\xe0\xa6\xdf\xf7\x9b\xf8\x48\x48\x98\xef"}, +{{0x15,0x4a,0x47,0xeb,0xa1,0xb8,0xc3,0x83,0x62,0xea,0x61,0xfa,0xeb,0x0c,0x0a,0xd7,0xe6,0x1e,0x41,0x2a,0x3c,0xba,0x46,0x88,0xaf,0x0d,0xb2,0xa4,0x87,0x20,0x8b,0x1c,},{0x16,0xde,0x2c,0x89,0x4a,0x50,0xcb,0xd4,0xca,0x90,0x41,0x9a,0x4c,0xa6,0x49,0x42,0xcb,0x14,0xbd,0x33,0x5c,0x5d,0x3f,0x4a,0x53,0xe2,0x39,0xc2,0x80,0xbd,0xa7,0x25,},{0xf4,0xb6,0xeb,0x1a,0x8d,0x95,0x0e,0x88,0x7f,0xd2,0xf3,0x0f,0x70,0xa2,0x3b,0x41,0x87,0x14,0x95,0xbf,0xa5,0xb8,0xa4,0xad,0x39,0x96,0xcd,0x9b,0xf5,0x1e,0xb7,0x42,0xe0,0x7f,0x4c,0x4d,0x2d,0xa4,0xb0,0x1a,0xb0,0x87,0x36,0x7a,0x50,0xe2,0xb6,0x5b,0x3c,0xef,0x51,0x4e,0x40,0xd8,0x37,0x54,0x0b,0x8c,0x89,0x96,0x64,0x85,0x91,0x0f,},"\xbf\x60\x7e\x8b\x6e\x14\xd9\xc8\xac\xd9\x68\x15\xaf\x0c\x03\x5a\xc7\x3c\x41\x04\xc9\x37\x86\xcc\xc1\xc9\xf8\x59\x39\x5d\xd7\x81\x90\x03\x20\xeb\xf3\x56\xaa\x99\x1c\xdc\x9f\x50\x3f\xce\xe9\xf8\x36\x75\x88\x8a\x7d\x59\x20\x02\xd2\xa5\x4a\x57\x3a\x96\x99\x4b\x3f\xa8\x65\x53\x8c\x61\x7e\xd8\xad\x1f\xf6\x20\x18\x28\x8a\x67\x4f\x44\x9b\xe0\xaa\xb5\x22\x2f\x74\xc4\xfd\x47\x5e\xd6\xa8\xdf\xb2\x7f\x45\x28\x7b\x22\xb2\xb6\xc3\xbd\x15\x17\x9f\x26\x7d\x15\x7d\x7d\x8a\x41\x59\x67\x9b\xe8\x5b\x25\xc2\xbb\x2b\xa8\x50\xaa\xed\x9a\xe3\xae\x57\x1b\xe4\xf7\x58\x36\x32\x9c\xf3\x6f\x41\x2c\x1c\x80\xf1\x41\x3b\x76\x61\xea\xb4\xa8\xe1\x1b\x60\x24\x24\x4f\xc6\x23\x23\xff\x02\xe3\x8a\xce\xb1\x73\x7b\xd4\x74\xbf\x1e\x98\x01\x5d\xbc\x78\x8b\x02\x7b\xbe\x21\x7c\xf4\xe7"}, +{{0xd3,0x02,0x84,0x31,0xce,0x2e,0xef,0x73,0xbd,0x94,0x0a,0xb8,0x4c,0xa2,0x9f,0x13,0xfb,0x26,0x43,0x6a,0xa2,0x5e,0x1b,0x7b,0xf2,0x6c,0xb3,0x3f,0x17,0xfd,0xf8,0x17,},{0x63,0xdf,0x20,0x3e,0x28,0x60,0xba,0xc4,0xd3,0x52,0xe7,0x22,0xc1,0xc9,0x1f,0xe3,0x77,0x6e,0x1c,0xbc,0xae,0x85,0x53,0xa4,0xf1,0x98,0x90,0x26,0x0b,0xf0,0xe4,0x57,},{0xce,0x97,0x29,0xa9,0x6c,0x3e,0xd2,0x89,0x43,0xb2,0x78,0x39,0xc7,0x33,0x82,0xec,0xd5,0x72,0x96,0x0c,0x1f,0x9e,0x90,0xc5,0xef,0xf9,0xdd,0x49,0x9f,0xf4,0x8f,0x17,0xd2,0x5e,0xdd,0x12,0x68,0xef,0xfe,0x41,0xee,0x6a,0x81,0xce,0x48,0xd8,0x4d,0xe5,0x13,0xdf,0x9c,0x41,0x44,0x26,0x21,0xb2,0xf5,0x49,0x1e,0x34,0x6b,0xe1,0x8c,0x04,},"\x08\x63\x35\xd6\x12\x75\xd1\x68\xea\xac\x05\x40\x47\x7f\x50\xd4\xb1\x5f\x9e\x50\xb9\xbe\x69\x39\x21\xed\x54\xa9\x94\x1b\xc4\x06\x43\xcd\xa6\x2e\x1d\x80\x5d\x02\x50\xa8\x11\x46\xbd\x5f\xe2\xd3\x9e\x81\x44\x4d\x21\xe2\xb2\x1b\x03\x1c\x11\x13\x06\xca\xcb\xf5\x27\x17\xf6\xfb\x4c\xd3\x41\x6f\x12\x15\xf8\xdd\xdc\xed\xd2\xf0\x09\x6b\x0f\xcf\xa0\xa6\xcc\x2c\xde\x7a\x2b\xab\x7f\x1e\x32\x79\x0b\x53\x61\xdf\x36\x71\x42\x4c\xc7\x22\xf2\x31\xbf\x71\x89\x5b\xcd\xcb\x7b\x22\xee\x07\x4e\x8f\xb4\xa9\x67\x85\x04\xe7\x35\x36\x6c\x17\x2f\x07\x63\x7b\x7a\x93\x14\x9b\xb2\x1f\x38\x88\x33\x78\xa1\xdb\x27\x3f\xc2\x32\x39\xe3\x53\x37\xf9\xce\x56\x6d\x8d\xdf\x3b\x31\x33\xca\xd7\xf2\xce\x81\xed\xb5\x03\xce\x1d\x27\xc5\xa6\x57\x16\x0b\x78\xdc\xa9\xae\xae\xa3\x79\xbe\x9c\x85"}, +{{0xee,0x89,0x85,0xdc,0x27,0x50,0x44,0x40,0xa8,0x75,0x8d,0x4c,0x53,0xe4,0x22,0x52,0x15,0x79,0x7a,0x00,0xcd,0x86,0x31,0xd5,0x9b,0xd9,0x3b,0xc6,0x6f,0x37,0x3d,0x5e,},{0xcd,0x64,0x7b,0xb0,0x65,0x69,0x3d,0x48,0x65,0x89,0x15,0x6a,0x9f,0xa2,0x61,0x43,0x75,0x34,0xdc,0x86,0xf4,0x6f,0x72,0xd0,0xa8,0x00,0x39,0x9a,0x7a,0xf0,0x10,0xf7,},{0x5b,0xd6,0x0a,0xd5,0xe9,0xba,0xd9,0x93,0x2c,0xa9,0xc7,0x5f,0x23,0x1a,0x76,0x88,0x9a,0xe7,0xa8,0xb8,0x64,0xb9,0x1d,0x1f,0xcb,0xa5,0xc5,0xd4,0xbf,0xa1,0xd9,0x28,0x38,0xad,0xb9,0x74,0x84,0x2a,0x07,0x10,0x77,0x9b,0x3e,0x30,0x94,0x04,0x49,0x09,0xe9,0x2c,0x7c,0xf0,0x46,0xce,0x51,0x9f,0x4c,0x68,0xe8,0xf1,0x9e,0xc0,0x3c,0x02,},"\xf2\x22\x04\x85\xad\xdf\xeb\xce\x02\xa8\x33\xac\xa3\x33\x81\xd1\xdf\x91\x7e\xd6\x09\x95\x0e\xd2\x4f\x85\xe3\xb0\x2b\x2b\x99\x4b\x4d\x93\x97\x84\xe3\x32\xf4\x10\x64\xc8\xb4\xa2\x63\x0a\xb3\x69\x61\x74\x2a\xa1\xcf\xfd\xcb\x08\xc1\x44\xee\xae\xde\xaf\xd4\x8b\x5d\xbe\x96\xbf\x24\x35\x0e\x14\xfd\x68\x28\x6b\xc0\x8e\xea\xef\x8b\xc6\xad\x9e\x19\x5d\x14\x84\xaf\xcd\x30\xaf\xa8\xce\xd4\x84\x81\x26\xd5\x6c\x81\xb4\x3c\x27\xa5\xdb\xbd\xec\x1a\x50\xc1\x10\x62\xce\x21\xc6\x1d\x86\x0c\x25\xa8\x62\xfb\xb7\x5c\x3b\xd5\x1c\x8d\xc0\x76\x36\x66\x86\x69\xbb\xf7\x51\xea\xca\xcc\xb3\xb5\x1d\x2c\x0d\x41\x40\x31\x6c\xfc\xe2\xeb\x18\xd2\x90\x8c\xec\xd5\xa1\x88\x67\x9b\xc5\xf5\xde\x29\x0f\x54\x8e\x7e\xbc\x57\xd4\x1b\x58\x9a\x24\xce\x88\xee\x48\xd9\x7e\x8d\x0c\x7c\x76\x99\x60"}, +{{0x80,0xdf,0xe2,0xbf,0x73,0x87,0xba,0xd4,0x65,0x4e,0xb0,0x76,0xf8,0xda,0xe9,0x59,0x51,0x63,0xe4,0x01,0x27,0xf5,0xdf,0x49,0x2d,0xad,0x7d,0xf0,0x4c,0x72,0x21,0xc4,},{0xd1,0x78,0x3c,0xee,0xb9,0xcf,0x8e,0x4d,0x07,0x76,0x4c,0x47,0x3f,0xa4,0x06,0x1b,0x82,0x74,0x39,0x71,0x03,0xf2,0x07,0x6d,0x70,0x32,0x49,0xd7,0x58,0xb8,0xfb,0xd5,},{0x27,0x27,0x9e,0x3c,0xdc,0xb0,0x3e,0xf5,0x57,0xa5,0xde,0xfc,0x2f,0x6c,0x58,0x12,0x8a,0x6d,0xc3,0xf8,0xb0,0x38,0x59,0x58,0x01,0x4e,0x70,0x9c,0x1f,0x61,0xb0,0xae,0x6b,0x40,0x35,0x76,0xf0,0xe4,0x54,0xd5,0xe4,0xc6,0x4c,0x17,0x31,0x38,0xee,0x4b,0xbd,0x5f,0xe7,0xb6,0x0d,0x06,0xc5,0xab,0xe2,0x3f,0xe9,0x9e,0xe3,0xb4,0x6a,0x00,},"\xaa\x09\xd7\x84\xbb\x09\xdc\x99\x99\x31\xeb\xb4\xc0\x0e\x42\x4c\xef\xec\xa1\x04\x81\x8d\x8e\xaf\x06\x61\xf0\x97\x28\xad\x02\x5e\xf4\x73\x93\x21\x05\x71\xf1\x74\x04\xe9\xaa\x6d\x8c\xbd\x5f\xd8\x8c\xd7\xdf\xb8\xe2\xe8\xa1\x08\xc0\x5d\xe2\x06\xf3\x40\x82\x34\xa3\xb4\x63\xdb\xe7\x1a\x07\xd0\x55\x87\x32\x45\x24\xb7\x32\x6e\xe7\x9d\x33\x48\xdd\xbe\xd7\x87\x1b\x86\xfc\xb4\x88\x03\x1d\xc9\xea\x93\xf6\xb8\xd7\xfd\xa6\x23\x93\x48\xa5\x62\x44\x4f\xaf\x1e\x72\xd3\x1a\xf3\x54\x43\xe9\xdf\x53\xe7\x62\xf3\xe5\x6b\x48\x66\x8f\x97\x84\xb3\x36\x8a\xb2\x78\xa4\x8e\xf4\x54\x6a\x26\xcf\xad\x0d\x0a\x51\x61\x69\x8f\x26\xee\x8d\x34\xfc\x2b\x3d\x6d\xfb\x93\xb0\x09\xac\x29\x6f\x6a\xfe\x48\x7e\xe3\x35\xea\xc9\xf0\x2c\xfc\xae\x5f\xcb\xd1\xa1\x6b\xa4\xe7\x1b\xe1\xb1\x12\x56\x2f\xc2"}, +{{0xda,0x1f,0x86,0x85,0x42,0xcd,0x7c,0xce,0x7a,0x5c,0xa3,0xfa,0x3c,0x24,0x08,0x1b,0x4d,0x23,0x44,0xb2,0x1a,0x15,0x7f,0x02,0x64,0xa3,0x47,0x13,0x2d,0x19,0x65,0x9d,},{0xcb,0x3a,0x25,0xa5,0x3f,0x27,0x2e,0xa8,0x13,0x80,0x44,0x68,0xd6,0x50,0x0e,0x96,0xa1,0xea,0xf8,0x22,0x70,0x5b,0x77,0x90,0xa8,0xac,0x3e,0x98,0xcc,0x4e,0x52,0x4b,},{0x75,0xc5,0x17,0xad,0xe4,0xf0,0x8d,0x77,0x46,0x30,0x57,0x43,0xd1,0xa7,0x76,0xc3,0xc5,0x5e,0xb5,0xee,0xdf,0xdf,0xcb,0x5e,0xb1,0xd5,0x63,0x4a,0x1b,0xda,0xf7,0xa4,0xb8,0xd2,0x41,0x87,0xd6,0xc8,0x85,0x0e,0x3c,0xed,0x65,0x67,0xa0,0x3c,0x4c,0x59,0x38,0x9a,0x4c,0xf4,0x71,0x14,0xce,0x54,0x73,0x16,0x0f,0x23,0x05,0x46,0xe6,0x0d,},"\xc6\x98\x7e\xf3\x80\xd5\xd0\xe7\x41\x96\x44\x3a\xaa\x3a\x32\x35\x6c\xbc\x02\x63\x6c\x5a\x4b\x6d\x62\xa8\x11\x4b\x21\x11\xbc\x1a\xbd\xdd\x9e\x44\xb3\x67\x2c\x18\xb5\x8d\x4e\xf5\x91\xaf\x45\x62\xe0\x20\x04\x9f\x8e\x12\x74\x68\x8e\x1f\x8e\x52\x96\xd2\xf9\x25\x2e\x7f\xc8\x4c\xd1\xd0\xc5\x8e\x98\xf0\xf1\x60\x53\x0a\xa2\x2c\x87\x1e\xef\x65\x2e\x71\x97\x4c\xe9\x1b\x4a\x65\xfc\x25\xfd\x09\xfa\x1b\x6c\x32\x08\x6e\x98\xec\x70\x8d\x9a\xbc\xb1\xd9\xcc\x8e\x1a\x08\x9e\xd8\xdb\x22\x06\xee\x95\x70\x23\x6a\xd6\x9b\x3d\xe6\x82\x18\x62\xfd\x2c\x70\xcd\x83\xa3\x2a\x68\xb0\x48\x62\x29\x55\x3d\x92\x8d\xe4\x8d\x03\xa1\x04\xe8\x73\x81\x96\x4a\xbe\xa7\x66\x83\x97\x6d\x52\x7c\x84\x16\x3a\x12\xee\xe0\xa5\x59\x86\xcf\x14\x31\xe9\xc8\x6c\xba\x81\x82\xca\x94\x68\x9b\xac\xd1\x65\xfb\xce"}, +{{0xf1,0x3d,0xae,0xc0,0xef,0x33,0xdd,0xd1,0x33,0xc7,0xd2,0x44,0xd1,0x0f,0xd2,0x7d,0xdb,0x23,0x70,0x52,0x80,0xff,0x5f,0x18,0x15,0xf0,0xf6,0x56,0xd8,0x36,0xfe,0x84,},{0x2d,0xc7,0xf1,0x36,0x7d,0xe6,0x72,0xc5,0x1e,0x00,0x5c,0x74,0xf8,0x76,0xf9,0x82,0x59,0x39,0x96,0x87,0x3a,0xcb,0xa0,0x79,0x29,0x27,0x34,0xc2,0x09,0xc2,0xb1,0x11,},{0xdb,0x77,0x18,0x33,0xf7,0xfd,0xba,0xcd,0xab,0x2b,0x5c,0xc8,0x0e,0xed,0x50,0xaf,0xdf,0x13,0x78,0x3b,0x7f,0xe5,0xe9,0x03,0xd5,0xdb,0xb4,0xc2,0xe5,0x35,0x31,0x6a,0x6e,0xef,0x4c,0x34,0xf0,0x04,0xd2,0xb9,0xa4,0xe2,0x70,0x0b,0xd6,0xe2,0xac,0xdd,0x56,0x4c,0x3c,0x80,0xcc,0x68,0xa3,0x03,0xf5,0xfb,0x09,0x1c,0xb4,0x34,0x0f,0x0a,},"\xec\x02\xff\x18\x04\xb2\xb3\x09\xaf\x31\x58\xb6\x62\x72\xa1\x4a\x3a\xad\x83\xc4\x1a\x71\x98\x46\xf7\x08\x8c\xa9\x79\x2a\xf5\x75\xc7\x89\x13\xc4\x32\x75\x9f\x0b\x9a\x74\x8b\xdc\x55\x68\x49\x6e\x41\x65\x8c\xc1\xcd\xb8\xda\x6c\x91\xd0\x7c\x3e\xc2\xf4\xaf\x50\x42\x49\xb9\x96\xaa\x00\xc0\x07\x1c\xdf\xa7\x93\xf8\x2d\x0e\xc5\xd2\x67\x26\x2f\x51\x8f\xc0\x29\xb8\x8e\x20\xb6\x20\x1f\xb9\xe0\x5a\xbd\x3f\x95\x24\xc5\xda\x2f\xa8\x97\x8f\xf2\xef\xd4\x81\x20\xcf\x00\x82\x2d\x1b\xee\x90\xdf\x81\x61\x25\xd8\xed\xc0\xcf\xb5\xde\x66\xd1\x6b\xe6\x38\x96\xa4\x12\xa6\x2b\x03\x1b\x71\x18\xac\x13\xfe\x2c\x9f\xaa\x6b\x1a\x33\x42\xf9\xcc\xf7\x88\x41\x66\xcf\x48\x9a\x84\xde\x26\xb5\xce\x5b\x21\x85\x6a\x3a\xf2\x89\xbc\x66\x22\xc0\xaa\xb9\xf2\x14\x2d\x39\x3f\x5d\x4b\x23\x67\x79\xdb\xb0\x66"}, +{{0x42,0xdc,0x16,0xc5,0x7f,0xb6,0xf1,0x28,0x94,0x5f,0xa1,0x01,0xe0,0x5b,0xbf,0x54,0x8e,0xf7,0xd9,0x77,0x26,0xb6,0x92,0xfe,0x40,0x40,0x69,0xcc,0x57,0xcc,0xef,0xa0,},{0x0a,0x1b,0xa5,0xdf,0x52,0x39,0x96,0xf9,0x54,0xb3,0x4d,0xdc,0xfa,0xba,0xd3,0xf3,0xde,0xe2,0x1a,0x5f,0xa7,0xa4,0xce,0x32,0x2d,0x21,0x6b,0xd8,0xcc,0xaf,0x43,0x8c,},{0xc7,0x59,0x77,0xe8,0x3b,0xcf,0xe9,0xdf,0x72,0x92,0xa8,0x60,0xed,0x97,0x25,0x55,0xb5,0xc2,0x44,0x16,0xfd,0x4b,0x7e,0xe3,0x28,0x53,0x88,0xfa,0x5b,0x14,0x47,0x60,0x8e,0x4a,0x34,0x78,0x13,0xcf,0xe0,0x93,0x51,0x2a,0x76,0x51,0xe4,0x22,0xe9,0x86,0x7d,0xb7,0xb9,0x7c,0x0b,0x08,0x67,0xf0,0xb8,0xc7,0xb7,0xf4,0xf0,0x2c,0x31,0x0d,},"\xf2\x71\x4c\x23\xa3\xa6\xfc\x11\xad\x15\xc9\x80\xb7\x35\x0f\xc8\x42\x17\x87\x76\x61\x18\x80\x55\xff\x75\x0d\x82\xc4\x9c\x5f\xef\x7b\xc8\xe6\xaa\xc5\x74\xa1\xb7\x9a\x3f\x26\xd1\x69\x69\xc0\xf4\x06\xee\xab\x3e\x9e\x12\x85\x0a\x55\x70\x97\x45\xe3\x0d\xff\xa6\x2a\x69\xdf\xb2\xb6\x4b\x3c\x1b\xd2\xbc\x35\x86\xe2\x6d\x4e\xea\x71\x4d\x2a\x7b\x71\xcf\x79\xfb\x8f\xfb\xf2\xaa\xad\x00\xca\x3e\x4f\x2b\x6f\x50\x3c\xc1\xfe\xf2\xea\xb3\x65\x6f\xb4\x4f\x8d\x62\xa8\xdb\x8a\xb5\x8f\x39\x46\x93\x94\x9e\xea\x57\xfa\xfe\xcf\x00\x5f\x6e\xbf\x12\x87\xdb\xa4\xd2\xd6\x23\xc0\x2e\xa1\x71\xf5\x67\xe5\x26\xad\xd2\x07\x09\xeb\xca\xb9\x62\xf8\x3d\x98\xef\x66\x8e\xbd\x01\xef\x20\x48\x8b\x36\x65\xe3\xa4\x46\xfb\xfb\x13\xd3\x40\x50\x94\x2c\x74\x9b\xb2\xdf\xfc\x76\x63\x67\xfd\x45\x2e\x68\xe5\xb0\xc6"}, +{{0x90,0xb4,0x55,0xc6,0xbb,0x9c,0xec,0x83,0xe1,0x37,0x35,0x70,0x65,0x33,0x9d,0x03,0x05,0x25,0xd0,0xea,0x7f,0x5b,0x92,0x3a,0x2d,0x59,0x72,0xc3,0xc1,0x2a,0xa3,0x7b,},{0x5c,0xef,0x03,0x8c,0x16,0xbf,0xa4,0xb4,0xc9,0x23,0xa0,0xfe,0x70,0xcd,0x7f,0x25,0xc8,0xbc,0x83,0x7f,0xdf,0x5a,0x7e,0xfb,0x9d,0x95,0xf2,0x1b,0x96,0xbe,0x92,0x5a,},{0xc9,0x34,0x5e,0xec,0x2c,0x4a,0x0a,0xec,0x73,0x23,0x86,0x49,0x4a,0x69,0xa3,0xfc,0xe8,0xb8,0xa1,0xbe,0x36,0x6b,0xbe,0xd1,0x65,0x9f,0x13,0x1f,0xe9,0x7c,0xc0,0x37,0xfb,0x1b,0x7c,0x1b,0x68,0xb0,0xf3,0x02,0x39,0x45,0xd2,0x00,0x90,0xa0,0xcd,0x2c,0x15,0x53,0xa4,0x7f,0xae,0xc4,0xd6,0x6f,0xd8,0x16,0xce,0x12,0x11,0x68,0xf3,0x09,},"\xc6\x2c\xfd\xb9\xd2\x1e\xee\x6b\xe4\x7f\x30\x72\x7a\xae\xe5\x1f\x07\x03\x78\x9a\x43\x1d\x32\x22\x85\x33\x35\x02\x17\xa9\x3a\x18\x90\x06\x69\xc9\x59\x56\xf3\xf2\xae\x90\xdc\x74\x5a\x71\xe1\x83\x40\xd0\x58\xd1\x6b\x4c\x6f\xe3\x3b\x64\xaf\x8d\xad\x97\x3f\xe5\xdc\x02\xe8\x52\x07\x05\xc7\xa8\xbb\x3c\xcb\xe1\x83\x8c\x6c\x24\x93\x37\xf9\xb6\xa4\xc0\xe1\xf8\xa4\xe5\xd1\x03\x19\x6f\xa7\x99\x98\x92\x3d\x04\x22\xe9\xd0\x79\xa7\x2c\xc2\xa8\xf8\x6d\x65\x90\x31\xa6\x07\xd4\xcc\xa0\xb9\x47\xb3\xab\xee\xee\xf6\x4c\x28\xda\x42\x0d\x05\xde\x66\x5a\x55\x10\xfe\x55\xf7\x75\x98\xec\xad\x7f\xaa\x0a\xc2\x84\x80\x0b\x53\x82\x93\x94\xc4\xae\x90\xbe\x66\x67\x8f\xf0\x4a\xb4\x6d\xa2\x65\xae\x06\x40\x2d\x8c\x83\xca\xd8\x4d\x61\xa0\x51\xde\x02\x60\x55\x98\x88\xe7\x79\xf7\x4b\x72\xa5\xd7\x1c\x13\x2f"}, +{{0xdc,0x18,0x5c,0x2b,0xa0,0xb3,0x78,0xdf,0xe5,0xdd,0xa5,0x10,0xc3,0x2f,0xef,0xf5,0x35,0xca,0x2e,0x8a,0x02,0x43,0x4b,0x32,0x6e,0x01,0x58,0xbc,0x87,0x8e,0x88,0x48,},{0x33,0xd6,0xcc,0x05,0xa4,0x34,0xe4,0x19,0x28,0x0d,0x58,0x64,0xa1,0xaf,0x20,0x9a,0x2c,0x67,0x68,0x14,0xb7,0x0f,0x72,0xf8,0x14,0x1a,0xc7,0xe0,0x57,0x3e,0xe6,0x3e,},{0xf1,0xe4,0x45,0x14,0xd2,0xec,0xbc,0xc8,0xd1,0xa7,0xe8,0x4b,0xf5,0x84,0xce,0x73,0x18,0x35,0xe9,0x89,0x4f,0x88,0x97,0x4f,0x09,0x8d,0x45,0x6b,0x60,0x71,0x8f,0x57,0x5e,0xf4,0xd8,0x06,0x2f,0x21,0x82,0x50,0x42,0x50,0xcf,0x83,0xbb,0x2a,0xf2,0xa7,0x9b,0x1f,0x58,0xa6,0xa9,0x7b,0xd9,0x8d,0xa4,0x67,0x13,0x2d,0x7b,0xec,0x2f,0x05,},"\xe2\x76\xb1\x19\x12\xcc\xa5\xa8\x4b\xba\x65\x0c\x17\x2a\xef\x3a\x4d\x5f\x91\xac\x72\x29\x13\xbb\x89\x1a\x3a\xb0\x42\x4a\xb0\x7e\xa7\x09\xcb\x8b\xba\x3a\x3d\x11\xf8\x2f\x51\xc2\xaf\x01\x62\xa8\x2f\x72\x19\xce\x27\xb3\x5a\x30\x50\x7d\x53\x6a\x93\x08\x17\xe4\x0f\x85\xa2\x2a\x5a\x43\x2b\x94\xd1\x92\xc3\xc8\x91\x17\x77\xcf\xdb\x7f\xe9\x37\xa6\x75\x02\x77\x0d\x6d\x75\x75\x3d\x3a\xe8\x82\x29\xe0\x8f\x1e\xd2\x3b\x43\x28\xd8\x62\xac\x61\x86\x3c\x06\x3e\xa9\x84\x8f\x8a\xb9\x6a\x02\x13\xd7\xb9\x36\xc4\x8f\xe7\x54\x83\x6c\x98\x48\x78\x59\xd1\x99\xb3\xd9\x40\x39\x27\x16\xa1\xd5\x69\xe6\xc0\xcb\x1b\xa9\x18\x93\x2c\xf8\x85\x25\xe2\x56\xc8\xab\xb1\x1a\xaf\x0b\x45\x46\x55\xd5\xdb\x55\x71\x3c\xeb\xba\x28\x7a\xe2\x02\x65\x1a\xc8\x72\xbf\xc8\x0f\xea\xa7\xe0\x0d\x47\xc0\xbe\x38\xe6\x58\xf7\xc5"}, +{{0x90,0x72,0x1c,0x43,0xbc,0x36,0x6f,0x24,0xbf,0x4e,0x8c,0x99,0x3e,0x13,0x80,0x24,0x68,0x2f,0x10,0x29,0xdb,0xa3,0x5a,0xbe,0xb0,0xd6,0x0c,0x7f,0xa7,0x10,0x02,0x1c,},{0x7c,0x63,0xa2,0xf1,0x3b,0x7b,0x22,0x0a,0x0b,0xb7,0x52,0xe3,0x80,0x07,0x53,0xb8,0xb6,0xb3,0x26,0x69,0x37,0x8c,0xe1,0x31,0xbb,0x77,0xa9,0xa8,0xd2,0x30,0xe9,0xae,},{0xd2,0x06,0x4a,0x6d,0x6c,0x99,0xc6,0xc3,0xf1,0x52,0xd2,0xd4,0x35,0xf2,0x4e,0x34,0xb5,0x45,0x9b,0x08,0x2e,0xf1,0x1e,0x94,0x4a,0x77,0xff,0x54,0xdd,0xf9,0x86,0x27,0x37,0xec,0xb2,0xac,0x8d,0x54,0x20,0x7d,0x36,0xc5,0x1a,0xd4,0x1f,0x36,0x49,0x0a,0x11,0x1b,0xa8,0x0e,0x12,0x6b,0xfe,0xcb,0x09,0xde,0xf6,0xac,0xcb,0xdf,0x88,0x0e,},"\x65\x1c\x96\x17\xca\xc9\x58\xc7\xed\xd4\xa5\xf3\xfe\xdf\xb8\x3d\xc9\x71\xab\xfb\xb6\x9a\x31\xe8\x98\xcc\xa8\x47\x2e\xf0\x68\x03\x4a\x6d\x23\x76\xee\x0e\x72\xd0\xa9\xbf\xee\x27\x57\x96\xc3\x79\x5a\xda\xc8\xeb\xe1\xd1\x2b\x66\xec\x26\x8f\x6b\x75\xfa\x39\x41\x15\x4f\x99\xe2\x23\xfa\xf2\xcb\xab\x5b\x92\xe2\xb3\xba\x7b\x79\xbe\x77\x00\xef\x9d\xba\x69\x25\x3c\xce\x53\x56\xb0\xc4\xe7\x47\x03\xcf\xca\xfd\xb5\x54\x68\x50\xb4\x62\x32\x67\x5c\x90\xc0\x2d\x5e\x42\x6d\x33\xd6\x0c\xeb\xf0\xc7\x93\x01\x82\x37\x9d\xbb\x00\x7f\x53\x61\x63\xc8\xdd\xbb\xd3\x15\x7b\xb2\xda\x62\x34\x01\x33\xf0\x0a\xe2\x68\x2e\xc6\xba\xa6\x41\x6b\x5a\x01\x52\x1c\xc1\x0e\x04\x69\x52\x95\xf2\xe5\xb9\x4c\x05\xf0\x03\x83\xff\xe9\x54\x83\x07\x97\xf6\xdf\x82\x31\x72\x53\x2f\x98\x16\x5f\xe3\x14\xab\x32\x59\x29\xaf\x83\x85"}, +{{0x9c,0xec,0x24,0x67,0x58,0xe4,0x12,0xe7,0x37,0x8b,0x45,0x79,0xea,0xfe,0x9f,0xac,0x5a,0x25,0xd5,0x40,0x5f,0x92,0x70,0xb5,0xd7,0xe5,0x43,0x41,0x4e,0xc3,0xd5,0xda,},{0x97,0x5a,0x9e,0x6a,0x15,0x2c,0xae,0xbb,0x2f,0x9d,0xd0,0xde,0xb7,0x6d,0xd9,0x22,0xb6,0xdc,0x77,0x05,0x5d,0xda,0x03,0xfb,0xae,0x9e,0x7c,0x68,0x5d,0x07,0x3a,0xa1,},{0x9b,0xad,0x1e,0x3b,0x12,0x79,0xef,0x65,0x8f,0x4d,0x07,0x16,0x44,0xc6,0x3a,0xe2,0xb7,0xa7,0x80,0x35,0x7e,0x9d,0xc4,0x26,0xf1,0x65,0x0e,0xc0,0x63,0x4d,0xfc,0x52,0x0f,0x8e,0xda,0x9d,0xc8,0xf1,0x0a,0xa7,0x32,0x4c,0x59,0x42,0xd2,0x34,0x7f,0xf8,0x80,0x2b,0xd9,0x0e,0x95,0xfc,0xec,0x31,0x33,0x52,0xcd,0xae,0x64,0xf3,0x2a,0x04,},"\x17\xec\x9b\xd4\x7a\xdd\x6c\xcf\xbd\x78\x7a\xf0\xd9\x01\x3e\x9c\xc9\x79\xaa\xf8\x50\xe0\x94\x26\xd3\xb2\x8e\xdf\xd7\x12\x96\xeb\x31\xff\x8b\x21\xc5\xfe\x7b\xe0\x50\xf5\x36\x32\x4c\x3e\xc4\x88\x50\xe0\xb5\x08\xa3\x6b\xb4\xcb\x7e\x75\x4b\x32\x71\x83\xa1\xb3\x94\xd8\x8a\x79\x41\xd1\xce\x8d\xac\x62\xa5\xd8\x29\x18\x74\xd7\x84\x85\xe5\x1f\x29\xed\x05\x86\x5a\x20\x6e\x52\xec\xb1\x2c\x5d\x10\x7d\x4f\xf9\x6f\x25\xd3\xc5\xd1\x81\xd2\xc4\xba\x64\x63\x60\x0d\xb1\xcc\xa3\x28\x57\xfc\xf5\x97\xcb\xdf\xb2\xfd\xa2\x70\x8a\x8a\xba\x28\x1b\x43\xc3\xd2\x8c\x4a\x4e\x79\x83\x36\x15\x09\xf6\x1a\x10\x74\xe6\xf0\xad\x61\x01\xc7\xb5\x67\xee\x40\x78\xe9\x83\x9c\x47\xf4\x65\x31\xb7\x29\xff\x0e\xfe\xef\x7c\x9d\x1a\x8d\x83\x3d\x9c\x0f\x42\x81\x2a\x34\x18\x7c\x3a\x77\x8c\x16\x5c\x09\xd6\x45\x9c\x9c\x7c\xea\xa2"}, +{{0xd1,0x40,0x3f,0x63,0x20,0x2e,0x08,0x05,0x25,0x84,0x3b,0xde,0x25,0x5e,0xeb,0x6b,0x67,0x83,0xc1,0xca,0xae,0x9d,0x6e,0xd0,0x0b,0xa6,0x08,0x05,0xbe,0xd1,0x94,0x1f,},{0x23,0x8a,0xea,0x3a,0xd6,0xd6,0xf2,0x77,0x83,0xe7,0x05,0x16,0xbb,0xfc,0xca,0x47,0x70,0x36,0x6b,0x50,0xed,0x0f,0xe6,0xa4,0xe9,0x66,0xb5,0x3a,0xf1,0x21,0xa7,0x21,},{0x8e,0x60,0xe7,0x3c,0x06,0x38,0x16,0x79,0x5e,0x29,0xf5,0xd6,0x4e,0xce,0x11,0x59,0xf1,0xb5,0xd5,0x02,0x1a,0x6f,0x8f,0x65,0x5e,0x26,0x1a,0x4d,0x00,0x26,0xf5,0xb9,0x4f,0xf2,0x92,0x32,0x50,0x49,0x9d,0x99,0x52,0x98,0x48,0x05,0x12,0xe4,0x12,0x62,0x76,0xaa,0x4a,0x22,0x6d,0x01,0x5a,0x95,0x82,0x7b,0x3c,0xe6,0x92,0xe2,0x33,0x02,},"\xc4\xf1\x7d\x44\x2f\xba\x4c\xa0\xdf\x8d\xc1\xd0\x62\x8d\x7d\x7f\x36\xb6\x0b\x57\x58\xd7\xc1\x3b\x80\xb8\xf9\x7a\x62\x12\x4d\x96\xa2\x3b\x27\x95\x65\x49\x5a\x8a\xcc\xab\x59\x97\x11\x5b\x13\xa4\xba\x22\x0a\x73\x95\x7e\xb7\x93\x05\x20\xac\xbb\xfb\x6f\x54\xcf\x68\x72\x6b\x64\x50\xc6\xff\xa9\x47\x0b\x05\x5e\xa2\x62\x91\x4e\x2b\xc6\x12\x63\x3f\x1a\xc3\xd0\x61\x8a\x23\xdf\xf1\x88\xa7\x33\xd7\x6b\xcb\xcc\x46\x0f\x52\xab\x61\xe1\x99\x38\xf9\xc8\xca\xaa\x79\x2c\x20\x8d\x1f\x6c\x75\x47\x28\x90\x5f\xda\x51\xd8\x81\xa3\x47\xa5\x3d\xa7\x44\xd3\xba\xad\xc0\xa7\x6c\x47\x4c\x55\x86\x80\x26\x90\x95\xf9\x08\x4a\x74\x47\x1d\x5c\x09\xff\xc2\x91\x41\xb5\xbf\xaf\x49\x54\xdf\xac\xbc\xa6\x63\xd0\x37\xb1\x7e\xbf\x95\x59\x88\x22\x33\xe5\xca\x5a\x8b\xf7\x5c\xca\x4f\xc9\xc5\xa4\x10\x9f\x32\xe1\x45\xf3\x85\x3b\x17"}, +{{0xbd,0xf6,0xbd,0xc3,0x1a,0xb0,0xb5,0x31,0x37,0x84,0x48,0x3a,0xbe,0xca,0x6e,0xa5,0xe9,0xcd,0xc6,0x8f,0x81,0xb2,0x1f,0x35,0x0d,0x09,0xc3,0x90,0x7b,0xb9,0xb6,0xa1,},{0x03,0x62,0x77,0x12,0xb7,0x55,0xe5,0x06,0x9f,0xb9,0xab,0x8f,0x9e,0x89,0x97,0x24,0x02,0x9a,0x7f,0x26,0x8a,0xf9,0x39,0x88,0x21,0xee,0xec,0x93,0x60,0xc9,0x28,0x5b,},{0x38,0xfa,0xc6,0x03,0xed,0x24,0x6f,0x83,0x3f,0x1c,0x0f,0xd4,0x58,0x56,0x98,0xb0,0xa7,0x13,0x05,0xef,0xf0,0xd1,0x4a,0x00,0x49,0xb3,0xce,0xf0,0x73,0xbd,0x03,0x6d,0xd4,0x51,0xb3,0xda,0xba,0xda,0xae,0xae,0xa2,0xae,0xaf,0x83,0xd3,0x95,0x74,0x6f,0x4e,0x86,0x86,0x6a,0xda,0x97,0x1c,0xbe,0x48,0x2e,0xdb,0x04,0x19,0x33,0x2f,0x0e,},"\x90\xa6\x6a\xaf\xa5\x64\x2a\x98\xe7\x9f\x0d\x88\x14\x70\x80\x16\x7b\x11\xe4\x46\x65\x18\xf1\x95\xcd\xdd\x89\x40\xd1\x2e\xe4\x91\x8d\x31\xa6\xd4\xcb\x77\xd0\xbf\x5a\xf2\x99\x83\xbb\xe5\x08\x56\x10\xa7\x9d\xaf\x0c\x75\xa7\x8c\xcb\xcf\xfb\xbd\xab\x21\x89\xc3\x94\xae\x24\xe2\x65\xbd\x8c\x55\xfd\x3f\x40\x98\xe1\xb1\x75\x57\x75\x49\x51\x8e\x7a\x4d\xcf\x74\x52\x08\x6d\xd1\x27\x8d\xd5\x8e\xa4\xc0\xaa\x69\x0e\x91\x79\x51\xef\x39\xfc\xff\x60\xcb\xfa\x1e\x90\x91\x0b\xab\x53\x74\x92\x8d\x47\x22\xf7\x02\xbf\x5a\xd6\x02\x8f\xfd\xa6\x54\x1f\xa5\xba\x1a\x37\x79\xec\x78\xb0\xa9\x5f\xe3\x85\x0c\x74\x8b\x6c\x8f\x42\xf3\x30\xec\x79\x54\x1a\x52\xa1\xcf\x57\xdb\x72\xdf\x4f\x92\xce\x7f\x74\x8a\xee\xf1\xaf\x33\xbc\x5a\xe0\xa8\x2c\x89\xdf\xf2\x16\xf2\x3a\xec\x16\x8a\x7d\xbb\x51\x0a\xa6\x32\xda\xab\xcc\x97\x1b\x3f"}, +{{0x57,0xb3,0xb1,0x4a,0xce,0x1c,0xd0,0xcd,0x60,0x3e,0x63,0x28,0xbd,0x21,0x9e,0xe7,0xd9,0xd0,0x94,0x48,0x7f,0xa6,0x68,0xf2,0x8a,0xee,0xc0,0x2b,0x43,0xc9,0x09,0xa7,},{0x24,0xe6,0xb6,0x39,0x5f,0x97,0xea,0x0e,0x23,0x71,0x86,0xd4,0x69,0xb7,0x19,0x23,0xd2,0x11,0x3a,0xdf,0x40,0x3b,0xee,0xeb,0x4a,0x2d,0x27,0x90,0x9a,0xaf,0x3e,0xda,},{0xfc,0x79,0xfd,0xc6,0xd0,0x90,0x88,0x7a,0x61,0xe4,0x3c,0x6b,0x91,0x87,0xb6,0x57,0xd2,0xe4,0xd9,0xcb,0xaf,0xd6,0xe7,0xca,0xeb,0x7e,0xbd,0xea,0x84,0x28,0x25,0xb7,0x8f,0xb9,0x49,0xd2,0xc4,0x9a,0x0c,0xf3,0x8b,0x6c,0x73,0x29,0x6d,0x82,0xc8,0xdd,0xeb,0x1f,0xe2,0xd4,0x0a,0xad,0xdd,0x79,0x64,0xda,0x68,0xac,0xf8,0xc6,0x6f,0x0e,},"\xb2\xe0\xde\xdd\x80\x2e\xed\x99\x6d\xbd\x58\x36\xbf\x86\x88\xb0\xd1\x20\x1b\xf5\x44\x2f\xf9\xbb\xd3\x51\xae\xef\xe1\xa0\xc2\x1f\xea\x2b\x5c\x9f\xe5\xed\xee\x47\xe9\x21\x09\x9b\x05\xae\xda\xa8\x03\x67\xc1\xce\x08\x82\x1d\x78\x3a\x5b\x64\xcf\x05\x9c\x0f\x43\x35\x08\x39\x86\xa5\xa6\xec\xff\x8c\x84\xfd\x40\xe0\xba\x5d\xd5\xe5\xd2\xf0\x11\x12\xa8\x4c\xe5\xcf\x8e\x0d\xb7\x8b\xeb\x18\x2d\x91\x39\xc0\xb0\xf3\xe0\x06\x0a\x3f\xa7\x38\x69\xe9\x64\x23\xf1\x70\xdf\x9a\xf1\xcb\x9c\x35\x56\x6d\x87\xdf\xf5\x42\x22\x3f\x6d\x43\x9b\xdb\x54\x72\x9d\x36\x6a\xff\x63\x7b\x0f\x36\xa5\xd1\x4b\x15\xd6\x12\xbd\x03\x07\x6c\xc4\xd0\x4c\x1f\x25\xb3\xba\x84\xe0\xd1\xfe\x47\x4e\x57\x18\xd1\xa1\x7d\x5a\x48\x84\x65\x66\x2e\xe4\xc3\xf6\x64\xb4\xc9\x27\x4b\x64\x9d\x78\xce\xa4\xe8\x52\x43\xf3\x71\x32\x39\x04\x8a\x90\x8c\xe3\xe1"}, +{{0x01,0x8a,0x2c,0x3d,0xee,0xa5,0x0a,0xb5,0x06,0x75,0x1f,0x9c,0x2a,0xda,0xad,0xfd,0x9e,0x21,0x92,0x12,0x16,0x09,0x93,0x16,0x84,0xeb,0x26,0x5e,0x19,0x3e,0x7f,0x89,},{0xaf,0x41,0x0b,0xdd,0xde,0xfc,0x64,0x4e,0xf1,0x2c,0x98,0x99,0xff,0x71,0xb9,0xe1,0xd0,0xdf,0xa3,0xd6,0x9d,0x8c,0x2c,0xd6,0x76,0xc1,0x91,0x6b,0x34,0x59,0x1c,0xfd,},{0x7a,0x44,0xe6,0xa3,0x19,0x32,0xde,0xe6,0xdc,0x2d,0x83,0x94,0xe2,0x9a,0x65,0x51,0xd1,0x3e,0x6c,0x6f,0xfd,0xfa,0x21,0x8f,0xa5,0xb9,0x98,0x66,0x8d,0x84,0x39,0xdb,0x5e,0x05,0x37,0x9f,0xbf,0xa0,0xda,0x5b,0x56,0x3e,0xd9,0x66,0x43,0x5a,0xe2,0xc5,0x4e,0x3a,0xd1,0x6e,0x1a,0x9f,0xca,0x1f,0x5a,0x15,0x7a,0x08,0x07,0x04,0xab,0x03,},"\xcf\x78\x13\xef\xac\x12\xad\x1c\x7c\x73\x22\xcc\xbe\x54\xaa\x0e\x9a\x8b\xa4\xfd\x43\x45\xb0\x6e\x4c\xe7\xa3\x5c\x8b\x1c\xd5\xe3\xf7\xf0\x68\x85\x33\x84\x9b\xa2\xcf\x4c\x75\xb6\xf2\x09\x26\xa1\x19\x4a\x72\xdf\x0e\x1b\x1b\x34\x45\x6a\x21\x33\x11\x2d\x00\x67\x22\xfe\x81\x1d\x5e\x40\xc4\x12\x11\x59\xde\xd8\x89\x90\xc0\xac\x2b\xfd\x34\xf3\x5a\xf4\xf0\x7c\xc4\x02\xe9\xa3\x81\xa6\x75\xd0\x3f\xec\x7e\xc4\x38\xc4\xad\x9d\x92\x9a\xec\x8f\x24\x2d\xef\x02\x3c\x99\x3c\x9e\x8b\xa1\x8c\x74\x28\xe8\x8f\xde\x68\xa4\x71\x1e\x50\x6d\x79\x69\xf6\x3c\x8e\x0b\xc8\x3f\xf0\xde\x4e\x13\x36\x10\x6c\x05\xe0\x9d\x59\x22\x40\x0e\x8a\x81\xbf\x54\x88\x56\x67\x89\x97\x85\x88\x2b\x70\xf2\x0d\xd8\xfb\x1e\x75\xf5\x85\x5b\x76\x5a\x25\x6d\xa4\x34\x1b\xf2\x3e\xa0\xff\xa1\x8a\xad\xda\x38\x18\x16\x94\x60\x01\x04\x56\x69\xc8\xd0\x4d\xf0"}, +{{0xbe,0xa4,0x45,0xe9,0xb6,0xd3,0xf2,0x12,0x35,0x91,0x2c,0xd6,0xc4,0x2e,0xc0,0x57,0x72,0x97,0xca,0x20,0xa1,0x03,0x57,0x88,0x0c,0x2b,0x84,0x6d,0xd8,0xe2,0xcc,0x77,},{0x02,0x41,0x74,0x96,0x62,0x21,0x69,0x9e,0xa4,0xb0,0xa3,0x7e,0x51,0x7f,0xf9,0xb1,0x65,0x98,0xae,0x4d,0x4e,0x83,0xbf,0xa3,0xca,0x50,0xbc,0x61,0x68,0x41,0xf5,0x95,},{0x69,0x64,0xb9,0xc5,0x90,0x3e,0x74,0xe9,0x93,0x28,0xac,0xef,0x03,0x65,0x58,0xee,0xcd,0x33,0x69,0x15,0x0a,0x52,0xe2,0xcb,0xad,0x4b,0xbb,0x97,0xd4,0x61,0xb3,0xdf,0xc6,0xb3,0xe8,0x45,0x58,0x13,0xa4,0xf4,0xbd,0xca,0x46,0x30,0x2e,0x02,0xe6,0x83,0xec,0xea,0x18,0x20,0x17,0x1c,0x53,0x8e,0x54,0xc3,0xde,0x6c,0x95,0x4a,0xa4,0x07,},"\x47\x43\xc7\xc0\x99\xab\x81\x59\x27\xb3\x67\x4d\x00\x54\xb6\xde\x59\xaf\x28\x11\xab\xc2\xcf\x7f\xde\x08\xf6\x29\x29\x18\x5a\xdc\x23\x8f\xad\xd5\xe7\x5a\xe3\xba\x00\x36\xff\x56\x5a\x79\x40\x5b\x42\x4f\x65\x52\x33\x1e\x27\x89\xd9\x70\x9a\xc1\xec\xbd\x83\x9a\xa1\xe9\x1c\x85\x48\x17\x59\x79\x58\xcc\x4b\xd9\x1d\x07\x37\x75\x07\xc2\xc8\xd3\xc0\x06\xcf\xeb\x6c\x0a\x6c\x5a\x50\xee\xe1\x15\xe2\x11\x53\xdd\x19\x8e\xa0\xa3\xaf\xf6\x2b\x70\x75\xd5\xa4\x61\x78\x87\x83\xf0\x50\xe6\x59\xc5\x72\x96\x3d\x7a\x59\xe5\xaf\xaa\x2b\x9c\x50\x1f\x43\xc6\xac\x08\xab\x47\x97\xc4\x56\x6d\x22\xb9\x3c\xdf\x65\xa9\x9a\x2a\x1d\x63\x8e\x79\xf7\x2b\x5f\x46\x31\xfe\x5e\x9e\x5f\x96\x8f\x6d\xb7\xa1\x88\x0d\xf5\x1d\x8f\xeb\xc1\x49\x42\x67\x2f\x8e\xa6\xfc\x3a\x72\x81\x4a\x44\xd6\x6d\x14\x84\x20\xa6\x90\x00\xf6\x8c\x33\x0d\xe5\xb8\x0f\xc6"}, +{{0x64,0x47,0x54,0x0e,0xd7,0xbe,0x0a,0x11,0xc2,0xa8,0xde,0x79,0x3d,0x83,0xc6,0xe2,0x44,0x98,0x3d,0xb1,0x8d,0x78,0xec,0x9d,0x75,0xf1,0x72,0x9c,0x92,0xe0,0xfd,0xf1,},{0x39,0x12,0x12,0xc8,0xed,0xc4,0xd3,0x34,0xa5,0xbe,0xc8,0x60,0xef,0x0f,0x5e,0xbb,0x5e,0xc4,0x4e,0x8b,0xb5,0x1c,0x0f,0x67,0x41,0x99,0x89,0x59,0xb2,0xb3,0x79,0xfc,},{0x3a,0xb5,0xf8,0x8e,0x2f,0x72,0x76,0xb5,0xb6,0x58,0x3d,0xff,0xba,0x56,0x39,0x99,0x3a,0x90,0x5d,0xbf,0x9b,0x88,0xce,0xea,0xaa,0xae,0x33,0x35,0x80,0x0e,0x4a,0x5f,0x10,0xf8,0x3d,0xa6,0xd6,0x22,0x5a,0x8d,0xbe,0x99,0xae,0x80,0x07,0x50,0x09,0xdd,0x50,0x87,0x86,0xb3,0x97,0x51,0x13,0xdb,0x47,0x8e,0x14,0xba,0x10,0x1b,0xee,0x0f,},"\xa4\x38\x1c\x76\x38\xc4\x87\x99\xe9\xb5\xc4\x3f\x67\xfc\x3a\xa3\xcb\xb5\xec\x42\x34\xf3\x7e\x70\xcc\xcc\xce\xd1\x62\x7a\x57\x68\x3d\x1e\x53\xf4\xe0\x88\x3d\x8b\x46\x2b\xf8\x3f\x13\x08\x63\x03\x68\xc8\x9b\x49\x15\x33\xdd\xb8\xc9\xa5\xb9\xe8\x15\x50\x02\xfd\xd5\x81\xa9\xa5\xbe\x0e\x43\x0b\x90\x86\xa6\xbe\xac\x47\x20\x21\x0f\x87\xb1\x4e\x86\x2d\x97\xe5\xcc\x69\x28\x67\x86\xa7\x58\x67\x23\xf2\x31\xef\x0e\x3e\x1b\x93\x2d\xbb\xa3\xa1\x8a\x0c\xb2\x21\xcb\x07\xf8\x0e\x6a\x8e\x13\x00\x05\x6c\x13\xe7\x02\xb2\x3b\xfb\x32\x50\xec\x7c\xc8\x64\xd5\xc7\xec\x57\x86\x24\x07\x09\xc5\x60\x24\xea\x6b\xe5\xf7\xb1\x5a\x4f\xa5\x55\x5e\x39\xa7\x44\xa1\xdc\x55\x7d\xf5\xb9\x48\xdb\x22\x0b\x3d\x57\x45\x74\x66\x91\xda\xcb\x44\x21\x64\x1c\xdc\xc1\x2e\x7e\xc0\x45\x02\x93\xf1\x9e\xc5\x7b\x09\xcf\xf1\x35\x84\x7a\xab\xe4\x46\xa6\x13\x32"}, +{{0x0c,0x58,0x7a,0x81,0x1a,0xdd,0x88,0xb9,0x94,0x45,0x8c,0x3c,0x80,0x8a,0xc4,0xe3,0xa8,0x3a,0xfa,0xb2,0x6d,0x4c,0xff,0x5c,0x96,0x1b,0x9d,0xf0,0xb5,0xc8,0x33,0x44,},{0x06,0x78,0x3b,0x0c,0xdc,0xc5,0x02,0x8c,0x56,0x38,0xbd,0x74,0x8f,0x0b,0xc7,0x6f,0x7e,0x94,0xd1,0xaa,0x20,0x15,0xca,0x94,0x87,0x38,0xa3,0x50,0x04,0x60,0xac,0xa0,},{0x33,0xb4,0xf4,0x27,0x4f,0x20,0x00,0x8a,0x72,0x1d,0x1e,0x8d,0x05,0x4a,0x2b,0x4e,0x95,0x32,0x7e,0x38,0xbb,0x07,0xb3,0x3c,0x4b,0xee,0x7e,0x1c,0xe0,0x20,0xa4,0x42,0xfb,0x26,0x27,0xed,0xa3,0xb7,0xac,0x93,0xcd,0x3a,0xb0,0xb1,0x2b,0x99,0x93,0x5a,0x1a,0x92,0x33,0x11,0x16,0x04,0xda,0x4a,0xcf,0xfb,0x53,0x15,0xb9,0x07,0x12,0x0b,},"\xf5\x6d\xc6\xb7\x60\x76\x32\x5b\x21\x26\xed\x11\xd1\xf0\x9d\xec\xef\x9d\x15\xc3\x1d\x0e\x90\xcd\xb1\xa2\x7e\x08\x9c\xc5\x63\x29\xf6\xec\x3f\x66\x5e\xb6\x73\x9e\xc5\x67\x8b\x3f\x37\xee\x1f\xb3\x7d\xeb\x9e\x24\x00\x92\xb7\xa8\x8f\xd2\x55\x25\xac\xd5\x5e\x29\x4e\xb1\x04\x6f\x9b\x1b\x69\xa8\x47\xeb\x9c\xeb\x7b\x15\x93\xb9\xf6\x97\x8e\xf6\x18\xc1\x5d\xe4\xe0\x59\xec\xc3\xbf\xda\x32\x97\xa1\x9c\x2d\xf2\x02\xad\xf7\x21\x55\xcf\x21\xea\xbd\x03\x94\x8d\xf1\x51\x98\xe8\xa6\x8b\x08\x84\xf9\x3a\xd5\xe3\x6e\xb0\x98\x3c\xca\x30\xe4\x5a\x8b\x4b\x5f\xb8\x13\x6f\xde\xa8\xa3\x34\x1d\xd7\x87\x75\x40\xa5\x57\xde\xbf\x75\x30\xcc\x33\xae\xee\xf6\x27\x1c\x3f\x0a\xf6\xd0\x97\x87\xe8\x15\xf2\xf1\xdd\x25\xce\x4d\x2f\xd0\x9f\xfa\x9f\x53\x08\x1b\x46\x9c\x50\x0d\xa4\xd4\x41\x80\xc0\x4e\xb1\x86\x93\x29\xcb\xf2\xd8\x23\x18\x7e\x83\x1c\x24"}, +{{0x66,0xcf,0x40,0x1a,0x21,0x42,0xfc,0xf4,0xa8,0x01,0x80,0x46,0xcf,0x41,0x40,0xbc,0xa1,0x8d,0x76,0xef,0x62,0x66,0xe7,0xa0,0x24,0x75,0x7d,0xf1,0x72,0xa5,0xd6,0x53,},{0x67,0xd4,0x8d,0xfd,0x23,0x74,0x3c,0xc2,0xca,0x40,0xe4,0xdf,0xd6,0xb8,0xcc,0x5d,0x84,0xbe,0x82,0xdd,0x2b,0x11,0x20,0xcc,0x47,0x6e,0x6a,0xf6,0xf2,0x5e,0xcc,0x98,},{0xd6,0xb0,0xe8,0x0e,0x60,0xbc,0x1b,0x29,0xab,0x8f,0x74,0x80,0x8f,0xc4,0x60,0x84,0x77,0x95,0xcc,0xb8,0x87,0xba,0xc0,0xec,0xaa,0x8e,0x13,0x52,0x97,0xa8,0x50,0x97,0x71,0x2b,0x24,0xb0,0xa1,0xfb,0xaf,0x7a,0x67,0xc5,0xd5,0x30,0xa4,0x7d,0x06,0x43,0xfc,0x87,0x02,0xc0,0x59,0xd2,0x15,0xfb,0x11,0x2d,0xbe,0x47,0x5e,0x5b,0xca,0x0d,},"\xda\xa8\xef\xb3\xfd\x41\xf1\x2f\xbc\x55\xbd\x60\x46\x41\x57\xa2\x6d\x71\x86\x32\xd8\x82\xae\xdb\x6b\xf9\x8e\x47\xdd\x23\x37\x87\x9e\x0b\x46\x45\x2e\x06\x2e\x6d\xfb\xff\x3e\x7b\xca\x72\x89\xe4\xef\x6b\x3f\x41\xd4\xb0\x3b\xdc\x2c\x84\x2a\xfe\x97\xf3\x02\x98\x83\xed\x45\xf6\x05\x4d\xde\x96\x90\x64\x9a\xbb\x2b\x8d\xc2\x8f\x5f\xe8\xce\xcf\x80\xfc\x1e\xa4\x11\xbf\xc4\x0b\xbf\x4f\xd2\x0b\x21\x8c\xf4\x7e\xa8\xee\x11\x8d\x4d\x5a\xef\xa5\xc1\xbf\xa0\x8a\x8f\xb1\xb3\x0d\x6d\xe0\x97\x7c\xd1\x5e\x50\x29\x2c\x50\x1f\x2e\x71\xce\x27\x40\xff\x82\x8b\x84\x32\xda\x5a\x59\x4b\xab\x52\x23\x76\x0b\x64\x79\x2e\xd3\xa6\x9d\xd7\x5e\x28\x29\x23\x49\x43\x65\x65\x13\xdf\x1a\x17\xa2\xa0\x67\xa9\xa8\xea\xa6\x4e\x19\x56\x9f\x46\x93\x9d\x34\xb9\x92\x71\xae\x50\xa4\x7d\x7d\xbc\xa3\x62\x0c\x81\x25\x5b\x0e\x1f\xd1\xf3\xce\xc8\x51\xf1\xb1\x1b\x35"}, +{{0x5d,0xbf,0x88,0x5a,0xa5,0x98,0xe8,0x95,0x57,0x1f,0x5f,0x65,0x09,0x0b,0x72,0x32,0x3e,0x9d,0x70,0xb0,0xf5,0x81,0x10,0x68,0x7a,0xfb,0xbc,0x38,0x3a,0xfe,0xdc,0xac,},{0xfa,0x17,0xeb,0xa7,0x6e,0x3b,0xc3,0xea,0x6d,0xab,0x3a,0x5b,0x12,0x0d,0xc5,0xec,0xb9,0xae,0x6f,0x00,0x13,0x8f,0x7d,0x36,0xdd,0xa9,0x26,0x8b,0xc4,0x72,0x21,0x74,},{0xe1,0x42,0x9d,0xab,0x2e,0x42,0xcd,0x03,0x5b,0x7f,0xc6,0x02,0xef,0xd6,0xba,0xf9,0x47,0x06,0xf1,0x6e,0xaf,0x2f,0x8b,0x5f,0xed,0x32,0x92,0x39,0xe8,0x75,0x60,0x5f,0xb1,0x72,0xf5,0xdd,0x9a,0xe2,0xbc,0x2e,0xb4,0x2e,0xb4,0x74,0x56,0x7e,0x29,0x2f,0x52,0x06,0xe8,0x2e,0x69,0x4b,0xca,0x0d,0x6d,0x43,0x3b,0x86,0x76,0x34,0xcb,0x0d,},"\x1e\x0b\x6c\xf1\x5c\xe0\x33\x37\x17\x9c\x02\xd6\x54\x08\xdf\x5b\xe9\x20\x0c\x37\x82\xb6\x00\x4a\xf9\x4e\xa4\xde\xcb\x25\x79\x99\xd6\xfd\xff\x30\x1d\x11\xd0\x0c\x98\xc3\x72\xfa\xc0\xd0\x26\xcb\x56\xdf\xef\xe3\xde\xf7\xeb\x99\xac\x68\xd6\x96\x8e\x17\x12\x4d\x84\x46\xf5\x3e\x8d\x2d\x3d\xd8\x90\xd3\x7a\x23\xc7\xe0\xb8\x3a\x48\x4b\x3c\x93\xbd\xdf\x6c\x11\x8e\x02\x81\x95\x9d\x27\xbd\x87\xd3\x7e\x84\x3d\x57\x85\xf4\xa4\x07\x71\x39\x84\x94\xe6\xc4\x32\x2f\xbb\x67\x5c\x1d\x47\x93\x21\x03\x21\x48\xf7\xfe\x52\x56\x4d\xdf\x7a\xe7\xac\x26\x9d\x0c\xd2\xe5\x52\xfe\xc5\x89\xae\xae\x0f\xb9\x3f\xe3\xee\xae\xf0\x85\x60\x96\xcf\x4f\x6b\x34\x97\xe7\x23\x5c\xc8\x49\x4d\x81\x0a\x0b\x46\xc5\xea\xc8\x7f\x18\x7e\x50\x5b\xb7\x76\x4f\x80\x45\xc9\x54\x19\x83\xf7\xb0\x25\x69\x80\x09\xa2\x3d\x9d\xf0\xbd\x1a\x47\x3c\xbe\xe4\xcf\x5e\x94\x88\xec\xbc"}, +{{0x84,0xb3,0xae,0xdd,0x47,0x97,0xa5,0x65,0xc3,0x51,0xde,0x7d,0xfa,0x07,0x00,0xb9,0xff,0x7c,0x4d,0x72,0x91,0xc8,0x80,0x8d,0x8a,0x8a,0xe5,0x05,0xcd,0xd2,0x25,0x90,},{0xd7,0xad,0x72,0xca,0xa7,0xc2,0x22,0x09,0xec,0x46,0x78,0xd1,0x1d,0x55,0x90,0xa6,0xcb,0x28,0xa0,0x71,0x17,0xfe,0x5a,0xef,0x57,0xb5,0x07,0x51,0x58,0x32,0x01,0xa5,},{0x92,0x20,0xf0,0xed,0xaa,0xae,0xe1,0xb8,0x76,0x35,0x0d,0xbe,0x92,0x66,0x06,0x17,0x67,0xb8,0x62,0x96,0xc3,0x51,0xd4,0xca,0xc9,0x9d,0x07,0xcd,0x61,0x2c,0x6e,0xfb,0x24,0xf8,0xf9,0xb0,0xb9,0x75,0xf9,0x5c,0x42,0xc5,0xb6,0xaf,0xed,0xc8,0x92,0xf8,0x7e,0xfe,0xdd,0x39,0xd5,0x16,0x02,0x94,0xc2,0x76,0x58,0xbd,0xcf,0x42,0x85,0x0b,},"\x53\x25\x67\xff\xa5\x3b\x5c\x0f\xcd\x29\xc3\x94\x99\xd2\xe7\x8e\xcd\x20\xe6\x31\x23\x49\x92\x40\xe7\x75\x08\x8b\x39\x4d\xc6\x5c\x8b\xaa\xa0\xfe\x8f\x6a\xa7\xe7\x01\x81\xf9\xe1\x0a\xdd\x8b\x4a\x8b\xeb\x0b\x2e\xc3\x8a\x43\x30\x9f\x10\x0c\xd4\xbe\x91\xc6\xf4\x8e\x79\xdc\x0a\xee\x93\xa1\x5c\x94\x03\x77\x3b\x35\x4a\x8d\x42\xed\x48\xd8\xf2\x76\x23\x0f\xa6\xde\x5a\xda\x50\x1e\xe0\xa6\x53\xb4\x45\x8f\x0e\xcf\x6d\x5b\x3c\x33\xe2\x14\x1c\x66\x2f\x6e\xa0\x55\xf7\x41\xe5\x45\x86\x91\x7d\x2e\x0c\x4e\xb2\xb5\x66\x21\xf9\x66\x5f\xef\x32\x46\xf0\xbd\x80\x0b\x53\x3e\x3b\xc6\x15\xc4\x02\x1f\x8d\x0e\x2a\xd2\x33\xa1\x1e\x77\x36\xc4\x93\xac\xc3\x1f\xae\xe7\x6a\x09\x7d\xc4\x0d\xb9\xef\xc2\x24\x46\xea\xcf\x1c\xc1\x8f\x51\xfd\x10\x23\x6a\x2f\x94\x2d\x0a\x53\xc3\xce\x20\x91\x08\xb5\x93\x8c\x0a\x9e\x53\x6b\x89\xef\x0a\xd6\xb4\x05\xa1\x0f\x22\xc3"}, +{{0x69,0x50,0xbf,0xcf,0x48,0x0b,0x98,0xea,0x18,0xa2,0xd5,0xae,0x5b,0xa6,0xe7,0x66,0x8f,0x4c,0x28,0x3f,0xf2,0x71,0x13,0x57,0x74,0x0f,0xfe,0x32,0xcf,0x25,0x81,0x9a,},{0x8e,0x4c,0x6f,0x23,0x3f,0x7b,0x86,0x32,0x1c,0x9d,0x67,0x99,0xba,0xc2,0x8a,0xaf,0xcd,0x25,0x03,0xd7,0xaa,0x0a,0x7b,0xde,0xd8,0x72,0x27,0x27,0xfb,0xbc,0xae,0xb8,},{0x94,0xde,0x5d,0xf7,0xa2,0x5e,0xcd,0x70,0x20,0x5d,0x40,0xbc,0x94,0x99,0xfc,0x7c,0xd7,0x13,0x65,0x68,0x06,0x0a,0x41,0x9a,0x93,0xbe,0x6e,0x31,0x86,0x64,0xbb,0x6d,0xfc,0xe6,0x0e,0x2d,0x4e,0x63,0x3f,0x7e,0xc1,0x48,0xfe,0x4f,0x83,0x4e,0xd2,0x77,0xc1,0xfe,0xc4,0xc4,0xe2,0xa8,0x6f,0x44,0xc4,0x58,0x9c,0x81,0x78,0x88,0xdb,0x00,},"\xa4\x01\xb9\x22\xab\xa5\x7e\xe0\xc6\xac\x1c\x8f\x1b\x48\x29\x6a\x85\x62\xee\xf1\x37\x52\x68\x93\x88\x6a\x08\x30\x6e\x22\x03\x66\x77\x88\x61\x8b\x93\x98\x64\x46\x7a\x31\xf1\x6e\xdc\xe1\x52\xa4\x2c\x25\x54\x6b\x64\x0e\xa8\xbe\xd1\x89\xa4\xf8\x98\x86\xa3\x7f\x10\x69\x11\xea\xe1\xf5\x00\x81\xbf\x79\x5e\x70\xc6\x50\x44\x37\xd2\xa8\x0c\xb8\x39\x47\x9e\xcb\xb8\x7c\x12\x9b\xcc\x5f\xe3\x1d\x71\x6e\xf9\x78\xc2\x06\xd7\xf0\x8a\x79\x34\x66\x59\x4f\x4d\x75\xe2\x15\xbb\x63\x74\x59\x6f\x8e\x7d\x00\xee\xa7\x24\x78\x09\x43\xe8\x9b\xd3\x86\x3c\x95\x1b\xbd\x24\xef\xee\x23\xc9\x7c\x2c\x79\x7c\x7f\xaf\xbf\x8f\x2c\x8b\x43\xf3\x7a\x5f\x88\x11\x29\xa0\x95\x73\xfa\x7a\x03\x4a\x28\x5e\x80\xdc\x4b\xa4\xbc\x95\x64\xa4\xdc\xed\xeb\x33\x16\x7e\x0b\x30\xc5\xa0\x0b\x9a\x10\x9a\x22\x31\xcf\xa0\x01\x2b\x29\xb2\xb3\x45\x0b\x89\x2e\xcc\xef\x08\x08\xe5\x03\xf8"}, +{{0x61,0xb2,0x60,0xf5,0xb8,0x48,0xb2,0x71,0xef,0x48,0xe5,0xa5,0x6d,0x29,0x74,0x32,0xd8,0x9f,0x2a,0xb8,0x5b,0xd5,0x38,0xfa,0x66,0x88,0x70,0xd0,0x56,0x02,0x20,0xe5,},{0x60,0x86,0xfe,0x87,0x35,0xf3,0x99,0xf1,0xaf,0x2e,0x39,0x5e,0x0f,0xdf,0xb5,0x62,0x9e,0xbc,0xb0,0x4b,0x6e,0xd4,0xa5,0x4a,0x9e,0x47,0x05,0x2c,0x6e,0x81,0x91,0xd4,},{0x98,0x28,0xfe,0xc8,0xff,0x5c,0xf8,0x5a,0x98,0xf4,0x50,0x77,0x0b,0x5b,0xdb,0x4b,0x80,0xda,0xca,0x44,0x37,0x9d,0x8f,0x53,0xc9,0x1c,0x34,0x8e,0x22,0xdf,0x64,0xac,0x48,0xf2,0xb6,0xe2,0xa7,0xb3,0xb6,0x42,0xbc,0x81,0x93,0xa1,0x94,0x31,0x62,0x29,0xe6,0x94,0x47,0xed,0x24,0x1c,0xd4,0x23,0xd8,0x3b,0x6f,0xe7,0xb2,0xd4,0x4b,0x00,},"\x28\x26\x29\x5d\x79\x94\x5f\x67\x54\x76\xbc\x4d\x45\xef\x80\x0d\x80\xb1\xf0\x39\x8e\x4b\xe6\x0e\x3d\xe4\x57\x1e\xd1\x08\xdf\x98\x9f\x03\x2d\xe6\xc2\x34\x5d\x99\x48\xd6\x77\x92\x7e\xa0\xb8\xcf\x1a\x5c\xa3\x6f\xd5\xf2\x3c\x25\xdc\x0d\x2a\xb5\xbd\x56\x5a\x54\xaf\x46\xfd\x97\xd3\x38\xd7\x70\xe3\xa7\xb4\x7e\xfb\x54\xc0\x7a\x16\x64\x70\x77\x71\xeb\x4e\x37\xd9\xd7\x0b\xa7\x79\x25\x1d\xcd\xcd\x3b\xf6\xd1\x24\x8a\xde\xc5\x3f\x78\x72\x59\xc4\xd5\x94\xd5\xfd\x4c\xed\x8e\x3d\xb7\x62\x1d\x49\x65\xd4\x82\x98\x17\x81\x24\x93\x1a\x3d\x0c\xd2\x69\xb2\xd5\x3b\x7c\xd2\x61\xb9\x6d\x37\x0c\x5d\x96\x93\xc8\xad\x13\x3e\xd5\x89\x45\xee\x35\x40\xe1\x06\x25\xd9\x24\xae\xba\x9b\xda\xfc\x65\x61\x00\xaa\xb2\x76\xfa\x99\x6b\x1d\xb4\x77\xbf\x85\xea\x55\x90\x81\xd5\xb4\xc7\x30\x7d\xc1\x59\x56\x54\xac\xa8\x2f\x7b\x6d\x2d\xda\xf7\x35\x7c\x15\xa4\xd7\xd8\xb9\x08"}, +{{0x93,0x6d,0xc1,0xce,0xf6,0xa3,0x10,0x74,0x7f,0x35,0x00,0x88,0x05,0x5a,0x39,0xaa,0x76,0x2d,0x9a,0x4b,0x52,0xc8,0xc8,0xe4,0xc6,0x82,0x79,0x43,0x80,0xc2,0x72,0x5c,},{0x03,0xb3,0x18,0x00,0x41,0x2d,0xf4,0xd5,0x6f,0x15,0x32,0xc0,0x58,0x28,0xc0,0xb7,0x25,0x28,0xa6,0x7a,0x78,0x1b,0xef,0x4c,0x06,0xc1,0xfb,0x6f,0xf2,0xce,0x32,0x4b,},{0x3f,0x99,0x4b,0x8e,0xf5,0x28,0xf6,0x42,0x1c,0x6a,0x6a,0x22,0xe9,0x77,0xad,0xe5,0xce,0xe8,0x87,0x26,0x3d,0xe3,0x8b,0x71,0x9a,0xcd,0x12,0xd4,0x69,0xbf,0xd8,0xc3,0xf6,0x8e,0x7a,0xc0,0x7d,0x2f,0xae,0x80,0xa2,0x09,0x27,0x78,0xdf,0x0b,0x46,0x35,0x37,0xad,0x3a,0x05,0x51,0x99,0x7a,0x3d,0x5b,0x51,0xf8,0x32,0xd9,0xc8,0x23,0x0b,},"\xeb\x58\xfe\x86\xc4\xef\x34\x9c\x29\xae\x6f\xb0\x4f\x10\x85\x0e\x38\xc6\x82\x3d\xbe\x64\xa0\x9a\x5b\xf1\xe0\xce\x60\x0d\x39\x4e\xfa\x6f\xb9\x6e\xd6\xa8\xf2\xc9\xd4\xbe\xc0\x5e\x6a\x5e\xbd\x5a\x1b\xf4\xd0\xc5\x1d\xb9\x34\xe5\x7b\x79\xe5\xc6\xa8\x79\xd9\x75\x19\x7d\xbb\x10\x47\x5f\x65\xc7\xf8\xa8\xc6\xa7\x7a\x42\x03\x84\xb5\x06\x2a\x27\x40\xf1\x40\x17\x40\xee\x0f\x5e\x04\x3a\xad\x7a\x2a\x2b\x42\x60\xc5\xd9\x07\xf7\x05\xed\xaf\x65\xb0\xe3\x75\xdf\xc7\xb0\x0b\xd6\x60\xdb\x61\x47\xf2\xeb\xe8\x70\xa0\xee\x18\xdc\x2b\xa3\xc9\x2b\x0b\x76\xfa\xe2\xb9\x09\x32\xcd\xb6\xc1\x49\xe4\x6f\x3f\xee\xcf\x4c\x26\xf0\x44\x1f\x3a\x9e\x00\x66\x78\xae\xcf\xf8\xcc\xae\xca\xed\xa7\x3a\x18\xa6\x8a\xc9\x88\xb6\x2e\x83\xa9\xbb\x51\x88\xae\xde\x38\xdf\x77\xa9\xa1\x64\xab\xbd\xd9\xd5\x8e\x52\xa6\xca\xf7\x22\x23\x89\xf1\x98\xe8\x5f\xbf\x96\x62\x36\xdc\xdb\xd4\xc1"}, +{{0xf8,0x9e,0xed,0x09,0xde,0xc5,0x51,0x36,0x1f,0xa4,0x6f,0x37,0x59,0x73,0xd4,0xfb,0xfa,0x5c,0x5c,0x12,0xf1,0xb5,0xe5,0xab,0xf4,0x5c,0xfa,0x05,0xff,0x31,0xa3,0x40,},{0x3e,0x0e,0xfd,0xca,0x39,0x19,0xfa,0x10,0xd4,0xa8,0x49,0xce,0xf1,0xde,0x42,0x88,0x51,0xbd,0x08,0xef,0xd2,0x48,0x59,0x4f,0xd8,0x9c,0xde,0xb9,0xde,0xee,0x43,0xb0,},{0x89,0x7e,0x6f,0x27,0x97,0xc3,0xf3,0x26,0xd2,0xcd,0xb1,0xd2,0x67,0x3d,0x36,0x06,0x31,0xf0,0x63,0x30,0x45,0x80,0xff,0x5b,0x4e,0xb4,0x3d,0x39,0xad,0x68,0x51,0x83,0x4c,0x9c,0xf8,0x91,0xd9,0xf0,0x90,0x5b,0xf8,0xde,0x07,0x5f,0x76,0x35,0xdf,0xca,0x60,0x1a,0xdc,0x0f,0x14,0xe7,0xb2,0xc7,0x6f,0x75,0x71,0xbf,0xa4,0x68,0xed,0x0c,},"\x4c\xf9\x77\x3d\xa0\x5f\xd3\x22\xfc\x14\x7b\xe9\x00\xef\x5c\xf2\x56\xc8\x8a\xfd\xad\x4b\x08\xc2\x30\xdf\xc8\x98\x1f\xb6\x9f\x47\x6f\x7d\x45\xef\x7c\x90\x06\xbc\x10\x03\x2b\xa5\x34\x36\xac\x22\x84\x3e\x0d\x76\x28\x9c\xf6\x8f\x98\x18\xfa\x64\x03\x1d\x4b\x40\x95\x50\x59\xaa\x69\x11\x09\x15\x88\x9f\x5e\x22\x73\x2a\x13\x43\x91\x25\x81\xab\x3b\x11\xa3\xba\xe7\xa4\x71\x35\x95\x08\x59\x65\x75\xf8\x88\x16\x0b\xee\xf9\x66\xe5\x70\x8f\x0e\x31\x47\xea\xcf\xce\xc1\xca\xa3\xef\x24\x0c\x5e\x0a\x14\xc1\x86\x54\x6c\x8e\xeb\x64\x65\x83\x50\xb1\xaf\xfc\x0c\xfd\x2a\xc2\x13\xaf\x67\x0a\xfc\xa7\xbb\xc9\xdd\xdd\x28\xa4\x65\xb5\x86\xe6\x9c\x38\x8c\xd7\x34\x78\xd6\x8e\xfb\x32\x2b\xdf\x86\xd9\x21\x30\x11\xe7\x11\xb2\xb9\x5f\xef\xa7\xbb\x9b\x59\x39\x76\x17\x06\xaa\x71\x21\x02\x49\x06\x42\x0b\xdd\xf1\xd8\x80\x0a\x43\x38\xd9\x38\xfa\x13\x7c\xf2\x7e\x9f\xfc\x51\xc6"}, +{{0x40,0x07,0x96,0xef,0x60,0xc5,0xcf,0x40,0x84,0xde,0xe1,0x80,0x1c,0x4a,0x19,0x75,0xe4,0x82,0xe7,0x0a,0xef,0x96,0x1c,0xd4,0x2e,0x2f,0xd5,0xa3,0xfa,0x1a,0x0f,0xbe,},{0xf4,0x7d,0xa3,0x81,0x28,0xf2,0xd0,0x12,0xcc,0x57,0x97,0x57,0x1d,0x47,0x9c,0x83,0xe7,0xd8,0xa3,0x40,0x98,0x02,0xf9,0xa7,0xd9,0x76,0xc2,0x70,0x67,0xcb,0xbe,0x43,},{0x84,0xd3,0xaa,0x3f,0x36,0x18,0x44,0x39,0x67,0x54,0xd8,0x0d,0x9f,0xa0,0x5b,0x8b,0x2f,0xa4,0xab,0xf3,0xa0,0xf3,0x6b,0x63,0x9b,0xee,0x9c,0xfb,0x5c,0x85,0x30,0xa3,0xa9,0xcc,0x34,0x67,0x7f,0x92,0xa9,0x13,0xc4,0x1e,0x80,0x0f,0x2e,0x80,0x41,0xf7,0x66,0x6d,0x07,0xed,0x85,0xf1,0x6a,0x57,0xd8,0x17,0xb1,0x24,0x1f,0xc5,0xee,0x04,},"\xc4\x73\x32\x5e\x78\x5b\x27\xdf\x44\x71\xee\xfb\x9e\xbe\xbd\x64\x61\xd5\x70\x80\x01\x81\x10\x0f\xf3\x6c\xaf\x3c\x38\xf6\x7c\x19\x21\xb1\x57\xec\x8e\x61\x26\xf9\x55\xae\xbd\x90\xea\x3f\xe5\x38\x5f\x80\x42\xcd\x70\x4b\x27\xcc\x1d\x69\x78\xc0\xe2\xa2\x96\x69\x5f\x5e\xf9\x7b\x7c\x2e\x16\xae\x4f\xf4\xd0\x63\xc6\x88\xd7\xf4\x6e\x96\x4e\x1f\x0a\x00\x50\x3f\x35\x73\x45\x97\x76\x83\xd6\xe4\xc3\x42\x3d\x56\xbd\xb6\xce\x86\x4b\x69\x87\xe0\x85\xe8\x3e\x70\xc7\xc1\xa1\x4e\x0e\x41\x3f\x59\x2a\x72\xa7\x1e\x01\x7d\x50\x5b\x64\xc2\x4f\x1a\x1a\x6b\x81\x3e\x06\x4e\x6e\x0c\xf8\xbd\x45\x71\xd0\xff\x2f\x26\x7a\x6a\x13\xe0\xcd\x43\x04\x63\xb6\xca\x3b\x88\xf0\xcd\x40\xb0\xfb\x83\xd5\xbe\xdf\x6f\x7d\x47\xe1\x70\xe8\x7d\x0a\x75\x00\x93\x69\x3e\xda\x23\x2a\x6d\xaf\x98\x12\x57\x27\xb9\x58\x8e\xcb\x89\x4a\xe3\x73\xba\xe3\xa4\x45\xa1\x06\x30\x64\x69\xa4\xc2\xcd\x77\xff"}, +{{0x67,0x03,0xa6,0x23,0x2c,0x5e,0x2e,0x65,0xe0,0xab,0x3b,0x92,0xe2,0xaa,0xf9,0xf5,0xfb,0xd3,0x3f,0xb4,0x69,0x88,0x04,0x7d,0x6f,0x4d,0x0f,0xf5,0x38,0x7f,0xa0,0x29,},{0x04,0x7c,0xff,0xca,0x8b,0x7b,0x11,0xac,0x6e,0xac,0xc0,0xea,0xa0,0xc5,0xb7,0x3c,0x75,0xb9,0xc6,0x37,0x95,0x69,0x73,0xaf,0x9d,0x97,0xb2,0xdd,0x5b,0x60,0x5d,0x6f,},{0xca,0xe9,0x68,0x79,0xe5,0xb6,0x03,0xbe,0x86,0x66,0x09,0xd4,0xa0,0x53,0xbf,0xa1,0x2a,0x51,0x37,0x8e,0x99,0xb2,0xa2,0x81,0x2e,0x47,0x89,0x26,0x7d,0x8f,0x32,0xf4,0x73,0x24,0x3f,0x8a,0xf7,0x4b,0x9b,0xe7,0x3f,0x47,0xde,0xa5,0x0f,0x0d,0x16,0x5e,0xbf,0x49,0x45,0x8b,0x73,0xe5,0x3d,0x88,0x58,0x0c,0x19,0x1a,0x18,0x2d,0x19,0x04,},"\xa2\x6b\x30\xa7\x69\x19\x79\x32\xa3\xa6\x28\x54\x96\x8d\x76\x01\x51\x61\x23\x66\x77\x8d\xc9\x94\x57\x6a\x2e\x0e\x03\x55\x49\x6b\x46\x20\x0e\x50\x69\x48\xa0\xd1\x02\xb6\x65\x1b\x2e\x73\x34\xca\x6c\x6e\xae\xf8\xbc\xa4\x4b\x42\x59\x70\xa0\xb3\x7d\x6b\xde\x0d\xa9\xd3\xc1\xb9\xf5\x1c\xbb\x25\xbc\x33\x5c\xd6\xfa\x92\x8a\x74\xf2\xc0\xdc\x2c\x6e\x99\xd3\x7a\x12\x86\x3a\x47\x4d\x4d\xf4\x3a\xad\x35\x41\x5f\xfc\xaa\x24\xd8\xc2\x9f\x91\x45\x72\xab\x2a\xbe\xc3\x89\x2d\xb4\x9e\x67\x9c\x5e\xa2\x20\xc2\xf5\x19\xa7\xd0\x33\xac\x1a\x2c\x5a\x46\x78\x69\xe3\x0e\xda\x3d\x26\x35\xca\x86\x34\x31\x47\x3f\x95\x8d\x55\x2b\xdc\x55\x82\x35\x2c\x29\x0d\x0c\xe4\xfa\x9c\xfd\x0a\xd4\x27\x99\xc2\x27\xec\x90\xb7\xc9\xe5\xdb\x9f\x5a\x7b\x6d\x56\x92\x12\xee\xd9\x4d\x32\x33\x26\x80\x5f\x2b\x3a\x00\x10\xd6\xc1\x1e\xb4\x10\x7c\x82\x83\x03\x76\x52\xf5\x0d\xc0\x67\xb6\xdc\x81\xf4\xdb"}, +{{0xe0,0xe7,0x2f,0x8f,0x17,0x86,0x33,0x62,0x67,0x33,0xbc,0xbd,0xa2,0xad,0x2a,0x50,0xe6,0x53,0x89,0x0f,0x15,0x35,0x9b,0x6c,0x22,0xfc,0x73,0x45,0xad,0x33,0x31,0x09,},{0xd1,0x3c,0xee,0x54,0x0d,0x84,0xb5,0x66,0x7d,0x51,0x6f,0xe7,0xec,0x72,0x39,0xbf,0x8d,0xa9,0x15,0x46,0xee,0x79,0x1f,0x84,0xed,0xd8,0xff,0xcf,0x3a,0x08,0x3e,0x76,},{0x14,0x55,0x21,0x71,0xb9,0x52,0x45,0xac,0x0f,0x0e,0x5a,0x6e,0x7a,0x2f,0x54,0x17,0x21,0x06,0x8d,0xb6,0x50,0xc6,0xda,0xda,0x04,0xc2,0x8c,0xab,0x7c,0x49,0x19,0x5f,0x64,0x36,0x71,0x21,0x44,0xcb,0x31,0x91,0x3c,0x56,0x2e,0x30,0xc3,0x9d,0x8a,0x85,0x49,0xfb,0x64,0xff,0xea,0x81,0xc7,0x44,0x51,0x43,0xb5,0xf2,0x32,0x86,0xda,0x05,},"\x79\x1f\xd6\x13\xc1\x09\x52\x92\xc8\xa4\xa2\xc8\x6b\x47\xae\x02\x61\x55\xb8\x46\x5b\x60\x7d\xbb\x41\x64\x77\xef\x79\xa2\x97\xc9\xd7\x75\x8c\xe3\x4a\xf9\xdc\xbf\x1c\x68\x47\x4f\x30\x90\x9f\xbe\x74\xb7\xba\x42\x96\x32\xf2\x40\x3a\xad\x83\x2b\x48\x6b\x72\xc2\x30\x54\xad\x42\xf7\x65\x3a\x9d\xdb\x45\x6c\xc7\x91\xf3\x48\x88\x6a\x7a\xe5\xdc\xec\x7c\x0b\xa8\x15\xf7\xa9\x3a\x10\xfe\x33\x1e\x90\x3b\x97\x0f\x7b\x50\x28\xbe\x49\xd1\x4b\xc5\x62\x0d\x63\x79\x26\x72\xb9\x8b\x94\x88\xc6\x7a\xe1\x66\x46\x69\x3e\x11\x20\x47\xf0\xac\x89\x21\xff\x56\x1c\x92\xdd\x05\x96\xd3\x2d\xf0\xa6\xe5\x07\xac\x1b\x07\xde\x51\x6c\x98\x42\x8d\x57\x0a\x37\xdb\x9b\xcd\x7c\x7e\x61\xc6\x94\x8a\xb3\xfe\x91\x25\x0d\xd1\xd5\xbd\x67\x12\x75\xdf\x9a\x97\x2f\x22\xc2\xba\x36\x80\x47\x47\xae\xc1\xea\x24\x16\xc1\xf4\x1a\xb8\x7b\xef\xde\x31\x62\x9b\x2d\x43\x31\x7c\xe4\x1c\xda\x03\x62\x62\x86\xc0"}, +{{0x54,0x4d,0xaf,0xd9,0x96,0x0d,0x82,0x97,0x56,0xc6,0xd4,0xb3,0xea,0xdd,0x44,0x37,0x5f,0xe7,0x80,0x51,0x87,0x6b,0xf9,0x78,0xa3,0x81,0xb0,0xde,0xca,0xaa,0x80,0x96,},{0xae,0x4f,0x64,0x25,0xc1,0xb6,0x7c,0xcb,0x77,0xf9,0xaa,0xcf,0xea,0x28,0xea,0xef,0x76,0x9c,0x8c,0xac,0xee,0x03,0x52,0x05,0xcd,0xcd,0x78,0x7e,0x8d,0x07,0x62,0x9d,},{0xa2,0xae,0x11,0x7c,0x8d,0xe4,0xca,0x6d,0x6f,0xe7,0x5e,0x46,0x60,0x23,0xbd,0x55,0x0c,0x26,0xfe,0xdd,0x3e,0x74,0xca,0x13,0xad,0xb6,0x25,0xf2,0x72,0xe1,0x75,0xf1,0x4d,0x5d,0xf5,0x50,0xac,0xe7,0xd8,0x22,0x88,0xef,0xef,0xab,0xf9,0x63,0x11,0xa1,0x23,0xbe,0xe2,0x38,0x89,0xad,0x37,0x11,0xbf,0xf2,0xb8,0x08,0x79,0x46,0xbf,0x0e,},"\x44\x7f\xe7\x34\x4c\xad\x1f\xae\x09\xd6\xa7\xd0\x5f\x09\xd5\x03\xc1\xb3\xd3\xd5\xdf\xa5\x84\x81\x0c\x35\xbc\x41\xe4\x95\x56\x93\x70\x61\x54\xe2\xd7\x51\xb2\xf1\xb5\x25\xe1\xa1\x45\x47\xba\x7f\x8b\x23\x20\x88\xa6\xfc\x92\x27\x02\xd9\x3a\x11\xcd\x82\x94\x9c\x27\xbe\xd6\x45\xdc\x35\x1f\xb4\xc1\x24\x2c\xf4\x1d\x01\x57\x54\x12\xe7\x92\xae\xd2\x14\x53\x1d\x94\xfd\x66\xe0\x3d\xd3\x2e\x97\x2f\xd7\x7f\x69\x47\xa3\x53\xe1\xae\x5e\x00\xf5\xa6\xca\x77\x99\x24\x72\xf0\x96\xb6\xe7\x47\x5f\xe5\x34\xe9\x13\xa7\x7b\xcb\x0d\x68\x1f\xdf\xb3\xa7\xa0\xdc\xb5\x6d\x27\x4d\xf4\xaa\x10\x9d\x4a\x8a\x37\x79\x4a\x92\x76\xf5\x00\x06\x69\x6f\xf1\x2c\xa4\xd0\x25\x40\x39\xdf\x0f\xb3\xf7\x2a\x96\x0d\xa0\x5c\x98\x72\xf2\xe3\x3e\xe8\x1d\x1c\xf7\xa6\xf4\x8b\xbc\xe0\xaa\x18\xc7\xc0\xf0\x6b\xa5\x5e\x67\x68\x9e\x0a\xf5\x87\xb5\x00\xea\xb7\x9c\xc7\xf9\x64\x0b\xca\x10\x4b\x7f\xbf\x31\xf0\x8e"}, +{{0xbf,0xbc,0xd8,0x67,0x02,0x7a,0x19,0x99,0x78,0xd5,0x3e,0x35,0x9d,0x70,0x31,0x8f,0xc7,0x8c,0x7c,0xc7,0xbb,0x5c,0x79,0x96,0xba,0x79,0x7c,0x85,0x54,0xf3,0xf0,0xf0,},{0x7c,0x5a,0xe3,0xba,0xb9,0x20,0x11,0x99,0xdf,0xbe,0x74,0xb7,0xd1,0xec,0x15,0x71,0x25,0xbd,0xba,0xa4,0x52,0x0f,0x50,0x1d,0xa3,0xf2,0x48,0x57,0x9d,0xc6,0xc2,0x2d,},{0xe4,0x86,0x15,0xb6,0x56,0x33,0xe6,0x19,0x93,0xb0,0xaa,0xa1,0xfa,0xfb,0x74,0xb9,0x62,0x9c,0x38,0x4f,0xd5,0x92,0xbd,0x73,0x5f,0xa1,0xf6,0x2c,0x5c,0xad,0x11,0x29,0x1f,0xcd,0x8c,0x2e,0x91,0xa5,0x0b,0xfe,0x0b,0x03,0xb4,0x35,0x02,0xff,0xf3,0xa5,0xc3,0x82,0xb9,0xc2,0x82,0x19,0x07,0xef,0xc3,0x4d,0xa5,0xba,0x05,0x4a,0xf0,0x0e,},"\x11\x7f\xae\x13\xe7\x87\x77\xb6\x21\x9f\x02\x02\x14\xc1\xb8\x7c\x57\x04\x6d\x1c\x09\xce\x82\xee\x2b\x56\x29\x89\x8d\x9b\x0d\xe7\x4a\x15\xcf\xe9\x9f\x80\x54\x8b\xa9\x13\xd7\x03\x6c\x56\x28\x5a\x4c\xba\x49\x3b\x52\xd2\xcb\x70\xd6\x36\x5a\xce\x3d\xa1\x2b\x1f\x34\xa2\x77\x8a\xf3\x6e\xf5\x2a\xb8\x2e\xde\x04\xca\xca\xf2\x79\x3f\x5f\x89\x83\x1e\x3b\x20\x5a\x9e\xe4\xc1\xd6\xfb\xda\xb4\xba\x4d\x9f\xae\x65\xdd\x79\xa5\xfe\x76\xb4\xb3\x9a\x30\x92\xcc\x71\x48\xd2\x11\xe8\x5e\xe8\x2a\xb4\x63\xd3\x4d\xce\xe9\x06\x1d\x9c\x21\xde\xd2\x05\x1b\xbd\x50\xb4\x13\xf0\xe2\x1a\x0e\x48\xd1\xff\xa8\xdc\xae\x24\x0b\x34\x95\xbe\x25\xd9\x31\x51\xb5\x7a\xa2\x71\xab\x99\xaa\x70\x8c\xa2\x80\x80\xca\xb4\x80\x4f\xce\xfa\x92\x9f\x5f\x1e\xf3\xf4\xc6\xc0\xfb\xfb\x40\xbe\xf7\xea\x1b\x50\x9b\x36\xba\x12\x60\x32\x35\x12\x37\x9d\x7b\xc3\xfd\xbb\x5d\x3f\xaa\xc9\xb0\x0e\x21\xf1\x2e\xa1\xca\x2e\x29"}, +{{0xdf,0x2d,0xf8,0xa9,0xd6,0x6d,0x56,0x38,0xcd,0xee,0x09,0x32,0x4e,0x7b,0x10,0xf8,0xed,0x29,0xab,0x91,0x38,0x7e,0x31,0x47,0xb7,0xdc,0x03,0xf7,0xcd,0x80,0x05,0x08,},{0x5c,0x04,0x2e,0x15,0x7f,0xb7,0xfb,0x12,0xd4,0xd4,0xfe,0xf2,0x84,0x71,0x41,0xec,0xfb,0x57,0xc1,0x25,0x3e,0x14,0xea,0xf3,0x00,0x4d,0x65,0x13,0xf5,0x2f,0xe6,0x25,},{0x9a,0x10,0x74,0x53,0x1e,0xd4,0x3d,0x07,0xbf,0xfc,0x7f,0x2b,0x6c,0x13,0xb8,0x83,0x8f,0xc7,0x5c,0xba,0x02,0xc7,0xd1,0xec,0x7b,0xa3,0x8b,0xca,0x3c,0xef,0x20,0xdc,0x9b,0xad,0xf3,0xa3,0x06,0x4a,0x2c,0x93,0xb1,0x84,0x24,0x41,0x42,0x0b,0x6a,0x8d,0x42,0x1a,0x96,0x0d,0x70,0xdf,0xb7,0xc7,0x0e,0xec,0x29,0x5f,0x21,0xf8,0x3f,0x0a,},"\x21\x57\x66\x15\xc9\x34\x6a\x63\xdc\xcf\x0c\x50\xec\xbd\x7c\x6d\x72\xad\x45\x2c\xfe\xd4\x3e\xa7\x32\x02\xcc\x7a\x98\x57\x60\x56\xb9\x66\x4b\x54\x62\x29\x05\xa1\xe7\x22\x17\x20\x73\x0a\xc6\x85\xd3\xbd\x39\x77\xec\x39\x59\xd4\x46\xbf\xa9\x41\xe7\x25\xb6\xfe\x16\xaf\xe5\x43\x2c\x4b\x4b\xde\xe7\xaa\x0f\xd8\x03\x09\x48\xed\x6f\xcb\xa7\xc0\xbd\xb4\x0c\x2e\x51\x7d\xa9\x74\x56\xe7\x4e\x1f\x93\xd5\xed\x67\x6d\xe0\xf4\xa8\xb0\xae\xa4\x49\x40\x4b\xd1\x5b\x6d\xa7\x9d\xc1\xb8\x13\x96\x5f\xe5\x57\x24\x10\xd7\x6f\x5b\x5e\xac\x66\x30\x50\x57\x03\x11\xdc\x98\x42\xb6\xfb\xf8\x80\x6a\xec\x03\x15\x17\x15\xca\xcf\x7f\x21\x80\x2e\x8b\xf5\xe9\x8a\x89\xc0\xd7\xd0\xd0\x98\xb7\x3c\x6e\xfc\x09\x96\x2e\x36\xb4\xe0\x30\xc1\xa6\x4b\x5d\x34\x9f\x5f\x20\x42\xc7\x44\x28\x67\x1e\x4a\x2c\x7f\xea\x0c\xae\xe2\x42\x2d\x85\xc4\xfc\xdd\xfe\xd3\x22\x13\x85\x9a\x69\x95\x5d\x4e\x3e\xbb\x7e\x1b\x20\x22"}, +{{0xe8,0xee,0x06,0x5f,0x99,0x07,0xf1,0xef,0xa2,0xda,0xec,0xb2,0x3a,0x04,0x25,0xf3,0x53,0x09,0x4d,0xa0,0x2b,0xc2,0xc9,0x31,0xf0,0xa5,0x87,0xef,0xc0,0xd1,0x3d,0xe1,},{0xc7,0x26,0x51,0xb7,0xfb,0x7a,0xc0,0x33,0x7a,0x17,0x29,0x77,0x49,0x6f,0xd7,0xf2,0xa7,0x2a,0xea,0x88,0x93,0x85,0x83,0x5e,0x56,0x3c,0x6b,0x60,0x53,0xa3,0x2d,0xc1,},{0xa5,0x10,0xdf,0xf4,0x2d,0x45,0x59,0xa1,0x9a,0x7b,0xf0,0xfe,0x0b,0xea,0x53,0xd3,0xe1,0xf2,0x2d,0xfa,0x6b,0xe5,0x50,0x39,0x89,0x5e,0x12,0xa5,0xd0,0x7d,0xa5,0xf2,0xe3,0x77,0x13,0xcc,0xb2,0xeb,0x21,0x60,0x11,0x62,0x8f,0x69,0x83,0xf8,0x71,0xfe,0xe2,0x86,0xe6,0x6f,0xff,0x4b,0xe7,0x58,0x2c,0x96,0x1a,0x1e,0xd7,0x56,0x84,0x04,},"\xa2\xf0\xc1\x37\x34\x73\xa3\x05\xd8\xf1\xd9\x91\x38\xb0\x6b\x9a\x96\x94\xff\xaa\x8a\x88\x22\x2d\xe9\xf7\x29\xbe\xe1\x30\x51\x75\xdf\xb1\x70\x01\xcc\x77\xf6\x7b\x6d\x40\xc9\x0c\x1a\x28\xfb\x22\x6c\x11\x28\x6d\xb4\xa1\x3e\x45\xe6\x92\x11\x24\x2b\xcd\xd0\x1c\xb6\xe2\xc4\x54\xe7\x6c\x0c\xab\x88\x1b\x4d\x2d\x9d\x3a\xb1\x00\xa5\xd6\x1d\x17\x25\xd8\x66\xe4\xfd\xb6\x6d\x93\xd7\x7f\x5b\x30\x86\x93\xb9\xb5\xa3\x33\xe5\x7f\xa2\x5d\x1e\x5d\x2e\x38\xdf\x6e\x4e\x9e\xc8\x41\x59\xbb\xee\x1f\xfe\xa9\x26\x83\x6a\x01\x01\xc9\x14\x83\xbd\x5b\xc8\x8a\x6f\x1c\xc4\xd4\xe7\xf0\x08\xad\x08\x45\x3a\x01\x23\x42\x9d\xd3\x35\x78\x1c\x7c\xbf\x8d\x68\x5a\x89\x99\xed\x11\x77\x60\x70\x04\xa1\x3c\x4c\xb5\xea\x49\x08\xc5\x42\x60\x7d\x3f\x2c\xd6\x69\x0c\xf1\xf2\xa7\x45\x5b\xbd\x38\xf5\x38\xf0\x7a\x10\x39\x64\x31\x7e\xfb\xce\xe3\x7e\xb4\x69\x31\xc0\x27\xcf\x15\x3e\xf8\x6e\x43\xd7\x82\x81\xeb\xd7\x10"}, +{{0xc7,0x2e,0x67,0xd8,0xc3,0xfe,0xc0,0x04,0xff,0x61,0x87,0x18,0xa9,0x09,0x9e,0xb8,0xad,0x7b,0x06,0xff,0x3b,0x8c,0x54,0x2a,0x7e,0x8b,0x98,0x47,0x31,0x34,0x75,0xe1,},{0x4e,0xb0,0x02,0xd3,0xcc,0xeb,0x18,0x8c,0x66,0x58,0xfe,0xc5,0x1c,0xb4,0x79,0xa6,0x52,0x64,0xac,0x55,0x5c,0x75,0xcd,0xc2,0x24,0x9c,0xf1,0xce,0x3d,0xef,0xc1,0x6d,},{0x2d,0x7b,0xab,0x8e,0xbd,0xa7,0xfc,0xa5,0xbb,0x3c,0x25,0xf5,0x1d,0xc5,0x1b,0x73,0xe6,0xff,0x6a,0x3b,0xb1,0xb5,0x2a,0xcc,0x78,0x11,0xa7,0xd2,0x59,0x5c,0xd6,0xfd,0xaf,0x73,0x04,0x94,0x41,0x8e,0x2f,0x57,0xef,0xdc,0x56,0x17,0xb0,0x66,0xfd,0x7b,0x62,0x07,0x68,0x0d,0x94,0xfb,0x8c,0x43,0xd3,0xd4,0x74,0x0b,0x41,0xcb,0x69,0x01,},"\xa8\xf3\x41\x35\xc0\x13\x2e\xc9\x5b\x64\xb0\xcb\xf5\x1d\x66\x90\x01\x43\x37\x04\x06\x79\x1f\xbb\x55\xf2\xb8\xca\x95\x3c\xc7\x4a\x46\xe0\x8b\x00\x2f\xa2\xda\x21\xb9\x51\xb8\x87\x1f\x7a\x29\xbc\x6d\x38\x79\x0a\xfc\x66\xa3\x29\xc3\x97\xd9\xf9\x25\x0b\xae\x0e\x30\xae\x34\x26\xe0\x8d\x8e\xad\x01\x79\xa3\xb3\x13\xc9\x08\x83\x91\x92\xf2\x89\xa3\xf3\xb6\xe9\x60\xb4\xc5\xce\xbe\xf0\xa0\x9d\xaa\x9c\x7a\x15\xc1\x9d\x4e\xbc\x6f\xc2\xac\x3c\xd0\x22\x32\xe8\x32\xb2\x34\xed\xd7\x96\x5d\x68\x7b\xfe\xb7\x58\xf7\x0f\xa7\x96\x38\x41\xb7\x85\x9b\xb9\x7c\x97\x1b\xd5\x57\xbc\x87\x69\x52\x4a\xc4\xc6\xee\xb3\x57\x97\x93\x33\x4b\x52\x2d\x17\x6b\xc6\x2f\x86\xb4\xd5\xc0\xd4\x01\x70\x36\xd2\xb6\xbd\x4e\x43\x84\x41\x6e\xf8\x26\x31\x39\x69\x1a\x86\x06\x17\x0d\x73\xc9\x3d\x64\x17\xdc\xc1\xa0\x8a\x53\x7c\x9e\xd4\x40\x04\x71\xa4\x6f\x52\x90\x7b\x46\xb1\x0a\x8b\x68\x89\xdb\xb4\x64\x7a\x8b\xbc\x71\x49"}, +{{0x69,0x64,0x50,0xb5,0x57,0xec,0x3c,0x94,0xcf,0x1a,0xf1,0x32,0x64,0x75,0x63,0x4a,0xa8,0x1d,0xef,0x38,0x14,0xff,0x30,0xa0,0x2b,0xa7,0xf2,0x04,0x4b,0x59,0xc0,0xfe,},{0x85,0x84,0x77,0x3c,0x56,0x6b,0x0e,0xed,0x3f,0x43,0x28,0x17,0x05,0xb5,0x75,0xa4,0x34,0xe4,0x7d,0x6c,0xf6,0xb2,0x51,0xb8,0x98,0x03,0xfe,0xf5,0x35,0x34,0xcb,0x29,},{0xce,0x8b,0x0a,0x57,0x79,0xf4,0xf5,0xf4,0x01,0xe8,0x4d,0x65,0x92,0x7a,0x0c,0x28,0xdf,0x82,0x9e,0x95,0xd0,0x9b,0xfa,0x97,0x11,0x1b,0x87,0x00,0x07,0x8f,0xf8,0x94,0xcf,0x72,0x77,0xe3,0x4a,0x71,0x61,0x44,0xd5,0x53,0x06,0xfc,0x9e,0x2f,0x64,0xcd,0x28,0x75,0x83,0xcc,0x80,0x03,0xbe,0x0e,0x8f,0xaf,0x26,0xaf,0x76,0x40,0x14,0x0e,},"\xcc\x25\x78\x29\xf3\x0a\x5f\x90\xdf\xdb\xc2\x47\xd4\x2e\x38\x87\x38\xb7\x6c\x41\xef\x8a\x82\xa5\xe0\x22\x5d\xdf\x1e\x38\x6d\x77\x08\x0b\x3b\x9d\xf8\x6c\x54\xb8\x5c\xdf\x2c\x32\xf3\x67\xab\xa0\xc3\xb6\xbf\x88\x8a\x5a\x69\x03\x52\x9b\x6a\xeb\x4d\x54\x07\xa1\x01\x80\x14\x91\x14\x13\x02\x28\xfc\x43\x56\xcc\xf3\x66\xb7\x7b\xe8\x97\x96\xa9\xe7\x1a\x0c\x69\x3f\x31\xe5\x84\xa4\xf1\x43\x09\x7b\xa3\x70\x36\x3b\x67\xb2\xf2\xe2\xfd\x8d\x6f\xe8\xb4\xe8\xdb\xf0\xd7\xdc\xc1\xa8\x36\x00\x41\x15\x8a\xa2\xaf\xf7\xe2\xa3\x25\xb8\xe5\x18\xf1\x93\xa2\x8b\xae\x05\xe3\xd5\x2b\x26\x62\x1a\xf4\x02\x02\x6d\x7f\x25\x0e\x86\xdc\xee\x30\x1a\x58\xb6\x31\xea\xdf\x45\x27\xe9\x58\xf0\x2a\x61\x58\x7f\x0b\xb5\x16\xce\xfa\xc0\x09\xfe\x51\x05\x2f\xff\x53\x33\x6d\xbd\x94\xe7\x26\x6d\x3b\x43\xca\xba\x8a\x1b\x38\xe5\xd8\x71\xc2\xa2\x4a\x4c\x41\x2f\xff\x3f\x7a\x9a\x52\xa8\xab\x23\xba\xc9\x79\x1b\x2b\x5a\x66\x9a"}, +{{0xa8,0xdd,0x35,0xf0,0x54,0xfb,0x6f,0xf6,0xf0,0xab,0x09,0x4a,0x0d,0x3d,0x1c,0x26,0x28,0x32,0x18,0x1d,0xf3,0x5c,0xcd,0x51,0x92,0x54,0x5e,0xbd,0x6a,0x9c,0xf5,0x29,},{0xca,0x41,0x23,0x38,0xd3,0x81,0x4b,0x88,0x6d,0x96,0x4b,0x71,0x92,0x5e,0x1a,0xab,0xb3,0xff,0xd0,0x78,0x34,0xdb,0xe7,0xdc,0x51,0x25,0x68,0x88,0x2b,0x53,0xe4,0xa3,},{0xfa,0x70,0x9f,0xbc,0x83,0x82,0xaf,0x83,0xd1,0x18,0x12,0x61,0x8d,0xfa,0xca,0x45,0x2e,0xab,0x83,0xe4,0xc5,0x3f,0xe9,0xe5,0x85,0x84,0x67,0xd0,0x7b,0x67,0x67,0xe1,0x79,0x75,0xc1,0xe0,0x63,0x93,0xd6,0xdd,0xe1,0x5a,0x34,0xd9,0x47,0x3d,0x1c,0xf4,0xd6,0xd8,0xc2,0xd5,0x73,0x94,0x52,0x00,0x80,0xfa,0xc4,0xe4,0x34,0x48,0xbe,0x07,},"\x55\xa7\xad\x91\x32\xd6\x3a\xc1\x61\xe7\xad\xb1\x32\xb9\x18\x9f\xdd\x84\xc3\x61\xc1\xe4\xf5\x41\x9a\x6d\xf7\x3d\xf4\xd7\xae\xb2\x9a\x8d\xc4\xbf\x01\x49\x0d\x4f\x48\x4e\x2d\x12\x07\x75\x17\xf5\xfc\x7a\xd0\xbd\xed\xa2\x0a\x6c\xb0\x22\x79\x42\x29\x0b\x08\xc3\xfe\x33\xab\x9b\x21\x35\xbc\x38\xa6\x57\x9a\x54\xbd\x98\x2f\x7d\x14\x17\xce\x86\x71\x17\xae\xa9\x18\xdb\xd3\xdd\x47\x6e\x7e\xb5\xb5\xd3\xc3\xe4\x8a\x86\x4a\x2f\x94\x2a\x31\x50\x1a\xa2\xb2\x9b\x53\xb8\x05\x13\xc9\x5d\x6a\x41\x18\x44\xf0\xde\xdf\x16\xa2\x9a\xc2\x67\xd3\x31\xe5\x3b\xdc\x25\x39\xbf\xcf\x32\xdc\x9b\x5d\x64\x0f\x12\x31\xe2\xca\xfb\x0a\xe9\x4b\xb5\x18\x94\x26\x86\x33\x64\x26\x2e\xfb\x47\xb5\xb5\xcc\xdb\xbc\x93\x32\x42\x16\xa7\x99\xb6\xf5\x0d\x37\x04\xf1\x5e\xd5\x9a\xf6\xcc\x7d\x91\x0c\xf0\x62\xd1\xbe\x63\x2d\xca\x5d\xf2\x13\xd4\x87\xd8\x56\x4f\x2b\x2b\xd7\xd8\x18\xbb\xa2\x7c\x36\x40\x13\xd9\x2d\x7f\x72\x62\x54\x62"}, +{{0xae,0x1d,0x2c,0x6b,0x17,0x1b,0xe2,0x4c,0x2e,0x41,0x3d,0x36,0x4d,0xcd,0xa9,0x7f,0xa4,0x76,0xaa,0xf9,0x12,0x3d,0x33,0x66,0xb0,0xbe,0x03,0xa1,0x42,0xfe,0x6e,0x7d,},{0xd4,0x37,0xf5,0x75,0x42,0xc6,0x81,0xdd,0x54,0x34,0x87,0x40,0x8e,0xc7,0xa4,0x4b,0xd4,0x2a,0x5f,0xd5,0x45,0xce,0x2f,0x4c,0x82,0x97,0xd6,0x7b,0xb0,0xb3,0xaa,0x7b,},{0x90,0x90,0x08,0xf3,0xfc,0xff,0xf4,0x39,0x88,0xae,0xe1,0x31,0x4b,0x15,0xb1,0x82,0x2c,0xaa,0xa8,0xda,0xb1,0x20,0xbd,0x45,0x2a,0xf4,0x94,0xe0,0x83,0x35,0xb4,0x4a,0x94,0xc3,0x13,0xc4,0xb1,0x45,0xea,0xdd,0x51,0x66,0xea,0xac,0x03,0x4e,0x29,0xb7,0xe6,0xac,0x79,0x41,0xd5,0x96,0x1f,0xc4,0x9d,0x26,0x0e,0x1c,0x48,0x20,0xb0,0x0e,},"\x9e\x6c\x2f\xc7\x6e\x30\xf1\x7c\xd8\xb4\x98\x84\x5d\xa4\x4f\x22\xd5\x5b\xec\x15\x0c\x61\x30\xb4\x11\xc6\x33\x9d\x14\xb3\x99\x69\xab\x10\x33\xbe\x68\x75\x69\xa9\x91\xa0\x6f\x70\xb2\xa8\xa6\x93\x1a\x77\x7b\x0e\x4b\xe6\x72\x3c\xd7\x5e\x5a\xa7\x53\x28\x13\xef\x50\xb3\xd3\x72\x71\x64\x0f\xa2\xfb\x28\x7c\x03\x55\x25\x76\x41\xea\x93\x5c\x85\x1c\x0b\x6a\xc6\x8b\xe7\x2c\x88\xdf\xc5\x85\x6f\xb5\x35\x43\xfb\x37\x7b\x0d\xbf\x64\x80\x8a\xfc\xc4\x27\x4a\xa4\x56\x85\x5a\xd2\x8f\x61\x26\x7a\x41\x9b\xc7\x21\x66\xb9\xca\x73\xcd\x3b\xb7\x9b\xf7\xdd\x25\x9b\xaa\x75\x91\x14\x40\x97\x4b\x68\xe8\xba\x95\xa7\x8c\xbb\xe1\xcb\x6a\xd8\x07\xa3\x3a\x1c\xce\x2f\x40\x6f\xf7\xbc\xbd\x05\x8b\x44\xa3\x11\xb3\x8a\xb4\xd4\xe6\x14\x16\xc4\xa7\x4d\x88\x3d\x6a\x6a\x79\x4a\xbd\x9c\xf1\xc0\x39\x02\x8b\xf1\xb2\x0e\x3d\x49\x90\xaa\xe8\x6f\x32\xbf\x06\xcd\x83\x49\xa7\xa8\x84\xcc\xe0\x16\x5e\x36\xa0\x64\x0e\x98\x7b\x9d\x51"}, +{{0x02,0x65,0xa7,0x94,0x4b,0xac,0xcf,0xeb,0xf4,0x17,0xb8,0x7a,0xe1,0xe6,0xdf,0x2f,0xf2,0xa5,0x44,0xff,0xb5,0x82,0x25,0xa0,0x8e,0x09,0x2b,0xe0,0x3f,0x02,0x60,0x97,},{0x63,0xd3,0x27,0x61,0x5e,0xa0,0x13,0x9b,0xe0,0x74,0x0b,0x61,0x8a,0xff,0x1a,0xcf,0xa8,0x18,0xd4,0xb0,0xc2,0xcf,0xea,0xf0,0xda,0x93,0xcd,0xd5,0x24,0x5f,0xb5,0xa9,},{0xb6,0xc4,0x45,0xb7,0xed,0xdc,0xa5,0x93,0x5c,0x61,0x70,0x8d,0x44,0xea,0x59,0x06,0xbd,0x19,0xcc,0x54,0x22,0x4e,0xae,0x3c,0x8e,0x46,0xce,0x99,0xf5,0xcb,0xbd,0x34,0x1f,0x26,0x62,0x39,0x38,0xf5,0xfe,0x04,0x07,0x0b,0x1b,0x02,0xe7,0x1f,0xbb,0x7c,0x78,0xa9,0x0c,0x0d,0xda,0x66,0xcb,0x14,0x3f,0xab,0x02,0xe6,0xa0,0xba,0xe3,0x06,},"\x87\x4e\xd7\x12\xa2\xc4\x1c\x26\xa2\xd9\x52\x7c\x55\x23\x3f\xde\x0a\x4f\xfb\x86\xaf\x8e\x8a\x1d\xd0\xa8\x20\x50\x2c\x5a\x26\x93\x2b\xf8\x7e\xe0\xde\x72\xa8\x87\x4e\xf2\xee\xbf\x83\x38\x4d\x44\x3f\x7a\x5f\x46\xa1\x23\x3b\x4f\xb5\x14\xa2\x46\x99\x81\x82\x48\x94\xf3\x25\xbf\x86\xaa\x0f\xe1\x21\x71\x53\xd4\x0f\x35\x56\xc4\x3a\x8e\xa9\x26\x94\x44\xe1\x49\xfb\x70\xe9\x41\x5a\xe0\x76\x6c\x56\x5d\x93\xd1\xd6\x36\x8f\x9a\x23\xa0\xad\x76\xf9\xa0\x9d\xbf\x79\x63\x4a\xa9\x71\x78\x67\x77\x34\xd0\x4e\xf1\xa5\xb3\xf8\x7c\xe1\xee\x9f\xc5\xa9\xac\x4e\x7a\x72\xc9\xd7\xd3\x1e\xc8\x9e\x28\xa8\x45\xd2\xe1\x10\x3c\x15\xd6\x41\x0c\xe3\xc7\x23\xb0\xcc\x22\x09\xf6\x98\xaa\x9f\xa2\x88\xbb\xbe\xcf\xd9\xe5\xf8\x9c\xdc\xb0\x9d\x3c\x21\x5f\xeb\x47\xa5\x8b\x71\xea\x70\xe2\xab\xea\xd6\x7f\x1b\x08\xea\x6f\x56\x1f\xb9\x3e\xf0\x52\x32\xee\xda\xbf\xc1\xc7\x70\x2a\xb0\x39\xbc\x46\x5c\xf5\x7e\x20\x7f\x10\x93\xfc\x82\x08"}, +{{0x6b,0xce,0x4d,0xfd,0x53,0xbf,0xa5,0x50,0x6f,0x2f,0x55,0x4d,0x2d,0x99,0x4a,0x0d,0xc4,0x0c,0xaf,0xcd,0xec,0x7e,0x1b,0xe0,0x50,0x00,0x6e,0x5c,0x5a,0x4b,0x38,0xa1,},{0xc8,0x90,0x02,0x37,0x28,0xd8,0x39,0x70,0x70,0x29,0x17,0x71,0xe6,0x5e,0x03,0x4d,0x34,0xd4,0xaa,0xe5,0xe2,0x47,0x65,0x3e,0x4f,0xf4,0xc0,0x74,0x59,0x1d,0xa7,0x02,},{0x99,0xae,0x67,0x82,0xff,0x27,0x64,0x6c,0x27,0xf6,0x1e,0x23,0x63,0x6a,0xe1,0x88,0x15,0x21,0xcf,0xa5,0xed,0x25,0x6f,0x70,0xbc,0xe7,0xce,0x00,0xb6,0x82,0x80,0xce,0x8e,0x0c,0x82,0xaa,0x76,0x5a,0xfb,0x8b,0x5a,0x1f,0xf2,0xfe,0x42,0xc5,0x74,0x41,0xe4,0x58,0xe4,0x43,0xdc,0x8b,0x12,0x34,0x77,0xae,0x33,0xd8,0x84,0x88,0x8c,0x0b,},"\x32\x39\x19\x07\x47\xee\x33\xd4\x0b\xf8\x70\xac\x9a\xd4\x9d\x88\xee\x32\x0f\x63\xc0\x52\x57\xe8\xab\x2c\x60\x30\x65\x97\xce\x76\xd1\xf1\xe7\x92\xab\x6a\x65\xca\xa5\x44\xfb\xec\x20\x89\x2f\xd4\x96\x05\x94\xf3\x1b\x37\x63\xef\x07\xd4\x98\x2e\xae\x4a\x2d\xbf\x33\x77\xdc\xc1\xe3\xf9\x5e\x46\xed\x39\xb7\xf0\x22\x2f\x04\xbb\x5c\x3b\x43\x4c\x8f\x9f\x31\x0d\xe9\xf1\x22\xa2\x9f\x82\x41\xe8\x1e\x20\x65\x49\xae\x62\x8d\x2b\x8a\xd7\x68\x97\x2c\x98\x84\x7c\x11\x88\xad\x04\xc8\x35\x35\x63\x78\xbe\xf7\x9c\xd1\x26\x86\x94\x05\xb1\x29\xfd\xbd\xc3\xbc\x48\x9c\xbd\x13\x99\x50\x5d\xad\xef\x76\x17\xb5\xbe\x5d\xa1\x73\xd3\xe8\x0e\x58\x38\xc9\x9e\x34\x92\x76\x24\x27\x29\xe0\x21\x9b\xd7\x47\x6a\xe5\xc4\xf8\x1a\x12\x87\x8f\xb4\x83\xa6\xc0\xe9\xb0\xdf\x29\x62\xeb\x0b\xf0\x01\x57\x78\x2c\xf7\x68\xa1\xb7\x1c\x01\x01\x69\xee\x85\x22\xde\xf0\x02\x4a\xd7\xe4\x57\x75\xa2\x90\x63\x9c\x53\xaa\xf4\x81\x98\xc4\x2d\xe7\x5c"}, +{{0x17,0x86,0x1a,0x8d,0x41,0x54,0xac,0xd4,0xfa,0x9c,0x8f,0xc9,0x47,0xc1,0x88,0x6c,0x11,0x29,0x0b,0xe2,0x22,0x87,0x2f,0xf4,0xf8,0xcd,0x25,0x93,0x9e,0x4d,0x13,0x61,},{0x43,0x77,0x3f,0x44,0x49,0x06,0x5e,0xae,0xba,0xf8,0x93,0x7b,0xaf,0x75,0x85,0x60,0xb0,0xc4,0xd2,0xde,0x46,0x97,0x78,0x39,0xb3,0xb8,0x73,0xd5,0xd7,0xd5,0xfd,0x8f,},{0xa5,0xee,0x02,0x4c,0xcd,0xbd,0xd4,0xc2,0x1a,0x24,0x70,0x9e,0xc5,0x3d,0xcc,0xb7,0xee,0x17,0x62,0x6d,0xd0,0x0a,0x09,0x3d,0x08,0x84,0xf5,0xb4,0x5c,0x4c,0x9d,0x16,0x91,0x84,0x01,0x51,0xc3,0x3c,0x8a,0xa0,0x7b,0x69,0xb3,0x4e,0x16,0xf6,0x16,0x47,0xeb,0xe7,0x93,0xae,0x4d,0xaa,0x70,0xcf,0xf4,0x8e,0x6a,0xb4,0x2f,0xfd,0xbc,0x00,},"\x18\x4d\xf5\xea\x32\x15\xeb\xe1\x80\x39\x0b\x0f\xf0\x42\xba\x23\x81\x15\x5a\x03\x8d\xc7\x32\xf7\x6a\x01\xc7\xe7\x0f\x82\xd1\xcc\xc9\xde\x9a\x05\x96\xb3\xfe\xe4\x47\x20\x9c\x99\x26\x84\xf6\x43\xdf\x21\xf4\xcf\x9d\x17\x92\x62\x79\x0e\x86\x23\xe4\x24\x72\xdc\x35\x19\x97\xe6\xda\x18\x9c\x07\xe1\xe8\x88\x2c\x07\xf8\x6c\x63\x37\xec\x01\x13\x91\x2c\xf9\x22\x15\xc8\xde\x19\x82\xb8\xfc\x57\xbf\xab\xc5\x5a\x3e\x87\x36\xf7\x36\x10\x42\x9d\x97\xfe\xb5\x1d\x79\x4f\x50\x5d\x0c\x5a\x0b\x3a\xbd\x48\xef\x7f\x55\xa6\x28\xf9\x0b\x85\x67\xa1\xc1\x5e\xa9\xd1\x90\xd7\xbf\x4e\xc2\xbc\x93\x34\xad\xa6\xcb\x92\x80\x8d\xfc\x20\x64\x83\x6f\xcf\xa4\x6b\x96\xfd\x7a\x5d\x6f\x4b\x05\x4d\xab\x09\xb7\x35\x95\xfe\xb8\x9e\xd0\x05\xb9\xec\x9d\x31\x88\x12\x1d\xe6\x96\x96\xd6\x4e\x7c\x7b\xbd\xfc\x1c\x46\x9f\xaf\x14\x8c\x38\xa7\x78\x59\x70\xaf\xe1\xac\xd0\x6a\x92\xc9\x94\x78\xfe\x44\x97\x4e\x3b\xb2\x09\x5e\x44\x67\xe9\xb2\xe9\x96"}, +{{0x0a,0x84,0xba,0xa5,0x4f,0x11,0xcf,0x17,0x09,0x0f,0xec,0x61,0xf3,0xf9,0x40,0x15,0x08,0xa3,0xa0,0x38,0x87,0xac,0xa1,0xa7,0x93,0x93,0x94,0xb1,0xee,0x40,0xa9,0x25,},{0x30,0x9a,0x73,0xc6,0x2d,0x23,0xd7,0x40,0xf2,0xe9,0x3c,0x18,0x58,0x7a,0xc1,0x5e,0x7e,0xc4,0x80,0xd2,0x5a,0xc0,0x79,0x4e,0x10,0xf8,0xcd,0x46,0x1c,0xc2,0xb1,0x30,},{0x4d,0x87,0x0b,0xd5,0x3a,0xf8,0xf1,0x3f,0x21,0x4d,0x99,0x34,0xec,0x90,0x3a,0xc4,0x82,0x84,0x09,0x2c,0xd9,0xb1,0x62,0xa4,0x4c,0xce,0xc8,0x51,0xfa,0x94,0x2d,0xe7,0x15,0xcc,0xda,0x07,0xb7,0x99,0x1d,0x71,0x27,0x23,0xe7,0xa4,0xd5,0xb4,0xf0,0x37,0x4a,0xb8,0x5a,0xc3,0x86,0x7e,0x0b,0x53,0xeb,0xc4,0x6b,0x53,0x0f,0x9f,0xed,0x05,},"\xfe\x70\x01\x7b\x14\x67\x8b\x0d\x3a\xd0\x3e\x18\x3d\x6f\x53\x31\x43\x78\x37\x9a\xb3\xda\x65\xb3\x51\x12\x57\xb3\xd5\x40\x86\xe8\x6f\x20\x31\x13\x90\x21\x39\x1a\xf9\xd7\x20\x85\xff\x7c\x3d\xc8\xc1\xe2\xd9\x1e\x53\x33\x38\x55\x42\x3d\x0f\x78\x5e\x2c\xc5\xf8\xb7\x79\x9f\xcf\x1b\x70\xe6\xbe\xcb\x78\x8e\x53\xe9\x02\x0f\x29\x95\xdd\xb0\xc3\x83\xa1\xf8\x10\x38\xfc\x3d\x54\x3c\xe0\xa3\x8c\x9c\x28\x8a\x9b\xc4\x07\x7f\x42\x77\xdc\xc6\xc5\x64\x22\x63\xfc\xfe\x19\x68\x80\x05\xa6\x03\xf5\x76\x75\xd2\x43\x4f\x3e\xd1\xf4\x6d\x32\xf1\x4e\xae\xb0\x73\xe8\x3e\xe7\x08\x6d\xa2\xfb\x67\x65\x9d\x3f\xb6\x8c\x62\x32\x0b\x77\x27\xb3\xb8\xea\x00\x65\x76\xbc\x2c\x7e\x6b\x5f\x1e\xce\xfa\x8b\x92\xe7\x0c\x92\xc8\x89\x51\xd0\xc1\x2d\x91\xde\x80\x1c\x38\xb7\xca\x5a\x0a\x04\xb4\xc3\x42\x9a\xba\x86\x38\x6e\x96\xe0\x6a\xfd\x20\xd4\xc5\xc2\xfe\x2b\x9b\x42\x73\xeb\x05\x20\x1a\x79\x27\x3a\xbd\xbe\xb3\x7e\xd1\x83\x0d\x22\x6b\x6b\xdb"}, +{{0x38,0x37,0x94,0x23,0xda,0xfd,0xbf,0x25,0xe1,0x9d,0x72,0x31,0xbd,0xdd,0x80,0xb4,0xce,0xfc,0xfe,0x2a,0xed,0x93,0x25,0x84,0xdf,0xa0,0xcc,0x3c,0x9f,0x92,0x32,0xde,},{0x59,0x7e,0x81,0xdc,0xee,0x94,0x48,0xb7,0x7d,0xe6,0x82,0x9e,0x79,0x21,0xc8,0xa3,0x90,0x53,0x5d,0x89,0xa0,0x84,0x94,0x30,0xae,0xd6,0x63,0x64,0xee,0x14,0x0d,0x8b,},{0xd8,0xb5,0x0a,0x88,0xae,0xd6,0xf2,0xa9,0x6d,0x08,0x22,0x13,0xad,0xf8,0xb2,0x51,0x9f,0x6a,0x0b,0xbd,0x30,0xdd,0x3c,0xb0,0xf3,0xfd,0x3c,0xe1,0xc6,0x43,0xfc,0x02,0x99,0x46,0xcd,0x43,0x46,0x2e,0xd2,0x25,0x13,0xf1,0xd6,0x5f,0xca,0x24,0xbd,0xe3,0x81,0x81,0x66,0xba,0xa8,0x6d,0xaa,0x79,0x87,0x92,0xaf,0xaf,0xe0,0xc1,0xa1,0x0a,},"\x36\x12\x5c\xa6\x66\x68\x80\x29\x06\x23\x7e\x63\xa2\xfe\x5a\xe6\x10\xf1\x1a\x7c\xf9\x25\x20\xd1\x9e\x66\x90\xa3\xad\xfa\xfd\x5d\x07\xa7\x84\xbc\x1a\x0e\x18\x52\x73\xd1\x1d\x34\x0d\x5e\xff\x90\x15\x97\xde\xdf\x45\x0c\x46\x99\xd4\x3f\x3f\xb1\x68\xd5\x57\xf6\xc9\xc0\x30\x77\xc3\xcd\xc3\x70\xd3\x48\x32\xcc\xdf\x2a\x8e\x3d\x75\x79\x64\x90\xed\x02\x42\x89\x9d\x25\xdd\xf4\x4b\xfc\x66\xf3\x29\xcf\x4c\x45\x16\x87\x03\xc3\x1b\xc9\x20\x2d\x89\x0f\x39\x69\xff\xd3\xac\x35\xa1\x28\x18\xdc\xa7\x51\xce\xb8\x80\x8f\xe8\x1e\xfa\x26\xa5\xe0\xd2\x00\xc5\xec\x1d\x94\xa5\x09\x7e\xa7\x4b\x64\x98\xfe\x28\x8f\x30\xc4\x8d\x72\x7e\x9d\x3d\x35\xc8\xe1\x2d\x85\x42\x07\x02\x55\x6f\x28\x61\x48\x4f\xfd\x09\xb4\xf1\x22\x65\xcc\x9a\xba\xfe\xb8\x2c\xf5\x90\x02\x88\x95\xa7\xd0\x50\xff\x57\xcc\xf5\xf2\x80\x22\xd0\x16\xab\x40\x94\xb0\x62\xe4\x8b\x66\xfd\x36\xd1\xe1\x96\x26\xe5\x21\x5e\xfa\x40\xfb\x7e\x3b\x70\x62\xf8\x1e\x95\x48\x30\xc9"}, +{{0xf9,0x25,0xd2,0x74,0xaa,0xf1,0xfe,0x1a,0x21,0x65,0x62,0x37,0x38,0x5e,0x97,0xf7,0x78,0x3e,0x78,0x09,0x0c,0x5d,0x42,0x17,0xfe,0xce,0x70,0x57,0xc8,0x0f,0x42,0x6d,},{0x3b,0x0f,0xc3,0x70,0xbe,0x3a,0x4b,0x19,0xa8,0x8a,0xb9,0x98,0xc5,0x95,0x04,0xff,0xb5,0x9a,0x87,0x60,0x63,0x38,0xe6,0x73,0xdf,0x5b,0x3f,0xab,0x4d,0x9b,0xfb,0x8d,},{0x79,0x54,0x9a,0x31,0x7d,0x10,0xa0,0xbe,0x32,0x2a,0x94,0xa1,0x51,0xad,0x11,0xe7,0x7e,0xfc,0x48,0x36,0xcc,0x80,0x06,0xa8,0x50,0x81,0x27,0x3d,0x76,0x02,0xa6,0x38,0x96,0x3a,0x9c,0xaf,0x19,0xc3,0xed,0xf1,0xe2,0x5f,0xad,0x1e,0x9d,0x68,0x70,0x1a,0x71,0xde,0xa7,0x27,0xda,0x6a,0x5c,0x5b,0xca,0xc9,0x33,0x95,0x89,0x22,0x4b,0x05,},"\x14\x3c\xaa\xfa\x5f\x62\xb1\x3e\x43\xdf\xfa\x49\xd4\x20\xfa\x99\xf7\x71\xb1\x92\x6d\x40\xd6\xcb\x2b\xbb\x42\x7f\x27\xb6\xc2\x66\xeb\x3d\xeb\x2d\x8b\xbb\xd4\x7b\x82\x14\xad\x40\x25\x1c\xb1\x90\x7a\xd6\x5e\xb9\x41\x93\xe5\x4a\xd8\x5c\x67\x00\xb4\x18\x9e\x80\xf1\xcc\x01\x54\xc6\x3e\xd1\x51\xa8\xbb\xbd\x30\xe0\x16\x37\xca\x58\xe7\x0a\xa3\xee\x52\xef\x75\xd0\x87\x30\x78\xa4\x05\x01\x4f\x78\x6e\xb2\xd7\x7b\x7f\x44\x22\xf9\x27\x82\x3e\x47\x5e\x05\xb2\x42\x45\xf9\x06\x8a\x67\xf1\x4f\x4f\x3c\xfb\x1e\xb3\x0b\xfe\xde\x7b\x32\x62\x23\x0c\xed\x9e\x31\x36\x1d\xb1\x96\x36\xb2\xc1\x2f\xdf\x1b\x9c\x14\x51\x0a\xcd\x5b\xc1\x8c\x0d\xdf\x76\x35\xe0\x03\x50\x3e\x6f\x71\xe1\xc3\x65\xcd\xfb\x4c\x65\xee\x75\xb4\xde\x06\x94\xaf\x87\x07\x63\x74\xd6\x31\xe6\xc4\xb8\xe2\x40\xfa\x51\xda\xb5\xe1\xf8\x0c\xa2\xa0\x6c\x49\xf4\x2e\xa0\x9e\x04\x75\xde\xfb\x18\x4d\x9c\xde\x9f\x58\xf9\x59\xe6\x40\x92\xaa\xc8\xf2\x02\x7e\x46\x81\x26\xf2\xfb"}, +{{0x97,0x1f,0x80,0x6b,0xe6,0xf0,0x7d,0x41,0xbe,0x88,0x30,0xff,0x8d,0xae,0x70,0x4b,0x08,0x63,0x8a,0xd6,0xcf,0xf7,0x22,0xd8,0x43,0x25,0x38,0x12,0x7b,0x76,0x96,0x25,},{0xaf,0x6a,0xc9,0x8d,0xce,0x20,0x78,0xa6,0xc7,0x3f,0x60,0x97,0xba,0xb6,0x3f,0x20,0x5c,0xaf,0x69,0x53,0xaf,0xa2,0x84,0xd0,0x42,0xbd,0x50,0xa4,0xfc,0xe9,0x6c,0xb4,},{0x20,0x37,0xa0,0xa7,0x67,0x4b,0x84,0xff,0x27,0xd0,0xb2,0x2f,0x62,0xb4,0xba,0xc6,0x5e,0x2d,0xc0,0xf5,0xfd,0xc8,0x99,0xfe,0xb7,0x80,0x0f,0x25,0xc2,0x99,0x81,0xde,0xe6,0x41,0xc5,0xa5,0x0f,0x8b,0x94,0x10,0x97,0x0b,0x49,0xd2,0xd5,0x36,0x58,0xc8,0x9e,0xe1,0x69,0x61,0xdc,0xcf,0x53,0x91,0xa6,0x91,0x8f,0x2a,0x84,0xea,0xda,0x0b,},"\x01\x34\x55\xd0\x49\xaa\x54\xed\x99\x5f\xbd\x94\xe6\x36\x99\x55\x49\x53\x95\xe4\x43\x88\x22\x25\x9b\x10\x60\xe9\xa3\x47\x79\x04\x2a\x1a\x69\x21\x1f\x6e\xa2\x07\x73\x99\xdd\x23\x48\x06\xba\x0b\x35\x3c\xd7\x9a\x57\xe1\xc4\x9b\x25\x0a\xb2\x71\x06\xdc\xde\x57\x6e\xcf\xa1\x15\xea\xe4\x61\xfe\xbb\x12\xd2\xda\x25\xff\xcf\x17\xb7\x15\xf8\xd9\x5c\x2f\x0c\x42\x5d\x5a\x81\xf7\x00\x11\x5b\x70\xd4\x9e\x1c\xfe\x49\xfc\xaa\x14\xfa\x20\x5e\x28\xec\x85\x24\x7f\x1a\x6e\x71\x28\xbf\x3b\xb3\x06\x0d\xc0\x84\x64\xbd\xa6\x53\x85\x40\xd0\xac\x47\x20\x93\xe5\xa0\x72\x0f\xde\x2f\x3d\xc4\x78\x8e\x0e\x9b\x0d\xbf\xe2\xa2\xb5\xf1\xa0\xf3\xf8\x0d\xe9\x84\x02\x5b\x15\xc6\x5a\xf7\x7f\x67\x1e\x1c\x5e\x28\x40\x44\x4d\xe5\xc7\xed\xa0\x25\xe6\xdc\x1a\x3f\xf1\x6e\x26\xcc\x54\xcd\xee\xd5\x6b\xe7\x3f\x9b\x01\xab\x2b\x1b\xc1\x6c\x8e\xf5\x8a\x5b\x76\xdd\x47\x28\x78\x07\xe5\xc5\x0f\x0d\x7c\x0a\x5b\x81\x20\xdf\xde\x64\x5a\x01\x2c\x5c\xf1\x14\x91\xbc"}, +{{0x2b,0xb0,0x65,0x2f,0x8f,0xff,0x69,0x01,0x99,0x11,0x48,0xc6,0x8a,0x32,0x67,0x87,0x72,0x71,0x00,0x6a,0xe9,0x58,0x91,0x49,0xbb,0x20,0x68,0x50,0xcd,0xf5,0x2f,0xb0,},{0xc0,0x3b,0x77,0xbe,0x98,0x3e,0x74,0xa2,0x34,0xc1,0x98,0x64,0x96,0xb2,0x92,0xe1,0x39,0x99,0x2e,0xb7,0x52,0x9e,0x70,0xb3,0xaf,0xad,0x7a,0xe4,0xfd,0xcf,0x8a,0x66,},{0x4e,0x15,0x8d,0xea,0xae,0xc3,0xd8,0x89,0x41,0x29,0x6a,0xf2,0xd2,0x73,0x41,0x01,0x2b,0x02,0x41,0xd4,0xe0,0xf4,0x6e,0x43,0x5e,0x37,0x5c,0x98,0x75,0xe8,0x9f,0x5e,0x32,0xc0,0x57,0xb5,0x27,0xbc,0x34,0x11,0xaf,0x09,0x6a,0x77,0xbf,0xce,0xb4,0x5b,0x98,0x3e,0xfe,0x45,0x5e,0x3f,0x03,0x15,0x5d,0x6b,0xc7,0xb0,0xac,0xc8,0xe6,0x0c,},"\xb9\x23\xca\x67\xe3\x96\xd8\x65\x6f\xa3\xdb\xce\x82\x89\xa3\x8b\xd3\xc1\x28\xce\xfb\x30\xef\xc1\x86\x2b\xb9\x44\xb4\x50\x78\x05\x41\x98\x24\xce\x2b\x83\xd6\x90\xef\x4c\xf1\x07\x49\x28\x17\x14\x3b\xf6\x4c\x02\x49\x89\xaf\x1a\x7d\x2e\x1f\x5a\xc9\x78\x74\xf8\x6b\xb0\xd3\x77\x3f\xf8\x40\xf5\x14\xd9\xa1\x39\x4a\x39\x59\xb0\x11\xd3\xa6\xb8\x16\xa3\xfa\xe5\xde\x17\xb2\xa9\xff\x34\x98\x63\xd2\x7f\xbb\xb5\x0c\xca\x73\x41\x08\x75\x10\x00\xd6\x35\x8c\xa0\x64\x7a\x93\xeb\x49\xe2\xe7\xaf\x06\x28\x7d\x48\xf2\xc0\x9d\x5c\x1c\x73\xe4\xd8\xf7\x7e\xa2\xbc\xaa\x73\x56\x79\x5b\x26\x72\x87\x19\xbe\xd5\xff\xdb\x82\x15\x78\xbd\x5d\x66\xbf\x92\xed\xaf\x8b\x23\x8b\x2b\xbd\x7d\x1e\x2c\x30\xa7\x87\xf9\x01\xa3\x3d\x0a\x76\x66\x9a\x9c\x3c\x7f\x2b\x55\x2c\xcb\x83\x49\xc7\xde\xd5\xe1\xa4\x61\x70\xcf\x28\xe3\x59\xe2\xfd\xd5\x4b\x05\xa5\x62\xf5\x28\xc6\x8a\x56\x97\x4d\xf8\x2d\x46\x66\x37\xc8\xe5\x32\x46\xa7\x21\x7e\x43\x86\x80\x1e\x0e\x32\x66"}, +{{0xdb,0x9b,0x81,0x2c,0xb3,0xc7,0xc0,0x3b,0x97,0x7f,0x48,0x7d,0x3d,0x65,0xcc,0xd9,0xcd,0x2f,0x3d,0xee,0x11,0x60,0x20,0x67,0xdb,0xfb,0x72,0xb5,0x89,0xff,0x3f,0x79,},{0xff,0xa0,0x38,0xad,0x8c,0x3b,0x37,0x8c,0xe7,0x5d,0x65,0x84,0x4d,0x08,0xe3,0xd6,0xa9,0x2d,0x19,0x4a,0x1b,0x78,0x62,0xe9,0xd9,0x72,0x0d,0x20,0x67,0x9b,0x29,0x44,},{0xa6,0x28,0xa7,0x74,0x21,0xb2,0xab,0xab,0x57,0x6e,0xed,0x35,0xd2,0xee,0x3d,0x14,0x56,0x1b,0x21,0xfa,0x14,0xa6,0xe2,0xfa,0xc2,0x63,0xc3,0xea,0xdd,0x79,0xf2,0xfc,0x06,0x69,0xf9,0x42,0x9b,0x91,0x0b,0x84,0x22,0xb4,0xb2,0x9a,0xc0,0x26,0xa4,0x2e,0x98,0xd1,0x81,0xbe,0x35,0x07,0xc5,0xed,0x7c,0x74,0x8a,0x1f,0xdc,0xf1,0xd8,0x07,},"\xa7\x00\x92\xc7\x69\x7c\xd4\xa2\x09\x56\x7c\x38\xba\x7f\xb7\x1a\xa8\xf1\x5e\x58\x27\xa2\x08\x76\x92\x39\x43\xfd\x6a\xdc\x65\x9c\x98\x67\xac\x6f\x58\xa6\x1d\xc7\xce\xc3\xd3\x62\x41\x16\x82\x00\x0c\x1a\x9a\xd1\x29\x5e\xb8\xb7\x0f\x24\x2d\x86\xb5\x86\x5e\xb7\x6b\x87\xe3\xf2\xc6\x94\x1d\x26\x12\xee\x3b\xcd\xe8\xf1\x97\x65\x56\x67\x33\x15\x2e\xf5\x4e\x95\x69\x09\x43\x28\x5f\x78\xb3\x75\xf4\x03\x65\x85\xd4\x73\x9d\xee\xde\xef\x6d\x94\x6d\xb6\x1c\xa4\x58\xef\x4f\x65\x0d\xa9\x63\xc3\x85\xe2\x9d\xfd\xee\x41\x5f\xe4\x95\x84\x5f\x55\x19\x7a\x87\x0f\x8c\xde\xb5\xa0\x10\xba\x6b\xbb\x32\xbf\x1a\x58\x8c\xc7\x74\xd4\x89\x01\x84\xc4\xb2\x92\x4a\x5b\x80\x73\x31\x3b\xce\x22\x65\x85\xf1\xad\xfc\x22\x9c\x90\xbc\x6c\xc9\xd2\x12\xe6\x2f\x05\xd3\x3b\xed\xac\x96\x1d\x77\xcf\x8c\x26\x20\xe4\x51\xde\x81\x7f\x8c\x1b\xb1\x6a\x2c\x59\xff\x80\x4b\x63\x5a\x73\xa8\xcf\x8c\x18\x1b\x3f\x94\x01\xc3\xb6\x43\xd1\x8a\x2f\x70\x6e\xa9\xca\xe4\x70\x71\xa6"}, +{{0xce,0x37,0x9b,0xbe,0x2f,0xa8,0xab,0xcb,0xa5,0x1c,0x7a,0x75,0x43,0xde,0x5b,0x71,0x80,0x77,0x1b,0x3c,0x44,0xbc,0x6b,0x41,0x89,0x2e,0x7b,0x88,0x97,0x9b,0xab,0x90,},{0x7f,0x3c,0xff,0x89,0xf4,0x1b,0xab,0xf4,0xfa,0x64,0xcb,0xa3,0x3a,0x5b,0xb1,0x7f,0x41,0x3b,0xbf,0x2a,0x1e,0x11,0x2b,0x50,0xa8,0xe9,0xb1,0xf8,0x21,0xd8,0x49,0xbf,},{0xda,0x98,0xdf,0xb1,0x89,0x38,0x5b,0x2c,0x85,0x3b,0x6c,0xf3,0x75,0x73,0x80,0x46,0xa8,0xf2,0x7e,0xf2,0x79,0x74,0xab,0xce,0xce,0xa1,0xdb,0x02,0x98,0x9b,0x95,0x1f,0xe4,0x33,0xa6,0xce,0x1e,0x22,0x5b,0x3f,0xa8,0x20,0x32,0xfe,0x06,0x0a,0x7d,0x3f,0x6c,0x18,0x3f,0xd1,0x15,0x7f,0x79,0x1a,0x06,0x4b,0x40,0x76,0x50,0x57,0x16,0x00,},"\x00\x1a\x74\xf0\x95\xc8\x14\xd3\xbe\xed\x67\xa8\xd1\x5f\xc1\x8e\xfe\x23\x5d\xc3\xf6\x45\x78\x12\xa4\x03\x9b\x7a\x46\xfe\x9a\x0e\x9d\xe8\x1a\x7a\x4e\x5f\xba\xb5\xeb\xe9\xe1\xe4\x80\x1b\xd1\x1b\x45\xc9\xf7\xad\x06\x36\xa0\x9b\xff\x42\x16\x4b\xe5\x74\x9a\x04\xc0\x2f\x0a\xb6\x1f\x0e\xcf\xdf\xef\x79\x9b\x82\x7d\xa6\xa2\x74\xc8\xd3\xb3\x9f\x2e\x38\x05\xa6\x79\x12\x87\xee\xdb\x23\x14\xd3\xf8\x42\xb5\x58\xb9\xb4\x89\xaf\xe1\xed\x37\xbb\xbc\xfc\x5e\x60\xa4\x31\xd5\xac\x60\xb3\x9e\x94\x6d\x90\x3d\x6b\xf6\xb1\x40\xe1\x2c\x7e\x07\xf9\xed\x7a\xc4\x6a\x39\x99\xc6\x24\x5c\x8a\xb1\xbd\xb2\x18\x79\xa3\x17\xa3\xdc\xd2\x57\xa5\xc4\xf3\x49\xb7\xf5\x9e\x4e\x43\xd6\x2d\x9f\x1c\xd1\x6f\x51\x8f\x1c\xa6\xca\xd3\x7e\x2c\xb2\x0f\x25\x98\xc4\x13\x42\x91\xc6\xb8\xa9\x8a\xae\x52\x47\xe2\x6e\xef\xb7\x6a\xa3\x8c\x9c\x82\x31\xc1\x7e\x9d\xbf\x27\x1c\xec\x80\xfb\xa5\xb4\xa8\x34\xbd\x9b\xe8\x1e\xa8\x41\x63\x7a\xa9\xcd\xd4\xc4\xbf\x26\xd7\xad\x24\xca\x3c"}, +{{0x2b,0x2e,0xe8,0x09,0xd6,0x47,0x02,0x3e,0x7b,0x77,0xfc,0x54,0x1f,0x44,0x87,0x5a,0x35,0xfa,0x94,0x1d,0x37,0xf7,0xc5,0xb2,0x1f,0xd3,0x49,0x34,0xd2,0x39,0x19,0x35,},{0x2c,0x29,0xd5,0x3e,0x1b,0xf2,0xc7,0x87,0x9d,0x73,0xd2,0x0b,0xa8,0x8c,0xa0,0x7a,0x0b,0x21,0x6d,0x7f,0x6d,0x05,0xd9,0x36,0x63,0xa6,0x5c,0x3d,0x9e,0x10,0x63,0x3a,},{0x12,0xd9,0x06,0x85,0x77,0x55,0x72,0xc9,0xea,0xbc,0x9b,0xe2,0x57,0x4c,0xa9,0xae,0x66,0xf0,0xe6,0x52,0xe5,0x78,0xb2,0x17,0x36,0xcd,0x6e,0x65,0x4f,0x7c,0x6b,0x15,0x45,0x88,0x3d,0x56,0xbf,0x76,0x0c,0xcf,0xc3,0xcf,0x87,0x54,0x4e,0x00,0x04,0xc7,0x98,0x06,0x12,0x57,0xe1,0x30,0x03,0x0c,0xb9,0x97,0xa7,0x88,0x36,0x9a,0x9a,0x05,},"\xc4\x14\x7d\x64\xeb\xfd\xa4\x1a\x1b\xe5\x97\x72\x62\x95\x81\x04\xe9\x40\xc3\x87\x6b\xcd\x5b\x69\x56\xac\xfd\xec\x32\xc6\x60\x91\x4d\x62\x62\x3c\x21\x06\x63\xcb\x2c\xbe\x62\x49\xd7\xf5\x27\x49\x91\xc6\x0e\x95\x0e\x8e\x28\x09\x04\x99\x53\xc6\x95\x81\xd2\x46\x9f\x4f\xe9\x82\xc7\x43\x4f\xed\xd9\xd4\xe0\x0a\xe0\x88\x96\xd6\x2c\xc1\xfb\x98\x4d\xd2\x33\x15\x0c\xc2\x48\x3e\x15\x9c\xff\x40\x97\xdf\x8c\x03\x6b\xb6\x33\x00\x3a\xbb\xfb\xe1\x8c\x8f\xa7\x9b\x5a\x22\x27\x08\x38\x12\x3f\xc9\xbe\x39\xb8\x89\x2c\x80\x38\x4a\x38\x50\x28\xc1\xa8\x1e\xc5\x8c\x8f\x21\x06\x0e\x78\xaf\xd2\xc0\x4b\xfd\x2d\x30\xca\x39\x77\xc6\xed\xad\x51\x8c\xc1\xe2\x00\x4c\xdc\x14\xbf\x3d\x15\xf5\xf5\x28\xe5\xaf\x27\x7f\xa1\x82\x27\x58\x70\xe5\xc0\x12\xf5\xf8\x2f\xb1\xaf\xd0\x4e\xdd\xe4\x57\x8d\xdd\x21\x60\xa1\xa3\xdb\xc0\x50\xe8\x0b\xdd\x81\x1b\xc8\x8e\xad\x79\xbf\x93\xf0\x10\xcd\x0f\xd4\x43\x3d\x0b\xc3\x48\xda\xcf\xd0\x94\x7c\xce\xda\x62\xbf\xa4\x97\x11\xd0\x13"}, +{{0x4e,0xa1,0x8d,0x6b,0x4a,0xf8,0x05,0x3b,0x88,0x5e,0xc1,0x88,0xbe,0x48,0xde,0xb8,0x6f,0xfb,0x2a,0x69,0xa4,0xce,0xc8,0x66,0x37,0xbb,0xd7,0xb4,0x1b,0x80,0x7c,0x46,},{0xe5,0x98,0x60,0x59,0x97,0x62,0x33,0xed,0x77,0x38,0x2c,0x3d,0x99,0x59,0xf3,0x4e,0x31,0x79,0x62,0x69,0x65,0x53,0xe8,0x6e,0xd1,0xe5,0x90,0x2c,0x4b,0xed,0xd1,0x67,},{0x27,0x57,0x0c,0x00,0x2a,0x48,0x7d,0x00,0x0c,0xa3,0x92,0x8b,0x83,0xcb,0x43,0x19,0x72,0x2c,0x46,0xdf,0xb4,0xcc,0xa2,0x60,0xde,0x79,0x0e,0xc0,0xe3,0xc1,0x93,0x26,0x88,0xf8,0x73,0x62,0x95,0x28,0x18,0xb5,0x4f,0x51,0xbc,0x7a,0xee,0xb2,0x63,0xf9,0x60,0xbc,0x0d,0xa8,0x96,0x4b,0xf3,0x12,0xef,0x93,0xe8,0x1f,0x06,0xc8,0x0b,0x04,},"\xe9\xc8\x9a\x1a\x11\x19\x37\x32\x06\xce\x40\xed\xe3\xb8\x9a\x82\xf8\x94\x62\xa1\xde\xe9\xe7\x89\xe9\x84\x5e\xec\x21\xf5\x71\xc0\xfa\xef\xd4\x30\xad\x33\x8e\x4a\x72\xc0\x47\xa3\x9a\x42\x59\x58\x03\x87\xfb\x9a\xac\xad\xdc\x36\xa2\xb5\x1e\x7b\x60\xa8\x7c\xa1\x32\x1f\xf8\x06\x79\x4c\xd6\xdd\x45\x49\xa4\xdf\x45\xc2\xda\xe3\xe5\x39\xc4\xd7\xd0\x6b\x6e\x6e\x9f\x46\x6f\xfc\xa2\xfa\x49\x78\xce\x3d\xc7\x92\xe4\x4a\x62\x83\x88\x0c\xd1\x38\xa7\x5a\x22\x6f\x98\x5d\xa4\x1f\xfd\xc0\xe3\x2a\x5a\x85\xc8\x5f\xe9\xa4\x3a\xe7\x8f\xcf\xe5\x7f\x4d\xd7\x54\x0a\x6d\xd3\x92\x4a\x49\xab\x39\xeb\x69\x95\x0d\x42\x11\x51\xd9\x6b\x1e\x4f\xd3\x93\x58\x90\xf6\x34\xcd\x52\xa7\x3a\x75\x5f\x5c\x2f\xb7\x2f\x9c\xd5\xa2\xe6\x7e\xa9\x30\x91\x5e\x13\x3b\x47\xcf\x6b\x7c\x10\xa9\xd8\x89\xc6\xaf\x6b\x5f\x1f\x4f\x51\x09\x4d\x27\xfb\xba\x22\x8a\xc2\x26\x8b\x34\x40\x27\xfd\x49\xe4\x26\x34\x3c\xc0\x13\x43\x99\xb4\xb5\x10\xaa\xea\x50\x23\x4d\xf4\x2c\x37\xfa\x1c\x4f\x4d\x0e"}, +{{0xfc,0x1b,0x75,0xd1,0x7d,0x38,0x07,0x21,0x73,0x51,0xd2,0xaa,0x40,0xd9,0xb0,0x4f,0x52,0x5b,0x89,0xed,0x3f,0x5f,0xcd,0xb3,0x11,0xbe,0xc2,0xae,0xc5,0xcb,0x7e,0xce,},{0x55,0xe4,0x84,0xe7,0x74,0xa4,0x39,0x2a,0x9d,0x6e,0xef,0xf8,0x35,0xa8,0xfb,0xb2,0x32,0xcf,0x62,0x76,0xa8,0x9c,0x74,0xfc,0x0d,0x1b,0xb2,0x04,0x5a,0x8b,0x21,0xbe,},{0x9a,0x68,0xd1,0x51,0xfe,0xa3,0x90,0x98,0x93,0x35,0x9e,0x60,0xb9,0x6b,0x68,0xb2,0xa3,0xe2,0x94,0x6f,0x2b,0x47,0xb8,0x75,0x39,0x8a,0x1e,0x39,0xeb,0x01,0x46,0x3d,0x35,0xea,0xe7,0xd9,0x76,0xf8,0x33,0xa7,0x62,0xb5,0x1f,0x27,0x26,0xee,0x0d,0xcc,0xad,0x5c,0xe3,0x60,0x05,0x64,0xfd,0x9d,0xd5,0x8c,0x23,0x80,0x7f,0xdf,0xfd,0x05,},"\xd0\x31\xbd\x11\xda\x30\x80\x97\xe3\xbe\xb6\xff\xdb\x26\x00\xee\x6a\x19\x3c\xa6\xd8\x32\x45\x01\xc9\x72\xb1\xa2\x51\x66\xfa\x7a\x36\x9f\x5b\xc8\x82\xea\x45\x61\x2c\xf0\x25\x80\x25\x4d\x21\xb4\x0b\x03\x63\x23\x7e\x83\x5d\xae\x26\x56\xc1\xb7\xf4\x73\x6e\x88\xbe\x53\xd6\xb1\x19\xc0\x7f\x57\x29\xbb\xd8\x2f\x67\xde\x03\x58\x83\x22\x87\x92\x43\xc5\x99\x0a\x7e\x61\xf5\x69\x07\xb2\x41\x71\xa5\x7c\xbb\x0b\xbe\xfb\xa2\x31\x62\x77\xaf\x93\x26\xf9\xcb\xf3\x53\x8b\xcb\xf6\x78\x0b\xe4\x18\x25\xa2\xca\x77\x4b\x41\xbd\xb1\xcd\x5c\x60\x88\x51\xec\x23\x39\xeb\x2f\x4f\xee\xdd\xaa\x89\x1a\x63\x26\xb2\x9d\x97\xd7\xfb\xf3\x11\xe3\xbb\x74\x9c\x5d\x4c\x05\x8d\xcc\x14\xf4\x52\xf9\x33\x49\x91\xe2\x71\xc1\x6d\x65\x08\xc8\x18\x63\x39\x27\xf4\x29\x80\x4c\xa7\xa3\x81\x70\xf1\xb9\xf6\xbd\x73\xed\x67\x5e\x11\xe8\xc0\xd3\x21\xfa\xc9\x12\x73\x0b\x4b\xa2\xf7\xc4\x28\x53\x4a\xdc\xaa\x4d\xad\x31\x4c\x55\x80\x7e\x6c\x64\x2d\x49\x4c\x6b\x2f\x0e\x8c\xd1\x29\x77\x5c\xc0"}, +{{0x0d,0x0b,0xf4,0xd4,0x2e,0xf8,0x10,0xb1,0x79,0xeb,0x84,0x17,0x71,0xde,0x6d,0xbd,0xe7,0x63,0x61,0xca,0xf8,0x94,0xe4,0x2a,0x14,0xb1,0xe0,0x97,0x87,0xea,0x3e,0x06,},{0x71,0x71,0x51,0x0b,0x43,0xfc,0x17,0xef,0xa8,0x0b,0x15,0xe3,0x20,0xb1,0xb0,0xa4,0x08,0x33,0x25,0x42,0xe0,0xd3,0x6e,0x4a,0xb9,0xa6,0x49,0xcd,0x94,0x1b,0x5a,0xed,},{0x24,0x44,0x6b,0xdf,0x03,0x41,0x6a,0x4d,0x08,0x61,0x44,0x66,0xfb,0x85,0x1d,0xb5,0x0e,0x91,0xa6,0x23,0xca,0xcd,0x1b,0x0b,0x35,0x66,0x0f,0x3c,0xf9,0x33,0x20,0x0e,0x15,0x30,0x87,0x08,0xda,0x34,0x99,0xa5,0xad,0x25,0xf0,0xf0,0x30,0x6b,0x79,0x42,0x76,0x2e,0x20,0xa7,0x65,0xb7,0xca,0x9b,0x90,0x1c,0x75,0x0b,0x3a,0x95,0x32,0x0a,},"\x8e\x21\x79\x97\x5d\x0a\x8e\x5a\x69\xfe\x87\x5a\x3c\xb1\xe7\x9a\xec\x49\xc3\x85\x3e\x30\xdd\x03\x20\xfe\x3e\xbf\xb6\x38\xb8\x2f\x89\xad\x16\x43\x03\x6b\x37\xe5\x6e\x0b\x55\xe0\xa9\xe2\x2a\x4e\x28\x3d\x7a\x27\x48\x5c\xe9\x10\x2d\xb6\x78\x7d\x66\x28\xb7\x79\x13\xe1\x08\x96\x77\x4e\x49\x5c\x26\xe8\xba\xb2\x6e\x7f\x9a\x94\xd2\x9a\xaa\x36\xae\xc9\xc2\x6a\xd3\xf5\x0e\x5d\x8c\x0b\x76\x98\xbb\x5f\x01\xb8\x76\xd0\xd6\x5f\xcf\x5e\x9e\x32\xcd\x7b\x89\x82\x9e\xd0\x5b\x0b\x8f\x63\xa9\x38\x58\x98\x5b\xc9\x56\x9f\xce\x42\x9f\xd3\x7a\x21\x1a\xbe\xd6\x50\xf5\x85\xc3\xb5\x59\x00\x44\x3b\x6c\x5d\x6e\x8a\x48\xba\x67\xde\xee\xd0\x7b\x76\xe9\x69\xfc\x88\x43\x0f\xce\x27\x09\xc0\xbb\x5c\xe9\x26\xab\x7f\x44\xe0\xcd\x79\xf4\xec\x35\x9e\xf7\x67\x48\x88\x3f\xcc\x3d\x02\x6e\xdd\x06\xc8\xb9\xcb\xa5\x4b\x99\x0d\x30\xaa\x41\xf1\x44\x8a\x10\x89\x3f\xb0\x53\x92\x80\xc5\x99\xd4\x23\x61\x43\x3a\x34\xcd\xaf\xd8\xeb\xdd\x92\xef\xb9\xc3\x8a\x36\xda\xf4\xc7\x40\x60\xc6\x96"}, +{{0x57,0xb5,0x19,0x4d,0x26,0xab,0xe4,0xab,0x21,0x16,0xc0,0xf0,0x3d,0x23,0xdb,0xe1,0x16,0xd4,0x88,0x25,0xa2,0x5e,0x77,0xd6,0x46,0x48,0xb4,0x36,0x92,0xae,0x25,0xbf,},{0x49,0x9c,0x02,0xdb,0xad,0x2a,0x4e,0xab,0x3b,0x6f,0xf1,0xab,0xa3,0x94,0x4b,0x91,0xc3,0xf2,0x73,0xa3,0x82,0xc5,0x48,0xa6,0xf3,0xa1,0x9c,0x83,0xf0,0xa8,0x67,0x24,},{0x4c,0x73,0x45,0x96,0x0c,0x8f,0xd4,0x8a,0x7d,0xea,0xd7,0x1d,0xbd,0x61,0x90,0x84,0x68,0xef,0xa8,0x65,0xa1,0x35,0x56,0x8c,0x8f,0x9c,0xa0,0x05,0x54,0x83,0x46,0x86,0x17,0xa7,0xe3,0x35,0x84,0x0f,0x57,0xc6,0xcd,0x8f,0x2c,0x98,0x05,0xcd,0x47,0xa9,0xd7,0xcd,0xfd,0xe5,0x3d,0xa8,0xef,0x4f,0x1a,0xdb,0xb6,0xf6,0x98,0xaa,0xf1,0x00,},"\xb4\x81\x3c\x9d\x13\x21\x5f\xe9\xf6\x3a\x78\xff\x7a\xc9\x51\x73\xeb\x81\x0b\x46\x13\xf0\xf4\x8d\x68\x76\xb2\xbd\x3b\x2c\x72\xbc\x7d\x98\xcb\x1a\xc3\x2b\xc4\x1c\xa4\x7f\x09\x89\x6f\x79\x20\x4e\xcf\xb8\x26\x4c\xe8\xf3\xc3\xe7\x6d\xc1\x24\xda\x8d\xdc\x6e\x0d\xfc\x1e\x13\xb5\xa5\x29\xf2\x0c\x82\x61\x3f\xb9\xa8\x2e\x5f\x5d\x77\x32\x6a\x86\x1f\xae\xda\xbc\x73\x25\xc5\x9a\xf3\x3d\xae\x67\x44\x02\x5e\x64\x97\x74\xfc\x4f\x79\x13\x4b\xf9\xf6\xe3\xd5\x87\x5d\xd9\x1b\xc8\xa1\x4c\xc3\x6a\x66\x28\x3d\x01\xd8\xd1\x08\xc1\x33\x27\xec\xa5\x30\x57\xba\x50\xbf\x21\x0c\x19\xf1\x39\xde\x64\x94\x98\x26\x46\x19\x8a\x12\x46\xc2\x71\xb0\xa3\x68\xc1\x0a\xab\x95\xcd\x89\x61\x23\x5d\x74\x2d\xf4\x54\x5b\xe6\x8b\xd0\x10\xdc\x0d\xb2\x3b\x67\x3e\x62\x36\x09\xe4\x20\xee\x76\xb1\x05\x6c\x52\x0f\x9c\xe8\xfb\xe8\xee\x18\x63\xdf\x97\xd1\x7b\x71\x74\x63\x6c\x3a\x2b\x61\x22\x95\x09\x19\x48\x81\x0d\x1d\x4b\x8a\x58\x43\x76\x0a\x28\x87\xdc\x55\xef\x51\x2a\xf0\x41\xec\x54\xfa\xd3"}, +{{0x06,0x8d,0x27,0xb2,0x1e,0x2a,0xcf,0xcc,0x19,0xc3,0xe9,0x67,0x3d,0xd4,0x41,0x42,0xd9,0x8a,0xac,0xae,0x89,0x49,0x30,0xe2,0x0c,0xa0,0x67,0x43,0x9e,0x74,0x9a,0x79,},{0xe2,0x2d,0xdd,0x39,0x6f,0x95,0x5b,0xb9,0x0e,0x28,0x47,0x76,0xaa,0x76,0xe9,0x21,0xe5,0x06,0x99,0xd0,0xca,0x89,0x14,0xa9,0xb7,0xb8,0x41,0xeb,0x5f,0xf4,0x7d,0x6d,},{0x0c,0x17,0x3c,0x48,0x8a,0xd0,0x01,0xcb,0xb9,0xc4,0x3d,0x7b,0x30,0xa7,0xc0,0x71,0xa2,0xfd,0xb0,0x8c,0xf7,0xf3,0x7d,0xaf,0x71,0xd7,0xae,0x71,0x28,0xdc,0x0d,0x43,0xf0,0xf0,0x95,0xb2,0x92,0x9c,0x54,0xb7,0x73,0xed,0x4a,0x1f,0x0b,0xf0,0xdc,0x4f,0x36,0x4f,0x06,0x01,0xe8,0xd5,0xae,0x06,0x2f,0x5b,0x78,0xc0,0x5b,0xfb,0xc7,0x02,},"\x1c\x68\x15\x42\x3d\x1a\x2c\x5e\xbe\x88\x28\xd1\x64\x65\x27\xc1\x7b\x20\x06\xe5\x47\xf0\x16\xb5\x35\x0f\x01\x0d\x79\xb1\x3d\xf4\xfb\x8c\x6e\xd5\x7b\xa9\xc2\x6c\x3c\xb0\xe0\xa6\x41\x78\xb6\x50\xa3\xea\x54\x44\xa4\xfa\xd5\xb2\x0a\x3e\xb8\xca\xa7\x02\x63\x40\x11\xcf\x78\x92\xa0\x72\x7b\x6e\x81\x50\xb0\x77\x04\x29\xa3\x7a\x8a\x0b\xb3\xa7\xed\xb8\x91\xa7\xc9\x02\x40\xbc\x03\x60\xb1\x4e\x6d\xd7\x70\xa9\x90\xb3\x1b\x31\xf3\x3d\xdb\xf6\x53\x98\x8f\x82\x74\x2e\x5e\xec\x31\xb2\x73\x68\xeb\x0e\x4f\x1e\xcf\x4d\x67\x6f\x49\x21\x4a\x52\x0d\x1e\x5b\x2b\xbb\x59\xac\x2e\x13\x26\x7e\x07\xa0\xcb\xac\xbe\xd9\xf9\x4d\x74\x73\xed\x69\x78\x28\xb0\x92\x8f\xcc\x61\x6e\xe0\x2e\x51\xfc\xd8\xdb\x4d\x8f\x75\x33\xb7\xb1\x39\xa0\x5e\x06\xf9\xe0\xea\xe3\x29\x93\xe3\x02\x5a\xef\x05\x90\xb3\xfb\xb4\x29\x2a\x3a\xc4\x07\x65\xe8\x58\x4e\xad\x00\x26\x6a\xcd\xcb\xdd\xe1\x45\x7a\x03\xb7\xd5\x7b\xd5\xc9\xe6\x4f\xb0\x6b\x64\xa5\x0f\x35\xf0\xa1\xec\x34\xb6\xdd\xbd\xe7\x67\xb9\x6f\xfd"}, +{{0xa3,0x4d,0x52,0x56,0x31,0x59,0xe0,0x72,0x3e,0x9f,0x3f,0xd1,0x33,0xbd,0x96,0xe2,0x0a,0xda,0xe6,0x23,0xf8,0xc7,0x98,0x01,0x3b,0xc3,0x6b,0x44,0x14,0x89,0xbd,0xc2,},{0x1f,0xb6,0x58,0xe6,0x45,0xde,0x6d,0x3e,0xfd,0xb0,0x83,0xa7,0x3f,0xbd,0x59,0x2f,0xcd,0x4b,0x80,0x0e,0x03,0xc7,0xbd,0x68,0x1a,0xea,0xe6,0x57,0x6b,0xfb,0xbe,0x2f,},{0x5f,0xab,0x5a,0x71,0x40,0xd4,0x78,0x73,0x68,0x43,0x05,0xaa,0x63,0x53,0xd3,0x86,0x2f,0x5f,0xc1,0x3e,0x54,0xa4,0x0c,0x95,0x63,0xcc,0xea,0xc8,0xf7,0x40,0x08,0xc6,0xc4,0x45,0x63,0x1f,0xa8,0x64,0xe0,0xf1,0xc3,0x45,0xb5,0x95,0x4f,0x80,0x05,0x6a,0xeb,0xa2,0x56,0x62,0xb7,0x88,0x27,0xb5,0xe8,0xe3,0xa9,0x43,0x78,0x13,0x72,0x0f,},"\x1d\x21\x5f\x85\xc0\x89\xf3\x5f\x30\x7a\x74\x6c\x66\xc7\xc1\xe4\x1d\x6b\xa3\x77\x30\xd7\x59\xe6\xe5\x62\x2d\x6c\x6a\x19\x8e\x40\xf6\x3d\x37\x87\x3b\x71\x5d\xf7\x51\x8b\x3c\x6b\xb5\xe9\x5a\x46\x77\x26\xb9\x7c\x9a\x0f\x8f\x5d\xfc\xdb\xfd\x1e\x0d\xe3\x57\x66\x1d\xde\xab\x55\x50\x42\xb9\x45\xfd\x89\x9f\xad\x6d\x38\x2d\x79\x17\xda\x9e\x12\xdf\xbd\xa0\xd6\x99\x00\xb3\x97\x51\x65\xa7\x3d\x0a\xc9\xde\x01\xfd\x30\x48\xb8\xfe\x5f\x0b\x90\xbe\x67\xe0\x3d\xc2\x2f\x65\x3a\x0a\x13\xeb\x4b\x0b\x75\x3f\x3f\x3b\xbf\x78\x73\x69\xeb\xd8\xbf\x5e\x00\xeb\x78\xbf\x0b\x35\x15\xa9\x1e\x68\xb1\xd5\xfc\x69\x20\xbf\x4f\x42\x59\xf8\xa7\x30\xef\xc7\xf1\x01\x6d\x50\x1e\xf6\xfb\x7c\xb8\x36\x6f\xc8\xe7\x16\xcf\xa5\x0e\xa8\xb2\x03\xcc\xa1\xa3\x16\x70\x7e\x0b\x0f\xc5\x7e\xaf\xce\x82\xd6\x2f\x7f\xf3\xae\x04\xac\x8f\xd0\x41\xb5\x5b\x19\xa3\x52\xa6\x9e\x6d\x4b\x79\xd0\xe6\x50\x17\x51\x68\xe3\x4f\xa3\x35\x8e\xac\x81\x6c\xec\xf2\xc8\xdd\x1b\xf2\xa5\x89\x11\x3e\x91\xbb\x81\x8f\x91\xf8"}, +{{0x58,0xdf,0xe7,0x68,0xbf,0x52,0x11,0x84,0x94,0xb2,0x99,0x75,0x15,0x4c,0xf4,0x52,0xbd,0x97,0x46,0xdc,0x7d,0xe1,0xd6,0xbc,0xd1,0x8e,0xe6,0xa0,0x5a,0xcf,0xd8,0x58,},{0x0f,0x14,0x76,0xc6,0xcc,0x2a,0x1b,0x47,0x64,0xaf,0x75,0x80,0x5e,0x77,0x34,0x1f,0x14,0xa0,0xd8,0xb0,0x9c,0x6a,0x5b,0x2e,0xa2,0x87,0xfd,0x51,0x7c,0x3f,0xa6,0xb9,},{0x97,0x71,0x37,0xa3,0x8a,0xf4,0x4f,0x4b,0x26,0x2a,0xbf,0xf7,0xe0,0x72,0x82,0x43,0x3c,0x58,0x92,0x6d,0x56,0x2f,0xbc,0x61,0x80,0xbd,0xe6,0xcd,0x94,0x97,0x86,0x1f,0xb6,0xd9,0x55,0xcf,0x38,0x3d,0x99,0x9f,0xa1,0x03,0x7b,0x8b,0x17,0x54,0xce,0x88,0x8c,0x9f,0xfc,0x15,0x60,0xa4,0x51,0xd0,0xe9,0xdb,0x8d,0x74,0xd2,0x94,0x06,0x04,},"\x60\x97\x94\x20\x1c\x4f\x6f\xaf\x48\x87\x90\xd6\x1d\xbf\xf3\xf4\x1b\x32\x8c\x5b\x06\x95\xcb\xe9\xaa\x8a\x13\x6d\x72\xb4\x97\x7b\x21\xb5\x00\xf2\x16\xe9\xf3\x21\x68\xad\xa8\xc1\x3b\xff\x25\x32\x76\x47\xe3\x0d\x8a\x24\x4d\x74\xd8\x83\x03\xab\xc9\x0b\x7f\x71\xaa\x07\xca\x04\xd1\x7b\xc8\xa0\x16\x7d\x6e\x63\xfb\x88\xba\xa1\xda\xb8\x1d\x50\xf1\xe9\x1f\x46\xf5\xaf\x77\xf2\xe8\x40\x8b\x82\x63\x36\xa3\x50\x52\xef\xff\xdf\x4a\xf7\x95\x96\xaf\x1b\xb2\x25\x9f\x83\xc1\xbc\x10\x9c\xfd\xc3\xdd\x50\xfd\x96\xd3\x10\xf2\x7e\xa4\xc6\xc7\x69\x0f\x21\x81\x5e\xa9\x2b\xd7\x93\x89\x68\x0c\xfe\x3e\xd4\x0c\x80\x18\x11\x90\x68\x8d\x24\x22\x2d\x9a\x1e\xd5\x2c\xe6\xa1\x6b\x41\xdb\xd9\x10\x7e\xb6\xd2\xe3\x59\x4e\x44\x94\xd7\x5d\xd7\xc0\x89\xe3\xb2\x6f\xfd\x00\xd1\x00\x3c\x92\xc4\xc3\x9a\xe5\x38\x2e\xf9\x29\x14\x91\xa8\x80\xca\x4e\xc3\xac\x2b\x86\xe6\x67\x19\xb9\x2b\x6f\x7c\xea\x2c\xb0\xbb\xb1\xcf\x62\x4d\x0d\x1a\xbe\xae\x55\x6e\x5f\x73\x90\x9d\xd5\x46\x27\x70\x37\xec\x97\x2f\xd4"}, +{{0x5a,0x63,0xef,0x9b,0xd7,0xdb,0xf0,0xe8,0x9f,0xef,0x15,0x59,0x83,0x65,0x9e,0x8a,0x0a,0x6c,0xa0,0x02,0xbc,0x42,0xfa,0xd5,0xa4,0x5a,0xf8,0xe0,0x28,0x19,0x23,0xf4,},{0xe6,0x32,0xf4,0xdc,0x99,0x42,0x31,0xcc,0x17,0x90,0xc2,0x1a,0xfa,0xda,0xa9,0x77,0xa5,0x89,0xb0,0xeb,0x0d,0xa1,0x9f,0xcb,0x27,0x92,0x91,0x1b,0x15,0xec,0xf8,0xaf,},{0x75,0x46,0x1f,0x99,0x65,0x0c,0x03,0x68,0x05,0x81,0x13,0xa1,0x5b,0xa1,0x6b,0xd2,0x33,0x7b,0x2e,0x63,0x3d,0xa3,0x81,0x12,0x87,0x8c,0x48,0x34,0xfa,0xc9,0xba,0x2e,0x30,0x7c,0x86,0x6c,0x02,0xaf,0x79,0xbe,0xa3,0x36,0x59,0x61,0x4c,0xbb,0x44,0x65,0xc5,0x7e,0xc3,0xef,0xfd,0x4c,0x47,0x8a,0xe3,0x8a,0x34,0xa0,0x5c,0xf1,0xed,0x07,},"\x79\x6b\xc8\x36\x1c\x6e\x8e\xec\x39\x83\x8b\x24\xf5\x39\x71\xe8\x20\xf8\x23\x61\xe0\x51\x0e\xb4\xde\xf1\xdb\x25\x12\x38\x7d\x6b\xf3\x5b\xbd\xfa\x31\x88\x79\x20\x94\x35\xd6\x88\x7b\x14\x10\xb3\xeb\xc1\x45\x5f\x91\xf9\x85\xe0\xfa\xb1\xce\x1c\x50\x5c\x45\x55\x76\xbc\xa0\x35\x39\xd0\x48\xad\x3a\x0e\xd1\xf1\x1c\x73\xba\xc6\x80\x9e\x2e\xa1\x47\x97\x5b\xee\x27\xc6\x52\x61\xac\xa1\x17\xdf\x0f\xae\x70\x08\xe2\xc3\xc1\x30\xbe\xc5\x53\x3a\xb8\x93\x51\xc2\x14\x0c\x9d\x1a\x62\xbd\xf6\x88\x62\x97\x87\xf9\x54\xe1\xc6\x10\xcb\xb7\x5e\xdb\x86\x20\x9d\x7c\x35\x7c\xd0\x6e\xf4\x19\x31\xdd\x5d\xfd\x1c\x7d\x40\x7f\xa4\xee\x1e\xf2\x93\x93\xbe\xab\x57\x13\x17\x38\x02\xcc\xe2\xd5\x62\x29\xcf\xa7\x6b\x60\x16\x62\xc4\xd9\xa8\x4a\x49\x36\xc5\x2a\xbb\x19\x81\x37\x8b\x71\x7e\xb5\x5c\xb6\x04\xa6\x8d\x34\xf0\x3b\x21\x9f\x32\x22\x6c\xa0\xe6\x69\x34\x8a\x2d\x8d\x24\x53\x93\x0e\xb6\xe9\xc2\xbf\x66\xfa\x4e\x92\xc7\x51\x36\xe1\x48\xcd\xb0\x34\x13\x0d\x3f\x64\x63\x82\xe1\xc7\x15\x79\xac\x70"}, +{{0x8b,0x2f,0x06,0x14,0x1e,0x40,0x11,0x63,0xf9,0x0f,0x67,0x4b,0x04,0xdc,0x90,0xdc,0xb6,0xdd,0x33,0x86,0x41,0x93,0x39,0x66,0x2e,0xcb,0x0d,0xff,0xad,0xf2,0x50,0x0b,},{0x54,0xda,0x93,0x4a,0x65,0x91,0x19,0x19,0x85,0x53,0xfd,0x45,0x66,0xb6,0x60,0xd8,0xd6,0x10,0xad,0xc3,0x29,0x0c,0xb8,0x48,0x29,0xc8,0x94,0x14,0x8c,0xf3,0xf6,0x7e,},{0xd6,0x8e,0x37,0x50,0xdc,0x56,0x43,0x23,0x97,0x40,0x1c,0x98,0xff,0x15,0x29,0xdb,0x9e,0xd4,0x8f,0xea,0x24,0x6d,0xd4,0xed,0x38,0x3e,0xc7,0x4c,0x1a,0x46,0x3a,0xeb,0x78,0x4c,0x87,0xb1,0xfd,0xa8,0xbb,0xce,0x97,0x0f,0xc9,0x7a,0xa9,0x80,0x7d,0xdb,0xe9,0x5d,0x41,0xfb,0x02,0x2e,0xa6,0x8c,0x1e,0x31,0x16,0x54,0xfa,0x1d,0xa2,0x07,},"\x1d\xeb\x25\xd4\x34\x58\x69\x03\x23\xa7\xd2\x6a\x26\x69\x50\x90\x99\x34\x74\xf4\x67\xc6\xfd\xe5\xdd\xb3\x4d\xa9\x45\xbe\x3c\xea\x2f\x6b\x75\x65\x2a\xe2\x1c\xbc\x4f\xd2\x27\x63\xa1\xb4\x55\x83\xe1\xc3\xe8\x8b\xbb\x5f\xea\x20\x49\xb7\x33\x6c\x91\x15\x99\x88\xc0\x15\x26\x82\x4c\xa3\xbe\xf1\x6b\x36\x2b\x92\x02\xb8\xb9\x75\x41\x85\xbd\x61\xbe\xa8\xf5\x39\xaa\xdf\x4a\x1a\xb1\x35\xfb\xc3\x1d\x2a\x8e\x33\x17\x80\x73\x10\x6c\xbb\xc0\x2d\x4c\xd0\xd3\xc8\xfe\xaa\x8e\xb7\x33\x08\x43\x56\x25\x17\x95\xaf\xbd\x78\xac\x3c\x4f\x8a\x3b\xa1\x9a\xed\x75\x5c\x64\x6f\x35\x56\x9c\x7a\x6c\x67\x5b\x6d\x69\x18\xe8\x34\x96\x9a\xca\x03\xf7\x1a\x2e\x72\xcc\xb1\x70\x03\xbb\x75\xb6\x2e\x85\x2a\xaf\x58\xb3\xba\xea\x89\xbc\xd6\x4a\x32\xeb\x14\xa6\xb9\xe1\x0d\xe4\x89\x71\xe5\x3d\x0e\x9a\xc9\x9a\x78\xf4\x2d\xe0\x38\x2e\xf0\xe8\x0e\xd3\xcf\xa3\x43\xf3\x5e\x4a\x99\x83\xb9\xae\xed\x98\x6d\x3a\x57\xf4\x7e\x5e\x46\xd4\x0e\x9d\x67\x73\x02\x80\x9a\x2d\x37\xe4\xec\x01\x1f\x05\x1b\x4d\x03\x1e\xd6\x00"}, +{{0xdc,0x64,0x9f,0xbb,0x1b,0xee,0x0a,0x44,0x81,0x4d,0x6d,0x9e,0x90,0x80,0xd5,0xd9,0x0c,0x1f,0xc1,0x73,0xab,0x5f,0xef,0xed,0x82,0x6a,0x74,0x72,0x3a,0x77,0x4e,0x0a,},{0x02,0x14,0xc8,0x9f,0x38,0x67,0xad,0x2e,0x88,0x70,0xe5,0x0f,0x8c,0x2a,0x62,0x54,0x98,0x6d,0x9c,0x22,0x0e,0x33,0x38,0x41,0x13,0x00,0xcd,0x9c,0x64,0x04,0xd4,0xb1,},{0x0e,0x0c,0x5e,0x4e,0x18,0x43,0x75,0xda,0x4e,0xf7,0xe2,0xa2,0xe4,0x88,0x80,0x50,0xcd,0x84,0xe2,0xfe,0x21,0xd0,0x8e,0x84,0xa8,0x52,0xdb,0x2b,0xe3,0xfb,0xc3,0x72,0xc4,0x72,0xde,0x09,0x54,0xdc,0xd1,0xdc,0x11,0xae,0xc4,0x93,0xc5,0x69,0xf4,0x0f,0xc6,0xf7,0x7f,0x03,0xee,0x52,0x4f,0xb0,0x6e,0xc4,0x0f,0xaa,0x1d,0x6c,0xc1,0x0f,},"\x32\x87\x00\xa8\xae\x58\x1c\x1e\xdc\x4e\x2c\x00\xc7\x8b\xf4\x60\x60\x97\xf9\xbd\x75\xaa\xde\x20\x5a\x24\x3c\x5f\xd7\x43\x4d\x62\x22\xda\x93\x7e\x28\x81\xa2\xe3\xc5\x74\x35\x6d\x4d\x56\x79\x30\x1d\xa9\x9e\x11\xcf\x74\x9c\x27\x92\x1c\x8c\xaa\x2a\xb2\xa5\x64\xd8\x7c\x5d\xf8\xec\xf1\xa7\x2b\x68\x01\x84\x82\x4f\x69\x86\x02\x2e\x3f\xc9\x8b\xd2\xa2\x1c\x34\x55\xab\xf1\x15\x49\x54\xfb\x30\xc8\x98\x82\x94\x7b\x02\xf3\x5a\xf7\xb1\xbf\xad\x05\x23\x7d\x24\x2e\x2b\x74\x83\x2f\xc5\x36\x19\x6f\x2e\x59\xd1\xac\xd0\xc1\xdb\x6f\x19\x43\xd0\xf6\x04\x3b\xbd\x6a\x76\x90\x83\xed\x66\xba\x0e\x05\xa5\x0f\xeb\x0a\xcf\x72\xb6\xc1\x6b\xa9\xaf\x03\x9a\xfb\x7f\xe2\xa4\xaa\xeb\x4d\x06\x18\x1c\x5a\x18\x78\x68\x9e\x67\xa3\xf5\xd0\xad\x39\xe7\x94\xd6\x23\x9a\x7e\x0a\x12\xce\x82\x0c\x5b\xe6\x0f\xd5\xf1\xdd\x79\x70\x2f\x49\xd0\x2b\x79\x75\x5f\xe8\x73\xf5\x78\x5c\x72\xf7\x46\x25\xcd\x7e\x24\x28\x26\x25\x97\xd3\x14\x82\xc2\xc0\x50\x88\x01\xfd\x96\x31\x9d\x61\xb9\x1b\xa2\x53\xa5\xe7\x22\xf4\x14\xcf"}, +{{0x39,0xb8,0x06,0x2d,0xa4,0x3e,0x64,0xe1,0x67,0x67,0x65,0xd6,0x2c,0x7f,0xb8,0xe0,0xa9,0x9c,0x4f,0xd4,0x17,0xd6,0xf7,0xe3,0x31,0x9b,0xb1,0x30,0x44,0x20,0x5f,0x3b,},{0x62,0x27,0xce,0xfe,0x88,0xea,0x4f,0xb2,0x7b,0x37,0xb5,0xf7,0x97,0x77,0x8b,0xd7,0x2f,0xda,0xfe,0xad,0xcc,0xd9,0xae,0xb6,0x7a,0xd4,0x37,0xce,0x08,0xfb,0xa6,0xa8,},{0xc5,0xf6,0x26,0x49,0x0c,0x0e,0xf4,0xe1,0xef,0xc3,0xed,0xeb,0x0c,0xbc,0x3f,0x7d,0xe2,0x67,0x05,0x7f,0xb7,0xb6,0xeb,0x8f,0x0c,0x81,0x35,0x84,0x96,0x5b,0xc5,0xc4,0x21,0xfe,0xed,0xf5,0x42,0x41,0xca,0xe0,0x01,0xec,0x6d,0x5e,0x25,0xc9,0xb1,0xfb,0xa0,0x38,0x5e,0x5d,0xbd,0x95,0xa0,0x6e,0xc1,0xd8,0xae,0x51,0x91,0x44,0x96,0x0d,},"\x74\x0a\xf6\x79\xe3\x06\x9f\xad\x05\x9f\xa4\x82\x5f\xa4\x1c\x59\xfb\xd4\x84\xaa\x64\x93\x03\xc2\x7c\x4f\x7a\x94\x71\x1c\x5b\x71\x3b\x2a\x6b\x89\x87\x85\x9e\x22\x71\xa6\xa7\x1e\xb0\xb4\xa1\x5a\xbd\xe4\xf5\x16\x8f\x6c\xb9\xdb\xdc\x6a\x27\xa2\xa1\x3d\x52\xc9\x72\x08\x96\xa1\xf4\xce\x3a\x53\x45\xee\x79\x3b\x6c\xc3\xad\x80\xd7\xd5\x81\x63\xd5\x45\x5b\x9c\xbd\x07\x3e\x2b\x7a\xdb\xff\x95\x59\x0c\x71\x72\x27\x1b\xd9\x1f\xef\xdb\xd0\x16\x57\xee\x17\x50\x65\x10\x36\xcd\xc3\x56\x0b\x44\x4c\xa2\x18\x4b\xf4\xf3\xea\x89\xfc\x97\x3a\xab\x6f\xb4\xa8\xee\x57\x04\xbb\xe5\xa7\x1c\x99\xfa\x3b\x5e\xf0\xd0\x39\x62\x49\x75\x82\x97\x69\x9a\xe2\x02\xb8\x19\x69\x0d\xc7\xac\x46\x92\x77\x03\x46\x90\x78\x45\xe2\x21\x0d\x53\x63\xad\xee\xc0\x3f\x0f\xc7\x76\x1b\x7e\x0e\xc0\xfe\xa1\xbc\xf6\xb0\x4f\xc5\x4b\x3e\x4c\x40\xd1\x9b\x8f\xa6\x49\xac\x84\x79\xe8\xf8\x07\x30\xc0\xc9\x4e\x9f\x4a\x1a\xd5\x06\xf2\xbc\xab\x0c\x49\x54\x0f\x6d\xec\xaa\x77\xb3\xd6\x57\xdc\x38\xa0\x2b\x28\xa9\x77\xec\xe4\x82\x54\x5a"}, +{{0x52,0xf4,0x67,0x5d,0x8c,0xcd,0x0e,0xb9,0x09,0xdf,0x0a,0x51,0x66,0x48,0xdb,0x26,0xfa,0x03,0x3b,0xa4,0x1d,0x43,0xfc,0x38,0x45,0x89,0x6d,0x45,0x6e,0x14,0x26,0x5f,},{0xf3,0x9e,0x7d,0xaf,0xc9,0x7b,0x0a,0x84,0xdc,0xbf,0x7f,0xa1,0x4a,0x94,0x03,0xee,0x1f,0xa9,0x2b,0x85,0xe5,0xa7,0xe5,0xd0,0x5f,0x03,0x1b,0x44,0xdd,0xf1,0xf7,0x94,},{0x4b,0xf6,0x68,0x82,0x7a,0x72,0x0a,0xf6,0x88,0x98,0xa0,0x6e,0xa7,0xb4,0x45,0x45,0xa3,0x4c,0xa8,0x96,0xec,0xf3,0x11,0xfe,0xea,0x47,0xe0,0x68,0x6d,0x91,0x1f,0xad,0xaa,0x03,0x11,0x89,0x97,0x15,0x3c,0x65,0x36,0x1f,0xea,0x15,0xde,0x9b,0xb8,0x91,0xb8,0x90,0x98,0x72,0x04,0x55,0x08,0xff,0xad,0x0c,0xd9,0xea,0xb2,0x1a,0x97,0x02,},"\x74\x42\x71\x10\x85\x7c\xb4\xaf\x0a\x33\x42\xc2\xb5\x29\x97\xbc\xe1\xa0\xdb\x64\x05\xc7\x4e\x96\x51\xc5\xb8\x59\x79\xac\xb0\x71\xe5\x67\xfe\x70\x41\x2c\x4e\x0d\x8c\x9f\xa4\x21\x91\x4f\x6a\x62\xf2\xae\x42\x0b\x7b\x2f\x4c\xf8\x0c\x90\x57\x42\x21\x22\x22\x88\xb6\x58\x67\xea\xa6\x6e\x7e\x0a\x05\x57\xa2\x6c\x54\x9f\x9a\x7a\x4e\x70\x83\x8b\xa4\x07\x4b\x4c\xd7\xa9\xd7\x58\xb3\x78\xb8\x8d\xd4\x94\x41\xdf\x80\x2a\x44\x4d\xcb\xc3\x06\x24\x93\x3b\x59\x92\x2f\x33\xc2\x0f\x01\x9f\xe7\x8e\xe2\x4b\x8f\xba\x79\xa6\x82\xf3\x88\x50\x5a\xc9\xc9\x7f\x4e\xb8\x7c\x61\x18\x80\x02\x6b\x4c\x23\x30\x6b\x86\x51\x73\xf5\xd7\x16\xab\xc6\xcd\x9a\x99\x06\xdb\x34\x30\x13\x6f\x75\x41\x29\xc4\x43\xb2\x0c\x42\xbe\x2f\xbc\xbc\xd4\x40\x34\xd7\x14\xf5\x8a\x4b\xa8\xe7\x56\x60\x7a\x02\xb6\x08\xef\x49\x64\x8f\x2a\xd0\xce\xa9\x9e\x7a\xb3\x0a\x8d\xd7\x81\x40\x04\xf7\x25\xf4\x93\x01\xd7\xb3\x04\xdc\xda\x62\x5c\x29\x6d\x92\x8c\xb5\x81\x73\x6a\xb7\x39\xc8\x6b\x46\x92\x41\xa8\x25\x93\x51\xfd\x37\xb4\x78\x0a\x99\x93"}, +{{0xba,0xd7,0x3c,0x9f,0xda,0x4c,0xeb,0x9d,0xa6,0xc7,0x01,0xc2,0xa6,0xe2,0xef,0xc0,0x46,0x7a,0xfa,0x0a,0x74,0xf8,0x75,0x0c,0x52,0xcf,0x1f,0xd4,0xc8,0xe7,0x48,0x9a,},{0xbb,0x0f,0x02,0x7a,0x90,0x35,0x37,0x6e,0x1a,0xa3,0x20,0x6c,0x3d,0x77,0x44,0x75,0xe3,0x51,0xf5,0x76,0x7e,0xf8,0x6e,0xf4,0x8a,0x72,0xc0,0x37,0xc2,0x4c,0xce,0x62,},{0x19,0x7d,0x6b,0x6c,0xc8,0x8a,0x98,0xc0,0x6d,0xfc,0xa0,0xc0,0x12,0x25,0xed,0xfe,0x38,0xa0,0xb2,0x28,0x9f,0x29,0xf8,0xa4,0x4e,0xc0,0x81,0x6a,0x95,0x2d,0x58,0x5e,0x2d,0x59,0xb5,0xb0,0x8d,0xe1,0x00,0xc0,0x60,0x62,0x96,0xcc,0xf5,0xe9,0x2a,0x99,0xe0,0x93,0x62,0x31,0x44,0xb8,0xb2,0x2d,0xb8,0x7d,0x92,0x92,0x25,0x54,0x60,0x05,},"\x74\xb9\x66\xcb\x78\x07\x71\xae\xe6\x3d\x73\x4d\xf3\x75\x67\x02\xd1\xd5\xfd\xed\xdf\x32\x13\x6c\x63\x58\xb8\x36\x31\x8a\x4f\x98\x4f\xe7\x1e\x77\x16\xad\xdd\xbd\x64\x9e\xba\x44\xcd\x42\x82\xe0\x05\x5d\x8c\x1e\xd2\xd3\x51\x23\xd6\x6e\x5a\x98\xf1\xc0\x83\x8d\xed\x56\x3b\x9a\x20\xeb\x80\x07\x53\x8f\xc7\xb0\x71\x3e\x7e\x48\x5e\x3c\x28\xf6\xeb\xc4\x21\xa2\x9d\xce\x25\x24\xdb\x7f\x29\x20\x57\x61\x03\x6a\xda\x62\xe5\xb0\xb7\xd5\xb7\xf2\x94\xff\x17\xf3\x38\x23\x2f\xa5\xfd\x42\xb6\xf7\x25\x33\x04\x09\x2d\x84\x8f\x50\x73\x52\x48\x59\x5d\xa0\xf7\xef\x28\xe5\x68\xe9\x91\x6b\xfc\x56\xd7\xed\x0d\x81\x1b\x59\xd5\xd8\x91\xae\x43\xe1\xb1\x98\x07\x13\x06\xbf\x52\x5c\x67\x8c\x63\x43\x99\x80\x05\xfb\xb7\x86\x9d\x1c\x40\xf8\xca\xc8\x07\xfe\x2e\xf0\x3f\x3d\x5b\x93\x3f\x58\x97\x8e\xf2\x90\x6f\xcc\xf7\x44\x4a\x29\x36\xe6\x3d\x92\x8c\x69\x09\x26\xc9\xc9\x94\xed\x3d\x66\x62\x63\xe9\x56\xfd\xfe\xa2\x77\x64\xbc\x5f\x74\x12\x5b\xc4\x6b\xc1\x02\xdd\x3e\x5f\xf9\x3b\x5e\x12\x3e\x4b\x38\xbd\xef\x69\x7e\x15"}, +{{0x70,0x73,0x27,0xa4,0x31,0xdb,0xa7,0x76,0x39,0xb3,0x96,0x6b,0x2b,0xc0,0x95,0xf8,0xee,0xdf,0x57,0xf7,0xa2,0x00,0xe3,0xb0,0x07,0x7c,0xe4,0x20,0x38,0x9c,0x92,0xfe,},{0xee,0x24,0x96,0x91,0x08,0x64,0x18,0x9f,0xda,0xa3,0xc7,0x75,0x7e,0xb3,0xcd,0xa9,0xab,0x1e,0x70,0xfc,0x9e,0x7f,0x71,0xa3,0x8a,0x0b,0xfc,0x84,0x59,0x31,0xc9,0x5a,},{0xfb,0x99,0x02,0x9f,0xec,0xa3,0x87,0xa5,0xd7,0x65,0x96,0x1e,0x36,0x1d,0x71,0x72,0xb9,0x8b,0x7e,0x0f,0x11,0x29,0x0b,0xb1,0xe5,0xb5,0x7b,0x51,0xbc,0x21,0x23,0xd0,0xbc,0xe2,0x90,0x20,0x39,0x2a,0x4f,0xec,0x9a,0xe6,0xa7,0x2c,0x4c,0x38,0x6c,0xea,0x18,0x57,0xcb,0x8f,0x9c,0x50,0xaa,0x9a,0x76,0xd7,0xf1,0x68,0x7f,0xcf,0x29,0x00,},"\x32\xef\x31\xb6\x4e\xee\x70\x0f\xca\x2a\xb2\x1a\x26\x7f\x8d\x9d\x3b\xdc\x68\x9c\x75\x38\xfe\x95\x9b\xf7\x13\xfa\x99\x5d\xb2\xc0\xad\x36\xdd\xe4\x30\xa8\x41\x7d\x43\x7b\x72\xc7\x4e\x26\xdb\xe3\x1d\x93\x70\x1d\x46\x17\xfe\x51\x82\x5c\xff\x7a\x54\x4f\xc9\xf4\x4e\x43\x45\xe1\x4b\x4b\x11\xe1\x5f\x26\xff\xc2\xaf\x80\x35\xf3\xf9\x70\xe4\xdd\xa4\x4c\x0e\xbc\x03\x63\xc2\xb5\x6f\xde\x21\x86\x63\xbf\x78\x83\x90\x92\x53\x8f\xc2\xf3\x91\x53\xd4\xeb\x29\xda\x0c\x1a\x08\xaa\x96\x66\x01\xcc\x68\xca\x96\xe9\x93\xb0\x1b\x17\x3a\x26\x1b\x2e\xf3\x27\x65\x03\x82\xf5\x68\xfe\x94\x48\x55\xb0\xf4\xfd\x9d\x15\xe7\x52\xac\x74\xdc\xfd\x37\xb3\x78\x6f\xff\xce\xf2\x33\x39\xc2\x1e\x92\x70\xdc\xe8\x89\x1d\xd5\xee\xeb\xa9\x60\x8f\xdc\x7b\x6f\xbc\xc9\x9f\xa1\xb5\x90\x3d\xaa\x09\x68\xe1\xb6\x91\xd1\x9d\x06\xf2\x15\xde\xd0\x47\xef\x9d\x76\x61\x0f\x5d\xe2\x20\xf5\x04\x1b\x31\x3f\xaf\x9e\x96\xc9\xfd\x7d\xb5\x4b\x52\x25\x72\x6a\xf4\x35\xf9\xcb\xd9\xfd\x87\xab\x40\xce\x8f\x2c\x69\x40\xb5\x5f\x0f\xaa\xe8\x78\x50\xca"}, +{{0x6a,0xa5,0xc9,0xf0,0x08,0xf9,0x90,0x47,0x3b,0xa4,0xa6,0x28,0x6a,0x41,0x66,0x14,0x02,0x66,0x61,0xf1,0x1e,0x1a,0x24,0xef,0xa8,0x1a,0xc3,0x58,0x52,0xd1,0xd0,0x70,},{0x60,0x5a,0xc9,0xb4,0xdb,0xdd,0x50,0x33,0xd6,0xc8,0x28,0xbf,0xaf,0xa9,0x3c,0x00,0x39,0x44,0x0a,0xa1,0x1c,0xa7,0x24,0xae,0x83,0x40,0x43,0xe0,0x7b,0xd0,0x32,0xd5,},{0x97,0x56,0x30,0x3b,0x90,0x65,0x5e,0x93,0x52,0x51,0x03,0x2a,0xb1,0x9c,0xfc,0x95,0xca,0x1c,0x2a,0x2c,0x3e,0xa2,0x8b,0x03,0x3b,0xd4,0x70,0x66,0xcb,0xd4,0xc7,0xd8,0x98,0x2a,0x8b,0x98,0x86,0xf1,0xb9,0xcd,0x02,0xe8,0x8a,0x65,0x56,0x4d,0xa8,0xdc,0xc3,0x4f,0x30,0x8b,0xa9,0xf1,0x01,0x44,0xba,0x46,0x9c,0x2e,0xfa,0x49,0xe0,0x04,},"\xb5\x16\x5d\x39\x63\xf6\xe6\xf9\xea\x56\x57\xe9\xf0\x7f\xf3\xa3\x21\xeb\x33\x8f\x9a\x8c\x3d\x3c\x42\x30\x6b\x2b\x27\x89\x78\xb3\x1c\x62\x3a\x63\x1b\xe3\xb0\x4c\x41\xed\xfd\xed\xdf\x53\x8e\x1b\x76\x5b\xc8\x78\x54\x01\xc1\xaf\x29\xd0\x46\x7a\x64\x41\x1c\x49\x73\x95\xd7\x55\xdc\xa0\x3a\xe3\x27\x2f\x4b\xc1\xfb\x19\x18\xdc\xc1\xed\x6f\x04\xd6\x49\x84\x04\xa8\xce\x14\x09\xd4\x47\xf5\x70\xa4\x35\x95\x22\xcc\x54\x62\x92\x02\xeb\xe5\x07\xab\x69\x38\x43\x14\x1b\xd5\xea\x05\x73\xb2\x0f\x32\x1a\x48\x3f\xf3\x83\xa4\x68\x97\xf5\x92\x6f\xe0\xb8\xaf\xc2\x55\x72\x70\x7b\x63\xee\xed\x28\x35\x32\x92\x8a\x41\x44\x19\x64\x97\x94\x2c\x57\x2a\xc5\x47\x60\x51\x39\x25\x6b\x0a\xa0\xea\xf0\x4d\xb1\xa2\x56\x01\x2e\xd4\x53\xb1\x73\xee\x19\xad\x6e\x9b\x1a\xf3\xf4\x5f\xf3\x04\x4a\x64\x1f\x8c\x8e\xb0\xac\x7b\xb4\x5a\xbb\xde\xd4\x72\x86\xb2\xa0\x69\xd3\x90\x86\x94\xee\x06\xf2\xfb\xd0\xef\x60\x5a\x79\x11\x02\x6e\xa9\xea\x3c\x49\x13\xf3\x8c\x04\xd8\xb6\x95\x65\xa7\x02\x78\x67\xab\x30\x92\xd0\x5f\x4c\xfb\x18\xfc\x7c"}, +{{0x8e,0xfb,0x8b,0x79,0x74,0x2b,0xe2,0x1e,0x6d,0x31,0xde,0x67,0x8b,0xc8,0x14,0x50,0xba,0x86,0x21,0x08,0x2c,0xd6,0xf0,0x00,0x3e,0x22,0x86,0x1e,0x22,0x91,0xc4,0x81,},{0x33,0x38,0x1e,0x35,0x6c,0x4f,0xd3,0x86,0xa3,0xf7,0xb9,0x69,0xaf,0xd9,0xf5,0xc0,0x0d,0x20,0x67,0xb6,0x98,0xb3,0xf1,0xf0,0x0f,0x37,0x84,0x20,0x2d,0x30,0x84,0xcf,},{0x92,0x30,0x05,0xcb,0x48,0x48,0x40,0x2a,0xa8,0xf9,0xd5,0xda,0x74,0x03,0x0b,0x00,0x94,0x44,0x92,0x4c,0x21,0x4a,0xd6,0x00,0xdd,0xba,0xb4,0xc1,0x53,0xa6,0xff,0x02,0x2b,0x53,0xcf,0x63,0x64,0xcd,0x7e,0xe9,0x9b,0xef,0x34,0xfe,0x14,0x4d,0xa9,0x64,0xed,0xfc,0x38,0xa0,0xba,0x63,0x33,0x12,0x65,0x0e,0xbf,0x0e,0x55,0xa0,0x60,0x09,},"\x6b\x75\x03\x25\xd3\xa0\xf0\x8a\x14\x77\x00\xb5\x1a\x9b\x37\x25\x57\x10\x94\x81\x8e\xd6\x9d\x1f\x76\x10\x13\xeb\x86\xf3\x23\xf7\x3c\x49\xf5\xe4\x39\x87\x7c\x27\x83\xb3\x36\xd1\xf1\xa6\x74\xef\x3e\x43\x1f\xc1\xae\x01\x80\x08\x2d\xf5\xfc\xa6\x9f\x84\x81\x39\xfe\x6a\xb6\x73\x9a\x05\x92\xeb\xd6\xd4\x70\x5c\x7f\x01\x36\xb2\x21\x89\xa1\x1d\x60\xd4\xd3\xc9\xbc\x80\xfe\x7d\x7c\x00\x95\x2d\x57\x42\xf9\xc0\xc2\x12\x1f\xe7\x92\xdf\x13\x3f\x22\x1d\xb9\x91\xfc\x96\x0e\xe6\x4b\x9d\x32\xe0\x17\x8e\x54\x2b\xce\x8e\xfa\x8d\x03\xac\x80\x26\xcd\x77\xba\x8b\xf0\xb2\x42\x15\xb9\xfa\xed\x2e\xae\xc9\x20\xe9\x25\xd5\xec\x46\xff\xf6\xbd\xe7\x25\xe9\x1c\x82\x80\xe4\xad\xa2\x32\xa5\x43\x3a\xe9\x68\x0e\xbb\x53\xeb\x55\x55\x31\x47\xc9\x33\x70\x57\x48\x54\x89\x61\x54\x51\x42\x99\xc0\x93\x21\x9a\x11\x1d\xca\x4e\x63\x7a\xd5\x00\x13\x38\xc6\xd4\xd5\xee\x90\x98\xc6\x58\x32\xf7\xaf\x83\x5b\xcb\x62\x21\x28\x42\x30\x36\xc7\x9a\x57\x37\x73\x8a\x75\x39\xf8\xd4\xa6\xb8\xb2\x21\xb5\x6d\x14\x01\xae\xb7\x4d\x45\x71\xbc\x00\x9d"}, +{{0xed,0x04,0x6d,0x68,0x8b,0x2b,0x0a,0x1b,0xc3,0xda,0xf2,0x11,0x9d,0xd3,0x21,0xa6,0x07,0xb1,0x6d,0x2a,0x2d,0x1d,0x96,0x3a,0xdd,0x12,0x09,0xc6,0x65,0xb5,0xcc,0xba,},{0x87,0x34,0xf1,0xff,0xcb,0xd7,0x1c,0xfd,0xe2,0x90,0x01,0x7e,0xa6,0x25,0x3e,0x58,0x0d,0x59,0xe6,0x5b,0x54,0x1b,0x46,0x52,0x1f,0x5e,0x5e,0xc1,0x45,0x1e,0xae,0xc6,},{0x72,0x1b,0xfd,0x47,0x76,0xcf,0xba,0x13,0x33,0x0f,0xd3,0x72,0x69,0xe9,0x79,0xc1,0xd7,0xb6,0xce,0x54,0xa5,0x1b,0x82,0xf4,0x56,0xe1,0x37,0x37,0x8e,0x58,0x2f,0x19,0x2a,0x12,0x08,0x9d,0xa5,0xab,0xa7,0x6a,0x7b,0x16,0x18,0x13,0xdc,0xe5,0x6b,0x72,0x89,0x2a,0x35,0x33,0x0c,0x94,0xf7,0xff,0x21,0xd0,0x9c,0xf0,0x9e,0x55,0x35,0x04,},"\xb9\xcc\x90\xfd\x8d\xe2\xa1\x41\xf9\x51\x16\xdb\x3b\x04\xbe\x83\xe9\x85\x22\x59\x7e\xc2\x17\x49\x64\x24\x51\x80\xb9\xa4\x73\x76\x7d\x6d\x47\x0a\x21\x7d\xb5\xff\x5a\x1a\xb7\x77\xe1\xe2\x8a\x0b\x16\x97\x5e\x2b\xac\xb8\x73\x02\x04\x44\xb4\x7e\xd8\x32\x64\x21\xb9\x0e\xbb\x50\x36\x88\xf0\x90\xc1\x1b\x3b\x13\x61\x7c\x5c\x50\x52\xc2\x97\xa4\x1e\x28\x93\x77\x5e\x34\xd5\x9a\xda\x49\xd9\x94\xc0\xe4\xa9\xf5\x22\x0e\x9f\x03\x15\xa6\x77\x05\xa3\xec\x08\xaf\x0d\xc7\x24\xb5\xcf\x67\xff\x34\xfa\xda\x8b\xa7\x10\x9e\xd2\xb5\xa8\x90\x7b\xb4\x03\xfb\x1a\x83\x8b\x4b\x05\x9f\x18\xc7\x92\xd7\xbf\xec\x05\xde\xe0\xc9\xcb\xbf\x17\x53\x40\x9d\x7d\xb3\xac\xea\xf4\x7b\x4c\x61\x39\x84\x97\xb0\xec\xa6\xc1\xf8\xac\x08\xa7\xea\x1e\xb9\xc4\x0b\xc4\xe9\x2e\x88\x82\x12\xf7\xd9\xee\x14\xfd\xb7\x31\x58\x16\x09\x44\xff\x9b\xcd\xfe\xf1\xa7\x46\x9c\xc7\x0f\x94\x74\xe5\xf2\x4d\xff\xfe\xa5\x85\xf0\x9e\xaa\xab\x4b\xe2\xaf\xeb\xbe\x8e\x6c\xf8\x6d\x35\x68\x0d\xc5\xd1\xb9\x29\x13\xe8\x48\x25\x6e\xc7\x36\x31\x6f\xd0\xa2\x14\x20\x63\xb0"}, +{{0x76,0xac,0x8e,0x57,0x0a,0x39,0xb3,0xa0,0x23,0x2c,0x45,0x49,0x75,0x37,0xfb,0x21,0x55,0xac,0xec,0x36,0x17,0x86,0x5e,0xd1,0xdf,0x21,0x0f,0x00,0xb4,0x9d,0x1b,0x8d,},{0x31,0x2a,0x3a,0xd8,0x99,0xae,0x6a,0x25,0x50,0x7a,0xe6,0xe4,0x52,0x4e,0x10,0xb6,0x3a,0x6e,0x7a,0xe5,0x3d,0x9c,0xff,0xd3,0x9c,0xf2,0x85,0x21,0xd9,0x35,0x33,0xd6,},{0xcf,0x03,0xf5,0x25,0x91,0x3c,0x44,0x30,0x3b,0x2f,0x80,0x07,0x93,0x93,0xc2,0x1c,0x11,0x58,0x14,0x6e,0xcf,0x99,0x63,0x6f,0x5d,0x97,0xad,0xfd,0xd9,0xf3,0x58,0x39,0x80,0x4c,0x23,0x80,0x4c,0xbf,0x1e,0x55,0x3c,0xfd,0x4b,0x73,0xf6,0x89,0xa9,0x14,0x3a,0xec,0x29,0x8f,0x82,0x76,0xe1,0xe4,0xee,0x08,0x91,0xf1,0xba,0x75,0xde,0x04,},"\x53\xce\xd9\xdb\x2b\x47\x9e\x59\xd3\xed\x64\x3f\x7c\xc3\x78\x4c\x24\xb8\xbd\x4c\x63\x20\x6c\x72\xe2\x3f\xa8\x50\x02\x88\x99\xa4\x1c\xe1\xa8\xbd\xc0\x03\xf1\x2b\x7c\x29\x97\x2c\x9a\x08\xbc\xd2\x31\xfe\x0e\x1a\x0f\xef\x0b\xaf\xbf\xa4\xe0\xe0\x27\xd7\x20\x04\x07\x5b\xa3\x7d\x49\x0e\xb9\x96\x4e\x78\x3b\xb9\x8f\x9e\x50\x3e\x9c\x1f\xd3\xd2\x3f\xb0\x01\x7c\xc7\xc7\xa9\xf8\x6d\x17\x1f\x04\x1e\x23\x55\xd8\xc5\xe6\x22\x9d\x34\xc7\xee\xac\xb6\x35\x8c\xf3\x06\x0d\x5d\x26\x5b\xae\x20\x04\xa5\x58\x87\x86\x59\xa3\x0d\xfe\xd5\xf2\xec\x78\x8b\x4e\x14\x39\x7b\x5d\x00\xc2\x9d\xb5\xd4\xeb\xf1\x66\x39\xa8\xdf\x29\x2a\x3d\x24\xf6\x98\x3c\xbc\xa7\x60\xd9\x03\xe9\x76\xf5\xb6\x98\x64\x2b\xa1\xfe\xd4\x9e\x79\xc3\x8f\x4b\xb3\x94\x6e\xfc\xcc\x9d\x6a\xef\xad\x33\x6d\x55\x8f\x78\xe4\xf2\x05\x42\x2e\x10\x38\x4a\x4e\x53\x1e\x75\x80\x7e\xfb\x38\x9d\x2a\xf4\xca\xb4\x38\x25\xfb\x87\xf1\x96\xa9\x08\x07\x69\xfe\x75\x85\x78\x29\x70\xa6\x91\x8a\xff\xe1\x0d\x20\xd6\x29\xb7\x05\x84\x55\x97\x41\x8d\x69\x9d\xe3\xf1\xde\x85\x4f\x94\xbd"}, +{{0xf6,0x4a,0x66,0xba,0x0f,0x08,0x19,0xf3,0x00,0x14,0x16,0xc2,0x20,0xbf,0x52,0xd8,0x60,0x13,0x0a,0x19,0x76,0x4a,0xa8,0xab,0x38,0xd1,0x5b,0x2a,0xa7,0x5a,0xc0,0x22,},{0x81,0x25,0x25,0x3c,0xd3,0x37,0xe0,0x0d,0x45,0xb4,0x50,0x79,0xb5,0x85,0x34,0x95,0x61,0xe5,0xf5,0x42,0xa8,0x1f,0x6d,0x2f,0xcf,0xd9,0x85,0xc1,0x0f,0xea,0xb2,0xaf,},{0x4d,0xe6,0xf5,0x25,0x08,0x22,0xd7,0xc9,0xd5,0xbb,0x98,0x58,0x25,0x00,0xb5,0xc0,0x85,0xf5,0x41,0xeb,0xdc,0x45,0x0e,0xd1,0xac,0xaf,0x83,0x68,0x48,0x27,0xed,0x1d,0xc7,0x71,0x47,0xaa,0xe4,0xb1,0x9e,0x14,0xa7,0xdc,0x5b,0xbe,0x1f,0x1e,0x4f,0x57,0x71,0xd8,0xa6,0xe4,0xf2,0x35,0x17,0x39,0xaf,0xb0,0x8c,0x80,0x6d,0x55,0x87,0x01,},"\x80\x72\x86\x2e\xd0\xab\x35\x92\x1d\xb5\xec\x2c\xba\x8e\x6a\xed\xb0\x44\x1f\xdf\x47\x49\x10\x06\xc0\x1e\x64\x56\xad\x70\xfa\xe3\xc4\x15\x2d\xcf\xbf\xdb\xb8\xf0\xfd\xde\xc5\xe9\x6b\x12\xbf\x67\x98\x9b\xa9\x67\x93\xf4\x86\x1a\x11\xb6\x39\x09\xce\x8d\x19\xb8\xca\x64\xa5\x44\xb3\x1c\xe0\x51\xfb\xc8\x8e\x06\x28\x06\xd9\x96\x5c\xbd\x29\x67\xb0\x16\x14\xe8\x6b\x53\x2f\xbf\x59\x84\x32\x18\xdc\x9c\x19\xc8\x03\x15\xf0\x44\x73\x17\x19\x37\x10\x92\xa3\xda\x38\x87\x8b\xc4\xcf\x77\xde\x97\x2e\x86\x04\x66\xb8\xfc\x45\xe4\x65\xdc\x3d\x0e\xbf\x94\xbd\xea\x60\xef\x0b\x98\x91\xce\xd4\x1b\x99\x7b\x11\xb3\x1e\xe4\x16\x7d\xb6\x0c\x9c\xfc\x8b\x85\xbe\xac\xfe\x22\x3c\xc1\x82\x92\x13\x77\x40\x85\xd7\xc0\x6d\x2b\x2e\x63\x2c\xc2\x1c\xd9\x66\x0d\xf4\x7c\x4f\xa9\x18\xbd\xd5\x96\xdd\xf6\x22\xdc\xb6\x52\x64\x2b\x67\x52\x7b\xa8\xed\x15\xa8\x19\xa8\xe2\x1f\x48\xd7\xee\x70\x24\x7f\x52\x00\xe3\x7c\x25\x9d\xff\xd1\x7e\xec\x8c\x23\x2f\x97\x0c\xb0\x31\x82\xfe\x39\x64\x13\x29\x93\xf6\xec\xb7\xc4\xdb\x18\xcc\xef\x39\x0c\x9e\xb3\x63\x9e"}, +{{0x84,0x39,0xb1,0xd6,0x0a,0xa4,0x84,0x60,0x13,0x5e,0xb1,0x00,0x2c,0xc1,0x12,0x79,0x29,0x95,0x07,0x9a,0x77,0xe6,0xe8,0xab,0x02,0x0b,0x9a,0xba,0xca,0x89,0x20,0xb4,},{0xea,0xdc,0x3e,0x0c,0x5b,0xdd,0xbc,0x30,0x52,0xc3,0xb2,0xf8,0xb0,0xa9,0x45,0x66,0xc2,0xb2,0xc8,0x79,0xed,0x17,0x03,0x4a,0xc0,0xe6,0xa4,0x5f,0x2b,0x3e,0x32,0xd2,},{0x62,0xda,0x81,0xe1,0x64,0x40,0x82,0x1b,0x59,0x3b,0x6e,0xe6,0x54,0x0e,0x15,0xd1,0xae,0xa7,0x5d,0x23,0xe0,0xa1,0xbb,0xfe,0xdc,0x80,0x8c,0x95,0x48,0xf8,0x7e,0x8b,0xbf,0x36,0x91,0x5a,0x39,0xa7,0x47,0x16,0xf6,0x45,0xcc,0xa5,0x71,0x4d,0x17,0x0a,0xf9,0x07,0x57,0x6d,0x4f,0x37,0x05,0xe5,0x43,0xd2,0xad,0xdd,0xc5,0xff,0x23,0x03,},"\x54\x19\xf6\xd2\x4e\xb4\x66\x35\xd4\xa7\xf8\xea\xb8\x03\xcf\xd0\xd0\x4d\xe0\x92\xaf\xbd\x86\xf2\xa6\x96\x1a\x8d\x1e\xb8\xc0\xd1\x97\xba\x55\xee\x08\xc9\x91\x82\x2a\x5a\xa7\x02\xba\xe0\x33\x7a\xbd\x5c\xa7\xfa\xa1\x5e\x1f\x1a\xe3\x69\x94\x6e\x9b\x81\x21\x6c\x0f\x5f\xc2\x2b\xbd\x44\x33\xc3\xde\x93\xc5\xca\xa2\x74\x16\x83\xbb\xd0\xe1\xa7\x8d\xf2\x8d\xda\x19\x17\x41\x01\x87\x63\x34\xd4\x03\x39\x65\x9f\x02\x1a\xe7\x66\x16\x2c\x6c\xc5\x42\x1b\x79\xcf\x9d\x5c\x09\x0e\xd4\xaf\x07\xec\x84\x49\x30\x35\xbd\x0b\x24\x21\xb5\x33\x68\x42\x95\xbb\xe7\x6a\x70\xfe\xc5\x96\xef\x8c\x89\xc5\xc9\xdd\xa3\xc3\x3b\x77\x35\xd2\xd2\xf2\x0b\x28\xf1\xa5\x40\x2e\x72\xd0\x4b\xa2\x91\xdd\x59\xf1\x4a\xf0\x8a\xdf\x56\xee\xb0\x86\xd7\x69\xc6\xbe\xc3\x45\x18\x91\x37\x23\x45\xfd\x6b\xd0\x2d\xcf\x95\xe8\x03\xaf\x03\x53\x15\x0e\x18\x2e\x32\x3a\xaf\x68\x3e\x03\x6d\x9a\x13\x5d\x2e\x6f\x98\xcb\x4d\x32\x7e\x2c\xe7\xd5\x42\x47\xf3\x59\x2e\xd0\x67\xb4\xce\x76\x27\x17\x4f\x99\x6f\x28\x16\x5c\x9c\x11\xf0\x7e\x5e\xe9\xce\xe6\x38\x51\xc6\xb6\x8e\xa2"}, +{{0x3a,0x04,0x63,0x97,0xf0,0xaf,0xc0,0x72,0xbc,0x7f,0x90,0x7c,0x74,0xd3,0x8f,0xd1,0xb9,0xaf,0xdf,0x27,0xe1,0x4a,0x35,0x34,0x76,0x8b,0x0d,0xd2,0xdf,0x3a,0x1c,0x22,},{0x99,0xcd,0x70,0xef,0x3b,0xe3,0x42,0x49,0x33,0x93,0x87,0x2f,0x54,0xc4,0x7d,0xea,0xa0,0x81,0x02,0x18,0x92,0xd1,0x1a,0x32,0x68,0xf3,0x14,0x5e,0xd4,0xf3,0xab,0xe5,},{0x50,0x24,0xce,0x60,0x25,0x79,0x65,0x68,0x70,0x80,0xc5,0xb1,0xfc,0x7d,0x13,0x01,0xc3,0x2a,0xa6,0xfc,0xc8,0x35,0x49,0x7d,0x9c,0xb2,0x3a,0x74,0xa6,0xca,0x27,0x24,0xf5,0x53,0x53,0xc1,0xb7,0x57,0x82,0x7c,0xa5,0x44,0x0c,0x9e,0xf8,0xf8,0xc1,0x05,0x09,0x13,0xe2,0x0a,0xab,0xec,0x35,0xc4,0x97,0xb5,0x60,0x41,0xb5,0xde,0xb2,0x09,},"\xf0\x8d\xde\xf4\x6c\xc6\xc3\x41\x79\x82\x0c\x98\x61\x37\x51\x72\xfd\xdf\x77\x4f\x8d\xc3\xf7\xd6\x4a\xa4\x32\xda\x8e\x5f\xae\x64\x4c\x0a\x8a\x9e\x69\x08\x51\x7d\x50\x5d\xeb\xd6\x12\x86\x8a\xc6\xda\xf9\x5c\xd7\xe1\x69\x97\x50\x02\x2c\xcd\x4b\x88\xdb\xae\x2b\xbf\x73\x54\x6e\xe4\xb8\x35\xd3\x19\xa8\x42\xda\xe8\xb9\xed\x68\x33\x23\xf3\x1e\x5c\xc5\x79\x19\xbc\x9d\xbe\x3b\xcf\xff\xb2\xad\xa4\x80\x72\x69\x7f\xf4\xa7\xd3\x10\xc9\x1a\xdb\xca\x81\xfa\xf2\x6a\x0e\xb7\xbb\x0c\x40\x4a\xc9\xd8\xdf\xec\x63\xe9\xc6\x4e\x2f\x42\x0c\x07\xd3\x23\xb7\xc0\xdc\x3b\x73\x50\x72\x83\xae\xb1\xce\xe5\x1d\xb4\xe1\xa8\x3a\x69\x2c\x7c\x1e\xa3\x98\xf6\xf3\x09\x40\xfa\xb8\x5e\x21\x38\xd4\xb8\x5a\xa4\xe2\x31\xe5\x42\x4f\x5b\x06\x4e\xd0\x26\xf0\xcc\xb9\x9d\x1c\x85\xa9\xeb\x15\xf5\x93\x4a\x11\x35\x9d\x41\x1c\xf9\x4a\xe8\xff\xa3\x36\x1a\x22\x4f\x46\xba\xb8\x52\xd1\x84\xa2\x48\xb4\xc3\x1f\xe3\xa7\xe7\xf5\x13\x4c\x05\x10\x31\xa9\xf3\x28\xa7\xbe\x4a\x7c\xbb\xb1\xd8\xd8\x63\xa4\x00\xfd\x2d\x58\xda\xa4\x4f\x1b\x9d\x8e\x9d\xdf\x96\x1c\xe6\x32\x2f"}, +{{0x12,0x4f,0x74,0x16,0xa8,0x04,0x53,0xe4,0xcf,0x1c,0xd7,0xb5,0xe0,0x50,0xa9,0x76,0x14,0x18,0x25,0x8b,0xf7,0xd2,0x7b,0xeb,0x7f,0x23,0x23,0x8c,0x45,0x40,0xbe,0x2d,},{0x0d,0xa3,0x4a,0xb1,0x73,0x99,0x01,0x50,0xdf,0x73,0x99,0xb6,0xbc,0xdd,0xba,0x93,0xc6,0xdb,0xcb,0xf4,0xd1,0x76,0x94,0x1c,0xb5,0x07,0x1e,0x87,0x34,0xc5,0xdc,0x92,},{0xb0,0x57,0x21,0x04,0xaa,0x69,0xe5,0x29,0xe3,0x46,0x5a,0x6f,0xd2,0x8f,0x40,0x4a,0x4e,0xc2,0x02,0x76,0xa9,0x93,0xb1,0x72,0x5e,0xb8,0xc5,0xf6,0x50,0xb4,0xa2,0x16,0xf1,0x87,0x1b,0x24,0xe3,0x68,0xcc,0x46,0xcd,0x1e,0xe0,0x17,0x4c,0xda,0x1b,0x5e,0x4a,0xe2,0x20,0x0a,0xa9,0xfc,0x44,0x52,0x2d,0x97,0x5a,0x9c,0x51,0x81,0x49,0x08,},"\x9d\xcb\x98\x73\xff\x05\x4d\xb1\x1d\x0a\x9b\x19\xde\x68\x85\xff\xba\x7f\x0e\x68\x1c\xf7\xfb\x8f\x6c\xd9\x50\xc4\x83\x28\xd1\xf9\x19\xca\x46\x05\x4e\xee\xe6\xc9\xe5\x78\x43\xeb\xdd\xa7\xb2\x4b\xc3\x50\x3c\x4d\x61\x2a\xbb\x1a\x31\x4f\x39\xf5\x82\x21\xd2\xb5\x4d\xc7\x55\xac\xca\x79\x69\x74\x0e\x7f\xa8\xb1\xa9\x52\x3b\x8c\x73\x79\xfd\x39\x52\x53\xf4\xe6\xcd\x05\x4e\xe2\x4b\x75\x61\x3c\x35\x81\xd4\x9e\x19\x24\x6a\x7b\x3b\xe1\xce\xcb\x33\x4b\xe4\x4f\x3d\x62\x6f\xe3\xb7\xb2\x69\xe6\x28\xd4\x45\x80\xc2\x06\x36\xeb\xa2\x64\x2f\x27\x44\xb9\x59\xe6\x57\x57\xd0\xee\x60\x18\x43\xf1\x88\xe9\x5d\x17\x25\x3f\xef\x56\x70\x68\xa5\x40\x5a\x3a\x9e\x67\x7f\xea\x3d\x7d\x55\xf7\xea\xd1\x9a\x3f\x30\xc5\xf9\x85\x67\x1b\x55\xfa\x12\x0c\xb9\xd0\x5f\x47\x1b\x6e\x1e\x8d\x77\x9a\x2c\x80\x3a\x19\xe6\xd0\xd7\xcd\x50\x78\x87\xed\x64\x7c\x2a\x95\x48\x3f\x93\x39\x91\xed\x45\xae\x30\x1a\x2b\x0e\x95\x4a\x57\x03\xd2\x48\xc7\x88\x10\xaa\x0b\x19\x9c\xc2\xbe\xbb\x2f\x1d\x71\xcc\x40\x48\x7d\xbd\x42\xee\xe0\xf7\x45\xf7\xd2\x85\x68\x5b\x1f\xb3\x1b\x15"}, +{{0x25,0xd1,0x3b,0x38,0x37,0x60,0x1b,0x07,0xa9,0x75,0x69,0x3e,0x5a,0x33,0xd5,0x33,0x7c,0x34,0xc1,0x12,0x7f,0xe4,0xc2,0x74,0x90,0x61,0x2a,0xaf,0x7f,0x64,0x2e,0x9a,},{0x3a,0x07,0xcd,0x68,0xee,0x26,0x92,0xd5,0x1c,0xfa,0xd1,0xa8,0x0e,0x77,0x63,0xb1,0x8a,0x04,0x3c,0x74,0xf4,0xe1,0xb0,0x1e,0xdc,0x55,0xba,0x9a,0x9e,0x07,0x79,0x5a,},{0x20,0xcb,0xf0,0x83,0x92,0xfe,0xa6,0xa9,0x9c,0xf4,0x46,0xa9,0x5c,0x19,0x9c,0xaa,0x0c,0x0f,0x98,0x13,0xcc,0x21,0x7b,0x8d,0x22,0x8e,0x2e,0xd9,0x0b,0xab,0x95,0xea,0x92,0xcd,0x73,0xac,0x95,0x83,0x47,0x64,0xd3,0x3e,0x42,0x24,0x3c,0x80,0xa7,0x60,0x34,0x91,0xc8,0xd3,0xe4,0x9a,0xc7,0x15,0xfd,0x8a,0x5b,0x9e,0x47,0x89,0xbb,0x03,},"\x11\x5b\x32\x20\xb4\x5c\xa8\xf3\x6c\x7f\xf5\xb5\x38\x87\xd4\x7e\x66\x9b\x78\xda\xc1\x3b\x98\xcc\x7a\xac\xa5\xc2\xe1\x9f\xce\x81\xec\x86\x17\xca\x41\x0e\x11\xc9\xa9\x11\x8a\x66\x84\x53\xb3\x29\xff\xb7\x18\xea\xec\x73\x91\x72\xf0\xa8\x49\xa0\x84\x81\x92\xa5\xbd\xea\x18\xab\x4f\x60\xd8\xd1\xa0\xd3\x38\x95\x2d\x77\xb2\xcc\x13\xef\xe8\x3c\x76\xe8\xdd\x58\x80\x3b\x1d\x8b\x3c\x97\x29\xef\x10\x2b\x20\x83\x5b\x7d\xe8\x72\xbe\xf3\x01\x0f\x15\xa4\xca\xdd\xf0\x7c\xf7\xbd\xd2\x22\xd8\x4b\x17\x4b\xc2\x15\x27\xcf\xfb\x1b\x7f\xfd\xe8\x1e\x28\x1d\x30\xcb\x7b\xce\x25\xea\x3d\xff\xb6\xea\x1f\xbb\x06\xcb\x70\x56\x9a\x95\xed\x1a\x07\xe9\x7c\xa4\x2d\xe7\x0a\xa2\x18\x15\x9e\xfd\x60\x8f\xa9\xb0\x89\x6e\x0b\x58\x51\x8a\x32\x2f\x25\x1d\x13\x3e\x58\xc8\xfc\x14\x28\xab\x0a\x17\x0e\xd8\x45\xc7\x5f\xb4\x03\xf1\xff\xb9\x7d\x2d\x2a\x6d\x4f\x27\x79\x11\xd3\x26\xc1\xca\xbb\xb8\x51\x6c\xbc\x17\x90\x8a\xb8\x1f\xf8\xd7\x9a\xf4\x46\x11\xea\x1d\x05\x87\x9c\x1e\xc8\x1d\x06\x93\x6e\x0f\x4a\x0a\xef\x6d\x57\x48\xe1\x81\xd3\x0e\xc2\x52\x36\x59\x7a\x97\x3d"}, +{{0x7b,0x3a,0x76,0xde,0xca,0xea,0x60,0xc4,0x1e,0x95,0xb0,0x58,0x77,0xa7,0xda,0x82,0x06,0x4c,0x27,0x27,0x8c,0x8d,0x7d,0xf5,0xf0,0xbb,0x95,0xf0,0xad,0x2d,0x04,0x35,},{0xf8,0x0d,0xb5,0xc2,0x87,0x21,0xb1,0xc6,0x11,0xbd,0x87,0xeb,0x14,0x5a,0x98,0xbb,0xf3,0x83,0xb0,0x68,0x04,0x5d,0xf2,0x45,0x8d,0x1a,0x6f,0xda,0x09,0x9f,0x7f,0xc2,},{0x2c,0xd2,0x6f,0xb3,0xc4,0xf7,0x44,0x0a,0x72,0xaf,0xfe,0x93,0x56,0x4f,0x6f,0x65,0x59,0xad,0xb1,0x5c,0xc7,0xa2,0xba,0x10,0x87,0x9f,0xb7,0xd6,0x7e,0x47,0xd4,0xeb,0xd0,0x2f,0xe4,0x82,0x36,0x98,0xa5,0xfb,0xd4,0xa9,0x07,0xfd,0x69,0x18,0x4c,0x25,0x5a,0x17,0x0e,0x5f,0x17,0x47,0xfc,0xe9,0x68,0x10,0x2d,0xc2,0x19,0xb5,0x0d,0x02,},"\x37\x5f\xad\xae\xdd\x9c\xac\x49\xb6\x4e\x15\x74\x02\x80\x46\x06\x9f\x4c\x83\x65\x4c\x8a\x70\x11\xab\xdb\x64\xdb\x16\xb4\x7f\xa3\x11\x79\x81\x72\xf9\x07\x22\x17\xb0\xa6\xa4\x3e\x5d\xf6\xff\xcc\x11\x54\xbc\xec\x1c\x68\xe1\xd3\x5e\xc0\x58\x80\xd0\x12\xce\x76\xe4\xce\xbf\x30\x1b\xb2\xec\x98\x3d\x00\xb4\xa0\x54\x0c\x93\x7f\xf1\xc6\xdf\x94\x41\xc6\x1b\xdb\x3b\xe8\xe0\xc7\xc1\x1a\x35\xd4\x9b\x6f\x55\xc3\x81\x26\x9a\x0e\x76\x8e\xfb\xd4\x53\x44\x7f\xe4\x8b\x75\xac\x39\x64\x6c\xa8\x2e\xca\x7d\x14\x93\x04\x42\x34\x91\x87\x1c\x10\xdb\xcf\xc5\x97\x3a\x57\xfa\xb8\x37\x1c\x30\xcb\xc4\xe9\x0b\xec\xc0\xb6\x71\x52\x22\x6e\xe1\x77\xb4\xff\x36\x8e\xc8\x79\xb3\x91\xeb\x95\xe3\x6d\xcb\xb0\x7b\x2c\x16\xba\x39\x55\x45\xd4\x52\x9f\x72\x7b\x1a\x11\xef\x65\xd1\x20\x97\x6b\x7c\xcc\x86\xaf\x4b\xd2\x04\xcb\x94\x89\xc9\x21\xe4\x3b\xa5\xe8\x50\xcf\xe5\x98\x99\xf1\xc1\xec\x4a\xa5\xc9\x2b\x6d\xac\x69\x14\xb1\x95\x2b\x53\xdc\xb5\x40\xb4\x09\x23\x13\x81\x56\x89\x87\xbb\x22\x36\xbc\x40\x89\x5d\xf3\xf1\x7e\xab\x7c\x02\x74\xf2\x24\x4f\x95\x86\x12\xe8\x8e"}, +{{0x5f,0xf8,0xd4,0x05,0x26,0x08,0xeb,0x03,0x3a,0x5e,0x94,0xb6,0x03,0xce,0x38,0x4d,0x84,0x52,0xf6,0x0a,0x26,0x49,0x8b,0x91,0x12,0x56,0x7f,0x34,0x10,0xc1,0x86,0x66,},{0xc4,0x90,0x0d,0xe2,0x4d,0x9a,0xf2,0x48,0x27,0x63,0x10,0x99,0x26,0xaf,0x7c,0x48,0x13,0x80,0xfa,0xbc,0xda,0x94,0x40,0xc1,0xa5,0x3e,0xa1,0xcd,0xc2,0x7e,0x65,0x68,},{0xb7,0x37,0xd4,0xe5,0xbe,0x27,0xde,0xb6,0xd8,0x77,0x29,0xc6,0x36,0xdf,0xf7,0xa4,0x06,0xc0,0x13,0xf3,0x13,0xc3,0x8c,0xf6,0x83,0xfe,0x14,0xf7,0x5a,0x3b,0x30,0x05,0xd9,0x53,0x5d,0x7e,0x58,0x15,0xc8,0xf8,0xb3,0x7c,0x51,0xd6,0x92,0x71,0x11,0xc9,0x79,0xf7,0xd9,0xd8,0x1a,0x34,0x7a,0xa9,0xcc,0x09,0xed,0x4e,0x6c,0x18,0xe9,0x0f,},"\x13\x8c\x60\x55\x7c\x2e\x90\x08\xaf\xc0\x3d\x45\xbe\xc7\x1f\x96\x11\x49\xa0\x83\x59\x26\x75\x1c\x8f\xf3\x93\x5c\x7d\x65\x2d\x83\xe1\xb0\xb1\xda\x7d\x5b\xbe\x0b\x8e\x17\x1a\x4e\x49\xaa\xe0\x6f\xd8\xa9\xde\xff\x78\xdc\xde\x4d\x25\xb1\xaa\x89\x99\x98\xa0\xf9\x9e\x1d\xf6\xf9\x33\x7a\x3e\xa2\xf2\x4b\x76\xc3\x17\xa7\x01\x4d\xb4\xe5\x28\x31\x91\x79\x5a\x70\xd8\x82\x1d\x21\x78\x46\x49\x0f\x95\x87\x01\xd3\x9d\xc2\xc8\xce\x47\xd9\x28\x93\x88\x74\xd8\x7b\x35\x58\x98\x9b\xc7\x7a\xf8\x20\x97\x9a\x35\x1e\xef\x95\x94\xaa\x5b\x94\xf3\x34\x1e\xde\xd4\xea\x20\xb0\x8c\x3e\x7c\x56\x10\xd4\x32\x67\x81\x8d\xfa\xc0\xa8\x7d\xdf\x52\x7f\xbc\xe8\x51\x2b\xbf\x85\xb6\x6c\x9b\xb5\xd6\x2f\x0f\xe8\x40\x48\xf2\x3b\x19\x60\x4a\x5c\x8d\x82\xb1\xf2\x5a\x8d\xa0\x27\x31\xfe\xb2\xec\xae\x48\x9b\x84\x75\xf7\xbd\x32\x6d\xdf\x1a\x08\x18\x9e\x46\xc0\x8c\xf5\x05\x38\xc2\xa3\x63\xe2\xf4\xeb\x2c\x01\xa2\x04\xc7\xff\xbc\x0b\x98\x1a\xdc\x0f\xd9\x97\xaa\xfd\xf2\xa2\x22\xee\x84\xc3\x09\xf6\xe9\x5e\xc7\xde\x4f\xa8\x5d\x47\x68\xd5\xc0\x03\x16\x50\x28\x22\x5e\x22\xe0\x9e"}, +{{0xee,0xde,0xfc,0x17,0x57,0xe3,0xa7,0xe5,0xed,0x39,0x46,0xdb,0xed,0xc3,0x96,0xa3,0x62,0xf6,0x83,0xd2,0xc5,0x1b,0x0b,0x9f,0x60,0x76,0x5d,0x4b,0xfc,0x51,0x34,0xde,},{0xa9,0x87,0x2b,0xc2,0x19,0x2f,0xc0,0x2b,0x18,0x9c,0xee,0xd4,0x03,0xab,0x9f,0x27,0x0a,0x03,0x2a,0x83,0x5f,0xde,0xbf,0xaf,0x1c,0x9d,0x69,0x34,0xed,0x83,0x04,0xbc,},{0xd5,0xbe,0xa8,0xea,0x9a,0x5f,0xe9,0xed,0x6d,0x2b,0xf8,0x39,0x93,0x0c,0x0c,0x6c,0xd5,0x03,0x9e,0x98,0x8f,0x55,0x1f,0xde,0xdb,0x54,0x37,0xe1,0xc1,0xaf,0x0e,0xd7,0xb3,0x89,0x7c,0x03,0x57,0x11,0xc3,0xc5,0x19,0x26,0xbe,0x8d,0x1b,0x32,0x02,0x4d,0x5c,0xd5,0x82,0xf5,0xf8,0x36,0x9a,0xd8,0x4d,0x18,0xb1,0x25,0x02,0x65,0x2f,0x07,},"\xb1\x94\xdb\x73\xf9\x94\xcb\xdc\x3c\xbe\x63\x0b\xa7\x2c\x47\xc2\x24\x9b\xc0\x59\x2a\xb5\x47\x94\x2b\x1d\x1b\x88\x2b\x44\xf5\xb3\x85\x5e\x56\x8b\xdd\xdf\x92\xef\x05\x02\x2d\x88\xfc\xfc\x29\x4e\x76\xb6\x4a\x00\xe9\xc7\x43\x55\x37\x37\x63\xe4\x9a\x4e\xbc\x47\x24\x3d\x48\xa9\xad\x58\x89\x94\xa5\x18\xf8\x0f\x86\x15\xc2\xb3\x1d\xa5\x87\xa5\x3e\x52\x9d\x43\x5a\x86\x97\x35\x0d\xfc\xde\x02\xd2\x0c\xce\x7d\x5e\xee\xfe\x3f\x5a\xb2\xaa\xc6\x01\x25\x9c\xda\x38\x53\x8a\x1b\x83\x01\xf9\x83\x2e\x75\xab\x90\xf8\xa9\x32\xf2\x67\xea\xc1\x81\x00\x39\x65\xd5\x26\x6f\x20\x61\x80\xc6\xc3\x80\xec\xe8\x03\x57\x7c\xcb\x46\x17\x6b\xf6\x07\x15\x94\x86\xf2\x42\x59\x74\x7e\x2c\xa6\xfb\x19\x12\xdb\x7b\x78\xa9\x73\xb2\x84\x63\x87\xc1\x20\x80\x30\xee\x1f\x40\x0d\x0c\x5b\x5e\x8b\xde\x96\x35\xae\x55\x63\x8b\xa1\x7c\x73\x4d\xe8\x63\x8b\xb8\x5d\xfc\xd7\x66\x29\xa7\xf9\xf4\x0d\x6a\xb9\x54\xd5\x5b\xf8\x57\x5f\xc9\xc9\xa5\x95\x09\x7e\x08\x93\xdb\x5a\x7b\x8a\x6c\x45\x5e\xcb\xd3\xd2\x2d\x72\x5e\x19\xde\x29\x41\xf4\x67\xf9\xeb\x93\xd6\x6a\x0e\x2b\xbd\xbf\x92\xed\x1c"}, +{{0x09,0xd2,0x2b,0xba,0xa5,0x95,0x6c,0xfa,0xcb,0xbf,0x9f,0xd5,0x51,0x09,0x75,0x12,0x86,0x86,0xc4,0x0c,0x6e,0xa9,0x6b,0x89,0xef,0x4c,0x0f,0x0c,0x64,0x9b,0xcd,0x7f,},{0xe5,0x59,0xea,0x8a,0xcb,0xdc,0x61,0xb6,0x70,0x9a,0x7d,0x83,0xae,0x15,0x84,0x9a,0x6c,0x78,0xb2,0x03,0x92,0x3d,0xd0,0xa2,0x99,0x23,0x9e,0xe4,0x88,0x69,0x30,0xba,},{0xe6,0x52,0x75,0xc4,0x32,0x8a,0x70,0xad,0x62,0x40,0x8e,0xd7,0xfb,0x17,0x28,0xbe,0x87,0xa7,0x3a,0x81,0x4f,0xee,0x8e,0xbd,0x94,0xf2,0x66,0x5c,0x71,0xbc,0x66,0xab,0x0c,0x1b,0x07,0xa6,0x00,0xb3,0x0b,0xc0,0x81,0xa7,0x4c,0x53,0x68,0x57,0xc2,0x06,0x10,0x38,0x4b,0xe2,0x68,0xd9,0xaf,0x3e,0x3e,0xcd,0xdd,0x3e,0xb0,0xc1,0x4c,0x0c,},"\x1c\x26\xa0\xf3\xa1\xa5\xb2\xd7\xd5\xb2\x97\xaf\x8a\x6a\x68\x9d\x7c\x62\xa2\x52\x67\xe1\x97\xd2\x3b\xec\xd2\xf2\xb8\x16\xc4\xde\x92\xfb\xda\xff\xb9\x41\xc3\xfc\x8d\xb7\xa8\x43\x35\xa8\x4c\xfb\xc9\x2c\xb3\xac\x80\x6e\xd5\x8d\xf1\x6b\x6b\x8e\x11\x9a\x48\xdf\x4f\x27\xc7\x1e\x93\x1a\x59\x38\xe7\xd0\x02\x73\x48\x85\xe1\x3a\x25\x8a\x15\xb6\xe1\x13\x6e\xfb\xa7\x2f\x1d\x09\x6b\x68\x9f\x76\x18\xf4\x9c\x96\x80\x63\xe8\xf9\x91\xfa\x0b\x55\x60\x1e\x43\x0e\xee\x13\x49\x2a\x1b\x09\x41\x3e\xb2\x38\x13\x59\x1a\x7a\x9f\x07\x0c\xc3\x96\xca\x9d\x1f\xac\xdd\x4f\x4c\xe3\x7c\x40\xf7\x24\x5f\x55\x03\x5e\x10\xfa\xd6\xb8\x5b\x5f\x01\xa1\xda\xac\xc0\xdf\x94\x06\x9f\x7d\xe8\xf6\x46\x7f\x96\xd1\xfb\x98\x64\x8e\x8a\x05\x20\xa8\xcd\x72\x3c\x98\xe9\xdc\x2d\xd4\xb2\x93\x4d\x82\x28\xf0\xae\x1a\x41\x5b\xd3\xa7\xcd\xa3\x8d\x7a\x99\x83\xce\x1a\xf6\xf8\xc9\x70\xa2\xa5\x91\x63\x5f\xe1\x2b\x91\x75\x36\xef\x81\x5e\xaf\x1a\x31\x38\xd7\x0c\xe7\x0a\x79\x42\x64\xd7\xc9\x86\xd9\xee\x32\x90\x44\x5f\x15\xa9\x24\x8f\x27\x65\x27\x1e\x5a\x99\x21\x96\xae\x33\x1a\xbd\x41\x64\xbf"}, +{{0x77,0x82,0x6e,0xd3,0x51,0xa3,0xf0,0x92,0x54,0xae,0x56,0x92,0x88,0x5d,0x77,0x4c,0xb3,0xf2,0x44,0x10,0xa4,0x80,0x9f,0xd9,0x0f,0x8a,0x00,0xda,0x9a,0xee,0x99,0x03,},{0x3e,0xac,0x8f,0x41,0xee,0x73,0xe6,0xef,0x13,0x68,0x21,0xf7,0x95,0x7a,0x1c,0x27,0xe1,0x56,0x38,0xd0,0xe3,0x91,0x6e,0x6c,0xaa,0xc6,0xfb,0x7b,0xeb,0x7b,0xcf,0xb0,},{0x97,0x7a,0xdc,0xcd,0xb8,0x29,0xb4,0x0b,0xbd,0x8e,0x53,0x85,0x6a,0x78,0x3d,0xb3,0x46,0xa3,0x9d,0xff,0x62,0x04,0x1a,0x29,0x72,0xd2,0x90,0x09,0xf1,0xc9,0xff,0x81,0xb8,0xad,0x54,0xcb,0x90,0x1e,0x49,0x7c,0x1d,0x30,0x21,0xb5,0x0b,0x6c,0x69,0xee,0x73,0x55,0x8f,0xd7,0xbe,0x05,0xd6,0x25,0xf5,0x72,0x7f,0x9a,0xf2,0xce,0x87,0x02,},"\x1f\xf0\x6c\x0b\x39\x99\xce\xcb\x19\x00\xa4\x7d\x26\x7b\xea\xfb\xb3\x5d\x93\xd1\x4c\xb2\xc8\x92\x5e\x3e\x3f\xe5\xd9\x67\x58\x69\x25\xee\x4b\xaa\x41\x99\x8e\xdd\x01\x03\x20\x58\x10\xaa\xd5\xc0\xbb\xdc\x77\x87\x44\x76\x81\x02\x46\xd1\x30\x89\xa6\x4d\xb5\x76\x42\x4f\xae\x0b\xed\x96\x64\xa4\x2a\x49\x11\x47\xd1\xee\x3b\x9c\x3b\x1b\xa4\x87\x5b\xe1\x54\x62\x39\x25\x40\xf9\x97\x8d\x9a\x46\x30\xba\x4c\x52\x54\x99\x75\x1a\x45\xef\xc2\x99\xec\x7d\x73\xb1\x7f\x9a\xd2\x75\xee\x71\xa6\x87\xe7\x26\x90\xd7\x32\x02\x42\xd2\xdc\x2b\xd4\xd5\xc5\xcf\x0f\x17\xa4\x65\x18\x5d\xcf\x60\xf8\xef\xff\x53\x90\x3f\x20\xb0\xc2\xab\x21\x92\xd4\x43\x68\xf2\xf2\xfb\x36\x04\x8a\xf0\x71\xf7\xaa\x85\x7b\x14\xad\x1d\x11\x46\x12\x05\xbe\xbe\x17\xe0\x2b\xe2\xe3\xcc\xb6\x09\x28\x21\x88\x5c\x4e\x0d\x48\x11\xbe\x3f\x45\xb1\xfe\xa0\x88\x45\x3e\x02\x24\x32\xf5\x62\x56\x2b\x43\xa3\x55\xcb\x56\x27\x0c\xed\xb6\xc2\xc4\x2d\xbf\x9b\xe8\x50\xe7\x71\x92\xfd\xc6\x5c\xfd\x36\x83\x4b\xe9\x88\xdb\xe9\xa9\x3e\x25\x18\xc1\x38\xb0\x90\xfb\x9d\xa8\x27\xcb\x1c\x91\xc8\xfe\x52\xfe\x7c\x57\xf7"}, +{{0x99,0xa9,0x95,0x31,0xc3,0xcd,0x6e,0x3e,0x9c,0x90,0x0a,0x9e,0xeb,0x26,0x26,0x7e,0x72,0xf0,0x9d,0x11,0xb6,0x51,0xa8,0x97,0xeb,0xb7,0x9b,0xe0,0x16,0xf6,0x4c,0x6e,},{0x9b,0xf9,0xf8,0xb4,0x8a,0x27,0x28,0xe0,0x26,0x08,0xfc,0x19,0x89,0x9d,0x21,0x96,0x56,0x83,0x9d,0x1c,0xc1,0xe9,0xa8,0x98,0x4d,0xf6,0x74,0xec,0x26,0x66,0x2f,0x41,},{0x0e,0x89,0xda,0x5d,0x94,0x9c,0xf2,0xbf,0x40,0xc7,0xe1,0x7c,0x2d,0x0f,0x9c,0xea,0xbc,0x88,0xa0,0x92,0xeb,0x4d,0x49,0xcf,0xbf,0xea,0xb7,0xc8,0xbf,0xf4,0x32,0x45,0xc6,0x7b,0x9e,0x2e,0x92,0xf9,0xbc,0xb9,0xb3,0x4b,0x3f,0xcf,0x8b,0x01,0xfa,0x2e,0xa7,0xa9,0x64,0x9f,0x81,0x4c,0x3a,0xa9,0x8b,0x3d,0xd0,0x45,0x40,0xc3,0x1d,0x09,},"\x7a\x89\xc0\xc1\x95\x2f\xdc\x42\x98\xdc\xae\xa8\x54\xef\xc1\x34\x65\x6b\xe1\x47\xe9\xe8\xe8\x2f\xc9\xa4\x49\x05\x9d\x80\x57\x0f\x75\x67\x6b\x81\xc4\xa9\x4f\x76\xa9\x68\x20\x0c\xde\xb0\x98\x8c\x73\xf5\x9a\xfc\x72\xad\x4c\x31\x03\xe1\x9f\xe6\x3b\x7e\x95\xe1\x40\xb5\xcb\x2e\xfc\x7b\x97\xa6\xff\xbb\x6c\x29\x8d\xda\xce\x3b\xe6\xd2\xed\x3d\x59\x8b\x8b\xdf\x0c\x2f\xe6\xc9\x76\x02\x14\x2a\x76\xe9\x78\x51\x4c\x19\x6c\x1b\x9a\x88\xef\xdc\x19\x25\xfc\x50\x61\x55\xcf\xf9\xa2\xf2\x1a\xb6\x34\xe2\xb9\x3e\x96\x92\x8a\x5d\x8f\x7c\xe4\xcb\x73\x26\xd9\x68\x94\x69\x24\x2b\xa9\xc6\xa0\x1b\x77\x49\x6b\xad\xef\x87\x57\x8f\x5a\x17\x28\x4e\x90\x0a\x72\xdf\x14\x1c\x61\x99\xb0\xe7\x1a\xb5\xda\x43\x75\x03\x76\x17\xec\x61\x96\xd4\xf4\xe2\x3a\xe2\x91\x6a\x72\xd0\xfc\xe7\x96\x02\x23\x05\xac\x9f\xbb\xbb\xe4\x70\x5b\x34\x0e\x42\xb7\x8e\x1c\x02\xbb\x10\x01\x86\x0c\xdc\xaf\x71\xed\x89\x25\x5d\xd5\x6c\xc0\xb3\x1c\x59\xd4\x59\x6d\xce\xf8\x4e\x22\x23\x4b\xe5\x62\xbd\x80\x1e\x94\x11\x1d\x83\xa7\x80\x64\xc9\x0f\x9d\x82\xfc\xe9\x1f\x68\xab\xb0\x3c\x73\xb6\xbd\x8d\x7e\x02\xd4"}, +{{0xaa,0x58,0x40,0x3e,0x76,0x3b,0xac,0x40,0x5d,0xb0,0x65,0xeb,0x11,0xeb,0x6b,0xe3,0xe3,0xb6,0xcf,0x00,0xec,0x4a,0x22,0x2b,0x52,0xbf,0xf4,0xb6,0xe3,0xd1,0x56,0xac,},{0x16,0x7f,0x9b,0x9a,0x46,0x65,0xf9,0x3f,0x5d,0x7d,0x30,0x16,0xac,0xe6,0xfb,0xd1,0x34,0x20,0xb2,0xe5,0x1e,0x72,0xbd,0xe5,0x9e,0xed,0xf2,0x69,0x93,0xb6,0x6c,0xae,},{0x64,0xb5,0x98,0xca,0x5b,0x8f,0x9a,0xe7,0x42,0xe4,0x6e,0xe0,0xd8,0xc1,0xaa,0xf3,0x14,0x58,0xb5,0x0c,0x25,0xd2,0x67,0xa6,0x77,0xe4,0x4b,0xe5,0xb7,0x55,0xf1,0x4d,0x51,0x80,0x1a,0x30,0x39,0x9b,0xfc,0xc3,0x8d,0x14,0x07,0x1a,0xa0,0xae,0x93,0xda,0x82,0x5a,0x58,0x1a,0xb6,0xc2,0x07,0x25,0xa0,0xa9,0x10,0xb4,0x73,0x5d,0xfa,0x0b,},"\x3b\xaa\x09\x98\xff\x02\xb3\x2b\x90\xb5\x1f\x9a\x84\x0c\x7b\x5c\x58\x70\xcf\xb1\x81\x0a\x9b\x0f\x77\xb5\x59\x09\xd4\x7a\xd3\x35\x14\x7a\x99\x1c\x29\xfb\xeb\xfc\x59\x2e\x93\x07\x17\x5c\x19\x64\x12\x9a\x2d\x5e\xfc\x62\x15\x80\x74\x53\xbc\xd7\x26\x96\x97\x81\x22\x2b\xca\xd1\xc9\x9a\x49\x74\x8b\x9e\xe6\x67\xc4\xd0\xc8\x28\x89\xe2\xf5\x00\x64\xc1\x15\xdb\xd8\xfb\x48\x3d\x72\xab\x0c\xca\xdf\x76\xbd\xdb\x2d\xc7\x27\xdb\xc3\xfa\x5c\x46\x24\xc2\x83\xd8\x92\x1c\x8a\xa4\x42\x51\x10\xdc\xdd\x69\xc0\x5e\x5e\xd5\x9b\x35\x96\x25\xee\xaa\xec\x1e\x27\xea\xfe\x9d\x9a\x5c\xe7\x36\xc3\xf9\xc5\x27\xea\x54\x78\x18\xb9\xbc\xa6\x81\x1b\xe4\xcc\x15\x05\x8a\x6f\x5b\x68\x33\x03\xb8\x0c\x90\xc9\x4a\x83\xb8\xb1\x58\x69\x71\x3a\x66\xb1\xe0\xf6\x56\x33\x1b\x28\x6d\x1e\xf7\x69\x88\x34\xab\x3e\x13\x84\x17\xaa\xd6\xbb\x3a\xb3\xbd\x9f\xc7\x87\x61\xa4\x82\xdf\xc6\x54\xf3\xf8\x62\x8c\x8d\x9f\xc1\x60\x18\x89\x8f\x16\x41\xe8\x62\x2b\xd2\x72\xe3\x8d\x41\x70\x6c\xb9\xce\xbe\x6e\xe5\xe1\x73\x57\x6b\xf6\x1b\xb1\x18\x8c\xf2\xf3\x9c\x62\x22\x0b\xba\x88\xfc\xb4\xde\x48\x98\xb2\x5b\x04"}, +{{0x10,0x44,0xee,0x37,0x08,0xc0,0xb0,0xe9,0x09,0xa8,0xcb,0x2b,0xa2,0xcd,0x0a,0xf8,0xd2,0x8a,0x5d,0xe0,0x1d,0x96,0x2e,0x82,0x60,0x87,0xfb,0x23,0x2d,0xf7,0xb2,0xd2,},{0x46,0xd2,0x41,0xea,0x0c,0x70,0x2c,0x18,0x89,0xd4,0x46,0x55,0x82,0x46,0x29,0xb6,0x72,0x84,0xd4,0xe6,0x44,0xa4,0x8f,0xa4,0x54,0x55,0xd2,0x7a,0xc5,0xf6,0x25,0x29,},{0x7d,0x6b,0xed,0x7f,0x87,0xd0,0x90,0xab,0xe0,0x13,0xc3,0x1e,0x12,0x03,0x90,0x3b,0xac,0x9c,0x93,0x44,0x5d,0x06,0xc7,0xb5,0x3d,0x31,0xd1,0x5f,0x97,0x0d,0x88,0x64,0x7a,0x7e,0xd2,0xc3,0xa6,0x30,0x50,0xba,0x19,0xd6,0x80,0x43,0xaa,0xdd,0x18,0xbd,0x86,0x1d,0xe1,0xac,0x47,0x15,0xb8,0xe8,0x28,0xb2,0xb1,0x6f,0x8a,0x92,0xb0,0x01,},"\xb8\xa4\x45\x45\x5f\xb6\x6e\x17\xe3\x14\x3d\x35\x20\x4c\x9e\xa9\x34\x74\xee\xbe\xef\x93\x96\x3e\xe5\xc1\xd3\x77\xca\x21\x7a\xcd\x4c\xa6\x3e\x57\x55\xda\x08\xfb\xff\xdb\xd4\x35\x2b\xf1\x65\x19\x38\x96\xc8\xd6\xf7\x6b\xb4\xcd\x3b\xc2\xd3\xa4\x76\xa4\xe3\x20\x82\x4a\x12\x10\xce\x74\xd0\x01\x4d\x74\x7f\x11\x1e\xec\x31\x0c\x5c\x89\xed\x4d\x08\x50\xe8\x11\xf8\x0a\x8b\xb2\x8d\xca\xf6\xf4\x11\xdf\x83\xe2\xc1\xdf\xd9\x0c\x4a\xd2\x35\x61\x45\x4e\xb5\xd7\x56\xb6\x3b\x4e\xa7\xf3\x7d\xc5\xd4\x66\xc1\x6e\xf7\x0d\x11\x19\x0c\x4f\x53\x16\xfe\x2a\xa8\x59\x74\x40\xe8\x8b\xbe\xba\xeb\x35\xea\x5f\x04\xf0\x7b\x03\x39\x26\x41\x58\xef\x90\x9a\xd5\x16\x3b\xfc\x24\x8c\xd7\x24\x13\x3e\x27\x4f\x81\x26\x95\xf2\x90\xe5\x71\x76\xa9\x6b\x93\x93\xd0\x7b\xb3\x10\x29\x9f\x5d\x2a\x6b\x6d\xd1\xda\xbc\xb5\x1b\xf2\x9c\x5a\xfa\x7e\xbb\x07\x01\xc6\xc8\x47\x67\xac\x13\x77\x93\x09\x1f\xe0\xed\x6e\x47\xd7\x80\x62\x8a\x32\xc8\x4f\x83\xe0\x0e\x9c\x16\x74\x2a\x52\x3e\xcb\x63\xc2\x4f\x4a\x33\x8e\xd2\x99\xa0\x61\x94\x92\x4f\x44\xc5\xa5\xd3\xc9\x37\xff\x9b\x09\x45\x98\x2a\xd2\x4a\x2d\x1c\x79"}, +{{0x95,0xdd,0x1a,0x5e,0x65,0x8f,0xa6,0xc8,0xd4,0x25,0x07,0xb3,0xe5,0xb8,0xed,0xb5,0xba,0xec,0xa6,0x2d,0xeb,0x00,0xfc,0x5d,0x4d,0xca,0x8e,0x1a,0xb5,0x83,0x5e,0x59,},{0x3a,0x53,0x23,0xdd,0x1e,0x07,0xf3,0x23,0xbb,0x6d,0x83,0xe9,0xc2,0xdb,0x92,0xa2,0x9f,0x62,0xe2,0xe0,0x03,0xee,0x0d,0xea,0xcd,0x7e,0x2e,0x4e,0x03,0x0d,0x8d,0x27,},{0xd0,0x2a,0x75,0x23,0xdc,0xbd,0x29,0x57,0x6b,0xa8,0x09,0xb5,0x31,0x03,0x77,0x74,0xdf,0x41,0x73,0x4a,0x41,0x17,0x58,0x13,0x11,0x9c,0x6a,0x6a,0x78,0x8c,0xd9,0xb8,0xad,0x78,0x08,0x65,0x67,0x86,0x67,0x69,0x9a,0xe6,0x6d,0x01,0x09,0x19,0xa9,0x66,0xa0,0x51,0xc0,0x81,0x63,0xdf,0x67,0xa9,0x77,0xee,0x6e,0x22,0x0d,0x0d,0xc3,0x0f,},"\x9b\x7a\xfd\x48\xc4\x74\x60\x4c\x26\x36\x75\x31\x55\x68\x40\xc3\x88\x66\x8b\x0f\x38\x40\x06\x3d\xfc\x98\x69\xad\x5b\x90\x12\x74\xb9\x31\x29\x3d\x04\xf3\xc8\xe8\xf7\xf8\xea\xb8\x15\xa6\x41\xd7\xc3\x51\x28\x4e\x8b\xb0\x43\x7a\xc5\x51\xbb\x29\x43\x89\x64\xe6\xa7\xc7\xba\x77\x23\x44\xb3\x33\xf9\xed\xa5\xa7\x75\x68\xc8\x93\x1d\xdc\xaf\x21\xe3\x2e\x07\xb1\x0b\xf4\x82\x0f\xb8\x59\xbc\xf8\x7b\x81\xc4\xbf\xf4\x26\xf2\x4a\x4d\x46\x8f\x2e\x9a\xed\xa8\xf1\x7d\x93\x97\x09\x97\x0d\xb1\x1d\xf7\x62\x47\xe9\x8a\x39\xeb\x8b\x38\xf5\x94\x9f\x34\x9f\x2a\xe0\x5a\xb4\x8c\x01\x85\x17\xc4\x8f\xa0\x20\x5d\xc7\xf1\x56\x64\x53\xe1\x05\xe4\x8c\x52\xeb\x45\x5c\x0c\x40\x80\x2f\x79\x7b\x3e\xef\xb1\xe2\xf3\xb1\xf8\x43\x15\xae\xd5\xb0\x71\x1c\x64\x99\xa6\x91\xb7\x4b\x91\xf1\x2e\xf7\x0f\x76\xc4\xc0\x5c\x1a\xa1\xa9\x93\xe2\xf3\xe5\x28\xab\x34\x3d\xd2\x36\x81\x62\xf4\x03\x6a\x61\xa1\x3a\x88\x04\x5d\xcd\xef\xa8\x5d\x68\x53\x22\x75\xbc\xf5\xb8\xf5\xf0\x0e\xfd\xea\x99\x9a\x95\x78\x31\x75\xd9\xee\x95\xa9\x25\xd4\x8a\x54\x49\x34\xd8\xc6\xb2\x62\x22\x5b\x6e\xbe\xa3\x54\x15\xdd\x44\xdf\x1f"}, +{{0x1a,0xbc,0x0b,0x9a,0xa0,0x1d,0xc5,0x7c,0xa5,0x3e,0xfe,0x73,0x80,0x96,0x2b,0x1a,0x88,0xd5,0x0a,0x96,0x4f,0x5c,0xd9,0x86,0x40,0x98,0x2c,0x74,0x39,0x3f,0x29,0x26,},{0x8d,0x4f,0xd1,0x43,0x94,0xd7,0xc1,0x40,0x57,0x00,0x30,0x69,0x83,0xfb,0xf7,0x6e,0xa9,0xf1,0x71,0xb1,0x5a,0x6b,0x56,0x61,0x2a,0x1f,0xeb,0x1c,0xbd,0xae,0x5d,0xd5,},{0xf7,0x38,0xaf,0x2d,0x3e,0x29,0x0b,0x3d,0x23,0xd9,0xaf,0xf7,0x41,0x4b,0xfc,0x5f,0xfa,0x47,0x23,0x5d,0xc0,0x53,0x68,0x7a,0x8b,0xa5,0xc8,0x54,0x1b,0x85,0x11,0xf7,0x81,0x56,0x6c,0xda,0xa1,0x30,0xe0,0x67,0x7d,0xb5,0x5f,0xa8,0xbe,0x9d,0x81,0xa0,0x92,0xcb,0x58,0x92,0x3a,0x86,0x28,0x49,0x4d,0x2f,0x62,0xd9,0x5c,0x16,0x71,0x00,},"\xda\x2d\xd9\x40\xd5\xe1\xdb\x6e\x80\xbf\x7e\x2b\x78\x2e\x7e\x74\x5c\xd4\xfd\x25\x2e\x98\x15\x17\x97\x58\x87\xdd\x05\xac\x77\xed\x83\x7d\x08\x29\x61\x57\x5e\xfe\xdf\x30\x1f\xdf\x24\xb7\x07\x18\xb9\x91\xb8\xd9\x2b\xdd\x2e\x6b\xee\x17\xc8\xaa\x4b\xc6\x94\xa7\x27\xbc\xfc\x78\xfd\x85\x19\x5c\x42\xca\xf8\x83\xa2\xc3\x8d\x16\x1c\xad\xd7\x9c\xfd\xa9\xa3\x91\x10\xe1\x26\x4d\x30\xbd\x4c\x5c\x4a\x58\x76\x77\x7f\x23\x3b\x07\x1b\x1b\x0b\x40\x89\x35\xf0\x46\x89\x54\xcc\x74\x4a\xf8\x06\x3b\x00\x4e\xde\x56\xcd\x98\x1c\x4d\xd5\x60\x8a\xbf\xfe\xae\xc9\xe5\x8f\x3f\xaf\xaa\x67\x14\x67\x80\x4b\x7f\xa2\x55\x8f\x4f\x95\x17\x42\x01\xf1\x83\xd8\x0a\x59\x14\x06\x5f\xed\x53\x11\x5b\x41\xeb\xc3\x38\xf7\x8d\xf0\x50\x05\x3b\x8a\x4e\x75\xea\x7c\x6f\xdc\x35\x4d\xad\x27\xbf\xd8\xa2\xe6\x6f\xcd\x7a\xe2\xf5\x87\xd2\x4b\xe0\xd4\xa3\x3d\xa3\x0a\x22\x0e\x51\xbc\x05\xfa\x4e\x41\x2b\x95\x9f\xd9\x5d\x89\xea\x6e\xc0\x16\x25\x16\xc0\x96\xa9\x43\x3a\x9e\x7c\xf5\x99\xc9\x28\xbd\x53\x05\xc2\x17\x3b\xf7\x49\x3e\xd0\xc1\xc6\x03\xcd\x03\xf0\x82\xcc\xe4\x42\x37\xa7\x9f\xfd\x8b\xe9\xa6\x72\xc2\xeb\xaa"}, +{{0xcb,0xff,0xce,0x2c,0x9b,0xd3,0xe2,0x3e,0x40,0x6e,0x5f,0x66,0xe6,0x32,0xdc,0xfa,0x72,0x66,0x54,0xd2,0x9a,0x95,0x5c,0xec,0x98,0x31,0x73,0x23,0x5f,0xa3,0x59,0xd0,},{0x49,0x65,0x3e,0xdd,0x64,0xa5,0x5f,0x7c,0xd4,0x0e,0xaf,0x3f,0x8e,0x72,0xeb,0x96,0xdb,0xcd,0xee,0x39,0x8f,0x34,0x81,0x7f,0x2c,0x95,0x86,0x79,0x49,0x71,0x0b,0x14,},{0xe7,0xce,0xd4,0xfa,0x2a,0x7d,0xff,0x73,0xf1,0x06,0x8b,0xba,0xd0,0xec,0x9a,0x11,0x09,0x04,0x3c,0x97,0xa6,0x2e,0xff,0xa1,0x48,0x87,0x6f,0x09,0x69,0xed,0x4d,0xc6,0x08,0xe2,0x8b,0xce,0x79,0x7a,0xf3,0xb8,0x25,0x32,0xc9,0x4d,0xec,0x4d,0x68,0x11,0xb7,0xf5,0x63,0x67,0x91,0x29,0xfa,0xcf,0x17,0xbb,0x73,0xd6,0x93,0x75,0xeb,0x05,},"\x1f\xfd\xe6\x82\x6e\x4f\x0c\x24\xa7\x96\x1f\x19\x1e\x74\xcc\x0b\xbc\x92\x8e\x3f\x1a\xec\x3e\xfa\xb3\x27\x65\xc2\x50\x1c\xbc\x16\x20\xe7\xee\x6f\x61\xfc\xcf\xb0\x0c\xfc\xa9\xfb\x98\x14\x3b\x52\x9b\xcc\x8c\x3d\x0f\xdf\x89\xee\x7c\x34\x2f\x10\x18\x15\xfa\xbf\x7d\xea\xf9\xf3\x02\xa2\x88\xfe\x17\x58\x26\xd5\x90\xd9\x9e\xe6\xfd\x92\xda\x74\xf9\x59\x6b\x78\x3c\x0e\x7d\x47\xd7\x11\xa3\x2f\x39\xea\x41\x65\xe5\x21\x24\x31\x44\x1b\x49\x8c\x6b\x70\xdb\x3b\x09\xd1\xf4\xe4\xa1\x4a\x6b\xae\x39\xda\x50\x88\xbb\x85\xb3\x28\x5c\xe9\xdf\x2f\x90\x68\x1a\xf2\xc7\x4d\xec\xe4\x39\xae\xb9\x1e\x1c\x1b\x07\x12\xed\xdb\xee\x8d\x72\x56\x98\x28\xf3\x7c\xb7\x20\xc5\x09\xd0\x2a\xec\x47\x60\x70\x48\x4e\x9b\x16\xec\x71\x79\x94\x7a\xc9\x6c\xaf\x0e\x1b\xe8\xb6\xb7\x4f\x37\x2d\x72\x35\xfe\x6e\x39\x99\xdf\x73\x3b\xcc\xd4\x82\xdf\xe2\xe6\x31\xf5\x6b\x58\x26\x67\xdc\xe5\xe3\x12\x17\x63\xad\xfa\xcf\x3b\x18\xcf\x20\x95\xf7\x39\x4d\xee\x49\x27\xfc\x2b\xea\x6b\x58\x24\xd9\x0c\xd5\x9e\x85\x4e\xc5\x87\x2b\x45\x51\xb0\x2e\xfa\xba\x5a\xd5\x4a\x9b\x7a\x8f\x6d\xe5\xd7\xcd\xa5\x82\x5b\x32\x5b\x07\x6d\xed"}, +{{0x9f,0x91,0x23,0x14,0x97,0x48,0x4c,0xab,0x39,0xb9,0xe2,0x0f,0x86,0x11,0x81,0xd3,0x97,0x90,0x85,0x77,0xbb,0xb2,0x96,0x82,0x42,0xd0,0x71,0xbc,0xa4,0x81,0x3f,0xfb,},{0x88,0x24,0xbc,0x6c,0xd6,0xa6,0xf1,0x5a,0x5f,0x41,0x66,0x8f,0x2b,0x3b,0xae,0x8f,0xc4,0x96,0x73,0x83,0x07,0x8d,0x08,0xb5,0x1d,0x6d,0x1b,0x2b,0x93,0xa1,0x07,0x1f,},{0x0a,0x1c,0x70,0x6d,0xd8,0xa1,0x30,0x77,0xab,0x18,0x38,0x6c,0x65,0xfa,0x97,0xcf,0x9d,0xfc,0x43,0x54,0x2d,0x18,0x46,0xec,0xbd,0xde,0xb7,0xb3,0xc9,0x3f,0x3c,0x66,0xf3,0xcc,0xd0,0x44,0x7a,0xac,0xdd,0x4d,0xad,0x8f,0xbf,0x73,0x6c,0x4f,0xf9,0xdb,0xdb,0x62,0xbf,0xc1,0x4d,0x88,0x83,0xe3,0x85,0xbc,0xe9,0xba,0xc5,0x6a,0x35,0x0c,},"\x21\xd4\xfb\xc9\x81\x63\xc3\xfb\x6e\x09\xf7\x75\xc2\xab\x7b\x18\xb1\x87\x92\x34\x0b\xaf\xed\xac\xb4\x96\x05\x62\x2e\x3c\x08\xaa\x3b\x2b\x8d\x0e\x09\x02\xf3\x61\xaa\x1c\x0f\x65\x2e\x27\x32\xb1\x0a\x0c\x5c\x6a\x05\x09\x89\x96\xb5\x88\x26\x7c\xc8\x95\x1a\x78\xb5\xd4\x31\xe7\x22\x2b\xbb\x50\x8e\xee\xf1\xb5\xe8\xb8\xd0\x1d\x39\x91\xe1\x8d\xdd\xc6\xca\x8d\x22\x2e\xf1\x77\xce\x62\x93\x8d\x18\x10\xee\xcf\x06\xf4\x73\x8b\x28\xf4\x40\x94\x6c\xca\xd2\xa1\x2e\x39\xd3\x86\x11\xbe\xd3\xa3\x9f\x93\x41\x9a\x17\x9e\xc2\xb1\xb5\x2d\x5f\xe5\xc8\x0c\x23\xb8\x4d\x88\x03\x75\x5f\x51\x46\x09\x2c\xc1\x99\xb4\xbd\xce\xa5\xbc\xf2\x03\x7b\xd5\x3f\xf6\x34\x66\x94\x15\x5f\x02\x7d\x8c\xe2\xba\xff\xe3\x0a\x56\x66\x59\x6c\x00\x78\x3a\xae\xad\xe9\xc7\x7f\xc8\x63\x79\x42\xec\xe0\x17\xd6\x48\x4c\x28\x99\xb1\x91\x8d\x3a\x48\x0b\xd5\x15\x76\x78\xd4\x77\x2d\x27\x1f\x9b\x99\x76\x8e\xe1\xbc\xc4\x6b\x24\x89\xae\x87\xcd\x03\x0f\x47\xd1\x33\x3c\x76\x72\xcb\x90\x2c\xb4\xf5\xfe\x74\x6e\x85\x3d\xe5\x79\x40\xba\x22\x64\xd3\xe6\x29\x64\x4d\x65\x3a\x5b\x7a\xf7\x8c\xe6\x4a\x99\x3f\x36\x25\x0f\x8c\xb7\xcb\x45"}, +{{0x1e,0x2b,0xd5,0x48,0x7c,0x5f,0x5c,0xed,0x46,0x1f,0x60,0x4d,0xcc,0xb4,0xe7,0x8e,0xb9,0x16,0x08,0xf0,0xb8,0x21,0xf5,0xaf,0xc4,0xe3,0xe5,0x34,0xf7,0x96,0x03,0x92,},{0xef,0x82,0x54,0x75,0xcf,0x20,0x51,0xa2,0x01,0x7a,0xe5,0x32,0xf0,0x77,0xd9,0x67,0x74,0x34,0x7d,0x27,0x67,0xea,0x7b,0x45,0xf9,0xc1,0xb8,0x60,0xab,0x99,0x35,0x06,},{0x4d,0x33,0xc9,0x6a,0x2e,0x3a,0x5d,0xb7,0x39,0x1a,0xdf,0x65,0xc1,0xcc,0x35,0x65,0xfe,0x76,0xee,0xaf,0xd0,0xb5,0xc7,0xab,0xb0,0xb4,0x92,0xa0,0xb5,0x1e,0x1f,0xa3,0x36,0x39,0x94,0x6a,0x24,0x3b,0x2d,0xde,0xf3,0x57,0x55,0x22,0x98,0xce,0x0a,0xa9,0x5e,0xac,0x6f,0xbf,0xe6,0x60,0x98,0x82,0x71,0x87,0x7e,0xb2,0xa7,0xda,0x18,0x06,},"\x1d\xbb\xbb\x13\xcd\xad\x88\x85\x4b\x80\x9c\xed\xed\x27\x33\x43\xd3\x06\xa8\xde\xab\xf3\xff\x02\xc9\xce\xc6\xf0\x02\xb8\xe9\xe1\x0e\xf5\xd1\xb0\xf5\x71\x1f\x33\x26\x7a\xa9\x1c\x17\x1b\x61\xe9\x60\xf7\x40\x45\x7b\x81\xd7\x51\xa4\x73\xf4\x4f\x75\x0a\x08\x0c\xab\x80\xaf\x7c\xcc\xa7\xdf\xfc\xfa\xc9\xee\x4c\x39\xdc\x85\xcb\xdf\x51\x25\x9c\xcd\x34\x70\xd9\xba\xd3\xad\x30\xf4\xee\x5d\xbd\x4f\xac\x6b\xd5\xc6\xc4\xdf\x73\x11\xa4\x70\x04\x46\x95\xa7\xe1\xa7\xe1\x85\x72\x20\x75\x88\xaf\xa5\x7e\xeb\xcd\x4d\x57\x5b\x6d\x42\x44\x57\xee\x92\x46\x5c\xe1\x86\x3e\x3c\x67\x7c\xf8\x75\xfd\xb9\x8d\x40\x78\xeb\xe7\x14\x42\x60\x80\x70\x52\x57\x71\x44\xcb\x8e\x03\x59\xaa\x42\xad\x15\x5d\x79\xda\xe3\xde\xb9\x9c\x46\x32\xc1\x91\xc7\x99\xcb\xfe\x58\x7d\x95\x47\x87\x06\x8d\x66\x3b\xdf\xc0\xfa\xb1\x33\x4f\x18\x76\xbf\x49\x8c\x4d\xb5\xc5\x3d\xb7\xb0\x20\x4e\xd5\xa5\x21\xc6\x2f\x09\xea\xca\x8d\x01\x89\xf3\xb3\x94\x14\x3f\x29\xc4\x21\xcb\x5c\x8d\x07\xbd\x75\x1b\xaf\x4c\xbe\x3b\xf4\xbe\x17\x01\xdf\x4b\x22\x07\xdf\xb2\x90\x4d\x84\xf4\xdb\xda\x51\xcb\xa5\x76\xd5\xa5\xbb\x16\xef\xe6\x98\xed\xd6\x08"}, +{{0xf7,0x8d,0xb1,0x4d,0x6d,0x1a,0x64,0x3d,0xd7,0x73,0x5b,0xaf,0x26,0x35,0x32,0x12,0x44,0xe7,0xec,0x8c,0xa7,0x2c,0x5c,0x38,0xc9,0x8c,0x80,0x9d,0xb9,0xcb,0x5a,0x55,},{0x54,0x14,0xf7,0x5f,0x52,0xf3,0x86,0x4a,0xfb,0x0c,0x79,0xc2,0xc5,0xc1,0xd0,0x6b,0x4b,0xce,0x40,0x0f,0xbd,0xdf,0x17,0xfe,0x9c,0xfb,0x2a,0x8b,0xac,0x47,0xa0,0xdd,},{0xd7,0xcb,0xd4,0x18,0x1f,0x67,0x71,0x20,0x07,0xb7,0xf0,0xe1,0x84,0x52,0xe0,0xa0,0x24,0x46,0x4d,0x9d,0xc9,0xb5,0xff,0x9c,0xf6,0x69,0xd1,0xb9,0x11,0x69,0xd7,0x57,0x32,0x62,0xf8,0x33,0x36,0xb9,0x7c,0x86,0x1b,0xfa,0xb3,0xfc,0xf6,0x69,0x22,0x3c,0xe8,0xca,0xf3,0x19,0xf2,0x1d,0x23,0xf1,0xfa,0x33,0x1a,0x2d,0x89,0xb6,0xca,0x0b,},"\x05\xca\xf1\xb8\xed\xc3\xb1\x73\xfb\xc1\xed\x29\xb9\x5e\x2b\xf0\x6d\x81\x4b\xa2\x40\x7d\x4b\x31\xc7\x28\xd0\x4e\xc2\x73\xd2\x53\x94\x42\x3a\xc7\xd4\xff\xf2\xca\x36\xee\x90\x27\x30\x93\xc7\x56\xe2\xbd\x13\xc9\x6d\x4a\x3d\xc7\xf5\xbe\x17\x59\xfc\xd3\x28\xeb\x66\xc5\x88\x2b\x58\xfa\x45\x88\xe5\xb2\xa3\x71\x3a\x41\x54\xa2\x34\x0d\x0b\x06\xad\x01\x96\x01\xb0\xe0\x28\xe4\x97\xf8\x98\x25\x6b\x02\x8a\xf9\x5c\xd8\x16\x8d\xf5\xe5\x8a\x57\xcd\x1e\xbf\xc0\xa0\xc9\x1c\xed\x61\xdb\xb4\x80\xac\xa7\xdf\x8d\xca\x91\xeb\x16\xe9\x80\x07\xcd\x2c\xd1\xa2\x04\x5b\x0e\x44\x77\xd1\x2d\x5a\x40\x72\xf3\x65\x42\x65\x67\xc9\xd6\x15\x77\xf3\x48\x5c\x8f\x46\x60\x5e\x7f\x47\x5e\xf0\x4a\x39\x48\xf6\x0d\xba\x8c\x55\x08\xd1\x4b\xfd\xdb\x9b\x11\xdd\x04\x4e\xf2\xd8\x4c\x16\xb9\xa9\x03\x8d\x8e\x78\xed\xa4\x3b\x91\x29\x7d\xf3\x5f\x43\x61\xa3\x83\xb4\x1d\x49\x67\x7a\x68\x7d\x5b\x34\x4a\xd1\xab\x0f\xc7\x30\x17\xb3\xbe\xbf\x32\x30\x6f\xb3\xfd\x7b\x3d\x50\x71\xf3\xab\x5f\x6e\x49\xaa\x15\x54\x0c\xad\x65\x03\xbe\xa7\x78\x4c\xf9\x42\x18\x01\xce\x13\x85\x83\x98\x93\x36\x2a\x97\xfa\xe1\x21\x30\x0d\x67\x83\xaf\x0f"}, +{{0x7d,0xfa,0x32,0x8e,0x90,0xa1,0xb8,0x49,0xc2,0x19,0xe3,0xda,0x83,0x2d,0xf9,0xed,0x77,0x44,0x82,0x34,0xf0,0xd8,0x9e,0xa5,0xd1,0x7a,0x3d,0x64,0xe7,0x88,0x3d,0xaf,},{0xe3,0x0c,0xe6,0xfd,0x5f,0x58,0x00,0x38,0x9a,0x70,0xcd,0x11,0x73,0x64,0xf5,0x99,0x45,0xaf,0xb1,0x80,0xf2,0x29,0x92,0x73,0x60,0xb0,0x6b,0x48,0x35,0xf8,0xdc,0x91,},{0x1c,0x61,0xd5,0x3b,0x87,0x2f,0x8c,0xde,0x59,0x86,0x09,0x68,0x2c,0x79,0xf6,0xc5,0xdf,0x00,0x7c,0x51,0x3a,0x71,0xcf,0xb3,0xa0,0x6d,0xcb,0x82,0xd8,0x5c,0x4b,0x00,0xcc,0xc4,0x0b,0x00,0xe5,0x9f,0x59,0x53,0x93,0x08,0x8b,0x4c,0xd0,0x43,0x28,0x55,0xc6,0x7a,0x20,0x7d,0xa7,0x1f,0x87,0xe7,0x2c,0x40,0x9b,0x3e,0x50,0x27,0x95,0x07,},"\xe5\xe4\x95\xd6\x63\xf4\x72\x36\x71\x45\x32\x68\x7a\x24\x30\x8f\x94\x2c\xa9\xc3\x3e\x08\x8f\x7f\x10\x6a\x5a\x72\x35\x18\xca\xcb\xbe\xf4\xa6\x8c\x93\x9a\x69\x50\xb2\xdc\x25\x89\xf8\x2d\x35\x4e\x57\x52\x72\xd4\x2b\x13\x83\xd3\x15\xab\x8a\x20\xaa\x0c\xdc\x9d\x4d\xf6\x78\xab\x3b\x26\x61\x2b\x5d\xca\x66\xe7\x1f\x9f\x3f\xa7\xd9\xe7\x31\xdc\x48\x1e\x2b\xc7\x12\x7c\xea\x3b\x62\x03\xca\x6c\xd8\x16\x2e\x90\x88\x6a\x73\xdc\x46\xc8\x3d\xde\xfc\x4b\x9e\x2d\x53\xd2\x9d\xd3\x87\xc6\x24\xe0\x8b\xd8\xd5\x3b\xe9\x28\xa4\x0a\x9a\xa8\xae\x8b\x1c\x8d\x0f\xb6\xa7\xbd\x6d\xce\x5f\x62\x31\x5b\x7a\x21\x81\xf6\x27\xf2\x56\xbb\xe7\xe2\xa9\x5b\xf4\x64\xe6\x13\x22\x04\xc1\x74\x20\x96\x29\x84\x02\x35\xb2\xc3\x99\x13\x30\x1a\x4b\x40\x32\x5d\x11\x8d\x38\x4b\xc7\xac\x02\x8c\xd4\xf1\x27\x02\xe1\x61\x19\x1b\x14\x9e\x42\x09\x05\x8a\x55\x12\x2b\xbb\x8b\x22\xb2\x46\x83\xba\x4f\x8e\x2e\x6c\xcf\xc0\x8d\xc8\xc8\xb1\xbc\xfb\x6d\x60\xbd\x8f\x06\x21\x96\x93\x3d\xf3\x19\xab\x16\x90\x6d\x08\x57\x30\xeb\xa1\x72\x0d\x4b\x02\xc6\x7d\xaf\x38\xcc\xe6\xab\xa3\x8e\x25\xd6\x8e\xf9\x5b\x2f\x52\x19\x13\xa1\xd7\x7d\x5e\xb6\x50"}, +{{0x6c,0xe1,0x3d,0x3c,0x2e,0xc7,0x1f,0xed,0x83,0x13,0x1a,0x69,0xd5,0xd0,0x30,0x31,0x4a,0xb4,0x9e,0x65,0x65,0xef,0x68,0x16,0x3f,0xff,0x09,0xac,0x5d,0x9b,0x47,0xe7,},{0x9c,0x7b,0x11,0x18,0xfa,0xb9,0x1e,0x0e,0x7b,0x19,0x2a,0x23,0xd9,0x5f,0xb8,0x77,0xcb,0x79,0x36,0xcc,0x6c,0x8a,0x33,0x05,0x92,0xf4,0x8e,0x67,0x84,0xed,0xc2,0x92,},{0x60,0x8b,0x2b,0xf6,0xf6,0xda,0x05,0xc2,0xac,0x5b,0xbf,0xd7,0x95,0xa2,0xac,0x32,0xc7,0x9c,0x74,0x15,0x3f,0x94,0x31,0xde,0xa5,0x97,0x68,0xff,0x4c,0x22,0x5e,0x3b,0x69,0x3b,0x64,0x5a,0x50,0x67,0x66,0xb8,0x60,0x85,0x0e,0xe9,0x7e,0xa4,0x30,0x32,0xb0,0x5b,0x69,0xe5,0x67,0x67,0xe8,0xeb,0x9d,0x19,0x18,0xdf,0x9a,0xfb,0xa8,0x05,},"\x10\xbb\xc3\x11\xeb\x2a\x76\x5e\x01\x67\xff\x37\x61\x8f\xf7\x0e\x13\xf0\x2d\x7b\x06\x17\xae\x4a\xc0\x6b\xef\xbb\xe1\x49\xc9\x72\xa9\x94\xf6\x80\xca\x4d\xc9\xa9\x2e\xc7\xef\xa5\x39\x97\xfa\xd3\x56\xb9\xff\x4e\xbd\xee\x62\x95\x41\xd1\xf4\xde\xa6\x2e\xd0\xd2\x49\x4f\x9c\xcf\xdf\x07\xa9\x31\x04\x91\xf6\x1c\x4b\x3e\x27\x00\xb4\xa3\xc6\x68\xd6\x78\x32\x9a\x38\xc2\xef\xf9\xd8\xcb\xa4\x31\xfb\x95\x9e\x7f\x76\x55\xbd\x0f\xbd\x77\xd5\x3b\xbb\xc2\xeb\x8d\xc5\x1d\xd7\x18\xed\x98\x72\x8a\x18\x16\x86\xbe\x12\x2b\x84\x4d\x3d\xa3\x31\xe3\x29\xd3\x95\x9b\x59\x23\xf7\x73\x43\x25\xa0\x21\x02\x6e\x27\x54\xe1\x7a\x15\x10\x8b\xe8\x01\x46\x5a\xd9\x58\xdb\xcf\x21\xdf\x89\x0c\xfe\x5d\x5b\x88\x3c\xa4\x3c\x61\xce\xdc\xcb\xdb\x58\xb8\x49\xea\x75\x37\x4f\x1e\x91\x8e\x80\x3e\x57\x7a\x5d\xc7\xa1\xc1\x79\x36\xec\xcf\xcd\x34\x81\xbd\x2b\x1e\xb0\x75\xb8\x32\x37\xca\x6f\x3c\x07\xc1\x9e\x9a\xf9\x73\x12\x67\xbe\x82\xd4\x89\x8e\xee\x96\xeb\xc9\x00\xd4\x8b\x05\x9d\x51\xb0\xdd\x41\x5b\x1c\x89\x06\x60\xa8\x8d\x25\xf5\xc5\xf3\x5d\x8e\x45\xe5\x23\xe0\xce\x33\x36\x92\x3a\xb4\x36\x70\xe3\x5c\x50\x57\xd5\x6c\x75\x88\x76"}, +{{0xd4,0x5e,0xe6,0x9a,0x5f,0x1a,0x7c,0xfd,0xd0,0x34,0x3f,0x87,0x70,0xd1,0xc6,0xbc,0x02,0x6f,0x06,0x7a,0x70,0xdb,0xe8,0x39,0xa8,0x6f,0x2a,0xa0,0x68,0xc3,0x3f,0x81,},{0xfc,0x8d,0x9f,0xb0,0xe4,0xf3,0x47,0x93,0x09,0x07,0x55,0xe0,0x32,0x80,0x96,0xe0,0x1e,0x28,0x1e,0xa3,0x51,0xb8,0xd9,0x5c,0xd9,0x11,0x6e,0x13,0x1a,0x5c,0xa5,0x4e,},{0x15,0x6c,0x51,0xc5,0xf9,0x15,0xd8,0x9b,0x8d,0x14,0x00,0x35,0x0f,0x8f,0x21,0x7a,0x5c,0x02,0xe2,0x62,0x9e,0xde,0x9f,0x4a,0x30,0xb6,0xe7,0x1d,0x1e,0xa7,0xa9,0x53,0xcc,0x6d,0xb3,0x1b,0xa5,0xc7,0x78,0xc2,0x69,0x92,0x0b,0x64,0x9f,0xb4,0x22,0x1c,0x6d,0x38,0xcf,0x2c,0xea,0x2a,0x7d,0xe3,0xad,0x42,0x3e,0x04,0xfa,0xaa,0x06,0x07,},"\xeb\x5e\xd8\xab\x79\xcb\xfe\x61\xc2\x59\x81\xb9\xd1\xd6\xb7\x0f\x10\xb6\x01\x94\xb4\x16\x1f\xe1\x7d\x11\xaf\xf1\x76\x79\x94\xaa\x08\x13\xe9\xec\xe2\xf4\xc5\xd5\x31\xb9\x9e\x8a\xdf\x18\x88\xc3\x0a\x63\x89\x3e\xb4\x51\xaa\xf5\x5a\xcd\x5a\x52\xad\x8c\x40\x1f\xaa\x88\xd6\xea\xcf\x3e\x49\x47\x05\x66\x11\x4f\xd0\xc6\xa2\x74\xe9\x54\x48\x46\xb0\xae\x9b\xfa\x12\x4d\x79\x51\xeb\x26\x71\x5e\x19\x25\x3f\xf7\xed\xc8\xa7\x09\x65\x77\x6f\x23\xce\x46\x03\x1e\x03\x4a\x20\x07\x23\xba\x3d\x11\xe1\x1d\x35\x3d\x7e\x7c\xd8\x4a\xed\xe2\x67\xff\x64\xbe\xd4\x18\xcb\x9f\x28\xc6\x1c\xd0\xf6\x3b\x6c\xe2\xec\xae\x14\xb2\x0b\xc6\xbd\xae\xd8\xc4\x28\xba\xd1\x8b\xe4\xb7\xd6\x63\x38\x36\x4a\xcd\x80\x42\xa8\x25\x6f\x25\x8a\x69\x96\x9b\x8d\x3c\xa2\xea\xb3\xae\xa3\x70\x6e\x5f\x21\xc3\xb1\xef\xcc\x25\x4a\x82\x4b\xb4\xe7\xea\x7a\xba\x88\x27\xc8\xeb\x82\x78\x6c\x66\x5a\xa9\x73\x82\x19\x31\xff\x99\x0a\x63\xfd\x34\xa7\x4a\x6d\x8c\x22\xa8\x82\xb0\xb9\x35\x15\x2c\xcb\x36\xfc\xc7\x6f\x4e\xca\x65\xd6\x7c\x86\x80\x94\x2f\x75\xdf\xad\x07\x34\x39\xc0\x91\x60\x65\xe8\x38\x77\xf7\xba\x20\x93\x03\xf3\x35\x48\xd9\xe4\x0d\x4a\x6b"}, +{{0x8a,0x76,0xea,0xab,0x3a,0x21,0xec,0x5a,0x97,0x5c,0x8b,0x9e,0x19,0x7a,0x98,0x9e,0x8e,0x03,0x08,0x99,0xeb,0x45,0xd7,0x89,0x68,0xd0,0xfb,0x69,0x7b,0x92,0xe4,0x6d,},{0x2d,0x9c,0x81,0x3d,0x2d,0x81,0xe2,0x73,0x0b,0x0d,0x17,0xd8,0x51,0x2b,0xb8,0xb5,0xd3,0x3f,0x43,0x6c,0xab,0xaa,0x13,0xe1,0x41,0xca,0x1c,0xb7,0x85,0x01,0x43,0x44,},{0xfc,0xee,0xcc,0xa4,0xb0,0x14,0xfe,0xcd,0x90,0xb9,0x21,0xb0,0xfa,0x3b,0x15,0xae,0xaa,0x4e,0x62,0xca,0xa1,0xfb,0x22,0x72,0x9c,0x70,0x26,0x92,0x32,0xc3,0x3c,0xef,0x0d,0x0a,0xee,0xa6,0x64,0x32,0xc1,0x28,0xaf,0xb9,0xa3,0x64,0x6b,0xc7,0xf0,0x3a,0x12,0x77,0x4d,0xa8,0x75,0x83,0x98,0xc2,0xa0,0xdc,0xce,0x0b,0xbb,0xf6,0x74,0x0a,},"\xc6\xc7\x8f\x2e\x20\x80\x46\x1a\xed\x9f\x12\xb4\xf7\x7c\x98\x9b\x19\x71\x67\x80\xfa\xb6\x0e\x6e\xcb\x97\x93\xb4\xbc\x7e\xd6\x9e\x5f\x70\xfa\x6b\xdb\xa1\x6e\x9b\xd3\x19\x49\x69\xee\xa6\x66\x5a\xbf\xd6\x30\xde\xee\xfa\x3d\x71\x7b\x6d\x25\x4d\xd2\x4b\xc9\x7d\xde\x21\xf0\xf2\x9f\x9e\xd3\x4b\x8b\xd7\xa0\x13\x38\x0f\x4f\x82\xc9\x84\xfd\xbd\x95\xaf\x98\x05\xb7\x44\xbc\xd9\x52\xc5\xa7\x1f\xbb\x57\xd1\x1f\x41\x1c\x18\xcc\x30\xbc\x35\x94\xf7\xad\x82\x28\xcb\x60\x99\x39\x4a\x1b\x6b\x0a\x81\x85\x81\xbd\xf9\x3c\xce\x58\xf3\xa4\xa2\x3e\x55\xdb\x3e\x69\xca\x9d\x60\xcf\xb3\xa9\x07\xfb\x68\x32\x9e\x2f\xfb\x6c\x65\xf1\xe8\x28\xd2\x81\x27\x10\x9c\x9e\x9f\xb7\x01\x60\xf2\xef\x82\xa2\xee\x9f\x9b\xd1\x70\xc5\x1e\x13\xfd\x3f\xc1\x86\x6b\x22\xc7\x9f\xe6\xd5\x10\x12\x17\x97\x9d\xbe\x27\x24\xdc\xad\x8a\x9b\xc6\x9a\xcc\x42\xc1\x12\xdc\x69\x7b\xd2\x71\xee\xa5\x50\xe9\xe5\x04\x06\xbf\xd2\x82\x45\xb8\x3b\x8f\x01\x2d\x34\xdb\x6d\xbd\xd5\x5a\xe6\xe5\x75\x74\x5c\x15\x3d\x6e\x75\x34\x90\x10\x27\xea\xdc\x2f\xcc\x33\xa5\x28\x7d\xdb\xca\x6d\x3a\xea\xb8\x97\x22\x94\xdc\x6c\x71\x2b\x99\x42\x54\x72\x77\x34\x0e\x7a\xd1\x9e"}, +{{0x18,0xa8,0xf9,0x36,0x48,0xcd,0xcf,0x47,0x13,0x36,0x30,0xaf,0x1e,0x11,0xc0,0xce,0xea,0x3d,0xe0,0x73,0x27,0x31,0x4c,0x96,0x58,0x0d,0xf7,0x75,0x59,0x7d,0x7a,0x9c,},{0x29,0x12,0xf4,0x1a,0xb4,0xc8,0x7e,0x39,0x37,0xa0,0x33,0x31,0x80,0x2c,0xba,0x87,0x71,0x6b,0x4e,0xea,0x14,0xb9,0xfb,0xa6,0xf5,0x46,0xd0,0xac,0x2c,0x09,0x73,0xdf,},{0x3b,0x77,0x39,0x4c,0xd6,0x9f,0x8b,0x45,0xd0,0x0c,0xfe,0x3a,0x79,0xa7,0x90,0x06,0x28,0xa5,0x65,0x18,0xb3,0x79,0xed,0x8a,0x11,0x58,0x1f,0xc3,0xa3,0x76,0xe5,0xd6,0x68,0x07,0xdf,0x11,0xe7,0x09,0x04,0xf6,0x96,0xc7,0x41,0xd2,0x1d,0x13,0x93,0x10,0xfa,0x1b,0x89,0xa9,0x3b,0xdc,0x4d,0x2c,0x39,0x97,0x99,0x1f,0x52,0x20,0xee,0x00,},"\x59\x20\x93\xac\x7c\xd6\x71\xd6\x07\x0b\x00\x27\xed\xac\x1f\xb0\x15\xcc\x20\x5d\x78\xbb\x60\x3f\x37\x8e\xb9\xf8\xaa\x38\x8c\xa8\x30\xdb\x3c\xb2\x34\x20\xc7\xe8\x52\xdb\x0b\x55\x24\x1e\xb8\x8a\x02\xcc\x62\x7a\xa9\x41\x43\xbe\x43\x9a\xab\x4b\xf2\x63\x47\x57\x47\x04\x06\xe8\x42\xf2\x0e\xb1\x0f\x07\x00\xe3\xc2\xda\x36\x4f\x58\x8a\x80\x00\xf2\x38\x50\xc1\x2c\xe9\x76\xf3\x26\xd2\xdf\x1b\xac\x13\xe9\x50\x20\xb4\x12\xb1\x75\xbf\x74\xbd\x7e\xbb\xac\xf3\xae\x55\xc0\xda\xeb\xb5\xc0\x10\xbf\x80\x4f\xee\xe1\xd7\xd4\x9f\xae\x05\x0b\xea\x55\x99\x6f\x53\xcf\xe1\xf1\x5a\x0c\xf2\x07\x27\xdb\x4e\xe3\x11\xc2\x60\xba\xd9\x68\x2d\x7b\x96\x5e\x27\xa9\x49\x1f\x47\x1d\x4a\x47\x3a\xff\x64\x6c\x7d\x42\x4d\x5a\x0b\xdc\xbb\x8a\x02\x33\xf4\xb3\x06\x0d\xd0\x4c\x98\xec\x98\xdf\xd0\x5e\xc7\x24\x78\x84\xe2\xd8\xe1\x52\xd4\xae\x52\xb3\xd5\x86\x5d\x9e\xfd\x67\x06\xa6\x0e\x08\x8e\x1e\x7c\x9f\x62\x45\x10\xab\xc7\xa2\x04\x5a\x2c\x7a\x75\x88\xe2\x53\x5e\x73\x19\x1d\xd5\xcf\x05\x42\x15\x63\xf5\x56\xa1\x3e\x82\x36\x67\x03\x43\xcd\x5b\xa4\xd4\x66\xe2\x45\xc4\xee\x3b\x5a\x41\xe7\x0c\x9a\x0f\x5e\x6e\xa2\xc5\x59\xeb\xe6\x1b\xa8\x1e"}, +{{0x20,0x6c,0xd2,0xb8,0x11,0x4a,0xae,0x18,0x8d,0x81,0x86,0x2c,0xce,0xc4,0xcb,0x92,0xc4,0xef,0x5f,0xc7,0x8c,0x24,0x43,0x5a,0x19,0xf9,0xed,0x9b,0x8a,0x22,0xf4,0x7e,},{0x97,0xa6,0x7a,0xc2,0x81,0x1f,0x52,0x94,0x56,0xdf,0x53,0x27,0x37,0xd7,0x6b,0xed,0x7e,0x38,0x7d,0xa8,0x3b,0xd5,0x54,0x59,0x37,0x2f,0xdf,0xb2,0x7f,0xfa,0xcf,0xf3,},{0x73,0xa4,0x0d,0x9d,0xa0,0x8f,0xb9,0x8e,0xa2,0x5b,0x67,0xe7,0x21,0x55,0x7a,0x1a,0x51,0x22,0x52,0x94,0xd3,0x16,0xb5,0x31,0x49,0xaf,0x89,0x5f,0xa4,0xd6,0x3c,0xb4,0xa3,0xf5,0x6f,0x68,0x85,0x66,0xef,0x6d,0xa4,0x2f,0xd2,0x94,0x1d,0xff,0xa0,0x6d,0x49,0x7a,0xa9,0x02,0x16,0x5d,0x50,0x21,0x3a,0x62,0x14,0x11,0x62,0x99,0xa9,0x0c,},"\x48\x0c\x48\x00\xf6\x8c\x79\xf5\xdf\xc0\xc3\x66\x6c\x0a\xc4\x29\xb3\x0f\xe0\xc5\xfe\x84\x87\x50\xdb\x21\x71\x38\x0b\x80\xc8\xe9\xfe\xc0\xa0\x54\xb1\x6d\x08\x67\x4c\xef\xe2\xf6\x4e\xc2\x8b\xb6\xb0\x59\x6b\x35\x23\x55\x75\xf1\x89\xbe\xe2\x59\xac\xa7\x66\xc2\x22\xac\x0a\x46\xcf\x2a\xf7\x57\x74\xda\x4e\x34\xa0\xb5\x4f\xc2\xac\x49\xec\x8b\xed\xf4\x88\x7c\xd9\xb7\xbe\x4f\xdb\x7f\x68\x69\x02\xdd\xfa\xb0\x46\x27\xe2\x6e\xa2\xdc\x3d\x97\xd6\x2a\x4b\x15\x46\x18\x02\x18\xed\x8f\xa1\x13\x33\x48\x19\xb5\x27\x5c\xc5\x4a\xfd\xee\x44\x30\x90\x08\x59\x65\x07\x97\x16\x75\xe6\xd8\xb8\xa8\xed\xec\x47\x18\xf2\xd4\xbd\x73\x52\x13\xcb\xbd\x18\x79\x1f\xaa\x80\x54\x17\x49\x07\xa7\xac\x17\xd7\x14\x3a\x47\x57\xe4\x93\xbe\xee\xc4\x84\x9d\x0b\x83\x6f\x18\xbb\x2b\x3c\x90\x16\xf2\x5a\xf4\x7f\xb9\x61\x99\x25\x17\x20\x54\x9f\x15\xd1\x49\x50\x3d\x41\x09\x5e\x25\xf2\x62\x09\xda\xac\x39\x15\x44\x85\xc3\xde\xd7\xcb\x1a\x8c\x3e\x83\xa5\x2f\x5a\x06\xec\x09\xcf\x83\xdf\x00\x72\x6b\x79\x68\xf6\x4c\x0c\xba\xe2\x99\x51\x2f\xb4\x38\x56\x0f\x04\xb3\xb6\x44\x34\x6f\x93\x8a\xc8\xe9\x04\x86\x61\x4c\xd8\x44\xb5\x4e\xae\x07\x8b\xf6\x78\xb3"}, +{{0x59,0xb1,0x44,0xa7,0x08,0xab,0xec,0x97,0x27,0x29,0xa0,0x4a,0x6c,0x13,0xf0,0xea,0x02,0x0b,0x4e,0xd4,0xa4,0x82,0x98,0x02,0x3a,0x56,0x89,0x58,0xc2,0x12,0x15,0xec,},{0xc4,0xf4,0x72,0x00,0x92,0xed,0x61,0x79,0xa0,0x82,0xae,0x4d,0x61,0x45,0xdf,0x37,0x71,0x78,0x6e,0xfc,0xa9,0xbd,0x9b,0xb7,0x9c,0x9f,0x66,0x67,0xd2,0xcb,0x56,0xb3,},{0x1a,0x80,0x85,0x0f,0xcb,0xd6,0xe6,0x43,0xc6,0xba,0x8e,0xb6,0x84,0xdb,0xef,0x7d,0xf0,0x15,0x15,0x92,0x28,0xda,0xed,0xcf,0x06,0x04,0x70,0x91,0x86,0x05,0x4d,0xb1,0x85,0xaa,0x7b,0xaa,0xcb,0x09,0xd6,0xca,0xad,0x01,0x63,0x8e,0xff,0x8e,0x46,0x87,0x35,0xa6,0x01,0x24,0xde,0x0c,0x53,0x76,0xe9,0x43,0x40,0xe5,0x41,0xa9,0x80,0x07,},"\x38\x57\xbd\x26\x0b\x8a\xad\x9d\x07\x3f\x06\x76\x5d\x37\xfe\x89\x3a\x3f\x53\xe2\x3d\xe8\x66\xdd\xac\x33\x49\x5a\x39\xad\x33\xee\x9e\x9d\x5c\x22\x50\x2b\xc1\xc4\xb5\x47\x0d\x0e\x3f\x3a\x58\x52\x23\xfe\x4c\xb9\x3c\xc4\xad\x2b\x5b\xa6\xd7\x88\x26\xa5\x3f\xc0\x25\x3d\xc5\x80\xa2\x01\x8c\xc9\xff\x1c\xfe\xdb\xd3\xac\x0b\x53\x29\x2d\xee\xfb\xc1\x4e\x58\x9a\xcf\x49\x6c\xb5\xf7\x67\x01\x30\xfd\xbb\x6c\xf3\x8d\x20\x89\x53\xc0\x15\xa0\x47\x46\x75\xb7\x24\xbd\x10\x9f\x7c\xb8\x9c\x33\x01\x67\x51\xfe\x7a\xa7\x85\xd0\x99\xd0\x9a\xb2\x0d\xd5\x25\x8c\xd7\x64\xac\x8d\xaf\x34\x3c\xe4\x79\x0e\xad\x08\x63\xaf\x43\x12\x1a\xa5\x27\xa3\x7a\x11\x62\x8f\x47\x86\x96\x68\xf8\xea\xc0\x0d\x80\xb6\xbf\x99\x06\x66\x3d\x7a\x28\x99\xc1\xcb\x67\x8c\xd7\xb3\xeb\x3b\xc8\x02\x26\xb8\xb1\x3b\x6e\x46\x87\x7f\x38\xf0\x7c\x3d\x9c\x86\xd3\x36\x8b\xaa\xc4\xa6\xf6\xb9\x3c\xce\xbc\xec\x98\x11\x47\x4b\x6a\x6a\x4d\xa5\xc3\xa5\x96\x65\x71\xee\xd0\x5e\xdc\xc0\xe3\xfe\x7c\xd1\x59\x15\xc9\x1f\x44\xee\xe8\xc1\x49\xae\x45\x1f\x37\x55\x18\xa7\x9f\xb6\x00\xa9\x71\xa3\x9b\x94\x33\xdf\xa1\x9f\x91\x93\x1b\x19\x32\x27\x57\x47\xc2\x62\xee\xdc\xbd\x27\xf1"}, +{{0x8d,0x16,0x21,0xee,0xab,0x83,0x27,0x0d,0xe8,0x57,0x33,0x5c,0x66,0x5b,0xbf,0x57,0x26,0xe3,0x72,0x22,0x25,0xfd,0x01,0x6e,0x23,0xbf,0x90,0xab,0x47,0xae,0xec,0x3d,},{0xbe,0xcd,0xbc,0x02,0x4d,0xae,0x6a,0x94,0xed,0x4e,0x29,0xc8,0x0f,0x2a,0xff,0x79,0x6a,0xed,0x8f,0xeb,0x2c,0x1b,0x37,0x90,0xa8,0xc7,0x2d,0x7b,0x04,0x8a,0x2c,0x61,},{0xe0,0x8d,0x6c,0xaa,0x5f,0x39,0x32,0x7d,0x6e,0x66,0x52,0xed,0x74,0xdd,0x1a,0x37,0x84,0x4b,0x97,0x9f,0x5c,0xce,0x74,0x7a,0x60,0x6f,0x56,0x79,0xf4,0x89,0x8b,0xbb,0x76,0x43,0xdf,0x7e,0x93,0x1b,0x54,0xa2,0xb4,0x0e,0xbd,0xef,0xe8,0x30,0x03,0xf6,0x1c,0xa0,0xf1,0x11,0x12,0xf0,0x23,0xc6,0xa3,0xe8,0xcc,0x18,0xca,0xfe,0x5f,0x0d,},"\x97\xfa\xcd\xdc\x82\xcc\xcc\xcf\x78\x8c\x31\xb3\x30\x5e\x93\xeb\xa9\x56\xf8\x96\x13\xe6\xe5\x35\x42\xb0\x43\x26\x7f\xee\x54\x4c\x2b\x0a\x8a\xe8\x88\x6a\x31\xb9\xd3\x21\xa6\x3c\x27\x62\x3b\xae\xfe\xa8\x40\xb2\xa8\xaf\x5b\x23\x30\x19\x3f\xfb\x5b\xaf\x87\x3c\x33\x55\x28\xaf\xea\xe2\x16\x01\x63\xc8\x51\xc5\xa2\xe5\x81\x54\xa1\xb0\x56\x9c\x2d\x13\x66\xc0\x71\x04\x37\x62\x3b\x0e\x08\xc6\x86\xe5\x4f\xc2\x79\xed\x4c\x45\xf3\xe8\x56\x86\x83\x75\xf7\x82\x24\xc7\x77\xb1\x3d\x75\xde\x10\xd7\x91\x73\x55\x24\x25\xd1\x5a\x56\x19\x04\x15\x5f\x21\x17\xb2\xf1\x47\x13\xeb\x0b\x04\x64\x8a\x3b\xde\xb3\x30\x21\x67\xd1\x97\x3e\x78\x8a\x06\xcb\x00\xd4\x8c\xcb\x26\x9f\xa7\x1a\xf8\xba\x68\xea\xe5\x5d\xbb\xfd\x95\x94\xd5\xc2\xb4\xdc\x13\xae\x03\x21\x71\x85\x61\xac\xdf\x67\xdc\x8c\xfc\xc2\x5b\xc4\x6b\xb6\x6e\x09\x6a\x19\x41\xd9\x33\x52\x07\xd3\xf7\xd1\x1e\x89\x04\x90\x4f\xab\xe3\xa5\x0a\x38\x83\xe7\x07\x80\x47\xdf\x25\x2f\x38\xb6\x7c\xd2\x8a\x6a\xc4\x5c\x7d\x7a\x1d\x2a\x1d\xe8\xd4\x57\x47\xcf\x09\x30\x1e\x01\xcd\xaf\xd0\xcd\x99\xa6\xe9\x1b\x70\x4d\x50\x9f\xce\x69\x2f\xbd\xef\x2f\x71\xa5\xce\x0b\x35\xbc\x15\xc6\x5f\x87\x68\x24"}, +{{0xf2,0x73,0x5d,0x50,0xee,0x3a,0x9a,0x65,0xb5,0x8c,0x8a,0xcf,0x55,0x16,0x63,0xe9,0x88,0x09,0xec,0x40,0x6f,0x73,0xe3,0xe7,0xf4,0xe7,0x3b,0xc4,0xea,0x92,0x38,0x74,},{0xdf,0x48,0xa5,0xb9,0x4a,0x07,0xaf,0x3c,0x2c,0x99,0xb8,0x38,0x87,0x62,0x24,0x32,0x33,0xc8,0x50,0xdc,0x17,0x53,0x17,0xd6,0x02,0x63,0x8e,0x5b,0x86,0xab,0x49,0xed,},{0x69,0x42,0xa7,0x69,0x64,0x17,0xef,0xaa,0x59,0x1b,0x95,0xe1,0x1f,0x02,0xd7,0x63,0xbe,0xf5,0x27,0x9b,0x93,0x2a,0x8e,0x2a,0x7c,0xbb,0x9f,0x58,0x36,0x95,0xc1,0x4c,0xe5,0xcc,0x55,0x6b,0xec,0x66,0x79,0x9b,0x33,0xcb,0x59,0x2d,0xa4,0xdf,0x27,0x35,0xf9,0xee,0xf2,0xc3,0xce,0xca,0x43,0x62,0x16,0x4b,0x6c,0xc9,0x3d,0xa4,0xe1,0x05,},"\xae\x31\xe9\x4e\x71\x97\xe4\xe4\xd0\x23\x93\x48\x02\x5e\xd6\x68\x1e\x51\x3c\xe1\xa6\xe0\xaa\x0e\x5b\x97\x93\x73\x91\x21\x50\xef\x11\x3e\x50\xef\x05\x69\xc4\x83\xf7\x56\x8c\x4b\xbc\x47\x03\xc5\xda\xca\xa8\x0a\x0d\xe4\xe7\x38\x38\x3f\xa1\xf1\x0d\x6d\x40\x71\xa3\x1b\x99\xe6\x48\x51\x43\x97\x23\x16\xc8\x65\x22\xe3\x7c\x68\x87\xa1\xc3\x07\xb2\x9b\x0d\xd6\xf9\xf1\xb4\x38\x31\x0a\xf9\xd8\xd7\x34\x6f\xb4\x1f\x9b\x2d\xd2\xe8\x0b\x14\xc4\x5e\xb8\x7d\x4e\xd4\x8e\x37\xa5\x26\x0b\x52\x25\x7b\x3e\x99\x78\x7a\x13\xc5\x53\x92\xba\x93\x0c\x08\xe0\x24\x0e\x96\x0d\xef\x0c\x29\xb8\x55\x07\x45\xcf\x14\x9d\xee\x53\xa5\xd1\x74\xec\x06\x5d\x2d\x66\x77\xde\xe1\xfc\x42\x05\x70\x62\xc3\x4e\x27\xea\x5d\xbc\xdb\x86\x1b\x9f\x67\x0c\x60\x32\xc7\x84\x6c\xec\x8e\x87\xa7\xc9\x52\x0e\x27\x96\x7b\x01\x86\xee\x71\xb7\x7e\xd6\xd0\x29\xbb\xdd\x70\x94\x9c\xec\x4a\x70\x93\x29\xfa\x37\xfe\xe0\x02\x49\x0c\xc1\xbc\x4c\x2d\xf6\xf7\x63\xf9\x85\x8f\x33\xd7\x50\xc5\xb5\x05\xa6\x7e\x23\x70\x63\xc0\x48\x6f\x94\x56\xd3\xc6\x20\xd9\xac\x7c\x98\xf1\x38\x1d\xe0\xef\xfe\x41\xc1\x82\x59\x50\x4a\x15\x0d\x68\xa6\xa2\x8b\x0a\x3e\xea\x80\x3b\x85\x53\x15\xc9\xe0"}, +{{0xca,0xd9,0xd2,0x1a,0x01,0xc7,0xe1,0xd1,0x5d,0xf2,0xfb,0xd7,0x9c,0x51,0x6e,0xb8,0xc3,0x40,0x1e,0x9f,0xe2,0x84,0x67,0xcc,0x7b,0x21,0x67,0x9d,0x4e,0x33,0x1a,0x3d,},{0xa7,0xb5,0x5c,0x15,0xd6,0x79,0x0b,0x40,0x53,0x6f,0xca,0xe5,0xad,0x28,0x92,0xcd,0x66,0xb1,0x86,0x89,0xf4,0x99,0xc1,0xfd,0xee,0xa6,0x6d,0x4a,0x7d,0xf3,0x94,0x24,},{0x31,0x92,0x7d,0x01,0xdb,0x9f,0x24,0x72,0xf4,0xdf,0x6f,0x63,0xc1,0x8e,0xbd,0x83,0xc2,0xb1,0xaa,0xf8,0x8d,0x58,0x0e,0x84,0x88,0x54,0xdf,0x8c,0xba,0x63,0x95,0xd3,0xda,0x7b,0xd6,0xbb,0x9e,0xdc,0x1f,0xce,0x1c,0x7d,0x7e,0x13,0x60,0x55,0x8f,0xcd,0xdf,0xa9,0x39,0x15,0xbe,0x07,0x6e,0xfb,0x8e,0xa2,0xdc,0x5e,0xa7,0xb2,0x0d,0x0a,},"\x70\x70\x2b\xf1\x9c\x91\x9f\x98\x36\xde\xfd\x7b\x84\x6f\xd9\x99\x2d\x8b\x7e\xb2\xe1\x06\xae\xb7\x1e\x60\xa3\x1b\x4e\xa2\x5a\x41\xb2\x12\xdc\x7d\xe7\xc9\x1c\xbd\x61\x3d\x58\xd0\x59\x5d\xb8\x33\xcf\xe7\xe5\x05\x84\xf2\x55\x69\x60\x2c\x77\x44\xfa\x67\x5d\x15\x6d\x0f\x63\xcd\x2b\x7c\x08\x9c\x8a\x00\x68\x6a\x43\x71\x69\x82\x6a\x12\xdc\x48\x5b\x38\xc0\x68\xa8\x00\x71\x42\xe5\x16\x37\x47\x01\x1a\x07\xa4\x15\x68\x36\x22\xab\x1e\x23\xce\x57\x7c\x73\x2b\xa1\x4f\x40\x1f\xbc\x30\x43\xe0\x69\x3a\x92\x05\xc1\x9a\x92\x29\x8a\x3d\x9b\x08\xfb\x7a\xfa\xfa\xe0\xa9\xf0\x16\xbc\x75\x0e\xe6\x31\xa5\xf5\xda\x5d\xb6\xf9\xba\x26\x92\xc7\x4c\xaa\xae\xb4\xd0\x97\xe9\x0e\x3c\x02\xd2\xe3\xa7\xfb\x3a\xa0\x00\x04\x0b\x7c\x17\xb7\x45\x64\xe6\x46\xbe\xa1\x6b\xad\x61\x1e\xbc\x08\x59\xa3\x82\x88\x04\xab\x4f\x5c\xfb\xa4\x17\xd2\x54\x51\x5c\xa3\x62\x0a\x3a\xd6\x83\xc4\x6c\xa6\x26\x7b\xb4\x95\x39\xbb\x30\xe3\x69\x08\x7e\x67\x43\x8e\x94\x89\x56\x27\x50\xdc\xcb\xa3\xaa\x0b\x1b\x0a\x6c\x26\x70\x32\xd2\x0c\x2a\xdb\x75\xe6\x8d\xf1\x12\x3b\x52\x59\xbf\xe4\xea\xc6\xca\xdc\xa6\x77\x81\x38\xa3\x73\x18\xad\xb3\x0e\x8d\x66\x9f\x3b\xc9\x69\x2c\xc7\x4b\x68"}, +{{0xd9,0xbe,0x84,0x22,0x55,0xe9,0xa1,0x6b,0x0a,0x51,0xa8,0x67,0x42,0x18,0xce,0xe7,0xcd,0x9a,0x8b,0xdf,0x34,0x35,0x08,0x39,0x7f,0x4d,0xdb,0x05,0xf3,0xfa,0x00,0x82,},{0x79,0x31,0xbc,0x6d,0xfa,0x33,0x24,0x94,0x3a,0xab,0x18,0x3d,0x12,0x85,0x51,0x59,0x19,0x39,0x9f,0xfe,0x0b,0x71,0x06,0x77,0xf0,0x91,0x5d,0x3a,0x5b,0xe5,0x1e,0x92,},{0xc9,0x38,0x45,0x65,0x8c,0x95,0x60,0xd2,0xc0,0xe2,0x8f,0x28,0x2a,0xdb,0xd4,0x65,0x2b,0xaf,0xd3,0xbb,0x2e,0xde,0xc1,0x7c,0x94,0x87,0x8f,0x7b,0x94,0xd3,0xc7,0x7a,0xfe,0xc9,0x06,0xed,0x29,0x2a,0x8d,0xfb,0xf5,0xf8,0xe7,0xc1,0x18,0xe8,0xf2,0xca,0x33,0xdd,0xa7,0x90,0x9d,0x9b,0x69,0x5b,0x8f,0xf5,0xa1,0xc0,0xe9,0x7a,0xc8,0x07,},"\xac\x6c\x55\xb1\x34\x66\x3e\x41\xf0\x2a\x6d\xcb\x85\x49\xea\xa1\xc0\x13\xf5\x96\x58\xd8\x1d\x81\x2f\x95\xb7\x40\x09\x51\x37\x23\x67\x19\x45\xe1\x32\x4f\x90\xf8\xa3\xf9\x71\x36\x91\x81\xb5\x87\xba\xb4\x56\x65\xf7\x88\xd6\x63\xab\x78\x14\x0c\x5a\x22\xc1\xc1\x8d\x4a\xfe\xdc\x74\x48\xa7\x48\xaf\xe5\xbf\x23\x87\x00\x3c\x1d\x65\xab\x18\x48\x2e\xf9\x89\x22\xb4\x70\xda\x80\xad\x14\xc9\x44\x95\x1c\xe4\xae\xd3\x73\x90\xcc\xe7\x9a\x8e\x01\xb2\x4c\x7d\xfc\x11\x41\xc0\xec\xa2\xc7\xf7\x73\xed\x4b\x11\x80\x6a\x34\x61\x55\x13\x48\x6e\x4e\xe1\x1a\xf0\x80\x78\xa1\xb4\x05\x4c\xf9\x88\x02\x98\x60\x8d\xd9\xb3\xfa\xa1\xa2\x42\xa4\x52\xfe\x51\x16\x04\xb3\x10\x2c\x31\x3d\x14\xcc\x27\xc6\xf0\xf8\x47\x1d\x94\x55\x53\x17\xea\xa2\x64\xcd\xf5\x2c\x69\xe1\x8f\x46\x1e\x47\x90\x3d\x21\x29\x87\x16\xb1\x72\xee\x9c\xb1\x78\xf0\x8f\xf2\xd3\xc9\xc1\x62\x12\x1c\x2e\xd2\x1d\x87\x34\xb2\xf0\x63\x0d\x39\x91\x46\xcb\xf7\x6e\x02\x8a\x14\x3f\x2b\xf7\xbb\x50\xaf\x0f\x57\xb9\xba\x80\x21\xd2\x64\xb0\x0c\x66\x62\xf8\x4c\x86\xcb\x6d\x59\x52\xb3\xd2\x41\xf7\xdc\x3e\x70\x0c\x96\x61\x6c\xbc\xfb\x0d\x0e\x75\x3f\xfd\x5d\x21\xee\x32\x0e\x65\xe9\x7e\x25\xcb\x86\x09"}, +{{0xcf,0xc4,0x8c,0xc6,0xf6,0x58,0x11,0xfe,0x7d,0x7b,0xba,0x85,0xd1,0xcd,0x84,0x85,0x8f,0xd6,0xf7,0xed,0xd6,0x38,0xf4,0xf5,0x52,0x36,0x3e,0xe7,0x68,0x5f,0x69,0xca,},{0xd2,0x9c,0x10,0x69,0x4c,0x5e,0x8e,0x3f,0x34,0x47,0xed,0x78,0xd3,0x4d,0xbd,0x74,0xa2,0xb3,0x01,0x37,0x3b,0xa8,0x71,0xb5,0x85,0x0c,0x33,0x3d,0xff,0x7b,0xf8,0xd0,},{0x80,0xc5,0xd5,0x1e,0x96,0xd1,0xca,0xc8,0xef,0xd3,0x45,0x98,0x25,0xe7,0x9c,0x1e,0x9f,0x65,0xaf,0x70,0x1d,0x1d,0x29,0xe1,0xf9,0x5b,0x03,0x67,0x07,0x11,0x3b,0x77,0x98,0x4b,0x7b,0x33,0x50,0xf0,0x40,0x77,0x33,0x3c,0x95,0x7f,0x8f,0xbc,0x7d,0x9b,0x04,0x0c,0x36,0x26,0x51,0x41,0x7b,0x98,0x99,0x02,0x7c,0xd3,0x3e,0xdb,0x11,0x03,},"\x8e\x7d\xef\xb9\xd1\x6d\x03\x6b\xd6\x42\xcf\x22\x6e\x32\x77\x3e\x60\x53\x61\xc5\xec\x4b\x95\x12\x55\x78\x8d\xb0\xa0\x42\xc6\x3e\x5a\x43\x67\xd6\x15\x24\xf1\x0e\x62\x58\x99\x13\x25\xa3\x9a\xb6\xb0\x36\x12\x26\x0c\x3f\xe3\xdf\x20\xb3\x42\x02\xd3\x43\x95\xbd\x4e\xd4\x0b\xd6\x13\x73\xdf\x78\x1a\x4c\x8b\xcf\xbd\x15\x30\x10\x60\xf0\x74\x37\x73\x23\x33\xd8\xe4\x97\x36\x32\x2d\xee\x6b\x22\x43\x8e\x78\x7d\x88\x56\xb7\x0c\x26\xec\x57\xd6\xda\xde\x9c\x3c\x28\xe2\x72\x20\xc5\x67\x0e\x39\x35\x44\xed\x09\x59\x37\x29\x8d\xc3\xad\xc7\x38\x65\xf7\x77\xe9\x00\x37\xbd\xef\x83\x47\x16\x47\x6d\x78\xf4\xe6\xcb\x49\x61\xa4\xc6\x8a\x8a\x83\x63\x38\xa9\xf5\xda\x17\x9c\x4d\x5e\x93\xc3\xf7\x0d\xd3\x5e\xec\x70\x96\x53\xdd\x8d\xe3\x79\x96\xb1\x20\x56\xd4\xee\xfc\xb4\xb6\xb3\xc1\x3b\xa9\x84\xd8\x32\x27\x5c\x43\x86\xeb\xf4\xa8\xff\x7f\x07\x8b\xe3\xd4\x28\xc1\xe0\xd9\xb1\x62\x38\x1f\x06\xa5\xb7\xbb\x12\x70\x40\x03\xd9\x1f\x25\xd1\xd8\xfd\x43\x62\x6c\xe7\x0f\xff\x59\xd2\x92\x77\x68\xa7\x6b\xf7\xf9\xef\x76\xff\x95\x48\x9f\x38\xed\xcd\x1c\x9e\x9b\x8a\x8b\x0e\xf6\x6c\x32\x80\x57\x76\xd5\xae\x9f\xbd\x84\xa7\xaf\x4f\xa6\x56\x3e\xc7\x0a\xc5\x73\x3a\x44"}, +{{0x15,0xc9,0xf7,0xc4,0xd8,0x4a,0x5a,0x47,0x90,0x41,0x95,0x2e,0x6a,0x8c,0xac,0x24,0xe7,0x6f,0xd2,0xd2,0x75,0xc1,0x97,0xe6,0xb5,0x21,0x92,0x9b,0x43,0xba,0x6c,0x5d,},{0x86,0x33,0xc1,0x82,0x9d,0x29,0x09,0x1d,0xf7,0x1f,0xd5,0xc0,0xef,0x64,0x05,0x72,0xe4,0xb6,0x49,0x74,0xcd,0x09,0x7d,0xbe,0xbb,0xcd,0xde,0xba,0x04,0x16,0x47,0xc0,},{0x1e,0x36,0xbe,0xa5,0xa5,0x83,0x76,0x7e,0xbd,0x80,0x30,0x6c,0xab,0x23,0x31,0x55,0xb7,0xb4,0x28,0x14,0xb4,0x34,0x73,0xcf,0x45,0xcd,0xc5,0x03,0x9c,0x93,0x97,0x44,0xa9,0x69,0x4b,0x87,0x22,0x0d,0xaf,0x4c,0xcd,0x29,0xf2,0x5c,0xea,0x40,0x5e,0x7c,0x08,0xdb,0x2e,0xf1,0x7f,0x3f,0x03,0x4d,0xbb,0x49,0xcf,0xf6,0x02,0x83,0xe3,0x06,},"\x11\x73\x0d\xd4\x5d\xda\x80\xd8\x4d\x08\x0d\x92\xe9\xbd\xda\xee\xa6\x87\x8e\x4a\x0b\x3b\x51\x2d\x9e\xa7\x33\x80\x8e\x1c\xef\x51\xd4\x90\x48\xd6\xc7\x81\x16\xa4\xbd\xe3\xc6\x4a\xce\xaa\x52\xbe\xca\x86\xb3\x31\xab\x59\xe9\x18\x5c\x70\x28\x6a\x02\xbb\x5d\xd0\x4f\x5c\x7f\x4e\x9c\x7e\x44\x5e\x77\x45\x85\x65\xf1\x59\xc7\x83\xdf\xd4\xd9\x76\xa9\x10\xe9\x37\x78\x9d\x21\x41\xd4\x16\xed\x3a\x7f\x60\x8d\x26\x73\x7a\x86\xb2\x0b\x62\x4e\x3c\x36\xaf\x18\xd2\x5c\x7d\x59\xb8\xd7\x42\x7e\xc6\xc4\xd3\xd4\x38\xd7\xae\x09\x49\xdd\x7d\x74\x8c\x1f\xfd\x6f\x28\xe8\x28\x5d\x44\x04\x22\xd2\x2a\x37\x61\x20\x2e\x95\x84\xf5\xcd\xb3\x50\x45\x47\xaa\x4b\x68\x57\x30\xc9\x82\xcb\xa2\x13\xde\x08\x02\x0a\x5e\x4e\x46\xa9\x5f\xac\x4b\x48\x1b\xea\x0b\x63\x0a\xbd\x03\x0d\xdd\x33\x5a\x20\xfe\x2c\xf7\x09\x4a\xef\x48\x13\x95\x69\x91\x91\x3c\x68\x21\xf4\xb5\x41\x0d\xf4\xf1\x33\xfe\x63\xe2\x2c\x08\x09\x2a\x0a\x65\x97\x27\x22\xa2\x7a\xe4\x20\x11\xa8\x07\xc3\x27\xb4\x17\x23\x7c\x54\x01\x14\xee\xcb\x9f\x0e\x96\xcd\xa5\xdc\xf0\x24\x6f\x1d\x27\x17\xf4\x9b\x9c\xea\x9d\xc6\xa3\xda\x9b\x39\x6f\x02\x70\x52\x92\x26\xf5\xdc\xba\x64\x99\x91\x8a\x6c\x28\x9f\xe0\x55\xfe\xc8"}, +{{0x6d,0x2d,0x0d,0x82,0x3f,0x29,0x47,0x46,0xb9,0xa5,0x51,0x2e,0x14,0xe7,0x3c,0x1d,0x85,0x5b,0x5e,0x4b,0xca,0x65,0xfe,0x81,0x77,0x29,0x81,0x0c,0xc5,0xef,0x84,0x0d,},{0x1b,0x64,0x80,0xa6,0xa9,0x0d,0xfb,0x47,0x29,0x84,0x85,0x5c,0xef,0x6f,0x1a,0xb3,0x1e,0xb7,0xb3,0xf1,0x3c,0x8a,0xc0,0x0f,0xa5,0x56,0xd2,0x0b,0x53,0xe5,0xae,0x17,},{0xb5,0x15,0xf4,0x9e,0xb3,0x2a,0xd4,0x78,0x69,0x2d,0xf8,0x8f,0x07,0xb7,0x80,0x2c,0x6e,0x0e,0x53,0x27,0xaa,0x08,0xa6,0x36,0x6e,0x4c,0xb1,0xd1,0xe2,0x6f,0x9e,0x65,0xfc,0x81,0xab,0xeb,0xe2,0x21,0x5d,0x64,0x91,0x00,0xf2,0x75,0x98,0x27,0x3a,0x41,0x2b,0x62,0x4e,0x84,0x2d,0x81,0x30,0x40,0x37,0x97,0xe5,0x7d,0xec,0x97,0x5a,0x0a,},"\x87\x72\x72\x1f\x72\xea\xf7\xf7\x30\x40\xc0\x68\xa7\xc3\x75\x3b\xff\xca\x7d\xc2\xd0\x93\x0c\x65\x25\xf4\x25\xe6\x00\x5c\x25\xcd\x4c\x0f\xf5\x09\x5c\x9c\x61\xa5\xd8\xa1\x96\x7b\x8c\x86\x01\x0c\x88\x4e\x50\x9e\x6b\x16\x70\xf7\x90\x46\xe2\x29\x79\xeb\xd3\x54\x73\x40\x90\xd3\xad\xa2\x14\x35\xc1\xf8\x25\x4f\x7b\x52\x22\xcd\x55\x64\xf0\x64\xe9\x77\x64\x03\x66\x44\x9f\x4e\x50\x08\xf8\x70\xf9\xc4\x84\x05\x65\xbf\x4f\xb5\xf5\x74\xc9\x77\x4b\xa2\x56\x8e\x71\xa9\xcc\xd8\x2f\xfc\x59\xb6\x94\xf2\x6e\x7d\xe4\xce\x2e\x3f\xd8\x80\xa0\xee\xf3\x87\x93\x13\x33\xed\xe0\x0d\xcb\x06\x5e\x6d\x0f\x79\x59\x1a\x2a\xa9\x56\xdf\x19\x48\xa2\x65\xcb\x95\x75\x0d\x8a\x23\x3b\x15\xc2\x88\xa0\x54\x87\xc5\x15\x66\x3f\x93\xe7\x40\xfb\x15\x70\xfb\xe4\xbd\x80\xc6\x8e\x8d\x92\x97\x34\x5a\x8a\x01\xcd\xbd\x88\xf4\xa3\x9b\xed\x9c\x5e\xf0\x9f\x14\x4b\xce\x5d\xe5\x68\xbf\x37\x33\xbc\x53\xb2\x03\x9a\x29\xcb\x3e\x19\x45\x01\xad\xc1\xc1\x0e\x86\x38\x3a\xac\x8b\x0f\x85\xc6\x7a\x66\x89\xbb\xe1\x47\x0a\x39\x24\x76\x31\x34\x39\xca\x88\xd9\x8c\x02\x1c\x0e\xae\xc2\x5f\xb2\xf9\xa1\x60\xce\x5c\x78\x61\x70\xbe\x02\x38\xfb\x87\x85\xdd\x33\xbf\xa9\x05\x9a\x6c\x37\x02\xd0\xde\x05"}, +{{0xc0,0xcf,0x79,0x9a,0xf7,0x39,0x5b,0xf2,0x7b,0xaf,0xa3,0x6c,0xab,0x43,0x70,0x45,0xe3,0x9c,0x90,0x3b,0xf8,0x07,0x54,0x83,0x19,0xce,0x44,0xf2,0x87,0x49,0x4f,0xbb,},{0xaf,0xbf,0x55,0x0c,0xa2,0x90,0xc9,0x05,0xbd,0xd9,0x2f,0xc8,0x83,0x1e,0xbe,0x3d,0xfe,0xb6,0xda,0xae,0x4f,0x56,0x00,0x52,0x53,0xcc,0x50,0x95,0x1e,0x50,0xed,0xc2,},{0x5b,0xba,0x01,0xa4,0xc7,0xb2,0x55,0x42,0xd0,0x69,0x12,0xde,0x70,0xaa,0x1e,0x22,0x04,0x23,0xfd,0xf8,0x33,0x8a,0x9e,0x69,0x33,0x95,0xcb,0x6f,0x0d,0xc1,0xfb,0xfd,0x01,0x8e,0x3c,0x77,0xe5,0x0a,0xef,0x90,0xa9,0x08,0x0f,0x30,0xf1,0xf5,0x79,0x2b,0x24,0x31,0x07,0x8f,0xe6,0xe3,0xe0,0x04,0x64,0x24,0x5e,0x17,0xcd,0x8d,0xc1,0x07,},"\xdb\xe6\x57\x80\xe9\x68\xde\x9e\x40\xff\xb5\x7c\xf5\x9a\x60\xfd\x93\xb3\xf9\xa5\xe7\xd8\xed\x51\x80\xad\xbc\x57\x8c\xa1\xbc\x48\xbd\x9f\xb6\x0a\x13\x24\xc9\xc2\xc1\x14\x14\x79\xa0\xdc\xf0\xf1\xd0\x7e\x84\x93\x65\x26\xdf\x42\x33\x3c\x0d\x77\x3e\x3f\xed\x9e\x40\x38\xde\x5b\x95\xad\x90\x5c\x92\xcb\xe0\x40\x48\x7b\xf5\x5e\x10\xe1\xed\xb4\x29\xa0\xec\xc4\xe0\xe8\xd0\x0a\x98\x8a\x9c\xd5\x3e\x2e\xb3\x72\xf4\xfc\x4c\xd9\x53\x7b\x26\x9b\xa3\xa2\x3c\xef\xbc\x8d\xf6\x47\x6e\x75\x43\x4b\x81\xd9\x3e\x88\x91\xbf\x41\x7c\x82\xe3\x63\xf3\xe4\xab\xf8\x0a\x4f\x73\xac\xa8\x4a\xc7\xdf\x63\x37\xf5\x36\xd6\x3d\x93\x9d\x92\xcb\xa6\x4b\xe7\x42\x22\x11\x16\x06\x9e\xf2\x51\xab\xba\x0b\x00\xaf\x01\x71\x8b\xb5\x80\xdd\xbe\xb7\x99\x73\xef\x10\xa6\x8b\x4d\x0f\xa0\x23\xd6\xeb\xd3\x07\x9d\x6b\x32\xa1\xaa\x20\xa2\x1e\x92\x02\xf2\x75\x90\xc3\xf0\xc0\xcc\x25\x30\x73\xc3\xf8\x22\xaa\xc4\x59\xd3\x9f\x50\x75\x8b\x70\xc0\x07\x10\xa3\xc9\x84\x38\x41\x65\x08\x52\x2e\x51\x2a\xda\xa0\xaf\xd5\x03\xa7\xce\xb0\x4f\xb9\x4a\x4a\x93\x2c\xe8\x0c\xd5\xa7\xf1\x1b\xb8\x61\x26\x3f\x58\xe5\x74\x9d\x54\x2a\x11\x0d\xe7\xc7\x68\x9d\xfc\xb0\xc5\x1a\xfa\x9d\x54\xa5\x8f\xf8\x9f\x3f\x67"}, +{{0xcd,0xaa,0x50,0xe8,0x52,0x7d,0xc7,0xa5,0x0f,0xb3,0x7e,0x28,0xfa,0x8b,0x95,0x68,0xc3,0x7e,0x85,0x67,0xe0,0xb4,0x99,0x99,0x7b,0x9a,0xed,0x67,0x61,0x80,0xc3,0xb0,},{0x7c,0x56,0xe1,0x64,0x51,0x02,0x68,0xc1,0x82,0xb4,0x23,0x74,0x79,0x04,0xf1,0xd3,0xa5,0x80,0x93,0x30,0xf6,0xe1,0xb2,0x92,0x66,0xec,0x46,0xe7,0x3b,0xe1,0x55,0x0f,},{0x13,0x7b,0xd1,0x0a,0x50,0xef,0x60,0x93,0x84,0xfe,0x66,0x87,0x68,0xfb,0x87,0x1d,0xe7,0x41,0xca,0x0f,0x53,0xff,0x84,0x77,0xd7,0xeb,0xfa,0x90,0xaa,0xfd,0x5e,0x26,0x81,0xfd,0xf1,0xb8,0x92,0x50,0x46,0x3c,0x15,0xdb,0x8e,0x17,0xa5,0x88,0x25,0xfe,0x94,0x27,0xde,0x08,0x9c,0x34,0xde,0x13,0xcd,0x07,0xbb,0xa1,0x8d,0x4a,0xa4,0x0d,},"\x94\xfc\xfb\xaa\xa3\x03\xde\xce\x7b\x90\x8f\x87\x4c\xc5\xf0\x95\x06\x1f\x17\x54\xbb\x35\x78\x0d\xb6\x66\xb6\x3a\xb8\x29\x08\x11\xbf\x1c\x52\x1a\x7f\x8f\x78\x5e\xa2\x70\xdf\xb3\x9d\x0d\x6e\xd9\x5a\xb7\x19\x55\xa1\x1f\xfa\xea\xa2\x68\xe0\x81\xff\x3e\x4f\x24\x25\xb4\x18\x80\xa9\x87\x15\x1e\x67\x8e\x89\x11\x13\x50\x94\x2d\x82\x0c\x3e\xec\x36\x21\x24\x26\x66\x3b\xe1\x75\xe5\x28\x6b\x4a\xd1\xcc\x80\x4e\x3e\x3a\x03\xb9\xfa\x3e\x82\x83\x8e\xbb\xc2\x61\x5a\x64\x5f\x2c\xa1\x46\x8a\xc4\xa1\xcd\xbe\x52\x37\x61\xe8\x3f\x43\x81\xb0\xc8\x55\x0a\xe5\xe8\xc8\xcd\x1f\xda\x57\x19\x14\x36\xe2\x7c\xb8\x83\xbc\x64\xbe\x86\xa9\xdc\x61\x10\xef\x34\x01\xd8\x8a\x7d\xeb\xd1\xb7\x01\xd9\xc2\x57\xa6\x82\x6c\xf0\x1e\x9e\x29\x22\xe3\xae\x57\x7f\x28\x34\x27\x5f\xb0\xec\xda\x80\xed\x8c\xf1\x80\x1e\x0b\xc5\xe0\x1e\x26\xa7\x7c\x48\xbd\xf4\x6a\x5c\x48\x94\xd2\x2a\xb5\x3e\x74\x18\x27\xe2\x4b\xed\x5f\x07\x50\xff\xad\x05\xe5\x3f\x1d\x5e\x61\xdf\xd3\x16\xb1\x91\xd9\x79\x7e\xf7\x13\x13\x1a\x8b\x43\x0a\xbe\x3f\xac\x5f\x3c\x4a\x2c\xa0\x21\x87\x8b\x15\xad\xc8\xc5\xf5\x42\x11\x42\x60\xe6\x87\xa9\xd1\x99\xd2\x30\xc4\xe0\xd3\xfc\x69\x69\x93\xb5\x9c\xcf\xa3\xff\xa9\xd8\xd2\xfb"}, +{{0x0f,0xde,0xa9,0xbe,0xe6,0x28,0x8f,0x94,0x7e,0x0a,0xdb,0xdd,0xa4,0xdf,0xb2,0xba,0xa0,0x38,0x91,0xaf,0x25,0x02,0x4a,0x5e,0x13,0x8a,0xc7,0x79,0x84,0xd0,0x05,0x07,},{0x70,0xab,0xd8,0x64,0x30,0xd7,0xe8,0xd6,0x32,0x09,0xc8,0xb3,0x73,0xec,0x4e,0x4b,0x79,0xe9,0x89,0xe6,0x72,0x5f,0xac,0xef,0xba,0xde,0x3c,0x75,0x74,0xd2,0x3c,0xd0,},{0x80,0xc4,0x2d,0xd5,0xdf,0x03,0xb2,0x85,0xa8,0x6a,0xc9,0x5c,0xe6,0x66,0x9f,0x78,0x6a,0x97,0x8a,0x81,0x3a,0x9d,0x7b,0x8c,0x6a,0x23,0xde,0x76,0xfb,0xd0,0x9b,0xdb,0x66,0xc5,0xdd,0x1c,0xc9,0xf1,0xa1,0x76,0xcb,0xa3,0x88,0xd5,0x05,0x17,0x64,0xa3,0x2f,0xa2,0x7f,0x00,0x28,0xba,0x48,0x98,0x06,0x8b,0xd0,0x1a,0x3e,0xe1,0x72,0x08,},"\xcf\x72\xc1\xa1\x80\xa2\xbc\x37\xd8\x47\x8d\x9a\x7a\x39\xac\xf0\x3b\xf2\xa5\x07\x90\xf7\x90\x2f\x81\x12\x12\x22\xd3\x1d\x3e\xc9\x16\xf4\xf2\x4c\xef\x9d\x7c\x41\xdc\x02\x1b\x0e\x84\x87\xbb\x89\x2e\x47\x30\x5e\x54\x52\x03\x03\xe8\x9b\x30\xb2\x63\xda\xc4\xa9\xba\x37\x5d\x46\xc4\x0f\xcf\x40\x05\x35\xc9\x59\xd2\xb7\x46\xa7\xfc\x97\x0c\xf6\x5b\x47\x2e\x84\xb5\xf1\xd0\xeb\xad\xcf\xa1\xae\xd6\xfc\x47\xfa\xcc\xe1\x6a\x36\x6a\x3b\x1d\x6e\x51\x68\x13\xc1\x96\x09\x75\xf8\xf2\xb4\x30\x42\xfb\x4e\xea\xab\xe6\x3c\x6f\x65\xdb\x45\xdd\xb7\xdb\x88\x8a\x19\xa9\xd7\xba\x6c\xa4\x79\xfc\xd7\x0c\x5d\x1e\x97\x0f\x12\xc1\x4f\x4d\x24\xfb\x7e\x2f\x35\x7b\xd3\xa9\x4a\xa1\xb8\x68\xcc\xc0\x84\x7f\x2e\xef\x21\x85\x3e\x25\x3b\xaf\xbf\x07\xc4\xe6\x17\x6a\x1e\xf0\x77\x16\x78\x41\xeb\xbe\x56\x29\x33\x71\x57\xf3\x9f\x75\xc7\x1d\x21\xe7\xe9\x6c\x51\xa1\xb1\x6f\xa8\xdc\x60\xf0\xb1\x27\x9f\xcd\xa2\x64\x1f\xc8\x59\x1e\x3c\x49\x2f\x15\xbf\x83\xca\xf1\xd9\x5b\x2c\xd9\x13\x32\xf1\xb4\x20\x2f\xe7\x28\x62\xca\x2e\xa2\xef\x92\xc1\x1d\xb8\x31\xd8\x2f\x8f\xc3\xd4\x1f\xe2\x9a\x76\xc2\x11\xa7\x58\xe2\xf7\x1b\xd8\x9d\x2c\x66\x10\xf2\x01\x42\x9f\x34\x8d\x56\xe1\x0e\x3b\x7a\xf5\x3e\x27"}, +{{0x03,0xd5,0xe4,0x66,0xf8,0x29,0x8a,0xb5,0x43,0x8a,0x30,0x97,0x6d,0x13,0x22,0xa7,0x21,0x5a,0x64,0x2d,0xd5,0xfb,0x4c,0x3f,0x85,0x19,0x40,0x9a,0x75,0x22,0xf0,0x92,},{0x4b,0x3e,0xd4,0xdb,0x08,0x0e,0x2a,0x45,0x2e,0x16,0x91,0x2c,0x14,0x50,0x44,0x24,0x92,0x0a,0x60,0x97,0x56,0x04,0xe4,0xf3,0x79,0x25,0x8d,0x1c,0x8b,0x19,0x3d,0x6f,},{0x6d,0x7e,0x46,0x58,0xf2,0x6f,0x33,0x7c,0x98,0xe0,0x3f,0x13,0x54,0x2e,0x2f,0x39,0x44,0x0f,0xf7,0xbf,0x8d,0x88,0xf3,0xf6,0xdf,0xa4,0xd6,0x49,0x48,0xcd,0x96,0xb7,0x90,0x51,0x49,0x2f,0xc2,0x8f,0x65,0xf2,0xcc,0x0d,0x23,0xa0,0xc4,0xd5,0xe2,0x30,0x7b,0xb1,0xc4,0x7e,0x11,0xe5,0x3b,0x37,0x1f,0x09,0x1b,0x69,0xf8,0x0d,0xbd,0x05,},"\x1b\x47\xb7\x00\x13\xcb\x53\xe1\xf8\xf4\x97\x1e\x0f\x39\x56\x3c\xe8\x7e\xdb\xc2\xce\xdd\x99\xe5\xa3\x55\x85\xdf\x8b\x00\xa8\x52\xf7\xb9\xc9\x7c\x7e\x4a\x54\x65\xfc\x56\x05\xae\x8c\x5c\x36\x57\x0a\x99\x20\x1a\x7a\xd6\x03\x12\x87\xef\x0c\x7b\x2b\xa6\xe5\x7b\x05\x6d\x0f\xc8\xd6\xca\x43\xbf\x6c\xbd\xab\x09\x89\x34\xb4\x03\x19\x7b\x52\x5d\x22\xd4\x5e\x6b\x29\xc7\x8f\x8d\x61\x83\xe4\x1f\xfe\x19\x7d\xae\x25\xba\x22\xb0\x66\x69\xae\x05\xba\xdd\x7e\x1d\xa6\x93\x2a\x7d\x05\x4c\xba\xb3\xf5\x4e\x51\x46\x22\x3a\xd8\x67\x12\x31\xbc\x16\xfe\x62\x67\x9b\xd2\x81\x7a\x6b\x80\xe6\x53\x99\x8c\x49\x49\xf8\x1f\xf5\x3b\x61\x73\x16\x3e\x11\xda\x3e\x6d\x3c\x76\xd8\x4c\x71\x32\x25\xb4\x17\x3d\x6b\xf0\x6a\x85\xb6\x98\x8a\x48\xbe\x43\x59\xcb\x51\x55\x03\xca\x56\x3f\x43\x53\xf8\xe7\xd4\x5e\x4d\x94\x46\x2c\x89\xa0\x4a\x00\xf1\xb3\xb0\xca\x64\x22\xd5\xdb\x02\x9c\x50\x7d\x46\x48\x34\xa2\x0c\x78\xa7\x13\x66\x1d\x84\xed\xff\xc4\x96\xd6\x92\x82\x61\x98\x94\x43\x7b\x44\x87\x95\x4c\xbe\xa2\xaa\x72\x61\xe6\xa6\x2b\x68\x51\x15\x4a\x5d\x25\xfb\x6b\x4f\x09\xc5\x94\x73\xd3\x85\xce\x03\xe9\x1b\xa8\x65\xea\xb6\x6c\x58\xc0\xab\xb0\xb7\xa7\x8e\x4b\xe9\x27\xe5\x54\x60\xcc\xd7\x0d\x82"}, +{{0x76,0xcc,0x18,0xa1,0xda,0xff,0xfa,0x10,0x05,0x86,0xc0,0x6a,0x7b,0x40,0xf7,0x9c,0x35,0xfe,0x55,0x8c,0x33,0x9c,0x29,0x99,0xa5,0xf4,0x38,0x75,0xcf,0xad,0xe0,0x3e,},{0x4b,0x9d,0xa8,0xd2,0xf1,0x37,0xdc,0x6c,0x85,0x7a,0x99,0xa5,0x99,0x8d,0xd8,0x9d,0xd5,0xf0,0x59,0x71,0xa2,0x1e,0x8c,0x77,0x66,0x70,0xeb,0x47,0xbc,0x12,0x70,0xa5,},{0xdb,0x74,0x75,0x1c,0x66,0xe6,0xb1,0x86,0x60,0x44,0xdd,0x9a,0xe9,0x9f,0x19,0xe6,0x33,0x4f,0x17,0x9e,0x79,0xd8,0xb8,0xe0,0xc8,0xcd,0x71,0xd2,0x2c,0xef,0xb9,0xea,0xb7,0xe3,0xe7,0xa9,0xc2,0xda,0x22,0x5f,0x2a,0x9d,0x93,0xa3,0x13,0xd1,0xcb,0xf1,0xb7,0xfe,0x25,0x97,0xb8,0xd7,0x02,0xbf,0x30,0x17,0xa6,0xa6,0xbc,0x7b,0x7b,0x06,},"\x45\x22\xb1\xd8\x23\x73\xf7\xa3\x18\x22\x1e\x7e\x57\x61\x75\x03\xdd\xf4\x4f\xd5\x39\x97\x52\x2a\x1d\x96\x3c\x85\xb7\x08\xd0\xb2\x45\xde\x37\x2a\xd5\x2e\xc7\xf5\x4f\x62\x13\xd2\x71\xf7\xc9\x1d\x5a\x1d\x36\xd1\x34\xdb\x38\x9d\xf0\xb0\x81\xa0\x6b\xc0\xc7\xa4\x87\x5f\x72\x40\x92\x79\x31\x72\xc9\x11\x56\x41\xc6\xd0\x54\xf1\xd9\x92\xe0\xfa\xe4\xdf\x58\x69\x5f\x0e\xa3\x44\x9d\x7a\x4b\x3a\x88\x57\xe1\x98\x03\xfe\x49\xb6\xd5\x2c\x9f\xf3\x74\x6a\x57\x4a\x27\x56\x95\x65\x79\xf9\xfb\x80\x9a\x0e\xde\xc9\x2c\x55\xe9\x5f\xfe\xfa\x3d\x05\xf1\x65\x82\x2f\x46\x4a\x21\x99\x9f\x29\x69\x1f\x67\x44\xac\x5a\x3e\xe4\x90\x17\x88\x06\x45\xe8\x37\xed\xeb\xfd\x2e\x0f\x24\x99\x7f\x04\x11\x45\xa7\x2e\x23\x76\xad\xa2\x83\x18\x6c\xa2\xb8\x36\x36\x29\x77\x19\x5b\xae\xe3\x0a\x3a\xcc\x81\xb2\x43\xf3\xee\x37\x6a\x2c\x47\x64\xc7\x83\x66\x7a\x4b\x11\x77\xe7\x95\x1d\x3e\x3c\x7b\xe4\xf1\xbd\x7a\xe8\xc6\x0f\xd5\xfb\x0f\xd9\x1f\x0c\x1c\x14\xd0\xd2\x32\x7e\x8f\x20\xd9\x2c\x0d\xfc\xc5\x38\x70\xe9\xd9\x9f\xdb\xf9\xdd\x9a\x17\xe8\x82\x50\x9a\xe7\xba\xa8\x65\x3e\x39\xed\xc8\xee\x56\x90\x00\xd6\x24\xcb\x93\xa0\x75\x4a\x79\x8d\x1f\x81\x1f\x6a\x0e\xf5\x50\x1a\x17\xbc\xf2\x5f\xd0\xf9\x16\x26"}, +{{0x71,0xad,0x98,0x0d,0x58,0xad,0x8e,0x7d,0x33,0x30,0x66,0x89,0x35,0x89,0x36,0xa3,0x72,0xd5,0x19,0x0b,0x24,0xec,0x7f,0x9b,0xde,0x74,0x9c,0xb8,0x11,0x50,0xef,0xda,},{0xfd,0x35,0xa7,0x5f,0xe5,0xab,0xc2,0x01,0x04,0x69,0x1a,0x24,0xa4,0x65,0x94,0x40,0xb5,0x5a,0xea,0xea,0x90,0x2a,0xc3,0xbe,0x27,0x4a,0xf2,0x7a,0xa8,0x31,0x28,0x69,},{0x81,0x67,0x0b,0x10,0x29,0xe4,0x81,0xe9,0xff,0x3c,0x17,0x1f,0x05,0xc1,0x68,0x61,0xc8,0x46,0xee,0x79,0xcd,0xf2,0xe2,0x1e,0x3b,0xf9,0x52,0xbc,0xfa,0xc9,0x75,0x65,0xf2,0xb1,0xdc,0xed,0xf6,0x9d,0x2e,0x7e,0xb3,0x5c,0xaf,0x56,0x62,0xe8,0xbc,0x67,0x1f,0xbb,0x96,0x75,0x6a,0x63,0xa5,0x96,0x26,0x4d,0x1b,0x7f,0x4a,0xf9,0x7e,0x06,},"\xe8\x7a\xe0\x73\xff\x5d\xcc\x54\x85\xa1\x99\x40\xe4\xe3\xff\x26\x3a\x06\x18\xa9\x02\x5a\xd4\x03\x2d\xfb\x36\xd1\x71\xce\x88\x1f\x71\xc1\x8a\x49\x21\x0e\xb4\x58\x19\x80\x61\x42\xe2\xf0\x0d\xb3\x04\x18\x35\xbf\x2c\x3b\xcc\xf1\xdb\xa0\x2b\x8b\x5a\x5b\xda\xf8\xfe\xa3\x16\xc0\x62\x3d\xd4\x8a\x56\x4e\xc1\x66\xf0\x37\xd5\x87\xc8\xc0\x16\x84\xe5\xe5\xc0\xba\x9d\xba\x4d\x23\xb4\x9a\x03\x09\x24\x4e\x28\x2a\x51\x40\x86\x22\xed\xb0\x57\x04\x74\x7e\x0c\xde\xec\x97\x68\x93\x77\x70\x71\x09\x89\x72\xc1\x13\xa8\xab\x63\x9c\x31\xf1\x61\x32\x33\xee\x46\x0e\xea\x8a\x8c\x10\xe1\xe6\xe1\x52\x21\x45\x29\x87\x8c\xf1\xad\xae\xaf\x78\xcf\x19\xba\xc7\x13\x61\x81\x5b\xf5\x79\x55\x49\x8f\xab\x4f\x0f\x2b\x75\x86\xc8\x6f\x9f\x4c\x2d\xdf\x89\x72\xf9\xb9\xe0\xeb\x63\x6d\x84\xbc\xc1\x43\x85\xb2\xd0\x38\xbe\x55\xa9\x63\x70\x2e\xfe\x22\x5a\x50\xbd\xd0\xc4\xda\x92\xa2\xa6\xa0\x91\x00\xea\x04\xa2\x11\xd3\x96\x45\x8d\xce\xb4\x48\x71\x16\x83\x7d\x13\x9e\xb0\xf1\x22\x53\x8e\xd3\x98\x6a\xd0\xaf\x4d\xa2\xdf\xfc\x89\xf3\x26\x9c\xa8\x85\x38\x08\x6e\x69\x1e\x5b\xea\xe9\x58\x1e\x7c\x63\xd8\xe6\x12\xda\x2c\x47\xf7\x4d\xde\x1d\x94\x95\x1e\xad\xb0\xdf\x60\xc3\x89\x7d\x2a\x30\x95\xc5\x06\x09\x3b"}, +{{0x61,0x59,0x4e,0x24,0xe7,0x5f,0x99,0x6b,0x4f,0xb6,0xb3,0xe5,0x63,0xf6,0xa4,0xf9,0x91,0x5c,0xfa,0x65,0xdd,0xb1,0x99,0xb0,0x1f,0xed,0x7f,0x8e,0xd7,0x82,0x4e,0xcb,},{0x86,0x27,0xd2,0x14,0x15,0x79,0xcd,0x25,0x21,0xaa,0x07,0x68,0x00,0xac,0x35,0x4b,0x9e,0x3a,0x47,0xd7,0x1c,0xed,0xc8,0x54,0x74,0x34,0x26,0x82,0x25,0xe3,0x30,0x05,},{0x63,0x02,0xb3,0xff,0x27,0x10,0xbe,0x30,0x6c,0x92,0xb9,0xaa,0xe3,0x0d,0x23,0xc3,0xd4,0xbe,0xff,0x39,0x4e,0x63,0x20,0x1e,0x6a,0xd1,0x17,0x13,0x34,0x5c,0x4f,0xcb,0x5c,0xc8,0xd3,0xdd,0x10,0xad,0xfb,0x82,0xbb,0x11,0xa1,0x89,0xce,0x7e,0xc3,0xe4,0x22,0x27,0x27,0x62,0x4f,0xc1,0x78,0x81,0xc1,0x47,0x88,0xd2,0x71,0x0e,0x16,0x08,},"\xbc\x01\xb0\x8c\x7c\xaa\x23\x61\x00\xa0\x12\xa7\x26\x47\x7d\x0e\xc3\x89\xdb\xfa\xda\xc7\x3d\x51\x06\x42\x4c\x5d\x1f\x3d\x1c\xef\x16\x95\xcf\xd9\x3a\x70\x62\xec\x8b\xf1\x06\x70\x47\x85\x49\x20\x16\x2f\x65\x13\x57\xbe\xdf\x1c\xd5\xa9\x2e\xc2\x9b\xdb\x5d\xff\x71\x6e\x8f\x60\x25\x51\x5a\x95\x49\xba\x36\xcd\xc3\x5c\xed\x7c\x5c\x0c\x36\x8e\x6c\xd9\x2f\x2f\x10\xae\x14\x6a\x20\x72\x8c\x37\x4b\xba\x50\x96\x41\xce\x88\xcb\x42\xff\xf0\xce\xdf\xd9\xfd\x67\xf3\x10\xf9\xd0\x1a\x3f\x36\x90\xeb\x21\xdb\x17\xbc\xe6\x7a\xe3\x5c\x4c\xd2\x4c\x20\x9f\x09\xf0\x44\x75\x9d\x8d\x5a\x7d\x24\x8e\x2b\xd9\x66\x52\x4b\xa8\xc0\xc2\x89\x74\x72\x6b\x43\xbd\x05\xde\x84\x34\x33\xcc\x40\x05\x98\x92\x29\x74\x62\x3d\x9a\xcb\xfd\xc7\x61\xc4\xc0\x43\x75\xa9\x52\xce\x54\xca\xff\xaa\x96\xac\xff\x6d\x9d\xc2\x78\x74\x2a\xf4\x76\xe1\x86\x5c\xb8\xc2\x0d\x13\xd1\xc1\x90\x08\x63\xbc\xa2\x31\xe4\x4c\x6b\x0d\x47\xcb\x41\xd5\x10\xf7\x95\x8f\x48\xf3\x04\xd0\x3d\xa0\x33\x48\x4a\x3e\x1f\x27\x3f\xaf\x69\x83\x37\x5b\x7d\x3b\xe0\x3d\x8a\x0a\x00\x2d\xef\x63\x65\xbe\xb2\xfa\x8c\xcf\x1a\x94\x98\x7a\xdc\xd3\x3d\x0d\xa1\x17\x7f\xc5\x15\x9b\x6e\x56\xd0\x04\x30\x1e\x92\x1d\xbc\x12\xec\x0a\x73\xf4\x13\xcf\x2c\x48"}, +{{0x54,0xe6,0xbb,0xfb,0xf8,0xc0,0x6f,0xf2,0xc0,0x66,0x31,0x8c,0x2e,0xbf,0x03,0xd5,0x06,0x54,0x7b,0xf4,0x3c,0x2d,0x7a,0x5d,0x4d,0xf3,0x05,0xa3,0x03,0x2b,0x71,0x38,},{0x3b,0x71,0xaa,0x1d,0xef,0x66,0x6d,0x91,0x88,0xf4,0x03,0xf8,0x2e,0xd3,0x04,0x54,0xab,0xa5,0xbc,0x9f,0x47,0x0f,0x6e,0xb9,0x88,0xda,0x18,0x7c,0x92,0x52,0x32,0x84,},{0x3d,0xf4,0xd0,0x90,0x79,0xf8,0x30,0xe3,0xf9,0x82,0x28,0x36,0x81,0xba,0x37,0xb5,0x0f,0x3c,0x73,0xde,0x2c,0x5d,0x22,0xa2,0x91,0x35,0x8e,0xbb,0x1f,0xb8,0x54,0xe5,0x10,0xf6,0x3f,0x9a,0x48,0xe9,0xff,0xf7,0xfd,0x83,0x11,0x30,0x2e,0xa3,0xe9,0x69,0x39,0x4e,0x6d,0x49,0xc9,0xe3,0x18,0x20,0x54,0x94,0x2f,0x6a,0x74,0x4c,0xee,0x03,},"\x03\x18\xd7\xcb\x48\x05\xaf\x98\x21\xdd\x3f\x91\x4b\x0e\x07\x6f\xea\x04\xa7\xd2\xdb\x3a\x59\xa0\x0a\xff\xea\xd3\x32\x5a\x2b\xe4\x0c\x1f\x87\xf5\x32\x76\xa8\x55\x26\x04\xf2\x28\xb9\x76\xe2\x88\xb9\xbe\x90\x6a\x7b\xd2\x5b\x2f\xfa\xb8\xa8\xaf\x5d\x0f\x6e\x08\x78\x6f\xd0\x34\xe2\xfe\x1e\xb7\xee\x03\x39\x79\x86\x0d\xd1\xe5\x32\x72\x87\xe9\xe6\x15\xf5\xdc\x5a\x96\x0f\x17\x02\x6b\x56\x84\x2f\xc8\xd4\x4c\xad\x00\x2e\xdc\x85\x01\xcf\xb9\x56\x00\x15\x02\xe4\xdd\xc8\x1a\x77\x00\xd9\xc0\xbe\x88\xeb\x4a\xaa\x64\xa6\xcb\xc3\x9d\xe8\x2f\x13\xc1\x10\x86\xde\x1a\x42\x70\xd3\xaf\x97\x28\x4b\xac\x1c\xae\xf1\xd3\xed\xaa\x10\x71\x66\x6b\xd8\x3b\x2e\xde\x39\x62\xd9\x8b\x9d\x93\x49\x7d\xdf\xd8\xe9\x7d\xab\x30\x89\x95\x0c\xf3\x0e\xd1\x1d\xb7\x7a\xd1\x43\x7a\x0a\xf5\x88\x9d\x8e\xfc\x44\xe6\x12\x42\x0e\x39\x07\x26\x7d\xf3\xac\xff\x4b\xd3\xfb\x6e\x8c\xa5\xba\xdf\x8e\x72\xf9\xde\x39\x52\x86\x53\x05\x85\x24\x45\x6a\x81\xda\x5f\x84\x98\x2a\xfa\xc3\x4b\xef\x5f\x71\xe9\x1f\x8f\x90\x93\x8a\x6f\x5f\x1f\x28\x77\x16\xde\x56\xa0\x94\x6d\x26\x1e\x87\xbc\x77\x5c\xe1\x89\xe4\x1a\x77\xba\xed\xe7\x32\x0a\x3c\x60\x8f\xc9\x71\xe5\x5d\x0a\x77\x3c\x4d\x84\x8d\x42\x86\x37\xf1\x1b\x4e\x44\x60\x39\x0c"}, +{{0x68,0x62,0x06,0x1b,0xe0,0xde,0x9d,0xfd,0x99,0x81,0x18,0x20,0x4b,0x2b,0x98,0xdb,0x3c,0xe7,0xd7,0xe8,0x19,0xdb,0xc1,0x07,0x94,0xaf,0x0a,0xb2,0xb0,0x6e,0x84,0x34,},{0x9c,0x5f,0x7c,0x22,0x65,0xdd,0xe1,0xb2,0x5e,0x4f,0x27,0xec,0x71,0x58,0x0d,0x52,0xdc,0x89,0xf2,0xc3,0xa7,0x12,0xbc,0x1a,0xd5,0xd6,0xd6,0x9e,0x71,0x1e,0x08,0xd4,},{0x96,0x5e,0xdb,0x34,0xe8,0xab,0x8b,0xc3,0x20,0x4a,0x32,0x01,0xd2,0x21,0x86,0x37,0x2d,0xe4,0x24,0x26,0x00,0x29,0x7c,0xfd,0xb5,0x7a,0xa1,0xdf,0x07,0x4e,0xc5,0x0d,0xdf,0x10,0x10,0x5e,0x9d,0x4c,0x89,0xa2,0x66,0xc3,0x4d,0xb7,0x77,0x2a,0xa9,0x4c,0xba,0x94,0x64,0x29,0xe6,0x8b,0xa6,0x2b,0xf9,0xa0,0xac,0x90,0xf5,0xf0,0x5b,0x02,},"\x17\x40\xdd\xe8\x43\x4a\x0d\x68\x99\x25\x67\x9b\x0c\x18\x03\x00\xcd\xbd\x0c\xf6\xa8\x9a\xd8\xfd\xe3\x46\x53\x31\x6c\xee\x4c\x57\x1a\x41\x05\xc9\xe9\xe0\x28\x42\x38\xfe\xf2\xc3\x8a\x09\x15\x7c\x5d\xb9\x43\x40\x57\x1b\x39\x0a\xdf\xb6\x9f\xf4\xc0\xdc\x50\x53\x25\x3a\x67\x9d\x42\xcc\x1f\x1b\xf1\xff\x42\x92\x29\xea\x0a\x50\x44\xc6\xf7\x95\x64\xe0\xdd\x28\x7f\x53\xf0\x15\xb8\x31\x87\xd9\xad\x27\xd9\x10\x39\xaf\x06\x2c\x43\x7b\x15\x75\xa0\xea\xb6\xae\xb8\xaa\x0d\x27\xb2\x76\x65\xd6\xde\xa9\x04\x1f\xf9\x96\x3a\x31\x18\xb3\x29\x8a\x85\x44\xe3\xfd\x69\xac\x68\x77\xe3\xe4\x05\x2f\xe4\x42\x2b\xf0\x35\x60\xb2\xc5\x7e\xc5\x31\xee\x8b\x5f\xf5\x3c\x28\xdb\xde\x35\xbb\x45\xc3\x50\x77\x63\x6e\x6f\x84\x1b\x59\xd7\xeb\x77\xbc\x77\x91\xb6\x09\x38\x58\xa3\xa8\x0a\x3a\xa6\xd7\x78\xdb\xf5\x3d\xb9\xd0\x61\x19\xc5\x0b\x71\xc7\x91\xc0\x49\x5c\x57\x6d\x1b\x59\xd3\x96\x87\x3e\xd8\x71\x48\x53\x52\xc8\x29\x9a\x35\x9d\xa5\xee\x9d\x7f\x36\xed\x14\x55\xf8\x98\x51\xa3\x08\x51\xbe\xa7\x19\x68\x5a\xec\xd0\x8f\x25\x56\x26\x09\xdd\x10\x66\x30\x73\x52\x77\xe1\xd6\x51\x9b\xb1\x68\x7d\xe8\xb8\xc6\x8b\x96\x71\x45\x2e\xdb\xb3\x49\x1d\xa2\x64\xcd\xfa\x00\x17\xc5\x12\xd2\x76\x97\x59\xcb\x92\x5f\xb6\x64"}, +{{0xb2,0x25,0x0b,0xbc,0xb2,0x68,0xd2,0x47,0x7c,0x83,0x12,0xb1,0x90,0x0f,0xd9,0x99,0x82,0xba,0xa2,0x9a,0x68,0x97,0x4f,0xbf,0x87,0x78,0xa1,0x22,0x8d,0xc9,0x75,0x50,},{0x44,0xaa,0x8d,0xf1,0x18,0x16,0x74,0xb0,0x5a,0xde,0x98,0x0f,0x7e,0xdd,0xba,0xf3,0xbd,0x74,0x22,0xa9,0x20,0x28,0x7c,0xb2,0xd2,0xdb,0x59,0xa0,0x63,0xee,0xbf,0x74,},{0xf2,0xb8,0xd9,0x2e,0xd5,0x1e,0xbd,0x10,0x00,0xbf,0x9d,0xd3,0x41,0x1a,0x9f,0xa9,0xe7,0xae,0xe5,0x4c,0x4c,0x86,0xe2,0x4a,0xd0,0xf9,0xad,0x5c,0x55,0x64,0x3a,0x12,0xd6,0x80,0x01,0x9c,0xa0,0x3f,0x21,0x6b,0xd4,0xbd,0x32,0xc9,0xce,0x1c,0xd8,0xa5,0x28,0xc3,0xff,0xaa,0x5d,0x5b,0x1d,0xc9,0x1a,0x4b,0xe5,0x6f,0x0e,0x2c,0x5e,0x06,},"\x7e\xf0\xae\x13\x36\xa6\xfa\xb3\x7f\x99\xda\x5f\xa7\xd0\xde\xc7\x40\x9c\x07\x26\x23\xea\xd8\x4f\x24\x1d\x53\xd0\x59\x6b\x46\x17\x05\xfb\x1b\x3c\x53\x7d\x36\xb8\x9e\x89\x60\xfe\xbb\x4c\xdc\x0d\x42\x7c\xe2\xfc\x1b\xe5\x8d\xbb\xce\x15\x1e\x35\xac\xd8\xb6\xac\xe4\x0a\x19\x82\x29\x14\xa4\xbd\x8c\x4a\xf6\x32\xf1\x36\x41\x8a\xc4\x9b\x18\x4d\x55\x19\x3e\xbc\xc3\x2d\x0d\x79\x87\x09\xb1\xa8\xfe\x29\x4f\xba\x8a\x1f\xe7\x2d\x97\x6b\x44\x00\xd4\xa3\x93\x24\x23\x11\xb0\xf8\xcc\x99\x4e\x89\x47\x5b\x00\x38\xae\x5d\x89\x14\x93\x8e\x8f\x6e\x87\xc6\xf5\x0b\x9d\x65\x6c\x45\xd7\xb1\x42\x31\xef\xed\x97\xf3\xc9\x06\x68\x91\x36\x70\xbf\x5b\xe2\xef\xd5\xc2\x70\xc7\xcb\xaf\x01\xe8\x57\x2e\x98\x00\x97\x8d\xfe\x2e\x10\xa2\xfc\x04\x40\xb8\x55\x62\x9b\xf9\xcd\x40\x9e\xa9\x41\xcb\x69\x22\x6c\xac\x77\x1b\x15\xea\x77\xc0\x32\x68\x48\x80\x6f\xf8\xd2\xe2\x01\xe6\xe2\x6c\xd5\xf4\x54\x30\xda\xdc\xff\x8f\x59\xc3\x21\xc1\xc9\xc6\xa2\x9b\x94\x88\x29\x35\x44\x7d\x3e\x6c\x2e\x88\x04\xb1\x16\x15\x76\xbd\xf0\x32\x0f\xe5\x3c\x30\x7d\x9c\xde\x42\x60\x77\xa7\x67\x7c\xde\x3c\x1b\xc8\x3e\x18\xe6\x0a\x0c\x4e\xe6\xdc\xcd\x87\x7c\x21\x3a\x8e\x4c\xca\x64\x0e\xe0\x49\x29\x80\x45\x70\xae\x1f\x96\x15\x7c\x04\x35\x7a"}, +{{0xb8,0x09,0x36,0x1f,0x55,0xcf,0xe8,0x13,0x7f,0xbd,0xa8,0x80,0xfc,0x62,0xcb,0xe4,0x4c,0x21,0x6e,0x14,0x18,0x93,0x34,0x63,0x02,0xb3,0x36,0x04,0x5d,0xe2,0x18,0x78,},{0xfd,0x23,0xe4,0x2f,0xf0,0x66,0x44,0xea,0xd3,0x47,0xab,0xcc,0x1b,0x3e,0x03,0xb0,0xe8,0x85,0x93,0xb6,0x12,0x54,0x98,0x1d,0xd8,0xae,0x59,0x45,0x4e,0x61,0xb3,0xe0,},{0xb5,0xb5,0x95,0x0d,0x37,0x72,0xd2,0xee,0xf8,0x8e,0x1b,0x0f,0x5d,0xf5,0xff,0xae,0x2f,0x21,0x03,0x88,0x5e,0x71,0x44,0x6d,0x34,0x6f,0xbb,0x5d,0xae,0xf9,0x49,0x67,0xa6,0xb7,0xb6,0xe4,0xbe,0x88,0x51,0x10,0x06,0x58,0x76,0xc6,0x65,0xb7,0x81,0x2d,0xe4,0x6a,0xd3,0x1e,0xc3,0xbf,0xcb,0xea,0xee,0x13,0xed,0x0c,0x1e,0x0b,0x30,0x0e,},"\x17\xac\xe1\x97\xd0\x83\xaa\xf1\x72\x6f\x53\xe5\xef\x81\xb5\xa8\xc0\x92\x22\xf2\x60\xee\x5f\x1f\x54\x04\xab\x78\xd9\x00\xd4\x89\x68\x84\x49\xb8\x43\xba\xd3\xc4\x98\xaa\xc6\xd8\x0b\x46\x39\xb7\x6e\x6e\x81\xc5\x52\x76\xa6\xf9\xc7\xce\xcd\x70\xb7\x1a\xaa\xf2\x01\x8e\xf7\x6c\x0e\x30\x15\x4a\xae\x86\xa5\xc8\x6d\x4e\x8d\x0e\x4e\xc6\x8c\xc4\x27\x06\x0b\xd5\x65\x14\xf7\x23\x80\x86\xbb\xef\x5b\xfc\xa1\xf5\x67\x1b\x18\x04\x18\x38\xfd\x01\x35\x72\x44\x3d\xba\x48\xfb\xdd\x95\xca\x74\x0b\x0d\xaa\x43\x27\x16\x4a\x1e\x34\x67\x72\x49\x70\x8f\x77\xbd\x79\x3e\x7c\xaa\x66\x38\xb5\xdc\x9f\xbe\x6f\x0d\xfd\x41\x20\x20\x90\x97\x20\x9c\x93\xce\xdf\xaf\x21\xb6\xbf\x59\xca\x6e\x99\xe6\x20\x96\x39\x44\x4f\x0e\x82\x7b\xbc\xc0\xa6\x1c\x3a\x23\x7c\xa2\x2a\x28\x32\x13\x22\x3a\xb6\x58\xe7\x12\xc7\x55\x62\x38\xd3\xa5\xfe\x31\x72\x2d\x65\xf5\x70\x6e\xf6\xd6\x4d\x73\x23\x2d\x30\x43\x22\x0f\x14\xe5\xcf\xd3\xc2\xc8\x3a\x83\xd6\x8e\x20\x27\x4b\x6f\x96\xb2\x9d\xe0\x40\xce\xc8\x47\x50\x30\xb6\xa8\xa8\x7d\x29\x80\x8d\xd3\x81\x79\x5c\x3d\x22\xac\xf5\xdc\x19\x3b\x72\x0d\x95\xa7\x52\xd9\xf1\x23\xc2\x09\xff\xba\x00\x4e\x48\xdd\x06\xdd\x8c\x9e\x17\x2b\xc9\xe0\x87\xd8\x0b\xc5\x21\x6c\x0b\x0b\x6e\x77\x03\x12\x41"}, +{{0xee,0xef,0x80,0x74,0xc2,0xeb,0x9a,0x1c,0xee,0x2f,0x2d,0x3b,0xb0,0x53,0x25,0x54,0x6a,0x9f,0xb7,0xcb,0xe4,0x4b,0x59,0x94,0x61,0xfc,0x58,0x85,0xf5,0xfd,0x9c,0xac,},{0x9b,0x89,0x29,0x41,0xa0,0x57,0x3b,0x7a,0x16,0x73,0xef,0x48,0x0f,0x08,0x11,0x68,0xd9,0xb7,0x49,0x6a,0x81,0xf9,0x17,0x7d,0xc4,0x27,0xca,0x1f,0x84,0xcb,0xbf,0x7d,},{0x6f,0x71,0x01,0x98,0x4f,0xd6,0x89,0x2e,0x21,0x44,0xb7,0xd4,0x56,0x19,0x83,0x0c,0xae,0xb6,0x71,0x3b,0xfa,0xb4,0xee,0xbb,0xe2,0x17,0xc5,0xbe,0xcd,0x24,0x9b,0xd9,0xd7,0x52,0xeb,0x76,0xe9,0xfa,0x99,0x5e,0x7c,0x71,0xff,0x7d,0xf8,0x6b,0xb2,0x60,0xcd,0xda,0x17,0x3f,0xf5,0xde,0xec,0x6a,0xf2,0x04,0xb7,0xdd,0xe0,0x11,0xde,0x09,},"\x9a\xe3\x9f\xea\xde\x90\x5a\xff\xcb\xed\xd2\xe7\x2a\x6f\x24\x29\xb3\xd1\x10\x8e\x5b\xc1\xa9\xdb\xaf\x49\x0a\x62\x99\xbc\xcd\x94\xac\xc4\x13\xad\xac\xc9\x18\xb1\x4a\xfa\x85\xc7\x8b\xc1\x68\xcc\x00\x74\x0c\x3d\xa0\xe0\x81\x83\x91\x5f\x79\xb7\xfe\x38\x68\xce\x2a\x7e\x88\x6b\x32\xad\x45\x00\x98\x05\xbf\xb8\x1b\x8c\x07\xb3\xb1\x02\x24\x20\xc0\xf0\x09\xb8\x89\xd7\xfc\x22\xfd\x19\x97\xae\x34\x19\x84\x38\xca\x94\x77\x85\x75\x12\x2f\xca\xaf\x96\xe6\x50\x2c\x33\xa7\x5a\x12\x9a\x2d\x0d\xbb\x07\x3d\x93\x82\x0d\x9c\x96\x68\x3d\xb3\x18\x99\x0b\xe3\xfe\xf4\xca\xfc\x89\x0a\xfb\xd9\xb1\x50\x4c\x74\x39\xa0\x8a\x06\x5e\x78\x14\xee\x4f\x9b\x6f\x57\xee\x16\xba\xed\x3f\x0e\x3a\xa3\x5d\xd2\x3d\x35\x28\xa4\x58\x91\x9a\xd7\x70\x48\xb4\xe2\xe6\x17\x23\x46\xbe\x24\x9a\x50\xaf\x02\xbc\x6c\x85\x33\x04\xc2\x08\xae\x0b\xa0\x27\x71\x26\x2a\x0d\x8a\x46\x5f\x71\xfa\x06\x35\xe5\x3e\xb2\xef\x0a\x84\x7d\x56\xa0\xbc\xd7\xdd\x3f\xe0\x77\xc9\x2b\xcd\xca\x30\x69\xa4\xa6\x82\xa2\x85\x99\x28\x31\x5c\xe3\xeb\x44\x5c\x60\x72\xa7\x14\x92\xee\x82\xe1\x72\xa2\x0b\xe0\xb6\x48\xb7\x56\xe6\xc7\x75\x37\x6f\x0c\x7c\x3d\xf8\xe6\x42\x88\x08\x9c\x2f\x81\xce\x95\x93\xc6\xe0\x8b\xb1\xcc\x1b\x27\xfc\xbd\x39\x2f\xc7\x95\x2c\x55"}, +{{0x61,0xfa,0xeb,0x15,0xf8,0x57,0xf6,0x55,0x78,0x62,0xc8,0xb8,0xc7,0xef,0x41,0xf8,0x05,0x45,0x52,0x09,0x96,0xfc,0xc1,0x12,0x7b,0x8c,0x24,0x91,0x82,0x22,0x01,0xae,},{0x60,0xa2,0x90,0xc0,0xfc,0x42,0x5a,0x08,0x74,0x67,0x3d,0x94,0xf9,0xbb,0x14,0x00,0xf9,0xda,0xcd,0xe9,0x95,0x4f,0x9f,0x5b,0x05,0xdd,0x48,0xab,0x74,0x7a,0x39,0x50,},{0x31,0xf9,0x0f,0x50,0xb2,0xdc,0x70,0x5f,0x1d,0x92,0xf1,0x2c,0xa9,0x97,0x5d,0x76,0xf1,0xb2,0x82,0x6a,0xda,0x3c,0xc1,0x85,0xb0,0xed,0x6c,0x83,0x86,0x07,0x77,0xbd,0x8c,0x48,0x9b,0x59,0x85,0x5a,0x91,0xf6,0x48,0x39,0xd4,0x9b,0xa4,0x67,0x98,0x5a,0xbb,0x37,0x6c,0x47,0xa4,0x90,0x8b,0x27,0x1b,0x8f,0x77,0xc5,0x8d,0x01,0xfd,0x04,},"\x25\x3b\x56\x6e\xcc\xb5\x63\xbd\x6e\x48\x0c\x69\x73\x9b\x8e\x37\x25\x19\xa3\x43\x72\x54\xe0\xe5\x02\x9c\xac\x86\xc7\x16\x38\xf2\xdf\x2a\x6c\xf9\xe5\x6d\xb2\x56\x99\x34\xde\xba\x90\xdb\x75\x54\x7e\x36\x71\x74\x7d\xf6\x4d\x6f\x2a\xaf\x3c\x11\x0f\xa6\x7a\x70\x94\xcc\xbe\x4c\xc5\x35\x5f\x0d\x43\x23\x51\x36\xee\x26\xdb\xe3\x7f\x42\x25\xd3\xbb\xfe\x24\x55\x95\x28\x05\x85\xfb\x54\x8f\x89\x4e\x86\xc5\x16\x10\x25\x80\x29\x1f\xa7\xa0\x28\x59\x55\x7f\xb9\x8e\xb5\x88\x87\x08\x28\xb0\x99\x0a\xe9\xd7\x4f\x38\x31\xda\x58\x94\x6b\xc7\xa5\xce\x1b\xa4\x98\xb4\xe8\xbe\x89\x89\xa3\xb5\x0d\x7e\x87\x89\xf5\x6b\x8b\x4f\xec\xbc\x2a\x33\xbf\xa3\xef\x59\x1a\x0f\xbc\xd9\x32\xfa\x93\xe1\x9f\x3a\x81\x2a\xe5\xe4\xe3\xb4\xb2\x42\xbe\x77\x05\xa5\x87\x4a\xf7\x3b\xe3\x10\xb0\x05\x82\x66\xa3\x78\xf2\x3c\x13\x48\x52\x47\x15\xb0\xcc\xc1\x8d\x66\x34\xb2\x36\x36\xc3\x16\xba\x6a\x1d\xd2\xfd\x50\x92\xc0\x67\x16\xa7\x17\xb5\x4d\x0e\xb9\xfc\x7f\x63\x6f\x85\xbb\xf2\x25\xa2\xcf\x03\x5b\x4b\x7c\xfd\xdd\x75\x35\x16\x82\xc0\x57\x6c\x6b\x3b\xa5\xa1\xc0\xb2\x5e\xc5\x94\xe7\x70\x9d\xd0\x9a\x00\x79\x77\x2f\xf3\xac\xc6\x7f\xb6\xc1\xb3\x7b\xb3\x74\x2b\x72\x6e\x77\xe8\x05\x61\xd9\xab\x73\x16\x0b\x73\x36\x25\x81\xda\x5b\x9c\x7f"}, +{{0xe6,0xb9,0xcd,0x4d,0xa0,0x7c,0xb3,0x4f,0x30,0x39,0x1c,0xf6,0x8f,0x0d,0x87,0xc7,0xcf,0xcf,0x68,0xf8,0x10,0xff,0xa4,0x0f,0x97,0x39,0xc9,0x5d,0xeb,0x03,0x7f,0x71,},{0x56,0x9e,0xde,0x0f,0x04,0x63,0x0b,0x43,0xa0,0x4c,0x5a,0x66,0xb6,0xa5,0x63,0x6b,0x76,0x6c,0x75,0x96,0x59,0x84,0xa7,0x47,0x7e,0x15,0x49,0x19,0x60,0xfd,0xd8,0x64,},{0x1e,0x37,0x5c,0x94,0xbd,0x80,0x9c,0xa0,0xcd,0xd0,0x2f,0x89,0xec,0xec,0x4e,0x43,0x77,0x32,0xdd,0x20,0xa0,0xa8,0x4b,0x25,0x4e,0xae,0x88,0x9d,0x80,0x70,0xe6,0x82,0xd1,0x13,0xb0,0xbe,0x22,0xe4,0x1e,0x6c,0xdc,0x3b,0xe8,0x77,0x68,0x0e,0x7e,0xeb,0x7f,0x09,0x95,0xe6,0x62,0x2d,0xc0,0xb4,0x34,0xfb,0x09,0x49,0xdd,0x99,0x4b,0x0c,},"\x69\xde\xf0\x52\x3a\xfd\xa6\x96\xf8\x44\x8f\x9c\x11\x43\xab\xc2\x65\x33\xe6\x86\x95\xa0\x90\xdf\x0d\x9e\x43\xd0\xc0\xef\xf4\x35\x83\xe6\xf7\x09\xd2\x04\x3c\x81\x5f\xbb\x3f\x96\xba\x2b\x0d\xc3\xbe\x6f\xec\xad\x5d\xd3\x81\x48\x78\x8e\x4a\x03\x85\xa9\xfe\x7a\x92\x1f\xcb\x8c\xce\xe0\xe4\xd3\xae\xd4\xbc\x3d\x21\x6d\x84\xb4\x14\xf9\x58\x0b\x02\x82\x0c\x03\xd9\x2e\x67\x5e\x68\x5c\x4b\x58\x51\xf3\x63\xbb\x4d\xf9\x7b\x41\x7c\x3f\xd9\x00\x22\xee\xaf\xa2\x0d\xfb\xe8\x29\x64\xf2\xff\x07\x3d\x25\x57\x58\xfb\xe5\x67\xc7\x6b\x2c\x35\xe2\xb0\x9f\x8a\x8d\x7a\xfa\x32\xc6\xf5\xad\x01\xbc\x3e\xbf\x6e\x21\x06\x06\xdb\x03\x8e\xcb\x68\x20\xce\x1e\xa4\xdd\x52\x9f\xc1\xad\xfb\xc2\xa1\x38\x56\x5a\xc6\xd0\xf4\xa4\x10\x9b\xdd\x47\xb8\xaa\x6e\xf4\xb8\xbe\xde\x45\x46\x80\xd1\xdb\xdb\x75\xfe\x1e\xb2\xe5\x48\xd5\xde\x7c\xb6\xd7\x92\xfe\xf3\xaa\x0d\x84\x80\xa6\x03\x0b\x30\xf1\x04\xd7\xe7\x6b\x58\xe9\xf4\x76\xeb\xf2\xcc\x83\x29\x23\xb5\x0c\x50\xc1\x11\xc3\x51\x5f\xc5\x18\x85\x23\x23\x42\x6c\xa7\x78\xa5\x96\xd3\x19\x5d\xa8\x58\x5d\x8c\x3a\xa9\x20\x83\x31\x3a\x6e\x65\x85\xb7\x0c\x98\xb1\x85\xb4\x72\x79\x8a\x61\xcd\xe7\x7e\x62\xec\x27\x2f\x14\xb0\xd9\xeb\x4f\x22\xf9\xc7\xc0\x58\x17\xda\x6f\xde\xfe\x78\x79\xa5\x84"}, +{{0x4d,0x90,0x44,0xf1,0x7b,0x5a,0x09,0x77,0xdc,0x5a,0xa9,0x91,0x6a,0x92,0x43,0x00,0xa2,0x44,0xa1,0xef,0x7f,0x06,0x02,0x77,0xad,0x49,0x78,0x35,0x1e,0xa6,0x42,0x91,},{0xab,0x9c,0x06,0x92,0xa6,0x06,0xb2,0x56,0x7c,0x19,0xc3,0x0f,0x9f,0xaa,0x3b,0x4c,0xfe,0x72,0xfb,0x23,0x70,0x77,0x76,0x7b,0x76,0xd3,0xb2,0xae,0x14,0x90,0xa6,0xd4,},{0x6f,0xa4,0x8a,0xea,0x4d,0x5b,0x9a,0xf6,0x5a,0xf9,0x64,0xcd,0xb7,0x09,0x44,0x3a,0x11,0xfa,0x84,0xf7,0xd4,0x4a,0xcd,0xda,0xb1,0x6e,0x04,0xa6,0xfc,0xef,0xb2,0x7a,0xe3,0x3c,0x05,0xb3,0x6d,0xa1,0x3c,0x23,0xde,0x51,0x7d,0x6e,0x6a,0xc5,0x74,0xa0,0x3e,0xa6,0x30,0xba,0x4f,0xbb,0x95,0x81,0x31,0x12,0x9a,0xa7,0xf1,0x35,0x4c,0x01,},"\x7c\x8c\x71\x89\xaf\x67\x32\x7a\xf1\xc6\xdd\x2c\x30\xe9\x75\xf1\x90\xe3\xb3\x8d\x00\x8b\x45\x85\x16\x7e\x0d\x45\x07\x40\xd4\x67\x34\x58\x7f\x6d\x20\x87\x84\x24\x5c\xc5\xcb\x06\x2a\x2a\x27\x7f\x17\xeb\xb2\x74\x6f\x9b\xdf\x4a\x82\x37\xca\x47\x9a\xb0\xa4\x30\x17\x7e\x19\xed\x7d\xd3\x62\x25\x76\xb1\x4c\xdc\x08\x28\x22\x14\xfe\x5e\xe4\xd7\x6b\x43\xc1\x6a\xc9\x08\x64\xc5\x1b\xe8\xae\xd4\x5d\x7b\x98\x0d\xf7\x91\x7f\x29\x0f\xdf\x79\x58\x46\x46\x5f\x27\xfc\xb7\xe5\x73\x06\x37\x94\x4f\x05\x77\xc9\x2f\x32\x37\x5e\x99\x5b\xc0\xcd\xa9\xd7\x19\x6f\x2c\x0c\x1a\xc8\xb8\x0d\x12\xa0\x43\x99\x63\xeb\xd2\x25\x4c\x34\x77\x03\x57\x58\x16\xe7\x96\x4c\x13\xd4\x4d\x62\x92\x80\xc3\x12\xea\x26\x53\x44\xde\x38\xf3\xb1\x8d\x91\x50\xf8\xf9\x24\xaf\xb4\x4b\x6b\xfb\x9e\xda\x51\x3d\x59\xe6\x5e\x2e\xf1\x86\x66\xe6\xc2\xa2\x1c\x40\x18\x66\x5b\xef\xe9\x2c\xae\x58\x1d\x3c\xb1\x4e\x23\xe9\x7d\x83\x00\x02\xcb\x90\x93\x1a\xe0\x21\x00\x68\xaf\x39\x4e\xbe\x35\x1b\xe5\xb8\x17\xf3\x67\x4b\xfb\xf4\x00\x49\x03\x0e\x4f\xe5\x05\xd3\x4a\x1d\x50\x2a\x2c\x50\xd8\xe6\x38\xe9\x26\xc2\x30\x67\x6b\x7e\xde\xfb\x6b\xec\x77\xb1\xc0\xce\x60\x93\x25\x28\x7b\xa5\xfd\xd7\xa9\x97\x69\x87\xbd\x07\xfc\x6a\x43\x44\x95\x6e\xbf\x81\x8f\x08\x58\x6c"}, +{{0x75,0xad,0x76,0xbb,0x4c,0x0c,0x22,0x9a,0x5a,0xdc,0x79,0xe4,0x44,0xb1,0x3f,0x88,0xa9,0x64,0x59,0x86,0x2c,0x8c,0xf0,0xba,0x49,0x8d,0x0c,0x99,0x6a,0xf9,0x4a,0x7a,},{0xf0,0x74,0xdd,0x2b,0x9c,0x1c,0x30,0x91,0x05,0xec,0x95,0x1b,0xb5,0x81,0x2a,0x91,0xdd,0xb5,0x40,0x23,0xb3,0x80,0x9a,0xb3,0x79,0xc5,0x6a,0xf0,0x46,0x1a,0xf6,0x17,},{0x0c,0x46,0x43,0xa8,0xbe,0x6d,0xc2,0x2f,0x4b,0xeb,0x6b,0xcc,0x70,0xc6,0x17,0x2e,0xc7,0x60,0x83,0x78,0x65,0x3c,0xb4,0xe9,0x9f,0x3a,0xe7,0x95,0xea,0xdf,0x4e,0x98,0x2a,0x29,0x76,0x09,0xca,0x79,0x38,0xf5,0xdf,0x63,0x2b,0x09,0x56,0x28,0xcb,0x75,0x06,0x2d,0x3d,0x51,0xfc,0x0f,0x33,0x23,0xbf,0xa7,0xb2,0x2e,0xc4,0xd4,0x72,0x05,},"\x0c\xa8\xc1\xc7\x41\x28\xd7\x4e\x9d\x0a\x7b\xf8\x96\x42\x91\xd0\x74\x91\x7f\x2f\x99\x20\xef\xb9\x11\x52\x05\x67\x64\x2a\x50\xa6\x15\xab\xcb\xd0\x0a\xed\x4a\xbb\xfe\xf1\xa9\x83\xcc\xe3\x33\xe1\xd0\xdf\x3e\x64\x04\xfb\x90\x43\xc6\x80\x39\x14\xcd\x5f\xff\xbc\x66\xa0\x79\x0c\x78\x78\xa2\x40\x89\xa5\x71\xf8\x95\x66\x2a\x1d\x18\xbe\x3f\x01\xff\x97\xfb\x33\x23\x33\x4b\x6f\x5b\xaf\x96\x55\x14\x48\xe4\x09\x0d\x03\x3c\x46\x42\x94\xd0\x91\x33\xb1\x51\xd5\xb5\xc6\x32\x1b\x50\xe2\x24\x1d\xe0\xef\x6f\x88\x28\x89\xcc\xf4\xad\x35\x40\xd5\xa1\xe3\xf7\x54\x8f\xb1\x3b\xe7\x1c\x16\x51\x66\x06\xe7\x9d\x04\x49\xc2\xa0\x8e\x5d\xc2\x31\x48\x84\x3c\x84\xe9\x7e\xd2\x40\x69\x16\x1c\x8e\x75\x20\x8f\x33\xe9\x5b\x3e\x10\xd1\xd4\x9a\x2f\xae\xf9\xd9\x86\xab\x62\x80\x9f\x62\xad\x39\xc7\xcc\x87\x1f\x37\x5a\x4f\x5a\x6f\xaf\x10\x4d\x7e\x11\xb8\x90\xcf\xb0\x58\x99\x02\x68\x52\x16\xec\x07\xcb\x8e\x8e\x9e\x7a\x7c\x43\x63\x5e\x23\x21\x2b\x69\xca\x3b\x7e\xd5\x4f\x0b\x97\x94\x9e\x3d\x9a\x66\x62\xf8\xe4\xb3\xab\x09\xcd\x49\x52\x94\xc3\x31\xc0\x47\xd8\x6e\xe7\x85\xff\x65\x8b\xcd\x7f\xcf\x9c\x48\x06\x05\xce\x05\xe8\x10\x06\x8d\x60\xfc\x9b\x26\xb5\xf0\x63\xeb\x90\x00\xd2\x65\x7a\x50\x94\x28\x4a\xc8\x0f\x13\x75\xd0\xb6\x6d\x6f\x5f"}, +{{0xad,0xc6,0xe9,0xb2,0xe1,0x03,0xb6,0x2c,0x24,0xad,0x43,0x46,0x41,0x0e,0x83,0xa1,0xa0,0xbd,0x25,0x3e,0x4a,0xbf,0x77,0x91,0x18,0x50,0xc6,0xd9,0x66,0x6e,0x09,0xf9,},{0xfc,0xe3,0x16,0xe3,0x3c,0x91,0x08,0x21,0xbe,0xed,0xdd,0x63,0x4b,0xed,0xc5,0x8e,0xe5,0x79,0x99,0xa7,0x6e,0xce,0x38,0x46,0x05,0x28,0x3b,0x99,0xb5,0x43,0xb7,0x8b,},{0xcb,0x01,0x7d,0x6d,0x26,0x82,0xc9,0x85,0x43,0x66,0x25,0x9a,0xa3,0x5f,0x30,0xd4,0x91,0xcf,0xaa,0x93,0x09,0x98,0xc2,0x97,0xdb,0xdd,0xc6,0xad,0xed,0x5b,0x3d,0x40,0x1c,0xf7,0x6d,0x80,0xd8,0xa2,0x76,0x4d,0xe1,0x31,0x71,0x8b,0x6e,0x0c,0x48,0x1d,0x71,0x96,0xbc,0x72,0x57,0x97,0x16,0xb0,0xc0,0xf6,0xff,0x05,0x3e,0x68,0xc5,0x0c,},"\x8c\xcc\xd9\x8e\xbb\xf2\x43\x9f\xfd\xfa\xc4\x16\x87\x63\x8f\xaa\x44\x4e\x1c\xa4\xb6\x3d\x13\xe8\x98\xea\xa8\x35\x54\x92\xf2\x88\x13\xab\x81\x3f\xd0\x15\x10\xe1\x12\xbe\x10\x6b\x20\x45\xd3\x0f\x63\x33\x5d\x24\x89\x04\xd5\x21\xde\x18\x1a\xba\xc0\x3e\x3d\x2c\xb2\xd1\x6c\x44\xb3\xb0\x12\xa0\xc5\x1f\x99\x01\xae\xf9\x05\x6c\x72\x4d\x7a\x2c\x6b\x2a\xcb\x0a\x07\x55\x59\x40\xe4\xc6\xe2\x11\x54\x89\x06\x11\xad\xeb\x64\x89\xf4\x61\xd3\xe5\xec\xd1\xaf\x5a\x4d\x2b\x0a\xda\xf4\x17\x47\x43\x6e\xb4\x14\x75\x7a\x8f\xe4\x77\x56\x74\xe3\xc6\xe5\xde\x45\x69\xd6\xfc\x6c\x78\x8e\x10\x90\x5e\xba\x32\xc2\x70\xa3\x93\xe6\xf7\x21\xa7\x65\x29\x4e\x2a\xc9\x9a\x9b\x6e\x53\x4d\x3d\xf0\x8d\x1d\xb9\x7d\x60\x2a\xc3\x19\x5c\xb0\xb7\x7f\x5b\xd4\xac\xaf\x73\x7f\xad\xd6\x99\x1f\x06\x88\xab\xc7\x49\x18\x04\x75\x74\xea\xc2\x82\x89\x73\x9a\x66\x4e\x0e\x0e\x20\x57\x4a\x2c\x25\xfd\xe4\x9d\x14\x53\x9d\xb1\xce\xdd\x4a\x92\x04\xa7\x0a\xcf\xf0\xa6\x2c\x8f\x25\xcd\x76\x8f\xfa\xb1\x5c\x4d\xb3\x16\x84\x0a\x4d\x1b\xc9\x2e\x21\x26\x70\xbe\x07\xc5\xbd\xcf\x53\x75\x90\x60\x7d\xfb\xbb\xb4\xd9\xf9\x8b\x89\xda\x0b\x4d\xf7\xd8\x8f\x3e\xca\x48\x14\xd1\x6b\xfa\x20\xc8\xd2\xfa\x94\xf9\xf2\x59\xf2\xee\x2d\x3a\x83\xc9\xe4\x17\x1b\x1a\x26\x2c\x4b\x99"}, +{{0x37,0xfc,0x1b,0xed,0xa4,0x06,0x0b,0x6c,0x57,0x88,0x3d,0xdb,0xa0,0x77,0x6c,0x2b,0xcf,0x5a,0xc2,0x8a,0x65,0x13,0x26,0x02,0x1c,0xca,0x97,0x72,0x37,0x30,0xfb,0xb0,},{0x7b,0xd7,0xbf,0x1c,0x99,0xdc,0x82,0xe0,0x6f,0x08,0xbb,0x45,0x4d,0x8f,0xb2,0x88,0xa5,0x79,0x27,0xe0,0x7f,0xf1,0xb1,0x2a,0xf1,0x5e,0xe2,0xc1,0x2f,0xbb,0x6b,0x3d,},{0xa0,0x1d,0xd6,0x5f,0xad,0xa2,0x70,0x39,0xf1,0x68,0xb1,0x23,0x41,0x9d,0x8a,0xbf,0xbd,0xa4,0x8c,0x57,0x2e,0xce,0x24,0xfd,0xa0,0x6e,0x1a,0x5e,0xc3,0x1e,0x08,0x4f,0x4e,0xe1,0xcb,0xf9,0x96,0x1e,0x88,0xed,0x51,0xe1,0x89,0xfc,0xb7,0xf5,0xf2,0x35,0xde,0x1e,0x5b,0x28,0xd0,0x8f,0x2b,0xfc,0xa1,0x90,0xb0,0xf0,0x19,0xec,0xc2,0x07,},"\x3d\xfc\xac\x02\x65\xa0\x24\xa8\x3c\xb9\x32\x67\x44\x89\xa1\x63\xaa\xc3\x14\xbf\x3d\x96\x9f\x27\x59\x6e\x45\x17\x33\xb9\x9d\xeb\xa5\xee\xb7\x79\x21\x0b\xaf\x95\xbf\x54\x5a\x1a\xe6\xb8\xa9\x15\x86\x06\x93\xee\x89\x0f\x93\x93\x20\xe0\x6a\x84\x44\x83\xd1\x8c\x6a\x1b\xcd\x03\xc6\x38\xbb\x7d\x1f\xe2\xa8\x2e\xb4\x48\xa3\x11\xb1\x30\x2e\xa6\x42\x8f\x54\xa3\x9f\x45\xa4\xd5\x60\xbe\x15\x57\xa2\xb2\x54\xc4\x5c\x13\x7f\x45\xcc\x68\x35\x68\x36\xe2\x1b\xed\x0b\x7f\x73\xa5\x18\xce\x09\xdb\x0b\xe3\x93\x92\x7c\x33\x9b\xf2\xa4\xb5\x98\x75\x39\x40\x4c\xe6\x50\x28\x4d\xe1\x2e\x3b\x55\x3b\x26\x2e\xfe\x23\x84\x83\x32\xcc\xfd\xc3\x5e\x79\x1a\x0a\xb4\x3f\x13\x9c\x71\xed\x0f\xcb\x2d\x17\x3b\xb3\x77\xee\x46\xb1\xa9\xdc\xa9\x27\x7e\x77\xdf\x85\x5f\x28\x30\x25\x1e\x31\xe2\x6a\xcd\x86\x76\x3c\x8d\x7e\xac\x22\xc8\x82\xfc\x17\x4f\x2b\x5e\x75\xca\x6a\xd1\xad\xe0\x3f\x94\x2b\xb2\xa1\x3b\xf5\x41\x90\x61\x59\x15\x8c\x68\x36\x3c\x74\x80\xc5\xb2\x7a\x99\x32\x0f\x82\x83\xa2\x69\x9d\x43\x69\xc0\x71\xc5\x0d\xbd\x90\xb7\x79\x2e\x47\x72\xef\xbc\x0b\x19\x5b\xce\x84\xcc\x4d\xcf\xff\x70\x72\xa4\x89\x68\xdb\x69\xf9\xfe\xdd\xd0\xf9\xce\xd6\x59\xeb\x5d\xb7\x16\x7f\x35\xf9\x88\xce\xc1\x14\x88\x7d\xcb\xfd\xf2\x7d\x02\xd3\x00\xb3\xe1\xab\xec"}, +{{0x8d,0x42,0xf4,0xdd,0xd2,0xbb,0xd2,0xb8,0x27,0xb0,0xa0,0xd3,0x1d,0x8f,0x75,0x8e,0xbd,0x13,0xa1,0xb9,0xb3,0x71,0x22,0x28,0x94,0x8c,0xa6,0x10,0xbb,0x88,0x58,0xe5,},{0xb7,0x35,0x48,0x98,0x79,0x4f,0x9d,0xb0,0xa8,0xaf,0x6e,0xea,0xfc,0xdb,0xdf,0x01,0x1d,0x3f,0xbe,0xf0,0x21,0x2a,0xd9,0x38,0xa4,0xa4,0xad,0x27,0xab,0x16,0xeb,0xbf,},{0x70,0x76,0x4b,0xe3,0x9c,0x6d,0xca,0x0f,0x06,0x7a,0xbe,0x1e,0xca,0x49,0x0f,0xda,0x95,0x1f,0xd4,0xe9,0x49,0x96,0x95,0x26,0x6e,0x27,0x0b,0x9b,0x05,0xea,0xe7,0x06,0xca,0x8d,0x1c,0xa6,0xa9,0x2d,0x7c,0x48,0x8e,0xc6,0xad,0x8b,0xa1,0x14,0x57,0xa4,0x2a,0x5e,0x31,0x70,0x2a,0x9c,0x2b,0xce,0x89,0x2d,0xc4,0x05,0x35,0xc0,0x9f,0x01,},"\xe3\xa2\xbe\xbc\x04\x96\xd8\x97\x4a\x8f\x40\x61\x88\x03\x69\x31\x4e\xd9\xe4\x40\xc1\xb7\x7e\x26\xfe\x50\x71\xce\x69\x4f\xfd\x21\x36\xdb\x0c\x4d\x5e\x88\x0e\x60\x00\x08\x3a\x75\xc9\x0d\x3c\xf7\x2b\x9c\xf5\xa2\xb1\xa9\x00\x2c\x27\x01\xa2\xff\x59\xb0\x69\x9a\x8f\x42\xd7\x9d\xd8\xa5\xfb\x71\xa8\x12\x54\x53\xd9\x1f\xb8\x00\x80\xa3\xf0\xa1\x65\x84\x28\x2f\x17\xec\x7d\xfd\xc2\xe5\xc6\x9c\x4d\x9b\xdf\x48\x4d\x55\x94\x4d\xae\x27\x3f\x21\x1c\xfb\x76\xad\x37\xda\x45\x87\x13\x65\x43\x9a\xf3\x5e\xea\x1f\xbe\xcd\x4c\xa6\x79\xb5\x9b\x5e\x01\xba\xcf\x49\xc7\xf4\xe5\xef\xaa\x40\x6b\xa1\xda\xeb\x08\x54\x82\xaf\x5d\xed\x89\xdc\x68\x85\xff\xbe\x3d\x14\xd2\x93\x1b\x83\x89\x7e\x28\xad\x06\xe5\x56\x4e\x27\x89\xba\xea\x81\xbd\x93\x2a\xa2\x79\xfe\x8e\x32\x4b\x9a\x8e\xf1\x11\xc2\xab\xe2\xf1\x37\xd4\xbb\x50\xd8\xab\x76\xce\xbc\x0b\xd9\x82\xa2\x39\x19\x75\x1a\xd4\xd4\x9e\x88\xeb\x14\x17\x3d\x33\x10\x28\x9a\x87\x23\x17\xe4\xa4\x51\xe8\x8d\x54\x32\x08\x91\x87\x0f\x15\xb2\xd5\x33\x24\x43\x08\x77\xa9\xfb\x5b\x49\xbb\x92\x9f\x21\x1c\x5b\x89\x76\x4d\xd9\xc3\xa5\x95\xa1\x45\x1e\x9f\x85\xa2\x38\x54\x00\x02\x56\x6e\x53\xa9\x9e\xd1\xe6\xdd\xc9\xb4\x85\x3f\x45\x5e\xdb\x4c\xf1\x98\x0d\x56\xbb\xdc\x13\x13\xa3\x6e\x76\xea\x9c\xbb\x04\x8a"}, +{{0xb6,0x2d,0xe5,0xa1,0xac,0xfe,0x4c,0xa2,0xd1,0xf0,0xc1,0x32,0xaf,0xcb,0xda,0xe6,0x6f,0xb2,0x9a,0x02,0xf2,0x97,0xfb,0xc2,0x40,0x7f,0xad,0xbb,0xf2,0x45,0x42,0x00,},{0xb6,0x3b,0x2d,0x0b,0xf3,0x55,0xf7,0xb6,0xd0,0xba,0xc0,0x74,0x03,0x41,0x1c,0x40,0xaf,0xbb,0xb2,0xf7,0x07,0x50,0x3b,0x3f,0xc2,0xce,0xe8,0xa1,0xc7,0xd0,0xa8,0x38,},{0x5c,0xdb,0x00,0xe9,0x8d,0xe7,0x3e,0xab,0x48,0x0b,0xe4,0x2f,0x8a,0x8a,0x61,0x63,0x80,0x9a,0x0d,0x37,0x10,0x1b,0x6a,0x5a,0x4e,0xed,0x6a,0x0c,0x92,0x03,0x0d,0x09,0xa5,0x56,0x2c,0x72,0x90,0x80,0xce,0x6f,0x65,0x94,0xc8,0xfa,0xfb,0x1f,0x59,0x47,0x72,0xdb,0x7a,0x90,0xa9,0xe7,0xda,0x15,0x89,0x6e,0x82,0xf7,0x05,0x69,0x39,0x0d,},"\xe6\x59\xe5\x1d\x7b\x19\x3c\x4b\x8e\x2b\x3e\xd7\x3a\x9d\x75\x57\xed\x2b\xab\x61\x53\x88\x3a\xb7\x23\x59\x2f\x73\x0a\x91\x45\x67\x14\x2b\x3f\xa4\x35\xdb\x32\x19\xf8\x3a\x54\x2d\xc7\xa4\xbd\x80\x5a\xf6\x66\xea\x86\x5b\x85\x31\x46\xf8\xe3\xa9\xfe\x87\x07\x11\xf9\x0d\x12\xb0\x69\x34\x92\xaf\x2a\x1e\xdf\x99\xa1\x64\x58\xf7\x81\xf1\x26\x6e\xc4\x37\xa5\x29\x6a\x82\x2c\xa9\xd6\x9c\xe8\x44\xb5\xc5\x90\x97\xa2\xa5\x6f\x3e\xb8\xfd\x27\x3a\x63\x61\x16\xdb\x77\x43\x00\x92\x2d\x45\xb7\x44\x65\x7a\x69\x2f\x5e\x8b\xfb\xcb\x06\xd2\x42\x28\x18\xae\xb5\x1e\x7c\xda\x68\xac\xfb\xed\xa1\x6e\x7c\x79\x58\x0d\xcc\xcd\xe2\x4e\x8e\x3d\x60\x1b\x16\xe0\x63\xb4\x3a\x6d\x0d\x14\x07\x55\x2f\x75\x04\xf5\xbe\x19\x88\x2e\x4f\xfe\x32\x34\x4f\x5f\x47\x3e\x73\xa8\xf6\xed\x37\xb0\xd8\xd9\xe5\xe0\xa0\xdc\x98\x28\x39\x5b\xcb\xd8\xf3\xa4\xe3\x12\x48\x69\x24\x9d\x05\x8b\xe0\xe0\x45\xde\x0b\x1e\x12\xb1\xc8\x3b\xa0\xaa\x22\x7c\x95\xb8\x2b\xf7\x42\xc3\xea\xc0\x15\x2b\x33\xe6\xd1\x9b\xe8\xb3\x3a\x35\xbf\x70\x5d\xaa\xb1\x06\x22\xa9\x0a\xed\x02\x2e\xa6\xe4\x39\xed\x50\xa9\x30\x84\x37\x92\x99\x24\xba\x3a\xb1\x11\xad\x0c\xaa\x6f\xeb\x0a\x6e\xb1\x65\x82\x4e\xbd\xb0\x86\x65\x71\xef\xc0\x7e\x52\x22\xed\x86\x86\xb1\x4d\x92\x70\xbf\x76\xb9\x45\xd5\x20\x14"}, +{{0x97,0x32,0x05,0x9d,0x7b,0xf0,0x20,0x0f,0x5f,0x30,0x41,0x24,0x30,0x33,0x6b,0xe4,0xef,0x1e,0x3c,0xae,0x62,0x93,0x8a,0xd0,0x87,0x29,0xce,0x3b,0xa7,0x14,0xcf,0xd4,},{0x0d,0xe8,0x42,0x5f,0x5e,0x30,0xb2,0xb8,0xae,0xbb,0x80,0x72,0x00,0x9a,0x30,0xcf,0x04,0x11,0xc3,0xc8,0x23,0x8f,0x4e,0x42,0x08,0x76,0x0c,0x56,0xc3,0x3e,0x43,0x4f,},{0xfb,0xa1,0x74,0x9b,0x64,0x1d,0xd4,0xdf,0x34,0x66,0x4b,0xc4,0x3c,0x00,0x46,0x8c,0x7d,0x75,0xe8,0x4a,0xfa,0xd7,0x2d,0xe4,0x73,0xfd,0x1e,0x9c,0x87,0xda,0x15,0xea,0x60,0x4f,0xc2,0x54,0x9a,0x1a,0x86,0x7f,0xa8,0x08,0x50,0xe9,0xc2,0xa5,0x9c,0xd9,0x90,0x53,0x88,0x67,0x60,0xa8,0xd9,0x76,0x4b,0x84,0xdd,0x67,0x26,0x76,0x72,0x0d,},"\x1a\x13\xe7\xab\x60\x3b\x48\xeb\x89\x6f\xe1\x71\x73\xfb\x31\x95\x0b\x0d\xcd\x5a\x35\xff\xdb\xe1\x37\x1c\x7a\x5b\xfb\xa5\x93\x31\x75\x89\xd9\x65\x2d\x88\x79\x77\x29\x18\x0b\x8d\x0e\x51\x5a\xbf\xe6\x54\x8f\x16\x04\x21\xe5\x37\xd5\xc9\x4a\xef\x2b\x34\xc7\xeb\xb0\x97\x42\x00\x03\xbc\x0f\x36\x1b\x42\x3e\x7e\x14\x63\x0a\x80\x3c\x11\x82\x02\x54\x00\x49\xf6\x8c\x9c\xf4\x6f\xae\x03\x68\xd1\x62\xe4\x00\xd7\x7b\xb4\x52\x3c\xf6\xc7\x53\xb9\x75\xc2\x45\xbc\x99\xed\x2f\x41\x3a\x9d\x06\xc2\xda\x6c\xe0\xcc\x09\x87\xb6\x40\x6b\x80\x9e\x8e\xb3\x19\x03\x3d\x2d\xe9\x13\x1d\xee\x3b\x1b\x7b\x5c\x95\xd6\x53\xce\xd8\xfc\xcf\x99\x8d\xa1\x76\x85\x11\xec\xa4\xd3\xc5\xf7\x35\xad\xab\x96\x50\x3b\x35\x51\x80\x3e\x49\x22\x63\x50\x95\xef\x81\x1b\xe4\xc0\x8a\x6c\xba\xc9\x17\xcb\xe6\xcd\x91\xa4\xae\x5a\x33\x0c\xce\xc0\xe8\xe8\x15\x37\x12\x17\xa3\xde\x62\xf2\xd2\xd6\x14\x66\x21\x98\x33\xf3\x34\x47\x13\x2f\x4d\x43\x35\x0c\x58\xcb\xaf\x42\x24\x75\xed\xb1\x28\xc5\x6d\x80\xa4\x95\x72\x6b\x1f\xdb\xc5\x65\x51\xeb\x72\xd0\xf4\xfe\xc2\x6b\xa8\xbf\xf5\xee\xd6\x77\x4b\x85\x03\x9a\x52\x92\x83\x4b\x5d\x1c\xc1\xb0\x9b\xa0\xa3\x95\x4d\x29\x32\x36\x73\xf5\xe7\x12\x76\xa1\x2a\xc4\xc5\x79\x35\x5b\xf1\xec\xca\x48\xe6\xa7\x16\xb9\xfc\xec\xdc\x56\x5c\x51\xb9"}, +{{0x9c,0x7f,0x6f,0x37,0x9e,0x38,0x57,0x00,0x7e,0x2a,0xc6,0x32,0x4c,0xbb,0xce,0xd5,0x7a,0xc9,0xee,0xe4,0x47,0x78,0x13,0xf8,0x3a,0x81,0xfc,0x8c,0xef,0xa9,0x64,0xd5,},{0xa5,0x4b,0xa3,0x96,0xd6,0x87,0x63,0x4d,0x3e,0xcc,0xf4,0x1c,0x57,0x82,0x49,0x4f,0x5f,0x10,0xa5,0x21,0xa1,0xe5,0xd3,0x88,0x52,0x3d,0x80,0xee,0xba,0x5b,0x0b,0x2b,},{0x65,0x68,0x5f,0x9c,0xa5,0x98,0x2e,0x15,0xa2,0x2b,0xa3,0xc8,0x3a,0x03,0x48,0x34,0x84,0x82,0xdf,0xae,0x57,0xce,0xa1,0x78,0xf0,0x78,0x0c,0x05,0x7b,0xae,0xbe,0x4a,0xf6,0x32,0xf9,0x84,0x54,0x0a,0x26,0x01,0x9a,0x7f,0xb3,0x42,0x53,0xc9,0xec,0xe7,0xff,0x30,0x8a,0xda,0x23,0x3c,0xe0,0x68,0x63,0x47,0xab,0x5b,0x21,0xce,0x57,0x0b,},"\x3f\x2d\x30\x72\xfe\x73\x83\xe5\x41\x55\x1e\xa9\xab\xdb\xae\xae\x6a\x46\x4a\xe6\xb9\xf0\xba\x78\x6a\x44\x1b\x2d\x08\xda\x5b\xca\xda\x3c\x54\x24\xdc\x69\x31\xd6\xb3\x95\x23\xe2\xde\x0a\x0c\x2e\x4e\x6b\x5b\x8c\xda\x92\x5e\x5e\xac\x93\x84\x16\xa2\xc5\x1b\xf1\x3d\x49\x53\x1d\x7e\xc7\x11\x4b\x1c\x82\xfe\xaf\x90\xf3\xf8\x75\x91\xe3\x97\xd0\x27\x02\xf8\xec\x1b\x30\xd9\x9f\x5b\xe7\xd2\x20\x3e\x4f\xe4\xdb\x2e\xa4\x7e\x7b\x45\x89\xd8\xac\x50\x62\x48\xd7\x34\x74\x66\xed\xbc\x96\xea\x32\xbf\x3a\x6e\xa7\x50\x2d\xd6\x0c\x9e\x84\x90\x27\x15\xab\x2c\x6c\xa6\x8f\x5b\x00\xe1\xd9\x09\xd8\x3a\xa6\xab\x66\x2d\x8a\xea\x87\x0e\xcd\x86\x1f\xec\x69\xf2\xee\xc0\xae\x67\x7d\x29\x95\xb0\xed\x68\x8f\xaa\x8e\xf7\x82\x44\xe0\xd1\x19\x56\x97\xb0\x71\x22\xce\xaa\x11\xf5\xa6\xea\x58\xfb\xdf\xa2\xe2\xec\x2d\xf9\xd1\x86\x93\xae\x96\xd4\x71\x27\x55\x6e\x91\xf0\x86\x49\x82\xc1\x34\x19\xb0\x4a\x63\xf2\x08\xe7\x30\xd2\x69\x51\x88\x2a\xef\xe0\x01\xbc\xa3\x40\x8b\xd9\x86\x27\x48\xc6\xcc\x87\x6c\x28\xca\xc3\xbb\x2e\xb3\x39\x58\x18\xc2\x09\x1e\x0f\xbd\x7a\x0b\x44\x68\xc6\xb0\xd0\x0c\xd0\x08\xc1\x1c\x3c\x3a\xd0\x10\x80\xa1\xf5\xa4\x0a\xe2\xe4\xb0\xc3\xa0\x71\xef\xc8\xe1\xd1\xba\x6a\xce\x6d\x4d\xf0\xff\x19\x82\x9b\x0c\x68\x0b\x3a\xeb\x75\x91\x77\xed\x34"}, +{{0xa4,0x78,0xf3,0x5a,0xbb,0x73,0x72,0x7b,0x6b,0xe6,0xee,0x5e,0x56,0xee,0xc3,0x23,0xc9,0x51,0x78,0x82,0xfd,0x69,0x19,0x36,0x0e,0xbb,0xbf,0x5d,0x5c,0xb8,0xb8,0x3a,},{0x7a,0x6e,0x26,0x6a,0x54,0xd1,0x35,0xdd,0xa0,0x00,0x9c,0xcd,0xa8,0xa9,0x4a,0x47,0x12,0xae,0x5c,0xb1,0x47,0x61,0xe8,0x43,0x6e,0x97,0xc4,0xb7,0x81,0x4d,0x8e,0x8c,},{0x9d,0x16,0xfd,0x40,0xb9,0xf8,0xdd,0x9b,0x4a,0x1a,0x8c,0x6d,0x70,0x3b,0x9f,0xcc,0xbb,0x94,0x0b,0x1e,0x0a,0xe7,0x7a,0x59,0x70,0x37,0x4a,0xf0,0xcf,0x72,0x6f,0x44,0x79,0xfd,0x30,0xd7,0xdf,0xf5,0xcf,0x53,0x49,0x4d,0x9a,0x29,0x6a,0xb6,0xb9,0xe4,0x6e,0xa6,0xc1,0x36,0xb4,0xdb,0x2c,0x71,0xc2,0x1b,0x97,0xc1,0xc8,0x25,0x4d,0x0a,},"\x01\x73\xa3\x40\x50\xb4\x37\x48\x06\x1f\xf8\xf5\xa3\xd7\xc4\x3b\x63\x60\x84\x77\x86\xe8\xbb\x75\xe5\x36\xfb\x47\xb6\x45\xb2\x14\xf2\x21\xba\x24\xd8\x3d\x28\xbc\x02\x50\x24\x66\x3e\x53\x4f\x90\xf6\xe8\x3a\x93\xd8\xbd\xde\xda\x2c\xd8\x80\x81\x55\x65\x2a\x90\x8c\x43\x7c\x2d\xb6\xf3\xed\x49\x12\xf5\x7c\xa5\xb9\x79\x28\xa7\x3b\xe9\x64\xaf\x59\xdf\x44\x39\x85\x4b\xb0\x06\xfc\x29\x5a\x87\xb7\xb7\x22\x39\xc7\xfa\xdf\xec\x40\x71\x55\x09\xd9\x85\x79\xda\xad\xfb\x8d\x52\x4b\x4c\xec\x66\x20\x70\x5e\xfd\x41\x04\xc2\x97\x14\x4a\xea\x72\x29\x74\xe1\x2c\x5e\xce\xe5\x39\x1e\xf2\xd9\x3a\xc2\xb1\x24\xe4\xac\x49\x61\x47\xc8\xb7\x03\x63\x58\x5d\x70\x78\xcc\xc5\x3e\x2a\xe5\x93\x35\x0b\xc2\x55\x48\xa0\x54\x25\x26\xab\x00\xaf\xe4\x77\xa0\xf4\xb2\x73\x97\xc7\x2b\xc7\x4a\x8a\x8a\xb1\x56\xe6\x2b\x8b\xb4\x7c\x3f\xbb\x4b\x34\x91\x3e\x45\x96\x87\x47\x6b\xf3\x31\x42\xc6\x14\x70\x21\x07\xff\xe2\xcc\x01\xe2\x5f\xa3\x02\x75\xe1\xe2\xe6\x3c\xea\x91\x68\xe4\xa4\x7c\x02\xde\x09\x7d\x4d\x85\x3b\x27\x67\x5c\x5b\xb3\x30\xb9\x4a\x97\x4e\xad\x85\xe2\xbd\xee\x8e\xe1\x7c\xbb\x56\x53\x34\x66\x58\xdf\x2f\x91\xf6\xbd\x73\x94\x91\xdd\x71\x98\x8b\x3a\x97\x6a\x3e\x2e\x7a\x9d\x13\x74\x10\xf4\xac\xba\x9f\xeb\x5f\x11\x79\x8c\x9a\x43\xb6\xad\xce\x14\x36\x5a\x7c\x6d"}, +{{0xff,0xe8,0x25,0x14,0x8c,0x09,0x59,0xb3,0xa6,0x8d,0xe8,0x6a,0xd8,0xe8,0xaf,0x7f,0xa5,0xe0,0x78,0xf3,0x63,0xdc,0x12,0x42,0x13,0xc9,0x00,0x20,0xda,0x0c,0x90,0x89,},{0x13,0x91,0x52,0xa0,0xbd,0x22,0x96,0x2d,0xd9,0x19,0xae,0x3e,0x0b,0x16,0x20,0xe0,0x3c,0x03,0x3c,0x2a,0xd0,0xa3,0x97,0x9e,0xc6,0xbc,0xd1,0x70,0x5e,0x23,0xd5,0x98,},{0xfe,0x4e,0x89,0xee,0x31,0x78,0x6c,0x0a,0x3d,0x3d,0xe3,0x64,0x9b,0xb9,0x3f,0x0b,0x8a,0xef,0x1c,0xaf,0x5a,0x83,0x2e,0xc5,0xe4,0x06,0x78,0x10,0x70,0x5a,0xdd,0xdf,0x53,0x9b,0x8f,0x4e,0x05,0xad,0x08,0xcf,0x34,0x79,0xe4,0x5b,0x42,0xc9,0x65,0x28,0xf6,0xd5,0x9a,0x46,0x25,0x70,0x3d,0xdb,0xf1,0x5b,0x63,0x09,0x39,0x65,0xd8,0x0d,},"\xf1\x25\x78\x0d\x0c\xd0\x88\x53\x0f\x0c\x87\xb7\x0b\xd4\x2e\xba\xb5\x6a\xdb\x5a\xd4\x34\x5f\x92\x9a\xe5\xde\xae\x07\xfb\x55\x32\x21\x53\xa8\xf0\x23\xd3\x88\x43\xbf\x5d\x6a\x93\xfe\x99\x3e\xee\x71\xbc\x2e\xe5\x63\xb2\x5a\x50\x91\x8f\x03\xef\xdb\x5d\xbf\x72\x69\xad\xd6\x9d\xed\x3e\x66\x95\x38\x95\x62\x0d\x9b\x6c\xf4\x6b\xa2\x34\x8f\x8d\x66\xd7\xf0\x92\x23\x5e\x37\x8c\x1e\x3e\xdf\xeb\xeb\x78\x08\x4b\xc8\xde\xa0\x13\xf9\x93\x3a\xae\x14\xa0\x41\x94\x82\x76\xd0\x1f\x1c\xb5\x83\x4b\x0e\x59\x0e\x13\xd9\x31\xd1\x92\x92\xbb\x1d\x80\x41\xff\x2f\xe2\xe1\x17\x1a\x2e\x0b\x9a\x05\x98\x21\xd0\x92\x4d\xde\x7f\x3b\x1b\xb5\x98\x13\xf5\xe3\xc6\x35\x20\xaa\xfb\x88\x01\xba\x62\xc7\x09\x7d\x4d\x8c\xf4\x37\xa5\x68\xa7\xf0\x08\x7c\x6e\xa0\xfc\xe6\xe5\x68\xc4\x88\x3f\x1c\xd1\x2c\x74\x9d\x06\xa6\xfe\xb2\x78\xf1\x08\x6a\x8b\x04\x76\x99\x21\xf7\x8a\x99\x59\x06\x2a\xb0\x6f\x98\xee\x80\xc2\xc7\x85\x4f\xfa\x76\x0f\x86\xa8\x9e\xe1\xa5\x12\x66\x05\x3d\x19\x5e\x61\xbb\x1d\xbd\x18\xdd\x89\xff\x39\x4e\x40\x8a\xce\x0f\x64\x1a\x39\x5d\x56\x11\x8e\xa7\x2b\x7d\x8a\xdf\x78\xb1\x65\x5e\xce\xce\x7e\x82\x50\xe8\xa3\xa9\x1c\xb8\xfc\xa0\xd9\xce\x0b\xaf\x89\x80\xa3\x87\xc5\xed\x43\x18\x66\x32\x80\xe5\xb4\x53\x1f\x31\x87\xc4\x7e\xae\xa7\xc3\x29\x72\x8d\xdd\x0e\x40"}, +{{0x49,0xaf,0xf4,0x21,0xa7,0xcd,0x12,0x72,0x2a,0xa8,0x4c,0x48,0xc1,0xfb,0x1c,0x5f,0x8d,0x9e,0x27,0x7d,0x0a,0x99,0xec,0xbc,0x93,0x48,0xc3,0xaa,0xa7,0x4b,0xe4,0x22,},{0x88,0xd2,0xc2,0x62,0x66,0xf4,0x93,0xbc,0x67,0x57,0x8c,0xa0,0xb1,0xf5,0x11,0x60,0xcf,0x0f,0xdb,0x6a,0x09,0xa9,0x06,0xdb,0x9f,0xaa,0x68,0x6f,0x11,0xf8,0x20,0x8d,},{0x74,0x91,0x81,0x28,0x4d,0xf0,0x5d,0xbe,0x59,0x74,0xb9,0x17,0x82,0xa1,0xa7,0x6e,0xa0,0x86,0x42,0xcb,0x0f,0x0c,0x98,0xdb,0x58,0x6c,0x57,0x5c,0x21,0x0c,0xdc,0x8b,0x65,0x1b,0xd3,0x4b,0x75,0x7a,0xe3,0x8e,0x4b,0x6b,0xe9,0x46,0x52,0x35,0xbd,0x0e,0xca,0x43,0x0e,0x26,0xc3,0xee,0xde,0x56,0x1c,0x6e,0x82,0x4d,0xfa,0x20,0x0e,0x0a,},"\x70\xa1\xac\x14\x4b\x75\xfd\xa7\x55\x86\xa7\x9c\x36\xfd\x39\xcc\xe5\xf5\xca\xe2\xe6\x37\x58\x52\xd3\xb6\x2a\x96\x30\x33\x6a\x29\x3e\xa6\xd2\xac\x6e\x5b\x57\xda\x21\xef\x36\x4a\x59\x5b\xb0\x75\x0f\x5b\xf4\xd2\xb3\x20\x67\x64\x23\x87\x0e\x4b\x8e\x08\x69\x60\x1f\x16\x68\x06\x19\x04\x8c\x4e\xde\x27\x6d\xa6\x9f\x20\x5a\x70\x17\x6e\x25\xea\x04\xbd\x08\x97\x63\xe7\x09\xba\x34\x3f\xc8\x83\x1e\x52\x04\x4e\xab\xf9\x44\x1e\x69\x97\xf8\xba\x1a\xeb\x9e\xf0\xf4\x91\x17\x06\x67\xa7\xf5\xfc\x96\x27\xcb\xd0\x55\x1b\x76\xbe\x27\x28\x3a\x4b\x0c\x5f\x66\x78\x46\x68\x82\x26\xa1\x15\xee\x80\x20\xdf\x08\x04\x2b\x19\xb5\x9f\xe5\x51\x31\x6a\x6c\xb6\x91\x68\x60\xb9\xec\xd7\x41\x54\xb4\x05\x10\x38\xa1\x73\x52\x37\x2e\xc1\x4d\x3c\x95\x7d\x2e\xf5\x0f\xf7\x86\x18\x9a\x8a\xeb\x9c\x08\xf4\x5e\xeb\x5e\xb8\xb0\x40\x33\x99\x74\xaa\x97\x98\xc4\x25\xd7\xbe\xcb\x22\x8c\x44\x7a\x6d\x0b\x3c\xef\x27\x18\x93\xe0\xf7\x07\x6e\x22\x3a\x7e\x87\xc6\xa3\xd2\x70\xa0\x33\xbc\x97\xa4\x56\x5e\xdc\xe0\xaa\x91\xff\xc3\xf7\x80\x17\x75\xa6\xf2\x9b\x23\x02\x45\xbd\x71\xfa\x03\x43\x53\xde\x37\x23\x95\xd1\xbf\xcb\xde\xbb\xa0\x81\x33\x0f\x7c\x07\x6b\xe9\x9c\x2c\xf4\x86\x7f\x15\xb7\x8d\x52\xf4\x6f\xc7\x39\x1c\x9c\xb9\x5e\x5d\x64\x64\x3b\xaf\xfe\x72\xa8\xe3\xa6\x50\x66\x7f\xbb\x3e"}, +{{0x70,0x3a,0x6e,0x2b,0x62,0xd0,0x09,0x0c,0x61,0xd8,0x65,0x9b,0x6a,0x96,0x3e,0x03,0xc9,0xd6,0x2c,0x1b,0x38,0xf7,0xd7,0x0e,0x5f,0x9f,0xf0,0x55,0x90,0xcd,0x03,0x60,},{0x37,0x0c,0x21,0xde,0x6e,0xf2,0xfa,0xb5,0x34,0xad,0xa9,0x99,0x86,0x9c,0x90,0xbc,0x9b,0x92,0xcc,0xbf,0x24,0x9b,0x79,0xd3,0x9d,0x95,0x44,0x1d,0x1e,0xde,0x21,0x0a,},{0xe5,0xfd,0x64,0xda,0x02,0x88,0x00,0xc6,0xce,0xed,0x06,0x8a,0x5e,0x59,0x6f,0x16,0x21,0xc7,0x0a,0x8c,0xb1,0x38,0xb3,0x1b,0x32,0x64,0x7e,0xb4,0xb0,0x7b,0xd2,0xec,0xc5,0x94,0x2c,0x18,0x84,0x4f,0x36,0x70,0x33,0xf6,0x73,0x98,0xe3,0x14,0xba,0x2c,0x7c,0xcf,0x29,0x9c,0x06,0x97,0x87,0x77,0x70,0x25,0xd8,0x45,0xf2,0xaa,0xd6,0x0e,},"\xd4\x2a\x17\x56\xe8\x4d\xf4\xb4\xe9\x77\x3f\x86\xf7\x67\x4a\x2c\xd7\x8e\x71\xe4\x0a\xa8\xf6\x44\xe6\x70\x2d\xfb\xc2\xc2\xc5\xca\x90\xfc\x24\x2e\x9c\xb0\x09\x9c\xc8\xf2\xc2\xd3\x13\x6b\xaa\xfc\x0f\xf6\x95\x48\x2f\xda\xcd\xef\x9f\x56\x56\x10\xb6\xe1\x90\x07\x22\xf4\x35\xc6\x38\x5b\x35\xe9\xf6\xc4\x36\xca\x03\x7e\x03\xf6\x4e\x22\x33\xdf\xfa\x58\xdb\x3b\x91\xcc\x1d\xaa\x0b\xb0\xc5\x4c\x8a\x43\xe4\x69\xd2\xcf\xf7\xfa\x2b\xf8\xf5\xd1\xd8\x77\x93\x10\x89\xc8\x2e\xd8\x9a\xba\x42\xf2\xee\x2b\x86\xe4\x45\xcf\xd0\x9f\x4c\xd7\x8b\x35\x19\x1b\xf4\x67\xe7\x84\xee\xf7\x5d\xc9\x87\xe0\x46\xd3\x7d\x4d\x4e\x8e\x9b\xbe\x14\xaf\x80\xd0\x3a\x1f\x40\x89\x83\x84\xb9\xd3\x27\x9f\xac\x9c\x57\xfd\x9c\x7e\xec\xbe\x19\xa5\xac\xc1\x50\x33\xb8\x4e\x07\xfd\x0e\x40\x9b\xdb\xd5\xa5\x7f\x65\x64\x11\x83\xa6\xc0\xa8\xec\x42\x6d\x1f\x1d\x22\x31\x66\xff\x0a\x19\x00\xb2\xe9\x2b\x7d\x85\x83\x5d\x01\x9d\x17\x77\x5e\x50\x93\xcc\xd1\x26\xf9\x0f\x63\xcb\x7d\x15\xcb\xeb\x53\x13\x24\x21\x9c\xd6\x4d\xed\x67\x14\xb2\x1a\x65\x37\x1a\xf0\x72\x10\xdf\xdf\x0e\x4e\x58\xdd\xc7\xd5\x9f\x4c\xfa\x65\xc4\x21\xd8\x14\xee\x2c\x9b\xf6\xdb\xf6\x48\x73\xd5\x79\xb0\x9e\xe5\xdc\xed\xd7\x33\x06\x3e\x03\x9a\xc9\xa5\xf9\xca\x4c\x25\x25\xa4\xcc\x8e\x98\x4d\xa7\x18\x5e\x2d\x64\xfa\xd8\x1c\x8a"}, +{{0x76,0x84,0x9c,0x18,0x8e,0x3e,0xdd,0x0f,0xf5,0xf8,0xfb,0x87,0x4d,0xc0,0x45,0x66,0x45,0x51,0x84,0x45,0xe4,0x1a,0x7d,0x68,0x33,0xe6,0x16,0xc3,0xc4,0x8c,0x98,0x68,},{0xd6,0x70,0xe2,0xea,0x07,0xdb,0x60,0xc2,0x2a,0xb7,0x9a,0x93,0xeb,0xf4,0x9d,0x22,0xa6,0x24,0x5e,0xe3,0xaf,0x07,0xb3,0xbe,0x58,0x4e,0xda,0x69,0x4c,0x37,0x72,0x9e,},{0x71,0x41,0x39,0x9d,0x51,0xda,0xa6,0xeb,0x45,0x19,0xbf,0x3f,0x01,0xb2,0x33,0x92,0x0f,0xa9,0x08,0xfe,0xfa,0x61,0x2f,0x0c,0xd7,0xd5,0xaf,0x8a,0x9a,0x3c,0x44,0x19,0x0e,0x3f,0x63,0x84,0xa8,0xd1,0x4d,0x37,0xc9,0x70,0x30,0xef,0x50,0x18,0xcf,0x8a,0xee,0x8a,0xeb,0x15,0x69,0xa7,0x3d,0x84,0x86,0x2a,0x59,0xb7,0xdf,0x72,0xfe,0x09,},"\x1e\xcc\xb0\xbc\x8e\xca\x3a\xb5\xbe\xe6\x8c\x5f\x8c\xaa\x34\x53\x67\x66\xc7\x05\xf5\x08\x27\xdb\x7a\xc3\x75\xd4\xfe\x30\xb5\x8f\xfb\x7e\x2f\xe4\x90\xcc\x71\xa8\xff\x86\xc0\x06\xd6\x17\x4d\x05\x79\x3a\xb8\xa5\x5d\xd5\x1b\x06\xde\x41\x7b\xc0\xac\x45\x2c\xdc\x7c\xfb\x0b\xb0\x03\x62\xb6\x76\x5d\x20\xdb\x23\xeb\x18\x48\x02\x70\x64\xa1\xd9\x09\x1d\x3b\x10\xed\x77\x6f\x28\xb7\x67\x68\xbd\xfc\x08\xf0\xbc\x51\x1f\x76\xfa\xeb\xa7\x6c\xfc\x4c\xb5\xc8\x3d\xc9\xeb\xe8\xa8\xd7\x9e\xdc\xa9\x23\xec\xcd\x52\x40\x09\xca\xfe\xdc\x90\xe3\xad\x87\xd1\x39\x2e\x1f\xcc\xf4\xe6\x0c\xca\xb9\x5d\xc0\xab\x54\xbf\x44\x24\x5a\x00\x7a\x96\xd4\x66\x34\xb1\xb2\x96\x5b\x82\x9c\x3d\x7d\xaa\x76\x59\x72\xb5\x4a\x7b\x36\x5b\x6f\x34\xd7\x7d\x71\x76\xac\xd8\xd8\x94\xf6\xb4\x17\x09\x1b\x6c\x00\xed\xb7\xa4\xe8\x13\x79\x98\x8b\xfc\xec\xb6\x92\xe9\xc3\xc4\x31\x0a\x7e\x24\x0e\x5c\x10\x63\xcd\xe1\x13\xf2\x2a\x68\x4a\x50\xa1\x12\xff\x47\xd3\x89\x88\x12\xef\xb9\x26\x37\x07\x2b\x86\x16\x3a\xd8\x93\x16\xd2\x21\x19\x5a\xcb\xfa\xd0\xa0\x3a\x1f\xbc\x2d\x96\x7f\xe8\x3f\x84\xc8\x45\x9f\xcc\xd4\x90\xb9\xc5\xb3\xe5\x5d\x27\xe9\x48\x4e\x94\x3c\x41\x7f\x21\x28\xd7\x37\x01\xda\x28\xf4\x9f\xd3\x68\x3f\x33\xa3\x9c\xde\xe2\x34\xbd\x30\x5b\x94\x91\xe2\xf3\xeb\x62\x1b\xe3\xdd\x1d\xbb\xb3\x1b"}, +{{0x83,0xae,0x48,0xad,0x70,0xda,0x0b,0xb3,0xcd,0xf8,0x74,0x81,0xee,0x2c,0x0c,0x85,0x71,0xc2,0xca,0x98,0x67,0x12,0xf8,0xbc,0x23,0x29,0xe9,0xa3,0xe3,0x33,0x83,0xc5,},{0xb7,0x85,0x30,0x90,0x00,0xdf,0x95,0xf5,0xa0,0x4f,0x7d,0x89,0xc4,0x11,0x33,0x01,0x05,0x7a,0xda,0xee,0xb2,0x9b,0xcd,0x28,0xd9,0x93,0x71,0xb5,0x37,0xbb,0xa2,0xf6,},{0x43,0x33,0x23,0x51,0xd3,0xfb,0x7b,0x45,0xfc,0xf3,0x7c,0x60,0x7d,0x44,0x2e,0xa8,0x0d,0xbd,0xa2,0xcb,0x69,0xc2,0x88,0x4f,0x42,0x4e,0x65,0xea,0x3a,0x33,0x1e,0xd8,0x47,0x2d,0x43,0x68,0x40,0x5c,0xb7,0x36,0xb2,0xd6,0x68,0x5a,0xd7,0x82,0xe2,0x39,0xfe,0x83,0x3e,0xd7,0x89,0xa2,0x92,0x31,0x85,0x16,0x6f,0x60,0x83,0x42,0xee,0x05,},"\xb7\x52\x1d\x3f\x71\xc6\x79\xfa\x70\x37\xfe\x74\x88\xa6\x41\xf6\xb9\x7c\x49\x45\x4a\xcc\x8e\x36\xb9\x03\xd8\xf9\xeb\xb5\x4d\x89\xcb\x56\xef\xd1\x9e\x04\xba\x6a\x7c\x8f\x48\xa7\xd3\xec\x9d\xec\xd3\xf1\xcd\x0f\xaf\x6e\x97\x81\x18\xe6\xad\xce\x9c\x6c\x6b\xe6\x3c\x6a\x6a\x1a\xe2\x16\x51\x82\x84\x79\xa4\x6b\xc9\xa0\xf7\x94\x30\x40\xf9\x40\xa0\xd4\x70\xc8\xe5\x77\xc5\xd5\x75\xcb\x53\xc1\xbf\x3a\xb1\xfe\xb0\x50\xdc\xb6\xfe\xf0\xba\x44\x47\xf2\x99\xfd\xb9\xf2\x7e\xcb\x07\x14\xec\xfe\xfd\x74\xba\xd7\xb1\x22\xa4\x62\xc2\x4a\x20\x98\x48\xa0\x33\x89\x07\x45\x78\xc5\xbd\xc3\x63\x96\xd8\x09\xb0\xf1\x40\x18\xda\x64\x91\x7e\x6b\xf8\x7e\xf4\x05\xc8\xf3\xe3\x33\xff\x9c\x3b\xaf\x63\x39\x66\x76\x20\x79\x4b\xb4\x74\x3f\x05\x14\xb5\xde\x7d\x7f\xdd\x94\x7a\x7e\x35\x01\xee\x88\xef\xad\x15\x9e\x33\xa1\x07\x2f\xbb\x99\xc7\xc7\x1e\x9d\x13\xa5\x02\xd5\xa0\x7c\x4f\x81\x7e\xeb\x7f\x0c\x53\x19\xaa\x41\xa9\x6d\x5f\xf4\xf1\x5a\x73\xc2\x9b\x57\x1f\xe2\x11\x09\x0e\x17\x2c\x8d\xb5\x18\x62\x46\x12\xa5\xc3\x71\xa9\xd7\xce\xf6\xde\x35\xeb\xef\x96\xe8\x8e\x1a\x78\xaf\x3b\xd5\xdd\x35\x25\x1a\xb5\x4d\x73\x71\x8f\x3e\x70\xd2\xd5\x90\x21\x53\x1d\xc7\x31\x84\xf0\xfc\x69\xc2\xe9\x29\x65\x84\x4e\xc2\x7c\x1c\x02\xaf\x5e\x9a\x34\x69\xde\x35\x5d\xb2\x25\x6e\x0e\xc2\xa4\xeb\xa3\x0a"}, +{{0x39,0xe5,0x6a,0x65,0x62,0x3a,0x0a,0xeb,0xad,0xe0,0xda,0x12,0xce,0x1d,0xf3,0x78,0xbc,0x92,0x40,0x73,0xf7,0x3a,0x54,0x9e,0xff,0xae,0xbc,0x46,0x5d,0x1a,0x78,0xe2,},{0x83,0xda,0x8a,0xd5,0x0b,0xad,0x09,0xeb,0x3e,0x94,0xc7,0x25,0xdf,0x3c,0xc3,0xa1,0x19,0x73,0x6a,0xdc,0x85,0x9c,0xa1,0xa1,0x05,0x03,0xf4,0x8f,0xf2,0xfe,0xc5,0x96,},{0x39,0x8e,0x82,0x60,0x01,0x1f,0x57,0xd8,0xac,0x8c,0x58,0xd5,0x45,0x7b,0xc6,0x52,0xc7,0x41,0x4a,0xaf,0x6f,0xb2,0xf4,0x26,0xb7,0x89,0x90,0x56,0x60,0x5c,0x0a,0xfc,0x28,0x39,0x24,0x23,0xb2,0xb5,0x71,0xf5,0xe6,0xc3,0xc7,0xf6,0xd6,0x02,0x45,0xe5,0x3e,0xbd,0x03,0xbd,0xc5,0xad,0x3c,0x1a,0xd8,0x73,0x8c,0xb3,0x22,0x14,0xd0,0x0f,},"\xa9\x6d\xc2\xea\x3f\xa1\x35\x14\x92\xa4\x61\x9d\x91\x94\x68\x1f\x8e\xc4\x00\xa9\x71\x58\x24\x44\x82\x65\x38\x38\xcc\xb7\xe1\x56\xa8\x2d\x56\x43\x68\xf8\x3a\x6e\xe1\xbe\x46\xbc\x34\xb8\x17\x20\x0e\x84\x64\xc3\xd1\x2b\x5e\xf2\xc5\x0b\x19\x56\x5b\x88\x1c\x4c\x3d\x45\x63\xfb\x94\x7e\xb4\x7c\x3e\xe9\xc1\xee\x78\x53\x26\x98\x74\x45\x5b\xfa\xcb\xa3\x05\xf3\x07\xd1\xac\x53\x09\xee\xae\x5c\x07\xfa\x5c\x4d\x42\x8e\xdb\xc8\xb9\x52\x8c\x44\x15\x24\x3a\x9e\xf5\x80\xaf\xf8\xfc\xfb\x12\x00\x0a\x71\xfc\xee\xe8\x9d\xe9\x7f\x90\x27\x95\x29\xbc\xc8\x22\xed\x3c\xb3\x4c\x82\xba\x5f\xec\x15\xf4\x94\x56\x63\x63\x6d\x67\xb5\xfe\xce\xac\xc3\x1d\x25\xf9\x8a\xea\x07\xf7\x80\x0d\x5a\x10\x34\x25\x1c\xb9\x1d\xd0\x96\x3e\xc2\xc1\xa5\x47\x73\xa4\xd9\x6c\x18\x35\x7f\x8d\x10\x1d\xe5\x8e\x93\x2f\x8c\x6c\xdd\xe8\xe3\xcf\xce\xf5\xa7\x44\x3f\xdb\xa7\xb7\x83\x20\x40\x3c\x01\x96\x84\x47\x24\xa6\x12\x18\x3e\x34\xbd\xd8\x08\xce\x7b\x95\x88\x61\xca\x37\x11\x57\x30\xea\xed\xe1\xfd\x0b\xaa\xbe\x97\x6e\xfe\xfd\x03\x65\xfd\xf9\x26\x77\x6c\x53\x6f\x47\xff\x80\xde\x5c\x18\x29\x1b\xb7\xe9\xf1\xb9\x13\xff\xd1\xd9\x44\x68\xb7\x89\x75\x2f\xae\x6c\xa8\x97\xc0\xcc\xa5\x3e\xf1\xe7\x31\xd0\x0c\x8b\xdb\xe8\x92\x9e\xa6\xb1\xdc\xe1\xf3\x1a\x20\x68\x8d\x37\xb0\xf3\xa2\xb4\x15\x3b\x30\x6b\xdb\xa1"}, +{{0x4b,0x99,0x21,0x85,0x2f,0x40,0x9a,0x32,0x3a,0xe3,0x81,0x75,0xe8,0xd7,0x6a,0x21,0x1f,0xc4,0xd9,0xc6,0x54,0x17,0x8e,0xea,0x3b,0xaa,0x7a,0x76,0x7a,0x6f,0xda,0x06,},{0x4c,0x72,0x3e,0x43,0x6b,0x6b,0xd9,0x7f,0x44,0xaf,0x52,0x50,0x3b,0x21,0xcc,0x50,0xd5,0xf6,0xad,0x6c,0xfc,0x82,0x88,0x34,0x5d,0xde,0x80,0x54,0xe9,0x95,0x58,0x2e,},{0xcb,0xf1,0xf1,0x64,0x2d,0xf9,0x50,0xeb,0x71,0xfd,0x09,0x59,0x0d,0x34,0xc2,0x65,0x92,0x2c,0x58,0xbd,0x80,0x26,0xbb,0xa3,0xfc,0x0e,0x59,0x4a,0x6b,0xb1,0xf2,0xb9,0x0d,0xa3,0xdc,0x1d,0x5f,0x6b,0x6d,0x5b,0x40,0x5a,0x89,0x6d,0x1d,0xbb,0x71,0xb8,0x68,0x5c,0x4d,0xfc,0x44,0x4a,0xca,0xff,0xe6,0x5a,0xb8,0x33,0x17,0x89,0xf5,0x07,},"\x3f\x33\xd8\xfb\x83\xe6\x87\x41\x09\x0a\x37\xbe\xdd\x74\x5c\xf1\x41\xaa\xae\xd8\xc9\x2f\xfa\x74\x2a\x52\x56\x17\x77\x88\x58\x05\xac\xe1\x42\x46\xab\x98\xa8\xcb\x59\x8c\x9c\xe3\xde\x9b\x29\xba\xe5\xfa\x04\xb1\xcf\x82\x8d\xe1\x1a\xff\x80\xa7\xef\x8a\x3a\x38\xae\xde\x4f\x3c\x35\x63\xa2\x5d\x04\x9b\xad\xca\xd5\xed\x7e\x47\xfd\xbb\xa6\xe1\x11\x30\x7e\xeb\xe9\xef\x49\x06\xbc\x98\x97\x28\xb7\x6e\x84\xaf\xe8\x08\xe6\x65\x3b\x27\x1e\x21\x10\x4a\xa6\x65\xf1\x89\x8d\xd2\xaa\xb2\x30\x90\xe2\x2b\x4e\x34\x4a\x26\x16\xfb\xd8\xee\x4a\xd8\xed\x81\x08\x39\x5e\xba\x81\x7f\xbd\x14\xfe\xc5\xc1\x7d\xcf\x56\xb8\x22\x08\x56\xb2\xb8\x33\xe0\x91\x40\x7d\x50\x89\xb3\x5d\xdf\x34\xb8\x6f\xf7\xdc\x9f\xde\x52\xb2\x1e\xf1\x21\x76\xef\x33\x70\xb7\xf3\xa0\xa8\xcb\x1b\x05\x8a\x51\xae\xff\xf3\xd2\x79\xd8\x0f\x51\xa6\x8b\xfb\x59\x25\x87\xb4\x5c\x5c\x63\xa7\xe4\xd6\x25\xb8\x87\xde\x48\x6a\x11\x83\x16\xc3\xb6\xa2\x38\x57\x5f\x92\xac\x5b\x1c\x94\xc3\xf5\xdb\xbd\x96\x68\x60\x00\xd6\xd3\x9c\xcc\xd5\x58\xd4\x20\xe4\xd4\x47\xa8\xcb\xc4\xbc\x7b\x8c\x6a\x03\xaf\x0f\x00\x34\xfb\x35\x18\xd9\x38\x00\xf0\xf7\x13\xe4\xb1\x37\x32\xe1\x6a\xda\x51\x80\x1d\x7e\x55\x9c\xf8\x39\xd1\x05\x8f\x64\x95\x56\x98\x31\x13\x99\x34\x54\x16\x85\x0d\xdd\xcc\x56\x01\xa6\x84\xfd\x09\xe6\xaf\xd3\x94\x4f\x5e\x19"}, +{{0x1b,0xff,0x65,0x2a,0x2c,0x83,0x09,0xa3,0x93,0xac,0x11,0xda,0x3a,0xa9,0x7f,0xb0,0x78,0xbb,0x28,0x4e,0xd5,0xe1,0xb8,0xcc,0xc9,0x83,0x65,0x2e,0xf8,0x55,0x6c,0xd0,},{0xaa,0xab,0xdc,0x09,0x1f,0xc3,0x68,0x23,0x54,0x20,0x17,0x44,0xe9,0xb7,0x3f,0xd2,0xa6,0xcf,0xb2,0x81,0x91,0x4b,0xf2,0xc7,0x0e,0xc3,0xdc,0x1d,0xec,0x72,0x16,0xb0,},{0x93,0xc9,0xc3,0x34,0x93,0xfc,0x64,0x17,0x2d,0x51,0xe1,0x6a,0x0a,0x1c,0xd7,0x29,0xa0,0xd9,0x9e,0x3c,0xb8,0x64,0xe8,0x9a,0x42,0x98,0x7f,0x39,0xdd,0x8c,0xd2,0x65,0x45,0xfd,0xfe,0x37,0x58,0x19,0x11,0xe8,0x03,0x67,0x7d,0xa4,0xc5,0x5b,0x0a,0x68,0x3d,0xdf,0x62,0xb7,0x28,0xf8,0xf3,0x06,0x85,0xae,0x58,0xf6,0x28,0xeb,0xe6,0x09,},"\x48\xd0\x26\x98\xa9\x7b\xdc\xb3\xef\x07\x8d\xcf\xcf\x57\x50\x00\x5f\x17\x02\xd3\x00\xe7\xe8\x9b\xc4\x36\xe3\x81\x11\x34\x01\xf8\x52\xb8\xb4\xac\xff\x60\xff\xbd\x4a\xb4\x6d\x20\x21\x68\xd9\x8b\x87\x35\xe7\x9c\xb3\x50\xe3\x5b\x07\x0f\xf6\xbd\xca\xfd\x95\x4b\x55\x19\x69\xb6\xb1\xa7\x0c\x91\x31\xeb\xd4\x0d\x96\x14\x02\x91\xd8\xd2\xb0\x91\x54\x0a\x8b\x18\xd8\xe5\x46\x59\x15\xc2\x5d\xbc\x6b\x5c\x9a\x68\x79\x42\x53\x3c\x37\x2c\x8b\x4e\x95\xa9\x53\x67\x71\x69\xb9\x50\xed\xd3\x46\x43\x75\xcd\x43\x13\x2f\xf9\xbd\x54\x1e\xe2\x2b\xd4\x18\xce\x23\x19\x5f\x65\xd8\xb2\x89\xf6\x33\xec\x8d\x71\xe1\xa8\x01\xb0\x6c\x3c\x82\x7f\x62\x7e\x72\x3d\x21\x99\x10\x0c\xe7\x3e\x8e\x4a\x44\x40\xe7\x78\x31\x7a\x47\x49\x10\x79\x3b\x47\xb1\x0f\xfb\x55\xdb\x7f\x28\x1c\x7d\x7a\x03\x3b\xd8\x00\x48\xb8\x26\x73\xb8\x7c\xf9\x5e\x99\x42\x2b\xa6\x28\x68\x8f\x3c\x97\x18\x90\xca\x15\xd1\x2f\x57\x2f\xa1\x97\x7a\x17\x30\x70\x69\xda\x30\x4e\xad\x30\x26\xeb\x01\x04\x26\x68\x89\x0d\x17\x00\x8c\xd1\xe9\x2c\x46\xcb\xe9\xc8\x57\xe7\x19\x3d\xe3\xab\xa3\x91\x1e\x4f\x86\xfe\x0a\x16\x98\xab\x7c\xdb\x92\x51\xa8\x42\x4b\x28\x48\xb9\x6a\xd8\x1e\xa2\x39\xd3\x65\xfd\xea\x92\xea\x5c\x04\x73\xd0\xa6\xbb\x1e\x37\x13\x56\xbd\xfa\xd2\xd0\x35\x03\x36\xd3\xe1\x94\x7c\x93\x6f\xd0\xc2\x51\x95\x44\x50\x11\x73\x1b"}, +{{0x00,0x2f,0xdd,0x1f,0x76,0x41,0x79,0x3a,0xb0,0x64,0xbb,0x7a,0xa8,0x48,0xf7,0x62,0xe7,0xec,0x6e,0x33,0x2f,0xfc,0x26,0xee,0xac,0xda,0x14,0x1a,0xe3,0x3b,0x17,0x83,},{0x77,0xd1,0xd8,0xeb,0xac,0xd1,0x3f,0x4e,0x2f,0x8a,0x40,0xe2,0x8c,0x4a,0x63,0xbc,0x9c,0xe3,0xbf,0xb6,0x97,0x16,0x33,0x4b,0xcb,0x28,0xa3,0x3e,0xb1,0x34,0x08,0x6c,},{0x0d,0xf3,0xaa,0x0d,0x09,0x99,0xad,0x3d,0xc5,0x80,0x37,0x8f,0x52,0xd1,0x52,0x70,0x0d,0x5b,0x3b,0x05,0x7f,0x56,0xa6,0x6f,0x92,0x11,0x2e,0x44,0x1e,0x1c,0xb9,0x12,0x3c,0x66,0xf1,0x87,0x12,0xc8,0x7e,0xfe,0x22,0xd2,0x57,0x37,0x77,0x29,0x62,0x41,0x21,0x69,0x04,0xd7,0xcd,0xd7,0xd5,0xea,0x43,0x39,0x28,0xbd,0x28,0x72,0xfa,0x0c,},"\x5a\xc1\xdf\xc3\x24\xf4\x3e\x6c\xb7\x9a\x87\xab\x04\x70\xfa\x85\x7b\x51\xfb\x94\x49\x82\xe1\x90\x74\xca\x44\xb1\xe4\x00\x82\xc1\xd0\x7b\x92\xef\xa7\xea\x55\xad\x42\xb7\xc0\x27\xe0\xb9\xe3\x37\x56\xd9\x5a\x2c\x17\x96\xa7\xc2\x06\x68\x11\xdc\x41\x85\x83\x77\xd4\xb8\x35\xc1\x68\x8d\x63\x88\x84\xcd\x2a\xd8\x97\x0b\x74\xc1\xa5\x4a\xad\xd2\x70\x64\x16\x39\x28\xa7\x79\x88\xb2\x44\x03\xaa\x85\xaf\x82\xce\xab\x6b\x72\x8e\x55\x47\x61\xaf\x71\x75\xae\xb9\x92\x15\xb7\x42\x1e\x44\x74\xc0\x4d\x21\x3e\x01\xff\x03\xe3\x52\x9b\x11\x07\x7c\xdf\x28\x96\x4b\x8c\x49\xc5\x64\x9e\x3a\x46\xfa\x0a\x09\xdc\xd5\x9d\xca\xd5\x8b\x9b\x92\x2a\x83\x21\x0a\xcd\x5e\x65\x06\x55\x31\x40\x02\x34\xf5\xe4\x0c\xdd\xcf\x98\x04\x96\x8e\x3e\x9a\xc6\xf5\xc4\x4a\xf6\x50\x01\xe1\x58\x06\x7f\xc3\xa6\x60\x50\x2d\x13\xfa\x88\x74\xfa\x93\x33\x21\x38\xd9\x60\x6b\xc4\x1b\x4c\xee\x7e\xdc\x39\xd7\x53\xda\xe1\x2a\x87\x39\x41\xbb\x35\x7f\x7e\x92\xa4\x49\x88\x47\xd6\x60\x54\x56\xcb\x8c\x0b\x42\x5a\x47\xd7\xd3\xca\x37\xe5\x4e\x90\x3a\x41\xe6\x45\x0a\x35\xeb\xe5\x23\x7c\x6f\x0c\x1b\xbb\xc1\xfd\x71\xfb\x7c\xd8\x93\xd1\x89\x85\x02\x95\xc1\x99\xb7\xd8\x8a\xf2\x6b\xc8\x54\x89\x75\xfd\xa1\x09\x9f\xfe\xfe\xe4\x2a\x52\xf3\x42\x8d\xdf\xf3\x5e\x01\x73\xd3\x33\x95\x62\x50\x7a\xc5\xd2\xc4\x5b\xbd\x2c\x19\xcf\xe8\x9b"}, +{{0x25,0xb0,0xf0,0xbb,0x3d,0xcb,0x42,0x2a,0x6f,0x3c,0x6c,0x22,0x0e,0xaa,0xdb,0x11,0xdb,0xfe,0x48,0x9c,0x2d,0x45,0x5b,0x27,0x6c,0xef,0xe8,0xcb,0xa0,0x57,0xf9,0xf3,},{0xfe,0x03,0xc9,0xc4,0x39,0x4a,0xdc,0x74,0xb1,0x3f,0x47,0x65,0x4b,0xea,0xd8,0xbc,0x85,0x59,0x58,0xb4,0x19,0x4f,0xda,0xb2,0x09,0x7a,0xc1,0xb1,0x57,0x93,0x3c,0x05,},{0xda,0x50,0xd5,0x24,0x2b,0xf5,0x1c,0x39,0x51,0x78,0x0c,0xaf,0xd9,0x26,0xd6,0x7b,0xdf,0x56,0x40,0xd5,0xd3,0xbb,0x08,0x43,0x38,0x31,0xd5,0x6e,0x48,0xe2,0x59,0x2a,0x1c,0x37,0x59,0x68,0xbb,0x4d,0x2f,0xbe,0xa5,0x61,0x45,0xab,0xf2,0xd8,0x29,0x91,0x36,0x3b,0x15,0x65,0xfa,0x1e,0xff,0xe2,0x14,0x01,0x1a,0x68,0x6e,0x39,0x95,0x0e,},"\x54\xd9\x9f\x96\x9e\xfa\x88\x70\xfc\x20\xfa\x9a\x96\x2b\xb3\x72\x61\x9c\x32\x44\x39\x72\x8a\xf3\x13\x9c\x2a\x07\xe8\xc1\xb2\x9c\x1e\x4e\xed\xc2\xd4\x0b\xa7\x22\xf6\x3c\xe3\x76\x70\x36\x2a\xf6\xf5\x20\x2a\xdd\x66\x8c\x4f\xb4\xd6\x2f\xa8\xba\xcb\xc7\xd0\x7f\xf3\xbd\x38\xc1\x5a\x01\x06\x42\x59\xcc\x34\x13\x48\x61\x63\x29\x67\x46\x05\x41\xa9\x9b\x8d\x51\x82\xbf\x59\x34\x7b\x5a\x59\x87\x9a\xa3\xb0\x91\xa1\xf3\xe0\x41\x35\xbd\x63\x01\xbe\x52\x26\xd4\x89\x5e\x5e\x9c\x2b\x15\xe4\x8e\x5e\xcd\xf4\x41\x29\xe6\x12\x28\x53\xa6\x06\xfc\x11\x84\x66\xfa\x72\x0b\x5a\xb1\x65\x63\x5c\x3b\xde\x04\xd7\x42\x89\x27\x4f\xa0\x35\x47\xac\xcb\xde\x78\x0e\x1f\xa0\xbf\x2c\x56\xf8\x43\x6a\x53\xe7\x38\x78\xa4\x24\xa2\x9a\xa9\xde\x38\x5d\xba\x41\x9a\xe6\xa5\xd1\x2e\x00\x42\x76\x15\x2b\x58\xd3\x25\xb3\x02\x40\x0a\x55\x33\x3c\x38\xcd\xe4\x90\x8a\xe1\xd0\x12\x1c\xbe\xca\x95\x08\x09\xc5\x43\x31\x42\x77\xc1\x48\x5e\x68\xd9\xf9\xc0\xa9\x62\xd1\xb1\xe0\xdd\xa1\xd4\xa5\x2b\x56\xf8\x30\x8a\x80\xb9\x2a\xcc\x9f\x4e\xbc\x3e\xd4\x5d\x91\xa1\x29\xda\x86\x75\x62\x1a\xf6\x76\x70\x3d\xef\x3b\x84\x11\x31\x83\xb2\xe3\xa8\xc5\x61\x57\xf2\x43\xf1\x39\x80\xf3\xd1\x75\x6f\xea\x76\x68\xc9\x15\x03\xd3\x5c\x83\x9a\x21\x20\xc7\x9e\xc9\x54\xfb\x54\x6d\x7b\x54\x2f\x98\x72\x89\x53\x4f\xfd\xef\x62\xd4\x7f\xd5\xec"}, +{{0xbf,0x5b,0xa5,0xd6,0xa4,0x9d,0xd5,0xef,0x7b,0x4d,0x5d,0x7d,0x3e,0x4e,0xcc,0x50,0x5c,0x01,0xf6,0xcc,0xee,0x4c,0x54,0xb5,0xef,0x7b,0x40,0xaf,0x6a,0x45,0x41,0x40,},{0x1b,0xe0,0x34,0xf8,0x13,0x01,0x7b,0x90,0x0d,0x89,0x90,0xaf,0x45,0xfa,0xd5,0xb5,0x21,0x4b,0x57,0x3b,0xd3,0x03,0xef,0x7a,0x75,0xef,0x4b,0x8c,0x5c,0x5b,0x98,0x42,},{0x27,0x9c,0xac,0xe6,0xfd,0xaf,0x39,0x45,0xe3,0x83,0x7d,0xf4,0x74,0xb2,0x86,0x46,0x14,0x37,0x47,0x63,0x2b,0xed,0xe9,0x3e,0x7a,0x66,0xf5,0xca,0x29,0x1d,0x2c,0x24,0x97,0x85,0x12,0xca,0x0c,0xb8,0x82,0x7c,0x8c,0x32,0x26,0x85,0xbd,0x60,0x55,0x03,0xa5,0xec,0x94,0xdb,0xae,0x61,0xbb,0xdc,0xae,0x1e,0x49,0x65,0x06,0x02,0xbc,0x07,},"\x16\x15\x2c\x2e\x03\x7b\x1c\x0d\x32\x19\xce\xd8\xe0\x67\x4a\xee\x6b\x57\x83\x4b\x55\x10\x6c\x53\x44\x62\x53\x22\xda\x63\x8e\xce\xa2\xfc\x9a\x42\x4a\x05\xee\x95\x12\xd4\x8f\xcf\x75\xdd\x8b\xd4\x69\x1b\x3c\x10\xc2\x8e\xc9\x8e\xe1\xaf\xa5\xb8\x63\xd1\xc3\x67\x95\xed\x18\x10\x5d\xb3\xa9\xaa\xbd\x9d\x2b\x4c\x17\x47\xad\xba\xf1\xa5\x6f\xfc\xc0\xc5\x33\xc1\xc0\xfa\xef\x33\x1c\xdb\x79\xd9\x61\xfa\x39\xf8\x80\xa1\xb8\xb1\x16\x47\x41\x82\x2e\xfb\x15\xa7\x25\x9a\x46\x5b\xef\x21\x28\x55\x75\x1f\xab\x66\xa8\x97\xbf\xa2\x11\xab\xe0\xea\x2f\x2e\x1c\xd8\xa1\x1d\x80\xe1\x42\xcd\xe1\x26\x3e\xec\x26\x7a\x31\x38\xae\x1f\xcf\x40\x99\xdb\x0a\xb5\x3d\x64\xf3\x36\xf4\xbc\xd7\xa3\x63\xf6\xdb\x11\x2c\x0a\x24\x53\x05\x1a\x00\x06\xf8\x13\xaa\xf4\xae\x94\x8a\x20\x90\x61\x93\x74\xfa\x58\x05\x24\x09\xc2\x8e\xf7\x62\x25\x68\x7d\xf3\xcb\x2d\x1b\x0b\xfb\x43\xb0\x9f\x47\xf1\x23\x2f\x79\x0e\x6d\x8d\xea\x75\x9e\x57\x94\x20\x99\xf4\xc4\xbd\x33\x90\xf2\x8a\xfc\x20\x98\x24\x49\x61\x46\x5c\x64\x3f\xc8\xb2\x97\x66\xaf\x2b\xcb\xc5\x44\x0b\x86\xe8\x36\x08\xcf\xc9\x37\xbe\x98\xbb\x48\x27\xfd\x5e\x6b\x68\x9a\xdc\x2e\x26\x51\x3d\xb5\x31\x07\x6a\x65\x64\x39\x62\x55\xa0\x99\x75\xb7\x03\x4d\xac\x06\x46\x1b\x25\x56\x42\xe3\xa7\xed\x75\xfa\x9f\xc2\x65\x01\x1f\x5f\x62\x50\x38\x2a\x84\xac\x26\x8d\x63\xba\x64"}, +{{0x65,0xde,0x29,0x7b,0x70,0xcb,0xe8,0x09,0x80,0x50,0x0a,0xf0,0x56,0x1a,0x24,0xdb,0x50,0x00,0x10,0x00,0x12,0x5f,0x44,0x90,0x36,0x6d,0x83,0x00,0xd3,0x12,0x85,0x92,},{0xba,0x8e,0x2a,0xd9,0x29,0xbd,0xce,0xa5,0x38,0x74,0x10,0x42,0xb5,0x7f,0x20,0x67,0xd3,0x15,0x37,0x07,0xa4,0x53,0x77,0x0d,0xb9,0xf3,0xc4,0xca,0x75,0x50,0x4d,0x24,},{0x7a,0x9b,0x73,0x6b,0x01,0xcc,0x92,0xa3,0x34,0x9f,0x1a,0x3c,0x32,0xdb,0xd9,0x19,0x59,0x82,0x53,0x94,0xff,0x44,0x3c,0x56,0x74,0x05,0xe8,0x99,0xc8,0x18,0x5c,0xe8,0xfa,0xd9,0x50,0x0e,0x1f,0xce,0x89,0xd9,0x5a,0x62,0x53,0xc0,0x04,0x77,0x43,0x5a,0xcf,0x04,0xbf,0xf9,0x93,0xde,0x1b,0x00,0x49,0x5d,0xef,0x08,0x34,0xee,0x1f,0x07,},"\x13\x1d\x8f\x4c\x2c\x94\xb1\x53\x56\x5b\x86\x59\x2e\x77\x0c\x98\x7a\x44\x34\x61\xb3\x9a\xa2\x40\x8b\x29\xe2\x13\xab\x05\x7a\xff\xc5\x98\xb5\x83\x73\x9d\x66\x03\xa8\x3f\xef\x0a\xfc\x51\x47\x21\xdb\x0e\x76\xf9\xbd\x1b\x72\xb9\x8c\x56\x5c\xc8\x88\x1a\xf5\x74\x7c\x0b\xa6\xf5\x8c\x53\xdd\x23\x77\xda\x6c\x0d\x3a\xa8\x05\x62\x0c\xc4\xe7\x5d\x52\xaa\xbc\xba\x1f\x9b\x28\x49\xe0\x8b\xd1\xb6\xb9\x2e\x6f\x06\x61\x5b\x81\x45\x19\x60\x6a\x02\xdc\x65\xa8\x60\x9f\x5b\x29\xe9\xc2\xaf\x5a\x89\x4f\x71\x16\xef\x28\xcf\xd1\xe7\xb7\x6b\x64\x06\x17\x32\xf7\xa5\xa3\xf8\xaa\x4c\x2e\x56\x9e\x62\x7a\x3f\x97\x49\xaa\x59\x7b\xe4\x9d\x6b\x94\x43\x6c\x35\x2d\xd5\xfa\x7b\x83\xc9\x2d\x26\x10\xfa\xa3\x20\x95\xca\x30\x21\x52\xd9\x1a\x3c\x97\x76\x75\x0e\x75\x8e\xe8\xe9\xe4\x02\xc6\xf5\x38\x5e\xaa\x5d\xf2\x38\x50\xe5\x4b\xeb\x1b\xe4\x37\xa4\x16\xc7\x11\x5e\xd6\xaa\x6d\xe1\x3b\x55\x48\x25\x32\x78\x7e\x0b\xee\x34\xb8\x3f\x30\x84\x40\x67\x65\x63\x54\x97\xc9\x31\xb6\x2a\x05\x18\xf1\xfb\xc2\xb8\x91\xdc\x72\x62\xc7\xc6\xb6\x7e\xda\x59\x4f\xa5\x30\xd7\x4c\x93\x29\xba\xd5\xbe\x94\xc2\x87\xfb\xcd\xe5\x3a\xa8\x02\x72\xb8\x33\x22\x61\x3d\x93\x68\xe5\x90\x40\x76\xfd\xbc\xc8\x8b\x2c\x0e\x59\xc1\x0b\x02\xc4\x48\xe0\x0d\x1b\x3e\x7a\x9c\x96\x40\xfe\xff\xb9\x52\x3a\x8a\x60\xe1\xd8\x3f\x04\xa4\xb8\xdf\x69\x15\x3b"}, +{{0x08,0x26,0xe7,0x33,0x33,0x24,0xe7,0xec,0x8c,0x76,0x42,0x92,0xf6,0x01,0x5d,0x46,0x70,0xe9,0xb8,0xd7,0xc4,0xa8,0x9e,0x8d,0x90,0x9e,0x8e,0xf4,0x35,0xd1,0x8d,0x15,},{0xff,0xb2,0x34,0x8c,0xa8,0xa0,0x18,0x05,0x8b,0xe7,0x1d,0x15,0x12,0xf3,0x76,0xf9,0x1e,0x8b,0x0d,0x55,0x25,0x81,0x25,0x4e,0x10,0x76,0x02,0x21,0x73,0x95,0xe6,0x62,},{0x4b,0xac,0x7f,0xab,0xec,0x87,0x24,0xd8,0x1a,0xb0,0x9a,0xe1,0x30,0x87,0x4d,0x70,0xb5,0x21,0x34,0x92,0x10,0x43,0x72,0xf6,0x01,0xae,0x5a,0xbb,0x10,0x53,0x27,0x99,0x37,0x3c,0x4d,0xad,0x21,0x58,0x76,0x44,0x1f,0x47,0x4e,0x2c,0x00,0x6b,0xe3,0x7c,0x3c,0x8f,0x5f,0x6f,0x01,0x7d,0x08,0x70,0x41,0x4f,0xd2,0x76,0xa8,0xf4,0x28,0x08,},"\x7f\x9e\x3e\x2f\x03\xc9\xdf\x3d\x21\xb9\x90\xf5\xa4\xaf\x82\x95\x73\x4a\xfe\x78\x3a\xcc\xc3\x4f\xb1\xe9\xb8\xe9\x5a\x0f\xd8\x37\xaf\x7e\x05\xc1\x3c\xda\x0d\xe8\xfa\xda\xc9\x20\x52\x65\xa0\x79\x2b\x52\x56\x3b\xdc\x2f\xee\x76\x63\x48\xbe\xfc\xc5\x6b\x88\xbb\xb9\x5f\x15\x44\x14\xfb\x18\x6e\xc4\x36\xaa\x62\xea\x6f\xca\xbb\x11\xc0\x17\xa9\xd2\xd1\x5f\x67\xe5\x95\x98\x0e\x04\xc9\x31\x3b\xc9\x4f\xbc\x8c\x11\x34\xc2\xf4\x03\x32\xbc\x7e\x31\x1a\xc1\xce\x11\xb5\x05\xf8\x57\x2a\xda\x7f\xbe\x19\x6f\xba\x82\x2d\x9a\x91\x44\x92\xfa\x71\x85\xe9\xf3\xbe\xa4\x68\x72\x00\xa5\x24\xc6\x73\xa1\xcd\xf8\x7e\xb3\xa1\x40\xdc\xdb\x6a\x88\x75\x61\x34\x88\xa2\xb0\x0a\xdf\x71\x75\x34\x1c\x1c\x25\x76\x35\xfa\x1a\x53\xa3\xe2\x1d\x60\xc2\x28\x39\x9e\xea\x09\x91\xf1\x12\xc6\x0f\x65\x3d\x71\x48\xe2\xc5\xce\xb9\x8f\x94\x08\x31\xf0\x70\xdb\x10\x84\xd7\x91\x56\xcc\x82\xc4\x6b\xc9\xb8\xe8\x84\xf3\xfa\x81\xbe\x2d\xa4\xcd\xda\x46\xbc\xaa\x24\xcc\x46\x1f\x76\xee\x64\x7b\xb0\xf0\xf8\xc1\x5a\xc5\xda\xa7\x95\xb9\x45\xe6\xf8\x5b\xb3\x10\x36\x2e\x48\xd8\x09\x5c\x78\x2c\x61\xc5\x2b\x48\x1b\x4b\x00\x2a\xd0\x6e\xa7\x4b\x8d\x30\x6e\xff\x71\xab\xf2\x1d\xb7\x10\xa8\x91\x3c\xbe\x48\x33\x2b\xe0\xa0\xb3\xf3\x1e\x0c\x7a\x6e\xba\x85\xce\x33\xf3\x57\xc7\xae\xcc\xd3\x0b\xfb\x1a\x65\x74\x40\x8b\x66\xfe\x40\x4d\x31\xc3\xc5"}, +{{0x00,0xad,0x62,0x27,0x97,0x7b,0x5f,0x38,0xcc,0xda,0x99,0x4d,0x92,0x8b,0xba,0x90,0x86,0xd2,0xda,0xeb,0x01,0x3f,0x86,0x90,0xdb,0x98,0x66,0x48,0xb9,0x0c,0x1d,0x45,},{0x91,0xa4,0xea,0x00,0x57,0x52,0xb9,0x2c,0xbe,0xbf,0x99,0xa8,0xa5,0xcb,0xec,0xd2,0x40,0xae,0x3f,0x01,0x6c,0x44,0xad,0x14,0x1b,0x2e,0x57,0xdd,0xc7,0x73,0xdc,0x8e,},{0xdc,0x50,0x1d,0xb7,0x9f,0xd7,0x82,0xbc,0x88,0xca,0xe7,0x92,0x55,0x7d,0x5d,0x27,0x3f,0x9b,0xa5,0x60,0xc7,0xd9,0x00,0x37,0xfe,0x84,0xac,0x87,0x9d,0x68,0x4f,0x61,0x2a,0x77,0x45,0x2c,0x44,0x43,0xe9,0x5c,0x07,0xb8,0xbe,0x19,0x2c,0x35,0x76,0x9b,0x17,0xbb,0xdf,0xca,0x42,0x28,0x0d,0xe7,0x96,0xd9,0x21,0x19,0xd8,0x33,0x67,0x0d,},"\xcb\x5b\xc5\xb9\x8b\x2e\xfc\xe4\x35\x43\xe9\x1d\xf0\x41\xe0\xdb\xb5\x3e\xd8\xf6\x7b\xf0\xf1\x97\xc5\x2b\x22\x11\xe7\xa4\x5e\x2e\x1e\xc8\x18\xc1\xa8\x0e\x10\xab\xf6\xa4\x35\x35\xf5\xb7\x9d\x97\x4d\x8a\xe2\x8a\x22\x95\xc0\xa6\x52\x17\x63\xb6\x07\xd5\x10\x3c\x6a\xef\x3b\x27\x86\xbd\x5a\xfd\x75\x63\x69\x56\x60\x68\x43\x37\xbc\x30\x90\x73\x9f\xb1\xcd\x53\xa9\xd6\x44\x13\x9b\x6d\x4c\xae\xc7\x5b\xda\x7f\x25\x21\xfb\xfe\x67\x6a\xb4\x5b\x98\xcb\x31\x7a\xa7\xca\x79\xfc\x54\xa3\xd7\xc5\x78\x46\x6a\x6a\xa6\x4e\x43\x4e\x92\x34\x65\xa7\xf2\x11\xaa\x0c\x61\x68\x1b\xb8\x48\x6e\x90\x20\x6a\x25\x25\x0d\x3f\xda\xe6\xfb\x03\x29\x97\x21\xe9\x9e\x2a\x91\x49\x10\xd9\x17\x60\x08\x9b\x5d\x28\x1e\x13\x1e\x6c\x83\x6b\xc2\xde\x08\xf7\xe0\x2c\x48\xd3\x23\xc6\x47\xe9\x53\x6c\x00\xec\x10\x39\x20\x1c\x03\x62\x61\x8c\x7d\x47\xaa\x8e\x7b\x97\x15\xff\xc4\x39\x98\x7a\xe1\xd3\x11\x54\xa6\x19\x8c\x5a\xa1\x1c\x12\x8f\x40\x82\xf5\x56\xc9\x9b\xaf\x10\x3e\xca\xdc\x3b\x2f\x3b\x2e\xc5\xb4\x69\x62\x3b\xc0\x3a\x53\xca\xf3\x81\x4b\x16\x30\x0a\xed\xbd\xa5\x38\xd6\x76\xd1\xf6\x07\x10\x26\x39\xdb\x2a\x62\xc4\x46\x70\x7c\xe6\x46\x9b\xd8\x73\xa0\x46\x82\x25\xbe\x88\xb0\xae\xf5\xd4\x02\x04\x59\xb9\x4b\x32\xfe\x2b\x01\x33\xe9\x2e\x7b\xa5\x4d\xd2\xa5\x39\x7e\xd8\x5f\x96\x6a\xb3\x9e\xd0\x73\x0c\xca\x8e\x7d\xac\xb8\xa3\x36"}, +{{0x15,0x21,0xc6,0xdb,0xd6,0xf7,0x24,0xde,0x73,0xea,0xf7,0xb5,0x62,0x64,0xf0,0x10,0x35,0xc0,0x4e,0x01,0xc1,0xf3,0xeb,0x3c,0xbe,0x83,0xef,0xd2,0x6c,0x43,0x9a,0xda,},{0x2f,0x61,0xa2,0x6f,0xfb,0x68,0xba,0x4f,0x6e,0x14,0x15,0x29,0xdc,0x26,0x17,0xe8,0x53,0x1c,0x71,0x51,0x40,0x48,0x08,0x09,0x3b,0x4f,0xa7,0xfe,0xda,0xea,0x25,0x5d,},{0xa8,0x17,0xed,0x23,0xec,0x39,0x8a,0x12,0x86,0x01,0xc1,0x83,0x2d,0xc6,0xaf,0x76,0x43,0xbf,0x3a,0x5f,0x51,0x7b,0xcc,0x57,0x94,0x50,0xfd,0xb4,0x75,0x90,0x28,0xf4,0x96,0x61,0x64,0x12,0x5f,0x6e,0xbd,0x0d,0x6b,0xf8,0x6f,0xf2,0x98,0xa3,0x9c,0x76,0x6d,0x0c,0x21,0xfd,0xb0,0xcb,0xfd,0xf8,0x1c,0xd0,0xeb,0x1f,0x03,0xcd,0x8a,0x08,},"\x3e\x3c\x7c\x49\x07\x88\xe4\xb1\xd4\x2f\x5c\xbc\xae\x3a\x99\x30\xbf\x61\x7e\xbd\xff\x44\x7f\x7b\xe2\xac\x2b\xa7\xcd\x5b\xcf\xc0\x15\x76\x09\x63\xe6\xfe\x5b\x95\x6f\xb7\xcd\xb3\x5b\xd5\xa1\x7f\x54\x29\xca\x66\x4f\x43\x7f\x08\x75\x3a\x74\x1c\x2b\xc8\x69\x2b\x71\xa9\x11\x5c\x58\x2a\x25\xb2\xf7\x4d\x32\x98\x54\xd6\x0b\x78\x17\xc0\x79\xb3\x52\x3a\xaf\xf8\x79\x3c\x2f\x72\xff\xf8\xcd\x10\x59\x2c\x54\xe7\x38\xdf\x1d\x64\x52\xfb\x72\xda\x13\x1c\x67\x31\xea\x5c\x95\x3c\x62\xea\x17\x7a\xc1\xf4\x73\x5e\x51\x54\x47\x73\x87\x10\x9a\xfa\xe1\x5f\x3e\xd6\xee\xb0\x86\x06\xe2\x8c\x81\xd4\x38\x6f\x03\xb9\x37\x69\x24\xb6\xef\x8d\x22\x1e\xe2\x95\x47\xf8\x2a\x7e\xde\x48\xe1\xdc\x17\x72\x3e\x3d\x42\x17\x1e\xea\xf9\x6a\xc8\x4b\xed\xc2\xa0\x1d\xd8\x6f\x4d\x08\x57\x34\xfd\x69\xf9\x1b\x52\x63\xe4\x39\x08\x3f\xf0\x31\x85\x36\xad\xff\x41\x47\x30\x8e\x3a\xaf\xd1\xb5\x8b\xb7\x4f\x6f\xb0\x21\x4a\x46\xfd\xcd\x35\x24\xf1\x8d\xf5\xa7\x19\xce\x57\x31\x9e\x79\x1b\x4e\xa6\x06\xb4\x99\xbf\xa5\x7a\x60\xe7\x07\xf9\x4e\x18\xf1\xfe\xd2\x2f\x91\xbc\x79\xe6\x36\x4a\x84\x3f\x9c\xbf\x93\x82\x5c\x46\x5e\x9c\xae\x90\x72\xbc\x9d\x3e\xc4\x47\x1f\x21\xab\x2f\x7e\x99\xa6\x33\xf5\x87\xaa\xc3\xdb\x78\xae\x96\x66\xa8\x9a\x18\x00\x8d\xd6\x1d\x60\x21\x85\x54\x41\x1a\x65\x74\x0f\xfd\x1a\xe3\xad\xc0\x65\x95\xe3\xb7\x87\x64\x07\xb6"}, +{{0x17,0xe5,0xf0,0xa8,0xf3,0x47,0x51,0xba,0xbc,0x5c,0x72,0x3e,0xcf,0x33,0x93,0x06,0x99,0x2f,0x39,0xea,0x06,0x5a,0xc1,0x40,0xfc,0xbc,0x39,0x7d,0x2d,0xd3,0x2c,0x4b,},{0x4f,0x1e,0x23,0xcc,0x0f,0x2f,0x69,0xc8,0x8e,0xf9,0x16,0x2a,0xb5,0xf8,0xc5,0x9f,0xb3,0xb8,0xab,0x20,0x96,0xb7,0x7e,0x78,0x2c,0x63,0xc0,0x7c,0x8c,0x4f,0x2b,0x60,},{0xef,0xe2,0xcb,0x63,0xfe,0x7b,0x4f,0xc9,0x89,0x46,0xdc,0x82,0xfb,0x69,0x98,0xe7,0x41,0xed,0x9c,0xe6,0xb9,0xc1,0xa9,0x3b,0xb4,0x5b,0xc0,0xa7,0xd8,0x39,0x6d,0x74,0x05,0x28,0x2b,0x43,0xfe,0x36,0x3b,0xa5,0xb2,0x35,0x89,0xf8,0xe1,0xfa,0xe1,0x30,0xe1,0x57,0xce,0x88,0x8c,0xd7,0x2d,0x05,0x3d,0x0c,0xc1,0x9d,0x25,0x7a,0x43,0x00,},"\xc0\xfa\xd7\x90\x02\x40\x19\xbd\x6f\xc0\x8a\x7a\x92\xf5\xf2\xac\x35\xcf\x64\x32\xe2\xea\xa5\x3d\x48\x2f\x6e\x12\x04\x93\x53\x36\xcb\x3a\xe6\x5a\x63\xc2\x4d\x0e\xc6\x53\x9a\x10\xee\x18\x76\x0f\x2f\x52\x05\x37\x77\x4c\xde\xc6\xe9\x6b\x55\x53\x60\x11\xda\xa8\xf8\xbc\xb9\xcd\xaf\x6d\xf5\xb3\x46\x48\x44\x8a\xc7\xd7\xcb\x7c\x6b\xd8\x0d\x67\xfb\xf3\x30\xf8\x76\x52\x97\x76\x60\x46\xa9\x25\xab\x52\x41\x1d\x16\x04\xc3\xed\x6a\x85\x17\x30\x40\x12\x56\x58\xa3\x2c\xf4\xc8\x54\xef\x28\x13\xdf\x2b\xe6\xf3\x83\x0e\x5e\xee\x5a\x61\x63\xa8\x3c\xa8\x84\x9f\x61\x29\x91\xa3\x1e\x9f\x88\x02\x8e\x50\xbf\x85\x35\xe1\x17\x55\xfa\xd0\x29\xd9\x4c\xf2\x59\x59\xf6\x69\x5d\x09\xc1\xba\x43\x15\xd4\x0f\x7c\xf5\x1b\x3f\x81\x66\xd0\x2f\xab\xa7\x51\x1e\xcd\x8b\x1d\xde\xd5\xf1\x0c\xd6\x84\x34\x55\xcf\xf7\x07\xed\x22\x53\x96\xc6\x1d\x08\x20\xd2\x0a\xda\x70\xd0\xc3\x61\x9f\xf6\x79\x42\x20\x61\xc9\xf7\xc7\x6e\x97\xd5\xa3\x7a\xf6\x1f\xd6\x22\x12\xd2\xda\xfc\x64\x7e\xbb\xb9\x79\xe6\x1d\x90\x70\xec\x03\x60\x9a\x07\xf5\xfc\x57\xd1\x19\xae\x64\xb7\xa6\xef\x92\xa5\xaf\xae\x66\x0a\x30\xed\x48\xd7\x02\xcc\x31\x28\xc6\x33\xb4\xf1\x90\x60\xa0\x57\x81\x01\x72\x9e\xe9\x79\xf7\x90\xf4\x5b\xdb\xb5\xfe\x1a\x8a\x62\xf0\x1a\x61\xa3\x1d\x61\xaf\x07\x03\x04\x50\xfa\x04\x17\x32\x3e\x94\x07\xbc\x76\xe7\x31\x30\xe7\xc6\x9d\x62\xe6\xa7"}, +{{0x0c,0xd7,0xaa,0x7d,0x60,0x5e,0x44,0xd5,0xff,0xb9,0x79,0x66,0xb2,0xcb,0x93,0xc1,0x89,0xe4,0xc5,0xa8,0x5d,0xb8,0x7f,0xad,0x7a,0xb8,0xd6,0x24,0x63,0xc5,0x9b,0x59,},{0x48,0x89,0x85,0x5f,0xe4,0x11,0x6b,0x49,0x13,0x92,0x7f,0x47,0xf2,0x27,0x3b,0xf5,0x59,0xc3,0xb3,0x94,0xa9,0x83,0x63,0x1a,0x25,0xae,0x59,0x70,0x33,0x18,0x5e,0x46,},{0xbf,0x91,0x15,0xfd,0x3d,0x02,0x70,0x6e,0x39,0x8d,0x4b,0xf3,0xb0,0x2a,0x82,0x67,0x4f,0xf3,0x04,0x15,0x08,0xfd,0x39,0xd2,0x9f,0x86,0x7e,0x50,0x16,0x34,0xb9,0x26,0x1f,0x51,0x6a,0x79,0x4f,0x98,0x73,0x8d,0x7c,0x70,0x13,0xa3,0xf2,0xf8,0x58,0xff,0xdd,0x08,0x04,0x7f,0xb6,0xbf,0x3d,0xdd,0xfb,0x4b,0x4f,0x4c,0xbe,0xef,0x30,0x03,},"\x28\xa5\x5d\xda\x6c\xd0\x84\x4b\x65\x77\xc9\xd6\xda\x07\x3a\x4d\xc3\x5c\xbc\x98\xac\x15\x8a\xb5\x4c\xf8\x8f\xd2\x0c\xc8\x7e\x83\xc4\xbb\xa2\xd7\x4d\x82\xce\x0f\x48\x54\xec\x4d\xb5\x13\xde\x40\x04\x65\xaa\xa5\xee\xe7\x90\xbc\x84\xf1\x63\x37\x07\x2d\x3a\x91\xcd\xe4\x0d\x6e\x0d\xf1\xba\x0c\xc0\x64\x5f\x5d\x5c\xbb\xb6\x42\x38\x1d\x7b\x9e\x21\x1d\x25\x26\x7a\x8a\xcf\x77\xd1\xed\xb6\x9c\x3a\x63\x0f\x5b\x13\x3d\x24\xf0\x46\xa8\x1b\xf2\x2f\xf0\x3b\x31\xd8\x44\x7e\x12\xc3\xf7\xb7\x71\x14\xa7\x0c\xbd\x20\xbb\xd0\x8b\x0b\x38\x27\xa6\xbb\xcf\x90\x40\x9e\x34\x44\x47\xa7\xfb\xc5\x9b\xdd\x97\xd7\x29\x07\x1f\x8d\x71\xdc\xc3\x3e\x6e\xf2\xcb\xab\x1d\x41\x1e\xdf\x13\x73\x4d\xb1\xdd\x97\x03\x27\x6f\x5e\xb2\xd6\xaa\x2c\xb8\x95\x2d\xd6\x71\x2b\xfa\xe8\x09\xce\x08\xc3\xaa\x50\x2b\x81\x35\x71\x3f\xac\x0a\x9c\x25\xb1\xd4\x5b\x6a\x58\x31\xe0\x24\x21\xbb\xa6\x5b\x81\xa5\x96\xef\xa2\x4b\x05\x76\xbd\x1d\xc7\xfd\xfb\x49\xbe\x76\x28\x75\xe8\x1b\xd5\x40\x72\x2b\xc0\x61\x40\xb9\xaa\x2e\xf7\xb8\x4a\x80\x1e\x41\xde\xd6\x8d\x45\x46\xac\x48\x73\xd9\xe7\xce\xd6\x49\xb6\x4f\xad\xaf\x0b\x5c\x4b\x6e\xb8\xd0\x36\x31\x52\x33\xf4\x32\x6c\xa0\x1e\x03\x39\x30\x50\xcd\x02\x7c\x24\xf6\x73\x03\xfb\x84\x6b\xd2\xc6\xb3\xdb\xa0\x6b\xed\x0d\x59\xa3\x62\x89\xd2\x4b\xd6\x48\xf7\xdb\x0b\x3a\x81\x34\x66\x12\x59\x3e\x3d\xdd\x18\xc5\x57"}, +{{0x33,0x37,0x1d,0x9e,0x89,0x2f,0x98,0x75,0x05,0x2a,0xc8,0xe3,0x25,0xba,0x50,0x5e,0x74,0x77,0xc1,0xac,0xe2,0x4b,0xa7,0x82,0x26,0x43,0xd4,0x3d,0x0a,0xce,0xf3,0xde,},{0x35,0x92,0x9b,0xde,0xd2,0x7c,0x24,0x9c,0x87,0xd8,0xb8,0xd8,0x2f,0x59,0x26,0x0a,0x57,0x53,0x27,0xb5,0x46,0xc3,0xa1,0x67,0xc6,0x9f,0x59,0x92,0xd5,0xb8,0xe0,0x06,},{0x98,0x5c,0xa4,0x46,0xdd,0xc0,0x07,0x82,0x7c,0xc8,0xf2,0x85,0x2c,0xbd,0x81,0x15,0xef,0x8c,0x59,0x75,0xe9,0xd7,0xce,0x96,0xd7,0x4d,0xfe,0xd8,0x59,0xaa,0x14,0xa4,0xc1,0x52,0x54,0x00,0x6b,0xea,0x5e,0x08,0x35,0x9e,0xfe,0x26,0x25,0xd7,0x15,0xe0,0x89,0x7e,0xe5,0xa1,0x6f,0x15,0x12,0x03,0xbe,0x50,0x10,0x41,0x86,0x37,0xde,0x05,},"\x27\xa3\x2e\xfb\xa2\x82\x04\xbe\x59\xb7\xff\x5f\xe4\x88\xca\x15\x8a\x91\xd5\x98\x60\x91\xec\xc4\x45\x8b\x49\xe0\x90\xdd\x37\xcb\xfe\xde\x7c\x0f\x46\x18\x6f\xab\xcb\xdf\xf7\x8d\x28\x44\x15\x58\x08\xef\xff\xd8\x73\xed\x9c\x92\x61\x52\x6e\x04\xe4\xf7\x05\x0b\x8d\x7b\xd2\x67\xa0\xfe\x3d\x5a\x44\x93\x78\xd5\x4a\x4f\xeb\xbd\x2f\x26\x82\x43\x38\xe2\xaa\xaf\x35\xa3\x2f\xf0\xf6\x25\x04\xbd\xa5\xc2\xe4\x4a\xbc\x63\x15\x9f\x33\x6c\xf2\x5e\x6b\xb4\x0d\xdb\x7d\x88\x25\xdf\xf1\x8f\xd5\x1f\xc0\x19\x51\xea\xed\xcd\x33\x70\x70\x07\xe1\x20\x3c\xa5\x8b\x4f\x7d\x24\x2f\x81\x66\xa9\x07\xe0\x99\x93\x2c\x00\x1b\xfb\x1e\xc9\xa6\x1e\x0e\xf2\xda\x4e\x84\x46\xaf\x20\x82\x01\x31\x5d\x69\x68\x17\x10\xd4\x25\xd2\x40\x0c\x38\x7d\x7b\x9d\xf3\x21\xa4\xae\xc6\x02\xb9\xc6\x56\xc3\xe2\x31\x0b\xff\x87\x56\xd1\x8b\x80\x21\x34\xb1\x56\x04\xf4\xed\xc1\x11\x14\x9a\x98\x79\xe3\x12\x41\xdd\x34\xf7\x02\xf4\xc3\x49\x61\x7b\x13\x52\x97\x69\xa7\x72\xf5\xe5\x2a\x89\xc0\x98\xe0\xdc\xa5\x92\x06\x67\x89\x3a\x25\x00\x61\xb1\x79\x91\x62\x6e\xb9\x31\x92\x98\x68\x5b\xe4\x6b\x6a\x8b\x68\x42\x24\x44\xfa\x5a\x36\xbc\xf3\xa6\x87\xe2\xec\xcb\x93\x22\xc8\x7d\xc8\x01\x65\xda\x89\x89\x30\x85\x0b\x98\xfc\x86\x3c\xad\xa1\xaa\x99\xc6\xd6\x1c\x45\x1b\x9c\xcf\x48\x74\xc7\xf0\xe7\x5b\x0a\x0c\x60\x2f\x04\x48\x12\xc7\x17\x65\xad\xaf\x02\x02\x53\x95\xb0"}, +{{0xbe,0xed,0xb8,0x07,0x3d,0xf5,0x8f,0x8c,0x1b,0xff,0xbd,0xbd,0x77,0xec,0x7d,0xec,0xb2,0xc8,0x2a,0x9b,0xab,0xec,0xef,0xc0,0x33,0x15,0x07,0xbd,0xc2,0xc2,0xa7,0xe7,},{0xb2,0x7e,0x90,0x8b,0x80,0x5e,0x29,0x6f,0xc3,0x0d,0x2e,0x47,0x4b,0x06,0x0c,0xd5,0x0c,0x0f,0x6f,0x52,0x0b,0x36,0x71,0x71,0x21,0x83,0xbd,0x89,0xd4,0xe7,0x33,0xe9,},{0x8c,0x89,0x0c,0xcc,0xad,0xc7,0x76,0x0e,0x1e,0x82,0xe4,0x3c,0x44,0xb3,0xdc,0x0b,0x68,0x5a,0x48,0xb4,0x79,0xae,0x13,0xcc,0x0a,0x6b,0x05,0x57,0xd0,0xfb,0x1c,0xba,0xbb,0xa6,0x3d,0x2a,0x96,0x84,0x34,0x12,0xea,0x8d,0x36,0xc5,0x0a,0xcb,0xf5,0x2b,0x92,0xcf,0xb2,0xdc,0xe4,0x9d,0xc4,0x8a,0xf6,0xdd,0xcf,0x8e,0xe4,0x7a,0x86,0x08,},"\x35\xca\x57\xf0\xf9\x15\xe5\x20\x9d\x54\xea\x4b\x87\x1f\xfb\x58\x53\x54\xdf\x1b\x4a\x4a\x17\x96\xfb\xe4\xd6\x22\x7d\x3e\x1a\xba\x51\x71\xed\x03\x91\xa7\x9e\x83\xe2\x4d\x82\xfd\xaf\xd1\x5c\x17\xb2\x8b\xf6\xc9\x4d\x61\x8c\x74\xd6\x52\x64\xe5\x8f\xaa\xac\xd2\x90\x28\x72\xfd\xd0\xef\xa2\x2e\x8d\x2d\x7c\xe8\xe3\xb8\x19\x7f\x0c\x36\x15\xb0\xa3\x85\x23\x5f\xa9\xfd\x8e\x45\x64\xee\x6e\x6b\x16\x50\xb4\xcf\xb9\x4d\x87\x2c\x80\x5c\x32\xd4\xf3\xa1\x8f\x96\x64\x61\xd3\xad\xbb\x60\x5f\xa5\x25\x88\x4f\x8e\xb1\x97\x62\x73\x96\xba\x4d\x99\x5d\x78\xac\x02\x94\x8a\x0e\xaa\xbb\x58\x51\x9b\x9a\x8e\x2e\x79\x85\xcd\x1d\xe2\xc7\x1d\x89\x18\xd9\x6a\x01\x68\x66\x0c\xe1\x7c\xdd\xf3\x64\xe3\xec\x0d\x4b\xd9\x0f\x21\x04\x75\x1a\x19\x27\xee\x1d\x23\xf3\xe7\xa6\x98\x40\xed\x04\x0b\x00\xe5\xf6\xe4\x86\x6e\xc5\x88\x13\x14\x9c\xc3\x82\xae\xbf\x61\x62\x60\x8c\x79\x57\x4d\x55\x3f\x47\x23\x0e\x92\x4a\x0e\xf1\xeb\xf5\x5d\x8e\x1a\x52\xab\xb6\x2a\x2d\x7a\xc8\x60\x27\xc7\xc0\x3c\xc8\x3f\xa1\x94\x9d\xa2\x9e\x2f\x30\x37\xab\x98\x6f\xd2\xff\xfe\x65\x0e\x31\x49\xba\xba\xe5\xa5\x0b\x1e\xe9\x69\x6f\x3b\xab\xec\x72\xe2\x96\x97\xc8\x24\x22\x81\x4d\x27\x20\x85\x50\x0f\xd8\x37\xfe\x3c\x7a\x97\x3e\xf4\xc1\x69\xaf\x12\xdd\x7f\x02\x70\x06\x20\xbb\x04\x5b\xdb\xf8\x46\x23\xf3\x26\x35\x05\x70\xb3\xca\xdb\xc9\xae\xa4\x20\x0b\x28\x28\x7e\x17\xab"}, +{{0x91,0x84,0xef,0x61,0x88,0x16,0x83,0x25,0x92,0xbc,0x8e,0xb3,0x5f,0x4f,0xfd,0x4f,0xf9,0x8d,0xfb,0xf7,0x77,0x6c,0x90,0xf2,0xaa,0xd2,0x12,0xce,0x7e,0x03,0x35,0x1e,},{0x68,0x7b,0x77,0x26,0x01,0x0d,0x9b,0xde,0x2c,0x90,0xe5,0x73,0xcd,0x2a,0x2a,0x70,0x2f,0xf2,0x8c,0x4a,0x2a,0xf7,0x0a,0xfc,0x73,0x15,0xc9,0x4d,0x57,0x56,0x01,0xe5,},{0xb3,0xc2,0x4e,0x75,0x13,0x2c,0x56,0x34,0x75,0x42,0x2d,0x5e,0xa4,0x12,0xb5,0xc1,0xe8,0xe6,0xe5,0xea,0x1c,0x08,0xea,0xd1,0x39,0x3c,0x41,0x2d,0xa1,0x34,0xc9,0xa1,0x63,0x82,0x84,0xea,0x7e,0x2c,0xa0,0x32,0xfe,0x3d,0x3e,0x32,0xa9,0x06,0x6a,0x8c,0x88,0x39,0x90,0x3f,0x6e,0xf4,0x6e,0x96,0x6b,0xb5,0xe4,0x92,0xd8,0xc2,0xaa,0x00,},"\x72\x9e\xb7\xe5\x4a\x9d\x00\xc5\x86\x17\xaf\x18\xc3\x45\xb8\xdc\x6e\x5b\x4e\x0f\x57\xde\x2f\x3c\x02\xe5\x4a\x2e\xc8\xf1\x42\x5e\xc2\xe2\x40\x77\x5b\x5a\xb0\xc1\x0f\x84\xac\x8b\xaf\xda\x45\x84\xf7\xe2\x1c\x65\x5f\xae\xcd\x80\x30\xa9\x89\x06\xbd\x68\x39\x8f\x26\xb5\xd5\x8d\x92\xb6\xcf\x04\x5e\x9b\xd9\x74\x3c\x74\xc9\xa3\x42\xec\x61\xce\x57\xf3\x7b\x98\x1e\xac\x4d\x8b\xf0\x34\x60\x88\x66\xe9\x85\xbb\x68\x68\x6a\x68\xb4\xa2\xaf\x88\xb9\x92\xa2\xa6\xd2\xdc\x8c\xe8\x8b\xfb\x0a\x36\xcf\x28\xbb\xab\x70\x24\xab\xfa\x2b\xea\x53\x31\x3b\x66\xc9\x06\xf4\xf7\xcf\x66\x97\x0f\x54\x00\x95\xbd\x01\x04\xaa\x49\x24\xdd\x82\xe1\x54\x13\xc2\x26\x79\xf8\x47\xe4\x8c\xd0\xc7\xec\x1f\x67\x7e\x00\x5f\xec\x01\x77\xfb\xd5\xc5\x59\xfc\x39\xad\xd6\x13\x99\x1f\xba\xea\xe4\xd2\x4d\x39\xd3\x09\xef\x74\x64\x7f\x81\x92\xcc\x4c\x62\xd0\x64\x20\x28\xc7\x6a\x1b\x95\x1f\x6b\xc9\x63\x9d\xeb\x91\xec\xc0\x8b\xe6\x04\x3f\x21\x09\x70\x5a\x42\xc7\xea\xe7\x12\x64\x9d\x91\xd9\x6c\xcb\xbf\xb6\x3d\x8d\x0d\xd6\xdd\x11\x21\x60\xf6\x13\x61\xec\xdc\x67\x93\x92\x9c\xa9\xae\xf9\xab\x56\x94\x4a\x6f\xa4\xa7\xdf\x1e\x27\x9e\xaf\x58\xce\x83\x23\xa9\xcf\x62\xc9\x42\x79\xff\xf7\x44\x0f\xbc\x93\x6b\xaa\x61\x48\x9c\x99\x93\x30\xba\xdc\xb9\xfc\x0e\x18\x4b\xc5\x09\x3f\x33\x0c\xbb\x24\x2f\x71\xfb\x37\x87\x38\xfe\xa1\x05\x11\xdd\x43\x83\x64\xd7\xf7\x6b\xcc"}, +{{0x35,0x4e,0x13,0x15,0x2e,0xe1,0xfe,0x74,0x8a,0x12,0x52,0x20,0x4c,0x65,0x27,0xbd,0xc1,0xb1,0xeb,0x2e,0xb5,0x36,0x78,0x15,0x0e,0x63,0x59,0x92,0x47,0x08,0xd8,0x12,},{0xd4,0x5f,0xf6,0xc5,0xfb,0x83,0xe7,0xbb,0x96,0x69,0xaa,0x89,0x60,0xde,0xb7,0xdb,0xc6,0x65,0xc9,0x88,0x43,0x9b,0x6c,0x9e,0xf6,0x72,0xc6,0x81,0x1d,0xc8,0xbc,0xf6,},{0xde,0x2b,0x46,0xe6,0x5f,0x3d,0xec,0xef,0x34,0x33,0x2e,0x50,0x0f,0x2e,0x11,0x30,0x6f,0xbd,0xcf,0x1b,0xe8,0x5a,0x1c,0x1e,0xe6,0x8b,0xa3,0x04,0x5d,0xce,0xc2,0xc7,0xbe,0x60,0x8d,0x22,0x92,0x7d,0xa1,0xf4,0x4c,0x0e,0x20,0x83,0xae,0x62,0x2c,0xf3,0xc2,0x9d,0x89,0x38,0x87,0x99,0x4e,0xfc,0xfa,0x2c,0xa5,0x94,0xf5,0x05,0x1f,0x03,},"\x8e\x5f\xcc\xf6\x6b\x1b\xa6\x16\x9c\xb6\x85\x73\x3d\x9d\x0e\x01\x90\x36\x1c\x90\xbc\xab\x95\xc1\x63\x28\x5a\x97\xfe\x35\x6d\x2b\xdc\xde\x3c\x93\x80\x26\x88\x05\xa3\x84\xd0\x63\xda\x09\xcc\xd9\x96\x9c\xc3\xff\x74\x31\xe6\x0a\x8e\x9f\x86\x9c\xd6\x2f\xaa\x0e\x35\x61\x51\xb2\x80\xbc\x52\x6e\x57\x7c\x2c\x53\x8c\x9a\x72\x4d\xc4\x8b\xf8\x8b\x70\x32\x1d\x7e\x1e\xee\xdb\x3c\x4a\xf7\x06\x74\x8c\x94\x2e\x67\xbd\xab\xdb\x41\xbe\xc2\x97\x7b\x15\x23\x06\x9e\x31\xe2\x9b\x76\x30\x02\x88\xf8\x8a\x51\xb3\x84\xb8\x0c\xc2\x52\x6f\x16\x79\x34\x0d\xde\xc3\x88\x1f\x5c\xd2\x8b\x03\x78\xd9\xcd\x0a\x81\x2b\x68\xdd\x3f\x68\xf7\xa2\x3e\x1b\x54\xbe\xe7\x46\x6a\xc7\x65\xcf\x38\xdf\x04\xd6\x74\x41\xdf\xa4\x98\xc4\xbf\xfc\x52\x04\x5f\xa6\xd2\xdb\xcd\xbf\xa3\x3d\xfa\xa7\x76\x44\xff\xcc\xef\x0d\xec\xdb\x67\x90\xc7\x0a\x0d\x73\x4e\xc2\x87\xcc\x33\x8c\xb5\xa9\x09\xc0\x05\x51\x89\x30\x11\x69\xc4\xf7\x70\x2c\x05\xc0\x91\x1a\x27\xb1\x6e\xf9\xed\x93\x4f\xa6\xa0\xca\x7b\x13\xe4\x13\x52\x34\x22\x53\x56\x47\x96\x80\x30\xed\xc4\x0c\xd7\x3e\x7d\x6b\x34\x5b\x75\x81\xf4\x38\x31\x6d\x68\xe3\xcd\x29\x2b\x84\x6d\x3f\x4f\x7c\x48\x62\xbc\x7e\x6b\x3f\xb8\x9a\x27\xf6\xf6\x0c\xd7\xdb\x2e\x34\xec\x9a\xae\x10\x13\xfe\x37\xac\xff\x8a\xd8\x88\xcb\x9a\x59\x3e\xf5\xe6\x21\xea\xe5\x18\x6c\x58\xb3\x1d\xcf\xde\x22\x87\x0e\x33\x6d\x33\xf4\x40\xf6\xb8\xd4\x9a"}, +{{0x7f,0xf6,0x2d,0x4b,0x3c,0x4d,0x99,0xd3,0x42,0xd4,0xbb,0x40,0x1d,0x72,0x6b,0x21,0xe9,0x9f,0x4e,0xf5,0x92,0x14,0x9f,0xc3,0x11,0xb6,0x87,0x61,0xf5,0x56,0x7f,0xf6,},{0x7f,0xdf,0xdb,0x9e,0xca,0x29,0xd3,0xf0,0x1d,0x94,0x86,0xd7,0xe1,0x12,0xce,0x03,0xaa,0x37,0xb9,0x13,0x26,0xa4,0x28,0x3b,0x9c,0x03,0x99,0x9c,0x5e,0xda,0x09,0x9a,},{0x05,0x8f,0x79,0x92,0x7f,0xbf,0x61,0x78,0x72,0x48,0x15,0xc7,0xb1,0x1c,0x63,0xba,0xaa,0x90,0xbc,0xc1,0x5d,0x72,0x72,0xbe,0x08,0x2f,0x8a,0x91,0x41,0x86,0x1c,0x81,0x64,0x33,0x05,0x5f,0x6c,0xf6,0x49,0x14,0x24,0x85,0x3f,0x9e,0xc7,0x8b,0xb9,0x1a,0xce,0x91,0x3a,0x93,0x41,0x1b,0x4e,0x5e,0xd5,0x8b,0xc4,0xba,0x57,0x15,0xc6,0x0a,},"\x99\xc4\x4c\x79\x65\x72\xa4\x82\x3f\xc6\xc3\x80\x77\x30\x83\x91\x73\x77\x4c\x05\xdb\xfc\x14\x92\xed\x0d\x00\x50\x9a\x95\xa1\xde\x37\x27\x4b\x31\x35\xed\x04\x56\xa1\x71\x8e\x57\x65\x97\xdc\x13\xf2\xa2\xab\x37\xa4\x5c\x06\xcb\xb4\xa2\xd2\x2a\xfa\xd4\xd5\xf3\xd9\x0a\xb3\xd8\xda\x4d\xcd\xaa\x06\xd4\x4f\x22\x19\x08\x84\x01\xc5\xdc\xee\xe2\x60\x55\xc4\x78\x2f\x78\xd7\xd6\x3a\x38\x06\x08\xe1\xbe\xf8\x9e\xee\xf3\x38\xc2\xf0\x89\x7d\xa1\x06\xfa\xfc\xe2\xfb\x2e\xbc\x5d\xb6\x69\xc7\xc1\x72\xc9\xcf\xe7\x7d\x31\x09\xd2\x39\xfe\x5d\x00\x5c\x8e\xe7\x51\x51\x1b\x5a\x88\x31\x7c\x72\x9b\x0d\x8b\x70\xb5\x2f\x6b\xd3\xcd\xa2\xfe\x86\x5c\x77\xf3\x6e\x4f\x1b\x63\x5f\x33\x6e\x03\x6b\xd7\x18\xbe\xc9\x0e\xe7\x8a\x80\x28\x11\x51\x0c\x40\x58\xc1\xba\x36\x40\x17\x25\x3a\xa8\x42\x92\x2e\x1d\xd7\xd7\xa0\xf0\xfc\x9c\x69\xe4\x3f\xc4\xea\xef\xfa\xaf\x1a\xe5\xfa\x5d\x2d\x73\xb4\x30\x79\x61\x7b\xab\xa0\x30\x92\x3f\xe5\xb1\x3d\x2c\x1c\x4f\xe6\xfa\xc3\xf2\xdb\x74\xe2\x02\x0a\x73\x4b\x61\x21\xa0\x30\x2f\xce\x82\x0b\xa0\x58\x0c\xe6\x13\x53\x48\xfd\xf0\x63\x2e\x00\x08\xdf\x03\xee\x11\x21\x68\xf5\xcf\xa0\x03\x7a\x26\xa1\xf6\x9b\x1f\x13\x17\xed\xf2\xa3\xab\x36\x74\x55\xa7\x7e\x00\x69\x12\x15\xd7\xaa\x31\x33\xc2\x15\x9d\x3d\xa2\xb1\x34\xcf\x04\xf0\xde\xfb\xf0\x7a\x60\x64\x01\x1e\x64\xdd\x14\xd4\xf8\xf0\x64\x35\x66\x55\x42\x88\x04\xc2\x77\x1a"}, +{{0x6c,0xab,0xad,0xd0,0x3f,0x8a,0x2e,0x6e,0xba,0xb9,0x6a,0x74,0xf8,0x0e,0x18,0x16,0x4e,0x4d,0x1b,0x6b,0xaa,0x67,0x8f,0x5a,0x82,0xe2,0x56,0x04,0xaf,0x98,0x9a,0xaf,},{0x2a,0x4a,0x31,0x79,0x56,0x41,0x94,0xe0,0x01,0x00,0xc1,0x8b,0xc3,0x53,0x51,0xd8,0xb1,0x35,0xbb,0xae,0x5b,0x32,0xb2,0x8f,0xce,0x1d,0x7b,0x67,0x66,0xca,0x4b,0x32,},{0x4e,0x65,0xc6,0xc1,0xd4,0x93,0x04,0x5e,0x8a,0x92,0x50,0xe3,0x97,0xc1,0xd1,0xd3,0x0f,0xfe,0xd2,0x4d,0xb6,0x6a,0x89,0x61,0xaa,0x45,0x8f,0x8f,0x0f,0xcb,0x76,0x0c,0x39,0xfe,0x86,0x57,0xd7,0xab,0x8f,0x84,0x00,0x0b,0x96,0xd5,0x19,0x71,0x7c,0xff,0x71,0xf9,0x26,0x52,0x2c,0x1e,0xfe,0xc7,0xf8,0xb2,0x62,0x4e,0xae,0x55,0xf6,0x0c,},"\x27\x9f\x78\xcf\x3b\x9c\xcf\xc6\xe1\xb0\x1e\x1a\x82\xf5\x0e\xd1\x72\xe9\xa8\xe1\xe7\x02\xbb\x15\x66\x1d\xd7\xdc\x3a\x45\x6f\xf7\xa7\xa7\xfd\xfb\x08\x1d\xb3\x86\x70\x79\x63\x0c\x7f\x70\xfd\x75\x32\x92\xec\x60\xec\xbf\x50\x63\x2e\x9a\xa4\x5b\x99\x65\x05\xc6\x6e\x6d\xc3\xc6\xae\x89\x2e\x21\xb6\xa8\x70\x5e\x4b\xba\xe8\xf1\x6a\x33\x78\x55\x4b\x31\xfd\xb0\x13\x9d\xcd\x15\xc9\x6a\x8a\x7e\x4b\x88\x75\x6a\x86\xd1\x8d\xb5\xdc\x74\xfd\x76\x91\x19\x7d\xd8\x8e\x2c\x7d\x5d\xf5\x2b\x04\x93\x44\xcd\xc4\x77\xc9\xcd\x7e\x89\xed\xa9\x9c\xcf\xb1\xd0\x08\x14\xd0\x15\x2b\x96\x54\xdf\x32\x79\x37\x2c\xa5\xf1\x8b\x1c\x94\x6f\x28\x94\xa7\x6b\x07\x9d\xdb\x1c\x3c\xd6\x1f\xbb\x96\x9a\xee\xc9\x19\x3a\x6b\x88\xfb\x7d\x13\x6c\x07\xf9\x82\x1e\x5c\x10\x74\xb4\xe9\x3b\xca\xf6\xfa\x14\xd0\xd1\xd7\xe1\x70\x75\x89\xd7\x7e\xc1\x33\x72\x06\xe5\x3a\x1f\x06\xcc\x26\x67\x2f\xf9\x5c\x13\xd5\xff\x44\x47\x66\x93\x1b\xa3\x0a\x0a\xfd\xcd\xad\xd2\x09\x8e\x9c\x41\xfd\x87\xa3\xf2\x3c\xd1\x6d\xbb\x0e\xfb\xf8\x09\x2c\xe3\x3e\x32\x7f\x42\x61\x09\x90\xe1\xce\xe6\xcb\x8e\x54\x95\x1a\xa0\x81\xe6\x97\x65\xae\x40\x09\xae\xed\x75\x8e\x76\x8d\xe5\x0c\x23\xd9\xa2\x2b\x4a\x06\xdc\x4d\x19\xfc\x8c\xbd\x0c\xde\xf4\xc9\x83\x46\x17\x55\xd0\xa3\xb5\xd6\xa9\xc1\x22\x53\xe0\x95\x68\x33\x9f\xf7\xe5\xf7\x8c\x5f\xdf\x7e\xc8\x9f\x91\x86\xa6\x21\xa8\xc0\xee\xd1\x1b\x67\x02\x2e"}, +{{0x0f,0xa0,0xc3,0x2c,0x3a,0xe3,0x4b,0xe5,0x1b,0x92,0xf9,0x19,0x45,0x40,0x59,0x81,0xa8,0xe2,0x02,0x48,0x85,0x58,0xa8,0xe2,0x20,0xc2,0x88,0xc7,0xd6,0xa5,0x53,0x2d,},{0xd6,0xae,0xe6,0x2b,0xd9,0x1f,0xc9,0x45,0x36,0x35,0xff,0xcc,0x02,0xb2,0xf3,0x8d,0xca,0xb1,0x32,0x85,0x14,0x03,0x80,0x58,0x0c,0xcd,0xff,0x08,0x65,0xdf,0x04,0x92,},{0x7e,0x9a,0xb8,0x5e,0xe9,0x4f,0xe4,0xb3,0x5d,0xcb,0x54,0x53,0x29,0xa0,0xef,0x25,0x92,0x3d,0xe5,0xc9,0xdc,0x23,0xe7,0xdf,0x1a,0x7e,0x77,0xab,0x0d,0xcf,0xb8,0x9e,0x03,0xf4,0xe7,0x85,0xca,0x64,0x29,0xcb,0x2b,0x0d,0xf5,0x0d,0xa6,0x23,0x0f,0x73,0x3f,0x00,0xf3,0x3a,0x45,0xc4,0xe5,0x76,0xcd,0x40,0xbd,0xb8,0x4f,0x1a,0xe0,0x01,},"\x53\xf4\x4b\xe0\xe5\x99\x7f\xf0\x72\x64\xcb\x64\xba\x13\x59\xe2\x80\x1d\xef\x87\x55\xe6\x4a\x23\x62\xbd\xda\xf5\x97\xe6\x72\xd0\x21\xd3\x4f\xfa\xce\x6d\x97\xe0\xf2\xb1\xf6\xae\x62\x5f\xd3\x3d\x3c\x4f\x6e\x9f\xf7\xd0\xc7\x3f\x1d\xa8\xde\xfb\x23\xf3\x24\x97\x5e\x92\x1b\xb2\x47\x32\x58\x17\x7a\x16\x61\x25\x67\xed\xf7\xd5\x76\x0f\x3f\x3e\x3a\x6d\x26\xaa\xab\xc5\xfd\xe4\xe2\x04\x3f\x73\xfa\x70\xf1\x28\x02\x09\x33\xb1\xba\x3b\x6b\xd6\x94\x98\xe9\x50\x3e\xa6\x70\xf1\xed\x88\x0d\x36\x51\xf2\xe4\xc5\x9e\x79\xca\xbc\x86\xe9\xb7\x03\x39\x42\x94\x11\x2d\x5d\x8e\x21\x3c\x31\x74\x23\xb5\x25\xa6\xdf\x70\x10\x6a\x9d\x65\x8a\x26\x20\x28\xb5\xf4\x51\x00\xcb\x77\xd1\x15\x0d\x8f\xe4\x61\xee\xd4\x34\xf2\x41\x01\x5f\x32\x76\xad\x7b\x09\xa2\x91\xb4\xa7\xf3\x5e\x3c\x30\x05\x1c\xbf\x13\xb1\xd4\xa7\xfa\x0c\x81\xa5\x0f\x93\x9e\x7c\x49\x67\x3a\xfd\xc8\x78\x83\xc9\xe3\xe6\x1f\x5a\x1d\xf0\x37\x55\x47\x0f\xda\x74\xbf\x23\xea\x88\x67\x6b\x25\x8a\x97\xa2\x80\xd5\xf9\x0b\x52\xb7\x14\xb5\x96\x03\x5b\xae\x08\xc8\xd0\xfe\x6d\x94\xf8\x94\x95\x59\xb1\xf2\x7d\x71\x16\xcf\x59\xdd\x3c\xfb\xf1\x82\x02\xa0\x9c\x13\xf5\xc4\xfb\xc8\xd9\x72\x25\x49\x28\x87\xd3\x28\x70\xc2\x29\x7e\x34\xde\xbd\x98\x76\xd6\xd0\x1a\xc2\x7a\x16\xb0\x88\xb0\x79\x07\x9f\x2b\x20\xfe\xb0\x25\x37\xcd\xa3\x14\xc4\x3c\xb2\xdc\xa3\x71\xb9\xdf\x37\xed\x11\xec\x97\xe1\xa7\xa6\x99\x3a"}, +{{0x7b,0x06,0xf8,0x80,0x26,0xfa,0x86,0xf3,0x9f,0xce,0x24,0x26,0xf6,0x7c,0xc5,0x99,0x6b,0xed,0xd0,0xcf,0xc4,0xb5,0xeb,0xb1,0xb5,0xe3,0xed,0xbb,0x47,0xe0,0x80,0xaa,},{0x3f,0x14,0x69,0xee,0x6a,0x2e,0x78,0x67,0xe2,0xe9,0x01,0x2d,0x40,0x2c,0xf5,0xa4,0x86,0x14,0x97,0xc0,0x1d,0xf8,0x79,0xa1,0xde,0xb1,0xc5,0x39,0x83,0x0b,0x58,0xde,},{0x42,0xf1,0x33,0xe3,0x4e,0x3e,0xb7,0x03,0x2a,0x13,0x3e,0xd7,0x81,0x53,0x7e,0xc6,0x2e,0x44,0xa5,0xce,0x83,0x81,0xe5,0xe0,0xbf,0x9e,0x13,0xa9,0x14,0xa4,0xb2,0xc7,0x57,0x81,0x1d,0x6d,0x3b,0x1e,0x86,0x67,0x24,0x24,0xea,0x42,0x30,0xd1,0x0f,0x7c,0x61,0x0a,0xbb,0x70,0x69,0xe6,0x1e,0x31,0x9b,0x40,0x66,0xa2,0xbd,0x7b,0xc9,0x00,},"\x71\x17\x5d\x4e\x21\x72\x12\x97\xd9\x17\x6d\x81\x7f\x4e\x78\x5d\x96\x00\xd9\x23\xf9\x87\xfe\x0b\x26\xfd\x79\xd3\x3a\x5e\xa5\xd1\xe8\x18\xb7\x1f\x0f\x92\xb8\xc7\x3a\xfd\xda\xbd\xcc\x27\xf6\xd1\x6e\x26\xaa\xfa\x87\x4c\xfd\x77\xa0\x0e\x06\xc3\x6b\x04\x14\x87\x58\x2b\xb9\x33\x76\x0f\x88\xb4\x19\x12\x73\x45\x77\x6e\xa4\x18\xf8\x35\x22\x25\x4f\xed\x33\x81\x9b\xc5\xc9\x5f\x8f\x84\x04\xcc\x14\x4e\xbf\x14\x86\xc8\x85\x15\x40\x9d\x34\x33\xaa\xf5\x19\xd9\x92\x0f\x52\x56\xe6\x29\x41\x9e\x9a\x95\x58\x0a\x35\xb0\x69\xb8\xd2\x55\x33\xdf\xcb\xc9\x8a\xd3\x64\x04\xa9\x51\x80\x8e\x01\x37\x8c\x03\x26\x63\x26\xd1\x20\x04\x69\x75\xfd\xe0\x7d\xae\xf3\x26\x6c\xaa\xcd\x82\x1c\x14\x03\x49\x9d\x7f\xdf\x17\xc0\x33\xc8\xd8\xc3\xf2\x8f\x16\x2b\x5f\x09\xdf\xda\xca\x06\x28\x5f\x00\xc6\xcb\x98\x6d\xfd\xf5\x15\x1a\xa6\x63\x96\x08\xb5\xb1\x3e\x78\xd6\x5a\x43\x68\x58\x5b\x16\x13\x87\x54\xfb\xd1\x13\x83\x5a\x68\x6c\xd0\x66\xc2\xb8\x9b\xb0\x95\x3c\x24\xd5\x0e\x77\xbf\x0f\xc4\x57\xc1\xe0\xfc\xf5\xd4\x4d\xa8\xdb\x9a\x88\xf0\x62\xbe\x3b\x68\x8d\x5c\xdc\xff\x1d\x1c\x00\xe8\x1e\xc9\xd4\x13\x88\x22\x95\xb3\x41\xfe\xe8\xfa\x42\x7d\xc1\x09\xad\xeb\x5f\x28\x4e\xec\x20\x2f\x1b\xef\x11\x5b\xf9\x6b\x17\x82\xd3\xcc\xde\xb6\x82\xb6\x9b\xf9\x2d\x17\x0c\x00\x7d\x5d\xf8\x0e\x1e\xd9\x62\xf6\x77\xdc\x24\xa1\x45\xa1\xe4\xe8\x29\xe8\xde\xc0\x10\x4e\x5f\x78\x36\x59\x44"}, +{{0xc3,0xf5,0xe1,0x49,0x96,0x8a,0x24,0xf4,0xde,0x91,0x19,0x53,0x19,0x75,0xf4,0x43,0x01,0x5c,0xcc,0xa3,0x05,0xd7,0x11,0x9e,0xd4,0x74,0x9e,0x8b,0xf6,0xd9,0x4f,0xc7,},{0x39,0xaa,0xcc,0xdb,0x94,0x8a,0x40,0x38,0x53,0x8a,0x45,0x88,0x32,0x2f,0x80,0x6b,0xb1,0x29,0xb5,0x87,0x6c,0x4b,0xec,0x51,0x27,0x1a,0xfe,0x4f,0x49,0x69,0x00,0x45,},{0x5f,0xa2,0xb5,0x31,0x67,0x7b,0x00,0xb8,0x5b,0x0a,0x31,0x3c,0xbd,0x47,0x9f,0x55,0xf4,0xab,0x3e,0xc5,0xcf,0xce,0x5e,0x45,0x4d,0x2b,0x74,0x17,0x6c,0xcc,0x33,0x99,0xc8,0x99,0xf9,0xd6,0xb5,0x1e,0xd4,0xc1,0xe7,0x61,0x85,0xac,0x9f,0xe7,0x30,0xc4,0xb4,0x01,0x40,0x44,0xf7,0x04,0x11,0x85,0xbc,0x3c,0x85,0x72,0x2e,0xb2,0xea,0x02,},"\xc4\x63\x70\xe3\x7f\x2e\x0c\xad\xcf\x93\x40\x2f\x1f\x0c\xb0\x48\xf5\x28\x81\xba\x75\x0b\x7a\x43\xf5\x6a\xb1\x1c\xe3\x48\x73\x2f\xb5\x7e\x7f\x9a\xaf\x8d\xfc\xbe\x45\x5e\x14\xe9\x83\xc2\x48\xd0\x26\xa2\x7e\x7f\x14\x8d\x5d\xb5\xa5\x3f\x94\x63\x57\x02\xb8\x95\x12\x77\x71\x04\x7a\x87\x6d\x14\x10\x73\x86\xc5\xe0\xff\x89\x33\x34\x5b\xbd\x7a\x93\x6d\x99\x0d\x33\xef\xa2\x8c\x2e\xc4\xe4\x86\x4f\xfd\x2f\xf5\x76\xf7\xc8\x8f\x95\x4c\xfc\x1c\x45\x9e\x88\x3b\xb7\x12\xda\xe3\xcd\xf6\x63\x20\x66\xf1\xf4\xd1\x3a\x50\x96\x15\xb3\x36\x0c\xad\xc5\xa3\x07\xf2\x3e\x52\xa5\x1b\x40\xa6\xfe\xeb\xe0\xb1\x8d\x0e\x9e\xe4\xe3\x48\xf3\x3c\xd8\x1a\x8d\xef\x22\x2f\x6a\x59\xb1\x28\x61\xd3\x35\xbd\x9a\xf8\x5c\xc0\x04\xbe\x46\xf1\xd3\xa4\x24\xf4\x87\x0a\xe9\xdc\x58\x7e\x5a\x4a\xde\x13\x6b\x93\x70\x64\x93\x48\xc3\x3a\xc3\xbf\x1f\xeb\xee\xbf\xfe\xa3\x70\x85\xed\x59\xca\xc9\xd9\xe6\x96\x47\x0b\x23\x46\x09\xe9\xa1\x0a\x9d\x43\x1f\xf9\x1e\x69\xcb\x51\x35\xfd\x11\x7f\xf5\x8a\x36\x53\x97\x44\xeb\xe7\x0c\xea\x69\x73\xc0\x0c\x7a\x4d\x57\xb6\x2f\x4a\x71\x36\xd7\x31\xb8\xe4\x6f\xf1\x8e\xc0\xed\x69\x07\x00\x31\x90\x50\x75\xd8\x54\x1d\x56\x8c\xfc\xe6\xee\xb7\x62\x42\xb7\x81\x9a\x7b\x6a\x93\x55\x21\x11\xbb\x88\xf1\x65\x52\x7c\xfa\x69\x66\xd3\x9f\xcb\xe0\xa7\xde\xa0\x08\xe3\x9c\x7a\x3e\x57\x7a\xb3\x07\xcd\x1d\x0e\xa3\x26\x83\x3d\x52\x65\x4e\x17\x29\x55\xf3\xfc\xd4"}, +{{0x42,0x30,0x5c,0x93,0x02,0xf4,0x5e,0xa6,0xf8,0x7e,0x26,0xe2,0x20,0x8f,0xd9,0x4b,0x3c,0x4a,0xd0,0x37,0xb1,0xb6,0xc8,0x3c,0xf6,0x67,0x7a,0xa1,0x09,0x6a,0x01,0x3c,},{0x3b,0x97,0xb1,0xf1,0x1c,0xe4,0x5b,0xa4,0x6f,0xfb,0xb2,0x5b,0x76,0xbf,0xc5,0xad,0x7b,0x77,0xf9,0x0c,0xc6,0x9e,0xd7,0x61,0x15,0xde,0xa4,0x02,0x94,0x69,0xd5,0x87,},{0x18,0xd0,0x5e,0x5d,0x01,0x66,0x8e,0x83,0xf4,0x0f,0xa3,0xbb,0xee,0x28,0xb3,0x88,0xac,0xf3,0x18,0xd1,0xb0,0xb5,0xad,0x66,0x8c,0x67,0x2f,0x34,0x5c,0x8e,0xda,0x14,0xc2,0xf8,0x84,0xcd,0x2a,0x90,0x39,0x45,0x9c,0xe0,0x81,0x0b,0xc5,0xb5,0x80,0xfe,0x70,0xd3,0x96,0x4a,0x43,0xed,0xb4,0x9e,0x73,0xa6,0xff,0x91,0x4b,0xbf,0x04,0x0c,},"\xd1\x10\x82\x8d\x44\x91\x98\xd6\x75\xe7\x4e\x8e\x39\x43\x9f\xd1\x5e\x75\xbf\x2c\xc1\xf4\x30\xab\xfb\x24\x58\x36\x88\x5b\xaf\xc4\x20\xf7\x54\xb8\x9d\x2f\xbb\xf6\xdd\x34\x90\x79\x2e\x7a\x4f\x76\x60\x73\xcf\xe3\xb3\x02\xd0\x89\x83\x1a\xce\x86\x9e\x27\x30\xfd\xe4\x5c\x21\x21\xec\x3e\xf2\x17\xaa\x9c\x43\xfa\x7c\xc7\xe9\xed\x0a\x01\xad\x9f\x1d\x2f\xc3\x61\x36\x38\xca\x9f\xc1\x93\xc9\x8b\x37\x45\x5b\xf5\xdb\xf8\xf3\x8b\x64\x70\x8d\xfd\xca\x6c\x21\xf0\x97\x5f\x10\x17\xc5\xda\x5f\x64\x34\xbd\xa9\xf0\x33\xce\xc2\xa6\x31\xab\x50\x31\x8e\x01\x7b\x17\x0b\x24\x0b\xf0\x1e\xb8\xb3\x6c\x7e\x1c\xb5\x9e\x77\x36\xac\x34\x44\x42\x08\x13\x2a\x8f\x59\xe4\xf3\x13\xd6\x5d\x84\x9c\x6a\x4f\xdf\x13\xe2\x0e\xca\xee\x38\x23\xe5\x89\xa1\x71\xb3\x9b\x24\x89\x49\x7b\x06\xe6\xff\x58\xc2\xc9\xf1\xdc\x5d\x3a\xa3\xbd\x10\xe6\x44\x3e\x22\xd4\x2d\x07\xb7\x83\xf7\x9f\xd4\x3a\x46\xe1\xcd\xe3\x14\xb6\x63\xa9\x5f\x72\x46\xde\xa1\x31\xfc\xd4\x6d\x1d\xc3\x33\xc5\x45\x4f\x86\xb2\xc4\xe2\xe4\x24\xde\xa4\x05\xcc\x22\x30\xd4\xdc\xd3\x9a\x2e\xab\x2f\x92\x84\x5c\xf6\xa7\x99\x41\x92\x06\x3f\x12\x02\x74\x9e\xf5\x2d\xcb\x96\xf2\xb7\x9e\xd6\xa9\x81\x18\xca\x0b\x99\xba\x22\x85\x49\x08\x60\xeb\x4c\x61\xab\x78\xb9\xdd\xc6\xac\xc7\xad\x88\x3f\xa5\xe9\x6f\x9d\x02\x91\x71\x22\x3a\xbf\x75\x73\xe3\x62\x30\xe0\xa8\x1f\x6c\x13\x11\x15\x14\x73\xee\x26\x4f\x4b\x84\x2e\x92\x3d\xcb\x3b"}, +{{0xc5,0x7a,0x43,0xdc,0xd7,0xba,0xb8,0x51,0x60,0x09,0x54,0x69,0x18,0xd7,0x1a,0xd4,0x59,0xb7,0x34,0x5e,0xfd,0xca,0x8d,0x4f,0x19,0x92,0x98,0x75,0xc8,0x39,0xd7,0x22,},{0x20,0x83,0xb4,0x44,0x23,0x6b,0x9a,0xb3,0x1d,0x4e,0x00,0xc8,0x9d,0x55,0xc6,0x26,0x0f,0xee,0x71,0xac,0x1a,0x47,0xc4,0xb5,0xba,0x22,0x74,0x04,0xd3,0x82,0xb8,0x2d,},{0x1e,0xde,0xf9,0xbc,0x03,0x69,0x71,0xf1,0xfa,0x88,0xed,0xf4,0x53,0x93,0xc8,0x02,0xe6,0xc1,0xa1,0x63,0x1c,0x8a,0x06,0x87,0x1a,0x09,0xa3,0x20,0x82,0x1d,0xce,0x40,0xbe,0xca,0x97,0xe5,0x3a,0x03,0x61,0xa9,0x55,0xa4,0xc6,0xd6,0x0b,0x8c,0xa8,0xe4,0x00,0xc8,0x13,0x40,0x91,0x1c,0xcb,0x4f,0x56,0x28,0x40,0x41,0xcd,0xbb,0x18,0x04,},"\xa4\xf6\xd9\xc2\x81\xcf\x81\xa2\x8a\x0b\x9e\x77\x49\x9a\xa2\x4b\xde\x96\xcc\x12\x64\x37\x44\x91\xc0\x08\x29\x4e\xe0\xaf\x6f\x6e\x4b\xbb\x68\x63\x96\xf5\x90\x68\xd3\x58\xe3\x0f\xe9\x99\x2d\xb0\xc6\xf1\x66\x80\xa1\xc7\x1e\x27\xa4\xa9\x07\xac\x60\x7d\x39\xbd\xc3\x25\x8c\x79\x56\x48\x2f\xb3\x79\x96\xf4\xbe\xb3\xe5\x05\x1b\x81\x48\x01\x9a\x1c\x25\x6e\x2e\xe9\x99\xeb\xc8\xce\x64\xc5\x4e\x07\xfe\xdb\x4f\xbd\x89\x53\xeb\xd9\x3b\x7d\x69\xce\x5a\x00\x82\xed\xd6\x20\x9d\x12\xd3\x61\x9b\x4f\xd2\xea\xe9\x16\x46\x1f\x72\xa4\xce\x72\x71\x57\x25\x1a\x19\x20\x9b\xbf\xf9\xfb\xdb\xd2\x89\x43\x6f\x3f\xca\xcc\x6b\x4e\x13\x18\x52\x1a\x47\x83\x9c\xba\x4b\x14\xf7\xd7\xa2\x1e\x7b\x5d\x6b\x6a\x75\x3d\x58\x04\xaf\xcd\x2b\x1e\xb7\x77\x9b\x92\xab\xab\x8a\xfa\x8a\xa4\xfa\x51\xca\xec\x0b\x85\xdc\xd0\xfc\x2a\x06\x76\x03\x6d\x3f\x56\x63\x0a\x83\x1f\xfe\xb5\x02\x86\x1d\xd8\x91\x61\xc7\x08\xa9\xc0\x06\xc7\x3c\x93\x0c\xe5\xb9\x47\x56\x42\x6f\xf1\x8a\xa1\x12\xfb\x4e\xb9\xa6\x85\x00\xb4\x8d\x4e\xed\xbd\x41\x67\xb6\xff\xd0\xa1\x1d\x49\x44\x3a\x17\x3c\xe9\xd9\x49\x43\x67\x48\xfc\x06\x34\xf0\x6b\xb0\x8b\x8f\x34\x23\xf4\x46\x3d\xba\x7b\x4d\x19\x9b\x64\xdf\x57\x81\x17\xf0\xa2\x64\x5f\x0b\x2a\x1e\x2a\xda\x27\xd2\x86\xf7\x67\x33\xf2\x5b\x82\xed\x1d\x48\xa5\xc3\x89\x8d\x4a\xd6\x21\xe5\x0e\xd9\x06\x0d\xaa\xd4\x0a\x39\x53\x2e\x4d\x1b\xf1\x62\xce\x36\x80\x4d\x5d\x4e\x2d"}, +{{0x2d,0xdd,0xb6,0xb8,0xfd,0x04,0xfa,0x90,0xec,0xe1,0xa7,0x09,0xf8,0x41,0x8f,0x2e,0x5d,0x0c,0x9c,0x43,0xaf,0xe7,0xcf,0xce,0x19,0xe6,0xad,0x15,0xa7,0x34,0x76,0xf7,},{0x80,0x59,0xde,0x6a,0x7c,0x47,0x76,0x48,0x9e,0xcc,0x2e,0x7d,0x70,0x7f,0xfc,0xe3,0x02,0x85,0xbf,0x30,0xa2,0x3f,0x78,0xd7,0x2d,0xb4,0x9c,0xfd,0x6e,0xd0,0xd4,0x92,},{0xc6,0x34,0xea,0x7b,0xf7,0x2e,0x89,0x5a,0x2e,0x79,0x6e,0x28,0x34,0x20,0x14,0x15,0xb8,0xb4,0x5e,0x05,0xe0,0x45,0x55,0x92,0x84,0xeb,0x90,0x52,0xc0,0xe8,0x4f,0x62,0xa5,0xa9,0xf0,0xc9,0x76,0x4f,0x75,0x76,0x78,0x8c,0x72,0x28,0xb1,0x9e,0xf5,0x17,0xc1,0x95,0x49,0x73,0x25,0xa4,0x8a,0x93,0x44,0xb1,0x47,0xc1,0x2f,0xd7,0x55,0x09,},"\x47\x4b\xaa\x59\x0a\x4c\xd7\x2d\x54\x24\xe5\x1d\x82\x57\xb3\xd4\x43\x25\xbc\x4c\x50\x63\xa0\x03\x3c\x86\xeb\xbe\x99\xed\x72\x12\x18\x4c\x19\x94\x4d\x08\x2a\x11\x53\x79\xdd\x4c\xec\xe9\x73\xfa\xa0\xbc\xa6\x48\x5b\xd2\x5f\x37\x44\xa7\x19\xe7\x0a\xa0\x29\x1e\x1b\x5a\x96\xe6\x37\xc1\x40\x61\x6a\x98\x26\x33\x57\xc7\x6b\x6e\xb0\x08\x3f\xe5\x14\x14\xe3\x86\x87\x0d\x0f\xdc\x7d\xd9\xab\xe4\xff\x6f\xb5\xbb\xf1\xe7\xb1\x5d\xac\x3e\x08\xe2\x61\x5f\x65\x5c\x31\x04\xce\xb3\x2a\x4c\xc2\xc9\xe9\xc4\x3c\xf2\x82\xd3\x46\xac\x25\x3c\xcc\x46\xb6\x35\xae\x04\x09\x73\xb4\x97\x35\x72\x0f\xfb\x89\x04\x69\xa5\x67\xc5\x82\x4e\x0c\x00\xd7\xcc\xd5\x50\x9a\x71\x80\x92\xa9\x06\x46\x1c\x4d\x61\x63\xea\xf4\x22\x41\x8f\x5f\xc6\xe0\x09\xfc\x3f\x52\x9a\xc6\x1a\x2f\x89\xbb\x8e\x0e\xd4\x5d\x94\x0c\x4c\x23\x31\xff\x8d\x8e\x1d\x6d\x58\xd4\x17\xd8\xfc\x26\x56\xa0\x2e\x87\x01\xae\xe7\x5a\xed\x91\x87\x24\xee\xbe\x4a\x2c\xf4\x74\x4c\x5c\x40\x1e\x21\x70\x23\xdf\x68\xa6\xf6\xa0\x22\x8b\xd0\x5a\x67\x9a\x69\x7d\x8d\xe7\x03\x6b\x9e\xd2\x69\x09\x0d\x3c\x65\x48\x6a\xfb\x91\xe2\x79\x54\xeb\x15\xb9\x64\x66\x5e\xde\x7a\xd0\x08\xf1\x2f\xb3\xa9\xd0\xe6\x9c\x13\xb4\x25\x4f\x43\x81\x9e\x08\x18\xa4\x19\x5f\x68\xb8\xa3\x8a\xe8\x1f\x3f\xcb\x18\x79\xc9\x5a\xb4\xcd\x0f\xfc\x38\xe3\x81\x08\x92\x60\xcc\xa9\x67\xac\xe5\xa0\x85\xb4\x57\xab\x5e\xb3\x63\x85\x21\x01\x37\x75\x70\xf9\xac\x9e\x38"}, +{{0x55,0x47,0xf1,0x00,0x4b,0xae,0xdf,0xce,0x5c,0xfc,0x08,0x50,0xb0,0x53,0x02,0x37,0x4a,0xad,0x24,0xf6,0x16,0x39,0x94,0xec,0xd7,0x51,0xdf,0x3a,0xf3,0xc1,0x06,0x20,},{0x7c,0xe6,0x20,0x78,0x73,0x85,0xee,0x19,0x51,0xac,0x49,0xa7,0x73,0x52,0xee,0x0d,0x6f,0x8c,0x5c,0xd4,0x7d,0xf7,0x4e,0x9e,0x32,0x16,0xa6,0x32,0x4f,0xc7,0xcf,0x7f,},{0x29,0xdf,0x3a,0xd5,0x89,0x00,0x9c,0x66,0x7b,0xaa,0x5e,0x72,0xda,0xbb,0x4e,0x53,0xcb,0x78,0x76,0xde,0x4e,0x7e,0xfe,0x5c,0xc2,0x1e,0xad,0x7f,0xa8,0x78,0xdb,0x57,0xf9,0x7c,0x11,0x03,0xdd,0xb3,0x9a,0x86,0x1e,0xb8,0x86,0x53,0xc1,0xd4,0xec,0x3b,0x43,0x06,0xe4,0x58,0x4b,0x47,0xb8,0xbc,0x90,0x42,0x31,0x19,0xe7,0xe4,0xaf,0x00,},"\xa6\xc1\x7e\xeb\x5b\x80\x66\xc2\xcd\x9a\x89\x66\x73\x17\xa9\x45\xa0\xc7\xc9\x69\x96\xe7\x7a\xe8\x54\xc5\x09\xc6\xcd\x06\x31\xe9\x22\xad\x04\x50\x3a\xf8\x7a\x3c\x46\x28\xad\xaf\xed\x76\x00\xd0\x71\xc0\x78\xa2\x2e\x7f\x64\xbd\xa0\x8a\x36\x2b\x38\xb2\x6c\xa1\x50\x06\xd3\x8a\xcf\x53\x2d\x0d\xed\xea\x41\x77\xa2\xd3\x3f\x06\x95\x6d\x80\xe9\x63\x84\x8e\xc7\x91\xb2\x76\x2f\xa9\x94\x49\xb4\xf1\xa1\xed\x9b\x3f\x25\x80\xbe\x3a\xc7\xd7\xf5\x2f\xb1\x44\x21\xd6\x22\x2b\xa7\x6f\x80\x77\x50\xc6\xcb\xb0\xb1\x6f\x08\x95\xfc\x73\xd9\xdf\xc5\x87\xe1\xa9\xe5\xd1\xe5\x83\x75\xfb\xab\x70\x5b\x8f\x0c\x1f\xd7\xdf\x8b\x3a\xd4\x46\xf2\xf0\x84\x59\xe7\xed\x1a\xf5\x95\x56\xfb\xc9\x66\xdc\x24\x9c\x1c\xf6\x04\xf3\xe6\x77\xc8\xa0\x9d\x43\x63\x60\x87\x74\xbf\x38\x11\xbe\xf0\x64\x27\x48\xc5\x5c\x51\x6c\x7a\x58\x0f\xa3\x49\x90\x50\xac\xb3\x0e\xed\x87\x0d\x0d\x91\x17\x4c\xb6\x23\xe9\x8c\x3a\xd1\x21\xcf\x81\xf0\x4e\x57\xd4\x9b\x00\x84\x24\xa9\x8a\x31\xee\xaa\xf5\xf3\x8e\x00\x0f\x90\x3d\x48\xd2\x15\xed\x52\xf8\x62\xd6\x36\xa5\xa7\x36\x07\xde\x85\x76\x01\x67\x26\x7e\xfe\x30\xf8\xa2\x6e\xbc\x5a\xa0\xc0\x9f\x5b\x25\x8d\x33\x61\xca\x69\xd1\xd7\xee\x07\xb5\x96\x48\x17\x9a\xb2\x17\x0e\xc5\x0c\x07\xf6\x61\x6f\x21\x68\x72\x52\x94\x21\xa6\x33\x4a\x4a\x1e\xd3\xd2\x67\x1e\xf4\x7b\xc9\xa9\x2a\xfb\x58\x31\x4e\x83\x2d\xb8\xa9\x00\x34\x08\xa0\x48\x75\x03\xfe\x4f\x67\x77\x0d\xd4\xb6"}, +{{0x3d,0xd7,0x20,0x3c,0x23,0x7a,0xef,0xe9,0xe3,0x8a,0x20,0x1f,0xf3,0x41,0x49,0x01,0x79,0x90,0x5f,0x9f,0x10,0x08,0x28,0xda,0x18,0xfc,0xbe,0x58,0x76,0x8b,0x57,0x60,},{0xf0,0x67,0xd7,0xb2,0xff,0x3a,0x95,0x7e,0x83,0x73,0xa7,0xd4,0x2e,0xf0,0x83,0x2b,0xcd,0xa8,0x4e,0xbf,0x28,0x72,0x49,0xa1,0x84,0xa2,0x12,0xa9,0x4c,0x99,0xea,0x5b,},{0x4c,0x03,0x69,0x35,0xa9,0x6a,0xbc,0x0d,0x05,0x0d,0x90,0x7b,0xed,0xbe,0x99,0x46,0xfb,0x97,0x43,0x9f,0x03,0x9c,0x74,0x2e,0x05,0x1c,0xcf,0x09,0xad,0xd7,0xdf,0x44,0xd1,0x7d,0xa9,0x8c,0x2c,0xa0,0x1b,0xdc,0x24,0x24,0xda,0x1e,0x4d,0xeb,0xf3,0x47,0xf8,0xff,0xf4,0x8a,0xc8,0x03,0x0d,0x2c,0xc0,0x7f,0x95,0x75,0xc0,0x44,0xbe,0x04,},"\xdb\x28\xed\x31\xac\x04\xb0\xc2\xde\xce\xe7\xa6\xb2\x4f\xc9\xa0\x82\xcc\x26\x2c\xa7\xcc\xf2\xa2\x47\xd6\x37\x2e\xc3\xe9\x12\x0e\xce\xdb\x45\x42\xea\x59\x3f\xea\x30\x33\x5c\x5a\xb9\xdd\x31\x8a\x3b\x4f\xd5\x83\x42\x99\xcf\x3f\x53\xd9\xef\x46\x13\x7b\x27\x3c\x39\x0e\xc3\xc2\x6a\x0b\x44\x70\xd0\xd9\x4b\x77\xd8\x2c\xae\x4b\x24\x58\x78\x37\xb1\x67\xbb\x7f\x81\x66\x71\x0b\xae\xb3\xee\x70\xaf\x79\x73\x16\xcb\x7d\x05\xfa\x57\xe4\x68\xae\x3f\x0b\xd4\x49\x40\x4d\x85\x28\x80\x8b\x41\xfc\xca\x62\xf5\xe0\xa2\xaa\x5d\x8f\x3a\xca\xb0\x08\xcc\x5f\x6e\x5a\xb0\x27\x77\xbd\xcd\xe8\x7f\x0a\x10\xef\x06\xa4\xbb\x37\xfe\x02\xc9\x48\x15\xcf\x76\xbf\xb8\xf5\xcd\xd8\x65\xcc\x26\xdc\xb5\xcf\x49\x2e\xdf\xd5\x47\xb5\x35\xe2\xe6\xa6\xd8\x54\x09\x56\xdc\xba\x62\xcf\xea\x19\xa9\x47\x44\x06\xe9\x34\x33\x7e\x45\x42\x70\xe0\x10\x36\xac\x45\x79\x3b\x6b\x8a\xce\xda\x18\x7a\x08\xd5\x6a\x2c\xe4\xe9\x8f\x42\xea\x37\x5b\x10\x1a\x6b\x9f\xcb\x42\x31\xd1\x71\xaa\x46\x3e\xeb\x43\x58\x6a\x4b\x82\xa3\x87\xbc\xdd\xaf\x71\xa8\x0f\xd5\xc1\xf7\x29\x2e\xfc\x2b\xd8\xe7\x0c\x11\xea\xa8\x17\x10\x60\x61\xb6\xc4\x61\xc4\x88\x3d\x61\x3c\xc0\x6c\x7e\x2a\x03\xf7\x3d\x90\xfc\x55\xcd\xc0\x72\x65\xee\xfd\x36\xbe\x72\x27\x03\x83\xd6\xc6\x76\xca\xe3\x7c\x93\x69\x1f\x1a\xe3\xd9\x27\xb3\xa1\xcd\x96\x3e\x42\x29\x75\x7a\xe5\x23\x1e\xea\x73\xa9\xf7\x15\x15\x62\x83\x05\x41\x0a\xc2\x59\x3b\x32\x5c\xc6\x31"}, +{{0x28,0x27,0x75,0xdf,0x9e,0xbb,0xd7,0xc5,0xa6,0x5f,0x3a,0x2b,0x09,0x6e,0x36,0xee,0x64,0xa8,0xf8,0xea,0x71,0x9d,0xa7,0x77,0x58,0x73,0x9e,0x4e,0x74,0x76,0x11,0x1d,},{0xa2,0xb4,0x96,0x46,0x03,0x3a,0x13,0x93,0x7c,0xad,0x6b,0x0e,0x91,0x4e,0x3c,0xec,0x54,0x98,0x9c,0x25,0x2c,0xa5,0x64,0x3d,0x07,0x65,0x55,0xd8,0xc5,0x5e,0x56,0xe0,},{0x15,0x76,0x39,0x73,0x85,0x94,0x02,0x90,0x7d,0x8d,0xcb,0x86,0xad,0xc2,0x4a,0x2a,0x16,0x8b,0xa3,0xab,0xf2,0x24,0x61,0x73,0xd6,0x34,0x8a,0xfe,0xd5,0x1e,0xf6,0x0b,0x0c,0x0e,0xde,0xff,0x4e,0x10,0xbc,0xef,0x4c,0x6e,0x57,0x78,0xc8,0xbc,0x1f,0x5e,0x9e,0xe0,0x23,0x73,0x73,0x44,0x5b,0x45,0x51,0x55,0xd2,0x3d,0xe1,0x27,0xa2,0x02,},"\x14\xcc\x50\xc2\x97\x3e\xa9\xd0\x18\x7a\x73\xf7\x1c\xb9\xf1\xce\x07\xe7\x39\xe0\x49\xec\x2b\x27\xe6\x61\x3c\x10\xc2\x6b\x73\xa2\xa9\x66\xe0\x1a\xc3\xbe\x8b\x50\x5a\xea\xad\x14\x85\xc1\xc2\xa3\xc6\xc2\xb0\x0f\x81\xb9\xe5\xf9\x27\xb7\x3b\xfd\x49\x86\x01\xa7\x62\x2e\x85\x44\x83\x7a\xad\x02\xe7\x2b\xf7\x21\x96\xdc\x24\x69\x02\xe5\x8a\xf2\x53\xad\x7e\x02\x5e\x36\x66\xd3\xbf\xc4\x6b\x5b\x02\xf0\xeb\x4a\x37\xc9\x55\x49\x92\xab\xc8\x65\x1d\xe1\x2f\xd8\x13\x17\x73\x79\xbb\x0c\xe1\x72\xcd\x8a\xaf\x93\x7f\x97\x96\x42\xbc\x2e\xd7\xc7\xa4\x30\xcb\x14\xc3\xcd\x31\x01\xb9\xf6\xb9\x1e\xe3\xf5\x42\xac\xdf\x01\x7f\x8c\x21\x16\x29\x7f\x45\x64\x76\x8f\x4d\xb9\x5d\xad\x8a\x9b\xcd\xc8\xda\x4d\x8f\xb1\x3e\xf6\xe2\xda\x0b\x13\x16\xd3\xc8\xc2\xf3\xed\x83\x6b\x35\xfe\x2f\xd3\x3e\xff\xb4\x09\xe3\xbc\x1b\x0f\x85\x22\x5d\x2a\x1d\xe3\xbf\xc2\xd2\x05\x63\x94\x64\x75\xc4\xd7\xca\x9f\xdd\xba\xf5\x9a\xd8\xf8\x96\x1d\x28\x7a\xe7\xdd\x80\x3e\x7a\xf1\xfa\x61\x23\x29\xb1\xbd\xc0\x4e\x22\x56\x00\xae\x73\x1b\xc0\x1a\xe0\x92\x5a\xed\x62\xac\x50\xd4\x60\x86\xf3\x64\x6c\xf4\x7b\x07\x2f\x0d\x3b\x04\x4b\x36\xf8\x5c\xec\x72\x9a\x8b\xb2\xb9\x28\x83\xca\x4d\xfb\x34\xa8\xee\x8a\x02\x73\xb3\x1a\xf5\x09\x82\xbb\x61\x31\xbf\xa1\x1d\x55\x50\x4b\x1f\x6f\x1a\x0a\x00\x43\x8c\xa2\x6d\x8a\xb4\xf4\x8b\xcd\xdc\x9d\x5a\x38\x85\x1a\xbe\xde\x41\x51\xd5\xb7\x0d\x72\x07\x32\xa0\x0a\xbe\xa2\xc8\xb9\x79"}, +{{0x47,0x30,0xa5,0xcf,0x97,0x72,0xd7,0xd6,0x66,0x5b,0xa7,0x87,0xbe,0xa4,0xc9,0x52,0x52,0xe6,0xec,0xd6,0x3e,0xc6,0x23,0x90,0x54,0x7b,0xf1,0x00,0xc0,0xa4,0x63,0x75,},{0xf9,0xf0,0x94,0xf7,0xcc,0x1d,0x40,0xf1,0x92,0x6b,0x5b,0x22,0xdc,0xe4,0x65,0x78,0x44,0x68,0xb2,0x0a,0xb3,0x49,0xbc,0x6d,0x4f,0xdf,0x78,0xd0,0x04,0x2b,0xbc,0x5b,},{0x55,0x2c,0x73,0x47,0xbd,0xfe,0x13,0x16,0x46,0xce,0x09,0x32,0xd8,0x2a,0x36,0xd2,0xc1,0xb7,0x6d,0x7c,0x30,0xee,0x89,0x0e,0x05,0x92,0xe1,0x9f,0x9d,0x18,0xb9,0xa5,0x6f,0x48,0xd7,0xa9,0xb6,0x8c,0x01,0x7d,0xa6,0xb5,0x50,0xc9,0x43,0xaf,0x4a,0x90,0x7b,0xaf,0x31,0x7e,0x41,0x9f,0xbb,0xc9,0x6f,0x6c,0xf4,0xbf,0xad,0x42,0xde,0x00,},"\xe7\x47\x6d\x2e\x66\x84\x20\xe1\xb0\xfa\xdf\xba\xa5\x42\x86\xfa\x7f\xa8\x90\xa8\x7b\x82\x80\xe2\x60\x78\x15\x22\x95\xe1\xe6\xe5\x5d\x12\x41\x43\x5c\xc4\x30\xa8\x69\x3b\xb1\x0c\xde\x46\x43\xf5\x9c\xbf\xcc\x25\x6f\x45\xf5\x09\x0c\x90\x9a\x14\xc7\xfc\x49\xd3\x7b\xfc\x25\xaf\x11\xe8\xf4\xc8\x3f\x4c\x32\xd4\xaa\xbf\x43\xb2\x0f\xa3\x82\xbb\x66\x22\xa1\x84\x8f\x8f\xfc\x4d\xff\x34\x08\xbb\x4e\xc7\xc6\x7a\x35\xb4\xcd\xae\xe5\xe2\x79\xc0\xfc\x0a\x66\x09\x3a\x9f\x36\xa6\x0f\xdd\x65\xe6\x33\x4a\x80\x4e\x84\x5c\x85\x30\xb6\xfd\xa3\x63\xb5\x64\x03\x37\xd0\x27\x24\x3c\xcf\xb3\xc1\x77\xf4\x3e\x71\x78\x96\xe4\x6e\xad\x7f\x72\xca\x06\xaa\x0f\xf1\xe7\x72\x47\x12\x1b\xaf\x48\xbe\x9a\x44\x5f\x72\x9c\xa1\x39\x0f\xc4\x61\x51\xcb\xd3\x3f\xcb\xd7\x37\x3f\x27\xa6\xba\x55\xc9\x2c\xbf\x69\x45\xb0\x9b\x44\xb9\xa4\xe5\x80\x0d\x40\x30\x70\xae\x66\x04\x89\x97\xb2\x19\x7f\x02\x18\x1a\x09\x7e\x56\x3f\x9b\x9a\xcc\x84\x11\x39\x25\x8a\x25\x8b\xc6\x10\xd3\xbd\x89\x16\x37\x35\x6b\x2e\xdc\x8c\x18\x4c\x35\xc6\x5a\xf9\x1a\xaf\x7b\x1c\x16\xd7\x4a\x5f\x5f\x86\x25\x48\x13\x92\x54\xec\xf5\x50\x63\x1d\x5f\x88\x49\xaf\xdb\x5b\x64\xcf\x36\x6f\xf2\x63\x3a\x93\xf3\xa1\x8c\x39\xb5\x15\x02\x45\xfb\x5f\x33\xc9\xe4\xe2\xd9\x4a\xf6\x96\x3a\x70\xb8\x8f\x9e\x7e\x51\x9f\x8f\xa2\xa0\xf2\xe3\x74\x9d\xe8\x83\xd0\xe6\xf0\x52\xa9\x49\xd0\xfc\x71\x53\xa8\x69\x3f\x6d\x80\x1d\x73\x52\xeb\x2f\x7a\x46\x5c\x0e"}, +{{0x27,0x70,0xaa,0xdd,0x1d,0x12,0x3e,0x95,0x47,0x83,0x2d,0xfb,0x2a,0x83,0x7e,0xba,0x08,0x91,0x79,0xef,0x4f,0x23,0xab,0xc4,0xa5,0x3f,0x2a,0x71,0x4e,0x42,0x3e,0xe2,},{0x3c,0x5f,0xbb,0x07,0x53,0x0d,0xd3,0xa2,0x0f,0xf3,0x5a,0x50,0x0e,0x37,0x08,0x92,0x63,0x10,0xfe,0xd8,0xa8,0x99,0x69,0x02,0x32,0xb4,0x2c,0x15,0xbd,0x86,0xe5,0xdc,},{0xf2,0x67,0x71,0x5e,0x9a,0x84,0xc7,0x31,0x4f,0x2d,0x58,0x69,0xef,0x4a,0xb8,0xd2,0x14,0x9a,0x13,0xf7,0xe8,0xe1,0xc7,0x28,0xc4,0x23,0x90,0x62,0x93,0xb4,0x9c,0xe6,0x28,0x34,0x54,0xdd,0x1c,0x7b,0x04,0x74,0x1d,0xf2,0xea,0xbe,0xdc,0x4d,0x6a,0xb1,0x39,0x7d,0xc9,0x5a,0x67,0x9d,0xf0,0x4d,0x2c,0x17,0xd6,0x6c,0x79,0xbb,0x76,0x01,},"\xa5\xcc\x20\x55\xeb\xa3\xcf\x6f\x0c\x63\x32\xc1\xf2\xab\x58\x54\x87\x09\x13\xb0\x3f\xf7\x09\x3b\xc9\x4f\x33\x5a\xdd\x44\x33\x22\x31\xd9\x86\x9f\x02\x7d\x82\xef\xd5\xf1\x22\x71\x44\xab\x56\xe3\x22\x2d\xc3\xdd\xcc\xf0\x62\xd9\xc1\xb0\xc1\x02\x4d\x9b\x41\x6d\xfa\x3e\xe8\xa7\x02\x79\x23\x00\x34\x65\xe0\xff\xae\xfb\x75\xb9\xf2\x9d\xc6\xbc\xf2\x13\xad\xc5\xe3\x18\xfd\x8b\xa9\x3a\x7a\xa5\xbf\xb4\x95\xde\x9d\x7c\x5e\x1a\x19\x6c\xd3\xa2\xd7\x72\x1f\x8b\xa7\x85\xaa\x90\x52\xa1\x81\x1c\x7f\xcc\x8f\x93\x93\x27\x65\x05\x9c\xab\x9c\x9b\x71\x89\x45\x89\x5e\xf2\x6f\x3a\xc0\x48\xd4\xca\xbf\x91\xa9\xe6\xaa\x83\xac\x14\xd4\x31\x56\x82\x78\x37\x91\x4e\xb7\x63\xa2\x3c\xba\x53\xf6\x0f\x15\x0f\x4b\x70\x20\x3e\xc1\x83\x3f\xf1\x05\x84\x94\x57\xa8\xda\x73\x27\x66\x1f\xb2\x3a\x55\x41\x64\xe0\x5f\xcf\x01\x46\xb1\x06\x74\x96\x4b\xe6\xf6\xaa\x0a\xcc\x94\xc4\x1a\xd5\x71\x80\xe5\x18\x0d\x19\x9b\xd9\x10\x2f\x55\xd7\x40\xe8\x17\x89\xb1\x56\x71\xbb\xd0\x67\x0e\x6d\xe5\xd9\x7e\x1a\xe6\x26\xd8\xa0\xeb\xc3\x2c\x8f\xd9\xd2\x47\x37\x27\x4e\x47\xd2\xdd\x59\x41\xa2\x72\xe7\x2a\x59\x89\x28\xad\x10\x9c\xde\x93\x7b\xf2\x48\xd5\x7f\x5d\x29\x42\x98\x3c\x51\xe2\xa8\x9f\x8f\x05\x4d\x5c\x48\xdf\xad\x8f\xcf\x1f\xfa\x97\xf7\xde\x6a\x3a\x43\xca\x15\xfc\x67\x20\xef\xae\xc6\x9f\x08\x36\xd8\x42\x23\xf9\x77\x6d\x11\x1e\xc2\xbb\xc6\x9b\x2d\xfd\x58\xbe\x8c\xa1\x2c\x07\x21\x64\xb7\x18\xcd\x7c\x24\x6d\x64"}, +{{0x4f,0xda,0xb7,0xc1,0x60,0x0e,0x70,0x11,0x4b,0x11,0xf5,0x33,0x24,0x23,0x76,0xaf,0x76,0x14,0xb4,0xd5,0xda,0x04,0x6a,0xc4,0xbe,0xde,0xa2,0x1d,0x8a,0x36,0x15,0x98,},{0xa2,0x5c,0x9a,0x94,0xd6,0xe4,0xec,0xd9,0x5a,0x4b,0xd6,0x80,0x5f,0x76,0x2e,0xb1,0xc4,0x57,0xa8,0xd4,0x5d,0x24,0x32,0x38,0xb1,0x83,0x9c,0xbb,0xa8,0xf4,0x41,0xcc,},{0x50,0x75,0xc0,0x90,0xcf,0xbe,0xb6,0xb0,0x18,0x02,0xaf,0x7f,0x4d,0xa5,0xaa,0x4f,0x43,0x4d,0x5e,0xe2,0xf3,0x53,0x0e,0xeb,0xb7,0x5c,0x85,0xe0,0x86,0x21,0xf8,0x3e,0xdc,0x08,0xaa,0x96,0x69,0x38,0x94,0xa4,0x27,0x76,0x33,0xba,0x81,0xe1,0x9e,0x9e,0x55,0xaf,0x5c,0x49,0x5d,0xaa,0x5e,0x1a,0x6f,0x8c,0xbb,0x79,0xc0,0x1c,0x72,0x07,},"\xda\x40\x58\x90\xd1\x1a\x87\x2c\x11\x9d\xab\x5e\xfc\xbf\xf6\x1e\x93\x1f\x38\xec\xcc\xa4\x57\xed\xc6\x26\xd3\xea\x29\xed\x4f\xe3\x15\x4f\xaf\xec\x14\x44\xda\x74\x34\x3c\x06\xad\x90\xac\x9d\x17\xb5\x11\xbc\xb7\x3b\xb4\x9d\x90\xba\xfb\x7c\x7e\xa8\x00\xbd\x58\x41\x1d\xf1\x27\x5c\x3c\xae\x71\xb7\x00\xa5\xda\xb4\x91\xa4\x26\x16\x78\x58\x79\x56\xaa\x4a\x21\x9e\x1a\xc6\xdd\x3f\xb2\xcb\x8c\x46\x19\x72\x18\xe7\x26\xdc\x7e\xd2\x34\x52\x6a\x6b\x01\xc0\xd7\x2c\xb9\x3a\xb3\xf4\xf3\x8a\x08\xe5\x94\x0b\x3f\x61\xa7\x2a\xd2\x78\x9a\x05\x32\x00\x0f\xac\x1d\x2d\x2e\x3a\xd6\x32\xac\x8b\x62\xbb\x3f\xf5\xb9\x9d\x53\x59\x7b\xf4\xd4\x4b\x19\x67\x49\x24\xdf\x9b\x3d\xb3\xd0\x25\x3f\x74\x62\x7c\xca\xb3\x00\x31\xc8\x5e\x29\x1c\x58\xb5\xfa\x91\x67\x52\x2a\x46\x74\x6f\xc3\x07\x03\x67\x45\xd4\xf9\x81\x77\x86\xe5\xd3\x00\xe6\xc5\xd5\x03\x12\x5f\xea\x01\xde\xc3\xe3\xfe\xdb\xf3\x86\x1c\xa2\x62\x7a\x05\x18\xfb\x2b\x24\xe5\xa7\xa0\x14\x17\x87\x19\xe9\xb3\x45\xf7\xb2\x49\xce\x3a\x41\x32\x80\xc8\xde\xb6\x74\xf5\x9a\x25\xbe\x92\xa8\xab\x64\x00\xc7\xc5\x2b\x07\x28\xae\x34\xe2\x2b\x2e\xc2\x00\xc1\xcb\xab\xa2\xcc\xd8\xaf\x29\x24\x9d\x17\xaf\x60\xc3\x60\x07\xa7\x22\xfc\x80\x25\x8a\x7b\xeb\xab\x1c\xda\xad\x74\x62\xa8\xb7\x58\x8c\x2f\x7e\x27\xc6\xd0\x7a\xfc\xf6\x01\x17\xfe\xd1\x1b\xd6\x85\x9e\x75\xe3\xb4\xfc\xee\x39\x81\x88\x1e\x95\xdd\x11\x68\x27\xdd\x4b\x36\x9a\xf0\x69\xd3\xc8\xf2\x67\x6f\x8a"}, +{{0x26,0x45,0x04,0x60,0x4e,0x70,0xd7,0x2d,0xc4,0x47,0x4d,0xbb,0x34,0x91,0x3e,0x9c,0x0f,0x80,0x6d,0xfe,0x18,0xc7,0x87,0x9a,0x41,0x76,0x2a,0x9e,0x43,0x90,0xec,0x61,},{0xeb,0x2b,0x51,0x8c,0xe7,0xdc,0x71,0xc9,0x1f,0x36,0x65,0x58,0x16,0x51,0xfd,0x03,0xaf,0x84,0xc4,0x6b,0xf1,0xfe,0xd2,0x43,0x32,0x22,0x35,0x3b,0xc7,0xec,0x51,0x1d,},{0xee,0xa4,0x39,0xa0,0x0f,0x7e,0x45,0x9b,0x40,0x2b,0x83,0x51,0x50,0xa7,0x79,0xee,0xd1,0x71,0xab,0x97,0x1b,0xd1,0xb5,0x8d,0xcc,0x7f,0x93,0x86,0xda,0xdd,0x58,0x3d,0xe8,0xdc,0x69,0xe2,0x67,0x12,0x1d,0xde,0x41,0xf0,0xf9,0x49,0x3d,0x45,0x0b,0x16,0x21,0x9c,0xdf,0x3c,0x22,0xf0,0x94,0x82,0xce,0x40,0x2f,0xe1,0x7c,0xa4,0x9e,0x08,},"\x90\x1d\x70\xe6\x7e\xd2\x42\xf2\xec\x1d\xda\x81\x3d\x4c\x05\x2c\xfb\x31\xfd\x00\xcf\xe5\x44\x6b\xf3\xb9\x3f\xdb\x95\x0f\x95\x2d\x94\xef\x9c\x99\xd1\xc2\x64\xa6\xb1\x3c\x35\x54\xa2\x64\xbe\xb9\x7e\xd2\x0e\x6b\x5d\x66\xad\x84\xdb\x5d\x8f\x1d\xe3\x5c\x49\x6f\x94\x7a\x23\x27\x09\x54\x05\x1f\x8e\x4d\xbe\x0d\x3e\xf9\xab\x30\x03\xdd\x47\xb8\x59\x35\x6c\xec\xb8\x1c\x50\xaf\xfa\x68\xc1\x5d\xad\xb5\xf8\x64\xd5\xe1\xbb\x4d\x3b\xad\xa6\xf3\xab\xa1\xc8\x3c\x43\x8d\x79\xa9\x4b\xfb\x50\xb4\x38\x79\xe9\xce\xf0\x8a\x2b\xfb\x22\xfa\xd9\x43\xdb\xf7\x68\x37\x79\x74\x6e\x31\xc4\x86\xf0\x1f\xd6\x44\x90\x50\x48\xb1\x12\xee\x25\x80\x42\x15\x3f\x46\xd1\xc7\x77\x2a\x06\x24\xbc\xd6\x94\x1e\x90\x62\xcf\xda\x75\xdc\x87\x12\x53\x3f\x40\x57\x33\x5c\x29\x80\x38\xcb\xca\x29\xeb\xdb\x56\x0a\x29\x5a\x88\x33\x96\x92\x80\x8e\xb3\x48\x1f\xd9\x73\x5e\xa4\x14\xf6\x20\xc1\x43\xb2\x13\x3f\x57\xbb\x64\xe4\x47\x78\xa8\xca\x70\x91\x82\x02\xd1\x57\x42\x61\x02\xe1\xdf\xc0\xa8\xf7\xb1\xae\x48\x7b\x74\xf0\x27\x92\x63\x31\x54\xdf\xe7\x4c\xaa\x1b\x70\x88\xfd\xa2\x2f\xa8\xb9\xbc\x35\x4c\x58\x5f\x15\x67\x70\x6e\x29\x55\x49\x38\x70\xf5\x41\x69\xe0\xd7\x69\x11\x59\xdf\x43\x89\x79\x61\xd2\x4a\x85\x2e\xa9\x70\xc5\x14\x94\x8f\x3b\x48\xf7\x1e\xe5\x86\xe7\x2e\xc7\x8d\xb8\x20\xf2\x53\xe0\x8d\xb8\x4f\x6f\x31\x2c\x43\x33\xbd\x0b\x73\x2f\xe7\x58\x83\x50\x77\x83\xe9\xa1\xfd\x4f\xba\xb8\xe5\x87\x0f\x9b\xf7\xad\x58\xaa"}, +{{0x2c,0xa7,0x44,0x7a,0x36,0x68,0xb7,0x48,0xb1,0xfd,0x3d,0x52,0xd2,0x08,0x0d,0x30,0xe3,0x4d,0x39,0x7b,0xb2,0x84,0x6c,0xaf,0x8f,0x65,0x9a,0xc1,0x68,0x78,0x8c,0xa5,},{0xab,0x33,0x1c,0xd4,0x0a,0x31,0xd0,0x17,0x3c,0x0c,0x8c,0x1c,0x17,0x00,0x25,0x32,0x80,0x7b,0xf8,0x9e,0x3e,0xdb,0x6d,0x34,0xc2,0xdd,0x82,0x94,0x63,0x2b,0x9f,0xbc,},{0xf9,0x3a,0xda,0x15,0xae,0x9c,0xd2,0xb5,0x4f,0x26,0xf8,0x6f,0x0c,0x28,0x39,0x2a,0xed,0x5e,0xb6,0xb6,0xb4,0x4d,0x01,0xa4,0xe3,0x3a,0x54,0xe7,0xda,0x37,0xc3,0x8e,0x8d,0x53,0x36,0x6f,0x73,0xfd,0x85,0xbe,0x64,0x2e,0x4e,0xc8,0x12,0x36,0xd1,0x63,0xf0,0xd0,0x25,0xe7,0x6c,0x8b,0xbd,0xd6,0x5d,0x43,0xdf,0x49,0xf0,0x9c,0x1f,0x01,},"\xa8\x2b\xcd\x94\x24\xbf\xfd\xa0\xf2\xf5\xe9\xea\xe1\x78\x35\xdb\xe4\x68\xf6\x1b\x78\x5a\xab\x82\x93\x47\x37\xa9\x1c\x5f\x60\x2c\xb7\xc6\x17\xcd\xff\xe8\x7c\xad\x72\x6a\x49\x72\xe1\x5a\x7b\x8e\xe1\x47\xf0\x62\xd2\xa5\xa4\xd8\x97\x06\xb5\x71\xfa\x8a\xa2\xb9\x59\x81\xc7\x8a\xbe\xaa\xae\x86\x20\x3f\xa2\xc0\xe0\x72\x97\x40\x6e\xa8\xc2\x71\x11\xa8\x6d\xbe\x1d\x5a\x7c\x3b\x7a\xe9\x30\x90\x4d\x98\x90\xf6\xd4\xab\xeb\xd1\x41\x2a\x73\xad\x5f\xee\xa6\x4a\xcf\x06\x5d\x3e\x63\xb5\xcb\xe2\x0c\xf2\x0b\xbd\x2d\x8b\x94\xf9\x05\x3e\xd5\xf6\x66\x33\x48\x25\x30\x12\x44\x46\x60\x59\x18\xde\x66\x45\x5e\x8c\xf4\xb1\x01\xa1\x27\x23\x3c\x4e\x27\xd5\xd5\x5b\xf9\x5b\xd3\x19\x5d\x03\x40\xd4\x35\x31\xfc\x75\xfa\xf8\xdd\xed\x52\x75\xbf\x89\x75\x0d\xe8\x38\xfd\x10\xc3\x17\x45\xbe\x4c\xa4\x1f\xa8\x71\xcb\x0f\x9b\x01\x67\x06\xa1\xa7\xe3\xc4\x4b\xb9\x0a\xc7\xa8\xad\x51\xe2\x72\x38\x92\x92\xfd\x6c\x98\xad\x7a\x06\x9e\x76\xe3\xf5\xf3\xe0\xcc\x77\x0b\x9e\x9b\x35\xa7\x65\xd0\xd9\x37\x12\xd7\xcd\xab\xd1\x7e\x5d\x01\xdd\x81\x83\xaf\x4a\xd9\x36\x5d\xb0\xa0\xfa\x41\x38\x1f\xce\x60\xa0\x81\xdf\x1c\x5a\xb0\xf8\xc1\x8f\x95\xa7\xa8\xb5\x82\xdf\xff\x7f\x14\x9e\xa5\x79\xdf\x06\x23\xb3\x3b\x75\x08\xf0\xc6\x63\xf0\x1e\x3a\x2d\xcd\x9d\xfb\xee\x51\xcc\x61\x52\x20\xfd\xaf\xfd\xab\x51\xbd\xae\x42\xcb\x9f\x7f\xa9\xe3\xb7\xc6\x9c\xc8\xad\xa5\xcc\xd6\x42\x52\x9b\xa5\x14\xfd\xc5\x4f\xcf\x27\x20\xb8\xf5\xd0\x8b\x95"}, +{{0x49,0x4e,0xa9,0xbc,0xce,0x26,0x88,0x5b,0x7d,0x17,0xd1,0xfc,0x11,0x44,0x48,0xf2,0x39,0xf0,0xce,0x46,0xe5,0xf2,0x47,0xb4,0xc9,0x99,0xfa,0x86,0x29,0x69,0x24,0x72,},{0x69,0x01,0xe5,0xef,0xae,0x57,0x53,0x6b,0xa5,0xfd,0xd9,0x6b,0x59,0x65,0x73,0x59,0x06,0x5f,0x25,0xd3,0x91,0xa1,0xaa,0x8c,0xdc,0x0d,0x38,0xbb,0x5d,0x53,0xc1,0x39,},{0x54,0x8a,0x09,0x3a,0x68,0x03,0x61,0xb7,0xdc,0x56,0xf1,0x45,0x03,0xb5,0x5e,0xee,0xc3,0xb3,0xf4,0xfd,0x4c,0xa9,0x9d,0x6a,0xed,0xce,0x08,0x30,0xf7,0xf4,0xae,0x2f,0x73,0x28,0x53,0x9b,0x34,0xc4,0x8f,0xc9,0x76,0x09,0x22,0x33,0x3d,0xae,0x9c,0x7c,0x01,0x7e,0x7d,0xb7,0x3b,0x8f,0xaa,0x6c,0x06,0xbe,0x05,0xe3,0x47,0x99,0x2b,0x06,},"\x3b\xad\xbf\xa5\xf5\xa8\xaa\x2c\xce\x0a\x60\xe6\x86\xcd\xce\x65\x4d\x24\x45\x2f\x98\xfd\x54\x87\x2e\x73\x95\xb3\x94\x64\x38\x0a\x0e\x18\x55\x57\xea\x13\x4d\x09\x57\x30\x86\x4f\x42\x54\xd3\xdd\x94\x69\x70\xc1\x0c\x80\x4f\xcc\x08\x99\xdf\xa0\x24\x20\x5b\xe0\xf8\x0b\x1c\x75\x44\x95\x23\x32\x4f\xe6\xa0\x75\x1e\x47\xb4\xff\x48\x22\xb8\xc3\x3e\x9e\xaf\x1d\x1d\x96\xe0\xde\x3d\x4a\xcd\x89\x69\x6b\x7f\xcc\x03\xd4\x9f\x92\xf8\x2b\x97\x25\x70\x0b\x35\x0d\xb1\xa8\x76\x15\x36\x95\x45\x56\x1b\x85\x99\xf5\xea\x92\x0a\x31\x0a\x8b\xaf\xc0\xe8\xd7\x46\x8c\xbf\x6f\x38\x20\xe9\x43\x59\x4a\xfd\xd5\x16\x6e\x4e\x33\x09\xdd\xdd\x76\x94\xef\x67\xe6\x94\xf3\x4f\xc6\x27\x24\xff\x96\xac\x33\x64\x17\x6f\x34\xe8\xa0\x2b\x4c\xf5\x69\xdb\x5b\x8f\x77\xd5\x85\x12\xae\xda\xbf\x0b\xcd\x1c\x2d\xf1\x2d\xb3\xa9\x47\x3f\x94\x8c\x5c\x32\x43\x30\x9a\xae\x46\xc4\x9e\xfd\x08\x8b\x60\xf3\x1a\x8a\x72\xad\x7e\x5a\x35\xac\xc5\xd8\x9f\xa6\x68\x07\xeb\x5d\x3b\xa9\xcd\xf0\x8d\x47\x53\xcb\x85\x08\x9e\xe3\x6f\x5c\x96\xb4\x32\xb6\x92\x83\x52\xaf\xad\x58\x01\x22\x25\xd6\x15\x7f\x9e\x36\x11\x42\x6d\xf9\x21\xb6\xd1\xd8\x37\x46\x28\xa6\x30\x31\xe9\xff\xb9\x0e\x42\xff\xbb\xa0\x21\xf1\x74\xf6\x85\x03\x15\x54\x30\x15\x2c\x91\x55\xdc\x98\xff\xa2\x6c\x4f\xab\x06\x5e\x1f\x8e\x46\x22\xc2\xf2\x8a\x8c\xb0\x43\x11\x0b\x61\x74\x41\x14\x0f\x8e\x20\xad\xc1\x6f\x79\x9d\x1d\x50\x96\xb1\xf5\x05\x32\xbe\x50\x42\xd2\x1b\x81\xea\x46\xc7"}, +{{0x00,0xd7,0x35,0xeb,0xae,0xe7,0x5d,0xd5,0x79,0xa4,0x0d,0xfd,0x82,0x50,0x82,0x74,0xd0,0x1a,0x15,0x72,0xdf,0x99,0xb8,0x11,0xd5,0xb0,0x11,0x90,0xd8,0x21,0x92,0xe4,},{0xba,0x02,0x51,0x7c,0x0f,0xdd,0x3e,0x26,0x14,0xb3,0xf7,0xbf,0x99,0xed,0x9b,0x49,0x2b,0x80,0xed,0xf0,0x49,0x5d,0x23,0x0f,0x88,0x17,0x30,0xea,0x45,0xbc,0x17,0xc4,},{0xdc,0xdc,0x54,0x61,0x19,0x37,0xd2,0xbd,0x06,0xca,0xcd,0x98,0x18,0xb3,0xbe,0x15,0xce,0x74,0x25,0x42,0x7a,0x75,0xf5,0x0d,0x19,0x7a,0x33,0x7a,0x3b,0x8b,0xa6,0x71,0x4e,0xf4,0x88,0x66,0xf2,0x43,0xbd,0x5a,0xc7,0x41,0x5e,0x91,0x45,0x17,0xa2,0xc1,0xc5,0xa9,0x53,0xf4,0x32,0xb9,0x9d,0xb0,0xe6,0x20,0xd6,0x4f,0x74,0xeb,0x85,0x05,},"\x59\xc0\xb6\x9a\xf9\x5d\x07\x4c\x88\xfd\xc8\xf0\x63\xbf\xdc\x31\xb5\xf4\xa9\xbc\x9c\xec\xdf\xfa\x81\x28\xe0\x1e\x7c\x19\x37\xdd\xe5\xeb\x05\x70\xb5\x1b\x7b\x5d\x0a\x67\xa3\x55\x5b\x4c\xdc\xe2\xbc\xa7\xa3\x1a\x4f\xe8\xe1\xd0\x3a\xb3\x2b\x40\x35\xe6\xda\xdb\xf1\x53\x20\x59\xee\x01\xd3\xd9\xa7\x63\x3a\x0e\x70\x6a\x11\x54\xca\xb2\x2a\x07\xcd\x74\xc0\x6a\x3c\xb6\x01\x24\x4c\xf3\xcf\x35\xa3\x5c\x31\x00\xba\x47\xf3\x13\x72\xa2\xda\x65\xdc\xff\x0d\x7a\x80\xa1\x05\x5d\x8a\xa9\x92\x12\xe8\x99\xaa\xd7\xf0\x2e\x94\x9e\x6f\xee\x4d\x3c\x9c\xef\xa8\x50\x69\xea\xff\x1f\x6a\xd0\x6f\xc3\x00\xc8\x71\xab\x82\xb2\xbe\xdb\x93\x4d\x20\x87\x5c\x2a\x26\x32\x42\xcd\xb7\xf9\xbe\x19\x2a\x87\x10\xb2\x4c\x7e\xa9\x8d\x43\xda\xec\x8b\xaa\x55\x53\xc6\x78\xa3\x8f\x0e\x0a\xdf\x7d\x3f\xf2\xdc\xc7\x99\xa1\xdb\xad\x6e\xab\x1c\x3d\x94\x58\xa9\xdb\x92\x2f\x02\xe7\x5c\xfa\xb9\xd6\x5c\x73\x36\xda\xe7\x18\x95\xd5\xbb\x15\xca\xc2\x03\xf2\xb3\x8b\x99\x96\xc4\x10\xf8\x65\x5a\xd2\x2d\x3c\x09\x1c\x20\xb7\xf9\x26\xd4\x5e\x78\x01\x28\xf1\x97\x47\x46\x2a\xbc\x5c\x58\x93\x2f\xbb\x9e\x0b\xc6\x2d\x53\x86\x88\x02\xf1\xb0\x83\xf1\x83\xb8\xa1\xf9\x43\x49\x86\xd5\xcf\x97\xc0\x4e\x2f\x3e\x14\x57\x30\xcb\xa9\x87\x79\xc7\xfe\xd0\xca\xb1\xc0\x5d\x5e\x46\x53\xc6\xc3\xf6\x73\x62\x60\xbc\x78\xee\x43\x72\x86\x2f\xfe\x9e\x90\x37\x1d\x76\x2c\x74\x32\x78\x1f\x35\xce\xd8\x84\xa4\xba\xca\x05\x65\x3e\xf2\x5f\x25\xa6\xf3\xd5\x62\x83\x08"}, +{{0x8c,0x34,0xb9,0x05,0x44,0x0b,0x61,0x91,0x1d,0x1d,0x81,0x37,0xc5,0x3d,0x46,0xa1,0xa7,0x6d,0x46,0x09,0xaf,0x97,0x3e,0x18,0xeb,0x4c,0x57,0x09,0x29,0x56,0x27,0xbb,},{0xb6,0x9a,0x8b,0x2f,0xdf,0x5c,0x20,0xe7,0x34,0xc2,0xff,0xb2,0x94,0xbc,0x8a,0xe1,0x01,0x1d,0x66,0x4f,0x11,0xaf,0xe7,0xfb,0xc4,0x71,0x92,0x5c,0xf7,0x2f,0xa9,0x9d,},{0x3e,0x0b,0x72,0x07,0x3d,0xc9,0x37,0x5e,0xed,0xcc,0xa6,0xc4,0xfc,0x1c,0xd3,0x15,0x93,0x8a,0x05,0x0c,0x92,0x71,0x6b,0xd2,0x28,0x4f,0x46,0x29,0xa9,0x62,0xbe,0xec,0x0b,0x7d,0x7c,0xf1,0x6a,0xb9,0x23,0xd5,0x8f,0x5b,0x90,0xd3,0x90,0x1a,0x8e,0x5c,0x75,0xc8,0xf1,0x7d,0xab,0x99,0x98,0xe0,0x07,0xd8,0xc4,0x95,0x11,0x97,0x3d,0x0e,},"\x30\xb5\x7a\x38\x9b\x48\xa0\xbe\xb1\xa4\x84\x32\xbf\xf6\xb3\x14\xbd\xed\x79\xc4\xa1\x76\x3a\x5a\xcb\x57\xce\xa1\xbf\xb4\xc6\xd0\x16\xcf\x09\x0f\x5b\xd0\x5b\xbd\x11\x4e\x33\xae\x7c\x17\x78\x2d\xfa\x26\x4f\x46\xc4\x5f\x8c\x59\x9c\x60\x30\x16\xfe\x9f\xf0\x5b\x6b\x5a\x99\xe9\x2f\xe7\x13\xa4\xcd\x5c\x41\xb2\x92\xed\x2b\xb2\xe9\xcf\x33\xa4\x40\x54\x2e\x82\x1e\xc8\x2c\xbf\x66\x5c\x3f\x02\xe3\xdc\x33\x7d\x7f\xdb\x58\xe3\x1b\x27\xcb\x29\x54\x54\x14\x68\x81\x46\x98\x51\x0d\xf1\x8c\x85\xc8\x1f\xad\x12\xdb\x11\xec\x6b\x96\x6f\x49\x30\xda\x56\x46\xb9\x91\xdb\x97\x44\x50\x97\xda\x30\xda\xb6\x1c\xda\x53\xa4\x10\x83\xcb\x96\xad\xd1\x9d\xe6\xc5\xee\xc3\x23\xbc\xa9\xd3\x53\x0e\x38\xc0\x0b\x35\xaf\x73\x60\x07\x76\x01\xbe\x6a\xc9\x7f\x30\x30\xf9\x30\xa2\x7b\x90\xfe\x8b\x69\x11\xba\xe3\x89\x06\x5a\xdc\x15\xe1\x88\x23\x00\xe2\xa0\x03\x27\x4d\x23\x18\x2d\x5e\xfd\x5b\xa4\xb9\x13\x0c\x07\xbd\x5c\x65\xfe\xcb\x8b\x5c\xb7\xeb\x38\x83\x6b\x31\x8b\xef\xdf\xd7\x7d\xe4\xd6\xca\x01\x81\xf7\x7a\xe5\x74\x08\x91\x68\x32\x25\xf5\x49\xdd\x84\x26\x14\x5c\x97\xc5\x81\x8c\x31\x9f\x7a\xb2\xd8\x68\xe1\xa4\x1c\xea\xb6\x4c\x08\x51\x16\x06\x98\x97\xbf\x2c\xa3\x66\x76\x52\x40\x61\x55\xed\x06\x46\x43\x1b\x6d\xe1\xcc\xc0\x3b\x42\x79\xae\x4d\x32\x66\x79\x26\x5d\xce\x82\x04\x8e\x72\x98\xe1\xf8\x7f\xce\xc0\x76\x8a\xc0\xf5\xd8\xff\x84\xf7\x21\x0b\xe5\x4d\x41\x1a\xf8\xed\xea\x72\x17\xf4\xe5\x94\x13\x12\x1e\x14\x8c\x60\xda"}, +{{0x77,0xa8,0x3e,0x18,0xc9,0xf0,0x00,0xee,0xff,0x7d,0xee,0xac,0x95,0x9e,0xcb,0xa2,0x20,0x6c,0x0a,0xa3,0x9d,0x2f,0x0e,0x2a,0xed,0x57,0x29,0x48,0x2a,0x7a,0x02,0x29,},{0x62,0xb1,0xb3,0x16,0x13,0x55,0x96,0xbf,0xbc,0xa6,0x03,0x7e,0xd8,0x47,0xc6,0x1f,0xb7,0xf0,0x9f,0xa3,0x6c,0xe9,0x0a,0xbb,0x77,0x89,0xb8,0x6f,0x76,0x8b,0x59,0xdd,},{0x1e,0xaa,0xd8,0x42,0x0a,0xc1,0x2c,0x99,0xac,0x1f,0xf4,0x47,0x66,0x78,0xe3,0xcb,0xbe,0x94,0xda,0x6a,0x79,0x7f,0x17,0x46,0x64,0xd5,0xee,0x0f,0x64,0x14,0x33,0xfb,0x1e,0x7c,0xb2,0xf5,0x61,0x3e,0x10,0x80,0x5d,0xf8,0x65,0x4c,0xd8,0xe0,0xd4,0x5d,0x96,0x23,0x09,0x32,0xbc,0x7f,0x20,0xb0,0x4e,0xae,0x83,0x64,0x35,0x13,0x43,0x09,},"\xf3\xd5\xfa\x2a\xca\xef\xd8\x58\xf1\xdf\x26\xe0\x30\x59\xcd\xcb\xc2\x46\x8a\xd7\x4a\xfc\x99\x3d\x0d\xb9\xc4\xcd\xe4\x11\x3f\x8d\x55\xc7\xda\x71\xd3\x8b\xa0\x65\x20\x53\x1c\x61\xfd\xdb\x5f\x33\xd5\xf0\x35\x3b\xe2\x37\x6e\x58\x07\x11\xbe\x45\xc0\xa3\x0b\x1f\xa0\x1b\x55\xe2\x28\xc6\xfa\x35\xe3\xf9\x5b\x67\x90\x9f\xc7\xdf\x3f\xd4\x64\xd9\x3d\x66\x1a\x92\x6f\x9d\x11\xf7\x55\x0c\x17\xfb\xcc\x34\x96\x52\x6e\x8f\x10\xe0\xc8\x91\x66\x77\xb2\xbe\x5b\x31\x9b\x68\x8f\x21\xe8\x1a\xaa\x94\x82\xe5\xc9\x3e\x64\xce\x8c\x43\x7b\x9c\x1e\x14\xfe\xfe\xd7\x0a\x3f\xee\x56\x88\x11\xdc\x31\xca\xda\xb3\xd5\xb2\x20\x25\x44\x65\x33\x6d\xc4\xd9\x7a\x3b\xd0\x96\xb5\xe0\x65\xe0\xcf\xbe\x82\x84\x9e\x2c\x19\x05\xac\xa4\x86\x53\x3f\x0d\xa7\xa6\x1f\x1e\x9a\x55\xb8\xe2\xa8\x32\x62\xde\xeb\x59\xf2\xb1\x3d\x3a\x8a\xef\x57\x00\x84\x5b\x83\xb2\x5a\xe2\x18\x3c\x0d\xda\xc0\xce\x42\xf8\xd2\x56\x74\xcb\x0d\x0d\x22\x0a\x6d\xe7\xc1\x85\x8b\xb0\x7d\x59\xa3\x37\x23\x44\xd9\x44\x60\x2a\xa4\x51\xd2\xb9\x37\xdb\x0f\xe6\xfe\xca\x0b\xeb\xa8\x17\x21\xfc\x36\x1e\xa7\x50\x9e\x2b\x6d\x39\x7e\x1c\x19\x1b\x56\xf5\x4a\xb4\x36\xd0\xd2\x7a\xb4\xc0\x61\xbd\x66\x1a\xd1\xa4\x45\x23\x87\xe8\x73\x57\x54\xd0\x7f\xa7\xef\x4d\x45\x48\xb1\x72\x58\x24\x25\xb2\x99\x04\x6e\x63\x01\xb5\xba\x6b\x91\x44\x18\xf1\x49\xcf\x72\x2e\x10\xbd\xe2\xe0\xd4\x17\x00\xf1\x2c\x84\x29\xfc\x89\x7b\x78\x19\xda\x92\x29\x22\x40\xcd\x45\x56\x54\x58\xc9\xa7\xb2\x9c\x12"}, +{{0x73,0xb0,0x33,0x73,0xef,0x1f,0xd8,0x49,0x00,0x5e,0xcd,0x62,0x70,0xdd,0x99,0x06,0xf1,0x9f,0x44,0x39,0xe4,0x03,0x76,0xcd,0xbc,0x52,0x09,0x02,0xbc,0x97,0x68,0x12,},{0x66,0x37,0x19,0xe0,0x8b,0xa3,0xba,0x16,0x66,0xf6,0x06,0x9a,0x3f,0x54,0x99,0x18,0x66,0xb1,0x8c,0xc6,0xbe,0x41,0x99,0x1b,0x02,0xeb,0x30,0x26,0xff,0x9e,0x15,0x5f,},{0xa4,0x0a,0xbe,0x98,0xfc,0x69,0xda,0x8a,0x1f,0xf9,0xff,0x5c,0x2c,0xca,0x93,0x63,0x2e,0x97,0x59,0x80,0xee,0x8b,0x82,0xc3,0xc3,0x76,0x02,0x2d,0x65,0x24,0xab,0x73,0x6d,0x01,0xb0,0x72,0xf2,0xb6,0x81,0xb5,0xf1,0xcd,0x3e,0xa0,0x67,0x01,0x2e,0xd6,0xd0,0x74,0xe9,0x49,0xc4,0x23,0x27,0xa3,0x66,0xca,0xa9,0xe4,0x75,0x0a,0x3c,0x08,},"\xd5\xc2\xde\xab\xa7\x95\xc3\x0a\xba\x32\x1b\xc7\xde\x69\x96\xf0\xd9\x0e\x4d\x05\xc7\x47\xfb\x4d\xae\x8f\x34\x51\x89\x5d\xef\x6e\x16\xe7\x2f\x38\xea\xce\x75\x6f\x36\x63\x5f\x8f\xb0\xb7\x2a\x3a\x0c\x1f\x54\x66\x38\x17\xa9\x4d\x4f\xd3\x46\xf8\x35\xab\x0e\x65\x7f\x00\x1a\x6f\x2c\xec\xb8\x6d\x08\x25\xbd\x02\x63\x92\x54\xf7\xf7\xf3\x8c\xa9\x9d\xbb\x86\xc6\x4a\x63\x3f\x73\xba\xf9\x33\xaa\xe3\x56\x32\x81\xf4\x00\x5e\x2d\x0e\x7c\xec\x9f\xbd\xe8\xe5\x88\xa9\x57\xe2\x11\x06\x8b\xe6\x5b\x3d\x3d\x35\xbf\x4e\x8d\x5b\xb3\x47\x83\x33\xdf\x9c\xed\x9b\x2a\xba\xf4\x86\x97\x99\x4a\x14\x5e\x93\x21\x49\x9f\xc5\xee\x56\x0f\x4f\xbb\x68\x49\xe1\xae\x8e\xb3\xd1\xde\x00\x83\xa2\x1a\x03\xf6\xa6\xb2\x81\x76\xf0\x13\x0d\x38\x95\xe5\x0e\x75\xe3\xd7\xd0\x94\x7a\x7b\xc2\xc5\xb9\xff\x69\x89\x5d\x27\x79\x14\x42\xba\x8d\x0f\x21\x80\x71\x2b\x56\x7f\x71\x2e\xa9\x12\xf3\xb0\xd9\x2c\x19\x34\x2e\x01\x06\xff\x1d\x87\xb4\x6a\xd3\x3a\xf3\x00\xb9\x08\x55\xba\x97\x69\xd3\x66\xe7\x94\x25\xd9\x8e\x4d\xe1\x99\x05\xa0\x45\x77\x70\x7c\xbe\x62\x5b\x84\x69\x17\x81\xcd\x26\xbf\x62\x26\x0b\x4a\x8b\xd6\x05\xf7\x7a\xf6\xf9\x70\xe1\xb3\xa1\x12\xe8\x91\x83\x44\xbd\x0d\x8d\x2e\x41\xdf\xd2\xce\x98\x95\xb0\x24\x6e\x50\x88\x7a\xa3\xa5\x77\xff\x73\xbe\x4b\x6a\xe6\x0f\xeb\x0c\xa3\x6f\x6a\x5f\x81\x71\xed\x20\x9e\x5c\x56\x65\x29\xc0\x94\x0d\x9b\x4b\xd7\x44\xcc\xee\x56\xe5\x4a\x9a\x0c\x6e\x4d\xa5\x20\xdd\x31\x5c\x28\x72\xb0\x2d\xb5\x63\x70\x3e"}, +{{0xea,0xb1,0x79,0xe4,0x1e,0xd5,0xc8,0x89,0xff,0xe6,0xaa,0xbd,0xc0,0x54,0xfa,0xf1,0x30,0x7c,0x39,0x5e,0x46,0xe3,0x13,0xe1,0x7a,0x14,0xfe,0x01,0x02,0x3f,0xfa,0x30,},{0x86,0xf3,0x47,0x46,0xd3,0xf7,0xa0,0x1d,0xdb,0xe3,0x22,0xf1,0xac,0xa5,0x6d,0x22,0x85,0x6d,0x38,0x73,0x3a,0x3a,0x69,0x00,0xbb,0x08,0xe7,0x76,0x45,0x0e,0xc8,0x03,},{0x14,0x3c,0xb2,0x80,0x27,0xc2,0xf8,0x2e,0x37,0x5e,0x5f,0x34,0x0e,0x7f,0xe6,0xe6,0x0c,0xe7,0xbd,0x51,0x00,0x0b,0x49,0xc7,0x41,0x68,0xaf,0x85,0xe2,0x6e,0xd2,0xed,0x63,0x0e,0xd2,0x67,0x20,0x90,0x16,0x4c,0xc5,0x4b,0x05,0x2d,0xa6,0x94,0xeb,0xdd,0x21,0xa2,0x1b,0x30,0x53,0xf4,0xdc,0xfd,0x78,0x95,0xea,0x5f,0x6c,0x8a,0xa8,0x0d,},"\x97\x10\x95\xce\xbe\x50\x31\x53\x02\x24\x38\x7c\x5c\x31\x96\x6e\x38\x9b\x85\x66\x39\x00\x54\xcf\x45\x26\x4b\x44\xe1\x89\x64\xb7\xbe\x52\xc3\x3c\x4f\xfb\x25\x9a\xf1\x62\x83\x43\x8f\xa1\x5d\xd6\x6b\xc7\x79\x1b\x75\x33\xef\x10\xcb\x0b\xea\xb5\x24\xa6\x43\x76\x26\xf4\xcc\x74\x51\x28\x51\xad\xcc\x2f\xb1\x29\x05\x5a\x48\x2c\x61\x10\x73\x83\xfb\x7c\x52\x41\x83\x1d\x55\x51\x63\x4e\xef\x0d\xc0\xb8\xf9\x05\x3a\x00\x97\x1a\xa8\xfa\x1a\xe0\x89\x8e\x4b\x48\x1b\x67\x07\xe9\x7c\x0f\x94\x20\x40\xb3\x39\xd9\x2f\xc1\x7b\xba\xde\x74\x67\x5a\xf2\x43\xd8\xb2\xda\xfb\x15\xb1\xdb\x55\xd1\x24\x15\xb8\x5f\x30\x37\x29\x19\x30\xab\x61\x60\x0b\xa3\x43\x1f\x8e\xb4\x25\xbe\x44\x91\x61\x47\x28\xaf\x10\x1e\x81\xc0\x91\xf3\x48\xbc\x5f\xfd\x1b\xde\x6a\xe6\xca\xd5\xc1\x5b\x3a\xa7\x35\x80\x78\xcc\x4e\xff\xb5\x4a\x86\xe7\xf0\xe0\xc5\x5e\x4c\xfe\x0a\x54\x60\x5e\xd4\x43\xfd\xf2\xaa\xba\x01\x65\x85\xda\x61\x7e\x77\x34\x1d\x52\x88\x9d\x75\xdd\x54\x0d\x39\xfe\x8b\x79\x93\xed\x70\x5c\xfd\xde\xa0\xcb\x0d\x5a\x73\x1d\x6b\xfc\xdb\x81\x6a\xfa\xff\x47\xe9\x63\xee\xde\xbd\xf2\x41\xaf\x55\x93\x35\x3d\x6d\x40\x1a\x34\xf0\x29\xa8\xcd\xeb\x19\x04\xcc\x2c\xaa\x4f\x96\x35\xcc\x2b\xa6\xb7\xb1\xa2\x9d\xa6\x25\xff\xc3\x83\xbe\x2f\x5a\x8f\x1f\xa4\xf3\x9b\x2d\x4b\x4f\x4c\x2d\x88\x38\xce\x25\x8a\x04\xd4\xa1\x20\x49\x3f\xdf\x07\xf6\x8c\x0f\xfd\x1c\x16\xb7\x68\xa3\x5c\x55\xfe\xa2\xca\xc6\x96\xb5\xc2\x0e\xfc\x10\x86\x5c\xde\x8a\x64\x62\x7d\xcd"}, +{{0xfb,0xf1,0x46,0xeb,0xd5,0x10,0x75,0x57,0x0e,0xc5,0x1a,0xc4,0x10,0xae,0x9f,0x39,0x1d,0xb7,0x5b,0x61,0x0a,0xda,0x63,0x62,0xb4,0xdb,0xd9,0x49,0x65,0x6c,0xfb,0x66,},{0xbe,0x7c,0x2f,0x5b,0x21,0xd7,0x46,0xc8,0xea,0x32,0x45,0xce,0x6f,0x26,0x8e,0x9d,0xa7,0x4e,0x00,0xfa,0x85,0xc9,0xc4,0x75,0x26,0x0c,0x68,0xfa,0x1a,0xf6,0x36,0x1f,},{0x67,0x68,0x00,0x6f,0xe0,0xf2,0x01,0xb2,0x17,0xdd,0x10,0xeb,0x05,0xd4,0xb8,0x2a,0xdc,0xfe,0xb2,0xec,0xfc,0x83,0x73,0xc3,0x30,0x8f,0x41,0x50,0x39,0x48,0x11,0xeb,0x60,0x49,0x18,0x81,0xa2,0xe5,0x3d,0x12,0x89,0xd9,0x64,0x78,0xe1,0x8a,0x64,0xc3,0x4b,0x2a,0x19,0x83,0x2c,0xdc,0xcf,0xd9,0x6a,0x2e,0x4a,0x0c,0x46,0x9f,0xdc,0x0b,},"\xcd\x7a\xd4\xf1\x7f\xcf\xf7\x3a\xcc\x40\x2d\xc1\x02\xd0\x90\x79\xb2\x9a\xaf\x2a\x0f\x4b\x27\xcf\x6b\xee\xb1\xe2\xb2\x3d\x19\xab\x47\xde\xb3\xae\x1b\xec\xd6\x88\x61\xea\x27\x9c\x46\x69\x17\x38\xf4\xff\xf4\x7c\x43\x04\x7c\x4f\x8b\x56\xb6\xbb\xcc\x3f\xde\x07\x23\xd4\x41\x20\xdc\xd3\x07\xa6\x31\x0d\xc4\xf3\x66\xb8\xf3\xcd\x52\xdb\x19\xb8\x26\x6a\x48\x7f\x78\x72\x39\x1c\x45\xfe\x0d\x32\x48\xa7\xab\xf2\xc2\x00\x22\xd3\x76\x95\x47\xf6\x83\x06\x7d\xcc\x36\x3c\xd2\x2f\xd7\xcd\xa3\xca\xdc\x15\x80\x40\x56\xf0\xe2\xaa\x2b\x79\x50\x08\xc5\x98\xbe\x7a\x96\x18\x05\xe6\xdf\x29\x1b\xa3\x04\x1c\x47\xff\x56\x40\x27\x5f\x46\xe6\xae\x82\x09\x2d\x21\xab\xcb\xcf\xba\x11\xe7\x30\x21\x60\x08\x82\x2d\xe3\xce\x46\x24\x00\x59\x6d\xa7\x9f\x7a\xe5\xd1\xdf\x83\x89\x11\x2a\xd9\x88\x68\xfa\x94\xfb\x05\x46\xbf\xe6\xa6\x7a\xa8\xd2\x8c\x4d\x32\x07\x2d\x2e\xad\xd6\x25\x62\x55\xf1\x8c\x23\x82\xe6\x62\xdf\xa9\x22\xa6\x80\xe0\x6a\x43\x62\x2c\x48\x71\xd2\x7d\x18\x07\xf7\xb2\x70\x30\x70\xc8\x3d\xb8\xdd\x92\x9c\x06\x03\x8b\x21\x83\xcb\x8e\x2b\x9e\xc4\xc7\x78\xd7\xec\xf9\xe9\xff\xac\x77\xfa\x77\x37\xb0\x55\xfe\xac\x2e\x79\x82\xae\xee\xc0\xb7\x2f\x1b\xbc\xa2\x42\x4e\x1a\x84\x4b\xba\xc7\x9c\xb2\xe7\x40\x0f\x81\xdc\x44\x9d\x05\x60\xb5\x21\xa7\xc1\x6b\xb4\x16\x7e\x66\x96\x58\x60\x58\xa9\xb8\xed\x2e\x51\x16\x69\x0b\x77\xf2\xa1\x7e\x5c\x0b\x16\xa8\x3d\xcb\xd2\xe2\x45\x52\x29\x3e\x25\x8b\x32\xba\x7f\x84\x49\x44\x37\x93\x42\x69\x86\x27"}, +{{0xdf,0xf0,0xeb,0x6b,0x42,0x6d,0xea,0x2f,0xd3,0x3c,0x1d,0x3f,0xc2,0x4d,0xf9,0xb3,0x1b,0x48,0x6f,0xac,0xb7,0xed,0xb8,0x50,0x29,0x54,0xa3,0xe8,0xda,0x99,0xd9,0xfd,},{0xc2,0x45,0x08,0x5e,0xce,0x69,0xfb,0x9a,0xa5,0x60,0xd0,0xc2,0x7f,0xdb,0x63,0x4f,0x7a,0x84,0x0d,0x41,0xd8,0x46,0x36,0x60,0xfb,0xe8,0x24,0x83,0xb0,0xf3,0xcc,0x3a,},{0x6b,0x48,0xb1,0x0f,0x54,0x5d,0xdb,0x7a,0x89,0xcd,0x58,0x29,0xf4,0xe5,0xb2,0x01,0x46,0xcf,0x6b,0xc9,0x6e,0x55,0x0d,0x06,0xf6,0x5d,0xe8,0xbd,0xae,0x7c,0xcd,0xde,0xd2,0x6c,0xd6,0x30,0xf8,0x6c,0x92,0x66,0xbc,0xcf,0x88,0xe9,0x24,0x03,0x3e,0x04,0xf8,0x3a,0x54,0xf8,0x29,0x0d,0x7f,0x73,0x4c,0xf8,0x67,0x3c,0xca,0x8f,0x97,0x03,},"\xe7\xc9\xe3\x13\xd8\x61\x60\xf4\xc7\x4a\xa0\xae\x07\x36\x9e\xe2\x2b\x27\xf8\x1b\x3f\x69\x09\x7a\xff\xae\x28\xda\xe4\x84\x83\xfb\x52\xa5\xc0\x62\x30\x6b\x59\x61\x0f\x5c\xdb\xff\x63\x32\xb1\x96\x0c\xd6\xf2\xb8\xf7\xb4\x15\x78\xc2\x0f\x0b\xc9\x63\x7a\x0f\xdf\xc7\x39\xd6\x1f\x69\x9a\x57\x3f\x1c\x1a\x0b\x49\x29\x45\x06\xcf\x44\x87\x96\x5e\x5b\xb0\x7b\xbf\x81\x80\x3c\xb3\xd5\xcb\x38\x29\xc6\x6c\x4b\xee\x7f\xc8\x00\xed\xe2\x16\x15\x09\x34\xd2\x77\xde\xa5\x0e\xdb\x09\x7b\x99\x2f\x11\xbb\x66\x9f\xdf\x14\x0b\xf6\xae\x9f\xec\x46\xc3\xea\x32\xf8\x88\xfd\xe9\xd1\x54\xea\x84\xf0\x1c\x51\x26\x5a\x7d\x3f\xef\x6e\xef\xc1\xcc\xdb\xff\xd1\xe2\xc8\x97\xf0\x55\x46\xa3\xb1\xca\x11\xd9\x51\x7c\xd6\x67\xc6\x60\xec\x39\x60\xf7\xa8\xe5\xe8\x02\x02\xa7\x8d\x3a\x38\x8b\x92\xf5\xc1\xde\xe1\x4a\xe6\xac\xf8\xe1\x7c\x84\x1c\x95\x57\xc3\x5a\x2e\xec\xed\x6e\x6a\xf6\x37\x21\x48\xe4\x83\xcc\xd0\x6c\x8f\xe3\x44\x92\x4e\x10\x19\xfb\x91\xcb\xf7\x94\x1b\x9a\x17\x6a\x07\x34\x15\x86\x72\x10\x67\x04\x10\xc5\xdb\xd0\xac\x4a\x50\xe6\xc0\xa5\x09\xdd\xfd\xc5\x55\xf6\x0d\x69\x6d\x41\xc7\x7d\xb8\xe6\xc8\x4d\x51\x81\xf8\x72\x75\x5e\x64\xa7\x21\xb0\x61\xfc\xd6\x8c\x46\x3d\xb4\xd3\x2c\x9e\x01\xea\x50\x12\x67\xde\x22\x87\x9d\x7f\xc1\x2c\x8c\xa0\x37\x9e\xdb\x45\xab\xaa\x6e\x64\xdd\xa2\xaf\x6d\x40\xcc\xf2\x4f\xbe\xba\xd7\xb5\xa8\xd3\xe5\x20\x07\x94\x5e\xcd\x3d\xdc\x1e\x3e\xfe\xb5\x22\x58\x1a\xc8\x0e\x98\xc8\x63\xba\x0c\x59\x0a\x3e\xd9\x5c\xd1"}, +{{0x9f,0x32,0x95,0x8c,0x76,0x79,0xb9,0x0f,0xd5,0x03,0x60,0x56,0xa7,0x5e,0xc2,0xeb,0x2f,0x56,0xec,0x1e,0xff,0xc7,0xc0,0x12,0x46,0x1d,0xc8,0x9a,0x3a,0x16,0x74,0x20,},{0x1d,0x72,0x69,0xdc,0xb6,0xd1,0xf5,0x84,0xe6,0x62,0xd4,0xce,0x25,0x1d,0xe0,0xab,0xa2,0x90,0xef,0x78,0xb9,0x7d,0x44,0x8a,0xfb,0x1e,0x53,0x33,0xf1,0x97,0x6d,0x26,},{0x98,0x81,0xa5,0x76,0x3b,0xdb,0x25,0x9a,0x3f,0xef,0xbb,0xa3,0xd9,0x57,0x16,0x2d,0x6c,0x70,0xb8,0x04,0xfa,0x94,0xab,0x61,0x34,0x06,0xa6,0xec,0x42,0x50,0x5b,0x87,0x89,0x46,0x5c,0xa1,0xa9,0xa3,0x3e,0x18,0x95,0x98,0x88,0x42,0x27,0x0c,0x55,0xe5,0xbd,0xd5,0x48,0x3f,0x6b,0x17,0xb3,0x17,0x81,0xb5,0x93,0x50,0x7a,0x6c,0x18,0x08,},"\xa5\x6b\xa8\x6c\x71\x36\x05\x04\x08\x7e\x74\x5c\x41\x62\x70\x92\xad\x6b\x49\xa7\x1e\x9d\xaa\x56\x40\xe1\x04\x4b\xf0\x4d\x4f\x07\x1a\xd7\x28\x77\x9e\x95\xd1\xe2\x46\x05\x84\xe6\xf0\x77\x35\x45\xda\x82\xd4\x81\x4c\x91\x89\xa1\x20\xf1\x2f\x3e\x38\x19\x81\x3e\x5b\x24\x0d\x0f\x26\x43\x6f\x70\xee\x35\x3b\x4d\x20\xce\xa5\x4a\x14\x60\xb5\xb8\xf1\x00\x8d\x6f\x95\xf3\xaa\x2d\x8f\x1e\x90\x8f\xce\xd5\x0d\x62\x4e\x3a\x09\x69\x38\xb9\x35\x38\x54\xb9\x6d\xa4\x63\xa2\x79\x8a\x5a\x31\x2e\xc7\x90\x84\x2c\x10\xc4\x46\xe3\x35\x0c\x76\x4b\xf5\xc9\x72\x59\x3b\x99\x87\xbf\x23\x25\x6d\xaa\x88\x94\xd4\x7f\x22\xe8\x5b\x97\x60\x7e\x66\xfc\x08\xa1\x2c\x78\x9c\x47\x46\x08\x03\x68\xd3\x21\xbb\x90\x15\xa1\x15\x5b\x65\x52\x3a\xd8\xe9\x9b\xb9\x89\xb4\x4e\xac\x75\x6b\x07\x34\xac\xd7\xc6\x35\x7c\x70\xb5\x97\x43\x24\x6d\x16\x52\xd9\x1b\x0f\x98\x96\x96\x51\x41\x34\x5b\x99\x45\xcf\x34\x98\x04\x52\xf3\x50\x29\x74\xed\xb7\x6b\x9c\x78\x5f\xb0\xf4\x39\x52\x66\xb0\x55\xf3\xb5\xdb\x8a\xab\x68\xe9\xd7\x10\x2a\x1c\xd9\xee\x3d\x14\x25\x04\xf0\xe8\x8b\x28\x2e\x60\x3a\x73\x8e\x05\x1d\x98\xde\x05\xd1\xfc\xc6\x5b\x5f\x7e\x99\xc4\x11\x1c\xc0\xae\xc4\x89\xab\xd0\xec\xad\x31\x1b\xfc\x13\xe7\xd1\x65\x3b\x9c\x31\xe8\x1c\x99\x80\x37\xf9\x59\xd5\xcd\x98\x08\x35\xaa\x0e\x0b\x09\xbc\xbe\xd6\x34\x39\x11\x51\xda\x02\xbc\x01\xa3\x6c\x9a\x58\x00\xaf\xb9\x84\x16\x3a\x7b\xb8\x15\xed\xbc\x02\x26\xed\xa0\x59\x5c\x72\x4c\xa9\xb3\xf8\xa7\x11\x78\xf0\xd2\x0a\x5a"}, +{{0xf8,0x6d,0x6f,0x76,0x6f,0x88,0xb0,0x07,0x17,0xb7,0xd6,0x32,0x7e,0xb2,0x6c,0xf3,0xce,0xeb,0xa5,0x38,0x51,0x84,0x42,0x6f,0x9c,0xfd,0x82,0x95,0xe2,0x42,0x1f,0xf2,},{0xcb,0x1d,0x25,0x05,0x04,0x75,0x41,0x83,0x70,0x4d,0xbe,0x21,0xc3,0x23,0xd6,0x6f,0x9f,0x90,0x11,0x75,0x8f,0x6d,0x8d,0xab,0x6f,0x59,0x7b,0x19,0x96,0x62,0x14,0x5b,},{0xec,0x61,0xc0,0xb2,0x92,0x20,0x3a,0x8f,0x1d,0x87,0x23,0x5e,0xde,0x92,0xb7,0x47,0x23,0xc8,0xd2,0x34,0x08,0x42,0x37,0x73,0xae,0x50,0xb1,0xe9,0xbc,0x44,0x64,0xe0,0x3e,0x44,0x6d,0xa9,0xdc,0xe4,0xc3,0x9f,0x6d,0xd1,0x59,0xbe,0xa2,0x6c,0x00,0x9e,0xd0,0x01,0x20,0xbc,0x36,0xd4,0xa2,0x47,0xdc,0x0d,0x24,0xbc,0xef,0xcc,0x11,0x0c,},"\xda\x84\x23\xa6\xb7\xa1\x8f\x20\xaa\x1f\x90\xed\x23\x31\xb1\x7b\x24\x06\x7c\x40\x17\x5b\xc2\x5d\x81\x09\xe2\x1d\x87\xac\x00\x52\x8e\xb3\xb2\xf6\x6a\x2b\x52\xdc\x7e\xf2\xf8\xce\xcb\x75\xc7\x60\x99\xcf\xa2\x3d\xb8\xda\x89\x70\x43\xba\x1c\xce\x31\xe2\xdf\xea\x46\x07\x5f\x5e\x07\x32\x03\xea\xeb\x3d\x62\xc8\x4c\x10\x7b\x6d\xab\x33\xa1\x4e\xaf\x14\x9a\xa6\x18\x50\xc1\x5f\x5a\x58\xd8\x8a\x15\xab\xa9\x19\x6f\x9e\x49\x5e\x8d\xbe\xcb\xcf\x7e\x84\x44\xf5\xdd\x72\xa0\x8a\x09\x9d\x7f\x62\x09\x99\x0b\x56\x29\x74\xea\x82\x9e\xf1\x1d\x29\xa9\x20\xe3\xa7\x99\xd0\xd9\x2c\xb5\x0d\x50\xf8\x17\x63\x1a\xb0\x9d\xe9\x7c\x31\xe9\xa0\x5f\x4d\x78\xd6\x49\xfc\xd9\x3a\x83\x75\x20\x78\xab\x3b\xb0\xe1\x6c\x56\x4d\x4f\xb0\x7c\xa9\x23\xc0\x37\x4b\xa5\xbf\x1e\xea\x7e\x73\x66\x8e\x13\x50\x31\xfe\xaf\xcb\xb4\x7c\xbc\x2a\xe3\x0e\xc1\x6a\x39\xb9\xc3\x37\xe0\xa6\x2e\xec\xdd\x80\xc0\xb7\xa0\x49\x24\xac\x39\x72\xda\x4f\xa9\x29\x9c\x14\xb5\xa5\x3d\x37\xb0\x8b\xf0\x22\x68\xb3\xba\xc9\xea\x93\x55\x09\x0e\xeb\x04\xad\x87\xbe\xe0\x59\x3b\xa4\xe4\x44\x3d\xda\x38\xa9\x7a\xfb\xf2\xdb\x99\x52\xdf\x63\xf1\x78\xf3\xb4\xc5\x2b\xcc\x13\x2b\xe8\xd9\xe2\x68\x81\x21\x3a\xbd\xeb\x7e\x1c\x44\xc4\x06\x15\x48\x90\x9f\x05\x20\xf0\xdd\x75\x20\xfc\x40\x8e\xa2\x8c\x2c\xeb\xc0\xf5\x30\x63\xa2\xd3\x05\x70\xe0\x53\x50\xe5\x2b\x39\x0d\xd9\xb6\x76\x62\x98\x48\x47\xbe\x9a\xd9\xb4\xcd\x50\xb0\x69\xff\xd2\x9d\xd9\xc6\x2e\xf1\x47\x01\xf8\xd0\x12\xa4\xa7\x0c\x84\x31\xcc"}, +{{0xa5,0xb3,0x4c,0xef,0xab,0x94,0x79,0xdf,0x83,0x89,0xd7,0xe6,0xf6,0xc1,0x46,0xaa,0x8a,0xff,0xb0,0xbe,0xc8,0x37,0xf7,0x8a,0xf6,0x46,0x24,0xa1,0x45,0xcc,0x34,0x4e,},{0x7b,0x0f,0x4f,0x24,0xd9,0x97,0x2b,0xc6,0xfe,0x83,0x82,0x6c,0x52,0x71,0x6a,0xd1,0xe0,0xd7,0xd1,0x9f,0x12,0x38,0x58,0xcb,0x3e,0x99,0xfa,0x63,0x6a,0xc9,0x63,0x1a,},{0x2f,0xbd,0x89,0x9d,0x72,0xb6,0xd3,0x9e,0x4f,0x45,0xb8,0xb6,0x2c,0xbb,0xd5,0xf3,0xc0,0xac,0xb1,0xad,0x85,0x40,0x91,0x3f,0xa5,0x85,0x87,0x7e,0x91,0xcc,0xfe,0xf7,0xbe,0xe5,0x0a,0x4b,0x0f,0x9f,0xed,0xf5,0xcc,0x1e,0x0d,0x19,0x53,0xad,0x39,0x9c,0x83,0x89,0xa9,0x33,0x91,0xe1,0xb7,0xc9,0x29,0xaf,0x6d,0x6f,0x3b,0x79,0x6c,0x08,},"\xe2\x1e\x98\xaf\x6c\x2b\xac\x70\x55\x7e\xb0\xe8\x64\xda\x2c\x2b\x4d\x6c\x0a\x39\xa0\x59\xd3\x47\x72\x51\xf6\x17\x8a\x39\x67\x6f\x47\x49\xe7\xfb\xea\x62\x3f\x14\x8a\x43\xa8\xb0\xfe\x06\x10\x50\x6f\xa6\x58\xab\xd2\xf5\xfa\x39\x19\x8f\x26\x36\xb7\x24\xdb\x22\xd1\xae\xbc\x2a\xb0\x7b\x2b\x6d\xbf\xfd\xee\x8c\xec\xe8\x1e\x1a\xf1\x49\x3e\xc1\x96\x4e\x16\xbf\x86\xab\x25\x8c\xa0\xfe\xb7\x7e\x3c\x87\x17\xe4\x40\x38\xab\xe1\x52\xc1\x4b\xe1\x56\x60\xbf\x93\xb2\xd4\x8d\x92\xc4\xed\x70\x74\xd2\x49\x42\x10\x62\x1b\xcf\x20\x4f\xba\x88\xc6\x54\xd5\xff\xe0\x1e\x1a\x53\xd0\x8f\x70\xbb\x23\x70\x89\xdc\x80\x72\x16\xff\x6a\x85\xdb\xec\x31\x02\x23\x7d\x42\x59\x07\x78\xac\xf6\xc1\xdc\x56\x6d\x5a\x2b\xb9\xa6\x3b\xc2\x1c\x32\x9c\x27\x2e\x59\x65\xba\xee\xb0\xfe\x89\x1d\xe3\xcc\x8c\xbf\xa8\xe5\x41\xa8\x88\x1d\xf6\x89\x42\xe7\xff\x8d\xc6\x56\xbd\x08\x57\x5f\x6a\xaf\x92\x4a\x17\x6d\x66\x3b\x1a\x1f\x43\x57\x4d\x11\x76\x8c\x70\x1b\x26\x95\x61\xe5\x54\x38\xdb\xeb\xfd\x44\x3d\x21\x15\xcb\x93\x3d\x1c\xde\x4a\x91\x5b\x54\xc3\x25\xc2\x7f\x49\x9e\xf0\x2b\xd0\x12\xff\x1f\x9a\x36\x39\x09\x22\x88\x76\x00\xfe\x71\x2b\xcd\xc2\x3e\xb5\x97\x4a\x30\x53\x72\xad\x52\x95\x1f\x83\xf0\xe5\x8c\xc4\x9e\x28\x98\x41\x62\x19\x17\xf1\xfc\xb0\x23\x51\x47\x24\x0d\xae\x4c\xf3\xb9\x9b\x6a\xc6\xd8\xde\x94\xef\xe7\xc4\x43\x67\x14\x50\x8b\xcd\x01\x14\xc5\x60\x68\xff\x1b\x7c\x16\xd5\x1b\xd9\x06\x43\x78\x74\xd6\x54\x9a\xb5\xd8\x08\x78\x96\x87\x2e\xc8\xa0\x9d\x74\x12"}, +{{0xad,0x75,0xc9,0xce,0x29,0x9c,0x4d,0x59,0x39,0x33,0x67,0xd7,0x7a,0x4c,0x9f,0x8d,0xf8,0xdc,0xec,0x76,0x5c,0x6d,0xbd,0x25,0xb5,0x27,0xfb,0x76,0x69,0x91,0x36,0x04,},{0xb9,0x91,0x05,0x48,0xfe,0x63,0x12,0xa1,0x19,0xc9,0x99,0x3e,0xeb,0xcf,0xb9,0xdc,0x90,0x03,0x0f,0xfb,0x0e,0x4d,0xe2,0xb7,0xcc,0xd2,0x3c,0xbe,0xb4,0xfe,0xf7,0x1b,},{0x6b,0x7e,0xf2,0x7b,0xcf,0xbf,0x2b,0x71,0x49,0x85,0x03,0x37,0x64,0xfc,0xcf,0xf5,0x55,0xe3,0xf5,0xbc,0x44,0x61,0x0d,0x6c,0x8c,0x62,0x11,0x7c,0xb3,0x83,0x1a,0x07,0xf4,0xa8,0xbd,0xdb,0x0e,0xae,0xd1,0xd4,0x6b,0x02,0x89,0xb1,0x5d,0xe1,0xaa,0x4d,0xcc,0x17,0xd7,0x1b,0xe9,0x6a,0x09,0xe6,0x6b,0xa4,0xdc,0x46,0x27,0xc7,0x87,0x05,},"\x62\xfc\x5a\xb6\x7d\xeb\x1f\xee\x9a\xb6\xcc\xa3\xb8\x8a\x1d\xf1\xe5\x89\xf0\xfd\x4a\x88\xf4\xaa\x77\x38\x94\x87\x61\xfe\x84\x37\x2c\x5b\x18\xe4\x65\x52\x20\xc1\xd8\x4d\x52\xac\xad\x32\xe2\x29\xa5\xc7\x56\xc2\x0f\xc6\x2f\xe4\xb4\xb4\xe5\xfd\x70\x77\xae\x4e\xd5\x39\x7a\xa7\x96\xf2\x30\x7c\xee\xdb\x65\x05\xb3\x92\x97\x85\x6f\x4a\xeb\x5e\x70\x93\x8e\x36\xee\x24\xa0\xac\x7d\x98\x68\x30\x6f\x6b\x53\x91\x06\x23\xb7\xdc\x89\xa6\x67\x2a\xd7\x38\x57\x6e\xd5\xd8\x88\x31\xdd\x33\x83\x21\xc8\x90\x2b\xc2\x06\x1f\x65\xe9\x4d\x45\x2f\xdf\xa0\xdc\x66\x5c\xef\xb9\x23\x08\xe5\x23\x01\xbd\x46\x27\x00\x6b\x36\x3d\x06\xb7\x75\xa3\x95\x91\x4d\x8c\x86\x3e\x95\xa0\x0d\x68\x93\xf3\x37\x61\x34\xc4\x29\xf5\x64\x78\x14\x5e\x44\x56\xf7\xa1\x2d\x65\xbb\x2b\x89\x65\xd7\x28\xcb\x2d\xdb\xb7\x08\xf7\x12\x5c\x23\x70\x95\xa9\x21\x95\xd9\x2f\xa7\x27\xa3\x72\xf3\x54\x5a\xe7\x01\xf3\x80\x8f\xee\x80\x2c\x89\x67\xa7\x6e\x8a\x94\x0e\x55\xfb\x2d\x81\x0b\xfb\x47\xad\xa1\x56\xf0\xed\xa1\x82\x9b\x15\x9c\xf0\x5c\x7f\x36\xcf\x38\x47\xd7\xb2\x1d\xe8\x4c\x3d\xc0\xfe\x65\x83\x47\xf7\x93\x96\xa0\x11\x39\xa5\x08\xb6\x00\x22\xdb\x1c\x0e\x5a\xee\xf4\x7e\x44\x5e\x66\xf7\x83\xe6\x2c\x96\x59\x7b\xdb\x16\xf2\x09\xc0\x8a\x91\x32\xc7\x57\x31\x36\x17\x0e\xe3\xeb\xf2\x42\x61\x26\x5a\x89\xfb\x4f\x10\x33\x33\x75\xe2\x0b\x33\xab\x74\x03\x46\x4f\x52\x49\x46\x1c\x68\x53\xc5\xfd\xdb\x9f\x58\xaf\x81\x68\x92\x91\x03\x93\xa7\x07\x7b\x79\x9f\xdc\x34\x89\x72\x09\x98\xfe\xea\x86"}, +{{0x1c,0xed,0x57,0x45,0x29,0xb9,0xb4,0x16,0x97,0x7e,0x92,0xeb,0x39,0x44,0x8a,0x87,0x17,0xca,0xc2,0x93,0x4a,0x24,0x3a,0x5c,0x44,0xfb,0x44,0xb7,0x3c,0xcc,0x16,0xda,},{0x85,0xe1,0x67,0xd5,0xf0,0x62,0xfe,0xe8,0x20,0x14,0xf3,0xc8,0xb1,0xbe,0xae,0xd8,0xee,0xfb,0x2c,0x22,0xd8,0x64,0x9c,0x42,0x4b,0x86,0xb2,0x1b,0x11,0xeb,0x8b,0xda,},{0xe0,0x30,0x3a,0xef,0xe0,0x8a,0x77,0x73,0x8d,0xcc,0x65,0x7a,0xfb,0xb9,0xb8,0x35,0xed,0x27,0x96,0x13,0xa5,0x3c,0x73,0xfd,0xc5,0xdd,0xbf,0xb3,0x50,0xe5,0xcf,0xf4,0xd6,0xc9,0xbb,0x43,0xdc,0x07,0xc9,0x5b,0xf4,0xe2,0x3b,0x64,0xc4,0x0f,0x88,0x04,0xc7,0x16,0x99,0x52,0xe3,0xc8,0xd5,0x9a,0x71,0x97,0x24,0x1b,0xfe,0xd0,0x74,0x0f,},"\x1b\x3b\x95\x3c\xce\x6d\x15\x30\x3c\x61\xca\x70\x76\x09\xf7\x0e\x72\x50\xf6\xc0\xde\xba\x56\xa8\xce\x52\x2b\x59\x86\x68\x96\x51\xcd\xb8\x48\xb8\x42\xb2\x22\x96\x61\xb8\xee\xab\xfb\x85\x70\x74\x9e\xd6\xc2\xb1\x0a\x8f\xbf\x51\x50\x53\xb5\xea\x7d\x7a\x92\x28\x34\x9e\x46\x46\xf9\x50\x5e\x19\x80\x29\xfe\xc9\xce\x0f\x38\xe4\xe0\xca\x73\x62\x58\x42\xd6\x4c\xaf\x8c\xed\x07\x0a\x6e\x29\xc7\x43\x58\x6a\xa3\xdb\x6d\x82\x99\x3a\xc7\x1f\xd3\x8b\x78\x31\x62\xd8\xfe\x04\xff\xd0\xfa\x5c\xbc\x38\x1d\x0e\x21\x9c\x91\x93\x7d\xf6\xc9\x73\x91\x2f\xc0\x2f\xda\x53\x77\x31\x24\x68\x27\x4c\x4b\xee\x6d\xca\x7f\x79\xc8\xb5\x44\x86\x1e\xd5\xba\xbc\xf5\xc5\x0e\x14\x73\x49\x1b\xe0\x17\x08\xac\x7c\x9f\xf5\x8f\x1e\x40\xf8\x55\x49\x7c\xe9\xd7\xcc\x47\xb9\x41\x0f\x2e\xdd\x00\xf6\x49\x67\x40\x24\x3b\x8d\x03\xb2\xf5\xfa\x74\x2b\x9c\x63\x08\x67\xf7\x7a\xc4\x2f\x2b\x62\xc1\x4e\x5e\xbd\xdc\x7b\x64\x7a\x05\xff\xf4\x36\x70\x74\x5f\x28\x51\xef\xf4\x90\x9f\x5d\x27\xd5\x7a\xe8\x7f\x61\xe9\x65\xee\x60\xfd\xf9\x77\x24\xc5\x92\x67\xf2\x61\x0b\x7a\xd5\xde\x91\x98\x56\xd6\x4d\x7c\x21\x26\x59\xce\x86\x56\x14\x9b\x6a\x6d\x29\xd8\xf9\x2b\x31\x2b\xe5\x0b\x6e\x2a\x43\x1d\x36\xae\x02\x2b\x00\xa6\xfe\x36\x0e\x3a\xf6\x54\x32\x89\x9c\x43\xbe\x04\x27\xe3\x6d\x21\xcf\xec\x81\xf2\x1a\xa5\x3b\x33\xdb\x5e\xd2\xc3\x7d\xa8\xf9\x6a\xc3\xe7\xdc\x67\xa1\xde\x37\x54\x6c\xf7\xde\x10\x08\xc7\xe1\xad\xbe\x0f\x34\xfa\x7e\xb2\x43\x4d\x94\xe6\xa1\x3f\x4c\xf8\x6a\x98\xd4\x97\x62\x2f"}, +{{0xf0,0x79,0x0d,0x93,0xe2,0xd3,0xb8,0x4f,0x61,0xef,0x4c,0x80,0x71,0x47,0xab,0xa4,0x10,0xe4,0x15,0xe7,0x2b,0x71,0xb0,0xd6,0x1d,0x01,0x02,0x6f,0xed,0x99,0xda,0x3d,},{0xef,0xdf,0x64,0x9f,0xb0,0x33,0xcf,0x32,0x8e,0x0b,0x28,0x77,0x96,0xf8,0xa2,0x5e,0x9c,0x6e,0x2e,0x87,0x1b,0x33,0xc2,0xc2,0x1a,0x40,0x28,0xa8,0xa2,0x5a,0x4b,0x28,},{0x08,0x77,0x3a,0x6a,0x78,0x76,0x2c,0xbb,0x1e,0x25,0xfc,0xbb,0x29,0x13,0x99,0x41,0xbd,0xf1,0x6f,0x4e,0x09,0xa1,0xfa,0x08,0xfc,0x70,0x1f,0x32,0xf9,0x33,0xed,0xd7,0x4c,0x0a,0xe9,0x83,0xc1,0x2a,0x0a,0x5b,0x02,0x0b,0x6b,0xcf,0x44,0xbb,0x71,0x9d,0xde,0x8e,0xd0,0x78,0x1a,0x82,0x98,0x26,0x56,0x40,0xe1,0x60,0x8c,0x98,0xb3,0x01,},"\x79\x73\xe9\xf3\x2d\x74\x80\x59\x92\xeb\x65\xda\x0d\x63\x73\x35\xe5\x0e\xff\x0c\xe6\x8e\xa2\xd1\xf3\xa0\x2d\xe7\x04\x49\x2b\x9c\xfb\xe7\xe7\xba\x96\xfd\xb4\x2b\xb8\x21\xa5\x13\xd7\x3f\xc6\x04\x02\xe9\x2c\x85\x5d\xea\xed\x73\xff\xea\xf7\x09\x52\x02\x90\x62\xc8\x33\xe1\x4e\xc1\xb1\x4f\x14\x4e\x22\x07\xf6\xa0\xe7\x27\xe5\xa7\xe3\xcb\xab\x27\xd5\x97\x29\x70\xf6\x95\x18\xa1\x5b\x09\x3e\x74\x0c\xc0\xce\x11\xbf\x52\x48\xf0\x82\x6b\x8a\x98\xbd\xe8\xbf\x2c\x70\x82\xc9\x7a\xff\x15\x8d\x08\x37\x11\x18\xc8\x90\x21\xcc\x39\x74\xae\x8f\x76\xd8\x66\x73\xc3\xf8\x24\xb6\x2c\x79\xc4\xb4\x1f\x40\xea\xa8\x94\x37\x38\xf0\x33\x00\xf6\x8c\xbe\x17\x54\x68\xeb\x23\x5a\x9f\xf0\xe6\x53\x7f\x87\x14\xe9\x7e\x8f\x08\xca\x44\x4e\x41\x19\x10\x63\xb5\xfa\xbd\x15\x6e\x85\xdc\xf6\x66\x06\xb8\x1d\xad\x4a\x95\x06\x55\x84\xb3\xe0\x65\x8c\x20\xa7\x06\xea\xf4\xa0\x77\x7d\xa4\xd2\xe0\xcd\x2a\x0f\xca\x60\x10\x9c\x2b\x44\x03\xdb\x3f\x03\xcd\x47\x81\xc1\xfb\xb0\x27\x22\x02\xbc\xb1\x16\x87\x80\x8c\x50\xcb\x98\xf6\x4b\x7f\x3f\xd3\xd4\x33\x33\xbb\x5a\x06\x1b\x9e\x37\x70\x90\xab\xb1\xe0\xa8\x85\xcb\x26\xb7\x3c\x16\x3e\x63\xff\x64\x51\xff\x2f\x4e\xc8\x24\x9c\x7e\x15\x2b\xd0\x39\x73\xa1\xe9\x64\xe2\xb5\xb2\x35\x28\x1a\x93\x83\x99\xa1\x12\xa2\x45\x29\xe3\x83\xa5\x60\xdc\x50\xbb\x1b\x62\x2a\xd7\x4e\xf3\x56\x58\xdc\xb1\x0f\xfe\x02\x25\x68\xac\x3f\xfa\xe5\xb4\x65\xa8\xed\x76\x43\xe8\x56\x1b\x35\x2e\xe9\x94\x4a\x35\xd8\x82\xc7\x12\xb1\x87\x78\x8a\x0a\xba\xe5\xa2\x2f"}, +{{0x4c,0xb9,0xdf,0x7c,0xe6,0xfa,0xe9,0xd6,0x2b,0xa0,0x9e,0x8e,0xb7,0x0e,0x4c,0x96,0x9b,0xde,0xaf,0xcb,0x5e,0xc7,0xd7,0x02,0x43,0x26,0xe6,0x60,0x3b,0x06,0x21,0xbf,},{0x01,0x80,0x69,0xdd,0x0e,0xb4,0x40,0x55,0xa3,0x5c,0xd8,0xc7,0x7c,0x37,0xca,0x9f,0xb1,0xad,0x24,0x17,0x27,0x13,0x85,0xe1,0x34,0xb2,0xf4,0xe8,0x1f,0x52,0x03,0x3c,},{0xe3,0x3c,0x07,0x83,0x6c,0x53,0x7d,0x6b,0xfb,0xd0,0xf4,0x59,0x2d,0x6e,0x35,0xb1,0x63,0x49,0x9b,0xa7,0x8d,0xc7,0xff,0xce,0xc5,0x65,0xd0,0x4f,0x9a,0x7d,0xb7,0x81,0x94,0x3e,0x29,0xe6,0xce,0x76,0x76,0x3e,0x9b,0xad,0xdf,0x57,0x43,0x7f,0xd9,0xc6,0xb0,0x32,0x39,0xa6,0xe6,0x85,0x0e,0x45,0x02,0xa3,0x56,0xc2,0xe1,0x2c,0x37,0x05,},"\x14\x62\x7d\x6e\xa0\xe7\x89\x54\x60\x75\x94\x76\xdc\x74\xc4\x28\x00\xce\xef\x99\x43\x27\x51\x81\x51\x49\x0d\x9d\xf2\x30\x67\x91\x4e\x44\x78\x8a\x12\x76\x8c\xcb\x25\x47\x1b\x9c\x3b\xa9\xd1\x4f\xb4\x36\xdc\xba\x38\x42\x9b\x3a\x04\x56\x87\x77\x63\xc4\x91\x75\xd0\xe0\x82\x68\x3e\x07\xa9\x05\x8f\x36\x85\xc6\x27\x93\x07\xb2\x30\x3d\x12\x21\xb9\xc2\x97\x93\xd8\xa4\x87\x7f\x6d\xf5\x15\x87\x38\x4d\xad\xf7\x51\xc5\xf7\xbf\xbd\x20\x7d\x51\x96\x22\xc3\x7b\x51\xce\xee\xe2\xc2\x0d\x82\x69\xf8\xcb\x88\xd3\xfe\x43\xd6\xd4\x34\xd5\xbb\xd0\xe2\x03\xc1\x53\x2d\x97\xba\x55\x21\x47\x22\x74\x96\xc8\x7f\x67\xb5\x0b\xb7\x61\x93\xad\xd0\x14\x4d\xf1\xc1\x76\x65\x75\x85\x40\x83\x62\xca\x2e\xd0\x4a\xd6\x2a\xcf\x1c\x25\xe3\x41\xdf\xd1\x49\x8d\x85\xb4\xb1\x34\x9a\x8b\x0b\x9b\x02\xc4\x35\x23\xc5\x58\x53\x41\x9b\xfe\xd3\x7d\x5a\x2c\xdf\x17\xdf\xbf\x1a\x3b\xd7\x75\x9d\x6a\xe1\x80\xf9\xd2\x7d\xcd\x9a\x89\x33\xe2\x9a\x7c\x0a\x30\x77\x1e\xea\x7c\x2e\x0f\xa2\x42\x92\x5d\x23\x36\xdc\xe5\x85\x62\x90\x57\xd8\x44\x32\x39\x64\xf6\xd3\xd1\x1f\xf0\xb3\xf8\x29\xa3\xbe\x8c\x9f\x04\x68\xa6\x82\x3d\x8e\x70\xab\x5a\x2d\xa2\x1e\x15\xfa\x8b\x04\x1a\x29\x81\x22\x22\xe9\xc3\x0b\x2b\xd9\xa1\x2d\x1f\xde\xe6\xf8\x78\x76\xe8\xce\x81\x00\x96\x37\xa8\xbb\x22\x36\x12\x9a\x47\xca\x74\x28\x9e\xe4\xaa\xd4\x29\xff\xe2\x9f\x47\x43\x02\x41\xca\x8c\xc3\x84\x8b\x72\x00\xfd\x6e\x14\x70\x65\x1a\x9a\x0a\x6f\x72\xc9\x03\x3e\x83\x1d\xf0\x51\x40\x8a\x62\x60\xf6\x5c\xba\xf6\xe0\x12\xb1\x8e"}, +{{0xa1,0x36,0xe0,0x09,0xd5,0x3e,0x5e,0xf5,0x9d,0x09,0x46,0xbc,0x17,0x56,0x63,0xa8,0x6b,0xc0,0xfc,0xd2,0x9e,0xad,0xd9,0x5c,0xfc,0x9d,0x26,0x60,0x37,0xb1,0xe4,0xfb,},{0x9c,0x18,0x06,0xec,0x04,0x54,0xf5,0x83,0x14,0xeb,0x83,0x97,0xd6,0x42,0x87,0xde,0xe3,0x86,0x64,0x0d,0x84,0x91,0xab,0xa3,0x64,0x60,0x76,0x88,0x84,0x17,0x15,0xa0,},{0xbc,0x09,0x4b,0xa9,0x1c,0x11,0x5d,0xee,0x15,0xd7,0x53,0x36,0x1a,0x75,0xf3,0xf0,0x3d,0x6a,0xf4,0x5c,0x92,0x15,0x7e,0x95,0xdb,0xe8,0xd3,0x21,0x94,0xb6,0xc5,0xce,0x72,0xb9,0xdc,0x66,0xf7,0x3d,0xf1,0x2d,0xca,0x0b,0x63,0x9f,0x3e,0x79,0x1d,0x47,0x86,0x16,0xa1,0xf8,0xd7,0x35,0x9a,0x42,0xc8,0xea,0xe0,0xdd,0xa1,0x6b,0x16,0x06,},"\xa4\x9d\x1c\x3d\x49\xe1\x3c\x2e\xda\x56\x86\x8a\x88\x24\xaa\x9f\x8d\x2b\xf7\x2f\x21\x95\x5e\xba\xfd\x07\xb3\xbd\xc8\xe9\x24\xde\x20\x93\x6c\xee\x51\x3d\x8a\x64\xa4\x71\x73\xa3\xbd\x65\x9e\xff\x1a\xcc\xff\x82\x44\xb2\x6a\xae\x1a\x0c\x27\xfa\x89\x1b\xf4\xd8\x5e\x8f\xb1\xb7\x6a\x6c\xab\x1e\x7f\x74\xc8\x9e\xe0\x7b\xb4\x0d\x71\x43\x26\xf0\x9b\x3f\xd4\x06\x32\xfa\xd2\x08\xea\x81\x6f\x90\x72\x02\x8c\x14\xb5\xb5\x4e\xcc\x1c\x5b\x7f\xc8\x09\xe7\xe0\x78\x6e\x2f\x11\x49\x5e\x76\x01\x7e\xb6\x2a\xa4\x56\x3f\x3d\x00\xee\x84\x34\x8d\x98\x38\xcd\x17\x64\x9f\x69\x29\xa6\xd2\x06\xf6\x0e\x6f\xc8\x2e\x0c\x34\x64\xb2\x7e\x0e\x6a\xbd\x22\xf4\x46\x9b\xdf\xd4\xcb\x54\xf7\x7e\x32\x9b\x80\xf7\x1b\xf4\x21\x29\xec\x13\xc9\xdf\xe1\x92\xad\xfa\xa4\x2e\xe3\xdd\xee\xda\x38\x58\x16\xfb\xad\x5f\x41\x19\x38\xc6\x3b\x56\x0f\x4e\xcd\x94\x53\x4b\xe7\xd9\x87\x25\xcd\x94\xc9\x9c\xe4\x92\xf0\xf0\x69\xba\x0e\xc0\x8f\x87\x7a\x78\x12\xef\x27\xae\x19\xd7\xa7\x7b\xe6\x3f\x66\xbc\xf8\xd6\xcf\x3a\x1a\x61\xfc\x9c\xfe\xf1\x04\xc7\x46\x2a\x21\xca\x7f\x03\xaf\xb5\xbb\x1a\xc8\xc7\x51\x24\xb5\x54\xe8\xd0\x44\xb8\x10\xd9\x5f\xf8\xc9\xdd\x09\xa3\x44\x84\xd8\xc4\xb6\xc9\x5f\x95\xc3\xc2\x28\x23\xf5\x2c\xe8\x44\x29\x37\x24\xd5\x25\x91\x91\xf1\xba\x09\x29\xe2\xac\xdb\xb8\xb9\xa7\xa8\xad\xf0\xc5\x2e\x78\xac\xdf\xdf\x05\x7b\x09\x85\x88\x1a\xfb\xed\x4d\xbe\xbd\xeb\xbd\xae\x0a\x2b\x63\xbd\x4e\x90\xf9\x6a\xfd\xcb\xbd\x78\xf5\x06\x30\x9f\x9b\xdb\x65\x00\x13\xcb\x73\xfa\xed\x73\x90\x4e"}, +{{0xff,0x0f,0x1c,0x57,0xdd,0x88,0x4f,0xbe,0xea,0x6e,0x29,0x17,0x28,0x2b,0x79,0xba,0x67,0xf8,0xa6,0x85,0x12,0x67,0xb9,0xf4,0x63,0x6d,0xaf,0xda,0x33,0xbd,0x2b,0x5b,},{0xfe,0xf6,0x37,0x8a,0xd1,0x2a,0x7c,0x25,0x2f,0xa6,0xeb,0x74,0x2b,0x05,0x06,0x4b,0x41,0x53,0x0f,0xf0,0x19,0xdc,0x68,0x0a,0xb5,0x44,0xc0,0x27,0xea,0x28,0x36,0xe7,},{0xd5,0x00,0x84,0x86,0x72,0x6c,0xce,0x33,0x0a,0x29,0xdd,0x7e,0x4d,0x74,0x74,0xd7,0x35,0x79,0x82,0x01,0xaf,0xd1,0x20,0x6f,0xeb,0x86,0x9a,0x11,0x2e,0x5b,0x43,0x52,0x3c,0x06,0x97,0x67,0x61,0xbe,0x3c,0xf9,0xb2,0x71,0x63,0x78,0x27,0x3c,0x94,0xf9,0x35,0x72,0xa7,0xd2,0xb8,0x98,0x26,0x34,0xe0,0x75,0x5c,0x63,0x2b,0x44,0x90,0x08,},"\x52\x2a\x5e\x5e\xff\x5b\x5e\x98\xfa\xd6\x87\x8a\x9d\x72\xdf\x6e\xb3\x18\x62\x26\x10\xa1\xe1\xa4\x81\x83\xf5\x59\x0e\xce\xf5\xa6\xdf\x67\x1b\x28\xbe\x91\xc8\x8c\xdf\x7a\xe2\x88\x11\x47\xfe\x6c\x37\xc2\x8b\x43\xf6\x4c\xf9\x81\xc4\x55\xc5\x9e\x76\x5c\xe9\x4e\x1b\x64\x91\x63\x1d\xea\xee\xf6\xd1\xda\x9e\xbc\xa8\x86\x43\xc7\x7f\x83\xea\xe2\xcf\xdd\x2d\x97\xf6\x04\xfe\x45\x08\x1d\x1b\xe5\xc4\xae\x2d\x87\x59\x96\xb8\xb6\xfe\xcd\x70\x7d\x3f\xa2\x19\xa9\x3b\xa0\x48\x8e\x55\x24\x7b\x40\x5e\x33\x0c\xfb\x97\xd3\x1a\x13\x61\xc9\xb2\x08\x4b\xdb\x13\xfb\x0c\x05\x89\x25\xdb\x8c\x3c\x64\x9c\x9a\x3e\x93\x7b\x53\x3c\xc6\x31\x0f\xa3\xb1\x61\x26\xfb\x3c\xc9\xbb\x2b\x35\xc5\xc8\x30\x00\x15\x48\x8a\x30\xfa\xdc\xa3\xc8\x87\x1f\xa7\x0d\xfd\xc7\x05\x5b\xf8\xe6\x31\xf2\x0c\x9b\x25\x28\x31\x1e\x32\x4a\x7c\x4e\xdd\x54\x62\x07\x9f\x34\x41\xc9\xec\xf5\x5f\xa9\x99\xe7\x31\x37\x23\x44\xfd\xc0\xd4\x13\xe4\x17\xaa\xa0\x01\xa1\xb2\xd3\xd9\xbc\x00\x0f\xec\x1b\x02\xbd\x7a\x88\xa8\x12\xd9\xd8\xa6\x6f\x94\x64\x76\x4c\x07\x0c\x93\x04\x1e\xef\xb1\x7c\xe7\x4e\xff\x6d\x4a\xff\x75\xf0\xcb\xf6\xa7\x89\xa9\xec\xde\x74\xab\xe3\x31\x30\xfc\xa0\xda\x85\x3a\xa7\xc3\x31\x3a\xda\x3f\x0a\xe2\xf5\x95\xc6\x79\x6a\x93\x68\x5e\x72\x9d\xd1\x8a\x66\x9d\x63\x81\x82\x5a\xb3\xf3\x6a\x39\x1e\x75\x25\xb2\xa8\x07\xa5\x2f\xa5\xec\x2a\x03\x0a\x8c\xf3\xb7\x73\x37\xac\x41\xfc\xeb\x58\x0e\x84\x5e\xed\x65\x5a\x48\xb5\x47\x23\x8c\x2e\x81\x37\xc9\x2f\x8c\x27\xe5\x85\xca\xad\x31\x06\xee\xe3\x81\x4a"}, +{{0x0b,0xc6,0xaf,0x64,0xde,0x57,0x09,0xd3,0xdb,0xc2,0x8f,0x7e,0xf6,0xd3,0xfe,0x28,0xb6,0xde,0x52,0x9f,0x08,0xf5,0x85,0x7c,0xcb,0x91,0x06,0x95,0xde,0x45,0x4f,0x56,},{0xfb,0x49,0x1f,0xc9,0x00,0x23,0x7b,0xdc,0x7e,0x9a,0x11,0x9f,0x27,0x15,0x0c,0xd9,0x11,0x93,0x5c,0xd3,0x62,0x87,0x49,0xff,0x40,0xef,0x41,0xf3,0x95,0x5b,0xc8,0xac,},{0xdb,0xc7,0x13,0x4d,0x1c,0xd6,0xb0,0x81,0x3b,0x53,0x35,0x27,0x14,0xb6,0xdf,0x93,0x94,0x98,0xe9,0x1c,0xf3,0x7c,0x32,0x43,0x37,0xd9,0xc0,0x88,0xa1,0xb9,0x98,0x34,0x7d,0x26,0x18,0x5b,0x43,0x09,0x00,0x41,0x29,0x29,0xe4,0xf6,0x3e,0x91,0x03,0x79,0xfc,0x42,0xe3,0x55,0xa4,0xe9,0x8f,0x6f,0xee,0x27,0xda,0xfa,0xd1,0x95,0x72,0x06,},"\xac\x78\x86\xe4\xf4\x17\x2a\x22\xc9\x5e\x8e\xea\x37\x43\x7b\x37\x5d\x72\xac\xce\xdc\xee\x6c\xc6\xe8\x16\x76\x33\x01\xa2\xd8\xef\x4d\x6f\x31\xa2\xc1\xd6\x35\x81\x8b\x70\x26\xa3\x95\xce\x0d\xaf\xd7\x1c\x51\x80\x89\x3a\xf7\x6b\x7e\xa0\x56\xc9\x72\xd6\x80\xec\xa0\x1d\xcb\xdb\xae\x6b\x26\xf1\xc5\xf3\x3f\xc9\x88\xb8\x24\xfb\xbe\x00\xca\xcc\x31\x64\x69\xa3\xba\xe0\x7a\xa7\xc8\x88\x5a\xf7\xf6\x5f\x42\xe7\x5c\xef\x94\xdb\xb9\xaa\xb4\x82\x51\x43\xc8\x50\x70\xe7\x71\x6b\x76\x12\xf6\x4e\xf0\xb0\x16\x60\x11\xd2\x3e\xb5\x65\x4a\xa0\x98\xb0\x2d\x8d\x71\xe5\x7c\x8f\xa1\x7b\xff\x2f\xe9\x7d\xc8\x19\x31\x77\xea\xdc\x09\xfb\x19\x2d\x80\xaa\x92\xaf\xa9\x87\x20\xd4\x61\x48\x17\xff\x3c\x39\xd3\xac\xce\x18\x90\x6f\xa3\xde\x09\x61\x89\x31\xd0\xd7\xa6\x0c\x44\x29\xcb\xfa\x20\xcf\x16\x5c\x94\x79\x29\xac\x29\x3a\xe6\xc0\x6e\x7e\x8f\x25\xf1\x26\x42\x91\xe3\xe1\xc9\x8f\x5d\x93\xe6\xec\xc2\x38\x9b\xc6\x0d\xbb\xf4\xa6\x21\xb1\x32\xc5\x52\xa9\x9c\x95\xd2\x6d\x8d\x1a\xf6\x11\x38\xb5\x70\xa0\xde\x4b\x49\x7e\xbe\x80\x51\xc7\x27\x3a\x98\xe6\xe7\x87\x6d\x0b\x32\x75\x03\xaf\x3c\xb2\xcc\x40\x91\xce\x19\x25\xcb\x2f\x29\x57\xf4\xec\x56\xee\x90\xf8\xa0\x9d\xd5\x7d\x6e\x83\x06\x7a\x35\x6a\x4c\xfe\x65\xb1\xb7\xa4\x46\x5d\xa2\xab\x13\x3b\x0e\xfb\x5e\x7d\x4d\xbb\x81\x1b\xcb\xbd\xe7\x12\xaf\xbf\x0f\x7d\xd3\xf3\x26\x22\x22\x84\xb8\xc7\x4e\xac\x7a\xd6\x25\x7f\xa8\xc6\x32\xb7\xda\x25\x59\xa6\x26\x6e\x91\xe0\xef\x90\xdb\xb0\xaa\x96\x8f\x75\x37\x6b\x69\x3f\xca\xa5\xda\x34\x22\x21"}, +{{0x2f,0x5e,0x83,0xbd,0x5b,0x41,0x2e,0x71,0xae,0x3e,0x90,0x84,0xcd,0x36,0x9e,0xfc,0xc7,0x9b,0xf6,0x03,0x7c,0x4b,0x17,0x4d,0xfd,0x6a,0x11,0xfb,0x0f,0x5d,0xa2,0x18,},{0xa2,0x2a,0x6d,0xa2,0x9a,0x5e,0xf6,0x24,0x0c,0x49,0xd8,0x89,0x6e,0x3a,0x0f,0x1a,0x42,0x81,0xa2,0x66,0xc7,0x7d,0x38,0x3e,0xe6,0xf9,0xd2,0x5f,0xfa,0xcb,0xb8,0x72,},{0x9f,0x80,0x92,0x2b,0xc8,0xdb,0x32,0xd0,0xcc,0x43,0xf9,0x93,0x6a,0xff,0xeb,0xe7,0xb2,0xbc,0x35,0xa5,0xd8,0x22,0x77,0xcd,0x18,0x7b,0x5d,0x50,0xdc,0x7f,0xc4,0xc4,0x83,0x2f,0xff,0xa3,0x4e,0x95,0x43,0x80,0x6b,0x48,0x5c,0x04,0x54,0x8e,0x7c,0x75,0x42,0x94,0x25,0xe1,0x4d,0x55,0xd9,0x1f,0xc1,0x05,0x2e,0xfd,0x86,0x67,0x43,0x0b,},"\xb7\x66\x27\x3f\x06\x0e\xf3\xb2\xae\x33\x40\x45\x4a\x39\x1b\x42\x6b\xc2\xe9\x72\x64\xf8\x67\x45\x53\xeb\x00\xdd\x6e\xcf\xdd\x59\xb6\x11\xd8\xd6\x62\x92\x9f\xec\x71\x0d\x0e\x46\x20\x20\xe1\x2c\xdb\xf9\xc1\xec\x88\x58\xe8\x56\x71\xac\xf8\xb7\xb1\x44\x24\xce\x92\x07\x9d\x7d\x80\x1e\x2a\xd9\xac\xac\x03\x6b\xc8\xd2\xdf\xaa\x72\xaa\x83\x9b\xff\x30\xc0\xaa\x7e\x41\x4a\x88\x2c\x00\xb6\x45\xff\x9d\x31\xbc\xf5\xa5\x43\x82\xde\xf4\xd0\x14\x2e\xfa\x4f\x06\xe8\x23\x25\x7f\xf1\x32\xee\x96\x8c\xdc\x67\x38\xc5\x3f\x53\xb8\x4c\x8d\xf7\x6e\x9f\x78\xdd\x50\x56\xcf\x3d\x4d\x5a\x80\xa8\xf8\x4e\x3e\xde\xc4\x85\x20\xf2\xcb\x45\x83\xe7\x08\x53\x93\x55\xef\x7a\xa8\x6f\xb5\xa0\xe8\x7a\x94\xdc\xf1\x4f\x30\xa2\xcc\xa5\x68\xf1\x39\xd9\xce\x59\xea\xf4\x59\xa5\xc5\x91\x6c\xc8\xf2\x0b\x26\xaa\xf6\xc7\xc0\x29\x37\x9a\xed\xb0\x5a\x07\xfe\x58\x5c\xca\xc6\x03\x07\xc1\xf5\x8c\xa9\xf8\x59\x15\x7d\x06\xd0\x6b\xaa\x39\x4a\xac\xe7\x9d\x51\xb8\xcb\x38\xcf\xa2\x59\x81\x41\xe2\x45\x62\x4e\x5a\xb9\xb9\xd6\x87\x31\x17\x33\x48\x90\x53\x15\xbf\x1a\x5a\xd6\x1d\x1e\x8a\xda\xeb\x81\x0e\x4e\x8a\x86\xd7\xc1\x35\x37\xb0\xbe\x86\x0a\xb2\xed\x35\xb7\x33\x99\xb8\x80\x8a\xa9\x1d\x75\x0f\x77\x94\x3f\x8a\x8b\x7e\x89\xfd\xb5\x07\x28\xaa\x3d\xbb\xd8\xa4\x1a\x6e\x00\x75\x6f\x43\x8c\x9b\x9e\x9d\x55\x87\x2d\xf5\xa9\x06\x8a\xdd\x8a\x97\x2b\x7e\x43\xed\xad\x9c\xed\x22\x37\xca\x13\x67\xbe\x4b\x7c\xdb\x66\xa5\x4e\xa1\x2e\xef\x12\x94\x71\x15\x86\x10\xea\xf2\x8f\x99\xf7\xf6\x86\x55\x7d\xcd\xf6\x44\xea"}, +{{0x72,0x2a,0x2d,0xa5,0x0e,0x42,0xc1,0x1a,0x61,0xc9,0xaf,0xac,0x7b,0xe1,0xa2,0xfe,0xd2,0x26,0x7d,0x65,0x0f,0x8f,0x7d,0x8e,0x5b,0xc7,0x06,0xb8,0x07,0xc1,0xb9,0x1d,},{0xfd,0x0b,0x96,0x45,0x62,0xf8,0x23,0x72,0x1e,0x64,0x9c,0x3f,0xed,0xb4,0x32,0xa7,0x6f,0x91,0xe0,0xae,0xad,0x7c,0x61,0xd3,0x5f,0x95,0xed,0x77,0x26,0xd7,0x85,0x89,},{0xc2,0x69,0x5a,0x57,0x17,0x2a,0xaa,0x31,0xbd,0x08,0x90,0xf2,0x31,0xca,0x8e,0xee,0xc0,0x28,0x7a,0x87,0x17,0x26,0x69,0xa8,0x99,0xad,0x08,0x91,0xce,0xa4,0xc4,0x75,0x79,0xb5,0x04,0x20,0xe7,0x91,0xcd,0xec,0x8c,0x18,0x2c,0x8a,0x0e,0x8d,0xde,0x21,0xb2,0x48,0x0b,0x0c,0xfd,0x81,0x11,0xe2,0x8e,0x56,0x03,0x34,0x7a,0x35,0x2d,0x04,},"\x17\x3e\x8b\xb8\x85\xe1\xf9\x08\x14\x04\xac\xac\x99\x90\x41\xd2\xec\xfc\xb7\x3f\x94\x5e\x0d\xb3\x6e\x63\x1d\x7c\xd1\xab\x99\x9e\xb7\x17\xf3\x4b\xf0\x78\x74\xbf\x3d\x34\xe2\x53\x0e\xb6\x08\x5f\x4a\x9f\x88\xae\x1b\x0f\x7d\x80\xf2\x21\x45\x6a\x8e\x9a\x88\x90\xb9\x1a\x50\x19\x2d\xea\xaa\xcc\x0a\x1a\x61\x5a\x87\x84\x1e\x2c\x5a\x9e\x05\x79\x57\xaf\x6e\x48\xe7\x8c\xc8\x61\x98\xe3\x2e\x7a\xa2\x4d\xcf\x6c\xff\xa3\x29\xbc\x72\x60\x6d\x65\xb1\x16\x82\xc8\xba\x73\x6c\xce\x22\xa0\x57\x85\xdf\x11\x46\x33\x1e\x41\x60\x9c\xf9\xca\x71\x1c\xf4\x64\x95\x82\x97\x13\x8b\x58\xa9\x07\x3f\x3b\xbf\x06\xad\x8a\x85\xd1\x35\xde\x66\x65\x21\x04\xd8\x8b\x49\xd2\x7a\xd4\x1e\x59\xbc\xc4\x4c\x7f\xab\x68\xf5\x3f\x05\x02\xe2\x93\xff\xca\xba\xaf\x75\x59\x27\xdf\xdf\xfb\xfd\xe3\xb3\x5c\x08\x0b\x5d\xe4\xc8\xb7\x85\xf4\xda\x64\xef\x35\x7b\xc0\xd1\x46\x6a\x6a\x96\x56\x0c\x3c\x4f\x3e\x3c\x0b\x56\x3a\x00\x3f\x5f\x95\xf2\x37\x17\x1b\xce\x1a\x00\x17\x71\xa0\x4e\xde\x7c\xdd\x9b\x8c\xa7\x70\xfd\x36\xef\x90\xe9\xfe\x00\x00\xa8\xd7\x68\x5f\xd1\x53\xcc\x72\x82\xde\x95\x92\x0a\x8f\x8f\x08\x98\xd0\x0b\xf0\xc6\xc9\x33\xfe\x5b\xb9\x65\x3f\xf1\x46\xc4\xe2\xac\xd1\xa2\xe0\xc2\x3c\x12\x44\x84\x4d\xac\xf8\x65\x27\x16\x30\x2c\x20\x32\xf9\xc1\x14\x67\x9e\xd2\x6b\x3e\xe3\xab\x4a\x7b\x18\xbc\x4e\x30\x71\xf0\x97\x7d\xb5\x7c\xd0\xac\x68\xc0\x72\x7a\x09\xb4\xf1\x25\xfb\x64\xaf\x28\x50\xb2\x6c\x8a\x48\x42\x63\x33\x4e\x2d\xa9\x02\xd7\x44\x73\x70\x44\xe7\x9a\xb1\xcf\x5b\x2f\x93\xa0\x22\xb6\x3d\x40\xcd"}, +{{0x5f,0xe9,0xc3,0x96,0x0e,0xd5,0xbd,0x37,0x4c,0xc9,0x4d,0x42,0x35,0x7e,0x6a,0x24,0xdc,0x7e,0x30,0x60,0x78,0x8f,0x72,0x63,0x65,0xde,0xfa,0xcf,0x13,0xcd,0x12,0xda,},{0x0c,0xe7,0xb1,0x55,0xc8,0xb2,0x0e,0xbd,0xaa,0xcd,0xc2,0xaa,0x23,0x62,0x7e,0x34,0xb1,0xf9,0xac,0xe9,0x80,0x65,0x0a,0x25,0x30,0xc7,0x60,0x7d,0x04,0x81,0x4e,0xb4,},{0x37,0x9f,0x9c,0x54,0xc4,0x13,0xaf,0x0d,0x19,0x2e,0x9b,0xc7,0x36,0xb2,0x9d,0xa9,0xd5,0x21,0xe7,0xba,0x78,0x41,0xd3,0x09,0xf9,0xbc,0xc1,0xe7,0x42,0xec,0x43,0x08,0xfe,0x9f,0x7b,0xa5,0x1e,0x0b,0x22,0xae,0xd4,0x87,0xcb,0x4a,0xa3,0x91,0x3b,0x9b,0xeb,0xfb,0x3a,0xac,0xd3,0x8f,0x40,0x39,0xf9,0xbb,0xbe,0xbe,0x1a,0xd8,0x00,0x02,},"\xc9\x49\x0d\x83\xd9\xc3\xa9\x37\x0f\x06\xc9\x1a\xf0\x01\x68\x5a\x02\xfe\x49\xb5\xca\x66\x77\x33\xff\xf1\x89\xee\xe8\x53\xec\x16\x67\xa6\xc1\xb6\xc7\x87\xe9\x24\x48\x12\xd2\xd5\x32\x86\x6a\xb7\x4d\xfc\x87\x0d\x6f\x14\x03\x3b\x6b\xcd\x39\x85\x2a\x39\x00\xf8\xf0\x8c\xd9\x5a\x74\xcb\x8c\xbe\x02\xb8\xb8\xb5\x1e\x99\x3a\x06\xad\xfe\xbd\x7f\xc9\x85\x4a\xe5\xd2\x9f\x4d\xf9\x64\x28\x71\xd0\xc5\xe4\x70\xd9\x03\xcf\xbc\xbd\x5a\xdb\x32\x75\x62\x8f\x28\xa8\x0b\xf8\xc0\xf0\x37\x66\x87\xda\xe6\x73\xbf\x7a\x85\x47\xe8\x0d\x4a\x98\x55\xae\x25\x72\xfc\x2b\x20\x5d\xc8\xa1\x98\x01\x6d\xdc\x9b\x50\x99\x5f\x5b\x39\xf3\x68\xf5\x40\x50\x4a\x55\x18\x03\xd6\xdd\x5f\x87\x48\x28\xe5\x54\x1d\xed\x05\x28\x94\xd9\xe2\xdc\x5e\x6a\xa3\x51\x08\x7e\x79\x0c\x0d\xd5\xd9\xc4\xde\xcb\x21\x7e\x4d\xb8\x1c\x98\xa1\x84\xb2\x64\xe6\xda\xea\xc0\xf1\x1e\x07\x4c\xae\x2b\xfc\x89\x9f\x54\xb4\x19\xc6\x5d\xcc\x22\x66\x4a\x91\x5f\xbf\xff\xac\x35\xce\xe0\xf2\x86\xeb\x7b\x14\x49\x33\xdb\x93\x3e\x16\xc4\xbc\xb6\x50\xd5\x37\x72\x24\x89\xde\x23\x63\x73\xfd\x8d\x65\xfc\x86\x11\x8b\x6d\xef\x37\xca\x46\x08\xbc\x6c\xe9\x27\xb6\x54\x36\xff\xda\x7f\x02\xbf\xbf\x88\xb0\x45\xae\x7d\x2c\x2b\x45\xa0\xb3\x0c\x8f\x2a\x04\xdf\x95\x32\x21\x08\x8c\x55\x5f\xe9\xa5\xdf\x26\x09\x82\xa3\xd6\x4d\xf1\x94\xee\x95\x2f\xa9\xa9\x8c\x31\xb9\x64\x93\xdb\x61\x80\xd1\x3d\x67\xc3\x67\x16\xf9\x5f\x8c\x0b\xd7\xa0\x39\xad\x99\x06\x67\xca\x34\xa8\x3a\xc1\xa1\x8c\x37\xdd\x7c\x77\x36\xaa\x6b\x9b\x6f\xc2\xb1\xac\x0c\xe1\x19\xef\x77"}, +{{0xec,0x2f,0xa5,0x41,0xac,0x14,0xb4,0x14,0x14,0x9c,0x38,0x25,0xea,0xa7,0x00,0x1b,0x79,0x5a,0xa1,0x95,0x7d,0x40,0x40,0xdd,0xa9,0x25,0x73,0x90,0x4a,0xfa,0x7e,0xe4,},{0x71,0xb3,0x63,0xb2,0x40,0x84,0x04,0xd7,0xbe,0xec,0xde,0xf1,0xe1,0xf5,0x11,0xbb,0x60,0x84,0x65,0x8b,0x53,0x2f,0x7e,0xa6,0x3d,0x4e,0x3f,0x5f,0x01,0xc6,0x1d,0x31,},{0x84,0xd1,0x8d,0x56,0xf9,0x64,0xe3,0x77,0x67,0x59,0xbb,0xa9,0x2c,0x51,0x0c,0x2b,0x6d,0x57,0x45,0x55,0xc3,0xcd,0xda,0xde,0x21,0x2d,0xa9,0x03,0x74,0x55,0x49,0x91,0xe7,0xd7,0x7e,0x27,0x8d,0x63,0xe3,0x46,0x93,0xe1,0x95,0x80,0x78,0xcc,0x36,0x85,0xf8,0xc4,0x1c,0x1f,0x53,0x42,0xe3,0x51,0x89,0x96,0x38,0xef,0x61,0x21,0x14,0x01,},"\x27\x49\xfc\x7c\x4a\x72\x9e\x0e\x0a\xd7\x1b\x5b\x74\xeb\x9f\x9c\x53\x4e\xbd\x02\xff\xc9\xdf\x43\x74\xd8\x13\xbd\xd1\xae\x4e\xb8\x7f\x13\x50\xd5\xfd\xc5\x63\x93\x45\x15\x77\x17\x63\xe6\xc3\x3b\x50\xe6\x4e\x0c\xd1\x14\x57\x30\x31\xd2\x18\x6b\x6e\xca\x4f\xc8\x02\xcd\xdc\x7c\xc5\x1d\x92\xa6\x13\x45\xa1\x7f\x6a\xc3\x8c\xc7\x4d\x84\x70\x7a\x51\x56\xbe\x92\x02\xde\xe3\x44\x46\x52\xe7\x9b\xae\x7f\x0d\x31\xbd\x17\x56\x79\x61\xf6\x5d\xd0\x1a\x8e\x4b\xee\x38\x33\x19\x38\xce\x4b\x2b\x55\x06\x91\xb9\x9a\x4b\xc3\xc0\x72\xd1\x86\xdf\x4b\x33\x44\xa5\xc8\xfb\xfb\xb9\xfd\x2f\x35\x5f\x61\x07\xe4\x10\xc3\xd0\xc7\x98\xb6\x8d\x3f\xb9\xc6\xf7\xab\x5f\xe2\x7e\x70\x87\x1e\x86\x76\x76\x98\xfe\x35\xb7\x7e\xad\x4e\x43\x5a\x94\x02\xcc\x9e\xd6\xa2\x65\x7b\x05\x9b\xe0\xa2\x10\x03\xc0\x48\xbb\xf5\xe0\xeb\xd9\x3c\xbb\x2e\x71\xe9\x23\xcf\x5c\x72\x8d\x17\x58\xcd\x81\x7a\xd7\x4b\x45\x4a\x88\x71\x26\xd6\x53\xb9\x5a\x7f\x25\xe5\x29\x3b\x76\x8c\x9f\xc5\xa9\xc3\x5a\x23\x72\xe3\x74\x1b\xc9\x0f\xd6\x63\x01\x42\x7b\x10\x82\x4b\xb4\xb1\xe9\x11\x0b\xfb\xa8\x4c\x21\xa4\x0e\xb8\xfe\xd4\x49\x7e\x91\xdc\x3f\xfd\x04\x38\xc5\x14\xc0\xa8\xcb\x4c\xac\x6a\xd0\x25\x6b\xf1\x1d\x5a\xa7\xa9\xc7\xc0\x0b\x66\x9b\x01\x5b\x0b\xf8\x14\x25\xa2\x14\x13\xe2\xff\xb6\xed\xc0\xbd\x78\xe3\x85\xc4\x4f\xd7\x45\x58\xe5\x11\xc2\xc2\x5f\xee\x1f\xec\x18\xd3\x99\x0b\x86\x90\x30\x0f\xa7\x11\xe9\x3d\x98\x54\x66\x8f\x01\x87\x06\x5e\x76\xe7\x11\x3a\xe7\x63\xc3\x0d\xdd\x86\x72\x0b\x55\x46\xa6\xc3\xc6\xf1\xc4\x3b\xc6\x7b\x14"}, +{{0x61,0x32,0x69,0x2a,0x5e,0xf2,0x7b,0xf4,0x76,0xb1,0xe9,0x91,0xe6,0xc4,0x31,0xa8,0xc7,0x64,0xf1,0xae,0xbd,0x47,0x02,0x82,0xdb,0x33,0x21,0xbb,0x7c,0xb0,0x9c,0x20,},{0x7a,0x2d,0x16,0x61,0x84,0xf9,0xe5,0xf7,0x3b,0xea,0x45,0x44,0x86,0xb0,0x41,0xce,0xb5,0xfc,0x23,0x14,0xa7,0xbd,0x59,0xcb,0x71,0x8e,0x79,0xf0,0xec,0x98,0x9d,0x84,},{0xeb,0x67,0x7f,0x33,0x47,0xe1,0xa1,0xea,0x92,0x9e,0xfd,0xf6,0x2b,0xf9,0x10,0x5a,0x6c,0x8f,0x49,0x93,0x03,0x3b,0x4f,0x6d,0x03,0xcb,0x0d,0xbf,0x9c,0x74,0x2b,0x27,0x07,0x04,0xe3,0x83,0xab,0x7c,0x06,0x76,0xbd,0xb1,0xad,0x0c,0xe9,0xb1,0x66,0x73,0x08,0x3c,0x96,0x02,0xec,0x10,0xae,0x1d,0xd9,0x8e,0x87,0x48,0xb3,0x36,0x44,0x0b,},"\xa9\xc0\x86\x16\x65\xd8\xc2\xde\x06\xf9\x30\x1d\xa7\x0a\xfb\x27\xb3\x02\x4b\x74\x4c\x6b\x38\xb2\x42\x59\x29\x4c\x97\xb1\xd1\xcb\x4f\x0d\xcf\x75\x75\xa8\xed\x45\x4e\x2f\x09\x80\xf5\x03\x13\xa7\x73\x63\x41\x51\x83\xfe\x96\x77\xa9\xeb\x1e\x06\xcb\x6d\x34\xa4\x67\xcb\x7b\x07\x58\xd6\xf5\x5c\x56\x4b\x5b\xa1\x56\x03\xe2\x02\xb1\x88\x56\xd8\x9e\x72\xa2\x3a\xb0\x7d\x88\x53\xff\x77\xda\x7a\xff\x1c\xae\xbd\x79\x59\xf2\xc7\x10\xef\x31\xf5\x07\x8a\x9f\x2c\xda\xe9\x26\x41\xa1\xcc\x5f\x74\xd0\xc1\x43\xec\x42\xaf\xba\xa5\xf3\x78\xa9\xe1\x0d\x5b\xf7\x45\x87\xfa\x5f\x49\xc1\x56\x23\x32\x47\xda\xfd\x39\x29\xac\xde\x88\x8d\xc6\x84\x33\x7e\x40\xcd\xc5\x93\x2e\x7e\xb7\x3f\xfc\xc9\x0b\x85\xc0\xad\x46\x04\x16\x69\x1a\xef\xbd\x7e\xfd\x07\xb6\x57\xc3\x50\x94\x6a\x0e\x36\x6b\x37\xa6\xc8\x08\x9a\xba\x5c\x5f\xe3\xbb\xca\x06\x4a\xfb\xe9\xd4\x7f\xbc\x83\x91\x4a\xf1\xcb\x43\xc2\xb2\xef\xa9\x8e\x0a\x43\xbe\x32\xba\x82\x32\x02\x00\x1d\xef\x36\x81\x72\x51\xb6\x5f\x9b\x05\x06\xce\xf6\x68\x36\x42\xa4\x6e\xd6\x12\xf8\xca\x81\xee\x97\xbb\x04\xd3\x17\xb5\x17\x34\x3a\xde\x2b\x77\x12\x6d\x1f\x02\xa8\x7b\x76\x04\xc8\x65\x3b\x67\x48\xcf\x54\x88\xfa\x6d\x43\xdf\x80\x9f\xaa\x19\xe6\x92\x92\xd3\x8c\x5d\x39\x7d\xd8\xe2\x0c\x7a\xf7\xc5\x33\x4e\xc9\x77\xf5\x01\x0a\x0f\x7c\xb5\xb8\x94\x79\xca\x06\xdb\x4d\x12\x62\x7f\x06\x7d\x6c\x42\x18\x6a\x6b\x1f\x87\x42\xf3\x6a\xe7\x09\xba\x72\x0e\x3c\xd8\x98\x11\x66\x66\xd8\x1b\x19\x0b\x9b\x9d\x2a\x72\x20\x2c\xb6\x90\xa0\x3f\x33\x10\x42\x9a\x71\xdc\x04\x8c\xde"}, +{{0xf2,0x19,0xb2,0x10,0x11,0x64,0xaa,0x97,0x23,0xbd,0xe3,0xa7,0x34,0x6f,0x68,0xa3,0x50,0x61,0xc0,0x1f,0x97,0x82,0x07,0x25,0x80,0xba,0x32,0xdf,0x90,0x3b,0xa8,0x91,},{0xf6,0x6b,0x92,0x0d,0x5a,0xa1,0xa6,0x08,0x54,0x95,0xa1,0x48,0x05,0x39,0xbe,0xba,0x01,0xff,0xe6,0x0e,0x6a,0x63,0x88,0xd1,0xb2,0xe8,0xed,0xa2,0x33,0x55,0x81,0x0e,},{0x17,0xf0,0x12,0x7c,0xa3,0xba,0xfa,0x5f,0x4e,0xe9,0x59,0xcd,0x60,0xf7,0x72,0xbe,0x87,0xa0,0x03,0x49,0x61,0x51,0x7e,0x39,0xa0,0xa1,0xd0,0xf4,0xb9,0xe2,0x6d,0xb1,0x33,0x6e,0x60,0xc8,0x2b,0x35,0x2c,0x4c,0xba,0xcd,0xbb,0xd1,0x17,0x71,0xc3,0x77,0x4f,0x8c,0xc5,0xa1,0xa7,0x95,0xd6,0xe4,0xf4,0xeb,0xd5,0x1d,0xef,0x36,0x77,0x0b,},"\x01\x55\x77\xd3\xe4\xa0\xec\x1a\xb2\x59\x30\x10\x63\x43\xff\x35\xab\x4f\x1e\x0a\x8a\x2d\x84\x4a\xad\xbb\x70\xe5\xfc\x53\x48\xcc\xb6\x79\xc2\x29\x5c\x51\xd7\x02\xaa\xae\x7f\x62\x73\xce\x70\x29\x7b\x26\xcb\x7a\x25\x3a\x3d\xb9\x43\x32\xe8\x6a\x15\xb4\xa6\x44\x91\x23\x27\x91\xf7\xa8\xb0\x82\xee\x28\x34\xaf\x30\x40\x0e\x80\x46\x47\xa5\x32\xe9\xc4\x54\xd2\xa0\xa7\x32\x01\x30\xab\x6d\x4d\x86\x00\x73\xa3\x46\x67\xac\x25\xb7\xe5\xe2\x74\x7b\xa9\xf5\xc9\x45\x94\xfb\x68\x37\x7a\xe2\x60\x36\x9c\x40\x71\x3b\x4e\x32\xf2\x31\x95\xbf\x91\xd3\xd7\xf1\xa2\x71\x9b\xf4\x08\xaa\xd8\xd8\xa3\x47\xb1\x12\xe8\x4b\x11\x88\x17\xcb\x06\x51\x33\x44\x02\x17\x63\x03\x52\x72\xa7\xdb\x72\x8a\x0c\xcd\xaa\x94\x9c\x61\x71\x5d\x07\x64\x14\x0b\x3e\x8c\x01\xd2\x0f\xf1\x59\x3c\x7f\x2d\x55\xc4\xe8\x2a\x1c\x0c\xb1\xea\x58\x44\x2b\xf8\x0a\x74\x1b\xca\x91\xf5\x8a\xb0\x58\x1b\x49\x8e\xe9\xfe\x3c\x92\xca\x65\x41\x48\xef\x75\x31\x35\x43\xd1\xaf\xf3\x82\xbe\xfe\x1a\x93\xb0\x21\x90\xce\x01\x02\x17\x51\x58\xe2\x07\x1d\x02\xba\xca\xd8\xdb\xe9\xfb\x94\x0f\xcb\x61\x0c\x10\x5a\xd5\x2c\x80\xfe\xb1\xec\x4e\x52\x4f\x4c\x0e\xc7\x98\x3e\x9c\xe6\x96\xfa\x4f\xcf\x4b\xf0\x51\x4b\x8f\x04\x32\xb1\x7d\x54\x48\xfc\x42\x6f\xea\x2b\x01\xac\x7b\x26\xc2\xae\xd7\x69\x92\x75\x34\xda\x22\x57\x6f\xc1\xbb\xa7\x26\xe9\xd6\x5b\xe0\x1b\x59\xf6\x0a\x64\x8a\xce\x2f\xc3\xe5\xe2\x75\x78\x9f\xa6\x37\xcb\xbd\x84\xbe\x3d\x6a\xc2\x44\x57\xa6\x29\x2c\xd6\x56\xc7\xb5\x69\xa5\x2f\xfe\xa7\x91\x6b\x8d\x04\xb4\xf4\xa7\x5b\xe7\xac\x95\x14\x2f"}, +{{0xfc,0x18,0x00,0x35,0xae,0xc0,0xf5,0xed,0xe7,0xbd,0xa9,0x3b,0xf7,0x7a,0xde,0x7a,0x81,0xed,0x06,0xde,0x07,0xee,0x2e,0x3a,0xa8,0x57,0x6b,0xe8,0x16,0x08,0x61,0x0a,},{0x4f,0x21,0x5e,0x94,0x8c,0xae,0x24,0x3e,0xe3,0x14,0x3b,0x80,0x28,0x2a,0xd7,0x92,0xc7,0x80,0xd2,0xa6,0xb7,0x50,0x60,0xca,0x1d,0x29,0x0c,0xa1,0xa8,0xe3,0x15,0x1f,},{0xa4,0x3a,0x71,0xc3,0xa1,0x9c,0x35,0x66,0x0d,0xae,0x6f,0x31,0xa2,0x54,0xb8,0xc0,0xea,0x35,0x93,0xfc,0x8f,0xca,0x74,0xd1,0x36,0x40,0x01,0x2b,0x9e,0x94,0x73,0xd4,0xaf,0xe0,0x70,0xdb,0x01,0xe7,0xfb,0x39,0x9b,0xf4,0xca,0x60,0x70,0xe0,0x62,0x18,0x00,0x11,0x28,0x5a,0x67,0xdd,0x68,0x58,0xb7,0x61,0xe4,0x6c,0x6b,0xd3,0x20,0x04,},"\xb5\xe8\xb0\x16\x25\x66\x4b\x22\x23\x39\xe0\xf0\x5f\x93\xa9\x90\xba\x48\xb5\x6a\xe6\x54\x39\xa1\x75\x20\x93\x2d\xf0\x11\x72\x1e\x28\x4d\xbe\x36\xf9\x86\x31\xc0\x66\x51\x00\x98\xa6\x8d\x7b\x69\x2a\x38\x63\xe9\x9d\x58\xdb\x76\xca\x56\x67\xc8\x04\x3c\xb1\x0b\xd7\xab\xba\xf5\x06\x52\x9f\xbb\x23\xa5\x16\x6b\xe0\x38\xaf\xfd\xb9\xa2\x34\xc4\xf4\xfc\xf4\x3b\xdd\xd6\xb8\xd2\xce\x77\x2d\xd6\x53\xed\x11\x5c\x09\x5e\x23\x2b\x26\x9d\xd4\x88\x8d\x23\x68\xcb\x1c\x66\xbe\x29\xdd\x38\x3f\xca\x67\xf6\x67\x65\xb2\x96\x56\x4e\x37\x55\x5f\x0c\x0e\x48\x45\x04\xc5\x91\xf0\x06\xea\x85\x33\xa1\x25\x83\xad\x2e\x48\x31\x8f\xf6\xf3\x24\xec\xaf\x80\x4b\x1b\xae\x04\xaa\x89\x67\x43\xe6\x7e\xf6\x1c\xa3\x83\xd5\x8e\x42\xac\xfc\x64\x10\xde\x30\x77\x6e\x3b\xa2\x62\x37\x3b\x9e\x14\x41\x94\x39\x55\x10\x1a\x4e\x76\x82\x31\xad\x9c\x65\x29\xef\xf6\x11\x8d\xde\x5d\xf0\x2f\x94\xb8\xd6\xdf\x2d\x99\xf2\x78\x63\xb5\x17\x24\x3a\x57\x9e\x7a\xaf\xf3\x11\xea\x3a\x02\x82\xe4\x7c\xa8\x76\xfa\xbc\x22\x80\xfc\xe7\xad\xc9\x84\xdd\x0b\x30\x88\x5b\x16\x50\xf1\x47\x1d\xfc\xb0\x52\x2d\x49\xfe\xc7\xd0\x42\xf3\x2a\x93\xbc\x36\x8f\x07\x60\x06\xea\x01\xec\x1c\x74\x12\xbf\x66\xf6\x2d\xc8\x8d\xe2\xc0\xb7\x47\x01\xa5\x61\x4e\x85\x5e\x9f\xa7\x28\xfb\x1f\x11\x71\x38\x5f\x96\xaf\xbd\xe7\x0d\xea\x02\xe9\xaa\x94\xdc\x21\x84\x8c\x26\x30\x2b\x50\xae\x91\xf9\x69\x3a\x18\x64\xe4\xe0\x95\xae\x03\xcd\xc2\x2a\xd2\x8a\x0e\xb7\xdb\x59\x67\x79\x24\x67\x12\xfa\xb5\xf5\xda\x32\x7e\xfe\xc3\xe7\x96\x12\xde\x0a\x6c\xca\xa5\x36\x75\x9b\x8e"}, +{{0xa2,0x83,0x6a,0x65,0x42,0x79,0x12,0x12,0x2d,0x25,0xdc,0xdf,0xc9,0x9d,0x70,0x46,0xfe,0x9b,0x53,0xd5,0xc1,0xbb,0x23,0x61,0x7f,0x11,0x89,0x0e,0x94,0xca,0x93,0xed,},{0x8c,0x12,0xbd,0xa2,0x14,0xc8,0xab,0xb2,0x28,0x6a,0xcf,0xfb,0xf8,0x11,0x24,0x25,0x04,0x0a,0xab,0x9f,0x4d,0x8b,0xb7,0x87,0x0b,0x98,0xda,0x01,0x59,0xe8,0x82,0xf1,},{0xe6,0xa9,0xa6,0xb4,0x36,0x55,0x9a,0x43,0x20,0xc4,0x5c,0x0c,0x2c,0x4a,0x2a,0xed,0xec,0xb9,0x0d,0x41,0x6d,0x52,0xc8,0x26,0x80,0xac,0x73,0x30,0xd0,0x62,0xae,0xbe,0xf3,0xe9,0xac,0x9f,0x2c,0x5f,0xfa,0x45,0x5c,0x9b,0xe1,0x13,0x01,0x3a,0x2b,0x28,0x2e,0x56,0x00,0xfd,0x30,0x64,0x35,0xad,0xa8,0x3b,0x1e,0x48,0xba,0x2a,0x36,0x05,},"\x81\x3d\x60\x61\xc5\x6e\xae\x0f\xf5\x30\x41\xc0\x24\x4a\xa5\xe2\x9e\x13\xec\x0f\x3f\xb4\x28\xd4\xbe\xb8\xa9\x9e\x04\xbc\xa8\xc4\x1b\xdd\xb0\xdb\x94\x5f\x48\x7e\xfe\x38\xf2\xfc\x14\xa6\x28\xfa\xfa\x24\x62\xf8\x60\xe4\xe3\x42\x50\xeb\x4e\x93\xf1\x39\xab\x1b\x74\xa2\x61\x45\x19\xe4\x1e\xe2\x40\x3b\xe4\x27\x93\x0a\xb8\xbc\x82\xec\x89\xce\xaf\xb6\x09\x05\xbd\x4d\xdb\xbd\x13\xbd\xb1\x96\x54\x31\x4f\xc9\x23\x73\x14\x0b\x96\x2e\x22\x58\xe0\x38\xd7\x1b\x9e\xc6\x6b\x84\xef\x83\x19\xe0\x35\x51\xcb\x70\x7e\x74\x7f\x6c\x40\xad\x47\x6f\xbe\xfd\xce\x71\xf3\xa7\xb6\x7a\x1a\xf1\x86\x9b\xc6\x44\x06\x86\xe7\xe0\x85\x5e\x4f\x36\x9d\x1d\x88\xb8\x09\x9f\xba\x54\x71\x46\x78\x62\x7b\xba\x1a\xff\x41\xe7\x70\x7b\xc9\x7e\xdd\xf8\x90\xb0\xc0\x8d\xce\x3e\x98\x00\xd2\x4c\x6f\x61\x09\x2c\xe2\x8d\x48\x1b\x5d\xea\x5c\x09\x6c\x55\xd7\x2f\x89\x46\x00\x91\x31\xfb\x96\x8e\x2b\xc8\xa0\x54\xd8\x25\xad\xab\x76\x74\x0d\xcf\x0d\x75\x8c\x8b\xf5\x4f\xf3\x86\x59\xe7\x1b\x32\xbf\xe2\xe6\x15\xaa\xab\xb0\xf5\x29\x30\x85\x64\x9c\xf6\x0b\x98\x47\xbc\x62\x01\x1c\xe3\x87\x8a\xf6\x28\x98\x4a\x58\x40\xa4\xad\x5d\xae\x37\x02\xdb\x36\x7d\xa0\xf8\xa1\x65\xfe\xd0\x51\x7e\xb5\xc4\x42\xb0\x14\x53\x30\x24\x1b\x97\xee\xca\x73\x3b\xa6\x68\x8b\x9c\x12\x9a\x61\xcd\x12\x36\xaf\xf0\xe2\x7b\xcf\x98\xc2\x8b\x0f\xbe\xea\x55\xa3\xd7\xc7\x19\x3d\x64\x4b\x27\x49\xf9\x86\xbd\x46\xaf\x89\x38\xe8\xfa\xae\xaf\xbd\x9c\xec\x36\x12\xab\x00\x5b\xd7\xc3\xee\xaf\xe9\xa3\x12\x79\xca\x61\x02\x56\x06\x66\xba\x16\x13\x6f\xf1\x45\x2f\x85\x0a\xdb"}, +{{0xf0,0x51,0xaf,0x42,0x6d,0x0c,0x32,0x82,0xfa,0xfc,0x8b,0xf9,0x12,0xad,0xe1,0xc2,0x42,0x11,0xa9,0x5a,0xd2,0x00,0xe1,0xee,0xf5,0x49,0x32,0x0e,0x1c,0xb1,0xa2,0x52,},{0xfa,0x87,0x95,0x5e,0x0e,0xa1,0x3d,0xde,0x49,0xd8,0x3d,0xc2,0x2e,0x63,0xa2,0xbd,0xf1,0x07,0x67,0x25,0xc2,0xcc,0x7f,0x93,0xc7,0x65,0x11,0xf2,0x8e,0x79,0x44,0xf2,},{0xb8,0xf7,0x13,0x57,0x8a,0x64,0x46,0x67,0x19,0xac,0xeb,0x43,0x2f,0xce,0x30,0x2a,0x87,0xcf,0x06,0x6b,0xf3,0xe1,0x02,0xa3,0x50,0x61,0x69,0x21,0xa8,0x40,0x96,0x4b,0xfc,0x7e,0x68,0x5d,0x8f,0xd1,0x74,0x55,0xac,0x3e,0xb4,0x86,0x1e,0xdc,0xb8,0x97,0x9d,0x35,0xe3,0xa4,0xbd,0x82,0xa0,0x78,0xcd,0x70,0x77,0x21,0xd7,0x33,0x40,0x0e,},"\xb4\x8d\x9f\x84\x76\x2b\x3b\xcc\x66\xe9\x6d\x76\xa6\x16\xfa\x8f\xe8\xe0\x16\x95\x25\x1f\x47\xcf\xc1\xb7\xb1\x7d\x60\xdc\x9f\x90\xd5\x76\xef\x64\xee\x7d\x38\x85\x04\xe2\xc9\x07\x96\x38\x16\x5a\x88\x96\x96\x47\x1c\x98\x9a\x87\x6f\x8f\x13\xb6\x3b\x58\xd5\x31\xfe\xa4\xdd\x12\x29\xfc\x63\x16\x68\xa0\x47\xbf\xae\x2d\xa2\x81\xfe\xae\x1b\x6d\xe3\xeb\xe2\x80\xab\xe0\xa8\x2e\xe0\x0f\xbf\xdc\x22\xce\x2d\x10\xe0\x6a\x04\x92\xff\x14\x04\xdf\xc0\x94\xc4\x0b\x20\x3b\xf5\x57\x21\xdd\x78\x7e\xd4\xe9\x1d\x55\x17\xaa\xf5\x8d\x3b\xdd\x35\xd4\x4a\x65\xae\x6b\xa7\x56\x19\xb3\x39\xb6\x50\x51\x8c\xef\xcc\x17\x49\x3d\xe2\x7a\x3b\x5d\x41\x78\x8f\x87\xed\xbd\xe7\x26\x10\xf1\x81\xbf\x06\xe2\x08\xe0\xeb\x7c\xdf\xe8\x81\xd9\x1a\x2d\x6c\xc7\x7a\xa1\x9c\x0f\xcf\x33\x0f\xed\xb4\x46\x75\xd8\x00\xeb\x8c\xff\x95\x05\xd8\x88\x75\x44\xa5\x03\xcb\xe3\x73\xc4\x84\x7b\x19\xe8\xf3\x99\x57\x26\xef\xd6\x64\x98\x58\x59\x5c\x57\xcc\xaf\x0c\xbc\x9e\xb2\x5d\xe8\x3b\xa0\x46\xbc\x9f\x18\x38\xac\x7b\x89\x53\xdd\x81\xb8\x1a\xc0\xf6\x8d\x0e\x93\x38\xcb\x55\x40\x25\x52\xaf\xb6\xbc\x16\x94\x93\x51\xb9\x26\xd1\x51\xa8\x2e\xfc\x69\x5e\x8d\x7d\xa0\xdd\x55\x09\x93\x66\x78\x97\x18\xcc\xbf\x36\x03\x0b\xd2\xc3\xc1\x09\x39\x9b\xe2\x6c\xdb\x8b\x9e\x2a\x15\x5f\x3b\x2c\xb1\xbf\xa7\x1a\xb6\x9a\x23\x62\x5a\x4a\xc1\x18\xfe\x91\xcb\x2c\x19\x78\x8c\xf5\x2a\x71\xd7\x30\xd5\x76\xb4\x21\xd9\x69\x82\xa5\x1a\x29\x91\xda\xec\x44\x0c\xda\x7e\x6c\xc3\x28\x2b\x83\x12\x71\x42\x78\xb8\x19\xbf\xe2\x38\x7e\xb9\x6a\xa9\x1d\x40\x17\x30\x34\xf4\x28"}, +{{0xa1,0x03,0xe9,0x26,0x72,0xc6,0x5f,0x81,0xea,0x5d,0xa1,0xff,0xf1,0xa4,0x03,0x87,0x88,0x47,0x9e,0x94,0x1d,0x50,0x3a,0x75,0x6f,0x4a,0x75,0x52,0x01,0xa5,0x7c,0x1d,},{0xee,0x63,0xa5,0xb6,0x96,0x41,0x21,0x7a,0xcb,0xaf,0x33,0x39,0xda,0x82,0x9e,0xc0,0x71,0xb9,0x93,0x1e,0x59,0x87,0x15,0x35,0x14,0xd3,0x01,0x40,0x83,0x7a,0x7a,0xf4,},{0x2a,0xa2,0x03,0x5c,0x2c,0xe5,0xb5,0xe6,0xae,0x16,0x1e,0x16,0x8f,0x3a,0xd0,0xd6,0x59,0x2b,0xcf,0x2c,0x4a,0x04,0x9d,0x3e,0xd3,0x42,0xfc,0xeb,0x56,0xbe,0x9c,0x7c,0xb3,0x72,0x02,0x75,0x73,0xae,0x01,0x78,0xe8,0x87,0x8e,0xbe,0xfc,0xa7,0xb0,0x30,0x32,0x7b,0x8a,0xad,0x41,0x85,0x7d,0xe5,0x8c,0xb7,0x8e,0x1a,0x00,0xcb,0xac,0x05,},"\xb1\x98\x4e\x9e\xec\x08\x5d\x52\x4c\x1e\xb3\xb9\x5c\x89\xc8\x4a\xe0\x85\xbe\x5d\xc6\x5c\x32\x6e\x19\x02\x5e\x12\x10\xa1\xd5\x0e\xdb\xbb\xa5\xd1\x37\x0c\xf1\x5d\x68\xd6\x87\xeb\x11\x32\x33\xe0\xfb\xa5\x0f\x94\x33\xc7\xd3\x58\x77\x39\x50\xc6\x79\x31\xdb\x82\x96\xbb\xcb\xec\xec\x88\x8e\x87\xe7\x1a\x2f\x75\x79\xfa\xd2\xfa\x16\x2b\x85\xfb\x97\x47\x3c\x45\x6b\x9a\x5c\xe2\x95\x66\x76\x96\x9c\x7b\xf4\xc4\x56\x79\x08\x5b\x62\xf2\xc2\x24\xfc\x7f\x45\x87\x94\x27\x3f\x6d\x12\xc5\xf3\xe0\xd0\x69\x51\x82\x4d\x1c\xca\x3e\x2f\x90\x45\x59\xed\x28\xe2\x86\x8b\x36\x6d\x79\xd9\x4d\xc9\x86\x67\xb9\xb5\x92\x42\x68\xf3\xe3\x9b\x12\x91\xe5\xab\xe4\xa7\x58\xf7\x70\x19\xda\xcb\xb2\x2b\xd8\x19\x6e\x0a\x83\xa5\x67\x76\x58\x83\x6e\x96\xca\x56\x35\x05\x5a\x1e\x63\xd6\x5d\x03\x6a\x68\xd8\x7a\xc2\xfd\x28\x3f\xdd\xa3\x90\x31\x99\x09\xc5\xcc\x76\x80\x36\x88\x48\x87\x3d\x59\x7f\x29\x8e\x0c\x61\x72\x30\x80\x30\xff\xd4\x52\xbb\x13\x63\x61\x7b\x31\x6e\xd7\xcd\x94\x9a\x16\x5d\xc8\xab\xb5\x3f\x99\x1a\xef\x3f\x3e\x95\x02\xc5\xdf\xe4\x75\x6b\x7c\x6b\xfd\xfe\x89\xf5\xe0\x0f\xeb\xdd\x6a\xfb\x04\x02\x81\x8f\x11\xcf\x8d\x1d\x58\x64\xfe\x9d\xa1\xb8\x6e\x39\xaa\x93\x58\x31\x50\x6c\xf2\x40\x0e\xa7\xed\x75\xbd\x95\x33\xb2\x3e\x20\x2f\xe8\x75\xd7\xd9\x63\x8c\x89\xd1\x1c\xb2\xd6\xe6\x02\x1a\xe6\xbd\x27\xc7\x75\x48\x10\xd3\x5c\xd3\xa6\x14\x94\xf2\x7b\x16\xfc\x79\x4e\x2c\xd2\xf0\xd3\x45\x3a\xda\x93\x38\x65\xdb\x78\xc5\x79\x57\x1f\x8f\xc5\xc5\xc6\xbe\x8e\xaf\xfc\xe6\xa8\x52\xe5\xb3\xb1\xc5\x24\xc4\x93\x13\xd4\x27\xab\xcb"}, +{{0xd4,0x7c,0x1b,0x4b,0x9e,0x50,0xcb,0xb7,0x1f,0xd0,0x7d,0x09,0x6d,0x91,0xd8,0x72,0x13,0xd4,0x4b,0x02,0x43,0x73,0x04,0x47,0x61,0xc4,0x82,0x2f,0x9d,0x9d,0xf8,0x80,},{0xf4,0xe1,0xcb,0x86,0xc8,0xca,0x2c,0xfe,0xe4,0x3e,0x58,0x59,0x4a,0x87,0x78,0x43,0x6d,0x3e,0xa5,0x19,0x70,0x4e,0x00,0xc1,0xbb,0xe4,0x8b,0xbb,0x1c,0x94,0x54,0xf8,},{0x62,0x7e,0x7c,0xa7,0xe3,0x4e,0xd6,0x33,0x1d,0x62,0xb9,0x54,0x1c,0x1e,0xa9,0xa9,0x29,0x2b,0xe7,0xb0,0xa6,0x5d,0x80,0x5e,0x26,0x6b,0x51,0x22,0x27,0x2a,0x82,0xdb,0x7d,0x76,0x5a,0xcc,0x7e,0x2a,0x29,0x0d,0x68,0x58,0x04,0x92,0x2f,0x91,0xed,0x04,0xa3,0xc3,0x82,0xc0,0x3f,0xf2,0x1a,0x17,0x68,0xf5,0x84,0x41,0x3c,0x4e,0x5f,0x00,},"\x88\xd7\x00\x9d\x51\xde\x3d\x33\x7e\xef\x0f\x21\x5e\xa6\x6a\xb8\x30\xec\x5a\x9e\x68\x23\x76\x1c\x3b\x92\xad\x93\xea\x34\x1d\xb9\x2e\xce\x67\xf4\xef\x4c\xeb\x84\x19\x4a\xe6\x92\x6c\x3d\x01\x4b\x2d\x59\x78\x1f\x02\xe0\xb3\x2f\x9a\x61\x12\x22\xcb\x9a\x58\x50\xc6\x95\x7c\xb8\x07\x9a\xe6\x4e\x08\x32\xa1\xf0\x5e\x5d\x1a\x3c\x57\x2f\x9d\x08\xf1\x43\x7f\x76\xbb\x3b\x83\xb5\x29\x67\xc3\xd4\x8c\x35\x76\x84\x88\x91\xc9\x65\x8d\x49\x59\xeb\x80\x65\x6d\x26\xcd\xba\x08\x10\x03\x7c\x8a\x18\x31\x8f\xf1\x22\xf8\xaa\x89\x85\xc7\x73\xcb\x31\x7e\xfa\x2f\x55\x7f\x1c\x38\x96\xbc\xb1\x62\xdf\x5d\x87\x68\x1b\xb7\x87\xe7\x81\x3a\xa2\xde\xa3\xb0\xc5\x64\xd6\x46\xa9\x28\x61\xf4\x44\xca\x14\x07\xef\xba\xc3\xd1\x24\x32\xcb\xb7\x0a\x1d\x0e\xaf\xfb\x11\x74\x1d\x37\x18\xfe\xde\xe2\xb8\x30\x36\x18\x9a\x6f\xc4\x5a\x52\xf7\x4f\xa4\x87\xc1\x8f\xd2\x64\xa7\x94\x5f\x6c\x9e\x44\xb0\x11\xf5\xd8\x66\x13\xf1\x93\x9b\x19\xf4\xf4\xfd\xf5\x32\x34\x05\x7b\xe3\xf0\x05\xad\x64\xee\xbf\x3c\x8f\xfb\x58\xcb\x40\x95\x6c\x43\x36\xdf\x01\xd4\x42\x4b\x70\x6a\x0e\x56\x1d\x60\x17\x08\xd1\x24\x85\xe2\x1b\xcb\x6d\x79\x9d\x8d\x1d\x04\x4b\x40\x00\x64\xec\x09\x44\x50\x14\x06\xe7\x02\x53\x94\x70\x06\xca\xbb\xdb\x2d\xd6\xbd\x8c\xee\x44\x97\x65\x3d\x91\x13\xa4\x4d\x4d\xe9\xb6\x8d\x4c\x52\x6f\xca\x0b\x9b\x0c\x18\xfe\x50\xfb\x91\x7f\xdd\x9a\x91\x4f\xb8\x16\x10\x8a\x73\xa6\xb3\xff\xf9\xe6\x54\xe6\x9c\x9c\xfe\x02\xb0\x5c\x6c\x1b\x9d\x15\xc4\xe6\x5c\xf3\x10\x18\xb8\x10\x0d\x78\x46\x33\xee\x18\x88\xee\xe3\x57\x2a\xaf\xa6\xf1\x89\xea\x22\xd0"}, +{{0xfc,0x0c,0x32,0xc5,0xeb,0x6c,0x71,0xea,0x08,0xdc,0x2b,0x30,0x0c,0xbc,0xef,0x18,0xfd,0xde,0x3e,0xa2,0x0f,0x68,0xf2,0x17,0x33,0x23,0x7b,0x4d,0xda,0xab,0x90,0x0e,},{0x47,0xc3,0x7d,0x8a,0x08,0x08,0x57,0xeb,0x87,0x77,0xa6,0xc0,0xa9,0xa5,0xc9,0x27,0x30,0x3f,0xaf,0x5c,0x32,0x09,0x53,0xb5,0xde,0x48,0xe4,0x62,0xe1,0x2d,0x00,0x62,},{0x68,0x87,0xc6,0xe2,0xb9,0x8a,0x82,0xaf,0x5e,0xe3,0xdf,0xa7,0xca,0x2c,0xb2,0x5d,0x9c,0x10,0x74,0x56,0x20,0xa8,0x29,0x56,0xac,0xba,0x85,0xcb,0x57,0xc8,0xec,0x24,0x27,0x9f,0xa4,0x2f,0x09,0x23,0x59,0xa1,0xb6,0xbb,0xea,0xfb,0xa0,0x50,0xf1,0x4b,0x62,0x88,0x20,0x9e,0x6e,0xf7,0xbc,0x1e,0x0a,0x2b,0x87,0x2c,0x11,0x38,0xf3,0x05,},"\xa7\xb1\xe2\xdb\x6b\xdd\x96\xb3\xd5\x14\x75\x60\x35\x37\xa7\x6b\x42\xb0\x4d\x7e\xbd\x24\xfe\x51\x5a\x88\x76\x58\xe4\xa3\x52\xe2\x21\x09\x33\x56\x39\xa5\x9e\x25\x34\x81\x1f\x47\x53\xb7\x02\x09\xd0\xe4\x69\x8e\x9d\x92\x60\x88\x82\x6c\x14\x68\x96\x81\xea\x00\xfa\x3a\x2f\xca\xa0\x04\x7c\xed\x3e\xf2\x87\xe6\x17\x25\x02\xb2\x15\xe5\x64\x97\x61\x4d\x86\xb4\xcb\x26\xbc\xd7\x7a\x2e\x17\x25\x09\x36\x0e\xe5\x88\x93\xd0\x1c\x0d\x0f\xb4\xd4\xab\xfe\x4d\xbd\x8d\x2a\x2f\x54\x19\x0f\xa2\xf7\x31\xc1\xce\xac\x68\x29\xc3\xdd\xc9\xbf\xb2\xff\xd7\x0c\x57\xba\x0c\x2b\x22\xd2\x32\x6f\xbf\xe7\x39\x0d\xb8\x80\x9f\x73\x54\x7f\xf4\x7b\x86\xc3\x6f\x2b\xf7\x45\x4e\x67\x8c\x4f\x1c\x0f\xa8\x70\xbd\x0e\x30\xbb\xf3\x27\x8e\xc8\xd0\xc5\xe9\xb6\x4a\xff\x0a\xf6\x4b\xab\xc1\x9b\x70\xf4\xcf\x9a\x41\xcb\x8f\x95\xd3\xcd\xe2\x4f\x45\x6b\xa3\x57\x1c\x8f\x02\x1d\x38\xe5\x91\xde\xc0\x5c\xb5\xd1\xca\x7b\x48\xf9\xda\x4b\xd7\x34\xb0\x69\xa9\xfd\x10\x65\x00\xc1\xf4\x08\xab\x7f\xe8\xe4\xa6\xe6\xf3\xed\x64\xda\x0e\xd2\x4b\x01\xe3\x3d\xf8\x47\x5f\x95\xfa\x9e\xd7\x1d\x04\xdd\x30\xb3\xcd\x82\x37\x55\xa3\x40\x1b\xf5\xaf\xae\x10\xee\x7e\x18\xec\x6f\xe6\x37\xc3\x79\x3f\xd4\x34\xb4\x8d\x71\x45\x13\x04\x47\xe0\x02\x99\x10\x10\x52\x55\x8b\x50\x65\x54\xec\x9c\x39\x9f\x62\x94\x1c\x3f\x41\x4c\xbc\x35\x2c\xaa\x34\x5b\x93\x0a\xde\xcf\xad\xda\xc9\x1e\xe5\x3d\x14\x51\xa6\x5e\x06\x20\x10\x26\x32\x5d\xe0\x7c\x93\x1f\x69\xbb\xa8\x68\xa7\xc8\x7e\xe2\x3c\x60\x4e\xc6\x79\x43\x32\x91\x7d\xfe\x2c\x5b\x69\x66\x9b\x65\x97\x06\x91\x7f\x71\xed\xdf\x96"}, +{{0xa8,0xd7,0x3d,0x63,0x9a,0x23,0xcc,0x6a,0x96,0x7e,0xf3,0x1b,0xca,0xbb,0x5d,0x06,0x3e,0x53,0xe1,0xea,0xb8,0xfc,0xc7,0xca,0xb9,0xbc,0x3a,0x17,0xfd,0xe9,0xc2,0xf8,},{0x8d,0xaa,0x9f,0x4c,0x8b,0x1a,0x44,0x69,0x1b,0xf4,0x45,0x21,0xf2,0xf7,0xca,0x45,0xdc,0x7f,0xc6,0x1f,0x6a,0x4c,0xe6,0xf9,0x8f,0xaa,0x41,0xc2,0xa7,0x49,0x77,0xd1,},{0xc4,0xdc,0xef,0x1a,0x24,0x53,0x93,0x9b,0x36,0x4b,0x34,0x02,0x50,0xc3,0x12,0x94,0x31,0x43,0x1d,0x5b,0xa3,0xf4,0x76,0x70,0xab,0x07,0xce,0x68,0x0c,0x69,0xbf,0x28,0xb6,0x78,0x62,0x7c,0x76,0xa6,0x36,0x0f,0xc4,0x0d,0xc1,0x09,0xaa,0x7d,0xea,0x37,0x1b,0x82,0x5e,0x46,0x13,0x4f,0x62,0x45,0x72,0x18,0x2a,0xcf,0x39,0x57,0xe7,0x0f,},"\xfd\x1f\xac\x3d\x53\x31\x3b\x11\xac\xd2\x9f\x5a\x83\xac\x11\x89\x6d\xab\x25\x30\xfa\x47\x86\x5b\x22\x95\xc0\xd9\x9d\xd6\x7c\x36\xed\x8e\x5f\xa5\x49\x15\x0c\x79\x4c\x55\x49\xef\xb5\xc1\xd6\x91\x14\xd5\xd6\x07\xb2\x32\x85\xb7\x21\x2a\xfa\xab\x57\x84\x6a\x54\xae\x67\xb9\xe8\x80\xe0\x7b\x65\x86\x60\x7c\xec\xf6\xd4\xee\xd5\x16\xa3\xa7\x55\x11\xfe\x36\x7d\x88\xeb\x87\x1e\x6d\x71\xb7\xd6\xaa\x13\x67\xa0\x14\x21\xb1\x08\x8f\xc2\xd7\x5e\x44\x95\x4b\x73\x62\x5c\x52\xda\x8a\x3a\x18\x3c\x60\xbe\x9d\xa6\x05\x0f\x59\xa4\x53\xca\xa5\x35\x20\x59\x36\x71\x72\x8d\x43\x18\x77\xbf\xaa\xc9\x13\xa7\x65\xfb\x6a\x56\xb7\x52\x90\xb2\xa8\xaa\xac\x34\xaf\xb9\x21\x7b\xa1\xb0\xd5\x85\x0b\xa0\xfd\xab\xf8\x09\x69\xde\xf0\xfe\xee\x79\x4c\xeb\x60\x61\x4e\x33\x68\xe6\x3e\xf2\x0e\x4c\x32\xd3\x41\xec\x9b\x03\x28\xea\x9f\xe1\x39\x20\x7e\xd7\xa6\x26\xff\x08\x94\x3b\x41\x52\x33\xdb\x7c\xfc\xc8\x45\xc9\xb6\x31\x21\xd4\xed\x52\xec\x37\x48\xab\x6a\x1f\x36\xb2\x10\x3c\x7d\xc7\xe9\x30\x3a\xce\xa4\xba\x8a\xf7\xa3\xe0\x71\x84\xfb\x49\x1e\x89\x1e\xde\x84\xf0\xdc\x41\xca\xdc\x39\x73\x02\x8e\x87\x9a\xcd\x20\x31\xaf\xc2\x9a\x16\x09\x28\x68\xe2\xc7\xf5\x39\xfc\x1b\x79\x2e\xda\xb1\x95\xa2\x5a\xb9\x83\x06\x61\x34\x6b\x39\xef\x53\x91\x5d\xe4\xaf\x52\xc4\x21\xea\xf1\x72\xe9\xda\x76\xa0\x8c\x28\x3a\x52\xdf\x90\x7f\x70\x5d\x7e\x85\x99\xc5\xba\xae\x0c\x2a\xf3\x80\xc1\xbb\x46\xf9\x34\x84\xa0\x3f\x28\x37\x43\x24\xb2\x78\x99\x2b\x50\xb7\xaf\xa0\x25\x52\xca\xfa\x50\x3f\x03\x4f\x8d\x86\x6e\x9b\x72\x02\x71\xdd\x68\xcc\xb6\x85\xa8\x5f\xff\xd1"}, +{{0x79,0xc7,0xdc,0xb7,0xd5,0x9a,0x8d,0xf6,0xb2,0xb2,0xba,0x04,0x13,0x05,0x9d,0x89,0x68,0x09,0x95,0xc2,0x0e,0x91,0x6d,0xa0,0x1b,0x8f,0x06,0x7d,0xc6,0x0c,0xde,0xb4,},{0x29,0x87,0x43,0xc7,0x39,0x18,0xbd,0x55,0x6b,0x28,0xf8,0xd4,0x82,0x4a,0x09,0xb8,0x14,0x75,0x2a,0x7a,0xea,0xe7,0xee,0x04,0x87,0x5c,0x53,0xf4,0xd6,0xb1,0x08,0xd9,},{0x7b,0x7c,0xbe,0x44,0xc7,0x71,0xe4,0x37,0x1b,0xae,0x13,0xb0,0x72,0x2b,0xab,0xcc,0x10,0x64,0x15,0x57,0x32,0x96,0x2f,0x40,0x7c,0xba,0x2a,0xcd,0x35,0x38,0x1d,0x42,0x21,0x0b,0xec,0xe8,0x22,0xf4,0x68,0x11,0x21,0xfd,0x4d,0xab,0x74,0x5a,0x1f,0x30,0x77,0x92,0x2f,0xba,0x1a,0x78,0x04,0x5b,0x71,0x29,0x02,0xba,0xcc,0xac,0x66,0x0e,},"\x5f\xe2\x02\xf5\xb3\x3b\x77\x88\x81\x0d\x25\x08\xa1\x3b\x31\x14\xd6\x9b\x85\x96\xe6\xea\xcd\xa0\x5a\x04\xa2\xeb\x59\x7f\xa3\x27\x9c\x20\x8b\x5a\x5b\x65\xda\xac\xb6\x99\xf1\x44\xe1\xd6\x60\xe7\x8e\x13\x9b\x57\x83\x31\xab\xec\x5c\x3c\x35\x33\x44\x54\xf0\x3e\x83\x2c\x8d\x6e\x29\x84\xdf\x5d\x45\x0e\xcb\x5d\x33\x58\x2a\x78\x80\x8a\x9c\x78\xf2\x6e\xbc\xd1\x24\x4e\xf5\x2e\x3f\xa6\xdc\xa1\x15\xc1\xf0\xcb\x56\xe3\x8e\xae\x0e\x5b\x39\xf5\xfd\x86\x3d\xff\xd0\xb2\xfb\x5b\x95\x8f\x2d\x73\x9d\xb3\x12\xfc\x66\x7a\x17\xb0\x31\xc4\xc9\xf8\xc5\xa2\xad\x57\x79\x84\xcc\x41\x46\xc4\x37\x58\x0e\xfd\x21\x52\x17\x3f\xe0\xd5\x78\x2c\xc2\xae\x98\x31\xa8\xd9\xa0\x41\x77\x25\x60\x18\xff\x76\x31\xe0\xb0\xd8\xa9\x9c\xb2\x8f\x00\x8b\x32\x04\x21\xe2\x7a\x74\xc3\x13\x59\x18\x86\x63\x45\x6d\x85\xe0\x98\xc1\xeb\xd2\x81\x70\x10\x97\xb6\xae\x5a\x87\x1e\x5c\xcc\x02\x05\x8a\x50\x14\x16\xcb\x91\xc1\x2c\xef\x5b\xe6\xf1\x91\x43\x70\xe5\x63\xf1\xa1\xb2\xaa\x41\xf4\xb8\xee\x84\xcd\x32\xa1\xd5\x09\xe5\x29\x78\x7d\x14\xa4\x45\x43\x8d\x80\x7e\xcd\x62\x0e\x2f\xa2\x6d\xe0\xda\x64\x26\x86\x47\x84\xd4\xa2\x8f\x54\x10\x3e\x60\x92\x83\xb9\x9e\xe9\xb2\xb6\x99\xc9\x80\xbb\xb7\x88\x2c\x3e\xa6\x8d\xdc\x90\x80\x2a\xc2\x32\xf2\xc8\xe8\x42\x91\x98\x7b\xf3\xc5\x24\x09\x21\xb5\x9c\xfa\x21\x49\x69\x31\x76\x73\xd0\xbe\x7f\x34\xb1\xca\x0e\x15\xea\x73\xc7\x17\x54\x01\xce\x55\x0b\xe1\x06\xb4\x9e\x62\xf8\xdb\x68\x69\x5e\x74\x0e\x0f\x3a\x35\x56\xa1\x9f\x3c\x8e\x6b\x91\xac\x1c\xc2\x3e\x86\x3f\xcd\x0f\x0d\x9e\xb7\x04\x7a\xa6\x31\xe0\xd2\xeb\x9b\xcc\x6b"}, +{{0xb9,0xce,0xd0,0x41,0x25,0x93,0xfe,0xfe,0xd9,0x5e,0x94,0xac,0x96,0x5e,0x5b,0x23,0xff,0x9d,0x4b,0x0e,0x79,0x7d,0xb0,0x2b,0xf4,0x97,0x99,0x4d,0x3b,0x79,0x3e,0x60,},{0xc1,0x62,0x9a,0x72,0x31,0x89,0x95,0x93,0x37,0xf5,0x53,0x52,0x01,0xe5,0xd3,0x95,0xba,0x0a,0x03,0xea,0x8c,0x17,0x66,0x0d,0x0f,0x8b,0x6f,0x6e,0x64,0x04,0xbb,0x12,},{0xf1,0xb7,0x97,0xde,0xd8,0xa6,0x94,0x2b,0x12,0x62,0x68,0x48,0x34,0x0f,0xb7,0x19,0xfc,0xdd,0xaf,0xd9,0x8f,0x33,0xe2,0x99,0x2d,0x35,0x7b,0xfd,0xd3,0x59,0x33,0xc7,0xac,0x56,0x1e,0x5b,0x2f,0x93,0x94,0x64,0x33,0x8c,0x56,0x66,0x85,0x4c,0xa8,0x85,0xc4,0xd0,0x46,0xeb,0x2c,0x54,0xe4,0x8a,0x1b,0x5e,0xd2,0x66,0xad,0x34,0xde,0x05,},"\x55\x5b\xb3\x9c\x18\x99\xd5\x7c\xab\xe4\x28\x06\x4c\x2d\x92\x5f\x5f\xc4\xcf\x70\x59\xb9\x5f\xb8\x9a\x8e\x9e\x3a\x7e\x42\x6c\x6c\x92\x2d\x9e\x4d\x76\x98\x4e\xa2\x38\x3c\xab\xb4\xf2\xbe\xfd\x89\xc1\xf2\x0e\xaa\x8a\x00\xdb\xe7\x87\xcf\xa7\x0a\xe2\xae\x6a\xa9\x03\x31\xcb\xbe\x58\x0f\xa5\xa0\x21\x84\xed\x05\xe6\xc8\xe8\x9d\x57\x6a\xf2\x8a\xee\xaf\x7c\x4e\x25\x00\xf3\x58\xa0\x09\x71\xa0\xa7\x59\x20\xe8\x54\x84\x9b\xf3\x32\x14\x29\x75\x40\x4f\x59\x8c\x32\xe9\x69\x82\x04\x3d\x99\x2b\xcd\x1a\x4f\xe8\x19\xbb\x56\x34\xad\x03\x46\x7a\xfc\x4c\xe0\x50\x73\xf8\x8b\xa1\xba\x4a\xe8\x65\x3a\x04\x66\x5c\xf3\xf7\x16\x90\xfe\x13\x34\x38\x85\xbc\x5e\xbc\x0e\x5e\x62\xd8\x82\xf4\x3b\x7c\x68\x90\x0a\xc9\x43\x8b\xf4\xa8\x1c\xe9\x01\x69\xec\x12\x9e\xe6\x3e\x2c\x67\x5a\x1a\x5a\x67\xe2\x7c\xc7\x98\xc4\x8c\xc2\x3f\x51\x07\x8f\x46\x3b\x3b\x7c\xc1\x4e\x3b\xcf\xd2\xe9\xb8\x2c\x75\x24\x09\x34\xcb\xdc\x50\xc4\x30\x8f\x28\x2f\x19\x31\x22\x99\x56\x06\xf4\x01\x35\x10\x0a\x29\x1c\x55\xaf\xdf\x89\x34\xeb\x8b\x61\xd8\x14\x21\x67\x41\x24\xde\xc3\xb8\x8f\x9a\x73\x11\x0a\x9e\x61\x6f\x5b\x82\x6b\x9d\x34\x3f\x3a\xc0\xe9\xd7\xbd\xf4\xfd\x8b\x64\x8b\x40\xf0\x09\x8b\x38\x97\xa3\xa1\xcd\x65\xa6\x45\x70\x05\x9b\x8b\xc5\xc6\x74\x38\x83\x07\x4c\x88\x62\x3c\x1f\x5a\x88\xc5\x89\x69\xe2\x1c\x69\x2a\xca\x23\x68\x33\xd3\x47\x0b\x3e\xb0\x98\x15\xe1\x13\x8e\x9d\x06\x50\xc3\x90\xee\xe9\x77\x42\x21\x93\xb0\x09\x18\xbe\x8a\x97\xcc\x61\x99\xb4\x51\xb0\x5b\x57\x30\xd1\xd1\x33\x58\xcf\x74\x61\x06\x78\xf7\xac\x7f\x78\x95\xcc\x2e\xfc\x45\x6e\x03\x87\x3b"}, +{{0x81,0xda,0x16,0x8f,0x02,0xd4,0x6b,0xb8,0x7c,0xda,0x84,0x5d,0xa4,0x3f,0x8a,0x6c,0xba,0x2c,0x01,0x68,0x78,0xd6,0xf4,0x9c,0x6f,0x06,0x1a,0x60,0xf1,0x55,0xa0,0x4a,},{0xaf,0xf8,0x6e,0x98,0x09,0x3c,0xa4,0xc7,0x1b,0x1b,0x80,0x4c,0x5f,0xe4,0x51,0xcf,0xdf,0x86,0x82,0x50,0xde,0xa3,0x03,0x45,0xfa,0x4b,0x89,0xbb,0x09,0xb6,0xa5,0x3b,},{0x4a,0xac,0xa9,0x47,0xe3,0xf2,0x2c,0xc8,0xb8,0x58,0x8e,0xe0,0x30,0xac,0xe8,0xf6,0xb5,0xf5,0x71,0x1c,0x29,0x74,0xf2,0x0c,0xc1,0x8c,0x3b,0x65,0x5b,0x07,0xa5,0xbc,0x13,0x66,0xb5,0x9a,0x17,0x08,0x03,0x2d,0x12,0xca,0xe0,0x1a,0xb7,0x94,0xf8,0xcb,0xcc,0x1a,0x33,0x08,0x74,0xa7,0x50,0x35,0xdb,0x1d,0x69,0x42,0x2d,0x2f,0xc0,0x0c,},"\x6b\xc6\x72\x6a\x34\xa6\x4a\xae\x76\xab\x08\xc9\x2b\x17\x9e\x54\xff\x5d\x2e\x65\xeb\x2c\x6c\x65\x9a\xe8\x70\x3c\xc2\x45\xcb\xc2\xcf\x45\xa1\x2b\x22\xc4\x68\xae\x61\xfd\x9a\x66\x27\xad\x06\x26\xc9\xb1\xe5\xaf\x41\x2c\xb4\x83\xea\xee\x1d\xb1\x1b\x29\xf0\xa5\x10\xc1\x3e\x38\x02\x0e\x09\xae\x0e\xee\x76\x25\x37\xa3\xe9\xd1\xa0\xc7\xb0\x33\xd0\x97\xfd\xc1\xf4\xf8\x26\x29\xa9\xde\x9e\xf3\x8d\xa1\xcf\x96\xa9\x40\x35\x7d\x5f\x2e\x0e\x7e\x8d\xbc\x29\xdb\x72\x8a\x1e\x6a\xad\x87\x6e\x5e\x05\x31\x13\xd0\x64\x20\x27\x2b\x87\xcf\x0c\x40\xdf\xe0\x3a\x54\x4d\xe9\x6c\x7a\xea\x13\xba\x00\x29\xb5\x7b\x48\xd9\x9d\xcc\x6a\x65\x04\x92\xd7\x8c\x4c\xdd\x1b\x28\xe1\xa1\x15\xa7\xe3\xe7\xa7\xcb\x21\x33\x3d\x4f\xf8\x08\x58\xdf\xb6\x77\x82\xc1\x63\x54\xb8\x71\x65\x96\x56\x0d\x7d\x8e\x38\x9e\xb1\x5a\x05\x2a\x0b\xf5\xd1\x6e\xb5\x4f\xb3\xe4\x97\x3a\xd4\x98\x4e\x72\xa1\x87\xf5\x34\x7d\x5b\x26\x2c\x32\xb1\x64\x7e\x42\xb6\xa5\x38\x37\x09\x6c\xc7\x8c\x2a\x05\xce\x1c\x6e\x12\x49\x3a\x03\xf1\xa6\x67\x58\x4c\xb9\x7f\x4f\xcd\x57\xee\x94\x4c\x65\xb7\xee\xd2\x5f\x7a\xe0\xf3\xf6\xce\xde\x17\x3f\xdf\xac\xf5\xaf\x1d\xb1\x43\x73\x0d\x18\x09\x66\x64\x91\x4b\xa4\xcf\xc6\x96\x6f\x39\x20\x22\x78\x1c\x66\xa9\x41\x7c\xa2\x68\x0b\x51\xf6\x3e\x4f\xba\x42\x4e\xcf\xdb\xc6\xa2\xf0\x17\x87\xd0\xe7\x48\x4f\x8a\x8a\xb3\x90\xae\xaa\x6d\x1f\x7e\xd3\x25\xd8\x2f\xea\xa1\x69\x2a\x49\x84\xfa\xe4\x3d\xa8\x73\x29\xb0\x45\xda\x8f\x0a\x4f\x56\xb6\x95\xaa\x93\x5d\xe1\x52\xce\x03\x85\x15\x37\x20\x97\x9a\x2b\x70\x06\xd4\x05\xfc\xb0\xfb\xa0\x9e\x23\xb8\x5f\xd1\x9b"}, +{{0xaf,0x2e,0x60,0xda,0x0f,0x29,0xbb,0x16,0x14,0xfc,0x3f,0x19,0x3c,0xc3,0x53,0x33,0x19,0x86,0xb7,0x3f,0x3f,0x9a,0x0a,0xec,0x94,0x21,0xb9,0x47,0x3d,0x6a,0x4b,0x6a,},{0xc8,0xbf,0xe2,0x83,0x58,0x22,0x19,0x9c,0x61,0x27,0xb8,0x06,0xfa,0xbe,0xef,0x0c,0xb9,0xff,0x59,0xf3,0xc8,0x1f,0xf0,0xcb,0x89,0xc5,0x56,0xf5,0x51,0x06,0xaf,0x6a,},{0x50,0xf9,0xf9,0x41,0xa8,0xda,0x9f,0x62,0x40,0xf7,0x6d,0x2f,0xa3,0xb0,0x6d,0xd6,0xb2,0x29,0x2e,0xd3,0x2d,0x1c,0x05,0x21,0x80,0x97,0xd3,0x4d,0x8a,0x19,0xdf,0xe5,0x53,0xf7,0x6a,0xe3,0xc6,0xb4,0xa2,0xed,0x20,0x85,0x21,0x28,0x46,0x15,0x40,0xde,0xcf,0x41,0x8f,0x52,0xd3,0x8e,0x64,0x03,0x7e,0xec,0x77,0x71,0xbd,0x1a,0xfe,0x00,},"\x7d\xbb\x77\xb8\x8b\xda\x94\xf3\x44\x41\x6a\x06\xb0\x96\x56\x6c\x6e\x8b\x39\x39\x31\xa8\x24\x3a\x6c\xab\x75\xc3\x61\xfd\xe7\xdc\x53\x6a\xec\x40\xcd\xed\x83\x29\x6a\x89\xe8\xc3\xbe\xf7\xd7\x87\xcf\xc4\x94\x01\xa7\xb9\x18\x3f\x13\x8d\x50\x00\x61\x9f\xf0\x73\xc0\x5e\x2f\x84\x1d\x60\x08\x35\x8f\x10\xa2\xda\x7d\xcf\xac\x3d\x4d\x70\xc2\x0d\x2e\xc3\x4c\x7b\x6d\x5c\xd1\xa7\x34\xd6\xbb\xb1\x1c\x5f\xd8\xd2\xbc\xe3\x2a\xc8\x10\xef\x82\xb4\x18\x8a\xa8\xea\x3c\xfc\x30\x32\x23\x3d\xc0\xe2\x60\x0e\x9d\xb6\xe1\x8b\xc2\x2b\x10\x04\x4a\x31\xc1\x5b\xac\xea\xf5\x55\x4d\xe8\x9d\x2a\x34\x66\x80\x7f\x24\x44\x14\xd0\x80\xff\x29\x63\x95\x6c\x6e\x83\xc8\xe1\x44\xed\x00\x66\x08\x8b\x47\x6d\xdc\xb5\x64\x40\x34\x47\xd9\x15\x9f\x90\x89\xab\xa2\xb4\xd5\x57\x5c\x4d\x8a\xe6\x6f\xc8\x69\x0e\x73\x49\xed\x40\x83\x2e\x63\x69\xc0\x24\x56\x3e\xc4\x93\xbf\xcc\x0f\xc9\xac\x78\x7a\xc8\x41\x39\x7f\xe1\x33\x16\x72\x83\xd8\x0c\x42\xf0\x06\xa9\x9d\x39\xe8\x29\x79\xda\x3f\xa9\x33\x4b\xd9\xed\xe0\xd1\x4b\x41\xb7\x46\x6b\xce\xbb\xe8\x17\x1b\xc8\x04\xa6\x45\xd3\x72\x32\x74\xa1\xb9\x2b\xf8\x2f\xd9\x93\x35\x87\x44\xde\x92\x44\x19\x03\xd4\x36\xfd\x47\xf2\x3d\x40\x05\x2a\x38\x29\x36\x7f\x20\x2f\x05\x53\xb5\xe4\x9b\x76\xc5\xe0\x3f\xa6\xce\x7c\x3c\xf5\xee\xb2\x1d\xe9\x67\xbe\xc4\xdd\x35\x59\x25\x38\x4e\xbf\x96\x69\x7e\x82\x37\x62\xba\xc4\xd4\x3a\x76\x7c\x24\x1a\x4c\xef\x72\x4a\x97\x0d\x00\xff\x3a\x8a\xb3\xb8\x3e\xed\x84\x00\x75\xc7\x4e\x90\xf3\x06\xe3\x30\x01\x32\x60\x96\x21\x61\xe9\xd0\x91\x0d\xe1\x83\x62\x2c\xe9\xa6\xb8\xd5\x14\x42\x80\x55\x0f\xc7"}, +{{0x60,0x5f,0x90,0xb5,0x3d,0x8e,0x4a,0x3b,0x48,0xb9,0x7d,0x74,0x54,0x39,0xf2,0xa0,0x80,0x7d,0x83,0xb8,0x50,0x2e,0x8e,0x29,0x79,0xf0,0x3e,0x8d,0x37,0x6a,0xc9,0xfe,},{0xaa,0x3f,0xae,0x4c,0xfa,0x6f,0x6b,0xfd,0x14,0xba,0x0a,0xfa,0x36,0xdc,0xb1,0xa2,0x65,0x6f,0x36,0x54,0x1a,0xd6,0xb3,0xe6,0x7f,0x17,0x94,0xb0,0x63,0x60,0xa6,0x2f,},{0xdd,0x02,0x12,0xe6,0x32,0x88,0xcb,0xe1,0x4a,0x45,0x69,0xb4,0xd8,0x91,0xda,0x3c,0x7f,0x92,0x72,0x7c,0x5e,0x7f,0x9a,0x80,0x1c,0xf9,0xd6,0x82,0x70,0x85,0xe7,0x09,0x5b,0x66,0x9d,0x7d,0x45,0xf8,0x82,0xca,0x5f,0x07,0x45,0xdc,0xcd,0x24,0xd8,0x7a,0x57,0x18,0x13,0x20,0x19,0x1e,0x5b,0x7a,0x47,0xc3,0xf7,0xf2,0xdc,0xcb,0xd7,0x07,},"\x3b\xcd\xca\xc2\x92\xac\x95\x19\x02\x4a\xae\xce\xe2\xb3\xe9\x99\xff\x5d\x34\x45\xe9\xf1\xeb\x60\x94\x0f\x06\xb9\x12\x75\xb6\xc5\xdb\x27\x22\xed\x4d\x82\xfe\x89\x60\x52\x26\x53\x0f\x3e\x6b\x07\x37\xb3\x08\xcd\xe8\x95\x61\x84\x94\x4f\x38\x8a\x80\x04\x2f\x6c\xba\x27\x4c\x0f\x7d\x11\x92\xa0\xa9\x6b\x0d\xa6\xe2\xd6\xa6\x1b\x76\x51\x8f\xbe\xe5\x55\x77\x3a\x41\x45\x90\xa9\x28\xb4\xcd\x54\x5f\xcc\xf5\x81\x72\xf3\x58\x57\x12\x0e\xb9\x6e\x75\xc5\xc8\xac\x9a\xe3\xad\xd3\x67\xd5\x1d\x34\xac\x40\x34\x46\x36\x0e\xc1\x0f\x55\x3e\xa9\xf1\x4f\xb2\xb8\xb7\x8c\xba\x18\xc3\xe5\x06\xb2\xf0\x40\x97\x06\x3a\x43\xb2\xd3\x64\x31\xcc\xe0\x2c\xaf\x11\xc5\xa4\xdb\x8c\x82\x17\x52\xe5\x29\x85\xd5\xaf\x1b\xfb\xf4\xc6\x15\x72\xe3\xfa\xda\xe3\xad\x42\x4a\xcd\x81\x66\x2e\xa5\x83\x7a\x11\x43\xb9\x66\x93\x91\xd7\xb9\xcf\xe2\x30\xcf\xfb\x3a\x7b\xb0\x3f\x65\x91\xc2\x5a\x4f\x01\xc0\xd2\xd4\xac\xa3\xe7\x4d\xb1\x99\x7d\x37\x39\xc8\x51\xf0\x32\x7d\xb9\x19\xff\x6e\x77\xf6\xc8\xa2\x0f\xdd\x3e\x15\x94\xe9\x2d\x01\x90\x1a\xb9\xae\xf1\x94\xfc\x89\x3e\x70\xd7\x8c\x8a\xe0\xf4\x80\x00\x1a\x51\x5d\x4f\x99\x23\xae\x62\x78\xe8\x92\x72\x37\xd0\x5d\xb2\x3e\x98\x4c\x92\xa6\x83\x88\x2f\x57\xb1\xf1\x88\x2a\x74\xa1\x93\xab\x69\x12\xff\x24\x1b\x9f\xfa\x66\x2a\x0d\x47\xf2\x92\x05\xf0\x84\xdb\xde\x84\x5b\xaa\xeb\x5d\xd3\x6a\xe6\x43\x9a\x43\x76\x42\xfa\x76\x3b\x57\xe8\xdb\xe8\x4e\x55\x81\x3f\x01\x51\xe9\x7e\x5b\x9d\xe7\x68\xb2\x34\xb8\xdb\x15\xc4\x96\xd4\xbf\xcf\xa1\x38\x87\x88\x97\x2b\xb5\x0c\xe0\x30\xbc\x6e\x0c\xcf\x4f\xa7\xd0\x0d\x34\x37\x82\xf6\xba\x8d\xe0"}, +{{0x9e,0x2c,0x3d,0x18,0x98,0x38,0xf4,0xdd,0x52,0xef,0x08,0x32,0x88,0x68,0x74,0xc5,0xca,0x49,0x39,0x83,0xdd,0xad,0xc0,0x7c,0xbc,0x57,0x0a,0xf2,0xee,0x9d,0x62,0x09,},{0xf6,0x8d,0x3b,0x81,0xe7,0x35,0x57,0xee,0x1f,0x08,0xbd,0x2d,0x3f,0x46,0xa4,0x71,0x82,0x56,0xa0,0xf3,0xcd,0x8d,0x2e,0x03,0xeb,0x8f,0xe8,0x82,0xaa,0xb6,0x5c,0x69,},{0x38,0xa3,0x1b,0x6b,0x46,0x50,0x84,0x73,0x82,0x62,0xa2,0x6c,0x06,0x5f,0xe5,0xd9,0xe2,0x88,0x6b,0xf9,0xdd,0x35,0xcd,0xe0,0x5d,0xf9,0xba,0xd0,0xcc,0x7d,0xb4,0x01,0xc7,0x50,0xaa,0x19,0xe6,0x60,0x90,0xbc,0xe2,0x5a,0x3c,0x72,0x12,0x01,0xe6,0x05,0x02,0xc8,0xc1,0x04,0x54,0x34,0x66,0x48,0xaf,0x06,0x5e,0xab,0x0e,0xe7,0xd8,0x0f,},"\x19\x48\x5f\x52\x38\xba\x82\xea\xdf\x5e\xff\x14\xca\x75\xcd\x42\xe5\xd5\x6f\xea\x69\xd5\x71\x8c\xfb\x5b\x1d\x40\xd7\x60\x89\x9b\x45\x0e\x66\x88\x45\x58\xf3\xf2\x5b\x7c\x3d\xe9\xaf\xc4\x73\x8d\x7a\xc0\x9d\xa5\xdd\x46\x89\xbb\xfa\xc0\x78\x36\xf5\xe0\xbe\x43\x2b\x1d\xdc\xf1\xb1\xa0\x75\xbc\x98\x15\xd0\xde\xbc\x86\x5d\x90\xbd\x5a\x0c\x5f\x56\x04\xd9\xb4\x6a\xce\x81\x6c\x57\x69\x4e\xcc\x3d\x40\xd8\xf8\x4d\xf0\xed\xe2\xbc\x4d\x57\x77\x75\xa0\x27\xf7\x25\xde\x08\x16\xf5\x63\xfa\x88\xf8\x8e\x07\x77\x20\xeb\xb6\xac\x02\x57\x46\x04\x81\x98\x24\xdb\x74\x74\xd4\xd0\xb2\x2c\xd1\xbc\x05\x76\x8e\x0f\xb8\x67\xca\x1c\x1a\x7b\x90\xb3\x4a\xb7\xa4\x1a\xfc\x66\x95\x72\x66\xac\x0c\x91\x59\x34\xaa\xf3\x1c\x0c\xf6\x92\x7a\x4f\x03\xf2\x32\x85\xe6\xf2\x4a\xfd\x58\x13\x84\x9b\xb0\x8c\x20\x3a\xc2\xd0\x33\x6d\xcb\xf8\x0d\x77\xf6\xcf\x71\x20\xed\xfb\xcd\xf1\x81\xdb\x10\x7e\xc8\xe0\x0f\x32\x44\x9c\x1d\x3f\x5c\x04\x9a\x92\x69\x4b\x4e\xa2\xc6\xeb\xe5\xe2\xb0\xf6\x4b\x5a\xe5\x0a\xd3\x37\x4d\x24\x6b\x32\x70\x05\x7e\x72\x4a\x27\xcf\x26\x3b\x63\x3a\xb6\x5e\xcb\x7f\x5c\x26\x6b\x80\x07\x61\x8b\x10\xac\x9a\xc8\x3d\xb0\xfe\xbc\x04\xfd\x86\x3d\x96\x61\xab\x6e\x58\x49\x47\x66\xf7\x1b\x9a\x86\x7c\x5a\x7a\x45\x55\xf6\x67\xc1\xaf\x2e\x54\x58\x8f\x16\x2a\x41\xce\x75\x64\x07\xcc\x41\x61\xd6\x07\xb6\xe0\x68\x29\x80\x93\x4c\xaa\x1b\xef\x03\x6f\x73\x30\xd9\xee\xf0\x1e\xcc\x55\x35\x83\xfe\xe5\x99\x4e\x53\x3a\x46\xca\x91\x6f\x60\xf8\xb9\x61\xae\x01\xd2\x0f\x7a\xbf\x0d\xf6\x14\x1b\x60\x4d\xe7\x33\xc6\x36\xb4\x20\x18\xcd\x5f\x1d\x1e\xf4\xf8\x4c\xee\x40\xfc"}, +{{0x31,0x01,0x0d,0x1d,0x67,0xeb,0x61,0x63,0x48,0xe8,0x47,0x92,0xb9,0x2d,0x5d,0xc1,0x28,0x55,0x3c,0xb5,0x2f,0x63,0x68,0x15,0x9f,0xe7,0xb8,0x16,0xcd,0x0e,0x7c,0x37,},{0x26,0x65,0x43,0xd9,0x67,0x87,0xca,0x90,0x1f,0xcf,0xf0,0x6e,0x6e,0x43,0x44,0x91,0xae,0x09,0x70,0x88,0x0a,0x5a,0x18,0x7d,0x53,0x5e,0xdb,0x19,0xdb,0x5c,0xab,0xeb,},{0x7b,0x1e,0xb6,0x77,0xc3,0xe5,0xe6,0xa8,0xb4,0xba,0x69,0xfc,0xb7,0xf6,0xb1,0x87,0x0e,0x42,0xa8,0xd5,0x89,0x58,0xa3,0x5c,0x67,0x4e,0x2d,0xb8,0x21,0x07,0x48,0x1c,0x4c,0x7b,0x37,0xf0,0xf6,0x89,0xd3,0x9d,0x9f,0x51,0xe1,0x81,0xb1,0x7b,0x11,0x08,0xc1,0x5a,0x3e,0x27,0xb2,0x9d,0xf3,0xa4,0x31,0x5d,0xcc,0x4f,0xaf,0x12,0x22,0x05,},"\x39\xf8\x9a\x5e\x7a\xa5\x30\xb5\x46\x3d\x49\x8f\x80\x35\xb9\x90\x9d\x55\xda\x52\x7c\xdb\xd4\xde\x6d\x22\x83\x79\xf0\x89\xe6\x08\xa9\x20\x7a\x2c\x5b\x9c\x42\x05\x1a\x60\xc8\xca\x3f\xb9\x7a\x1c\x06\xcd\x74\x7d\x9d\x07\x39\x97\x0c\xeb\x88\xce\x52\x6f\x97\x11\x40\xea\x2e\xc2\x1f\x09\x0b\xa0\x75\xbf\x89\x75\xfa\xa5\x08\xb1\xcc\x10\xef\xa4\x94\xdc\x17\x2e\x6d\x3d\x3f\x3f\x75\xdc\x8e\x0e\x96\xf0\x5c\x0c\xcc\xb2\xf9\x6e\x91\x1c\xfa\x7a\x2c\x82\xc9\x84\x50\x18\xbb\x1f\x9d\x75\xf8\x2e\x3d\xfe\x11\x39\x34\x7b\x2a\xc0\x58\xb0\x14\xac\x93\x76\x0c\x90\xf5\x56\x7a\xb5\xc4\xeb\xa0\x4b\x49\xfb\x09\xdd\xad\xd3\x05\xbe\x51\x1d\xfe\x05\xc9\x6e\xbc\x86\xfd\x67\xb5\xd0\xab\x57\xd8\x5f\x4f\xe5\xe2\xf0\xfa\x9d\x88\xa6\x8f\x0f\x6b\x6b\xc8\xbb\x94\x4e\xb3\xc0\xb1\x75\x57\xe5\x5d\x5e\xa1\x87\xd9\x22\xa4\x28\x13\xe6\x90\x57\xc9\xb6\xa7\xf7\x5e\x49\x92\x1b\x70\x79\xe5\x8f\x8a\x63\x71\x9e\xe3\xe1\xad\x10\xcf\x0e\x8a\x70\xc4\xf1\x54\x02\x18\xb7\x04\x94\xbd\x02\x9e\xe0\x2f\xf9\x72\x7a\x7d\x85\xd3\x77\x91\x9e\xc4\x05\x14\x79\xb7\x0f\x7c\xd6\x76\x77\x23\xfe\x42\xc1\xc7\x89\x9c\x2b\x7c\x1f\x70\x2d\xd6\xb4\xd1\x3b\x67\x2d\x48\x8f\x34\xa0\xe9\x69\xdb\x79\xcc\x2c\xb2\x52\x4a\x94\x8a\x8d\xe4\xc5\xb6\x23\xec\xd9\x0d\x6e\x82\xd9\x70\x33\xc1\x25\x63\x7d\x1c\xd8\xc8\x48\x03\xd8\xfb\xc0\x12\x84\x6f\xfe\x48\x4f\x6c\x02\x14\x92\x58\xf9\x46\x2f\xa1\xe9\x9c\x30\x7d\xd0\x06\x2f\xe0\xb6\xf1\x1e\xee\x40\xc2\x62\x9e\xf7\xc0\xf6\xa5\x10\x72\x59\xea\x5b\x9f\xfb\x6f\x29\xf1\x2c\x32\xf7\xb5\x22\x8c\xab\xc9\x86\xab\x66\x45\x0a\xf9\xdc\xc3\xda\x09\xd0\xe0\xb9\xa4"}, +{{0x8f,0xf2,0x39,0x8c,0xd5,0x1f,0x51,0xd4,0xc2,0xc5,0x78,0x69,0xa2,0x21,0x8b,0x84,0x86,0x82,0x20,0x31,0xf4,0x00,0x72,0x9f,0x4a,0xc4,0xd5,0x90,0x9c,0x48,0xba,0xfe,},{0xa5,0xa8,0x87,0x04,0xb6,0x86,0x77,0xbe,0x3d,0x16,0xc3,0xdc,0x00,0x52,0xcf,0xee,0x6e,0x2b,0x30,0xe0,0x86,0x09,0x05,0x9d,0x4c,0xba,0x52,0xc6,0xd9,0x60,0x61,0xfb,},{0x41,0x7a,0x64,0x78,0x29,0xc9,0x28,0x98,0xe5,0x20,0xff,0x53,0x11,0xda,0xa0,0xa1,0x39,0xcd,0x8f,0xff,0xcb,0x25,0xa1,0x8e,0x6d,0x9b,0x50,0xcb,0x52,0xcb,0xc3,0x54,0x24,0xc3,0x9e,0xbb,0xb5,0xd5,0xac,0x6a,0x6d,0x63,0xf1,0xf5,0x3c,0x4d,0xf2,0x12,0xf7,0x02,0x5a,0x8a,0xae,0xf8,0xe3,0x64,0x93,0xc8,0x74,0xc3,0xce,0x34,0x1a,0x0e,},"\x99\x39\x53\xe4\x7a\x34\x11\x88\xbc\x59\x29\x42\xe1\x55\x7a\xf2\x95\x46\xe4\xe9\x36\x8e\x2f\x1a\x5e\xe9\x80\x6e\x2b\xaf\x66\xb6\x19\x01\x91\xfc\x5d\x2b\x7e\x47\xde\x37\xff\x05\x4f\xb2\xbb\xb1\xf0\x31\x68\x4a\xda\x5d\x60\x7a\xdd\xa3\xd6\x54\x33\x12\x2f\xa9\x04\xe0\x45\x6f\xaa\x84\x10\x9b\xbc\x51\x7f\x8a\xd3\x96\x60\x87\x63\x82\xad\xcf\xed\x0f\x76\x20\xcf\x11\x64\x62\x2e\xac\xd9\x1e\xb3\x7a\x85\x96\x46\x2e\xbe\x9e\xbe\x26\xbd\xc1\xe3\x2c\xc3\x4a\xd4\x6f\xb1\xce\xa4\x20\xe7\x3c\x31\x21\x54\x08\xe6\xd3\x54\x25\xf4\x4a\x82\x9b\x13\x2f\x63\x1a\x3f\x6d\xd4\xb8\x73\xa0\x00\x66\x7e\x19\xeb\x22\xff\xfd\x59\x03\xaa\xa7\xd4\xc8\xfd\xf2\x19\x53\xc3\xc6\x17\x8f\x5f\x8c\xb2\xaa\x6b\xff\x92\x89\x4e\xad\x83\x58\x88\xdf\x06\x0a\x3c\x90\x43\x02\x6e\x0e\x2c\xef\x27\x54\x97\xe7\xd1\x05\xdf\x3b\x64\x4a\x98\xf2\x6b\xf0\x01\x05\xc9\x94\x13\xee\x0a\xf8\x85\x19\x54\xd6\x5c\xeb\x8d\x79\xad\x30\x71\xb8\xbb\x87\xf0\xb1\x97\x43\xd2\x55\x6f\xfd\x98\x19\x83\x0b\x6e\xeb\xf7\xec\xc7\xe0\x45\x66\x1f\x43\x57\x0c\xe9\xfd\xbb\xe2\xd2\x52\x40\x6f\xa9\x0d\x04\x23\x6f\x22\x2c\x42\x9e\xc1\x6b\x12\x87\x22\x4a\xda\x1a\x53\x21\x61\xae\x8b\x48\x1b\xca\xb8\xd4\x7a\xfb\x3e\xd0\x44\x5b\x30\x60\xfd\x67\x59\x17\x98\x56\xf4\x08\x5c\x1e\x58\x5f\xd7\xc1\x40\x97\x99\xaf\x69\x3c\xf4\x27\xbd\x1d\x3d\xc1\x0b\x5a\xe3\x44\x7a\x8d\x2a\x18\xdc\x3a\x12\xa6\x86\x0b\x22\x17\x5d\xd5\xeb\x53\xa0\x95\x04\x32\xe2\xd7\xae\xfe\xce\x8a\xf0\xad\xe3\xd8\x56\x77\x43\xde\x43\x69\x0f\x2d\x25\x37\x23\xc5\xd7\xe4\x8b\xd3\x0d\x29\x37\x59\x37\x01\xce\xcd\xe9\x15\x4b\x76\x65\xcb\x61\x1d\x7d"}, +{{0xef,0x81,0x6c,0x8f,0x5e,0xc3,0x4e,0xf4,0x1f,0x68,0x83,0x1d,0x90,0xcd,0x29,0xe5,0x2d,0xe8,0x97,0x37,0x82,0xd0,0x03,0xee,0x4e,0xda,0xda,0x2a,0xda,0x26,0x91,0xd6,},{0x47,0xf9,0xb3,0x63,0xa8,0x8a,0x45,0x05,0x3a,0x05,0xbb,0x72,0x16,0x08,0x52,0xbf,0xe8,0xf7,0xdf,0xef,0xc2,0xf3,0x72,0x83,0xde,0x34,0x67,0x52,0xca,0xf0,0x92,0xcc,},{0x65,0xc5,0xd1,0x0e,0xa7,0xbf,0xdb,0xb3,0x8d,0x55,0x36,0x4a,0x99,0x68,0xf8,0x2b,0x54,0x82,0x24,0xdf,0xf3,0x36,0x3b,0x2d,0xdc,0xf5,0x85,0x16,0x3d,0xea,0x27,0xdc,0x63,0xb0,0x56,0x3e,0xb1,0xa8,0xdf,0xbe,0xe9,0x51,0xd3,0xc9,0xb3,0x3f,0xcd,0x6b,0xbf,0x09,0x21,0xc3,0xab,0xb2,0x17,0x86,0xb2,0x29,0x06,0x9b,0xd9,0xca,0x00,0x0a,},"\x95\x93\xc3\x5c\xde\xc5\x35\xbe\xbb\x69\x65\xda\x68\xea\xb0\xb6\x46\xbf\xfc\xfb\xd0\x48\x83\xbc\x4c\xef\x90\xd5\xd0\x1f\x01\x8c\x63\xc9\xb0\xdd\xfb\x3c\xef\x5e\x78\x62\x84\xd5\x21\x8c\xaa\xaf\x06\x0e\x92\x88\x95\x2f\x16\x30\x1e\xd8\xa4\xc1\xbc\xee\x25\x63\x56\xa0\xc8\xbd\xa3\x59\xfb\xaa\x27\x82\xb1\x0c\x86\xd1\x8e\x20\xf7\xa0\xec\x99\xb2\x7a\x0b\x4d\xbe\xfc\x0a\x26\x2a\x3b\xf6\x8f\xe8\x14\x44\xdc\xae\x5f\x69\x3e\xb0\xf1\x6e\x6e\xe0\x3f\x8f\xcb\xf3\xa3\x39\x81\x46\xd2\x0e\xc4\xd2\x65\x77\x61\xfd\x03\x20\xfe\xe7\xea\x70\x3c\x49\xa6\xa5\x43\xbc\x9b\xba\x91\x1e\x79\x25\x03\x87\x10\xe8\xc3\x65\x52\xd4\x76\xd6\x02\x7f\x58\xb2\xc5\x2b\xa5\x1a\xd6\x5e\xa4\xf0\x39\xc7\x8f\x96\xb8\x89\x10\x2b\xb4\xbd\xd6\x9b\x68\xe9\xc3\xd4\x5b\x51\x76\xa2\xd8\x2b\x0b\x95\xdc\x32\x10\x16\x37\x0d\xae\x30\xc3\x93\x65\x15\xdb\x04\x64\xc4\x17\x74\x30\x1c\x74\xe4\x2d\x89\xb8\xbf\x4b\x9c\x19\xed\x55\x4b\x12\xfe\xba\xc0\xf6\x0d\xdb\x32\x19\xcc\xc5\x60\x35\x31\xdb\xf2\xeb\x5f\x29\x34\x25\xd7\x2c\xce\xfa\x0c\x7f\x14\x4a\xba\x89\x34\x7b\x29\x6b\xe8\x7f\xf1\x89\x94\xb4\xa0\xc7\x0c\x93\x0f\x05\x93\x03\xb5\xdd\x4c\x8f\xe1\xe6\xbb\xc3\xcd\x68\xc6\xc0\xd8\x42\x46\xdc\x6e\x61\x40\xa2\xab\xd1\x78\x0b\x13\xf1\x59\x4a\x60\x19\xd1\x77\x8b\x7c\xbb\x3a\x3e\x3a\x34\xbf\xae\x72\x97\xf0\xb3\xed\xc3\x76\x94\x1c\x32\x35\x2a\x4b\xe3\x14\xb8\x4a\x9d\x8d\x6d\x7f\x1f\x38\xa0\xad\x37\x98\x02\x0a\xa2\xa3\x31\xa4\x02\xbe\x9c\x70\x44\x84\x74\x4a\x73\x0c\xbd\xed\xcb\x90\x4b\x6f\xde\x70\x8f\xbd\x14\xbf\xdc\x29\xef\xd4\x61\xd1\xd0\xb5\x82\x5d\xe0\xbc\x79\x42\x2b\x69\xa2\x72\x2f"}, +{{0x45,0xeb,0x0c,0x4d,0xfa,0xfa,0x2a,0x76,0x90,0xef,0x57,0x9c,0x09,0x54,0x56,0xce,0xed,0xcd,0x32,0xf0,0xb6,0x14,0x4d,0x0c,0x38,0x0f,0x87,0xfb,0x74,0x4a,0x0b,0x1f,},{0xfc,0x85,0x63,0x2c,0x98,0x38,0x4b,0x5f,0x96,0x82,0xae,0xd9,0xcd,0x66,0x4c,0xf1,0xf4,0x8e,0x58,0x8b,0xe2,0xd5,0x68,0xe5,0xc7,0x34,0x49,0x4d,0xf4,0xc7,0x12,0xb8,},{0x55,0x85,0x1d,0xe8,0xe1,0x09,0x2f,0x78,0x94,0x4f,0x6c,0x6d,0xd9,0x5b,0xf0,0x7e,0x2d,0xbc,0x8d,0xf7,0xf5,0x7a,0xd5,0x76,0x82,0x9b,0x97,0x8e,0x3a,0xf5,0x8a,0x7a,0x8e,0x94,0xed,0x4d,0xcc,0xbc,0x01,0x82,0x46,0x7e,0xdf,0x0b,0xad,0x4b,0xae,0x7c,0xa8,0x4a,0xa9,0xa0,0xc1,0x7c,0x61,0xa9,0xe0,0xdd,0xff,0x1d,0x75,0x25,0xd7,0x04,},"\x6f\x66\xd8\x47\x40\x5a\x03\xd7\xbd\x6f\x8d\x28\x97\xdb\xdf\x04\xe7\x6d\x7d\xf2\xd9\x47\x0a\x49\x96\xb7\xdd\x6d\xb8\x85\x00\xf8\xf4\xf8\x3e\x96\x0e\x21\x9a\x24\x86\xe2\x45\x45\xad\xd1\x36\x14\x55\x04\x14\xd8\x27\xc4\x1a\x9b\x08\x31\x8d\xaf\x01\xb1\x52\x14\xc6\x4a\x42\x66\xcb\xf8\xa5\x71\x7a\xda\x3e\x62\xc2\x67\x29\x07\x3e\x16\xdd\xbd\x66\xf2\xd5\x20\xe1\xe0\x99\x35\xde\x05\xe4\xdb\x11\xc3\x96\xd4\x77\x01\x0a\xec\x66\xaa\xfb\x76\x2e\x69\x23\x8d\x0b\x9e\x76\xb4\x52\x45\x4b\xf9\xe4\x51\xe7\x6a\xc7\x9e\x69\x90\xd4\x1b\x93\x2b\xc3\x29\x17\x09\x37\x83\xc9\x1b\xc9\xcf\x0b\xbe\x3b\x51\x40\x70\xa1\xe6\x92\xff\x34\xfd\x06\xb6\x6e\xa1\x1f\x39\xe1\x0a\xf9\x33\xee\x96\xd8\xe9\xb6\x77\xcb\x03\x73\x7e\x79\x64\xee\xaa\x72\x5f\x12\x12\x07\xf9\xc1\xb2\x6a\x96\xc6\x16\xdf\x7c\xb7\xca\xef\x47\xbd\xa9\x01\x36\x8f\xf2\xea\x58\x6e\x42\x2e\x65\xbf\x21\xa6\x91\xbd\xd2\xc1\x3e\x67\xff\xf5\x8c\xfb\xfe\xd8\x17\x82\x04\x9d\xaf\xa0\xf7\x27\xdf\x88\x62\x3f\x2f\x7e\x8f\x26\x2d\xaf\x93\x95\x42\xa1\x87\xb8\x72\x0a\x9b\x6b\x2b\x09\x89\x0e\x54\x87\x6b\x28\xa4\x38\x74\xab\xbe\x3b\xfa\x98\x1f\x81\x38\xb7\x72\xc5\xd5\x17\x36\x88\x5f\x86\xac\xac\x22\x15\xa0\xb0\x10\xdf\xc2\xc6\xb1\x50\x84\x5d\x4f\x82\x96\x25\x25\x86\xa3\xe1\x15\xf3\x03\xc3\xd8\xa5\x82\xe2\x0f\xd2\xd4\x3f\x6c\x44\x6e\x5d\x00\x28\x0e\xc1\x79\x82\x3b\x7f\xb4\xc1\xb0\xfe\xb9\x4e\xb4\xef\x17\x07\xf5\x18\x4e\x3b\x52\x46\x1a\x75\x62\xd1\xf3\x07\xcb\x75\x1c\xdb\xbf\x6e\xae\x49\xff\xae\x91\x86\x23\x58\xe7\x4e\x95\x48\x82\x2b\x8a\x04\x9f\xec\x6b\xf4\xc7\xa9\x9c\xab\xbe\x09\x20\x65\x77\xb6\x57\xe3\x1f"}, +{{0x70,0x9d,0x2e,0x19,0x90,0x06,0xf5,0x36,0x9a,0x7a,0x0b,0xdd,0x34,0xe7,0x4d,0xc7,0x84,0xbe,0x33,0x88,0x0e,0xa3,0xc5,0xdd,0x10,0xed,0x5c,0x94,0x45,0x1e,0x79,0x72,},{0x06,0xf9,0x89,0x20,0x2b,0xa2,0xcb,0xc9,0xc1,0x50,0xbe,0x61,0x12,0x62,0xac,0xa0,0x0c,0x45,0xf0,0x12,0xf8,0x9f,0xba,0xf8,0x9f,0x8c,0xec,0xcb,0xa0,0xb1,0x93,0x4a,},{0x62,0x9b,0xf9,0x7b,0x0c,0x78,0xee,0x6a,0x9c,0x87,0x59,0xfb,0xea,0x28,0x22,0x4e,0x27,0xab,0xbb,0x6c,0xbe,0x4d,0xea,0x5b,0xb7,0x97,0xe6,0xe0,0xfe,0x80,0xc9,0x13,0xf9,0x53,0xe3,0xa9,0xb6,0x23,0x35,0x2d,0x13,0xac,0xf4,0xce,0x62,0x50,0xfb,0x02,0x9a,0x1e,0x19,0x8d,0x72,0xbd,0x5e,0x74,0x02,0xe6,0x0e,0x9e,0x48,0xca,0x35,0x01,},"\x62\xf0\x03\x14\x0f\xa0\x9e\x03\x87\xd1\x87\xa0\xff\x96\xc4\x56\x3d\xf9\xf4\xe2\x8c\x22\x82\xc0\x18\x3a\xc3\xee\xde\x13\x12\x35\x49\x21\xf7\x80\xfc\xa5\x36\x1d\x30\x68\xd2\x99\x49\x63\x0b\x75\x30\xcd\x59\x14\xac\xe0\x46\x8d\x01\x4b\x6f\x53\xd8\x39\xb8\x2e\x38\x81\x7d\xbf\x2d\x83\x92\xc3\xce\x34\x24\xea\xb8\x6a\x24\xd8\x04\xc7\xac\xb1\xce\x7a\xcf\xe0\xa1\xcd\xa4\x39\x39\x24\x28\x31\x05\xda\x4a\x77\x41\x19\x6e\x02\x75\x50\x04\x7f\x85\xb7\xa0\xa0\x1d\x45\x41\x24\xef\xc0\xe2\x99\xf0\xef\x9a\xd1\x43\x50\x54\x30\x53\x48\x22\x61\x52\x8b\xaa\x56\xe6\x59\x99\xac\x80\x2c\x00\xa3\x36\x26\x7c\x63\x51\x06\xb2\x64\x03\xc1\x9f\x39\x1d\x53\xbd\x82\x86\x1d\x6d\x48\xa4\x38\x0b\x30\x43\xaa\x91\xd6\x49\x53\x68\x81\x20\x4e\xcc\xb0\xde\x20\xd4\x3e\x5a\x37\x55\xb7\xf6\x00\x91\x6e\xcc\xae\x42\xa0\xc9\x05\x3b\x46\x2d\x94\x17\xa1\x3d\x67\xd7\x78\x26\x4a\x89\x6e\x8e\xaf\x90\xba\xf6\x6d\x29\xe5\x43\x8a\x71\x67\x81\x12\x3a\x89\xfa\x9b\x8b\xee\xf9\x1d\x96\x5a\xf2\xf4\xa1\xa5\xbd\x5d\x2e\x2a\xaf\x46\xd5\xc9\x4b\x77\x09\xcd\xd3\x8d\x05\xfe\xee\x4b\xfb\x76\xa3\x59\x07\x7c\x16\xbc\x4b\xe9\x11\x6e\x69\x00\x12\x71\xcd\xa5\x65\xbc\x19\xbf\x47\xd4\xf9\x86\xbd\x9c\x0d\x18\x4c\xd8\xa3\x52\x0c\xa1\xbd\xb4\xb5\x05\xaa\xf7\xcb\x4e\xc9\xf9\x47\x89\x77\x9d\x30\x71\x4e\x79\x11\x6d\xd5\x01\x9d\x59\xb2\x8b\x17\xda\xd9\x6f\x4e\x21\x55\xad\x9c\x61\x27\x4a\xdd\xc6\xb6\x38\x10\x95\x04\xe9\xed\x19\xf4\xed\xa5\x37\x77\x62\x64\x8c\x40\x98\x22\x4e\x33\x91\x04\x3e\x4c\x2a\xd5\x91\x65\x4c\x9e\x7f\x97\x4e\xfd\xf0\xb0\x50\x4b\x6f\xa5\xf6\x46\xce\xcf\x44\xcd\x37\x24\x12\x37\x25\x05"}, +{{0x51,0x51,0x61,0x74,0x21,0xaa,0xdc,0x9c,0x95,0xa4,0x42,0xb4,0x5e,0x7f,0xf6,0xde,0x06,0xa2,0xc7,0x33,0xb8,0x5b,0xd7,0x89,0xfb,0xad,0x41,0x4e,0xe3,0xc9,0x1a,0xdd,},{0x14,0x94,0x1d,0x55,0x97,0x61,0xb3,0x0a,0xb0,0xa8,0x6d,0x47,0xe0,0xf7,0xd1,0x89,0x6b,0x33,0x78,0x45,0x27,0xc8,0x0a,0xf4,0x1c,0xb8,0x48,0x10,0xcb,0xff,0x9d,0xbf,},{0xfa,0xe4,0x77,0x3b,0x33,0x44,0x60,0xc7,0x7b,0xf0,0x1e,0xc6,0x36,0x6c,0x4f,0xe6,0x1c,0x0c,0xab,0x57,0xd8,0xa4,0xb0,0x39,0x09,0xc6,0x19,0xe1,0x1e,0xe3,0x46,0x1c,0x13,0xfa,0x21,0x57,0x6f,0x63,0x87,0x0e,0x42,0x3d,0xd0,0x41,0x81,0xe4,0xa7,0x01,0x3a,0x75,0x24,0xf2,0x46,0xfe,0x33,0x85,0x3c,0x67,0x41,0x62,0xa7,0x81,0x51,0x04,},"\x21\x6e\x9d\x40\xbc\xdc\x3b\x26\x50\x18\x8d\x12\x1c\x9f\x8e\xf2\x9e\x91\x4f\xac\xd0\x22\xfe\x01\xb9\x0e\xd1\x12\x25\xf2\xeb\x93\x53\x8e\x5f\xce\xe5\xab\x80\x45\xe9\x19\x9a\xa7\x6a\x16\xbd\xd0\x61\x68\x05\x66\x0e\x24\x7f\xec\xd7\xe2\x28\x21\xb6\x9b\x1f\x8e\x8a\x58\xac\x3f\xb8\x56\x91\xd7\x5d\x59\x57\xa1\xda\xf5\x3f\xf9\xee\x64\x76\xd7\xc4\xbc\x54\x1e\x6a\xd3\x8e\x3a\x34\xea\x90\xfc\x52\xa4\x8b\x93\x99\xf9\x2d\x17\xc9\xbb\x0d\x7f\xc3\x10\x4c\x55\xd0\xef\xb4\xea\x5b\x83\x1f\xf9\x49\x0b\x3f\x79\xf4\xd9\xd6\x99\x59\x4b\x74\x15\x66\xf2\xb5\x0a\x8f\xc7\x8c\xc4\x03\xfa\x40\xf5\xab\xb6\x63\x8a\x32\xf4\x49\xa8\xb3\xef\x02\x9c\x40\x2f\x46\x93\x1a\xd2\xbd\x3e\x8e\x68\x31\x08\x71\x4c\x98\x9a\xe2\x16\x89\xe9\xc4\x44\xb9\xf5\x5b\x81\x11\x9b\xb5\x03\x5b\xcf\x73\xe9\x7c\xe4\x3a\x22\x18\xc7\xbc\x3e\x43\x0d\x1e\x81\x4f\x34\xde\xe0\x57\x26\x5d\x31\x94\xb9\xf4\x38\x75\xd8\x38\x1f\x52\x5f\x78\x57\x6e\x64\xce\x69\x25\x84\xfa\xa3\x0f\xb7\x43\xa1\x2d\x1b\x77\x61\x4d\x2e\x10\xa6\xb8\x56\xb5\x2b\xe2\x7c\xdb\x63\x0b\xa1\xf0\xd3\xa6\xf8\xea\x98\x44\x54\x2e\x58\x4e\xa0\xa2\x77\x75\x27\xd0\xc5\x2a\xca\x94\x9a\xac\xda\x45\xad\x83\xd1\x6d\x5c\x83\xd6\x63\xad\xb7\x9c\xad\x6f\x3e\x39\xe9\x90\xfe\x28\x2a\x14\xc3\x53\xaa\x23\x79\xd7\xf0\x6a\xda\xb7\x4c\xea\x02\x1b\x89\x83\xa5\x7f\x1d\x0c\xf7\x03\x29\x2e\xb0\x5e\xce\x89\xc5\x3f\x3a\x12\x65\x61\x0e\x0c\x1e\xa8\xdd\xd4\x44\xd1\xff\xd6\xbc\x3d\x03\xf0\xa6\xe4\xd0\xdf\x5c\x5b\x8d\xc1\xf9\x5d\x9f\x55\x58\xb1\x18\xaf\xe6\xbe\xa0\xf6\xc2\x93\x13\x63\xf0\x3a\xb3\x4e\x75\x7d\x49\x36\x41\x74\xf6\x58\xef\xbb\xf3\x8d\xc1\x77"}, +{{0x38,0xbe,0xd4,0x45,0x55,0x6d,0xe7,0x44,0x82,0xbf,0x5f,0xec,0x05,0x06,0xf9,0xaf,0x33,0x0b,0x15,0x1e,0x50,0xd4,0x77,0x4d,0xfe,0x85,0x91,0xd7,0xb7,0xe0,0x27,0x6b,},{0x4c,0x0f,0x9c,0x49,0xa4,0x2f,0x40,0x47,0xbf,0xe6,0x88,0x55,0x51,0xc5,0xe4,0xb8,0x56,0xcf,0x77,0x1a,0x67,0xaf,0x3f,0x89,0xdb,0xf6,0x02,0xf9,0xdb,0x92,0x20,0xf3,},{0xf7,0x02,0xd0,0xd4,0x63,0x28,0x2f,0xc7,0xfd,0x5f,0x8f,0x90,0x29,0xb8,0x9c,0x62,0x6c,0xaf,0xd8,0x34,0x50,0xc3,0xbb,0x9d,0xd8,0xf6,0x58,0x9f,0x0c,0x4b,0x4b,0x71,0xf6,0x49,0xea,0x21,0x2e,0x5e,0x33,0x48,0x7c,0x59,0xc1,0x68,0xea,0x3a,0xd8,0x31,0x50,0xf1,0xfc,0xdf,0xe8,0xc5,0x3e,0xba,0x65,0xad,0xc2,0x02,0x3c,0x25,0x83,0x0f,},"\x0f\xf0\x03\x1d\xf0\xbe\xef\xf3\x71\x0c\x6b\x76\x3f\x9b\x8e\xc8\x17\x19\xbf\xa1\x52\x8c\xe4\x65\x19\xad\xf3\xd3\x41\x2d\x93\xfb\x18\x8f\xd4\x97\xd5\xd1\x70\x91\xc0\xf0\x34\x59\x60\xdd\x0e\xb0\xc0\x9f\xc4\x00\x51\x73\x66\x5d\x4d\x97\xf9\x5c\x13\x82\x8b\xc7\x6b\x34\x92\xb8\x7a\x4b\x64\x25\x3c\x8b\x5f\xa4\x7a\xa7\x5f\xa3\xb8\x6d\x5a\xbe\xea\x8d\xe5\x95\x9a\x60\x22\x89\x13\x6f\x60\xa6\x9b\x30\x9e\x77\x3b\x22\x55\xcd\xe1\x9e\xd2\xa2\xe1\x99\xc3\x3d\xb1\x1c\x16\xad\xe0\x8a\x31\x97\x50\xb8\x51\xd9\x2c\x69\x29\x24\xfc\x98\x59\xbe\x52\x34\x31\xcb\xe7\x8e\xc0\x92\xdb\x11\x29\x21\x0e\xbb\xea\xa7\xc2\xa2\xc0\x00\xee\xb1\x05\xca\x03\x01\xa4\x8f\x3e\x45\xfd\xfb\x15\xb2\x75\xcb\xab\x83\xca\x5c\x99\xd7\x37\xa5\x85\x32\x0e\x9e\x3b\x31\x71\x79\xbd\x86\x46\x7f\xa9\x69\x4f\xcd\xb2\xac\x6a\xd3\x6e\xd7\x14\x48\x43\xdb\xc3\x4e\x42\x3d\x35\xaf\xd7\xd8\x97\x2a\x1c\x43\xc1\x99\xa1\x91\xab\xd6\xce\xba\x49\x36\xd3\x95\xc9\x95\xa3\xeb\x13\xcb\x05\x7f\x88\xa9\xdc\x94\x90\xfe\x98\x84\x5e\xe5\xd2\x6a\x89\xfb\x64\x2a\x2a\x51\x6d\xc3\x05\x6c\x54\xd3\x63\x72\x13\x36\x3a\x86\x28\xa4\x2a\x39\x5d\x94\x2b\x95\x4a\x89\xe8\xef\x7a\x74\x4d\x8a\xe5\xad\xac\x88\xc6\x16\xef\xaa\x90\xe2\x07\x72\x05\xa6\x0b\xaf\xfe\xde\x5c\x87\xbb\x14\xde\xad\x30\x62\x29\x49\x5f\x69\x8f\x3e\x49\x06\x16\x96\x6b\x16\x36\x38\x7d\x0d\x86\x18\x3f\x94\x5b\x24\xa9\xdc\xfc\xcf\x4d\x36\x72\x2c\xd1\x2e\xbb\x6b\xd8\xe7\x83\x25\x75\x2a\xfa\x2b\x1a\xbd\x13\xc4\xbd\xbc\xad\xd1\x70\x86\x91\x36\x82\x62\x42\xac\xfb\x72\x1d\xe5\xff\x27\xba\x8a\xa0\xc0\x18\xb2\x25\xed\x34\x04\x80\x3c\xe9\xfa\x2d\x50\x8d\x89\x44"}, +{{0x05,0x54,0x60,0xb3,0x2d,0xd0,0x4d,0x7f,0x4b,0x23,0x11,0xa8,0x98,0x07,0xe0,0x73,0xfd,0x55,0x65,0x65,0xa4,0x77,0x18,0x57,0xd8,0x82,0x79,0x41,0x30,0xa2,0xfe,0x5d,},{0x26,0x0f,0x8f,0xed,0x4b,0xba,0x30,0xb9,0xe1,0x2a,0xd8,0x52,0x3f,0xbb,0x6f,0x57,0xf0,0xa7,0xa8,0x82,0x55,0x00,0x61,0xf1,0xda,0x46,0xfb,0xd8,0xea,0x44,0x22,0x21,},{0x23,0xf4,0xf1,0x62,0x7f,0xba,0xbd,0x78,0x91,0xd7,0xd8,0x48,0x96,0x31,0xc7,0x23,0x1d,0x22,0xde,0x71,0x86,0x4e,0x26,0x2a,0xb4,0xda,0x84,0xea,0x8a,0x13,0xa6,0x0f,0xea,0xc4,0xdc,0xfb,0x18,0x12,0xf1,0x20,0x04,0x44,0xb7,0x75,0xf1,0x21,0xd7,0x26,0x6d,0x75,0x5c,0xe9,0xb6,0xa9,0xad,0x79,0x65,0x59,0xc0,0xa2,0x6b,0x51,0x6d,0x02,},"\x74\x07\xf9\x6e\xe3\xe7\x9c\x69\xd3\x6c\xe1\xf6\x4e\x4f\x18\x86\x55\xea\x68\xb9\x47\xe7\xe2\xbe\x97\xb0\x5e\xbc\x6d\x44\x39\xe9\x50\x27\x6e\xf3\xf0\xe6\xa0\x3d\xd4\x8b\x24\xf6\x69\x29\xb4\x9c\x15\x80\xeb\x46\x88\x07\xe1\xe7\xa2\x5e\xb9\xb9\x4d\xa3\x40\xc5\x3f\x98\x4f\x8b\x81\x60\x3e\xfb\x61\x04\x7b\xf3\xf1\x4b\x68\x6d\x97\x98\x00\x3d\x2f\x68\x58\x9a\x79\xeb\xfa\xd5\x44\x09\xc7\x1c\x90\xff\x67\xc1\x1f\xbd\x76\xcc\x72\xc2\xd1\x45\xf4\x58\xe4\x2f\x88\xb7\x5d\x25\x0e\xad\xca\xfe\x66\xbf\x37\xff\xc8\x37\xb6\x2f\xf0\x06\x68\x5b\x7f\x85\xa9\xd8\x75\xfc\x07\x8c\x82\xe6\x1f\xe3\x5d\x19\x22\x52\x7a\x55\x1d\xab\x62\xf9\xe4\x77\x49\x91\x46\xba\xd9\x12\x20\x3e\x66\x4c\x41\x7c\x36\x79\xc0\x2d\x87\x2a\xba\xc0\x03\x2f\x8c\xc7\x7f\x77\xbf\xe5\x4d\x33\x26\xfd\xee\x92\x76\xa4\x8e\xa4\xeb\x25\x13\x50\x40\x68\x82\xd0\x8c\x83\x0e\x76\x49\xfe\x68\x54\x55\x8a\x75\x13\xab\x2d\x8d\x2a\xc3\xe5\xce\xd8\xa8\x08\xd2\xae\xe4\x54\x77\x9e\xda\xbd\x1a\xa6\x3b\xb1\x9f\x71\x8f\x47\x0b\xdc\x84\x51\xcd\x9b\x29\x49\x41\xe3\x49\x70\x63\xb1\xe3\x9b\x6c\xa1\x84\x56\x2f\xe8\x38\xcb\xfe\xee\x92\x2d\xe2\x4d\xdf\xcf\x98\x82\xc5\xe6\x15\xb1\x1b\xf9\x04\x81\x7f\xbd\x64\x71\x39\xdb\x80\xb4\xe8\xfe\xb3\x7f\x11\xe1\x85\x2d\x7e\x87\x6d\xb9\xcb\x63\xc9\x4d\x7e\xe3\x41\x92\xf7\x20\x0b\x5b\xc7\x7a\x03\x11\xae\x43\xb8\x06\xeb\xd4\xc2\x89\x6c\x53\xf5\x8f\x7e\xbc\x16\x25\xcb\x20\xd7\x10\x7e\xf9\xdb\x0d\xa2\x87\x88\x52\x3d\xe9\x91\xef\x6c\x58\x66\xb1\x8d\x8d\xe8\x3a\x95\x4d\x32\x81\xe0\x6d\xbf\x27\xc4\xf2\x38\x2e\x08\xcd\x0e\x0f\x6e\xba\xe3\xf9\x61\xb7\x7f\xce\x5a\x95\xa9\xb0\x62\x1b\x75\x6f"}, +{{0xe9,0xf6,0xd3,0x1b,0x93,0x69,0x42,0xc5,0x26,0xe0,0xf9,0xec,0x4f,0x5a,0x7a,0xc2,0x5f,0xa7,0x89,0xe0,0xc4,0x34,0xbc,0xd9,0x19,0x9d,0x72,0x0c,0x74,0x3c,0x84,0xc4,},{0x32,0x12,0x6d,0x26,0xe2,0x82,0x31,0xc5,0xb5,0x85,0xb1,0x3f,0x43,0xa0,0x1c,0x6f,0xe5,0x42,0x94,0x6b,0x07,0xd3,0xa9,0x1e,0x57,0xd2,0x81,0x52,0x3f,0x5c,0xb4,0x5c,},{0x7e,0x3b,0x1c,0x4c,0x71,0x6c,0x80,0x8e,0x90,0xb9,0x74,0x45,0x89,0x15,0xf3,0xb2,0x23,0x9c,0x42,0x07,0x71,0x19,0xfe,0x27,0x07,0x88,0xfa,0xe5,0x20,0x57,0x8b,0xd7,0xda,0x64,0x88,0x04,0x41,0x32,0xe1,0xbe,0xf2,0x3e,0x3b,0x23,0xc3,0x4d,0x9c,0x18,0x62,0x74,0x4f,0x28,0xfc,0xae,0xcd,0xa6,0xca,0xc0,0xfd,0x72,0xb9,0x3b,0x6a,0x0f,},"\xe8\x81\x33\xf3\xd1\x76\x42\xd5\xc2\x27\x79\xa8\x53\x16\xba\x0d\xf3\x4c\x79\x2b\x4e\xfe\xe4\x9e\xd7\xdd\x93\xca\x33\x22\xef\x47\xc7\x2e\x5b\x2e\x45\x95\xc7\x78\x00\x43\x4b\x60\x71\x9a\xdf\x54\xe4\xc1\xa3\x4c\x89\xfa\x1e\x27\xee\x8d\x35\xa0\x92\x1f\x97\x55\xac\x4a\x77\xa6\xc1\x68\x4e\xa0\xf5\xc8\xee\x5f\x75\x9c\xe5\x9b\xfe\x83\x15\x80\x0a\x67\xaa\x6c\x64\xdd\xfa\xac\x92\xea\xbe\x6c\x2c\x61\x37\x79\x78\x4b\x3a\xff\xaf\xcc\x62\x0f\x2a\x6d\xc5\xcb\x8d\x8d\xc7\xd7\x4a\xa4\xd7\x94\x94\x67\x84\x94\xe5\xe6\x39\x4c\x43\x3c\x14\x80\x9f\xf4\x0c\x9a\x59\x2d\x0d\x69\x4a\x81\x10\x3b\x44\x53\x1e\x1f\x48\xbc\x13\x96\x5d\x15\xaf\x8b\xf3\x34\x04\x88\xf8\xcd\x58\xf0\x9a\xe1\xa6\x61\x6b\xf8\x5a\xc9\xde\x7e\x0c\x66\x96\xaa\x2f\x1b\xec\x15\xe1\x7a\x44\xda\x4a\x84\xed\xb4\xec\x6d\x77\x24\x77\x88\xba\x0d\xe3\xae\x12\xa1\x55\xcb\xed\xc0\xda\x2f\x56\x8e\xef\x0b\x75\xa8\x77\xea\x5b\x0c\x2c\x0d\x4b\xf2\xc6\x1d\x46\x8a\x46\xfa\xad\xfa\xec\xe3\x5f\xc2\x63\xa9\xbe\x99\x87\xf4\xf7\xf7\x8f\x05\xc7\x07\x78\x43\x78\xc7\xb8\xf7\xda\xf9\xac\x3a\x12\x2a\xad\x39\xa1\x67\x79\x66\xda\x9e\xf2\x86\xc9\xe0\x62\xc4\xf4\x39\xad\x0b\xdd\xea\x26\xe5\x4b\x2f\x73\x88\xe2\x38\xb2\xa6\x49\x28\x45\x0d\x34\x56\x4c\x5a\x44\x7e\x7a\xfb\xbe\xdd\x10\x85\xf1\xf2\x4c\x11\xae\x08\x43\x22\xd1\xa3\x2c\xf8\xaa\x47\x39\x41\xf0\x0d\x56\xb1\x61\x82\x13\xca\xb3\x90\x0a\xa6\x06\x46\x3d\x9f\x80\x0e\x92\x6f\x9f\x42\xd4\xb0\x82\xd8\xc5\xec\x3a\x4a\x02\x5b\x45\xf9\xaa\xdc\x8b\xcb\xd1\x70\x91\xb3\xda\x49\xe9\x45\x3d\xc5\x5e\x89\xb5\xb5\xfe\x6b\x31\xf5\xed\xda\xd1\x0b\x66\x01\x57\x25\x68\xd8\xe2\x05\xd3\x25\x1a"}, +{{0x6b,0xf4,0xca,0xaa,0xbb,0x96,0x85,0x4a,0x38,0xa5,0x72,0xf4,0xce,0x6c,0x78,0x38,0xf7,0xe7,0x50,0x11,0x8c,0x73,0xf2,0x72,0x35,0x82,0x61,0x8e,0x23,0x07,0xf8,0x38,},{0x08,0x12,0x63,0x73,0xd0,0x56,0xf0,0x0e,0x54,0xb8,0xd4,0x3d,0x77,0xc3,0x5f,0x5f,0x91,0x98,0x33,0xe9,0x0d,0x8a,0xaf,0xd6,0xc8,0x24,0x6d,0x27,0x91,0x7a,0xd0,0x91,},{0xd2,0x11,0x3f,0x80,0xd6,0xcf,0x92,0x84,0x86,0xa2,0x50,0xa6,0x79,0xd6,0xe7,0x4b,0x35,0xea,0x9d,0x26,0x06,0x1f,0xa9,0x4d,0x76,0x9e,0x1a,0x8f,0xbf,0xa0,0xa7,0x34,0x22,0x7f,0x55,0x53,0x7e,0x4e,0xbf,0xf5,0x93,0x36,0xdb,0x14,0x1c,0xf5,0xd6,0xd4,0x82,0xa0,0x71,0x1f,0x1e,0x9f,0xc7,0x2f,0xf7,0x09,0x56,0xa1,0x1b,0x4f,0xb9,0x09,},"\x47\x76\xe9\xd6\x00\x85\x48\x1f\xa5\x37\xbf\x29\x5b\xda\xbd\x8b\x1c\xf6\x32\xa8\xcd\x40\xbc\xe6\xbd\x32\x5c\x12\x9f\x97\x70\x00\xe8\x84\x68\xeb\xf2\xdc\x15\x8a\xc0\xf2\x07\x21\x2d\xb0\x0f\xb6\x0b\x8e\xc8\xba\xe2\x29\x37\x2e\x9a\x6b\x01\x53\x0a\x7e\xd1\xbc\x9d\x38\x9e\xc8\x91\x3f\x59\x03\x0d\x5b\x54\xaf\x56\xae\x1c\xcc\x28\xf3\x7c\xc9\x6a\x8e\x53\x20\x4e\x92\xa6\x77\x76\x6a\xdf\xaa\xda\x99\xb0\x28\x1f\x86\x7f\x61\xac\x9f\xf7\xd9\x72\xee\x3e\xd4\x27\xd7\x2f\xaa\xe7\x5d\x4a\xec\x01\xb5\xff\xc3\x70\x61\xb6\xf0\xf7\xe5\x71\x4c\x4c\xf3\x0d\x5b\x73\x1b\x07\x46\x06\x5f\x19\xe4\xc8\x92\x2d\xde\x64\x2f\x80\xfe\x24\xa3\xc8\xdc\xb2\xe5\xf1\xc2\x66\xe2\xaf\x6c\x37\xde\xcf\x55\xa2\xba\xa5\x4f\x0d\x5c\xf0\x83\x93\x70\xc3\xe0\xb4\xe7\x7a\x4f\x36\xbb\xb3\x16\x20\x14\x93\x3a\x4a\x4e\xbc\xae\x8c\x60\x96\x1a\xc6\xdc\xf1\x34\xf3\x08\x28\xd3\x14\x02\xae\x74\xe7\xe8\x51\x3c\x9d\x2a\xd8\xee\x46\xb7\xa9\xd5\x3a\x1f\x87\xeb\xfc\xe0\x4f\x46\x1b\xde\xd1\x74\x9b\x6f\xc4\xc4\xf2\x57\x93\x52\x56\x92\xd7\xa0\xe4\x26\xc8\x4e\x06\x08\x2c\xc3\xe6\xab\xb5\x13\x68\x37\x0c\xbb\x10\x6c\x7a\x08\x97\xf6\x6d\x92\xc9\x73\x9c\xff\x9f\x27\x06\xd6\xa2\x98\x0e\xce\xa3\xac\x49\x45\xf0\xf4\x7e\x65\x6b\xd9\x63\x77\x77\xe8\x53\xd2\xa8\x39\x10\x43\x27\xdc\x04\x9e\xbc\x34\xf0\x49\xd6\xc2\xf8\x0e\xca\x99\xdb\x7b\x41\x84\x24\xac\xef\x75\x22\x60\xd2\xd4\x27\x94\x93\x23\x99\x7c\xd9\x61\x7e\xdf\x50\xd4\x41\xd0\x08\x8b\x1d\x47\x91\x2e\x35\xcf\x54\x23\x15\x26\x58\x29\xf3\x83\xf4\x58\x60\xd3\xb4\x5e\x73\x5b\xb2\xf8\x58\x6d\xcf\x58\xdb\x4f\x2a\xcf\xb4\xa6\x88\x53\xa9\x6e\xed\x7b\x89\x76\x9d\x36\x56\x13"}, +{{0x5d,0x95,0x85,0x73,0x6a,0xb2,0x09,0xb0,0xab,0xe8,0xbf,0x74,0xac,0xa4,0xee,0xa4,0xf6,0xd1,0x65,0x0b,0x53,0x25,0x50,0xa2,0x23,0xe0,0x44,0x58,0x0f,0x8e,0x20,0xde,},{0xe7,0x77,0x29,0xed,0xfd,0x21,0x44,0xb2,0xb1,0x20,0x78,0x76,0x54,0x17,0xfa,0x21,0xf1,0x59,0x4f,0x09,0xb2,0x69,0xe9,0xb6,0x70,0x68,0x02,0xb4,0xf3,0xbd,0xfe,0x85,},{0xe7,0xb0,0x8e,0x1d,0x58,0x09,0xfd,0xd8,0x52,0x94,0x43,0xd6,0x5a,0xda,0x5d,0xd6,0x55,0xea,0x55,0xb5,0x41,0x5a,0x01,0x13,0x93,0xbe,0x70,0x71,0x67,0x64,0x86,0xd3,0x58,0xe8,0xd2,0xa4,0x60,0xeb,0xe0,0x75,0xb0,0xe7,0x01,0xb2,0x4c,0x9e,0x3a,0xb5,0xf2,0xb0,0x33,0x59,0x2d,0x4d,0xe3,0xb7,0xf3,0x7f,0xd5,0x41,0xf6,0x92,0x09,0x09,},"\x08\x69\x35\x91\xe6\xc5\x8a\x5e\xad\x9c\x85\xfe\x8e\xc5\x85\x08\xf8\x1a\x34\x67\x63\x6c\x2d\x34\xfc\xc1\xf4\x66\xe5\xc6\xda\xfd\xc3\x7c\x35\xcb\xee\x35\x58\x9c\x69\x97\xe2\xb1\x54\x48\x13\x27\x44\xe5\xa1\xe1\x31\xbb\x49\xbf\x5c\x25\x63\xf8\x7e\xad\x3e\xfe\x01\xe8\x8c\xbf\x24\xcc\x17\x69\xc7\x8c\xdf\xc1\x67\xe3\x78\x21\x5b\x15\x85\x9c\x7a\x28\xec\xe7\x0e\x18\x8f\xa3\x30\x26\x7d\x3f\xc5\x7b\x4a\xce\x6c\x15\x20\xec\x67\x87\x50\x67\xfd\x33\xbe\x86\xf4\xa1\x96\x7a\xfb\x3e\xb1\x64\xc7\x97\xcf\x28\xd8\x07\x2a\xa6\x9d\x82\xaf\xa3\x83\x74\xf8\xe5\x79\x7c\x4c\x28\x47\x1b\x7d\x69\xf5\xb9\xc7\xb4\xac\xdb\xc1\x9f\x3c\x5c\x5d\x40\x08\x08\xa9\x82\xa4\x78\x37\xae\xd1\xb3\x84\x1d\x69\x89\x0e\xeb\x31\x49\x4e\x10\xe3\xe5\x13\xd1\x2d\x0c\xa6\x86\xc7\xce\x65\x17\x78\x09\x27\x03\xfe\xf0\xdc\xc0\x21\x40\x77\xdf\xb3\x61\x25\x1b\xde\xa4\x36\x4d\xd4\x1b\x97\xbc\xeb\x0f\xb1\x47\x5a\x50\xe4\x70\x8f\x47\xf7\x87\x8c\x74\x40\x1e\x97\x71\xcc\x3f\xce\xac\xe8\x91\x69\x98\x1a\xa7\x72\x50\x85\x00\x90\xd1\x81\xd8\x35\x8e\xbb\xa6\x5e\x29\x0a\xcb\x03\x52\xbe\xce\x8c\x57\x98\x32\xa6\x01\x55\x18\x16\xd1\xc0\x56\x21\xcc\xbb\xee\x0f\xbe\x39\xea\x2f\x19\x53\x93\x19\x9e\x69\xc2\x34\xc2\xfb\x1c\x37\xe4\x74\x84\x08\x60\xce\x60\x91\x61\xfc\xfc\xe2\x86\x95\x74\xbe\x0d\x38\xf9\x5e\x20\xf4\xf8\x72\x52\x47\xb9\x62\x7b\x46\xe8\x34\x90\x51\x01\xac\x12\xb9\x34\xcb\xf8\x7c\xb2\xd1\x90\xd2\xf5\x14\x90\xa8\x2c\x4e\x81\x0e\xdd\xb8\x1f\x95\x6a\x9f\x36\xbd\xa4\x97\xbc\xa5\x06\xa4\x9e\xe9\xcd\x47\xfd\xa5\xb7\xf2\xb8\x84\xa3\x64\x8c\xad\xd1\x2a\xb6\x18\x98\xad\xa4\x6e\xcc\x97\x0f\x81\xdc\x9f\x87\x68\x45\xdb"}, +{{0x60,0xb1,0x42,0xf1,0x65,0x11,0x41,0x43,0xca,0x30,0xa6,0x04,0xfe,0xf5,0x1c,0x68,0x64,0x36,0xaa,0x1b,0x9a,0xfd,0xb2,0x66,0xb3,0xe3,0x98,0xcc,0xb3,0xc4,0xd8,0x55,},{0xea,0xf6,0xc5,0xa7,0x6c,0xa9,0x9b,0xf7,0x30,0x64,0x98,0x88,0x8c,0x3b,0x7a,0x1f,0xea,0xe9,0x8b,0xf8,0x98,0x8d,0x7f,0x2e,0x15,0x47,0xf8,0xf5,0x3a,0x45,0x28,0xaa,},{0xa6,0x21,0xf0,0x84,0xea,0x1a,0x36,0xef,0x81,0x2a,0x97,0x55,0xc9,0xaf,0xbb,0x53,0xda,0xda,0xae,0x6b,0x3a,0x53,0xfa,0x83,0x44,0xca,0x40,0xd3,0x61,0x2a,0x26,0x8a,0x35,0xfe,0xd0,0xfd,0x39,0x8a,0xb7,0x5b,0xcd,0x63,0x9c,0x54,0x79,0x37,0xc9,0x41,0x55,0xab,0x1a,0x7a,0x34,0x67,0xdd,0x4b,0xfd,0xdf,0xac,0xab,0x16,0x55,0xe9,0x08,},"\x18\x15\xde\xe1\x17\x3b\x78\x26\x47\x20\xd3\x5b\x7c\xc2\x45\x4a\x00\x0a\x65\xff\xf2\x14\xe2\x47\x3e\x20\xbc\x83\xf3\xec\xde\x9c\x04\xc1\xe0\x69\x6c\xe6\xe5\x55\x19\xdd\x2a\x75\xce\x04\x64\xbf\x60\x1a\xdc\x38\x1e\x79\x3e\xcb\x9f\x8c\xe7\xab\x87\xb6\xca\x2a\x3e\x41\x0f\x63\x90\x69\x45\x19\x78\xd1\x48\x73\xd3\x39\x0f\xab\x86\x23\x96\x97\x13\xc3\xdf\xcd\x58\xd8\x6d\x12\x40\x73\x76\x1e\xe0\x9a\x65\x2a\x48\x76\x7f\x96\x46\xcb\x72\x6a\xc4\x54\xac\x9a\x1b\xc5\xfa\xed\x30\x26\xb7\x03\x98\x2b\xc2\xb1\xe0\x75\x82\x10\xe1\xd6\x25\x19\x23\x0e\xb2\xb2\xf4\xa4\x86\xbc\x55\x16\x85\x60\xc4\x36\x3d\xf5\xff\x5a\xdf\xda\x11\xac\x7e\xf5\x1b\x18\x19\x6c\x94\x33\x7c\x07\xae\xf1\x17\x99\x0f\x77\x0c\x0f\x1e\x8c\x0f\x88\xeb\x6f\xfc\x40\xe8\xed\x7c\x3a\x80\xa6\x32\xdb\x1e\x7f\x63\xb6\x30\x96\xe2\xac\x49\xe5\x77\x92\xb3\x11\x43\xe2\xf4\xfa\xab\xce\xae\x66\xb2\x74\x71\x68\x1c\x36\xfc\x11\x39\x00\x7f\x9b\x54\x8c\xdc\x6e\x3b\x8f\xbb\xda\xba\x7a\x8a\xdb\x84\x34\x31\x23\x8b\xb4\x61\xba\x24\xf6\xe0\x9f\x62\xc7\x2d\x63\x77\xb4\x04\x8c\xb0\x13\x4c\x25\xa5\x41\x1a\x20\xbf\xcf\xc1\x3e\x48\xd8\x0e\x36\xbf\xb0\xda\x7e\x01\x85\xd3\x3f\x19\x28\x63\x6e\x15\xde\xe0\xe5\xdf\x89\x92\xa1\x65\x72\xb1\x3e\xa8\xf7\xcf\x85\xca\xe3\x2d\x52\x9f\x66\xe8\xf6\xd2\xfb\x2a\xd0\xbb\xfe\x71\x99\x16\x9b\x25\x67\xba\x00\xc7\x81\xb2\x0a\x48\xe1\xd7\x0d\xf9\xfa\x31\x19\xcd\x7e\x5b\xbe\x58\x88\x4b\x0b\x51\x21\x89\x40\xfa\x81\x5f\x85\x62\x5f\xa2\x03\x47\x1c\xee\x80\x84\x78\x0e\xb0\xb9\x35\x6f\x9f\x3d\x4f\x6d\xf7\x40\x30\x1d\x70\x7e\xf1\xff\xb3\x51\x9e\x3f\x90\xb8\x06\x4b\x98\xe7\x0f\x37\x5d\x07\x14\x26\x88\x17\x18"}, +{{0x73,0x4b,0xa4,0x70,0x33,0xc6,0x14,0x02,0x32,0xdd,0x4a,0x7a,0x14,0xf1,0xa7,0x74,0x3e,0xef,0xe9,0x07,0x0b,0xad,0x96,0x62,0x49,0x16,0x30,0xcc,0x9d,0x28,0xc1,0xf3,},{0x2f,0xa5,0xdf,0x30,0x26,0xd6,0x07,0x42,0xe2,0xaf,0xf6,0xb5,0x78,0x42,0xc7,0x12,0x68,0x46,0xc8,0xa7,0xbb,0xe9,0x26,0x6e,0xfa,0x7b,0x3f,0x23,0x98,0xc3,0x57,0xea,},{0x9b,0xd0,0x74,0xd1,0xd0,0xbd,0x28,0x00,0x1b,0xaf,0x7d,0x2d,0x4e,0x82,0x43,0x5d,0xf0,0x8c,0x42,0x64,0xd8,0xcb,0xb1,0xc3,0x81,0x18,0x3c,0x2f,0x01,0x22,0x3f,0x79,0xf9,0x49,0x23,0xca,0x17,0x8c,0xac,0x75,0x56,0x4e,0x16,0xc7,0xf5,0x60,0x79,0x08,0x8f,0x7e,0xd8,0x85,0xde,0x4d,0x50,0x9f,0xbc,0x78,0xf4,0x38,0xfb,0xa3,0xf6,0x07,},"\x5d\x3c\x65\x98\x10\xc3\xfe\xa5\x2a\x6d\xf3\x86\x1e\x5c\xdc\x5b\x70\x3c\xc1\xce\xf4\x85\x58\xc6\x1d\x8c\x51\xd0\xed\xea\x5a\x14\x79\xcf\xe5\x06\x3d\x82\xde\xd9\xca\x68\x1e\x57\x48\x88\x7c\x40\xec\xfb\x9e\x1a\x9a\x8b\x7f\x85\x09\xd1\x07\x76\x46\x1c\x39\x23\x39\x96\x93\xa7\x81\x89\x08\x91\x78\xd5\xaa\xbd\x15\xf8\xc8\x46\x64\x2b\xe4\x7d\x6d\x4c\xaf\x13\x82\x4e\xdc\xef\xb8\x09\x86\x8f\xa7\x2d\xdf\x03\x5c\x4d\xe8\xef\x0a\x9c\x83\x22\x64\xf6\x6f\x01\x27\x61\xce\x69\x55\xbc\x3c\x41\x6e\x93\xe2\x91\x88\x02\x5e\xbb\xb1\x3a\x55\x32\x58\xc1\xd7\xc4\x99\xc9\xa4\xae\xb1\x0b\xb3\x6f\x61\xd1\xbb\x4c\xec\x5a\xe5\x5d\x17\x57\x22\xb9\xa9\x69\x6d\xf8\x81\x95\x1e\x35\x20\x0b\x96\x53\xcf\x6e\xd4\xb3\xd1\x5d\xe0\x87\xa9\xd1\xc3\x19\xfc\xe8\x58\x21\x56\xbe\xbf\x3f\xc9\x1e\x0e\x61\x0f\xf7\xa1\x53\x08\xfd\x1d\x2c\x60\x69\xfb\xbb\x29\x47\xd3\x11\x07\x31\xd2\x45\xae\x29\x63\x01\x4b\xd7\x6d\xea\x42\xdb\x12\x5c\xec\xc4\x93\xc8\xe9\x09\x1a\x76\x64\x65\x77\x72\x9a\xed\x49\x66\xfc\xe9\x69\x9f\xe1\x2e\x36\x7d\x66\x5d\xf9\xe9\x5a\x91\x93\xe1\x13\x3e\x14\x3a\xf9\x2f\x82\xb6\x6a\xc7\x76\x4e\x50\x33\x17\x86\x90\x52\x18\x09\xa7\x10\x7d\x8a\xe9\xb8\x8e\x0e\xd1\xf3\x5b\x17\x19\x90\x1b\x93\x0a\xd0\xe1\xcb\xce\x7f\xb3\x02\x67\xb1\x15\x52\x04\xf6\x05\xf5\x25\xe4\x9d\xe2\x98\x8e\xa7\xf7\x4b\xe8\x81\x51\x77\xfd\x97\x6a\x1b\xcc\x12\x6d\x9c\x9c\x13\x5c\x5b\x42\x76\xd3\x80\x19\xc3\x4a\xef\xb7\xa0\x22\x0f\x7f\x5a\xef\xf3\x80\xae\xd6\x27\xb0\x70\xc2\xc9\xe2\x15\x33\xbb\x35\xc0\x8e\x39\x4c\x85\xae\x25\xe6\x86\x29\x42\x59\x9c\x65\xdb\xae\x59\x77\xa5\x84\xa8\x81\x80\xe0\xc8\xc7\x1e\x5a\x84\x09\xe0\x4e\xf7"}, +{{0x45,0xe3,0x4d,0x0e,0xf4,0xc1,0x96,0xfa,0x6d,0x57,0x2b,0x6b,0x17,0x74,0xb5,0x21,0x8f,0x7c,0x32,0x91,0x30,0x4c,0x13,0x50,0x0d,0xf7,0x07,0x0d,0x90,0xe8,0x03,0x9e,},{0x13,0xa7,0x30,0x4d,0xff,0x42,0x33,0x59,0x17,0x7a,0xba,0xfa,0x5e,0x65,0x08,0xd2,0x67,0x69,0xca,0x99,0xcf,0x8a,0xf4,0x5c,0x38,0x3f,0x3f,0xf6,0x34,0x40,0x60,0x03,},{0xb4,0x2c,0x1f,0x92,0x5f,0x4b,0xac,0xcd,0x12,0x9e,0xfb,0x10,0x9d,0xb3,0x54,0xac,0xa3,0x1c,0x68,0x98,0xf4,0xf4,0x51,0x29,0x47,0x49,0xa2,0x6a,0x6d,0xa1,0x67,0x7b,0xd3,0xa5,0xc0,0x41,0x19,0xe3,0x5f,0x47,0x31,0x9f,0x20,0xcf,0xdf,0xc0,0x8b,0xb4,0x52,0x8b,0x21,0x00,0x9e,0x00,0xbd,0x41,0xeb,0xc0,0xf4,0x68,0x63,0xbe,0xd1,0x0b,},"\x3d\x9e\xd5\xc6\x4b\x75\xe1\x35\xdf\x2f\x5e\x85\x30\x0d\x90\xf2\x1b\x36\x39\x35\xe2\x81\x75\x56\xfc\x93\x11\x75\x1b\xa7\x53\x54\x77\xde\xc8\x35\x6e\xc3\x85\xef\xb8\x2b\x41\x40\x62\xf3\x5b\xb6\xd3\xed\xea\xfd\xe3\x05\xf9\x90\x0a\x25\xe9\x81\x3c\x9e\xe0\x23\x7d\x46\x40\x96\x50\xcd\xcd\xb5\xdf\xa2\x30\x1a\x8e\x26\x47\xf8\xd3\x81\x9d\x86\xf7\xb7\xe3\x07\x0d\x33\x44\x0f\x82\xc4\x05\x4b\x1a\xb5\xed\xeb\xeb\x27\xf9\x5b\x3c\x4c\x6f\xdd\x46\x8f\x21\x60\x0f\x03\xb3\x49\x4d\xa2\x00\xba\xb9\x29\x3c\x38\xd0\x2f\xc4\x40\x48\xe5\x2f\xf5\xfd\x0f\x72\x17\xa0\x4d\x4c\xe9\x12\xa1\x80\xd1\x62\x8f\x36\x82\x80\xb6\x89\x26\x72\xe8\xff\x98\xd4\x62\x9a\xc2\x8b\x60\xc0\x2a\x30\x1e\x6c\x60\x26\xc1\xb9\xe9\xef\x21\xcf\x03\x92\xdf\x22\x50\x08\xd5\xa0\xe0\x28\x4b\x28\x26\x31\xad\x17\x10\xf8\x11\x61\x56\x97\x06\x6c\x98\x29\x65\x19\x94\x8a\x7c\xfe\xd5\xae\xeb\x45\x4e\xe7\xa6\x1c\xc2\x71\xbd\x3d\x49\x9b\xe1\x7d\xf0\x9d\x3a\x0e\x79\x0e\xe6\xb9\xbd\x99\xe1\xb9\x19\xbe\xd4\xa0\x63\xb8\xd1\xa3\x4f\x1a\xfd\x2e\x95\x2b\x9d\xfe\xfd\x77\x09\x69\xc8\xb2\xfc\x37\x97\x7a\xbb\x0f\xee\x63\x17\x25\x3a\x23\xec\xc9\x75\x78\x16\x89\x73\x33\x4c\x8f\x91\x76\x3a\xb9\x7f\x29\xc4\x9b\xae\xee\x7b\x35\xf3\xae\x7f\x5c\xd3\xa4\xa6\xe6\x97\xef\x25\x5a\x3c\x2e\xc0\xc7\x52\xa3\x39\x6f\x69\xf6\x63\xca\x1f\xc2\xb3\x32\xdf\xe6\xc0\xfa\xf7\x8a\xfe\x9c\x68\xd9\x95\x71\xe8\xe8\x96\xc5\x09\x30\x85\xe9\x86\x3a\x27\x64\x8a\x9e\x58\xf3\xa9\xa8\x4c\xbb\xfe\x2b\x41\xca\x36\x33\xdd\x5c\xf6\xe8\x2c\xb7\x7c\xec\xac\xad\x8d\x78\xb3\x53\xf4\x8d\xb4\x2d\x99\xc3\x6b\xca\xd1\x70\xea\x9e\x98\xab\xb2\x78\x8c\x33\xa3\xc7\x06\x26\x8f\x36\x31"}, +{{0x88,0x8c,0xe2,0xec,0xce,0xda,0x9c,0xa2,0xb9,0x48,0xac,0x14,0x43,0xc2,0xae,0xdd,0x75,0x95,0xaa,0xcf,0x36,0xed,0xaf,0x27,0x25,0x5b,0xde,0x7a,0x69,0x91,0xdc,0xc0,},{0x01,0x6e,0x57,0x2b,0x4f,0x98,0x41,0x7c,0x6e,0xe2,0x97,0xab,0xd7,0x84,0xea,0x48,0x22,0x6f,0xf4,0xfb,0xf0,0x05,0x0a,0x5a,0xde,0x88,0x06,0xe7,0x04,0x6d,0x3b,0xa3,},{0x99,0xd8,0x3f,0x14,0x8a,0x23,0x6e,0xbb,0xef,0x1c,0xad,0x88,0xcb,0x3c,0x76,0x94,0xf4,0x98,0x6c,0x92,0x50,0xe2,0x1c,0x36,0x03,0xa0,0xd9,0x41,0xbf,0xf1,0x99,0xcf,0x77,0xd6,0xce,0x99,0xef,0xdb,0x20,0x53,0x31,0x88,0xd6,0x8a,0xd1,0x33,0xde,0x03,0x3a,0x1f,0xb3,0x46,0x8a,0xbb,0x70,0x6d,0x2b,0x8b,0x4f,0xba,0xc0,0x8d,0xfe,0x03,},"\x5c\x80\x1a\x8e\x66\x4e\x76\x60\x76\x0a\x25\xa5\xe1\x43\x1a\x62\x15\x9f\xc3\xf3\xaa\x71\x37\x80\xae\x7c\xbc\xe2\x3b\x85\x64\x78\x27\x99\xbf\x2b\xe4\x81\x7e\xe2\x92\x19\x65\xba\xb7\xe1\xd4\x48\x33\x82\x4c\x16\x28\xd4\x2d\xce\xe3\xe4\x6a\xe4\x2b\x28\x16\xd0\xa4\x32\xa1\xab\x0b\xd2\x1f\xcf\x30\xad\xb6\x3d\x8d\xd7\x65\x69\x54\x43\x43\xd0\x03\x5c\x76\x05\x22\xca\x68\xbe\xa7\x2c\x40\x4e\xdd\xa1\xe9\x09\x5e\xc9\x0f\x33\x25\x68\x1c\x6d\xe0\xf4\xc1\x2d\x1a\xfb\xcb\xa2\xc7\x87\x1a\x1b\x1e\x1f\x19\xc3\x5b\x0b\xed\x9e\xc2\xa8\x7c\x04\x3d\x36\xd8\x19\x39\x6b\xd5\xd0\x99\xe1\xaa\x09\x03\x91\x29\x7c\x73\x3f\x65\xa8\xc5\xd2\x12\x0c\x67\x63\x53\x16\xfa\xb2\x5b\x4d\x48\x47\xa4\x5f\xc3\xf7\x6f\x2e\x24\x26\xdb\xee\x46\x29\x97\x50\x62\xfc\xe1\x4e\x21\x89\xdb\xa2\x7f\xb1\xde\xd2\x45\x3f\x00\x1d\xeb\xfa\xa8\x99\xc1\x16\x60\x61\x2d\x2c\xe2\xad\x2f\x76\x2e\xa5\xde\xe7\xe7\x1e\x58\xad\xcd\xce\xfa\x79\xe8\xe8\xb2\x7f\xc4\xcc\xf8\x9a\xab\xf1\x76\xb5\xd3\x4f\x82\xdd\x15\xd8\x89\xf9\xf0\x87\xdc\x9a\xe8\xa4\x2a\x72\xf3\xb8\x35\x83\x61\x6e\x17\x06\x37\xcd\x1a\xdf\x38\xaa\x65\x51\xcb\xac\xca\x36\x02\xbd\xc7\xae\x21\x0c\x4a\x44\x6b\x3a\xf8\xdb\x27\x20\xe5\x49\xbb\xed\xb8\xbe\xd2\x15\xae\x00\xf1\x9d\xa2\x9d\x8f\xb0\xb6\x42\xd2\x7b\x2d\x88\x57\x5f\x0e\xe8\x4f\x3d\x12\x9e\xb7\x74\xd2\x0f\x53\x7a\x1c\x0f\xdc\xf7\x17\xbd\xeb\xcf\xe4\x7f\x83\x31\xa3\x41\x86\x43\x46\xfa\x6a\x1c\x6b\xbf\xd1\x78\x81\x9e\x38\x7a\x0d\x54\x99\xa6\x8e\x81\xcc\x9f\x82\xad\x39\xe3\x1e\x4d\xfe\x71\x95\x2d\x5e\xa5\xcc\x80\x52\xa3\xce\xed\x17\x51\xf5\x9d\xc7\xec\xc9\x74\x2f\xad\x14\x4e\x18\xdd\xa8\xd0\x58\x2e\x74\xe3\x9c\xa8\xc4"}, +{{0x61,0x73,0x90,0x85,0x7d,0xc1,0x0c,0xdf,0x82,0xb5,0xc9,0x42,0x61,0xf5,0x8c,0xe2,0xd4,0x4a,0xa2,0xf5,0x7d,0x29,0x8f,0x08,0xa2,0xd6,0xc7,0x4d,0x28,0x14,0x7d,0xaf,},{0x89,0xe0,0xc3,0xe0,0xa0,0xf1,0x30,0xd1,0x91,0x6e,0x0e,0x38,0x49,0xb7,0x28,0x6f,0xa2,0xe3,0xac,0x4c,0x17,0xbd,0x1f,0x71,0x6e,0xe5,0xa7,0x2f,0x02,0x57,0xfb,0x8d,},{0x63,0xe9,0x0a,0x6a,0xfb,0xbb,0xb0,0xee,0x69,0x6b,0xfb,0x56,0xef,0xd6,0x79,0xd6,0x8a,0x98,0x51,0xa8,0x94,0x76,0x40,0xa9,0x7f,0x41,0xf6,0x8e,0xdf,0xea,0xdd,0x21,0x6e,0xd8,0x69,0x8e,0x2e,0x43,0xc8,0x20,0xc9,0x04,0x4c,0xaa,0x7a,0xda,0xab,0x5b,0x76,0x76,0x2b,0x68,0x18,0x31,0xa9,0xf7,0x60,0x47,0x6a,0x84,0x43,0xc4,0x3c,0x06,},"\x1f\xd9\xe7\x45\x3e\xaf\xfd\x7c\x9b\x54\x05\x56\x22\xdd\xe1\x70\xdd\x58\xb7\x1c\xb9\x45\xde\x75\x35\x1d\x5f\xce\xb1\xf5\x36\xbd\xe2\x51\x58\xf0\x37\x86\x15\x5f\x95\x3d\xc2\x07\xa1\x70\x8f\x90\xd9\x5b\x15\xac\xa0\xae\xe3\x09\x7f\xdc\xaa\xe8\x5e\x4a\xb1\xc2\xcd\xb7\x05\xc5\x3e\x6c\x2e\xd2\x1a\x99\x4b\x30\x4a\x75\xca\xf2\xce\x4f\xc7\xd6\x1f\x56\x1e\x74\xe2\x97\x39\x7e\x2c\xde\x5c\xc6\x90\x56\x94\x03\x43\xaa\x81\x37\x5d\x0a\xf1\x8d\x17\xd2\xf3\x4c\x0a\x71\xdc\xf1\xde\x3c\x4f\xc4\x88\xa1\x4c\x5f\xa6\xb3\x33\x7a\x31\x74\xb1\xda\x79\x58\xfb\x00\xbd\x59\x55\x14\x82\x21\x42\x7c\x60\xdb\xa0\x41\x17\xc8\x0d\x24\x88\x65\x6d\xbd\x53\x43\xde\x89\x12\x87\xb5\x0e\xf4\xdf\x98\x25\xed\xa7\x6b\x49\x77\xf3\xac\xd4\xab\x6d\x31\x02\xfa\x56\x87\x83\x06\xcd\x76\x56\x14\x91\xbc\xfd\xaa\x1d\xa5\x67\xe6\x77\xf7\xf0\x3b\xae\x5d\xbf\x44\x26\xc3\xc4\xa6\xc3\xd0\x82\xf9\x17\x8b\x2e\xfd\xd2\xbd\x49\xee\xe9\x7e\xf4\xdc\xf3\xf0\xf5\x1b\xbd\xef\xfe\x5a\xe6\x60\x1e\x28\x01\x95\x18\xf8\x27\xf0\x2e\x51\xf6\x67\x9b\x87\x15\x97\x8b\xec\x3e\x69\xd5\x77\x15\x6d\xd7\x19\x95\x93\x71\xba\xf0\x34\x21\x9f\xbb\xd1\x7a\x23\x69\xa8\x54\x14\x90\xf6\xa0\x20\x13\xe3\x3e\x74\xf4\x76\x9b\xe3\x7a\xef\xa4\xde\xfb\x6b\xfb\x3f\x35\x1c\x2a\x26\x14\x82\xc2\xfb\xec\x49\xf8\x5f\x84\x45\x45\x6e\x8f\x5a\x47\x40\x30\xcd\x72\xd0\x95\xef\x6a\x62\x20\x30\xe1\xe4\x3a\x0c\x5d\xeb\xb0\x34\x73\x1d\x2f\x5e\x8e\x4b\xa3\x99\x0f\x07\x7d\x0c\x16\x26\x49\xd1\xfa\x3e\xa4\xfe\x1e\x81\xd7\x4a\xa8\x49\xe2\x1b\x05\x9d\x96\x6c\xba\xd4\xc4\x93\xca\x10\xba\xfe\x7a\x69\x24\x3e\x3c\x0a\x6e\xbf\xd1\x3d\x69\x79\x06\x30\x33\x92\xba\x65\xd4\xfe\x06\xb6\xa5"}, +{{0x87,0x7d,0x01,0x74,0x36,0x36,0x9e,0xc2,0x45,0x3f,0xed,0x46,0xe9,0x77,0xd6,0xac,0xc3,0xa7,0xbe,0x60,0xd3,0x13,0x95,0xad,0x6e,0x7e,0xa9,0xe0,0x74,0x80,0xe4,0xc9,},{0x4e,0x65,0x42,0x2f,0xed,0x33,0x4a,0x55,0xe8,0xb6,0x73,0x89,0x3e,0xba,0x7c,0x18,0x1d,0xd7,0x24,0xdd,0xa0,0x02,0x81,0x7b,0x0b,0xae,0x28,0xac,0xdc,0x3f,0x7f,0xc0,},{0x76,0x88,0xf3,0xf2,0x40,0x1e,0xac,0xaf,0x2d,0xd8,0x8e,0x17,0x0f,0xf1,0xc4,0xd7,0xe9,0x48,0x22,0xa7,0x7f,0x6b,0x55,0x0b,0x56,0x9e,0x82,0x15,0x2b,0xbb,0xb4,0x34,0x05,0x7e,0x01,0x23,0x0b,0x05,0xce,0x58,0xee,0x1d,0xee,0x52,0x26,0xb5,0xc7,0xcd,0xbe,0x5a,0x8a,0xde,0x3b,0x94,0x65,0xf5,0x9a,0xed,0x74,0x14,0x5d,0x14,0x33,0x0c,},"\x4e\xd3\xf5\xbd\xbd\x41\xd0\xe3\xb0\xa8\xa7\xfc\x37\x52\xee\xa4\x96\xd6\x14\x16\x78\xcb\xfe\x06\x75\x7f\x61\xe1\xa1\x68\xd7\x61\xb6\xda\x83\x05\x2f\x79\x94\x95\x0d\x24\x62\x6f\x00\x4f\xbe\x9b\x8c\x95\x62\xe0\xc9\x55\xfb\x3b\x5c\x08\xfd\x2d\x3d\x25\x83\x93\xa3\x49\x03\x0c\x8e\x15\x62\x05\xb4\x04\x83\x03\x8b\xe1\x95\x9f\x1c\xba\x49\x0a\x87\xfe\x13\x89\x9e\x4f\x37\x52\x06\x3b\x68\xfe\x3e\x1c\x50\x71\xf7\xdb\x00\x02\xf0\x14\x94\xb4\xa3\xee\x2e\x07\x99\x2b\xdd\x20\x0d\xb4\x31\x66\x29\xee\x8a\x95\xca\x34\x7f\x0b\x28\xd6\x40\x2a\x6d\xa8\xb5\x3e\x6b\x32\x58\x1c\x36\x91\xe1\x1a\xe9\xb6\xe0\xf0\x49\x48\x94\xe6\x49\xa9\x2d\x03\xeb\x49\xc4\xd6\x83\x3f\xa1\xf5\x4f\x8d\xcd\x91\xd0\x69\x36\xa6\xe6\x2d\x49\x1e\x2c\xea\x46\xdd\x07\xd9\xf0\x2d\x32\x54\xb8\x50\xbc\x97\x49\xf2\x58\xa6\x1a\xd3\xb9\xcc\x24\xb0\x32\x87\x33\x1b\x85\xa2\x41\x43\xaa\xf8\xfc\xcc\xac\x5f\x18\xbf\xc7\x2d\xec\x75\xc0\x23\x35\x16\xaa\x6e\x45\x89\xc7\x8c\x66\x5a\x18\x6e\xd9\x02\x09\x1d\xf9\x7b\x0d\x04\xe8\x3a\x2d\x74\xd7\x89\x89\x1a\xea\x2c\xac\xf8\x13\xff\xfb\x5e\xfa\xf7\x8d\xbc\xd7\xaf\x54\xef\x55\xc7\x7b\x1c\x4c\x8a\xce\x9e\x92\x78\xad\xc2\x3d\x76\xc7\x79\xd6\x4b\x3b\xbb\xd1\xfb\x33\xb0\x98\x36\xea\x64\xa7\x1e\x47\x11\xe8\x9e\x8d\xa0\xf7\x09\x21\x33\x42\x17\x6a\xe2\x2c\x6e\x78\x52\xc3\x97\x3b\x60\xd9\xf9\x88\x89\xb4\x42\xaa\x48\xd7\xbf\xdf\xde\xf6\x4c\x36\xc5\x86\xc4\xfb\x2a\xd2\xe2\x7e\xbe\x47\x9f\x6d\x72\x2f\x06\x9f\xd6\x10\x6b\x0d\x08\x97\x5d\x5f\x72\x15\x47\xc3\xb9\xc5\x2f\x9f\xc5\xf4\x5b\xb4\x5b\x5b\x63\x21\x88\xe8\x06\x26\x51\x8a\x79\x05\x6b\xdc\x4e\xe1\xd2\xbe\x6c\x65\x42\xa2\x1f\xad\xea\x92\xc6\xdf\xb7\x76"}, +{{0x4f,0x0b,0x36,0x07,0xd7,0x0b,0x0f,0x26,0x98,0x32,0x7e,0xf4,0xf1,0x98,0x2c,0x5b,0x4b,0x94,0xbe,0x78,0xf5,0x0c,0x76,0xf4,0x3b,0xd6,0x42,0xf1,0xf0,0xed,0xe3,0x9b,},{0x94,0x2b,0x43,0x08,0x9f,0xd0,0x31,0xce,0xc0,0xf9,0x9e,0x5e,0x55,0x0d,0x65,0x30,0x7f,0xb6,0xc3,0xe7,0x93,0x44,0x9f,0xb3,0x90,0xff,0x73,0x0f,0xff,0xd7,0xc7,0x4b,},{0xf3,0x96,0xa1,0x1f,0x2f,0x03,0xc6,0x14,0x39,0x68,0x4f,0x79,0x00,0x1b,0xd4,0xf3,0x46,0xa3,0x48,0xdc,0xf1,0xd3,0xbe,0xb2,0xd3,0xbf,0xe3,0x3e,0xa7,0x3a,0x5a,0xd4,0xeb,0x97,0x50,0x6a,0xcf,0xbf,0xfb,0x78,0x4e,0x77,0x54,0x81,0x89,0xcd,0x59,0x9f,0x8c,0xcf,0x17,0x35,0x5d,0xde,0x80,0xe7,0x50,0x24,0xef,0x2a,0x78,0xd5,0xfa,0x03,},"\x9f\x70\x0a\x1d\x25\x60\xf6\x9d\x9b\xc1\x05\xbc\x83\xbf\xf5\x39\xe4\x25\x8c\x02\x48\x60\x20\x13\xa9\x59\xb9\x78\xa1\x9c\xc2\x73\x28\x0d\x90\xc0\x17\x80\x89\x57\x8b\x50\x51\x8e\x06\xad\x1e\xab\x79\x0f\xfe\x71\x0c\x63\xd7\x88\x87\xa9\x55\x69\x14\x4f\x3e\x58\xa8\x83\x7f\x93\xdd\x51\x6f\xcd\xdd\x22\xbc\x97\xa7\xf1\x44\x11\xd4\x24\xb2\xe8\xe9\xaa\x7c\x28\x01\x19\xad\x94\xce\x92\x53\x3f\xc7\xfe\xa6\xc6\x62\x48\x64\x4a\xc3\xe1\xbe\xef\x25\x53\xa6\xf6\x1e\x91\xb9\x37\x9b\x0f\xe0\xc6\x8b\x40\x68\x14\x55\xb3\x11\xf4\x0d\xf0\xc9\x7f\x53\xfc\x95\x42\x42\xc3\x75\xe7\x70\x8d\x61\xba\xd9\xf5\x12\x96\x24\x72\x74\xfa\x01\xa7\x32\x8f\xa5\x00\x9d\x99\x95\xf5\x01\xae\x86\x83\x55\x2b\x11\xa4\x9d\x26\x38\x11\x67\x23\xb1\x31\x94\x50\xa9\x01\x38\xd2\x78\xcd\x95\x12\xb8\x0c\xa5\x79\x2e\xd1\x6c\x68\x3b\xef\x92\xec\x87\x88\x4c\x9f\x07\xf1\x37\xdc\x47\xa1\x31\x46\xe5\x11\x06\x5c\x2e\x1b\x4b\x80\xef\xde\x88\xae\x12\xe2\x94\x31\xbe\xb7\xae\xe3\x65\xc1\x6d\x80\x50\x6b\x99\xaf\xa6\xa1\x40\x6e\xdb\x06\x17\x66\x87\x58\x32\xdb\xa4\x73\xe5\x19\xdd\x70\x18\xf4\x02\xeb\x1b\xb3\x01\x4b\x7c\xee\x4f\x02\xe9\x80\xb1\xb1\x71\x27\xe7\xd2\x5d\xfe\x0c\x16\x8c\x53\x44\xf1\xc9\x00\x44\xf8\x27\x70\x7d\xca\x03\x07\x0e\x4c\x43\xcc\x46\x00\x47\xff\x62\x87\x0f\x07\x5f\x34\x59\x18\x16\xe4\xd0\x7e\xe3\x02\xe7\xb2\xc2\xca\x92\x55\xa3\x5e\x8a\xde\xc0\x35\x30\xe8\x6a\x13\xb1\xbd\xfa\x14\x98\x81\x30\x98\xf9\xba\x59\xf8\x18\x7a\xbc\xaf\xe2\x1b\xa0\x9d\x7c\x4a\xaa\x1a\xd1\x0a\x2f\x28\x33\x4a\xb5\x39\x96\x14\x7c\x24\x59\xc0\x1b\x6a\x10\x83\x9e\x03\x01\x12\x3d\x91\xa3\x5c\xed\x7a\xf8\x9a\xfb\xac\x7d\x9c\xf8\xac\x9a\x38\xce\xeb\xef\x83"}, +{{0xb8,0xa0,0x01,0x0c,0x78,0x4d,0x8d,0x00,0x2a,0x31,0xda,0x11,0xd0,0x22,0xd3,0x01,0x88,0xa4,0x19,0x7a,0x1d,0x5f,0x14,0xea,0x4c,0x0d,0xab,0x29,0xa2,0xe4,0x06,0x68,},{0x8b,0xdc,0x63,0xe5,0x0b,0xed,0xe1,0x3c,0x91,0xa4,0x1e,0x4b,0x4b,0x78,0x57,0xb9,0xe5,0x53,0xf4,0x84,0xe3,0xc1,0xec,0x16,0x7d,0xc0,0x4c,0x28,0x1e,0xa8,0x66,0x22,},{0xb3,0xf6,0xcf,0x4c,0x0e,0x0f,0x90,0x74,0xff,0x2c,0x2c,0x47,0xe1,0x63,0x20,0x2f,0x1e,0x9d,0x6e,0xe1,0x17,0xcf,0x75,0x76,0x33,0xe4,0xab,0xe7,0x44,0x23,0xaa,0x70,0x00,0x8a,0xda,0x15,0x09,0xec,0x1d,0xc1,0x17,0xc1,0xc2,0x30,0xe9,0xb2,0x37,0x86,0xf3,0xd0,0xf2,0x9b,0x73,0xaa,0x28,0x45,0x36,0xe9,0x58,0x01,0x06,0xa8,0xa7,0x0c,},"\x5c\x6c\xcb\x29\x8b\xe2\x16\x80\x8b\x81\x1e\x56\xd9\x72\xf4\x56\xb6\x9a\xd3\x95\x94\xee\xe3\x54\x70\x1c\xa6\xb3\xe3\x8d\x1f\x41\xa3\x59\xe5\x51\x2a\xf9\x8a\x3a\x08\x73\x26\x5f\xe5\x19\x1f\x4f\x2e\xca\xf6\x6b\xee\x75\xa3\xac\x0b\x71\xa4\xdd\xf2\xa7\x59\xeb\xdd\xdb\xd8\x8a\x6a\x1c\x6f\xd0\xfc\xf7\xd7\xcb\x92\xa8\x4e\x33\x07\xb4\xa4\xf9\x8c\x71\x0a\xbf\x4f\x55\x3d\xee\x74\xf6\x52\xd2\xac\x64\xbc\x30\xf7\x2b\xf4\x35\x4e\xf7\xe8\x06\xa1\x90\x71\xa0\x51\xbc\xfc\xfb\x27\xe3\x7f\xdd\xd4\x1e\xce\xae\xc1\x75\x8e\x94\x69\x5c\x67\x0e\xf4\xc5\xa5\x90\x21\x78\x32\x9d\xb9\x58\x5c\x65\xef\x0f\xa3\xcd\x62\x44\x9b\xb2\x0b\x1f\x13\xae\xcf\xdd\x1c\x6c\xf7\x8c\x51\xf5\x68\xce\x9f\xb8\x52\x59\xaa\xd0\x5b\x38\xc6\xb4\x85\xf6\xb8\x60\x76\x92\x8d\xdb\x4e\x20\x36\xf4\x5e\x7b\x9c\x6a\x7f\xf2\x4a\xe1\x77\x60\x30\xe2\x57\x68\x25\x01\x9a\xb4\x63\xeb\xf7\x10\x3a\x33\x07\x20\x33\xea\xcb\xb5\xb5\x03\xf5\x32\x66\xaf\xb8\x2f\x9b\x24\x54\xb8\xdc\x05\x7d\x84\xf3\x0d\x9d\x2c\xb7\xc3\xa3\x1a\x7d\xbd\xfb\xa5\xb8\xe4\x92\x31\xc2\x31\x39\x6c\x47\xca\x04\x2c\x8e\x48\xa1\xa5\xe3\xec\x9a\xfe\x40\x20\x59\x53\x90\xf9\x99\x0d\xfb\x87\x4e\x08\x25\xae\x9a\xe5\xe7\x52\xaf\x63\xaf\x6f\xd3\xe7\x87\xe7\x5e\x8d\x8d\xc4\xc6\x63\x02\x27\x7a\xc0\x1b\x30\xa1\x8a\x56\xcb\x82\xc8\xa7\xeb\xdc\x91\x5b\x71\x53\x25\x5a\x1f\xed\xc4\x92\xe4\x96\x60\x26\x2b\xb2\x49\x78\x0d\x17\x3e\x1f\xd2\x0d\x18\xc4\xf6\xb0\xb6\x9a\xa2\xec\xa0\x24\xbf\x3c\x80\xd7\xd5\x96\x2c\xc4\xa1\x29\xa7\x94\x3b\x27\xf3\x3c\xc7\x99\xa3\x60\x45\x54\x12\x75\xa2\xcd\xb9\x2a\x40\xe4\x85\xba\x8b\x73\x7a\x04\xb4\x3d\x29\xc3\xe2\x5f\x76\xcb\x3d\x93\xa6\xb9\x44\x61\xf8\x8f\x56\x96"}, +{{0xef,0xc8,0x6c,0xbe,0x40,0x36,0x3a,0xbf,0xbb,0x2a,0x4b,0x1f,0xcc,0xe5,0xfd,0x60,0x84,0xda,0x96,0xe7,0xe8,0x14,0xde,0x71,0xaa,0xdf,0x9a,0x61,0x8f,0x30,0x36,0x25,},{0x22,0xf2,0x95,0xce,0xe7,0x27,0xd2,0x8d,0x2b,0x93,0x17,0x15,0x3e,0x7d,0x94,0x12,0xda,0x10,0x65,0xc1,0xb1,0x6a,0xe2,0xa2,0x51,0xdd,0x1f,0xb4,0x31,0xc6,0x2b,0x01,},{0xf8,0x81,0x83,0x10,0x22,0x8c,0xa7,0x61,0x11,0x52,0x4c,0xe9,0x4b,0xfc,0xb0,0x24,0x6e,0xa6,0x35,0x08,0xce,0xe9,0x30,0x65,0x92,0xb2,0xf7,0x75,0x48,0xed,0xef,0xcf,0x76,0xbd,0x14,0x54,0x50,0x8e,0xa7,0x15,0x04,0x2c,0xec,0x16,0x9c,0xea,0x51,0x15,0xab,0x54,0x23,0x5c,0xb1,0x09,0x7b,0x10,0x70,0x2a,0xa3,0x83,0x78,0x02,0x8e,0x0c,},"\x9e\x4f\xa4\x5d\xc0\x26\x71\x0f\x6b\xef\x4e\xd0\xf0\x7c\x54\x4b\x0b\xb0\xd8\x8f\xa7\x9e\x71\x77\xd8\x44\x8b\xc2\x09\xd7\x1c\xfe\x97\x43\xc1\x0a\xf0\xc9\x93\x7d\x72\xe1\x81\x9e\x5b\x53\x1d\x66\x1c\x58\xc6\x31\x41\xce\x86\x62\xc8\x83\x9e\x66\x4d\xb7\x9e\x16\xc5\x4d\x11\x3a\xbb\x02\xa7\x5b\xdf\x11\xb3\x45\x3d\x07\x18\x25\xbc\x41\x57\x41\xe9\x94\x83\x54\x6b\x8e\x1e\x68\x19\xde\x53\x01\x70\x92\xe4\xef\x87\x1f\x1c\xa0\xd3\x50\x8f\x93\x78\x28\xa4\x66\x7d\xb1\x1f\xff\xf9\x41\x6e\xeb\xb9\x4b\xf9\xb8\x4d\x65\x46\x03\x09\x48\x34\xa9\x9c\xa7\x0b\x90\xf5\x62\xa8\x68\x23\x62\x4d\xfe\x9c\xb2\xf9\xe8\x8c\x17\x3f\x13\x46\x4d\x4c\xe2\x55\xf2\x22\xdb\x50\xdd\x63\xab\x42\x46\x57\x34\xe7\x52\x95\xc0\x64\xb6\x4c\xc3\xf1\x5e\x62\x37\xe3\x7f\x33\xd6\x15\xf7\xc2\x43\xe4\xba\x30\x89\x60\xcf\xd4\x39\x34\x02\x52\x55\x00\xbb\x79\x02\x97\x0b\x39\x31\xd4\x8b\x35\x66\x6a\x2d\x4d\x2a\xb0\x8f\xa1\x2a\xf3\x66\xa0\x04\x34\x6c\x9d\xd9\x3d\x39\xfb\x1b\x73\x40\xf1\x04\xe5\x1f\xed\xbb\x53\x36\x05\xb5\xff\x39\xcf\x6d\x59\x51\x3f\x12\x85\x6d\xcf\xa1\x98\xd7\x93\xb0\xfc\x87\x5c\xde\xa0\x74\x1f\x14\x55\x74\x6d\x8a\x19\xc3\xe9\xd9\x28\xf0\x02\x1b\x01\xc2\x51\x31\x81\x1e\x48\xc3\xc7\x5c\x6f\x41\x42\x2a\x88\x10\xc6\xc8\x1f\x35\xb4\x54\xee\xae\x8c\xd1\x7c\xf3\xf2\xe6\xf0\xbc\xd9\xf2\x90\x98\x4f\x49\x65\x78\x62\x3a\xb8\xe2\x73\x8d\x2d\x10\x84\x0e\xb9\x1d\x10\x1c\xb4\xa2\x37\x22\xb7\x2e\x3d\xd1\x85\x44\x0c\x3b\x9f\x44\xd4\x6a\x39\x3a\x34\xc1\x87\xa2\x0d\x61\x0b\xb6\x98\xc5\x05\x31\x74\x1e\xfe\x96\x32\x35\x12\x32\x98\x00\x77\x2a\x40\x80\x65\xa7\xef\x8e\x4e\x41\x05\xeb\x1f\x5b\xf6\xd3\xfd\x6b\x21\x7f\xd8\x36\xd8\x9f\x53\xb9\x6f\x45"}, +{{0x33,0x55,0x6c,0x60,0xde,0x2f,0x2c,0x9a,0x93,0x03,0xb9,0x9a,0xdd,0x37,0x85,0x92,0x06,0x05,0x05,0xf8,0xe4,0x98,0x61,0x08,0x5a,0x4b,0x15,0xf0,0x72,0xa7,0xef,0x28,},{0x23,0x1e,0xc8,0xcd,0x84,0x58,0x59,0xf6,0x99,0x61,0x27,0x51,0x19,0xdb,0xe4,0xf7,0x15,0xe5,0xec,0x5a,0xa9,0x8b,0xb8,0x74,0x16,0x75,0xb3,0xc2,0xd0,0xc8,0x9f,0xee,},{0xe0,0x6a,0x7a,0x41,0x44,0x57,0xbb,0xbe,0xf2,0xba,0xc3,0x77,0x5c,0xca,0xd0,0x87,0xda,0xcb,0x1f,0xa4,0xbf,0x93,0x88,0x94,0xe8,0xc9,0x29,0x11,0x8e,0x09,0xe6,0x78,0xdd,0x19,0x93,0x8b,0xc8,0x8f,0x43,0xed,0x0f,0x7d,0x31,0xcc,0x6a,0x0e,0x60,0x2c,0x4e,0x4d,0x1f,0xee,0x33,0xd4,0x1e,0x74,0xa1,0x19,0xfa,0x2d,0x1e,0x4e,0x34,0x0f,},"\x96\xaf\x54\x0e\xa2\xb1\x92\x3f\x5f\xd0\xaa\xd3\x21\xac\x03\x20\x70\xc2\xd6\x5b\xa1\x3d\x16\x4e\x75\xc3\x46\x97\x58\xfc\xf3\x1b\xb3\x16\x55\xcb\x3a\x72\x1f\x9c\xb3\x4b\xe2\xc9\x0c\x77\xeb\x65\xbe\x37\xf6\x06\xd3\x2a\x91\x7a\x4c\xb9\xa7\x09\xac\x07\x05\x22\x99\x30\xef\x6e\xb6\xfd\xb0\xfa\x3c\x0f\xd3\xa9\x0c\xe1\x71\x67\x4e\xe3\xed\x06\x35\x4b\xaf\xc3\xc7\x07\x54\x67\xa5\x74\x45\xb8\x03\x85\x64\x04\x47\x90\x2b\xe3\x92\x62\x89\x4b\x1f\x64\xfe\xa5\x82\x87\xdc\x32\x2d\x19\x87\x59\x72\xa7\xc8\xbe\x91\xd3\x1f\x02\x1c\x70\xeb\x68\x2f\xdf\x11\xa1\x0f\x8f\x58\x2a\x12\x6e\x06\x47\x94\x83\x8c\x69\xfd\xf6\x4f\x5b\x6e\x8b\xa5\x9d\x48\xb4\x38\x4f\x8e\x9f\xb5\xc0\x87\xcc\x77\x38\x29\x5c\xd3\x23\x44\xba\x3b\x69\x7e\xe6\xb6\xa8\xb7\x8e\xe7\xa9\x57\x5c\x97\x97\x2a\x4d\x1b\xb1\x84\x86\xf9\x03\x7a\x0f\x3c\x6f\x47\x1a\x90\xf8\x64\x98\xdb\xc0\xdf\x52\x32\xc0\x7e\x8c\x01\xb6\x90\xbe\xe7\x53\x02\x99\x2a\x7a\x36\xfb\x44\x37\xc2\x5a\x8b\xf5\xe3\x4c\xf7\xd5\xb5\x55\x72\xc7\x00\xa0\x79\x84\x8d\x38\x13\x64\xf9\x94\x6a\x91\xeb\x16\x03\xff\x3d\xe5\xeb\xdd\x52\x3b\xd9\x25\x64\x81\x8e\x23\x7a\x53\xe8\xf5\x22\xde\xaa\x2c\x29\xb8\x97\xe9\x61\x58\x6e\x10\x0e\xd0\xfc\x0a\xd7\x0d\x16\x09\x34\xe6\x94\x02\x7e\x5c\x95\x79\x20\xbc\x05\x46\xe9\x01\xbe\x39\xa8\x45\x35\x59\x7e\x1f\x28\x0c\x22\x22\x67\xab\xe9\x7f\x41\x20\x5d\x81\x71\x82\x0d\xd2\xfa\xaf\xc0\x69\x94\x19\x32\x1a\x91\x60\xf6\x9b\x99\xfd\x41\x18\x09\x45\xb6\x2d\x2d\xd1\x05\xcc\x7b\xbe\x82\x1d\x28\x60\x5e\x09\x8e\xdf\xa8\xb2\x30\x9a\xeb\x05\x34\xe7\x56\x37\x7f\x59\x93\x7c\x67\x46\x3f\xd8\x7c\x8b\x92\xab\x58\x11\x9c\xf4\xce\x6c\x66\x5a\xf5\x72\xfb\xae\x1d\xe4\xa2\xcc\x71"}, +{{0x7a,0x5c,0x74,0x31,0x4e,0x11,0x83,0x33,0x4a,0x4b,0x62,0x26,0xb9,0xa8,0x2d,0x70,0xfc,0x2a,0x12,0x4e,0x3f,0x87,0xdb,0x6a,0x22,0x83,0xee,0x05,0xb6,0x8e,0x34,0xe0,},{0xbe,0xae,0x7d,0x3d,0xd9,0x7c,0x67,0xf6,0x27,0x3b,0xfa,0xa0,0x66,0x13,0x1f,0xed,0x8a,0xce,0x7f,0x53,0x5f,0xe6,0x46,0x4e,0x65,0x79,0x1c,0x7e,0x53,0x98,0x57,0x6c,},{0xc2,0xab,0x1f,0x6f,0x51,0x14,0xa8,0x4f,0x21,0x85,0x02,0x58,0x2c,0x56,0x7b,0x37,0xa8,0xbd,0xbc,0xdf,0x63,0x40,0xfa,0x46,0x22,0x87,0x3b,0xe8,0x91,0x06,0xf0,0xa9,0x0b,0x48,0x29,0x50,0x5f,0x72,0x12,0x9d,0xf0,0xab,0x3d,0x85,0x13,0x26,0x87,0x74,0xa3,0x4d,0xf3,0xad,0x21,0xce,0x25,0x4b,0x46,0x44,0x88,0xad,0xdd,0x6c,0x9b,0x04,},"\x98\xba\xc6\x72\x47\x55\x91\x29\x92\xad\xc2\xa4\x8b\x54\x42\x37\x6f\x2d\x92\x79\x97\xa0\x40\xfb\x98\xef\xe5\x44\xeb\x0c\x8e\x18\x66\xb9\x61\x6e\x29\x8d\x33\x60\x31\x6e\xd9\x76\xbd\x94\x6a\x41\x1f\xdd\x3a\x6b\x62\x5c\x0c\x1a\x37\xaf\x0f\x41\xcf\x65\x69\xa7\x88\x4a\xb8\x46\x74\x91\xa9\x87\xdf\x3e\xa7\xa0\xb7\xeb\xc4\x69\x25\x69\xa3\x4c\xe3\xa2\xea\x35\x03\x49\x5b\x2c\x02\xd4\x9d\x7d\x7d\xb5\x79\xd1\x3a\x82\xcf\x0c\xf7\xa9\x54\x7a\x6e\xae\xbe\x68\xe7\x26\x7d\x45\xa6\x0b\x8d\x47\x72\x45\x52\x28\xcc\xa4\x03\x6e\x28\x2e\x1a\x12\x16\xf3\x4c\xef\x7e\xa6\x8f\x93\x82\x70\xbd\xb0\x42\x93\xc8\x85\xd0\x05\xf9\xf7\xe6\x38\xa8\xb4\xea\xd2\x62\x6c\x09\x45\x17\x4f\xf2\xa3\xe2\xd6\xe1\x5a\x4c\x03\x38\xc0\x9e\x12\x60\xf0\x92\x8c\xa9\xd3\x49\x98\x24\xf3\xfe\xdc\x47\x85\xda\x49\xc5\xc3\x4a\x56\x85\x5e\x24\x1f\xac\xc6\x34\x7a\x39\x9d\xdc\xac\x43\x99\xa8\xb1\x58\x19\x8c\x15\x14\x61\xa3\xb1\x89\xe5\x8e\xc1\xf7\xef\xcf\x2a\xb2\x03\x1f\xb1\x7b\x6f\x03\x5b\xa1\xf0\x92\xe9\xee\xe2\xe9\x2c\x2d\x6c\xc2\x03\x22\x87\xf8\x54\xb4\x1e\x70\xfc\x61\xc8\xd1\x1a\x2e\x4f\x07\x08\xf0\x2e\xeb\xd0\x2e\x8c\x7e\x8c\x7b\x38\xa5\x7b\xfa\x1a\x74\x5f\x3a\x86\xc2\x39\x09\xf6\xf8\x9a\xb1\x6c\xe7\xe1\x81\x3c\x1d\x20\x14\x7f\x31\xb4\xcf\x2a\xd0\xb6\x06\xfb\x17\xe5\xac\x1a\xb5\x1e\xf4\xa7\xd8\x09\x3c\xee\x9a\x65\x5f\x47\x1d\xc5\xb1\x46\xbd\x1b\x93\xe5\x40\xa3\xd3\xd3\xe2\xde\x81\x05\x91\x1c\x10\xd6\xab\x5f\xf7\x9c\x2d\x06\x02\x7f\x7a\x54\x56\x1f\x20\x71\x41\x4b\xd3\x30\xa8\x78\x54\x42\x25\x1c\x81\x0e\x23\x2f\x83\xc3\x67\xf0\xbe\x77\x99\xa9\x3f\x52\x38\xf7\xf1\x7b\x5b\xe8\x29\xfd\x89\x12\x3c\x04\x83\x3a\xf8\xb7\x7e\x5a\x43\x63\x04\x7c\xec\xa7"}, +{{0xda,0x80,0x06,0xad,0xc4,0x92,0xca,0x5d,0xc8,0x6c,0x29,0x59,0x43,0x7a,0x75,0xde,0xb6,0x12,0x0f,0xf7,0x87,0xd2,0xec,0xb9,0xc2,0x0c,0x30,0xb5,0x2c,0x26,0xbc,0x41,},{0xff,0x11,0x3b,0xf0,0xaa,0x58,0xd5,0x46,0xf2,0x38,0x5d,0x44,0x4e,0xcb,0x78,0x88,0xf8,0xca,0xba,0x43,0xa1,0x74,0xa8,0x9f,0xd6,0x06,0x5f,0x2b,0x7d,0xc1,0x7b,0xf0,},{0x1f,0x53,0x75,0xdc,0xb3,0xad,0x2b,0xaa,0xff,0x95,0x6d,0x85,0x54,0xec,0xb4,0x24,0x17,0x6b,0xe9,0xa6,0xeb,0x9e,0xa5,0x4e,0x81,0x4e,0x0a,0x73,0xdf,0x2a,0x5d,0x84,0x8a,0xda,0x26,0xba,0x8e,0x18,0x05,0xcd,0x51,0xc5,0xe1,0x69,0x50,0xc1,0xff,0x7d,0x4d,0x27,0x64,0xda,0xa6,0xf4,0xc7,0x50,0x2f,0xb8,0x65,0xcb,0xe5,0x5a,0xaf,0x0b,},"\x3e\xb4\x32\x4d\xbc\x01\x49\xd2\xe7\xd6\xdf\x63\x2b\xb0\xcb\xe9\xa9\xf6\xdf\xa8\x3e\x22\x7f\xc0\x7b\xde\x1b\x57\x7b\x36\x11\xfb\x92\x1c\x9f\x83\x13\xf0\x68\xe6\x29\x5d\x49\x13\xa8\x19\x6b\xe5\x30\xf6\xa0\x1f\x57\xc0\x9c\x02\x84\x91\x44\x4b\x78\x47\x20\xe9\x09\xea\x1f\xb6\x9c\x1c\x1d\xd6\x30\x44\x00\x32\x7b\x77\x31\xb3\x3c\xc4\x6d\xeb\x04\x6c\xda\xb6\xad\x1b\x53\xf1\x74\x9a\x0c\x65\xcb\x9a\x7e\x37\x6f\xfa\x02\x23\x0f\x53\x65\x84\xae\xa2\x43\xc6\x39\x10\x3a\xdb\xba\x76\x43\x21\x64\x9d\x7e\x01\x26\xf8\x2e\x0b\x4f\xd9\xdc\xb8\x6c\x73\x1c\xbc\xc5\x17\xf2\x01\x68\x41\xe9\x16\xbc\xd5\xfd\xe8\x71\xdc\x09\x8c\xd9\x13\xdc\x54\x62\x84\xd1\xb2\x16\x5c\x63\xe8\x8f\x32\xa2\x78\x9a\x50\x08\x56\x37\x1b\x50\xd2\x2f\xb8\xc8\x7d\x1a\x3c\xae\xdc\xdf\xd0\x1e\xe5\xf8\x70\xa5\x3c\x28\x41\x81\xd6\x32\xec\x66\xd4\x8b\x6b\xdd\x56\x46\xac\x39\xc9\xe7\x53\x38\xa5\x20\x21\x20\x62\xbc\x34\x66\xef\x5c\x58\x76\x55\x70\xb9\x05\xf6\x3a\x93\xd0\x7f\x8f\x1b\xaa\xc3\x52\x6b\x01\x6d\xa7\x99\xf3\xe9\xe0\x3a\x4f\x7f\x81\x35\x5e\x0f\x7a\x76\xf3\x0a\x42\xb8\x07\x32\x20\x51\xb7\x1c\x62\x6a\x7a\x29\x6d\x75\xb9\xd9\xd1\xa2\x3b\xcb\x13\xc9\xef\x48\xa9\x12\xdc\x05\x73\x25\xd3\xbc\xfb\x3f\x9f\xad\xaf\x0c\x24\x9b\x10\x2a\xeb\x85\x4a\xa3\x63\x1e\x34\xf6\x9a\xd9\x0c\x2a\xb2\xed\x33\xba\xcc\x40\xb9\xed\x10\x37\xfa\xe6\x7c\xdf\x79\x9d\x5a\x9b\x43\x78\x59\x61\x12\x7d\x62\xf8\xe0\xbc\x15\x89\xfd\x1a\x06\xfc\xa2\xae\xa7\xcf\xc0\x12\xcb\xf7\xb5\xb2\x07\xdd\xc4\xe6\x77\xd8\xae\x4a\xec\x10\x00\x45\xce\x36\xc0\x0b\x74\xd1\xd2\x82\x50\x79\x12\x36\xdc\x5d\xcc\x1e\xd3\x13\xc8\xc2\x46\x17\x26\x66\xf7\x52\x17\x43\x7c\x60\x34\xac\xd6\x41\x98\xcd\x96\xdf\x2a"}, +{{0xa2,0x84,0xe2,0x6b,0x97,0xe5,0x38,0x83,0x9c,0x80,0x8d,0x45,0xbd,0xe6,0xf0,0x12,0xa3,0x54,0x45,0x4a,0xef,0x81,0xca,0xa8,0xc5,0x59,0x14,0x62,0x4f,0x2b,0x7d,0x66,},{0x5a,0xe4,0x6e,0x34,0x69,0x5e,0xfa,0xf4,0x63,0xa4,0x20,0x8f,0xc4,0xe3,0x5b,0x81,0xf2,0xc6,0x35,0x93,0x23,0x8a,0x56,0xf2,0x44,0x4b,0x85,0x0f,0x05,0x8c,0x3c,0x5c,},{0xbf,0x11,0x0e,0x2e,0x9c,0xec,0xbc,0x31,0xfa,0x3e,0x0c,0x24,0x38,0xcd,0x1f,0x43,0x21,0xf9,0x2c,0xd2,0x87,0x00,0x5a,0x48,0x52,0x8a,0xdd,0xf7,0x6c,0xad,0x8d,0x88,0xbb,0x22,0x71,0x9e,0xf9,0x1b,0x13,0x95,0x62,0xa1,0x51,0x18,0x38,0x68,0x26,0x74,0xfa,0xa9,0xff,0x7e,0x7a,0xde,0x6c,0x9d,0x57,0x3f,0x84,0x50,0x36,0xd1,0x89,0x05,},"\x9e\xbf\xe9\x10\xb5\x0a\x5c\xb7\x19\xd9\x5b\x96\x1e\x59\x05\xf0\x0e\xc7\x94\x3b\x55\x46\x8a\xb5\x95\x66\x92\x01\x76\x45\xb3\x66\x07\x1f\x8f\xbb\x77\xeb\x49\xec\x73\xea\x7d\x64\x51\x14\x05\xb9\x0d\xe2\x2d\xb9\x8c\x3e\xae\x39\xc4\x03\x9c\x7a\x13\x34\x30\xe8\x01\x0b\xdd\x39\xa0\x0f\xd1\xa5\x28\xb1\x13\xda\xe1\x49\xcf\xad\x3a\xe3\x40\xda\x27\xdc\xc5\x07\x78\x2e\xcd\x89\x29\x23\x75\x17\xaf\xe7\x46\x3e\xca\x24\x73\xc7\xac\xf6\xf7\xaa\x04\xef\xc9\xf2\x66\xae\x7b\x6d\x63\xbb\x8c\xc2\xa4\x38\xb3\x44\x82\x7f\x07\x13\xd1\xf1\x73\x6f\x0c\xbb\x65\xb9\x93\x53\xf2\x03\x55\xfa\x02\x30\xd4\xfa\x70\x73\x28\xa8\x66\x26\x54\xe8\x3a\xd0\x53\x0a\x10\xf9\xa6\x9e\x17\xc0\x99\xe1\xe2\xb5\xdb\x18\xe5\xf6\xf1\xdc\xed\xa5\x88\x3e\x8c\xab\x79\x70\x1a\x5e\x90\x89\x56\x2e\xd1\x53\xad\x08\xc6\x74\xf0\x97\xc2\x8e\x4d\x16\x63\x3e\x09\x29\x69\xa8\xf0\xbd\xac\x54\x52\x7c\x0e\xe0\x3b\xc2\x00\xe5\xbe\x61\x2e\x3d\x1e\xab\xd8\x70\x91\x10\x1b\x49\x62\xaf\xa0\x7b\x31\x08\x06\x99\x2f\x37\x30\x76\xd7\x6a\x58\x18\x51\x18\x13\x7c\x9d\x26\xee\x2c\xd4\xc6\x18\xc1\x82\x83\xdd\x19\xf0\xe7\xa0\x89\xee\x37\x30\x5b\x6b\x95\x18\xa7\x8d\x80\x98\x43\x6e\xf6\x2b\xe7\xd6\x99\x80\x8a\xce\xcf\x67\x93\x9d\x61\xb3\xe0\x29\x37\xcd\x8c\x5f\x1e\x74\x6d\x42\x74\x33\x4b\xc9\xc3\x7f\xdc\xba\x23\x4c\x16\x6f\xd7\x12\x89\x3f\x3a\x04\x08\x32\xec\x54\x25\xe5\x7d\x80\xf1\x1e\xf9\xca\x5f\xbc\xd6\xc1\x47\xfb\xbf\x5e\x2f\xae\x74\x6e\x0d\xdb\x60\x58\x67\xe3\xbd\x05\x04\x83\xc3\xcd\x13\x29\xab\xe5\x7a\x60\xbf\x88\x89\x8d\xc7\xe8\x0e\xde\x0f\x45\x17\xde\x8f\xc8\x07\xe8\x88\xb6\x21\xa0\x0f\x66\x30\x84\xff\x94\xb9\x99\x96\x62\x8f\x3b\x11\x69\x0a\x60\xf0\x91\x8c\xb5\xc9\xa7\xef"}, +{{0xcc,0x97,0xa9,0x63,0x01,0xce,0xed,0x0f,0x92,0x27,0x31,0xb6,0x85,0xba,0xd8,0xad,0x4f,0x06,0x20,0x7b,0xe3,0x40,0xf5,0xa4,0x4f,0xd1,0x87,0xf2,0x99,0x03,0xec,0x20,},{0xeb,0x56,0x3a,0x7b,0xce,0x12,0xdb,0x97,0xf1,0x89,0x1d,0x0f,0x61,0x0b,0xeb,0xd5,0x51,0x01,0xa3,0x12,0x5c,0xa8,0xdb,0xb5,0x0b,0x25,0xa6,0xb5,0x05,0x0d,0x37,0x84,},{0xff,0xbd,0xd3,0x24,0x41,0x81,0xcd,0xf6,0x03,0x4f,0x4a,0x45,0x0f,0xdd,0x95,0xde,0xe4,0x97,0x1a,0x93,0x3f,0x8b,0xe0,0x22,0xbb,0x0a,0x41,0x06,0xae,0xf3,0x9a,0xf3,0x05,0x5b,0x72,0x18,0x81,0xc9,0xb5,0x4d,0x1e,0x99,0xb9,0x40,0x90,0x96,0xfb,0xe6,0xdc,0x2c,0x99,0x66,0xe3,0x67,0x99,0x64,0xbd,0x7e,0xf4,0xc8,0x08,0xca,0xbf,0x01,},"\xb9\xea\x3b\x3d\xf7\x18\x7e\xa4\x15\xa3\xc3\x35\xe0\x83\x4e\x10\xf4\x40\x91\x5b\x2a\xd4\x1c\x71\xf2\x55\xd6\x95\x0a\x4e\x91\x20\xe4\xd4\x94\xfd\x9e\x67\x2c\xe5\x32\x06\xfd\xc4\x17\xd8\x65\x89\x7b\x47\xac\x10\x54\xe1\xca\x10\x68\x19\x52\x32\xd4\x29\x74\x35\xe4\x4e\x12\x24\xe6\x6a\x91\x2d\x9d\x7d\x18\x29\x46\xff\x5a\x9f\x08\x5b\xb8\xba\x19\xc5\x4d\x16\xb5\x86\xa9\xb3\x04\x61\xb6\x77\x3b\x93\x95\x03\x11\xe1\x61\x98\x86\xf5\xa5\xb3\xf1\x11\xaa\xad\x09\x4b\xae\x31\xc4\x8f\x19\x41\x08\x09\x68\xbd\x02\x77\xbb\x6f\xa9\x2e\xeb\xf3\x24\xb1\x92\xdf\x5c\xc9\x69\x51\x6c\x78\xc7\xb2\xd1\x21\x59\xb4\xd1\xc8\xeb\x03\x16\x0c\x4c\xd1\x90\x7f\x62\xed\x4b\x85\x4c\x56\x9e\xcc\x48\x1c\x08\xe6\x36\xf4\x4e\xd7\xc3\x90\xe5\x8b\x59\x37\xd2\x90\x6b\x28\x17\xbc\x37\x69\xda\xd9\xda\x1b\x0f\x79\x39\x1b\x55\x94\x20\x63\x05\x5d\xa0\xd6\xf2\x49\xa3\xe4\x52\xba\xdd\xaa\x03\x29\x98\xd7\xf7\x33\x98\xcc\xd0\x15\x1b\xfc\x92\xc5\xe2\xfd\xfa\x9b\x14\x85\x5e\x6b\x0d\x37\x46\xdc\xe2\x48\xe2\x19\x67\x29\x87\x25\x2e\xc7\x47\xdf\x27\x47\xfd\x3f\xbd\x8b\x71\x4c\x88\x2d\x70\x7e\xe3\x02\xa9\x04\x95\x0c\x34\x75\x4f\x85\x35\x0e\x1a\xa3\xf8\xea\x62\x93\xcf\x01\xf7\x17\xce\xfb\x6b\x83\xa2\x21\x26\xdf\x5c\x4f\x56\x98\xaa\xfd\x06\xa2\x24\x4a\xd7\xd0\x1f\x34\x01\x7c\xa0\xec\xe6\xf2\x10\x40\x04\x8a\xba\x6c\xa4\xae\xb0\x43\x25\xb9\x40\x2b\xcd\x43\xab\x13\x0a\x10\x57\x88\xac\x3d\x7b\x7d\xa0\x1e\xa9\x42\x6d\xd0\xea\x19\x33\xa8\x18\x99\x33\xa6\xc0\xc6\xcd\x64\x8e\xa3\x16\xa7\x46\x9a\x5f\xdc\x6e\x7c\x93\x4d\x91\x86\x58\x60\x97\xb5\x5d\xd5\x1a\xc4\x87\xbb\x80\xed\x11\xd4\xdf\x8d\x33\x62\x6b\xbc\xe9\x5e\x4f\x13\xbd\x49\x92\x2f\x00\xc9\x20\x22\x3f\x4c\xbf\x93\xcb"}, +{{0x67,0x9e,0x3e,0x34,0x77,0x3a,0xbe,0x4a,0xe2,0x5c,0xae,0x7d,0x07,0xcc,0xd0,0xeb,0x3b,0x0e,0xc0,0xa3,0x5d,0x57,0x02,0x57,0xd6,0x25,0x70,0xde,0x58,0xea,0x25,0x16,},{0x18,0xac,0xff,0xce,0x25,0x3b,0x27,0x25,0x95,0x79,0xed,0x99,0x24,0xf4,0x79,0xca,0xe3,0x12,0x16,0x7b,0xcd,0x87,0x6e,0xdb,0xa8,0x8b,0x5d,0x1d,0x73,0xc4,0x3d,0xbe,},{0x1a,0x51,0x02,0x26,0x28,0xcc,0xbb,0x88,0xea,0xe9,0xb2,0x17,0x73,0xc3,0xf8,0x30,0xb7,0xb6,0xe5,0xbc,0x36,0xc9,0x90,0x3c,0xe7,0x0f,0xbc,0xf4,0x59,0xd6,0xa1,0xed,0x8a,0x1d,0xce,0xff,0x5b,0x19,0x26,0x9e,0xbf,0x5a,0x6f,0xd3,0xd8,0x95,0x88,0x60,0xf5,0x54,0x46,0x1f,0x0e,0x9f,0xc0,0xe2,0x9a,0xf9,0xb1,0xfb,0x17,0x44,0xa8,0x0b,},"\xfb\x2b\x64\x8e\xbb\x16\x68\x82\x44\xf7\x8b\x2e\xe9\xa2\x73\x59\x9d\x56\xb6\x19\x89\x00\xd4\x38\xa9\xe9\x9c\x19\x14\x25\xc7\x2b\xec\x4f\x23\x58\x47\xe1\x8e\x47\xf5\x7c\x3c\xb3\x96\x65\x5f\x77\x89\x21\xf9\x08\x58\x0e\x8e\x83\xc9\x6c\x10\x8b\x20\xdd\x41\x66\x78\x02\x1b\xca\x25\x9b\x98\x51\x8f\xab\xb2\xd3\x53\x2e\x48\x51\xd9\xd5\x2a\xdd\x25\x42\xc0\xcb\x3e\xfa\x38\x57\xa1\x7e\x51\x24\x38\xbc\x0e\xc4\x76\x2e\x2f\x9b\xab\xa4\x29\xc0\x3e\x99\xbe\xc4\x03\x8e\x6b\x0c\xa4\x2b\xff\x5b\x23\x3b\x24\xc3\x33\xb4\xca\xea\xd2\xde\x37\x4a\x87\xb2\xab\x5d\x80\xd6\xe4\x9e\x44\x56\x32\x9d\x51\xae\x97\x3b\xc8\x3d\x78\x62\xf3\xd3\x15\xe5\x14\x48\x1b\x12\x85\x4a\x9d\xfc\x09\xe7\xd1\x4f\x0d\x02\x2c\x0b\xa3\x02\x25\x78\xeb\xa8\xf8\x74\xde\xba\x4a\xa8\xc8\x33\xf2\xb1\x32\x86\x1d\x4d\x51\xe5\x0f\xe9\xaa\x4b\x78\x7b\xd2\xf0\x51\xaa\xc5\x0c\x37\x53\x90\xcb\xbc\xfb\xa2\x00\x2b\x80\xad\x00\xcd\xc1\x29\x80\xf8\xba\x8b\xcb\x70\x64\xaf\xc0\x4d\x5c\x46\x82\xc1\x02\x9b\x10\xa6\xd4\x5f\xe6\xec\xd7\x04\x24\x5f\xaf\x59\x8c\x46\x59\x59\x7c\x5d\x68\xa1\x92\xcc\x1c\xd4\xfa\x45\xe8\x4b\x54\x9e\x8e\x5e\x67\xda\xa8\x79\xae\x5a\x52\x0a\x6b\x55\x50\x51\x98\x76\xa5\x62\xac\x49\xc6\xdb\x0a\xa7\x6e\xc6\x9b\xb6\x4d\xd6\xb5\xe1\xa3\xaf\x2e\x13\x1e\x72\x2e\x7c\xdd\x05\xbe\x34\xb5\xfc\xc6\x25\x9a\xa1\x24\xcc\xf8\x14\xcf\x5b\x50\x0d\x17\x6b\xe2\x8e\xbc\x40\xbb\x21\xf0\x3e\x24\xcc\xc1\x31\xe0\xf4\x1d\xaa\x1c\xa0\x2e\x6b\x00\xc9\xc5\x3f\xad\x12\x48\x61\x4e\x94\x0d\x4b\x23\x77\x60\xab\x75\x69\xa7\x67\xb7\x51\x5d\xd2\xd6\x23\xe5\x7a\x28\x41\xb7\xd2\x44\x1c\xf4\x30\x49\xe4\x69\x8d\x2f\x9c\x9e\xae\x7b\x29\x10\xf6\xad\x65\xed\xf9\xcb\x2b\xdb\xd9\xb2\x9f\x60\x6e\x0d"}, +{{0x9b,0xfa,0x60,0x92,0x3a,0x43,0xed,0x0c,0x24,0xe2,0xf1,0x2f,0x5b,0x86,0xa0,0x71,0x63,0x29,0xf9,0x3d,0x4d,0x8d,0x3e,0x06,0x23,0x80,0x02,0x89,0x32,0x78,0xc1,0x9a,},{0xfb,0x1c,0x00,0x68,0x77,0x81,0xb5,0x5b,0x89,0x3d,0x6b,0x2f,0x4f,0x49,0xcf,0x5f,0x73,0xd2,0x90,0x3c,0x31,0x6d,0x1e,0xee,0x75,0x99,0x1d,0x98,0x3a,0x18,0x68,0xc0,},{0x55,0xf2,0x02,0xef,0xb2,0xa5,0x7b,0xe8,0xb4,0xe4,0xfd,0x89,0x4d,0xcc,0x11,0xa4,0xfc,0x5f,0x82,0x76,0x61,0x8e,0xf5,0xcd,0x34,0xa4,0x49,0x5a,0xdb,0x01,0x6a,0x29,0x8e,0x64,0x80,0xa3,0x5c,0xfc,0x53,0xed,0xb2,0x5f,0xf1,0x49,0x9f,0xc5,0x32,0xa3,0x30,0x61,0xcc,0x01,0xa2,0x50,0x45,0x8a,0xa5,0xe4,0xf7,0xf1,0x6f,0x51,0x44,0x0d,},"\xa9\x90\x28\xb0\xf4\xa3\xaa\x5e\x79\xab\xef\x6c\x0d\xf4\xa7\x83\xef\x47\x0f\x1a\x29\xba\x51\xeb\xa0\x0f\x62\x14\xe8\x40\xfe\x19\xe5\xb6\xdc\x60\x21\xab\x59\x9b\xb2\xee\x36\x99\x57\x60\x15\xd7\x9a\x79\x39\xaf\x82\x35\x35\xb6\x30\xe3\x93\x8c\x72\x3f\x6e\x0b\x92\x29\xd4\x6b\xb3\x37\x9a\xcd\xba\x58\x7c\x23\x85\x67\xe3\xd8\x9b\xc3\xbd\x35\x19\xb7\x27\xfc\x69\x4f\xff\x11\x18\xbf\x22\xc8\xbc\x8b\xc8\x2c\x4d\xf7\xf5\xad\x38\xde\x05\xfe\x9f\x76\x29\x99\xec\xaa\x79\x5f\x3a\xe6\x30\xa9\xa3\x16\xd2\x6d\xce\x9f\x15\x68\xff\xa3\xf2\x2b\x02\x95\x21\x40\x20\xb3\xd3\xf5\x33\x7c\x14\x95\x68\x19\x22\x18\x13\x2a\x90\x70\x92\x79\xc0\x1d\x23\xba\xef\xa6\x69\xe1\xc4\xe4\x20\x38\x17\x3f\x13\x19\xc2\x12\xda\x14\x4f\x1c\x4e\xa4\xc5\x2c\x00\x5c\xbc\x0b\x5b\xc2\x83\xe7\x44\x83\xa0\xdc\xa6\x92\x79\xde\xb1\x7a\xe5\xb2\x9c\xfa\xfa\x7d\x00\x63\xf4\xe1\xbc\x93\x53\x7e\xfd\x93\x7e\x58\xa8\xac\xa7\x37\x22\x8f\x93\x7f\xf2\xa7\x41\x89\x0e\x96\xc5\x72\x5d\xa1\x1b\x45\xc4\x13\xa9\xbb\xb4\x18\x0a\x41\x99\x87\xbb\xf0\x46\xbf\xd3\x46\x29\x5d\x62\xf0\x81\xc7\x6d\xaf\x2b\x0e\x1e\xb4\xf6\x71\x2f\xee\xbe\x6f\x0a\x92\xe3\x58\xe7\xdd\xb8\x58\x96\x50\x7c\x34\x0a\x01\xf6\x8d\x1b\x0f\x08\x57\x78\xb7\xc4\x4b\x01\x4a\xa6\x67\x3e\x50\x17\x96\x95\x9a\x17\xa6\x88\xdb\x09\x59\x05\x84\x88\xa7\x11\x25\x72\xf2\x3c\xf9\xcd\xb5\x3b\x5e\xb4\xb4\x5f\x59\x53\xba\x0c\x0c\x69\x0f\x86\xbd\x75\xe8\x9a\x04\x7b\xeb\xaf\x84\x7c\x1d\xfc\x34\x5a\x4f\x3c\x7d\x3b\xee\xc9\x8b\x84\xb0\x21\x90\x03\xe8\x19\xf5\xc2\xad\xb4\x5f\x87\x17\x90\x3d\x1f\x5b\xd5\xd7\x19\x14\xc5\x6f\xca\xbc\x7a\x29\x0f\x9c\x41\x69\x9c\x95\x58\x4d\x6a\x3a\x16\x34\x0c\xb1\x7b\xaa\x1f\xc5\xe5\x46\x7a\xf7\xac\x32\x21"}, +{{0x6e,0x3a,0xf4,0x5e,0x66,0xe2,0x28,0x90,0xc3,0xf3,0xc9,0x34,0xf5,0x23,0xa4,0xd6,0x94,0x27,0x97,0x6e,0x6e,0x52,0x62,0x5f,0x8b,0xad,0x55,0x89,0x93,0x96,0x32,0x19,},{0xe0,0x97,0x36,0x4e,0x76,0xff,0x9f,0x2e,0x1d,0x16,0x7f,0x6b,0x20,0xc1,0xbc,0x58,0x30,0x08,0x5e,0x7e,0xc9,0x93,0xc1,0x38,0xf8,0xb1,0xb2,0x17,0x56,0x37,0xe7,0x41,},{0x26,0xba,0x56,0x2e,0x8a,0x40,0x65,0x70,0x82,0x07,0xc2,0x5e,0x23,0x9b,0x78,0x0a,0xee,0x38,0x79,0x4c,0xf9,0x83,0xa3,0x7a,0xcb,0xb9,0xd5,0x57,0xa6,0x5c,0xee,0xd3,0xc0,0xda,0x47,0xd1,0x7f,0x3e,0x8b,0x8f,0x4e,0xeb,0x1b,0x65,0xa2,0xc1,0x82,0xea,0x6f,0x29,0x62,0x3b,0x63,0xbb,0x0f,0x1c,0x72,0x59,0x26,0x83,0xb1,0x26,0xb9,0x01,},"\x5c\xfc\x2f\x4b\x55\x9f\x82\x05\xb3\x91\x02\x08\x76\x17\xf4\xd8\x6c\x7c\xe6\xcb\x25\x1e\x5f\x89\x60\x1d\xfc\x88\xed\x28\xe8\xd7\xa6\x70\xec\x00\x87\xd2\xea\x5d\x89\x30\x21\xc7\x04\x4d\xa2\x89\x9a\x22\xd7\x76\xfe\x90\x17\x0e\x51\xc2\x03\x25\x06\x90\xd3\x7a\x29\x45\x55\xe7\x4a\xf9\x23\x4c\xbf\x1a\xd8\xf2\x2c\xee\x89\x74\x82\x8a\x0d\x09\xe9\x55\x4b\x71\xee\x3b\xcf\x88\x0a\xb9\x83\x25\xf7\x06\x27\x21\x94\xeb\x2e\x80\xc7\x01\xd4\x41\xb5\xf8\x66\x85\x61\xb8\x88\x49\xf8\x27\xaf\x70\x3a\xb0\x95\x41\x05\xfd\x3c\x54\xb3\xf6\xec\x54\x93\x59\x6d\x0e\x3b\xc6\x78\x18\x04\x83\x10\xc4\xa3\xe0\xc5\x56\xbc\x80\x67\x5f\x20\x1f\x9b\xb9\xc6\x53\x8a\x41\xd9\x9a\xa4\x0c\x88\x6f\xc4\x31\x46\x72\x18\xd8\x19\xc2\x3e\x78\x49\x8a\xed\x06\x13\xfa\x6f\x97\x3e\x22\x11\xdf\x9f\xb8\x7f\x44\x11\x6f\x3f\xe4\xc2\x6d\x6c\xb2\xfa\x33\x4c\x87\xf7\x8c\x08\xca\x8c\x9b\x90\x41\xd8\x3a\x12\x30\x67\x7e\x0a\xf7\x88\x59\x8a\x42\xe4\x4c\xfd\xf6\x96\x4a\x4e\xe8\x0e\x38\x40\x2b\xa6\x7c\x73\xa5\x81\xe5\x52\xba\xa2\x28\x24\x25\xcb\x2c\xa1\x7c\xa9\x2e\xdf\xbf\x98\x29\x91\x02\xfb\xa7\x61\xb9\xb7\x1a\x54\x52\x14\x1b\xb9\xc1\x8d\xd9\x5f\xeb\xc2\xa7\x82\xde\x9c\xee\xc0\x8b\xd2\xee\x3f\x7f\x0c\x1b\xd8\x94\x6d\xba\x99\xcf\x9e\xa0\x86\xab\xaf\xd3\x7c\x9c\xa6\x02\x13\xf0\xde\x17\xc6\x1f\xf9\xc3\x91\xc9\x81\x8e\xd5\xcd\x85\x71\x77\x8b\x7d\xcc\x13\x22\x49\x62\x38\x6f\xb8\xca\x14\xf8\x61\xe9\x9f\x3b\x18\xed\xac\x8a\x5f\x13\x0f\x7b\xfc\xd4\x5d\x04\x5d\x0f\xf3\x4c\x81\x57\x2a\x51\x23\x63\xd6\x53\x0f\x93\x81\x3e\x5f\xb1\x0e\x9c\xb8\x33\x8a\x7f\x93\x80\x04\x91\x00\x6f\x44\x63\xe8\x9f\x0e\xd4\x53\x0e\x5f\x12\xdf\x67\x4f\x59\x89\x04\x78\x0a\xd0\x81\x2b\x1e\x35\x21\xfc\xd0\xf8\x3e"}, +{{0x5f,0x1f,0x27,0x18,0x44,0xd9,0xed,0x5a,0x6a,0x6f,0x20,0x9a,0x21,0x40,0x8d,0xae,0xa4,0x70,0xf6,0xfd,0x53,0xba,0x64,0x79,0xd7,0x40,0x71,0x05,0xb7,0xde,0x4d,0x65,},{0x60,0x85,0xd7,0xfb,0x5a,0x9b,0x2e,0xd8,0x06,0xc1,0xfd,0x30,0xa2,0xaf,0xde,0x76,0x09,0x61,0xf7,0xa3,0x6b,0x48,0xf4,0x87,0x52,0x46,0xe6,0x15,0xa2,0xbd,0x99,0x28,},{0x31,0x9b,0xb4,0xde,0xb2,0x17,0x81,0x12,0x24,0x1b,0x3f,0xb8,0xf4,0x6e,0x10,0x5c,0x3b,0x8e,0x4e,0xf7,0x21,0xeb,0x20,0x0d,0x76,0x2e,0xf3,0x63,0xe2,0x71,0x6f,0x2a,0x89,0xf8,0x0b,0x5b,0x9e,0x89,0x97,0x08,0x90,0xa0,0x98,0x92,0xad,0x6a,0x58,0x80,0x8b,0x47,0x7e,0x94,0x3b,0x3c,0xfa,0x77,0x77,0x4a,0x36,0x45,0xbc,0x74,0x5f,0x03,},"\xee\xd6\xb4\x47\x5d\xc2\x63\xbd\x22\x07\xfe\x9d\x41\xd4\x82\x82\xb7\x13\xf6\x80\xf2\xe0\x37\x38\x4f\x18\xb4\xbf\x22\x43\x47\xf5\xe4\xc4\xb0\x60\xb8\x08\xd4\x12\xea\xab\xcf\x73\x3d\xc3\x9a\x40\xc6\xbd\xa0\x50\x5c\xe7\x1f\xa8\x23\xbd\x1b\x17\x94\x84\x76\x78\xdc\x03\x4e\x79\x99\xc1\x63\x69\x34\x0b\xc6\x0c\x64\xd0\x9b\xb9\x18\x7b\x2e\x32\x60\x55\xa0\x53\xf8\xe5\x05\xea\x41\x96\x86\x14\x71\x62\x2d\xb0\xe4\x6f\x0f\x89\x54\xd8\xa1\xf0\x73\x32\xda\x4d\x8a\xc5\x57\x12\x62\x60\x09\x91\x2f\x8a\x15\xa9\xcd\x63\xa7\x4a\x03\xc9\x2f\x24\x6c\xb6\x3c\xc7\x3f\x92\xe5\x1d\xad\x1b\xc9\x71\x5b\x1e\xd3\xfe\x5f\x2e\x1b\x29\x59\xb9\xb7\x1e\x0e\x37\x36\x0e\xb2\x95\x36\xcf\x79\x71\x47\xfa\xb1\x08\x64\xd6\x14\x6c\x36\xb8\x23\x35\xa0\xce\x93\x14\x08\x47\x9c\x7e\xde\x48\x4f\xf7\x3e\x2d\xbf\xff\xc6\xc9\x22\x7e\x16\xd7\xa2\x3f\x4d\x90\xf1\x55\x84\x51\x4c\x39\x59\x4e\x17\xbf\xbb\x29\x5d\xe9\xd6\x2a\xda\xdb\x58\x9d\xbb\xe0\xb0\x6d\xc8\xda\xc5\xb3\xbf\x51\x7b\x24\xc1\x83\x7b\x39\x47\x2a\x6d\xd3\x89\x31\xff\xbb\xff\x5b\x76\x36\x38\x80\x5b\x4e\x22\x32\x1f\x7a\xfe\x92\xcd\xf5\x02\xfb\x63\xd1\x09\xdd\xcd\x9e\x40\x51\xad\x6f\x45\x59\x85\x32\xbe\x17\x95\x23\x71\x08\x51\xd3\x93\x1e\x88\x7d\x02\xc3\x45\xc7\x9c\x48\x9f\xc1\x06\xa4\xae\x16\x2f\x7d\xf7\x1a\xb9\x0b\x75\x1d\xa7\x03\x8a\x6d\xf7\x61\x6c\xfc\x11\x88\x7e\x21\x06\x8f\xb9\xe3\x3b\xe5\x66\x40\x2b\xe5\x04\xf3\xfc\x27\x42\xb8\x81\x50\x9b\xd4\xfe\x6a\x0f\xc7\x22\x64\x98\x83\xf8\xcb\x65\x55\x98\xa1\x5a\x1d\x4c\x22\x9d\xd8\x6b\x5c\xae\xb7\x11\xa0\x28\xde\xfd\x43\x11\x54\xbb\xa4\x6b\x48\x17\x2a\x4d\x8c\xbd\x45\xbc\x90\xaa\xf8\x74\xb6\x08\x5f\xa2\x84\xf5\xfe\xd6\x55\xad\x6f\xa1\x7d\x67\xb3\xb9\xa7\x96\xfa\x3e"}, +{{0x04,0x8a,0xc9,0xec,0x3e,0xcb,0x30,0xa3,0xb1,0xbf,0xda,0x9b,0x3b,0x79,0xa4,0x8c,0x07,0x93,0xb4,0x90,0x87,0x9e,0x3c,0x8a,0x5e,0x23,0xee,0x2b,0xab,0xcd,0x9b,0x7c,},{0x94,0x6c,0x18,0x6f,0xea,0xfc,0x35,0x80,0xa5,0x8d,0xdd,0x52,0x6f,0xf2,0x29,0xc0,0x47,0x20,0x25,0x0f,0x4c,0xf6,0xbd,0xe0,0x27,0x1e,0xef,0x9b,0x12,0xb1,0xc3,0xf3,},{0x2e,0xcf,0x5b,0x8a,0x59,0xa8,0xe2,0x7d,0x25,0x89,0x0a,0x2a,0xa3,0x2f,0x4a,0x06,0x73,0x27,0x5d,0x53,0x9b,0x17,0x4a,0xfa,0x7b,0x2c,0xeb,0xf2,0xe7,0x62,0x80,0xdf,0xfc,0x33,0x8e,0xde,0x85,0xac,0x8f,0x61,0x40,0x39,0x56,0x0e,0x28,0x06,0xd9,0xe1,0xe3,0xcf,0x9c,0xce,0x2c,0xeb,0x78,0x74,0xff,0xe1,0xa7,0xe8,0x0c,0xde,0xf4,0x0b,},"\xd6\x8b\xe8\xef\x7b\x4c\x7a\x42\x89\xf2\xb1\x8b\x16\xad\xe9\x7f\x4e\x4f\xa1\x64\x52\x97\x6a\xfb\x58\x16\x93\x38\x0c\xc5\x4d\xe3\x8a\x07\x58\x7f\x32\xe2\xd4\x54\x9f\x26\x59\x5f\xee\x23\x93\xbd\x06\x2e\x9b\x00\xba\xe7\x24\x98\xe4\x14\x8c\x8b\x88\x2a\x88\x40\xe1\x5b\x58\x5c\x82\xb5\xc0\xde\xfb\x23\x35\x18\x40\x99\x16\x61\x5d\xeb\x3a\x55\xa5\xf8\x4e\x6b\x3a\xab\x93\x84\x4d\xe3\xb1\xe4\xd8\x6e\x09\xf8\x89\xac\x71\xc3\x24\xeb\x12\xd0\xfb\xd8\x61\xcc\x31\x22\x95\x40\xe8\x43\xa3\x4f\x8d\x5b\xe4\x7c\x0e\xc0\xd2\x3d\xf4\x3e\x06\x81\x3f\xca\x30\x94\x39\x90\x4c\x16\x7d\x10\x43\xc0\xdc\xd4\x44\xb0\x04\xbe\x1f\xf2\x7b\x78\x62\xb0\x0e\xba\x94\x33\xb9\x4b\x0f\xcd\xc6\x75\x21\xda\x0c\x1d\x53\x58\x63\x6c\x78\xf5\x30\x43\x11\x64\xdd\xe2\x0a\x1c\xf1\x64\xf5\x1e\x29\xb8\xe6\x3e\xac\xde\xcc\x86\x9b\x41\x39\x2c\x66\x76\x64\xd9\x16\x80\xd9\xac\x51\x6a\xf5\x48\xf0\x9e\x60\x56\x4e\x81\x4e\x36\xe0\xb5\x63\xdb\xae\x55\xc6\x27\xff\xc1\x41\x58\xa5\x6d\x8e\xb3\x60\x9e\x17\x43\x81\xb2\x1d\xe4\xba\x82\x34\x44\x66\xdd\x57\x7f\x4d\x11\x03\xc4\x3c\x27\xfb\x83\xcb\x83\x3d\x87\xaf\xdf\x74\x12\xb4\x09\x09\x09\xb1\xdd\xe2\x64\xda\xdd\xce\x96\x7f\x49\x6b\xf6\xf1\x71\x12\xbf\x35\x1e\x41\x7d\xb5\x95\x3b\x13\xb8\xf0\xfc\xcc\xbf\x30\xf5\xbc\xf3\x76\x86\x1c\x12\xef\x20\xee\xc8\x9e\xd2\x3c\xf3\x84\xee\x78\xdc\x6e\xb4\x0f\xd5\x81\x1a\x7b\x23\x92\x7c\x13\xe7\xdc\x5d\xa3\xa9\x21\xb8\x83\xa9\xb2\xb1\x15\x59\x70\xfb\x0d\xa7\xd2\x99\x3d\xcd\xfd\x43\x43\x64\x2a\x9d\x5a\x63\x47\xe4\x3c\x19\x3b\x57\x93\xe4\x45\x3a\xc1\x53\x7a\xa3\xd0\x4d\xc9\xf7\x74\xe8\x40\x93\x48\x81\xd7\x8a\x39\xba\x25\x04\x38\xc5\x07\x25\x0e\xed\x2f\x6e\x07\xcc\x95\x3f\x78\x3d\x6b\x72\xb1\xcc\x61\x99\x81"}, +{{0x2f,0x05,0x7d,0x20,0xb1,0x67,0x85,0x31,0x61,0x1f,0x48,0xf0,0x03,0xb7,0xd2,0x2e,0xba,0x5d,0xbb,0xd7,0xe2,0xdd,0x41,0xb7,0xc7,0x9d,0x09,0x07,0x1f,0x85,0xe9,0x93,},{0x62,0x0f,0xc4,0xea,0xa3,0x4d,0x78,0x7d,0xf6,0x75,0xcc,0xbf,0x7e,0x89,0x32,0x04,0x82,0x8d,0xb9,0x2e,0xad,0x17,0xa1,0x16,0x5a,0xc7,0xfa,0x1a,0xb4,0x27,0x19,0xd8,},{0x30,0xdf,0x7b,0x0b,0x1c,0x04,0xfb,0x1e,0xfa,0x35,0x17,0xe9,0x28,0xd6,0xd5,0x7c,0x2c,0xa0,0xd0,0x7f,0x4e,0x04,0xff,0xb1,0xf0,0x8b,0x47,0x92,0xc5,0x93,0x7d,0xd2,0x71,0xcc,0xab,0xdc,0x00,0xdc,0xe8,0x50,0xaf,0xe5,0x0a,0xf5,0x99,0x0f,0x22,0x4e,0x84,0x20,0xa6,0x81,0xd9,0x5f,0x9f,0x7f,0x51,0x5a,0xfe,0xc1,0x02,0xef,0xd1,0x0e,},"\x6e\x35\xf6\xea\xa2\xbf\xee\x06\xea\x6f\x2b\x2f\x7a\xb1\x5f\xa9\x7c\x51\x80\x95\x8a\xf2\xe9\x0a\xf9\x18\xad\xfb\x3d\xb8\x32\x3f\x44\x7c\x7b\xf2\x6d\xc5\x34\x99\x7c\x38\xb7\xfc\x97\x7f\x64\x2d\xe2\x88\xcd\xf2\x53\x07\x1c\xac\xf3\x56\x4e\x3b\x8e\xd6\xdc\xe5\x7d\xdf\xba\x9f\xf7\x83\xba\xd2\xe7\x6d\xf1\x24\x82\x8f\xc1\x03\x1a\xcf\xad\xf0\x1a\x44\xd4\x1b\x42\x16\x1a\xd9\x06\x03\x01\xc1\xaf\x19\x28\xb9\xe5\xb7\x3b\x9b\xd2\x1c\xac\x60\xa8\x42\xb5\x04\xdc\x3c\xc3\x11\xc5\x22\xe3\xbb\x04\x8b\xf2\x21\x44\x4f\x53\xce\xb0\x8e\x77\xe9\x48\x59\x0e\x94\xed\x98\xf1\xb6\x04\xcb\x9e\xad\xc9\x3b\xbe\x74\x31\xc1\x14\x9b\x23\x19\x3f\xf9\x3e\x85\x69\xf1\x13\xe1\x68\x4d\x89\x76\xec\xae\x6f\x09\xe0\x10\x36\x14\xbe\x41\x8a\x47\x2e\xf5\x5b\xb8\x89\x0d\x72\xb3\x41\xcd\xd7\x50\x5b\x50\xa4\x55\x22\xab\x63\xed\x79\x1c\xe8\xf8\x2f\xed\xdd\x7a\x62\x0a\x4f\x6f\xb1\xd2\xfb\x0e\xd0\xc4\x56\x0d\x78\x44\x6d\x83\xb3\xd1\xb1\xbb\x56\xb3\x66\xd1\x96\x02\x0d\x06\x24\xb1\xfb\xdb\x75\xce\x73\x5d\xd4\x3e\x8e\x8d\xf1\x63\xc4\x4e\x23\x69\x93\xdc\xa3\x41\xf5\x13\x2d\x82\x5d\x0a\x4e\x39\x3a\x19\xd3\x8f\x61\xe1\x1e\x0c\xf3\x92\xcb\x9b\x64\x6e\xa2\x3c\x58\x09\x98\x24\xdd\x8d\x9f\xbe\x26\xa4\x9e\x33\xb2\x3d\xf8\x06\x07\xab\xf1\x97\x15\x79\x9c\x19\xac\xc7\x22\xed\x9b\xcf\x94\xa0\xc2\x9a\xd2\x4b\x78\xb0\xb0\x35\xb3\x24\x1c\x64\xcd\x86\xed\xea\xc8\x10\xe6\x67\x45\x69\x4b\x5e\xb1\x62\x50\x60\xed\xf2\xd9\x49\xde\x0d\x34\xf5\x22\xdf\x2d\xc6\x0a\xe6\x94\xa1\x93\xf3\xb8\x2c\x1d\x6f\x83\xa0\xcb\xb8\x40\xf4\x6c\x49\xa3\xd7\xd1\xcf\x06\xde\xaf\x96\xc6\x4f\x8f\x9e\x17\xbd\x9a\xd5\x12\xae\x63\x09\xc4\x86\xd9\xe2\xa7\x8d\xce\xec\xa4\x73\xa0\x42\x1d\xd1\xb6\x43\xc7\x87\x54\x27\x1b\x53\xce"}, +{{0x3a,0x3d,0x27,0x97,0x0f,0xe2,0xac,0xb6,0x95,0x1e,0xdd,0x5c,0xa9,0x0d,0xda,0x0f,0xc6,0xdd,0x22,0x9c,0x0a,0x56,0xdf,0x6e,0xb1,0x1a,0x9c,0x54,0xd2,0x42,0xdb,0xbf,},{0x56,0x4f,0x0d,0xc3,0xdc,0x47,0x20,0xe6,0x8e,0x44,0xdd,0x16,0x71,0x1e,0x04,0x9e,0x61,0x12,0x00,0x00,0x98,0xfa,0x62,0xa1,0xb9,0x8c,0x28,0x80,0x42,0xf7,0xc3,0xbd,},{0x22,0xeb,0x8e,0xa0,0x50,0x73,0x49,0xb6,0xa0,0xac,0xe2,0x5c,0xf9,0x18,0x0c,0xb0,0x8e,0x03,0x57,0xb0,0x45,0x02,0x90,0x5f,0xbe,0x69,0xb4,0xe2,0x1b,0x2b,0xd9,0x4e,0x22,0xcf,0xbd,0xb8,0x51,0xae,0x71,0x6a,0x5c,0x25,0x3c,0x70,0xd5,0xe2,0xb2,0x4e,0xa7,0x8f,0x35,0xbc,0x21,0x32,0x92,0x54,0x3d,0x94,0xe1,0x41,0x10,0xb2,0x41,0x06,},"\x43\x74\xf6\x1c\x2c\xd8\x8a\x3b\x89\x72\x24\x9b\xfa\x79\xb3\x6a\xb6\x9e\x3e\xd4\x84\xcc\x60\xe5\xd9\x54\x1f\xa7\x68\x6c\xf4\xee\xd1\x21\x0c\x5d\x0d\xcf\x42\xdd\x25\x97\x25\x01\x90\x91\x93\xca\x76\xae\x6e\xb7\xf4\x71\xd8\xbd\x0d\x5f\xb5\xa6\xb4\x31\xbc\x3d\xe0\xe0\x31\x8d\x50\x51\x45\x24\xde\x87\xc4\xb8\x30\x05\xdf\xb4\x12\x45\xfb\x1a\xf7\x9b\x84\xa9\x7b\x83\xd3\xca\xc7\xad\x7a\x53\x36\x4e\x2e\x9b\x21\xc9\x7b\x76\x9b\xdc\x57\xf0\x70\x31\x16\x16\x83\x80\xf3\xcc\x88\x36\x89\xeb\x4a\x7f\xa3\xb2\x6d\xbe\x12\xbc\x28\xf8\xc4\x03\x81\xaf\x64\xdf\x4b\x53\x61\xd1\x74\xcf\x75\xac\xbd\x46\x42\x87\x40\xb0\xd1\x32\x2d\x32\xbb\xe9\x48\x45\x21\x59\x66\xae\x58\x87\x77\xa8\xc0\x53\x36\xe3\x52\x30\x6d\x49\x27\x8d\x32\x8e\x49\x6d\xb6\x5e\x9e\xcf\x6c\xe6\x40\x5e\xd1\xc8\x93\x49\x0b\xc4\x8c\x13\xa1\x34\xe1\xfb\x6e\x80\xde\xbe\x6d\x32\xfc\xe6\xef\x74\x78\x3c\x8d\x77\x98\x0a\x44\x1a\x26\xae\xb4\xfd\x83\xcc\x85\x53\x52\xce\xdc\x18\x8f\x52\x79\xce\x21\x1f\x74\x4a\x40\xb2\x3c\xe7\xff\x24\x43\x7a\x1d\xd3\x37\x3e\xc5\xb2\x90\xda\x1f\x94\xf4\x3a\x07\xa3\xff\xea\x5b\x5f\x67\xb5\x2c\x19\x61\x85\xbc\xe9\xe9\xa8\x58\x25\x7f\xcd\x7a\x8e\xba\xf9\x04\x0e\xd0\x91\xfa\xce\x5a\x15\x5a\xa4\x47\xfa\x15\xe1\x21\x22\xd2\x5e\x8f\xc3\x6e\xae\xe2\x13\x7c\x7b\x3a\xa3\x0b\x7e\x3f\xf6\xcc\x86\xb6\xdc\xb9\xea\xf4\x9c\x95\x76\xf0\xf4\x62\x00\x84\x39\xcb\x1a\x3a\xba\x01\x3e\x89\x7a\x0f\xaf\x99\x4c\xb7\xd5\x9e\xde\x57\x74\xbb\x14\x47\x74\xf7\x3c\xa3\x0e\x64\x14\xa7\xcc\x7c\x74\xb2\x0c\x51\xa1\x40\x4d\xdc\x41\x9e\xf7\x62\x45\x93\xe9\xbc\xfb\x37\xc0\xa7\x62\xea\xb6\x8f\xac\xa5\x86\x34\x43\xe1\x6e\xdb\x75\x9d\xbc\x87\x88\x73\x2b\x9e\x4f\x59\xc1\x11\x92\xc3\xfc\xc8\x72\xaf\x55\xf3\x2d"}, +{{0x06,0xd4,0x98,0x31,0x8d,0xa4,0x56,0x24,0x2b,0x9c,0x3b,0x9a,0xb6,0xd5,0x32,0xa1,0x28,0xfc,0xe0,0x44,0xf5,0x38,0x82,0x68,0x2e,0x92,0x62,0x14,0x9c,0x16,0x52,0x88,},{0x41,0x35,0x17,0xaa,0x63,0x20,0x0a,0x17,0x17,0x32,0x09,0xa4,0xb3,0xe7,0x8a,0xb9,0x38,0x3c,0xb4,0xe3,0x9e,0xfd,0x67,0x94,0xc4,0x6a,0x2d,0x13,0xfa,0xfa,0x99,0xc0,},{0x82,0x50,0xf7,0x6d,0xc5,0x99,0xc5,0x12,0x87,0x87,0xe4,0xf6,0xd3,0xda,0x23,0x17,0x33,0x30,0xce,0x33,0x20,0xdb,0xa9,0x59,0xbd,0x71,0x4c,0xc8,0xcc,0x07,0xc6,0x79,0x45,0xd6,0x3e,0x75,0x66,0x2c,0x07,0x5e,0x26,0x74,0x60,0xab,0x7b,0xf5,0x61,0xf2,0x4f,0xaa,0xe3,0xb4,0x1d,0xbf,0x67,0x68,0x99,0x19,0x1e,0x3b,0x02,0xb5,0xaf,0x0a,},"\x3f\xe3\x0e\xcd\x55\x07\x7a\x6e\x50\xdf\x54\xbb\x1b\xf1\x24\x8b\xea\x40\x63\xe3\xfa\x75\x5f\x65\xfc\xd1\x15\x9e\xe0\x46\xef\xd0\xeb\x5f\x2f\xbb\x38\xb5\xc0\x09\x47\xc9\x7d\xc8\x79\xb3\x6b\x9e\x53\x61\x92\x28\x60\x86\xd0\xdc\x12\x05\x36\x10\x38\x61\x74\xa7\xc5\x6f\x22\xa8\x5b\x73\xff\x20\x8c\x59\x44\xf3\x93\x23\x6c\x32\x41\x58\x09\xda\x03\x6e\x73\xca\xd8\xfc\x3c\x30\x37\x80\x64\xa7\x6a\xfa\x93\x0a\x3b\xaa\xe9\xaa\x35\x70\x61\xa8\xc5\xe8\xe7\x56\xa9\xce\xcf\x94\xb7\x2d\xf4\x3f\xac\xd8\x8f\xa4\x9c\xb4\x94\x8c\x63\x68\x31\x8a\x6b\x1e\x5c\xff\x52\xe5\x87\xec\xdf\xae\xfd\xb6\x90\x81\xf2\x8c\x2d\x13\xbf\x8e\xab\x81\xdb\xaa\x5e\x37\x28\xc4\x31\x7f\xb7\x93\xdd\x19\x6b\xca\x0f\xe5\x4a\x6c\x24\x2c\xf2\x6e\x2d\x12\x9b\xa0\xd8\x2a\x2c\x3a\x45\xbc\x8d\x1d\xfd\x6f\x54\xf8\xda\x4f\x51\x89\xc9\x1a\xc2\x14\xfd\xab\xf4\xc5\x97\x38\x1b\x2e\x5c\x40\xcc\x71\xfa\x70\x51\xcf\x2e\xa9\x39\x06\xa3\x7d\x57\xdf\x12\xd5\xc7\xe5\xcd\x77\xc9\x07\xe4\x42\x56\x63\x15\xba\xe5\x1a\x22\x22\xd6\x2e\x3f\x42\xd1\x76\x78\x82\x63\x7d\x66\xa1\xd5\x30\x5a\xb4\x01\x0a\x0e\x49\xc5\x7d\xef\x69\xdc\xea\x83\x9e\x1b\x76\xa4\x11\x35\xba\x95\x2c\xc4\x24\x95\x0e\x8d\x3a\xac\x19\xe1\xd9\x3d\xe7\x75\x7c\x15\xff\x99\x97\xb3\xd2\xa8\x61\x3c\xd9\xa1\x64\x78\x1d\x1b\xe3\x31\x79\x9f\xa6\x10\x9c\xef\x61\x43\x05\xa1\x95\x8f\x62\x90\x3c\x8c\x9e\xa0\xb2\x3b\xa7\x06\xd4\x9c\x54\xba\xcc\xc1\xe6\x3c\xb4\xbf\x14\x78\x5f\xc7\xb0\x62\xa9\x80\x03\x49\xbd\xb0\xbb\x92\x72\x60\xb6\x77\xb6\x0f\x10\xe6\x2c\x87\x80\xf3\xeb\xb5\xeb\x6f\xf0\x36\x02\x63\xd4\x57\xab\x52\xfd\x11\x25\xc9\xce\x04\x6a\x95\xd8\x9d\x28\x73\x50\xc8\x04\xcf\xd4\xff\x2b\x2d\xdd\x18\xa9\xe1\x35\x19\xf2\x0b\x4d\x1e\x05\x1a\xf6\x24\x64\x0f"}, +{{0x8e,0x8e,0x1d,0xb5,0xb1,0x10,0x2e,0x22,0xa9,0x5c,0x47,0xaf,0x36,0x61,0x46,0x9f,0x00,0x0a,0x33,0xf1,0x3b,0x8b,0x87,0xb1,0x15,0xd2,0x45,0x2a,0x41,0x1f,0x6f,0x39,},{0x56,0xd7,0xb3,0x16,0x9a,0x95,0xc2,0x29,0x98,0xec,0x93,0x79,0x25,0xbd,0x7c,0xad,0x13,0xcc,0x65,0x80,0x8c,0xd5,0xd3,0x4a,0x6c,0x4d,0xa8,0x70,0xea,0xf3,0x23,0x64,},{0xf6,0xee,0x5e,0x13,0xcf,0xaa,0x36,0x2c,0x89,0x71,0xd5,0xa4,0xa8,0x79,0xa7,0xe3,0x69,0x66,0x52,0x5c,0xcd,0x86,0xc5,0xa4,0x8c,0xba,0x08,0xd9,0x13,0xec,0xe1,0xa7,0x9c,0x4c,0xd1,0x46,0xb8,0xe9,0xc6,0x51,0x25,0xfb,0xad,0xf1,0x7b,0xac,0x1c,0xab,0xcd,0xe8,0xfd,0x17,0xcf,0xd6,0x8f,0xa1,0xf9,0xc4,0x4e,0xa6,0x1c,0x08,0xa4,0x05,},"\xb2\x46\x34\xfb\xdd\x1b\x76\x61\x31\x5d\x9d\xc1\x53\xba\x90\xd6\x6a\x88\x62\x2a\x41\x58\xf8\xbc\xff\x25\xba\x9c\x29\xe6\x5f\x29\x7f\x8e\x60\x31\x18\x00\xb7\x33\x1b\x69\xfc\x20\xc9\xf8\x5b\xb7\xc1\x84\xbd\x40\x86\xb3\xa9\xf9\xa2\x71\x02\xb6\x23\x62\xbd\xb4\xfa\x5b\x20\x15\x94\x25\x0f\xc6\x28\xfd\x2e\x0e\x0d\x1b\xe0\x3d\xcf\x81\x8c\x60\x94\xc4\xc2\x91\x21\xcb\x2b\xf6\xd9\x08\xed\x8a\xab\x42\x7c\x37\x71\xc0\xc9\x5f\x0a\xc1\x46\x9a\x08\x10\xb6\x03\xa4\x70\x28\x2e\x59\x80\xa6\x07\x29\x19\x7f\xe6\xc2\x0e\xf6\x81\xcd\x1b\x96\x93\x2d\x20\x58\xf8\x96\xea\x74\x16\x42\x2a\x7e\x54\x1f\x22\x4a\x5f\x04\x25\x30\x80\x74\x1c\x5d\x4e\x3e\xb0\x39\xdb\x6b\xa0\x51\xb4\xca\x54\x17\xce\x8a\xfd\xc7\x02\x14\xba\x4d\xcc\x85\xb6\x23\xd1\x1e\x68\x1c\x60\x09\xae\xe4\xe6\x13\x0a\x83\xed\xd0\xd2\xc9\x9f\xb0\x64\x7e\x11\xed\xe7\x30\x1a\xe5\x6b\x59\x90\x4e\xf7\x02\x57\x32\xcd\xe0\x38\x80\x1e\xc7\xe8\xd9\x0a\x9a\x1b\xba\x04\x7f\xe6\x28\x35\x1b\x3b\x89\xd0\xbc\x5a\xe6\x65\xa7\x00\x89\x1f\x09\xeb\xee\xc0\x55\x91\x84\x2a\xdf\xcc\x25\xad\xc3\xc7\x1c\x1e\xbc\x4a\x31\x2e\x54\x71\xbe\x67\x25\x3b\x0e\x94\x28\xb0\xca\xe3\x76\x45\xa0\xf7\xec\xb8\x9d\xd7\x9f\xbd\x9b\xe2\x87\x54\x33\x66\x7a\xe0\x7d\x74\xa7\x98\x3c\x4c\xea\x60\x1e\x72\xe9\x75\xc2\x1d\xf9\x93\xe7\xfa\x22\xa9\xfa\xbd\x45\x45\x5d\x45\xe3\x70\x31\x55\x8e\x13\xa7\xa4\xf5\xf4\x97\xea\x78\xfb\x73\x99\xf8\x83\x8c\x0f\xd5\xde\x4e\xbb\x66\xdb\x29\x0f\x43\xa4\x86\x7d\x50\x53\x09\xf1\xc1\xbc\x27\xe9\xfa\xbc\xbb\xa7\x13\x02\xfc\x12\x04\x71\x5c\xe3\xfc\xb0\x90\x5b\xfa\x41\x1c\x9d\x1c\x9a\xb4\xa3\x99\x54\xe5\x0b\x8e\x0c\xf7\x36\xc1\x02\x89\x56\x3b\xdf\xa9\x67\x55\x3c\x36\xcd\x9e\x55\x5b\xc8\xcc\x56\xbe\x59\x48\x47\xde\x9f\x26\xf9"}, +{{0x38,0x84,0xb8,0xb7,0x9a,0xbf,0xd3,0xbe,0x6c,0x13,0x98,0x5e,0xb8,0x59,0xab,0x74,0x3f,0x15,0x7c,0xd9,0xde,0xb8,0x1b,0x2f,0xe9,0x7e,0xa4,0xd6,0x17,0x3e,0x46,0xf5,},{0xbd,0x7f,0xd9,0xa8,0xde,0xf1,0x3a,0x54,0x2e,0xd2,0xf2,0xfb,0x04,0x88,0x86,0x88,0x5b,0xa9,0xb5,0xce,0x59,0xcb,0x70,0x19,0xfb,0x54,0x66,0x79,0x86,0xee,0xbc,0x26,},{0xf4,0x20,0x6f,0xcd,0x34,0x50,0x24,0x41,0xd5,0x4a,0x73,0x32,0x3f,0x33,0xa5,0xdb,0xb4,0xc9,0x85,0x57,0x31,0x9f,0x21,0x24,0x6f,0x26,0x0f,0xfb,0xbe,0x58,0x44,0x88,0x6d,0xb5,0x67,0xf4,0xb6,0x3c,0x47,0x94,0x3d,0xbb,0x78,0xfc,0x35,0x65,0x7d,0x7c,0x04,0xd4,0xfe,0xb0,0x42,0xff,0x85,0x36,0xf6,0x72,0x92,0x5c,0x31,0x9e,0xfb,0x09,},"\x12\xad\xaf\xe3\x0e\xaf\x2b\x9c\x72\x03\xca\x5d\x44\xb9\x7f\xfe\xd4\xbf\x65\x17\xa4\x99\x88\xe4\xe6\x76\xc8\xe3\x14\xad\xbd\xbe\x23\xd8\xf2\xd3\xe2\xb0\x81\xa7\x02\x4f\xa5\x25\xab\x5a\xae\x26\xe6\x00\x57\xc1\x01\xe8\xf3\x68\xd3\xad\xdb\x93\x76\xc4\x68\x2c\x1f\x42\x24\xd7\xf1\x49\xa8\x47\x4b\xb9\xa8\xf6\x63\xef\x21\x0e\x95\x72\xce\x82\x9d\xa3\x88\xd8\xaa\xe7\x2a\x46\x71\x41\xad\xc1\x53\x47\x3b\xe3\x65\x3b\xaa\xa6\x4b\x5b\x1e\x2e\x30\x68\x3f\x6f\x06\xda\xc2\x78\x4d\x5b\xbf\x0d\x08\x2a\xab\x47\x30\x5e\xd8\xa8\xef\xd0\x88\x6c\xe6\x3a\x17\x93\x15\x22\x5d\x1e\x4d\x4f\xfc\xf1\xf2\x4a\xc2\xf4\x64\xcf\x5e\xd3\xa8\xb6\xd3\x99\x84\x54\xf1\xc0\x2c\xdb\xf0\xa4\x44\xee\x2b\x59\xdd\xbe\x0a\x17\x4a\x0d\x93\x7f\xa6\x28\x65\x08\x8a\xc6\x47\x49\x99\x57\xd2\x81\xc6\x94\x98\x03\xa5\xfb\xdf\xdd\x0d\xd9\xe9\x1b\x69\x76\x86\x1f\x3c\x5f\x21\x26\xf3\x9a\xac\x93\x5b\xe0\x9f\x4b\x97\x15\xbd\x4f\x0d\x5c\x55\xdf\x73\xa6\xb9\xf2\xc0\xad\x26\xce\x49\xd8\x22\xbf\x85\xbf\xa2\x34\x6f\x31\x65\xb0\x38\x59\xa7\x1c\x3d\x2a\x7b\x86\xdb\x6e\x9f\x2e\x5d\x7b\x16\x9a\x91\x0e\xeb\x7e\xf3\x8f\xbd\xfb\xbe\xc4\x3a\x9a\x25\xf0\x4b\xc3\xac\xfd\x3b\x06\x91\x54\x2a\xb6\xde\x9d\xb6\xf0\x30\x58\xf9\x58\x40\x24\xf9\x91\x8e\xde\xcd\x90\xfb\xb8\x57\x35\xd6\xdc\xec\x5b\xd5\x93\xae\x63\xe2\xcc\x96\x55\x35\x99\xa3\x10\xf8\xf2\x00\x9b\xa9\x53\x71\x19\x6b\x4d\x5b\x80\xe7\x55\x96\x37\xf2\x29\x26\x77\x8b\xe5\xe1\xcc\xef\x51\x26\xe2\x44\x3f\xa9\x39\xc2\xa5\x3d\xdd\xb0\x49\x61\xee\xfd\x34\xe5\x38\xcd\x8d\x7f\x0b\xec\x2b\xff\x1e\xf0\xd3\xa4\xbd\xd3\x58\x31\x76\x37\xf4\x2d\x59\x55\x38\xc1\x12\x22\x51\xa9\x4e\x96\x3d\x1f\x81\xe7\xb9\xae\xb1\x64\xf9\x5d\xa9\xa4\xed\x75\x29\xb8\x45\xeb\xc9\x61\xb2\x7b\x5c\x19"}, +{{0xec,0xd5,0x19,0xf2,0x87,0xad,0x39,0x50,0x52,0xb0,0xb3,0x0d,0xea,0xc3,0x41,0xd2,0xa9,0xdf,0x13,0xd6,0x56,0x7c,0x89,0x1c,0x81,0x3a,0x0c,0x9c,0xa5,0x2e,0x87,0x1e,},{0x8e,0xe9,0x4c,0x58,0x8e,0x0b,0x34,0x35,0x85,0xfc,0x67,0x48,0xfd,0x1b,0x54,0xb5,0x77,0x0c,0x64,0xe9,0x93,0x7a,0x56,0x35,0x7a,0x48,0xd4,0x4a,0xe2,0xf5,0x18,0x24,},{0xe8,0xf5,0x1b,0xe7,0x3f,0xc4,0xe0,0x23,0x5a,0xa1,0x53,0xa2,0xe1,0xb3,0x54,0xe9,0xc5,0xd2,0xd3,0x3a,0x11,0xae,0x0e,0x33,0x34,0x78,0xde,0x1d,0x8e,0x6c,0x44,0x56,0xd2,0xe2,0x50,0x82,0x4c,0x32,0x46,0xca,0x0e,0x8d,0x6a,0xe3,0xe1,0x66,0x77,0xa9,0x73,0x44,0x14,0x41,0x08,0xc1,0x3b,0x95,0x9e,0x1d,0xaf,0x51,0xcf,0x0f,0xe5,0x01,},"\xaa\x71\xbe\x5f\x55\x7e\x10\xc9\xfb\x5f\x09\x1a\x3a\x27\x44\x53\x94\x7c\x07\xa0\xe2\x5b\x26\xf9\x50\x92\x24\x54\x1d\xff\x76\xf4\xd9\x6e\xff\xd0\xd5\xa4\x1d\x31\x9b\xc9\x32\x1a\x86\x66\x7d\x55\xcf\x49\x43\x2f\xb5\xc3\xe7\x15\x38\x8f\x3f\x10\x6c\x91\x74\xb1\x61\x0c\x8f\x30\x75\xd5\x93\x1c\x29\x00\x99\x38\x5c\xe9\x24\x9e\x23\x51\x28\xe9\x07\xc5\x33\x90\x03\x6f\xbf\x5d\xa9\x68\xf8\xd0\x12\x33\x69\x58\xde\x90\xc5\xe8\xe6\xb1\x01\x6a\xd4\x3f\xb5\x7c\x8e\x28\x8d\xaf\xe1\x4e\x90\xe6\x4b\x63\x79\x1e\x5c\xbe\x55\x7e\x02\xdf\x8a\xc9\x37\x06\x42\xa7\x1f\xaf\x85\x10\x75\xe5\x56\x5f\x6f\x9a\x26\x7f\x4f\x6b\x45\x4c\xe4\xc5\x47\x48\x10\xb8\x04\x84\x4d\xda\x38\x39\x29\x39\x71\x97\x93\x24\x6a\xa4\x74\x54\xb9\xb0\xe8\x2e\x98\x03\xc0\x99\x35\xd0\x02\x7f\x39\x95\xcc\xa9\x71\x30\x69\xbb\x31\x02\x7f\x7b\x2a\xf1\x2f\xe5\xfe\xec\x7e\xeb\x06\x84\x3d\x82\x96\xec\x56\x82\x26\x2a\x07\xda\xe7\x47\xed\x7b\xc8\x21\xec\x17\x01\x8d\x89\x9f\xd1\x67\xb3\x6a\x7e\x37\x73\xb4\x27\x49\x9d\x99\xdc\x58\x3b\xbe\x4b\x42\x9a\xfa\x6a\x26\x59\x39\x53\xf9\x43\xe4\x67\x3b\xdd\x0d\x2a\x84\x42\x56\x13\x16\x03\xcd\x09\x03\x25\x6f\x33\x4d\x4f\x8e\xc8\x2d\xe1\x15\xb6\xca\x53\x38\xc7\x5c\x8b\xaa\x44\xb4\xba\x96\x3c\x7c\x78\x51\x0d\x8d\xe9\xb2\xa5\x85\x2f\x42\xf3\x46\x3c\x68\x5f\xb3\xa6\xda\x61\xa8\xe0\x89\x26\x62\xd6\xa2\x50\xfc\xaa\x6f\xef\x74\xd4\x50\xfc\x45\x7b\x98\x71\xd0\x8b\xb5\xbe\x30\x11\x29\x4a\xc8\x88\xfc\xe2\x15\xd5\x35\xc3\xb1\xa4\x3b\xb4\x7e\xfe\x3a\xd2\x5d\xa1\x59\x19\x1a\xed\x55\x19\x54\x69\xc5\x90\x93\xff\xb2\x4f\x65\xd6\x0c\x40\x20\xbf\xbe\x64\x7f\xf5\xdb\x7a\xb8\xa0\x1d\x5e\x48\x7b\x0b\x1b\x64\xef\x25\xda\x15\x6d\xb1\x42\xe6\xad\x87\x2a\x4d\xc1\xee\x9b\xa6\x68\x46\x52\x65\x37\x9e"}, +{{0x19,0x3f,0x3c,0x63,0x0f,0x0c,0x85,0x5b,0x52,0x9f,0x34,0xa4,0x4e,0x94,0x49,0x70,0xf4,0xa6,0x97,0x2e,0x6c,0x38,0x59,0x35,0x9c,0x2e,0x0c,0x87,0x62,0xba,0x9e,0xaf,},{0x32,0x56,0xf2,0xc8,0x2e,0x7c,0x80,0x12,0x01,0x21,0x01,0x40,0x56,0x9f,0xaf,0x18,0x50,0x7e,0x60,0x33,0x8c,0x2c,0xc4,0x11,0x8b,0xb1,0xce,0x60,0x5b,0x0e,0xbe,0x61,},{0xb1,0x25,0x10,0xac,0x5f,0x2f,0x6d,0x33,0x36,0x0c,0xdd,0xc6,0x72,0x91,0xd6,0xc2,0x70,0xfd,0x9e,0xe6,0x2d,0xc0,0x86,0xb3,0x8d,0x93,0x2d,0x26,0x47,0x3f,0xe9,0xa2,0x4e,0xfb,0xd4,0x24,0x88,0x67,0xea,0x7e,0x91,0x5a,0x30,0xc5,0xbf,0xb3,0xb8,0xb1,0x9a,0xa0,0x1a,0xa2,0xfe,0xbf,0x0d,0xac,0x6c,0xfd,0x66,0x38,0xa2,0xba,0x7e,0x0c,},"\x98\x62\x3f\x65\x16\x98\x08\x5b\xde\x02\x76\x2e\x8c\x33\x21\xf1\x4d\xa1\x61\x9b\x5c\x3f\x7c\x1a\x56\x8e\x8c\x26\xff\x0c\x62\xfd\xcc\x41\x24\x75\x91\x2e\xb8\xe8\xc4\xb0\xd3\x09\x18\xb8\xff\xee\xf3\x50\x93\x15\xe5\x8d\xa3\x59\xcd\xc2\xf2\x6b\xeb\xfb\x57\x03\x95\x3b\xe1\x6b\x8f\x3b\xeb\x1e\x54\xa1\xab\xee\x0a\xeb\xe2\x4e\x64\xdb\xe8\x73\x40\x2e\x15\x6f\x37\xdf\xc1\x68\xea\xf8\xa1\x14\xce\x08\xa6\x79\x5d\x3f\x64\xf5\x15\x1e\x9a\x8b\x82\x75\xcc\x7b\x49\xa6\xb8\xd8\xa6\x6b\x6d\x4b\x76\x32\xef\x80\x74\x0d\xc1\xc1\xb0\xa3\x8d\x1a\x28\xf7\xc1\xb2\x9f\xa4\x45\x41\xc1\xaa\xd3\x54\xd4\x59\x0c\x23\x1d\xae\x68\x7a\x2a\x8f\xed\x09\xe8\xc1\xeb\xbf\xcc\x38\xf3\x47\xbf\x06\xd9\x45\x77\xe4\x9a\xd1\x39\xf7\x10\xed\x8b\xb1\xfd\x07\x66\x3c\x03\x20\x84\x6f\xbb\x45\x5a\xb8\x37\xef\x96\x4a\xe7\xd4\xec\xee\xa4\x5f\xd7\xbd\x8d\x50\x9f\x82\x1e\x6e\xb0\x27\x49\x4e\xfd\x8d\xd8\xe9\x92\xb8\x86\x98\xee\xc2\xeb\xc5\xe0\x30\x25\xbe\x78\x9c\x18\x01\x3f\x20\x1f\x77\xaa\x2d\x34\xf5\x68\x64\x60\xe4\x3f\xb4\x89\xe0\x87\x76\xf9\x8b\xcd\xe2\xce\xeb\x9d\x4f\xaf\xdf\xfe\x03\x75\x60\x43\x71\xec\x32\xf4\x6b\x81\xfe\xc4\x74\x38\x29\x08\xe9\xd2\x50\xa0\xba\x27\x80\xa7\xd6\xdf\x40\x7b\xd2\xb1\xeb\x12\x67\x48\xd7\x25\x11\xb9\xb0\x69\xeb\x1c\xd4\x42\x70\xf2\x9f\xe8\x4b\x9a\x71\x77\x51\x83\x1d\x04\xc2\x81\x8e\x40\x8f\x22\x78\x93\x76\xc6\x1c\x2c\xa4\x5e\x32\xe7\x88\xea\xd3\xa7\x53\x6b\xf0\x9d\xa8\xaf\x47\x03\x90\x2f\x55\x16\xa0\x20\xd8\x92\x63\xe9\x37\x01\xa2\x56\x5e\xef\x12\x70\x41\x89\x25\xf3\x5a\x28\x8e\x32\x7b\xab\x62\x8a\xc2\xf0\x24\x8c\xfb\xca\x34\x82\xe2\x65\xd1\x62\x1c\xc3\x43\xc3\x1f\x65\x49\x3f\x06\x4b\xad\x0d\x76\x02\x46\x07\x15\xfa\x48\x6f\x29\x42\x63\x46\xaf\x53\xe3\x33\xb7\x5f\x59\x05"}, +{{0xa8,0x8a,0xd0,0x04,0x8d,0x38,0xc4,0x4c,0xeb,0xe7,0x35,0xea,0x38,0x02,0xca,0x57,0x6e,0x37,0x12,0x1c,0x7d,0x4d,0x76,0x0d,0xfd,0x88,0xde,0x16,0x63,0x06,0x4a,0xbb,},{0x14,0xdd,0x8b,0xb3,0x06,0x80,0x3e,0x5a,0x75,0x8e,0xd6,0x8a,0xd2,0x1d,0x07,0xd8,0x81,0x61,0xd5,0x0f,0x1c,0x74,0x71,0x37,0x77,0xda,0x12,0x09,0xaf,0xba,0xea,0x0b,},{0x13,0x41,0xa1,0x48,0xda,0x45,0x93,0xc8,0x8e,0xbc,0x5a,0x58,0x82,0x1e,0xef,0x77,0xf9,0x21,0x86,0x39,0x0f,0xf6,0x33,0xe7,0x62,0x07,0x08,0x4e,0x78,0x74,0xcc,0xf0,0xeb,0x1f,0x9e,0xc7,0x0a,0x3a,0x3f,0x96,0xb5,0x89,0x34,0xbc,0xb0,0x61,0xff,0x92,0x01,0x24,0xf7,0xe5,0x80,0xfa,0x2b,0x0b,0x27,0x95,0x83,0xad,0xf9,0x23,0x2d,0x0c,},"\x2c\xe8\xbc\xa2\x61\x78\x91\x3b\x16\x76\xe9\x0f\xfe\xfd\x94\x5b\xc5\x61\x98\x26\x60\xe2\xa7\x5d\x48\x2f\xf3\x0a\xab\xa1\xba\x43\xf8\x2d\x2e\x6b\x90\x9e\xc1\x0f\xc0\x97\x89\xff\x5c\xf3\x2a\x51\x80\xb6\x01\xea\x80\xfa\xde\xce\x6d\x7e\x7b\xae\xef\x48\x1d\xc6\x97\x9e\x2f\x65\x8a\xe0\xf6\xd8\xe4\x16\xb9\x32\x98\xf7\xd3\x40\x31\xbb\x76\xf7\x16\xed\x99\x1a\x16\xd0\x9a\x58\x2e\x58\xba\x40\x03\xac\x17\xbe\x8b\x44\x69\xe1\xa8\x89\xb2\xfb\xb2\x28\x9e\x98\xaf\x1c\x6d\x5b\xbe\xe7\x77\x56\x71\x3c\x07\x78\xb0\xdc\x44\x6a\x1f\x6c\x48\xc4\xd4\x08\x18\xec\x79\x99\x05\xf0\x69\xbc\x95\x34\x16\x57\xca\x5d\x02\xb7\xa5\x39\xa1\x3a\x02\xcd\x03\x76\xa5\x0e\x83\x43\xc0\xdc\x20\x34\x6d\xe5\x27\x5b\x1d\xcd\x4a\xd7\xaf\x72\x51\x31\xac\x75\xe9\x54\x82\x5d\x30\xea\xa5\x7a\x68\xbb\x98\xdf\xc4\x1c\xaf\xe5\x71\x05\x56\x64\x7b\x38\x7d\x9b\x7f\xd4\xe4\x76\x51\xe5\x13\x80\x50\x79\x8f\x6d\x40\xf4\xee\x71\x20\xb5\x8f\x74\xda\x94\xd7\x3c\xac\xbf\xd3\x93\xd1\x34\x73\x88\xee\x00\xb7\x9b\x8d\xbf\xeb\x57\x81\x41\x21\xbd\xda\x60\xc6\x27\xdc\xe1\x47\xd4\xd5\x68\xd7\x90\x52\xe9\x7b\x9a\x5f\x3e\xb5\x40\x7c\xc4\x64\x61\xa5\x5e\x18\xa9\x60\xd8\x09\x4a\x5f\xea\x48\xb6\x93\x75\x29\xcc\x4e\xc9\x19\xcd\xbe\xdf\x91\x85\x45\x6d\xc0\x0e\x8d\x98\xad\x15\x37\xee\x10\xa0\x57\xf4\xee\xc4\xb8\x1d\xc6\x03\x92\xfc\x91\x88\xd3\xe5\x61\x78\x59\x65\x09\x2e\x44\x31\x7f\x2a\x48\xe3\x66\x05\xfc\x58\x3f\xc1\x73\xb0\x5d\xb9\xdc\xbc\x75\x57\xd0\x64\x87\x39\x0f\xbb\xba\x77\xaf\x3a\x01\x4e\x1a\xc3\x51\x39\xca\xa1\xc5\x3a\x8d\x17\x34\x7f\x17\x8e\x1c\x54\xd0\xf5\x2b\x40\xe9\x10\x42\xc9\x3e\x7e\x48\x1d\x79\x2e\x28\x8f\xc2\x7e\x4c\x2f\xcf\x11\x1f\xe9\x7d\x9e\x23\x37\xd2\xfc\x1c\x30\x98\xf0\x66\x84\xa3\x1d\x55\xeb\xf3\x62\xc0\x27"}, +{{0x3f,0x59,0xd6,0xa0,0x18,0xf5,0x0a,0x82,0x21,0x17,0xe5,0xb4,0x73,0x60,0x9e,0x30,0xcd,0x64,0x92,0x0c,0xa1,0xc2,0x75,0x0d,0xcb,0x09,0xea,0xab,0x80,0x7a,0x3e,0xac,},{0x45,0x7d,0x0e,0x59,0xc1,0x1f,0x34,0x8f,0x3b,0xfb,0xdd,0x3f,0x32,0x7d,0xe7,0x8c,0x0a,0x75,0x77,0xc0,0xae,0xef,0x42,0xd4,0xc1,0xe5,0x67,0x00,0xd1,0x08,0x80,0x8b,},{0xd7,0x42,0x5e,0xa1,0x94,0xa6,0x71,0x5c,0x45,0x2e,0xc4,0xf6,0xd6,0xc7,0x6e,0x6d,0xd3,0x74,0xd3,0xca,0x7a,0xe7,0xa1,0x19,0x95,0xd0,0x2b,0x94,0x2d,0x4a,0x31,0x87,0x0d,0xd7,0x34,0xc1,0x2f,0xca,0x89,0xa8,0xeb,0x02,0x13,0xeb,0x13,0x9c,0x14,0xa8,0x7a,0x6a,0x33,0xe8,0x18,0x60,0x3b,0x2e,0x31,0x30,0x23,0xfa,0x58,0x73,0x7d,0x0e,},"\x7d\x10\x3a\x6c\x6b\xa2\xd0\x90\x87\xee\xf2\x25\x4c\x1c\x90\x3f\x06\x76\x95\xa5\x4c\x45\x15\xe4\xd1\x3b\xc1\xfb\xfb\x54\xd6\xe7\xa1\x67\x34\x9c\x14\x80\x99\x76\xda\x04\xa7\xe5\x8d\x96\xb4\x0a\xac\x3b\x2b\xdd\x14\xb9\xb5\x03\x22\xbb\x11\x64\x5f\x05\xe5\xe9\x78\xbc\x7f\xbd\x02\x49\x2e\xf8\x8f\x87\xd6\x68\x28\x0f\xd7\x08\x37\x32\x07\xff\x67\x0f\xcd\xa9\x7d\xf8\x48\x5d\x5e\x46\xdc\x3b\xd0\x43\x47\xf4\xd7\x52\x7e\xab\x27\x18\xf7\xd9\x3d\x13\x2b\xa7\x75\x82\x18\x89\x4e\x75\xa7\xde\xab\xe6\x93\x33\x5b\xa0\xdc\x73\xbf\x26\xc2\x88\xbf\xe9\xbe\x8a\x73\x6d\x75\xe5\xe0\xea\xa7\xbb\xe8\xd0\xb7\x7a\xbd\xd5\x14\x6e\x0f\xc9\xb3\x0d\xb9\xf0\x7c\xf4\xbf\x36\x26\x0a\x1f\x41\x41\x03\x31\xf8\xb4\x7c\x6b\x38\x33\x8c\x6d\xc9\xe8\x01\xff\xe1\xd5\x85\xf9\xb7\xfc\x31\xe9\x77\x8b\xca\x30\x27\xc2\x32\xc0\x74\xcb\x18\xe5\xb7\x29\x97\x00\x5f\xfe\xee\x4b\xf3\x7c\x8f\x87\x4b\x1b\x24\x6a\x63\x45\x41\x5d\xac\xac\xa7\x07\x5a\x60\x44\x3a\xc3\x31\x92\x36\xe2\x3c\xf6\xb7\x54\x47\x40\x80\x70\x52\x11\x49\x84\xb8\xd8\xf7\xe8\x57\xdc\xc6\xfa\xec\x88\x69\xcf\x96\xb9\x97\xdf\xa9\xaf\x91\x84\xad\x62\x3f\x1d\x90\xb8\xca\x75\x9b\x44\x8e\xab\xfc\xe1\x8c\x17\xcf\xdf\x9a\x3e\x33\x12\xe6\x3e\x5f\x08\x4c\xea\x90\x4c\x1c\x90\x99\x13\xcc\x4b\x19\xd0\x44\xa3\x72\x00\x34\x97\x3c\x73\x84\x94\x9b\xd6\xf9\xba\x92\x56\xf9\x8c\xd3\x94\xc5\x66\xda\x83\xc3\x11\x80\x10\x9f\x16\xd1\x03\x47\xb7\xe3\xe9\xdd\x6b\xe3\xbd\x3c\x77\xff\x1a\x79\x96\xa0\x78\xdc\xf8\x9d\xcd\xce\x2d\x1b\x61\x56\x95\xf4\xcc\x9f\x8f\x4f\x2a\x08\x80\x46\x41\xbc\xa8\x26\x62\xce\x88\xfa\xa5\x31\x45\xb6\xa4\x59\x55\xae\xc8\xcc\x2a\xf8\x1c\xcc\xb5\xd7\xc6\x4f\x9e\xce\x1c\x99\x83\x32\x64\x84\xa1\xe5\xec\xe4\xce\x36\x54\x4d\x63\x73\x5f\x77\x76\xf2\x1a\x20"}, +{{0xa1,0x21,0x2b,0x34,0xdb,0xca,0x63,0xb7,0x09,0x36,0x12,0xd0,0x5d,0xab,0x7b,0x4c,0xc8,0xf7,0xb6,0x76,0xa9,0x34,0xad,0x01,0xf6,0x59,0x85,0x1b,0x3b,0xb4,0x4e,0x4e,},{0xba,0x2f,0xcc,0xea,0x9a,0x08,0x05,0x91,0xbe,0x71,0x26,0x8d,0x7e,0x95,0x1f,0x25,0x0d,0xed,0xc0,0x04,0x16,0xe5,0xf3,0xf9,0x08,0xdb,0x6c,0xc5,0x71,0x25,0x49,0x25,},{0xfa,0x93,0xed,0x65,0x95,0xbc,0x95,0x8d,0xc0,0x42,0xce,0x16,0x45,0x16,0x7b,0x79,0xe8,0xf6,0x73,0x4c,0x46,0xf8,0x0f,0x63,0x1f,0xd5,0x48,0x49,0x08,0xf5,0xe5,0x1a,0x22,0x42,0x7e,0xe6,0x86,0xf5,0x64,0xff,0x98,0x2f,0x6e,0xf4,0xd2,0xca,0x1f,0x0c,0xa5,0x62,0x49,0x10,0xcd,0xd6,0x3c,0x11,0xa3,0xc2,0xb1,0x6d,0x40,0x97,0x3c,0x07,},"\x07\xc3\x7c\x46\xbe\x3c\x68\xd0\x56\x89\x57\x7a\xa6\x4a\x93\x2b\x90\x64\x46\xb2\x9b\xaf\x12\xf6\x17\x4a\x6b\x42\xbb\xae\xfd\x1f\x1f\x37\x3e\x0b\xcc\xc4\x73\xdd\xfc\xee\x1a\x7f\x21\xb9\x6a\x62\x60\xef\x0a\xa1\xf2\xd8\xb2\x95\x9e\x71\xd1\x2c\x95\x33\x58\xa2\x77\x4c\xc5\xe6\xf3\x79\xa3\x13\xe4\x35\xed\x69\xdf\xd6\xd4\xa5\x9a\xde\xe3\xcc\x7e\xc4\xba\xcb\xdb\xb3\xfe\xe5\x43\x0b\x73\xf6\x05\x1a\x60\x96\xc6\x0e\x9b\xc9\x2c\xc8\xfa\x05\x9f\xac\x2a\x93\xef\x70\x07\xd6\x4f\xbe\x50\x06\x49\x64\xd5\xa0\xad\x60\x11\x75\xcd\x9c\xab\xa4\x53\xf9\x10\x3b\x25\x48\x55\x45\xd3\x01\xf0\x3c\x5f\x9f\x94\x78\xbd\xf9\xd4\x14\xbf\x1d\xca\x3b\x1c\x1d\x9d\xaa\x99\x71\xf9\xe6\x17\xfb\xfa\xf5\xb0\x2a\x7f\xbd\x5d\x4f\xb8\x94\xc0\x97\x5c\x54\x59\x2b\x49\xa0\xfc\x85\xdd\x08\x53\xf3\x0c\x51\x50\x2d\x98\xfc\x1a\xb8\x5a\x17\xcc\x58\x96\x1a\xae\x97\x64\x57\x0b\xa5\xcb\xdb\xc9\x6d\xfc\xeb\x8d\x11\xda\x53\x36\x4b\x40\x25\xfe\x0b\x8b\xa8\xa3\x53\xad\x23\x68\x67\x20\x16\x9f\xe9\x73\x43\x2f\xfe\x29\x1a\x4b\x11\xde\xdd\xa0\xaa\xc7\x9a\x5e\x42\x62\x0a\x64\x58\x7d\x20\x59\xe7\x87\x01\x3b\x40\xce\xec\x59\x92\x08\xf6\x6e\xd0\xca\x6e\x1b\xe9\x09\x2e\xc2\x7d\xb2\x16\xee\x6d\xad\xfe\xbc\x21\x70\x5b\xc4\xa8\x5a\xee\x57\x7e\x57\xd2\x39\xaf\x58\x6e\xfe\xec\x22\xcf\x38\xd1\xcf\xb3\xcd\x74\xdd\x0d\x9a\x33\x81\xaa\x81\xe6\xa2\x97\xe3\x9b\x81\x91\x37\xad\x27\xd4\x75\xe2\xbf\x54\xaa\x42\x6d\xc2\x9c\x4c\xa8\x17\x6d\xf3\x43\x13\x7a\x2d\x79\xd1\x2e\xf9\xaa\x7b\xe1\xcf\x67\x75\xe5\xd8\xa4\x43\x0a\x85\xc3\x3d\xb6\x1c\xd2\xf3\x51\x87\xb4\xf6\xea\x9e\xbd\xd7\x53\xd1\xc4\xef\x72\x47\x11\x59\xff\x07\xb7\x78\x70\x90\x64\x96\x24\x9d\x42\x78\xe3\xf3\xca\x6b\xcb\xf3\x7a\x26\x5b\x89\x65\x39\x19\x0f\x9a\x31\xf1\xe7\xb4\xb6\x5c\xd1"}, +{{0xd9,0x68,0x20,0x86,0xfe,0x7d,0xda,0x30,0xb8,0x71,0x11,0x06,0x01,0x93,0xd8,0x47,0x56,0x6a,0xb9,0x4c,0xfd,0x9c,0x97,0xab,0x6b,0x43,0xe7,0xa8,0xd3,0xf7,0x93,0x82,},{0x8b,0x0b,0x13,0x72,0xd8,0x87,0x33,0xef,0x72,0x33,0xf6,0x37,0x97,0x90,0xd1,0xe4,0x6e,0x1e,0x07,0xe9,0xd3,0xfb,0x8b,0x0b,0xe2,0x52,0xed,0x04,0xc5,0xfa,0x16,0x3d,},{0x17,0x93,0xe4,0x97,0xeb,0x52,0x1c,0xa7,0x4e,0x35,0xd1,0x4a,0x63,0x86,0x8c,0xbe,0x94,0x99,0xda,0x2f,0x21,0xb4,0xeb,0x52,0x60,0x34,0x0f,0xca,0x3c,0x1f,0xec,0xa7,0x8d,0xbe,0x5b,0x14,0xac,0x10,0xf3,0xfa,0x76,0xfa,0x2e,0x71,0xe4,0xc9,0x14,0x61,0xaa,0x75,0x97,0x7e,0x5e,0x70,0x79,0x26,0x70,0xef,0x7f,0xf0,0xe6,0xa2,0x87,0x08,},"\xe8\x81\x4b\xe1\x24\xbe\x3c\x63\xcc\x9a\xdb\x03\xaf\x49\x3d\x44\x2f\xf2\x0d\x8b\x20\x0b\x20\xcd\x24\x93\x67\xf4\x17\xf9\xa9\xd8\x93\xfb\xbb\xe8\x5a\x64\x2b\xe2\x70\x1d\x1d\x1b\x3c\xd4\x8a\x85\xcf\x58\xf1\x59\xa1\x97\x27\x31\x43\xa5\x78\xf4\x2e\x8b\xcc\x8b\x62\x40\xf9\x32\x71\x90\x05\x38\xff\xc1\x87\xc0\xaf\xc8\xdb\xcc\x49\x2b\xcd\x67\x9b\xaa\xef\x3a\xf5\x08\x84\x34\xa9\x45\x86\xf9\x4b\x49\x97\x0b\xba\x18\xf5\xea\x0e\xbf\x0d\x27\xee\x48\x2a\xa8\x3a\xd0\xdd\x0e\xe6\x09\xdf\x59\xd3\x7f\x81\x8b\x2c\x8d\x7c\x15\xf0\xf6\xf5\x44\xdd\x4c\x7e\x7c\xb3\xa1\x67\x24\x32\x4f\x77\xd5\x89\x48\xf8\x47\x5a\x60\xd5\x3e\x5b\xd5\x10\xc1\x71\x37\xc9\x9e\x1c\xfa\x51\x5a\xf9\xbc\x85\x56\x9d\x21\x2a\x21\x19\x07\x29\xf2\x81\x7d\xe8\xc4\x69\x15\xe0\x21\xdf\x70\xff\x6d\x60\x21\x5f\x61\x4f\xc2\x11\x39\x90\x4d\xf3\xb2\x92\xb7\x49\xdc\x4d\xea\x02\x51\x8b\x62\xd1\x58\x62\xc9\x2d\x2a\x4c\x99\x67\x01\xcd\xec\xae\xd8\x4a\xb6\x28\xee\x98\x4f\xc1\x11\xee\xcb\x59\xe4\x84\x44\xef\xc0\xd4\x56\xe2\xc8\x52\x51\x84\x41\xc3\xdb\x76\x30\xdd\xd5\x15\x62\x49\xa2\x87\x30\x98\x38\x38\xae\x59\xac\x4c\xc7\x11\x0f\xd6\xde\x68\x10\x1e\xa5\xb2\xff\x69\xfd\x36\x4e\x3c\x94\x48\xde\xfe\xfe\x17\x5b\xcb\xe1\x17\xcc\x11\xb4\xff\x75\x49\xc3\x3e\x10\x25\xb6\xb5\x92\x04\x8a\x8e\x31\x96\x9e\x81\x8d\xcc\x18\x8b\xb1\x9d\x7a\x24\x40\xa3\xba\xba\x4e\xb1\xb8\x1c\x45\x67\x9d\xb4\x6b\x31\xbc\xde\x77\x76\x75\x7d\x99\x31\xec\x20\x63\xfc\x6f\x1f\xcd\x76\x1e\xcc\x57\xa7\xd0\x30\xa8\x5e\xa2\x73\xef\x18\x25\xb0\x50\x92\xab\x96\x45\x35\x9a\x44\x4f\xf7\xd1\x66\xb5\x75\xfa\xc2\x98\x30\x8d\x9f\xaa\x68\x46\x3d\x1d\x0f\x7b\x7d\xf8\xa5\x1c\x68\x15\xd3\x71\x59\xad\xc0\xb5\x93\x22\x4a\x81\x83\x21\xd7\x21\x9f\x09\x68\x6c\xfc\x95\x22\x59\x71\x8d\xfc"}, +{{0xb5,0x2b,0x24,0x9a,0x7a,0xea,0xe0,0xfb,0xd9,0x4f,0xfc,0xf9,0xa9,0xfd,0xe1,0x0d,0xe6,0x1c,0x3f,0x4c,0xbd,0xa1,0x4b,0x28,0x9f,0xe0,0x1f,0x82,0x70,0x73,0x34,0xca,},{0x73,0x51,0x63,0xbf,0xcf,0xd5,0x4f,0x9d,0x35,0x2e,0x1c,0x2f,0x3c,0x01,0x70,0xc9,0x5c,0x18,0x42,0xcc,0xc7,0x42,0x16,0x23,0xae,0x04,0x96,0x98,0x0c,0xee,0x79,0x1c,},{0x6f,0x48,0xa9,0xf7,0xf0,0xfa,0x19,0x2b,0x66,0xd1,0x21,0x75,0xa3,0x33,0x61,0x23,0x03,0xe1,0x80,0xb9,0xfa,0xb1,0x8e,0xda,0xbe,0xbc,0xdf,0x66,0x74,0xfd,0xfc,0xc5,0x36,0x07,0x08,0x9b,0xf9,0x80,0xce,0x35,0x89,0x4c,0x2f,0x9b,0xab,0xdc,0x44,0x38,0x66,0x7a,0xb3,0x29,0x7a,0x62,0x48,0xec,0x02,0x69,0xfa,0xa9,0x9c,0x72,0x48,0x07,},"\x1d\x44\x5e\x8e\xe3\x6f\x6e\x10\x64\xee\x12\x81\xe6\xb4\xa4\xce\xc5\x0a\x91\xc2\xb6\x67\xc8\x30\x5d\x1e\x9a\x5f\x7b\x73\xa3\x44\x58\x82\x58\x1f\xb0\xc1\x1e\x64\xf6\xee\x92\xe8\x11\xf9\xf2\xd6\xc5\x9c\x63\x44\xbe\x76\x91\xd1\x16\xdd\xa4\x93\xca\xde\x51\xc0\xce\x77\x37\x2b\x61\xa7\xc4\xfb\xb6\x33\x40\x13\x33\xcb\xf7\x13\x72\xad\x2f\x04\x4e\x99\x2a\xc0\x35\xf5\x87\x9c\x05\x30\x04\xf8\x22\x3f\x23\x7a\x24\xa4\x09\xb7\x89\x4f\x6a\xd5\x18\xe0\x46\xb8\xa8\x4c\x3f\x4c\x62\x60\xe6\x16\x9f\xd9\x44\xd5\x7f\xbc\xf9\xba\x27\x75\xf2\xd6\x0e\xd7\x72\xc4\x6c\xcd\x63\xc8\x50\xb8\x0d\x58\x7c\x52\x08\xdf\xb1\xa2\x58\x78\xc0\x2d\xec\xe3\xe6\x02\xe9\x63\x2f\xc3\xc2\xc7\x9b\x25\xab\x41\x03\x4c\x6e\x26\xb8\x69\x25\x53\x57\xa6\x86\x78\x1d\xfe\x6e\x64\x4b\xeb\xa9\xb6\x27\xda\x1f\xcb\x5e\xc0\xbe\x49\x7c\xf1\x88\xe1\xef\x1a\xf0\x60\x1b\xf1\x6b\x29\x11\xfd\x9f\xf3\x4f\x0e\x97\xac\x95\xa7\xfe\x2c\xf9\x0e\xa6\xce\xd3\x3c\xcb\x0e\xd1\xef\x2d\x41\x60\xef\xb0\x7c\x59\x1a\x5c\xb1\x6c\x70\xca\x16\x94\xfb\x36\xf2\xca\x19\xeb\xa5\x2b\xe3\xd4\xad\x89\x5a\xbc\xad\xa4\xb3\x6f\x02\x61\xd6\x5f\x59\xe0\xcf\xd2\xa6\x14\x8a\x88\x92\xdd\xbb\x45\x81\x0d\xb3\xbf\x4a\x9e\x26\xe9\x2c\x15\xea\x26\x18\xcf\xee\xb4\x62\xd8\x62\x8f\x25\x4f\x54\xd2\xaf\x27\x11\x3b\xab\x4f\x9a\x7d\x06\x79\x18\x11\x94\x2b\xdc\x32\xf8\x45\x92\x2d\x7b\x2d\xdb\xa9\x59\x14\x09\x28\xf8\xc2\x8d\x98\xb4\x4e\x1d\x19\xb9\x7f\xd3\x9c\xc0\xf9\xa5\x23\x6d\x34\x9f\xc8\x35\xac\x49\x21\x92\x46\x2e\x40\xac\x62\x9b\xeb\xff\xd2\xeb\xa7\x2d\x27\x88\xb2\x44\xbb\x77\x7a\xd0\xf7\xb7\xf9\x6f\x23\x41\x23\x99\xfc\x1d\x87\xa1\xd0\x87\xba\x08\x90\x27\xea\xbb\xc0\x5e\xda\xfe\xe4\x33\x79\xe8\x93\x29\x13\x31\xb4\x60\xbf\xa7\x33\x2e\x08\x42\xec\x25\x73\x39\x3d\xe9\x53\x06"}, +{{0x78,0x2a,0x93,0xef,0xe0,0xef,0x06,0xcb,0x25,0x34,0x33,0x0e,0xfd,0x0e,0x96,0x84,0xe9,0x96,0x9b,0x52,0x58,0x12,0x3e,0x49,0x02,0x39,0xbf,0x24,0xbf,0x9f,0x65,0x23,},{0x94,0x2f,0xa1,0x40,0x6e,0xe2,0x68,0x3e,0x29,0x37,0x7e,0x49,0xf7,0xba,0x75,0x7c,0xf5,0x0e,0xf0,0x72,0x37,0x07,0xd4,0x40,0x3d,0x28,0x62,0x25,0x70,0x45,0xde,0x87,},{0x93,0xe7,0x40,0x5a,0x40,0x44,0x51,0x01,0x66,0xc8,0xac,0x26,0x4c,0xe3,0xb5,0xba,0x66,0x65,0xd6,0x8b,0xad,0x45,0x87,0x12,0xdc,0x93,0xc2,0xc3,0x90,0x56,0x8d,0x74,0x02,0xef,0x7d,0x57,0xf5,0x49,0xb8,0xa1,0x04,0x2f,0x7f,0x69,0xa6,0x79,0xaa,0x85,0x5f,0x34,0xf8,0x01,0xd5,0x7d,0x79,0x89,0x5d,0xeb,0x8d,0xea,0xdb,0x35,0x23,0x08,},"\x46\xa4\xe3\x19\xa6\x70\xac\x99\x39\x94\xa5\x33\x00\xc3\xf7\x91\x44\xc2\xf7\xfe\xc1\x11\x6e\xee\xb3\x62\x1c\x76\xac\x35\xda\x79\xdb\xff\x6e\x18\x9c\xa9\xdb\xfc\x9a\xbb\xda\x05\x48\x47\xb2\x97\x1b\x02\xfa\xce\xbb\xe9\x26\xd4\x69\xeb\x0a\x86\x03\x89\xac\x74\x41\x62\xbf\x6f\xb1\x3b\x42\xcb\x9b\xb8\xc9\xd7\x26\x07\x13\x8e\x78\x00\x12\x1e\xe0\xcd\x63\x3e\xd5\x35\xc7\xae\x5f\x40\x60\xbb\xdd\x27\x1c\x9d\x11\x0a\xbf\xf5\xe0\x60\xea\x6e\xe8\x38\x90\xb1\xe9\x2a\x92\x56\xd7\xb2\xba\x98\x2a\x31\x14\xbb\x6d\xef\xfe\xe2\x69\x6f\x0a\x2f\x9c\x21\xaa\xa5\xb2\xde\xfa\x11\xaa\xb7\x07\x6d\xe6\xe5\x7e\x86\xf2\x84\xbb\x67\xf5\xa4\x9e\xe6\x85\x92\x10\x32\xc9\x5b\x74\xe7\xe3\xea\xc7\x23\xf1\x75\xaf\x08\x2c\x85\x8e\x0d\xfa\x01\x72\x8c\x38\xfb\xbb\x4c\x83\x58\x1f\x81\xac\xe6\xc6\x3c\x6b\xda\xac\x56\x20\xeb\x9a\x56\x8e\x7e\xbb\x7b\x72\xb3\xd1\xa1\x64\xef\x52\x4e\x7b\x9f\x00\x79\x9a\xb0\x86\x71\x59\x76\xc1\x4d\x0d\xf6\x5f\x7b\x96\xbf\x9e\xbc\xda\x7f\xee\xef\x11\x34\x22\x00\x1a\x03\xa7\x63\x3d\xf5\xe4\x99\x39\xa1\x21\xdb\x89\x9d\x9b\x8a\xc2\xdb\x4f\xad\x0c\x30\xcf\x0b\x8b\xdb\xc9\xe9\x80\x2a\x79\x7c\x82\x38\xe4\x65\x11\xff\x24\x06\x8c\xad\xcf\xf2\x44\x8c\xc0\xbf\xf9\x27\x69\x22\x33\x48\xd4\x5d\x6b\x6f\x2c\x8f\x15\x93\x38\x8c\x0b\xbb\xf4\x4b\x6d\xdb\x50\xb9\x8c\xd7\xf0\x9c\x73\x0f\x7d\xe4\xd0\x08\x15\x6c\xb3\xcd\xe0\xca\xb3\xad\x0a\x58\xa8\x39\x54\xe2\x34\xa0\xa8\xa0\x4b\x57\x3c\x9a\x8e\x9b\x92\x9e\xd3\x8b\x8b\x22\x8b\xf5\x5a\x3c\x6e\x2c\x6b\x51\xf6\x82\x65\x2f\xbb\x70\x8e\x74\x64\x0e\x33\x13\xe1\x7b\x46\x94\xd7\xfd\xf0\x11\x1f\x90\x60\x8c\x1b\x5a\xf4\x22\xdc\xde\xca\xd9\xdd\xb7\xf5\x0d\x1b\xf5\xbc\x63\x78\xcc\xaf\xfc\x32\x01\xe6\xc7\x87\xb4\x8c\x44\x3b\xa2\x40\xd9\xd5\x0f\xf6\xc0\xe9\xdf\x7f\x1a\x5b"}, +{{0x6f,0xe7,0xbc,0xf7,0xa6,0x84,0x42,0x3d,0xe1,0x07,0x6f,0xd7,0x6d,0xa7,0x83,0x42,0x33,0x73,0xb3,0x81,0x32,0x9e,0xfd,0x61,0x57,0x42,0x4e,0xc4,0xb2,0x65,0x5a,0x94,},{0x77,0x40,0xe9,0x1a,0xfe,0x45,0x32,0x4f,0x8b,0xb9,0x90,0xca,0x2a,0x34,0x12,0x79,0xdd,0xaf,0x23,0x2c,0x3b,0xb4,0x15,0xf1,0x78,0xb6,0x09,0x2f,0xba,0x19,0x5f,0xec,},{0x99,0x14,0xcc,0x50,0xfe,0xf0,0x93,0x5e,0xfb,0x89,0xb3,0xd6,0x4e,0x3c,0x1c,0x34,0x12,0xae,0xd6,0x59,0xb9,0x01,0x66,0x22,0x2c,0x0d,0x13,0xec,0x1c,0xe3,0xa6,0x8a,0xe6,0x28,0x1b,0x7e,0xfd,0x9d,0x4e,0xc6,0x4b,0x82,0xe7,0x3e,0x14,0x47,0x9f,0x03,0xfb,0xac,0x8f,0xa3,0xab,0xdb,0x41,0xea,0x42,0x15,0xc4,0xa4,0xd4,0x94,0x9d,0x09,},"\x0b\xaf\x0a\xd4\x40\x61\x2b\x4c\x5a\x13\x6c\x3a\x42\xbe\x1c\xa2\xb7\xc3\x19\x86\x2a\x44\xa9\xfd\x50\xc4\xee\x73\x54\x1c\x5e\x64\x57\xef\xa8\x18\x25\xb6\xdd\x4a\x72\x19\x4a\x29\x68\x68\x8b\xd4\x9e\x5a\x8f\x4c\x04\xdb\xaf\xc2\xe7\x88\x4c\x0c\x70\xc2\x08\xd4\xe9\x54\xcd\x16\x75\xda\x8e\x74\xc6\x5c\x49\x7c\xf9\xdc\x69\x42\x49\x65\xbd\xcb\xa5\xde\x52\x93\x6f\x92\x5f\x62\xe2\x01\xf9\x95\x05\xd3\x77\x7b\xeb\x3c\x2e\x08\xb2\xec\x9a\x87\x3e\x5a\x9c\x21\xfb\x4a\x2f\x3e\x86\x1f\x3c\xf4\xd6\xb5\xdc\xd1\xc8\x8b\xcd\x91\x63\x53\x9a\xc6\x2c\xd0\x65\x9f\x4e\xf2\x32\xc2\xce\x57\xfc\x77\xf9\x02\x85\xeb\x35\x01\x69\xed\xc6\xa8\x06\xff\x50\xf6\x1c\x7e\x0b\xee\xeb\xec\xec\x63\xbf\xc9\xd3\x98\x3f\x5b\xb4\xb2\x61\xc7\x46\x47\x1f\xcb\xf2\x89\x2c\x61\x08\x97\x0b\x68\xdb\x5e\x43\xc4\x50\x4d\xda\xe2\xd0\xff\xff\xa2\x8b\x67\x59\xae\x11\x28\xe1\x6f\x66\xd4\x92\xad\x61\xe3\x72\x2c\x96\x0f\x88\x69\x2b\xe8\x1a\x9f\x41\x28\x90\xff\xa3\x46\xe7\x02\xc8\x67\xdf\xa2\x59\x70\x3b\x73\xf5\x25\x07\x4f\x32\x27\xc4\x9c\xec\x1b\x64\x5a\x10\x3b\xd4\x47\x1f\x33\xf9\xf1\xba\xc3\x27\xd7\x91\x78\x61\xd0\xad\x91\xab\xee\x60\x22\x2e\xa2\xa3\xc8\xca\xc0\x52\xae\x9a\x2c\xbd\x90\x85\x5d\x73\x3d\x53\x19\x13\x3f\x95\x41\xbd\x0b\x61\xf0\x99\x52\x68\x35\x1e\x28\x63\xc1\xca\x2c\xa5\x1e\x3c\x97\x63\x83\xf5\xc4\xc1\x1f\xf4\x10\x03\x6f\xd5\x1d\x5a\xc5\x6b\x02\x3c\xe9\x02\x9c\x62\x0f\x22\x55\x70\x19\xad\x9b\x42\x64\xed\x4d\x71\xb4\x34\xf4\xa4\xd1\x7a\x7d\x57\x69\xfa\x1e\x14\xa6\x9f\x7a\xe4\x19\xcc\xf5\x94\x7f\x8c\x76\x82\x69\x71\x16\xc2\x40\x5f\x5a\x19\x59\xc5\x4b\x48\xf0\x87\x2f\x59\x6e\xd4\x59\x64\x48\x8d\xde\xc1\x2b\xdb\x63\x6d\x0b\x34\x9e\x74\x9e\xb6\x60\x92\xff\x45\x11\xfb\xa5\x9b\x59\x62\xcb\x93\xcc\x85\x51\x5c\xc8\x6a\xb0\xc6\xb2"}, +{{0xdd,0xa4,0x8a,0x0d,0x15,0xa2,0x9e,0xba,0x9a,0x76,0x30,0x5d,0x36,0x0e,0x46,0x6e,0x72,0xd8,0x04,0x0e,0xfe,0x2e,0x89,0xc0,0x4b,0x64,0x61,0x31,0x5a,0x9b,0x8b,0xf4,},{0x4f,0x5c,0xc3,0x6a,0x80,0x94,0x16,0xb5,0x8e,0x15,0xd2,0x4c,0xc5,0x79,0x68,0xcb,0x57,0x3b,0x76,0xad,0x90,0x88,0x7a,0x8e,0xf3,0x6c,0xde,0x7e,0xca,0x40,0x0f,0xcc,},{0xce,0x71,0xbc,0x82,0xd5,0x31,0xd0,0xf9,0x3b,0x57,0xbf,0xdc,0x2f,0x73,0x16,0xcf,0x40,0x4e,0xe0,0x9a,0xf8,0x8f,0x33,0xbf,0x80,0x6c,0x7c,0xad,0x6b,0x8f,0xfa,0x36,0x62,0x36,0xba,0x74,0xe7,0x5c,0x15,0x09,0x6d,0xda,0xa6,0xe3,0xa6,0x2a,0x8f,0x5e,0xb1,0xc8,0xc3,0xf6,0xb6,0xc9,0x4a,0x6a,0x34,0x9f,0xc7,0xc0,0xcb,0xfb,0x19,0x0d,},"\xf5\xac\x19\xb8\x1f\x21\x11\xa0\xdb\x0a\xe3\x0d\x15\x13\xed\x34\x3e\x7f\x57\xf7\xf7\x7d\x65\xb8\xac\x7c\xe3\xa6\x01\x17\x4b\xae\xd9\xbf\xa1\x36\x03\x59\x76\xf5\x16\xd5\xa8\x70\xf4\x5d\xb1\x91\x9f\x1e\xb1\xcb\xec\xbe\x88\xec\x32\xd1\x91\xe9\x24\x88\x21\xa7\xe7\x68\x1f\xe3\xab\xec\x11\x58\x4b\xdb\x33\xde\x1b\x4c\xa9\x48\x91\xeb\x66\xdc\xb8\x53\x9a\xc4\x11\x63\x73\x6c\xcf\xd6\x9a\xbb\x83\x81\x4d\xd3\x8c\xd6\x03\x81\x31\x87\x28\x05\x2a\x25\xcb\x66\x54\x71\x05\x86\x50\xcc\xc7\x57\x56\xdb\xee\x68\x8a\xb8\x26\xec\xad\x4a\xd5\xa7\xdb\x57\xe8\xf6\x5f\x1b\x64\xab\xff\x82\xdd\x53\x33\x4b\x79\x7a\xc4\x02\x28\xdd\x81\x7f\x23\x9d\x3e\xe8\x04\xa1\x9a\xea\xc8\xcf\xe3\x3e\xb6\x57\xec\x9c\xe9\x23\xd6\xb3\x88\x91\x4c\xfb\xa2\xe7\x2b\xfc\x2b\xc3\xd6\xf9\x85\xc0\xd9\x75\x34\xdb\x95\x8e\xed\xe5\x7b\x16\x49\x1f\xfb\x75\x5c\x1a\x58\xd7\x8a\xb3\x77\xfa\xec\x0d\x31\x18\x18\xe8\x99\x26\x0e\x3e\xbd\x1c\xcd\x29\x24\x6f\xa8\x2d\x0b\x76\x62\x2b\x2c\x4b\xc5\x2f\x54\x9f\xee\x72\xa3\x0f\x55\x4f\x33\x1f\x36\xd2\xa7\x4d\x99\x9e\xc1\x0a\x08\x29\x4f\x00\x2b\x43\x61\xe5\x90\x27\x9c\x2f\xb1\xbd\xa4\x31\x2c\xcb\x24\xd7\x52\x82\xce\x7c\x06\x1a\x0c\xa5\x52\x0c\x74\xf6\xf6\x33\x3b\x18\xc4\xb5\x41\xcb\x6c\x51\xe0\x15\x75\xba\x80\x51\x2f\xfa\x7c\xe0\xac\xcd\x22\xd1\x40\x27\xc5\x3a\xba\x1f\x74\x37\x83\x5f\x11\x14\xd6\x8e\x3a\xcf\x3f\xf8\xde\x94\xc8\xe4\xef\x6d\x3a\xb3\x12\xc9\x1d\x02\x97\x01\x57\x50\x8f\x54\xa5\x81\x6f\x46\x7a\x21\x4e\x9b\x12\x84\x30\x02\x89\xe6\x5f\x36\x5a\x61\x0a\x8e\xa2\x84\x66\x6c\xfe\x55\x18\xe4\x35\xbc\xcd\x21\x62\x75\x01\xc7\x25\xf0\xb8\xeb\x57\x25\xe0\xe0\x6e\x0c\xef\x5d\xb2\x01\xb4\x8e\xc9\x1e\xbf\x87\x8d\xd5\x7c\xe8\xda\xc7\x33\x48\x48\xa1\xbc\x82\xc1\x8b\x06\x59\x55\xe4\xf5\x9b\xe3\x39\x85\x94\xdc"}, +{{0xec,0x57,0xb9,0x41,0xad,0xf3,0xca,0x13,0xe7,0x7a,0x78,0x05,0x77,0xcf,0xd0,0xdf,0x5b,0x49,0xed,0xc8,0x53,0x51,0x05,0x2d,0xa3,0x4e,0x99,0xf8,0xa9,0xbf,0x32,0x08,},{0x28,0x59,0xc0,0x71,0x97,0x8a,0x04,0xb7,0xf5,0x40,0x7b,0x6d,0x22,0x40,0x1a,0x78,0xef,0xd0,0x39,0x4b,0xb9,0x66,0xb9,0xa0,0x4d,0xa6,0xb5,0xef,0x81,0x9d,0xe3,0xfa,},{0x11,0x8e,0x14,0x62,0x12,0x6b,0x45,0xb8,0xc6,0x80,0x35,0x23,0x75,0x5c,0x56,0xdf,0xc4,0xe1,0x23,0xe4,0xac,0xbb,0x66,0xba,0x0b,0xa6,0xfe,0x3e,0x05,0x3d,0xa4,0x11,0x9f,0x57,0x19,0x29,0x5e,0x0c,0x82,0xac,0x64,0xd7,0xc5,0xcb,0x1a,0xc8,0x98,0xdf,0x26,0x3d,0xdf,0xd3,0x60,0xf3,0x00,0x8d,0x91,0x01,0x8b,0x26,0xf6,0xa1,0x73,0x0a,},"\xd2\xbc\xbd\x1b\xc3\x61\xab\x32\xc6\x6d\x72\xfd\x48\xa8\xe2\x27\xdc\x6b\x8d\x6b\x15\x08\x48\xba\x71\x5f\xf4\x7d\xd3\x5c\x8e\x49\x38\x1b\xb4\xe2\x93\x3f\x42\xcd\x26\xb7\x5b\x14\xd9\xc0\x03\x92\x82\xb6\x2b\x85\x56\xaa\xa1\x1c\xd6\x91\xe8\x28\x38\x2b\xe3\x06\x88\x9f\xc9\x20\x51\x37\xb1\x69\xd3\xbf\x17\xb7\xf3\x76\x93\xfc\xe2\x86\x03\x9f\x03\x80\x9d\x7d\x9d\x98\xc8\xfd\xe4\x6f\x11\x01\x94\x2a\x27\x9c\x51\x67\x06\xf5\x01\x91\xa9\x11\x2f\x6a\x24\x63\x0e\x1a\x26\xc3\x21\xe4\x6c\x9c\xcc\x85\xb6\xef\x94\x2f\x35\x3a\x64\x2b\x9e\x7e\xf9\x98\xc0\xfc\xe2\xd3\xa7\x5b\x99\x9e\xeb\x77\xf3\x1f\x9b\x08\x13\xa9\x7e\x30\x14\xc3\xa8\x6e\x25\x58\x73\x46\x21\xa3\x06\x6d\xae\x35\x84\x50\x31\xe3\x56\x65\xf1\x92\x29\x07\xdb\xb7\x39\x78\x6a\x8b\x76\x58\xab\x60\x27\x6f\x2d\x92\x1d\x1a\x51\x23\x0f\xc7\x4d\x19\xe8\x01\x84\xa4\xf1\x0e\x9e\x83\x4a\xbc\x9a\x36\xc4\x29\x72\x6b\xc0\x55\xdc\x8c\x06\x3f\x0e\xca\x9c\x61\xa8\xa9\x70\xbd\x4b\xb5\xf4\x24\xee\x4d\x04\xbf\xc2\x95\xe3\xbb\x1f\x34\xbe\xcb\xd9\x92\x0f\xe2\xe7\x7f\xcf\x36\x76\x3f\x32\xfc\x9c\xfd\x5e\x46\x59\x79\xc1\x67\xca\xbf\x5a\x12\x44\xb4\x91\xfc\x06\xb8\x94\x64\x19\x04\x6b\xa5\x16\xc5\xb2\x33\xc4\x14\xdd\xef\xb6\xda\x04\xf2\xe1\x3d\xaf\xf7\xa9\xa0\xc0\x2a\x51\x8e\xde\x57\xad\x95\x21\xde\x64\xed\xdf\x6f\x49\xa9\x67\x0f\x63\x2d\x3f\x7d\x42\x42\x52\x07\xd0\x53\x60\x4f\xe3\x9d\x13\xb9\xf5\x2c\x8b\xc2\x92\xb0\x07\x6e\xa4\x2a\x56\x00\x56\xdf\x25\xde\x51\xad\x35\x88\x1d\x08\x54\x32\x24\xd7\xfa\x5d\x70\xb8\x60\x3e\xf2\x3c\xe0\x63\x39\xd6\xcd\x09\xe2\x2a\x95\x74\x9e\x50\xdf\xbd\x3b\x8a\xd6\x9f\xd3\x04\x96\xb9\x84\xd1\xc0\xa1\x99\xc8\x59\x48\x05\xf3\x8b\xa4\x46\x31\xa2\xc5\x9e\xad\xc6\x55\x4d\x19\xf9\xbc\x98\x36\x6d\xfd\xec\x2a\x12\x1d\x0e\x48\x14\xd2\xcd\x3f\x58\x71"}, +{{0xcb,0xfd,0x91,0xd7,0x69,0x5c,0x1f,0x27,0x0f,0x69,0x24,0x6a,0xb3,0xdf,0x90,0xed,0xb2,0x14,0x01,0x10,0x1c,0xa7,0xf8,0xf2,0x6c,0x6d,0x00,0xf4,0xdc,0xb7,0x23,0x3e,},{0x51,0x38,0x79,0xcf,0x79,0xd2,0xf4,0x6d,0xf4,0xb8,0x5a,0x5c,0x09,0x49,0xeb,0x21,0x16,0xab,0xf9,0x81,0x73,0x5a,0x30,0x31,0x64,0xcb,0xd8,0x5a,0xdf,0x20,0xb7,0x52,},{0xf3,0x36,0x13,0x7d,0xfe,0x6f,0x42,0xa6,0x66,0x9b,0x55,0xf7,0x4b,0x80,0xb3,0x03,0x5a,0x04,0x03,0x67,0xf9,0x06,0x56,0xfc,0xef,0x0a,0x64,0x4c,0x52,0x27,0x2d,0xdc,0x39,0x27,0x3c,0xd7,0x72,0x60,0x10,0xeb,0xcd,0x8a,0x30,0xa0,0x52,0x01,0xab,0x70,0xb8,0xff,0x97,0xd0,0x28,0x8a,0x2c,0xb9,0x4c,0xbc,0x49,0x02,0x06,0x47,0x39,0x0b,},"\x26\x4a\x93\x3f\x7d\x0a\xec\xba\xc1\x3e\xef\x64\x4b\x0b\x53\xdd\x53\xa1\x28\x09\x04\x10\x0d\xbc\x1a\xb8\x7b\x51\x14\x89\x98\xf9\xda\x0b\x3a\x0a\x63\x37\xf5\xe3\x48\x6c\x2b\x7e\x54\x8d\x21\x12\x59\x39\x7a\xaa\x19\x4e\xe4\x69\x5b\xf9\x8c\x2d\x5f\x44\x87\x69\x9f\x73\x97\xe5\xd3\xa7\xe6\xd5\xf6\x28\xfb\xd0\x54\x97\xc5\x56\xa5\x0a\x4d\x05\xe2\xb7\x12\xcd\xbc\x35\x10\x68\xe4\x2a\xf1\x95\x38\x90\x1b\x88\x25\x31\x0e\x34\x3e\x1a\x17\xa1\x86\x7d\xde\x0e\xb4\x7d\xda\xb4\x56\xd3\x16\xf3\x52\x15\x54\x93\x7b\xf8\x08\xae\x4e\x4b\xc1\xc3\xc5\xb4\x75\x6e\x4a\x16\x5a\xd9\xe8\x82\x7f\x53\x16\xf7\x48\xca\xc6\x99\x8e\xd2\xd2\x10\x4f\x26\x84\x07\xc1\x35\xe6\x2f\x26\xa9\x22\x46\x0e\xab\x6d\x85\x16\x39\xa0\x0e\x5f\x08\xb3\x47\x65\xea\x02\x44\xf4\x75\xbb\xfe\xac\x18\x3e\x3b\x5b\xd1\xaa\xb7\x98\x52\x27\x98\xa0\x8e\xc6\xbf\x22\x57\xd4\x69\x2f\x5b\x03\xcd\xd0\xa2\x13\x3d\xe9\x70\x60\x3e\x32\x51\x47\x5a\xad\x8d\x93\x4a\xf6\xb2\xbf\xc7\xa6\x50\xb9\x1b\xde\xc1\x43\xf8\xad\x25\x4c\xfa\x50\x6b\xbf\xf2\x8a\x03\xbe\xb6\x59\xef\x5e\x5d\xdf\xfe\x76\xe2\x32\x30\xc4\xcc\xd4\x63\x10\xb3\x7d\xd9\x1f\xa6\xaa\x68\x16\x7f\x62\xa5\x5c\x8a\x69\xf9\xed\x1e\xc6\xcd\xb1\x44\xdd\x81\xab\x0b\xcb\xd6\x26\x43\x42\x0b\xca\xe6\x78\x69\xf6\x4c\x0b\x16\x9f\x3c\xdf\x3c\x90\x58\x95\xb7\xd3\x5b\x6f\xaf\xda\x25\xcc\xf2\x3c\x3d\x10\xde\x32\xe7\xf2\x71\xe3\x00\xd3\x95\x97\xda\x8f\x84\x37\x22\xef\x08\x36\x4a\x5f\x7a\x10\x5b\x96\x55\x17\x2d\xf7\xc8\x2d\x73\x74\xf9\x82\x64\xc9\xcd\xcc\xb4\x96\xf2\xe1\x0f\xd8\x26\x2f\xb1\xa9\xa9\x96\x5b\x0b\x84\x1a\xc0\xd0\xe9\xc1\xa3\xd9\x49\x3e\xa7\xaa\x60\x02\x05\xb8\xf9\x00\xbe\x0d\x7a\xbb\x4d\x98\xa0\x65\x83\xd2\x29\x5c\x27\x63\x18\xbe\x28\xd4\x21\x98\x2d\xed\xd5\xbf\xc3\x3b\x88\x65\xd9\x4e\xf7\x47\xd6\x26\xaf\x99"}, +{{0x51,0xa4,0x19,0x7a,0xb7,0x68,0x6f,0x82,0xf6,0x00,0x3a,0x0c,0x32,0xf3,0x9d,0x0f,0x2e,0x47,0x55,0x5f,0x4e,0x9f,0x8d,0xee,0xe7,0x5b,0xcb,0x1b,0xd1,0xef,0x69,0xe5,},{0x06,0x38,0x6d,0xf8,0x6b,0x61,0xf1,0xf8,0xf4,0xdc,0x45,0xb7,0x3e,0xda,0xa8,0x41,0x92,0x09,0x68,0xbb,0xd1,0x31,0xcc,0x5c,0xa1,0xc5,0x29,0x4e,0xee,0xd5,0xc8,0xba,},{0x2c,0x07,0x29,0x69,0xff,0x47,0x19,0x21,0x2a,0x12,0x19,0x38,0xb5,0x06,0xc6,0x02,0x99,0x5b,0x4d,0x02,0xa2,0x2e,0x61,0x98,0xd6,0xe8,0x7d,0xd6,0xae,0x07,0x62,0x25,0xac,0x70,0xbb,0x25,0xef,0x8c,0x0e,0xe8,0x1e,0xb6,0xfe,0x95,0x3d,0xf6,0xb1,0x81,0x59,0x49,0xe8,0xed,0x05,0x06,0xcb,0x01,0x2e,0x87,0x3c,0xd3,0x6c,0xd0,0x9b,0x0a,},"\x2a\xed\xb7\xe8\x2f\x1f\xe4\xce\x46\x9a\xda\x48\x34\x5d\x00\x6d\x1b\x3b\xff\x40\xeb\x21\x86\x7f\x51\xfc\xe9\x65\x64\x0c\x40\x9e\xc1\x3a\xd4\xd5\x2f\x89\x1b\xd7\x90\x66\xd6\xb4\xd9\x44\xca\x86\x8d\x89\x86\xd2\x42\xb5\x7e\xcc\xc4\xc4\xa4\x88\x29\x1b\x15\x9c\x8d\xe4\x39\x2b\xe4\xb8\x6f\xeb\xaa\x75\xea\xc5\xd2\x2d\x3c\x4f\x8d\x6b\xef\x79\xad\xb9\xb9\x2b\x49\x14\xd5\xea\x07\xc7\xf0\x21\xe2\xc2\x9f\x58\xd0\x7b\xe8\xa0\x84\x10\x0b\xc1\x52\xd5\x1c\xa8\x97\xd7\xc1\x31\x64\x4d\x08\x95\x32\x2e\x94\x40\xa8\x33\x9e\x1a\xa3\x90\xa7\xf4\xfc\xb5\x1d\xdf\xb6\xdf\x48\xaa\xf5\x67\x63\x37\xd8\x7d\xdd\x85\xb1\xd9\x25\xe1\xa9\xc2\x9f\xe0\x81\x8f\x51\x4e\xf7\x2f\x74\x7a\x67\x49\x46\x47\x69\x07\xa7\xca\x99\xe9\xdb\x8d\x20\x96\x41\x05\x7a\x7f\x44\xa3\x17\xb9\x09\x74\xbc\x86\xf9\x61\x7a\x96\x8a\x76\xa6\xb8\x38\x7c\xf5\x85\x3e\x60\x81\x90\xc1\xa7\x9f\x1e\x1d\x68\x6e\x0d\xe2\x2d\xb6\xcd\x9a\xeb\x85\x32\xc5\xc8\x5c\xc9\x0b\x5a\x01\x85\x79\xf2\x8e\x50\x2a\x77\x0a\x4e\xc6\x75\x26\x3d\x0d\xd7\x81\xb4\xfa\x53\xc9\xdb\xf8\x09\x8d\x57\xb3\x3a\xe2\xaf\xba\xeb\x3e\x68\x26\x6a\xd9\xaa\xb7\x17\x4b\xa6\x8c\x64\x79\x88\x39\x92\x67\x0c\xcf\x3e\x5a\xc6\xa1\x7e\x65\xe3\x1e\x1f\xdc\x85\xe2\x69\xc8\x09\x35\xef\x57\x4f\x20\xd2\x39\x56\x84\x86\xe7\xd9\x4a\x4f\x72\x4a\xb7\x00\x60\x98\xb2\x4f\x3f\x61\x58\x76\x91\x43\x5c\x7f\x29\xce\x4e\x5c\xa7\x1b\x2b\x18\x74\x55\x64\x33\xa3\x58\xc8\xc5\xef\x3c\x88\x08\x43\x03\x0c\x2d\x13\xd5\x1b\x78\xc9\xbf\x1a\x88\x24\xe6\x2e\x11\x18\x44\x39\x6f\x5a\xf2\xe2\x5c\x31\x26\xef\x36\x26\xe2\x6e\xfa\xfa\xcf\x99\x83\x0a\xa4\x12\x12\x33\x2f\x37\x8a\x16\x72\x33\xa0\xb4\x22\x13\xaf\xe3\x6d\x83\xdc\x45\x82\xa7\x96\x93\xb9\xd5\x71\xa5\x77\x12\xa0\x8b\x85\x66\xd3\x61\xac\x90\x26\x47\xaf\xc8\x86\x60\x3e\x24\x28\x3e\xfb"}, +{{0xb1,0x11,0x9c,0x36,0x11,0x8b,0x7a,0x06,0x5a,0x19,0x5b,0xfb,0x8b,0x79,0xa5,0xc2,0x87,0xe0,0x9b,0xd2,0x87,0xc2,0xda,0xac,0x5e,0x6b,0x01,0x16,0x4c,0x5d,0x73,0x7f,},{0x88,0xf2,0x18,0xec,0xba,0x99,0xe7,0x70,0xed,0x21,0x4a,0x8d,0x01,0xa9,0x2a,0x10,0x40,0x0a,0xca,0xf1,0xf6,0xee,0xd4,0x20,0x06,0x7e,0x13,0x6e,0xe2,0xc0,0xc6,0x70,},{0x24,0xec,0x1e,0x54,0xfc,0x7e,0x72,0x2d,0x37,0x55,0x1d,0x02,0xcf,0x13,0x5d,0x33,0xf5,0xd3,0xff,0x53,0x57,0x73,0xe0,0x29,0x91,0xee,0x85,0xff,0xd3,0xaa,0x29,0x99,0x7f,0x9c,0x46,0x44,0x70,0x19,0x7f,0xee,0x81,0xdc,0xe1,0x10,0x60,0x9f,0x87,0x0b,0x27,0xc1,0x8d,0xfb,0xcf,0xd9,0x32,0x05,0x48,0x52,0x5e,0x93,0x14,0x8e,0x22,0x05,},"\x88\x16\xb1\xeb\x20\x6d\x5f\x6d\xcc\x2e\x4c\xc3\x91\xd2\x32\x09\x00\x6d\xe9\x35\xe3\x18\x15\x2e\x93\xfc\x8c\x2c\xf0\x8e\x26\x43\x2b\xad\x9a\xdb\x32\x03\xd8\x98\xdf\x0a\x2e\x7f\x1f\x83\xdc\x2f\x3e\xd3\x20\x5b\xec\x8e\xfc\xfd\x31\xad\xc1\xac\xa5\x75\x5d\xb9\xbd\x4e\xfe\x54\xcc\x17\x07\x30\x77\xde\x4a\x3f\xdd\x11\x99\x6e\x84\xb6\xa0\x52\xf0\x34\xb4\x10\x99\x22\x6c\x9c\x27\x2e\xae\x12\x52\x8f\x16\x58\x1b\x91\xb8\x12\x85\x0c\x20\x71\x44\xdb\xff\x3e\x85\x0c\xca\x84\x8e\xc2\xb1\xdd\x16\x47\x44\xd7\xb5\x93\x37\xd7\xe3\xef\xef\x00\x81\x62\xe6\x80\xbd\x4a\x08\x99\xce\xd6\x0b\x17\x1f\x8c\xbe\xb4\x8c\x51\x58\xdf\x6c\xbf\xdb\x26\x24\x08\x81\xbd\x58\xeb\xb8\xb6\xa0\x79\x58\x72\x79\x67\x9c\xb5\xad\x82\xf3\x71\xb5\x3c\x80\x13\x80\x4c\x35\x59\x6c\x88\x7e\x43\x6d\x23\x92\x6f\x99\x4e\x09\xd9\x8f\xbb\x8c\xe2\x70\x41\x74\xef\x38\xb6\x82\x62\xa7\xf1\xa7\x12\xda\x0e\xf0\xde\xc6\x39\x60\x68\x14\xb3\xbd\xca\xf2\x53\xff\x31\xc4\x8e\x8a\x75\x2c\x11\x1b\xd7\x10\x10\x31\xcc\x3d\x38\xef\xb0\xc9\xc7\xf1\x9c\x59\x08\x15\x84\xa0\xe0\x15\xee\x7c\x75\xb1\x0a\x4c\x51\xff\x54\x3a\x30\xe5\x2d\x5f\x94\xd8\x18\x8c\x6b\x08\xe9\xdf\x1e\x84\xa4\xe2\xc8\x07\x17\x0a\xc1\x24\xa7\x71\xb9\x94\x65\xa0\xd3\x8b\x1f\x1c\x63\x30\x40\x3c\x82\x54\x35\x82\xc5\xbb\x61\xb2\x20\xde\x1b\x9e\x0e\xf6\x9b\xda\xe2\x60\x23\x18\x1b\xa4\xcc\x07\x7a\x5f\x0d\x42\x57\x32\xac\xe1\x32\xae\x0c\x6f\xf0\xbb\x18\xba\xea\x83\xe8\x87\x7a\xfb\xe6\x50\xfe\x0b\xd0\x20\x93\xf0\x0a\x7b\x53\x65\x72\x8d\xcb\x66\xfb\xb8\x81\xf5\x92\x94\x50\x58\xa5\xb3\x50\x66\x5a\xf9\x1c\x55\x7a\x54\x72\x50\xad\x29\x5e\x68\xb4\xfb\x72\x45\x7c\xfb\x9d\x5e\xa1\xa7\xb2\xa3\x9c\x9a\xb7\xd7\xac\xe0\xaf\x5d\x51\x66\x9c\xb6\xc2\xc4\xc0\x7b\x22\x56\xd1\x0e\x5f\xfc\x6b\x97\xc6\x60\x00\x63\x13\xc4\xeb\x8d"}, +{{0xcb,0xb5,0x87,0x51,0x4e,0x0a,0x34,0xff,0xc3,0x4c,0xbc,0x04,0xf2,0x8c,0x9b,0x4f,0x64,0x65,0xf1,0xeb,0x22,0x5c,0xca,0x19,0xb8,0x64,0x87,0x6d,0xae,0xf3,0x7d,0x7f,},{0x6b,0x70,0x5d,0x46,0x77,0xd2,0xd8,0x49,0xb6,0x74,0x4b,0x1e,0xbe,0xd1,0x67,0xdb,0xcb,0xf6,0x45,0x92,0x4b,0x1f,0xf2,0xe6,0x36,0x07,0x94,0xbd,0xd0,0xe0,0x97,0x88,},{0x12,0x74,0xd6,0xf3,0x56,0xeb,0x64,0x14,0x72,0xb6,0xb9,0xe5,0xb3,0xce,0x65,0xd2,0x65,0x4e,0x6c,0xb8,0x7d,0x3a,0x83,0xfb,0x49,0xd0,0xf7,0xda,0x9c,0x44,0xbe,0x2b,0x53,0x26,0x04,0x46,0x5f,0x60,0x89,0xd6,0x80,0xd2,0xd9,0x4b,0x0e,0xdd,0x2b,0x6b,0x2b,0x80,0x5c,0x5e,0x84,0xc3,0x79,0xef,0xc0,0x59,0x67,0x3d,0x31,0x00,0x7a,0x09,},"\xbd\xf7\xd1\x7c\x70\x67\x96\xef\xd3\x48\x95\x59\xb5\x27\xb1\xc0\x58\x4b\x90\x22\xc9\xcb\xda\x3a\xac\x51\x46\xda\x34\x0d\x9c\xea\x69\xf9\x16\x03\x7c\xd2\x1b\x3e\xb1\x10\x43\x48\x88\x0f\xd5\xc5\xb7\xc6\x5f\xf8\x20\xf7\x49\x93\x46\x01\x69\x51\xcb\x71\x5d\x8d\xf2\xb4\x1c\x88\xcd\x3c\x66\x10\x54\x58\xb7\xb5\x90\xc2\x1c\x1a\xe2\xf6\xea\x9d\xde\xa7\x47\x0f\x25\xe0\x20\x27\xd1\x71\xe0\xe5\x74\xa2\xbb\x21\x64\x2f\x8f\x9d\xa5\x08\xe2\x1d\x8e\x73\x35\xb5\xac\xe5\x93\x52\x99\x40\x7b\xd1\xb0\x1b\xdd\x14\x23\x13\x3e\xf0\x45\x23\x4e\x70\x1f\x55\x54\x94\x34\xad\xe9\x4a\x60\xbe\x1e\x14\x06\xca\x5c\x75\x8c\x36\x79\x9c\xe1\x70\x30\x84\x47\x6e\x48\x4f\xb1\x74\x05\x30\xae\xe8\x42\x66\xd0\x7a\xdf\xb4\xcc\x68\x9f\x32\x65\x13\x3a\x59\xcd\xf9\x92\xfb\xb9\xa4\xb1\x2d\xef\xbe\x24\x1d\xdb\xf6\x5d\x12\xb2\xfb\xdd\xfc\x05\xaf\x0f\xb8\xde\x42\x08\x07\x75\xba\xd2\x9c\x6b\x04\x59\x84\x1c\xbb\x64\x8a\x9a\x95\xe4\x8d\x6e\x36\xac\x51\x44\x80\xa3\xde\xb4\xb3\x65\x54\xd8\xda\x62\x08\x08\xae\x9d\x47\x32\x97\x10\xd2\x0a\xaa\x6e\x5d\x7f\x54\x7d\x81\xad\x30\xf8\x4c\x0e\x3d\x23\x9c\xde\x5b\x16\x9d\x9d\xdf\x29\x48\x32\xd6\x7a\x80\x60\xba\x32\x9c\x4e\xf3\x9b\xe9\x4a\xc4\x64\x34\xdd\x21\x85\x93\x1d\x12\x31\xf9\xb6\xdf\x87\x8a\x5a\xf0\x83\x1e\x0e\x9d\x8a\x08\xd0\x80\x69\xde\xd6\xa9\x61\xef\x7f\x39\xfa\xd5\x01\xff\xd1\x7d\x6d\x9b\x7c\x65\x46\x53\xc1\xf5\x8f\xce\xe1\xa6\xcd\x80\x3d\x2a\xef\x16\x6c\x78\xef\x55\x14\xa3\x27\x6d\x69\x98\xdc\x7c\x09\xa3\xfa\x98\x2e\x42\x7c\x78\x5a\xa6\xa9\xe2\x56\xf7\xba\x72\xd5\xa6\xba\x33\xeb\x46\xf1\xf9\xfe\x9b\xe2\xbf\xc1\x41\x09\xf6\x47\x73\xc0\x0c\x06\x3b\x4d\x5c\xb4\xf4\xf8\xa0\xbe\xca\x92\xa9\xa0\x16\xc4\xf5\x40\xfe\xea\x9c\x3a\x31\xe3\x13\xbb\xcb\xc2\xff\x5e\xca\x99\x67\x85\x7f\x5f\x8a\x90\x9a\x29\xd7\xf2\x0d"}, +{{0x8b,0xde,0x3f,0xf6,0x1a,0x16,0x99,0x5a,0xb9,0xd5,0x39,0xf6,0x05,0x32,0x19,0x08,0x1b,0xca,0xea,0x1d,0x45,0x8e,0xc3,0x36,0x84,0xfc,0x1c,0x01,0xfb,0x56,0x5b,0xfa,},{0xcd,0x9d,0x78,0x2a,0x35,0x6e,0x84,0x7b,0x7a,0x04,0xc8,0x85,0xa9,0xb0,0x90,0x7c,0xc3,0x3b,0xa9,0x7a,0xd5,0x39,0x0d,0x4e,0xa5,0xfe,0xe5,0xeb,0x19,0x8d,0x08,0xb3,},{0x74,0x64,0xdf,0x0b,0x67,0xeb,0x90,0xb4,0xb7,0x3f,0xf0,0x82,0xad,0x0d,0x60,0xeb,0xfe,0x06,0x60,0xda,0xe9,0x70,0x69,0xb5,0x2c,0x37,0x27,0x22,0x3b,0xf7,0x0e,0x29,0xe4,0x87,0x11,0xa2,0xbb,0xb4,0x38,0xf5,0xf8,0xd8,0xa3,0x3b,0xb9,0xc4,0x8f,0xe7,0xb6,0x28,0xfa,0x8a,0x54,0x2f,0xf0,0xb5,0xae,0x36,0x26,0x9d,0x40,0x07,0xa5,0x05,},"\xa1\xf4\x0e\xc5\x80\x7e\x7a\x27\x06\x9a\x43\xb1\xae\xbf\xf5\x83\xef\x03\x70\x28\xc0\x2c\x85\x95\x25\xeb\x8f\xa4\xc3\xba\x95\xa9\x01\xff\x3a\xed\x78\xc4\xf8\x77\x52\xfb\x79\x55\x22\xf5\xbf\x71\x5b\xe7\xe3\xde\xfa\xc1\x0f\xcf\x17\xe3\xfa\x5c\x54\xb2\x00\x89\xa4\x72\x33\x33\x27\x25\x2e\xc9\x45\x71\x8f\xb4\x55\xe3\xf2\x7c\xcf\xde\xf8\x23\xd1\x2d\x40\x6e\x62\xa4\xae\xba\x3c\xb9\xd1\xc6\x1b\x2b\x17\xe4\x9e\x20\x0a\x84\x18\xf9\x35\xf2\x6e\xeb\x57\x60\x2c\x7a\xa3\xb3\xa2\x4f\x7e\x62\x38\xd3\xe0\x8d\x2d\x60\x9f\x2e\xad\xa0\x33\x2b\xc8\xcb\x12\x91\x6c\xb0\x3b\x0d\x4f\x9c\xd6\x02\x00\x25\x86\xd3\xe4\xcc\x7e\x0e\x03\x81\xc0\x45\xad\x2e\x1e\xe2\x82\x98\xae\x7f\xcf\x0c\x10\xf2\x12\x80\x85\x65\x29\x6f\x15\x8d\x2c\x32\xe8\xcb\x28\x15\x65\x81\xaf\x52\xbf\xc3\x47\x0c\x3c\x95\x82\x13\x8d\x22\x55\xe8\x42\x6d\x64\x8c\xa2\x37\xd7\xaa\xd2\x85\x6f\x17\x16\x38\x55\x82\x41\xd8\xae\x3f\x62\xba\x92\xdb\x59\x65\x68\xed\xee\x3e\xc0\xef\x37\x0f\x83\x62\x6a\xa0\x44\x5a\xf0\x8f\x96\x78\x63\x66\x0e\x8f\xba\x5a\x41\xc8\xe8\xed\xe1\xc9\x60\x51\x4a\x14\x68\x7a\x4a\x81\xe7\x76\xae\x0e\x8e\x77\x7f\xb0\xf2\x50\xd5\x1a\x83\xb5\x5f\x8c\x1f\xfd\xd7\x8d\xf3\xbd\xc9\x7f\xf1\x77\xaf\xec\xa0\x46\xc7\x2d\x72\xaf\x92\x4a\xd0\xd0\xab\x2b\xfc\x11\xb7\xf4\xab\xde\xd5\x1c\x39\x87\xa8\xbb\x94\xd6\x40\xc8\x71\x0e\x5f\xc9\xa4\x19\x0e\x8a\x00\x83\x63\xd7\x41\x9c\xea\x17\xc4\x0d\xea\x20\xea\x51\x56\x02\x9f\x3d\xeb\xf0\x52\x41\x91\x8f\x54\xaf\x50\x39\xe2\xc4\xcf\x2c\xa2\xe1\x39\xf6\x0e\x45\xcc\x65\x59\x5c\xdf\x54\xa6\x7d\x92\xb6\xac\x66\xfc\x0c\x5a\x29\x04\x95\xca\x57\xb0\x7e\xf5\x75\x0d\x05\xf5\x7d\x87\xd0\xc2\x28\xf7\xe4\xe1\x5a\xd0\xba\x01\x78\x73\x0f\x95\x1c\x69\x75\x83\x48\x1c\x66\xcb\xfc\xd4\x80\x32\x54\x4a\xa8\xd5\x09\x08\x30\x4b\xd8\x19\x40\x30\x87\x06"}, +{{0xda,0x59,0xbb,0xc5,0x23,0x40,0x4f,0x07,0x64,0x6a,0xdd,0x79,0x08,0x29,0x49,0x77,0xe4,0x66,0x45,0xbc,0x8a,0x38,0xba,0xd2,0x80,0x96,0x41,0xa2,0x3d,0xe3,0xb1,0x5a,},{0xb2,0x2c,0x0f,0x21,0xaa,0x1c,0x2d,0x45,0xf4,0xb2,0xe5,0x6c,0xc9,0xb5,0xe0,0x2f,0x9e,0x31,0xa2,0xea,0xa3,0x67,0xec,0xb4,0x82,0xf8,0x74,0xcb,0xd8,0xe9,0xfe,0x34,},{0x14,0x72,0x45,0x9c,0xbb,0xae,0x2c,0xf2,0x1c,0xe4,0x4a,0x15,0xba,0xe9,0xfc,0x85,0xdc,0xa4,0x0b,0x81,0x82,0xda,0x7d,0x52,0xcb,0xf5,0x6e,0xd5,0x38,0xd1,0x8e,0x03,0x47,0x7c,0x14,0x0a,0x3d,0xdd,0x0e,0xfb,0xa4,0x3c,0x96,0xaa,0x92,0xf5,0xf9,0xbc,0xdf,0x34,0x81,0x28,0x6c,0xe7,0x62,0xa7,0xe2,0xbd,0x1e,0x77,0x9b,0xa9,0x9b,0x0d,},"\x09\x71\x06\xc3\x62\x4d\x77\x4d\xde\x25\x51\xe0\xc2\x7e\x19\x50\x4e\x65\x18\xcc\x86\x36\x9a\xb2\x6f\xf8\x10\x96\x9e\x7d\xe2\x4a\xbc\x68\xb4\xb5\x3f\x11\xd9\x45\xd4\x9e\xf0\x78\xeb\x4f\x6b\xa6\xbf\x25\x7f\xf7\xb6\x08\xaf\xdc\xb3\x0a\x5c\x59\xa7\x56\xfd\x77\xa6\xc1\x24\x7f\x6f\x2a\x41\x10\x0d\x99\xfc\x52\x06\xaf\x3b\xcc\x6d\xe1\xd3\xe4\x96\x8e\x28\xfb\xa0\x12\x3f\x60\x45\xa1\xb5\x4d\x69\x3a\x42\xbd\xfa\x07\x1b\x2b\x91\x4b\x3c\x3c\x0c\x29\xb2\x59\x3d\x07\xe8\xbd\xc8\x6c\xa4\x2a\xc5\x55\xb7\xdc\xd9\x43\x9d\xf9\xfb\xd4\xbb\xec\x73\x0d\x63\x27\xbf\xae\x4f\xc4\x1e\xd4\x98\xb4\xf0\x4a\x0e\xb1\x4c\xee\x60\x82\x83\xaa\xa6\xe6\xaa\x46\x67\x6b\xc8\x8a\xed\x5d\x99\x39\x03\x7a\xad\x49\x15\x66\x1a\xf9\x4b\xb5\xf6\xe6\x53\xa2\xca\xc1\x23\x28\x70\x73\x27\x0e\x0b\x13\xfd\xa1\xdd\x48\x71\xaf\x6a\x92\xf9\x92\xf5\x39\xdf\x88\x17\x12\xfe\xfb\x03\x85\x40\xd4\x11\x91\x12\x3b\x6b\x3b\x4b\x6f\xf8\x7f\xfc\x92\x9a\x6b\xe5\x3c\x6c\xef\x02\xf4\x8f\x2f\x0c\xf2\xfe\x64\xa4\x5f\xd6\x60\x25\xcc\x2d\x7e\xe5\x5e\xbe\x23\x16\xc0\x00\x85\x56\x61\x16\x5e\x2a\x5b\xa4\x1a\xfc\x20\x97\x95\x7b\x6f\xe4\xc5\x52\x21\x20\x4b\x6f\xc1\xf3\x17\xdd\x3b\xa1\x3c\xac\x39\x92\x40\x26\xbd\xb6\x6b\xe4\x54\x22\x68\x87\x56\x31\xd2\x77\xf2\x10\x10\x7a\x33\x76\x7f\x6d\x95\x96\xe2\x57\x42\xd7\xa9\x0e\xa7\x91\xea\x4b\xc9\xee\x84\xa6\x7f\xd3\x28\xb8\x0f\x79\x1e\xde\x96\xd8\x96\x63\xe9\x37\xf0\xb7\x55\xba\xa9\xd5\x2b\xda\x21\x0c\xee\x1d\xb3\x39\xff\x1d\x3c\x4b\x00\x0b\x65\x3b\x9b\xde\x33\x80\x49\xaf\x84\x36\x4e\x21\x77\xf8\x0d\xd5\x1e\x2a\x16\x72\xee\x55\x5d\x63\x17\x58\x9f\x6f\x1d\x5a\xbe\x6c\x28\x77\x35\x8b\xf9\x4b\x0b\x80\x8f\xf8\x57\x36\x3f\xbf\xbe\x32\xe9\x73\x37\xe4\xb8\xa8\xc2\x21\xa9\xe7\x59\x62\xa8\xdc\x9b\x5a\x3d\x7c\xa5\xf9\xc9\xb6\x1c\x73\xc1\x46\x9a\x72\xbd"}, +{{0x40,0xea,0x82,0xda,0x41,0xfd,0x15,0xb0,0x6f,0xfe,0xb9,0x9c,0xd6,0x16,0xdc,0x6b,0xc8,0xc1,0xb2,0x14,0x77,0xea,0x23,0x94,0x66,0x08,0x8e,0x28,0x49,0xbf,0x10,0x16,},{0x59,0x10,0xe5,0x80,0xbf,0x41,0x2c,0x31,0xa8,0x74,0x51,0xd9,0xdd,0xf3,0x2b,0x3a,0xb7,0x13,0xf9,0xe4,0xa2,0x2c,0x59,0x0c,0x64,0x1c,0x14,0xa5,0xdf,0xbb,0xe0,0xd7,},{0xd2,0x98,0xfc,0xc9,0xa8,0xec,0xb7,0x6a,0x98,0xd4,0xa7,0x1d,0xfb,0x01,0xd2,0x76,0xab,0x2d,0x96,0x70,0xa9,0x5b,0xab,0x34,0xcf,0x1d,0x83,0x64,0x51,0x6d,0x1e,0xbd,0xb2,0x39,0x03,0x46,0x02,0x15,0x30,0x71,0x25,0xaf,0xd0,0x9c,0x75,0x8e,0x98,0x1a,0x45,0x2d,0xa9,0x5c,0x0a,0xc2,0xc0,0xb9,0x58,0xc6,0x91,0x7e,0x68,0x74,0x19,0x0d,},"\xa0\x6c\x4e\x02\xb8\x3a\xb7\xe1\x91\xad\x81\x8c\xb8\x18\x7b\x52\xa8\xda\x00\x4f\xe8\x38\xdb\x33\x3c\x4e\x02\x54\x8d\xb6\xbd\xf7\x91\x44\x46\x42\xe5\x7f\xdb\xc8\x59\x4e\x59\xd7\x02\x32\x80\xbb\xae\x82\x98\x6f\x39\x98\x05\x43\x4b\xb0\x72\xc8\xa2\x7a\x2d\xcd\x5a\xa6\x2f\x06\x5b\xc5\x8b\x06\x21\xfc\xd3\x65\xf6\xcd\xbf\x4d\x57\xd5\x77\xd9\x11\x50\x30\x1f\xa4\x8f\x18\x2f\x87\xe8\xdc\xa7\xce\x45\xa7\xd6\x48\x45\xff\x43\x4d\x1b\xab\x05\x34\xcc\xc8\x3a\xa0\x97\x4e\x88\xb3\x8f\xc2\x50\x8c\xef\xcb\xbc\x82\x13\x5b\x73\xb3\x84\xc8\x0e\xcc\xb8\xa0\x9e\x28\x73\xcc\x07\x12\x90\x21\xd8\x1c\xe1\x29\xa9\xdf\x65\xe6\x13\x41\x0a\xf9\x50\x19\x7d\xbf\x9a\xfc\x28\xed\xc4\xe6\x5c\x3e\x84\xda\x40\xd2\xef\x84\x1b\x88\x6b\xc4\x47\x19\xa5\xd5\x9d\xb2\xc6\xdc\x77\x64\x01\xc8\x95\xe2\xb3\xc8\x37\x83\xd7\x81\x7b\xba\x68\xba\xff\x59\x47\x0d\x60\x15\xbb\xa8\xd9\x75\xf0\xeb\x71\x2f\x3b\x89\x02\x91\x28\x05\x52\x3a\xa7\x1c\x90\x49\x9d\xe6\x89\xd3\x1a\xe4\x4e\x21\x0b\x84\x46\xf2\x48\x47\x27\xcc\x49\x1b\x92\xa8\xe8\xb1\x99\xd6\x28\xe1\xdf\x79\xa2\x8c\x56\x1e\x5a\x7d\x88\x2e\x30\x78\x7d\x08\xfb\x2d\x51\x96\xba\x61\x19\x63\x09\xb3\xbf\x0c\x58\x24\xa3\x54\x8c\x70\x00\x03\xfe\x99\x13\xbe\xfe\x12\x22\x31\x50\x01\x26\x85\xe9\x07\x20\xe9\xec\x6b\xc4\xdb\x60\x74\x25\xae\xc5\x31\xc4\xfa\x36\x08\x6d\x3b\x9b\xe3\x91\xa3\xf0\x46\x35\xa8\x07\x7a\x44\x7a\x16\xa6\xfd\x89\xaf\xbb\x9a\x72\xd0\xd3\x55\xcb\x0b\x22\xd5\x62\xf4\x3f\x59\xd4\xe3\x71\x28\xb3\xe2\xd9\x06\xc8\xae\x23\xd0\xaa\x59\x9c\x70\xd3\x77\x8a\x07\x6c\x1a\x39\x72\x8f\x1d\x69\x37\xbd\x48\xb9\x78\x74\x08\x50\x56\x61\x38\xd3\x48\x52\xb6\x30\x75\xe8\x9a\x8e\x22\x80\xed\xba\x6f\x4e\xe8\xf6\x15\x11\xe9\xb7\x68\xe9\x5c\x78\xd1\x97\xb6\x93\xb1\x09\xe8\x88\x18\xb4\x86\xa9\xdf\xdb\x74\xb4\xc5\x55\x0a\xcd\xfb\xd5"}, +{{0x28,0xbb,0x81,0xa1,0x7d,0x45,0x84,0x75,0x4d,0x52,0x81,0x8c,0xd0,0xf1,0xf2,0x1b,0xaa,0x77,0x7e,0x69,0x58,0x44,0xa1,0x51,0x22,0xac,0x05,0x34,0x4d,0xdd,0xc0,0x27,},{0xd5,0xf6,0x1d,0x51,0x99,0x44,0xd1,0x3b,0x84,0xbf,0xa7,0xcd,0x67,0xcb,0x0b,0xea,0x4e,0xf2,0x28,0x1e,0xfa,0x46,0x1f,0x22,0xad,0xe4,0xba,0x88,0x2d,0x11,0xb2,0x52,},{0x9c,0xe4,0x5a,0x07,0xdb,0xd2,0x8d,0x3f,0x6f,0x1b,0x35,0x63,0x0a,0x3f,0xd5,0x6f,0x1d,0x54,0x8f,0x84,0xff,0xb1,0xc6,0xae,0x64,0xb2,0x14,0x98,0xae,0x38,0xe5,0x96,0x91,0x6e,0x77,0xf7,0x99,0x05,0xe6,0x09,0xfb,0x1a,0xe0,0xda,0x36,0x13,0x8a,0x80,0xf2,0x42,0x12,0x21,0x67,0x06,0x80,0x92,0xcc,0x60,0x57,0x96,0xc5,0x66,0x9e,0x06,},"\x92\xe8\x4c\x7a\x55\xb0\xbe\xa0\x3e\x17\xcf\xb6\x5f\x70\x85\xce\x3f\x44\x5b\x15\x42\xba\xe9\x97\xde\x5f\x09\x2a\x24\xff\x24\x33\x80\x28\x6d\x13\x70\x91\xa5\x98\xf3\x5e\x6d\xae\x1a\x1c\x64\x8f\x5a\x49\x4c\x81\x9d\xfb\x24\x06\x52\xff\x90\x83\x81\xf3\x2d\x70\xbc\x51\x31\x00\xac\xa1\x6f\xe7\x22\x02\x95\xb1\xc7\x18\x35\xf1\x6d\x93\x10\xa9\xd2\x7a\x04\xa9\x80\xac\xe2\x97\xd5\xaf\x3f\x7c\xb7\xc7\x8b\x24\x99\x7c\xcb\x41\xf5\x4e\xcb\xab\x50\x7e\xb7\x3e\xa6\xa3\xed\x47\x0e\x49\x59\x05\x09\xf5\xd1\xe6\x03\x2a\x26\x05\xdb\x87\xf4\xa9\xb9\xec\x91\x60\x25\x83\xf1\x4e\x2f\xe1\xbd\xb9\x00\xec\xb8\x97\x11\x96\xb5\x5c\x0d\x43\x34\x89\xf2\x6b\xe9\xca\x15\x7c\xbd\x56\x57\x28\x87\xba\x85\x9f\x39\x67\x4a\x8e\x0c\xa0\x8f\x2d\xbb\x0f\x27\x07\x35\x51\xd0\xb1\x99\x06\x85\x17\x8b\x1a\xe9\xe7\x88\x54\x99\x14\x3d\x9d\x72\xc8\x57\x1d\x11\xe0\xd8\x5b\xf5\x8d\xf9\x4e\x2a\x74\xd9\xb6\x84\x65\x57\xf9\x12\x5c\xa0\x94\x4c\xe5\x71\x8d\x2c\xba\xe1\x67\x2b\xa0\x2b\x84\x7c\x17\xa6\xf6\xb4\x45\x63\x4d\x2f\x01\x75\xa7\x5c\xf6\x88\x3c\x62\xe5\xb5\x21\xc5\x71\x41\xf2\x18\xb2\xfb\x09\x94\xb3\x72\xa7\x16\xc4\xa2\x17\x43\x4b\xea\xb7\x57\x40\xb8\xe9\x1c\x62\x21\x87\xd0\x3c\x85\xda\x00\x1e\x00\x24\x73\x12\xa4\x65\x22\x5f\x5d\x6a\xf2\x32\x06\x4a\x42\x7d\x30\x18\x70\x0d\xed\x77\x4b\x90\x26\x77\x7a\x52\x75\xfc\x04\x75\x46\x06\xc8\x66\x00\x29\x7b\xf7\xb7\x1a\xaf\xf8\xb9\xa7\x46\x67\x7a\x36\x62\xf3\x75\x0e\x81\xb5\x01\x66\xf6\x23\x70\x00\x05\x1f\xfa\x15\x86\x8d\xef\xdf\x09\x00\x57\x72\x2a\xe2\x29\x96\x4a\x4e\xa0\x85\xe0\xdb\xc0\x4c\xe1\x99\x77\x22\xc5\xbb\x65\xd2\xb4\x7e\xcb\x74\x6f\xd8\x3a\x9f\x6a\x69\xc8\x15\x45\xa9\xb5\x02\xf5\xe7\x6d\x31\x30\xc5\xaf\xcb\x1c\x9a\xf9\x9d\x91\x87\x40\x83\x7c\xe8\x9d\x7c\xd2\x13\xfe\xf2\xfd\x06\x2c\xe8\x85\x0f\x69\x65\x9e\x4a\xd3\x27"}, +{{0x24,0xbf,0xd4,0xfc,0x45,0xd5,0x09,0x35,0x85,0x67,0x81,0x01,0xcf,0x56,0x3a,0xb8,0x01,0x1f,0xd6,0x43,0x0d,0xe1,0x55,0xf2,0xa4,0x25,0xf0,0x63,0x3e,0xe3,0xb7,0xcd,},{0x9c,0xf5,0xc5,0xfc,0x0c,0xcf,0xae,0xb2,0x8a,0x08,0xba,0x67,0x70,0x7b,0x18,0xdc,0x84,0xea,0x06,0x98,0xff,0xbd,0xbc,0x16,0x9a,0x09,0xc2,0x81,0x23,0xe6,0xc2,0xac,},{0xdc,0x93,0x5b,0x60,0xfd,0xe4,0x43,0x59,0xaf,0x8f,0x50,0xed,0x7f,0x91,0x9f,0x48,0x3c,0xe3,0xf2,0x4e,0x23,0x20,0xc5,0x5b,0xa9,0x2f,0x3e,0x76,0x17,0xc1,0x9b,0xfb,0x54,0x70,0x19,0x03,0xff,0x18,0x3b,0x42,0xcb,0xed,0xfe,0xf0,0x87,0x5f,0x42,0xb1,0x28,0x75,0xd3,0x6a,0x0a,0xee,0xc7,0x3f,0xfd,0x09,0x50,0x9d,0x92,0xb2,0x8b,0x0d,},"\xba\x54\x12\x8f\x45\xbe\x20\x01\xdb\xb0\x60\xd5\xdc\xc4\x71\x44\x99\x74\x15\xd4\x29\x4f\x6e\xba\x8d\xce\xba\x4f\x6c\xf2\x23\x46\x83\xc4\x26\x5f\x88\x03\x22\x05\x29\x6e\x9b\x27\xd6\x85\x06\x23\x2d\x57\xb6\x88\x40\x76\x48\xf8\x7c\xeb\x34\x20\x52\xbd\xe9\xd0\x06\x55\x42\xff\x17\x15\xc9\x42\x02\x7e\x67\x48\x2a\xf4\xbc\x27\x8f\xf7\x19\x66\xfb\x3f\x62\xa2\xa5\x32\x3c\xb1\xb4\xba\xe1\xe7\xb8\xfe\xdc\xbc\x73\xea\x05\xb4\x07\x64\x21\xb0\xb4\xfa\xe8\xbc\x33\x37\x41\x6a\x17\xfe\x12\x4e\x7e\xe4\x65\xeb\xb3\x8d\x87\x92\x30\x64\x29\xd8\x27\x9a\x1b\xd5\x4c\x37\xbe\xe8\xf9\xc8\x5e\xeb\xe3\xaf\xd1\xf6\x44\x89\xd4\xe5\x3a\xc5\xf5\x06\x57\xbb\x6f\xfb\x97\x12\x07\x44\xb7\x5d\x47\xc6\x22\x6d\x5a\x9c\x9c\x26\x4e\xe3\xe6\xa6\xde\xd0\x50\x62\xca\x10\x06\x66\x91\x18\x45\x45\x50\x01\x09\x19\xc2\x63\x3c\xf0\x86\x95\x03\x45\xe5\x14\xaf\x38\x43\x14\x8e\x5c\x64\x35\x2e\x69\x03\x7d\xfe\x60\xd4\xa8\xea\xb3\xeb\x8c\xb5\x4b\xd3\x9a\xf2\xf3\x53\xd5\xde\xd2\xe2\xbc\x8b\x11\xc0\x9f\x61\x2e\x12\x8c\x6e\xfa\x41\xf6\xeb\x2c\x95\x80\x87\xbe\x34\xc6\x33\x5a\x43\x00\x5d\x11\xa9\xd3\xb5\xa5\x29\xc2\xd1\xb0\x64\x2f\x77\xaf\xdd\x8c\x6b\x1d\x6f\xb2\xa9\xdc\xb6\x5f\x42\xf4\xec\xa8\xea\x9a\x05\x40\x58\xbe\x86\x13\x66\x76\x10\xe3\xee\xd8\xd1\xdf\x07\x39\xec\xa1\x71\x95\x41\x17\x98\x9d\x1b\x12\x18\x9a\xb5\x79\x04\xaa\x96\x0b\x0c\xa8\x55\x41\x74\x63\x85\xef\xa9\x85\xbe\x9d\x97\xb5\xa9\x02\x99\x89\xa9\xc7\x14\x98\xdf\xab\xdb\x81\x36\x81\xf5\x7e\x27\x6b\x64\xdb\x49\x1b\x8f\x08\x2a\x88\x51\x45\x46\x9a\x53\x1b\x7f\x9f\x04\xca\x0a\x2c\x2f\x8d\xff\x20\xcc\xb9\x9c\x28\x61\xf5\x4e\x5e\xaf\xa9\x62\xcc\x53\xea\xf1\x8d\x3d\x5e\x50\xd3\x37\xaf\x48\x5f\x19\x97\x5f\x05\x93\x07\x00\xa8\xa7\x25\x3f\x11\xf1\x84\x13\x0d\x0a\xee\x70\x96\x9d\x96\xfe\x08\xf2\x16\x95\x1d\x9d\xce\xd5\x23\x88"}, +{{0x2f,0xc2,0xf9,0xb2,0x05,0x0a,0xd7,0xd1,0x39,0x27,0x3e,0x93,0xe2,0xa0,0x45,0x1c,0x7b,0x5c,0xce,0x57,0x59,0x9a,0xa6,0xb0,0x8d,0x3e,0xdc,0x5b,0xb0,0x75,0x90,0xc8,},{0xff,0xe5,0xa1,0x78,0x80,0xd7,0x18,0xcc,0x79,0x88,0xc2,0xfd,0x98,0x25,0xb0,0x3b,0x93,0x45,0x0a,0xc1,0xde,0xb8,0xfb,0xd1,0xf1,0xbf,0x3b,0x8f,0x87,0x80,0x59,0x54,},{0x7a,0xff,0x16,0x2a,0x3c,0x0d,0x28,0xdf,0xf4,0x17,0x15,0xa9,0x74,0xaf,0x07,0xec,0xac,0x21,0x32,0xfc,0x18,0xbc,0x43,0xa1,0x98,0xfe,0x66,0x46,0x59,0x05,0x0d,0xa1,0x9a,0xe2,0x27,0x58,0xd5,0x2c,0x9c,0xbb,0x94,0xf1,0x35,0x8b,0xb0,0x26,0x10,0xa8,0xa3,0x51,0xc2,0x11,0x62,0x79,0xe7,0x24,0x5a,0xdf,0x69,0x67,0x5d,0xfd,0x36,0x0a,},"\xdc\x12\x97\x99\x0c\xc0\x27\xd5\x6d\x1f\xee\x26\x5c\x09\xbc\xf2\x07\xa9\x58\x3e\x6b\xab\x8d\x32\x47\x82\x28\xe0\xbc\x30\x5b\x98\x18\x15\x4c\x33\x8c\xee\xc3\x4b\x04\xc4\xad\xe7\xac\x61\xdc\xb0\x9b\xfa\xc8\xad\xe0\x0d\x1f\x29\xde\x31\x70\x60\xb8\xa4\xda\xf1\x98\x7d\xe4\x09\xca\x2c\x3f\xe4\x38\x00\x88\x07\x3c\xcf\x48\x5e\x9a\x69\x51\x6b\x5b\xbb\x41\x30\xf2\x0b\xe6\x9b\x2d\xd6\xa9\xb4\x65\x15\x9c\xca\x1a\xc8\x8b\x32\x8b\x80\xc5\x1b\x66\xaf\x7f\x4c\x50\xf6\x22\x87\x72\xf2\x87\x34\x69\x3c\xe4\x80\x5a\x41\x63\xdf\xf1\x4b\x4d\x03\x98\x11\xee\x3f\xce\x65\x93\x54\x44\xa6\xea\x9a\x72\xd7\x8b\x91\x5c\x9c\x3b\x76\x6c\x60\xb7\xe0\x32\x9e\x43\xc9\xc5\x7e\xde\x94\xb9\x15\x25\xce\x5a\x07\x5a\x72\x97\x21\x97\x72\xef\x3c\x02\x96\x49\xb5\x86\xa9\x5a\x73\xbb\xdf\x16\xd8\xfc\x20\x36\x8d\xe4\xba\x44\xde\x10\x64\xbe\x58\x26\xb3\x76\xbe\x31\xa8\x6c\xa4\x78\xa5\x2e\xfb\x98\xf1\xfa\x33\x31\x57\x71\x9b\xd6\xe0\xda\x80\xed\x68\xd0\xef\xea\xfe\xe5\xa1\x3b\xcc\x3b\x45\x75\x25\x25\x8f\x1f\x7e\x03\x1f\x7b\x40\x3a\x46\x15\x06\x92\x7b\x1e\x6c\x7d\x4a\x0c\x8d\x84\xb5\xf3\xdd\x0e\xb8\xbd\xb1\x3e\xdc\x2b\x51\x4a\x81\xd0\x88\xeb\x07\x7a\x52\xc8\xa8\x31\x86\x1f\xee\xe8\x11\x0e\x41\xa3\x25\xdc\xe2\x06\xb2\xd6\x7d\x25\xf9\x0e\xf5\x7e\x0f\xde\x70\x9f\x3e\x5a\x39\xc0\x4e\xed\x31\xe5\x7c\x19\x3b\x28\x3e\x2d\xa7\x27\x9e\xe3\xf1\xee\xd4\x82\xb3\xbb\xcd\x37\x39\x02\xc1\xdf\x81\x1a\xc3\x3e\x1d\xe0\x64\x29\xe8\xf8\x44\x3f\x60\x20\x19\x65\x0b\xdc\x2e\xe8\xd7\xf6\x50\x03\x6a\x7a\x22\xb8\xfd\x88\x51\x75\x11\x22\x9c\x72\x9a\x32\x69\xb3\xa3\xe8\xfc\x72\xb0\x1b\x5a\x4b\x3e\x33\xf5\x27\x2f\x3a\xd2\x16\x29\xd0\x8b\x1f\x71\x79\x35\xe9\xe1\x04\xad\xd2\xf0\xf2\x03\x34\x32\xbe\xc8\x2e\x21\x21\xd9\x8c\x9c\x1a\x58\xe0\xda\xba\x25\x53\x6a\x1b\xe8\xe5\x08\x83\x47\xf4\xa1\x4e\x48\xd8\xe3"}, +{{0x8a,0xfe,0x33,0xa0,0xc0,0x8a,0xa3,0x48,0x7a,0x97,0xdf,0x9f,0x01,0xf0,0x5b,0x23,0x27,0x7d,0xf0,0xbb,0x7e,0x4c,0xe3,0x95,0x22,0xae,0xc3,0xd1,0x78,0x16,0xe4,0x67,},{0xd0,0x04,0x37,0x0e,0x6e,0xdc,0x34,0xb3,0xe8,0x81,0x86,0x67,0x21,0x6f,0x5b,0x22,0x6b,0x0f,0xf7,0x5a,0x58,0x48,0x4c,0x86,0x16,0xe1,0xa8,0x66,0x44,0x4c,0xab,0x57,},{0x63,0xa8,0xae,0xac,0x02,0x5f,0x2d,0xde,0x9a,0x73,0x28,0x6e,0x56,0xc2,0xd6,0x2d,0xcb,0x79,0xa2,0x41,0xba,0x0b,0x2e,0x2d,0xba,0xca,0x87,0x52,0xed,0x2f,0xc8,0xcc,0x7a,0xb8,0xe6,0x60,0x0b,0x67,0x64,0x5f,0xb5,0xe8,0x18,0xa4,0xe8,0x2c,0x29,0x18,0x0a,0x6b,0x2c,0x3f,0x58,0xd0,0x99,0xcb,0x63,0x5c,0xe5,0x2b,0xdc,0x15,0x70,0x04,},"\x86\xfb\x74\x1f\x1b\x97\x08\x92\x91\x95\x03\x1a\xa1\x64\x5f\xb7\x09\xa8\xae\x32\x3f\xff\x85\xe5\x47\x01\x94\x45\x2e\x11\xb7\xb1\x27\x91\x94\xb5\xe2\x42\x7c\xe2\x3e\x1d\x74\x9c\x3d\xdf\x91\x0b\x01\x7e\x4f\x2d\xff\x86\xdb\xe4\x82\xc9\x1b\xd9\x94\xe8\x49\x3f\x2e\x68\x24\xbb\xa3\xbc\x7d\x7a\x84\x5f\x21\x7a\xe9\x76\x0b\x3c\xd0\x02\x26\xd9\xff\x26\x16\xd4\x52\x75\x1a\x90\xc3\xd0\xd3\xc3\x6d\x4a\xb4\xb2\x52\x0f\x67\x28\x81\x71\xbd\x3a\x34\xb2\xea\xca\xe8\xd4\x4c\x1e\x15\x3d\xda\x1f\x90\xbc\xd3\x59\x5d\xad\x37\x71\x3b\x8d\x34\x01\x56\xea\x90\xa4\xe1\x35\x95\x1b\xa7\x16\x9a\xc1\x75\x57\x8b\x81\xe9\x7a\x54\x1a\xb9\xbf\xb7\x63\x28\x79\x8d\x7d\x63\x1c\x14\xdf\x2a\xd6\x13\xe9\xc6\xe1\x14\x7a\x0e\x84\x06\x2d\xdb\xa0\x35\x85\x9d\x46\xba\xde\x5f\xad\xd9\xb3\x2b\x43\xda\xd4\x83\xc6\xb8\x02\x3b\x32\x39\x1e\x51\xef\x15\x20\xc6\x8c\x61\x91\x32\x6c\x49\x44\x23\x08\x0c\x62\x3d\xc4\xad\x0a\xa0\x74\x74\x8d\x82\x6c\x29\x64\x4c\x38\x98\x6a\x77\x00\x2f\x0c\xab\x90\x68\xe6\xc9\xec\x73\xcc\x2e\x0c\x58\x4b\x80\xe0\xbc\x37\x57\x21\xf7\xa8\xfc\x35\x31\x7a\x5e\x24\x0e\x8c\x66\x09\x2f\xb6\x30\x5b\x01\x2c\x70\xe1\x7a\xea\xff\x13\x38\x6d\x5e\x28\xd0\x64\x30\xca\x58\x5b\x0c\x85\xb2\x74\xe7\xfc\xbb\x63\xe3\x42\x3a\x98\x25\x79\xe5\xa6\x4a\x02\x62\xc4\x19\x08\xe5\x5d\xbe\x43\xda\xc1\xe5\xcc\x1b\xb7\x29\x8b\xe4\x28\x72\x0a\x12\xe3\xb0\x72\x55\x9e\xc2\x67\x5d\x45\x7a\xaf\x8f\x13\x25\x2e\x28\xaa\xd6\x3c\x15\x13\xf5\xf2\x39\x56\x4d\x36\x3c\x85\x05\xff\xa4\xe5\x0f\x66\x48\xc1\xcb\x82\xbb\xa8\x52\xbf\xf0\xac\xb0\x30\xcb\xe7\x3f\x05\x9d\xd8\x7b\xbd\x73\x18\xc5\x58\x6e\x70\x86\x18\xa4\xf4\xc9\xf3\xbe\xc3\xf4\xf0\x7c\x60\x9e\xeb\xb2\x4b\xa8\x78\xc6\xbf\x1e\x4f\x2d\x0f\xd1\x45\x0a\xb9\x4e\x31\x75\x52\x17\x78\x6f\xb1\x51\x82\x76\x0f\xfb\xe5\xa2\x67\xcb\xe9\x98\xa4\xff\x90\xa2"}, +{{0x6d,0xc7,0xcc,0xf3,0x29,0x37,0x8e,0x81,0x31,0xb6,0xde,0xfc,0xd8,0x93,0x70,0x30,0x10,0x68,0x94,0x63,0x36,0xb0,0xb7,0x62,0xac,0x5e,0xa5,0x14,0x87,0xdb,0xd3,0x9e,},{0x04,0xe9,0x0d,0x27,0x5e,0x79,0xdf,0x5f,0x2b,0x6e,0xf4,0xa3,0x15,0x05,0xaa,0xc0,0x5a,0x69,0x45,0x9b,0xaf,0x2c,0x58,0x1b,0x3c,0xe3,0xdb,0x29,0xf0,0xf1,0xfc,0x14,},{0x04,0x50,0x9d,0xb0,0x03,0xa1,0xa6,0xed,0x3f,0xbc,0xec,0x21,0xac,0x44,0xec,0x10,0xcc,0x06,0xd7,0x9f,0x27,0x14,0x96,0x08,0x82,0x17,0x03,0x16,0x27,0x5d,0xf8,0x04,0x23,0xa1,0xc1,0xa1,0x12,0xd8,0x81,0xfc,0x24,0xd2,0x81,0x25,0x26,0x07,0x90,0x58,0xaa,0x8b,0x60,0x8b,0xfc,0x6b,0x5e,0x57,0x63,0x22,0x40,0xc6,0x36,0xd6,0xeb,0x00,},"\x20\xce\xbb\xe9\x84\x01\xac\x89\x34\xc3\xe6\x5a\x57\x38\xcb\x0e\xc0\xcd\xc7\x5f\xdb\x09\xdc\x96\x31\x28\x94\xb1\x87\xc0\xa4\x6d\x2c\x38\xf4\x85\x5b\xe3\xee\xcc\xdc\xdc\xc5\x6d\x92\x6a\x8c\x08\xce\x6e\x74\x8e\x2a\x85\x8f\x53\x53\x2e\x7e\x5f\xc5\xf7\x01\x4c\x8c\x6f\x86\x31\x0c\xc2\x6e\xfe\xf3\x0a\xe5\x25\xa5\x15\x79\x40\xab\x53\x5e\xd8\xe4\x03\x11\x2b\x08\xe3\x5e\x2b\xb3\xdd\x91\xa9\xae\x8f\x77\x2d\x2a\xff\x37\xd8\xc4\x0d\x2b\x5c\xc8\x87\xa6\xf1\x50\x50\xa0\xf5\xbc\xf0\x36\x0c\x3a\x9d\x12\xd5\x91\x86\x55\xed\xc3\xc1\x3c\x86\xba\x6f\x4a\x2f\xa3\xbf\xcd\x40\x5e\xd3\x8f\x87\x1c\xf7\xdf\xf0\xf7\x5d\xaf\x2c\x32\x10\x84\xee\x9f\xa8\x12\x11\xad\xb1\x05\xb2\x5c\x22\x88\xf0\xf2\xf7\xf9\x3e\xf6\x56\xb2\xde\x19\x01\x22\xe7\xa4\xbf\xd4\xa1\xbd\x98\x93\xa8\x48\x5b\x50\x9f\xf0\xbc\x46\xcc\x96\x10\x51\xc1\xdb\x5a\x12\x49\x0c\x7e\x74\x19\x22\xcc\xc0\xa6\x65\x49\x64\x70\x27\x6f\x69\xc7\xb7\x70\x98\xc1\xe6\x70\xaf\x6b\x9f\x85\x12\x52\x99\x68\x75\xeb\x80\x35\xa8\x17\xfa\x9b\xe0\x7f\x2b\xe0\xbb\xb1\x20\x25\xe0\x56\x54\x14\xc8\x17\xe9\x42\x1a\xc7\x00\x37\x38\x93\x86\x2f\x24\xcb\x16\x5f\x9a\x27\x1a\x64\xfd\x23\x05\xc6\x67\x2c\x46\x76\x7f\x8f\x07\x5b\xe5\xd2\xd4\x07\x9b\xfa\xdc\x39\x56\x28\x8b\x02\x15\x60\x53\x11\xb5\xbf\x32\xf0\x03\x7b\x7c\x5a\xd5\x02\x01\x3e\x82\xae\x34\x19\xd9\xd8\xf3\x9c\x54\x5b\x58\x88\xf4\x71\x06\xc9\x4d\x5f\xd6\x08\x4d\x26\x03\x4a\x99\xf5\xdc\xbf\x26\xa8\x4e\xb4\xee\x14\x9c\x62\xa0\x41\x0d\x8c\x70\x7b\x1a\x9b\x07\x1f\x74\xed\x23\x93\x25\x85\x07\x2c\xe6\xcb\xd3\x3d\x4d\x54\xee\x91\x79\x16\xf5\xdf\xc6\x4d\x26\xa4\x98\x01\x84\x38\xb4\x55\x73\x93\x45\xdd\x60\xae\x0f\x47\x50\x62\x59\x15\xcc\x82\x9a\xb6\x82\x2d\x6f\x05\xf6\xd2\xbd\xa0\xa7\xbf\x56\x01\xe9\xa2\xed\x6d\xe9\x60\x37\x1d\x17\xe6\xf4\x37\x09\xc9\x67\x8c\xa7\x43\xad\xfb\xdb\x45"}, +{{0xcc,0xae,0x07,0xd2,0xa0,0x21,0xfe,0x3e,0x6e,0xe2,0x38,0x36,0xa7,0x11,0xb9,0x7b,0x04,0xe0,0xa4,0x41,0xf1,0x69,0x60,0x75,0x72,0x73,0x1c,0xb0,0x8c,0x26,0x94,0x88,},{0xa3,0x22,0x65,0xe5,0x32,0x8a,0x4f,0x49,0xcf,0x06,0xb4,0x67,0xa9,0x8b,0x9f,0x9d,0x5b,0x99,0x7b,0x85,0xdf,0xb7,0x52,0x3c,0xa6,0xa0,0xa1,0xd6,0x27,0xd3,0x28,0x91,},{0x0e,0xec,0x75,0x41,0x05,0x44,0x7f,0x97,0xd4,0xa9,0xcd,0x24,0x6c,0x7e,0xed,0xe3,0xfd,0x06,0x90,0x18,0xf0,0xd0,0x1a,0x41,0xdf,0xab,0xca,0x3e,0x90,0xa7,0x41,0x83,0x5e,0xa4,0xa9,0xd6,0x82,0x34,0x22,0x67,0xb2,0x50,0xfc,0x1c,0x8c,0x54,0x7c,0x89,0x63,0x2d,0x9f,0x68,0x9a,0xf5,0x36,0xc7,0x92,0x90,0x04,0xde,0xd0,0xd9,0x6f,0x09,},"\xa4\xbf\x82\x97\xd0\xdc\x5e\x4c\x92\xbd\x00\xad\x5b\x9c\x09\xb1\x23\x8b\x50\x3d\x61\x91\x16\xef\x74\x26\x03\x78\x34\x9a\x92\x82\xb4\x1f\x3f\x46\x76\xa6\x21\x5e\x3c\xe6\xd0\x22\x38\x48\x0a\x96\x04\x3b\x29\x42\xb3\xfe\xed\x12\x62\x0b\x1f\xa9\x7f\x77\x03\xb3\xeb\x68\x3c\x16\x01\xbd\x2f\x51\x82\x5c\x45\x0d\xf4\xfd\x1f\x33\xb0\xbf\x9c\x23\xc0\x32\x23\x78\x9e\x06\xe2\x4c\xf1\x36\xd3\xb5\x57\x40\x3a\x66\x98\x1f\x4b\x77\x7d\xcf\xe8\x90\xd2\xba\x96\xda\x4a\x47\x42\xae\xed\xdd\x6a\x61\x1d\x05\xfc\x21\x56\x94\xa5\xd8\x9a\x5d\xe6\x76\x0b\x1d\x94\x15\x15\x50\x44\xc0\x49\xcb\x02\x29\x1a\x15\x14\xfa\xa2\xe7\x7d\x2a\xe3\x3d\x44\x58\x5b\xda\xc6\x36\x5b\xf4\x81\xd9\xc9\x78\x33\x93\x7e\xab\x63\x6e\xd6\x57\x42\xa0\xd5\x97\x3b\x24\xd5\x40\x89\xb2\xda\xf0\x84\xd5\x41\x47\x65\x10\x5e\x4e\xca\x14\xaa\xad\xd1\x05\x33\x38\xa8\x47\x05\x05\x23\x2e\x4a\xc6\x33\x34\x5c\x5c\xde\xe1\xe4\x65\x3d\x1d\x93\x58\x3a\xf1\x18\x54\xb1\xd9\xb6\x5f\xc2\x02\x81\x83\x8c\x56\xdf\x11\x48\xf3\x5c\xcf\x9b\xfe\x2f\x3f\x80\xab\x73\xf5\xb7\x91\xcb\xed\x2d\x92\x06\x44\xcf\x03\x16\xf0\xcb\x5d\x36\x62\xb9\x12\x06\x47\xda\x56\xaf\xbe\xb4\x7a\x95\x29\x53\xbc\x1a\x37\xde\x85\x7e\x4b\x39\xfd\x92\xb6\x32\xb8\x51\x59\xf4\x6c\xd0\x5b\x6a\xbc\x23\x38\xd4\x63\x2d\x48\xe9\xa1\x78\x86\x0d\xe8\xf6\x5d\x9b\xc2\x3f\x24\x50\x7b\x7c\x56\x29\xe0\xbd\xaa\xc0\x67\xc4\x76\xc9\xc3\x94\x1d\x86\xf7\x88\x94\x4d\x74\x48\x52\xa6\x1d\xa7\x16\xf9\x5f\x3b\x04\xf0\x78\x3a\x56\x29\x41\xbc\xdd\xa4\x39\x59\x0f\xd1\x86\xb2\xa8\xeb\xf1\x9a\x5a\x7e\x4f\x4a\x3a\xaa\xb7\xa8\x7a\x43\x45\x24\xfb\xc9\x79\x9c\x99\x31\xeb\x8c\xe4\xe3\x4e\x99\xb6\x08\xca\xc9\x4a\xb7\xe7\x44\x95\x66\x8d\xf1\x36\x18\x5f\x48\x7d\x9f\xbc\xb6\x60\x5a\xd7\x25\x34\x54\x03\xec\x57\xf3\xf6\xdb\x36\x4a\x87\xf3\x8f\xea\x4b\x4c\x27\x15\x52\xe9\xf2\xe4\xa1\xbe"}, +{{0xdb,0x5d,0x5f,0x41,0xfd,0xdd,0x67,0x68,0x70,0x97,0x47,0xab,0x82,0x39,0xbb,0x4f,0x42,0xa3,0x1d,0x34,0xb4,0xfa,0x88,0x82,0x4d,0x94,0xbf,0x78,0xd3,0x14,0x92,0x64,},{0x03,0x85,0x8c,0xe6,0xb2,0xd2,0x40,0x79,0xee,0xad,0x66,0xca,0x0d,0xfe,0x77,0x2e,0xcd,0xa9,0xaf,0x4d,0x46,0xbc,0x9b,0x5e,0xdf,0xdc,0x28,0x6b,0x95,0xfe,0x97,0x16,},{0x5b,0x3d,0x0d,0xa7,0x10,0x23,0x55,0x48,0x6b,0xe4,0xd6,0x9c,0xfd,0x65,0x88,0x6c,0x9d,0x9c,0x87,0x38,0xb2,0x93,0xca,0xfb,0x23,0xb2,0x10,0x4b,0xfd,0xac,0x8d,0x7d,0x01,0x29,0x8e,0xeb,0x18,0xfd,0xe3,0xde,0xd6,0x49,0x1d,0x41,0xb4,0x19,0xcc,0x66,0x37,0x52,0xc4,0xe6,0x7d,0xbe,0x89,0x86,0x83,0x3d,0x20,0xe4,0xef,0x34,0x18,0x0b,},"\x67\xee\x03\xde\x45\xc3\xe7\x03\x0d\xb5\x24\x6e\xe5\xb5\x1b\xf2\x98\xbb\xa3\xe4\xd0\x93\x49\x37\xfc\x12\xd9\xa6\x29\x60\x4c\x53\xc0\x70\xe3\x0d\x61\x19\x99\xa9\xcd\xda\xf2\xd9\xac\xda\x6a\x9f\x67\x20\x2b\x35\x23\x69\xd4\x82\x60\xee\xbc\xe0\xe7\x8e\x4d\x5a\xe5\x4f\x67\x75\x21\xf8\x4a\x7b\xe0\x01\x7f\xab\x27\x8b\x2b\x57\x27\x5e\xfc\x5f\xa5\x7c\x61\x71\x86\xfc\x1b\xa4\x9e\xdf\xbd\x33\x08\x63\x48\x78\xd8\x64\xf2\xda\x15\x83\xca\x8d\x56\xce\x9f\xae\x77\xc4\x62\x03\x9a\xbc\x32\xd0\x53\x9c\x0a\x60\xb7\xbb\xba\x50\x29\xe9\x32\x9d\x27\x56\x83\xd9\xc4\xce\x77\xd0\xb9\x08\xad\xe9\x8b\x0e\x32\xb4\x42\x0d\x9a\xee\x2c\xc1\x0e\x4b\xe9\x22\xf9\x57\x25\x82\xdd\x89\x67\x14\x1c\x1d\x40\x2e\x21\x5f\x20\xae\xe0\xa8\x90\xe2\x36\x8e\x40\x6d\xea\x11\xbd\x11\x17\x7f\x2e\x03\x8a\xa2\xf1\xa0\xdf\xf5\x1a\x12\x8d\x95\x5d\x5e\x5f\x8d\x5d\x00\x09\xaa\xa8\x24\x40\xa9\x68\x64\xd6\xc6\x97\xf9\x10\xd1\xdf\x23\x0f\x46\x7f\x0e\x02\xa2\xe0\x2b\xf9\xe4\x5d\xa9\x5f\x25\x54\x10\xcc\x5a\xab\x8d\x85\xf4\x49\xa5\xde\x99\xaa\xbd\x44\xfd\x76\x3e\xc1\x46\x29\xf3\xdb\xab\x1a\x24\x7b\xff\xb7\x17\x46\x48\xe4\x3b\x9f\xb1\xeb\x0d\xf5\xe4\x10\x9b\x7a\x88\xe0\x55\x12\xb2\x08\x65\xba\xd3\x9f\x9e\xa7\x9d\x52\xf5\x18\x8e\x7c\xa5\x19\x44\x05\xbf\xb1\xa0\x97\x27\x61\x7f\x3f\x6c\x88\x19\x20\x08\xed\xbc\x0c\x65\x85\xdb\xf2\x61\xf1\x49\xdf\xfb\x59\x3d\x42\x71\x6e\x5a\x57\x77\xf5\x46\x2b\xee\xb1\xe9\xa5\x6a\x2c\x76\xe6\xcb\x73\x51\x17\xcc\x11\x83\xa3\x8d\x1e\x00\xb3\x03\xd1\x74\xaa\x9c\xf5\xc7\x31\xb2\xc7\x0e\xdd\x79\xcc\x5d\xc9\x6f\x40\x18\xf1\xd7\x1d\x71\x98\xbb\xb7\xd1\x34\xcd\x2f\xf8\xc1\x5f\x9a\x04\x28\x0d\xb2\x6a\x8f\xa9\x99\x7e\xb8\x6b\x13\x3c\x02\x2e\xda\x15\xd8\xad\x5e\x77\xcc\x9f\x62\x61\x59\x60\xba\xc2\xf9\xbb\xc3\xeb\xbd\x19\x8f\x72\xc5\x72\xb9\x71\x56\xfa\x7f\xa2\x29\xa9\x80\x14\xe1\x70"}, +{{0x7f,0x04,0x8d,0xfc,0xc2,0x65,0x0c,0xda,0x59,0x49,0x1d,0x4c,0xe2,0xb2,0x53,0x3a,0xec,0xc8,0x9c,0xc4,0xb3,0x36,0x88,0x51,0x94,0xb7,0xad,0x91,0x7d,0xb5,0xcd,0x14,},{0x08,0x00,0x1b,0x5d,0x40,0x95,0x8b,0xcb,0x27,0x0b,0xee,0xa9,0xba,0xba,0x33,0x87,0xe3,0xa4,0xb9,0x00,0xfc,0x42,0x27,0x56,0x57,0xc6,0xc6,0x91,0xa2,0xe2,0x64,0xf2,},{0x58,0x33,0x70,0x97,0x1d,0x24,0x65,0x2a,0xd2,0x13,0xc4,0x26,0x15,0x91,0x19,0x38,0xfa,0x9a,0xa3,0xd9,0xb7,0x19,0x69,0x40,0xe6,0xeb,0x08,0x15,0x12,0x00,0xc7,0xb6,0x72,0x9d,0x1e,0xff,0x8f,0x4f,0x09,0x04,0x07,0x4d,0xab,0x3d,0xdd,0xa6,0xaf,0x1e,0x4e,0x56,0x2b,0x7d,0x62,0x20,0xc1,0xa5,0x62,0x68,0x3b,0xea,0xb2,0x68,0xf8,0x0e,},"\x91\x75\x19\xcd\xb3\x35\x19\x68\x0b\xca\xe0\x4f\xaa\x79\x07\x71\xce\x7d\x13\x97\xc3\x45\xf1\xb0\x3d\xd7\x62\x57\x76\xf3\xf1\x95\x80\x99\x32\x61\x8b\x1c\x64\xac\xd9\x3a\xd0\x00\xea\xd0\x96\x54\xa3\x3d\x14\xf7\x48\xb4\x6b\x67\xaa\xe0\xff\x12\xdf\x3c\xc1\x63\x28\x0f\x47\xce\xdc\x16\xa8\x57\x90\x34\xe4\x98\x84\x29\x67\x72\xec\xbd\xbb\x71\xca\x29\xc1\x66\x23\x35\x33\xc8\xde\x54\x01\x2b\x41\x2c\xa1\x3c\xc2\x58\xf7\xc5\x46\x5d\x83\x42\x2f\x52\x4e\x4c\x05\xf8\x06\x31\x34\x78\x31\x9f\xd1\x43\xcf\x50\x88\xe6\x98\x37\x69\x7d\x36\x15\xd8\x0a\x7f\xa7\xe7\x44\x3f\xca\x65\xe7\x53\xac\x1b\x11\xd8\xef\xf3\x47\x66\x36\xae\x02\xd7\xa2\x0f\x4b\x23\x88\xda\xd6\x84\x00\x2f\x5c\xe9\x57\xca\xdd\xd2\x05\x3d\x0e\xd5\x33\x13\x2a\x81\xca\x19\xbb\x08\x0b\xd4\x3b\xe9\x32\x02\x8c\xb5\xf6\xb9\x64\xf0\x08\xb5\xb1\xc1\xc5\x99\x3b\xc9\xb5\x48\x5b\x22\xbb\xef\x70\x1f\x0a\x26\xa3\xe6\x75\xea\x31\x12\x2b\xba\xe9\x1d\x86\x4b\x54\xd8\x95\xaf\xdc\x79\xca\x58\xd4\xfe\x44\x92\x13\x35\x3b\x14\x9f\x31\x43\xb5\x14\x4d\x74\x7c\x5b\x46\x97\x47\x9a\xe6\x85\x28\x48\x53\x84\x04\x4a\xa2\xc9\x9b\xa4\xb1\x7b\x18\x4e\x94\x98\x22\x69\xbd\xe2\xde\x0b\x17\x70\x5d\x0b\xfc\x46\xd6\x90\x6a\x90\xed\xef\xe8\x91\x95\xde\x6b\xb8\xf3\xfb\x6a\x37\x41\x86\xc7\xcd\x08\x6d\x13\xd1\xb3\x52\x5a\x39\x94\xdc\x80\x20\xe1\xa0\x05\x54\xac\x8a\x82\xd6\x04\x7c\x5b\xff\x5e\x7f\x12\x45\x0f\x48\x65\xda\x16\x1e\x1a\x02\x1f\xd9\xbe\x8b\xd3\x3a\x32\xbb\x54\xa4\xdd\xf8\x74\x51\x2e\x74\xb5\xcf\xd3\xfc\x3c\xd9\xac\x11\xed\xd8\x78\x43\x36\x68\xe3\xfc\xc7\x82\xb9\x7b\x6d\x90\x5a\xdb\x0e\xbe\xc4\x2c\x92\x54\xac\x90\xf3\x58\x22\xc0\x0f\x97\xff\x3f\x0c\x7c\x39\xed\x3c\x7c\xb3\x92\x0f\x56\x08\xbb\x45\x83\x8b\xb2\x42\xa5\x2a\x86\x37\xd7\xce\xcd\xcf\x48\x9f\xa1\x83\xb4\x54\x51\xc6\xc9\xfc\xbb\xbf\x91\x4f\x5f\x7e\x6b\x22\x3b\xcb\x46\x75"}, +{{0x9f,0xeb,0x3d,0xf8,0x8c,0x49,0x4a,0x99,0x84,0x9c,0x6f,0xca,0x19,0x42,0x01,0x47,0x7a,0x2f,0xa7,0x56,0x4e,0x29,0xfb,0x06,0xcb,0x44,0xc1,0x15,0x4e,0x8c,0xea,0x3a,},{0xc3,0x56,0x28,0xca,0x6e,0xe2,0x8e,0xc1,0xc2,0x39,0xdd,0xc5,0xbb,0xa2,0xa9,0xe0,0x9e,0x48,0x46,0x81,0x6b,0x14,0x3c,0x74,0xdf,0xa2,0xae,0xc1,0xf6,0x25,0x51,0xb6,},{0xa1,0xc2,0x60,0x78,0x35,0xbe,0xc1,0xa1,0xd8,0x78,0x72,0xfd,0x8e,0xe4,0x88,0xd0,0xae,0x9e,0xd2,0x3d,0x49,0xfd,0x67,0x86,0xfc,0x49,0x96,0x72,0x5e,0x49,0xb3,0x26,0x21,0x18,0xba,0xbb,0x48,0x34,0x87,0x7c,0x7f,0x78,0xfb,0xea,0xc0,0x2d,0xf4,0x0a,0xb0,0x91,0xb8,0xb4,0x20,0xdc,0x99,0x51,0x38,0x1e,0x3b,0xcd,0xa0,0x67,0x05,0x02,},"\x95\xfb\x75\x81\xbd\x25\xff\xd4\x42\xc3\xae\x38\xa1\x9b\xea\x73\x49\xc7\xb7\x68\x3b\xa6\x76\x7e\x14\x8f\x0a\xfc\x15\x37\x3f\x67\xc1\x6d\x47\x17\x81\x20\x2e\x6d\xa8\x05\x4e\xd7\xfb\x9e\xe2\x04\xcc\x0f\x63\xc2\x10\xa6\x70\xa5\xf9\xce\xd4\x29\x45\x88\x19\x63\x30\xd3\x1b\x8e\x83\x92\xbe\xf6\xb4\x8f\xe3\xc9\x20\x78\xfa\xe1\x12\x84\xb4\xc3\xba\x20\xd9\x37\xe2\x71\x9d\xe7\xbf\x67\xc0\x06\x69\xad\x23\xe6\x13\x84\xeb\xdf\x8c\x6e\x60\x73\x54\x28\xc0\x84\xfe\x21\x7f\xdb\x47\x09\xcc\xb6\x08\x3f\xc0\xae\x4a\x05\x27\x3e\xef\x73\x90\x23\xd3\x4b\xb7\x3f\x66\x2d\xac\xdf\x11\x0b\x6d\xbd\x3e\x74\xfc\x14\x91\xe8\xc9\x65\x96\x07\x5f\xae\x5c\x36\xaa\xbe\x2a\x0a\x53\x05\x2b\xf7\x7c\x44\x62\x43\x80\x63\xaa\x7b\xc0\xc5\x0a\xb9\x20\xc9\xeb\x28\x86\x71\x56\x0c\xa5\xba\x7a\xf4\x4a\x53\xdb\x2e\x2f\xf4\x3c\xa5\x60\x69\xea\x55\x17\xcb\x21\x4e\x76\xfa\xa5\x3d\xbd\xa1\x00\x00\x3c\x4f\x61\x75\x41\x40\x41\xbe\x74\xde\x22\xce\x15\x5d\x22\x81\xb6\xf4\x03\x5b\xe3\x98\x41\xaf\xdb\x96\xdd\x89\xaa\x80\x8e\x68\x65\xba\xe6\x2d\x6b\xed\xd9\x19\xd3\xe8\x65\x10\xb9\xfa\x5f\xed\xd1\x97\x7c\x41\x31\xb2\xb8\x6e\x0f\x48\xd7\x21\x5e\xb1\x3d\x54\x98\xca\x5d\x23\x68\xf8\x18\x95\xed\x85\x5a\x52\x71\x24\x65\x7e\xc9\x53\x9e\xfe\x3b\x24\x99\xa3\xb0\xb3\x38\x26\x2f\x26\x34\x0e\x22\x55\x4c\x79\xf4\xfa\xd2\xb4\xe4\x19\xc7\x0b\xc1\xa2\x10\x7d\x20\x64\x56\xb6\x36\x87\x81\xbe\x4b\x5e\x2c\x54\xda\x42\xd3\x36\x04\x0f\xb7\xba\x49\xc3\x2d\x75\x23\x21\xad\xcd\x92\x98\x6e\x78\xbe\xdb\x22\x6c\xea\xc5\x02\x92\x08\x9b\xb5\x79\x02\x7f\x70\x22\x17\x74\x5a\xfe\x06\xa5\xbe\x13\x6b\x39\x98\xa3\x60\x4c\x9f\xf2\xac\xd6\xfa\x3f\x3f\x71\x63\x3d\x31\x02\xfb\xf0\x30\x47\xc5\x48\x6f\x84\xc4\xdc\x24\x47\xd8\x63\x79\x63\x83\xd5\x5f\x08\xc9\x81\xfd\x4d\xd7\xdc\x1c\xb7\x2b\x8b\xa4\x43\x5a\xf6\xab\xdd\x74\xe6\xf6\xe6\x79\x8f\x1a\xe2"}, +{{0xbf,0xf6,0x89,0x55,0xdd,0x6a,0xe0,0xe8,0xba,0x85,0xab,0x0d,0x0c,0xda,0xf0,0x4a,0x9f,0x5b,0xef,0xd5,0xef,0x60,0x14,0xf4,0x99,0x94,0xa7,0x83,0x63,0xdc,0x17,0xf7,},{0x0a,0xd9,0x49,0x3a,0xf8,0x0b,0x15,0xf0,0x7a,0x52,0x1c,0xcd,0x67,0x4f,0xe9,0xe5,0x21,0x2a,0x4a,0x28,0xc1,0x7c,0x74,0xf6,0x60,0x5f,0xfe,0xf7,0x8a,0x4a,0xed,0x72,},{0x93,0x19,0xee,0xf7,0x40,0x63,0x3a,0xda,0x1a,0xf0,0xe1,0x37,0x64,0x4c,0x61,0xfb,0x3e,0x11,0xba,0x4b,0x01,0xd3,0xc6,0xf2,0x53,0x92,0xdc,0x93,0x67,0x87,0x2a,0x23,0xbe,0x56,0x31,0x0d,0x31,0x2e,0xfc,0xb9,0x1b,0xdb,0xab,0x78,0xa7,0x5e,0x57,0x6e,0xbe,0x90,0x81,0x97,0x24,0x15,0xf5,0x62,0xdb,0x41,0xba,0xf5,0xe2,0x33,0x8b,0x07,},"\xd8\xf5\x65\x0a\xa3\x58\x1c\x4d\x39\xbd\x1b\x8a\xfc\x96\xc1\xad\x7c\x4b\xf7\x23\x42\x6f\x9d\x7f\xab\xd1\xa5\xc8\xac\x1d\x2f\xe5\x4a\x97\x1f\xac\x76\x5e\x05\xaf\x6e\x40\x7d\x72\x69\xba\xb6\x61\xb3\x43\x22\x92\xa4\x84\xf9\x52\xc1\x10\x95\xbb\xd2\x0a\x15\xd7\x7c\x41\xf8\xf3\x73\x1a\x50\x4d\x51\x8e\xe1\x0c\xd0\x06\xc9\x6e\xe5\x73\x72\xde\x5b\xea\x34\x8e\xc8\xba\x15\x91\x62\x17\x0c\x63\xe9\x70\xf1\xc7\xa3\x46\x5a\x3d\x59\x2e\x1d\x56\xc6\x54\x0f\xbd\xb6\x02\x28\xe3\x40\x90\x96\x46\x32\x0c\x95\xf2\x56\x98\xcd\x48\x96\xbd\xff\x58\xe2\x56\x1e\x3b\x3d\x9a\x73\xb8\x97\x47\x91\x2a\x1c\xf4\x67\xd6\x3e\x41\x45\x5f\xda\x77\x47\x7f\x46\xfe\x69\x37\xbb\x0e\x79\xd9\x2c\xcd\x52\xe8\x2d\xba\x90\x8a\x05\xa5\x7c\x7e\xcf\x49\x55\x4a\xb4\x4c\x0b\x71\x8e\x3b\xdd\x5f\xc0\xbf\x70\x70\xd9\xc5\x8f\x86\x05\x91\xc1\x8b\xca\x8b\x3a\x9a\x14\x8a\x06\x54\x8e\x0f\x01\x60\x2b\x1e\x6f\x68\x60\x37\xc9\x4f\xf7\x32\xe1\x55\xd5\x2d\x5b\x0b\x44\x70\x3b\x3d\x11\x16\x3e\x3f\x56\xe3\xb9\xc1\xb8\x64\x76\xe4\xdc\xbf\xc5\x3f\xa0\x59\x84\xe8\xc7\x5d\xd2\x18\x43\xcf\x96\xf9\xe4\x94\xab\xba\xe7\x18\x4a\xa4\x27\x36\x63\x3e\x38\x11\xae\xff\x40\x2b\x2f\xcb\x7d\x7f\x70\x2e\x44\x72\x41\xe2\x2a\x58\x84\x2f\xd6\xd0\xc0\x3d\x33\xff\x5b\x8c\x79\x22\x00\xe1\x73\xda\xa7\xb2\x17\xe4\xb2\xf4\x43\x3e\x6c\x02\x0a\xcc\xe5\x01\xb9\x32\x3a\xa0\x24\x11\x44\x43\x4b\x08\xe9\xd2\x46\x91\x39\xff\x67\x34\x22\x08\x90\x05\x46\x20\x0f\xd9\x71\xa6\x5d\xbd\x6d\xb6\xc2\x1e\x3e\xf9\x17\x2a\xbb\xa1\xea\x9e\xa2\xa2\x49\xad\xdf\x1a\x1e\xaa\x3c\xe1\x19\x38\xb1\x3e\x30\x91\x3c\xd0\xda\xd4\x91\xfc\xbb\x32\x85\xea\x37\x8b\x8e\xf9\x22\x7f\x3f\xa8\x0b\x58\x6e\xcf\xea\xe1\x37\x06\x6f\x84\x48\xac\xdf\xb7\x8d\x6d\x3e\x9e\xf4\xa6\xb3\x62\xdf\x42\x41\xad\x9a\xe2\x53\xb8\xe1\x59\x7d\x65\x6e\x00\x0c\xea\x44\x7a\x02\xfa\x49\x33\x32\x86\x09\xbb\xa0"}, +{{0x1b,0xa9,0x19,0xc0,0x66,0xbb,0x56,0xe6,0x40,0xc3,0x33,0x59,0x68,0xe1,0xd1,0xb5,0xbc,0xc0,0x93,0x38,0x3e,0x2d,0x7c,0xf8,0xb5,0xff,0xf5,0xc6,0x1e,0xc4,0x7a,0x77,},{0x80,0x4c,0x90,0xbd,0xc2,0xb3,0x61,0x8b,0x01,0xf0,0x75,0xe0,0x41,0xfa,0x97,0x1b,0x83,0xc5,0xb6,0xcf,0xa3,0xb6,0xb3,0x97,0x4f,0x3f,0xa4,0x35,0x99,0xbe,0xac,0xab,},{0x50,0x3e,0xb7,0xed,0x6d,0xe1,0xb7,0x76,0xc9,0x52,0xf2,0x55,0xbb,0xd4,0xbc,0xfb,0x0e,0x48,0xbc,0x70,0xc2,0xcc,0x2f,0x1f,0x72,0xbf,0x68,0x81,0x47,0x90,0x40,0xc4,0x75,0x24,0xec,0x54,0x2a,0xe1,0x3f,0x60,0x05,0xca,0x50,0x16,0xb5,0x8b,0x73,0x6a,0x50,0x89,0x8d,0xd0,0x56,0x9d,0x4d,0x38,0xad,0x29,0x86,0x30,0xd6,0x8a,0xdb,0x0b,},"\x87\xc5\xc7\x5d\x8a\xd0\x7d\x52\xac\xd7\x81\xd1\xbb\x95\xf7\x8c\x70\xe2\x1c\x2d\xd6\x6f\x7a\xa4\x42\x34\x15\x2f\x98\x23\x4d\x12\x83\x58\xa8\xae\xe9\x8e\xa9\x03\xa7\x7b\x44\x1d\xb1\x44\x7a\xe6\xff\x34\x32\xdd\xd4\x57\x0f\x7f\x58\x03\x61\x22\xc1\xfd\xcc\x93\xcb\x21\x57\x37\x39\xc1\x9c\xca\xa4\x11\x50\x8e\x08\xde\x26\x06\xf3\xd8\xf2\xdb\x89\xdf\x6a\x44\xa4\x61\x33\xd5\x70\x18\x46\x26\x27\xe2\x2f\x57\xef\x36\xd1\xde\x02\x4d\xe3\xd4\xae\x41\xb7\x52\xdf\x48\x21\x15\x59\x34\xb4\x47\xb2\xef\xfe\x51\x24\x87\x52\x1b\xe0\x35\x68\x32\xa7\x4c\xe0\xe2\xd8\x30\x1b\x79\xf9\x31\x75\xe8\xb6\xb9\x61\xb1\xdf\x63\x7d\x8a\xca\xdc\x88\x45\x43\xc6\x86\x4f\x80\x25\xec\xec\xec\x7c\x6e\x4f\xe0\xfe\xcf\xc4\x0d\xcd\x95\xe8\xd6\xab\x93\xce\x25\x59\x53\x84\x43\x6b\x59\x8b\x73\xc7\x4b\x03\xd4\x9e\xd5\x00\x2c\x0f\x85\x8c\xfd\x9d\x0d\xf6\x1e\xde\x93\x7c\xc4\x16\x59\xd6\x70\x8b\x96\xfc\x5a\xaa\xde\xe1\x09\xe2\xa6\x88\x46\xba\xf2\xc2\x46\xdf\xcf\x3d\x27\xc2\x8b\xd1\x37\x1e\x35\xfc\x94\x12\x63\x14\x42\xee\x75\xf3\x8c\x6e\x49\x58\x07\x0a\x74\xf6\xe6\xa2\x20\xf7\x5c\x72\x80\xea\xb4\x73\x7d\x97\xe3\x78\x82\xf3\x62\x48\x11\x67\x5f\x16\xca\xf6\x0c\xb9\x44\xbc\xe9\x2e\x75\x88\x4c\x56\x48\x3c\x61\xf2\x6b\x63\x71\xb1\xb5\x12\x37\x62\x1a\x06\x54\x3e\xb4\xab\xea\x7b\xec\xc4\xfc\x31\xdb\xb5\x47\x5b\x3d\xeb\x9b\xb3\xc8\x99\x23\x87\x10\x48\x30\xc6\x07\x2a\xfe\x1a\xf2\x44\xbf\x68\x1a\x40\x32\x9c\x9b\x37\x77\x2b\x09\xc5\xe8\x8e\x78\xf7\xdf\xfb\xc0\x45\x49\xff\xa1\x3b\x41\x44\xdd\xfa\x53\x8f\xc4\xb3\x30\x05\x40\xad\x83\x02\x15\xe2\x5f\x11\x44\x6d\x28\x9f\x33\x12\x2c\x2c\x88\x0d\xe3\xda\x71\xc4\x53\xd7\xe8\x8f\x7c\xa4\xea\x3d\x12\x55\xe8\x2f\x4b\xc9\xe5\x53\x3d\xc4\x01\xc3\x30\x40\xe1\x69\x40\xb2\xcf\x9c\xf2\x1f\xea\xca\x1c\x2c\x6c\x33\x33\x7c\xf7\x5e\x18\x84\xb4\x83\xbf\x80\x15\x36\xd3\x04\x08\x91\x15\xa0"}, +{{0x9b,0x36,0x24,0x7c,0x17,0x71,0x0e,0x95,0x26,0x1a,0x7d,0x70,0x2f,0x57,0xfe,0x81,0xf2,0x97,0x11,0x17,0xa5,0x0c,0x87,0x92,0x01,0x93,0xb3,0x86,0xd4,0x94,0xca,0x97,},{0x29,0xae,0x39,0xf2,0x73,0xe3,0x5f,0xb3,0xf6,0x11,0xda,0x09,0x16,0x00,0x65,0x0e,0xfb,0xc4,0xfc,0x4d,0x1e,0x7b,0x4c,0x76,0xac,0xed,0x5a,0x83,0xf8,0x26,0x34,0xf3,},{0x03,0x59,0x70,0xa6,0x72,0xe9,0x3f,0x87,0xeb,0x42,0xcc,0x39,0x6f,0x6e,0xa7,0xe1,0xb3,0xdd,0x5c,0x59,0x51,0x57,0x28,0x26,0xd1,0x07,0x5a,0x15,0xc2,0xd7,0xe4,0x54,0xdf,0x19,0x5b,0x51,0xaa,0xe8,0xdc,0x61,0xef,0x7a,0xb8,0x95,0x48,0x5f,0x64,0xe5,0x98,0x95,0x73,0xd9,0x8a,0x06,0x2e,0x67,0xae,0x73,0x56,0xfe,0x5c,0x9e,0x3b,0x0f,},"\xe8\xd9\xd5\x3b\xa2\x7e\x98\xed\xd5\x5d\xf3\xc6\xb2\x45\xea\xcd\xdc\x8a\x40\xe3\xef\xb0\x07\xbc\x91\x8e\xc5\xa8\x69\x17\x8a\x17\x0b\xb4\xa6\x35\xb7\xf8\xf7\x42\xe3\x7a\xd4\x5d\x14\xa7\x43\x44\xa6\xb5\x22\x83\x0a\x52\x21\x06\xeb\x96\x0d\xaf\x19\x2d\xc1\xe0\xfd\x70\xf1\x61\x60\xe1\x22\x51\x68\x92\xd0\xe2\xab\xd0\xd4\xae\x0f\x0d\x2e\x5a\xdc\xc9\x9a\xd5\x53\x02\xe2\x51\xb3\xe7\xa4\xd0\xcb\x33\x77\x4a\x49\x70\x49\x90\x5c\x33\xde\x1f\xbb\xc1\xad\x2b\x6c\x64\x52\x95\xfe\x41\x6b\x4d\x12\xb2\x32\xef\xe0\xa3\x3c\xd2\xad\x87\x32\xeb\xa1\xc3\xcb\x0e\xae\xb0\xb2\xa5\x7f\xa0\x3e\xc5\x67\xca\x29\x21\x0b\xf6\xff\x95\x42\xa7\x66\xf4\x96\xfe\x68\x05\x8a\xa9\x83\x80\x6c\xbe\x7a\xb1\x0a\x47\x92\x0b\xac\x82\x48\x81\x8e\x54\xa4\x15\x51\xc9\xa0\x95\x9e\x89\x94\xca\xc6\x0f\xc8\x68\xad\x48\xb5\xa2\x4d\x5f\x24\xa7\xa5\xa3\xfd\x90\xb8\x47\xe8\x17\xad\x3d\xd5\xd0\xd6\xf8\xde\x2d\x20\x4f\x64\x24\x83\xbd\x53\x58\x5a\x92\xef\x92\x54\x15\xa9\xb3\x8f\xbb\xf0\x7f\xc0\xf3\x5e\x70\x75\x69\xcf\x48\x8b\x20\x54\x53\xce\x54\x33\xeb\xa6\xfd\xe8\x78\x1a\xf7\x2b\x52\xbf\xbc\xab\x85\xea\xd3\x85\xd9\xd3\x17\x5e\x21\xad\x33\x73\xad\x53\x5c\xf0\xe3\x57\xed\x6b\x53\x83\xef\x38\x29\xa9\xd5\x09\x5b\x87\xdc\x9a\xad\xbe\x0c\xa7\xab\xad\xf3\x3e\xc3\xb6\xff\xd6\xeb\x94\xaf\xdc\xc1\x2e\x8d\x66\xa6\xfc\x05\xac\xf9\x73\x68\xdb\x0f\x69\x56\x5d\xcd\x8f\xef\x4d\x1e\x49\xd7\xdd\x4a\xc0\x53\xc2\x18\xf5\x24\x0c\x81\x2d\x4e\xbb\xa4\x40\xdc\x54\xca\xcd\xdb\x1c\x39\x32\x9e\x5b\xd0\xc3\xc8\x0d\xc3\x25\x9a\x80\xf0\x59\xf9\x46\x79\xaa\x07\x94\xca\x01\x15\xcc\x62\xaf\x25\xe1\x24\xcb\x8a\x9d\x41\x60\xea\xce\x6d\x22\xc7\xb1\xc4\x45\x44\xf8\x11\x42\xa1\x9e\xbb\x02\xa9\xbd\xa6\x42\x9c\x50\xe7\x83\xdb\x4a\x07\xf0\x21\x9e\x85\x7c\x8d\x3c\x56\x55\xa5\x82\x83\x1c\x8e\xab\xc3\xf1\x9b\x59\xad\x8d\x2c\x71\x4a\xde\xaf\x40\x39\xd5\xcf\x70"}, +{{0x6f,0xed,0xe7,0x39,0x6c,0x46,0x20,0x33,0x18,0x9a,0xcd,0x23,0xd2,0xf9,0xd0,0x2b,0x68,0x89,0x8d,0x35,0xf3,0xa0,0x1a,0x79,0x8f,0xc2,0x4d,0x48,0x8d,0xe9,0x3a,0x78,},{0xb3,0x40,0x62,0x06,0x0b,0x2c,0x20,0x07,0x6a,0x98,0xfe,0xa9,0x39,0xb3,0xb3,0xa5,0x04,0x51,0xa5,0xf4,0x9f,0x83,0x51,0xc0,0xad,0x75,0x91,0xdb,0xbe,0xbb,0x13,0x0f,},{0x88,0xa8,0x3e,0x20,0x12,0xd2,0x09,0xca,0x03,0xb8,0xeb,0xf6,0xde,0x5b,0xb7,0xef,0x4c,0xcb,0x5e,0x3d,0xf5,0xca,0xc7,0x89,0x54,0xaa,0x69,0x49,0x30,0xe4,0xde,0x82,0x54,0x4e,0xf5,0x08,0x3c,0x48,0x92,0xdb,0x9f,0x05,0xd7,0x7b,0xf6,0x3f,0x4f,0xdf,0xce,0x15,0xa4,0xd1,0xc3,0xf8,0x5b,0xae,0x80,0x77,0x06,0x2b,0xec,0x0e,0x7b,0x07,},"\x5a\xbc\xc1\x4b\x9d\x85\x78\xde\x08\x32\x1d\xe0\xd4\x15\xe3\xd4\x0e\x9d\xe3\x1e\x18\x88\x13\x74\x75\xce\x62\xbc\x6f\xbe\xe8\xfd\xd0\x3b\x9d\x47\xc7\xb8\x8b\xbc\xeb\x80\x44\x44\x49\x0b\xf6\xa3\xcc\xb7\xa2\x73\x26\x1e\x24\x00\x4e\xa6\x7c\xef\xa3\xd5\xd1\x73\x57\x6d\x01\xe3\x8f\x76\xc1\xe0\xe5\x15\x08\x3c\x97\xe7\x99\x14\xac\xf2\xbe\x41\x60\xef\x93\x60\xbb\xe9\x86\xb3\x6e\x9f\xf9\x33\x46\xb0\xe7\x06\x91\xd9\x34\xe4\x7f\x8a\x50\x3f\xa9\x33\xab\x2a\x50\x42\x69\x47\xcd\xa8\xe8\x10\xc9\xeb\xe3\xb3\x69\x82\xf0\x9a\xee\x60\x92\x73\x9f\xa2\x35\x8b\x61\x3c\x7f\x12\x9d\xb0\xdc\xbe\x36\x8b\xee\x52\xf2\xf7\xf1\xdf\xe3\xd2\x43\x46\x05\xb5\xaf\xcf\x25\x60\x71\x71\x7d\x92\x4f\xd0\x80\x3b\xbd\x0d\xd1\xf9\x55\x5c\xe8\x34\xda\xc7\x81\xdf\x4c\xc7\xaa\x19\xe7\xf1\x1d\xa9\xfb\x99\xcb\x9e\x6b\x9e\x1e\x6f\xb4\xf7\xe8\xdc\xb2\x23\x6c\x28\xae\xb6\xcb\xc5\x5a\x13\x0e\x03\xc1\xb1\x7a\x99\x1c\xca\x1b\x79\x4e\x6c\x13\x73\x2d\x5b\x0a\x66\xf6\xeb\xa8\x60\xec\xb9\x85\x55\xaa\x4c\x21\x8d\x11\x2b\x11\x6b\xce\x23\x82\x95\xde\x14\x27\x41\xf6\x87\xbe\x0b\x24\x87\xf5\x8f\xfc\x5c\x12\xa0\xa5\x19\xf1\xe2\x37\x93\x24\x2e\xf8\x57\xed\x39\x8a\x20\x69\x9d\x43\x51\x45\x3f\xc2\xf0\x92\x76\x2a\xbd\xe3\x4f\x4d\xa2\xdb\xe0\xce\x2a\xab\xaf\x6b\xc4\xc0\x15\x9f\x3f\xe1\xae\xa1\x6a\x03\x6f\x7e\xae\xcd\x62\x95\x38\xf3\xe0\xee\xd8\x3c\x9a\x4d\xc1\xab\xc2\x38\xf9\x0d\xaa\xf4\x89\xfd\x61\xb3\x4d\x93\x7b\x6f\x46\x07\xa7\x88\xba\xa8\x20\x61\x94\x3d\xba\xb2\x6c\x1d\x38\x4d\x8d\x49\xf9\x93\x48\x80\x0b\xf3\x61\xf8\x71\xf5\xd6\xcd\xa1\x8f\x68\x99\x18\xce\xc3\x1a\xd1\x58\xf1\x86\x3d\x13\xff\xac\x54\x05\xc1\x62\xc3\x2d\xe0\x6e\x32\x99\x4c\xc4\x10\x6f\x95\xbb\x4f\xff\xdb\xef\xe7\xd6\x29\xec\x77\x97\x39\x46\x09\xfd\xbf\xea\xdb\x46\x92\x73\x70\xa1\x1f\xb3\x84\x71\x54\x0f\x95\x1b\x93\xc6\xeb\x23\x86\x68\xdc\x00\x6c\x21\x66\x0b\xa2"}, +{{0xd5,0x59,0x58,0x01,0x34,0xab,0x05,0x0a,0xca,0x44,0x6e,0xa7,0x75,0x0e,0xf6,0xb3,0x71,0xd9,0x2d,0x76,0x45,0xec,0x76,0x35,0xfe,0x78,0x51,0x10,0x0b,0xc4,0xe5,0x1e,},{0xde,0x50,0x20,0xcd,0x21,0xa8,0xb3,0x23,0x39,0xde,0xcb,0xed,0xff,0x24,0x66,0x4d,0x95,0x80,0x32,0x63,0x27,0xae,0xdf,0x09,0xc5,0xec,0x6b,0x3f,0xe5,0x40,0x52,0x26,},{0x6f,0xcb,0x1a,0xc9,0x29,0x0a,0xb7,0x67,0xd5,0x9b,0x59,0x8c,0x9a,0x24,0xec,0xdb,0x6c,0x05,0xbb,0x02,0x3e,0xc3,0x60,0x14,0xa4,0x0d,0x90,0x8e,0xf0,0xdc,0x37,0x8a,0x45,0x28,0xb3,0x76,0x0d,0x88,0x9a,0x79,0x17,0x4e,0x21,0xca,0xe3,0x5d,0xf4,0x5d,0x42,0x7b,0xa6,0xea,0x81,0x2b,0xdd,0xca,0x16,0xe3,0x5a,0x69,0xb5,0xe7,0x9f,0x0a,},"\x68\x42\xe3\x19\x0a\x11\x0e\xee\x96\xc5\x07\xd4\xbc\xb4\xc5\x48\xc3\xa0\xed\x7b\x1a\x8e\xd7\x7d\xd9\x3b\x38\x61\x3b\x23\xc7\x3e\x83\x0b\x20\x5e\x62\x65\x19\x21\xad\x82\x96\xb0\x8d\x1e\x10\x08\xad\x78\xf2\x99\x6e\x3c\x7f\x38\x03\x2e\x46\x7c\xff\xec\xd7\x7b\x85\x25\xe2\x43\xce\xc0\x21\xf8\x52\x96\xaf\xd5\x45\xd7\xbe\x1a\x62\x56\x8b\xb0\xcf\xcd\xb9\x0d\x61\x4e\xd7\x98\xbf\xb7\xef\xc6\x55\x32\x68\x16\xa6\x10\x82\x25\x1d\xf0\x16\x13\xaa\xc8\x8e\xfc\xea\x1e\x0e\xa2\x96\x1b\x8f\x92\x1e\xbe\x15\x58\xde\xe8\x33\x74\xa0\x11\x3a\x78\xc5\x58\x57\xce\x20\x55\xbb\x2c\x48\xba\xdb\xd3\xd8\xf4\xcb\x19\x73\x4d\x00\xd0\x60\x4b\x61\x90\x73\x02\x0d\x72\xa9\x9a\x19\x23\xe6\x16\x0a\x09\x94\x65\x67\xfd\x4b\xda\x66\x44\x2e\xf5\xa7\x36\x07\x86\xd1\x78\xda\xe4\x49\x22\xf3\x50\xce\x2e\xdc\x6a\xf7\x3d\x1b\xd8\x0d\xc0\x3e\xc3\xca\x70\x05\xf4\x10\x9d\x10\xc6\xd4\xf7\xd8\xfa\x61\x73\x51\x10\xf8\xdb\xae\xdf\x91\xa0\xba\xd7\xd7\xfb\x5c\x04\xd7\x06\x37\x3c\x15\xc6\x45\x06\x3f\xf4\xb4\xfb\xd2\xd5\x59\xb0\xaf\xad\x43\x2d\x4c\x49\x6c\xd8\xab\xfe\xa2\x86\xfa\x67\x5d\xc0\x76\x72\x6e\xc5\x22\xb3\xa3\xc2\xf4\x7a\xec\xc5\x39\xf4\x8a\x79\x21\x69\xc4\xcc\x8c\xd4\x1c\xd2\xcb\x6b\x63\xdd\xbc\x19\x37\x3a\xc9\x69\x1c\x2b\xc2\xf7\x8f\x22\x60\x3d\x55\x13\x71\x5a\x16\xd4\x57\x4e\x7a\xcc\x4b\xea\x6d\xcd\x8c\xa7\xf1\x98\x65\xa4\x9d\x36\x64\xa2\x10\xdf\xad\x29\x07\x74\xb1\x0b\x71\x88\xf2\x55\xb3\xbe\x4d\xc8\xfa\x86\xf8\xda\x3f\x73\xa4\xe7\xc9\x29\x95\x1d\xf3\x0f\xe6\x6a\x17\xc8\xce\xe2\x3e\x4f\x2e\xd2\x06\x3f\x0b\x02\xab\x40\x37\x2c\xbe\x54\xb9\xa7\x08\xdf\x7c\x48\xa0\x65\x66\xd3\x9b\x19\x43\x4c\x6c\x76\x69\x87\xb3\xeb\xb0\x06\x75\xf4\x4c\x4b\x3c\x1e\x9f\x45\x04\xe7\xa9\x27\x05\x89\xc0\xd0\xf4\xcb\x73\x42\x35\xa5\x8e\xf0\x74\xcf\x9d\xec\xf3\x60\x1a\xee\xca\x9f\x1d\x8e\x35\x6c\xb2\xdb\x5f\xce\x79\xcb\xc3\x61\x43\xf3\x4b"}, +{{0x9d,0x4c,0xe9,0x75,0x54,0x78,0x76,0x63,0x6f,0xea,0x25,0x43,0x7c,0x28,0x80,0xc9,0xaa,0x8e,0xe6,0xb2,0x70,0xd1,0xb2,0xda,0x19,0x7c,0x8d,0x7f,0x95,0xe7,0xdc,0xcc,},{0xbd,0xe4,0x99,0x3c,0x03,0x04,0x77,0xc3,0x58,0x90,0xaa,0xe8,0x2b,0xb5,0x08,0x7e,0x91,0x4e,0x64,0xb9,0x4f,0xfc,0x64,0xe2,0xd7,0xa5,0xa7,0xc9,0x19,0xe2,0xd9,0x02,},{0xbe,0x17,0x44,0x4c,0xd4,0x65,0xa8,0x7a,0x97,0x1d,0xf8,0x4e,0xb1,0x02,0xf9,0xc7,0xa6,0x26,0xa7,0xc4,0xff,0x7a,0xea,0x51,0xd3,0x2c,0x81,0x35,0x3d,0x5d,0xbc,0x07,0x39,0x3c,0xa0,0x3d,0xb8,0x97,0xd1,0xff,0x09,0x94,0x5c,0x4d,0x91,0xd9,0x8c,0x9d,0x91,0xac,0xbd,0xc7,0xcc,0x7f,0x34,0x14,0x4d,0x4d,0x69,0xeb,0x04,0xd8,0x1f,0x0c,},"\xea\x0f\xa3\x2a\x4a\x28\x88\x11\x30\x1b\x9e\xe5\x33\xfa\x35\x1f\xdf\xbf\x6b\xc1\xd0\x55\x5a\x74\x02\x76\x7a\x3a\x91\x98\x55\x8f\x74\xbb\xa7\x03\x18\x57\x99\x5b\x9f\x32\x62\x26\xf1\xdd\x5d\xf1\x07\xb0\x63\x42\x20\x3e\xb8\xd4\x0c\x5f\x1d\xc9\x5b\x4f\x3f\x88\x97\x5a\xa2\x4a\xf8\x76\x9e\x26\x70\xc4\x66\x71\xbe\xbb\x7a\x0f\x1b\x75\x68\x72\x9a\xee\x47\x7e\x89\x88\xaf\x9c\x74\x9f\x32\x02\x70\x81\x71\xfd\x94\xb3\x37\xae\x67\xed\x21\xa6\xc4\x41\x74\x01\x4b\x0b\x0e\xb5\xba\x71\xc2\x77\x97\x8d\x48\x8c\x24\xc4\xa7\x84\x13\x09\x84\x6b\x4e\x30\xa4\xfb\xbc\xfc\x45\x07\x8d\x7e\x14\x01\x41\x14\xb1\xac\x64\xf7\xc3\x3c\x9a\xc2\x5e\xa5\x62\x6c\x2c\x81\x9f\xba\xa2\xa4\xde\x8a\x2b\xf5\xf1\x36\x5d\x6b\x70\x40\x7e\x80\x94\xf9\x91\x97\xce\x1f\x0c\x35\xe1\x1a\x98\xfb\xe3\x72\x41\x4e\xa2\x06\x4a\x3a\x12\xd1\xcd\x5c\x8d\xf8\xfc\x0e\x79\xf5\xb7\x70\xb5\x8f\x47\x7f\x91\x97\x6c\xa0\x13\x98\x95\x12\x0e\x24\x6b\xaa\xb5\xa0\x26\xf2\xd3\x9c\x68\x7d\xc0\x78\x83\x34\xb5\xc6\x26\xd5\x2c\xde\xbe\x05\xea\xf3\x08\x64\xb4\x13\xee\xbd\xc5\x58\x1e\xf0\x0d\x43\x92\x76\xe5\x2f\x47\x9c\x9c\x05\xb1\x16\x39\x58\x26\xb6\x04\x90\xb3\xce\x70\x0c\xc0\x02\x7f\x61\xe4\x6c\xa2\xf6\xfb\xc2\xc9\xde\x2e\x80\x08\x06\x55\x0a\xfb\x06\xd4\xa0\x8e\xac\x7a\x75\x8e\x24\x58\x2a\x4d\x6d\x42\x8b\x43\x3d\x36\x5f\xc3\x1d\x44\x44\x60\x7a\xfb\x64\xf1\x5e\x37\x07\x94\x00\x5a\x3a\x22\x44\xe6\x66\xd5\xd4\xc3\x8a\xd2\x00\x9c\x76\x9a\x51\xcd\xbf\x73\x8d\x23\x59\x42\xf4\x12\xd0\x7f\xee\xb7\x3b\x36\x57\xd0\xb0\xc9\x1c\xb5\x94\x0b\xad\x6a\x70\x6e\x14\xed\xcd\xc3\x42\x25\xb1\xc1\xf3\x8b\x1a\xbe\xcb\x2a\xdc\xaf\x81\x91\x55\xa9\x4f\xe1\x90\xfd\x55\x68\x22\xd5\x59\xd9\xc4\x70\x85\x4d\x3a\x43\xbf\xb8\x68\xda\xdd\x6e\x44\x3d\x98\xee\x87\xe4\xd8\x28\x4f\x5c\xf3\xa6\xda\xfa\xf2\x95\xb9\x02\x83\x6c\x64\x05\x11\xe6\x10\xae\x7d\x0c\xb1\xb1\xd3\xd6\x07\x9f\xe6"}, +{{0x02,0x73,0x86,0x82,0x32,0xf5,0xbe,0x48,0x59,0x2c,0xfa,0x05,0x13,0x4e,0x8d,0x55,0x54,0xed,0x1f,0x9a,0x57,0xbc,0x7e,0x39,0x82,0xa3,0x30,0xc5,0x7e,0x5a,0x7f,0x3a,},{0xf1,0x72,0x20,0x87,0x82,0xdb,0x66,0xd4,0x66,0xcb,0xe4,0xf4,0x41,0x7f,0x6f,0xc4,0x77,0xb7,0x34,0x9f,0x2a,0x98,0xdb,0x56,0xc0,0x3a,0x47,0x22,0x75,0x46,0xbc,0x5a,},{0x15,0xe8,0xd8,0xdc,0x7d,0x5d,0x25,0x35,0x9d,0x6a,0x10,0xd0,0x4e,0xe4,0x19,0x18,0xa9,0xc9,0xdf,0x4c,0x87,0xbe,0x26,0x9f,0xa8,0x32,0x43,0x4d,0x53,0x01,0xdb,0x02,0x24,0x81,0xbf,0xa3,0x95,0xa3,0xe3,0x46,0x6f,0x95,0x54,0xce,0xee,0x05,0x32,0xa8,0x18,0x3a,0x0d,0x05,0x50,0xe7,0xd1,0xab,0xe9,0x9f,0xc6,0x94,0xc6,0xff,0x93,0x01,},"\xf7\xa1\xd4\x61\x4c\xc6\x4a\x3b\xc4\x8f\x00\xc6\x27\x63\x04\xf3\x4d\x4d\xfd\x15\xe0\x61\x7b\x93\xcc\xef\x12\x6c\x5c\x63\x8c\x9d\x99\x53\xaa\xbb\x7d\xf4\x2d\xf4\xe0\xaa\xa7\xea\xc9\x6a\x4b\x38\xc7\xba\x75\x8d\x86\x0c\x90\xd0\x5e\x3d\x14\xe4\x79\xe5\x45\xf3\x19\xb0\xe5\xa8\x5a\xd8\xf0\x99\x1b\x43\xd6\xe4\x9c\x24\xfa\x06\x0e\x3e\x5d\xf9\x5c\x98\xd9\x45\x1a\xb8\x33\xe1\x2a\xa9\x7f\x40\x46\x11\xbb\xa3\x59\x49\x62\x65\xa6\xdb\x11\x91\x7d\x0d\xa5\xc6\xa7\x02\xd0\xb1\x02\xde\x36\xdd\x0c\x98\xdf\x5b\x54\x80\x6c\xe6\x26\xbb\x96\x37\x44\x75\xf6\x8a\x60\x60\xeb\x35\x0a\x7d\x2a\xae\x32\x04\xb3\xdf\xdf\x9f\x1e\x31\xbe\x81\xf7\x17\x0f\x8a\x1b\x93\x85\x41\x3f\xf8\xf6\x88\x1e\x10\xc1\xe8\xda\x4c\x88\xaf\xb5\x06\x39\xab\x44\x88\x7a\xca\x2a\xbe\xec\xed\xf1\x10\xd2\x95\x8c\x13\xfd\x33\x90\xd1\xb9\x6a\x76\x2d\x16\xce\x19\x69\x20\xce\x85\xf6\xc4\x15\xbe\xd5\x45\xb1\x44\x53\x02\xa6\xf0\x01\xeb\x8d\x00\xe9\x7c\x75\x18\x87\x86\x8d\x48\x1a\x0b\x1e\x4d\xfa\x04\xb6\xf7\x61\x08\x6e\xe8\xe6\x97\xb0\x19\xe0\x17\x10\x4b\xaf\xb9\x8f\xca\x24\x2e\x33\x4c\x6f\x18\xf1\xdb\x5b\x6f\x29\x5f\x05\xc5\x59\x36\x1c\x68\x31\xda\xbc\x42\xc2\x11\x07\x03\xf9\xd1\xf6\x4e\x12\xdd\xf2\x6a\x86\x79\x85\x4e\x9f\x8e\xf8\x47\x9e\x1f\x12\xc3\x54\x47\xaa\xc0\x2e\xa7\xf2\x42\xe5\x86\x32\xcf\x2f\xd0\x63\xfe\x66\x50\x70\x44\x5b\x80\xf3\xdc\x6a\x33\x03\xbb\xa9\x6e\x05\xfa\x88\xee\xc2\x01\xc5\xc2\xd0\x0c\xa8\x1b\x8d\xa6\x96\x9d\x0a\x4d\xd0\x48\x3b\x34\x77\xd3\x25\xa7\x1f\xac\xd6\xfa\x22\x09\xb4\x8c\xb4\xf6\x52\x5d\xa7\x3c\x9c\x05\xb2\xd9\x78\x9b\x01\x44\x8e\x15\x27\xe5\x6a\x09\xa9\xbc\x61\x36\xd9\x83\x72\x43\xc2\x07\x7b\x92\x5b\xbb\x93\x3f\x8f\xb1\xda\xac\x96\x33\x98\xc5\x80\x2a\xed\xa3\xbb\xca\x8a\xe3\xb8\xf4\xa9\xa8\x71\xf7\xea\x8e\x2c\x0c\xe8\x98\xc5\x66\x21\x7b\x5c\x06\xff\x55\xff\x9f\x4f\xe7\x83\x98\xae\x79\x73\x64\x1e\xaf\xb5\x21"}, +{{0x33,0x6a,0x83,0xb5,0x5a,0xbf,0x4c,0x02,0xe2,0x5e,0x54,0x03,0x29,0xb5,0x27,0x58,0x43,0xc2,0xec,0xb8,0xdf,0x69,0x39,0x5b,0x5a,0x5e,0x24,0x1b,0xd0,0xd8,0xc1,0x0d,},{0xdd,0x60,0x56,0x98,0x44,0x57,0x0c,0x9f,0x0a,0x82,0x64,0x3f,0x44,0x64,0x78,0xb5,0xac,0x6f,0xc5,0x42,0x21,0x42,0x31,0xa7,0xca,0x65,0x6a,0x92,0xb5,0xfd,0xaa,0x54,},{0xd2,0x63,0xf5,0x6d,0x59,0xcb,0x9b,0x28,0x96,0xa9,0x47,0x26,0x7c,0x2e,0xd7,0x8a,0x94,0x5b,0xac,0x5a,0xbd,0xbf,0x3c,0x14,0xdc,0x3a,0xd0,0x92,0xb2,0x30,0x8c,0xb9,0x31,0x5c,0x46,0x49,0x42,0xa0,0xa2,0x0b,0x20,0x24,0x51,0x1d,0x76,0x6e,0x85,0xc9,0x36,0x49,0x9a,0x14,0x9c,0xd0,0xbb,0xb2,0x09,0x15,0x0a,0x16,0x43,0x26,0x52,0x00,},"\x9a\xfe\xe8\xab\x48\x20\x10\xe2\x92\x64\xb4\x06\xd9\xb4\x94\x53\xd1\xce\x6d\x55\x09\x39\x07\x21\x82\x86\x3e\x46\x65\x28\x4a\xb0\x5d\x86\x25\x8e\x06\x23\xb1\x87\x54\xc4\x78\x52\x38\xf6\x97\xf0\x75\xad\xfb\x9e\x1d\x31\xa4\x2e\x85\x93\x4e\xc0\x71\xdd\xdd\xec\xc2\xe6\xc2\xf6\x13\x34\xa7\x95\x26\x78\x8b\x49\x52\x19\x07\x16\x90\x6d\xde\x17\xfb\xa5\x56\xee\xa4\xc8\xb5\x97\x27\x51\x4f\x6f\x56\x15\xa1\x9c\xa3\x6d\xa3\x58\xfa\xe6\xa6\xc5\x4f\x7f\x4b\x7a\x92\x9e\x31\xba\x7c\xc7\x1b\xde\x78\x82\xfa\x9f\xfd\x87\x30\x01\x36\x40\x9c\xaf\x3c\xa6\x4e\xef\xea\x61\x6a\xed\x58\xda\x5d\xfb\xf2\x8b\x66\x8e\xc1\xcc\xcf\xfc\xef\x6e\x2e\x14\xf8\x10\x9e\x9c\xbf\x76\xcf\xa4\x14\xf9\x1a\xc0\x0f\x48\xe9\x3e\xad\xa3\x85\xdd\x3d\x5c\x16\xe1\xa3\x9e\xa3\xdd\x55\xc7\x61\xfc\xa3\x61\xb4\x28\xf5\x16\xc0\x5e\x69\x4f\xe5\xc3\xc3\x45\xcd\x94\x45\x71\x87\xa8\xe6\x04\xb2\x00\xa1\xa0\xf9\x37\xae\x89\xf4\xd6\xb5\x42\x1d\xff\xcf\x7c\xa1\x5f\x2e\x2c\x25\x37\x8a\x41\x13\x23\x3f\x76\x13\xf4\x57\x0a\xa4\xb9\x09\xa9\x13\x5e\xae\x4c\x7b\x9e\xad\x45\x80\x07\xae\x17\x12\x6a\x11\xd1\x45\x25\x8a\xf9\x56\x3d\xb2\xf7\xe8\x92\x54\x31\x87\x8b\x0e\xec\xa8\xaf\xfc\x01\xac\x59\x13\xbf\x5b\xac\x4f\xa3\xa8\x57\xc5\x4c\xc8\x90\x6d\x6a\xf7\x7d\xe6\xb9\x32\x6b\x65\x06\x15\x10\x99\xe8\x7e\x99\xb1\xe8\x19\xc6\xfb\xe0\x82\x68\x8f\x34\xb8\x03\xd5\x88\xe4\x16\xd8\x53\x16\x97\x65\xd6\x2f\x7e\x0b\xdf\x72\xc5\xcd\x66\x66\x9a\x03\x35\x56\x23\x36\x73\x5e\x7e\xfb\x73\x4a\x2f\xad\xa3\x27\xf8\x58\xbe\xc6\x02\xd0\xda\x08\xeb\xa4\x47\x9e\x7f\x6d\xc4\xde\xf6\xe4\xeb\xdb\xb7\x30\xee\x91\xa3\x34\x45\xca\xdc\x9d\xf5\x2c\x82\x5a\xd3\x61\x49\xce\xfb\xc5\x1a\xb1\x02\x03\x35\x30\x81\x4b\xaf\xa7\xe8\x79\x61\xb0\x63\x67\xff\x89\x6f\x08\xae\x33\x4a\x9b\x1a\xad\x70\x3d\xa6\x86\x70\x6c\x11\xa0\x49\x43\xea\x75\xe1\x29\x92\xdc\xf6\x10\x6e\x37\x20\x77\xcd\x03\x11\x02\x9f"}, +{{0x88,0x40,0x91,0x72,0x61,0x8b,0x49,0x03,0x93,0xdb,0x27,0xd9,0x60,0x17,0x1c,0xbc,0x18,0x7e,0xaf,0x4d,0xd8,0xb3,0x20,0xb3,0xd2,0xf8,0x24,0x98,0x00,0x43,0x71,0x8f,},{0xce,0x2e,0x7c,0x58,0x39,0xef,0x56,0x32,0xa1,0x23,0xdc,0x37,0x3d,0xc1,0x4b,0x1f,0x05,0x05,0x76,0x6e,0x96,0x75,0x40,0x76,0x04,0xca,0x7c,0xf5,0x4e,0x8d,0x44,0xb2,},{0x93,0xb6,0xe2,0x9d,0x63,0x94,0x5d,0x5c,0x42,0x73,0x87,0xd0,0x06,0xc7,0xf0,0xb0,0x19,0x56,0xa9,0x5f,0xc0,0x43,0x6e,0xd4,0x2b,0x46,0xd0,0xf1,0x7b,0x5b,0xb1,0x93,0xea,0x8c,0x0e,0xbb,0xf3,0xd6,0xd1,0x3b,0xb5,0x39,0xe3,0x5c,0x91,0xf3,0xf0,0xf9,0xfa,0x34,0x14,0xa0,0x22,0x3c,0x90,0x60,0xba,0xc8,0x36,0x53,0xc6,0xfc,0xd9,0x06,},"\xfb\x3e\x82\xf1\x1b\xc2\x86\x26\x7e\x12\x38\x17\xad\x88\x64\xe0\x77\xd9\xf7\xa8\xe7\xa1\x63\xac\x7e\xea\xf9\x3d\x55\xdd\x11\x1d\xe8\x08\x3b\x66\xb5\x3c\xe7\xbc\x77\x1f\xc5\x07\x1a\x2d\x7a\xc2\xf8\x5d\x6f\xc6\xad\xcf\xce\xc4\x46\xe1\x6a\xa1\x04\x6d\xf3\x72\x09\xad\x7a\x29\xcf\x96\x65\xb4\x39\xa5\x4d\x6f\x8d\x94\x2f\x89\xbd\xaa\x56\xf2\xf1\x12\x60\xcc\x95\x99\x30\x38\xb0\xe8\xfb\xdb\x32\x14\xf1\x42\xe6\xc9\x0b\x61\xa1\xd2\xb1\x42\x07\x62\x06\xaf\x30\xac\x35\x78\x4a\x6d\xc1\x5a\x1e\x79\x25\x1a\x8c\x77\x31\xa1\xc5\x39\x78\x03\x8f\x8d\x76\xd7\x0c\x6c\x1c\xdf\x52\x9f\xbd\xb8\x4d\x15\x07\xdc\xff\xdd\x42\x87\x3d\xfa\x6a\x8f\xe6\xbd\x6f\x7f\xd2\x9c\x80\xe4\xb2\xf9\x33\xd2\xb6\xc9\xe6\x2c\x94\x57\xe6\x65\x47\x26\x55\x05\x9b\x63\xb6\x18\xe2\xa9\xa8\xe5\xb9\xe4\x1c\x36\x46\x17\x3a\x89\x2b\x8e\x6d\x4b\xca\xd6\xa6\x2a\x6f\xcc\xd3\x45\x58\x90\xb5\x8e\xc2\x68\x1a\x95\xcc\x97\x76\xa9\xfc\xe8\x3c\x54\xa9\xef\x31\x2a\x33\x19\x59\xc7\xef\x3f\x79\xee\x57\x6e\xb7\xb7\x94\x69\xc9\x23\x4b\x1e\xae\xf6\x09\x88\x47\x08\xfe\x4b\xb0\xef\xac\x66\x2d\xa8\x71\xba\x61\xdd\xab\xb3\xfc\xbd\xeb\x8f\x63\x56\x57\xdd\x9a\x5d\x73\x11\xe6\x39\xa8\x24\x85\x8b\x9a\x98\x68\xd3\xf9\x38\x4d\xa6\x12\xc7\xf2\xe7\x71\xa4\x6b\xd2\x62\x4c\x99\xea\x2b\x6c\xcb\xca\x99\x6c\x1d\x9c\x37\x55\x54\xf2\xa5\x51\x61\x9c\xe6\xd5\xe6\xe4\xd6\xb8\x44\xa4\xdb\xea\x83\xba\x73\x23\x31\xfc\xf4\x65\x72\xc1\xfb\x0e\x25\x7c\xe1\x04\x1b\x26\x5d\xf0\x2e\x69\x0a\x92\x81\x4b\xbf\x3b\x5e\xca\xc6\x9e\xe9\x98\x76\x6a\x02\xb0\xd2\xf9\x08\xb3\xc1\x5f\x95\x26\x99\x61\x6f\x2c\x07\xd5\x89\x19\x89\x89\xe6\x05\x6c\x16\x31\x9a\xab\x6c\xf8\x77\x19\x02\xc0\x78\x04\x6a\x88\xb2\x57\x0c\x13\xbc\x5e\xde\xba\x2e\xd1\xe3\xba\x13\x1d\xaf\x94\xe6\x89\x18\x62\xbb\x3d\xe7\xd1\x06\x3f\xe4\x05\x30\x7a\x5c\xd9\x75\x69\x3e\x9d\x58\xe1\x7c\x69\x0e\xee\xf4\xa2\x60\x3c\xaf\xc6\x8c\x2b"}, +{{0xe5,0x71,0x18,0x9b,0x5c,0xd9,0xe7,0x88,0x30,0x2d,0xe3,0x91,0x9d,0x85,0x0c,0x22,0x7d,0xcb,0xb6,0x15,0x02,0x2e,0x56,0x8b,0xda,0xeb,0x37,0xac,0x5b,0x29,0x39,0xc5,},{0xed,0xda,0x89,0x0f,0x42,0xdd,0x5f,0xbc,0x73,0x16,0xa5,0xfa,0xdf,0xbe,0xc3,0x85,0x56,0xf2,0x3f,0x51,0xb8,0xef,0xd2,0x62,0x54,0x37,0xf6,0xb5,0x06,0x9f,0x1e,0xe5,},{0x7f,0x79,0x7a,0x31,0x71,0x5d,0x7c,0x35,0x6f,0x8f,0x1f,0x78,0x37,0x00,0xaa,0x99,0x74,0xbb,0x93,0x6d,0x66,0x16,0x61,0xad,0x96,0x8c,0x7c,0xde,0x1a,0xc9,0xe7,0x67,0xbe,0x56,0xa2,0xdd,0x49,0xb9,0x23,0x0e,0x90,0x11,0x0c,0x67,0xc0,0xed,0x18,0x7c,0xb7,0xe7,0x5c,0x30,0x53,0xec,0xe8,0x44,0x98,0x4d,0x29,0x6f,0x0d,0x85,0xcb,0x07,},"\xb6\x2c\x86\x7a\xd6\x22\x74\x35\xbf\xa6\xda\xb8\x30\x68\x4e\x38\xd1\x96\xe1\xf8\x61\xaa\xde\x0f\xd6\xa7\x69\x9b\x6d\x60\x90\x1f\xef\xb2\xd7\x99\xc3\x5c\x6f\x3d\x8b\xb9\x4d\xee\xe8\x34\x40\x39\x81\x86\x6b\xab\x84\x94\x6a\xe9\x47\x6c\x75\xe9\xf1\xd3\x60\x2b\x42\xcb\x2d\xb4\x37\xbf\xf3\x3a\x77\x58\x22\xf0\xd6\xa2\x57\xd4\xb7\x54\x00\xeb\xa5\xb8\xab\xb3\x14\xb7\x1f\xc6\xb4\x6f\x8a\x34\xe8\x61\xa9\xa6\x2a\xbf\x33\xde\x84\x82\xf6\x3f\x9d\x71\x69\xe7\x73\xa2\xdc\xeb\xee\x03\x70\x5d\xac\x11\x7f\xd1\x49\x9b\x68\xe7\x41\x4f\x51\xff\x94\x37\xf2\x53\xa1\xd9\x90\x1e\xc3\xb0\xbb\xa8\x69\x65\xa1\x93\x83\x65\x54\x87\xb5\x80\x10\xf8\x04\x90\x9d\xe1\xff\xb2\x21\x2c\x02\x52\xdd\xd9\xbf\x2a\x56\xac\x46\xbd\x59\xc0\xc3\x4d\xd5\x9e\x46\x59\x8b\x6b\xab\xd4\xe5\xf3\xff\xfd\xe5\x5e\x48\xda\xb0\x39\x8c\x22\xaf\x9e\x26\xba\xdd\xf7\x72\x75\xe5\xf0\x17\xb3\x5a\x9b\x8f\x84\x35\xf9\x63\x19\x36\xb3\x91\xcb\x95\xd7\xad\xf3\x5d\x1d\x85\x45\xa0\xfd\x06\x64\x12\xd5\x08\x96\x7b\xbe\x9a\x20\x24\x5a\x26\x9e\x3b\xe2\x77\x71\x17\xe7\x5f\xba\xc1\x70\xdb\xa3\x52\xbe\x69\xb2\x54\xd3\x53\xb3\xb2\xcb\x3b\x7e\x21\xb7\x21\xaa\x9f\xe0\x44\xf8\x91\x6b\x4b\x2a\x6f\x8c\x28\xf8\xab\xe6\x6a\xc9\x2b\x91\x32\x3a\xc7\x3a\xfd\x93\xdf\xbe\xea\xee\xf2\x6d\x19\xbd\x9f\x67\xe9\x9d\x48\xcd\x2a\xd2\xd3\xe5\x5e\x45\xd2\x4d\x54\xb5\x0f\x44\xa3\x9b\x90\xe2\x42\xeb\xe9\xb4\x2b\xeb\xdb\x23\x0c\x47\x0b\xdf\xde\x1b\xc7\x72\x1c\x31\x20\x00\x84\x77\x39\x3d\xcc\x2e\x15\xfd\x22\xb2\x51\xfe\xb0\xe1\x8b\x02\x88\x3c\x07\x8a\xee\x4f\xb7\x60\x65\x5a\x67\x1d\xc7\xb8\xaa\xdb\x9a\x56\x24\x20\xa3\xc2\xef\xa2\xd3\x42\xe1\xe0\x09\x9d\x95\x1b\x42\x24\x29\x84\xf5\x94\xe6\x91\x4f\xe2\x82\xb1\xee\x12\x87\x35\x98\x4e\xf9\x3a\x66\x9e\x6e\xcb\xa2\x6c\x9f\xcb\x9f\x09\xf0\x92\x56\x64\x56\x17\xf1\x39\x2d\x35\x90\x89\x17\xcb\x8d\x29\xe0\x89\x7c\x75\x03\xcd\xdd\x5d\xe1\x95\x96\x86"}, +{{0x37,0x17,0x44,0xab,0x63,0xc1,0x15,0x61,0x39,0x29,0xa3,0x43,0x70,0x9b,0xb0,0x19,0xb7,0x35,0x7d,0xff,0x72,0xd2,0xa1,0x49,0xf1,0xd0,0xf7,0x1d,0x3a,0x20,0x1e,0xfe,},{0xe5,0x8a,0xbf,0xad,0x4a,0x13,0x85,0x9f,0x0a,0xcb,0x05,0xd0,0xe4,0x7d,0x59,0x63,0x8f,0x7b,0x1b,0x49,0x36,0x10,0x0b,0x98,0x8d,0x61,0xe6,0xe7,0x0e,0x22,0x66,0x7d,},{0x5e,0xae,0x4a,0xc7,0x2a,0xf0,0x17,0x4a,0xb2,0x56,0x52,0x7b,0x7c,0xd3,0x37,0xa0,0xe5,0x48,0x2e,0x61,0x5a,0xf0,0x68,0xdb,0x21,0xda,0xe3,0x5a,0x64,0x64,0x07,0x42,0x60,0x4d,0xf7,0x3f,0xd4,0xca,0x02,0xed,0x95,0x15,0xa5,0x60,0x8d,0x73,0x19,0x52,0x30,0xfa,0xdc,0xa7,0xb4,0x26,0xf0,0x2a,0x2f,0xbf,0xd0,0x20,0x61,0xaf,0x36,0x00,},"\xc2\x19\xde\x1e\x8d\x7a\xd8\xdf\x08\xc4\x93\x77\x39\x6f\xe7\xc1\xf2\xd5\x7b\xd2\x17\x06\x33\xa0\x0d\x70\x8f\xaa\xde\xe1\x80\xce\xba\x92\x84\x9a\x77\x78\x50\x6c\xbb\x36\x68\x75\xbf\x91\x24\x70\x18\x94\xce\xcd\xb3\x38\x51\x47\xd0\x67\x18\x43\x92\x2a\x64\x9a\xff\x7c\x43\x5e\xb5\xa9\xc7\x49\x27\x50\x30\x72\xd0\x06\x79\x78\x71\x6d\xc8\x0b\xe1\x54\x5a\x2d\xbf\x5a\x1c\x38\x53\x6e\x12\xbd\x77\x20\xc1\x96\x5d\x38\x03\xa4\xe8\xaa\x55\x76\x51\x92\xa1\x3b\x70\x5c\xa1\x05\x9d\xed\x0e\x80\x63\x62\xfc\x5b\xbe\x6c\x76\xa1\xc9\x67\x4b\xb8\x53\x79\x0f\x7e\x90\xaf\x00\x75\x3e\x00\x43\x6d\xa4\x8c\xd0\x82\xea\xd6\x4f\xdd\xb6\x89\x89\x01\x62\x08\x2f\x84\x82\x92\x4f\x33\xac\xd6\x04\x64\x0f\x69\x92\x73\x52\xb4\x3f\x64\x40\x2d\x27\xa8\x83\xfa\x6b\x72\xaa\x70\xd2\x41\xdf\xfa\xa1\x70\x1a\x25\xcf\x10\x79\x35\x82\x60\x79\x38\x75\xf7\x6a\x29\x78\xe9\xf9\xf9\xd6\x86\x34\xeb\x3f\x5f\x01\xbd\xe1\xce\x49\xe5\x92\x12\x52\xf9\x49\xf0\x82\x79\x5e\x4e\xaf\xed\x7b\xe5\xb4\x9a\x9f\x95\xed\xbb\x4a\x13\x53\x2e\x3f\x3b\x3b\xe6\x2e\x26\x52\x23\x12\x53\xa2\x0c\x1d\x54\x77\xe8\xf4\xbc\x57\xed\x76\xfa\x19\xea\xf0\x3a\x11\xbb\xa4\x29\xb6\x49\x6c\xe7\x62\x46\x17\x0e\x04\x3b\xc1\x4f\x2d\x2f\x70\x3d\x96\x8f\x1d\xeb\x09\x38\x87\x15\xc3\x7c\xb4\x75\x2d\xa8\xd4\x64\xe3\x48\xe0\x31\x3c\x89\x93\xe2\x41\x33\xa7\xc5\x45\x28\x4e\x3c\x9c\x90\x7d\x01\xb2\x60\xc4\x88\x3f\x9c\xb3\xe3\xdc\x5b\x6f\x7f\xb6\xd7\x55\x36\x36\x5f\x21\x32\xea\xed\xda\xb5\x70\xe7\x27\x3a\xfa\xc0\xbf\xf5\xc9\xfc\x0b\x82\x0f\x20\x78\xe0\x33\x60\x52\xe1\xfe\x7b\xde\xc8\x66\x74\xd0\x99\x8e\xc7\x8d\xa1\xc3\xf3\x47\x51\xf8\x86\x72\x76\x95\xf3\x5e\xca\x13\x04\xb1\x47\x34\x76\x6a\xb0\x5c\x11\x86\x30\x6d\xed\x9d\xb3\xee\xf6\x5d\x3c\x04\x56\xcd\xae\x81\x81\xaf\xee\x04\xb2\x96\xc6\x72\x2a\x88\xc7\xef\x30\x88\xd2\x6f\x7f\xe7\x4b\xc8\x9c\xf5\x28\x5c\x68\x8f\x02\x7b\x7e\x68\x60\x04\x86\xaf"}, +{{0x49,0x8b,0x6e,0xe6,0x49,0x2d,0x53,0x23,0x1b,0x35,0x32,0xd1,0x93,0x57,0x8b,0xa7,0x5d,0x6a,0x89,0x4e,0x2e,0x53,0x00,0x34,0xe2,0x1a,0xb8,0xad,0x8d,0x2c,0x0d,0x1f,},{0xd1,0x24,0x66,0x5b,0x28,0xfa,0xcd,0x2d,0x17,0x94,0x6a,0x04,0xdf,0xe3,0xd1,0x29,0xa4,0x56,0x1a,0x2b,0x24,0xeb,0x32,0x6d,0x84,0xb6,0x2b,0x42,0x2e,0x44,0xdb,0xcf,},{0x11,0x2f,0x5c,0x6d,0x3b,0xcb,0x3d,0xd9,0x93,0x46,0xd3,0x2a,0xd6,0x9c,0xbf,0xac,0x3e,0x65,0x3b,0xef,0x29,0xc6,0x8a,0x33,0xf4,0x32,0x31,0xf6,0x6c,0xea,0x1d,0x0a,0x19,0x54,0x27,0xd6,0xe1,0x0c,0x0e,0x77,0xc5,0xd5,0x5f,0xe2,0x79,0x42,0x87,0xee,0x32,0xe5,0xe2,0x2b,0xaf,0xbb,0xd8,0x05,0x2a,0xd3,0x60,0x6b,0x90,0xf9,0x45,0x05,},"\x04\x98\xa5\x9b\x87\xcd\xae\x28\x69\x55\x47\xe1\x08\x63\xbc\xe8\x04\xd9\x7d\xe0\xac\x80\x08\xf3\xd5\xfb\x65\x2c\x17\x57\x41\x9f\xdc\x9e\x0f\x97\x36\xf4\xc5\x9a\x34\xf2\x1c\xfc\x74\x59\x9f\xa7\x88\xfc\xc1\x0c\x67\x30\xc7\xdf\x8c\x3d\x2c\x1b\x6a\x78\x6d\x12\x30\xb6\x55\x85\x71\x9d\x1c\xb5\xc4\x90\x35\x9b\x94\x43\x5d\x6d\xd6\x71\xf5\x4d\x6e\x9a\x19\xb9\xb5\xaa\xad\x7e\x0f\x23\x3f\x87\x97\xdf\x99\x78\x28\xd8\x8c\xd9\x2e\xf0\x89\xef\x7d\xbf\x1e\x95\x27\x78\x94\xa2\xf7\xc2\xfd\x0c\x8e\x4d\xfd\xfa\x6d\x3d\x14\x58\x9f\xf0\x19\x16\xdb\xf9\xdd\xd8\x11\xc2\xf5\xe0\x1e\x94\x29\x89\x90\xa1\x45\xa6\xcf\xc2\x68\x95\x61\x4c\x7c\x96\x3f\xef\x30\x8a\x4e\x38\x56\xc3\x2d\xd3\xe3\x59\xbc\x56\xd2\xcc\xa4\x96\xad\x19\x9f\xf1\xa5\x68\xd6\x43\x0a\xc5\xcd\x20\x8e\x0e\x2d\x07\x80\x3c\xa5\x23\xe0\xd8\x13\xad\x37\x33\xab\x50\xbd\xca\xdc\xb9\x88\xae\xe7\x58\xea\x50\x43\x9b\xf3\x8e\xe6\x49\x99\x76\x04\xf1\x51\xc6\x02\xc8\x29\x00\xa8\x20\x5d\x8f\x6f\x67\x0c\x86\x84\xbf\x5a\xbb\x5f\x75\xff\x29\xa3\x7e\xb9\xbf\x81\x05\x19\x9f\xbb\xfb\x47\x07\xe1\x62\xe6\x4c\x71\x52\x70\xf8\x53\xe6\x48\xb0\xaa\x26\xfe\xa0\xf6\xdb\x56\x28\x96\xbf\x42\x4a\x9f\xfc\xb2\x92\xfa\xe8\x5b\x76\xce\xfb\x8b\xd5\xa4\xb3\xce\x1f\xb3\x9b\xd2\xa5\x0d\x0c\x9e\x6d\x93\x3e\x16\x7f\xf6\x29\xb8\xa4\x94\xf2\xa9\xb7\x74\xeb\x30\x3c\x78\x1e\xa0\x2a\xff\x1a\x8a\xfa\xdc\x24\x65\xcc\x61\x69\x68\x01\x5e\xd6\xa5\xa3\x3c\x31\x20\xb9\x45\xed\x53\x51\x98\x1e\x32\xfb\x9f\xb9\x6b\x22\x12\xdc\xf8\xfe\x9a\xc5\x6e\x3c\xf4\x1d\xc5\x24\xf8\x00\x63\x10\x20\xb0\x25\x91\x91\x78\xce\x07\x4e\xef\x07\x8d\x68\x42\x01\x2a\x27\x6e\xfa\x62\x8d\xb5\x40\x58\xd1\xeb\x5b\x5b\x70\x5f\x1e\x18\x18\xd2\xdf\x51\x64\xba\xab\xb0\xc6\x19\x56\xec\xdb\x8c\x70\x6e\x56\x2f\xc4\xfd\x64\x05\x28\x70\x53\x0a\xe4\x25\xb2\x21\xf8\x9d\xd6\xf9\x0d\xab\x88\x2e\x76\x3e\x7a\x7f\xfa\x14\x1b\xba\xa8\xbf\x7a\x3f\x21\xb0"}, +{{0xce,0xfc,0xfc,0xd1,0xcf,0xf4,0xd8,0x91,0x07,0x49,0x27,0x91,0x31,0x83,0x0b,0x1d,0xa1,0x9d,0xfc,0x52,0x45,0xf7,0x8c,0xa6,0x8b,0x8c,0x3c,0x1b,0x62,0x2b,0x45,0x51,},{0x1d,0x39,0x4a,0xbd,0x1b,0x4e,0xd1,0xae,0xdf,0x96,0x6a,0x60,0xef,0xd3,0xff,0x88,0x21,0x40,0xa7,0xe5,0x6b,0x42,0x83,0x74,0xec,0xb4,0x43,0x28,0x9a,0x9c,0x7f,0x00,},{0x7d,0x83,0xff,0x66,0xec,0x79,0x30,0x7b,0x1c,0x0c,0x09,0x3f,0xda,0x39,0x68,0xa9,0x6c,0xf6,0x04,0x4f,0x5c,0x80,0x28,0x88,0x58,0x40,0x18,0x84,0x5e,0x7c,0xaf,0x2a,0x13,0x5a,0xc6,0xf1,0x67,0x7e,0x84,0xd2,0x2e,0x45,0x8e,0x22,0x7e,0x4f,0x93,0x02,0x09,0x91,0x9b,0xc1,0x1b,0x12,0xf7,0xaa,0xf2,0xb8,0xc9,0x43,0x02,0xd6,0x42,0x00,},"\x5e\xc9\x4e\xd0\x6f\xc1\x25\x7a\xe9\xc1\x83\xce\x56\x27\x12\x07\xac\xa3\x7a\x23\xfd\xb4\xb0\xe7\x4a\xc9\x30\x7a\x1b\xb1\x12\xe0\x5e\xd5\xa5\xd0\x47\xc9\x31\x09\xe2\xe5\x94\x77\xb0\x33\x78\x34\x64\x22\xde\x36\x71\x4c\x29\x61\xbb\x97\x36\xa5\x13\xca\x36\x71\xc6\x03\xa6\x8c\x2b\xe7\x31\x7b\x1b\x52\xa0\x76\xda\xe2\xaf\xf7\xbc\x88\xcd\x5e\xea\x0a\xa2\x68\xfa\xaa\xda\xe5\x39\xc9\x38\xbb\x4f\xd4\xb6\x06\x9b\x19\x45\xeb\x6a\xf0\xc9\xe6\xc8\xaa\x5e\xe4\xa4\xaf\x37\xe9\x0c\x67\xe2\x48\xe8\xd2\x7b\xd7\xf9\x58\x9c\x4d\x30\xe9\x05\x65\x1b\xaf\x45\x36\x4f\xa0\x49\x95\x7e\xa5\xd9\xb7\x14\x6c\xa6\x82\x04\xe5\xe9\x73\xd0\xf1\xc9\x1a\x1c\x4b\xde\xd6\x61\x15\x02\x8a\x71\x11\x4f\x0f\x4f\x85\x1b\xd1\x15\xfa\xeb\x95\x4e\x3f\x71\xa0\x14\x70\xb2\x48\x1a\x00\x98\xd9\x9f\x9d\x74\x89\x8c\x8b\xa0\x28\x7c\xc7\x83\x41\x55\x21\x41\x73\xd1\xfc\xba\xfc\xfe\x9b\x08\x25\x03\x84\x43\x94\x76\x05\x58\x83\x83\x38\x16\xc9\x52\x4c\xfd\x57\x44\xaa\xa2\x59\xdb\x7e\xbd\x3a\x6a\xa2\x0b\x5a\x65\x46\xda\xde\xfd\x14\x06\x68\xeb\x0e\xcc\xb5\xf6\x68\xdb\x9f\xc6\x29\x83\xdf\x98\x08\x50\xc9\xd1\x98\x82\xa1\x75\x50\xd5\xdc\xa3\x54\x2c\xd3\x60\x03\xa0\xd0\x3c\xff\xb0\x45\x75\xa3\xe8\xe1\xd0\x70\x15\xc7\xb3\x0e\xca\x91\x15\xcd\x2b\x72\xe4\x6d\xfd\xdf\x6a\x4d\xda\x1f\xaa\x2d\xbd\xc8\x90\x00\xd4\x33\xf6\xec\x9a\xdc\x46\x14\x6d\x93\x9f\x32\x12\x1b\x99\xb2\x89\x83\xd9\x8b\x9d\xde\x8c\x3f\x6e\x57\x79\xf2\xb0\x70\x0c\xb0\x23\xdb\x13\xde\x65\x6e\x0a\xed\x1d\xa2\xd5\xc6\xba\x26\x52\x34\x36\x48\xad\x42\x0f\x6a\xb9\xe5\x5a\x97\x48\x2a\x1a\x22\xb3\xbc\x2e\xe5\x98\x62\x9a\xba\xd9\x54\x7e\xdb\x5f\xf7\x90\x99\x05\x64\xbd\x87\x1f\x81\xb2\x4b\x12\xf2\xbf\x8d\xbd\xfe\x7a\x88\x37\x5f\xad\x9c\xcb\xd9\xfc\x0b\xa1\xd3\xbb\xa5\xe3\xc4\x81\x3c\x18\xa0\x34\x8a\xad\x83\xfb\x1b\x82\x68\x90\x54\xd9\x9b\x46\x00\xdd\x17\x60\xd0\xdc\xce\x44\x75\x74\x67\xbe\xc1\x94\x64\x06\xd5\x30"}, +{{0xd1,0x07,0xcf,0x26,0xf5,0x27,0xdb,0x71,0xa2,0x06,0xe4,0x1d,0x17,0x95,0x53,0x21,0x01,0x32,0x25,0xbb,0x20,0xf9,0x3e,0x12,0xdf,0x3d,0xc7,0x39,0x9e,0x72,0x0c,0xa3,},{0x18,0x6b,0xf4,0x53,0xc9,0x5d,0xc0,0xa2,0xfd,0x58,0x9a,0x78,0xe2,0xc8,0x00,0x40,0xb3,0xf6,0xdd,0xf9,0xa6,0xf8,0x68,0x1d,0x14,0x60,0x36,0xcf,0x21,0x46,0xe8,0xfc,},{0x80,0x71,0xd9,0x7f,0x32,0x4f,0x10,0x35,0x8f,0x13,0xac,0x8c,0x61,0xd4,0x24,0xb4,0xf3,0x00,0xdd,0x04,0x19,0x57,0x1c,0x39,0xe4,0x0d,0x99,0xae,0xa5,0xf0,0x31,0x40,0xe6,0x2a,0xb4,0xc9,0x71,0x27,0xab,0x33,0xe9,0x82,0x69,0x96,0x6a,0xe1,0xd4,0x55,0x7e,0x45,0x9b,0xf7,0xf5,0x97,0xb3,0x13,0xf3,0x51,0xa2,0x01,0x22,0xf0,0x66,0x0e,},"\x78\xeb\x9e\x13\x78\x99\x28\xa7\x4f\x36\x01\x41\x72\x8e\xde\x98\x38\x96\x85\xc8\x36\xb9\x1f\xaf\xbf\x1a\x7e\x8c\x19\xcf\xbe\x21\xbd\x3c\x3d\x6c\x6e\xd8\x3c\x40\x9e\xf6\x93\xf1\xd7\x35\xda\x3f\xa4\x66\x49\x7e\x19\xf3\x8e\x30\xfb\xa2\xa1\x02\x37\x85\x45\x90\x70\xe6\xe9\x2c\x1c\xb7\xc9\xbd\x0c\x9b\xa6\x12\x20\x15\x78\x66\xc3\xbe\xd2\xb0\x1e\x6e\x6b\x9b\x8d\xd3\xf0\xc4\x7c\x02\xf1\x81\x34\x6a\x0a\x9b\x9b\x5d\x3d\x7e\x18\xa9\x4d\x69\x56\x85\x5e\x16\xe8\xea\xaa\xab\x71\xb1\x03\x02\xf3\x5b\xd8\xfb\x1f\x9b\x58\x47\x30\x41\x60\x32\x49\x26\x64\x5b\x05\x82\xc2\xf2\xf1\x53\x3a\x24\x28\x14\x61\x51\x42\x41\xdb\x28\x50\xef\x31\xc5\x76\x3b\x2e\x3d\x4f\xb1\x8f\xc6\xd8\xc1\xd7\xe5\x2f\x7c\x13\x39\x2c\x17\xe2\x70\x19\xff\x60\x00\x8e\x43\x1f\x17\x14\x37\x0b\xc0\xef\xd9\x45\x2a\x61\xf5\xc5\x64\x88\xd9\x1a\x18\x50\x37\xf1\xf6\x47\xf7\x2f\xa7\x85\x01\x0d\x5d\x78\xf0\xa1\x15\x87\xcc\xf6\x6b\x80\x88\xe0\xe6\x35\xff\xf3\x77\x41\x93\xb2\xed\xef\xfd\x92\xd6\xe8\xa0\x32\x11\x28\xae\x64\xcd\xb8\x62\xe6\x31\xe2\xee\x5b\xa0\xda\x44\xbb\xd5\x89\xdc\x39\x2b\x5a\x11\x3b\x86\xa7\x27\xa8\xdd\xb6\x98\xa3\x34\xcc\x66\x8b\x39\xb1\xcd\xe1\x99\xb8\x88\x37\xca\x5f\x00\xf5\x53\xf8\x9c\x62\x28\x34\x27\x36\x41\xd3\x9b\xc1\x0c\x6a\x24\xe1\xeb\x42\x58\x75\x42\xf0\x3f\xc1\x62\x75\x24\xed\x6b\x74\x93\x91\xf1\x10\x28\x70\x6c\x42\x36\x44\x25\xb2\xca\xf2\x01\x80\xe1\xb8\x02\xc7\x44\xb4\x9b\x7b\xcd\x9b\xf7\xb1\x5c\x23\xa0\xbf\x1c\x69\x65\x96\x0d\x34\x15\x54\xe1\x96\x6b\x6e\xf8\x2f\xcf\xbb\xe4\x1d\x1e\x09\xd7\x41\xe3\x09\x25\x44\x46\x77\x7f\x13\xc2\x9a\x67\xb8\xbd\xeb\xc5\xf7\xf0\x4d\x16\x0d\x60\xe3\x32\xe3\xd0\x44\x1a\x0f\x2f\x7b\x19\x2c\x3e\x2b\xdf\x6d\xad\xec\x2a\x42\x4f\x88\x66\x98\x06\x23\x6e\xe0\x4d\xea\x69\x2b\xd8\xbb\x6f\x91\xca\x06\x82\xec\xe3\x49\x14\x25\x75\x35\x8b\x9b\x7b\xe7\x06\x00\xb3\xcb\x81\xe1\x45\x6b\xa0\x79\x9f\xdc\x01\xff\xd6\x86\x23"}, +{{0xaf,0x7e,0xa8,0xe4,0x1c,0x89,0x37,0xa4,0xec,0x47,0x5a,0xd8,0x13,0x71,0xa1,0x71,0xd3,0xd0,0xf9,0xfd,0x75,0x19,0xa0,0x4c,0x75,0x1e,0xd4,0xad,0x8f,0xf8,0xfe,0xf9,},{0x15,0xdf,0xc7,0x15,0x85,0xba,0xc7,0x1e,0xf2,0x0f,0x37,0x49,0x87,0xc5,0x55,0xa3,0xf2,0xf0,0x7d,0x6b,0x9c,0x78,0x70,0x66,0xc1,0x0d,0x63,0xcf,0x06,0xe0,0x2a,0xb0,},{0xc0,0xf1,0x73,0x91,0x67,0x27,0x4b,0xf9,0x18,0x31,0xc7,0x4b,0xeb,0x64,0x5a,0xf7,0x90,0x45,0x9b,0x28,0xbb,0x3f,0x21,0x32,0x53,0x65,0x13,0x0f,0x40,0x9a,0xcb,0x66,0xdf,0x1d,0x22,0x37,0x59,0xa9,0x75,0x8e,0x08,0xfd,0x72,0x53,0x73,0x74,0x84,0xe2,0x85,0xa6,0xfb,0x47,0x40,0x4a,0xbe,0x2e,0xba,0x5e,0xf2,0x49,0xfd,0x02,0x5c,0x0a,},"\x05\xf2\x26\x3f\x02\x45\xec\xb9\xfa\xeb\x14\xe5\x7a\xca\x43\x66\x68\x30\x8c\x81\x25\xdf\x31\x16\xc4\xee\x20\x50\x1d\x0c\xde\x70\x1b\x36\x6e\x2b\x50\xa1\xc5\xed\xf4\x84\x14\x4c\xe1\x6b\xfb\x1f\x7d\x26\xdc\x42\x75\xea\x97\x32\xe2\x64\xba\x4d\x4a\x36\x2b\x40\x27\x5b\xa4\x73\x77\xdb\xc3\x32\xcb\x65\xe2\xf4\xc8\x85\x38\x94\xaa\x87\x8a\x4c\x17\x5d\xc5\xb3\xb2\xa7\x57\xff\x3c\x8d\x7d\xe6\x60\x97\x3b\x89\xda\xdf\x07\x6e\x2e\x4f\xc7\x62\x39\xb7\xbc\x75\x2a\x22\x9d\x44\xe0\x00\xce\xb6\x67\x10\x4c\xb0\x74\x6b\xfc\xf5\x9d\x69\x60\x3a\xe7\xfc\x1b\xcf\x11\xd2\xe3\x3f\x61\xdc\x49\x7e\xc1\xb0\xbd\x5e\x4f\x1d\xbe\xf4\x35\xf2\xf2\x91\xf3\x0b\x00\xa8\x5e\x83\x39\x46\xc8\xb1\x04\x84\xe4\xab\xd7\xd6\x0b\xdb\xb1\xfe\x6d\xff\x58\x07\xa5\x3b\xb8\x93\x82\x15\x30\x13\xb7\x0c\xa0\x8e\xfc\x91\xb7\xe9\xfc\x5b\x5d\xbb\xb6\xaf\x12\x3b\x57\xbe\x2e\x14\x0f\xc4\x71\xa4\x5d\x89\xfa\x82\x84\xcc\x27\xe0\xa1\xfe\x77\x1f\x55\x59\x8b\xbd\xcf\x06\x8d\x50\x6d\xad\x0a\x59\x21\x79\xce\xca\x39\xee\x95\x26\xf9\xe4\xfe\x47\xbf\x2b\xb1\x4f\xb1\x48\x6a\x67\x7d\x4d\x7b\x99\xa5\x20\x54\x56\x76\xa0\xf1\xfa\x80\x90\x49\xaa\x24\x14\xae\x7b\x81\x7d\x9a\x03\x6e\x5c\x15\x78\x86\xe8\x34\x1d\x4e\x81\x9c\x09\x2a\x3b\x48\xb3\x60\x6b\x03\xac\xb7\x27\xc6\xc2\x21\x7d\x0a\xf3\x01\x21\x54\x6a\x94\xaf\x6b\x49\xca\xa2\xa8\xc9\xb1\x78\x6f\xa0\xc2\xa5\x24\xec\x7a\x02\x3e\x92\x4b\x5f\x8a\x89\xa5\x37\x80\xc7\xf8\x78\x1c\x5b\x8e\x86\x94\x30\xca\xa0\xe6\xd0\x43\x79\x67\xe3\xae\xd4\x4f\x45\xc9\x01\xcb\xcf\x10\x26\xfb\xbd\x4e\x3d\xd9\xa0\x91\xec\xf8\xb3\x4f\x7d\xd5\x03\x8e\x54\x3d\xc7\xeb\x6a\xd5\x49\x4e\xfb\x14\x5c\xf6\x3e\xc0\xd3\x55\xbb\x8e\x17\x2f\x45\x5d\x8a\x6b\x13\xda\xca\xad\xdb\xc5\x6e\x47\xde\x3c\xf7\x62\xa1\xa7\x38\xef\x09\x2f\x14\x36\x68\x04\x67\xb5\xcd\x82\xe9\xe3\x6e\x2d\x2b\x68\x42\xb3\xbd\x5d\xce\x77\x18\x0d\xda\xf0\xb6\x43\x37\x8e\x69\x85\x99\xdd\x47\xf5\xcd\xbb"}, +{{0x0c,0x57,0xcb,0xfc,0xeb,0xde,0x10,0xed,0xe0,0x2d,0x1c,0xb0,0x1d,0xf3,0x60,0xd4,0x1f,0x2e,0x66,0xa5,0x04,0x43,0xd5,0x8b,0x5d,0x4f,0x08,0x28,0xc9,0xa1,0x8b,0xb7,},{0xc4,0xd7,0x61,0xba,0x18,0x99,0x71,0xb9,0x46,0x2c,0x61,0xbf,0x46,0xa7,0x65,0xf8,0x8e,0x2e,0xca,0xa5,0xbf,0x22,0x11,0x22,0x0a,0xfb,0x00,0xac,0x65,0x7f,0x7c,0xe5,},{0x8a,0xf7,0xbb,0xe0,0x1b,0x8a,0xb9,0x39,0x51,0xd1,0x6f,0xca,0x05,0xa9,0xc9,0x67,0xd1,0xc5,0x2c,0x97,0x4b,0xea,0x15,0x1e,0xa7,0x2e,0x4c,0xeb,0xaa,0x20,0xcc,0x78,0x3b,0xb6,0x1d,0x8d,0x69,0x38,0x5c,0xac,0x5b,0xc6,0xd7,0x2d,0xbd,0x16,0x2b,0xee,0xf1,0xfc,0xb5,0xdd,0x0e,0x0a,0x08,0xb4,0x8c,0xa0,0xb9,0xf6,0xd9,0xa9,0x88,0x0c,},"\x33\x77\x03\x24\x3a\xb5\xb4\xe4\xd3\x48\x1e\xe8\xdd\x1f\x44\x94\x50\x71\x74\x41\x26\x58\xa9\x39\x88\xb5\xc3\x04\x03\xa7\xb7\xed\x85\x22\xce\xb4\x6f\xa1\xee\x02\x75\x3a\x87\x4e\xf0\x67\x5d\x39\x7c\x57\x5d\xa0\xb0\x8c\xaa\x8c\xee\x33\x93\x78\x4d\x0f\x0d\xb8\x45\x98\x37\xaf\x90\xb9\x05\x6d\xf4\xe3\x8e\x41\x7f\x3a\xd2\xeb\x1a\x10\x0e\xf2\x07\xce\x2c\xa6\xc6\x10\x01\x80\x21\x66\x1e\x30\x70\x99\xf2\xb7\xc4\xae\x87\x59\x91\x14\x0b\xdd\x3f\x0f\x99\xad\x2c\x5d\x55\xaa\xcb\x84\xcc\x1c\xdc\xd5\x79\xe0\x80\x72\xb6\x95\x1f\xd4\x5e\xd2\x89\xac\x9f\xf7\xf0\x98\x6a\xc8\x8a\x4f\xbb\x9d\xc9\x20\x3d\x9b\xaf\x18\x0c\x90\xed\xf9\x37\x25\x8c\x9d\x0a\x6d\x48\xe2\x20\xf7\x2d\x25\x0c\x7f\x2c\x77\x7e\xaa\x7f\xb9\xfa\x11\xd5\x0a\x57\x98\x77\x2f\x9f\xd9\x76\xb0\x05\x99\xf1\xf0\x27\x6f\x3a\x2e\x4d\x98\x8a\xe9\x21\x25\x46\x7a\x8d\xed\xb7\xa1\x6f\x9e\x3a\x56\xe8\xd0\x06\x62\xb3\xeb\x67\xa3\x5b\x9b\x60\xe7\x3b\xd9\x35\x07\x7e\xe2\x38\xdf\x8f\x6e\x83\x3b\x9a\x55\x23\x38\x68\x26\xc1\xf2\x91\x7b\x1c\x3e\xc9\x8e\x0a\x5f\xde\x89\xc4\x8b\x1d\x44\x6d\xa5\xd0\xc8\x85\xfe\xf0\xe3\x74\xbf\xf3\x0a\x99\x7c\x7b\xaf\xd5\xe7\x43\xc8\x5d\x0c\x6a\xaa\x6e\xf1\x0a\x06\x12\x11\xa2\x32\x7c\x6d\x84\xeb\x74\x7a\x56\xe9\xbf\x60\xfc\xd5\xb5\x53\xb7\x98\x83\x4d\x0c\x5c\xca\xdb\x9d\x4b\x54\xe7\x23\x7d\x12\xc6\x79\xc1\x93\xa2\x87\xbb\x2f\x51\x1c\xd4\xee\x2a\x2d\x85\x49\xb4\x4b\x21\xc1\x1f\xbe\x57\x23\x38\x1c\x6c\x5f\x78\x46\x87\xfd\x90\xce\xbc\x5b\x49\x5a\xf9\xe4\x14\xf2\x96\x1b\x06\xa1\xc8\x43\x3b\x9a\xa3\x29\x2b\xcf\xf4\x24\x1c\x22\x71\x67\xf8\xd1\xde\x05\x4b\xa3\x3a\xd8\x1d\xa3\xeb\x3e\xc6\xe4\x0a\x6e\x26\x85\x4a\xf3\x49\x54\x01\x71\xb7\x5d\x75\xfb\x9a\x8d\x12\x93\x78\x27\xfd\x59\x4d\x31\x7b\x7a\x8d\x9f\x1c\x2f\xca\xbd\xa5\x63\x75\x56\x8c\x3e\x9e\x51\x4c\x2e\xff\xfc\x38\x78\x36\x3d\xcf\xad\x9f\xd9\x54\x36\xb0\x22\xe8\x77\x2a\x88\xcb\x71\xe8\x03\xbf\x90\x38\x19\x62"}, +{{0xfe,0x71,0x72,0x27,0x83,0x64,0x19,0x4b,0xcf,0xef,0xb4,0x78,0x31,0x42,0xb7,0x9f,0x59,0xd5,0xfd,0x97,0x8b,0x1e,0x47,0xc3,0x14,0xd7,0x8d,0x4c,0xb3,0xf6,0x1c,0x8a,},{0x2e,0x82,0xcc,0xe4,0x79,0x10,0xc7,0xe2,0xa7,0x9b,0xc1,0xf4,0x19,0xdc,0x3c,0x3d,0xf5,0x4f,0x23,0x29,0x1f,0xc8,0x19,0x3e,0x82,0x58,0xcc,0xd2,0xfd,0x38,0xd5,0x48,},{0xf6,0xc2,0xa4,0x29,0x6b,0x9a,0x34,0x07,0xc6,0xd7,0xa5,0x67,0x9d,0xae,0x86,0x66,0xb5,0x03,0xd1,0xa1,0x7e,0xac,0xf7,0x1d,0xf4,0x93,0x79,0x1b,0x8f,0xf0,0xc0,0xaa,0x8e,0xed,0x36,0xb3,0x27,0xa2,0x9a,0xb7,0x82,0x8f,0x46,0xf2,0x2d,0xe8,0x68,0xb6,0x28,0xb1,0xcf,0xd5,0x01,0xe8,0x59,0x9f,0xa3,0x16,0x93,0xb1,0x5f,0x61,0x08,0x0f,},"\x23\x50\x94\x51\xa0\x59\x96\x9f\x2b\x4b\xdf\xce\xe5\x38\x89\x57\xe9\x45\x6d\x1f\xc0\xcd\x85\x7e\x4f\x4d\x3c\x25\xa4\x15\x5d\x5e\xe9\x1c\x20\x53\xd5\x58\x06\x2e\xea\x68\x27\x95\x0d\xe8\x63\xbc\x9c\x3d\xf9\x67\x2c\xde\x8b\xa7\x41\x74\x4e\xbb\xdd\xb4\x5e\xc1\xf4\x28\x45\x70\xfd\x0a\xac\xd0\x7e\xa5\x8c\x58\x1b\xe2\xaf\xc9\x5a\xe4\x44\xe6\x78\xed\xc2\xa0\x24\x39\xf3\x87\xce\xc9\x82\xea\x3a\x44\x81\x4a\x8a\x30\x2b\xb3\xbf\xe8\x22\x8d\x58\xde\x03\x9d\xeb\xdf\x7c\x2a\x7e\xdd\xb4\xe7\x1c\xa4\x74\xf9\x4f\x7e\x2b\xd8\x9d\xc6\x5b\x16\x10\x73\x3c\x91\xff\xf8\x9b\xd4\x99\xf4\x01\x54\xa6\x19\x8f\xdf\x5e\xc7\xad\x37\x22\xd9\x25\xb2\x92\x19\x6c\x42\x94\x99\x07\x5b\xe0\xc5\xb6\xda\x9c\x09\x0c\x07\x91\xa7\x01\x9e\xb5\xe7\x36\x6b\xe6\xce\x58\xab\x2f\x04\xfe\xcd\x91\x27\xc4\x27\x18\x04\x7b\xf4\x70\x30\x69\x15\x21\x31\x2c\x08\x77\xaa\x3f\x36\xcc\x5f\xbc\x9c\xaa\xe0\xfd\xe3\x94\x5d\x2a\x86\x8e\xe2\x50\x2a\x38\x33\x20\x8e\xb8\x50\xa1\x63\xcf\xcb\xf6\xda\x9e\xe6\xad\x9f\xe0\x67\xfe\x24\x19\x86\xfe\x44\x36\xd6\xae\x4e\xdc\x61\x56\x19\x38\xe2\xa3\x3f\x4a\x33\xdb\x63\xf6\x9d\x3f\x1a\x88\x50\xed\x40\x02\x88\x69\x16\x41\x03\x48\x8f\xb7\x95\xcd\x82\xca\x06\x7f\xe1\xb4\x89\x7c\xaa\x49\xa7\xca\x9a\x80\xf3\xa8\x15\x1f\xd1\x3b\xbb\x7f\xf3\x50\xe8\x57\x9f\x56\x5d\xc1\xc4\xa9\xca\x93\x8d\x27\xb1\x5b\x3f\x85\x8e\xf4\x5d\x3d\xd7\x8b\x2c\x35\x86\x35\x35\x63\x15\xf5\x5a\x97\x52\x8e\xcf\xec\x5d\x11\xa5\xb7\x21\x50\x31\x07\xfa\xa4\x06\xc1\x70\x34\xe6\x01\x47\x4b\x3b\x60\xcf\x48\x69\x2e\x26\x92\x61\x15\x8f\xc3\x53\xd4\xdf\x42\x74\x38\x13\x57\x79\x0b\x77\x56\x08\x7b\x00\xcc\x79\xe3\xb9\xd2\x8a\x3f\x24\x39\xfe\xbf\x19\x9e\x64\xa8\xb3\x7c\x91\xb5\xa4\x33\x4e\x33\x54\xe8\xfa\xf3\xa3\x61\xe8\x56\xc5\x4b\xda\xa4\x3b\xfd\xcd\x6e\xe6\xc9\xf9\x67\x95\x88\xf6\x06\x99\x50\x83\x23\x48\xaa\xcb\xa2\xbf\xee\xba\xca\xa2\x07\x1d\xdc\x7d\x77\x89\x8e\xf0\xf6\x87\x93\xcd\x25"}, +{{0xa9,0x51,0xe4,0xe6,0xba,0x9f,0x1f,0x0b,0x35,0x48,0x31,0xc9,0x86,0x94,0x24,0x48,0xfa,0xed,0xe3,0x7e,0x11,0xb0,0xf2,0x47,0xda,0x27,0x06,0xdc,0xee,0xf7,0x3a,0xc7,},{0x30,0x36,0x20,0x14,0x97,0x4b,0xf7,0x5c,0x84,0x95,0xc2,0xe2,0x71,0xe7,0x13,0xd5,0x73,0x84,0x38,0x4d,0x0a,0x5d,0xa8,0x8e,0xde,0xea,0x79,0x27,0x9c,0x0c,0x58,0xec,},{0x02,0x78,0xc8,0x6a,0x15,0x20,0x8d,0x9b,0xe5,0xb1,0xe1,0x57,0x47,0x61,0x86,0x1b,0x8a,0xf7,0x2a,0xe0,0x8d,0x40,0xcd,0xcb,0xec,0x35,0x4e,0x65,0xa9,0xc3,0xd0,0xa0,0x6b,0x5f,0xcb,0xb2,0x97,0xd0,0x9b,0xef,0x39,0x74,0x62,0x39,0x59,0x86,0xc3,0x09,0x3e,0xeb,0x22,0x64,0x4c,0x00,0x3c,0x30,0x78,0x17,0x8c,0xdf,0x67,0x4e,0x99,0x0a,},"\x20\x57\x7d\xca\xc8\x91\x74\x88\x5e\xed\xb0\x62\x48\x9c\xd5\x12\xfa\x72\x86\x3e\xc5\x43\x8e\x31\xe9\x58\x78\xb7\x5c\xe2\x77\x2a\xee\x62\x90\xa0\xba\x3c\x8f\x64\x2c\x1d\x0e\xf5\x5d\xa8\xd5\xbc\x14\x84\xf8\x3b\xb9\x87\x6c\x7a\x8c\x0b\x6b\x60\x9b\x94\xd1\x12\xa0\x6f\xc8\x3c\xe8\xd2\xc1\xe0\x8e\xd6\xc7\x35\xe5\x7b\x24\x4a\xad\x6e\xcf\x70\x75\x36\x3d\x56\x5b\xa4\x78\x65\x69\x5c\x84\x23\x51\x09\x09\xe0\xa3\xdb\x4b\x61\xed\x7a\xa6\x7a\x74\x71\x33\x1e\x83\xa0\xc5\x8b\x82\x20\xa6\x24\x5f\x65\x66\x15\x49\xc1\xa1\x2d\x4c\x0d\x50\xc3\x26\xfb\x94\x91\x7c\xbd\x07\xbe\x51\xe8\x3f\xe8\xbb\x3e\x46\xca\x01\xb0\xa2\x60\xda\xaf\x1d\x6a\xbe\x37\x03\xd6\xa9\x25\x11\x3b\xb4\xd5\x7e\xa1\xa4\x8b\x4c\x7d\xbd\xaa\x03\xee\xa8\x14\xa4\xb5\xf0\x2e\x1d\xfb\x54\x5c\xc6\x23\xfe\x17\xa3\xbb\x18\xe4\x37\x3f\x5f\x7e\xc2\xfb\x52\x17\xd2\x3e\x4f\xed\x54\xa7\x72\xe1\x13\x23\xe7\x30\xaa\xd7\xef\xca\x8c\x46\x44\x00\xe7\x67\x90\x55\xfc\xc1\x25\xa8\x76\xef\x7b\x8b\x9d\xe1\x86\xe2\x29\xa7\xab\xf1\x91\xd0\xc5\x6d\x91\x81\x5f\x67\x87\x2e\x95\x7b\xfb\xc7\x63\x4a\xac\x40\x35\x76\xa5\x8f\x42\x7b\xdb\xb3\x0e\x8c\x4b\x6f\xc6\xc4\x47\x74\x10\x24\xeb\xb5\x03\xa5\xa9\x02\x51\x24\xa4\x88\x7f\x82\x5a\x43\xee\x94\x0f\x21\x0a\x1b\xd5\xae\x4f\x67\x32\xd6\x0f\x95\xf2\xb8\x32\x01\xc4\xc6\xdf\xe2\x79\x41\x2d\x75\x02\xa5\x21\x1f\x8f\x48\xf8\x00\xdb\x30\xfc\x37\x76\xc4\xed\x3a\x38\xbb\x46\x34\x82\x2c\x98\xa6\xd6\xdd\x32\x33\xbe\x60\xe4\x2c\xca\x45\xa3\x16\x3c\xc8\x4e\x9e\x8d\xa6\x47\xc0\x71\x1b\xc4\xc6\xcc\xd6\x5a\xa1\xe9\x72\xc0\x74\x04\xd1\x03\xe7\x4b\xcc\x31\xa7\xe2\xc3\xee\xa5\xac\x92\x57\xab\x42\x89\x47\xab\x3d\xd3\xfb\x15\x3d\x90\x69\x4a\x40\x73\x37\x3c\x4d\xd9\xce\xb1\x31\x15\x4f\xe8\x77\x47\x3f\xd9\x96\xf4\x24\xf3\x3e\x31\x6e\x4e\xb0\x2b\x8c\x75\x13\xbe\x69\x98\xe5\x16\xcb\xba\x54\xd9\x4c\xd0\xa4\x35\xe0\xff\xcc\x2c\x0a\x8e\xf7\x2b\x63\x0e\xc2\x47\x81\x06\x6a\xa5\xef\xb9"}, +{{0x38,0xa9,0xb2,0xd4,0x9b,0xa8,0xb8,0x2f,0x30,0x1a,0x57,0x72,0xce,0xa0,0xef,0xc2,0x21,0x84,0x55,0xc8,0xb2,0x18,0xb2,0x2c,0xba,0xa2,0xaa,0xd2,0xd7,0xad,0x3b,0x35,},{0x9d,0xf5,0xea,0x1f,0x78,0xf8,0x10,0xa5,0x21,0x77,0x46,0x02,0xbb,0xba,0x49,0x42,0xf0,0x45,0x92,0x38,0x96,0x6c,0x8b,0xcd,0x21,0x90,0x0a,0xfb,0xf3,0xd8,0x42,0x93,},{0xe1,0x9e,0x62,0xac,0x53,0x9a,0x9c,0xa2,0x51,0xd1,0x2d,0x4c,0x71,0x05,0x5b,0x0a,0x3f,0x58,0x1d,0x19,0xf2,0x68,0x2e,0x67,0x24,0x04,0xc7,0x8a,0xc1,0xf1,0x2b,0xbe,0xfc,0x91,0x51,0x92,0x76,0xa5,0xcb,0xe1,0x6f,0x52,0x0c,0xf7,0xa7,0xf6,0x87,0xa2,0x40,0xf0,0x32,0x91,0x57,0xc5,0x9f,0x50,0x02,0x6a,0x58,0xdc,0xdc,0x50,0xfc,0x08,},"\x17\x78\x16\x7c\x49\xb3\xa4\x4d\x4a\x5b\xa8\x38\xb7\x38\x85\x53\xb1\xe1\x3d\x36\xea\x4f\x86\xd3\x02\x42\xe1\xa8\x22\xa3\xbb\xaf\xf5\xce\xa6\x3e\x2a\xe2\xa4\x63\x5b\xe2\x36\xfe\xf2\xb8\x13\x5d\x14\xfb\x62\x1c\x0b\xb7\x73\xc9\xc1\x77\x53\xf8\x09\x26\xeb\x55\xd0\xf1\x15\xbd\x09\xa8\x85\xd8\x44\xb8\x18\xc9\xf0\x44\x89\xa3\x31\xbb\x5e\x03\x2b\x8e\x58\xcd\xa3\x69\x49\xc5\xa8\xd0\x8b\x55\xbb\x8d\xe9\x65\xe1\xf9\x0d\x3b\x9c\xfe\xec\xfc\x6a\xd9\xa4\xee\x5c\xb4\x04\x7e\x94\x50\xac\xdc\x64\x64\x01\x66\xa8\xc0\x69\xea\x84\x9a\xeb\xdd\xac\x1a\xe4\xaf\xec\x91\xdd\xd1\x7f\xa5\x55\x3f\xa8\x7c\x56\xf7\xe5\x1e\xc1\xcd\x6b\x5c\xc2\x33\x51\xd0\x57\xa4\xce\x4a\x89\x23\xc8\xae\x6a\xc7\xa8\xaf\xdc\xc0\x88\x1c\x0e\x74\xeb\xb0\x24\xef\x72\x96\x16\x2c\xb9\x3c\x68\xe5\x0b\xbb\x07\x4e\x65\x1a\xc8\x7d\xac\x9e\xa5\x9d\x4c\x3f\xbf\x0f\xe3\x79\xf3\xe9\x7a\x24\x56\x6e\xca\xe5\x43\x03\xbc\xfb\x6f\x0c\xc9\xf1\x5f\x66\x39\x43\x0e\x66\xb1\x9a\x42\x78\x49\xfd\xff\xf8\x33\xdf\x02\x68\x9e\x9d\xe4\x40\x06\xc9\x03\xc5\x59\x18\x34\x59\xb9\xf4\xa9\x7f\x54\xa0\xf2\xa2\x8d\xf7\xb0\xe9\xde\xed\xa8\x23\x9d\x7b\x51\x69\x77\xf5\xe7\xd6\x97\x1b\x45\x02\xe9\x88\x5f\x75\x0a\xf8\xd1\xa6\x66\x9e\x25\xe7\x7d\x5f\x32\x7c\x77\xc8\x7a\x86\xe0\xa1\x87\x2b\xc9\x6a\x76\x06\x0f\x5f\x8a\x0c\x40\xcc\x97\x3b\xfc\x7f\xe6\xed\x9b\xca\x78\xf8\x84\xe6\xa2\x82\x8b\x94\xd4\x89\xd3\x2a\x0f\xd3\x37\xe6\x9d\xb8\x3f\xb8\x78\x9a\xfd\x4e\x8e\xf5\x4c\x22\xa7\x8c\x25\x87\x46\x8b\x9a\xe0\x71\xba\xe3\xb2\x02\xd3\x18\x3a\xd5\xf0\xf8\xe8\x42\xe5\xa8\xde\x85\xbf\xff\x49\xe0\x3c\x83\x81\xbc\xa7\xfd\x42\x78\xdd\xcc\xaf\x01\x34\xfb\x55\x93\xa3\x95\xa7\x7a\x5c\xbd\x43\x45\x93\xbc\x4a\xd0\xff\x4b\x84\x00\xec\x67\x4c\x4e\xca\xf1\xd5\x77\x54\xbe\x0c\xb2\xfa\x9a\x64\x41\xa9\xab\xad\x7b\x42\x19\x7a\xd8\x2e\x50\x82\x7e\x4a\x42\x45\x57\x3a\x8f\x0e\xf8\x7f\x58\x22\x8a\x28\x67\xf4\xb3\xb8\x34\xb6\x63\x50\x37\x94\x0a"}, +{{0x9a,0x17,0x17,0x87,0x36,0x89,0xa0,0x3c,0x11,0x2d,0xd6,0xb4,0xd7,0x6a,0xe7,0x3b,0x89,0xb4,0x16,0xa5,0x98,0xce,0xec,0x20,0x9e,0x27,0x96,0x1e,0x7b,0xb1,0xee,0x8a,},{0xee,0xca,0xd1,0xe0,0xe4,0xb8,0x63,0x29,0x18,0x81,0xa8,0xc2,0x41,0xdb,0x9c,0xcf,0xff,0xe4,0xe5,0x5d,0x8b,0x5a,0x42,0xf3,0x07,0xb4,0x43,0x6a,0xcd,0x06,0x49,0xa6,},{0x1a,0xf8,0xbe,0x09,0x55,0x38,0x96,0x58,0x00,0xd8,0xef,0xf6,0xd7,0x23,0xd0,0x28,0xd6,0x5d,0x0e,0x9c,0x6e,0xb5,0xe9,0xd1,0x25,0xbb,0x3b,0x17,0x83,0xf1,0x1e,0xf7,0x07,0x9a,0x49,0xa8,0x07,0xe2,0x7e,0xf1,0x26,0x0b,0xe2,0x6a,0x3b,0x23,0x1d,0x03,0xb2,0xae,0x15,0x1e,0x49,0xf6,0xf1,0x89,0xf1,0x5b,0x1c,0x83,0xea,0xb0,0x1c,0x02,},"\xe2\x65\x80\x47\x09\x01\xa0\x7a\xb0\x93\x1a\xa2\x38\x29\x80\x2c\xe0\x4d\xa5\x9f\xdc\x2f\x77\x3b\xc5\x67\xf1\xe6\x5b\x4f\x2e\x2d\x4a\x1a\x6a\xec\x1f\x54\x15\x8a\xdf\xce\x9b\x09\x97\x90\xb5\x03\xa1\x3d\x22\x09\x7a\xe2\x3e\xbc\xcf\x92\x3f\x3b\xb1\x98\x6d\x6e\x49\x11\x1a\x8c\xf0\xd4\xeb\x82\x36\xbf\xe0\xd7\xc9\xe9\x3a\x5e\xfc\x7f\xeb\x8e\x6a\x9c\xd1\xb8\xd9\x21\xef\xa2\x1e\x44\x9f\xf4\x9e\x06\xc1\xcc\xfe\xa3\x1f\x93\xe0\x33\xc3\xc2\xa5\x4d\xdb\x0f\x65\x3a\x09\xfb\xd1\x8a\x70\xb5\x63\x15\xf1\x93\xe7\xbe\x56\xe5\x16\x8f\x59\x56\x38\x21\xd4\xbc\x3b\xbb\x0e\xaa\x20\x48\x28\x6b\xbe\xee\x5a\xa3\xf3\xe7\x53\x6c\xf2\xb7\x50\xfd\x32\x26\x02\xbb\x38\x47\xce\xca\x39\xb7\x54\x74\x32\x2d\x76\xb1\xde\x80\xfa\x2e\xad\xba\x15\x2d\x6f\x8f\x02\x0d\x4d\x93\x1c\x53\xf0\xa2\x80\x12\x24\xd3\x5d\xeb\x6e\xc1\x3b\x01\x48\x73\xe6\x89\x90\x36\x07\xde\x96\xd9\xb7\xa7\x43\xa8\x87\xd2\xf4\x8d\xaf\x2e\xd2\xee\xfb\x20\x2a\xbf\x60\x82\x79\x69\x81\x12\x3b\x96\x6e\x93\x6d\xcf\x34\x83\xe2\xd2\x4d\x69\x4e\xcb\x86\x5f\xbe\xb6\x96\x9f\x34\x70\x27\xfb\x8b\x17\x5d\x24\xa4\xc0\x45\xc0\xbb\x4a\xb5\xe0\x2d\xdc\xbe\x77\xd4\x75\x6c\x46\xd1\x37\xb0\x94\x47\x3a\x02\x30\x7a\x10\x83\x40\xac\xad\x9d\x03\xba\xe8\x40\x3a\xf1\x99\xcb\x75\xca\xe3\x16\x2f\x38\x15\x81\x3c\xc6\x8b\xf2\xa5\xe4\x99\xe5\x94\x92\x11\x49\xf3\xbb\xd2\x14\xda\x51\x37\xe7\x56\x52\x15\x59\xdc\x80\xd9\xa4\xb7\x4a\x0f\x49\x43\x02\x2c\x7c\xd5\xfc\xa4\x23\x15\xe0\xbc\xee\xae\x90\x69\x61\x5c\xe6\x7a\x04\x38\x24\x12\x31\x3a\x31\xd6\x7b\x34\x6c\x32\x9a\xd8\x2e\x74\x2c\x0a\x6c\xe0\xa6\xa0\x24\x54\xc1\x13\xe5\x20\x22\xf3\xcc\x03\xfd\xa6\x91\xeb\xdf\xe1\x4c\x53\xc8\xce\x5c\xa9\xb9\x32\xca\x1a\x38\x6e\x3e\xb4\xe9\x0a\x4d\xc6\xe8\xad\x85\x33\xb5\xaf\x1a\xae\xf5\x00\x31\x28\x65\x5c\xa6\x4f\x67\xfc\xd9\x7c\x6a\xc8\x03\x00\x24\x04\x90\x0b\xc0\xfa\xe9\x84\x63\xbc\xc3\x14\x09\xf9\x98\x17\x48\x78\x9a\xde\x2d\x07\x78\x3b\xc3\x2b"}, +{{0x43,0xbd,0x92,0x4d,0xb8,0x15,0x60,0x08,0xc6,0xb3,0x99,0x4a,0x81,0x30,0xd4,0x27,0xd5,0x14,0xdb,0x8a,0x61,0x3b,0x84,0xdf,0xb0,0xb8,0xe0,0xde,0x6a,0xc3,0x06,0x76,},{0x1b,0x34,0x61,0xc2,0x69,0xd5,0xb0,0x06,0x2d,0x5d,0xf6,0xfa,0x65,0x4a,0x25,0x86,0xf6,0x47,0xa0,0x68,0x42,0x18,0xa0,0x6e,0x5e,0x2f,0x7b,0xad,0xfb,0x39,0x41,0x31,},{0xd2,0xa0,0x5d,0x88,0xd9,0xd5,0x43,0xd9,0x4d,0x57,0xec,0x88,0xae,0x55,0x68,0x17,0x50,0xf2,0x0b,0x9b,0xe9,0xc1,0xe9,0x18,0xcd,0xaf,0x45,0x77,0x67,0xf2,0x94,0x8d,0xd6,0x29,0xe9,0x4f,0x06,0x8e,0xdc,0xf3,0xd9,0x92,0x7e,0x33,0x02,0x34,0xba,0xdc,0x3a,0x02,0xfa,0x5a,0xd3,0xd9,0xd8,0x5e,0x94,0x8c,0xb0,0xb0,0xcb,0x3c,0xd7,0x0a,},"\x61\x84\xe6\x48\x0c\x42\xe9\x6c\xc8\x77\x26\x9b\x16\x37\x15\x45\xff\x95\x23\xc4\x5e\xa8\x8e\x76\xa1\x34\x8c\x68\xae\x7f\x31\x8b\x08\x8f\xe4\x61\x09\x28\x23\x91\x85\xb6\xb5\x5b\xfa\x0f\x43\x64\x4c\x4a\x4c\x97\xc5\x6e\xd7\x7d\x08\xb1\xf4\xaa\xd2\xf4\xaa\x06\x99\x94\xab\xec\xa9\x6b\x7b\xf8\x1b\x80\x64\xea\x43\x50\xd8\xa8\xb0\x22\x97\xa5\x13\x08\xb6\x1c\x57\xc8\xf1\x87\x3c\x6f\x97\x00\x7a\xca\x31\x80\x42\x9e\x73\x0a\x66\x43\xf2\x87\x33\x54\x7b\xcf\x7b\x9a\xdf\xe3\x27\xe8\x57\x36\xbd\x04\xaf\x7f\x1d\x9f\x4f\xb8\x4a\x7f\x3a\xff\xdf\x4e\x22\xb5\x74\xec\xb4\xbc\x88\x36\xb1\x0b\x84\x53\xae\xaa\x5c\x1b\xf1\x32\x24\x8b\x82\x6c\xc5\x23\x0f\x75\xe0\x75\xfa\xc9\xf0\x37\x56\x11\x36\xe0\x06\x43\xd0\x82\x53\xe7\xad\x65\x2f\x70\x2c\x0d\x15\xb6\xd7\xd4\x8a\xa6\xf8\xe9\xb5\xf5\xcc\x14\x6e\x3f\x15\x6f\xb2\x52\x27\x51\xc3\x71\x00\x41\xbd\x92\x2f\x37\xa5\x03\x77\xe0\x28\xb0\xc4\xe4\xbc\x34\x65\xd7\xc8\x4a\xf6\xa5\xfb\x42\x7a\xcb\x3b\x41\x37\x8b\x10\x2b\xda\x46\xd8\xf6\xf2\x03\xa5\xff\xcf\x39\x5d\x43\x5e\x93\x45\x8a\x0b\x0a\x4c\x2e\x77\x82\xfa\xfe\x11\x9f\x76\x9f\x67\x05\x8c\x66\x77\xf6\xd1\x0d\x9c\xf5\xcb\x87\x48\xe1\x80\x57\x98\xed\x23\x3f\x6f\x93\x0e\xee\x0e\x50\x75\xbc\x58\xb9\x7a\xf9\x17\x7f\xda\x75\xd5\x37\x08\xbe\xb0\x4d\xc4\xf1\x9a\x43\xe7\x68\x07\x46\x09\xf1\x40\x65\xf4\x8f\xda\xd5\x07\x7c\xe1\x09\xba\xcc\x35\x71\x74\xa6\xb7\x95\x6f\x6e\x7f\x32\xe3\x84\x15\xbe\x52\x63\x70\xfa\x58\xc3\xc0\xb3\x1f\x51\xe6\xcd\x4b\x2c\xf2\x7f\x8b\xcb\xc2\x12\x59\xd9\xe5\xc3\xb5\xc2\x94\x6a\x9f\xc1\xb0\x0d\x9d\x15\xc3\xb7\xd8\x0b\xfd\x9d\x05\xdb\x91\xd2\x49\xd3\xe4\x2d\x89\x56\x68\x20\x44\x54\x8d\x83\xbd\xa8\xd5\xcc\x92\x12\x44\x2f\x30\xb4\x5c\xf4\xae\xad\x80\xcc\xe9\xb3\x51\x2c\x39\xc5\xc7\x37\xd3\xf8\xd7\x47\xaf\xba\xb2\x65\xaf\x5e\xee\xf8\xca\x93\x62\xec\x76\xe9\x43\xb0\xa0\xd7\xa3\x9f\x3d\xb1\x1e\xca\x14\x45\x8a\x7b\x59\x2e\x5e\x4f\xf2\x27\x5d\xd4\x8b\x28\x53"}, +{{0x8f,0xb0,0x86,0x20,0x6d,0xd9,0x5a,0x26,0x21,0xf5,0x98,0x56,0x0c,0xcb,0x28,0x1f,0x82,0x73,0xc8,0xfc,0x72,0xe2,0x36,0x11,0x08,0x9b,0xaa,0xc8,0x9d,0x3c,0x3c,0x78,},{0x20,0x27,0x6e,0xf4,0x79,0xf4,0xd4,0x52,0x3a,0xb7,0x74,0x20,0xd4,0x24,0xe8,0x81,0x9c,0x33,0xc8,0x37,0x79,0xed,0x80,0xc7,0xf6,0x66,0xe8,0xf4,0x40,0x3f,0x94,0xd7,},{0xa9,0x30,0x5e,0x00,0x16,0x00,0xd5,0x97,0xd0,0x5e,0xf6,0x71,0x69,0x9b,0xf0,0x9f,0x0d,0xcc,0x0c,0x44,0x47,0x5d,0x3c,0xa3,0x1e,0x7f,0xf1,0xbf,0xfe,0xdc,0x0c,0x67,0xda,0xa1,0xf3,0xb7,0x6a,0x03,0x59,0x48,0xc5,0x9c,0xd8,0x7f,0x82,0x45,0x3a,0x40,0x95,0x0a,0x1c,0x97,0x03,0xc2,0xe7,0xd9,0x28,0x0e,0x73,0x03,0x96,0x6d,0xa3,0x01,},"\xf0\x29\x03\xed\x42\x66\xe8\x49\xa4\x48\x52\x05\x95\x4f\xff\xa8\xa1\x08\xc3\x23\xb7\xe3\xf8\x43\x31\x04\x35\x14\xe4\x85\x56\xab\x01\x94\x97\x23\x3a\x5a\x12\x7b\xff\x3c\xd7\xc9\x70\x86\xbe\xce\xf5\x38\xb3\xf3\x39\xd7\xd0\x6e\x53\x2d\xc7\x32\x5e\x59\x7a\xe3\x57\xf8\x16\xde\xa4\x2a\x6a\x22\xc7\x9d\x22\x07\x4a\x2e\x1a\xd8\x02\x3c\x42\x4b\x7e\x09\x6e\x5a\xd8\x89\x7b\x05\xef\x7d\x00\xd3\x0a\x04\xaa\xf2\x98\x1e\xdd\xff\x2b\x34\x7f\x1e\x27\xe2\x0a\xab\xbe\x7e\x7a\x95\x44\x97\x8e\x09\x2b\x00\xcc\xe4\x20\xab\xa0\x61\x87\x37\x4f\xfb\xb3\x7b\x4c\x22\xd7\x5f\x04\xe5\x75\x90\xf6\x10\xa2\x73\x47\x28\x6c\x29\x83\x12\xa6\xc9\xb1\xbd\xf2\x4f\xbd\xa8\x51\x3c\x4f\x83\x56\xcc\xf7\x57\x06\x8f\xfc\x11\xbc\x65\x11\x37\x83\xa5\xdd\xe7\x72\x2f\xaf\x4c\xeb\x19\xfb\xb6\x2f\x40\x70\x2e\x2c\x6e\x6a\x8b\xb4\x9e\xf4\x04\x46\x45\x0c\x4c\x59\xa2\x99\x09\x44\xda\x47\x44\xf6\xee\x77\x0b\x93\x0c\x24\x66\x69\x81\x3c\xe5\xa9\xf5\xa4\x7d\xd8\x03\x88\x98\x1b\xfc\xc3\xa5\x6b\x5b\xe2\xc4\xc7\xe6\x59\xa2\xe9\x18\x2d\xec\x0a\xaa\xfe\x90\x31\xaa\x39\x54\xd4\xfe\x7c\x43\x11\x96\xa5\x61\xa5\xb7\x8e\xab\xa6\x4f\x3d\xb1\xb5\x86\xc5\x3b\x16\xf6\x79\xa8\x49\x21\xa6\x42\xc2\x60\xe4\x65\x3a\x61\xde\x10\x8e\xbd\xe6\xf7\x05\x3a\xfa\x2c\xb3\xf3\x66\x8e\xde\x12\x10\x20\xdd\x1b\xac\xe8\x41\x8a\xeb\xac\x3a\x5b\xd5\x14\x2f\x10\x5a\xc2\x6f\xe4\x9e\x5f\xb1\x40\xc1\x9b\x22\xd5\x4a\x62\x91\xdf\xc9\x54\x67\x02\x47\x88\x16\x46\x87\x4d\xef\xad\x81\x49\x95\x51\x9f\x62\x60\xe9\x77\x4a\x8d\x18\x5c\x37\x88\x1b\x4f\x25\x43\xc4\xb6\x3f\xbf\x19\x85\x01\x6a\xb4\x1c\x4d\x72\x8c\xbc\x90\xb3\xab\x87\x62\x67\xbe\xd4\x1d\x0c\x09\x02\xf6\xb5\x0e\x8f\xa9\x06\xfc\x47\x88\xf7\xb8\x20\x46\x73\x06\xe0\xfe\x9e\x03\x6a\x0a\x00\xf8\x04\xf9\x1c\x3c\xa7\x18\xb9\x5f\xf6\xd9\xe2\x20\x4b\xc3\x16\x1b\xf7\x0f\xcc\x17\xb2\x96\x4b\x56\xbc\x61\x2e\x29\x40\x2d\x96\xf5\x09\x86\x51\x4b\xc7\xd8\x31\xd5\x8e\x42\x79\x37\x86\xd5\x80\x6f"}, +{{0xaf,0xa1,0xb8,0x46,0xc2,0x10,0xb5,0x23,0x00,0xe9,0x76,0x96,0xf8,0x1b,0x8e,0xa7,0x74,0xd1,0xdf,0x12,0xe6,0x12,0x52,0x7c,0x55,0x74,0x7f,0x29,0xc1,0x93,0x73,0x96,},{0xb6,0x09,0x56,0x6b,0xbd,0x19,0x47,0xbd,0x7a,0xfa,0xce,0xb1,0x43,0x89,0xe8,0x36,0x22,0x71,0x69,0x21,0x5f,0xab,0x66,0x85,0x1a,0xa5,0xd7,0x0d,0x6e,0x2e,0x3b,0x89,},{0x98,0xb0,0xc6,0x31,0x3c,0xec,0xaf,0x7c,0x82,0xcb,0xde,0xb3,0xd0,0x28,0x06,0x41,0xc6,0x1a,0x06,0x0f,0x65,0xe5,0x63,0xaa,0x93,0xce,0x18,0x30,0x0a,0x9b,0x58,0x27,0x2d,0xc8,0x68,0x0b,0x48,0x5e,0x8c,0xd1,0x1c,0xf8,0x0f,0xdc,0xa8,0x68,0xfa,0xb3,0x65,0x37,0x83,0x84,0xa1,0x42,0x72,0x7f,0x2f,0x84,0x4f,0x87,0xcf,0xdf,0x19,0x05,},"\x4c\xac\x1b\x1f\x4b\xd4\x82\x84\xdc\xc9\xaf\xc8\xb5\x95\x5b\x64\xb4\x36\xdb\x70\x4b\x03\x35\xd9\x75\x5c\xc1\xf9\x74\x77\xf8\xd3\x23\xcb\x64\x10\xef\x14\x6a\xb8\xa9\xef\xb9\x52\x6d\x8b\x62\xe3\xbb\xad\x1f\x72\x95\xf4\x7b\xa9\xf0\xde\x95\x8f\x8e\xc9\xb7\x7a\xb4\x22\x32\x43\x7e\xd9\x74\x85\x64\x44\xcd\x22\xe2\x0b\xe3\x5e\x91\x81\x3b\xff\x4b\x01\x6f\x81\x0d\x0f\x61\xd8\x9f\x6b\x61\x4d\xb3\x3f\x34\xbd\x09\x98\x5b\x59\x3f\xe3\xe0\x6e\x06\x5b\x7b\xc6\xcd\x39\xd5\x5c\x2c\xfb\xec\x7b\x6d\x59\xc0\xb3\x7d\xd1\xd0\xd3\x51\x35\xab\x1d\x1b\x04\xf2\xf3\x0c\x2f\x04\xf4\xba\x2b\x36\x58\x27\x38\x08\x1c\xf5\x91\x90\xf5\x28\x36\x3d\xb9\x44\xed\x61\x29\x31\xd1\xd5\x14\xc6\x21\x4f\x9a\xb9\x2a\xbb\x18\x33\x92\x61\x83\xac\x52\xfb\xa2\xa4\x55\x1e\x20\xe4\xc0\xac\x95\x9a\x49\xdd\xb1\x67\xa3\x81\xe0\x24\x1d\x40\xc0\x86\xe9\x0e\x52\xac\xa0\x17\x25\x89\x75\xdb\xab\x2b\xa4\x51\xee\x53\x9a\x71\x8f\x07\x6a\x58\x70\x9c\x66\x97\x41\x8d\x9c\x6f\x13\xe4\xd3\x91\x36\x8b\xf0\xe8\xbd\x8f\x29\x32\xdd\x95\xce\xaf\x7a\xac\xa1\x24\x11\x47\xd3\x41\xa3\xac\xd0\x8d\xc3\x29\x05\x48\x35\x72\xb8\x9a\x80\xcc\x47\x23\x14\x68\xab\x8d\xe3\x59\xdd\x52\x5a\x62\x57\xcf\x19\x6c\x2e\xcb\x82\xfa\x8a\x78\xaa\x3a\x85\x1c\x7c\x96\xca\x25\xbf\x7c\xa3\xdc\xf3\xca\x21\x45\x3d\x0d\xfd\x33\x23\xd5\xa4\x22\xde\xc8\x43\x16\x10\x2f\x68\x4c\x35\x9f\x22\x6b\xb5\x37\x79\xc0\xb9\x95\x09\x39\x28\x1e\xf7\x9a\x58\xc0\x11\x99\x3e\xac\xe0\x85\x49\x7a\xfa\x4d\xaf\x64\xc9\x68\x7b\x0a\x11\xaa\x11\x6c\xfa\x7b\x03\x93\x62\x41\xa5\x56\x7b\x64\x6e\x7e\x42\xe9\xfb\x59\x24\x05\xb8\xfa\x3c\x0a\x82\x1f\xc3\x12\x1b\x45\xb1\x75\x3c\xec\x9a\x83\x94\x7d\x21\x1a\x45\x49\x9b\xd6\x37\x90\xb8\x7f\x01\x47\x2f\xe5\x66\xd8\x76\x96\xef\xed\xbb\x74\xed\x00\x04\x8c\x38\x4b\xa7\xf0\x27\xb3\xaa\x42\x98\xdc\x41\x10\x34\x9f\xed\xf5\x2a\x96\xcd\x05\xd0\x8b\xd6\x35\x77\x1e\xd4\x51\x07\x38\xd8\xf0\x7a\x60\x21\x24\x4d\x19\x03\x57\x9a\x3e\xa7\x39"}, +{{0xc8,0x59,0x13,0xa6,0x87,0x78,0x77,0x13,0x10,0x01,0x62,0x3c,0xcd,0xa9,0xcd,0xc1,0x2b,0x9d,0x40,0x43,0xb8,0xa8,0x37,0x93,0xc4,0x46,0x96,0x63,0x2c,0xd6,0x42,0x1c,},{0x9c,0xc6,0x7c,0x69,0x48,0xf7,0xbf,0x6e,0x55,0x6d,0x08,0x49,0xd3,0xb8,0xd2,0x03,0x45,0x7a,0x7b,0x61,0x54,0x9b,0x36,0x68,0x1d,0x75,0x4f,0x1d,0xc0,0x84,0x1e,0x96,},{0x01,0xfc,0xcf,0xdb,0x1f,0xb6,0x88,0x8b,0x03,0x10,0xa9,0x13,0x17,0x0f,0x7e,0x36,0x68,0x16,0xda,0xeb,0xe7,0x65,0x0d,0x72,0x51,0x3d,0x95,0x06,0xe6,0x6f,0x7d,0x62,0x20,0x8a,0x49,0xec,0xe0,0xaf,0x18,0x71,0x49,0x7f,0x45,0x41,0xef,0x60,0x5b,0xde,0x71,0x1c,0x9e,0x0a,0x12,0x05,0xef,0x48,0xf2,0x6c,0x03,0xdc,0x1a,0xd4,0xaf,0x03,},"\x91\xb5\x00\x9e\x83\xd0\xf6\x10\x33\x99\xc2\xd3\xfe\xec\x00\x84\x97\x3a\x30\x5b\xf4\x17\x6e\xc7\x82\x53\x75\x60\x47\x2d\xb1\x87\xa1\x1b\x4d\xcb\x4b\x2f\xfb\x7f\x06\x44\xfe\xb3\x94\xb2\x8e\x5b\xfe\x97\x24\x7c\x4a\x4a\x23\x1c\xf6\xe9\x16\xbf\x99\x34\x4c\xcd\xa8\x8a\x7f\x5d\x83\x1d\x6d\xe3\xd5\x63\xdd\x10\x2e\xae\xb1\x08\xc5\xbd\xce\x44\xe0\x63\x2d\x17\xe6\xfa\x55\xb1\x80\x67\xdf\x2f\xa8\xd2\x00\xa9\x86\x9f\x6a\xff\x92\x0c\x51\xd4\x6a\x1c\xed\x2d\x90\x3b\x1d\x9b\x6b\x07\x5f\xac\xbf\x91\xcd\x05\xeb\x41\xad\x81\x1a\x8e\xf4\x0d\x91\x18\x26\x10\x12\xc7\x2b\x89\x79\xf1\x51\x53\xdb\xb8\x56\x12\x93\xda\x9f\x8b\x77\xc8\xff\x14\xf7\x53\x87\x53\x6f\x00\x36\xd1\x71\x3a\x72\xce\x8c\x35\xb1\x06\x2f\x2c\x67\x32\xae\xbf\x32\x93\x67\x99\xb5\x1c\x2c\xbc\xd6\x57\x24\x13\xe7\xdf\xaa\xb8\x64\x1a\x02\xc1\x50\x23\x73\x81\xcf\x7a\x14\xe2\x2c\x74\xc6\xc2\x00\x09\xde\x7d\x3b\x7e\x69\xcd\x1b\x45\x84\xac\x2c\x01\xba\xba\xf9\x73\xc5\x6b\x38\x14\xbb\x00\x89\x72\x0e\x41\x96\x81\x06\xcf\x26\x50\x9d\x4a\xa5\x46\xfc\xad\x55\x34\xaf\x30\x3f\xfc\xa4\x2b\x16\xae\x6c\x93\xee\x06\xbc\x3c\xac\xe1\x2e\x4e\xc7\x18\x84\x4b\xd3\x0d\x22\x24\xcc\x48\x6d\x10\x6d\x1c\x45\x6b\xfa\x16\x5e\xa0\x12\x0f\xab\x3d\xf2\xc5\xab\x3a\x52\x3b\xbf\xa7\x89\xde\xed\x44\x03\x2a\xb0\xbe\x86\xeb\x7c\xc0\x9c\xdb\x7c\x07\xaa\x94\x8d\xd5\x27\x7c\x3d\xf1\xd9\xd1\x84\x35\x67\xde\xc8\x4f\x92\x88\xe0\x85\xb0\x5a\xe4\xb8\xaf\x2c\xea\x5d\x9a\x18\x4d\x50\xbe\xf8\x55\x50\xc8\x36\x61\x3d\x5d\x3a\xf5\xf9\xc2\x92\x8e\x6a\x89\x66\x0f\xa6\x27\x19\xeb\xff\x77\x3e\x46\xb7\x7e\x34\xbc\x04\x70\xda\x4d\x2c\xdb\xc7\x07\x1d\xa7\x58\xc4\xd3\x9f\xe6\x52\x01\xc8\x8a\xaa\x8e\x66\x03\xd0\xbb\xe7\xc3\xe9\xb2\xd9\xe4\x1b\x63\x46\x82\x09\x2f\x14\x73\x41\xad\x6d\x66\x7f\x20\xc6\x4e\x81\xa6\x8d\x62\x94\x67\xa5\x4d\xd8\x6e\x1c\xe1\x2c\x56\x0a\x6f\x9b\x64\x51\x2d\x6f\x38\x86\xcb\xb9\xf3\x7c\x37\xeb\x39\x85\xc8\xac\x38\xdd\x66\x82\xf4\x8f\xe1"}, +{{0xfa,0x1e,0x11,0xdc,0x83,0x64,0x20,0x8d,0x8e,0x1c,0xb6,0x6a,0x36,0x1b,0xe7,0xe8,0x4c,0x5e,0x36,0x81,0x66,0x58,0x7d,0x4f,0xdb,0x06,0xac,0xed,0x7f,0x62,0xe1,0x7c,},{0x4d,0x8e,0x6f,0x4b,0x34,0x15,0xdf,0x6c,0xed,0xab,0xfb,0x29,0x5c,0x19,0x84,0xfd,0x41,0x99,0x23,0xc6,0xac,0x41,0x76,0x4e,0x32,0xd2,0x2d,0xaf,0x37,0x2c,0x50,0xfc,},{0xe8,0x57,0xdb,0x08,0x7e,0x28,0xd6,0x75,0x0b,0xf5,0x4e,0x53,0x79,0x72,0x51,0xd8,0x43,0x99,0x89,0x57,0x6c,0x12,0xda,0x2d,0x9c,0x81,0x1a,0x14,0x87,0x7c,0x3b,0xd4,0x6c,0x4e,0xfa,0xb8,0x61,0xa1,0x0e,0xeb,0xe7,0xda,0x04,0xc0,0xb0,0xb4,0x45,0xc7,0xa3,0x90,0xa5,0x0c,0x13,0xde,0x36,0xf3,0xa3,0xc7,0xae,0x01,0x57,0x02,0x2c,0x0e,},"\x29\x4e\x63\xba\xcc\xcb\x80\x1b\xbf\x04\xc1\xf1\x9d\x0a\xee\x16\xf5\x65\x0a\x6e\x8e\xea\x6f\xe4\x11\x10\x66\x3e\xc0\x15\x32\xbd\x49\x60\xa5\x27\xf1\x5e\xca\x4a\xf2\xf4\xe6\xb7\xb0\xfc\x34\x0c\xf9\x7a\xa2\x34\xe9\x2c\xf7\xd6\x9d\x50\xe4\x00\x9c\x24\x96\xe3\xed\x4d\x9a\xff\x00\x0f\x9e\x18\x52\x75\xb8\x17\xd2\x6a\x0b\xab\x69\xb7\xf7\xee\x1e\xa3\x0d\xae\xc8\xbc\xee\x38\x7a\xe4\x6b\x4b\x29\x9c\x27\xbd\xc0\x6e\xea\x63\xf2\x4d\xbe\xe9\x55\xa6\xc0\x96\x90\x37\xee\xf9\x1c\x34\x32\x1e\x3c\x5c\x97\x2f\xde\x99\x31\x83\xb7\xd2\x3f\x6e\x01\x9c\x3e\x0c\xac\x75\x89\xae\x4a\x15\x21\xaf\x87\xea\x42\xdf\x8c\x22\xc2\x27\x0e\xc2\x3d\x6d\x14\x0f\x9c\xf6\xd4\xd5\x2f\xac\x1b\x9d\x6c\x89\x39\xef\x81\x31\xcb\x62\xa0\x35\xc5\x26\x15\x38\xbc\xdf\xd6\xdb\x41\x9a\x55\xef\x9f\xe5\xd7\xa5\xac\x44\x57\x9d\xe7\x00\x85\x8d\x74\xa3\x43\x48\x44\xf2\x83\x42\xc5\x65\x89\x27\x22\xe2\x7f\x40\x7d\x7f\x17\xb7\x4a\x59\x34\xbe\x91\x5b\x20\xc2\x40\x06\x43\x23\x5f\x8a\xb5\x79\x5f\x32\x4e\x33\xc5\x06\x44\xa0\x40\x33\x54\x2c\xb3\x81\x6d\x77\x0f\xa8\x99\xe7\x31\x1c\x14\x30\x1c\x1b\xd0\xf5\xaa\x60\xa2\xeb\x31\x65\x68\x0c\x72\x0e\x1e\xfa\x80\x96\xfc\x25\xd2\x77\x92\x75\xf1\x84\x2b\x2d\xb5\x3b\x4d\xa0\xad\x3e\x59\xc0\x75\x40\xc2\x84\x60\xce\xc1\xfd\xd3\xcd\xb7\xa3\x47\x8b\x91\xa9\xca\xf9\xac\x89\x1c\xdf\x3a\xea\xee\xca\x9a\x96\x56\xac\x13\x07\x25\x99\x22\xfc\xa7\x4c\x5c\xc6\x9f\x7e\x25\xc6\xbf\x58\x79\x73\xa4\xb7\xd3\xe3\xac\x06\x35\xb0\xdb\x22\xa0\x09\x3a\x79\x07\x68\x81\xc7\x17\x36\xee\x1d\x4d\x45\xf8\xed\x2d\x29\xa0\x67\x1a\x64\xe6\xca\x2f\x7a\x5e\xf4\x04\xb1\xed\xeb\x84\x20\x34\xf5\x71\xb6\x99\xbc\x59\xe5\xa3\x7d\xf0\x20\x54\xe8\x48\x2b\xf1\xe7\xb7\x7d\x8e\x83\x97\xda\x15\xd8\x9d\x73\x55\xa5\xdc\xe8\x6b\x16\x83\xa9\xac\x4e\x40\x6c\x08\xa9\x4a\x6e\xb0\x0e\x5a\xe1\x6d\x96\x72\x29\x72\xe5\xc5\x0c\x7b\xee\x4a\x84\xd0\x69\x7b\xbe\x67\xce\xb7\xef\x29\x5f\x06\xaa\xea\x5a\xbb\xa4\x44\x66\xbe\x0f\x67"}, +{{0x24,0xa9,0x14,0xce,0xb4,0x99,0xe3,0x75,0xe5,0xc6,0x67,0x77,0xc1,0xed,0x20,0x43,0xbe,0x56,0x54,0x9d,0x5e,0x50,0x2a,0x84,0x47,0x10,0x36,0x40,0x42,0xba,0x9a,0xcb,},{0x20,0xd2,0x1e,0xe7,0x64,0xb1,0xf3,0x5f,0x94,0x56,0x82,0x00,0xd6,0x3b,0xd5,0x82,0x8a,0xca,0x8c,0x5d,0x3e,0x90,0x47,0xd2,0x3f,0x47,0x8b,0x92,0x52,0x95,0xfa,0x2e,},{0x3a,0xe0,0xcc,0x7b,0xca,0x8d,0x73,0xbe,0x83,0xa9,0xb8,0x09,0xb1,0x33,0x38,0xc1,0x27,0x06,0xaa,0xef,0x75,0xc4,0xd1,0xa4,0x78,0x17,0x8f,0x9d,0xc5,0x65,0x51,0x4c,0x75,0x29,0xe2,0x98,0x04,0x3e,0xa7,0x8d,0x21,0xa5,0xa0,0x9d,0xd0,0x4f,0x10,0xae,0x87,0x44,0x1e,0x56,0x86,0xa9,0x33,0xc9,0x2c,0x75,0x54,0x84,0x27,0xad,0x3a,0x03,},"\x3f\xf9\xf6\x6f\xa2\x64\x6e\xc6\x6a\x1b\xf9\x33\xc2\xb4\xcc\x0f\xbf\x91\x2b\x4d\x6d\xb5\x05\x34\x25\x7f\x97\xd0\x1e\x69\x8d\x05\x48\x57\x47\xde\x25\x44\xe9\xf5\xa4\xa4\xa0\x75\x38\x8c\xf4\x40\x0a\xb8\x9b\x03\x53\xce\x86\x19\x82\x02\xdb\x3a\x90\x37\x67\xb8\x79\xa2\xaf\x9d\xaa\x15\x58\x43\x11\x1a\xf1\x5a\x2b\xc3\x5e\xfe\x41\xbc\xc9\x2c\x82\x07\xe0\x01\x13\xb0\x4f\x13\x03\x00\x79\x49\xff\xb6\xce\x8d\xf4\xb0\xb3\x42\x48\xfe\xdf\x5d\x9c\xb2\xce\xe9\x4b\x81\x2e\xd5\x8e\xce\x2a\x0c\xe0\x45\x4c\xf1\x4c\x20\xe4\x9e\x09\xfe\x66\x4d\x6e\x25\x76\x2e\x87\x89\x59\x32\xcd\x5c\xd3\x2e\xb6\xa3\xab\xb3\x8e\xe1\x63\x07\x8c\x13\x3e\x93\x58\x87\x91\xdb\xf6\xaf\x49\x9a\x31\xea\x44\x53\xbb\xcc\x7a\x85\xe4\x06\xc9\x84\x8a\x66\x40\x52\xf1\x11\x13\xfb\xb4\xff\xa7\x60\xde\xe4\xc2\x61\xe3\x96\x94\x24\x91\x11\x9d\xa2\x9a\x33\x58\x2f\x82\x1d\x41\x25\xe0\xb4\x16\x2f\x28\xbe\xb0\x66\x03\x1a\x65\x2d\x05\x74\x9a\xa7\x24\x4d\xd4\xf3\xd3\xbb\x15\xd2\x68\x32\x8d\x6a\x02\xfc\xe2\x50\x18\x15\x25\x7f\x8a\xd5\xaf\x4e\xcb\xe7\xcb\x8a\xe9\x66\x1e\x34\x4f\x90\x72\x31\x87\x91\xf3\xe8\x59\x09\x11\x21\xe0\x8a\xef\xca\x89\x82\xea\xaf\x66\x25\x9d\x9d\xe4\xf4\x6a\x31\xe7\x16\xdc\x03\x3d\x0f\x95\xd1\xfa\x93\x6b\x6c\x60\x79\xb1\x37\xdd\x11\x58\xd1\xde\xf1\x13\x01\x8c\x73\xf8\xeb\xb9\x80\x7e\x0f\x74\x15\x40\x4e\xa9\xc7\x85\x44\xac\xe7\xce\x46\x3c\xd1\xd1\xc5\x7e\x31\xf4\x09\x1b\xc0\x91\x80\x4c\xbc\xdd\xad\x0e\x15\xa4\x0c\xa9\x1a\xcb\xe1\xc6\x22\x4e\xd1\x3c\xaf\xb4\xdf\x2c\x84\xac\x9f\x0c\x3c\x9b\x54\x60\x07\xd9\xdd\x6e\x52\x4c\x46\x70\x72\x56\x3d\x4a\xc0\xd7\x00\xcc\x1b\xf3\x0f\xeb\xb3\x34\x31\x3d\xae\x57\x61\x74\x5e\xc0\xa5\xe9\xe8\x81\x50\x25\x95\x8f\x00\xfa\x2e\x58\x06\x0d\x7e\x9a\x5f\x2b\x72\x7f\x48\x69\x9f\x92\x9c\x84\x59\x93\x08\x92\x57\x3f\x78\x4f\xef\x56\x92\x51\x8b\x5c\xa2\x68\xe2\xa7\x3e\xbe\xad\x6e\xbd\xeb\x7e\xc2\x4e\xac\x92\xaa\x7d\xcb\x41\xb5\x98\xbd\x6e\xff\x36\x32\xd0\x69\x72\x62\x91"}, +{{0x55,0x32,0xe0,0x9b,0x93,0x7f,0xfd,0x3d,0x5f,0x4c,0x1d,0x9f,0x1f,0xfc,0xde,0xd2,0x6e,0xe7,0x4d,0x4d,0xa0,0x75,0x26,0x48,0x44,0x69,0x0b,0xd9,0xc8,0x61,0x39,0x94,},{0x50,0x93,0x96,0x9f,0x37,0x7b,0xec,0x3e,0x35,0xf5,0x9e,0xfd,0xa0,0x1a,0xb4,0x18,0x6c,0x5d,0x2a,0x36,0x74,0x0c,0xf0,0x22,0x67,0x5e,0x01,0x09,0x6b,0x1a,0x3f,0x0a,},{0xd5,0x27,0xff,0x0d,0x4a,0x21,0x9d,0x61,0xf4,0x18,0x12,0x12,0x06,0xa5,0x4a,0xe4,0x98,0x58,0x54,0xa3,0x10,0x48,0x27,0x44,0x48,0x6e,0x4d,0x13,0x0a,0x7d,0xe9,0x7c,0x31,0x9d,0xf8,0x37,0x2c,0x82,0x82,0x8c,0x93,0x6e,0x6a,0x8a,0xfd,0x9c,0x5d,0xe1,0x82,0x85,0x73,0xd8,0x26,0x1a,0xe9,0x36,0x5b,0x8f,0x23,0x76,0x76,0x18,0x24,0x02,},"\xad\xd4\xd7\xa9\xce\x3f\x63\xd1\xf9\x46\xe8\x67\x90\x65\x54\x5d\x8c\x7b\xf0\xa2\xcc\x3a\x4c\x00\xb8\xf1\x42\xf0\x94\x5a\xe3\x62\xc4\xc9\x46\x2a\x75\x76\xa4\x05\x9d\x57\x86\x16\x62\x88\x4b\xd8\x0b\x96\xd9\x0d\x27\x9a\x95\x2e\xda\x95\x2d\x37\xd4\xf9\x5c\xf0\xd7\x0d\xa9\x8f\x4f\xba\xca\x39\xe1\x69\xf9\xd9\x45\xd4\x1f\x87\x23\x97\xbb\xdd\x57\x01\x45\x43\x03\xd7\x7d\x31\xe8\x63\x48\x27\x1d\xa4\x0a\x1b\x8f\x1e\x57\xc3\x6f\xcd\x80\x3e\x14\xfa\x17\x71\x6c\x56\x31\xef\xa0\x1d\x3a\x79\x5d\xc2\x0b\x2b\xde\x36\xab\x73\xff\x6a\x2d\x53\x3b\xc1\x5c\xce\x22\x32\x87\x13\xc3\xc9\xcc\xd0\x72\xc3\xe4\x50\xd7\xf2\x2c\x0c\x9f\x94\x91\x97\x52\xcb\xfe\x45\xee\x65\x5d\x1b\x53\x67\x65\x93\xcd\xb4\x48\x70\x41\x02\x63\x1c\xaa\xa9\x76\x95\x2e\xaa\x1f\x6c\x2e\x87\x65\x64\xe4\x20\xf0\xc6\x46\xa0\xf8\x83\x65\xf7\x64\x15\xb4\x08\x5f\x60\xa3\x38\xb2\x9c\x51\x63\x3e\x54\x0f\x0b\xf3\x2d\x40\x87\xe7\xd0\xfb\x68\x5b\xe8\x8c\x75\x95\xdc\x53\x1c\x99\xb4\x89\x58\x45\x60\xad\x82\x34\xb1\x8e\x39\xa1\x07\xcf\x5d\x84\x2d\xab\xd4\x21\xe7\x7d\x26\xea\x5e\x0f\x14\x05\xce\x35\xfe\x79\x27\x14\xeb\x4e\xe1\xa8\x01\x76\x48\xac\x1a\xe7\x39\xa3\x3d\x7b\x1e\x08\x91\x05\xd1\xe5\xad\xd2\x7a\x62\xce\x64\x15\x45\x70\x34\x0a\xf9\xeb\x14\xe7\xfd\xfc\x2f\x9a\x2c\x2f\xcf\xcd\xac\x3c\xc4\x22\x77\x63\xf4\xd6\x29\x49\x74\x79\xf8\x49\x21\x6e\x5d\x90\xec\x16\xdf\xa3\x6b\x72\x51\x7f\x7b\x54\x86\xba\xee\x7f\xda\x44\x50\xc3\x52\xcf\xfb\xba\xe7\x39\x26\xc8\x43\x22\x4f\x8c\xe4\x4b\x38\xda\xe5\x3f\x3e\xad\x21\x89\x0b\x52\xa7\x80\x10\x75\x29\x16\x84\xfd\x59\x10\xed\x86\xad\x33\xe8\xa0\x07\xf6\xc3\xf8\x5c\x16\xb2\x09\x29\x37\x40\x18\x4f\x58\x90\x87\x4d\x43\x1c\xd4\xe0\xea\x40\x87\xc4\x9c\x34\x71\xd7\x89\xc8\x13\xc6\xdc\x9a\x78\x69\x93\x63\xa1\xd8\x71\x97\xd3\xb9\x2c\x02\x86\x68\x93\x11\x82\x3f\x4d\xf2\x2c\xe8\x03\x5e\x75\x73\x2c\xde\xa7\xf5\x62\x1f\x67\xdb\x0e\x2a\x4c\xa6\x61\x61\x93\x22\x1c\x0a\xa3\xd6\xde\x50\xd8\x52\x82\xee"}, +{{0xeb,0x36,0x51,0x10,0x09,0xd3,0x7a,0x9c,0x46,0xc4,0xd1,0x37,0x4d,0x0b,0xbd,0x0d,0x99,0x81,0xe7,0x8c,0xee,0x7d,0x18,0x8c,0x5a,0xab,0x98,0x3e,0xc2,0x39,0xe1,0x0c,},{0xb1,0xcc,0x21,0x2b,0x45,0x21,0xbb,0xe7,0xb1,0x9a,0x76,0x93,0x87,0x8a,0x55,0x84,0x40,0xee,0xc3,0x62,0x05,0xd8,0x43,0x9d,0x04,0x0a,0x46,0xa9,0x90,0x2f,0xbf,0x55,},{0x9f,0x58,0x37,0x24,0xde,0x55,0x2e,0xae,0x82,0xf2,0x54,0xac,0x6e,0x2e,0xd4,0x83,0xec,0x1a,0x07,0x34,0x62,0x66,0x73,0x5c,0x49,0x09,0x20,0x69,0x0c,0x1e,0x3f,0xb2,0xa9,0xe9,0xa3,0x41,0x94,0xed,0x64,0x73,0x73,0x3b,0x30,0x0d,0x4f,0x23,0xc9,0xae,0xc0,0xda,0x5a,0x20,0x22,0x05,0x4c,0xa4,0x38,0x85,0xa1,0x5a,0x29,0x84,0x32,0x0e,},"\xba\x24\x66\xe5\x6c\x1d\xf7\x7f\x22\xb6\xf0\x24\x1f\xc7\x95\x2a\xe9\xbc\x24\x75\x64\x19\xa9\x44\x6d\xd2\xb4\x9e\x2c\xb9\xdf\x59\x4e\x5b\x6c\x77\xa9\x5a\xa5\xfb\xd9\xdc\x57\xfe\xc8\x39\x62\xc7\x75\x1e\xeb\xb4\xba\x21\x82\x53\xf9\x16\xa9\x22\xa5\x13\x96\x63\xe3\x20\x3e\x3b\xe4\x82\xbe\x37\x9c\xa1\x51\xc4\x63\xd9\xad\xa2\x14\x46\x13\x5f\x35\x69\x94\xfa\x54\x49\xf0\x84\x47\x8f\x5b\xb4\xf5\xba\x61\x45\xc5\x15\x8e\xb7\xb1\xc4\x3c\x32\xeb\xea\x25\xe0\x9c\x90\x0f\x01\xef\x91\xe9\x2f\x88\xc0\x3c\x76\x50\x4a\xce\x96\x46\x01\x6f\xfc\x27\x89\x55\x9d\x0f\x3c\xc9\xd0\x0f\xb6\x1b\xdc\x6a\xf7\xd3\x94\x0f\x30\x2e\x58\x8e\x04\xf7\x9f\x7b\x3d\x4b\x91\xa5\xd1\x93\xa4\xf8\x22\x2b\xfe\xb6\x9b\xf0\x34\x7d\x98\xad\x81\xef\x99\xd1\x30\xeb\xc7\xb3\x6b\x07\x83\x39\x4e\xea\x92\xa3\x8d\xdd\x5e\x74\x80\xd2\xad\xd4\xe4\xde\xf5\x3e\xb9\x9c\x44\x9b\xff\x94\xe4\x71\x8b\x09\xf2\xea\x9b\x1f\x2b\x88\x65\x94\xa9\x5c\x33\xa6\x9e\x03\x33\x15\x4e\x44\x0a\xb3\x4b\x7b\x6c\x11\x34\xd8\x17\x9b\x6f\x0c\x56\x25\x1a\x9a\xd8\xe1\xb6\xb0\xf9\xb8\xa5\xc9\x70\x81\xa7\xf8\xfd\x05\xd0\xb0\xaf\xfc\x82\xdb\xdd\xc8\xb0\xc0\xab\x7e\x83\x3f\x30\x06\x26\xd4\xb9\x73\xb3\xf6\x0f\xea\xc5\x55\x71\xe8\x9c\xda\x0f\x2b\x44\x1e\xd2\xfa\xa6\x69\xa7\x0d\x55\x6c\xb4\x8f\x9b\x1d\x1c\xbc\xe3\x2e\xde\x5d\x16\x6b\x11\x43\xe2\x64\xb1\x1e\xa3\x27\x68\x1c\xb5\x59\xed\xd1\x3c\x36\x4b\xd2\xba\xf1\xfd\x54\xbb\x78\x18\x07\xbd\x59\xc8\x68\xb0\xe4\x79\x5a\x77\x9e\x67\xf0\xbd\x0d\x14\xb5\xa6\xb9\xe4\x40\xb5\x7a\x58\x23\x32\x8b\x59\xaf\xfb\xd0\x27\xed\xa7\xdd\x78\x50\x79\xc5\xf0\x2b\x5e\x32\x89\x0b\x03\x87\x30\x98\x6a\x39\xa5\xa9\x83\x4a\x3f\xed\x86\x8b\x6f\x45\xcb\xdd\x28\xac\xb2\x70\x9a\xff\x55\x62\x63\x86\x4f\x9a\xe1\xe7\x57\xb3\x27\x8c\x28\x8d\xbe\x29\x32\x82\x57\x12\x77\x3e\x43\x1f\x7c\x29\x32\x98\x57\xfd\xae\xa7\x98\xed\x93\x92\x08\x93\x63\x14\x02\xe6\xb1\x3b\xab\x62\xb4\x85\x54\x61\xed\xb9\x46\x20\xf2\xd1\x75\x18\x65\xf4\x45\xc4\x66"}, +{{0x7d,0xbc,0x81,0x90,0x2e,0x4e,0xaa,0xb3,0x07,0x75,0x40,0xf5,0x59,0x99,0x5c,0x38,0x74,0x03,0xca,0xc3,0x06,0xd4,0x86,0xe9,0x59,0xc5,0xeb,0x59,0xe4,0x31,0xc0,0xa8,},{0xe0,0x30,0x66,0x13,0x90,0x82,0xf6,0x13,0x44,0x8b,0xdb,0xc2,0x7f,0xe5,0x3a,0xa3,0xf8,0x89,0x94,0xc3,0x1d,0xdc,0xe0,0x02,0xe3,0x6b,0xbb,0x29,0x63,0xdf,0x3e,0xc8,},{0x5b,0x7f,0x65,0x2f,0x08,0xf2,0x29,0xfd,0xa1,0xb0,0xbd,0x75,0x93,0x77,0xb3,0xfb,0x72,0x6c,0x1b,0x9c,0x9a,0x10,0xef,0x63,0x42,0x6d,0x35,0x2d,0xd0,0x86,0x9b,0xd5,0x4d,0x87,0x6c,0x30,0x92,0xf1,0xcd,0x41,0x1c,0x37,0x57,0xd3,0xc6,0xb6,0xea,0x94,0x2a,0xa7,0x0c,0x3a,0xae,0xb4,0x21,0x7a,0x4c,0x73,0x64,0xd1,0x8e,0x76,0xe5,0x0f,},"\xdf\xf7\x98\xb1\x55\x7b\x17\x08\x5a\x06\x34\x37\x1d\xed\x5d\xdf\x7a\x5a\xcb\x99\x6e\xf9\x03\x54\x75\xe6\x82\x63\x36\xf6\x4a\xd8\xb8\x4b\x88\x2e\x30\xba\xde\xc2\xb4\xa7\x11\x99\x87\x52\xf4\xa1\x57\x4b\xc1\xf8\x9d\x43\x25\xcf\x2b\x39\x86\x10\x44\xdd\x03\x69\x1e\x71\xd0\x77\x68\xb5\x93\x3a\x30\x52\xcc\x7c\x81\xd5\x71\xa9\xde\x06\x1d\xc1\x90\x26\xc2\xf1\xe7\x01\xf2\xdc\xf2\x6a\x88\xd3\x40\x1b\xc9\x9f\xb8\x15\x59\xdc\xa7\x6d\x8a\x31\xa9\x20\x44\xa2\x73\x58\x7d\x62\x2a\x08\xd1\xcc\xe6\x1c\x8f\x94\x8a\x34\xde\xd1\xac\xb3\x18\x88\x1c\x9b\x49\xf6\xf3\x7c\x30\xa6\x5d\x49\x5b\x02\xd5\x42\x9e\x7a\xb4\x04\x0d\x8b\xeb\xeb\x78\x79\x4f\xf7\x36\xd1\x51\x10\x31\xa6\xd6\x7a\x22\xcd\xf3\x41\xb9\x80\x81\x1c\x9d\x77\x5f\xb1\x9c\x64\x78\xf0\x5e\xd9\x84\x30\x10\x3e\xa2\x4c\x0f\x41\x4d\x4c\xc0\x7d\x86\x0b\x72\xdc\x54\x2f\xf2\x2d\x83\x84\x5a\x42\xf8\xba\x45\xca\x7f\xf3\xaa\xb0\xb1\xe7\xde\x2b\x10\x94\xde\xac\x08\xd1\x6e\xee\x01\x96\x9f\x91\xbc\x16\xfe\xc2\x9c\xcc\x06\x1c\x54\xdb\x53\x45\xba\x64\x84\x2d\xac\xc9\x9e\xe7\x72\x94\x68\xd8\x0a\x3f\x09\x55\x83\xd8\xe8\x01\x24\x08\x51\x9d\x58\x2c\xc3\xff\x9a\x2e\xb7\xae\xba\xa2\x2d\xb8\x1f\xfc\x78\xee\x90\xef\x4e\xc5\x89\xdc\xce\x87\x11\x8d\xab\x31\xa6\x32\x8e\x40\x9a\xd5\x05\x9a\x51\x32\xc8\x2d\xf3\xce\xfe\x2e\x40\x14\xe4\x76\xf0\x4c\x3a\x70\x18\xe4\x52\x67\xec\x50\x18\xec\xd7\xbf\xf1\xdd\xa9\x26\x7e\x90\x66\x6b\x6b\x14\x17\xe8\x9d\xda\xcb\x50\x85\x94\x3b\xef\xc7\xad\x2f\x4d\xf5\xf1\xee\x0a\xf9\x43\x1a\xee\xb6\xb2\x4a\x55\x15\xb9\x3d\xbc\xf6\x86\x40\xf7\xda\xf8\xc9\x61\xe5\x67\xd7\x53\x49\x00\x20\x5c\x3d\xf2\x18\x4b\x6a\xc2\xda\x96\x1c\x4c\x1d\x2b\xc4\x9b\x4e\xa9\x6b\x81\x54\xff\xd4\xef\xff\xdc\x5e\x55\xa7\x11\x9c\xb8\xaf\x42\x9e\x85\x10\x5d\xff\xd4\x1f\xe4\xa2\xeb\xba\x48\x16\x8a\xa0\x5f\xa7\xdf\x27\xc4\x29\x87\x35\xff\x86\x8f\x14\x96\xbe\xb4\xb2\xed\x0b\x89\x80\xc7\x5f\xfd\x93\x9d\xdd\x1a\x17\xe4\x4a\x44\xfe\x3b\x02\x79\x53\x39\xb0\x8c\x8d"}, +{{0x91,0xb0,0x95,0xc8,0xa9,0x99,0xe0,0x3f,0x3e,0xd7,0x49,0xcd,0x9f,0x2f,0xaa,0xcc,0x00,0x76,0xc3,0xb4,0x77,0xa8,0x7a,0xb5,0xcc,0xd6,0x63,0x17,0x38,0x76,0x74,0x46,},{0xda,0xd1,0x74,0xd3,0x59,0xda,0xec,0xca,0x9c,0x6b,0x38,0x9b,0xa0,0x96,0x45,0x2a,0xb5,0xca,0x91,0xe6,0x38,0x3c,0x6d,0x04,0x2a,0x28,0x4e,0xce,0x16,0xba,0x97,0xb6,},{0x64,0xee,0x9e,0xfd,0xb0,0xc2,0x60,0x1a,0x83,0x5f,0x41,0x85,0x20,0x64,0x1e,0x43,0x6c,0x7d,0xd4,0x7c,0x33,0x3d,0x9f,0xc3,0x0c,0xfb,0xb9,0xe3,0x90,0xfe,0x76,0x45,0x30,0x65,0x47,0x08,0xb4,0x0b,0x03,0x58,0x18,0x99,0xa9,0xac,0x87,0x0e,0xfd,0x76,0x6f,0xfb,0xb4,0x63,0x71,0x52,0xf8,0xff,0x27,0x79,0x64,0xfe,0x35,0x42,0x52,0x09,},"\x9b\x0d\x8b\x00\x29\x98\x52\xd6\x8b\xbf\x49\x7f\xe6\x03\x96\x1a\x48\x54\x66\xa9\x9a\x54\x84\x00\x5d\xb7\x3d\x4e\x4b\xad\x81\x4e\x85\x74\xef\xd5\x4d\x64\x8b\xd5\xc9\x1a\xe8\x48\x3c\x54\xb2\xf9\x98\xb0\x2e\x1a\xbd\x6f\x40\x1a\x25\x52\x68\x43\xa5\xf2\xa2\x3a\x97\xbd\x58\x9d\x1f\x7e\x1a\xb1\x49\x15\xb1\xe3\x59\xa3\x96\xd3\x52\xc3\x60\xae\x65\x84\x32\x5a\xe4\xbb\x7d\x62\x4f\x61\x25\x5c\x5c\x7b\xf0\xa6\x7a\xca\xb4\x6c\x3b\x57\xb3\x45\x34\xc0\xee\x84\x31\xd2\x60\x57\x66\x06\xcb\xd8\x4d\x8d\x18\x39\xe7\x3d\xa6\xfe\x4b\x0b\x8b\x78\xf0\xf9\x58\x82\x7c\x2f\x1d\x93\xba\x7a\x34\x6d\xcc\x75\xcb\x56\x3d\xff\xde\x26\xf9\x97\x59\x8e\x8b\x5c\x2f\x16\x17\xc6\xfe\xfc\x9b\xe4\xb2\x8b\x54\x01\xb0\x00\x64\x13\xa2\x51\x69\x0d\x12\x03\xaa\xae\x4f\x6d\x8a\x3f\xb2\x1f\x24\x00\x9a\xb3\xbf\xf1\x37\x37\xa8\xa7\xe6\x64\x6c\x02\x73\x2d\x9e\xc5\xa4\xa5\x10\x46\x9e\x2d\x29\x9e\x4c\xc1\xad\x64\x80\xa4\x82\xaa\x95\x6f\x89\xdd\xcc\xcc\x64\xa1\x36\xfb\x15\xb8\x76\xb6\xec\xd8\x8c\x7c\x86\xa4\xdf\xc6\x0e\x66\x62\x07\xc6\x04\x16\x7d\x16\x34\x40\xca\x9a\xb9\xcf\x87\xa5\xe0\xf7\xbb\xc5\x51\x7d\xe4\xde\xe8\x76\xc0\x37\xf8\xcc\x9d\x95\x9c\x8f\xf5\xdb\xe9\x44\xff\x54\xcd\x91\xa7\x71\xe2\x92\x31\xf8\xb5\xf1\x7d\x61\xde\x90\x4c\x95\x5f\xe2\x02\x5d\xc5\x2e\xd4\x80\xfb\x3c\xc9\x0f\x23\x24\x59\xc6\x07\xef\x7e\x2a\xdb\x52\xc7\x48\x2b\xec\xd6\x7a\xd2\x14\x9a\x41\x28\xf9\x84\x03\x8b\x58\xaa\x90\x17\x67\x82\x39\x36\x04\xaa\xc7\x4c\x18\x20\x9a\x3d\x6a\x78\x63\x0c\x01\x95\x5a\x7c\xec\xe5\xda\x83\x84\xda\x3b\xaf\x63\xaa\x2d\xdf\x59\x63\xfa\xe0\x5b\xa3\xb8\x1c\x6a\x03\xd8\x6a\x00\xef\x78\xed\xb4\x18\x4f\xdc\x89\xb1\xd6\xbf\xeb\x31\x0f\xd1\xb5\xfc\xce\x1e\x21\x95\x24\xa3\xcf\xb2\xe9\x72\x57\x7f\x06\xb1\xdd\xde\xba\x00\x86\x5d\xae\x49\x79\x00\x0c\x00\x8a\xd9\x9f\x3b\x63\x8c\xce\xb8\xe8\xc7\xa0\xf9\x98\xd3\x4d\x92\x14\x3d\x81\xc0\xe1\xc0\x96\xa9\x25\xce\xba\x65\xc4\x30\x03\xee\x18\xd4\x94\xd0\x03\xe9\xc6\x1f\x77\xd6\x57\x59"}, +{{0x8c,0x56,0x8b,0x31,0x0a,0xce,0x7d,0x1f,0x0e,0xde,0xce,0xfd,0x60,0x3a,0x88,0x40,0x00,0x54,0x4c,0x79,0x25,0x65,0xd4,0x81,0xc3,0xd3,0xe0,0x6e,0x2d,0x82,0xca,0x96,},{0x5f,0xa6,0xe2,0x67,0xc7,0x66,0x73,0x68,0x41,0x41,0x10,0x72,0xd1,0x98,0x3d,0x19,0x00,0xac,0xf0,0x1d,0x48,0xc3,0xce,0x11,0x77,0x0b,0x26,0xf7,0x8d,0xa9,0x79,0xf7,},{0xde,0xbd,0xd8,0xe5,0xd3,0x11,0x2f,0xd7,0x7b,0x39,0x4a,0xa0,0xe3,0x6e,0x94,0x26,0xba,0xc9,0x1d,0xf1,0x26,0xfa,0x9c,0x31,0x7c,0xea,0x7c,0x9d,0x45,0x95,0x7c,0xdd,0x96,0xa4,0x5a,0xe3,0xad,0x76,0x04,0x13,0xee,0x12,0x05,0xaf,0xd7,0x1a,0x29,0xf9,0xc3,0xcb,0x58,0x6c,0xd2,0xd7,0xcd,0x1e,0x93,0xbc,0x16,0x52,0xfc,0x34,0xdc,0x04,},"\xb5\x9f\x5f\xe9\xbb\x4e\xcf\xf9\x28\x95\x94\x72\x1f\x26\x47\x04\x7b\x0d\xa5\xe0\xe4\x94\x1b\xbe\x57\xc5\xb7\x22\xb4\x76\x72\x3f\x0a\xc5\x97\x0b\x41\x11\xf8\x93\xbc\xaa\x41\x1f\x28\xfc\xeb\x4f\x58\x5a\x2a\x71\x87\x01\x8a\x90\x4b\x70\xef\x8f\xe1\xf6\x56\x9a\x54\xd0\x0a\xda\x37\xb6\x9c\xb5\xe9\xc9\xd2\x6c\x16\xa9\x03\x51\x81\x48\xe0\x4a\x1b\x93\x6a\x32\x32\x9c\x94\xee\x1a\x8f\xb6\xb5\x91\x89\x2c\x3a\xff\x00\xbf\x6e\x44\xdd\x0a\x76\x2b\xab\xe8\x9d\x70\x60\xc1\x7b\x90\x39\x0d\x23\xbf\x9d\x36\x0a\x29\x3b\x83\x08\x38\x30\x86\x91\x6e\x11\x82\xb1\xba\x43\x36\xf0\x01\xb8\xd2\x0d\xea\xe9\xa0\x29\xf7\xe8\x53\x97\xa9\xae\x5c\xf3\xca\x10\xc7\xf3\x87\x55\x88\xb8\xff\xab\xb0\x63\xc0\x0c\xa2\x6f\x58\x0f\x69\xed\xc5\x27\xa1\xac\xcf\x4f\x41\x39\x7b\x33\x76\x6b\xcf\x6d\x55\xeb\x8d\xe0\x81\xa4\x8c\x98\x1d\x05\xc0\x66\x61\x7b\x80\xd8\xf6\xf5\xe6\x0e\x59\xdd\x9b\x93\x0b\xc4\xd0\x45\x86\x40\x3b\xb8\x68\xdf\x75\x93\x3b\xdd\x86\x23\x0e\x44\x70\x36\xc1\x75\xa1\x0d\xe9\xbb\x39\x95\x3d\xcb\x19\x66\xa1\xf1\x19\x12\x07\x8e\x35\x8f\x48\xc5\xb2\x09\xa6\x36\xc7\xf7\x83\xf4\xd3\x6a\x93\xad\x2c\xc2\xe3\x24\x45\x19\x07\x8e\x99\xde\x1d\x51\x58\xb3\x96\x1e\x0f\xc5\xa4\xf2\x60\xc2\x5f\x45\xf5\xe8\x58\x5e\x60\x1d\xb0\x8b\xa0\x58\xd2\x90\x9a\x1b\xf4\x99\x5f\x48\x13\x46\x0d\x36\x95\x03\xc6\x87\x36\x85\xeb\xcd\x33\x30\xa1\x30\xb7\x5f\x23\x65\xfb\x2a\x5a\x34\xea\x63\xd9\x58\xa2\xa8\x67\xe9\x05\x52\xd2\xce\xc8\xc3\x90\x08\x4b\xe0\xc1\x08\xb0\xfd\x2d\x83\xcb\x92\x84\xdb\x5b\x84\x2c\xbb\x5d\x0c\x3f\x6f\x1e\x26\x03\xc9\xc3\x0c\x0f\x6a\x9b\x11\x8e\x1a\x14\x3a\x15\xe3\x19\xfd\x1b\x60\x71\x52\xb7\xcc\x05\x47\x49\x79\x54\xc1\xf7\x29\x19\x9d\x0b\x23\xe5\x38\x65\x40\x3b\x0a\xd6\x80\xe9\xb4\x53\x69\xa6\xaa\x38\xd6\x68\x5a\xbd\x39\x7f\x07\xfb\xca\x40\x62\x7e\xca\xf8\xd8\xd3\x01\x33\xa6\xd9\xd5\xaf\x00\x91\x92\x75\x1c\x9c\x45\xf7\x7c\x0b\xc0\x11\x26\x88\x00\xbf\x55\x25\x12\x73\x0e\x69\x97\x3c\x5b\xf3\x62\xab\x16\x48\x94\xbf"}, +{{0x3d,0x09,0xaf,0xce,0xe3,0xc4,0x32,0xfd,0xfb,0x6b,0xdc,0xea,0xd5,0x4e,0x3d,0xa5,0xb1,0xb4,0x16,0x5c,0x50,0xd6,0xd3,0x10,0xb7,0xfa,0xd7,0x87,0xb4,0x44,0xd6,0x80,},{0xb0,0xd9,0x02,0x8c,0x4d,0x14,0x87,0xd2,0x93,0xed,0x58,0x5a,0x76,0xbc,0x94,0xff,0xfb,0xaf,0xe2,0xc6,0x5d,0x98,0x0c,0x49,0x4e,0x14,0x1e,0x48,0x10,0xa3,0x5c,0xb9,},{0x89,0x73,0x9f,0xe4,0x41,0xca,0x0c,0xed,0x08,0xa6,0xeb,0x57,0x96,0xe9,0xbd,0xda,0x0e,0x74,0xfb,0x47,0x35,0x28,0xfd,0x49,0x07,0xed,0xb6,0x59,0xaa,0xb4,0x4d,0x33,0x43,0x22,0x90,0x46,0x71,0x63,0x68,0xfa,0xf8,0x8e,0x85,0xc1,0x64,0x4a,0xf6,0x6f,0xf2,0xdc,0xaf,0x0b,0x17,0xac,0x93,0xca,0x13,0x81,0x9f,0x3f,0x24,0x1d,0xd3,0x00,},"\x76\x71\x65\xca\xae\x0e\x57\x8f\x16\x53\x7e\x17\x50\xbe\x7d\xe8\x7a\x78\x9a\x51\xff\x2d\xe1\x18\x38\xf5\x64\xe2\x58\x0b\x23\x91\x36\x2d\x28\x68\xa5\xa4\x70\x8a\xf1\x5d\x2e\x2d\xb7\xb9\xbe\x39\xc1\x6a\xdc\xc1\x20\x0b\x34\xe6\xb4\xd4\x02\x7d\xdf\xfc\x1a\x2a\x35\x95\xe2\x9e\x85\x5e\xc5\x26\x1b\x20\xbd\x55\xc4\x28\xb0\x13\x09\xba\xdb\x59\xe2\xca\x3e\xdb\x96\x7f\xc2\xf4\xba\xc0\x72\x9d\xdf\x54\xfb\x6c\x20\x05\x7b\xdd\xa9\xe7\xaf\x7c\xbf\xc0\x92\xfb\xa8\x65\xfd\x32\x75\xb9\xd3\xbc\xb0\xc3\x46\xb9\x51\xd1\x70\xac\x9a\xa6\x50\xa8\x6d\xf4\x98\x55\xd4\x8a\x1b\x37\xce\x56\xc9\xf2\x73\x89\xf5\xc8\xb1\x5f\x5c\x2c\x90\x0c\x4f\x10\x7c\x06\x4f\x60\x3e\x4f\x86\x7e\xf2\xe9\xc1\x0a\x1b\x74\x21\x0e\x6b\x89\xbb\x01\x17\x93\xaa\x85\xde\xd4\x3b\x51\xb7\x49\xba\x7f\x70\x28\x7b\x6b\xc1\xb8\x94\x34\xdb\x8b\x8c\x8b\x5d\x73\xb2\x14\xb4\x1e\x36\xb5\x28\x00\x5b\xfb\xfe\x00\x2e\x21\xb1\x00\x6f\xb9\xd2\x4b\xab\xd7\x21\x06\xd0\x93\xe3\xc7\x09\x3b\x31\x38\xae\xa7\x19\xd6\x94\x79\x08\x46\x47\x49\x8c\xd6\xc9\xbb\xb7\x44\x50\x9c\xd7\xda\x8d\xd6\x1a\x62\x71\x00\xf0\x3c\x21\xe7\x50\xac\xb3\xfc\xf4\x63\x1d\x7c\x0f\x61\x81\x54\xd2\xe5\xfa\x66\x56\xfb\x76\xf7\x4c\x24\x79\x50\x47\xbb\xce\x45\x79\xeb\x11\x06\x43\xfa\x98\xe1\xf7\x76\xca\x76\xd7\xa2\xb7\xb7\xb8\x67\x81\x73\xc7\x73\xf4\xbe\x7e\x18\x2f\xd2\x4d\xd7\x62\x91\xac\x67\xd9\xf2\x6a\x28\xc5\xe3\xcb\x02\x5c\x68\x13\xa3\x78\xb3\x83\x22\x46\x42\xb4\xae\xfa\xd0\xc7\x6a\x65\x79\x51\x7b\x8f\x36\x07\x97\xdd\x22\x61\x3e\xe6\x82\xb1\x79\x38\x19\x50\xfb\x71\x60\x9a\x5f\xb5\x49\x4d\x2d\x57\xdc\xb0\x0f\x26\xd1\xe7\x29\x56\xf4\xd6\x67\x28\x30\xe0\x5c\x01\xb3\x77\x96\x77\xc0\x7e\xa0\x09\x53\xc6\xb8\xf0\xdc\x20\x4c\x8d\xbd\xcc\xb3\x81\xbc\x01\xb8\x9c\x5c\x26\x1d\xb1\x89\xab\x1f\x54\xe4\x6b\xc3\xed\xc4\xde\x5a\xd4\xf0\xeb\x29\xc0\xa1\x20\xe4\x37\xcd\x8f\x37\xac\x67\xd4\x8c\x7f\x0e\x73\x02\x78\x70\x8f\x02\xb5\x4a\xee\x62\xb7\x29\x52\xbc\x1c\x0e\xb4\x37\xca\x8b\xd5\x65\x54\x37"}, +{{0x41,0xc1,0xa2,0xdf,0x93,0x69,0xcd,0xc9,0x27,0x16,0x4a,0xa5,0xad,0xf7,0x75,0x71,0x36,0xab,0xe5,0x13,0x95,0x60,0x42,0x66,0x33,0x4c,0xc5,0x46,0x0a,0xd5,0x68,0x3e,},{0x40,0x55,0x78,0x34,0xcc,0xe8,0xe0,0x43,0x58,0x0a,0x42,0x72,0xa8,0x80,0x4d,0x4f,0x92,0x6e,0x88,0xcb,0x10,0xd1,0xdf,0x0c,0x5e,0x28,0xb9,0xb6,0x7e,0x1b,0x63,0xda,},{0xb8,0xb2,0x75,0x2a,0x09,0x71,0x96,0xc2,0x89,0x84,0x9d,0x78,0xf8,0x11,0xd9,0xa6,0x2f,0xc7,0x67,0x27,0x8f,0x0c,0x46,0x62,0x8b,0x52,0x1f,0x62,0xed,0x27,0x59,0xd7,0x44,0x62,0xa1,0x75,0xda,0x22,0x40,0x3f,0x15,0x02,0x04,0x45,0xca,0xe0,0x6d,0xa3,0xed,0x61,0xcc,0xa6,0x20,0x3b,0x70,0x06,0x36,0x2a,0x0e,0x19,0x89,0x63,0xd2,0x0e,},"\xb6\x4b\x14\xba\x77\xd2\x39\xe6\xf8\x1a\xbe\x06\x0a\xcc\xef\x85\xf0\x44\x2b\x65\x0c\x44\x01\x5e\xfc\x43\xa0\xaa\x2b\xa1\x0b\xf4\x8d\x30\x18\xb1\x95\x3d\xdf\xff\xbc\xda\x5b\xf3\xbb\xe0\xb6\xb3\xe4\xb0\xd9\xa3\x2c\x6b\x72\x5b\xbb\x23\x1e\x0a\x27\x04\x47\x1e\xe8\xbc\x1d\x59\x4f\x5c\x54\x22\x6f\x5d\xd9\xdf\xa1\x63\xcf\xc1\x45\x2c\x61\xf9\x3e\x4f\x81\x39\xab\x4c\xe4\x47\x6f\x07\xec\x93\x36\x61\xea\xe9\x1b\x6d\x50\x0b\xf5\x08\xac\x63\xe4\xba\xaf\x1f\xfc\x8f\x00\x07\xd8\x02\xe0\x05\xf1\xb4\xfc\x1c\x88\xbe\xe4\xd5\xe9\xe7\x63\x84\xf5\xa7\x04\x3b\xd6\x60\xcc\xe7\x1f\x3b\x67\xf0\x1f\x6a\xb8\x44\x29\x85\x31\xaa\xc7\x3a\x39\xd0\x45\x37\x00\x88\x85\x50\x05\xa0\x9c\x6d\x04\x23\x8e\xa4\x78\xdf\xac\xad\x1e\x6b\x22\xb2\xbe\x4c\x46\xb0\xd5\x9b\x1e\xba\x1f\x06\x0b\xf7\xda\x5d\x15\x66\xcf\x1f\xdb\x5c\x54\x3a\x33\x92\x6a\xf6\x3f\x01\xa0\xdb\x86\xe1\xa6\x71\x1c\x47\x3d\xc7\x95\xab\x28\x3c\x8d\x93\xfa\xcf\xb5\x70\x1f\xa2\xf2\xf6\xbb\x99\xf9\xb7\xe3\x74\x9b\x07\x1d\x58\x60\x7b\xe4\x4a\x70\x89\xbc\xb5\x03\xec\x14\x95\xb5\xfe\xed\xb3\x99\x96\x1f\xd3\x67\x7d\x74\x93\xea\xa3\xb3\xe9\xcc\x5e\x36\x42\xf4\x0d\x47\xde\x9b\xfe\xe7\xc2\x0b\x0e\x51\x9c\x4e\xb4\xa4\x0f\x4d\xa4\x46\xed\x6a\xc7\xaa\xca\x05\x3e\x75\x9c\x97\xda\xbe\x0a\x8e\xc2\xf5\x8e\x7f\x2f\x9b\x20\x72\x76\x2f\x9f\x79\x4a\x6a\x4e\x36\x06\x0b\x88\x72\xbd\x2c\x18\xd0\x6a\x85\xc2\xc1\x41\xa7\x82\x93\x77\x3e\xe8\xcf\xbf\x15\x4b\x99\x30\xcd\x39\xda\x31\xb4\x97\xe7\x37\xa7\x75\x0c\x90\xa1\x3f\x5a\xaa\x14\x7c\xd0\xdc\x43\x11\xf2\xe3\x49\x41\x25\x2e\xf1\x98\xb0\xc1\xf5\x08\x27\xe5\x6c\x9f\x16\xf5\x95\xac\xed\x6d\x2a\x69\x34\x65\x31\x49\x5a\x64\x99\x77\x4d\x36\x07\x66\xca\x9b\xe5\xed\x88\x81\xc0\xdb\x26\xed\x7c\x5e\x6f\xf3\xa4\xf9\xb7\x3c\xd8\xb6\x54\x64\x0d\xc9\x6b\xf4\x3b\xd4\x26\xa0\xf2\x8c\x9b\x25\xfa\x70\x4d\x62\xff\x02\x88\xfc\xce\xff\xaa\xeb\xd3\xea\x30\x97\xbc\xbb\xd7\x78\x42\x0e\xbc\x52\x0a\x41\x77\x30\xa1\xb5\xb3\xb8\xc9\x6c\xda\x9f\x4e\x17\x7d"}, +{{0xa0,0x06,0x11,0x48,0x94,0x67,0x12,0x2c,0x4c,0x16,0x4b,0xfb,0x6a,0x61,0x6e,0x6a,0x61,0x9b,0x9f,0x83,0xc4,0x36,0x72,0x06,0xb8,0x5d,0x3f,0xbe,0xc3,0x8c,0xd6,0x2c,},{0x57,0xab,0x58,0xba,0xbb,0x41,0xdc,0x0d,0xa0,0xbc,0xd5,0x06,0x05,0x9a,0xac,0x9f,0x46,0xec,0xa9,0x1c,0xd3,0x5a,0x61,0xf1,0xba,0x04,0x9a,0x9a,0xc2,0x27,0xf3,0xd9,},{0xc7,0x71,0xba,0x0a,0x3d,0x3c,0x4a,0x7b,0x06,0x4b,0xd5,0x1a,0xd0,0x5c,0x9f,0xf2,0x7f,0xd3,0x26,0x61,0x0f,0xbf,0xa0,0x91,0x83,0x03,0x9e,0x5e,0xdf,0x35,0x47,0x2d,0xde,0xd8,0xfc,0x22,0x75,0xbb,0xcc,0x5d,0xf1,0xbf,0x12,0x98,0x60,0xc0,0x1a,0x2c,0x13,0x11,0xda,0x60,0x2f,0xba,0xff,0xc8,0xb7,0x9c,0x24,0x9c,0x9c,0xc9,0x55,0x02,},"\x34\xdb\x02\xed\x75\x12\xbf\x8c\x67\xd3\x59\xe7\x20\x3a\x2e\xa4\x41\xe2\x0e\x72\x97\x66\xc1\x5a\xa0\x0f\xa2\x49\xa3\x51\x8f\xc2\x9e\xf8\x90\x5a\xa5\xb4\x67\x09\x58\xc6\xa4\x60\xd7\x7b\x3a\x80\xef\xcb\x47\x38\x59\xbb\xaf\xf8\x62\x22\x3e\xee\x52\xfe\x58\xac\xfd\x33\x15\xf1\x50\xf3\xc6\xc2\x7f\xf4\x8f\xca\x76\x55\x2f\x98\xf6\x58\x5b\x5e\x79\x33\x08\xbf\x59\x76\xba\xd6\xee\x32\x7b\x4a\x7a\x31\x32\x14\xb9\xae\x04\xb9\x65\x1b\x63\xcd\x8d\x9f\x5b\x3b\xec\x68\x9e\x0f\xd0\x00\xdd\x50\x17\x70\xdd\x0e\x99\xb8\xf9\x9e\xaf\xa0\x9c\x39\x6a\x24\x5a\x4a\x96\xe5\x68\x96\xa2\x9b\x24\x19\x0b\x1e\xf1\x10\x63\xf3\x9b\x63\xee\x3a\x58\x6b\x07\x62\x7d\xd3\x50\x0c\x4e\x17\x0b\x83\x5d\xc0\xec\x23\x6f\xa5\xa3\x5c\x44\x18\x47\x07\x56\x5c\x4a\x50\x66\x2d\x8d\xbc\xcf\xff\x7f\x9a\x7a\x68\xd0\x21\xb4\xaf\x64\xd5\x32\xb7\xc3\xd2\x74\x74\x18\xc2\xd7\x17\xbb\x6a\xca\x6b\x58\x74\x7a\xe4\xdd\x56\x41\xd8\x26\xf7\x9a\x8a\x31\x5c\x38\x21\x1a\x53\x8a\x92\x9e\x5b\x45\x1f\x62\x3f\x4f\xcb\xbc\xac\xdb\x86\xc8\x75\x2e\xa1\x3a\x61\x7a\xb4\x14\xab\x65\x3e\xb2\xe6\x8d\x54\x20\xdf\x7c\x6d\xf9\x24\x38\x16\x8d\xcf\x9c\x06\x65\x81\xdf\xe7\xb2\xc4\x68\x19\x4a\x23\x70\x7d\xe4\x65\x9b\xd6\x7e\xb6\x34\xff\x02\x47\x41\xc5\xfc\x86\x98\xfd\x4d\xc4\x1f\xe5\xdf\xc6\x29\x9b\x7a\x08\xe6\xff\xca\x37\x10\x9c\x02\x10\xc8\xf9\x4e\xa2\xd3\xdd\xc9\x77\xff\xc0\xb3\x79\x4f\xe6\xba\x43\x37\xc7\xaa\xb4\x34\xa6\x8a\xc6\x65\x48\x4e\xa8\x24\x3a\x84\xb7\x9a\xa1\x81\xee\x6a\xb5\xaa\x37\xa3\x2d\x87\x97\x25\xed\xc0\x18\xf8\x55\x21\x81\x81\x6d\x7d\x27\x2c\xa8\x81\x8a\x7b\x92\xe6\xee\x44\x54\xd1\xf7\x82\x8d\xd8\xaf\xba\x1a\x79\x03\x64\xb4\xff\x28\xd8\x4e\x02\x85\x97\x35\x3e\xbb\xef\x24\x83\x7b\xc3\x19\xe1\xae\x8f\x2b\x0b\x6a\x85\x1b\x48\x9c\x3e\x17\x0e\xef\x53\xe0\x65\xf7\x03\x26\x53\xcd\x6b\x46\xd8\xe5\x7e\x4e\x11\x1b\x78\x9b\xa9\x50\xc4\x23\x0a\xba\x35\xe5\x69\xe0\x66\x15\x40\x34\x07\xbc\xe0\x36\x9a\xaa\xb4\xea\xfa\xef\x0c\xae\x10\x9a\xc4\xcb\x83\x8f\xb6\xc1"}, +{{0xde,0x16,0x34,0xf3,0x46,0x0e,0x02,0x89,0x8d,0xb5,0x32,0x98,0xd6,0xd3,0x82,0x1c,0x60,0x85,0x3a,0xde,0xe2,0xd7,0xf3,0xe8,0xed,0xd8,0xb0,0x23,0x9a,0x48,0xcf,0xaf,},{0x9d,0xc1,0x46,0x5b,0x33,0x83,0xf3,0x7d,0xe0,0x0e,0xa2,0xd3,0xc7,0x0f,0x2c,0x8f,0xac,0x81,0x5f,0x01,0x72,0x02,0x9c,0x3f,0x57,0x95,0x79,0xc9,0x84,0xa5,0x89,0x5e,},{0xd2,0x05,0x06,0xeb,0x84,0x69,0x23,0xa0,0xb1,0x6f,0xf8,0x2f,0xb2,0xc3,0x92,0x3b,0x00,0xc1,0xb3,0xbc,0xc6,0xe2,0xf6,0x48,0x2f,0xba,0x24,0x80,0x75,0x21,0xe8,0xe0,0x22,0x3f,0x69,0x2e,0x62,0xea,0xc9,0x93,0xf4,0x98,0xf6,0x71,0x02,0xa0,0x4f,0xd1,0xac,0xf9,0xc7,0xe3,0x88,0x8d,0x85,0x7c,0x9a,0x08,0x0b,0x8a,0xf6,0x36,0x10,0x06,},"\xd1\x0c\x3e\x4d\xe7\xfa\x29\x89\xdb\xa8\x75\x37\xe0\x05\x93\xd0\xee\xd4\xd7\x5e\xe6\x58\x46\xda\xb1\x49\x8b\x47\x49\xd6\x4f\x40\xe3\x4b\x59\x11\xc5\xce\x3b\x53\xa7\xe3\x7d\x2d\x02\xbb\x0d\xae\x38\xed\x96\x2a\x4e\xdc\x86\xc0\x02\x07\xbe\xe9\xa8\xe4\x56\xec\xca\xe8\xbd\xf4\xd8\x7a\x76\x74\x60\x14\x20\x1a\xf6\xca\xff\xe1\x05\x66\xf0\x8d\x10\xda\xaf\x07\x71\x60\xf0\x11\xfe\xac\xa2\x5b\x9c\x1f\x6e\xca\x9f\xc5\x33\x14\xa8\x05\x47\x95\x17\x54\x35\x55\x25\x25\x7d\x09\xa7\xfd\xad\x5b\xc3\x21\xb7\x2a\xa2\x8d\x1e\x02\xd8\x69\x6d\x4f\x9e\xb0\xad\x3b\x21\x96\xf8\xbc\xfa\xeb\x1d\x61\x48\x28\x7a\x3f\xae\xfe\xf9\x1a\x7a\x3e\x06\x09\xc2\x8c\xe5\x9d\x0c\xa1\x4d\x0b\x30\x50\xdd\x4f\x09\x6b\x7b\xc2\x51\x39\x88\xba\x21\x21\x28\xd5\x02\x6d\xaa\xa7\x18\x88\x46\xdb\x21\xc5\xc1\xd1\x79\xab\x94\x87\xc1\xa5\xbd\x34\x65\x88\x12\x7c\x20\x39\x8d\x36\x2d\x4c\x75\x9c\xfa\xb2\xa6\x77\x75\x0b\x9e\x45\x67\x6a\x1e\x7e\x09\x2e\xf0\x2e\xdb\xf2\x78\xfb\x19\xa5\x8e\x9b\xf6\xc9\xe9\x96\xe2\x4e\xda\xd7\x3f\x3c\xe3\x1f\xa0\x4b\x6d\x85\x33\x43\x6b\xf8\x0b\x4b\x2f\x80\x5e\xd9\x1e\x7f\xcd\xa3\xbc\x2b\xab\x3b\x2b\xb1\x57\x15\x8a\xf0\xea\x8e\x3f\x07\x31\xdf\xad\x45\x9d\x2e\x79\xb6\xd3\x71\x5f\xe7\xbf\x1e\xaf\xc5\x39\x75\x93\x20\x88\x57\xe5\x7b\x7f\xeb\x2f\x73\x87\x94\x3a\x8e\x09\x13\x47\x0c\x16\x1a\xef\x4f\xe2\x05\xd3\x63\x7f\x23\x17\x7f\xf2\x63\x04\xa4\xf6\x4e\xba\x3f\xe6\xf7\xf2\x72\xd2\x34\xa6\x72\x06\xa3\x88\xdd\xd0\x36\x6e\x89\x4e\xaa\x4b\xb0\x5d\x73\xa4\x75\xf1\xb3\x4c\xa2\x22\xbb\xce\x16\x85\xb1\xb5\x6e\x03\x4e\x43\xb3\xc4\x0e\x81\xff\xf7\x96\x82\xc1\x9f\x32\xaa\x3f\x2a\x89\x5c\x07\x09\xf9\xf7\x4a\x4d\x59\xd3\xa4\x90\x29\xec\xfc\xb2\x83\x08\x2b\x06\x7f\x1a\x0d\x95\x05\x75\x0f\xd8\x67\x32\x19\x99\x48\x42\x49\xef\xa7\x25\xf5\x2c\x94\xc7\x59\x62\x06\xa9\x11\xf3\xf5\x05\xd6\x3f\x03\x13\x25\x4b\xd4\x45\xf0\x5b\xe3\x99\x6b\x58\xfe\x18\x19\xaf\x87\x35\x2e\x7f\x0a\x2c\xa3\x20\xd9\xcc\x00\xa5\xfe\x77\xad\x41\x64\x0d\x50\xbe\x84\x36"}, +{{0xc7,0x38,0xef,0x5f,0x09,0x35,0x28,0x1b,0xa6,0x25,0xfa,0x40,0x14,0xd4,0xa4,0xd0,0xbe,0x7e,0x28,0xfe,0xd7,0x79,0xa9,0xcf,0x65,0x8e,0x21,0xdb,0xa4,0x3c,0xeb,0xc1,},{0x95,0x79,0x9f,0xaf,0x70,0x6d,0x19,0x5e,0x54,0x4c,0x76,0xca,0xfd,0xdf,0x09,0xd0,0x2d,0x1b,0xea,0xfc,0x42,0xc9,0xd6,0xc9,0xea,0xd4,0xc1,0x84,0x55,0x87,0xd3,0x9e,},{0xf4,0x43,0x71,0xe6,0xc3,0x39,0x16,0x39,0xd4,0x57,0xed,0x14,0x64,0x81,0x84,0x80,0x94,0x11,0xe8,0x0a,0x32,0x01,0xf8,0x81,0x16,0x70,0xe5,0x00,0xfc,0xad,0x92,0xf3,0x00,0xaa,0xbf,0x7f,0xc6,0x8e,0x44,0x01,0x91,0xe8,0x81,0xd6,0xc3,0x47,0x4e,0xfd,0x6d,0x28,0xf0,0x9d,0xc4,0x43,0x12,0xfc,0xfc,0xb8,0x27,0x01,0xba,0x3c,0x29,0x0a,},"\x16\x8d\x0b\xc5\x59\x8b\xe0\x2f\x54\x43\xbf\xe7\xdf\xb8\x82\x99\x85\xca\x5d\x28\x2a\xf9\xcf\x1b\x14\x82\x60\x2f\x24\x3d\x48\x6b\xd8\x2b\xa0\x39\xa0\x75\x09\x09\xe9\xb3\xc7\xd4\xd5\xf8\xb8\xba\xf4\x57\x18\xaf\x03\x11\x85\x4f\x4d\x1c\x78\x37\xf3\x1d\x8e\xe6\x8d\x35\x58\xe7\xe5\x1e\x0c\x64\x6a\x4a\x63\x75\x96\xee\x90\x05\x7b\x01\xed\x0a\x17\xda\xa3\x95\x0b\x81\xab\x47\xae\x8b\x94\xc1\x7d\x40\x74\x69\x13\xc4\x6b\xa1\x47\x8b\xfc\xa5\x1b\x16\x76\x28\xfc\x3e\xe1\xe2\x2f\x2f\x19\xd6\xd8\xda\xf9\x3d\xf6\x54\x0c\xed\xb7\xa8\x59\xd1\xa2\xba\x59\x11\xba\x71\x76\x6e\x8b\x7f\xce\x0c\x0e\x86\x63\x61\x6d\x01\x80\x69\x7d\x78\xce\x30\x40\xd4\x38\x13\x19\x82\xf3\xf8\x11\x2a\xcc\xa2\x9a\xe5\x3e\x53\x9f\xf8\xc9\xec\x41\x06\xd1\x32\xf4\x02\x01\x85\x18\x30\x84\x85\xf2\xaa\x6c\x9e\x8d\x1e\x62\xfe\xd6\x0c\xb2\x49\x45\x7d\xb3\x3c\x6f\xd1\xfe\x07\x44\x53\x61\xf0\x81\x94\xa2\xb5\xa0\x57\xcb\x03\xcc\x75\x4e\x5c\x7d\x4a\x7e\xea\x53\xa7\xf7\xd2\x07\xca\xcc\xa5\xe6\x8c\xaf\xa9\x69\xa3\x52\x1d\xbb\x81\x03\x99\xa1\x7f\x32\x8e\xe7\x67\xcf\x55\x92\x6b\x2b\xd5\xf0\x29\x54\x9d\x3b\x46\x45\x79\xc4\x26\x55\x26\x53\x98\x47\x2e\x1c\x77\xcc\x8d\xd9\xaf\xf1\x87\xf7\xac\x34\xdd\x45\x6a\xce\x99\x9a\x73\x6e\xcc\xa6\xd4\x05\xd4\x92\x2c\x77\x9c\x60\x0c\x47\xb8\x4c\x9c\x1d\xf5\xe5\xf8\xed\x3b\x28\x11\xd3\x51\x33\x91\x13\xf8\x45\x3c\xca\x4c\x44\x11\x68\x8c\xb0\x38\x82\x58\xeb\xbd\x18\x72\xb8\x36\x10\x04\x22\x49\x49\x4e\xd5\x60\xd4\xcd\xa6\xa6\x84\x55\xd9\x57\xe8\x06\xdd\x0b\xdd\x83\x00\x4c\x4c\xa8\x07\x74\xb8\xa0\xa1\x66\x58\x66\xf1\x70\x85\x01\x4e\xad\xb3\xea\xe7\x38\x2f\xa8\x70\xde\xb2\x9d\xd8\xc9\x31\xb5\x30\x19\x62\x57\x40\xe2\x83\x92\xf3\x85\x75\xc0\xe2\xa9\xe5\x04\xfc\x35\xbd\x95\xdf\x56\x43\x9a\x89\x82\x30\xa2\x39\x8c\xd2\x22\x5c\x76\x6e\xf3\x6f\x12\xae\x7e\x49\xb3\x0a\x9c\x0a\xad\x46\x9d\x58\x95\xbb\xf7\x21\xcc\x0f\xf5\x1d\x84\x0c\x80\x2d\x4a\x7e\xef\xba\x84\xfe\x52\x05\xa2\xc2\xf1\x40\x11\x92\x2d\xde\x56\x14\x56\xf7\x9e\x61\x61"}, +{{0x5f,0xea,0x38,0x73,0x9c,0x61,0xca,0x83,0xbf,0x7b,0x4a,0xd1,0x75,0xa2,0x11,0x76,0x27,0xb9,0x71,0xa6,0x34,0xa3,0x05,0xa8,0x4f,0xa5,0x7f,0xec,0xb8,0x03,0x56,0x24,},{0xdd,0xd1,0x4b,0x0f,0xc0,0x67,0x68,0xd5,0x10,0x4c,0x50,0x76,0x4b,0xfd,0x3b,0x95,0x23,0x52,0xa3,0x40,0x07,0xc5,0x0d,0x5d,0xdd,0x22,0x4f,0xf5,0x1a,0xfc,0xdf,0x9c,},{0xf4,0xe2,0x74,0x82,0x3f,0x2c,0x39,0x6f,0x3a,0x32,0x94,0x86,0xaa,0x64,0x10,0xc5,0xff,0x19,0x26,0x6f,0x07,0x70,0xfd,0x04,0xfb,0x14,0xa7,0x60,0x2d,0x2b,0x69,0xa4,0xa2,0xb0,0x09,0x28,0xe9,0xe1,0xd9,0x23,0x89,0xf8,0x03,0x33,0x59,0xed,0x6f,0xb2,0x14,0x64,0x67,0xaa,0x15,0x4c,0xba,0x59,0x7d,0xec,0x6a,0x84,0x17,0x3f,0x8d,0x07,},"\x10\x13\xc6\x0a\x73\x95\x35\x49\xe5\xed\x10\x5b\xde\xa1\x50\xb9\x1e\x60\xec\x39\x20\x0d\x43\x72\x13\x04\xbf\xc8\xec\x43\x9d\x39\x60\x96\x13\xc2\xd8\x78\x04\x4a\x9d\xa0\x1b\x26\xd8\x6d\x6d\x65\xdb\x93\xd9\x1a\x13\x7e\x9c\x48\x08\xa9\x7d\x4e\xf2\x86\xa9\x03\xf3\xf1\x38\x2c\xc6\xd1\x29\x42\x16\xb9\xfa\xfc\x01\x3c\x86\xb9\xff\x68\xb5\x5a\x50\xea\x37\x66\xe6\x1d\xc1\xce\x38\x34\x8e\x91\xd6\x2c\xe7\x32\xc1\x52\xd7\x66\xb9\x33\x5c\x68\xd6\xca\xd7\x7b\xe2\xb4\xa0\xcd\x50\xb9\xa1\xec\x63\x2b\xa5\x56\x48\xa6\xe7\xe1\x1a\x14\xc0\x68\x53\xc0\x2a\xec\x48\x09\xbd\x14\x7a\x5d\xdd\x9f\xbc\x3b\xe9\xf0\xc8\x15\x8d\x84\xab\x67\x95\xd7\x71\xb4\x2b\x18\x14\xa1\x7a\x3c\x7a\x6c\xa0\xf4\xa8\xf7\xb3\xa0\xdb\x1c\x73\xba\x13\xb1\x64\x00\xdf\xec\xbd\x03\xd2\x16\x65\x0e\x4d\x69\x70\x4a\x70\x72\x46\x44\x4d\x57\x91\xfa\x27\x37\x52\xf5\x9c\xb5\xae\x9f\xd4\x16\xa5\x18\x66\x13\xd6\x6a\xfd\xbd\x1c\xe6\x91\xa8\x7b\xd7\xd8\xb6\x71\x90\xe9\xac\x68\x70\x62\xa0\x80\xd2\xec\x39\xfe\x76\xed\x83\x35\x05\x82\x51\x87\x28\x39\xe8\x5e\xb6\x2f\x18\xec\xe1\x87\xca\xba\x55\xb5\xf7\xd5\xed\xca\xde\x01\xcd\xc5\x43\xcc\x67\x7e\x50\x23\x8b\x89\xc5\x63\x5a\xd5\xc8\xfc\x22\x0f\x5e\x0b\xe1\xbc\x66\x7d\x20\x98\x97\x53\xa6\xd6\x16\xfa\x69\xf8\xb1\x29\x40\xb8\xca\x9e\x2c\x48\x57\x71\x32\xd8\x69\x1b\x05\x37\x79\xa1\x52\xcb\xac\xff\x3b\x8b\x1b\xd7\xaf\x69\x2e\x56\xc7\x3b\xba\xe4\x63\x47\x76\xcf\xc2\x13\xc9\x9b\x9a\xe4\x58\xdf\x1b\xef\xc8\xc8\x77\x74\x26\x64\xb0\xa0\xbb\x1f\x69\x15\xc8\xda\xe3\xb3\xf5\x5d\xd7\x5a\xba\x6a\x3b\xcc\x41\x76\xb4\xe3\xba\x03\xd0\xc1\xc0\x4c\x3c\x64\x08\x77\x8b\x2b\x8e\x5a\x8a\x3e\xb5\x2e\xd3\x2a\x74\x28\xc0\x0a\x98\xa5\x89\xd8\xca\x93\x90\xa2\x10\xf4\xa7\xac\x00\x4f\xa1\xfe\x4c\x6d\xa6\x94\xf1\x22\x76\xe3\x20\xb4\x1b\x0b\x59\xf7\x5d\x26\x4a\x39\x6d\x45\x0b\x63\x1a\xb3\x53\xf1\x61\x27\x09\xe7\xa2\xe6\xa5\x0d\x01\xcb\x11\x0e\x53\x04\x05\x46\xdd\x3b\x1e\x11\xd2\x57\x32\x81\x3a\xa7\x6b\xe5\xe8\x1f\xcf\x7a\x57\x73\xf6\x81\x5b\xbd"}, +{{0x60,0xf9,0xa1,0x4c,0xce,0x5d,0x43,0xfd,0x9a,0xab,0x4e,0xe8,0xcc,0x83,0x79,0xd5,0x75,0x94,0x91,0x52,0x69,0x3b,0xf2,0x9a,0x67,0x90,0xb0,0x35,0xe4,0x2a,0x44,0xde,},{0xbd,0x4a,0x70,0x74,0x0d,0x5a,0xca,0xbe,0x49,0xf9,0xa2,0x15,0x20,0x82,0xfa,0x20,0x25,0x33,0x0e,0x64,0x40,0x43,0x7f,0x1d,0x04,0x7f,0x31,0x3d,0xe4,0x90,0xdc,0xa5,},{0x72,0xf5,0x4b,0xb8,0xbd,0xd1,0x7e,0x9e,0x42,0x2c,0xd3,0x39,0x63,0x1d,0xd3,0x9f,0x57,0x35,0x50,0x15,0xd4,0xcb,0xd1,0x5a,0xca,0xb7,0x54,0x2e,0xfd,0x78,0x4a,0x32,0x1c,0x1f,0x61,0x25,0x76,0x4c,0x0d,0x15,0x40,0x45,0xb3,0x2e,0x70,0xdc,0x2e,0x03,0xfb,0xfe,0x11,0x17,0x46,0x8a,0xc3,0xe7,0x31,0x27,0xb5,0xfa,0xc8,0xd4,0x21,0x02,},"\xdd\x7f\x44\xf9\xeb\x72\x8a\xb4\x8d\xe5\x4e\xcd\xe6\xb6\x18\x4b\xd5\xdd\xd8\x70\x75\x45\xa0\x12\x9f\x2e\x90\x59\x05\xb5\x5d\x3e\x7f\xd5\x7e\x28\x48\x5d\x25\x81\x48\xf6\x60\x5e\x23\x77\xd5\xb2\x67\xd2\xea\xf4\xcd\x4b\x46\xe4\x54\x96\x22\x19\x86\x82\x32\xb6\xf4\x1f\x88\xa7\x97\xf9\xcd\xd5\xc3\x9a\xda\x51\xa6\x41\x21\x4f\xb9\xdb\x2c\x2a\x9b\x5a\x5b\x16\xe3\x03\x57\x53\x18\xb6\x25\xcc\xa9\x70\xb7\x43\x48\x72\x79\x02\xa1\xcf\x26\x8b\xd1\x6e\x10\x71\x13\x16\x1c\x8c\xbc\x99\x30\x3c\x2b\x9f\x23\x55\x41\xa7\xb3\x1e\x43\x31\x20\xfe\xba\x14\xfe\xbe\x4b\xcb\x0f\x5b\x93\x6c\x7e\xdd\xdd\x0e\xcf\xc7\x2c\x8d\x38\xf6\x4c\xdb\x6c\xfc\x29\x10\xbc\x29\xa5\x21\xc5\x0a\x51\xab\xcb\xc2\xaa\xbf\x78\x9d\xe8\x22\xcb\x04\xf5\x72\x8f\xee\x15\x3d\xd5\x50\x1b\x2d\xb5\x9c\x59\xf5\x0c\xab\x17\xc2\x92\x16\xd6\x69\x51\x01\x9e\x14\x5b\x36\xfd\x7e\x84\x1b\xfb\xb0\xa3\x28\x55\x4b\x44\xdd\x7e\xf5\x14\x68\xc3\xd5\xb7\xd3\xa1\xf7\xb9\xde\xf5\x8d\x8c\xf9\xd9\xbc\xaf\xe9\x2c\x86\xcf\x6d\x61\x19\xe9\x8d\xba\x6f\x38\xea\x57\xe3\x22\xdd\xc9\xc2\x19\x8d\x4b\xbc\x3b\x94\xea\x13\x29\xdb\x0d\x45\x8e\x01\xc7\x08\x1b\x33\x92\x5a\x3e\x28\x7f\x59\x9a\x85\x8c\x50\xc3\xa8\xf1\x8c\xc2\xaa\x63\x4d\xf6\x3e\x7f\x10\xe4\x03\xad\xea\xb2\xf4\x1d\xb5\x57\x87\x90\xc3\xb4\xf0\x41\xa8\xb7\xa4\xf6\x9c\xd6\xe0\x62\x15\xdf\x82\x01\xae\x5b\x3e\x1d\x1d\x25\xa0\xa3\x9b\xfc\x3d\x04\x1a\x2f\x98\x21\x3e\xf4\x14\x12\x45\x79\x2a\x76\xf0\x6d\x4d\xe2\x5f\x64\x67\xa0\xe5\x6f\x2f\x5c\xf6\x94\x00\xd2\x21\x17\xde\x7b\x46\x14\x95\x54\xb7\x0c\x75\xb9\xf9\x94\x84\xa4\xf6\xf0\x35\xad\x3f\x10\xe3\x75\x3c\xb1\x4f\x4f\x39\x8d\xcf\x6a\x64\xd1\x0c\xf6\xc4\xfa\xc0\x7c\x91\x19\x3c\xc0\xf5\x4f\x0d\xe5\x8c\x63\x43\xe9\xca\xaa\x6b\x4f\x47\x5e\xf9\x1a\x59\xe0\x83\xf9\xf2\x11\xf5\xbc\x8e\x7e\x45\x16\xb4\x5c\xf0\x6b\xf5\x0b\xeb\x8f\xc4\xab\x57\x9d\x86\xd4\xa4\x19\x0e\xea\xc7\x48\xd0\x6e\x08\x52\xc4\xb9\xba\x8c\xfc\x50\xdd\x0a\x03\x7a\x7b\xad\x7f\xad\x55\xaf\x30\x9a\x5f\x13\xd4\xc9\x1e\xd3\xe0"}, +{{0xa3,0x90,0x53,0xc5,0xc5,0x8b,0xf3,0x1d,0x46,0x2b,0x27,0xa6,0x20,0xb0,0xb3,0x7b,0x80,0x52,0xc6,0xb1,0xc4,0x10,0x2b,0x61,0x45,0x66,0x3a,0xa1,0x5e,0x97,0x87,0x18,},{0x36,0x42,0xac,0x2a,0x32,0x80,0xdc,0xe5,0x2a,0xd8,0xdf,0xcf,0xd3,0x70,0x94,0x36,0xed,0xc4,0xe7,0xe4,0xae,0x1b,0x45,0x2d,0x9b,0x22,0x07,0x80,0xb0,0x86,0x79,0xfa,},{0xf7,0x38,0x3e,0x96,0x6c,0xb2,0x30,0x9d,0xee,0xdf,0x86,0x01,0x00,0x18,0x3a,0xae,0xfa,0xc6,0x72,0xca,0x16,0xd5,0x41,0x9c,0xd6,0x42,0x2c,0xa7,0x0e,0x16,0xb3,0x97,0x6f,0x5f,0x16,0x5a,0xfc,0x27,0x86,0x11,0x7c,0x86,0x82,0x34,0xba,0x11,0x09,0xed,0xe0,0x31,0xf8,0x97,0x9b,0x50,0xe5,0x67,0x35,0x8b,0xd4,0xf8,0xbd,0x95,0x82,0x02,},"\xf6\x55\x40\xd3\xab\xeb\x1e\xe5\xea\x98\x70\x62\xc1\xb5\x79\x51\x6d\x3c\x29\xc3\x9c\xbc\x6b\x09\xd6\x0e\x18\xfe\x27\x4c\x2b\xef\xe0\xf5\xfe\x7d\xbd\x57\xc2\xd5\x83\x52\x29\xbb\x75\x4e\xc4\x34\x13\x94\x76\x57\x76\xd6\xa9\x17\x8c\x4e\x6a\x31\x2c\xd7\x4b\xdb\xac\xa0\xe8\x82\x70\x62\x8c\xd8\x41\x00\xf4\x72\xb0\x75\xf9\x36\x92\x83\x01\x22\xf0\x0f\x9b\xd9\x1a\xc5\x82\x83\x6c\x8b\xfa\x71\x4a\xa4\x8e\x97\x70\x03\x55\x6e\x1b\x69\x6d\xf3\x28\xef\x58\x4f\x41\x3f\x8a\xb6\x14\x76\x06\x99\xc4\xd1\x47\xc3\xee\xa1\xda\x04\x35\x83\x5c\x9b\xf7\xad\x54\x60\x6f\x02\x13\xeb\x74\xa1\xb4\x76\x14\x15\x06\xae\x2c\xd1\x24\xcd\x51\xd6\x6e\x7e\x7e\x57\x95\x60\x57\x63\x05\xc5\xfb\xe8\x43\x0b\xe3\xeb\xeb\xaa\xcb\xa3\xf9\x98\x9d\xd7\xd1\x99\xf5\xa4\x55\xa5\x0c\xdb\x37\x55\x03\x7e\x1a\x70\x67\x4a\x4f\xef\x40\xb4\xa3\xaa\xf7\xbd\x3c\x95\xb1\xab\x41\xbb\x20\x62\x11\xc3\xa1\x27\x6d\x3e\x37\xd8\xa3\xa5\xc3\xd5\xd0\xf3\x6e\xf5\xb4\xf3\xde\x26\xb7\xf2\x0f\x6b\x29\x00\x71\x6d\xcc\x22\xab\x73\x4e\xba\xf1\xe8\xd0\x00\x20\xe5\xf0\x19\x55\x16\x53\xb9\xc2\xf7\x0a\x40\x38\xdf\xb2\xf1\x2d\x25\xd6\xd8\x4e\x79\x07\x3a\x65\x48\xfe\x15\xe4\x82\x8f\xe5\xde\x83\xac\x3d\x8d\x98\xb7\xda\xf9\x27\x10\x48\x2c\x37\xf7\xbd\x24\x31\xa8\x11\x4c\x61\x37\x65\x7b\xb1\x77\x88\x2d\x8a\x3c\x76\xba\xbf\x1c\x67\x1a\x70\x55\x36\x5f\xe9\x08\x66\x16\x7a\x2d\x1d\xbc\x87\x0b\xe8\x3b\x36\x01\xf0\x9d\x4a\x31\x7a\xe2\x54\xca\xc9\xf9\x8d\xcc\x7a\xea\xd9\x22\x4c\xd9\xc9\xd8\xa2\x00\xab\xc8\x0a\x2d\xd1\x08\xaf\x28\xfd\x46\xad\x70\x80\xae\x74\x1b\x50\x05\x4b\x9b\x9a\x92\x01\xef\xb7\x83\x8b\xc4\xc5\xc2\xcc\x3d\x76\xba\x0f\xcc\x49\xc4\x6e\x79\x2c\x26\x29\x2b\x7d\x03\x12\xaf\xf9\x55\xa9\xf8\xed\xf0\xc6\x96\xa7\x0a\x61\x4f\x35\x53\xad\x38\x69\xbf\xde\x48\xd2\x6a\x4d\x36\x7b\x6c\xec\x05\x7e\x62\xa4\xe5\x48\x55\x4b\x48\xb5\x3e\xcd\xa7\x90\xba\x7a\x0a\xb2\xe3\xde\x58\x7b\xdc\x22\xb0\x2f\x59\x47\x63\x4d\x73\x09\x9f\x54\x7d\xb2\x2e\xc1\xbb\xf8\x23\x43\xf9\xa2\xca\x38\xbc\xe4\xeb\x59\xbe"}, +{{0xe0,0xc2,0x9d,0xf4,0xde,0x45,0xc4,0x75,0x39,0xe0,0x89,0x6b,0x3a,0x59,0xbc,0x3d,0xe6,0xb8,0x02,0xfd,0x14,0xdb,0xdc,0x9f,0x25,0xe7,0x17,0xac,0x82,0xc3,0x28,0xf3,},{0xa6,0x90,0x02,0xb0,0xf5,0xef,0x35,0x4c,0xe3,0xb2,0xd6,0xb8,0xd8,0xba,0x70,0xab,0x77,0x84,0x32,0xb2,0x2f,0x14,0x4d,0xc9,0xc2,0xeb,0x92,0xd9,0x9d,0x99,0xdd,0x2a,},{0xbb,0x3b,0x8c,0x5c,0x27,0x59,0x1f,0xd8,0xb9,0xc5,0xba,0x48,0x9d,0x6b,0x6e,0xe5,0xb0,0xfb,0x4a,0x7b,0x0d,0xe5,0x1f,0x16,0x39,0xaf,0xc6,0x73,0xd0,0xe5,0xf7,0x5e,0x31,0x3a,0xa7,0xe1,0xd0,0x00,0x90,0x81,0xdb,0xca,0x74,0x35,0xb6,0x87,0xcc,0xd1,0x2f,0x64,0xf7,0x4a,0x38,0x6e,0x77,0x2b,0x9e,0x24,0x78,0x1b,0x92,0x5c,0x8c,0x0c,},"\x6a\x37\xcb\x4c\x74\x9c\x58\x35\x90\xc8\xd8\x49\xbc\xe3\xfa\x65\x7f\x10\x00\x91\x90\xca\xd9\xbe\x41\xed\xe1\x9b\xf2\xfd\xb3\xc5\x62\xa6\x10\x1f\x27\xbd\x37\xf2\x23\xca\xb1\x3c\xed\x24\x5a\x1c\xed\xf8\x52\xf5\x51\xf8\x57\xaa\xd9\x72\x7f\x62\xc9\x67\xc0\xa9\x21\xdf\x11\x6f\x48\xa8\x0a\x60\x40\xb3\xc7\x23\xab\x5c\xb5\x94\xc4\x50\x7a\x3d\x20\xcd\x60\x51\x4e\x22\x16\x4a\x82\xb7\x4f\x19\xdc\xfd\xd8\x3c\x57\xbc\x36\x52\x37\x55\x17\x41\x4a\xf5\xd1\x8e\x0a\x64\xcc\xab\x36\x69\x97\x68\xd0\x7c\xf4\x0b\x70\x63\xa8\x3e\x43\xd5\xf6\x07\x96\x4b\x1b\xf0\x84\x0a\x45\xad\x50\xab\xf8\x3d\xbc\x84\x9f\x40\xe5\xb4\xcf\xb6\xa3\x34\x7b\x29\xfe\xc5\x07\x74\x04\x6a\x4b\x50\x04\x10\x32\xaa\x4d\x56\x7e\x85\x64\xb3\xee\xd1\x64\x20\x40\x68\x2d\xd8\xae\x7d\x71\x79\x28\x6c\xf6\xe1\x85\x3d\xc8\x7d\x27\xc3\xe9\xe6\x0f\xa4\x7c\xf8\xcb\x2d\xa0\x18\x1d\x53\xee\xc4\x06\x14\xb0\x73\x31\xa4\xfb\x70\x28\x08\x6d\x0b\x1c\xe2\xe1\x11\x5b\x73\xa1\x62\xc5\x27\xbd\xd7\xca\xb5\x33\x5b\x86\x3d\x10\x8b\xe0\x47\xbd\xbc\xa1\x12\xcc\x6e\x77\x6b\xb4\x53\xc3\x17\x31\x43\x88\xbb\x96\x53\xef\xb4\x44\x4b\xf5\xcf\x1e\xc8\xda\x23\xb7\x11\xba\x71\x79\x6c\x0a\xe0\x2b\xa1\xdc\xc8\x38\x45\x50\x78\xc3\x89\x7f\x07\xe9\xe1\x3b\x76\xe4\x92\x74\xc2\xe2\x07\x50\x6b\x00\xa0\xb5\x58\x88\x3a\xa1\x22\xb6\x67\xdb\x9d\x67\x05\x08\x60\x6a\x3f\x54\x32\x06\x36\xcd\x19\xf9\x73\x91\x7f\xb1\x87\x5f\x43\x63\xe2\x20\xf1\xe1\x23\x98\xcc\x6a\xfd\x79\x09\x47\x43\x33\x84\x56\x81\x3a\x58\x26\xad\x3f\x1a\xba\x7c\xd7\xbe\xab\x1f\xe1\x83\x85\x9c\x0c\xc9\xef\x40\xa5\xea\xb9\x12\xca\xf5\x15\xa8\xd4\xc3\xb9\x3d\x64\x1b\x7a\xb3\xe7\x6b\x16\xc1\x29\x71\xac\xe8\x8f\xf3\x3e\x5a\x1e\xd9\xb4\x4e\x45\xdb\x8f\x30\x85\xdb\xf0\x70\xb2\x56\xb0\xd7\x51\x2e\xe1\x06\x94\x32\x60\x3d\x73\x09\x5d\xb8\x74\x9c\xa5\x47\x96\x3b\xd7\x1a\x8a\x68\x4a\xb8\x51\x6b\x14\x6c\x41\x87\x17\x63\x86\xaf\xdf\x6c\xb1\x36\x8a\x3d\xd8\xfc\xb2\xcf\xff\x77\x05\x6a\xaf\x78\x23\xf8\x00\xb2\x66\xac\xce\x72\xbf\x64\x3c\x6d\x0c\x28\xf0\xab"}, +{{0x19,0x8b,0x5f,0xd1,0xc0,0x38,0x27,0xe0,0x99,0x4a,0xd5,0xbf,0xee,0x9b,0x5b,0x7b,0xe9,0x96,0x6c,0x9c,0x3a,0x26,0x7e,0x4d,0x74,0x30,0x34,0x37,0x67,0x40,0x3c,0x67,},{0x66,0x82,0xc6,0xf1,0xa8,0x66,0xb4,0x9b,0x2f,0x8e,0xe9,0x7f,0x2e,0x53,0x2f,0xa9,0x16,0x66,0xbf,0x38,0xda,0x1b,0x4d,0xd6,0x55,0x43,0xa1,0x77,0x77,0x94,0xcb,0xee,},{0xf4,0x54,0xf3,0x5b,0x18,0x53,0x8f,0x87,0x7e,0x5d,0x61,0x4a,0x76,0xb5,0x27,0x6a,0x27,0xfc,0x0b,0x43,0x3f,0x21,0x5d,0xc4,0xe9,0x63,0xb3,0xf0,0x47,0x69,0x4c,0x78,0x0c,0x51,0x5c,0x6e,0xf6,0xfe,0x2d,0xb4,0xb0,0x09,0x00,0x9b,0xc2,0x73,0x3a,0xec,0x4f,0xd4,0x6e,0x61,0x53,0x57,0xcc,0x0b,0xcc,0x9f,0x1f,0x7f,0xc2,0x1e,0x3c,0x02,},"\x3f\xda\xa1\x5c\x46\xf2\x51\x43\xdb\x97\x20\x79\xd7\x01\x3c\x7f\x69\xa1\x36\xf4\x5f\x3f\x6b\xa2\xce\xd8\xb8\x28\x46\x8e\xb3\xda\xa6\xb5\x0b\x4f\x8d\x33\x80\xfe\xc6\x4a\x03\x43\xbe\x11\x6f\x6f\x83\xb6\xee\x64\xcc\x4c\x1b\x1d\x08\xd5\x4f\xd4\x20\x29\xe4\x28\x5c\xfc\x6c\x6d\xd5\xcd\x18\x1a\xb5\x33\xff\xcd\x41\x1f\x23\xa1\x00\x3d\xa9\x4e\xc9\x34\x0e\x2e\xc7\x11\x99\xd6\x78\x54\x0d\x51\x82\xe1\x39\xff\xcb\xc5\x05\xa1\x70\xb8\xf0\x7f\x4a\x7e\x69\x4c\xa9\x2f\x58\x32\x0c\x0a\x07\x85\x64\xce\x9d\xe9\x9b\x0f\xa8\xe6\x6b\x0d\x82\x2e\x46\x7a\x5a\xeb\x83\x56\x79\x96\xa4\x8b\x89\xdb\x25\xca\xde\x64\x57\x79\x4e\x54\x14\xd6\x7e\x9d\x4a\xb7\xcd\x6c\xc2\x05\x8b\xb7\xa5\x13\xab\xd7\x09\xf4\xca\xf2\x4b\xb6\x7c\xe1\xc0\x3a\xb6\x2d\xbd\xfe\x30\x9e\xc7\xdb\x0f\xa3\xea\x7a\xae\x82\x36\xf2\x59\xb9\x22\xd4\x53\x61\x15\xa6\x3b\xc8\x9a\xcb\x20\x51\xd0\x9e\x73\x1c\xbb\x0d\xf1\x57\xd9\xd3\x45\xbd\x91\x09\x97\x3c\x2b\x59\x4f\x14\x8e\xfc\x6f\x33\x77\xde\x51\x63\xb7\xf6\x98\x69\xff\xef\x85\x3e\xae\xfe\xb4\x02\xe2\x35\x29\x59\x4f\xbd\x65\xca\x05\xfe\x40\x62\xc5\x29\xd8\xe3\x21\xab\xc0\x52\x00\xca\xc1\xe8\x39\xe8\x7b\x1f\xd3\xfd\xf0\x21\xd6\x8c\xbb\x3a\x41\x42\xb6\x9c\xc3\xaf\x6f\x63\x2e\xdd\x65\xb8\x3f\x5a\xa4\xcb\x17\xda\x5b\x6b\xa3\xfc\x03\xed\xb1\x7c\x2a\x3c\xb5\xb0\x48\x36\xe7\x66\x0e\x63\xc8\xa0\x48\x3e\x24\x39\x83\x37\x1d\xfa\x98\x39\xf9\x16\x4a\xd4\xda\x0d\x59\x53\x65\x5e\x3a\x95\x18\xe1\x36\xda\x74\x57\x37\xc7\x92\x43\xc3\x55\xfc\x12\x5c\xbd\xcc\x76\xae\xc9\x22\x16\x84\x6c\x45\x74\xf4\xf7\xf2\x98\xbc\xde\x54\xfd\x24\x44\xad\x30\x25\x95\x5c\x10\x03\x15\xde\x5a\x4e\x27\xc3\x33\xa0\x02\x84\xb2\xf7\x02\xfd\xd3\xde\x22\xac\x6c\x24\x0d\xbc\x14\xbf\x71\xe6\x2d\x13\x1b\x62\xf2\xdb\x99\x24\x73\xf2\xf9\x13\xf6\x0c\x91\x6e\xcf\x57\xdf\x5f\x3f\x02\x1f\xb3\x30\x83\x43\x95\xb7\x94\x72\xca\xff\x19\xfc\xfa\x0a\x27\x17\x95\xc7\x6d\x69\xb4\xdb\x3f\x85\xb8\xd2\xe5\xc3\x44\x19\x65\x48\x4d\xcc\x39\xab\xa5\x9b\x70\x12\x74\xf7\xfc\x42\x52\x46\x85\x60\x69"}, +{{0x43,0x92,0xf7,0xd4,0xfb,0xd6,0x8f,0xe1,0x54,0xe4,0xba,0x38,0xad,0x52,0x07,0x61,0x2a,0x06,0x48,0x55,0x60,0x56,0xc3,0x9a,0xc1,0x16,0xad,0x46,0x8f,0x89,0xbd,0x2d,},{0xcb,0xea,0xef,0x41,0xac,0xac,0x02,0xbf,0x1f,0x78,0x0c,0xe9,0x34,0xaa,0xbd,0x63,0x13,0x64,0xb3,0x69,0x56,0x7b,0xe1,0xbe,0x28,0xe3,0x90,0x6f,0x9d,0xb1,0x20,0xfa,},{0x86,0xe7,0xcc,0xf0,0x6e,0x79,0x36,0x2d,0x40,0xcd,0xb7,0xfb,0x75,0xa9,0x89,0x78,0xbb,0xd3,0x34,0xa1,0xdb,0x75,0x90,0x36,0x7d,0x60,0x84,0x9b,0xd5,0x3e,0x2f,0xb1,0xa4,0xbd,0xae,0x59,0x0d,0x1f,0x47,0xb5,0x49,0x0d,0x87,0x02,0xe7,0xc1,0xa8,0x72,0x68,0xb8,0xee,0x9d,0xb6,0x12,0xde,0x7b,0xdc,0x2e,0x38,0xfa,0x6d,0xeb,0x7e,0x05,},"\xcf\x17\x09\xdc\x9a\x08\x67\xee\x90\x87\x21\xb1\x36\xcb\x93\xa8\x42\x29\xe8\x3b\x46\x20\x47\x77\xca\x81\x94\xd0\x8b\x7a\x3c\xa9\xc9\x12\xeb\x24\x3e\x5b\xda\xbf\xee\xd3\x52\x34\x9d\x20\xbe\x80\x1b\x72\x2a\xf0\x89\x22\x38\xe7\x2e\xdf\x19\x0e\x63\x61\xf5\x75\x72\x78\x1a\xd3\xc2\x59\x0b\x19\x73\x57\x64\x1c\x80\x53\x83\xba\xa1\xd4\x97\x2f\x76\xc6\x54\x48\x53\x2c\x11\x08\x34\xa0\xba\xa8\xf4\x88\x63\xe1\x66\xb7\x06\x65\x37\x08\xcd\x40\x57\xd3\xa4\xf9\xfc\xb2\xce\xb4\x12\x00\x01\x27\x7d\x38\xc4\x38\x47\xd8\x22\x82\x2b\x77\x7c\x2b\xb4\xda\x40\x15\xa1\xc2\x4d\x41\x6d\x50\x62\xa8\x71\x84\x91\xd8\x55\xaa\xa5\xdb\xf5\x57\x9c\x16\x4d\x8e\x52\x4a\x9f\x2f\xa3\xf2\x2e\xb0\x98\x61\xff\xe6\xad\x65\x9f\xe3\x6e\xb4\x04\x31\x22\x2c\x22\xd7\x13\x7a\x6c\xab\xca\x8d\xb7\x86\xe3\x9d\x81\xf6\x61\xaf\xde\x4e\x39\x58\x9b\x4d\xb4\xd3\xc5\x1c\xa5\x35\x90\xa1\x4e\x11\x5d\x0a\xfc\x3a\x87\x7b\x83\x9a\x96\x38\xbe\xce\x80\xc3\x2c\x19\xe5\x1b\x75\x32\x02\x48\x45\xf7\x6c\xfe\x9b\xfb\x2a\xc0\x51\x30\xf6\x75\x8b\xf7\xfe\x99\x3a\xa9\x3a\xa2\x72\xe4\xe6\xbd\x0c\x75\xc1\x40\x99\xd4\x3e\x65\x2a\x22\x3e\x5b\xcd\x64\xc3\x62\xd4\xb8\xf4\xb9\x5e\x01\x6f\x93\x50\xc7\xfa\x74\xe6\x53\x52\x5d\x08\x01\x15\x58\xb2\xc6\xe9\xbf\x4f\xdf\x9d\xbd\x5e\xf9\xb0\x9b\xbc\x84\x6a\xfc\x2b\xcb\xc8\x6c\x4c\xcc\x31\x5f\x6d\x1c\xcd\x48\x9b\x0c\xf8\xed\x0d\x93\xf2\xf5\x32\xa4\x26\x26\x5c\x59\x0b\xa3\xa5\x90\x23\x34\x7d\x81\x9d\x9b\x28\x1e\xf8\x53\x10\xb0\x53\x16\xd4\x6c\x8a\x8c\x03\x65\xd0\x68\xa8\x70\x86\x64\xea\x4d\x77\xac\x0c\xd1\x50\xa6\x5a\x56\x58\x6b\xab\xd3\x4b\x74\x36\x5b\xb8\xfe\x3e\x61\x87\x26\x22\x84\xd6\x44\x32\xe4\xc8\x1e\xa4\xc0\xe5\x7c\x1d\x71\xae\x98\x0c\x7f\x4d\x1d\x87\x10\x32\xe1\x88\xbb\xf9\xd1\x75\x8c\xdc\x1d\xff\x98\x9f\x2d\x12\x88\xfe\xf4\xe2\x05\xe9\x9e\x7c\xbf\x2c\xc3\x24\xb8\xc9\x30\x46\xf4\x76\xc5\x9d\x3d\x0a\x59\xdb\x6f\xe3\x73\x82\xdc\x79\xc5\xec\x16\x05\x6a\xb3\x93\x4a\x52\xf7\xd2\x88\x0d\x04\x71\xa3\x77\xb6\xa8\xae\x84\xd5\x6a\xc2\x2d\x1d\x54\x55\x1c"}, +{{0x0b,0xea,0x98,0xab,0xe7,0xd6,0x3f,0x15,0x83,0x90,0xee,0x66,0x8a,0xa0,0x50,0xe8,0x4a,0x25,0xd2,0x89,0x3e,0x49,0xfc,0x83,0xf0,0x79,0xf9,0xbb,0xa6,0xa5,0x5a,0x75,},{0x22,0x19,0x2e,0xc0,0xd3,0x2e,0xf9,0x83,0x56,0x65,0xa6,0x1b,0xc8,0x8b,0xcf,0x4e,0x16,0x04,0x63,0x79,0x21,0x15,0x2c,0x11,0x6a,0xf5,0x03,0x36,0x5b,0xf6,0xbe,0x42,},{0x7e,0xb3,0x13,0x9b,0x88,0x0f,0xdf,0x66,0x37,0x6a,0x20,0x90,0x81,0x88,0x40,0x04,0x97,0x67,0xc8,0x37,0xf3,0xad,0x00,0x36,0xb1,0x41,0x66,0x70,0x52,0xb3,0x36,0x09,0x81,0x7c,0xa5,0xe2,0x40,0xed,0x8c,0xdf,0x3c,0xcf,0x3a,0xee,0x29,0x27,0x45,0x34,0x59,0x4d,0xb0,0xb4,0xcc,0xc5,0xc6,0xe5,0xbb,0xa3,0x28,0x0b,0x87,0x3f,0x29,0x01,},"\xc1\x78\xe3\x8d\x4e\x83\xed\x2b\xe5\x7c\xe1\xc3\xab\x64\x25\x3a\x81\x71\xe6\x10\x00\x81\x81\xfb\xfc\x6d\x75\x22\x69\xf7\xf1\xc5\xa9\xec\x62\xcb\x27\xf1\x9a\xd9\x9c\xe1\xf5\x11\x6a\x36\x3d\x96\xfd\xc5\xa4\x2f\x35\x8b\x6d\xbe\x7c\xab\xdf\xc9\xf6\x07\x18\xe4\x01\x2c\x1b\xb1\xf8\x42\xc5\x56\x08\x11\xba\x83\x74\xa0\x63\x77\x47\xff\x92\xea\xc2\x1c\xa6\x5d\xde\xaf\x43\xe9\x98\x9b\x7d\xe2\xd4\x32\x52\x0a\xfe\xe3\x64\xec\xfb\xa4\xda\x66\x9a\xd4\x89\x3d\x0b\xf6\x9f\x9f\x81\xe7\xdf\x69\x65\x7b\xe2\x2b\x92\x06\x97\x45\xf2\x16\xc2\x42\xcc\xd4\x6d\x02\xd3\x56\x16\xe1\x6c\x75\x5e\x0e\x37\xf9\x61\xa6\xf3\x63\x77\x52\x53\x4f\x6d\xfa\xb8\x80\x5a\xb7\x59\xa0\x32\xa4\xe7\xe4\xc8\x19\x53\x32\x5a\x2f\x68\x6b\xb6\x9a\x02\x9c\xe4\xe0\x3b\xec\xb3\x60\x56\x37\xc5\xa6\x5b\x52\xe3\x31\xc2\x6c\x92\x6e\xd4\x71\x1a\x50\x4d\x37\x33\xbb\x53\xc9\x7b\x80\xea\xfe\x4e\x75\xdd\xd9\xf4\x15\x36\x28\x88\xc3\xd4\xd3\x7b\xae\x0e\x63\xfa\x11\xbf\x75\x56\x66\x43\x7d\x72\xf5\x8c\x91\xd7\xa2\xf8\xcb\x61\x9b\x76\x20\xa0\x70\xb2\x6b\x18\xb4\xd5\x01\x84\xc5\x81\x87\x12\x11\x0e\x36\xd3\xe2\x83\x0f\x6a\x85\x76\xba\x57\xf9\xcc\xcb\x8f\xff\x40\x28\xbf\x8e\xf9\xcb\x81\x48\x25\xbb\xca\x82\x7d\x64\x95\x47\xbf\x6f\x2b\xef\x93\x17\x04\xca\x7f\x6d\xf1\x5f\x78\x01\x55\xed\x46\xea\xa7\xca\x7d\x72\xe2\x24\x34\xca\x04\x83\xbf\xb2\xf7\x90\x2d\xc7\x87\xf6\x17\xeb\x9b\xd4\x1e\xd4\x52\x0a\xdf\xd4\x30\x94\x8c\x71\x08\x05\xa7\x3c\x1b\xa5\x49\x2e\x96\x48\x4c\x4b\xaa\x7d\xa2\x4c\x74\x35\xc4\x6a\x05\x2b\xf3\x51\x5d\x33\xe4\x2d\xce\xf5\x17\xca\xa4\x5f\x36\xc8\x79\x12\x10\x78\xc6\x88\xdd\x10\xd7\x66\x56\xa1\x19\x76\x2b\x6a\x83\x41\x36\xfa\x1f\x8a\x64\x32\x24\xb9\x22\x4c\x54\x3c\xf0\x47\x0b\x3f\x8e\xe0\x17\xd6\x20\xdb\xdc\xc8\x4d\x98\x51\x54\xe9\xd1\xae\x80\xe5\xf1\x43\x87\xb8\x8a\x0f\x6a\x5c\x35\x90\x5a\xa5\x7f\xb3\xab\xeb\x0e\xa6\xec\xcd\xdb\x00\x44\x74\x63\x3c\xc4\x83\xb5\x6b\x8a\x8e\x20\xe8\xf2\xe0\x9e\x97\x9a\xa0\x98\x93\x08\x78\x75\xc6\xb1\x17\xb5\xf1\x38\x47\xad\x8f\xc0\x56\x04\xc4"}, +{{0xc2,0x58,0x78,0xb0,0xd1,0xe0,0x92,0x5c,0x8f,0x5f,0x04,0xa1,0xe5,0x79,0x90,0x80,0x96,0x3c,0x41,0x3a,0x13,0x99,0xc1,0x18,0xaf,0xb1,0x68,0x7c,0x79,0x7f,0x48,0x39,},{0x13,0xac,0x2c,0xad,0x41,0x90,0x8c,0x25,0x5f,0x67,0x1f,0x93,0x93,0x4a,0xe5,0xd7,0xbe,0x32,0x53,0x46,0x72,0x5c,0x8b,0x40,0xdc,0x39,0xea,0x80,0xd7,0x0d,0xdf,0x34,},{0x06,0xf5,0x51,0x98,0xb4,0x19,0x19,0x14,0xb7,0x43,0x06,0xf3,0x8e,0x38,0x13,0x16,0xea,0xc4,0x0b,0x5b,0x5a,0xdb,0x8a,0x31,0x24,0x64,0xf6,0x71,0x75,0xec,0xf6,0x12,0xe0,0x14,0x7b,0x1c,0xef,0x46,0xc2,0x51,0x87,0x50,0xa5,0x60,0x6b,0xb0,0x3b,0xc6,0x46,0x7b,0xb9,0x32,0x15,0x14,0xf6,0x9d,0xcb,0xeb,0xce,0x8f,0x69,0x05,0x80,0x02,},"\x68\x56\xcc\x71\x44\xb6\xbd\xdc\xc4\xb5\x89\x54\xd1\xa2\xe7\x10\x1d\x65\x84\xb5\xd5\xe7\x19\xa0\xae\xa0\xfb\xbd\xf2\x21\xc2\xa2\xaa\xcb\xac\xdc\x40\x20\xc5\xc8\xce\x68\x1f\xf7\x38\x1a\xcd\x60\x7b\x0f\x52\x39\x69\x23\x35\x70\x06\x55\xbe\x2d\x94\xc5\x3d\x7b\x51\x48\xe9\x2a\x2b\xc1\x63\x38\xc2\xf4\xc1\xa7\xd1\xc5\x95\xaf\x62\x2c\x24\x0c\xe5\x79\xa5\xe0\xf5\xb6\x51\xbf\x56\x25\x18\xce\xc8\xaa\x2c\xe4\xb4\xaa\xdb\x1f\x2f\xda\x6c\xf6\x29\x5b\xc3\x78\x03\xb5\x37\x7d\xab\x65\xc9\xb9\xa2\x94\x9f\xdd\x49\xbf\x9d\xdc\x8f\x96\xd2\x60\xff\x95\x1b\xf8\xe8\xcc\xf9\x82\x7e\x68\x69\xc4\x4b\xfd\x97\x33\x58\xce\xfd\xb0\x10\xdb\x5e\x1f\xe5\xdb\xd9\xf5\xd2\xb2\xca\x39\x3c\x17\xd4\x46\xf6\x37\x05\x9e\x69\x2d\x7a\x91\xaa\xdc\xc7\x68\x9f\x5f\x9e\x1b\x30\x52\x17\x5d\x9b\x6b\x20\x8f\x90\x26\x78\x7f\xdb\x66\x78\x3f\x45\x37\x2a\x24\x94\x6b\x1b\xd1\x68\x7b\xf0\xcf\xcc\x81\x74\xeb\xe4\xd3\x2e\x43\x28\x4f\xc7\x8d\x78\x44\xde\x0f\xa2\x2e\x20\x65\xe0\x75\x28\xba\xab\xaf\x01\x5c\xb3\x4d\x62\x9c\x35\x96\xad\x04\x0d\xe3\x1c\x56\x20\xeb\x26\x6d\xef\xa7\x53\x3a\xc0\x40\x19\x98\xe5\x67\x3a\x75\x43\x65\x04\x7d\xeb\xfc\xf7\xe1\x37\xa2\x0d\x16\xcd\xd6\xa5\x52\x19\x82\xf4\x44\xcf\xc3\x42\x93\x97\xc6\x41\xbd\x7e\x74\xa7\x70\xbb\x11\xfc\xb2\x94\x83\xe3\x37\xba\xe5\x16\x9e\xe8\x2d\xa9\xa9\x1a\xdf\x3a\xf6\x7c\xd8\x14\xc2\x82\x5d\x29\x01\x8e\xf0\x35\xea\x86\xf8\xde\x4c\x75\x63\xaa\xf6\x6e\x0c\x75\xd1\x7c\xa6\x8f\x49\xf0\x75\x8e\xc2\xd9\xc5\x17\x9d\x01\xaa\xed\x7d\x45\x15\xe9\x1a\x22\x2b\x0b\x06\xfb\xde\x4f\x07\xa7\xd9\xdf\x2d\xe3\xbc\xae\x37\xca\x2c\x84\x60\xc2\xa6\xb3\x74\x9e\x9b\xda\x36\xd0\x8e\x66\xbc\xc3\x56\xb3\x90\x43\x4b\x4a\x18\xcf\xa4\x5a\xf5\x57\xdc\xa3\xd8\x57\xff\x3a\xd3\x47\xcf\xb0\x7e\x23\x58\xc2\xac\xfd\x5c\xd5\x3b\x3b\x0e\xa2\xa4\x1e\xe5\xc0\x80\x2f\xd4\x73\xdb\x5f\x30\x52\x63\x34\xda\x41\xeb\x4b\xc7\x51\x83\x83\x89\x8a\x0b\x75\x07\xad\x4c\xa2\x89\xd6\x6c\x5e\x2e\xb7\x5c\xf2\x55\xdf\xf3\x12\xcb\x1e\x04\xee\xbe\xb4\x7f\x29\x30\xb9\x0d\x5e\x00\x2e\xb0"}, +{{0x0b,0x2e,0xc6,0x27,0x63,0xf6,0x87,0x59,0x31,0x35,0xda,0x19,0x61,0xef,0x29,0xa2,0x88,0x08,0x96,0x96,0xd9,0x44,0xb2,0x65,0xa5,0xf9,0x68,0x93,0xcd,0x2d,0x82,0x25,},{0xc1,0xe2,0x34,0xfa,0x8b,0xc9,0x6d,0x26,0x8e,0x7a,0xad,0x02,0x8b,0x03,0xf0,0xa9,0x11,0xb6,0x97,0x71,0x5d,0xb3,0xa2,0x1c,0x2f,0xc7,0xdf,0x48,0xec,0xda,0x88,0x75,},{0xff,0x70,0x1f,0x34,0xb3,0x59,0x4d,0xe3,0xb8,0x00,0x45,0xf4,0x29,0xe5,0xe3,0x2d,0xd8,0x8d,0x60,0x51,0xd4,0x19,0x5f,0x16,0x85,0xbe,0x78,0x37,0x66,0xe8,0x01,0x19,0x36,0x8f,0x56,0xb3,0x74,0x97,0x25,0xb9,0x13,0xf1,0x22,0x3f,0x87,0xfb,0x0f,0xb2,0x4d,0x9d,0xfa,0x08,0x41,0xd6,0xa0,0xe2,0xeb,0x1f,0xdd,0xf7,0x75,0xc2,0xd2,0x05,},"\xa8\x34\x34\xc6\x86\x93\xd5\xfc\xed\x91\xbd\xa1\x02\x13\xfc\xd5\x0c\x48\x92\x0b\x90\xce\xe9\xb7\x3a\x9c\x61\x08\x1a\x09\x74\x93\x3f\x4f\xdb\x0a\x67\xe6\x71\xf8\x35\x1b\x0e\xd5\xec\x0f\xe7\xb5\xfb\x0c\x87\x58\x6f\xe5\x82\xff\xb1\xbf\xa2\xdb\x5f\xce\xdd\x33\x02\x42\x82\x34\xb2\xbb\x0e\x72\x6d\xed\xf4\x5b\x13\xa7\x0c\xd3\x5a\xb3\xe2\x99\xd1\x3f\x34\x50\x35\x08\x27\x8c\x44\x58\xee\xa5\xb7\x35\x1b\x05\x83\x6b\xda\xd5\xb0\x5f\x60\xe4\x45\xfc\x65\x73\x7a\xe2\x7d\x2e\x52\xdf\x9c\x39\xe5\xda\x02\x86\x39\x2d\x08\xff\xf7\xec\xb7\x06\x68\x20\xfc\x90\xfc\x8a\x44\xd5\x61\x65\x61\xc5\x0b\x52\x71\x47\x02\x30\x2b\xca\x58\x74\xde\x85\xdb\xa0\x45\x04\x5f\x9f\x0e\x60\x4e\xb8\x6d\x6d\x7f\xbd\x77\x5f\x72\xea\x49\x3b\x2c\x4e\xf7\xc3\xbe\x16\xdb\x2c\xa7\xe4\xd8\xbd\x79\xeb\x20\xcf\xb5\xf0\xf6\xf0\x53\x36\xb7\x5c\xc8\x6d\x21\x9f\x3b\x8f\x2e\x91\xba\x7d\x52\xb6\x4f\xdd\x6a\x66\x64\xf0\x4f\x2f\xba\xb7\x58\xcd\xf9\x84\x16\x86\x91\xc3\x2f\x53\xe8\x61\x6b\x49\xf7\x6a\xb7\xb1\x92\xb9\x00\x90\x30\x82\xcc\x89\x65\x6a\x97\x05\x80\x4c\xc9\xb9\x28\x8a\x3e\x42\x17\x09\x84\xf8\xdc\x45\x4e\x08\x64\xb9\x34\x16\x72\x68\x6a\x17\x8c\x06\x00\x50\x17\x8a\x36\xc6\xd9\x06\xb2\xce\x07\x0d\x8f\xaa\xac\xd9\xa5\x8c\x79\x4a\x5e\xa4\x10\x8b\x4a\x48\x5c\x65\x81\x1c\x2d\xca\x2e\xe7\xbb\x10\xbf\xff\xf7\x5d\x45\x86\xb9\x90\xf4\x37\x63\xa1\x6f\xbc\x0b\x48\xae\x1f\xaf\xb0\x8a\x9a\x36\xfa\x43\x26\x84\x5d\xba\x5b\xa2\xfb\xd3\x2b\xbf\x66\x50\x5c\x5e\x86\x57\xed\x01\x07\xe3\xe1\x61\x44\xef\x31\xfa\x6a\xae\x72\xe7\x74\x09\x74\x83\xf5\x48\x0a\xa4\x55\x40\x56\x8f\xd0\x8c\xba\x0d\x57\x77\x68\x00\x4f\x58\xae\x9b\x95\xbe\x37\x4e\xd7\xf0\x29\x9f\xe7\x21\x27\x5e\x47\x6e\x0b\x9a\xb7\x2d\xc0\x6e\xa3\x28\x38\x4e\x39\xbf\x3a\xc3\x31\xc6\x25\x48\x43\x12\xcd\x9b\x06\xb1\x5a\x29\x54\xd3\x3e\x7a\xab\xa6\xbe\x22\x61\x88\x6c\xa8\x11\xdb\x96\xb1\x14\x3d\x06\xdd\x6e\x0f\x3c\xba\x7a\x1a\xe9\xb9\x4e\xaf\x67\x77\x1b\xb2\xd2\x4e\x2f\x94\xde\x9c\x47\x0f\xcd\xe7\xbf\xdb\x32\xf4\x10\x19\x8b\x5a\xa9\x69\x8e\x32"}, +{{0x89,0x60,0xd7,0xbe,0xe8,0xc6,0xb3,0x9c,0xa5,0x93,0x4d,0x7c,0xdd,0xd1,0x6f,0x16,0xb3,0x66,0x3e,0x6e,0x03,0xe8,0x33,0xc0,0x57,0xe2,0x18,0x1e,0x45,0x97,0xcb,0x68,},{0x43,0x40,0x90,0x95,0xd4,0xf5,0x0f,0x5e,0xdd,0xbd,0x5c,0xd4,0xd2,0x01,0x22,0x98,0xcb,0x41,0xa4,0x0e,0x99,0x49,0x2d,0x5a,0x2d,0xb0,0x8b,0xe5,0x37,0x7e,0xa1,0x83,},{0x72,0x13,0xdd,0x4a,0x79,0xfd,0x54,0xde,0xc0,0xc5,0x48,0xef,0x42,0xe6,0xca,0xe0,0x15,0xbe,0x77,0x80,0x2b,0xf5,0x15,0xcd,0x25,0x82,0x76,0x8f,0x72,0xf5,0x63,0xeb,0xb2,0xda,0x36,0xaf,0x4a,0xae,0xac,0x56,0xbb,0xff,0xc9,0x93,0x2c,0x2e,0x24,0xec,0x95,0xda,0xff,0x00,0xa5,0xf7,0xa0,0xac,0xab,0x9c,0x8b,0xd3,0xc2,0x3b,0xb4,0x0c,},"\x30\x8d\x84\xc7\xa5\xf7\x86\xe5\x63\xe5\xc1\xea\x57\xaa\xb5\xe5\x55\xc0\x09\x97\x74\x9d\x15\xae\xe3\x54\x39\xef\xa6\x45\xda\x2c\x39\x67\x70\x31\x15\xc6\xc6\x3e\xd7\xf9\x47\x85\xc5\x47\x8f\x38\x46\x7b\x86\xe7\x62\x6e\x8f\xff\xa4\xd5\x1a\x2d\xc4\x5e\x6d\xf2\xa3\x5c\xec\x99\x55\x5e\xab\xc9\xf7\xa9\x3e\x2e\x2b\x68\x94\x59\xb4\xe0\xc9\x2b\x35\x15\x62\xc4\x17\xb1\x99\x71\x13\x75\x4e\xa5\x9e\x4a\x91\x51\x07\x28\xff\x30\x71\xa2\xbb\xd1\xf4\x65\xa6\x87\xf6\x7d\xae\x95\x56\x15\x03\x1a\x8a\xd5\x51\xfe\x73\x8a\x26\x0b\xbc\x44\x6b\x48\xdc\xa1\xd9\x79\x05\x1a\xb5\x84\x08\x32\xe1\x9d\x47\x3b\x66\x62\x17\xa9\x18\x39\x80\xd6\xb2\x7e\x3d\x3c\x76\xd9\x36\x65\xba\x23\x93\xe6\xab\x1a\x42\xc3\x90\x4d\x40\x25\x93\x2d\x60\x1a\x20\x2a\x59\xa4\xc4\x9f\xdb\x77\xf0\xe0\x28\x68\x24\x7d\xe5\xaf\xdf\xaa\x1b\x89\x42\x08\xac\x00\xd7\x7c\x6b\xb5\x4c\x6b\x2a\x73\xa4\x76\x57\xe4\x4c\x85\x13\x79\x63\xb5\x75\x21\xaf\x20\x97\x62\x48\xeb\x26\x14\x82\x14\x7c\xdf\x7a\x14\x5c\x36\x43\xe2\x9e\x05\x88\xbf\xda\xe6\xa0\x82\x90\x48\x53\xce\x5a\x10\xd2\x49\x70\xeb\xdf\xb7\xf5\x9d\x5e\xfd\xd6\xa5\xe7\xe0\xd2\x87\x97\x1c\x84\x6a\xcd\x54\xd8\x4d\xd4\x54\x68\xa4\x11\x0b\xab\x6e\xf8\xd9\xa5\xb4\xb2\x42\x67\x88\x90\x0b\x7e\x1a\xdf\xe0\x62\x43\x44\xf9\x8f\xe5\x9e\xf8\xa1\xe6\xc4\x05\xb3\x44\xeb\x97\xbb\x20\x47\x73\x74\x4b\x6a\x2d\x8c\x6e\x65\xd1\x7c\xea\x07\xde\x03\xb7\xf0\xfe\x49\xf1\xa5\x5c\x33\xd5\xf1\x5c\xe5\x5d\xf7\xc9\x56\x1b\x25\x1c\x6a\xc8\x07\xa9\x25\x53\xe1\xce\x91\x70\x12\xdc\xcf\xd6\x9e\x7d\xbd\x03\x8c\x7e\xee\xca\xe9\x86\x23\xf1\x8f\xbb\x65\x0e\x22\x18\xa0\xbc\x0f\xff\x43\xa7\x5a\x11\x64\x48\xbb\x73\x62\xf5\x27\xee\x6b\xc8\xe1\x07\x61\xcc\xcf\x9b\xcf\xc0\xd0\x00\xf2\x12\x7b\x4c\xc1\x92\x11\xd0\x95\xa0\xbd\xaa\x4e\x4b\xe4\x51\x9e\x6c\x84\x45\xea\xb9\xb3\x14\x4a\x45\xca\xb9\x99\x61\x35\xbf\x7f\x75\xa7\x8d\x22\x27\x59\x00\xf4\xce\x1f\x0a\x9e\xac\x13\x63\x64\x10\x30\x62\x89\x3d\xad\x43\x90\x42\x2b\x77\xe5\xf5\xd1\xd9\x4d\x70\x29\xc6\x09\x7b\x35\xca\x64\xa7\xa4\x76\xfc\xc7"}, +{{0xef,0x6b,0x9b,0x51,0xfd,0x4f,0x85,0x86,0xca,0x62,0x65,0x8e,0x04,0x2f,0xc0,0x9a,0x83,0xb9,0x43,0x03,0x35,0x26,0xff,0xc3,0x26,0xc6,0x5e,0xb3,0xa5,0xfb,0x59,0x4b,},{0x1d,0x6e,0xec,0xe8,0x05,0xe0,0x88,0x78,0x21,0x87,0x6b,0x7e,0xd6,0xed,0x5b,0x07,0x14,0xd6,0x46,0xfb,0xec,0xda,0x38,0x76,0x4f,0x94,0xc8,0x15,0x5e,0x61,0xd0,0x04,},{0x71,0xd1,0x71,0x07,0x1c,0xd0,0xfe,0xa1,0xc6,0xa9,0xcf,0xad,0x1f,0x7f,0xd8,0x35,0xe8,0x5f,0xf9,0x06,0x77,0x8b,0xc6,0x34,0x5a,0x4d,0xec,0x43,0x13,0xec,0xc2,0xbf,0xf7,0x55,0xa7,0x17,0xeb,0xd9,0x12,0xa5,0xe0,0x28,0x40,0xac,0x07,0x38,0x42,0xf9,0xbf,0xca,0xa5,0x89,0x13,0xe2,0x60,0xe3,0xc7,0x33,0x93,0xd3,0x66,0x85,0xc7,0x0e,},"\xa8\xf3\xf1\x96\x65\xde\x23\x90\xd5\xcc\x52\xb0\x64\xb4\x85\x12\x73\x67\x74\x86\xd8\xf5\x56\x3b\xb7\xc9\x5f\xa9\x4d\xb3\x35\x61\x61\xee\x62\x22\x21\xf1\x0c\xbb\x1f\xa1\x95\xaa\xc7\x23\x1e\xa7\x16\xd7\x4b\x46\xb3\x7b\xc8\x5a\x70\xdb\xa3\xdf\xaa\x16\x75\x21\x7b\x35\x11\x99\xe7\x4a\x97\x10\x28\xf7\x29\xb7\xae\x2b\x74\xae\x8c\x6b\x3a\x06\x79\xc3\xe3\x29\x68\x02\x84\x4a\xd5\xbb\xa3\x43\xf6\xf9\xf7\xc4\x66\x1b\x4a\x29\xb4\x4f\x17\xe8\x9e\x11\x4f\xb2\x20\xe9\x84\xcd\x98\x0e\x94\xc3\xd2\xbf\x98\x73\xe0\x60\x5c\x92\x30\x17\x44\xa3\x03\x5e\xf0\x46\xba\xd2\x66\x6b\x5c\x63\xeb\xec\xf9\x3c\xc1\x40\x29\x19\x46\xc0\xfa\x17\x03\x40\xce\x39\x50\x92\xde\xed\x79\x84\x13\x52\xfb\xfe\xe0\x3a\x92\x7e\xb4\x58\xf2\xa6\x33\xed\x32\x71\x65\x2f\x5b\x0f\x99\x60\xcd\xf9\x01\x5d\x56\xfd\xab\xd8\x9e\xe7\x1e\x25\x9a\xf6\xeb\x51\x4b\x4c\x1b\xd4\xa6\x66\xf5\xb5\xa3\x5c\x90\xf3\x5b\x14\x94\x57\xaf\x29\x44\xdd\x0a\xa8\xd9\xb5\x42\x28\x3a\x7e\x54\x12\xb7\x75\xe4\x21\xd2\x12\x6f\x89\xbe\xbc\x3c\xa3\x7f\x73\x07\x16\x21\xf1\x32\x1e\xee\x52\xe9\x69\x04\x86\xa3\x3c\xd7\xff\x9c\x99\x67\xfb\x65\xee\x4e\x90\x7b\x6b\x85\x22\x11\x47\x3d\x21\xe9\xd9\x1a\x93\x36\x2a\xc7\x61\x76\x0e\x8c\x7b\xbe\xa4\x86\xc3\xd6\x05\xf9\xe1\x1b\x86\x13\x68\x19\xa7\xab\x3f\x32\xf1\x3f\xfc\xa1\x68\x17\xfe\xd1\x97\xff\x88\x0b\x4d\x6d\x9a\x80\x8f\x7f\x87\x87\x63\xa0\x45\x72\x8d\xf7\x2f\xaa\xa9\x63\xe4\xcb\x1c\x09\xcc\x2b\x2d\xa9\x20\x28\x0c\x83\x66\xb7\xd1\x8b\xf8\x97\x2d\xf1\x6c\xc2\x34\x48\xfb\xe6\xb2\xe6\xe1\x6c\xbb\xf0\x74\x51\x29\x85\x40\x53\x18\x96\x37\xce\x11\x5d\x23\x98\x43\x3c\x15\xd6\xf1\x16\xa2\x05\x33\x48\x24\xaf\x28\x2f\xa7\x58\x49\x4c\x47\x86\x8e\xa8\xf4\xdf\xad\xc7\x05\xe8\x61\xaa\xd2\xeb\x8e\xf3\xdb\xbe\xd2\xa4\x56\x9e\x15\x83\x4a\x76\x0c\xce\x0c\xbb\xc8\x4b\x28\x9e\x77\x9b\x98\x83\x46\xb9\x06\x9c\x74\x4c\x97\xab\x2b\xf4\x2b\x08\x6d\x2f\xb0\xa4\x11\xf5\xce\x99\xf0\x81\x9a\x30\x86\xb4\xfe\x9d\x96\xc7\xc9\x90\x8d\xce\x28\xdf\x1d\xdd\x30\xf3\x50\x1d\xda\xf7\x81\x10\x73\x4f\x9d\xcd\xfe\xc3"}, +{{0xba,0xd4,0x7c,0xd4,0xbd,0x89,0x84,0x90,0x67,0xcc,0xe1,0xe6,0x3c,0x3d,0x91,0xe9,0xb7,0x87,0xae,0xa8,0x58,0x4e,0xdb,0x07,0xf3,0x45,0x1e,0xf6,0x7e,0x7b,0xd7,0x9b,},{0xab,0x0c,0xe9,0xba,0x1d,0x29,0xbd,0xfb,0x85,0xa0,0xe6,0x6b,0x76,0xb5,0xe2,0xe0,0x5f,0xf7,0x32,0x56,0x9e,0x43,0x75,0xcc,0xd7,0x50,0x98,0xe9,0xe7,0x1d,0x17,0xbf,},{0xe5,0x72,0x4a,0x1d,0xd4,0x63,0xa9,0x7d,0x12,0x22,0xc5,0x18,0xc4,0x92,0x5d,0x32,0x22,0x02,0xd1,0x0f,0x04,0xcd,0x07,0x8e,0x77,0x1e,0x0f,0xb3,0x95,0x1d,0xbc,0x14,0x93,0xa2,0x34,0x46,0x07,0x54,0xc3,0xaa,0xe3,0xdf,0x93,0x00,0x8d,0xbb,0xfb,0x31,0x0c,0x99,0x59,0x2b,0xed,0xe7,0x35,0xa4,0xae,0xab,0x03,0x23,0xa1,0x21,0x0d,0x0e,},"\xb5\xa6\x1e\x19\xe4\x86\x3e\x0b\xb5\xf3\xfa\xb6\xc4\x97\x0d\x87\x85\x96\x89\x55\x21\xfa\x1e\x7f\x67\x8c\xaf\xa2\xde\x53\x32\x2f\xd4\x58\xa9\x8a\xa6\xe3\x58\x05\x42\x9f\x65\x12\x91\xb9\x5b\xd9\x95\x0e\x15\x5f\x3a\xda\x0b\x60\x91\x59\xa4\xab\xda\x59\x90\xc0\x4b\xc2\xe7\x64\x42\x2f\xb4\x9e\xf4\x2f\x12\x52\x9f\xf6\xf6\xa8\x20\x29\xff\x01\x85\x66\x2e\x65\x8f\x83\xc5\x46\xee\xd0\x9f\x06\xb5\xa6\x8e\x85\x7c\xda\xd0\xeb\x9e\xc4\xee\xcb\xfd\x88\xf3\x4b\xc8\x09\x90\xf8\x64\x4a\x9b\xfd\xde\x1d\x9f\x3a\x90\xd5\x57\xa8\xb8\x28\xd5\xce\x06\xa6\x4e\x3b\x23\x85\x82\xbb\x4c\xbe\xba\x30\xed\xc4\x9e\x81\x22\xc5\x5e\x95\xba\xdc\xf5\x02\xcc\x56\x78\x69\xc0\x9e\x9f\x46\xc6\xff\x3f\x68\x78\x98\x6b\x1d\xe0\x0b\x72\xa1\x85\x80\x46\xfc\xd3\xa6\xe9\xcd\xaf\x5b\x07\x3c\x56\xf2\x02\x50\x63\xa2\xd1\x78\xbd\x4c\x1e\x8c\xbc\x1e\x6e\x67\x1a\xa9\x7f\xb2\xcb\x4c\xc8\xa6\x2c\x20\xbe\x41\xc7\x76\x37\x2c\x8e\x7b\xe6\x3b\x48\x2e\x6c\x63\xfa\x85\xd7\xcf\xfb\xc1\xb2\x82\x0b\xae\x1f\xc1\x28\x34\x3a\x1e\x20\xfc\xf1\xbc\x35\x02\xee\xe8\x13\x58\xcc\x9a\x74\xc7\x2a\xf6\x35\x30\xf9\x6a\x25\xa6\x04\x64\x8f\xf5\x70\xdf\x1e\xb8\x9d\x1f\xdd\xba\xb2\x86\x79\xba\x2e\x9b\x41\x97\x7e\x9a\x9c\x1c\xae\xcd\xbf\xc3\x61\xa1\xdd\x05\x5e\xc5\x16\x20\xa9\xbb\xdb\xba\xf7\x18\xc9\xcc\x13\x6d\x20\x07\x71\x03\x99\x53\x6d\x13\x33\x24\x85\xec\x38\x87\x97\x85\xe0\xc9\xce\x99\x15\xa8\x02\x51\x37\x39\x90\xa5\x9b\xce\x44\x03\x26\x03\x1a\xb1\xb4\x58\xbf\xa5\xb8\xa4\x79\x3d\xa4\xee\x11\xab\x7a\xf2\x0d\xe2\xa1\x18\xc9\xae\x52\x1a\x41\x7b\x68\x20\x7f\xc8\x85\xe1\x09\xd8\x46\x3e\x9f\x02\x27\x87\xcc\x73\x0d\xb0\xb1\xfa\xae\xd2\x57\xbe\xd9\x01\x71\x08\x85\xb7\x4e\x99\x4f\x54\xf6\xf2\xae\xb6\x4f\x0f\x60\xb5\x9e\xfb\xf2\xe3\xbb\x65\x15\x42\x46\x03\xa1\x13\xc0\xb8\xa3\x1b\xa3\xc1\xe9\xa9\xb8\x11\x8c\x87\xec\x69\x49\xb7\x5f\x49\x62\x7e\xa7\xb1\x32\x88\x89\x39\x11\x04\xd4\xf4\xa3\x89\x2c\xf0\x0f\x26\xa7\x3c\xda\x2a\x40\xf9\xb7\x15\x7a\xfc\x40\x66\x7f\x4a\x04\xf6\x47\xdb\xf9\x39\x06\xb8\x4c\x9a\x35\x16\x4e\x1b\xc9\x02"}, +{{0xca,0xba,0x8e,0x05,0x33,0x11,0x3a,0x4b,0xe1,0x73,0x40,0x8b,0xa8,0x3c,0x0d,0xb7,0x42,0x60,0x80,0x2f,0x91,0x86,0xc3,0x91,0x40,0x26,0x55,0xac,0xde,0x60,0x15,0xcb,},{0x2d,0x7b,0xef,0x61,0x64,0xc2,0x79,0xfa,0x10,0x28,0xa9,0x78,0x8e,0x3e,0x8e,0xe8,0xac,0x15,0xed,0xcf,0x92,0xa5,0x85,0x50,0x62,0x95,0x23,0x10,0xb4,0x68,0x45,0x47,},{0xec,0x35,0xec,0x32,0xc8,0xa4,0x00,0x88,0x27,0xe1,0x78,0x49,0x2b,0x3b,0x8b,0xee,0x22,0xa4,0x95,0x4f,0xc6,0xb2,0x5f,0x4f,0x22,0x5d,0xd7,0xed,0x23,0x69,0x89,0x00,0xde,0x81,0x56,0x75,0x6a,0x8e,0xdc,0x35,0xc5,0x1d,0x10,0xf8,0x2b,0x83,0x0a,0x2a,0x65,0x96,0x76,0xea,0xc9,0x11,0xf9,0x60,0x24,0x47,0x66,0xe0,0xc3,0xc6,0x07,0x05,},"\x24\x13\xa3\x2b\xca\x5c\xe6\xe2\x30\xe5\x65\xeb\x85\x84\x93\xd5\xd0\x4e\x6d\x2e\x2a\x7a\xb1\xf8\x9a\x3b\x42\x33\x11\x67\x6b\xfa\x93\xc6\x7d\xaa\xfd\x1c\xfc\x71\x09\xe0\x40\xba\xc5\x2c\xbf\xe0\x7c\x28\x28\x0b\xb6\xac\xf6\xe3\xa3\x10\x73\xda\xb2\x96\x53\x78\xdd\x77\xf6\x1f\xe9\x24\x71\x35\xc1\xa6\x31\xb7\x9a\xd6\x68\xc9\xea\x1c\xd4\x11\x2d\x8d\x3a\x06\x4c\xc2\x1d\xf3\x2a\xea\xc7\xdd\x71\x8b\x09\x1f\xb6\x91\x5b\x8b\xc0\x63\xbb\x58\x15\xc3\x76\xe0\x14\x76\x31\x2a\x2e\x54\x33\x41\x7a\x7a\x93\x15\xd6\x59\x99\xb0\x2f\xf4\x64\xa4\x74\xa5\x97\xe5\x39\x88\x77\x36\x70\xec\xa4\x6a\x6e\x26\xcf\x96\xe9\x48\x8e\x9e\x63\x44\xbc\x78\x3d\xdf\xb5\x35\xe7\x6b\xb3\xb9\xa6\x03\xff\x4c\x59\xc7\xdb\xe2\xd8\xb6\x19\x8d\x5b\x24\x49\x0b\x4e\xa9\x6c\x95\x95\x9f\xfb\xf3\xd8\x21\x8e\x76\x0d\xaf\x20\xe0\x1e\x2f\x36\xc8\x4b\xb0\x97\x11\x5a\xbd\xde\xe9\x2b\xed\x82\xd1\x6b\x15\xa9\xe1\x92\xe9\x89\x3a\xc6\x38\x46\x1d\xf5\x07\x20\x7b\x0c\xf5\x95\x88\x4d\x8a\x99\xfb\x9c\x70\x45\xf9\xbf\xf7\xb7\x3f\x00\xca\x3f\xd5\x95\xa5\xce\xc2\x92\xad\xb4\x58\xbd\x94\x63\xbe\x12\x04\xd0\x16\x78\xd2\xf4\x38\x9b\x87\x20\x11\x5f\xa5\x97\xc4\x02\xb4\xff\x69\x4b\x71\xce\x4f\x3d\x33\x0d\x5e\x2f\x3c\x3a\xd6\xd9\x6a\x9b\x34\x39\x23\x0f\xc5\x3a\x44\x79\x4c\xda\x59\x55\x57\xc4\x06\xca\x15\x89\xbc\x7b\xe8\x1e\x2d\x79\x63\x60\x33\x25\x3f\xa7\xbd\xd6\x00\xc6\x7f\xc5\x59\x36\xbd\x96\xce\x04\x28\xc3\xeb\x97\xba\xd1\xde\x0a\x5f\xbb\x9b\x67\x51\x57\xde\x5f\x18\xbc\x62\xa7\xc2\x2c\x94\x83\xe2\x80\x2e\x67\x9b\x5b\x8f\x89\xdb\x0f\xc3\x7f\x7c\x71\x50\xad\x5a\xc8\x72\x2c\xeb\x99\x9b\x24\x35\xe6\x99\x72\x17\x09\x23\x36\xef\x1c\x8a\x22\x92\xda\xb9\xa4\x6f\xf8\xa9\xe1\x0d\x33\x55\x76\x5c\xac\x9d\x65\x98\x77\x0f\x4f\x01\xea\x63\x91\x25\xfd\x03\x16\x09\xdd\x1a\x50\x7d\x96\x28\x0c\x7d\x01\xa3\xee\x98\x7e\x9b\x21\x0e\xc8\x74\x4c\xd4\x8c\x74\xf8\xaf\xee\x96\x1e\x8e\xf2\x21\xf8\x26\xa1\xfe\x6e\x7d\xf0\xcb\x15\xad\x7c\x7e\xf4\xa9\x1f\x9d\x0f\x4c\x2e\x1b\xde\xa6\x35\xd2\x75\xfa\xc8\xc4\xbc\x06\x01\xf4\x90\xdb\xdb\xc7\x34"}, +{{0x9b,0xf3,0xfb,0xc7,0x30,0x8b,0x46,0xf6,0x03,0x6b,0xad,0xe0,0xc3,0xca,0x19,0x9f,0xac,0x66,0x2b,0x07,0xf1,0x03,0xbf,0x75,0x18,0x1d,0x52,0xba,0x6a,0x58,0xbe,0x05,},{0x2f,0x6a,0xc6,0xfc,0x33,0xbc,0x06,0x0c,0x1d,0xc3,0xcb,0x9d,0x1a,0x2b,0x91,0x15,0x84,0x5a,0xdd,0xb1,0x6c,0x4b,0x84,0xbe,0x37,0xed,0x33,0xad,0xb3,0xb3,0xd3,0xa8,},{0x0c,0x31,0x36,0xe0,0x1f,0x9b,0xcd,0x99,0xe1,0x0d,0x3d,0x12,0x4b,0x0c,0xdb,0x07,0x72,0xbe,0xc1,0x8a,0x86,0x4b,0xe8,0x1b,0xd1,0xda,0xa4,0x4d,0x81,0x8c,0x3d,0x47,0x0d,0xfa,0xa8,0xab,0x6e,0x9a,0x76,0x1c,0xf0,0x3f,0x93,0xef,0x9c,0xc7,0x82,0x91,0x09,0x6e,0xd6,0xd1,0x0c,0x08,0xfa,0x2f,0xba,0x3b,0xac,0x04,0xdd,0xe2,0x0f,0x0c,},"\xd6\x5e\x36\xa6\xa3\x81\x95\xec\xb9\x1d\xe3\xc8\x48\xb5\x1f\x63\x92\x45\xfa\x2b\xab\xa8\xa6\xf8\x59\x47\x15\x9d\xec\x0e\xd3\xfa\xe8\x0c\x5a\x0f\x8c\x66\xff\x24\x79\x3c\x89\xc0\xc6\x87\x54\x3b\xc6\x33\x54\x7a\x1f\x37\xf7\x30\xd9\x70\x12\xeb\xbd\xc7\xac\x33\x9c\x48\x90\xc0\x85\x6b\xbf\xe2\xba\x29\xb2\x5a\x7a\xa6\xb0\x89\xc0\x33\xfe\xcb\x76\xdb\x62\xdd\x3c\x00\xf6\x42\x1b\x9e\x76\xdd\x0e\xa3\x66\xeb\x2d\x4a\x05\x2e\xe6\xcc\x73\x6e\x38\x19\x19\x1d\x5a\xd7\xa6\x6d\x2b\xe0\x42\xcc\x65\x39\xe5\xf3\x56\x52\xb1\x55\xa7\x27\xf3\x88\x8d\x93\xf9\x3a\x91\x02\x59\x8f\x75\x38\xa9\xab\x7c\x77\x7e\xec\x79\x42\x6a\x60\x75\xd6\xf3\x8d\x64\xc4\x85\x52\x0f\x64\x13\xff\x4d\x35\x8a\x8a\x9c\xbd\xab\x01\xad\xf4\xdb\x02\xad\xae\xa2\x64\x94\xd1\xf5\xd6\x17\x63\x7f\x27\x7f\x8b\x0e\x6e\x7e\x61\xe2\xee\xcc\xdd\x33\x7d\xe2\xba\xf0\xca\x26\x4c\x14\xc8\xcb\x83\x68\x00\x0b\x9c\x71\x43\x85\xf4\x13\x73\x7d\x68\x16\xe2\x12\xca\xe2\xae\xcf\xff\xc3\x2f\xd1\x6d\x46\xc3\xec\xee\x6a\xb0\x74\xc0\xd7\x68\xbd\xfe\x99\xb8\x6c\xbb\xc8\xdf\x9c\x47\xcd\x58\x6d\x46\x58\x71\x26\x8d\x4a\x9d\x1c\x87\x72\x36\xab\x78\xf8\x85\x9c\x11\x4e\x25\x1c\xab\xc4\xbe\x0f\x8b\xc2\x5d\x14\x8c\x5f\x54\x3e\x29\x07\x45\xd1\x18\x03\xe4\x9f\x5b\x53\x19\x3f\xe3\x99\x69\xc0\x39\xb3\xf2\x49\xb3\x2f\x2b\x85\x98\xb6\xac\xf4\xed\x64\xd5\x75\x2b\xb7\x72\xff\x4e\xe0\x0c\xe0\xf8\x5e\xcb\xb4\xcf\xc4\xce\x07\xda\xf2\x80\x98\x68\xc2\x90\x3b\x78\x1e\x12\xa2\x74\x10\x5f\x06\x18\x10\x29\xe4\x7f\x2b\xfb\x21\xf4\x94\x80\xaa\x1e\x44\x47\x15\xc0\xb9\xff\x07\xea\xd8\x89\x75\xd9\x35\x85\xd2\xff\x42\x48\x32\xa9\x78\x3d\x94\x90\x6a\x60\xf8\x77\xae\x1c\x85\xff\x15\x31\x7b\xad\xca\x1e\x61\x31\x74\x33\xc7\xce\x96\x27\x9b\x67\x8e\xc9\xd1\x74\xdd\x08\x70\x08\x0b\x23\x41\x54\xf6\x26\xa5\x34\x62\xcf\xd5\x47\x84\x2e\xab\x87\x05\x60\x5b\x8e\xe8\x85\x72\x9e\xe7\x8d\x18\x33\xaa\x43\xf5\x5a\xc2\x27\x31\x98\x9f\xde\xda\x7d\xc5\xfa\x9c\x01\x98\x5f\x26\x61\xe6\xc7\x32\x6d\x34\x6e\x6d\xb2\x7e\x6f\x92\x1f\xae\x7c\x93\xa2\x17\x0e\x10\xdd\x0c\x46\x0b\xdc"}, +{{0x64,0xe8,0x93,0x04,0xa3,0x35,0xe9,0x03,0xcb,0x36,0xc0,0xbd,0xf1,0xa6,0x41,0x2e,0xf3,0x68,0x46,0x80,0x06,0xb7,0x3d,0x3d,0x2d,0x61,0xcb,0x03,0x0c,0xc5,0xf8,0xd1,},{0xa1,0x80,0xef,0x3a,0x66,0x1c,0x3c,0x47,0x9d,0x5f,0x69,0x80,0x7c,0x90,0x27,0x48,0xe3,0x5e,0x7f,0x72,0x51,0x21,0xe3,0x7a,0x5d,0x91,0xb8,0xbe,0xc8,0x8d,0x83,0xa6,},{0x92,0xeb,0x44,0x54,0x81,0x40,0x01,0xec,0xfc,0x18,0x02,0x5d,0x64,0x21,0xf6,0x46,0x45,0xa5,0xbc,0xbb,0x5c,0xb8,0xfd,0x85,0xc1,0x4d,0x77,0x26,0x17,0xc5,0x03,0xe8,0xbe,0x7d,0x3b,0xcf,0x11,0x7f,0x5e,0x68,0x01,0xd1,0xc3,0xb9,0x6f,0x90,0x90,0xa6,0x6d,0xdc,0x67,0xf8,0xcf,0x8f,0xf0,0xf1,0xc1,0x25,0xb1,0x6b,0x15,0xe2,0xce,0x07,},"\x2f\x51\x07\x4d\x98\x1b\xda\xfa\xfb\x02\xa4\x0f\xe8\x26\xc4\x5f\x31\x71\xc1\xb3\x18\x4d\x8c\x26\x0b\x82\xb8\x41\x1f\xc6\x25\xcb\x02\xcc\xfe\x75\x5d\xc2\x9d\xc7\x89\x5b\xf7\x59\xe6\x1b\x24\x50\xda\x1a\x65\x6a\x38\xd4\xf7\x0d\x2e\xe7\x48\xc5\x18\xc6\x42\x03\x06\xe5\xf0\x1e\xc7\xa0\xff\xe0\xe9\xdc\xeb\x93\xf6\xc0\x77\xb1\x26\x62\x88\x15\x84\xf9\x8c\xe6\xab\x94\x5f\x87\xfc\x6d\x12\x3c\x45\xd6\xcd\xfd\x82\x37\xa1\xce\x36\x35\xb6\x23\xa7\x9d\x02\x0d\xf4\x4c\x74\xb8\x9a\xc1\x4a\x32\x1f\xbf\x33\xa8\xc0\xa2\x55\x9f\xea\x1c\x2b\x15\x60\x76\xb8\x13\x90\x8f\x84\x2e\xbe\x4c\x2b\x94\x90\x89\xe5\x2b\x1a\xe4\x0d\xc6\xe4\xb2\xab\xbc\x43\x9a\x0b\xf7\x23\x69\x67\x9a\xab\x6f\x4c\x00\x01\x8b\xe1\x47\xf7\xc0\xa6\x7b\x96\x79\xee\x88\xa5\x38\x19\xc4\x9f\x7b\x67\x5e\x30\xa8\xb5\xaf\x39\x66\x1e\xe8\xdb\x21\x01\x04\x11\x29\x49\x68\xf8\x8e\x5d\x60\x4d\x0d\x88\xd7\x6a\x7e\x48\x64\xfa\xd3\xa5\x6f\x5f\x62\x4b\xa1\xb3\x4e\xa9\xcb\x72\x08\x50\xaa\xd3\xbd\x4f\x0a\x88\x2a\x7d\x25\xfb\xec\x2b\xb7\xca\x86\xda\x61\x6d\xa9\x6c\x15\x62\xc6\xd6\xa1\xab\xcc\x64\x1e\x1b\x58\xb2\xc1\x78\xe1\xc3\xbc\x8a\x3b\x36\xec\x9e\x14\x4d\xd2\xe7\x5b\x0b\xc8\xc0\x8c\xcb\x0d\x6e\x34\x27\xb0\x32\x2b\x3d\x6a\xb9\x3f\x3f\x60\xb9\xcc\x5b\x61\xda\xd0\x23\x85\xa1\x49\x49\xf9\xb8\x7a\x8e\x3a\xf1\xe0\xe0\xfa\xb7\xa9\xa9\x28\xc7\x53\xfc\x61\x10\x44\x4a\xf7\xcc\xaf\x80\x27\xed\x64\x1b\x9e\xd8\x7f\xa5\xd8\xe1\xf7\x6c\xae\x46\x5d\x57\xa7\x0d\xad\x9e\xbf\xdd\x3c\xe7\x57\x6a\xc4\xde\x89\xd9\x8f\x42\xe2\x82\xad\x87\xad\x6a\x50\x42\x57\x7c\xbb\xbc\x4d\x95\x1e\x2a\x86\x76\xfe\xdc\x8c\xb1\xb1\xbd\xf7\x6c\x3a\x38\x84\x63\x85\xa8\x5a\xa2\x47\x06\xc2\x0a\x8b\x38\x46\x5f\xe2\xae\x0e\x41\xf7\x8e\x61\x4b\x8e\x96\x42\xfe\x24\x71\xa9\x01\x57\x47\xdb\x97\x6e\x0c\x78\x48\xc2\x3f\xf3\xf4\x17\xcb\x05\xa8\xd5\xef\x40\x13\x0a\xdf\x85\x5c\x99\x8a\x62\x10\x4d\x7e\x2f\xb7\xc0\xf9\xaa\x2a\x49\x60\x75\x62\x3c\xed\x2c\x0f\x7e\xec\x10\x14\x7f\xf9\x60\x8a\x8a\x04\x2e\xf9\x81\x17\x45\x9b\x93\x83\x7f\xd1\xb8\xd5\xef\x03\x97\x8e\xad\xa7\x4c\xac"}, +{{0x6f,0x63,0x43,0x87,0xca,0x2c,0x0c,0xb1,0x67,0xa7,0x40,0xd6,0xaf,0xd8,0x9e,0x2a,0x28,0xf5,0x30,0x71,0x84,0xe8,0x1c,0xba,0x3c,0x03,0x70,0x46,0xa5,0xed,0xe2,0x3c,},{0x01,0x1f,0x2a,0x9a,0x11,0x1c,0x38,0xf3,0x49,0x0c,0xad,0x16,0x85,0xbe,0x78,0xec,0xee,0xdc,0x6f,0xac,0x4a,0x32,0x21,0x30,0x1c,0x69,0xc8,0x4b,0x1e,0xc7,0xb3,0xa7,},{0xfd,0x17,0xc6,0x18,0xcd,0xbb,0x5d,0x45,0x9e,0xa2,0xac,0xa8,0x86,0xf0,0x51,0x2c,0x62,0x32,0x51,0x28,0x4a,0xae,0x3a,0x83,0xeb,0x5d,0x7f,0x60,0xda,0x1d,0x9b,0x2b,0xa0,0x83,0xc4,0x55,0xa5,0xe2,0x58,0x3a,0x3c,0xba,0x73,0x6e,0x7b,0x96,0x1b,0xa1,0x9c,0x1c,0xc8,0xdd,0x90,0x74,0x5d,0xa8,0x2a,0x15,0xdf,0xc6,0x62,0xe8,0xe1,0x0d,},"\x86\x5c\x20\xa9\x4a\xc3\xf2\xe3\xbd\x5c\xb8\x5b\xec\x9d\x33\x72\x66\x71\xfe\x01\xf9\xc5\x37\x01\x7d\x59\xc8\xd5\x10\x6e\x43\x36\x0b\xf7\x6f\xc0\x61\x86\x70\x59\x80\xc8\xa8\x7b\xa3\x63\x3a\x4a\x17\x04\x26\xec\xc0\xde\xfb\x6d\xb2\x67\x0f\x5f\x59\x25\x33\x77\x4c\xda\x50\x05\x2a\xe5\x97\xd4\x8d\xea\xcc\x26\x37\x06\x3b\xfd\x51\x9f\x2e\x79\xba\xc8\x17\x75\xbe\xcc\xb1\xab\x2f\x5b\x39\x71\x2e\x2e\x82\x94\x69\xb7\x5a\x2d\x2d\xbd\x08\xaa\x6d\x24\x72\x34\x04\xb2\x5e\xb9\x48\xa4\x83\x4c\x55\x24\x6c\x80\x79\xa8\x2e\xc6\x43\x54\xe8\xc2\x38\x8f\x8c\x5a\x61\x6b\x3c\xdc\x37\x1e\x62\x63\xfa\xbc\x9f\x60\x99\x21\x9e\x86\x15\x85\xfe\x82\xa6\x7d\x61\x0d\xd1\xeb\x5c\x81\xc9\x6b\x5c\xb3\x54\xa6\x89\xfd\x8a\xac\x8d\xb7\x6c\x43\x3f\x0c\xb0\xb3\x1c\xf1\xd8\x55\xb6\xa3\x0a\x3d\x2a\x21\x2e\x9b\x4f\x7d\x7a\xfe\x61\x99\x51\xf9\x8d\x2f\x1b\xa2\xc1\x01\x08\x5b\xa8\x1f\x49\xb3\x60\x37\xcd\x64\x57\xa7\xea\xa8\xf4\xf3\xbe\xdf\x68\xd0\x9f\xc9\xfa\x25\xa9\xd7\x54\xdb\x65\x36\x02\x85\x41\x2d\x1a\x6d\xa5\x37\x88\x90\x5f\xcf\x4e\xfa\x8a\x80\xcd\x86\xca\x48\xb8\x45\x63\x3d\x8c\x31\xc2\xae\x06\xf1\x6c\x4c\x6b\xbb\xe9\xcd\x1a\xfb\x59\xe1\x01\xbe\x50\xe0\x35\x35\xdd\x8a\x65\xe4\x5b\xba\x46\xd4\x5c\xb1\x4b\xad\xfc\x8e\x93\xab\x52\x67\xf4\xe4\x92\xab\x1f\x9a\x95\xe6\x1f\xca\xb8\x1c\xbf\x2b\xd8\x67\xa3\xec\x7b\x4b\xaa\x18\x9a\x0f\x08\x56\x70\x75\x59\x61\x29\xdc\xf9\xff\x1c\x50\x2d\x32\x79\xe8\xaa\x6c\xe5\x6e\xaf\x13\x45\x82\xa9\xe4\x30\xa5\xaa\x8c\xa1\x0c\x3d\xa8\xbc\x79\x3d\x02\x56\xad\x19\xae\xa7\x14\x9f\x0e\xa7\xea\x95\xfa\xcf\xac\x1c\x5c\xfd\x29\xd7\xa3\xfe\x1a\x41\x79\x75\x73\x9e\x14\xda\x8e\xdc\x81\x99\x00\x47\x2c\xa8\xc6\x97\x16\x32\x8e\x8a\x29\x9f\x97\x4e\xdf\xf7\x41\xaa\xbc\x1c\x07\x4a\x76\x1b\x3e\xc8\x76\x1d\xda\x2e\x7e\xed\x7a\xf3\x3e\xf0\x04\x09\x84\x9d\x41\x54\x97\xc5\xed\x5d\xfa\xa2\x25\x9a\x31\xd0\x76\x39\x81\x70\xb2\xd9\xd2\x10\x20\x8b\x4a\x4c\x7d\xb8\xc6\x26\xd1\xc5\x33\x56\x2a\x1f\x95\x48\x9f\x98\x19\xe4\x98\x5f\xc4\xe1\xd1\xa7\x07\xbe\x5e\x82\xb0\x05\x48\x1d\x86\x37\x7f\x42\x4e"}, +{{0x4b,0x2e,0x1a,0xe6,0x0f,0xa5,0xd3,0x83,0xba,0xba,0x54,0xed,0xc1,0x68,0xb9,0xb0,0x5e,0x0d,0x05,0xee,0x9c,0x18,0x13,0x21,0xdb,0xfd,0xdd,0x19,0x83,0x95,0x91,0x54,},{0x36,0xc0,0x20,0xb1,0x85,0x52,0x34,0x56,0x19,0xef,0x88,0x37,0xeb,0x8d,0x54,0x94,0x84,0x0e,0x85,0xf4,0x68,0x09,0x34,0x3b,0x4d,0x6f,0x40,0x61,0x25,0xda,0x55,0x7d,},{0x22,0x20,0x11,0x9e,0x83,0xd6,0x9a,0x6a,0x3e,0xed,0x95,0xfa,0x16,0x6d,0x1d,0x11,0x28,0xa3,0xf2,0x32,0xca,0x1b,0x78,0xbc,0x94,0xb4,0xd4,0x76,0xc4,0x77,0x94,0x43,0x61,0x4b,0x87,0x72,0xaa,0x22,0x32,0xcb,0x07,0x20,0xa0,0x55,0xeb,0x71,0xd8,0x40,0x7f,0x3a,0xb1,0x9b,0xaa,0x1d,0x96,0x2c,0x05,0x2c,0x84,0xc0,0xbd,0x58,0x96,0x08,},"\xfa\xb9\x8b\x2b\xbf\x86\xae\xb0\x50\x86\x81\x2a\x4b\x00\x49\xa1\x04\x2a\xbb\x76\xdf\x9c\xd2\x90\x87\x55\x70\x63\x03\xef\xed\xb1\xad\x21\xe8\xbc\x8d\x75\x62\x34\x9e\x1e\x98\xce\x0d\x75\x2f\x4b\x3d\x99\xe6\x77\x36\x8b\xd0\x8c\x78\xfe\x74\x25\xec\x3b\x56\x0e\x38\x3b\xd4\x2a\xf6\x49\x98\x86\xc3\x5a\xdd\x80\xa5\x82\x8b\x61\xd6\x64\x4d\x7d\xc4\x43\xba\x2c\x06\xf9\xba\xd2\xec\xcb\x98\x3d\x24\x45\x8f\x6a\xda\x1b\x10\xbb\x5b\x77\x17\x2c\x5c\xdd\x56\xd2\x73\xd1\xe4\x10\x10\xb2\x5c\xf4\x8a\x7d\x58\xd7\x25\x57\x02\xac\x12\xf2\xa6\xfe\x29\x18\x46\x63\x95\xf4\x60\xd1\x52\x36\xd0\x35\xae\x94\x10\xca\x86\xc4\x60\x51\x28\x29\x9f\xaa\xf0\x90\x15\xf1\xad\xee\x77\x68\xee\x1a\x8f\x8c\xa0\x6d\x10\xdd\x7f\x95\xc4\x6f\xa1\x02\x53\x06\x5f\x9d\x6f\x90\x29\x59\x08\x80\x9f\xd7\x79\x57\x1b\xe2\x9e\x0a\xe6\x6e\x0b\xcb\xde\xb7\x91\x3d\x2b\xbb\x76\xac\x30\x2f\x34\x52\xc5\x5e\xf1\x99\xa4\x8e\xce\xb0\xe3\x59\x6c\x7b\x4c\x03\x86\xda\xe7\x10\x1e\xa2\x44\xa3\x3c\x4c\xdc\x83\x06\x72\xdf\x83\x65\x5b\x35\x33\x80\x52\x30\x7b\x94\xd2\x23\xca\xb1\xaf\x69\xe0\x7f\x78\xe5\x8c\xbb\x0c\xb3\xc5\x35\x1e\x3a\x6b\x0c\x4a\x92\x7f\x75\x62\xc5\x98\xd2\xd3\xdf\x90\x56\x9f\x61\xdb\x1a\x3c\xb0\x14\x0b\x56\xea\x02\xcf\x77\x45\xfb\xee\xc2\x02\x86\x73\xd6\x7f\x1e\xc5\xf7\xda\xf9\x71\x5f\x75\x4a\x9d\x8e\xd4\x6a\x7a\x63\xef\x72\x2e\xe0\xd5\x89\x93\x31\xb6\x3c\x97\x4f\xa8\x80\x42\x94\x35\x76\x7f\x96\x25\x4e\xf4\x6c\x99\x68\xf3\xfe\xda\xaf\xea\xf3\xe8\xf4\x56\x34\xb5\x4f\x5e\x0a\x5f\xc2\xd2\x37\x3a\xb9\xe9\x8d\x9a\xcf\xe3\x69\x7e\x64\x2a\x18\xe0\xdf\xd9\xfb\xc2\xf0\x94\x86\x6d\x40\x1f\x0a\x4c\xa2\xa4\x56\xed\xf6\xa1\xa7\x7b\x9c\x29\x6c\x39\x22\x06\x7e\xb3\xd5\xa5\xca\x0a\x77\xf4\x30\xe4\xc8\x61\x1d\x8f\x05\xa1\xba\xac\x16\x35\xef\x7b\xa8\x3d\xfc\x69\xd3\x01\x94\x98\x56\xbe\x4d\x2c\x8a\xb6\x1d\xe2\x9c\xf3\x92\x50\xc5\x79\x4c\xbf\x57\x50\xcd\xa9\x5d\x04\x68\xaf\xa2\xb7\xf2\x3d\xba\x4e\xf5\xf5\x29\x5a\x3b\xf4\x14\x00\x18\xb7\xed\x06\x18\x84\x44\x4f\x5b\xb1\xb7\xd2\x39\x31\x2d\xd7\x39\x99\x95\x36\xc6\x84\x45\x6e\xa0\x6b"}, +{{0xb2,0x16,0xce,0xbf,0x87,0x80,0x24,0xc2,0x0d,0xfc,0x86,0xce,0x4b,0x37,0xbd,0xc4,0x7a,0xa2,0x8f,0x29,0x20,0x3b,0x5b,0x44,0x92,0x50,0x65,0xd9,0x93,0xa2,0x59,0xfe,},{0xc3,0x6e,0xdb,0xb6,0x25,0x4a,0x91,0x3f,0x08,0xfe,0x25,0x9e,0x23,0x87,0x80,0x63,0x8f,0x72,0xec,0x0b,0x30,0x07,0x26,0x4b,0xcc,0x60,0xa9,0xe8,0x1e,0xe9,0x29,0x8f,},{0xb7,0x38,0x9e,0xe7,0x8d,0xd9,0x76,0x3f,0x9d,0x28,0x92,0x91,0x2e,0xdc,0xbe,0x3e,0x8a,0x23,0x6b,0x8b,0xdc,0x25,0xf4,0x4b,0x9c,0xfd,0xc8,0xc4,0x7c,0xd5,0x81,0x68,0xab,0x56,0xeb,0x04,0x02,0xa5,0xbd,0x75,0x2a,0xc8,0xf4,0x97,0x8d,0x2e,0xa2,0xb6,0x5d,0x2f,0xa8,0x52,0x65,0x96,0x6b,0x9f,0x57,0x22,0x7e,0xf4,0xa5,0x9a,0xe0,0x09,},"\x9c\x87\x17\xcc\x86\xfe\x02\x48\x0b\xfd\x9e\x92\x2b\xd7\x6b\xff\xee\x21\x70\xc4\xcb\x1b\x13\xdf\x83\x4a\xc0\x1d\x45\x00\x60\x86\x29\x7f\x1b\x8a\x26\xf2\xba\x67\x4d\x33\xe1\xd1\x62\xf1\x93\x67\xfe\xba\x97\x35\x2b\x7d\xf2\xe7\x5b\x30\x9d\x4b\x6f\x8b\x07\xcc\x0e\xb6\x77\x7e\x81\xe2\x68\xe0\x2d\x07\xf2\xa0\x8f\x8f\x39\xd5\xa8\x32\x0b\xfc\x01\xfc\x8c\x92\x27\xd2\xcf\x05\xe1\x28\x91\xff\x4d\xe8\x85\xa1\xc9\x33\x71\xa0\x91\x0b\xa5\x33\x92\xaf\xf9\xba\x2e\xed\x9a\x20\x55\x97\x7e\xc4\x15\x7b\xd6\x5b\x34\xdf\x79\x37\x2f\x4d\x50\xed\xbc\x48\x92\x43\x53\xcf\xa1\x69\x23\x19\xd8\x8a\x7a\x5b\xb7\x26\x25\x4c\x20\x92\x91\xe9\xb1\xd2\xc1\xa6\xc8\x23\x63\x98\x10\x9c\x59\xed\x42\xa0\xac\x9e\x76\x33\xc5\x20\x73\x4e\xcc\xfe\xa4\xfe\xa9\x5a\x47\xa8\xf0\xa0\x68\xb4\x27\x50\x00\x43\x9c\xc9\x7c\x57\x87\x1e\x10\x5c\xc0\x79\x0e\x9d\xcc\x9c\x25\xd5\xaf\x70\x63\xff\xd0\x5c\x4f\x37\x80\xe7\xbc\xa4\xc4\x56\xd0\x17\x0d\xa7\x09\xfc\x6c\xb3\xfa\xa7\x2b\xdc\xf5\x62\x90\x8a\xe9\x34\x0a\xef\x4d\x0c\x8b\x91\xf0\xfb\xcc\xbc\xf1\xcd\x89\x8b\x1c\x71\x6f\x4f\x14\x74\xc3\xaa\x31\x62\x42\xab\xdf\x63\x68\xe5\x7a\x24\x7f\xf2\xfd\x5c\xe2\x3d\x18\x7f\x69\x4f\x11\xe3\x8d\xfb\xfb\xc3\xd9\xdb\x20\x90\x3b\x4e\xbb\x44\x9b\x90\x49\xee\x02\x0f\x6e\x2f\x50\x8e\x8b\x2b\x16\x5b\xad\x74\x64\xdb\xdd\x17\x8c\xbd\x42\x32\x33\x76\x5d\x37\x1e\x7a\xe1\xc3\xe8\x78\xcd\xb5\xb8\x24\xb2\x0c\xb3\x09\x86\x7c\x0e\x47\x3c\x06\x7e\x67\x44\x00\x85\x27\xb6\xbc\x07\x6d\x07\x7f\x48\x67\x62\x2a\xee\xd1\xc2\x53\xdb\xde\x7c\x6a\x76\xc7\x01\x59\x62\xfb\x73\x39\x16\x98\x60\x0b\xb3\x18\xff\xa7\xb0\x13\x6e\xe4\xcc\xb0\x7d\xaa\xf0\x1f\x40\xff\x9c\x19\x4f\x98\x68\x1f\x9f\xae\xf8\xb6\xf9\xe9\x9f\x95\xdf\x00\x80\xda\x89\x66\xa8\xba\x7a\x94\x74\xc5\x37\xb9\x2d\xf9\x79\x9e\x2f\xd1\x6f\x78\x8d\xad\x7a\x7b\xcc\x74\x52\x26\xe1\xe6\x37\x1f\x52\xeb\xcd\xbd\x14\x40\x44\xdd\xfe\x63\x2d\xfc\x0a\x43\xd3\xa4\x50\x92\x31\x70\xeb\xc7\xae\x21\x9e\x50\xe0\x78\xa5\x11\xbc\x12\xef\x14\xcd\x14\xb5\x30\x9f\x38\xab\xd6\x5d\xb2\xb2\xa7\xaf\x22\x43\xb2\x29\xc9\xfd\x2e"}, +{{0xaf,0xce,0xce,0xa9,0x24,0x39,0xe4,0x4a,0x43,0xed,0x61,0xb6,0x73,0x04,0x3d,0xcb,0xc4,0xe3,0x60,0xf2,0xf3,0x0c,0xd0,0x78,0x96,0xcd,0xa2,0x0c,0xb9,0x88,0xd4,0xe3,},{0xd2,0x31,0xf6,0x92,0x35,0xa2,0xe3,0xa1,0xdd,0x5f,0x6c,0x2a,0x9a,0xaf,0x20,0xc0,0x34,0x54,0xb9,0xa2,0x9f,0x4e,0x3a,0x29,0xab,0x94,0x68,0x9d,0x0d,0x72,0x3e,0x50,},{0xa6,0x55,0x45,0xcf,0x3d,0xf4,0x56,0xb2,0x8d,0x83,0xa6,0xd9,0x4c,0x03,0x6a,0x19,0xd0,0xd2,0x9f,0xb0,0x65,0xed,0xc2,0x7e,0x5e,0x93,0xa1,0xf4,0x02,0x79,0x89,0x7e,0x1c,0x6f,0x25,0x95,0x9a,0x72,0x5a,0xba,0xbc,0x87,0xcf,0x2a,0xe7,0x27,0xf3,0x46,0x7b,0x79,0x57,0x0e,0x90,0x27,0x11,0x91,0x71,0x91,0xd9,0xcb,0x0d,0x2d,0x66,0x0c,},"\x0b\x05\xf8\x9e\xbb\x33\x97\x94\x76\x87\xaf\xbe\xf0\xed\xe8\x7c\xf3\x81\x06\x76\x27\x70\x37\x52\x1d\x95\x2a\x3b\xbb\xbd\xc8\x56\x59\x88\xa0\x95\xd8\xd4\xf6\xf5\x9b\xe5\x72\xd3\xd8\x21\xdd\x78\x99\x77\xef\x77\xa2\xfd\x71\x10\xce\xee\xd9\xf3\x75\x6e\xd8\xe1\x88\x26\x7b\x97\xa3\x0e\xf8\x95\x7c\x78\xae\xa3\xa2\x96\x3d\xec\xa6\x18\x60\x54\x5e\x0c\x40\x82\x48\x81\xeb\xb1\xdb\x10\xf6\x07\xe1\x0d\xdb\xdd\xce\x40\x0e\xa2\x36\xba\x47\x45\xaa\x99\xa0\x56\x41\x97\x67\x66\x78\x9e\xd0\xda\x7d\xb5\x5f\xda\xb4\x59\xeb\xd4\xb4\x41\xa6\x28\x2f\x7c\xfd\x5a\x20\xea\x06\xef\xfa\x33\x59\x55\xe5\xfd\x29\x18\x16\x71\xbc\x92\xc0\x00\x52\xf7\xf7\x5c\x39\x27\x7c\x9a\x43\xb7\x87\xac\x9f\xb1\x51\x6e\x99\x62\x32\xa5\x09\x77\x4d\x1d\xc2\x1d\x8c\x05\x13\xf7\x84\x4b\x0a\x5b\x5f\x18\x95\x75\x81\xf9\x90\x44\xa1\x42\x23\xcc\xda\x8a\x28\x4d\xe1\x2f\xd4\x24\x26\x5f\xe5\x7b\x27\x02\x15\xf8\xfa\x9f\xf2\xbe\xa5\x17\x93\x4e\x48\x00\xa4\x7d\x34\x6f\xb6\xc3\x61\xcf\xba\xbe\xff\xab\xd9\xc4\x16\x4f\x45\x15\x6e\x24\x5c\x97\x7e\xdb\x47\x36\x42\xc3\x94\x0b\xe5\xad\x6f\xd1\xa7\x11\x9a\x7b\x18\xe9\x8d\x6d\xc8\x43\xe0\xd2\x54\xc9\x3d\x01\x46\xd1\x8e\x5c\x62\xed\xe1\x49\x0f\x89\xa6\x05\xeb\x45\x4f\x97\x47\x78\xcf\xae\x20\x93\x2e\x95\x47\x7b\xd0\x3b\xcd\xb9\x7d\x5b\xcb\x76\x33\x59\x42\xe9\x2e\xe6\x68\xf2\x31\xe6\x9c\x57\x0a\xc5\x44\x6d\x0f\x77\x40\x66\x73\x7f\xdf\x49\xf1\x0c\xeb\x1b\x52\xd6\xd8\xa4\x63\x98\x46\xa3\x37\x3a\x7c\x6f\x3b\x4b\x31\x59\xfe\x2e\x7a\xf7\xee\xe2\xf0\xdf\x17\x2d\x94\xd2\x55\xd0\x17\x65\x1d\xa3\x00\x90\x05\xe5\xea\xc3\x17\x6c\x09\x38\x9e\xe4\x0d\x70\x38\x3b\xd3\x71\x17\xec\xa0\x83\x59\x8a\x18\x01\xf5\x92\xd0\x57\x18\x6e\x56\x8e\x24\x7c\x25\x2b\xe4\xb1\x4f\x72\x3a\xb7\xdd\xb9\x7a\xe9\x76\x8c\x26\x82\xfd\x63\xac\xc3\x00\x77\x9f\xe0\x4e\x2b\x88\x87\x47\x51\x34\x6c\x9e\x0f\x97\xa2\xa2\x16\x77\x2f\xf9\x62\x5c\x33\xbd\x7e\x29\xfe\xd8\x00\x3a\x08\xdb\xd3\x3b\x5d\x17\x89\x9c\x94\x3c\x25\xe9\x5a\xd7\x54\xfb\x63\x2e\x04\x7c\x11\x2a\xf7\xf7\xce\xba\x72\x36\x2e\x1a\x3d\xdd\x29\x35\xaa\xf7\xf8\x18\xa2\x7c"}, +{{0xb8,0x34,0xc6,0xe0,0xfa,0xcb,0xff,0x58,0x0d,0xd3,0xb2,0x37,0x53,0x95,0x9a,0x4c,0x21,0x54,0xc2,0x19,0x52,0x1b,0x3d,0x27,0x03,0x5d,0x07,0x1f,0x65,0x99,0xbd,0x02,},{0xd1,0xc3,0x84,0x71,0x5e,0x3b,0x3d,0x02,0xc1,0x3e,0x09,0x06,0x05,0x53,0x4c,0x7d,0xb7,0x40,0xda,0x2a,0xa5,0x60,0xf5,0x32,0x00,0xa3,0xce,0xd8,0xbe,0xae,0x8c,0xf8,},{0x0f,0x19,0xb7,0x06,0x6d,0x57,0x92,0x32,0x8a,0x98,0x00,0xd9,0xd4,0xf8,0xf6,0x7d,0x5b,0x08,0x9b,0x54,0x12,0x26,0xa1,0x67,0xda,0xcd,0x43,0x9f,0xa4,0x85,0xb0,0x02,0x5a,0x5d,0xc7,0xf2,0xc7,0xe2,0x3f,0xc4,0xa5,0xc6,0x86,0x9e,0x76,0x19,0xd3,0x56,0x39,0x97,0x00,0xc9,0x36,0x50,0xe8,0x9c,0xd2,0x5b,0x90,0xfb,0x99,0x25,0xe3,0x04,},"\x6c\xf1\x47\xb1\x60\x55\x28\xa3\x6b\xe7\x57\x16\xa1\x4b\x42\x0b\xcf\x06\x7c\x03\xf1\xcf\xe9\xc4\x40\x2f\x14\x98\x7f\xbf\xc9\xd3\xec\xc3\xcc\xf4\xf8\xd2\xd0\x3a\x55\x90\x0b\x8d\xc7\x9a\xf3\xb6\xe7\x74\x36\xf6\x9b\x14\x17\xad\x4b\x68\xfd\x44\xe5\xe3\x33\xed\x90\xea\x79\x43\xfb\xd1\x12\x26\x09\xec\x8f\xf6\xbb\x25\xe4\x2e\x99\x14\xf5\x92\x0f\xc7\x2c\x4d\x01\x3b\x6a\x96\x85\xc9\x96\xfb\xd8\x35\x2a\xaf\xb1\x84\xc2\x2d\x9e\x47\x87\x1a\x52\x80\xe4\xab\x7d\xd6\xa5\xcf\xd1\x0a\x59\x94\xa2\x00\xf6\x70\xe0\xb6\x22\xa9\x39\x4d\x47\x93\xd0\xa4\x20\xe7\xd8\x80\x6c\xb1\x27\xc7\xac\x69\x0d\x45\xa2\xe9\x41\x66\xce\xa6\x72\xbc\xd9\x82\xb0\xe9\xba\xad\x56\x31\x2d\x25\x70\xdd\xde\x7e\x0b\x9e\x7f\x47\x13\x6f\x04\x81\xd0\x0f\x66\xa2\xaa\xca\x4d\x1b\x09\xd7\xce\x6c\x5a\x98\xa7\x6b\x68\xcd\x97\xd5\x79\x39\x68\xd6\x67\x07\x3f\x82\x17\xf9\x05\x47\x35\x34\x0f\x9b\x14\x9c\x0d\xce\x84\x5b\x09\x9e\x88\xd0\x70\x96\x80\xf0\xf7\x76\x03\xff\x0a\x23\x31\xc5\x58\xfc\x36\xd5\xf2\x4d\xa9\xa6\x2d\x69\xaf\x51\x90\xd2\x1b\x5c\x85\x7a\x1e\x08\xf0\x14\xc6\xd4\x56\x46\x86\x65\xa7\xf8\x45\xc6\x6f\x91\x11\xf9\xc0\x98\xc6\x89\x40\xef\xcd\x87\xb6\x57\x07\x0c\xb9\x16\x4b\xc9\x74\x3a\xce\xb7\x43\x9a\x0d\x01\xc0\x06\x2a\x11\xaf\x2e\x11\x34\x93\x97\xf5\xd1\x52\x87\x2b\x13\xc5\xab\x32\xf5\x1c\xc5\x8f\x14\x75\xec\x82\xac\x67\x15\x61\xdc\xbd\x34\x3c\xfb\x3c\x5f\x78\xd0\xfc\x73\x05\x3c\x60\x04\xb0\xa4\xca\x3f\x20\x43\xff\x4b\x0c\x54\x27\x5c\x4f\xcb\x9c\xad\xc6\xba\xab\xe5\x7b\x1d\x5a\xcd\x53\x1e\x97\x2e\xf9\x33\x51\x36\xcd\x1d\x65\x51\x2b\xa1\xf5\xb6\xcc\xc4\xb6\x6b\x42\x50\xaa\xfa\x29\x67\xdd\x42\x11\xa2\x74\x2e\x0f\x17\x7d\x8f\x40\x63\x89\x9f\x61\x81\x5c\xbe\x6d\x8f\xbf\xcd\xf7\x48\x12\xbd\x40\xcc\x10\x08\x4e\x46\xa9\x9a\xc1\x28\x05\x8e\xaf\x16\xa4\x9a\x24\xb6\xae\x22\x8e\xcf\x01\x09\xc5\x2d\xfc\x06\xe3\x7d\x6a\x33\x3b\xcb\x24\xab\xa3\x12\x16\x4c\x6c\x02\x90\x48\x5d\x25\x12\x80\x53\x8c\xe9\x54\x1c\x09\x16\x64\x0e\x36\xd6\x92\x9d\xcd\x95\x88\xeb\x99\x57\x7f\x5f\x6d\x82\xbc\xbb\x19\x88\x26\x26\x7e\x49\xf5\xda\xff\x2c\x0d"}, +{{0x22,0x69,0xa5,0xd8,0xf7,0xac,0x2c,0xd9,0x04,0x8f,0x5f,0x49,0xe3,0x49,0xe5,0xc4,0x35,0xa1,0x59,0xb3,0x19,0xfe,0x3b,0x30,0xbf,0xac,0x8d,0x0d,0x50,0x59,0x43,0xf4,},{0x1c,0x81,0x79,0x43,0xdc,0x39,0xc2,0x4b,0x01,0xda,0x38,0xa4,0x87,0xb1,0x75,0x48,0x24,0x60,0xc6,0x09,0xe4,0x72,0x63,0x49,0xa9,0xaa,0x7a,0xea,0x9b,0xc0,0xfb,0x34,},{0xbe,0x0f,0xb3,0x30,0x8a,0x07,0x6a,0x61,0xa4,0xa9,0x2a,0x97,0xf6,0xac,0x55,0x32,0x71,0x90,0xe1,0x34,0x1d,0x6d,0xd4,0x10,0xd8,0x6b,0x41,0xbd,0xaf,0x2d,0x33,0x74,0x09,0x3e,0xf7,0x20,0xbd,0xb7,0x7f,0xeb,0x70,0x14,0xe0,0xf7,0x7d,0x3b,0x80,0x96,0x23,0xc7,0xca,0x53,0xe2,0xae,0x4b,0x09,0x71,0x13,0xe9,0x6d,0xb7,0x7a,0x2d,0x08,},"\x71\x53\xd4\xd9\xe6\x41\xaa\x61\x92\x0d\xb0\xff\x4b\xd5\x37\xa6\xd6\x13\x0a\x39\x65\x54\xcc\x94\x53\x76\x98\xf9\xca\xd1\x6b\x99\xee\xbe\xfa\x5f\x27\x76\xf2\xfe\xaf\xf6\xbd\x9a\x69\x04\x12\x0c\x67\xe0\x88\x3f\x6b\x96\xbb\xbb\x19\x5e\x95\xae\xc7\x53\xb6\x99\xba\xb3\xd0\x39\x44\xc1\x3c\x72\xfc\x84\xe3\xf2\xcb\xf6\x29\x6f\x64\x55\x49\x11\x1c\x93\xfa\xe1\xa7\x59\xbf\xcd\x16\xfc\x09\xe6\x0b\xb9\x78\x55\x35\xad\x27\xda\x24\x4e\xf2\xf8\x57\xf2\xde\x99\xa6\xe9\x21\x88\x89\x0e\x45\x2c\x7f\x5b\x9e\x3a\x4b\x96\x8e\x11\x74\x3b\x6f\xc7\xfa\xf1\x27\x5e\x53\x60\xa5\x46\x89\x41\x79\x78\x94\xd7\x70\xfa\x7d\xa3\x64\xa3\x37\x30\x22\x39\xfe\x83\xae\x0b\x0d\x08\x4a\xa1\x2a\xcd\xc6\x34\x62\x52\x4e\x0e\xb1\x0f\xef\xe8\x1b\xa9\x6f\x71\xf2\x75\xf3\x44\x9a\x3f\x8d\xb2\x1d\x58\x74\x9a\x38\x85\x3d\x39\xb0\xad\x8e\x69\x89\x1b\xd2\x04\xdf\xca\x8f\x6c\x23\x9d\xc9\xa0\xac\x27\xf5\x4d\xb4\x23\x8d\x47\x06\xdf\x11\xd6\x07\x36\x9d\xc7\xf7\x04\xda\x1d\x39\xf2\xe8\x2a\xf8\xc2\x83\xd2\x20\xc1\x24\x31\xf5\x6d\x80\x30\x69\xb4\xac\xb7\x70\x81\xc0\x31\xae\x33\x19\xfc\x77\xfc\xa7\x84\x50\x97\xfd\x72\x7a\xd0\xd0\x80\x89\x5b\xba\x23\xe8\x73\xd2\xde\xf8\xcd\xc2\x16\xc3\xee\xd6\x1b\x08\x76\x1b\xb9\xeb\xce\x02\x82\xcf\x50\x2a\xaf\x6c\xe7\xe8\xc0\x58\x63\x79\x58\xc3\xea\x1b\x72\xfe\x6e\x8d\xf8\xd3\x7a\xc0\x55\xdb\x69\x92\x58\x7f\xab\xbd\xc4\x67\xf5\x24\x75\x64\x4f\x91\x88\x63\xaf\x62\x04\x92\xf3\x46\x80\xf2\x05\x6c\xbc\xab\x75\xe2\x32\x36\x26\xc0\x94\x75\x9c\x0e\x0e\x99\xef\x19\x75\x95\x27\x25\x06\x46\xad\x76\x01\x20\xba\x38\x66\x99\xd5\x39\x34\xf9\x56\xb8\xbb\xc7\x39\x5b\xb4\x96\xce\xb2\xdd\x22\x3c\x7b\x50\x1b\x92\xd3\x6a\x95\xf8\xf0\xa0\x2e\xb5\xba\x4d\xdd\xf1\x66\xb9\xb9\x5b\x4a\x59\xe7\x2a\x30\xc6\x3c\xf2\x1e\x60\x85\x75\x19\x23\xd5\x4b\x30\x28\x1e\x52\xa0\x96\x18\xe6\xf0\x23\xba\x0a\x21\x67\x5e\x7f\x98\x9b\x89\x91\x58\x8c\x96\xc2\xb5\x6a\x78\xf5\xd2\x94\x5a\x7b\xae\xb6\xa0\xc1\xbb\xd5\xd9\x5a\xf3\xee\x83\x0f\x58\x09\xc7\x94\xa1\x5a\xb4\xb5\xf8\x9d\xd2\xbe\x2d\xfd\xcd\x8f\xe0\x52\x0f\xda\x2b\x3f\x02\xa1\xac\x01\x55"}, +{{0xe9,0x65,0xb3,0xf2,0x57,0x35,0x66,0x85,0xc9,0x8b,0x42,0xb9,0x64,0xa2,0x53,0xfc,0x49,0x53,0x99,0xcc,0x94,0xb0,0x99,0xc2,0x44,0x5f,0xc8,0x1c,0x75,0x9c,0x68,0xe5,},{0x68,0x9f,0x54,0x10,0xc8,0xe0,0xf4,0xd3,0x7b,0xc0,0x7c,0x85,0xd7,0xcc,0xe6,0xc9,0xb6,0x36,0x01,0xf9,0xbd,0xaf,0xec,0xaa,0x44,0x8a,0x5e,0xed,0x64,0xaf,0xc8,0xc6,},{0x8d,0x2b,0xc4,0xe1,0xcd,0x25,0x6a,0xad,0x8a,0x15,0x1d,0xec,0x01,0x0d,0xc9,0x3a,0x5e,0x5c,0xca,0x58,0x29,0x8d,0xec,0x49,0xcb,0xc9,0xc4,0x71,0x7b,0x5c,0xfb,0x54,0x60,0xd4,0x30,0xbe,0x72,0x6b,0x0f,0x30,0x2c,0xbd,0x92,0x6b,0xee,0xa1,0x9a,0xa3,0xc9,0x3a,0xeb,0x45,0x2a,0x44,0xf6,0x00,0x7a,0xf4,0x9a,0xdf,0x2f,0x05,0xbb,0x04,},"\x6f\x20\xa9\xad\x27\xe3\x0d\xac\x76\xb3\x0d\x4c\x19\xa5\xbd\x6d\xfd\x6d\x04\x92\x13\xf4\xbe\xcd\xd9\x63\xd7\x2b\x8b\x2d\xad\x68\x7b\x00\x38\x08\x20\x1d\x50\xf7\xdd\x6e\x59\x9e\xf5\x8c\xeb\x60\x68\xc5\x45\xed\x99\xb9\xe7\x63\xf9\xb0\xec\x1d\xb5\xfc\xbd\x7d\x49\x0a\x12\x1e\xce\xc6\xbb\xa1\xeb\x5e\xdb\xd6\xde\x85\x36\x47\x07\xc5\x5e\x30\x0c\x8b\x16\xbb\x25\x30\xf7\x08\x98\x13\x66\x89\xc9\x88\x59\x1d\x53\x91\xd9\xcc\x34\x7d\x79\x31\x06\x1a\x9b\x76\x96\xe2\xc9\xf3\x5b\xc0\xd3\x04\xa8\x1c\x2c\xf9\x54\xd9\xc3\xa8\x8a\x22\xe1\xd6\x7b\xbe\x0a\x85\x30\x84\x77\xf6\x29\x18\xc2\x5d\xb5\x04\xe4\x76\x2f\x0e\x3b\x42\x46\x00\x79\x08\xac\x70\x17\x79\x00\x6b\x77\xd7\x25\x10\xed\xc6\x9e\x17\xd0\xf6\x39\x4c\x77\xe5\x55\x18\x75\xa4\x46\xf8\x12\x33\x41\x5d\x0a\x91\xa0\x46\x0b\x51\xc4\x13\xd6\x44\xe8\x50\xf8\x55\x72\x81\xc4\x66\x99\xe5\x3b\x22\xa7\xc7\x3b\x06\x8e\xa3\x86\x52\xcf\xf3\xb0\xa7\xb8\xba\x30\x97\x1e\xab\x18\xfd\xbb\xd8\x73\x9e\xe1\xee\x0c\xd5\xcb\xfb\x7d\x5d\x41\x75\x7b\x63\x31\x27\x1f\xb7\x80\x97\x51\xe2\x03\x51\x3c\x99\x70\xf6\x6d\x91\xbc\x0c\xe0\x62\xf4\xfc\xb2\x8b\xe0\xa6\x99\x86\x7b\x79\x59\x4c\x64\x58\xa0\xd3\x07\xac\xac\x91\xf4\x13\xc4\x61\x58\x77\xdc\x53\xe1\xb0\x18\xda\x5c\xfc\xe1\xb6\x3f\x40\xbe\x1e\x55\x27\x4c\x43\x74\xcd\xfc\x21\x52\x44\x99\xa6\x83\xa2\x31\xad\xef\x77\x9d\x19\x21\x44\x0e\x5d\x3f\xdb\xd5\x03\x3d\xc9\x83\xcf\xc9\x31\xab\xe6\x38\xc3\x5d\x5a\x95\x86\x9e\x9f\xe3\xd9\x3e\xb9\x0b\xd1\x86\x1f\x85\x5c\xe1\xf6\x08\xb7\xbc\xad\x6b\x5e\x1b\xd9\x7e\xdc\x95\xed\x5d\xdc\xbc\xb7\x15\xd9\x19\xf5\xff\x77\xdf\x2d\xa4\x38\xf7\xa3\xa9\x82\x86\xdb\xd5\xb6\xe0\x43\xfc\x73\x72\xf6\x97\x04\xf0\x9d\x86\x55\x30\xf4\xf0\xed\xd3\x30\x0f\x18\x5b\x6d\x73\xd8\x71\x6d\x32\xd3\x2b\x1c\x9a\xc2\xdd\xf4\xf9\x02\xd3\xf2\x16\xd3\x5a\x33\xf3\x68\x09\x5d\xed\x10\xbe\x94\xbb\x53\xd6\xf2\x56\x56\x0f\xac\x2f\x4a\xf0\xed\xf5\xc5\xc7\x02\x14\x37\x77\x12\x6e\x7d\xe3\x2d\x07\x49\x39\x32\x66\x21\x29\xba\x0e\x7f\xc7\xcf\xb3\x6f\xd2\xca\x53\x16\x46\xe8\xcd\x22\x11\x85\x4f\xc5\x10\xaf\x3b\x1e\x8c\xaf\xde\x7a"}, +{{0xbc,0x3b,0x1e,0x0b,0xf8,0xd6,0x9e,0xa5,0xb4,0xcb,0xbf,0x10,0xbb,0x33,0xfc,0x95,0x5a,0xdc,0xbe,0x13,0xfc,0x20,0xaf,0x8a,0x10,0x87,0x2c,0xe9,0xdf,0x39,0xd6,0xbd,},{0xac,0xcd,0x26,0x28,0x15,0x59,0x19,0xbb,0xc7,0xf9,0xd8,0x6f,0x91,0xda,0xfe,0xc3,0x5c,0x71,0x1a,0x78,0xc7,0x9a,0xd3,0x60,0xed,0xdb,0x88,0xfa,0x8a,0x18,0x0b,0x2d,},{0x6e,0xf7,0xf0,0xe9,0x1f,0x2c,0xc6,0x71,0x5f,0x8e,0x5a,0x98,0x57,0x4b,0x44,0x00,0xc2,0x61,0xa6,0x43,0xe0,0x54,0x5f,0xf2,0x67,0x47,0xf8,0xe1,0x73,0x98,0x99,0xd7,0x66,0x40,0xb6,0x45,0x1c,0x43,0xc1,0xd0,0x3a,0x47,0x75,0xb5,0x4f,0xcf,0x9b,0xce,0x18,0xed,0x3f,0xcc,0xad,0x33,0x8b,0x77,0x64,0x02,0x4f,0xdf,0xa2,0xde,0x82,0x01,},"\x4c\x73\xe0\x4a\xbe\x08\x19\xde\x1f\x84\xd7\x05\x41\xeb\x1b\xb6\x1c\x4f\x42\x92\x0e\x1f\x2d\x1d\x9e\x62\x81\xa8\xa2\xe8\xb3\xeb\x45\x53\x7d\x83\x96\x90\x27\xf9\x9e\xf0\xea\x27\xca\x08\x5b\x13\xf9\xdb\x48\x0f\x00\xc0\x2f\x3f\xd7\x42\x9d\xd5\x67\x70\x89\x53\xbb\xf3\xb9\xe8\xe2\xc6\xac\x4d\x32\x1f\xf8\xf9\xe4\xa3\x15\x47\x23\x08\x5a\x54\xe9\xc9\x57\x3c\xc7\x35\x0c\x09\xf8\x97\x3f\x94\x8b\x08\x73\x03\x73\x59\x7a\x5f\xd0\x34\x98\x21\xae\x0a\x3c\xd6\xc8\x49\x92\xb1\x89\x12\x8f\x34\x90\x98\x7e\x1e\x9a\xd4\xf6\x57\x4c\xa5\x38\xfd\xfd\x83\x28\x4c\x1e\xb0\x95\x3f\x24\xc0\x8f\x74\x93\x2d\x43\x64\xdb\xbe\xf9\x22\x54\x24\x40\xda\xe8\x04\x24\xa9\x2e\xae\xf2\x7c\x18\x89\xbd\x08\xc4\x4f\x9d\xf0\x3a\x3a\xf3\x0d\xff\xb4\x8f\xae\x44\x5e\x62\x5f\x4d\x92\x65\xcf\x38\x7a\x1d\xa3\x5f\xe4\xc2\x31\x50\x45\x35\xdb\x72\xea\x81\xa1\x86\x80\x5f\x85\x6e\xbe\x6a\x6a\x65\x24\x14\x32\x53\x0f\xe6\xc9\x60\xc5\xf9\xbe\x6c\x22\x95\x70\x60\x30\x4e\x9d\xd8\xef\xbc\x1e\x48\x2e\x7d\xdb\xd8\xaf\x03\xbf\x23\x82\x89\x9c\x98\x6d\x91\x66\x11\xe4\xf2\x7a\xe5\x2f\x81\x7e\xf0\x1b\x6a\x14\x1f\xe4\xf6\x85\xd9\x4d\xc8\xcd\x52\x83\x00\x43\x93\x45\x87\x70\x4c\x1e\x64\x2e\x8f\xe5\x6b\xe6\xd6\xb8\x5b\xf4\xa6\xfe\xb2\xb6\x85\x8f\x1f\x00\x7f\x99\xd3\x9e\xa0\x4c\x9f\xe5\xfa\x7e\xf1\xb9\x1f\x49\x5e\xd0\xe7\xfa\x42\x13\xdd\x68\xce\xa4\x2b\x67\x29\xf9\x50\x31\x90\x7e\x27\xc4\x40\x98\x09\x43\x86\xfa\xbf\xb0\x4a\xb9\xb4\xde\x3d\x68\x61\xde\x46\x23\x12\xc5\x9b\x27\xc7\x6f\x7b\x6a\x4f\xc7\x1e\xa0\xd5\xda\xf6\xb7\x32\x05\x21\xa6\x7e\x5c\xb3\x75\x04\x97\x6a\xd7\x3d\xae\x2d\x64\x9f\xeb\x75\xe2\xea\xdd\x34\x01\xa7\xf2\xf3\x6e\x16\xdf\xbf\xbd\xb2\xaf\x57\x16\xcb\xa1\xbc\xe2\x0c\xd4\x7c\xe1\xc1\xd7\xbe\x00\x69\x70\x01\xfb\xbe\xb4\x91\x5a\xa6\xe5\x39\x3b\x5a\xb2\x0e\x0f\x31\xf5\x11\x91\x49\xa2\xcb\x4c\x4d\x45\x2c\x81\x56\x11\x3a\xc7\x82\x4f\x84\xf0\x9a\xeb\x81\x20\x2e\x8d\xd3\xda\xc0\xaa\x89\x39\x9b\x5a\x38\xb1\xe2\x18\x30\x19\x60\xa3\x7d\x52\x63\x2e\xea\xef\xe3\x68\x74\x55\x46\x42\x88\xeb\x17\xd9\xe1\x9a\x3a\x72\xed\x9d\xe3\x2c\x17\xbe\x79\xa3\xb9"}, +{{0x10,0x71,0x8f,0xa6,0xe2,0xd7,0xf6,0xed,0x38,0xfd,0x66,0xcb,0x6d,0xbf,0xa0,0x87,0xe8,0xf1,0xe8,0xa8,0xa2,0x4f,0xab,0x58,0xd7,0x9d,0x79,0x54,0xb8,0x72,0x0c,0x3e,},{0x87,0x0d,0x4f,0x66,0x6d,0x06,0xfd,0xa9,0xf9,0x51,0x1b,0x58,0x60,0x2e,0xec,0x05,0x0d,0x75,0x4e,0xa6,0xd8,0xe7,0x9c,0xdd,0x19,0xf6,0x01,0xc4,0x77,0xdf,0x1a,0xa0,},{0xe1,0x65,0x91,0x86,0xf1,0xf7,0x6f,0xe4,0x3a,0xc8,0xa1,0x17,0x03,0x36,0x0f,0xbe,0xff,0x53,0xb5,0xe5,0x7b,0x59,0x74,0xaa,0xa0,0x8e,0x25,0x75,0x57,0x9c,0x27,0x08,0x4c,0xf6,0x80,0x2e,0x7c,0x20,0x63,0x47,0x31,0x44,0x75,0xb6,0x03,0x19,0x74,0x94,0xe7,0xd6,0x1f,0xe4,0xb1,0xee,0x7b,0x78,0xe1,0x8d,0x94,0x46,0x93,0x52,0xdf,0x0c,},"\x41\x25\x9b\x6e\xef\x13\xd6\xff\xe3\x3c\xdd\xe7\x99\xb9\x95\xc4\x0b\xe7\x82\xcf\x97\x84\x40\xb6\x6b\xe5\x1c\x44\x05\x82\xab\xd4\x2f\x52\x66\x96\xbb\x3c\xb9\x22\x65\xb1\xed\x0e\x4b\xba\x76\x4c\xae\x28\x39\x83\x0a\x25\x26\x35\xdc\x80\xce\x5f\x73\xd5\x21\xb3\xd6\xff\x03\xac\x30\xe1\x98\xad\x20\x56\x7e\x75\xa3\x4f\xa8\x25\xeb\xf9\x84\x15\x08\xda\x84\xcd\x67\x42\x36\xca\x7b\x43\xde\x35\x64\xc9\x4a\xb0\x79\x40\x8f\xd9\x41\x37\xce\x3f\x90\xa5\xdd\x5d\x3a\xc3\x9a\x05\xec\x86\x71\x5a\x8f\x02\x5e\x45\x39\xa7\x64\x0a\xb8\x88\x36\xf4\xef\xba\xbd\x5e\x16\x52\xc4\x9e\xa2\x16\x13\xac\xfe\x34\x3a\x88\x0e\xe5\xa4\x2f\x2f\x91\x34\xef\x4e\x37\x16\xb1\x6d\x13\x4a\x9c\x4c\x71\xc3\x9b\x3c\x1a\x85\x7d\x3c\x89\x43\x97\x83\xee\xf1\xed\xd7\x1b\xf4\x49\x2d\x05\xfd\x18\x67\x3a\x52\x42\xff\x41\x87\xb9\xde\x47\xad\x49\x68\xda\x49\xdb\xa5\xa6\x09\x2e\x95\xea\x27\xdd\xfc\x74\x48\xdc\xf5\x97\x2d\x9d\x22\x8d\x63\xe5\x29\x1b\xa6\xe6\xfb\xd0\x7e\x32\x41\xf9\x36\x6c\xa4\x97\x6b\xb0\x4b\x22\xd0\x1f\x0d\xba\xe7\x94\xfa\x9c\x1d\x90\x29\xf8\x8a\x83\x60\x2b\x0e\x0e\xc5\x5e\x22\xc3\x7b\x20\x11\x25\xca\xdb\x53\x41\xef\x73\xf6\xda\x1a\xbb\xe2\xb1\xc4\x75\xf0\x75\x03\x45\xb1\xbe\x42\x59\xd8\xc2\x85\x31\xff\xe7\x78\x86\x67\xc4\x10\xda\xc3\x39\x91\x8c\x86\x9b\x00\xab\x80\xf2\x0b\xf7\x99\x0d\x36\x6f\x9b\x3d\x5e\x8e\xb2\xf4\x8d\x7e\xd0\xe6\x4b\x85\xdc\x9f\xe3\xbb\x99\x8b\x1e\xec\xd1\x23\x1e\x90\x2d\x2d\x15\x2e\x09\xda\x2d\x25\x92\xbd\xb3\x2c\x8c\xd2\xe2\xc4\x89\x49\x6b\x29\x80\xc0\x3d\xbb\x09\xec\x7f\x8a\x4e\xa2\xc7\x02\x0f\x2a\x0f\xaa\x65\x7c\xd6\xce\xd4\x8d\x6d\xa2\x78\x64\xcf\x5e\x97\xee\xa9\xb3\xc2\xf0\xf3\x4a\xbf\x8d\x87\xbd\x2a\xde\xb6\x0c\x72\x72\xfc\x43\x06\xd9\x55\xbd\xc8\x02\x3d\x7d\x3d\xc2\xf3\xda\xfe\x9e\xbe\x8a\x8d\x13\x89\x65\xa7\xf6\xce\x93\x51\x7c\xd2\x09\x96\x63\xf6\x7c\x34\x55\x21\x76\xdd\xb5\x95\xac\x6e\xa5\x60\x9f\xeb\xcf\x24\xc7\xd6\x9d\x41\x27\x09\xe5\x78\x67\x0a\x21\xac\x8a\xfc\xcb\x8b\xf2\xb1\x8f\xf3\xaf\x7d\xe2\x1d\xc7\x1d\x50\xd6\x0d\x37\xb6\xed\x72\x9d\xb0\x4b\xef\xf7\xd3\x4b\x29\x20\xd8\x75\x51\xce\x15"}, +{{0xc1,0xd4,0x72,0x4c,0x6c,0xb1,0xbc,0x67,0x23,0xb2,0xb4,0x30,0x34,0x27,0x8b,0x3c,0x5b,0x48,0xfe,0xd7,0xf8,0xa3,0xcc,0x23,0x18,0x03,0x3e,0x75,0x52,0x04,0x73,0x51,},{0xc2,0x7e,0x39,0x2e,0x7c,0x36,0x64,0xb9,0x06,0x1e,0xa7,0x6d,0x25,0x75,0xdd,0x7c,0x41,0xea,0xf1,0xda,0x3a,0x65,0xf3,0xa9,0x86,0xe0,0xa5,0x7f,0x6c,0x40,0xc1,0x7e,},{0xd3,0x7a,0x6e,0xc8,0x2e,0xd4,0x5c,0xa9,0xb4,0x85,0x5d,0xe9,0xcb,0x94,0x25,0x64,0xe8,0x83,0xff,0x70,0xa7,0x9b,0x8e,0x71,0x2d,0x5f,0x60,0x4e,0xc8,0x97,0x4d,0xe5,0x36,0x3a,0xc8,0x49,0xcb,0xab,0x28,0xe7,0xae,0xef,0xf2,0x8e,0xd3,0xf2,0xd1,0x4b,0x60,0x8b,0x31,0x46,0xc2,0xef,0xe0,0x73,0x5a,0xd8,0x15,0xc7,0xd7,0x5a,0x1a,0x01,},"\xde\xee\x99\xd7\xa7\x7d\x43\x00\xc1\x7a\xec\x1a\xb3\x23\xc5\x71\xc6\xe9\xe7\x3a\x43\x49\x1a\x3c\x78\x88\xb7\x6f\xc0\x3e\xc4\x3d\x07\xaf\x42\xa0\x5a\x2a\xa3\x22\xd0\x0c\x85\x60\xac\xef\x31\x41\x06\xb1\x0b\x9b\xd1\x26\x54\x35\x7f\xfa\x26\xf2\x39\x00\x50\xda\x63\xd6\x68\xc9\xe2\xdf\x54\x8f\x87\x63\x9e\x09\x6a\x35\x85\x3f\x82\xe7\x61\xfd\x71\x1d\x2a\x26\x54\x38\xf5\xd4\xdb\x5e\x32\x77\x57\x08\x15\x0d\xa6\xcb\x68\x6a\x2b\x4c\xa2\x11\xd7\xf0\x0d\xc0\xab\xcb\x2c\xa1\x50\xe7\x91\x11\x6a\x10\xa5\xef\xcf\xf3\x51\x4d\xab\x8e\xd8\x0a\x70\x92\xc3\xa0\x15\x15\x2c\xb2\x5d\x9f\x86\xec\x0d\x1c\xa6\x7d\xda\xb4\x4d\x64\xee\xb1\xf9\x31\xbf\xab\x2a\xb1\x88\x95\x6c\x74\x3d\xb4\x81\x48\x08\xc5\xcd\xe1\xb0\x74\x5b\x3e\xdd\x34\x0e\xb0\x3f\xfc\xc8\x0a\x78\xf3\xdb\x31\x0f\x4f\x5c\x20\x00\x9f\xc0\x27\x9c\x2c\x1b\xcb\x3c\xed\xf9\x90\xbd\x0e\x20\xc6\xf9\xfb\x75\x15\xad\x6e\x93\x3b\x07\xe9\x9d\xa6\xac\x32\xb9\x71\x41\x18\x7e\xf6\x3b\xdb\x10\x62\xe3\x72\x20\xa4\xdc\xd4\x19\xd6\x24\x4c\xdc\xc3\x4e\xa4\x1d\x0b\xcb\xc3\x13\x8b\x1d\x54\xae\xfc\x01\x90\xe3\x0b\x18\x7d\xb0\x73\xaa\x7d\x6c\xfe\x04\xbd\x3f\xd2\xac\x00\x31\x3e\x3d\xdd\x64\xa1\x81\x93\x5c\xa4\xb8\xb2\xa8\x5d\x36\xbc\x27\xd9\x7b\x76\x26\x76\x7b\x93\xee\x38\xde\xf8\xb6\xb2\xc8\xda\x9b\x00\x26\x36\x14\x34\x2f\xaa\x9d\x3e\x73\x8d\x27\x13\xc4\x5f\xfb\xee\xf8\xc8\x4b\xcd\xbc\x8d\xa4\x30\x9c\x84\x45\x53\x0f\x5c\x61\x7d\xc8\x66\x25\x1f\x54\x89\x50\xa1\x4f\x07\x5a\xa3\x11\x7f\x96\xe4\x1f\x89\x9d\xbe\x73\x40\xb1\xd9\x0a\x13\x52\xd3\xb8\xfb\x41\xb7\x9f\x16\xa8\x2b\xc2\xe4\xa1\x93\xb8\xa7\x23\x24\x00\x99\x6b\x73\xb1\xfc\x00\xb2\xec\x1c\x66\x75\x77\xf8\x28\x24\xd3\x9f\xb7\xf6\xe7\x69\x2d\xcd\x97\xb1\xd8\xce\x94\x08\x3c\xa1\x97\xe9\xa5\xd4\x0f\xad\xff\x0b\x9a\xc5\x7e\x9d\xe7\x61\xc1\x56\xe6\xd3\x1d\x52\xc3\x32\xd5\x13\xe9\xf5\x86\x97\xdc\xbd\xd8\x0a\x5e\x42\xc5\x51\x70\x2c\x3d\xe7\xbe\xcc\xc3\xdb\x84\x5b\x1a\x04\xc8\xcb\xd4\x16\x95\xea\x74\x28\xab\xba\x89\xe0\xdc\xe3\xe3\xd9\xe7\x02\x30\xae\x91\x47\xc2\xb8\x85\x59\xdc\x69\x5d\x68\x09\xa5\x1c\xcb\xc1\xdd\x9e\x08\x9c\x58\x5f"}, +{{0x37,0xc0,0x70,0xd4,0xa5,0x3b,0x13,0xbe,0x76,0x06,0x35,0x11,0x0d,0x1b,0xd4,0xf0,0x19,0x20,0x22,0x5a,0xfa,0xbe,0xc5,0x76,0xfa,0xae,0xc9,0x10,0xf2,0x92,0x6d,0x1a,},{0x0a,0xa8,0x5f,0x2a,0xb1,0xdf,0xf8,0x95,0xd1,0xfa,0xd0,0xc1,0x19,0xf2,0xbf,0x57,0x12,0x6a,0xab,0x60,0x1c,0x52,0x8d,0x37,0x69,0x8e,0x97,0x70,0x2d,0x35,0xf5,0x25,},{0x9d,0xa6,0x0c,0xc4,0xa6,0x4d,0x07,0xde,0xe1,0x34,0x6b,0xd3,0xd3,0x01,0x09,0x95,0xce,0x27,0x38,0x20,0x8a,0xb3,0x5b,0x34,0xc2,0xa8,0xfd,0x17,0x87,0xae,0x3a,0x1e,0x20,0x7f,0xe7,0x84,0x52,0x51,0x54,0xfa,0xe4,0xf5,0x79,0x4c,0xd8,0x50,0x30,0x45,0xfe,0xa8,0x5c,0xf7,0x7f,0xd9,0x2f,0x6a,0x70,0xcd,0x0c,0x5a,0x52,0xc0,0x81,0x0e,},"\x10\xc6\x46\x44\x7f\x81\xad\x94\xd0\x15\xd8\x6d\x0d\x98\xb2\x45\x2d\xca\x60\xa4\x7a\xb3\x52\x64\x03\x5e\x33\xa0\x94\x2b\x95\x4e\x3e\x23\xb9\x1d\x81\x23\xb8\x59\x3c\x6a\xf7\xc8\xd3\xec\xd2\x90\xe0\xe5\xee\x36\xfd\x4e\x53\xb7\xbe\x63\x3a\x6c\xf0\x27\xa5\xac\x3f\x0f\x67\x9e\xb1\xbd\xd2\x10\xa3\x8e\xa6\xe4\x8b\x05\x58\xe3\x03\x01\x0a\xf4\x74\xe7\xf6\xdf\x2a\x4e\x45\x76\x99\xfc\x38\xe3\x69\x38\xb0\x5f\xfc\xaa\x1b\x69\x4e\x32\xf3\xd1\xb2\xcc\x5d\x00\xcf\x25\x6f\x12\x18\x4c\x87\x3e\x51\x90\x89\xec\x1d\xf1\x5b\x0d\xc7\x6e\x7b\xfe\x90\x78\x0d\xf5\x81\x36\xfe\x59\x7f\xce\x89\x4c\xa5\x63\xe0\x8e\xfa\x0f\x2d\x4d\x20\x8b\xed\xe9\xa8\x74\x88\x28\x73\xd2\x51\xba\xf0\x19\xfe\x46\xd1\xd6\x50\x4b\x3b\xcd\x24\x3b\x79\x53\x51\xf3\x4d\x2e\x76\x06\xaa\x97\x55\x28\xee\x50\xd5\x9e\xfb\x6e\xe6\x99\x2a\x89\xb2\x42\x69\x56\xc2\xca\x42\x47\xe0\xdf\x01\x29\x85\x29\x83\xe9\x76\x7a\x8e\xed\x1b\xc7\x33\x5f\xfc\xa8\xd0\x28\x9f\x04\x80\x7f\x67\xca\x7d\xa9\x71\xf5\x8d\xb8\xb9\xbc\x9f\xdb\xe4\xf8\x3c\xfe\x9a\x00\xf1\xca\x58\x47\x98\xbc\x71\xd8\x51\xff\x7c\xd6\xc5\x1b\x89\x90\xaa\xba\x4d\x38\xb4\x16\xb9\x22\x40\xdf\xb7\x0e\xe3\xc1\x2b\x5e\x73\x10\x57\x76\x2e\xf9\x08\x23\xfb\xf6\x83\xca\x06\xd0\x5c\x20\xd3\xae\x2b\x97\xa8\x3e\xbe\x70\xae\x17\xaf\xff\x9d\x16\x60\x9d\x54\x6d\x8d\x3c\x74\xbc\x28\x18\x84\x89\x4f\x3d\x49\xe0\x83\xf1\x0a\xe7\xc1\x1c\x1d\xca\x0e\xff\xef\xcf\xa6\xe0\xf1\x53\x50\x81\xfa\xc3\xa2\x81\x9f\xd2\xe3\x26\x55\x27\x18\x2a\xe9\xd3\x91\xb2\x32\xbb\x75\x42\xe6\x84\x55\xcd\x26\x77\x60\xdb\x65\x2d\x19\xe2\x2f\xb2\xed\x11\xcd\x13\x05\xba\x8d\x98\xc1\xeb\xf2\xd1\x96\x9b\x24\xd6\x4f\x3e\x31\x9a\xf7\x4e\x09\x20\x06\xd2\xa3\xff\x74\x48\x72\xa2\x0e\xbf\x18\xd1\x77\x48\xab\x71\x10\x80\x50\x96\xea\x13\x6b\xce\x2f\x96\x8b\x20\x5e\x65\x0b\x80\x3c\x53\x1d\x06\x77\x5a\xe5\xce\xea\x28\xbb\x92\xe9\xa0\xed\xec\x89\x51\xce\x20\x09\xa8\x8e\xe1\xb6\x4d\x9b\x9e\x89\xf6\x90\x51\x20\x33\x84\x21\x0a\x10\x2a\x44\xd2\xd6\x70\x31\x73\xb6\x85\x07\xdc\xea\xdd\x3b\xf6\x51\x0d\xf2\xa5\xce\xfd\x9c\x80\xe4\xf3\x85\xb2\xf9\xe6\x21\x58\x13\xed\x32"}, +{{0x11,0x26,0x49,0x6a,0x58,0x2c,0xe5,0x8d,0x3d,0x61,0x8d,0xd8,0xa3,0x93,0x35,0x47,0xaa,0x7a,0x8a,0x30,0xfb,0x54,0x06,0x3b,0x8d,0xfd,0xd3,0x16,0x71,0xc6,0xc7,0x3d,},{0xe1,0x02,0x29,0xc6,0x23,0xfa,0x8a,0xd8,0x98,0x2c,0x3e,0x4c,0x36,0xff,0x52,0xdf,0x0f,0x21,0x9b,0x57,0x91,0x5b,0x6e,0x98,0x0e,0x5f,0xe7,0x2e,0xa0,0x96,0x2e,0x22,},{0xb3,0x0e,0xb5,0x6c,0xa9,0xb1,0x20,0xbf,0x84,0x9a,0x3a,0x9d,0x56,0xaf,0x03,0x3d,0xe8,0xa5,0x90,0xc9,0xe1,0x24,0x0c,0x1e,0x36,0xdb,0xc6,0xcf,0x0a,0x71,0xb7,0x8a,0x11,0xec,0x14,0x3f,0xb9,0x95,0x9a,0x8f,0x25,0xb5,0x77,0x11,0xd6,0xa9,0x0a,0x67,0xe0,0x1b,0xe3,0xa4,0xda,0x2b,0x69,0x39,0x48,0x69,0xbb,0x8d,0x64,0xb8,0x7e,0x0f,},"\x6a\x4b\x52\xd7\x30\xdd\xab\x82\x9b\x2a\x17\x95\x90\xcb\xd4\xc3\x72\x49\x8e\x9f\x43\x99\x77\xc0\xa1\x0d\xc1\x3c\x0a\xe1\x73\x6e\xaa\xff\x06\x33\x71\x43\x4f\xd0\xda\x80\x36\x0e\xc5\x89\x06\x07\xd2\xfa\xe1\xc9\xa2\xe1\xab\x0b\x7f\x3d\x66\x7f\x5b\x1b\x9c\x41\x8f\x18\xb1\x0c\x9e\x6f\xd6\x69\xd3\xeb\xec\x16\x8e\xfe\xf4\x41\x63\xe5\x77\xa2\xeb\xd0\xf2\xcb\x76\x8f\x80\xc2\x31\x88\xe8\x60\x69\xe4\xd1\x0f\x41\x03\x06\xce\xdd\x7a\x34\x1a\x61\xe0\xf4\xf3\xbc\x25\x04\x1b\xc2\xf9\x22\xed\x07\x3e\x1e\x2f\x1b\x70\x9c\x57\x9d\x10\x63\x0f\x33\x07\x17\x54\xd7\x07\x89\x4a\x1c\x62\x19\x0d\xe1\x88\x82\xc5\x64\xdc\x4c\x01\xdc\x54\x5d\xd8\x96\x64\x04\xed\x78\xfa\x32\x67\xa9\x46\x9f\x63\xb6\x12\x0a\xbb\x65\xf9\xb3\xba\x3e\xee\x28\xd7\x9c\x2e\xb4\xe7\x02\x0c\xc6\x98\x7d\xfc\x5c\x29\x67\x2f\x8c\x0f\xa3\xe6\x90\xd5\x84\xfe\x00\x0c\x64\xf3\x52\x61\x01\x79\x62\x1b\xfd\x5f\xf3\xeb\x30\xd1\x8f\x1a\x02\x50\x41\x6d\xb9\x3b\x1c\x1e\x93\xcf\x8a\x36\x46\x51\x75\x60\xd1\xcc\x8f\xff\x82\x2b\x51\xef\x27\xb2\x00\xe9\x87\xb5\x92\x39\x07\x53\x45\x3e\xf1\x38\xbd\x3d\x29\xdb\x7c\xb1\xb5\xf4\x5e\x47\x95\xb8\x9c\x53\xf4\x97\x04\x19\x27\x52\x23\x7c\x6a\xb2\x74\x84\x9f\x95\x94\xee\x97\x77\xf6\xef\xe7\x04\x83\x12\x9d\x06\x7f\x97\x19\x9d\x9a\xe3\x60\x90\x70\x38\x64\xf7\xca\x47\x50\xa6\xf3\xb6\xff\x83\x82\x4c\x91\x04\x84\x39\x4d\x1e\x2e\xce\xba\x18\x44\x6f\xe4\xe9\x94\xce\x07\x43\x3a\x74\x0d\xdd\x05\xf0\xe3\x96\xd4\x82\x89\x4e\x6f\x14\xac\xf7\xb9\x7b\xae\x6c\x7e\xb8\x87\x03\x03\x9f\xa7\x85\xd6\x0a\x3a\xf7\x8b\x13\x24\x3a\x4f\x88\xdd\xe1\xd9\x98\x61\x7f\x2e\x3f\xa7\xea\xfc\x2f\x43\x5d\xd4\xac\x1e\xa9\xc2\x38\x40\x7a\xa0\x9b\x4e\xea\x8e\xd4\x34\x92\x7b\x40\x66\x74\xac\x27\x04\x58\xcf\xb3\xbf\x29\xc3\x47\xf9\x45\x59\x61\x31\x79\xb9\x50\x21\x92\x32\x1b\x88\xe9\xaf\x0a\x90\xe9\xa4\xab\x9e\xdd\xaa\xe3\x82\xe3\x73\x4d\x14\x15\xeb\xe3\x24\x99\xc3\x4e\x6f\xde\xaf\x15\xb0\xd9\x78\x79\x85\xe0\x8d\xfe\x49\x54\x60\xc5\x4f\x67\x43\xd8\x1f\xf1\x68\x81\xe5\xe3\x0c\x51\xf4\xb0\x92\x37\x37\x83\xf1\x24\x23\xc3\xe1\xae\x85\x91\x13\x0a\x26\x99\x80\xca\xa1\xcb\x5c"}, +{{0x9c,0x16,0x7a,0xff,0x3b,0x1b,0x78,0x8f,0x13,0x3d,0x42,0x2d,0xe8,0xca,0x9a,0x64,0x31,0x64,0x09,0xf9,0xe3,0x5b,0xfe,0x22,0x03,0x2e,0xc4,0x17,0xae,0x9a,0xbc,0x6d,},{0xef,0xb5,0x34,0xf0,0xd4,0x7c,0x06,0x8e,0x77,0xb2,0x8a,0x90,0x6d,0x95,0xad,0x8d,0x21,0x3a,0x4d,0x4f,0xc1,0xc7,0x05,0x42,0xf0,0x1e,0x59,0x6d,0x57,0xb5,0xf0,0x19,},{0xc9,0xae,0x67,0xfd,0x64,0x15,0xdc,0xba,0xb2,0x92,0xfa,0xb3,0x94,0xca,0x6c,0x3b,0x7d,0x90,0xca,0x24,0x4d,0xc6,0xa7,0x76,0x4e,0x74,0xfd,0x20,0x2b,0xf4,0xb2,0x90,0x5b,0xd2,0x03,0x0e,0x6b,0xeb,0x91,0x4c,0x3c,0x23,0x8d,0xb3,0x71,0xb1,0xcb,0xa6,0xd9,0x26,0x1a,0xa3,0x92,0xec,0x87,0x1a,0x4b,0x8b,0x12,0xfe,0x9c,0x1c,0x97,0x0e,},"\x68\xac\x0f\xc2\xb6\x07\xba\x38\xe3\x77\xfa\xe8\x45\xc8\x08\xc8\xf9\xfa\x61\x4e\xb1\xf3\x11\x58\xa9\x62\x0a\x93\x7d\x3e\x30\x1e\x85\xac\xaa\x69\x14\x4b\xc3\x49\xa3\x9d\xfb\x58\x20\x41\xc4\xa1\x97\xae\x99\xb4\xd4\xd5\x9b\x7a\x2c\xa3\xd1\x62\x28\xb5\x59\x1c\xbf\x57\xc1\x8a\x78\x1e\xfd\x19\x19\x3c\x47\xb1\x6c\x60\x23\xa3\xa8\xba\x3d\x66\x8f\x05\xa3\x7f\x1e\x83\xb0\xd7\xfe\xbd\xd1\x0f\x63\xe4\x8e\xf7\xa2\x0e\x01\x5b\x1c\x67\x25\xd4\xc3\x00\xa9\x86\xc6\x0e\x3a\x11\x54\x69\xc8\xe5\x2b\xa0\x5b\x51\xc0\x5d\x0a\xf4\x0d\x89\xfd\x9e\xd7\x6f\x36\x95\x0a\xee\x3c\x78\x19\x89\x8a\x90\x3c\xfe\x03\x61\xa9\x1c\x69\x10\x0b\x49\x51\x41\xe8\x6e\xe7\x9d\x63\xd1\x74\x03\xfb\x1a\x16\x29\xef\x63\xcb\x7e\x9d\x27\x20\xcb\xff\xf0\x00\x2b\x19\x0b\xcd\xc2\x67\x94\x12\x4d\xd3\x8d\x42\xbc\xaa\x71\x75\x40\x5e\xb0\xbb\xcf\x8e\x37\xd6\x5d\x05\xa3\x71\x95\xb4\x79\x37\x1f\xa2\xbb\xbb\x16\x7d\x91\xce\xe8\x82\x35\xdd\x72\xea\x88\xfc\x73\xce\x3c\xe4\x3d\x33\xb7\x15\xf2\x5f\x19\x2e\xc2\x15\xda\xc1\x24\x89\x9c\x5e\x75\x86\xe8\x63\x40\xd8\xcb\xe5\x37\x35\xde\xfb\xe0\x2e\x4c\xc9\xfd\xe6\x9f\xb9\x79\x4d\x1d\xb7\x2b\x98\xc0\xf1\x97\x66\xee\x51\x38\xbb\xfa\x78\x90\x9a\xa2\x99\xb4\x91\x3c\x49\x9d\xea\xf5\x4b\x48\x41\xd5\x04\x48\x29\x98\x49\x36\x70\x0d\xcf\x92\xf3\x65\x42\xb2\xfc\x7e\x86\x44\x1b\x99\x25\xf5\xd0\xb7\x8c\x17\xa8\x5c\xfc\xfc\xb2\x0b\x0f\xd7\x51\x34\x9c\x27\x46\x3a\xbd\xe4\xd2\x7d\xf7\x42\x65\x28\x87\x13\xf9\x6d\xea\x01\x3b\x94\x55\x21\x80\x8b\x49\x96\xb1\xb2\xdc\x03\x38\xb6\xd2\x36\xef\xd6\xd2\xb2\x7d\xaf\xda\x46\xec\x5f\xa3\x2b\x96\x5e\x8b\xb5\xe8\xbb\x61\xbd\x96\x6e\xde\xb7\x74\x68\x1e\x0e\xa8\xc1\x7b\x8c\x99\xfa\x7d\x66\x0f\x0f\x66\xc9\xbc\x6d\x95\xcb\xd7\xdc\x09\x47\x24\x09\x8e\xb0\x51\x91\xb5\x3a\x3d\xf6\x56\x6b\x9c\x90\xe0\xd7\xdf\xf2\x94\x38\x48\xb6\x1a\x20\xd4\x8c\x22\xb6\xd3\xc9\x58\xe2\x93\xd7\x09\xc8\xf4\x81\x10\x23\x0f\xf5\x19\x18\x56\x28\x77\xda\xf6\xd9\x20\xc8\x5a\x82\xe0\x7c\x45\x1f\xe7\xae\x97\x59\xc0\xa7\x7e\x97\xbb\x29\x8b\x5d\x05\x92\xa4\x1d\x08\xf6\x7a\x4e\xd5\xa1\xbb\x41\xe9\x37\xb6\xa6\x8a\xeb\x38\xfd\x5b\xe9"}, +{{0xe9,0x94,0x88,0x05,0xeb,0x34,0x1b,0x28,0x67,0x47,0x9c,0x66,0x8f,0xd3,0x53,0x2c,0x30,0x99,0x41,0xc0,0xad,0x4c,0xb2,0xe5,0x42,0x31,0x75,0x6e,0x6a,0x1b,0xde,0xcb,},{0x54,0x47,0xa8,0xe3,0x4d,0x6a,0x64,0x00,0x02,0xd8,0xd6,0x0b,0xcf,0x1d,0xdc,0x71,0x1e,0x4c,0x46,0x5c,0x94,0xc3,0x4b,0x50,0xbd,0xef,0x35,0x89,0x60,0xff,0x81,0xf1,},{0xd3,0xdc,0x62,0xd6,0xce,0x9c,0x76,0x6f,0x2a,0xba,0xf9,0xa7,0xfb,0xe0,0x9d,0x6b,0xdb,0x07,0xa4,0x74,0x7b,0x56,0x08,0x0d,0xb0,0x9b,0xeb,0x4a,0x4e,0x80,0x4a,0x70,0xd7,0xdd,0xf4,0x11,0x94,0x75,0xc7,0xbe,0x83,0x4f,0x31,0x95,0x6f,0x4a,0x71,0xda,0xd0,0x29,0xcd,0xf2,0x36,0x3d,0xd0,0x36,0x5c,0xe2,0x2d,0xc2,0x7f,0x07,0x80,0x03,},"\x91\xcf\xfd\x7e\xb1\xcf\x6b\xd4\x75\x6b\xce\x6a\x30\xaf\x9d\xfb\xa2\x6d\xdd\x1c\xce\x03\x94\xc1\x94\xa3\xe3\x9c\xc3\xd1\xcb\xc2\x21\xb7\xeb\x70\xbe\xa1\x8d\x29\xc2\x67\x45\x71\x76\xa3\xc9\xe5\x3c\x18\xe4\x7d\x10\xa6\x7c\x46\x45\x05\x19\x77\x02\xe6\xb2\x47\x0d\x38\x86\x9d\xb5\x17\x4b\x15\x8f\x99\x92\xe4\x43\x5d\x02\x24\x6f\x54\x02\x58\xde\xdd\x3c\xe3\x3d\xf5\x82\x55\x5a\x68\x1f\xb7\x6e\xca\xcc\xb1\xc2\x98\x9b\x17\x7e\x3b\x7e\x45\x4a\xaa\x52\x9d\xe5\x9b\xf5\xa0\x31\x23\xd5\x71\xdf\x2e\x7f\x7c\xb8\x30\x80\x5c\x58\xb7\x4a\x65\x3b\xac\x0e\x5a\x88\x8e\x08\xdc\x22\x36\xd6\xcd\x49\x6a\xa0\x6d\x0d\x67\xcf\x3b\x33\x5e\x21\x8c\x49\xde\xda\xd8\x2f\xc1\xbe\x9e\xf2\x0c\xac\x61\x90\x5c\x30\xeb\x13\x2d\x73\x9b\x16\xca\x8a\x8c\x90\x66\x19\xc0\xe0\xd8\xb3\x39\x85\x32\x7e\x36\xf3\xd4\xb8\xfd\xa3\x87\xc1\x86\xcc\x50\x44\x31\x04\xdb\x76\x1f\x7f\xf9\x30\x12\x70\x20\x4a\x71\x3e\x58\x90\x21\x01\xfa\xd0\x00\xce\x93\x16\x47\xc5\x77\xfd\xec\x14\x8d\xca\x95\xcd\xc0\x89\x18\xeb\xed\x03\x7c\x60\x33\x2f\xad\xf0\x88\xf0\x36\x08\x3e\xbc\x92\xe1\x73\xb7\xdd\xcc\x30\xc4\x93\xf2\x7e\x69\xcd\x17\xa2\x0d\x30\xb7\x8f\x83\xa7\x2e\x4f\x5a\x74\x7d\x86\xd9\x6c\x5e\x1b\xb7\xa4\x38\x16\x62\x04\x01\x3e\x21\x64\xd6\xaa\xbc\x0d\x56\x2f\x54\x01\x5c\x36\x5c\x80\x44\x56\x07\x14\x5e\x56\x92\xee\x34\xf6\x35\x30\x77\xfa\xb7\x45\x2d\x88\xce\x3e\xb0\x1d\x2b\x37\x97\xdc\x91\xb3\x41\xa3\xa7\x26\x30\x15\x16\xba\xae\x18\xe8\x51\xf7\x4d\xfb\xdf\x08\x66\xbb\x23\x76\x86\x7d\xe5\x52\x31\xe3\x62\xc4\x72\xc5\x21\x16\x54\x4c\xd4\xf8\x1e\x93\x57\x1c\x4e\xc8\x20\xe7\xe6\x53\xf4\xe2\x1b\xe0\xa9\x42\x57\x6c\x9d\xe9\x1e\x7d\x12\x51\x68\x3d\x85\x9d\xe4\x48\xf8\x22\xdc\xf3\xd2\xcf\x55\xed\xe2\xf9\xc7\x1b\x60\x63\xd1\x37\x30\x61\xf8\xf5\x93\x6b\x69\x8d\x13\x84\xe6\x54\x59\xea\x2b\xc2\x6e\xc9\x67\x75\xef\x42\x52\x07\x43\x2d\xda\x0a\xc1\xfe\x28\x52\x6c\x5e\x45\x59\x34\x9c\x3d\x8d\xf9\x91\x82\x30\xf4\x04\x46\x83\xcc\x2c\x1b\x85\x8d\x14\x1a\xb8\xd0\x80\x5b\xb9\x33\x60\x67\x52\x2a\xa8\x9c\x81\x0f\x3e\xaa\x7a\xc2\xd8\xdd\x28\xc3\x75\x12\x25\xa1\x9e\xce\xc8\xbc\xca\x52\x43\x99\x46"}, +{{0xb0,0x17,0x53,0xef,0xa7,0x3b,0xb3,0xde,0x7a,0xa7,0x78,0xbe,0x7a,0xfc,0xbf,0xf6,0x6a,0x5d,0x3e,0x2c,0x2f,0x8b,0x5a,0xa2,0xb0,0x48,0x84,0x40,0x50,0x99,0x69,0x65,},{0xd0,0xcc,0x6c,0xf1,0x09,0xc9,0x99,0xfb,0xf6,0xd1,0x6f,0x47,0x1f,0xaf,0xd0,0x23,0x2b,0x0a,0x68,0xd4,0xc4,0x64,0x06,0xec,0x75,0x45,0xdb,0xab,0xa8,0x19,0x41,0x58,},{0x16,0xb7,0x42,0x12,0x27,0xae,0x09,0x13,0x06,0x85,0xcb,0xb1,0xa0,0xc6,0x0a,0xa5,0x7a,0x5e,0x1a,0xfe,0x1b,0xbe,0x6b,0xac,0xea,0x0c,0x28,0x1b,0xcc,0x89,0x98,0xe6,0x82,0x4a,0x77,0x2c,0x32,0x08,0xa6,0xb6,0xb4,0xd2,0x36,0x69,0x55,0x05,0xc9,0xbe,0x82,0x70,0x0c,0xf9,0x3a,0x78,0x39,0x85,0xa3,0x9e,0x16,0xe3,0x77,0xa7,0x41,0x0e,},"\x68\x4e\x61\x2f\x27\xee\xad\x0d\x34\x84\x4c\xc8\x1b\xa9\x11\xc2\x8a\xaf\x6d\x66\xe7\x12\x29\xe8\xcc\x34\x62\xf7\xc7\xa0\x50\xda\xa3\x0c\xb7\x44\x71\x15\x0f\x07\xda\xd4\x59\xb5\xa9\x13\x58\x47\x6c\x05\x98\x25\x5d\x8a\x64\x2d\xd7\xc0\x80\x28\x11\xbd\x88\xe4\xca\xc5\x97\xef\xe4\x1e\xbd\x96\xcd\x0f\x3b\x5c\xe7\x2d\xb4\xbe\x1a\x3d\xbd\x6b\x84\xf5\x44\x6e\x3d\xa6\x00\xd3\xb1\xd2\xb4\x60\xa0\x09\xbd\x31\xca\xcd\x98\xa9\x15\x18\xce\x33\xe9\xa7\x03\xd4\x04\x28\x87\x36\xcc\xc4\x31\x03\xfc\x69\xe6\x79\x74\xf3\x16\x52\xfa\x3d\xad\xef\x33\x37\xf6\xc8\x97\xa3\xd2\x01\x30\x3c\x8f\x03\x59\x7b\x4a\x87\xc9\x8f\x29\x1c\xcd\x58\xa3\xf1\xe8\x98\x33\x2a\xa5\x99\x3b\x47\xfc\xb5\xdd\xaa\x1c\x08\x68\xb6\x43\x74\x2d\x0e\x4a\x4b\x9c\xd4\x27\x03\x8b\x3b\x74\x99\x9b\xc8\x9a\xc3\x48\x4c\x0c\xa1\x3f\x25\xaa\xe8\xe7\x8a\xe1\xcc\xee\x62\x18\xac\xca\xb8\x1a\x4f\x69\x4f\x53\x24\xa3\x47\x62\x9d\x49\xb5\x5e\x40\x37\x50\x4a\x9a\xcc\x8d\xf5\x8c\x68\x41\xdd\xdc\xd4\xfc\x43\x47\xf7\xb6\xf1\xfd\x9d\xe0\x56\x45\x77\xe6\xf3\x29\xed\x95\x1a\x0a\x6b\x91\x24\xff\x63\xe2\x2e\xb3\x6d\x3a\x88\x63\xbc\x1b\xf6\x9c\xea\x24\xc6\x05\x96\x7e\x7d\x89\x48\x95\x3f\x27\xd5\xc4\xc7\x5f\x08\x49\xf8\x72\xa3\xe3\xd1\x6d\x42\x2f\xa5\xa1\x1e\x1b\x9a\x74\xdf\x6f\x38\xb9\x0f\x27\x7d\x81\xfc\xe8\x43\x7a\x14\xd9\x9d\x2b\xef\x18\x9d\x7c\xac\x83\xdd\xc6\x13\x77\xed\x34\x8b\x3c\x4f\xc0\x9e\xc2\xb9\x00\x59\x25\xd0\x4a\x71\xe2\x6d\x64\x16\x67\xbd\xf5\x49\x29\x43\x31\xc6\xea\x01\xcd\x5c\x0b\xd1\xb6\xa7\xec\xfd\xa2\x0b\x0f\x19\x29\x58\x2b\x74\x69\x7c\xb2\x62\xc3\x92\x7d\x6b\x22\x3f\x4b\x5f\x30\x43\xaa\x6e\xb4\x57\x1a\x78\xe9\xda\x11\xc2\xb3\x6f\x64\x55\x25\x80\xca\xa7\xb5\xfa\x6b\x90\xf9\x29\xe0\x16\x2e\x60\x8d\x12\x40\xd7\x24\x2c\xd2\xf4\x70\x25\xc0\x3d\xeb\xe0\x59\xb1\xdc\x94\x77\x02\x32\xbc\x67\x65\x14\x84\x80\xbb\x1d\x9f\x50\xda\x1e\xe6\x44\x8c\xf9\xc8\x8b\x19\xdd\x45\x99\x32\xc0\x6e\xd8\x11\xc4\xa6\x4a\x12\xd5\x93\x8b\xd1\xc7\x57\xbc\xfa\xea\xee\x89\x33\xfe\x5f\xff\x21\x76\x3d\xe7\x40\x48\x2b\xcf\x1b\xa5\x9a\xfd\xc8\xfc\xf8\x73\xc3\xd5\x07\xbb\x39\x4e\x32\xe4\x5f\x73\x65\x19"}, +{{0x4f,0x4b,0x20,0xd8,0x99,0x36,0x6f,0x2f,0x23,0xee,0x62,0x8f,0x22,0x9b,0x23,0x6c,0xf8,0x0f,0x43,0xba,0x18,0x31,0x77,0xc9,0x7e,0xe3,0x48,0x29,0x54,0x6f,0x17,0x42,},{0xc9,0x45,0x76,0x64,0x1f,0x4a,0x89,0x3c,0xdf,0xce,0xe7,0xb3,0x9f,0xc2,0x19,0x29,0xb8,0x6b,0x34,0x99,0x76,0xd7,0xb0,0xa4,0x6d,0x39,0xa5,0x88,0xbc,0xfe,0x43,0x57,},{0x0f,0x80,0xff,0x5d,0x17,0x48,0x8f,0xe2,0x6f,0x93,0xc5,0x43,0xb0,0x4e,0xd9,0x59,0xb5,0xf0,0x64,0x3f,0xc6,0x1c,0x7f,0x2c,0x3b,0xc6,0x01,0x32,0xba,0x9c,0x62,0x10,0xc8,0xb2,0x50,0xea,0x5e,0x84,0xd0,0x7b,0x01,0xde,0x68,0xbc,0x17,0x44,0x14,0xee,0xeb,0x31,0xfd,0xc2,0xba,0x68,0x23,0xe2,0x31,0xe3,0x12,0xa9,0x1e,0xde,0xdd,0x02,},"\xdb\x8e\xf0\x2e\x30\x33\xe6\xb9\x6a\x56\xca\xb0\x50\x82\xfb\x46\x95\xf4\xa1\xc9\x16\x25\x0d\xd7\x51\x73\xf4\x30\xa1\x0c\x94\x68\x81\x77\x09\xd3\x76\x23\x34\x6a\xe8\x24\x5b\x42\xbd\xa0\xda\x6b\x60\x46\x2c\xcf\xdf\xc7\x5a\x9a\xb9\x94\xe6\x6c\x9a\xb9\xfe\xcd\xd8\x59\x96\x10\x91\x0a\xff\xe4\xf1\x02\x15\xcb\x28\x0b\xf8\xf9\xf2\x70\x0a\x44\x47\x96\xda\xe9\x3e\x06\xc6\xbe\xa7\xd8\xb4\xfe\x13\x01\xba\xa7\x9c\xce\xc7\x69\x36\x8f\xeb\x24\x42\xc7\xde\x84\xf0\x95\xe6\xb3\xbf\xf6\x3d\x38\x8c\xba\xfb\x2b\x98\x09\xdc\x38\xe9\xb1\x2e\xbd\x03\x9c\x0a\x57\xf4\xd5\x22\xe9\x1e\xc8\xd1\xf2\xb8\xd2\x3a\x4a\x0a\xe0\x59\xaf\x85\x39\x3b\xb0\xa1\x5f\x74\x91\x10\xf6\x77\x4a\x1f\xd7\x31\xa6\xec\x21\x3e\x4f\xf4\x35\xda\xab\x54\x6d\x31\xed\x9e\xc3\xb6\xd8\xcc\x2e\xda\xce\xbf\x4f\xac\xc5\x56\x65\x56\xee\xa9\x2e\x5b\x3f\x25\x42\x23\x9b\x25\xe2\x80\x12\xdd\x4e\xf4\x00\x72\xee\xbf\x83\xed\x2a\x25\x51\x81\xf3\xa4\x42\x18\x9d\x68\xc6\xc6\x09\xf4\xdf\xdf\x3d\xb7\xd6\x7d\x08\x7a\x2f\xcd\x6d\x2d\xc5\x0b\xbf\xed\x8b\xfb\xbf\xcb\x74\xd3\xc4\x1f\x02\xa8\x78\x65\xb1\x3b\x8e\xfc\xf5\xc3\x58\x12\x57\xbe\x0a\xa9\x13\xf6\x0c\x37\x05\x27\xbd\xe1\x1a\x47\x5c\x13\x6a\x17\xc5\xee\xfe\xb0\x3f\x5b\xff\x28\x69\x3e\xd8\x41\xe8\xed\x1f\x7c\x29\x10\x2f\x55\x99\xdd\x44\x40\x09\xbc\xea\x6a\x92\xd5\x57\x41\x52\x45\x8e\x0c\xaf\x8a\x36\xaa\x72\xb5\xdc\x49\x08\xa6\x46\x1c\x9b\x74\x14\x53\x00\x5c\x8f\xbc\xc6\x81\x13\xae\x18\x42\x08\xee\x14\xb8\x35\x48\x0c\x6e\xfa\xfe\xd1\x8a\x76\x00\x0b\x38\xe5\x85\x82\x90\xf4\xd5\x1f\x52\xf0\x96\xcb\xe4\x90\xe1\xeb\x5c\xac\xb2\x26\xec\x49\x5a\x55\xa7\xfa\x45\x78\x43\xd5\x7f\xab\x67\xf8\xbe\x7e\x20\x93\x34\x78\x5b\xdd\x66\x5d\x7b\x63\xe4\xda\xf5\x7b\x6e\x78\x92\x8b\x60\x3c\x8c\x0f\x9b\xc8\x54\x64\x73\x3b\x61\x27\x3e\xf9\xe2\xb8\xa0\xcd\x7c\x3b\xf8\xee\x0a\x68\x72\xe3\x4d\x5a\x27\xa6\x25\xe3\x5e\xaf\x7f\xf5\x44\x0b\x8b\x14\x1a\xf7\x04\xdf\x70\xc9\xc1\x86\x23\xbd\x11\x20\x95\x13\x19\x25\x05\x10\x5c\xd7\xbc\xfa\x5f\x0d\x91\x9d\xa7\x06\x94\x8f\xbe\x1f\x76\x1f\x31\x58\x46\xaa\x3b\x48\x13\xdd\x9b\xa3\xd8\x1b\x92\x04\xe5\x40\x9c\x03\x82\xb6\xeb"}, +{{0xd2,0xe0,0x1d,0x25,0x78,0xb6,0x25,0xa7,0x06,0x0a,0xab,0xc2,0x57,0x65,0xf1,0x68,0xc6,0x80,0xce,0xf7,0x67,0xaa,0x97,0xca,0x0e,0x5e,0xb3,0xd6,0x67,0x47,0x4b,0x2a,},{0x19,0x1a,0xc2,0x23,0x57,0x54,0x24,0xaa,0x35,0x4b,0x25,0x5b,0x81,0x2d,0xd3,0x02,0x5d,0x70,0xed,0x82,0x9e,0x08,0x26,0xc0,0x16,0x29,0xf9,0xdf,0x35,0x45,0x08,0x2b,},{0x87,0xa0,0x10,0x39,0x4a,0x9f,0x2c,0x90,0x4e,0xff,0xef,0xca,0x9f,0xb4,0xd5,0xce,0x13,0x79,0x33,0x01,0xa4,0x92,0x5b,0xa5,0x1d,0xb1,0x19,0x12,0x3a,0x4d,0x73,0x0a,0xbf,0x76,0x4c,0xe0,0x65,0xe4,0x8d,0x90,0xa7,0x9d,0x90,0x7d,0x72,0x54,0xc4,0x0c,0xc3,0x58,0x98,0x7a,0x46,0x94,0x9e,0x92,0x8b,0xbb,0x3c,0xd0,0x85,0xdf,0xab,0x06,},"\x20\xd5\xdd\x69\x9b\x28\x53\x30\x2a\x68\x17\x09\x4d\x5e\xa5\x12\xbd\xf8\x53\x45\x04\xcb\x28\x9c\x60\x24\x67\x41\x07\x40\xec\x7e\xb8\xea\x64\x42\xc8\x0f\x14\x59\x35\x06\x8f\x91\x22\xfd\xf4\xa3\x9f\x20\x10\xf3\x3d\xb5\x5b\x81\x4d\x97\xbf\x2e\x58\x72\x32\x9f\x11\x26\xd4\xeb\x95\xb8\x06\xca\x19\x73\x11\x31\x65\xb1\x16\xbe\x87\x16\x37\x1f\x81\x33\x17\x79\xdc\x79\xa5\xcb\x39\x42\x08\x1a\xb5\xf2\x07\xf6\xb5\x3d\xb0\xe0\x03\x81\x07\xd6\x3c\xa9\x77\x08\x18\x19\x82\xdc\xb5\xf3\xb9\x30\x10\xec\x6e\xdf\xb2\xcf\xd3\x1c\xab\x00\x09\x0b\x3c\x38\x51\x5f\x97\x81\x76\x96\x86\xcb\x17\xab\x81\xd5\x4a\x8b\x77\x57\x54\xd4\x2f\xba\xd0\x86\xb8\x0b\x28\xd6\x36\xf7\x8b\x7e\xb7\x7e\xd9\xca\x35\xb6\x84\x3a\x51\x0f\x0a\xd0\xac\x1b\x20\x26\x7a\x00\x03\x01\xb3\xc7\x07\xa2\x0f\x02\x14\xd5\x9b\x5b\x81\x99\xc2\xf9\xee\x25\xd3\x20\x60\xac\xe3\xe0\xf2\x59\x46\x50\x41\x6a\x00\x71\x6c\xd3\xf9\x86\x04\xa5\xe1\x04\xb3\x33\x10\xfd\xae\x94\xc3\x14\x01\x3c\xdc\xa5\xba\x24\x14\x40\x9e\xb7\xf1\x90\x13\x94\xf0\x07\xd6\xfa\x0a\x29\xdb\xe8\xec\x3d\xf9\x8c\x39\x3c\x8d\x72\x69\x58\x77\xcc\x9b\xaf\x49\x1e\xf3\x0e\xf7\xdb\x33\x71\x60\x8c\xa9\x7c\xc6\x21\x56\x25\x20\xee\x58\x1d\x5d\x1c\xdb\xc7\x82\x32\xd6\xc7\xe4\x39\x37\xb2\xcc\x85\x49\xe6\xf1\xe0\x8d\xf5\xf2\xea\xc8\x44\xfe\x0f\x82\x2b\x24\x83\xad\x0a\x5d\xe3\x3b\xe6\x40\x89\x49\x0e\x77\xd6\x98\x00\xfa\xe2\x58\x9e\xe5\x87\x12\xac\x15\xa3\xf1\x9e\x6f\xfd\xbc\xa4\x2f\xe1\x89\x4e\x88\x9b\x94\xc0\x4b\x04\x24\x0d\xaf\xb0\xb2\x73\x0c\x23\x6b\x8c\xce\xb2\xcb\x97\xaf\xd1\xd5\x15\xdc\x19\xd1\x06\x7f\xd4\xab\xa8\xce\x29\x7f\xd6\xd1\x10\xb3\x5a\x21\xbd\x3c\x07\x5c\x57\x7d\x93\xfe\x1d\xf7\x7d\x64\x8f\x71\x19\x49\x20\x99\xb0\x17\xaf\x44\xeb\xa0\x9c\x80\x7f\x11\xa4\xc3\xf4\xa1\x1a\x2f\xff\x30\x6a\x72\x8b\xa7\x89\x83\x32\x3c\x92\xa2\xfd\x5f\xcc\x80\xc1\x8d\x42\x34\x26\xf8\x23\xa7\x3f\xe0\x40\x94\x95\x52\x84\x29\x3f\x5f\x6b\x3c\xa4\xff\x10\x80\xdb\xb1\xe4\xc6\xf7\x4c\x1d\x93\x5e\xd2\x1e\x30\x09\x4c\x7d\xe3\x36\xb8\x2d\xd8\x20\x0b\x0d\x65\x95\x83\xc5\xbf\xd5\x47\x0f\x9d\xb3\x42\xe7\x0e\xc4\x00\x07\x42\xc5\x64\x0a\x21\x4e\x3c\x2e"}, +{{0x7c,0xd7,0xec,0x99,0xdd,0x03,0xae,0xde,0x1f,0xf1,0x07,0x3e,0xc2,0xca,0x70,0x10,0x27,0x6e,0x94,0x7e,0x2a,0xa9,0xb0,0xe6,0x5f,0x87,0x7e,0x4c,0xcf,0x1b,0x3a,0x14,},{0xe4,0xc3,0x9d,0xbe,0x94,0x93,0x17,0x6b,0x82,0x13,0xf1,0x42,0x2a,0x9d,0xe7,0xc7,0x4f,0xb6,0xa5,0x91,0x90,0xfc,0xdb,0xf6,0x37,0xc7,0xad,0x5e,0xe1,0x65,0xc0,0x4f,},{0x6f,0x99,0x20,0x27,0x70,0x96,0x45,0x35,0xe4,0x83,0xa0,0xee,0x01,0xa5,0x29,0x44,0x2e,0xb3,0x21,0x30,0x3f,0xa8,0x05,0xd4,0x75,0x60,0x4d,0x7f,0xc7,0x28,0xa9,0x10,0x3f,0xb7,0xb5,0x58,0xb9,0x55,0xf4,0xd0,0x37,0x19,0xee,0xfa,0xa3,0xb7,0xed,0x5b,0x0d,0xa7,0x57,0x10,0xbb,0x98,0x78,0x7f,0x5c,0x22,0x82,0xed,0x66,0xe9,0xf6,0x0c,},"\xa6\x03\x4a\xa3\xc2\x48\x49\x23\xe8\x0e\x90\xe5\xa8\xe1\x74\x83\x50\xb4\xf2\xc3\xc8\x31\x9f\xaf\x1a\x2e\x32\x95\x15\x0a\x68\xe1\xee\xca\x1b\xc8\x49\x54\xcc\x89\xd4\x73\x1a\x7f\x65\x12\xaf\x01\x46\x4f\xdb\xce\x5d\xf6\x8e\xe8\x06\x6a\xd9\xa2\xfd\x21\xc0\x83\x5a\x76\x55\x9c\xa1\xc7\x44\x9a\x93\x3b\xcb\x15\xaf\x90\x22\x3d\x92\x5f\xf6\x1c\xd8\x3e\xb9\x35\x69\x83\x47\xa5\x70\x72\x70\x9a\x86\xb4\xe5\xa7\xa6\x26\xe0\x7a\x3f\x2e\x7e\x34\x1c\x77\x83\xa5\x40\xf8\x4a\xa7\x3e\x91\x7e\x86\x7b\xb8\x0b\xac\xe6\x25\x47\x05\xa9\xd1\xa1\x18\x5d\xe5\x6e\x1a\x4e\x78\xaa\xf5\x39\xe7\x49\xb8\xf7\x65\xbd\x05\x2c\x4c\xd1\x5b\x63\x8b\xf8\xec\xf8\x7d\x98\x14\x60\x6f\xed\x5a\x69\xf4\xda\xe9\xda\x47\xf3\x80\x6d\xd9\x0b\xe6\x4f\xcc\xd3\x36\x5c\xbe\x9e\x01\xc5\x88\xfe\x65\xd6\xb6\x03\x28\x07\x40\x96\x2a\xa8\xdd\xb9\x5a\x3f\x4f\x67\x4c\x03\xbc\x40\x43\x09\x2c\x54\x45\x95\x56\x82\x70\xa2\xc2\xa8\xaa\x06\xe3\xf6\x7c\x31\x99\x8c\x50\xb9\xa5\x8a\xca\xd0\x06\x90\xd3\x84\x81\x14\xcb\x19\x32\x93\xc8\xac\x21\x01\x6f\xd9\x96\xf5\xc6\x42\x14\x06\x4f\x82\x16\x7b\x2c\x92\x0c\xd8\xa8\x39\x75\x58\x52\xac\x77\xc3\xd9\x05\x26\xdd\x3a\xdb\x96\x83\x7c\xf4\xe7\x26\xf3\x4b\xd0\x29\x55\xcb\xac\x5b\x82\xc9\x2c\xf4\xaa\x8b\x54\xbb\x6e\x43\x6d\xae\x9b\xf8\x93\xef\x05\x0c\x6f\x13\x5a\x7e\x62\xfc\xd8\x34\xda\xc1\xd2\xbe\x8b\x8e\x59\xd6\x96\x13\x18\x11\x70\x1c\x43\x18\xbb\x6e\x9b\x5a\x20\xbe\xc6\x56\xfd\x2b\xa1\x92\xe2\x73\x2f\x42\x29\x63\xbe\xd4\xa4\xfd\x1e\xc9\x32\x63\x98\xdc\xe2\x90\xe0\x84\x8c\x70\xea\x23\x6c\x04\xc7\xdb\xb3\xb6\x79\x21\x44\x0c\x98\xd7\x27\x53\xf6\xa3\x32\xea\xad\x59\xfd\x0f\x57\x74\x29\x23\xfb\x62\x5f\xef\x07\x0f\x34\x22\x5e\xa0\x6c\x23\x63\xd1\x23\x66\x6b\x99\xac\x7d\x5e\x55\x0d\xa1\xe4\x04\xe5\x26\xb5\xb2\x29\xcb\x13\x0b\x84\xb1\x90\x3e\x43\x1c\xdb\x15\xb3\x37\x70\xf5\x81\x1d\x49\xfb\xd5\x0d\x60\xa3\x47\x4c\x0c\x35\xfc\x02\x1d\x86\x81\x81\x9e\xc7\x94\xcc\x32\xa6\x34\xbc\x46\xa9\x55\xaa\x02\x46\xb4\xff\x11\x24\x62\x3c\xba\xfb\x3c\xb9\xd3\xb9\x2a\x90\xfd\xe6\x48\xe4\x14\x63\x61\x92\x95\x2a\x92\x29\x1e\x5f\x86\xef\xdd\xb8\x9c\xa0\x78\xae\xa7\x71\x7f\xc7"}, +{{0xe3,0xca,0x37,0x13,0xa2,0xfd,0x41,0x2a,0xd5,0x33,0x6b,0xc3,0x56,0xb7,0x7b,0xe0,0x27,0xd5,0xb7,0x08,0x15,0xb3,0xac,0x2a,0xec,0xd8,0x34,0x0e,0xf5,0xf8,0x89,0xb1,},{0x1d,0x51,0x6c,0xb8,0xbe,0xf1,0x16,0xa0,0xc1,0xb6,0x92,0x90,0x09,0x93,0x3f,0x6e,0xb6,0x2c,0x23,0x05,0x07,0x45,0xfe,0x7e,0x8d,0x3c,0x63,0x16,0x23,0x77,0x81,0x11,},{0xb3,0x85,0x7e,0xa6,0x1b,0xaa,0x9e,0x62,0x83,0x8c,0x4e,0x3a,0x99,0x65,0x02,0xd3,0x36,0x4f,0xe1,0xec,0x59,0x42,0x58,0x35,0x50,0x73,0xdd,0x10,0xe4,0x97,0xc6,0x00,0xbe,0xfb,0x1f,0x8f,0x23,0x3f,0xd6,0xe3,0xb2,0xc8,0x7f,0x10,0xdc,0xb7,0x26,0x1a,0xaf,0x34,0x81,0xbf,0xd0,0x90,0x26,0x05,0xac,0xcc,0x90,0x0f,0xef,0x84,0xd4,0x07,},"\xdd\x99\xba\xf2\x95\xe0\x13\xee\xd1\x07\xba\x8a\xf8\x11\x21\xaa\xf1\x83\x5a\x3c\xca\x24\xf8\xe4\x64\xb4\xcf\xca\xa3\xc7\xbf\xfe\x6f\x95\x36\x01\x6d\x1c\x8c\xf3\x75\x03\x8c\x93\x27\xe8\xe2\x1b\x00\x40\x66\xf5\xea\xc0\xf7\x6a\x3e\x8e\xdf\xb0\x7b\xe8\xbd\x2f\x6b\xc7\x9c\x3b\x45\x6d\xe8\x25\x95\xe2\xc2\x10\x5b\xb1\xb0\xaa\xba\x5e\xee\xe1\xad\xef\x75\x21\x67\xd6\x33\xb3\x22\xeb\xf8\xf7\xcd\x5f\xbf\x59\x50\x8f\xdb\xdb\xec\xf2\x5e\x65\x7a\x9c\x70\x50\xaf\x26\xa8\x0a\x08\x5b\x08\x17\xc6\x21\x7e\x39\xac\xd5\x4c\xb9\xfa\x09\x54\x0f\xc7\xbd\xc5\x22\x6d\x6a\x27\x6d\x49\x2c\xc8\xa3\xdf\xfc\x2a\xbc\x6d\x0b\x9f\xb0\x8c\xbc\xcd\xd9\x43\x2e\x44\x98\x21\xa5\xdc\x98\xcf\xb3\xa4\x18\xe5\x39\xc8\x90\xfe\x5a\x04\x46\xb9\xf8\x1d\x30\x67\x00\x92\x7a\xde\x61\xcf\xdc\xc0\x62\x4f\x13\xb5\x84\x07\x48\x77\x46\x04\x80\x57\x31\xd9\x2e\x77\xd5\xde\xf6\x6b\xe4\x4c\xc8\x17\x94\x6f\x1c\xd7\x58\x19\x6c\xf4\x80\xf9\x9e\x71\x17\x83\x5c\x4c\x87\xcb\xd6\x40\x77\xa5\x62\xa8\x0c\xf1\x1d\x8c\xa6\x5b\xe7\xa9\x4d\x92\xb9\xdd\xae\xa9\x97\xe9\x3f\x14\x48\x57\x7e\xd6\xd8\x43\x6b\x2f\x31\x44\x69\x2c\x1f\xd7\xd2\x8a\x03\xe9\x27\x4b\xc9\xe8\x66\x9d\x85\x75\xf5\xde\x20\xcf\xbd\xbc\xb0\x4e\x9f\x39\xf3\x45\x1d\x70\x48\x37\x5e\x26\x98\xe7\x22\x84\x6c\xb4\xf2\xd1\x9a\x81\x0c\x53\xd4\xc1\xa6\xc3\xb7\x70\xfb\x40\x2d\xf0\x53\x0e\x7b\x29\x07\x22\x3f\xd0\x89\x9e\x00\xcb\x18\x8c\xa8\x0c\x15\x31\xb4\xe3\x7f\xba\x17\x6c\x17\xa2\xb8\xf5\xa3\xdd\xc7\xa9\x18\x8d\x48\xff\xc2\xb2\x72\xc3\xda\x9c\x9b\x89\xdf\xe5\x3f\x2f\xe7\xe3\x67\x2f\x91\xd1\x18\x18\x49\x1a\xce\x14\x0a\xdc\xae\x98\x50\x2e\x11\x4f\x4b\x35\x2b\x90\xe2\xe7\xfb\xd3\x33\xb2\x45\x9e\x7f\x15\xdd\x07\x64\xc9\xc3\x4e\x4c\xb7\xcc\x09\x55\x00\xcd\xa0\x35\xe8\xe2\xe4\xe3\xc8\xfd\x5d\xf5\xf3\xaa\x57\x9a\x73\x5d\xd8\xa9\xf1\x9e\xf3\x36\xfa\x97\x11\x14\xe4\x66\x18\x73\x4a\x4c\x13\xd3\x0c\x81\x12\x8c\xa2\x1d\xef\x47\x33\x01\x03\xd2\x3d\x80\xff\xe6\x74\x21\xa6\xcc\xf9\xf3\x6a\x93\xf0\x56\x03\xc5\x99\xee\x10\xb0\x34\x51\xf3\x6b\x21\x33\xc1\x87\xa7\x9a\xd9\xe6\xfd\xfb\xb1\x25\x95\xab\x73\xbb\x3e\x2e\x2e\x43\x03\x0f\xd3\x7e\x59\x1c\xf5\x5d"}, +{{0x29,0xa6,0x3d,0xcd,0x48,0xa3,0x51,0x77,0x14,0x11,0xfd,0xdc,0xab,0x46,0xbb,0x07,0x1e,0x91,0x49,0x85,0x76,0xe8,0xd0,0x2f,0x8b,0x60,0x44,0xf5,0xbd,0xd3,0xed,0x90,},{0x39,0x23,0xfd,0xcc,0x2a,0x9f,0xe5,0xca,0xbf,0x6e,0x99,0x32,0xe4,0x6d,0xbd,0x2b,0x7f,0x36,0x32,0x50,0x0f,0x9d,0x95,0x55,0x2d,0xb2,0xb0,0x45,0xbc,0x41,0x16,0x6f,},{0x12,0xbf,0x62,0x95,0x93,0xe2,0xca,0xad,0xc9,0x10,0xec,0x40,0xbf,0xe2,0xb7,0xa6,0x25,0x14,0x12,0x6b,0x16,0xba,0x3a,0x43,0x8d,0x88,0xe2,0xd2,0x1f,0x59,0x5a,0xae,0xe8,0xab,0xfa,0x4a,0xf2,0xec,0x87,0x03,0x61,0xd0,0xea,0x04,0xdf,0xc8,0xc6,0xa3,0x30,0xfb,0x28,0x41,0xc2,0xd8,0x21,0x1a,0x64,0xfa,0x1e,0x7e,0x7d,0x27,0x38,0x00,},"\xff\x18\xca\x0c\x20\x4c\x83\x86\xa4\xaa\x74\xec\x45\x73\xc7\xb6\x92\x16\xb3\x14\x70\xda\xed\xd9\x6a\x4f\x23\x02\x11\x6c\x79\x55\xd7\x2d\xac\xc8\x8e\x37\x14\x55\x0c\x09\xe6\xf7\xb9\xa8\x58\x62\x60\xdc\x7e\x63\xda\x4c\x63\x3b\xae\x01\x62\xe1\x16\xe5\xc1\x79\x7b\x78\xd8\x7d\x47\xff\xee\xa3\xd7\x81\x9d\xf9\xc8\x52\xf0\xff\x30\x93\x6a\x10\x5d\x3a\xf5\x53\x1a\x8f\x89\x54\x97\x11\xc1\x4c\x2d\x3e\xe1\x15\x64\xe7\xc8\x52\x5b\xd5\x88\x64\x00\x97\x62\xa0\x55\x41\xd8\xe0\x7a\xd8\x41\xa5\x5a\x6a\x9a\x00\x7e\xf2\x09\xcc\xec\x4b\x56\x40\xba\xbe\x35\x65\x1b\x61\xdf\x42\xde\x4d\x91\x0e\xe7\x3a\x93\x3c\x0b\x74\xe9\x95\x75\x7e\x84\xa9\x9e\xb0\x34\xf4\x18\x07\x18\x3c\x90\xca\x4e\xa8\xd8\x4c\xdb\xa4\x78\x61\x3c\x8e\x58\x7c\xb5\xf8\xfb\x6a\x05\x50\x81\xda\x6e\x90\x22\x0d\x5d\x86\xe3\x4e\x5f\x91\xe4\x88\xbd\x12\xc7\xa1\xa6\xb3\xc9\xfc\xe5\x30\x5e\x85\x34\x66\x58\xef\xfa\x81\x0d\x0e\x8a\x2a\x03\x9d\xb4\xa4\xc9\x49\x65\xbe\x40\x11\xf9\xd5\xe5\xda\x26\x62\x33\xe6\xc4\xe1\x8e\xd4\xf8\xa2\x5a\x57\xe4\x0a\x59\x1c\x7e\xd5\x90\xc0\xf8\xb1\xa1\x19\xc7\xc9\x74\x7f\x69\x1b\x02\x19\x6c\xd1\x8e\x69\x45\x21\x3f\x1d\x4c\x8c\x95\x79\xc6\xe0\xa2\xac\x45\x92\x41\x28\xd6\xd9\x2c\x8e\x4c\x66\x06\x53\x20\x35\x3d\x48\xd1\xd5\xe1\x31\x94\xd9\x05\xf8\x37\x07\x8f\x8d\xac\x0b\x68\xcf\x96\xae\x9e\x70\x55\x4c\x14\xb2\xfa\x29\xb1\x96\x30\xe4\xb0\xf5\xd2\xa7\x67\xe1\x90\xef\xbc\x59\x92\xc7\x09\xdc\xc9\x9a\xa0\xb5\xaa\xf4\xc4\x9d\x55\x13\xe1\x74\xfd\x60\x42\x36\xb0\x5b\x48\xfc\xfb\x55\xc9\xaf\x10\x59\x69\x27\xbc\xfa\xd3\x0b\xac\xc9\x9b\x2e\x02\x61\xf9\x7c\xf2\x97\xc1\x77\xf1\x92\x9d\xa1\xf6\x8d\xb9\xf9\x9a\xc6\x2f\xf2\xde\x3b\xb4\x0b\x18\x6a\xa7\xe8\xc5\xd6\x12\x39\x80\xd7\x59\x92\x7a\x3a\x07\xaa\x20\x8b\xee\xb7\x36\x79\x5a\xe5\xb8\x49\xd5\xda\xe5\xe3\x57\x37\x10\xaa\xa2\x4e\x96\xd5\x79\x1e\x27\x30\xd0\x27\x0f\x5b\x0a\x27\x05\xba\x51\x5d\x14\xaa\x7e\x6f\xa6\x62\x23\x75\x37\x7f\x9a\xba\x64\xd0\x25\x69\xa2\x09\xd3\x3d\xe6\x86\xe0\x89\xec\x60\x11\x8e\x48\x14\xff\xc6\xc0\x77\x8c\x64\x27\xbc\xe2\xb6\xb8\x44\xcf\xcd\x5a\x7c\xed\x0e\x35\x30\x3f\x50\xa0\xdf\xe5\xdf\x5d\xde\x1a\x2f\x23"}, +{{0xc7,0x18,0x8f,0xdd,0x80,0xf4,0xcd,0x31,0x83,0x9e,0xc9,0x58,0x67,0x1e,0x6d,0xd0,0x8b,0x21,0xf9,0xd7,0x52,0x8c,0x91,0x59,0x14,0x37,0x34,0xf9,0x4b,0x16,0x98,0x83,},{0x01,0x97,0x52,0xff,0x82,0x9b,0x68,0x59,0xb9,0x05,0x8d,0x00,0xc2,0x79,0x5e,0x83,0x56,0x55,0x44,0x06,0x75,0x75,0x3f,0x37,0xe8,0x5e,0xb7,0xbc,0x58,0x39,0xc4,0xca,},{0x35,0xc1,0x70,0xdd,0x0c,0x6d,0xc2,0x92,0x0a,0x59,0x57,0x75,0xd8,0xe2,0xdd,0x65,0x24,0x3e,0x9c,0x1b,0xf9,0x6e,0xf4,0x27,0x79,0x00,0x1e,0xd4,0x5f,0x01,0xb7,0xdf,0xeb,0xd6,0xf6,0xa7,0xdc,0x2d,0x38,0x6e,0xf4,0xd2,0xa5,0x67,0x79,0xeb,0xe7,0x7f,0x54,0xe5,0xae,0xcf,0xda,0x2d,0x54,0xa0,0x68,0x47,0x6b,0x24,0xdb,0xd7,0x8b,0x0c,},"\x4a\xf5\xdf\xe3\xfe\xaa\xbe\x7f\x8f\xcd\x38\x30\x8e\x0b\xd3\x85\xca\xd3\x81\x1c\xbd\xc7\x9c\x94\x4e\xbf\xe3\xcd\x67\x5c\xf3\xaf\xbe\xf4\x54\x2f\x54\x29\x75\xc2\xe2\xa6\xe6\x6e\x26\xb3\x2a\xc3\xd7\xe1\x9e\xf7\x4c\x39\xfa\x2a\x61\xc5\x68\x41\xc2\xd8\x21\x2e\x2b\xd7\xfb\x49\xcf\xb2\x5c\xc3\x60\x9a\x69\x3a\x6f\x2b\x9d\x4e\x22\xe2\x09\x9f\x80\xb7\x77\xd3\xd0\x5f\x33\xba\x7d\xb3\xc5\xab\x55\x76\x6c\xeb\x1a\x13\x22\xaf\x72\x6c\x56\x55\x16\xce\x56\x63\x29\xb9\x8f\xc5\xdc\x4c\xbd\x93\xce\xfb\x62\x76\x88\xc9\x77\xaf\x93\x67\xb5\xc6\x96\x59\xe4\x3c\xb7\xee\x75\x47\x11\xd6\x65\xc0\x03\x2a\xe2\x29\x34\xf4\x4c\x71\xd3\x11\x78\xef\x3d\x98\x10\x91\x28\x74\xb6\x2f\xa5\xe4\x02\x0e\x6d\x5d\x64\x58\x18\x37\x32\xc1\x9e\x2e\x89\x68\x5e\x04\x64\xe9\x1a\x9b\x1c\x8d\x52\x51\xe2\x4e\x5f\x91\x81\x3f\x50\x19\xa7\x40\xa0\x4b\x5d\x91\xcb\xb8\x30\x9e\x51\x61\xbb\xa7\x9d\xca\xb3\x82\x39\xa0\x91\xf5\x0e\x09\x9f\xf8\x19\xe3\xa7\xb5\x20\x5f\xe9\x07\xcd\xfe\x9c\x0d\xc3\xee\x85\xe3\x2d\x7b\xcd\x3c\xe0\x26\x35\xe2\x05\x83\x88\x03\x1e\x31\x7f\xbf\x22\xab\x9f\x39\xf7\xf7\xe3\xcd\x1a\x11\xa9\xc1\xf4\x5f\x4e\x1e\x42\xd2\x53\x6c\x12\x2c\x59\x18\x37\x91\x18\x47\x10\x8c\xea\xfd\x99\x08\x13\xc2\xb6\x34\x4c\xff\xc3\x4b\xe3\x71\x61\xdd\x81\x56\x26\x90\x0e\x8f\xcb\x85\xc2\x1a\xfb\x4f\x6b\xe8\xad\x01\x51\x6a\x31\xc2\xa6\x58\x03\x15\x85\x7c\x6a\x21\x67\x35\xca\x99\x10\x09\xdb\xc2\xea\x50\x34\x16\x07\x47\xa8\x69\xd5\xca\xdb\x0b\x47\xff\xbd\x5d\x3a\xc9\x7f\xdd\x05\x26\xca\xe6\xea\xa3\x5c\xff\x7a\x16\xea\xf4\xfb\x95\x0c\xa3\x15\x11\x34\x6f\xea\x61\x41\x99\x9a\x3f\x75\x4e\x62\x81\xcf\xba\x15\xe8\xa8\x26\x93\x2c\x58\x9c\x5d\x24\x7c\x90\x9d\x94\xb4\xea\xb7\xeb\xcb\x09\x07\x76\x48\xaf\x06\x5c\x2d\x86\x61\x1e\xb5\x88\x45\x3e\xd7\xc2\x47\x80\xd7\x3c\x68\x9c\x87\x44\xaf\xd5\x33\xa8\x6d\x9e\xe9\xe3\x36\x57\x32\xcb\xd0\xc3\x51\xe4\x36\xf8\x98\xb7\x04\x32\x92\x09\x7e\x03\xe6\x08\x1a\x23\xac\x86\x5e\x19\xdc\x88\x58\x96\x9b\x99\x9d\x01\xfa\x65\xef\x20\x0c\x3f\x26\x9c\x81\x8e\x30\xb9\x36\x5e\xcc\x68\x3b\xcf\xe6\x9c\x20\x3b\x4e\x0a\xb6\xfe\x0b\xb8\x71\xe8\xec\xaa\xae\x82\xd3\xac\xd3\x5d\x5b\x50"}, +{{0x38,0xba,0x06,0x21,0x70,0x4d,0x21,0x55,0xfc,0x2f,0x78,0x55,0x51,0x96,0x57,0x5d,0xe0,0x6d,0x80,0x25,0x5c,0x35,0xe9,0xdc,0x96,0x5b,0x6f,0xe9,0x6a,0x4d,0x53,0x89,},{0x43,0x88,0xf7,0xf6,0x8a,0x9e,0xff,0xbc,0x36,0x6e,0x42,0xd9,0x07,0x01,0x56,0x04,0xda,0xce,0xd1,0x72,0x7c,0xd1,0xd8,0x9d,0x74,0xad,0xcc,0x78,0x9f,0xd7,0xe6,0xe1,},{0x42,0xbe,0xd6,0xa9,0x87,0x86,0xf6,0x64,0x71,0x5f,0x39,0xbb,0x64,0x3c,0x40,0x5a,0xe1,0x75,0x00,0x56,0x46,0x0e,0x70,0x04,0x69,0xc8,0x10,0x38,0x95,0x04,0xc5,0x1c,0xff,0xd9,0xe1,0xa9,0x4c,0x38,0xf6,0x92,0xfb,0x31,0x62,0x65,0x31,0x6d,0x8f,0x4d,0xc3,0xad,0x1c,0xdd,0x8a,0x6d,0x59,0x91,0xef,0x01,0x0c,0xd1,0x48,0x9d,0x7c,0x09,},"\xed\x4c\x26\x83\xd6\x44\xb0\x5b\x39\xb0\x48\xef\x1f\x8b\x70\x25\xf2\x80\xca\x7e\x8f\xf7\x2c\xb7\xed\xa9\x93\x29\xfb\x79\x54\xb7\x00\x40\x07\x05\x27\x5f\x20\xb8\x58\xcf\x7e\x34\x9a\x35\x10\x66\x5b\x63\x06\x09\xc5\xe2\xe6\x20\x69\x26\x3a\xb9\xc5\x5e\x41\x23\xa5\x64\xdc\xa6\x34\x8c\x8a\x01\x33\x20\x75\xe7\xa5\xbe\xc9\xc2\x0a\x03\x80\x79\x57\xfe\xfa\x91\x0e\x60\xc3\x5a\xe5\x79\x77\x8c\xe2\xce\x42\xe6\xa6\x9a\x1b\x64\x76\x81\xe4\x3e\xc4\xb6\x3b\xd5\xfb\xef\xab\xb3\x17\x12\xcb\x3d\x64\x19\xea\xd7\x8d\xd4\x1c\x8a\x92\xaa\xce\xb6\x3c\xbf\xa8\x9d\x2a\xf3\x96\x06\xde\x01\x0a\x39\x7e\x30\x20\x53\xa6\x15\xc1\x6e\x5e\x95\xad\x99\x35\xc0\x79\xa0\xb8\x10\x31\x25\x78\x94\x71\xa1\xe3\x57\x4f\x42\x9b\x29\xe4\xd2\x25\xc7\x72\x3f\xbb\x3c\xf8\x8c\xbd\x73\x82\x3d\x9f\x0b\x6c\x7d\x05\xd0\x0b\xde\xb0\xfb\x0a\xd3\xd7\x13\x20\x33\x18\x3e\x21\xf6\xc1\xe8\xd8\xe4\xc0\xa3\xe4\xf5\x2f\x50\x01\xda\x68\x71\x71\x34\x5c\x6d\xc8\xb4\x2c\x42\xa6\x0d\x1f\x1f\xfa\x8f\xe3\xe7\xbc\xec\xe5\x9a\x03\x58\x78\xf9\xd4\xd8\x11\x27\xe2\x24\x96\xa4\x9b\xfc\xf6\xbf\x8b\x46\xa8\x0b\xd5\x62\xe6\x52\x55\x07\x1f\x9d\x11\xa9\xeb\x04\x81\xf4\x62\x6d\x4d\x71\xff\xc3\x8a\xfe\x6e\x35\x8a\x4b\x28\x91\x79\xcb\xce\x97\x64\xd8\x6b\x57\xac\x0a\x0c\x82\x7e\x8f\xf0\x78\x81\x33\x06\xa1\xd5\xfa\xdd\x32\xb4\x6a\x1f\xbc\xd7\x89\xff\x87\x54\x06\x3e\xec\xfe\x45\x31\x3b\xeb\x66\x01\xc3\xa3\x01\x0e\x8e\xb9\x7c\x8e\xff\xbd\x14\x0f\x1e\x68\x83\x11\x09\x2d\x27\x3c\x4d\xef\xca\x47\xda\x6f\x1f\x08\x25\x74\x46\x76\xf9\xa2\x80\xb6\xc2\xa8\x14\xfa\x47\xfa\xbc\x19\x80\xd0\xb3\x7f\x08\x7a\x53\xca\x87\x78\xf3\x9f\xfb\x47\x4f\xf5\xf1\x17\x1b\x44\x2c\x76\xdd\x00\x8d\x92\x18\x2f\x64\x4a\x71\x4a\x0f\x01\x1e\x21\x5a\x78\xb9\x7a\xf3\x7b\x33\x52\x0e\xbf\x43\x37\x2a\x5a\xb0\xcf\x70\xdc\xc1\xdc\x2f\x99\xd9\xe4\x43\x66\x58\xf8\xe0\x7c\xdf\x0b\x9e\xa4\xdd\x62\x24\xc2\x09\xe7\x52\x1b\x98\x1e\xe3\x51\xc3\xc2\xdf\x3a\x50\x04\x05\x27\xfc\xd7\x28\x04\x17\x60\x46\x40\x5d\xb7\xf6\x73\x4e\x85\xc5\xd3\x90\xf5\x20\xb0\xc0\x8d\xcb\xfa\x98\xb8\x74\x24\x80\xd5\xe4\x6f\x9b\xe8\x93\xf6\xd6\x61\x43\x40\xf8\x16\x16\x11\xd5\x05\x3d\xf4\x1c\xe4"}, +{{0xae,0x33,0x1f,0xc2,0xa1,0x47,0x59,0xb7,0x3f,0x1c,0xd9,0x65,0xe4,0x85,0x14,0xe1,0x2b,0x29,0xf6,0x3b,0x06,0xcc,0xfc,0x0a,0xd4,0x9f,0x36,0x82,0x0e,0x57,0xec,0x72,},{0x08,0x80,0x3d,0x48,0x23,0x8e,0xda,0x3f,0x9c,0xeb,0xb6,0x28,0x53,0x01,0x21,0xde,0x00,0xf0,0xf0,0x46,0x8c,0x20,0x2d,0x88,0x52,0x8b,0x8b,0xce,0xc6,0x87,0xa9,0x03,},{0x75,0xf7,0x39,0x08,0x88,0x77,0xe0,0x6d,0xc5,0x6d,0xae,0xc8,0xf1,0xe4,0xd2,0x11,0xb7,0x54,0xe3,0xc3,0xed,0xbf,0xa7,0xed,0xa4,0x44,0xf1,0x8c,0x49,0xb6,0x9c,0x5a,0x14,0x2d,0xb4,0x5a,0x0a,0x76,0x50,0xe4,0x7d,0x10,0x55,0x0b,0xa6,0x81,0xff,0x45,0xdd,0x44,0x63,0xc4,0xac,0x48,0xbf,0x44,0xb7,0x30,0x34,0xbd,0x56,0x59,0x22,0x0e,},"\x57\x16\x00\x33\x90\xe4\xf5\x21\x65\x98\xa0\x3d\x7c\x43\x0d\xbf\x49\x5e\xe3\xa7\x55\x7b\x58\x06\x32\xba\x59\xf1\x51\x98\xb6\x18\x0a\x42\x46\x9c\x23\x7d\xb5\xbc\x81\xf2\x9c\xfa\xab\x0a\xff\x3c\x99\x66\x30\x9a\xb0\x69\x58\xc9\xd7\x12\x6a\xdd\x78\xe3\xb3\x24\x59\xff\x8a\x0e\x0b\xde\xf8\x74\xb5\x8e\x60\x83\x66\x8f\x38\xad\x7d\x63\xaa\xe1\xf1\x2e\x26\xa6\x13\x34\x8f\x9f\x03\xea\x5d\x20\x5f\x04\x5d\x78\xcc\x89\x02\xd4\x7f\x81\xe8\xb5\x22\x93\xe7\x0e\x86\xc9\x80\x3d\x4d\xac\xea\x86\xc3\xb6\x74\x58\xae\x35\x79\xbc\x11\x11\x3b\x54\x90\xbc\xf3\xe1\xcd\x4e\x79\x79\xc2\x64\xd8\x35\x16\x1f\xd5\x5e\xfe\x95\x3b\x4c\x26\x39\x5d\xd9\x2c\xa4\x93\x09\x20\xe9\x04\xfa\xdc\x08\x89\xbb\x78\x22\xb1\xdf\xc4\x45\x26\x04\x84\x0d\xf0\x24\xdb\x08\x21\xd2\xd5\xe9\x67\x85\xa5\xc3\x7d\xbf\xd2\xc3\x75\x98\x32\x83\xe9\xb5\xb4\x3a\x32\x07\xa6\xa9\xb8\x33\x94\x83\x29\xd5\xde\x41\xe4\x50\x08\xbc\xba\xd4\x93\xde\x57\x54\xdd\x83\xde\xcc\x44\x0e\x51\x66\xed\xaa\xe0\x20\x8f\x00\x0c\x5f\x6d\x9c\x37\x21\x53\x20\x9e\x5b\x75\x78\x11\x6f\x89\xcf\x2f\x8b\x10\x04\xd1\x30\x7e\xa7\x9e\xd3\x74\x80\xf3\x19\x4a\x7e\x17\x98\x3a\x23\x04\x65\xcc\xc3\x0f\xcc\x1a\x62\xd2\x80\xfb\xba\xcc\xf0\x06\xdc\x4d\xee\x0e\xa7\x96\xb8\x1a\xcc\xc6\x1a\x06\x3e\x2c\x08\x3d\xae\xc0\x39\xbd\x9a\x64\xa7\x70\x24\xaf\x82\xec\x1b\x08\x98\xa3\x15\x43\x29\xfd\xf6\x16\x73\xc3\x6e\x4c\xc8\x1f\x7a\x41\x26\xe5\x62\x90\xe4\xb4\x56\x81\x9b\xde\xbf\x48\xcb\x5a\x40\x95\x5b\xab\x29\x7c\x2b\xbc\xb0\x18\xad\xbf\x24\x82\x86\x60\xa5\xd1\x2a\x06\x13\xbf\x3c\xcb\x5e\xeb\x9a\x17\xfb\x0a\x05\x47\xdb\x8d\xa2\x4d\x2e\xfb\x87\xba\x1b\x84\x31\x42\xa7\x5e\x4c\xa0\xb0\xa3\x33\xe4\xa1\x4f\xab\x35\xa6\x26\x69\x32\x9c\xa8\x75\x3f\x01\x6a\xc7\x0c\xd9\x97\xe8\xbc\x19\xee\x44\x8a\xea\xf0\xf4\xbf\x3c\xe5\x23\x05\x50\x57\x8a\xb6\x4c\x19\x01\x94\x46\xce\x2d\x9c\x01\xa0\x3d\x88\x9a\x99\x09\x86\x0a\xef\x76\xf0\x67\xc5\x0b\x61\xc3\xd0\xf1\x2c\xc8\x68\x6f\x5c\x31\xbf\x03\x2a\x84\x10\x15\xcf\xef\xf1\xcf\xda\xe9\x4f\x6b\x21\xda\xe9\x41\xb3\x35\xdc\x82\x1f\x32\x84\xce\x31\x50\x8f\x5d\xb5\xc4\x48\xff\xaa\x37\x73\xe9\xbe\x1a\x4c\x85\xa1\xc5\x8b\x00\x9f\xa3"}, +{{0x82,0x43,0x5f,0x39,0x79,0x01,0x06,0xb3,0xaf,0x72,0xf9,0x1f,0x14,0xc9,0x28,0xd2,0x46,0x5f,0x98,0xcd,0xd1,0x00,0x84,0xc4,0xa4,0x4d,0x19,0xaf,0x71,0xa1,0x92,0x7c,},{0xc5,0x2a,0x92,0x64,0x6f,0x5a,0xdb,0x21,0xc6,0xdd,0xe0,0xde,0x58,0x78,0x68,0x37,0xf8,0xa3,0x41,0x4c,0x09,0xae,0xdf,0xc2,0x7c,0x81,0x22,0x18,0xa7,0xe7,0x23,0x9e,},{0x1d,0xaa,0x44,0xef,0x06,0xd4,0xc1,0x0d,0xdb,0x48,0x67,0x84,0x23,0xc5,0xf1,0x03,0xa1,0xb5,0x68,0xd4,0x2b,0x20,0xcc,0x64,0xaf,0x11,0x0f,0xce,0x9d,0x76,0x79,0xa2,0xde,0xe4,0x12,0xb4,0x98,0x05,0x85,0xc2,0x6c,0x32,0x0d,0xba,0xa6,0x01,0xc4,0x72,0xde,0xfc,0x3c,0x85,0x41,0x5d,0xae,0xcd,0xd6,0xd2,0xd9,0xea,0xca,0xc8,0x5e,0x07,},"\xf3\xd6\xc4\x6a\xc5\x24\x8d\x53\x86\xb6\xb6\x84\x62\x59\x7d\x64\x70\x39\xf5\x44\xbb\x01\xac\x2d\x10\x67\xda\xaa\xa3\x97\xd2\xdb\xaf\x12\x5a\x1c\xf8\xfd\xf2\x80\xa6\xaf\xec\x32\x4d\x53\x11\xf5\x43\x68\x8a\x15\x6c\x84\x98\x19\xbb\x04\x6b\x91\x1c\x42\xea\x3c\xa0\x1b\x99\x80\x8c\x4d\x1f\x3b\x8b\x15\xda\x3e\xfe\x2f\x32\x52\x3e\xc3\xb0\x9c\x84\xb4\x8c\xff\xd1\x3c\x17\xc9\xe2\x6c\x91\x2d\x9c\x3e\x93\x46\xdf\xae\x3f\xd0\xc5\x6c\x88\x58\x78\x07\x82\xf6\x1a\x4c\x4d\xbf\xff\x1e\x9c\xb4\xb3\x62\xcd\x80\x01\xf9\xcd\xfe\xb1\xa7\x20\x82\xdc\xe9\xc9\xad\xe5\x2e\xff\xc9\x74\x46\x88\xac\x0b\x86\xc8\x82\x66\xb5\x3d\x89\x5c\x17\xea\xd9\xe8\x9e\xd8\xd2\x4d\x40\x64\x2f\x3a\xd3\xb9\xbf\x9b\xbc\x4d\xda\x79\x66\xef\x83\x28\x28\x9f\xb3\x1e\x17\xc8\x1f\xd0\x28\xef\x1b\xd9\xa1\xd4\xc7\x92\xe8\x6e\xc2\xdb\xdc\xe3\xf9\x37\xee\xcc\x3e\xeb\x51\x88\xd3\x25\x94\x19\x19\xbb\xf7\x5b\x43\x88\xe2\x39\x95\x07\xa3\xd7\xfb\x38\x75\x02\xa9\x5f\x42\x1c\x85\x82\x6c\x1c\x91\x76\xc9\x23\xe3\x16\x31\x0a\x4b\xa4\x5c\x8a\x5e\xf7\x55\x7c\xf8\x7b\x77\x02\x0b\x24\xf5\xba\x2b\xfd\x12\x28\x10\x95\x66\x30\x7f\xea\x65\xec\x01\x50\x19\x69\x12\x17\xbc\xe6\x9a\xee\x16\xf7\x62\x49\xc5\x8b\xb3\xe5\x21\x71\xcf\xef\xd5\x25\x4e\x5e\x0f\x39\x71\x69\x18\x6d\xc7\xcd\x9c\x1a\x85\xc8\x10\x34\xe0\x37\x18\x3d\x6e\xa2\x2a\xee\x8b\xb7\x47\x20\xd3\x4a\xc7\xa5\xaf\x1e\x92\xfb\x81\x85\xac\xe0\x1d\x9b\xf0\xf0\xf9\x00\x61\x01\xfc\xfa\xc8\xbb\xad\x17\x1b\x43\x70\x36\xef\x16\xcd\xae\x18\x81\xfc\x32\x55\xca\x35\x9b\xba\x1e\x94\xf7\x9f\x64\x55\x55\x95\x0c\x47\x83\xba\xb0\xa9\x44\xf7\xde\x8d\xf6\x92\x58\xb6\xaf\xe2\xb5\x93\x22\x17\x19\x5d\xa2\x45\xfe\xe1\x2a\xc3\x43\x82\x4a\x0b\x64\x03\xdf\xe4\x62\xd4\x3d\x28\x8d\xb3\x1f\x99\x09\x7e\xc3\xed\xc6\xe7\x65\x47\xa3\x74\x2f\x03\xc7\x77\xef\xb1\x58\xf5\x8d\x40\x53\xfa\x6c\xc8\xd6\x8b\x19\x6a\xf4\xf9\xde\x51\x6f\xd9\xfb\x7a\x6d\x5d\x9e\xe4\xa8\x9f\x9b\x9b\xce\x1e\x4d\xee\x35\x7a\x1e\x52\xc0\x54\x4c\xfb\x35\xb7\x09\x2d\x1a\xa5\xa6\xf7\xf4\xc7\x60\x26\x10\xe9\xc0\x0e\xf5\xb8\x76\x1b\xc7\x22\x79\xba\x22\x8a\x18\xb8\x40\x0b\xd7\x6d\x5b\x2b\xfd\x7c\x3c\x04\xaa\xc4\x43\x6d\xae\x2e\x98"}, +{{0x1b,0xea,0x77,0x26,0xd9,0x12,0xc5,0x5e,0xc7,0x8b,0x0c,0x16,0x1a,0x1a,0xd3,0xc9,0xdd,0x7b,0xc3,0x29,0xf8,0x5d,0x26,0xf6,0x2b,0x92,0xe3,0x1d,0x16,0xd8,0x3b,0x48,},{0xc9,0xdd,0xb4,0x21,0x06,0xcc,0xef,0x4e,0x0e,0xf4,0x79,0x45,0x51,0xd2,0x1d,0xf9,0x4a,0x63,0x06,0x87,0x2f,0x23,0x16,0x63,0xe4,0x7e,0x24,0x1f,0x77,0xcc,0x3e,0x82,},{0xf9,0xb0,0x45,0x17,0xbd,0x4f,0xd8,0xef,0x90,0xf2,0x14,0x0f,0xc9,0x5d,0xc1,0x66,0x20,0xd1,0x60,0x2a,0xb3,0x6c,0x9b,0x16,0x5f,0xff,0x3a,0xba,0x97,0x8d,0x59,0x76,0x71,0x10,0xbb,0x4e,0x07,0xa4,0x8f,0x45,0x12,0x14,0x47,0xac,0x0c,0x1a,0xba,0xc5,0x85,0xd3,0x91,0xd4,0x04,0x20,0x41,0x89,0x86,0x28,0xa2,0xd2,0xdc,0xc2,0x51,0x0d,},"\xb1\x12\x83\xb1\xf0\xce\x54\x9e\x58\x04\x73\x0a\xc3\x20\x7a\xc0\x03\x32\xd2\xaa\xcf\x9c\x31\x0d\x38\x32\xd8\x79\xf9\x63\x4b\xd8\xa5\x8a\xdf\x19\x9e\x4b\x86\x3b\xb1\x74\x81\xd2\x8a\xcb\x2d\xa0\xe1\x55\x7b\x83\x36\xa4\x00\xf6\x29\x56\x25\x03\x1d\x09\xe4\xdf\x4d\x31\x9b\xbc\x1e\x8f\x6e\x92\x32\xd2\x30\x53\xbb\x3f\xfa\xc4\xfe\x2c\x70\xce\x30\x77\xfc\x00\x60\xa5\xcb\x46\x92\xa1\xcf\x0b\x3e\x62\xfe\x45\x48\x02\xae\x10\xb8\x3d\xed\x61\xb6\xbf\x45\x4c\xa7\x5e\x4c\xda\xd5\x53\x2f\x20\xb7\x06\x54\xf1\x2b\xa9\x06\xf0\x03\xa8\xb9\xe9\x86\xf1\x5a\x39\x41\x9d\xeb\x2e\xa1\xea\xd7\x59\x82\x90\xee\xeb\xf9\x25\x2b\x0c\x27\x60\x5a\x7a\x73\xa6\xab\xeb\xb4\x22\x71\xd7\x1a\x3c\x19\x7a\x46\xbc\xc8\xdb\x11\xd9\x24\x28\x42\xf3\x78\x36\x4a\x37\xee\xca\xa3\x4e\x98\x21\x35\xbe\x34\x18\x2c\x69\xca\x8e\x6e\x3c\x8c\x90\xe1\xb4\xb2\xb4\x75\x81\x5a\x17\x83\x77\xae\x01\x65\xa7\x64\xc8\xba\x28\x89\xb5\xab\x29\x09\x49\xd8\x48\x7a\x88\xe0\xd3\xd2\xbc\x7e\x25\x20\x17\x6a\xa6\xff\x9f\xf0\xc4\x09\xff\x80\x51\x5f\x4f\x0b\x83\xc5\xe8\x2c\x23\xfd\x33\x26\xcd\xd6\xb7\x62\x52\xe7\xfd\xdc\xd6\xe4\x77\x09\x78\xcd\x50\x3e\xd2\xd6\xb4\x80\x10\x11\x67\xd3\xf1\x91\xfe\xd8\xd6\xd7\x4d\x74\xa2\x00\x7d\xb1\x09\x2e\x46\xa2\x3d\xde\xcd\xdc\xdb\x98\x46\x64\x04\x7b\x8d\xd7\xcc\x8a\x57\x6e\x1a\x80\x6f\x52\xcb\x02\x7a\x94\x80\xa9\x5c\xc4\x4b\x1e\x6f\x2e\x28\x6e\x9b\x7a\x6b\xf7\xb3\x96\xfa\x54\x96\xb7\xa5\xb1\xc0\x3d\x9c\x5c\x27\xda\x1a\x42\x99\x0d\x10\xb1\x2f\xb8\x64\x0e\x15\x96\xf2\x6b\x36\x6d\x27\x0b\xa6\x4f\x99\xaf\xff\xe3\xfe\xce\x05\xa9\xb0\x25\x4b\x20\x8c\x79\x97\xcd\xb5\x12\xfc\x77\x52\x79\x54\xa1\xcb\x50\xfd\xab\x1c\xc9\xa4\x51\x62\x74\x1f\xd6\xf9\xd3\xfd\x5f\x2e\x38\x28\x53\xd7\x33\x5d\xba\x1e\x6b\x29\x59\xdd\x86\xe1\x25\xe6\x7b\x53\xdc\x8e\x45\x3c\x81\x0b\xc0\x1b\xf2\x0b\xce\x7b\x61\x8d\xd5\xd1\xed\x78\x41\x06\xee\x06\xa3\xec\xaf\x6b\x3b\xee\x0b\x56\x83\x3b\x0b\x81\x31\x39\xc5\xa6\x96\x00\x0a\x44\x9c\x97\x90\x6a\x2f\xbd\xdc\x2d\x9d\xe9\x40\x6e\xa2\x82\xac\x4e\xe5\xef\x8b\xf3\x85\x4c\x74\xa6\xb7\x17\x3d\xd2\xf7\x9c\x7a\x12\x6f\x3c\x7b\x04\x33\xfd\x4e\xa2\x6e\x87\x7a\x14\x83\x1d\xd4\x15\xa1\x9d"}, +{{0xd0,0x1a,0x0e,0xad,0x9d,0x69,0x48,0x33,0x28,0x3b,0x9c,0xd7,0x29,0x9a,0x7b,0xd7,0x5f,0xa9,0x0b,0x1d,0x2d,0x78,0x84,0xe4,0x55,0x7b,0x33,0xc9,0x98,0x77,0x2a,0x68,},{0xa0,0xf7,0x57,0x47,0x9b,0xa6,0x27,0xef,0xef,0x95,0xd6,0xec,0x7a,0x93,0x1d,0xfa,0xc4,0x37,0x3d,0xf3,0x3d,0xaa,0xf4,0xdd,0xc4,0xec,0x68,0x94,0xc8,0x26,0x1e,0xd7,},{0x9a,0x0f,0xf7,0xf3,0x51,0x74,0xec,0x3f,0x66,0xd2,0x2a,0x6f,0x06,0xdf,0x60,0xe0,0x9c,0x8f,0x62,0x3a,0x5a,0xca,0x81,0x0e,0x23,0xa8,0x8d,0x0e,0x6a,0x31,0xcb,0x6f,0x1c,0xe1,0xc1,0xf9,0xdc,0xcc,0x9e,0x14,0x84,0xb6,0x8d,0xd0,0x04,0xac,0x53,0x59,0x7e,0x29,0xad,0x6a,0xb7,0x2e,0x8c,0xe2,0xb7,0x5a,0xd5,0xb8,0x0e,0xb8,0x48,0x03,},"\x76\x27\x53\x4e\x9a\x83\xd1\xe4\x06\xab\x94\x8d\x30\xd1\xda\x9c\x6a\x5d\xb0\x8e\x0f\xeb\x7f\xc5\xba\x5c\xbf\x76\x84\x9e\xe8\xad\xd4\x84\x7e\xf5\xca\x5a\x0d\xae\x41\x1a\xca\x09\x74\x51\xcb\x4c\x2b\x49\x8c\x94\x70\x97\x40\x70\x07\x64\x0d\xc1\x9e\xd9\x38\xe3\xb9\x1b\xf5\x1c\x95\x81\x16\x8d\xf8\x60\xbd\x94\x75\x16\x68\xda\xbd\x72\x1d\xc7\x39\x98\x40\x0b\xe2\x0c\x9a\x56\x3d\x50\x51\xef\x70\xe3\x54\x6f\xee\x67\x33\x12\xb5\x2a\x27\x40\x41\x05\x7e\x70\x84\x8e\xb7\xc5\xa2\x16\x44\xc9\x7e\x44\x8a\xbd\x76\x40\x20\x7d\x7c\xda\xfc\xf4\x5d\xa6\xdf\x34\x94\xd3\x58\x5b\x0e\x18\xac\x5a\xc9\x08\x1c\xb7\xa4\x07\xa3\x9a\x87\x77\x05\xcb\xaf\x79\xa0\x1b\x91\x5f\x73\x6e\xb0\x25\xc5\x8b\x4b\x5d\x80\x7f\xb7\xb7\x56\x6c\x59\x69\x78\x7c\x1d\x6c\xa4\xeb\xa9\x7d\x50\x9e\xf7\xfb\x35\x50\xd2\x1d\x37\x7e\xce\xff\xcf\x0e\xb6\x68\x18\x95\xad\xbd\x24\x6e\xe7\xbf\x3c\x93\x5a\x00\x64\x78\xb8\x32\xec\xe4\x6d\xe6\x11\x8b\x17\xe4\x66\xa2\x7f\xc2\xa4\x4a\x89\x6b\xaa\xe2\x72\xf9\xec\xf0\x18\xc6\x5c\xb5\x0c\xfb\xfc\x8d\x26\x09\x94\xa1\x8a\x83\x2d\x97\x19\x28\xc4\x49\x67\x57\x24\x58\x51\x31\xc8\x71\x53\x3c\x98\x97\xd8\xf8\x0f\x9c\x04\x16\xb7\x18\x78\x6b\x10\xfe\xa8\xeb\x5b\xd8\x13\xa2\x69\xa1\xb6\x77\xb7\xa2\x50\x7a\x44\xb7\x13\xd7\x05\x08\x65\x30\x99\x5e\x59\x33\x5d\xdc\x28\x55\xe8\x47\xe4\xf4\xdb\x06\xc9\x1f\x1d\x54\x02\x3d\x8a\x10\xf6\x9f\x9e\x61\xbd\xce\x4b\x68\x6f\xb6\x17\xbd\x50\x30\xe7\x55\xca\xdb\x1f\x64\x4e\x1d\xdd\x91\x61\x9b\x96\xec\xd6\x05\xb0\x01\x98\xb9\xa6\xed\xdb\x5a\x84\xeb\xd3\x69\x2b\x66\x59\x79\x76\x66\x37\xc6\x77\x37\x8c\x1c\x77\x04\x1f\xd4\xa6\xb3\x55\x5c\x1d\xc8\xa8\x3f\xe9\x01\x3b\xb6\x10\x6c\xc1\x8a\x2b\x03\x7c\x93\x77\xb7\xa1\xa5\xa5\xd0\xdc\xc5\x49\x18\xea\xad\x7e\x32\xc8\x80\x76\x7b\x26\xfd\x2e\xa2\xd6\x8b\x04\x05\xf5\xe0\x74\xf5\x5a\x19\xd8\xa3\x9f\xfb\xb7\xdc\x32\xfa\xee\x6a\x7f\x95\x32\xae\xc8\xa0\x77\x6c\x3f\xf8\x3a\xe3\xa4\x62\x77\x38\x49\x6a\x37\x1e\xb9\xe0\x90\xb7\x4e\x0e\xdd\xec\xfc\xd4\x1b\xed\x0c\x0c\xe5\x81\x27\x52\x43\x47\x2d\x26\xda\x8c\x99\x8e\x4b\x6d\x6b\x44\xfc\x88\xba\x2a\xb5\x46\x42\x22\x54\x17\x12\x02\x94\x41\x78\x05\x74\x2b\xdb\x33\xb7\xb1\x22"}, +{{0xdf,0x64,0x89,0x40,0xb5,0x78,0xbc,0x31,0xd2,0xa6,0x52,0x96,0x5f,0x30,0x39,0x1c,0xaf,0x06,0xd5,0xf2,0x51,0x59,0x9a,0x73,0x7c,0xe1,0x0b,0xe5,0x5f,0x4a,0x9d,0x0d,},{0x27,0xde,0x92,0x04,0x19,0xc1,0x86,0xb0,0x1b,0xe5,0x42,0x79,0xfb,0x8f,0x9b,0xe4,0xbb,0x4b,0x2c,0xad,0x75,0xca,0x7e,0x8f,0x79,0x2b,0xfa,0x7b,0xb9,0x7c,0x7f,0x41,},{0x62,0xbc,0x99,0x1c,0x45,0xba,0x9b,0x26,0xbf,0x44,0x01,0x16,0x26,0x41,0x62,0xc3,0x4c,0x88,0x59,0x78,0x85,0xe9,0x60,0x50,0x83,0xc6,0x04,0xb5,0xf5,0xd8,0xfa,0x6f,0x66,0x2b,0xa2,0x14,0xf7,0x6e,0x6c,0xf8,0x4e,0x5e,0xc0,0x4d,0xf1,0xbe,0xef,0xc5,0xf2,0x5d,0x3a,0x3b,0x72,0xf9,0x8b,0x50,0x69,0x83,0x19,0x16,0xa6,0x32,0x96,0x01,},"\x1a\xe5\x20\xbe\xeb\x4a\xd0\x72\x2b\x43\x06\x7f\xa7\xcd\x28\x74\xab\xcf\x34\xdd\x92\x37\xb4\x47\x8e\xae\x97\x72\xae\xa2\x97\xa6\x7f\xb7\x9b\x33\x07\x02\x04\xba\xee\x44\x0b\x9c\x87\xe2\xfb\xcb\xeb\x76\x80\x1d\xdd\xea\x5e\x45\x30\xd8\x9e\x11\x58\x31\x79\x93\x9a\x00\xa3\x2f\x81\x13\x32\xc5\x22\x91\xcc\x7a\xc9\x1e\x5a\x97\x0c\xd5\xaa\x70\x8b\x1d\xa2\x6b\xe9\xfe\x43\x2a\x9b\xbd\xa1\x31\x9e\x31\xe4\xbc\xc9\xf1\x66\x6a\x05\xb5\xc0\x5b\x87\x6b\xfd\x1f\x76\x66\x87\xcc\xea\x4e\x44\x82\xe9\x24\x32\x9a\xfa\xce\x5e\xe5\x2e\x98\x79\xfd\x69\xb7\x6e\x0f\x7e\x45\x2e\xc4\x71\x3b\xff\x21\x6d\x00\xc8\x25\x99\xd2\x7c\xa4\x81\xf7\x3a\xae\x13\x6f\x08\x75\xc8\x8a\x66\xb1\xb6\xf3\x4c\x50\x52\x3a\xb6\x02\xe9\xd4\xeb\xb7\xee\xb9\xe0\x43\xa6\x5e\x41\x89\x9d\x79\x75\x2a\x27\x9d\x2e\xd4\x69\x93\x92\x6f\x36\x21\xe7\xc3\x2c\x9a\x9b\x3b\x59\xd8\xdd\x57\xbe\xca\x39\x28\x54\x34\xde\x99\x1c\xbd\x2d\xfc\xbc\x5c\xa6\x2a\x77\x79\xf4\x75\xd0\xce\xf2\xf3\xe5\x62\xf2\x9a\xcd\x47\x4f\x3c\x99\xec\x5b\xd8\xde\x01\x10\x1b\xed\x2e\x0c\x9b\x60\xe2\xd7\x0f\xd4\x32\xc8\x92\xfc\x66\xf8\xd4\x61\x9a\x91\x1b\x56\x25\x16\x3e\x9a\x42\xbf\x9e\xa3\x85\x86\xd8\xe7\x64\x00\x15\x64\xd3\x35\x41\x12\x25\xfc\xb0\xa0\x6d\xc2\xa8\x2d\xa0\x77\x9a\x3c\x44\x4e\xb7\x86\x42\x01\xb4\x3e\xbb\x72\xb9\x21\xf3\x4d\x3c\x13\x08\x9d\xf2\xf4\xfa\xc3\x66\xff\x1e\x3c\x0b\x96\xf9\x3d\x2b\x4d\x72\x6a\x5c\xe4\xd6\x91\x6d\x82\xc7\x8b\xe3\x54\xa1\x23\x0c\x2c\xf0\x41\x8c\x78\xa1\x91\x3e\x45\x4f\x64\x8c\xc9\x2c\x8d\xd0\xe1\x84\x64\x5f\xe3\x78\x1d\x26\x3c\xff\x69\xf5\xc6\x0b\x1e\xbb\x52\x00\x5a\x8b\x78\xa5\x15\xc7\xe8\x88\x6f\xfe\x05\x4d\xab\x42\x8e\x2e\x22\x1d\x9d\x76\xaf\xf4\x26\x54\x16\x8d\x83\x3b\x88\x17\x82\x93\xe1\xfe\xdd\x15\xd4\x6c\xd6\x09\x48\x31\x29\xc4\xd2\xd8\x44\x32\xa9\x9d\x31\xff\xe9\xbd\xb5\x66\xf8\xc7\x5c\xe6\x5e\x18\x28\x8e\x4d\xf8\xc1\x67\x31\xa0\xf3\xfd\xde\x1c\xca\x6d\x8e\xde\x04\x35\xff\x74\x36\xca\x17\xd0\xae\xb8\x8e\x98\xe8\x06\x5c\xbc\xbf\xd0\xff\x83\x04\x3a\x35\x7c\xd1\xb0\x82\xd1\x70\x3d\x46\x18\x81\x87\x2c\xdf\x74\x1e\x4f\x99\xbd\x14\x67\x45\xba\x70\x39\x74\xbe\x40\xf5\x79\xbf\x5c\x4d\xba\x5b\xdb\x8c\x94\x1b\xce"}, +{{0xc8,0xac,0x23,0x45,0x58,0xaa,0x69,0x81,0x6b,0x36,0x8b,0x77,0xb7,0xcc,0xcb,0x5c,0x8d,0x2a,0x33,0xec,0x53,0xae,0xef,0x2c,0xe2,0x28,0x71,0x43,0xbd,0x98,0xc1,0x75,},{0x53,0x64,0xba,0xf1,0xfd,0xb2,0xc6,0x38,0x40,0xb3,0x0d,0x40,0x31,0xcf,0x83,0xa2,0xe1,0x8e,0x62,0x07,0x93,0xba,0xe5,0x9d,0x10,0x35,0xc0,0xed,0xe5,0x5e,0x52,0x8b,},{0x32,0x25,0x03,0x61,0xdf,0x6e,0xd2,0x83,0x48,0x5f,0x95,0xf3,0xd3,0x57,0xa4,0xf1,0xc3,0x3a,0x8c,0xf9,0x16,0x58,0x32,0x7c,0xd4,0x53,0xd4,0x9c,0x95,0x36,0x65,0x51,0x08,0x70,0xaa,0x45,0x4c,0xfa,0x3b,0x83,0x24,0x52,0x20,0xa8,0x27,0xd0,0xec,0x74,0x77,0xf9,0xec,0xeb,0x79,0xc4,0xa2,0x9f,0x30,0x1f,0x95,0x3c,0xc8,0xca,0xac,0x07,},"\xce\x48\x8d\x26\x97\x5c\x1c\x93\x28\xb4\x7f\xa9\x2e\x19\x56\x13\x30\x04\x1b\x23\xa0\xe5\x7a\x4b\x8b\xca\x89\xeb\x5f\x61\x5e\x73\xdd\x7f\xae\x69\xc2\x38\x0e\x32\x12\xf9\xb7\x33\x41\xc3\x56\xdb\x75\xa6\x25\x6d\x7a\x20\xa9\x7f\x75\x9d\x4c\xba\x71\x97\x17\x8e\xa7\x24\xdd\x93\x29\x49\x36\x0e\x96\xc5\x0a\x4b\x3b\xa5\x5a\x95\x33\x72\xc3\x97\xb0\x96\x9c\x2b\x14\xd3\x60\x9e\x0a\x85\x2d\x48\x4d\xf7\x0e\xaa\xb1\x12\x49\xeb\xeb\x32\x37\x92\x1f\x0a\x39\xa5\x5d\x7d\xcc\xfe\xf2\x05\xd9\x4e\xc8\x0d\x9e\x1f\xd6\xa2\xc1\xef\xd2\x98\x44\x10\x1d\xfe\x2c\x5f\x66\x8a\xdb\x79\x75\x91\x5d\xed\xd0\x86\x50\x0c\xee\x2c\x1e\x23\x3e\x8e\x48\x85\x5c\xc1\xa6\xf2\x87\xd6\x3d\xce\x10\xad\xdd\x13\xca\xc7\xb7\xa1\x87\xef\xe4\x7e\x12\xd1\xc3\x5b\xb3\x97\x40\x52\xb2\x3a\x73\x66\x8d\x3e\x4c\x87\xdb\x48\x41\xaf\x84\x6e\x80\x86\x72\xc4\x3d\x0a\x15\x22\xe2\x96\x5f\x08\x39\x51\xb2\xb2\xb0\xc4\x09\x54\x8e\xe6\x18\x2f\x0c\x98\x50\x51\x4c\x9e\x6c\x10\x2f\x54\xba\x41\x24\xc9\x2a\x90\x27\x4f\x40\x58\x91\xe6\x62\xf5\xeb\xb3\x77\x1b\x85\x78\x31\x56\xe9\xe5\x83\x67\x34\xd0\x9d\x1b\xaf\x5b\x21\x34\xc9\x31\x62\xee\xc4\xbe\x03\xbd\x12\xf6\x03\xcd\x27\xbe\x8b\x76\xac\xcc\x6e\x8b\x8b\xac\x02\x0c\xba\x34\x79\x65\x1c\x9f\xfa\x53\xce\x4e\xb7\x7a\x77\x31\x3b\xc1\x26\x5d\xda\xb8\x03\xef\x7a\x65\x63\xba\x6f\x79\x9d\x1e\xf3\x0e\xf5\xa0\xb4\x12\x96\x5f\xda\xc0\xb9\xda\xb8\x42\xc7\x8e\xe2\xcc\x62\x8e\x3d\x7d\x40\x61\xe3\x4e\xde\x37\x97\xe1\x54\xb0\x6e\x8c\x66\xce\xbd\xf2\xde\xd0\xf8\x1b\x60\xf9\xf5\xcd\xda\x67\x5a\x43\x52\x77\xba\x15\x24\x55\x7e\x67\xf5\xce\xfa\xfc\xe9\x29\x29\x1d\xce\x89\xec\xb0\x8a\x17\xb6\x7a\x60\xc5\x82\xb4\x87\xbf\x2f\x61\x69\x62\x66\x15\xf3\xc2\xfe\x3b\x67\x38\x8b\x71\x3d\x35\xb9\x06\x66\x69\x96\x0d\xe4\xdb\x41\x3c\xd8\x52\x8e\xe5\x6e\xd1\x73\xe9\x76\xa3\xc9\x74\xac\x63\x3a\x71\x34\xcc\xe3\x83\x19\x73\x5f\x85\x7b\x7d\x71\xba\x07\xf4\x77\xef\x85\x84\x8a\xa8\xf3\x9e\x11\x81\x18\x77\x9e\xd8\x7b\x4f\x42\xaa\x35\x8a\x89\xf7\xec\x84\x4a\x45\x1e\x7e\x8f\xc0\xaf\x41\x8b\x85\xbc\x9b\xf2\xf2\x6d\x1e\xa1\x37\xd3\x35\xec\x7e\xe7\x57\xb7\x0a\xe2\xfd\xd9\xcc\x13\x49\x32\xf0\xe5\x42\x5b\xf3\x7f\xb9\x15\xe7\x9e"}, +{{0x2c,0x47,0xf2,0xb8,0xb9,0xd2,0xce,0xe9,0xe6,0xf6,0x54,0xbc,0x24,0x65,0x8f,0x9e,0xaf,0x43,0x9c,0x23,0xbe,0xaa,0x0a,0x79,0xbf,0x35,0xcc,0x8c,0xd2,0xde,0xba,0xf4,},{0x44,0x4a,0xf2,0xf3,0x4f,0xd3,0x2e,0x5a,0x19,0xf6,0x1f,0x87,0xd0,0x3e,0x10,0x76,0x27,0xa3,0xee,0xb8,0xbd,0x94,0xd2,0xfa,0xea,0xa3,0x48,0xb0,0x5d,0xea,0x19,0x80,},{0x85,0x54,0xb0,0x1d,0x09,0xed,0x86,0xe6,0x13,0x95,0xb9,0x1a,0x2b,0x1e,0xe1,0x87,0x15,0xc4,0x2f,0x9c,0x7e,0x7f,0x07,0x00,0xd7,0x9f,0xf9,0xfb,0x57,0x81,0x29,0x3d,0x61,0xc5,0x58,0xdd,0x5b,0x43,0x1c,0x93,0x71,0x8d,0xcc,0x0f,0x98,0xfb,0x65,0x2b,0x59,0x6f,0x18,0xc3,0x0f,0x82,0x21,0x5e,0x8e,0x63,0xe4,0xf6,0x56,0x8c,0x88,0x00,},"\x04\x4c\x8f\xaa\x8c\x8a\xaf\x9f\x2b\x81\x86\xa6\xb9\xb3\x38\x47\xec\x7b\x45\x24\x23\xb2\x2a\x91\x74\x3d\x2e\x59\x7e\xcc\x1e\x1e\x22\xae\x60\x05\x3e\x9e\xe6\x23\x3b\x04\x4e\x77\x59\x20\xe4\xe3\xd6\x67\x19\x90\x13\x25\xcf\xdd\x39\xbb\x53\x2f\x8a\xa4\x69\xaa\xb4\x2e\x96\x08\xc2\x12\x60\xc0\x4c\x27\x41\x3a\x7a\x94\xe4\x66\xf6\x3c\x49\x52\xe9\x0e\xf9\x0c\x12\x81\x4b\x34\x51\xb1\xca\xd7\xda\x91\x47\xf8\x40\x92\x20\xf6\x49\x8c\xc0\xa6\x7f\xef\x4b\xc0\x4f\xc0\x6e\x1d\x89\x8a\x55\x15\x59\x1e\x8b\xe0\xc4\x3d\x75\xa6\xfe\x42\x5b\x7c\xbe\xfb\x1b\x91\xb1\xbd\x78\xb5\xbe\xc7\x82\x90\x56\x98\x2e\xfd\xc5\xbe\x24\xaf\x66\x78\x00\x6a\xdc\x6f\x04\x46\x20\x2e\x7e\xc3\xa2\xd6\x97\x9c\xb0\xdf\x7e\x25\xd7\x42\x33\x91\x4d\x9c\x58\xb8\x1c\xf5\x5b\xe0\x69\x67\xd3\xa5\x95\xc1\xb9\x67\x28\x69\x99\x4c\xfb\xa6\x71\x62\x83\x3a\x21\x43\xaa\x91\xcc\x93\xac\xda\xfa\x5b\x45\x20\x8d\xf3\xe8\x8c\xcc\x01\xa2\xa4\xd2\x20\xe3\x60\x09\x8d\x91\x54\xd2\x25\xa7\xca\x5f\x2f\x1e\x52\xb1\x00\x3d\x10\x66\x50\xa7\x7b\x28\x3b\x95\xe4\xba\xf1\xe7\x33\x6f\xa9\xa7\x47\xa2\xb3\x82\x3d\x36\x09\x10\x41\x2e\x76\xdb\x72\x5c\xe1\xab\x1e\x1d\x18\x9d\x0d\x3a\xbe\xf8\x2d\x76\x66\xbc\xf1\xb7\x66\x69\xe0\x64\x3b\x44\xf7\x4e\x90\xce\xaf\xa0\xc8\x37\x1b\x57\xc5\x8f\x3b\x37\x0a\x54\x7c\x60\x95\x8f\x0f\xcf\x46\x1b\x31\x50\xf8\x48\xc4\x70\xfa\x07\xe2\x9b\xf5\xf0\xd4\xb5\x9e\xfa\x5a\xb0\xd0\x34\x1e\x04\x51\xd0\xab\xb2\x9d\x74\x14\xcd\xdc\x46\xcc\x6d\x74\xcf\x3d\xc2\x33\xd0\xd1\x70\x73\x87\xbd\x8c\x77\x80\xff\x78\xe5\x46\xfb\x77\x29\x4d\x58\xa5\xdd\xa5\xf0\x5c\x12\x97\xe3\xd1\x77\x11\x56\xd2\x85\x63\x5b\xf7\xec\xed\xb3\x8a\x9e\x5e\x77\x44\x98\x04\xf3\x89\x9e\xa4\x6a\x50\x26\x6b\x25\x5a\xeb\x52\xd1\x8e\x0f\xa1\x36\xe5\x35\xcc\x90\x26\xf6\x78\x55\x2f\xa3\xee\x21\x46\x08\x1d\x99\x96\x85\xe2\x4b\xf7\x80\x7c\xc4\x7c\x13\x04\x36\xc5\x44\xd3\x5b\x4b\x87\x5b\xd8\xaf\xa3\x12\xce\x3a\xe1\x7c\xf1\xc7\xf5\xea\x1e\xce\xcb\x50\xf9\x53\x44\x72\x0c\xec\xf0\x88\x43\x4f\xf8\xe0\xba\x04\x4e\xc1\x9c\x98\xad\xa7\x78\x21\x16\x30\x4c\xbe\xac\x1c\x3e\x35\xf5\xa4\xf4\x43\x13\x35\x4d\xc9\xa4\x0e\xce\x5a\x0f\x9a\xd3\xa2\x02\x5a\xce\xf2\x62\xc5\x67\x9d\x64"}, +{{0x88,0x7f,0xdb,0x48,0x70,0x68,0x1d,0x4f,0xb0,0x6a,0x93,0x62,0x59,0xf7,0x5c,0xae,0x05,0x17,0xf5,0x01,0xaf,0x64,0x6b,0xc0,0x7a,0x4d,0x72,0xbe,0xe7,0xfb,0x1c,0x73,},{0xc7,0x62,0xeb,0xd4,0x8b,0x2c,0xe0,0x2d,0x06,0x38,0x4e,0x38,0x55,0x4b,0x82,0x5a,0xd3,0x22,0xeb,0xea,0x74,0xd2,0x59,0xdf,0x15,0x47,0xa4,0xd5,0x47,0xce,0x00,0x24,},{0x41,0x0a,0x5a,0xf3,0xc5,0x9b,0x7c,0x6b,0xdb,0x21,0x4b,0x16,0x6c,0xb7,0x9d,0x96,0xf8,0x30,0xcf,0x98,0xbf,0x52,0xda,0xd7,0xb6,0xff,0x29,0x79,0xc9,0x7f,0xea,0x4f,0xed,0x5e,0xf7,0xd3,0xd4,0x9f,0x03,0x09,0x72,0x79,0xb9,0xa0,0x99,0x22,0x6e,0x2a,0x08,0xdd,0x30,0xc6,0x07,0x86,0x25,0x4e,0x2d,0xa8,0xde,0xe2,0x40,0xbf,0xc3,0x08,},"\xc5\xdc\x77\x9f\x3f\x3f\xac\x06\xdd\x28\xe5\xa6\x7e\x0e\x52\x4a\xf5\xb5\xdc\x3b\x34\x40\x96\x57\xb6\x3d\xfa\xce\x94\x71\xe9\xa4\x1e\x11\x32\x17\x5a\x0b\x56\x9c\x8f\xea\x9d\x2e\xef\x2c\xf5\xd5\x96\x2c\x7e\x0b\x61\x45\xa9\xe7\xa0\xc1\xaa\x33\x77\x20\x44\xf9\xc3\x99\x8c\x5a\x8c\x48\x86\x45\x8b\x4e\x58\x6f\x93\x07\x60\x83\x61\xf5\x11\xe7\xab\x50\x92\xac\x41\xec\x76\xe0\x58\x6e\xf5\xb9\xc2\x36\xfc\xf5\xca\x2f\xc8\xdd\x6a\xae\xb7\x89\x36\x7f\x2e\x7c\x99\x09\x32\x55\x5d\xc5\x22\x61\xe4\x4e\x49\x42\x34\x98\xb5\x24\x41\x91\x83\xb6\xc1\xf1\xd4\x2c\x45\x46\x4e\xcc\xb0\xc2\xf7\xe2\x51\x77\xfe\x5c\xd4\x63\x50\x2b\x40\x3e\x06\xd5\x11\xfc\xf9\xdc\xb6\x40\x12\xe0\xf2\x0b\x34\xc2\xea\x7c\x00\x4d\x9e\x48\x4a\x7e\xd8\x1f\x32\x60\xc4\x1c\x8b\x19\x53\x52\x9f\x47\xf7\x1e\x86\x78\x43\xcc\x3c\x33\x2a\xd0\x36\x6a\x63\x81\x7e\xd1\x2d\xd4\x73\x0d\x3d\xfd\xbd\x75\x72\xb9\xff\x79\x80\x45\x94\x0d\xd1\x9f\xad\x0c\x8a\xea\x0b\x4a\xb6\x1c\x40\x16\xde\x32\x79\x9c\x73\xaa\x2b\x92\xd2\xc2\x5e\xe9\xb7\x2d\x46\xfe\x8f\x06\x93\xc5\x87\x75\xef\xb0\x5e\x9e\x17\xa5\xc3\x46\xa8\x12\x65\xd3\x5b\xe6\x9a\x22\xd0\x95\xde\x18\x60\x66\xa5\xc6\xd8\xc0\x7a\x3d\x38\xd0\x02\xa1\x0e\x5e\xfd\xb8\x66\xda\x4a\x9b\xdd\x54\xf5\x09\x26\x61\xb6\xc2\xd7\x43\xf5\xae\xaa\x4c\x6c\x31\x8f\xb5\x93\x23\x90\x30\x57\xe4\x9c\x23\x7b\x45\xf6\x75\x42\xa4\xf2\x7c\xaf\x65\xb5\x7c\xfc\xf8\x8b\x71\x20\x3d\x43\xd7\xf9\x53\x22\x16\x0f\x95\xc2\x32\xdd\x10\xab\xb1\x13\xb7\x21\xdd\xba\x22\x26\xb0\x63\x22\x9b\xb4\x41\x02\x33\x6b\x10\xbf\x16\x56\x55\x11\x61\x24\x97\x86\xd4\x54\xf4\xe0\x90\x9d\x50\x00\x17\xf6\xc7\x56\x4f\x73\x3c\x83\x1a\xf4\xe5\xec\x94\xdf\xd3\xbf\x8f\xf5\xf3\x02\x1b\x70\xa5\xca\x5d\x28\xc6\xdf\xb8\xa2\xc1\x8a\x1a\x66\x2a\x33\x35\x9f\x26\x4d\x16\x96\x98\xc1\xab\x55\x78\x3f\xac\xa7\x3b\xd6\x8c\x0f\x79\xd1\xd0\x4a\xe0\xec\xdb\x52\xae\x76\x18\x92\xc0\x24\x93\xff\x35\xf3\xd8\x4f\x66\xe2\x36\xfc\x58\x13\x4a\xd6\xa7\x7d\x92\x25\x49\x05\xd7\x73\x90\x0d\x9d\xdf\x26\x54\xc7\x0b\x46\xf3\x41\xda\xcb\x47\x93\xca\x51\xee\xde\x45\x53\x3e\xae\xeb\x6e\x33\x23\xbc\x3e\x6c\x85\xa7\x94\x06\x51\xc4\xf6\xf9\x81\x91\xc6\x18\xc8\x91\xea\x4e\x22\x0e\xa4"}, +{{0x88,0xb3,0xb4,0x63,0xdf,0xc3,0x0d,0x01,0x5e,0xef,0xbb,0xbd,0xd5,0x0e,0x24,0xa1,0xf7,0x27,0x77,0x75,0xbc,0xef,0x14,0xa6,0xbe,0x6b,0x73,0xc8,0xc5,0xc7,0x30,0x3e,},{0xf2,0xb6,0x28,0x4c,0x93,0x0d,0x4a,0xd3,0x2d,0x0a,0xc7,0x19,0x04,0x0e,0xe7,0x88,0x6b,0x34,0x72,0x2e,0xdf,0x53,0xda,0x80,0x1a,0xcb,0x5f,0x93,0x19,0x69,0xe1,0x19,},{0x82,0x5a,0xff,0x71,0xf7,0x93,0x03,0xbf,0x45,0x92,0xbd,0x8d,0xa4,0xd7,0xd9,0x43,0x7f,0xf2,0x67,0x97,0x6f,0x74,0x64,0x37,0x65,0x59,0x88,0xdd,0xcf,0x29,0x37,0x94,0x65,0xa3,0xb4,0x8c,0x9f,0xb0,0xf3,0x1c,0xef,0x03,0xe6,0x36,0x88,0x61,0xc3,0x69,0xb4,0x36,0x4f,0xb8,0xe4,0xb0,0xc7,0x2e,0x26,0xa9,0xa9,0xdd,0xed,0x1c,0x25,0x04,},"\x17\xc3\x17\xfa\x6b\xc9\x0c\x55\x32\x32\x8f\x02\xcc\xfb\x6c\x09\x9e\x6f\xe1\x00\x01\x74\xf2\xaf\x3a\x3a\x93\x09\x42\x85\x06\x71\x7c\x5c\x43\x35\xbd\xd7\xc3\x67\xff\x4e\x44\x8a\x9c\x04\x75\x03\xaf\xba\x68\xfd\x8f\x79\x87\x23\x7b\xe7\xf7\xfb\xdc\x6d\x73\xf2\x4c\x64\x21\xca\xb4\x22\xb3\xfb\x25\xf6\x7b\x2d\x71\x04\x2e\x71\x57\x0d\xf2\xaf\x37\xbf\xe5\xc1\x14\x21\x1f\xd5\x52\x4b\x6c\x1c\x6c\xc5\x2f\xab\xc3\xcd\x7f\xb4\x64\xcd\x58\x0b\xb7\x40\x71\xcb\x30\x0f\x8c\x9f\x8a\x46\x20\x8e\x5a\xa5\xdd\xfe\xa5\xfe\x90\x69\x7a\xa2\xf1\x4c\x60\x79\x50\xc9\x8f\x23\x12\xa9\xe1\x6e\xf6\x34\x6a\x8f\xd1\x29\x23\x27\x33\x82\x7e\x15\x01\xa6\x60\xc7\x7c\x29\xc5\x6d\x2f\xdd\x1c\x55\x97\xf8\xbc\x89\xaa\xef\xe3\x71\x37\x34\xfe\x82\x85\x82\x01\x89\x1a\x11\x47\xef\xaf\x1d\x78\xa4\x71\xf9\x20\xde\xfc\x88\x03\x44\x55\x3e\xb7\x16\xcc\xe3\x26\x0e\x86\xa1\xbc\x0b\xe2\x83\x73\xa6\xa0\x66\x11\x6e\x8e\xcb\x10\xa0\xc4\xa7\x0c\xa2\xb5\x36\x4e\x11\x9f\x84\xae\xc6\x0d\xec\xed\x3a\x4e\xff\x1f\xe6\x88\xc5\xe3\xe2\x51\x47\x0a\xb5\x16\xfa\x96\x4a\x4b\x6f\x28\x36\x8d\xd1\xe2\x83\x59\x79\x34\x06\x4d\xc0\xc5\xb5\x69\x10\x62\xcb\x2e\x26\x7b\xd1\x5f\xd4\x22\xbc\xfe\xfb\x83\xcc\xef\x7a\xa9\xa2\x27\x5e\xf5\x7e\x47\x31\x49\x98\x8c\x15\x78\xfd\x18\x70\x8d\x2f\xf6\x9f\x8e\x59\x80\xaa\x82\x6a\x82\xca\xb7\xd8\xb9\x2b\xb5\x3b\xdd\x46\xdb\x04\x6e\xcd\xfc\x8c\xd7\xae\x5c\xe4\x4f\x3c\x5b\x8c\x05\x65\xb5\xd3\xc0\x72\xc7\x6b\x95\xce\x90\x0a\xc3\xee\x55\x10\xdb\x0e\x75\xd3\xa4\x15\x0a\x98\xf3\xcc\xcc\xc6\x9e\x93\x0c\x6b\xa7\x41\xdb\xb0\xeb\x9f\xb3\x19\x68\x71\xba\x20\x6a\x58\xe0\xda\xe3\x9c\x8d\x6b\xb7\x2a\x82\x39\x9c\x4b\x7b\x9d\xa3\x85\x77\xac\x17\xff\x15\x24\xd6\x53\xc0\xbf\x33\x67\x93\x23\xca\x7e\xef\x4e\x92\x28\x72\x90\x31\x56\x0e\xd8\xf2\xe5\x19\x3c\x64\x0b\x2f\x5e\x60\x80\x75\xa2\xed\x61\x42\x8d\xfc\xcd\xc0\x00\x50\xba\x4b\x99\xed\x6d\x15\x36\xd5\xac\x1e\x93\x96\x74\xb4\x1d\x16\x31\x2a\xe5\xb0\x7d\xef\x1b\xf5\x35\x89\xbe\xd4\x40\x06\x02\xee\x11\xb8\x50\x33\x0f\x38\xaa\xd3\x3e\xf0\x41\x70\xa3\x90\x5c\x28\xb5\x0e\xcc\x57\xdc\xcf\x4f\x29\xd0\xc0\x0f\x71\x3d\x32\xff\xc8\x57\x95\x65\x88\xa6\x32\x6b\x95\x49\xed\xb0\xe4\xfe\x61\x85"}, +{{0x42,0x7d,0x6e,0x42,0x39,0x17,0x89,0x68,0x31,0x60,0x1b,0x8f,0x4e,0x21,0x56,0x1d,0xb6,0x10,0x85,0x71,0xbe,0x00,0x9e,0x29,0xdc,0xa4,0x9a,0x59,0x60,0xff,0x31,0x4b,},{0x8d,0x9e,0x63,0x60,0xfd,0xef,0x24,0x99,0x75,0xdf,0x27,0xb3,0x10,0x6a,0x71,0x12,0x05,0x87,0x72,0x2d,0xf3,0x27,0x0a,0x85,0xa1,0x3a,0x8c,0x3b,0xb8,0xc9,0x80,0x9e,},{0xd1,0xc9,0xa0,0x1c,0x56,0xe3,0x39,0x60,0xf4,0x9d,0xf3,0x7e,0xab,0x96,0x3b,0xc5,0xa9,0x9f,0x25,0xc6,0x00,0x44,0x6c,0xe2,0xca,0x48,0xd9,0x13,0x9d,0xa5,0x73,0x3b,0x71,0x8f,0xbf,0x1a,0x98,0x73,0x93,0xf6,0xe5,0x82,0x3c,0x2d,0x13,0x0c,0x7c,0xe6,0x0e,0xa3,0xdb,0x35,0x43,0xc8,0x85,0x4e,0xf1,0x2b,0x98,0xd3,0x3a,0xdd,0xe7,0x05,},"\x9c\x2c\xc7\xf2\x46\x2e\x09\xc4\xc5\x8c\x27\x09\xab\x42\x59\x88\x5a\x4e\x88\x7d\x9f\xa5\x31\x88\x15\x05\xaa\xf2\x03\xc1\x63\xfb\x3a\x0d\xc0\x28\xf4\xad\xa6\x06\x70\x63\x8d\x4a\x97\x27\xa3\x90\x83\xbe\xdb\xac\xed\x58\xed\xb7\x79\xe1\xce\x6c\xcd\xfb\x42\x8c\x36\x2b\xb1\xdb\x0c\x10\x53\x00\x6b\xd8\xf4\xbe\xf8\x9a\x1a\x9d\xe0\x1c\x77\x4e\x35\x7f\x91\x0e\x5c\x39\xb2\x24\x77\x55\x5e\x5f\x7c\x04\x98\xb5\xb2\x8f\x36\x9e\x5d\x3f\xa4\x2a\xb3\x60\xe4\xf4\x51\xc6\x9f\x81\xba\x0f\x3c\xce\xd4\x3a\x55\x9d\xb6\x00\x10\x42\x78\xf8\x68\x79\x6b\x2c\x91\x1b\x3b\x03\x2b\x72\x9f\x4b\x22\xac\x14\x9d\xc4\x67\xa0\xca\xe4\x8d\x19\xe9\xd9\x85\xb4\x2b\x62\x54\x9d\xe1\x71\xff\x56\x6e\x1d\x1e\x9b\xb8\xe5\x6c\xfd\x1a\xe8\xf7\xbd\xdc\xfd\x8a\x23\x41\x82\x7d\xbe\x89\xc8\x82\xab\x3e\x49\x83\x39\xff\x68\x1c\x7d\xc1\x10\x4d\xe7\x38\xb4\x80\x31\x69\x43\x10\x9f\x70\x3d\x47\x1a\xb8\x6e\x4c\xa4\x28\x7e\x4c\xd7\x4c\x31\x2f\xf7\xd0\x37\x39\x56\x06\xfb\x25\xf8\x71\xe7\x27\x70\x78\xa7\x87\xd0\x2f\x31\xcc\x9e\x81\x5b\xe8\x60\x0a\x7c\x47\xc6\xfd\xd8\x23\x31\xae\x9c\x49\x6a\x54\x7b\xdb\x23\x5b\x8a\x56\xd5\x32\x59\xe6\x29\x61\x24\xa3\x2c\x3b\x62\x5d\x20\x24\x19\xd0\x64\xb9\xa4\xe8\x3e\xfa\x87\xf1\x35\x37\xb4\xf5\x13\xb9\x16\xa8\x4f\xc8\x66\xd8\xa8\x99\x80\x4c\x78\x33\xea\xa0\x19\xe0\xd7\xe0\xe8\x07\x5b\xd6\xb5\xcb\x6f\xfc\x76\x64\x79\xf3\xf6\xe2\x0e\x48\x1e\x6a\xb2\x7b\xd8\x08\xad\x90\x6c\xdc\xc7\x82\x74\x30\xe3\x12\xf7\x40\xf2\x75\xdd\xf5\x1d\xd8\x32\x48\xfa\x05\x7c\x43\xc9\xcb\x77\x55\x7b\x2f\xd9\xc2\xd5\x28\x24\xff\x9e\x14\x6d\xea\xc1\xe6\x69\x1d\x45\x02\x13\xbc\x59\x0a\x49\xbe\xc7\x2d\x52\xe3\x8f\x6b\x4d\xc6\xcc\xa9\x51\xee\xf2\x18\x4d\x24\x25\x03\x1a\xd5\x9b\x24\x2e\xff\xa6\x8b\x6c\x72\xc5\x4c\x9d\xfd\xb4\x19\xc0\x2e\xb4\x3e\xf3\xf3\x4d\x33\x8d\x2a\x9d\xd0\x3a\x78\xcf\xdd\x01\x40\x98\xe2\x49\x25\x9e\x77\x28\x2e\x0c\x3f\xc1\x01\x0b\x02\xa6\x7f\xf8\x51\xe9\xcf\xd9\x74\x9c\x1c\xd8\xf0\x6c\xf4\x62\xe6\xad\xe9\x95\xac\x46\x6f\xab\x5c\x79\x5e\x9e\xff\x13\xe5\x5b\x43\x50\xb9\x4c\x73\x16\xaa\x49\x8d\xf9\xfd\xee\x99\x58\x04\x77\x93\xe3\xbb\xb8\x9f\xb8\x1d\xa8\x5f\x4b\x9d\x43\xe4\xb0\xd4\x3b\x38\x1b\x94\xcd\xc9\xa9\x9d\x06"}, +{{0xbe,0x93,0x52,0x09,0xf6,0x2d,0xea,0x60,0x12,0xec,0xda,0x6a,0x61,0x56,0xcd,0x16,0x6a,0x4d,0x76,0x11,0x50,0xde,0xed,0x45,0x68,0x16,0xea,0xf0,0xce,0x78,0xa7,0xf6,},{0xd3,0x9a,0x89,0xaf,0x72,0x29,0x39,0x48,0xb1,0x34,0x21,0xfb,0x88,0x3b,0xbe,0x37,0x2a,0xf9,0x08,0x9c,0x22,0x4d,0x42,0xb9,0x01,0x97,0x9f,0x7e,0x28,0x04,0xe1,0xc0,},{0x08,0xe0,0x98,0xa7,0x49,0xfc,0xe6,0xd1,0x23,0x54,0x39,0x58,0x78,0xa8,0xbe,0x35,0xfe,0x9e,0xdf,0x72,0x68,0x4d,0xd8,0x28,0x12,0x24,0x89,0x9b,0x1c,0xae,0xa4,0xed,0x68,0x77,0x85,0xdf,0xf5,0x5a,0x19,0x98,0x9e,0x03,0x63,0x6e,0x16,0x66,0x38,0x6f,0x22,0xc3,0xf4,0x43,0xec,0xf6,0xfd,0x34,0xd5,0x99,0xff,0x3e,0xc2,0xfa,0xf1,0x01,},"\x11\x7f\x42\x7c\xb6\x81\x50\xca\xfc\xfa\x46\x2c\x42\x20\x61\x41\x42\x7c\x4d\xce\xa1\xc8\xea\xcc\x2d\x30\xbe\xd1\xe9\x02\x07\xd5\xae\x30\x5e\x1f\xc1\x6c\x54\xe4\xc5\x4c\xc6\x87\x8c\xdb\xed\xc9\xf5\x1f\xe1\x84\x61\xec\x37\xc5\x57\xb1\x15\xd1\x3c\x86\x82\xc4\xe1\x5f\x50\x52\x96\xa1\x76\x0e\x1e\x75\xf5\xab\x27\xa5\xc1\x5a\x13\x57\xd2\xc8\xc4\x0d\xd5\x35\x5f\x7c\x82\xfe\xa5\xd2\x7e\x28\x87\x63\x58\xc1\x2e\x91\x13\xee\x29\x83\xea\x6f\x09\xc6\x4e\x06\xe2\x97\xdd\x96\xb3\x4d\x9b\x5e\xd4\x9f\xc4\x7a\x88\x39\x54\x9c\x66\xb0\x02\xfe\x94\x5e\x8f\x94\xe7\xd2\x31\x5c\x50\xca\x4d\xc0\x98\xbe\x4b\x32\x89\x81\x2f\xbe\xa9\x6b\x47\xce\x60\x45\x40\xbd\xe0\xe5\xab\x0b\x1b\xc0\x36\xbe\x9b\x6a\x95\xe0\x9c\x81\xe8\x98\x64\x0c\x8f\x05\xd6\x0a\xd9\x42\x18\xd0\xe6\x6c\xeb\x85\xa2\x6b\x78\x29\x22\x20\xbf\xd0\x61\xdd\x07\x35\x12\x92\x3b\x90\xc7\x9d\xcf\x5a\x19\x35\xfa\xfe\x8e\x01\xef\x8b\xf8\x1b\x4d\x37\xc5\xa5\x71\xb5\x0c\x42\x1f\x9b\xd2\x19\x4b\xef\x35\x86\xfc\xb8\x58\x48\x77\xbb\x7e\x04\x81\x65\x5b\x05\xc7\xb6\x43\xb1\xe4\x5b\x04\x03\x62\x72\x84\x18\x52\xe3\x19\x40\xef\x8f\x3b\x6d\x4f\xeb\x5d\xf0\x79\xd1\x76\xf9\x79\xc1\x8a\x11\xa6\x6d\x12\x14\xe5\x2f\x68\x7e\x90\x63\xc1\xc2\xb7\x27\x7b\x68\x5d\x5c\x72\xad\x56\x9f\x78\x73\x83\x8f\x91\x02\x57\xa0\x53\x13\x1c\x83\xeb\xce\x86\xe6\x9d\x73\x63\x62\xbe\xbc\x96\xbb\xfa\x35\xfc\xba\x1c\xb5\x27\xe7\x48\xe5\xf5\x79\x92\x9f\xd4\x0c\x56\xb1\xa5\x1a\x22\x2e\x86\x33\x02\x70\x5c\x86\xf7\xb5\x4e\xbf\xbb\x94\x82\xf7\xe2\x80\xf7\xbe\xc8\xca\xf3\xa6\xb5\x67\x1a\xc3\x0c\xd1\xbe\x52\x92\x88\x79\x7c\x01\x3c\xe5\x6b\xd1\x86\xde\x7d\xfc\x18\x28\x69\x14\x25\xc1\x47\xc5\x17\x4a\x29\x0d\x80\xcb\xd5\x9c\x19\xda\x7a\xdf\x77\x91\x88\x82\xa7\xb2\xa9\xa6\x4e\x6d\x76\xb4\x8b\x92\xf2\xa2\x66\xee\xe6\xe2\x51\xd2\xe8\x17\x65\x2b\x88\xb5\x02\xde\x73\x99\x78\x2d\x75\x29\xa8\x1d\x0a\x36\x39\x96\xb9\xdf\x68\xb1\x5a\x76\x30\x90\x4c\x8c\x24\x60\x81\xfa\x4f\x09\x29\x9f\x15\x75\x79\x58\xe0\x89\xa9\x01\xc3\x56\x46\x15\xc0\xf7\xcf\x27\x52\xb8\xb9\xe5\x21\x33\x8d\x83\x6e\x3d\xae\x4c\xe2\x37\x46\x42\x25\x3c\x4c\x98\x31\x97\x4e\x5d\x8c\x28\x42\xf4\x90\x07\xb7\x17\x75\x09\x3d\xfe\x57\xf4\x44\x92\xf0"}, +{{0x68,0x18,0xc6,0x0b,0xb6,0x43,0x9a,0xc2,0xee,0xe2,0xd4,0xe1,0x28,0xe9,0xd8,0x69,0x1d,0x4a,0xd5,0xd3,0x63,0xfe,0xd7,0xd6,0x57,0x7a,0x62,0xb6,0x56,0x99,0x94,0xa4,},{0x73,0x45,0xec,0x11,0xbc,0xcc,0x05,0x6f,0xc4,0xef,0xfa,0x3e,0x4e,0xf6,0x70,0x99,0x6a,0xa2,0x6a,0x1b,0xb1,0xb8,0x33,0x91,0xba,0xbc,0x39,0xa1,0xa5,0x96,0x01,0xf9,},{0x15,0x05,0x96,0x7a,0x27,0xb9,0xf8,0x6e,0x92,0x42,0x44,0x40,0x02,0xa1,0xe3,0x19,0x7d,0x74,0xdd,0xcd,0x89,0x65,0x9e,0xc5,0x14,0x02,0x02,0xaa,0xc7,0x94,0xb8,0xad,0xc1,0x93,0xe7,0xd3,0x0f,0x33,0x82,0x64,0x29,0x90,0xf6,0xfe,0xd7,0xa9,0x99,0xca,0xc8,0xc6,0x1e,0xaa,0x39,0xb7,0xd9,0x08,0x16,0xf1,0xd7,0x38,0x74,0x4b,0xe1,0x01,},"\xb2\xae\x65\x8b\x3c\x13\xc3\xcd\xeb\x1d\xc9\x93\xb0\xf4\x5d\x63\xa2\xea\x9a\xbd\x0b\x7a\x04\xf1\xf5\xce\x59\x32\x80\x6c\x2c\xa9\xb7\xa2\x04\xfb\xf8\xd0\x66\xb7\xf0\xfe\x6a\xe0\xd1\xda\x68\xc8\x85\xee\x11\xf6\xf6\xdb\x7e\x83\x20\xa2\xea\x65\x0b\x53\x38\x51\xcd\xd9\x9d\x90\x3a\xa0\xb3\xfa\xa3\xc9\x50\xf7\x02\xf0\x4e\x86\xb4\xee\xb3\xa1\xc7\xbc\x85\x4b\x25\x14\xfa\x5b\x47\x66\xd3\x75\xb4\xf1\xad\x61\x07\x53\x78\xdd\x92\xfd\x62\x6c\x2b\x47\xe0\x13\x83\xea\x72\x98\x79\x59\x26\x2c\x56\x28\x62\xb4\x5b\x75\x57\x67\x14\x13\xb6\x66\x14\xbc\xc9\xf7\xbd\xb9\xee\x46\xcb\xed\x89\x65\xbf\xa5\x05\x31\x50\x90\xc7\x20\x4b\xea\x89\x17\x5b\xe5\xf2\x08\x02\xe3\xde\xdd\xcb\xd8\xdd\x64\xcf\xef\x7e\xe6\xa6\xe3\x86\x0c\xe1\xe5\x79\x9d\xf5\xd8\x10\xd5\xec\xf3\x2e\x61\x5d\x16\xdf\xf8\x7a\xbd\x4a\x63\x6e\xa1\x7a\xa4\xec\xe5\xb6\xb2\xc0\x46\xb6\x5b\x5a\xf7\x49\x86\x2b\x45\x79\x0c\x39\x17\x68\x20\xb3\x69\x01\xbe\x64\x9c\xf4\x16\x9d\xf7\xe9\x23\x95\x6d\x96\x06\x49\x50\xc5\x55\xf4\x5a\xcb\x94\x50\x7c\xfd\x0c\x3b\x33\xb0\x80\x78\x5e\x35\xc0\xd2\xb0\xad\xdc\x4c\x0a\xd3\xfb\x21\x6a\xc2\xe6\x01\xc9\xc7\xe6\x17\xda\xbd\xa3\x33\xda\xe6\x03\xcc\x9d\xb1\xfc\x62\xae\x4e\x0e\x45\xe3\xcc\xdd\x16\x6a\x67\x81\xe2\x43\xb7\xda\xa1\x38\x80\x66\x32\xf5\x38\x84\x4e\xe3\xd1\x40\xb7\xa8\xbb\x2b\x54\x01\x00\x77\x8c\x45\x8e\x06\x61\x70\x70\x5e\x5f\xb2\xc8\x80\x29\x09\x8b\x99\x2c\x39\xbc\x9f\xf6\x33\x0b\xfc\xfe\x77\x52\x32\x0e\x6e\xa0\x94\x9d\x2c\x87\x1a\xed\xc1\x87\xbe\x27\xfe\xf7\xdb\x5f\x72\xa6\xa7\x73\xed\xde\x0d\xc5\x2a\xe2\xed\x93\x1c\xb2\x68\x17\xb8\x5b\x15\x45\x89\x4d\x92\x29\x8a\xaf\x87\xcc\xbc\x78\x3e\x8d\xd6\xd1\x64\x93\xf5\x6e\xad\x2b\xa8\x52\xee\x9c\x7d\x10\x07\x44\x06\x44\x0d\x2a\x27\x9a\xbc\x87\x4f\x15\x46\x8d\xd6\x6a\x71\x7b\xac\xe3\x7b\xe7\xb7\x05\x5d\xd9\x68\x1f\x8b\xe8\x13\x29\xee\x7a\xf9\x7e\x3a\xbc\x43\x4a\xc1\xc9\x3a\xec\x58\x2f\x23\xfd\x1e\xc0\xfa\x5a\xaf\xcf\x7b\xfb\xda\x00\xff\xa9\x7a\xe3\x17\xae\x91\x8d\x34\x9d\x21\xa7\xf4\x61\x91\x42\xba\x23\xda\xce\xf7\xb3\x90\xae\x26\xa1\x7e\x2e\x29\x62\xae\x27\x00\x53\x76\xb7\x2d\x4d\xa9\xe2\x97\x96\x53\xa6\x63\x25\xa1\x46\x17\x63\x8d\xbe\x1a\x55\x40\xb6\x83\xac\x00\x17"}, +{{0x6d,0x1d,0xa5,0xb4,0x83,0xe6,0x4b,0x03,0x65,0x99,0x0f,0xf0,0x93,0x81,0xfb,0x17,0x02,0xfd,0x8e,0xc3,0xa1,0xa3,0x69,0xcd,0x52,0xe4,0xc5,0x67,0x13,0xa3,0x14,0xa5,},{0x08,0x05,0x5c,0x26,0x1f,0x26,0xe0,0x2a,0x65,0x8f,0x66,0xd9,0xba,0x01,0xfc,0xde,0x53,0xe9,0xad,0xe3,0xed,0xc6,0xbf,0x81,0x5e,0x4a,0x68,0x02,0xe1,0x67,0x7a,0xb3,},{0xa5,0xb8,0xb4,0x4a,0x91,0x44,0x4c,0x64,0x37,0x4b,0x52,0x3c,0xb4,0xdc,0xb0,0xce,0xf4,0xce,0x52,0x40,0x8b,0x98,0x12,0x6d,0x7e,0x1a,0xe8,0xbd,0xc2,0x8c,0xf5,0x14,0x70,0xce,0x4e,0x25,0x3e,0x0b,0xe6,0x2b,0xd6,0x8e,0xbf,0x5f,0xa6,0xbc,0xe1,0x58,0x5e,0xcc,0xfa,0x92,0x56,0xc0,0x73,0xee,0x03,0xe5,0x4c,0x52,0x5b,0xbe,0x2d,0x0a,},"\x79\xa2\xc3\x70\x55\xf1\x89\xf3\x24\x7f\x1f\x8c\xea\x19\xb2\xea\x40\xd8\x58\xdb\x1f\x5d\x13\x92\xee\x6d\x41\x1c\x78\x02\xee\x23\xde\x52\xad\x02\x81\x17\x25\xa9\x4d\x76\x67\x5d\xa8\x9a\x96\xb5\xd0\x7a\xbc\xee\x23\x3a\x1a\x2e\x1f\xa3\x24\xff\xf9\xe7\x8a\x4c\x19\x61\x47\xf8\x57\x0b\x0b\x13\x71\x3d\x96\xaa\x5d\x75\x0a\x15\xd7\xcd\x16\x2e\x7b\xa2\xe7\x53\x33\x60\x7d\xd6\x98\xeb\x47\x73\xc7\xe9\x1f\x76\x68\xff\x8b\x62\xf0\x46\x40\xeb\x12\xec\xf1\x22\xfc\xe6\xb8\x32\xe0\xd0\xdf\x92\x8e\xef\xd2\xc2\x00\x23\x64\xaf\x6b\xb5\x52\x91\xd3\xf5\x49\x29\x08\x5b\xe3\x38\x34\x2f\x09\xda\x73\xe2\x79\xc8\x7c\x83\x24\x55\x58\x19\xed\x57\xe7\x8d\x7a\xc4\x09\x51\xd3\x3f\x65\xb9\x4a\xa1\xe5\x55\xe9\x2a\x06\x3d\x11\xf1\xff\x7b\x12\x69\x43\x41\xe3\xfe\x44\x49\x33\xd0\x1a\xa3\x67\x53\xed\x3c\xdd\xa8\x90\xbd\xf9\x5a\x82\x05\xb5\xd8\x93\x22\x19\x91\xc7\x95\xad\x0a\x4a\x94\x6f\x58\xd4\x0a\x45\x34\x51\xaf\x21\x4f\xd4\x65\xe2\x8d\x3e\x2f\x0a\x56\xaa\x56\xde\xf8\xdc\x04\xaa\xd3\x57\x13\xab\xfc\x8b\xd7\x85\x6d\x5a\x9d\xc3\xf6\x0a\x3f\x2b\xd3\xe6\x36\x6f\x1f\x24\x4e\x94\x1d\x6a\xea\x89\x2f\x6a\x88\x93\x1f\xe1\xc3\x13\xe0\x90\x78\xe9\x0b\xc6\x39\x2d\x49\x05\x33\xc9\xea\x3f\xf6\xde\xaf\x3a\xad\xfa\x8d\xfd\xc4\xe9\x0f\x64\xaf\x47\x58\x9e\xa6\x5a\x87\xac\xd2\x19\x96\x02\x35\x1d\x3a\xfc\x21\x03\x19\x6e\x03\x94\xed\x52\x3a\xa7\x99\xd3\x1e\x11\xd3\x4f\xff\x54\x6d\x44\xf4\x36\xb3\x48\x59\xf9\xcf\xbc\x9c\xe4\x03\xde\x5a\x98\x30\xec\x3d\x45\x3f\x0d\x45\x97\x0f\x57\x2c\x14\x4f\x19\x1b\x2f\xbb\x2d\x0e\xa6\xcc\x9c\x8e\x24\xd9\xc0\xb2\x18\x3b\x27\x80\x72\xeb\xb0\xbe\x2d\x70\xd0\x37\xfd\x2e\x8e\xc1\x8d\xc4\xc9\xb2\x1a\xbd\xc6\xa4\xce\x8d\x46\x68\xa2\x20\xee\xbd\x69\x34\xf0\x4b\xaf\x0e\x88\xa4\x88\xd2\xdf\xc7\x35\xa7\xc5\xa7\x0d\xbb\x01\x66\xa2\x1a\xe0\x11\xfc\x6e\x7d\xa1\x0f\xc3\x20\x33\x62\x71\xd9\xee\xad\x51\x0a\x6f\x70\x32\xf2\x29\x66\x92\xbe\x50\x80\x21\xbc\x98\xc1\x70\xbe\x42\x35\xf7\xce\x31\xf2\xbc\xd6\x34\x11\x63\x68\x33\x76\xae\x2c\x56\x62\xcb\x47\x70\xc9\x6e\x01\x8e\xf1\xbf\x47\x91\x33\x19\xc9\xa0\x9b\x9e\x96\x5a\xb5\xc3\xe9\x7b\xbc\x75\x6a\x56\x66\xb4\x56\x7f\x2c\xff\x2d\x0c\x3a\x6a\x40\x26\x15\x8c\xb9\xf9\x0f\x95\x00\x56"}, +{{0x51,0x46,0xf5,0xb7,0xf1,0xba,0xa1,0x9f,0xc8,0xcd,0x78,0x5c,0x89,0x6e,0x0f,0x90,0xf9,0xf6,0x59,0xb7,0x7b,0x1b,0x9b,0xb4,0xad,0xca,0xb5,0xa6,0x26,0x72,0x05,0xe4,},{0x68,0x8a,0x8d,0xe6,0x4e,0xff,0x33,0xba,0x6b,0xbe,0x36,0xcd,0xd6,0xa3,0x84,0xbb,0x67,0xb3,0xf4,0x26,0x36,0xdb,0x23,0x4f,0xf5,0xef,0xe0,0xb3,0x17,0x43,0xc7,0xe6,},{0x4b,0xdb,0xd7,0xc6,0x4f,0x13,0xe2,0x78,0xc2,0x39,0x69,0xe7,0xeb,0x38,0x6b,0xbe,0x49,0x9d,0xbd,0xef,0xc3,0xff,0x4e,0x30,0xcf,0xac,0x5c,0xf8,0x6f,0x21,0x6c,0x24,0xc9,0xe6,0xcd,0xe2,0x0e,0x52,0x9d,0x14,0x7f,0xb7,0xea,0x08,0xf2,0x59,0x3a,0xd5,0x09,0x03,0xb5,0xed,0xbf,0x86,0xb4,0xd2,0x8f,0x2e,0xb3,0x2e,0xf1,0x37,0xf0,0x0c,},"\x97\xbd\x99\xf5\x18\xee\x07\x88\xd5\x76\xd9\x9c\x04\x3b\x44\x9d\xfc\x24\x2a\xc5\xee\xae\xc3\x44\xa1\x94\x32\xb3\x45\x96\x2e\xc4\x12\xce\x55\x36\x2b\x3b\x85\x1d\x98\x11\x9f\xce\xb9\x32\x83\x47\xf6\xfc\xc6\x8d\xbf\x56\xa2\x81\x4d\xb0\x9e\x93\x85\x84\x3a\x93\x11\x89\xea\x3e\x72\xda\x9d\x79\xa4\x56\x93\x05\x3c\x03\x57\x01\xdc\x55\x51\x24\x0f\x95\xb3\x03\xfb\xa1\x6f\x89\xaa\x53\xa4\x38\x82\xb0\xf1\x38\x12\x02\xc7\x8f\x9c\x74\x19\x89\x9f\x23\x51\xec\xa9\x5e\x20\xbf\xee\x76\x35\x1c\x48\xd0\x04\x99\xf5\x91\xda\x56\xa9\x95\x24\xbb\x74\xfe\x1c\x83\x4e\xe9\x10\x77\x13\x9f\x1e\xdf\x67\x31\x5c\x07\xa3\xfd\x97\xf8\x0b\x7c\x27\x6b\x6c\xf6\xb5\xcc\x36\xbe\x36\x3b\x73\x12\x17\xf6\x31\x9f\x51\x29\xba\x7b\x14\xd0\x54\xc8\xd8\x1d\x8e\x3a\x3f\x3b\xe6\x2a\xc3\x1f\xf6\x2d\xf6\xa3\xb2\xee\x25\x96\x96\x9b\x99\x17\x04\xb3\x1c\x68\x99\x97\xab\x46\x28\xbc\x26\x60\xc6\x78\x72\x13\x2e\x85\xda\x0c\x4f\xcf\x56\x79\x65\xf1\x25\x4a\x8f\x43\x26\x92\xa1\x7b\xb8\x6c\xb3\xc1\xdc\xba\xac\x93\x95\x52\xf0\x9e\x50\xec\x5b\x0d\xe2\xef\x85\xe0\xac\x25\x3a\x41\x65\x65\x5d\xb5\xb5\xc4\x98\x03\x82\x1d\x85\x9c\x60\x96\x1e\x06\x1d\x58\x27\x8b\x82\x7d\xd4\xd3\xbc\x47\xf1\xc2\x2d\xe0\x94\x90\x6b\xdb\xbf\x3b\xad\xbd\xde\x22\xba\x24\x25\x58\x55\xeb\x86\xd1\xd7\xf3\x70\x82\x05\x93\x11\xdc\x07\x28\xeb\xea\xf2\x6c\x44\x73\xba\xd1\xfa\x9e\x61\x4b\x53\x3b\x81\x1b\x6b\xcb\x06\x50\xc0\x6d\x87\x9a\x52\x45\x78\x8f\x34\x01\xb4\x61\x97\x30\x07\x74\xa9\xaa\x73\xcd\x97\x8c\x05\x30\xc8\x1a\x53\xbd\xb3\xfc\x93\x24\x14\xb3\xe3\x04\x40\xdc\x12\x74\x41\xef\xf1\x60\x5e\x7f\xd9\xac\x8c\x63\x2e\x82\xbf\x1b\x45\x3d\x4f\x33\xa5\x7e\x4b\x67\xb0\xb6\xfc\xf6\xed\x55\x55\xb5\xf5\xa3\x00\xa1\x4a\x00\xd0\x38\x5a\x33\x75\x05\x25\xb0\x0e\xdb\x31\x2c\x6b\xfd\xd6\x4e\xdd\x3b\x53\x16\xd1\x9f\x95\x8c\x51\x76\x34\xf0\x13\xb0\x08\x93\x6d\x34\xe9\xb5\xe1\xe9\x28\x3a\x5f\x0f\xd7\x78\x33\x77\xc0\xe5\x09\x06\x41\xbb\x9d\x33\x8c\xf3\x13\x3a\xcd\x0b\x97\x1e\x53\x79\x04\xf1\x7a\xf9\x29\x11\xaf\xad\x72\xee\x97\xf9\xa8\x28\x3a\x16\xa7\xe2\x6a\xb4\x28\x41\x6c\x10\x17\xda\xe9\xb1\xa9\x9c\x4c\x33\x20\xad\x16\x3b\xdc\xfc\x32\x8b\xfa\xf9\xb8\xd5\xd7\xd2\x6d\x41\xd1\xef\x21\xa5\x20\x8f\x01"}, +{{0x5e,0x6f,0xda,0xc9,0x35,0x1a,0x63,0x7b,0x99,0xf3,0x3a,0x26,0x4e,0x12,0x87,0x69,0x7e,0x2a,0xba,0xb0,0xcc,0xa1,0x66,0x21,0x79,0x24,0x84,0xf5,0x60,0x6f,0x44,0xc1,},{0x57,0xe5,0xf8,0x8a,0xcd,0xdc,0x8c,0xde,0x7d,0xd0,0x7a,0x31,0x46,0xfb,0x1d,0x4f,0x7a,0x9b,0x63,0x83,0xa8,0xf6,0xb2,0xb8,0xd9,0xb0,0x7e,0xbc,0x3f,0xc4,0xdd,0x20,},{0x98,0x7e,0x32,0xe0,0x0a,0x8a,0x16,0x32,0xf4,0x7b,0x50,0x31,0x94,0x35,0x5c,0x98,0x0c,0xb2,0x2a,0xde,0xb3,0x26,0xb4,0xe3,0x11,0x5e,0xca,0xb0,0x4b,0x70,0x4d,0x18,0x6c,0xd9,0x2e,0x3c,0x3a,0xc7,0xb4,0xe2,0x93,0x6c,0xbd,0x07,0xcb,0x79,0x4e,0xc0,0xcf,0xe9,0x1a,0x97,0x87,0x2f,0xf2,0xb4,0x13,0x76,0xf5,0xf1,0x8f,0x55,0xb8,0x05,},"\x4d\x6c\xd3\xbc\x2f\x86\x26\x6b\x8b\xb1\xb6\x1d\x0e\x1c\xaa\x9b\xd2\xd4\xa1\x80\x36\x1a\xef\x3a\x18\xd3\x90\xb1\x0f\x7e\x86\x0f\x69\x7e\x24\x7e\xb6\xc3\xe5\x1d\x3b\x97\x6b\xf0\xca\x18\x3d\x01\xa6\x98\x80\xf1\x5c\x94\xb8\x75\x66\x8c\xa3\x0d\xad\xa0\x89\x5b\xed\xd4\xd7\x05\xa0\xe0\x33\x04\xd0\x63\xde\xa8\x7c\x7f\xde\xc9\x8b\x89\xc0\x6f\x13\x0d\xd5\xbd\x58\x6b\x54\xd9\xba\x73\x78\x26\xbb\x40\x5c\xd8\xac\x8b\xbc\x95\x00\xac\xda\x3c\x07\x46\x1d\x00\x94\x40\xaf\x0b\x25\x31\xe7\x2f\x3f\xf5\x01\x6a\xe2\xd8\x6d\x69\xb8\x7f\xb2\x73\xd1\xe8\xdd\x5f\x6a\x26\x4b\xee\xbb\x2f\x88\x59\x96\x74\x1f\xfd\xa2\x77\xa0\xfb\xf8\xef\x08\xf8\x1f\x22\xee\x59\x61\xd9\xd3\xfc\x93\x83\x62\xe1\xca\x12\x00\x4a\x91\xd9\xb5\xf7\xa6\x83\x3a\x6c\x22\x95\x5a\xc0\xcd\xa3\x39\x06\x71\x91\x0c\xbd\x51\xe6\x85\xfe\x09\x59\x73\xe4\x15\xfc\x2d\xb8\xad\xf1\x0b\x14\x7e\xc7\x08\x0c\x3b\x8e\xbd\x07\xd2\x1b\xb9\x55\x6d\xa8\x54\x30\xa2\x68\xee\xd8\x48\x6b\x1e\x31\xc9\x43\x13\xb0\x16\x49\xfe\x91\xb2\x22\xf8\x5a\xde\xe1\x5e\xb7\x77\x07\xd7\x8f\xfc\xb6\x60\x92\x65\x44\xd3\x3b\xe9\x99\x4a\x29\x76\x20\xdc\x7a\xed\x97\xf3\x92\x63\x90\x53\xf3\x88\xb0\xb3\xaa\x3b\xd0\xac\x5b\x03\x3c\xb4\x14\xbe\x52\x0b\x43\xdf\x68\x26\xb9\x76\x89\x0d\x0c\x53\xb9\x7b\x6c\x92\xe7\xd1\xa1\x57\x3d\x0c\x74\x94\xd7\x47\xe0\xca\xd9\xbd\x8e\xa5\x38\xd6\x2a\xd5\x98\x01\xad\x07\x16\xf1\x70\x19\x3e\x30\x09\xd9\x95\x9c\x55\xd2\xff\x64\x79\x9b\xd9\x59\x35\x9a\xbb\x94\xca\x97\x23\xb5\xff\xc2\x4c\x95\x07\xf8\xc5\xfd\x6e\x88\xea\xae\x7a\x70\xad\xd8\x4d\x74\x4c\xcf\x8b\x98\x36\x37\x88\xf0\xbf\xb1\xa0\x25\x22\x02\x57\x51\xe5\x34\x71\x0d\x40\xa2\xd3\x8a\x79\x11\x94\xeb\xa2\x93\xfd\x20\x46\xcc\x14\xdd\x38\x76\xd1\x68\xfc\x6e\x23\x6c\xbe\x14\x6d\x63\x69\xd2\x25\xbf\xa6\x7e\x53\x97\x98\x65\xf7\x88\x73\xa9\xfc\xf0\x3c\x18\x6f\xa8\x52\x1f\x0a\x55\x45\xac\xce\xe8\x0d\x1e\x55\x10\x72\x21\xe2\x1f\x0f\x22\x91\xc1\x43\xde\x02\x3e\x88\xd7\x33\x0c\xc8\x7d\x4c\x51\xff\x29\xa3\x09\x06\x05\xe9\x73\x94\x90\xc1\xdc\xee\x71\x34\x95\xf2\x31\xc2\xa3\x6b\x11\xab\x23\x55\x47\xfb\x63\x28\xf7\x47\x33\x6d\x9b\x1e\xf2\x5a\x8a\xb9\x9c\xed\xa9\x57\xb2\xdc\xce\xe4\x07\x5b\x0d\x03\x38\x1b\x94\xae\x18\xd0\x41\xea"}, +{{0xfc,0xff,0xf0,0x93,0x2d,0xc8,0x6e,0xa5,0x90,0x2a,0x8d,0x33,0x07,0x33,0x29,0x96,0x0c,0xd8,0x18,0x8a,0x07,0x5d,0xd0,0xbc,0xdf,0xa8,0x38,0x2c,0x20,0xb0,0xe7,0x8f,},{0x0c,0x92,0x05,0xa9,0x0b,0xbe,0x7f,0x2d,0x50,0x5e,0x17,0xfa,0x3d,0x08,0x0b,0x52,0x2a,0x1d,0x7a,0x15,0x2c,0xad,0x2d,0x85,0xd3,0x1b,0x34,0xa0,0x47,0x1c,0x0d,0x4c,},{0x37,0xdd,0xd8,0x3f,0x98,0xb0,0x57,0xb7,0xcb,0x32,0x08,0xa8,0x32,0xc5,0x8a,0xa9,0x06,0x94,0x56,0x3c,0x23,0x54,0x8d,0x43,0x22,0x91,0x38,0x0b,0x73,0x59,0x13,0x01,0xf2,0x74,0xb0,0x4c,0xee,0x2e,0xf7,0x8c,0x06,0xd9,0x6c,0x3d,0x9b,0x7c,0x17,0x52,0x1a,0xae,0x1a,0x8c,0xa5,0x0d,0x34,0x7c,0x09,0xc3,0xcf,0x70,0x3b,0xc8,0x83,0x0b,},"\x3d\x4b\x76\x12\x23\x73\xe2\x12\xa3\x46\xd1\x9a\x66\xbb\xfc\x4b\x62\x32\x92\x64\x9b\xd0\xce\x5c\xf6\xbb\x13\x56\x48\xbd\x01\xdb\x74\x03\xb3\xd0\xbd\xd1\x69\x7f\xf4\xe6\xe9\x08\x90\x41\x16\x75\x4d\x37\x0c\x40\xd7\x00\xcd\xb6\x64\xc4\x6a\x91\xdd\x84\xa3\x58\xb9\xd2\x38\x14\x43\xe6\x0f\x2c\x3f\x56\x40\x26\x1b\x6b\x85\x8b\xa8\xf8\x28\xb0\x97\x1f\x41\x22\xb2\x02\x88\xa2\x6b\xa2\x09\x0b\xa1\x4f\xd2\x76\x36\x0c\xc6\x86\x79\xcd\x84\x19\xae\x19\xc6\xd4\xdc\x7b\x66\x14\xc0\x6d\xf5\xe5\xc0\x51\x0e\x2c\xb6\x86\xde\x0e\xbd\x75\xe5\x21\x0a\x21\x55\x62\x58\x9b\x28\xc9\xcc\xc7\xd2\x72\xb9\x8b\xd4\xbf\x93\x49\x5e\xfe\x4f\xc5\xb7\x8d\xef\xec\xfb\xca\xa9\xfe\x12\x6b\xad\x30\xe8\x9b\x3a\x38\x9b\x42\x56\xf6\xa4\x8a\x76\xc3\x45\xde\x5a\x36\xa1\x44\x9f\x08\x34\x5b\x9a\x5e\x6a\x00\x1d\xa1\xff\x9c\xd4\x33\x70\x93\x48\xe9\xae\xfb\xc7\x8b\xa5\x2d\x3a\xb3\xb4\x69\x86\x93\x5e\xba\x8e\xcf\x81\xed\xc4\x3c\x5b\x2e\x3b\x5e\xb3\x8d\x9a\x16\x5e\x9e\x7f\x72\xf6\x17\x60\x54\x63\xbe\xdb\xa9\x73\xeb\xfd\xcd\xf2\xb0\x88\x9c\x71\x41\x2f\x8f\x85\x0c\x7a\x3b\x55\x18\xec\xd8\x9d\x2e\x25\xc0\xc1\xc3\x0f\x08\x5a\x0f\xfe\x54\x0e\xf9\xc0\xe8\x8f\xc7\xec\x4a\xf1\x94\x8a\x4e\x6f\x7a\x6e\x25\x6b\x30\x7a\x11\x27\xb7\x1b\xa6\x86\xef\xea\xdc\xa0\xe4\x86\x09\x47\xcf\x67\x4f\xce\xd6\xca\xf7\x31\x0c\xcb\xaa\x8d\x90\x47\xda\xed\x30\xfd\x55\x85\xd4\x1d\xde\xae\x4d\xf2\xfe\xd4\xb6\x22\x80\x32\xc3\xe4\xae\x23\x80\xe8\x7e\xc6\xcd\x72\xe4\xd7\x4b\x8b\x4c\x38\x13\xfb\x04\x33\x89\x39\x1e\x9c\x13\xf7\xd3\x3c\x3a\xab\x5a\x78\xfc\x4c\x6a\x63\x4c\x61\xa7\x0f\x02\xa9\x40\x54\x8d\xa1\x77\xc6\x5d\xf6\xab\x17\xcd\x96\x83\xf3\x7e\xa8\x21\xc7\x40\x88\x9d\x82\xe8\x8c\x83\x4e\x7d\x5d\xc1\x16\x62\xea\x78\xb1\x3c\x6a\x4b\x62\x18\xd3\x17\x84\x21\x9a\x47\x67\x59\x5b\x1a\x56\x21\x65\x25\xcd\x68\x93\x8b\x22\xbd\xb1\xf8\xc5\xa7\xf1\x70\x1a\xfe\xb9\x61\x88\x8e\x2e\x0e\xc0\xc8\x38\xcd\x62\x0c\xb7\xdd\x8a\x14\x93\xa0\x2c\xd5\x6b\x54\x51\x25\xe4\x70\x0c\x08\x89\xfa\x26\x44\xe6\x44\xa3\xaf\x53\x1d\x1c\xd6\xbc\x95\xe5\xdf\x91\x75\xf1\x37\xf2\x84\x08\xcb\x69\x9c\x7a\xe6\x6f\x65\xd1\xd2\x93\x0f\xac\x57\xca\x8a\x60\xe6\x31\x1a\x40\x78\x48\x8c\x9e\xa4\x04\x94\x8a\x9d\xeb\xeb\x9d\x5e\x10"}, +{{0xa1,0xe4,0xfc,0xfd,0xe0,0x44,0xf1,0xbb,0x0e,0x7b,0xbc,0x63,0x1a,0x83,0x1a,0x8d,0x07,0xe9,0x0a,0xe0,0x8a,0x96,0x6a,0xd6,0x27,0xb6,0x20,0xb1,0xe2,0x8c,0x42,0xcf,},{0x25,0x56,0x0f,0x31,0x16,0x8b,0xd4,0xb7,0x25,0x52,0xed,0xed,0xd0,0x8b,0xb6,0xbf,0x79,0xa9,0x40,0x63,0xc1,0xf1,0xe1,0xd3,0x04,0x86,0x9d,0xd1,0xce,0x04,0x9b,0x95,},{0xc8,0x00,0x15,0x27,0xbd,0x90,0x2c,0x15,0xc3,0xdd,0x5a,0xe1,0x81,0x80,0x52,0x5b,0x5e,0x82,0x02,0xbe,0x66,0x71,0x1f,0x82,0x88,0x5c,0x82,0x22,0xa1,0x5f,0x06,0x00,0x92,0xa2,0xa6,0xe2,0xf7,0xd7,0xe9,0x80,0x31,0x12,0x09,0x19,0x1b,0x32,0xb8,0xad,0xe4,0x8d,0x3e,0xa9,0x8c,0xf2,0x45,0xf0,0xfa,0xd6,0x2c,0x00,0x9c,0x5a,0x71,0x08,},"\x8c\x14\x54\xd4\xe0\x8a\x14\x01\x64\x6b\xf7\xa8\x85\x9e\x8a\x14\x5e\x85\xee\xeb\x40\xdb\x38\xff\x01\x69\x70\x96\x41\x21\x2c\x81\xb6\x73\x90\x74\x9c\x01\xa7\x98\x07\xf3\xcc\xad\xbb\xd2\x25\x6f\x36\xff\xc1\x80\xcf\x9b\xa4\x4b\xf4\xa7\x61\x2d\x44\x1c\x23\xb2\xe2\x5d\x33\xc4\x8a\x73\xe1\x6c\xe3\x57\x56\x27\x58\xad\xb0\x05\x53\xc3\x14\x2f\xb8\x17\x6b\x6a\xe8\xfb\x61\x0a\x60\xf9\x23\xb0\x91\x18\x14\xb1\x0f\x56\x79\x93\x6c\x36\x77\xb7\x0e\x84\x6e\x21\x8f\x58\x75\x67\xf2\x01\x9c\x7d\x28\x2a\x10\x7f\x3c\xc8\x47\x63\xad\xae\xc8\x89\x93\xc0\xcc\x50\x03\xe7\x7a\xf6\x0d\x67\xdb\x53\xf8\xcb\x72\x7a\xa6\x67\x2d\xe0\x04\x49\x8c\x3b\x3e\x22\x2a\xa7\x08\x2d\x91\xf9\x8a\x1a\x06\x83\x74\xc5\x10\xff\x53\xa5\xe5\x59\xcb\xe2\xd6\xc7\xc3\x44\x2d\x72\x38\x90\x7c\x81\x1d\x58\xaa\x7f\x5a\x46\xb8\x31\x12\x44\xf0\xdb\xe1\xb9\xc0\xe9\x44\xdd\xa1\xd8\x01\x08\x64\x94\x9c\x59\x39\x6c\x6b\x34\x6a\x11\xf3\xaa\x86\x6d\x6b\xce\xad\xfc\x90\x90\x38\xd2\x2e\xfb\xc8\xf1\xda\xc8\x10\xa9\xf2\xfa\xfc\xce\x7c\x03\x89\xeb\x0a\x56\xc0\xf6\x8c\xae\x24\xae\x3d\xdb\xdf\xf7\x11\x6d\x2f\xad\xeb\x9b\x0e\x75\x09\x53\x6f\xdc\x3b\x83\xe7\x13\x54\xda\x6a\x1a\xed\x16\x88\x74\x90\xdc\x2f\x4d\xf5\x7b\xba\xa7\x24\x45\x28\xfa\x30\x94\xb9\x9e\x86\x75\x81\xac\xef\x90\x62\x70\xb2\xcf\x4d\xed\xa6\xb8\xfd\x9d\xbb\x79\xad\xd7\xbe\xa8\xf8\x6f\xcb\x1f\x64\xdf\xd5\x0e\x38\x5b\x42\x09\xec\x0b\x1a\x9f\x6d\x2e\x51\x90\x68\x29\x7a\x2b\x5c\x40\x5c\x21\x6b\x4a\x2e\xd9\x83\xff\x69\xc5\x9b\x53\x0e\xff\xa6\x0c\x03\x67\x05\x12\x67\xdd\x2b\xbd\x1e\x86\xa9\xab\x5a\x11\x4d\xd4\xf6\x9b\x54\x0b\xfa\xbf\xe9\x7c\x04\x03\xb8\xfc\xbb\x27\x62\x57\x61\xed\xa3\xe2\xad\x8e\x62\x5c\xfe\x4b\x61\x5b\x70\x25\x53\x1a\x49\x89\x18\xc2\x4e\x02\xa0\x0e\x79\x7b\xba\xfd\x14\xf9\xd3\xf6\x82\x7e\x39\x00\x63\xc4\x36\x08\x06\x88\xd0\x37\xa6\xe2\x99\x3c\x56\xd3\xa8\xe9\x5f\x37\x5c\x10\x04\x0b\xf0\x4f\x03\x0c\x97\x26\x23\xd9\xe3\x80\x1c\x13\xb4\xec\x8d\x01\xcf\x18\x38\x55\xf5\x93\x5f\x10\xdd\xb2\xc5\x4c\x51\xc8\x0c\xbe\xd0\xc2\x4d\xb5\x6e\x1e\xd1\x48\x93\x1d\x89\x16\x1c\x5e\xa3\x7c\x2f\x97\x87\xf8\x8e\xf7\x33\x0e\x5d\xcd\x0e\x43\xd8\x1b\xfc\x8b\xf2\x3d\xdf\x79\x83\xcc\x1d\x73\x38\x43\xa3\x3c\xcb\x39\x5d\xfc"}, +{{0xbe,0xd1,0xbb,0xca,0xe1,0x86,0x43,0xd6,0xf6,0xaa,0xc3,0x4f,0x3d,0x9b,0x6a,0x14,0x78,0x39,0x4d,0x02,0xb9,0x31,0xcf,0xf0,0x06,0xd8,0x5f,0x21,0xb7,0xdb,0xc7,0x47,},{0x4f,0x52,0x8b,0x38,0x18,0x5a,0x42,0x4c,0x6f,0xde,0xce,0x46,0x51,0x1a,0x0c,0x29,0xb7,0xc0,0x4b,0x32,0xeb,0x04,0x83,0xab,0xb5,0x2d,0x5f,0x8e,0xb6,0xb3,0x52,0xeb,},{0x0f,0xc9,0x9d,0xd3,0xb9,0xa0,0xe8,0xb1,0xfc,0x6e,0x63,0x5a,0xf5,0xc6,0x40,0x06,0xb6,0x72,0x00,0xfe,0x95,0x8f,0x53,0xcc,0xe1,0xb9,0xb0,0x91,0xa4,0xe7,0x06,0x69,0xb5,0x93,0xf1,0x55,0x94,0xbc,0x08,0x42,0xe5,0x57,0x62,0x59,0xf9,0xa6,0x85,0x9a,0x0d,0xb2,0x2d,0x74,0x0f,0x9f,0x80,0x24,0xb5,0xba,0xf1,0xef,0x6f,0x95,0x8c,0x05,},"\xff\x7c\x64\x13\xe6\x18\xa0\x56\xde\x40\x1e\xe1\x0c\x40\xad\xe3\xd7\xc0\xe6\x86\x14\x95\xd9\x7c\x26\x89\xec\x6a\xbb\x69\xdd\x2a\xe7\x01\xfd\xca\xc8\xf0\x83\x31\xea\x5c\x5f\x5d\x80\x5b\x57\x89\xee\x5e\x24\x1f\xf4\xac\x8b\x96\x0f\x4f\x2b\x9f\xef\x6a\x72\x7f\xad\x86\xdc\xd4\x32\xde\x9f\xad\x6b\xa4\x5e\x00\xaa\x36\x87\xb0\xce\xeb\x2c\x0d\x43\x0b\x7d\x5f\xde\x63\xb4\xf6\xb9\x82\xc4\xf9\xe0\x3c\x43\x0a\xba\xd9\x04\x4d\x06\xdc\x49\xe8\x9d\xf4\x81\x40\x5d\x8f\xeb\xbb\x06\x53\xe9\x68\x69\x48\xaa\xd2\xd9\x07\x25\x44\xdf\x94\x24\xfd\x48\x7f\x4e\x24\xba\x7f\x24\x55\xdd\xec\x41\x05\x82\x8c\x39\x81\xbd\xdb\xb1\xb7\xfb\xdb\xac\x15\x59\x03\xe9\x60\xfc\xd9\x4c\x07\x16\xe7\x36\xf5\x19\x86\x7f\xbc\x52\xc5\x12\x60\xf5\x71\xd7\xed\xcb\x08\x1a\x23\x55\x0a\xd8\xc7\x0b\xb2\x68\x86\x4a\xb2\x76\xaa\x2c\xc2\xdb\xf6\x23\x83\xbb\x66\x03\x0e\xbe\x94\x35\x41\x74\xcc\xec\x2d\x2a\x90\x75\x78\x55\x64\x44\x50\x7c\xbf\x84\x88\xbb\x23\xc6\x24\x23\xa3\xa9\x8d\xa7\xcc\x96\x8f\x59\x9d\x3d\xc8\x4d\xca\x3a\xfa\xd7\xf1\x4e\xc3\x06\xe1\xdb\x53\x41\x43\x21\x6a\xa2\x2a\xd1\x80\x74\xc7\x19\x57\x08\x05\xea\x46\xbc\x86\xb7\x1a\x8f\xf5\x8e\x41\xe7\x3c\xb2\x9a\xd5\x75\x0f\xcf\xc9\xa1\xc5\x42\x92\xb6\x4b\x47\xec\x95\x38\xf5\x38\x16\xe3\x6e\xd0\xd0\xc1\xae\x5e\xad\x06\xd4\x77\xaa\x97\x5e\xce\xba\xf6\x2d\x90\x23\xb7\x7e\x50\xe7\xb6\xd4\xab\xda\xa4\x85\xea\x34\xec\x76\x6b\xeb\x1d\x9b\xa0\x3c\x9c\x06\x71\x86\xe2\xe3\x82\x66\xc6\xe2\x53\x1e\x97\x48\x02\x14\x63\x8a\x2b\xb3\x14\x31\xac\x20\x86\x79\x71\x55\xfc\x77\x5b\x3a\xad\x8d\x5a\x0b\x90\x4c\x38\x1e\xdd\x0c\x6b\xc2\x3c\x66\xa1\x90\x49\x55\xed\x45\x0a\x9c\xbd\x16\x45\x9c\x32\xf5\xca\x35\x4b\xbc\x2d\xa7\xb1\xa4\xd8\x14\xf1\xb8\x71\x0a\xad\xb2\xcc\xc4\xf3\x97\x75\x8b\x7e\x9d\x91\xf3\xa9\x1e\x58\x25\xab\x86\x82\xff\x5e\x41\x70\x2e\x07\x84\x1a\xc7\x69\x8c\x3d\xa9\xf5\x58\xed\xd0\x1f\x86\xce\x2c\x50\x6b\xf4\xc2\x14\x9a\xc9\xc1\x95\xa5\x9c\x7d\xd7\xd4\xec\xf9\x3c\x90\xb4\x42\x3b\x43\x50\x58\x8d\x41\x67\x2c\xed\xc8\x51\x0a\x7a\xd5\x3b\x4b\x7e\xdc\xaf\x23\xe4\x3e\x05\x66\x9d\x27\xa1\xfe\x97\xb7\x87\x30\xd3\xfc\x06\x0b\xd4\xed\xd9\x87\x2c\xff\xb9\x62\x85\x35\x1b\xef\x14\x8e\xf7\x83\xab\x39\x21\x16\xbd\x7b\x90\x7b\xad"}, +{{0xc7,0x18,0x82,0x3f,0x43,0xdb,0x22,0x17,0xc6,0x6a,0xb2,0x89,0x97,0x04,0x16,0x5d,0x20,0x85,0x73,0xde,0x60,0xf3,0x3b,0xc0,0xb9,0x33,0x8d,0x88,0x0f,0x19,0x3f,0xb5,},{0x29,0x40,0xb8,0x79,0xb6,0x3f,0x2c,0xb1,0xf6,0xe3,0xef,0x9c,0x9d,0x33,0x3b,0xa9,0x17,0x70,0xfe,0x18,0xcc,0x5a,0x34,0x7f,0xdf,0x12,0xb0,0xef,0xc5,0xca,0x2e,0xc9,},{0x4c,0x9c,0xdb,0x1a,0xd4,0x65,0x09,0x56,0x0d,0x87,0x1d,0x30,0x89,0xaf,0xb8,0x73,0x46,0x48,0x20,0x1b,0x10,0xac,0xc9,0x53,0xe8,0xb6,0x1f,0x2c,0xce,0x2d,0xba,0xe0,0xfb,0x9b,0x86,0x8a,0xc9,0x57,0x43,0x2b,0x72,0x22,0xdb,0xf7,0xe4,0xcf,0x0b,0xc7,0x53,0x09,0xbe,0xa3,0x60,0xb2,0x63,0xab,0xbd,0xe1,0x88,0x53,0x2d,0xda,0x25,0x04,},"\x05\x0e\x68\x77\xf6\x5e\xc7\x26\xee\xc7\x01\x86\x3f\xab\x14\x0b\x99\x4a\xa1\xe9\x2a\x48\x7d\xb1\xa1\x87\x01\x31\x20\x57\xdb\x44\xbf\xde\x70\x91\x1e\xc2\x6e\xaa\x28\x63\x2d\x03\x79\x4d\x54\x5d\xfc\xb2\xae\xd4\x34\x0c\xab\x7d\x09\x25\x95\xcd\x59\xed\x23\x99\x40\x43\xf5\x0b\xa6\x96\xe9\x80\x2b\xd6\x49\x90\x12\x13\x97\x28\x64\x57\xae\x69\xd7\x6c\xb8\xe3\x4d\x7c\x1a\xb2\x45\xcb\x07\xb1\xb4\x08\xf2\xbb\xbf\xdf\x33\xa1\xbd\xd5\x59\x63\x67\x02\xc9\x18\xf9\x82\xc2\xac\x02\x21\xf7\xf9\x4d\xb9\x1e\xde\xfc\xe2\x81\x18\x25\x9f\x89\xd9\x94\xda\xd5\xbb\x01\x3c\x67\x8c\x1c\x33\x8b\x65\x39\x6b\x15\xe8\x89\x9c\x16\x99\x21\xf2\x78\x85\x9c\xe0\xc8\x56\xd8\x89\xb8\xc6\x34\x18\xeb\xc5\x73\xd2\xd6\x25\xd5\xb5\x93\x88\x39\xf2\xb1\x69\xb6\x91\x6d\x8e\x40\xdd\xe7\x0d\x3b\x72\x88\x7a\xd2\x47\x8e\xf6\xfb\x12\x84\xfa\x0e\x4f\xc5\x24\xe3\xc6\xfa\x1d\xd2\x2b\xa6\xb8\x1d\xef\x82\x79\xf3\x82\xbc\xb4\x50\x48\x85\x1b\x17\xcd\x65\x9d\x59\x40\x9f\x57\x1f\xa8\xa9\x20\xa2\x09\x34\xd9\xdb\xe1\x02\x2d\x63\x58\x40\x96\x54\x00\x24\x0f\x87\x0a\xce\xff\xd5\xdb\x7c\x7d\xf0\x8a\xf8\x9e\x47\xe1\xb9\xe2\x0b\xb9\x9f\x96\xab\x07\x3e\xdf\x53\x69\x4c\x74\x82\x89\x0e\x36\x31\x34\x02\x17\xe6\x87\xab\x27\xc9\x84\xb6\x08\x25\x16\x94\x57\xd4\x35\xa5\x40\x9a\xd8\xe4\x2d\xa0\xaa\x63\xe2\x0c\x2b\xc6\x7b\xd8\xb9\xa2\x67\xf3\x96\x73\xa7\x7f\x7f\x31\x36\xdc\x5c\xb2\xd2\x49\x48\xdb\xe7\xbc\xd7\x12\x93\x18\xc6\x8c\x6f\xe9\x5d\xd4\xdd\x4f\xe9\x42\x28\x68\x31\xea\x53\x35\x2f\xbb\x25\x2a\x12\x88\xbc\xd8\x38\x92\x13\x56\x78\x5d\x07\x21\x34\xcb\x82\x0f\x62\x79\xcc\x71\x46\x1f\x43\x1b\xe9\xd3\x01\x47\x24\x32\x1c\x92\xfd\xc5\x76\x32\x01\x37\x70\x5c\xff\xb2\xc2\x36\x64\xb7\x05\xe9\xbe\x60\xae\x1a\x19\x0f\x3e\x34\x84\xf7\x00\x58\xe7\x02\x40\x7b\x05\x6d\x7f\xe5\xd3\x1c\xee\x9c\x2a\x6a\xc6\xea\xda\x35\x16\xab\xc5\x51\x72\x56\xdf\x12\x43\x78\x0a\x03\xbb\x00\xba\x00\xce\x24\x80\x76\xee\xca\x6f\xee\x91\xd5\xef\x9e\xb9\x07\xb8\x01\xaf\x09\x7f\x3e\x9e\xb2\x56\xbd\xcd\xe8\x1e\xfe\x4b\xaf\x81\x89\xb0\x39\x9e\x36\xf1\xea\xa3\xab\x62\x66\x17\xcf\x3b\x47\xdd\x89\xca\xf6\x9c\x64\xc5\xb8\xf6\x8b\xd9\x17\xfe\x03\xe4\x66\x85\x38\x46\x0a\x1b\xe8\x8d\x9a\x84\x6c\xef\x39\x93\x46\x27\xd4\x74\x73\x4f"}, +{{0x25,0x43,0xd1,0x66,0xc9,0xf5,0xf7,0x42,0x7f,0xf3,0x03,0x4f,0xfa,0x81,0x03,0xcb,0x11,0x7b,0xf4,0x72,0x33,0x1a,0x73,0xd9,0xa2,0xf1,0xbc,0x0a,0x02,0xa6,0xff,0x1b,},{0x42,0x67,0x8c,0xf3,0x85,0x70,0x21,0xaa,0x55,0x67,0x70,0x6d,0xb0,0x31,0xe7,0x92,0x71,0x5c,0xca,0xf8,0xab,0xb0,0x2a,0x04,0x2b,0xad,0x17,0xdb,0x3d,0x5f,0xa1,0x03,},{0x20,0xea,0x93,0x68,0xa2,0xcc,0xd0,0x8b,0xf9,0xcb,0xf4,0x8d,0x4a,0x2f,0x7d,0x03,0xf0,0xdb,0x08,0xa5,0x4b,0x87,0x67,0x9c,0xda,0x03,0xe2,0x96,0xaf,0x9e,0xf3,0x78,0xbe,0x9b,0x8f,0x04,0xb4,0x06,0x5b,0x00,0x9d,0xa6,0xdb,0x01,0x6f,0x3d,0xf9,0xdb,0x64,0x82,0x58,0x73,0xe2,0xfb,0x4d,0xe3,0x04,0x49,0x91,0x5c,0xd7,0x3c,0x46,0x09,},"\x74\x6d\x7a\xbf\x0b\xfb\x26\x62\xc2\x5a\xb5\xc5\xe4\x61\x2c\x30\x6f\x16\xd1\x3e\x44\xd0\xdb\x39\x4a\x00\x15\x67\x6c\xe6\x09\x78\x4f\x03\x23\xda\x1d\xfa\x94\xd2\xb2\xf1\xf6\xe0\x24\x44\xa9\x36\xd0\x19\xb1\x43\x02\x1f\x73\xc7\x9d\xf9\x30\x9e\x7b\xdf\xf3\x9d\xae\xec\x4c\xac\xa0\x0c\xba\x4e\xf3\x1c\x83\x10\xc1\xa0\x8e\xf4\xb3\x6f\x81\xc3\x77\x84\x6b\x5b\x90\xac\xd4\x11\xaa\x67\x1e\xd7\xaf\x27\x8a\x24\x22\x9b\x78\x93\xc1\xb4\x15\xd7\x98\x88\xd7\x63\x7f\x5c\xb5\xc9\xc6\xc6\x31\xae\x5f\xfa\x29\xf1\x34\x0e\x44\x40\x96\xab\x53\x36\x17\xfd\xcb\x80\xff\x81\xda\x0a\x7c\x6c\x14\x2e\xe0\xfe\x5e\xa8\x2f\x68\xcc\x3e\xa3\x8b\x56\xf2\x72\xb0\xd8\x0f\xd5\xf4\xf5\x5c\xa9\x34\x8c\x16\x18\x81\x43\x58\x13\xc3\xfa\x9f\xff\x66\xa2\xee\x6d\x5b\xd3\xed\xba\x0d\x2f\x9a\xa7\x4b\x1c\x44\xbf\xd0\xe6\x46\x78\xd3\x71\x51\x24\x96\x3a\xc5\x75\xff\xb0\x9e\xe1\x64\x37\xda\x48\x4b\x3b\xa5\x8e\x5a\xeb\x8e\xd8\xc5\xc0\xf4\x7b\x59\x90\x8f\xe5\x80\xf3\x7e\xc1\xde\x26\x6b\x29\x5d\x6b\xe8\x5e\x62\x35\x8e\x9b\xbd\xc7\x89\x64\xfb\x83\x7e\xea\x29\xfd\xb7\xde\x86\xcc\x56\xf4\x8b\xd9\xa3\xe6\xe2\xbe\x51\xd8\xa1\xdc\xff\x3c\xa4\xd5\x6e\xa9\x34\xc6\x82\x77\x2b\xca\xfb\x51\x49\x7b\xe5\xd0\xf2\xa2\x3d\xd4\x97\x0c\x02\xc4\x4c\x09\xad\x89\x7b\x42\x41\xac\xd7\xd6\xab\x12\xd8\xf0\x0c\x9a\xad\xc3\x34\xb4\x31\xfe\xc5\xbb\x69\xa2\x85\xb7\x55\x0a\x63\x9e\xce\x96\x95\x26\x82\xb7\x33\x4b\x68\xc6\x51\x52\xe8\x93\xb1\xc8\x10\x0c\x69\x4d\x8c\x5c\xfe\x26\xac\x03\xc1\xf3\x91\x4e\x65\xc8\x4f\x0e\x77\x72\x90\xc7\x6f\x6a\xcc\xe3\x40\xbf\xf6\x6d\xa7\x22\x0f\x73\x17\x5e\x94\xaf\x52\xf9\xf1\x9e\x61\xf8\x0d\xc1\xf3\x57\x16\xb3\xf4\x8d\xfa\x50\x25\xc9\xeb\xef\x73\x82\xe0\x55\x83\x0f\x5b\xbf\x15\xc6\xf6\xa9\x50\x32\x90\x9c\x89\x2c\x0f\x89\xc8\xc1\x5f\xc3\xea\x40\xa2\x0e\xe1\xa4\x52\x9b\x52\x19\x51\xdf\x44\xd9\xd7\x9d\x74\xe0\xc4\xc2\xe0\xfe\xd8\x49\xb8\x78\x52\x06\xdb\xe6\x2b\xfa\x2c\xa2\x10\x87\xa9\x12\xe9\xb1\x84\x55\x16\x59\xcd\x8a\x58\x7e\x95\xb0\x43\x17\x19\x25\x96\xbb\x0b\x7f\xc9\xf7\xbb\xb6\xee\x04\x9c\x8b\x02\xfd\xd7\x58\xb4\xe7\x98\x82\x07\x3b\x71\xea\xab\x18\xaa\x29\x37\x01\xc1\x7d\x55\xf9\xec\x46\xc5\x2d\xe1\xe8\x86\xb6\x75\x0f\xb0\xfb\xcd\x64\xf4\x56\x8a\x21\x0a\xe4\x51\xe9"}, +{{0x85,0xe0,0xa8,0x0f,0x3b,0x30,0xc2,0x01,0x99,0xd9,0xc1,0xec,0x66,0x2e,0x39,0x2f,0xdf,0x15,0x46,0x37,0x73,0x43,0xf1,0x24,0x71,0xdb,0x2a,0x03,0x10,0xa7,0x05,0xbd,},{0x54,0x0a,0x3a,0x1d,0x83,0x67,0x2e,0x49,0x50,0x34,0xcf,0xf4,0x08,0xe1,0xfb,0xe8,0x2e,0x53,0x8f,0x09,0x17,0xe8,0xa1,0xc7,0xd1,0x7a,0xab,0x58,0xe0,0x43,0xd3,0xc6,},{0x18,0x5e,0xf2,0x24,0x6a,0xba,0x2b,0x1a,0x56,0x80,0x32,0xc7,0xdf,0x93,0xc6,0x67,0x79,0x9b,0x8a,0x52,0x1a,0x6f,0x97,0x32,0x1e,0xad,0x58,0x66,0xb4,0xcb,0x9c,0x65,0xb6,0x4a,0x1c,0x40,0xb9,0xb6,0xa9,0x10,0xe7,0x42,0xdc,0x32,0xa7,0xe6,0x6d,0x11,0xea,0x45,0xdb,0xea,0xac,0xae,0x9f,0x09,0x51,0x1b,0x81,0x01,0xf8,0xaf,0x0c,0x0c,},"\xd2\x80\x2f\x15\x96\xf8\x38\x3b\x64\xed\xbd\xc5\x94\x06\x0b\xff\x0e\x70\x13\xd5\xb7\xc8\x5d\x83\x0f\xae\x11\xae\xb3\x4d\xd5\x94\x95\x9d\xa6\x24\xe0\x44\x47\x4c\x54\x09\xc0\x05\x96\x73\xbd\xc6\x1a\x67\x1e\xf5\xb0\xb8\xa2\x6f\x30\x10\x0b\x3b\x73\x96\x8d\x8e\x4d\x83\xa7\x2f\x25\xb5\x13\x44\x8d\x2f\x6b\x6a\x44\x75\xfd\xf8\x9e\x31\xca\x92\x68\xa3\x07\x05\xaf\x3f\x64\x9e\x3f\xe0\x1d\xde\x0c\xf4\xb2\x9e\xc2\xda\x54\x36\x44\x4a\xf0\x91\xd6\x27\x30\xac\xd4\xca\xb6\x08\xf0\xdf\x26\xf0\x88\xc6\xb9\xb9\x67\x37\x94\xf0\x74\x7d\xab\x2c\xe1\x90\xf9\x05\x92\x00\x9f\xdc\xe5\x46\x4b\x36\x61\xb7\xe8\x62\x0b\xad\x65\x50\x9a\x6c\x75\x2b\x72\x7a\x8d\xc8\xd3\xef\xa5\x84\xfd\xe0\x27\x2c\x45\x1d\x65\xa9\x3b\xec\xe4\xf5\x9d\x87\xdc\x6f\xbe\xb4\x51\x40\x1e\x3e\x2e\x00\x3c\x6a\xca\x7b\x3d\x3f\x92\x71\x91\x50\xc6\x77\x8f\x01\x5a\xff\x2a\x59\xbf\xbf\x2e\x91\xb2\x1b\x0a\xd6\x87\x75\x36\xeb\x54\x56\x70\x59\xf5\x87\xf5\x4d\x4e\x2a\x6f\xe1\xfd\xcd\xd6\xa7\xfd\xcb\x85\x15\x57\x5b\xcc\x37\x05\xd7\x78\x59\x35\x2f\xa0\xb0\x44\x16\x6e\x3c\x31\x88\x46\xa5\xdf\x33\x56\x30\x03\xcb\x20\xbc\x94\x2d\x30\x39\x10\x93\xe8\xd5\x83\xe8\xe6\x4d\xec\x57\x0e\xe1\xc4\x13\x87\x62\xf6\x48\x38\x98\xd3\x2e\x20\x32\xbd\xe9\xbb\xe0\x7e\xc2\xc3\xeb\x47\xd9\x68\x76\xf0\xfc\x0f\x02\x4d\x75\x3c\xeb\x34\xff\x84\x80\xb4\xcf\x57\x62\x30\xbb\x82\x63\xdd\x80\xee\xac\x66\x2e\xba\x31\xd8\xa6\x1f\x30\x9e\x17\x5f\x4c\x01\x43\xe2\x8a\x85\x2b\x1c\x30\x61\xce\x78\xef\xbd\x16\xa2\x87\x3d\xd2\x81\x98\xa4\x6e\xc0\xa8\x00\xb3\x0d\xc8\xa9\x3b\x8d\xbb\x81\xa7\x30\xde\x45\x0b\x86\x4d\xea\x76\x80\xe5\x09\xd8\x00\xe8\x23\x29\xc2\x61\xb0\x7e\x72\xaa\x80\xee\x16\xec\x37\x5d\xdb\xbb\x6f\xe3\xd8\xd4\x7b\x0e\x3c\x5a\x9f\x23\xc4\xd2\x0b\x72\x4c\x1d\xf5\x98\x35\xd8\x30\xdd\x22\xd1\x04\x03\xd8\xf1\x5c\x10\x2c\x4b\x37\x69\xc4\x16\x66\xc3\xab\x8c\x7e\x80\xb9\x40\xd0\xbb\xb5\x86\x52\xd1\x0a\x3f\xfe\x8d\x44\xdf\x10\x12\xa3\xdd\xc4\xe1\xc5\x18\xd4\x90\x19\xf7\xc5\xd3\xd9\xf9\x5e\xd9\x3a\x31\x97\x46\xd1\xe5\x43\xff\xa6\x9e\xdb\x49\xbb\x34\x39\xf8\xa3\x25\xac\x6a\x0c\xb4\xed\xd6\x5b\xa6\x00\x80\xa0\x44\x7c\x67\x4f\xaa\x72\xd8\xae\xbd\xb5\xd2\x54\x4f\x2f\x2d\x84\x7c\x72\xc2\xdf\xa6\x05\x7a\x69\x0a\xdc\x5c\x44\x1a"}, +{{0x82,0xa2,0xc6,0x49,0x3f,0x11,0xba,0x80,0xe4,0xb8,0xb3,0xb4,0x38,0x41,0xbe,0x97,0x0e,0x2a,0x10,0xa9,0x4d,0x22,0x49,0xd8,0xac,0x6f,0x54,0x14,0xcf,0x5a,0x3c,0xb5,},{0x4c,0x2e,0xe0,0x1c,0xde,0xa0,0x7d,0xb3,0x63,0x5f,0x5d,0x4c,0x10,0x82,0xb9,0x2f,0x29,0x8d,0xeb,0x17,0xd0,0xf9,0x05,0xdf,0x71,0xb6,0x6f,0xb2,0x27,0x4e,0xae,0x99,},{0x68,0xa9,0x1d,0x4f,0x8d,0x24,0x1c,0x1d,0xef,0xbd,0x5c,0xa9,0xe9,0xe1,0xed,0x82,0x74,0x41,0x95,0x06,0x75,0x1c,0x96,0x79,0x47,0xb1,0x0d,0x50,0x11,0x8b,0xbf,0xab,0xc7,0x65,0xff,0xd7,0xb3,0x1a,0x01,0x67,0xc4,0xfd,0x8b,0x11,0x75,0x33,0x24,0x12,0xdf,0x19,0xd8,0xaa,0x1a,0x90,0x95,0x90,0x86,0x13,0x20,0x92,0x3d,0xbc,0xb2,0x04,},"\x09\x85\x4d\x13\x68\x49\x50\x41\x9e\x0b\xb1\x64\x64\xe0\x99\x88\x90\x5c\x02\x17\x18\x3a\xa1\xe4\x8a\xdb\x14\x7b\xfc\xc2\xeb\x57\xc2\x30\x0b\x0d\xfc\x39\xd4\x89\x66\x55\xa5\x7a\xe2\x04\x15\x40\x8b\xb5\xf2\xc2\x38\x01\x39\x55\xf0\xa4\xfc\x78\x2e\x0c\x99\x3f\xe4\x2c\xb0\x8c\xd8\xcf\x41\x5c\xcb\xd6\xcf\x1c\xee\x2e\x80\x97\xf0\x4e\x8f\x09\xae\x5d\xa5\xf4\x15\xb1\x6c\x2c\xb3\x0c\xb2\xab\x66\x52\xba\x50\xeb\xbc\xae\x4a\x59\xe3\x1f\xe1\x1e\x7e\xf3\x69\x9c\xa9\x0a\xaf\xa5\x86\xbb\x24\x2c\x89\xcd\x2e\x33\x2b\x2b\xfa\x2f\x81\x42\xac\xca\xf4\x36\xf8\x9b\x64\x53\xbb\x48\x05\xa1\xe7\xf3\xab\x62\x70\xf0\xda\xf8\x93\x89\xe7\x17\xd1\xb7\x01\x75\xec\x57\x07\xc8\xf5\x12\xc4\x0a\xb9\x24\xc4\x57\xe9\xf0\x91\x47\x91\x75\x0d\xc2\x92\xbb\x27\xd6\xf6\x3b\xa8\xcc\xf5\x4b\x90\xd3\xeb\xa7\xf1\x9e\xb3\x00\xd9\xeb\x8f\x3b\x72\x03\x2b\xa9\x30\x37\xf5\x52\xb4\x09\xb5\x80\xa5\xf6\x51\x16\xfa\xff\xe0\xfd\xfd\xc6\xdb\x38\x81\x38\x6c\x3c\xbc\x16\xb6\x7e\xb2\x57\x63\xd7\xae\x3a\xac\x0b\x85\xaa\x1e\x9a\xa2\x2e\x49\x59\x60\x9d\x43\x81\xe4\xb6\xd7\x15\x9f\xf3\xe3\xb2\xd3\x7b\x64\x0f\x88\xcf\xbe\x4f\x8a\x77\xf8\x01\x64\x57\x22\x8b\xa6\xd3\xaf\x5c\x4e\x33\x12\x5d\x48\xbc\xfc\xf3\x67\x8c\x16\x3b\x69\x8e\x52\xe8\x56\x17\xab\x1a\x75\xff\x20\xc6\x90\xab\x07\x15\x5e\xe7\x57\x59\x85\x78\x07\x2d\x4a\x09\xdf\xc6\xc6\xc0\x94\xec\x04\x85\x67\xd5\x13\xce\x2b\x18\x34\xe1\x63\xdf\x15\x45\x31\x9d\x80\x61\xe0\xe5\x7f\x58\xef\x04\x1b\x7b\xff\xc4\x96\x6a\xc1\x66\x03\x31\xb9\x7a\xbb\xc9\x7b\xe2\x1a\xe2\xbc\x58\xc6\xc3\x27\x4a\x8a\xda\xd5\xfd\x2c\x3b\xc1\x6b\x92\xe1\xf8\xde\x87\x7b\x6a\x26\xf0\xc6\xab\x71\x62\xe8\xaa\xb9\x3a\xf8\xd8\x59\x18\xc1\x3d\x3e\x23\x5a\x27\x37\x48\xc6\x2f\x0d\x22\xcb\x1c\x93\xe1\x34\xa4\x95\xb1\xb5\xef\x8f\x1a\x11\x34\x51\x2d\x53\xb7\xa2\x11\x26\x31\x77\xf7\xa6\x0b\xdf\x47\x46\x91\xf2\x24\xa3\xb5\xba\xc4\x00\x6d\xb3\x45\xca\x67\x25\xf5\xee\x70\x3e\xca\x0d\xea\x10\xd7\x12\x67\x6f\x63\xef\x3e\x53\x7e\x63\xab\xd2\x60\x8c\xb4\xfb\xe2\x00\xe1\x5f\x18\x20\x91\x53\x49\x60\x72\x90\x80\x44\xc9\x5a\x4e\x9c\x53\x56\xaa\xe8\xed\x5f\x09\x59\xea\xc0\x91\xe2\x27\xa0\xb8\x1f\x58\x03\x27\x6b\x3b\x3b\xf4\xb6\x86\x5a\x55\xfc\x67\x82\xf6\x2e\xa6\xd6\x39\x90\xf9\xbe\xfe\x01"}, +{{0xe5,0x5b,0x34,0x3a,0x0f,0xa1,0xfb,0x74,0x71,0x89,0xcb,0x00,0xdb,0xc3,0xa6,0xaa,0x2d,0xcf,0x5b,0x86,0xe5,0x7d,0x76,0x93,0xf3,0x07,0x42,0x03,0x89,0x76,0x11,0x53,},{0x23,0xa1,0x44,0x60,0xea,0x98,0x3c,0xf9,0x97,0xc7,0x82,0xeb,0x45,0x82,0xab,0x3c,0x8a,0xa6,0xdd,0xe5,0x33,0x25,0xb9,0x77,0xb7,0x8e,0x33,0xd2,0xdc,0x5f,0x27,0xaa,},{0x07,0x26,0x6c,0x18,0x65,0x0e,0xcf,0x06,0x32,0xe2,0x25,0x62,0x4e,0xc4,0xc9,0x7f,0xc3,0x87,0xdc,0x37,0x46,0x87,0xa6,0x19,0x56,0xdc,0xcc,0xe7,0x28,0x94,0xee,0x13,0x8a,0xab,0xc8,0x0c,0xfc,0x90,0xc9,0xee,0xa6,0xdd,0x4c,0x59,0xaf,0x45,0x02,0xee,0x29,0x63,0x5a,0x92,0x88,0x07,0x86,0x67,0x8b,0x14,0xa3,0x93,0x1a,0x69,0xf9,0x07,},"\x36\x28\x9b\x5e\xaf\xf2\xa8\x5a\x7c\x6d\x57\x5b\xd1\x5e\xa5\x94\xb2\xfd\x85\x10\x87\x4a\x46\x9b\x52\x10\x91\x63\x69\x6d\x85\xb6\x8c\x5b\x21\x1d\x29\x64\xef\xdc\x66\xe6\x25\xab\xe8\xaa\xfe\x4c\xd9\x22\x0c\xdb\x34\x11\x07\xff\xa8\x27\x6e\xd4\xb3\x70\xfe\x37\x6c\x14\x82\x68\x71\x67\xdb\xc8\xf7\xb2\x05\xa3\xf3\x30\x1a\x16\x64\xd9\x07\x28\x77\xd9\xf9\x8b\x8f\x69\x83\x13\x01\xdf\x99\x94\x71\x7f\xc8\x89\x69\x24\x23\x91\xd9\xb0\x51\x7d\x6e\xfb\x27\x17\x01\xea\xb3\xf4\xa9\xb1\x20\x42\x13\xe8\xcd\x13\xf9\xd0\x99\x04\x8b\x82\x07\x56\x2f\x2e\x4e\xbc\x65\x3c\xc6\x5e\x9d\x55\x12\xd6\x5b\x41\x02\x2c\x79\xb4\xeb\x37\x29\x87\x69\xae\xaa\x6e\xfe\xd6\x9e\x9a\x8c\xb4\x45\xc7\x01\x22\x74\xde\x62\xf5\x09\xf4\xe4\x81\x4a\xdc\xbf\x44\x53\xb4\xfa\xb8\x5d\x7c\x8f\xd8\x45\xe0\x08\x30\xef\x5b\x7b\x1e\x63\xc6\x76\x13\x98\x4c\xae\xfe\x91\x5a\x54\x8e\x18\xe5\x05\x62\x2c\xb2\xb3\x92\x99\xf4\x27\xf4\xd8\x39\x83\xba\x2a\xa0\x0d\x53\xbe\xe1\xf5\x9a\xec\x83\x18\xc5\xea\x34\x5d\x29\x42\x52\x36\x97\x92\x76\x2a\xdd\x3e\x56\xfc\xfa\x6e\x77\x97\xf0\x28\xc7\x99\x47\x90\x45\xed\xb2\xe2\x05\xeb\x6d\xd6\xca\x04\xee\xe5\x6f\x94\x96\xd2\xbf\x26\x09\x93\x57\xc9\x73\x83\x5b\x99\x36\x02\x49\x11\xe4\x65\x5d\x3e\x22\xc8\x11\xc8\xd4\xdb\xd1\xb0\x4f\x78\x97\x3f\x07\x75\x23\xa3\x89\xb6\xf2\x8f\x6f\x54\x21\x61\x42\xcb\x93\xe3\x3d\x72\xb4\xa5\x05\x2d\x27\xe4\x91\x1e\x41\xe6\xce\xc7\xbe\xbe\x1b\x0a\x51\x13\xe6\xb7\x0b\x47\x9d\x2a\xbe\xed\xf6\x9b\x75\x64\xe5\xa5\x73\xb3\x52\xd1\x6c\xec\x89\x07\x01\xbb\x38\x3d\x3f\x66\x56\xed\xa0\x89\x2f\x8c\xcc\x70\x94\x0f\x62\xdb\xe5\x28\xa6\x5e\x31\xac\x53\x88\x26\xc1\x38\xac\x66\x52\x4e\x33\x16\x37\xba\x2d\x37\x73\x03\x58\xe6\xc7\x32\xcf\xf8\xfe\xe9\x40\xaf\xd2\x2c\x39\xae\x38\x1e\x5d\x88\x26\x73\x9b\x23\xfd\xc1\xb8\x0a\xea\x5a\x62\xa2\xcf\x0f\xf1\x52\x5e\x44\x6c\xf3\x10\x46\x19\x50\x51\xd5\x85\x03\xee\xd1\xbe\xfd\x79\x3e\xea\xe1\xd5\xd1\xb6\x2a\x5c\x98\x45\x15\x7a\x09\x5c\xdc\x08\xa1\xd7\x7b\xa4\x7e\x84\xa5\xa7\x39\x98\x0f\x0f\x5b\xe7\xaa\xec\x9a\x21\x5b\x20\x4b\x4b\xb7\xcb\x1b\x38\x6d\xed\x58\xd7\xaa\xf7\x28\x53\x41\x90\x7c\x63\x33\x6e\xe3\xe6\xef\x07\x7a\xd1\x11\xb9\x74\xe7\x50\x4b\xd9\x89\xf5\x66\xfd\xa1\xb1\xb5\x9a\xba\xa9\x1c\x78\xbb\x40"}, +{{0x39,0x73,0x03,0x8f,0xa2,0xef,0x6a,0x27,0x8d,0x3c,0x1c,0xff,0x9a,0x22,0x56,0x69,0xe4,0x65,0xa6,0x9d,0x07,0x50,0x50,0x3d,0xe7,0x48,0xc0,0x02,0xdb,0xf9,0x27,0x8a,},{0xc7,0x5e,0x77,0xc7,0x81,0x49,0xd9,0xd2,0xdb,0xc2,0x63,0xdd,0xf8,0xac,0x4d,0x65,0x4d,0x1f,0xf4,0x55,0xcb,0x18,0x97,0xe1,0xc3,0xce,0x31,0xb9,0x4c,0xfe,0x32,0x10,},{0xfc,0x0c,0x54,0x53,0x83,0x9e,0xa9,0x92,0x96,0xff,0xfa,0x50,0x1d,0x58,0x36,0x66,0x28,0xdf,0x89,0xf6,0x16,0x76,0x69,0x42,0xd5,0x04,0x0a,0x05,0x60,0x56,0xda,0xb1,0x8b,0x44,0x05,0xc0,0x4a,0xbf,0x90,0x59,0xc3,0x08,0x68,0xd7,0x9c,0x93,0x6c,0xcc,0xc8,0x4c,0x4f,0xbd,0x6f,0xd3,0x0b,0x60,0xf8,0xbc,0xbd,0x7a,0x66,0x40,0x42,0x02,},"\x33\x92\xe0\x2f\x3c\x84\x66\x1e\xaf\x81\xa5\xff\x04\x35\x7f\x21\x2e\x92\x36\x1c\x5c\x22\x07\x39\xd9\x6b\x4d\x3d\x9c\x22\xd1\x8d\xf4\x8b\xe6\xb5\x51\x26\xf5\x81\x60\x1f\xfe\x0d\xa6\x3f\x38\xe1\x9c\xbb\x12\x72\x6c\xa0\xa6\xaa\x32\x55\x67\xa0\x03\xa7\x84\x9d\x06\x78\x39\x92\xeb\x9e\xb9\x28\x53\x29\x7d\x72\x28\xdb\xa9\x80\xb2\x50\xbb\x11\x0f\x63\xd0\xb8\x46\x70\xe5\xec\xb3\x19\xcb\xfd\x61\x27\x8f\x1f\x4c\xab\xf1\xfc\xb3\xf7\x01\xf1\x2f\x6e\xf8\xd3\xcc\x42\x82\xfc\xbe\x58\x9e\xb5\x65\x95\x03\xa2\xdd\xd8\xbb\xa3\x8e\x5e\xff\x09\x2d\xfa\xf5\x39\xfd\x80\x4f\x21\xf7\x3a\x90\xad\xf5\x69\xa0\x0b\xf9\xd2\x5a\x9a\xd3\xa6\x33\x09\xcc\x60\x93\x14\x24\x71\xa4\x78\xf0\xb8\x99\x22\x86\xde\x02\x3c\x68\xef\xd4\x99\x87\xec\x27\x0b\xd9\x46\xf6\xdb\x48\xf6\x84\xf1\xc2\xad\xee\xe2\x6d\x68\xdc\xe9\x5a\x55\xe4\xcb\x27\xbc\x60\x52\x30\x80\xdf\x6b\xa2\xb1\x99\x99\x6b\x1f\x1d\xa6\x92\x0d\x15\x59\xf7\x9b\xfd\xe9\xfa\x1a\x02\xde\xae\x14\x80\xc7\x6f\x94\x7f\x9d\x21\x3f\xc4\x3b\xb2\x88\x0a\x1b\x4d\x03\xbb\x14\xf5\xb0\x44\xa0\xfd\x83\xce\x04\x92\xf4\x9c\xa3\xaf\x25\x21\x1b\x86\xfa\xa5\x73\x5a\xd7\xfe\xaf\x31\xa1\xa7\x49\x1e\x70\x8b\x41\x82\x9d\x68\xe3\x24\x14\xf6\x83\x52\xb7\x1d\x1c\xd2\x3c\x8e\x12\xfb\x02\xda\x71\x14\x84\xf6\xef\x97\x52\x8a\x00\xd2\x4f\xcf\x91\xd4\xe0\x6e\x9b\xad\xae\x9a\x44\xdb\xdb\x3f\x77\x80\x41\x76\x8d\x86\x37\x04\xd7\x36\x81\x04\x00\xe7\xf2\x93\x1e\xfb\x85\xc8\x72\x4a\x59\x34\x26\xaa\x2a\xf1\xec\x5b\x66\x4f\x85\xc2\x25\x48\x96\xfd\xcf\x31\x6d\xb0\x92\x4e\x11\xaa\xe8\xd6\x83\xe9\xa0\x21\x92\x9d\x0a\x9d\x6f\xec\xb4\x59\x4b\x1b\x3f\xbc\x16\xb1\x76\xd2\x9d\x1e\xfb\x18\x19\xa4\xa4\x23\xfb\xe0\xca\x05\x59\xc5\x7e\x9e\x54\x49\xf1\x4b\xce\x91\x36\x0d\xaf\xda\x6a\x42\x7c\xe4\xa0\x99\x3d\xd0\x30\x82\xdd\xee\x06\x65\x33\xf6\xd3\xbd\xa5\x66\x0f\x42\xfd\x77\x57\x69\x0d\x67\x05\x98\xec\x70\x96\xf4\x75\xa0\x1a\x51\x99\x50\x34\x1a\x83\x1f\xc9\xa2\x81\xc0\x94\x7a\x86\x3f\x1f\x6e\x03\xbb\xa7\x74\xde\x77\xad\xc2\x3f\xbe\x52\x5c\xae\x6c\xcc\xe4\x7a\x0e\xc4\x97\x9e\x8b\xec\x86\xf3\x32\xfc\x6a\x57\x36\xe3\xb9\x8f\xb3\x32\xe9\xe8\x24\x4e\x68\xa1\x00\x45\x5e\x64\x99\xba\x8d\xba\xe9\x8b\x92\xba\x3d\x9c\x6b\x4f\xf9\x80\x34\x3e\x4c\x8e\xf4\xd5\xa4\xaa\xcf\x8b\x1a"}, +{{0xc7,0x1c,0xc1,0x0a,0xd2,0xd4,0x43,0xe0,0x25,0xad,0x06,0x25,0x68,0x6b,0x12,0x35,0x03,0xe5,0x90,0x19,0x3a,0x2b,0xc8,0xcc,0x57,0xa7,0xb9,0xb4,0x15,0x8d,0xe6,0xcb,},{0xfc,0x06,0xac,0xaa,0xb5,0x3a,0xd0,0x8e,0x97,0x62,0xdd,0x11,0xcd,0x21,0x22,0xb3,0x15,0x99,0xbd,0x25,0x98,0xce,0x6f,0x24,0x87,0x95,0xe7,0x32,0x21,0x9c,0x2f,0xc7,},{0x2e,0xb3,0x3b,0xc2,0xd5,0xde,0xb7,0xf3,0xa2,0xdc,0xc3,0x77,0xb0,0xc6,0xa8,0x62,0x13,0x4b,0xf3,0x19,0x1e,0xc4,0x0f,0xc1,0x28,0xac,0x28,0xab,0xf2,0x31,0x6e,0xf1,0x40,0x16,0x49,0xb8,0xf4,0xcf,0xa1,0xa9,0x36,0xde,0x79,0xb5,0x32,0xdc,0x04,0x3b,0x6d,0x36,0x02,0x4b,0x4c,0x37,0xbb,0xa2,0x92,0x90,0xac,0x9f,0x44,0x9b,0xa6,0x0d,},"\x2e\x08\x46\x53\x6d\xc6\xcc\xe1\x9c\xcf\x82\xdc\x2d\x0c\xd2\x1b\xd4\xe1\xca\x7b\xc3\x17\x06\x7a\xf8\xd9\x0e\xe4\x81\x8c\x85\x18\xbc\x3e\xf9\x60\xce\x11\x2a\x41\xd2\xb9\x97\x9a\x28\x2a\xe1\x3d\x70\x6a\x00\x5e\x00\x34\xf0\x6b\x39\xff\x4b\x0a\x5a\xfa\xed\x70\xb5\x61\xbc\xce\xb1\xbb\xd2\xec\x19\xf9\x74\x48\xea\xed\x4b\xe6\x20\xe3\x6a\x96\x2d\x87\x8c\x6f\x80\x17\x2b\x9f\xad\x43\xee\xd0\x7f\xf9\x3d\xb9\xb9\xca\x22\x62\xd5\xa3\xc2\x29\xc5\x4e\x30\xa4\x5e\x73\x66\x08\x92\xf0\x48\xe3\x63\xf3\x71\x44\xed\x19\x21\xf7\x29\x92\xb4\xd0\x15\x29\x87\x0c\xfe\x37\x3b\x7e\x7c\xbe\xda\xf9\x69\x26\x9f\xb7\x0a\xa7\x83\xd1\xe7\x44\x17\xc7\xba\xe0\xfe\x03\xd9\x51\xfd\xb8\xc7\x1c\x62\xe9\xbe\x7f\xdd\x5d\x23\x3e\x39\xf4\x6f\xed\x05\x7e\x49\xb6\xf3\x40\x68\x45\x91\x48\xda\x3d\x42\x41\x61\xad\x2c\x86\x95\x08\x60\x2e\x9c\x0b\xb3\x0b\xfb\x88\xac\xd5\xf4\xdf\xdf\xfd\x47\x35\x03\xcd\xfe\xda\xbc\x44\x42\xb7\x43\xbe\x07\x5e\x7c\x6f\x61\x0e\x64\xff\xc2\xe5\x31\x87\x74\x5c\xd7\x19\x65\x8f\xc6\xe6\x2a\x5b\xe5\x18\x43\x7c\x5b\xd6\xa4\xfe\xba\x94\xae\x3f\x44\xf2\xf2\x93\x08\xe8\x31\xfe\xef\xed\x67\x69\x09\xce\x5e\x80\xc8\x4c\xbd\xca\xc4\x7e\x47\xd2\x7c\x97\x12\xa0\x1f\x6b\xc5\xda\xed\xc0\x2e\x64\x14\x40\x7e\x91\x1c\x0a\x5a\x53\xe5\x32\x8a\x5a\x5f\xd9\xf0\x40\xaa\x7f\xb7\x0b\x79\xb3\x1c\xd1\xb6\xfd\x9b\xd5\x02\x90\x40\xbd\x22\xae\x22\x2f\xd2\xf6\x87\x0d\x07\xf4\x35\x32\x26\x39\xcf\x31\x93\xca\x57\x09\xb8\x82\xb0\x7a\x58\xf9\x52\xa9\x96\x3e\x56\x8f\x8c\x5a\x58\x4a\x6b\x9e\x27\x5c\x5c\x07\x95\x7a\x4d\x2c\xda\xa9\xf1\xeb\x44\x4e\xd1\x22\x4b\xac\x65\x63\xb2\xf9\x27\x3e\x80\x30\x1d\x44\xd5\x0a\xe3\x83\xb5\x97\x21\x3b\x00\xda\x5b\xf2\x7e\x5d\x1f\xe2\x40\xcc\x3b\xb6\x5a\xa5\x03\x0d\x65\x1b\x6b\x5b\x31\x76\x1d\x53\xce\x0c\x6d\x74\xa1\x5d\xad\x54\x79\xf3\x1c\x91\x5c\xcf\x44\x66\x59\x85\x3b\x89\xa5\x1a\x28\xee\x89\x76\x85\x35\x53\xfd\x2e\x02\xfe\x72\x43\x53\x8d\x00\xb4\xed\x07\xd8\xb8\xa8\x0b\x5c\x16\x5c\xd4\x63\x41\xff\xd8\x16\x3c\x55\x57\x02\x66\x3a\x4e\x6a\xb2\x95\x2b\x7e\x74\x43\xd0\xf6\xb1\x23\xb6\x94\x67\x21\xaa\x63\xe8\x7b\x11\x55\xec\xa8\xa6\xa1\xbc\x9f\xd2\x5c\x67\x62\xe5\x27\x42\xc8\x6b\xca\x1b\xa9\xd8\x37\x04\x15\x24\x4f\x0e\xdf\xdb\xe0\x93\x2b\x5c\xa0\x61\x15\x09\xc9"}, +{{0x0a,0x4f,0x5e,0x16,0x70,0xf1,0xe2,0x4b,0xfa,0x37,0xb7,0x3c,0x99,0x43,0x30,0xb3,0x6e,0x7d,0xaa,0xf9,0x30,0x16,0x1b,0x78,0xa4,0xa8,0x48,0x66,0xff,0x25,0xe3,0xd5,},{0x9d,0xcb,0xba,0x90,0x39,0x81,0x59,0x4c,0x7b,0x67,0x7e,0xa8,0x00,0x20,0x01,0xd6,0x64,0xcf,0xf7,0xce,0x8e,0x5c,0xfa,0xe5,0x88,0x40,0xcf,0x74,0xaf,0xf0,0xd3,0xa9,},{0xdc,0xf3,0x53,0xb2,0xb9,0x9a,0x4e,0xf4,0x5f,0x3f,0xdf,0x65,0x28,0x63,0x2e,0x8a,0xbd,0xc4,0x33,0x34,0x24,0x76,0xa8,0xc2,0xb3,0x79,0x00,0x40,0x4a,0x4e,0x33,0x3d,0x38,0x78,0x14,0x23,0x57,0x57,0xef,0x7a,0xd0,0x38,0x58,0xa0,0xf3,0x5d,0x46,0x15,0xe8,0xab,0xa4,0x84,0xfd,0x64,0xf1,0x11,0x2e,0xc1,0xb1,0xae,0xd2,0xcb,0x64,0x0e,},"\xf4\xb0\x5b\x3e\xfd\xcb\x1d\x5c\x07\xda\x95\x0c\x46\x56\x55\x28\x44\x0b\xb4\x88\x35\xee\x4c\x13\xf4\x3d\x7a\x16\x18\xde\x11\x9e\xbb\xb2\x59\xea\x74\x80\xa5\x04\x81\x74\xfa\xec\xc1\x05\x5b\x32\xdc\x01\xac\x71\x56\x34\x43\x21\xe8\xeb\xa6\x98\xf3\x02\xee\x16\x43\xb5\xf0\x4b\x8e\x7e\xcc\xa6\x3b\x91\x56\x1c\xe3\x51\x4a\xbe\x78\x51\xb6\xfb\x17\xfc\x94\x3b\xdc\x94\xda\x30\x8c\x8e\x47\x69\xfe\xc2\x0f\xad\xf4\xfa\x8e\x7f\x62\xb6\xff\xb5\xf1\x70\xd6\x44\xed\x29\x35\x5e\xbd\x22\xcb\x3a\xa1\x48\x6b\x1e\x36\x7c\x72\x9d\xd3\xf7\x9b\xcd\x40\xff\xd0\x8a\xf2\x8c\xeb\xc8\xd7\x76\xe1\xa4\x83\xe9\x11\xd7\x9b\xc6\x13\xe0\x9c\xc6\x21\xca\xde\xb0\x34\xdd\x6f\x72\x37\x47\x71\x98\x51\x27\xf7\xa3\xa1\xaa\x78\x6a\x52\x3a\xe6\xe3\x4e\xe4\x33\xdc\x30\xc3\x75\x98\x7c\xff\x50\xbd\xcb\xc9\x97\xfc\xd5\x1c\x94\x56\x7a\x67\xae\xfb\x6e\xf5\xed\xf9\xbd\xd6\x59\x64\xd4\x64\xbe\x9e\xbd\xfb\x88\xc0\xe2\x31\xb0\x7f\xf6\x40\x5c\x00\xf8\x25\x31\xe9\x61\xbf\xc5\xea\xd2\x66\xbc\xc0\x87\x18\x87\x8c\xaf\xb1\xd3\x75\x36\xf1\x83\xe4\x8b\xf3\x8d\x3f\x6b\xe9\x00\x25\x2d\x1f\xb4\x19\xe6\xa2\xac\x58\x96\x03\x9f\x63\xc3\x14\x01\xff\xf9\x32\xce\x98\x14\xb0\x85\xab\x20\x41\x69\x72\xa2\xb3\x51\xc8\x15\xa6\x2d\xe5\x09\x67\x46\x28\xb0\xd3\x56\x6f\xc9\xc2\xe0\xa9\x23\x7b\x93\xf9\xbb\xb2\xde\xed\xf0\x2b\xff\x83\xbf\x6d\x86\x8b\x63\x99\x32\x6d\x48\x09\xd0\x41\x9f\x31\xb2\xf3\xa4\x81\x28\x5b\x94\x07\x8b\x47\x06\x1c\xe9\x1d\xad\x58\x3d\xd5\xb1\x3b\xd0\x10\xfb\x30\xf2\x49\x5b\xb7\x04\x20\x18\x3a\x93\x01\x59\xe4\xdb\x19\x3d\xf6\xac\xd1\x24\x42\x3e\x03\x9a\x67\xf1\x56\x88\xae\xc5\x0c\x59\x27\xfb\x27\x18\x22\xaa\xa6\x6f\x29\x4b\xc8\x05\xd3\xbc\x7c\x83\x41\x87\x8a\x54\x10\x09\xf3\x0d\xa9\x9f\xcc\x00\x85\x07\x9c\xe7\xfc\x55\xe0\x01\x16\x85\x56\x2a\xbd\xb3\xa9\x47\x1f\xfd\xe6\x17\x63\x00\xef\x5b\x31\xe0\xdf\x60\x9a\x54\xa1\xee\x66\x24\x07\x0d\xa9\x9c\x87\x76\x89\x1f\xdf\x6a\xa7\x8b\x4d\x55\xb1\xf5\xda\xdf\xc0\x61\xad\xd5\xaf\x00\xfd\x3a\xde\xdb\x44\x8c\x55\x9b\xff\xf2\x04\x06\x80\x43\xa5\xd1\xd6\x21\x47\x48\x62\x8c\x3e\xbc\x5f\x02\x24\x32\x6c\xa1\x8e\xf0\x48\x42\x5d\xa9\x30\x01\x33\xfb\x69\x5d\x4f\x26\x31\x65\xac\x22\xf3\x61\x9d\x40\x5a\xf2\x71\xa7\x1a\x9a\xfb\x19\x8b\xf6\x31\x24\x1d\x34\x59\xb9\x53\x98"}, +{{0xb8,0x55,0xc8,0x18,0x05,0xc7,0x08,0x74,0x10,0xe6,0x9f,0x96,0xb0,0x24,0x02,0x71,0xdc,0x76,0xc1,0xe4,0xad,0xe3,0x8c,0x6a,0x92,0x78,0xe3,0xc9,0x4f,0xbe,0xa2,0x56,},{0x6a,0xdb,0x02,0x5a,0x40,0x26,0x0f,0x56,0x98,0x84,0xb8,0xca,0xb3,0x75,0x2b,0x4f,0x25,0x5c,0x37,0x3e,0x2b,0x42,0x4b,0x62,0x87,0xeb,0xb5,0x10,0xfa,0x06,0xff,0xf0,},{0x3c,0xaa,0x81,0x32,0x73,0xe7,0x53,0x54,0x2f,0xfb,0xfe,0xb2,0x1b,0xc3,0xe2,0xcf,0x8c,0xa7,0xd9,0x20,0xfa,0xac,0x7c,0x49,0xdc,0x2a,0xa9,0x91,0x17,0x68,0xc7,0xad,0x43,0xb3,0x8b,0x02,0x36,0xdb,0x27,0xf3,0xee,0xae,0x0b,0x12,0x06,0x00,0x1e,0x66,0x5a,0x60,0x70,0x78,0xc5,0x22,0xed,0x7a,0x9d,0xc4,0x68,0x85,0x34,0x63,0x59,0x00,},"\x85\xa9\xbd\xb7\x0a\x6c\x75\x28\x97\xe4\x3a\x91\x10\x6e\xe9\xa9\x9c\x2c\xa9\x4f\xf7\xb4\x46\x1a\x44\xa3\x91\x74\xc1\x7e\xcd\x99\xdf\x46\xee\xcd\x81\xc3\xf5\x25\x13\xdc\x9d\x54\x7d\xad\x37\x21\xc6\xd5\xee\x1f\x8f\xac\x0b\xa5\xaf\xb3\x68\x70\x44\x73\x9e\xd5\x35\xb8\x44\x00\x87\x04\xc0\x9f\xe1\xe5\xd7\x85\xd4\xc9\xc3\xd0\xb0\x58\x89\xb9\xc2\x0f\xc3\xfd\x68\xdf\x12\xdb\xeb\x2c\x34\xf6\xf7\xec\x1c\x6f\xb7\xfa\x81\x1f\xf8\x46\xb5\xa6\x1f\xa5\xfe\x55\x37\x9e\xe6\x3a\xbc\xd3\x73\xfe\xd0\x02\x54\xeb\xd0\x6b\xc8\xb2\x2f\x7f\xbf\x2f\x72\x7a\x5f\xad\x88\x51\x41\x59\xe2\x6d\x78\xdf\xdb\x09\x57\xf6\xef\xaf\x51\xa8\xe8\x0b\x58\x5e\x83\x8b\x96\x21\xd0\x51\x07\x4a\x4f\x58\x67\xb4\xae\x2f\x2f\xf6\xd6\x2b\x85\xbc\xce\xc0\xb4\xaa\xa4\x79\x16\x37\x38\x8c\x09\x01\xfd\x49\xdc\xcc\xce\x72\x04\x85\x9f\x81\xee\xfc\x63\x9f\xed\x92\x28\x04\x56\xe6\x9a\x15\x09\xb4\xb1\xbd\x76\x24\x44\x7d\x86\x2c\x45\xa0\xc8\xb0\xc5\xbb\x2c\x4c\xa5\x12\xcb\xc0\x37\xf5\x1b\x78\x09\x82\xb1\x83\xa5\xca\xfa\x15\x29\x75\x85\xc9\x47\xa2\x5b\xe8\xc2\x24\x0e\xbf\xb6\x86\x8e\xce\x5e\xa2\xaa\xb2\xc2\x39\xc8\x37\x54\xc7\xd5\x94\xb3\x72\x5a\xce\xef\x34\x4b\xa7\xe6\xae\xf4\x9f\x7f\x31\x3b\x0a\xe8\x2c\xca\xca\xd3\x87\xa6\xe9\x33\x7f\x05\xf8\xc7\x99\xef\xe7\x82\x9b\x27\xb4\xd5\xb2\x01\xfd\x5a\xe5\x83\x43\x51\x69\x07\x59\xf3\xea\x17\x5f\xd4\x74\x1b\xe2\x28\xd8\x07\xfb\x54\xdf\x4a\x74\x10\x38\xfa\xee\x47\xed\xf1\xf5\x61\x65\x25\x98\x60\x1f\x27\x15\x5f\xc5\x0d\x9d\x50\x11\x43\x37\x11\xc1\x06\xd4\xb6\x07\x85\xa5\xcc\x93\xb3\xfd\xd1\xda\xd7\x0c\x0c\x8e\xaa\x33\xf1\x51\x2e\x35\xa5\x41\x74\x5e\x37\x6c\x15\x16\x7f\xa8\xf6\xb3\xb2\xc4\xc3\xa3\x66\xfc\x41\x49\x7d\x29\x73\x57\x81\x6a\xe7\x95\xa8\x04\xc9\x80\xe7\xcb\xfb\x0c\x74\xd8\x83\x5d\x92\x9a\xe3\xbb\x52\xba\xb1\x29\x64\x56\x6d\x74\x6b\xd2\xc1\xd1\x32\xb6\x23\x3f\xa3\x4f\x75\xe2\x68\xed\xee\x77\x5e\xb3\xce\x13\x2e\x6b\xeb\x2e\x8d\x71\xf0\xc8\x76\x29\x91\xcd\xe4\xe2\x6f\x71\x43\x9d\xfa\x83\x97\x8f\x99\x56\x03\x86\x1b\xc0\xb1\xd9\x06\x0b\xbc\xca\xcc\xf8\x6f\x87\x45\xad\x96\x99\x4d\x5d\x00\x7d\x52\xe8\x3a\xa5\xe6\x94\x12\x96\x4b\xdb\xfb\xe4\x78\x0a\xaa\x8d\xe4\x1b\xe1\x29\x8a\xbb\xe9\x89\x4c\x0d\x57\xe9\x7f\xca\xcc\x2f\x9b\xbd\x63\x15\xd3\xfc\xd0\xea\xf8\x2a"}, +{{0x95,0xb9,0xc8,0xa6,0xef,0x80,0xeb,0xd5,0xcb,0xd4,0x7a,0x04,0xca,0x54,0x38,0x73,0x73,0xdf,0x4d,0x67,0xa2,0xb4,0x75,0x59,0x77,0x65,0xac,0x89,0xfc,0xf9,0x3e,0x93,},{0xf2,0xc9,0x47,0xb1,0x8a,0xdc,0x3e,0xa6,0xa2,0x3f,0x7a,0xbc,0xa3,0x64,0xb9,0x85,0x3a,0xe8,0x5a,0x2b,0x0c,0x8c,0x26,0xf0,0xd3,0x17,0x3c,0x27,0x32,0xc3,0xc7,0xff,},{0x2c,0x8b,0xf5,0x43,0xe2,0xa3,0xe0,0x04,0x15,0xee,0x4f,0x10,0x7b,0x2f,0x5a,0x66,0x87,0x17,0x6f,0x5d,0x52,0x11,0x17,0x75,0x9c,0xeb,0x56,0x17,0x51,0xbc,0xc7,0x7d,0x9b,0x08,0xa6,0xa6,0x31,0xf6,0x44,0x7c,0xd9,0x01,0xde,0x96,0x69,0x9a,0xeb,0xb1,0x68,0xbf,0x97,0x50,0x0d,0xc5,0x4a,0x05,0x43,0xef,0x14,0xe4,0xb5,0xa0,0x81,0x06,},"\x78\x55\xbc\x39\x26\x30\xcc\xf5\x31\xd3\x06\x16\x06\xdd\xfc\x81\xa0\xfd\x92\x94\xc5\x47\x91\xb5\xf9\x55\x9b\x68\x27\x25\x4a\xa1\xf2\x5c\x54\x0b\x7d\x7d\xf3\xec\x9c\xdf\x14\x25\x66\x29\xdb\xcf\x9b\x72\x5f\xeb\x34\x12\xeb\xf3\x5f\x0e\xf9\x37\x9e\x41\x31\xcc\x77\xe0\xf0\xfb\x6f\x74\x59\xa7\x38\x36\x1a\x99\xae\x4c\xcb\x2b\x60\xa9\x9f\xe9\x2b\xd6\xc3\xa5\x3d\x6f\x45\x4e\xe9\x00\x5b\xce\xc5\xae\xdc\xfa\x82\x34\x73\x92\xef\xcf\x11\x75\xe5\x78\x39\x6a\x8d\x80\x0d\xab\xa0\xf4\xc2\xcf\x4d\x49\x13\xb0\x52\x86\x20\xe3\xba\xa0\xf6\xd8\x6e\x06\x28\xe4\x7c\x0c\xa2\x6d\xf3\xb0\xc7\x88\xc4\xe1\x65\x57\xf7\xfc\x28\xdf\x82\x0c\x12\xfb\xb6\xff\xbf\xec\xb9\x82\x9d\xdb\x65\xef\x8d\x63\xe9\x0d\x68\xfc\x71\x94\xb5\xb8\x85\x91\x3f\x08\xed\xee\x84\x56\x76\x47\xff\xa3\xf0\xd0\xd3\x25\xd0\x82\x60\x0c\xe7\x1a\x23\x45\xc7\x7d\x65\xbd\x96\x25\x20\x03\xe5\xc1\x25\xa7\x18\xa0\x73\x70\xc3\x1b\x57\x08\x07\x5c\xf1\x83\x7c\x69\x25\x63\x5c\xc6\x8d\xd1\xb7\x51\xe4\x0a\xb6\x08\xb0\xd9\xd8\x85\x2c\x18\xd3\x06\x92\x19\xef\x80\x7b\x76\xd2\x88\xf9\x2c\x29\xa9\x3e\x3d\x75\xb5\xb2\xe5\x36\x81\x67\x1d\x3a\xe0\x14\x5a\xc0\x3c\xca\xd3\x16\x2e\x44\x70\x3b\x04\x01\xd3\xeb\x16\x7c\xd8\xdd\xc1\xe1\xa5\xa3\x26\xb7\x28\xb1\xe0\xc0\x0a\x94\xd8\x6d\xe6\x13\x52\xa6\x61\xe4\x08\x97\x17\x5d\x28\xd3\x41\xe4\xd1\xd9\x96\x2e\x35\xf4\xde\x18\xa5\x40\x17\x61\x1a\xd0\x53\x59\xce\x08\xb9\x7b\xfe\xdb\xfb\xe3\x99\x2e\xd5\x8e\xd4\x0f\x51\x7a\xab\x01\xc0\xfe\xfe\x8b\x63\x64\x3d\xa1\xa4\x54\x15\x27\x30\xbf\x99\xaf\x87\x40\xad\xf9\x8a\x77\xb8\xd7\x3a\xdb\x08\xe6\x09\xe0\x0c\xe9\xb1\xcc\xdf\xef\x3e\x9a\x9b\x05\xaa\x56\xe0\xbc\x79\xb6\xbb\xba\x80\xdd\x8e\x46\x1a\xf7\xcb\x20\x28\x92\xd8\x9b\x2d\x05\xa4\x45\x8a\xb3\xfa\x54\xb4\x74\xb8\xf8\xf5\x81\x79\x5d\x6c\x27\x39\xe5\x9d\x0f\xe0\x62\x40\x0b\xae\x2d\x2d\x53\x4b\x34\x0b\xb8\xe2\x61\x57\x77\xa9\xa5\x61\x5b\xb2\xcf\x43\x7b\xa5\x25\xe0\x0e\x70\x38\xf2\x2a\x57\x88\x2a\xc5\x20\xb3\x33\xe7\x5c\x3c\x92\xa8\xb9\xf0\xe3\x7f\x67\x1c\x94\xb1\x5d\xd8\x18\x2a\x08\xd7\xc1\x43\xe9\x4e\x92\x62\xb3\xcc\x55\x44\xc2\x94\xf5\xf3\x35\xc2\xb2\x8a\xc1\x19\xfe\xa0\x0f\x96\x34\xdb\x06\x39\x93\x98\x8b\x5f\x15\x05\x79\xc7\xcc\x25\xb6\xa1\xfb\x0d\xde\x94\x80\x4f\xa6\xef\x66\xff\x79\xfb\x91\x07"}, +{{0xb7,0x86,0xcc,0xfb,0x58,0x6d,0x43,0xb8,0xc4,0x6b,0xb9,0x7b,0x96,0xc9,0x18,0x73,0x1b,0xc2,0xcc,0x11,0x92,0x77,0xf1,0x23,0x67,0x1e,0x30,0x14,0x81,0x58,0xd2,0xed,},{0x90,0xc7,0x00,0x46,0x00,0xf3,0xdc,0xe4,0x09,0xfd,0xea,0xdc,0x8e,0xd0,0x18,0xf9,0xea,0x26,0x3f,0x75,0x16,0x0a,0x74,0xab,0x54,0xf4,0xc2,0x39,0x9a,0x90,0xca,0x78,},{0x52,0xba,0x96,0x58,0xa1,0xa0,0xb3,0xe9,0x8e,0xd5,0x20,0x9e,0x39,0x3e,0x42,0x00,0x66,0xa3,0x7d,0x37,0x14,0xda,0xa7,0x3d,0x5c,0x67,0x1d,0x33,0x07,0x5a,0x5f,0x57,0x27,0xfe,0x4e,0x08,0x1e,0xe0,0xfa,0x3c,0x21,0x33,0xdc,0x95,0x3a,0x2d,0xa6,0x20,0x29,0x13,0x71,0xf0,0x0c,0xcb,0x57,0xd8,0x79,0x2e,0xb5,0x96,0xa2,0xff,0x81,0x01,},"\xba\xbf\x48\xbd\x55\xea\x91\xbd\x0c\x93\xb9\x70\x24\x1b\x52\x9d\x9d\xb4\x3d\x49\x27\xfe\xa5\xf1\xa1\xf7\x08\x2d\xd6\xcb\x50\xa5\x2b\x09\x4b\x31\x29\xfc\xd9\x03\xa4\x4f\xec\x8b\xfd\xb5\xc8\x6c\x00\x2a\x2a\x45\x28\x87\xca\x25\xa6\x0e\xce\xb5\xe1\xf9\xf5\xc9\x3d\xc5\x94\x23\xc7\xaf\xe7\x47\xc6\xbf\x40\x7c\xac\xad\xec\xcf\x5d\x78\x79\x70\xcb\x06\x17\xbb\x3c\xfe\x7f\xd1\x75\x63\xd3\xa0\xdc\x91\x63\x1f\x71\xb8\x4b\xe2\x4a\xe8\x00\x11\x37\x50\xf0\x31\xd0\x1f\xd0\x53\x64\xb4\xf2\x7f\x86\xf8\xdc\x3a\xd7\x40\x7e\x1a\xe9\xe7\x68\x15\x4e\x3d\xde\x58\xe8\x67\x12\x9e\x24\x74\x54\x7b\x40\x82\x17\x96\x48\x44\x85\x8d\x05\x6b\x31\xc3\x74\x99\x1b\x7f\x16\x1f\x52\xf0\x88\xb8\x06\xe0\xf3\x13\xd6\x8a\x15\xc5\x40\x1e\xd5\x5b\x2b\x77\xde\xea\x58\x6c\xb0\x54\xdc\xd7\x1a\xf2\xab\x6a\xb1\x1e\x84\xb3\x0c\x53\x93\x45\xde\x3e\xb4\x3f\xb7\xb3\xa3\xb4\x89\x87\xc3\xbf\xa7\x06\x55\xd5\x99\xf2\xe3\x1d\x12\xad\x23\xcc\x96\xe8\x6d\x38\x0b\xfd\xa8\x12\xfe\xff\x3d\xd3\x02\x42\x92\x91\x69\x07\x02\x28\x91\xe1\x19\xbf\xc3\xed\x9c\x25\x54\x6c\xd1\x9f\xc9\x92\xd8\xa6\x1e\x60\x59\xca\x3c\xe7\x80\x2a\xf1\x11\x87\x56\x62\x0b\x87\xa7\x24\x2b\xd8\x38\x97\xc9\x4d\xd5\xa3\x6e\xd4\x0f\xc0\xf3\x4c\x2c\x93\x11\x0b\x37\xd1\x7d\xd9\x6a\x22\x06\x25\x90\xbc\xdb\x54\x67\x42\xef\x72\x18\xad\xcc\xc5\xad\x28\xf4\xfc\xe6\xec\xf7\x05\x83\x5f\x41\x13\xd8\x2e\xa5\x33\x90\x3a\xec\x8c\x38\x20\xfe\x4b\x47\x15\xf3\x7e\x20\xce\xbc\x1e\x71\x51\x9a\xa0\xb2\x40\xb4\x84\x0a\xa4\xfd\xcf\xb5\x24\x67\xfe\xdd\x8f\x4d\x1f\x9b\xc3\x3e\xe1\x14\xf3\xef\x85\xf5\xfd\xb0\x9c\xa8\x84\xaf\x38\x8a\xd3\xad\xf8\x4c\x79\x3f\x38\x6e\xfe\x6f\xf8\xa4\x6e\xd8\x1e\x5d\x45\xa3\x7c\x25\xcd\x80\xf2\xd7\x36\x3f\x43\xae\x45\xe3\x77\x2c\x0d\xf8\x9f\x11\x44\x79\x39\x80\x6c\x09\x6e\xf9\x33\xa1\x39\x44\xf0\x89\x0d\x88\x7c\x2e\x5b\xbb\x6b\x12\xea\x95\x0b\x09\xb8\xfe\x42\x52\x89\x37\x73\x52\xf3\x5f\x84\xcc\x4d\xcd\x4d\x7a\x44\x94\x89\xfa\x92\x51\xc0\x31\x13\x48\x92\x25\x80\x9c\xdf\x3c\xb6\x34\x75\xf1\x0d\x34\x17\x09\x37\x1c\x6f\xd4\xbb\x7a\x94\x94\x83\xd1\xbc\x2b\x31\xdd\xf4\xd9\x63\xa0\x7d\xe7\xea\x5c\x3f\xee\x9a\x0e\x33\xf0\x76\x9f\x2f\xaa\x40\x61\x2a\x54\x69\x74\xbd\xe0\xb7\x33\x91\x79\xe4\x12\x4a\x44\x7b\xd4\x28\x79\xcc\xda\x5c\x8a\xd1\x81\x9c\x53"}, +{{0xdd,0x1a,0x97,0x74,0xf7,0x58,0x4d,0x85,0x89,0xb1,0x9f,0x92,0xab,0x69,0x39,0xac,0x48,0x56,0x02,0xfe,0x16,0x44,0xce,0xe2,0xf6,0xf3,0xcd,0x60,0xfb,0xd5,0x84,0x00,},{0x4b,0xea,0x7d,0x0b,0x0f,0x4b,0xd5,0x90,0xf9,0xe3,0x57,0x9f,0x0c,0x5f,0xa4,0xce,0xf4,0xd6,0x0a,0x49,0xd2,0xc4,0x37,0xa0,0xaa,0xea,0xd9,0xd4,0x3a,0x73,0xd4,0xa3,},{0x19,0x59,0xbd,0xe0,0xa6,0x97,0xa6,0x39,0x93,0xec,0x47,0xd1,0x58,0x22,0x37,0x39,0xfe,0x65,0x87,0x1f,0xa0,0x58,0x70,0xd7,0xde,0x0d,0x38,0x08,0x65,0x91,0x20,0x2a,0x51,0xb1,0x74,0xd1,0xc6,0x18,0x28,0x08,0xc6,0xce,0x62,0x63,0x1d,0x81,0xdb,0xa3,0x4e,0xbe,0xd4,0xaf,0x2f,0x29,0xb0,0x6c,0x00,0xa5,0x7a,0x3c,0xb6,0x66,0x36,0x06,},"\xe5\xdc\x3e\xd2\x6c\x1f\x69\x3c\xf8\x52\x46\x5a\x05\xe3\x04\x8b\x50\x5d\xb5\x11\x6d\x9e\x31\x59\x22\x05\xa9\xc3\xd4\x72\x0b\xc1\x0b\x6c\x20\x63\x9a\x0e\xe2\xf0\xe1\x47\x22\x5b\x5b\x19\xea\x51\x1c\xfb\xa0\xc2\x1a\xac\x10\x71\x5a\x2f\x23\x2f\x10\xc2\xc8\xaa\xd4\x11\x12\xb6\xb0\x12\xe7\x5a\x41\x55\xf8\xc6\x92\x62\x53\xca\x2b\x4d\xdb\x7b\xfe\x7f\x86\xe9\x0a\x53\xdb\xc0\xcb\xa8\x9e\x48\x5c\xec\xa8\xfd\x26\xe5\x0c\x7f\x28\x2a\x25\x35\x73\xcb\x0a\x8f\xa8\x8c\xc4\x46\x23\xe8\x2e\x8f\xa2\xed\xb6\xcb\xc7\x53\x8a\xc9\x2c\x11\xe4\xc5\xb1\xea\x5f\x68\x96\x6d\x15\xd9\x3c\x34\xf3\x96\xd2\x75\x72\xf8\x64\x38\x2a\xb7\x6a\x7b\xe6\x5a\x55\x7b\x13\x97\x66\x36\x8a\x20\x7d\x98\xbc\x0c\x20\x92\x63\x70\xde\xa2\x70\x48\x16\x03\x63\xed\x85\xf4\x09\x9e\x7c\xd6\x6d\x12\xd0\x98\x8c\xfc\x9e\x2f\x16\xaa\x56\x5f\x8f\x33\xb3\x9e\x97\x8c\x05\x87\x37\x1f\x92\xdb\x50\x56\x31\x75\x64\x41\x1b\xd8\xa3\xb6\xfe\xa0\x9d\x34\x87\xaa\xf7\x34\x03\x49\x18\xff\xed\x1c\x9f\xba\x7b\xde\xc6\xfe\x68\x87\x6f\xc7\x36\x0c\xc5\x62\x9b\x92\x10\x40\x27\xfe\x57\x59\xc5\xab\x36\x53\x54\x75\x1e\x79\x69\x11\x6c\x3b\x9a\x21\xb1\x52\x33\x0a\x96\xa9\x38\x1a\xf7\x30\xd1\x78\x22\xd7\x8a\xd6\xea\x86\x00\x06\x91\x5b\x5c\xab\x44\x7a\x75\x93\x72\xe0\x5d\x49\x5e\xbb\x32\x8e\x75\xd2\x48\xda\xa0\x2f\x5d\x2e\xb9\x78\xd2\x71\x0c\xf1\xc5\xfb\x82\x48\x76\x77\x0e\x32\xca\x6d\xe2\xc7\x30\x56\x48\x92\x41\x5b\xcb\x53\xe5\x98\x1d\x70\x7a\xdd\x96\x1c\x5f\x37\xfd\xaf\xa1\x39\x9a\xf8\xae\xa9\x60\x45\x8d\x2c\xa3\x10\x55\x3f\x7c\x98\x66\xcc\xbe\x8e\x9d\x88\xe0\x8a\x44\x68\x72\xea\x66\xfc\x30\x8c\x82\x45\x14\xb7\xda\xce\x03\x34\xdb\x73\x5e\x6f\x14\xc8\x5b\x5e\x61\x9a\x5d\x60\x56\x48\xa8\x81\xe8\x76\xc7\x8d\xbe\x06\x57\x23\x3d\x4f\x7f\x3b\xfd\xdf\x63\xb4\x45\x31\x1d\x6a\xbc\x47\x63\x47\xec\x4f\xb4\x3c\x89\x46\xf9\xd1\x7c\x36\x93\x81\xd1\xc5\x64\xff\xcf\xe2\xdc\x7b\x47\x26\xfd\x57\x38\x7f\x0b\x44\xdb\x8e\xf9\x5a\x0b\x4e\x32\xa7\xbe\xdf\x31\x9e\x53\xa9\xe7\x12\x6c\x28\x11\xf9\x82\x9d\x1f\x4a\xe9\xab\xd9\xd5\xf4\x2e\xfe\xf2\x07\x5f\x47\x05\x1c\x63\xa4\xf8\x20\x20\x40\xec\x47\x23\x68\x63\x82\xc6\x03\x31\x27\xc1\xfb\xff\xf4\xbc\x82\x37\x35\x08\x75\x2d\x43\x1d\xc4\x73\xf5\x2d\xde\xab\x03\x42\xdc\x4f\x54\x47\xf8\xf2\x57\x38\xef\x65\xd7\x85\x56"}, +{{0x66,0xf5,0xea,0x8c,0xdb,0x95,0xee,0x1a,0x75,0xe3,0x24,0x67,0xd7,0xc8,0x3c,0x59,0x44,0x77,0x42,0xc8,0x5d,0xdd,0x49,0x9c,0x43,0xc0,0x86,0x73,0xe1,0x49,0x05,0x3a,},{0xa8,0xad,0x04,0xb9,0xc1,0x44,0xb9,0x7f,0xe8,0x67,0x37,0x4d,0x4f,0xe5,0x7d,0x7e,0xc0,0xc2,0x49,0x18,0x3e,0x43,0xbd,0xfb,0x5d,0x52,0x64,0x4e,0x7f,0xbe,0x1d,0xf3,},{0xec,0x5c,0x7e,0x83,0x92,0xfa,0x8b,0x61,0xbc,0x82,0x96,0x81,0x86,0x6e,0x45,0xac,0x8b,0xe4,0xb5,0xb7,0xb6,0xa8,0x22,0xc1,0xbc,0xd0,0xf2,0xcc,0x2c,0x8c,0x44,0xc3,0x3c,0xf8,0x3f,0xa4,0x2d,0x43,0xa2,0xf1,0x88,0x41,0x41,0xb4,0xa5,0x9a,0xaf,0xf4,0x7f,0x9b,0xe0,0x7e,0x63,0x2e,0x20,0x18,0x75,0x93,0x24,0xea,0xc9,0xd1,0x49,0x00,},"\xc0\xd0\x1d\xce\xb0\xa2\xd1\x71\x91\x10\x18\x79\xab\xb0\x93\xfb\x07\x75\x71\xb5\x21\xbe\x7b\x93\xa1\x17\xc6\x96\xc0\x87\x2f\x70\xea\x11\x39\xab\x62\x83\x29\xee\x56\x55\xfc\x0a\xa7\x7e\x81\x11\xd2\xfc\x88\x47\x48\xc1\xf2\x67\xb9\xeb\x09\xdc\x26\xf5\x7f\xc4\x02\xd6\x1b\xa3\x6f\x63\xf4\xd5\x89\xaa\xe6\x3c\x76\xee\xee\x15\xbf\x0f\x9e\x2d\xcd\xe4\xe4\xe3\xe7\x8f\xc6\xc2\x9e\x3a\x93\xf3\xff\x0e\x9a\x6e\x0b\x35\x66\x45\x95\x38\x90\xde\xbf\x62\xdb\xea\xf4\x90\x51\x78\xd4\xf0\xa5\xa5\x92\xc1\x92\x94\xee\xba\x7c\x21\xcf\x8f\x1b\xb3\xf4\x51\x21\x87\x37\x6d\xe7\x2f\x11\x36\xa4\x8a\xc2\xdf\xaf\x32\xd0\xf3\x7d\xe0\x64\x59\x25\x92\xb6\xe1\xbc\x0c\x51\x2c\xf4\xd2\xd8\x5d\x16\x79\x78\x53\xa8\x09\x33\xb0\x9c\x2f\x7b\xfb\x9e\x54\xa6\x9e\x51\xa8\xe4\x23\xa9\x1c\x3e\x5f\xde\xb4\x79\x05\x33\xe8\x7a\x4b\x1c\x0e\x0e\x23\xa9\xdb\x95\x73\xac\x17\xab\x6e\xc7\x01\x4d\x8b\x7c\x44\x86\xe1\x57\x25\xf8\xd2\x64\xee\xa3\x05\x0e\x83\x5a\xe0\xac\x44\x9d\xb3\x34\x50\x2a\x6d\x97\x35\x8f\xa8\x59\x10\x6a\xd0\xf6\xf4\x29\x5f\x23\x44\x92\x0a\xdf\x93\x55\xa6\x94\x9d\x8d\x14\x5c\x25\x62\x8a\x46\xa1\x04\xca\x09\x9b\xd9\xdd\xe9\x41\x11\x9c\x83\x82\x0c\xdc\x2c\xb2\xd0\x97\x22\x69\x49\x01\x04\x3c\x37\xcf\x0a\xe8\x79\xbe\x20\x30\xd0\x37\x31\x58\xb9\xc4\xb0\x71\x82\x98\xbe\x45\xf6\x30\xf6\xfc\xdc\x19\x0f\x7b\x29\x26\xd8\x76\x55\xa1\x8b\xb7\x97\xac\x50\x75\x7f\xcd\x36\x55\xc9\xe4\x1d\x51\x63\x29\x3d\x9a\x13\xd9\x84\xf5\x91\xf7\x5b\x7e\x4e\x5c\xad\xb6\x4c\x4c\x9f\xdf\xef\x76\xca\xb6\x93\x81\xd0\xf6\x0b\x48\x3f\x80\x4b\xb3\xb3\x33\x64\xdf\x8c\xff\xac\xb3\xc9\xb1\x3f\xf4\xc8\xd8\xd4\xea\x40\x76\x6a\x7d\x42\xd8\x25\x6c\x6b\x1c\x11\xc1\x91\xda\xba\x1b\x8e\xf2\x15\x93\xe4\x7b\x18\x85\x8e\xc1\x9d\x81\x73\x58\x67\x8d\x85\x48\xff\x15\x35\xd5\xfc\xf4\x41\x4b\x6a\x11\xd3\x4a\x37\x42\xf8\xd7\x14\x9f\xa6\x81\x38\x3a\x94\x08\x88\x7f\x1c\x0a\x98\xed\x52\x1e\x72\x79\x32\x77\x82\x4d\x6f\x74\x6d\x49\xb6\x3d\x44\x4e\x31\x2e\x6d\x9b\x98\x66\x11\x25\x81\x96\xa5\xb0\x12\xb8\x8f\xaa\x29\xf9\xa6\xc6\x7e\xd2\x5d\xf8\x7b\x2d\xbf\x0d\xbd\x2d\xc3\x08\x0c\x5b\x8d\x15\xa3\x7d\x34\x72\x90\x98\xed\x0d\xe9\x2d\x75\x80\x74\x29\xb2\xca\xe5\xd7\x28\x3c\x4e\x5c\x9b\xd1\x96\xd1\xad\x43\x6c\x7c\x34\xf3\xc9\x46\x6e\x5c\xb3\x19\x6b\x44\x3f\x4b"}, +{{0xed,0x25,0x58,0xe5,0xc5,0x67,0x84,0xbc,0xfb,0x4f,0x4d,0xde,0xa3,0xc0,0xdf,0xbe,0xf8,0xd9,0x6f,0xf1,0xca,0xbf,0x15,0x8e,0xc4,0xab,0xe6,0x0a,0xff,0x66,0x99,0x9e,},{0x1e,0xdc,0x99,0x10,0x12,0xac,0x6f,0x88,0x8f,0xa7,0xe6,0x04,0x57,0x77,0xe9,0xba,0x1d,0x4c,0x03,0xc4,0x02,0x92,0xd2,0xda,0x6b,0x72,0x2b,0x4a,0xd0,0xa3,0xed,0x74,},{0xab,0x9e,0x01,0x16,0x65,0x24,0xfd,0x28,0x8e,0x5c,0x68,0x9e,0x56,0xd7,0x30,0xd4,0x98,0x30,0x00,0x55,0x10,0x30,0x49,0x33,0x34,0xa3,0x98,0x4e,0x22,0x23,0xdc,0x9f,0x7a,0x5b,0x91,0x0c,0x61,0x76,0x0c,0x61,0x57,0x99,0x0a,0x4c,0x33,0x5e,0x34,0x8e,0x3a,0x7b,0xc8,0x22,0x3e,0x09,0xc1,0x0c,0x5e,0x52,0x0c,0x8d,0x61,0xaf,0xf5,0x00,},"\x2c\x64\x33\xe9\xbf\xbf\x4c\xfd\x4e\x07\x1f\x15\xce\x6b\x12\x9d\x78\x0a\x4b\x3d\xe0\x14\xfa\xc0\x34\xe0\xd4\x4e\xf7\x72\xe2\xc8\xb0\xd6\xa3\x48\x1d\x7b\x3d\xde\xb2\x37\x63\x26\x73\x55\x33\x13\xde\xac\x1e\xfa\xfe\x37\x02\xa7\xa4\x41\x1e\x12\xbd\x34\x1e\x8d\x8e\x96\xc5\x9c\x5e\x30\xc3\x68\x07\xa8\x38\x5a\x53\x8e\x9b\x66\x90\x7d\x6a\x52\x84\x00\xbd\x9f\x95\xee\xdc\x52\x16\xb2\x8f\xd7\x43\x7d\x8f\x4a\x02\x9f\xdb\xdc\x7c\x93\x8e\x4e\xb9\x81\x2f\xec\x05\xea\x69\x32\x29\x62\x9a\xce\x6a\xcc\x7a\xf6\xba\x4c\x23\x8e\x77\x22\xf3\x12\xf7\x89\x6b\x00\x49\x22\xf7\x06\x7e\xde\x10\x6f\x8e\x70\x15\x4d\x78\x3f\xb4\x12\x91\xf3\xc7\xe2\xe4\x82\x60\x45\xb5\x74\x1b\xcb\x4a\x88\x38\xf8\x7a\x32\xe0\x04\x97\x04\xe9\xb5\x32\x34\xc2\x24\xff\x89\x8a\x75\x6e\x52\x91\x34\xc1\xa9\xbf\x50\xfd\x02\x98\x19\xb2\x23\x8b\x60\xb2\xae\xc1\x12\x8f\x34\xd2\x1f\x9d\x66\x98\x3b\xed\x39\x86\x59\xd8\x08\xb6\x7a\x2e\x50\x1b\x5a\x1f\x25\xf7\x1f\x0f\x0c\x1e\xb2\xfe\xa0\xab\x42\xd8\x2f\xf3\xbc\x93\x58\xbb\x20\xc2\x75\x20\xc1\x44\xcf\x21\x16\xf4\xa4\x9c\xbc\x61\x99\x4d\x2d\x71\x05\x46\x69\x4c\x4f\x60\x2d\xc4\x06\xe0\xb0\xc2\x7e\x5f\x5e\x64\x66\x7e\x95\xc2\xec\x9d\xf2\xd6\x52\x9c\xf5\x36\x22\xea\x10\xb9\x56\xb3\x45\xec\x55\xb6\xc3\x9a\x1e\x6e\xd8\x8a\xe6\x6e\x5b\x45\x71\x79\x42\x5d\x1a\x84\x90\x37\xb0\x7c\x46\xcf\x5f\x36\x33\x01\x09\x58\x37\xce\x81\x1b\xff\x49\x60\xbf\x9c\xbd\x15\x20\x1c\x1b\x67\x40\xbd\x70\x10\x21\x40\x74\x4c\x33\x27\xac\xa9\xd6\xd6\xd1\x54\x93\x67\x98\xac\x38\x1f\xa6\x39\xdb\x43\x6e\xe8\x16\x56\x67\xd5\x38\xa6\xc7\x4a\x23\x3c\x12\x4b\xf6\x04\xfd\xad\x51\x98\x4c\x41\x70\xb8\x20\x0d\x2d\xf7\x3c\x29\xbb\x1e\x37\x6a\xff\xc3\x14\xdd\xe3\xe8\x6a\xf9\xd2\xc2\xe6\xc3\xa6\x52\x4d\x32\x1b\xce\x93\xe2\x1f\xc9\x65\x56\x4f\xaf\x77\xd0\xcd\x1a\xcc\xb4\xd7\x62\x94\x85\xf5\x64\xc7\x9f\x4d\x8a\x2f\xde\xfb\x46\x54\x54\x02\x8c\x6d\xd1\x42\x80\x42\x80\x53\x70\x74\x33\x63\xbb\x18\x47\x6a\x3f\x23\x20\xdb\x25\x89\xc7\x21\x33\xcf\x5e\x29\xda\xfb\x7d\x07\xaa\x69\xa9\xb5\x81\xba\xb5\xa8\x3f\x40\x3e\xef\x91\x7a\xfa\x14\xb7\x64\xc3\x9a\x13\xc0\xc5\xea\x70\x19\xd2\xfd\xfb\xd7\xf3\xf7\xd4\x0e\xb6\x3b\x2a\x08\x4d\xa9\x21\x89\x5f\xe4\x8f\x4f\xd5\x94\x01\x7f\x82\x56\x9b\x46\x7a\xb9\x01\x16\x9e\xb5\xda\x9c\x40\x17\x1d\x5f"}, +{{0xb7,0x27,0x98,0xb8,0x11,0xe2,0x33,0x84,0x31,0x25,0x6d,0x24,0x80,0xfe,0x7a,0x36,0x63,0xac,0xec,0xbb,0xe6,0xe6,0xc1,0xb9,0x19,0x1e,0x9d,0x9a,0x22,0x44,0x79,0x40,},{0xce,0x49,0x1d,0xaa,0xd2,0x96,0xb5,0x57,0x27,0xb0,0x95,0x13,0xdf,0x02,0xba,0x59,0x28,0xa3,0x71,0x73,0x7c,0xd3,0x58,0x41,0xe5,0xf7,0x35,0xac,0xab,0x7c,0x5d,0xf8,},{0xdc,0xfc,0x6f,0xd4,0x77,0x99,0xfe,0xc7,0x72,0xc2,0x09,0x9b,0x3c,0x64,0x37,0x24,0x6c,0x3a,0xd0,0x72,0x29,0xfc,0x74,0x0e,0x05,0x31,0x1a,0x20,0x6b,0x18,0xb0,0x2e,0xcd,0xb0,0x26,0xc9,0x26,0xf4,0x9c,0x65,0x52,0xe3,0x47,0xfd,0x35,0xdf,0xde,0x06,0xcb,0x63,0x9a,0x79,0x7c,0x50,0x61,0x2f,0x98,0xe2,0x47,0x8a,0x92,0xaa,0xf6,0x09,},"\xa5\xd4\x62\x98\xb0\x79\x06\x10\xae\xdc\x09\x70\xfe\xa2\xa7\x07\x50\x81\x84\x72\x66\xf2\x2f\x12\x47\x8b\x93\xd7\xe6\x74\xc6\xc5\x17\xf3\xc1\x4e\xd0\x61\x26\x9d\x17\x0a\xc3\x1e\x2a\x64\xf9\x75\x4a\x56\x5b\xac\x1d\xd9\x75\x73\x22\xc1\x11\x32\xe7\xbb\xee\x5f\x32\x81\x8e\x0e\x30\x63\xab\x64\xe5\x52\xd0\x9b\x0f\xd1\x75\x76\x39\xb9\xb9\xd1\xc7\x70\x01\x6b\x67\x74\x65\x87\x2b\x66\x9d\xd4\x8b\xe0\x38\x66\x57\x51\x67\x4d\xd2\xf4\x0a\x96\x6a\x26\x74\x8f\xd3\xe5\xdb\xfd\x92\x26\x5e\xb9\x36\xf5\x5b\x09\x42\x86\xc0\x10\x62\x99\x04\x34\x7c\xb4\xc5\x26\xe3\x77\x47\x0a\xa9\x6e\x81\x69\xa6\xf2\x11\x63\x38\x07\xa5\x00\x30\xe7\xff\x68\xe3\x89\x11\xb3\x55\x5e\x72\x8e\xd8\x59\x0b\x2d\xc4\x5f\xea\x69\x94\x5c\xc0\xc9\xa3\xd3\xe6\xc9\x54\xb3\xe8\x01\x06\xa5\xc9\x1d\x3d\x22\xe8\x9e\x8c\x0e\x1d\xe9\x02\x05\x8e\x9c\xd0\xf8\xce\x80\x6e\xac\x4f\x89\x3e\xe0\x42\x99\x00\xfb\x54\x87\xb8\xfd\x36\xdb\xdc\xb3\x4f\x2d\x54\xfc\x6c\xc7\x4a\x92\x39\x51\xb8\x63\xda\x70\xf1\xb6\x92\xbf\x04\x38\x48\x43\x66\xcd\x85\xee\xb8\x80\xb2\x79\xf8\xfc\xa9\xd3\x24\x2c\x55\x83\x30\xf1\xca\x57\xc6\xa5\x86\x08\xcd\xbc\x07\x73\xe1\x60\x82\xbc\xa9\x64\xdd\xc4\x03\x47\xda\x8a\x36\xb2\xa9\x32\x8c\x2f\x46\x60\x9e\x09\x2f\xd6\x4b\x41\x34\xee\xe1\xd0\x99\x81\x3e\x12\x46\x48\x9e\x8e\xe5\xb1\x9b\x3d\x3b\x89\x1c\x28\xf3\x0b\x38\xb6\xa2\x8e\xc1\xd3\xe9\xb0\x05\xde\xc9\xc6\x3f\x8b\x98\x13\xbc\x1d\xe4\xaa\xf9\x95\xf1\x77\x9d\xde\xd1\x5c\x7a\x43\x0d\x70\xca\x46\xe7\xca\xfd\x4e\x9a\x54\x38\x04\x44\x6a\xb0\x80\x7d\x64\xf2\x55\xe2\x01\xef\x42\x8a\x47\x4d\xae\x8a\x0a\x75\x02\x1b\x62\xad\x39\x88\xff\xb8\x1c\xd8\x22\x1b\x24\x30\x85\xa0\xad\x04\x6f\xdc\x16\xc6\x7f\x17\xb9\xf8\x18\x20\x09\x59\x53\xa5\xb9\x8a\xcb\xdf\x93\xeb\xcf\x80\xbc\x9c\x99\xaf\x5f\xbf\xfa\xcb\x61\xa9\x25\x1c\x5a\xaf\xdb\x22\xb1\x12\x9b\xfc\x60\xc9\x8e\x0f\x17\x52\x63\xbd\xf9\x3d\xc9\xa0\x8b\x8e\xfc\x2e\x8c\xda\xf0\xf8\x3d\x6c\x49\xec\x90\x16\x45\xea\xc5\xa4\xff\x63\x38\x5a\x6f\x1a\xf2\x07\x18\x97\x66\x2a\x37\x22\x19\xc9\x30\x1f\x54\x5a\x2e\xbb\x8f\x59\x17\xdb\x7f\x29\xca\x13\xfc\x86\x1a\xf3\x8d\x90\xc3\x5c\x03\xac\x91\x84\xc1\x22\xe5\x7b\x05\x7c\xde\x42\x6f\xd7\x6d\xca\x79\xe2\x5e\x64\xdb\xb4\x1c\x84\x14\xa0\x45\x0d\xa4\x90\x5b\x90\x2a\xe9\x8d\x2d\xa4\xba\x79\x28\x01"}, +{{0x1f,0xe7,0x32,0x7e,0xa9,0x07,0xd3,0xff,0x17,0x9b,0x11,0x78,0x11,0xd3,0x01,0x93,0xfc,0xba,0x4c,0x34,0x7b,0x90,0x65,0x7f,0xee,0xd9,0x8d,0xee,0xec,0xda,0x9a,0xc9,},{0xee,0xf3,0x01,0xb1,0x6f,0xd7,0xbf,0x3c,0x7b,0x64,0x0b,0xf5,0xee,0x87,0x00,0xac,0x5a,0x87,0x16,0x9e,0xab,0x5f,0x56,0x01,0x5b,0x3f,0x49,0x9d,0x95,0x5e,0x07,0xeb,},{0x9c,0x7f,0xdb,0x53,0xfd,0x60,0x6b,0xc7,0xc9,0xc2,0x23,0xfe,0x94,0x31,0xe1,0xad,0x00,0x95,0x46,0xd0,0x00,0x98,0x81,0x2a,0x49,0x51,0x97,0xf2,0x54,0x1e,0x87,0xf8,0xd6,0xf5,0xda,0x22,0xec,0xef,0xcb,0xb7,0xda,0x56,0x66,0x2a,0x73,0x09,0xd1,0x0a,0x6c,0x4a,0x4f,0x7f,0x29,0x92,0x78,0xd5,0x1b,0xbd,0x11,0xe0,0xcc,0x1b,0x87,0x09,},"\x19\xa8\x32\xf2\x6f\xbb\x02\x39\xf0\xd9\xd2\x6a\x2e\xbd\xed\x24\x03\xc2\xa4\x06\xdd\x1f\x68\x31\x8d\x67\x7a\xfa\x64\xf3\x50\x43\x31\x6a\x5e\xfd\x72\x97\x83\xc7\xf9\xd1\x8c\x09\x82\x46\x14\x65\x20\x91\x88\x6c\xc9\x54\xbe\x9f\x93\x12\xd4\x58\x6b\xf3\x6f\x30\x35\xac\x70\x34\x38\xb0\xcf\xe3\xde\xc5\x07\x78\x13\xc7\x10\xd1\x44\x75\x61\xab\x61\x57\xbc\x7a\xd5\xea\xb5\xb0\xc0\xaf\xdc\xc9\xdb\x77\xe6\x6f\xa8\x07\x13\x66\x82\x9c\x50\x10\x96\xc3\xd3\xa9\x38\x21\x8a\x6e\x42\x07\x10\x9d\x1e\xb8\x1f\x7d\x88\xbd\x6f\xbb\x2a\xef\xb1\xad\xef\x35\x94\xaa\xe5\x7c\x46\xb7\xb9\x84\xdb\x94\x68\xcd\x96\x2c\x61\x84\xfb\x97\x6f\x0e\x2a\xa8\x41\x52\xde\xb1\xc7\x6a\xea\x75\xae\x48\x84\x42\x94\x3a\x80\xba\x7d\x98\xa2\x8c\xb8\x64\xb5\xe8\x7c\xdb\x28\x4a\xd6\xe8\xd7\xaa\xdc\x6b\x75\xd6\x9d\x3b\xd3\x45\x78\x3b\x3e\xbb\x67\x6f\xf9\x5d\x7b\x41\x91\xe5\x99\x85\x1c\x96\x28\x83\x5c\x7c\x01\x19\x7e\x7c\x8f\x86\xf9\xc8\xfb\x49\xfe\x3e\x28\x45\x8b\xa9\xb0\x23\x62\x19\xbd\x46\xc2\x8d\xf6\x53\x24\x96\x99\x4a\xc9\xba\x73\x3c\x01\x05\xa0\x2a\x26\x9a\x2b\xe8\xb7\xcb\x40\x07\x4b\x88\x16\x02\xef\x92\x47\x05\x2d\xe9\xd6\x37\x08\x91\x88\xbd\x4c\x18\x5c\xca\xe2\x58\xa2\xae\x98\x56\xa2\xcb\xf8\x45\x11\x17\x68\x3c\xe3\x41\xf8\x09\x6e\x1d\x91\xe8\x74\xc5\xcb\x8a\x4e\x09\x39\xeb\x77\x37\x3a\x9a\x0e\xb7\x91\x64\x5b\x8f\x54\x60\x47\x2d\x66\x9d\x80\x14\x68\x1a\x5e\x77\x87\x06\xcb\x55\x66\xbb\xd4\x72\x7d\x17\x16\xb2\x3c\x62\x0d\x22\x8b\x5d\x4d\xc2\xb3\x52\xb4\x23\x93\x1f\x8a\x7e\x8f\xb5\x9e\xda\xd8\xae\x42\x45\x87\x29\x86\x1a\x98\xe0\xc8\x50\xa7\x7e\xd6\x55\xe7\xfc\xfe\x4f\xe3\x6f\x97\x72\xdf\x1a\xc3\xc6\x43\xad\x31\xdb\x56\x30\xd5\x71\xdf\x9f\xcc\x9c\x50\xde\x76\x22\x10\x84\x11\x96\x2b\xbf\x72\xde\xfb\xf4\x9e\x99\x70\x59\xc7\x31\x1b\xd9\xdd\xd5\xb3\x38\xa9\x85\x19\x38\xd3\x7e\x7a\x26\x21\x08\xa2\x91\xe2\x01\x68\x03\xbb\xef\xf4\xf9\xc7\x76\x12\x5c\xeb\x7e\x72\x72\xb5\x1c\x7c\x33\x46\x1d\x80\x89\xf8\x40\x8d\x8d\xda\x92\x50\x6d\x50\x02\x08\x4d\x4f\x41\x4d\x8a\x4d\x28\xd3\x69\x4c\x88\x63\x0e\x31\x80\x19\x90\xd9\x52\x71\xce\xf4\x7a\xa5\xc2\x63\xf9\x7b\x7d\xac\xa1\x78\x87\x01\x43\x63\x29\xb5\xbf\xaf\x72\x65\x3c\x16\x6d\xb0\x87\x70\x81\x30\xc5\xc0\xd7\x8c\xc4\xe9\x06\x4f\x86\x06\x80\x27\x1a\xfe\x4c\x40\x98\x53\xc2\xfa\xd6\x75"}, +{{0x5f,0x9d,0xcd,0x93,0xfb,0x14,0x06,0x10,0xb0,0xe2,0x11,0xb3,0x9a,0xdd,0xb1,0xeb,0x87,0xba,0x97,0x80,0x48,0x77,0xaf,0xbc,0xc3,0x81,0x38,0x8c,0xad,0x65,0x08,0x45,},{0x18,0x2a,0x23,0x7d,0x87,0x8c,0x58,0x19,0x33,0x33,0x2b,0x41,0x78,0xb6,0x7e,0xc4,0x08,0xb3,0x19,0x4d,0x44,0xe4,0xe6,0x93,0x92,0xef,0x80,0x0b,0x26,0x7c,0x29,0x49,},{0xc1,0x91,0x5e,0x05,0x2b,0x66,0x47,0x97,0xe0,0xd5,0xfa,0xad,0xc7,0x8f,0x2a,0x00,0x9d,0x6f,0xbc,0xfd,0xe0,0x3f,0x3a,0xaa,0xd5,0x9b,0x9f,0x45,0x88,0xe7,0xfc,0x3b,0x21,0x99,0x0c,0x52,0x08,0xd3,0xd7,0x6b,0x4a,0xa9,0x5b,0xd9,0x34,0xe8,0x8d,0x3c,0x98,0xc5,0x91,0x93,0x0a,0x59,0xde,0x2a,0x05,0x67,0x01,0xd9,0xf7,0x57,0x74,0x00,},"\xc3\x8b\x87\x4d\x3f\xf0\x10\xff\xf1\xa6\x61\x3b\xfa\x13\x42\x57\xb2\x48\x33\xcb\x53\x6d\xe3\xe7\x49\x92\xc3\xcb\x01\xfe\x3b\xbd\xee\xd9\x7d\xc3\xc4\x59\x6f\xa4\x40\x61\x44\x2b\xd3\x1a\x9d\x4a\xa8\xc8\x1e\x34\xad\x98\x88\x71\x82\x06\x63\x55\x09\xb1\x33\xb1\xba\x69\xcb\x1a\xa0\xe7\x5c\x7a\x18\x93\xc0\x80\x16\x1d\x26\x15\x2a\xce\xf4\x0f\x6e\xf4\x21\x0e\x95\x2a\x49\x82\x8b\x5c\xdd\xe8\x04\xbc\xb5\x36\xcd\xc3\x49\xa8\xe8\x31\xb4\xb6\x9d\x37\x85\xa7\x6b\xd9\xfb\x27\x08\x05\x65\x97\x2d\x0b\x8f\xbd\x16\xf3\xf9\x60\xa6\xbf\x3b\xa0\xc5\xb9\xc4\x04\x96\x7e\xc1\xaf\xfe\x59\xb8\xc4\xec\xc6\x50\xfd\xde\x1c\xb0\x6b\x70\x59\x5a\xd4\xd3\x25\xda\x0f\xab\x4c\x55\x40\xa7\xa8\xd5\xeb\xea\xcc\x4e\x99\xbd\x0d\xc9\x6b\xde\x82\xf2\xbd\x7d\x95\x86\x30\x84\x65\xe5\x5b\x1c\xc3\x88\xd7\x50\x48\x6b\xdd\x5c\x72\x64\xd5\x4f\x56\x14\xd4\x87\x26\xd9\x9e\x44\xd7\x77\x8d\x9e\xd0\x32\x39\x58\xab\x98\x58\xe2\xb2\x5d\xf2\xbf\x99\x4b\xa3\xe6\x25\xe2\x80\x3b\x6c\x69\x31\xe7\xa9\x92\x6f\x1e\x61\xed\x86\x24\x03\xce\x39\x2a\xb8\x3b\x7d\x1b\x66\x08\x5d\xcc\x06\xd8\x2d\xbf\x17\x6d\x01\x6d\x9f\x44\xcd\xcb\x50\x72\xd0\x04\x59\x1e\x92\xd0\x45\x9e\xf0\x5a\x51\xb8\xf5\x4b\xa1\x72\x51\xe1\x66\x21\xeb\xb7\x53\xe5\xb1\x59\x0c\x02\xd2\x1e\x40\xf4\xb7\x5e\xee\x46\x02\x86\x0b\x97\x41\xfb\xbc\x0d\x2e\x38\x5b\x8d\xac\xa8\x3c\xce\x68\xc3\x4a\x99\xbd\xe6\xa6\x0d\x13\xba\x64\x34\x7d\x0a\x38\xd6\x4b\x2a\xde\x25\x0f\x38\x85\x2c\x4e\xda\x2e\x2e\x4f\x30\x3c\x3d\xe1\xa8\xa9\xd4\xab\x33\x00\xc9\xe6\x36\x22\x87\x9f\xc8\x53\x7f\xfc\x63\xb1\x85\x61\xfa\x1f\xff\x65\x53\x12\x41\x51\x5a\x62\xbb\x9b\x08\xb8\x0a\xf3\x76\x67\xa6\x01\xae\x04\x17\x17\x93\xcc\x83\xb1\x1a\xdf\x9c\x30\xca\x9f\x4d\xab\xc7\xb4\x01\xe1\x6a\x18\x14\xcf\xc7\x50\x24\x8c\xc2\xf7\x7e\x03\xf9\xc4\x33\x44\x65\xff\x6a\x2c\x83\xcb\xb5\x6d\xb4\xb7\x34\x75\x10\x43\x83\x2c\x40\x00\x97\x2e\xe3\x23\x2f\x92\x9f\x23\x33\x7e\xba\x5e\x65\x1e\x34\xcb\xdd\xfe\x68\xba\x21\x9b\x63\x2e\x7a\xcd\xbd\x46\x30\xa0\x31\xbf\x16\x89\xfb\xbc\x7f\xbb\xb2\x10\xdb\xf2\x5e\xe8\x7e\x2e\xf2\xb3\xcb\xaf\x8d\x9e\xbd\x8f\xc9\x2c\x3a\x58\xd3\xc0\x5b\x13\x85\xa7\x6c\x87\x79\x1d\x7c\xd3\x74\x1b\x71\xb6\xc3\x29\xde\x9a\x9d\x75\x08\xa0\xc1\x56\xa9\x52\x1a\x90\x20\x56\x30\x99\xa8\x2b\x87\x70\xae\x9a\x94\x4a\x7e\x94"}, +{{0x92,0x5e,0xbe,0x04,0xc6,0xea,0xc4,0x9b,0x26,0x73,0x8d,0x6c,0x13,0x00,0xf3,0x1f,0xd4,0x82,0x84,0x78,0xcb,0xe9,0x7d,0xab,0x18,0xbb,0x88,0x96,0x42,0xe1,0xe1,0x10,},{0xcd,0x72,0x31,0xb6,0xeb,0x74,0xe1,0xfe,0x9f,0x92,0x6f,0x00,0xd8,0xde,0x2c,0x51,0x3d,0x49,0x64,0x05,0x25,0xb0,0x79,0x5c,0xab,0x89,0x3d,0x0c,0x89,0x29,0xe3,0xe0,},{0x2c,0x4d,0x69,0xbe,0xd5,0xad,0x8b,0x95,0x84,0xd8,0x49,0xcf,0x3d,0xf2,0xba,0xc7,0x22,0x82,0xb5,0xf3,0x0d,0xe2,0x66,0xb1,0x4f,0x53,0x3c,0xa9,0x6e,0x95,0x50,0xc4,0xb8,0x54,0xc1,0x54,0xbd,0xc1,0x7a,0xa8,0x80,0xcf,0x00,0x1a,0x64,0x54,0xff,0xaf,0xaa,0x2e,0x50,0x17,0x8d,0xe2,0x12,0x16,0xed,0x12,0x6b,0x63,0xf7,0x7f,0x2d,0x02,},"\xe6\xc0\xba\xd2\x3a\x92\xae\x8b\x1d\x85\x77\x82\x88\x15\x7a\xc6\xc6\x17\xc6\x33\x63\x34\x1d\x77\x78\x70\x34\x1b\xb1\x0a\x8d\x3d\xfc\x89\xbe\x4f\x55\xad\x4f\x64\xe8\x3b\xf2\x49\x9b\x69\xfd\xf7\x21\x74\xd2\x84\x4e\x6b\xd2\x89\xda\xaa\x03\x5f\xec\x5b\xf7\xcf\x45\x52\x21\x19\xdc\x7a\x8c\x81\x1d\x79\x57\x8c\x5b\xb0\xf6\xd3\x4d\xb5\x07\xad\x1f\xb6\xdb\xff\xf9\x97\xb7\x9d\xac\xfb\x3d\xa5\x0a\x41\x5e\x35\x0c\x99\x8c\x0a\x02\x80\x0a\xa5\x0f\xfd\xfe\x5f\x42\x76\xd8\xe6\xbb\x82\xeb\xf0\x47\xfe\x48\x71\x1d\xaf\x7a\x89\x3b\xdc\x75\x37\xbd\xae\xdf\x3d\xcb\x4d\xec\x5d\x24\x58\x68\x11\xf5\x9b\x25\xb1\x9e\x83\xca\x61\xe5\x59\x2f\xed\xc0\x8c\xa5\x44\x73\xce\xa2\xec\x12\x1b\xaa\x0e\x77\xfb\x2d\x9d\x76\x56\x57\xde\x67\x98\x0e\xd5\x7f\x2f\x17\x78\x58\xb6\xde\xcf\x84\xff\x90\x21\x2d\x96\x47\xf4\x1e\xed\x9b\x9d\x0e\xa3\xd8\xd6\x21\xe4\xbb\x40\x41\xac\xc5\x14\x6e\x96\xdf\xcf\x14\xea\x96\x2d\x30\xc8\xcc\xb3\x9e\xa2\xbe\x95\x8c\x9b\x87\x74\x45\x1b\xfe\xb7\xdd\xce\x71\x6e\x94\x92\x3c\xc8\x5f\xbd\x3a\x31\x30\x78\x0e\x2b\x3b\x2b\xb7\x6d\xa5\x34\x19\x12\xa4\xe9\x94\xca\xfa\x19\xbb\xa1\x97\x32\xf2\xea\x40\x2d\x71\xd3\xd8\xa9\x69\x67\x9b\x9d\x10\x42\x43\xd9\x83\x9c\x69\xee\x9e\x95\x5e\x1c\x60\x44\x97\x88\xd1\xf4\xf6\x65\x1f\x4b\xc9\xb9\x4d\x73\x52\x2e\xc0\xcf\x72\xca\xcf\xcf\x19\xf1\xf0\x3a\xd6\x23\x21\x04\xb5\x5c\xbb\x8b\x5b\xb1\xe2\x13\x44\x71\x3d\x48\x27\x42\xd6\xab\xc5\xa9\x57\x17\x4f\x62\x3b\x84\x95\x27\x2c\xc1\xe2\xb8\x31\x5e\x5c\x80\xf9\x47\xf5\x00\xc8\x3d\x85\x44\xf7\xcd\x4f\x65\x34\x89\x49\xef\x44\x20\xd7\xfc\x83\x1f\xa4\xae\x2e\xe1\x8d\xbb\xa6\x14\x92\x5c\xe1\xd7\x67\xc1\x77\xa6\x26\xc4\x52\x7a\x81\x54\xb5\x72\x92\x18\x6b\x04\x4c\xbf\x92\x89\x42\x53\xb0\x0f\xd9\x34\x3f\x9e\x69\x7b\x14\x12\xeb\xa4\x35\x97\xeb\x72\xa6\x69\xaa\xa2\xd7\x7e\xac\xb9\x68\xc2\x0f\xe1\x95\x05\xa3\x80\x74\x15\x86\x21\xb6\x06\xf7\x7d\x97\xbc\x6e\xbe\x50\xe7\x58\x92\x93\xdb\x27\xfc\x7d\xfe\x63\x1a\x4b\xee\x83\xb2\x26\x82\xa7\x73\x28\xc3\x6d\x9d\x7d\x1d\x89\x1d\x65\x21\x7c\xc4\x78\x64\xf6\x80\xdc\x8b\x5f\xd1\xa0\x1a\x0f\x7c\x34\x43\x0f\x77\x06\x0b\x69\x1a\x1a\xd2\x13\xd2\x28\x68\xe6\x1b\xbd\x38\xf4\x3f\x0c\x8b\x4d\xa6\x8a\x58\x31\x86\x66\xc0\x99\x76\x61\x70\xc2\xdb\x76\x6a\xaf\x41\x7f\x55\x6c\xc9\xa0\xa3\x93\x4e\x9f\xce\xf1"}, +{{0x4d,0xd3,0xb4,0x78,0xeb,0xdc,0x59,0x47,0x2b,0xab,0x14,0xa8,0xcd,0xd0,0xc2,0xfd,0xac,0x57,0x23,0xee,0x04,0xdd,0x89,0x17,0xc7,0xcf,0xe7,0xa5,0x36,0x48,0x5c,0x77,},{0x5b,0xcc,0xb3,0x7e,0x68,0xc2,0x34,0xbe,0xad,0x49,0x33,0x7d,0xe2,0x08,0xaf,0xba,0xf6,0x11,0x81,0x1d,0x96,0x58,0x59,0xa0,0x6d,0x31,0x30,0x12,0x47,0xd6,0x6a,0xcf,},{0x57,0x88,0xe7,0x9e,0x84,0x3b,0xde,0x9e,0xf1,0x1a,0x9d,0xfa,0xc9,0x70,0x19,0x6a,0x56,0x7c,0x63,0x08,0xc3,0x48,0xe5,0x17,0x4b,0x38,0x77,0x95,0x04,0x6d,0x59,0x0a,0x47,0x49,0x1f,0xd7,0x1d,0x97,0xae,0xaa,0x78,0xc1,0x61,0x59,0x71,0xb8,0x34,0x90,0xe8,0x59,0x28,0x20,0xf9,0x59,0x2a,0xc7,0x62,0x69,0xb9,0xd2,0xba,0x70,0x29,0x01,},"\x1c\xdb\xd2\x85\x56\xec\x44\xe8\x70\x5a\xfd\xa9\x2b\xd5\xa5\x3f\x95\xd8\xfe\x8b\x0f\xfe\x46\x33\x73\x63\x33\x16\xc5\x22\x74\xc1\x1e\xdc\xd6\x15\x51\xe3\x19\x9e\x49\x4d\xff\x6d\x90\x6a\x73\x9e\x7b\x32\x43\x03\xfc\x47\x82\x7e\x56\xde\xf0\xbd\xcc\x46\xb8\x16\x01\x7c\x71\x23\x05\x37\x02\x63\xba\xbd\x2c\x71\xbe\x47\x8f\x41\xce\x30\xb1\xdf\x63\xbe\xdd\x3b\x2e\x6a\x51\x9c\x53\xdf\x51\x58\x52\xc4\x13\x7b\xc1\xac\xa4\x9b\xf4\xc4\x63\x1f\xd6\x56\x46\x57\xd1\x1c\xd8\x3e\xa7\x3c\xc3\xd0\xcf\x9e\x3b\x3c\x3e\x7c\xa9\x9b\x4f\x12\xa9\xc9\xb6\x7c\x87\x98\x14\x8e\x0a\x0d\xc1\xef\x8b\xf5\x86\x42\xa1\x4f\x97\xa5\x72\x13\x55\x14\xc1\x0b\x19\xaa\xbe\xc2\x5a\x9c\x6b\x35\xaa\x40\x34\xa5\x7a\xae\x1b\x6d\x05\xbd\xe2\xb6\x33\x0f\x25\x1d\x78\xdb\x09\x93\xf0\xca\x4c\x26\x38\x6e\x34\x89\xa2\x09\x28\x33\xb8\xac\xbb\xc4\xf4\x91\x7f\xd3\x09\x3d\xf5\x82\xff\xf7\x1e\xce\x21\x9d\x36\x72\x45\x55\x82\x60\x9c\x0d\xb8\xd9\x6a\x70\xfc\x8a\xed\x67\x98\xde\x54\xbf\xb2\xb3\xee\x6c\x5d\x32\x8d\xb1\x63\x59\x3f\x58\x01\x9f\x38\xf3\x39\xfd\x37\x53\xf8\x96\xa4\xa2\xcc\xa8\xc1\x40\x0a\x77\xea\x39\x19\x35\xf3\x4e\x26\x39\xc5\x60\x86\x08\x10\xbb\xbe\x4b\xe1\xd1\x6e\x01\x2c\x11\x49\x0a\xa8\x4f\x29\x64\xc8\x77\xc2\x93\xb3\x00\xf4\x3d\x37\x9f\x3e\xba\x9a\xf3\x91\xde\xe5\x10\x85\x6a\x4d\xdc\xf7\x6e\x0a\x0a\xe0\x6a\x6a\x7c\x0f\x9c\x5e\x3f\xa1\xb8\x35\x4f\xe8\x97\x7b\x4e\xa3\xb2\x06\x61\x49\x1f\xa4\x61\x3b\xa6\x2f\x55\x6d\x5d\x5d\xa8\x21\x3d\x01\x21\xde\x2c\x87\x25\xdf\x0a\xae\x04\x8a\xc8\x91\xab\xbc\x06\xbd\xce\xf3\xc3\xef\xfd\xf5\xa3\x17\x49\x47\x6f\x81\x4d\xb9\x45\x79\x45\xf0\xd9\x1e\x14\x08\x00\x56\xbe\x92\x1a\x16\xaa\x96\x4a\x92\x98\x22\x1b\x15\x75\x94\x97\x3e\x32\x96\x99\x93\x31\x0c\x87\x07\xe1\x9f\x31\x43\xab\xc4\xfd\xa7\xc8\xad\x01\x60\xac\xf0\x31\xab\xa6\x52\x80\x1a\xa8\x1a\x01\x6b\x31\x37\x03\x9e\x27\xd6\x73\x8d\x02\x80\x0a\x93\xa8\x6f\x9f\x55\x85\xc5\x18\xdf\xa9\xe7\xd8\xac\x72\x7f\x37\x43\x7e\x56\xd2\x78\x83\x86\xe1\x16\x53\xa0\x4e\x16\x51\x69\xf9\x03\x97\x2a\x01\x48\x47\x51\xe7\xcb\x38\x63\x25\x90\xec\x80\xd5\xfc\xe4\x54\x16\x01\xa0\xe0\x95\x78\x5a\x9e\xe8\xd3\x59\xed\xf2\x6b\x99\x46\xe7\x98\xda\x59\x98\xcb\xb7\x36\xf9\x4e\xb7\x13\x46\x3f\x79\xf5\x61\x75\x9b\xbc\xb4\xc4\xac\x69\x3c\xab\xf2\xe1\xe0\x36\xb2\xd0\xb0\x87\x9a"}, +{{0x07,0x4d,0x92,0x18,0xc1,0x21,0x7e,0x75,0x82,0x3c,0x90,0xe0,0x10,0x48,0x4c,0x2a,0xdb,0x88,0xec,0xcc,0xd2,0xbd,0xf0,0x12,0x0a,0xa3,0xed,0xff,0xcf,0xcb,0xd4,0xbf,},{0x37,0x35,0xad,0x19,0x19,0x03,0x3d,0x16,0x17,0xb8,0x5b,0xda,0x04,0xb1,0x61,0x21,0xda,0x1d,0x86,0x1b,0x40,0x41,0x54,0xfa,0x96,0x1d,0x49,0x46,0xe5,0x5e,0xcd,0x83,},{0xb1,0xf7,0x1c,0x3b,0xd1,0xb6,0xbe,0xc4,0x33,0x37,0xe2,0x6d,0xee,0x65,0x5a,0x8d,0x5f,0x4a,0x8d,0xad,0x84,0xa5,0x11,0x84,0xb7,0x75,0xb6,0x86,0xfa,0xd3,0x1d,0x80,0x29,0xe3,0x87,0x69,0x27,0xf9,0x57,0x6e,0x90,0xc3,0x62,0x48,0x75,0xfc,0x00,0x29,0xa5,0xc1,0x0a,0x8a,0x0a,0xf7,0x5d,0x7a,0x88,0x0c,0x68,0x44,0xa4,0xa8,0x3a,0x00,},"\x6b\x5a\xa4\x0e\x91\x67\xbf\xdb\x84\x7d\xaa\x7d\x27\x86\xe2\x8e\x75\x33\xe1\xd6\xac\x53\xbe\xb6\xf6\x9b\x59\x53\x79\x5a\x2b\xf5\x9b\xbf\x7d\x14\x19\x26\x96\x8f\x50\x96\x9b\xad\x74\x2a\x4f\xb5\x79\xd3\x25\x0f\xb1\xbe\x4c\x57\xeb\xf4\xf9\x11\x2c\x70\xcd\x9f\x72\xa0\x0d\xb1\xc8\x89\x6f\xe2\xb5\xbd\xa7\xc7\x03\x0f\x49\x7c\x0b\x00\x1e\xa2\x5b\xa0\xd4\x47\xf0\x8c\x36\xdb\x8b\x90\x7c\x2f\x2a\xbb\xbb\x62\x0d\x3e\x8a\x2c\x66\xe4\x17\x12\x85\xad\xca\xad\xd1\xc1\x4f\xe2\x39\xbc\x59\x5f\x09\x83\x96\xaa\x87\x80\xff\xb8\x0f\xe1\x44\x6a\x07\x00\x1e\xc2\x34\xd8\x2a\xbd\xcd\x81\x00\x79\x39\x15\xb0\xb3\xf8\x0d\x84\xe2\x0e\x51\xea\xbc\x79\x78\x06\xf3\xbe\x81\x08\xa4\xf4\x37\x55\x0b\x06\x69\x40\x50\xa8\x29\x31\xac\x40\xc0\xa4\x89\x77\xed\xf6\xce\xd2\x42\x8d\x7c\xfe\xa8\x20\x55\x06\xde\x86\x40\x80\x65\xd1\xa1\x98\x70\xfa\x33\xa7\x08\x10\x37\xb3\xee\x44\x91\xb6\xe7\xf3\xd1\x0b\x14\xa3\x0c\x20\x91\x59\xa1\xc8\x12\x31\xa3\x5f\x03\x65\xb4\x7d\x3e\x0d\xa0\x4a\x32\xc9\x5d\x98\x33\x3c\x44\xf5\x72\xcd\xaa\xa9\x05\xd0\x69\x19\x7f\x6e\x86\x1b\x5d\xfc\xdf\xb9\xdb\x6c\x7b\x0d\x0c\xb0\x0f\x37\xc9\x16\xa1\xc4\xc0\xb8\x98\x5b\x09\xf3\x34\x09\x5e\x12\x83\xed\xfd\xd4\xe6\x2a\x29\x41\x09\x9a\x2b\x69\x36\x96\x60\x4d\x99\x43\x11\xe3\xd5\xf6\x10\x66\x83\xe1\xd7\xa1\xc7\xe5\x3d\xf7\xb7\x90\x94\x7a\x9a\x80\x1a\x0c\xcd\x48\x43\x95\xf6\xcb\xfd\x9c\xa4\xd9\x80\x4f\x18\xd5\x2b\xb0\xf9\x46\xd1\xa8\x9f\x97\xa6\xfb\x06\x80\xa8\xc4\xc0\x57\xb6\x06\x2b\x2b\x9d\xe7\xc0\x37\x48\x79\xb8\xa6\xa6\xd2\xc1\x0a\xef\x78\x05\x08\xeb\x28\xbb\x56\x9a\x08\x35\x09\x44\xc8\x2f\x6e\xf2\x8d\xb2\x30\x4d\xb6\x97\xc3\xae\x1a\xf4\x3a\x50\x0b\x0b\x97\x48\x03\xe9\xf4\x6e\xa2\xa0\x2e\x85\xed\x27\xdd\xa6\x16\xd2\x4d\x6d\xb3\xcc\x4f\x5a\xed\x82\x40\xb1\xae\xa3\xdc\xf6\x9d\xee\x5f\x14\xf9\x5e\x6e\x72\x98\x7b\xbe\x61\x89\xbc\x20\x45\xf0\xd7\x83\xa7\xb4\x7b\xfc\x19\x83\x0b\xc7\xf4\xe7\x98\xab\xe9\x02\x45\xfb\xd4\x3f\x37\xc3\xf0\x36\xd1\xcb\xf1\xe7\x3d\xcb\x1d\x9d\xaa\x87\x37\x9b\x11\x06\x97\x34\x81\xa2\x15\xc1\xf4\xf4\x6c\x16\x03\xa5\xd5\xcd\x97\xb7\x07\x6f\x1f\x5d\xc7\x89\xaa\x6a\x71\xe7\x2e\xf5\x4e\xd3\x28\xa4\xab\x64\x34\x05\x39\xff\xd1\x64\xd0\xec\x64\x5f\x32\x2d\x1b\xc3\x71\x12\xdc\x08\xd8\xc8\x07\x9d\x19\xd3\x7a\xbb\x23\x53\xf4\x8b\x5c\x49\x2f\x80\x6e\xd2"}, +{{0xd2,0xea,0x2d,0xff,0x7a,0xf0,0xba,0x2a,0x6b,0xed,0x7f,0x6c,0xc6,0x8c,0x0d,0xf6,0x64,0xa6,0xb1,0x0c,0xe8,0x01,0xc4,0x2e,0xd5,0xbb,0xe6,0x17,0xbc,0xc8,0xb8,0x4a,},{0xab,0x44,0x70,0x63,0x44,0x02,0x6e,0xd3,0x5e,0x21,0x98,0x29,0x64,0xf7,0xb4,0xdb,0xbb,0xe2,0x07,0xfd,0x27,0xc4,0x67,0x99,0x70,0x1c,0x19,0xa4,0xd8,0x8d,0x1d,0x72,},{0x9a,0xbd,0xb9,0xdd,0x2a,0xb7,0x7b,0x6f,0x5e,0x1b,0x91,0xba,0x0b,0x61,0x3f,0x5f,0x36,0x0e,0xfb,0x50,0x0d,0x3f,0xe9,0x92,0x90,0xef,0x7c,0xa1,0x4b,0xd2,0xb3,0x30,0xf4,0x05,0xa4,0xf7,0xdc,0xda,0xef,0x49,0x23,0xd3,0x11,0x1d,0x40,0xbf,0x03,0x20,0x35,0x33,0x86,0xf6,0x34,0xb4,0x0d,0xe6,0xf0,0x4d,0xe9,0x19,0x0a,0xd5,0x1c,0x08,},"\x03\xab\x5d\xae\xbc\x6e\x70\xd3\x52\x97\x79\x32\xa0\x31\x07\x87\x9b\xd5\x5d\xaf\xd0\xc6\xba\x7a\xd9\x69\x7a\x17\xb1\x27\xb3\xa7\x4a\x3e\xae\xba\xbd\x0f\x8e\xee\xbf\xc0\x48\x3d\x63\xfe\xdd\xe5\x2d\xeb\x46\xa3\x75\x24\x49\xc9\xc4\x49\x5c\x51\xa1\xc9\x1f\x57\xe3\xad\x2e\x6d\x01\xa1\x3d\x0c\x47\x0c\x52\x91\xb8\xe9\x12\x28\x83\x40\x97\x0f\xbb\x85\x78\x7b\x8b\x37\x6d\x72\x17\x52\x50\xe8\xcd\x90\xc0\x78\x88\xbf\xef\x5e\xbf\x50\x86\xc8\xff\x2a\xbc\xdd\x12\xd2\x14\xb9\xc4\x5d\x12\x08\x73\xb4\x60\x2e\x57\xa6\xaa\xb0\xb8\x28\xd1\x08\x4d\xff\xaa\x36\x51\xee\x35\x66\x26\x95\xb7\xf3\x43\x3f\x4a\xb5\x30\xc2\x9a\xc6\xcc\x5b\xb4\x3e\xcc\xd1\xb6\x89\x8b\x9e\xf7\xae\xc6\xd5\xae\xc6\x8d\x5c\x11\x14\xbb\x5d\xf7\x82\x09\x66\x59\x4c\x99\x4d\x64\x08\x91\xb8\xf2\xdc\x5d\x25\x63\x8d\xe4\x35\x49\xd8\x6d\x34\x30\x6f\xf3\xf5\x74\x57\x51\x16\x40\x5b\x9e\x8e\x28\x6e\xe0\xcd\x97\x8a\x76\x00\x2c\x44\x35\xfe\xaa\xc6\xe8\x4e\xae\x16\x54\xf3\x39\xa5\x67\xd8\xd0\x4f\xcf\xa3\xeb\x6a\x04\xb9\xad\xc6\x66\x02\x13\x00\xe9\xee\x59\x72\xb3\xdf\x5d\x4d\x0d\xd4\xbf\x79\x21\xdc\x98\xde\x82\xce\xf2\xd1\xb1\xd6\x1b\x79\x7f\xc9\x96\x8e\x11\x84\x84\xc4\x13\x42\x41\x6d\xdc\x6a\xdc\x4e\xe5\xd6\x87\xd9\x4a\x40\xce\x57\x2f\x42\xa2\x04\x86\x68\xc1\x75\xcf\x7b\x1f\x24\xc4\xef\xd0\x20\x55\x4f\xc6\xf6\x42\xe1\x4a\x57\xba\xec\x23\xe9\x5c\x25\x14\x30\x6d\x0a\x6d\x33\x64\x88\x41\x49\x7e\xac\x48\xea\xbd\x96\xd0\x47\x31\xba\xb0\x8b\xf5\xea\x9d\x43\xe0\xcf\x9a\x37\xfa\xaf\xa7\x32\x86\x9d\x68\xe7\xd5\xfe\x69\x54\xf8\xa3\x19\xef\x55\xda\x1e\x17\x8e\x43\xe8\x4a\x3b\x9a\xa3\xad\x00\xc2\x9b\x1d\x16\x11\x63\xdf\x4b\x79\xf2\x88\xe9\x39\x1d\x70\xa2\xf8\x81\x3d\x66\x62\x2e\x8a\xc3\x33\xfa\x6a\xa5\x31\x1e\xab\xec\x38\x3b\xa4\xcc\x12\x28\x15\xde\x00\x88\x77\xef\xbe\x6e\x12\xc3\x22\xc9\x75\x43\x4a\xfa\xd1\x73\xeb\xe2\x42\x03\xd9\x16\xd5\x75\x78\xbd\x2b\xca\xcc\x78\xf6\xe2\x56\x45\x13\xf8\xd1\x13\xa8\x33\xc2\xc2\x26\xeb\x97\xba\x2e\x23\x36\x1a\x5d\x02\x66\x4a\xb3\x77\xf9\x64\xc4\x30\x0b\xe2\xd7\x7b\x62\xd9\x24\x08\x23\xa0\x98\x84\xdf\x30\x7e\xff\x3b\xe5\x66\x4d\x72\xd1\x1a\xd5\x13\xe1\xbc\x56\x10\xdb\xfd\x10\x09\xdb\x39\xf0\xcb\xfe\x47\x05\x55\xec\x1b\x56\xb8\x71\x67\x07\x93\xd3\xb7\x04\xfb\x06\xee\x95\x0b\x1a\xd2\xa4\xd7\x29\x7c\xa5\x8b\xba\xd8\x10\xc3\xfa\xd4"}, +{{0x7a,0x60,0xcd,0xf1,0x87,0x04,0x60,0xde,0x8a,0xe7,0x78,0x11,0x76,0xd5,0x12,0x7e,0x71,0x20,0x7f,0xaf,0x2f,0x21,0x0b,0xd4,0xdc,0x54,0x73,0x85,0xb6,0x67,0xf2,0xf2,},{0xea,0xd6,0x7a,0x9c,0xf3,0x4d,0x0f,0xf1,0x4e,0x79,0xaf,0xa4,0x6f,0x2d,0xc9,0x96,0xe9,0xac,0x0e,0x3e,0x07,0x63,0x22,0xfb,0xb4,0x00,0x97,0x67,0xb1,0x33,0xf0,0x1b,},{0xb2,0xe0,0x81,0x42,0xbd,0xd6,0x2b,0x78,0x65,0x92,0xc0,0x91,0xf5,0xfe,0x6a,0x9b,0x7f,0x30,0xce,0x13,0x4c,0x3b,0x23,0x6f,0xbc,0x6d,0xfe,0x67,0x34,0xf8,0x82,0x70,0xac,0x58,0xf6,0xd7,0x4b,0x4f,0xd9,0x9c,0x22,0x45,0x1c,0xa4,0x65,0xa4,0x2c,0x00,0x6d,0xb2,0x5a,0xf2,0x15,0xed,0x24,0x1a,0xf1,0x18,0x96,0x27,0xc6,0x05,0x0f,0x00,},"\x9d\xc0\x23\xa5\x25\xd0\x1b\xa3\x51\x37\x98\xb7\x38\xc7\x91\x62\x92\x6e\xbc\xcc\x0a\xdf\x1e\x57\xac\x47\xc2\x0d\xea\x6c\xe1\x37\x5c\x3d\x2a\xaa\x17\x33\xb7\xf0\xc3\xbd\x94\x5c\x33\x5f\xf3\x57\x61\x12\xbb\xdc\x10\xb6\x78\x3b\xa6\x54\xe8\xc6\x10\x47\xf2\x77\x3a\xa2\x29\xbf\x84\x69\x22\xa8\x9c\x6a\x73\xd5\xf1\x05\x1e\x8d\x96\xed\x36\xd7\xd6\x74\x7e\x06\x3a\x7a\xc6\x02\xf1\x9f\xc5\x2e\x02\x1a\x4b\xbc\x28\xb0\x35\x14\xfb\xd5\x1c\x7b\x3f\xd6\x59\xf1\x2d\x54\x7d\x05\x92\xdd\x09\xf8\x73\xc9\xec\xc6\x43\x9c\x7e\x93\x1a\xd0\xe4\x85\x6b\xe3\x1c\x60\x5d\xef\x2e\xd9\xb5\xd1\x3c\x59\x42\xb2\xf3\x25\x39\x7d\xac\x6c\x97\x60\xe9\xb1\xbb\x0c\x06\xf7\x13\xcb\x92\x0c\x23\x4b\xcc\xfe\xe9\xf0\xb8\x5d\xd0\x20\xf7\x98\x8f\x3b\xe1\xcc\x66\xe9\xe5\x1b\xab\xe2\xfe\xe2\x37\xeb\x84\xec\x7e\xff\x94\x09\xaa\x91\xc1\x94\xe3\x0d\xb1\xe0\x65\x01\x59\x55\xde\x97\x46\xbb\xa0\x3f\x7e\xdf\x9a\x58\x75\x12\x40\x9a\x41\x61\xfa\x77\xea\x62\xcc\xf4\x31\x60\x2d\xcd\xcf\x36\x5e\xd6\xbf\x0a\xed\xdd\x32\xf7\xc8\x44\xe3\xa3\x4d\x26\x6e\x28\x38\x2f\x40\x62\xfd\x4d\x6f\x82\x14\x25\x21\x04\xd6\x43\xa9\xbf\xd8\x07\x17\x16\x37\x1c\xcb\xb5\x4c\x8c\xc8\xdb\x79\xad\xd6\x5b\xcb\xce\xa0\xd0\x80\xd8\x40\x28\x03\xfe\x23\x2d\xf7\x0f\x76\x57\x72\x47\xa6\x3d\x55\x83\xbb\xd5\x64\x27\x67\xbc\x63\xf3\xc5\xa7\xbb\x3a\x47\xeb\x12\x98\x4e\x45\x41\xf4\x1f\xdb\x55\x86\x9a\x08\xfa\xde\x66\xc2\x0f\x69\xa5\xa9\xde\x25\xf6\xb3\x6b\xa1\x8a\xce\x5b\x4a\xc3\x36\xbb\x2a\x8e\xbf\x63\x0a\xd0\x3e\x8b\xb8\x73\x1d\x01\xe8\x4b\x91\xd0\x24\xd1\x17\x45\x9a\x74\x89\x2e\x93\xd5\x3b\x61\xe6\xb8\x06\x8e\x4f\x04\xb4\x18\x1f\x03\x87\xb4\x56\x7c\xcd\x45\xe1\xb8\x71\x8a\x2d\x7d\x78\x78\x72\xf3\xdc\xf8\x7a\x15\x93\x5a\xd7\xda\xaa\x74\x4e\xd6\x8a\x28\x66\x6a\x51\xa1\x0d\x39\xfc\x13\x9c\xdf\xe9\xa6\x87\x30\x76\xf7\xc4\x25\x00\x9c\x38\xfa\xee\x13\x5e\x51\x32\x07\xb0\x6e\x7b\xa3\x56\x85\xf5\x07\x2d\xa3\x4b\x60\x45\xb5\x7c\xd5\xd1\xb1\xa1\xfd\xf0\x17\xb8\xaa\x8e\xbd\x27\x52\x2b\xc9\x5e\x47\x90\x87\x34\xe4\x17\x22\xa7\x67\x90\x5c\x5e\xcc\x30\xc7\x24\x81\xb6\xc1\x2b\xf4\xac\xe9\x4d\x5b\xb3\xa3\x15\x56\x91\xb7\x07\x5b\x40\xeb\xf5\x96\x8f\xdd\x90\x3d\x8f\xd3\xcc\x50\xb8\xd6\x46\x48\x59\xb1\x0f\x75\x51\x32\xc6\xd9\xb6\xda\xd1\xd6\xf1\x4c\x41\x85\xb2\x64\xd3\x49\x7a\x4e\x54\x98\x77\xfe\x94\x6e"}, +{{0x33,0x79,0xd2,0x5c,0x11,0x17,0xcf,0x80,0x2e,0xc7,0x9c,0x06,0x57,0x5d,0x18,0xe6,0xbe,0xce,0x4c,0x70,0x93,0xdd,0x43,0xfd,0xee,0x03,0x68,0x5c,0x70,0xb2,0xfa,0x9f,},{0x85,0x25,0x15,0x6f,0xe2,0x9f,0xc2,0xfb,0xf6,0x61,0xba,0x50,0x18,0x2b,0xe2,0x0c,0x89,0x98,0xd9,0x41,0x49,0x3d,0x59,0x33,0xdc,0xa4,0xd8,0xb4,0x1f,0xb4,0x42,0xd5,},{0x4c,0x36,0xbf,0xc8,0x1e,0xef,0x00,0xb9,0xcb,0x3a,0xb5,0x14,0xc6,0xd4,0x51,0xb9,0x93,0x36,0x1e,0x09,0xa4,0xbe,0x4b,0x50,0x40,0x92,0x6f,0xeb,0x0e,0x0d,0x9b,0x52,0xf0,0x3d,0xe4,0x68,0xe7,0xba,0xd8,0x3f,0x37,0x91,0x54,0xbf,0x2c,0x43,0x7a,0x71,0xf7,0x54,0xf3,0xf4,0x07,0x98,0xee,0xeb,0xd6,0x2e,0x55,0xf2,0xbe,0x77,0x14,0x03,},"\x7a\xcd\xb3\x9f\x12\x26\xbd\x3a\xbf\xfa\x50\x35\x0a\x14\x97\xd7\x61\xf8\xf0\xaa\xef\xbf\xbb\xbb\x92\x5f\xf5\x63\xe3\x89\x76\xaa\x17\x2d\x40\x7b\x61\xff\xdf\xb1\xcd\x53\x8a\x4c\xd0\x00\xb5\x78\x18\xa0\xbc\x92\xc0\xe0\xcd\x0a\x5a\xbf\xcf\x57\x83\x00\xf5\xf4\xe6\xce\xfa\x26\x72\x75\xd1\x78\x45\xda\x70\x66\xfd\x4e\x18\x01\x00\x27\x96\x0c\xd3\x95\xe6\x82\xad\x71\xaf\x34\x9b\xbd\xad\x5e\xba\xa0\xf1\x1a\x77\x61\xe1\x9e\xa1\xbe\xf6\x61\x07\x43\x16\x4b\x17\x14\x14\x53\xb4\x72\xae\x2c\x8f\x36\xce\x6b\x08\x0f\x1c\x07\x45\x35\x24\x54\xce\x5a\xea\xe1\x1c\x9d\x75\xde\x3c\x08\x00\x42\x65\xfc\x4c\xa8\x0d\x33\xb2\x6e\xae\x14\x00\xdf\xd8\x97\x7b\xf7\x23\xa6\x16\xda\xeb\x6d\x42\x19\x90\x10\xb7\x3e\x19\x3a\xb7\x2a\x58\xbd\xd2\x48\xa7\xf4\x11\x1c\xa5\x0c\x1d\xe6\x46\xbf\xea\x7b\x4d\x5b\xaf\x0f\x93\xdd\x97\x3e\xe9\x36\x49\xe2\x1e\xc0\xc6\xc4\xfc\xca\x8c\xd6\xff\x69\xdf\x76\x16\x12\x02\x1d\x85\xff\x1f\xb2\xa9\x53\x37\xda\x48\x05\xa7\x6d\x34\x7e\xe7\x1e\xf1\x9c\x0d\xff\xb5\x9f\x15\xf6\x50\x29\x3a\xbb\x97\x21\x05\x3f\x74\x06\x90\x5a\xe6\x83\xf9\x6c\x83\xa3\xa7\x44\x7b\x1a\xfb\x14\xe1\x20\x8c\x63\x9f\x37\xa9\x75\x0b\xa2\x1d\xa5\x55\x2c\xc2\x04\xea\xc4\x53\xca\x03\x62\x82\xf7\xe0\x96\x10\x93\xc3\x9e\xc1\x18\x13\x8d\xcf\x71\xcf\x2d\x28\xfb\x96\xa2\x49\x62\xb5\x2d\x33\x93\xf8\x80\x65\x3b\xcb\xa2\xc9\xb9\xd5\x7b\x77\xc5\x22\xf4\x21\xfc\xf5\xad\x75\xfb\xa9\xcf\x33\x89\xb1\x23\xaa\x97\x52\x17\x13\xff\xf8\x84\x67\xde\xb8\xc8\x99\x1d\x4b\x57\xc1\x43\x81\x70\x53\x7c\xb5\x0c\xdc\xc6\x57\xe5\x0e\x5c\x48\x0e\x12\xc0\xd4\x49\x39\xb6\x39\x99\x44\xe7\xc7\x1e\x18\x6c\x2a\xbb\x81\xfc\x57\x34\x88\x36\xd5\xe5\x7b\x72\xb2\x24\xa6\xb7\x1b\x6c\xaf\x72\x1a\xca\x73\x47\x8c\xb6\xcf\x5f\xb8\x90\x71\xae\x3a\x39\x82\x02\xdb\xb3\x8c\x30\x81\x25\x63\xbb\x9a\x23\x40\x66\x57\xa9\x56\xd3\x05\xa3\x44\x9a\x60\xcc\x86\x41\xb6\x21\x75\xa7\x17\x0c\x23\xbd\x5a\x25\xf0\xf1\x2e\x15\xa7\xed\x91\xfa\xda\x6a\x4a\x2f\x0e\x7b\x15\x5a\x3d\x64\x85\xec\x03\xce\x6e\x34\xdf\x7e\x21\x62\x40\xbb\x28\xa2\xdd\x73\x2f\xf7\x90\xd2\x28\x6e\x20\x0b\x33\xc2\x9a\x31\xa5\xe1\x9a\xd2\xcd\x02\x97\x4b\xad\xc4\xbc\x22\xde\xb7\x50\x4c\x15\x24\x1f\xc1\x06\x0c\x8a\xce\xf4\xfb\xb2\x5e\xc7\x60\x2f\xce\x36\xa2\x7b\xb8\x7b\x6e\x64\x23\xe6\xb4\xf6\xe3\x6f\xc7\x6d\x12\x5d\xe6\xbe\x7a\xef\x5a"}, +{{0xef,0x38,0xc3,0xfc,0x74,0xf0,0x54,0xae,0x43,0xe8,0xd2,0x9d,0x6b,0xa6,0xdc,0x80,0xb5,0xaf,0x84,0x82,0x70,0xd4,0xaf,0x58,0x84,0x4d,0x24,0xbc,0xf9,0x87,0x41,0x4e,},{0x0a,0xe1,0x47,0x8b,0x05,0xfb,0x32,0x99,0x65,0xea,0x0f,0xa9,0x28,0xdc,0xbe,0x81,0xa0,0xbd,0xbb,0x6f,0xf6,0x6c,0x81,0x16,0x71,0x63,0x5e,0x43,0x88,0x88,0x80,0x51,},{0x1d,0x3a,0xc6,0xb6,0xbf,0x18,0xab,0x53,0x09,0x14,0x87,0x99,0x48,0x5b,0x27,0x6d,0x20,0x40,0x1c,0x6a,0xf5,0xf9,0xb2,0xf6,0x03,0x23,0x95,0xa3,0xc2,0xf4,0xb6,0x73,0xb7,0x14,0x0c,0x07,0xcc,0x26,0xf4,0xfc,0x56,0xa5,0xee,0x00,0xb0,0x74,0x6b,0x2a,0x80,0xda,0x6f,0xda,0xd1,0x7e,0xdd,0x11,0x49,0x20,0x10,0x1d,0x2c,0x89,0xc3,0x0e,},"\xbf\x29\x0d\xb3\xdd\xa8\x76\x39\x37\xae\x4c\x83\x74\x67\x05\x32\x72\x95\xc2\xc2\x48\x06\x8f\x5a\xb8\x5c\x8b\x5d\x75\x6f\x4e\x3e\x34\x06\x2b\x55\x49\x38\x72\x61\x47\x6b\xcb\xd1\xe7\x33\x19\x90\xf1\x19\x10\xd1\x1f\x94\x60\x7c\x2b\x71\xf6\x5b\x77\x1a\xac\xab\xdc\x10\xf4\x2a\xe9\x18\xdd\x25\x94\xac\x71\x05\x1c\x85\xb3\x30\x77\x9c\x47\xaf\x00\xa5\xb9\x81\x91\xb5\x6c\xbc\xf7\xef\xe4\x1a\x27\xe8\x7c\x67\x71\x68\xc8\xab\xe9\x49\x6e\xb2\xe7\xab\xbd\x0b\x16\x04\x28\x6e\xd1\xa1\xb1\x8d\x26\x4d\x73\x3d\xe8\x7d\x0d\x3f\x80\x55\x52\x8c\x4d\x42\x6d\x7f\x8e\x6e\xd0\x24\xa7\x41\x40\xab\xd3\x54\x00\x79\x62\xa2\xa9\x7a\x5c\x2f\xf9\x76\x54\x6a\x8d\x1a\xc4\x92\x4c\x09\x22\x3d\x34\x8d\xdc\xd8\x71\x0a\x37\x99\xf9\x1b\xb8\x70\xb3\xf4\x6d\x51\xf1\xe7\xf6\x89\x2d\x6b\x08\xb9\x91\x74\x8a\x03\x7a\x86\x7e\xcc\x39\xee\x8d\x64\x62\xa7\x61\x44\x88\xed\xd3\xc2\xba\x61\x5c\xa2\xe3\x78\x54\x88\x94\x41\xb1\x3d\xc8\x35\xc3\x6b\x38\x65\x3f\x65\x98\x61\x6f\x35\x78\x3e\x2e\x15\x83\x84\xbb\x93\x1c\x90\x1b\x70\x3a\xcb\x39\x91\xfb\x7a\xa5\xba\x69\xd9\xa5\xbd\x05\x70\x24\x29\x61\xa7\x1a\x52\x47\x03\x15\xe9\x82\xe3\x41\xa6\x1c\x64\xa6\x19\xbd\x16\xfe\x81\x19\xaa\xe0\xd7\x50\x3c\xe7\xd7\xe9\x26\x14\x6b\x91\xc2\x89\x2f\x13\x16\x69\xd1\xe3\x9e\x5b\x75\xe9\xc7\x24\x52\x61\x80\x99\xa5\x7d\xc2\xee\x37\x7b\xe6\x58\x75\xee\x01\xbb\x88\xed\x52\x6f\xc3\x94\xe2\xf5\xc8\x12\x7a\x5f\x69\x12\x5e\x67\x38\x5e\xf9\x4b\x1f\x33\xad\x52\x62\x9d\x72\x0e\x31\xc0\x2a\xe0\xb5\x82\x33\x9f\xf0\xf0\xbb\x07\xff\x2b\x03\x0f\x48\xfa\x7b\x69\x27\x16\x50\x1a\xd7\x77\x3a\xd3\x15\x12\x04\xa2\xa5\x40\xfa\x94\x36\xbd\xd4\x20\x2a\x15\x73\x09\xec\x36\xce\xcb\xe5\x8b\x33\xef\xf5\x57\xfd\x33\xe0\x3f\xd3\xeb\x19\x00\x9b\xd7\xa2\xde\xa9\xef\xee\xf8\x78\x55\x67\xaa\xb2\xa4\xc9\x8b\xd1\xf2\xa8\x10\x11\xb3\x43\xa9\xf2\x0c\x44\xc5\x77\xa4\x52\xfd\x54\xba\x21\x02\x9d\x47\x06\x81\x3b\x29\x87\xc7\x6b\xb2\x42\xab\x26\x20\x84\x3c\x22\x60\xb6\x69\xad\x35\x8e\xfe\xe7\xf9\x83\x0d\xc9\xc7\xd4\x78\xa2\xde\x4a\x2c\xf8\xc4\x3d\xa7\x70\xe2\x88\xe2\xed\xbb\x6d\x73\xbc\xf2\xec\xb0\x23\xde\x6b\x2d\xcc\x6b\x16\x6e\x87\xa3\x85\xeb\x0a\xdc\x30\x56\x65\xc5\xbf\xa5\x7f\x25\x0f\xe2\x23\xad\x7f\xf4\x51\x8d\xe3\x9c\x79\xe8\x7d\xc1\x01\xa9\xfa\xa6\x82\x1a\x74\x44\x2b\xfc\xfd\xf0\xa9\xe6\x3a\x50\x9e\x2a\x2e\x76"}, +{{0x7e,0x7b,0x39,0xaf,0x69,0x38,0x0c,0xf4,0x46,0x60,0xe2,0xc1,0xff,0x30,0x83,0x34,0xe8,0x25,0x0f,0xee,0xb8,0x8b,0xe0,0xd4,0x3a,0xab,0xe5,0xe6,0x8b,0x8e,0xf1,0x71,},{0xcc,0xef,0x9d,0xae,0xd9,0x25,0x23,0x53,0x3d,0x4a,0x2d,0xab,0x6d,0x24,0x19,0xf6,0xd0,0x86,0x04,0xdb,0x64,0xce,0x37,0xe3,0x29,0x04,0xac,0x77,0xb9,0xb4,0xa0,0x1c,},{0x10,0x62,0xa2,0xdc,0x9c,0xd5,0x37,0x96,0x75,0xc0,0x4f,0x5e,0x21,0x33,0x8d,0xcf,0xb7,0x7d,0xfb,0xab,0xce,0xdd,0x62,0xb2,0x60,0x71,0x00,0xd7,0x64,0x9a,0x05,0xe8,0x08,0x71,0xe9,0x61,0x23,0x21,0x4f,0x80,0xf4,0xf7,0x3b,0x0d,0x9b,0x06,0xe2,0xd3,0x1f,0x56,0x11,0x9c,0xea,0x69,0xda,0x23,0x47,0xda,0x84,0xa2,0x75,0xb7,0xb2,0x07,},"\xd4\xa3\x97\x6d\xbf\x83\x20\x18\x56\x67\xb5\xa8\x23\x66\x40\xf2\xeb\xc9\xe4\x5e\x6d\x5f\x2a\x8d\x92\x99\x79\x27\xdd\x9b\xc5\xdb\x95\xf4\x46\x34\xbd\x65\x4e\xef\xec\xe1\x0d\x99\xd9\x2b\x46\x71\x57\x91\x64\x50\x04\xac\xcc\x6d\x14\x0f\x32\xa1\xc8\x72\xe5\x4a\xa9\xa7\x49\x3a\xf9\x45\x88\xb7\xbb\x40\x0d\x94\xd4\x58\xd4\x32\x92\x30\x7c\x5a\x1a\x38\x82\xa1\xc8\xa6\xa7\x8d\x9a\x94\x5f\x79\xd6\x4b\x32\x94\xa2\x8c\x3d\x59\xd8\x20\x22\xb0\x09\xcc\x4d\x2d\xa9\x3a\x16\xb0\x71\xc9\xab\x8e\xe9\xa3\x66\x3d\x72\xed\x34\x4f\x15\x1d\x68\xc6\x66\xa4\xb4\x96\x52\xd9\x7a\x46\xd1\x42\xa4\x74\x11\x27\xf3\xc5\x7f\x15\x51\xc4\x09\x76\xcd\x13\x81\xa8\x2a\xea\xe7\xbc\x5a\xdb\x39\x87\x20\xeb\x43\x3f\x08\x99\x48\x7e\xd2\x37\x84\x46\xb1\xa8\xdc\x6a\x33\xfc\xd4\x53\x7a\x05\xfb\x60\x3e\xc0\xa9\x0a\x27\x53\x23\x00\x24\x2b\x20\x00\x10\x86\x21\xb6\x5a\xb0\x00\xbc\x06\x38\x15\x30\xf6\x90\xd7\xe5\x6f\x81\x60\x4d\xac\xff\x19\x10\x71\x50\x40\x41\x0a\xa1\xf9\x44\xc9\x2d\xd9\xbb\xaa\x5b\xd0\x8e\xa0\x0c\x84\x42\xdf\x94\xf0\x85\xeb\x3d\xe9\x73\x35\xb6\x00\x5e\x6f\x84\xf8\x23\xd4\x34\x70\xab\x1c\x67\xda\x12\xad\x44\x99\x36\xc6\xb5\x5f\x9f\xfd\x20\x3d\xfd\x6e\x3f\x33\x30\x9e\x8a\x99\x45\xa5\x93\x20\xe6\x67\x34\xc7\x9c\x48\x14\xdb\xa5\xa1\xc1\x40\x95\xc6\x29\x25\xa1\xe1\x73\x3e\xfd\x94\x81\x7a\x25\xef\x9e\x47\x9d\xd9\xcc\xde\x6c\xa8\xad\xb7\xa8\x05\x3c\x1b\x55\x13\x46\x97\x50\x4a\xf8\x05\x3d\x59\x5b\x84\x46\x40\xb6\x1e\x93\x16\x80\x75\x46\x84\x50\xeb\x5d\xe0\x35\x86\x97\xc1\x04\xaf\xa6\xa3\x79\x6a\x50\x9c\x26\xb4\xc2\x77\xc2\x3f\xff\x42\xdf\x14\x6d\xe5\x5e\x95\xd0\xd4\xb8\x0a\x7a\xa1\x77\xd9\x92\x27\xec\xb2\xa0\x59\x4d\xee\xde\xbb\x9c\xaf\xb1\xa4\x58\xac\xa8\x07\x2c\xc7\xd7\x7c\x71\x75\xf6\x10\xca\x30\x0e\xfd\x7a\xf9\x38\x83\x46\x49\x8c\x22\x99\x15\x64\x50\x0e\x0b\x0a\xa4\xd2\x94\x6f\x18\xe6\xf5\x37\x5a\x84\x82\x86\xf3\x69\x54\xc1\xca\x22\x68\x4c\x69\x28\xc2\xa2\x5c\x7f\xe2\x1a\xba\x4a\x71\x11\xd7\xe0\x5b\xc8\xd7\x0b\x3d\xcb\x4f\x6a\xae\xc0\x64\x84\x5e\xef\x55\x25\xf8\x50\x24\xc2\x57\x0f\x3b\x78\x69\x8c\x4b\xce\xc0\xd7\x1a\xad\x53\x78\xd8\x81\x9e\x1f\xac\x44\xee\x41\x63\x70\x21\x2d\xba\xaa\xe5\x4d\x2a\xf2\x93\x9b\x82\xcb\xaa\xe7\xf4\x2f\xf4\x85\xd4\x5b\x3a\xcc\x21\x09\x0f\x5b\xa4\x1e\xc0\xda\x30\x9e\x52\xef\x28\x38\xd1\xde\x47\x1e\x0b\x7c\xf9\x85"}, +{{0xa9,0x04,0x8a,0xf0,0xc2,0x0a,0x12,0x5f,0x5d,0x39,0xc5,0x0f,0x22,0xb8,0x05,0xae,0x74,0x2c,0xf6,0x4f,0x1f,0xe8,0xdf,0xbe,0x8d,0xfd,0xaa,0x51,0x1a,0xaa,0x57,0x6f,},{0x15,0x86,0x55,0xdb,0x94,0xb1,0x5c,0xa7,0x29,0x83,0x87,0x7b,0x6d,0xb2,0x31,0xa5,0x84,0x3d,0xf5,0xdb,0xca,0x28,0x10,0xa7,0xe4,0x96,0xfb,0x59,0xab,0x71,0x04,0xca,},{0x18,0xa3,0x12,0xb2,0x0d,0x86,0xac,0x33,0x9a,0x58,0xef,0x2b,0x85,0x2d,0x46,0x7c,0x23,0xbb,0x2c,0xb1,0x22,0x7c,0xb1,0x53,0x38,0xaf,0x07,0xfd,0x04,0xb9,0xa7,0x11,0xe8,0x56,0xee,0x5b,0x2c,0x82,0xe3,0x66,0xc1,0x7f,0x86,0x17,0x13,0xd1,0x08,0x8c,0x1b,0x21,0x44,0xd1,0xc3,0x7d,0x05,0xbd,0xc0,0x0d,0x73,0x96,0x73,0x85,0x20,0x00,},"\x8e\xef\x2d\x9f\x5d\x59\x70\x99\x59\xc9\x24\xf8\x7c\x22\x78\x97\x67\x39\x3a\x15\x5d\x5c\x87\xde\x48\x8c\xef\x50\xb7\xbf\x7d\xa8\x70\xe3\xad\xc3\x00\xae\xe6\x60\x3b\x2e\xf0\x87\x64\xd9\x9d\x9e\x77\x51\xe5\xdc\xe9\x2a\xaa\x71\xaa\x18\xa6\x9c\xc8\x23\x13\x4e\x85\x52\xd9\x59\xa0\xdb\xb4\x11\x17\xe0\xa5\x93\xc3\x18\x33\xb6\xec\x21\x72\xdd\xaf\xaf\x78\x48\xdd\xd1\x8d\x28\xd0\xd4\xed\x33\x23\x7e\xc8\x04\xf6\x59\x38\xae\xd8\xe8\xa3\x28\x0d\x42\xe3\x53\xd0\x1b\xe0\x18\x7b\x13\x01\xf8\x3d\x89\x84\x90\x67\xb0\x4a\x90\x31\xf7\xe0\xf3\x3e\x34\x16\x24\x0c\x53\xd9\x26\x5e\xd0\x66\x39\x59\x97\x1f\x41\x7c\xb5\xf2\x10\xcd\xc5\xae\xbc\xb5\xe1\xdb\x7d\xfb\x82\xdf\x43\x58\x76\xa6\xe9\x8f\x41\x5b\x0d\xf8\x69\xf0\xd8\x85\x15\x35\x37\x56\x45\xee\xf7\x0f\xae\xc7\x44\xee\x0d\xc3\xac\xbc\xb0\x40\xf6\x8d\x50\x2c\x2c\x62\xc8\xdb\x45\xeb\xe5\x48\x54\xa4\xb3\x6f\x43\xfe\xb4\x9a\x6d\x1c\x2c\x2e\xa7\x99\x14\xa7\xc2\x3c\x60\xba\xaa\x67\xcb\x47\xb2\x17\x8e\x12\xdc\xe7\x6b\x00\x4c\x87\xb7\xb8\x34\x6e\xfa\xdf\x38\x0b\x9e\x1e\x41\xf6\x31\x48\xda\x51\x78\x1d\x75\xce\xc0\x40\xe4\x26\x88\x20\x21\x1f\x3c\x46\x25\x01\xd8\x08\x99\x89\x4e\x79\xd6\x18\xde\x42\x46\x1d\x78\x5a\xea\xce\x53\xae\x14\xb7\x9d\x33\x50\x1e\xd5\x62\x9b\xbd\xd0\x71\x28\x15\x6d\xb0\x72\x5f\x5b\x4b\xed\x59\x3a\x95\x29\x47\x83\x03\x84\xf6\x1d\xf0\x0e\xe0\xaa\x09\x90\x99\xc3\xcd\x97\x65\xa9\xc1\xc7\xe8\xa6\xa8\x34\x30\xb8\xd9\x86\x7c\x8e\x17\x92\x0a\xd0\xff\x64\xd8\xcd\x2f\xf5\xf1\x14\x38\x8c\xe6\xd4\x3e\xec\x17\x15\xd0\x35\xf0\x22\xfa\x97\x96\x9e\x1a\x5d\xd9\xf5\x8d\x89\x6b\x17\xc1\x22\x1c\x9e\x6c\x85\x55\x59\x72\x35\xee\xda\x6e\xc4\x1b\x0c\x11\x76\x12\xb0\x0c\x5f\x0e\xd1\x81\x6b\x05\x73\x63\x58\x27\x07\xa8\xaa\x0d\x98\xd4\xd4\xbe\x5e\x8f\xa3\x2d\x6c\x9d\x27\x82\x21\xef\x30\x67\xb8\xba\x15\x16\xd9\xe0\x51\xd2\xf6\x8b\x7d\x1b\x15\x1f\x74\xa3\x53\x4e\x78\x12\xc0\x51\xe5\xf2\xb6\x3b\x30\x35\xf8\xe5\x70\x3b\x5f\x68\xfd\x2d\x65\xbb\x75\x65\xe8\xaa\x67\xbf\xd2\xa1\x2c\xaf\x0b\xc5\x48\x11\x97\xa9\xff\x89\xd7\x7d\xf7\xa0\xe9\x65\x5e\xf0\x29\xb4\x3d\xd9\x06\xd0\xb8\x88\xe3\x13\xae\x9d\x1c\x7e\x93\x68\xa0\x13\x52\xd0\x0c\x66\x80\xdd\x0f\x1f\x57\x4a\x58\x77\x34\x8a\x7e\xa2\xc0\xb9\xe8\xe2\x72\x75\x10\xbf\x0c\x9e\xf7\x44\xf3\x69\xeb\x3c\x6c\x4f\xc1\x6a\xde\xb6\xe1\x94\x5b\xe8\x28\x7d\x0f\x30"}, +{{0xf8,0xc9,0x18,0x3f,0x23,0x10,0x5f,0xad,0x0c,0x6e,0x51,0x03,0x35,0x8b,0x58,0x32,0x88,0xf9,0xff,0x6c,0x7d,0xfc,0x91,0x10,0x6d,0x07,0x98,0x7f,0xf6,0x9c,0xe1,0xeb,},{0x4c,0x79,0x62,0x8c,0x95,0x8c,0xde,0x0c,0xc3,0xcf,0x68,0x60,0x95,0xb8,0xa2,0xf4,0x4b,0x71,0x93,0xc6,0x16,0xf5,0x1b,0x21,0xb6,0x70,0xb0,0x38,0xce,0x6f,0x67,0xff,},{0xc6,0xa8,0xbc,0x7a,0x0d,0x5c,0x61,0x85,0xb6,0xec,0xd6,0x03,0x3e,0x42,0x32,0x1d,0x5c,0x87,0x1b,0xf8,0x89,0xbe,0x72,0xbd,0x54,0xcc,0x00,0x83,0xed,0x60,0xa4,0x70,0xb2,0xcc,0x0f,0xb4,0x68,0x2c,0x89,0x4c,0x75,0xb0,0xdf,0x95,0xf1,0xec,0xfb,0xba,0x2d,0x5a,0xce,0xf3,0xe1,0xaa,0xfe,0x54,0xb9,0xf7,0xe8,0x03,0xa1,0xd0,0x15,0x0a,},"\xb1\xd6\x05\x95\x32\x3f\xf3\xc8\x44\x87\x41\x90\xe1\x83\x6e\x41\x01\x40\x9c\xbc\xea\xe2\x8d\x5d\xa8\x1f\xad\x29\x8f\xe4\x7f\x6b\xdf\x44\x74\x5b\x7c\xd0\xd3\x71\x31\xc3\xec\x36\x5b\x92\xf5\xa1\xa6\x9c\x09\xfe\x2d\x9e\x81\xda\x10\xcf\x19\xd8\x5f\xf5\xff\x26\xf9\xe7\xdb\x9f\x07\x93\xb2\x5a\xb2\x6e\x6a\x74\xf4\x4e\xb8\xc4\xf0\x78\xeb\x7a\xd1\x8e\x65\xa1\x62\x10\xd5\xc8\x44\xd3\xce\xf7\x5f\x1d\xaf\x44\xee\xe5\x58\xf9\x0e\x52\x4a\x03\x2b\x6c\xae\x6c\x8d\x23\x36\x7c\x28\xce\x1c\x75\xfc\x25\xac\x87\x43\x39\x77\xd5\x97\x53\x3c\x92\xae\x65\xf2\x91\x3a\x18\x90\x7a\xc7\xd9\x54\x3d\xf2\x41\x27\x74\x39\x43\xfe\xfd\x9c\xf8\x3e\xd8\x33\xf6\x3e\xc8\x36\x72\x33\xd8\x97\xbf\xa1\x2d\x46\x6d\x2c\x4a\x9a\xd7\x0d\x5a\x67\x2f\xc1\x07\x75\xea\x2d\x20\x4e\x63\x6d\xe7\x01\x07\x88\xda\x27\x1d\xf0\x38\x81\xa2\x5c\x8d\xfa\x5a\xf7\x3e\xe5\x59\xf8\x1b\x52\x9b\x35\xaa\x12\x7f\xdc\x0e\xe8\xfd\x36\x9c\x7a\x04\x36\x62\x39\x86\xaa\x64\x07\xfa\x67\xa1\x42\x0c\x46\xf3\x21\x1a\xb8\x4f\x84\x46\x6d\xd5\x8b\xb7\x95\x08\xa1\xfe\xb0\xa5\xa5\xdc\x3b\xb0\xc1\xb2\x48\x09\x82\x62\xa0\x64\xf3\x7b\xb2\xf0\x19\xe2\x90\xc6\x0a\xfa\xa1\x20\x66\x51\xa2\x69\x7c\xaa\xcc\x3e\xcc\x02\xec\xfc\x07\x7f\x27\x2e\x8f\x75\xce\xa7\x1c\x3b\xc3\x35\x6d\x2b\x58\x07\x27\x6f\x19\x55\x00\x1c\xfe\x10\xa6\x17\x16\xb4\x08\x2b\xd6\xf8\x4c\xae\x4b\xb0\xd9\xa4\xb7\x5a\x4b\x57\x62\xf8\x10\x79\xf1\x9d\x7d\x19\xea\xff\x86\x31\xc9\x24\x88\x5b\xd3\xa6\x4e\x12\x9f\x4c\xf6\xb7\x9c\x7a\x98\x29\x66\x55\x11\xe9\xd8\x5c\x74\x5e\xb2\x2c\x1b\x7c\xb2\xa1\x7a\x49\xb6\x28\x5c\xce\x37\xb3\xde\x41\x59\x40\x32\x83\x23\xef\xe2\x4a\x1a\x07\xee\x87\x46\x8f\x65\x10\xe4\x2d\xd2\x06\xfe\x7f\x09\xe3\xd4\x33\xfb\x52\x15\x6a\xe3\x48\x38\x31\x15\x64\x88\x63\xe4\x5b\xf6\xa3\x71\xb1\x7e\x70\xe1\x9f\x96\x27\xd7\xf0\xa5\x8b\x95\xc6\xa4\x78\x8d\x5f\xd7\x86\x2f\x16\x12\xc0\x34\x73\x25\xb7\x97\x65\x1b\xe3\x0c\x3e\x1e\x60\xea\x4a\xe6\x0b\x57\x45\xa3\x8b\x6a\x9d\x4e\xb4\x93\x5d\x6f\x3c\xb8\xd7\x1a\xd3\xf3\x9a\xdd\xa5\xe4\x2e\x22\x19\xde\x0d\x38\x19\x09\xc9\xcd\x31\x7d\xd4\x37\x94\x21\xa2\xa8\x42\x68\xa7\xea\x71\x80\xa6\x4c\x12\x9b\xe1\xe5\xe8\xfc\xbb\xf5\xed\x65\x9e\x9f\x7e\x76\x3c\xe8\x4f\x63\x0d\x54\x07\x95\x4f\x9f\x75\x57\x50\xa6\xdb\xf9\xf7\x66\x07\x17\xde\x8e\x2a\xdc\x1e\x9a\xc9\xee\x31\x65\x4d\x18\x37\xce\xe3\x97\x95"}, +{{0x16,0x08,0x9a,0x1b,0x93,0x2f,0x8d,0x14,0x99,0x56,0x88,0xb4,0x8d,0xd8,0x41,0xed,0xae,0x3d,0xa5,0xcf,0xd2,0xcb,0x16,0x55,0x53,0x06,0xf3,0xfe,0x8b,0xd3,0xed,0xb9,},{0x9e,0xcd,0x9f,0xdd,0x7e,0x0b,0x92,0x3d,0xef,0xf5,0xd8,0x87,0xb2,0x42,0x58,0x5d,0x9d,0x41,0xcd,0x2c,0x7c,0x10,0xf9,0xc3,0x45,0xb3,0x9f,0x63,0x3f,0x4a,0xb9,0x03,},{0x78,0x78,0xab,0x74,0x1e,0xba,0xe2,0x74,0x7c,0x78,0x97,0xcb,0xb1,0xd1,0x05,0x48,0x2f,0x37,0xbe,0x2f,0x5f,0x91,0x79,0x52,0x32,0xcd,0xfb,0xcc,0xc5,0x26,0x60,0x89,0x18,0xe2,0x75,0x6d,0xdb,0x75,0x36,0xb3,0x68,0x0c,0x16,0x2c,0xf8,0xa1,0xef,0x38,0xa3,0x41,0xb9,0x36,0x2b,0xfe,0x5d,0x46,0x8b,0x4b,0xce,0x21,0xdf,0x23,0x4f,0x0f,},"\x58\x50\x02\x32\x38\x8d\x9a\xa4\xb5\xfa\xf8\x5b\x02\x33\x24\x7e\x71\x7f\xd1\x68\x40\xde\x9b\xfd\x0e\xf8\x6e\x01\xe6\x13\x02\x77\x55\x13\xe2\x24\x12\x5e\x0d\x20\x42\x0e\xa9\x49\xf6\xc2\x64\x25\xf7\x00\x77\x91\x1f\x97\x11\x31\x0c\xd6\xfd\x8b\xff\x27\xcd\xea\x11\x48\x0c\x73\xe8\xf8\xb3\xc3\x76\x41\xe7\xe8\xdd\x86\x07\xc1\x64\x02\x18\xfe\xc8\x0a\x02\x09\x28\xb9\x3d\x4d\x55\x7e\xbe\x82\xec\x0b\xb1\x75\x38\x86\x7d\x2c\xb1\x4d\x44\xd3\xea\x72\x7f\xdd\x52\x82\x0b\x0d\xa9\x44\xde\x21\xcd\x5d\xa3\x03\xd7\x76\xfe\x99\xcb\xc2\x64\x83\x65\xe6\xa0\xa9\x8d\x4d\xb1\x50\x84\x26\x61\x76\x8b\xe8\x4c\x68\x50\x7a\x5c\x45\xd2\x07\x84\x0b\x03\x35\x37\x78\x6c\xb2\x1d\xad\xad\x5f\xba\xb9\xc5\xcf\xc1\xe3\x54\x7d\xe5\x50\xd3\x13\x63\x1d\xd4\xfb\xb7\xca\x8f\x71\x93\x86\x27\x60\x8d\x2e\xbf\x65\x5d\xb4\x32\x5a\xbf\x3e\xd5\x04\xdc\x18\x30\x58\xf9\xde\x1e\x44\x93\x12\xd9\x04\xc8\x46\xa1\x84\xa0\x28\xf3\x64\xc0\x28\xb2\x7e\xb4\x94\x64\x27\xe3\x1c\x21\xe1\x05\x1d\xf3\x64\xd4\x99\xf4\x77\xbf\x51\xe7\xa8\x89\x31\x83\xe5\xec\xf7\x7d\x51\x3a\x1a\x76\xb1\xa6\xfd\xfb\x16\xbe\x90\xd7\x4b\xe4\xc4\x34\x5a\x4f\x9f\x87\xee\x44\x1a\x10\x22\xd6\x7e\xe8\x44\x78\x9f\x21\xb0\xc3\x1a\xdc\xc0\xd9\x56\x63\xcd\xfb\x40\xa8\x95\xb9\x22\xdc\xe8\x06\x9b\x93\x2c\x80\x2f\xd3\xab\x1e\xf0\xce\x6b\xff\xdc\xc5\x65\x3b\x1c\xd5\x25\x7e\x19\xa0\x95\x16\x87\xe5\x45\xfa\xf4\xaa\x66\x06\x5a\x55\xc4\xb4\x19\x1e\x34\xe8\x04\x7d\x6a\x4a\xb5\x2d\x1b\x06\xc3\x69\xa4\x26\xca\x2d\x16\xb5\x1a\x02\x71\xf2\x7f\x8d\x74\x4c\x71\x1f\xce\x3a\xad\x9d\x4a\xc0\x38\xee\x70\x0e\x4e\x97\x1b\x21\xca\x48\x9f\xf2\xb8\xc7\x78\xa3\x72\x1a\xdf\x47\xc1\xae\x5a\x41\xb9\xa2\x7f\xa7\x42\xfd\x0f\x18\x16\x4e\xf3\xc2\x6b\x8a\xe7\xd1\xfa\x29\xb7\xc0\xcc\x46\x83\xbe\x65\x02\x5c\x96\x53\x7a\x12\xd5\xfc\xeb\xbd\x05\xe9\x30\xc3\x69\x3e\xbb\xba\x0a\x78\xad\xf5\x9d\x8a\x3b\x59\x8a\x34\x8e\xaa\x9f\x47\xca\xf5\x31\xfe\x44\x96\x52\xdb\x5b\x20\xd6\x89\x94\xe3\x5a\xfe\xc2\xc2\x57\x09\x05\x5a\x1d\xe2\x60\x82\xe3\x91\x2d\x49\x7c\x64\x77\x20\xa3\xf8\x73\x62\x14\x56\xe6\xa5\xb9\xeb\x61\x3a\xcb\x43\xb6\x6d\x47\xd0\xb9\x54\xc6\x9e\x8f\xbf\x2c\x5e\x63\x4c\x48\x6e\x57\x24\x93\x0e\x0b\x56\xa5\x16\x94\x0c\x8c\xb0\xe7\x75\x27\x4d\xef\xf9\x7c\xbb\x77\x59\xce\x90\xa2\xb9\x3e\x9e\xfa\xa6\x24\xe6\xb3\x8a\x39\x84\x9d\xca\x1d\xf6\x12\x73\x6f"}, +{{0x94,0xd5,0x09,0x15,0x14,0x4c,0x7e,0x7d,0xd0,0xf8,0x5f,0xef,0x87,0xed,0xdc,0x22,0x06,0xc1,0x56,0x9e,0xd1,0x43,0x1c,0x8c,0x5a,0x15,0x3e,0x32,0xe1,0xcb,0x2f,0xb7,},{0x3b,0xb0,0x98,0xcf,0x16,0x0f,0x3a,0xec,0x31,0x70,0xb5,0x7d,0x6a,0xdd,0x4f,0x56,0x73,0x92,0x70,0xe4,0xb3,0xa8,0xef,0x79,0x66,0xec,0x30,0x61,0x9b,0x29,0x91,0x02,},{0x59,0xa1,0xce,0x55,0xf5,0xa6,0xba,0xdc,0x1b,0x93,0x91,0x26,0x36,0x20,0x54,0x2c,0xfc,0xae,0x87,0xa0,0xf2,0xb9,0x50,0x22,0x50,0xcf,0xe4,0xbd,0xcb,0xf7,0x6c,0x46,0x19,0x77,0xc3,0x34,0xa4,0x8d,0x91,0x6e,0xde,0xbd,0x56,0xc2,0x1c,0xe2,0x17,0xc3,0x5a,0x64,0x44,0xcf,0xbf,0xd3,0xb1,0x1a,0x3d,0x48,0xfa,0x2e,0xdb,0x6e,0xb4,0x0f,},"\x4d\x91\x5f\x27\x33\x2d\xd7\x50\x51\x71\x9a\x24\xae\x8d\x0e\x9c\x30\xda\x79\x09\x99\xe2\x2d\x9b\x58\x7e\xf2\x03\x21\xbe\xe4\xc0\x7d\x0a\x12\x49\x4f\xfe\x59\x9f\x47\xf9\x69\x25\xf5\xd9\x25\x17\xfc\x3e\x5f\x04\x1d\x0c\x70\x9f\x2a\x97\x83\x12\x5e\xec\xa6\x65\x29\x97\x20\x1c\x42\x9a\xa6\xf1\xce\x2f\x07\xa0\xd4\xa0\xa1\x8c\xf2\x0b\x3e\x9a\x4f\x76\x63\xea\x52\x62\xca\xd8\xf9\x49\x41\x1b\x05\xff\x5c\x5e\xdd\x7b\x30\xb2\x17\xd7\x5d\x8c\x86\xc9\x4e\x5f\x92\xc1\x67\x34\x37\x4e\x8c\xea\xd6\x1b\x0b\x27\xbb\x4b\xf5\xf4\x3a\x31\x3c\x1d\xd5\xb8\x3e\x0e\xa9\x33\xb6\xca\xdf\xed\xd7\xa6\x4a\xa5\xdd\x5b\x5d\x02\xc6\x95\xea\x20\xe0\x91\xfd\xaa\x72\xef\x4e\x7c\xa4\x0f\x38\x39\x5b\xe8\xbf\x7a\x25\x5c\x6d\x06\xa6\x32\xd7\xd7\x85\xd9\xe0\x47\xf2\x32\xaa\x50\xfa\x14\x52\x9f\x98\x6f\x9e\xf9\xd7\xb5\x80\xa0\x39\x65\xb0\x15\x47\x88\x82\x2a\x22\x5b\xb5\xab\x34\x38\xb8\x9a\x5c\x28\x74\x4a\xb0\xbc\x0b\x20\x14\xe5\x79\x6a\xcb\x49\x35\xa8\x1b\x02\xa0\x46\x32\xac\xb8\x8c\xaa\x7e\x39\xe0\x69\xc7\xc8\xe1\x75\x82\x91\x09\x4a\x53\xe3\x62\xfc\xed\xaa\xa5\x83\xec\xa7\x66\xef\xeb\xf6\x9b\x38\xe8\xcd\xe9\xce\x58\xe0\x12\xc6\x0e\xc8\x8e\x8c\x42\xbe\xad\xfa\x83\x8c\xfe\x44\x0f\xa0\xc0\x1d\x65\x9c\x96\x34\x57\x6d\x7d\x7a\x2d\x3a\x04\x4f\x99\xc6\xe4\x26\x3d\x4c\x0b\x37\x4a\x38\x8a\x2a\xcf\x38\xef\xf2\x9c\x77\x7e\x9d\xaa\x60\xd5\x98\x03\x5a\x7d\x9e\xdf\x67\xa5\x02\xc3\xf5\x73\x20\x7b\x11\x9c\xac\xac\x3f\xa7\x1e\x2a\x02\x07\xc6\x01\xcc\x0d\xd6\x37\xef\x56\x2b\xac\xc3\x5c\x57\x04\x27\x38\xf1\xf5\x58\x15\xa5\x26\x80\x82\xcd\x6a\x50\x82\x92\xfa\x29\xe3\x4e\x96\x45\xd8\x7a\x1a\x2b\x6e\x58\xad\xb7\xf4\xa5\x7f\xbb\x53\xe9\x21\x3e\xf3\xdc\x87\x3f\x29\x39\x62\x58\xa1\xea\x54\x6f\xb5\x95\x2c\xe3\x43\xce\xe9\xbb\xb9\x0c\x1c\xda\x72\xc6\x5a\x7c\x8e\x40\x31\x2b\x32\x8e\x23\x19\x20\xc2\x33\x07\x7d\xca\x34\xd0\x4f\x9d\x89\xda\xa9\xa2\xf4\x34\x59\x16\x5f\xd1\x02\xff\x56\x43\xc7\x17\x52\x30\xb3\x9e\xc7\xc3\xc4\x75\x65\x0e\xf1\x31\x60\x9d\x32\x20\xf5\xa2\x94\xa4\x03\xb1\xe1\xc4\x2c\xfa\x16\x2c\xd4\x26\xf0\xae\x43\xfd\x6b\x7a\xb5\x47\xa6\x2b\x7d\x5f\x84\x74\x03\xc4\xe5\x98\x79\x53\x87\x71\x58\xcf\xde\xe2\x3c\x04\xf7\x51\xc7\xc8\x6d\x07\x8e\x82\x4c\xa6\x3b\x5e\x65\x54\x3e\x97\x8b\x6b\x0c\xc6\x89\xef\x66\x44\x12\xb0\x1b\x8f\xf1\x65\xe7\xdb\xde\x3c\x09\x9b\xf4\xf3\x4e\xbd\xdc\xb4\xc4"}, +{{0x0d,0x81,0x92,0x6f,0x51,0x3d,0xb4,0xb2,0x5d,0xfa,0x1e,0x52,0xb5,0xdc,0xa6,0x78,0xf8,0x28,0xa6,0x1c,0x7c,0x91,0x3c,0x82,0x82,0x47,0xc2,0xeb,0x04,0x22,0xb7,0xd1,},{0x0f,0x32,0x41,0x1e,0xf9,0x1d,0x4e,0x4b,0x69,0x41,0xdf,0xca,0xab,0x14,0x2e,0xf3,0xbe,0xc1,0x60,0x98,0x39,0x93,0xa5,0x26,0x2c,0xcf,0x27,0xfa,0xdd,0x2a,0xf8,0x90,},{0xe0,0xcb,0x6c,0x71,0xeb,0xf8,0xd7,0x05,0xe5,0x0c,0xad,0x9f,0x0b,0x8c,0xba,0x3e,0xcf,0x4b,0x9e,0x37,0x93,0x40,0x00,0x92,0xaa,0x5b,0x12,0x1e,0x7d,0xbb,0xc8,0xbe,0xa7,0x1d,0xf2,0x95,0x28,0xca,0x9b,0x47,0xab,0xf8,0x7c,0x19,0x8a,0x8d,0xc4,0xe1,0x4d,0x51,0x80,0xce,0x93,0x2d,0xd2,0x11,0x4a,0x3c,0xda,0xa5,0x55,0x2c,0xc2,0x05,},"\xa9\x38\x37\x52\x2f\x7e\xc2\xe9\x3a\x2e\x4b\x4c\x8b\x46\xde\x92\x6a\x81\xad\xa2\xd2\x48\xbc\xd3\x3b\x39\xb6\xc9\x5f\xb6\x2a\x61\xdb\xbe\xda\x1a\xa8\x5a\x21\xd9\xb9\x6a\x08\x51\x0d\x8d\x3a\x65\x8c\xf3\x20\xa1\x09\x28\x69\x59\x99\xd2\xc0\xd6\x05\xc7\xf9\x5a\x12\xf5\x6a\x87\x18\x50\x7d\xb0\xf4\x97\xe3\xea\xd6\x13\x13\x2a\xb0\x92\xcb\xf1\x9d\x22\x60\x35\x86\x30\x35\x8d\x9b\x26\xe6\x8d\x50\xdd\xae\x37\xc8\xaf\x0b\xb7\xd2\x74\x1f\xd2\x92\x9c\x21\x27\x9a\x78\xd1\x0e\x2c\x5f\x3c\x5b\xf4\xa4\x2a\x36\x17\x03\x6d\x54\x74\x36\x47\x76\x5a\xfd\x8c\xd9\x10\xf8\x1b\x38\xce\xd7\x23\x90\x63\x0e\xe6\x89\x44\xa3\x7d\x29\xc2\xfe\xca\xda\x1c\xc5\x9e\xc5\x44\x07\x5b\xdb\xc1\x4c\x63\xc6\x23\x4b\x88\x40\x49\x00\x0c\x27\xc7\x34\x06\x03\x56\x04\xfc\xa8\x76\x0b\x49\xa5\xe2\x10\x9e\xf9\x12\x85\xad\xc4\xec\x48\xc8\x19\xd6\x2d\x94\x8f\xac\xa9\x0f\x62\xcf\xae\xf0\xb0\x7d\x6f\xe5\x76\xd7\x62\xbf\xd0\xee\xf9\x4c\xf6\xb5\x33\x2c\x4d\x42\x25\x11\x60\x7f\x2f\xac\xc7\xac\x04\x6a\x59\xb9\x61\x7e\x83\x83\xd1\x02\x9c\xc9\x1a\xc5\x92\xb5\x20\x84\x41\x30\x32\xbe\x84\x1b\xaa\x9b\xf9\x62\x51\xa6\xbd\xa6\x71\xd4\xcd\x4b\x12\x5d\xa6\x58\xa4\xe5\xa5\x0f\x44\x28\xee\xbf\x26\x14\xfb\x0c\xe5\xfe\xbe\x80\xf7\x21\xa5\xf4\xc0\x32\x55\x06\xd2\x7a\x8d\x31\xe3\x3d\x86\x25\x38\x70\xdd\x63\xc0\x8e\xdc\x73\x02\xb2\x80\xe9\xb9\xbd\xc2\x8b\xee\xf0\x5c\x7d\xcb\x30\xd4\xc1\x62\xe9\xbe\x83\x2e\x1c\x78\x5e\x37\x55\x12\x18\x42\x1e\xec\x85\x2c\x42\x98\x21\x3b\x2f\x27\xf8\xf8\xc7\x06\xd3\x91\xb9\xc6\x9a\x56\xdb\x7c\xe5\xd8\x15\x48\xfc\xa5\xfe\xd4\x56\xf2\xd8\xaf\xd0\xb7\x5f\x79\xf8\x58\x68\x31\x6f\x4a\x09\x21\xf0\xc6\x63\x99\x26\x51\x6b\x3c\x3e\x52\xa9\xcb\x22\x55\x45\x46\xef\x70\xe1\x4c\x77\xec\xbd\xcd\x5c\x0d\x59\xa8\x17\x69\xb3\x0d\x5d\x13\x1f\x2f\xb4\x49\xc9\x96\xb8\xde\x8a\xc7\xf8\x08\x4f\x84\x99\xe1\xa5\x6f\x7c\xd2\x9d\xb6\xaa\xef\xcc\xae\x8a\x60\xe7\x56\x16\xa1\xf7\x02\xc3\xbc\x8d\xea\xa1\x00\x4a\x8d\xae\x03\x92\xa5\x9c\xee\x54\x81\x0c\x6e\x94\x0e\xee\x25\xfb\x2e\x5d\x57\x32\x67\x04\x4b\x89\x3f\xfd\xe3\x78\xfe\x75\xac\x26\x13\x37\x3d\x84\xa0\xca\x81\x87\xaf\x4a\x33\x58\xe5\x0a\x99\x4e\xd0\x33\x67\xde\x64\x5e\x10\x39\x0f\xea\x4c\x33\xbb\x1a\x6c\x0c\x39\x85\x8b\x8d\xb4\xa6\x9f\xe8\x94\xa4\x22\x3d\x45\xaf\x69\xb3\x6c\x61\x17\xc4\xdc\x25\xde\x49\xa6\x30\x17\x00\x2b\xa9\xae\x55\x1e\xf9"}, +{{0x6c,0x8c,0x53,0xb5,0x6b,0xbc,0xb4,0xc0,0xa2,0x5d,0xc4,0x0c,0x18,0x24,0x0b,0x6a,0x5c,0x75,0x76,0xb8,0x9d,0xde,0x45,0xef,0x13,0xfb,0x15,0x8e,0xa1,0x7f,0x8e,0xd9,},{0x23,0x8e,0x51,0xd6,0xa4,0x4f,0xa7,0xac,0x64,0x26,0x88,0x01,0x26,0x1e,0xa3,0x5b,0x62,0x63,0x8a,0x00,0x6c,0xc4,0x52,0xbd,0xdb,0x9f,0x16,0xfc,0x58,0x03,0x06,0x0c,},{0x4b,0xf1,0xe7,0xd4,0x9c,0xd4,0xd5,0xc3,0xc1,0xfd,0x4a,0x4b,0xc4,0x8f,0xf6,0xb6,0xe5,0x2f,0xd9,0x51,0x0a,0x41,0x18,0x12,0x29,0x69,0x96,0xe4,0xfe,0xc5,0x6b,0xe4,0x45,0x14,0xc5,0x67,0xd1,0xd3,0x34,0x77,0xbd,0x5d,0xc0,0x83,0xc3,0x95,0x8b,0xd9,0x5b,0xfe,0x59,0x9c,0x15,0x3f,0x21,0xae,0x26,0x25,0x29,0x67,0xb7,0x32,0x60,0x03,},"\xb6\x0d\xf2\x94\x4b\xa0\x15\x75\x98\x02\xd3\xc5\x87\xbc\xfe\xbe\x52\x1a\x7e\x77\xb9\x98\x5b\x76\x1c\x96\x76\x45\x4d\x24\xa6\x64\xaf\x0b\x0d\x44\x22\x5a\x55\x75\x12\xe1\xc1\xcd\x7d\xd8\x33\x5c\x8f\x6a\xdf\x92\x8e\x18\xf8\x9f\xd5\xee\xdf\x6f\x41\x1d\xcd\xaf\x99\x69\x12\xe8\xc3\xe2\x3d\x1c\xb9\x5e\xca\x4b\x9e\x24\xe7\x53\x9c\x3b\x98\xbf\x3d\x07\xec\x25\x13\x92\x09\x6c\x19\xac\x53\x74\xdc\xba\x52\x61\x32\xb6\xd9\xbb\x8f\x6c\x85\x9c\xe9\x85\xd5\x84\xc7\xbb\xa5\xb0\x2a\x81\x03\x4b\x6d\x8b\x52\x1b\xd2\x80\xe5\x0d\x77\xda\xa2\xb2\x41\x3e\xd6\x79\x83\x4f\x81\x61\xd5\xd0\x57\x3b\xdd\x47\x6a\xc3\xcd\x0a\x3a\x7d\x8d\xb4\x53\x34\xe8\x9c\x00\xab\x66\xbc\x36\x8a\x07\xb4\x23\xe2\x46\x43\x46\x36\x27\x2a\xa4\xe4\x63\x7a\x53\x06\xb2\xc3\x39\x79\x92\x78\x1f\x30\x23\x8d\xe7\x9e\xc1\x04\xac\xc7\x20\x0d\xef\xad\x96\x08\x83\xd3\x91\x44\x3e\x70\xef\xbd\x22\xf1\xcf\xce\xec\x51\x12\xfe\x9e\x8e\x13\xbb\x94\x1c\x08\x34\x68\xdd\x71\xff\xca\x97\x6c\xd5\x1c\xe1\x61\x79\x31\x10\xef\x00\xaf\xf5\xee\x2c\xcb\x77\x06\xa5\x12\xb8\x5b\xeb\x94\xac\x49\xd1\x9a\xfb\x63\x33\x65\x5c\xf3\xae\xa5\x35\xa6\xf9\xc7\x5e\x03\x48\x41\xe7\x63\xc5\xa2\x49\xb4\x70\x4e\x1b\xe7\x8b\x0e\xca\xc6\x80\x2c\x34\x3c\x1b\x7e\x7b\x57\x70\xde\x4c\x93\xa3\xa7\x9c\x46\xe6\x83\x5d\xa8\xae\x5d\xb3\x83\x8e\x17\x96\xb5\x64\xa4\x80\xa4\xf2\x90\xb6\x0a\x1c\x63\xa7\x25\xff\x3f\xef\x43\x4d\x2a\x0b\x3d\x89\x31\x97\x87\x42\xb5\x25\xc8\x3b\xae\x67\x94\xae\x64\x19\x37\x94\xb3\x70\xc2\x89\xba\x35\xed\x79\xd3\x70\x72\xa8\xdc\xfc\xad\xb4\x6d\x5f\xfa\xee\xba\x1b\xfd\x4f\x87\xd7\x66\xb5\x04\xe6\x2b\x4a\xcd\xd7\x74\x46\xe7\x9b\xa9\x94\xd6\xdb\xf4\x76\x5e\xbd\x74\xb0\x36\x51\x00\xda\x56\x16\x2c\x36\xfe\x5a\x95\x07\x7f\x6b\x42\x65\xe8\x17\x96\xb4\xa5\x74\x43\x78\x29\x70\xb9\x6c\xb4\x56\x9b\xa9\x85\xc5\x5f\xe3\xa7\x18\x38\x0b\xca\x39\xf1\x66\x24\xf8\xe4\x7c\xc6\x3c\x1b\x6f\xa1\xbd\xe1\xae\xba\x9c\x51\xf9\x4b\x70\x2b\x13\x10\x8c\xc1\x48\x1d\x42\xe6\xfa\x98\x1e\x3e\xbf\xe0\x64\xd2\xdc\xa7\x42\x0c\x74\x59\x57\x92\x31\x2a\xe3\xfb\x91\x01\xd4\xb6\x6d\x99\x16\xdf\xd6\xc1\x3a\xe8\x83\xe6\x61\xc6\x28\x22\x8b\xe9\x79\x4c\xf6\x03\x45\x07\x6d\xb2\x61\x84\xb6\x17\xe2\x72\x29\x8c\xd4\x18\x3f\x27\xbd\x52\xd4\x05\x10\xbb\x01\x5d\x20\x97\xd4\xcc\x76\xe7\x6c\x0a\x62\xbb\xfd\xaf\x53\xc7\x26\x87\x75\xbb\xfb\xdb\x88\x70\xeb\x9b\xab"}, +{{0x69,0xb3,0x20,0xfb,0xd4,0x77,0x40,0x30,0xa2,0x97,0x67,0xa0,0xcc,0x15,0x50,0xd1,0x0b,0x74,0x9b,0x44,0xd6,0x19,0xd4,0x1d,0xce,0x11,0x46,0xf7,0xac,0x80,0xa7,0x55,},{0xdc,0x50,0x8a,0x79,0xc6,0xb8,0xab,0x86,0x6c,0xd1,0x17,0xa5,0xa8,0x4d,0xd9,0xd9,0x31,0xfd,0xa4,0x50,0xbe,0xc2,0x93,0x35,0x34,0x4d,0x0d,0x21,0x92,0x16,0xd6,0x5e,},{0x69,0x7d,0x4d,0x89,0x7e,0x0e,0x2c,0xc0,0x2b,0xc1,0xc2,0xdd,0xa5,0x7f,0x0d,0xda,0x62,0x0b,0x37,0xe8,0x61,0x82,0x2b,0xb7,0xf1,0xa7,0x01,0x93,0x5e,0x95,0x9e,0xa0,0xd8,0x45,0x3f,0x74,0x6f,0xb9,0x2c,0x08,0x7e,0xd6,0x5d,0x98,0x0e,0xea,0x1d,0x6f,0xdb,0xf2,0x3e,0x99,0xb2,0x89,0xaa,0xe0,0xdc,0xbb,0x12,0x8e,0xf8,0x36,0x64,0x0a,},"\x21\x7e\x33\xf8\x86\x22\xc9\x6f\x8d\x09\x2c\x9e\x26\x66\x4f\xe9\xef\xc0\xd8\xd2\xeb\x59\xa0\x36\xfa\x46\x4c\xee\x65\xce\x44\x89\xca\xf9\x03\xdc\xe1\x7a\xfa\xfb\xc4\xf1\x8d\xc9\xbb\xfd\x6c\x1a\x4b\xe7\xb8\x34\x85\xa6\xca\x94\x7d\xef\xb1\xd3\x51\x25\xd0\x77\x39\x62\xa3\x44\xa3\x8b\x6d\xca\x9a\x40\xc3\x1c\x1c\x4e\xb2\xd7\xf6\x81\x8f\x97\x8e\x57\x3d\x66\xb9\x90\x92\x1b\x92\xb7\x77\x47\x1a\x4f\x6f\x05\x47\x7e\xbc\x35\x3a\xce\x1d\x86\xb0\x0c\xc2\x51\x77\x7a\xaf\x6a\xf3\xaa\x11\x79\xbf\xf7\x8d\xf5\x04\x8e\x5e\xf2\x99\x68\x67\x0e\x53\x54\x83\x56\x8d\x6b\xb1\x6d\xa8\x29\x56\x8f\x81\xc7\x99\xb9\xaf\xd4\xaa\xd6\xef\x08\x52\x52\xc0\xce\x3a\xc0\x1a\xc2\x1a\x9e\xa6\x9b\xd5\x8e\xad\xc6\x69\x68\xf5\x5d\xee\x38\x6b\x65\x3f\x33\x34\xef\xc3\x98\xef\x3c\x37\xa3\x8c\xe9\x3b\x21\xf1\x07\xcc\x54\xde\xc2\x6f\x53\xfe\xe5\x60\x4e\xb0\x9a\x36\xaf\xe6\xb6\x65\xb6\x32\x4a\x84\xc7\xda\x7b\x7d\xd0\x1d\x92\x78\xe4\x72\xf1\x5a\x5c\xe9\xff\x0f\xd9\x3d\x0a\xa0\x60\x4d\xd2\xdf\x8d\x5b\xf6\xa9\x12\x73\x4e\xc5\x1d\xe7\x7f\x0c\xe0\x99\xba\x11\x67\x02\x10\xa6\xa2\x06\x10\x6b\x0e\xde\x2d\xed\x85\x8a\x6b\xc4\x11\xe7\x61\x3e\x6f\x80\xe1\xaa\x52\xc3\x23\xe3\x0f\xa8\x49\x95\x1c\xc9\xb7\x76\xe4\xcc\x58\xc9\x0c\xfc\x8f\x44\x2d\xf6\x41\x51\xa7\xfd\x4a\x3d\xd6\x1a\x43\x36\xda\x21\xd0\x39\x44\x63\x5d\x3f\xd6\x67\xbe\x74\x1e\xf4\x5b\x1f\x7c\xb2\x76\xd9\xf4\xde\x81\x07\xde\x64\x58\x2f\x79\x17\xc6\xea\xb3\x8e\x0a\x88\x90\xa4\xbe\xe4\x8b\xc9\x26\x17\xa3\x61\xcc\x7b\x1d\x25\xe0\x89\x45\x3c\xe0\xa5\x25\x44\xf8\x68\xdc\xb3\x24\x9d\xe7\x61\xe7\x9d\xf6\x3e\xfa\x07\x94\xe3\xc4\x61\x8c\x55\x47\x53\xee\x28\x1c\x52\xac\x8a\xd7\x8d\x53\x38\xf0\xda\xc3\x60\xa7\x69\x38\x1b\xb4\xa3\x9f\x19\x0b\x88\x7b\x47\x23\x80\x6a\xc4\xa4\xf2\xff\x30\x4b\xc6\xf9\x33\x7a\xb5\x4c\x86\x6e\x6b\xa5\x1d\xf5\x0c\x43\xea\xb5\x2e\x2b\x39\x79\x4c\x99\x17\xe0\xc3\x14\x33\xf0\x36\x81\xd2\xf1\xd9\x3a\x04\x36\x01\x8c\xaa\xae\x20\x20\x6a\x34\x58\xad\x6c\x03\x7a\xcb\x51\x1e\xf1\x28\xf6\xdc\xd0\x53\x05\xf0\x70\x49\xa1\x3b\x6c\x6c\x3c\x5b\x81\x70\xf1\x58\xc8\xf1\x2d\x46\xe1\x60\x93\x1b\xa1\x8b\xd5\x9a\xe1\x29\xec\x07\xa0\x65\x5f\xa4\x82\xeb\xbd\x3b\x85\x0d\x36\xb8\x32\xbb\xb7\x75\xf5\x38\xe3\xc1\xb3\xa4\x3e\xcf\x94\xca\x63\x0c\xa1\x5d\x50\x28\x13\xee\xd3\xe3\x5e\x8f\xd2\x3d\x2a\xb6\x38\x60\x04\x27\xd1\x59\x7c\xb2\x9d\xa2\xa5"}, +{{0x66,0xda,0x8b,0x25,0x4a,0x37,0x06,0x73,0x78,0xf6,0x81,0x38,0xaf,0xed,0xd6,0x64,0x96,0x59,0x6a,0x05,0x85,0x52,0x4c,0x71,0x6b,0xde,0x2b,0x31,0x24,0xc3,0xe7,0xd1,},{0x85,0xbd,0xe2,0x8a,0x92,0x2a,0xb5,0xee,0xaa,0x4a,0x62,0x94,0x52,0x1a,0x2c,0xca,0xc0,0xef,0x23,0x03,0xdc,0xdf,0x8c,0x7f,0xee,0x22,0x8f,0xb4,0x55,0x20,0x12,0xe7,},{0x40,0x82,0xa5,0xbc,0x73,0x0f,0xb5,0x4b,0x6b,0xd0,0xbc,0xd2,0xa0,0x44,0xed,0x5d,0x3d,0x32,0x7d,0xc1,0x9c,0xea,0xc8,0x82,0x5e,0x62,0x9b,0x9e,0x64,0x23,0xcb,0x1c,0x61,0x42,0x36,0xf0,0x97,0xa6,0xb7,0x3d,0x47,0x39,0x47,0xcb,0x81,0xc4,0xe2,0x70,0x85,0x2e,0xe5,0xf1,0x3a,0x5b,0x03,0xdc,0x18,0xe1,0xc9,0xc2,0x7a,0x9a,0x68,0x02,},"\x3f\xae\x36\x63\x88\x37\xd0\xed\xc8\xdc\xee\x51\x7e\x43\xc4\x88\xed\x57\xfa\x6c\x98\x53\xa7\x45\xaa\xed\xfb\x10\x9e\xc1\x40\x9f\xb8\xa2\xfe\x51\xd2\x3e\x0d\xd9\xfb\xfd\x94\xf9\x1c\x18\xe6\x11\x4d\x80\x89\x01\xbf\x61\x7d\x26\x67\xce\xeb\xd2\x05\xc5\xc6\x6f\x5d\x75\x34\xfd\x2e\xc3\x3d\xbf\xe5\x80\xad\x91\x9f\x50\x42\x04\xea\xf2\x42\xaf\x87\x00\xb1\x38\xcf\xbe\x0f\x37\x29\x19\xc0\x6b\x86\x1a\x27\xd7\x20\xd0\x9d\xf2\x0f\x4f\xb7\xb7\x48\xe7\x18\xb0\xfc\x48\x6d\xbd\xfc\xb6\x94\xcb\x3f\x14\x20\x03\x5a\xc1\xbe\x55\xd3\x1f\x30\xf9\x97\xa0\x43\xd0\x47\x08\xa5\xc5\x42\xee\x37\xc0\xf7\xfe\x0b\x32\x11\xd1\x8a\x87\x03\x3d\xcb\x15\xc7\x9e\x66\x81\xc4\x97\x05\x93\xd3\x2a\x13\xc4\x8f\x0a\x3a\xf8\xbf\xc1\x36\xe0\xf9\xb5\x6a\x12\x3b\x86\xc4\xc6\x40\xb6\x50\xcb\x7d\xee\x9a\x89\xe8\x2a\xee\xee\x77\x3b\x5c\xb0\x32\xfc\xa4\x1c\x20\xc4\x07\x32\x8b\xfe\xd2\x92\x44\xe4\x60\x55\xa8\x31\x14\x61\x4d\x3d\xb5\x65\x81\x60\x4b\x11\x5f\xba\x14\xf6\x18\xe1\x02\xa1\xe1\x6c\xb0\x36\xea\x69\xdf\x92\x75\xb9\x77\xa0\x85\x81\x18\xc9\x1a\x34\xb9\xa8\x51\x9b\xd0\xda\xc3\xb6\x14\x34\xea\x08\x8f\x38\x1b\xa0\x8b\xc1\x58\x31\x89\xa4\xa7\xc8\xb6\xad\x18\xf7\x32\xd7\x4e\xff\x3a\xce\xf4\xb6\x90\x4d\xf5\x8c\x64\x69\x43\x21\x51\x37\x2d\xf9\x32\x7a\xe7\x1a\x0f\x35\x6c\x94\x46\x8d\xcf\xc2\xe4\xa5\xc0\xe4\xec\x0b\x16\x6d\x90\xcd\x46\x5f\x92\x60\xeb\xd6\xa7\xa6\x2c\xe6\xc7\x15\xbc\xc7\x15\xbe\x0c\x7e\x1f\x28\xc4\x45\x60\x12\xd3\x31\x77\xa7\xd4\x11\x3c\x9a\x5a\x22\xac\xfa\xf2\xd6\xb6\x33\x09\x07\x8f\xc1\xb1\xba\xa8\xf3\x6c\x7e\x86\x6c\x1f\x97\x2a\x65\x00\xa5\xee\xa7\x92\x01\x65\x1a\x73\x05\x20\x8b\x6c\x93\xc4\x92\xbc\x77\xca\xcb\xc9\x9c\x9c\xde\xd1\x79\xe6\x64\xa2\xf4\xe1\x69\x38\xcc\x26\xfc\xa8\xb4\x33\xeb\x80\x12\xf7\xb3\xad\x19\xba\x1f\xb8\x58\xfe\x4a\x00\xfb\x3d\x1f\x8f\xd0\xed\xdf\x0c\x37\xdc\xdb\x2e\x5d\x35\xc2\x54\x6f\x22\xe8\xc0\xf8\xce\x90\xe2\xdf\x8a\xbf\x24\x82\x7a\x01\x9b\x2c\x33\xfc\x59\x0b\xbe\x71\x2f\x01\x92\x87\x00\x2b\xc2\x21\x7c\x0d\xc0\x93\x1d\xc8\xed\x8f\x50\xbb\x44\x2f\x8b\x2d\xe2\x78\x57\x36\x2c\xe5\xa9\xfd\x97\xf0\xfd\x1b\x2b\x92\x51\xca\xd2\xa4\xac\xa1\xa9\x4d\xe2\xe9\x53\x90\x2d\x72\x28\x14\x24\x07\x44\x3b\x1d\x51\x71\x07\x64\x8a\x7b\xab\x83\x07\x49\x87\xd0\x97\x8b\xc6\x1d\x41\x9b\xc8\x45\x91\xc9\x69\xc3\xd6\xf4\xe8\x6f\xc4\x73\x87\x37\xbc\x05\x58\x75\x5c\x11\x0a"}, +{{0x27,0x65,0x48,0x29,0x0f,0x3e,0x0f,0x90,0x05,0x15,0xdc,0x63,0x36,0x6c,0x03,0xfe,0x0f,0xc6,0xee,0x13,0x0c,0x21,0xfb,0x60,0xa4,0xdf,0x9c,0xf4,0x64,0x79,0x7c,0xda,},{0x7e,0x2a,0x35,0x78,0x00,0x0a,0x08,0x7e,0xdc,0xc9,0xe9,0x4f,0xde,0x50,0x9f,0xc4,0xbe,0x05,0xca,0x0d,0xd0,0x90,0xdf,0x01,0xae,0x11,0x21,0x12,0x35,0x36,0xf7,0x2a,},{0x88,0xa1,0x46,0x26,0x1a,0xd1,0x11,0xc8,0x0f,0xa4,0x29,0x95,0x77,0xe7,0x10,0xf6,0x85,0x9c,0xf0,0xd1,0xca,0x80,0xe5,0x12,0xa5,0x52,0xc7,0x25,0xb8,0x38,0x40,0x37,0xee,0xcf,0x64,0x65,0xce,0x97,0x58,0x5c,0x9d,0x66,0x0a,0x41,0xab,0x91,0x04,0xe5,0xf7,0xc9,0xb2,0xf8,0xec,0x6f,0xb2,0x1f,0x1d,0xdd,0x50,0xd6,0x5b,0x9b,0x66,0x0e,},"\xf0\xdb\x44\x2d\xe2\x9a\x7a\x1d\xed\x55\x0d\x12\x00\x02\xcc\x12\xab\xff\xf9\x8b\x1f\x57\x6d\x65\xbd\xe1\x6d\xea\xba\x68\x7e\x4e\x0b\x0d\x5a\x87\x48\xd7\x50\x3d\xa2\x96\x9c\x64\xd6\xa7\xc2\x8d\x27\xb6\xc9\x3a\xd2\x57\xce\x32\xec\xda\xee\x37\x5f\x43\xff\xf9\x7c\x43\x2d\x45\x3f\x71\x96\xc7\x09\xc3\xbd\xfb\x73\x88\xd4\xd8\xea\xf1\x39\xf1\x82\x94\x0c\xe1\x7b\x45\x52\xe2\xd2\x0a\xed\x55\x57\xba\x4d\x2a\xcb\xf8\x45\x73\x0c\x0a\x66\xb4\x5b\x40\x95\x0b\xaf\x6a\x94\x64\x37\xaf\x6c\x9e\x3b\x33\xa7\x9e\x04\xdc\xea\xe5\x7c\x2a\x54\x95\x42\xea\xbd\x21\x6b\xf1\x39\x48\xd4\x1f\xfb\x94\x83\xfe\x29\x80\x1f\xc8\xc1\x78\x28\x40\xde\xeb\x3f\xb4\xda\x31\x92\x78\x5b\xca\x13\xed\x0a\x9e\xff\x57\xd6\x13\x6b\xaf\xbf\x9d\xec\x69\x7b\x83\x24\x47\xb2\xb6\xe7\x30\xfa\x7f\x99\x95\xba\xc6\xb7\x83\x2e\xaa\x09\x90\x5e\xe4\x9d\x46\x5a\x5e\xe4\x50\xf5\x2d\x1a\x6d\x36\x4c\x61\x81\x44\xe8\x86\xe8\xef\x63\x3d\xc7\x9d\x0a\xf8\x93\xd1\x6b\x3e\xed\xa0\xfe\xfe\xfd\x87\x59\xf2\xa0\xda\x19\x30\x17\x0d\xd1\x9e\xb7\x8f\x0d\x7a\x7b\x74\x51\x54\x03\x37\x5a\x95\xbd\xbc\xce\x01\x8b\xc1\xed\xb0\x8d\x89\x7b\xb7\x98\xa9\x5e\x7e\x86\xa5\x2a\xf3\xd9\xb8\xa4\xa1\x4b\x03\x71\xd6\x34\x98\xdc\xb2\x01\x62\x48\xeb\xd0\xbe\x80\x0e\x9f\x21\xd5\x49\xe5\xe0\xe7\xb4\x89\x5c\xa5\xcb\x72\x5a\x0c\xab\x27\xda\x8a\x8b\x12\x99\xbe\x38\xa4\x26\x09\x00\xae\x10\xdf\x5b\xab\xa1\x1a\xe2\xba\xb7\x17\x9d\xd8\x45\x39\x69\x42\x9c\xcc\x4d\x41\x60\x55\xf2\xbc\xb9\x3c\x1c\xac\x6d\x7e\x80\x4c\xf8\x12\xdf\x14\x62\xf2\x2e\xe9\xe8\x33\xa9\x76\x9e\x8e\x67\x75\x50\x40\x2c\x40\x94\xdf\x21\x2f\xd2\xc5\xfc\xc0\x9a\x72\xc7\xce\x00\x77\x51\x00\x73\x09\x0d\x0e\x63\xdb\x63\x7d\x43\xd4\xc2\x1f\x86\x19\xd3\x4d\xa5\xdb\x08\x03\x3f\x68\x6c\xe8\xb8\xa0\x82\x12\x22\xf9\x54\x34\xac\x4e\x6f\x70\x30\x94\xed\xde\xd6\xfb\x1b\x84\x6e\x97\x96\x50\x97\x9d\x3c\x77\x45\x3f\x40\xf7\xfe\xe7\xc3\xe8\x8a\x96\xfd\x1d\x70\x2e\x81\xc2\xa4\xf3\xf3\x75\x3c\x79\x64\x84\x2d\xfd\x9d\x39\x58\xa7\x43\xda\x06\x3d\x1d\x64\x8e\x51\xb2\x10\xa2\x8e\xd2\x48\x7f\x14\xd5\xf1\xbc\x6f\x33\x9b\x2d\xd1\x7a\x66\x1c\x39\x73\x6d\xa9\x9e\x4a\x4f\x07\x36\x03\x42\xd2\x37\xe3\x81\x3e\xa3\x99\x8d\x66\xeb\x31\xa2\xd7\x08\xaf\x06\x5c\x32\xb9\x27\xf7\x57\xc3\x7a\x80\x06\x60\x67\x4e\x97\x17\xba\x58\xf2\x80\xeb\x2a\xa4\x64\xfa\x74\x40\x21\x08\xa5\xd5\x66\x2e\x8d\x0f\xea\xf3\x29\x68\x7a"}, +{{0x97,0x2c,0x06,0x16,0x55,0x6e,0xf2,0x2c,0x21,0x48,0x68,0xfd,0xd8,0x22,0xc5,0x57,0x39,0xe1,0xf9,0x6a,0x93,0xae,0x83,0x51,0x2a,0xfd,0xa9,0xca,0x7a,0xa7,0x4c,0xd2,},{0x9e,0x1c,0x6d,0x41,0x07,0xf8,0xab,0x81,0x61,0xc5,0xdb,0x5b,0x88,0xa3,0x7c,0xa1,0xde,0x9f,0x4e,0x29,0x13,0x67,0xab,0xb1,0xef,0xc8,0x4f,0x83,0xf7,0x07,0x69,0x53,},{0x54,0xdd,0x06,0xfb,0xb3,0xd7,0xc6,0x3f,0x8c,0xda,0xf7,0x83,0xc2,0xd7,0xba,0xc1,0x6b,0x4c,0x82,0x6e,0x2d,0x1b,0x18,0x07,0xc8,0x4e,0x04,0x9f,0x64,0xe2,0x71,0xb2,0x1c,0xfa,0x3e,0x37,0xc3,0x44,0x26,0x02,0x87,0x80,0x5d,0x71,0x88,0x06,0xb6,0x2c,0x56,0xb4,0x7f,0x6d,0x5c,0x50,0x81,0x25,0xc9,0xfb,0x5d,0x5e,0xa3,0x5f,0xd5,0x01,},"\x86\x89\xe2\xf9\x5c\x8f\xd5\x0d\xc4\x46\x64\xa1\x8f\xb1\xa9\xf2\xc8\xf3\xee\x73\xc0\xf9\x58\x7e\xe2\x8b\xfa\x35\xc9\x23\x1c\x75\xbf\xd3\xd9\x53\x41\x74\xe5\xad\x3f\xa9\xf0\x92\xf2\x59\x94\x2a\x0f\xf0\xba\x2c\xa2\xcb\x59\x04\x3d\x19\x2c\xa8\xe3\xc8\x86\x9b\xed\xd2\x35\x4c\xbc\x5a\xc7\x82\xd7\x27\xc0\xb6\x94\x07\xf6\x8d\x13\x26\xdf\x65\xa6\x0c\x4d\x32\xf8\x7f\x19\xa1\x0f\x3d\x76\x5f\xf9\x23\x43\x4f\x55\x11\xd1\x34\xd3\x97\xc4\xfe\xf6\xbb\x19\x53\xab\xfc\xe6\x08\x27\xc3\x59\xaa\x4b\x54\xf9\x12\xaa\x8b\x17\xb8\x3d\xcc\x7e\x3b\xcb\xc5\x05\xba\x04\x6f\xe5\x7c\x16\xda\xcf\x4e\xe2\xfa\xd5\x38\xbc\x06\x81\x7c\x9b\x9d\x8d\xbc\x5f\x9d\x9b\xbf\x9f\x4a\x93\x4f\x14\xa4\x2c\x29\xe0\xe2\xf3\xa4\x9f\x46\xb2\x0e\xe7\x6c\xfe\x20\xde\xa1\xe9\x74\x50\xeb\x6a\x8f\xda\x04\x81\x68\xdd\x82\x78\x10\x20\x7f\x00\x5a\x3c\xaa\x93\xca\x11\xf4\xee\x60\x8a\x7a\x93\x55\x49\x43\x13\xae\xc8\xd7\x07\x5a\xfc\x94\xc7\xcc\xcc\x75\xc2\x31\x9b\xb4\x58\xc0\xce\x37\x3e\x9d\x00\x7f\x75\x3b\x33\xb5\x27\x93\xd5\x84\x96\xb2\xd2\x5c\xd1\xdc\xd7\x83\x2a\xac\x5d\xdb\x38\xf4\xdb\x19\xc4\x27\x21\x9e\x1a\x04\x20\xea\xd4\x7b\xa9\x5a\xb6\xd8\x9c\x65\x93\x90\x41\xcc\x73\x4c\x08\xeb\x6b\x47\x6c\xaf\x7f\xc7\x6c\x59\x8d\x94\x7f\xf4\x44\xb1\x07\x70\xf6\x29\x45\xae\x65\x04\x4f\x78\x09\x82\x99\xe2\x62\x6b\x63\x8a\x73\x28\xd1\xb7\xda\xa5\x88\x9e\x8d\xb9\x4b\xbf\xf2\xde\xd6\x2e\x14\x46\x37\x60\x22\x7c\x3f\x32\x6e\xd4\x93\x56\x5d\xdf\x0a\x17\x61\xb8\xe4\xbb\x7d\x24\x10\xfa\x0f\xdb\xf3\x56\x84\x39\x7e\xef\xea\x95\x89\x58\x89\xa0\xa9\xdf\xfc\x5e\x02\xc0\x92\x38\x3b\x7c\xe7\x4d\x2d\x90\x93\x99\x16\xf2\x6b\x71\xaf\xd2\x65\xf8\xbe\xc7\x4f\x0d\xe2\x47\xc9\x64\x39\x05\x58\x3d\xf3\xce\xe2\x35\x37\xd6\xb5\x68\xc8\x33\x8c\xe5\xfe\xe4\x2f\x7d\xd1\x5d\xad\x52\x47\xf0\x09\xac\xbf\xd5\xd7\x69\xb6\x36\x69\x59\xcd\x0a\xe1\x50\xf5\x8f\x7c\x80\xfa\x10\xd9\x89\xed\x90\x11\x93\x72\xe5\xfe\xa5\xda\x48\xa4\xe8\xea\x9c\x72\x78\x75\xdc\x4a\x20\x05\xb0\xdc\x2e\x3f\x69\x7c\x0c\xe0\xa4\xbd\xb2\xf7\x50\xc0\x4f\xbc\x0c\x27\xd0\x2d\xd8\x28\x6e\x54\xc9\xc3\x95\x9b\x6f\xfb\xdb\x1d\xe2\xaf\xfe\x9e\x78\x26\x51\xe5\x16\x8a\x50\x0a\xfe\xd0\x37\xb3\xe1\x79\x0d\xdd\x59\x38\x51\xa6\xa6\xcc\xca\x9f\xff\xb4\xa9\x9e\x27\xdf\x43\x81\x88\x71\x53\x6a\xb0\x4f\x14\xa0\x6a\x1c\x7c\xb4\x7b\xed\x62\x41\xce\x74\x30\xad\x3e\x64\x0a\x72\x67\x52\xfa\x06\xa9"}, +{{0xe0,0x40,0x5d,0x37,0x89,0x3e,0x89,0xf5,0x38,0x11,0xd6,0xd4,0x46,0xe1,0xf1,0x93,0xf5,0x1a,0xfa,0x1b,0xbb,0xa7,0x25,0xf9,0x5e,0xb4,0x80,0x33,0x42,0x4a,0x25,0x09,},{0x45,0x10,0x4d,0x59,0x5e,0x44,0x3e,0x8c,0xe6,0x54,0xde,0x9d,0x65,0x50,0x54,0xbf,0x0a,0x99,0xd3,0x56,0x13,0xd7,0x7d,0x57,0x45,0x4c,0xa2,0xd1,0xc8,0x99,0xb5,0x17,},{0x77,0xdd,0xd4,0x91,0xca,0x66,0x2e,0xbf,0xfb,0x12,0xf7,0xf4,0x92,0xd7,0xfb,0xc1,0xa1,0xb4,0x47,0xf6,0xc8,0x59,0x98,0xf2,0xf7,0xcc,0x9a,0xdc,0xe6,0x7d,0xe6,0x3b,0x6e,0xeb,0xd0,0x81,0x17,0x84,0x5a,0x03,0x02,0xf7,0x34,0x97,0x14,0xba,0x9d,0xb2,0xaf,0x58,0x04,0x8b,0x85,0x83,0x7d,0x76,0x60,0xec,0x3d,0xeb,0xee,0xe2,0xd0,0x0f,},"\xdf\x58\xc4\xfd\x07\x02\xa2\x0f\xaf\xa3\xd1\xd4\xfe\x7d\x85\x93\x8b\x12\x0f\xc1\x1e\x8d\x41\xb6\x01\xf0\xe6\x0e\x42\x23\x6a\x49\xf1\x26\x81\x3b\xd5\x12\xee\x71\x35\x90\x61\xe1\x3e\xb3\x14\xd4\x17\xf5\x6d\x6d\x56\x02\x85\xfa\x89\x91\x21\x32\x84\xc4\x2b\xc2\xce\xf2\xdc\x93\x7b\xdc\x0b\x5e\x9d\xc2\x26\x9a\xfa\xb3\x2d\xb3\x0e\x68\x49\x85\x59\x51\xcf\xbc\x53\xec\xfa\x01\x64\x38\x63\xe0\x32\x89\x95\xfe\x85\x0c\x0d\xb5\x54\x21\xbf\xa5\x64\x60\x1b\x8c\x9d\xb7\x55\x2c\x7e\x6a\xa7\xad\xfa\x15\xa5\x80\x21\xa8\x42\x66\xe9\x59\x5c\x65\xfc\xa4\xa1\x5f\xa7\x0f\x55\xf5\xd2\x12\xc9\xe2\x77\xff\xb8\x30\xf4\xca\xd1\x86\x1f\x3f\x49\x5a\x9d\x67\x2f\x56\x91\x31\x06\x39\xc1\x2d\xcd\x07\xe3\xef\x17\xa2\x37\x50\xbc\xb4\x6b\x7a\xd7\xea\xc4\x62\xeb\x51\x22\x25\xf3\xbe\x7e\x32\xf8\xf4\x98\x7a\x11\xdf\x34\x11\x66\x06\x2b\x43\xc6\x3a\xb8\x58\xa6\x00\x49\x76\x67\xfb\xb8\x8e\x93\xc7\xe2\xe0\xaa\xb4\x1c\x09\xc0\x23\xeb\x90\x2e\xc3\xba\xf6\x79\xe2\x5b\x96\xe1\x06\x92\x1a\x91\x4f\xd5\xde\x20\x0a\x47\x88\x9d\xe2\x3e\x7b\x65\xd0\xcc\xdf\x0c\x29\x03\x64\x67\xa1\x21\x0c\x00\x30\x30\x9a\x2d\x04\xec\x25\x6d\x5a\x4d\x8b\x97\xd4\x6a\x3e\x15\xf3\x45\xb6\x67\x17\x08\x03\xcd\xac\xf6\xcb\x48\xad\xd0\xa1\x34\x62\xdd\x30\xfa\x06\x2b\xd4\x56\x66\x41\xda\x07\xd7\xf6\x1e\x06\x36\x86\xed\xd9\x6b\xfe\x8f\x97\xb9\x86\xb7\xc0\xe4\x42\x49\xcd\x2d\x73\x17\x47\x29\x99\xb8\xee\x4e\xa8\x0c\x90\x2f\x3b\x18\x89\x36\x71\x2e\x89\xd8\xbf\x02\xce\x8a\xe7\x7b\x6b\x31\xab\xb0\x63\x20\x65\x45\x5d\xdd\x9f\x9d\x1c\xd9\x53\xa4\xa4\x9a\xac\x1a\x15\x16\x9e\x68\x7d\x4f\xd3\xf7\xc2\xed\xfb\x3a\xab\xc3\xb6\x61\x55\xf7\xd3\x15\xf8\xa2\x94\xfa\xdd\xff\xdb\x49\x51\x36\x7a\x0c\xb8\x70\x75\x9e\x85\xa8\x38\xaf\x66\xba\x3f\xc1\x03\xda\x2b\xab\xc3\xf3\x81\x69\x6e\xf8\x88\x2d\x85\xa8\x27\x8d\x5f\xac\x3a\x72\xf1\x6e\xb1\x19\xee\x99\x00\xb1\xfd\x98\x6c\x2a\x9f\x94\xee\xd8\xe0\xd4\xf2\x73\x69\x7e\x43\x63\xa9\x75\xff\x6a\x7b\x80\xd5\xb4\xec\x53\x55\xbf\x63\xb4\x2b\x71\xcd\x48\x42\x40\x1d\x38\xb5\xe0\x0c\xc9\x7b\xfd\xa4\x0e\x45\x66\x53\x68\x3b\xc8\xe6\xda\xde\x7d\xcf\x98\x5a\x97\xb0\xb5\x77\x6c\x4d\x72\xca\x13\xa1\x47\x4e\x4e\xb2\xec\xcf\xcd\x42\x87\x86\xdd\xd0\x24\x6d\x73\xa6\x37\x7a\x79\xcb\x8d\xa7\x20\xe2\x26\xc1\x94\x89\xbd\x10\xce\xdd\xe7\x4b\x49\xfa\xc2\xcf\xa2\x07\x12\x9c\x6a\x10\x8a\xa1\x64\xbe\x9d\x80\x9c\x4d\x31\x14\x73\x60"}, +{{0x57,0x56,0xe7,0x52,0xdf,0xf6,0x9e,0x3e,0xed,0x84,0x8e,0x4a,0x49,0xc7,0xa8,0xba,0xca,0x12,0x15,0x4f,0x94,0x31,0xde,0xc3,0x56,0x26,0xef,0x8d,0x75,0xa4,0x45,0x14,},{0x59,0x10,0xef,0x00,0xa5,0xb3,0x54,0x14,0x3c,0x46,0x56,0x1d,0xa6,0x2c,0x41,0xaa,0x13,0xd2,0x9c,0x18,0xdc,0x61,0x53,0xbf,0x8e,0x50,0x2e,0x01,0x14,0x00,0x77,0x28,},{0x81,0x57,0xd8,0x33,0x4d,0xed,0x1a,0x32,0x69,0x9b,0x35,0x0a,0xc0,0xd4,0x12,0x00,0x28,0xcd,0x8e,0xf8,0x18,0x94,0x48,0x93,0x48,0x50,0xe5,0x0e,0xe4,0x99,0x9d,0x8f,0xa2,0xcd,0x25,0x76,0x46,0xd9,0x2f,0xba,0x5d,0x66,0x2a,0x82,0x3e,0x62,0x20,0x8a,0xb4,0xfb,0xe0,0x17,0x14,0xa8,0x48,0xa0,0xb9,0x0b,0x55,0xad,0xcd,0x24,0x69,0x02,},"\xeb\x21\x90\xa3\x21\x9c\x79\x2b\x66\x66\xb2\x75\x27\x33\xad\x9f\x86\xfc\x39\x01\x55\xc4\xb4\x38\xbe\x19\x69\x59\x38\x3b\x25\xf3\xa7\x49\x53\x0d\x5a\x4b\x15\xeb\xe2\xc1\x8d\x99\x17\x8e\x6d\x45\xbb\x4a\xa2\x12\x0f\x95\xa3\x52\xe0\x40\x6c\x63\xac\x86\x72\x48\xd9\xef\xba\x12\x42\x31\x06\x48\x73\xc8\x2f\xe9\x95\xdd\x03\x1c\x7c\xbc\x7d\x15\xec\x19\x1f\xbb\x6c\x47\x4d\xc4\xc7\x77\xe8\xf4\x57\x84\x1e\xb4\x62\x48\x41\xc1\x52\xd1\x5e\xde\x26\xe7\x84\x79\xa6\xa2\x5f\xfa\x33\x55\x63\xf1\x06\x4e\xf0\x95\x58\xb9\x10\xe2\x60\x84\x18\x82\x0f\x49\x55\x4b\x67\x0c\x6b\xab\x34\xd1\xd6\x09\x84\xde\xa5\x0e\xd6\xa3\x75\xf4\x5a\x74\xbe\xad\xfb\x04\xbd\x93\x00\xbd\x59\x4e\x2e\x20\xea\x5d\x30\x52\xbb\x7d\xdc\x51\xa9\x49\xa0\x04\x79\x72\x68\x2e\xbe\x66\xd3\x8a\xac\x62\x92\x72\x70\xde\x42\x15\x0d\x58\x22\x1d\x03\xb8\xac\xe3\x58\x99\x33\x48\x7b\xf2\x3d\x29\xc5\xc2\xc8\x43\xae\xfa\x2e\x1c\xa2\x2f\x9d\x16\x80\xf8\x0c\x76\x6d\x14\x3c\xe5\xec\xef\x25\x3a\x74\x5c\xb7\x1e\x72\xf6\x50\x4a\xd9\x11\xf7\xcb\x4a\x81\x9c\xd0\x74\x86\x3a\x92\x70\x69\x29\xa3\x14\x2f\x8d\xb7\xac\x16\x41\x02\xac\x2c\xa0\xd2\xe1\x9a\x72\x5e\x1b\x5f\x81\xf4\x43\xc7\x3e\x04\x84\xf2\x6a\x45\xa3\xae\xf8\x4f\x1f\x3f\xa0\x4a\x4a\xc6\x95\xd2\xda\xb6\xef\xba\x45\x6a\x28\x1a\x39\x73\xcc\x18\x6e\x68\x0a\x66\xdf\x52\x1a\x4d\x1f\x9e\xdf\x4d\xfb\x27\x4a\x42\x70\x97\xbf\x86\x32\x81\xcf\xb0\xed\x80\xf8\xd7\x67\x66\x38\xd6\xcd\xac\x93\x78\x43\xef\xbc\xfc\xe9\x1d\xe1\xdf\x6c\x52\xb5\x94\x57\x1b\x93\x15\x60\x0e\x4b\x65\x52\xde\xfb\x84\x37\xa8\x07\xba\x21\x29\x8e\x3d\x97\x22\x12\xba\x31\x46\x92\x91\x7f\x40\x07\x53\x11\xac\xd0\x09\x39\x52\x41\xb9\xf1\xb2\x56\xc5\x15\x73\x5d\xc6\x74\xf8\xe8\x66\xd1\xee\xb4\xc3\x28\x54\x8a\xee\x71\x23\x1c\x4c\x9d\x5b\xd2\x2e\x39\xde\x88\xd1\x9f\xab\xf4\x9f\x0b\x98\x69\xcb\xf8\x35\x21\x4b\x15\x52\x2a\x93\xd3\xa5\x00\x7b\x11\xf0\xb5\x0e\x52\x28\xd4\xee\xbb\x45\x71\xb3\x5d\xa8\x4f\x4f\x68\x7e\x3f\x43\x79\x3d\x54\xf3\x82\x5b\x37\xa5\x09\xea\x56\x4b\xdf\x21\x7f\xf4\xad\xf6\x84\x7b\xbe\xa4\x31\x6a\x1d\xbc\xc7\x44\x8e\xcd\x53\x63\xea\xab\xc1\x28\xde\xcf\x05\x4e\xe1\xa0\xee\x2d\x87\x19\x79\xf8\xa6\x3b\x26\x92\xb0\x9f\x6e\x98\x6a\x13\x8e\x7f\x68\xf6\x0a\xa4\x26\xa1\xc9\xb0\x1a\x49\x02\xe1\x3b\x17\xbc\x83\x12\x41\x0c\x28\xbe\xd2\x9b\x60\x1b\x0f\xc9\xf3\xbc\x2d\x22\x3f\x87\x52\x51\x10\x0f\x86\x9c\x6b\x58\x44"}, +{{0xb9,0x04,0xac,0xb1,0x9e,0x5c,0xf8,0x72,0xd3,0x64,0x0c,0xd1,0x8d,0xdf,0x3c,0x0b,0x66,0x57,0xe0,0x11,0x7c,0xe6,0x59,0xdb,0xf5,0x02,0x59,0x01,0x5d,0x3f,0xbf,0x32,},{0xe0,0x4a,0x8a,0xa5,0x6d,0x18,0x18,0x48,0x3b,0x10,0xd0,0xa7,0xc9,0x19,0xe1,0xd5,0xd8,0x00,0x1e,0x35,0x51,0x0e,0x1e,0xc6,0x2f,0x71,0x14,0xdb,0xe8,0x1a,0xe0,0xbe,},{0x9a,0xaf,0x8a,0xc9,0x71,0x40,0xd5,0x50,0x8d,0x58,0xf5,0xac,0x82,0xb7,0xfd,0x47,0xe6,0xb1,0xf6,0x8a,0x7c,0x78,0xa2,0xac,0x06,0xf0,0x41,0x6e,0xf8,0xe9,0x91,0x95,0x3f,0x62,0xc4,0x7f,0xd5,0xfb,0xc6,0xc1,0xe0,0x1b,0xae,0x1c,0x92,0xa3,0x3e,0xf5,0x2b,0x7e,0xfa,0x5f,0x17,0xbb,0x86,0x33,0xbd,0xc1,0xae,0xeb,0xce,0x31,0x8f,0x0f,},"\x83\xf4\x12\x4d\x5a\xf9\x55\x13\x9b\x1b\xc5\x44\x1e\x97\xc5\xfa\xc4\x91\xb4\xea\x91\x14\x07\xe1\x54\x20\xa0\x34\x7e\xd7\xfa\x1f\x88\x19\xe3\x6c\x8e\xd5\x74\x0c\x99\xd4\x50\x5a\x78\xb6\x19\xd5\x60\x74\x9a\xf5\x0b\x05\x73\x51\x08\x16\xd6\x13\x22\xcd\xa9\x76\xa5\xd4\xca\x32\x05\xf5\xf0\xe6\x0e\x75\x9a\x5d\xf1\xa0\xbd\xf3\x6d\xfe\x97\x17\x90\x6a\xc5\x7c\xbf\xc9\x70\xab\x43\xb6\xfa\x18\xe6\xc0\x00\x6c\x84\xfc\x72\x54\x47\x0a\x0b\x77\x47\x27\xbf\x5f\x8e\x67\x94\x23\xa5\x31\xe4\x1c\xb5\x31\x0f\x9b\xcb\xf5\xa5\x44\x5e\xbc\x39\xfb\xd9\x09\xce\x11\xe9\x7b\xc2\xf6\x6a\x4a\x1b\xb6\xc2\xf1\x67\xf2\xc6\xe8\x0e\xb9\xb8\xb7\x2d\xf3\xe8\xcf\xd4\xe5\x14\x48\xdc\x14\xc0\xb8\x37\xf2\x94\x96\x93\xd1\xd0\x54\xc8\xf9\x5b\xff\x7f\x1e\x36\x45\x67\xd0\x34\xf2\x22\x3e\x15\x94\x77\x2a\x43\xdc\xfe\x05\x97\xfd\x6d\x13\x3b\x3f\x2e\x96\xff\xc5\x66\x7d\xd5\x92\x8f\x23\xec\x3c\x75\x0f\x84\x59\x93\xa3\x4e\x97\x76\x15\x9a\x68\x30\xd6\xfd\x90\x13\xee\x7a\xea\xa1\xfc\xcd\x69\xb9\x6d\xf2\x84\x70\x4f\xd0\x88\x88\xb1\x5b\x64\xe2\xe9\x0d\x57\x8c\x5c\xfc\x0f\x95\x69\x3f\x6a\xb6\x5c\x69\x47\x44\x6a\x85\x7c\x02\x9c\x7c\xa6\x60\x80\xb7\x54\xc7\x73\x4b\x78\x99\x8a\xbe\x9b\x7c\xc6\xef\xd0\x9a\x44\x18\x19\x4d\x88\xb3\x4e\xc6\xc3\x3a\xf6\x30\xdb\x81\xde\x5b\x99\xfe\x65\xaa\xc8\xb7\x33\x62\x37\x91\x19\xc7\x00\xd1\x07\xed\xfc\x19\xf2\x70\x76\x04\x68\xee\x8e\x5f\x15\x5d\x9a\x34\x7e\x57\xb5\x93\x0f\x32\x7a\x8d\x11\xc6\x67\x4d\xdd\x02\x0f\x9e\x7d\x9b\x76\x1d\xba\x5b\x83\xa8\x73\x02\xf1\x83\x3e\x5a\xbd\x49\x52\x6d\x66\x39\x1e\x5b\xf0\xe3\x5b\x44\x53\xd6\x30\xbf\x7d\x0a\xdb\xfe\x50\x1a\xef\x81\xe6\xc5\x93\x8f\x92\xcb\x75\x2f\x5f\x14\xd2\x80\x6f\x90\xae\x15\x46\x05\x1c\xcc\x7f\x91\x3c\x5d\x6a\x38\xff\x3b\x7b\x9a\x23\x66\x2e\xf1\xf0\x08\x08\xed\xb2\xfa\x31\xec\xba\x5c\x8d\x33\x87\xe8\x75\x41\xcd\x06\x16\xed\xbf\x3a\xaa\x35\xa5\x37\x92\x28\x61\xf4\x4c\xbd\x9f\x99\x2b\x82\x46\xd9\xc6\x4c\x41\x98\x81\x70\x1a\xb4\x3f\x7f\xd4\x64\x21\x0d\x80\x2b\xa6\x56\xd9\x5c\x0f\x24\xa3\x45\x99\xb2\x0b\x1e\xc2\x00\x11\x48\x5c\xfc\xb3\x18\x6b\x7b\xcf\x69\xd7\x45\x81\xa7\xa3\xee\xd6\x13\x4c\x4e\xec\xd6\x55\x74\xa4\x32\x0d\x9c\x57\xa8\x49\xc4\xe7\x8c\x8a\x5c\xe8\x25\x05\x00\x4a\x54\xf1\x9d\x4b\xdc\x82\x23\x40\x1b\x34\x94\x6b\x7d\x66\xe4\x7e\x63\xcf\x9d\x0f\x57\xd0\x94\x54\x91\x38\x4b\xc6\x86\x8c\x4b\x47\x86\x90\xe5\x50\x02\x1d\xf1"}, +{{0x8a,0x35,0x01,0xb7,0x69,0x53,0x60,0x3c,0x90,0x33,0xe3,0xbc,0xbf,0x3e,0xc3,0x78,0xd2,0x57,0x01,0x1a,0x6c,0x50,0xb8,0x97,0x62,0xd4,0x91,0xea,0xa7,0x2c,0x5e,0x0d,},{0x77,0x8f,0x20,0x19,0xdc,0xd8,0xdb,0xb8,0x6c,0x67,0x37,0xcc,0x8d,0xc1,0x90,0xc5,0xa0,0x4c,0x50,0xb5,0xbf,0x45,0x88,0xbc,0x29,0xfa,0x2a,0x47,0xaf,0x25,0x26,0x72,},{0xa8,0xa3,0x09,0xba,0x52,0x12,0x5e,0x76,0xa4,0xa6,0x1e,0xb4,0x3f,0xd4,0x13,0x5c,0x41,0xab,0x11,0x79,0x9b,0x91,0xcc,0x54,0xff,0xc9,0xc6,0xa2,0x0f,0x05,0x0c,0xc5,0x95,0xb2,0x81,0x43,0xc8,0x74,0xbd,0xb9,0x28,0xbe,0xed,0x26,0x1d,0x9c,0x0f,0x12,0xaa,0x19,0x2e,0x66,0x40,0xbf,0xda,0xd5,0x4b,0xa0,0xd4,0x78,0x42,0x6b,0xce,0x09,},"\xe6\x09\xf1\x22\x4a\x6a\x45\x11\x40\xcb\xc0\x25\x4d\x43\x2c\xe5\xfd\xdd\x08\xa8\xe9\x12\xf8\x1c\x41\x2f\xdf\xd5\x18\x2f\xf6\xac\x2f\x13\xc5\x76\xc8\x14\x5b\x15\xf2\x5b\x40\x9d\x85\x3f\x91\x44\x09\xe4\xe0\x2c\xef\xc3\x9d\x9b\xef\x4a\x2a\x06\x04\x98\x57\x0b\x2d\x3a\x28\x38\xc9\xb0\xb8\xe3\xaf\x4f\xc3\x7e\x19\x15\xf8\x04\xa8\x01\x88\x58\x5b\x30\xb6\x8a\x3f\xfb\x2e\x96\x0c\x73\x20\xe8\x27\xd2\xfe\x36\xe6\xa3\x28\xcc\x6e\x78\x06\x34\x8a\xdb\x0b\x77\x3b\x78\x4d\xe5\x29\xbb\x6f\x64\x75\x1b\x21\x05\x85\x94\x94\xfd\x49\xdb\x0b\xc7\xf6\x2d\xf4\x6b\x9d\x7c\xe6\x76\x97\x5c\xc5\xf4\x38\x56\x49\x84\x36\x81\x2e\x04\xf2\x6f\xb8\xb8\xab\x7e\xba\x12\xf1\xd5\x67\x22\xeb\x82\xeb\xfa\xfa\x47\x35\x97\x7a\x26\x68\x1c\xb0\x3f\xa4\xbc\x69\x51\xab\x9c\xbd\xf7\x87\xe3\x27\x8f\x2f\x57\xf2\x9e\x12\x09\x5f\x8c\xa2\xa1\x78\xcf\xa7\x57\x13\x37\xf0\x27\x42\x37\x66\x9f\x97\x65\x7d\x4b\xad\xb3\x94\x36\xd7\x86\x49\x25\x80\xfd\x55\xd8\x6b\xe3\xa0\xcd\x17\xd1\x60\x57\x01\x7b\xaa\xae\xa0\x0c\x1e\x14\x55\x21\x59\xbc\xab\xc0\xe6\x66\xba\xd3\x41\x8e\x4e\xc1\x3b\xfe\x16\x3b\xe2\x56\xf0\xc8\x9b\xc2\x34\x4a\x8d\xdf\x99\xca\x81\x60\xb1\x89\x87\x5a\xd3\x22\xd9\x0f\x58\x13\x25\x28\x1d\x53\x89\x96\x5c\x0a\x7b\x7b\xca\xe2\x29\x4a\x3c\xbe\x35\xa4\xe4\xe8\x3b\x54\xc4\x27\x63\x53\x96\x0f\xad\x11\x85\x32\xd4\x9b\x70\x76\xf2\x5a\xd1\x90\xab\x56\x94\x91\x4f\x71\x08\xb0\xab\x69\x69\xa1\x91\x28\xfb\x0a\xef\x00\xe6\x5a\x04\xfc\x83\x2d\x07\x69\x61\x67\xb9\x34\x2b\x35\x5e\xc5\x77\x37\xca\x37\xcb\xff\x3b\xb3\x19\x31\xcb\x58\x71\x2a\x4c\x46\x89\x52\xc6\x45\x9d\x56\x7a\x26\xe7\x95\x01\xe4\xe3\x1b\x1b\x09\x53\x53\x76\x32\x02\x9e\x9b\x49\x0f\x72\xe5\xa6\xe0\x57\xdd\xb4\xb3\x17\x56\xfd\x97\x04\x21\x8b\x1b\x8f\x4d\xcb\x54\x30\xc0\x25\x04\x2f\x47\x16\x9b\xfc\x7c\x80\xd7\x1c\xab\x8c\xa0\x7f\x34\x0a\xfa\x00\x8a\xbb\xe2\xe3\xa0\xab\xe1\x41\xda\x8d\x41\xca\x6b\xd6\x9d\x36\xfd\xb1\x1a\x41\xce\x0b\x72\xfa\xbc\x00\xd9\x7e\xa6\x05\x27\x00\x10\xb2\x59\xdf\x8e\x10\xdd\x22\xdc\x17\xc1\x39\x90\xa0\x5f\x02\x33\xe3\xca\x85\x6b\x40\x97\x1c\xb3\xe2\x1c\x8b\x39\x50\xb1\x3f\xc8\x4e\x1f\x26\x6c\x2a\x6f\xbe\xce\x88\xd5\x97\x25\xc3\xcf\xb2\x22\x5d\xbc\x1e\xe9\x5b\x68\x6d\xb7\x04\xfc\x93\x7b\x76\x6f\x0a\x9b\xfe\x95\xa4\x2b\x90\x10\xf1\x22\x9c\x61\x0d\x7e\xde\x09\x57\x12\xc8\xf0\xf1\xfb\x00\x47\xc0\x40\xa8\x70\x30\x6c\xd8\xdc\x74\xc4\xda\x51\xbf"}, +{{0x42,0xb5,0x36,0x52,0xd0,0x8b,0x5d,0x76,0x6e,0x66,0xad,0x8f,0x3e,0xbf,0x69,0x3c,0xfd,0x77,0x90,0x7c,0xad,0xd9,0x8b,0x54,0x66,0xdf,0x77,0xdf,0xa2,0xc6,0x37,0xad,},{0x88,0x46,0x3b,0xb8,0xa4,0xb6,0x38,0x8d,0x92,0x4c,0xb8,0x62,0x09,0x83,0x41,0x95,0x43,0x5d,0x79,0xd7,0x7f,0x8c,0x02,0xf4,0x6b,0xbd,0x16,0xd8,0x2e,0xfe,0x42,0xb3,},{0x30,0xc4,0xb9,0x9e,0x68,0xec,0x33,0x51,0x30,0x8f,0xbc,0x76,0xd9,0xca,0xf0,0xaf,0x62,0x21,0xb5,0x96,0xb7,0x01,0x7f,0xe1,0x0c,0xc6,0x33,0x02,0x3b,0xa9,0x7f,0x02,0x38,0x96,0xfe,0x32,0x2b,0xaa,0x34,0x76,0x60,0x61,0x0e,0x05,0xfa,0x49,0x3d,0x21,0x8f,0xa3,0x60,0xf1,0x8d,0x93,0xe2,0x75,0xd1,0xef,0xf6,0x66,0xb6,0x3d,0xb2,0x04,},"\x9e\xe9\x13\xc7\x4e\xe3\xc5\xe8\xc9\x0d\x64\xb8\xae\x3a\x60\x04\x9f\xc7\x65\xe1\x76\x06\x0b\xcd\x1c\xd0\x9f\x0e\xda\x60\xbf\x23\xba\xdb\x8a\x1c\xaa\xc3\xd6\x6e\xbc\x52\x68\x14\x6e\xe4\xa5\x4e\x1e\xb2\x31\xed\x25\xef\xf9\x5b\x90\xa6\xe9\x83\x37\xa5\x40\xa3\xf4\x84\x49\x79\x4a\x48\x73\xbf\xc2\xe8\x47\x28\x96\x6b\xb7\xc6\xff\x67\x6a\x2f\xf5\x73\x11\xc1\xc2\x5e\x15\xfb\xf3\xd4\x0e\x9f\x25\xab\x5d\xb9\x1f\xdd\xb7\xa0\xae\x43\x6c\x8e\xc0\x70\x75\x4b\x6d\x74\x3a\xa1\xd6\x04\x8f\xb5\xbd\x7f\x5b\x8e\x4c\xca\xd2\x03\x28\x38\x95\x30\xf1\x13\x74\xa4\x89\xb1\xd5\x05\x31\xa3\x9c\x9b\x32\xb4\x03\x69\x62\x60\x06\xd2\x64\xa9\x9e\xec\x4f\xac\x13\x41\xf4\xe7\x46\x79\x45\x7b\x41\x8e\x6b\xbf\xba\x23\x3f\x1c\xa1\x58\xf7\xb2\x9d\x40\xd5\x03\x01\xf9\xd9\x25\x36\xfd\xc5\xc2\x3f\xe5\xde\xe4\xd6\xdf\x0e\xbf\x13\xdf\xa3\x75\x4a\x14\xc8\x56\x00\x9a\xde\xa1\xdd\xa4\x09\x30\x4c\x1f\x60\xd2\x53\x30\xfb\x10\x95\x79\x47\xa0\x05\x08\xf2\xfd\x76\x42\x2e\xac\x69\x4c\xc3\x9f\xa8\xae\x7f\xcc\x77\xa0\x2f\xd9\xee\x5f\x91\x0d\x93\xe8\xaa\xc6\x8f\x14\x5d\xd8\x78\x87\x6b\xa8\xed\xa0\xa4\x9f\xcb\x20\x9c\x34\xea\x22\x0d\x4d\x06\x05\x54\x6f\xc4\xa8\x09\xba\xf0\x10\xd5\x33\xe4\x5d\x17\xb0\xe1\x6a\x46\xe9\x1e\xa6\xfe\xc2\xcd\xc5\xa8\xb3\xec\x50\x14\xb2\x5e\x92\xd8\xe5\xc9\x28\xab\x06\x99\x3d\x4f\xe2\x3a\xc8\xd4\x5c\x89\x03\x78\xdd\x13\x3f\x00\xed\xb9\x37\xc0\x71\xf7\x5c\xfc\x13\xa4\x02\xe3\xe4\x29\xa8\x48\x65\x2a\x17\x5c\x9b\x6f\x6e\xac\x86\xf6\x18\x8a\x44\x48\xa9\x6c\xe2\x87\x2e\x5f\x65\xf9\xbd\xb8\x71\x66\xc9\xb8\x7a\x7e\x95\x8e\x80\xbb\x65\x66\xe3\xfc\xf8\x71\x19\x0c\xf4\xa8\x67\xe6\x12\xcf\xc1\xe4\x37\x1d\x2b\x73\xd2\xa0\xad\x0a\xa4\x00\xba\x69\xe6\x63\x36\x23\x3b\x0f\x3c\x52\xb8\xa6\x8b\xca\x05\x12\x56\x01\x25\x50\x46\xe6\xf4\x9d\x68\x8d\x2d\xb8\x5c\x7b\x82\x12\x70\x51\x6e\x3c\x06\x13\xf3\xf2\x3f\x9c\x57\xcb\x4c\x87\x14\x28\x5c\xdf\x95\xe1\x06\xa3\xb5\xaf\xca\xeb\x81\xb7\x2f\x34\x3e\x87\xbd\x92\xf1\x58\x1d\xcf\x9a\xa9\x0a\x02\x4f\xa4\xa1\x04\x80\x59\xe3\x0d\xe8\xff\x0d\x16\x79\x4d\xcd\x74\x5d\x2b\x2d\x53\x4c\x52\x0f\x82\x78\x53\x86\x74\xa9\x34\xc6\xf1\x4a\x84\x28\xe3\xda\x01\x8a\x36\xe4\x5a\xa5\x82\x7c\xf4\xb1\x52\x84\x34\x6f\xd6\x93\x63\x14\x92\x19\xbb\x0d\x1b\xc9\x27\xd8\xd1\x93\xc4\x82\x69\x2f\x97\xdc\x88\xd8\xed\x33\x7d\x0c\x9d\xc9\x9c\x7a\x5e\x11\x1d\xce\xd4\x22\x50\xd5\x80\xe2\x06\x92\xbb\x7b\x88"}, +{{0x14,0xcf,0xe0,0x0f,0xa7,0x19,0x0a,0xe8,0x10,0x88,0x8a,0xe2,0xbb,0xd0,0xff,0x64,0x12,0xcf,0x1f,0xd4,0x08,0xa3,0x08,0x29,0x43,0x83,0xa1,0x94,0x53,0xb5,0x90,0x73,},{0x4e,0x61,0xaf,0xe8,0xc1,0x74,0xb6,0xee,0x1a,0x29,0xfa,0x09,0xcf,0x87,0xb4,0x00,0x81,0x39,0xf1,0x07,0x0b,0xc8,0x53,0x1b,0x6d,0x06,0xf5,0x4c,0x95,0x62,0xa4,0xf3,},{0xf7,0x85,0xa4,0x6f,0x69,0xbb,0xd0,0x99,0xfa,0x01,0x11,0x24,0xba,0x90,0x32,0xc1,0x89,0x74,0x2c,0x9e,0x00,0x1d,0xbb,0x87,0x81,0xd8,0x22,0x33,0x45,0xa9,0x56,0x9d,0xc1,0x44,0xca,0x69,0x4d,0x90,0x24,0x5e,0x0e,0x51,0x3e,0x88,0xab,0x02,0x3f,0x7f,0x0f,0x99,0xb7,0x41,0x61,0x59,0x75,0x8d,0xd0,0x34,0xe7,0xa8,0x9c,0xff,0x36,0x00,},"\xbc\x66\xf8\x01\xda\xa8\x29\x85\x8e\x74\x02\x93\xd4\xd2\x18\x7b\x8e\x1a\x5a\xfb\xa5\xfd\x67\xb1\x09\x56\xc6\x53\x46\xac\xa9\x44\x29\xd3\x2e\x4c\xfb\x35\x84\xab\x0e\x00\x5d\x0d\xd7\x42\x78\x1d\x47\xe8\x94\x47\xc4\xe1\xd8\x1b\xf7\xe6\x15\x4f\x8f\x73\xaf\x03\x36\x1a\xd5\x6e\xa3\xc0\x60\x00\x75\x4b\x9f\x32\x7d\x4e\xde\xac\xc4\xd3\x48\xaf\xb5\x48\x23\xe1\xc9\xd4\x9c\xd8\xff\x2b\x19\xf4\x20\x21\xb4\x0d\x58\x0c\x39\xce\x3d\x24\x36\x61\xb8\x54\x21\xfe\xc9\x15\xba\x9d\xd2\x76\x2f\x85\x0b\xd2\x08\xfd\xbf\x20\xff\xab\xa5\x6a\x46\x86\x60\xf1\x7c\x00\xfb\x1c\x0f\x4e\x85\x27\xa5\x09\xdd\x4e\xec\x13\x36\x0c\xf6\xe3\xca\xc5\x42\xb8\x75\x18\x2f\x2a\x7c\xe7\xbe\x0a\x33\x30\x2f\xe2\x6d\x36\x29\x62\x93\x84\xe3\x5c\x06\x78\x9d\xe6\x34\xe9\x0e\x96\x4f\xbd\xa8\xcb\xba\x98\x11\x1e\x22\xe8\xd0\x76\x26\x84\x26\x6a\xab\x76\xae\xba\x4a\x38\x07\x78\x69\x68\x14\xa1\xe3\x11\x94\x3c\xb3\x50\x58\x92\x64\x0c\x44\xe3\xaa\xc4\x53\x0c\x50\xac\x60\x4a\x8d\x2c\xcc\x7c\xea\xbf\xfe\xa4\xaa\x3d\x7f\x48\xa6\x6d\xcd\x75\x88\xb8\x02\x09\xdb\xc1\x73\xf0\xc6\x63\xe8\xfc\x87\xa3\x6e\x89\x2e\xc9\xa3\xff\x8f\x60\xd2\xe0\xd8\x70\x4e\x5b\x6c\xbb\x87\x32\x75\x15\x1a\xd4\xcc\x00\x57\x16\x50\x31\x90\x50\x39\x65\x1c\xa1\x0a\x95\xc6\xfd\xa3\xb2\x78\x27\xa6\x57\xef\x9a\x5f\xc3\xeb\x5b\x53\xca\xc6\x1d\xda\xf5\xa4\x17\x04\xc8\x78\x57\x0c\xbc\x3c\x41\xc4\x75\xb1\x17\xc0\x5e\xab\x0b\xb1\x96\xbc\xb7\xc4\x33\x34\xde\xbd\x64\xb9\xe3\x74\x50\xd2\x3f\x5c\x10\x16\x1e\xc5\xab\x4f\xcc\xd7\xcf\x30\x8e\x2a\x99\x95\xcc\x9e\x57\x8b\x85\xe8\x28\x5a\x52\x08\xb9\xef\xd4\x2a\xf9\xcf\x2a\xc2\xb3\xb7\x46\x42\x54\x88\x9a\x21\x87\x31\x7e\x32\x49\x97\x09\xb9\x13\x95\x3a\xd4\x6f\x1c\x23\xe1\xb6\xb5\x6f\x02\x4c\x4a\x7d\x48\x46\x11\x92\xc0\x1c\x56\xc5\x4c\x56\x47\x91\xec\x0a\x67\xb6\x1a\xcb\xf9\x57\xe6\xd0\xd7\xda\x80\x53\xed\x13\xa4\x18\x93\xd7\x67\xfc\x57\x37\xcd\x19\x55\x53\xda\x5d\x5b\x07\x06\x5f\x47\xd7\x2a\x35\xc4\x2b\x00\x1e\xb6\xdb\xd0\xf8\xe7\x7a\x4b\x76\xa6\x26\x61\x92\x64\x7f\x41\x55\xea\x11\xbd\x12\x37\xba\x77\xc8\x7c\x62\xbf\x4b\x01\x14\x9f\xc5\x8b\xc2\x8f\x0b\x5a\x28\x64\x85\xd3\x71\x7d\x32\x39\x64\x04\x62\x18\xe7\x0c\x7e\x38\xb7\xd5\xe7\x4b\xa6\xb1\x2b\x02\x2f\x18\x19\x7d\x92\xc1\x3b\xca\x89\x33\x5c\x85\x6c\xbc\x57\x56\xaa\x3b\x64\xec\x1f\x46\xe3\x96\xb1\x16\x1c\x87\x1c\xd2\xdf\xde\xd1\xa4\xec\x91\x92\x74\x29\x37\xc0\x70\x45\x31\xc7"}, +{{0xac,0x0f,0x7f,0x04,0x18,0xde,0x67,0xe3,0x48,0xfa,0x6d,0x56,0x86,0xc4,0x6d,0x21,0xca,0x72,0x62,0x2e,0xe6,0x9e,0xaa,0xbe,0x00,0xd5,0xc9,0x07,0x5a,0x34,0xf1,0x79,},{0xfe,0xab,0xde,0x08,0xf0,0x0a,0x2b,0x68,0x2b,0xce,0x9d,0x45,0x99,0x0b,0xf4,0x5a,0xfc,0x95,0x83,0x39,0xdc,0x44,0x10,0x6d,0xad,0x33,0xb2,0xc4,0x90,0xef,0x70,0x90,},{0x75,0x91,0xcf,0x82,0x57,0xbe,0xad,0x39,0xa1,0xad,0x3b,0xa1,0x91,0x8d,0x51,0x8e,0x67,0x24,0x35,0x6b,0xf6,0x25,0xa5,0x73,0xea,0xe5,0x01,0xd1,0xaf,0x94,0x6c,0x13,0xc2,0x90,0xcb,0x63,0x15,0x6e,0xc9,0xd3,0x62,0x72,0x6e,0xe5,0x0b,0x39,0xfc,0x0a,0x7a,0x2b,0xbd,0x69,0xd4,0xa8,0x1b,0x75,0x93,0x2a,0x90,0xf8,0xc7,0xac,0x7d,0x03,},"\xe8\xd0\xe8\x32\x53\x35\xe0\xf3\x5a\x85\x46\x7b\xee\xd1\xe1\x1c\x6a\x20\x78\xc3\x5a\xe4\xa4\xa1\x05\x43\xed\xe4\x0c\x17\x12\xbc\x95\x20\x12\xd2\xf8\xfe\xc1\x05\xae\xf7\xc6\xc6\x5b\x36\x34\xb4\xa7\x4b\x22\xb4\x98\xb9\x13\x50\x7d\x1f\x6c\xfd\xe8\x38\x58\xe6\x83\x0c\x0a\xf4\xf4\x64\xa6\x89\x9d\x5c\x4e\x27\x9a\xff\x36\x75\x4c\x21\xda\x80\xa1\xbb\xd1\xdc\xf4\x62\x20\x37\x5b\x1e\x11\x2a\x5a\x72\xf1\xab\x6e\x8f\x64\x19\x42\xf6\x6d\x9b\xbd\xbb\x17\x9c\xf0\x13\x9e\xa8\xde\xb0\xf4\xb8\x14\xf5\x0c\x51\x33\x29\xa1\xa0\xe2\x67\xc4\x43\x3a\x23\x31\x82\xbc\x4a\x2a\xcb\x2c\x6d\x4f\x00\xb2\x40\x94\xd3\xbd\xc0\xeb\x81\xcf\x37\xd3\x82\x60\xc2\x10\x7d\xd9\x49\x06\x13\xd2\x76\xee\x1f\x72\x26\x6c\x6e\x4a\xcc\xa5\x24\x98\x11\xa0\xf8\xa7\xda\xe6\x6a\xed\xb7\x5c\x3d\xf4\xc8\xca\x3c\xb5\xd9\xc5\x67\xba\x54\x1e\xe5\xa9\x14\x0c\x50\x58\x72\x72\xaf\x34\x53\x0a\xb8\xb0\x8b\x9e\xc0\x32\xea\xc0\x60\x39\xe6\x92\x63\x0e\x2d\x55\x4d\xf7\x7c\x1a\x03\x88\xb3\xca\xaa\x3b\xe3\x75\x4a\x84\x96\x1f\xb2\x99\xe4\x02\x22\x71\x58\xce\x36\x3e\xac\x26\x47\x8d\x47\x97\x75\xe5\x68\x5a\xdb\xf8\x28\xbb\x35\x5e\x3c\x89\xcc\xe2\x41\x50\x3c\x15\x36\x64\x32\xba\x94\xcd\x3c\xd9\x54\x79\x14\x4b\x63\x6e\x0d\xe7\x0b\x3f\x16\xd1\xa3\xca\x51\x8e\x39\x90\x09\xa4\xc2\x47\xa7\xf9\x63\x67\xc7\x14\x66\x08\xaa\xcc\x00\x14\xfc\x35\xb8\x4a\xf9\x93\x3f\x09\xba\xbb\x89\x93\x7a\xbb\x8c\xed\x11\x18\x91\x34\x3d\xdb\x79\xf6\x0b\x78\x89\x8a\xb5\x93\x8f\x8b\xa3\x81\x4b\xd8\x00\x26\x05\xb1\xdf\xd2\x97\xfa\x07\xc4\x75\xa0\xd4\xf8\xf4\x45\x1a\xcd\x70\x7d\xe8\xaf\x6c\x0e\x88\x18\x83\x3a\x3a\xbe\x5c\x96\xd1\xa8\xc6\xc9\x6e\x2c\xb6\x33\x28\xeb\xa4\x4d\xd1\xd3\x46\x84\xe4\x12\xf2\x88\xe0\x65\x20\x9d\x11\xeb\x80\x94\xd2\x2e\x4c\xc8\x02\x62\x9c\xcb\xa3\x39\x26\xbf\x1a\xd3\x6a\x62\x85\x13\x8a\xbe\xe0\x5c\x5a\x39\xa4\x75\xf3\xfd\xd0\xb3\xec\x8c\x37\x0c\xd9\x57\xa8\x37\x9e\xc2\xcd\xaf\x03\xe8\x95\xc1\xba\x12\xb4\x49\xd6\xcd\x8b\xe0\xf3\x5d\x99\xe2\xb7\xfb\xaa\x92\xdd\x54\xe6\x4e\x7c\x35\xce\xb8\x8a\x71\xa6\x80\x52\x7c\xb3\x73\xaf\xe1\x4c\xdd\x15\x8a\x0b\x90\xbf\x2d\xae\xc8\x0d\x2e\xdb\xdc\x31\x28\xcd\x6b\x63\xfa\x53\x2a\x1c\x27\x8c\xdf\xe0\xf8\xeb\xb4\xab\xba\x5e\x1a\x82\xbc\x5c\x3f\xed\x15\xc5\x79\x5b\xd9\xff\xb5\x76\x08\x2c\xc4\x79\xfa\x1b\x04\xc5\xc5\xaf\xca\xd2\x69\xa0\xf1\xad\xdf\xe7\x60\x42\xc3\xa8\xf1\xf2\x53\x77\xb6\xcb\x72\xec\x16\x14\xeb\x63\x83"}, +{{0xb5,0xa7,0xc7,0x67,0x93,0x63,0x80,0xb3,0xe9,0x87,0x51,0xca,0xfd,0x3e,0xa8,0x9b,0x38,0x8a,0x32,0xcf,0x82,0x8b,0x32,0x1c,0x5b,0xd0,0xcc,0x8d,0xd8,0x5b,0xaf,0x00,},{0xbe,0x7f,0xa6,0x5f,0x1f,0x6b,0xe5,0x10,0x27,0xf8,0xb8,0x48,0xdb,0x7a,0x8c,0x40,0x49,0x61,0xbf,0x1e,0x21,0xa2,0x3d,0xf2,0x3b,0xb8,0xce,0x05,0x85,0x0c,0xda,0xa1,},{0x60,0xe4,0xd2,0x3f,0x1f,0x08,0xfc,0xe4,0x66,0xc9,0x91,0x5d,0xde,0xd9,0x32,0x56,0xb5,0x2b,0x32,0x7e,0x5f,0x81,0xfb,0xb3,0x1d,0x1d,0x10,0xd3,0x21,0xc3,0x90,0x36,0x6e,0xf0,0x01,0xfd,0x75,0x9a,0xa9,0xd0,0xa5,0x51,0x62,0xd5,0x36,0x4d,0x91,0x8b,0x48,0xc7,0x32,0x7e,0x77,0xcf,0x53,0x58,0xbc,0x43,0x19,0xe3,0x25,0xcd,0xd6,0x08,},"\x6b\x67\xc7\x95\xd6\x6f\xac\x7b\xac\x84\x42\xa6\xc0\x99\x2c\xb5\x75\x88\x43\xb3\xe3\x93\x9e\x3c\x27\x6c\x6e\x90\x08\xda\x82\x00\x76\x77\xbf\x9e\x67\xe9\xac\x5a\x1a\x0f\x48\x6b\xea\xc0\xd8\x56\x19\x1f\xae\x25\xa1\x27\x39\x2b\xed\x46\x9b\xc7\x8d\xeb\x0c\x4b\x89\x3f\x67\xf1\x71\x6d\x83\x50\x90\x77\xe4\xa1\xbf\xd4\x13\x6d\x03\x15\x2d\xcc\x3b\x76\xd9\x52\x49\x40\xa6\x06\x4c\x66\x9f\xbf\x51\xf6\xb9\x10\x34\xb6\xd5\xf2\x89\x86\x78\xa1\x3a\x24\x70\xf6\x64\x1e\xc8\x02\x45\x7c\x01\x02\xc3\xeb\xf6\x34\x5c\x32\x7e\x74\x1b\x80\x64\x4b\x3a\x99\xbf\x72\xb5\x9a\xb8\x01\x6f\x35\xd2\x51\x88\xa0\x85\x75\x0d\xc0\x60\xe5\xa8\xd5\x24\xae\x21\x3f\x07\x8f\x28\x8c\x7b\x34\xbc\x41\xf3\xce\x35\x6b\xf2\xda\xfd\xd2\xe0\xdb\x4f\xb8\xd7\xc2\xc3\x19\xf9\x90\x60\x05\x97\x17\x02\xe4\x9c\xa6\x2e\x80\x50\x54\x0d\x41\x21\xd2\x42\xf2\xee\xab\x1b\xd1\x34\xe6\x0b\xf1\x1b\x3e\xc7\x1f\x77\x65\xa9\x7c\x0e\x09\x84\x55\xe5\x9d\x22\x35\xd6\xb3\x7e\x7c\x9f\x5b\x21\xfa\x11\x2c\x3b\xa3\x9e\x4e\xa2\x00\x61\x4f\x58\xdf\xb3\xeb\x7b\x83\x6f\x0b\xec\x1d\xdd\x43\x8d\x14\x22\x45\x0a\xe7\xde\xd1\xdf\x9d\x71\xe5\xd9\xbc\x8f\xa3\xb6\xe6\xf7\x84\x46\xce\x7c\x79\xd0\xbc\xfb\x1c\x2d\x26\xc6\xfe\xce\x68\x68\x2d\xff\xc6\x0a\x9c\x6e\x0a\xd0\x5f\x2a\x09\xf2\x1d\x75\x23\x25\x1c\xb0\xc3\xd0\x8e\xfb\xbf\x8a\xc1\x63\x39\xd7\x17\x02\x4d\x67\x60\x24\xc1\xee\x3c\x1f\x62\xc5\xae\xab\x7f\xff\x93\x7c\x57\x45\x4d\xf7\xbd\x96\xf9\x84\x4a\x2a\x39\x99\x58\x41\x8a\xaa\x6f\x18\x48\xbe\xbf\x7b\xf1\x29\x2c\x24\xeb\x5c\xd8\xea\x56\x34\x0c\x5b\xeb\x26\x88\x02\x4a\x69\x53\x27\x5b\xe6\xef\xd1\xb7\x1b\xa8\xbe\x6e\xb7\x7f\x0c\x65\xa7\xc5\x11\x1b\x96\xc4\xc1\xf3\x9c\xb7\xaa\xf8\x3f\xda\xae\x8d\x14\x8d\x7a\x8a\xf4\x0a\xe9\xe6\x51\x91\x9f\x7c\xe2\x8c\x8b\x2b\x6e\x45\xe4\xd3\xd5\x6f\xdd\x54\xd0\x0c\x24\x12\x79\x0c\xbd\x6f\x80\xe1\x08\x19\xe0\xb8\xf3\x7c\x84\xfa\x00\x49\x88\xad\xaf\xcc\xbb\xc2\x1c\x63\xd6\xbf\x2e\x73\x2d\x9d\xd6\x3b\xd4\x9b\x04\x12\xb9\x67\x4e\x1e\x88\xf6\x14\x2f\x7f\x86\x7f\x1f\x26\x89\x1b\x22\x43\x04\x23\xce\xc4\xdb\x91\xb6\x1c\x2a\xbc\x5c\x8f\xbd\x46\xb8\xb9\x35\x96\xfc\x51\x60\x68\x31\x36\xe2\x11\x29\x82\x27\x96\xeb\x5e\xa0\x88\xe0\xa7\xd8\x12\x1b\x25\x57\x2e\x3e\xc3\x77\x43\xd1\xff\x6d\x8d\x1c\x35\x36\x43\x9a\x10\xe8\x4a\x66\x5f\x2c\x75\xee\x73\xcd\xc6\xff\xac\x4c\xc2\x87\x24\x46\x9f\x79\x70\xb4\x75\x07\xdf\x3e\x1b\x14\xd4\x77\xae\xc2\xbb\x20"}, +{{0xe1,0x36,0xf3,0x98,0xa6,0x05,0xd1,0x34,0x57,0x84,0x8c,0xea,0xd0,0x7c,0x72,0x86,0xf4,0x2e,0x2f,0x28,0xdf,0x8c,0x12,0x8a,0x3d,0x0b,0xb7,0x2b,0x29,0xaa,0xcc,0x19,},{0x6a,0xa5,0x04,0x5a,0x66,0xf7,0x72,0xa5,0x71,0xfe,0x3e,0x42,0xd1,0x17,0xef,0xcd,0xf6,0xc4,0x95,0x91,0x99,0x61,0x86,0x01,0x2f,0xa9,0x8f,0x7c,0x48,0xe0,0xcd,0xa7,},{0x75,0xa4,0x5c,0x6b,0x95,0x66,0x89,0x98,0x29,0xb4,0x1e,0xe5,0x17,0xb7,0x04,0x5a,0x47,0x3a,0x4f,0x7a,0x26,0x41,0x43,0x9b,0x5d,0x7c,0x56,0x73,0xe0,0x0d,0x8f,0x5c,0x06,0x6f,0x12,0x91,0xf8,0x5d,0xea,0xda,0x05,0x02,0xbd,0x16,0xe9,0x70,0x9f,0x82,0x7d,0x47,0x51,0xf2,0x87,0x38,0x62,0xe8,0x21,0x9e,0x57,0x74,0x6a,0x19,0xa9,0x00,},"\xd3\x28\x57\x9d\xe4\xc5\x37\x2f\x3b\x38\x2c\x48\x01\x1b\x2d\x4c\x60\x29\xf9\x04\xf3\xa3\x3e\x07\xd0\x83\xd7\xe2\xb0\x37\x56\xaf\x2c\x4c\x97\xa2\xd6\x6c\x10\xec\x41\x54\xd8\x74\x79\x20\x42\xb6\x46\xe4\xaa\xe5\x10\x1d\x50\x1b\xd1\xbf\x6f\x51\x17\x51\xd0\xaa\xf8\x21\xcd\x7c\x0b\x3e\xe6\xd0\xd7\xc6\x90\xa2\x77\x7f\xe1\x6b\xdc\x7e\x49\xb7\xda\x4b\xbb\x4c\xce\x3b\x61\x8e\xe9\xb6\xf2\xe3\xa1\x92\x40\xcd\xb7\x07\x33\xb9\x84\xb1\xc9\x40\xec\x66\x96\x0b\x72\x8c\xbb\x87\x4b\x80\x64\x31\x23\x72\x2d\xb9\xdb\xbe\x88\x32\x20\x08\x93\x1b\x1c\x89\x4e\xf5\xd2\x10\x99\xe6\x3e\x7c\x65\x00\x7a\xcd\x61\x78\x4d\xb4\x99\x4a\x2f\xb4\x0c\x3e\xfe\x9c\x47\xfa\xd6\x37\x63\xdd\xe0\x6f\xa0\x17\xa2\x6b\x82\xe7\x1b\x9d\xaa\xbc\x4f\xf0\xf6\xc7\x9b\x8c\xa7\xcc\xb4\xdc\x20\x31\xbe\xf1\x08\x73\x67\xc7\x08\x69\x74\xa0\x05\x66\xde\x41\xa7\x1e\x11\xd9\x93\xab\xe4\x33\x56\x98\x92\xb8\xf7\x5d\x76\x37\x99\x32\x45\xc8\x84\x47\x8a\xbe\x3f\x95\xf4\x4b\x0a\x4b\xbe\xde\xfe\xf8\x90\x6b\x75\xe0\xd3\x40\x20\xae\x53\x64\x55\xb0\xe0\x6f\x9b\xfe\xe1\x1e\xc9\xb8\x60\x4b\xac\x2c\xc6\xeb\xe0\x8c\x8f\xd5\xf5\xcc\xcc\xcb\xc1\x61\x7b\x7c\xf6\x9a\x3c\x51\x2e\x1f\x0b\xdb\x58\x5d\xf5\xe1\x27\x43\x06\x1f\x7c\x20\x53\xbc\x37\x14\x43\x61\xc0\xb3\x5f\xd3\x9d\x56\xb1\xef\xaf\x92\xc6\x10\x36\x01\x93\xec\x20\x59\x8b\x82\x85\x80\x50\xa6\xd9\x9e\x08\x2b\xce\xfd\xbd\x53\x18\xee\x5e\xfb\x3b\x26\x0f\x32\x76\xf3\xc7\x3f\x9c\x24\xce\x0c\xda\x33\xc7\xac\xc5\x0c\xa5\xdd\x61\xbd\xb8\x5d\x79\x38\x25\xf6\x73\x2a\x6e\x33\x0c\xe6\x72\xac\x44\xfe\x6b\x2b\x9a\xfe\x6e\x2e\x96\x5c\x02\xd2\xa1\xfe\x0b\x57\xcb\x1b\x31\x7c\x1d\x31\x3e\xfd\xc3\x56\x49\x2f\xe8\x96\xfd\x14\x9d\xae\x51\xc9\x5c\xcd\xbb\x7d\x11\xf7\xd6\x10\xe0\xc6\xe2\xfd\x3e\x57\xfc\xfe\xf1\xc5\x7c\x71\x19\xa0\xaf\x6c\x78\x21\xfe\xcd\xb8\x9d\x80\x30\x2b\x49\xfa\xd4\x17\x43\xf3\xd2\xd7\xa0\x75\x15\x4b\x31\x43\xe5\x1a\xeb\x94\x7d\x4b\x5e\x8b\x7e\x4c\xa8\x6f\xec\x3e\x80\xbd\x9a\x78\x6e\x4e\x46\xed\x1e\x6e\x9f\x7e\x0b\x63\x52\x66\xd9\xfa\x09\x7a\xa9\xe2\x0f\x32\xe3\xd2\x77\x2d\x7c\x1f\x00\x8b\xcd\xd3\xf9\x2c\x72\x83\xc5\x77\x90\xc3\x62\x2c\xba\xd3\xca\x35\x80\x3c\x45\xc8\x69\xdc\x37\x7f\xf3\x6b\xd7\xc0\xe6\xf1\xbb\x89\x2f\x73\x29\xa6\xe0\x8d\xf1\xdb\xeb\xc8\x1d\xc7\xb1\x15\xf8\x52\xe3\x6a\xe5\xd9\x28\x72\x5f\xa7\xc6\xfb\x9f\x28\xb0\xfb\x39\x4f\x9e\x38\xfd\x87\x62\x5c\x5f\xa2\x3a\xab\xa4\x70\x54\xe8\xcf\xea"}, +{{0x97,0xb6,0x70,0x2e,0x24,0x68,0x05,0xdb,0xcf,0xc7,0xfa,0x42,0x4a,0x8c,0xaa,0xbc,0xf2,0x62,0xd4,0x66,0xa0,0x5e,0x0d,0xd2,0xd4,0xe7,0xc3,0x74,0xd5,0x7d,0x52,0x51,},{0xa7,0x16,0xc3,0xd5,0xce,0x78,0xf4,0xd9,0xc5,0xbe,0xe3,0x44,0x7d,0xda,0xf4,0x88,0x1c,0x98,0x6e,0xfd,0xf6,0x67,0xac,0x89,0x77,0xb4,0xfb,0x69,0xb5,0xa7,0x11,0x0a,},{0x90,0x00,0x55,0x41,0xdc,0xc1,0xd7,0xab,0x83,0x7f,0x4d,0xe5,0x39,0x3f,0xad,0xd6,0xa9,0x2b,0x26,0xa7,0xd9,0x3a,0xf3,0xf6,0x69,0xe0,0xf1,0xbf,0xd6,0x21,0xcb,0xd0,0x0c,0x8a,0x23,0x05,0x6d,0x2d,0xa6,0x78,0x65,0x57,0xc8,0x28,0xa4,0x9b,0xe1,0xe4,0x02,0x1d,0x99,0x31,0x12,0x35,0xac,0x0d,0x4d,0x56,0xee,0xfc,0x7c,0x95,0x36,0x05,},"\xea\xa8\x6c\xf7\x6f\xcb\x65\xc6\xf9\xfc\x20\x8a\xc3\x6f\x28\xb2\x00\xd3\xb4\x03\xac\xa7\x32\x07\x46\x1d\x8d\x96\xaf\xa2\x46\xd7\xc6\x9d\x17\xa7\xa9\xbf\x77\xf0\x55\x43\x56\x3a\x7d\x3e\xca\x1d\x40\x79\xe2\x29\x38\xab\xa1\xf6\xe9\xe0\x4b\x49\xfb\xc8\xed\x6f\x63\xb5\x99\x73\x0d\xe9\x97\x98\x31\xc0\x2f\x8c\xba\x61\xe5\x55\x60\xd7\x11\x0d\x4c\x6e\x61\x67\x97\x06\xa7\x15\x5d\x5a\x67\x3c\x54\xd1\x6f\xe4\xd2\x28\xc2\xec\xa7\x54\x6f\xaa\x13\x39\xf2\x6d\x7a\x0b\xb4\xee\x33\x96\x11\xaf\xde\xc9\xa6\x8f\x5f\xf5\xb5\xd2\x03\xb6\x00\x53\x3a\xd5\xa3\xb3\x68\xc8\x5d\xa1\x15\x63\xf0\x98\xcc\x26\x87\x1e\x7f\xa9\x9a\xef\xd3\x8c\xc2\x61\x51\xdb\x3b\x0b\xae\x38\xdb\x6a\x87\xb6\x78\x9e\x58\x40\xb1\x08\x84\xaf\x51\x1f\x3e\xcb\x3e\xcb\xf9\x4f\xf8\x6f\xdb\x90\x55\x05\xa8\xc3\x4b\x2a\xa6\x1f\xf2\xec\x9e\xc8\xfe\xbd\x1d\xfe\xd0\x96\x5b\x6f\xc5\xb9\xf8\x86\x9d\xc3\xa4\x75\x59\x97\x4a\x88\x22\x99\x67\x06\xda\xef\xbc\x6c\x5b\xf9\x84\xce\x06\xb0\xd3\x2b\x31\xcf\x9d\x8a\xd1\x36\xae\xd4\xb0\x52\x58\x6d\xce\x70\x73\xb7\x67\xb2\x34\xe4\xa3\x7b\xeb\xbc\x39\x3d\xd2\xe0\xf7\xd1\x55\x17\x35\x48\xc3\x8a\x15\x83\xef\x94\xe0\xaa\x84\xe7\xfc\xe0\x4f\xcc\x9b\x4e\x30\x0a\xd0\x99\x44\x9a\x49\x23\x2a\xbd\xcf\x3d\x1a\x6e\x6f\xca\xb6\x96\xf5\x99\x6f\x9b\xd1\xb9\x48\x5d\x07\x47\x55\xac\x5b\x42\x97\xfe\xe3\x12\x4c\x7c\x03\x97\x6a\x40\xd5\x70\xbe\xae\xc2\xfa\xc9\x92\x33\x9f\x88\x5f\x74\xd4\x0e\xd4\xac\x87\xa4\xf4\x0c\xef\xbc\x48\x64\xf4\x4c\x36\x83\xaa\x8f\x10\x26\xe2\xc3\x7a\xef\xfc\xeb\xfd\xfe\x24\xdd\x0b\x01\x9c\x36\xa7\x98\x88\x20\x30\x04\xb2\xad\x83\xe8\x92\x21\xf3\xf6\x36\xf4\x55\xbb\x64\xe1\x7d\x17\x54\xc7\xc6\xdd\x7f\xc0\x9a\x0d\x65\xdd\xdd\xed\x46\x22\xfc\x4f\x9f\xba\x07\x2b\x45\x10\x34\x35\xe1\x02\x20\xa5\x86\xf1\x52\x26\xd2\xeb\x37\x7f\x40\x64\xd3\xff\x37\xcb\xb4\x70\x5a\x1f\xaa\xf5\xb3\x48\xf8\xc0\xef\x7f\xd1\x56\x4d\x42\x86\x88\xf5\x8f\x33\x92\x96\x7c\xf3\x96\xa8\xff\x2f\xd9\xe7\xb5\x17\xb7\xd6\xa5\xed\xe7\x44\x03\x73\xd8\xcc\x1a\x83\x99\x00\xe8\x4d\x42\x25\x42\x83\xd9\x69\x9c\x7c\xa3\x7e\x47\x76\x92\xa3\x49\x40\x08\xb8\x04\x44\xc5\xcf\x61\x4c\xbb\xc1\x69\xbf\xb9\x29\x63\x03\xc6\x45\xe2\xce\x28\xd1\x68\xdc\x6c\xba\xef\xae\x9c\x73\x19\x1f\x57\x15\x1a\xa4\x73\x00\x9d\x29\xe1\x80\x0b\x10\xf4\xc4\x98\x60\x9b\xa1\x15\x20\x98\x5c\x78\x09\x20\x58\x69\x6f\xdb\xca\x9c\x02\x0e\x2d\xfb\x8a\x04\x3a\x3d\xe8\xe4\x52\xd5\x8c\xd1\xad"}, +{{0xd1,0x52,0x8c,0x14,0x06,0xa6,0xe4,0x94,0xa0,0x2f,0x63,0x53,0x05,0xfa,0x74,0xd7,0x45,0xc6,0x93,0x27,0xfd,0x31,0xb7,0xd2,0xc2,0x62,0x3d,0xe2,0xc0,0x30,0xed,0x85,},{0x0c,0xfe,0x36,0x9c,0xf9,0x3d,0xaf,0x6d,0x53,0xef,0x02,0x8d,0xdb,0x9f,0x00,0x04,0x43,0xb0,0x97,0x2f,0xe2,0x53,0x2f,0x83,0xa4,0x1c,0xe6,0x57,0xc1,0x83,0x6c,0xa3,},{0xb8,0x39,0x9b,0xc3,0x32,0x6c,0xba,0x0a,0x93,0xa4,0x24,0x97,0x16,0x8b,0xf5,0x7f,0x91,0x06,0xee,0x43,0xd3,0x9b,0xf0,0xfc,0x86,0x68,0x51,0x99,0xdc,0x6e,0x0a,0x13,0xb9,0xc7,0x24,0xef,0x17,0xe7,0x88,0x2a,0xf8,0xc2,0xeb,0x70,0xf6,0xc9,0xe4,0x2d,0xfa,0x2f,0xbf,0x0c,0x1c,0xb5,0x00,0x2b,0x58,0xf1,0x08,0x66,0x19,0x73,0x3e,0x02,},"\xab\xb3\x67\x3f\x3f\xa1\x7a\x33\xa7\xaf\xf7\x6e\xac\x54\xe7\x68\x7c\x04\xbc\x84\xf7\x66\x65\x1a\x8b\x24\xba\x22\x94\x79\x08\xb0\x4c\xa4\x59\xfe\xb9\x8a\xce\x7c\xab\x1e\x74\x33\xa6\xa6\xbe\xff\xd8\xd9\x50\x4e\x29\x91\xda\xa0\x64\x4d\x61\xb8\xb2\xe4\x54\x48\xf5\x4d\xf8\x81\x3f\x50\xc4\x18\xb4\x8f\x49\xe1\x03\x4e\x85\x1c\xbe\xc3\xef\x0a\x18\x50\xef\x72\x67\x33\xaf\xaf\x68\xe1\xa4\x61\x04\x16\x51\xc1\x38\xd5\x4e\x4e\xf7\x81\x87\xaf\x9a\x73\x42\xf7\x12\x87\x27\xf9\x03\xbf\x4f\xc5\xef\x3e\x40\xc6\x4e\xc2\x6f\x89\x2f\x59\xad\xd9\x8f\xe3\x94\x76\x5a\xaa\x7d\x09\xca\xe8\x1b\x9f\x69\x9a\x9d\xd8\xbf\x2e\x2f\xe8\xe1\xec\x78\xfc\x88\x4e\xaa\x0d\x2d\xbd\xbf\xb8\xc1\x68\x83\x3e\xe0\xd2\x18\x03\xcc\x35\xdc\x62\x8d\x7c\x07\xe0\x44\x04\xfb\x60\xe8\xc4\x90\xa8\xdd\x34\xed\xbc\xba\xaf\x80\xcc\xda\xe3\xf7\xd3\x73\x9e\x0e\x89\x70\x23\xee\xb5\xb1\xa8\xc0\x0a\x96\x73\xc5\x92\x58\x24\x0d\xdd\x44\x20\x65\x0f\xe5\x77\x1f\x7e\x28\xcb\x23\x99\xf5\xe1\xe0\x2a\xd0\xb6\x43\x2d\x9b\x49\x60\x8f\xcf\x0b\x1c\x0d\x7c\x41\x2a\x44\x52\x55\xb8\xba\xdc\x53\x21\xc2\x4c\x1a\xc9\x2c\x79\xa0\xba\xcc\xb9\xde\xff\xed\x02\xd1\x2f\x55\x36\xcd\x59\x5d\xc6\x60\x83\xb3\x3a\x36\x03\xa9\xd1\x6e\xce\xa2\xbf\x38\xc4\xf2\xaa\xf5\x70\xf3\x0d\x21\x16\x2b\x2e\xfd\x7e\x4d\x5e\xbf\x1e\xca\xe9\x58\x8e\xee\x36\xdd\x9d\x3d\x8e\x3b\xe7\xbc\x6d\x4b\xc2\x18\x56\x22\xf1\x1d\x1d\xa7\xc4\x9c\x93\xe6\x23\xac\x56\xfe\xe7\xe3\x70\x6d\xb8\x31\x3c\xf9\x26\xbe\x92\xe5\xc8\xa5\x39\xfd\x16\xb0\xf4\x38\xda\x8e\x51\xa5\x1f\x2d\x27\x64\x03\x56\x12\x4e\xf7\xbe\x2f\x91\xff\xa1\x79\x6a\x91\xb1\x23\x01\x93\x4d\xde\xf0\xc7\x93\x8a\x7a\x45\xf3\x6f\x53\xb6\x32\x2d\x9c\x8f\x9d\x27\x5e\x1c\xd2\xc0\xf1\x29\xf8\xab\x8d\x74\x15\x5b\x5d\x9e\x5c\x15\xc0\x15\xb0\xb0\x00\x03\xb2\xbd\xdf\xa0\xbc\xfc\xc6\x93\xa1\xdf\xcb\x4f\x53\xda\xec\x12\x6d\x16\x69\xf3\x3f\x39\xad\x05\x51\x9e\xf7\xc5\xce\x40\xe6\xf4\x57\x3c\x24\x7a\x32\xc4\xa0\x16\x28\x31\x35\x2f\x6d\x55\x8f\xf5\x83\x6a\x53\x17\xdb\xc4\x51\x5b\x3d\xf2\x69\xa8\xac\x76\xd6\x43\x6f\x26\x4b\x64\x56\x1e\x79\x68\xb5\x82\x21\x08\x48\x7b\x04\x5c\x92\xd6\xc6\x14\x2a\x1c\x28\x55\xb3\x8b\xee\xbd\x64\x25\x65\x12\x3c\xc8\x27\xcb\x18\x31\x19\x9e\x6f\x12\xa7\xe4\x23\x68\x56\xb9\x4d\xad\x73\x8f\x69\xd1\x10\x6e\x77\x35\xd7\x11\xf7\xc6\xa3\xa3\x37\x80\x41\xfc\x7a\x21\x10\x3b\xbf\x86\x69\x07\xd4\xed\xdd\xaf\xa0\xe7\xf1\xbb\x5f\xfd\x41\xa6\x0d\x64"}, +{{0x51,0x23,0x40,0xf9,0x61,0xf1,0x42,0xd1,0x91,0x5e,0x85,0xfe,0x4f,0xa0,0xf5,0x51,0xf8,0x08,0x92,0xe7,0x5a,0xcc,0xce,0x7c,0xd1,0x86,0x9e,0x6e,0x2c,0x9e,0x80,0x15,},{0x0c,0xa0,0x26,0x04,0xfa,0x87,0xe2,0xc2,0x05,0x06,0x25,0x1f,0x07,0x92,0xcd,0x21,0x25,0x85,0x6f,0x0a,0xb1,0x6d,0x66,0x3f,0x28,0x11,0x96,0x3b,0x1f,0x2d,0x81,0x72,},{0x6b,0xb4,0xd9,0x75,0xaf,0xae,0xf4,0x1e,0xa9,0xef,0x08,0x5a,0x68,0xc5,0x68,0xa0,0x5d,0xa3,0x7e,0xf2,0x1d,0xad,0x46,0x4e,0xd8,0x6a,0xc0,0xd4,0x08,0x0e,0x7d,0x01,0x29,0xfb,0x02,0x31,0x31,0xec,0xa5,0xf7,0xad,0xb2,0x58,0x6a,0x18,0xbe,0x40,0x56,0x2f,0xa2,0x76,0x4c,0xa8,0x07,0xe6,0x70,0xa0,0x59,0x6a,0x5c,0x54,0x7b,0xc0,0x01,},"\xaf\x37\xb2\xc7\x58\x7a\x8d\x5b\xc8\x95\xcd\x35\x77\x46\xab\x03\x55\x2a\x0a\x56\x1a\x29\x3d\xc7\x16\x4e\x39\xb6\xa1\x33\x3a\x92\x0b\xb6\xda\xca\x60\x06\x67\x6e\x99\xbb\x7e\x92\x8f\x9e\xa3\x91\xe5\x48\x02\xa8\xd3\x15\x96\x28\x9f\xb9\xbf\xe3\x00\x00\xcf\x52\xeb\xf0\xc1\x24\xa5\x89\x5b\xce\x33\x98\xc1\xbf\x53\x56\xbe\x82\x61\x9b\x8d\xdc\x15\xa7\x7c\xa9\x22\x49\x4b\xdb\x04\xf5\xc2\xe1\xb6\xe8\xff\x77\xae\x74\x9f\xaf\x2b\x8a\x41\xd8\x22\xc1\x7c\x06\xdf\xb7\xa5\xf9\x43\x4d\x8b\xd7\x15\xec\x87\x78\xe8\x0b\x81\xd2\xe8\xd0\x62\x98\x74\x86\x90\xc6\x55\x52\x83\xc9\x8b\xb9\xb1\x9b\x92\x46\x66\x7b\xc4\x10\x46\xff\x98\xc2\xc3\x5d\x16\x1e\x1f\x4d\x69\xd2\x54\xec\x5a\x07\x6f\x25\xbd\x5c\x7e\x2c\x98\xca\x3c\x09\xd8\x08\x33\x96\x2c\xf9\x66\x02\x87\x88\x40\x96\xeb\x30\xc4\x6c\x54\x17\x41\x06\xaf\x4e\x29\x79\xa1\x12\xf3\xe8\x94\x4e\xaa\xf7\x66\x9c\x40\xd5\xaf\xb9\x1a\x02\x4a\xbb\xeb\x14\x66\x4e\x30\x89\x03\xe4\xd2\x6d\x70\x09\x44\x6e\xe2\xe8\x30\xab\x5e\xca\x0d\xbb\xc5\x13\xfb\x4e\x04\x35\x1d\xf2\xf6\x74\x18\x64\xfb\x23\x71\xb2\x50\x2b\xe4\x3d\xc1\x5f\xc0\x44\x31\xff\xf5\xeb\x8d\x4b\x68\xd7\x24\x62\xae\x32\x2e\x57\xba\x2d\x4a\xdd\xdf\x15\xa1\x90\x2c\x21\x13\xae\xbd\x3b\x5d\x61\x29\x17\xc1\xbb\x73\xe7\x08\xad\x54\x18\xe7\xd4\x5e\x4b\x72\x80\xfc\x88\x96\xab\x80\x85\x3f\xf5\xf8\xe9\x8f\x26\x55\x3f\xc7\x8e\x30\xb3\xb0\xd7\x27\xbf\x6d\x06\x4a\x8f\x32\x88\x87\x68\xc5\x1e\xbb\x61\xb2\xc6\x00\xb4\x02\x8a\x77\x06\x0f\xeb\xbb\x02\xeb\x3d\x20\x17\x80\xe7\x45\x66\xc8\x6a\x34\x03\x18\x36\xbc\xe9\xea\xda\x81\xe5\xd0\xf3\x39\x60\xcb\x2d\xf0\x8a\xff\x3c\x97\x49\x21\xfc\x9b\x7d\x3a\xa7\xc8\x1e\x9c\x67\x1e\xd6\xd3\x3e\x7a\xe5\xed\x03\xa5\x41\x7d\x7e\x5c\xd6\xfa\xac\x91\xb5\x4b\x8f\x79\x2f\x48\x28\x3c\x60\x64\x7d\xe3\xda\x81\x6c\xa9\x75\x6c\x5b\xfe\x1b\xb8\xb5\x97\x9e\x57\x54\x01\xbd\xa3\x4e\x9c\xbc\x4d\x77\xe7\x11\xd6\xb7\x3b\x82\xda\x19\xda\x47\x3b\x55\xe8\xe7\x2d\x34\x1b\x2d\x85\x03\xe4\x86\x09\xbe\x0f\xe2\x91\x44\x4c\x28\x36\x69\xe5\xde\xad\xea\xf5\x2a\xa8\xec\x48\xda\x83\xf5\x32\x8c\xc0\x99\xfb\x41\xf8\x2b\xec\xdd\x58\xd0\x4b\x1d\x66\x20\x3d\x73\x7b\xed\x06\xcf\x21\xc9\x78\x19\xac\x13\xed\x71\x1c\xa2\x17\xa5\x7c\xf7\xd8\x0f\xf0\x82\xaa\x1a\x1c\xf8\xfe\xa5\x55\xcd\x2e\x47\xe4\xdd\xab\x5e\x3f\x99\x41\xad\x4f\x77\x5f\x49\x41\x9d\xca\xdb\x5b\x00\x4b\x68\xca\xf4\x5b\x27\xef\x49\xba\x14\xfb\x52\xb0\x9f\x1b\x18\x5b\xe9\xf9\xc7"}, +{{0xb1,0xb6,0x36,0xe9,0x57,0x57,0x4c,0x21,0xa9,0x57,0xa4,0x5b,0xd1,0x95,0xc6,0xf9,0xfe,0x4c,0xc1,0xc5,0x7e,0x84,0x13,0x4d,0x39,0xb4,0x2e,0x1a,0x84,0x32,0x9e,0xdb,},{0x95,0xe7,0x7b,0x15,0xdd,0xa4,0x7c,0xaf,0x69,0xb7,0x28,0x88,0xdd,0x69,0x96,0x1b,0xac,0xbe,0xc3,0xbc,0x75,0x35,0x30,0x03,0xe8,0xbf,0xf0,0xa4,0x3d,0xdf,0x4b,0x7a,},{0x76,0x3c,0x7d,0x0d,0x46,0x87,0x8e,0x5c,0x7e,0xcf,0x71,0x04,0xfc,0x1f,0x22,0x30,0xe4,0x61,0x78,0xa2,0x7c,0x75,0xf1,0x96,0x16,0x9c,0x02,0x79,0xed,0xb0,0x1c,0x28,0xfc,0xde,0x3b,0x0d,0x5b,0x86,0x35,0xcf,0xe3,0x39,0xfb,0x23,0x27,0x74,0xb2,0x20,0x6d,0xab,0x8a,0x46,0x0c,0xe4,0x17,0xab,0xf4,0x90,0xbb,0xfa,0x78,0x5c,0x02,0x05,},"\xe2\x5d\x32\x9c\xad\x83\x64\xd2\xde\xc2\x43\x73\xe9\x2d\x9d\x50\xfc\x7a\xbe\x8f\xdc\x3d\x0b\x4e\xe5\x7e\x1c\xfa\x5b\x7c\xd5\x8c\x23\xbe\x91\x8f\x05\x17\x9b\xa8\x41\xb6\x1e\x18\x00\x34\xca\x7e\x74\xd4\x9b\x0a\x1a\x2c\xeb\xb4\xbe\x65\x34\x4c\x91\x3c\x46\xd3\x26\x52\x33\x6e\x6b\xda\x4e\xfa\x3f\x58\x73\x0d\x39\xa6\x33\xa1\x4c\xa3\xd9\xa6\x2a\xbb\x0a\x73\x98\xcc\x29\xaf\xf9\x16\xee\xea\x2e\x7c\xaa\xc8\x08\x45\x56\x2f\x73\xd4\x03\x0f\x9c\xab\x0b\xf1\xc6\x40\x7f\x54\x01\x51\x3e\xf8\x7f\xe6\xdc\x09\x9d\xbc\x5d\xfc\x33\x52\x91\x1c\x07\xaf\x6c\x52\x3b\xef\x4c\xca\x78\x37\x96\x59\xe8\x80\x3f\x58\x59\x04\xee\x6e\xf6\xfd\xe7\x73\x66\xd9\x6d\x2c\xcf\x24\x8a\x53\x20\xd9\xb8\x29\x8b\x2a\x73\x36\x38\x79\x10\x7a\x02\xb4\x7f\x57\x21\x3a\x85\x20\x3a\xbb\xca\x5a\x41\x95\xf8\xaf\x3e\x35\x93\xed\x2f\xa3\x50\x4b\xb7\x6a\x3e\x1b\xe2\x4b\x66\xd3\x55\x66\x29\x32\xcb\x67\xdc\x88\x50\x3a\xfa\xf7\x62\xbf\xf7\x41\xba\x1c\xac\xe9\x7a\xc5\x8b\xaf\xad\x5d\x36\xc3\xaa\x02\xe0\xcb\xe2\x0e\x5f\x3d\xc8\x09\x2c\x51\x2e\xaa\x9c\x49\x43\x47\x4a\xad\x41\x99\x00\x76\x72\x1a\xd3\xf5\x3f\xb0\x8a\xc2\x29\x82\xed\x9b\x15\xc7\x51\xa9\xe2\x33\x82\xf6\xa6\x9c\x72\xe6\xe2\x44\xe0\xeb\x68\x1e\x6d\xd2\x28\xd3\x77\x4f\xcc\xb3\x7e\xb6\x23\x2f\x82\x5d\x16\x9a\x2a\xc8\xb7\xe1\x8a\x42\xcd\xaa\x4f\x2c\xf0\x58\x90\xbb\x0c\x59\x8c\xf8\xc3\x1f\x82\x9e\xf8\xca\x24\x35\xbd\xcc\xeb\x0e\x61\x93\xad\xa7\x84\x1e\xe6\x92\xf3\x0a\xed\xf8\x8b\x62\x73\x11\xb1\x38\xac\x78\xb3\x91\x3e\x06\xf7\xc3\x21\xca\xfb\x39\xd9\x01\xdf\xe1\x74\x30\xb1\xa2\x0b\xc4\x37\xa5\x55\xa5\x78\xfa\x31\xe4\xb6\x80\x79\x54\x45\x6b\xd4\xb0\x4d\x5d\x88\x79\x87\xbd\xf0\x4e\x0f\x14\xaf\x31\x41\xb2\x4c\x3a\x7b\x9a\xc7\x5a\xa3\x2e\x2f\xcd\x21\x71\xa1\x26\x09\xe1\x5e\x73\x09\x4f\xd0\x92\x21\xb4\xd2\x70\x90\xe7\x32\x19\xb6\x48\xbc\xaa\xbf\x38\x07\xc9\x28\x0b\x6c\x4a\xd7\x50\xa4\x68\xbe\x0e\x1a\xd3\xe6\xe6\x30\x16\xcb\x5c\xec\x3a\xad\xdc\x56\x89\xc2\x95\x5a\x2a\x8d\x5b\x89\x84\xd7\xc4\x43\x76\xfd\xd9\x4d\x3f\x5f\xf1\x29\x8f\x78\x17\x2b\x56\x59\x13\x70\x4e\x90\xe5\xac\x03\x8c\xb1\x72\x0e\x19\xb0\x80\xf8\x1b\x53\xd6\xa4\x5d\x45\x28\x53\x07\x11\xb6\x3d\xfe\x1e\x47\x81\xc2\x4d\x74\xae\xb2\xbd\x8a\x73\xfd\x2a\x99\x3c\x5b\x08\x91\x39\x21\x96\xac\x32\xc5\x23\x69\x99\x60\xd8\xb2\x3e\x01\x66\x4c\xf9\x02\x1d\x93\x92\x80\x50\xca\xf9\x7f\xb9\x85\x55\x45\x80\xe3\x33\x36\xa4\x56\x32\x47\xdf\x59\xef\x6c\xae\x53"}, +{{0x10,0xca,0x41,0x3d,0x70,0xeb,0x3d,0xb6,0xe3,0x37,0xf0,0xf1,0x1a,0xbc,0x07,0x5c,0x95,0x85,0x9e,0x82,0x5f,0x87,0x61,0x76,0x07,0x69,0x52,0xd2,0xf1,0x88,0x80,0x30,},{0x50,0x28,0xba,0x38,0xaf,0xec,0xc2,0x42,0x63,0x5f,0x6e,0x35,0x3d,0x5f,0x4a,0xfd,0x12,0x3f,0x86,0x0a,0x04,0x25,0x22,0x0e,0x96,0x65,0x52,0xa0,0x57,0x88,0x08,0x23,},{0x6a,0xec,0x02,0xdc,0x6b,0xdf,0xcb,0x67,0xf0,0xef,0xc1,0xfd,0x31,0xe2,0x3e,0x69,0xe3,0x71,0xab,0x38,0x02,0x50,0x5b,0x32,0x01,0xa9,0x5d,0xd5,0x25,0x41,0x7e,0xd1,0xa1,0x28,0xdb,0x4e,0x18,0x2c,0xb3,0x7c,0x28,0xf6,0x28,0x06,0x66,0x70,0x99,0xa8,0xad,0x48,0x0b,0x0a,0xc9,0xe9,0x4c,0x2a,0x7d,0x5a,0x0e,0x96,0xe2,0xa7,0x36,0x0d,},"\xea\x7f\xaf\x79\xf6\xff\x5d\x78\xa8\x23\xa7\x54\x34\x71\x34\xf1\xb3\xc3\xe9\x1c\xe5\x18\xfd\xd6\x33\xfe\xb4\xf0\x5d\x12\x5f\x05\xcb\x54\x33\x6e\xf5\x60\xe9\x2d\xeb\x68\x51\x12\xa5\xff\xcd\x3d\xfd\x39\x64\xb2\x75\x8c\xe4\x78\x5f\x6a\x34\xbf\xeb\x39\x78\x4f\x0a\xee\x55\x95\x5a\xeb\xd1\x2d\xdd\xa6\x41\xd0\x57\x69\xf7\x44\x02\xf7\x06\xda\xd2\x01\xc4\x4c\x91\x08\x1c\x7d\x7f\x65\xe7\xaa\x42\x46\xde\x6d\xc3\xed\x64\x96\xd1\x0f\x4a\x41\x20\x60\xd4\x93\xba\xc9\xae\xd5\xbe\x4f\x6d\x74\x22\x9e\x3c\x55\xeb\x68\x76\xe3\xbb\x2e\xd4\x1f\xa4\x50\x4b\x66\x70\xdd\xa8\xc7\x98\xf6\xda\xa2\x80\xd1\xaa\x72\x02\x11\x74\xf6\xc0\x1a\xec\x49\xb3\x21\xd8\x7f\x53\xac\xbc\xad\xcc\x46\x07\xd5\xb1\xe4\x5d\x63\xfc\x48\x1a\x6d\x90\x57\x6c\x87\xc1\x88\x0b\x2e\x8f\xf3\xe5\x90\xa9\x6b\xee\xe1\x80\x47\x68\xc7\x56\xbe\xb8\x6b\xf1\xde\x8a\xdc\x40\x8b\x1b\x8d\x66\x6f\x74\xba\x28\x63\x08\x22\xf9\x2d\x18\xb0\x56\xae\x37\xce\x02\x93\xee\x61\xb9\xe8\x0f\x33\xac\x26\x96\x71\xbd\x62\xa4\x05\x9b\x24\xf7\xc1\xa4\x40\x80\x74\x40\xd5\xd5\x38\xa6\x54\x58\xad\xc8\x15\x87\x24\xb2\x5c\x12\x12\x7a\xa0\x34\x9e\x55\xf6\xe5\x5b\xc9\x20\x78\xfd\x1e\xf2\x74\xc2\xaa\x79\x19\x05\x76\x6b\xe3\x94\xa2\x62\x8f\x7b\xbd\x1a\x32\xda\x5e\x48\x74\x46\xbb\xef\xae\x88\xfa\x6c\xf3\xf7\xb4\x99\xf1\x31\xfa\x19\x31\x3d\x13\xb2\x80\xad\xca\x50\xf7\x78\x02\xd1\x73\x31\xb3\x81\x68\x3b\x5e\x7e\xda\xb9\x94\x73\xed\xd3\x1d\x77\x44\x34\x88\x21\x41\x35\xfd\x6f\x26\x44\x50\x93\xe9\xe2\xaf\xf7\xd7\xe8\x92\x33\x7f\xdc\x87\x79\x06\x5d\x4d\x97\xd6\xd6\x73\x57\x67\x94\x95\x8d\xbf\xa6\xc5\x0b\x1b\x13\xac\x39\x60\x7c\x1e\x66\xef\x96\x29\x76\x10\x71\x15\x5f\xbc\xa6\xf3\x6e\xb0\x2c\xee\xae\x16\x36\x7f\xea\xc0\x74\x76\x90\x8c\x84\x7c\x9a\x53\x3e\xf6\x8c\x94\x31\x1f\xa0\x89\xff\x28\xfb\xd8\x78\x09\xb0\xd3\x87\x6b\x43\x1d\x9a\x18\xb2\x02\xf9\xa4\x04\x9a\x05\x77\xb8\x17\x76\x10\xdd\x02\xe5\xc5\x20\xec\xa9\x55\xe8\x03\xc3\xad\x4f\x50\x97\x6f\x7c\x2e\xa8\xaa\x3e\xe4\x83\x6a\x19\x85\xdf\x0a\x4f\x16\xef\x46\x98\x15\x95\x41\x98\x97\x99\x35\x60\xaf\x82\x65\x1c\x2b\x49\x4e\x68\x0b\x37\x80\x2e\x75\x37\xef\x68\xa5\x75\xc3\x4f\x85\x88\x06\x3e\xe0\x19\x72\x06\xd9\xa3\x2b\xb4\x89\x0e\x7c\x21\x6a\x4d\x33\xfe\xca\x36\xb5\x49\xe5\x32\xfe\xa6\x85\x56\xe7\x54\x0a\x4f\xb1\x69\xd4\x9f\xc5\x53\xb2\xe6\x70\x0a\xe4\x2d\x9a\x51\x6e\x68\x16\x0a\xcf\x6b\x27\x0c\x77\xca\x5e\xc2\x6e\x5a\xd5\xdc\x75\xc2\xc3\x93\xe2\x99"}, +{{0x1f,0x0a,0x10,0xa2,0xcb,0x11,0x19,0x17,0xb9,0xa6,0x7a,0x2a,0x1f,0x38,0xfb,0x86,0xf8,0xed,0x52,0x60,0x7d,0x1d,0x65,0x3a,0x45,0x7d,0x7f,0x47,0x18,0xd9,0xa7,0xde,},{0x70,0xc0,0x75,0xb2,0xe9,0x4c,0x4c,0x02,0xf4,0x5e,0x73,0x04,0x4f,0x24,0x39,0x97,0x41,0xb1,0x61,0xfe,0xb6,0xf6,0x9e,0xab,0x63,0x54,0x17,0x28,0x2a,0x4a,0x93,0x68,},{0xa4,0x24,0x5a,0xa3,0x39,0x5e,0x7b,0xad,0xa2,0xbc,0xdf,0x16,0x03,0x14,0x7c,0xc5,0xf3,0xf0,0xba,0x91,0xf4,0x0f,0xda,0xd8,0xf6,0xd3,0x71,0xc3,0xeb,0xef,0xb4,0xc1,0x50,0x1d,0x07,0x87,0x5b,0x57,0x6f,0x40,0x79,0x78,0x06,0xa4,0x84,0xc7,0xa3,0xf7,0x05,0x69,0xe2,0x32,0xb0,0xc9,0x9d,0x29,0xca,0x23,0xa2,0x33,0xb6,0x8e,0xdb,0x0c,},"\x4f\x6a\x43\x4b\xd5\xfc\x77\xf0\xf1\xb7\x04\x9c\x91\x85\x3c\xcb\xd8\x94\x39\x96\x2a\x60\x78\xa6\x74\xb8\x67\x54\x3b\x6b\x7d\x10\x55\x2e\xc1\x75\x8c\x52\x83\x04\x2b\xd6\xb4\xce\xa8\x8c\x95\x20\xdb\x04\x74\x6f\x08\x9c\xf3\xa2\x60\xfb\x0f\x33\x85\x8e\xfd\x6f\x68\x0d\xe5\xb7\x2d\x98\x76\x32\x4b\xa5\x90\x29\x91\x38\xf8\x5a\x76\xf5\xbe\x0e\x05\xe8\x85\x9c\x02\xb2\x35\x12\x55\x9c\x8b\xea\xfc\x9c\xfe\x90\x1b\x28\x3e\x15\xd1\x6c\x79\x2e\xb0\x3b\x92\x88\x0f\x6f\xf9\x7a\xa3\x8e\xee\xad\x3f\x4f\xd6\xc0\xa9\x21\x43\x23\xaa\x39\xa1\xc1\x65\x15\xe3\x0d\xbd\x08\xb8\x33\xee\x40\xa8\x14\xa2\x88\x09\xc8\x70\xe1\xd0\xa6\x2c\x37\x93\x2d\x54\x08\xfc\x6a\xfc\x63\xe7\x9a\x65\x5c\x5f\xe3\xd4\x02\x6e\xf0\x9e\x02\x99\xfb\xde\x5a\xb3\x4f\xce\xab\x14\x13\x0d\xc4\xbe\x00\x7e\x8e\x64\x44\xd7\xaa\xae\xc6\x2c\x87\x3d\xf7\x7e\x80\x10\x74\x3c\x31\xe8\x75\x7f\x1e\xae\x9e\xdb\x55\x97\xa1\xb5\xd8\x4b\xd7\x7a\xe7\x64\x2e\x1a\xca\x99\x87\x3a\x15\x2f\xfd\xe0\x68\xa8\xe4\xad\x92\x40\xb9\x03\x33\x27\x95\xe4\x0b\xb3\x28\x65\xe5\xce\x03\x43\x07\xa6\xc9\xfe\x33\x9a\x1c\x93\x77\x0d\xf5\xca\x46\x32\x9f\x6b\x09\x41\x97\x85\xcb\xf2\x84\x7b\x0c\x68\x32\x83\x71\x23\x85\x3a\xd9\x52\x65\x32\x65\xc5\xb5\x74\x0d\x19\x4e\x00\xf2\x3f\x9e\x96\x67\x91\xf0\x05\xf8\xbf\x55\xc3\x88\xc2\xbe\x9e\x21\x53\x89\x25\xf8\x55\x5e\x0d\xbd\x83\xbe\x07\x3d\xf7\x65\xaf\x49\x40\xe5\x9a\x37\x90\xb9\x83\x6b\xab\x79\x09\xe5\x67\x6f\xbf\x1c\x21\x26\xfe\x22\x6d\x78\x1a\x44\x33\x0c\xc0\x1d\x32\x83\x0f\xf8\xae\x00\xb9\x79\x2e\x39\x8c\x2c\xbb\x4f\xb8\x3a\x10\x05\xc2\x45\x54\x9a\x89\x06\x3f\xbe\x06\xc6\x2a\x48\xda\xc4\x3c\x51\x01\x24\x99\x94\xe9\x5e\x37\xf2\x4c\x1d\x8b\x3b\xc6\x73\x53\x8c\x46\x05\x5f\x80\x0d\xb1\xc0\xf9\x56\x86\x9b\x6b\x29\x7d\x99\x0f\x44\xf0\x5b\x50\xc7\xad\x6b\x85\x6f\x46\x21\x28\x58\x47\x1d\xd0\xd3\x93\x72\xb0\xdb\x75\x15\x73\xdd\xb6\xb5\xb5\x6b\xa0\x1e\x37\x1c\x78\xfe\x58\xdc\xd1\xbe\x53\x11\x2a\x6a\x73\xda\x9a\x6b\xac\x75\xd3\xc3\x9a\x1a\x70\x5a\x36\xf6\x40\xfc\xfa\xd8\xcd\x04\x07\x75\x94\xd5\x96\x85\xf6\xe3\x0d\xe7\x1d\xfd\x4a\x44\xc4\xe7\xc0\x4d\x6e\xc7\xc2\xe8\xbe\x12\x78\x5b\xb0\x5b\x29\xb3\x91\x51\xd3\x29\xf5\x87\xfd\xc3\x81\xc2\xdf\x0c\xef\x73\xfe\x0e\x3f\xd9\x20\x8d\x7c\xcb\x6e\x08\xd0\x2f\x42\xd1\xfe\xed\x27\x56\x1d\x5e\x32\x3a\xa1\x48\x62\x4e\x55\x2a\xbe\x87\x53\x2d\xe1\x5b\x7f\x42\xc2\x2c\x98\xe4\x05\x25\xb1\x74\x7c\xbd\x75\x8b\xfb\x26\xfd\x3e\xed\x3b"}, +{{0x7f,0x05,0xba,0xac,0xf1,0x67,0x58,0x3c,0xf2,0xfe,0x95,0x62,0xa5,0x06,0x99,0x1e,0xd9,0x87,0xf6,0x8f,0xfb,0x71,0x56,0x7c,0x7c,0xcc,0xe3,0xfc,0xc5,0x9b,0x78,0xb0,},{0x0d,0xec,0x39,0x52,0x85,0x2b,0x96,0xfd,0x75,0x58,0x7e,0x97,0x74,0x3f,0x9e,0x41,0xc0,0x9f,0xbe,0x6b,0xa9,0x81,0xbf,0xce,0xb4,0xeb,0xb8,0x89,0x2d,0x98,0x6a,0x16,},{0x0d,0xee,0xd2,0xdf,0x82,0xac,0xf4,0x52,0x9c,0x40,0x8a,0x02,0x93,0x1f,0x67,0x6b,0xec,0x5c,0xb7,0xad,0xe8,0x4e,0xbd,0xcd,0x57,0x8f,0x70,0xf9,0x71,0x38,0x2c,0xf3,0x11,0xbb,0x83,0x09,0x73,0x00,0x45,0x6a,0x55,0x8b,0xc4,0xc0,0x9d,0x89,0x83,0xff,0x13,0x49,0x3f,0xd6,0x11,0xeb,0x66,0xc0,0x43,0xbf,0x01,0x9b,0xad,0x6f,0x33,0x02,},"\xa2\x7d\x1e\xab\x05\x15\x09\x20\xde\xd1\xb1\xc2\x57\x8a\xf5\x82\xb2\x94\xf7\x83\x7f\xe4\xfb\x1a\x31\x69\xc2\x5e\xfb\x70\x63\x4b\xa6\x6c\x7e\x29\x91\xb3\xe7\x5c\xc5\x12\x48\x26\xa0\x3e\x05\x72\x59\xb5\xcb\x70\x62\x28\x78\x0c\xbc\x82\x75\xc3\x39\xf8\x34\x0e\x40\x2a\x66\x50\x32\xa4\xab\x65\x78\x27\xb1\xc3\x48\x1f\x75\x66\xd3\x69\x73\x5b\x82\xdb\x76\x28\xc0\x22\xb2\x12\x73\x0d\xb1\xe4\x7c\x9b\x2d\x9b\xc4\xd8\x1b\x23\x42\xd8\x9c\x6e\xaf\xc3\xe0\xb6\xde\x50\xd4\x84\xcc\xef\x11\x23\x8c\x8e\x2d\x24\x0d\xd5\x95\xdc\xef\x8b\x2f\xc5\x7b\x54\xff\x9a\x8a\x74\x11\x1f\x61\xf8\xa6\x52\xf2\x0e\xa0\x12\xc1\xad\xe3\xe2\x80\xec\xde\x29\x4c\x0e\x35\x71\x71\x90\x16\x2e\xc6\xa2\x26\x5e\x7e\x6f\x3f\x07\x04\xcf\x8a\xb1\xa0\x3e\x5c\xc9\x53\xe2\x92\x62\x91\xcc\xd4\xb0\x59\x0d\x5c\x20\x56\x8f\x94\xf9\xff\x0f\xe2\xab\x78\xcf\x9a\xe2\xc3\x8b\xcd\x49\x1e\x51\x8f\x23\xe9\xb6\x36\xf8\x80\x61\x5f\xc5\x60\x78\xe5\x12\xd7\x57\x7e\x09\x49\x7c\x11\x83\x45\x3d\x50\x81\xfd\x47\x37\xf2\x80\xec\x5e\x26\x7c\x45\x86\xb7\x8b\x70\xff\xfd\xfd\x73\x0d\x80\x9d\xf5\x60\xf2\xe3\x77\x21\x91\x84\x7b\xbc\x3f\x60\x4f\xb7\xf8\xca\x49\xee\xd3\x18\xb5\xe7\xd1\xf2\xb8\x3a\x10\xda\x0c\x85\x94\xb3\x39\xb6\x87\x1a\x57\x72\xdd\x64\x16\x8e\xcc\x27\xe2\x40\xa4\x5c\x76\x72\x5e\x7d\x55\xbe\xf3\x7e\x13\x5e\x3d\x9e\x0e\x34\xe3\x6c\x16\xe3\x4d\x77\x45\x9a\x55\x2f\x40\x74\xd0\x67\xa3\x1a\x3e\xd2\xa4\x8c\xde\xa4\x89\x5b\x10\xbd\xf1\x65\x6f\x4b\x7a\x41\x3c\x6a\x08\x8c\x64\x9f\xc9\xd7\xbc\x56\xab\xf6\x44\x35\x49\x12\x14\x19\x2a\x66\x70\xcb\x8b\x9c\x91\x7f\x8e\x1b\xc7\xb2\xcf\xce\x78\xd2\x8f\xbc\x3a\xfc\x2a\x50\xe9\x82\x13\xe7\xe0\x26\x37\x8e\x4e\xa7\x11\xd1\x51\xad\xaa\xa7\x19\xbe\xb8\x97\x46\x56\xc1\x0e\xbc\x7d\xe4\x6b\x19\xec\x82\x95\x1e\xf4\x6a\x8c\x68\xe7\xf4\x36\xe1\xb3\xeb\xed\xb2\xd0\x9b\x05\x75\xc9\x91\x4e\xad\x27\x96\xb5\x3e\x00\x61\xe2\x12\x99\x4a\xc5\x02\x6a\xea\x81\xec\x37\xc8\x13\x78\xf4\xcc\xfc\x46\x77\x00\x08\x79\x68\x59\x7d\xa3\x8f\xed\x52\xfa\x48\x09\x3a\xe4\xba\x10\x66\xc3\x1e\x3c\x7d\x85\x08\x09\x5b\xb4\x5c\x28\x01\x20\xf4\xaa\x69\xa2\x4f\x3e\xfe\xf1\xf7\x67\x98\x5a\xa1\xa3\x0e\x14\x08\x56\xf7\x6d\x15\x20\x73\x28\x78\x48\x7b\xe5\x3f\x71\x2d\xbd\x7d\x77\x9e\x31\x51\x01\x58\x8f\xd7\xdb\xdb\x13\x2f\x92\xc2\x75\x75\xac\x14\x86\xf1\x76\xc7\x90\x66\x1b\x01\x48\x39\x4e\x92\xff\xa3\xae\x6f\x8a\xfb\x2f\xaa\x2b\x7f\x4f\xbd\x0a\xd9\x1e\x75\x9a\x70\x2b\x3c\x70\x2b\x4d"}, +{{0xd0,0x0c,0x21,0x64,0x26,0x71,0x0d,0x19,0x4a,0x3d,0x11,0xcf,0xc9,0x0a,0x17,0xa8,0x62,0x12,0xe7,0xa0,0xe5,0x4b,0xaa,0x49,0xb0,0x16,0x9e,0x57,0xff,0xf8,0x3d,0x61,},{0xcf,0xe6,0xae,0x89,0x03,0xc6,0xc7,0x01,0xaa,0x30,0x46,0x95,0xc6,0x51,0xbf,0xd8,0x50,0x33,0x1f,0x9a,0xd4,0x81,0x63,0x3a,0xe3,0x70,0xc8,0x6d,0x7b,0xd1,0x3f,0xb9,},{0x15,0xc4,0x5c,0x19,0x42,0x97,0xe8,0x87,0x02,0x9f,0x49,0xd8,0xbd,0xf9,0xd6,0x10,0xdd,0x8c,0x34,0x79,0x9e,0x1e,0x92,0x30,0x26,0x9e,0x7a,0x58,0x92,0x89,0x38,0xcf,0x39,0x6a,0x02,0xcd,0x42,0x20,0x54,0x90,0x39,0x1e,0x1c,0x64,0x35,0x3f,0xb0,0x6b,0x9f,0x8e,0x9b,0x81,0x8a,0x9a,0x36,0x1c,0x20,0x4a,0x38,0x69,0x95,0xbf,0x3b,0x03,},"\x82\xf9\x78\x41\xb3\xba\x22\xdd\x9a\x44\x50\x83\x7e\xa7\xbf\x8d\x27\xa9\x73\x14\x70\xca\xbb\x0c\x20\x78\x03\x4b\xf2\x4e\x4c\x1a\x62\x90\xc0\x3f\x40\x02\xb8\x6f\xa0\x9f\x07\xb5\x20\x9f\x1f\x53\xd0\xec\xf4\xd9\xe9\x22\x3b\xec\x12\x5a\x95\x45\x51\xfe\x8b\xff\x71\x8f\x5e\x26\x48\x68\xe2\x07\xf7\x01\x19\x4e\x41\xde\x39\x97\x1f\xd3\x85\xf4\x9a\x4b\x4a\xdd\xa9\x11\xeb\xa5\x52\x59\xfc\x68\x36\x65\x32\x73\xf6\x56\xf4\xaf\x60\xb2\x06\x64\x95\x6d\x4f\x21\x35\xd9\x0d\x09\xe9\x03\x7d\x53\x66\xa0\x25\x34\x44\xe0\x22\xc7\x21\x2a\xf5\xfd\x4f\xcc\xd7\x42\x37\xd2\x88\x53\x38\xe2\xfd\x72\x15\x22\xde\x67\x63\xc2\x54\x90\x28\xc6\x23\xb9\xcf\x38\x7d\x23\x4a\xb5\xe7\xfc\xbe\x5a\x47\xc6\x85\xb7\x9e\x75\xa5\x7b\x09\x57\x40\x82\xa0\x22\x21\xdf\x64\xa2\xe8\x41\x61\x80\x87\xe7\x22\xa2\x1b\xac\x1b\xa4\xf0\xd7\xd8\x7b\xdc\x51\x0a\xaa\x8f\xbd\x10\x75\x7f\x6c\x02\x9c\xa8\x20\x37\x1f\xc7\x4c\x3b\xc5\x0b\xd8\x98\xc5\x5d\x81\x67\xf7\x3a\xda\x37\x7a\xec\xc9\x16\x29\xd6\x4c\x36\x0c\x2c\x24\x1c\x5c\xb4\x2e\x3a\x51\x8c\x5d\xab\xf0\xf4\x18\xb2\xa7\xf3\xd8\x2e\xef\xd9\x20\x26\xd3\x1e\x8b\x81\x60\x35\x8e\xae\x82\x1f\x73\x0e\xca\xfe\x7a\xce\x64\x7b\xff\x87\x41\xde\x2f\x6a\x13\x1d\x11\xc9\x69\xe9\x78\x7c\xfe\x6a\x2f\xab\x37\xbf\x8d\x1c\x7f\x4a\x2f\x36\x4d\x2f\x1a\x76\xef\x04\x6c\x18\x43\xe6\x3e\xc0\x0c\xf7\x92\x0f\xfa\xae\x56\x1e\x73\x70\xb7\x19\xfc\x16\xfc\xeb\xca\x3c\xfd\xfa\xba\x43\xf4\xf0\x90\xc4\x6f\x47\x73\x03\xa6\x60\xee\x88\xdd\x4e\x89\xbf\x14\xb9\xf8\x04\xb6\xfd\x49\x5c\xb1\x41\x27\x53\x47\x4a\x05\x6a\x0d\x89\x31\xcd\x9c\xcb\xd6\x4f\x8f\xcc\x7a\x31\x23\x46\x7c\x5d\x47\xf6\x90\x67\x9e\x88\x71\x28\x80\x93\x73\x4f\xd6\xa1\x32\x60\x38\x65\x81\x56\x41\x36\x96\x59\x4c\x13\x4d\x73\x88\x7f\x34\xee\x67\x60\x9a\xe8\xff\xb3\x26\x6c\x16\xd8\x7f\x15\x34\x5a\x47\x6f\x72\x95\x0c\x15\x87\x96\xa8\x8b\xbb\x44\x4f\x1a\xa8\x09\xca\xd8\x75\xb8\x5f\xb9\x15\x1a\x0e\x2e\xef\x2e\x00\xe8\x0d\x6b\x7a\x9b\xa4\x06\xc0\x51\x9e\xff\xdd\x94\x12\x62\x32\xfd\xf6\xf1\xe7\xb9\xbb\xc0\x36\x2a\xa7\x75\x16\xfd\xf9\x39\xe7\x90\x6a\xab\x01\x30\x71\x28\xcf\x82\x4c\x10\x2c\x09\xb9\x29\xc9\xb2\xd7\xaf\x8f\x85\xb7\xd7\xf9\xa8\x38\xb2\xae\xd0\xc6\x97\xe8\xbd\xfe\xe6\x6e\xe0\x16\xbb\x1b\xf3\x5e\xff\x6b\x2f\x7e\xf4\xb9\x1b\x1f\xc0\x4f\xac\x9f\x11\x6e\x2e\xdf\xf4\x0f\x95\xc1\x5b\x77\xc3\x1e\xe5\x22\xf3\x93\x7c\x7f\xa0\x04\x7d\x62\x25\xe0\xc8\xe5\x5e\x27\x8c\x81\x03\x91\x1f\xea\xb2\xb7\xf4"}, +{{0xdd,0x12,0x39,0x72,0xe6,0x28,0x58,0x4a,0xcc,0x46,0x29,0x3b,0x8e,0x4c,0xe2,0xb2,0xdd,0x46,0x9c,0xc4,0xed,0xe1,0x4e,0xf3,0x95,0x21,0xcf,0x08,0x37,0x35,0x85,0xb3,},{0x35,0x22,0xf7,0xae,0x59,0x6e,0xed,0xb2,0x17,0x03,0x5d,0x95,0x39,0x5e,0x44,0x8d,0xbd,0x6f,0xfb,0xf4,0x25,0x85,0xea,0xeb,0x30,0x70,0x26,0x54,0x1c,0x78,0xa6,0x51,},{0x89,0x65,0xa8,0x89,0xd5,0x4c,0xd8,0x07,0x6d,0x35,0xbc,0x2e,0x12,0xb0,0x09,0xd5,0x6b,0x07,0x04,0xc8,0x94,0xf9,0x12,0xa0,0xd1,0xd3,0x07,0x20,0xc2,0x32,0xfe,0x44,0x04,0xbf,0x30,0x09,0x54,0x1e,0x8f,0x32,0x83,0xe8,0x9e,0xa8,0x6f,0x67,0x8a,0xfb,0xdf,0x1c,0x21,0xc9,0x24,0xb2,0x3a,0x52,0xb4,0xca,0x6d,0x63,0xf4,0x8f,0xc2,0x03,},"\x2b\x28\x57\xf4\x52\x80\x17\x3e\x2e\x0e\xf9\xd5\x94\xe6\x08\x3f\x1d\xc7\xa6\x54\x92\x97\x5b\x83\x7d\xef\x6c\xad\xd8\xc8\x54\x50\x31\xee\x9d\x68\x36\x9a\x93\x93\xcc\x7b\x79\x2f\xeb\x98\x04\x0b\x21\xf1\xeb\x84\x66\x5f\x87\x85\x37\xce\x41\x2e\x9d\xb6\x80\xd2\x9f\xbd\x8f\xfc\x77\x31\xea\xe9\x1a\x20\xb4\x75\x48\x99\x62\x04\xfb\x06\xad\x74\x0e\x78\xf0\xfc\x59\x0b\x67\x91\xdc\x7a\x0f\x26\x59\x28\x6c\xc1\x6d\x02\xc5\x11\x7b\x56\x58\x36\xb4\xb8\x73\x8c\xf4\x0e\x28\x5c\x69\xc5\x0e\x41\x29\x11\x29\x23\x67\x35\x2d\xfd\xae\xd9\x98\x2d\x0f\x89\x9a\x23\xc0\xab\x51\x81\x2b\x3e\xc6\x78\xf6\x88\x2e\xa4\x27\xcd\xc9\x3a\xb4\xb2\x48\x24\x37\x70\x54\xaa\x25\xd8\x22\x46\x65\x33\x40\x07\x8c\xf1\x1d\x14\xa5\x1f\x0e\x68\x6d\x7e\x01\x8b\x36\x74\x16\x68\xfc\xe7\x45\x8d\x16\x92\x93\x36\x1d\xd1\x6b\x3d\xeb\xbe\xd1\x9e\x1b\xef\x7c\x36\x93\x4e\x20\xf3\x3a\x09\xad\x3e\x82\xb5\x3a\xb4\xe9\x4c\x25\x5d\x04\x18\x98\xb9\x77\x37\xdf\x99\x58\x4a\xf1\x4e\x40\x40\x58\xd0\xc9\x3b\xca\xe7\xbb\xbc\x06\x39\x5a\x2a\xef\xbd\xef\xa7\xb2\xed\x17\xce\xbd\x15\x13\xfa\x39\x0f\xe9\xa9\xb0\xce\x68\xce\xcc\x2b\x9e\x12\x9b\x7a\x29\xf4\x9b\x6d\x18\xc2\x8b\xac\xd3\xaf\x39\xdc\x39\xca\x97\x2f\x0e\x0d\x06\x85\x5d\x57\xc2\xb5\xfc\xac\x2f\x79\xcb\x8c\x05\x79\x9e\x4f\x65\x73\x46\x68\xda\xd6\xaa\x7a\x43\xa1\x18\x56\xe2\x3b\x1e\x73\x2d\x00\xe5\xfe\x38\x85\xb7\xda\xd4\x2e\xc1\x8a\xc8\xe0\x96\xa0\x80\xf7\xd5\x50\x70\xfd\xcf\xf6\x07\xbc\x0b\x85\x2d\x8a\x08\x0d\x2a\x74\x05\xd5\x94\x14\x69\x5f\x2e\xb7\xfb\x0a\xca\x23\xc8\x63\x57\x42\xf8\xae\x57\xf1\x37\x80\x31\x6e\x28\x08\x72\x37\x4e\x69\x29\x59\x8d\x02\x8a\x33\xc0\x5d\x83\x1c\xda\xbd\x02\x94\x93\xc3\xcc\x85\x9f\xff\x1a\x67\xd5\x62\x16\xf0\x2a\x22\x95\x66\x53\x65\x88\x7a\x35\x0a\x80\xaf\xaa\x0c\x36\x7a\x74\xd3\x70\x1a\xe8\x8f\x59\xd8\xa9\xd3\xa1\xdc\xe0\xcf\xd2\xea\xbe\x2a\xf5\x06\x5a\x1c\x7f\xca\x4a\xad\xcf\x8e\x51\xe7\x56\x12\xa1\x37\x1b\x4d\xc8\xff\xc0\xc0\xb9\xc4\xfa\xdb\x2f\x08\x1e\x2e\x03\x2d\x96\x81\x8e\x55\x73\x7a\xdd\xe3\xe1\xac\x12\x1f\x56\xcc\x86\xfb\x58\xa0\xa5\x82\x69\x2f\x62\xce\x58\xac\xce\x17\xaa\xfe\xc7\xbc\xb7\xe4\x4f\x83\x92\x58\xcd\x4a\x85\x1f\xc0\x13\x44\xee\x9f\x1b\xd0\x3e\xb9\x43\x44\xf4\x77\x86\x93\xc1\x71\xdd\x28\x92\xb2\x42\x6a\x88\x29\xab\x0c\xfe\x33\xa7\xd4\xa3\x6e\xb4\x01\x7f\x7f\xcf\xd2\x41\x34\xab\x8a\x45\xf2\x37\x17\xcd\x13\x8a\xa6\x00\x01\x72\xe3\x7b\x40\x64\xdc\x9b\x6d\x1e\x1e\xf3\xaf\x84\x97\x1d"}, +{{0x33,0x35,0xea,0x92,0x81,0x17,0xcf,0xee,0xfb,0xee,0xae,0x14,0x60,0x03,0x88,0x1b,0xdc,0x88,0x89,0xd6,0x58,0x0e,0xed,0x13,0x52,0x37,0x08,0x20,0xad,0x1f,0x58,0x4f,},{0xcb,0x20,0xd4,0xfd,0x75,0x61,0x84,0x80,0x13,0x11,0x1c,0x3e,0x97,0x61,0x7f,0x34,0x18,0x1d,0x2e,0x7f,0xbc,0xf1,0xbb,0x2a,0x2c,0xd2,0xe8,0xc1,0x77,0x5b,0x8b,0x03,},{0xf7,0xc3,0x9f,0x92,0x47,0xd2,0x2f,0x01,0x89,0x99,0x24,0x7f,0x0e,0x00,0x05,0xcd,0x63,0x07,0x6c,0xcf,0x2f,0xee,0x41,0x63,0x42,0x1f,0x86,0x40,0x7a,0x41,0x69,0x8c,0x40,0x58,0x16,0x64,0x73,0x51,0xc0,0x4e,0x93,0xb5,0x44,0x15,0xb6,0x2f,0xc0,0x3f,0xc8,0xc2,0x5e,0x20,0xf7,0x54,0x1d,0xab,0x03,0x19,0x7d,0xc9,0x00,0xb2,0x9c,0x0c,},"\x0f\xa7\xf6\xa6\xfc\xa9\x81\x42\x9b\x57\x2a\x67\x04\x87\x1b\xed\x14\x0d\xab\x93\xee\x19\x92\x00\x6e\x9a\x3b\xb2\xe6\xcc\x9a\x09\xd4\xc9\xcf\x17\x06\x6b\x32\xff\x7e\xf5\xb6\xb2\xe7\x91\x11\x78\xed\x74\x62\xc4\xc1\x75\x60\x31\x71\xca\x61\x36\x68\xb3\xbe\x19\x3d\x94\xc3\x52\x1e\x58\x89\x13\xb5\x94\x8b\x55\x0b\xe9\x9d\x82\xd9\x66\x19\x7d\x71\x0a\xcf\xd9\x59\x14\xcf\x3e\x19\x75\x36\xe8\x3e\x68\x23\x0d\xc3\xd6\x7e\x67\xdc\xdb\xde\xe0\x4f\x0d\x9c\x48\x02\x37\xec\xd2\x8f\x74\x33\x8d\xb5\xf3\xf6\x97\xd3\xd0\x7f\xf3\x36\x13\xbb\xce\x54\x2a\xcc\x9a\x7f\xed\x5d\x12\x49\x0b\x9b\xfe\x1d\x10\x95\x40\xf8\x63\x80\x0d\xd3\x56\xda\x84\x1a\x45\xa3\xcd\x8a\x08\xa9\x45\xbf\xa3\xaa\x98\xe1\x71\x23\x12\xc4\xc0\xf0\xd9\xdd\x64\xf6\xef\xcf\x73\x6b\xd9\x7d\xea\xfc\xa9\xdc\xaa\x3f\x06\xd8\x7f\x2e\xd7\x2a\xeb\x6a\x94\xf3\x28\x00\x00\xc4\xbf\x72\x8a\x01\xc1\x86\x2d\xaf\xd9\xfc\x5c\x7d\x5a\x46\xec\x7d\x3a\x87\xaf\x59\xa1\x1d\x87\xf7\xff\x84\x40\x7d\x37\x01\x0e\x1d\x94\x6c\xf2\x25\xd6\xb3\xb1\xed\xee\x2e\x8b\xbf\x1e\x07\x9e\x47\xfb\x1f\x66\x66\x93\x94\xfb\xf2\xfa\x68\xfc\x56\xfc\x89\x82\x0a\x68\x09\xc2\x51\xdd\x62\xf5\xb8\x65\xc5\x47\xb1\x4f\xbd\x3a\x19\x50\x42\x44\xff\xbc\x7e\x52\x40\xf8\x8d\x43\x60\xf9\xca\xca\xaf\x5f\x82\x43\x3d\x33\x44\xfc\xae\xe0\xac\xde\xb7\xbe\xb9\xc0\xb3\xc7\x69\xea\xc9\x20\xef\x4f\x09\xab\xc2\xa2\x09\x55\x12\x04\x59\x43\xec\xcc\x53\xb1\xc0\x3e\xd2\x4e\x56\x7f\x3d\x7a\x71\x97\x7c\xab\x98\x40\xce\x89\x8e\xe5\x8e\xd5\xc7\x3f\x6a\xde\xa8\x23\x39\x4c\x5c\x8e\x36\x58\xa6\xbf\x5a\xcb\xbf\x00\x55\x99\x2c\x31\x2c\x26\xc7\x9c\x5c\xfb\xea\x38\x60\xb8\x76\x4a\x6d\x8f\xfe\x44\x91\xf8\xa5\xb8\xa2\x15\xe0\x11\x7a\x9a\x68\x16\x4a\xee\x25\xf8\xc0\xbb\x38\x11\x95\xb2\x40\x0b\xcb\x46\x44\xeb\xce\x1c\xde\x5a\x9a\x26\x58\x2c\xab\x9d\xc7\xf4\x3c\x33\xea\xe3\x50\xdb\x65\xaa\x7d\xd2\x2a\x07\x9b\xdd\xdc\xf5\x6d\x84\x8d\xeb\x0c\xfa\x50\xb3\xbd\x73\x2d\x9d\xa9\xe8\xd8\xab\x79\xe9\x34\x69\xde\x58\x02\xb6\xdf\xf5\xac\x2a\xa8\x48\x2b\xb0\xb0\x36\xd8\xf9\xd5\x95\xb8\xea\xd9\x4b\xb8\xd7\x41\x8e\x2e\xa4\x31\x92\xef\xcb\xfc\x05\xc4\x67\xbd\xe0\xa8\x68\xa5\x16\xa7\xc1\x4a\x88\x9b\x72\xc5\xb7\x3e\x7d\x85\xc2\xba\xe9\x02\xe4\xe6\x8d\x1f\x3c\xea\xb2\xb2\x77\x3a\xf5\xbb\xae\xe6\xa0\x0d\x08\x06\x3e\x78\x33\xcd\x4e\x29\x53\x47\xe5\x8f\x5d\x1b\x33\x97\xf6\x40\xc1\x59\xcc\x60\xa6\x74\xa2\x27\xb4\xcd\x8c\x10\xf1\xdb\xae\xd5\x16\xcc\xac\xdd\x29\x5f\x11\xb0\x81\x47"}, +{{0x32,0xa1,0x88,0x3e,0xff,0x57,0xa3,0xa7,0xec,0xdb,0x31,0x02,0x21,0xee,0x83,0xc4,0xde,0x92,0xb7,0x22,0x15,0x96,0x13,0xec,0xf8,0x16,0xe3,0x82,0x43,0x7b,0x60,0xb9,},{0x82,0xdd,0x1a,0x03,0xe5,0x85,0x20,0x62,0xba,0x4a,0x8b,0x6b,0x3b,0x93,0xc5,0xe9,0xc4,0x3f,0xf6,0x99,0x5b,0xd2,0xaa,0xc7,0x26,0x06,0xfa,0xc8,0x58,0x02,0xc6,0x82,},{0x83,0x09,0xcb,0xe7,0x2f,0x80,0x4b,0xd9,0x52,0x1d,0xef,0x5d,0xad,0x4d,0x8b,0xc1,0x38,0x86,0xb1,0xd4,0xf6,0x62,0xc9,0xbb,0x5b,0x97,0xba,0x47,0x90,0xf4,0x4b,0x80,0x1f,0x31,0x95,0xea,0xd0,0xd4,0xdd,0xb6,0x60,0x81,0x8e,0xcb,0xf9,0xa6,0x83,0xca,0xcf,0x85,0xf1,0xdc,0xc9,0xe8,0x2c,0x09,0x11,0x6d,0x73,0x36,0x58,0x09,0x1a,0x00,},"\xed\x2b\x12\x3b\x5d\xd7\xf5\xe7\x18\xe0\x26\xc7\x9c\xfa\x61\x11\x92\x49\x02\xd1\x89\xa4\x06\xef\x2b\x2e\x56\xa9\xee\x55\x73\xa7\x6d\xdd\x1d\x06\x29\xeb\xcd\xec\xf2\xaa\xa7\x4e\x84\xfc\xd0\x20\x8f\x14\xee\xa2\xe1\x71\xe7\xc8\x60\x8b\x81\x8f\xef\xf4\xdb\xea\x52\xdb\x35\x42\x27\xd0\x23\x25\x0b\x1f\x01\xcb\x4c\xc8\xc5\x21\x32\xa9\x8d\x4a\xcf\x55\xa5\x4f\xee\x81\xe0\x94\xae\xd6\x6f\xa0\xd6\xb6\xa2\x00\xb6\xb8\x74\x14\x40\x22\x78\x53\x8b\x90\x52\x9a\x8c\x60\x3d\x92\x7e\xdd\xda\x97\xbc\x4b\x8c\xb9\x5d\x04\xb5\x33\x7f\xa2\x2c\xea\xfc\x8b\x34\x0c\x46\xfe\xf6\x71\x98\xd1\xfd\x98\xd8\x9c\x65\xcd\x08\x9e\x23\xf5\x3d\xbd\xca\x96\x77\x98\xb5\xcd\x92\x32\x05\xad\x51\x1e\xdf\x70\x6f\x12\x25\xf4\x64\x8c\x98\x5e\x00\x9e\xf8\xa2\xf6\xa0\x11\x7c\xdb\xe1\x4e\x75\x31\x2d\x8a\xc1\xf0\x3d\x04\x6b\x37\xcd\xee\x7d\x69\xc0\xf2\x5c\xcf\x18\x14\x5a\x68\x8a\x8b\x3c\xa8\x87\x5f\xe8\xd9\x0b\xaf\x86\xd4\x39\x69\xe4\xd6\x10\x21\x4f\x1a\xc5\xdb\xba\x87\xa1\xef\x10\x37\x7e\x40\xd7\x80\x6f\xd9\xd2\x34\x57\xfc\x9d\xf2\x98\x99\x23\x9f\xd1\xd2\x78\x84\x96\x81\xa9\x43\xad\x9c\x91\xfd\x1b\xbd\x92\xb7\x3c\xb1\x77\xa8\x78\xf9\x05\x9e\xe0\x7a\xf7\xa8\x73\x16\x13\xe3\x3d\x59\xdf\x3d\x97\x79\x60\x79\xd5\x63\x1e\xd8\x5e\xb2\x24\x51\x06\xa5\xff\x6a\x2b\xca\x40\xdf\x5c\x6e\x87\x47\x3b\x2c\x08\xc2\x21\x2f\x56\xfc\x29\x33\xa9\x69\xa3\xc9\x58\xd3\x7c\x53\x43\xba\x27\x60\xc8\x13\xa7\xa5\x16\x5d\x23\x1c\x5f\xea\xae\x62\xb7\x55\xdf\x49\xfe\xca\x80\x04\x1a\x65\x35\xf7\xe0\x3b\xc4\x8e\x5f\x27\xf9\xbe\x26\xef\x53\x67\x3e\xb7\xc3\x7a\x2b\x64\x74\x4a\x6c\xf1\x7e\x88\x77\x34\xae\x01\x0b\xf4\x0e\xea\x03\xcd\xa2\x12\xf5\x12\xfb\xa0\x58\x59\x47\x17\x96\x40\xbc\xc4\x54\x4b\x8d\xeb\x4e\xad\x12\x9b\xc3\x32\x28\x00\xad\xf9\x88\x18\xf9\x95\x74\xbe\xfd\x9b\x00\x16\xd4\xee\xc8\x1a\x8e\x78\xdc\x3a\x2a\xf1\x3c\xab\x01\x64\x9a\xe2\xe3\x3d\x51\x6b\x9d\x42\x08\xad\x66\x13\xd8\xe2\x78\xc3\x93\xba\xa8\x82\x34\x0e\xf4\x61\xff\x4f\x94\x42\x3d\x55\xcf\x3c\xed\xd2\xa6\xb5\x6e\x88\x36\x55\x31\xdd\x29\xd6\x82\x73\xad\xbf\xe3\x69\x40\x2e\x6a\x7c\xee\x05\x3d\xa1\xf1\x00\x54\x00\x91\xa0\x09\x29\x25\x29\x83\x44\x90\x24\xb1\xc3\x39\x11\x10\x65\x00\x82\xf0\xe7\xdf\xdd\xb8\xed\xc2\x04\x2f\x3c\x17\x13\xc6\x94\x4b\xa5\x14\xee\x74\x07\xd3\x2b\xf0\x6c\x85\x8e\xfe\xc4\x2a\x78\xbe\xe9\x77\x46\xe5\xb4\x87\x91\x41\xa1\x3d\x9f\xc5\xcb\x12\x3b\x78\x32\x73\xb8\x4d\x57\xad\x35\x26\xb7\xda\x3c\x68\xb8\x39\xef\xd2\x3f\x5f"}, +{{0x22,0xec,0xef,0x6d,0xab,0xe5,0x8c,0x06,0x69,0xb8,0x04,0x66,0x49,0x73,0xe4,0x57,0xc0,0x5e,0x47,0x77,0xf7,0x81,0xc5,0x25,0x22,0xaf,0x76,0xb9,0x54,0x81,0xa9,0x14,},{0xd4,0x78,0x40,0x10,0xef,0x04,0x03,0xed,0xdc,0x5a,0x62,0xd5,0xd4,0x5b,0xb2,0x43,0xb8,0x0b,0x4b,0x9d,0x69,0xc3,0x9c,0xa3,0x87,0xc6,0xf5,0xcb,0xa0,0x28,0x64,0x0f,},{0x5d,0x0d,0x2a,0xf6,0x78,0xb3,0xd1,0xb6,0x77,0x51,0x6d,0x08,0xa7,0x9a,0xaf,0xd3,0x6e,0xc6,0x7c,0x14,0xca,0xf5,0xbc,0xda,0xae,0xaa,0xcc,0x51,0xa1,0x4f,0xb8,0x05,0xcf,0x29,0x04,0xe8,0x72,0x1d,0xb2,0x71,0xb2,0x0d,0xf7,0x09,0xbe,0xe1,0xa4,0xfb,0xfe,0x62,0x56,0x50,0x73,0xb2,0xa7,0xe9,0x42,0x72,0x44,0x61,0xf9,0x27,0x93,0x0d,},"\xc5\x35\xc1\x3d\x77\x9f\xc0\x98\x59\x73\xd6\xbc\xd5\x52\xd8\x17\x34\xe9\x2b\xdf\x10\x99\x4b\x00\xcd\x4d\x53\xce\x36\x5f\xad\x8c\x7c\xfa\x96\x20\x6a\xdb\x62\xd4\x56\x7b\xe5\xe4\x66\x31\x32\x38\x53\xe3\x8c\xe4\xbd\xc1\x6d\x7b\x8f\x63\x2a\x3a\xd9\xe0\x26\x19\xef\xf3\x71\x74\xea\xc3\xf0\xbf\x2f\x7a\x75\x17\xd4\xb8\x2d\xe6\xaa\x1a\xf0\x06\x38\x19\xd5\xe1\xf9\x27\x8f\xb4\xf2\x4c\x8c\xc0\x02\xaf\xb1\x5f\x33\x4c\x04\xfa\xdb\x00\x30\x30\x13\xc0\x16\x67\xf4\x93\x2a\x6c\x4b\x97\xd3\x9c\xd4\xa4\x59\x85\x06\xc0\xbd\x74\x0e\xa9\xf1\x16\x96\x35\x7d\x7d\x17\xfe\x4d\x75\xf9\xd7\x42\x41\xa7\xaf\x71\xf9\xd8\x69\xef\x6c\xd6\x95\x68\x7c\x03\xfc\x34\xad\x65\xa6\x8a\x48\x88\xa1\xa7\x41\x26\xcb\x55\xcf\x7d\xa9\xcb\x4a\x67\x17\xf6\xeb\x88\x48\x40\x89\xd2\xc5\x18\x9a\xe3\x81\xf2\x5e\x7b\x3b\xc3\xb2\x3d\x0c\x9d\x9f\x9c\xdb\xbe\xec\xfd\x1e\x72\xa0\x5e\x67\xbb\x48\x3a\x97\x64\xd9\xfc\x75\xad\x69\xe4\xab\x12\x70\xfb\x40\xf3\x95\x8f\xea\x4d\xa5\x59\xb4\x39\x80\xb2\x46\x81\x31\x3e\x85\x91\xe6\x85\x46\xa3\xbf\x76\xee\x34\xb3\x39\x70\x92\x95\xa8\xd4\x6f\xb2\x43\x2d\xda\x2f\x22\x18\x12\xdf\x69\x28\x95\xe6\x7c\xb2\x9c\xbf\x6f\xf4\x50\x2b\x43\x9a\x4e\x9e\x43\x63\x9e\xc0\x67\xbc\x90\xae\x81\x4a\x29\x3a\x7b\xd4\x69\x68\xe6\x56\x78\x76\x42\x30\x0a\x0f\xf2\x69\x7e\x33\x13\xf6\xa4\x18\xd3\xd1\x2a\x5f\x7c\x51\xa4\xc5\x7b\x63\x38\x5f\x2d\x2a\x21\xd5\xd1\xd7\x63\xfc\x8d\x1b\x93\xc1\x34\x35\xf9\xe4\x7e\xe7\xa4\x25\x98\x0a\x6a\xe6\xf1\xa9\xd0\x07\x60\x74\x76\x78\x3c\x6d\x0c\x78\x87\x38\x0f\x86\x8c\x65\xb3\x82\xd4\xcc\x8c\x04\x47\x8b\xbd\x79\xa1\xd9\xa9\x64\xb7\x81\x71\xd6\xbc\xf0\xb8\xee\xc5\x0a\x06\xa4\xea\x23\x4d\x1c\x23\x46\x5d\x3e\x75\xb8\x8b\xc5\x40\xda\xde\x74\xed\x42\x67\x5b\x07\xf7\xcf\x07\x82\x11\xe9\x07\xf8\x6d\x0d\xc4\xb9\x78\x62\x3d\x9f\x08\x73\x8a\xf9\x28\x69\x5e\x54\x2e\xc2\x98\x0e\x55\xa1\xde\x49\xe2\x52\x47\xfa\x0a\x09\x67\x81\x18\xe3\x93\x0b\xc4\xd2\x4b\x32\x14\xd6\xdc\xfb\x6e\xbd\xf4\x90\x6c\x92\x8d\xeb\x37\xbb\x9b\xa2\x9c\x8d\xe1\xbb\x94\x18\xdb\x71\x8b\x28\x53\xba\x57\xad\x8c\xae\x46\x77\xad\xdf\xd1\x8b\x6c\x7e\x8c\x24\x26\x21\xb3\x5c\x7f\x0e\xfe\x8d\xd5\xeb\x26\xff\x75\xfd\x57\x48\xb1\xd7\x83\xf6\xd6\x8a\x7d\x9d\x56\xda\x2c\x1a\x97\x8a\xc2\x5f\x84\xfb\xb2\xbe\x55\x68\xd9\x1e\x70\x93\x82\x21\xc1\x02\xae\xe6\x04\x09\xbc\xbe\xc0\xc8\x2e\x12\xdd\xb4\x25\xee\xb6\xec\xd1\x15\x51\xec\xd1\xd3\x3d\xda\xe8\x71\xae\x0c\x8f\x24\xd0\xd1\x80\x18\x73\x2b\x5e\x0e"}, +{{0x8d,0xe8,0x63,0x30,0xb2,0x56,0x09,0x5e,0x11,0x14,0xb6,0x52,0x9b,0xed,0xce,0x18,0x2c,0x16,0x6f,0x67,0xa9,0x15,0x39,0xce,0xbc,0x4b,0xec,0x25,0xad,0xd7,0xa4,0xa9,},{0x33,0xcb,0x05,0x4b,0x55,0xbb,0x79,0x0a,0xc0,0xf3,0xaf,0xdd,0x9a,0x6e,0x7c,0x05,0x0e,0xfe,0x90,0x06,0xc2,0x4f,0x60,0xb8,0x04,0x4f,0xd0,0x8a,0x5c,0x10,0x6c,0x11,},{0x6d,0x01,0xd2,0x37,0xdd,0x2b,0xb4,0x18,0x8d,0x29,0xbf,0xde,0xc3,0x87,0x97,0x6a,0x71,0xbe,0x7a,0xdf,0xbf,0x9e,0x23,0x63,0x9b,0x21,0x6d,0x0a,0xa0,0xc1,0x19,0x32,0x23,0x5e,0xdc,0xcb,0x3b,0x42,0xad,0xcd,0xb6,0x29,0x1a,0x0d,0x29,0x9a,0xed,0x64,0x8d,0xe8,0xb1,0x95,0x79,0x49,0xb9,0xd1,0xcf,0x2e,0x50,0x49,0x30,0x30,0xa4,0x0f,},"\x39\xe6\x1e\x0e\xcc\xec\x92\x9c\x87\xb8\xb2\x2d\x4f\xd1\x8a\xea\xbf\x42\xe9\xce\x7b\x01\x5f\x2a\x8c\xac\x92\xa5\x24\x48\xa4\x2f\xed\x4c\xba\xdc\x08\x5b\xbb\x4c\x03\x71\x2a\xe7\x2c\xfc\xb8\x00\xb9\x78\x35\x06\x69\xb0\x99\x00\x84\xf2\xda\xb7\x6e\xca\x60\x6d\x1a\x49\xfc\x55\xc5\x29\xe1\xe7\xda\xdf\x39\x12\x2d\xd5\xbd\x73\x38\x93\x85\x8b\x05\x23\xef\x62\xdf\x4f\x13\x4c\xf6\xc2\x6e\xed\x02\xfd\xbc\xb3\x0c\xe4\x74\xb1\xad\xa3\xf0\x60\x76\x9f\x93\x4b\xbe\x68\x6c\xce\xbd\x60\x88\x3e\xce\xc9\xce\x3f\xfb\x8a\xc4\xa0\x67\x8c\xdc\x5b\x00\x5a\xe3\xdb\xa7\xe4\xfe\x8b\xc0\x45\x73\x99\x57\xd8\x49\xf6\x9c\x14\x74\x05\x7b\x42\x8c\x54\x25\xf3\xcc\x25\x16\xe8\xbb\xe3\xbe\x81\xaf\xd4\xe7\xb5\x75\xab\xe8\x8c\x87\xf2\xf0\x3b\x56\xf6\x9f\x9e\x3b\x61\xb3\x78\x81\x20\xda\xa4\x95\xef\x0e\x50\xeb\x97\x0a\x64\x5c\x13\xd2\x13\xc7\xcf\xb7\xd0\xad\x55\x5c\x92\x0a\x1e\x5d\xbc\xb4\x67\x97\xd9\x39\xfe\x04\x01\xf5\x47\xbf\xd1\x75\x43\x22\x1a\x53\x01\x0d\xe0\x1f\x25\xb6\x45\x19\xc8\xf0\x39\x63\xe4\xb9\xca\x58\xb0\x11\x36\x27\xc0\x5b\x96\x08\xee\xaa\x7b\x9a\xe6\x30\x5c\x96\x18\x81\x60\x00\x0e\xe3\xa7\xad\xe9\x6e\x0b\x4b\xde\x9d\x0e\xd6\xa0\xce\xd7\x65\xd7\x86\x84\x0a\x48\x17\x5a\x6e\x09\x0a\x38\xaf\x6a\xde\xaa\x14\x86\xa9\xcb\x5c\x8c\x8c\x92\x23\xee\x0a\xe4\xc6\xc0\x26\x91\xa3\x54\x7e\x32\x58\x2a\x5b\x70\x59\xd2\xee\x66\xfa\x9c\xd9\x65\x61\x5c\x31\x5b\x47\x6f\xd8\x61\x27\x9c\xd1\xdd\x76\x07\x74\x3f\xc5\x56\x12\x96\x31\x2f\x11\xe4\x65\xca\x40\xbc\xe3\xcf\x0b\x1f\x1d\x5a\x30\xaf\x60\x87\xde\x4d\xe9\x6c\xe4\x39\x65\xa4\x6c\x4f\xcc\xa1\x5f\x28\x11\x49\xb5\xc1\xa0\xc8\x8f\xdb\xf2\x74\x09\xa1\x34\xed\x4f\x1f\xb7\x30\xfa\x19\x18\x16\xea\x78\x4d\x98\x6c\xc9\xec\x4b\x69\x44\x02\xde\x1d\xcc\xa9\xcc\xc6\x4f\xbd\x07\xb0\x7e\x54\xe9\x31\xde\x82\x7a\x84\x24\x60\xca\x0b\xf6\xb0\x4e\xbb\x57\x1f\xa7\x77\x87\xe3\x88\x4b\xe2\x2f\x1e\x40\x2c\xf2\xb8\xa9\x6a\x5d\x39\x77\x0e\xc4\xa8\x43\x03\x61\x42\xa0\xbe\x97\x0b\xb1\xab\x16\x5a\x63\x74\xdc\xf4\x3d\xeb\x8b\x98\x30\xb2\xc4\x9d\xb9\xcd\xfe\x4b\x52\x42\xe3\x6f\x95\xe0\xc3\xe0\x77\xe8\xd2\x38\xfa\x6a\x8a\xc0\xd5\x86\xbf\x61\xb8\x24\x8f\xb3\xa7\x9a\x27\x0a\xb2\x2b\xe8\xa9\xda\x05\x5f\xf3\xd5\xbb\x2d\x1c\xa9\xbc\x25\xf7\x01\x4b\x96\x40\x77\x19\xde\x34\x4c\x3e\x73\xb8\xc1\x14\xf7\x92\x07\x5a\x5c\x22\xfd\xd4\x16\x15\x4d\x34\x94\xec\x3f\x02\xfb\x11\x2e\xe5\x73\x7f\x70\x70\x4c\x1b\x6b\x07\xea\xcb\xf9\x45\x62\xca\x7b\x90\xdd\x84\xd9\x8c\x3e\xdf"}, +{{0xba,0xb5,0xfa,0x49,0x18,0x7d,0xa1,0xca,0xb1,0xd2,0x91,0x90,0x00,0x19,0xe6,0xcb,0xaf,0xec,0xcd,0x27,0xbf,0x7e,0xcb,0xf1,0x26,0x2a,0x70,0x05,0x16,0xe7,0xc2,0x9f,},{0xf6,0xfb,0x19,0x85,0xec,0x59,0x1f,0x69,0xe3,0xba,0xc8,0x07,0xb2,0xea,0xbf,0x26,0x39,0x90,0xcd,0xfa,0x09,0xb1,0x78,0x09,0xe4,0x8e,0x38,0x5d,0xa0,0x65,0xec,0x21,},{0xe3,0x16,0x03,0x8d,0x6a,0xa1,0x5b,0x1c,0x1b,0x61,0xc1,0xa1,0x6b,0x36,0x90,0x4f,0xe8,0xa2,0x89,0xc8,0xd6,0x02,0xbe,0xcc,0x51,0x4d,0x99,0x22,0x00,0x86,0xb2,0x67,0x85,0x9f,0x5b,0xf6,0xe9,0xc0,0x86,0x35,0x59,0xac,0x62,0x3a,0x56,0xd7,0x53,0x23,0x44,0xe8,0xd2,0xf2,0x8b,0x3f,0x9d,0xf9,0x20,0x89,0x70,0x8b,0x1b,0x05,0x90,0x08,},"\x5c\xf8\xff\x58\x7e\x52\xcc\xcd\x29\x84\xf3\x47\x91\xee\x68\x43\xe7\x70\x17\xc3\xb5\x5a\xd4\x5c\x44\x45\x09\x65\xb7\x5d\x83\x6e\x78\xfb\xd7\xa1\xd1\x72\x9e\xff\x6d\x6d\x34\x0a\x90\x3f\x3c\xf1\x7d\x9e\x2a\xec\xaa\xff\x2a\x32\x1f\xcd\xde\x0a\xbc\xfb\xbc\xbc\xc0\x9f\x40\x86\xf8\x12\xc4\x6e\xfb\x01\xb7\x83\x43\xaf\xbe\x48\x30\x9f\x91\x74\x78\x45\x5f\x32\x00\x0c\x6a\x69\xf7\x9f\xe2\x11\xb9\x9f\x03\x7f\x59\x56\xd7\x22\x75\xa7\xfe\x7b\x45\x29\x6b\x5f\x73\x9a\xa4\x51\xff\x05\x75\xbc\x70\x58\x85\xaa\x56\x31\xb0\xd0\x85\x0b\xc2\xb1\x2c\x41\x92\x43\x5a\xe5\xd2\xf5\x2b\xc5\x43\x86\x49\x7c\x4a\x24\xb8\xb6\xdb\x51\x6b\xe0\x9d\x8c\xcf\x1e\xca\x78\x5b\xde\x97\xe9\xbe\x1a\xc0\x64\xf0\x94\xe2\xaf\xcc\x30\x7c\x0e\x06\xb4\xc5\x64\xcd\x9a\x9a\x95\x30\x5b\x37\xb8\x1f\x43\x46\x11\xdc\xa5\x5c\xaa\xa0\x31\xe8\x84\x95\xd5\xdc\x5a\x04\xff\x5f\xaf\xdf\x0a\x82\xa0\xc0\x3a\xff\x1b\xfb\xf4\xff\xeb\xae\x71\x82\x4e\x35\xe7\x51\xb0\x92\x70\x00\x76\x69\x86\x0b\x58\x00\x35\x65\x9e\x23\xac\xe7\x6b\x3b\x36\x9f\xa3\x06\xf2\xbe\xd9\x57\x99\xfa\xfa\xbc\x2e\x69\xc1\x41\xbe\xb0\xba\xca\xc7\xea\xa3\x47\xe7\x7b\xe5\xaf\x3f\xcd\xbe\x7b\x36\x4a\x7f\x9a\x66\xd5\xe1\x7a\x07\xdf\x62\x02\xfd\x98\xc1\x4b\xfe\xe2\xca\x6f\x07\x45\x65\x1f\x0c\x85\x50\xf9\xff\xff\xca\xfb\x96\xff\xb3\xf1\x03\xe6\x52\xe7\x8f\x53\x91\x6c\xd6\xf1\xdd\x05\xb3\xfe\x99\xb3\x42\x01\xb0\x7e\xac\x26\x52\xf5\x25\x35\x71\xfd\x38\x22\xc6\x95\xd2\x65\xc7\xdf\xdd\x6c\x6b\x14\xa8\x0b\x6e\x87\x18\x3e\x6e\x03\x2e\x5f\x24\x01\xcd\x23\x8c\xdd\x37\x69\xbb\x6e\x39\x08\x23\x43\x8f\x56\x73\xea\x9a\x47\x9e\x5c\x63\xfe\x07\xa0\x7f\x4e\x14\xf5\x77\x57\xc4\xd7\xd2\x2b\x35\xd7\x1c\x44\xea\xad\x48\x73\xc8\xec\xa6\xf6\xb2\x1d\xcf\xa9\x55\x20\xff\x96\x14\xab\xf7\xa0\xe1\x88\x53\x09\xf2\xce\xd3\xbc\xdf\xc3\x19\x36\x3a\x2d\xa4\x6d\xed\x79\xa5\xcc\x7b\x6f\x69\x38\x3f\x94\xab\x35\xc2\x50\x62\x9c\xb9\x15\xd6\x67\xb6\x28\x11\x86\x75\x48\x95\x80\x3e\x4b\x95\xe7\x41\x82\x89\xa6\xac\x3b\xcd\xb6\xe1\xe7\xf6\xf1\xdc\x38\xe7\x7d\x28\x19\x14\xcc\x40\x4f\x97\xcf\xf1\x4f\xb2\xc4\xfd\x81\x41\x2d\x10\x1c\x1b\xfb\x36\x8c\xe5\x93\x11\xe8\x92\xa8\xb9\xcd\xca\x86\x93\x6f\x3b\xca\x7e\xc7\x91\x63\xed\xdf\x1c\xee\x68\xf4\x9f\x1e\xba\xa2\x7e\xc5\x0f\x49\x0d\x61\x60\x1c\xa3\x5f\x8d\x6e\xd2\x66\x05\x4a\xeb\x9b\x19\x9f\x93\x3b\xff\xd6\xe0\x05\x0f\x26\x1b\x4e\x13\xd5\xeb\xfe\x2c\xaa\x65\x57\xc3\x2d\xde\xae\xeb\xc2\xa1\x1f\x0a\xa2\x33\x24\x0d\xa1\xc7\xe4\x0f\x76"}, +{{0x74,0xca,0x12,0x2a,0xb6,0x0d,0xe5,0x0c,0xdc,0x04,0xa8,0xe2,0xed,0xa4,0x5d,0x96,0x31,0x06,0x1b,0xf1,0x87,0xd3,0x16,0xbe,0x5b,0x7c,0xc0,0x6f,0x02,0x0c,0x48,0x3e,},{0x78,0x7d,0xef,0xd4,0xfb,0x24,0xa3,0x99,0xbd,0x2a,0x4e,0x76,0xdf,0xf7,0xd6,0x03,0xed,0x0a,0xcb,0x32,0x69,0x81,0x3e,0x4d,0xf6,0x90,0xbb,0xf5,0xb2,0xbc,0x69,0x6e,},{0xbc,0xb4,0xb8,0x50,0x69,0x60,0x11,0x99,0x7e,0xb5,0xdf,0xe1,0x43,0xf1,0xa3,0xd5,0x62,0x8e,0xf1,0xa5,0x40,0x76,0x91,0xee,0x48,0xc7,0x9d,0x69,0xab,0xe4,0xd5,0x33,0xf8,0x17,0xad,0x73,0x13,0xb5,0x79,0x5e,0x46,0xe5,0x95,0xf3,0xae,0x3a,0x91,0x65,0xb1,0xb6,0xfd,0xda,0xe8,0x61,0x64,0xff,0xcb,0xa3,0x76,0x24,0x98,0x37,0xf6,0x09,},"\xa8\x0b\x46\x07\x9f\xa7\x75\xf8\xc1\xa1\x9f\xa0\x82\x9b\xe6\x66\xbd\xfd\xca\x07\x9c\xad\x43\xd7\x0e\x08\x42\x18\x3b\xc0\xdb\x95\x46\x8a\x53\x9f\x0d\xb2\xae\xa3\xab\x9c\x70\x73\xb4\x5d\x22\x8a\x9b\xde\x23\x28\x97\xa6\xeb\x6f\xc9\xed\xf7\x36\x5e\x71\x01\xba\x97\xc4\x46\xa5\x19\xa3\x64\x9c\xf5\x27\xc8\xa6\xde\x72\x51\xb9\x28\x06\x81\x5a\xc2\xfa\x00\x82\xef\xf7\x5e\x25\x82\xcb\xca\x7e\x1e\x4d\xa2\xa4\x46\xea\x23\x3e\x7c\xf7\xce\xdf\xb0\xe2\x39\x8e\xb6\xe1\x1b\xba\xef\xe3\xf7\xec\x89\xf5\xd7\x3d\xd3\x4b\xd4\x7f\xbc\xb4\xd7\xb2\x2f\x2a\xae\xe3\x73\x78\x56\x51\x84\x11\x35\xcd\x86\x61\xa7\x01\xb2\x10\x84\xa3\x16\xde\xac\x30\x74\xe2\x4a\x2e\x35\xa0\x33\x0f\x7d\x14\x79\xb9\x32\xf2\x85\x27\x7c\x18\xa4\x41\x78\x72\x24\xfb\xbe\x46\xc6\x2e\x83\x4a\x18\x51\xed\x23\x79\x98\xd4\x8d\xce\x20\xba\x11\x4d\x11\xe9\x41\xbe\x29\xd5\x6d\x02\xf7\x37\x0c\x8f\x6d\x6d\x7e\x50\x24\x8d\xcd\x8e\xc8\x9d\x3b\x22\xf4\xf5\x87\x78\x12\x9f\xaf\xd4\xbb\x92\xed\xe1\x77\x14\xbf\x02\x2a\x5b\xf9\x2b\xe4\x79\xf1\x8e\x63\x85\x2e\xcd\xcf\x8c\x42\x11\xf5\x30\xdd\x30\xf7\x9c\xbf\x4b\xfa\x57\x37\xf0\xba\xd3\xb0\x10\x60\x67\xf4\x13\x27\xc3\x18\x9e\x6f\x20\x6f\x0d\x4f\x3c\x70\x4b\xf2\xbd\x0b\x16\x1f\x01\x8f\xd2\x1c\xdd\xfb\x41\x8b\xac\x4d\x52\xef\x02\xc4\x1c\x87\x92\xe4\x13\xb0\x4f\x08\x36\xce\xa1\xf8\x6c\x92\xe5\xd5\x70\x3b\xee\x2b\x5c\x58\x99\xe2\x85\x99\x20\x24\xf6\x4e\x0d\x16\xc6\x0a\xd0\xfd\x92\x54\x79\x32\xd0\xc5\xcb\x98\xd8\xda\x22\xfe\xeb\xdb\xba\x8d\x1d\xe1\xe7\xe9\xbb\x21\x9a\x92\xeb\x6c\x1c\x69\x8d\x3b\x33\xa3\x7f\x9b\x81\x97\xd2\x6b\x55\x0f\xeb\xd2\x60\x1e\x7a\x64\x3e\xa7\xe1\xd9\xe4\x48\xae\x03\x7f\x62\x9a\x30\x6c\xe4\x17\xae\xb7\x9f\x2e\x3c\xa4\x4d\x8d\xb3\x84\x8a\x81\x1f\x18\x46\x81\x1c\xbc\xb8\x74\xf8\xaf\x09\xe0\xfd\x01\x73\xcf\x17\x5f\x30\x41\x15\x47\x6b\xf2\xc6\xc2\xd2\xf3\x32\xeb\xa5\x34\xf4\x6a\xae\x80\x1c\x26\x92\xc2\xd2\xfa\xdd\xfe\xac\xc0\xf1\xda\xce\x44\x0a\xbc\x2a\xe5\xe5\xa4\x9d\x57\x8f\xd7\xf9\xde\x2a\x84\x1a\xd6\xb6\x76\x9c\x32\xb1\x44\xce\xea\x16\xd0\xf3\xc0\xcb\x3a\x8e\xe6\x94\xc3\x8c\x28\x07\x35\x95\x09\x6c\x81\x37\x62\xcc\x2c\x5e\xc4\xb0\xd8\xd7\x23\xdd\x66\x08\x53\x27\x8f\xc7\x2f\xd6\xbd\x9d\x12\x72\x93\x3d\xd2\xa3\x8e\xd9\xd0\x4b\x13\x90\xff\xe4\xb2\x94\xa6\xff\xfa\x72\x1e\xe3\xbb\xa3\x3a\x03\xa1\x49\xc4\xa0\x34\x52\x65\xc0\x1c\xe0\x15\xe9\x4d\xb4\x19\xcf\xf7\x04\x98\x52\xee\x00\x00\x48\xa8\x57\x58\xf6\xd7\xb1\xc5\x9c\x50\x89\xee\x01\x8e\xd0\x9b\x52"}, +{{0x65,0xee,0xa9,0xff,0xb7,0x56,0x12,0xbd,0xe1,0xd9,0xba,0x3e,0xa4,0xfb,0x5e,0xda,0x0a,0xa6,0xf2,0x55,0x6a,0xb1,0x5b,0xf1,0x81,0x7c,0xee,0x3b,0x95,0xbb,0xba,0x12,},{0x5b,0x39,0x36,0xdc,0x74,0x9b,0x6b,0x92,0x39,0xf1,0x57,0x98,0xac,0xca,0xfd,0x88,0x4c,0x36,0x59,0xee,0x01,0xb2,0xd1,0x7d,0x74,0xfc,0x7d,0xa7,0x82,0x74,0xe7,0xe6,},{0xba,0xa7,0x11,0x31,0x55,0x35,0x8c,0x92,0x4f,0xed,0x57,0x48,0x8a,0x65,0x67,0xf8,0x72,0x38,0x50,0xa9,0xf5,0xc0,0x3a,0x0d,0x7d,0xe8,0x5f,0xcc,0xd8,0xfb,0x4d,0x17,0xd7,0x75,0x35,0x23,0xb0,0x0c,0x0d,0x8a,0xdb,0x88,0x4d,0xc0,0xc8,0xa7,0xa4,0x4d,0xc2,0xa6,0x00,0x83,0xaa,0x5b,0x3c,0x5b,0x94,0xa8,0xd8,0x80,0xf2,0xa9,0x4d,0x09,},"\xc0\x69\x36\x32\x3c\xe3\x25\x3c\xac\x5a\xb4\xf6\xb8\x32\x70\xcd\x4c\xfe\x85\xd0\xbf\x8b\xac\x1e\x1b\x8d\x5f\x0b\x15\x3f\x54\x1c\x8e\x8e\xd9\x5f\x28\xd5\xc8\x5a\x23\x15\xcd\x93\x1b\x7c\xf3\xed\xae\x50\xf9\x28\x30\x59\x91\x62\x80\x4b\x13\x63\xd3\xac\x0d\xa0\xab\xd0\x97\x51\x02\x3b\xdd\xc1\x62\x88\x94\x4e\x61\x6d\x21\xd9\x12\x71\x97\x8b\xb7\x82\xd3\xeb\xed\x7f\xa6\x12\x84\xc7\x49\x0d\x27\x59\x3c\xa8\xa3\xd5\xb4\x75\x62\x33\x07\x01\x0a\xbc\x1f\xbf\x79\x3a\x81\x6a\xaa\xb5\xe0\x92\x4d\xec\x79\xd6\x04\x98\x96\x5c\xf7\xf8\x0a\xb5\x9f\xc0\x29\xf7\x82\x16\x67\x55\xb7\x2b\x86\x90\x75\x43\x4a\xb6\x06\xcc\x87\x0a\x7c\x0b\xc8\xbf\x29\xae\xe0\x33\xfa\x9c\xc1\x22\xed\x7c\x8e\x06\x9b\x54\x7d\xba\xe2\x59\x01\xb9\xe2\x49\xb4\x1f\xea\x0b\xf8\xda\xf3\x82\x68\x66\xbc\xae\xd2\x75\x3b\x5e\x91\xae\x93\x7e\x71\x7b\x50\x8a\x0a\xcf\x4c\x3b\x06\x1f\xf0\xcb\x9c\xfd\x38\x0e\x24\x94\x50\x09\x51\xa6\x62\xfd\x49\x28\xfc\x5f\xca\xf6\xc1\x8e\x84\xb1\xd3\x78\xe4\x9b\xd9\xd5\x96\x86\xd0\x87\xeb\xd5\x52\xd0\x7f\xa9\xba\x81\x6f\xa5\x40\x2c\xa9\xe7\x25\x2a\x64\x8d\x10\x6c\xfe\x6c\x43\x1c\xc2\xa0\x53\xe2\x29\x46\x37\xcd\xb9\x9d\x96\xab\xe6\x89\xed\xab\xc5\xca\x07\x0f\x77\xc1\xec\xd1\xd5\x2d\x53\x85\x28\x9f\x17\xce\xd7\x68\xc3\x97\x16\x71\xb9\xc0\xb2\xf8\x55\xb8\x46\x1c\x1e\x74\x6c\x7b\x38\xf7\x78\x96\xb8\x5a\xfb\xbe\xdd\x08\x37\x5f\xe9\x22\x98\x46\x14\xdd\x84\x9f\xe2\xcb\x89\xae\x71\x49\xdc\xd1\xd3\x7f\x49\x36\xe6\x7b\x14\x40\xbe\x72\xe0\x09\x39\x8b\xe6\xf0\x83\xbf\x96\x11\x48\x0b\x59\x2f\xe2\xf0\x11\x8e\x25\x3d\xb5\xd2\xe9\xe4\xb4\x54\x1c\x11\xda\x00\xf7\x16\x1a\x73\x6e\x5f\x0b\xb9\x34\x20\x8e\x3e\xf4\xe0\xb9\xa5\x22\x58\x20\x3f\x06\x0d\x18\xa1\x95\x15\x9e\x5e\x26\x8a\xa2\x80\x53\xc8\x34\xf7\xbd\x5d\xb9\xbd\x71\xf5\x07\xd9\x13\x70\xb3\xff\xca\xbb\xd4\xac\xb3\x07\x1d\x3f\x6d\x52\xc3\x49\xac\xf3\x50\x95\x34\x8c\xeb\xf5\xa8\x6f\x8c\x59\xdd\xc9\x65\xef\xf6\x10\xac\x42\x58\x04\xc0\xe2\xf6\xbe\x42\x85\x3f\x5b\x46\x43\x4a\x2c\x31\xd9\xac\x99\x53\x9b\xfd\xc0\x4e\xcf\x2f\xef\xd0\x45\x98\xfa\x63\xc1\x39\xff\x6c\x6d\x88\x41\x0e\x73\xbd\x32\x8c\xc4\x34\x9a\xb4\xbb\x86\xf2\xe2\xed\x7c\x73\xde\x96\x52\x0e\xf7\x73\x0e\xf3\x83\x45\xe0\xf9\x72\xa8\x4c\x53\x88\x10\x36\x87\xe6\x8c\x50\xf9\xd8\xc9\xaf\x90\x3b\xc6\x32\xd4\x32\x04\x06\x2a\x4f\x50\x2e\x21\x4c\x07\x05\x9c\x2c\xbe\xf7\x2a\x54\x11\x0d\xbf\x73\xe4\x25\x40\x2d\x17\xe9\x78\xec\x19\x9b\x51\x8c\xec\x03\x10\xbf\xbf\x7d\x9a\xd3\x00\x43\x4a\x4a"}, +{{0x08,0xda,0xbd,0x4e,0x5c,0x11,0x9e,0xa9,0x07,0xce,0x45,0xf0,0xa7,0xaf,0x9e,0x62,0xc0,0xc3,0xf1,0xc9,0xec,0x61,0xad,0x10,0x56,0x7d,0x79,0x36,0x28,0x54,0xc5,0x57,},{0x94,0x54,0x06,0xb8,0x5d,0x7b,0x32,0xe0,0xb1,0xab,0x12,0x00,0xb9,0x42,0x22,0xde,0x1a,0xaa,0x68,0x62,0x4c,0x60,0xbb,0x47,0x16,0xb0,0xbc,0xe9,0xdf,0x00,0x57,0x71,},{0x33,0xad,0xbf,0xcd,0x4e,0xd4,0xfa,0x67,0xc5,0x8b,0x5c,0xb5,0x9e,0x16,0x98,0x71,0x48,0x69,0x78,0x12,0x66,0x0b,0x35,0x31,0xff,0x6a,0x21,0xc7,0x49,0xb9,0x60,0x16,0x60,0xba,0xee,0xe2,0x48,0x9b,0x82,0xb4,0xcd,0xe1,0x32,0xb6,0xe6,0x2f,0x2f,0x90,0xd8,0xf9,0x92,0x78,0x60,0xaa,0xad,0x25,0x28,0x1d,0x03,0xeb,0x17,0xa9,0x52,0x0f,},"\x6c\x47\x19\xa5\xa2\xa6\x89\x48\x35\xc4\xac\x1e\xd6\x91\x59\xe5\xeb\xb5\x69\x2a\xd8\xea\xad\xa4\x39\xf7\x9e\x96\x68\x4b\x36\xce\xcf\xb4\x4b\x89\x01\x56\x31\x66\x3e\x06\x44\xf6\xc7\xab\x71\x39\x89\xd7\x42\xda\x27\x42\x72\x53\x31\x8a\x52\x43\x2d\xfa\xb2\x12\x1d\x1e\x92\x33\xea\xd7\x19\xe2\xc8\x6a\x6b\xe0\x73\x63\xd0\x02\x17\x3f\x20\x54\x46\xca\x95\xfc\x17\xb2\x46\x35\x82\x7f\xe3\x15\xf2\x22\x40\x8e\x45\xe8\x33\xf2\x9f\xf0\x8f\xf3\x1d\xac\x58\x3a\x4b\xec\x70\x76\xd5\xcc\x78\xcf\xc9\x44\x51\xcb\xf4\xf7\xe2\xfc\x5b\x5e\xd8\x07\x0f\x4e\xf8\x08\xbe\x1d\x8a\x68\x0e\xcd\xff\x59\x01\x0f\x39\xb1\xde\x80\xbe\xf1\x71\x9f\x1e\x21\x8e\x0c\xe0\xa1\xe3\x93\xa5\x66\xc5\x17\x64\xd2\x37\x0d\x95\xa6\x11\x91\xd8\xf7\xaf\x74\x0d\xc2\x08\xfa\x78\x31\xb2\x10\x67\x05\x12\xcd\x73\x76\x6e\x60\x9e\x9b\x78\x00\x21\xeb\xb2\x0c\xc8\x79\x0d\x8d\xa5\xf1\x0f\x5b\x6a\x11\x4a\x1d\xb8\x8f\x66\x76\x65\x01\x80\x2d\x9c\x36\x6e\xa3\xfa\x6f\x1b\x1e\x1e\x8b\x04\x20\x94\x34\x13\xcc\x6f\xea\xb2\x8c\x6b\x68\x3c\xd2\xb3\x33\x06\x9c\x89\x51\xbc\x45\xe8\xa1\x3b\xd5\x22\x57\x83\x51\xc8\x82\xf7\xc3\x42\xfe\x43\x31\xb9\x21\xf5\x33\xc9\x2e\xc0\x4a\x49\xb2\x92\xbc\x56\x9d\xdc\xef\xca\xb5\x72\x7f\x9b\x56\x25\xb1\x67\xa9\x02\xdc\x89\x6d\x8b\xc7\xd8\xe9\x99\x20\xf5\xdb\x8d\xd7\x67\x83\x9c\x43\xe3\xcd\xf9\x47\x08\x0d\xec\x95\x42\x14\xa6\xfb\xbe\x04\x87\xa2\xf3\x2c\xd1\x7a\x6b\x00\x03\x70\xbd\x41\x44\x84\xfb\x73\xc5\x10\xea\x01\x24\xc6\xcf\x0f\xe5\x6c\x08\x46\xa7\x9b\xfc\x59\x77\x9d\x3b\x07\xa1\xbd\x2c\x7f\xb7\xe2\xd0\x03\x9f\x0b\xd2\x1c\x8a\x30\x8f\xb0\xf5\x8f\xdb\xf9\x4e\xfa\x08\x57\xac\x3b\xdd\xdd\x86\xd5\x76\x3e\x20\x5e\xe1\xb2\x21\xf0\x60\xce\xdb\x8b\xc0\x5f\x03\x1b\x60\x6c\xc7\x4d\xad\xc5\xdb\x04\x23\x27\x48\x86\x5a\x73\xd6\xcc\xdd\xb4\xd5\xe9\x30\xd5\x28\x34\x8c\x5b\xe9\x08\x8b\xfe\x34\x45\x84\x87\xa6\x7b\x19\xa1\x8e\xca\x25\xc0\xd3\xfb\xe2\x19\x5e\xb9\x17\x07\xb6\x5d\x91\x61\xea\x93\xed\xdd\x64\xa6\x34\xb2\x32\x80\x19\x5f\xdb\x0d\x13\x88\xf6\x99\x8e\x18\x58\xa4\x5b\x88\x69\x99\xb8\x44\xe6\x79\x5d\x83\xd3\x18\x37\xe4\x41\x1f\x71\x69\x92\x26\xde\x1b\xa0\x24\x56\x08\x00\x0d\xcf\x22\x3d\xd1\x83\x59\xb7\xc6\xd4\x59\xa6\x5d\xbe\x66\xc9\x0f\x5c\xb8\xc0\x91\x22\x18\x7a\x30\x46\xa1\x6d\xd1\x79\xc3\xf4\x37\x3e\x57\xcf\x5e\xe0\xea\xb6\xa2\x12\xcc\x9e\xd8\xb5\x4b\xf3\x7f\x1d\x27\xfb\xd7\x98\x48\xe4\xec\x1f\x56\x72\x43\xab\x87\x40\xa0\x51\x49\xd9\x60\x2e\xad\xa9\x20\xa4\x6d\x61\x0d\x3c\xc8\x23\xb5\x64\x98"}, +{{0xe0,0xf7,0xd0,0x08,0x24,0xc5,0xf3,0x70,0x1e,0x55,0x17,0xa4,0xab,0xc1,0x3e,0x2f,0x2c,0x0b,0x13,0x8c,0x83,0x69,0x77,0x84,0x3b,0xbd,0x1e,0xef,0xfa,0xbd,0x96,0x8a,},{0x52,0xfd,0xda,0xe3,0xe0,0x18,0xa6,0x84,0x73,0xb3,0x16,0x8d,0x07,0x64,0xcf,0xe2,0x74,0xdc,0xc8,0x34,0xc9,0x0a,0x91,0xfb,0x4f,0xe7,0x4b,0x93,0x9d,0xd2,0x38,0xb1,},{0xcc,0xdf,0xe1,0x8a,0xd6,0xd0,0xb6,0x5d,0x08,0x6d,0x63,0x2f,0x83,0xcc,0x46,0xff,0x3b,0x3f,0x2c,0x07,0xbb,0x8e,0x76,0x9d,0x0f,0xb4,0xe8,0x2d,0xf8,0xa3,0x87,0x3f,0x9a,0xee,0x35,0xfd,0xd1,0x8a,0x57,0x83,0x60,0x31,0x80,0xa9,0x5c,0x9f,0x74,0xce,0xd9,0xdb,0x51,0x46,0xaf,0xcf,0xbb,0xdd,0x40,0xdf,0x29,0xe0,0x42,0x01,0x20,0x0c,},"\xb3\x9e\x3a\xc7\x5a\x22\x1a\xdc\xce\xd0\x9a\x85\x91\xac\x5e\x2f\xe1\x5d\xfe\xd5\xb9\x19\xcb\xaf\x14\xc6\x5e\xb7\xcd\x93\x08\x6d\xde\xe3\xf7\x47\x25\x47\xe6\x6d\xdc\x70\x06\x2b\x97\x62\x97\xd1\xa3\xc1\x70\xee\x52\x5c\x9c\x53\xba\x93\xa4\xc4\xfd\xb2\x35\x72\xb7\xca\x6e\xd1\x38\x53\xe7\x0d\xb1\xd7\x2e\xde\xb9\x94\x4b\xbc\x35\x4a\x52\x0e\x77\xae\x59\x1f\x31\x80\x92\xef\xd5\xe6\x6d\x9c\x09\x81\xc4\xa4\xbd\xa9\x8a\xa4\xe5\x90\x45\xff\x9c\x4b\x4c\xa3\xac\xb2\xff\xd8\x93\x20\x1c\x70\xb3\x4a\x77\xf2\x4e\xda\x54\x54\x9d\xc8\x4a\xd1\x34\xa3\x55\x32\x55\x38\x15\x88\x8a\xe3\xdd\x9e\x24\x1e\xc4\xeb\xbf\xf8\x6f\x8c\x1e\x8a\xdb\xaa\xc4\xb9\x1a\xfd\x18\x22\x8c\xbb\xd5\xdd\x80\x5a\xca\xbf\x0a\x1e\x29\x0c\xe5\xdd\xa0\x25\x1a\xdf\xb3\x7c\xb7\x14\xc1\x39\xb5\xa3\x24\x2d\x88\xc6\x44\x84\xa3\x76\x55\xcc\x8f\xcb\xec\xff\xa9\x7f\xbd\x14\xd6\x4d\x51\x2b\xf8\xf6\x30\x5f\x89\xc5\x09\x22\xde\x54\x16\x92\x15\x8f\xb5\x47\xfd\x53\x9f\x1e\x58\x77\xcc\x64\x94\x95\x16\x63\x32\xea\x2b\x68\x5c\xfa\x3f\x60\x20\x19\xdf\x2a\xb2\xc2\x5e\xd9\x6b\x68\x74\x5e\x9a\xe8\x9c\x94\x8d\xa1\x1a\xd8\xa8\x30\xdf\x8b\x00\xf2\xe6\x68\x19\x2d\xad\xf2\xc5\x62\x0d\x35\xc6\xe8\x1a\x28\x53\xf8\x41\xe3\x75\xa0\xd9\xfc\xa2\xd2\x96\xef\xce\x2a\xc3\x8d\x40\xb0\x30\xb5\x75\x60\xae\x6e\x83\x41\x33\x9b\x3d\x3c\x2d\x06\x11\x64\x12\x43\x19\x59\x86\x88\xfc\xa6\x18\xfc\x64\xc9\xe8\xf5\xf8\x31\x09\x7a\x05\x3a\xf1\x9d\x7d\xbd\x61\x21\x8d\x92\x67\x42\xc2\xe9\xa4\x2a\x79\xcc\x1b\x14\x89\x12\x72\x2d\x8c\xd5\xca\x79\x3a\x1a\xd7\x3b\x5f\x14\x1b\x41\x80\x9c\x2f\xc0\x53\x0b\x76\x30\xe8\x03\x90\xc6\xb3\x38\xc7\x18\x68\xda\xcc\x59\xbf\x46\x3f\xfc\x48\x90\x16\xbf\x67\xf9\xc9\xd5\x55\x3c\x1e\xde\x17\x15\x28\x13\xfe\x0b\x26\x4b\x65\xdc\xa1\xb2\xb3\x8e\x4b\x80\x9f\x8c\x97\x25\xac\x5b\x1d\x8d\x2e\x56\xbe\xc9\x64\x9f\xe5\x5c\x75\x83\xff\x23\xb0\x43\xd6\xf3\x76\x86\x28\xf1\xf0\x51\x63\x37\x82\x4a\x5a\x56\xb4\x09\x52\x0a\x6a\x6c\xb7\x7e\x4f\x5f\xc2\x0b\x9f\x68\x99\xe0\x0a\xb2\x2d\xb1\x0d\x18\x2f\x09\xb8\x1e\x94\xf3\xad\x56\x8a\x0b\x81\x24\x4d\xf3\xf1\x85\x5c\x6e\xf2\x22\xa4\x1a\x51\xb6\x2a\x46\x49\xbb\x82\x69\x0a\xb6\x5f\xac\xac\x0d\x81\xd6\xfe\x02\x60\x11\x70\xa8\xdb\x62\xcb\xc5\xec\x99\x55\xd7\x71\x1a\x1c\x39\x65\x6a\x9f\x6e\x1f\xb6\xbc\x18\x3d\x9b\xea\x15\x03\x53\x1f\x17\x36\x27\x68\xbb\x84\x1f\x9d\x21\xf1\x3a\x2c\x99\x1e\x55\xdf\xf7\xf2\xb3\x36\xe2\x9e\xb2\x95\x07\x63\x8b\xdc\xad\x7b\xb3\x1c\x69\xe9\x09\x20\x7e\xba\xbc\xc6\x53\xff"}, +{{0x6a,0xcd,0x93,0x9e,0x42,0x22,0x26,0xcc,0x54,0x43,0xd4,0xaa,0xbf,0x58,0xc1,0x1a,0xf6,0x50,0xcb,0x40,0xb9,0x64,0x8b,0x4d,0xa3,0x8b,0x92,0x7b,0xff,0x9a,0x58,0xdb,},{0x4c,0x0b,0x91,0x75,0x6b,0x9e,0x20,0x6f,0x78,0x63,0xb1,0x55,0xff,0xc5,0x50,0x9b,0xb5,0x24,0x77,0xce,0xac,0xd0,0x1c,0xa0,0x11,0x43,0x51,0x53,0x67,0x86,0x46,0xcc,},{0x79,0x99,0x58,0x77,0xed,0x24,0xc7,0x91,0x68,0x4f,0x29,0x84,0xbd,0xf9,0x60,0x9c,0x3f,0x7b,0x57,0x6c,0x57,0xd1,0x62,0xee,0x62,0x2d,0x4c,0xe8,0xf3,0x6d,0x9c,0x55,0x73,0x16,0x9d,0x88,0x01,0x21,0x6f,0x1c,0x46,0xff,0xe2,0xf6,0xe2,0xc0,0x90,0x48,0xe4,0x7d,0x4b,0xeb,0x99,0x7e,0x9a,0xbc,0x4a,0xbb,0x12,0x9f,0x9b,0x79,0x69,0x0a,},"\x82\x50\xd5\x31\xcf\x2b\x66\xaa\xc2\xb3\x78\xd5\x4b\xc5\x7f\xd3\x29\xad\x5a\x41\x4a\x59\x92\x55\x89\x8b\x3c\x3b\x45\xbf\x9c\x0d\x2c\x77\x54\x75\x66\xb6\x60\xee\xcc\x76\xa6\x95\xa2\xd6\x08\xab\xf1\x1a\x5f\x6d\xb3\xe6\x07\xfd\x5a\x21\x71\x4b\x0f\xad\x5d\x81\x4c\x01\x5e\xbf\x48\xbb\x73\xad\x75\xda\x9c\x03\xc4\xaf\x54\x89\xe7\x82\xb6\xbf\x79\x08\xa1\xbd\x52\x8d\x7c\xe7\x88\xa1\x8b\xa3\x52\x8e\x35\x37\xaa\x7b\xbf\x75\xf6\x52\x4b\xbd\x19\xa5\x30\x4b\xa2\xa4\xa3\xee\x58\xc4\x1f\xec\x31\x32\xee\x65\x01\x64\x12\x15\xef\xf7\x46\xd7\x80\x0c\x4d\x33\xf5\x2b\xe8\x35\x7e\x0e\xe7\x58\x04\x1d\x91\xcf\xe4\x3c\x60\xc3\xce\xdc\x09\xb0\xd4\x6d\x4c\xfb\x9a\xe2\xa0\x23\x9b\x6f\x33\xc6\x94\x1c\xff\x35\x37\x26\x70\xee\xf5\xc8\x85\x9a\xb6\x5b\x6e\x9f\x7e\xbc\xe3\x2f\xa1\x5a\x9a\x47\x7a\xec\xdc\x96\x83\xa1\xe3\x3a\x1e\xdc\xdc\x90\xd4\x20\xa3\x1e\x78\xc1\x53\xd2\x60\x20\x87\x1d\xaa\x4f\xff\x28\xac\xc3\xf1\x1a\x72\x06\x78\x88\x06\xb6\xfa\x02\x34\x68\xea\x5a\x3d\x18\x6d\x10\xf0\xdd\x56\x77\x96\x66\x3b\xa3\x7c\x83\x2f\xe7\x5a\xae\x7d\xcc\xeb\xf3\x19\xf9\x36\x00\xc4\x6a\x22\xf5\x72\x23\x81\x2d\xdd\x0a\x68\xd7\x6b\xaf\x5e\x27\xa9\xfc\x8b\xd6\x8c\xc1\x0b\x5b\x51\x51\xd6\x2b\x41\xf9\x34\x8e\x21\xb7\x15\x35\x2f\x26\x30\xb6\x17\xf8\x13\xb0\xc2\x89\x96\x28\x59\x04\xcf\x29\x4e\x9c\x28\x56\xb1\x7b\xa3\x5f\x9a\x82\x19\x8b\x82\x14\xa0\x35\xe2\x89\x6d\x65\x68\xbe\x42\x39\x2c\xce\xf3\x2c\xd4\xeb\xfe\xeb\xf1\x2b\xe0\x12\x52\x06\xbb\xe8\x93\x36\xd3\xe7\x62\x99\x1d\xfa\xb6\x8f\xc9\x9d\xc1\x64\x9b\x89\x13\x83\xdb\x31\xfa\xb6\x49\xe6\x28\x82\x3f\x45\x98\xcb\x63\x6a\x38\xfe\x1d\xf7\x3e\x68\xd7\x42\x5f\xc5\xd2\xeb\x55\xa0\xfd\x1b\xc9\xf5\xce\xaa\xbd\x6d\xd4\x1f\x23\xe4\xf0\x86\xc6\x92\x63\x3d\xc3\xc4\x61\x9a\x97\xab\x0e\xad\xa1\x71\xf8\x4a\xdf\x20\xec\xc8\xec\xd4\x7c\x51\xcc\xa3\xe5\x9d\xd8\x09\xb0\xae\xaa\x73\x0d\xf9\x4b\xe3\xba\xcf\xd8\xee\x88\x8b\xba\x9d\x57\x08\x50\x65\x2c\xd4\xd5\xe6\xc5\x52\xa5\x7e\x9f\x48\xa2\xb0\x6a\xac\xdc\x70\x8d\x84\xa3\x76\xfb\xc6\xc9\x4b\xa6\xbf\x64\xa5\xf0\x18\x80\x0a\x7c\xc8\x51\x24\x5a\xed\xb2\x03\x78\xb3\x29\xac\xeb\xb2\x97\x7c\x13\x98\x08\x2b\x3a\x0e\x5e\x2a\x9c\x24\x84\xfa\x30\x1d\x30\x37\xa8\x22\x4d\xdc\xc0\x95\xb1\xdb\xd8\xa2\x31\x5b\x55\xbf\x33\x18\xc2\x78\x10\xef\xc3\xd8\xe2\x5f\xa7\xa8\x78\x9b\x73\xa4\xf5\x50\x59\x08\x0b\x08\xab\xb3\x69\x9b\x7b\x86\x26\xcb\x2a\x78\x0d\x97\xcc\x1c\xa8\x03\x28\x51\xba\xf4\xed\x8b\x64\xfc\x43\x30\x86\x5f\x84\xcc\xb1\x2a\x3d\xae"}, +{{0x4d,0xef,0xf6,0x47,0xcb,0xc4,0x5e,0xca,0xed,0xc3,0xf7,0xdd,0xf2,0x2c,0x16,0x7a,0xf2,0x4e,0x3d,0x63,0xda,0x22,0xb0,0xe6,0xa5,0xb8,0x43,0x9c,0x0f,0x3b,0x19,0x34,},{0x0c,0x27,0xc9,0xd7,0x7a,0xc8,0xc7,0x25,0xbb,0x06,0x63,0x93,0x3a,0xb3,0x0d,0x1a,0xad,0x09,0xcb,0xcf,0x2c,0xd7,0x11,0x6c,0x60,0x85,0xa8,0x49,0x9f,0x70,0x14,0x02,},{0xdd,0x54,0x89,0xfd,0xe4,0xba,0x87,0xd1,0x17,0x3d,0x4c,0xee,0x06,0x82,0xaf,0xdd,0x4b,0xad,0x80,0xdd,0x77,0x0e,0xa7,0xd0,0xdc,0xeb,0xaf,0x21,0xac,0xc6,0x1d,0xd6,0x32,0x4a,0xca,0x29,0x5e,0xd0,0xe2,0x3a,0x91,0x5e,0xcf,0xda,0xd5,0x0f,0x17,0x5e,0xbc,0x51,0x6f,0x1b,0xe5,0xb6,0xd8,0x7d,0x90,0xbb,0xe3,0x86,0x22,0x49,0x53,0x02,},"\xd6\x20\x1e\xbc\x21\xce\xc1\xe9\xbc\x28\xf9\x57\xc9\xd0\x29\xcc\x38\xf9\xe8\x5e\x06\xdf\xc9\x0b\xf2\x97\xe6\x1f\x2b\x73\xb4\x07\xd9\x82\xa6\x6b\x91\xe9\x4a\x24\xe9\x1d\x06\xab\x8a\x5c\x07\x9d\x0f\x69\xbe\x57\x88\xea\x8f\xea\xce\xbd\x91\x72\x91\x19\x22\x33\x86\x2e\x6a\xcd\xa1\xe8\xcf\x9a\x48\xbf\xfb\x54\x91\xdd\x65\xaf\x54\x1b\x6c\x72\xaf\x68\x1a\x81\x82\x3d\x98\xa0\xab\xee\xb6\xba\x9f\x95\x46\x5b\x84\x11\xf9\x9e\x11\x9c\xd2\x84\x79\xda\x98\x42\x59\xbd\xf8\x6c\x9f\xef\x3c\xca\x34\xe2\x24\x69\x1f\x18\x3c\xf0\x95\x03\x77\x27\xda\x9c\xad\x29\xf2\x42\xf8\x3e\xb4\xf7\x36\xe2\x7f\xdf\x67\x01\x8d\x71\x1b\x74\xc4\x5b\x29\x55\xa6\xa7\x6e\xc1\x53\x30\xdf\x5b\xad\x80\x30\xc6\xb3\xa8\x8d\x72\xf2\x84\x47\x65\x2a\xc8\x90\x2b\x5b\x76\xcb\xf6\xb9\x45\xce\xab\xfe\xc0\x4a\x9b\x8c\xb3\x0f\x43\xd9\xeb\x77\x3e\x67\x05\x59\x4f\x0d\xe1\xb7\x0f\x1a\x20\xc9\x9f\xc4\xb1\x22\x1f\x8c\x81\xb0\xbc\x30\xda\x12\xcd\x5d\xea\x8f\x4d\x90\xf1\x3a\x81\x1a\x2c\xc1\x1a\x96\x84\x6a\xaf\xb4\xc4\x2a\x00\xe9\xae\x7d\xa2\x56\xa0\xd2\x2b\x19\x8a\xfc\x25\xcc\x10\x41\xd2\x4e\x05\x6c\xf3\x87\x60\x1d\x7b\xf7\xeb\x31\x82\xd6\x05\xfe\x5e\x63\xb1\x8d\x53\x1a\x5f\x84\xe5\xdb\xd0\x18\x4a\x76\xc6\xc4\x67\xa8\x26\x3a\x98\xb5\xc0\x05\xfc\xb2\xaa\xf9\x89\xf5\xcb\xd0\xa9\xd9\x03\xfc\xfc\x60\x9d\x6e\x57\xd9\xc4\x39\x02\x1c\xea\x93\xe4\xc4\xe9\x91\xf1\x93\xca\xf3\x24\x37\x70\xb3\x25\x78\x74\x80\x76\xb7\xf4\xcb\x97\xf1\x7c\x17\xa7\x9b\x82\x25\x3c\x24\x23\xdb\x69\x8c\xd0\xa3\x3a\xb3\x3b\xb0\x9b\x0b\x08\xcb\x8c\xea\xdc\xa1\xe2\x9c\x5d\xe2\xfc\x12\xb2\x40\x7b\x6c\xc5\xaf\x5a\xe9\x76\xdd\x3e\xc6\x30\xd8\x33\x9b\x7d\xd1\x1f\xa3\x4c\xaa\xc1\x50\xc7\xc4\x79\x1d\x8c\x42\x7b\x0a\xd9\x2e\x05\x29\x06\x7a\x88\xd5\x20\x11\xe1\xe0\xa1\x82\x99\xb9\x69\x89\x6f\x8b\x83\x60\xf7\x5c\x45\xc4\x96\xda\x47\xb0\x9b\x45\x0f\x98\x22\xbc\xbc\xd4\x3f\x42\x93\xc5\x16\x80\x2b\xf7\x47\xc4\xab\xee\xdf\xaa\x3e\x79\xcb\x91\x03\xd3\x77\x0f\x56\x07\xb7\x75\x16\xe5\xb1\xce\x0f\x64\xb6\xee\xc7\xbe\xc3\xc6\x47\xc0\x06\x95\x6d\xc5\x5b\x6c\x79\xf6\xaf\xb3\x9d\x1f\xc3\xec\xf1\x1b\x97\x4b\x44\xae\xdb\x72\xae\xd1\x31\x66\x35\x08\x3c\x21\x24\x50\x2e\x5c\x72\xd8\x6e\xca\xb6\xac\x90\x24\x3e\xb3\x9a\x6a\xa9\xcb\x94\x80\xda\x38\xe1\xed\xb8\xd2\x8f\xf9\x09\x24\xc0\x5d\x5d\x21\xaf\x5a\xf9\x59\x57\xb8\x02\x07\x81\x37\x87\x11\xa2\x9d\x09\x20\xac\xad\x8c\xcb\x39\xa3\x11\x69\x32\x78\xc9\x90\x0b\x47\x0d\xa2\xbd\x4c\x12\xa0\x1d\x73\x96\x26\x44\x01\x7b\x60\x34\x71\x3b\x2a"}, +{{0x5a,0x19,0xbf,0x6c,0x94,0x1f,0x39,0x4e,0x93,0xbd,0x36,0x25,0xfb,0x81,0xcd,0x9d,0xa8,0x1c,0x90,0x20,0xb1,0xc5,0x31,0x25,0x7a,0x7b,0x59,0x57,0xbb,0x07,0x92,0x11,},{0x20,0xe8,0x69,0x9d,0x08,0x7c,0xe5,0xe8,0x15,0x1d,0x28,0x05,0x3d,0xce,0x66,0xc2,0x3f,0x28,0x08,0x1f,0x35,0xbd,0x26,0x81,0x9b,0xbe,0x85,0xd3,0x8a,0x09,0xd7,0x02,},{0x2a,0x2f,0xd6,0x05,0x4e,0xf4,0xe7,0x9b,0x72,0x19,0x1a,0x0c,0xcb,0xd2,0xb1,0x8a,0xeb,0xab,0xe8,0xb9,0xa7,0x18,0x61,0xde,0xd9,0x8b,0x7c,0xdc,0xb6,0xa6,0x25,0x53,0x28,0xbc,0x1a,0xec,0xb0,0xc9,0x33,0x57,0x21,0xa9,0xa9,0x6e,0xe4,0xb5,0xb4,0x3f,0x90,0xd3,0x22,0xec,0xf8,0x35,0xf7,0x8b,0x26,0x4d,0xae,0x6e,0x38,0x7b,0xfb,0x04,},"\xf7\x21\xca\x3a\x32\xc1\xe8\x1c\x9c\x6f\x46\xd5\xe1\xfb\x50\xe7\xce\x2f\x4e\x70\x93\x33\xca\x2b\x55\x0d\x52\x13\xb6\x77\x3d\x67\x0c\xa5\x9a\x2b\x50\x86\xa4\x43\x84\x3a\xc5\x08\x13\xb2\x44\xc9\xc9\xfa\xc6\xd1\x19\x69\x89\x27\x81\x35\x12\xc8\x4f\xe3\x0a\x89\x55\x30\x10\x13\x8f\x91\xe8\x17\x6f\x5c\xf2\x57\x89\xd7\x28\x1d\xdb\x83\xa2\x46\x70\x5d\xcc\xb9\x99\xc4\xcd\x0a\xe2\x19\xc6\x45\xf6\xd7\x1d\x45\x1a\xe1\xf8\xd2\xf9\x89\x1a\xf8\xcc\xce\x03\xf4\x38\x55\x9f\xb8\x36\x67\xb8\x07\x7f\xbe\x43\x5a\x74\x4a\xf0\x19\xd6\xd1\x39\x9f\xd2\x13\x7f\x5a\xfb\x8e\xf3\xf4\x7b\xcf\x73\x5e\x7c\x9e\xd8\xa5\x4b\xa0\xc1\xc6\x56\xb6\x65\x0b\xb3\x0a\xdb\x1d\x57\xec\xd2\x07\x46\x39\x49\x42\x31\xa2\xe9\xe2\xf9\x85\xed\x84\x22\xee\x03\xcb\x3f\xd7\x38\xc7\x35\xa1\xb8\x28\x06\x04\x74\x60\xed\x84\xf7\x46\x8c\x3c\x64\xb3\x5d\xb0\x6b\xc5\x8d\xe4\xbb\xa4\x63\xe6\x38\xa9\x41\x33\xdf\x10\x6a\xc4\xf4\x70\x36\x1c\xcd\xe4\x41\x57\x29\x9d\x22\x5b\x17\x79\x88\x91\xba\xf5\x92\x19\x86\xa2\xba\xe3\x26\xdd\xa0\xb8\x96\x17\xc6\x77\xbd\x14\x08\xba\x27\x48\xba\xa6\x7c\x8a\x2c\x5a\x96\x9b\xc0\x0c\xb4\x0d\xbf\x49\x0e\x07\xe2\x2c\x91\x3a\xfd\xde\x63\x04\xa0\x7f\xc9\xe6\x08\x46\x99\x24\x56\xbf\xb0\x66\x3a\x09\xde\xf6\x8d\xef\x67\xa1\x6d\x29\xe9\x8c\x7b\x55\x35\x18\x48\xa8\xcf\x92\x31\x0c\x74\x63\xc4\x75\xf2\x49\xc6\xf7\x55\x7f\xd0\xd7\x55\xca\x88\xf8\x77\x84\x7f\xe0\x76\x57\x56\xac\x34\xa2\x3f\x78\x40\xd9\x5c\x3d\x29\x4e\x66\x3b\xb1\x51\x8b\x75\x92\x7c\x41\x07\x57\xe0\xf5\xc0\x7c\x5a\x7f\xb2\x15\xdc\x72\x07\x43\x3e\xbf\x79\x1e\xdf\xce\xc9\x0e\x93\x0f\x8e\x3b\xa9\xdb\xbb\x98\x54\x13\xc2\x23\xbe\x87\x87\x3b\xd3\x23\x99\x75\x81\x80\x4d\x88\x96\xda\x38\x6a\x6e\x91\x20\x05\x0a\x0e\xae\xd3\x12\x40\xaa\x17\xc7\xb6\x69\x4c\x30\xcb\xcc\x3c\x69\x56\xa6\x82\x0f\xc9\xab\x21\x87\x55\x33\x96\x3d\xc3\xb0\xd8\x83\x58\x27\x12\x76\xc6\x05\x65\x28\x91\x0d\xd9\x89\xae\x0c\x33\x0d\x17\x98\xf7\xd8\xe7\xd1\x18\x4b\x84\xa8\x14\x34\x32\x5b\x8c\x30\x2e\xdf\x60\x1d\xc5\xe6\xf8\x47\xfb\xac\xbd\xee\xff\x78\xc6\x62\x1d\x1d\xaf\xdc\x23\x9b\x18\xb8\xc1\xaf\xdc\xb4\xb9\xda\xbd\x5d\x3a\x92\xa9\x32\xea\x15\x99\x54\x6e\x62\x5f\x96\xd6\xec\x6f\xb1\xcc\xcb\x76\xb4\x76\xb3\x30\xac\x59\x25\x9c\x63\x4f\xac\x9b\x3f\xa7\xde\x7a\xe7\x05\x37\x73\xb5\xbe\xfa\x00\x1b\x04\x92\x9f\x74\xb7\x12\x41\xe1\xb2\x57\x69\x6d\x65\xa2\x6c\x1b\x4a\xc8\x6b\x7b\x1f\xbd\x69\x57\xfb\x9b\x95\x08\x4c\xe7\xd7\x00\x90\xf5\x5d\x44\x53\x46\x94\x30\x5e\x91\x76\x9a\x82\x94\x13\x04"}, +{{0xb5,0x06,0xc0,0x1d,0x69,0x74,0x6e,0xb4,0xbc,0x63,0x58,0x72,0x0e,0x43,0x8a,0xd3,0x30,0xc8,0x8b,0x60,0x5a,0xad,0x65,0x2f,0x47,0x99,0x57,0x3a,0xb0,0xa1,0xaa,0xf9,},{0x7a,0xc8,0xb6,0x88,0x63,0xbd,0x69,0x15,0x15,0x83,0x78,0x9d,0x86,0x4a,0x73,0x57,0xe3,0xa0,0x45,0xfa,0x86,0x52,0x2a,0x9d,0xaa,0x6e,0x26,0xfb,0x79,0xed,0x6d,0x23,},{0x17,0xa1,0x9d,0x26,0x91,0xb7,0xb0,0x46,0xd7,0xb1,0x96,0x69,0xad,0x73,0x14,0x0d,0xb9,0x2f,0x0c,0x97,0x8c,0x7f,0x61,0xbc,0x38,0x67,0xd9,0x2c,0xa9,0xd4,0x75,0x80,0xa0,0x38,0x0b,0x59,0x01,0xba,0xd8,0x2a,0xf4,0x5f,0x67,0x6f,0x74,0x28,0x73,0x01,0x98,0x0f,0x71,0x87,0x1a,0x42,0x26,0x1d,0xbe,0x08,0x02,0x95,0x03,0x36,0xe6,0x0b,},"\xf7\xfc\x18\x06\x6e\xd0\x4b\x30\xe6\x33\xd9\x86\x5d\xa3\x21\x4b\xec\xa6\x0b\xd7\x96\x01\x9c\xd7\xec\xc9\x18\x66\xf9\xef\x24\x46\xc1\xfa\xb0\x6d\x86\x51\xbe\x7f\x10\x1a\xec\x7b\xb8\x4e\xe2\x1e\x71\xad\x02\x02\x15\xfc\xfb\x36\xf2\xd1\x1e\x45\x79\xac\x39\xf8\xe2\xb1\x29\x0e\x38\x96\xd5\x22\xbc\xf5\x13\xaa\xa0\x67\x71\xf8\x6e\xe2\x28\xcf\xf3\xa2\x0a\x1f\x10\xc5\x64\x33\x95\x89\xbb\xa9\x60\x53\x44\xc0\xa6\xe6\x82\xad\x5b\xa4\x0d\x10\x41\x94\x1b\xc4\x6f\x98\xb9\xd0\x9c\xa1\x7f\x8f\x04\x4e\x98\x3b\x8a\x49\x08\x93\x3d\xf2\x26\x3c\xf7\x88\x11\xc2\x4c\x8f\x48\x14\x35\x4f\x6f\x4c\x68\xb7\xee\x7b\x78\x30\x82\x93\xbf\x78\xfd\x0f\xf1\x22\xf0\x95\xc1\x4a\x73\xa5\x97\x97\x17\x2a\xe0\x5c\xfc\xec\x19\x56\x3e\xb1\x8d\x2b\xc5\x30\x0e\xd4\xbf\x6b\xdc\x44\x3e\xa9\xb8\xbc\x1c\xbe\xde\x94\xca\xb9\x05\xed\xa5\xa6\xa9\x31\x59\x7d\xe4\x02\x14\x6f\xac\x9c\xf8\xcd\x6a\x8d\x10\x46\x69\xf9\x13\xfa\x83\x40\x01\xca\x4d\x09\x0f\xb7\x94\x9d\x31\x09\xa6\x3c\x05\x49\xb0\x3f\x15\x1b\x71\x17\xc4\xf4\x69\x74\xba\x59\xc6\x82\x96\xed\xfd\xde\x76\x92\xee\x43\x2a\xce\xf7\x61\x06\x47\xe0\x95\x78\x65\xe6\x2c\x1a\x0c\xf0\x56\x59\x82\x3a\x55\x45\x2d\xd5\xe4\x71\xb3\x1c\x5a\x49\xab\x05\xb5\xaa\xfd\x5a\x0e\x53\x0e\x89\x6b\x58\xcc\x52\x2e\xcf\x19\xe5\x2e\xc8\x2f\xa1\x47\xf9\xe3\x85\x17\x4c\x7e\xc3\x3d\x1d\x9b\x86\x93\x4a\xeb\x4f\x6c\x57\x00\xf7\xd5\xeb\x33\xff\x73\xc9\xfc\x6a\xa4\x7d\xf5\x1e\x09\x22\x9e\x6a\xe8\x94\xe8\x6c\x81\x8b\xef\x06\x5f\x82\x59\x71\xa4\xcb\x90\xad\xfe\xfb\x31\xeb\xd9\xd1\xb7\x94\x22\xdc\x98\x68\xf9\xf7\x4e\x7a\x32\xcd\x40\x71\xef\xb6\x9b\x27\x23\x3e\x6e\x5c\x60\xde\xdc\xd5\x32\x1c\x03\x0a\x46\xcd\x26\xf5\x60\x2c\xac\x74\x7e\xe4\xb5\x22\xd8\x57\xa3\x32\x1a\x03\xf4\x03\xa6\x00\x62\x50\x40\x63\x61\xe4\x88\x15\xaf\xba\x77\xce\x08\x90\x34\x41\x84\x5b\xa8\x72\x25\xd8\xb2\x40\x46\x74\x5d\x40\x65\x64\x5a\x1b\x98\x41\x0c\xac\x48\xd1\x37\xcb\xbb\x8a\xb1\xeb\xa5\x0d\xa9\xc2\x31\xe9\xac\xf3\x22\xa6\xdb\xec\x0e\xf4\x16\xa4\x46\xc3\xb6\x10\xd9\x35\x69\xfd\xf4\x5a\xa6\xcd\xc1\xb6\x40\xd8\xf3\x01\xd7\x86\x93\xb2\x82\x6c\xc6\xed\x46\x85\x68\xad\x9a\x0f\x94\xaa\x9b\x9f\xb9\x2f\x7e\x78\xd4\x84\xfd\xf5\xd8\xd4\x5c\x99\x1e\x28\x07\x4d\xcd\xd6\x80\xd3\xb1\xf1\x89\xef\x6b\xdc\x32\x0e\xe6\xe6\x4d\xd1\xf8\x0d\x92\x64\xd8\x30\x42\xd2\xc4\x3d\x83\x58\x1e\xf0\x39\x4b\x1b\x5d\x1f\x69\xf3\xbb\xbf\x04\xb7\xc8\x08\xba\x34\xc1\x58\x0f\x16\xf7\x65\x37\xb6\xa7\xeb\xd0\xa1\x90\x8b\xe9\x49\x4d\x3f\xca\xa9\x87\x1d\xb1\x57\x50"}, +{{0xe1,0xcc,0xb8,0x0a,0x26,0x2f,0xf8,0xaf,0x1e,0xda,0x07,0x5c,0x97,0x2c,0x8e,0x94,0x1e,0x77,0xce,0xf5,0x7b,0xdb,0x0a,0x82,0x57,0x2c,0x28,0x20,0x0b,0x49,0x3c,0xa3,},{0x3d,0x37,0xe2,0xa5,0x02,0x7e,0xff,0xde,0xe0,0x7f,0xa5,0x11,0xe4,0x23,0xb2,0xbc,0x56,0xed,0xce,0xa0,0x75,0xb4,0x16,0x49,0x76,0x67,0x25,0xc6,0xb3,0x0a,0x10,0xf4,},{0xfd,0xa3,0x4b,0x65,0x2b,0x79,0x74,0x6f,0x89,0x7e,0x22,0x2d,0x37,0xb7,0x7a,0xa2,0x50,0xd0,0x2c,0x52,0x7c,0x48,0x33,0xdf,0x80,0xea,0x41,0xd5,0x21,0x89,0xd5,0x07,0x00,0xe1,0x28,0xb7,0x8e,0xe8,0x14,0x9c,0x9b,0x19,0xf3,0xab,0xf7,0x55,0xac,0xef,0x53,0x48,0xf5,0xfb,0xaf,0x1c,0xeb,0x41,0xc0,0x38,0x90,0x6a,0xc5,0x94,0x60,0x01,},"\xcf\xdc\x54\x97\xb0\x23\xaf\xa6\x2a\x7f\xe5\x92\xca\xa9\x2b\x87\x5c\x77\x05\x74\x78\x34\x00\x2f\x77\x84\xff\x16\x61\x89\x39\x88\x15\xd4\xe8\xa7\xa0\x03\x8e\x1f\xda\xdd\xde\xba\x51\x05\x73\x27\xad\x19\x60\xe8\x59\xce\xe5\x65\x26\xbb\xb4\x12\x7b\x6a\x5f\x90\xd0\x4d\x08\xb1\x5e\xee\x66\xc9\xcc\xf8\x8b\x4b\x7d\x1e\xe9\xd3\xb8\xb8\xc6\xf4\x2d\xb3\xc3\x4e\x59\x04\x8a\x15\xc6\x04\x1f\x14\x2c\x40\x79\x36\x8b\x7b\x11\xe2\x99\x70\x11\x8b\x99\xe5\x67\x0a\xe3\x1f\xcc\xfd\xff\x13\x99\x14\x2e\xe0\x6b\x2e\x3e\x2b\x3c\x97\x07\xdd\x64\x11\x97\x86\xe2\xfa\xb4\x7e\x0b\xad\x2c\xc8\xb5\x58\xd9\x63\xbb\x48\xa4\x9a\xd2\xc6\x37\xdd\x35\xb2\x5d\xb5\x4b\xc5\xa2\x63\x02\x22\xfa\x2a\xce\xce\x9c\xe1\x2a\xb0\x81\x30\x77\xf7\x65\x9f\x50\x74\x42\x9c\xa6\xb4\x94\x33\x10\x32\xae\x79\x2a\x59\x9c\x42\x5e\xe2\x97\x45\x1d\xcf\x5e\xe1\x95\x29\x03\x12\x74\x2e\x64\x7a\x77\x95\xb8\x4d\xcc\x66\x4d\xda\xe2\xa1\xfb\xf8\xc4\x54\x8a\x37\xfd\x82\xd8\x10\xe2\x14\x5f\x01\xdf\x1a\x6d\x3b\xcc\x42\xa9\x1a\x10\x76\x8e\x09\x1f\x3d\x69\x32\x9a\x7b\xad\x6c\x07\x2c\xac\x6d\x89\xaf\xa3\x1c\x02\x90\x56\xd6\xb6\x22\x12\x16\x5c\xeb\xcd\x49\xac\x67\x2e\x38\x30\x26\x7a\xf9\xf2\x8e\xa3\x19\xbd\x04\x2f\x6c\x59\xde\x47\x01\xe5\x82\x48\x73\x6c\x8d\x97\x6a\xcf\x93\xb9\x9d\x2f\x46\x47\xa5\x47\xd3\x92\x44\x7a\x48\xda\xc1\x11\x81\xe1\x6b\x15\x01\xa9\x4c\x93\x16\xe5\xa6\x7c\x99\x0b\x35\x81\x0b\x4c\xda\x04\x73\xa6\xa4\xe5\x76\x14\x21\x58\x68\xe2\xe0\x02\xc6\x05\x8b\x42\xe4\xee\xec\x84\x13\x9d\xc1\x9e\xdf\x5f\x80\xae\xef\xfa\x4f\x5b\x07\xe8\xfd\x23\x13\x9e\xdd\xa3\x18\x99\xeb\xe6\xfe\xe7\x86\x43\xce\x68\x6b\x29\x63\xa3\x20\x72\xbd\x3b\x3b\xba\x68\x48\x5a\x05\xc2\xcc\x04\x56\xc3\xda\x50\xc7\xc8\xc6\x51\xa3\x06\x6d\x13\xa3\x66\x0b\xd4\x7a\xb6\xdf\xec\x49\xe0\x15\x57\xa6\x74\x28\x96\xaa\x4b\xc6\x36\x3a\x79\x7d\xba\xd1\xa4\x09\xcd\x4a\x50\x91\x1e\x70\xea\x00\x7a\xf8\xe9\xb1\xbb\x7e\x3a\xb5\x62\x15\xa5\x75\xc9\x0f\x73\x9c\x2d\x48\xb3\xb3\x46\x94\xb5\xac\xdf\x07\x98\x0a\xe5\x28\xde\x06\x21\xed\xfa\xc8\xb8\xfa\x84\x95\x4d\x56\xdb\xb4\xd0\x30\x82\xb9\x84\xf1\x3e\x5d\xbe\x9c\x71\x12\xff\x97\x16\xf5\x50\x53\x06\x46\x62\xce\x0f\xb8\x1e\xa3\x5f\x98\xfd\x2c\xd5\x11\x37\xa4\x6f\x64\xe0\xc1\xca\xf4\x4e\x54\x07\xdc\x96\x17\x60\xb2\x59\x7f\x7f\x92\x00\x61\x7d\x47\x13\x40\xcf\x15\x17\x6c\x3d\xa8\x80\xfe\x4e\x0e\x93\xa7\x2f\xb9\x49\x26\xfa\xed\x86\x5d\xfd\xc7\x72\xe1\x85\x29\x2c\x1e\x36\xb1\x21\x17\x81\xc3\xe9\x38\xe3\xd4\xf2\x4e\x29\xaf\x51\x7a\x37\x96\x83"}, +{{0x4f,0xc5,0x12,0xef,0xd8,0x6e,0x3a,0x63,0xb3,0x95,0xea,0xff,0x1b,0xa0,0x11,0xe1,0x59,0x0f,0xb9,0x32,0x6a,0xd3,0xff,0xed,0xe7,0x87,0x6d,0xcc,0x3e,0x9f,0xab,0xdc,},{0x26,0xc2,0xa2,0x2f,0x9b,0xfa,0xd9,0x06,0x06,0xdc,0x61,0x3f,0xf1,0x07,0x02,0x1f,0xcd,0xdb,0xec,0x72,0x37,0x06,0x66,0x60,0xb4,0x88,0x96,0x43,0x49,0xe0,0xc8,0x28,},{0x82,0xc8,0x24,0xa7,0xd1,0x13,0x9e,0xc7,0x3a,0xe1,0xd0,0x23,0xad,0xf6,0x28,0x11,0x44,0x1e,0x96,0x82,0x87,0xf1,0xa5,0x80,0xb8,0x59,0xcd,0x66,0xcb,0x33,0xb5,0x8e,0x40,0x9b,0xde,0xb2,0xa8,0x74,0xbf,0x4c,0x23,0x61,0x0b,0xd4,0x4f,0x69,0x31,0x47,0xf2,0xf7,0xc2,0x9d,0x44,0x3a,0x90,0x50,0x84,0xf3,0xea,0xaf,0xd9,0x33,0x0e,0x04,},"\x07\xcd\x1e\x9b\xfa\x38\xa7\xd8\x85\x34\x65\xa9\x3c\x77\xab\x4f\x30\xfa\xf9\x14\xe4\x8b\xc4\x76\x3b\xa0\x7b\xf9\x6b\xa8\x08\xc1\xf5\x9a\xd4\xce\x9b\x7d\x92\x1f\xbb\xc7\x79\x65\x9d\x7c\xa3\x6e\xdb\x7d\xd3\xac\xf7\xa2\x94\x52\xa8\x45\xb4\x9f\xb6\x54\x3a\x3b\x6c\x5c\x1c\x29\x3a\xff\x61\x84\x85\xa1\x0e\xea\x60\xee\x96\x49\xac\x9d\x48\x1e\x69\x49\x96\x7d\x39\x38\xb5\x2f\xe0\x9c\x36\xb9\xad\xe0\x75\x81\xdb\x4e\xb5\x42\xa9\x7f\x5a\xc8\xac\x73\xd3\xee\xa1\x84\x72\x25\x56\x76\x0c\xf4\x83\x09\x05\x64\x55\x30\x61\xb9\x0a\x0b\x6d\x2d\xff\x47\x07\xbe\x76\x39\x37\xa1\x05\x94\xa8\x2b\x76\x6b\xb2\xcf\x6d\xaa\x52\xfa\x8d\x7b\x48\xf3\x21\x27\xc4\x31\xad\x9a\xae\xd3\xbf\xde\xb9\x9a\xd4\x21\x18\xa1\xb4\xde\x7b\x99\x21\x34\xed\x9c\xda\xd0\xb5\x29\x6d\x19\x7a\x48\x5e\x49\x3e\xcf\xec\xa3\x65\x3a\xd2\xce\x0f\x92\x41\xaa\xbc\x09\x6d\x7c\x4b\xa6\x03\xba\x7d\xdd\x07\xa8\xb2\x57\xfe\x52\x32\x76\x41\x70\x73\xa6\x5f\xa4\x43\x42\x56\xfd\x1f\x23\x9e\xc1\xde\x5d\xa1\xa0\xa8\xc5\xe6\x86\xee\x14\xd9\xdf\xa4\x38\xc5\x3b\x99\xc9\x54\xaf\xab\x2f\x79\xe6\x0b\x71\x26\xf2\xcb\x58\xa2\x6e\x29\x0d\xa1\xdc\xcf\xc3\x01\xf2\x39\x74\x8e\xde\x7b\xcf\x1b\xb7\xcc\xb4\x72\x0e\x69\x2f\x57\xe5\x3e\x6f\x59\x07\x53\x99\xe1\x08\x0a\xc8\xaa\x9a\x61\xa5\x68\xc4\xc5\x69\xd3\x6e\x76\xa2\xd7\x27\x1f\x2c\x44\xde\x4e\x36\x3a\x8c\x91\x6a\x4e\x44\x6b\x02\x7b\x64\x39\x2e\x90\xce\xab\xf6\xb6\x07\x1b\xc4\x7a\x13\x79\xb6\xaa\x63\x44\x76\x3b\x2a\x0e\x7f\xf7\xc4\xa2\x7b\xff\x31\x06\x72\x1c\x25\x3e\x4c\x1d\x67\xc3\x7f\xa3\xd7\xc1\xec\xd0\x55\xb8\xe9\x29\xd5\x2a\x8e\x45\xed\x89\xfb\x18\x0f\x74\xb5\x52\xfe\x06\xf0\x66\xc7\xe4\x31\x8c\xa2\xf9\x15\x94\x6e\x83\x20\xd5\x80\x65\x61\x47\x2f\xb8\xff\x7f\xa8\x07\x2d\x8e\x6f\xd1\xce\x63\xcf\x87\x38\x2f\x7b\x94\x04\x54\x0c\x1d\x40\x6c\x70\xb2\x26\x85\x36\x77\x09\x26\x45\xce\x99\x69\x22\xe7\x34\x5d\xc0\x7f\xb7\x33\x9f\x9a\x54\xff\x07\x35\x2d\xd2\xb9\x93\x06\x3c\x2c\x83\xd1\x28\x1a\x4f\xd1\x78\xe5\xa5\xf8\x0a\x5b\x33\xc2\x29\xd0\x57\x83\x67\xd4\x41\x92\xe9\xa4\xd2\x1e\x97\x34\xd3\xbd\xa0\x83\xb7\x0f\x47\x10\x3f\xd1\x25\x17\x70\x21\xdf\x3e\x53\xd7\x99\x86\xef\xea\x2d\xc0\x4f\x02\xc0\xac\x27\x87\x88\x31\x9e\xf3\xa9\x13\x2e\x62\x32\xea\x6d\xb3\x9c\xa5\x87\x08\x55\xf9\x59\x2f\xff\x6c\x20\x9a\xd2\xf1\xc2\x9d\xd1\x68\x55\x28\x98\x97\x9e\xcf\xf8\xc8\x11\x27\x24\x8f\x83\x10\x51\x53\x00\x65\x61\x29\xd9\xb7\xac\xbb\x7e\xd1\xe4\x6b\xc9\x8c\x04\xd1\xa3\x5b\x18\x91\x37\x38\xe9\xdd\xe4\xd2\xb0\x65\xf4\x18\x42\x42\xd8"}, +{{0x0b,0x7d,0xfa,0xd0,0x5b,0xa6,0x65,0x11,0x1e,0x16,0x81,0xbd,0xc0,0xbc,0x8b,0xa9,0x73,0x76,0x7c,0xb8,0x58,0x77,0x02,0x0a,0x2d,0xbf,0x91,0x83,0x25,0x57,0x1d,0x9f,},{0x95,0x05,0xd9,0xe8,0x6d,0xce,0xf5,0x6c,0x9d,0xb7,0x6f,0x28,0x62,0xb9,0x0e,0x1f,0x27,0x73,0x20,0x2f,0x17,0x50,0x40,0x5e,0x7e,0xe5,0xae,0xd0,0xfc,0x54,0xf8,0xb9,},{0x41,0x5a,0xdb,0xb2,0xf2,0xb9,0x84,0x05,0x77,0xfd,0x18,0x41,0xf9,0xaa,0xe2,0x52,0xaf,0xe8,0xf5,0xa7,0x22,0x36,0x01,0x7d,0x50,0xdb,0x22,0xd2,0x28,0xcd,0xee,0x9f,0x5b,0x3e,0x8f,0xe9,0xa1,0x7a,0x4d,0x4e,0x98,0xb7,0x34,0x13,0x81,0xe8,0xd8,0x62,0x5c,0xdc,0xea,0x95,0x6d,0x25,0x3b,0x74,0xe0,0x2d,0xac,0xb8,0x49,0x20,0xa0,0x09,},"\xc4\x3f\xd3\x4b\xb1\x42\x4c\xca\x4e\x4d\xfb\xa7\x5c\x28\xbe\x80\x18\x44\x44\x6c\xa0\x89\x02\x08\x85\xc7\x48\x38\x25\x47\x16\x4a\x9d\x4a\x7f\x95\x70\xd3\xd1\x71\xad\x69\x81\xab\x50\xee\xee\x08\xa4\xa6\xc6\x6d\x76\x99\xd2\x3e\xdb\xe1\xfa\xaf\x44\x66\x0c\x72\xf4\x55\x2d\x87\xd2\x65\xac\xe8\x79\x28\x23\x47\x4b\x90\xa5\xd7\xf7\x40\x1d\xeb\x93\x77\x62\x7f\x60\xb0\x36\xb3\x6e\x04\x4e\xb7\x6b\xf1\x32\xfd\xdf\xcc\x0e\xf5\x70\x4a\x63\x3d\x84\x5e\x96\x2b\x47\x51\x7f\x0b\xaa\x34\xd3\xd6\xe9\xa8\xb9\xf8\x16\x8b\xcd\xc8\x4c\x6d\x2b\x30\xc6\xf3\x43\xe7\x53\x57\xf7\xf2\xc0\x03\x9b\xd2\x54\xb2\x44\xd3\x6c\xd6\x16\x75\x58\x1f\xb8\x34\x57\x0e\xd4\x11\x3a\x78\xe6\x06\xf1\x45\xa1\x11\x99\x2c\x2c\x6b\x61\xc4\x26\x76\x28\xec\x87\xcd\x88\xc3\x6a\x3c\x84\x70\x6e\x44\xae\x96\xa9\x6e\x0c\x84\x80\x31\x85\x46\xd6\xea\x6a\x6d\xf1\x8a\x2b\x4f\x19\xf8\x36\x0c\xfb\xce\x4e\x9d\x1c\xf1\x01\x1f\xfe\xa5\x63\x3a\x66\x61\x9a\xa4\xa6\x5c\xf6\x9b\xe4\x45\x96\x17\x94\x5e\x43\x59\xa9\xd4\x32\x60\xca\x1a\x20\xf4\xed\x7c\x1a\xe5\xff\xff\x3b\xd9\x22\x94\xea\x70\xab\xba\xe0\x38\x5b\x09\x35\xcd\x1c\x0e\xb5\x18\x30\x29\xc5\x85\xa0\x29\x4b\x79\x99\xe3\x2e\xf7\xa2\x90\xfc\xb0\x95\x67\x5d\xc4\xf6\x01\xe8\xf2\xc9\x6f\x35\xb7\x34\x9a\x37\x05\x75\x09\xf4\xec\x70\xc9\xf5\x0f\x60\x11\xf1\xf5\xe6\xb0\x61\xc0\x91\xd1\x1c\x0e\xd5\xde\xc8\xec\xe8\x81\xaa\x34\x05\x08\xf6\x96\xd9\xe9\xcc\x72\x98\xe6\xbc\xcd\x7c\x21\x0e\x2c\xe0\xde\xd8\x35\x92\xa3\xcf\xa1\x3e\x80\x78\xfd\xb3\x25\x8b\x39\xf1\xd1\x1c\xdf\xe0\x96\x70\xc1\xe6\x0a\x39\x10\xa4\xff\xf5\x1c\x6c\x7f\x7d\x66\x24\xf4\xc9\x3d\xf8\x88\x8c\x52\x6f\x48\x4f\x9b\x13\xe0\xa7\xf6\x29\x64\x78\x39\x78\x68\x4e\x29\x26\x79\x80\x0e\xd5\xeb\x28\x0e\x28\x7c\x7e\x63\x9e\x85\xfa\xa5\x3f\xba\x2f\xa2\x04\x5c\xe2\x7d\x8f\xb3\x08\x36\x07\x26\x55\x0d\xf9\x75\x2d\xb3\x05\xf8\xf0\x66\x47\x97\x0d\x01\x46\x91\x99\x9a\xfa\x97\xb6\x19\x3f\xfc\xc6\xd5\x32\xf4\xfa\x69\xe1\x33\xa1\xd1\x0f\x30\x47\xfc\x00\x38\x1f\x49\x97\xbb\x84\xe5\xb6\xcd\x60\x28\xc6\x21\x32\xcf\xc0\x24\xbf\xeb\x98\x03\x01\xf2\x95\x12\xbb\xd1\x09\xd0\x89\xac\xe1\x82\xcf\x9c\x2f\xfa\xb1\xb1\x7e\xb0\x0b\x6e\xb4\x6a\xe1\x98\xda\x99\x3f\x5e\xfe\x7c\x1d\xc2\x2d\x25\x04\x7c\x1e\xe5\x24\x65\x17\xe7\xf5\x75\x8f\x99\x6a\xbd\x83\xf1\x3d\xa2\x2c\x13\xdd\x20\x5e\xe1\x91\xb5\x5a\xfd\x48\x31\xef\x07\x8b\xb6\xea\x07\x3a\x62\x5b\xc9\x7c\x81\x29\x61\x60\xbb\xf2\x55\x9b\x27\x5c\xc3\x7c\xcf\x01\xb9\x1f\xd8\x7d\x4d\x99\xa3\x67\xaa\x99\x78\xda\xdd\x06\x89\xf8\xa6"}, +{{0x78,0x18,0x8d,0xf8,0xc7,0x54,0x78,0x56,0x21,0xe2,0x7a,0xe5,0x8e,0x10,0x0d,0x50,0x80,0xe1,0x6e,0x0a,0x15,0xe2,0x77,0x05,0x1f,0x95,0xf0,0x80,0x90,0x0e,0xc0,0xd3,},{0xa1,0xbd,0xee,0xe9,0x8b,0x07,0x57,0xba,0x9c,0x2d,0x84,0x09,0xb8,0x74,0x24,0xe6,0x4e,0x42,0xf9,0x93,0x2a,0xcf,0xa9,0xbc,0x71,0xfb,0x3f,0x8c,0xa0,0xe1,0x1d,0x52,},{0xb9,0x41,0x14,0xed,0xa4,0x6c,0xcf,0xc2,0x2a,0x44,0x71,0xa6,0x4d,0x79,0x08,0x92,0xe5,0x9c,0x5d,0x50,0x56,0x18,0xeb,0x0e,0x70,0x13,0x92,0xc7,0x09,0x61,0x3e,0x2d,0x50,0x3a,0x5c,0x2b,0x66,0x60,0x1e,0x63,0x6a,0x3c,0x1c,0x7d,0x49,0xb1,0xac,0x79,0x8d,0x90,0x89,0xb0,0xf9,0xcc,0xd0,0x57,0x9b,0xb9,0x06,0x34,0xd0,0xbd,0x75,0x0e,},"\xcf\x70\xcc\xa5\x7f\xeb\x1b\xee\xfe\x98\x5a\xd5\xaf\x9d\x43\x48\xd3\xa4\x6a\x63\xde\x10\x75\x38\x1f\xb3\x63\x9a\x04\x4f\xd6\xe6\x09\x1f\x5d\xb9\xc9\x4d\x39\xbe\x0f\x13\xad\xe6\xd9\xa0\x74\xe6\x7b\xa7\x06\xb3\xa8\x80\x62\x95\xf6\xb6\x54\x86\x57\x28\xc5\x8c\xa6\xe9\x41\x9d\x5d\x04\x3f\x21\x10\x81\x4b\xbf\x36\xfc\x40\x70\xe4\xd9\x45\x49\x65\xc2\x51\x20\x2c\xa3\x95\xef\xe3\xfd\xbd\x54\x4f\xeb\x18\x7e\x34\xca\x3c\x80\x79\x51\x79\x55\x2f\xce\x9a\xa8\x04\x43\x0e\x5b\x6c\x86\x85\x34\x1e\x91\xd5\x88\x9f\xbf\x3f\x98\x19\x04\x62\x0f\xfe\x70\x13\xf5\x3b\x93\x9e\x17\x44\x3d\x61\x4e\x7e\x6b\xb5\x7a\xd6\x74\xf3\xb4\xb0\x01\x63\x05\x26\xcf\x73\x02\xa7\xd0\xaf\xe7\xdc\x24\xd6\xda\xde\xf6\xfe\xba\x3f\x96\x97\x3a\xa5\xb8\xd6\x27\x52\x62\xe4\x30\xa8\x2f\x67\x86\x96\x97\x1a\x8b\x60\xe3\x8d\x3b\x2b\xcc\x17\x0d\x5b\xc2\x03\x02\xa3\x9c\x59\x6d\x27\xfe\xe3\x9e\x5d\xa5\xb1\x0e\xa9\xf3\x82\x29\x9e\x19\x81\x97\x17\xa7\x18\xd3\x7d\x15\x5f\x13\x92\x31\x82\xb5\xb7\xa1\xc5\x4c\xa1\x09\xb2\x2c\xa8\xe8\xb2\x6c\xa5\xca\x3f\x3b\x90\x62\x21\x94\x61\xba\xce\x97\xe8\x90\xc9\x4e\x41\xca\x3d\x84\x58\x7f\xbd\xf6\xe2\x40\xc3\x5c\xca\xb7\x1d\x58\x47\x7d\x28\x16\x8e\x93\x37\x26\x86\xd4\x2a\xad\x32\x4a\x3f\x16\xaf\xe0\xe9\xb8\x9e\xe2\x0e\x48\x5f\xe6\xc8\x64\xb5\x01\x3b\xa8\x83\x99\xee\xaa\x15\x98\x35\xa8\xb2\xbb\x2f\x25\xf5\x79\xca\x3b\xae\x67\x5c\x63\xda\x1b\x50\xd9\x9d\x4e\xd9\x78\x69\x2e\x56\x00\x23\x3f\x38\xab\x7e\x7a\x5a\xe0\xfb\xf8\xc0\xb6\x9c\xc3\x8b\xd3\x0e\xab\xd9\x77\xef\xa0\x5e\xe2\xc8\x35\x14\x30\x2b\xd4\x0c\x4b\xdc\xe7\xa4\x11\x0a\xfb\xb6\x57\x9c\x62\x0e\x97\xf8\xcf\x2e\x9b\xab\x2d\xcc\x7c\x33\xf1\x96\xe5\x7f\xe7\x61\xa0\x50\x12\x28\x94\xb7\xa7\x5a\x92\x95\x31\x99\x6d\xda\xad\x78\xde\x1d\x4d\x92\x4c\xd9\x3a\x61\xdf\x22\x77\x76\xbc\x1c\x39\xfb\xb8\xde\x1c\x44\x38\x86\x8b\x6a\x3a\x2c\xd9\x4c\x07\xb2\x9e\x3f\x6b\x23\xcc\x7e\x0b\x63\x68\x90\x09\xd9\xd0\xba\xe1\x60\x6b\xaf\xc7\xa8\x08\xf2\xd2\xfa\x25\x62\xb8\xdc\x09\x38\x42\xc0\x1f\xdb\x84\x0d\xa4\x86\x0a\xce\xd3\xfc\x52\x5c\xa3\x34\xed\xcf\x65\x94\x8b\xc4\x16\xf9\x8c\x45\x0f\x00\x12\xa6\x10\x7d\xd7\xf8\xed\xe4\x0e\x1c\x48\xc9\xe8\xa5\x65\xa8\x10\xb9\xcf\xd2\x03\x56\xdb\x19\xf1\xdb\xde\x59\x89\x21\x33\x2e\x0d\x81\x3f\x0c\xb8\x76\x84\x37\x03\x88\x77\x2f\xf3\xcb\xfc\xbf\xa2\x99\xc1\x98\xc9\x7b\xfb\x96\x17\x76\x8a\x05\x16\x1f\x41\x69\xff\x5d\xe5\xd9\xf4\x00\x62\x09\x0f\xb8\x82\x98\x4d\x9d\x5c\x7a\xa7\x8e\xdd\xcb\x96\x34\xe4\x66\xb8\x85\x3d\x51\x2b\x4a\x54\x6d\x74\x23"}, +{{0x73,0xcb,0x02,0xb0,0xbf,0x26,0xa0,0x15,0xda,0x1d,0xc3,0x01,0xfc,0x12,0x5d,0x7e,0x6c,0x30,0xb6,0x3c,0x9e,0x6e,0xee,0x9e,0x06,0x5d,0x4e,0x84,0x71,0x32,0xc3,0x25,},{0xac,0x9e,0x3d,0xd2,0xce,0xb9,0xb2,0x3e,0x74,0x8c,0x04,0xba,0x75,0x77,0xfe,0xdf,0x7c,0xea,0xb9,0xed,0x87,0xdc,0x43,0x0b,0x5f,0xe2,0x2e,0xac,0x50,0x95,0x0e,0x0d,},{0x1a,0x5d,0xd4,0xc8,0x91,0xc8,0xe1,0x32,0x57,0x01,0x87,0xc2,0x3b,0x9a,0x1e,0x4b,0x26,0xf0,0x54,0x60,0xe8,0x75,0x67,0x38,0x19,0x39,0x6d,0xf5,0x61,0xc8,0xaf,0x0e,0x48,0x33,0x3b,0x62,0xc7,0x77,0x29,0xd4,0x9f,0xc4,0x0e,0x17,0x4a,0x7f,0x3c,0x21,0xf8,0x5e,0xf4,0xd3,0x39,0xce,0xb8,0x0b,0xd2,0xe0,0x37,0xd8,0x03,0xaf,0x56,0x0e,},"\x0a\x2b\x61\xba\x35\xe9\x6e\x58\x19\xb8\x8b\xfd\xb2\x8b\x7c\xe0\x2e\x64\xae\x9c\xf5\x72\xb2\x1f\x13\x55\x2c\x0d\xb1\x0f\x39\x60\xd4\x4b\xa3\x47\x2f\x43\xab\xc4\xe6\x29\x5b\xdf\x79\x0b\xd9\x33\xba\x39\x75\xfd\x44\x65\xfa\x3e\x2f\xe2\xdb\x02\xb6\x37\x77\x52\x22\x3d\xec\x98\xfc\xb2\x40\x4f\x3a\xba\x43\x26\x5a\x6f\xa7\x97\x6b\x6c\x6c\xb6\x86\x8b\x88\x1b\xd6\xf3\xd2\x5c\xd9\xd6\xf7\x0e\x51\x2f\x80\x89\xc8\xef\x26\xfd\x58\x24\x50\x53\x77\x9e\x59\xc4\x72\x5a\xef\xa2\x64\x67\xc9\xf5\x00\xe1\x7f\x3e\x15\x73\xf1\xa8\x55\xe9\xb8\xb2\x19\x25\xea\x05\x27\xf3\xce\x8d\x88\xfb\x54\xa4\x7a\xbe\xed\x14\xf3\x99\xcc\x2d\x9f\x1f\xe5\x46\x65\xfa\xe0\xa8\xf0\xc6\x88\x72\xa6\x00\x04\x6d\x1d\xc3\x63\x97\xd3\x10\xce\x39\x3f\xce\xaf\xe8\x7c\x17\xeb\xe1\x22\xfd\xb5\x43\xae\xa7\x10\x85\xba\xec\x98\x27\x3f\x41\xac\x96\x69\x8c\x15\x0c\xf9\x11\xd0\xe5\xde\x23\x92\xd8\x48\x41\xd0\x12\x76\xae\xfb\xfe\x99\x95\xe1\x0a\x6d\x46\xef\xdc\x26\x78\xd4\x56\xc9\xf3\x6b\x2e\x10\x11\x4d\x11\x87\xe7\xac\xa7\x39\x03\x7e\xa5\x1f\x85\xfd\x62\xa2\x94\x29\xba\x52\x9c\xdd\x8a\xd9\x13\x47\x49\x74\x87\xed\x7e\x87\x09\xd4\x77\x6e\xf6\x86\x70\x79\x2d\x06\x15\xbc\x96\xda\x51\x78\xd6\x06\xdb\x63\xe4\xe5\xcb\x17\x2a\xcf\xbc\x1c\xbe\x20\x26\x93\x50\xf1\xb6\x05\xf3\x5d\xcd\x47\x91\x35\xbd\x30\xfb\x4b\x5a\x39\x17\x6c\xff\x74\x4d\xdb\xb3\x06\xc9\xe7\xb4\x16\x7d\xe0\x37\x9a\x61\x66\xbe\x5a\xaa\x74\xd7\x15\x7f\xac\x95\x7d\x88\xdc\x57\x59\x7c\xfe\xf2\x3e\xb5\x10\x8b\x3c\xe5\x3f\xc6\x32\xda\xd1\xb9\x72\xa2\x9d\xa5\xde\x32\xd2\x0d\x8e\xce\xde\x67\xff\x00\xda\x4a\x08\xa0\xcc\x1a\x98\xbe\xe7\xa9\x4e\x3c\xb3\x2f\xee\x94\xae\x25\xa4\x13\x54\x47\x02\xc3\x7b\x3e\x17\x78\xa0\x70\xcd\xd4\x84\x0b\xd3\x9f\x5f\x45\x79\x51\x92\xa8\x67\x86\x38\x76\xed\x0d\x13\x0d\x46\xe2\x91\x39\x35\x08\x28\x09\xf7\xe1\x5a\x49\x67\x10\xf2\x55\xd7\x83\xda\x3d\x01\x6a\x65\x4c\x15\xff\x5d\xf9\x07\xa3\xcc\xaf\x37\xcf\xe1\x1c\x8c\x3d\x49\x65\x07\xd6\x76\x0c\x05\x38\x20\xf0\xf5\x94\xc3\xd0\x1c\xa2\x69\x17\x8a\xca\x52\x5a\xb2\x82\x1e\xf5\x5f\x92\xd8\x5f\xe6\x85\xea\x34\x47\x2e\xd1\x39\x81\x71\x06\x4d\x74\xa4\x22\xec\x91\xd1\xa6\x70\x61\x8f\xc9\xf3\x24\x24\xbc\xb1\x1a\x77\xf6\xfb\x4e\x2f\xef\xd2\xc4\xe8\xa7\x3c\x45\x28\x86\xe9\x31\x66\x4d\x1a\x83\xbd\x92\x73\x29\xc0\x4d\x25\x0b\x83\x52\x1d\x7d\xc1\x3c\x91\xce\xe1\xec\x05\x0e\x11\xd4\x2a\x4b\x0c\x8c\x06\x9b\x61\xc4\x42\x2d\x3a\x49\xc0\x7e\xff\x29\x05\xb7\xbc\x7f\x4a\x5b\x43\xe6\xb0\xd6\x1d\xfb\x50\xe4\xee\xa2\xe9\x0d\x29\x8a\x78\x1d\x05"}, +{{0xdb,0x05,0x60,0x63,0x56,0xba,0xcf,0x23,0xaf,0xf6,0xcd,0xdd,0x42,0xb2,0xc6,0x94,0x35,0x2b,0x5a,0x0f,0xec,0x56,0x0a,0xff,0x54,0xd9,0xbd,0x97,0x10,0xef,0xe0,0x6a,},{0x32,0xa5,0xc7,0xcc,0x49,0x09,0x78,0x6b,0x48,0xa5,0x3f,0x31,0x09,0x3f,0x54,0x9a,0x9f,0x17,0x30,0xca,0x66,0x90,0x38,0x3f,0xdb,0x5f,0x14,0xc2,0x66,0x6e,0x31,0x32,},{0x53,0x09,0x9b,0x76,0x6a,0xdf,0x29,0x44,0xb6,0x82,0x13,0x74,0x84,0x2c,0x25,0xd6,0xe6,0x7b,0x0c,0xcd,0xe9,0xc6,0x37,0xfe,0xcb,0x11,0xb8,0xb8,0xb0,0x72,0x03,0xe3,0x07,0x57,0x32,0x80,0x5f,0x4f,0x14,0xae,0xae,0x73,0xbd,0x62,0xe3,0x08,0xb5,0x88,0x7d,0x68,0x9e,0x29,0xcd,0x89,0xb2,0x3a,0x47,0x69,0x43,0x11,0x07,0x17,0xb1,0x00,},"\x1b\xc9\xc2\x83\x3f\x37\xcd\xf1\x35\x6f\xad\x16\x67\x68\x64\x27\x17\x70\x1b\x38\xa0\xab\x0c\x2f\x58\x1a\x26\xd2\x22\xd6\x5c\xce\xe4\xbf\x0f\x6d\xfe\x64\xd3\x3b\xc0\x23\x9f\x71\xd4\xb8\x26\x44\xb0\x16\x25\xa1\xa3\x5f\xe7\x98\x67\x62\x39\xe0\xca\x77\x9e\xf2\x31\x38\xee\xbe\x3b\xd1\x9d\xe2\xd8\xf7\xc1\x5b\x4d\x96\xf1\x3e\x51\xbc\x63\x3b\xea\x5d\x61\x22\x5b\xca\x1d\x63\x39\xba\x53\xe8\x1f\x7d\x8d\x24\xc5\xd6\x0f\x04\xce\x8c\x72\x67\x61\xd2\x64\x58\x4f\x1c\x7e\x5b\x5b\x69\x92\x45\x6c\x1c\x76\x89\x2d\x63\x52\x11\x1e\x3b\x92\x6f\xe0\x25\xc0\x00\x9d\xb6\x7c\xe0\xdd\xc7\xf7\x64\xe0\xc9\xad\xb0\x48\x1b\xc2\x79\x54\x84\xd9\x63\x73\xa9\x62\xa7\xb7\x4a\x55\x96\xf5\x27\xa7\x34\x76\x49\x8c\x78\x23\xdf\xfa\x6c\x85\x43\xb0\x79\x71\xb5\xaa\x27\x1c\x12\x25\x5e\x09\x18\xdd\x73\xf5\x0c\x30\xc9\xa8\x5a\xc7\xc2\x99\x3d\xd6\x55\xda\x59\x43\x12\x63\xf5\x91\x4b\xe7\x06\x37\x4b\xe9\xc0\x75\x85\xc2\x87\x13\x28\xb4\xdb\xc3\x94\x01\xc9\x57\x07\x38\x7e\x6e\x06\x9d\x44\xb9\xd8\xfb\x05\x8f\x22\xe3\x15\xaa\x0d\x5b\x4f\x11\x68\xfc\x10\x79\x62\xb0\x64\xf7\xd8\x45\xaf\x8e\x21\x31\x95\x1d\x1c\xd6\x6d\xc8\x4d\xba\x46\xd2\x00\xaf\x4f\x4c\x5f\x51\x22\x1b\xc9\xb2\x19\x69\x42\xf8\xb4\x0e\x7d\xdb\xc9\xae\xb3\xd9\xaf\xc0\x71\x25\x95\x13\x13\x5a\x01\x6f\x28\x66\x09\x9f\xa1\x0f\x4c\x3b\x73\x50\x0b\xd5\x5c\x47\x7b\x24\x15\xe1\x0a\x27\x9b\xa1\x10\xd2\x94\xf3\xdd\x18\x42\x17\x7d\x0b\x4b\xfb\x17\x34\xdd\x0c\xcb\x7e\x39\x4b\x43\xd1\x6f\x0b\x75\x48\x36\x22\x80\xf4\x34\x76\x4d\xa5\x7f\x19\xed\x3e\x30\x2e\x53\x70\xfb\xa4\x96\x64\xc2\x30\x05\x74\x33\xcc\x64\x7e\xb2\x7c\xd2\xc7\xc1\x8c\x7d\x66\x90\x6f\x08\x82\x46\xc2\x2f\x7f\x79\x03\x99\xde\xb4\xc5\xfb\xb9\x06\x18\x17\x69\xbe\xf5\xaf\xbe\x8a\xd1\xf5\xde\x55\xbe\x58\x8f\x52\xf6\x9c\x54\xd4\xef\x5a\x96\x9a\x0d\x99\x5c\x27\x40\x7b\x23\xed\xd9\x24\x3d\x24\x99\xfd\xf2\x94\x73\xb1\x95\x5c\x84\xb3\xf7\xcb\xdc\xd8\x1b\x76\x56\xec\x0b\xe9\xe0\xfd\xb3\x38\x13\x56\x96\x0f\xd0\xca\x70\xe7\xea\x74\xb6\x46\xfc\xd3\x13\x94\x8e\x6d\xdb\x47\x60\x94\x76\xfb\x6f\xa4\x84\x2f\xa7\x88\xa0\xd5\x7b\xe3\xb0\xa6\xca\x18\x19\xf7\x16\x14\x76\x00\x43\xec\x49\x04\x88\x19\x39\x96\x8a\x43\xb5\xd1\x92\x8f\x84\xa5\x91\x90\x93\xbc\x38\x41\x58\x81\x71\xa9\xcd\x39\x0f\x8f\xcd\x61\x53\x8b\x54\xe6\xef\x99\x77\x05\x73\xe1\x98\x6d\x15\x0f\xa9\x6b\x7a\x07\xe1\xd1\x94\xaf\x1c\x0b\x40\x55\x00\xac\xb3\xd1\x0e\x3b\xe6\x47\xc8\x98\x62\x00\x6f\xa7\x85\x83\xe7\x61\x66\x84\x29\x20\x16\x0e\xb5\x7f\x0b\x2a\x6e\xdf\x19\x3c\x44\xc5\xee\xac\xf4"}, +{{0x1d,0x13,0x9b,0x1a,0xd0,0xc3,0xaf,0x1d,0x5b,0x8b,0xe3,0x1a,0x4e,0xcb,0x87,0x8e,0xc6,0x67,0x73,0x6f,0x7d,0x4f,0xa8,0x36,0x3a,0x98,0x09,0xb6,0xd1,0xda,0xbf,0xe3,},{0x24,0x28,0xcf,0x1d,0xeb,0x20,0xfb,0xad,0x1f,0xdc,0x66,0x5d,0x82,0x5b,0x61,0x41,0x22,0xdf,0x10,0x1f,0xbe,0x14,0x73,0xa7,0x99,0x96,0xba,0xf6,0x96,0x74,0x34,0xb8,},{0xdd,0x64,0x5e,0x51,0xed,0xab,0x04,0xdb,0x31,0xe3,0x31,0x72,0xcf,0x27,0xac,0xee,0xed,0xcc,0x04,0x63,0xa9,0x63,0x91,0x4a,0x0e,0xac,0x8e,0xfd,0x5a,0x34,0x34,0x1f,0x6b,0xbc,0x52,0xe0,0x42,0xba,0xaf,0x3b,0x40,0xc8,0x9a,0x57,0xef,0xb6,0x45,0x74,0xe6,0x96,0x77,0xfc,0xe9,0x55,0x24,0x6c,0x1f,0xc0,0xf2,0x69,0xef,0x81,0x90,0x00,},"\x8d\xf2\xd2\xdf\x9b\x98\x4d\xa8\x44\x33\x48\x6a\x81\x3c\x98\xc5\x97\x3a\x69\x6c\x11\x62\x46\x10\xb2\x3a\xa4\x38\x08\x34\x64\xf6\x5a\x76\x79\x66\x15\xb7\x28\xc2\xed\x4e\x60\x71\x58\x55\xaf\xc2\x39\x45\x0d\x5b\xc0\x91\x1f\xf2\xa8\x52\x30\x20\x5c\x6f\x13\x49\xba\x5b\xd8\x7e\xa6\xf7\x20\xdb\x6b\xa7\x0b\x77\x42\x17\x88\xe0\xc6\x54\xae\xbc\x23\x07\x4c\x5f\x41\xd2\x29\x07\x72\x14\x0d\x98\x1a\x6b\xc4\xfe\x70\x9a\x26\x8e\x64\x17\x2a\x02\x6b\x27\x01\x18\xb4\xdb\x51\xab\x6a\x13\xc9\x9b\x06\x31\x86\xd8\xd5\xb3\x38\xe9\x77\xed\xdc\x6b\xb5\xfd\x7d\xd5\x7d\x98\x45\xa3\xc3\xfe\x76\x17\x7d\x57\x38\xdc\xa1\x6a\x8f\x91\x02\x85\x75\x00\x17\x4f\x23\xff\x4c\x3b\xf3\xc8\x53\x6f\x11\x58\x0e\xf8\x51\x4a\x40\x9f\x5b\xbc\x9c\x02\x96\xf1\x2e\x34\x78\xd4\x08\x7f\x95\xef\xaa\x6c\x63\x60\x71\xd2\x11\x57\xbf\x11\x77\x4b\xbf\xe7\x69\x33\x06\xca\x72\x13\xda\x47\x13\xeb\xaa\xab\x35\x54\xed\xf0\x80\x11\xa5\xff\x73\xda\x12\x03\x75\xae\xd1\x96\x28\x67\x0f\x28\xab\x24\xb6\xf5\xd5\xa1\xd5\x70\x48\x0f\x65\xd3\xc1\x52\xbf\xf1\xb4\x7b\xf0\x66\x69\x29\xcb\x7c\x99\xd9\x03\x3f\xaa\xe8\x53\x4f\xc3\x5d\xa7\x30\xb8\x11\xeb\xcc\x25\xae\x10\xa1\x95\xaa\xb1\x2c\x32\x6a\xa4\x5b\xf8\x05\xc6\x2d\xd4\xcd\x5f\x86\x86\x23\xc0\x4a\x8e\x1c\x6a\xa7\x2f\x1e\xa4\x40\x0c\x60\x86\x7d\xff\x62\x2f\x31\x64\x34\xf1\xec\x89\x50\x3c\x6f\x9f\x65\xc1\x37\xb4\x94\x4c\xbc\xb3\x5f\x08\x6c\x74\xcc\xea\xfa\x22\x42\xac\xca\x6f\xfe\x61\x1c\x4b\x55\x87\xf5\xb7\x5f\xfa\xd3\x49\xf0\x0b\xf9\x6e\x4a\x58\x0a\x87\x5b\x92\x65\x40\x69\xb6\x2e\xea\xc0\xbf\x78\xe5\xae\xdd\x71\x86\x9e\xe0\x5b\x9a\x94\xe1\xc9\x8e\x35\xa9\x78\x00\xa4\xa2\x12\x20\xb0\x39\xcd\x5e\xbb\xb7\x56\xd4\x0b\x40\x42\xe2\xc8\x4a\x2a\xe9\x81\x82\x51\x1d\xae\x8e\xd3\xb8\x9f\x4f\xa0\x0f\xb8\xed\x94\x63\x16\x45\x97\x10\x05\x2a\xd4\xc0\x2f\x63\xdf\x05\xd3\xbb\x1a\xce\x33\x67\x21\x51\xbd\xf5\xda\xb4\x6c\x7b\x58\x3d\xb3\x73\x89\x9d\x4f\x03\x5b\x6c\x11\x12\x58\xb4\xe5\xa9\xe7\x07\xa1\x1d\x21\x5e\x44\xe6\x8e\xf1\xa6\xf0\x53\x80\x9a\xa5\x1b\xd9\x02\xe1\x3c\xa9\x9c\x1b\x1c\xec\xc8\x3b\x9c\x23\x5c\x71\x0e\x79\x7d\x2b\x1a\x24\x9b\x2e\xa0\x79\xb5\xc1\x67\x4e\xd7\x16\x9f\x1b\x6e\x67\xf1\xac\x77\xf8\x6b\x74\x32\x98\x96\x93\x35\xa7\x72\x44\x0f\x7f\xbf\xa7\x25\x13\x50\x0d\x84\x16\x61\x14\xa8\xfd\x54\x13\x94\x64\xd4\x2b\x99\x55\x30\xd3\x23\x70\xb6\x9b\xff\xc7\x58\x9d\x6d\xcc\x97\xe0\xbf\x17\x85\x6c\xc3\xbf\x41\x64\xdb\xec\xcc\x8a\x88\x1d\x41\x4d\x6a\x62\x02\x92\x76\xc5\xf8\x13\x7c\x0b\x3c\x68\xbc\x8f\x4b\xd4\xe7\xcf\xf6\x5e\xf2"}, +{{0x4d,0x22,0xe3,0x31,0xe0,0xcf,0x6f,0x6a,0x27,0x2d,0xb4,0xd2,0x06,0x87,0xff,0xb0,0x59,0xf1,0x22,0x5d,0x81,0xe4,0x11,0x23,0xb8,0xc8,0x9b,0x07,0x4d,0xe7,0x6a,0x3b,},{0xb1,0xe4,0xcf,0xae,0xad,0xd6,0x7b,0x12,0xd7,0xb9,0xdb,0xfc,0x0f,0x88,0xed,0xd0,0x37,0x3f,0x9a,0x88,0xc7,0xfa,0x33,0xfb,0x7f,0x2b,0x1e,0x47,0x5e,0xcc,0xb6,0x1b,},{0xc3,0x66,0xb8,0x02,0xf6,0x82,0xfc,0xd7,0x05,0x25,0x26,0x4f,0xb1,0xa3,0xcb,0xcd,0x0e,0xe3,0x5e,0xcf,0xf5,0x97,0x7c,0x2a,0x55,0x4d,0xa9,0x39,0x22,0x9f,0x17,0x81,0x9a,0x96,0x1e,0xa7,0x4c,0x3d,0x7a,0x78,0x81,0xac,0x5c,0x1f,0xa1,0x6b,0xf9,0x84,0xd9,0x45,0x6a,0x13,0x88,0xd3,0x46,0x3c,0x44,0x94,0x42,0x9b,0x1d,0xc4,0x54,0x02,},"\x9c\x8e\x3f\x5b\x4d\x70\x40\x30\xe1\xba\x71\xf0\x2e\xfc\x4b\x87\xd6\xff\xfb\x55\xbc\x3d\x8d\x03\x81\x8f\x91\x56\x24\xfc\xf7\x01\xc5\x4a\xdf\xaf\xa2\xb6\x94\xb8\x77\x51\xcb\x9f\x69\x91\x8c\x0f\x05\x0f\x4c\x10\x5d\x5c\xcb\x40\x10\x0b\x28\xdf\xd4\xf4\x11\xd5\x91\xc1\x20\x19\x17\x6a\xc2\x01\x6b\xfb\xfd\xf0\xdd\xf1\x1d\xb8\xa7\xe3\x9a\xa7\xb9\xe2\x16\xf6\x67\xc0\xa1\x5f\xb9\x77\xea\xa9\xba\x3b\xc4\x55\xcc\x58\x94\x5f\x3e\x94\x4b\x8a\xc2\xfb\xf4\xd2\x4f\xe7\xe1\xe6\x19\xcd\xbe\xee\x3e\x5e\x12\xa9\xa5\x27\xd2\x8f\x5f\xd7\xcf\xd9\x22\x0f\x13\x08\xd8\x97\xb6\xd4\x31\x4a\x5a\x01\x87\x86\x4a\x2d\x62\x1c\xf1\xb2\x84\x42\x61\x24\x7b\xf5\x20\xba\xfa\x9b\xf2\x26\xe1\x15\x68\x1e\xcd\x77\x42\x79\x80\xcd\x12\xb0\x8c\x35\x9c\xec\xd1\xde\x3f\x55\x45\xf8\x07\xf8\x1e\xd7\x63\x02\xff\xd6\x47\x7f\x89\xb9\x58\xcd\xf1\x29\x54\xcf\x70\xc1\x42\x53\x29\x93\x83\x16\x47\xea\xca\xb0\xb4\x80\x7b\xfd\xad\xb4\x38\x9d\x7d\xff\x2c\x4e\xf0\xef\x5a\x5c\x61\xd0\xdf\x76\x2e\x2e\x90\x80\xa7\x18\x1c\xec\xd0\x6a\x53\x19\x9f\x0d\xfe\xf7\x02\x62\x7a\xde\xcf\x5f\xcd\x9b\x3e\x68\xc7\x23\x33\x16\x17\x27\xf8\x71\xc7\xd1\xc4\x30\x51\xff\x1c\x92\x1f\xd5\x3b\x64\x22\x38\xb9\x78\x80\xd6\x4e\x25\xfa\xc5\x12\xab\x95\x4b\xed\xbc\xa5\x40\xf5\xb2\x00\x91\xec\x72\xe6\x7f\x88\x77\x0a\xfc\x32\xf2\x12\x5c\xa0\xda\x4f\xe8\x7b\x56\xaa\xc9\x17\x7f\x1f\x4f\x67\xc8\x51\x72\x5c\x5e\x8a\xfe\x64\xf6\x64\x79\x98\x33\xfd\x79\x10\x0b\x77\xea\xd2\x58\x38\x87\x9f\xff\x47\x47\xaa\x0d\x56\x72\xec\x0a\x94\x34\x81\x34\xbd\xbd\x4b\xb3\x9b\x0c\x67\xa0\xcd\x30\x60\x2e\xdf\x4f\xec\x6f\x7a\xf0\xcc\x2b\xda\xe1\x26\xce\xa8\x42\xdf\xaa\x43\x91\xdc\x5d\xde\xa9\x38\xe1\x79\x21\x68\x24\x0c\x2d\x8b\x25\x35\x2f\x9f\x3a\x64\x42\x35\xce\x36\xfe\xfe\xb6\x99\x2a\xd8\x8e\x28\x7a\xd2\xd8\x5b\xd8\x50\x39\x6f\xc2\xe5\x17\xa1\x52\x09\xf5\x92\x0a\xc9\x8c\x53\x2b\x1f\x4d\x86\x9b\xeb\x08\xbb\x03\xcf\x7c\x91\xaf\x3f\xfc\xed\x68\xd5\xfb\xfe\xf8\x6f\xf9\x4e\xce\x6e\x2e\xad\x34\x84\xce\x08\x0d\xb1\x7b\xbe\x40\xf1\xdb\x43\x2e\xc1\x65\x0e\xd2\x4f\xdd\x25\x0f\x33\x45\x74\x5c\x9b\x7b\x91\x98\xc9\x10\x9a\x37\x26\x1f\xc5\xec\xbb\xb1\x2f\x83\xa0\xe1\x22\x0a\x18\x67\xd4\x5f\xdd\xfe\xa8\x1d\xcf\x75\xf4\xec\x7f\xdb\x52\x50\xe5\x77\x54\xd6\xde\xa2\x70\xb6\x28\xa7\x95\x30\xec\x28\xb6\x19\xbc\xa9\x49\x3e\x63\x05\xcf\xc4\x41\x4c\x1c\x1d\xe3\x38\x9e\x89\x01\x97\xc8\x5f\x28\x40\x4f\x3f\xa9\x6a\x1e\x2f\xd9\x20\x6b\x47\x2e\x8a\x0a\x0d\x32\xaf\x55\x60\x6b\xb0\x83\xf7\x6a\x19\xb8\xea\xe3\x47\x9a\xe5\x1d\x98\xa9\x9a\x62"}, +{{0xa5,0x22,0x8f,0xf9,0xbb,0xb6,0xf2,0x32,0x32,0x7e,0xb8,0xd8,0x79,0xd7,0xf8,0xb2,0x77,0xca,0x72,0xba,0xe1,0xf9,0xa9,0xd0,0xe2,0x60,0xdd,0x90,0x57,0x1d,0xb4,0xf9,},{0xd8,0x2f,0x6a,0x69,0x74,0xf5,0x1c,0x88,0x08,0xd9,0xd6,0x17,0xf4,0xce,0xc2,0xd8,0xa3,0x7e,0xb1,0x1a,0x14,0x23,0x7c,0x9a,0xb9,0xcf,0x11,0xeb,0xc8,0x0f,0xf6,0xc0,},{0x97,0x65,0x0f,0xae,0x3f,0x59,0xca,0x76,0x47,0x7f,0x25,0x47,0x16,0x77,0x49,0xc5,0x83,0x02,0x48,0x88,0x32,0x25,0xe3,0x54,0xff,0x46,0xc7,0xe3,0x81,0x96,0x52,0x20,0xd9,0xbe,0xf2,0xc2,0x05,0x7c,0x7d,0x19,0x90,0xf0,0x8b,0xca,0x4c,0xfd,0xe8,0x77,0xff,0xf2,0xb4,0xaa,0x81,0x3d,0x9c,0x4b,0x84,0xfb,0x79,0xec,0xed,0x81,0xef,0x05,},"\x1d\xf7\xa6\x83\x5e\x33\x10\x98\x3e\xe7\xec\x73\x11\x25\xf5\xb5\xcf\x11\x7a\xf0\xe3\x6b\x36\x85\xbf\x54\xac\xe1\xc4\x8c\x46\x30\x05\x60\xa4\x5e\x9f\x9b\xdd\x96\xa0\xbc\x4d\x14\xe8\x9d\x4b\x57\x21\xa2\xca\xff\x66\x18\xb1\x82\xed\xb1\x20\x2f\x3d\x0c\x5d\x11\x8d\x09\xb6\x18\x12\xc0\x10\xe8\xb1\x96\x34\x45\x41\xcd\xee\xfe\x5f\xd1\xf9\x61\xc5\xdd\x75\x45\x95\x55\xab\x72\xef\x2a\xa7\xa7\x59\xa4\xf3\xad\x3c\xae\xd4\x4f\x4c\x9a\x8e\xf9\x5b\x76\xed\x9a\x99\xb5\x5d\xd8\xa2\x60\xba\x08\x01\x0d\x29\xff\x81\x9f\x2a\xf3\x51\x3c\x1a\x64\x0d\x6c\xcd\xde\x49\x99\x20\x5f\x9f\xca\x88\x57\x11\x5d\x8b\x5d\xb9\xf7\x0a\x62\xe5\xee\xa0\xd5\xaf\x06\x5d\xe1\x53\xf2\xed\xed\xee\xc6\x3e\x15\xc8\xe0\x9a\x92\x58\x21\x82\xac\x07\xd8\x1c\xa6\x3c\xa4\xaa\x59\x7a\x22\x20\xe7\x04\x81\x95\x7d\x41\x52\x64\xe2\x58\xbc\x26\x3e\x1c\xc3\x6e\x53\x47\x8a\xac\x5c\xa0\x16\x94\xcc\xb0\x9b\x4f\xfd\x84\x73\x99\x72\xc7\xdc\xcf\x3d\xef\xea\xfd\xed\xe1\x62\xab\x6c\x58\xa1\xdf\x27\x37\x1e\x3f\x54\x93\x06\x7f\xc9\xe2\x06\x7e\x57\x96\x23\xc0\x09\xfc\x82\x5e\xef\x0e\x01\x0f\xd1\xcc\xf2\xa8\xd3\xfb\xbb\x31\x56\xf9\xdf\xde\x0c\x7c\xbb\xaf\x84\x33\x09\x85\x17\x49\x1b\x78\xdb\x96\x98\x61\x4e\xa4\x0e\x0b\x1e\x6a\x1e\x36\xb9\x00\x45\x3a\x16\xea\x27\x6f\x34\x42\xbb\xd2\x7a\x7e\xcb\x98\x15\x11\xf5\xc9\x20\x9e\xb0\x96\xe2\x85\x88\xb6\x5b\x96\xb5\x01\x88\xc0\x38\x1f\xf7\x12\xbc\x06\xb2\xc6\x55\xcc\xa0\x75\x1c\x09\x5d\x80\x16\x25\x15\x85\x85\x1e\x67\x74\x34\xdc\x3e\xfd\x08\x7a\x12\x68\x0f\xc2\x2e\x5b\x83\x10\xa1\x0e\x32\xca\xac\x9b\x71\xc8\x76\xee\xd3\x1e\xf0\x9f\x7f\xa0\x12\xba\x08\xdf\xd2\xad\x68\xc1\xe1\x47\xf5\x05\x98\xe5\x50\x46\x7e\xf9\x9f\x29\x5a\x31\x8f\xaa\x50\x7e\xbe\x77\x6c\xe5\x5c\x4d\xa1\x64\x32\x3c\x30\xa5\xe7\x2d\xbe\x02\x7c\x3c\xcf\x96\xc7\x01\x97\xa6\xfb\x1b\x74\xaf\x13\x3a\x8b\xe2\xb0\x3c\x1b\x99\xfd\x25\xb3\xce\xd5\x1f\xe3\x88\x20\x21\xa3\xaf\xd9\x22\x9f\x64\x1b\xc6\xca\xd4\xe1\xd3\xcb\x6e\xd9\xb6\xb6\x8a\x25\xf1\xe1\x39\x72\x89\x98\x1f\x78\x92\x4b\xff\x24\xc8\xde\xe6\xa1\x8a\x04\x21\xfa\x32\xae\x3a\xb6\x0a\x0d\x93\x3a\x6a\xf4\xff\x70\x48\x74\xb0\x9b\x07\x39\xe2\xf2\x9d\x8f\x25\x2d\x79\x05\x5f\x89\xd3\xbf\xf1\x0a\x22\xc5\x4a\xc3\xd8\xaf\xee\xce\x81\x83\x53\xa6\xab\xe2\xb7\xfb\x8e\x8e\x0d\xa5\xb7\xac\x1c\xfc\x98\x5d\xf9\x75\x80\xb1\x82\x11\xa4\xe3\xed\xff\x95\xaf\xdd\xa0\x61\x54\x7d\x3a\xe0\x40\x6d\x32\x86\xcd\x30\x5b\xdf\xd2\xc3\xab\xf8\xf7\x4a\xf9\xa0\x34\x20\xe5\xb0\x3f\x82\x5e\x9c\x53\x90\x7e\x13\xa5\x81\x21\x74\xbe\x42\x89\x86\x45\x14\x9d"}, +{{0xc0,0x4d,0xc0,0x9f,0x11,0x9d,0x67,0x0f,0xb1,0xea,0xe0,0x13,0x6f,0xcc,0x06,0x08,0x5f,0x29,0x0f,0x4a,0xd1,0xaa,0x1f,0xfc,0x9c,0x16,0x0e,0xa5,0xcf,0x47,0xf0,0x9d,},{0xff,0x49,0x8c,0xe8,0xc9,0xdb,0x78,0x67,0xf6,0xd0,0x27,0x64,0x52,0xa4,0x66,0x72,0x48,0x87,0xe6,0x17,0x2f,0x66,0x81,0x67,0x1b,0x8a,0xe0,0x35,0xf5,0x86,0x5e,0xa3,},{0x4b,0xd1,0x9f,0x3d,0x9c,0x51,0x16,0xec,0x6a,0xe0,0x02,0x4d,0x0f,0x24,0x6d,0x2c,0xe2,0x50,0xd9,0xe0,0x63,0x4a,0x23,0x2b,0xa0,0x6f,0xd3,0x56,0x6a,0xed,0x55,0xcb,0xe5,0x9f,0x12,0x33,0x2c,0xba,0xd6,0x5d,0x43,0x49,0xa9,0xd2,0x2e,0x7d,0x6e,0x46,0xd2,0xfb,0xdc,0x71,0xd5,0xc8,0xf9,0xda,0x15,0xdf,0xbf,0x17,0xba,0x22,0x51,0x07,},"\x1e\x42\x29\x7f\x8a\xee\xf2\x9a\x84\x2e\x0e\x21\xf5\xdb\xae\x06\x8e\x2c\x9d\xda\xa6\xfd\x34\x8e\x48\x88\x1f\x0d\x42\xc5\x0b\xf0\xec\xf1\x70\x6b\x94\xa5\xd1\x98\x17\xca\x02\xd8\x3e\x9a\xb2\xf9\x9d\x8b\xfa\xaa\x5c\x85\xad\x39\xa1\x50\xb2\x25\xad\x3e\xaf\xa0\x67\x81\x5b\x74\x67\x2f\xe0\x26\xc3\xcc\xc6\x77\x25\x54\x40\xb6\x84\xa7\x6e\x12\x8c\xa2\xcc\xc4\x29\xf1\x52\x57\x7d\x25\xb6\x9f\x40\xdb\x58\x2d\x49\x47\x9a\xfa\xe6\x80\x71\x2d\xc0\xfd\x1f\xe1\x41\x88\x39\x68\x7c\xa6\x0c\xdd\xe9\x74\x14\x04\x62\xf9\x61\x48\x29\x5d\xf1\xce\x43\xa9\x77\x35\x1c\x77\xf2\xf0\xb0\x9a\x6b\x26\xd6\xfe\x96\x5f\xce\xae\x17\xd7\xb8\x62\x03\x71\x40\x24\x28\x54\x4f\xdf\x91\x69\x0b\x44\xe9\xaf\xc2\xe9\x08\x8c\x83\xca\x48\xdc\x85\x76\xf6\x28\x72\x47\x98\xdc\x90\x32\x31\x74\xc4\x49\x96\x59\x65\x02\xa3\x5d\xf8\xb9\x82\xc5\x70\xa6\xcb\x51\xb9\xa1\x97\xd4\x31\xaf\x33\xf0\x2b\x80\x01\x15\x67\xfe\x50\xcf\x45\xac\x11\x1b\x3d\x55\x6f\x8c\x8c\xe5\xae\x8c\x99\x72\xf2\xa9\x93\x6b\x1a\x01\x2b\x9c\x33\x9e\x30\xc9\x73\x12\xb6\x5e\xa5\x9c\x10\x0f\x79\xd7\x95\xb8\xa2\x4b\x31\xa0\xa9\x7d\xc2\x5c\xce\xd6\xb8\xff\x5a\xe1\x45\x33\x9a\x04\x8c\xa1\x2a\x57\x90\x17\xfa\xe8\xd5\xcb\xcb\x61\xd5\x2e\x31\x4d\xd7\xc2\xe7\x20\x10\xc4\x72\x17\xb1\xd0\x68\x78\xbf\x28\x18\xca\x18\x8e\x8e\x30\x79\x60\xc1\x68\x9d\x7d\xfc\x02\x02\x97\x3c\xd2\x9f\x2f\x7b\xa7\x43\x46\x9e\x68\x5e\x0e\x70\x4b\x04\xba\xca\x4f\xab\x54\x88\x44\x8a\x92\x2e\xab\xf4\x0b\xe5\x81\xc1\x99\x4d\x74\xd1\x3a\x36\x6c\xe8\x57\xfb\x40\xa6\xe0\x5d\xa8\x55\x36\x94\x17\x2c\xc3\xfd\x28\x06\x2f\x53\x82\x50\xaa\x8c\x11\xf6\x81\x39\xe7\x9c\xd1\x19\x1b\xa3\x31\x4b\x5c\xea\x08\x64\x43\x7e\xd2\xe4\xb6\xfb\xd7\x5b\x9d\xed\x09\x87\xb4\x1c\x20\x2a\x58\xec\x02\x54\xd9\xd3\x71\xa7\x95\xf1\xdb\xec\xdd\xac\x11\x2b\xe8\xd0\x9e\x2d\x7b\x9c\xa5\x75\x2f\x40\x6c\xff\xb9\x11\xca\x36\x45\x0b\xc0\x5f\x1e\xc1\xca\x3c\xa8\xd3\x51\x24\xd1\x28\x6c\x55\xf1\x0f\x61\x33\x4e\x46\xec\xe4\x18\x3b\x92\x21\x9a\x9d\xcd\x0e\x5e\x78\xef\x2a\x76\xcf\xe9\xa9\xab\x37\x95\xdf\xdc\xb4\x4f\x63\xd4\x5f\x5f\x48\xff\xb4\x15\x61\x33\xad\x2e\x99\x50\x88\x4c\x5b\xbd\x2c\x1c\xb8\x72\x9e\x40\xa8\x78\x7f\x78\x49\x69\xfa\x88\x0c\x07\xff\xcc\x97\xd5\xc0\xd2\xd4\x88\x08\x5e\x91\x16\xd7\x10\x7c\xd5\xdb\x16\xce\xcc\xde\xad\x55\x02\x5e\xea\x2e\xde\xe9\x3c\x1b\x10\x64\x27\x61\x8e\xe0\x9d\xc3\xda\xd1\xe0\x56\x76\xa2\x36\x80\x69\xc8\x04\x5c\x3e\xbc\x6c\x67\xaf\xa5\x2d\x59\x39\x82\x48\xef\xcf\x15\xe9\x04\xc7\x14\x23\x04\xff\x61\x97\x1f\x4d\x9b\xf6\x46\x0c\x1d\x64\x17"}, +{{0x67,0x91,0xbd,0x74,0xd3,0xb4,0x62,0x0e,0xf5,0xf1,0xff,0x56,0x40,0x64,0x32,0xc2,0x6a,0xb6,0x46,0xf6,0xd5,0xe9,0xdd,0xa6,0x84,0x2e,0xd6,0x90,0x52,0x27,0x53,0x92,},{0xda,0x99,0x15,0xa7,0x55,0x2f,0x11,0x0f,0xae,0xa1,0x2d,0x47,0x92,0x0a,0x09,0x60,0x14,0x43,0xd4,0x00,0x0a,0x9c,0x7e,0x21,0x8d,0x5b,0xa7,0x2b,0x74,0x98,0x9f,0xa6,},{0xb1,0xe8,0xd4,0x81,0x06,0x5b,0xd5,0x12,0x1b,0xb3,0xbf,0x56,0x96,0x00,0xbc,0xc2,0x6d,0xf4,0x0c,0x49,0x9f,0xba,0xa9,0x54,0xb3,0x9a,0x61,0x9d,0xc4,0x0b,0x95,0x90,0xc3,0x17,0x56,0xb8,0xb6,0x3f,0x86,0x01,0x51,0x69,0x4b,0x95,0x76,0x5d,0x69,0x7b,0x2e,0x1a,0xde,0x08,0x06,0xe9,0x2a,0x06,0xc4,0xa5,0x59,0xe9,0x0f,0xcf,0xa5,0x06,},"\x36\xa2\x0e\x66\xbb\x29\x15\x51\x61\xad\x85\xee\xfe\x89\x3b\x53\xac\x5a\xde\x16\x5f\x08\x9a\x77\x19\x0b\x0c\x23\x9d\xec\x8a\x20\x16\x85\xb0\x76\xb4\xde\xd4\xa1\x0a\xa4\x59\xb9\x80\xa8\xcc\xa4\x7d\x5f\x8d\xe4\xd2\xa6\x62\xe4\x46\xd5\xf7\xfb\x70\xed\x9b\xe0\x5d\xb1\xcc\xea\xdd\x13\x0b\x33\x46\xd9\x40\x9f\x9d\x6e\xf5\x28\x24\xc7\x64\xac\x6f\xb1\xcd\x15\x6d\xbd\x6a\x47\x3a\xe7\x22\xd0\xeb\xb2\x56\x38\xc5\x12\x65\xa2\x2f\xeb\xbb\x14\x96\x7d\x6d\xd8\x25\x3c\x1d\x03\x88\x95\xc6\x73\x7f\x06\x7c\x8f\x73\xc3\xc1\xcb\xe6\xcd\xa4\x36\x96\x32\xd7\xf4\xc9\xac\xeb\xe8\x7d\x05\x71\xc8\x1a\x58\xcf\xd7\x2c\xce\x4a\x5c\xf5\x3a\x1e\x75\x25\x9f\x4c\x99\x3e\x67\xef\xc8\xd9\xc3\x57\x6c\x43\xaf\x04\xa5\xca\xf3\x3d\x85\x6f\x7f\x27\x55\xd3\xa9\x75\xab\x2b\x68\x5c\x6f\x65\x68\x0c\xba\x9a\xc8\x79\xf3\xa8\xc9\xa4\x76\x5b\x87\x9c\x0a\xde\x1e\x4b\xd0\xd4\xa7\x0b\xb6\xf9\x2b\x24\xd4\x29\xdc\x74\x6c\xc7\x8f\x84\x81\x1f\x07\x6f\x32\xc6\x1e\x35\x85\xcc\x8a\xad\xe9\xb0\xca\x15\x22\x4b\xfb\xfe\x18\xbe\x10\xa3\x36\x43\x60\x0f\x66\x12\xbf\x01\x3f\x0e\xfc\xca\x83\x72\x46\xa0\xee\x5b\x03\xc0\x2f\x15\x73\x62\x4c\x4a\x44\xa9\x0f\x9e\x42\x3d\x4e\x56\x06\x1a\x71\xd0\x14\x4f\x5a\x88\x7a\x8c\xd4\xa9\xd6\xf2\x47\x90\x4e\x26\x79\x59\x51\x95\x9d\xa1\x21\xc8\x3c\x6c\x94\x1e\x2b\x6b\x9a\xb7\x62\x09\xff\xe9\x17\x85\x91\xea\xd6\x82\x30\xb9\x4a\xe9\x7d\xf5\x8f\x9f\x17\x24\x28\xc9\x50\x67\x59\x8a\xc5\x82\xff\xb9\x50\x84\x0d\x82\x66\x30\xc4\x62\x5f\x5d\xea\xdd\xec\x13\x05\x20\x3b\x4d\xb6\xb9\x45\xf9\x91\xed\x7c\xd3\xd6\xfa\xbc\xa5\x1e\x21\x66\xad\xad\x0a\xad\x51\x17\x33\x6d\x52\xd5\x94\x22\xf0\x13\x5c\x8f\xa8\xcd\xd0\x88\x4b\xe7\x35\x86\xbf\x28\x4e\x5d\xdd\xdb\xcb\x95\xb4\x11\xf9\x85\x68\x52\x6f\xbe\x71\xa5\x59\x2b\x56\xad\x5a\x73\x45\xf2\x87\x4d\xb1\xd5\x7b\xea\xb4\x3e\x8c\xc6\x95\x47\x52\x06\x29\xf0\xee\x76\xdb\xf4\x32\xa3\x76\xfa\xd2\x8b\xfc\x77\xe1\x4d\x84\x0f\x0c\x02\xd4\x78\xf1\xe2\x33\x7c\x23\xb8\x9e\x73\xe5\x27\x91\x08\xb5\x60\x9b\x18\xe8\x0d\xb0\xde\x11\xcf\xa9\x4e\xcf\x72\x39\xbc\xff\x59\xc5\x41\x18\xe4\xed\xe4\xfb\xfc\x08\x23\xae\x54\x60\x16\xf7\x74\xc5\x21\x98\xa9\x63\xb5\x54\x5a\x34\x89\xb8\x9d\xf7\x62\x6f\xd1\x1e\xd4\x65\x8d\x71\x5a\x46\x57\x99\x40\x35\xd4\x03\xb3\x37\x0d\x14\xee\xd9\x71\x8d\x59\x8d\xb6\x75\xf0\x42\x59\x2f\xea\x89\x05\x65\x44\xb3\x2e\x5b\x9c\x80\x62\x82\x8a\xaa\x3c\xf5\x9c\xb4\x76\xad\x36\xdb\x1d\xaa\x24\x82\x22\x7a\x9b\x7a\xfb\xc1\x53\xce\x93\x25\x3d\x1b\x39\xda\x95\xeb\x96\xf8\x31\x28\xff\x25\x54\xa5\x47\xe3\x4e\xea\x4a\x00\x00"}, +{{0x23,0x4c,0xe4,0xd3,0x9b,0x5e,0xba,0xbe,0x9a,0x2c,0x1e,0x71,0x97,0x0d,0x71,0x81,0x38,0xdc,0xb5,0x30,0xcf,0xd2,0x96,0x02,0x34,0x27,0xd8,0x92,0xbf,0x88,0xf8,0xa4,},{0xcb,0x73,0x93,0x0d,0xb4,0x21,0xf6,0xd2,0x45,0x36,0x83,0x7b,0xd0,0xbf,0xf6,0xfa,0x75,0xbb,0xd1,0x41,0xc9,0x8a,0x40,0x5d,0x42,0x44,0xa3,0xc4,0x24,0x55,0x07,0x79,},{0xf6,0xd0,0x60,0xed,0x7d,0x18,0x27,0x3f,0x18,0xf7,0xa6,0x9c,0xd1,0xd8,0x12,0x6e,0x47,0x8e,0x88,0xa1,0xd7,0x29,0x4f,0xf6,0x04,0x08,0x46,0xd4,0x61,0x07,0xc3,0xe4,0x1a,0x42,0x3b,0xab,0xb2,0x41,0x71,0x39,0xfe,0x58,0x7d,0x29,0x10,0x27,0x1a,0x35,0x7f,0xe5,0xbf,0x57,0xc9,0x2e,0xe3,0xa7,0xb7,0x75,0x33,0x72,0x9d,0x0a,0xc2,0x0d,},"\x77\x73\x0c\xf8\xc8\xf9\x6b\x91\x87\x90\x2a\xcf\xf9\xff\x0b\x21\x74\x6c\xca\xf0\xa3\x82\xa7\xb3\x43\xd1\xc7\x20\x27\xae\x3c\x31\x68\xa7\x3a\x6b\x8f\x49\xbc\x87\x98\x14\x1e\x15\xc2\x73\x2b\x6a\x6b\x3f\x75\x7f\x8a\x8e\x86\xc7\xa4\xba\xcb\x39\x55\x1c\x54\x87\x4d\x6b\xf7\x16\x89\x7e\xe4\xaf\x13\x25\x3a\xa5\xbb\x79\xa1\x92\x10\x4f\x44\xdc\xb3\xde\x96\x07\x45\xa8\xe6\xaa\x98\x80\x52\x4a\x62\x9f\xb5\x10\xa4\xce\x4c\xbd\xa7\xe2\x95\x7d\xff\x1d\x62\xe7\x05\x60\x6a\x2c\xc8\x4f\x91\x85\x0b\xea\xac\x5e\x58\x46\xe1\x42\x0b\xc9\x1d\xcd\xd2\x42\x7b\x69\xcf\xa4\x6a\xe3\x8a\x4f\xef\x41\x46\xea\xe3\x5f\x9c\x22\xe9\x67\xcb\x14\xa1\xaf\x9c\xab\xf8\x3b\x18\x04\x65\xbe\xd6\xef\x2c\xda\x38\x2a\x84\xd9\x99\x4a\xad\x65\x5d\x89\x52\xe0\xfb\xb0\xf9\x6f\xc8\x08\x9f\x2e\x74\x89\x49\x7f\xac\xdc\xd6\x56\xa8\xa4\x51\xb9\x28\xc1\x1e\x7a\x40\x75\x07\x2a\xaf\xbf\x17\xd8\xf1\x05\x4c\x91\x96\x28\x8d\xed\x3a\xe2\x1f\x9a\xfd\x58\x10\xa1\x00\xd8\xe4\xd8\x4c\x4a\x35\xa9\x8b\x30\xd3\xe1\x85\x24\x43\x8d\xd4\x40\x2d\xfd\x8e\x76\x75\xf0\x9d\x08\x0c\xd9\x15\xf1\x4a\xf4\x37\x2f\x7c\xe5\x83\x84\x97\x2d\x5d\x11\x10\x79\x65\x1b\x2a\xcf\x39\xd2\xa1\x67\xc6\xa0\x0b\x2b\x17\xce\x0b\x26\x87\x91\xbd\x2b\xe5\x17\x8f\xe0\xf8\x2d\x64\xda\xcd\xde\x37\x7a\x1e\x8b\xe9\xe7\xd8\xdf\xc8\x2b\x08\x64\x45\x37\xbd\xc8\x70\xc5\x81\x92\x86\xfd\x51\xf6\x79\x2d\xc5\xf6\x7b\x54\xbe\x33\x6d\x44\xd5\x4f\xeb\xf8\x1b\x8d\xf8\xde\xc5\xd8\x68\x6d\xb1\x2f\x16\x4d\x0e\x8f\xf1\xaa\x2c\x16\xba\xcc\x98\x06\x01\x0e\xc8\xe9\x11\x96\x59\x7e\xf0\x6a\x4c\xf1\x70\x7d\xef\x50\x67\xa0\x48\x89\xd8\xe4\x8a\x9b\xc2\xc0\xbe\xf6\x64\xf5\xac\xd1\xb4\xf5\xbc\x2d\xa7\xda\x43\xdc\xb5\xf9\x63\x24\x5b\xa5\x52\xfd\x49\x30\x01\xd8\x70\xa9\x51\x7a\x17\x9c\x2f\x0d\xe8\x5b\xe0\xc6\x82\xd0\x57\x48\x8e\x35\xc7\x81\x6f\xf4\xba\x52\x9a\xef\xd7\xc6\x60\x91\xf2\x06\xf5\xf4\xd7\x5c\xac\x8b\xd2\x09\xec\x2f\xa5\x5b\xe7\x4a\xf2\x31\xe2\xf3\x89\xdc\xc2\xd6\x68\xbf\x69\x5e\xd2\x67\xc3\x59\x4b\xad\x9e\xfc\x00\x21\x7c\x7a\x0e\x9e\x7b\x6a\x56\xa3\x30\x79\xa3\x0e\x73\xc3\x73\x3f\x2d\x24\xef\xec\xdd\xe8\x7f\x72\xf9\x48\xd2\x77\xd6\xb6\xd5\xb0\x35\xb4\xc5\x31\x80\xd2\x3d\x66\xcc\x0f\xf1\x7c\x15\xdd\x46\x85\x85\xe3\x89\xd9\x1a\x4c\x97\xfd\x80\x11\x0b\x21\x8a\x0b\xf7\xa5\xe0\x35\x3f\x46\x09\xd2\xcf\x01\x8a\x06\x55\x71\x00\x1c\x78\x88\x55\x5e\xed\xbd\x36\x22\xc3\xb1\x76\x9c\xd1\x3f\x33\x37\x47\x72\xaa\x6c\x8a\x8f\x58\x81\x02\x01\x7d\x4e\xe4\xe5\x0d\xcb\xbd\xb1\xd6\x10\xc3\x26\x70\x93\x4a\x6d\x9e\x6d\x9b\x78\x4b\xbf\xe7\x18\x62\xbb\x38"}, +{{0x10,0x3d,0x11,0x8c,0x7d,0xd6,0x5d,0x07,0xe8,0xd5,0x58,0x2e,0x45,0x04,0x2a,0x75,0x79,0x24,0x17,0xc6,0x92,0x00,0x1e,0xe6,0xbd,0x9a,0x92,0x7b,0x2b,0x3d,0x90,0x16,},{0xb4,0x5c,0xc9,0x45,0x14,0xa6,0xad,0x67,0x24,0x96,0xcd,0x4e,0xb9,0xfd,0xaf,0xc1,0xd4,0xa1,0x67,0x07,0x2c,0x68,0x74,0xdc,0x8f,0xf1,0x6d,0x76,0x1f,0xb6,0x69,0x86,},{0x2f,0xaf,0xc1,0x3c,0x43,0xaf,0xe5,0x05,0x43,0x72,0xb9,0x23,0xd2,0x4f,0x29,0x2b,0x28,0x3a,0xfc,0xa3,0xac,0xa3,0xb3,0xe4,0x32,0x38,0x06,0x84,0x96,0x17,0x13,0xc8,0xd2,0x3e,0x86,0xb3,0x58,0x04,0x95,0xdf,0xba,0xe4,0x24,0xb7,0x67,0xe4,0x79,0x5a,0x0f,0x92,0x2f,0x71,0xb5,0x0f,0x5d,0x7a,0x36,0x9a,0xb8,0xc6,0xe8,0x80,0x42,0x0c,},"\x5a\x8e\xe0\x79\x18\x6b\x51\xcf\x46\x29\x83\x4d\xe0\xc6\xbd\x73\x34\x85\x50\x39\xa7\x63\x1d\x68\x87\x65\x2a\x77\x28\x99\x59\x72\xe3\x62\xc1\xc4\x09\xf0\x84\xf5\xaa\xf2\x98\x6a\xe3\xf5\x36\xbe\x00\x70\xc4\xba\xf4\x59\xef\x60\xa0\x15\xef\x9d\x70\xdf\xa3\xea\x96\x71\x1c\xbb\x18\xe9\x2a\xf5\x0c\x52\x7d\x7e\xd4\x57\x87\x7a\x07\xab\x83\x72\x15\x18\xc8\x9f\x7a\x86\x41\x91\xb1\xe9\x74\x33\xb7\xc6\xcd\x63\x4a\x83\x2e\x19\x89\x1e\x76\xc6\x21\x22\xa4\x9d\xbf\xfd\x83\x49\x8a\xa4\x16\xac\xcc\xb7\x73\x7f\xe7\x5f\x4f\xb2\xc3\x53\x28\xe6\xf6\xec\xec\xaa\xa4\x2e\x43\xdb\xa5\xbc\x96\x89\x67\x3d\xab\x96\xf0\xbe\xfa\x3c\x83\xeb\x41\xd4\xd8\x87\xb3\xa1\x17\xd0\x55\xe3\x0b\xb8\x7f\xbe\x7c\x71\x94\x72\xf6\xc7\xa4\xcc\x45\xf6\x28\xf5\xfa\xdd\xc4\x8c\xa3\x44\xf7\x7b\x73\x3c\x0e\x3b\x9f\x50\x79\xdb\xd0\x7a\xf3\xa3\x84\x7a\xf1\x41\x71\x9c\xca\x2f\x6a\x76\x65\x52\xb4\x5d\x0f\xdc\xdb\x98\x68\xf2\xc7\x62\xb6\xd4\x93\x3b\xa1\x08\x36\xf9\x5b\xff\x71\xcb\x88\x04\x00\x24\xc9\x05\x34\xc4\xd7\xa9\x5a\x23\x03\xb0\x4c\x29\x61\x01\x2a\xf5\x8b\xc7\x84\xa9\x63\x27\xbb\xfe\xd0\x39\xd0\x80\x2a\x05\x26\x2d\x8e\x66\x3b\x78\x50\x8e\x92\x50\x8b\xc1\xf2\xea\x2b\x9b\xe7\x58\x0b\xde\x10\xa4\xd6\x63\xd0\xd2\x5b\x0e\x97\x3b\x8c\x5d\xed\x59\xde\xbf\x19\xbb\x04\x4a\xff\x1c\x60\xc7\x0e\xa1\xae\xfe\x85\xf6\xd1\x5c\x2c\x1b\x84\x75\x3b\x59\x57\x6a\x49\x47\x3d\x65\xaf\x3e\xd9\x41\xa3\xd5\x14\xb5\xc4\x52\x2c\x14\x1b\xdb\xee\xd9\xcb\x33\x96\x95\xb2\xe0\x2d\xc0\x70\x00\x86\x7f\x1b\xf8\xed\x8c\xfd\x3b\x1a\xfe\x68\x8f\xbc\xa8\x0e\x2f\x9b\xa5\xc0\xb1\x88\xa1\x9a\xda\xff\x66\x86\xca\x0f\xf0\xed\xd4\x44\x66\x12\x91\xfa\x27\xca\x1f\xc5\x29\x42\x9a\x5d\x8f\xf7\x9e\xd2\x02\x7c\x60\xff\xe3\xb2\xc0\x3f\xb8\xa6\x6a\x39\x85\x41\x7b\xa4\xac\xe7\xd1\x4f\xd0\xe2\x37\x1e\xdf\x5d\x71\xbc\x02\xb9\x05\x27\x67\xc7\xf7\x2c\x4e\x6f\x3f\x30\xe0\x63\x82\x76\xb9\xc4\x20\xaa\x43\x33\x09\x5d\x31\x31\x30\x33\x09\x05\x82\xe3\xac\x4d\x9f\xd3\x20\x31\x20\xba\x25\x14\x97\x3a\xb9\xd1\xc7\xfc\x42\x29\x01\x16\xb5\x1d\xae\x9f\xd5\x79\x41\x0a\xe0\x78\xed\x32\x0a\x5a\x1b\x49\xaa\x7b\x5f\xef\xcd\x75\x63\x95\x21\x3a\xf8\x64\x1e\x29\xb0\xeb\xb5\xb8\x3e\x37\x80\xe5\xd1\x0e\x9d\x3d\x11\x99\x81\x48\xf6\xc6\xf8\x6c\x4d\x4e\xb2\x52\xe2\x8c\x70\xfa\x3a\x55\xc4\x3d\x4d\x7f\xaa\xfc\xbc\xdd\x45\xad\x26\x37\xf2\x15\xe8\x15\x49\xeb\x8a\x4c\xde\x47\x15\xb7\x10\x72\x07\x50\x3a\x79\x59\x50\x60\xb8\x3a\xce\x8f\xeb\x67\x3b\x99\x79\x68\x46\x9d\xd9\xb4\xad\x6a\x7e\xa8\x1c\x6e\x61\x81\x00\x33\xf3\xed\xfc\x13\x7d\x97\x42\x09\x57\x5c"}, +{{0x47,0xee,0xe2,0x02,0x4d,0xbe,0x09,0x95,0x3e,0x98,0x1f,0x69,0x86,0x52,0x0f,0x66,0x60,0x82,0xaa,0x9e,0xf4,0x89,0x2d,0xfd,0xfb,0xdb,0xd2,0x50,0xd2,0xa1,0xdf,0x28,},{0x9f,0x13,0xcd,0x8e,0xbf,0x50,0x80,0x34,0x79,0x75,0x15,0x9f,0x36,0x02,0x96,0xa7,0x16,0x40,0x14,0xd8,0xd0,0x69,0xe8,0x31,0xda,0xb0,0x33,0x26,0x07,0x99,0x7c,0xde,},{0x5d,0xef,0xae,0x0e,0x17,0x3e,0xcc,0x18,0xd5,0xf0,0x1e,0xc9,0x29,0x1b,0xe1,0x60,0xd5,0xea,0xbf,0xf6,0x3f,0xd5,0x42,0x3f,0x2b,0xc6,0x6e,0x3f,0x64,0x08,0xc1,0x96,0x35,0x35,0x02,0xdc,0xef,0x21,0xef,0xfa,0x4b,0x9c,0x14,0xbf,0x27,0xb6,0x87,0xd1,0xb6,0xe8,0x6b,0x2a,0x20,0x5a,0x89,0xeb,0x35,0xc3,0x76,0xa3,0xa3,0x25,0x69,0x0d,},"\xc1\x33\xf0\x33\xcf\x3b\xec\x6c\xd1\x92\x12\xea\x47\xdb\xec\xb1\x3f\x2c\x60\x18\xf9\xe0\x87\x8a\xc8\x84\xbf\xb5\x75\xc0\xf5\xd3\xfc\x5b\x49\x99\x58\x0e\xb8\xac\xbc\xaa\xc8\x3a\xe9\xac\x9b\x44\x3e\x6d\x1c\xff\x44\x9c\x36\x89\xb4\x33\xd5\x09\x00\xb2\xe8\xb7\x1d\x00\xe1\x19\xc8\xb8\x75\x09\x4b\xda\xb9\x16\xad\xaa\xb7\x5b\xcc\x85\x29\x59\xd8\xd7\x59\x79\x5b\xbd\x6b\x36\x0e\xe4\x84\xaf\xe4\x7b\x1a\xd2\x83\x91\xf2\x5a\xfb\x8d\x4e\x3a\xfe\x0c\x5b\x60\x04\x98\xa1\x28\x33\xfe\x2a\x1a\x54\x83\xdf\x94\x0b\x17\x3b\xa0\xd9\xd8\xc4\xd1\x32\x1f\xa4\xb7\x33\x33\x4b\x0f\x6d\x87\x8a\x0e\x5a\x76\xf4\xf1\x80\xac\x11\x9a\x82\x08\x2a\xcb\x14\x88\xe4\x9b\xbc\xa7\xa0\x36\x9c\x19\x1b\xd6\xd0\xc5\xd4\x45\x65\x68\x21\xa9\x9c\xcb\xc9\x45\x94\x9e\xca\x81\x36\xcc\x6e\x12\x7d\x9d\xe9\x2e\xf6\x4f\x17\x4a\x6c\x04\xc8\xb5\xe5\x24\x95\xf0\xdd\x67\x4b\xb5\xca\x12\x8a\x92\x09\x96\x8f\xd4\x50\xdc\xe3\x19\x91\x3f\xd6\xa3\x0c\x33\x82\x79\x81\x63\xe6\x58\x5f\x58\xef\x20\x8b\xe4\xd0\xc6\xa2\x51\x3a\x75\x23\x88\x39\x7a\x4a\xe4\x44\x83\x8c\x84\x66\xdb\xc3\x6f\xbc\x36\xae\x08\xbe\xc8\x8e\xed\xa1\x31\xc1\x4d\x06\x36\x6b\x67\x31\x51\x45\x41\x00\xde\xa1\x11\x81\x50\xfb\xe4\x41\xb1\xe7\x82\x6e\x54\x5d\x98\x68\x24\x2e\x89\x9f\x5e\xa5\x3e\x43\x4c\x37\x93\x6c\xe6\xfd\x06\x14\x62\x83\xe8\xfb\xd5\x36\x48\x0d\xe5\x5a\x16\x10\x2c\x44\x75\x4b\xc5\x54\xd5\xbc\x2d\xe2\xf2\x5e\x19\xe5\x67\xa0\x23\xdf\x46\x40\xe7\x4f\xf3\xa4\x9e\x4d\xd3\x0e\x0e\x25\x58\xb3\xdb\xc2\xaa\xb9\x2f\xdd\x5e\x79\x42\x5e\xcb\xc4\xc6\x99\xfe\x1f\x16\x19\x65\xf1\xd0\xb4\x5d\x8b\xda\xb5\x2e\xc9\xbf\x7a\x69\xd8\xaa\x0b\xd1\x71\xe7\x55\xce\x7b\x8d\x07\x18\xf7\x26\x7a\xfb\x73\x3e\xfc\xa5\x4b\x21\x3e\x6f\x5a\xda\xb4\xc9\xd7\x6c\x86\x7f\xcb\x69\xae\x05\xc7\x4b\xd2\x15\x16\xcf\x34\x2c\x61\x61\xf6\xfc\x9e\xcc\xac\xf9\x70\xeb\xce\x54\x0c\xd8\x92\xbc\x10\x6c\x6b\xd5\x63\x61\x02\x98\xb7\x09\x68\xf0\x91\xbc\xc6\xe1\xf7\xab\x4a\x5b\x2c\x63\x74\xa1\x90\x3f\x4d\x3a\xd5\xe1\xbd\x86\x43\xa9\xc2\xf8\x78\xc3\xd7\xa4\xdc\x49\xef\x31\x97\xed\xbc\xda\x7b\xb9\x1e\x7e\x06\x60\x60\x87\xd4\xe9\x81\xbf\xab\x93\xa6\x02\x49\x77\x96\x2e\x45\x26\x25\x17\xf3\x38\xb6\x85\x7e\xec\x21\x58\xa2\x97\xb2\xaa\x91\x52\x4b\x67\x7a\x21\xaa\xc5\x7b\xe0\xb6\x3a\x80\x74\xfe\x54\xe7\xa9\xdc\x70\xc5\xa5\xc3\xde\x72\x8b\x9c\x17\xec\x12\x12\xab\x11\x30\xeb\x17\x62\x2c\xd7\xb2\x2a\xb6\xeb\xa9\x18\x5e\x8d\x67\xbe\x6c\x47\xa2\xe5\xad\xc6\x63\xd4\x64\x2c\xc1\x20\x22\x2e\x29\x9f\xe1\x34\xfd\x7f\xcd\x00\xad\xab\xcf\xaa\x64\x2f\xe2\xe0\x8d\xd5\x2e\x2c\x3f\x32"}, +{{0xb6,0xc8,0x8b,0x4c,0x90,0xfd,0x19,0xa1,0x49,0xd3,0x81,0x67,0x19,0x53,0xb9,0xb1,0x6d,0x42,0x8f,0x63,0x61,0xcf,0x50,0x3a,0x11,0x04,0x77,0xe2,0x97,0xf8,0xd2,0xf8,},{0x8e,0xbf,0xb0,0x84,0xf9,0x97,0xb2,0xea,0x79,0x32,0xa2,0x35,0x3b,0x2c,0x8b,0x16,0xbd,0x82,0x5e,0x1a,0xf5,0x87,0xa8,0xeb,0xc5,0x1a,0x6c,0x45,0xae,0xa3,0x43,0xae,},{0x74,0x47,0xa2,0x01,0x81,0xb0,0x2c,0xf1,0xb6,0xad,0x52,0x95,0x69,0xce,0x43,0x7c,0x2a,0x05,0x08,0x11,0x6f,0x50,0x20,0x5c,0x41,0xe6,0x37,0x8b,0x74,0xfe,0x2f,0xc5,0x36,0x30,0xaa,0x0d,0xc4,0xb8,0x0c,0x31,0xcb,0x26,0xc8,0xf0,0x9b,0xf8,0xfa,0xb2,0x7e,0x3a,0xbc,0x8f,0x1f,0x60,0x4a,0x5e,0xc0,0x66,0x31,0xa8,0x4f,0x6f,0x2e,0x06,},"\x7f\x4b\xf4\xf5\x21\x73\xef\xf0\x72\xf8\x18\xd0\xaa\x97\xe6\x93\x5d\x8b\xac\xcf\x48\x39\x66\x32\x53\xb2\x41\x4f\xe6\xb1\xf3\x4c\xf4\x3a\xb1\x20\x15\x5a\x1a\x3a\xea\x7b\x48\x19\xdd\xd1\x03\x16\x73\xb8\xa7\xa6\xbd\x0b\x9d\xda\x4a\xde\xfe\x69\x2a\x56\x16\x2c\x64\x61\x80\x79\x42\x64\xc5\x12\x21\x15\xeb\x90\xa6\xd3\x05\x4f\x08\x43\x02\xdc\xe3\xd8\x36\xac\x3d\xe8\x20\x63\x8b\xd8\x9a\x86\xbf\x0a\x4c\x01\x54\x7c\xfd\xc5\x43\xd6\x76\xfe\x16\x39\xef\x72\xc5\xb8\x45\xc4\x94\xe0\x78\x14\xce\xc8\xa4\x7d\x03\xdf\x73\xbe\x4e\x33\xc0\x5a\xfe\x9a\x19\x0d\xda\x04\x33\x60\x49\x6b\xe4\xcf\x3a\x63\x19\xda\x9a\xb0\x64\x81\x67\x7f\x1a\x43\x74\xd6\x0d\x3d\x3b\x63\x94\xf8\x84\x3c\x86\x9b\x0f\x41\xa1\xe8\x1c\x2b\x1a\x54\xbf\x5a\xac\xbd\x98\x20\x7c\x8d\xba\xcb\x36\x42\x2a\x3a\xa0\x13\xd5\xe8\x49\xe0\x44\xaf\x92\x85\x45\xc0\x46\x09\x7c\xaf\x14\x9d\x97\x02\x15\x11\x5d\xea\x0b\x5a\x85\x40\x1f\xf6\x72\xe0\x2e\xd4\x0b\xd0\xf5\xa4\x40\xcd\x56\x49\x40\x53\xc8\x96\xc3\xbd\x32\x60\x63\x49\xf7\xcb\xe7\xec\xe2\xa2\x23\x0c\xf2\x36\xda\xc5\x9f\x78\x17\x96\x5f\x3f\xa8\x0f\xb4\x8a\xa3\x0b\x0b\x19\xef\xa9\xa9\x65\x91\x64\x6b\xd2\x5e\x67\xc1\x85\xf7\x7e\x21\xd6\x63\x0b\x28\x8d\x4e\x55\x14\x6b\x2a\xbc\x15\xe9\x50\x88\xd9\x36\x08\x07\x75\x61\x81\x54\xbb\xdd\xa1\x15\x70\x2a\x2a\xfd\x6f\xd5\xf5\x6b\x92\x3e\x18\x88\x33\xec\x44\x89\x44\xd3\x02\x83\xe3\x37\x25\x42\x42\xc5\x81\x2d\x72\x45\xa4\xe9\x26\x70\xbc\xe3\x54\x6e\xfa\xed\x22\xd2\x74\xe1\xe6\x04\x8b\x5a\x0f\x01\xef\xbf\x89\x5d\xc4\x24\x94\xba\xf1\x74\x71\x85\xcb\x1a\x4b\x88\xfd\xf1\xe6\x09\x9b\xaa\xbc\x6a\x5a\xb5\xa2\x72\x7b\x1e\x24\x87\x89\xd1\x70\xca\xa2\x44\x96\x71\xa8\xf6\xe0\x94\xc1\x13\x32\xea\x0a\xc2\xaf\xe8\x81\x32\xc6\x44\xff\x88\x3d\x0c\x49\x9a\xd7\x6a\x93\xdf\x47\x2f\xa0\x13\xea\xa2\x7a\xb4\xda\xd6\x79\xd2\x51\x1b\x50\x49\xc4\xe9\x8b\xaa\x2e\x7b\x00\xa5\x34\x89\x1e\x29\x02\x65\xed\xb0\x76\xf7\xdc\xa8\xe6\xfe\xf3\xf4\x33\x03\x4a\x16\x57\x5f\x0e\x53\xda\x45\x77\xe6\xb1\x3f\x0c\xb0\xd7\x85\x87\x0d\x0d\x09\x8d\x5d\x80\xf4\x13\xa2\x68\xba\x84\xe0\x43\x1a\x78\x69\x23\x77\x13\x78\xcd\x57\xb8\x19\x22\x58\xe2\x63\x3c\xdb\xe0\x3c\xc3\x16\xa0\x95\x09\x70\x52\x6f\xd3\xe0\x93\x76\xbc\xef\x0d\x03\xb7\x07\x4e\x59\xa5\xa8\x4f\xc6\x4e\x79\x5a\x81\x21\x56\xd9\x60\x56\x76\x50\xbb\x1e\x14\x24\xb3\xcc\x9a\x4d\x99\xd5\x7b\xa8\x58\xdd\x1a\x0c\xad\x35\x32\xe9\x98\x14\x6e\x79\x26\x40\x45\xe2\x8e\xbb\xfd\x75\xa4\x26\xb0\xbb\x85\x1a\x24\x4a\xd6\xbe\x7b\xd5\x76\x5a\xf4\x93\xdf\xc4\x4e\xe3\x78\xcd\x04\xda\xf3\x91\x7e\xef\x2a\x62\x06"}, +{{0x79,0x49,0xa9,0x47,0x2f,0x72,0x5c,0xe7,0xc6,0x8d,0x7e,0xa8,0xfc,0x16,0xe1,0x3d,0x9e,0x0e,0x0a,0x58,0xf5,0x8c,0x24,0xf9,0x22,0x8c,0x88,0xe8,0x02,0x64,0x09,0x0d,},{0xa3,0x70,0xf8,0x28,0x33,0xf8,0x8b,0x4f,0x5f,0x53,0x10,0xb9,0x18,0xe6,0xaf,0x93,0xbb,0x72,0x4b,0xfb,0xdf,0x3c,0x02,0xc5,0x03,0x78,0x0b,0x2c,0x83,0xab,0x6c,0xc6,},{0xe0,0x28,0x98,0xcc,0x7c,0x30,0xee,0x01,0x64,0x82,0x47,0x49,0x7b,0xe8,0xa9,0xc6,0x37,0x85,0x93,0xdc,0x88,0x20,0xbf,0x7c,0x17,0xff,0xcd,0x18,0x11,0x8a,0xf0,0x98,0x79,0xa7,0x69,0xf5,0x39,0xdd,0x92,0x37,0xe9,0x68,0x21,0x16,0x66,0x34,0x99,0x8f,0x94,0x6d,0xa6,0x5e,0x6d,0xba,0xd8,0x27,0x15,0x11,0x66,0x9e,0x2d,0x6c,0xad,0x02,},"\x95\x53\x86\xb9\x2d\xd6\xbf\x92\x60\x1b\xf8\x1e\x84\xd2\x51\x44\xb5\xfc\x0b\xcd\x7d\x23\xc7\x6e\x7d\xeb\x5f\x5b\xa6\x31\x6b\xb6\x1a\x5d\x8e\x74\x18\x5b\x01\x29\x67\xf0\xa4\x43\x8b\x53\x16\x96\xde\xb4\xb8\x10\x10\x89\xe0\xc0\x48\x2a\xdf\x13\xc0\x61\x31\x91\xb9\x77\xf7\x7b\x04\x19\x81\x41\x47\xf5\xda\x64\xa1\xd3\xbe\xb1\x27\x5b\x98\x49\xd1\x29\x7b\xa8\x53\x2a\xe0\xa6\x47\xa8\xac\xe3\x95\xae\x0e\xd0\x0f\x67\x34\x8c\x5e\xe5\xea\x19\xb5\xf1\xc5\xbd\x2e\x62\x28\x18\xe8\xad\xcb\xa3\xc1\x7c\x27\x98\x7e\x4e\x3d\x6d\x91\x0a\x56\xc7\xe5\x14\x9d\x3f\x55\x74\xfc\x06\x00\x9b\xf4\xdd\x3e\x37\xcf\xe3\xeb\xda\x2c\x21\x16\xd3\x66\xdd\x88\xce\x5e\xa7\x2a\xb3\x87\x49\x05\x85\x44\x3b\x08\x6e\x8a\xa3\x8d\x11\xd3\x82\x0b\x72\xc6\x58\xe4\x63\xcd\xb5\x9c\x53\x93\x01\x1d\x4a\x8f\x4c\xb6\xa1\x95\x22\x93\x04\xe7\x62\x39\xfa\x5e\x8c\x2c\xbe\x0f\x39\xdc\xad\x13\x8a\x0e\xcb\x3c\x51\x57\x9e\xc9\xa1\x20\xa5\x16\x07\xee\xfe\xbf\xa5\x9a\x44\x62\x0e\xa5\xb1\x91\x60\x87\xea\x33\x85\x33\xfc\x13\x2f\xf2\xe4\xa4\x3d\x05\x2f\xd0\x8b\x6b\x1b\x24\xfb\x67\x2f\x73\xc9\xb9\xba\x20\xb7\xc1\xc4\x1e\xa2\x4d\x91\x2d\xe9\xb5\x55\xb6\xe5\x68\x2b\x97\x06\x08\xff\x22\x9a\xd3\x08\x6f\x43\x1f\x9b\xe1\x90\xec\x39\x22\x4b\xa2\xed\x8a\xcb\x4c\x8e\xac\x85\x82\xe2\x3a\xaa\x79\x82\x7c\x44\xe2\x48\xc5\xba\x09\x2d\xda\xc0\xf2\xf7\x96\x84\xaa\x93\xfc\x06\x10\x73\xe1\x82\x1a\x56\xaf\xb9\xbf\xec\x95\x2d\xf2\x71\x9a\x9c\x7a\x40\x3e\x6a\x93\xf7\xa6\x56\xd7\x4b\x61\xc1\xd1\x90\x83\xf8\xd3\xf1\x9e\x65\x9f\xa2\xb7\x18\xe0\xbd\x04\xb6\x93\xd6\x3d\xaf\xb8\x6a\xdb\xee\x5d\x87\xc7\x5b\x7d\x12\x91\x22\xf1\x78\xa0\xe6\x69\xeb\x03\x5c\xa4\xd8\xeb\x45\x39\x7f\x18\x51\x26\x4e\x2c\xf0\xa0\xcd\xd3\x07\x20\xc5\xe1\x39\xcd\x6a\x57\x3f\x1f\xa2\x41\xca\xe9\x42\x58\x05\xac\x79\x60\x3e\x8d\xe3\x50\xef\xdb\x0b\x9b\xc9\x5b\xa7\xb0\x85\xc1\xed\x92\xc1\x2a\xcf\x53\xf5\xd4\xa1\x13\x75\x98\x00\x8f\x2a\x36\x72\xc8\x4e\x5f\x76\x9a\x25\xc7\xa4\xa1\x65\x79\xd8\x62\x88\x77\x49\x72\x60\x6e\x4e\x7d\x85\x26\x3a\xd2\x17\xe0\xdb\xcf\x34\x3f\xe5\x54\xc1\x09\xc5\xd9\x40\x9b\x79\x39\x07\x3a\xc5\x5a\x03\x42\x0f\xec\x28\x9b\x11\x4a\x5c\x54\xc2\x0b\x45\xea\x69\x93\x85\x33\xad\xe7\xb3\xae\x85\xe1\xa7\x83\xdd\x97\x89\x7c\x3a\xe8\x25\x41\x83\xcc\x54\x04\x5c\x2a\x18\xec\xbe\x52\x16\x91\xf2\x61\x9d\x9b\x8f\x1f\xb3\x47\xca\x05\x5a\x7b\x0b\x4c\x24\xf6\x4d\x17\x73\xe0\x14\x16\x44\x1e\xfe\x15\x99\x23\x21\x7a\x84\x87\x4b\x9c\x4e\xc2\x65\xcd\xaa\xb6\x43\x90\x80\x68\x49\x78\x12\xc1\xaf\x15\xc1\x88\x07\x1e\x78\xf5\x97\xfe\xdf\xce\x91\xc5\xd4\xc6"}, +{{0xd6,0x8a,0x5e,0x3c,0x47,0xee,0xdb,0x30,0x99,0xdf,0xfc,0x80,0x4c,0xf1,0x9c,0x5e,0x74,0xbf,0x7b,0xf5,0xf0,0x1f,0x54,0xd4,0xd9,0x1d,0x75,0x74,0xf3,0xd3,0xdc,0x7c,},{0x46,0x46,0x7f,0xe9,0xce,0x3a,0xcf,0xd0,0xd7,0x43,0x46,0xbe,0x21,0xc4,0x62,0x16,0xdb,0x81,0xae,0xce,0x6c,0xe0,0x30,0x8f,0xb8,0xdc,0x63,0x86,0xfc,0x34,0x46,0xcf,},{0x89,0x6f,0xc3,0xca,0xba,0x7f,0xd3,0xfc,0x28,0x5d,0x5e,0xdd,0xdd,0xc0,0x12,0x0c,0xd4,0x6d,0xa7,0xc6,0xef,0xab,0xe6,0x6b,0x15,0x0b,0x00,0x27,0x60,0xb8,0x41,0x4a,0x89,0xac,0x9e,0x7f,0x1f,0x7b,0x7c,0x7b,0x33,0x59,0x8f,0x61,0xf4,0x57,0x18,0xe4,0xff,0x4a,0xc3,0x68,0xff,0x12,0x96,0x14,0xb4,0xfe,0x92,0x19,0xf2,0x37,0xb0,0x09,},"\x59\x6c\x03\xd0\x87\x3f\x57\x2f\x45\xc3\xb1\x6f\x0e\xf4\xb5\x2a\xd2\xbf\x59\xec\x76\xd3\xc0\xe5\x34\xd6\x2c\x1f\x84\x16\x4d\xda\xa4\x25\xfb\x85\xc9\x54\x84\x85\xb7\x06\x46\x77\xe9\x9d\x04\xc3\x9b\x6e\xba\x04\xc9\x66\x39\x7b\xa6\xa5\xf4\xeb\xaa\x69\xa2\x41\xdf\x95\xa6\xe4\x45\x02\x50\x9d\x63\x50\x55\x7e\xbf\xea\x60\x26\x4b\x62\xad\x7f\x74\xd1\x6e\x5d\x25\xd4\x59\x70\xcf\xeb\xeb\x33\xe7\xb1\xba\xc3\x34\x8d\xd0\x3a\x8e\x99\x13\x3b\x26\xbb\xfd\x7a\xa7\x22\xc2\x58\x7f\x72\xd5\x52\x6e\x98\x0d\xa9\xee\xbd\xf1\x08\x21\x1d\xae\x50\xbb\xe8\xc6\x5f\x9a\xbe\xe6\x9a\x1b\xbf\x84\xc0\x3e\x40\x44\x8b\xab\xad\x03\xd3\xcf\x3b\x7d\xe4\x88\x7d\x2b\x47\x73\x77\x02\x79\x64\x82\xd2\x26\x5c\x56\x6b\x0f\x62\x3b\x53\xc8\x67\x1b\xd3\x71\x9e\xde\xc0\xff\xd5\xf4\x9b\x49\xb0\x72\xc1\x56\x4a\x57\xf9\xba\xb6\xb9\x2d\x1f\x06\x8d\x75\x66\x39\xa4\x33\x14\x52\xe6\x1a\xa7\xb2\x18\xa8\x8b\x9d\xb7\x7a\x19\xfb\x82\xf1\x3e\x98\x68\xed\xb7\x98\xd5\xbe\xec\xa5\x5d\x1a\xb0\x95\xb3\x16\x22\x5f\x3f\x63\x90\xf8\x95\x78\xf0\x16\x04\x28\x74\x7b\xcd\x21\xbe\x6a\xe1\xd8\x69\x91\xb4\x8e\xf8\x0d\x56\x92\x50\x85\x8f\xeb\xf3\x27\x6b\xd5\xde\x3d\xb6\x5a\x24\x5c\x8b\xdc\xf1\x48\x8c\x48\x25\x96\x89\x45\x78\x6b\xed\x63\xf3\xd1\x3f\x14\x09\x36\x3b\x94\x85\x60\x47\x68\x58\xb3\x96\xbc\xe5\x88\xe4\x0b\x31\x1d\xdf\xc2\x2a\xd6\x22\xca\x7d\x1e\x69\x56\x14\x64\xdd\xa5\x00\x9e\x63\x8a\xa5\xec\x9f\x4c\x03\x92\x93\xaa\xec\x75\x00\x1f\xfc\x68\xa7\xcb\x3a\xe0\x18\x74\xdc\x7f\x39\xd7\x50\x27\xf5\x9a\x28\x96\x5f\xc1\x95\x30\xc0\x75\x2f\xe9\x9b\x15\x3d\xa7\xc0\xe5\x42\xbd\xa7\x6c\xa1\xe1\x0b\x7e\xa1\x58\xef\xb4\xd8\x21\xfb\xc6\x5e\x72\x71\xad\x99\x41\x09\x53\x15\x44\x7a\xbc\xad\x08\x80\xa0\x07\x5d\xd0\x4b\x13\x25\xc7\x26\x33\xac\xbc\xb2\x61\xfc\xb4\x07\xc2\x64\xa3\x4d\x70\xbf\x1f\x04\x4f\xee\xad\x06\x9a\xf5\xa8\x7d\xd3\x52\xf4\xbd\x81\x10\xfa\x17\x8a\xdb\xd8\xdb\xf2\x3c\x6b\x57\x5c\xdd\x5d\xf2\x2c\xc9\xa5\xcd\xd3\x7d\x9c\x8f\xaa\xb8\x1a\x4c\xb3\xfb\x5c\x4f\xe7\xff\x62\x9d\xba\xa9\xfc\x06\xb8\x0c\x1f\xb6\x91\xc2\x86\x55\x95\x5c\xfe\x5c\xa4\x41\x49\xb1\x50\xb3\xcf\x14\x0d\x9a\xca\xcb\x14\x31\x3a\x72\xc8\x40\x98\xde\x72\xba\xcc\x02\x72\xd7\x9e\xd6\x61\x7f\x72\xde\xc8\x8e\x19\xb8\x44\x25\x49\x2a\x42\x9e\xc6\xd2\xec\x08\xb8\x63\x46\xdf\xbf\x20\xea\x2a\x36\x19\xe7\x7b\x6a\xc6\x42\x30\xeb\xe2\x5f\xa0\x06\x7a\xbb\x5f\x33\xee\x49\xad\xc7\xc4\x4b\xda\x70\x46\xd7\xf2\x24\xf2\xe7\xa4\x89\x56\x83\xfc\xa8\x68\x4e\xd6\xa0\x31\x84\x4f\x57\x86\xbc\xda\x48\xb5\x04\x23\x94\x48\x7b\x52\x40\x2a\x09\x90\x77\x88\xa1\xe1\x40"}, +{{0x31,0xe8,0x2b,0xc1,0xcc,0x5c,0xed,0x21,0xcd,0xc8,0xbf,0xc2,0xdb,0xbb,0x97,0x6b,0x08,0x78,0x0a,0xfc,0x69,0x44,0xaf,0x7e,0x88,0xe5,0x0e,0x67,0x87,0x4d,0x84,0xf1,},{0x8d,0xf9,0x77,0xe2,0xb0,0x40,0xac,0xeb,0xd3,0xda,0xfd,0x67,0xb8,0x7f,0x92,0x16,0xe8,0xc3,0x71,0xbe,0xce,0xd6,0x18,0xfe,0xf3,0xa4,0x96,0xd6,0x51,0xa5,0xd7,0xb5,},{0x24,0x07,0x02,0xac,0x6c,0x68,0xd5,0x97,0xd2,0x22,0xda,0x94,0x9d,0x0c,0x47,0xd1,0x6b,0x39,0x0a,0x47,0x7d,0x1f,0xb5,0x79,0xe9,0xd8,0x94,0x8a,0xdf,0x9b,0x3b,0x6a,0x7f,0xd4,0x45,0x8a,0xe6,0x38,0x5b,0x7e,0x2b,0x68,0x4a,0x05,0xb5,0x5c,0x63,0xfa,0x6c,0xd0,0x87,0xbb,0x90,0x11,0x3c,0xba,0xb8,0xe4,0xaf,0x14,0x2f,0xcf,0x81,0x0e,},"\x69\xd4\x61\xb6\xb7\xa8\x66\xe9\x4c\xd5\x9a\x5a\x23\xbb\xa4\xa1\x27\x66\x02\xf0\x42\xba\xa8\x50\xd5\xb2\x92\x49\xd6\x74\x3a\xda\x04\xd3\xd9\x38\x21\x9a\xbb\xc2\x2a\xda\x66\xa1\x77\x81\x97\xf7\x0b\xf8\x0b\x59\x7a\x8b\x4a\xe0\x0b\xdb\x87\x68\x12\xd3\xab\x4e\xc0\x11\xdf\x73\x34\x1c\x85\x05\x3e\xeb\xcc\x2d\xf0\xac\xfc\x21\x54\x82\x83\xb5\x53\xec\xde\x01\x54\x82\x8e\xd5\xaf\x47\x57\x19\x85\xf8\x97\x67\xb0\x05\xb6\x22\xc9\xe7\xc0\x79\xdd\xe6\x94\xe4\x9d\xc0\x55\x0c\x79\x18\xcc\x51\x5c\x27\x4d\xbd\x9c\x54\x69\xd2\xf1\x8e\xcd\x90\xde\x66\x4e\x03\xca\x41\xe5\x3b\xe2\x0b\x96\xe2\x5a\xf4\x0c\x54\xab\x0f\x7c\xbe\x9e\x05\xca\x3f\xa5\xa3\x7c\x1a\xa8\xeb\xfb\x64\x44\xa3\x2c\x49\x6e\xfc\x68\x15\x7c\x69\xf3\x58\xc1\x5f\x6a\xc0\x9d\x46\xef\xef\x9a\x68\x5d\xf7\xe8\xdd\x63\xb3\x04\xbd\x3c\x63\x8c\xcf\x53\x2f\xe9\x01\xf1\x1c\xf9\x7c\x5b\x1c\xbe\xd3\x3c\x70\x63\x7c\x72\x1b\x02\x89\xad\xf6\xbb\x6d\x87\xc3\x04\x79\xfa\x92\x6e\x04\x30\x74\x30\x2b\x76\xf1\x15\x7d\x0a\x81\xde\xc4\x93\xe8\x7a\x3c\x64\x3e\x7a\x20\xb7\xa4\x15\x25\xa3\x8d\xb0\x4e\x78\xda\xe5\xe7\x79\x70\x66\xbf\xae\x2c\xf4\x48\xa4\x47\xe9\x00\x4c\xce\x8e\x41\xf0\x98\x79\x91\xfa\xd3\x03\x11\xdd\xaa\x45\x9a\x26\x44\xf4\xb9\x41\xc0\x68\xc0\xd6\xc0\x77\x1a\xfc\xf4\x2b\xf9\x13\x9a\x68\x4d\xa2\x98\x48\x6e\xcf\x67\x52\x3b\xf8\x50\x9a\x45\xba\x5c\xb8\xb3\x86\x4a\xd2\x2c\x0c\x6a\x82\x8c\x6d\xb7\x2e\x37\x1d\xe4\x10\xb4\x7d\xac\x49\xae\x9d\x3b\x57\x02\xb1\x73\x9b\x8d\x76\x0c\xe9\x86\x11\xc0\x7d\x88\xdf\x5f\x04\x68\x38\x08\xa2\x1a\xfc\x2e\x61\x71\x3f\xc2\xc0\x25\xcb\x25\xfc\xc4\xee\x94\x18\x41\x08\x3b\x22\xf6\x1e\x26\x56\xfb\x3b\x8d\xad\x41\xc2\x62\xc8\x9d\x2f\x17\x61\x03\x09\xf2\xd5\xc2\x95\x89\xa2\xdf\x61\xe5\x51\x49\x89\x50\x32\xca\x98\x1e\x45\x57\xe1\x30\xa2\x37\xfc\x08\x26\xfc\x87\x25\x29\x86\x1b\xbb\x83\x28\xd6\x73\xf3\x9b\x58\xb7\x3d\x06\x0e\xc5\x96\xbf\x22\xe7\xee\x08\x1f\x44\xe9\x2c\x02\xa5\x67\x76\x79\x52\x0e\x2a\x2b\x4d\x22\xc7\x7f\x2b\x21\x2d\x5a\xaf\x05\x0b\xf2\xc1\x41\xe3\xe2\x8b\x85\x71\xd4\x32\x19\x37\x42\x62\x35\xc7\xa6\x46\xd6\x47\xe3\xef\xe1\x83\xc2\x7b\x74\x92\x56\x5e\xca\xcd\x7f\x43\xc6\x7a\x74\x45\x3f\x47\x80\xe8\x87\x11\xba\x2d\xd4\xa3\x94\x1b\x12\xdd\xd3\x90\x92\x70\xfb\x3d\xeb\xd4\x22\x43\x6a\xb6\x16\x6f\x08\xc9\x9c\x88\x6c\xc0\xe8\xe3\xce\xcd\x06\x42\xe4\x42\x85\xb8\x86\x4a\xa4\x16\x94\x3c\x5a\x18\x69\x74\xf4\x64\x53\x5a\x87\x0a\x01\x28\x61\xbc\x2e\x58\x71\x49\xca\xe9\x71\x62\x4e\x61\xc3\x1d\x8a\x50\x7e\x3a\xd8\x27\x73\xe7\x23\xbc\xb7\x5d\xf5\x4b\xef\x84\x7a\x40\x7b\xcb\x7b\x1d\x57"}, +{{0xcc,0x56,0xbc,0x7c,0xdf,0xa6,0x11,0x92,0x4e,0x72,0xb0,0x7f,0x68,0xab,0xc6,0xca,0x5b,0x85,0xff,0x8b,0xba,0xcd,0xff,0x40,0x6e,0x51,0xba,0x72,0x0d,0x09,0xa8,0x66,},{0x5f,0xfe,0xe2,0x21,0xab,0x4d,0x0f,0xe6,0xf4,0xc9,0x34,0x6c,0x5e,0x5a,0x4b,0x8a,0x63,0x6a,0x6a,0x0b,0xad,0xce,0x96,0x67,0xbe,0x73,0x9f,0x4c,0x9e,0x67,0x33,0xc1,},{0x9b,0x86,0xa1,0x92,0xb6,0x4f,0x4f,0x04,0x4f,0xfb,0xf8,0x7b,0x41,0xc7,0xee,0x52,0xf7,0xa7,0x21,0xaa,0x32,0x0e,0x7b,0xad,0x64,0x25,0x99,0x59,0x90,0x31,0x5c,0xdd,0x50,0x2b,0xe4,0xe1,0x11,0x60,0x19,0xd1,0x31,0xa9,0x21,0x8d,0x19,0x61,0x4a,0xd9,0x55,0x43,0xb1,0x88,0x9a,0xf0,0xa9,0x7e,0xd4,0xd2,0x56,0xdc,0x33,0xd7,0x6e,0x08,},"\x08\x83\x04\xf2\x2e\x1a\x28\x60\x62\xde\xfb\xeb\xb1\x82\x7a\x64\xb7\x6a\x14\xe8\x70\x15\xe7\xf6\x46\x17\x87\x77\xab\xa7\x97\x04\x68\x8d\x7b\xf3\x2e\x1e\xfa\xc9\x7a\x9f\xc3\x39\x81\x0e\xbd\x3d\xf9\x3e\x4e\xa0\x24\x68\x69\x53\xed\x91\xfa\x6d\x2a\xb6\xe0\x7e\xc7\x81\x1a\x6d\x91\xca\x91\xb0\x98\xdb\x47\x25\xdf\x65\x84\x6a\x95\xb8\x08\x63\x5a\x8d\x0c\x5f\xe5\xac\xe2\x5f\x07\x80\xe8\x96\x17\x7b\xc1\xbb\xa1\xcd\xb4\x44\x92\x51\xc0\x1b\x48\x2f\x02\x38\x62\xf8\x8e\x07\x2e\x79\xcd\xe5\xdb\xd6\xc1\xd9\xad\x9c\x07\xc6\x06\xf5\xdf\x85\xa6\xec\xa2\x96\x6c\xbf\xe0\xa1\x67\x39\x68\x11\x2f\x26\xa3\x17\x05\x3f\x16\x7f\x61\x1a\xf2\x97\xef\xa8\x02\xe0\xa9\x4b\x3e\x1f\x33\xa2\x7b\x73\xe5\x59\x7a\xbb\x22\x41\x15\xeb\xe7\x5e\x29\x4a\x1b\xcd\xcd\x97\x92\x55\xb0\xa8\x02\x65\xc0\x89\xaa\xa7\xd6\xbe\xd2\xe3\xd0\xc9\x18\xf5\x6f\x4a\x55\xf4\x48\xd8\x63\x36\x5c\x6c\x58\x46\xfb\x9b\x2b\x9b\xb5\x5f\x6b\x7c\x6d\xff\x58\x47\xb7\x1b\xfd\xd4\xbb\x5b\x9b\xb2\xe4\x24\x9b\xc0\x24\x3a\x02\xab\x4d\x22\xba\x78\xa4\x3d\x18\x21\x95\xae\xd7\x8f\xec\xe8\x4c\xb1\xdd\xae\xb9\xef\xf6\x81\x56\x04\x5b\x29\x32\xe6\x38\xd7\x73\x1d\x0e\x8b\x4c\x9c\x8c\x38\x3b\x0d\x6d\x39\x2d\x21\xfc\x64\x07\x62\xc8\x7d\x36\x92\xb1\x81\x0b\xcc\x4a\x42\x39\x2f\xf1\x3d\x45\x16\x9e\xcb\xf0\x13\x50\x55\x09\x31\x05\x09\x8c\x86\x9b\x68\x88\x7e\x93\x4e\x2b\x9d\xa5\x23\x2a\xc6\xc9\x37\x38\x00\xf7\x0b\x64\xec\x64\xa4\xaa\x0c\xa0\x44\xc0\x77\x7c\xa3\xa3\xac\xaa\x13\x8c\x14\x24\x96\x72\xa5\x5b\x24\xdd\xfe\x4d\xc3\x57\x57\x32\x41\xe1\x4a\xd0\xac\x16\x47\x5a\x8e\x38\x67\x88\x6d\x41\xee\xa3\x5f\xe7\x93\x2b\xa9\xae\xaa\x0c\x86\xc9\xeb\x6d\xb7\x80\x80\x49\xad\xe7\xb5\xcc\x1a\x40\x82\x2c\x66\xde\xa9\x3a\xd2\x2d\x44\xb9\xe4\x29\x04\xb5\xb8\x36\x84\xae\x29\x31\xfe\x36\xc6\x08\xff\x70\x96\xf1\xb0\x9f\x81\x1b\x02\x67\x28\x04\x40\x6e\x08\xed\x9e\x77\x45\x67\x6c\xe0\x47\xf0\xf7\xf6\x47\x08\xe4\x9b\xb7\x87\x54\x72\x0b\x8a\xa2\x26\xf5\x55\x6a\xbf\x05\xb5\x65\x84\x64\x52\x92\xda\xd0\x8e\x24\x73\x63\x9a\x8c\xe5\x47\x5e\x0c\xe9\x19\x2f\x8b\xa2\xdd\x32\xce\x14\xc9\x19\x75\xab\x60\x2f\x7c\x13\x53\x8c\x52\x95\x2d\x03\x96\x15\x8c\x7c\xc6\xb9\x42\xbe\x7d\x92\x3e\xeb\x52\x3a\x73\xb5\xb4\x11\x96\x6d\x14\xac\x96\xe5\xb0\x96\xa5\x29\x32\xa4\x16\x29\x2e\xcc\xdd\xb9\x10\x71\xc8\x85\x60\xe7\x0e\xcd\x4f\xe2\xfe\x24\xd5\x23\xfa\xfc\xb9\x8e\x40\x21\x50\x2f\x41\x90\xa0\x51\x5e\xdc\xb2\x40\x19\xea\xca\x09\xec\x26\x15\xa9\xbf\xde\xb6\x0e\xb3\x54\xc8\x4a\x1f\x3c\xec\x7f\xfd\x7e\x65\xa5\x51\x5d\x47\x95\x9a\x4c\x4e\xc4\x8d\x80\x21\xb1\x75\x4a\xe2\xbf\x84"}, +{{0x7a,0x57,0xf2,0xdd,0xa0,0xad,0x03,0x38,0xab,0x9a,0x13,0xc9,0xa3,0x49,0x7e,0x9c,0x75,0x23,0x8c,0x15,0x31,0x58,0x97,0x89,0x22,0x7c,0xd2,0x74,0x9b,0xc6,0xe9,0x50,},{0x6f,0x73,0x8d,0xc5,0xe7,0xd9,0xe2,0x40,0xc9,0xf4,0xd0,0xc0,0x6a,0x5e,0x02,0x17,0x47,0x56,0x8b,0x69,0xa7,0x5d,0x50,0x7a,0x2e,0x0b,0xe7,0xea,0x61,0x35,0x26,0xc5,},{0x98,0x91,0x23,0x76,0x1d,0x93,0x56,0x32,0x78,0xfd,0x0a,0x78,0xae,0xd6,0x4e,0x2d,0xe6,0xf4,0xa7,0x00,0xfc,0x9a,0x70,0xd2,0x18,0x77,0x48,0xac,0x06,0xd9,0xc2,0xc3,0x77,0xd1,0x99,0x5f,0x89,0xc7,0x72,0x7f,0xe2,0xf1,0x20,0x78,0x4e,0x41,0x71,0xc4,0x2d,0x63,0x53,0xac,0x3d,0x4e,0x3f,0x62,0x0c,0x63,0x9c,0x75,0x78,0x6c,0x46,0x0a,},"\x8c\x85\x75\xa1\x1d\x2f\xf2\xc2\x38\xe4\x19\xcc\xb0\x06\x33\xd0\x4e\x8b\x8b\xd7\x74\x29\x01\xd5\x88\xdd\x6a\x2f\x00\xaa\x12\xf0\x8a\xe4\x1d\xca\xa9\x33\x8f\x8c\x47\xe9\x53\x12\x19\x2c\xf6\xb2\x45\xa0\x0c\xe6\x88\xa0\x29\xda\x56\xdd\x1b\x1d\xeb\x0d\x34\xb5\x41\x4f\xe1\xc2\x1d\x6b\x63\xd0\x6b\x85\x34\xac\xe8\xe8\x66\xc9\x33\xfd\x7c\x5a\x65\xed\xa9\x5a\x17\x37\xa9\xec\xdb\x17\x85\x91\x49\xac\x69\x69\x51\xb8\x2c\x23\x0e\x82\x75\xe9\x6d\xd0\x2f\xd4\x55\xea\x67\x53\x79\xe6\x7b\xa6\x34\x84\xb6\x28\x38\x31\xfe\x3f\xfe\x52\xd6\xec\x49\xb7\x09\x10\x67\x05\xc9\xd1\x9b\x85\x9d\xe9\xfd\x20\x08\x87\xcb\x44\xd8\xfd\xfe\x69\x61\xfa\x4c\xa2\x34\x09\x44\xc7\x64\xc7\x04\x49\x12\x08\x25\x7e\x73\x54\x82\xaf\x8c\xb6\x90\x41\xdd\xe6\x85\x24\x1d\x3f\xbf\x46\xfd\xa0\x57\x24\x8b\x89\x87\xbe\x1f\x80\xb5\x4e\xb5\x40\x09\xf3\x24\xdc\x45\x0e\x88\x6e\x79\xf9\x12\x58\x5b\x91\xc9\xdf\xaf\xe9\x01\x22\x62\xc4\x71\x40\x3b\x1e\x8b\x5c\x31\xfc\x53\x75\xa1\xdd\xf9\x9b\x68\xed\xf9\xed\x70\xaf\x85\x94\xf7\xd8\x4b\x2c\xc4\x91\x1f\xe9\x05\x00\xc6\xee\xbf\xba\xc0\x85\x55\x35\x50\xe3\x5b\xd2\xe5\x25\x14\xe9\x79\xe7\x24\x1e\x9f\x8e\x34\xcd\xf8\x51\x3a\xbe\x72\x51\x0d\xff\x3c\xfe\xc7\xe2\xbc\x64\x88\x64\x1c\xfd\x0a\x65\xae\x0e\x09\xeb\xe9\x9b\x15\xb2\x9d\x45\xea\x67\xa5\x7a\xad\x55\x4d\x4f\x8b\xfc\xe1\x38\x6a\xce\x22\x88\x39\xe3\xa8\xa5\x34\x14\x0e\xec\x3d\x37\xd5\x1b\xe3\x61\xf5\xea\x18\x83\x73\x9f\x56\x61\x5f\x75\xb0\x55\xa0\x6a\x91\x47\x1b\xe9\x8b\xc9\x45\x37\x83\xc3\x58\x38\x2b\xd0\x55\x5a\xe9\xeb\x0b\xdc\xd6\x66\x29\xa6\x11\xfc\x1a\x11\xc6\x53\xc8\x22\x14\x58\x7d\xec\x12\xba\x12\x0e\x25\x13\x07\x0f\xe6\x9e\x98\x2f\x7a\x80\xad\x15\x9f\x6a\x32\x5d\x97\x7d\x01\xd0\x50\xd1\x16\xa6\x2a\x4f\x8a\xca\xb6\xc3\xd6\x9f\xf6\xc8\x78\x21\x3c\x60\xa9\x48\x45\xca\xe1\x06\xde\x6c\x5d\x6f\xe2\x50\x8d\x94\x56\x5b\x7b\xa7\x5d\x58\xd1\xad\x47\xd7\x6a\x20\xde\xfa\x75\x68\xcb\x7f\xd6\x6f\x57\xcf\x37\x74\xa2\x1d\x3f\xfa\x7d\x8a\xa6\xd8\x6d\xc2\x84\xb7\x0e\x0f\x17\xe7\x63\x0b\xfc\x10\xcd\x1f\xc9\xa8\xd9\xc5\x92\xd3\x9f\x24\xa7\xb5\xc8\xe8\xaf\xf3\x53\x57\x7e\x6a\xc9\x00\x86\x90\xc7\xa1\x59\xa7\xe8\x3b\xe5\xa6\xae\x8f\xca\x96\x44\xbd\xdf\xa3\x7a\x92\xb0\x70\x55\xf9\xfa\xc9\xfa\x97\xfb\x3e\x8f\x5f\x4d\x91\x7d\xda\x5c\x6d\xc6\xea\x34\xb6\x4d\x30\x24\x05\xbc\x38\x06\x2e\x07\xce\x93\xa1\xa8\x8a\xed\x5f\xba\xf9\x95\xa0\x9b\x45\xb2\x8a\xd4\xa6\xb2\x73\xde\xc1\x41\x3c\x54\x04\x52\x9d\x82\x5b\x5e\xdc\x2e\x27\xa3\x90\xeb\x7e\x8c\x2b\x43\x90\x5e\x11\x6d\x88\x7a\xb5\xfb\x99\x3d\xfe\x15\x0e\xbd\xcf\x81\x7a\xe6\x2e\x03"}, +{{0x32,0xef,0x6d,0x78,0x9a,0x1e,0xa3,0x93,0xf1,0xbf,0x9f,0x11,0xde,0x34,0xf5,0x7d,0x65,0x3c,0x4e,0x77,0xd5,0x1e,0x60,0x50,0xfe,0xf4,0xe8,0xd7,0xbf,0x18,0x3d,0xb5,},{0xc1,0xaa,0x18,0x1e,0x62,0x0f,0x60,0x52,0x5c,0x2b,0x17,0xda,0x8d,0x29,0x0b,0xae,0x5d,0x33,0x9e,0x17,0xea,0xbc,0xea,0xb5,0x8c,0xd7,0x6a,0xe0,0x66,0xf4,0x11,0x79,},{0x88,0xf3,0xa6,0xe0,0xbb,0xaa,0x3e,0x06,0x0b,0xc9,0xd9,0x1f,0xe2,0x96,0x8c,0x61,0x12,0x6b,0x20,0x31,0x7f,0x59,0x84,0x2e,0x4a,0xe4,0x87,0x11,0xcd,0xba,0xf6,0x2c,0x6c,0x02,0x07,0x40,0x5d,0x1c,0x48,0x49,0x95,0x02,0x71,0xf0,0xaa,0xa7,0x59,0x30,0x91,0x10,0x9e,0x47,0x8d,0x13,0xf3,0x56,0x96,0x4f,0x7d,0xba,0xb7,0x29,0xaf,0x00,},"\x11\xa9\xc3\xc1\xba\x7c\xfb\x61\xad\x10\x33\x05\xc2\x58\x86\xde\x9f\x88\x15\xc6\xc2\x1f\x17\xa8\x73\x3a\x02\x4f\x94\x97\xda\x05\x40\xdb\x36\x03\xa6\x71\xaa\xe8\x37\xdb\xbb\xa1\x9e\x19\xf8\x2d\xdf\xc8\xaf\x85\x59\x80\xa7\x01\x25\xfc\x61\xcd\x7f\xfd\x10\x77\x7e\x36\x6e\x5e\x95\x69\x92\x7a\xf0\xf2\x45\xd4\xf3\x9b\x3f\xd0\xf4\x58\x79\xc2\x53\x40\x14\x12\x85\x5e\x57\x61\x90\x5e\xd6\xef\x31\x8b\x6a\x06\xea\x6e\x9f\x90\x6f\x9b\xd0\x16\xbc\xb6\x94\xa0\xdf\x65\xa0\x16\xbd\xfe\x84\x5a\x09\xf2\x3e\x50\x86\xc5\xaa\xf3\x75\xef\xeb\x86\xda\x51\x23\x9d\xdc\x35\x0b\xac\x0c\xdb\x03\xb8\x74\xdb\x15\x07\xe6\xad\x4e\x2c\x9f\x46\x02\x8c\xa2\x38\x83\x63\x54\x14\x93\xb6\xcb\x92\xc1\xdf\xca\xa3\xef\xd6\x8c\x6b\x4e\x91\xef\xb4\x67\x51\xd2\x3f\x4c\x48\xa9\x73\xf0\xa5\xc7\xc6\xfe\x2a\x12\x69\xd2\xa6\x9e\x9f\xc4\xab\x8b\xa3\xb9\x2f\x79\x64\x49\xba\x3d\xc7\x02\x45\xed\x50\x5c\xc0\xee\xee\x16\x36\x64\x7a\x68\xc7\x67\x9d\x0b\x6d\x65\x1b\xba\x35\xc2\x9b\x81\x47\x8d\x17\xca\x36\x85\x70\x7a\xd6\x16\xe6\xe5\x60\x43\x81\xf8\x4e\xe5\x2b\x25\xad\x02\xfc\x0d\xfb\x85\x43\x2e\xfb\x1f\xec\xd0\x90\xc0\x2a\xd0\x02\xc1\x85\x7f\xce\xd8\x8f\xdf\xb2\xff\x26\xdd\x0f\x50\x18\xfb\x47\xd8\x13\x58\x1f\x65\x08\xca\x63\x7c\x73\x65\x17\x7c\x51\x3d\x1e\xe0\x58\x79\xa6\x5c\x5b\x67\x6b\x3a\xa8\x73\xa1\x93\x5c\x54\x37\xea\xdc\xb6\x6d\xfb\x05\x2a\x5e\x7c\x3e\x81\xd4\x4b\x3d\xaf\x69\x8f\x42\x24\x4e\xe2\xee\x4b\x6e\xd2\xb7\xe6\xe5\x6e\x61\xff\x9c\xb4\x5e\x71\x9f\xd7\x46\x19\x8b\xf2\xa7\xde\x6d\x25\xaf\x3b\xc6\xc7\xb0\xed\x8a\xbe\x3c\xb3\x89\xaf\xd8\x4f\xfa\x2a\x23\x0d\x93\xbc\x0c\x29\xd5\xa9\x41\x9c\xbf\xf1\x1b\x78\x83\x32\x99\x21\x48\x0b\x58\x44\x65\x5d\x99\x6c\x7c\xab\x29\xdf\xb2\xa3\x92\x7b\x82\xba\x7c\x30\x6c\x45\x77\xb6\xf8\xb5\xdb\xe2\xaf\xaf\x9b\xf1\x4a\x8f\x95\x54\xcd\x01\xa6\x9a\x99\x1b\xf2\x12\x82\x8d\xe1\xe6\x31\x72\xe8\x33\xde\x06\x69\x8c\xdb\x3b\x28\x71\x63\x80\x31\x45\x72\xbf\x5b\xcf\xd3\x4e\xf5\x2a\x6f\xad\xda\x87\xba\xbe\x6b\xac\xdb\x20\xce\x63\xc7\x25\xcb\x0f\xf6\x1f\xe3\x0c\x1b\x51\xdb\xda\x2c\x26\x25\xf9\x9d\xfe\xb0\x29\xa3\xe5\x8c\xba\x7d\x01\x90\x51\x11\xca\xf4\x2f\x27\x02\x5e\x72\x0e\x18\xee\xb0\x7d\xae\x91\x55\xc5\x5a\xa3\x00\xe2\x2e\xb5\xe9\x4d\xc7\xa0\xa8\x4e\xe6\x7d\x91\xa9\x60\xae\x08\xca\x63\x2d\xbb\x17\x37\xfc\x9a\x43\xdb\xcf\xb3\xa8\x79\xeb\x9f\xbf\xfd\x72\x99\x33\x8e\x26\x4b\xc1\x23\x7a\xb6\xa5\xbc\x2a\x26\x3c\xfa\x99\xe8\x54\x44\x39\xd9\x63\x31\x63\x9f\xe9\x40\x8e\x54\xa3\x50\x61\x0f\xf0\x1d\xe3\xf8\x57\x99\xad\xeb\x73\xd8\x2b\xe9\x38\x07\x4d\xea\x85\x8e\xa6\x36\xb6\x3a\xbd"}, +{{0x0a,0x55,0x25,0xa4,0x59,0x8f,0x60,0x99,0x2f,0x86,0xba,0x1a,0xb9,0xee,0xe6,0xe2,0x67,0x56,0x22,0xf9,0x43,0x28,0x4f,0xc0,0x55,0x3e,0x44,0x46,0xac,0x5a,0x4c,0x53,},{0xdb,0x60,0xd7,0xea,0x29,0xf8,0xd6,0x0d,0xad,0x33,0xd0,0x2e,0xc5,0xf4,0x22,0x32,0x05,0x7b,0xd1,0xc4,0xbd,0x61,0x80,0xa2,0x42,0xcb,0x7a,0xb6,0xf4,0x42,0x67,0x81,},{0x8f,0xa6,0xb0,0xae,0xac,0x71,0x13,0x2a,0xd8,0x82,0x97,0x58,0x68,0xf1,0xbd,0xb8,0xc1,0x1f,0x1a,0x6c,0x1b,0x9c,0x54,0x59,0x4e,0x0e,0x46,0x28,0x6e,0xa6,0xc9,0xa5,0xd6,0xd5,0xb0,0xea,0xea,0xca,0x9a,0xe3,0xaf,0x74,0xe7,0x23,0x26,0xb3,0xb6,0xf2,0xea,0xa8,0x93,0xc0,0xec,0x42,0xa4,0x9c,0x56,0xef,0x51,0x4f,0x75,0xc7,0x7f,0x01,},"\xf7\x87\x32\x1b\x42\xc0\x8d\x40\x52\x44\x9a\x48\x85\x93\xd8\x85\xb4\xe0\xc3\x4a\x5d\x64\x14\x9f\xa8\xb9\xc8\x5e\xe5\x4b\xcb\xec\xb5\x09\x09\xb2\xa8\x6b\x88\x25\x8a\x10\xe0\x7e\x8f\x8c\x2d\x06\x8a\x89\xfb\x16\x5a\x6a\xce\x7e\x64\x99\x8b\xa5\x7d\x89\xd9\xbf\x2b\x8b\x38\xa1\xf6\xd8\x36\x4a\xee\x05\xce\x33\x48\xbe\xd4\x8b\x88\xc2\x47\x3b\xf5\xf2\x66\x5f\x51\xca\x07\x3a\x53\x05\x35\x8e\xaa\xd4\x36\x5d\x58\xb8\x3b\xc9\x81\x4e\x25\xf5\x4c\x37\xcd\x9b\x68\xa8\x08\xa5\x7d\x6c\x2d\x7d\x7b\x6d\xeb\x5f\xe2\x0f\x4f\x96\xfe\x72\x5f\x8d\xe6\x5c\x29\xa4\xf1\xcc\xef\xd7\xc2\xc6\xf2\xfc\x01\x16\xd5\x86\x76\xac\xbc\x58\x69\x1c\x79\xc2\xb0\x06\x78\x5a\x09\x75\xa3\x1d\x8d\x3c\x94\x91\x61\x59\x6a\x06\x8a\xaf\x22\x26\xab\x84\x25\x50\xe9\xc0\xb2\x61\x0a\x29\x53\x1d\x1f\x3f\x7f\x00\x82\x6b\xb6\xc7\xdb\xe0\x4e\x28\xae\x1b\x9f\xf6\xf8\x88\xa4\x9d\x82\x81\x2f\x45\x2e\x1b\x32\x74\x0b\x23\x4d\xdd\x96\x42\xe1\x8f\x32\xad\x9a\x9a\xf7\xf8\x95\x25\x28\x67\x4a\x2c\xda\x25\xb4\xf7\xba\x86\x70\x07\xff\xa7\xf7\x8f\x16\x3d\xb8\xf3\x69\x14\x95\x6b\xfa\xec\xd5\x0f\x6d\x1a\xf4\xee\x13\x32\x75\xa8\xea\xab\x94\xbb\xc0\xae\x52\xb6\xd9\xb2\x83\x26\x34\x23\x2e\xc0\xe8\xb5\xf8\x02\x2d\x3e\xf1\xea\xd9\xb7\x9e\xf9\xa1\x65\x64\x27\x71\x94\xf2\x38\x0d\x90\x21\xe1\xf1\x7b\x18\x4b\x8d\x3a\x7a\x34\xd1\x51\x39\xa3\x9c\x77\x28\xc2\x2e\x1a\x3a\x67\xa2\x7a\x6c\xa4\xb8\xa8\xa0\x63\x6c\x60\x54\xd0\xf7\x41\xf0\x46\x67\x36\x19\xfc\x6b\x07\x0e\x62\xff\x48\x62\xf5\x9d\x26\x90\x07\xf3\x43\x13\x39\x63\x7a\x89\xf5\x64\xc0\xdb\x3d\x9b\xcf\xcd\x19\xfc\x25\x13\x8a\xc6\x6d\x47\x4d\x80\xf4\xad\x79\xf6\xd1\xe7\x84\x44\x08\xe8\x80\x34\xee\xaf\xf4\xa7\x90\x33\x8d\x54\x6b\xfc\xd7\x42\x4c\x11\x9e\x21\x1f\x36\x3c\xb8\x9c\x88\x87\x49\x34\x6a\x89\xd3\x2f\x02\x3b\xb6\xb0\x36\x6a\x1e\xde\x43\x25\x03\x2a\xa3\x5f\x52\xe9\xdf\x93\x8a\x50\x27\xeb\xee\x96\x88\xae\x48\x0d\xde\x1a\x9c\x9b\x42\xd1\xa9\xc0\x8f\x71\x92\x23\xdf\xae\x1c\xfc\xd4\x9d\xd1\x05\x3a\xaa\x38\x1c\x24\xcc\x9c\x7a\xbf\xcf\x8f\x6d\x86\xd6\xaf\x72\xee\xf0\x53\x04\x41\x2f\x3d\xb2\x58\x5a\xa9\xe0\xf3\xa4\xf1\xb6\xd7\x10\xd0\x2a\xb1\x1d\xb1\xfc\x90\xad\x4d\xe2\x5d\x04\x29\x9f\x31\x29\xc2\x12\xe9\xcb\x73\xc0\x04\x79\x53\x45\x5b\xf9\x8e\xc8\xfd\x26\x74\xe4\x7b\x94\x99\x57\xde\xed\xa0\x18\xba\xdc\x9f\x2f\x68\xa1\xb1\x8e\xf5\xc5\x83\xb0\x95\xe0\x8d\xd9\x06\xda\x5f\x22\x0d\xa0\x29\xb9\xc4\x00\xe3\xca\x91\xc7\xcb\xd8\x7f\x34\x30\xc7\x42\x33\x7f\x61\xcf\x54\x74\x5b\x06\x22\xbc\xb9\x07\x62\xc6\xba\xfe\xf8\x7e\x1e\xc8\x88\xc3\x64\xfa\xd6\x46\xc3\x3a\xcc\x22\xaf\x54\x38\xb8\x4c\xd5"}, +{{0x2d,0x5d,0xdf,0xfa,0x2e,0x58,0xc9,0x04,0x51,0xea,0x05,0xde,0x47,0xb8,0xc4,0x92,0x34,0xe2,0x6c,0xed,0x54,0x85,0x4e,0x3a,0xce,0xf1,0x1d,0x8e,0xe6,0x85,0x2d,0xa7,},{0x7b,0xfd,0x1c,0x8a,0x4a,0x0b,0xbb,0x46,0x06,0xd2,0xe5,0xbc,0x09,0x0f,0x56,0xb2,0x0d,0x58,0xf2,0x20,0x4b,0x6a,0xed,0x83,0x1d,0x3d,0xf4,0xd4,0x06,0xb4,0x76,0x05,},{0xce,0xd9,0xd6,0x10,0x10,0x33,0x9c,0x47,0x1d,0xdf,0x9f,0xef,0xca,0xa8,0x2d,0x1e,0xab,0x3a,0x2e,0x0e,0x60,0x27,0x85,0x53,0xb4,0xdd,0x9f,0x39,0x5b,0xe5,0x81,0x49,0xc9,0x15,0x94,0xe5,0x61,0x8b,0x0b,0x10,0xbf,0x3a,0xab,0x94,0xf1,0x59,0xb5,0x30,0xf6,0x44,0x63,0xee,0xd6,0x6f,0xa2,0xac,0xe5,0x4f,0xd9,0x25,0x72,0xa0,0x6a,0x0e,},"\x4f\x1c\x5b\x4e\x6f\xac\x3b\xaa\x3e\x90\x10\xf3\xbf\x29\x3c\x77\x9e\x61\xfd\x7b\xbe\x05\xa5\x86\xf5\xaa\xf0\x80\x26\x37\x16\x27\xa2\x09\xac\xd1\x88\xaf\xb2\xdb\xe0\x31\x15\x47\x94\x05\x59\x71\x16\x40\xf7\x8a\xea\x9a\x62\x81\x89\x62\xf4\x45\xa8\xe7\xed\x6f\xe6\xc5\xf4\x91\x62\xe7\x43\x5d\x1b\x62\x5b\x88\xba\x39\xda\xb0\xad\x56\xfd\x2c\x0a\xd6\x51\x26\x61\x36\x2b\xf7\x8a\xfe\x5a\x14\x16\xb6\x47\xf3\xb8\x8a\x05\x6c\x9e\x72\x89\xc9\xb0\xcc\x3a\xfb\x43\x40\x21\x98\x56\x34\x93\xe7\x37\xb1\xda\x05\x25\x06\xb6\xc9\x30\x6d\x75\xad\x66\x93\xdb\x6d\x15\x71\xf9\x6f\x6f\x52\x99\x0c\x4d\xf1\x96\x65\xa6\xbb\x63\x07\x3f\xdd\x9f\x55\x59\x68\x96\xa2\xe9\xc2\x62\x2f\x2b\x0c\x2c\xc9\x9d\xdd\x1b\x64\x9f\xb0\x31\x80\x58\xd7\x47\x94\xe3\x8e\xc6\x57\xeb\xc8\x2a\xbd\x5b\xed\xf8\xb3\xf4\xbb\xa3\xbb\x6c\x99\x35\xfd\xf6\x82\x65\x02\xb7\x69\x04\x6b\x36\xd9\x6d\xc6\x95\xd7\xc8\x54\x04\x28\x4d\x2a\x2a\xb7\xfc\xf3\xb0\x2f\x68\xa1\x49\x3d\xd3\x83\xca\x63\x39\xfa\xc1\xcd\xe4\x7f\x53\xc5\xe0\x26\xd0\x86\x9f\xaf\xfe\x40\xab\xdb\x98\x19\x52\x30\xf1\x7d\x0c\xfa\xa5\x33\x31\x5a\xfd\xbf\xe7\xd1\xaf\xc3\xa6\x15\xb4\xf7\x50\x90\x23\x3a\x50\x3f\x88\x61\xe3\x23\x74\xe1\xea\x95\x57\x67\x42\x31\xd9\xd7\x37\xd4\x77\xb3\x3f\xf8\x2a\xc0\xb2\xc0\xba\x93\xc1\x1f\xb5\x23\xe6\x13\x61\x8e\xd3\x70\x52\x4a\x60\xf4\xd4\xc8\x36\x94\xc0\x33\x60\x6d\x1d\x06\x9d\x54\x4d\xcc\xd3\x90\x0c\x37\xa3\xb3\x36\x3e\xfb\xcf\x66\x97\xf9\xf7\x62\xb3\x3b\x12\x94\x58\x39\x53\xfc\x53\x77\x3e\xf5\x67\x26\xee\xb4\x70\xeb\xe9\x21\x49\xb7\x36\x48\xa1\x61\x61\xd4\x94\x12\x0a\x31\x8b\xfb\x08\x0c\xc3\x8e\x49\x96\xf4\xb2\x63\xff\xe7\x8c\x78\x77\xfe\x13\xc2\xfc\x55\x21\x9f\x44\x26\x0e\x8f\x25\x3b\xdd\x37\x9d\x87\x0e\x6c\x91\x04\x8b\x1d\x8d\x4e\x88\xb8\x82\x18\xb2\xb0\x49\xfe\xf5\x3b\x2a\xe1\xf8\xc9\x21\xed\x2b\xcb\x43\x46\x69\xe3\x97\x5d\xcc\x3f\xe4\x52\x0c\xa8\x02\x48\x42\xf7\xff\x2b\xa1\xe2\x2c\xfe\xb5\xd4\xc9\xe4\x35\xea\xda\x60\x1f\xf1\x83\xb2\x63\x64\xee\xe1\xfa\xa5\x9d\x19\xe6\xaa\x4f\x09\x75\x23\x84\x96\xa7\x09\xe4\x6b\xf6\x83\x36\xb0\x68\xbd\x80\xb3\x46\xf1\x1f\xaa\x38\x17\xa0\x7d\x1c\xbd\x84\x38\x2b\x21\x02\x98\x6f\x29\x5a\x13\x98\x07\x7b\xa2\x91\xd6\xb5\xf5\xbd\x86\x0e\xc6\x17\x72\x73\x46\x8f\x0e\xe0\xf2\x59\x1b\x57\x5c\x43\x66\xe1\x89\xb2\x24\xe9\xff\xa3\x5b\xc7\x8a\x4a\xa8\xc0\x69\x54\xfe\x33\xd0\x80\xff\xc0\xb2\x3e\x20\x9f\xd0\xe7\x94\x21\xf1\xbd\xe8\x18\xa8\x68\x90\xcf\x17\x22\x36\xdb\x21\x16\x57\xd1\x00\x31\x19\xfe\x91\xd4\xe2\x7c\x52\x4c\xcc\x11\xfa\xde\x0a\x25\xf5\x7a\x7a\x1d\x67\x7e\x1d\xa0\xb9\xc0\x43\xd0\x2f\xca\x38"}, +{{0x4d,0xf5,0xe1,0x1d,0xec,0x80,0xec,0xd8,0x82,0x83,0x75,0x54,0xfa,0x31,0x35,0xb9,0xd5,0x02,0x9d,0xf4,0x20,0x27,0xaa,0x3b,0x3c,0x92,0x92,0x46,0x32,0x9f,0xee,0x96,},{0xef,0xd9,0x28,0x89,0x8f,0xa1,0x44,0xc2,0xd1,0xc8,0x33,0x4f,0xa2,0xe6,0xb5,0xb6,0xa3,0x25,0xa7,0x10,0x2a,0x2c,0x34,0x4a,0x14,0x55,0x41,0xee,0x9a,0x6c,0x04,0x6d,},{0x62,0x54,0x5e,0x6c,0x07,0x80,0x1f,0xde,0x95,0xb4,0x61,0xe2,0xe7,0x53,0xc4,0xb6,0xc8,0x4c,0x25,0x12,0x4e,0xb3,0x30,0xa2,0x72,0x59,0x89,0xd5,0xe3,0x40,0xdc,0xef,0x0c,0x74,0x56,0xd4,0xc7,0xc6,0xa1,0x78,0xa2,0x21,0xb6,0x32,0x83,0x48,0x25,0x3d,0xb7,0x87,0xa9,0xe5,0x51,0x0a,0xb9,0xcc,0x27,0x85,0x15,0xae,0x3e,0x58,0xfb,0x01,},"\xfb\xd6\xf3\x71\xb4\xc8\xb1\x52\xc9\xce\x0c\x63\x96\xa7\x7c\x0f\xe4\x80\xbc\x02\x00\x7f\x33\x6a\xc5\x8f\xd4\xad\xdd\xa9\xd6\x98\x55\xac\x9e\x93\xa4\x5d\x3e\x35\x0f\x41\xff\x50\x2a\xa1\xd8\xfe\x15\x9c\xe8\x9b\x06\x48\x02\xa0\xa1\x89\x0f\x6a\x40\xa7\xef\x57\xc6\xe5\xe5\xed\x04\x02\x80\xdf\x07\xe7\xf4\x8f\xe8\x19\xbe\x63\x17\x67\x10\x75\x7c\xb6\xe4\x40\xb4\xf7\x8b\x57\x59\xdc\xe0\x28\xbf\x58\x5b\x3c\x3f\xec\xa1\xcf\x59\x81\xda\xda\xdf\xd2\x7e\xa1\x24\xaf\x45\xef\x63\x85\x42\xa8\x61\x7f\xf4\x9f\x94\x70\xac\x22\x85\x94\x3c\x7c\x3b\x11\x63\xb9\x03\x95\x5a\xb9\x9b\x6e\xab\x17\xf4\xd4\x9f\xfa\x87\x20\x7a\xbb\xfc\x11\x1c\x4b\x91\xf5\x41\x3d\xfc\x9b\xea\x31\x84\x3d\x11\x5d\xde\xb1\xda\x40\xb4\x5f\x58\xf4\x7c\x41\x7b\x5e\x77\xd5\x81\x89\x34\xe7\x30\xeb\xa9\xc4\x55\x7b\xbf\x48\xcb\x7f\xd4\xe6\x64\x55\x8a\xf4\xfb\x44\xee\x3d\x94\xc1\x6e\x88\x36\x31\xf3\x84\x76\xf4\x83\x7d\xb9\x4d\x54\x12\x2f\xa1\x34\xca\x51\xa5\x25\xaa\xd5\xe2\x4b\x76\x01\x8f\xee\x9a\x2e\x8f\x60\xe2\xbb\x48\xd2\x4a\xb8\xb1\x46\xf8\x4f\xfa\x98\x20\x12\x0e\x7c\x50\xd4\x5c\x0c\xfb\xe3\x5c\x8c\x31\x41\x9b\x07\x8e\x90\x71\x2c\xfe\x93\x4c\x3b\xe3\xa9\x4f\xf2\x15\x88\x73\xae\xfe\x34\xdc\x6e\x36\x90\x2b\x16\x75\xe1\xa4\x7c\xb6\x08\xdf\xe9\x60\xfb\x4d\xa8\xd2\xa8\x49\x0c\xc3\x8e\xba\xdc\x73\xa1\x00\x3c\x49\x41\xfd\xa8\xfa\xe9\x44\xa1\xde\x8e\x3b\x10\xef\x6d\x9e\x67\xce\xec\x74\x59\x77\xd3\x33\xac\x9e\x71\x21\x41\x21\xed\xe8\x89\x22\x95\xe2\x77\x99\xf2\x06\x67\x5a\x9d\x54\xac\x12\x15\x9d\x3a\x1f\x95\x4f\xd0\xee\xff\xbd\x30\xa3\x19\x04\xfb\x2e\xee\x77\xa8\xaa\x9d\xc4\xcc\xbb\xe2\x85\x10\x96\x14\x6a\x4c\xe0\xe8\x1f\xb9\xc6\x24\x98\xdb\xd8\x3b\xf8\x3b\x55\x02\x9a\x5e\x90\x00\x86\xb9\x53\x1c\xe3\x24\x7a\x98\xf8\x65\x4e\xfd\x8f\xe7\xa8\x36\x43\x1f\x75\xda\xf0\x86\x8f\x01\x08\x32\x6e\x23\x02\x6d\x2d\xb4\xa7\x21\x24\xec\x4e\x39\xd4\xbb\xf3\xd8\x46\xc9\xf5\x1c\xa3\xcc\x31\xeb\x1d\x02\xc2\xba\x32\x1e\x46\x19\xf2\xb6\x59\xc0\xbf\x0f\xe5\xc1\x9b\x21\x3f\x3c\x79\x12\x4f\x36\x43\xf7\x4d\xd0\xff\x9c\xe5\xd2\x77\x27\xbe\x6c\x69\x58\x15\x9c\x16\x44\x04\xf4\x33\x01\xfe\x17\x42\xe2\x79\xde\x9e\xfd\x44\x1e\x73\xe4\xea\x7a\x84\x25\x87\xa7\x9d\x11\x5d\x36\xec\xa9\xc0\x3c\x90\xff\x0d\x14\x74\x74\x10\x9f\xc2\x0a\x91\xd7\xb3\xcc\x22\xeb\xcb\xb8\xc7\xf7\x1b\xd6\x1e\x8c\xae\x47\xc5\x05\x0c\xec\x1d\x48\x49\xa1\xd4\xa8\xe7\xa6\xf8\x45\x54\x84\x37\x70\x6c\x25\x33\x1c\x9e\x57\xc2\xcc\x6d\xa1\x17\xf2\xe5\xa0\xf4\xb3\x68\xc4\xcb\x20\x62\x65\xc4\x17\x8e\x06\x55\xff\x67\x5f\xfc\x1d\x4c\x58\xec\xeb\x9e\xdb\x4d\xa3\xad\x2c\x5f\x62\xcd\x13\xab\x48"}, +{{0x85,0xd3,0x23,0x30,0xe2,0xe0,0x73,0xa4,0x60,0x30,0xca,0x0e,0xe2,0xdf,0x2f,0x8e,0xb8,0x74,0xa9,0xfd,0xdf,0x56,0x24,0xc8,0x03,0x17,0x75,0x11,0x1f,0x11,0xee,0xa2,},{0x6e,0xa7,0xde,0x2e,0xd5,0xea,0x5c,0xdf,0x50,0xbf,0xff,0xee,0x77,0xf7,0xbd,0x2f,0xcc,0x21,0xd4,0x86,0x66,0xbb,0x1f,0x48,0x90,0xc7,0x6a,0x69,0xcc,0x7b,0xa4,0xe8,},{0x41,0x43,0x63,0xfe,0xad,0x6e,0x59,0xa3,0x43,0x8c,0xe5,0xa3,0xa2,0x77,0xd6,0x2b,0xdd,0x00,0xfa,0x2e,0xfa,0xc6,0x46,0x3d,0xd1,0x3f,0xcd,0xde,0xd9,0x3a,0x7f,0x10,0x8a,0xe1,0xf5,0x28,0xff,0xc8,0xff,0x4e,0xca,0x33,0x1d,0xab,0x91,0xae,0x5b,0x14,0x16,0xe2,0xdd,0xb7,0x3b,0x6d,0xaf,0x85,0x3b,0x03,0xc8,0x1e,0x99,0x36,0x56,0x0a,},"\xae\x61\x07\xf3\x8f\xf9\x4e\xd0\x32\x79\x03\xcb\xaf\x6c\x3e\x3a\x34\x98\xc4\x7a\xbb\x29\x89\xa8\xb3\x7b\x3a\x19\xdf\x88\xc6\xde\x79\x0a\xcc\xb4\xb7\x25\x81\x77\xb9\x15\x1d\x1f\xe0\x40\x63\x57\x7d\x3c\x3a\xcd\xb4\xc9\x29\x96\x8a\xfd\xad\x6f\x25\x2a\x67\xed\x4c\xa8\x9d\x06\x0f\x1a\x46\x53\x98\x3f\x7a\xb5\x8d\xdb\x93\xe2\x87\x8f\xba\xb0\x63\x7d\xbb\xeb\x95\xd2\x5c\x59\x86\x83\x9d\xe2\x74\x8d\x9f\x34\x02\x7a\xee\xbf\x1d\x9e\xb9\x36\xcb\x67\x70\xe0\x8d\x45\xb8\x09\x5b\xac\x9c\xbb\x71\xdb\x14\xe8\xa3\x42\x22\xb1\xf2\x23\x7b\x9f\x0b\xc9\x76\x6a\x23\x1a\x6d\x10\x27\x99\xf7\xc0\x81\xd5\x00\xfb\xea\xde\x60\x3c\xdc\xdd\x7d\x5b\x96\x5f\xba\xce\x4b\xe5\xc2\xcd\x93\x2d\xcf\x5f\x6e\xd3\x17\x22\xf4\x1d\x5a\x36\x3b\x34\xba\xbf\x3f\x63\x6f\xb3\x03\x82\x4a\xa7\x01\xdf\xe1\xd3\xe4\x12\x63\x07\x8c\x1e\xbb\xdc\xb1\xf7\x3f\x12\x45\xb8\x3e\x3f\xa7\x0a\xb8\xe3\xf1\x41\x3e\x6b\x06\xbd\xae\x02\x2b\x71\x4d\x60\xa4\x01\xd5\x74\x80\xdc\x64\xe7\xaa\xc6\xd3\xde\x85\xfc\x94\xd8\x53\xca\x13\xb7\xe6\x74\x15\x57\x9d\x5c\x67\x21\x23\xa5\xaf\x19\x4b\xee\x14\xae\x35\xdc\x27\x24\xff\x20\x9f\x11\x66\x63\x86\x61\xf8\x81\xb1\x19\x4a\xa4\xe3\x1b\x42\xa5\x27\x96\x47\x81\x59\x15\x04\xba\x76\x10\x3f\x97\xb7\xf5\x52\x03\x15\x47\x3e\xc9\x4b\xb0\x17\xa1\x66\x67\xb2\x2a\x85\x76\xa7\xcc\x2a\xc0\xb7\x75\x63\x03\xc7\x56\xf0\xdd\xaa\xe9\xd0\x18\x9e\x6c\x8d\xe3\x49\xf9\x19\x57\xc7\x2a\x52\x9e\x9f\x7e\x9b\x94\x56\x52\x48\x40\xba\x02\x34\x4f\x55\xad\x3c\x11\xa0\xb2\x59\x90\x14\x39\xf2\x65\x5a\xb9\xf8\xc6\xc8\xe8\xe9\x60\xc0\x57\xd9\xc7\xda\xfe\x42\x5c\x75\xd4\xa3\x3b\x80\x1d\x45\x47\xcd\x05\x51\xa6\x80\x2a\x80\x05\xdd\x72\x42\x47\x64\xdc\xf5\x7e\x4a\xa2\x22\x90\xea\x4f\x5b\xaa\xc5\x1d\x79\x39\xc0\x53\x42\x88\x2e\xe1\x43\x80\xef\x2d\x47\x04\xb4\x19\x49\xb2\x28\x2a\x1e\x1a\x3f\xa7\xdd\xea\x9f\xe8\x3b\x9f\xc5\x1d\x4e\xef\xa2\xeb\xac\x72\x2e\x4c\x0a\x7c\x59\x9b\x69\x25\xf0\x1b\x8a\x20\x66\xdc\x0c\x26\xf9\x21\x96\xf4\xf5\x03\xe8\x87\xc1\xe6\xef\xb0\x93\xf1\x53\x13\x87\xbd\x88\xc6\x91\x99\x7b\x9b\x89\xe3\xcd\xf7\xda\x12\xd3\x73\x41\x83\xa4\xb6\x12\x6b\xe9\xe0\x77\x47\x04\xb5\x29\x65\x9b\x55\x48\xf1\xb8\x75\x12\xcc\x18\x78\xca\x4e\xf5\x59\x90\xb4\x83\xc9\xaf\x6a\xa9\x76\x35\xf4\xf0\x79\x49\x72\x70\x65\xab\xf2\x1e\x21\xe3\x29\x90\xb1\xa7\xd0\x7d\x74\xe0\x2d\x9b\x07\xec\x63\x99\x31\xbf\x9e\x2c\xa3\x94\x1f\x2b\xa6\xb5\xef\x14\xdc\xc2\xa2\x47\xd2\x11\x7e\x9c\xb4\x1e\xfa\x3f\xcc\xa2\x47\x16\x64\x14\x52\xbe\xed\x2f\x92\x65\x7c\x2f\xb7\x31\xf0\xb9\x4e\x8c\x89\x2a\x81\xbb\xa9\x1f\x63\x9d\xf4\x37\x96\xac\xd3\x01\x3a\xc0\x44\xf6\x08"}, +{{0x66,0x59,0x0d,0x36,0x99,0x84,0xc6,0xf5,0xad,0x3a,0x89,0xc7,0x8d,0xdf,0xca,0x10,0xa0,0xa7,0x65,0x79,0x95,0xdc,0x01,0x88,0xb6,0xb5,0x7a,0xc3,0x16,0x47,0x31,0xa4,},{0x98,0x87,0x3a,0xb1,0x33,0x46,0xee,0x48,0x67,0x7c,0x4f,0x86,0x12,0xdb,0x31,0xeb,0xd1,0x3d,0xb5,0x8b,0x2b,0x03,0x4f,0xd1,0x55,0xaf,0xa8,0x72,0x0f,0x4e,0x93,0xe8,},{0xf0,0xdb,0x63,0xa1,0xbc,0x76,0x24,0x16,0x1c,0xa0,0x06,0x38,0x53,0xb2,0xde,0xe4,0x5f,0xcc,0xd2,0x24,0x71,0xe0,0x12,0x36,0x6f,0x86,0x8a,0x4a,0x9c,0x74,0x65,0x4e,0x13,0xf1,0xa3,0x15,0xad,0x83,0x91,0x6e,0xbf,0xb8,0xdc,0x31,0xa4,0x20,0xf8,0x3c,0xf6,0x45,0xc4,0xc9,0xd1,0x6b,0xb4,0xd5,0xd9,0x9d,0x23,0xc7,0xb4,0x3e,0x23,0x00,},"\x2e\xc1\xc6\xb0\x82\x97\x37\x83\x2c\x9c\x79\x8a\x92\xeb\x49\x0b\x23\xd3\x34\xc3\xbb\xe6\x27\xcb\x58\x2d\x17\xa9\xe4\x29\x60\xef\xcd\xc7\xd3\x47\x50\xe0\xb4\xaa\x86\x4c\x20\x4f\xb8\xd6\x2b\x47\x99\x2e\x91\xdb\xfc\xfd\x69\xf5\x1d\x93\x7d\xc0\x6c\x48\xc0\xad\x43\xe8\x59\x83\x71\xcd\x0e\x3b\xbc\xe4\x16\xbf\xd4\x4b\x09\x44\xb9\x93\xaa\x29\x93\xfd\xea\x48\x71\x34\xcd\xe4\x22\x77\x72\x3e\x06\x83\xec\x98\xe6\x95\x95\xe9\xb7\xb1\x4c\x8c\xf9\x61\x7a\x1e\x30\xdd\xb8\x06\x0e\xac\xba\x48\xd8\x82\x53\xb1\x65\x33\x61\x08\xde\x0c\xb0\x2f\xf2\x0f\x54\x24\xb5\x67\x83\x08\x69\xc9\xb4\x32\x9c\x99\x45\xf0\xbf\x2f\x3c\x7a\xcd\x1e\x77\x43\x58\x93\x0c\xd8\x90\xfd\x9c\xb8\x64\xd9\x50\x93\x5a\xd8\xa4\xa3\xbe\xcc\xae\x8f\x83\x3f\x63\x56\x19\x13\x71\xc3\x26\x33\xdc\xf8\x82\x70\x9b\x0d\x98\xbd\x80\x7b\x38\x3a\xed\x8d\x7b\xb0\x97\xb6\xe2\x62\xef\x70\x0c\x9d\x76\x8f\x4b\x56\x90\xe3\xa1\xa8\xf2\x17\x55\xd6\x58\xdb\x2d\x1b\xfd\x2f\x70\x71\xe0\xca\xec\x7c\x2c\x53\x81\xc5\xef\x5c\x2c\x22\x81\xc6\xbc\xed\xc8\x67\x39\x0b\x90\xf3\xb2\x7b\x0f\x0f\x64\xa3\x36\x58\x57\x8a\x5c\x0d\x66\xe2\x11\xe6\xff\xf6\xe8\x64\x88\xac\xf8\x2b\xc0\xf5\xe2\x66\x4b\x83\x69\x90\x46\x03\x7c\x0d\x33\xd3\x40\xff\x98\xed\x62\x63\x35\x4c\x24\x27\x31\x36\xff\x0e\x4f\x0f\x23\x3a\x6c\x82\x54\xfc\x0c\x90\x76\x43\x30\xe3\xb1\x05\x7b\x1e\x66\x6d\x5e\xcd\x5a\x2e\xfe\xaa\x6a\x10\x5b\xfc\x85\x84\x31\xb8\x8e\xd7\xfe\x55\x1e\xb3\x2a\xc0\xaf\x27\xc6\x6a\x98\x03\xa3\xbc\xf8\x76\x34\xc6\x6c\x70\x66\xdd\x01\x97\xa3\xcb\xd2\xd6\xf4\xe6\x5c\xfd\xb8\xf3\xda\xf9\xf3\xca\x5c\x4f\x4e\x0a\xdd\x45\xf5\x54\x1a\xa1\x8d\x04\x1f\x70\x6e\x4f\xa8\x7c\x34\xe9\xa2\x23\xd8\x85\x72\xeb\x50\x08\x3e\xe8\xc7\xc4\x75\xdf\x56\x8b\xc7\x3b\xd0\x8c\x0f\x0d\xea\xa3\x74\xaf\xb1\xc1\x78\xd0\xdd\xdb\x23\x6e\x15\xa8\xbc\x23\x85\xed\x3f\x52\xb8\x76\x1e\x63\x78\x87\x40\x7a\x20\xae\xc3\xe9\x9e\xc8\x30\xda\xe3\x16\x7e\xf0\xcd\xb3\xf3\xff\xd2\x00\xd8\x3b\x75\xb7\x49\x69\x0b\x9e\x25\xe2\x17\x1d\x07\x2c\xa5\x6f\x71\xba\xec\xd2\x1f\x7d\x45\xa1\x2c\x91\xb2\xc0\xfb\x3f\xea\x3b\x15\x8e\x54\x64\x82\x84\xbb\x00\x95\xb3\x62\x44\xb0\xb1\x21\xf9\xf1\x38\x4c\xe9\x00\x43\x65\xe7\x77\x2f\xa3\x08\x28\x25\x0f\x51\x98\x5f\x1b\x17\xb2\xd2\xf8\x0a\x33\xe8\xfc\x6d\x85\x65\xea\x15\xcd\xaa\xcd\x42\xa8\x7b\xd7\xc9\x40\x8b\x1f\xe1\xc7\x70\x66\x5b\xdd\xed\x75\x4b\xc2\xff\x2e\xf9\x1b\x97\x3a\x86\xb9\x9f\x10\x59\xc6\xf2\x27\x24\x6a\x69\x8b\x38\x54\x15\x09\xdd\x54\x49\xfc\xe6\x0d\x38\x62\x24\x18\x3b\x7d\xce\x1b\x38\x84\xf7\xba\xe1\xc2\xe4\xeb\x59\x45\x10\xb5\xca\x58\x52\x79\xd9\x04\x1d\xf8\x81\x7b\x06\x19"}, +{{0x41,0xcf,0x07,0x1f,0x48,0x42,0xec,0xd4,0x94,0x19,0x1b,0x8c,0xf2,0x8c,0xc0,0x92,0x31,0x85,0xef,0x1b,0x07,0x45,0x8a,0x79,0xa5,0x9a,0x29,0x6d,0x35,0x49,0x82,0x2e,},{0x6d,0xc8,0xe4,0x46,0xdb,0x1d,0xa3,0x53,0xb5,0x8d,0x0c,0x45,0xd8,0xb4,0xd8,0x16,0xba,0x59,0xe2,0x5b,0xb6,0x80,0x71,0x2d,0x62,0xd6,0xd3,0xdb,0xf7,0x8d,0x06,0x98,},{0x41,0x05,0x2b,0xc4,0x17,0xb2,0x4d,0xc4,0x83,0x83,0x96,0x6a,0xf0,0x14,0x3f,0x9c,0x0b,0xa8,0x5b,0xbe,0xfb,0xda,0xf7,0x91,0xb1,0x6a,0x4d,0xad,0x1f,0x57,0x0e,0xb8,0x07,0x03,0xc0,0xa2,0xcd,0xeb,0x2f,0x7a,0xd6,0xdc,0xd3,0xfa,0x7b,0xdb,0x5c,0x22,0x5e,0x86,0x9c,0xd8,0xfb,0x27,0x8d,0xff,0x06,0x67,0xd3,0x8a,0xcc,0xf3,0xdb,0x08,},"\xda\xeb\x5f\x0e\x84\xf1\x59\x0b\xca\x2b\x9d\x97\x19\xef\x5d\x1c\xfa\x79\xe0\x58\x34\x46\x33\x2f\x18\xe9\xe4\xfe\xb0\xb1\xf1\x53\x40\x29\x7a\xc9\xad\x67\x24\xc8\x5b\xb1\x65\x58\xea\x54\xeb\x5d\x70\x2a\x47\x24\x8b\xad\xc6\x25\x2a\x80\x43\x71\xb7\x4c\xfe\x10\x62\xd1\xdb\xa1\xec\x68\xfd\x1d\x4d\xd0\x29\xcb\x55\x03\x4b\xbf\x61\x06\x82\x51\xef\xf3\x98\x36\x36\xf6\xde\xbd\x57\x27\xbe\x91\x99\x3b\x3e\x4d\x0a\xbc\x96\xec\x19\x64\x21\xa4\x7b\x78\x93\xf8\x39\x86\xd6\xc0\x32\x3f\x0d\x19\xaa\xf2\xcd\xe9\xd3\x56\x5c\x10\x4c\x9d\x31\x76\xec\xb5\xed\x5e\x17\x3f\xee\x52\xb5\xa0\xc4\x2b\x6a\xb2\xfc\xb1\xcc\xba\x96\x49\xc2\xc6\x7c\x52\x0e\x9b\x96\xce\xa6\x93\xdf\x3e\x58\x60\x9a\xd6\xa0\xbd\x52\x2e\xfa\xaf\x03\x85\x8d\x24\x5d\xd0\xa3\x8f\x84\xa2\xfb\x10\x20\xf4\xdd\x97\xc3\xae\xef\x0e\x24\x47\x7d\x30\xd2\x56\x70\x1e\x90\x0b\xef\x26\xa8\xa6\x26\x9a\xb6\x60\xd7\x42\x93\xa2\xbf\x1d\x20\xc2\xcf\xae\xbb\x7c\x28\x20\xf5\xf5\xb0\x74\x53\xbb\x69\xee\x76\x9b\x52\x39\x15\x39\xf0\xc6\x06\xd2\x2e\xb3\x92\x3e\xe6\xf5\xa1\xd4\x60\x50\xaf\x90\xf0\x11\xf8\x51\xac\xe7\x63\x27\xd3\xd1\x8c\x48\x17\x0a\x9a\x25\xb0\x4b\x77\x0f\xd9\x38\xef\x8a\x30\xb7\xbd\x03\x39\x1d\xd3\x6c\x51\x6b\x62\xf0\xcb\x78\x67\x07\x40\xe0\x0e\x69\x59\x5c\x41\x8d\x96\x72\x53\x82\x0b\x75\x4c\x4f\xd6\x66\xe3\xcc\xe1\x6e\xe0\xc9\x41\x83\xbb\xea\x70\x6f\xe2\x98\xe1\xc9\x9d\xdb\x82\x12\x17\xed\x90\x08\xcc\x8e\x8b\x83\xbc\x8b\x81\x99\x15\xb0\x7b\x14\x6f\xe7\x45\x02\x4a\xc3\xc4\x61\x16\xcb\x4c\xce\x5e\x32\xec\x5d\x75\x24\xa2\x38\x8d\x9f\xe2\x97\xeb\x02\x81\x1a\xf4\x54\x6f\xcd\x58\x60\xe1\x4c\x0d\x13\xf0\x3d\xd7\x5a\x42\x49\x61\x59\x00\x07\x8a\x3c\x35\x8c\x53\x42\x96\x2b\xc1\xbe\xac\xf6\x8c\x24\x68\x21\xa4\x59\xab\x53\x21\xec\x9f\x57\x4f\x49\xd1\x03\x89\xf4\x0f\x14\xdd\xfc\x85\x13\xff\xe3\xde\xaa\x73\x36\x03\x5a\x67\x5f\xa5\x85\x8b\x49\x0c\x5d\x24\x77\x80\x06\x4a\xdb\xaf\x75\xa7\x63\x35\xee\xc9\xab\x91\x87\x71\xb0\xb1\xdf\x51\x47\x64\x2a\xef\x4a\x16\x6a\xb1\x72\xed\x60\x1f\xed\x21\x0f\x6c\x0c\xff\xd9\x18\x69\xf7\x49\x0b\x57\xe7\xc6\x52\x41\x86\x3e\x7e\x8c\x0a\x26\xeb\xa6\x3b\x53\x42\xd0\xfd\x82\x14\xac\x73\x1e\x1c\x43\x8d\x01\x77\x11\x5f\x6a\x19\xe0\x93\x5c\x7a\xf6\xbc\x7d\xbe\xb7\x55\x11\xd9\xbd\x8e\x63\xe3\xe2\xf4\x7a\xb0\xdd\x1c\xed\xd7\xb1\x80\xd7\x4a\x4b\x44\xd4\x61\x19\x7a\xef\xdd\x36\x20\x46\x51\x66\xa3\x9b\x45\x39\x50\x43\xce\x88\x74\xcd\xd7\x2c\x60\x2b\xd3\xd2\xee\xcb\xad\x34\x66\xb5\xcb\x1a\xa4\x1a\xe9\x2a\x8a\xfe\xf2\xd7\x64\xce\xc0\xc4\x49\xd2\x7e\xfa\xc4\x37\x93\x8f\x28\x0b\xea\x9c\x50\xa5\x82\xe5\x7c\x27\xf9\xb3\xde\x87\x2f\x0c"}, +{{0xa2,0xc8,0xe1,0x61,0xa8,0xd9,0xd6,0xe8,0x88,0xc3,0xd0,0x9b,0x0b,0x97,0x27,0x37,0x30,0x7a,0x2c,0xbd,0x2a,0xcd,0x7c,0xcd,0x80,0x4d,0x24,0x31,0xac,0x6c,0x58,0xd2,},{0x3a,0x32,0x57,0x75,0x88,0x67,0x32,0xde,0xca,0x40,0x68,0x57,0xa8,0x05,0x60,0x10,0xaa,0xea,0x28,0x75,0x54,0x5b,0xa6,0xf3,0xdf,0x30,0x75,0x45,0x71,0x38,0x69,0x92,},{0x56,0x0d,0x01,0xb9,0x4d,0xf1,0x1d,0x83,0x34,0x77,0x52,0xff,0x51,0xb3,0x54,0x5e,0xf5,0x5c,0x56,0x32,0xae,0x7c,0x8e,0xfb,0x11,0xaa,0xdd,0x83,0x12,0xde,0xf7,0x25,0x62,0xe8,0xf5,0xd7,0x5e,0xce,0x10,0xad,0x46,0xbc,0x96,0xc8,0x60,0xde,0xec,0xe3,0x9e,0x63,0x4a,0x5f,0x50,0x65,0x4d,0x4c,0xdb,0xa8,0x4a,0x8e,0x6f,0x70,0x24,0x0a,},"\x83\xa3\xbe\xbc\xac\x5f\x28\xc5\x43\x3e\x3c\x4f\x1e\x7b\xf5\xd2\xe4\xdc\xd2\xf5\xe5\x9d\xbe\xe0\xa8\x3b\x07\x02\x57\x15\x35\x07\x46\xf8\x56\x75\xf1\xdf\xea\x37\x4a\xa7\xd7\x94\x28\x7b\x89\x2e\xf9\x09\x7f\xf6\xd2\xe1\x22\xf0\xa6\x56\xfb\xa0\x79\x8c\xdc\xfc\xb3\x64\x5d\xfc\xfd\x78\x8c\x74\x0c\x0f\xd0\x45\x20\xe7\xa0\x6a\x02\xa0\x58\x29\x63\x0a\x2b\xf0\xcd\xfe\x2e\xcc\xa0\x09\xec\x44\x04\x99\x46\xbb\x1d\x23\x26\xdd\xd6\x1d\x7e\xc6\x40\xbf\x69\xeb\x44\xfb\x23\xcc\x1f\xf4\x78\xc5\x70\xc7\x5d\xb7\xe7\x66\xe3\x5b\x7c\x43\xdb\x73\x68\x0d\x14\x07\xa9\x43\x99\xfb\x62\x1b\xaf\x38\x45\x74\x5c\x1c\x4e\xd0\xb9\xf0\xb4\x85\xbe\x2d\x53\xc5\x68\x54\x5d\xdf\x18\x77\x5a\x83\x7a\x05\xd9\xc9\x15\x7b\x08\x4e\x8c\xd0\x1f\xc3\x24\xf0\x7f\x11\x68\x77\xe4\x07\x5d\xba\x24\x32\xc8\xa7\x75\x2e\x9e\x93\x95\x86\xad\x93\xf0\xc0\xaa\x5e\xda\xc9\x4b\x8d\x82\xe5\x44\x99\x97\xb1\x5b\x8c\x89\x61\x58\x9c\x44\x28\x21\xaa\x83\xb6\x02\x39\xec\x5f\x15\x8c\x3f\x5e\x9e\xc5\xbe\xa5\x11\x5d\x5f\xed\x61\x91\x8e\x8f\xcd\x5b\xce\x61\xc7\x77\xf2\x0b\x6b\xfe\x80\x3a\x69\xc6\xfc\x79\x4a\xb8\xc5\x7d\xf2\x71\xda\x86\x38\x72\xa6\x13\x35\xb1\xfa\x29\xf4\x60\x8f\xf0\x37\xf7\x12\x06\x98\x09\xca\x64\x2a\x03\x07\xc7\x9a\xa9\x2e\x10\xcb\x89\x3a\x29\xd1\x72\x01\xa0\xb6\xd1\xb4\x6a\x72\x12\xb3\xba\xec\x97\x03\xc0\xb0\x39\x2b\xa6\xb7\x6e\x5c\x9c\x10\xf8\x35\x99\xb8\x1e\xa2\x22\x83\xf9\x54\x7a\xac\xda\xa7\xf3\x08\x96\xd1\xff\x73\x1e\x11\xfb\x9e\x56\xad\x06\x03\x04\x17\x11\x98\x05\xba\xb6\x35\x21\x49\x6c\x3b\xb9\x2a\x12\xf5\xe5\x5a\xfc\xf6\x0e\xd4\x21\x77\x37\xf3\x04\x6b\x16\xca\x50\x66\x57\xa6\xd6\x96\xd7\x5a\x6d\x8e\x18\xe9\xef\xe2\xb0\x8c\x8b\x1f\xa0\x72\x82\x38\xe2\x7c\xfb\x32\x21\x66\xee\xe4\xee\x76\x96\x8b\x77\x7b\x50\xee\x6a\x2b\x80\x4e\x1e\x9b\x46\x01\x66\x20\x13\x2b\x65\x88\x71\x8d\x97\x8c\xa2\xc0\x02\x69\x79\xc4\x00\xd3\xc5\x33\x67\x51\x21\x0f\x0b\x00\xd2\x69\xec\x8f\x4e\x2f\x95\x59\xe1\x80\x33\x2d\xd2\x70\xe5\x0c\xc9\x46\x5c\x55\x58\x93\x63\x55\x52\x1b\xc3\xc9\x56\x0f\xc1\x9e\xc1\x42\x42\x12\x1e\x6b\xb2\xff\xf8\xf5\x03\x37\xfc\x26\x4a\xcf\x1a\xc1\x70\x43\x28\x33\x4b\x3b\x52\xcb\xa9\x6d\x93\x03\xb1\xb5\xdb\x85\x9d\xae\x31\xd8\x0f\x17\x11\xfb\xa2\x51\xe1\x0b\x4d\x12\x21\x28\xf9\xfa\xff\x68\x72\xd0\xc0\xb8\x1e\xef\x59\x54\x1f\x83\x2b\x0a\x9d\xf3\xa4\xcd\xd5\x91\xc8\x77\x36\xb1\xae\xcf\x24\x2c\x27\x5a\x10\xc3\xfd\x67\x83\x9d\xad\x4e\xf3\x99\xb9\x49\x4e\xcd\x77\xf7\xba\x5b\x5d\x4f\x2c\xa3\x04\xe5\xb2\x29\x21\x30\x7c\xb1\x8f\xa6\x4a\xa3\xd0\x1c\x44\x11\xc8\x36\x9c\xce\xde\x46\x5e\xe3\x69\xee\x63\x7d\x43\xd2\x88\x26\xbf\x60\xdd\xde"}, +{{0xd3,0xd1,0x88,0xb3,0x90,0xba,0xcc,0xd9,0x50,0x24,0x52,0x61,0x46,0xb8,0x2b,0x91,0x84,0xe1,0x97,0xe4,0x6a,0x93,0x40,0xa0,0xe6,0xec,0x18,0xbf,0x75,0xbe,0x7f,0xc5,},{0xd8,0xf7,0x94,0x94,0x8a,0xa6,0x98,0x61,0x00,0x21,0x4e,0x9b,0x7b,0x90,0x24,0x42,0x08,0x06,0xb4,0xc6,0x78,0x46,0xd5,0xbd,0x50,0x61,0x13,0xb3,0x53,0xa2,0xea,0x3d,},{0x16,0x97,0x6b,0x26,0x7d,0xe9,0x6e,0x38,0xdd,0xdc,0x84,0x78,0x07,0x5f,0x6b,0xdd,0x71,0x59,0xe5,0x63,0x34,0xb2,0xd2,0xd1,0x92,0x09,0x46,0x29,0x4f,0x33,0xcd,0x6b,0x7f,0x9c,0x50,0xf8,0x05,0x7f,0x49,0x6c,0xab,0x5d,0x94,0xbb,0x4d,0xca,0x26,0x2f,0x9f,0x0f,0xdf,0x9b,0x1b,0x64,0x74,0x1f,0x4b,0x72,0x2d,0x32,0xef,0xa8,0x22,0x03,},"\x5e\x65\x65\x8e\x42\x03\x75\x43\x3f\xd7\xc1\xf6\xbe\x67\x88\x41\xe5\x81\x04\xf1\x0b\x4c\x67\x63\x59\xd8\x4f\xce\x79\x92\xf5\xc5\x75\x57\xd7\x38\xf8\x30\xb5\x05\xfa\x0c\x2b\x9e\xab\xf8\xd1\xa9\xf8\x1f\xe8\xf3\x15\xd6\x62\xe2\xb8\x4c\xe9\x52\x99\xeb\xf4\xe5\x03\xb5\xe1\xf7\xf8\xcd\xb6\x68\xae\x73\x3f\x3d\x0c\xdd\x4c\x74\x2a\xb5\xf2\x72\xbe\xa4\xf1\x8d\x18\x3e\x89\x23\x84\x76\x62\xf9\xa3\x9c\xd4\xb1\x4e\xc7\x6d\x11\x03\x2f\xe5\x73\xc2\x62\x01\xae\xf6\x66\x01\xce\xc6\x83\xe3\x4b\x89\xaf\xd9\x64\xe9\x87\x80\x1c\x70\x6a\x85\xe2\x7b\xab\x33\x70\x1c\xd1\x09\xbc\xf0\x7b\x27\xca\x67\xf0\x22\xc4\x94\xa0\x4c\xbe\x5a\x9c\x6d\x63\xaa\xd9\x36\xcd\xf1\xa1\x80\xfd\x05\x86\x51\x98\xb9\x6f\x06\xa7\x8d\xa9\x57\x99\xd3\xaa\x4d\xf3\xb1\x70\x03\x3c\x69\xe8\xfb\x04\x28\x8c\x35\x46\x55\x3b\x57\x9c\x0a\xe3\x93\x80\x62\xd3\xd8\x42\x1c\xfa\x66\x26\x85\x29\xbe\xc0\x27\x1e\x53\xb4\xee\x7d\x09\x9e\x71\x48\xa8\x02\xdf\x80\xfe\x5e\xed\xee\x1c\x90\x3a\xe8\xed\x4d\x64\x0e\xad\x76\x12\x62\xdd\x40\x14\xf2\x5f\x93\x97\xba\x3f\x1c\x08\xd8\x3a\x3c\x48\x5c\xfb\x55\xf8\x99\x19\xaa\x97\x2d\x6b\x7e\x77\x11\xbe\x9e\x30\xc1\xeb\x96\xa0\xc3\x84\x53\x09\xfb\x23\xdb\xc7\x5b\x69\x91\xdd\x6e\x48\xcd\xde\x90\xe0\x4f\x22\x8e\x8c\xcf\x3b\xa2\x3f\x27\x47\xcf\xb9\xd3\x38\x1a\x93\x05\xf8\x16\xf2\x6c\xdd\xe4\x1c\x02\x20\xfa\xd2\x28\xff\x6a\x8b\x09\x5c\x77\xb6\xba\xe8\xfa\x33\x68\x14\x27\x24\xbf\x1f\x5e\x0f\x6f\xbc\xa5\x32\x0c\x21\x5b\x6b\xa8\x6b\x91\xe3\xa8\xac\xf7\x50\xe9\x3f\xa7\xea\xa6\x5c\x4f\x78\x5e\xf8\x42\x1a\x19\xc1\xe2\x7b\xc2\x4b\x42\x8e\x08\xa9\x02\x42\xab\xac\x9b\xd4\xaa\x03\xc6\x56\xf8\xf4\x6d\xc4\x0b\x36\x15\x2c\x1b\xd0\xde\xf1\xac\xfc\x0d\xa1\x0a\x2f\xa1\xdc\x3d\xa7\xac\xe5\xa8\xfd\x76\x22\x7b\xb1\xa6\x02\x39\x0f\xe5\x7a\xfd\x32\xef\xe2\x81\xf2\xea\x6b\x2e\x4d\x25\x45\xcb\x88\xd2\x30\x8d\x72\x69\x1c\x9a\x52\xb4\xca\x25\x23\x1a\x01\x07\xf2\x5d\x11\x7c\xc9\x35\x39\x76\x21\xc6\x83\xbd\xc8\xf2\x2e\x81\x03\x40\xf2\xcb\xac\x4c\xea\xa3\x46\x86\x65\x26\x18\x79\xf0\x07\x42\x00\x74\x3e\x0d\xe5\xf3\xe5\x83\x08\xb9\x8b\x04\xb8\xc7\x14\x8a\x4e\x00\x4e\x66\x7e\x83\x2b\x00\x84\xb5\xf2\xbd\xc6\xfd\xc9\x59\xf2\xfc\x28\xa8\xd3\x1d\x9a\x9e\x78\xe5\xd5\xf9\xc0\xb1\x19\xe5\xff\x1f\x68\xf7\xc0\xda\xf0\xc0\xf1\x69\x47\xcc\xa5\xb7\xce\xd0\x96\x01\xe2\xeb\xed\x28\x2e\xf2\xbf\x8f\xe9\xa2\x7e\xd2\x7f\xc5\xbc\xda\x8a\xed\x6c\x71\xbe\xe3\xe7\x75\x10\x04\x47\x26\x89\xbb\xf6\xd9\xd0\x79\x52\xa2\x42\xff\x87\x0d\x7c\x3f\x5e\x1f\xfc\x2c\x1f\x40\xfc\x9a\xb7\x57\x9b\x39\x2b\x55\x4f\x3d\xc5\x88\xc0\x3a\xb9\x57\x43\x1f\xe5\xd0\x2c\xbc\x71\x1a\xd4\x89\xfe"}, +{{0x61,0x91,0x7a,0x97,0x5c,0xb7,0xec,0x56,0x4c,0x70,0x8a,0x56,0x53,0x88,0xc5,0x72,0x36,0xa6,0x6b,0x69,0x7d,0xcd,0x5a,0x7f,0x10,0xba,0xe6,0x71,0x57,0x2a,0xc7,0xf0,},{0xec,0xc0,0xf0,0xb9,0x92,0x76,0xe5,0x28,0xf8,0x2b,0x42,0xf2,0xef,0xce,0x85,0x79,0xf8,0x3e,0x63,0x8c,0x6a,0xce,0xfd,0x07,0x28,0x28,0xc0,0x4e,0x43,0x4f,0x55,0xaf,},{0x6a,0xbb,0x3e,0x37,0x7b,0x5c,0x80,0xb7,0x4f,0x77,0x21,0x9c,0x1a,0x9e,0x09,0x6f,0xba,0x0e,0xb6,0x89,0x90,0x81,0x7a,0xcf,0xf1,0x2d,0xba,0x7f,0x61,0xc7,0x7c,0xcf,0x59,0x5f,0xb6,0x60,0x85,0x52,0x00,0x3c,0xea,0xd0,0x6c,0xa1,0x31,0x7c,0x9c,0xd5,0x1a,0xc4,0x72,0x4b,0x29,0xf4,0x09,0x21,0xfb,0x92,0x84,0x33,0x76,0x87,0x64,0x01,},"\x6e\x97\x0e\x0b\x1c\x92\xa7\xf4\x96\xa8\x2d\x8a\xe8\x0c\xfd\x0c\xce\xf1\xd2\xc7\x99\xd4\x17\x28\xf3\x5d\xdc\xd6\x03\xb4\x21\xc2\xa5\xab\x3b\x48\x9e\x78\xf4\xb6\x22\x97\xde\x43\x7c\x5a\xd1\xa9\x68\x3f\xf8\x7f\xa2\x8e\xb3\xcc\x38\xce\x24\x2a\xf5\x94\x19\xf9\xfd\x43\xfc\xaa\x54\xfc\x39\x89\x92\xf8\xc8\xe3\x1f\x2b\x33\xdc\xcc\xd0\xee\x11\xba\x7b\x38\x8e\x8d\x2a\x36\xea\xd0\x67\xc6\xbe\xce\xd5\x89\x0a\xb7\xd4\xa9\x4f\x55\xda\xb9\x21\x28\xa0\xf8\x14\xc0\xe6\x89\x71\xdf\x57\xbd\x50\x78\xa7\x40\x31\x75\xc7\xc2\xfd\xd4\xa5\x24\x47\x15\x3a\xb3\x74\x56\x72\x9a\xee\x33\xe5\xfc\x93\xdb\x8e\x7f\x48\x03\x09\x87\x5e\xcf\x6d\xb0\x7c\xe7\xf3\xca\xc5\xde\x49\xe3\x61\x27\x5c\xa5\x0b\x6b\x71\x9f\x4b\x71\x5b\x3e\x30\x86\x3c\xbb\x3b\x71\x64\xba\x9e\xb9\x6e\xf3\x30\x4b\x19\xad\x4d\x74\xdc\xe4\xbd\x25\xe7\x7b\xbb\xbe\xff\x1e\xe7\xd1\xfb\x55\xb9\xc4\xf7\xfc\x4c\xd9\xbd\x55\x10\x8a\xfc\xf9\x9c\x1a\x41\xcd\x6f\x6b\x1a\xdb\x29\x7b\x10\x6c\x8b\xa2\x4e\x31\x34\xf8\x7d\xd8\xef\xe5\xcf\x85\x49\x22\x91\xb9\x4d\x66\x00\x95\x8c\x28\xb9\x12\x2f\xe6\xe0\x1b\xd3\xe3\x29\xe4\x2d\x19\x26\xb8\x9f\x7a\x8c\x40\xa4\x98\x67\xe5\xaa\x3a\xd7\x49\xbd\x98\xda\xe7\xd0\x06\xb4\x53\x60\x9e\x7d\xae\x26\x36\x4d\x91\x72\xbe\x72\x83\x33\x01\x21\xed\x2b\x40\x27\xe0\x88\x51\x18\x74\x3a\x6e\xa0\xcb\x7d\xc2\x74\x09\xa9\xb2\x82\x0b\xcc\x24\x2e\xa1\x0a\x00\x93\x7b\xf8\x49\x20\x1e\x0f\xb6\x19\x94\x21\xf1\x63\xe9\x79\x4f\x2d\xd4\xb3\x32\x01\x4a\x09\xd3\xee\x80\x71\xda\x78\x77\x47\xf9\x90\xf5\x17\x99\x19\x02\x7d\xdf\xf7\xca\xb0\xf5\x5e\x9a\xfa\x8e\xcc\xb1\x6c\xc2\xdd\x3c\xbb\xea\xd7\xff\x7e\xc8\x18\xc2\x53\x39\x3f\x74\x87\x41\xf5\x54\x07\xf7\x40\x8e\xe3\x3a\x42\xae\x2d\x6e\xcb\x3f\xb6\x00\xa7\x1f\x30\xab\x63\x06\x06\xe5\x53\xb4\x36\x78\xe5\x98\x54\xf3\xa2\x94\x7b\xcf\x4e\xa0\xfc\xfe\xdc\x31\x4d\x83\x70\xd1\x26\x63\x95\xfd\xa3\xc9\x10\x5e\x97\x59\x52\xf6\x0e\x30\x86\xbb\x82\x48\x15\x13\xd6\xfe\x8a\xdb\x4f\x95\xef\xb9\xa9\x5b\x66\xd4\x80\xd2\xbb\x17\x10\x78\xcf\x40\x68\x4a\xc6\x9a\x78\x9c\x7f\xb7\xfa\x42\x53\x33\xd7\x05\xdb\x00\x06\x67\x55\xdf\x72\x8d\xe0\x2d\xf2\x5b\xae\x34\xf1\xd7\xd4\x9c\xaf\xfc\x51\xe9\xba\x2b\x10\xb9\x8f\xe4\xcd\x9d\x22\xb7\x76\x4e\xd9\x31\xed\xb5\xf0\xb5\x54\x49\x6e\x99\x53\x91\xe0\xaf\x0b\x8d\x1c\x7a\x82\x95\xa8\xd1\x5a\x7c\x65\x56\xd2\x9c\xb1\x9e\x08\x55\xca\x50\x5a\xd0\x1d\x2a\xa3\x09\x28\xa8\x4b\xc4\x89\x59\x57\x6d\x81\x2d\x9b\x27\xb8\xe8\x88\x79\xfa\xa2\x80\x6c\x08\x41\x36\x0e\xcd\x0f\xe8\x3f\x5b\x84\x8f\xc1\x2f\x65\x8f\x1e\x7f\x40\xe5\x61\xc2\xe7\x8d\x3b\x01\x25\x21\x0a\x92\x06\x1c\x2d\xb2\x1b\xa6\x60\xe8\x60\x8f\xf5"}, +{{0x7b,0xa2,0x5f,0x27,0x97,0xa2,0x83,0x6f,0x37,0x9d,0x6b,0xbc,0xbe,0x9a,0xbf,0x4f,0x2d,0xef,0x5e,0x52,0xf7,0x2b,0xd9,0xe0,0xb0,0x06,0x57,0x10,0x22,0xfa,0xc2,0xf3,},{0x6c,0x2e,0xd4,0xe8,0xc0,0x12,0x4d,0x5d,0x05,0x40,0x79,0x6d,0x39,0x45,0xd1,0xde,0x71,0xaa,0x69,0x69,0xe6,0xab,0xea,0x0f,0x1b,0x0e,0x6f,0xc4,0x29,0xc7,0x04,0x6f,},{0xf1,0xf5,0x90,0xa9,0x07,0xba,0x98,0x0e,0xb0,0xd6,0x48,0xab,0x4d,0xed,0x5f,0x92,0xfa,0xf7,0xcb,0x85,0x1d,0x81,0xd8,0x58,0xa7,0x8f,0xa6,0xb7,0x7c,0xbb,0xe1,0x2f,0x64,0xd2,0x0d,0xf5,0x27,0x71,0xa7,0xd5,0xe5,0x39,0xa1,0x52,0xd7,0x31,0xe1,0x90,0x3d,0x42,0x11,0xfd,0xcf,0xef,0x9a,0x48,0xb4,0x6c,0x8f,0xd5,0x39,0x4c,0xa0,0x09,},"\x17\x1a\x34\x09\x87\x80\x97\xb3\xb2\x2b\x2c\x00\x66\x0b\x46\xe5\x42\xc2\x16\x4c\x00\xbb\xee\x54\x55\x48\x37\x94\x0e\x70\xf0\x3d\xa9\x91\x6a\x40\xf9\xbd\xe8\x28\x8f\x45\xe4\x7b\xef\x7f\xfe\x4e\x55\x7c\xd4\x47\x40\x45\xe7\x40\xfd\x95\x9d\x98\x4f\x4e\xc8\x1d\xa8\x8d\x44\xa3\x73\xc1\xed\xa0\xcf\xc6\xb0\x8e\x35\x13\x73\xd3\xb8\x2a\xb0\x90\x2d\xf8\x06\x3f\xd9\x08\xe7\x03\xe0\xcb\xec\x41\x0a\xb5\xcd\xfe\xaa\xe0\x01\x88\xce\x2a\xd4\x2b\x8b\xf0\x4f\x7d\xaa\x5f\x0e\xe3\x33\xa6\xf9\x31\x1b\x4a\xd9\x81\x09\x52\xd5\xd5\xa6\x4b\x20\xf3\x7e\x84\x54\x15\xfc\x3c\xdd\x61\x6f\xeb\xec\x50\xdb\x29\x6f\xb3\xf3\xbb\x7f\x6b\x36\x6b\xbe\x52\xe4\x89\x7a\x05\x61\x7b\xf7\xc9\x81\xa6\x2e\xdc\xbb\xbe\x5d\xa4\xc3\x9c\xaf\xa8\x69\xaa\x2b\x27\x34\xe6\xcf\xed\x90\xed\x8b\xe7\x59\x49\x39\x0e\xe4\x45\x66\x89\x24\x55\xb8\x90\xcf\x56\x8b\x94\x5a\xab\xb7\x58\xd3\x85\x4b\xe6\x53\x9f\x3b\x86\xbf\x01\xd1\x88\xe4\x8c\xf2\x62\x6a\x0d\x7d\x38\x17\x03\xbe\x6e\xd1\x29\x0d\xfb\x94\x7b\xc2\xe0\xf8\x3d\xbc\x58\x70\x30\x80\xd7\xf5\xb9\xef\x19\xae\xf9\x30\x90\x8f\x68\xf0\xc8\x00\x10\xa9\x40\x1b\x30\x3a\x9f\x6d\xa8\x05\xbb\x8a\x0e\xd0\xf3\x94\x13\xee\xfe\xdf\x91\x9f\xfd\x8e\xa6\x39\x1b\xf9\x5d\x42\x29\x60\x4e\x49\x45\x7b\x8e\x23\xbe\xc6\x11\x48\x4c\xc7\xf9\x83\x2d\xd9\x5b\xdc\x3a\xd1\x77\xc0\x50\xf4\xab\x63\x3d\xcd\xb3\xe6\x91\xf5\x90\x28\x73\xb3\x8c\xb0\x72\x0b\x91\x13\x35\x7f\xe0\xcf\xb9\x8a\x68\xcc\xcb\x5d\x5f\x08\x09\xd5\x9a\x37\x5c\xf7\xb5\xa2\x75\xd4\x3c\x4c\x34\xff\x68\xe4\x48\x52\x6e\x8e\x1a\xad\x44\xe2\x00\x08\xa2\x32\xaf\xbc\xf5\x32\xa4\x2b\x50\xa0\x25\xa1\xb2\xee\x4e\x07\x7e\xb0\x12\x5a\x59\x3d\x51\xa2\x00\xec\x20\xd8\x72\xc0\x58\x38\xad\x36\xaa\xae\xec\xcc\x3e\xd9\xef\x41\xf6\xd1\x22\x67\x02\x17\xd5\xc0\x8f\x6e\x13\xc1\x72\x19\x45\x89\xac\xc3\xc5\x9f\x7e\xf7\x90\xc7\xc8\x5a\xa6\xd5\xeb\x69\xd4\xc8\x9a\x72\xf5\xe7\xc9\x24\x69\x85\xc1\xac\x0c\x5d\x19\x7f\x76\xa7\x3e\x37\x74\x83\x9d\x4a\xa2\x09\x6a\xca\x19\x0a\x30\xf4\xaa\xc5\x40\x57\xb6\x4f\x35\x8e\x0e\x06\x40\x0c\x0d\xf2\xf8\x76\x41\x2d\x34\x48\x4c\x43\x44\xf4\xd7\xc8\x66\x51\x7d\x3e\xfb\xa4\xa9\x0f\xa7\x14\x4c\x9b\xa5\xdb\x33\x61\xdb\x57\x69\x40\x3e\xc8\x16\x26\xa5\x11\xf9\x3e\x30\xf8\x58\x6e\xad\xfc\xaf\xd9\xa3\x6e\xcf\xf8\xd2\x4b\x42\x07\x9a\xda\x8e\x57\x9a\xc3\x08\x51\x17\x7b\xce\x90\x38\xb0\xe1\x30\x00\x72\xd6\x8e\xfd\xd7\x23\xf6\x35\x50\x64\x84\x32\x75\x81\x5a\x66\xb9\xd7\x3a\x12\x99\xaa\x59\xa1\x81\x2f\x64\x52\xfb\x41\x15\xea\x2b\x1f\x9f\xf4\xa9\x96\x90\x59\x6e\x3f\x20\x22\xd8\x1e\xd8\x74\xdd\x67\xe6\x18\x9c\xa0\xe6\x8b\x93\x04\xe9\x93\xa9\x5b\x66\x66\x5e\x0d\x07\x4c"}, +{{0xd1,0xe1,0xb2,0x2d,0xe5,0xe0,0x4c,0x9b,0xe4,0x65,0x1d,0xd7,0x39,0x95,0xa3,0x66,0x6c,0xb5,0x35,0x2c,0x65,0xac,0x7b,0x70,0x51,0xb3,0x66,0xfe,0x1a,0xc0,0xc3,0x10,},{0x12,0xfe,0x56,0xf1,0x01,0x2d,0x5c,0x12,0xf1,0x35,0xed,0x59,0x82,0xf3,0x82,0xae,0x5f,0x11,0x43,0xbc,0x90,0xe8,0xcb,0x8c,0x93,0x05,0x17,0x54,0x55,0x1e,0xe9,0x0a,},{0xab,0xaa,0xb4,0xfa,0x6a,0xeb,0x0a,0x0b,0x34,0xee,0x0d,0x61,0x3a,0x0a,0xf0,0x49,0xed,0xb4,0xce,0xdb,0xfe,0x9d,0x3b,0xeb,0xe9,0xc0,0x06,0x18,0xb1,0x15,0xb9,0xd1,0xfa,0x52,0x4e,0xc3,0x49,0x5e,0x13,0x30,0xb0,0x93,0x61,0x81,0xea,0xbb,0x14,0x29,0x9f,0xac,0xcc,0x40,0xea,0xa8,0xcc,0xa5,0x7e,0xd3,0x24,0xb7,0xa6,0x42,0x0c,0x0e,},"\xc7\xf2\x18\xb5\xaa\x7a\xae\x17\x99\x62\x5a\x56\xc4\xd7\xd7\xb0\x26\x37\xe5\x72\xf1\x41\x1a\x61\x22\xf1\x13\x79\x1a\xa3\xc6\x28\xe8\x19\x60\x2f\xb4\xf0\x33\x5a\x61\x23\x01\x3f\xa6\x4e\x9f\xdc\x4e\x4a\xe4\x97\xbd\x16\x9c\x2f\xa7\x7b\xc2\x36\x12\x97\x17\xf4\x62\x88\x6b\x41\x08\x93\xfa\x78\x09\xcb\xfd\xc8\x92\x22\x3b\x40\xee\x04\x1e\xbd\x4e\xc7\xdd\xab\x55\xbe\x60\x81\xa1\x64\x66\x43\xa9\x12\x0b\xaa\x46\x28\x9a\xcb\xa1\x5b\x3b\x48\xaf\x3b\x7a\xde\xcd\x69\xf4\x3e\xed\xe7\x9d\x9b\x19\x57\xe1\xd8\xc3\x12\x9e\x0f\xa0\x57\x9d\x3d\x39\x53\x70\x46\x1b\x0e\x12\x55\xc9\xca\xa9\x4e\x47\x25\x60\x1c\xb9\xd0\xe2\xd6\x02\x44\xd1\x5b\x64\xe1\xf7\xbc\x90\x15\x59\x0a\xd0\x99\x1f\x12\xf8\x26\x73\x11\x20\x6e\x9e\xb5\xd1\x6a\xdd\x0b\xa5\x21\x8f\xce\x5f\xff\xe1\xc9\xce\x5f\xfe\x1f\x73\x11\x32\xf4\xb1\x2c\xac\xb0\x2f\x97\x45\x17\x10\x84\x6b\x7f\x82\x4f\x4f\xa9\xe0\x89\x19\x26\x64\x69\x78\x9c\x00\xce\x0d\x94\xd3\x8f\xa8\xfe\xc3\xf5\x1f\x2f\x88\x6e\x9d\xb0\x9b\x80\x44\x70\xb1\x9e\xc9\xe8\x06\x63\xf1\x55\xb4\x98\x4d\x2b\xbd\x0b\x2c\xe9\x93\x02\xe0\x6c\x64\x44\x4b\x69\x6e\x31\x29\xfc\xef\x34\xc3\xdd\x00\xf7\xab\x5b\xed\xa7\x47\xa3\xfc\x63\x39\x19\x2b\x74\x0f\x35\x69\xb6\x7d\xbd\x6f\xfa\x39\xe2\x71\xfa\xa4\x00\xd9\x61\x6b\xff\x86\xec\x49\xa6\x59\xde\xf2\xe7\xf5\xd4\x51\xf2\xa2\xb3\x5e\x66\x2a\x6e\x7c\xc2\x2f\x1e\x5c\xdc\xde\x8a\x59\x98\x81\x35\xb7\xe7\x65\x62\x74\x3c\x1e\x6a\x09\x99\x01\xb3\xef\x97\xcb\xff\x23\xf2\x09\xbd\x70\x88\xc2\xf0\x32\x45\x27\x9a\x1d\xc7\x8d\xdd\xc1\xbb\x0c\x1d\x35\x10\x03\x57\x88\x21\x26\xb3\x28\xd3\xd9\x4e\x08\x71\xb6\x0b\xe2\x53\xfd\x1b\x6e\xcf\x03\xc1\xdb\x73\x1d\x9e\xed\x0e\xdf\x2b\x26\x43\x23\x07\x80\xa4\xd6\x6e\x99\x17\x9a\xad\x1b\x82\x40\x2e\x55\xf6\xd7\x85\xeb\xc8\x0f\x8d\xd2\xfd\x2b\xeb\x09\xf3\x10\x35\xdf\x62\xc1\x7f\x42\x8e\xd0\xb2\xd5\x65\x08\xdb\x31\xe6\xd2\xdd\x5f\xb6\x9e\xbe\xee\xa3\x25\x70\x70\xcf\x2f\xe6\x7d\x42\xd2\x88\x16\xa5\x5d\xba\xe0\xb1\x85\xdb\x44\x21\xbb\xfd\xae\xfc\x79\xc0\x8c\xdc\x1a\xcc\xf7\x16\x42\x56\x2e\xc7\x00\x36\xda\x2b\xba\xfa\x4a\x89\x19\x54\xc4\xee\x40\x49\xb5\x5c\x64\x0e\x91\x93\x0e\x39\xe3\xef\x10\x18\xdc\x16\x47\xf2\x69\x42\xc6\xdb\xdf\x4d\x56\xe4\x1e\xb2\xc8\x98\xc8\x21\xfa\xc1\x7c\xc2\x73\xe8\xe4\xaa\x56\x08\xa8\x12\xcf\x4b\x82\xf9\x60\x19\xc2\x52\xd5\x6e\x78\x05\x29\x8c\xcb\xe8\xce\x40\xb0\xbd\x0f\x93\x3b\x88\x4c\x0f\xaf\x97\xa9\x58\xb2\x04\x08\xb8\xa5\x29\x7c\xce\x55\x27\xb2\xca\x21\x28\x06\xe7\x2a\x32\x64\x45\x7a\x7f\xac\x86\x62\xb8\x2c\xa2\x33\xe1\xc7\x75\x8d\xc6\xe4\xf1\xb9\x99\x58\x63\xf2\x5f\x74\x7b\xce\xe4\x3b\x63\x9b\x1f\x8f\x20\x26\xd2\xd2"}, +{{0xdf,0x29,0x4e,0x47,0x7b,0x1b,0x91,0xc5,0xac,0x5b,0x98,0xc3,0x30,0xd2,0x22,0xd7,0xcd,0x2d,0x53,0xe7,0xd0,0xbc,0x0c,0xa4,0x03,0xdf,0x4e,0xc7,0x53,0x27,0xa2,0x74,},{0x5f,0x0b,0xd2,0x2f,0x2f,0x18,0x96,0xd1,0x56,0x3b,0x4f,0x69,0x40,0xc7,0xdf,0x89,0xef,0xc2,0x58,0xc0,0xff,0x6c,0x2f,0xcd,0x67,0x4d,0xaf,0x4f,0x59,0xfc,0xdb,0x60,},{0x99,0x45,0xab,0x73,0xb5,0x85,0x62,0xb3,0x55,0xda,0xbc,0x4e,0x2b,0x6b,0xe7,0xe0,0x5f,0x37,0xf8,0x95,0x71,0x44,0x0c,0xcc,0x32,0xc1,0xa9,0x47,0x37,0x09,0x5b,0x78,0x66,0x74,0x7d,0x21,0x00,0x70,0x00,0xa0,0xf0,0xe3,0x51,0x11,0x4b,0x88,0xe0,0x13,0x8b,0x55,0xdf,0x44,0xfe,0x72,0xeb,0xe9,0x59,0x14,0x10,0xe7,0x07,0xfa,0x9d,0x02,},"\x3e\x42\xd6\x68\x40\x96\x30\xcb\xb8\x48\x12\xac\x7f\xf1\x15\x4f\x70\xfc\xa8\xbd\xff\x3f\x1a\x04\x0f\xa3\xaf\x86\x8a\xa1\xc4\xe9\x15\x08\xb1\xae\xfd\xf5\xc3\xa8\xb4\xb0\x77\xa4\xd1\x62\xd2\xc0\x5b\xd3\x64\xfb\xbe\x8c\x5a\x08\x31\x4c\x2e\x07\xdf\xfb\xd6\xe8\xdd\x2e\x08\xa0\xdc\xc9\x6e\xa9\x2d\xdd\x4c\x97\xf7\x9d\xb9\x42\x5a\x6c\x6b\x34\xc4\x60\x43\xd0\x9a\x68\xb7\x68\x72\x36\xa9\x18\xd2\x1a\x56\x16\x10\xa1\x3a\xc5\xe4\x46\xe0\x88\x1b\xb2\x6c\xc8\xe2\x8a\xad\x16\x54\xf8\x67\xad\x82\xae\x33\xf8\xf7\xa7\x8a\x65\xbe\x57\x69\x94\x75\x51\x6a\x1a\x87\x46\x84\x3e\x93\xa1\xa2\x94\x35\x46\x24\xfa\xc0\x4d\x45\x2c\xcf\xbe\x4f\xdd\x92\xa9\x51\xaa\xa0\x7d\x26\x67\x6d\x5c\xb0\x77\xa5\x00\x0d\x43\x9c\x12\x42\x76\xc0\xdb\xcf\x86\xe7\xaa\x15\x3c\xc2\x4b\x5a\xff\x67\x7c\x6b\xad\xc2\x61\xc2\x89\xf4\xa4\xae\x51\x9b\x2e\x2f\xff\x31\x2f\xbf\x0f\x5b\x4c\x46\x98\xf6\xae\xdd\x8f\xcb\x1d\x23\x48\x94\x2d\xe3\xfb\x73\xba\x27\xf6\xdb\x14\xc2\xf0\x91\x80\x35\x6e\x5f\xca\xe1\xad\xf6\x5e\x22\x42\x5f\x8c\x27\xf1\x9e\x98\x94\x83\x50\x6e\x5d\xf5\x7a\x1b\x61\x3a\x22\xe3\x45\x03\x8b\x3e\xa9\x1c\x0f\x78\xff\xff\x46\x38\x3f\x38\xc7\x22\x25\x35\x8a\x34\x57\x0d\x6f\x66\x4a\x17\x45\x4a\x15\x16\x13\xf0\x1c\xba\x77\x7f\x62\xec\x83\x18\x75\xec\x5e\x27\xd2\x57\xf1\x80\xb6\x36\x6c\xb1\x83\x10\x7c\x40\xf5\x0b\x01\xb2\xb9\xbf\x91\xb3\xb5\x54\x9e\xd9\x31\xa3\x53\x7a\xa4\x16\x89\xf7\x2b\x25\x7a\x6a\xa3\x9c\xdc\x6f\xce\xdf\x14\x39\x83\xbe\x5b\xff\xe3\xae\x2b\x29\xf8\x2f\x88\x21\x22\xd6\x6a\x79\x25\xf5\xa7\x10\x82\x6c\x0d\xad\xb7\xe4\xfa\x4e\xc0\x79\xba\x2e\x76\xda\xda\x43\x3f\x30\x77\xcb\x1e\xf7\x46\x13\xfc\x5d\xbf\x82\x58\xb6\xda\x7c\x73\xc8\x66\x37\x24\x57\xed\x50\x0f\x97\xf9\x90\x7e\x1f\xc2\x63\x53\xc7\x0b\xa3\xbd\x9c\x36\x15\x1d\x46\x86\x5d\x2c\x65\x98\x65\x62\x48\x5c\xf8\x42\x1f\xeb\xbe\x77\x7c\x73\xe6\xcd\x00\x26\xd6\x6d\x35\x12\x8b\x9f\x8f\x33\x26\x4a\xeb\x56\xbd\x3e\x4b\x8d\x1f\x52\x66\x41\x1e\xf3\xb2\x3b\x76\xb3\x6d\x4c\x9d\xf3\xc5\x12\xfd\x56\x0c\x2b\xe5\x2a\xc5\x23\xc1\x93\x77\xad\x2a\xdc\x0e\x8c\x30\x9c\xf5\xbb\xf7\x2d\x9e\xb8\x5d\x65\xa9\x48\x47\xd4\x97\xd8\xd1\x02\x42\x4f\xb8\x43\x81\x66\x6e\xcb\x1c\x35\xa3\x72\x5d\x7d\x9e\x92\x84\xfd\xeb\xb6\xb3\x62\xaa\x6a\x9c\x6f\xb3\x7a\xba\x87\x35\x7f\x57\x4c\x0e\x63\xb4\x49\x7d\x49\x8f\xfb\xb7\xd0\x69\x2d\x78\x4b\x4b\x18\xce\x9f\x91\x50\xc1\x46\xd3\xd1\x8c\x38\x2e\xda\x04\x93\x8c\x69\xd0\x77\x8f\x29\x02\xd5\x23\x5a\x56\x52\xb9\x7c\xef\x6d\x5f\x60\xda\x6b\xd7\xed\x4f\xf9\x7c\xd9\x4d\x49\x39\xca\xca\x3b\x6b\xaa\x3c\xfd\xac\x04\xcd\xa9\x55\x96\xf4\x67\xcb\xc6\xcb\xcd\x92\x64\x16\x77\x43\xea\xc1"}, +{{0x70,0xc6,0x85,0x9f,0x08,0xcf,0x42,0xb4,0xbd,0xa9,0xeb,0x62,0x97,0x9d,0xff,0xb7,0xcb,0x08,0xeb,0x3d,0xab,0xe9,0x3f,0xe9,0x4b,0x01,0x38,0x46,0x17,0xcf,0x67,0x30,},{0x40,0x1c,0x9e,0x20,0x33,0xe2,0x25,0x9f,0xb6,0x38,0x3b,0x3e,0x8b,0x9e,0x17,0xb3,0xf2,0x06,0x27,0x46,0xbb,0xe6,0x48,0xcf,0x48,0x45,0x16,0xdb,0x0f,0x2f,0x1b,0x06,},{0x0f,0x03,0xa4,0xf1,0x5c,0x33,0x9b,0x4f,0x7b,0x88,0xb4,0xe2,0x1a,0xd9,0xe3,0xd6,0xbb,0xf3,0xef,0xfb,0x7b,0x67,0x8f,0xfa,0x50,0x0d,0x47,0x38,0x3b,0x71,0xa7,0x45,0x4f,0x62,0x90,0x7b,0x56,0xf5,0x9f,0x9b,0x9a,0xf6,0xd5,0xb2,0xa0,0xfc,0x1c,0x73,0x7a,0x64,0x10,0x51,0x95,0x08,0x98,0x99,0xf5,0x7a,0x2c,0x9d,0xba,0x50,0x9e,0x0a,},"\xdd\x06\x09\xea\x15\x99\x21\x39\x5d\x11\xfb\x2d\xa8\xea\x4f\x74\x7d\x7f\x74\xb5\x80\x52\xe0\x1c\xad\x40\xa2\x71\xfa\x0b\xbe\xed\x91\x02\x0f\x4f\x0c\x08\x46\xc4\xf0\x77\x78\xa6\xaa\x76\x8e\xb5\x17\x12\x29\x4e\x9e\x1f\x32\xa6\x02\xb1\x52\x51\x4f\x5e\x6d\x39\xf9\xe0\x8f\x7a\x78\x12\xbd\x90\x0c\x10\xa9\x14\x69\xe4\x7e\x8a\x78\xe5\x4c\xd4\xbd\x7c\xfe\xde\xde\xc1\x71\xef\x37\x3f\x1c\x4f\x9b\xbc\x2c\x81\x40\x2f\xb1\x4e\xd0\xbf\xac\x8d\x04\x3f\x11\x7d\x61\x24\x52\x1a\xfa\xe0\x91\x6a\x51\x0d\x56\x8a\xcf\xa3\xaa\x33\x01\xbc\x97\x9a\xc2\x8d\x55\x1d\xbb\xea\x6c\xea\xc4\xc2\x12\xaa\x8c\x84\x92\xb3\x61\x3a\xe7\x39\x5d\xd4\x12\x5f\xc4\xc2\x5d\x5b\x4d\x99\x23\x08\x21\xd4\xb1\x7e\xc2\xee\x6b\xe7\xd6\x04\x19\x5a\x21\x54\x33\x3b\x97\x35\x26\x58\x0c\xa7\xef\x9e\x30\xc6\xc1\xdd\x42\xef\x2a\xfe\x42\xb1\x1b\x1a\xa4\x9b\x9c\xca\xba\xca\x17\x09\x1e\xeb\x38\x0e\xc5\xe3\x4a\xd1\xe3\x82\x7c\xc6\x0d\xac\xf1\x44\x28\x6c\x78\x92\x59\x0b\xd2\x67\x1a\x8d\xc5\xf3\xa7\x02\xc1\xde\x7c\xd3\xb4\x2c\x1b\x15\x0b\x09\xc3\xe5\x8e\xf6\x94\x3b\x45\xd8\x9d\x41\xdf\x36\x1f\x1d\x5c\x25\x56\x55\x91\xb6\xac\x8d\xea\xa7\x36\x76\x53\x1f\x6e\x5a\xbe\x58\x04\xb0\x09\x7f\x8d\x45\xea\x29\x39\x17\x73\x33\xca\xce\xf1\x2e\x4b\x71\xfe\x49\x36\xba\xfe\x00\x74\x7a\x89\x30\xbc\xea\x55\xb8\xfd\x84\xa0\x1f\x6d\xf8\x4e\x7a\xcb\x93\x1f\xc7\xc0\x1d\xdf\xd6\x3d\xee\xc3\xad\x3e\x69\xdf\xa2\xb7\x35\x50\x58\x3d\x57\x47\xee\xe9\x6c\x55\x36\x36\x87\x97\xe2\x47\xf2\x3f\x53\x7d\x79\x07\x9a\xb6\xda\x31\x41\x02\xc7\x44\x3d\x41\x96\x0e\x3a\x3d\x8c\x35\x9c\x4a\x4e\xc6\x26\xfc\xc4\x4e\x11\x0e\xa7\x44\xd4\x17\xaa\x85\x0d\xb8\xec\xdb\xfe\x34\x0a\x96\x2d\xb0\xd8\xc5\x7d\xc5\x17\xbe\x8b\x40\xd1\x4d\xe9\x7b\x1e\x9e\x04\x26\x44\x7f\xde\x0a\x04\xe5\x06\x79\xc5\x3b\xa1\xaa\x3c\xdc\x38\xc7\xed\xe6\xdb\x6c\x05\x4b\x1e\x9c\xe7\xde\xad\xaf\x93\xeb\xdd\x47\x07\x91\x53\x5f\x3e\xcf\xab\xf3\x41\x63\x55\xf7\xa1\x8a\x38\xaf\xe6\xbf\xe5\x07\xef\x08\xc4\x37\x3a\x4a\x69\xde\xe1\xfc\xb6\x5b\x16\x31\xa0\xde\x14\x88\x64\x9d\x0b\xb2\x67\x9a\x9a\x45\xf6\x78\x20\xb2\xa4\xa1\xe5\xa5\x48\x07\x2d\xa7\x03\x2d\x17\x25\x55\xe7\x88\xcc\x98\x60\xeb\xb3\xc0\xc3\x59\x49\x37\x51\xb0\xc2\xc9\x50\xa7\xfc\xf4\x80\x3c\x14\x7f\x93\x40\xfc\x93\xd8\x5f\x1e\xfa\x57\xb3\x90\x81\xb9\x2d\x93\x47\x3f\xd2\x35\x16\xc4\x95\x0e\xd4\xb2\x9a\x2e\xd3\xa0\x42\xae\x3d\x92\xa1\xe5\x2c\xb7\x09\x63\x6f\xc7\x27\x2f\xd7\x47\x20\x8b\xee\x2b\x16\xd1\x91\xe4\xc6\xde\xb2\x76\x72\xaa\x34\xe4\x39\x14\xcf\xf2\x05\x5c\xa4\xee\x8b\xa3\xe1\xdc\x58\xa6\x79\xc7\xf7\xde\xe2\xc1\xd5\x3e\x28\x75\x09\x70\xf5\x7d\x85\xea\xb1\xc2\x6b\x89\xbb\x73\xe0\xb1"}, +{{0xc5,0x96,0x29,0x61,0x81,0x5b,0x57,0xcd,0x16,0x24,0x03,0xce,0x08,0xe4,0x10,0x5d,0xdb,0x8a,0xae,0x2d,0x3f,0x53,0x3f,0xb4,0x9c,0xc2,0x36,0xb5,0xff,0x50,0x4d,0x6e,},{0xdb,0xad,0xe7,0x22,0x36,0xba,0x12,0xd4,0x97,0x7b,0xa4,0x6c,0x36,0x4b,0xb6,0x9a,0x88,0x7f,0xf4,0x02,0xde,0x91,0xd4,0x7a,0xfa,0x9b,0x93,0xc9,0x5b,0xe7,0x1e,0x7e,},{0x81,0x01,0xba,0xef,0x00,0x4e,0xb6,0xf5,0xad,0x4d,0xe0,0x97,0x9f,0xf3,0x6d,0x34,0x39,0xb8,0x21,0x2b,0xdc,0x92,0x89,0x42,0xe4,0x31,0x91,0x5b,0x3f,0xd1,0x8b,0xc2,0xad,0x67,0xb2,0x6f,0x18,0x94,0x1d,0xcb,0x16,0xd2,0xc2,0x91,0x91,0x42,0x1e,0x77,0x9f,0xed,0x62,0x2f,0xd9,0xf5,0x82,0x64,0x4e,0xaa,0xdb,0x3f,0xe5,0xc0,0x98,0x03,},"\x4a\xe4\x14\x8d\x79\xca\x94\x25\x59\x2a\xa2\x40\xbd\x15\x34\x24\xa3\xbf\x4a\xe2\x73\x95\x87\x2c\xe5\x72\x8a\xc7\x61\x35\x96\xa7\x7d\x5c\xe8\x56\x5d\x8d\x6e\x1b\x59\x35\xb3\x90\x6c\xaf\xe1\xff\x88\x8e\xbc\x98\x15\xe0\x4a\x62\x4d\xfc\x4c\x69\x07\xb8\x5f\x6f\x1a\x0d\xbd\xdf\xf6\x2e\x91\x51\x22\x0d\x47\x44\x62\xcb\x9f\x13\xd8\x9d\x3a\x93\xa0\x0b\xa2\xb6\x0f\x7e\x7c\xa6\x3d\xa1\x7a\x63\x79\xd6\x73\x55\x1e\x79\x0b\x59\x11\x72\x7c\x90\x6d\xc9\x4f\x86\xd8\x27\x75\x46\xc1\x56\x4a\x45\x57\x3a\x77\x43\xbb\x8a\x13\x8c\xde\x87\xb3\xb2\xf2\x8e\x5e\x24\x59\x40\xa5\x1e\x7c\x45\x8c\xf8\xc5\xf0\xa7\x02\x75\x96\x25\x53\xe0\xd2\x39\x0d\x17\x1d\xb4\x4c\x2f\x7a\x5c\x9e\x9f\x93\xb9\x0f\x7a\x5f\x54\xf1\x91\xb0\xd8\x75\xba\xd7\xe0\xbe\xb9\x80\xc2\xa3\x36\x5c\xd7\xb9\x20\x87\x24\xf4\x65\x44\x18\x11\x7e\x16\xef\x71\x34\xe3\xe2\x79\x4b\x6f\x9e\x80\xec\xab\xec\xa3\x25\x4e\x70\x4c\x21\xb7\xad\x30\xc5\xde\xe0\x17\xea\x25\x33\xfc\xd9\x42\x51\xe5\x5a\xe7\x5a\x8c\xc6\xdb\x66\x74\xb3\x9c\x88\xca\x42\x00\x60\x43\xd6\xbd\x9b\x00\xec\xf6\x4c\xea\xfe\xeb\x40\x2b\x1f\x22\xfd\x89\x1f\x2d\x11\xc5\x15\xc1\xab\xa6\xa2\xd4\xc0\xbd\x21\x81\xa4\x8e\x43\xfd\x1c\x0a\xf9\x1f\x9b\x7b\x7d\x37\xf3\xdc\xd9\xe4\xc0\xa7\x59\x74\x84\x67\xd3\x48\xa8\xb1\x16\xdf\x6a\x4e\xac\xf1\x78\xae\xcc\xcd\x30\x66\xe9\x2d\xca\x45\xda\x7a\x3e\x31\x9f\x37\x71\xeb\x34\x90\x02\x21\x93\xc5\xb6\x52\xf0\x45\x68\x7e\x17\x05\xf2\xe5\x69\x1c\x13\x4b\xe4\x00\x63\x53\xd7\xec\xd0\xe9\x18\xd5\xde\x0f\x3b\x87\x80\x9f\xca\x4a\xcf\xab\x94\xe1\x14\x8f\xf7\xcf\x07\xf7\xcf\xd0\xc7\x45\xdd\x2b\xe0\x1a\x24\xa5\xe0\x69\x28\x06\x98\xbc\x3f\x54\x00\xa6\xdc\xd0\x8e\x44\x59\x5c\x03\x88\xe4\x48\x33\x76\x8f\xc4\x91\x04\xee\x11\x5b\xdc\xb0\x2b\xfb\xda\x17\x9d\x16\x4c\xe9\x69\x93\x66\x29\xf2\x33\x56\x01\xb5\x6f\xe8\xf7\x85\xcc\xa3\x80\x5f\x04\x03\x87\x2c\x62\xf7\x3c\x3c\xe8\x05\x63\xd0\x70\xe9\x76\xd8\xec\xc5\x11\x24\xe2\xca\xce\x7e\xe1\x86\x99\x04\x7c\xb0\xf8\xfb\x8d\x9c\x59\xb8\xa6\x0d\x12\xc0\x8a\x09\xfc\xe5\x8f\xd9\x2c\xd3\x6d\xb6\xa8\xe8\x9d\x11\x8c\xf8\x8a\x92\xdc\x8a\x26\x00\xbd\x95\xf5\xa8\xe8\x5d\xb5\xcd\xbb\x24\x9c\xa8\x12\xca\x20\x9c\x76\x18\x05\x1c\x45\x64\xa3\xa0\xe1\x92\xb7\xe4\x59\x92\x45\x6c\x87\xd1\x74\x12\xc1\x1a\xde\xad\x52\x6a\xb8\xdb\x21\x45\x2f\x74\x71\xd1\x7f\x2e\xbc\x90\x01\x54\x50\xed\xf4\xf0\xa4\x4f\xb2\xf4\x90\x5f\x74\xd7\x02\x75\xcc\xd8\x9b\x93\xa6\x50\x47\x3c\x02\xa7\xda\x0c\xbc\x67\x91\x5c\xeb\x7a\x1e\xa5\x9f\xa8\x88\x44\x72\xdc\x91\x7e\xe9\xd2\x46\x33\x9c\x59\x26\x84\x3e\xcf\x53\xfa\xfd\xc5\x6a\x69\x56\x01\xa2\x76\xc2\x3a\x84\x3e\x4d\x30\xf8\x9c\x97\xc9\xee\xe6\xdf\xc7"}, +{{0xde,0xe6,0x86,0x6c,0x78,0x74,0xc1,0x27,0x02,0x9e,0x96,0xe0,0x25,0xbf,0xfd,0x35,0xfc,0xfd,0xf4,0xdc,0x36,0x96,0x6c,0x15,0xee,0x62,0x93,0x36,0x80,0x13,0xd3,0x79,},{0x08,0xc9,0x4d,0xa3,0x51,0xbb,0x2b,0xee,0x72,0xe6,0xe1,0x96,0xbe,0x74,0x88,0x07,0x58,0x37,0x62,0xc5,0x29,0x6e,0x05,0xb1,0xe5,0x29,0xc4,0x7c,0x6b,0xba,0xce,0xc6,},{0xb7,0x8e,0xbd,0x6d,0x65,0xb1,0x75,0xd4,0xbb,0xd3,0xd9,0xa2,0x08,0x2a,0x0e,0xfe,0x6e,0x99,0x1c,0xb2,0xe4,0x03,0x52,0x1e,0xec,0xe0,0x0f,0x41,0x8f,0x2e,0x95,0x6b,0x66,0x90,0x78,0x80,0x65,0x8b,0x9e,0x8e,0x47,0x69,0x96,0x53,0xd1,0x59,0x13,0x23,0x80,0xd9,0xce,0x11,0x09,0xaf,0x9c,0x27,0x57,0xda,0xf4,0xcd,0xf1,0x8c,0x9c,0x0a,},"\xf1\xaa\x19\x77\xf5\x31\x1b\x53\x8b\x94\x0a\xe4\x42\xa3\xab\xc8\x9a\xac\xcd\xcd\x0a\x79\x38\x0a\x24\x25\x8d\x4a\x9f\x1c\xe6\x38\xfc\x2f\x5b\xa2\xe5\x3f\x8e\x1f\xa6\x17\x6f\x17\x8d\x90\x24\xa7\x78\x94\xc2\x8c\xad\x42\xd6\x29\xc7\x93\xd6\x8a\x02\xbe\x94\x11\xb5\x27\xac\xad\xae\x7e\x5c\x38\x51\xba\xbb\x45\xb5\xfe\xce\x32\x9e\x29\x03\x4c\xd4\x25\x71\x08\x37\x27\xf3\x5a\xec\xad\x7c\x9b\xe5\x95\x4e\xc6\x4e\x8f\x6e\xca\xb7\xcc\x05\x90\xe5\x41\x56\xa4\xe1\xa4\x53\x03\x84\x9f\x78\x97\xe7\x2c\xf2\xfb\xcd\x84\xf5\x6c\x72\xf9\x41\xdb\xb0\xb0\x9a\x32\xe6\x38\x6f\xbe\x18\xa4\x3b\xb9\xbd\x8b\x79\x3e\x4b\x9e\xdd\x53\x21\x03\xea\xb5\x4d\x62\x71\x17\xd2\x81\x39\xb6\x4e\x60\xfb\x0b\x81\xd0\x90\x01\xbb\x24\x04\xd9\x25\xe2\x65\xba\xbd\xc6\x9f\x96\xb1\x35\xe9\xe6\xab\x7f\xeb\xb1\xed\x30\x75\xd6\xaa\x2a\xbd\x2b\xbf\x9b\x65\xfa\x9b\x3b\x71\x91\xef\x37\xb6\x33\x60\x59\x10\xee\x88\xf6\x6e\xad\xa7\x9f\x00\xf5\x36\xd3\x80\xb8\x2f\x2f\x4b\x59\x85\x11\x2d\xe0\x04\xa5\x66\x03\xf4\x43\x6d\x8f\xf3\x00\xf4\x2b\xf5\xac\xdc\x7a\x4b\xf1\xea\x9d\x41\x96\xc4\x80\x49\x5b\xac\xb0\x06\x76\x30\xfc\xc0\x00\xb4\xf2\x79\xdd\x3f\x30\xf3\x53\x27\x60\x92\xd1\x52\xc3\xf4\x3e\xfd\xc0\x41\xde\xaa\x0b\xc5\xaa\xab\xa7\xf8\xbb\xd8\x5e\x69\xc1\x37\x42\xd6\x78\xdb\xb6\x53\x60\xaa\xf7\xb5\x48\xa0\x44\xc0\xec\x60\xa5\x7a\xf6\x50\xbc\x31\x97\x3f\x83\x2f\x96\x12\x65\xbc\x23\x18\xf8\x07\x75\xaf\xd5\x1f\x55\x19\x4c\x42\x42\x3f\x7b\xf4\xe0\x05\x2f\x98\xcb\x20\x69\x13\xff\xea\x48\x86\xec\xd2\x7a\x41\x79\xb1\x37\x73\xf9\x47\x50\x2e\x18\x1b\xf1\xa1\xf2\xc6\x2c\x6f\x08\xc2\x03\x59\xf0\x6d\xf2\xb1\x81\x27\x04\x3b\x10\x70\xd0\x19\x4e\xf5\xe5\xbf\xd3\x7d\x22\x79\x84\xcf\xb1\x09\x89\xf2\x1c\x71\xad\x0f\xe3\xb8\x12\x27\xd3\xa7\x17\x89\x45\x5e\xda\x38\x3c\x22\xf4\xd2\xfc\xc7\x25\x79\xf4\x65\xe0\x66\xf3\xd3\x8b\xef\xc0\x24\xef\xef\x6c\x2e\x32\x96\x49\xce\x43\x4d\x62\x73\x67\xa9\x00\xd0\x7f\xe6\x23\x42\x35\xc8\x46\x56\xea\xc5\xdd\x0d\x78\x8c\xf4\xcb\x31\x87\x18\x24\xd6\x6a\xe4\xbc\x89\xed\xeb\xa1\xb3\x67\x01\x29\x84\x53\xe8\xda\x1e\x69\xcf\xb8\x68\x09\x5c\x3b\xe6\xed\x21\x82\xda\x1c\xff\x49\x05\xaf\xd2\x07\x31\xac\x1e\xd9\x84\x16\x47\x37\x90\x3c\x7d\x8b\xb0\xad\x16\xae\xcf\x2f\xae\x33\x74\x04\xfe\x35\x66\x45\x15\xd9\x3b\x70\x1e\x2f\x87\x86\x64\x45\x4c\x0d\xec\xd1\xc6\x55\x8a\xda\xce\x3c\xdb\x22\x75\x07\xa5\x16\x06\xf0\xa5\x4d\xf8\xdf\xaa\x42\x02\x05\xdd\x57\xc6\x52\x42\xff\x24\xa4\x05\xef\x85\xc9\x2d\x60\x28\x86\x93\x2b\x35\xfa\xbe\x9c\x3b\xce\xbf\xc6\x23\x56\x39\xe8\x73\xfc\x2d\xd0\x84\xc5\x2c\xd6\xa7\x41\x3b\x83\x1d\x1c\xc9\x99\x31\x37\x3a\xab\xd8\x47\x62\x0e\xb6\x9b\xb0\xfa"}, +{{0x52,0x36,0x23,0x55,0x59,0x95,0xba,0xaf,0x2a,0x27,0xad,0xcb,0x1e,0xba,0xfa,0xa8,0x02,0xd2,0x3e,0xf7,0xab,0xfa,0x97,0x75,0xf2,0xc9,0xbf,0xa0,0x7d,0x64,0xe0,0xac,},{0xd3,0x4d,0xea,0xe6,0x52,0x3e,0x61,0x9d,0xd1,0xbf,0xc8,0xf3,0xc4,0xca,0x4b,0x78,0xb3,0x68,0xc0,0xf7,0x20,0x03,0x5e,0x14,0x4c,0x3f,0x2f,0xc1,0x05,0xd4,0xce,0x21,},{0xb1,0x87,0x17,0x29,0xfe,0xc8,0x3a,0xea,0x0a,0xaa,0x47,0x2b,0x70,0x0a,0xcd,0x09,0x48,0x13,0xfb,0x7d,0x57,0xb9,0x09,0xe0,0xea,0xaf,0x21,0xee,0x93,0x18,0x47,0xad,0xde,0xdd,0x2b,0xe8,0x53,0x3d,0x0c,0x30,0x5c,0xb9,0xcf,0xe5,0x08,0x0e,0x76,0xc2,0x80,0x8b,0x6e,0x51,0xc9,0x82,0x62,0x90,0xdd,0xb7,0xb9,0x4b,0x6f,0x7d,0x58,0x0b,},"\x05\x53\xe6\x9e\xf2\x11\x65\x2d\x62\xbf\x28\x1b\xfb\xdd\x37\xbe\x22\x76\x9d\x81\x97\x46\x36\x1c\x7d\x65\xdd\xd0\xfa\xd6\x77\xcc\x04\x38\xb3\x01\xd1\x51\x45\x78\xe0\xda\x58\xe5\x5f\x72\x9f\xa8\xe6\x6d\xde\xb7\xf9\x73\xa8\x18\xd2\x4e\xd8\xfe\x02\x7b\x84\x91\x17\x9d\x07\x77\x3f\xb5\xd2\xbb\x96\xaa\x85\xd6\xb3\x75\x04\x54\xe5\x0d\xe9\x1f\x9b\x88\xae\xe8\xaa\x68\xe6\xbb\x53\xed\xc6\x66\x77\xb4\x1e\x60\x1a\x46\xab\x4b\xb1\xe6\x56\xe7\xfa\x5f\x01\x79\x93\x36\x80\xa6\xec\x95\x04\x27\x5e\x7a\xdf\x7a\x32\x48\xe6\x3a\x0f\xc9\xc1\xea\x5a\xe9\x6c\xd0\xc6\x5a\x89\xa7\x7c\xec\x2b\x1f\xd8\xf4\x53\x7e\x82\xc1\xc4\x88\xa6\x9a\x0e\xf6\x4f\x58\x73\x4d\x9e\x73\x47\x8e\x1d\x1f\x12\x31\x14\xef\x66\x08\x5e\x0b\xa3\x19\xcb\x81\x0b\x66\xaf\x96\xd1\x30\x8b\x1a\x2b\xd9\x2b\xa2\xc2\x65\xaa\x30\x9e\xcd\x55\x57\xd4\x02\xc3\x80\x2c\xae\x8d\x7e\x95\x00\x7f\xe6\x10\xc2\xaa\x75\xfc\x66\x19\x6c\x3f\xad\xfe\x99\x7d\x6d\x59\x98\xe1\x8d\x26\x0e\x9d\xa3\x1d\xa9\x21\x8c\xba\xd1\x03\xcb\xfc\x2c\x75\x47\x76\x5d\x67\xe8\x1f\x24\xac\x83\x02\x2e\xf5\x1c\x6c\xc5\x08\x64\x36\x6a\x35\xf6\xb9\xb9\xaf\x94\xe8\x4c\xaa\x9f\xd3\xd7\x67\xc8\x31\xf0\x96\x7a\x61\x46\x2f\xbc\xfc\xc8\x03\xf1\x2e\x37\x39\x03\x9a\xcd\x5d\xbe\x93\x66\xf0\x5a\x33\xdb\xea\xf3\x60\xe2\xdd\xcb\xe5\xc4\x43\xf8\x0e\xf2\xad\x62\xe0\x3c\x1d\x5b\x70\xcd\xea\xb4\xa7\xdd\x41\x55\x30\x64\xc8\xd1\x52\x70\x9d\xef\xf8\x20\x76\xb9\x07\x11\x92\x37\x6f\x51\xd4\xc2\xc7\x1a\x84\xe8\x9f\x2d\x94\x01\x32\x0c\x2e\x45\x9b\x3e\x24\x3c\xca\x7c\x26\xfd\x09\x8c\x26\x4a\xc8\x8e\xf6\x38\x92\x1d\x98\x0b\x0a\xe9\xe5\x12\xd3\x72\x03\x7d\x81\xad\xc4\x81\x26\xd7\xc9\xe4\xb5\xaf\xa5\x7e\xc2\x65\xd4\x01\xb9\x65\x3e\x92\x8a\xfb\x7d\xff\x9b\x48\xe2\x95\xe4\x70\xd6\xb5\x2e\x88\xb3\x9d\x0a\x40\xcb\x8e\xba\x24\x9f\x8b\x13\xd8\x11\x13\xdb\x1d\x3e\x01\xef\x75\xc7\x22\xf2\x69\x48\x8e\x96\x3c\xc8\x18\x27\x04\xf8\xca\x01\x8e\x73\xdc\x07\x14\xe9\xa9\xfc\x79\xbc\x43\x63\xc2\x8c\xb3\x98\x43\x74\xf7\x3b\x2a\xa8\x78\x6e\x74\xe0\x15\x95\x07\xa2\x98\x83\xfe\x0e\xd1\xc6\x00\xf5\x25\x88\x5f\x2f\x10\xea\x00\x6c\x39\xe5\x9b\x92\x5b\x76\x5b\x1e\xde\x53\x42\x57\xa1\xf4\x0f\x28\x46\x58\x4f\x06\x97\x46\xb5\x2f\x56\x00\x43\x0a\x28\x63\xd7\x93\x60\x95\xfb\xc2\x2a\x6a\xda\x67\x4d\x41\xb3\x74\xe2\xb8\xb9\xa1\x9f\xa7\x12\xb5\x94\x45\x33\xbb\x6d\x6e\xc4\x3b\x89\xd4\x97\x1b\x70\x20\x5a\x6a\xcd\x72\xa8\x99\xda\x12\x61\x82\x04\xdb\x0c\x3e\x82\x67\xb8\x45\x79\x16\x93\xe0\xae\x6a\x35\xf1\x4d\xa1\xf8\xf4\xdd\x17\x4b\xce\x03\x18\xfb\x5a\x00\xf6\x72\xed\xe4\x23\x04\xcf\x04\xa6\x27\x60\x57\x75\x90\xf2\x7e\x2d\xfa\x6e\x5e\x27\x95\xd6\x60\x53\xb3\x0a\xf7\xf1\xbf"}, +{{0x57,0x5f,0x8f,0xb6,0xc7,0x46,0x5e,0x92,0xc2,0x50,0xca,0xee,0xc1,0x78,0x62,0x24,0xbc,0x3e,0xed,0x72,0x9e,0x46,0x39,0x53,0xa3,0x94,0xc9,0x84,0x9c,0xba,0x90,0x8f,},{0x71,0xbf,0xa9,0x8f,0x5b,0xea,0x79,0x0f,0xf1,0x83,0xd9,0x24,0xe6,0x65,0x5c,0xea,0x08,0xd0,0xaa,0xfb,0x61,0x7f,0x46,0xd2,0x3a,0x17,0xa6,0x57,0xf0,0xa9,0xb8,0xb2,},{0x90,0x3b,0x48,0x4c,0xb2,0x4b,0xc5,0x03,0xcd,0xce,0xd8,0x44,0x61,0x40,0x73,0x25,0x6c,0x6d,0x5a,0xa4,0x5f,0x1f,0x9f,0x62,0xc7,0xf2,0x2e,0x56,0x49,0x21,0x2b,0xc1,0xd6,0xef,0x9e,0xaa,0x61,0x7b,0x6b,0x83,0x5a,0x6d,0xe2,0xbe,0xff,0x2f,0xaa,0xc8,0x3d,0x37,0xa4,0xa5,0xfc,0x5c,0xc3,0xb5,0x56,0xf5,0x6e,0xdd,0xe2,0x65,0x1f,0x02,},"\x2c\xc3\x72\xe2\x5e\x53\xa1\x38\x79\x30\x64\x61\x0e\x7e\xf2\x5d\x9d\x74\x22\xe1\x8e\x24\x96\x75\xa7\x2e\x79\x16\x7f\x43\xba\xf4\x52\xcb\xac\xb5\x01\x82\xfa\xf8\x07\x98\xcc\x38\x59\x7a\x44\xb3\x07\xa5\x36\x36\x0b\x0b\xc1\x03\x0f\x83\x97\xb9\x4c\xbf\x14\x73\x53\xdd\x2d\x67\x1c\xb8\xca\xb2\x19\xa2\xd7\xb9\xeb\x82\x8e\x96\x35\xd2\xea\xb6\xeb\x08\x18\x2c\xb0\x35\x57\x78\x3f\xd2\x82\xaa\xf7\xb4\x71\x74\x7c\x84\xac\xf7\x2d\xeb\xe4\x51\x45\x24\xf8\x44\x7b\xaf\xcc\xcc\xec\x0a\x84\x0f\xec\xa9\x75\x5f\xf9\xad\xb6\x03\x01\xc2\xf2\x5d\x4e\x3b\xa6\x21\xdf\x5a\xd7\x21\x00\xc4\x5d\x7a\x4b\x91\x55\x9c\x72\x5a\xb5\x6b\xb2\x98\x30\xe3\x5f\x5a\x6f\xaf\x87\xdb\x23\x00\x1f\x11\xff\xba\x9c\x0c\x15\x44\x03\x02\x06\x58\x27\xa7\xd7\xaa\xae\xab\x7b\x44\x6a\xbc\xe3\x33\xc0\xd3\x0c\x3e\xae\x9c\x9d\xa6\x3e\xb1\xc0\x39\x1d\x42\x69\xb1\x2c\x45\xb6\x60\x29\x06\x11\xac\x29\xc9\x1d\xbd\x80\xdc\x6e\xd3\x02\xa4\xd1\x91\xf2\x92\x39\x22\xf0\x32\xab\x1a\xc1\x0c\xa7\x32\x3b\x52\x41\xc5\x75\x1c\x3c\x00\x4a\xc3\x9e\xb1\x26\x7a\xa1\x00\x17\xed\x2d\xac\x6c\x93\x4a\x25\x0d\xda\x8c\xb0\x6d\x5b\xe9\xf5\x63\xb8\x27\xbf\x3c\x8d\x95\xfd\x7d\x2a\x7e\x7c\xc3\xac\xbe\xe9\x25\x38\xbd\x7d\xdf\xba\x3a\xb2\xdc\x9f\x79\x1f\xac\x76\xcd\xf9\xcd\x6a\x69\x23\x53\x4c\xf3\xe0\x67\x10\x8f\x6a\xa0\x3e\x32\x0d\x95\x40\x85\xc2\x18\x03\x8a\x70\xcc\x76\x8b\x97\x2e\x49\x95\x2b\x9f\xe1\x71\xee\x1b\xe2\xa5\x2c\xd4\x69\xb8\xd3\x6b\x84\xee\x90\x2c\xd9\x41\x0d\xb2\x77\x71\x92\xe9\x00\x70\xd2\xe7\xc5\x6c\xb6\xa4\x5f\x0a\x83\x9c\x78\xc2\x19\x20\x3b\x6f\x1b\x33\xcb\x45\x04\xc6\xa7\x99\x64\x27\x74\x1e\x68\x74\xcf\x45\xc5\xfa\x5a\x38\x76\x5a\x1e\xbf\x17\x96\xce\x16\xe6\x3e\xe5\x09\x61\x2c\x40\xf0\x88\xcb\xce\xff\xa3\xaf\xfb\xc1\x3b\x75\xa1\xb9\xc0\x2c\x61\xa1\x80\xa7\xe8\x3b\x17\x88\x4f\xe0\xec\x0f\x2f\xe5\x7c\x47\xe7\x3a\x22\xf7\x53\xea\xf5\x0f\xca\x65\x5e\xbb\x19\x89\x6b\x82\x7a\x34\x74\x91\x1c\x67\x85\x3c\x58\xb4\xa7\x8f\xd0\x85\xa2\x32\x39\xb9\x73\x7e\xf8\xa7\xba\xff\x11\xdd\xce\x5f\x2c\xae\x05\x43\xf8\xb4\x5d\x14\x4a\xe6\x91\x8b\x9a\x75\x29\x3e\xc7\x8e\xa6\x18\xcd\x2c\xd0\x8c\x97\x13\x01\xcd\xfa\x0a\x92\x75\xc1\xbf\x44\x1d\x4c\x1f\x87\x8a\x2e\x73\x3c\xe0\xa3\x3b\x6e\xcd\xac\xbb\xf0\xbd\xb5\xc3\x64\x3f\xa4\x5a\x01\x39\x79\xcd\x01\x39\x69\x62\x89\x74\x21\x12\x9a\x88\x75\x7c\x0d\x88\xb5\xac\x7e\x44\xfd\xbd\x93\x8b\xa4\xbc\x37\xde\x49\x29\xd5\x37\x51\xfb\xb4\x3d\x4e\x09\xa8\x0e\x73\x52\x44\xac\xad\xa8\xe6\x74\x9f\x77\x78\x7f\x33\x76\x3c\x74\x72\xdf\x52\x93\x45\x91\x59\x1f\xb2\x26\xc5\x03\xc8\xbe\x61\xa9\x20\xa7\xd3\x7e\xb1\x68\x6b\x62\x21\x69\x57\x84\x4c\x43\xc4\x84\xe5\x87\x45\x77\x55\x53"}, +{{0x03,0x74,0x9c,0xa2,0x04,0x58,0xa3,0x5a,0x37,0xa8,0xd7,0xa2,0x6f,0x95,0x9f,0x0d,0x59,0xf6,0xdc,0x99,0x73,0xfa,0x36,0x3c,0x1f,0xf8,0xca,0x4e,0x63,0x8c,0x2c,0xd3,},{0xea,0xeb,0x94,0xf4,0x06,0xbd,0xe6,0xa7,0xcf,0x8b,0xde,0x2a,0xdf,0x30,0x81,0xf8,0x37,0x5b,0x87,0xd9,0x33,0x5d,0x49,0x6c,0x71,0xd0,0x42,0xcd,0x2e,0xaa,0x16,0x6c,},{0x78,0xa3,0x87,0x7e,0x02,0xbd,0xfd,0x01,0x5e,0x7f,0x86,0xa3,0x27,0xa4,0x8c,0xc3,0xa5,0x23,0x0b,0xbd,0xb1,0x24,0x3f,0x1a,0x8c,0xf2,0x27,0xf7,0x8a,0xb5,0xe7,0x68,0x0d,0xe3,0x01,0xa9,0x15,0xdc,0x11,0xb3,0x36,0xfb,0x5f,0x65,0x66,0x84,0x8b,0x42,0x50,0x0a,0xdb,0x5d,0x67,0x39,0x69,0x12,0x2b,0xa8,0xf0,0x05,0x3c,0xd3,0x06,0x0b,},"\xee\xf5\xce\xeb\xd0\x44\x5e\x9c\x91\x81\xaf\xf9\xc6\xf2\x66\x01\x28\xfc\xfb\x63\x69\x1a\x42\xcf\xa4\x43\xd6\xa6\x49\xef\xc5\xfa\xd8\xc2\x08\x03\x76\x3e\xe9\x7d\x1d\xba\x08\xe6\x3e\x08\xa2\x61\x6d\xa0\x50\x77\x48\x9f\x2f\xa2\xc5\x6b\x75\x34\xf9\x40\x26\x19\x25\x1f\xdf\x9c\x32\x0d\xe7\xaf\x10\x9e\x2f\xd8\xb2\x56\x5c\xe8\xa7\x52\x4c\x94\x05\xec\x0f\x8f\xca\xa7\x14\x9a\x6d\x21\x0e\xfd\xe8\x3b\x11\x1c\xf8\x2d\xc0\x83\x5c\xf9\x4f\x20\xcd\xb0\x21\xb7\x3b\xd2\x62\x66\x65\x55\xe6\xd6\x27\x07\xb4\x6e\xe4\x2f\xa9\x00\xb4\xf4\xf7\x05\xde\x33\xd3\xdb\xdc\x68\xa8\x8d\x1a\x4d\x0a\xe9\x33\x56\x6d\xb6\xc6\x23\x7e\xc8\xab\xe1\x02\x4d\xac\x4b\x7f\x46\xd4\x07\xbe\x16\x59\x4d\x90\x46\xc7\x31\x2d\xda\x66\x14\xd9\xbc\xdb\x01\xfb\x83\x24\xfc\x62\xb8\xee\xaf\x0a\xbc\x23\xcd\x57\x0e\x30\x4f\xca\x08\xe8\x8c\x73\x5e\x5d\x31\x59\x24\x09\xce\xb5\x83\x86\x2e\x6b\x0a\x76\x77\x29\xf7\x55\x6f\xa2\xc0\x53\x64\x4d\x36\xc8\x33\x7c\x02\x74\xe7\x49\x20\x29\x82\xfb\x4a\x17\x1a\xca\xc1\x96\xc0\x2b\x7f\x16\xa8\xda\x49\x07\x1c\x8a\xb8\x07\x6d\xd5\xd3\xab\xad\xfe\x3a\xf8\x2c\xa8\x5d\xa0\x2d\xcc\x1c\x4a\x6f\x2e\x19\x30\xbe\xe2\x00\x9e\xee\x0d\x97\x1e\x40\xdd\x12\x17\x5c\x8d\x00\x69\x4f\x03\x25\xa3\xb3\x13\x3c\x0d\x0b\xd3\x82\xa5\x19\x4f\xb2\x14\x22\xce\x67\xc7\x8a\x5a\x6e\x15\x37\xe3\xb9\x7d\x5e\x20\x4e\x5d\x19\x56\x96\x39\x0f\x77\xd1\x90\x24\xc1\xbf\x6b\x51\x25\xa0\xcd\xbf\x7b\x98\x80\x03\x61\x81\xc9\x8e\x1a\xc2\xe5\x16\x5b\xd4\x96\xcf\x99\x74\x51\xa1\xc1\x21\x02\xe6\x69\x46\xb1\x67\x6a\xbd\x4c\xbd\xd2\xc1\x16\x73\xf4\xf2\xcd\x5f\x3c\x9a\x43\x4d\x74\x7f\xa0\x5b\x40\xfb\xc7\x22\x68\xb4\xeb\x28\x42\xe4\x74\x1f\x51\xb7\x70\x9b\x6a\xcc\xc4\x7f\xca\xf7\x0d\x9c\x1c\x4c\x35\x86\x71\x19\xd8\x1c\xb3\xff\x1f\x16\x08\x11\x33\xf1\x65\x9a\xed\x85\xf6\x3b\xc9\x01\x98\x9e\x26\x17\xfc\xce\x15\x3c\x29\x78\xd7\x08\xfd\x02\x44\x9a\xe4\xd5\x38\xd1\x22\xdd\xb8\x52\x7c\x0a\x76\xa1\x02\xee\xff\x6e\xdb\x65\xdb\xa2\x98\xd3\xc2\x17\xf6\x55\x18\x14\xed\xde\xec\xe1\xae\xf5\xf3\x71\xa5\x4f\x12\xbf\xfd\x6b\x49\x61\x81\x9a\x0f\x24\x4f\xf0\xd7\xd8\x69\x4c\x14\x42\x2d\xe9\x82\x2c\x13\x17\x9e\x4e\xeb\x81\x59\x50\x79\xb9\xdd\x2a\xd1\xe7\xc3\x9b\xd3\x03\xcc\x44\xae\x3f\x36\x34\x88\x15\x77\xa2\x66\xfd\x6b\xb7\x91\x78\x12\xb9\x99\xdc\x80\x9d\xc0\x9c\x3d\x70\x19\xda\xcd\x28\xe4\x30\x13\xa2\xf9\xe4\xf9\x4b\xb0\xbf\x71\x24\xef\x09\x17\x83\xf7\x96\x39\x7f\x64\x63\xbf\x1e\xfb\x39\xcd\x46\xf3\x79\x0a\x1d\x9b\x6a\x7c\x30\xf1\x49\xb5\xe6\x6c\x29\x37\xe3\x9c\xb9\x74\x4d\xdc\x66\xab\x56\x1b\xad\x4e\x6f\xa8\x53\x4d\x69\x88\x38\x22\x64\x3d\x63\xd8\xbd\x7b\x18\x16\x21\xa2\x67\xe9\x55\xe7\x58\xd1\x79\x2b\x44"}, +{{0x53,0xcb,0xd6,0xf6,0x8c,0xee,0x27,0xb9,0xf7,0xbc,0x05,0x9b,0x80,0x3b,0x44,0x79,0x49,0xbb,0xc9,0xc5,0xd5,0xa3,0x86,0x52,0xd7,0x78,0x9c,0xa1,0x54,0x20,0xde,0xa1,},{0x61,0x16,0x99,0x0b,0x53,0x31,0xe2,0x16,0x5f,0x82,0x74,0x3f,0x01,0xd8,0xe7,0xbd,0x5d,0x70,0x88,0xb3,0x01,0x59,0x83,0x3f,0xa7,0xb9,0x39,0xcf,0xb1,0xcc,0x04,0xd7,},{0xd8,0x25,0x04,0x40,0x5f,0xf1,0x6b,0xa6,0x44,0x3d,0xc4,0x82,0x36,0x72,0x63,0xa8,0xe2,0x00,0x36,0x0a,0xca,0xaa,0x83,0xfc,0x4e,0x4b,0x72,0xbd,0x24,0x9f,0x16,0x10,0x3e,0xc7,0xe5,0xa7,0xe9,0xca,0x17,0x19,0x8f,0x88,0x8e,0xac,0xa1,0x6b,0x74,0x0c,0xc3,0xf5,0xc3,0xb7,0xb6,0x17,0xa3,0x4b,0x94,0x91,0xc3,0xed,0x76,0xaa,0xb3,0x0d,},"\x30\x6f\x8e\x1d\xf0\xa4\xca\x78\xbd\x77\xe8\xe1\x19\x1c\x94\xde\xaa\x82\x64\x83\x55\xc2\xae\xcb\x7e\x82\xfc\x56\xd6\x4c\x50\x46\x19\x24\x7e\x7c\xf8\x94\x33\x28\xd1\x1f\x3d\xb4\xb1\xdc\x14\x8e\x8e\xf6\xf6\xc3\xbc\x35\x59\x69\x66\x2a\x28\x1a\x65\x57\x63\x91\x24\x2b\x7b\xd5\xa6\x2f\x8f\xa7\xac\xb6\x04\xe3\xa3\x44\xae\x1a\x9d\x73\x2a\x25\x43\x15\xf3\x1a\x04\x64\xc1\xe6\x58\x74\x62\xd2\x92\x12\xc4\x0e\x5e\xcf\x06\x1e\x26\x9a\xa0\xb9\x03\x90\xba\x41\x04\x07\x21\x68\x4b\xf2\xaa\x95\x82\xd8\x30\x66\x22\x1d\xb6\x0d\x0f\x7a\xe2\xf1\x49\xa3\x6e\x16\x95\x27\x04\xfb\x1f\x3a\x98\x2e\xac\x6b\x45\x83\x66\x5c\x63\xe5\xa8\x99\x6f\x24\xa5\x66\xdd\x50\x6a\x33\xd4\xec\x8a\x02\xb2\xbd\x34\xb7\x14\xc7\x45\x00\x0c\x01\x28\xa3\xc8\x9d\x94\x25\x06\xd1\x2f\x4b\xeb\x90\x0e\x29\x03\xcd\xb3\x4b\x35\xca\x9b\x6d\x3a\xd9\xb3\x50\xac\x99\xf4\x1d\xb3\xac\xfe\x7f\xe5\x5a\x28\xc0\xf0\x06\xb8\x44\xc9\xdc\x48\x53\xfd\x98\x53\x5a\xda\x79\x41\x6d\xca\x5f\xee\x58\x03\xa2\xd9\xf5\xd6\x8e\x6b\x80\x53\x9f\xf3\x02\xe9\x73\xf2\x4e\x9b\xc8\x8b\x7c\x41\x94\x11\x7d\xdb\x9f\x93\x2b\x32\xd5\xec\x74\x86\x8a\x13\x63\x1e\xce\x68\x81\x4b\x93\x14\x21\xdc\x89\x02\x49\x57\x03\x41\xf4\xb4\x23\xe8\x6e\x8e\xe0\x81\xb2\x27\x02\xf6\x49\xa6\xc7\xa0\xb7\xbd\xf5\xfb\x75\x62\x02\xbd\x10\xb0\xbb\x22\x15\xc7\xd6\x59\x7e\xff\xd8\x52\xf0\xb8\x9a\xbe\xc1\x5e\xa8\x22\x57\x68\x9d\xf8\x1e\x33\x82\x54\xf9\x3e\x81\xcb\xf0\x61\x72\x9d\x48\x3e\xb5\xcf\x64\x98\x05\xd7\x8e\xd8\x92\xdd\x0b\xd2\x48\xca\x1e\x25\x2b\xea\x51\x84\x7e\x1e\x82\xd3\x9a\xf5\x80\x50\xdc\x4a\xfb\xf9\x11\x5a\x3a\x60\x49\x3e\x8c\x0b\xa2\xe8\x6e\x08\x98\xcd\x0d\x43\x08\x91\xb9\xeb\x0a\x40\xf8\x74\x31\xe2\x5f\x41\x53\x8a\x03\x0f\x88\x4f\xab\x36\xad\x11\x16\x5d\x26\x7e\x8d\xd9\x4d\xcb\x05\xb9\x3a\x5a\xe7\x79\x69\x43\x0e\x18\x10\x13\x4e\x15\x72\x51\xb9\x82\xdf\x34\x3d\xff\xae\x61\x23\xa9\x9a\xa0\x56\x2d\x5d\xf7\x24\x08\xf1\xa6\xe2\x9c\x40\x59\xa5\xa8\xaa\xa4\xe6\x21\x52\x8f\xc6\x3a\x9c\xbe\x1f\x4c\x0f\xef\x25\xfe\x3f\x8e\x18\x15\x77\x74\x09\x7a\x9d\x91\x02\x0a\x90\x06\xb6\xc8\x60\xec\x1e\xe1\x0d\x52\x1d\x20\x3a\x1f\x8b\xb8\x25\x61\x29\x6f\xaa\xd4\xb2\x20\x3d\xa5\x3b\x20\x7a\x45\x9b\x29\xc1\x8b\xc0\x64\x93\x32\xb1\x80\x7c\x13\xca\x61\xac\xfa\xf9\x07\x79\xfe\xbb\xc7\xf3\x24\x21\x64\x79\x7e\x6f\x57\x2c\xb1\x5a\x9b\xe5\x88\x73\x43\x45\x5e\x26\xb9\x10\xc8\xbe\xfe\xe4\x2a\xeb\x04\x7f\x9a\xbe\x6b\x37\x50\xdb\xd7\xde\x99\x20\x2a\x0b\xb5\x76\xce\x14\x89\xe6\x1c\x1f\x5d\x27\xc6\x79\x2e\x63\x21\x8e\xdb\xfd\xb9\xb3\xdc\x51\x5b\x42\x54\xd8\x2c\x85\x9e\x52\xce\x6b\xd7\xad\x29\x6d\xd0\xe3\x70\x9d\x4c\x46\x63\x62\xf9\x02\x65\xe9\x9d\xa7\xd0\xb7\x01"}, +{{0x8b,0x65,0x74,0xf6,0xd7,0x39,0x69,0x81,0xe2,0x23,0xa4,0x83,0x7b,0xc3,0x39,0xc3,0xfd,0x65,0x94,0x19,0x84,0x5a,0x21,0x21,0xbf,0x85,0xbe,0x2e,0x69,0x5d,0x86,0x0d,},{0xe3,0x81,0x1a,0xca,0x70,0x63,0x4f,0x5a,0x9c,0xe4,0xb5,0x92,0xa1,0x7b,0xb5,0xcf,0xda,0x53,0x44,0x24,0x22,0xe2,0x03,0xcd,0xa9,0x50,0x4c,0x9d,0x65,0xb2,0x63,0xe8,},{0x2f,0xd0,0x90,0x54,0x75,0xa2,0xce,0xc3,0xe7,0x6f,0x99,0x09,0xb8,0xaf,0xd8,0x3b,0xeb,0x8d,0xae,0xfa,0x77,0xaf,0xcd,0xa3,0x4c,0xb4,0xf1,0x17,0x28,0xef,0x15,0xfc,0x9c,0x1d,0x7f,0x6f,0x6a,0xff,0xfc,0x28,0xf3,0x87,0x4f,0x91,0x3e,0x17,0x98,0x0f,0x0e,0x8e,0x3d,0x5a,0xd2,0x39,0x51,0xdf,0x2b,0x32,0xef,0xaf,0x62,0x19,0xce,0x0d,},"\xa4\x8a\xac\xc0\x49\x5f\xa0\xf1\x25\x9b\x27\x86\x5d\x3d\x75\xdc\x52\xc2\xc8\x28\xea\x8c\x4c\x2a\xd7\x85\x77\x07\x2f\xef\x72\x70\xf6\xa4\xd5\x82\xbb\x7b\x96\x2f\x4c\x3f\xd1\x49\xa6\x0a\x06\xbc\x8e\xfd\x29\x70\xef\x03\x14\x8d\xdf\x61\x98\xb9\xb6\x95\xa6\x9f\xad\xb5\x34\x09\x51\xcb\x75\x39\x8a\xc5\x1a\x4f\xd5\x54\x30\x37\x8c\xd5\xda\x88\x85\x21\x0b\xfd\x21\x46\xf9\x5c\x62\x76\x32\xfe\x8b\xe0\x6d\xe0\x1a\x7c\x27\xb8\x9d\xee\xfd\x67\xef\xc6\x9c\x9b\x5c\x62\xb3\x81\x08\xf7\x76\x22\x91\x43\xda\xe6\x60\xc1\x0c\xbe\xa3\xcd\x4f\x7e\xe5\x3d\xc3\x69\x2e\xd0\x11\x77\xe4\xa6\xf7\xe4\x24\xb5\x66\x6f\x7f\x49\x5f\x2a\x65\x60\x2c\x7d\x08\xc5\xd5\x72\x23\x4a\x56\x7c\xb6\xc3\x8a\xfd\x79\xca\xb5\xc4\x03\x6d\x62\x63\x7a\xef\xab\x55\x88\x76\x9a\x44\x8a\xb4\xc6\x5e\x24\x55\x4b\xd4\x15\x80\x50\xe0\x9e\xb5\x8f\x99\xab\x40\x77\x7b\x03\x56\x70\x9b\x7c\x02\x5a\xe5\xae\x54\x22\xac\xf8\x74\x44\x93\x1a\xe4\xd9\xa8\xb3\xd9\x44\x76\x88\x11\x28\xba\x1e\xb7\x32\x8f\xaf\xc7\x5f\x6b\x9d\xac\xc9\x6d\x3b\x64\x87\xdd\xef\x7c\x59\x26\x2d\xca\xda\x42\x6a\xac\xb1\x39\x22\x93\x54\x11\x56\x62\x35\xe0\x58\x37\x26\x22\xd8\x85\xbd\x0c\xc0\x49\x58\xdc\xfb\x17\xe0\x8f\xcd\x7f\x14\x7e\x20\x15\x6c\x8e\x26\xaf\x85\x53\x0f\x55\x11\xa6\x8d\xb4\x3d\xaf\xc4\xe6\xa2\x3f\x66\x7d\xf3\x74\x3e\xed\xd7\x1a\x3f\x07\xf7\x6f\x94\xd1\x68\x8a\xfc\x84\x63\xbf\xa5\xa4\x39\xae\x31\x14\x69\x94\x8e\x74\x47\x06\x4f\x0b\x05\x06\xf3\x67\x19\xc1\x34\x66\xa1\xb9\x87\x76\xd9\x67\xec\x58\x20\x8b\xa6\x74\x03\x73\x03\xdf\xc6\x19\x0d\xa7\x83\xff\x27\x30\x3b\x86\xb5\xfc\x32\x11\xf0\x1c\x91\x5e\x83\xa6\xad\x01\x21\x44\x79\x11\xcb\xe1\xcf\x69\x6f\x61\x8f\x60\x23\x66\x43\xf2\xe9\x4e\x15\x5d\xb6\x57\x18\x29\x44\xc1\xa4\x3b\xdc\x7b\xd5\xea\xf3\x48\x1f\xe1\x28\x40\x92\xcb\x37\x89\xa8\x92\xbd\x79\xa1\x11\xfd\x41\x01\x43\xcf\x91\xae\x33\x28\x60\xb1\xd2\x9a\xa0\x41\xd1\x77\xb5\x0d\x6c\xc2\xb9\x66\x0d\x32\x8c\x0f\x23\x0a\x35\x15\xe6\xa0\xd6\x88\x70\x9c\x0c\xd3\x47\xad\x2f\xf3\x2d\x61\xd1\xe1\xe9\xba\x76\xf8\x1e\x87\x3a\x6c\x42\x0f\x17\x07\xf3\x84\x1d\xb5\x19\x6c\xb5\x3f\x50\x6f\x00\x06\x35\x2c\x7c\x44\xc0\x80\xf3\x09\x68\x01\xa5\x7a\x49\xcf\xe8\x42\x05\xbd\xd7\xa9\x80\x1f\x84\x3c\xf2\x6b\x95\x58\xa2\xdb\x78\x8e\xf1\xb2\x37\x91\x5d\x58\x7b\x9b\xa9\x77\x98\x90\xf6\x1f\xdc\x91\xe0\x3e\x4f\x4c\xdb\xef\xe4\x17\xcc\x22\xd5\x22\xa8\x6a\xdd\xdb\x53\xf3\x74\x74\x50\xab\x62\xb5\x76\x56\x5d\xb3\x2e\x0c\xd4\x42\x76\x54\x7d\x9a\x16\x65\x3c\x27\x96\x59\xdd\x4d\x17\xec\x04\x82\x7c\x53\x3e\x33\x39\x0f\xe9\x4f\x79\x35\x09\x25\x6d\xb6\x75\x31\x73\x6a\xb3\xfc\xee\x2a\x30\x1a\xc3\xf0\xa2\x4d\x3b\x10\x8d\x7e\x75\xc3\x2a\x5a\xba\x36\xd6"}, +{{0x29,0xb2,0x88,0x1b,0x8c,0xaa,0xdb,0x33,0x6e,0x78,0x80,0xc5,0x10,0xb8,0x00,0x85,0xf4,0xb1,0x22,0x18,0x60,0xb3,0x01,0xeb,0x45,0x25,0x65,0x07,0x52,0xa6,0xd2,0x89,},{0x0c,0x5c,0x44,0xed,0x29,0xd2,0x1b,0xca,0xde,0xe2,0x1c,0xbd,0xe6,0x1a,0x9c,0xdb,0x6d,0x59,0x36,0x00,0x9b,0xa2,0xf5,0xb2,0xe7,0x77,0xc9,0x24,0xdd,0xfb,0x67,0x51,},{0x99,0xe9,0x96,0xe8,0x5a,0x49,0x4f,0x19,0x80,0xcb,0x07,0xde,0x9c,0xa6,0x16,0x5e,0x7d,0xe1,0x04,0xd3,0x9f,0xe3,0xc3,0x22,0x67,0x35,0xc5,0xda,0xa5,0x69,0x51,0x6f,0xca,0xf1,0xb6,0xe4,0xdf,0xad,0x0d,0x38,0x9b,0x6d,0xb0,0xec,0x8a,0x8f,0x20,0xdd,0x2c,0x60,0x26,0x56,0xb5,0xe7,0x61,0xc8,0xf3,0xa6,0x55,0x83,0x82,0x15,0x19,0x09,},"\x19\x74\xa2\xe2\xb4\x79\x49\xf4\x67\xa9\x31\xd1\xd9\xdd\x5c\xe1\x16\xe9\xf5\x03\x0a\xd0\x9a\x8c\xc7\x28\xd1\xae\xb1\x48\xbb\xf9\xac\xf5\x98\x74\xda\x80\xe7\x08\xd5\x3c\x66\x8f\x2f\x14\xd7\x52\x20\x71\xe9\x09\x80\x84\x27\xb2\xab\x5a\x05\xf8\xb9\x4f\x21\x50\x5c\xd2\x6a\xbc\x53\x45\x89\x78\xc7\x84\xd4\x79\xea\x6d\xab\x10\x5c\x4f\x79\x84\xa0\xfb\x97\x90\xe5\x06\x24\xf4\x73\x4b\x55\x19\x05\xaa\x5f\xfa\x60\x18\x4c\xd2\x01\xcf\x2b\x26\xc9\x79\x5d\xa6\xe7\xe0\x8d\x6a\x0b\xc7\x72\x24\x00\xfe\xf9\x4f\xc2\x10\x38\xbe\x89\xd3\x4b\xcd\x14\xc4\x27\xb8\x5b\x68\x66\x73\x71\x96\x15\x2d\x4e\xeb\x66\xd0\x5b\x24\x5a\xe8\x4b\xdc\x77\x87\xc1\x4a\x8b\xec\x2e\xea\x53\x60\xf0\x42\x43\x3d\x70\x79\x44\x67\xd4\x73\x93\xb9\x37\x57\xf3\x31\xcf\x2b\x53\xc6\x60\xd7\x1c\x29\x58\x2a\xee\xa7\x9b\x12\x52\x7a\x28\xb0\xc5\xe1\x10\xdf\x6f\x85\x4e\xea\xd9\xa2\xb0\x0d\x42\x54\x2c\xa8\x27\x6b\xb8\xbf\x98\x8b\xaa\xb8\x56\x59\x96\xfe\xe5\x0c\xf3\x1b\x24\x59\xc4\xc5\x0a\xb4\x75\x26\x5e\x83\xe2\x28\x5d\x43\xfe\x1f\x75\x2a\x55\xb2\xdb\xc4\x9f\xca\x04\xa8\x10\xf0\x41\x3b\xf6\xbd\x81\xb7\x9a\xc6\x4e\xe1\xf8\x9b\x97\xbd\x7d\x26\xd6\x25\x12\x27\x3e\x24\xa6\xba\xb2\xd5\xf7\xd2\x22\x6b\xaa\xab\x7b\x11\x12\x09\xbb\x03\x73\x3d\x8a\x60\xdf\xa3\x1a\x51\x6f\x4a\x8c\x76\x99\xd8\x28\x5c\x10\x65\x15\x9a\x6c\x73\x31\xc1\xde\xfb\x47\xa3\x0e\xf5\x85\x8c\x50\xb7\xd0\x45\x12\x4a\x09\x81\x3d\x1c\xfd\xa5\xc9\xcc\x3b\xb5\xbf\xae\x73\xc9\x84\x19\x7f\x8f\x85\x7f\x18\x6c\x41\xab\x87\xfb\x79\x62\xb6\x31\xf4\xd0\x07\xcf\xbe\xe2\x21\xfc\x65\x72\x78\x4a\x55\x11\x94\xc1\x97\x77\xb0\x8e\x6b\x59\x67\x57\xe7\xcb\xa7\xa0\xe2\x7f\xe4\x53\xf9\x0d\xc5\x9c\xc0\x8c\x64\x72\x43\x1c\x02\x0e\x8d\xd0\x91\x75\x90\xe7\x9c\x1f\x20\x73\x83\xaf\xb3\x90\x76\xad\x24\xda\x8e\xe5\x24\x86\x73\x94\x53\xa2\x59\x0e\x51\xbf\xc8\x9b\x13\xc2\x03\x3c\xfa\x5f\x89\x03\xcb\xe9\x96\x1a\x85\x98\xba\x55\x62\x32\x86\x9d\xfa\xb4\xd5\x6e\xdf\x4f\x05\xe8\xb7\x7d\x05\x87\x18\x95\xe6\x3b\x53\x51\xf7\x6c\xb2\xd2\xc8\x38\x5c\x10\x9d\x73\x06\x19\x2a\x25\x44\x6e\x4d\x62\xdc\x7d\x62\x4f\x0c\x66\x73\x98\x6b\xe0\x62\x8b\x2c\x2d\x73\xeb\x94\x1d\x35\xa3\x43\x30\x90\xf5\x9b\x28\xa5\x97\x9d\x56\xdb\xc9\xfd\x69\x73\xf6\x36\x47\x64\x2c\xd9\x03\xb0\xcf\x7a\x6a\xcd\x33\x0d\x87\xe2\x29\x27\x10\xde\x99\xe0\xc1\x79\xca\x78\x92\x9c\xca\xec\xfa\xed\xbf\x27\x42\x41\x4f\x17\x6b\x60\x90\xc0\xd5\x9a\x9d\xb7\x81\xc9\x96\x7e\x28\xfa\x4e\x77\xd2\xa0\x82\xe4\x2f\x52\x16\x91\x67\xe9\x2d\x4f\xdd\x82\xe2\xcc\x05\xdd\x91\x84\xc7\xdf\xee\x49\x0a\x23\x7f\xda\xd4\xdf\xeb\xc0\x18\x68\xe0\xa4\x35\x3a\x29\x54\xd0\x90\x92\x84\x61\x82\x1a\x7a\x84\x8d\x1b\x60\x81\x7f\xc3\xbd\xef\xa1"}, +{{0x42,0xaf,0xe8,0x9d,0xac,0x83,0xe7,0xd3,0x89,0x96,0xc0,0xdb,0xce,0x0c,0x98,0x74,0xc0,0x09,0x27,0xba,0xbd,0x77,0xca,0x8c,0xea,0xc3,0x4e,0x56,0x44,0x74,0x28,0x2b,},{0xa4,0xc5,0xf5,0xe3,0x80,0x3f,0x0a,0x03,0xd5,0xc1,0xc9,0x06,0xca,0xec,0x9c,0xc6,0xd2,0x85,0x14,0x07,0xf1,0xca,0x29,0xf7,0x2a,0x45,0xf2,0x33,0xe6,0x65,0x62,0x44,},{0x4f,0xba,0x2d,0x6c,0xc1,0xb7,0x19,0x3d,0x35,0x62,0xf8,0xc8,0xbf,0xe6,0x90,0x5c,0x82,0x9d,0xb2,0x65,0xa5,0x42,0x7c,0x5c,0x26,0x57,0x14,0x78,0x5b,0x83,0xf6,0x95,0x14,0xc5,0xe3,0x0e,0x28,0xb5,0x66,0x84,0xc8,0x2d,0xae,0x26,0x37,0x58,0x1b,0xf3,0xf4,0xef,0x27,0x14,0x20,0xbc,0x7e,0x60,0x10,0x61,0x3a,0x38,0xfa,0x10,0x1a,0x0d,},"\xe7\x10\xa1\x63\xad\x28\x85\xae\xb7\x65\x8e\xb3\x74\xf1\x18\xb7\x68\x42\xec\x36\xef\x3b\x01\x0c\x3c\x6b\x95\x59\xe8\xb1\x60\xc2\x62\x8d\xed\x0b\x85\x11\xeb\x49\x07\x18\x0d\xa4\xb6\x21\xe9\xaa\x4a\x32\x22\x88\x88\x8a\x1c\x09\x13\x0f\x69\xf8\x90\x59\x7a\x92\x93\xe7\x4f\x92\x89\xbd\xaa\x5c\x91\xb6\xfd\x24\xaa\x04\x4a\xb9\xfc\xb3\x40\x2f\x7a\xbc\x48\xd2\xab\x7b\x38\x80\xa0\x48\xda\xa4\x48\x64\x5a\xd2\xec\xb5\x5b\x3c\xae\xe2\xd6\x8a\x8b\xed\xb5\xd1\x86\x5d\x5e\x21\x1d\xe3\x9b\x0e\xaf\x22\xe5\xda\xf1\x0f\x71\x68\x20\x3a\xa1\x5b\x85\xaa\x47\xbb\xd3\xcc\x41\x69\xcb\xc1\xfe\x80\xb4\x70\x0b\x62\x58\x71\xed\xab\xcd\x4f\xe7\x4a\x3e\x96\x55\x69\xce\x24\x5c\xfc\xde\x42\x09\xcc\x8a\xbc\xd6\x79\x7d\x44\x18\x5b\x4f\x96\xc0\x18\x1b\xbd\x27\x00\x87\x83\xe9\x35\x8a\x53\x94\xfe\x3a\x34\xa0\x68\x71\xd3\x79\xda\x35\xb2\x0b\xb5\x7e\xef\x9e\x55\x24\xee\x79\x12\xa6\xf4\x1b\x4a\x1f\x68\x4c\x39\x19\xcf\xcd\xc0\x0f\x45\x80\xba\xf9\xe0\x9d\x31\x6c\xef\xa0\xf4\x65\xdc\xa5\xd8\xee\xc5\x14\xe9\x5e\x5a\x57\xbb\xcd\x27\xe4\x1f\x81\x19\xb2\x64\xae\x14\xa3\x19\xd8\xc3\x85\x9b\xab\xf1\xf4\xa6\xb6\xb7\x7e\x44\x2c\x86\x1d\x6e\xe2\x8a\xd1\x2b\x82\x36\x2e\x90\xdb\x0c\x36\x72\xb0\xe0\xd9\xff\x58\x14\x6f\xd1\x59\xaa\x8f\xa9\x9d\xc7\x55\xfc\x85\xb9\x0c\xf9\x41\x92\x79\xc0\x62\x4b\x93\xe7\x5e\xda\x0e\xf7\xc0\x96\x95\xae\x93\xbd\x72\x82\x41\x93\x77\xb7\x6c\xa8\xbd\xc0\x52\x1c\xfe\xe6\xf6\xd7\x29\xc3\xad\xff\x89\x46\x87\xb1\x77\xef\x19\x52\x9a\x6b\xda\xce\x70\xb6\x85\xc6\xd7\xa5\xd7\x4a\x08\xe2\xa9\xe7\x24\x03\x59\x75\xc8\x0d\x18\xcb\x36\x94\x70\xde\x72\x99\xcb\xd6\xb0\xa2\x7c\x92\x32\xc7\xea\xba\xc8\x6d\x50\x93\xa6\x5f\xfe\x0b\x40\xd4\x0b\xef\xe8\x0b\x68\xcd\x9d\xce\x1e\xa1\xe6\x57\xe4\x5e\x9c\x49\x9d\x0b\x69\x0f\x74\x45\x5f\xb4\x70\x96\xed\x8c\x18\xd1\x51\x7f\x90\x44\x29\x01\xa6\xc4\x10\xb7\xf6\x41\x5f\x20\xae\x48\xc5\x8a\xde\x8d\x67\x5b\x6c\x05\x8d\xf1\x6a\xe7\x69\x8f\xce\xae\x95\xaa\x77\x1b\x4c\xd8\x8a\x0b\x3f\x22\xc5\x1f\x98\xc7\x1c\x1e\xb4\x6b\x26\x4b\xf9\x7a\x30\x0e\xcb\x1f\xd2\x62\x26\xad\x8e\x87\xa0\x58\xcf\x3e\x70\x8e\x26\x0f\x56\x6b\x68\x53\x14\x04\x51\x33\xf4\xa5\xe8\xfb\xc3\x45\x61\xb9\xa0\xf1\xff\x93\x39\xf5\x52\x31\x07\x6b\x73\x6b\x6e\x11\x52\x43\x19\xa2\x72\xbd\x44\x53\xa0\xaf\x14\x93\xda\xa0\x91\x67\xe8\x46\x43\xd2\x07\xa0\x2f\xee\x98\xfb\x22\x3b\x01\xa9\x9a\xa5\xce\xf2\xb7\x00\x1e\x47\x0f\x6f\x94\xa5\xdc\x20\x8e\xdf\xc0\xcb\x8c\xf3\x11\x4a\x91\x96\x00\xf0\x61\x17\x2f\x0e\xfe\x03\x90\x36\xbf\x4d\xdd\xbf\xd0\xd4\x5f\x91\x44\x3b\xf2\x6f\x8e\x15\xed\x7d\xb8\xe5\x5f\x08\x6a\x4a\x45\x83\xf4\xbd\xa0\xf5\x56\x28\x4d\xcf\x71\x29\x2f\xe7\x0f\xca\xa8\x25\x9b\x9f\xaf\xf3"}, +{{0x10,0xf0,0x09,0xaa,0x88,0x7d,0x91,0xce,0xd8,0x09,0xaf,0xe1,0x92,0xd7,0x8e,0x47,0x99,0xd9,0x03,0x77,0x62,0xf4,0xa9,0xd3,0xa4,0x29,0xfd,0xe0,0xf3,0x9f,0x7b,0x7a,},{0xcf,0x51,0x16,0xb9,0x21,0x21,0x2e,0x9b,0x78,0x82,0x9a,0x02,0x63,0x46,0x36,0x91,0xc6,0xfb,0xcc,0xdc,0x0c,0x11,0x8b,0xe1,0x41,0xc9,0x6f,0x8c,0x88,0x05,0x3d,0xd3,},{0xc3,0x7b,0xb7,0xb7,0x3b,0x11,0x05,0xbe,0x08,0x6f,0xf3,0x07,0x69,0x72,0x07,0x72,0x62,0xdf,0x4d,0x73,0x32,0xf6,0x08,0xc7,0xb2,0xb9,0xd9,0x78,0xd4,0x74,0xcb,0xbc,0x27,0x10,0x46,0x08,0x00,0x35,0xf3,0x96,0xee,0x36,0x47,0x9b,0x7a,0x67,0x11,0xc6,0x8e,0x25,0x61,0xc7,0x41,0xc0,0xec,0x5f,0xc9,0xec,0xa1,0x73,0x4e,0x81,0x1f,0x04,},"\x2e\xdf\x14\xd6\xcd\x56\x89\x6e\xea\xa7\x70\x21\x1c\x49\x84\xbe\xd8\x0e\xca\x8d\x65\x34\xd5\xd5\x10\x88\x4f\x55\xf1\x1f\x99\xff\xa9\xf8\x9b\x58\x6f\xfe\x7b\x1e\xc7\xea\xab\x6a\x9d\xc1\xa2\x4a\x3e\xe3\xc7\xa6\xab\x44\xad\xe9\x91\x78\x83\x26\x4e\xde\x2f\x13\x61\xbe\x7d\x7a\x38\x17\xf2\x9d\xec\x95\x81\xc3\x19\xf1\x8f\x95\xd5\xbe\x26\xd9\x11\x8b\xe6\x78\x34\x00\x37\xa6\x8a\xbf\xc5\xef\xbb\x9a\x3f\x3f\x38\x78\xaa\xe3\x72\x1f\xfe\xf5\xbb\x6a\x26\xc7\xb1\xa3\xa5\x6d\x2b\xda\x6c\x6e\x86\x0e\xb4\x1f\xd8\xd8\x37\x11\x74\xd9\x1c\x74\xc5\xeb\x67\xc3\x85\x5c\x63\x0d\x64\x1d\x2e\x57\x1a\x9a\x51\xc6\x40\x2c\xfe\x18\x42\xce\xf3\x89\x80\xcb\x8d\x0a\x64\xbc\xc8\x9b\xe3\x18\x9e\x68\x11\xf4\x7e\x8f\x4d\x00\x63\xa5\xb1\x60\x1f\x44\xfd\xa2\x0c\x1c\x4c\x2f\xc4\x9c\xbe\x27\xa4\x13\x7d\xc4\x63\x8c\x2a\xd2\xd0\xa5\x47\x47\x47\x22\x9c\x56\x8e\x38\x05\x43\x1f\xa3\x6e\xeb\xa7\x85\xf7\xb9\x78\x44\xb5\xe3\x19\xfa\x6a\x09\xcc\x5a\xe8\x40\x34\x74\xbb\x91\xdd\x89\x6c\x1e\xc2\xba\xc7\x3d\x2e\x50\x5e\xfc\x62\xbd\x50\x2b\x5c\xeb\x08\xd1\x6e\x83\x2e\xc5\xdc\x4f\x98\xb5\x1b\x9d\x07\x38\xb9\xfb\x28\xf3\xab\xe8\x96\x6b\xf2\x23\x75\xa0\xb2\x2c\x47\x1a\x9e\x58\xe3\xfd\x70\x0d\xe1\x5c\x52\x96\x37\x3c\x1b\xc9\xd4\x64\x0e\xb7\x81\x6e\x1d\xc9\xc8\xce\x86\x19\xa8\x11\x83\x00\x9e\xc9\x74\x87\x1e\x8f\x0a\x97\x72\xed\xe0\xa6\x38\xb3\x57\x4b\xf7\x5d\x8f\x55\x98\x7f\x3c\xfa\x6f\xec\x68\x97\x0b\xfe\x00\xb2\x3b\x59\xfb\x5b\xf4\x99\x6e\xa5\xd7\x70\x4f\xcf\x2e\xff\xcc\x0f\xd7\xf3\xd8\xe6\x05\x60\x08\x09\x7f\x26\xca\xff\xd5\x41\x5a\x28\x2a\x27\x6a\x9b\x26\x45\xe5\xca\xb1\x29\x68\x87\x2e\xb0\x52\xf4\xd7\xc1\x0c\xc7\xc2\x1d\x51\x61\x81\x8b\xb4\x4c\xc8\x56\xb0\xde\x76\x9d\x55\x9c\x55\xdf\x64\xad\x9a\xdc\x16\xc0\xac\x65\x83\x8f\x66\x0d\xa8\x13\x86\xb7\x0b\x93\x52\x5e\xc2\xf4\x0f\x6f\x63\xf8\xea\x5d\x48\x30\xb9\x64\x6c\x46\x18\x3b\xb4\xe6\xf2\x70\x47\xbd\xa2\xa5\x46\xbd\x34\xbd\x4d\xb5\xfb\x88\xfd\x8a\xb7\xc7\x5f\x65\x2e\x15\xd5\xaa\xa6\xb4\x6a\x8a\xcf\x6e\x44\x8b\xf2\xdd\x64\xde\xe3\xc1\x05\x64\x7c\x7f\x83\xad\x20\x0d\x80\x97\xc4\x44\xa1\x58\xd8\x5a\x54\xf0\xe5\xdb\xb1\x2b\x43\xde\x94\x3a\xf1\xa8\x18\x56\xac\x96\x9f\x52\xa0\xbd\x45\x43\x81\xbd\x26\x50\x41\xa2\x69\x1d\x1a\x4a\x0d\x81\x9f\xa7\x90\x92\xc8\x80\x35\x21\xfa\x53\x68\x9a\xb8\x52\xf1\xfb\xab\xe0\x0c\x94\xb7\xf6\x82\xd1\x21\xcf\xf5\x43\x91\x32\x25\x29\xc8\xd5\xad\x7b\xbb\x98\xea\xfe\x30\x0a\xb9\x22\xf1\xc8\x92\x40\xa1\xe6\x33\xcf\x56\xa7\xb0\x2f\x74\xa2\x92\x14\xe5\x69\xa0\x57\xbd\x58\x5e\x40\x4d\x7c\xd5\x35\x20\x41\x45\x6e\x6c\xf9\x0c\x15\x34\x2e\x02\x56\x70\xf4\xfc\xcd\xf9\x87\x83\xb6\x85\x32\x14\xca\xc3\xfa\x80\x8a\x66\xc2\x7b\x65\x3c"}, +{{0x45,0x78,0xc6,0x5a,0x7c,0xa4,0x8f,0x27,0x74,0x05,0x0a,0x7b,0x0c,0xe7,0xa4,0xfd,0x5a,0xd4,0xe6,0x96,0xb2,0xb8,0xaf,0x23,0x96,0x16,0x4a,0x1c,0x7e,0x1b,0x7b,0xd7,},{0x15,0xbf,0x9d,0xbd,0x3b,0x81,0x73,0xe6,0xf0,0x3d,0xcf,0xd5,0x75,0xd9,0x09,0x84,0x5f,0x03,0x8e,0xaa,0x09,0xc5,0xd9,0x08,0xfe,0xf9,0x08,0xa9,0x74,0x58,0xb3,0xef,},{0xa1,0xc2,0x42,0xb4,0x5e,0x94,0xfd,0x18,0x0f,0x05,0x4c,0x71,0x01,0xe5,0x5b,0x39,0x65,0x68,0xf4,0x83,0xdb,0x6f,0x0d,0xfc,0x41,0x68,0xb6,0x9b,0x59,0xd3,0x85,0x81,0x4c,0x19,0xeb,0x30,0x75,0x23,0x7d,0x1f,0xbb,0x1f,0xee,0xbb,0xfe,0xa5,0x0c,0x56,0x81,0x3c,0x8c,0x39,0xc2,0x27,0x52,0xe0,0x2d,0xb7,0xe5,0x7f,0x3e,0x3f,0xbf,0x0d,},"\x50\x6f\x32\xb9\x68\x14\x24\x3e\x4d\xd8\x87\x0a\x8f\xd6\x0d\xde\xf0\x9b\xb8\xc5\x63\x15\x10\x70\xd9\xbc\xb2\xb1\x60\xa3\xea\xbd\x71\xa0\x44\xd7\x1e\xc9\x3f\xba\x95\x28\x8e\xd6\xfe\x1a\x7b\x92\x16\x51\x60\x43\x07\xd6\x5a\x45\xec\x5d\x3f\x26\x31\xac\xe4\x0e\x58\xd5\x3c\x72\xe5\x26\x88\x6e\x16\x97\x2f\x6e\x0d\xb9\x4d\x57\xb5\x56\x34\xfd\x39\xd5\x5e\x9b\xb7\xf2\x12\xaf\xab\x00\xf7\x74\x64\x09\x26\x7e\x8d\x56\x5f\xf5\xc2\x25\x73\x33\xc3\xd0\x41\x52\x17\x4f\xe1\x2d\xe6\xa5\x7b\xea\x05\x7d\xc2\x19\xe2\xfb\xa5\xf1\x91\xed\x81\x41\xc0\x18\x96\x9d\xe1\x94\x72\xd6\xaa\xf7\x63\xf1\x9e\xc5\x54\x70\x2b\xb3\xdc\xbe\x13\xca\x9b\x23\xb2\x41\x8c\x99\xe7\x18\x38\xa8\x8c\xf4\x54\x72\x8c\xf9\x20\x8a\x16\xc8\x4e\xa3\x98\x29\xb4\xba\x9b\x4c\x77\xe1\x76\x11\x2b\xfe\x1b\xf3\x5f\x95\xc4\x02\x8c\x7d\xb8\x0b\x36\xfa\xa2\x9d\x2b\x89\xe9\xe8\x62\xf3\x10\x00\x06\x5f\x13\x9b\x3d\xa7\x7d\x9d\x86\x85\x30\x57\x4b\x7e\x39\x1e\xd9\x7b\x34\xf8\x78\x16\x4f\x6b\x8d\x87\xb4\x06\xc7\xdc\x78\x60\xa5\x17\x5f\x92\x0e\x5a\x62\xdc\x1f\xc8\x2e\xd8\x45\x25\x43\xb1\x07\x36\x0d\x35\xd2\xb4\xc4\x23\x9e\xab\x46\x6d\x32\xbf\xda\x34\xf5\x10\x37\xa6\xfa\xe7\x6f\x6d\x8b\x83\xe8\xf7\xf4\x89\xdd\x4c\x1b\x49\xc3\x8f\x53\x57\x6e\x62\x17\x2c\x17\xde\xe3\x66\x5f\xde\x8c\xbf\x01\x5a\xf9\x66\x5b\x0f\x1d\xa2\xfb\x77\xb1\x34\xf0\x4b\xe2\x71\xe4\x02\xf3\x15\x37\xc2\xfc\x05\xc2\xf9\xb6\xfc\x3f\xfe\x47\xde\x33\x69\x13\x38\x67\xc6\x9d\x10\xe7\xf5\x37\xba\xe4\x56\x7d\x46\x8e\x0f\x2e\xd8\x06\xfe\x33\x5f\x93\x9c\x75\x99\x4f\x36\x3c\xe3\xb7\x0d\xaa\x7d\x5b\xd2\x31\x7c\x83\x38\x51\xfd\x8c\xc9\x72\x51\xec\x41\x90\x23\xd9\xd0\x17\x4d\x84\xd5\x60\x9a\x69\x18\xa1\x74\x0e\xb1\xe3\x09\xbd\x12\x73\x66\xde\xb9\xc5\xab\x12\x99\x2e\x99\x02\xe0\x15\xfe\x58\xd6\xad\xbf\x52\xd2\x2a\x76\x0a\xcd\x63\xe1\xed\xd8\xf1\x38\xe9\xfb\x01\x37\x18\x86\x01\xe1\x97\x8e\x7d\x04\xfb\x2a\xda\x2b\x2a\xee\x12\xf4\x9f\x28\x36\xc6\x84\x2d\x88\xcf\x48\xc8\x66\xe3\xd3\x3f\xcd\x26\x9c\x27\x5c\x89\xc2\x5e\x36\x69\xca\x90\xde\x7b\x67\xa7\xe7\xa3\x82\xcb\x7e\xfa\x47\xe9\xc2\xbf\x76\x57\x1c\x79\xa2\x50\x85\xef\x02\x04\x87\x15\x2f\x06\xbf\xa1\x33\x01\x5a\x1b\x8f\x1c\x0f\x6a\x9f\x0e\xae\x1b\xa6\x2b\xf1\x04\xf1\xc1\x6a\xc1\x4e\x1e\x96\xc4\xeb\xdf\x06\x1e\x0c\xc7\x10\x1d\x38\xda\x7e\x9e\x09\x94\xda\xf0\xf3\x22\xaa\x3c\xfe\xf9\x1b\x61\x6c\x2d\x00\x06\x89\xab\x18\xed\x45\x26\x8d\xcd\x27\x50\x94\xf6\x56\xba\x3c\xf5\x15\x26\x10\x24\x74\x1f\x74\x44\xab\x7f\xc4\xde\xcc\xe1\x67\x56\x03\x2a\x1b\xe2\x70\xff\x0b\x03\x17\x54\x2b\xa0\x26\x62\x26\x0a\x37\x6f\xc9\x12\xcb\xb0\x29\xca\xc5\x45\x15\xf5\xa5\x51\x36\x4f\x6a\x99\xff\xad\x0b\x9c\xbc\xd0\xe6\x93\xb7\xa5\x21\xcb"}, +{{0xc2,0x1e,0x70,0xc4,0x6e,0xde,0x66,0xe6,0x8a,0x88,0x73,0xbb,0xc6,0x4b,0xa5,0x12,0x09,0x30,0x3a,0x0a,0xc4,0xfc,0x49,0xb1,0xd8,0x3e,0x81,0x93,0xad,0x46,0xc0,0x37,},{0x9f,0xbf,0x80,0xa4,0x25,0x05,0xd2,0xc9,0x52,0xf8,0x9f,0x45,0x58,0xc3,0xe6,0xd1,0x87,0xa7,0xbc,0x1e,0xf4,0x46,0xb2,0xe3,0x73,0x23,0x43,0xc1,0x3b,0x33,0xd2,0x00,},{0x0a,0xe3,0x43,0xbb,0x84,0xe3,0xa2,0x99,0x07,0x8e,0x24,0x34,0xba,0x22,0x00,0x22,0xf3,0x16,0x0f,0x96,0x8a,0xc0,0x44,0x82,0xbf,0x8c,0xad,0x13,0xb4,0x23,0xf2,0x67,0x0f,0x01,0xfb,0x5f,0x7b,0x32,0xc5,0x97,0x52,0x0f,0x84,0x60,0x7e,0x0f,0x79,0xc0,0x75,0xfa,0x70,0x78,0xe6,0xe6,0x9d,0x3c,0xec,0x31,0x92,0x65,0xd4,0x66,0x08,0x0b,},"\xf5\x5a\xa5\x70\xce\x4f\xc9\x5f\x73\xf5\x17\x20\xd2\x54\xe4\x69\x5f\xcd\xc8\x1a\xaa\x04\x01\x30\xc7\x68\x7f\x03\x9b\x8b\xa5\x9e\xd8\x57\xce\xb2\x9c\x12\x10\x25\xa8\x57\xfe\xac\xb4\xa0\x1f\x38\xe0\x11\x78\x31\x0a\xe6\xe3\x5c\x99\x8e\xbf\x89\xdd\x79\x05\x7b\x4a\xfc\x6d\xb3\x40\x60\x1c\x81\x70\x3c\x87\xa8\xc4\x0e\x5c\xeb\xb0\x44\x1d\xf7\x8a\x6d\xe1\x3a\x44\x7c\xb0\x16\xc6\x5e\x74\x1b\xb7\xdf\x30\x4d\x83\x05\x6b\x72\xc6\x82\xc7\x31\xfa\xc0\xa0\xc7\x0b\x78\x11\xca\x14\xa5\x01\x54\x61\x30\x99\xc2\xc4\x37\x52\x1c\x40\x4b\x63\x61\xde\x36\x21\xf8\xea\x56\xb0\x8e\xbf\xdb\x07\xb4\xf2\xbb\x8b\xa2\xec\xc1\x64\x33\x6d\xa8\xef\xc9\x42\x76\x6e\xf0\xc7\x4d\xfd\x3b\x49\xe0\x87\xe9\xa2\x7a\xe5\x4a\x7a\x2b\x98\x28\x1b\x9a\xf9\x3d\xc1\x1a\xa2\xf0\x92\x24\xab\x5a\x73\x0f\x02\x18\xf4\xa6\xe1\xea\x48\x85\xa7\x7f\xbd\x93\xa1\xc5\x82\x77\xd9\xe0\x1b\xe7\x3a\x25\xcd\xa9\x18\xfc\x27\xdd\xdb\x45\x3a\x5d\xa6\x90\x2a\xd0\x2b\xa0\x57\x75\xc6\x7e\x07\xbe\xa4\xdf\x86\x91\x34\x66\x74\x43\x65\xc1\x32\x6e\x0a\xb5\xe1\x25\x4c\x17\x96\x74\x47\xd5\x91\xba\x5e\xd1\xb6\x3a\x42\x54\x3b\x87\xfe\xd4\x14\x59\xa0\x89\xbc\xea\xff\x21\x98\x02\xa8\x7a\x87\x2a\x76\x3e\x69\x23\x33\xce\x1c\xc7\x39\x78\x25\x08\x4b\x2b\x83\x1e\x93\xd8\x0d\x67\x37\xf3\x29\x80\xf2\xf3\xae\x82\xc6\x21\x90\xfe\x3f\xa7\x00\xc5\xb7\x32\x9d\x6d\x50\x04\x2b\xdf\x83\x1f\x37\x54\x8f\xcc\x80\xb1\x1f\x57\xcf\x20\xf6\x7a\x3b\xb6\x51\xa7\xbe\xff\xcc\x48\xb7\x0d\x17\xeb\x60\xf7\x25\x9c\xc5\x3b\xf7\xff\x60\x80\xeb\x2b\xd0\x92\x3b\x04\x83\xaa\x30\x65\xa8\x95\x5f\x01\xd2\x3b\xa8\x09\x51\xe0\xae\xfd\x2a\x93\x72\x19\x15\x72\xbc\x52\x91\x6a\xa2\x2a\x2a\xec\x39\x37\x67\xfa\xfd\x08\x68\x39\xe2\x36\xfe\x04\x60\xce\x6d\x63\x9c\x7c\xe6\x9f\xe7\xf9\xd3\xaa\xd2\x13\x05\x73\x44\x35\x70\x44\x3b\xe6\xba\xb9\x3a\x06\xa5\x4b\x8a\xc2\x9b\xf3\x3f\xf9\x94\x9b\xc9\x21\x58\xe6\x92\x4b\x6b\x68\xec\xda\x5f\x6f\x3a\xaf\x42\xb3\xd2\x2d\xf6\xd5\xe6\x7d\x5c\xb3\xab\x71\xeb\x8e\xe0\xb0\xe6\x67\x32\xe1\xda\xca\x6c\xd6\x0d\x9a\xa7\x43\x05\xfc\xd5\x70\x07\x6d\x22\x8d\x44\x6d\x5e\xe5\x42\xb1\x04\x88\xbf\x8a\xa9\x88\xf4\x51\xfa\xeb\xe7\x4a\xb6\x69\xd6\x04\xd9\xdd\xb1\x51\x06\x62\x0e\xa0\x2e\x8d\xb3\x8c\xe6\x39\xb5\x74\x78\x12\xbb\x90\x48\xee\x8b\xf7\x2b\x1a\x95\x1a\x05\xdf\xfa\xc9\x54\x17\xcb\x43\xb0\x6d\xce\x61\xee\x3d\xa6\xf2\x83\x2e\xe8\x3b\x2e\x72\x88\xdd\xd6\x2e\xeb\x58\x93\xf7\xf2\xf6\xc8\x09\x0d\x99\xe3\x36\xc9\xf9\x06\x9e\x18\x15\x98\x58\x41\xbd\xd5\x05\xb5\xf8\x3d\x89\x5e\x87\x95\x93\xda\xde\xe7\x2c\xeb\x97\x65\x69\x9b\xf8\x0b\xd0\x6a\x5c\x55\x33\x1b\x25\x45\x52\x7d\x0c\x7c\xae\xce\x96\x58\x4c\xe3\xec\x7f\xe0\x22\x60\xf2\x0b\x8a\x1c\x06\x35\x76\x3f\xf4"}, +{{0xf2,0xc1,0x05,0x77,0xf7,0xdf,0x77,0xf0,0xc1,0x15,0x7a,0x8c,0x33,0x1a,0x7b,0xd2,0xae,0x63,0x86,0x67,0x0e,0xb6,0x5f,0x0f,0xae,0x12,0x23,0x31,0x69,0x0f,0x82,0x8a,},{0x0d,0x4c,0x34,0x0f,0xc2,0x31,0xaa,0xfb,0x3b,0x6f,0x74,0xb8,0x9b,0xce,0xf7,0xee,0xaa,0x0b,0x04,0xf2,0x93,0xec,0x85,0x44,0x24,0x7b,0xfc,0x3f,0x2d,0x57,0xc1,0xe0,},{0x60,0xb7,0x03,0x11,0x5a,0x32,0x2a,0xb8,0x92,0xc2,0x76,0xbf,0xd1,0x8f,0x70,0xa9,0xeb,0x0c,0x73,0x23,0xe2,0xc0,0xa6,0xeb,0x5f,0xc7,0xe3,0x30,0xb0,0xbc,0x3b,0x07,0xa5,0x78,0xa0,0x82,0x84,0x62,0x64,0xf0,0x32,0xc6,0x19,0x1d,0x04,0x0b,0xd9,0x8e,0x5d,0x5a,0x4d,0x4f,0x07,0x6f,0xb9,0x06,0x2a,0xcd,0x36,0xbe,0xa4,0x0c,0x91,0x02,},"\x38\xea\x1e\x02\x8a\x49\x3d\x1c\x60\xec\x70\x74\x9f\x14\xd4\x36\xeb\x3a\x2b\x2d\xe5\x4f\x21\x3d\x01\xa6\x45\xb5\x80\x43\x0e\xcd\x8e\xce\x6b\x55\x69\xcc\x01\x7a\x49\x43\xe5\x59\x5c\x5e\xd6\xe4\x8c\x94\x43\xf2\xfa\x5e\xb2\x22\x7f\xfe\x56\xd2\x11\xf2\x69\xbc\x8f\x6f\xa9\xee\x8c\xd5\x6f\x6b\x84\x70\x53\x92\x08\xaf\xe2\x9a\xb0\xa1\x95\x04\x4d\x95\x7b\x31\xf9\x3e\x18\x4a\x9c\xbe\xf1\xa1\x4e\x14\xf8\x08\xbb\xf5\x89\xac\x77\x70\x08\x4f\x99\x8e\x1b\x25\x4d\xa5\x9c\xa6\xd3\xe6\x2e\x7b\xe1\x79\x07\x16\xd2\x56\x0f\x01\x5f\x39\x9c\xbb\xce\x48\xcf\xd0\x39\x1e\xad\x19\x93\x44\x6f\x6b\x24\x93\x97\x7d\x93\xd7\xb0\x9a\x07\xa7\x9a\x59\xce\x15\xdc\xe7\xa1\xda\x9c\x64\x6f\x45\xaf\x2c\xca\xd5\x5b\xa1\x58\xe6\x38\xc4\xa3\x0c\x5d\x30\xe9\xac\x6e\x3a\x33\x39\xc2\x43\x42\x6d\x86\x49\x1b\x2d\x92\xda\xc1\x47\x8e\x8d\x74\xff\x0b\xf1\x49\xbd\xb5\xe0\x9e\x3f\xb6\xb8\x26\x2e\xb0\x68\x79\x81\x55\x4a\xe2\xcb\x47\x19\x63\x39\x07\x9d\xa0\xa1\xa5\x72\x39\xc1\x9b\xf7\x81\xf6\x2f\xda\xf4\xe3\x15\x60\xa8\x43\x17\xef\x03\x04\x92\xcf\x1b\xb1\x30\x5b\xa8\x51\x8e\xba\xf2\xb4\x34\xd3\x64\x16\x72\xc8\xf6\xea\x2d\xef\xa6\x96\xdc\x7e\x4f\x39\xef\xc0\x8d\x28\x8d\x1c\x96\x6a\x6c\x71\x48\xc0\x12\xee\xc4\x39\xf7\xe1\x2d\xba\xb5\xb8\x7c\xfa\x44\xc9\xae\x19\x00\xf8\x38\x6f\x24\x44\x4e\x10\x92\xb2\x3a\x27\x4c\x13\x8e\x95\xc6\x61\xe9\x37\x7e\x8a\xd2\xd1\xfc\xaf\x19\x39\xec\x9a\x63\x2a\x87\x3f\x7e\xad\xbe\x68\x7b\x4a\x03\x3b\x92\xa4\x77\xf2\xe0\x2e\x9e\xd9\x2c\xe4\xf9\x5c\xf1\x70\xb3\x90\x15\x18\xa0\x62\x14\x3e\x56\xdb\x05\x4d\xf4\xe4\x43\x15\x44\x78\x5a\x6d\xfa\x24\xee\xc0\xf0\xde\x7a\x69\x9c\xcf\x28\x6d\xad\xfa\xd8\x59\x03\x61\x22\x50\x76\x4f\x25\xcd\xea\x81\x27\xd0\x07\x8d\x55\x48\x25\xea\x6e\x73\x71\xc4\x38\xbc\x46\xf2\x9f\xb8\x93\x7f\x8d\x9a\x39\xcf\x88\x49\x05\x2d\x43\xec\xbf\xf6\xc4\xa3\x76\x2a\x5f\x40\x0c\x15\x14\xe8\x5e\x91\x38\x4f\xef\x9b\x40\xf4\x31\x4e\x22\x3a\x9d\x68\xc5\x26\xac\xc7\x02\x27\xd6\x2b\x8b\x63\x7a\x34\x2d\xf1\x13\xd3\x18\x20\x2c\x51\xed\xd3\xc1\xef\xd1\xff\x20\xb1\xff\x07\x8b\x32\x06\x8e\x79\x4d\x92\x81\x33\x03\x7f\x1e\x3a\x34\x68\x9e\x62\x9e\x43\xfd\x2b\x8e\x88\xea\xb5\x0d\x7e\x7a\xb0\x64\x70\x14\xab\x5e\x4a\xd5\x82\x00\x65\x67\xef\xf7\x2b\x5a\xf2\xda\xc5\x36\x89\x2c\xcc\x87\x1f\x8a\x80\xb5\xcb\x79\xd9\x0b\xcc\x6b\x77\xd4\xcd\x08\xf8\x76\x18\x4e\xf5\x8c\x06\x4a\xe4\x30\xbb\x79\xa6\xb9\xe9\x6b\x0a\xd8\x73\x68\xaa\x83\x8a\x8d\xcc\xff\xac\x0c\xd8\xce\x9e\xa0\xd0\xec\x4c\x4b\x0f\x42\x67\x34\x16\x65\x9c\x98\x49\x92\xcf\x53\xb1\xe4\x45\x43\x10\x07\x64\x0d\x47\xec\xe2\x6d\xee\x4a\x29\x43\xaa\x70\x97\xdd\x35\x6c\xff\x47\x54\xf2\x1a\xc0\x7f\x6b\x3f\x73\xc4\x69\x05\x55\x12\xf3\x7a\xba"}, +{{0x04,0x1a,0x97,0x90,0x6b,0x59,0x56,0xb9,0xd3,0x40,0xf2,0xe0,0xd7,0xa1,0xdc,0xbf,0xef,0xe6,0x63,0xe9,0xbb,0x40,0x26,0xf8,0xcc,0x1a,0xe7,0xe2,0xa1,0x4d,0xe2,0x7e,},{0xf3,0x82,0xd3,0x2e,0x88,0xc3,0xa7,0x2c,0x7c,0xad,0xda,0xfc,0xf8,0xaa,0x69,0x9e,0x21,0xdb,0x7a,0x6b,0xf4,0xed,0xd6,0xe4,0x9a,0x00,0x5a,0xad,0x70,0x2e,0x6a,0x79,},{0xa2,0x3f,0x03,0x2e,0x66,0x92,0xa0,0xe8,0xbf,0xee,0x5b,0x2d,0x30,0xb4,0x14,0xcb,0x16,0xc3,0x5a,0xd0,0x8d,0xa3,0x1f,0x69,0x6d,0x46,0x1a,0x02,0x85,0x78,0x22,0xc4,0xef,0x35,0x7f,0x0c,0xcf,0x31,0x02,0x5a,0x4d,0xc9,0x5c,0xed,0x30,0xa9,0x94,0xf4,0x1e,0xdd,0x1d,0x08,0x7a,0xfc,0xaa,0xf3,0xe8,0xe8,0x75,0x70,0x83,0x20,0xf8,0x0c,},"\x71\xa7\x59\x57\x41\x15\x44\x97\x5a\x48\xcf\x10\x3a\xa1\xf8\xe2\xad\x15\x24\x44\x59\xcd\xc0\xe3\x36\x96\x6e\xb8\xb2\x6c\x97\xf2\x16\x9e\x5d\x78\x53\x70\x37\xef\xc0\x77\xe8\x6f\x06\xe0\x5e\x9c\x1d\xc3\x41\x82\x88\xc0\xa2\xbe\x6b\xa3\x4b\x3a\x04\xab\x20\xba\xe7\xf3\x62\x10\x94\xb8\x7d\x78\xa7\xea\xcb\x86\x4d\x40\x78\xcb\x4e\xfc\xba\xc5\xad\xd9\x37\xa2\xc6\x01\x2e\xe1\xa8\xb2\x56\xcc\x27\x6b\x65\xd5\xe9\x2b\x4d\x00\xb9\xb1\x1f\xad\x88\x49\x91\xde\xc4\xc1\xcb\x9d\xce\x18\x63\xc8\xb0\xa2\x10\x16\x1a\xe6\xb3\xf8\xbf\x9c\xc4\xdc\xe4\xad\xfd\xc8\xed\x57\xd8\x3e\x95\xab\x9d\xd2\xd9\x26\x58\xdf\xbd\x3a\xfa\x99\xe3\xf8\x95\x1e\x2a\xd7\x4a\x14\x8f\x6f\x59\x7e\xb2\xc9\x45\xc1\xf1\xb9\x44\x61\xae\x07\x45\x48\x1f\xd0\xed\xf8\x38\xc6\x28\x60\x35\xe3\x6f\x01\x12\x38\x87\x5d\xbb\xa2\x28\x9d\x3d\x6a\x39\x42\xa7\xf9\x55\x4c\x64\x43\x05\x24\x4d\xdb\x77\xc1\x17\xcb\x4b\x56\x23\x77\x29\xdd\xe4\x28\xb8\xbb\x42\xdf\x9c\xe2\x9e\x14\x4d\xfc\x96\xcf\x6c\x67\x67\xb1\xee\x6d\x05\x3c\xe4\xf8\xbb\x20\x56\xab\x78\x10\xaa\x13\x68\xa8\x91\x0f\x2f\x69\xe0\x61\xc1\x9d\x88\x47\x18\x4f\xed\x53\x4f\x98\x75\x8d\x70\x3a\x76\x88\x5f\x91\xeb\x75\x2a\x21\x95\x4a\x10\xc6\xf6\xb4\xda\x10\x46\x4d\xed\x36\xb0\x00\x89\xf6\x62\x91\x54\x21\xbf\xda\xd4\x96\x75\x36\x89\xcc\xd0\x3b\x62\x40\x21\x08\x07\x61\xe6\x81\x76\xb1\x06\x97\xda\xc8\x78\xe4\xc3\xdb\x2f\xd0\xb2\x8c\x65\x53\x35\xd9\x80\x16\xf1\x9f\x26\x5b\xb0\xb2\x43\x4c\xb4\x63\x78\x44\xd9\x1e\xd0\xce\x05\xed\x25\x91\xfd\x99\x89\x65\xf8\x3f\x31\x97\xd1\x0e\xef\x44\x88\x50\xe7\x92\x03\x27\x24\x70\x1d\xa3\x05\xcb\x6d\x79\x46\x69\x48\x3f\xc3\xdc\x6f\x68\x6b\x18\x3e\x29\x99\x13\x0c\x8f\xc0\x05\x8d\xca\xbb\xc9\x18\x8f\x26\xb2\xd6\x3e\xbd\x6c\xb1\xe1\x8a\x09\x7c\x77\x04\xa5\x9b\x5e\x18\x7e\x01\x42\x59\x3b\x70\x83\xf7\x40\x0a\xfa\x9b\x1b\xf0\xc1\xcc\x6c\x35\x6b\xc4\x33\x4a\xf7\x72\xe6\x71\x53\xb4\x5b\x33\x1b\x99\x09\x20\xc2\x4e\xed\xe2\xc6\xe3\x23\x70\x3f\x52\xec\xd6\x07\x35\xb2\x3b\xf2\x2b\x81\xee\x77\x59\x27\xc3\x7e\x53\xda\xd7\x59\x6e\xa6\x5a\x73\xbb\x96\x77\x5f\x3b\x87\xc8\xb3\xc0\x88\xec\x69\x5b\xc3\xa7\x50\x2c\x0c\x51\x0f\x02\x0b\xf9\xac\xa3\xcb\xb7\xa2\xc0\x11\xc6\x7f\xf2\x7d\x63\x4c\xaf\x1d\xcf\xc5\x8e\x5e\x39\x7e\x66\x58\x25\x22\x72\x01\x1c\x8f\xfd\xd6\x42\x30\xa9\x32\x41\xff\xf6\x83\x72\xc4\xba\x85\x38\x2b\xbb\x22\x93\x09\x65\x29\x22\xdb\x68\x83\x66\x31\xe5\x5b\xe6\x9a\xb6\xad\xb8\xe4\x33\x53\x57\xfc\x92\x3e\xfe\x15\x4a\xfc\xc2\x22\xd6\x0d\x07\xf5\x69\x90\xa3\xe5\xa2\x14\xb2\x27\xae\xcf\xf2\xcd\x1b\xb6\xf0\xc7\x9f\xf5\x45\xf7\x0a\x61\x61\x41\xa9\xd5\x3f\x92\x2a\x02\x44\x3f\x7d\x2a\x46\x89\xc3\x5b\x09\x5d\xd3\x94\xd5\x0b\xf4\x9f\x96\x80\xa5\xf7\xd9"}, +{{0x4b,0xc5,0xe0,0x5a,0xa0,0x03,0xa4,0x49,0x2f,0x4b,0xad,0x10,0x2a,0x53,0x90,0xf7,0xce,0xba,0xb3,0xd3,0xec,0xa9,0x15,0x21,0x42,0xad,0x5e,0xf7,0xd8,0x40,0x30,0xae,},{0x67,0x51,0xd3,0xad,0x8b,0xb6,0xc6,0x4d,0x6a,0x17,0xd7,0xe4,0x47,0xa2,0x7d,0xa2,0x2f,0x5f,0x04,0x03,0xf4,0x37,0xba,0xc9,0x44,0x9f,0x13,0xcc,0x85,0x3d,0xd8,0x40,},{0xa2,0x4f,0xee,0x11,0xf7,0xec,0x6d,0xa3,0xe9,0xdf,0xaf,0x6c,0x85,0x8a,0xc0,0x04,0xb4,0x53,0x1a,0xbd,0x1c,0x9d,0x3b,0xb6,0x4f,0x40,0xdd,0x24,0x7f,0x00,0x35,0x93,0x50,0xe4,0x3b,0x2d,0x4b,0x8f,0xbe,0xc5,0xf6,0xb2,0x41,0xec,0xf9,0xf1,0x10,0x14,0x85,0xcf,0x41,0x87,0x35,0xb0,0x5f,0x71,0x20,0x18,0x33,0x5b,0x20,0x06,0x83,0x08,},"\xa8\xf7\x94\xdb\x17\x95\x66\x7d\x28\xd2\x4b\x70\xac\x22\x00\xa6\x23\x9a\x34\xe2\x43\x8c\xed\x1d\x03\xf9\x7e\xd4\x8b\xeb\x4d\x6b\xea\x67\xc1\x43\x38\xf7\x73\x64\x19\xdc\xd2\xa2\xa7\x97\x37\x26\x57\x2e\x6a\xfe\x7e\xdf\xef\x22\xc9\x9b\xe8\xb0\x69\xf0\x4f\x6d\xc6\x1a\x13\xb3\x43\xc6\xe5\x85\xab\xad\x22\x14\xd8\x5c\x36\xf0\x29\x96\xfa\xbb\x46\xbb\x91\xb5\x17\x6a\xc7\x08\xe4\x9a\x0b\x05\x30\x17\x04\x8f\xbb\x55\x45\x3f\x2b\x82\x08\xd6\x67\x8d\x1a\x8c\xf6\xa1\xee\x9a\xd7\xa9\x1e\x38\x03\x25\x63\x5d\x1e\x23\x6a\x6c\xa1\xd6\xcc\x7f\x6b\x59\xf2\xa2\xbf\x18\x4f\x5e\xe4\x51\xd6\x79\x9f\x69\xba\x11\xa0\xcd\x6b\xc0\x4b\xe8\xa3\x51\xa8\x0e\x72\x5b\x5f\xc4\x56\x3e\x45\xbd\x47\x49\xec\xbc\x45\x20\x52\x29\x10\x5b\x9d\xe7\x32\x61\x49\x85\x27\xf3\xd4\xec\xfb\xb5\x83\xff\x53\x27\x53\xd0\x7c\x38\x52\x6b\xb4\x82\xd1\x71\xa2\x61\xb9\xcf\x89\x90\x6a\x7d\xea\x8c\xbd\x7e\x72\x6b\xa3\x1e\xa6\x88\x03\xa6\xb0\x04\xf6\xdc\xd1\x9e\x67\x19\x50\x46\x37\x38\xcc\xa7\x8b\xb0\xdf\xfa\x3d\x64\x57\xe4\xae\xca\x65\x7e\xc6\x49\xb9\x7e\xe3\x0e\x97\xc8\xcb\xe6\xce\x43\xc2\xaa\x9a\x69\x95\x8e\x9d\xc8\x81\xe4\xaa\x7b\x32\x78\x07\x4e\x78\x7a\xce\x5f\xb6\x01\xd7\xfa\xf7\xca\x51\x03\xec\xbb\xd3\xbd\x55\x4e\xb1\xb0\x66\xf8\x29\x6d\x2c\xc5\x7e\x8c\x8a\x32\xe9\xc0\xe6\xa9\x26\x96\x4d\x6d\xf2\xd8\x64\x58\x64\xb3\x22\xc3\x22\xf1\xca\x80\x73\xce\xdf\x2b\x55\x67\x11\xa7\xa2\x0b\x77\xc0\xa1\xed\x27\x7a\x9a\x6c\xa2\xc0\x71\x54\xe8\x63\xfe\xf5\xa4\x04\xe3\xe8\x9f\x0d\x7f\x30\xf2\x18\xec\x4d\xe7\xa5\x3a\xeb\x9c\x41\xee\xaa\xf6\xce\x74\x96\x49\xc9\x99\x8f\xd6\x2b\xcb\xa2\x87\x23\x38\xe1\x9c\x94\xe5\x9d\xd5\xe2\xdd\x77\x6f\x53\x71\x9d\x21\x74\x69\x76\x93\x2e\xf1\x1a\xbf\x7a\x32\xae\x6b\x07\x44\x66\x5d\x0e\x0c\xe5\x13\x95\x5a\x9e\x68\x53\x1d\x8e\xe4\xde\x9a\x8d\x35\xdd\xfb\x88\xeb\x5a\x48\x6a\xd6\x31\x37\xe8\x89\x2f\xd7\xc6\x89\xd4\xf9\xe7\x02\x1b\x11\x73\xbb\x37\x52\xa5\xee\xcf\x29\x92\xe3\xfd\x46\x42\x26\x3c\x7b\x3d\x81\x5c\x29\xb4\x66\xab\x69\x28\x5f\xfe\x4b\x8d\xaf\xcb\xf3\xd0\x1d\x63\x55\x53\xab\x75\x75\xa7\xa3\x47\x1e\xdc\x7b\xe4\x12\xd3\xd0\x1e\x6f\xe8\xe3\xcd\xc3\xfa\x04\xd2\xa7\x59\x93\x81\xe2\x2b\xba\x49\xc5\x53\x9d\x79\xc6\x2b\x52\xbb\x0e\xca\x33\xf7\x42\x55\xe4\x1a\x95\x26\xa8\x92\x89\xb1\x5f\x18\x50\xd9\xaf\xa8\x7e\x6b\x6f\xa1\x27\x10\x1c\x1a\x6d\x88\xd4\x33\xe0\xc8\x6a\xa6\x0b\xba\x8f\xe7\x10\x0e\xd6\x1d\x5a\x9d\x00\xa0\x07\x64\x51\x3e\xb1\xc7\xf5\xf5\xc3\xb3\xef\xc4\x53\x2a\x36\xb4\x07\xfe\x2d\x17\xcf\xb4\xe6\xfc\xd6\x04\x9c\xff\x3a\x35\x56\x23\xa3\xa4\x13\x90\xea\x48\xf4\x21\x20\xd8\x97\x94\x91\x11\xbe\x3d\x16\x9b\x2d\x2e\xf4\x5b\xdb\x89\x4f\xe2\x0b\x1a\x95\xef\x66\x14\x94\x27\xa9\xd8\xf8\x0a\x9b\x2e"}, +{{0xa3,0xbe,0xd9,0xfe,0x23,0x54,0xbd,0x28,0x60,0x14,0x9a,0x3d,0xb7,0x5a,0x85,0xb1,0x29,0xcf,0x83,0xe9,0xd7,0x3e,0x63,0x17,0xba,0x70,0x54,0x52,0x19,0x33,0xf8,0x96,},{0x5a,0xc0,0x3b,0x4f,0x13,0xd9,0x1d,0x06,0x6b,0x2c,0xe3,0x59,0xe9,0xbb,0x1d,0xfb,0x6b,0xfa,0x5a,0xfa,0x38,0x2f,0xd1,0xcc,0xd7,0x2a,0xef,0x11,0x76,0x07,0x9f,0x89,},{0x33,0xbc,0x1e,0x0b,0xf1,0xb4,0x93,0xe0,0xcf,0xb7,0xea,0x40,0x48,0x0a,0x14,0x23,0xe0,0x91,0xf7,0x14,0x57,0x45,0x01,0x31,0x73,0x78,0x7d,0xf4,0x7a,0x10,0xdb,0x24,0xc1,0x65,0xd0,0x05,0x96,0xfa,0xb7,0x0e,0x68,0xc9,0x4c,0x10,0x4e,0x8a,0x74,0x07,0xcf,0x69,0x5c,0xd3,0xfb,0xe5,0x85,0xb5,0xb1,0x76,0xb8,0x5c,0xcc,0xa4,0xfd,0x08,},"\xdb\x85\x38\x08\x68\x6d\x6d\x21\xf4\xc5\x7b\x54\x1e\x5a\xd6\x33\x94\xd4\x65\xe6\x00\x78\x64\x3c\xab\x1e\x06\x5c\x9f\x30\x6c\x50\x00\x78\xf0\xcc\x41\xef\x0f\x95\x42\xb5\xfe\x35\x6a\xec\x47\x77\xef\x8a\x95\x55\x4c\x97\xb6\xa4\x40\x99\xe9\xbd\x64\x04\xfb\x0b\x2e\x41\xf9\x19\x14\xb0\x74\xd1\x22\x37\xcd\x44\x2e\xbd\x40\xb5\x1b\x8b\xc8\xbb\xe4\x37\xa2\xc5\x33\x32\xd2\xbe\xb2\x28\x1b\xf7\x32\x4a\x0c\xf5\xb7\x41\xbb\xf9\x8d\x1e\xb9\x85\x8b\xe9\x26\xe9\x15\xa7\x8e\x8d\x31\x4b\x41\x44\xf3\xd2\x0d\xfc\x6c\xb7\xf4\x8c\x23\xaf\x90\xf8\x71\xc6\xcd\xa9\x08\x45\xa4\x1a\xff\x17\x07\xa8\x7b\x4e\x55\x16\xf1\x8e\x8b\xd7\x68\x3c\xfd\x74\x07\x08\x03\xe8\x88\x33\x8c\x9a\x18\xf7\x92\xc8\xd3\xa7\x04\x17\x0f\xf9\x82\xbf\xfc\x9e\x8e\xc9\xea\x5d\x1a\x62\x59\x2f\x16\x88\xd4\xf2\xb0\x1e\x11\xf9\xf8\x87\x74\xc4\x7a\xc1\xd5\x8f\x69\x0b\xcf\x28\x8c\xf8\xa4\x73\xd3\x50\xa8\x23\x9d\xf9\xd3\xa6\x28\x81\xda\xdd\x33\x85\x31\xfd\xce\x76\x15\x80\x7c\xe9\x65\x49\x6d\x6f\x35\xd6\xc0\x42\xf0\xce\x7f\x21\xef\xe5\xce\x64\x25\x18\x59\x41\xed\x56\x36\xb8\xae\x91\x3a\x75\xd2\x1a\xb9\xdb\xdb\x3c\x3b\x66\x87\xa4\x5e\x04\x49\x38\xa9\xf1\xc1\x3a\x33\x0e\xa9\x76\x1e\x28\x3e\x61\xd4\xa3\x20\xe1\xf5\x59\x88\x2f\x34\xb6\x07\xfe\xfe\x32\xc3\x43\x17\x4a\xbc\xdc\x77\xb0\x65\xa9\x29\x04\xb4\x2d\x96\x1d\xb8\xed\x91\x6c\x01\x46\x4f\xfd\x43\xf9\x3c\x10\x77\xf1\xdf\x7e\xe6\x50\x31\xcf\xe0\x5d\x78\x0d\x01\xd0\x8e\xe0\x36\xf2\x2a\x2b\x05\x12\x19\x3b\x0c\x0f\x38\x01\xe0\xa0\x20\x8e\xef\x24\x5c\x9e\x51\x93\x52\xd2\xb0\x09\x63\x82\xf2\xcb\xa0\x6e\xb2\xa0\x1d\xac\xf6\x19\xea\xbb\xc8\x83\xc5\xd4\xf2\xfd\x7c\x34\x23\x17\x9c\x0f\x5f\xfd\xaf\x8c\xaf\xff\x5c\x46\xb3\x4a\x09\xc3\xc5\x0e\x29\x49\xc0\x60\x00\x20\x7d\x70\xd3\x7d\x65\xa7\x43\x07\x5f\xdc\x2b\xe6\x2d\x41\x2a\xa6\x3e\x36\x37\x06\xca\x90\xe6\xef\x44\xe1\x52\xea\x4d\xc5\xc2\x89\x3e\xcd\x08\xd7\x96\xd4\x1f\x17\x22\x54\xc3\xd1\xd1\x4b\xb0\x67\xb5\x3a\x08\x97\xbb\xd7\x3c\x99\x54\xd9\x64\x8b\x2a\xf1\x0d\x9c\x27\x03\xe3\x8b\x6c\x62\x46\x9f\x6f\x95\x8a\x1c\xa0\xa3\x20\xc1\x23\x39\xe9\x0c\xf7\x68\xc8\x7b\x47\x38\xc2\x19\xf8\x09\x3b\xff\x4c\x2c\xfd\x29\x45\x9f\x6d\x32\x81\x34\x93\x78\xe9\x15\xa3\xb0\xe7\x24\xc7\x4d\x2b\xd7\xa8\x51\xac\x7c\x6b\x48\xe8\xaf\xc7\x12\x4f\xdc\xbc\xab\x5f\xf8\x0d\x1d\xee\x30\xa6\xc0\x24\xcb\x43\x31\x97\x23\x66\xeb\xab\x26\xbb\xb9\xf6\x08\xca\xac\x7e\x51\x91\x4d\xf0\x58\xb9\xb3\x74\x5d\x98\xc5\xd2\x7e\x97\x10\x54\x75\xec\x01\x73\x77\xe6\x31\x61\x98\xec\xe4\xec\x59\x09\xf0\x4f\xc2\x7e\x7b\x38\x2e\x66\xad\xb6\x2a\xc8\xa9\x77\xf3\x76\xfd\x5d\xae\x43\x4f\xb5\x51\x75\x24\x9c\xa1\xab\x6b\xb0\x2d\xec\x06\x96\xf0\x89\xbe\x34\x54\x88\x7a\x0c\x32\x36\x1d\x17\x2b\xd2"}, +{{0x88,0xa2,0x4f,0x0d,0xf3,0xae,0x29,0x14,0xdf,0x79,0xda,0x50,0xec,0xf8,0xec,0xb4,0x2f,0x68,0xc7,0xba,0xad,0x3b,0x6c,0x3a,0x2e,0x0c,0xc9,0xc2,0x5d,0x09,0xd1,0x42,},{0x12,0xe6,0x60,0x3f,0x71,0x3b,0x23,0x05,0x35,0x85,0x68,0x71,0x00,0x18,0x68,0x5e,0x14,0x15,0x53,0xc4,0x75,0x91,0x39,0x6f,0xb4,0x25,0x9e,0x42,0xdc,0x53,0xb9,0xc9,},{0x17,0x07,0xcc,0x00,0x91,0x86,0xbf,0x3f,0x03,0xf7,0xbb,0x9e,0x3c,0xd4,0xcf,0x6b,0x73,0x7b,0x7a,0x6b,0xaa,0xde,0x7f,0xc6,0xc3,0xff,0x5c,0x12,0x25,0xdb,0xb2,0xba,0xf5,0x4f,0x47,0xc8,0x5e,0xaf,0xa1,0x32,0xc3,0x1e,0xac,0xa0,0x3e,0x6a,0xec,0x14,0x47,0x73,0x3f,0xac,0xd3,0x71,0x49,0xb7,0xc6,0xcf,0x0c,0xd4,0x1f,0x61,0x14,0x04,},"\x65\x4e\x9e\xdc\x69\xfe\x63\x4c\x23\x08\xba\x8c\x46\xa9\x55\xe8\x82\x45\x62\x86\xea\xe3\x59\x3c\xae\x73\x9c\x44\x86\x6c\x0d\xe9\xed\xcb\xbf\x0d\xb1\xc4\x41\x49\x66\x84\x67\x70\x9d\xc9\x70\x62\x98\xdd\x2e\xac\x33\x01\xda\xba\xd5\xbd\x8e\x93\xc5\xe8\xa9\x3f\x19\x4e\x0f\xc1\xd9\xf3\x76\xc1\x44\xc2\x93\xae\xfd\xa0\x86\xb2\x21\x8f\x2e\x9d\xfd\x7c\x2d\xc5\x2b\xa3\x3e\xb2\x29\xdc\xf7\xbb\x68\xce\x0f\x87\x6c\x5f\xd4\xe8\x1a\xfd\x80\x16\x9f\x73\xcf\x26\x4e\x5d\xc0\xce\x16\xe1\xb8\x76\xcd\x11\xc7\xad\x89\x05\x8e\xe0\x82\x0c\x40\x00\x5d\x01\xf1\x19\xf8\xbe\x6f\x1a\xfb\xe2\x4c\xa4\xae\xdc\x18\xe9\x78\x96\x82\x7c\x3e\xd6\x7f\xc4\x56\x30\xe7\x90\x3b\x7f\xee\x9c\x99\x0e\x36\x19\x37\xbf\x4e\xa0\xa4\xd8\xd1\x6c\xf6\xd9\xcf\x03\x81\xe9\x06\x5e\x36\x25\x14\x8f\x8a\xe0\x49\x1a\x03\x41\xd0\xff\x9f\x72\x7b\xe1\xf3\x10\xca\x1e\xc3\xf0\x10\x4a\xa0\x54\x32\x17\x84\xdd\x24\xd5\x3c\x98\x5b\x28\xd4\x40\x82\xf8\xe1\xc1\x08\xa4\x41\x09\x63\x8f\xf5\x11\x6e\xdd\x85\xae\xb8\x6b\x6e\xa5\x12\xa1\x9b\x60\x2e\xdd\x9d\x21\x10\x70\xd0\x44\xaf\x5b\xed\xb6\xc8\x52\x7b\xa3\x49\x1e\x34\x5b\xac\xc1\x30\xb3\x69\x60\x28\x2a\xe7\x37\xb8\x5c\x76\x92\x74\xf0\xf7\xc5\x88\xf4\x0e\x66\x25\xb2\x36\xbd\xc1\xa3\xb8\x73\x20\x46\x0e\xee\xad\xa2\x78\x12\x4b\x56\x68\x87\x4f\x39\xf5\x9c\x2e\x6a\xa2\x08\xc3\xb6\xa9\xb8\x45\xc4\xd0\xa2\x7a\x05\x46\x78\x6f\xa1\x3e\x51\xcc\x98\xb7\x3f\xd7\xee\x32\x7b\x62\x15\xec\x6b\x62\x9f\x4c\xc7\xe4\xbd\x3c\x0a\x3d\xb7\x8a\x21\xff\xfe\x24\xc7\x04\x38\x71\x6b\xc3\x7b\x8d\xa7\xc5\xff\x7c\x36\x88\xa9\x03\x39\xc2\x2e\xb5\x0b\x7c\x2c\xd3\x6b\x68\x83\x1f\xd5\x93\x91\x75\x68\x9b\xd3\xe2\x2c\x38\x81\xaf\x33\x7e\xe1\x44\x35\x70\x9e\x35\x10\x40\xef\x3d\xa9\x55\x72\x4e\x51\xc2\x4a\x5e\x2c\x09\xf8\x91\x80\x83\x93\xfb\xf8\xef\x7f\x1f\x5f\x02\x98\xde\xeb\xdc\xd8\xd6\x66\xcb\xcf\x3e\x86\x6c\x71\x89\x99\xab\x6b\x1f\xee\xc9\xc4\x7e\x02\xe7\xd6\x35\x40\xf8\x99\x63\xd5\x42\xc5\xd0\x1f\xb6\xfc\x30\x76\x89\x68\xae\x81\xb2\x0c\x35\x4b\x40\x00\xc1\x32\x77\x47\x64\xd6\xd4\x43\xad\xd6\x4f\x6d\xd7\x48\xf5\xfb\x5b\x7f\x6e\xba\x40\x1d\xb4\x31\x8b\xe9\x93\x98\x9f\xcc\x25\x77\x96\x1f\xa5\xad\x31\xf6\xa2\xa9\xd6\xa7\x55\x28\x58\x65\xcd\x5d\xc3\xa8\x8c\xfb\x5a\xba\x7d\x92\x3b\xaf\x78\xb5\xd1\x31\xb4\xc2\x14\xdf\x55\xb6\x17\x1f\x45\x20\x9e\x21\xca\x66\x45\x49\x0d\x3a\x36\x44\xdd\xa6\xdc\x92\x9c\x7c\x40\x95\x76\xd3\x71\x64\x75\x5e\xf8\xaa\xf3\xdc\xd4\xd2\x27\x75\xee\x7d\xea\x0e\x56\x5b\xd5\x47\x27\x92\x1c\x64\x9b\xc5\x1f\x20\xc1\xf6\x8c\x1f\xde\xac\x45\x5c\x67\xd7\x1a\x1c\xb8\x83\x7f\x46\x91\x44\x8b\xf0\xbf\x04\x4a\x46\xf1\x68\x5f\xbe\x22\xb1\xe0\x18\x77\xf7\x47\x7d\x34\x99\x40\x8c\x4c\x31\x65\x10\xce\x2e\x55\xb9\x80\x05"}, +{{0x18,0x4d,0x0c,0xe2,0xe9,0xdb,0x7f,0x25,0x7a,0x8b,0xf4,0x64,0x6d,0x16,0xd2,0xc5,0xef,0xc2,0x70,0x2c,0xed,0x02,0x6b,0x69,0x06,0xd3,0xc8,0xc0,0x11,0x8f,0x22,0x61,},{0xe9,0xda,0xb8,0xfd,0x9d,0x94,0xdc,0x9b,0x24,0xcc,0x79,0xc6,0x35,0xcc,0x57,0xce,0x66,0x51,0x89,0x82,0xba,0x3e,0x24,0x47,0x24,0x07,0x41,0xba,0xc0,0x73,0x0e,0xc5,},{0xb1,0xe3,0xbf,0x5f,0xa7,0x4d,0x7e,0x44,0x2c,0xed,0x9a,0x98,0xd9,0x27,0xd8,0xc4,0x5e,0x0e,0x64,0xd8,0x74,0xf8,0xea,0x59,0x20,0xa3,0x60,0xa4,0xbf,0x42,0xd8,0x3c,0xe1,0x8a,0x92,0x4a,0xc7,0x96,0xe1,0xa7,0x7d,0x1b,0x02,0x08,0x29,0x4b,0x50,0xf8,0x22,0x17,0x7f,0xdb,0xdd,0x45,0x8c,0x74,0x35,0x6f,0xcf,0x6b,0xd7,0x94,0x51,0x06,},"\x6a\x9b\x87\x6b\x0b\xf4\x18\x9b\x3c\xc1\x5f\x9e\xb4\xfb\xe7\x93\x2b\x55\x77\x89\x2a\x22\x20\x0c\xe1\x07\x15\x68\x53\xd6\xd3\xca\x36\x3f\x02\x5a\xd7\xa2\xd8\x62\xaa\xdc\x74\x2d\x94\x15\xbd\x8d\x1f\xca\x13\xc9\xdc\xa3\x58\x60\x44\xe5\x5a\x8c\xf5\xde\xe1\xce\x56\x45\x76\xe3\xe8\xe3\x65\x54\x05\x46\x50\x1b\x34\xca\x67\x5c\xf2\x00\xe0\x77\x1a\x81\x8c\x73\xd3\x7f\xcd\xa8\xcb\x15\xe4\x8d\x5a\x0b\x9e\xa3\xbe\xec\x0f\xf6\x61\x0b\x2a\x8a\x21\x4c\xa4\xf7\xef\xac\x0e\x71\x38\x10\x52\xd9\xbf\x3c\x00\xc3\x29\x59\x34\x74\xeb\xd0\xa6\x87\xa0\xb4\x1d\x14\x4b\x5e\x7a\xb1\x41\x2b\x97\x0a\x74\xba\xba\x4d\x27\x4b\xb0\xdb\xfd\xb0\x2b\x11\xf7\xf6\x39\x64\xba\x6f\x3b\xa0\xad\x23\x34\x1d\x08\x3b\x91\xa4\x30\x82\x39\xe3\x3d\x50\x82\x43\x96\x12\x65\x88\xde\x72\xa2\x39\x0c\x1c\x0f\xc0\x67\x47\xc2\x87\x72\xf6\x30\xbf\x4d\x14\x3f\x7a\x11\x59\xf0\x28\xc0\x93\x40\x48\x94\xe6\xd1\x6f\x63\x46\x35\xd4\xfc\x33\x0f\x3d\x7a\x73\x13\xef\x75\x6f\x5d\x49\xd8\xf6\x20\x5e\xb1\xc7\x92\xa9\x49\x5d\xa1\x31\xb4\x33\x45\xa0\x09\x0c\x12\xca\x56\xe6\xad\xac\x5b\xe0\xcb\xca\xc3\x60\x9d\x69\xf7\x24\x15\xf6\xc3\x7f\x3c\xfb\x2c\xf7\x6b\x3e\x65\xf3\xc9\x3a\xc9\x2b\x63\xf2\xba\xa4\x66\x24\x90\x75\xbc\xa6\x9d\x4c\x1d\x1f\x3a\xde\x24\xab\x31\xef\xfc\xb9\x04\x69\xc2\x4b\xb4\x10\xab\x47\x23\xe1\xb7\xe1\xc8\x8b\x3a\x36\x43\x35\x63\xf7\x1a\x99\xaa\xd5\x8f\xe8\x05\x68\xf9\xc1\x02\xda\x89\xba\xd9\x79\x63\xe7\x7d\x66\x22\x48\x31\x66\xf3\xae\x26\x1f\x32\xa5\x2a\x86\x10\x1e\xbd\x64\x5f\x61\x42\xc9\x82\xe2\xcd\x36\x25\xcf\x8b\x46\xb9\xb2\x89\x12\x46\x92\x0f\x69\x7f\xca\xed\x39\x7c\xb9\x22\xc2\x74\x94\x51\x67\xa0\xe6\x19\xb0\xb5\x06\x37\x76\x06\xdb\x04\x57\x83\xb0\xb8\x8e\xa0\x4e\x93\x2d\x21\xff\xc0\x64\xa1\x2a\x40\xeb\xe9\xb4\x80\xf1\xa2\xc7\xdd\xd3\x95\xa9\xb1\x5e\xfd\xc4\x95\xc9\x71\x4f\x36\xfa\x99\x6f\x79\xf8\xeb\x8e\xfa\x52\xd9\x9a\x24\xab\xfe\xf4\x3b\x32\xa2\x37\xc5\xbc\x00\x18\xda\x3b\x16\x2f\x59\xb8\xd3\xd4\x74\xe2\xce\x08\xfa\x80\x24\xc5\x8a\xcc\x0a\x99\xff\x61\x4e\x6c\xd7\xfd\xd9\xca\x4e\x8f\x41\xa1\x44\x9a\xa6\x18\xd0\x33\x37\xe8\xa3\x74\xd5\x60\x55\xb2\x07\xa9\xdb\xe6\x9f\x59\x48\xf9\x01\xca\x7d\xb0\x41\x0f\x01\xaa\x37\x3d\x9e\x02\x27\x62\x35\x99\xbc\x21\x28\x45\xb0\x06\xe9\x42\xfa\xbc\x58\x2c\xd7\x26\xdb\x5c\x44\x3e\xb2\xdf\xfb\xc9\xe3\xe7\xf0\xe5\xcb\x67\x44\xf7\xad\x71\x60\x50\xfd\xf2\xc6\x0c\x7c\x77\xc2\x53\xab\x74\x5d\xb9\xc8\x55\x26\x55\x68\x3e\xa7\xea\x68\x0a\xa4\xaf\x34\xdf\x13\x25\xc2\x9b\x88\x74\xb6\x1b\xe2\x3d\xe4\xff\xba\x25\x42\x4f\x46\x19\xec\x68\x2c\x26\xb3\xa6\x7b\xda\x9b\xc4\xc9\x4b\x79\xa9\xfc\x4d\x82\xd3\x40\x49\x5b\x43\x7a\x1c\xbd\x6b\x60\x30\x7c\xfc\xb1\x00\x26\xf9\x64\xa0\x17\x62\x3e\x33\xdb\xf2\x33"}, +{{0xd0,0x2b,0xbf,0x70,0xd5,0x13,0x51,0xe3,0xb4,0x7a,0xd8,0xe5,0xed,0x26,0x3d,0xbf,0x55,0x6d,0x14,0x98,0xfa,0x9b,0xd5,0xdb,0xd9,0x9f,0xb4,0x26,0x90,0x09,0xdc,0xed,},{0x8c,0xe4,0xb5,0x9f,0x94,0xce,0xd6,0xec,0x96,0x14,0xd6,0x7d,0x30,0x66,0xd9,0xd3,0xa0,0xdf,0x7a,0x46,0xb3,0x7b,0x4c,0x17,0x25,0xef,0x1e,0x57,0xbc,0x68,0xa0,0xd1,},{0x6e,0x7c,0x66,0xac,0xc9,0x54,0xff,0xd9,0xdd,0x4c,0x1c,0x63,0x35,0xab,0x4f,0xe7,0x9d,0xbb,0xed,0x78,0x2c,0x4a,0x47,0xec,0x30,0xd8,0x48,0xd8,0xbb,0x2b,0x4f,0x10,0x69,0xdc,0x62,0xe5,0x22,0xa1,0xe8,0x01,0x7f,0x54,0xa6,0x34,0x5e,0x17,0x28,0xc0,0x73,0xaf,0x64,0x47,0x85,0x6d,0x8c,0x1e,0xd3,0x58,0x78,0xb5,0x71,0xe5,0x23,0x0d,},"\x55\x45\x60\xf7\xa7\xfd\x1a\xe7\x75\x8a\x2f\xce\x7d\x78\x0f\x6b\x3f\x04\x3d\x3a\xf8\x9d\x4f\x19\xef\x57\x3c\x34\x99\x75\x54\xdf\x24\x3f\xaf\x2a\xaa\xb6\x5b\x2a\xfd\xd2\x86\x10\xd4\xa5\x1e\x9a\x4b\x46\x4d\xb6\xdb\x09\xeb\xf7\x3b\x7d\x24\x05\x4c\xc9\xb1\x28\x14\xbb\x29\xee\x99\xe1\xa7\x3b\xd6\x03\x89\x83\x60\xf9\xdc\xf0\x1e\x67\x08\x36\x28\x6f\x82\x36\xed\x8c\xef\x07\x5f\x3d\x56\x33\x12\xc1\x6c\x73\xfc\x37\xee\xdf\x25\x2f\x8f\x42\xd3\x0a\x13\xe7\xfb\xa3\xb1\x65\x23\x8c\x7f\x81\xea\xae\xb5\x31\x90\xf3\xec\x3b\x5d\x63\xf0\xee\x03\xe3\x98\x7e\x39\x0d\x1d\x81\xe8\x27\x7e\x9f\x6c\x1e\xe6\xec\x4e\xc3\xfa\x0d\x72\x0e\x9f\x53\xf9\xc2\x6f\x04\xaa\x2e\xd2\xb5\xef\x31\x60\x89\x59\x99\xea\xce\x29\xcf\x5d\xc2\x54\xad\x71\x10\x6b\xb7\xe8\xbc\x29\xa5\xb1\xd2\x41\x25\x93\xd0\x81\x94\xe8\x8e\x16\x59\xa7\x31\x59\xa2\xa2\x20\x33\xab\x06\x6e\x8d\x3d\x8c\x3b\xc8\x6b\x7b\x01\xde\x81\xa8\xc6\x60\x47\xb0\x7f\xe2\x4e\xd2\x40\x31\x8b\xa3\x7b\xa3\xef\xb6\xcf\x63\x26\x04\xca\x4f\x44\x6a\x75\xfd\x8e\x70\xc4\x53\xf0\xc6\x0e\xe1\x6e\xca\xf5\x24\xe7\x03\xf4\x7d\xf5\xc2\x82\xca\x32\x89\xb3\xaf\x61\xde\xe4\x70\x9e\xe0\x85\x32\x3b\x1e\x5c\x8a\x6b\xc0\x76\x62\x01\xc6\x35\x03\x14\x46\x89\x1f\x34\x94\xe9\xdb\x20\xdd\x4e\x9e\x08\x38\x24\x9a\x67\xe1\x38\xd1\x3e\xe2\xc9\x6f\x61\xe7\x71\x06\x15\x42\xaa\x16\xef\x20\xd8\x1e\x3a\x0f\x4e\x45\x21\xa6\xcd\x6c\x92\xfc\x26\xfe\xef\x03\xb6\x6c\x70\xe0\x35\xca\xfc\xc1\x9c\x96\xfb\x9d\x82\x91\x8f\xe1\x97\x78\x0e\xff\x0e\xda\x6e\x25\x12\xc5\x6e\x2a\x73\xd7\x70\x32\xb7\x68\x91\x9b\xea\x97\x72\xf5\x98\x9c\x8b\x6c\x65\xc3\xd1\xe9\x7a\x21\x80\xcc\x3a\x37\x57\x9d\xa7\x0c\xe9\x80\x6a\xc1\x28\x5a\x3e\xab\x41\x5c\x06\x07\xd8\x8c\xb8\x65\x42\xea\xb9\x0b\x9d\x2d\x67\xfa\xff\xfc\xad\x23\xa7\x14\x00\x0e\xe5\x9e\xd6\x8c\x95\x6e\x81\xc4\x45\x42\x88\x82\xf9\x7a\xf7\x4d\xb3\x62\xe4\x5c\x0d\x1b\xd8\x85\x6e\xed\x16\x6e\x4a\xec\x4b\xfd\xf9\x5e\xad\xb2\x51\xe2\xa1\xef\x80\x48\x52\xa9\xea\x77\xd3\x45\x77\xfe\x70\x83\x1a\x92\x8b\x10\x1b\x60\xac\x61\x3e\x7b\xa2\xe6\xba\x0a\x94\x01\x3a\x64\xc2\xf8\x21\x9f\xd3\x0b\xff\x40\x90\x99\x66\x7a\x78\x6f\x99\x32\x7b\xb0\x3e\x2f\x21\x87\xf4\x45\xb4\x6b\xee\xda\xb6\xd3\x25\xaf\xd9\x04\xe3\x95\x43\xe9\x3f\x4b\x6c\x54\x43\x24\x9d\x74\x4b\x2d\x1a\x43\xe1\x41\xe4\x76\x8b\xd4\x0a\xab\xe4\x05\x72\x44\xe1\xea\xdd\x9d\xae\xc1\x75\x71\x9e\x51\xa0\x93\xac\xe3\x2f\xe8\x2b\x2e\xac\xb5\xec\xb0\xda\x6c\x1f\xfe\x98\xc8\xce\xe7\x88\x6e\x30\x16\x70\xdf\xf8\x71\x13\xef\xed\x42\x82\x47\x1a\xfb\x6b\x8a\x0f\xdb\x50\x5e\x2e\x8e\x7d\xbc\x1a\x08\xa2\x2e\x96\x80\xbd\x09\x8b\xf1\x27\x58\x02\xbd\xb4\x59\x41\x3a\x3b\x23\x7d\x77\x13\xa1\xbb\xf5\x97\xe6\xad\xf2\xb6\x0e\xaf\x82\x37\x91\xb3"}, +{{0xaa,0x0f,0xda,0xe2,0xa5,0xa4,0xc9,0xc0,0x45,0x21,0x91,0x30,0x04,0xcd,0x89,0xef,0xbc,0x88,0xb2,0xda,0xdf,0x5a,0xbb,0x24,0x6f,0x3c,0xa7,0xf6,0x92,0x35,0x44,0xaf,},{0xbf,0xfc,0xb1,0x7c,0x35,0xc1,0x30,0x4c,0xdd,0x9d,0x62,0x4f,0xf6,0x9b,0xee,0x60,0xec,0x7c,0x9e,0xc3,0x27,0xd1,0x23,0x50,0xd7,0x0f,0xac,0x12,0xb4,0x7c,0xc2,0x5c,},{0xf9,0x37,0x29,0x89,0x69,0xca,0x34,0xd9,0x75,0x84,0x44,0x89,0x07,0x35,0x8b,0x0f,0x47,0x84,0x1f,0x30,0x23,0xaf,0xc7,0xef,0x76,0x81,0x52,0x1c,0x5b,0xe0,0xf5,0xe5,0x62,0x8a,0x8f,0x60,0x7e,0x2f,0x31,0x63,0x6e,0xf6,0x36,0x46,0xb0,0xe9,0x89,0x8a,0x72,0xad,0x35,0x57,0x06,0xd2,0xc8,0x06,0x0f,0xbc,0x64,0x0e,0xfb,0x3d,0x66,0x05,},"\xb1\x41\x84\xcf\xdc\x4a\x5f\x0c\x7f\x83\xf9\x4a\x83\x2f\x58\x85\x07\xe2\xd7\x2a\x89\x32\x98\x70\x07\x85\x71\xd2\x08\xa0\xc4\x96\x0c\x2f\xdc\x4c\x23\x6c\xf8\x82\x29\x98\x1d\x12\xb1\x0a\x1b\x68\x84\xc8\x65\x0d\xda\xf1\xd4\xb2\xeb\x98\x15\x75\xb1\xe0\x19\xfe\x3f\x60\x42\x36\x76\xf8\x85\x6a\x99\x2c\xce\x36\xd6\xd0\xa3\xd0\x26\x63\x1c\x8c\x1e\x1f\xfe\x34\x13\x4b\x29\x6f\x40\x84\x2b\x6d\xf4\xf8\x6f\x83\x3e\x01\x75\xba\xe5\x0e\x86\xbf\x85\x6d\x1e\xe7\x99\x25\xf4\x34\xb8\xbf\x2c\x84\x51\x9f\x1f\x5d\x25\x38\x60\x49\xce\x3c\xa6\x17\x77\xe3\x0b\x70\x0a\x60\x2d\x39\x52\x50\xb6\x0f\xc6\x4a\xc6\xf8\xdb\x02\x7e\x8d\xa8\xb9\x55\x0f\x24\xed\x11\xa1\x1d\x9f\x9f\x9c\x5e\x0a\xf1\x45\xb8\x65\x97\x51\xac\x6b\x55\x86\x1f\x63\x88\xa6\x43\x36\xb3\x1e\xfe\x45\xc0\x80\x2d\x76\xa5\x34\x86\xa8\x1e\xba\x07\x31\x4b\x4d\x96\x1c\x14\x1a\xb3\x4e\x2f\x76\xed\xac\x0e\x6d\xe3\x14\x22\xdf\x79\x2a\xf0\x81\xe7\x69\xc7\xed\x05\xda\x9a\x5a\xf2\xfd\xf3\x6f\x14\x17\x69\x90\x8b\x70\x09\x37\xf0\xe1\x06\x8c\x13\x1f\x17\x6e\xb9\x6c\x67\xaf\xdb\xe7\x8f\x40\xd8\x60\x07\xfb\xcd\x47\xe4\x9e\x2e\x4c\x4c\xe0\x49\x93\x6a\xdf\xf1\xce\x3e\xac\x42\xb9\x6b\x34\x29\xb5\x62\x6b\x1a\xa6\x2a\xcd\xe0\x7f\x45\xa1\x3c\xe1\xbd\x21\x1f\x32\xbd\x7e\xfe\x47\x90\xc8\x37\x1e\xbf\x87\xc1\x64\x47\x7a\x5c\x9f\xa3\xe7\x8c\x2f\x88\x07\x7b\x09\x73\x44\xcf\xfa\x03\x1c\x44\x29\xc7\xf4\x2d\xca\x07\x73\x78\x50\xee\x7a\x76\x9b\x36\xd0\xf0\x62\x5a\xdf\x12\x0e\xa2\x3f\xf4\xe3\x93\xa4\xfd\xcb\x65\x58\xdb\xf9\xb2\x66\xa0\x32\xe3\xb0\x59\x9b\x9d\x66\x92\xfc\xeb\xd8\x15\xa3\x89\x76\x07\x85\x63\x25\xfc\xd0\x11\x5d\xc3\x10\xdb\x3a\x87\x92\xfb\xeb\xd3\x99\x49\x4c\x83\x71\xe5\x85\x72\x7b\x3d\x63\x24\x14\x49\x68\x93\xd0\x38\x13\xba\x1f\x99\x66\x1b\xce\xb9\xdc\x18\xec\x5d\xc2\x7f\x52\x67\x03\x18\x68\x77\x69\xfc\x67\x8d\xdc\x7e\x40\x22\x7c\x20\x05\x22\x01\x3f\x5c\x0e\xec\x0e\x47\x81\xe6\xfc\x15\x3a\x0c\x2f\x4f\x3f\x95\xe5\x17\xc8\x41\x99\x24\xab\x39\x99\x2a\xf8\xc1\x94\x65\x05\x7f\x13\x44\x86\x69\x6b\xa7\xfd\x46\x51\x76\x8b\x4e\x74\x9e\xf3\x6f\x02\x44\x46\x17\xcf\x97\xf0\xa4\x23\xe4\xc1\x3b\x7b\x66\xba\x2b\x6c\x45\x68\x78\xb0\xb5\x0c\xe2\xee\x5e\xc5\x64\xed\x88\x54\xf7\x82\xaa\x1d\x1c\x6a\xa7\x60\xf2\x52\x2c\x7d\x97\xb9\xb1\xab\xe0\xba\x81\x09\x59\xd7\xaa\x40\x3a\x99\x37\x5a\xa3\xe3\x9a\x11\x5d\x1f\xc6\xfe\xdd\x00\x2f\x38\x30\xa5\x0a\x83\x7d\xc7\x20\x32\x9e\xc0\xc7\x3d\x5b\xfd\x50\x03\x85\xc7\x36\x83\x82\x87\xe1\x92\x01\x52\x5d\x18\x9c\x3a\x08\x4c\xd5\xa3\xf3\x59\x87\x5e\x3b\x83\x25\x28\x9c\xed\x18\xb6\x3b\x00\xff\x9c\xd0\x70\xc3\xe6\x74\x44\xbd\x3d\x83\x46\x17\x40\x85\xcc\x45\x13\x5c\xaa\x0c\x67\xb3\x22\x6e\x4a\x52\xe9\xa1\xc5\x5a\xed\x7e\xc5\xfa\xde\x6b\xf1\x6c\x19"}, +{{0x71,0x62,0xfe,0xf0,0xac,0xa4,0x97,0x4b,0x09,0x4a,0x6a,0x08,0x05,0x43,0x95,0xf8,0x77,0xff,0x94,0x33,0xf1,0xe3,0x3e,0x20,0xe8,0x8e,0xaa,0x90,0xf9,0x38,0x99,0x7d,},{0xa2,0x80,0x64,0x0f,0x13,0x9f,0x45,0xc3,0x5a,0x48,0x71,0x53,0x7e,0xef,0xe6,0xef,0x9d,0xb0,0x2d,0xe7,0x85,0xee,0x9f,0xd5,0x4f,0x80,0x5f,0xb5,0x7d,0x37,0x46,0xef,},{0xae,0x16,0x1c,0xce,0x95,0x40,0x33,0x84,0xb6,0x5c,0x6b,0xc9,0xb3,0x93,0xeb,0x07,0x25,0x64,0xc3,0x5f,0x3a,0x6c,0x04,0xfa,0x51,0x7a,0xb0,0x68,0xbc,0xd2,0x37,0x67,0xcc,0x0c,0x8e,0xdd,0x92,0xb1,0xa1,0x3a,0xe9,0xa9,0xce,0x48,0x64,0x13,0x7f,0xb8,0x9c,0x1f,0x37,0xb7,0x48,0xcf,0xc9,0x13,0x4b,0x67,0x41,0xba,0x1b,0x22,0x28,0x0d,},"\xc9\x0f\x45\x0b\xda\x1c\x6e\xfd\x8d\x12\x78\xde\xbd\x7a\xe0\x3e\x2e\xac\x27\x40\xa5\xa9\x63\xfc\xf9\x6c\x50\x4e\x31\xd4\xd6\xfc\xc5\xe2\xb5\x2a\x25\x18\xd2\x74\x1c\x55\xe9\x59\x18\x67\xb2\x42\x32\x28\xf9\xc1\x9f\x33\xc6\xf3\x87\x05\xc6\x20\x36\xd4\x80\xff\x53\xdf\x12\x07\x7e\x38\xfd\xb0\x73\xc6\x73\x10\x5d\xa1\xe1\x16\x19\xba\x53\x21\xa7\x1b\x5f\x49\x93\x23\x4a\x11\x94\x8e\xa1\x10\xcf\xa2\x42\xbc\x23\xfa\xc9\xaa\xe4\x62\x60\x6e\x39\x64\x1c\xa7\x14\x7e\xeb\xba\x1e\xec\x55\x3f\xce\x94\xe5\x3e\x4e\x01\xb0\x73\xdd\x78\x0a\x2f\xf6\x78\xb3\x15\x72\xca\x11\xee\x08\x77\xe7\x56\xbc\xdb\x66\x53\xe5\xe1\xb4\xcb\xfb\x56\x9a\x9d\x60\xe3\xee\x33\x61\x82\xdc\xb9\xb2\x5d\x1b\xe6\xdb\xf9\xb5\xc7\x14\x6d\x77\x55\x85\x83\x4c\xab\xde\x02\x78\xae\xe5\xd5\x7c\x85\xe9\x83\xf8\x4d\x88\x33\xa9\xe1\x5b\xcc\x11\x19\x8e\x1c\x1d\xa6\xba\x59\x28\x21\x29\xf1\xdb\x96\x6f\x54\x60\xc8\xfb\x65\x30\xfb\xc3\xa9\x8a\x31\xfc\x0f\x4e\x9b\x33\x73\x66\xee\xc1\xdc\xe1\x08\xc8\x26\xd4\x90\x45\xab\xfa\x12\xee\x88\x79\x7f\x08\xf0\x68\x3f\xef\x77\xed\xaa\x35\x43\xb9\x1c\xb1\x18\xe4\x24\xd9\xc4\x08\xda\x54\x74\x31\x12\x51\x07\xd9\xb0\x74\x4c\x24\x43\xce\x99\x17\xe1\xe3\x28\xd8\x18\x50\xba\xbb\xc9\x4d\x92\x0a\x1d\x06\xe5\x24\xdb\xb6\xc2\x3d\xd8\x2e\x17\x87\x82\x2d\x71\xc4\xcd\xc4\x09\xae\x85\xba\x4d\xeb\x58\x1f\x93\x47\x48\xf7\x5e\x7a\x76\x9b\x9d\x68\xc4\x58\x9e\x59\x4e\x65\xcb\x6c\x8f\x49\x03\xff\xba\xbd\x5a\x32\x6e\x89\x44\x1a\x54\x2f\x8a\xc2\x64\xcc\xc6\x4e\x95\xa8\x98\x2a\x71\x0b\x6c\x56\xff\x7d\x10\x91\x6a\xfc\x40\x9e\xa8\xa4\x1b\x74\x67\x9d\xd6\xa7\x66\xf5\x9c\x52\xb9\x30\x5b\xa7\x33\xb1\x3c\x9e\x81\x1e\xe1\x30\x83\x92\x5f\x42\x00\x68\x2b\xd0\x5d\xea\x33\x95\x32\x52\x29\x70\xaa\x14\x9d\x00\x4a\x2e\xa2\x0f\xf4\x61\xe9\xec\x0f\x3b\x62\x56\x5c\x1a\x10\x62\x59\xc8\x36\x60\x5c\xc2\x7c\xad\xc9\x51\x5c\xb9\x97\x9e\x89\xaf\x28\x7c\x02\x7d\x75\xed\xbf\x87\xd5\xcf\xf6\x3a\x7f\xec\x9b\xd1\x0e\x78\x77\xab\x9b\xf8\x68\xd7\x34\xbd\x3a\x23\x74\xce\xf7\x02\x5c\xc4\xda\xb7\x10\xe2\x54\x80\x66\x85\xa1\x36\xec\xd0\x3e\x36\x77\x03\x46\x51\x3a\x15\x14\x5b\x89\x0e\xee\xf4\x7b\x80\xea\x08\xe4\x6c\x81\xd2\x02\xe5\x33\xe9\xa0\x6a\x38\xa6\xf7\x6e\xf5\x7a\x9c\x73\x6e\xc7\x8d\x00\xb8\x08\xe3\xff\xd9\xc7\x9b\x9d\xc7\xa2\xe5\x89\x90\x76\x56\xc9\x32\xab\x8a\x8b\x57\xda\x1a\x49\x5b\xa7\x45\x20\x15\xe7\x92\x4b\x52\x69\xab\x1f\x67\xbd\xb4\x3a\x35\x83\x14\x87\xab\x90\x02\xf5\x2d\x78\xb1\x34\xcd\x37\x51\x92\x5a\xaa\xb0\xb4\x5c\x8e\x6b\x0f\x2b\xf0\xcc\x9a\x46\x59\x31\x71\x08\xfb\xa9\x13\x6a\xab\xb0\x92\x1a\x58\xfb\xb9\xb5\x0e\x51\x24\x3f\x9b\x53\x18\x47\xdc\x96\x57\xe9\x6f\xba\xf7\xaa\x69\x8f\xe6\xfe\x44\xf9\x05\x90\x14\x4c\x70\x33\x72\x50\xc5\x8b\xc5\xdd"}, +{{0xde,0xa1,0x80,0xc9,0x1b,0x53,0x3a,0xaf,0x73,0x6b,0xc5,0xd3,0xc8,0xe4,0x74,0xd5,0xe5,0xd4,0x75,0xb7,0x5b,0x92,0xcd,0xe6,0xbd,0x1d,0x10,0xf3,0xb8,0xf5,0x5a,0xd4,},{0x30,0xb2,0x0f,0xb3,0x20,0xb0,0x0e,0x77,0xc4,0xe0,0xa8,0xeb,0x37,0x30,0xaf,0x3c,0x0b,0x1c,0x5f,0x5e,0xd9,0xee,0x2b,0x05,0x62,0x70,0x7e,0x4f,0x55,0xc4,0x93,0x8b,},{0xd0,0x83,0x33,0x3f,0xb8,0x4e,0x79,0xc9,0xb3,0x3e,0x55,0xe8,0x19,0x2d,0x57,0x1f,0xfc,0x8d,0xc5,0x07,0x45,0xb6,0xb5,0xfd,0xd8,0xc4,0x4d,0x92,0xa6,0x3f,0xd1,0x78,0xc4,0xe5,0x7c,0x2a,0xb3,0xa1,0x21,0x1c,0x0b,0xa2,0xd3,0x9d,0xa3,0x0b,0x06,0x62,0x9d,0x8d,0x1c,0xc1,0xd9,0xf2,0x59,0x32,0x63,0xd5,0x24,0xfa,0x5a,0x2e,0xbc,0x03,},"\x60\x61\x44\xb7\xd4\xf9\x6b\xef\x7f\x11\x2b\x6d\x41\xbc\xb5\x00\xd2\x13\x6c\x13\x4c\xed\xa2\x20\xe2\x4d\x0f\x15\x24\xec\xa1\x2c\x30\xf2\xb1\x02\xc7\xf3\x78\xd6\xbb\xa2\x59\xc5\xb4\xa5\xef\x8e\xc9\x30\x9d\x5c\x8d\xa7\xe8\xd2\xde\xd3\x79\x2a\xee\xea\x21\x08\xf7\x7d\x66\xb2\x30\x45\x93\x8e\xd6\x47\x51\xf2\x0d\x48\x32\x6b\xe2\xfb\x99\x62\x8c\xfb\x18\x73\xd7\xdd\x27\x58\x1c\x10\x5e\xc1\x32\x49\xa9\x52\xa5\x07\x84\xb8\xb3\x4c\xb3\xb2\xc1\xa0\x04\xfa\x8b\x62\x8a\x07\x67\xfa\x9a\xbf\x05\x8d\x95\x5d\xf8\x5d\x13\x4a\x0f\xc7\xf4\xb7\xd7\xfb\x0c\x8d\x31\xbc\xe3\x45\xdd\x0a\x42\x82\x14\x5a\xfb\x2f\xf1\x97\x51\xf2\xcc\x3a\x1c\xae\xa2\x42\xba\xaf\x53\x87\x49\xbf\x38\x80\x00\xe3\xdc\x1d\x73\x93\x59\xdf\xeb\xae\x64\xae\x1e\x10\xfb\x6f\xc1\x7c\xc9\xfb\x95\x05\x35\xc2\xde\x12\x95\x87\xa8\x68\x59\xb7\xbe\x36\xdf\xe9\xb6\xc1\x14\x1b\x25\xe0\x91\x5c\x8d\x4a\xa1\xcc\xea\xe7\x04\x6b\x3d\x7c\xfa\x94\x0b\xc9\x8d\x4d\x69\xfc\x5a\x30\xdd\xe1\xde\xe4\x2f\xb5\x27\x22\x81\xbf\x8f\x8e\x7f\x3e\x1a\x04\x39\x7f\xb4\xf3\xad\xef\xc5\x75\x32\xdd\xbd\xe3\x68\x33\xa6\x76\xe6\xf3\x9c\x82\xaf\xf6\xbf\x48\x32\xec\x97\x1e\x03\xbe\x38\x29\xc0\x2a\x20\x3c\x82\xd9\xeb\x8c\x16\x30\xee\x96\x93\xf4\x5d\x26\xf5\xf5\x1a\x31\x03\xca\x64\xd4\x68\xec\xea\xc1\xb2\x9a\xf4\xc4\x2e\xb2\x16\xd7\x6e\xc8\x99\x48\x36\xb4\xbe\xc7\x64\x89\xca\x50\x70\x68\x0c\x2c\x2e\xb4\x57\x21\x0a\x77\xc4\x7f\xdc\xbf\x60\x01\x72\x07\x3a\x53\xf1\x45\x3b\xb5\xc8\x04\x39\xc8\x82\xf0\x73\x6d\xe4\x06\x37\xb4\xf5\xab\x1f\x76\x1f\xf3\x55\xc6\xe9\xbd\x4a\xbd\xe7\x56\x0d\x5f\xc1\x13\xc8\x30\x15\x9a\x1b\x77\xc4\xe8\x7b\xc2\xc6\x98\x80\xa4\x0c\x58\x05\xec\xc8\xaa\xaf\x57\x57\x5b\xcc\xd8\x17\x7f\xc6\xb8\x35\x69\x23\x3c\x0f\x5c\xa2\x23\xac\x40\x13\xca\x10\x6c\xac\x28\x54\x70\x6a\xea\xd7\x14\xfa\x29\xf2\x86\x0a\x5f\x97\x53\x26\x8a\x36\x71\xd9\xf5\x9c\xde\x60\x48\xcf\x0b\x89\x86\x05\x0f\x7f\x54\x9e\x4f\xd7\x55\x7f\x2f\xc3\xfc\xdc\xcd\xdc\xef\xda\x58\x6a\x64\xb3\x00\x6e\x58\x25\xf2\x7c\xa3\x16\x87\xca\xf6\x63\xbd\x90\xa0\x5b\x11\x52\xd7\xc8\x8d\x7f\x10\x51\xa9\xd7\x91\x74\x86\x51\xd8\x88\xa6\xa1\x2f\x22\xd6\xc8\xc3\xf7\x8c\x2b\x86\xea\xf5\x39\x4b\x4e\xf7\xee\xfb\x89\x79\x7b\x25\xe5\x42\xdc\x93\x10\x2d\x02\x1a\x1d\x0b\xed\x6a\x7d\xcd\xd8\x10\x2b\x8f\x04\x30\xa0\xbc\x21\xd9\x04\xa3\xc9\x34\x6c\x01\x83\x43\xdd\x99\x37\xcb\x35\x25\x00\x07\xa2\x84\x82\x5d\xb0\x8e\x9a\x11\xfe\xe3\x1c\xff\x7a\x31\x4c\x48\xc4\x2d\x8b\x31\x4a\xcc\x27\x82\x2a\xf0\x3d\x19\x54\xc7\xcc\x8b\xf9\xad\x4e\x9e\x98\xf4\xad\x4e\xfb\x35\x52\x88\xda\xa8\xc9\x0d\xe9\x03\x7e\x64\xa7\x86\x1f\x5e\xe4\x3a\xda\x9f\x0f\xcc\xde\x34\xd0\xbc\xf5\x02\x88\x55\x0f\x70\x0f\x21\x5a\x79\x44\xa5\x38\x0e\x2a\x8e\x3f\x04\xf2\xb4\xf5"}, +{{0x9d,0xaf,0x6d,0xbb,0x7f,0x76,0x29,0x66,0xe7,0xa5,0x7c,0x2e,0xc1,0x99,0x6e,0x9f,0x5b,0x55,0x5b,0x98,0x66,0xb8,0xe3,0x1d,0xea,0xab,0x43,0x56,0xeb,0x13,0x81,0x6e,},{0xf0,0x21,0xb5,0x5a,0x36,0xd9,0xfb,0xfb,0xf2,0x97,0x8b,0xc0,0xdf,0x73,0x6b,0x28,0x9c,0x82,0x41,0xd6,0x43,0x53,0x09,0x84,0x1a,0x13,0x4b,0x07,0xd4,0x7c,0xe4,0xed,},{0x49,0xb6,0xbc,0x46,0xb7,0xab,0xb5,0x69,0x4d,0xa9,0x42,0x15,0xef,0xc4,0xb3,0x0e,0xea,0x04,0xae,0x2e,0x73,0xeb,0x2d,0xa8,0xe8,0xc9,0xef,0x9b,0xe2,0x22,0x24,0x98,0xb1,0x7e,0x13,0x93,0x96,0x46,0xc2,0x9e,0x32,0xd6,0x45,0x58,0x46,0x40,0x64,0x15,0x90,0xb1,0xbb,0xdb,0xfe,0x24,0xf3,0x6c,0x6f,0x69,0x4b,0xf8,0x72,0x38,0xee,0x04,},"\x54\x45\x23\x90\x0d\xaa\x67\x78\xc0\x39\x1a\xe4\x04\x4a\x51\xc0\xc4\xa5\xe4\x44\x13\x3f\xbd\x77\x47\xd5\x39\xa7\x44\xfa\x60\xab\x5d\xc5\x4e\x18\x19\xdc\x8e\x56\x89\x9c\x56\xef\xd7\xef\x3d\xa3\x41\x79\x0e\xcc\x49\x64\x5e\xf3\x25\xc6\x56\x8a\xe9\x71\xd3\x0d\x21\xbb\x7f\x23\x46\x4f\x46\xa2\x4b\x80\xd4\x9b\xb9\x3c\x6e\x91\xde\x79\xb2\x43\x31\xd0\x70\x7f\x43\xd0\x66\x5d\x01\x97\x74\x3a\xdf\xf6\x90\xd6\x15\xa1\xc9\x25\x87\x77\xfc\x47\xd0\x21\x71\x42\x42\x6a\x47\x34\x89\x2e\xb6\x22\xab\x8e\x50\xbb\x12\x8e\xc3\xa8\x95\x26\x6a\x38\x61\xa3\x97\x68\xbc\x76\x09\x6f\x58\x1f\xd0\x82\xdf\x9b\x72\x23\xe8\x5a\x8a\xfb\xdb\x5c\xaa\x49\x22\xaf\x2a\x01\x4b\xf8\xa5\xcd\x11\xe5\xc5\xea\x93\xe9\x1c\xd4\x6d\x5a\x1b\x99\xb8\x5a\x26\x70\xe3\x21\xde\x2e\x32\x25\x5a\xfd\x67\xfe\x2c\x37\xfd\x93\x2c\xac\xa2\x2d\x24\x1f\xaf\x4c\xce\xfe\xff\x58\xd6\xbd\x04\xcf\xaf\x11\xde\xdd\x29\xc8\x71\x9f\xfc\xb0\x2e\xf6\x5c\x5d\x3e\xb7\x8b\x4f\xc0\xd1\x70\xa2\xe3\x43\x2c\xc8\x12\xf0\xd0\x41\xd9\x76\x0c\x13\xc1\x2f\x7c\x7f\x2f\x84\xfe\x5e\x0f\x70\x0c\x10\xb1\xa6\x9c\xa4\x66\xa7\x0b\xde\xff\x8d\xbe\xc7\xd3\x18\xfb\x09\xdd\xd8\x27\xef\x61\xca\xa6\x91\x0b\xbc\x06\x1c\xbd\xa2\xb5\x27\xef\x2e\x59\xed\x4c\x17\x22\x99\x72\xf8\x95\x67\xd7\x05\xde\x92\x31\x92\x4b\x41\xbb\x6e\x7c\x01\xfe\x85\x42\x64\x47\x4f\xa7\x6b\x1f\x88\xcd\x57\xea\xc3\x11\x17\x1a\xf1\x03\xd2\x30\x78\x42\x4a\x12\x67\x5f\x2f\xa3\x6c\x2d\xe0\xbf\x53\xc2\x95\xfe\xeb\x31\x57\xde\x95\x89\x22\x98\x6e\x32\x51\x3d\xfa\x33\xb3\x5e\x15\xc3\x94\xa1\x1c\x0f\xcc\x55\xb8\x2d\x6d\xd0\x59\x7c\xdd\xd2\x7e\xde\x7d\xe1\x29\x85\xa6\x16\xe6\x40\x26\xbe\xfb\x5d\x69\x04\x82\xb3\xff\x22\xc0\xdd\x21\xf2\x7a\x08\x6d\x37\xa0\x49\x9e\xa3\x6f\xe2\xc4\xb5\xa9\x59\xd1\x0e\x9a\x61\x0c\xab\x1f\xe0\xd2\x8c\xf1\x01\x3d\xca\xe6\x3d\x8f\xde\xe0\xec\xbd\x8b\x4e\x19\xd5\xd0\x40\xe2\xfa\xd7\xd0\x41\x3a\x38\xe8\xc4\xe7\x35\x52\xad\x46\x04\x7b\x5b\xbd\xd1\x5c\x09\xcc\x0d\x34\xe4\x8b\x91\xfd\xba\xe2\xa9\xd1\x62\xd4\xb2\x1e\xe2\x0a\x1e\xf5\x35\xea\x88\x35\x95\xbc\x49\x51\x69\x2a\x67\x16\x34\x54\xc7\x36\x7f\x13\x4b\xf6\x45\xd4\x8f\x99\x69\xe3\xd4\xf0\xf9\xea\xf4\x14\x4c\xe9\x80\xa0\xa2\xe3\x34\x2c\x74\x6c\x2b\xdc\x3c\xcd\xc2\xf8\xa7\xda\x57\xa0\xe8\x02\x87\x82\xd3\x0a\xf5\x85\x7d\x9e\xfb\x37\x66\x6d\xf6\x5d\x7c\xc3\x84\x71\x66\x61\xe6\x1f\xf5\xc0\x97\x52\x59\x5e\x94\x11\x2c\xa1\xa8\x40\xd6\xe4\xf6\xec\x0e\x55\x49\x4c\x5b\x44\xf7\xc0\xf0\xd4\xa9\x9c\xd7\x09\x05\xbf\x84\x85\x56\x17\x48\xf4\xdc\x0f\xd7\xa4\x4a\x1b\x13\x91\x13\xc3\x8a\x1e\x8e\xb5\xc7\xa2\x0f\x3e\x95\x2e\xae\xa8\xce\x38\xb2\x07\xc2\x8e\xd9\x72\x71\x8f\x03\x1f\x47\x7c\x62\x07\xce\x43\x3c\x51\x5f\x5a\xc2\x84\x0f\x49\x74\xf1\xf1\x69\x89\x62\x6c\x76\xbc\x98"}, +{{0x71,0x86,0xf8,0xd1,0x68,0xd9,0xdd,0xf1,0x7e,0xdb,0xaf,0x0e,0x7b,0x1a,0xbc,0xb2,0x6d,0xa3,0xe4,0xc0,0x27,0x2d,0x98,0x79,0xc7,0xfd,0xff,0x64,0x21,0xc4,0xea,0x50,},{0x96,0xb4,0xa6,0x56,0x23,0x20,0x29,0xfc,0x1b,0x83,0x64,0x70,0x3c,0xbe,0xa7,0xa5,0xd7,0x38,0x75,0x18,0xa8,0x8c,0xed,0x1a,0x91,0x5e,0xc8,0xd8,0x86,0x84,0x81,0x32,},{0xa9,0xc0,0x49,0x9f,0xc2,0x16,0xa1,0x45,0x32,0xd7,0x36,0x36,0x5c,0x63,0x55,0xf9,0x38,0xf8,0xd8,0x19,0x4f,0xa1,0x13,0x28,0x48,0xf8,0x3e,0x49,0x04,0x54,0xd4,0xbb,0xf6,0x92,0x69,0xf1,0x22,0x59,0xfc,0x6c,0x07,0x4c,0x10,0x15,0xe4,0x25,0xe4,0xf4,0xf2,0x7c,0x02,0x9c,0x93,0x33,0x49,0x51,0x36,0x1a,0x35,0xad,0x11,0x76,0x54,0x0e,},"\xa3\xe6\xcb\x6b\x84\xcc\x5c\xf1\xfb\x1a\x84\x8b\x4b\x8e\xa7\xcb\x7c\x87\xe0\x44\x57\x50\xc6\x1f\x9a\xa5\xd7\x7d\xed\xdf\x94\x94\x63\xec\xd3\x9b\xfc\x71\xf2\x61\x0c\x2a\x94\x24\x84\x7f\xb7\x6f\x84\xc5\xda\x1f\xa1\x0e\xf7\x18\xa3\x45\x66\xce\xc1\xb3\xe8\x99\xe7\x25\x2e\x8d\x4d\x34\x60\x16\x49\x8f\xf1\x19\x97\x27\x50\x06\x16\x60\xba\xed\x31\x28\x27\x58\x31\x81\x07\x3d\x1d\xc7\x4b\x76\xc4\x30\xca\x30\xd4\x09\xe4\xe8\x43\x9c\x0f\xc4\x8c\x00\x68\x06\x29\xd4\x3a\xe2\xa7\x7d\x69\x22\x8f\x7f\x8a\x12\x53\xaf\x15\xbd\x2c\xb6\xbb\x1c\x16\x96\x55\x0c\x4c\x79\x0f\x44\x98\x69\x63\x0a\xb9\x2b\x9c\x11\xcd\xe1\xf9\x61\xaa\x21\x03\xec\x23\xf7\xd9\xf0\xfe\x9c\x3c\x41\x32\x58\x2e\xfa\x79\xa6\x6a\xe3\x42\x6e\x51\x05\xb8\x0b\xfe\x5e\x04\xdc\x8b\xb1\xe3\x8a\x31\x10\xcd\x72\x98\x4b\x3e\xf0\x2a\x0c\xa6\x2a\xb6\x38\xcb\xcf\xbc\x8a\x6b\x59\x3d\x26\x13\xdc\x06\xec\x86\xfe\xe3\x4f\x65\x18\xd4\xa3\xfb\xdc\x15\x72\x37\x17\x45\x64\xda\xeb\x66\x74\xcd\xc3\x4f\x4d\x65\x37\xcf\x81\xd8\xaa\x9b\xdd\xbf\x3a\xed\xa3\x12\xda\xae\xee\x33\x6f\x9e\xd8\xbf\xf8\x1e\x29\x4b\xc7\xd4\x4d\x25\xcd\x78\x70\x72\xe6\xcb\x41\x4b\x65\xfb\x7a\x84\x6f\xc0\x65\x36\x7b\xa8\xe3\x7b\xef\xfd\xf0\xb7\xba\x8f\x98\xcd\xf1\xeb\x87\x0f\x4e\x8b\x71\x30\xfa\x34\x29\xd2\xe2\x4b\xce\x59\x94\xda\xf1\xaa\x65\xe5\xf6\x03\xb6\x31\x05\x3d\xc5\x10\xb2\xf0\x97\xe8\x6e\x9b\x9b\x55\x23\x02\x75\x79\x68\xd0\x13\x6e\xe6\x75\x4c\x42\xa3\x2c\x99\x0a\xdd\x9c\xb5\x29\xbc\x89\x75\x1d\xfa\x4e\x5e\x3a\x0b\xad\xaf\x4c\xc4\x0b\x6a\x09\x50\x7f\x9f\xcd\x24\xc3\xca\x72\x25\x95\x99\xc6\xee\x58\xd8\x57\xb3\xa1\x89\xe0\x48\x90\x2e\x88\x5a\x36\x07\x42\x60\x93\xcb\x0f\xab\x43\x7c\x0f\xb0\xed\x2f\x1e\x96\xe9\x44\x1a\x7e\x95\x4f\xe3\xef\x76\x46\xe2\x6a\x39\xa0\x70\x33\xd0\xa1\x55\x5d\xfe\xed\x9a\x6f\x57\x79\x4a\xf3\xa2\xab\xf0\x05\x7e\x9f\x85\x3a\xe5\xc3\x01\x38\xfd\x80\xe2\xf2\x9c\x2f\x4a\x93\xad\x31\x45\xda\x10\xa3\xe3\x1c\xe9\xff\x97\x86\xac\x65\xd8\x60\x37\xd9\x8b\x7a\xa6\xd1\x1d\xe8\x80\x00\x10\xe1\x33\x86\x9e\xb6\x7a\x50\x39\xb9\xb8\xfe\xb6\xef\x90\x3d\x0c\xc7\x46\x41\x26\x07\xda\x72\x5c\xe2\xdc\x6a\x35\x21\x09\xdb\xc6\xa5\xe4\x0b\x17\x0c\x23\x05\x0b\xc4\xfb\x1e\xfa\x0c\x34\xfe\xc0\x0e\xae\x32\x19\xc2\x90\x40\xe8\xf5\x97\x8c\x93\x84\xee\x91\x5d\x8c\x93\x98\xdd\x12\x0d\x5c\x3c\xba\x38\xf8\x52\x6b\x06\x19\x7c\xb2\xc2\x61\xde\xc7\xd7\x26\xae\x13\x0f\x9b\xee\x17\x26\x17\x00\xe9\x99\x31\xfa\xc4\xb4\xdc\xa0\xf7\x58\x70\x1a\xcb\xf3\x70\x7d\x47\xdf\x53\x21\x13\x0e\xc1\x0b\xb3\xb1\x30\x78\xc4\xdc\x5d\xe3\x47\x0f\x15\x8b\x57\xdb\xeb\x87\x8b\x3a\x85\x24\xe0\xed\x2c\x95\x47\x54\x5f\x0f\xdd\xf1\x31\x25\xe4\x5b\xb2\x3d\x6a\x7b\x38\x3a\x18\x7f\x4c\x5d\x54\xa7\xb4\xc8\x3d\x59\x57\xf2\xcd\x7e\x6f\xbc"}, +{{0xe8,0x6e,0x8c,0x62,0x56,0x6e,0x15,0x75,0x3b,0xd5,0x57,0x7e,0xaa,0xe7,0xf2,0x41,0x05,0xb7,0x40,0x55,0xa2,0x56,0x29,0x58,0x07,0x08,0xbf,0xc8,0x3a,0xeb,0xf0,0x6c,},{0x8c,0x8c,0xe8,0x82,0xd5,0xf7,0x65,0x86,0xd8,0xdd,0xcc,0xc5,0x57,0x9b,0xcc,0x1c,0xdf,0x4c,0xfd,0x71,0x62,0x30,0x4c,0xb1,0x0e,0x76,0x96,0x02,0x6e,0x70,0x7f,0x17,},{0x54,0xd2,0xfd,0x44,0xac,0xf9,0xe2,0x09,0xbc,0x7e,0x43,0x33,0x72,0xbd,0x73,0x07,0x4d,0x07,0x80,0x6a,0x77,0xc6,0xce,0x22,0x8e,0x9b,0xe9,0x94,0x41,0x8b,0x00,0xc7,0xec,0xbc,0xb7,0xac,0x00,0x6c,0x29,0x4a,0xec,0x9d,0xe6,0x68,0x57,0x2a,0xdd,0x51,0x7c,0x06,0xb4,0xeb,0x4f,0xe2,0xff,0x35,0x23,0xbf,0x04,0x3d,0xf4,0x4d,0x3d,0x0d,},"\x12\xfa\x63\x1b\x0e\x48\x2e\x9b\x9d\x63\x3e\x94\xb8\x2d\x8a\xb4\x36\xfe\x54\x8e\x5b\x95\xda\x92\x62\x46\x23\xd1\x3f\x2c\x70\xda\x77\x5b\xa1\x36\xc5\x22\x9c\x16\xa0\xc7\xa6\xfa\x91\x4b\x2f\xed\xa5\x64\xe1\x72\x19\xe4\x73\x70\xf9\x51\x5b\xb1\xd5\x9d\xe6\xe9\x58\x62\x04\xd9\x43\xdc\x56\x0d\x73\xe2\xe7\x57\xf7\xeb\x39\xbb\xc7\x11\x1b\xb4\x6b\xc6\x43\xc1\x3f\x60\x21\x12\x73\x9b\xec\x77\x8d\x7d\x4f\x49\xd0\x92\x56\x3d\x68\xf5\x77\x6e\x43\x0e\x3b\x0b\xf2\xdc\x1b\x01\xbe\xb3\x04\x01\x96\xda\x63\x02\x90\x8b\xfe\x91\xe0\xfc\x38\xe0\x4c\x15\x0e\xf9\x07\xdc\x73\x6c\x44\x5f\xf2\x1f\xdb\xd2\xdc\x1e\xac\x0a\x0f\x5d\x00\xa3\x0a\xf0\x28\xaf\xe2\xff\x61\x16\x2b\x75\x8c\x7d\xa9\xa7\x76\x66\x6a\x11\x23\x59\x43\x1c\x48\x85\x6a\x87\xca\x82\xd3\xdd\x1c\x8a\xf3\x76\x59\x86\x35\x43\x2b\xf8\x91\xbe\xcb\xc3\x3a\x8f\xda\x44\xce\x88\x3e\xa8\xaf\x4a\xd8\xb9\x1a\x92\x61\xce\x76\xb9\xe9\x39\xc4\x61\xfa\xc5\x3a\xe0\xf0\x76\xe8\x2d\x87\x9a\xac\xe8\xf3\x8f\x12\x0b\xc9\xb0\x4d\x81\x25\xed\x24\xbc\xd7\x79\xd9\xd2\x43\x86\xb1\xdd\x20\x17\xeb\xee\x81\x97\x37\x6e\x8c\x36\xfa\x3a\xef\x8c\x1e\x71\x3e\x2b\x8b\xce\x49\x66\xd8\x48\x88\x68\x1b\xa7\x84\x95\xfb\xd1\xd6\xcc\xa5\x86\x26\xe6\x85\x4c\xda\x60\x6b\x83\xd6\x29\x3d\x01\xe8\xe3\xe1\x3b\xbf\x4a\xac\x85\x1d\x9a\x1e\x00\xd0\x02\x4e\x26\x99\x3b\x0b\x30\x91\xbe\x7e\x80\x61\xbc\xbb\x3c\xbb\x23\x02\xce\xab\x96\x89\x7a\x8e\x1f\xf3\x67\xec\x86\x25\x69\x3c\xf3\x15\x34\x12\x4a\x9d\x5d\x72\x5b\xca\xe0\x01\xd6\x7b\xc2\x11\x1d\x0a\xb8\x11\x1f\xa1\xd2\x4e\x4e\xd0\x6d\x63\x58\x3c\xe6\x90\xf2\xa0\x46\x26\xd7\x91\xd2\x9e\x3e\x31\x5a\x41\x5b\xf2\xe8\x53\xa5\xf2\x97\x4c\x83\x3a\x3f\xe2\xe2\x90\x9c\xf6\x69\xc7\x3c\x1f\x59\x39\x2d\x30\xc3\x7f\x3b\x9c\x5a\x3d\xdc\xfd\x75\x62\x1f\xda\x36\xe4\xba\x2f\x16\x14\x78\x58\xf6\xf2\x06\xb9\xa1\x40\xf1\xdd\xc1\x46\x6c\x9a\x53\xed\x73\xf8\x24\x90\xbc\x95\x32\x2c\x95\x5f\x61\xd1\x1c\xb5\x1d\x5e\x8a\x58\xc6\xb3\xcb\x0f\xdf\x04\x19\x76\x32\x01\xbe\xea\x93\xa8\x51\x2b\x14\x05\x24\x5b\xfc\x38\x41\x55\xad\xc5\xce\x77\x8a\xa7\x4d\x00\xa3\x22\x72\x64\x65\x11\x9a\xf7\x95\x01\xf0\x40\xdd\x0a\x7a\x84\x06\x00\x01\xca\x89\xd2\xfe\x5e\x9c\xf9\x77\x9a\x54\x7e\x3e\xbd\x3b\xf8\x64\x29\x90\xa3\x69\x0e\x2b\x2c\x3e\x54\xcb\x7e\xee\xea\xbc\x24\x2b\x4d\xd9\x92\x74\xc4\x25\xa8\x67\x93\x1c\x92\x9c\xa7\x08\x08\x60\x1c\x39\x08\xcf\xd7\x88\x86\x7d\x68\x7d\xc3\x66\xe9\x76\x35\x0c\x9e\x70\x58\x4b\xd3\x90\xd6\x7e\xeb\x7c\xfe\xa2\x6c\x42\x68\x6d\x3d\x96\x20\xf6\x2f\x64\x10\x4e\xf4\x1e\xd1\xd1\x30\xd7\x9e\x32\x59\x38\x48\x62\x96\xb7\xab\x2d\x2a\xdb\x78\x52\x67\x43\xe4\x00\xac\xb2\xb7\xaf\x09\x62\x8d\x68\xcf\x94\x75\x10\x16\x25\xc2\x0e\x1d\xc0\x51\xd7\x3c\x99\x7c\x95\x2e\x12\x81\x2c\x80\x5b\x68\xff"}, +{{0xa5,0xca,0xb2,0x72,0x7e,0x2f,0x13,0x1a,0x4d,0x63,0xfa,0xce,0xe7,0x99,0x33,0x66,0x63,0x93,0x0a,0xa0,0x7a,0xfd,0xa6,0xbd,0x5a,0x8e,0x98,0x5a,0x02,0xde,0xb1,0xea,},{0xac,0x35,0x5f,0x95,0x26,0x0f,0xbf,0xea,0x77,0x8c,0x55,0xb5,0xaf,0x8b,0x3f,0xd1,0xf2,0x4d,0x26,0x93,0xda,0x35,0xde,0x4e,0xe5,0x08,0xa2,0x7e,0xd3,0x50,0x39,0x1f,},{0x13,0x8c,0x7a,0x8e,0xca,0x5b,0x5c,0x37,0x15,0x88,0x13,0x84,0x3c,0x9a,0x90,0x4e,0x5f,0x53,0x0a,0xd9,0x71,0xee,0x43,0x2a,0x44,0xf3,0x44,0xf8,0xc6,0x4b,0xbf,0xaf,0x10,0x2f,0xf4,0x1d,0xaa,0x5c,0xf7,0x22,0xa4,0xbc,0x66,0x40,0x58,0x87,0x59,0xb8,0xf3,0x6f,0x9c,0x05,0x9e,0xab,0x93,0x6c,0xc4,0x5e,0xd4,0x79,0x63,0x94,0xa0,0x02,},"\x48\x34\x39\x15\x4d\xd5\xe5\xd1\x09\x85\x7c\x24\xd1\xc4\xe7\xfb\xbe\xfd\x2f\x38\x65\x1d\xa8\x12\x89\xf2\xad\x3d\x61\x54\x30\x65\x38\xb8\x2a\xc7\xdb\xa9\x21\x0e\x74\x07\x76\xed\xe4\xcc\xf5\x1d\x4f\x63\x09\x4b\x03\xe4\x6a\xd3\xaa\x3c\x31\x94\x7d\x8c\x36\xce\x6f\x94\xe8\x52\x96\xbd\xed\xcc\x1e\xad\x62\xea\xa1\x44\x1e\xcd\xe0\xa2\x25\xd0\xbf\x02\xed\xca\xcf\x86\x50\x14\x89\x9a\xf6\x6d\x98\x08\x04\x0c\x2d\x02\x00\x0a\x0f\x5c\xe4\xf1\x68\x3c\x1a\x49\x52\x76\xd9\xc4\xd7\x28\xc9\xec\xd6\xf0\x78\xdb\x8a\x0c\xfc\x26\x71\x87\x23\x85\x62\xab\x1a\x1e\xa2\x81\x3f\xb4\xf1\x2e\x87\x8e\x1b\xa1\x43\xf4\xd0\x6a\x3b\xc8\x10\x0c\x35\x50\x11\x8d\x69\xda\xe6\x7b\x55\xed\x69\x2a\xcf\x94\x44\xda\xa5\xc3\xe3\xc0\xa9\x8e\xe2\x8c\xf1\x72\xde\x0c\x58\x4c\x9f\x2e\xc9\xbb\x6e\x9b\x57\xf5\x72\xa8\x6f\xf8\x72\x9f\x65\xf4\xc6\x5b\x7f\xea\xcc\xaa\x21\x72\x0e\xd7\x9e\x90\x61\x8b\xca\xfb\xfd\x95\x33\xda\x85\x23\x2b\x45\x08\x83\xaa\x91\x9f\x82\x7f\x04\xc4\xa9\x7b\xf5\x13\x90\xd4\xf8\x56\x9c\x19\x17\x26\xf4\x4f\x7e\x39\xfb\x3d\xb7\x3b\xfc\x41\x5b\x6f\xfc\xa8\xb9\x1a\xca\xad\x69\x23\x85\x72\xf1\x4b\x49\x98\x5e\xa0\x3c\x98\xd7\xb1\xd4\x4b\x3a\x65\x54\x76\x5b\x19\xab\xf9\xb2\x52\x74\xe9\x7e\x46\x34\xe4\xb0\xf9\xe8\x02\xeb\x6f\x74\x3f\xff\x95\x07\x57\xee\x01\x3a\x69\x88\x22\x18\x81\xa7\x44\x3f\x1f\x32\xbc\xcb\x00\x7e\x99\x37\x9c\x7c\xa4\xf9\x06\xd5\xfe\x11\xcb\x12\xf6\x6b\x53\xa3\xd2\x1a\xc9\x47\xbe\x0c\x81\x50\xbc\xd0\x4f\x1c\x81\x6b\x3f\x0c\x07\xc5\xfb\xc0\x90\x5a\x71\x36\x95\x68\x49\xda\x03\x83\x6d\xae\xc2\x5c\x3e\x1a\x06\xec\x3a\xeb\x20\x56\x48\x17\x6f\x89\xf4\xa2\x91\xfa\xc4\xf1\xd3\x89\x9f\x56\xc9\x06\x5e\xeb\xb8\x76\x8b\x84\xb3\x1b\x7c\xc0\x31\x08\xbd\x08\x88\x33\x8d\x17\x74\x99\x49\x70\x29\x2d\x93\x50\x31\xfe\xa3\x35\xd9\xe7\x90\x8f\xe0\x25\x48\x89\xc0\xb1\x71\xcf\xe0\xaf\x2e\x6f\xde\x7a\x5e\xa3\xde\x1f\xdc\xda\xe5\x37\xb6\x31\x31\x19\xc2\x7f\x77\x20\x24\xef\x36\xe4\x5c\x8b\x89\xf2\x6c\x93\xd9\xee\xa1\x37\x25\xe1\x2d\x81\x0c\xf9\x82\x4a\xea\x04\xcb\x80\x2d\xa7\xe4\x58\xe8\x42\xca\x37\x5e\x36\x71\x34\x6e\x00\x89\xde\xc5\x71\xbe\x16\x9b\x0d\x90\x96\x6b\xf3\x68\xfe\x36\x98\xfd\x3e\x72\xbf\x16\x24\x9d\xd9\x00\xaf\x6d\x29\xff\xa4\x83\x51\x36\x0f\x12\x24\x17\x14\x58\x5f\x7a\x9b\x4c\x7b\xaf\xc9\x52\x22\x67\x35\xde\x14\x62\x74\x3d\x78\xab\xad\x0f\x67\x11\xf2\x49\x5f\x33\x13\xad\x4e\x0b\xa2\x16\xb0\xde\xa5\xdc\x15\x16\xa9\x54\x9f\x7d\xfc\xfe\xb9\x3e\x59\x1a\xbe\xda\x5e\xa3\xc7\x04\x59\x06\x52\x3b\x40\x86\x8c\xa5\x73\x5d\x6a\x33\x71\xc3\xc2\x94\xc1\x11\x26\xd0\x97\xf4\xc7\x08\xe9\x04\x64\xc1\xad\x91\x42\xfa\x0b\xed\xf0\x7d\xfc\x5f\x4c\xb6\x7d\x6e\xd8\x0f\x1b\xfe\x72\x68\x3c\xfb\x2a\xd6\x65\x30\xdc\x43\xd7\x02\x3f\x37\x90\xff\x42\xd9\x5b\xd8"}, +{{0xcb,0x63,0x19,0x61,0x37,0x79,0xa4,0xef,0x66,0xbe,0x14,0x14,0x4b,0x28,0x40,0xad,0x01,0x67,0xc0,0x3f,0x3b,0x8d,0x04,0xff,0x59,0x2c,0xd1,0xd2,0xd7,0x22,0xe3,0x30,},{0x18,0xeb,0x03,0xf0,0xa3,0x34,0xb0,0x80,0xe1,0xaf,0x43,0x99,0xd8,0x37,0x6d,0x83,0xc5,0x33,0x31,0x6d,0xc6,0x87,0xcf,0x34,0x1f,0x0a,0xfa,0xb4,0x50,0x96,0x52,0x99,},{0xc1,0xb3,0x99,0xcd,0xc1,0x98,0xe9,0xa1,0x59,0xe6,0x84,0xfc,0x26,0x68,0x6d,0xe6,0x60,0xda,0x54,0xcf,0xe3,0x12,0xca,0x73,0x45,0xdf,0x0c,0x7d,0x15,0xa3,0x57,0x43,0x01,0x44,0x10,0xbd,0x2f,0x6c,0xd1,0x1e,0xef,0x33,0xa8,0x9b,0x3d,0x15,0xcb,0xc1,0x7c,0x7a,0x35,0x89,0x37,0xfd,0x99,0x72,0x05,0x05,0x1f,0x92,0x57,0xc2,0x56,0x09,},"\x87\x4a\x6c\x81\xd6\xdb\x71\x33\xa7\x91\x69\x76\x0c\x84\xd3\x6e\xea\x3d\x42\xea\x08\x92\xb7\xc8\xdd\xe8\x44\xa3\xa6\xb6\x0a\xa9\xf2\x66\x07\x26\xc9\xc4\xdd\x26\xa0\x1f\x4e\xd0\xdc\x1c\x53\xba\x60\x05\x46\x3f\x7e\xa6\x4a\x1e\xc6\x39\x53\xbc\x3d\x81\x05\x2a\x2f\x10\x84\x38\x9a\x77\x06\xdf\x74\xed\x41\x36\x08\x2a\xb5\xc6\xe8\xc7\xf4\x11\xdf\x9d\x3a\x0f\x3c\x40\xf5\xa6\x0e\x2d\x21\xa8\x54\x8e\x7a\x25\xde\xe3\x40\x30\xb3\xc3\xe7\x5c\xaa\x93\xdd\xaa\x9c\x19\x0c\xb6\xde\xda\x24\x13\xd5\x4e\x37\x3d\x43\x53\xdb\xa4\x3d\x39\x49\x1a\x2f\x56\xc8\xb3\x6d\x45\x01\x6f\x77\xd7\x47\x16\x91\x63\x45\x39\xe7\x6c\x4f\xb4\x19\x13\x47\x2b\x0a\x23\x05\x4f\x54\x8f\x54\xb1\xe7\x10\x9c\x8b\x65\x21\xb5\x7a\xe9\x81\xd0\x50\x31\x6a\x33\xc4\x9c\x71\x16\x26\x8d\xcc\x4b\x78\xc2\xba\xe5\x3a\x3a\xe4\xdd\x17\x8b\xb8\xb7\x6b\xb3\xbe\xfe\x19\xe4\x1a\x2c\xf1\x2c\xeb\xb7\x11\x68\xf9\x71\xf2\x02\x46\x1c\x63\xf7\xd6\xee\xf1\x07\xf5\xb1\x03\x0e\xdd\x4e\x75\x00\x9e\x91\x16\xc3\xcd\x0e\x8b\xdd\xc2\x99\xb4\x1f\x1a\x45\xe7\x84\xef\xa6\x46\xda\xda\x64\x06\x8e\x92\x48\xec\x98\x8f\x23\x26\x34\xad\x3d\x5a\xab\x19\x56\x0e\x83\x0a\x5b\xd6\x65\x45\x7c\x94\x29\x5e\x1a\xf0\x16\x0f\xbc\xe2\x72\xef\x48\x45\xdd\xf0\xc4\xf2\x4d\x97\x6f\x51\x86\x90\xea\x1f\x82\xff\x4d\xfa\x48\x13\x64\x1a\x67\x59\x8e\xa9\x84\x01\xe0\xff\x10\xa0\xe5\x82\xe2\xb9\x08\x67\xb4\xe6\x23\x2c\x34\xea\x49\x9c\x16\x99\x09\xa4\x41\x26\xf3\x77\xd8\xcc\x1c\x11\x90\x58\x66\x34\x0e\xfd\x1e\x7b\x07\x7d\xc7\x45\x6d\x59\xc9\xb9\x6a\x12\x4a\xac\x3b\x33\xbb\x22\x74\x41\xbb\x7a\x52\xe6\xc3\x14\x0d\x7a\x4f\x67\xca\x05\xbb\xc9\x3c\x93\x77\x5b\x92\x91\x19\xa2\x24\xed\x8f\x39\x00\x58\x20\xf4\x20\xcc\x6c\x53\x0e\x61\xe2\x0a\xdc\xa0\x1e\x93\x9c\xc0\x31\xdf\x49\xcd\xb1\xec\x8f\xf4\x93\xc9\xef\xbc\xad\x34\xc5\x71\x08\xef\xd7\x64\x55\x89\x66\xfb\x14\x70\xb0\x74\x5e\x69\x66\x19\x1a\x9a\x9e\x44\x58\x1b\x09\xfa\xf4\x69\xf9\x51\x53\x72\x03\xd9\x26\xbc\x8a\x55\xd0\x80\xa8\x05\x18\x1d\xd7\x29\x6e\xd2\x0a\x81\x82\x68\xf7\x55\xea\xa6\x6b\x08\x22\x42\xf4\xd0\x20\xf7\xcd\x67\x20\x89\x04\x84\xc0\x1c\x75\x7f\xe3\x5d\x87\xb5\xbc\x90\x6d\xea\xcc\x2e\x30\x71\xde\x46\x01\xbc\xf0\xdd\x6b\x83\x7c\x43\x31\x06\x04\x7f\xd8\xec\x9b\xd0\xe9\x8c\x9e\xe8\x06\xf7\xec\x8c\x5a\x10\xea\x21\x36\xf1\xf9\x0f\x90\x0b\x85\x3f\x95\x3f\x00\xb0\x76\xbd\x1e\xbd\x92\x9d\x08\xa3\x8b\xec\x68\xd8\x66\x43\x50\x47\xbc\xb6\x72\x1e\x06\xb6\x40\x85\xdc\x05\x58\xc1\xfa\x85\xa2\xc8\x3b\x0c\xaf\x4c\x81\x60\x84\xf1\x0a\x4c\x58\x85\x29\x5b\xca\x15\xff\x7c\x18\xe5\x96\xc6\x2c\x92\xee\x99\x21\xa2\x7c\x29\xd1\x95\xbd\x28\x22\x13\xff\x36\x60\xb6\xe7\x54\x6b\x4e\xaa\x77\x7c\xe3\x9f\xc5\xd2\x04\x84\xc7\x1e\xd6\xca\x06\xf9\xb7\x7a\xb1\xd8\x72\x39\x3a\xb2\xd1\x02\x55"}, +{{0xb2,0x98,0xad,0xf3,0x8a,0x67,0x08,0xf8,0xd1,0x8f,0xf1,0xed,0x96,0xbf,0xba,0xb4,0x21,0x54,0x0d,0x09,0x6c,0x4e,0x43,0x51,0xb9,0x22,0x09,0xb5,0xe6,0xaa,0xab,0x65,},{0x77,0x0e,0xdf,0x42,0xb8,0xa0,0x39,0xc6,0xca,0xb9,0xba,0x65,0xeb,0xfb,0x13,0x5a,0xbc,0x2d,0xa3,0x14,0xa4,0xc3,0x09,0xf4,0x6a,0x8f,0x32,0x5b,0x52,0xd0,0x65,0x93,},{0xe5,0x5f,0x8d,0x30,0x41,0x22,0xdc,0x17,0x5c,0xf0,0x27,0x46,0x74,0xfc,0x9d,0xed,0xfe,0xc2,0xb5,0xf8,0xa2,0xee,0xb1,0xe3,0xe7,0xf8,0xe0,0xdf,0xba,0x0d,0xac,0x2d,0x32,0xf4,0xe7,0x04,0xce,0x91,0xcd,0x59,0x91,0x84,0x13,0x3c,0x3b,0xf1,0x06,0x3d,0x2f,0xae,0x63,0xd7,0x3a,0xcc,0x57,0x72,0xd7,0x18,0xd8,0x11,0x83,0x31,0x86,0x02,},"\x9d\xf4\xd5\xd7\x56\x5d\x2c\x05\x22\x62\xdd\x34\xd6\x00\x7d\x86\xd9\xc0\xf0\x7c\x70\x89\xaf\x61\x19\xe3\x04\xf4\xd8\x01\x1d\x7e\xaa\xd7\x7b\x3e\xf7\x0c\xc2\x80\x84\x7d\x59\xf2\x97\x20\x2b\x7e\x18\x61\xae\xf3\x34\xbf\x38\xde\x14\x74\x0e\x80\x73\xc9\x55\xa8\x51\xd2\xcf\x3d\xad\xc3\xed\xce\x15\xbe\x49\x0e\xaa\x84\x5b\xa5\x53\xfc\x6e\x87\x46\xe5\x29\x15\xe6\x55\xaf\x4b\x86\xc6\x29\xd4\xc5\x22\x78\x36\x35\xd4\x64\xa2\x82\x57\x77\xd8\x9d\x70\x97\x67\x7e\xf0\xe5\xee\xae\x38\x53\x7e\xcb\x65\x6e\x3b\x28\xdd\x07\x35\x8f\xd9\xfb\x2c\xd4\x62\x51\x72\x86\x65\x9a\xef\xc7\x9d\x37\x4d\x1d\x13\xed\x93\x96\x7c\x53\x0c\xde\xa4\xf3\x14\xa0\xf9\x1d\x62\x89\xb4\xc7\xa4\x27\x9b\x6f\x4c\x4a\xbc\xa3\x33\x57\xf6\x9e\xd8\x4b\x91\x19\x63\x7a\xdb\x7c\x18\xe6\x94\xcb\x3c\x56\xe7\x36\x37\xda\x91\x07\x35\xd4\x3c\x38\xaa\x80\x86\x67\x5a\x06\xad\x37\x0e\x57\x26\x88\x1d\xa5\xe1\xa1\xdc\x61\x44\xd6\xa6\x2a\xff\x7f\xb0\xc3\x52\xd8\x8d\xc9\x71\xa3\xd7\x2d\x30\x71\xe1\x4b\x47\x42\x53\x56\xaf\x1b\x01\x92\x33\x53\x82\x61\x45\x1a\x99\xa6\xcf\x4a\x07\xce\x9a\xb1\xc3\x99\x0d\xe6\xab\x8d\xe2\x11\x6c\x75\x61\x05\xc5\x12\xb7\xa3\xee\xb3\x15\x7b\x15\x8b\x32\x1e\x44\x4e\x80\x6d\x89\x0b\x38\x90\xed\x9d\xdc\x86\x9f\x17\x11\x72\x3b\xb9\x9a\x72\xbd\xb9\x23\xd1\x31\xba\x4e\xdb\xfb\xb6\xda\xe9\x9a\x5c\x7b\x32\x8d\x31\x0d\xf9\xa6\xd1\xdc\xd8\x59\x18\x96\x28\x33\xe8\x9e\x20\xf5\xc5\xe6\x33\x3a\xc8\x61\x09\x4a\xe9\xe7\x99\xc8\x64\x1b\x9b\xae\xa1\x1a\x2e\x0e\xc2\x34\xbe\x59\x30\xe0\x28\x80\x85\x9c\xde\xc0\xd9\x78\x23\x7c\xbe\xa5\xc7\xc3\x2c\x11\x1b\xaf\xdd\x4b\xfb\xff\xe4\xfb\x34\x85\xef\xfe\xcd\x51\xbd\x19\x5a\x71\x40\x4c\xa5\xb5\x9a\xfa\x25\x2d\x7b\x5f\xf9\xd0\x30\xf4\x8c\x6f\xaa\xdb\xdb\xa9\x18\xf2\x1a\x0c\xd3\x9a\xf5\x69\x66\xdc\xcf\xa2\x5f\xb5\xa5\xcf\x9a\x4b\x26\xa7\xf5\x44\x1d\xf6\xe3\x20\xe3\x4b\x27\x39\x3d\xe2\xec\xfb\xd6\x9a\x15\x94\x90\x9a\x6c\x68\x5e\xc6\x45\xfc\xf3\x04\x8d\x01\x48\xfa\x38\xd3\xe8\xa6\x4d\xc3\xc2\x1a\xe4\x4d\xa7\xe4\x6a\x5e\xa7\x93\x6c\x2b\xa0\x83\x68\x9a\x78\xca\x3a\xc6\x0b\x87\xbe\x6d\x23\xea\x40\xf5\x96\x15\x83\x74\x28\x42\xe3\x75\x25\xa4\x9c\x5f\xe8\xfd\x15\xd7\xb0\xc9\xe8\xfc\xcd\x07\x93\x6d\x19\x53\x82\x12\xf7\x37\x3d\xbb\xf3\xdf\x7d\x46\xad\xf9\xd9\xf5\xdb\x09\x52\x4c\x65\xb8\x83\xae\x6f\x6c\xef\xa2\x4b\x19\xec\x48\xce\x28\xcf\xa7\x34\xd9\xbd\x6e\x77\x83\x7d\x1a\x14\xd6\xa1\x9d\x34\x5b\xfb\xea\x55\x9e\x7e\x6b\xfb\x71\xdd\xad\x83\xcd\x8d\xee\xab\x68\x7f\xe7\x3c\x05\x74\x88\xf8\xf2\xb3\xe2\xe2\x6d\x13\x00\x9f\x4d\x23\xe6\x61\x9a\x23\xc0\x69\x2a\xf7\x66\x69\x21\x7d\x5e\xbd\x46\x08\x5b\x39\x88\x90\xe5\xc9\x1f\xdb\x4d\xb5\xba\x40\xe7\x77\x3d\x51\x8d\x3c\xf0\x0c\x0a\x5b\x5a\x4b\x0f\x1b\x85\xd6\x29\x16\xa5\x9e\x56\x07\xb7\xb1\xeb\x80"}, +{{0xe9,0xcf,0x16,0xd6,0x96,0xf6,0x3b,0x59,0xe5,0xe2,0x5c,0x9e,0xe2,0xd7,0x5b,0xb0,0x5e,0xd2,0xba,0xa5,0x91,0xa7,0x55,0x7f,0x9f,0xb1,0x29,0xcf,0x98,0x3d,0xe0,0xba,},{0x6d,0x1a,0xe3,0x85,0xe8,0x0a,0x39,0x55,0xe8,0xd0,0xc5,0x93,0xa8,0x1f,0x43,0x1c,0xd4,0x32,0x67,0x1e,0x78,0xcd,0xba,0xfe,0x83,0xfe,0x58,0xdb,0xcd,0xb9,0x85,0x60,},{0x81,0x12,0xac,0x37,0xea,0xfb,0x74,0x9d,0x3f,0x4a,0x1e,0xa1,0x48,0x43,0x79,0xdf,0x3e,0x38,0x3b,0x01,0x9c,0x12,0xde,0x85,0x15,0xe3,0x49,0xe4,0xf6,0xf9,0x98,0x63,0x2e,0x30,0x96,0x83,0x47,0xa1,0xd1,0x5b,0x09,0xda,0x2e,0xb8,0x00,0xb0,0x3d,0x81,0x9d,0x20,0x2b,0xd1,0x0a,0x6a,0x46,0x3b,0xb0,0x2b,0x36,0x6d,0x68,0x55,0xfe,0x0e,},"\xa1\x0f\xea\x8f\xc9\x3e\xcc\xfe\x2a\x6b\x78\x26\x07\x95\x63\xad\xf8\xaa\x9a\x66\x64\x44\x93\x22\x00\xcc\xa9\x44\x7d\xd0\x27\xc5\xc7\x20\x4e\xa6\x2b\xf8\xf5\xe2\xe3\x91\x45\xac\x39\x48\xab\x3f\x31\x86\x88\x7b\x30\xbc\x60\x23\x30\x24\xb4\x83\xf3\xf5\x19\x03\x6a\x3e\x94\xc8\xd7\x51\x0a\x85\x3a\xc6\xe2\x0c\x6e\x52\x6e\xe3\xcd\xb7\x6d\xe6\x63\xf6\x73\x05\xad\x80\xdf\x23\x42\xc8\x50\x1b\x4f\x4a\x8e\xe3\x66\x5a\x79\x8f\xc4\x37\xdd\x81\x4e\x4e\x47\xe7\xa4\x66\x89\x0e\x0f\xfa\x8f\x51\x0f\x3e\x6e\x19\xc9\xc9\x69\xf7\x0a\x76\xe5\xcf\x30\x54\xd1\x7d\xe4\x59\xac\x8e\xe9\x95\x50\xbd\x38\x31\x9f\x36\xe4\x33\x43\x4a\x92\x6a\xd6\x8b\x96\x1e\x0c\xa1\x0a\xdd\x4b\xa9\x92\xb3\x65\x06\x60\xa2\xc3\xc2\x6f\x5d\x74\x0a\x31\xaf\xb7\x76\x3f\x54\x2f\x72\x3b\x8a\x3c\x92\xd8\xae\x92\xa5\x67\x76\x4e\xfc\x70\x53\x03\x12\xba\xab\xdd\x3f\xbb\xd5\x27\xfe\x0f\xcb\xca\x3f\x6a\x70\x64\xcd\xde\x18\x56\xe9\x7a\xb7\x86\xaf\x7d\x70\x22\xa9\xd4\x6a\x33\x8e\x8e\x17\x54\xaf\xd9\xad\xac\x85\x6a\x38\xde\x2a\x4c\x97\x66\xde\xe8\xdb\xc7\x09\xb0\x67\x1a\x6a\x6e\x6e\x1e\x5d\x12\x07\x4d\x22\x24\x5c\xd7\x3b\xee\xeb\x1b\xd8\xec\xfc\x1e\x85\xa2\x1b\xde\x25\x3f\x7c\x46\x5a\xbc\x1f\xea\xa9\x61\xc0\xff\x5c\xff\x2d\x89\x64\x72\xae\x17\xab\x84\x88\xe3\x3f\xfe\xfd\xb7\x2c\x10\x5e\x20\x4f\x94\x4a\xda\x51\xee\x13\x98\x1a\x13\x6c\x0f\x38\x42\x6e\x3e\x49\xb0\xe9\x18\x41\xc3\x27\x94\xd5\x2f\x13\x35\xdf\xa6\x37\xf1\x51\xc7\xe4\x0f\x9b\x83\x0a\xed\x53\x9a\xc5\x73\x1b\x81\xcd\xe3\x26\x4d\x22\xbe\xad\x31\xa6\xcc\x68\xd1\xa7\x31\x43\xb5\xba\x48\x16\x13\x92\x32\xf3\xf7\xf9\x79\x83\xf4\xec\xba\x64\xc4\x95\x53\xbe\x9d\x6d\x94\x3f\x91\xdf\xe0\x3d\x1e\xe8\x61\x8c\xd4\x0d\x2f\xb7\x23\x8a\x31\xd1\xbc\x38\xe7\x6a\x55\x1f\x9e\xee\x22\xe7\x3a\x27\xd7\xa4\x8b\x40\x87\x72\xea\x72\xc3\xed\x63\x7b\xb4\xb1\x68\xf9\xd7\xae\xad\x94\xea\x03\xbc\x11\x10\x99\x01\xc8\x89\x92\x7d\x51\xcd\xac\xf9\x62\x12\x59\x62\x55\x99\x79\xd3\xe4\xc8\xe3\xb5\xae\x58\x2f\x2d\xba\xd4\x99\x88\x02\x85\x6c\x4d\xf6\x9e\x8f\xb5\x49\x17\xe2\xf3\x6b\xb6\x7a\x19\xa2\x6e\x9a\x9a\x94\x85\xbc\xe9\x8d\xbf\xff\x0d\x2b\x02\xb9\x37\x7a\x91\x37\xa7\x34\xe5\x7b\x5c\xe6\x65\x05\x30\x17\xe9\x92\x67\x7a\x1a\xa0\x79\x24\x0d\x2c\xf9\x63\xcd\xf9\xbf\xea\x8d\x46\x00\x91\x23\x2d\xaf\x89\x80\x1f\xd7\x51\x71\xa6\x19\x5a\x5c\x04\x68\x15\x91\x4b\xe1\xf6\x28\x68\x78\x3d\x6f\x2c\xf2\x8a\xf9\x37\x8d\x6c\x68\x93\xe7\x5d\xe6\x41\x11\x1c\x68\x47\x27\xef\xfa\x31\xb8\xbc\x9b\x0a\x01\xdb\x9c\x9e\x81\xcc\xd8\xf4\xd4\xe8\x75\xd4\xbd\x90\xd2\x53\xf5\x89\x89\xa8\xa5\x2a\x20\x3a\x77\xa4\x96\xd6\x97\x98\x6b\x03\x1e\x9f\x69\x9b\xc6\xa1\x6c\xd5\xf9\xc3\x60\x18\xeb\xda\xa3\x6b\xad\x0e\x01\x4f\x4c\xf3\xb4\xb7\x46\x17\x1b\xf8\x93\x14\xe8\xb7\x2c\xbd\x47\xcc\x61\x6a"}, +{{0x23,0x8a,0x6d,0x49,0x79,0x32,0x1a,0x14,0xa9,0x97,0x23,0x6f,0x45,0x85,0x04,0x6c,0xf7,0xa0,0x5c,0x0a,0xdc,0x6b,0xa1,0xfd,0xb1,0x9e,0xc2,0xa3,0x2f,0x62,0xbe,0xeb,},{0x0b,0x4b,0xa6,0x74,0xe4,0x01,0x66,0x5b,0x67,0x90,0xcf,0xda,0x08,0x07,0x04,0xcd,0x90,0xe2,0xf3,0xd3,0xef,0xab,0x25,0x3e,0xd8,0xdc,0xfb,0xd1,0x8e,0x40,0x67,0x89,},{0x29,0x42,0xf7,0x08,0xc0,0xed,0xe4,0xcb,0x0d,0xde,0xf1,0x3b,0x85,0xd7,0x1d,0x72,0x13,0xe0,0x38,0x3d,0xd2,0x94,0xf5,0x34,0x13,0x5f,0xd6,0x9c,0xaf,0xbc,0xfc,0x0e,0x33,0x09,0x0a,0x2a,0x0c,0xa3,0xfa,0x57,0x2c,0x72,0xcd,0xf5,0x59,0x2d,0xe9,0x03,0xb1,0x58,0x44,0x95,0xab,0x63,0x99,0x81,0x50,0xf2,0xb3,0x93,0xa3,0xb3,0x40,0x0c,},"\x97\xcd\x61\x9a\x22\x51\xed\xa9\x16\x64\x64\x31\xd4\xcd\x15\x98\xc2\xd4\x4d\x06\xaf\x3e\x48\xbd\x18\xe3\xde\x7f\xb4\xbd\x4f\x78\xe0\x0a\x69\xee\xab\xde\x3f\x82\x06\x5c\xfe\xe6\xcd\x71\x1f\x07\xd2\x26\x37\x16\x1f\xf6\x85\xf6\x5a\x7d\xdf\x54\x55\x31\x97\xfd\x31\xc5\xc6\xb7\x1d\x9e\x36\x5a\x94\x1d\xce\x4c\x3e\x22\x5d\x19\xcc\x63\x3a\x7e\x12\x86\x2c\xd2\x3e\xbb\x7c\x74\xa7\x04\x85\x0f\x76\x1a\xc0\x24\x1b\xe5\x17\xce\x7c\x36\x09\x36\xce\x07\x25\x0d\x9f\x2e\xb2\x78\x71\x15\xee\xc3\x77\xe1\x13\x4d\xc0\x8f\x44\xeb\x0a\x2a\x2a\x27\x16\xf0\x01\x44\xa4\x9f\x01\x2a\x57\xb3\xcd\x06\xef\xeb\x3f\xae\x92\x0f\x28\x5c\xff\xd9\xa4\x01\xa0\xb9\x86\x59\x4e\x17\xb2\xc9\xc8\xfd\xab\x83\x5d\x9f\x3f\x5d\x47\x4b\xe7\x33\xc1\x92\x5e\xe6\xf0\x93\x86\x71\x10\x66\xc3\xfc\xd6\x45\xee\xb0\xfb\xe7\x05\x41\x69\xeb\x70\x9d\x4a\x3f\x0d\x16\xf2\x8a\x1f\xf5\x06\x6c\x84\x2b\xc6\x3e\x35\x9e\x92\x48\x5b\x38\x75\x7f\xf4\x6c\x27\xf7\x9d\x0c\xdc\xf0\xe1\x6e\x97\xe3\xc7\xb7\xe2\x17\x8d\xff\xd2\x70\x28\x2d\xd6\x12\x05\xd5\x85\x4d\x84\x1f\x0e\x3f\xc0\xe4\x82\xcc\x1e\xe4\x85\x52\xcf\xe6\x58\x93\x5b\x54\x27\xc3\x66\x23\x0a\xef\x79\xae\xf4\x02\x1d\x6f\xab\x5f\x18\x75\xcc\x84\x9e\x32\x1a\x75\x50\x0e\x9e\x1b\xa5\xdd\x59\x6b\x43\x8c\xf8\x8b\x23\x5b\x01\xa6\x76\x25\xc4\xbf\x84\xd0\x72\x4a\xe6\x88\x0a\x37\x85\xe3\x3b\xd9\x23\x5f\xd0\xf5\x98\x18\x04\xd2\x1c\xbd\x63\x3c\xb1\x80\xf3\x44\x56\x46\x02\x07\xa2\x90\xa2\x54\xd9\xfe\x61\x06\x3d\x40\x63\x4c\xa3\x87\x2f\x09\x35\xfa\x28\x32\x87\x95\xca\x41\xb0\x06\xa2\x11\x1f\xc5\x93\x2b\x1e\x77\x9c\xe9\x66\xcc\x47\xad\xb7\xc0\xdd\x98\x73\x33\xba\x75\x29\xa1\xa4\x99\x6c\xe9\xf5\x6e\x05\x19\x81\xfe\x1f\x55\x3e\x57\x8f\x43\xc3\xba\x94\xbe\xac\xc9\x3c\x3e\x73\x96\x67\xc7\xa7\xc6\xfa\x27\xe1\xe0\x81\x69\x5d\x20\xba\x70\x5c\x3f\x10\xb2\x0d\xf5\x30\xcb\xb0\xec\xb8\x74\x56\x50\x11\x09\x68\x70\x19\x31\x84\x52\x78\x5d\x38\xe7\x66\xb3\xcd\x35\xb0\x07\xd7\xe3\xcf\xe0\xb2\xcc\xa8\xaa\x6e\xf7\x39\x55\x99\xdc\xb9\xc4\xd2\x8b\xcc\x35\xc7\x6d\xfc\x35\x34\x3c\xb1\x34\x8b\xa3\xe9\x62\xf1\x0e\xe8\x6f\x86\xf5\xb6\xd4\xca\xe2\xe8\xc2\xb1\x85\xe3\xea\xa1\xae\xb8\x7b\xcf\xcf\x2f\xb7\x6c\xc7\xfc\xc6\x89\x50\x71\xb1\x68\xe8\xb7\xf6\xca\xa0\xfd\x63\x98\xe7\x78\xcc\x07\x91\x2f\xf5\xd6\xe6\x10\x21\xa8\xa5\x9a\xe0\x35\x21\x60\xf5\x6d\x54\x88\xfe\x2f\x2a\xcc\x94\x03\xda\x9a\x9f\xfc\x66\x1c\x1e\x9d\xc5\xbe\x88\xc4\x20\xdb\x0f\xd7\x7d\x84\x5d\xc8\xdd\x9d\x8e\x58\xf9\x96\x1b\x79\xaf\xc6\x86\x24\xba\xa8\x6a\xa6\x43\xa8\xa3\xc7\xed\xf7\x1d\x55\x3c\xc0\xd3\x22\x4a\x60\x69\xec\x67\x4f\x52\xda\x29\xa1\xcb\x60\xc4\x19\x23\x01\xa2\x43\x47\xa8\xaa\x83\x26\x26\x9e\x0a\x14\x78\x0c\x95\x83\xcd\xff\x51\x59\x27\xfd\x5b\xef\x52\x8f\x9d\x23\x78\x7a\xeb\x80\x3d\x70\xeb\x91\x6b"}, +{{0x59,0xd5,0x01,0x39,0x3d,0xc5,0x99,0x97,0x23,0x81,0x07,0x06,0xfa,0xd7,0xd6,0xef,0xd1,0x63,0xc4,0x47,0x10,0xc7,0x41,0xc1,0x85,0xc2,0x7e,0x04,0x25,0xe3,0xc0,0x5b,},{0x82,0x65,0xd4,0x3c,0xfb,0x07,0x35,0xb5,0xd7,0x25,0x0f,0xcf,0x0f,0xcb,0xd1,0x54,0xbf,0xc0,0xee,0xcb,0x13,0xb7,0xad,0x93,0xb6,0xb0,0x29,0x40,0x58,0x8b,0x84,0x3b,},{0xe6,0x46,0xf1,0x64,0xcf,0xed,0x8c,0x2e,0x06,0x07,0x10,0xdc,0xfb,0xc3,0xe9,0xfa,0x5e,0xb3,0x96,0x37,0x68,0x13,0x19,0x01,0x84,0xe3,0x46,0xf5,0x2b,0xb0,0xba,0x57,0x46,0xcc,0xb6,0xb5,0x95,0x22,0xb1,0xaf,0xf9,0x83,0x0f,0x2f,0x98,0xb9,0xe5,0xda,0xfc,0xd8,0x32,0x07,0x78,0x83,0xc4,0x4e,0x8a,0x35,0x38,0x8f,0x71,0x8b,0xf4,0x0c,},"\x56\x4e\xd2\x2c\x17\x2f\x5c\x3a\xfb\xb0\xb9\x5a\xd2\xfc\x64\xe4\xbe\x6d\x4d\xb1\xeb\xb8\xd3\x99\xc4\x3a\x5e\x16\x04\x8e\x7f\x87\x32\x18\x1e\x5d\x0e\xed\x8e\x63\x8e\xf2\xa5\x5a\xa0\xd7\xb6\x81\xfe\x02\xbb\x54\x23\xaf\x94\xbd\x35\x2d\x3c\x2d\xde\xc0\xf8\x47\x60\xa4\x11\x2b\x4f\xe0\x17\xcf\xbc\x50\x2f\x95\x43\xcf\xa4\x1f\xb2\xaa\xe7\x5a\x3a\x08\x1f\x8c\x49\x90\x33\xd1\xfa\xe5\xd9\xc5\x0c\xb4\x4d\xbc\x63\x60\x5a\x54\x39\x8f\xbf\x07\x98\x52\xeb\xa8\x6f\x2f\xdf\xc2\x72\xd0\xc4\x17\x9d\x7c\x13\xcb\xc1\xc2\xa3\xda\x0b\x82\x84\x5c\xf1\xa4\x6e\xbb\xe3\x1e\x79\xb6\x00\x97\x33\xc7\xbf\xe7\xaa\x4f\x9f\xfd\x71\x9c\x77\xdc\x7d\x74\x8e\x49\x2e\x14\xee\x5e\x41\x79\xbf\xa9\xe6\x49\xcf\x0d\x89\x53\x41\x86\x38\x5e\xe9\x94\x10\x05\x1d\x66\x56\xe6\x23\x43\x8c\xc7\xb2\xe7\x07\xe4\x8c\x84\x91\x55\x49\xae\x8d\x67\xa3\x06\xc6\x7b\x10\x6b\x7a\x25\xf4\x5f\x8e\x10\xdd\x7d\xd3\xea\xac\x31\xf1\x05\x22\x57\xeb\x6a\x75\x76\xb6\x85\xcb\x9e\x6c\x1c\xd0\xd7\x3c\x7a\x3c\xed\x5a\x8d\xd2\x73\x08\xae\x00\xf9\x5e\xab\xda\xe9\xd1\xc4\xaa\x89\x34\xe2\x42\x4c\x93\x28\xa5\x22\x8f\x4f\x82\xdd\x4a\x66\x55\x6d\x82\x17\xc5\xa2\x2b\x2b\xeb\x86\xa2\xa4\x34\x13\xee\x5e\x10\xf8\x83\xf2\xcd\x6c\x2e\x87\x49\xb5\x50\x88\x42\xec\xae\x5f\xfc\xcb\x79\x6d\x96\x33\xe8\x7e\xf4\xa9\x6c\x0d\xf7\xef\x47\xb2\x83\xd0\x96\x72\x3b\xa3\x13\x5b\xad\x75\xb2\xe1\x9e\xc0\x4f\x70\xa4\x78\x42\x8a\xd5\xd0\xaa\xc0\xdd\x2a\xb9\x90\x59\x13\xe7\xe5\xad\xe4\x08\x80\x1d\x5d\x3c\x54\xd9\xcf\x7b\x8f\x0f\x0c\x5e\xb0\x54\xc1\x47\x5c\xc2\x10\xa2\xc7\x98\xd8\xbd\x89\x93\x2f\xf9\xf3\x60\x42\x18\x58\x05\x3a\x70\x7b\x8b\xbd\x32\x05\x5c\x44\xb2\x07\x12\xa2\x67\x8a\x9a\x6a\xf9\xe3\x6d\x04\xdc\xff\x44\xf4\x31\xcf\x19\x30\xcd\x18\xfc\x93\x5d\x22\x67\x77\x5c\x69\x09\x67\x25\xed\x89\xa2\x91\xdd\x60\xe2\x1a\xc0\xb0\x12\x87\x34\x07\x29\x92\x82\x3e\xf8\x7b\x5e\xfa\x6c\xc5\xb0\x50\x17\x7f\x55\xf4\xce\xc9\x2a\x08\xa6\x5b\xca\xdc\xab\x9a\x41\xc3\x60\x86\x37\x0b\x7b\x9d\xd6\x29\x8a\xc7\xb0\xae\x6a\x09\xc9\x71\x0a\xbb\x46\x76\xa8\xfc\x87\xa3\x65\x12\x90\x14\x4b\x6b\x30\xef\x4f\x6f\xbe\x5b\x9a\xd2\x52\x37\xfe\x06\x05\xe3\xb9\xf1\x8a\x77\x18\xac\x9f\xca\x6f\x32\x5e\xa5\x5f\x49\xa8\x07\xfb\x80\xa2\x40\x2a\xe1\x34\x23\x08\x0d\x32\x77\x58\x64\x90\x23\x79\x8d\x57\x28\xe0\xdc\x64\xac\x88\xa6\xe2\x94\x5d\xbb\x3e\x3f\xfa\x9f\xdb\x4c\x7b\x58\xfb\xa3\xf5\xfb\xd6\x7c\x68\x6b\x29\x71\xbb\xd8\xba\x4d\x27\x5d\x57\x3e\xb7\x96\xeb\x91\x46\x77\x5d\x8c\xdc\xd5\xfd\x3e\xb5\xa8\x8e\xa5\xa9\x30\xec\x32\x44\xe6\xa3\x7c\x81\xf6\xa2\x55\x4e\x5b\xa7\x87\xf0\xe4\x53\x19\xfe\x4b\x8a\x2f\xfb\xfe\xd5\x07\x70\xe7\x82\x7b\x3e\x7b\xc2\xb4\x4c\xe5\x12\xae\x60\x51\xb6\xf9\xf1\x39\x31\xea\x6a\xcc\x09\x6b\x8d\xcb\x01\x96\xbe\x42\x24\x84\xdb\x5f\xcb\x29\x9d"}, +{{0x83,0x9f,0xb1,0x32,0xe6,0x92,0x50,0xca,0x1a,0xd9,0x45,0x10,0x08,0x7f,0x92,0xce,0x06,0x87,0x69,0x21,0x3a,0x19,0xb2,0xa6,0xc8,0x94,0x90,0xf1,0xf5,0x78,0x80,0x7a,},{0xeb,0x58,0x66,0x19,0xb4,0x4a,0x15,0x37,0x9a,0xcc,0x46,0x21,0xa2,0xac,0x71,0xea,0x58,0x97,0x00,0x26,0xc2,0x8e,0x24,0x09,0xfc,0x1b,0xa2,0xbd,0x8b,0x23,0x6d,0x1d,},{0x66,0x43,0x7b,0x6b,0xc0,0x5e,0x75,0xdd,0x16,0x26,0xc3,0xc4,0xff,0x1f,0x72,0xe6,0xdb,0x38,0x1b,0xa1,0x59,0x09,0x48,0xf8,0xf1,0x6a,0xd4,0xd6,0x6e,0x59,0x91,0x65,0x9a,0xa8,0x44,0x05,0x56,0x8c,0xfb,0xc0,0xa7,0x7c,0x02,0x5e,0x59,0xe4,0x3f,0xd5,0x3a,0xb9,0xff,0xab,0xba,0x7b,0x25,0x8f,0x78,0x79,0x62,0x39,0xf9,0x0d,0x45,0x01,},"\xc5\x72\x32\xfe\x32\xf1\x1e\x89\x4b\x43\x7d\x40\x45\x62\x07\xcc\x30\x6d\xb4\x81\x69\xb2\x0e\x07\x81\x10\x3a\xff\xe8\x02\xf5\xaa\xbe\x85\x82\x95\x2c\xa8\xe9\x57\x45\xe9\x94\x0d\x53\x5e\x00\xff\x65\xab\x3c\x64\xbe\xd3\xd1\x17\x3a\x0f\x3d\x70\xce\x4e\xbe\x2b\x50\xd0\x48\xbb\x47\x16\x4d\x2a\x2c\xd9\xd9\x5a\x10\xcf\x0d\x07\x3e\xd1\xc4\x1b\x3d\xe3\x33\x52\x8e\xe3\x29\x68\x22\x3a\x0d\x84\x7c\xad\xbb\x5b\x69\xf3\x82\x16\x4e\x9a\x28\xd2\x3e\xc9\xbd\xe9\xa8\x28\xe8\x77\x1c\x9e\xb4\x92\x20\xaf\x54\x18\x55\x08\xaa\x07\x3a\x83\x91\x95\xf1\x03\xbc\x2f\x32\xfe\x04\xf9\x51\xca\x45\xbf\xbf\x30\xd2\xfb\x81\x14\x05\x6a\x73\x6a\xdd\xf2\x7e\xcd\x9a\xf0\xf6\xe5\xe9\x7e\x57\x73\xc4\xfa\x90\x22\x68\xc3\x2a\x15\x14\x10\x95\x5f\x3c\x76\xaa\xe2\x55\x54\x9e\x0f\x03\x3f\x89\xe1\xa7\x8f\x26\x5c\xba\xb6\xbe\xb7\x51\x6d\x4b\xad\xc4\x9c\xda\x45\x88\x31\x62\x25\xb4\xc8\x5e\xa9\xfa\x99\xc7\xd6\x76\x6e\x94\x90\xc4\x9d\xe5\x9d\xa7\x17\xf6\x67\x65\x35\x30\x07\x1d\xd2\xf0\xc5\x3e\x31\xd8\x76\x81\x56\xfe\xb0\x8f\xaf\x00\xdb\x0a\x04\x53\x3d\xf9\x79\x57\xa8\x4a\xa4\x6a\xeb\x7e\x36\xc0\xb0\xbe\x69\x01\x89\x46\xf1\x53\x8a\x6a\xea\x71\xdf\x53\x6f\x14\x42\xc2\x44\x4a\x43\xa0\x43\xd0\x46\xab\xde\x1a\x78\x2b\x0f\x4f\x5c\x6a\xa7\x20\xaa\x60\xaf\xed\x94\x7c\x0c\xee\x47\x7d\xbe\xc0\x05\x57\xb3\x72\x12\xd9\x33\x57\xca\x2b\x6b\x6f\x82\x71\x5b\xa0\xe4\x84\xf6\xda\xf2\xd0\xb7\xa9\x8c\x03\x35\x19\xce\x38\x26\x35\x86\x79\x6d\x5d\x31\xcb\x2b\xc3\xd1\x12\x5b\xc0\xcc\xd3\x29\xa5\xc2\x1f\xd2\x7a\x21\x8d\xed\x60\x7a\x0e\x75\x15\xb5\x71\xf1\x92\xc3\x3f\x5f\xba\x51\x4a\xfe\x4d\x45\x81\x00\xf3\xcc\xba\x3f\x38\xeb\x43\x0b\x4f\xc8\x8f\xae\xf9\x99\xfa\x71\xee\xe4\x88\x22\x89\x03\xbe\x29\xf2\x4d\xf8\x1d\xc9\x11\x04\x4e\x92\x4c\xda\xa0\x17\xcc\x7d\x87\xe5\x6a\x6c\xba\x87\x60\x85\x9b\xd6\x3d\xd2\xd4\xf5\x81\xb9\x55\xec\x92\x4a\x49\xaf\xb4\x7c\xa0\xd6\x3e\x78\x26\xfd\xc7\x12\xb4\x94\x3b\x73\x9e\x18\x57\x75\x5a\x33\xc6\x50\x36\x75\xfd\xde\xae\x06\x27\x06\xe3\x4f\x74\x4f\xd9\x32\x64\x8a\x56\x08\xce\x60\x8a\x61\x99\x57\x83\xf3\x33\x9c\xa3\xfe\x10\x7e\x19\x72\x74\x4b\xf6\xd4\xed\xaf\xbf\x47\xce\x02\x1e\x05\x82\x1f\xb1\x24\xc7\x08\x39\x30\xe6\x8e\x6f\x5c\x32\xd2\xd9\xfc\x4a\x88\x4c\x0b\xc8\x84\x04\xe4\xcf\xe3\xc1\xa2\x42\x0d\x41\x82\x3a\x38\x5f\xb3\x28\x8d\xb6\x5c\x89\x54\x5f\x6e\x73\xf0\xd8\x00\x4b\x2b\xa1\x2a\x4e\x07\x72\x75\x23\xef\x08\x56\x70\xda\xff\xaf\x41\xc2\x8a\x4c\x11\x57\xbd\xd2\x45\xe6\x87\x50\xdd\x20\x0e\x02\x3a\xf9\x0c\x67\x56\x1e\x0f\xe4\xba\x34\x0c\x43\x3f\x75\x5e\xef\xab\xd4\xb0\x39\xbf\xc3\x23\xdc\x11\xad\xb7\x5a\xec\xc4\x48\xa8\x69\xc7\xf2\xa5\x8b\x9d\x86\x17\xc6\x4b\x8f\x89\xfc\x58\x3f\x8c\x94\x8e\x2d\xf0\x25\x1a\x6c\x7d\x8c\x73\x8c\x3b\x5a\x42\xb7\x49\xad\x5e\x8e\x98\x6b\xd8"}, +{{0xad,0xc1,0xe5,0x6c,0x3a,0xc9,0x4e,0x6c,0xda,0x04,0x11,0xcb,0xc3,0xce,0x2a,0xf1,0x28,0xd1,0x85,0xa2,0xa2,0x73,0xbd,0xb2,0xaf,0x8d,0x7e,0x50,0xfb,0x96,0xb5,0x26,},{0x5d,0xcf,0xec,0x1f,0x91,0x12,0x75,0x15,0x64,0xec,0xb6,0x07,0x15,0xeb,0xb2,0xc5,0x17,0xb5,0xec,0x37,0xb2,0x53,0x4f,0xd6,0x32,0x99,0x24,0x42,0x9b,0x7f,0xd5,0xc5,},{0xf0,0x2e,0x5d,0xbc,0xb6,0x87,0x04,0xaf,0xad,0x03,0xac,0xa8,0x10,0x61,0xdb,0xdb,0x99,0x85,0x70,0x04,0x9f,0x10,0xce,0x65,0x0e,0xc7,0xa2,0xef,0xf1,0x5c,0x79,0x3d,0xdf,0x5a,0x27,0x2c,0xb6,0x83,0xc2,0x2c,0x87,0x25,0x7c,0x59,0xbd,0xef,0x39,0xef,0xea,0x79,0xbd,0x67,0x95,0x56,0xea,0x15,0x05,0xed,0x00,0x36,0xcb,0x46,0x04,0x0c,},"\xd4\xf9\x59\x47\x4e\x0b\x89\xe2\xdc\xd0\x20\x66\x98\x4f\x88\xd7\x39\xdd\x11\x34\xa3\x33\x09\xf0\xa8\xb7\x80\x2e\xaf\x01\x33\x03\xc1\x35\x15\xdf\xeb\x46\x1e\xa3\xd2\x48\xe9\x98\xb9\xa4\xe5\x4d\xae\x5b\x00\x19\x0a\x45\xe7\x0d\xc6\x7e\x98\xf3\xd4\xcf\x90\x6c\x21\x4d\x4f\x63\x6d\x29\x52\x92\x5e\x22\xb1\xa8\x6a\x1a\xab\xb3\xa8\x92\xa9\xf8\xed\x45\x4f\x39\xc6\x3d\x35\xb7\x1e\x87\xa2\xda\x55\xa8\xe1\x67\xac\x83\xa8\x66\xad\x16\x7a\x17\xae\xd1\x83\xc0\x85\x18\xc1\x5e\x6b\xe3\x48\x58\xb4\xce\xe2\xb8\x42\x73\x14\x76\x0f\xff\xdd\xd5\x92\x38\x54\xb1\x74\x7f\x79\x6e\x1a\x52\x49\xfb\x30\x44\x89\x4e\xd6\x46\x82\x9f\x65\x43\x16\xee\x52\xf4\x01\x0c\x8d\xd3\x21\xfa\x1d\xec\x39\x7e\x50\x14\x5e\xd9\xe3\x16\x86\xfd\x52\x03\xf7\x23\x3b\x8d\xa7\x80\xac\xaa\x91\xee\x0b\x5b\x47\x20\x78\x66\xaa\xd8\x5f\x83\x7e\x03\xb4\xe6\xf6\xde\x8c\x04\xac\xaf\xd7\x07\xbd\xc1\xdd\x45\x50\x0a\xb5\x64\x80\x1b\xee\x9a\x58\xec\xe3\x60\xd0\x04\x82\x8b\xaa\xf5\x23\xe2\xf5\xab\x69\x32\x6a\x03\xaa\xbe\x01\x08\x78\xfd\x43\xff\xaa\x56\x87\x22\x44\xd7\x68\x1f\x16\x18\xe6\x23\xe3\xd4\x74\xc7\x3a\xf8\xb0\x80\xa6\x18\x21\xa5\x74\xef\x2f\xd7\x52\xd2\x3b\x60\x5e\xc5\x21\xc1\x9c\x15\x50\xde\x98\x0c\x09\x4d\x05\xe0\x23\x8f\x3e\x00\x8e\x6b\x19\x5a\xbf\xdd\x40\x28\xee\x1e\xe1\xd6\xc6\x6a\x76\xf1\x78\xf0\xb4\x31\xe4\xaf\x44\xdd\xcc\xfc\x52\x90\xed\xff\x36\xec\xe6\x3e\x83\x85\x56\x70\x13\xf4\x3a\x2a\xeb\xb6\x7e\x3e\xf4\x06\x30\x8c\x20\x48\x8a\x76\xd5\x8a\x21\x4f\x31\x39\xd9\x83\xb1\x9a\xfb\x12\xe3\x28\x36\x07\xfd\x75\x10\x7b\xd3\x1f\xeb\x62\x56\x17\x4b\x7a\x18\xae\xca\xc9\xf8\x56\x25\x82\x01\x8b\x0e\x6d\xe4\x05\x35\xe3\x5b\xef\x2b\x56\x25\x53\x88\x51\x29\x39\x75\x62\x90\x0d\x34\x17\xf9\x8c\xdd\x1e\x29\xd7\x31\xff\x48\x93\x3f\x29\x52\x95\x81\x63\xba\x67\xd5\x95\x61\x81\x1b\x83\x77\x2b\xd0\x57\x10\xb6\xe3\xcc\x04\x34\x60\x99\x37\x50\x72\x23\xab\xb7\x1a\x6a\x8c\x83\x8f\xec\xdb\x1d\x2d\x37\xc9\x5d\xc8\x06\xf6\x5f\x3f\x96\x63\xd9\x9f\x06\xe6\xc0\xf3\xc3\x2e\x95\xaf\x1d\xd7\x08\xe8\x11\x08\x63\x6a\x26\xb9\x68\xe9\x83\x39\xc7\x41\x28\xb6\xcf\x67\x13\x35\x88\x4a\xc7\x2f\x75\xb6\x37\x19\x5e\xa9\xec\xa0\x53\x60\x89\x96\xc3\x2e\xd4\x45\x41\x0f\x67\xfa\x10\x4b\x39\xf0\xfd\xf3\xc9\xb5\xc6\x15\x7b\x76\x80\x37\x56\xb2\x7f\x4c\x3b\xa1\xb4\x7f\x32\x85\x76\x24\x8e\x9b\xc5\x3e\x7b\x8a\xb0\xb2\xed\x97\xc2\xf9\x99\x8b\xcc\x7d\xfe\x39\xe2\x64\xaa\xd3\x0c\x6c\xfe\xf2\xb5\x55\x3f\xfb\x5a\x69\x9a\xa4\xbd\x0e\xab\xe4\x38\xce\x05\x22\xcc\x91\xfe\x4e\x72\xbf\x7e\xac\xba\x47\x71\xcc\xf6\x3a\x37\xaa\xfc\xad\xbf\xbf\x99\xdd\x76\xb8\x5b\x80\xee\x07\x5d\x3a\x7d\x1a\x90\xa5\x5b\x77\x29\xa5\x41\x6e\x5b\xe6\x96\xbf\x9f\xb7\xf3\x15\x8c\xfd\xb5\xcf\xda\xcd\xde\x81\x72\xee\x1a\xb9\x48\x6e\x24\xcc\xea\xd2\x9b\x45\x7a\xcf\x43"}, +{{0xdb,0x89,0xdf,0x6a,0x23,0xd8,0x90,0xb7,0xf0,0x02,0x60,0xe8,0x1f,0x4a,0xd9,0x8f,0xd0,0x94,0x40,0x36,0x51,0x31,0xe8,0x5e,0x22,0xc7,0x95,0x1a,0x18,0x7b,0x02,0x18,},{0xc9,0x67,0x63,0x67,0x2e,0xe4,0xa2,0xcc,0x5a,0x93,0xb6,0xa6,0x83,0xdf,0x9b,0x5d,0xe4,0xd9,0x38,0x6a,0x79,0x08,0x35,0x68,0x1d,0x12,0x17,0xd1,0x92,0x96,0xbd,0xc8,},{0x80,0xb7,0xfc,0x8b,0x6a,0xe6,0xee,0xce,0x81,0x66,0xb7,0xea,0x53,0x4c,0xb5,0xb2,0x14,0xc9,0xea,0x99,0x73,0x92,0x1e,0xd0,0x5d,0xe4,0x0c,0x78,0xe1,0x4f,0x16,0x2b,0x09,0xe9,0x78,0xca,0x6d,0x86,0xee,0x43,0x4d,0x98,0x4b,0x8b,0x00,0x70,0x40,0x9d,0xd2,0xad,0x11,0xb5,0x31,0x78,0xe2,0x39,0xda,0xb5,0xbc,0x39,0xc7,0xba,0x46,0x0d,},"\x54\xc1\xc5\x11\x1e\x08\xc9\x82\x45\xba\x4f\x13\x18\xba\x1d\xb1\xdc\xc7\x4d\x14\xa5\xc9\x8a\xb9\x68\x9c\xba\x1c\x80\x2c\x68\xbc\xfc\x81\xfd\x87\xff\xc6\x1c\xaa\x94\x2f\x66\xd7\xe5\x15\x7f\x65\x53\x8c\x7e\x7b\x33\x17\x04\x84\xb4\xb6\x54\x3f\x36\x20\xff\x29\x63\x8b\x64\xd4\xda\xe7\xb0\x22\x21\xcf\x77\x83\xf1\x87\xec\x42\x31\xe6\xb6\x94\x6d\x82\x76\x20\x74\xf0\x9c\x32\x78\x1c\x2f\x38\x46\xde\x3e\x82\x17\xf6\xe1\xb6\xe0\xd2\xb5\x59\x5d\x74\x2e\x2c\x4e\x32\x5a\x28\x41\x92\x40\x44\xdf\xcf\x12\xb4\x79\xeb\x69\xf1\xbb\xd4\x0e\xab\xdd\xd1\xff\x54\xa9\x18\x4d\x36\x6d\xff\x9d\x8f\x2d\x86\x3e\x37\x8a\x41\xf1\x0c\xd1\xda\xe9\x22\xcd\x7f\xbb\x2a\x54\x4e\x47\xea\xbf\x47\xca\x0a\x38\xab\xba\x34\x45\x49\x19\xbb\x9a\x4e\xf0\x44\xbf\xb9\x7b\x70\x8c\x2f\x74\x28\xd6\x8f\x9c\x57\xc0\xee\x7e\x79\x25\xf7\xa2\xb5\xc6\xe7\xdf\x82\xbb\x26\x80\xc8\x62\xdc\x7c\xc6\x8b\x0f\x54\x53\x0e\x64\xaf\xe2\x76\x3d\x9c\x7b\xaf\x45\xcc\x6f\xe6\x12\xd1\xf7\x82\x77\x39\xc4\x41\x13\x98\x88\x8f\x73\x67\xc3\xd4\x37\x79\x07\xac\xc0\x6a\x06\xf9\x3f\x88\x72\x26\x79\x8f\x48\xaa\x54\x64\xf6\x01\xc2\xc1\xed\xda\x77\xed\xfe\xb9\xb9\xb5\xd5\xf9\xcb\x6f\xed\x37\x90\x05\x47\x47\x7f\xca\x1d\x09\xab\x52\xd6\x3e\x49\x1f\xeb\x12\xfd\x6d\xc8\x05\xa7\x8c\xee\x3b\xaa\xde\x43\x52\x98\x20\x61\xde\xa5\xa2\x65\x3d\xb8\xe7\x60\x77\x72\xe8\x34\xb3\xa5\x05\xc1\x6d\xd6\xe7\xc7\x1b\x91\x1e\x84\x2e\xba\x92\x5d\x77\xa3\x3c\x5c\x57\xce\x11\x84\x09\x80\x78\xca\x2e\x6a\x3f\x69\xaa\x6a\x14\x63\x9d\xc9\x7b\x4b\x30\xc9\x9d\xc4\xfa\x3e\x2c\xf6\x3c\x70\x1c\x30\x6c\x5e\x25\x3c\x51\x13\x85\x4c\x18\x5e\xbc\x8b\x47\x98\xf6\x8d\x1f\xd7\x80\x05\x4d\x3e\xed\x2f\x39\x4c\x45\x43\x04\x96\x6b\xdd\xbd\x12\x28\x08\x34\xec\x9b\x40\xc1\xe9\x8b\xc2\xd9\x8f\x48\x45\xf6\xeb\x44\xf2\x53\x15\xee\xdb\x3b\x79\xff\xca\x41\x80\xc1\xbd\xdd\x97\xd0\xc9\xaf\xfb\xac\x58\x81\x49\x37\x68\x26\x80\x07\x6f\xe5\xa3\xba\xbb\x65\xd2\x8f\x25\x17\x03\x6c\x0c\xfb\x42\xf0\x29\x3e\xb2\xac\xb1\x39\x49\xfe\x91\xe0\xad\x06\x78\xaa\x24\x3d\x77\x34\xa8\x9d\x99\x78\x70\xbf\x9a\x6a\x58\x4e\xd6\xe6\x28\x16\x3e\x39\xd8\xaa\x61\x0d\x46\xb9\x28\x5b\x9e\x1d\xd7\xe8\xf8\x07\xfd\xf5\xca\x2b\xbf\x6d\xe5\xe5\xe6\x8a\xf7\xcb\x7e\xbd\x43\xec\xce\x22\x7c\xd7\x0c\x7b\xf4\xee\x14\x33\xed\xfc\xfe\x88\x66\x14\x67\x0c\xdd\x19\x63\x43\xfb\x91\xe1\x54\x16\xd2\xf6\xac\xba\xe3\xea\xdc\x03\x02\x31\xee\x9d\x2e\xcc\x52\xa8\x8c\xe8\xdc\x7d\x09\x8e\x7f\xac\x77\x68\x5b\x4e\xb5\x40\xe3\x01\x93\x07\x14\x32\x21\xb8\xef\x77\xf3\x63\x2c\x89\x3d\x55\x6e\x0b\xb7\x43\xa1\x96\x3e\xc1\x58\x86\xc8\x54\x5e\x87\xc9\x5c\xc8\x25\xf2\x00\xd0\xf3\xcf\x4f\x55\xa3\xd6\x60\xa5\x36\xa2\x3a\xef\xcc\x42\x8a\x43\x20\x34\x85\xee\x84\x34\x2f\x5c\x00\x1e\xe8\x40\x4e\x75\x90\x17\x00\x62\x82\xab\x8b\xa8\x90\x3e"}, +{{0x00,0xe6,0xbb,0x17,0xaf,0x3c,0x2d,0xf6,0x52,0xb3,0x4f,0x9a,0xbe,0x19,0xf9,0x90,0x19,0x07,0x42,0x33,0x68,0x6c,0x71,0x14,0xe3,0xa0,0xed,0xf0,0x83,0x09,0x93,0x4f,},{0x7b,0x82,0x32,0xa6,0x6c,0xec,0x2f,0x91,0x5a,0xaa,0x79,0x51,0xd2,0x9d,0x2b,0x9e,0xe9,0x3d,0x32,0x1d,0x15,0xb2,0x03,0xc5,0x1e,0x61,0xe8,0xce,0x83,0xd1,0x87,0xf8,},{0x04,0xb3,0xb8,0x50,0x1e,0x39,0x6c,0x4a,0x78,0x8e,0x14,0xac,0x49,0xf6,0x17,0x4c,0xdb,0x5c,0x85,0x5e,0x65,0x12,0x03,0xcf,0x68,0xd1,0xef,0xa8,0x9a,0xa5,0x86,0x78,0xd4,0xd1,0xf3,0x03,0xa9,0x87,0x7a,0x37,0x86,0xd2,0x03,0xc3,0x55,0xb0,0x9d,0x52,0x86,0xc1,0xca,0x0d,0xf0,0x4a,0x89,0xaa,0x06,0xcc,0x3f,0x9d,0x0f,0xd3,0x05,0x04,},"\x06\x32\x81\xe4\x1e\x8b\xa9\x70\x3e\xd0\x9e\xf3\xbf\x0e\xa4\x6e\x4c\xab\xdd\x6e\xbd\x76\x9d\x05\xdc\x04\x5d\x4f\x99\x0d\x69\xfc\x55\x41\x30\xa4\xe6\x1a\xa2\x1e\x2d\xe4\xc9\x2d\xb4\x8a\x20\xa3\x7b\x17\x47\xa7\xea\xc5\xeb\xb2\x73\x5a\x89\x38\x19\x7f\x13\x9f\xad\x14\x97\xb3\x51\xad\x06\x4c\x0f\x18\xf8\xfa\xf1\xfe\x11\xf6\x39\x79\xa6\x99\x68\xe2\x4c\xf9\x1e\x58\xa3\xab\x03\x26\x69\xe4\xef\xee\x27\x4f\x96\xb5\x8b\xe7\xd9\xe3\x91\xf3\x6f\xcf\x07\x09\xb2\xcb\x2d\x22\x69\x4a\x6c\xeb\x17\x24\x69\x45\xeb\xb3\xbc\x7f\x0f\x03\xbf\x0b\x08\xdc\x96\x26\xe3\xe7\x15\xc9\x91\x67\x1d\x53\xeb\xb9\xae\x83\xa7\xd0\x8d\x44\xf6\x36\x35\xc4\x0f\x8d\x48\x17\xf5\x8d\xe9\xeb\x77\xcb\x25\xb2\xac\xd6\xde\xf9\x69\xab\x56\x9e\x97\x4a\x8a\xda\xc1\x1a\x86\xb5\x8f\xe6\xc1\x00\x67\x49\x9f\xc9\x14\xdf\xf5\x69\x02\xcb\xc3\x93\xa7\x1c\xc2\x5e\x8f\x05\xc0\x3c\x94\xf1\x3b\x84\xa2\xb0\x1a\x58\xc1\x0d\xbc\xbb\x60\xeb\xce\xe4\x87\xf5\x29\x17\x74\x66\x29\x99\x25\xda\x50\xe2\xda\x5b\x55\x57\xf0\xae\xee\x3f\xd7\xf4\x7b\x5c\x2e\x3f\x84\xce\xfa\xb4\x67\x96\x91\x39\x4d\xd1\x22\x30\x3b\xb7\x69\xaf\xb3\xad\xfe\x83\x58\xb0\x2b\x67\x92\x73\xb3\x5a\xbd\xc6\x40\x25\x76\xcc\xce\x5e\x10\x44\x2a\x13\x7e\xf9\x45\x69\x39\xb2\x89\xef\x4e\x41\x7b\x1c\xc6\x23\x9f\x7c\xee\xdd\x68\xf1\xa8\x26\x41\x80\xe0\x68\xb4\x96\x6f\xd6\x7f\x2b\xad\x6e\xdd\x8b\x4a\x1e\x8d\x2b\x54\x2d\xaf\x26\xdb\x83\x1f\x1f\xb5\x1e\xb8\x6f\xfa\xde\xcc\xd9\xac\x3d\x66\x4f\x34\x6e\x7d\x04\x6c\x33\xa5\x72\x84\x1e\xa8\x33\x4e\x7f\x2f\x41\x7a\x05\x71\x2a\x9e\x33\x4e\x48\x7f\xd3\xae\x17\x54\x55\x16\x2f\xe8\xf4\x9c\xc0\x26\xa6\x40\xc6\xcf\x93\xcf\x58\x87\x50\x52\xf4\x1c\xc9\x82\x06\x15\x65\x3e\xa2\xd0\x84\xc8\x96\xea\xfe\x5a\xd4\x72\x55\x79\x65\x30\x84\x99\x4f\x95\x6d\x5c\x94\x59\x0a\x24\x09\x58\x1b\x6f\xc8\x6e\x40\xaa\x58\xbf\x6e\x60\x57\xa6\xf9\x0a\xf3\xb8\x7a\xea\xf3\x29\x94\xa5\x5a\x54\xf7\x9b\xdf\x3d\xbb\xf5\xce\x0f\xf8\x12\xe4\x86\xb0\x54\x5d\x9e\x9c\x2b\x0b\xce\x0d\x4c\x36\x47\xb1\x82\x72\x62\x49\x88\x34\xe1\x98\xa3\xec\x70\xf3\xb0\x3d\x6a\xad\x2c\x49\xeb\x80\xb5\xe2\x05\x14\x39\x22\x5f\xd9\xce\x94\x68\xd6\x9a\xf7\x0a\x26\x2e\xe3\xb8\xb6\x2a\x8e\x5b\x41\x34\x6d\xa3\x01\x2f\xfb\x45\x81\x6b\x7b\xec\xb0\xe7\x9a\x60\xbf\xf7\x16\x36\xa3\xe4\xbb\x1b\x35\xca\xf1\x95\xf5\x51\x17\x28\x0f\x78\x72\x17\xb3\xca\xa2\xe7\x93\x72\x6f\xc5\xa7\x4d\x11\x60\xdc\xad\x86\x89\x04\xc1\x97\x38\x11\x34\xed\x8c\x3d\xb3\x75\x0b\x75\x56\xf6\x9c\xcc\xe1\x8b\x77\x38\x8b\x58\xc5\xb8\x11\x3e\x59\x0a\xd6\xea\xc5\xb9\x1e\xce\x5a\x67\x05\x02\x5c\x80\x35\x3c\xeb\x1e\xd8\x4a\xaa\x1c\xc4\x8a\x41\x6b\xc0\x16\xae\xf1\x73\xbb\x80\xb2\xba\x28\xc5\x79\x60\xc6\xb0\x11\xb6\xb4\x95\xa3\xf3\x31\x1e\x79\xfe\x46\xbd\xb6\xa4\xc3\x81\xfb\x9d\xc4\x62\x8b\x0a\x83\x02\x35\x58\xf1"}, +{{0xfb,0xdd,0xf6,0xe6,0x1e,0x20,0xd8,0x06,0xe5,0x59,0x17,0x75,0x6d,0xe6,0x0d,0x0c,0x9a,0x99,0x97,0x6f,0x64,0x67,0x16,0xff,0x2f,0xf1,0x31,0x2c,0x54,0xdd,0x97,0x1d,},{0xac,0x53,0x8f,0xab,0xad,0x43,0x80,0xe6,0x0e,0x97,0x71,0x26,0xe7,0x69,0x5e,0xed,0xa5,0x41,0x7d,0x85,0xf7,0xd2,0x3d,0xb2,0x1b,0xd0,0xad,0x11,0x11,0x16,0xf0,0x5d,},{0x8c,0x9b,0x77,0xaa,0x0f,0x1c,0xf5,0x2e,0x8f,0x7a,0x91,0x8b,0x21,0xb4,0x68,0xe6,0x23,0x35,0x91,0x1b,0xc5,0x93,0x06,0xb3,0x0c,0xe7,0x7b,0xf6,0x92,0xc1,0x10,0x59,0xb0,0xee,0x9c,0x5d,0xaa,0xf6,0x83,0x9b,0xb8,0x13,0x73,0xc6,0x1d,0x28,0xd0,0x72,0x70,0x2b,0x59,0x5e,0x4d,0xce,0x28,0xcb,0x99,0x38,0x22,0xb2,0x48,0x13,0x04,0x0b,},"\x3e\x99\x53\xca\x55\xd0\xcd\x23\x3b\x98\x83\x3e\xb1\xbc\x79\xd3\xb5\x5f\x18\xc8\xfa\x1c\x42\x02\x7b\xca\x25\x57\x91\x53\xb5\x5d\xa0\xc5\xa1\x78\xb8\x38\x69\x56\xd9\xa5\x41\x83\xb2\x4c\x91\xdc\x4b\xe9\x94\x84\x72\x37\xd3\x66\x6a\x0a\x01\x30\xfe\x19\x92\x4b\xc0\xee\x50\x89\x6c\x35\xa2\xe1\x6a\x29\xe2\xe2\xac\xf1\x80\xbd\xd9\x37\x93\x54\x68\x7f\x0e\xce\x68\x82\xd2\x6e\x98\x0e\x68\x66\x98\x04\x3b\xb1\xb0\x12\x13\xaa\x64\x4a\x4f\x8d\x61\xf9\xb6\x13\xe6\x2e\xaa\x35\x76\xce\xa0\xb0\xb8\x3f\x05\xce\x25\x58\xff\x63\x56\x49\x5c\x45\xed\xe4\xa8\xf6\x5b\x81\x4a\xb8\xa7\x30\x94\x03\xdf\xd4\x3c\xbe\xa9\x08\x93\x93\x9b\x78\x00\xaa\x00\x23\x2b\x5f\x6b\x77\x14\xeb\xdc\xd8\xbc\xf3\x4a\x5a\x7e\x82\x2a\xc7\xb1\xb0\x99\xac\x61\x5f\x13\x5f\x8c\x35\x1d\xc4\x1a\xe5\xf6\x6d\x5f\x9c\x26\x00\x45\x4c\xa0\x1c\x00\x9b\xa6\xde\x04\x16\x2a\xe5\xf1\xf2\x70\x89\x3c\xa3\x90\x7a\xff\x7f\x78\xe0\x33\x96\xe3\x2b\x62\x2f\xf3\x40\x53\x7b\xf1\x23\xe5\x59\x95\xe9\x20\x96\x09\x33\x0b\x2e\xee\x51\x12\x74\x84\xa4\x0e\x25\x07\x00\x82\x3f\xeb\x0b\xc9\x7b\xb5\x09\xff\x73\x26\x75\xde\xc3\x2e\xcb\x63\x5e\xd9\x2c\x7d\x78\xfe\x30\x50\x20\x0c\xf1\xd9\x41\xd6\xb3\x88\x80\x0a\x84\x19\xd9\x6a\x59\x5e\xce\xd5\xec\x4e\xfd\xcb\x6f\x98\x7f\x54\x72\xa5\xc4\x30\x58\xd3\xa3\xa7\xbb\x56\xd7\x98\x03\x65\xed\x43\xdb\xc2\xbe\x48\xf1\xd1\x8c\xe7\x6a\x89\x18\x54\x26\xfd\x5c\x69\xdf\x7e\x92\x91\xab\x78\x23\xc2\x3a\x76\x94\x1e\xd3\x83\x6a\xac\x7b\x58\xc0\xd5\xfb\x6b\x63\x6c\x42\x47\x1a\x4d\x17\x03\x51\x6f\x03\xe9\x35\xf3\x1f\x19\x54\x50\xe5\x37\xb2\xa0\x7d\x54\x5b\xa4\xb6\x8a\xfb\x06\x38\xc6\x5b\xb0\xff\xaa\x0c\xfd\x69\xd7\x10\x48\x19\x79\x66\x19\xd4\x83\xa0\x24\x5b\x4f\xd9\x01\x7f\x62\xa7\xd3\xa5\xfc\x3b\x72\x89\xd7\x57\x35\xf2\x87\xca\x0a\x95\x1a\xd5\x83\x44\xb2\xab\x7d\x7d\xf8\xdb\xd7\x92\x2a\x5a\xbb\x8d\x7c\x2e\x79\x14\x7e\x6d\x36\xee\x31\xf9\x30\x47\x3b\x07\x27\xdc\xfd\x58\xd6\x44\xd7\xd7\x0a\x0e\xd3\x1c\xa6\xa1\x3e\xd9\xdb\xd2\x24\x49\x2e\xfd\xa1\x9e\x4f\x8e\xed\x46\x18\x0f\xe7\x50\xf0\x7b\xbe\x8e\x99\x85\x4d\x13\xf5\x8b\xa9\x68\xce\x38\x59\xd6\x11\x89\xcd\x2b\x66\x7f\x3b\x2d\x06\x65\xb5\x74\xc4\xba\xc1\x9d\x9e\x37\xe5\xb7\xa8\x0e\xb3\x34\xe3\x68\x10\x53\x0a\xa5\xd1\x76\x63\x93\xf8\x11\x5a\x52\x09\x0c\x91\x82\x34\x28\xc8\x97\xa5\xf3\x5e\x12\xa8\xaf\x2c\xd4\xfb\x13\x90\x7c\xa6\x60\x3a\x4f\x76\xf5\xc2\xe0\x23\x74\xa8\xdc\x3a\x47\xc1\xbe\x6f\x1d\x1c\x8e\xbc\x59\xb3\x6d\x1c\xfa\x0a\xb2\x3e\x9b\x0a\xe9\xb0\xe6\x37\xee\xed\xb9\xc6\x6b\xea\x62\xdc\x63\x0c\xde\xfa\x71\x82\x39\x61\x7e\x31\x18\xe5\xb6\xde\xb7\xc2\x94\x47\x52\x82\xe8\xab\xe2\x4f\xd5\xa5\x4b\x78\x6f\xff\x90\x28\xc5\xa0\x33\x38\x4e\x4b\xc8\x01\x4d\xec\x8d\xa1\x00\xa9\x4b\x17\x8e\xf8\x8e\xc3\x57\xb6\x6d\x2b\x90\x98\xab\x64\x79\x16\x96\xb1\xa6\x6b"}, +{{0x8a,0x55,0xe7,0x7b,0xb0,0xc8,0x74,0x0b,0x8c,0x2e,0x8d,0xdf,0xdf,0xdb,0x40,0xf2,0x7e,0x45,0xfe,0x81,0xfe,0x45,0x71,0x11,0xbf,0x1c,0x87,0x30,0xea,0xb6,0x16,0xb4,},{0x9f,0xf1,0xfd,0x0c,0x50,0xeb,0x24,0xf9,0x9f,0xe2,0xf7,0x71,0x1d,0x52,0x87,0x2d,0xfc,0x90,0x03,0x80,0xdd,0xdc,0xdb,0x86,0xfe,0x6f,0x4a,0x5f,0x35,0x0a,0x87,0x43,},{0x8a,0xae,0xba,0x53,0x5c,0x51,0x1c,0x31,0xd3,0xf8,0xe9,0x5c,0xb0,0x77,0xa9,0xa7,0xec,0x7d,0x08,0x44,0x1e,0x53,0x42,0xa6,0xab,0xe0,0xbf,0x2a,0x5d,0x7f,0xc9,0x30,0xb4,0x3d,0xac,0x3d,0x1e,0x8e,0xf2,0xcb,0x03,0x45,0x52,0xeb,0x4d,0x08,0x39,0xbc,0x8b,0xf2,0x94,0x55,0x1d,0xd2,0xd8,0x0c,0x53,0xfd,0x62,0x79,0x35,0x1a,0xc2,0x0c,},"\x20\xfb\x41\x4e\x26\x4a\x95\x47\x84\xf1\x12\xba\xce\x7e\x04\x74\xb3\x9c\xb3\xc9\xe5\x3d\xee\x0a\x21\xf4\xcf\x6d\x4a\x99\xb9\x34\x7d\xdf\xfb\xe2\x81\xa6\xc2\x30\xa7\x5d\x63\xa7\x2f\xd0\x5f\x6d\xb5\x3e\xa7\x01\x4e\xf7\x70\x9d\x18\xff\x97\x0f\x48\x5f\xe8\x3b\xa1\xd3\x71\x47\x33\x8a\xde\xd6\xda\x4c\xfd\xac\xc1\xe6\x9d\x2f\x3e\x0e\xf3\x62\xf4\x7b\x5b\xcf\xb7\x8a\x1e\x17\x9e\xb5\xc5\xb1\x06\xc8\xd8\x2a\x0a\x0b\x29\x0d\xf0\x75\xab\x27\x43\x69\x29\xcd\xe6\x56\xf0\x23\x09\xf9\x57\x50\xeb\x67\x65\x83\x26\x2e\x5f\x2f\x69\xf0\xff\x72\xa8\xe0\x57\x26\x63\x82\x26\x92\x05\x31\x87\x40\xbf\xe0\x6b\xf5\xc2\xcb\x45\x33\x90\x8e\xf9\xf9\xf2\x86\x9a\x75\xb9\x53\x35\x79\x82\x0e\x3b\xc0\xca\xff\xd6\x46\x17\x1c\x82\x86\xc3\xa4\xab\xa1\xff\x09\x15\xd9\x36\x11\x20\x5e\x23\x0f\x39\xff\x4c\x4c\xaf\x3f\x33\x3e\x75\x3f\xce\x2b\x71\x21\x3e\x53\xd6\x08\x41\x5e\xe1\x7f\xd4\x82\x12\xee\xdd\x88\x40\xf3\x37\x10\x1e\xf0\xd0\xb6\xf7\xbe\x4b\xff\xc0\x6e\xee\xfe\x80\x66\xdd\x27\xa0\x54\x1a\x46\x88\x31\xac\xdd\xc4\x90\x2e\x2f\xef\xef\xbe\xd1\x9c\x30\x8e\x56\x21\xe0\xbf\x46\xbc\xd5\x38\xaa\x13\xfa\xf0\x4d\x38\x07\x59\xc0\xe1\x07\xe9\x12\x00\x18\x39\xdf\xd0\xb6\x35\x44\x0e\x96\x38\xf5\x37\x7c\xa8\x45\x0f\x35\x0c\x01\x12\x9e\xe3\x37\x64\x41\x5c\x53\xcb\x2f\xfb\xf9\x68\xdf\x78\xb7\x42\xfd\x06\x65\xe7\x8a\x34\xab\xf4\xde\xcd\x1f\xd3\x86\x28\x9a\x13\x64\xe6\x45\x55\xee\xc5\x8b\x0a\xf9\xa4\xcd\x6b\x36\xd1\xd5\xc6\x11\xa2\x84\x6d\xfb\x55\x89\x34\x4b\xbb\xb0\x25\x60\x24\x1b\x74\xb9\x93\xa2\x5b\xef\x50\xfb\x1e\x73\x19\x08\x6e\x6a\x23\x98\x63\x00\x83\x4e\xd2\xdb\xa9\x8a\x16\x87\x21\xc2\xf7\x84\xdf\xb8\xd3\x80\x0d\x06\xa0\x54\xae\xf1\x4d\x17\x72\xb6\xc5\x74\xaf\x25\x63\xd1\x93\xef\x2e\x51\xbd\xc6\x2d\x2a\xbc\xe2\xee\xbe\xad\xa7\x92\x03\x49\x8e\x66\x86\xc2\x87\xf3\x7b\xd8\x8a\xeb\x16\x6f\x7d\xff\xc3\xe6\xad\x02\x94\x11\x7e\xf6\xee\x9d\xa8\x47\x9e\xd8\xa1\x6f\xe9\xbe\x24\x6d\x26\x68\x04\xf2\x96\x58\xdb\x75\xe7\xa0\x87\x3b\xe7\x1d\xc7\xd4\x07\xe3\x9f\xab\xd6\x6f\x98\x8b\x45\x74\x77\x42\x7f\xad\x81\x30\xf0\x9a\xb6\x65\xf1\x59\x7c\x90\x46\xe7\x37\x3a\xf9\xa8\x35\x2a\x86\x83\x0c\xb9\x2a\x80\x44\x88\x70\x0f\xe6\x89\x19\x24\xfe\x2a\x72\x01\x73\x3d\x95\xe5\x91\xee\x0a\x1f\xef\x1c\x26\x36\x07\x8d\x37\x0e\x7a\xd3\xb6\xa9\x44\xfe\xd2\xcf\x2b\x30\xab\xa2\xd5\x6f\x34\x95\xb2\x84\x9c\x03\xbb\x61\x4f\x48\xbc\x4e\x50\x7c\x39\x5a\x6c\x35\xd3\xee\xd4\xc7\xbe\x8e\x68\x0f\x2d\x45\xa3\x10\xb1\x87\xeb\x88\xcf\x0e\x8e\xd4\xde\x7d\x37\x24\x6a\x50\xa6\x36\x7b\x97\xee\x37\x84\x32\x2c\x0b\x71\x13\x1a\x28\x31\x98\xda\x48\x04\xde\x75\x1d\xcf\x70\xc4\xba\xd0\x0d\xd9\x8d\x87\x3a\x69\xdd\x1a\x09\xcf\x69\xdd\xfa\xd7\xae\x60\x35\x00\xb6\xa4\x62\x25\x80\x98\xd8\xb6\x6b\x85\x29\x35\x94\xe2\x08\x82\x9b\x52\x28\xfa\xe2\xfa\xfc\x39"}, +{{0x16,0x3b,0x0c,0xb6,0xa1,0x2e,0x8f,0x07,0xb0,0xc2,0x9d,0x6a,0x63,0xf6,0xa6,0x52,0xce,0x49,0x72,0x70,0xb5,0xe4,0x6f,0xcf,0x83,0x3c,0x99,0xbd,0x84,0x3f,0x8c,0x64,},{0x68,0xa3,0x5d,0xe4,0xba,0x6f,0x0f,0x82,0xec,0xf4,0xb1,0xe0,0xdf,0x8e,0x24,0xcb,0x4f,0x18,0xf2,0x10,0x3f,0xf0,0x4d,0xc1,0xb5,0x33,0x39,0x91,0xb6,0xd3,0x14,0xba,},{0x17,0x73,0x8f,0x57,0x26,0x55,0x07,0x80,0x65,0x1d,0x60,0x19,0x9f,0xda,0x39,0xd9,0xc4,0x76,0x8d,0xb5,0x91,0x7e,0x32,0x39,0x36,0x31,0xc5,0x4a,0x41,0x9d,0x59,0xf1,0x8e,0xf9,0x60,0xdd,0xd4,0x39,0x38,0x0d,0xab,0xc3,0x14,0x76,0x1b,0xd0,0xcd,0xb5,0x7c,0xce,0x48,0x1e,0x61,0x09,0xfe,0xd0,0x95,0xde,0xa6,0xe8,0x65,0xaa,0x67,0x0b,},"\x56\xa1\x60\x3f\x72\x5b\xe0\x76\x13\x05\x8c\xdb\x3a\xcd\xc5\x23\x54\xe3\xbb\x1f\xf2\xbe\xd1\x3f\x89\x51\x75\xb1\x5c\x8c\x5a\x90\xff\xbe\x46\xb1\x1a\x06\xcf\xe3\x62\xda\xdf\x73\x23\xc9\x40\x41\x72\x55\xaa\x7a\xa5\x43\x12\x10\x3e\x71\x46\x3d\xaa\x0b\x5c\xda\xeb\xd0\xbe\x72\x3c\x73\x22\x73\xe3\xc3\xf5\xbf\x7a\xa3\x51\x9d\x69\xdf\x6f\x47\x70\xda\xa1\xdf\x82\x80\xbb\x3c\xd2\xc7\x14\xac\x03\x02\x00\x54\x65\x79\xf5\x6c\x60\xb9\x1a\xe1\x1f\x4c\xf8\x74\xa3\x5f\xc5\x9b\x35\x4b\xed\x80\xf5\x6e\x11\xa6\xcd\x62\xa8\x8c\xe6\xb4\xf6\xbf\x39\xd6\x4c\xe3\xd8\x04\x09\x82\x5f\x90\x16\x2c\x3d\x96\xd1\x0e\x47\x86\x07\x36\x5f\x7a\x24\x1e\x71\xaf\x98\x00\x42\xfe\xc2\xd6\x88\x91\xe0\xc8\xa3\x7c\x58\xec\x4e\x60\x0f\xd5\x81\xe7\x90\xb0\xaa\xe8\xe0\x9f\x35\xd4\xcc\x18\x76\xdf\x43\x4b\x80\xee\xe0\x53\x69\xf8\x48\xfc\x49\x30\x57\x7d\x16\x84\x27\x58\x88\xf3\x25\x9c\xb4\x73\x76\xc5\x16\x9c\x99\x37\xf8\x55\xa9\x6a\x9e\x74\x8a\xd0\xa6\x9a\xe4\xab\x2f\x2f\x17\x44\xa3\x92\xf9\xac\xc6\x20\x99\x75\xb7\x84\x98\x4c\xb1\x2f\x98\x29\x2c\x36\xa5\x32\x21\x99\x4a\xbc\x56\xf9\xa6\x6d\xae\x45\x60\xb7\x93\x56\xff\x47\xe1\x28\xc0\x79\x6a\x7f\xb0\xe0\xbb\xc9\x60\x0a\xf4\x8e\x49\xea\xa9\x42\x7c\xf6\xeb\x66\x20\xb1\x0c\xd2\xc0\x85\xb0\xb3\x42\x00\x4d\x5b\x0d\x3e\xdc\x11\xd2\x92\x42\xa4\x63\x87\x80\x76\x2c\x9d\xc6\x06\x9b\x66\xbd\x84\x97\x3b\x50\x11\x96\x1c\xe5\x6d\xb5\x8b\xda\xf4\x8e\x6b\xe1\x2a\xb9\xad\x24\x41\x62\x97\x00\x4d\x02\x91\x4b\x95\x9f\x54\xe0\x92\xf8\xcd\x43\x65\xfa\x6a\xb7\x8d\xdb\xff\x4c\xe8\xda\xd4\xe2\xf5\x3a\x05\xc0\xcc\x49\x9b\xfb\x47\x81\x4a\x27\x13\x55\x1d\xcd\x19\xd4\x47\xf6\x27\x57\x6e\xa4\xea\x4b\xbd\xa8\xba\xe1\x8a\x64\x65\xce\xd7\x47\xea\x17\x18\x0b\x00\x9f\x01\x21\x21\x60\x48\x2b\x04\x33\xaa\xc6\x8e\x67\x64\x4d\x00\xf4\x1f\xdf\x99\x90\xb9\xe1\x11\x17\x63\x4d\xeb\x13\x9b\x1a\x40\xad\x3f\xce\x42\x99\xa1\x7f\xe1\xdd\x22\x53\x01\xc7\xf8\xd8\x01\x0a\x79\x6d\xc7\x9c\x13\x30\x7d\x3f\xf9\x92\xa8\x8b\xe6\x64\xd4\xc8\x86\xd6\x8c\xa9\xe4\x47\x0c\xfb\xe6\x3e\xbf\xfc\x42\x40\x10\xe3\x72\xb6\x92\x2a\xa9\x5c\x80\x1d\x1e\x94\x06\xda\x4b\xc1\x88\xca\x82\x06\x64\x05\xbc\xdb\x3e\xaf\xc9\x37\x62\x9b\x32\x63\xdc\x7d\x50\xee\x52\x78\xcc\xec\x6f\x11\xd5\x51\x7f\x56\xbc\x26\x9c\x87\x36\x91\xe7\xeb\x53\xfa\xef\xf0\x75\x64\xab\x46\xb4\x03\xf1\x5d\x9e\x0e\x69\x24\x86\xee\x09\x8e\x7b\x51\xb4\x28\x13\x46\x9b\x82\x35\x04\x22\x33\xca\x3f\x9c\x4f\x8f\xf2\x4a\x57\x1f\x47\xe0\xad\xf9\x14\x4a\xea\x48\x8a\x2d\x2d\xd0\x01\xe3\x1f\xc9\x61\xe0\x5c\x3e\x85\xf0\xd9\x81\x40\x7c\x87\x31\x58\xbb\x0d\x35\xba\xfe\x4b\x60\x42\x2e\x67\x55\x1e\x97\x01\x65\xce\x3f\xc5\x99\xd0\xfc\xc9\x2b\x16\xac\x36\xa9\x2b\x2c\x1d\xc6\xb3\xf0\x33\xfe\x31\x0c\xd1\x96\xda\x04\xa4\xe6\x39\x03\x11\x77\xcd\x27\xd7\xc2\xfb\xec\x65\xa0\x0b"}, +{{0x8c,0x83,0x93,0x81,0xb6,0xa7,0xce,0x26,0x49,0xc1,0xea,0x46,0x4a,0xe3,0xc2,0xd3,0xfd,0xb1,0xec,0x66,0x6d,0x7b,0x4b,0xe4,0xe2,0xa9,0x41,0xab,0x6d,0x65,0x57,0xa7,},{0x5c,0x72,0x4a,0x30,0xc6,0xfb,0x32,0x81,0x53,0x43,0xa8,0x0d,0xde,0xe6,0xee,0xe5,0x44,0x51,0x64,0x18,0xea,0x95,0xe1,0xba,0xc8,0x0a,0xfc,0x80,0x40,0xd6,0x3f,0xc6,},{0x5d,0x21,0x10,0xd1,0xd2,0xf3,0xed,0xd6,0x83,0xbd,0xfd,0xbe,0xa3,0xff,0xa7,0xcf,0x55,0x28,0xa4,0x0b,0x8b,0x3d,0x8d,0x8c,0x9b,0xfd,0x22,0xae,0xac,0x28,0xba,0xd4,0x71,0x66,0x6e,0x06,0x2f,0x7d,0x38,0xce,0xda,0x8b,0xb3,0x73,0x97,0xa1,0xc5,0xc3,0xf7,0x33,0xb5,0x37,0x96,0x70,0x45,0x70,0x64,0x78,0x43,0x7d,0x4d,0x18,0x7a,0x0a,},"\xcb\xcf\x89\xc3\x54\x89\x64\xc3\x8d\x70\xfd\x8f\x68\xe8\xec\xe3\x6c\xc3\x97\x55\xc9\x71\xd1\x4d\x7e\x05\x6f\x39\xb0\x23\xef\x16\x6d\x17\xf2\x43\x85\x22\xf0\x10\xd6\xd8\x35\xd8\x86\xe7\x1f\x47\x4c\x67\x27\xa4\x22\x1f\xd0\x3a\x75\x74\x57\x82\x89\xed\x54\x93\xac\x4c\x09\x47\xe3\xf4\x28\xd8\xfe\x06\x40\x06\xa2\x56\xce\xf2\x18\x11\xd7\x26\x78\xf5\xdf\xc6\xba\x66\xac\x29\xec\xd1\xb3\x2f\xf5\x55\x7c\xb0\x8c\x5f\x13\x05\x59\x21\x7a\x04\x13\xb7\x59\xc2\x4d\x83\x38\x8a\x2b\xb9\xb2\x9b\x6b\x91\xd1\xf3\x10\x1e\xd6\x25\x21\x1e\x4d\x73\x80\x51\x93\x47\x8c\xf9\x95\x39\x6c\x10\xb1\xc5\xaf\xfa\xcb\x00\x89\x9d\xa0\x4e\x3c\xce\x19\x3b\x49\x4e\x2a\x93\x3c\x4e\xeb\xe0\xa3\x7b\xfb\x8f\x1b\x83\x71\xbd\xe5\xfd\xa0\x9e\x80\x4e\x94\x0f\x34\x48\x96\xa5\x29\x46\x7a\xde\xe4\x5a\x8f\xeb\xf8\x5a\xb0\x36\xca\xb8\x80\x14\x3b\xe4\xf5\x9b\x77\x41\xd8\xe4\x50\x27\x8b\x06\x36\x55\x78\xd4\x0b\x19\xdc\xec\xc6\xe1\xee\x3d\xa3\x4a\xb2\x90\x13\xfa\x3a\xf7\x72\x92\x72\x96\x21\x10\xe3\x85\xab\x9a\x02\x2f\xae\x41\x46\xf8\x97\x16\xf7\xba\xb9\xd3\xdc\x68\x2f\x4f\xac\x77\x36\xd3\xe0\x89\x73\xc6\x85\xbb\xb2\x75\xbb\xf8\xf2\x17\x41\x9e\x5c\xae\x02\x19\xeb\xa5\x16\x6a\x5d\xe1\xb1\x1e\x3f\x9a\x90\x8b\x8a\xc7\xe6\x5b\xcd\x62\x3f\x8c\x18\xbb\x02\x4f\x60\x5d\xcb\xac\xda\x79\x0d\x83\x62\x95\x74\x44\xa9\x5c\x13\x0a\x37\xee\x9d\x56\x3d\x0c\xbb\x4c\xb2\xb0\xff\x71\x59\x1d\x93\x90\xb6\xc8\xfc\x28\x75\x3a\x0e\x40\x2d\x64\x87\xcf\xac\x60\x71\x35\x92\x7d\x89\x26\x75\x12\xb3\x4f\x87\x70\x57\xd9\x27\x1b\xcc\xc0\x24\xdf\xed\xcc\xc6\xc3\x2e\xdf\x75\xc8\xb7\x55\x1c\xdf\x80\x15\x4e\xe8\xe0\x8a\x0c\xc4\x30\x44\xe1\x03\x6b\xae\x01\x7e\xb4\x8b\x65\x02\xc7\xa9\xd6\x0c\x8b\x37\x0c\xf3\x79\x9c\x46\x4f\x96\x4a\x69\xee\x65\x95\x01\x22\x3e\x78\x9a\x64\x97\xb6\x34\x96\xdf\x1a\xda\x2e\x80\x8d\x24\x34\xfc\x8b\xb9\x79\x4e\x5e\x2a\x20\xbb\xf4\xd6\x92\x5c\xb3\xc5\xbb\x14\x84\x2f\x19\x20\x09\x05\xba\x93\x54\xe0\x0d\xc3\x3c\xff\x5b\x42\xd4\xe9\xd9\x66\x8b\x34\xe6\x61\xd4\x4b\xef\x76\xfe\xfe\x2e\xd5\x1f\x94\x42\x3a\x93\x3a\xc9\x4f\x15\x23\xbf\x37\x82\x3a\x23\x8d\x61\x6c\x6b\x17\x97\x34\x41\xe3\x5f\x94\x05\xa0\x4d\x99\xea\xa8\xf5\x04\x53\x4c\x8b\x5f\xa5\xe8\xe3\x35\xc7\x43\xbc\xf2\x1f\x5d\x49\x2b\x71\x12\xe0\x0f\xd8\x64\x2c\xb1\x2b\xfe\xc8\x49\xdf\x62\x12\x0d\xbb\x06\xbf\xc2\x94\x6a\x56\x01\xe2\x5b\xe7\x50\x11\xc6\xf0\x0c\x65\xd3\x5f\x44\xa4\x6a\xf9\xe4\xf7\x80\x9e\x57\x89\xa3\xa6\x1b\xa0\xa3\xb2\x13\x89\x04\x97\x29\x6c\x81\xe4\x2e\x88\xf0\xec\x0f\x5d\xef\xc1\xf5\xd3\x9f\xf2\xa4\x8b\x7e\x30\x26\xc9\xe5\x47\x20\x2e\xdc\x7e\xb7\x38\xc3\x4a\xd3\xa1\x5d\x37\x3e\xf8\x2a\x4c\x1d\x18\x1f\x28\x5a\x98\xbd\x33\x14\xc2\xc1\x94\x7c\x9e\x2c\x60\xac\xa5\x17\x50\xee\x7f\x94\x3c\xaf\x0c\x4e\x1e\x5c\x7d\xf7\x29\x1e\x97\x3b\x1f\x93\x6b\x73\x70\x76\x19"}, +{{0xaa,0xbb,0xb2,0xef,0xed,0xb5,0x99,0x42,0x4a,0x5f,0x3e,0x08,0xf9,0x0f,0xa8,0x82,0x6c,0x5c,0x92,0x17,0x0b,0xe5,0x01,0xa1,0x18,0x1f,0xe8,0xe8,0xdf,0x97,0x4e,0x0e,},{0xce,0x73,0x19,0xef,0x88,0xb2,0x42,0x42,0x06,0x66,0xca,0x69,0x7b,0xa8,0x50,0x1d,0x27,0x4e,0xc4,0xa5,0xdc,0xf8,0x44,0x59,0x66,0x08,0xb9,0xdd,0x5a,0x8a,0x3a,0xcd,},{0xa0,0xb1,0x9c,0xfa,0x6c,0x80,0xde,0x77,0xbf,0xcd,0x32,0x10,0x30,0xbf,0x8c,0x03,0x89,0x3e,0x2b,0x21,0xac,0xe6,0xc6,0xba,0x1f,0xf7,0x40,0x8e,0x6f,0xf0,0x7d,0x84,0x7e,0x6b,0x2b,0x68,0x8d,0x4f,0xd5,0x1a,0xa9,0x32,0x70,0x1d,0xb6,0x40,0x2e,0xf2,0x23,0x22,0xe6,0xe9,0xfc,0x7e,0x32,0x0a,0xbb,0x4d,0x24,0xe1,0xac,0xc6,0xcf,0x06,},"\xfc\xc1\x5c\xc5\x79\x70\x56\x9e\x9c\xcf\xa5\xa7\x78\xfc\x7a\xed\x71\x97\x8a\x3f\x56\x24\x57\x7b\x6f\x57\xfa\x3f\x16\x7e\xa2\x23\xef\x31\x76\x4c\x48\x8d\x05\x9d\x06\x53\x1d\x01\x6b\xcb\x17\xd5\x44\xd4\x69\x77\xaa\x24\x1f\x8e\x07\xaf\x47\x87\xa0\x81\x0f\x98\xd7\x66\x46\x0c\x08\x41\xad\x81\xb8\x8f\x4d\x5d\x81\x64\x48\x5a\x12\x58\xa9\x46\x22\xc5\x49\x24\x28\xd6\xd5\x75\x94\x37\x15\x76\x6c\x2b\x0a\x86\x5b\xed\xba\x16\x7d\x5d\x34\x0e\xdb\x57\x9c\x47\xaa\x32\x45\x9b\x8f\xc9\x8a\x79\xbb\x0b\xed\x1c\x96\x0b\x4c\xcb\x7f\x2d\x4b\x56\x81\xa2\xa7\x0d\x50\x5b\x85\xb8\x1e\x3d\x99\x67\x27\x14\xe4\xea\xb4\x1f\x3a\xb0\xca\x87\x4f\x41\x71\x86\xfe\xb6\x9e\xd1\x3f\xb9\x11\xf4\x9d\x15\x84\x75\x8b\x2d\x18\xb4\x67\x3e\xdf\xae\x49\x5e\x68\xda\xd5\x13\xa7\xac\x0d\x47\xb2\x75\x3c\xb4\xed\xa7\x8f\xb4\x31\xf0\x4d\xda\x8f\xe8\x03\x0d\x7b\xb4\xe8\xdb\xcc\xb9\x69\xd7\xf5\x80\xd9\xc1\xef\x93\x5d\x07\x4d\x7a\x41\xd1\xf8\xb9\xdc\x45\xc9\xa2\xe4\x10\x6a\x55\x29\xa9\x8b\x95\x52\x9a\xb0\xed\xea\x0b\x57\x22\xdd\x68\x6f\x5a\x7f\x3c\xd8\xfb\x26\x24\xab\x26\xc4\x2d\xf1\x1f\x51\x0a\x10\x3d\x8a\x92\x98\x30\xad\x85\xf5\x21\x24\xe3\xd5\x82\x7b\xa6\x0b\xfb\xcd\x73\x6c\xb6\xc5\x90\xee\x77\x7e\xad\x7a\xa2\x22\x4d\x7a\xe4\x6d\x25\x7a\x90\x40\x72\x47\x96\x0c\x9c\xb0\x38\x60\xae\xaa\x7f\x54\xc1\xa8\xe1\x11\x60\xd1\x1b\xb4\x73\x06\x5e\x19\xb7\x07\x21\xc8\xf0\x72\xe1\x90\x9d\x53\x9e\x9a\xc9\x41\x85\x90\x4b\xbb\xfe\x54\x87\x37\x54\xae\x1c\xa7\xbc\xed\x6f\x40\x56\x1a\xf4\xb5\x05\xf0\x3a\xc9\x72\xa6\xf0\xbf\xa7\x3b\x5f\x83\x2f\xe2\x3b\x89\x8b\x2b\xbb\x05\x74\xa6\x66\x2e\xe9\x3b\x3b\x36\x0d\xa1\xec\x7e\x83\x8e\xb2\xc7\x7c\x7c\xb7\xfc\x16\x4f\x7c\x46\x27\x01\x04\x89\xc8\x58\x90\x07\x52\xc9\x2d\x9d\x75\xad\x54\x71\x67\xe4\xbd\xd1\x1a\x07\xd2\x8b\x65\x1a\xa3\x0f\x16\xa8\x50\xe0\x60\xdd\x28\x82\xfb\x82\x09\x19\xa3\x98\xe8\x05\xeb\x63\x69\x9f\x4f\xf5\x95\xf9\x91\x52\x47\x31\x64\x1e\xce\x25\xfb\x3f\x8e\x89\xad\xa5\x01\x19\x2b\x1e\xdd\xae\xcb\xac\xc8\xb8\x98\x52\x8f\x2d\x5b\x33\x12\x69\x4f\x5e\xc2\xdc\x91\x42\xe1\x51\x3f\x77\x7a\x5c\x83\x34\x09\xc1\x71\x63\x3f\xf9\xfa\x26\x09\xd0\x49\x7f\x5d\xf4\xfb\xf4\x8e\xf2\xb7\x7d\x55\xe2\x55\x19\xd2\xee\x79\xb5\xfe\x9d\x8f\xa4\x60\x00\xde\xcd\xb4\xf2\x5d\xfb\x3f\x2b\xaf\xb1\x9f\xbe\x2c\xbd\xac\x00\x2a\x35\x9a\x95\x4b\xc6\x9b\xdf\xe2\xfb\x36\xad\xfd\x9a\x15\x09\xf3\xe3\xa4\xc6\xb1\xf3\xf3\x6e\x7c\xf8\x0d\x58\x3d\x44\x0f\xf2\xa1\x44\x64\x30\x98\x97\x4d\x71\x49\x3e\xcb\x64\x17\xc0\xb8\x06\x5b\xd2\xc2\x1c\x1e\x34\xaf\x09\x24\x3f\xb4\x9e\x9d\x35\x29\x7e\xb0\xa5\x2d\x56\xdd\x27\x0f\xea\x6d\xc5\xc0\x80\xa0\x55\x99\xf7\x85\x81\xe9\x0f\xd8\xcc\x4c\xd1\x1a\x50\x5e\xdd\xe8\x4b\x89\x2d\x89\x53\xbd\xbb\x23\x79\xd3\x3a\xad\x64\x65\x8a\xe2\x06\x07\xdd\x35\xb0\xbf\x3a\x26\x37\xd2\x0c\x3f\x86"}, +{{0xc2,0xe0,0x74,0xfa,0xa2,0x34,0xe9,0x9a,0xb2,0x0a,0xdb,0xbe,0xae,0x11,0xb8,0x10,0x97,0x23,0xb7,0x08,0xc5,0x45,0x86,0xdf,0x65,0x2b,0x40,0x2c,0x35,0xcd,0xd1,0x27,},{0x5e,0x52,0x4e,0xce,0x1c,0x69,0x6e,0x70,0x5a,0x35,0x14,0xdd,0x00,0x82,0xb8,0x40,0x79,0x5a,0x59,0xc3,0x6a,0x96,0xcb,0xc4,0x82,0xbf,0xf5,0xab,0x4e,0xf5,0x15,0xd1,},{0x65,0x7c,0x38,0x26,0xb3,0x48,0x3f,0xd4,0x2a,0xb6,0xdf,0x86,0x9d,0x1b,0x77,0xa8,0xc4,0xdf,0x67,0xa6,0xa5,0x90,0xc7,0xc6,0x77,0x29,0x69,0xe3,0xdf,0x33,0x12,0xae,0x06,0x54,0xfb,0x83,0x84,0x7a,0xf2,0x21,0x93,0x5a,0x05,0x12,0x29,0x16,0x36,0xec,0x05,0x95,0x70,0x08,0x79,0xeb,0xdb,0xa8,0xa1,0x46,0x7c,0x53,0xd4,0x0c,0x23,0x06,},"\x31\x29\x03\x38\xe4\x6d\x1c\xc2\x5c\xe9\x9c\xba\xcc\x40\x16\x03\x41\xb7\x85\x82\x3c\x82\x3c\x4a\xb9\xba\xee\x3b\x61\x25\x79\xf1\xc0\x11\x71\x67\x96\xe5\x6e\x26\x93\xf6\xdd\xad\x43\x92\x2a\xa7\x84\x7c\xbb\x41\x48\x10\x16\x51\xbb\xe6\x2d\x50\xbe\x90\x82\x5e\x8e\xab\x77\x7a\xa4\xb8\x02\x6d\xc5\x38\x5a\x97\xd3\xdf\x76\x16\x01\x91\xf9\x22\xcd\xd2\xf0\x7b\xa5\xf8\x5e\x95\xf4\x5d\xb2\x29\x28\xf9\x07\x34\xff\x52\x0c\x44\xdc\x8f\xe3\x90\x3b\x4c\x51\xcd\x23\xe0\x64\xf0\x1c\x82\x9e\xc7\x4f\xbf\xfe\x25\xfd\x0d\x36\x9d\x27\x65\x74\x0f\x43\x85\x6b\xd7\x39\x8a\x19\x11\xad\x74\x98\x36\x16\x0f\xd9\x8d\x04\xb2\x8e\xe8\x7e\x11\x1d\x40\x71\x8b\x5a\x16\x6f\x05\xc9\xa4\x71\xa4\x15\x66\x55\x70\x69\xf7\xa1\x4d\xe9\x88\xbb\xbf\x67\x77\x52\x1f\xcb\xa6\xdd\x65\xde\x4c\x06\x67\x4a\x11\x85\x3a\xf8\x3a\xcc\xb7\x0f\xb3\x28\xdd\x8f\xd6\x10\x5a\x7d\xf5\x26\x9c\x9f\xae\xc8\xd9\x00\x14\x7e\x92\x8d\x97\x0c\x36\xcd\x83\x4b\xd6\x05\x4f\x70\x65\x0d\xfa\xce\x94\xb7\x62\x9d\x16\xe3\x70\x3d\x76\x6c\xe7\x63\x8d\x0a\xd1\xe1\x7b\x77\x46\x9b\x95\x8d\x2b\xa2\xa1\xe6\x31\xa1\x63\x5e\xfd\xcb\x00\x6e\xbc\x6e\x5d\x8b\x9f\xaf\x7e\x5f\xb9\x89\xdc\x08\x96\xc5\x61\xa2\x6f\x3c\x25\xf0\x55\x71\x6b\x36\x71\x38\xea\x5d\xa1\xf8\x1d\xc7\x2c\xff\x7a\x55\xaf\xae\xe5\x83\x9e\xf5\xaa\x82\x2b\x29\x70\xaa\x18\xa8\x98\x21\x63\xbf\x5e\xed\x1b\x67\x7c\xca\xac\x12\x24\xff\x6c\x6c\xf2\x56\x37\x47\x80\xae\x65\x80\x3b\xf5\xc6\xe2\x3c\x80\xba\xcd\x76\xec\x3e\x2d\xdd\x3a\xb7\x19\x97\x50\x64\x48\xe1\x9d\xb1\x98\xef\xad\xc9\xf7\x57\x49\x1f\x1b\x09\x72\xc8\x2d\xb2\x94\x10\xe1\xe8\xbb\x67\xbb\xb2\x3d\x53\x56\x3b\x88\x07\xe5\xe0\xc2\xe3\x2e\xe5\x96\xb5\xb4\x40\x23\x28\xf9\xe1\x79\xe9\xce\x85\x6d\x3b\xd1\x99\xd5\x8d\xe6\xc5\xc2\x52\xe7\xa6\x12\x4d\x81\xfc\x9e\xea\xf2\x3d\x34\x7d\x2a\xb8\x89\x17\xaa\x68\x44\x50\xdd\x58\x30\x35\x16\xc1\xa4\xd2\xbd\xcd\xde\x22\x0c\x9a\xe3\x79\x0f\x29\x8d\x7d\x38\x4b\x70\xc2\xfe\x25\x88\x07\x84\x8f\xc3\x53\x20\xb5\x78\xb3\x35\x03\xb7\x5f\x38\xa1\xdf\x63\x0b\xd3\x3e\x6a\x85\xa4\xdd\x4d\xf9\xf6\xe5\x5a\x6e\x68\x67\xc7\x38\x01\xe5\x93\xe1\xd5\x91\xdb\x89\xba\x9a\x9a\xf0\xfc\x29\x2e\x06\xfb\x51\x5a\xc8\xa5\xe8\xe3\x43\xa8\x21\x33\x55\x75\xba\x48\xfb\xaa\xe3\xfb\x12\xde\xea\xae\xe6\x0f\x4b\x3d\x31\x7e\xc0\xa5\x54\xdd\xd4\x25\xc8\x49\x32\xc2\x7a\x7a\x12\xf2\x9d\x63\x71\x51\x07\x83\xbd\x75\xe6\x0e\x2f\x6d\xa2\x00\x52\x06\x9e\xd7\x1e\x69\x5a\x94\x31\x82\x19\x3c\xb6\x85\x1a\x7d\x2f\xa3\xc6\x66\xc1\x93\x02\x80\x15\xac\x8b\x7e\x7d\xaa\x6c\x52\x04\xf7\x7a\x62\x32\xb8\x8b\x4a\xbf\xfc\x53\x62\xfd\xe7\xde\xc3\x6b\x9d\x45\x48\x80\x84\x92\x83\xb1\x15\x63\x39\xea\x2e\x8c\x3b\x10\xe5\x1b\xfa\xbd\xf7\x25\x78\xc7\x26\x41\x9a\x38\x54\x2c\xf8\x64\x9d\xf9\xa0\x90\x9f\x58\x2d\xeb\xad\x5f\xd8\x9d\x8c\x81\xf8\x3d\x9e\x42\x3e\x75\x03"}, +{{0xb9,0xda,0x4e,0x6a,0xf0,0x7e,0x39,0x8a,0xb4,0xd2,0x17,0x52,0xa3,0x2c,0x8f,0xfa,0x9b,0xe0,0xc3,0x10,0xd3,0x50,0x59,0xfb,0x66,0x1b,0xd7,0x3a,0xfa,0x97,0xe2,0xa8,},{0xf8,0x62,0x80,0x3c,0x96,0xcc,0x42,0xad,0xc8,0x25,0x28,0x84,0x54,0x72,0x30,0xb9,0x70,0x04,0x7b,0x7e,0x5d,0xa9,0x96,0x26,0x0c,0xcc,0x02,0x40,0xab,0x71,0xa6,0xec,},{0x62,0x5e,0x1f,0x42,0xc8,0x74,0x34,0xa2,0x5d,0x62,0x2d,0x80,0xd1,0x25,0x32,0x80,0x6a,0xfb,0x25,0x09,0x33,0x24,0x49,0xe6,0x96,0xb6,0x5e,0x1e,0x58,0x88,0x50,0x8f,0x11,0xc4,0xac,0x25,0xf5,0x9b,0x8d,0x94,0xd0,0xbf,0x27,0xe4,0xc8,0xd1,0x86,0x70,0x07,0xc4,0x08,0xda,0x57,0x30,0x82,0xdc,0xf1,0x9d,0x15,0xa9,0xd5,0xcc,0xcb,0x0c,},"\x6b\x95\xaf\x0e\xeb\xb6\xa0\x8a\xfa\xda\xa1\x96\x21\xf7\x6a\x83\x9b\xe8\x08\x51\xc6\xdd\x31\x5e\x82\x76\xf5\x01\x99\x5d\x4c\xe6\xd1\x34\xdf\x5e\x79\x8e\xd5\x17\xa2\xf0\xe6\x2a\xa1\xd6\xc9\x8c\x36\xef\x14\xbb\x1e\x5d\xdf\xc9\x8d\x5a\x7f\xcc\x81\x14\x0a\x13\xc2\x0d\x2c\xa0\xc4\xb4\x0e\x6e\x6a\x03\xee\xd8\xc8\x99\xf9\xd1\xf7\x92\x46\x81\x52\x19\x9f\x4b\x95\xa4\x32\x66\x89\x47\xa5\x1d\x7b\x8e\x10\x4d\x8d\x1f\x12\xaa\xcd\x96\x7e\x08\xb0\x8c\x41\xc3\xc8\xca\x3f\xee\xda\xa5\xb8\xb6\x3b\xce\xc0\x61\x38\x64\xd9\x53\xd8\x11\x43\xec\x81\x42\x5b\xde\x29\x16\x4a\x08\x76\xf2\x3f\x37\xac\x9a\xc9\x47\x36\x72\xce\x11\xa0\x8b\xd5\x47\x6f\x6f\x66\xd6\x65\xe9\xad\x61\x7e\x34\xeb\x32\xee\x56\xff\xa4\x59\xf2\x0d\x1b\x93\x53\xd7\x82\x12\x98\x54\x57\x50\xc6\xef\xf3\xe7\xd4\x07\x3d\xc3\x18\x5e\xde\x03\x91\xcc\xe0\x57\x5f\x8b\xa6\x37\xd8\x00\x06\x8d\x9d\x7e\x54\x03\xba\x70\x38\xd2\xdb\x77\xda\x14\x47\x84\xf2\xe8\xea\x76\xae\xdf\xe5\x21\xe7\xdc\x6a\x67\x4e\xde\x35\x57\x95\x95\x99\x3f\xb2\x0d\x44\xb4\x05\x27\x83\xf5\x6c\x8c\x0b\xbd\x04\x40\xb6\x9e\xab\xde\x84\x46\x8d\xd1\x3c\x67\x1f\xb1\xbb\xd5\xcb\x02\x2c\x2a\x4f\xcf\x35\x42\xd8\xb3\xbb\x51\x8e\x5a\xde\xbd\xdc\x84\xe7\x14\xb1\x3b\xe5\x2c\x56\xb2\x82\xb4\x2a\xc0\x89\x2a\x54\x59\x28\x1b\xe7\x16\x07\x29\xf4\x11\x2c\x7d\x99\xdf\x9b\xe5\x43\x4f\x82\x3a\x9c\xe0\x50\x17\x89\xde\x1d\x55\x0a\xd5\x0b\xb1\x8c\x8d\x89\xa3\x36\x68\x27\x0b\xff\x7b\x91\xff\x11\x8f\x5c\xd9\x90\x9a\xdd\xde\x90\xc0\x24\xa3\xad\x71\x39\x15\x17\x46\x74\xf2\x8a\xaa\x9f\x94\xa3\x22\xba\xa5\x43\x73\x8e\xda\xb4\x97\x33\x12\xb5\xbf\xa1\x21\x55\xde\xbc\xee\x16\x3c\xfe\x2b\x04\xac\x9c\x12\x2a\xc8\xa4\xe1\xbc\x41\x8c\x14\x95\x5d\x96\x10\x45\x5b\xd9\x45\xe9\x79\x3b\x91\x62\x67\xc9\xc5\xf9\xe5\x3a\xc0\x45\x18\x92\x6e\xc9\x8e\xcb\x84\xa4\xf0\x44\x5d\xcb\x12\x36\xc7\x6c\x3a\x67\x8c\x69\xab\xe4\xe9\x2c\x22\x97\x1d\x62\x21\x72\x01\xa1\xbd\xf0\x5c\x04\xdf\x84\x20\xa3\xde\x6a\x91\x7a\x85\xe7\x1e\x2b\x97\x25\xe7\x7b\x52\x29\x15\xd4\xc9\x94\x60\x77\x63\x7c\x2d\x88\x13\xf0\x10\xb9\x49\x1c\xf0\xed\xdc\x3d\x46\x68\xcc\x0f\x8b\xc8\xa6\x83\x57\x9b\xe5\x43\x93\x4d\xa2\x85\x3a\x16\xf5\x71\x57\x24\xf7\x79\x81\x9f\x44\x43\x9e\x1d\xeb\xca\xa4\x27\x0d\x9b\x85\x94\xba\x4c\x86\xe1\x06\x3b\x3c\xe4\x79\xd7\x1a\x54\x09\xbe\xf2\x7e\xf4\xe5\xc1\xd1\xc9\x6e\x8b\xe1\x38\x65\xaf\x7b\xb4\x3f\x09\x16\x2c\xcb\xc8\x3a\x2c\xa9\xe9\xb8\xa2\x32\x4e\x6d\x99\x65\x75\xee\xfe\xd3\x7e\xf4\x99\x08\x18\x57\x38\xb8\xea\xe4\x3f\x8a\xdc\xa3\x30\xc9\x9b\xc6\x6c\xc1\xfd\x52\xc5\x30\xd7\x37\x1c\x60\x86\x9c\xe4\x2c\x19\x7d\xca\x0a\xd1\x28\xb8\x5f\x61\xc8\x75\x8f\x0d\x54\x2f\x3d\x32\x98\xb6\x5e\x93\xc6\xe8\xa6\x8f\xa0\xe9\xa1\xd5\xe8\xc5\xfe\xc8\x05\xb8\x3a\xff\x43\x90\xe1\x15\xeb\x64\xf3\xf0\x78\xa0\xb9\xb6\x6c\x27\x38\x43\xfc\x6c"}, +{{0x14,0x3f,0x7b,0x42,0x47,0xd5,0x49,0xf6,0xb7,0xc0,0x91,0x72,0x66,0xc5,0x0f,0x96,0x2c,0x28,0xa2,0xea,0x24,0x76,0x2f,0x53,0x7a,0xa0,0x6a,0xd1,0x5e,0x40,0xb3,0x5a,},{0xc9,0x95,0x9f,0x90,0xa2,0xd5,0xfe,0xac,0xba,0xe2,0xc4,0xc8,0x03,0xde,0xd5,0xde,0xab,0x86,0x98,0x76,0x37,0x06,0x43,0x37,0xaa,0x2a,0x0b,0x0d,0xde,0xf2,0xfd,0x86,},{0xc1,0xcf,0xae,0x58,0x51,0x57,0x13,0xea,0x72,0x8c,0xfa,0x09,0x09,0x0e,0x89,0x42,0xf8,0xdf,0x18,0x62,0x1b,0xa7,0x09,0x0e,0x3a,0x33,0x76,0xc3,0x80,0x27,0x75,0xa1,0xec,0xaf,0x43,0x6b,0x18,0x49,0x78,0x04,0x1e,0xbb,0x75,0x22,0x6f,0x97,0x0d,0xf7,0x1d,0x6a,0xd3,0x53,0xc0,0xfb,0x46,0x50,0x23,0xf9,0xe2,0x98,0xf6,0x4a,0x70,0x02,},"\xe2\x74\x20\x23\x47\xa0\xd0\x57\xa4\x8b\xf2\xa1\xf6\xe9\xf6\xcb\x42\x56\x07\x9d\x80\x03\x74\x09\x3c\x02\x0c\xbf\x52\x0e\x5f\xa2\x7f\xe9\x96\xff\x07\xf3\x3a\xd3\xb2\x1f\x74\xab\x0c\xd9\x3c\x86\x47\x5f\xf3\x7c\xf6\x22\xd3\xf9\xfa\x4d\x13\xbc\x99\xf0\x13\xe8\x50\x2b\x24\xe4\x6c\xc8\x7c\x47\xe6\xb2\xc3\x66\x2b\x50\xe9\x79\xa0\xf3\x45\xb7\x84\xff\x21\xa8\xa4\xd9\x2a\xdc\x65\xe8\x6e\x33\xb4\xdb\xe1\x7f\x52\x8c\xcd\xf5\xb4\x86\x46\x64\xba\x94\xff\xdb\x7c\x7d\x24\x12\xb4\x38\xe6\xe4\x3f\xa9\x66\x81\x47\xee\x33\x28\x22\x4d\x1f\x52\xa3\xf5\xb5\x43\x59\xb4\xf7\xfe\xf6\x9a\xf8\xf8\x67\xb4\x78\xf1\x30\xa1\x47\xbe\xa4\x2e\xd3\x98\x03\xbc\xbc\x25\x57\xbc\xa8\xc3\x99\x9f\x1d\x24\xf0\xa6\xb0\x3c\x98\x84\x60\x11\xf9\xec\x74\xf6\x66\x41\x7b\x95\x02\x0e\xb1\xfb\x2f\xb8\x8b\x63\x12\xe5\x00\x8c\xff\x03\xe2\xd7\x7a\x26\xaa\x53\x2d\x17\x80\xb5\x07\x7f\x9e\x8b\x82\x86\x74\x45\x5d\x6b\xc9\x57\x97\x5f\x7b\x2a\x50\xe7\xfd\x7c\x16\x12\xce\x02\x36\x2e\xfa\x4c\x55\x5a\x1e\xef\x68\xec\x34\xa5\xc0\x06\xa6\xda\x00\x8a\x31\xd4\x19\x3d\xc2\xcc\x64\x76\x85\xad\x3c\xfa\x3b\xd7\xc5\x60\xb7\xae\xd4\x5f\x0f\x1a\x3d\x1b\x5b\x36\x22\x68\xde\x53\x28\x57\x05\x5a\xb9\xd1\xd5\xd8\x58\xd9\xae\x9a\x75\x9a\x51\xbb\x94\x78\xe8\xf0\xee\x93\xc9\x84\xb5\x76\xb8\xb4\xab\x46\x02\x80\xbe\x3d\xe2\x05\xa3\x2f\x1d\xc3\xd5\x72\x92\x3f\xb2\x13\xac\x15\x12\xd8\x0e\xb5\xad\x5c\x18\x94\x4b\xe7\x7f\xc1\x7d\xef\x13\xa6\x1b\xbd\x31\xbc\x71\xac\xc2\x3d\x25\x0e\xc5\x89\x4e\xbc\x21\x4c\xfe\xc0\xc1\xb9\x06\x51\x6d\x32\xd8\x36\xad\xc8\x38\x80\x2e\x8d\xe3\x0d\xd7\x6d\xf6\xe6\x1c\x1b\xc4\x38\xb6\x8d\x2b\x02\x5a\x84\xf2\x11\xfa\xcf\x3f\x13\x84\xd2\x61\x2d\x0f\xae\xf5\xd1\x71\x31\xcf\xe0\xcf\xe8\x33\xfe\x95\x0e\x47\x9b\xc2\x9c\xbe\x7f\xd6\xda\x0c\xce\x30\x7c\xf0\xb1\xbd\x92\xc8\x0e\x87\x8e\x43\x2f\x63\x6e\xa0\xcd\x42\x48\x0c\x07\xe8\xb8\xe5\x7e\x69\xb2\xf9\x38\xb7\x81\x20\xf6\xaf\x4a\xbe\xbf\x7d\x4b\x05\xca\xcd\x6e\xed\x85\x44\x91\xc0\x29\x75\x5c\x4e\x66\x33\x89\x93\xed\x2a\xc2\x5d\x19\xa0\xc5\xb4\x0f\x5e\x32\xc8\xa8\xb1\xbc\xe3\x69\x71\x81\x86\xc9\x1d\x60\xed\xff\x24\xa8\x37\x7a\x99\x69\x75\x75\x99\x06\x7d\xd3\x12\x63\xa0\x6d\x6a\x61\x15\x47\x81\xf2\x96\x11\xab\x81\x2f\xf8\x2e\x81\x37\x39\x64\x62\x63\x70\x4c\xd6\x04\x63\x57\xa2\x3c\x04\x5e\x24\x07\xb7\xa8\x95\x08\x25\x93\x91\x31\x4f\x2f\xbe\xe4\x9a\xef\x08\x55\xc6\xe5\xe6\x3d\x91\x2a\x19\xdf\x15\xb1\x1e\xce\x34\xe2\x76\xdc\xb8\x8b\xf2\xf2\xe4\x75\x63\x58\xf3\x4a\x0e\xe3\x95\x2b\x68\x6f\xcd\x17\x57\x8a\x88\x41\x76\xd3\x4e\xa2\x91\x6c\x5d\x9f\xcd\x00\xeb\x9e\x0a\xa9\xf2\xcf\x0f\x16\xe2\x56\x4b\xfd\x28\xb6\xab\x59\x68\xb8\x44\x8f\x06\x83\x20\xe4\x18\x71\x60\xf8\x66\x57\x81\xb1\xe2\xed\x9d\x04\x9e\x1b\x54\xa7\xd7\x27\x20\xff\x9d\x4f\x07\x30\x51\x99\x6a\x9d\xb6\xf0\xc6\x82\x1c\x42\x4f\xa5\x1d"}, +{{0x0d,0x1f,0xe9,0xd8,0xb9,0xa2,0xf0,0x4c,0x22,0xbb,0xb0,0xed,0xea,0x38,0x33,0xa0,0xce,0x43,0x33,0x93,0x47,0x53,0x1f,0xdb,0x67,0xed,0x51,0x3a,0x13,0xd3,0x6b,0x39,},{0x67,0xc4,0x9f,0x41,0x0f,0x48,0x53,0x29,0x3d,0x0c,0x4d,0x39,0xf4,0xc1,0xb3,0xd6,0xc6,0x10,0x3c,0x5c,0xfe,0x20,0xa9,0xa5,0x9b,0x53,0x93,0x20,0x43,0x51,0x73,0x69,},{0xb0,0x57,0x25,0xe7,0x37,0x1e,0xd0,0xa9,0x1e,0xbc,0x89,0xf3,0xc3,0x0b,0xaa,0x99,0x18,0x37,0x63,0xed,0xb4,0xce,0x34,0xfe,0x90,0x1a,0xf3,0x73,0x1e,0x00,0x1c,0xc5,0x4f,0x28,0x71,0x18,0x91,0x5e,0x90,0x36,0x5d,0x91,0xac,0xa8,0xfe,0xb1,0x70,0x87,0x69,0xf9,0xf1,0xd6,0xee,0xf5,0xaa,0x11,0x3b,0xee,0x00,0xb5,0xef,0xab,0x27,0x04,},"\x64\x21\x7a\xc8\x41\xfd\x4d\x64\x59\xbf\xc4\xa4\x9b\x88\x01\xd6\x92\x9b\xf1\x9b\x40\x8e\x8a\x53\x79\x0c\xeb\x51\xec\x34\x1f\x9b\x46\xa3\x51\xe8\xc2\xe5\x9d\x88\x7e\x1e\xac\xcb\x91\x42\x31\xcd\xca\x1d\x3e\x5c\x47\xd1\x66\xb4\xcd\xb9\xb5\x8c\x01\x3c\x59\xa3\xbd\x28\x3a\xd1\x0f\x6b\xd6\x2c\x0f\x15\xf7\x64\xce\x14\xf3\xb2\x65\xf5\x37\xc6\x3e\x73\xb6\xc4\xfa\x65\xe0\x6c\xe1\xe1\xf4\xae\x0d\x11\x48\x9d\xd2\x60\x2f\x95\xfc\x40\x2b\x77\x12\x05\x2a\xbc\x84\xbd\xc7\x78\xc1\x9f\x10\x00\x1b\x4e\x0d\x5f\xbe\x46\x30\x90\xe8\x3e\xf4\x38\xfe\x06\x8f\x3b\xb6\xfb\xc2\xc1\x39\xaf\x06\x78\xed\x2a\x11\xfa\xa1\xb9\xe4\x9a\xaa\x46\x20\xab\xfc\x08\x43\x9f\xbf\xe2\xc6\x18\x40\x76\x9e\x5f\xda\x26\x77\xf8\xe2\xf0\xa1\x45\x64\xf9\xf5\x04\x23\x2a\x9f\xc0\xd9\xda\x47\x1e\x67\xfb\xc5\x74\xc3\xd5\x6d\x2a\xeb\x93\x7a\x58\x6e\xd5\x58\x35\x56\x30\x8a\x99\x8e\xb1\xdc\x47\x6a\x01\x4f\x5a\x08\x22\x8d\xbe\xd9\x5a\x12\x08\xbc\x1d\x1f\x5d\x76\xb4\xe8\xd0\xb2\x43\x4b\x99\x5a\xd4\x58\xe4\x29\xee\x61\x42\xa0\xc9\x71\x76\x8c\xc4\x0c\x40\xbc\xb0\x8e\x96\x03\xf0\x96\x11\x47\x44\x71\xb3\x85\x9d\x7f\xd5\x84\x21\x9f\x02\x65\x7b\x43\x0e\x9e\x56\x95\x5b\x34\x67\xac\x56\xff\x2e\xab\x22\xcc\x49\x84\x89\x03\x6a\x57\x41\x20\xe2\xdb\x76\x9a\x3b\x21\x50\x03\x89\x14\x2c\x78\xa8\x7d\x06\x9f\x0e\x25\x76\xca\xfd\xa8\xcd\xdd\x79\x15\xa9\x22\x87\x73\xd2\xac\x9a\x07\x5c\xb3\x87\xf2\xa8\x98\x61\x72\x13\xb2\xcc\x50\x59\xd1\x19\x41\xbc\x4f\xe5\x86\x41\xe7\xc1\x75\x02\x67\xe5\x3e\x99\xc4\x21\xcb\x4c\xf2\x1d\x09\x8c\xa2\xd1\xf4\x16\x44\xf7\x90\x89\x83\xeb\x17\x4a\x23\xa7\x81\xcf\x15\xef\x38\xeb\x91\x16\xed\xa4\x12\x3a\x15\x22\xf5\x3b\x81\xfb\x73\x68\xe8\x07\x5f\xb8\x38\x59\xd2\xcf\x98\xd9\x21\x53\x5a\x70\x9f\xaf\xa9\x87\x3c\x4a\x03\x9a\xae\x68\x2f\x7e\x62\x86\xb8\x99\x25\x7c\x09\x24\x01\x6c\xa5\xbf\x6d\x31\x69\x09\x92\x11\xa9\xa4\xa6\x74\x5c\xdd\x31\x98\xf1\x33\x7f\x60\x92\x82\x27\xce\x3c\x7d\x60\x96\x0b\x53\xde\xdf\x01\x1a\x89\x40\xf5\xc4\x68\x20\x7a\x38\x94\xbb\x08\x72\xb3\x33\xcc\xde\xc9\xd5\xec\xd9\x11\xec\xbb\xb9\x6c\x9b\xc4\xbd\x48\x75\x32\x0e\x4d\x3e\x9c\x02\xd9\xdc\x76\x10\x9e\xc4\x5e\x61\xd1\xcf\x5a\xc7\x29\xf2\xe3\x4a\x96\x47\xb9\x5b\xce\x70\xb0\xc6\x33\x17\x1a\xda\xf0\xdf\xdb\x5a\xfb\xa4\x03\x5b\x3c\xce\x8c\xb7\x14\x1a\xd1\x42\xbb\x7a\xdd\x4f\xc3\xf9\x61\xd4\x2d\x72\x03\x75\x4a\x4e\x31\x32\x21\xd4\x87\x83\x1e\x32\x94\x7d\xa9\x11\x38\xab\x64\x8b\x59\x52\xef\x69\x56\xe2\x7a\xa5\xd2\xc1\x75\x79\x4b\xf8\x1e\xf2\x77\xfa\xa6\xb9\x05\xe1\x45\x02\x86\x68\x87\xd8\x78\x80\x60\x6e\x81\xb2\x7a\xf0\x1b\xb2\x63\xec\xf2\xc5\x82\x05\x85\xea\x6c\xe8\xd8\xb3\x91\xd8\x6f\xce\xda\xdc\xd1\x1f\xdb\xb5\x66\xfd\xf1\x47\xf4\x02\x01\x0f\xc3\x5f\x51\x57\xe0\x36\x14\x6b\x37\x36\xc8\xa4\x33\x59\x12\x7c\x26\x1f\x6b\xf0\xca\xd3\xbd\x8a\x34\xcb\x15\x09\xf7"}, +{{0xc1,0x0b,0x5a,0xc6,0x05,0x5a,0x1d,0xdb,0xca,0x28,0x55,0x2e,0x5c,0x72,0xeb,0xd0,0x52,0x78,0xc9,0x22,0x39,0xb2,0xfc,0xd0,0xc1,0x35,0x36,0x51,0xa8,0xe5,0x59,0xa0,},{0xb2,0x18,0x3e,0x1b,0x00,0x81,0x6d,0x29,0x30,0x5f,0x74,0x68,0xe7,0xe4,0x5e,0xed,0x3f,0xd8,0xf2,0x3c,0x15,0xb3,0x05,0xf9,0xfd,0xa9,0x3e,0x81,0x2d,0x65,0xbc,0x27,},{0x8a,0x9a,0x32,0x17,0xfd,0xf0,0x64,0x3a,0xaa,0xa5,0xc8,0xfb,0x2a,0x88,0xa5,0x56,0x39,0x88,0x59,0xb8,0xfe,0xef,0xbc,0xb4,0x8c,0xcd,0x88,0xe5,0x85,0xa1,0x67,0xc9,0x4d,0xbb,0x5c,0x0c,0xad,0x24,0xd1,0x5b,0xca,0xbb,0xc1,0xed,0xb2,0x1f,0x02,0xa8,0xc4,0x57,0xc5,0x61,0x20,0xa3,0x23,0x4a,0xc3,0x35,0x77,0xb9,0xaf,0x2d,0xdc,0x01,},"\x35\x94\x90\x5f\x9e\xa4\x64\x61\x5f\x41\xb8\x7a\xbb\x9d\x16\x73\x37\xf2\x9d\x45\xd9\x7f\x7a\x14\x64\xec\x9f\x2e\xe5\x0f\x90\xf2\xe6\x73\x39\x87\x4d\x3f\x20\x93\xbe\x92\x26\x10\x77\x01\xec\x1a\xab\x94\x1c\x4e\x05\x9f\x1b\xb2\x6c\xe8\x6e\x14\x8d\x1d\x9f\x0d\xa2\xa2\xa0\xf9\x82\x9a\x36\x4f\xb4\xf1\x3f\x58\xb9\x60\xd0\xf8\xd7\x23\x23\x28\x3c\x44\x90\xef\xdf\x57\x87\x86\x45\x89\x0f\xf7\xbc\x50\x65\xda\xd6\xe5\x1d\xd1\xe5\xb9\xa5\x07\x51\x50\x97\x8b\x33\x67\xf1\xba\x84\xe4\x5f\xf1\xf1\x27\x6c\x57\x6e\x4b\xc7\x2b\xe8\xaa\x8e\x40\x5f\xc2\xb2\x7f\x81\x46\xb9\x99\x84\x5f\xaa\xa0\x59\x5d\x3c\xb7\x0e\x5d\x37\x12\xed\x54\xa0\xfb\x3e\x32\x2d\x45\x38\x0b\x5d\xe3\x60\x9b\x96\x7b\x95\x9b\xca\x5a\x58\x3c\xc5\x20\xcd\xcb\x7b\xcb\xb8\x29\xaa\x25\xd7\x93\x20\x95\xec\xb3\x03\x92\x3c\x25\x60\xaf\xc3\xfd\x73\x24\xb7\xb7\xac\xd0\x89\xa9\xf0\x0c\x03\xa7\x3d\x04\x3d\xc0\xcf\x0b\xa0\xd8\x41\x1e\x2b\x1b\x18\xd2\x1d\x2a\x32\xa7\x26\xa5\x30\x59\x14\x0f\x78\x4f\x7c\xed\xf2\xf3\x3c\xec\x66\xfe\x4a\xd5\xcc\x9e\xac\xcb\xe4\xae\x10\x03\x6a\xc3\x52\x3b\xac\x70\x0a\x11\x3a\x98\xb5\x98\xe6\xdf\x03\x04\xc6\xfa\x32\x12\xac\xc0\x4c\x4e\x3c\x7f\x66\x87\x36\x2e\xf8\x6d\x61\x7c\x6d\xd4\x83\xf8\xd8\x0c\xea\x66\xd1\x95\x11\x27\x42\x8a\x61\xc1\xe1\x55\xa6\x85\x0b\xb2\xaf\xb7\xf9\x1c\x82\xd7\x3e\xb2\xb0\x54\x3e\xe8\xfc\x1f\x38\xe1\xdc\xdb\x3c\x50\x3d\xdc\x9b\xa0\x81\x24\x56\xa5\xce\x2e\x11\xd5\x56\x48\x7a\x64\x69\x74\xa7\xbb\xf8\x6e\x80\x6c\x58\xc6\x8c\x42\x69\xa7\xc9\xbb\xca\xc0\xff\xef\x98\x35\xb3\x3d\xc4\x49\xa7\x54\x79\xec\xd2\x3f\x6d\x14\x9c\x1e\x5e\xa8\xb6\x92\x08\xff\x36\xe5\xfb\xd6\x82\x95\x55\x03\x18\xbf\xa0\xd3\xb1\xd6\xc1\xad\x42\x70\xbc\xab\x09\x04\xae\x53\x49\x1f\x9b\x1c\xa5\x02\xe0\x12\xee\xd7\x7c\x42\x7d\x49\xa0\x96\x2f\x10\x55\x12\x5d\xd7\xb5\x37\x33\xd8\x52\x89\x34\xb5\x58\x0d\xd5\xfd\x5b\xbe\x85\x49\x78\xba\xe3\xd2\x5b\xb4\xae\x94\x4e\x90\x65\xe8\xe2\xe0\x79\x46\x51\x8a\x6f\x54\x8e\x36\xe0\x56\xbe\x82\x4d\x9e\x02\xa7\xa3\xea\xad\xd3\x79\x29\xf5\x81\x01\xcb\x18\x53\xbe\x3d\x75\x47\xf5\x8f\x49\xe3\x8b\x01\x8a\x74\x8d\x3f\x19\xc4\x85\x82\xab\xbd\xbe\x95\x3a\x8a\x25\xba\x9d\x36\x5d\xea\x83\x59\x35\x89\x9c\x19\xfb\x0b\x51\x90\x6a\xa9\x72\xc5\xac\x45\xe9\x9c\x40\xb3\xb7\x6e\x35\xd3\x27\xe3\x21\xe8\xae\x23\x06\xa6\xeb\x3d\x8c\xb6\xec\x2f\xa5\x39\x9a\xdd\x19\xea\x00\x28\xa0\x17\x92\xc0\x8e\x27\xc1\x6c\xf4\xf8\x5a\xaa\xae\x72\xf9\x86\xb0\x99\xf9\xeb\xe4\xad\x0b\x25\xd0\x6d\x3d\xe4\x4a\x8b\xfa\x52\x84\x4b\xe4\xa9\x39\x44\x83\x3c\xe2\xad\xd5\x1b\xb5\x54\xb3\x56\xa7\xdc\x49\x74\x8d\xd4\x5a\xe7\xec\x9e\x8d\xb4\x26\xc9\x7a\x25\xda\x5e\xdd\x3b\x62\x1e\x4a\xdb\xde\x48\x19\x7a\x33\x14\xde\x1c\x50\xf4\xd6\x00\x20\x27\xdd\x75\x19\xdd\xe3\xe1\x57\x29\xe4\x86\x95\x5a\xc4\x0d\x9d\x66\x87\x6f\x90\x66\x8c\x68\x9d\x8a\xb5\x98"}, +{{0x06,0x1b,0xdd,0xab,0x28,0x0b,0x0f,0xdc,0xb2,0x6b,0xfd,0x9a,0x0f,0xc7,0x21,0xf6,0x8f,0x88,0x34,0x3b,0x5d,0x39,0x83,0xa1,0x6b,0x6d,0xfa,0xa5,0xe7,0x69,0x69,0xf3,},{0x81,0x55,0x78,0xbb,0xa6,0xe7,0x07,0x0e,0xbd,0xec,0xa1,0x17,0x56,0x8b,0xd7,0x7e,0xbf,0xf9,0xe1,0x4c,0xb8,0xbc,0x20,0x0c,0x32,0xbd,0x87,0xdb,0x1f,0xb3,0x7d,0x6c,},{0xb8,0x32,0x97,0xcc,0xdd,0x6d,0x00,0x98,0xeb,0xf5,0xd1,0x32,0xd1,0x74,0xde,0x19,0x58,0x31,0x1a,0x76,0x6b,0xcc,0x4d,0xa1,0x5f,0x86,0x4d,0x80,0x1f,0x38,0xe0,0x9d,0x61,0x3e,0x7a,0xa8,0xc3,0x36,0x30,0x27,0x35,0xd7,0x5b,0xe4,0x16,0x6d,0x73,0xb0,0x18,0x4b,0x0e,0x0b,0xc5,0xef,0x39,0xed,0xbc,0xcb,0x6e,0x0e,0x61,0xaf,0xeb,0x0c,},"\xee\x76\xb4\x0c\xd4\x29\xea\xc7\xbc\x12\x83\x9c\xa2\xf7\xcd\x31\xf1\xe0\x09\x8a\x39\xc5\xfc\x19\x80\x5b\xe0\x33\x1f\x44\x79\x9e\x31\x8d\x12\x57\x1f\x06\xe2\x99\x37\x53\xa3\x68\x5c\xd2\xa9\x6b\x23\x01\xe2\x00\x24\x20\x9a\xdc\x5a\xdf\x74\x79\xff\x90\xc4\x77\xc3\x69\x5a\xbb\x99\xbd\x28\x57\x9d\xbc\x78\x31\xa1\x92\xbe\xed\x0c\xe1\x7b\x03\x8b\x20\x76\x48\x00\x65\x3a\xf7\xaf\x02\x4e\x2a\x10\x4e\xd0\xf3\xe5\x2d\x4b\xbd\x3e\x10\x9c\xf1\x26\x29\x1f\x49\xb0\xa2\x1b\xe4\x33\xc1\xc5\xa2\x58\x9e\xa5\x72\x99\x7f\x63\xd2\xbb\x39\x72\xd5\x32\xbe\x35\xa0\x47\x1e\xf0\x57\x3d\x79\x5c\x07\x2b\x6a\x86\x85\xb9\x5e\x47\xb0\x9e\xa9\xf4\x75\xd9\x3b\xf1\x2b\xbd\x77\xb7\xd2\xbf\x5d\x5b\xdd\xf0\xae\x02\x37\x53\x71\xd1\xd7\x99\xea\x92\x04\xbe\x38\x9e\x6a\x8e\x5d\xee\xdc\xd4\x92\x02\xe9\x2d\xf7\xc3\xe7\x61\xf9\x2e\xf8\xd7\x9f\xa7\x38\xd2\xc5\xbc\x28\x0e\xd3\x28\x79\x83\x2f\xf2\xb0\x26\x42\x45\x89\xcd\xbd\x52\xd1\x5b\x60\xf2\xaa\x35\x26\xb8\x98\x84\x9a\x34\xa8\x5f\xf1\xc4\x7d\xc6\x55\x4b\x85\xac\x76\xaa\x79\x35\xcb\xf3\xf7\xbc\x80\xad\x00\x91\x92\xa8\x75\xca\x20\x9b\x40\xfe\xb0\x47\xcc\x44\x69\x68\xf9\x70\xda\x47\xb8\xcd\x67\xda\x7e\xb4\xe5\x4a\x0e\x5a\xb2\x0c\xb3\x5b\xc6\xfb\x7f\x13\x30\x7c\xe6\x7e\xb6\x20\x4a\x67\xce\x9b\xb1\xd1\x39\xc1\xb4\xbd\x5d\xbe\xd5\x80\x10\xc8\x7b\xf8\x31\xe6\x52\x2e\xe1\x82\xda\xd9\x45\x80\x4b\x76\x7c\x4d\xf2\x55\x4f\x15\xb9\xe9\xaf\xd2\x59\x9e\xf2\x58\xc6\x7a\x22\xca\xeb\x92\xa5\x79\x88\x00\x6b\xbc\x72\xc1\x04\xfa\xc7\xe5\x41\x3c\xd3\xd3\xb8\x02\xc8\x3e\x63\x9e\xaf\xe2\x12\xa3\x8b\xb7\xef\x77\x9a\xf1\xa9\x4e\xe1\x37\xf6\xc6\x06\x67\xbc\x48\xf2\x7b\xf4\xa2\x22\x41\xbc\x44\xbb\x60\x33\x83\x62\x39\xbd\x6e\xaf\x3e\x2e\x22\x31\x87\x84\x1e\x46\x41\xb0\xf4\xe9\xff\x8d\x5a\x41\xdd\xbe\xab\xb4\x13\x8f\x6b\x58\x5a\xce\x0f\xb6\xb5\x3d\xc3\xc9\xed\xc0\x37\x3b\x60\x47\xf2\x7d\x83\x5e\x8e\x24\x66\x44\xfd\x83\x2c\xcf\xe0\xdf\x25\xc3\xd7\xda\x18\x7c\x9f\xa0\x54\x20\xd4\x34\x55\xf2\xd0\x8b\x57\x19\x29\x38\x6b\x59\xc6\xe0\xe1\x0a\x35\x60\x1d\xa8\x99\xb1\xb4\xdc\x3d\x95\xb6\x7d\xd9\xa8\x38\x18\xb0\xa3\x18\xbf\xdd\xa0\x64\x64\xb4\xa4\x2d\x3c\xb9\x85\xf3\x0e\xc9\x7d\x6a\x2a\xf1\x32\x91\x15\x5d\x60\xce\xc5\x7c\xbd\x58\xd5\xcf\xcb\x35\xc1\x85\x35\xe8\xd2\x99\xb5\xb0\x07\x59\x08\x92\xea\x94\x9d\x1b\x13\x7a\x62\xb3\x9a\x43\x6c\xd7\xe5\xb9\xf8\xd1\xb6\x93\x8d\xba\xa6\x2c\x22\x68\xd4\x59\xc6\x22\x0a\x3e\x6f\xcb\xf8\x0b\xa0\x11\x8a\xcd\x23\x42\x56\x3f\xbd\xbc\x1f\x7c\x9d\xba\x7e\xa2\xc0\x72\xaf\xc8\xae\x21\x28\xe3\xeb\xca\x06\x44\xff\xd8\x16\x3e\x80\xa1\xa5\x57\xd9\xd3\x90\x34\xcc\xd9\xdb\xd1\x2c\x88\x55\xa6\xf9\x16\x5b\x08\x01\x83\x9c\xf6\xe0\x7a\x9f\xba\x4c\x64\xd9\xc0\x99\xe1\x54\x10\xe2\x90\xe6\x77\x03\x1b\x65\xcf\x7d\xeb\x00\x79\xbd\xad\xc5\x73\xcc\x05\x6d\x76\x66\xd9\x5d\x03\x3a\x0b\x6b\xdb\xa7\xec"}, +{{0x2c,0xab,0x5b,0xf5,0x5f,0xfa,0x91,0x4e,0x9a,0xd0,0x76,0x22,0x19,0x0d,0x34,0x3e,0xc5,0x5c,0x13,0xcd,0x91,0xb3,0x88,0xcb,0x75,0x00,0xff,0xe0,0x6d,0xf7,0xc1,0x80,},{0xb6,0x1e,0x43,0x2b,0xb9,0x7c,0xba,0xe3,0x88,0xa2,0x57,0x8a,0x74,0x84,0x99,0x8e,0x00,0xe9,0xad,0x3d,0xdf,0xd6,0xca,0xb8,0xd3,0xa5,0xfc,0x5b,0xa0,0x43,0x07,0xc8,},{0x4c,0xf0,0x8f,0x4f,0xab,0xbd,0x06,0xdc,0xcb,0xcc,0xe2,0xa7,0xa5,0x94,0x1f,0xe9,0xaf,0xdd,0xc4,0xd2,0xd0,0xbc,0x80,0x80,0x2e,0x93,0xb1,0x2c,0xb1,0x35,0xd3,0xac,0xf6,0x51,0x1e,0x0f,0xe4,0x11,0x3c,0x5e,0x3c,0x55,0x41,0xb2,0x7d,0x3a,0x21,0x50,0xa7,0x57,0x74,0x2a,0xc6,0x5f,0x95,0xa9,0xce,0x66,0x73,0xff,0x0c,0xd2,0x1c,0x0f,},"\x2c\x2d\x04\xdc\x3a\xd1\x98\x23\x59\xec\xd5\xbc\x3e\xe0\x35\xf3\x49\x8e\xed\xff\x61\x04\xa9\x3c\x60\x2a\xf2\x17\x9a\xeb\x2c\xb1\xf4\x1c\x5c\xdb\x0a\x77\xb1\x24\xf9\x46\xaa\x8a\x82\x4a\xa3\x07\x6c\x2e\x1a\xcf\xd4\x8f\x68\x07\x0b\x26\x27\x6a\x65\x6b\x4a\x47\x58\xab\x15\x1a\x6a\x9c\x41\xbd\x74\xe0\x9b\xbd\x9a\xdc\xce\x1e\x87\xa0\xa8\x0d\x17\xfd\x92\xe8\x5e\x4b\xda\x47\x2c\x98\x8b\x6b\xb1\x18\x3b\x7e\xe5\x9a\x09\xd8\x05\x70\x46\x6d\xb9\x0d\xd3\x74\x95\x79\xc4\xeb\x19\xab\x75\xfc\x15\x2e\xcd\xcd\x68\xcd\x10\x78\xef\x06\xe5\x93\xc7\x35\x16\xfa\x82\x91\x48\x1a\x66\x7d\x3f\x95\xbf\xeb\x14\x4b\xab\x59\xd6\xdd\xc7\x3a\x27\x95\xc1\x01\x7e\x09\x53\x6b\x31\x62\xe4\xbc\x58\xf8\xea\xd3\x89\x57\x01\x8c\xfe\xc7\x2b\xad\xbf\x22\x81\x9a\xb0\xb4\x06\xc6\x47\x30\xfc\x73\xfd\x9e\xe6\x1f\x74\x18\x7e\xda\x91\xed\x4e\x79\x93\xe6\x68\x84\xaf\x43\xef\x4c\x6b\xf7\xf7\xc3\x79\xe8\xf0\xf6\x3d\xcb\x80\x41\xe2\x6b\x8b\x82\x92\xb6\xb6\xd1\x90\xe4\xad\xf4\x30\xfa\x82\xdd\x74\xc5\x73\x85\xb9\x19\xc4\x46\xdb\x37\xb5\xe8\x76\x7e\x4a\x0c\x95\x01\x3b\xe8\x9b\x2b\xc4\xe9\xfd\x62\x75\x4a\x84\x44\x18\x40\x09\x68\xae\xd2\xdd\x32\x8d\x7b\x1d\xc9\x1e\x1a\x2b\x30\x09\xdc\x7a\xd1\x40\xa0\x68\x6f\x67\x31\x68\xa6\x0e\x88\xd8\x0c\x52\x0f\xc2\xdc\xfc\x56\xca\x9d\x4b\x0c\x88\x85\x90\x99\x23\x07\x14\xde\xc8\x3d\x26\xb4\x63\x05\x54\xdc\xb9\xc4\x90\x18\x95\xf7\x8f\x38\x34\xb0\x97\x66\xb6\x7a\x46\x5d\xe8\xc9\x49\x00\x65\xbf\x56\x83\x39\x24\x33\x99\xfd\xc9\xd5\x10\x03\x24\x66\x7c\x5a\xb2\x8f\x35\xc0\x0f\x61\x25\x63\x8e\x61\xda\xb7\x0d\x1e\xec\x48\x95\x1d\xe0\xfb\x3f\x7b\x23\xd3\xcd\x98\x24\x37\xc6\x34\x73\x41\x5b\xef\x37\x4a\x66\x32\x96\xf2\x98\x6b\x1a\xe9\x57\x9b\x9f\xfc\xe7\x1e\xc3\x5e\xec\xa1\x16\xd1\x94\xf8\xfb\xa9\xa4\x5a\x91\xba\xe2\x7a\xc4\x55\xdb\x71\xa6\xb0\x1a\x72\x9d\x0c\x13\x5f\xcd\xcb\xc2\x3e\x50\x4a\x29\x43\xc0\x0a\xa4\x20\x70\x51\x9d\x9c\xd7\x7a\xe6\x75\x4f\x31\xeb\x46\xa3\xe5\xbe\x9e\xeb\x3f\xc8\xd3\x1f\xf1\x82\xda\x9b\x08\x7b\xe3\x46\x2c\x84\x59\x12\x6e\x86\x29\x09\x23\x2f\xd5\xf2\xd8\x9c\x01\x81\x59\x57\x61\x1e\x6a\xe7\xca\xa9\x8b\x60\x53\x77\x6a\x77\x15\xc2\xf9\x3c\xcf\x03\x08\x87\x03\x0c\x56\xc2\xb8\x22\x6d\xae\x29\x77\x99\x5a\x6d\x3f\x1e\x9d\x79\x11\xa9\xc9\xd2\xa3\x03\xf0\xe0\x1f\x32\x33\x8e\xfd\xaf\x8e\xe6\x3f\xc4\x1b\x25\x39\x9c\xff\xd0\xb3\x5f\x7e\xe5\x67\x6b\xd8\xfd\x3d\xa2\xcb\xee\x4a\xe2\xea\x98\x08\xd7\xe7\x35\x83\xd9\x94\x33\x99\x31\x46\x67\x4a\x40\x40\xf4\x2f\x63\xd1\xb3\x13\x5c\xc7\x97\xa8\xd8\xf0\xb8\x85\x73\xa3\x28\x90\x69\x6c\xac\x94\x39\xd1\xe1\x5d\x19\x6d\x90\x90\xb6\x2b\x6d\xb7\xe6\x3c\x96\x47\x2d\x94\x6e\x66\x8c\xbd\xa1\xf4\xdb\x88\x93\x00\xcd\xcc\x25\xe8\x4c\x9f\x38\x57\xd1\xd9\xe5\x32\x41\xcf\x62\x5f\x39\x09\xaf\x1c\x8a\xaf\xf4\x30\x9f\x68\xf6\x54\xb7\xa1\x5b\x67\x71\x1c\x5b\x7f\x9d\xe7\x67\x75"}, +{{0xdd,0x7b,0x59,0xa3,0x3d,0x97,0x0b,0xef,0x62,0xe0,0xe2,0x1a,0x7b,0x6e,0x4c,0x30,0x96,0x06,0x86,0xf1,0x7f,0x49,0xaf,0xdb,0x4a,0x9f,0x4e,0x80,0x8e,0x35,0x5c,0x7f,},{0x53,0xa0,0xe5,0x72,0x77,0xd9,0xbb,0xee,0xcf,0x99,0xc4,0xd1,0x38,0xfd,0x66,0xfa,0xfc,0xae,0xc7,0xbc,0x5f,0x56,0x7f,0x83,0x20,0x80,0x0c,0x4e,0x58,0x4f,0xf8,0x2e,},{0x87,0x29,0x4d,0x22,0xd4,0xad,0x0d,0x08,0x14,0xe2,0xd6,0xd5,0xfa,0xf5,0x57,0x49,0xe9,0xb3,0x98,0x03,0xb4,0xd4,0xb7,0x87,0x9e,0x60,0xb7,0x77,0xc1,0xfc,0x41,0x58,0x4f,0xe1,0x51,0x35,0xba,0x11,0x23,0xff,0x5f,0x20,0x0d,0xb3,0x5a,0x34,0x68,0xdd,0x4d,0x58,0xda,0xd7,0x7b,0xd9,0x6e,0xe2,0xb8,0x88,0xa5,0xa8,0xb1,0x8c,0x32,0x04,},"\x75\x58\x03\x67\x93\x05\x18\x16\x8b\x0a\x76\x4d\x09\x58\xbe\xc4\xfc\x46\xcf\x59\x19\x99\xeb\x37\x37\xe4\x2a\x02\xea\x72\xd2\x10\xda\xad\x53\xe5\x4a\x7c\x2c\x13\x4a\x6d\x47\x83\x37\xd2\x63\x33\x68\x54\x81\x70\xed\xef\x0d\x85\x17\x9f\x30\x23\xe1\x50\x38\x68\xa6\xe5\xe2\x77\x5e\x41\x2a\xc0\x5f\x05\x89\xd4\x2a\x37\x7e\x75\xaa\x6b\x8f\x52\x20\xa7\x69\x9a\xe8\xaf\xf0\x10\x94\xec\x46\x9d\x63\x61\xd3\xe8\xf3\x86\x15\xed\xcd\xa4\xd2\xd5\x28\x9a\xcf\x73\xdb\x64\x56\x98\x57\x80\xc9\x2e\x07\xf6\x2c\x77\xa9\x09\xfb\x6e\xf5\x98\x82\x20\x62\xbd\x57\x2b\xf7\x05\x8d\xcb\x83\x5e\xf3\x44\x3d\x3e\x47\xb5\xc6\x03\xd9\x27\x36\xdd\x1d\xf2\x6b\xe4\xb9\x28\x3b\x76\xe3\x21\xd5\x5c\xe2\xb6\x38\xcd\xe2\x25\x77\xca\x59\xc9\x63\xc2\x47\x95\x56\xc5\x75\xcc\xb0\xd6\xd1\x8c\x80\x4e\x2e\xb0\x1f\xf5\x35\x81\xeb\x04\x0f\xfd\x2c\xc4\x67\x60\x73\x7a\x74\x67\x2e\xa6\xbf\x78\x05\x8a\x6a\x0a\x1f\x5e\xbf\x56\xde\xcb\xf9\x4b\x54\xaf\xb2\x3c\x11\xd3\x41\x79\xbf\x09\x76\xb4\x15\x80\x17\xd4\x07\xc9\x5a\x40\x1f\xa6\xf9\x62\x4d\x77\x13\x5e\xae\x81\x41\xeb\xea\x9f\x35\xd5\xf5\x1b\x3d\xed\x99\x5c\x7f\x70\xc0\x25\xb0\x94\xad\xef\x2b\x07\x1f\x97\x11\x55\xd7\x79\x6d\x61\x3a\x55\x0d\x09\xe7\xf4\xdf\xc3\x45\x17\xb3\xf8\xfa\x43\x93\x28\x6a\x2b\x22\x80\x17\xda\xf2\xe0\x15\x38\x7e\x13\x52\x7f\x63\x66\x1d\x3c\x13\xe7\x8e\x90\xfb\x29\x55\xee\xe3\x45\x73\x91\x19\xb7\x91\xf0\x5b\x07\xc8\xf4\x2a\x43\x6e\xfc\xad\x1e\xc5\xea\x10\xf3\x08\xf8\xe2\x3c\xa9\x8b\xc6\x5a\x5f\xd9\x39\x3e\xfa\xaf\xe5\xcd\xef\xba\x81\x05\x81\x70\xcc\x54\x93\xc0\x0c\xed\xf2\x54\x09\x74\x35\xd2\xe2\xfd\xe5\x5f\x86\x6b\xb8\x2d\xbd\xfb\x91\x54\x34\x49\x74\x86\x63\x59\x16\x7b\x46\x6c\xaa\x90\x9b\x91\x53\x0c\x9c\x7e\xe8\xc5\x3f\xa9\x01\x64\xbb\xd0\xb1\xfa\xdb\xdc\xd0\x81\x27\xf1\x9b\xe5\x03\x30\x71\x51\x8d\x3c\xf1\x0a\xe6\xbd\x6f\x98\x27\xe1\x20\x6f\x5e\xc0\x95\xc1\x98\x61\x70\xe8\xd5\xd8\xe7\x2e\x57\xd4\x22\x87\x01\xdf\x2a\x48\xc9\x54\x87\x30\x56\xcf\xdf\xba\xaf\xb1\x0e\x46\xa0\xc1\xf1\x44\xb1\xa0\xea\xcd\xd2\xcb\x66\xbb\x91\x2a\xc4\x71\x78\x7d\xab\xe4\x83\x53\x85\x91\x20\xb0\x34\x03\x56\x7c\x41\x5d\xdb\x88\xfc\x0d\x7f\xba\x40\x69\xbb\xfe\xf4\x06\xee\xd7\x24\xa1\x1a\xbc\x04\x1e\x8e\x7b\xeb\x66\x3d\x0d\xc9\x9d\xce\xf3\xac\x6a\x14\x90\x07\xb4\x2d\xd1\xf2\x2a\x77\xdd\x52\x90\x18\x14\x32\x51\x72\x22\x4a\x27\x78\xf3\x66\xfb\x9e\xb0\x2c\x81\x2b\x84\x2a\x42\x84\x25\x61\xc6\x8f\x2a\xc2\x31\xc2\x6c\xe9\xe8\xb1\x9a\xe9\x1e\xbf\xad\x3c\x0e\x9f\x66\x36\x3a\x13\xec\xd8\xb8\x97\xa3\xd0\x0a\x26\xd2\x57\x64\x8d\x56\xc6\x74\x74\x41\xca\x1c\x6e\xe9\x9f\x08\xdd\xad\x25\xd1\x16\xdf\xad\xab\x03\x83\x00\x0d\x3d\x72\x25\xcf\x2e\xff\x70\x76\xb2\xad\xab\x95\x22\x29\x25\x55\xf3\x19\x32\x06\x78\x60\x00\xd4\x2c\xa3\x4d\x70\x8d\xc0\x42\x84\xa9\x4d\x17\x4c\xc9\x2f\x10\x2e\xfd\xdf\x31\x48\xc2\x99\x69\x16\xd4"}, +{{0xd8,0x80,0xd2,0xfb,0x06,0x26,0x2f,0x57,0xab,0x87,0x78,0xe3,0x3d,0x16,0xb4,0x73,0x06,0x09,0x78,0xa6,0x54,0x9c,0xdb,0xcd,0x55,0x86,0xba,0x81,0x05,0xf5,0xac,0xa8,},{0x0d,0xe4,0x86,0xd2,0x11,0x5f,0xaf,0x2d,0x54,0x72,0x66,0x77,0x2e,0x43,0x0f,0xd9,0x72,0x7b,0xdc,0xac,0xe6,0xec,0xbf,0x2f,0xe2,0x3a,0xb6,0x0f,0x7b,0x52,0x54,0xb1,},{0x4c,0x00,0xa7,0x16,0x68,0xd3,0x21,0x3c,0x29,0xc7,0x04,0x1c,0x5a,0x03,0x7e,0xdf,0x13,0xc6,0x51,0x4b,0xd0,0xeb,0xc8,0x80,0xc9,0x09,0xca,0xff,0x15,0x06,0xa4,0x5d,0x27,0x80,0x9f,0xb7,0x4e,0x66,0x02,0xea,0x2a,0xad,0x0f,0x84,0x28,0x31,0xb7,0x4f,0xb3,0xd6,0x90,0x0c,0xcc,0x52,0x06,0x52,0xda,0x28,0x36,0x8f,0xd9,0x0c,0xa3,0x0e,},"\x11\x47\x43\xe8\x2a\x09\x93\xce\xc9\x70\x50\x67\xab\xd7\x7c\x16\x8b\x53\x67\x7e\xde\x5c\x15\x9f\xad\x36\xf0\x6f\xc1\xa1\x4a\xcd\x77\xf8\x83\x79\x9e\xd9\x88\x3f\x99\x15\xae\xa6\x38\xec\x17\x41\xf3\xf4\x21\x58\x55\xfb\x5b\x07\xdf\x37\x93\xbb\xe5\xb5\x68\xeb\x35\x94\x39\x1a\x9e\xf5\x72\x7f\xab\x93\xe5\x74\x69\xb3\x7d\xe1\x25\xb1\xe9\xf2\xe6\xfe\x2c\x3d\x1a\x10\xec\xf8\x7b\x6c\x0a\x66\x5c\x6d\x46\x0a\x17\x0e\xef\xb9\xbf\x71\x6c\xd8\xfa\xea\x97\x64\xf5\x79\xff\x34\xeb\xfa\x9c\x4c\xfb\x34\x70\x6d\x8d\xd7\xc9\xeb\x1d\x10\xb2\xdf\x46\x0a\x46\xbb\x57\x89\x43\x0b\xf4\x49\x15\x8b\x58\x24\xf2\xa3\xa7\xb9\x18\xb3\x3a\xcf\x2d\x9e\xbe\x90\x21\x6d\x1b\x7c\xbf\x4a\xf7\x70\xc5\xdb\x95\xfc\x62\xff\x3a\x3c\x38\x5c\x3a\x82\x17\x85\x3b\x73\x46\x63\x4a\xaf\x30\x60\x72\x88\xdb\x0c\x48\x3b\xd4\xc2\x22\xeb\x33\x2c\xb8\x9d\xc4\xa2\x17\xe6\x33\x4a\x26\x84\x13\xa3\x90\xbb\x37\x1a\xec\x35\x5f\xbe\x4c\x73\x6f\x7d\xa7\x5f\x9c\x88\x75\x41\xa2\xb7\xd0\xda\xc0\x18\xb6\x13\x8f\x02\x1e\x77\x26\x6d\xde\xce\x84\x68\x45\x2a\xda\x39\xf5\xe6\x3d\x02\x09\xb9\xd6\xda\xbf\x97\x54\x13\x25\x6d\xca\xa1\x5a\xc1\x4b\x60\x68\xe1\x77\x05\x6c\x7b\xf0\xf0\xf7\xc8\x84\xa3\x40\x20\x32\x29\x8c\xd5\x59\xa6\x31\x20\x39\x40\x06\x32\x32\x7f\x9c\x0e\x76\x3e\x52\x79\x8c\xb1\x77\xda\x44\x75\xe4\xb2\x40\x5c\x15\x7c\xa4\x27\x74\x11\x08\xd3\x3e\xd0\xb7\xa3\xf5\x34\x38\xce\x6b\x72\x5c\x6d\xd5\x81\x4a\xf5\x1c\xfa\x45\xdb\xce\xd5\x57\xf7\x26\xdb\x13\x0d\x55\xcd\xe7\x53\x3b\xc2\x09\x2d\x6b\x69\x9c\x2c\x87\x0a\xf2\x82\x73\x1e\x18\xd6\x51\xae\x85\xb3\xdb\x4b\xa0\x28\x53\xf8\xc8\x7f\xd5\xe3\xab\x69\xbc\x57\xb0\x8b\x81\xf8\x3c\x23\x9c\xcf\x22\xe8\x17\xe2\xad\xa4\xd0\xad\x14\x48\x7e\xd1\x46\x12\xc8\xb0\x97\x3e\xc0\x65\x0a\x55\xf6\xbf\x9a\xf4\xae\x92\x56\xad\x35\x46\xa3\xf6\x7d\xd3\x5d\x98\x7e\xf2\x19\x09\xa9\x4c\x50\xf0\xef\x06\x40\xe7\x55\xb1\xc4\xe1\xa0\x12\xaf\x0d\x31\x76\x6e\xeb\x5d\xf3\x1c\xd1\x04\xc6\x4e\xb6\x2e\xb4\xef\xb1\x39\xcf\x30\x57\x69\x40\x1d\x21\x3f\x96\xa4\x88\xd5\xee\x7e\x3c\xe3\x2b\x01\x92\xee\x8f\x08\x31\xbf\xbe\x8f\xe9\x5d\xe9\x56\x88\x6b\x52\x4d\x33\x19\xb7\x3f\xd5\x6d\xc6\x0e\x9f\x1c\x72\xd7\x81\x55\xa9\x7c\x6f\x43\x69\x7b\x20\x46\x6b\x3e\x7a\xeb\xd3\x57\xb9\x16\x96\xe7\x34\x8f\x45\x99\xb3\x4f\x35\x91\xed\xdf\xce\x2a\x7b\xd8\x49\xab\x16\xf7\xb4\x3e\xbb\x16\xe2\x3d\x6f\x52\x10\xef\xa3\x0a\xb3\xba\x8d\x32\xc4\x06\x62\xb8\x66\x2f\xd9\x11\x54\x4b\xc2\x45\x8c\x65\x69\xef\x75\xa9\xb9\xdf\x6a\x0f\x6d\x80\xd6\x58\xba\x86\xb2\x41\xca\x19\xce\x9a\x6f\xcf\x01\xd3\xda\xa9\x5a\xfb\x59\xc3\xd8\x9a\x18\xb9\x48\x62\x13\x94\x32\x7f\xc5\xe9\x20\xa7\x5f\x98\xf5\xe2\xb3\xd6\xc9\x5f\xd8\x52\xad\xf5\x67\xb6\xd3\x7c\x54\xd2\x97\x08\x56\xa5\x99\xf7\x49\xe2\xc5\x5d\xac\x7c\x23\xe3\xfb\x1a\x63\xbb\x4c\xc4\x7b\x8b\x94\xf3\xd5\x89\xac\x4b\xee\xf0\xaa\xd4\xe6\x29\x2f"}, +{{0x58,0x58,0x71,0x94,0x1c,0xc2,0x82,0xe3,0x33,0xd5,0x7b,0xbf,0xc3,0xd4,0xae,0xda,0x86,0x2c,0xfa,0x0a,0x37,0x50,0x30,0xcd,0x59,0x4b,0x36,0x92,0x84,0x8c,0x5f,0x00,},{0x4f,0x34,0x38,0x16,0xcd,0x48,0x05,0x0b,0x67,0x8d,0x3a,0xdf,0x70,0x00,0x88,0x77,0xc9,0xfc,0xf5,0xcb,0x66,0x2c,0xc4,0xad,0x2b,0x93,0x86,0x4c,0x02,0x09,0x07,0x07,},{0x29,0x88,0x56,0xe5,0x70,0x18,0x8a,0xef,0xca,0xd8,0x1b,0xb9,0x70,0xf0,0x76,0x96,0x57,0x70,0xc2,0x67,0x62,0xfe,0x29,0xe6,0x55,0x4d,0xc7,0xaf,0xcd,0xb8,0x01,0x72,0x3b,0xf6,0xc7,0x63,0xb4,0xcc,0xd6,0x5f,0x4e,0x15,0xd7,0xd8,0xea,0x38,0xfc,0xf6,0x7e,0xa9,0xd2,0x85,0x90,0xc7,0x92,0x55,0xc1,0xcf,0xeb,0xa7,0xb5,0xe4,0x5a,0x00,},"\x65\x1c\x10\x1b\x3e\x2d\xfe\xf0\x78\x3c\xe9\xf6\x1b\xd0\xa8\xbd\xc9\x30\x7a\xc0\x48\x8b\x9d\xd7\x0c\xd9\x0a\x7e\xd8\xf1\x79\xa7\x89\x35\x55\x62\x95\xb9\x1c\xc2\xb9\x72\x11\xe3\xb9\x81\xb8\xda\xfc\xb3\xd0\x6b\x76\xd0\xb6\xed\xa7\xfc\x61\x94\x5c\x0e\xe2\x65\x2c\x5a\xc4\x54\x25\x64\x96\xcb\x82\xf9\x8c\xc1\xcc\x92\xd8\x18\x93\xb1\x08\x2b\x31\xb4\x7e\x6d\x22\xa2\xde\x60\x9d\xe4\xce\x8d\x7c\xc4\xf4\xa1\x52\xc4\x7f\x41\x0d\x7f\xc3\x7d\x38\xcc\xd6\x29\xa4\xb3\x3e\x62\x21\x89\x60\x81\x79\x7d\x07\x53\xdd\x4f\xaa\x8a\x8b\x44\xd6\xc4\x67\x71\x66\xdf\xb4\xd5\x21\x54\x46\x36\x0a\x3c\x28\xd8\xf6\x8e\x38\xab\x54\x60\x8b\x98\x82\x1b\x83\xc1\x87\xb5\x39\x3a\xd8\x74\xa7\x6f\x4f\x5d\x72\x94\x93\xa1\xfd\x74\xcc\x77\x19\xca\xea\x99\x1d\x22\x9c\x5d\x0c\x8c\x4c\x5f\x89\xd8\xe4\x34\x5f\x4f\x52\x21\x43\x13\x41\x0b\x8c\x06\xb3\x31\x5f\x45\xed\x0c\x2f\x91\x38\xab\x96\x6a\xec\x0a\x64\x5b\x6d\xba\x76\x38\x0a\x53\x91\x23\xe0\xf3\x3b\x97\xf3\xd0\x60\x39\x4a\x30\x53\x58\x1f\xfd\xef\x3e\x6d\x36\x53\x11\x66\xb5\x53\xa9\xdd\xe0\x31\x05\xc0\x4a\xf6\x97\xd9\x5e\x95\x21\x7f\xd6\xdc\x96\x8b\xf3\xb4\x48\xd5\xf3\xa8\xe4\xf5\xae\x7e\xdc\x30\xec\x78\xb1\xae\xa4\xf0\xdb\x18\x9a\x94\x9a\x12\x21\x38\xcd\xfb\x5f\x96\x93\xdb\x00\x4b\xae\xd1\xa4\x21\xdc\x44\x12\x2f\x32\x72\x87\xf7\x27\xcf\x98\x9f\xca\xe3\xcf\x3b\xe3\xe3\xdd\x9b\x9f\x53\x50\x2c\xf5\xd9\xfb\x18\x6d\xe7\x91\xd3\x10\xd1\x22\x86\x9c\x9f\xc3\xb6\x95\xde\xc1\x60\x74\x77\xf3\xe1\x49\xe5\x2b\x63\xcf\xdf\xb0\xd9\x83\xe8\x9a\xf2\xf7\x5a\x8f\x48\x98\x43\xec\x05\xc5\xea\x5f\x0e\x72\x1a\xca\xb3\x87\xc6\x80\x25\xf2\x0a\xbe\x0d\x27\xb4\xce\x29\xf4\xa6\x4f\xb7\xf8\xe8\xa3\x32\x87\x3d\x3e\xd1\x21\xfb\x49\x34\x14\xb8\xcb\x0c\x00\xad\x3a\xb6\x16\xc5\xbe\x52\x41\x47\x1a\xde\xe9\xf8\xf4\x69\x74\xea\xe8\x4a\x4a\x8c\xe6\xfa\xbb\x7f\x5d\x9a\x6b\x75\xa7\xe6\x70\x45\x6f\xcd\xcd\x1d\x98\x2e\x8f\x82\x7a\x4b\xbb\x69\xde\xc7\xe3\x05\x3d\xfe\x83\x5b\x70\x30\x1b\x7b\x76\x3f\x00\x04\xbc\x90\x6e\x14\x55\x42\xf4\x87\xb4\xdb\xa2\xed\x56\x1b\xd1\xa2\x03\x06\x23\x6a\xf4\xb3\x6e\x40\x68\xe8\xc0\x07\xb9\x45\x4f\x87\x41\xa5\xf8\xf0\x79\xec\x1d\xb8\x83\x5e\xb6\x54\x42\x90\xd6\xad\xb5\x2a\x70\xd7\x67\x5d\x85\xdf\x4a\x9a\x12\x55\xbf\xd9\x36\xc3\x31\xfe\x51\xc0\x97\x7d\x12\x4b\x5a\x50\x6d\x29\xc6\xee\xc3\x3c\xaa\x25\xd8\xeb\x28\x95\x2d\x6f\xfb\x9d\x6e\x3d\xa8\x90\x38\x2d\x88\x87\x96\xd3\x74\x60\x7f\x66\x43\xb8\x9e\x73\x26\xd9\xed\xc4\x9a\x0f\x53\xbd\xcb\x8c\xc7\x6f\xfd\x39\x3a\x77\x06\x52\x2d\x04\x17\x00\x36\xcc\xb6\x63\x30\xdb\xac\x9d\xa7\xe6\x16\x8c\xaa\x88\xcb\x62\x18\x1e\x55\xa7\xb6\xd5\x21\xa2\x11\x5e\x23\xe2\x02\xee\x24\x80\xb5\x87\xbe\x45\x01\x44\x79\x79\xa8\xd7\x36\xf9\x01\x2e\xcf\x00\xe6\x7b\x31\xe8\x10\x4f\x6e\x7d\xf0\x8a\x96\x83\xcd\xc8\x9c\x03\xa4\xe3\x7e\xe2\x29\x28\xd4\x5f\xa1\x90\x94\xe0\xd6\xe7\xb4\x0b"}, +{{0x05,0x88,0xac,0xd4,0xe0,0x9b,0xa9,0x02,0x74,0xc8,0xf3,0xd1,0x57,0x5b,0x2b,0xf3,0x64,0xa7,0x76,0x88,0x4a,0x9a,0xeb,0x41,0x03,0x41,0x5e,0x16,0x3b,0xa0,0xbf,0x81,},{0x3e,0xca,0xe6,0x97,0xb4,0x25,0xd8,0x7e,0x34,0xa1,0xd9,0x44,0x09,0x8e,0x3d,0x32,0xe2,0xc1,0xec,0x56,0xc3,0x62,0x7d,0xf8,0x0b,0xa2,0xb8,0xa4,0x3d,0xdc,0x19,0x03,},{0xa1,0x11,0xb9,0x70,0x6d,0x24,0x2c,0xd3,0x6d,0x6e,0x87,0x41,0xcb,0xb0,0x97,0xb9,0xe2,0xff,0xfa,0x40,0xf4,0x3f,0xd6,0xf2,0xd3,0xd9,0x16,0x93,0x66,0x73,0x32,0xb5,0xf2,0xdb,0x5e,0xe3,0xea,0x20,0xb8,0x32,0x91,0xb8,0x40,0x57,0x95,0xb7,0x4d,0x63,0x3d,0x46,0xf4,0x75,0xab,0x7c,0x47,0x61,0x71,0x18,0x53,0x5b,0x80,0x51,0xd9,0x07,},"\xf8\x28\xf8\xc9\xda\xd2\x98\xc5\xb7\x19\xda\xa8\x52\xb1\x7e\x76\x25\x98\xa7\x0f\x4e\xcd\x16\xa2\xfc\x59\x6e\xb0\x26\x38\x99\xe9\x83\xd4\x4e\xdc\xc7\xbd\x24\x0c\xb0\x76\x10\x60\x0a\xe9\x6a\xac\x0d\xfc\x3b\xe3\x87\xb6\x16\x85\x08\x99\xb5\xcf\x44\xe1\x76\x7f\xfa\xca\x3d\xf3\x81\x58\x59\x84\x24\xf8\x07\x14\x14\xc7\x04\xe6\x0b\x42\x2a\xd7\x73\x77\xfa\x7f\x6a\x8c\x5d\x0e\xbc\x02\x35\xe2\xd4\x3a\x98\x4f\x3a\xdf\x75\x9e\xb1\x04\x47\xf3\xc2\xf6\xb8\x0d\x5a\x11\xef\x41\xd3\xa0\x98\x52\xc0\x93\x2a\x1b\x9a\xc2\x3e\x6f\x40\xa1\x67\xde\x21\x04\x1b\xec\x88\x85\xf9\x43\x3e\xb8\x0b\x95\xc9\x78\x59\x58\x04\x6c\xdb\x7b\xf1\x47\xa7\x99\x47\x82\x3b\x41\x49\xae\x05\x21\xd7\xe5\xaa\xbc\x15\x64\xfa\x40\x44\x10\x6e\x2e\x39\x2e\x9c\x34\x44\x57\xe9\x92\x93\x76\xea\x9b\x42\x29\xc6\xe7\x73\x8f\xe7\x90\x08\xd5\x54\xc4\x29\x39\x69\x14\xc3\x63\x87\xf5\x79\xb4\x6b\xab\x14\x6f\x6a\x95\x10\xeb\x6f\x8c\x85\x55\x1c\xbd\x84\xc7\xdc\x0d\x0b\x1c\x01\x0c\xcb\xa5\x96\x3a\x7f\x39\xf1\x81\xe4\x4d\xbc\x98\xe4\x95\xaa\x63\xc0\x10\x59\xcb\xe6\xa9\x9b\x07\xb4\x49\xe7\x75\x9c\x9a\xf9\xe0\xf8\xd9\x05\x4a\x67\xa3\x48\xfa\x19\xd7\xf9\x1e\xc0\xa4\xd4\xf2\xc7\x02\x6c\x3b\x84\x92\x59\xa3\x50\x41\x7f\xd8\x6c\xab\x21\x42\xe4\xcf\xe3\xc0\xaf\xbf\x25\x18\x2a\x2d\x52\xbd\x2e\x0b\xc9\x20\xe8\x50\x80\x83\x2b\x91\xb9\x27\xb6\x29\x48\xa6\x7c\x31\x7e\xb0\x90\x91\x46\x1d\x49\x3e\xea\x5f\xfc\x47\xbf\x08\x55\x82\x96\x82\x58\xa3\xc8\xdd\x81\xa8\x58\x27\x0b\xdd\xaf\xe7\x92\x56\x84\xa1\x5f\xfb\x51\xbc\xfa\xab\x93\x1a\xfa\x46\x5e\x30\x90\xe8\x6b\xe4\x1e\x35\x47\xcb\xa2\x34\xb8\x5f\xe7\xdb\x70\x04\x96\xa5\x05\x00\x2d\xf3\xca\x4e\xae\xc7\xb9\x62\x78\xc7\xd1\xa7\x7d\xb8\x34\xa9\x17\x97\xbb\xb8\x26\xd0\x92\xaa\x28\xb4\x95\x45\xed\x3b\x1e\xda\x23\xbe\x11\xa3\xf5\x28\xb9\x55\xcb\x0c\x4f\xa6\x6e\x16\xe9\x57\xe5\x70\x4c\xf3\x19\xe5\xf7\x9c\xc0\x9f\x2d\x05\x4e\x6d\xaf\x19\xe2\x92\x6b\x11\xe1\xe4\x13\xff\x82\x2c\xa1\x41\xf7\xc3\xd3\x85\xae\x95\xdd\x20\xb3\x46\xe5\x83\xcf\xb0\xc2\x29\xec\x39\xcf\x88\x9a\x54\x19\xcd\x37\xbc\x18\x4e\xf5\xfb\x14\x46\x22\x08\x0a\x30\x2d\x9d\x77\x45\xc4\x51\xf7\xd8\x82\x42\xcc\x26\xb9\x16\xa3\x56\x9a\xbc\x7d\x1f\x21\x6d\x57\x79\x7a\x47\x2b\xc6\x21\x76\x17\x58\xe8\x40\xeb\x8e\x29\xbc\x8e\xfc\xb7\xaa\xfc\x7c\xf8\xf4\xe5\x93\x30\xd3\x5e\xe1\x07\x49\x6d\xec\x6e\x71\x4b\x1f\xa4\x30\x98\x37\xbb\x47\xeb\x3a\x06\xb4\x60\x4d\xd2\x07\x33\xcc\x0e\xaa\xc2\x64\x9e\x18\xc0\x73\x42\xef\x55\xd1\x9b\x8d\x03\x95\x91\xac\x28\x69\xac\xc3\x4b\x6c\x3c\x1c\xa3\xcf\x26\x3f\xf8\x4c\xa4\x3a\x5f\x64\x65\xba\x34\x88\x8c\x10\x90\x13\xb3\x2b\xfc\x0d\x0d\x15\xf5\xa7\x6c\xec\x27\x0a\xb3\xac\x9a\x10\x63\x31\x31\x2f\x5a\x0a\x84\x28\x2c\x3a\x3d\x4a\xea\x1e\x7c\xf5\x3d\xbf\x8b\x24\x0b\xdd\x11\x1c\x34\xd2\xa9\x3d\xfd\x12\x58\xfe\x92\x67\x13\x3f\x75\x54\xdc\xc2\x1a\x8f\x43\x9c\x16\x5d"}, +{{0x7d,0x14,0x02,0x3e,0xb4,0x8b,0xbd,0x43,0x76,0x49,0xa2,0x41,0x87,0x79,0x05,0xa3,0xc9,0x32,0xf1,0x46,0x40,0xf2,0x9a,0x0f,0xb1,0x34,0x11,0x4e,0x8f,0x33,0xf5,0x82,},{0xea,0x5c,0x11,0xb4,0xb2,0xc5,0xef,0x4a,0xb7,0x06,0xcc,0xa3,0x47,0x50,0x43,0xc9,0x58,0x18,0xeb,0x56,0x5a,0x79,0x7e,0x33,0x68,0x8a,0xfe,0xac,0xd6,0x8a,0xdc,0xca,},{0x31,0x33,0x9d,0xce,0x23,0x33,0x6d,0xf5,0xb2,0xb1,0x93,0x52,0x2a,0xa3,0xdd,0x2d,0x41,0x14,0xa6,0x6a,0xf1,0x65,0x62,0x89,0xc9,0x52,0xbc,0x11,0xc9,0xb2,0x10,0xf7,0x7a,0x54,0xd4,0x61,0x61,0xf4,0xe0,0xc5,0x2b,0x30,0x13,0xe4,0x0b,0x9e,0x9e,0x84,0x27,0xd8,0x51,0x32,0x5b,0xd7,0x1c,0x4d,0x99,0x35,0x3e,0xee,0xd7,0x51,0x08,0x0d,},"\x90\x01\xdb\x31\xf2\x79\xbe\x50\x53\x19\xb8\xe7\x2b\xde\x11\x99\x51\x29\x80\xdf\x65\xf0\xd8\xa9\xb4\x93\x04\x67\x41\x3a\x99\x7b\x97\xa3\x62\xb5\x72\xa4\xb4\x4b\xc9\x40\x48\x7f\x18\xb2\x08\xce\x6a\xc5\xc6\x87\x16\xd3\xaf\x1b\xce\xf1\x70\x38\x3b\x5c\x4b\x5c\x47\xe4\x47\x37\x72\x6f\x93\x83\xbc\x4f\x14\x47\x68\xbf\x5c\xaf\xb4\xe9\xdf\xe3\x97\x61\xe6\xed\x47\x89\x71\xd1\xc7\x0e\x6d\xab\x2f\xd0\x49\x9d\xff\x92\x93\xb2\x39\xd1\x6c\x96\x02\x61\xc6\x82\x18\xb9\xf5\xb1\xbe\xe6\x90\xf0\xd2\x40\xc1\xb3\xdb\x71\x1f\x9e\x82\x1f\x08\x09\xbb\xeb\x9a\xaf\x24\x9c\xcb\x16\x8c\x67\xd9\x65\x56\x2d\x24\xf8\x48\x51\x61\x40\xbf\xd9\xfc\x05\x0d\x4f\x20\xda\x5a\x17\x94\x46\x8a\x9c\x07\x25\xea\x5c\x66\x9d\x5c\x63\x0d\x93\x10\xe5\x74\x51\x07\xda\xd3\x72\x61\xb5\xd9\x1e\x38\xe0\x85\x12\xe6\xf3\x73\xec\x5d\xca\xd5\xca\x09\x07\x29\x07\xc8\xfb\x7b\xf3\xb9\x26\xc3\x33\x94\x90\xb3\xf5\x1f\x76\x44\xe7\x3a\xe2\xec\x01\xd6\x1b\xe7\xc6\x52\x65\x36\xb4\xff\xd1\xab\x68\x49\xfe\x0c\x2f\x40\xd3\xbd\xa2\xa4\x9e\x55\x50\xb8\xdf\x97\x90\x81\xda\x85\x16\x8d\x0f\x71\x58\x2b\x90\x36\x77\x52\x6d\x1f\x1b\x15\x11\xe1\x38\xb6\x84\xfc\x46\xaa\xc8\xbd\x80\xc3\xde\xf7\xee\x81\x38\x19\x04\x61\x80\x7c\x55\x36\x12\x5c\xb0\xe2\xc3\xd0\x83\xa1\x87\xc7\x26\x9c\xb5\x31\xec\x36\x78\x78\x7b\x32\x55\x5c\xf0\x4a\xb0\x93\xc9\x00\x2e\x7d\x79\x2b\x4d\x93\x3f\x2e\x30\x70\xf3\x9a\xc8\xcc\xf8\xd5\xf5\x45\x5f\x12\x10\x9d\x8a\x8a\xeb\x4e\x21\x2f\xad\x4a\x70\xb1\x47\xc0\x4a\x7b\x91\x84\x60\xb1\x31\x63\x76\xe6\x40\x20\x85\x95\x17\xeb\x7e\xe3\x0c\x29\x0b\xe8\xb8\xd6\xf9\x67\x39\x15\x25\x6c\x3b\x04\xb9\xd9\x05\x4b\x52\x33\x8e\x0d\x36\x07\x85\xe4\x6a\x18\x28\x44\xc5\xc3\x76\x6a\xea\x8e\xd3\x11\xb2\xd4\x81\xc0\xb7\xb2\x11\x4e\x41\x8e\xd1\x7f\x8d\xeb\xf0\x1a\x83\xff\x37\x51\x70\x24\xee\x9e\x28\xe0\xc9\x0d\xce\x6d\x05\x9f\xfe\xe4\x13\xd2\x7c\xd6\x27\x83\xa8\xb8\xb5\x01\x6a\xd2\x76\xe3\x9d\xfd\x8f\x8f\x3d\xdf\xc4\x28\x10\x18\x18\xce\x50\x7f\x00\x3e\xb5\x8c\x9a\x5c\xc8\xb1\xaf\xf0\x5a\xab\x8f\x0d\x7f\x1d\x1f\x6d\x4b\x87\x1d\xbc\xed\x1f\x3d\x28\x66\x23\x97\x52\xfb\x13\xf6\xe1\x80\x34\xbb\x2b\x5a\x66\x35\xca\xa6\xec\xc4\x62\xe0\x58\xeb\xe2\xfa\x65\x1d\x3d\x0f\x36\xe2\x0a\x31\xf7\x65\xe4\xb9\x58\x27\x0b\xd8\x25\xc6\x81\x8a\xac\x1a\xd7\x56\x31\x35\xae\xed\xf1\x4a\x2b\x6d\x39\x8b\x6e\x34\x00\x84\x01\xb2\x18\x46\x18\x20\x07\x1c\x5a\xf7\x78\x46\xcb\x9c\x32\x81\x90\xc0\x61\xd5\xaa\x6e\x0e\xcd\xe7\xef\x58\x56\xb0\xe6\x81\x4f\x83\x3f\x70\x40\x96\xdf\x08\x25\xfa\x4b\x46\xdc\xda\xcf\xa2\x7c\xd8\x7b\xd7\xbf\xef\xf7\xf8\xca\xe1\x66\xa3\xa0\x4d\x43\x7c\x7b\xe7\x16\xc4\x90\x45\xc7\xbd\x3d\x13\x49\x62\x7c\x9c\xbd\x04\xc1\x5f\x00\xa6\x96\xe3\xcf\xfb\xb4\x5a\xf2\x91\x22\x62\x7e\x7e\xd3\x3b\x42\x49\x91\x3b\xec\x00\xf0\xe2\x8a\xa1\x12\x98\xcc\xe8\xb6\x49\x08\x1f\xe3\xb1\x69\xb4\xaa\xea\xca\x48\x5b\xda"}, +{{0xe8,0x30,0x6b,0xad,0xa6,0xd5,0x5e,0xb1,0x88,0xd9,0xf7,0x5c,0x81,0x5c,0xc9,0x14,0xe9,0x3c,0x9c,0x72,0x22,0x39,0x1c,0x15,0xbb,0xae,0xaf,0x93,0x54,0x43,0x79,0x35,},{0xbf,0x27,0x98,0xb8,0xe5,0x54,0xf5,0x1e,0x22,0x86,0xc3,0x03,0x4a,0x88,0xe5,0x77,0xff,0x23,0xfa,0x32,0xa6,0x72,0x44,0xea,0x82,0x45,0x91,0x2e,0x8b,0xf4,0x6d,0xa4,},{0xcc,0x66,0x27,0x30,0x8e,0x2f,0x42,0x43,0x83,0xfa,0x70,0x59,0x4f,0x57,0x57,0x91,0x60,0x05,0x40,0x02,0x7a,0x27,0x51,0x61,0x9b,0x28,0x3a,0xff,0xea,0xeb,0xc9,0xc9,0xd2,0x9a,0xc6,0xdb,0x28,0x6d,0xd2,0xc1,0xb5,0x96,0x58,0x7b,0x87,0x8d,0x1d,0xf4,0x78,0x1d,0x43,0x6b,0xb5,0x70,0xc1,0xc0,0xf0,0xd3,0x33,0x68,0xdc,0x66,0x52,0x0b,},"\xd7\x04\x38\x09\xc3\xe3\xdc\x00\xb1\x7e\xfd\x52\xc9\x13\x0b\x11\xb7\x86\xf1\xe2\x57\xb5\xe2\x2f\x81\xa7\xfa\xae\x60\x0b\xbc\xdf\xd5\x18\x53\x7f\xe8\x52\xc6\x42\x35\x97\x62\xfb\x75\xe8\xad\x85\x92\x49\xe6\xab\x49\xce\x1b\xb0\x4f\x24\x92\xf2\xaa\xc3\x54\x46\xba\x6e\xb0\x3e\x76\xde\x3a\xbd\x2d\x5f\xc7\xe6\x14\x68\x43\xad\xd0\x42\x86\x0a\x4a\x16\xb5\x9b\xdd\x7d\x03\x83\x78\xa3\x5e\x1a\x04\xb1\x21\x7a\x55\x71\x0d\x93\x7e\x2c\x90\x32\x23\x2e\xa2\xcd\xd1\xd2\x5a\x0b\xff\x71\xef\x5d\x3e\x0c\x05\x6b\x29\xcb\x92\xf6\xdf\x69\x2b\xde\x14\xdf\xa5\x0e\x13\x2b\xeb\xd8\x9e\x9f\x18\x33\x88\x0b\x65\x7a\x78\x1e\x94\xec\xb6\x03\x04\x17\x56\xe5\x51\x7d\x44\x23\xc5\x6f\xad\xc1\x3e\x2b\x31\x80\x88\xfe\xdd\xf3\xb5\xc8\x3c\x20\xb4\x6f\xdd\xbb\xa9\x23\x05\xe4\x86\x06\xda\xb7\x48\xce\x38\x48\xb8\x43\xf4\x71\x1f\x37\x0c\x3e\xc7\xd5\xe1\x9a\xb4\xc0\xac\x1a\xe1\x5a\xaa\xf2\x3d\x65\xfe\xce\xda\xbc\x08\x04\x9b\x9e\x29\x11\x3e\x57\x61\xed\x9d\x1c\x62\xeb\x07\x5c\xab\xb2\x67\x4c\xdb\xe1\xe3\xa8\x89\xba\xe4\xb1\xdd\x31\xb6\xa5\xb2\xea\x1b\x8d\xed\xcc\x3c\x51\x5e\xdc\x44\x67\xc3\x02\x31\x17\x6c\xd4\x4b\xec\x8a\x05\x79\x51\xab\x5c\xd3\x9a\x96\x23\xf8\xaf\x84\x73\xcd\x27\xd9\x33\x02\xbf\x8a\xa6\x24\xc9\xc3\xc5\x79\x9d\xa1\xdc\x49\x44\x94\xef\x8f\xf1\xdb\xe0\x18\x7e\xa5\x16\x26\x70\xb8\xd0\x98\xc3\xa9\x49\x19\x39\x8d\xad\xf7\x9e\x6c\x24\x91\xc4\x44\x39\x2c\x29\xcd\x50\xd5\x74\x35\x06\x32\x90\x84\x2b\xfa\x0e\x85\x30\xfa\xeb\xc0\x06\xd6\xea\x78\x01\x11\x7e\x0a\x3f\x01\x9e\xe2\x8f\xb3\x79\x22\x35\x40\x2e\x2f\x69\xb8\x7a\x43\xdc\x22\x7f\x9d\xe3\x16\x02\x97\x56\xc3\x16\x7d\x64\xa3\xa3\xf6\xd7\x31\x60\x33\x1d\x5a\x18\xee\xe5\xb0\xe6\xe2\x2a\x66\x3e\xfd\xcc\x8d\x67\xaf\x3b\xce\xd0\x41\xea\x84\x3a\x56\x41\x60\x3e\xc7\x2e\xfd\x64\x4e\x17\x3d\x19\x9a\x8c\x83\x0b\x2e\xa5\xfe\xc0\x37\x80\x27\xc3\x72\x25\xaf\xcb\x60\x4c\x4c\xdc\xf4\x09\xbe\x1c\x50\x9c\x9a\x37\x7b\xe0\xd0\x52\x41\x07\xc6\xd9\x2b\x5f\x09\xa2\x9e\xfb\x71\x09\x29\x56\x70\xbb\x1a\x1d\xd3\xea\x00\x8b\xb7\x91\x85\xf0\x9b\x98\xf0\x20\xc4\x3f\x14\x39\x68\x5b\x96\xf6\x19\x93\x11\xa0\x90\x87\x0f\x0d\x9b\x10\xd4\x95\xcd\x41\x0a\xa9\x5b\x7e\x53\x74\x9b\xe3\xa6\xc0\xfb\xc7\x29\xf9\x6c\xf8\x56\x43\x97\xb0\x9c\x13\x51\x40\x16\x82\x5f\x72\xf1\x4e\xb9\x32\x94\xd7\x01\x0a\xcc\xfd\x11\xf1\x7a\x6a\xc8\xf5\x44\x26\x3d\x60\x38\xd5\xc7\xdb\x29\x48\x62\x91\xb3\x0e\xa4\x9b\x6b\x54\xcf\x88\x82\x6d\xd2\x52\xcd\x9d\xbb\x57\xd8\x41\xb5\xa4\xcf\x70\x2a\x32\x64\xfa\xa4\xdc\xcc\x86\xab\x14\xda\xf1\x24\xef\x3d\x53\x35\xa6\x87\x8d\x06\x5c\x6b\xa2\x99\x91\x04\x57\x65\xee\x55\x42\xcc\x9f\x5d\x9f\x35\x4d\xcd\x2c\x6e\x0c\xf7\xff\x3a\x30\xf6\x49\xb5\x91\x2d\x97\x1d\x63\x35\x78\xf1\xe9\xf2\x63\x87\x4d\x05\x65\xc2\x47\x30\x1d\xcb\xd1\x5d\x76\x21\x1a\xe2\xd3\xd5\x06\xfc\x64\xde\xb7\xe0\x42\x56\x5d\x43\x8e\x2b\xfb\x24\x92\x43\xb7"}, +{{0x36,0x3c,0x1e,0xa7,0xc3,0x2e,0xa3,0x28,0xa0,0x55,0xaf,0x7b,0xd8,0xb3,0xbf,0xd2,0x04,0xfb,0x0b,0xbd,0x4b,0xf4,0x2f,0xfe,0x26,0x2f,0x3a,0x5e,0xbd,0x54,0xda,0x55,},{0x7a,0x83,0xec,0xca,0x51,0xef,0x6e,0x5a,0xa0,0x43,0xa5,0xce,0x04,0xd9,0x28,0x8a,0xdd,0x49,0xa2,0x77,0x54,0x8b,0xd3,0x01,0x6b,0x69,0x3f,0xfa,0x79,0xa2,0x2e,0xdc,},{0x5f,0xd1,0xe5,0xf9,0x92,0x2a,0x12,0xf6,0x36,0xb7,0x2a,0x7d,0x62,0x17,0x09,0x1f,0x94,0x8a,0x55,0xbc,0xb1,0x82,0x6b,0x8f,0xca,0xf9,0x9d,0x26,0x41,0x6c,0x7a,0xb1,0x35,0x1c,0x10,0xf4,0x09,0x3f,0xfd,0x8a,0x2a,0xf8,0x69,0x14,0xa0,0xa9,0x81,0x84,0xec,0x7e,0x06,0xd2,0xde,0xe8,0x7f,0xdc,0x0f,0x4a,0x47,0xf8,0xc6,0x3c,0xf5,0x01,},"\xc4\x1c\x1e\x1f\xb7\x59\x54\xa0\xae\x0e\xbc\x29\x09\x0b\x9f\xc5\x33\xe6\x93\xe7\xc7\x10\x5c\xfe\x40\xef\x52\x6e\x4e\x12\xa7\x40\x52\x21\xf2\x18\xc7\xac\x01\x9e\x1d\x4c\x92\xda\x28\x53\xf2\xd7\x26\xaa\x62\x27\x79\x24\xdf\x0c\x34\x3f\xc3\xd4\x7c\xd5\xa9\x9a\x3e\x27\x9b\x26\xa1\xb1\x3b\x1f\x2a\xa3\x6f\x7c\xcb\x4b\x54\xfb\xef\x18\xbd\x87\xa5\x5f\x1b\xc4\x0c\xe7\xb2\x02\x91\x45\xee\x7a\xab\x39\x17\x95\xac\x68\xde\x61\x99\xf5\x05\x94\xfc\x79\x61\x1b\x85\x13\x1c\x14\x30\x21\xf2\x6f\xa3\x58\xda\x0c\x7c\x6a\x65\xdd\xe0\x76\xda\xb4\x88\x67\x5b\x72\x23\x09\xe5\xed\x97\x46\xd1\x8a\x89\x30\x99\x06\xa7\xa9\xdf\x23\x7d\xd2\x7b\xd5\x90\xcc\xc7\x7c\x40\x2e\xf6\xe1\x9c\xa6\x3c\xc8\x6b\x85\x16\x03\x30\xee\x6e\x1f\x1f\x47\xa2\xff\x80\x7e\xef\xad\xc0\x09\x63\x52\x0a\x1c\x60\x0a\x3e\x45\xaa\x7f\xb2\x55\x4f\x47\xd8\x97\xbd\x86\xd8\x1c\x3b\x08\x77\x10\x12\x22\xfa\x78\x50\xb8\x0c\xe3\xbc\x06\xc9\xe5\x8c\x0c\x96\xe3\x2f\xec\x85\x30\xc9\xfa\x1e\x41\x63\xf0\xef\x84\x56\x95\x2b\xf6\xdd\x58\x04\x5a\x36\x3d\x61\x88\x0e\x9a\xc9\x76\xa3\x60\x3e\xf7\x7a\x4c\x39\x5e\x6a\x07\xe3\x42\xf6\x02\x3b\x8a\xf1\x02\x25\xcf\xf2\x40\xef\xc0\x36\x6a\x79\x9f\xd8\x6e\x9d\x06\x20\x60\xd8\x72\x40\x33\xbd\xf6\x75\x88\xcd\x73\xac\x28\x4d\xe4\xc6\x94\x3c\xf4\x5e\xe4\xf7\x5f\x59\x37\xd9\x7d\x78\x10\x5f\x0b\xbe\xce\x04\xd3\xdc\xb5\xe4\x24\xef\xf8\x9b\x77\x3e\x5d\x6b\x4f\x37\xef\xa9\xa0\x65\x4c\xb3\xef\x34\x52\x78\xa6\x2d\x87\x6c\xfe\xf9\xa3\xdc\xdc\xeb\x70\x81\x44\x18\x77\xeb\xd5\xfa\x30\xc9\xd9\x54\xe3\x68\x4f\xa4\x76\xa4\xf4\x85\xd4\x26\xfd\x3c\x8c\x32\xbe\xa0\xf9\xcc\x20\xb1\x5e\x8f\xdf\xc3\xca\x4b\x30\x2c\x07\x4f\x50\x81\x32\xd1\x5d\xe6\x25\xc1\x0a\xe0\x73\x78\x11\x46\x3d\xcc\x55\xfc\xc4\x01\x4b\x20\x20\x8f\xff\xce\xfa\x9d\xd4\x52\x11\x9b\x16\x52\xde\x41\x34\x8f\x69\xf2\xc4\x88\xf5\xcc\x18\x56\xd6\xe7\x8a\x5c\xbe\x3e\x37\x3d\xd4\x59\x8e\x2d\x39\xf8\x76\xeb\x94\xe0\xb0\x1b\x21\xfa\x91\x29\xef\x41\xb6\x39\xf4\xe0\x5e\x69\xde\xb1\x83\x5e\xd4\x4b\x91\x12\xa6\x86\x2a\x5b\xce\xa0\x72\xc6\xe1\xb8\xf0\xf0\x58\xf4\x6b\xac\x2a\x84\x5a\x58\x2d\x14\x8f\x17\x76\x0b\x9e\x0a\x2b\xa6\x0b\xbb\xf3\x88\x4a\xf9\x4d\xd4\xc7\xec\x9d\xb0\x8e\x9a\x5b\xcc\x6d\xde\x13\x46\x44\x2e\xe1\xf4\x70\x7d\x1f\x79\xb6\x9b\xa8\x67\xf4\x18\xdc\x27\x91\x73\xf7\x7a\xdb\xc5\x8a\xb8\x5e\xa3\x93\xb9\xdc\x68\x26\x19\x00\xc1\xca\xa8\x2d\x2f\x50\x47\x4c\x42\xae\xc9\x11\x31\x42\x78\xc0\xaf\xfa\x2a\x6b\x6c\x36\xd1\xff\x88\xf3\xb4\x9f\xb2\xb7\xc3\x39\xd2\xa7\xc2\xb3\x04\x9f\x8c\x0a\x08\xd1\x6a\x9e\x8d\xf9\x3d\x13\x0d\xa4\x84\xbd\xba\x6d\xbe\xc5\x34\xcd\x51\x09\x7a\x04\x82\x21\x10\x6b\xab\x48\xd6\x7f\x95\x1b\x75\x05\xa1\x48\x48\x92\xb8\x57\x79\xc5\xa3\x11\x17\x02\x12\x4d\x95\x7a\xcf\x2d\xc3\x52\xef\x9b\xa2\x47\xbc\x80\xe2\xce\x96\x26\x9c\xe8\x5e\x78\xb9\xeb\xda\x98\x90\x76\xdd\x5f\xf7\x3e\x1e\xb2\x75\xe5\xd7"}, +{{0xdb,0x22,0x28,0xff,0xff,0xa9,0xd2,0x53,0x4a,0xef,0x91,0x8f,0xb8,0x5b,0x82,0x1a,0xd3,0x60,0xe2,0xd3,0x9d,0xec,0x5a,0xeb,0x2d,0xb0,0xdf,0x02,0x49,0x7f,0x94,0x16,},{0x6d,0x01,0x95,0x77,0x7f,0x81,0x05,0xff,0x52,0x3b,0x79,0xc5,0x9e,0x3c,0x30,0x81,0xfe,0x89,0xdb,0x6f,0x87,0x03,0x3f,0x09,0x4f,0xa5,0xa9,0x40,0xce,0xf8,0x4b,0xb4,},{0x82,0x18,0x9d,0x34,0x0b,0xc1,0x1c,0xea,0xa4,0x00,0x41,0x0e,0x08,0xba,0xe9,0xd9,0x01,0xaf,0x05,0x91,0x25,0xe9,0x53,0x78,0x6f,0x8a,0x04,0x3d,0xdf,0x11,0xf7,0xb2,0xf8,0xe3,0xb6,0x17,0xac,0xcd,0x78,0xe2,0x93,0x9a,0xdf,0xab,0xf2,0xd2,0x47,0x1f,0xaf,0xd6,0xf5,0xbc,0x45,0xb1,0x40,0x75,0xb3,0x28,0xe3,0x4d,0x80,0x75,0xb2,0x07,},"\xfc\x07\xcd\x99\x04\x0f\x13\xe5\xa8\x4f\x94\x74\x6d\x6b\xb8\x68\xf7\x52\xb4\x48\xb6\x2d\x99\x59\x3e\xf2\x9e\x43\xcc\x82\x45\xf0\x47\x0f\x65\x55\x2d\x64\x32\x20\xf6\x71\x92\x85\xe1\x5c\x37\xa6\xd1\x74\xae\xf7\x60\x88\xcc\xda\x5f\x88\x68\x5b\x52\xda\xe2\x84\xc6\x5b\x38\x0d\xa3\x45\xa2\xe1\xaf\x2e\xd7\x64\x80\xd2\x69\xcb\x93\x4b\x43\x17\x62\x0b\x79\x2e\xbb\x39\xb2\xa6\x78\x24\x7d\x6d\x81\x5f\x2a\x5c\xb9\xaa\x56\x0e\x4b\xf6\xde\xba\x4c\x0a\x0d\xdc\x82\xd0\xe5\xa5\xa6\x5a\xcb\xc4\x78\xe1\xec\x6b\x06\x4d\x7b\xb7\x38\x8a\x73\xf6\xed\xa3\x0b\x0b\x6b\x73\xdd\x8f\x87\x92\x63\xad\x1a\x03\x48\x67\x1d\xcf\x21\x1c\xb9\x6e\xd0\x8e\xd5\x2f\x33\x17\xda\x68\x18\x5d\x6b\xb2\x58\x9d\xc1\x1d\x75\x5d\x47\xa3\xb6\xf6\xa0\x38\x6a\x85\x94\xd9\x57\x0b\x2e\x9b\x0d\x4b\x5e\x13\xdc\xcd\x9b\xb7\xac\xbe\xf0\xab\x27\x6a\x7a\xeb\xe1\x29\x31\xbe\x67\xf1\x0d\xe2\x67\xa0\x29\x89\x53\x01\xf5\x66\x25\x30\xad\x8a\xb3\xd2\x30\xb3\xb6\xd7\x09\x3a\xcd\xfb\xf2\x74\x75\x7a\x90\x78\xe2\x0c\x23\xbc\x82\x2d\xef\xfa\x61\x00\x54\x86\x10\x2c\x01\xab\x82\xbd\xc8\xcd\xcf\x1b\xb3\x7f\x9b\x56\xd3\x9e\x50\xfd\x5a\x68\x95\x41\x6e\x76\x7f\x4e\x36\xc1\xa4\x17\x78\x90\x81\x25\xb5\xca\x3f\x92\xa9\x0d\xa9\xad\xdf\xf1\x55\xfb\x1f\xd7\x76\x88\x08\xa8\x0f\x20\x3e\xd7\x37\xef\x00\x77\x63\xbd\x2f\xea\x9f\xf2\x8c\x84\xb4\x35\x51\xc9\xfc\x43\x8f\xfc\x47\xfc\xfc\xf6\x4d\xc7\x70\x06\x13\xaa\x8b\x3a\xf8\x63\x3a\xe8\xb6\x98\x74\x37\xc0\xaa\x47\x81\xbe\x1e\x82\x13\x96\xc5\x36\xcb\x30\x05\xd0\x55\x49\xb1\xcb\xa7\x01\x35\xaf\xb7\xfe\x30\x68\x96\x1c\xad\x3a\x14\x63\xcc\x0b\x55\x60\x68\x4e\x27\xbb\xa7\x7a\xef\x41\x9d\x82\x38\x68\xe0\xce\xba\xd1\xf1\xce\x0a\xe9\x02\x74\x4a\x15\x2d\xd2\x94\x51\xa1\x7e\x28\xa8\x9a\x71\x58\xa1\x83\x6e\xfc\xe4\xa3\xe5\xc7\xd1\xfa\xa4\xc3\x87\x5b\xc4\x6c\x4d\x9b\xe2\x2d\x66\xd3\x66\xac\x6f\x59\x53\x8a\x00\xb2\x75\xb0\x2f\xac\x6d\xa7\x55\xa8\x54\x08\x19\x97\xd5\xd1\xd0\xe6\xe5\x68\xa5\x95\x8c\xf3\x34\xc5\x18\xcd\x51\x7a\xb9\xd7\x3c\x48\xd6\xcb\xc4\xae\x4e\xea\x43\x53\x11\x3e\x7e\x4a\x7c\x05\x92\x0e\x68\x6b\xf0\x7a\xfb\xfb\x8d\xd2\xec\x4f\x18\xfa\x71\x38\xe5\x7d\x33\x2c\xd7\xa4\x22\x8f\xea\x73\xbc\x09\x25\x2f\x24\x42\x72\x94\xeb\xd3\x64\x5e\xe0\x99\x6c\x2e\x85\x1a\x8a\xa5\x1a\x7c\xd9\xfc\x2e\xab\x47\xc0\xab\x21\x3f\x4f\x51\xd2\x16\x09\x1e\xd0\x89\xe4\x59\x2e\x9b\xb0\x82\x8b\x85\x8f\x84\xf6\x0b\x93\xad\x84\xa0\xa2\x28\x27\xcb\xd2\x74\x14\xb7\x81\x32\x2a\x04\xd3\x96\x08\x28\xf6\x38\xdf\x28\x34\xc7\xf7\x83\x9d\x70\xdb\x12\x6b\xee\x5a\xf2\xee\x75\x59\xa8\xac\x4c\x01\xa6\xc3\x91\x39\x6a\xf9\x3f\xa0\x60\x89\x40\x29\x7d\xdf\x89\x00\xc5\xdd\xb4\x66\x34\x0a\xe5\x1c\x60\xc7\xea\xd7\x62\x44\x7e\x76\xd8\xbc\xcb\x57\x39\x97\xcf\x66\x14\xd1\x88\xa0\xb9\xa2\xf5\x6e\xed\x9b\x0f\x9d\x46\x3a\x19\x78\x7f\x40\x92\x58\x1a\x65\xc6\xbf\x78\x1b\x93\xc5\x60\x87\xe5\x4e\xe1\x34\x3a\xab"}, +{{0x66,0xb5,0x0f,0x69,0x2e,0x39,0x5e,0xb8,0x33,0x86,0xe0,0x27,0xc8,0x2c,0xe3,0xfd,0xee,0x3b,0xd8,0x99,0xb0,0xd3,0x17,0x9d,0xb0,0x86,0xfb,0xf5,0x24,0xf5,0x74,0x59,},{0x44,0x85,0x36,0xe9,0x82,0x40,0x84,0x37,0xce,0x89,0x67,0x40,0x53,0xe3,0xc5,0x89,0xc9,0x8c,0x09,0x5c,0x60,0x02,0x1a,0x11,0x81,0x78,0xc6,0x26,0x1d,0x88,0x10,0xfe,},{0xbd,0x13,0xf6,0x36,0x2c,0x07,0x07,0x89,0x22,0xf3,0x0c,0x63,0x30,0x75,0x1b,0xf6,0xe7,0xcf,0x42,0xa7,0x69,0x16,0xee,0x65,0x3e,0xb1,0x7a,0xcc,0xff,0x1f,0xbb,0xca,0x35,0x25,0x8c,0x4c,0xbc,0x58,0x2a,0x5e,0x8c,0xc9,0x4f,0xd2,0xc7,0xed,0xeb,0x53,0x76,0x2f,0x1f,0xc2,0x31,0x23,0xd7,0xf4,0xf1,0x45,0x40,0x9b,0x31,0xcd,0x38,0x02,},"\x74\x28\xa9\x64\x21\x2b\xcb\xe8\xdf\x7d\x59\xe4\x8e\x92\x34\x80\xaa\x0e\xe0\x9b\x91\x0d\x04\xef\xb6\x90\x36\x62\xef\xc3\x10\x7a\xc8\xfd\xc0\xc5\xf3\x92\x72\x74\x0c\xd8\x77\xe1\x6c\xd7\x1c\x54\x92\x38\xc3\x37\x22\x0c\xe2\xf6\xb5\xa1\xfc\x6f\x7b\x0a\x1c\xd4\xed\x21\xd9\x38\x89\x08\x1e\x34\xfb\x7f\xde\xcf\x41\x78\xbb\xd4\x31\xe6\x11\xe5\x39\xd9\x00\xc3\xd0\xac\x3d\xc7\x10\x7b\x36\xb4\x1d\x6d\x0d\x5d\x32\xc1\x97\x27\xf9\x08\xb6\xeb\x36\x7f\xeb\xb3\x52\xa4\x93\x58\x1f\xf1\x28\xb5\x6c\x4c\xaf\x6f\xb8\xe0\x99\x81\xf0\xd3\x79\x57\xd1\x28\x20\x17\xfb\xb8\x07\x61\x4c\x20\xf4\x65\xdc\x02\xb0\xcd\x96\x99\x83\xbd\x5a\xe1\xeb\xf6\x57\x8d\x7f\xf3\xce\xff\x32\x0e\x25\x56\x21\x99\xde\xe9\x34\x75\x7c\xc1\xf5\x8d\x55\x40\xc4\x1a\xac\x1c\xe4\xf2\x11\xf0\xb8\xec\x41\x07\x17\x40\x30\xe7\x02\xbc\x6a\x8a\x9c\x85\xc5\x05\xc9\x31\x6a\xef\xea\x3e\x43\x72\x24\x2d\xe0\x19\xb3\x5e\x2b\xd3\xc5\xa9\x56\x52\x19\x71\xc1\x06\xa3\xad\xbb\xc1\x3c\xdc\x4f\x7f\x9d\x3c\x58\xb9\x6a\x34\x4b\x4a\xc3\xef\x6b\xd8\xac\xa6\xed\x98\x76\xb4\x3e\x64\x97\xfa\xf7\xfa\x4c\xf2\x7f\xbc\xb6\x65\x73\x0c\x09\x1e\x13\xaa\xf7\xe9\xef\xe7\xdd\x10\xe1\x4e\xb1\x9a\x92\x00\x42\x42\x10\xec\x8b\x8f\xba\x7e\x69\x44\x4c\xe1\xa9\xe3\xa7\xb2\x6c\x11\xf6\xb7\x14\x5b\x69\x83\xa7\x80\x57\x76\x48\x40\x31\xbf\xf5\x2e\x81\xae\x76\x9b\x70\xa2\x82\xb0\x94\xff\xb5\xfb\x55\x25\xdc\x1a\x87\x2e\x20\x7e\x82\x7a\x2e\x11\xf4\xec\xf7\xb5\x30\x8c\x74\x8a\x92\x78\xea\x7b\xd6\x61\x88\x19\x44\x00\x43\x0c\x8c\xd5\x96\xeb\xb8\x72\x21\xe5\x36\xf6\xaf\xe1\xf1\x50\x5d\x6a\x59\xf4\x1d\x16\xa2\xf0\x14\xe1\xcf\xa5\x13\xf7\xa6\x97\x31\xd7\xbf\xdb\x2a\xff\xce\xfe\x05\x37\xd4\x2c\x79\x6e\x3f\xd2\x7e\x41\xb7\xca\x72\x05\x1b\xef\x28\xbb\x7b\xde\x70\x10\xdc\xfe\xd8\xaa\x16\xef\x67\x6d\xb6\xe5\x20\xc3\xce\xf8\xd6\xf5\x8a\x9a\x28\x13\xcf\xf0\xf7\x04\x1f\x87\xfb\xfb\x84\x31\xe0\x20\xed\xe1\xd4\xea\xf1\x9e\x23\xb9\x83\x44\x5c\x59\x15\xb5\x4a\xdf\xb5\x57\xfc\x20\xd0\x05\x8f\x40\xf5\xe0\x98\x25\xdb\xa8\xd8\xf2\x0c\x00\xf4\x3b\x3a\xee\xbb\x61\x57\xbe\x32\xec\x54\x62\x7d\x5d\x42\xab\x81\x3c\xf9\x7f\x09\x5d\x26\xdb\x80\x36\xc1\x2e\x82\xcb\x96\x3e\x80\x01\x16\x7e\x61\xab\x39\x3b\x4c\xca\x75\x5e\xce\xa8\x69\x95\x4e\x32\x3f\xa5\x26\x2c\x5f\xda\x3e\x0b\xe9\xa5\x1e\x5a\xf5\x1f\xa6\x44\x48\x24\xfb\x83\x7c\xc6\x7b\xe5\x37\xa8\x75\x69\xc3\x0c\xf0\x11\x4d\x39\xa0\x39\x42\xde\x4e\x1c\xd5\x23\x35\x5d\xab\x1a\xf3\x60\x80\xa9\xa9\xa5\x48\xbe\x1c\x2a\x7f\xbe\x54\x33\x77\x23\x15\xd2\x83\xe5\x15\x6d\xf6\x48\xbe\xe4\xb7\xdc\xda\x74\xf1\x59\x05\xd5\x42\xbe\x54\x87\x3c\x15\xc5\x3f\xf4\x2a\xca\xbf\x8c\x56\xf2\x57\xd7\x64\x72\x2d\xb4\xe9\xc7\x18\xe1\x20\x98\xa3\x45\x74\x86\xa6\xc9\x47\xac\x2d\xe0\xaf\x53\xe8\x2c\xf9\x50\xbb\x37\xca\x29\xc8\xda\xdf\xa3\x64\x6d\xb4\x98\x2a\xf5\x72\xd3\x9b\x26\x8c\x7f\x96\xb0\x3e\xf6\xb6\x53\xc8\x79\x45\xf2\x9b\xc5"}, +{{0x55,0x32,0x8b,0xe4,0xb3,0x70,0x82,0x27,0x33,0xff,0x39,0x89,0xa6,0xa3,0x28,0x2d,0x65,0xfe,0x8f,0x20,0x7a,0xb7,0x27,0x0d,0x7c,0x2e,0x72,0x7c,0xa3,0xcf,0xaa,0xc4,},{0x51,0x8e,0x02,0xee,0xf5,0x2f,0x5a,0xae,0xbd,0xe3,0xd1,0x08,0xea,0x79,0xec,0xad,0xfc,0x4d,0x99,0x4c,0xe1,0x95,0x36,0x21,0xe5,0x4b,0x7b,0x3b,0x12,0x1f,0xf8,0xff,},{0xf5,0x8d,0xb1,0x9f,0xd8,0x34,0xe1,0x51,0x94,0xc3,0xc0,0xf8,0xa6,0xa5,0x0e,0xbc,0x4c,0xf0,0x74,0xe8,0x0e,0xa2,0xe7,0x0c,0xda,0xf1,0xe1,0x69,0xbd,0x51,0xeb,0xd0,0x99,0x0b,0xad,0x77,0xc4,0xfa,0x20,0x8b,0x8d,0xd1,0xe2,0xc8,0x57,0x4c,0x01,0xb5,0xf5,0x96,0xc8,0xdf,0xa6,0xbb,0x8e,0x6a,0xe3,0xa4,0x7f,0xf4,0x12,0xe7,0xe2,0x09,},"\x6c\x24\xc9\xaf\xbb\xf1\x2d\xca\xee\x6f\x10\xe4\x08\x92\x52\xf2\xc6\x0b\x2a\xb9\x3a\x02\xc1\x60\x2f\xb5\xde\x4c\xe3\xbd\x92\x3e\xb0\x2f\xe1\x03\x9f\xdc\x15\x99\x6a\x44\x69\x15\xe7\x67\xde\xe0\x17\x6d\xdd\xb7\x8e\x9d\x6b\xbf\x06\x96\x75\x77\x5a\x82\x9d\xd8\x08\xd3\x76\xb0\xcf\x79\x20\xbf\x1a\x66\xe1\x30\x3b\xa5\x24\x19\x78\x5f\x25\xf2\x8b\xb3\x38\x99\xeb\xde\x84\x0c\x0a\xb1\x4b\x91\x9a\x65\x80\xcb\xaa\xc3\xa8\x05\x62\x7b\x9c\x4a\x77\xba\xa1\x6f\x82\x5a\x9e\xac\x2d\x6d\x36\x41\x65\x14\x93\x37\x0e\x50\xee\xe9\x4c\x74\x04\x97\x64\x36\x56\x05\xab\x4d\xac\x1a\x03\x02\x27\xa3\x30\xaa\x17\x8f\x2f\x8d\xa3\x77\xaf\x73\xf0\xbb\x04\x0b\xac\x12\x36\x6e\x65\xe0\x59\x10\x55\xf9\xf2\x3e\xac\xa3\x5e\x96\x88\xd8\x37\xa3\xc0\xd9\x9c\x16\x8f\xd8\x86\xac\xc9\x22\xcf\x37\xa7\x11\x8e\xf8\xa4\x4b\xb0\xa4\xfa\x42\x88\x04\x93\x09\xa7\xdc\x1b\xed\x80\x62\x1e\x10\x63\xe3\xe5\x92\xc0\xfb\xa4\x2d\x73\x98\xeb\x15\xf7\x40\x28\xac\x15\xd7\xed\x65\xa6\x36\x8a\x13\xb7\xf9\x56\xd1\x95\x47\xeb\x50\x6c\xe7\xec\x90\x73\x4e\xb9\x49\xcf\xf1\xd9\x8c\xe4\x14\xf1\x0a\xdc\xba\x8c\x00\x73\x20\x01\x87\x50\xa7\x1b\xd3\x6d\x3b\x6b\xfd\x61\x27\x05\x45\x08\xe3\xef\x65\xd9\x98\x48\x51\x4d\x33\xd6\x8b\x58\xe3\xa4\xb2\x24\xf7\x9b\x6e\x34\xdd\x48\x03\x40\x46\x7f\xe7\xf0\x25\xcc\x88\x21\x3d\x80\x8f\xbb\x5b\x91\xe2\xe4\x3c\xf9\xd9\x50\x64\x07\x98\x65\x92\x73\xd4\x7a\x25\xf1\xf0\x13\x2f\x68\x82\xfa\xad\xba\xfb\xa2\x8f\xee\x5f\xa1\x72\x72\xc1\xa9\x00\x11\x72\xb3\xab\x6f\xf2\xc3\x15\xf2\x6c\x07\x73\x44\x05\xb5\xee\x8b\x5e\x4f\x08\xe1\xe3\xb8\xae\xa0\x19\x46\x7f\xb0\x71\x88\x7f\x19\x19\x01\xa2\x1c\x59\x76\xc1\xca\x8a\xaf\x0a\x1d\x4a\x2e\x69\x8e\x76\x23\xe9\xbb\xe9\xca\x2a\x67\xa1\x53\xa1\x6f\x89\x5e\x6d\xd9\xea\x92\x44\x41\xb4\xbd\x0b\x67\x45\x52\xe3\x98\xb8\xd9\x70\x34\x3a\x9b\xc7\x76\xa3\xa3\xfc\x1a\x86\x60\xc5\x62\x5d\x60\x81\xb5\xd8\x7f\x0f\x8a\xc9\xf0\x7a\xb5\xab\xe7\x7c\xdb\x8e\x30\xd2\xfd\x1f\x6f\x46\x52\x5c\x75\xdd\x0d\xd1\xca\x32\x81\xcc\x89\x34\x6f\xb3\xe6\xd7\x38\x8e\xbe\xe1\x54\xcb\x59\xbd\x9e\x95\xed\x6a\x41\xd5\xdf\x66\x8b\x59\xea\x13\x78\x68\xeb\x12\x0b\x8a\x2c\xfd\xf4\x67\x44\x14\xfd\x27\x96\x99\xf2\x8b\x5a\x5c\xcc\x2e\x2f\xc8\x02\xa4\xc9\xe0\xb8\x5b\x76\xf2\x0f\x6b\xce\x2a\x49\x54\x88\x6f\xc4\x02\x67\x0a\x71\xef\xd2\x61\xf5\xdd\x7b\xca\x16\x88\x4a\x28\x7c\x62\x2f\xd4\x45\xf6\x8d\x44\x15\x1c\xc0\x13\x4b\x22\x9d\xa3\x8d\xaa\xab\x81\xb5\xc9\x60\xd5\x77\x00\xca\x92\xb2\x6d\x0b\x14\x21\x34\xce\x94\xb7\xbe\x6c\x18\x61\x0e\xa2\x13\x6f\x8b\xa8\x32\x9a\x2e\x8c\x00\x0b\x8f\x02\xfe\x05\xbc\xf7\x2c\xb7\x1f\x8c\x72\x53\x5f\xfc\xd8\x18\xe3\x8e\x79\x92\xa8\xf0\xc3\x2a\xc6\x21\x77\xd1\x52\x2a\xe5\x52\xc6\x0c\x1e\xe6\x16\xb7\x5e\x4b\x34\x42\xe7\x96\x57\xe4\xa3\x33\xc0\xb3\xd7\x44\xea\xf2\x60\xd0\xc3\x36\x93\x16\x86\xa6\xd6\x68\xc6\x4f\xef\x44\x00\x52\x35\x2c\x2b\x25\x8c\xfb\x65"}, +{{0x7d,0xa0,0x5f,0x04,0xe5,0xd3,0x8b,0x98,0x9b,0x83,0xf7,0x2f,0x7a,0xb2,0x6c,0x13,0x87,0x76,0x75,0x8f,0x4f,0x57,0x7e,0x49,0xdc,0x73,0xd6,0x01,0x3f,0xf4,0x37,0x59,},{0xb1,0xde,0x51,0x67,0xf4,0xd3,0x30,0x80,0x4e,0xec,0x9e,0xb5,0x65,0xef,0x40,0x55,0xf1,0xb6,0x4d,0xd9,0x5e,0x1c,0x9b,0x27,0xc6,0x7f,0xfe,0xf9,0x14,0x82,0xcc,0xa8,},{0x05,0xf1,0x17,0xf9,0xbc,0x3e,0xa5,0x5d,0x45,0x5e,0x9e,0xf1,0x35,0xe9,0x2e,0x76,0x65,0xd1,0x80,0x70,0xd8,0xf5,0xe3,0x75,0xdf,0x67,0xbe,0x18,0x17,0xce,0x14,0x35,0x7a,0x55,0xe7,0x01,0x66,0xf3,0x26,0xb7,0x7d,0x85,0x24,0x32,0x27,0xcf,0x67,0xd8,0xf2,0xe0,0xbf,0x84,0x40,0xca,0xbf,0xb0,0x52,0x75,0xb3,0x73,0xf1,0xe1,0x19,0x0e,},"\xa6\xa8\x61\xd8\x94\x7c\x5c\xd6\xad\x08\x19\x60\x2e\x32\xea\x76\x81\xc8\xf7\x30\x10\xee\xe5\x53\xe5\xde\xfb\xf7\x98\x20\x98\xb5\xf7\xb3\x99\x24\xbb\x79\x59\xad\x64\xc3\x03\x26\xbe\xd5\x60\xbf\x51\xe9\x98\x3c\xda\x5d\xff\x4f\x31\x1e\xea\x24\xcb\xe6\x8c\x61\x06\xce\xac\x9b\x84\x3a\xa4\xe2\xad\x1b\x6f\x8a\xe1\xe4\xf9\x68\x71\xfc\x02\x5b\xe4\xa6\x16\x38\x5f\xf2\xd4\xb7\xf5\x68\x29\xab\xef\xaf\x6a\xac\xbb\x78\x0d\x6c\xbb\xc9\x51\xb6\xe0\x5a\x78\x7f\x88\x5e\x33\x25\x61\x16\x65\xec\xc9\x24\x27\x4a\xa5\x31\xbc\x13\x3f\x62\xc7\x6c\xb3\xad\x14\x8f\x3c\x95\x79\xa8\x15\xa1\x42\x00\xb7\x64\x8d\xae\x0b\x07\xb3\x27\xd3\xbf\xcc\xdb\x6f\xe3\xb6\xcb\xd7\x0e\xa6\x5e\x6c\x0c\xc2\x51\x6a\x89\x66\x96\xd0\x7b\x2e\x77\x71\x3b\x0b\xee\x3b\x92\xfb\x1b\x6f\x75\xb0\x82\x0a\x5c\xb6\x2c\x5f\xe6\x20\x40\x03\x94\x3e\x24\x85\x71\x66\xfb\xdf\x57\x1f\x11\x5d\x45\xf4\x2e\x75\x90\x1d\xf8\xb1\x2c\x32\x61\x8a\xac\xb0\xd2\x42\x86\xc8\xd3\x03\x96\x05\x1f\xc2\x72\xaa\x17\xf4\xd2\xd4\x74\x61\x15\x2a\xac\xd3\xfa\xa2\xb7\xb2\x08\x31\x22\x78\xe8\x09\x24\x05\x92\xd1\xd1\xaa\x58\x5c\x56\x28\x0e\x66\xff\xd9\x2b\x57\x17\xd0\xcd\x1e\xb9\xfb\x74\x01\xde\xf8\x79\x48\x7c\x37\x4e\x5c\x53\x0b\x6f\xeb\xf9\x11\x12\x25\x74\xd2\x4f\xe1\x04\xb4\xf4\x5c\x7c\x60\x1e\x6c\x91\x7d\x3c\x18\x82\xc1\xad\x3c\x55\x5d\x8f\x2c\xe9\x55\xb5\xa1\x0d\xb0\xd5\xa8\xb8\xac\x7a\x62\x66\xb2\xe6\xb2\x7a\xd0\xee\x34\xf4\x7a\xd8\x57\x36\x7d\x52\xf7\x09\x6d\x4b\xac\xef\x0e\x46\x72\x54\x88\x42\x4b\x93\xb8\x9a\xcd\x42\x9f\xfb\x5e\xf3\x3a\x0b\x08\x1d\xd0\x94\x79\x67\x91\x96\x02\x3c\x39\x67\xf4\x4a\xd4\x1e\xb1\xa2\x39\x55\x27\xfd\x3b\x79\x76\x8f\x1b\x88\x5f\x04\x29\xb4\x95\xab\x60\x52\x56\x91\xbe\x84\x65\x06\x32\xa2\xf6\x6c\xb6\x3a\xd5\xbf\x2f\x6a\xe7\x0b\x66\x8c\x5a\x19\x3f\x74\x99\xfc\x4f\xc4\x2c\xf8\xcb\x30\x8c\xe5\x02\x9a\x50\x27\xba\xbe\xf5\x5d\x19\x25\xec\xfb\xa9\xf2\x7e\xb6\x08\x16\x19\xed\x0d\xf8\x56\x9f\xd8\x0e\x9d\xa1\x04\xdb\x39\xb5\xb8\x14\x0b\xfe\xbe\xbd\x29\x08\x54\x40\x06\x58\x19\xde\xba\x8d\x46\x9a\xe8\xb3\xea\x6d\x3b\xac\x58\x91\xf9\xa4\xdd\xfb\x7f\x1f\x06\xd1\x3c\x31\xa0\x7e\xe5\x3f\xb5\x4b\xc9\x7b\xd0\x86\x96\x39\x4c\x38\xe7\xf3\x68\x0c\x0f\x02\xf9\x75\xf4\x69\x92\x11\x47\xa4\x09\x85\x90\x97\x81\x3b\x4c\x3f\xa4\x3d\x17\x4a\xc4\x02\xf1\xa5\x28\xcb\x5f\xc4\xb8\x07\x51\x84\x32\xef\xf3\x34\x07\xa1\x11\xca\x3a\x3d\x7e\x9e\x84\x13\x5a\xba\xc8\xa8\xf5\x2e\xa6\x31\xc8\x6d\x74\xa1\xc6\xe5\x74\x9e\xdd\x14\x91\xc0\x02\x4e\x7d\xe7\xfe\x52\x85\x68\x29\xb7\x2f\xd1\x3d\xa6\x3a\x1a\x23\x43\x34\x9d\xf6\x62\xab\x31\x63\x53\x60\x32\x34\x6e\x53\x47\xf0\x43\xff\xf5\x28\xbf\x67\x15\x09\x22\xff\xf2\x02\x6b\xab\x74\x2d\xb9\xca\xe7\xcb\x2e\x3c\x74\x58\x07\x19\x65\x2c\x28\x44\x7c\x5e\x20\x98\x23\x17\x97\xee\x6e\xf1\x23\x1f\x57\x92\x05\x4b\xc3\x35\x9a\x32\xc8\x6d\x2f\x94\xf8\x5f\xa7\xd4\xa7\x41\x9d\xd2\x41\xff\x66\x2a"}, +{{0x1b,0x8e,0xc6,0x58,0x80,0xed,0xbf,0x03,0x9a,0x13,0xe9,0x70,0xb1,0x5a,0xa6,0x7e,0x19,0x2a,0xa0,0x2c,0xa6,0x5c,0xff,0x9a,0xda,0x17,0xd4,0x55,0x8f,0x40,0x13,0x7d,},{0x12,0xc1,0x19,0x1e,0x4d,0xe3,0xbd,0x44,0xd0,0x39,0x07,0x01,0x53,0xad,0xb7,0xb5,0x81,0xf6,0x00,0xe9,0xa1,0xdd,0x69,0xaa,0x89,0xf2,0x77,0xc7,0x06,0x9e,0x76,0xf8,},{0xbf,0xf2,0x69,0xa3,0x5d,0x6c,0x8e,0x55,0x2c,0xe7,0x16,0xd1,0x63,0x81,0x81,0xce,0x85,0x83,0xb4,0x5c,0x0e,0xc5,0x93,0xb4,0xe5,0x8c,0x40,0xac,0x76,0xe7,0xf8,0x5c,0xa1,0xda,0xff,0xfd,0x68,0x54,0x1e,0x62,0x3a,0x1e,0x35,0xa7,0xc0,0x97,0x26,0x88,0xb2,0x5e,0xed,0x72,0xf4,0xda,0x57,0xec,0xa1,0x68,0x57,0xa8,0x26,0x3c,0xaa,0x0b,},"\x37\xf1\x8b\x7f\x64\xc5\x13\x34\x79\xd6\xda\xe3\xbe\xf6\x79\xcd\xc2\x1e\xce\x3f\x5b\x57\x9a\x6a\x9c\x3f\xa2\xe5\x9e\x9b\xe8\x7d\x20\x09\xf7\x4e\x1c\xfd\xac\xcb\x1c\xe3\x7d\x00\x70\x23\x69\xbd\x16\x9d\x94\xfd\xcf\x85\xaf\x9f\xa3\x21\x7d\x27\xe6\xed\x6d\x1d\x8e\x5d\xf7\x61\x5e\x8e\x37\xea\x55\xde\x1f\xd0\xb0\x6d\x77\xb4\xc8\x3b\x92\x9d\x80\x58\x6f\xa0\x69\x4b\xe7\x2e\xc8\xb3\x65\xad\x2c\xbc\xdd\x2b\x1a\xd8\xcf\x7f\x03\x6d\xfa\x4d\xaa\x1a\x90\x36\xcd\xb1\x20\x43\x22\x27\xb1\xf0\x7b\x88\x66\xb1\x22\x12\x03\x09\xeb\x91\x4a\xb8\x4c\xdd\xeb\xa1\xde\xc4\x8a\xb9\x26\x36\x72\x85\x88\xfe\xdb\x3a\xaa\xd7\xe7\xdb\xb2\xac\x30\xe6\x3c\x6f\x5f\x90\xfc\x6c\xe6\x2d\x6d\x3b\xd8\x8b\x0d\x5a\xac\xfa\x61\xde\x9f\x32\x67\xb3\x00\x91\x7b\x57\xa4\x80\x36\xab\x20\xc9\xa0\x54\x46\xb8\x76\x74\x94\xaf\x24\x9e\x7d\xe7\xbc\x50\x7a\x22\x07\xcc\x95\x6f\x71\x84\x55\x5a\x7d\x5d\x88\x83\xbb\x4b\x3e\x93\xf2\xdc\xfc\x57\xb0\xda\x86\x38\x65\x8d\xcd\xce\x88\x5d\x44\xd9\xcc\x68\xb1\xd8\x17\x0a\x36\x77\xcc\x5e\x50\xcb\xf3\x3d\x54\x3e\xba\xe4\x47\x7d\x92\x39\xcf\x83\x38\x4e\xc5\x9b\x42\x33\xe8\xff\x33\x43\xf0\x6f\x30\x18\x77\x72\x9a\x53\xd4\x20\xbf\x01\xc6\x2e\x66\xab\x7f\xe5\x5d\xd8\x7e\xe8\x23\xa5\x8f\xcb\x87\x87\x0e\x1f\x52\xe8\x79\x17\x7c\xd4\x39\xc5\x33\xf5\xa2\x23\xe5\xa3\x43\x6f\xe9\xd6\x42\x65\x48\xda\xcf\xc8\x6a\x08\x46\xd3\xed\x23\xac\x04\x25\x63\xe8\x87\xff\x46\xaa\xd0\x05\xf4\xe1\xde\xe3\xee\x0e\xe4\xc2\x7a\x72\x51\x70\x9a\xe4\x0a\xbc\x5e\x25\x68\x64\xe4\x78\x5a\x4e\xdd\x8b\x2a\xdf\x1b\xc5\xb4\x01\x8e\x28\xd0\xb1\x75\x86\x7b\x02\xd0\x52\xa6\xe1\x7e\x41\x1a\x3d\x8b\xeb\x2a\x42\x08\xb7\x6c\xc6\x21\xfd\x18\xbe\x14\x8e\x23\x5d\x55\xaa\x71\x27\x70\x65\x57\xde\xc0\x53\xa1\x3f\x1a\x47\xdf\xda\x40\x5b\x3f\xe5\xbd\x28\xef\x5d\x34\x86\x19\xf5\x1e\x59\x5e\xf5\x05\x5f\x83\x9e\xfa\xf1\x10\xe4\x90\x16\x31\xac\x31\xa0\x2f\x4f\x7e\xe4\x24\xa3\xa2\xc3\xe0\x0d\x26\x02\xd2\xcc\x1e\x49\x29\x06\xee\xa4\x20\xa9\x26\x82\x38\xac\x66\x22\xa0\x89\x74\xe5\x73\x02\x92\xe6\xed\x51\x02\x56\xef\xde\x66\x7e\x0d\x9a\x0f\xf2\x21\x3f\x54\x12\x0c\xcd\x81\xff\xaa\x6b\x7c\xc4\x81\x41\xa2\xb7\x29\x85\x2a\xf5\x83\xd2\x6a\xa5\x1f\xbd\xe6\x7b\xe4\xdf\x14\xe5\x20\xc2\x25\x7a\x73\xc5\xc2\xe3\xc3\xd8\x7d\xfb\x25\x36\x11\x75\xfd\x18\xab\xd7\xe9\x9a\xa0\x9b\x85\xf8\x8f\x19\xc8\xd8\x2d\x45\x85\x8f\x31\x44\xc5\xdf\xb7\xa4\x9e\xde\x45\xb4\xef\xd8\x71\x05\x92\xa3\x72\x06\x36\xe7\xe8\x89\xc7\xe2\x2a\xd1\x3b\x2d\x44\xbb\x7e\x2b\x47\xb2\x96\x3a\x5f\xa3\xf2\x55\x7b\x85\xbc\x0c\x69\x3d\xe3\xd2\x2e\xf9\x46\x4f\x7b\x81\x4a\x20\xa4\x67\x6a\xd2\x6f\xca\xa0\x35\x44\xc6\xaa\xd4\x12\x83\x09\x5f\xcd\x12\x10\xaa\x8c\xc0\x29\xff\x5a\x26\x00\x5a\x89\x12\x26\xc2\x98\xe9\x4a\x52\xaa\x71\x33\x91\x3e\xc9\xd2\x2a\x5b\x2a\xc0\xbc\x6f\x15\xb2\x51\xd0\xb9\x38\x89\x21\x3c\xd1\xb1\xe5\xc6\xfd\x08\xf1\xa8\xf5\xcb\xd4\x21\x53\x29\xa3"}, +{{0xe7,0x53,0x88,0x02,0x6a,0x6a,0x6d,0x6c,0x6d,0x19,0x9e,0x36,0x29,0x93,0xa5,0xb1,0x04,0x49,0x01,0xe1,0x8a,0x76,0xc2,0xfa,0xc7,0x26,0x1a,0x6d,0x1c,0x19,0xa4,0xf3,},{0xb9,0xce,0x14,0x25,0x1c,0x0c,0xdf,0x3b,0xdd,0xb2,0x06,0xdc,0x6b,0x8b,0x2b,0x7f,0x5b,0x7e,0x4d,0xd1,0xbe,0x2c,0xe1,0x86,0x3f,0xf1,0x88,0x06,0xae,0x00,0xf1,0xee,},{0x6d,0x0f,0x83,0xd9,0xc5,0x5d,0x84,0xbc,0xf9,0xa8,0x61,0x47,0xd9,0xb6,0xba,0x9a,0xd5,0x37,0x83,0x2f,0xd0,0xf9,0x9d,0xae,0x7e,0x72,0xc8,0x13,0x9a,0xfc,0xb3,0x0c,0x7b,0x24,0xf6,0xb2,0x92,0xe3,0x2f,0x98,0x47,0x09,0x75,0x51,0xb7,0xfb,0xfd,0x51,0x0c,0x84,0xe8,0x9b,0xe9,0x82,0x54,0x44,0x14,0x57,0xbd,0x08,0xe5,0xf0,0x53,0x02,},"\xb9\x9c\xdc\x84\x72\x11\xc0\x66\x42\xdd\x11\x1b\xc5\xe0\xbe\xca\x53\xa7\x4f\xfb\xa2\xe3\xac\x93\xaf\xb4\xb0\x94\x75\x18\xe8\x32\x35\x27\x33\x0a\x4e\xfe\xfb\xe4\xba\xfa\x00\xba\xfe\xcb\x43\x4a\xb1\xe5\xb7\xce\x65\x65\x6f\x7a\x4f\xd8\x56\xaa\x6c\x38\x5e\xd8\xd7\xbd\x62\x85\x58\x0d\x7d\xd6\x08\x82\xe6\x9c\x19\xda\x07\x69\x09\xd6\x47\xde\x09\x5a\x80\xe9\x8a\xd8\x9b\x81\x4a\xad\xcb\xbf\x6f\x03\x3c\x49\x20\x2f\x65\x6c\x09\x10\x50\x39\x59\xcf\x97\xcd\x0f\xa8\x2d\x5f\x6d\x22\xfb\xa3\x38\x99\x51\x29\x4c\x4f\x7c\xdc\x21\xeb\x82\x44\xbd\x65\x60\x63\x7a\x5e\xca\x62\xa8\xeb\xa1\xf4\xa9\x33\xd1\x87\xa7\x5f\x86\x71\x16\x43\xaf\x35\x88\x31\xc8\xc1\x6a\x9a\x0f\x09\xe2\x53\xb2\x39\x5e\x9c\xb3\x71\x61\x1e\xec\xdd\x66\xb4\xab\x52\x1a\xa9\x4b\x3f\x20\x23\x7e\xae\x41\xcd\x10\xc5\xe2\x1a\x45\x2d\x48\xe7\x48\x18\x7f\x35\x4a\x67\xad\xf6\x81\xb0\xfe\x61\xcd\xae\xc9\x4a\x5e\xaf\x01\x26\x9f\xce\xb5\x70\xd5\x14\xff\x3c\x55\xff\x1d\xba\x2f\xd2\xdf\x17\xf8\x6a\x8a\xeb\x74\x78\x38\x11\x3d\xee\x94\xa4\x3b\x13\x84\xcb\xe1\x33\xcd\xf6\x42\x7e\x8d\x12\x2e\x4e\x93\x37\x04\xda\x6e\x26\xcf\xce\xe9\x7f\xe3\xf6\x29\xb6\x0b\x91\xb2\xdd\x86\x38\x67\xfa\x79\x80\x1e\x2b\x91\x6e\xc4\xc0\xfb\x62\xe0\x71\x59\x42\x1e\x65\x79\x74\x30\x7a\x1d\x02\xf7\xf2\xed\x47\x24\xa8\xb5\x21\xa8\x61\xf5\x5f\x35\x52\x1e\x8b\x2e\x1a\x84\x90\x4c\x42\x8c\xfc\x5b\x60\x14\xbb\x0f\x8b\xa8\x43\x4c\x22\x09\xbd\x40\xac\xa3\x11\x30\xdb\x97\x74\x33\x33\x59\x7d\x23\x51\xd5\xf6\x81\x17\x41\xf6\x26\x88\x97\x3b\xd7\x73\xd3\x02\x66\xfd\x1e\xfb\xd8\x9d\x47\xa9\x64\xf9\xd0\x19\x97\x15\x3d\x08\x7d\x92\x69\x66\x16\xdd\x10\x3a\x93\x4c\xcb\xac\x4c\x1d\x14\x2f\x20\x75\xd4\xe2\x2c\x3d\xa4\xa0\xe9\x73\xb2\x38\x63\x19\x62\x87\xb7\x91\x74\xfa\x29\x75\x5f\xc6\xd9\xb5\xe1\x00\xac\xe0\xa4\x59\x75\xe5\x03\xb2\x54\xd3\xf1\x95\xc2\x61\x71\x09\x10\xfe\xf1\x06\x89\x2c\x08\xbb\x29\x6d\x23\x0c\xde\xa9\xf5\xa1\x1f\x91\xac\xaa\x6e\x7c\x05\xe9\x2c\x28\x1d\x2b\x31\x55\xfe\x44\x80\xb0\xaa\x5e\x0d\xb4\x1d\x10\xe0\x5c\xfd\xef\xa4\x36\x40\x51\xcb\x75\x5d\xc7\x2f\xfa\x97\x8c\x00\xb9\x4a\x5f\x21\x2d\xc6\x91\xf8\x39\xb4\x9d\xe9\x7e\x01\x39\xd6\x5e\x8d\x73\xb2\xb2\x89\xb2\x6a\x12\xc6\xcc\xd8\xed\xc0\x4a\xdb\x45\x2a\xf7\xff\x09\x4a\xa9\x01\xea\xf5\x76\x51\xeb\x1b\x87\xb8\x33\xd0\xa0\x9b\x4a\x4a\x64\x62\xf4\x06\x64\x62\x37\x69\xe9\x50\x79\xf3\xc9\x62\x85\x0c\xc3\xb4\x01\xbb\x00\x58\xb8\x47\x5b\x10\xc8\x62\xf3\x2f\x30\x0a\x2b\x14\x3b\x3d\xea\x26\x9d\xdc\xbe\xa7\xbe\x7d\xd2\x42\x6d\x0d\x42\x04\xeb\x66\xa3\x9f\x13\x18\x82\x2d\xcb\x9c\x56\x13\x98\x63\x7f\x4a\xb8\xde\x19\x67\x68\xac\xe7\x4f\x34\x8c\x01\x2d\xd1\xba\xbe\xc1\x7f\x53\x00\xff\xe0\xd7\xaa\xae\xaf\xef\x7d\xb6\x50\xa8\xf2\xf3\x09\xa9\x79\x3f\x52\xc6\x85\xc7\xe1\xd5\x13\x32\x74\x91\x57\x84\x89\x9c\x48\x1d\x48\x5c\x9b\xd3\x0e\x99\xfc\xdc\x97\xd9\x6e\xf0\x74\x87\xda\x66\x3b\xef\xe6\x82\x99\xdf"}, +{{0x5b,0x32,0x3f,0xc0,0x1a,0x16,0xc4,0x5d,0x10,0x64,0x66,0x7d,0x2e,0xa4,0xa7,0xea,0x59,0xd2,0x03,0x42,0x56,0x2d,0x12,0xfb,0xc5,0x98,0xd5,0xaa,0x73,0x00,0x68,0x8e,},{0xd4,0x14,0x1b,0x45,0x5d,0x30,0x16,0x42,0xba,0xda,0x28,0x14,0xaf,0xcb,0x16,0x20,0xd5,0xeb,0x56,0xd9,0x2b,0x11,0x85,0xfe,0x5d,0xad,0xef,0x55,0x96,0x25,0xfa,0x71,},{0xe2,0xef,0xf6,0x07,0xf0,0x22,0x7a,0x29,0xd5,0x82,0xd6,0x9f,0x34,0x58,0xac,0xad,0xd3,0x22,0x6f,0xce,0xaa,0xc0,0xab,0xbd,0xae,0xd5,0x26,0x75,0xc5,0x16,0x30,0x07,0x3c,0xd3,0xa9,0x01,0x70,0x7e,0xcf,0x05,0xe8,0x93,0xf2,0xc3,0x6d,0xaa,0xf0,0xcc,0x49,0x01,0x11,0x69,0x46,0xb5,0x77,0x0d,0xc0,0x38,0x12,0x5f,0x6d,0x13,0x1b,0x09,},"\xad\x24\x66\x9e\xf5\x5c\x54\x0a\x8e\xd1\x62\xce\x1d\x28\xf0\x17\x60\xa6\x07\x19\xa0\x37\x73\x36\xeb\x00\xb1\xec\xbe\x6f\x61\x60\x1c\xd5\x64\xf9\x2c\x95\x68\x04\xf9\xbe\xd4\xe1\x47\x6b\x94\xe5\xea\x8c\xca\x80\xcb\x49\xa3\x04\xef\x85\x1f\x7f\x67\x5a\xbe\x58\xe6\x68\x1d\xc0\x12\xad\x55\xe5\x1b\x02\x1d\x98\x28\x56\x9d\x0b\xcc\x9e\x05\x27\xa3\xfc\x03\xc8\x91\xd1\x7a\x90\xe6\x33\x7a\x1e\xa6\x7f\x2f\x08\x81\x05\x87\x69\x38\x37\x08\x1e\x4c\x08\xa3\xd7\x2c\x53\x6c\x21\x40\xda\x20\x0b\xa4\x56\xc3\x76\xf6\x1d\x05\x65\x1f\x0c\x5f\x39\x57\x11\xf4\x1c\x0d\x6e\xae\x98\xc9\x06\x76\x4d\x1e\xbe\xf3\xf9\x04\x6c\xb7\xc8\x62\x26\x40\xfc\xaf\xaf\xbf\xb8\xf6\x2e\x1c\xd3\x2c\x66\xee\x1c\x55\x50\x94\x89\xa5\x38\xab\x61\x29\x99\xe7\x99\x7b\x77\x9c\x64\x22\xef\xf1\x09\xda\x4d\xf8\x29\x20\x93\x0d\x8d\x36\x3d\x78\x30\x90\x87\x95\xa3\x88\x8f\x25\xd6\x67\xe1\x4d\x15\x5e\xd4\x45\x81\xbe\x43\x0f\x79\x73\xb5\x74\xe2\xbc\x0b\x13\x4c\xf1\x39\xfb\x4b\xb0\x1d\xbd\xa4\x1b\x67\xb9\x81\x47\xd8\x01\x2f\x40\x67\x7f\x4b\x80\xce\x4a\x53\x4c\x90\xad\xea\xbf\x48\x4b\x21\xfa\x99\x4b\x7a\x17\x5f\x8a\x8b\x8a\x40\x75\x56\x44\x78\xdd\xb0\x50\x24\x58\x0b\xab\x03\x8c\xd9\xea\xa1\xdf\xda\x55\x2f\xb3\x12\x29\x42\x9b\x61\x4f\xa1\xd8\x0c\x52\x61\x4e\x84\xfa\xa2\x21\x7f\x26\x0f\xf7\xcc\xea\x8c\x7b\x06\xe3\xd7\x7f\xf8\x74\xeb\x81\xfc\x85\x97\xe5\xfc\xdc\xec\x95\x1b\x5f\xe6\x4a\x1a\xf8\x6e\x73\x19\x3a\x88\x24\x69\xeb\x3b\xa3\xc3\x82\x73\x4b\x28\x87\xb4\x19\x31\x6e\xa4\x48\xaf\xc2\x82\x47\x8c\x25\xf7\xbc\xa1\x84\x29\xcb\xbf\xfd\x88\x71\x17\x7c\x5e\xcc\x7d\x8a\xa9\xa1\xb9\xec\x87\x19\x2d\x29\xa5\x25\x39\xc0\x81\xc3\x59\x33\x32\x44\x4c\xbe\x66\x87\x2c\xf3\xd0\xe1\x97\x29\x2b\x82\xb0\xbe\x5f\xcd\x85\x8c\xd6\xca\x48\xb5\x3e\xe5\xb6\x16\x41\xbc\xaa\xf3\x1d\x81\x9c\x7e\x1c\xed\xaf\x9e\xe6\xb0\x7e\x09\xca\xed\xfb\x30\xb9\x20\x4a\x1d\x4d\xdb\x70\x56\x0c\xbe\x1e\xb0\xc0\xec\x43\xf1\xd1\x78\x20\x1b\x29\x08\x19\xfc\xdc\x92\xc6\x3e\x0d\xb6\x0f\xb8\x7d\xff\x00\xe5\x12\x64\x8c\x89\x58\xa8\x47\xef\xc3\x63\x46\x07\x3f\x1a\x4f\x1f\x23\x17\x06\x0f\x1c\x54\x3e\x6f\x01\xb4\x24\x85\xbe\xeb\x56\xca\xb3\xba\xb2\x6e\x6a\x0c\xa6\x93\x58\x02\xc7\x62\xb7\x99\x15\x9e\x32\x0f\x36\xb5\xe8\x3d\x4a\xca\x89\x62\xaa\x2c\x3c\x2b\x7a\x38\x70\xe9\xe0\x47\x31\xf3\x94\x8c\xf9\x41\xe2\x1d\x50\x96\x4e\x5d\x63\x5a\x35\xa5\x3e\x29\x98\x11\xb8\xca\xdf\xcb\x44\x16\xc5\x75\x98\xa3\xfd\x05\x41\x09\x10\xdb\xc0\xea\x2c\x78\xfd\xb9\x25\x74\x99\x7d\x58\x79\x62\x79\xea\xaa\x78\xb3\x6d\xce\xf1\xc9\xa1\x29\xee\xff\x82\x39\x9a\x26\xd0\x08\xff\xa3\xbf\x04\x18\xff\x7d\x39\xb6\x42\x7f\x34\x18\x95\x02\x4d\x16\xe2\x2a\x0c\x62\xa8\x2b\xeb\xa2\xe2\xba\xc2\x3d\xee\x18\xcf\xcd\x5d\xb2\x39\x7f\x37\x8c\x53\x67\x30\x90\x82\xc4\x4e\xb4\x3c\xed\xc1\x52\x20\x25\x3a\x62\x32\x03\x99\x66\x5f\x71\x34\x9c\xc1\xb9\x44\xf5\x8c\x73\xa1\x0a\x0b\xbf\xd4\xca\xf1\x28\x91\xe3"}, +{{0xbe,0x1c,0x11,0x2f,0x78,0xcf,0x13,0xae,0xfc,0x5c,0xe7,0xe3,0x37,0x64,0xac,0xa4,0x48,0x1f,0x9f,0x88,0xb0,0x18,0xe1,0x22,0xdb,0x9f,0x8d,0xac,0x14,0x62,0x46,0x05,},{0xae,0x38,0x99,0x36,0xbb,0xf6,0xd1,0x6e,0x3c,0x1e,0xeb,0x64,0x74,0x29,0x89,0x70,0x86,0x6e,0x12,0xec,0x9c,0x1d,0x6a,0xea,0x2f,0xd9,0xdb,0x6b,0x56,0xaa,0x59,0xc4,},{0xf5,0xfc,0x5a,0xcb,0x17,0xe9,0x95,0x7e,0xa3,0x04,0xf1,0x23,0xb6,0x50,0xe1,0x44,0xc9,0xe4,0x37,0x72,0x83,0x50,0x9d,0x43,0x1d,0xa6,0xa2,0xbb,0xd5,0x27,0xbe,0xb3,0x82,0xc9,0xf5,0x87,0x45,0xa3,0xe5,0x6d,0xcc,0x65,0x5b,0xd2,0xeb,0xb7,0xae,0xef,0xc9,0x3e,0xdc,0x3f,0x20,0xd8,0xd3,0xc3,0x79,0x23,0x03,0x1e,0xec,0x0c,0xb4,0x07,},"\xd7\x7f\x9a\xee\xa0\xfe\x98\xed\x7f\xb7\x4d\x58\x2a\x40\x2b\xcb\x79\x31\x47\x4b\x4a\x95\xd5\x23\xf3\xfb\x76\x9f\xb7\x09\x7d\x2b\xe4\xc6\xec\x10\x52\x14\x01\x63\x22\x25\x53\xaa\x8f\x4f\x89\xe4\x21\x73\x00\x14\xec\x73\x46\x97\x20\xce\xa9\x67\xf8\x8b\x6a\x48\xd0\x2a\x2d\xdc\x1a\x12\x1f\xdf\xfb\x8a\xe1\x27\x73\x8e\x29\x3c\x4d\x6b\x1b\x74\xad\x03\x84\x4d\xe6\xbf\xe8\x21\x50\x6b\x3a\x7a\x81\xd1\x9c\x37\xa7\xf0\x1c\xa4\x81\x47\x12\x19\xef\xe2\xa7\xb9\x2c\x4b\xd2\xac\x07\x74\x3b\x49\x75\x69\x64\x41\x71\x4b\x84\xd6\x3c\x54\x9d\x7a\x6f\xb6\x1f\x16\xfb\xcd\xb7\x2b\x91\x4d\x78\x82\xd0\x91\xf9\x70\x6d\xa3\x8c\x1a\x81\xa1\xc6\xa4\x0f\xbe\xc0\xd8\xe2\x38\xb5\xd5\x6d\x46\x0e\x90\x9f\x85\x47\x9f\x7a\xd8\xb1\x19\xf3\x54\x55\xe3\x40\x10\xca\xa7\xe5\xd0\x1f\x38\xe3\x01\xad\x37\xe8\x00\x5f\x6e\xd2\x9e\x4a\x10\x2d\xb3\xf6\x1d\x84\x09\x3f\x78\xc4\x9a\x96\x48\xc9\x77\xbf\x4d\x5b\x68\x9f\x71\xf4\x06\xf8\xad\x7b\x9a\xeb\x1a\xe2\x21\x33\xa8\x4c\xe1\xb2\x78\xb2\xcd\xde\x46\x59\x01\xb2\x3a\x17\x9d\x07\x2a\x80\x87\x9d\x0a\x24\xd2\xaf\x19\x7b\x32\x2a\x07\xbf\x5d\x40\xee\xab\x3a\xf1\x21\x17\xf1\x30\x21\xdf\xc1\x68\x1a\xba\x5c\x08\x3f\x25\x96\xe3\x7f\x11\x23\x42\x2b\xbd\xca\x3b\x2c\x32\xcb\x59\x4f\x56\xc3\x25\xe0\xc5\x64\xa1\x73\x32\x88\x05\x34\x59\xc6\x24\x88\x92\x5c\xd8\x0e\x7c\x94\x4d\xb9\x98\xc3\xc7\xbe\x54\x6b\xf8\x9d\x7a\x51\x1c\xcd\xba\x4b\x80\x9e\xee\x0f\xc2\x87\x3d\xad\x72\xb4\xcf\x3b\xa0\x51\x28\x9b\xb3\xf4\xe9\x92\x57\x32\xe4\x5a\xe7\x74\x10\x58\xc8\xfd\x11\x59\x9d\xd8\x43\x92\x7e\x3d\x14\x59\x8b\xb8\x30\x52\xd3\x35\x69\xcf\xb0\x2a\xf0\xc8\x8f\xa7\xae\xa4\xbb\x46\x84\x1c\xd2\xdd\xbd\xf5\x98\x8f\xcf\x32\x5f\xf1\x04\xa5\xdf\xc4\xa3\x0d\x26\x9d\x2a\x94\x97\x30\xc3\x61\x3b\xdd\xd3\x67\x3b\x42\xf6\x09\x0e\x6a\x60\xe4\xa2\x53\x06\x24\x63\xa6\x5d\x7e\x7f\xc0\x03\x0b\xba\x76\x9c\xa3\x44\xbf\xa9\xac\x82\x3f\x58\xcb\x5c\xee\x8a\x5f\xc0\xca\x37\x22\x8d\xe5\xa4\xd9\x3e\x0e\xcf\x7f\x10\x82\x16\x59\xa2\x26\x1f\x7e\xf1\x59\x6e\xda\x4e\x41\x1c\xf3\xc9\x66\x9d\x81\xde\x74\x54\x7c\xe4\xbf\x83\x3e\xb4\x32\xf3\x85\xce\x90\x38\xfe\x84\x8a\x8c\x96\xda\x7f\x01\xfd\x95\xbe\xa0\x6d\x1d\x74\x7c\x8a\xe7\x36\x49\x5b\xba\x22\x85\xbe\x5c\x32\xaf\xea\x44\x95\x20\xcf\xe8\xe1\xce\x25\xf9\x07\x7e\xd0\xec\x0f\x65\x98\xa9\xb8\xf7\x38\x6f\x15\x35\x81\x70\xcc\xef\xc3\xd5\xff\xb0\x09\x28\x81\x54\xde\x87\x7c\x24\x09\xae\x5f\xd8\xfe\xf0\x09\x3f\x1c\x36\xb3\xa8\xf5\x47\x43\x2c\xd0\xf6\x2c\x40\x33\x24\x2a\xd9\x92\x1a\x8f\x11\xc0\x0f\x36\x6d\xa9\x39\x69\x30\xa8\x0c\x99\x7d\xf4\x29\xa4\xf5\xf4\xe4\x5c\x7a\x6d\x7e\x02\xaf\x03\x31\x86\x75\x7c\x73\xcb\xe6\x4d\x2d\x4e\x78\xea\xaf\xe2\x75\x39\x52\x80\x35\xf2\xcf\xcf\x8e\xaf\x0a\x42\xbd\x25\xf8\x8b\x2f\xc6\x9e\x42\x66\x8f\xae\x66\x77\xc9\xac\x90\x91\xd9\xd1\x5a\x41\xf3\xac\xe6\x5d\x90\xa0\x22\x98\x73\xdc\xf2\x54\x25\x6c\xca\x44\x9e\xd4\xc1\x7d\x54\x35\xba\xe4"}, +{{0xbd,0x85,0x23,0xed,0xa8,0x99,0xb9,0x84,0x23,0x0e,0x32,0x88,0x75,0xb9,0x67,0x2e,0xdc,0x9f,0xcd,0x24,0xea,0x5c,0xc1,0x2d,0x7b,0x57,0x2d,0xa4,0xbe,0x01,0xfb,0x7b,},{0x02,0xb7,0x34,0xeb,0xbe,0x88,0xc1,0x3b,0xfa,0x95,0xa5,0xd9,0x64,0xfc,0x7e,0xf9,0xd3,0x95,0xbd,0x63,0x03,0xf0,0x65,0xdc,0x4e,0xe1,0x7b,0x3a,0xc1,0x54,0x8b,0x7b,},{0xfc,0xfc,0xdb,0x08,0x8d,0xcb,0xd0,0xa5,0x1b,0xd3,0x01,0xe3,0xe1,0x56,0x16,0x71,0x93,0x5d,0x8b,0x6f,0x71,0x9c,0x5d,0x92,0x69,0x06,0x40,0xd3,0xc9,0x1e,0x77,0x5b,0xf4,0x05,0x41,0x32,0xef,0xc0,0x5a,0x21,0x22,0xfc,0x20,0x9d,0xb3,0xc3,0x34,0x32,0x33,0xff,0x8a,0xec,0xeb,0xd5,0x2d,0xaa,0x2b,0x3b,0x21,0xee,0xb1,0x5f,0xd1,0x02,},"\x16\xc2\x16\xc9\xbe\x9f\x0d\x4b\x11\x54\x10\xbd\xfd\x15\x93\xc8\xe2\x62\x22\x1a\xb9\x7a\x2a\x39\x5a\x12\x19\x8f\x95\xc3\x02\x05\xb0\x89\x62\xd4\x89\x31\x18\xba\x9f\xf9\x9a\xb1\xc7\xa6\xe1\xf2\xf1\x75\x19\x10\x70\xac\x94\x53\x27\xad\x6c\x47\x0b\xab\xf7\x92\x8b\x07\xdd\x78\x8c\x85\xb6\x4b\x71\x2e\x0a\xae\x6c\x0e\xa2\x02\x81\xe4\x2f\xd5\x61\xe8\x3e\x3f\xba\xc6\x7f\x14\x00\x0e\xe5\x6d\x98\x1d\x2a\x2f\x0b\x9c\xa0\x0a\x9e\xa4\x7c\xa2\xf6\xfc\x8d\xca\x10\x35\xfc\xeb\x14\x2c\x3f\x26\xf2\x0e\x3c\x73\x22\x07\xff\xff\x11\xb7\x96\x95\xbd\xaf\xa4\x15\x21\x4a\x44\x99\x30\x23\x26\x60\x5c\xf0\xb8\xc8\x2f\x2b\x11\x39\x2e\xcc\x90\xcd\x74\xa7\xb4\x11\xb6\xd9\x07\xa3\xd5\xc1\x30\xc8\x79\xb7\xcf\x88\x0f\x22\xbb\xd7\xf0\xe9\x59\x33\x71\x8e\x96\xd7\xd1\x6c\xae\xa9\xf2\xc3\x9e\x89\xb1\x3c\xd5\x22\x66\x27\x36\x04\xa9\x6b\x51\xd6\xe3\x4f\x70\x67\x35\xdd\xd9\xfc\xa4\x4d\x09\xcd\x86\xbb\x72\x17\x60\x0e\x0d\x34\xd4\x16\xac\x24\x9f\x2e\x41\xbd\x0f\x4a\xbc\xbd\x25\x80\xad\xae\x21\xd7\xeb\xa5\xfa\x44\xf3\x9d\x78\x0f\x17\xeb\x85\xcc\xbe\xf5\x8f\xef\x90\x3a\x28\x0d\x95\xf8\xf3\x21\x07\x89\xfa\x12\xe1\x20\xe2\x1b\x6e\x8c\xad\x91\x78\x35\xbb\xdc\xc3\xb0\x7e\x84\x69\x39\x54\xe2\x3a\x94\xf9\x9f\x93\x7d\xdb\x0d\x4a\x18\xd4\x2c\x3e\xa8\xfc\xa7\xd1\xea\x6e\xd5\x3a\x00\x24\x6f\x99\xea\x52\x0e\x64\x05\xbd\x2a\xa5\x49\xb0\x6e\x7d\xa7\x22\xc1\xba\x74\xaa\x1c\x13\x6e\x8e\xa5\x8b\xaa\xf8\xd3\x76\x58\x69\x3f\x3e\x0b\x44\xf6\x31\xdd\x6d\x08\xff\xdf\x4f\x09\x18\x9d\x30\x35\xa3\xf0\x34\x68\xe2\x96\x96\xef\x05\xe0\x2c\xc1\xaa\xbf\xec\xbd\xa2\x30\x1b\x54\x0c\xb0\xeb\x0a\x75\xbc\xce\x73\xdb\x92\x73\xa9\x16\x1a\x98\xad\x89\x8f\xcd\x65\x79\xfb\x7e\x4b\x32\x79\x54\x4f\x2e\x0b\xd7\x74\xdd\x1a\x81\x57\xda\xa8\x8a\x70\x32\x11\x67\x70\x3c\x60\xa6\x08\xa4\xb5\x42\x16\x59\x03\x75\xe5\x97\xfe\x21\xae\xa9\x7b\x52\x18\x5d\x0e\x37\xa5\x3b\x63\x88\xa7\x07\xa2\xbc\x24\xac\xf9\x44\x25\xf8\x4f\x3d\x56\xbc\x9f\x7e\xe7\x41\x2a\x9e\x18\x33\xad\x55\xb7\xea\xe6\xda\x58\x16\x98\x16\x63\x83\xa2\xeb\xa8\xb6\xf5\x39\x20\xf5\x17\xa5\xc8\x0b\xd3\xe0\x3f\xaa\xd4\x08\x7e\x3e\xe8\xfe\xc9\xa7\x9a\x01\xc7\x79\x51\x21\x33\xd7\xb6\xe5\xf1\xde\xc7\x66\x30\x0d\xc4\x05\xcc\x21\xa8\xc5\x83\xfb\x73\xbc\x90\xcf\x24\x38\x5b\x08\x60\x49\xd3\xbf\x20\xc3\x00\x98\x3c\x0b\x35\x15\x38\xdc\xcb\x22\x7a\x14\xfa\xfd\x23\xac\x4b\x26\xbe\x81\xa2\xb1\x20\xcf\x21\x6f\xc5\x83\x54\xf9\xdc\xbf\x05\xf6\x63\x39\xad\x6d\xdc\x2c\xac\x14\x67\x7b\x90\xe2\x47\xeb\xb6\xc5\xc2\x29\x00\x7d\xc6\x0f\x37\x4a\x06\xd4\x04\xeb\x23\xeb\x1e\xc4\x99\x07\xc6\xe8\x81\x62\x9e\x18\x67\x26\x8c\xa6\xff\xfa\x59\xaa\x3c\xa8\xf6\xc2\x95\x16\x2b\x95\x36\xc2\xbe\x22\xbb\xe3\xb7\x23\x80\xef\x11\xb6\x1b\x35\x7a\x62\x53\x10\x0e\x30\xa5\x86\x81\x8b\xa0\x03\xfa\x3f\xfd\x1f\xc9\x19\x88\x1c\x05\x02\x2f\x94\x84\x85\x98\xf2\x17\xfe\xa2\x22\x50\x72\x20\xd1\x08\xa2\x8f\xc7\xbc\x39\xa8\xa1\x1c"}, +{{0x33,0xa8,0x5a,0xe1,0x50,0xbb,0xf5,0x52,0xf4,0x16,0x63,0xb2,0x15,0x21,0xc2,0x96,0xd2,0x46,0xdd,0x6c,0xf8,0x19,0x5d,0xf8,0x51,0xc6,0x95,0xbd,0x15,0xf4,0xa5,0x02,},{0xc8,0xc9,0xc4,0x25,0x21,0x00,0x8d,0x5e,0xff,0xf5,0x76,0xc7,0xe4,0xa5,0x60,0x83,0xce,0xd9,0xa9,0x28,0xda,0x6f,0xd5,0xcf,0x93,0xfd,0xa5,0x72,0xa5,0xa2,0xd0,0xc0,},{0xbb,0xe4,0xcd,0x63,0x67,0x6e,0x26,0xd6,0x75,0xa1,0x91,0x15,0x1d,0x30,0xdb,0x72,0xb5,0xb8,0x4d,0x46,0x1e,0xec,0x65,0x64,0xaf,0x86,0x7a,0xb4,0x1b,0xae,0x99,0x31,0x14,0x78,0x85,0x51,0x9e,0xc9,0xd7,0xe6,0xc8,0x18,0x74,0x3c,0x8e,0xf6,0xd5,0x16,0x7b,0x35,0xb4,0x21,0x36,0x3c,0x09,0xb3,0x57,0x36,0x7f,0xe8,0xde,0x44,0x3a,0x06,},"\x93\x7e\x05\xf2\xf1\xfd\xbd\x41\x73\x15\x53\xe7\x7c\xf1\x81\xb5\x07\x97\x58\x94\x0a\xee\x8e\x92\x62\x3f\xb1\xd5\xf0\x71\x28\xb7\xd7\xf1\x7e\x48\x42\x70\x7a\x56\x2c\x45\xba\x69\x26\x4c\x0f\x73\x0a\x82\x1c\x7d\xb6\xbf\x82\x99\x0d\xc6\x51\x26\x9b\x29\x6c\x33\x51\x79\x11\x30\x53\xd6\xf8\x5b\xb0\x96\xb2\x91\x11\x65\xfa\x39\x00\xcb\x10\x24\x16\x48\x7b\xa8\x07\x86\x79\xc6\xb3\x36\xdf\xf3\x87\x63\xc0\x8d\xcd\x20\xfa\x66\xdd\xa4\x5c\x57\x5d\xf1\x50\xd8\x51\x16\x5a\x48\x04\x97\x38\x30\xf4\x36\xdf\x60\xb8\x13\x19\xf9\xcf\xb5\x64\xc0\x65\x28\x96\xed\x5f\x18\x49\xcb\x33\x54\xf5\x0f\x00\x12\xf2\x86\xe8\xa3\x0c\x21\x35\x28\x69\x34\x74\x00\x4e\x85\x04\x01\x2b\x94\x55\x60\xc0\x74\xa6\xa1\x63\x43\x2c\xf4\xac\x4b\xa7\x17\x5c\xf2\x60\x05\xdb\x71\x99\xee\x96\xd8\x93\xcd\x1a\xad\x3f\xdf\x5d\x57\x46\x0e\xf0\x2d\xda\x6d\x3a\x14\x08\x25\x19\x6f\x3f\x8e\x2f\x37\xda\x36\xb6\xfd\xad\x18\x4f\x27\x40\xf1\x16\xde\x75\x8a\x92\x91\x70\x30\xc5\xfb\x80\xf0\x26\x24\x96\xd2\xdf\x93\xc7\xe2\x76\xf2\x5d\xa7\xdb\xed\x8e\xb8\xdd\x4c\x56\x3a\xba\x55\xb8\x2a\xf6\xba\x3a\x70\xca\x5f\x85\x8b\x44\xa0\x33\xcf\xb7\x95\x60\x4d\xde\xe7\x46\xe7\xc8\xae\x79\xd2\x72\xfb\x9a\x23\x41\xa2\xa2\x02\xdf\x5e\xac\x08\xde\x75\xad\x80\xc6\x58\x0d\x92\xb1\x69\xf2\xe1\x31\x88\x57\xb1\xb1\x42\x1c\x30\xf3\xdd\x46\x10\x93\xde\x2d\x34\x5e\xde\x74\x04\xb7\x2a\x45\x0d\xe0\x7b\x16\xee\xe6\x8c\xe6\x28\x87\xb6\xea\xa4\x36\xee\xe6\x84\xbe\x75\xce\x0e\x1f\x96\x26\x3e\x8d\x87\x36\xf9\xba\x00\x0d\x88\xe9\xe5\x86\x0f\x32\x8a\xe1\xe2\xdc\x73\x09\x9d\x32\xfc\xeb\x1b\xd2\xc0\x12\x36\x98\xa4\x9b\xea\xd1\x90\xa0\x0e\xc9\xa6\xf8\x71\x33\xed\xdd\x45\x31\x6f\x65\xeb\x0d\x32\x9b\x07\xb9\xa6\x6b\xb9\xfe\x42\x58\x8b\xf7\xb8\xd0\x6e\xfe\xc1\x98\x6b\x82\xa0\x81\xed\x3f\x68\x02\xe9\xbe\x73\x46\x47\x84\x55\x9a\x4f\x2c\x09\x7b\xa1\x4b\x0b\xfd\x5d\x7e\x0a\xff\x65\xcb\x69\xab\xd0\x3f\x86\x16\xcd\x7e\xdf\x7e\xc3\x68\x21\x9e\xdc\xf8\x93\xe9\xee\x71\xda\xd9\xf1\x8d\x79\xe5\x68\x26\x5d\xdc\x67\x16\x22\x32\x13\x23\x5b\xb9\x28\xe9\x08\xde\xa8\x27\x78\x4c\xd1\xaf\x39\x6d\x59\x0c\x81\xf4\xea\xcd\xfc\xf8\x9c\x5c\xac\x96\xfa\x05\x00\x64\xa2\x28\x41\xea\x71\x5f\x8c\x89\xd6\xd5\xaf\xbf\x59\x7a\x4d\x00\x5d\xbc\x6b\x13\x85\x6d\x33\x5b\x42\xa9\xa8\x2e\xdc\xb9\x49\x83\x5c\xca\x20\xb0\xa2\x3d\xe5\x1c\xc3\xae\xc3\x55\x66\xef\xf0\xc5\xae\x1a\xb3\x75\x13\x20\xd2\xc3\x10\x49\x52\x38\xed\xa3\x83\xc3\x8a\x41\x63\x15\x2b\x88\x15\x69\x0b\x8f\xf0\x15\x03\x5d\x1d\x00\xea\x4a\x0d\x6c\xaf\x32\x4b\xb7\x1a\x66\x4a\x1b\xed\x31\x48\x07\x84\xa6\x8f\x43\x8c\xaa\x35\x9e\x8d\x26\x73\xc8\x57\xd4\xb8\xc0\xb6\xc6\x95\x84\x7b\x86\x80\x0e\xa3\xd7\x34\xb5\xec\xc4\xd5\x2b\x50\x7a\xc6\x9b\x3a\x67\x78\x91\x60\x16\xeb\xc2\x31\x5f\x44\xc9\x0b\xf0\xc3\xe7\xda\xe0\x1d\x49\xcb\xc3\x03\x40\x2b\xbc\x63\x4a\xe1\x19\x1f\x3f\x6f\xd6\x3d\x30\x3b\x0c\x0b\xe0\x33\xa4\x7b\x90\xf8\xd3\xa7\x7f\x0a\x44"}, +{{0xba,0x9e,0x68,0x62,0x04,0x97,0x5c,0x3b,0xde,0xd4,0xc1,0xe9,0xf7,0x4c,0x7e,0x4c,0x7a,0x7e,0x3c,0x99,0x81,0xd0,0x1b,0xfc,0xa0,0xad,0x01,0x15,0xc3,0xf0,0xf5,0xc3,},{0x49,0x90,0xfc,0xe6,0x95,0x2e,0x8b,0x7d,0x0a,0xfc,0xf4,0xbf,0x9d,0xba,0x9b,0xce,0x1b,0xc4,0x81,0x5e,0x37,0x51,0x1d,0xa7,0xc2,0xad,0x48,0x92,0x58,0x1d,0xe0,0x3a,},{0xc7,0xd2,0x3a,0x58,0xe2,0xfb,0x2a,0x8d,0x4b,0x8e,0xd1,0xe9,0xea,0xe9,0x1e,0x11,0x29,0xc2,0xaf,0x8b,0xd0,0x5f,0x0b,0xd5,0x72,0xab,0xeb,0xbe,0x0f,0x30,0x82,0x59,0x25,0xf0,0xdf,0x71,0xcf,0xb7,0x21,0x8c,0x68,0x6e,0x55,0x48,0xd9,0x42,0x77,0x10,0xa6,0x90,0x36,0x6b,0xa8,0x55,0x41,0xc7,0x91,0x01,0xa5,0x8a,0x10,0xe8,0xaf,0x0a,},"\x46\xbb\x48\x95\x2a\xe5\x8f\x2b\xf5\x8f\x5b\xe8\xdf\x4f\x31\x6b\x50\xf3\x63\xec\x84\xee\xd8\xf8\x2f\xf4\xc0\x4b\x06\x92\xd0\x3a\xef\x26\xe8\xe1\xe6\xc9\x54\x9a\x22\x47\xd5\x40\xa6\xe2\x2f\xeb\x11\xe5\x7f\x4b\x80\x8a\x20\x97\xe8\xa7\xb6\xb3\xb7\xaf\x37\x69\xe6\xd8\x1d\x64\x88\x6e\x69\x62\x37\x2f\x4f\x39\xe4\x9c\xd4\x6c\x1b\x5f\x73\x5f\x38\x0f\x7c\x27\x7d\x09\x97\x76\xed\x1a\xea\xa5\x7a\x35\x9c\x0a\xa8\xc7\x2f\x40\xeb\x91\xa1\xbf\x07\xea\x15\x7f\x5d\xdb\x30\x40\x9d\x6e\x3a\xf9\x89\x90\xce\x7f\x30\xaf\xfd\xac\x5e\x22\x01\x06\x46\xdc\xa9\x6a\x54\x00\x60\xfc\x90\x8a\x31\x25\xb0\x00\xad\x1e\xd3\xa0\xf2\x55\xcd\x34\xf1\x5d\x7d\xd1\xfd\x68\x1c\x3c\x35\xa1\xcd\x65\x20\x56\xec\xc5\x26\x4d\x39\xaa\xf7\x2a\x9b\xb8\x3a\x55\x1c\xc9\x34\x88\x7a\xe1\x07\xaf\xdf\xef\x06\x32\x17\x27\x0d\x95\x96\x89\x14\x18\xbd\x46\x1b\xba\x63\xde\x65\xbe\x06\x7b\x1b\x78\x64\xfe\x46\x48\x4c\x7c\x9e\x96\x34\x9a\x7c\x03\xa8\x0f\xa0\x55\x05\x0a\xa1\x8a\xce\x2a\x44\xb4\xa0\x3c\x94\x78\x24\x17\x2b\x30\xe2\x10\x11\x15\x94\x43\xca\x3c\xef\xaf\x69\x6a\x7a\xa8\xf9\x80\x11\x26\x0c\x94\x36\xbf\x48\x99\x1f\x41\xd4\xd5\x07\xb9\x6c\xe7\x32\x3e\x53\x1a\xdc\xf6\x63\x47\xc5\x5c\x88\x55\x67\x3a\x9f\x2e\xc8\x9b\x5c\x80\x24\x46\x06\x17\xec\x72\x71\x77\x3b\x36\xd6\x4f\xc1\x4e\xb5\xd8\x26\x52\xc5\x3a\x30\x31\x45\x72\x27\x09\x3d\x11\x8f\xd8\xeb\x93\x84\xe8\x02\x29\x04\x1a\x96\xa6\x49\x34\x50\xf9\x7e\x67\x36\x26\x3a\xbf\x1e\xcd\x9e\x9f\xb9\xa4\xf0\xf6\xd6\x67\xfa\x82\x41\x51\x48\x5e\xdc\x37\xb3\x4a\xcf\x3d\x8c\x35\xf9\xc1\xbe\x48\xb5\xe9\x6a\x12\xaf\x8e\x2d\x35\xc2\x3a\x03\x58\x0f\x21\x1d\xa6\x31\x6b\x34\xc5\x6b\xee\x87\x2d\x47\x64\x1b\xca\x77\xda\x64\x0f\xdb\xba\xd5\xa9\xad\x8a\xb9\xdc\x79\x57\x91\x3d\xa7\x34\xad\x37\x49\x2b\xa4\xde\x8c\xf1\x36\xcc\xcd\xeb\x6b\xa3\xf1\xbd\x3f\x00\x3b\xe7\x26\x3c\x4f\x2a\x40\xc3\x3f\x24\xca\x33\x39\x59\x6e\x6c\x34\x28\x33\x81\x00\xeb\xcc\x07\x22\xd4\xf5\x0d\x30\xb3\x3b\x91\x2d\x4e\x7c\x1a\x9f\xe6\x5f\x66\x58\xa6\xf2\x39\x14\x0a\x62\xc3\x26\x1e\x10\x39\x2e\xd1\x93\x0a\xa9\x17\x65\x2d\x3b\xd2\xbe\x4e\x8a\x08\xab\x97\xe1\x45\xb9\x20\xab\xb3\x1e\xe4\xbc\xd5\xa0\xd7\x1f\x63\x81\x80\xf6\x1c\x24\x58\x23\xa3\x99\xa7\x34\xa4\xdc\xde\x09\x97\x88\x02\x45\xed\x71\xeb\x9b\xc6\x5e\x3c\x6f\xc9\x5a\xb9\x20\xb8\x02\x4c\x17\xd4\x4c\xed\x00\x37\xd0\x4a\x13\x3c\x26\x41\x78\x2f\x1d\x62\x2d\xf4\x52\x69\xb4\x91\xd3\xfa\x2a\x12\x27\x57\x9e\xaa\x38\x6d\xe3\xe7\xde\x7b\xc4\x55\xc6\xa1\x54\xee\xe5\x72\x7f\xff\x04\x37\xa2\x00\x76\xc5\xc3\xb0\x57\x7c\xac\x5b\x4b\x69\x34\xe2\x69\x38\x02\x22\x46\x1a\x60\xf9\x54\xe4\x89\x79\xc0\x67\x12\x17\xf1\x6f\x70\x27\x98\x30\x34\x12\x10\x93\x18\x6c\x78\x70\x5f\xc2\x7d\xc9\x2e\x2e\xda\x41\x16\xa6\xbf\x7d\x23\xe0\x54\x8d\x62\xb6\x7b\x25\xc4\x1e\xd0\x61\x92\xbc\x26\xef\x13\x97\xbf\x16\x01\xf3\xa6\xe2\xa0\xe7\xf6\x61\xfb\x05\x05\xee\x38\x2f\x27\xae\xc2\x80\x5a\x3e\x21\x17"}, +{{0x59,0x07,0xa8,0xc0,0x84,0x04,0x38,0x75,0x23,0x8e,0xdb,0xdc,0xb7,0x83,0x2f,0xbb,0xa4,0xc0,0x5e,0xa3,0xc5,0xf8,0x8a,0x96,0xf1,0xfb,0xf9,0x50,0x40,0x1e,0xc1,0x64,},{0xe2,0xf4,0x95,0x09,0xd1,0x00,0x7f,0x61,0x8e,0xfe,0x4f,0x1f,0xd6,0x7e,0xaa,0x6e,0x2a,0xb1,0x8a,0xfb,0x2d,0xec,0xce,0xd5,0xa0,0xb2,0xba,0x83,0x63,0x78,0x92,0x60,},{0x8c,0x49,0x12,0xc0,0xf8,0x85,0xd7,0x6c,0x91,0x40,0x59,0x50,0x53,0x73,0xa6,0x4b,0xdd,0xd6,0x7d,0xd4,0x68,0x36,0x9a,0xb9,0x18,0xf2,0x3e,0xa2,0x8e,0x04,0xc1,0x91,0x77,0xa8,0xd4,0x61,0x14,0x4f,0x0a,0x8b,0x51,0xd2,0x15,0x17,0x6c,0xb0,0x8b,0xd6,0x53,0x01,0xc3,0xc4,0x62,0x37,0xb6,0x1b,0xb1,0x49,0x8c,0xa7,0x9d,0x4b,0xe7,0x0e,},"\x43\x3b\x24\x78\xe1\x8f\xad\x5c\xb8\x10\x67\x06\x1d\x22\x55\x28\x22\x97\x78\x30\x78\x85\x47\x54\x60\xfb\xe3\x13\x7a\x5b\x44\x02\x48\x94\xdd\xbe\x56\xfa\x6e\xd0\x21\x49\x6f\x07\x86\xe4\x2b\xc6\xc2\xd2\x79\x7e\xa0\xa6\xbf\x35\x5e\x88\x11\x5f\xaa\x55\xcd\x92\xed\x42\x13\x3d\x9d\xcd\xa6\xb9\xeb\xf6\x3c\xe4\xa9\x94\xd1\xa8\x2d\x2a\x49\x26\x75\x58\xbe\x54\x18\x2a\x6f\x85\x11\x2b\xd1\x2b\x24\x7a\xda\xcf\x14\x05\xfc\x7e\xc7\xa0\x15\xd4\x3a\xb4\x0b\x82\xc6\x77\xf7\xf8\x5a\x0e\x48\x19\x7c\x5b\x96\x57\x61\x99\xf4\xc3\x34\x3f\xf7\x65\x4d\x52\x3a\x30\xc4\x3a\x05\x4c\x3e\x46\x44\x51\x27\x80\x34\xb7\xf1\x96\xc3\x66\x76\x8c\x62\x8a\xf9\x4f\xc0\xcc\xfc\x9a\x29\x55\xf9\xd3\x23\x38\xb9\x44\x78\x0f\x8e\x32\x70\x85\xb1\x03\x78\x18\x68\xe4\xfb\x79\xd5\x61\x22\xd7\xf3\xf5\xab\x30\x9e\x5d\x63\x4a\xdd\x15\xda\x38\x2c\x0d\x23\x58\xe6\x47\x18\x2b\xe4\xde\x6e\x9a\x9e\x43\xe6\xa3\xa3\xb8\x21\x5b\x20\x4d\x95\x07\x61\x0d\x46\x16\x21\x00\x0f\xb1\x89\x37\x07\xaf\x7d\x25\x95\xbf\xef\x8a\x8c\x5c\x5c\xd0\x8f\x30\x9a\x5f\xb5\x5e\x45\x51\x9a\xea\x9b\x84\x74\x8c\xa5\xc6\x72\xbf\xec\xd3\x0d\x25\x65\x12\x34\xa3\xcc\x31\x9b\x43\xdf\xce\xfc\x1a\x07\xb5\x5b\x4a\xca\x71\x4c\x2e\x7e\xf9\x63\x8f\xe7\x88\x4a\x77\xb2\x22\x53\xa0\x1a\x22\x29\x50\x0e\x9c\xe1\x0f\xda\x73\xa8\x43\xc1\x9c\xc0\x96\x26\xd2\x45\x6c\x22\xa9\xc9\x01\x88\x1d\x52\x1f\x4b\x15\xd2\xf6\x13\xcb\x46\x9d\x30\x4d\x57\x92\x23\xbc\x5f\xf7\x38\x04\xdf\x63\x71\x51\x7e\xba\xa5\xb6\x77\xea\x91\x0f\xf1\xa0\x2a\x26\xfa\xfe\x48\xfe\xf4\x69\xed\x79\x9b\xed\x6d\x56\xce\x96\x18\x34\xa2\xed\xc2\xe2\x3c\x0d\x94\x26\xec\xcd\xcc\x93\x4f\x4c\x22\x0e\x37\x81\x5f\x7c\x33\x4b\x73\x83\x60\x7d\x43\x05\x20\x94\x6a\x88\x1a\x08\x32\x5b\x41\x64\x97\x9d\x5e\x82\xcd\x81\x34\xd7\x8c\xec\x48\x61\xc0\x19\xf6\xde\x30\x1c\x1b\x9a\xec\x52\xbb\x98\x20\x33\xfb\x79\xb2\xe9\x73\x1b\xab\x29\x68\xbc\x3f\x93\xfa\x56\x04\xb8\x93\xc6\x02\x8c\x20\x4c\x36\xbb\x8c\x6b\x07\x4b\xe2\x8c\x96\x4d\x28\x49\xb5\xbb\x19\xd7\xe0\xba\x24\xe2\x2a\x20\x4d\x4f\xda\x83\xb1\x01\x31\xd3\x83\xf1\x0b\x13\x6b\xd0\xdb\xa3\x9e\xc2\x6a\xf3\x0e\x3f\xfb\x4d\xbc\x0c\x92\x1f\x0c\xc9\x91\x07\x15\xd5\x1c\x81\xfe\x4c\x62\x95\x0e\x85\x55\x49\xa1\x7c\xd7\x3a\x09\xac\x91\xe0\x6d\x46\x15\x18\x37\x6d\x0f\xcf\xa1\x23\xdf\x0a\x83\x71\x03\x45\x8d\x9c\xe2\x21\x80\x8d\x1f\x9e\xf2\xed\xc5\xcd\x2e\x68\x23\x14\x5b\x52\x48\x94\xea\x48\x52\x6d\x98\x5e\xef\xd3\xf6\x06\x79\x39\x95\x48\xe1\xed\xea\xdb\x53\x95\xb4\x3d\x87\x04\x4b\x2b\xfe\x7c\x60\x37\x02\x9b\x34\x6a\x40\x22\x27\xea\xb8\x1f\x33\x3e\x10\xe7\x7f\x1d\xbc\x06\xa2\x11\xd4\x3b\x82\x55\x86\x76\xc2\xdc\xff\x90\x82\xb1\xdd\x53\x36\x8d\xf0\x02\xde\x13\x29\xaf\x30\x00\xb1\x71\xa6\x91\x43\x89\xbb\x80\xec\x0c\x9f\x3e\x41\x2a\x44\x1b\x80\x0a\xfc\xeb\x04\x86\x70\x9a\xda\xc6\x6c\xaf\xee\xf2\x48\x83\x93\x31\xf5\xd8\x92\x19\x7e\x25\x42\x0f\x1e\x37\xd7\xc0\x24\x7f\x66\x9f\x5f\xcb\xf0"}, +{{0x60,0x20,0xae,0x27,0x3e,0x0e,0x05,0x37,0xba,0xc8,0x81,0xd7,0x54,0x9d,0x92,0x3e,0xb1,0xcc,0x20,0x0d,0x49,0xca,0x65,0xd4,0xbe,0x63,0x5e,0x39,0x17,0x3d,0xf9,0xda,},{0xda,0xaf,0x0e,0x69,0x9a,0x12,0xa9,0x2c,0x16,0xe0,0xde,0xd3,0xeb,0x34,0x50,0xa3,0x63,0x11,0x82,0x45,0x77,0xe3,0x61,0xf0,0x56,0x96,0x60,0x33,0x00,0x16,0x62,0x97,},{0xb1,0xba,0x88,0xfe,0xd7,0xe5,0xf4,0xb7,0x57,0xf3,0xfa,0x4d,0x1e,0xd9,0xb1,0x9e,0x49,0x8e,0x5d,0x2f,0x5e,0x6c,0xd4,0x6e,0x42,0x6f,0xe8,0xf0,0x39,0x88,0x2f,0x1b,0xe7,0x7a,0xc9,0xe5,0xa9,0x26,0x5c,0xbf,0x7e,0x3c,0xd2,0xa9,0xe9,0x92,0x6c,0x18,0x19,0x91,0x43,0x79,0x8d,0xa5,0xbe,0x47,0xa4,0x08,0x64,0x40,0x49,0x6b,0xa0,0x0f,},"\x6a\x80\x11\xde\x09\xaa\xc0\x0d\xb1\x6f\xf7\xe5\x5c\x2d\xe6\x7d\x8c\x98\x83\xfc\xb2\x04\x0d\xed\xbc\x1e\x32\x1c\xab\xa7\xbb\x03\x69\x71\x53\x01\x76\xd1\xdb\xba\xa9\x27\x52\x0b\xdf\xcc\xbe\xd8\x84\x01\x26\x04\x3e\xdc\x44\xcb\xb7\xfa\x35\x28\x68\x0e\x5f\x1b\x56\x64\x95\x1d\xc9\x01\x09\xae\xa4\xb9\xc3\x36\xca\x04\x3d\x82\x21\xa4\xc8\xd2\x01\x16\x56\xbf\x94\x4e\xfd\x36\xba\x0a\x10\xa4\xb3\x89\x19\x60\x55\x75\x0b\x0e\x38\x8f\xb5\x28\x70\xbb\xec\x8c\x55\x19\x81\x31\x44\x39\x45\xc0\x9f\x3a\xac\xe3\xe6\x91\x50\x14\x37\x40\x73\x26\x6f\x34\x88\x74\x42\xd7\x4f\x46\x8f\x8d\x70\x78\xbb\xa0\xbd\x81\x4c\xd6\xdd\x42\x3c\x97\xb5\x69\x05\x58\x7b\x15\x2d\x1f\xcf\xba\x0e\xb9\xfd\xe2\x11\x26\x91\xda\xfa\xf4\xf9\x21\x56\x2f\x24\x1b\x62\x84\x10\x01\x83\x4f\x6c\xe3\x66\x85\xf8\x2a\x8f\xaa\x3b\x7a\xfa\xd7\x3a\x5e\x59\xbf\x5f\x9e\x71\x3e\x59\x16\x3f\x31\xdb\xe6\x96\x11\x8a\xf3\x35\x06\xd2\xff\xea\x3d\x9c\x15\x56\xfb\x15\x2f\xd2\xb3\x21\xc3\x17\x57\xd0\xc3\xc0\xf6\x0e\xe1\x13\xed\xac\x02\xd6\x7e\xfb\xb3\x03\xdc\xe6\xfa\x88\xf7\xb9\x74\x6c\xa1\x10\xe6\xa0\xcd\x09\x9c\x08\x31\xf5\x3c\x55\xc2\x8b\x6c\x82\xaf\x44\x64\x56\xb8\x42\xb2\xc9\x50\xa5\x53\xee\x2c\x76\x5e\x97\x29\xe6\xb0\xc5\x46\xbf\xc2\x6b\xd6\xd4\x2d\x06\xb2\xed\x5d\x4c\x8c\xbb\xc7\x5f\x2a\x3a\xd8\x12\x93\x95\x79\x3d\x97\x9c\x03\x1f\xce\x7e\x20\xb3\x8b\xd8\x9c\x9b\x62\x47\x48\xb2\x01\x34\x23\xce\xba\xda\x02\xcd\xe2\x05\x2d\xa5\x66\x4c\x6c\x64\x26\xcb\xfc\x88\xf8\x4f\xf6\x02\xe2\xe2\x0d\xf9\x67\x8f\xbb\xa5\x77\xa4\xc1\x34\x51\x7e\xe0\x50\x68\x11\x51\x58\x0f\x7c\x5c\x97\x87\xb9\x6e\x55\xc4\x07\x5a\x26\xf4\xf8\xcc\xff\xbb\xb6\xea\x18\xde\x1b\x2c\xc8\xc4\x49\x6b\x16\x04\x27\x70\xb7\xec\x6e\xb5\x42\x9e\x7a\xc1\x89\x12\x32\xaa\x4e\x47\x46\x7f\x4e\x9a\x98\x5d\x80\x54\x7e\xcc\x4c\x6f\xd9\xf5\x97\x63\xed\xe9\x16\x71\xf2\xaa\x57\x36\xa5\xd1\x48\xe3\xa8\xff\xc8\x8e\x61\x25\x3a\x85\xb0\x95\x36\x54\x95\x8e\xb2\xd6\x94\x01\xcb\xea\xe7\x75\xf8\xcb\x8c\x3c\xa4\x2d\x21\x69\x3e\xbe\x29\x88\x38\xdf\x94\xc1\xd7\x7b\x12\x6a\x12\x05\xcc\x47\xd5\x0d\x53\x67\xb6\xf2\x76\xec\x8d\xb6\xb9\x53\x24\xa3\x1e\x8f\xd2\xed\x2e\x43\x42\x0c\x4a\xd0\x2e\xa2\x77\xdd\x94\x8a\x55\x19\x3d\x0f\x0b\x4d\x1c\xf2\x83\x86\xc7\x25\x97\x5c\xe5\xc1\x2d\x2a\x6f\x35\x67\x3c\xc2\x2a\x06\x94\xcc\xa4\xda\xf6\xaf\xbf\xd3\x26\xd8\x8c\x18\x50\xf8\x34\xc4\x2f\xf0\xe2\x92\xba\x4f\x13\xe5\xef\x07\x74\xa5\x96\xd3\x39\x04\xc0\x26\x2d\x31\xdf\x2c\x58\x4a\x0a\x4f\x45\x3f\x6a\xe4\xa8\x8a\x27\x5f\x7d\xe7\x9c\x13\xae\x1a\x73\x11\x5b\xe0\x2f\x42\x5c\x6f\x17\x7a\x1e\xc4\x63\x9c\x42\xa7\x92\x80\x9a\x2b\x09\x19\xeb\xd3\x21\xe3\x16\x00\x1d\x5b\x2f\x84\x89\x4f\xce\xbd\x50\xa1\xdc\xf4\x4d\x70\x2b\x92\x45\x32\xfc\x0e\x4d\x3f\x9f\xf8\x48\x6c\x0e\xd1\x80\xee\xcc\x3e\x09\xe2\x27\x2a\x94\xdc\x7d\x24\xa4\xe8\x7a\x93\x1f\xe2\x49\x5c\xbf\x99\x2c\x0a\xae\x92\x01\xe0\x79\x62\x98\xf9\x36\x3d\xba\xc4\x75\xe8\xed"}, +{{0x93,0x2a,0x20,0x0e,0xce,0xe7,0x22,0x3f,0x24,0x14,0x62,0x83,0xa4,0x04,0x8c,0x67,0xa6,0xa2,0xd2,0xfc,0x4b,0xa0,0xf9,0x24,0x8b,0xdf,0xfd,0x82,0xc6,0xcc,0xe3,0xcb,},{0xec,0x9b,0xfb,0x7a,0x6d,0x04,0xe7,0x26,0xfc,0x1e,0xa0,0xc4,0x24,0x61,0x0d,0xcb,0x79,0x67,0xbf,0x15,0xd6,0xd6,0x62,0x68,0x58,0xd4,0x11,0x19,0x8d,0x40,0xe2,0x39,},{0xcd,0x1e,0x4b,0xdf,0x4a,0x3e,0x4a,0x31,0xd6,0x52,0x54,0x33,0x3c,0x8c,0xc4,0x08,0x7e,0x4c,0xc4,0x0b,0x02,0xe2,0xa3,0x47,0xd0,0x9a,0x3d,0xde,0x69,0x84,0x90,0xc0,0x87,0xd7,0x10,0x9a,0xd0,0x20,0x9c,0x53,0xe9,0x87,0x58,0x9c,0xbf,0x3c,0xe2,0x64,0x12,0xa2,0xb0,0x2c,0xb8,0xa3,0xbc,0x93,0xfe,0xc7,0x5a,0xb5,0xd2,0xc3,0x87,0x03,},"\xdf\x95\x32\x07\x04\x82\x13\xaf\xb8\xe2\xaf\x45\x2c\x88\x9a\x21\xca\x13\x6a\x68\xc9\x29\xbd\xc8\x24\xf9\xa8\x9a\xc5\x96\xdc\xb9\x00\x19\xa4\x6f\xb6\x82\xbc\xfd\x96\x2f\xcc\xb2\x7d\x00\xba\xf8\xec\xca\xf9\xd9\xa7\xd8\x18\x3c\xab\xd7\xdf\xa5\x06\xf7\xba\xfb\x49\x35\xab\x04\x59\x31\xff\x8f\xae\xb7\x16\x31\xf9\xed\x6b\xb8\xf8\x47\x3a\xd6\x29\x0d\x7c\xf5\x19\xdb\x31\x0a\x44\x42\xc4\x61\x11\x8f\x67\xd1\xa6\xd1\x03\xba\xe6\xf2\x69\x7c\x94\xb7\x42\x6d\x9e\x02\xe3\xcb\x95\x22\xfd\x0b\x44\xae\xf6\x00\xc9\x62\xfe\xff\x58\x73\xd9\x8c\x27\x90\x88\x7b\x8e\x88\xd1\x60\x82\x4f\x1b\xba\x22\x01\x76\x39\xf8\xdc\xe6\x8f\x74\x34\x80\xde\xea\x1f\x92\xaa\x1f\xd4\x13\x5d\xd0\x64\x57\xa6\x0f\x36\xb7\xd7\xf5\x17\xd4\x0c\x94\xc0\xdd\xdc\x2e\x46\x58\x47\xd9\x09\xb9\xf6\x82\x45\xff\x2b\x42\x1d\x59\x19\x00\x1a\xae\x5a\xef\x24\xe0\x2c\x00\x2d\xa9\x07\xe8\x60\x5f\x16\x0e\xa6\x09\x6b\x58\x0b\x75\xce\xa0\x22\xd4\x02\xf7\xf5\xfd\xc4\x64\xf8\x7f\x78\xc7\x90\x6a\x01\xe8\xe4\x8f\xb5\xb3\x51\x74\x61\x2b\x48\xac\x8b\xc7\x50\xe0\xf3\xae\xb0\xa1\x2f\x7d\xfc\x09\xb0\x84\x2c\x17\x80\xa5\xfd\x9c\x54\xaf\xb9\x39\x9b\x94\x08\xba\xac\xcd\xa2\x0a\xfb\xe3\xd6\x82\x24\x8d\x7b\xf1\xef\xde\xf4\x90\x5a\x31\x9b\x0f\xfb\x10\x8b\x75\x3b\x71\xcc\x97\xe9\xe2\x1e\xc9\xb3\xdd\x28\xce\xe0\x39\xd9\x41\x8a\x11\x35\xf0\xad\xd0\x92\xaa\x66\x31\x2e\xa2\x91\x33\x00\xd1\xcc\x89\x16\x52\x43\x02\xbd\x3d\x1b\x09\xe6\xb2\x9c\x68\x57\xcb\xdc\x56\xef\x4b\x3f\x35\xd8\xee\x67\x72\x08\xef\xfa\x84\x6f\xdb\x06\x6b\x05\xeb\x71\x7b\x4d\x45\x12\x0c\xab\x72\xa7\xdb\x7a\x7c\xa8\x46\xe8\x7b\x16\xb6\x90\x47\xeb\x76\xd8\xf1\x8d\xa8\xe1\x39\x9e\xc0\xa8\xc9\xc3\x28\xcb\xe6\x0e\x0b\xf4\x20\x44\xd2\xeb\xf2\x81\x8b\x3c\x04\x75\x88\x45\x2f\xcd\x2b\x3e\xfc\x1e\x10\x09\xae\x07\x68\x87\x27\xdb\x8f\xb6\xdf\x2a\x2f\xe7\x5d\x1c\xf2\x2f\x32\xba\xc0\x9c\x82\xa6\xa3\xd7\xee\xd7\xd0\x05\x08\xcb\xe5\xb7\x24\x60\xec\xfc\xdd\x3e\xe9\x11\xef\xe5\x89\x8d\xbd\x8e\x4c\xe8\x59\x13\x26\xdd\x15\x22\xf9\xd2\x55\xda\x86\x1b\xf9\xeb\x2a\x1d\x57\x25\xd7\xd5\xd4\x27\x34\x03\x41\x94\x5e\x7b\xca\x8c\xf2\xff\x8a\x99\x74\x50\x95\x3e\x77\xd2\x03\x68\x3e\x4b\x0d\xaf\xc3\x30\xe0\x56\x72\xd2\xec\xd1\x3a\x3f\x44\x2d\xf1\x37\x04\x4e\x0f\x55\x6f\xfb\xce\xff\xea\x26\xcb\xae\x26\xcb\xa6\xf2\x56\x8c\xf3\x9f\x90\x84\x89\xe1\xa9\x2e\x76\xaf\xbf\x29\x79\x95\xda\x4b\x2c\xb1\xab\xc9\xee\x1f\xe4\xdc\xa5\xaa\x83\x8b\x2f\xbd\xc1\x09\xe8\x9b\xef\x3c\xe5\xa3\x6e\x5b\x2f\x71\x2a\xc4\xc8\x89\x43\x82\x48\xfa\x5a\x21\x50\xca\xc6\xc9\x77\xb5\xe0\x54\x3f\x40\x10\xb7\x31\x47\x32\xfd\x18\xe7\xfd\x59\x82\xe8\x32\x76\x51\x9e\x78\x72\x5e\x5a\x5e\xeb\x86\xf4\x89\x20\x84\xae\x52\xda\x38\x49\xc2\x28\xc8\x09\xed\xbf\x69\xa2\xcc\x47\xc4\x78\xd1\x87\x19\xf1\x11\xd7\x37\x88\x7c\x7a\x2e\xb3\x25\x08\x98\xdb\x34\xe5\xe5\x07\x6f\xab\x9f\x4a\x9e\x6e\x19\x29\xa3\x48\x08\x36\xde\xa0\x7b\xa4\xd6\x3f\xce\xfc\xe5\x54\x34\x30\xa8"}, +{{0x5c,0x48,0x3e,0x83,0x7e,0xb0,0x1e,0xd5,0xa4,0xad,0x5d,0xb3,0x79,0x26,0x99,0x82,0x4d,0xf1,0x3e,0x57,0x6b,0xe9,0x67,0xd1,0x21,0x15,0xc8,0x5e,0x02,0x86,0xe6,0x28,},{0xfe,0x1a,0xa8,0xb0,0x69,0xda,0x56,0xe6,0x76,0xef,0x3a,0x57,0xd9,0xbb,0xa8,0x83,0x05,0xea,0x03,0x28,0x08,0xee,0x63,0x52,0x73,0xb3,0x7c,0x5c,0x63,0x5d,0xef,0x4e,},{0xc1,0x7c,0x2f,0xbf,0x8c,0x00,0xbc,0xea,0x30,0x35,0xbf,0x0a,0x62,0xd3,0x02,0x29,0xdb,0x74,0x2c,0xab,0x11,0x99,0x67,0x7c,0x7e,0xb4,0xeb,0x0e,0xf5,0xc7,0xb5,0x1a,0xd4,0x87,0xa4,0x97,0x1b,0x63,0x1e,0x79,0x4a,0x58,0xbb,0x08,0x23,0xcc,0x0f,0xe6,0x26,0x10,0xfd,0xa6,0xa9,0xe0,0x3f,0x8c,0x4c,0x33,0x81,0xcb,0x15,0x4c,0xef,0x0b,},"\x58\xd5\xe2\xcd\x89\x9b\xa9\x85\x37\x8b\x3e\xc3\x3e\x9a\x86\x98\x22\xb2\x3d\x5d\x89\x6a\x28\xf4\x24\xfc\xd6\xe4\xcc\x28\xb8\x0d\x4a\xaf\x2d\xe8\x04\x36\x7e\xfd\xf5\xe4\x23\xb1\x23\x4d\x82\x1d\x63\xac\x05\xea\xed\x12\xc7\x3e\x8e\x36\x08\xaf\x0d\xdc\xcc\x83\x86\xb7\xd8\x42\xb1\x2e\x60\xd3\x0c\xed\xe3\x25\x53\x94\x5e\x78\x29\xe9\xb2\x3f\x5c\xcc\x2e\x71\x03\xa0\x8f\x2c\xdd\x9e\x75\xa7\xb3\x6f\x5e\x63\x72\x0e\xf0\xd4\x9b\x25\x92\xbe\xf3\x74\x02\x68\xc8\x9c\x86\xa6\xcb\xdf\xe2\x01\xde\x0d\xb9\x98\x5c\xeb\x19\x39\x9c\x9a\x1d\x5b\xb0\x58\x6a\xf3\xc8\xcd\xf2\x71\x32\x99\xeb\x04\x43\xa5\x41\xa4\x73\x84\x60\x72\x43\xc5\x4a\x05\x91\x50\x58\x36\x7d\x3f\x2d\xb3\x80\xed\x31\x7a\x8c\x12\xc7\xa6\x3e\x80\x9c\x2e\x84\xd4\xac\xb9\xd9\xee\xf5\x4c\x6f\x5a\xf7\xab\x59\xcb\x91\x68\xb1\x06\x8f\x9d\x2c\xcd\x97\x8f\xe7\x21\xba\xd6\x8a\x66\x9f\xfe\xde\xa3\xe9\x2c\x76\xb3\x2e\x31\x66\x65\x8e\xe3\xbd\x0d\xeb\x1b\x08\x41\x94\xce\x35\xd9\xa7\x41\xc5\x7f\xc2\x24\x1e\x68\xef\xaa\x65\x32\x0b\x23\xa1\xdd\x19\xea\x8b\x7e\xc8\x1e\x76\xf1\xe9\x16\x3f\x95\x92\xee\xee\x5a\xf8\xec\xed\x02\x72\xf3\x35\x12\xd0\xd4\xca\x06\x7f\x05\x55\x1b\x26\x53\x96\xe1\x00\x14\x78\x3c\xac\xac\x79\x43\x7b\x19\x84\x2d\xe6\xab\x91\xb9\xd9\x23\xbb\xeb\x50\x33\x25\xbc\x54\x86\x9f\x66\x3e\x6e\xa4\xae\x68\x97\x70\x1b\xe7\xe1\x1d\x16\xcd\xfa\xe0\xee\xe8\x61\x86\x20\x00\xe7\xa4\x16\x07\x81\x54\x7e\x42\x52\x6a\xf5\x1b\xa9\x69\x8d\x23\x4a\xaf\x51\x0d\xa8\x1a\x0d\xbf\x26\x43\x66\x15\x3d\x7a\x6d\x5e\xb3\xfb\x08\xb9\xbb\x5e\xa0\x65\xc2\xf5\xe5\xb6\xbb\x67\x9d\x2e\x21\x0b\x5b\x40\xe2\xbc\x82\xf7\x8d\xc9\xab\x58\x24\xb7\x4a\xad\xad\xd8\x9b\xf8\xa8\xb7\x3a\x0a\x2f\x43\xac\x74\x83\x78\x92\x1a\x73\xa2\x52\x70\x4a\x4a\xdb\xf7\x40\xcb\x99\xc1\xe1\x59\x4c\x37\xac\x9a\xcc\x19\xf5\x23\x15\xc6\xa8\x46\xa5\x7b\x36\x12\x8c\x64\xd7\x67\xaf\x44\xe9\xc8\x63\x05\xbf\x18\xba\x7c\xd5\x26\x80\x52\x3a\x3b\x10\x2f\xba\x6f\xe5\x55\x67\x06\x9d\x20\x47\xcb\xdd\x96\x05\xea\x12\xc8\x87\x7d\x39\x9c\x1e\x66\xe3\x38\x17\x73\x1f\x50\xb8\x4f\x81\x7d\x1f\x07\x60\xa4\x0f\x97\x46\x86\x18\x93\x41\x05\xeb\x00\xec\x50\xc7\x6d\xb3\xc5\x3f\xcf\x43\xfe\x17\x02\x90\x7d\x9a\x75\x6b\xcf\x43\x9f\x88\x31\xd0\xbf\xac\x92\xe7\x05\x8f\xb1\x57\xbe\x3e\x59\x1d\x37\xeb\x34\x16\x5e\x3c\x6f\xc6\x0e\x72\x29\x4c\x08\x3e\x47\x76\x26\xf9\x00\x1c\x1d\x73\x7c\x29\x03\x77\xdf\xa5\x8e\xa4\xea\xd3\x02\x8f\xc7\x62\xce\x8a\x3a\xfe\xc2\xe6\xe1\x32\xc6\x62\xdf\x60\x34\xab\x55\x4f\x93\xef\xac\x65\x7a\xd3\x4f\x61\x07\xd3\x47\xfc\x5c\x5e\x53\xf3\x73\x3e\x17\x8b\x76\x01\x4d\x2f\x9b\xbd\x06\xef\x2d\xfe\x60\xe2\x08\x3d\x88\x65\xf7\xf5\xb2\xac\xc0\x25\xd9\x12\xe5\xcf\x6c\xda\x6e\x79\x81\x43\xe9\xdb\xbc\x70\xa0\x21\x1d\x8e\x40\x03\xd7\x8b\x38\x3d\x66\xa6\xad\x29\x71\x7c\xa2\x4e\xdd\xef\x7d\xf7\xcd\x3a\x7e\xf6\x52\xab\xa5\x48\x7a\xfe\x5d\x02\x6c\x9b\x10\x28\x07\x29\x4e\xb2\x7d\x98\x24\xee\xb6\xb4\x0f\x08\x3d\xe7"}, +{{0xb0,0xd0,0xab,0xdd,0x84,0x44,0xe1,0x0f,0x29,0x37,0x54,0xac,0x9f,0x16,0xe3,0x1b,0xdc,0xdd,0x97,0xb7,0x06,0x71,0x28,0xaa,0xe8,0xe4,0xd7,0xf1,0x12,0x89,0xe2,0xcd,},{0x1c,0x78,0xcc,0x01,0xbe,0xa1,0x53,0x52,0xb6,0x3c,0x56,0x97,0xf1,0xcf,0xe1,0x2f,0xfd,0xd1,0x6d,0xdc,0x1d,0x59,0xe7,0x79,0x51,0xb6,0xe9,0x40,0x8e,0xe2,0x28,0xad,},{0x64,0x40,0x8b,0xdd,0x2d,0x0f,0xc8,0x92,0xa5,0xb6,0x2b,0x5a,0xcf,0x8e,0x3b,0x3c,0x73,0xc0,0xb5,0xc4,0xfa,0x2a,0x72,0xe3,0x9d,0xd6,0x08,0xd4,0x93,0x7f,0x93,0x32,0xf7,0x3e,0x14,0xd0,0x8b,0xad,0xc6,0x27,0x01,0x14,0xd1,0xf1,0xa5,0x56,0xcc,0x6e,0xe8,0x48,0x8a,0xbb,0x90,0x7f,0x79,0xae,0x17,0x5c,0x35,0x2e,0x9f,0x11,0xee,0x05,},"\xaa\x27\x6c\xc5\x43\xfc\xc6\x2d\x70\xa7\x04\x60\x8d\x98\xce\x51\xb6\x45\xb5\xc2\x4a\x64\x0a\x5d\xf1\x0a\x55\x91\x41\x7d\x10\x89\x26\xdf\x3f\x0c\xe1\xb9\x21\x03\x33\x09\xeb\x8d\x86\x59\xf4\x89\xfd\x6f\x79\xaa\x1b\xf4\x88\x2d\x72\xac\x69\xcc\x58\xd3\xbc\xe0\xfa\x89\xb1\x64\x11\xe9\x75\x3e\xb4\x0c\x6c\x4d\x59\x8d\xc8\xf4\xab\xb0\xbc\x48\xf1\x37\x03\x71\x32\x6c\x9a\x86\xbb\xc2\xac\x62\x14\x47\x8e\x78\xa3\x84\x08\xbd\xda\xfa\xa9\x59\x26\x00\xc4\x9a\x12\x9c\x05\x39\x2f\x8a\x7d\x64\x2b\x49\x13\x7a\x20\xf3\xfe\x9f\x11\xee\x17\xcf\xa3\xaf\xd2\xaf\x71\x56\x5e\x9c\x40\x08\x0b\x60\xcd\x0d\xbc\x37\x8e\xda\x06\x2c\x7c\xbc\x7f\xe9\x72\xbd\xe4\x50\x9a\x1d\xe9\x5f\x14\xdf\x48\x2f\x48\xaa\xcc\x46\x3c\xd5\x94\xf6\x6d\x64\x8d\x37\x94\x73\x8a\xd6\xab\x49\x6e\x2d\xa5\x0b\x0d\xb2\xba\x7b\x65\x91\x85\xe4\x58\x7f\x18\x2e\x83\x3d\xe7\x50\xfa\xac\xdd\xf2\x1a\xf5\xe0\xcf\x4c\x9a\xf3\x85\xb0\x4f\x7b\xe2\x31\x49\x8a\xd0\xb7\x42\xd5\xa8\x7c\x06\x11\x5d\xb2\x30\x97\x3a\x51\x42\x7f\x20\x2f\xa3\x9a\xfb\x98\x28\xb5\xf0\x3f\xa3\x27\xcb\xd5\x2d\xfe\xc6\x6d\x71\xea\x31\x98\x65\xdc\xf6\x81\x0f\x18\x58\x47\x2d\x8b\xea\x3e\x44\x7a\xdf\xb4\xb6\x07\x58\xe8\x6b\x48\x13\x37\x09\x73\x2d\x2b\xcf\x51\xc7\x6c\xaa\x84\x7b\x65\x37\xfc\xb0\x5b\xb8\xc8\x7d\xc5\xe9\xfb\x02\x2b\x32\x60\xc1\xd7\x1b\x14\x98\x59\xc9\x66\x3d\xbd\xae\x6a\x7b\xbf\xd6\xde\xb9\xd1\x23\x80\x9c\x24\x14\x01\xaf\x10\x71\x9c\xf9\x1a\x6b\xed\x16\x08\x4c\x44\x46\x07\x35\x9e\xd8\xf0\x18\xdb\x11\x15\x11\x89\x2b\x46\xbd\xac\x6c\x9c\x61\x38\x41\xde\xd8\x86\xb9\xde\xc0\x6c\x01\xe8\x04\x87\xe4\x8f\xbe\x77\x8e\x9e\x97\x50\x8f\xfd\xa0\x57\x78\x53\xaa\xbd\xca\xca\x8b\x0b\xab\x6c\xe4\x15\x57\xaa\xb9\x63\x1c\x96\xd6\x09\x77\xe3\x57\x18\xb6\x05\x95\x27\x3f\xdb\xa1\x40\xf5\x50\x0a\x8d\x35\x76\xf5\xa9\xfc\x8f\x3c\xa4\xc0\x2c\x16\x7a\xf2\xe0\x3d\x25\x75\x0b\x42\xad\xb0\x3b\x14\x17\xf2\xb6\xd2\x19\xbe\x5f\x84\x29\x33\x1a\x26\xa4\x49\xb5\xd4\xdb\x2b\x1a\x09\x15\x2e\xea\x2b\x25\xd2\xdf\x7e\xf6\xfe\x0a\x32\xe2\x5f\xae\x79\x36\x0a\x9a\xee\x15\x11\xfd\xa8\x06\x45\x50\x93\x7a\x71\x30\x97\x19\x30\xc6\x73\xbb\x35\x8e\x5f\x55\x95\x1f\x50\xb1\x46\xd8\x5d\x38\x3f\x3e\x01\xc1\x51\xec\xe6\xc0\x6d\x83\x67\x01\x25\x32\x80\xfd\xcf\xf4\xe1\x39\xd3\x31\x9a\xb2\xe2\xca\x71\xbc\xc3\xfa\x0f\xaf\x7c\x70\x2c\x9c\x60\x4e\x56\x51\xde\x4a\xf5\x70\x0e\x9e\xde\x72\x58\xb9\xbc\x14\x8d\x55\x95\xcd\x34\x17\x0e\x3e\x5c\xf2\x92\x82\x83\x90\x90\x8f\xda\x96\x1f\x22\x30\xac\x0b\x8c\xac\x64\x73\x97\x32\x70\x6c\xe2\xd5\xe5\x9a\xbd\x6d\x5e\x20\x7b\xda\xfe\xa7\x4d\x28\xd7\xa7\x58\xf2\x20\x0e\x4e\x00\xa0\xbc\xf0\x30\x6a\x3c\xab\xda\x47\x02\x4f\xab\xea\xe4\x88\xab\x5c\x32\x37\x15\xcf\x3c\xa7\x72\x0a\xf9\xeb\xbf\x85\x82\xe1\x15\x8a\x09\x9d\x73\x6b\x56\x9b\x9d\x40\x29\x58\x17\xea\x25\x54\x06\x8b\xef\x32\x44\x2c\x11\x1e\xc8\x14\xc6\xed\x41\x59\x19\xba\x73\x52\x63\x34\xdf\x30\xba\xc6\x66\x08\x4e\x56\x01\xc2\x28\x1c"}, +{{0x49,0x84,0x97,0xfd,0xcc,0x6a,0x10,0x58,0x91,0xe0,0x23,0xff,0x32,0xd7,0x5f,0x7c,0x37,0x48,0xd8,0xc5,0x2d,0x87,0xdd,0x3b,0x27,0x75,0xae,0xfd,0x81,0x60,0xa1,0x43,},{0x2d,0x79,0xae,0x9c,0xee,0x4a,0xc6,0x27,0x5b,0x05,0x74,0x9c,0x43,0x8e,0xbe,0x55,0x2b,0x41,0x3d,0x87,0x3c,0xc0,0x7f,0x14,0xf5,0xfa,0x13,0x01,0x77,0x21,0x4c,0x54,},{0xb0,0xa3,0x6a,0x2c,0x93,0x47,0x56,0x34,0x8e,0xb4,0x7c,0x25,0xa3,0x2c,0x3f,0x2a,0x5d,0xdb,0xd5,0x8f,0xcc,0x72,0xa0,0x8c,0x3c,0xea,0xd1,0xa2,0xd9,0x00,0x33,0x5c,0x30,0x01,0xe3,0x5b,0xfe,0x1f,0x3f,0xb5,0xa5,0x55,0x00,0x9b,0xa8,0xe9,0x68,0x74,0x49,0x4b,0x97,0xe8,0xb0,0x97,0x00,0xed,0xcb,0x1f,0x25,0x84,0xb9,0xd0,0xfe,0x03,},"\xbe\x38\xbc\x8c\xdf\x46\x19\x0e\x30\x4a\xb5\x3d\xd2\x9c\x2b\xc4\x09\x54\xfd\x4c\x6d\x2b\xb9\x90\xf9\x3b\x2b\x5c\x69\x1f\xdf\x05\x27\xc2\x60\xf5\x06\x61\x87\xf2\xd0\xf3\x1f\x43\xa0\x8b\x36\x0e\xa1\xed\x82\x00\x65\x17\x64\xb8\xfa\x49\x59\x5a\x15\x94\x10\x9e\x49\x67\x59\xab\x66\x23\xfa\x33\x37\x8d\x80\x0e\x61\x17\xe0\x79\xe1\x3f\xe8\x5c\x81\xb6\x3e\xbe\x24\x7b\x3d\xf6\xc1\x58\x4b\xc7\xcf\xfb\xdf\xa4\x5f\x2a\x2c\xe7\xc2\x37\xaa\xaf\xef\x8c\xbc\xa7\x0b\xca\xbc\xe0\xb8\x47\xd5\x51\xf4\x6a\x7d\x15\xce\x2a\x0d\x3d\x54\x5a\xba\xcc\x59\x30\x01\x0c\x53\x64\x88\x87\xd4\x76\xe0\xd1\x3a\x34\xfc\x1c\x54\xdf\x09\xd1\x06\xed\x75\x8d\xee\xdc\x76\x1d\x55\x7a\x73\xb2\xbc\xdd\xde\xfb\xa4\xed\x00\x59\x97\xb1\x92\x79\xb9\xd2\xde\x37\xd0\x41\xfe\x01\x3e\xef\x05\xa2\xe1\x1c\x9a\x23\x4e\x87\xcc\x0e\x16\xc0\xc6\xda\x42\xaa\xa5\xbf\x99\x64\x17\xbf\x64\xe5\xb7\x85\xd6\x7d\xc3\x25\x47\xc1\xf0\x52\x17\x8d\x69\x4c\xf2\x0f\x16\x98\x58\x9e\x7e\xd4\x9b\xe2\x9d\xd5\x9f\xd5\xc0\x1b\xa1\xd9\xf5\xfb\x06\xa7\x58\x95\xb7\xb1\xe1\x58\x95\x09\x7e\xbd\xe8\x4c\xad\x63\x03\xaa\x0a\x86\xdb\xc3\x24\x74\x7d\x97\x24\x5d\x70\xc5\x20\x3b\xe0\x1b\x06\xcb\xde\x06\xae\x03\x72\x04\xd2\x37\x30\xcd\x69\x61\x89\xf7\xac\x26\x7c\xf2\x02\x17\x99\x29\xce\x54\x10\xe0\xe3\xad\xe5\x13\xd2\x20\x1b\xfd\x20\xfe\xfa\x40\xb4\x47\x6f\x27\xbf\x90\x7c\x76\x2e\xb7\x26\x2a\x5b\xe1\x3c\xfc\x04\x7a\x84\x6d\x20\xa9\xf2\x31\x1b\x64\x69\xb0\x6a\xb5\x45\xf0\xec\x9f\xc4\x46\xea\x25\x0c\xd3\xb7\x3a\x7b\x6b\x96\x0c\x10\xca\x4c\x2d\x6c\x64\xa1\x56\xa1\x8c\x9f\xb8\x10\xe4\x9a\xfd\x0c\x36\xda\xab\x8b\x8b\x85\x66\x43\xa4\xcc\xaf\xa9\xad\x88\x6e\x91\xe5\x44\x53\x5b\x8e\xdd\xa2\x7c\x90\xc0\x6a\xb6\xbc\xc5\x36\x28\xbe\x18\xd7\xd6\x36\x9c\xa1\x80\x1f\x91\xc2\xe0\xb9\x5f\x36\xd7\x02\xf7\x72\x34\xb4\x10\x07\x19\xc0\x59\x95\x1e\x45\xb1\xf9\x16\x98\x39\x34\xe3\x2b\x4d\x4d\x8f\x29\xc0\xa3\x73\xf8\xd8\xf0\x91\x8b\x96\x78\x65\xcd\x0e\x4b\xec\xa0\x13\x27\xc9\x9d\x5f\xde\xd4\xc1\xa6\x9a\xc2\xd4\xd9\xb7\x8f\xfb\x83\x05\x67\x00\x21\x04\x02\x50\xcc\x27\x73\x7e\x75\xdf\x75\x76\x0f\xec\x8b\x8d\x30\xb2\x45\x65\x4f\x3c\x12\xf1\xf7\xce\xa0\xbc\xe7\x8a\xb3\x69\x35\x78\xaf\x3e\xa6\x1f\xfc\xcd\xf9\xba\xf7\xc3\xea\x65\xb8\x8f\xc8\x54\x12\x81\x26\x47\x67\x96\x89\x2c\x66\x3b\xd1\x45\x18\xc9\x91\x86\x29\xa1\x09\x5f\x61\x4e\x04\x92\x44\x6c\x3d\x84\xb1\x6e\xc9\x4f\x7e\xca\xda\xeb\x6b\x65\x9b\xbb\x48\x67\xb5\x79\x06\x17\x14\xfd\x5b\xb0\xfa\xa4\xad\x6b\xe0\xff\xb3\x88\x8b\xea\x44\x7e\x4e\x34\x38\xc8\xf0\xea\xe6\x44\xfb\xd4\x5a\x38\x02\xdc\x40\xec\x45\x1b\x21\x2b\xd5\x92\xda\xcd\x4d\xa9\x66\x86\xdc\x8b\x20\x24\x25\x7f\x25\xe9\xc8\x30\xbf\xf7\x95\xee\xe8\x5d\x87\xa0\x90\xc1\xa4\x23\x21\xe7\x10\x55\x57\x64\xed\x82\x57\xc9\x41\x5c\x7f\x22\x4b\x53\x75\x58\xce\xfd\xc6\x15\x12\x9f\x28\x35\x02\x67\xc0\x1b\xa0\x40\x3e\x07\xf5\xc6\x06\x7f\x91\xc8\x5a\x2c\x50\xc8\x66\xdc\x43\x88\xaf\x38\xd2\x16\x02\x03"}, +{{0xd9,0x62,0xa6,0x71,0x9e,0x5c,0xc7,0x72,0x4c,0xa4,0xa1,0xd5,0x59,0x53,0x68,0x12,0xb4,0xe2,0x2a,0xa7,0xbc,0xb1,0x3e,0x4f,0xb1,0x72,0x2d,0x28,0xe0,0x45,0x21,0x7c,},{0xa9,0x44,0x59,0x2d,0xbc,0x7d,0x77,0x03,0x9d,0x72,0x02,0x56,0xc3,0xfd,0x34,0x0d,0x34,0xdb,0x89,0x2a,0xb1,0x3e,0x48,0x12,0xd6,0x62,0xe2,0x84,0x0c,0x28,0xb6,0xd0,},{0xdf,0xb9,0xb6,0x35,0xac,0x0e,0xdf,0x83,0xb7,0xb5,0x9d,0x0b,0x84,0x09,0xaf,0x47,0x5f,0x66,0xfc,0x99,0x46,0xaf,0x0b,0x7c,0x63,0xab,0x8c,0xf5,0x92,0x9d,0x47,0x01,0xa1,0xbf,0x66,0x95,0x9c,0xde,0x62,0xfb,0xcf,0x59,0xa4,0x8a,0xb3,0xbb,0xaf,0x0b,0x9a,0x61,0xb6,0xe0,0x0b,0x21,0x81,0xeb,0x93,0x42,0x82,0x07,0x0a,0x5d,0x53,0x00,},"\xa6\xaa\x7a\x19\x0d\x00\x3a\xb1\x75\x33\x2b\x8f\x58\xe7\xca\xeb\x69\x08\x54\xd9\xdb\x56\xdb\xb6\x95\x7b\x3f\xb6\x54\xe2\xe0\xda\x99\x1f\x31\x54\x21\x42\x04\x13\x5d\xf1\xe1\x10\x43\x17\xc9\xe3\xc5\x8e\xed\xff\x1f\xc6\x1a\xba\x57\x74\x4c\x0c\x7e\xf4\x86\x00\x0a\x70\xb2\xc1\x42\xeb\xad\xdc\x07\xab\x06\x5e\x2a\x85\x5d\xaf\x19\x8a\x68\x03\xac\x24\xef\x37\x24\x48\x7c\x13\x51\xdd\xed\xa0\x51\x39\x13\x45\x7d\x76\x86\x0d\x78\xa9\xb6\xbc\x3d\xba\x66\xc4\x0e\x5f\xc3\x49\xa8\x73\xad\x60\x65\xce\x7d\x7f\xdc\x2c\xc4\x83\xb3\xae\xfb\xf2\xf0\x3d\xd6\x69\xbd\x9c\xb8\xf6\x3c\xee\x47\x78\x5c\xac\xb0\x9d\x87\x2c\x9a\xeb\x83\xe9\x86\x84\x05\x25\x43\x24\x03\x79\x82\xe0\x86\x13\x45\x5d\x95\x21\xd8\x8e\xa2\xfd\xa0\x20\xbe\x73\x0c\xfc\x8c\x07\xcb\x0b\x37\x61\x4c\xcb\xa2\xfa\x3e\xc4\x98\xb8\x15\xbb\x5a\xdb\x99\x6e\x84\x8b\x38\xc0\x15\xa6\xa5\xc7\x52\xeb\xda\xc7\xb9\xee\xd8\xb6\x96\x19\xd8\xc8\x46\xb6\x6f\x78\x16\xd1\xdf\x1e\xbc\x21\x07\x1c\xef\x0b\x25\x1e\x2e\xab\x59\x82\x7f\x6d\x60\x55\x08\x43\x70\xfd\x27\xc2\x03\xe8\x6a\x18\x9f\x1e\xe1\x1e\x84\x03\xab\xdc\xbd\x1f\x45\x34\x1a\x82\x05\x25\xd8\x63\x7d\xc4\x84\xa5\x18\x5d\x65\x51\xcb\x88\x2a\x96\xb9\x98\x1a\x5f\x1a\x82\x1f\x27\xb6\x56\xff\xf9\x0e\x7f\x69\xbf\x28\x6f\x75\x2f\x97\x0f\xfc\xa5\xc5\x3e\x08\x50\xb2\x0b\x94\xf9\x43\x16\x27\x09\x4a\xce\xa9\x12\xa8\x80\xb7\x49\xa6\xf8\x0b\xb2\x06\xcc\xaa\x74\x6f\xa7\x0c\x83\x3c\x9f\x32\x30\x89\xce\x05\x58\xc9\xdc\x20\x0d\x57\x39\xd1\xe4\x99\x63\x4f\x2c\x16\xe5\x4b\x7f\x6d\x78\x19\xc4\x70\x71\xb6\x0b\xd5\x4d\xd0\xf2\x73\xa3\x19\x75\x0f\xd3\xc5\x10\xa4\x9a\xb5\x6f\x63\x0c\x7c\xe6\xd8\x02\x3d\x97\x86\x23\x46\x85\x9b\xc0\xb4\xd6\x05\x22\x49\x69\x70\x89\x03\x76\x03\x01\x40\x9c\x60\xab\x25\x17\x56\x11\xf0\xbe\x98\xb2\x3a\x8c\xd8\xac\x53\x5e\x35\x13\xbc\x77\xe1\x45\x21\x93\xda\xdf\x44\x35\xe6\x3c\x36\x29\xb6\x66\xa5\xea\x4c\x4b\xad\x36\xea\xca\xd2\x60\x14\x04\xea\xbd\x8d\x9a\x07\x95\x6e\xc2\xb4\xb7\xbb\x63\x36\xed\x75\xb8\xdf\x8f\x16\xde\x42\xc0\xfc\xae\x93\x65\x2e\x3c\x40\x7c\xbd\x45\xe8\xd4\x13\xef\x51\xe8\x54\x2d\xf6\x25\x12\xee\x79\x3e\x41\x35\x8a\x1d\xe1\x92\x46\xc6\x58\x6b\x3c\x14\x07\x41\x04\x21\xf6\xe8\x65\xc7\x5a\x9f\x4a\x6a\x47\x88\xf8\x4a\x9c\x78\x1d\x8f\x80\x24\xbf\xdb\xe2\x5b\xdc\x7d\x4b\x69\xcb\xaa\x77\x19\x62\x8c\x0b\x07\xec\x2c\x4a\x23\x4f\xff\x4a\xc3\xd4\x93\x5b\x9c\xe4\xc8\xa1\x69\x47\xab\xe7\x95\x1f\xf8\xd9\xac\x92\x15\xe3\x38\xfa\x0f\xe9\x12\x41\x76\xd1\x7b\xac\x1e\x05\x59\x2c\x43\x98\x68\xae\x5a\x4f\x75\xfd\x1e\xa8\x2a\xa4\x54\xc2\x0a\x93\x9d\xed\xa7\x29\xa0\xe1\x96\x46\xce\xbd\x82\x20\x49\xc8\x25\xc7\xe3\x1c\x6e\xfa\xd4\x5e\x30\x6f\x2d\x9f\x05\x69\xe0\x71\x73\x31\xf4\x80\x04\xc2\x6e\xbf\xe6\x8f\x38\x43\xe9\x0f\x80\x67\x03\x2d\x21\xe7\x86\xc8\x53\x9e\x01\xbe\x3c\xea\xc5\x95\x4a\x05\x46\xc8\x4b\x73\x4d\x99\x94\x56\xa7\xc4\x5f\x8c\xeb\xaa\x47\x8e\x54\x80\x07\xf9\xd3\xaf\x83\x6f\x75\x4d\xe4\x12\x3f\x2f"}, +{{0xe1,0xd1,0x41,0x65,0x18,0x92,0x1d,0x07,0xc8,0xc3,0x9e,0x29,0x73,0xd8,0xea,0x12,0x49,0xca,0xa8,0xbf,0x65,0x9c,0xc3,0x6c,0x79,0x37,0xf8,0x4e,0xce,0x7a,0xd4,0xfc,},{0x48,0xbd,0xcc,0x3f,0x1a,0x5b,0x80,0x58,0xed,0x9a,0x32,0xef,0x1c,0xc4,0x8c,0xf7,0xa8,0xab,0x76,0xa6,0xe4,0x51,0x9e,0x5a,0x82,0x85,0x52,0x41,0xad,0x6f,0xff,0x8a,},{0x42,0x32,0xd2,0xa4,0x81,0x08,0x4d,0x11,0x96,0xdb,0x62,0xf2,0x2d,0xc7,0x4c,0xf2,0xea,0xf2,0xdb,0x0d,0xf0,0x5a,0xd7,0xcd,0xde,0x67,0xbf,0xc2,0x9b,0xff,0x56,0xcd,0xe0,0x19,0xac,0x9f,0x03,0xd8,0x1f,0x18,0x27,0xeb,0x1e,0x3b,0x0a,0xbe,0x02,0x04,0xca,0x7f,0x77,0xfa,0x87,0x4a,0xb5,0x26,0x83,0x54,0xff,0x08,0xbb,0x7f,0x48,0x00,},"\x3d\x26\x3d\xe1\xab\x91\xe8\xdd\x7b\x31\x7f\x7a\x27\xfb\x60\xa6\xe1\x83\x8c\x0c\x79\x3b\x03\xab\xbe\x70\x82\xb6\xbd\xa0\xc7\xc4\x60\x62\x26\x21\x92\xc8\x8b\x65\xc0\x26\xc1\x74\x58\x4d\x29\x64\x97\x10\x42\x9a\xe4\x4a\x46\x14\x0b\x4c\x82\xc8\xa0\xb7\x4d\x56\xa0\x04\xf8\xe2\xf5\xc1\x8f\x84\xf0\x46\x41\x53\x77\x2f\x83\x12\x63\x3f\xc6\xad\x28\xa7\xd9\xfb\x55\xf7\xd7\x8c\xd6\x48\x8c\xa5\x81\x17\xea\xf9\x23\xfa\x28\x87\x5e\x2b\x31\x89\x89\x31\x85\xaa\x3c\xcd\x04\x4d\x3f\x11\x0e\x2e\x7c\xab\xdf\x6f\x81\x4b\x9f\xdd\x67\x33\xbd\x5f\x30\x7a\x87\xbc\x73\xb6\x25\x0d\x58\x83\x93\x6d\xeb\x1d\xb0\xe0\xaf\x1b\xe7\xab\x32\x9b\x5c\x6b\xd9\x35\xbd\x8f\x8d\xc8\x88\xf0\xd1\xc4\x64\xed\xbc\x02\x3c\xbc\x08\x07\x53\xee\x8f\x79\x9f\x10\x72\xba\xd1\x14\x4d\xfa\xa6\x15\xa5\x9e\x2a\xed\xc6\x62\xe8\x3c\xb1\xf8\xe5\x20\x96\xa7\xee\x48\x3b\xf8\x73\xb2\x5a\x0c\x04\xc1\x85\x1a\x0e\x87\x37\x50\x63\xaa\x1a\x94\xfa\x83\x5c\x05\x26\x40\x36\x6b\x79\xf7\x35\xd3\x28\x61\x97\xab\x32\xeb\xdb\x51\x23\xf6\xb4\x7a\xd3\xf4\x42\xc4\x4c\x53\x0a\x68\xf8\x51\x27\x59\xe9\xcf\x38\x6f\xba\x07\xb8\x06\x4b\xc8\xfe\x83\xe2\x45\x49\x5e\xc4\x5f\x89\x38\xf8\x25\x9d\xc8\x01\x62\x05\xf7\x8d\x39\x54\x44\x2e\xc1\xb4\x45\xd8\x3d\x95\xad\x18\x05\xa5\xe0\xe8\xb3\xd5\x6b\x87\x0a\x20\xda\x18\xd7\x4f\x26\xf5\x50\xa9\xc7\x53\x4a\x41\x44\xdc\xbc\x1c\x3c\xdb\xbe\x47\x0c\xc1\x53\x90\x50\x43\x08\x8f\xac\xf1\xd3\x03\x55\x9d\xe4\x1e\x96\xc0\xab\x40\x9b\xb3\x6d\xcf\x38\xcc\x90\x38\xa6\xa4\x90\x8d\xea\x82\xa6\x53\x19\x5c\x16\xf2\x90\xa7\xc3\xac\x48\x76\x36\xcc\x5b\xcb\x18\xd1\x5a\x14\xac\x62\x4c\x70\xb6\xf6\x46\x2b\xf2\x49\xe0\x00\xce\xe9\x24\x01\x8b\xdf\x7d\xde\x39\x11\x4c\xb4\xf6\x52\xe1\x22\xe8\x74\x4d\xa2\x8b\x05\x89\xe1\x28\x4d\x70\xd9\xf1\x06\xde\x16\xd0\x73\x64\x80\x80\xe6\x43\x7f\xf3\x84\xe6\x81\x77\xd5\xcb\x71\x8e\x2c\xe3\xf1\x7b\xa1\xe9\x90\xae\x3c\xe9\x40\x66\x01\x30\xe9\x37\x50\xb8\x2e\x2f\xb4\x1a\xa3\x69\x77\x45\x68\xd7\xcf\x28\x67\x25\xe3\xc5\x8f\x63\xe7\x3f\x86\x97\xae\xec\xc7\x17\xc5\xcf\x1a\xf7\xad\x74\xf4\x46\x29\x2c\x90\x5d\x84\xe2\x2b\x23\xd4\xe0\xd2\x60\x4b\xff\x48\xfe\xfc\x40\xc6\x20\x4b\x5e\x34\xc0\x42\x29\x2e\x53\xbe\xc9\x36\x01\x59\xa5\xcd\x97\xb2\xdf\x57\x86\xb8\xf5\xa2\x92\xc0\xb3\x9d\x14\xa8\x70\xa4\x58\x8e\x67\xbd\x12\xb2\xc2\xf7\xa4\x40\x84\x62\x85\x1d\x2a\xa7\x87\x97\x1d\x93\x15\x19\x0f\x42\xcc\x58\x8a\xf0\xd2\xdc\xd9\x1f\x31\xbb\x71\x5e\x92\x50\xf1\x19\x28\x14\xf7\xb8\xa2\x1f\xef\x45\x17\xb0\xcf\x8b\xb8\xa1\xa1\xa5\xf5\x00\xee\x21\x9d\xfb\x46\x13\x2e\xfe\x8e\x90\xbc\x49\x09\x3a\x55\x59\xf9\x68\x1b\x4f\xb5\x9e\x5b\xa9\xef\x3f\x05\xd3\x4e\xed\x03\x4c\x14\xd7\x7e\xe9\x5e\xbd\x76\xff\xa5\xaf\x0b\xef\xcb\xa1\x8f\xdf\x93\x2a\xf4\x85\x45\x10\xb7\x5d\xb0\x0a\x72\x57\xb2\x34\x88\x7d\x49\x60\x7d\xfd\x16\x18\x0d\xb5\x16\xc7\xa2\x0c\xcf\xca\xed\xa6\xae\xdf\xb6\xa2\x37\x7f\xbf\x31\xe6\x7b\x51\x76\x55\xdb\x73\xca\x29\xe1\x18\x62\x4d\x60\x80"}, +{{0x2b,0xf7,0x4f,0x00,0x4d,0x7d,0x0a,0xf7,0x3a,0x83,0xea,0x20,0x8c,0xc2,0x06,0x72,0x3d,0x18,0x8f,0x4c,0xf6,0x07,0xbc,0xad,0x4b,0x69,0x80,0x26,0x8f,0xf2,0x1f,0xa7,},{0x8f,0xdc,0xd9,0x93,0x52,0x43,0x8b,0xeb,0x52,0xf0,0xd1,0x74,0x2b,0xae,0x71,0x84,0x45,0x12,0xdd,0x06,0x85,0xaa,0xf1,0xc9,0x09,0xe3,0x8f,0xc4,0xb5,0xaa,0xb6,0xcc,},{0x3e,0xb5,0xb3,0x39,0xe1,0x91,0xa3,0xb6,0x16,0x85,0x45,0xda,0x5f,0xb0,0xca,0x9b,0xe2,0x09,0x04,0x39,0x19,0xb9,0xc7,0x0a,0x07,0xb4,0xa7,0xa3,0xbf,0x64,0xb1,0x02,0xf6,0xff,0xd6,0xd2,0xb0,0x25,0x59,0xdc,0x68,0x1e,0xd3,0xb9,0xc8,0x22,0x97,0xb2,0x01,0xdc,0x25,0xc4,0x97,0x38,0x80,0xe1,0x55,0xe1,0x3a,0x29,0x42,0x6e,0xb4,0x0d,},"\x89\x8e\x43\x03\xea\x5b\xeb\xd2\x00\xa5\xf7\x56\x2b\xe5\xf5\x03\x26\x40\xa3\xf5\xcc\xfa\x76\x42\x92\x04\x5a\x1a\x36\x8d\x02\xaa\x59\x10\x77\xd8\xf3\x04\xf7\x4d\xbd\xfc\x28\x07\x34\x45\x4e\xd8\xc2\x72\x7a\xff\x39\x2c\x10\x8c\x52\x6e\x52\x7e\x67\x2c\x53\x97\xb2\xd7\x7c\x01\xf7\x74\x1e\xf8\xdc\xc2\x51\x0e\xe8\x41\xb5\x9d\xd1\x0f\x4e\x1d\x3a\xc5\x01\xaf\x7c\xbd\xb8\x5b\xa3\x11\x29\xc2\x62\xfd\xe1\xa0\xc8\xbc\x83\xd6\xff\x94\x4b\x6b\xae\x3f\xa7\xfb\x62\x58\x7c\x68\x1d\x8e\x34\x29\x65\xc5\x70\x5f\xd1\xa6\xab\x39\xe5\xa0\x77\x0e\xe7\x79\x8d\x9f\xb6\xc0\x01\x8a\x51\x4d\x53\xaf\x84\x8d\xb6\x04\x7c\xd0\x2d\xb3\x52\xd5\x56\x3b\x53\x66\x23\x73\xb9\x71\x93\x5a\x1a\xc2\xb7\xb6\x36\x1d\xac\x67\x48\x77\x18\x13\xf7\x74\x93\x16\x69\x49\x61\xb9\x40\xff\x38\x05\x81\x1a\x49\xfa\x27\xa9\xba\x45\x7a\xd2\x88\x48\xc6\x97\x05\x0e\x01\x88\xd0\x77\x3e\x17\xfb\x52\x19\x4e\x19\x0a\x78\x72\xa3\x98\xf3\x1c\x0f\x0a\xe0\x65\x37\xa2\x73\xff\xb5\x0c\x2c\x81\x64\x45\xab\x88\x28\x11\x92\x2c\x06\x21\x55\x6c\x46\xa3\xa0\xec\x40\xbf\xed\xb4\x11\xe9\x0b\x6d\xb1\xdd\xd4\xbb\xeb\xb5\x7d\x10\xdf\x56\x6a\x63\xd7\x26\xa3\x33\x08\x51\x4c\xe3\xb4\x99\xd5\xe5\x26\xc2\x2b\x95\x6d\x8b\x99\x91\x3d\xcb\x13\xe4\x37\xe9\x47\xb6\x66\xc4\x1c\x54\xd8\xb3\xae\x23\x56\x64\x7e\x80\x17\xab\x67\x83\x86\xc9\x27\x21\x9a\xe7\xbd\xdc\x0d\x82\x12\x65\xf9\xdc\x4f\xf3\xf8\xce\x5b\xe6\x0f\x8e\x9d\xef\xc5\xca\x33\x50\x68\xee\x29\xfe\x83\x04\x91\x7b\x78\x87\x84\xa2\x38\x8a\x32\x01\x92\xf9\x32\x5d\x0e\x6c\xff\xfe\xa2\x1e\x6e\xaa\x29\xe7\x70\x7f\x63\xa9\xea\x4f\xbb\x25\x58\xe3\xd0\x83\x5b\xab\x1f\x52\x36\x10\x37\xae\x59\xe5\x03\xee\x96\xb9\xd7\x08\xa4\x7a\x3a\xe4\xba\xd1\x13\xe2\xa4\x60\xa2\x69\xcc\xf2\x5a\x00\x03\xcb\x3e\x68\xa5\x51\x86\x4e\x59\x84\x09\x14\x79\x11\x26\xf9\x54\x78\x8b\x25\xb5\xaf\x5a\xaf\x58\x6e\xbb\x87\xfa\x5f\x37\x7b\x4d\x7d\x7f\x84\xc0\x00\xdd\x2c\xb4\x40\xe2\x14\xd3\x8d\x5e\xcf\x70\xf2\x0e\x98\x81\x82\x8e\xda\xa1\xdb\xec\x37\x09\x3d\xb9\x60\x68\x6c\xa1\x23\xf1\xec\xba\x63\x36\xb3\x7f\x46\xcf\x76\x5b\xe2\x81\x4b\x9e\x67\x05\xbc\x9d\x6a\x49\x31\x81\x18\xc7\x52\x9b\x37\xc8\x4e\xc8\x8d\x58\xa8\x45\x3d\xcb\x69\x2c\x9a\x36\x01\x6b\x94\x8e\xbe\x6f\xb2\xc1\xd0\xad\xf5\xf1\x98\xee\x30\x97\xa6\xff\x0b\x8e\xeb\xba\xd8\xb0\x76\x93\x30\xb1\x86\x89\x51\x6b\xc0\xfe\x66\x8b\x0d\x05\xe3\xa5\x84\xfc\xf8\x9c\x49\xdb\x50\x1d\x61\xc2\xde\xf7\xed\x37\x22\x07\x01\x93\xa5\xb6\x83\xc5\x08\x7e\xf2\x74\xce\x6a\x19\x3d\xd4\xa3\x03\x53\x6c\x67\x93\x4b\x46\x60\xa8\x41\xee\x1b\x44\x6a\x68\x92\xb1\x4d\x0b\x0a\xa3\xe9\x8f\xdf\xfd\x43\xc7\x97\xad\xd3\x65\x83\xf7\x4c\x94\xd0\xe2\xd6\x8e\x2d\xe8\x18\xd9\xaf\x20\x05\x98\xf0\xb2\xbe\xae\x16\x9c\x8d\xfb\xc4\xd3\x97\xe6\xd1\xce\xb6\xda\xa6\xc9\xf6\xbb\xf4\xf8\x31\x1b\xa2\x6f\xfb\x19\x4d\x44\x21\x6c\x51\x30\x52\x67\x07\x4e\x85\x6a\x1d\x6e\x92\x27\x80\xf4\x79\x8e\x2f\x22\x02\x23\xff\xf1\xdc\x37\x0c\x8e\x34\x51\x4a\xba\x42\xdf\x51"}, +{{0xf5,0xf7,0xd5,0xb7,0x3c,0x5a,0x65,0x30,0x1b,0x5b,0x4c,0x67,0x10,0xed,0x12,0xc1,0x6e,0x79,0x03,0x17,0x7d,0xb7,0x92,0xca,0x71,0x5e,0x23,0x38,0x9d,0x05,0xd8,0x3e,},{0x7c,0x47,0x62,0xe9,0x79,0xf0,0xc7,0xe2,0x07,0xbe,0x18,0x43,0xe2,0x66,0x6a,0xca,0x27,0xea,0x89,0xbf,0xf5,0xb6,0x1d,0x57,0x3c,0x98,0x5f,0xc7,0x02,0x5e,0x1e,0x28,},{0x58,0xfb,0x39,0x2f,0x82,0xd5,0xe5,0x2f,0xf0,0x72,0xcc,0x77,0xef,0xe0,0x48,0xf2,0x23,0x52,0x50,0xc7,0x11,0x25,0xee,0x82,0x1c,0x5f,0x3b,0x39,0x3b,0xcf,0x2f,0xa4,0x6b,0xe4,0xc5,0xd8,0xca,0xf1,0x3c,0xb5,0x19,0xef,0xe0,0xc2,0xfa,0xd9,0xee,0x23,0x1a,0xe9,0xb6,0xfd,0x1f,0xd5,0x09,0xc9,0x8c,0x69,0xc2,0xd3,0x6c,0x75,0x3e,0x0e,},"\x7c\x93\x18\xd5\x6e\x63\xf1\x65\x35\x43\x6f\xa4\x5a\xfe\x27\x8e\x74\xe6\x18\x81\xbb\x46\x89\x97\xd0\x41\x8b\xc7\x20\xb6\x30\xda\xdb\x81\x28\xb4\xb6\x5c\xa6\xe9\x21\xe5\x01\x81\x3d\xf9\xfe\x03\xb4\xef\x0a\xae\x80\x35\xdd\x08\xc5\xf8\x20\xce\x5d\xf1\x2e\xe1\x18\xd9\xc3\x6d\x3b\x15\x1a\x52\xc3\xf9\x6a\xe1\xca\x4c\x82\xfd\x19\xda\x66\x9d\xdb\xa9\x4f\xeb\xf8\xea\xc8\xc4\x2b\x44\x7b\xab\xc8\xa6\x0b\x36\xe8\x03\x62\x4f\x7d\x20\x47\xbd\x8d\x8a\x15\x36\x87\xf1\x0d\xc1\xca\x82\x10\x0b\x7c\x87\xd3\x23\x70\xec\x8f\x26\x71\xed\x7d\x06\x7c\xc8\x05\x87\xca\xb8\xdb\x3a\x71\xce\x5e\x40\x63\x27\xf7\x63\xec\x1b\x3c\x16\x67\x70\xa7\x55\x36\x63\x0c\x81\x5f\xd8\x26\x75\x82\xd1\xb5\x05\x1f\x0f\x82\x1c\x02\x15\x0b\x2e\xef\x34\x9b\x50\x59\x03\x14\xaa\x25\x70\x79\x3f\xa6\x4a\x76\xed\x2e\xd8\x3d\x2b\xa1\xf9\xb9\xf1\x16\x31\x54\x61\x2b\x49\xa6\x4a\xd8\xd5\x57\x3c\x25\xb1\xcd\x37\xc4\x1a\x44\xe3\xdf\x78\xf1\x05\x3d\x90\xb0\x68\xf0\xd3\x7a\xe0\x0c\x4a\x32\xb1\xa3\xff\x87\x4c\x41\xda\x4a\x70\x43\x39\x2f\x18\xef\xe5\x51\x8d\x76\xe8\x8b\x41\xce\xd6\x9e\x6f\x4c\x01\x4f\x06\xeb\xc5\x14\x6e\x61\xe8\x2f\xae\x1c\x49\xc3\x7c\x39\x4f\xea\x34\x19\x9a\xb8\x6c\x11\xa4\x46\x7a\x37\x4e\x40\x25\x5a\x05\xd4\x26\x97\x14\x30\xd5\x6c\xdb\xa2\x5a\x21\xad\x77\x9c\xc7\xf6\x2d\x22\xcd\x87\xb6\x0f\x08\x91\xbd\x85\x6a\x51\x7e\x14\xb7\x2a\x9a\xc7\x67\x2e\x4e\x8f\xb3\x74\xa9\x75\x8a\xb0\xc4\xe5\x96\x4a\xae\x03\x22\x89\x73\xf1\x73\xa5\xd4\x2a\xef\x9d\xb3\x37\x36\xc3\xe1\x8d\x8e\xec\x20\x4a\x1a\x17\xb9\xd0\x45\x93\xde\xa4\xd8\x04\xcb\xc8\x1b\x9a\xc5\x45\x80\x50\x49\x55\x39\x99\x9a\x99\x85\x48\x7e\x7c\xa1\x1c\x37\x58\x2e\xf8\x5c\x84\x1e\x8f\x06\x5e\xa9\x8f\xdd\x6b\x1c\x60\xde\xa1\xec\x28\x83\x52\x15\x68\x85\x6a\x6e\xbb\x27\x49\xf2\x07\x2e\xb4\x34\x48\xbe\x07\x05\xed\x47\x7c\xf4\xb2\x00\x48\x65\x21\x7d\xe5\xfa\xdb\xe2\xa0\xf9\xd6\xb8\x4b\x3f\xe7\xf7\xbf\x6c\x77\x53\x74\x96\x24\x6e\xc7\x96\xb8\xef\x2c\x04\xf6\x8a\xb5\xb1\x4f\xce\x0c\x6d\x28\x7b\x83\x62\x27\xd9\xf0\x8f\xa0\xee\x19\x72\x2f\x67\x98\xa5\xd8\x28\x0d\x10\x7c\xfc\x1b\xd5\x92\xd9\xdd\xc7\x24\xea\x86\xfc\x39\xdc\x94\xa3\x94\x01\x9e\x3a\x3d\xe9\xe0\xd1\xc7\x35\xe8\x62\xde\x2b\xb9\x52\x5b\x5f\xb4\xbd\x12\x12\x12\xbf\xaf\xf9\xff\x58\x6a\xc3\xc7\x5c\x5a\xce\x74\x6d\x9c\xa3\x07\xf7\x95\xff\x26\x97\xf2\xb4\x1a\x63\x46\xed\x23\x39\x7e\xb3\x88\x98\x69\x1e\x6f\x66\x84\x16\x37\xd0\xab\x0d\x96\x83\x09\xe0\x19\x40\x02\x30\x90\x15\x41\x6e\x74\x47\x2f\xe3\x24\x25\xd4\x5f\x07\xc7\x71\x19\x18\xb1\xe5\x79\x0f\x57\x2c\xe4\x44\x10\x42\xd4\x26\x03\x37\x92\x29\x7b\x5f\x81\xe0\x80\x9b\xd9\x69\x1f\x0a\x50\x5e\x32\x59\xfc\x03\xc9\xff\x10\x7e\xb9\xb4\x87\x95\xf4\x9f\xb0\x9c\x1b\xab\x56\x59\xd3\x9f\xfe\xcb\xdc\xc4\x03\xe3\x80\x3d\xc0\x12\x43\x8c\x2f\xb3\x6f\x68\x30\x15\xc5\xdf\x04\x82\xcb\x7d\x7f\xc5\x75\x73\x64\xa0\xa3\xc1\x0d\x0e\x12\x59\xc0\x1f\xcc\x4d\xd5\x49\x4b\x52\x90\xa6\x94\xae\xa3\xf6\xfa\xe5\x47\xac\x57\x6f"}, +{{0x43,0xd4,0xbe,0x6d,0xe9,0xcb,0x00,0x89,0x8e,0x99,0xdd,0xcc,0x2e,0x15,0x30,0x11,0x0f,0xa2,0xcb,0xc4,0x37,0x6c,0x48,0x5e,0x9c,0xa5,0x7f,0xd6,0x55,0x86,0xd8,0xa3,},{0x36,0x32,0xad,0x38,0x9b,0xe2,0xfa,0xb3,0xfb,0xa0,0xd8,0x04,0xbf,0x63,0x45,0xcd,0x32,0x2e,0xdd,0xd6,0xa7,0x5d,0x8c,0x37,0xfd,0x4b,0x5b,0xa1,0xc9,0xc2,0x5e,0x8f,},{0x86,0xae,0x93,0x25,0xf8,0x0b,0x98,0x86,0xc8,0x38,0x1f,0x96,0xa1,0x8c,0x21,0x20,0xe6,0xdb,0x01,0x6a,0x0d,0x6c,0xa2,0x82,0xed,0x93,0xba,0x9b,0x61,0xca,0xec,0x02,0xde,0x88,0xef,0xca,0x8b,0x8e,0x91,0x6a,0x4b,0x16,0xa5,0x85,0x25,0xa2,0xf6,0x8d,0x21,0xe5,0xfb,0xe6,0x7d,0xb4,0xc4,0xd6,0x20,0x95,0x95,0xc4,0xab,0xc3,0x2b,0x09,},"\xd9\xd5\x5d\xab\x0f\xa6\xda\x76\xb6\x8e\x84\x1c\x24\xd9\x71\xba\xc1\xf7\x9a\xf5\x13\xd8\x34\xe4\x26\xa5\xd0\x81\x14\xce\x8b\x54\xce\x8b\x7a\xfe\x01\x6b\x0f\xad\x03\xee\x74\x50\xc6\xc3\x09\x71\x73\x68\x1a\x4b\x2e\xb9\xf9\xc1\x79\xa8\x8e\x7c\xc3\x68\x13\xf2\xf5\xd1\x5f\x79\x98\xaf\xa9\xfd\x4e\x54\x6c\x73\xbb\x42\xe7\xf9\x52\x2b\xe6\xaf\xab\xca\x8c\x7b\x64\xfe\xd0\xe2\x92\xe4\x37\x5f\x3e\x1e\x5f\xd9\xfc\xb5\x39\xf4\xe5\xe5\x43\xfb\x6a\x11\xa0\xdf\x32\x1e\x70\x08\x4a\xaa\xbb\x70\xa9\x95\x0c\xee\xe3\xd8\x79\xc3\x86\xef\xca\x1e\x59\xc3\xcb\x7c\x45\xb5\x60\x09\x5e\x7a\xf0\x0f\xf5\x2f\x8a\x1a\xaa\x9c\xcf\x09\x2f\x0b\xb8\x06\xd9\x76\x10\x74\x2a\xc5\x82\xa3\xab\xbe\xdd\xf3\x9f\x49\xd2\x29\xd3\x2a\x11\x86\xd0\x21\x51\x8d\x74\x72\x8d\x13\xd9\x62\x63\x5d\x63\xba\xa6\x74\x3b\x12\x6b\xf4\x58\xfa\x2a\xc7\x56\xfb\xf8\x80\x96\xc8\xd3\x34\x0c\x62\x23\x90\x53\x4a\x74\x3f\x18\x64\xd5\x4d\xea\xb5\xe5\x53\x63\x72\xce\x5a\xc9\x37\x62\x28\x74\x14\xea\xe1\x58\xa7\x6b\xf8\x1d\xf5\x41\x7c\xf4\xc0\x47\xbe\x3a\xc1\x47\x5c\x51\x7e\xbd\x3a\xc1\xd1\xd1\xbd\xda\x11\xb3\xf9\x9c\x18\x17\x3e\x03\x0a\xcd\x51\xd2\xb5\xcf\x79\x51\x65\x09\x41\x54\x05\x07\x75\x11\xbd\xd9\xcb\xe1\x7d\x04\xf4\x78\x05\xe9\x8d\x0d\x14\x5e\x60\xa5\xd0\xe0\xf4\x53\xcd\x9b\x5c\x1a\x24\xf1\x2b\x75\xe8\xcc\x34\xd5\xe0\x06\x91\xff\xac\xbf\xf7\x88\xfe\xa8\x34\xd9\xd7\x79\xc1\xe6\x10\x29\x4d\xce\x19\x17\x0d\x28\x16\x0c\xff\x90\x9b\xea\x5a\x0a\xa7\x49\x40\x17\x40\xea\x3a\xf5\x1e\x48\xb2\x7c\x2b\x09\xf0\x25\x44\x42\x76\xc1\x88\xc0\x67\x1a\x6d\xa9\x4b\x43\xd1\xe5\x25\xe6\xa4\xa8\xa1\xa7\x3d\xfe\xdf\x12\x40\x18\x46\xba\x43\x06\x8a\x04\x09\x2b\x12\x91\x22\x70\xd2\xb6\x0d\xf6\x09\x97\x79\x75\x6b\x8b\xbb\x49\xec\xe8\x2d\x55\xf0\xf8\xdb\x1b\x80\xfb\x4b\x59\xbb\xa8\x60\xbd\x18\xc7\x5d\x6c\x83\x4d\x69\x44\x2a\xe0\x31\x4c\xf2\x39\x9f\x53\x92\xa3\xc6\x72\x8c\x63\xe5\xc5\x16\xc4\x22\x2a\xac\x60\xf9\x16\xdd\x63\xd1\xd0\x51\x7e\x8e\xb1\x0b\xd0\xe1\x5e\xb9\x06\x14\xde\xb2\x96\x40\x3a\xd1\x5b\x8c\x12\xb9\xe9\x71\xef\x2f\x01\xe5\x9f\xc3\x5d\x90\xc5\x5a\x8e\x20\xe9\x43\x7d\xd4\x34\xb2\x6d\x5c\x2c\x6e\xc2\xd5\x3a\xce\xc1\x7e\x81\xe4\x78\x31\xdc\x2d\xe8\x21\x83\xd7\x13\xb5\x9a\x4d\x1f\x46\x96\x9d\xdc\xdd\xaf\x27\xf4\x4e\x5a\x31\x1a\xaa\xc3\x9c\x3d\x5a\x97\xbc\x90\xca\xd7\x12\xf4\x6f\x85\xe6\xc8\xfb\xf5\xd5\x8d\x8b\xc3\xec\x27\xd3\x10\xa9\xea\xf2\xc3\x69\xcb\x00\x64\x97\x70\x39\x0a\x3f\x98\x8f\x36\x2e\xfc\x15\x5f\x56\xa1\x46\xa6\x26\x50\x54\x7e\x91\x53\x25\x07\x01\xee\xad\x1b\xd0\x1c\x89\x46\x22\x72\xdf\xaf\x0a\x43\x1a\xf4\xbd\x7c\x3d\xb4\x51\xad\xa6\x03\x23\x3f\xda\xd3\xaa\x89\x99\xaa\x21\xe2\xd3\xa4\x3b\x0b\x56\xfc\x6a\x91\x24\xd3\x35\x98\xb3\x73\x7f\x4e\x5c\xb2\x58\xbe\xda\x75\x6a\xd2\xe1\x7d\x06\x91\xd1\x5d\x41\x6b\xb7\xcb\x07\xec\x8d\x8c\x7a\xf5\xde\x80\xe5\xb9\x39\x4e\x32\x0c\x4c\x6e\x43\xef\xaa\xe6\x84\xad\x00\xf6\xdd\x20\xa8\x75\x0e\x95\x9c\x2f\x04\x20\x6f\xc0\x23\xaa\x19\x0c"}, +{{0x7d,0x01,0x0d,0x76,0x0f,0x24,0xe5,0xa2,0xde,0x34,0x08,0x9c,0x9f,0xdb,0x19,0xc3,0x3b,0x15,0x5b,0x0a,0x37,0xca,0x45,0x5a,0x5e,0x5b,0x1d,0xae,0x7a,0x07,0x31,0x76,},{0x4c,0x87,0x7b,0x3c,0x49,0x71,0xfb,0xb5,0x51,0x16,0x6e,0x21,0x4d,0x1c,0x76,0x24,0xc5,0x22,0x77,0x90,0x3c,0x59,0xa5,0x62,0xa8,0x0b,0x91,0xa8,0x54,0x83,0xfb,0x47,},{0x55,0x70,0x61,0x38,0x79,0xae,0x22,0x77,0x8b,0xd5,0x4f,0x14,0xfb,0x6e,0x8c,0x02,0x56,0xa7,0x1f,0x3d,0x79,0xc3,0xe5,0xcd,0x8e,0x41,0xae,0xa8,0xcf,0x77,0x3e,0x24,0xd2,0x9f,0x1f,0x1b,0x24,0xf8,0xc8,0x0d,0x29,0x49,0xe8,0x20,0x14,0x65,0xdb,0xde,0x89,0x40,0xb1,0xfa,0xb6,0x48,0x3b,0x08,0x5d,0x41,0x8e,0x25,0x10,0x14,0x20,0x0c,},"\x86\xe2\x11\x55\x72\xbf\x4c\x01\x3e\x6b\x4b\x04\xd0\xb0\x3e\x60\x6e\xe7\x0d\x92\x9c\xb8\xec\x36\xf4\xe2\xf3\x55\xdb\x3b\x5e\x15\x73\xd6\x58\xd1\x7b\xb1\xa3\x10\xc1\x69\x89\xa1\x6b\x95\x58\x92\x2e\xe4\x93\xf3\x59\x04\x21\x03\xc4\xdc\x1b\x40\xdf\xf7\x70\x99\x01\xfd\x58\x30\x13\x3f\x42\xc4\x65\x1e\xca\x00\x8b\x49\x9e\xe4\xf8\x4c\xd4\xec\x1e\xda\xa7\x82\x56\xed\xb6\x2f\x24\x02\x1a\x00\x76\x25\x69\x19\xe4\xe2\xce\x0a\x5a\x20\xf9\x21\xc2\x78\xcc\x29\x91\x59\x64\x4b\x5e\x3a\x3b\xbd\x08\x9d\xcb\xbe\xba\xd3\x76\x6a\xea\x77\xe9\xf0\x8e\xe5\xf7\xd4\xc1\x9d\x81\x70\xbc\x3d\xe1\xba\x77\x9a\x76\x99\x14\xf9\x65\xdb\xde\x2b\x61\xba\xd2\x14\xc5\x08\x18\x60\x41\xf7\x6c\x25\xbe\x95\x76\x56\xf5\xcf\xb7\x33\x4e\xb8\x38\xa3\xcf\xbc\x55\xcf\xba\xb6\x7a\xdf\x15\x52\x61\x99\x41\xb8\x35\xcd\x3e\x34\x10\x3b\x18\xb4\x91\x31\xe8\x20\x96\xf0\x5f\x57\x0b\x89\x98\x04\xba\xb8\xb6\xcb\xad\xdb\xbc\x02\xf9\xf3\xb5\x59\x73\x6d\x99\xca\x7b\x02\xd3\x26\x8f\xa2\x73\x99\x6f\xcf\x05\x71\x97\x7d\x1c\xc3\x00\x8c\x4e\xf8\x48\x97\x0e\xe3\x50\xb1\x58\xc4\x7e\xc2\x77\xad\xd4\x74\x2f\xa2\xbc\xbe\xa9\xbd\x55\x49\xc7\xbc\xa0\x38\x02\x0e\xce\x68\xf1\x88\xc1\xea\x3a\x62\xdd\x9a\x07\x3d\x4c\x13\x8c\xa8\xa9\xac\x04\x08\xdc\xfd\x46\xe3\x6b\xdf\xf7\x39\x88\xa5\x8b\x96\x17\xca\xa0\x8b\xd4\x1b\xf3\xe8\x12\xe7\x82\x4f\x0f\x7e\x81\x46\xa4\x44\xf3\x6b\xf5\x3a\x1c\xd8\x92\x03\x9c\xcd\x33\x5f\x5a\x2e\x79\x74\x5e\xac\x96\x14\x8c\x2a\x29\x99\x47\xf1\xb2\xe3\x28\xa3\x78\x9b\xf1\x3c\x6d\x73\x50\x6f\x3b\xdc\x68\xea\x48\xab\xf0\x02\x27\x0f\xe4\xee\x9e\xf9\xed\x6b\x10\xc2\xfb\xb4\xff\x12\x75\xb9\xd7\xdd\x35\xd8\xa5\x2e\x37\x17\x58\x57\x4c\xb4\x66\xc5\x7b\x5a\xbc\x24\x29\x76\xbe\xfc\x8d\x98\xa0\x13\x1b\x9b\xb8\x46\xb2\x19\xe4\x66\x91\x86\xa8\x3c\x05\x6c\xd8\x08\x06\x61\xde\x16\xb5\x1c\xe5\x76\x7b\x22\xe9\xa9\x32\x42\xbf\x8d\x32\x05\xc6\x6a\x67\x3c\xe7\x83\xd1\xc0\xd3\x7b\x63\x00\xfb\xf0\xd6\x12\x79\x40\xf8\x8f\x18\x19\xc4\x50\xdc\xc9\x05\x43\xed\x79\x4f\x1f\xd4\x4e\x65\x39\xfe\xba\xf1\x9a\x4c\xc9\x88\x70\x01\x4d\x7c\xca\xd7\x4d\x18\x76\xa1\x23\xec\xd1\x45\x51\x6c\x74\x3b\x4b\xba\x62\xd8\x21\xca\x9a\x79\x51\xe0\xdf\xb2\x3f\x38\xd9\xe3\xa3\x65\xfd\x83\x22\xf2\xee\x47\x99\xe9\xff\x11\xe1\xc5\xc3\x0b\x55\xa3\x55\xc8\xa5\xde\xea\x81\xa5\x45\xe3\x47\x05\xab\x56\xd1\x7b\x1f\xa0\x6e\xd7\x64\x15\x55\x67\x02\xf3\x64\x80\x82\x46\xf8\x63\xc3\x19\xf7\x5c\xdf\x6b\xd7\x48\x43\x8d\x1a\x2e\xaf\x42\x06\xc5\x60\xbf\xaf\xc2\x35\x67\x9a\xd6\x04\x9c\x1a\x01\x52\x6f\xcb\x9a\x3c\xe1\xb1\xd3\x9b\xe4\xdf\x18\xb1\x5f\xa0\xea\x55\x27\x2b\x17\xeb\xde\xdf\x6c\x30\x49\x8a\x8a\x14\xf2\x04\x2b\xe1\xc2\xcd\xb0\x9e\x9e\xf3\x84\x6d\x66\x59\xa9\xf6\xd6\x73\xdf\x9a\xfb\x7e\xde\xd0\x4b\x79\x3d\x97\x31\xf0\xac\xcc\x41\x46\x8d\xc1\xf3\x23\x6c\x99\xac\xad\xee\x62\x39\xc3\x61\xb8\xbd\x7e\x2d\x0c\xfe\x8b\xb7\xc0\x66\x87\xe0\x8e\x76\xb7\x1a\xd5\x7a\x03\x61\x79\xf2\x91\xd0\x96\xae\x2f\xa0\x81\x8e\xf4\xbf\x48\x66"}, +{{0xaa,0xaa,0xbb,0x7c,0xe4,0xff,0xfe,0x4d,0xc3,0x57,0x47,0xba,0xea,0x2b,0xc5,0xf0,0x50,0xbe,0xf0,0x6e,0xe0,0xc1,0xfd,0x63,0x2a,0x06,0x7f,0xec,0xe1,0xef,0x4f,0xb5,},{0x82,0x0a,0x24,0x42,0xd5,0xf4,0x5f,0x3c,0x79,0x14,0x78,0xe0,0x98,0xfb,0x3b,0x06,0x8d,0xa5,0x2e,0xc4,0xe8,0xda,0xde,0xc8,0x50,0x65,0xc3,0x56,0x59,0xf4,0x37,0xe0,},{0x05,0x0a,0xe8,0xae,0xce,0xec,0x96,0x27,0xb8,0x01,0x37,0x35,0x7a,0x22,0x96,0x2a,0xc8,0xb4,0x50,0x48,0x66,0x17,0x08,0xd3,0x94,0xd0,0xa5,0x1a,0xad,0xc3,0x81,0xfe,0x85,0x35,0x02,0x3d,0x6e,0x1b,0xda,0x0e,0x72,0xb3,0x49,0xb5,0x0b,0x26,0xda,0x7c,0x3a,0x30,0x85,0xe8,0x1e,0x9d,0xd6,0xcf,0x12,0x78,0x68,0xfc,0x5b,0xae,0xab,0x01,},"\xf9\xd2\x85\x97\xa3\xe2\xb6\x4b\xa3\x27\xac\x5c\xd2\x9f\x08\x1e\x74\xbf\x46\x1b\x2e\xb2\xd3\xcf\xd9\xd5\xe9\x21\x58\xd2\x1d\x1d\x2a\x47\xab\x50\x98\x1c\xb1\x9f\xe3\xf8\xc6\xfe\x48\x82\x49\xb1\xc4\x9f\xb8\x97\xa0\xfe\x21\xab\x54\x04\x41\x4f\xd9\x14\x87\x5c\x22\x0f\x1c\xbc\x12\xf5\xc3\x8c\xfb\xa7\x9f\x7a\xc3\x03\xa5\x23\x1a\x37\x2b\x02\xfa\xd6\xc8\x46\x2f\x8c\xc4\x9f\x0f\x64\x96\x5b\x65\x1d\xcc\xef\x0b\xb9\x60\x82\x15\x09\x08\x49\x17\x7b\xe4\x7b\x2d\x30\x72\x94\x4d\x36\xe8\x56\xda\x18\x5c\x7b\x3a\x68\x9f\x7e\xde\xf9\x88\x33\x8e\x09\x63\xed\x31\xa6\xb0\xa8\x0d\x5c\xb0\xb1\xcc\xcf\x6f\x39\x48\x37\xaa\x6f\x8b\x2f\x3d\xa5\xef\xbd\xf4\xd3\x60\xd4\xbf\x4d\xd7\x08\xce\x64\x45\x58\x7d\x94\x2b\x79\x76\x1c\xe9\x51\xb1\xbb\x4d\x90\x50\x70\x36\x18\xa6\xd9\x30\xa8\x0c\x69\x57\x6f\xc4\xaf\x30\x6a\x2a\x56\xdb\xd8\x84\xa0\x5a\x1e\x4e\x9f\x31\x36\xcd\x0b\x55\xae\x47\x4b\xb5\xd3\xd0\xfb\xc9\xb0\x33\x9c\xec\x34\x4f\xdd\x08\x5c\x19\x28\x10\x14\x81\xc6\x87\x94\xf5\xc8\x90\x13\x71\x08\xce\xa7\x91\xd2\x1f\x81\x68\x3d\x3e\x1a\x9e\xec\x66\xac\xe5\xc0\x14\xd8\x9e\x69\x80\x8e\x5f\xa8\x3d\x38\x12\xee\x68\x0f\x5a\x99\x71\x68\x1b\x8a\xdc\xd4\xa1\x6e\x9a\x4c\x16\x5b\x5e\xf9\x93\x2c\x5e\xd8\x25\x23\x7f\xd5\x03\x7b\xcb\xef\xe4\xcb\x11\x56\x4f\xa7\x07\xc8\xa9\x32\x90\x75\x14\x14\x89\x1b\x1e\xdd\x33\x13\xc6\x5f\x8b\x91\xc2\xe9\x25\xa3\xc1\x2a\x9d\x3a\xa4\x5f\xd5\xa6\x67\xb7\x83\x93\xc3\xe3\x9d\xf8\x8a\x8f\x0d\x11\x48\xb5\x31\x1e\x3d\x87\xc4\xa9\x2e\x0a\x3f\xb9\x15\xbc\x90\xd5\x55\x8d\x05\xb4\x75\xa8\x83\x47\x78\xaa\x94\x3e\xa3\x9b\x8e\xaa\x95\xad\x18\x32\xe5\x91\x6e\xa3\x10\x2d\x7d\xe0\xb8\x36\xcd\xe8\xf3\x75\x9d\xbb\x3b\x9d\x56\xea\x81\x7b\x3e\x49\xc9\x83\x21\x02\x77\xc2\xc7\xc5\xb0\xdb\x18\x74\x22\x53\x2f\xca\x98\xa2\x8b\x3b\x65\x9c\x6b\x81\x5a\xc1\x26\xfa\xdb\xe2\xf4\x00\xc7\x3e\x9d\x2d\xed\xcb\xbd\x2d\x3a\x36\x5f\xfa\xd7\xe6\x66\xc8\x96\xe3\x1e\x61\xb3\x84\xed\x3a\x9f\xcf\x12\x90\x53\x8d\xf1\x1b\x94\x74\xc6\x28\x1c\xc5\x92\xc7\x1c\x88\x08\x86\x8b\x42\x92\xc1\x7e\xce\x6b\x3e\xdf\x5e\x35\x42\xa7\x0b\x91\x15\x93\xe9\x3f\x35\xec\xd9\x72\x9b\xd8\x88\x0a\x24\xea\xf4\x1f\xbc\x65\x74\xdf\xe1\x67\xec\x2d\x0e\x7a\xb3\xdf\x5e\xc3\x4b\x8b\x55\xd5\x48\xab\x93\x73\x8a\x2e\xea\xf2\x1c\x88\x4c\x5c\x85\x51\xdb\x2e\xdf\x2b\x04\x9f\x1a\x2a\x84\xfa\x72\xac\x89\x78\xa4\xc2\x78\x09\xf2\x09\xc1\xb2\x19\x5a\xff\x50\x4f\x69\x98\x56\xcc\x4f\x22\xd4\x4e\xbd\xd0\xfe\x50\x37\x44\x68\xd0\xb1\x79\x2e\x57\x4b\x51\x10\xa1\xf4\xcd\x0e\x22\x1e\x82\x4a\x78\xdd\xc4\x84\x5f\xeb\x46\xd6\x6d\x63\x3d\x23\xcd\x23\xf4\xb6\xfb\xe4\xc8\xce\x16\xcd\x1a\xf6\x15\x36\xda\x5f\xa6\x7b\x10\xac\x75\x55\xa6\x8c\x0e\x0b\xdb\xf2\xf8\xd7\x23\x09\xd9\x95\x51\x6b\x81\x18\xbf\x43\x83\x5d\x0a\x01\xc0\x8f\xfe\xba\x3e\xa3\xed\x05\xcd\x2d\x54\xf0\xea\xbc\xda\x05\xd0\x03\x7d\x52\xca\xed\x3b\x19\x37\x4f\xaf\x73\x99\x90\x94\xf7\x90\x55\x92\x4b\xea\x9a\xec\x44\x70\x13\x5f\x5e\x8b\xf1\x83\xc9\xd1\xc9"}, +{{0xe9,0x5c,0xc2,0xa4,0xd1,0x19,0x3b,0x75,0x39,0xfc,0xbb,0xea,0xae,0xed,0x98,0x5b,0x6f,0xb9,0x02,0xdd,0x0e,0xfb,0xd6,0x38,0x74,0x57,0x55,0x0d,0x0d,0x6a,0x2f,0xea,},{0x72,0xa1,0xff,0x1e,0x9b,0xb1,0x1c,0x8d,0x88,0x96,0x8a,0x7b,0x16,0x96,0x37,0xad,0xee,0x43,0x8e,0x22,0x63,0xf0,0x06,0xdc,0xa4,0xfe,0x02,0xfe,0x06,0x6c,0xba,0xd3,},{0x1b,0x8d,0x7c,0xc2,0xad,0xf3,0x6c,0xae,0x16,0x31,0x25,0x0c,0x82,0x43,0x1b,0xd8,0x84,0x37,0x16,0x3a,0x63,0x49,0xad,0x96,0xe7,0xa8,0x64,0x44,0x7e,0x9f,0xee,0x75,0x3a,0xc3,0x65,0x5c,0x98,0x35,0xb4,0xd1,0xec,0xbb,0x30,0x6c,0x63,0x8b,0xa5,0x40,0x2a,0xd0,0x2b,0xa6,0xd2,0x25,0xd9,0x68,0x82,0x88,0x9f,0xe8,0xd2,0x04,0xa6,0x04,},"\x84\x26\x74\x39\x20\x1b\x05\x91\xdb\x60\xc0\xf1\x7a\x9c\x15\xe4\x54\x09\x29\x56\x52\xd5\xf5\x5b\x87\xfb\x35\x19\x67\xc8\x46\xa5\x67\xf5\xce\xba\xae\xd1\x76\x2b\xff\x54\x85\xf0\x48\x53\xca\x92\x69\xf4\x64\x09\x4e\x51\x2d\xf1\xf0\x2e\x13\xe5\x17\xb1\xda\xa5\x8d\x34\xca\xa2\xd5\xff\x9f\x9e\x79\xbc\xaf\xb4\xce\x96\xe8\xa0\x89\x25\x8a\xd6\x13\x43\xb4\x46\x62\x8e\xbc\x4f\x5b\x2a\x84\xd0\x3b\x72\xef\x3f\x73\x85\x89\xfa\x13\xc4\x25\x19\xa8\x28\x29\x9a\x3f\xae\xc0\x35\x03\x7b\xc1\x0b\x44\xe3\xbd\xfe\xd9\xe0\x87\x07\x17\xcb\xaf\x31\xbe\xf8\xb2\x2c\x4e\xa1\x6e\x81\x57\xfc\xbc\x63\xee\xfa\x39\xed\x82\x2e\xfd\x42\x15\xc2\x47\xdd\xa4\x87\x86\x27\x7e\xc0\x30\xa8\x6c\x0e\xf4\x85\x1d\x67\x3c\xfe\x75\x2d\x06\x77\x88\x3c\x2c\x45\x20\x38\x97\x0c\x09\xbd\x48\x17\x14\xbc\x3f\xbe\xcf\xa4\xff\x2a\x3c\x24\x56\x95\xd7\xec\xc2\xf4\xde\xc7\xf5\xed\xe0\x4f\xf6\xdb\x43\xe2\xbb\x91\xc0\x66\xb6\x49\xef\x73\xfd\x3b\xe8\x60\xcb\x83\xfa\x80\xb0\x74\x14\x9f\x43\x1e\xeb\xb9\x17\xec\x84\x78\xda\x87\x0c\x11\xe3\x17\x70\x38\x59\xf9\xf2\xf4\x00\x8a\x6c\x7c\x75\x4b\x06\xe1\xf7\xd2\x47\x96\x89\xda\x84\xe8\x89\x22\xf3\x82\x74\x98\x5e\x11\xce\x13\xcd\xbd\xb0\xf2\xec\xe6\x8f\xb6\x02\xad\xe0\x3d\xd5\x49\xa3\x62\x49\x1f\x4a\x20\x3f\xf8\x07\x44\xf6\x63\xc5\x23\xa0\x26\xb4\x31\xaa\xd4\x5c\x58\x29\xe0\x29\xad\x62\x56\xd1\x27\x6f\xd7\xb7\xa1\x2d\xdb\xf1\x72\x7d\x9e\x23\x3f\xb5\x34\x45\x73\x70\xa4\x26\xe5\x6f\xb3\x9c\xf4\x04\xa3\xec\xbf\x0c\x4b\x50\xbb\x52\x2d\xce\x98\x1e\x08\x30\xfd\x84\x06\xe6\xd9\x72\x5c\xeb\x1d\xdd\x3a\x19\x47\x93\x7d\x90\xe0\x4d\x76\x8a\xe1\xd1\x26\xe2\xae\xac\x21\xb8\xc9\xef\xc5\x4c\x40\x96\x1b\x7f\x4e\x9e\x88\x02\x5f\x7e\x0b\x9d\xe9\x01\xeb\xf0\x04\x9e\x74\x1b\x79\x79\x97\xd8\xdb\x78\xe9\x28\x3b\xbb\x5f\x90\xf3\x5a\x2c\x4d\xee\x27\x31\x42\xec\x25\x8c\x02\xad\x0e\xcc\x61\xcc\x5c\x9f\x12\x13\x2d\xb2\x8a\xf4\x1c\x1f\xb7\x8e\x52\x4b\xe5\x32\x7b\x5f\xfc\x35\x96\x27\x79\xfb\x11\xff\x0c\x5d\x3e\xe0\xa3\x1f\xf4\x7e\x73\xb1\x72\x9d\xfa\x46\xe8\x98\x6b\x1b\x89\xab\xc8\x8a\xd0\x6a\xbd\x5b\x6f\x76\x6d\x23\xab\xf6\x42\x25\x78\x94\xeb\xdf\xa7\x9e\x63\x09\xf1\x27\x23\x74\xee\x94\x33\x67\x7b\xa1\x3e\x45\x1b\xaa\x95\x33\x0e\x66\x0c\x80\x52\xae\x87\x2e\x0e\x32\xe2\xb2\xd1\x28\x6d\x01\xa0\xab\x58\x10\x42\x4e\xd8\xb9\x40\x54\x65\xbd\xeb\xa0\x3b\x69\x83\x84\x67\x6f\xe5\xea\x46\x4a\x03\x44\x6c\x4f\x7c\xd7\xb4\x33\x12\xec\xf1\x51\x36\x04\x64\x57\x1a\xd2\x86\x10\x58\x1f\xba\xdb\x94\x5a\x1d\x68\x18\x1d\xeb\x40\x3a\xa5\x6e\xba\x0b\xb8\x40\x32\x8e\xee\x36\x10\x3c\x7d\xe0\x73\xa6\x87\x9c\x94\x1c\x75\x54\xc6\xf6\xf2\xa0\x80\x80\x9e\xb0\xe5\xbd\x0e\x13\x0f\x29\xa2\x29\xe9\x30\xdb\x01\xfe\xca\xc2\xe0\x36\xbd\xf0\xe0\x01\xe2\xa8\xea\x32\x64\xf8\x64\x9d\x5b\x60\xc2\x91\x03\xf0\xb4\x9c\x24\xc9\x7f\xac\xaf\x7e\x81\x06\x9a\x2b\x26\xab\x3f\x93\x3f\x42\x7d\x81\x27\x2c\x6c\x8b\x7c\xd0\xdf\xb7\xc6\xbb\xe9\xc0\xea\xab\x32\xbb\xda\x22\x18\xb9\x62\x3a\x21\x19\xaa\xb1\xf3\xeb"}, +{{0x77,0xad,0x0f,0x94,0x2c,0x37,0xf0,0x31,0x3e,0x6b,0x04,0x56,0xda,0xba,0xec,0x81,0xb2,0xd6,0x1f,0x6c,0x11,0x8d,0xdb,0x29,0xea,0xf3,0xac,0x5b,0xf1,0x95,0x04,0xd4,},{0x69,0x2d,0x2d,0xa5,0xa9,0x5f,0x48,0x61,0x1a,0x6d,0xa8,0x9c,0xfb,0x3b,0x35,0x40,0xf6,0xaa,0x0c,0x85,0x0d,0x6d,0x98,0xde,0xea,0x87,0x0e,0x39,0x7f,0xed,0xe3,0x28,},{0x69,0x6b,0xd5,0x52,0xdd,0x01,0xdb,0x80,0xb3,0xd6,0x7d,0x61,0xee,0xb7,0xec,0xc5,0x68,0x78,0x40,0x4a,0xb1,0x19,0x44,0x2a,0x1c,0x74,0x22,0x99,0x2c,0xfa,0x35,0xae,0xa9,0x20,0x82,0x5d,0x2d,0xaf,0xd8,0x92,0xad,0x7e,0xb6,0x82,0x5a,0xd9,0x99,0xae,0xe5,0xc8,0x3b,0x7b,0x50,0x79,0x06,0x53,0x4f,0x91,0xac,0xe7,0x59,0xc5,0x51,0x0c,},"\x87\xe6\xde\xad\x2c\x85\x54\x9e\x3d\x8d\x25\x88\xa0\xa3\x36\x06\x03\xa6\x24\xfb\x65\xae\xbb\xc1\x01\xbf\x7f\x1f\xec\x18\xd0\xb2\x8f\xbd\x5d\xba\xee\xd3\x87\x52\xcd\xf6\x35\x5c\xe8\xdc\x84\xe1\x8a\xc1\xa4\x39\x3d\x2a\xb8\x88\x88\x2c\x4f\xf1\xc9\xc8\x13\x7f\x83\xbe\xe3\x63\x36\xbc\xbf\xbb\x72\xd5\x04\x9e\x0a\x40\x08\x74\x51\x4f\xdc\x36\x33\x04\x6e\x89\x38\x3d\xde\xd9\x3c\xa3\x1f\xde\x0d\x89\x8e\x11\xe9\x26\x8d\x3d\x5c\x24\x06\x66\xed\x55\x27\x61\x3d\xa7\x9f\xb7\xe4\x96\x25\xb4\x4c\xde\x78\xb4\x1c\x67\x90\x2e\xb0\x21\x6b\x3a\x7a\x3e\x56\x0e\x26\x1d\x71\xd7\x64\xaa\xcf\x15\x95\x9c\x17\xfc\xd6\x17\x6f\xb2\x5e\x24\x9e\xe6\xbb\x1b\x3b\xd7\xbd\x90\xf6\x0b\x0b\x0f\xfa\x03\x15\xa0\x65\xa2\x4b\xba\xe8\xf2\x55\xbf\x29\x8d\x7e\x4d\x44\xf0\xb4\x30\xc4\x15\xb4\xfb\x36\xcf\xa6\x62\x6a\x83\xf4\x9a\x25\x67\xf6\x24\x4f\x40\xe9\x23\xad\xd1\xd4\x9a\x72\xf5\x7b\x15\x30\xf5\xb3\x79\xde\x3a\x91\xc2\xe9\xa1\xac\x79\xab\x37\xbc\x3b\x9b\xa7\x3d\x88\x28\x13\x6b\xcc\x87\xd2\xc0\x11\x90\xde\x54\x57\xfa\xcd\x90\xf3\x69\x55\x3f\x7a\xc5\x21\xc5\x67\x2b\x08\x67\xdf\xa8\xda\x3b\x95\x2a\xd9\x5b\x67\xda\xb9\x9b\x48\x20\x57\x2f\x2d\x4a\x29\x8e\x95\x18\x63\x77\x79\x28\x9c\x03\x1b\x79\x3d\xee\x85\x9c\xde\x7b\x24\xad\xd6\x49\xff\xf8\x71\x24\x8a\x66\x02\xd2\x51\x62\x79\xda\x60\x58\xcb\xb6\x96\xfa\x8b\x1d\x89\xa2\x0d\x20\x99\xe6\x46\x44\x32\x10\x48\x3e\x5d\x41\x34\xe9\x28\xfa\xeb\x38\xa3\xb5\x08\x19\x9e\x0d\x69\xbb\x55\xee\x34\x77\x42\x05\xc0\xa6\x12\x05\xb5\x0b\x08\xfe\xbe\xaa\x40\x1e\x6e\x3a\x51\xa2\xbf\x98\xef\xac\x78\xb7\xae\x2b\x85\x2c\x53\x95\xa1\x2c\x40\xe2\xc7\xdd\x1b\x20\x25\x04\xb5\xa7\xd2\xf7\xe4\xfd\x4f\x86\x10\x93\x0d\x28\x68\xcb\xa8\x86\x43\x39\xe0\x41\xda\x21\xc0\x71\x5f\x41\xb2\xb2\x3d\x14\xd0\xb5\x45\x48\x0b\xc3\xbd\x7d\x72\x15\xcf\x2f\x81\x6a\x33\x32\x08\x1e\xca\xa0\x8c\x0f\x8b\x99\x52\x52\x51\xf5\x72\x31\xb6\x75\x0c\x2d\xbd\x11\x09\xac\x41\x60\x48\x6b\x76\x83\x24\xb6\xba\xc8\x7e\xf5\xa2\x26\x44\x8c\x43\x12\x40\x32\x8f\x42\xcc\xa5\x86\xbe\x7a\xff\x3c\xbe\x76\x05\xfa\x34\x15\x14\xfc\xcf\xb9\x66\xaf\x3d\x45\x30\xe8\xcd\x90\x37\xa1\x1c\xe5\x93\xc2\xd3\x83\xe1\x03\x5a\x0c\x2e\xda\x09\x8d\xe9\x0d\x50\xc5\x18\x4a\x9c\x01\xb5\x7f\x26\xb9\x4d\xed\xd1\x45\x4c\x34\x06\x37\xec\xcc\xee\x70\x62\x57\x54\xa3\x28\xc6\x5f\x42\x64\x5b\x5e\x1a\x56\x55\xee\xf9\x7d\xfb\x1c\x63\x08\xed\xf4\x9f\xa3\x68\xd1\x7d\x17\xe0\x6a\xdc\x51\x2b\x39\x73\xea\x65\x2a\xc4\x0a\x99\x78\xe1\xbb\x1b\x2f\x86\xc5\xa9\xff\xbf\x60\xdc\xc4\xf6\xbb\xc9\x8a\x64\xf4\xde\x65\xe7\xec\x61\x72\x1e\xde\xb0\xe5\x23\x84\x56\xf7\x61\xd2\xd1\x29\x3a\xf0\xde\x9f\x79\x3b\x11\xd8\xca\xdf\x01\xa9\x43\x19\xa0\x2a\x42\x73\xff\xc4\xd3\xff\xa7\xb3\x4d\x74\xfd\x2e\x0b\x10\x0f\xca\x58\xb5\x32\x5f\x90\x7a\x74\x91\x93\xe7\x51\xd6\xc1\x16\x68\x7a\xee\x37\x47\xb5\x94\x60\xd4\xef\x15\x6e\x72\x47\x6e\xae\x1b\x84\x55\xd7\x6e\x71\xb3\x06\xb9\x81\x29\xb7\x2f\xe1\xcb\x5e\xb4\x05\xa7\xc2\xf4\x32\x7f\x38\x62\xd4"}, +{{0x29,0x32,0x14,0x69,0xee,0x9f,0x2b,0xb1,0x65,0xa0,0x69,0x64,0x03,0x32,0xb4,0x89,0xbf,0x5c,0x3f,0xab,0x68,0x2e,0x93,0xda,0xe9,0xd8,0x63,0x17,0xbf,0x50,0xc5,0x2c,},{0x96,0xf7,0x30,0xf8,0xef,0x89,0x70,0x26,0x8d,0xba,0x0f,0x75,0x70,0x41,0x0b,0x61,0x88,0xa1,0xa3,0xc8,0x63,0x97,0x74,0x09,0x13,0xd5,0x3a,0xda,0x26,0x2a,0xb8,0x7e,},{0x4e,0x1a,0xff,0x84,0x63,0xbc,0xa1,0xb7,0xde,0xb1,0xd3,0x77,0x3d,0xf2,0xe7,0xa0,0x68,0x64,0x11,0x1b,0x6d,0xc4,0x2a,0x62,0xae,0x98,0xde,0xb2,0x31,0x39,0x43,0xb3,0x15,0x3e,0xe4,0x66,0x96,0xb1,0x5c,0x24,0xef,0xc2,0xa8,0x08,0xaa,0xba,0x81,0xc7,0x8e,0x3d,0xfa,0x4d,0xfb,0x50,0xca,0x9f,0xe8,0x44,0x45,0xea,0x68,0xbc,0x8e,0x0a,},"\x9c\x71\x2c\x83\xd5\x4f\x2e\x99\x3c\xa6\x8a\x96\x32\x84\x60\x04\x49\x9c\x51\x95\x44\x8d\xdc\x49\x1c\x3a\x0d\x2e\x3a\x66\x6d\x6b\x33\x09\x8e\x48\x64\xfd\xf8\x6e\x61\x9d\x50\xf1\x0b\x7c\xc6\xc3\x9b\x3f\xf2\x80\x1a\x94\x91\xf6\xfa\x97\xc5\xf1\xc4\xaf\xa7\xae\xff\x31\xd7\x38\xf9\xa7\x68\xa7\x9c\x73\xb2\x55\x77\x31\x0f\xb0\xad\x4f\xaf\x85\x43\xa0\x98\xf8\x59\x57\x1b\x61\x48\xe8\xb5\x29\x26\x44\x57\x57\xd5\x54\x9f\xd2\x5a\x26\x51\x85\x31\x56\x63\x79\xd1\xc2\x74\xe6\xc6\xa9\xd6\x41\x32\xe4\xac\x25\xac\x9a\xf9\x38\x1b\xcb\x88\x53\x32\x11\x3f\x43\x01\x4a\x13\x9a\x81\xf8\xd4\x3c\x8a\x6a\xb5\x4c\x11\xa5\xc9\x2e\x06\x19\x1c\x1e\x51\xb7\x57\xac\x9f\x11\xe3\xdc\x15\xdb\x44\x86\xd1\x67\xff\x9f\x2d\x65\xe2\x3e\x6c\x96\x22\x3d\x9a\xff\x8d\x10\xd1\x50\x2c\xf3\xdb\xce\x5e\x35\x7e\x6b\x12\xdb\xe9\xb7\xe9\x97\xc3\xd0\xa5\x07\xd3\xba\xe3\xcf\xef\x1f\xfc\x8d\x05\x6e\xf7\xdc\x72\xdd\xc1\xc8\x1e\x31\x0a\xd2\x05\xbe\x16\xe7\x7f\x27\x38\x35\x4b\x10\xb4\x84\xd3\x07\x6c\x27\xe6\xb4\xf1\x66\x38\x85\x81\xf3\x50\xbe\xfe\x22\xfb\xb0\x82\xb5\x41\x21\xee\x59\xec\xc7\xae\x5d\xec\xe8\x98\x82\xac\xf2\x6c\xb7\x47\xff\xaa\x3e\x2d\x05\xa6\x96\xf6\x0f\xd9\xe8\x29\xc7\x09\xd8\xf0\x2d\xaf\x53\x7b\x23\x69\xb8\x91\xfe\x6c\xcb\xf8\xdf\xcd\xd7\xf4\xa3\x64\xb1\x99\x85\xbe\x7e\xde\xc6\x7d\xdc\x1d\xb7\x13\xc0\xa9\x0f\xaf\xa4\x88\x37\x77\x25\x62\xde\xac\xc2\xd2\xa0\xe7\x89\xe1\x8a\x8b\x5b\x3b\xd9\xe0\x83\xea\x92\xff\xfc\x31\x83\xd5\xd4\x14\x15\x32\x59\xb3\x3a\x43\x29\xcf\xc8\x08\x24\xeb\xcb\xe0\x44\xa7\xe3\x3a\xb8\xa2\x4f\xde\x54\xbd\x95\x20\xae\xa2\x84\xb0\xc4\xc4\xfa\x94\x27\xd2\x51\xc0\xdd\xd0\x13\xec\xdd\x82\x90\xef\x55\x65\xf6\x08\x50\x8e\x36\x35\x89\xe5\x29\xd8\x4f\xf0\xf2\x6f\x9e\xcb\x03\x05\x2d\x58\x97\xfa\xbc\x91\x7e\x56\xe6\x01\xb6\x4a\xbf\xe5\xa1\x7c\x39\x50\x28\x9d\x0c\xdc\xaf\x1f\x60\x05\xa9\xf8\x10\x6f\x43\xe1\x7a\xdc\xaa\x2d\x1e\x26\x91\x66\x76\x2f\x80\x54\xde\x05\x13\x5d\x5d\x13\x93\xd7\x00\x0a\x15\xb8\x7b\xd6\x88\x46\xa8\x9d\x5b\xc2\x28\x63\x32\x51\x51\xaa\xc8\x43\xf7\x22\x78\xae\x6f\x4a\xf7\x2a\x4e\x44\x9a\xdb\x7e\xae\x6d\x43\x6a\x1e\xc7\xe5\x8e\x59\xb7\xb8\xbb\x9e\xf0\xdd\xaa\xa0\x01\x82\x6f\x8d\xcb\x44\x64\x79\xde\xaf\xd8\xb8\xd5\x42\x04\x1c\x19\xa0\x5b\x1e\x0e\xe4\x7b\x46\x40\x91\x0c\x31\x93\x0c\xa4\xe2\x0b\x10\x57\x58\xec\x75\xf1\x95\x03\x56\x94\x7f\x62\x61\xd0\x03\x7f\xe3\x07\x73\xa3\xec\xe6\xa9\x6c\x8d\x54\x33\x33\x3d\x82\x2c\x27\x77\xef\x7f\xf8\xbe\x60\x33\x34\x5b\x50\x55\xd5\x8f\x5e\xb3\x72\x9a\xf5\xae\x88\x24\xf3\x31\xee\x07\x31\xc8\x9b\x20\xac\x11\x8f\x55\x04\x27\xcd\x95\x8a\x55\xf6\xb1\xa2\x88\x8a\x08\x7b\xb7\xdb\x55\xbf\xc7\x3b\x29\x42\x9b\x44\x48\xdb\xe9\x11\x9c\x45\xa8\x73\x39\xb4\x49\x7a\x69\xa4\xcf\x83\x3e\x8f\x37\x70\xcc\xe5\xe0\x1f\xaf\x5e\x73\xbb\xaf\x62\x76\x83\xc0\xa2\x8c\x73\x05\x2f\xbe\xce\x20\x30\x43\x38\x9d\xfb\xfd\x45\x49\x5e\x51\xda\xb8\x6a\x25\x2e\x5b\xc1\xb4\xb7\xfe\x28\x07\xe3\xd0\xe2\x36\x3b\xea\xb5\x1c\x67\xfb\x31"}, +{{0x04,0x65,0x77,0x50,0x49,0x7e,0x68,0x15,0x2c,0x43,0xce,0x34,0xa5,0x8d,0x21,0x06,0xe6,0x4c,0x55,0x7c,0xd7,0xa8,0x4e,0xf0,0x5d,0x9e,0xb8,0x2e,0x6b,0xcb,0x05,0xf5,},{0x3b,0x3a,0x19,0x47,0xb4,0xcb,0xf6,0x0b,0x82,0x6d,0x60,0x9f,0x19,0x2d,0xc2,0x30,0xaa,0x9b,0x9b,0xaf,0x4c,0xd6,0xa6,0x09,0x2e,0x49,0x5f,0x1d,0x2e,0x47,0xad,0x62,},{0x7e,0x2e,0xae,0x5a,0x29,0x3f,0x41,0x83,0x91,0xf6,0xd8,0x5a,0x79,0x94,0xb0,0x7c,0x45,0x22,0x80,0x01,0x7e,0xe6,0x53,0xbf,0x61,0x7a,0x8d,0x5b,0xe2,0x4c,0xbb,0x5d,0x0e,0xfd,0xfb,0x7f,0x7f,0x00,0x13,0x12,0x26,0x0f,0x34,0x4e,0x6f,0xb9,0x15,0xad,0x8d,0x7d,0xe9,0xc0,0x51,0x98,0x27,0xc0,0x57,0x26,0xf9,0xce,0x25,0x45,0xdd,0x0b,},"\x29\x48\x22\x7a\x89\x0f\x6f\x84\x5b\x77\x5e\x62\xc5\x3a\xf3\x80\x50\x64\xa1\x57\x64\x46\xf0\x85\xd9\x0f\x8b\x9a\x5e\xd6\x8d\xf1\xea\x39\x3c\xe4\x79\xc4\x41\x41\x49\xa9\xec\x5a\x17\x10\x36\x42\x4d\xff\x03\x44\xb4\x95\x8f\x61\x32\x29\x8d\x0e\x24\xc9\x26\xd2\x8a\xd9\xd7\x9f\x98\xc6\xe6\xbc\xf1\xc5\x76\x76\x06\xec\xd2\x91\xc6\xad\x47\xb4\xf9\xfb\x2b\x02\x01\x15\x5a\xda\x62\x7b\x7a\x1f\xd5\xb0\x74\x19\x87\x40\x83\x05\x9e\xb5\x2b\x2f\x6e\xc2\x28\x18\xb7\x82\x46\x22\x8f\x3f\xe6\x35\x5d\xfd\xa7\x0e\xbb\x9b\xbe\x73\x22\x93\x78\x73\x63\x99\x55\x7c\xe2\x4b\x30\xbf\x64\x5a\x14\xe2\x25\x6f\x70\x01\x9b\x33\x36\xb2\x03\xfb\x77\xc6\xec\x94\xa7\xa2\x63\x48\x88\xfe\xea\xd4\xd7\x2c\x23\x91\xe9\x9e\x8c\x8d\x53\x3f\xd8\xa4\x2b\x08\xc1\x1f\x88\x7a\xb2\xde\xb6\xeb\xbf\xe3\xd2\x51\xde\x63\x53\x6c\x36\xcd\x53\x42\x23\x98\xe5\x44\xcf\xf8\x7b\x07\xa6\x33\x49\xfc\x50\x85\xdd\xe9\x3a\x1b\xfd\x71\x71\x13\x3a\x20\x43\x98\x1f\x60\x75\x22\xc8\x13\x3c\x63\x42\x8d\x1b\x92\x62\x6c\x79\xb7\x35\x8e\x70\x21\xcf\x1f\x41\x2a\x78\xaf\xa7\xcb\x3f\x59\xff\xef\x92\x79\x88\x5a\x5b\xdb\x24\x66\xac\xd3\x4c\xd5\x15\x80\x83\x0b\x83\x51\xeb\xd4\x40\xa9\x66\x23\x90\x7a\xd1\xf4\xb5\x62\x03\xf5\xe1\x59\xa4\x29\xe3\x54\x6e\xad\x0c\x01\x1d\xbe\xd0\x90\x28\x71\x7e\x3c\x3d\xfe\xd3\x91\x97\x76\x4d\x4d\x24\x5e\xf2\x28\xb9\x80\x44\x71\x8e\xf4\xd8\x82\x2f\x21\xb2\xc5\x68\x50\x38\x47\x3b\xf9\x3d\xc0\x93\x74\x51\xeb\x02\xd3\x1a\x46\xc8\xdc\x7e\x94\xc3\xe8\x67\x8c\x83\xb9\x8a\x43\x81\x8f\x12\x5b\x52\x8b\x47\x6a\xad\x31\xd1\x58\x4f\xfd\x48\xf1\x49\xe5\x73\x6e\x58\xf9\x42\x05\xd3\x88\x9e\x56\x7e\x4d\xd1\xea\xc2\xfa\xc1\xf8\xf4\xdc\x54\x0e\x53\x22\x46\x0f\xb9\x40\xe1\x2e\x93\xc4\xc9\x8d\xed\x19\x41\xc1\x90\x4f\x96\x7f\xb4\x64\x36\x84\xc1\x9a\x4d\x5c\x44\x1d\x60\xb0\xe9\xf4\x08\x55\xe5\x23\xfe\x7f\x99\x10\x76\x57\xa6\x80\x76\x27\x5b\xf8\x4b\x7c\x69\xa3\xf2\xb3\x85\x5b\xc8\x02\x6b\xa9\xb0\x0b\xc6\xfe\x34\xb9\x9d\xa0\x63\x17\x00\xa6\x7f\x52\xb3\x4e\x17\x96\x33\x98\x87\xa4\x83\x05\x12\x1d\x53\xab\x44\x40\xfc\x4b\x5c\x9b\xf7\x23\x94\xd5\xed\x37\x2f\xf1\x8c\xa3\xf0\x07\xbd\x02\xdf\x65\x1d\xc3\xac\x43\x82\x75\xf1\xa3\xe5\x24\x22\xb8\x6c\x45\x86\x76\x6a\x21\xcd\x89\xf8\x05\x80\x5d\xbb\x44\xfd\x89\xfe\x24\xfb\x2c\x0b\x40\xd1\xb7\x54\xc3\x35\xdb\xaf\xfc\x3b\x3b\xb8\xbb\x46\xc7\x4c\x36\x37\x45\x04\x04\x2d\x86\x78\x92\x27\x59\x98\x62\x31\x2e\x99\xca\x89\xeb\x50\x4c\xc3\xd7\x5d\x19\x49\x5a\xa8\x6b\x20\xb2\x73\x6b\x12\x1b\xb2\x07\x5c\x88\xed\x4a\x3f\xbd\xaa\x6b\x2c\x3f\x76\xd1\xff\x55\x25\xd3\xa2\x86\x3e\x4d\x83\xc7\x2b\xfe\x01\xe1\x02\x78\x80\x94\x74\xe1\x82\x2d\xe2\xd9\x62\x83\x48\x93\x20\x02\x96\x11\xaa\x9d\xff\xc4\x82\x9d\x66\x86\x9e\x63\x49\x4f\x9a\xad\xe7\x0b\x77\xa7\xb8\x0f\xbc\x93\xe3\xde\x4d\x93\x59\x13\x75\x2d\x04\x5e\x13\xb3\x12\xc5\xd0\x82\xf6\x24\x2d\x49\x85\xb0\x53\xb3\x78\x3e\xb0\x2c\x66\x14\x96\x3d\xc0\xd5\x5d\x4c\xbe\x88\x7b\xae\x29\xcc\x18\x97\x9e\x5e\x2e\xa9\x45\xbc\xd4\x0d\x89"}, +{{0x8b,0xd9,0x90,0x70,0xc5,0x0a,0x9f,0xa4,0x18,0xef,0x7f,0x75,0xc0,0x01,0x29,0x91,0x6a,0x41,0xc8,0x60,0x70,0x96,0x1c,0xcb,0x2b,0x20,0x2b,0xe1,0x8c,0x2d,0x10,0xd7,},{0xdd,0xd7,0x33,0x08,0xfc,0xe8,0xca,0x65,0x52,0xd0,0x39,0x42,0x8c,0x7a,0x1a,0x94,0x92,0x33,0x20,0xa3,0x1c,0x0f,0x58,0x0d,0x3c,0x23,0x52,0x80,0xf0,0x3c,0x18,0x30,},{0xb1,0x4a,0x7b,0x26,0x20,0x12,0xc5,0x90,0x9e,0x21,0xd5,0x87,0xfb,0x4f,0x29,0xa9,0x09,0x3c,0x8e,0x1c,0x29,0x99,0x81,0x6a,0x82,0x11,0x8f,0xef,0xbf,0x10,0xe6,0x8e,0xa8,0x98,0xbf,0x0d,0xa1,0x8e,0xbf,0xd0,0x34,0x1e,0xa8,0xf8,0x2a,0x18,0x44,0xc8,0xe0,0xdd,0x53,0x06,0xe5,0x09,0xb9,0xd0,0xc3,0x5b,0x47,0x3a,0x7d,0x20,0x95,0x07,},"\x48\x5f\x8d\x68\x0f\x79\xee\x2d\x82\x8b\xe7\xd0\x18\xa6\x5e\x0b\x64\xb0\xf0\x18\x48\x19\x86\x3e\x71\x10\xee\xa8\xf2\x99\xa7\x2c\x4d\xc8\x7f\x8e\xe8\xa8\xae\xaa\x81\xaf\x91\xdc\x71\xad\xea\x79\xfc\x97\x97\x42\x1c\xcc\x64\x6e\x6c\xd5\xdd\x48\xb4\xde\xc1\xde\x96\x86\x93\xfb\xce\x0d\x00\x21\xa3\xd9\x8d\x38\xa8\xbb\xc5\x81\x95\xe6\xdf\xc3\xb5\xe1\x46\x1b\x2a\x59\x41\x03\xe8\x0a\x29\x44\x1d\x5a\xaa\xf8\x89\xe3\x1c\xc8\x65\x14\x1f\x0c\x6b\x2c\x8c\x81\xf7\x21\x67\x9e\xa2\x39\x4e\xc6\xe4\x08\x1e\xc2\x03\xc2\xea\x39\x7d\x94\x84\x75\x7a\x7a\x0e\xcd\x53\xe6\x52\xdb\x9d\xf1\x7b\xea\x0e\x32\xfe\x8b\x2c\xbc\xe0\xd1\xd9\x7b\x96\x1e\xd7\x4e\x8e\x62\x2b\xcd\xd3\x55\x8b\x7c\x48\x69\x5a\xdf\x18\xaa\xe6\x11\x0e\xa9\xa3\x39\xb9\xda\x40\x7a\x9e\xda\xf2\xab\x08\x1a\x68\x1e\x18\x32\xcc\x21\x5b\x1f\x08\xa6\x7d\x55\x9a\x47\x44\xaf\x7c\xd5\x03\x18\xc2\x06\xee\x91\x15\x75\x82\xf8\x2e\xb6\xc0\xfc\x29\x02\x7b\x44\x61\xc3\x07\x33\xb8\x16\x9d\x14\x81\x32\x2c\x48\x60\x50\x9b\xa0\x96\xba\xcb\x71\xa5\x79\x24\x67\x51\xd5\x67\x54\x0e\x41\x43\x1e\x14\xf1\xb4\x6e\xf1\x6e\xba\x27\x61\x04\xbc\x01\x65\x0d\x5c\x49\x26\xe4\x7c\x9c\x60\x40\x78\x4b\x04\x3c\xd0\xaa\x48\x54\xef\xe8\x79\x7f\xd0\x46\x2d\x45\x39\xf3\x80\x35\xae\xf0\x8b\x45\x77\xc1\xa9\x11\x8d\x00\x4b\x6d\x01\x86\x2f\x52\x76\x77\x6d\xfe\xf1\x37\x18\x64\xf1\x55\xac\x0f\x07\x83\x89\xc2\x05\xcf\x05\x38\xd8\x5f\xa3\x48\x24\x4d\x7a\x42\x29\x11\x31\x0f\xf6\xc1\x01\x32\xb1\x59\x8b\xb4\x45\xc7\xe2\x07\x7b\x76\x3c\x47\x3d\x1e\x7a\x61\xa3\x8b\x64\x92\x9a\x64\x8b\x60\xb2\xe5\x43\x54\x37\x39\x22\x4b\x40\xfb\xf6\xd8\x7f\x10\x79\xc3\x0b\xc8\x73\xac\x38\x99\x1d\x51\xb8\x9e\x9d\x26\x1c\x4b\xcc\xb3\x75\x35\x5c\x07\x2c\x1e\xa2\x0e\x4f\xf9\x1d\x55\xd9\xf7\x54\x4e\x90\xd1\xc6\x64\x6c\x59\xaf\x72\x42\x4d\x8a\xaa\x8e\x0a\xed\x07\xb3\x88\x9d\x4e\x45\x0c\x12\x09\x68\x4c\xe1\x38\xd0\xc9\xda\x07\x95\x25\xf5\xaa\x02\x05\x0a\xf5\x70\xe4\x31\x5c\x2f\xa8\xb0\x99\xb7\x76\x5b\xfb\xb8\x94\xfa\xd3\x59\xb8\xe2\x48\x04\xec\xe0\x52\xac\x22\xa1\x91\x70\x53\x35\xe9\x88\x40\xa6\x24\xe4\xcb\xf3\xa1\xa1\xa3\x27\x81\x27\x85\xb2\xc0\xf5\xd6\x38\x14\x57\xb7\x2f\xdb\x63\x3e\x81\x93\x8b\xbb\x54\xb8\xc3\x7c\xcc\xb5\xd5\x9c\x58\x27\xc7\x68\x3a\x52\x47\x54\x49\x77\xe9\x84\x44\x21\x78\xd0\x85\x29\x06\xca\x6f\x94\x5c\x42\x29\xeb\x08\xad\x27\xe6\xc2\x75\xd7\xb4\xec\x8d\xc2\x5f\xb2\x81\x93\x37\xe5\x3e\xad\x6c\x7a\xa7\x87\xf9\x1a\x7d\xc6\xdd\xaf\xd5\x36\xee\xfc\xbd\xec\x2c\x50\x16\x7b\xe3\x43\x06\xa8\x2e\x16\xd5\xd5\x2b\x3b\x1b\xe0\x08\xa7\xa6\x11\x27\x4c\xe2\xcf\x8d\x62\xe3\xb9\x00\xc0\x99\x43\xbe\x70\xcc\xc7\x7b\x07\x06\x37\xc2\x50\x61\xd6\x1b\xe9\x10\xee\xf5\x0d\xf1\x87\x44\xc3\x3e\x76\xf6\x70\x1e\x0a\x8f\xf6\x29\x7f\xa6\x7e\x4b\x41\x08\xc1\x37\x56\x72\x7a\x9d\x74\xbc\x9e\x17\x98\x3e\xec\x08\xf8\x66\xb7\xc7\xff\xb3\x7f\x3c\xcb\x01\x41\xa8\x0f\xef\xf6\x32\x2b\x2a\xc6\x2b\x84\xce\x27\x97\xfd\x98\xd6\xff\x26\x9a\x41\xa0\xc3\x84\x82\xdb\x67\x98\x62\xa3\x8c\xd2"}, +{{0x1a,0xf4,0xcf,0x6d,0x24,0xab,0x37,0x82,0x86,0x7d,0x96,0xa1,0xc2,0x75,0xce,0xeb,0x02,0x2c,0x69,0x1a,0x30,0x8e,0x62,0x45,0x66,0x5d,0x61,0x6b,0xf6,0x7c,0x2c,0x32,},{0x19,0xd3,0x17,0xea,0x98,0xd3,0x5b,0xa5,0xfa,0x67,0xc1,0x2e,0xcf,0xb3,0x27,0x50,0xdf,0x27,0x5d,0x7a,0x45,0xb8,0xe2,0x11,0xa7,0xac,0x47,0xed,0xe7,0x71,0x2d,0x9f,},{0x7e,0xb4,0x6c,0xd0,0xde,0x31,0x55,0xb4,0x37,0x47,0xd7,0x32,0xf1,0x04,0x5d,0x8e,0xf7,0x44,0x92,0xad,0x82,0x7a,0x22,0x45,0xbd,0x17,0x10,0x28,0x28,0x44,0x2e,0x43,0xa0,0xce,0x7e,0x8b,0x26,0x8e,0xd7,0xfd,0x8d,0x3e,0x7b,0x28,0xf0,0x72,0x79,0x5d,0xa3,0xe0,0x70,0xf1,0x2b,0xc4,0xe2,0x3e,0xae,0xf5,0x7b,0x85,0x3c,0xee,0x88,0x0a,},"\xf4\x45\xfd\xcf\xe2\x8c\x17\xbd\x44\x27\xae\xa5\x67\x6c\x0e\x12\x80\x84\x15\x97\xe9\xd6\x6d\xe7\xd7\xa7\x17\x23\x11\x09\x39\xbe\xd0\x0f\x4e\xba\xf9\x60\x3d\x53\xc9\xcb\xf6\x27\x1b\xe5\x47\xaf\x29\xb2\xa0\x45\xec\x41\x28\x8a\x7b\xb7\x9d\x66\x2d\xc2\x10\xe2\x15\x95\x7f\xa8\x46\x88\xc9\x16\x54\x3e\x56\x17\xf5\x60\xe4\xd3\x8f\x73\xba\xef\xc3\x7e\x11\x91\x4e\x47\xc5\x15\x06\x78\x51\xe8\xed\x21\x39\x3e\x13\xdd\x19\xed\x9b\x73\xd9\x89\x45\xfc\x82\x6a\x25\x8e\x95\x7d\xc0\x83\xdd\x8e\x53\x5c\x30\xa5\x4b\x42\x66\xdd\x71\xd1\x13\xce\x85\x6b\x46\x28\x2a\x18\x03\x36\x27\xa9\x8e\x64\x72\xcc\xb4\x63\xed\x3d\x96\xfa\x7b\x35\x5d\x3b\x2c\x2a\x2b\x60\x10\xdd\x14\xf4\xea\x39\x65\xdd\x87\xbe\x1c\x42\x9b\xde\xa8\x30\x0b\x4b\x0b\x44\x45\x86\x35\xb4\x97\x9f\x5e\x3e\x8e\xb5\xc6\x18\xd4\xe1\x3e\x1d\x68\x8b\xf8\x8c\x7e\x4a\x3d\x93\x8e\x84\x33\x6d\x67\xbe\x68\xdf\x34\x35\xc5\xc9\x90\x86\x32\x1c\x02\xe1\x3b\x4a\x12\x52\x4b\x34\xe4\x6a\x0b\x4d\x27\xf3\x0d\x7e\xd4\xf5\xce\xcb\x36\xde\xad\xf0\x9e\x7e\xfc\xc7\x55\xca\x66\x75\x68\x29\x79\x14\xc6\xbc\x24\x06\x27\xd9\xd0\x9a\xac\xf8\x54\x15\x41\x2c\x06\x35\x62\x34\x53\x27\x8d\x9b\xf0\xe1\x0e\xec\x65\xfc\x72\xaf\xff\xfa\x93\x92\xdc\x78\x81\xd1\xe5\xc7\x60\xa4\x02\x80\xf1\x6b\x14\x75\x12\x7b\x91\xb6\x9c\xcb\x65\xdc\x4b\x35\xde\x10\xf9\x43\x25\xc0\xcb\xe1\xc4\x70\x19\xa2\xea\xf2\xb4\xba\x92\xd7\x85\x22\x9a\xac\xfa\xd1\x82\x6e\xbb\xde\xbe\xfb\x7d\xad\x4b\x05\xf8\x82\x43\xe1\x5f\x27\x97\x66\xe3\x32\x1d\xd8\xdb\xa6\x50\x44\x4d\x81\xfb\x08\x78\x76\x7a\x9c\x63\x53\x4b\xb4\xba\x21\x28\x5a\x24\x16\xcb\x8f\x85\x6d\x11\xa9\x6e\x0a\x8c\x8d\xe1\xe1\xa7\x51\x32\xf1\x56\x4c\xd9\x94\x99\x56\x90\xbb\xed\x2e\xe1\x54\x53\x7f\xb6\xf2\x79\xfb\x09\xc8\xde\xa6\xf6\xaf\xab\xc6\x28\x56\xe3\xd1\x28\xfd\xfa\x79\xfc\x49\x76\x19\x3b\xb9\xb3\x36\x86\x1e\x47\xb5\x6d\xc2\x58\x23\x93\xd2\xe5\x44\x65\x1a\xc8\x5b\xc5\x8e\x9e\x6a\x94\xdc\x4c\x39\xc4\xef\x72\x53\x8a\x14\xf8\x56\xcd\x95\xc3\xe2\x79\x0a\xde\xe0\x3a\xb2\xe5\x2c\xa0\xae\x47\x1d\xe5\x02\xcb\x19\xe6\x76\xaf\x35\xf5\xf9\x3d\x84\x0f\xef\x96\x06\xcb\xe9\x2d\x8b\xc2\x50\x06\x10\x5d\x92\x34\x45\x88\x83\x88\x42\xc3\xbe\x50\x5c\x73\x50\xe3\x51\xb7\x35\xe6\xcc\x6f\xb7\x92\x75\xb2\x7b\xd9\xeb\xd3\x6b\xa4\xd0\x60\xac\xee\x73\xb5\xa3\x15\xce\xff\xab\x86\xd0\x6f\x21\x68\xa6\x70\x65\x57\x81\x96\xa0\xed\x04\xa4\xdd\x71\xd6\x73\x48\x37\xdb\x08\x38\x57\xab\x1e\xb5\xe0\xee\xc4\xff\xba\xc9\x54\x4f\x4e\xc1\x9b\xde\x19\x4d\xf8\x4b\x1c\x84\x83\x41\x57\x4b\xf1\x0d\xae\xe8\x5b\x81\x78\x19\x6f\xb6\x08\x12\x3a\x80\x81\x71\xd7\x3c\xe4\x20\x6a\xd6\x52\x16\xad\x1a\x5c\xbd\xe4\x0b\x19\xd6\xae\x7f\x40\xdf\x97\xab\x84\x32\xe2\xc5\x3a\x50\x4e\xd1\x22\xe2\x5f\xb7\xa5\x1c\x14\x35\x4a\xb3\x92\x8e\xde\xb3\x9c\x29\xeb\x24\x6b\x74\xa0\x76\xf8\x9d\x03\x50\x4f\x40\x1b\xd1\x76\xb5\xcf\xfe\xe4\xb9\xdb\x09\x7c\x45\x76\x4f\x51\xaa\x37\x67\x04\xb5\xa7\xf2\x10\xb3\xf1\xa9\x05\xe2\x5d\x67\x00\x2f\x65\x57\xeb\xb7\x49\x73\x7c\xda\x31"}, +{{0x2a,0xac,0xc8,0x19,0x7f,0xf8,0xfa,0xe1,0xc1,0xcf,0x38,0x62,0xe3,0xc0,0x4a,0x21,0x78,0x29,0x51,0xf8,0xe4,0x8e,0x40,0xb5,0x88,0xf8,0xbc,0x74,0x60,0xc3,0x0a,0x03,},{0x9a,0x1b,0x01,0xe2,0x15,0x4f,0x1c,0x36,0xa8,0xe1,0x6b,0x79,0xee,0x7d,0x2d,0x05,0xb8,0x71,0x2e,0x0d,0x27,0xa0,0x61,0xa6,0xd4,0x1d,0x47,0x57,0x78,0xb0,0xdf,0x8c,},{0x64,0x7c,0xdd,0x6c,0x1a,0x67,0x29,0x0e,0x57,0x67,0x6a,0x78,0x11,0x3a,0xaa,0xdc,0xa6,0x9a,0xc5,0x7b,0x99,0x77,0x15,0xc5,0x09,0x89,0x5b,0x8c,0x5c,0x94,0xe8,0x2c,0x0b,0x6a,0xce,0xcc,0xf3,0xba,0x8b,0xd7,0xcf,0x61,0x75,0x2b,0x1b,0x19,0xd1,0x3b,0x49,0xf1,0x5f,0x8b,0xfa,0x04,0x6e,0xb4,0x42,0xa5,0x5c,0xd5,0xba,0xb1,0x42,0x02,},"\x5d\x82\x75\x2c\xe5\xda\x31\x80\xfa\xf4\x78\x7a\xed\xfb\x19\x29\x4b\x43\x48\xa1\xd9\x20\x2c\x85\x39\x83\x31\x32\x3e\x0f\x42\xb0\x83\x52\x27\xe6\x8e\x11\x56\xf2\xd4\xba\x2f\xe4\x50\xe6\xd6\xef\x2b\x92\xd8\x9b\xbb\xe4\x09\x6e\x12\xca\x83\x97\xeb\x2f\x45\xe6\x76\xf1\x67\x3a\xa4\x1c\x95\x9f\xcd\x30\xd5\x57\x88\x53\xb5\xdb\xd1\xc0\xd5\xb3\xa0\xf0\xd8\x70\xec\xa7\x1e\xa1\x33\x90\x11\x1b\x25\x8f\x65\x48\xb3\x2f\x37\xa0\x5e\x97\x44\xa6\x56\xfd\x77\x8d\x65\x72\x19\x65\xc6\xd9\xb3\x28\x60\x0b\x45\x70\x47\x70\xe0\x4b\x09\x97\x90\xaa\x78\x84\xf0\x0d\x7b\xb7\x65\x9e\x33\x72\x10\xbd\xc2\x3e\xaa\x71\xd7\xb0\x16\x03\x0a\xca\x62\x23\xb5\x56\x9b\xdf\xc2\x90\x81\x1a\xac\x40\x95\x24\xdc\xcb\xf9\xba\xbc\xbe\x4b\xf2\x09\x46\xb5\x44\x31\x7c\xa6\xf2\xf9\x18\x31\xc7\x9f\xb2\x73\xb6\x40\x4e\xb4\xe6\x1e\x1f\x7b\x10\x6e\xbd\x0d\xb9\xf2\xb1\x97\x4d\x2f\x03\x1b\xce\x25\x80\x36\x06\x55\x2c\x34\x41\x65\x5e\xfc\xf2\xc7\xea\x52\xad\xcb\x30\x99\x3d\x85\xf2\xdd\xa7\x96\x03\xe9\x41\x5a\x02\x32\x45\xa6\x6c\x07\xa9\x56\x93\x31\x46\xf5\x3c\x99\x3c\x08\x89\x18\x08\xb8\x16\x6b\x30\x72\x1f\xbd\x1f\x8a\x1b\x93\x7d\x14\x07\x0d\x78\x6e\x9e\xb4\x51\xf2\xab\x51\x42\xf8\x3a\x60\xf3\x5d\x76\xad\x8b\x81\xd6\xa5\x7c\xf3\x68\xfc\x6f\xca\xcc\x0c\x47\x58\x44\x0d\x9c\xd5\x95\xb1\xb0\x94\x2a\x36\x55\xe2\x50\xda\x98\x3b\x72\x41\x54\x6d\xcf\xbe\x0a\xe8\x10\x77\x65\x02\x95\x40\x9f\xf9\xe9\x09\x77\xfb\x99\x60\xcb\xf4\x0a\x2a\xf5\x17\x74\x02\xba\x2f\xaf\x50\xdb\x6f\x1a\x73\x65\xcf\x99\xe9\x92\x42\x9e\x38\xdb\x43\xea\x83\xfd\xdc\x95\xa6\x48\x67\x6c\x0b\x16\xbc\x95\x2b\x15\xde\x99\xd5\x2f\x6b\x52\x33\xda\x4e\xae\x19\x78\xe8\xba\x25\xe6\x23\x5a\xfb\xc5\x11\xc7\x6c\x4c\x87\x4c\x92\x37\x92\x2b\x1c\xef\x08\x47\xd0\x7a\x80\x20\x0c\xba\xe3\xc7\xc8\x1f\xcb\xd0\xd1\x72\x52\xed\x8c\x61\xad\x19\x54\xfc\x86\x2e\x1e\x04\x44\x4c\x32\x08\x6f\xee\x38\x0d\x1c\x17\x54\x13\x22\xb9\xa6\x0d\xa6\x62\x35\x2e\x21\x0e\x9a\xe2\x15\xe3\x53\x29\x6d\xb9\x22\x33\x9a\xa1\x7d\x21\x73\xec\x31\xf1\xc5\x30\xa2\x4b\x1f\x34\x8a\x31\x57\x2e\x14\x69\xca\xac\x80\x8f\x9c\x76\xec\x27\x31\x87\x3b\x80\x3e\xad\x3e\x54\xea\x24\xbc\x24\x49\x9b\x97\x04\xb3\xbd\xce\x81\x38\x9b\x9d\x14\xd4\x95\x27\xc0\x4b\x3b\xb9\xe3\xba\x6d\x94\x6c\xea\x58\xcf\x78\x6d\x4d\x28\xb8\x9b\x41\xc5\x82\x74\x03\x5a\x86\x90\x5a\xd9\x57\x58\xc3\x16\x13\x66\xab\x93\xda\x81\xe6\xb4\xc8\x08\x36\x4e\x08\x7d\xae\xea\x4c\x4c\x5c\x2a\xa6\x87\x19\x37\xc5\xfe\xab\xa2\x14\x9f\x01\xf7\x38\xf4\x53\x96\xe6\x6e\xa8\x06\x32\x21\xe1\xc8\x1c\x05\x25\x5b\xa5\x64\xad\x44\x0c\xb5\xd0\x7c\xbd\x4b\xab\x94\x1e\xa5\x93\x24\x49\x30\xbc\x5c\x28\x9b\x31\x65\xd3\xec\x88\x47\xeb\xc4\xb6\x74\xc0\xa4\x9f\x91\x69\xad\xef\x78\x6d\x77\x67\xbc\x8f\x21\x3d\xb7\xd9\x5c\x06\xe9\x9b\xc1\x1e\x20\x00\x55\xb6\x5e\xb7\x9a\xda\xa0\x1b\xcd\x2c\x85\xda\x43\xce\x63\x70\xe1\x2e\x34\x9b\xf6\xd4\x75\x48\x7a\xff\xdf\x92\xe2\x0a\x3a\xcd\xed\x1d\x76\xf9\xe8\x3e\x91\x9e\x98\xde\xf1\x95\x07\x2a\x50\xd0\xc5\x71\xdd\x25"}, +{{0xff,0x86,0x21,0x56,0xc7,0xea,0xb6,0x81,0xc9,0x5e,0xff,0xf8,0x00,0x3e,0x00,0xa1,0x4f,0x1f,0x0d,0x50,0x5d,0x55,0x07,0xe6,0xe5,0xb3,0x91,0x79,0xdf,0x9b,0x1c,0xda,},{0xe1,0xb8,0x9f,0xb3,0x11,0x14,0xea,0x46,0x10,0x7f,0xfd,0x03,0x29,0xf1,0x06,0x64,0x28,0xde,0x54,0x70,0x8e,0xdb,0xec,0xf3,0xed,0x9d,0x47,0x08,0xcd,0x14,0x3f,0xe2,},{0x4b,0x81,0x37,0x04,0x2d,0x67,0x84,0x75,0x7d,0x4a,0x9c,0x06,0xbc,0x74,0x32,0xf4,0x80,0x9b,0x1c,0x6a,0x90,0x35,0x42,0x73,0x6d,0x9a,0x57,0x66,0x8c,0x20,0x84,0x5c,0x17,0xd4,0x68,0x55,0x70,0x85,0xc5,0x7f,0xb6,0x32,0x13,0xda,0xd3,0xbe,0x0f,0xa3,0x6a,0x11,0x8f,0x7c,0x1a,0xef,0xf2,0x56,0x2f,0xf4,0xb8,0x88,0x8c,0x26,0x90,0x0e,},"\xb3\xd1\xdb\x72\xa6\xa9\x85\xec\xd7\x0a\x2c\xff\x6c\x18\xc1\x79\xe2\x17\xd4\xf4\x10\xfd\x39\x34\x96\x96\x85\x90\x1b\xd0\x71\xbc\xe6\xc2\xfb\x67\x63\xe1\x0c\x6f\xa1\x6e\x75\xa1\x17\x60\x66\xb8\xec\x81\xae\x3a\x80\x39\xe7\x1d\xc2\xcd\xc6\x4a\x40\xfd\x62\xb7\xce\xe7\xbe\x4b\xa0\x33\x2f\xe4\x5d\x0b\x60\x15\x86\x52\xe3\x3f\x8d\x3a\xff\x3c\xb4\xd6\xb0\x21\x74\x4d\x0d\xd1\x78\xb1\xbf\x0a\x1c\xc1\xd3\xfe\x93\x21\xbe\x28\x42\x1e\xb8\x82\x63\xa1\x24\xf4\x97\x92\xd0\x79\x47\x5a\x8c\x55\x5f\xf5\x69\x08\x73\x51\x4b\x5d\x48\x3e\x53\x21\x7e\x0c\xbb\x12\x86\x2b\x85\x0f\xe3\x90\xc8\xf8\x30\x08\x08\x6e\x64\x9a\xc9\x04\xb0\x18\x35\x0a\xb4\x91\x57\xee\x9b\xca\xe6\xc0\x7a\x4b\x87\x8b\x48\xe2\x5e\x98\x4f\xbb\x4d\x36\xb6\x1d\x68\x9b\x13\x46\x8a\x28\xd1\xe3\x87\xe0\xe8\x86\x57\xf8\xc8\xac\x95\x86\xa6\xe2\x6c\xf9\x4d\xff\x6f\x82\x64\xe3\xff\x62\x58\x86\x5c\x6d\xcf\x85\x7b\x00\x14\x78\x86\xe1\x75\xdf\x04\x32\xe3\x2f\x04\x40\x0e\x29\x9f\x21\x18\x83\x12\xb3\x2d\xfc\x05\x0e\x7b\x7e\x87\xee\xaa\x0c\xba\xac\x6b\xe9\x93\x7a\x5e\x0c\xc3\x11\x13\xde\x7c\x8b\x23\x3e\x1c\xe8\xe5\xd9\xc5\x64\xfb\xe9\xf3\x7b\xbd\x41\x1d\xf7\xa5\xe4\x4e\x6c\x7e\xbb\x67\x6d\x85\x89\x4d\xcc\xf4\x86\x5e\x4d\xda\x0c\xad\xef\x2b\xbc\x55\x00\x0b\x3a\x29\xf1\xf7\x1e\xf4\x46\x1d\xdc\x3b\x33\x1d\x91\x56\x65\x34\xc5\xd6\xd8\x4c\x73\x13\x76\x29\x53\x20\xf8\x0a\xdc\x90\x28\x8f\x99\x53\x55\x4f\xcd\xf9\x21\x3d\xe6\xa9\x05\x21\x0d\x4c\x80\x64\xaf\x91\xcd\x98\x32\x5e\xf9\x18\x98\xd3\x3d\x70\x03\x82\x02\xe3\x2f\xb6\x70\x9c\xa3\xd7\x88\xfe\xcb\xd1\xb8\x41\xfa\x4e\x5e\x90\x62\xd6\x42\x67\xc3\x5c\xfd\x44\x4f\xb6\x9e\x2f\x60\x47\xf5\x8b\x1c\x2a\xf4\xcc\x7e\x4c\xac\x2f\x89\x08\x88\x36\x05\x92\x11\x3e\x96\xad\x3a\x85\x7e\xd0\x5e\xaa\xba\x6f\x91\x53\xef\x89\xb9\x3e\x00\xe8\x74\x37\x33\xec\x47\x2d\x9b\x0e\xec\x1c\xd8\xfa\x52\x42\x5c\x4a\x26\xbd\x7d\xf7\x3a\x27\x12\xbe\xbe\x51\xae\x3b\x25\xeb\x78\xdb\x82\x14\x90\x31\xfe\x7b\x28\x1a\xf6\xcb\x77\x14\xed\xf8\x9d\xe9\x15\xf3\x47\x0f\x15\x3e\xed\x7f\x45\x62\x43\xbb\x90\x34\x2e\x19\x0e\x64\x7f\x39\xe0\x46\x88\x3c\xe2\x8a\x89\x20\x03\x31\x5e\xa3\x79\x42\x9e\x95\x82\xa9\x35\xeb\x78\x96\x33\x96\xd1\x36\x84\x5f\x86\xc4\x66\xe8\xfa\xf2\x27\x2f\x43\xff\xef\xc2\xad\xa5\x60\x1f\x8a\x6b\x2a\xc4\xcc\x6b\x92\x82\x09\x17\xf2\xe0\x39\x3c\x8f\xaf\x98\x2d\x6c\x5f\x4f\x23\x0e\x27\xce\x22\x78\xa7\x23\x77\x47\xfa\x85\xa9\xc8\x57\xbf\x18\x02\xc3\xea\xe0\xd2\x35\xb5\xad\x58\x49\x7d\x66\xa0\xd3\xa9\xba\xeb\xcc\x41\x7f\x18\x33\xe9\xcc\x44\x60\xf9\x75\xd7\x28\x58\xcd\x11\x8d\x7a\xaf\xaf\x1c\x87\x82\x97\xca\xcf\x71\xac\x75\x67\x6d\xc1\xb4\xfb\x51\xc1\x77\x58\x10\xd0\x35\x37\xf2\xd7\x66\x27\x8b\x99\x71\xbb\x97\xd3\xc4\x9b\x51\xfe\xb2\x6d\x37\x5e\x0c\xb9\x10\x95\x74\xa8\x16\xf8\x4e\x76\xfc\x7e\xf0\x72\xd5\x79\x3c\x2f\x65\xab\x2e\xfd\x90\x52\xe6\xb8\x56\x9f\x28\x05\x86\x1c\x31\xa7\x34\x4a\x3c\x44\x06\x9a\x94\x32\x0d\x27\x4e\x27\x12\x71\xea\xfa\x3b\xfe\x64\xde\x75\x37\x84\x6a\x01\xe5\x1f\xda\xe0"}, +{{0x58,0x26,0x19,0xab,0x3c,0xf5,0xa3,0xae,0x77,0x66,0x88,0xbf,0x6d,0xba,0xcb,0x36,0x33,0x0a,0x35,0xad,0x75,0x24,0xe4,0x9e,0xf6,0x63,0x68,0x77,0x64,0xcf,0x6e,0xc7,},{0x20,0x02,0xea,0x0a,0x38,0xa3,0x27,0xe0,0x38,0x4a,0xea,0xe4,0x68,0xdb,0x0f,0x6c,0x85,0x16,0xa6,0x96,0x09,0xaf,0x9e,0xee,0x93,0xe9,0xec,0xb9,0x4b,0x44,0x9c,0x66,},{0xfe,0x97,0x01,0xda,0x1a,0xa8,0x1c,0x55,0xba,0xc3,0x36,0x38,0xf7,0x75,0x54,0x2b,0x80,0x44,0x80,0xf3,0x4b,0x7b,0xfc,0x78,0xda,0x99,0x16,0xe5,0x24,0x6a,0x60,0x4d,0x39,0x0b,0xf9,0x20,0xc8,0x72,0xa7,0x79,0x24,0x24,0x6e,0xe8,0xd0,0x39,0x3b,0x20,0x2e,0x7b,0x25,0xb2,0x48,0x4f,0x65,0x4a,0xc3,0x67,0xcb,0x09,0x25,0xec,0xe3,0x05,},"\xca\x74\x28\x4f\x11\xc5\x6e\x25\x98\xd7\x8a\x4e\xcd\x03\xb4\x0e\x01\x7a\x55\x81\x76\x01\x2b\x26\xfd\xf6\x95\xc3\xde\x98\xa7\x4f\x8f\x40\xa4\x7d\x79\x78\xed\xc2\x4e\xe8\x09\x2b\xfe\x5e\x61\x59\x68\x34\xde\xed\x1d\x9d\x34\xa0\xf5\xcd\xae\xbe\x34\x21\xaa\x19\xe0\x12\xde\x86\x5b\x9e\xe1\xb7\x34\x79\xb2\xbd\x1a\xc9\x82\xf9\x7e\xd9\xc7\xcd\x20\x45\x9c\x60\xfb\xb1\x1e\x1e\x2b\x4e\xac\x5d\xb6\x84\x4c\x71\xd7\x29\x49\x50\x2b\xba\x50\x3a\xce\xc9\x05\xad\xba\x25\xf6\xb1\x19\xea\xf9\x63\x9f\xa8\xab\xb3\x02\xdf\xf9\x93\x2d\x85\x0c\xc4\x4c\x57\xcf\x90\xb2\xe5\x8a\x8b\x52\x51\xc1\x26\xa9\xe2\x8f\x5c\x76\x1b\x62\x80\xe2\xcd\xdd\x79\xcb\xd6\x8e\x53\xff\x4a\x62\x26\xd3\xbd\x4c\x96\x1b\x9b\x9e\x43\x45\xa2\x54\x58\x62\xc7\x97\x38\x66\xf0\x42\x0b\x89\x8e\x7b\xae\xa9\x0e\xa4\xee\x00\x40\x42\xef\x38\xa1\xfd\x95\x6a\x72\xfd\xf6\xfd\x43\x25\x7d\xa9\xfd\xb9\x66\x80\xef\x4f\xdf\x9e\x94\x3d\x26\x5c\xdc\xf2\xe5\x2e\x32\x01\xd5\x40\x8b\xc6\xce\x10\xe5\x70\x0a\xdf\x12\xb5\x5b\xa1\x4a\xa8\x29\xd8\x69\x1c\x31\xf2\x4f\xc4\xa5\x1c\xe6\xfa\xa1\xf3\xef\x2e\xad\x78\xe5\xe7\x53\x44\x6a\xd3\xfa\x4a\x84\xc1\x93\x97\x9a\xeb\xc8\x30\x9b\xad\x60\x81\x4f\x48\x59\xb9\x31\xd7\x04\x14\x76\x44\x91\xc6\xc9\xed\x8d\xb6\x73\xc5\x43\xd3\x51\x85\xcd\x28\x88\xaa\x21\xc1\xa9\x20\x34\x27\xe0\xac\x0b\x1f\xe3\x4c\x0e\x4a\x40\x01\xe0\x95\x6c\x13\xcb\x59\xa3\xba\xf8\x7c\x21\x09\xa8\x88\xa4\xc9\xe7\xaa\x48\x17\x67\xd8\x02\x0f\xf3\x5d\xd7\xc5\xcc\xec\x7c\x08\xe9\x71\xa7\xe2\x18\x13\x8c\x90\x54\x6a\x7d\xdf\x36\xad\x11\x4b\xe5\x85\x57\x43\x2c\x2d\xdf\x34\xce\xd3\x37\x9f\x70\xd4\x40\x7e\x58\x79\xf9\x84\x2f\x38\x17\x17\x05\x1b\x16\x85\xaa\x7a\xb0\xad\x38\x54\x1e\xc1\x68\xf5\x1c\xb6\x88\xf3\xcd\x1a\x01\x9a\x33\x6c\x9f\x4f\x3f\x82\xde\x78\x5c\x07\x48\x67\xfd\xc8\x80\x0f\xc7\x6f\xba\x04\xc8\xad\x8d\xe1\x0d\x2e\x9b\x43\x05\x81\xbe\x44\xc4\x1e\xcc\x8f\xc8\xa6\x16\x31\x43\x99\xd1\x8c\x64\x79\xf5\x7e\x57\x3b\x22\xa6\xee\x5c\xe2\xdc\xc0\x89\x48\xa0\xde\x1f\x0d\xd2\x5b\x65\x71\x5a\xb1\x8c\x70\xc7\x62\xfc\x3d\x7d\x60\x0c\xad\x63\x22\x60\x38\x50\x9c\x19\xab\x35\xb5\x49\x3e\xee\x73\xa7\x03\x73\x1e\xc5\x35\xc9\x0c\x6f\x06\xd9\x4d\x3e\x5f\x7e\x51\xa0\x9f\x9f\x8f\x42\xc5\x01\xb8\x50\x46\x86\x36\x5c\xee\xe9\xe0\xfe\x00\x13\x29\xf3\x03\x52\x21\x46\x71\x7c\x6a\x12\x58\xd0\xf1\x57\xcb\xea\x4b\x5a\x5e\x3d\x13\xbc\x90\x7e\x95\xfd\x6e\x8a\x71\x89\x6a\x02\xc3\x10\x6b\xd2\x6a\x51\x00\x51\xf1\xb3\x02\x58\xab\x27\xf8\x75\x67\x3b\x13\x37\xee\x36\xb7\x1a\x37\x6e\x0f\x9e\x78\x09\xa6\x7c\x67\xd9\xac\xc1\x6c\x25\x1d\xcb\x8c\x92\x6c\x8e\x93\x25\x16\xd3\x8b\x72\x33\xea\xc6\x15\x9c\x59\xca\xd0\x30\x7c\x59\x0e\x71\x31\xb6\x22\x19\x14\x5a\xaa\x35\x5b\xfb\x4a\xcb\x6a\xf0\xa5\x50\x00\x06\xcd\xd8\xb8\x13\xfe\x19\x08\x60\x2e\x08\x74\xc9\x62\x2b\xb3\x76\x73\xba\x1a\xcb\xa4\x14\x23\x16\x67\xbc\xc4\x90\x7a\xc8\x71\xf8\x7e\x6c\xe3\xf5\x91\xc1\x91\x71\x05\x7a\x9f\x45\x7f\x53\x62\xae\xda\x10\x5d\x18\xfb\x84\xf7\xd0\xf0\xa7\xda\x7e\xf8\xda\x91\x14"}, +{{0x2b,0xbd,0x83,0x0c,0xe7,0xde,0xf3,0xfe,0xce,0xa1,0xec,0xd6,0xea,0x0a,0xe9,0xc9,0xf4,0xfa,0x8f,0xfc,0x3b,0x1f,0x19,0x38,0xc5,0x05,0x05,0x1b,0xab,0x40,0xcf,0x7a,},{0x0f,0xdf,0xed,0x8d,0xe3,0xc1,0xea,0xf8,0x91,0xce,0x37,0xe3,0x4c,0xb4,0xa2,0x44,0x1c,0xbb,0xae,0x08,0x83,0x38,0x3d,0x70,0xde,0x24,0x64,0x85,0x0b,0x4a,0x64,0x2a,},{0x13,0xeb,0xc9,0x79,0xa8,0x87,0x10,0xe3,0xc5,0xf3,0x45,0xcf,0xbb,0x82,0x48,0x13,0xb3,0x08,0xa9,0xd5,0xc6,0xde,0xe3,0x28,0xbf,0xd2,0x35,0xa9,0x7d,0xe7,0xb3,0x26,0xde,0x6c,0x73,0x8f,0x96,0xf6,0x98,0x31,0x94,0x92,0x09,0x99,0x68,0x52,0xdd,0x9c,0x09,0x8d,0x58,0x08,0x41,0x87,0x09,0xf2,0xbf,0x51,0x0d,0x46,0xb7,0xf0,0x36,0x06,},"\x5f\x1e\xde\xaa\x3c\x0b\x2a\x63\x31\x1d\x97\xf1\xc5\x4e\x7e\x2f\x68\x71\x70\xe6\xb4\x6e\x21\x69\xcb\xf5\x6c\x66\xf2\x31\xbf\xc4\xa5\x76\xbd\x2b\x84\x20\xbf\x35\x7d\x3a\x90\xf8\xf3\x2e\xa1\xad\x99\x39\xb4\x67\x25\x4b\x66\xa1\xdf\x1f\x5b\x4c\xba\xc6\x3a\x5c\x27\x24\x26\x0d\x24\xd8\xdf\x8e\xdb\x58\xae\x24\x7a\x25\x91\xe9\x20\xb1\xa4\x20\xcf\x8d\x85\x39\xea\x57\xdb\x0d\xad\xff\x1a\xd3\xe9\x8c\x31\x72\xd0\x33\x16\x3c\xb4\x34\xa7\x66\xb0\xc1\x18\xa5\x6a\xbd\xcc\xe7\x9c\x82\xaf\x7b\xac\x74\xed\x0e\xa0\x24\xac\x4c\xe0\x22\x2d\x0a\xa9\x14\xf4\x32\x09\x2b\x1b\x51\x78\x04\xdb\x59\x18\xa8\x45\xe9\xcc\xa5\x5a\x87\xdb\x7c\x28\x52\xf7\xdd\x2e\x48\x36\x01\x85\xcc\x44\x2c\x79\x30\xaf\xe1\x5d\xd6\x22\xcc\x02\xbc\xd1\xee\x77\x8b\x59\x70\x5f\x14\x33\x32\x41\x58\x8a\x52\x2d\xe2\x44\x07\xe8\xe6\xe1\x0d\x5e\xf3\xa8\x8e\x3a\x3c\x44\x38\xc1\x7f\x75\x04\x67\x4f\xd7\xe4\x18\xcb\x2f\x77\xad\x0a\x56\xd2\x38\x67\x03\x15\x5e\x9a\x40\x1c\x43\xdd\xb5\x1e\xad\x55\x20\xaa\x7b\xa0\x38\xe7\xde\x53\x31\x41\x8a\xd5\x52\xbd\xcd\x18\x5f\x50\x3a\x85\x48\xf5\x5b\x63\x86\xe4\x68\x7c\xa5\x15\xf7\xc0\xee\xa5\x70\x98\x3b\xfb\x24\xbe\x16\xf7\xb3\x00\x3f\xb7\x56\xe3\x26\x56\x2f\x2a\x32\xfe\x65\xff\x84\x4c\x39\x84\xc7\x2e\x40\xdd\x49\xe4\xf3\xae\x8c\x0f\x81\x9a\x79\x39\xb2\xe7\x36\xe3\x81\xf5\x82\x3c\xbc\x61\xb2\xed\x01\xd9\xb0\x5c\xf8\xb1\x46\x48\xa4\x8b\x0d\x7c\xbe\x88\x2a\xc1\x6c\xad\xd8\xc4\x2a\xa2\xc7\x02\x46\x34\x7b\x4d\x84\x95\x36\xa7\xac\x22\xc7\x20\xda\x3c\xf1\x78\x72\x5e\xe5\x57\xa9\x2c\x25\xb1\x2b\x8b\x95\x6d\x3b\xf4\x80\x2e\x9e\x8a\x15\xb5\xab\x75\x42\x35\xcc\xa0\xe5\xb7\xe5\x5e\x4a\xec\xe4\x5a\x47\xe0\x84\xce\x14\x47\x44\x05\x98\xef\x5d\x4f\x5f\xdc\x2c\x98\xa5\xad\x13\x6c\xff\xbf\x87\xd3\xcf\x52\xf6\x73\x8c\xca\x79\x48\x35\x60\x92\x07\x8f\xdf\x25\x45\x77\xf5\x59\x69\xa0\xc6\x52\x46\xda\xc8\x09\xa2\xfc\xa1\xf6\x0a\x1d\x92\x98\x77\xb9\xa6\x54\x0e\x88\xa9\xe6\xe9\x15\x59\x38\xd2\x2c\x68\x7e\x63\xb3\x87\x53\x4d\x38\x5e\x89\x61\xe5\x88\x67\x43\xf9\x5f\x4a\x70\x80\xd9\x16\x62\x45\x17\xb1\x53\x36\x03\x0a\x46\x71\x4b\x16\x8b\x83\xd6\xf9\xcc\xe0\x60\x66\x49\xc0\x1f\x0a\x1d\x0a\x2a\x53\xf5\xe3\x78\xf6\xaa\x98\xc3\x84\xaa\xfb\x3e\xef\xdb\x34\x21\xfa\x3a\xc9\x8a\x0d\x3a\x9c\x02\x9c\x23\x00\xae\x02\x41\x06\x7d\x1a\x4f\xc9\x2e\x43\x86\x88\xea\x88\x9f\xcb\x1a\x1a\x9e\x86\x34\xb9\x16\xc6\x0b\xaa\x0c\x18\xbf\xcd\x13\x9b\xfe\x30\x17\xbf\xbe\x16\x29\x13\x43\xce\x86\x05\xbb\x78\x72\x55\x8c\x6b\x5f\xd5\x6d\xfd\x22\x15\x77\xed\xcf\xfa\xa8\xbd\xa3\x4d\x7a\x11\xab\x8c\xb2\x78\x28\x8e\x58\x34\x84\x26\x76\xfc\xcf\xfa\xa9\x11\x1b\xce\xd2\xb3\x57\x5f\xdd\x49\x62\x1b\x76\xe8\xd1\x29\xb6\x17\x00\xee\xab\x03\x14\xef\x94\xd5\x50\x50\x6a\x4b\x8d\x1e\xe6\x55\x08\xd8\x9d\x0e\x99\xe9\x33\x6b\x41\xd9\xf7\x4a\xa4\xd7\x22\x11\x4d\xe0\xf3\x1e\xcf\x00\xb0\x97\xf5\x3c\x9a\xca\x9c\x7a\x28\x5b\x58\xa3\x5d\x70\x29\x8c\x5c\x34\xf7\x4b\x4a\x70\x53\x08\x03\x31\x00\x34\x9f\x0c\x62\xf9\xc2\xeb\xf7\xde\xad\x0a\x77\xb2\x98\xeb"}, +{{0x1a,0x7a,0x3c,0x2f,0x54,0x81,0x13,0x1b,0xe5,0xf8,0x68,0x45,0x6a,0xa2,0xfa,0x90,0xe5,0x6d,0x52,0xcb,0x72,0x1c,0x71,0x84,0xeb,0xff,0x06,0xfe,0xd2,0xfe,0x68,0x5d,},{0x7c,0x2a,0xd0,0xf2,0xa5,0x70,0x55,0x03,0x26,0xfb,0x50,0xa8,0x50,0x83,0x58,0x21,0x67,0x6d,0xe1,0xde,0x12,0x7f,0x6d,0xe1,0x67,0x02,0x99,0xd8,0x14,0xf6,0xe3,0xce,},{0x97,0x61,0x60,0xfb,0x5b,0xbd,0xab,0xe5,0xc8,0x96,0x2f,0x23,0xba,0xba,0xcf,0x0b,0x0a,0xb4,0x1c,0x2b,0xb1,0x3e,0x9c,0x0d,0x44,0x90,0x67,0xb7,0xde,0xcc,0x7d,0xb4,0xe9,0x4e,0x76,0xa7,0x1b,0x9c,0x0a,0xc4,0xd6,0xaf,0x38,0x7a,0x72,0xa8,0xcd,0x73,0xe3,0xbc,0x63,0xb7,0xed,0x65,0x0b,0xee,0xbf,0x17,0x42,0x4c,0x49,0x0b,0xd6,0x0d,},"\xc6\x28\x34\xd9\xd5\x5d\x1a\x44\x03\xe9\x25\xd0\xa5\xb5\x52\xda\x17\x4c\x02\xf4\xe9\x45\xde\xc3\x38\xc1\xbb\xb2\xae\xb4\xff\x40\x02\x0e\xf7\x0f\xf5\x05\x20\x5c\xf8\x81\xb6\x29\x96\x0a\xbd\x62\x76\x4e\x5a\x54\xf2\xb5\x10\x56\x67\xb1\x1c\x7d\x5b\x7a\x4c\xcc\x3f\x48\x8b\xdd\xdb\x95\x8a\x7b\xe9\x54\x62\x07\xe6\xc4\x67\x18\x97\xc0\x53\x50\x8e\x1f\xd8\x32\x22\x13\x0a\x79\x33\x97\x6d\x2b\xec\x61\x4e\xd8\xf9\xb6\xa6\xb9\xf4\xef\xb2\xa5\x8b\x9d\x00\x5b\x94\x3e\x42\xf1\x71\xb7\x09\xa7\x31\x30\x70\xcb\x2e\x06\x8d\xa3\x9c\xf9\x99\x22\xb6\x9e\x28\x5c\x82\xad\x97\xf2\xd6\xc7\x79\x22\xca\xe2\xb5\xe3\x20\xe8\x35\x77\xc0\xd0\x88\x76\x1e\xc8\x81\x52\xc2\x97\x49\x29\x78\xa9\xd7\xa3\xff\x67\xed\xe4\x4c\x2a\x70\x7c\xf3\xe2\x35\x2e\x23\x2f\x53\xc8\x78\x2b\xa4\x89\x28\xa9\x7f\x8a\x36\xb2\x0a\x41\x68\x16\xe9\x45\x79\xb9\xd7\x25\x0a\x29\xdc\x84\x70\xf6\x3a\x70\x58\xe2\xd2\xa9\x9d\x6f\x0c\xcb\x53\x0d\xf5\x96\x95\x05\xef\x5c\x78\x44\xeb\x16\x7d\x20\xf4\x12\xa5\x08\xfa\xb1\xf8\xcd\x9c\x20\xc5\xeb\x9a\x41\x7a\x54\x12\xb5\xda\x6a\x57\x13\x57\x59\xfa\xb1\x7f\x63\x14\xf6\x8d\xf3\x5b\x17\x72\x42\x14\x43\x67\x6f\x31\x25\x79\xaf\x6b\x14\x11\x53\x5a\xda\x8f\x76\x01\x2b\x69\xbb\xeb\x60\xb2\x89\x7e\xe6\x60\x7c\xb3\x69\xcd\xf5\x2f\x4f\x6d\xdf\x88\xcd\xb2\x63\x0d\x78\x89\x6f\x13\x61\xfe\xa2\x2a\xe6\x34\x21\x76\x96\xff\x11\x4f\xb4\x2d\xbe\x4f\x43\x46\xf1\xbe\x5b\x57\xad\xb3\x84\xae\x7e\x49\xb4\x1f\x74\xb3\x1b\x9a\x62\xbc\x69\xdc\xa1\x65\x89\xc6\x34\xeb\x9d\x7c\x6c\x94\xf8\xec\xe4\x4b\x60\x62\x8f\x98\xe1\x02\x4c\xf3\x2e\x3e\x3d\xd6\xdc\xe5\x5a\x12\x22\x53\x2f\x49\x0d\x63\xe6\xa2\x75\x28\x1c\x0f\x3a\x6c\x10\x18\x91\xb8\xd5\x7a\x45\xde\x11\xde\x35\xeb\xb1\x51\xc0\xdc\xd7\x5e\x6c\x05\x0b\x3c\xd8\xba\xba\xe8\x45\xc3\x9f\x66\xc3\x6c\x77\xcd\xe0\x5b\x68\x3e\x4f\xb0\x10\x3d\x93\xe7\x65\x93\x35\xc8\x7f\xc0\xe3\x23\x5b\x2e\x82\x48\x8c\xda\xbe\xb5\xc5\xc8\x75\x80\x87\x45\xee\xa9\x2d\xe8\x6b\x8e\xfc\xb6\x3e\x16\xd0\x82\x91\x9a\xee\x2e\x92\x89\x9c\xb0\xbc\xf1\xc1\x42\x15\x77\xa4\xa0\xd9\xdb\x09\xee\x1f\x9f\xeb\x92\xa5\x38\x21\x03\xcf\x7c\x32\xcf\xe4\x63\x72\x5a\xe4\x86\x6d\xaa\xfe\xda\x05\x34\xc1\x69\xf8\xf9\xbe\x40\x4f\x3b\xaa\xe1\x23\xfa\x76\x8a\xce\x46\x17\x8d\x4b\x9b\xbc\x5b\xd7\xae\xec\x79\x03\xb0\xa5\xbc\x57\x53\x89\x86\xee\x09\xe0\x7e\x32\x07\x7b\x3b\x9d\xe5\x0d\xd1\x96\x7a\x37\x2c\x38\x5a\xc8\x86\x28\x7c\x18\x45\x1a\x64\xef\xb3\x7d\x05\x6f\x9f\x41\x94\xc0\x8b\x1e\x3e\xc9\x70\x22\x26\x7b\xf0\x04\x3c\x13\xd2\x6b\x9c\xe1\xf5\x39\x05\xf6\xe4\x1b\x3d\x99\xdc\x81\xb3\x31\x90\x9b\x72\x26\x66\xef\x24\x32\xe6\xaf\x8a\x45\x31\x07\x53\x12\x30\xce\x4a\x1a\xf8\xee\xd6\x26\xda\x22\x3d\xa7\x6b\x46\x50\x7e\x33\xd7\xcd\xbd\xe0\x2d\x41\x10\x40\xc8\x9a\x11\xd9\x51\x56\xed\x4a\xc2\x60\x5b\x82\x69\x39\xc6\xcf\x87\x7b\x4e\xe7\x36\xc5\xda\x77\xcf\x46\x50\xa9\x99\x7a\x3b\x9c\xf4\x6a\x82\xba\x2b\xc0\x13\x33\xc0\x44\x78\xb5\xc9\x2e\x24\x98\xbd\x00\x2f\x01\x31\x40\xae\xdb\x30\x1b\x95\x99\x3d\x1d\x75\x08\x70\xd9\x88"}, +{{0x19,0x1a,0x1d,0x90,0x32,0x1c,0x7f,0x4e,0x74,0x94,0xbb,0x98,0x29,0x09,0xa9,0xeb,0x40,0xc3,0x34,0x1d,0xd3,0x2a,0xe4,0xd9,0x67,0x50,0xb7,0xd0,0x29,0x66,0xb4,0x0f,},{0x95,0x62,0xd9,0xe2,0x13,0xf1,0x45,0xc4,0x56,0x93,0x5b,0x70,0x31,0xc6,0x80,0x66,0x9f,0x8b,0xbd,0x31,0xa4,0xc2,0xed,0x3c,0x91,0xc4,0x00,0x2a,0x56,0x29,0xe9,0x7b,},{0x74,0xcb,0x02,0x8d,0xc6,0xb7,0x5b,0x37,0xa1,0xda,0xea,0x1c,0xf8,0x84,0x65,0xdb,0x83,0xa0,0x09,0x3f,0xec,0xb2,0x2d,0x99,0xba,0x85,0x5e,0x9a,0xb5,0x9d,0x05,0xcb,0x22,0xc8,0x7d,0x0b,0x09,0xdf,0x7c,0x11,0x62,0x13,0xba,0xa8,0xf1,0x89,0xb2,0x70,0x3f,0xf9,0x53,0xcd,0x20,0x2e,0xb9,0xde,0xa3,0x97,0x6e,0xe8,0x8f,0x5f,0xa7,0x03,},"\x85\x89\x0d\xb4\xe2\xfb\xce\x09\x3d\xde\x5a\x80\xbf\x8f\xe0\x9a\x98\x4b\x83\xa4\x9b\x7c\xcb\x5d\x4b\x06\xcd\xaf\xdd\xd3\x82\xe4\xb8\xa8\xa5\x05\x30\xe8\x2c\x20\x06\x12\xc9\xd7\xd8\xa0\x89\xbc\x8a\xa8\x45\xc3\xcf\xcc\x38\xa6\x19\x5d\x21\xc2\x61\x8c\x3d\xba\x2b\x57\x09\x20\xec\xcf\xcd\x23\x6f\x17\xf0\x8d\x81\x42\x68\xf8\x82\x24\x2d\xdf\x07\x02\xda\x87\x85\xf4\x07\xaa\x8f\x86\xfe\xcf\xa9\x03\xc4\x8d\xa8\x3f\x83\x97\x77\xeb\x6b\x4a\x2b\xbf\x5d\xf7\xa4\xda\x53\x47\x5a\xf1\xff\xe4\x4b\x5f\xe0\x07\x2b\x8f\xbf\x3d\x26\xe6\xd8\x9e\xa6\x7d\x8a\xc8\x45\x94\x92\x89\x0a\xda\x65\x7e\xb3\xdc\x24\x92\xb8\x8d\xe1\x75\xb4\xbb\xa1\xa5\x08\x06\x4d\x61\x96\x74\xaa\xae\x2a\xf0\x9d\x31\xa5\xc2\x7c\x8d\x5d\x5a\x29\xb0\x37\x79\xf4\x28\x6b\x89\x66\xce\x40\x7e\x6f\xf6\x92\xfb\x94\x25\x20\xa9\x93\x8d\x69\xcc\x70\xac\xb0\x6b\x01\x4b\x6d\xfc\x19\x83\x42\x06\xcf\x1a\xc6\xc4\x48\xae\x6f\x07\x80\x25\xb5\x5f\x3d\x82\x72\x01\x26\x8a\x92\xad\xd9\xad\x17\x8e\xf7\x6a\x29\x89\xfe\xdc\x6e\x39\xf4\xeb\xb9\xf9\x6c\x9b\x83\x52\x69\x4f\xa5\x4f\xa0\x22\x01\x9c\x0e\xc0\x01\x2d\x0d\x76\x9e\x23\x67\x80\x3f\x92\x5f\x17\x5f\x9f\xb9\xcb\xec\x4a\x0c\x9c\x1e\x2c\x83\xea\x57\xe6\xa9\x2a\x17\xf5\x55\xca\xb9\x34\x27\x1e\x72\xc8\xcc\x32\x15\xfc\xb8\x7c\x20\x53\x9b\xf1\x42\x77\xb1\xbf\xbd\x6e\x58\x80\xef\x95\x3f\xc7\x5f\x23\xc0\xdd\x4f\xcc\x1e\x0b\xe3\x40\xaf\x94\x7d\xe0\x2e\x87\x7f\xd5\xc7\x7d\xd1\xdf\x7b\x41\x4b\x5c\x0b\x40\xc7\x49\x56\xa5\x45\xa1\x15\xb0\xc6\x99\x3a\xb2\x33\xb7\xe7\x2c\x82\x2b\x6b\x33\x81\xbb\x1f\xc1\x08\x75\xbf\xfe\x3e\x2e\xd1\x19\x0f\xa3\x3f\xc1\x5d\xa0\x83\x79\x4f\xcc\x2c\x5b\xf5\xa0\x79\x09\x06\x3c\xb2\x89\xa0\x8a\x2c\x8a\x33\xd3\x43\x84\x2c\x2d\x6a\x3c\xfa\x2a\x16\xca\x2e\xaf\xca\xb7\xea\x10\x0d\x1c\x71\x4b\xaa\xbb\x71\x49\xf0\x7e\x25\xde\xe3\x23\xe7\x80\x75\x7d\xfa\x80\x16\xfa\xa7\xc0\x62\x62\x22\xc3\x65\xf8\xf2\xf6\x68\x7d\x1d\xed\x23\x4f\x79\x9c\xc5\x0d\x1c\xd2\x6b\x4c\xfa\x40\x45\x91\x70\x56\xfc\x79\xc3\xb8\x8b\x2b\x19\x08\xe3\x72\xdf\x66\xda\xc8\x73\x46\x31\x64\x83\x49\xbc\x37\xfa\x34\xb2\x5f\xff\x3b\x07\x47\xb6\xbc\x16\xb9\x4e\x3e\x58\x95\xe4\xbb\xd9\x3d\x47\x8a\x6c\x1f\x75\xe4\xfa\x30\xfa\xa9\x22\x04\x9e\xd4\xc5\x0f\x12\xf4\xb3\x12\xa8\x97\x4d\x0f\xed\x8d\x44\x25\x5d\xcb\x2b\xf0\xfe\xbe\x47\xfb\x3f\xb8\xed\x99\x03\xb5\xba\x4c\xa1\x8e\x3c\xc6\x76\x2c\xfa\x1e\xaf\x04\xdf\xa9\x44\xd4\x96\xe0\xfe\x8b\xb7\xdc\x04\x54\x51\x39\x6b\xfa\xba\x54\x85\xd9\xd5\xf3\x91\xa9\x54\xc3\x71\x42\x53\xcc\xd9\xb1\x99\x64\xd4\x28\x06\x80\x72\x07\x83\x03\x6b\x3a\xbf\xaf\x28\x84\x58\x3e\xa5\xbd\xbc\xf6\x9d\x08\x89\x7a\xb2\x88\x31\x46\x35\xab\xb4\xc2\x96\x4b\x71\xad\x92\x91\xfe\xb5\xb6\x1f\x80\xe9\xb0\xcc\x07\xf9\x12\xa8\xe5\x59\x8d\x55\x48\xde\xfe\x0e\xea\x1c\x44\x85\x73\x71\x0a\xac\xdd\xb1\x52\xf9\x3c\x7c\x6f\xd3\xf7\xe4\xed\x9f\x74\x42\xa6\xb9\x00\xf2\x3c\x3c\x54\x4c\xe5\xc9\xba\x5f\x5e\x92\xaa\xfd\x11\xc9\xff\x5f\x79\xc0\x8b\x9d\x04\x5f\xef\x07\x97\x06\x25\xf6\x2e\x2f\x43\x34\xa4\xd6\x64\xca\xf7"}, +{{0x62,0x85,0x63,0xaa,0x3e,0xe2,0xfc,0x61,0x1b,0xcf,0xf7,0x8b,0xfb,0x2a,0x75,0xe9,0xfd,0x87,0x80,0xe8,0x7a,0x93,0x94,0x99,0xa6,0x1b,0xea,0xa6,0xa4,0xb7,0x19,0x13,},{0xda,0x20,0x61,0x6e,0xe4,0xa4,0x1c,0x2e,0xbf,0xdc,0x50,0xab,0x54,0x95,0x3b,0x6d,0x38,0x7b,0x06,0xc6,0xde,0xf7,0x57,0x96,0xb0,0x88,0x09,0x56,0x5c,0x6c,0xf8,0x05,},{0xc9,0xa6,0xaa,0xa9,0xb4,0xe1,0xcc,0xe1,0xb5,0x84,0x45,0x72,0x5f,0x61,0xf5,0x52,0xc8,0xfb,0x45,0x83,0x1f,0x03,0x48,0x27,0x98,0xf0,0x1f,0x66,0x3e,0x99,0x83,0xdb,0x1a,0x82,0xfd,0x33,0xab,0xa3,0xec,0xcb,0x96,0x22,0x64,0x26,0xd5,0x0a,0xe1,0x7c,0xc5,0x12,0x74,0xce,0x18,0xa3,0x88,0x60,0xf4,0x0b,0x2f,0x82,0x36,0x1b,0x5c,0x03,},"\x05\x6f\xb9\x54\xfb\xe6\xa6\x01\x4f\xad\xac\x1e\x1a\x9f\x56\xcc\x08\xaf\x37\x34\x8e\xba\xf6\x92\x06\x83\x38\x4e\xfa\x47\x62\x6c\xcd\xdf\xea\xd2\xd5\xe9\xe8\xcf\xff\x45\xf7\xac\x63\xde\x63\xf6\x9d\x12\x84\x8c\xe3\xc0\xef\x1f\x53\x0a\xde\x43\x0f\x0a\xfd\x5d\x8e\xcf\xd9\xff\xd6\x0a\x79\x74\x6a\x2c\x5b\xee\xdd\x3e\x67\x24\x99\x82\xf8\xb6\x09\x2e\xe2\xd3\x40\x47\xaf\x88\xa8\x1f\xea\xb5\xd5\x2b\x47\xd5\xb3\xf7\x6c\x20\x41\x72\x5f\x6f\x81\x32\x93\x05\x0a\xaa\x83\x4b\x01\xa3\xa5\x8f\x69\xaa\x4a\x8c\xa6\x1f\x5b\x74\x6f\x60\x0f\x3d\x45\x2c\x62\x82\xff\xdc\xa4\x42\x9b\x93\x38\x96\x7b\xa3\xa7\x26\x66\x90\xae\xc7\x5e\xbf\xbf\x7b\xe9\x8d\x99\x9b\x03\xed\xdc\x72\x92\x58\x1b\x0d\x69\xe3\x0a\x03\x51\xa1\x51\xdb\x70\x41\x2b\x0b\xfd\x43\xd3\xba\xa9\xd4\x56\xcb\x3e\x0b\x4f\xc1\x9c\xb0\x9e\x6c\xad\xcb\x6d\x3f\x3b\xe5\x13\x7c\xc7\xa8\xd3\x21\x9e\xc2\x03\x6e\xc6\x70\xed\x7e\xc5\x23\xb1\xb1\xc6\x87\xb5\x46\x53\x07\x88\x2f\xe3\x8d\x74\x72\xd0\xba\x87\xa4\x71\x86\x83\x09\xd2\xf7\x73\xff\x24\xc8\x7d\x39\xc1\x6b\x70\x8a\x4e\xd9\xaf\x43\xf7\x4c\x8d\x85\xcf\xe8\xab\x54\x06\x90\x7e\x94\x1a\x14\x97\x0e\x20\x9c\x29\xff\x7e\xd8\xa2\xf9\x35\xae\x41\x70\x9f\x27\x0d\x0d\x08\x55\x5e\xf7\xaf\x2e\xdf\xe4\x0d\xf3\x99\x22\x3c\x78\x5a\x43\xe7\xf3\x69\x15\x89\xe2\xea\x4c\x03\x6f\x11\xd0\x3d\x7d\x1e\xea\x14\xf6\x20\x03\x53\x25\xcf\x2b\x33\xba\xf3\x86\x39\x3e\x8a\x97\x2a\x7a\xf6\xcd\x9b\x85\x43\xb3\x2e\x25\x33\xd1\xfc\xc3\x17\x7f\xd9\x6d\x1e\x13\xbf\x8b\x68\xde\xb2\x22\xf9\x44\x97\x26\x5d\x3c\xcb\x34\x57\x51\xbd\x5b\x66\x90\x78\x08\x19\x98\xd6\x08\xca\x5f\xdc\x13\x48\x39\xd4\xed\x2b\xeb\xb2\x95\x2f\xea\x5a\x39\xc6\xf0\x33\xc1\x55\x8f\x69\x8c\xe4\x94\x6e\x4f\x6c\x08\xaf\x87\x4f\x27\x35\x7f\x87\x0e\xbe\xeb\x21\x99\x97\x6f\xfa\xef\xac\x95\x1f\x8e\x17\xfe\x7d\x08\x21\xe1\xb9\x2a\x90\xaa\x4e\x9d\xef\xd3\xfa\xfd\xa0\x52\xa4\x44\x47\x6d\xb1\xce\x38\xa9\xe1\x76\xe8\x41\x18\x9a\xbd\x8f\xec\xde\x0f\xbc\x5c\xb5\x5f\x51\x1f\x5f\xde\x07\xea\x97\xde\xb3\x9b\x7a\xa8\xdc\x84\xa3\x94\x6a\x6c\xf9\x26\xd3\x9b\x95\xc1\x1a\xf9\xd6\x4d\x98\xb8\x07\xf4\x70\x4d\x0a\x2b\xda\x97\xda\xd9\x88\x1a\xda\x1b\xf6\x63\x63\x66\xe6\x0a\x52\x2b\x48\x21\x04\x78\x61\xc7\xaa\xe2\x14\x6a\x02\xee\xf6\xb2\x5d\x51\x37\x1a\x0f\x17\xd2\x4b\xc1\x87\xdc\xdd\x05\xd5\x41\xc2\xf7\x22\x01\x42\x79\x15\xa3\x92\x8c\xd3\x78\x68\x91\x03\xac\x50\xb3\x3f\x87\xa4\x7e\x8c\xdf\xa6\x87\xa5\xf0\xaf\x8a\x56\x73\x1d\xab\xe6\x62\xf4\xf2\x83\x6d\xe0\xba\x8f\xaf\xd8\x6a\x38\x54\xbc\xa0\x12\xd7\x08\x8a\x00\xb9\x85\x4c\x2d\x3c\x70\x8d\xdf\x58\xfa\xa3\x55\xa8\x9a\xfc\x2c\x80\xf3\xf5\x33\x6d\xa0\x1d\x72\xa2\x77\x1a\x05\x58\x13\xfb\x35\x33\x0f\x7d\x2e\x01\xb1\xd1\x2d\xaa\x95\xed\x55\xd3\xbd\xc5\xdf\x77\x39\xcb\xc3\xca\x09\x7a\x41\xb6\xb2\xbd\x7f\x0f\xf9\xdd\x1d\x86\x58\x98\x3b\xa3\xff\x79\x20\xc1\x5f\x29\x2a\x1e\xf9\xfc\xad\xa1\xc6\x07\xec\xb4\x5d\x3a\x73\xc9\xff\xd4\x2f\x3e\x16\x02\x2f\xdf\xe1\x27\x44\x92\x63\x95\xf7\x4f\xb3\x11\x17\x93\xfa\x92\x81\x82\x1a\x66\xa0\x1d"}, +{{0x91,0x41,0xf7,0x9e,0xd3,0x0b,0xf6,0x00,0x61,0x1a,0x13,0xf3,0x67,0xb4,0x03,0x96,0xf2,0xec,0x83,0x9c,0x56,0x12,0xbb,0xf1,0xe6,0xe4,0x97,0xf8,0x39,0x54,0xbc,0x88,},{0xf1,0x4e,0xda,0x96,0x26,0x40,0xbe,0xcb,0x66,0xc4,0xd1,0xf1,0xa0,0x21,0x11,0x02,0x51,0x91,0x7b,0x8b,0x1d,0x34,0x82,0x82,0x98,0xd3,0x21,0x45,0xba,0xf6,0xe5,0xd9,},{0xcf,0x20,0x2d,0x7f,0x2f,0x9e,0xd1,0x17,0xf4,0x29,0x50,0x2b,0x2a,0x5a,0xff,0x54,0xa7,0xf7,0x51,0xd2,0x17,0x15,0x15,0xa4,0xd2,0x03,0x75,0x34,0x46,0xdf,0x0e,0xba,0xc8,0x69,0x84,0xc8,0x8b,0xd4,0x2b,0xd1,0xfb,0x8d,0xcb,0x40,0x87,0x76,0x72,0x2a,0x38,0xf3,0x2c,0xce,0xb2,0x5f,0x32,0xa2,0x5d,0x73,0x93,0xf1,0x38,0xee,0xdf,0x0a,},"\x8f\xec\xaa\x7a\xe9\xa3\xd4\xa4\x85\x1a\x66\x36\x2b\x36\x6e\x16\x7b\x9f\x43\x00\xfd\xab\x20\x56\x54\x75\x19\x87\xf0\x85\xde\x61\xbe\xc9\x34\x4a\xa8\x6f\x5e\x5c\x64\x77\x51\x4c\x28\x04\xce\xd7\xac\x0c\xd0\x62\x85\x29\xa3\xa1\x59\x92\x36\xed\x67\xbe\xbe\x1f\x2e\x95\xaa\x15\x1f\xe0\xf3\xb3\x01\x1a\x1d\x4b\xe9\x90\x1c\xaf\xab\x2f\x18\x91\x90\x4d\x4b\xff\x01\x28\xc1\xd3\x5e\xce\xcb\x32\x2b\x3c\xc0\x1d\xac\xc5\xae\x3d\xca\x69\x14\xa7\xd3\x4d\xa8\xc9\x65\x7b\x95\x0f\x89\xd1\xd6\xae\xc3\x29\x9b\xb6\x90\x11\x10\x71\xfa\x87\x28\x27\x74\x94\x3d\x96\xa4\xab\x7c\x3d\x6d\xe7\xd1\xbf\x11\x93\x63\x06\x8c\xc8\x2d\x45\xe4\xb7\x64\x54\xc6\x08\xbc\x35\x66\xb7\xf9\xb3\x85\xcc\x7e\xb3\x8e\xe4\x29\xaf\xc2\xda\x99\x66\x9f\xc5\xc1\xbe\x82\x16\x1a\x1b\x0c\x33\xf7\xba\x9a\xd4\x41\x9d\x20\x62\x97\x19\x01\xdb\x00\x3b\xfa\x23\xc4\x47\x14\x99\x5c\xb0\x6b\xfa\x96\x6e\x50\x23\xaa\x93\x46\xfd\x37\x5a\xe2\xa1\xe8\x40\x84\x31\x4d\xf3\xf0\x8c\xe2\x08\x00\xc2\xc2\xad\xfb\xb8\x13\x66\xf6\xb1\x04\x24\x3d\x62\xd5\x04\x1e\x72\x73\x43\x3f\x17\x58\x1b\xf9\x3f\x4c\x61\x46\xfa\x96\x6f\x63\x8a\xb0\x7e\xa1\x66\x94\xa7\xce\x30\x5c\xc6\x09\xa6\xe1\x06\x23\xff\x7f\x6c\x79\x16\xb6\xe4\xdb\xde\xbb\x7b\x52\xec\xa7\xf0\xd5\x18\x7f\xf6\x64\xd7\xc3\x70\xed\x22\x88\x6a\xa2\x67\x13\x29\xd9\x28\xe0\xa3\xbe\xa3\xb4\x71\x1a\x12\x8b\x9a\xab\x90\x26\x6f\x86\x51\xd2\x20\xb9\xcc\x1c\xbf\x5b\x1c\xe7\x26\x59\x31\x80\x36\x90\xd3\x29\x1c\x01\xea\xd4\xdb\xc3\x32\x9a\x97\xe8\x5c\x4f\xe1\xd3\x56\x60\x8c\xc9\xe6\x0b\x05\xbc\x14\x83\x8a\x86\x08\x27\x9a\x00\x61\xde\x28\xff\x7b\x8e\x81\xf5\x9c\x8a\x8c\x55\x23\x92\x4c\x4c\x48\x5e\x6e\xa8\x0a\xc8\x17\x50\xbb\x0e\x41\x9e\xfc\x78\x58\xcd\x4a\xf5\x0c\x8b\x8c\x80\x65\x0f\xac\xab\x4d\x82\x58\xf9\xca\xfa\x03\x10\xa0\x07\xcc\xcb\xc4\x18\x5c\x82\xfd\x14\x6d\xf1\xd8\x11\x87\x9d\xa3\x65\x0d\x57\x16\xf1\x00\x4b\x71\xd2\xc7\xf2\xbd\x65\x03\xc3\x54\x58\x9f\x86\x02\xc9\x50\xa1\xf5\x13\x9f\x81\x14\x60\x75\x28\x80\xa3\x41\x11\x66\x30\xe4\xff\x84\x94\x8e\x74\xa9\xeb\x35\x0d\x64\xd8\x29\x30\x02\x20\x02\x33\xf2\x09\xb1\x7d\x78\x89\x7c\x7c\xe6\xce\x29\xe2\x9f\x82\xd4\xad\x6c\x61\xeb\x79\xf5\x73\x9c\xb6\x68\xb2\x1a\x74\x55\x55\xc9\x6e\x19\x52\x68\x45\xe8\x2c\x6e\xd2\xb1\xc6\xbd\xd6\x36\x4b\x8f\xc7\x9b\xa9\xa3\x2d\xbd\x3f\x8b\x97\x5e\xb9\x23\x62\x39\x58\xae\x0d\xaa\x4f\xfa\x13\x92\x17\xc0\x0e\x02\x1f\x93\x7e\x9b\x79\x1c\x37\x99\x1a\x35\xe5\x23\x1a\x19\x14\xc0\x45\xa7\x87\x43\x2f\x97\xb8\xe2\x06\x3d\xb1\x05\xe1\x4d\xa9\x79\xc1\xc4\xcb\xa7\x85\x21\x0e\xb0\x20\x11\x33\x4b\x23\x0c\xfb\x68\x31\x99\x8c\xcc\xe2\x53\x86\xf4\xf3\xba\x0d\xce\x20\x06\xe9\xc3\x94\x0b\x4d\x5a\x56\xaa\xcc\xdc\xab\x02\x71\x86\x89\x81\x63\x60\xf1\x88\x52\xfd\x19\x98\xa9\x9f\xce\x9a\x04\xda\x3f\x5e\x23\xaf\x94\xc6\xe8\xa5\xba\xdf\xd3\x93\x04\xb9\xe2\xa3\x76\xa1\xf9\xba\xc0\x9a\x85\xbd\x04\x24\x76\xe2\x6b\x58\xec\x73\xf1\x23\x6d\x41\xab\x4b\x4e\x7a\x54\xde\xf9\xd6\x6a\x38\xf8\xe5\x46\xde\x7b\x38\x8e\x1e\x7d\x66\x81\xe5\xe2\xa0\x96\xf1\x60"}, +{{0x69,0x5c,0x96,0x0b,0xbb,0x0d,0xd5,0x7f,0xfa,0x36,0x15,0x1c,0x85,0xde,0x73,0x51,0x54,0xfe,0x5a,0xd5,0xf5,0xfc,0x77,0xd0,0x05,0xa0,0xa3,0x20,0x11,0xde,0xb3,0x0c,},{0x34,0x12,0x5e,0x4e,0x21,0xf7,0x89,0xed,0x0e,0x11,0x80,0xc1,0xf6,0x36,0x9c,0x72,0x1d,0xca,0xe9,0x85,0x9b,0x6f,0x7b,0x04,0xf9,0x57,0xe5,0x10,0x01,0xee,0xde,0x8a,},{0x4a,0xf4,0x1c,0x55,0x4d,0x99,0x08,0x12,0x68,0x6c,0x32,0x9a,0x87,0x5c,0x41,0xee,0x24,0xb4,0xa7,0xfd,0x7b,0x3d,0x4f,0x8c,0x8d,0x52,0x75,0xf2,0xe7,0xcb,0x24,0x2b,0x25,0x8b,0x58,0x58,0xa4,0x66,0xde,0x59,0x5c,0xe2,0xa2,0x17,0x7e,0x35,0x1c,0x7f,0x08,0xc7,0xfc,0x4e,0x0b,0xf9,0x7e,0xc5,0xfb,0x2d,0xcb,0x82,0x52,0xd2,0xc9,0x0a,},"\x37\x06\x69\x6c\x7a\x90\x66\x90\xd0\xd3\xb7\x1e\x7e\x21\x1c\x7b\x06\x71\x68\xf3\xa8\xf1\xed\x98\x4a\x0a\x5e\x60\x78\x59\x76\x62\xe4\xe7\x88\x9d\x52\xdb\x0f\x78\xe0\xd5\xef\x0e\x5f\x7a\x0a\x0f\x42\x63\xb6\x84\x8b\x07\x25\xca\xa4\xb1\xce\xa6\x98\x74\x09\x51\x1c\x8e\x5e\x98\x2d\x3f\x5b\x82\xbb\x56\xa4\xa7\x94\x71\x21\x93\x7f\x8e\x10\x5c\x5a\x14\xb5\x3e\x6c\x37\xcc\x71\x6b\x1e\xba\x92\x24\x21\x82\x8b\x04\x6f\x68\x56\xc4\x4f\xab\xf1\x3a\x75\x16\xc6\x2a\x5f\xf9\x85\x68\x45\x0c\xee\x78\xb1\x40\x33\x50\x47\xbf\x1c\xa7\x7e\x15\x49\xa8\x94\xfe\xeb\x07\x80\x45\xe4\x64\x18\x32\x25\x3b\xf6\x95\x48\x54\x52\xec\x36\x90\x65\xa6\x00\x29\xa6\xc9\x07\x7a\x37\x9d\xb2\x04\x85\xea\x2e\xdb\x6c\x96\x95\x47\xbb\x26\x53\x28\x9b\xc6\xe8\x1f\xfc\xb8\x4b\xdb\xf7\x73\xdd\xea\x4b\x37\x50\xe9\xa7\x23\x95\xd1\x17\xf6\x44\xb0\xe2\x20\x61\xd4\xf3\xbb\x7c\x5b\x61\x2e\x4b\x70\x39\x5e\x07\x79\x51\x6b\x46\x65\x91\x16\x90\x2f\xd0\xfb\xcd\x23\x40\xee\xa4\x5e\x9c\x23\xdb\x25\x64\xa5\xe1\x1d\xc7\x9e\x8f\x4b\x33\x2a\x44\x3e\xc3\x5a\xad\x96\x04\xfe\x79\x12\x52\x08\x82\x95\xe8\x4f\x65\xa3\x07\x31\x25\x50\xd9\xeb\xf6\x1f\x36\x7e\x4a\x0f\x2b\x56\x23\xe5\x3e\xf6\xbc\x13\x28\x25\xfc\x24\xeb\xee\x4e\xbf\x33\x8c\xbf\xb5\xdf\x69\xb3\x2d\x03\x0d\x44\x7c\x44\xf3\x13\xba\x96\xfe\x07\xbb\xfe\x5b\x01\x66\xea\xec\xbc\x61\x9b\xb6\xb2\xe5\x92\x40\x10\xba\x3e\xc1\x50\xff\x6a\x69\xfe\xc4\xde\xd9\xc4\x42\xf9\x8c\x15\xe7\x7f\x31\x9b\x48\x43\xb3\xb7\x48\xb5\xd2\x60\x89\xa7\x6c\x2b\x83\x4f\xf9\x3c\x41\x3e\x04\xca\x95\x50\xcd\x21\x1c\xe2\xd6\xa5\x83\xd7\x82\x57\x50\x66\xdb\x6d\xd3\x3e\x8d\x5e\x83\x74\x35\x5d\x06\x8a\x5e\xb9\x6f\x8b\x3d\xa8\xdd\xdf\xb5\xba\xf5\xc5\x96\xda\xaf\x55\x6a\x8f\x2c\xb5\x78\x1e\x50\x42\x32\x7f\x92\xae\x06\x21\xea\xe0\x88\xb5\xf0\x13\x59\x2e\x77\x87\x3a\x81\xd7\xe0\x68\xd7\xb8\x33\x7d\xb9\xf1\x09\xa8\x35\xb4\x75\xe5\xca\xf7\xce\xa5\xaf\x3b\x4a\xd6\xd9\x0b\xaa\xf1\xc7\x36\x55\xec\x67\x67\x47\xfc\xdd\x41\x77\x5b\x4f\xbe\x39\x24\xc3\xf4\x1d\x8a\x73\x75\x28\xd1\x2d\x61\x56\x65\x3a\x22\x35\x8c\x68\x21\x42\x6b\x2c\x0a\x33\xe1\x63\x4c\x62\xc7\xc8\x38\x56\x49\xbc\x23\x3e\x7d\xaf\x94\x39\xf0\x9d\xb9\xbd\x11\xea\x01\xe2\x8b\x77\xec\xbb\xc4\x59\x0e\x29\xfd\xcf\x0f\xdd\xe1\x52\xf6\x47\x81\x32\xfe\x4c\x3a\x5b\x45\xa7\x30\x5a\xf6\xe3\x81\xca\xdd\x72\x49\x6e\x66\xbb\xb8\x66\xce\xa4\x7f\x7e\x7d\x7e\x63\x34\x16\x00\xaf\x3f\x49\xce\x9c\x9e\x4e\x37\x39\x4d\xf5\xdf\x71\xdc\x10\xcd\x39\x1f\xdc\xb8\xa1\x93\xdc\x98\xfc\x19\x05\x9f\xa3\xac\x23\x0e\xc5\x47\x6b\xf9\x4d\x85\x55\x6a\xce\x6e\x1b\xa3\x24\x21\xbf\x59\xdc\xbe\x05\xc5\xe1\x5d\x34\xc6\x64\x4e\x27\xd0\xa0\x2b\xe9\x7f\xa8\x38\x7e\xe0\x37\x06\xf2\x2a\x8f\x4b\x3b\x40\x40\xad\x7d\x3f\x8a\x86\x97\x1a\x20\xa0\x9e\xc8\x1b\x76\x96\xd8\x34\xc5\x26\xb8\xe5\x1c\xb9\x7d\x27\x64\x3f\x9a\xbf\x5e\x29\xff\xd0\x33\x3f\x95\xde\x15\xd1\x10\xc2\x06\x4c\xa4\x94\x67\xc1\x4e\xf2\x27\xf4\xba\xbf\x1a\x55\xe7\xb1\xcd\xa0\x42\x9c\xff\x25\x6b\xe3\x1c\xf1\x16\x71\x9a\x81\xb9\xc5\xfb\x75\xfd\xf6\x4e"}, +{{0x25,0xcb,0x17,0xfc,0x33,0xd2,0xbf,0x83,0x84,0xae,0x4d,0xf2,0x0c,0x1f,0xad,0x5c,0x35,0xfd,0x76,0x5a,0xff,0xde,0x04,0xb5,0x25,0x6d,0x4d,0xe0,0x1c,0xa8,0xde,0x14,},{0xb8,0x6c,0xa3,0x12,0xfe,0x59,0x85,0x20,0xc6,0x4b,0xe5,0xc7,0x2f,0x5b,0x23,0x81,0x65,0x07,0xf6,0x9e,0x07,0x0f,0x82,0x8e,0x02,0xd2,0xaf,0xcf,0xe1,0x1b,0xfa,0x01,},{0x8c,0xcb,0x0d,0xbc,0xf7,0xcc,0x03,0xe8,0x3e,0x21,0xc5,0x74,0x74,0xaf,0xd3,0xad,0x88,0x98,0x09,0x7b,0x97,0x2e,0xde,0x17,0x5a,0xca,0xae,0x48,0xe3,0xec,0x17,0xb2,0xdb,0x06,0xfc,0x82,0x77,0x6b,0x07,0x51,0xc0,0xf9,0x56,0xfd,0x71,0x96,0xf3,0xd1,0xc9,0x63,0x21,0xa6,0xcf,0x3d,0x89,0x24,0x15,0xd8,0xf8,0xee,0xb4,0xa1,0x41,0x08,},"\x4b\x4a\x71\xcb\xf8\xcb\xaf\x57\xa7\x7d\x4e\xa1\x88\xa6\xf9\x64\x84\x0f\x0d\x71\x4a\x5f\x38\xa0\x95\xa1\x3b\x4e\x57\x12\x97\xa8\x8b\x79\x24\x17\xd1\x61\x84\x42\x7f\x90\xe0\x43\xdd\x8a\x55\xb7\xf1\xc1\x3e\x00\xdf\xa6\x05\x16\x44\x5c\xbe\x77\x06\x8c\x79\xc8\xc3\x5e\xbe\xac\x33\x0c\x33\xf1\x12\x1d\x05\x73\x1a\x8f\x51\x32\xd6\x48\x00\x73\x27\x46\x41\x19\x5a\x75\x20\x21\x16\xff\xf1\xc3\x18\x81\x71\x78\xfd\xd7\x68\xbb\xdf\x10\x5f\xa0\x69\xc7\xa3\xd1\x43\xfd\xf5\xd1\x7b\xfa\xd7\xc0\x62\x4e\x52\x92\x06\x8f\xd7\xbb\x6d\x30\x3b\x4a\x27\xcb\x20\xa4\xe6\x18\x75\x07\x67\x87\xd1\x9f\xa6\xf7\x29\xc9\x4d\xc0\xba\x9b\x8c\x0b\xfd\x98\x66\xda\x5c\xb2\xe7\xa2\xcd\x2e\xdb\xdc\x95\xac\x34\x9e\x5e\x5c\x21\x72\xe5\xa4\xcf\x7b\xd9\x0c\xab\xe2\xc6\xe2\x24\x59\x80\xbd\x72\xd0\xf6\xf5\x47\x98\x81\xe8\xc4\xc3\x54\xf6\x8a\xa7\x28\x41\xd0\xc7\x3b\x98\x6b\xa5\x10\x21\x20\x31\x61\x02\x6e\xe3\xd7\x29\xdd\xf1\xa0\x49\xff\xe9\xeb\x25\x43\x98\x02\xf0\x30\x11\xd1\x44\xe5\x0b\x02\xbd\x4a\xca\x5e\x55\x06\xd3\x2f\xcf\x69\xe3\x2f\x54\x25\x44\x79\x8f\x4e\x87\xf7\x2b\xdf\x24\x33\xb1\xff\x32\x59\x29\x2e\x1d\x90\x81\x2c\xff\xd7\x9f\x6a\x54\x32\x70\xba\xf2\x4a\x3c\x39\xdd\x35\x98\xe1\xc6\x61\x61\x29\x22\x52\x2f\x38\x7d\x51\x59\x76\x92\xf3\x14\xc4\xd5\xac\x4b\xf1\x88\x3a\x61\x46\x36\x33\x6a\x55\x44\xd5\x9f\xf4\x1d\x1e\x0d\xbc\xf8\xe6\x62\x7e\x7c\x80\x85\x64\x63\x22\xdf\xc2\x0c\x33\x2c\xbd\xf3\x53\x70\xd4\x7d\xca\xbb\x80\x2e\x17\xca\x84\x78\x0e\xec\x66\x1c\x90\x4d\x5b\xfb\xc2\x40\xad\x6a\x14\xa7\x53\x3f\x71\xa2\x75\x00\xc6\x1d\xd3\xe4\x73\x98\x38\x87\xa8\x68\x35\x18\x7a\xbb\x0d\xf0\x8f\xa6\x2c\xda\x69\xdc\xe8\x6e\x21\xfa\x5a\xe9\x54\xc2\x2e\xdd\xb6\x0e\xe3\x13\x15\x04\xa6\x9b\x50\x48\x6a\x17\x76\x70\x91\x88\x37\x60\x63\x8a\x29\xc3\x80\x30\xe1\xe0\x5f\xdb\x28\xe1\x58\x63\x30\x10\x38\x5a\x62\x06\x13\xcc\x10\xd5\xa5\xf3\x50\x95\x5f\x4a\x34\x7c\x65\xed\xdd\xb7\xe2\x51\x59\xda\x8d\xcc\x26\x55\x92\x8a\xd6\xf6\xd8\xc4\xc1\xab\xb8\x17\xd7\xfe\xf3\xba\xe5\xde\x04\x02\xed\xde\xe7\xb5\x15\x21\xce\x28\x0a\x66\xb7\x96\x14\x0f\x56\xaf\x9b\xc2\x0e\x46\x58\x75\xce\x26\x28\xa8\xa1\x04\x77\xce\x9b\x2e\xac\xc7\xd8\x6f\x88\x27\x24\x57\xbf\xd4\x43\xe7\x12\x52\x69\x96\x25\x43\x80\xf0\x13\x52\x27\xe9\xfc\x15\x1c\x86\x95\xe9\xcc\x64\xd2\x72\xb2\x56\xab\x95\xc9\xa9\xf5\x68\xe9\x37\x16\xe0\xe5\x3d\x29\x88\x2e\x3c\xe7\x42\x61\x25\x7a\x02\xcd\x49\x7c\x37\xd7\x64\xd9\x0f\x7f\xd4\x78\xa1\x7a\x89\x0a\x8b\x2e\xa6\x1a\xb8\x1f\x68\x69\xb1\x20\xa2\xf6\x48\x4a\x88\xc1\x51\x95\x33\x91\xec\xa4\x45\x01\x53\x77\xb3\xa5\xdf\xfe\x4c\xfb\xac\xfb\x5b\xab\x2c\x47\xf6\x54\xf7\x2a\x9d\x19\xcb\xc4\xd2\x95\x37\x19\x84\x05\xe3\xa0\x4b\x4b\xfe\x11\xbc\xdb\x5c\x1f\x30\xd9\xac\x02\xf5\x48\x49\xc5\x7a\xa9\x6f\x7b\x56\x63\x61\x16\xf2\xbb\x6f\x25\x83\xd9\xaf\x94\xc8\x6a\xff\x5c\x13\x7f\x63\xce\x54\xe8\xf0\xc2\x1b\x6c\x25\xc1\xf0\x47\x2a\x22\x9c\x90\x81\x7e\x61\x62\xea\xc7\x1c\xcd\xa3\x09\xa1\x64\x3b\xd6\x31\x2a\x52\x63\xa2\xef\xe6\x46\xdf\xfe\x79\xeb\xd8\x15\x7a\x28"}, +{{0x49,0xe2,0x4d,0x16,0x99,0x83,0x37,0x26,0xb1,0x8c,0x78,0xea,0x65,0x68,0x40,0x1a,0x97,0x1e,0x1c,0xa3,0x9d,0xd0,0x6d,0x75,0x63,0xac,0x8b,0x42,0x50,0xd4,0xa9,0xf5,},{0x71,0xcf,0x05,0xe9,0x0d,0x30,0x1a,0x6d,0x9f,0xad,0x7f,0x0b,0x38,0xec,0x8b,0xb0,0x44,0xfc,0xfd,0x97,0xc8,0x49,0xb0,0x4c,0x00,0x36,0x25,0xde,0x29,0xbe,0x86,0xbb,},{0xa0,0xb6,0xa2,0xaf,0x15,0xb6,0xbe,0x9e,0x95,0x1e,0xf3,0xf3,0x2c,0xbd,0x1c,0x67,0x02,0xe8,0xe0,0x17,0xfb,0xd3,0x15,0xa3,0xf2,0x59,0x9c,0x3f,0x1a,0x11,0x86,0x5d,0x46,0xe7,0x84,0x59,0xa0,0xd7,0xf7,0xbe,0x04,0x6a,0xae,0x29,0x3c,0xad,0x09,0x13,0x7e,0xc8,0x47,0xe2,0x69,0x28,0x10,0x6d,0x9a,0xa3,0x5e,0x09,0x82,0xb9,0x92,0x02,},"\x6d\x26\x05\xf6\x1e\x1a\x04\xb6\xae\x18\xc2\xc2\x5a\xe1\x00\xdd\x42\xa6\x1e\x66\x4e\x2d\xb5\xc3\x4d\x7a\xd1\xf8\x4a\xc5\x07\x55\x2b\x74\x1c\x20\x86\xc1\x7c\x85\x2b\xab\xe0\x7a\x91\xe1\x29\xa5\x06\xee\x59\xed\xb9\xce\x73\xbe\x1b\x1d\x06\xd1\x20\xec\x36\xa1\xe9\x4c\x62\x81\x05\x4e\x78\xce\xb1\xbd\xef\xfb\xcb\xf4\xf0\x10\x51\xed\x38\x1b\xfc\x8a\xd1\x76\x9f\x41\xe2\x40\xbf\x60\x59\xd9\x70\x4c\xac\xec\x66\x66\x11\xf4\x1e\x4d\xd4\x38\xb7\xf5\x02\x42\xea\x86\x75\x6b\xb1\xf8\x1e\x59\x42\xc0\x92\x12\x9f\xbc\x6d\xe4\x95\x5d\x28\xdf\xf3\x52\x37\xdb\x30\xe4\xa5\x03\x6a\x99\x14\xc9\xf8\x4d\xbd\x8c\xcf\x82\xba\x2b\x1b\x3b\x55\x54\xa2\xb7\xa7\x4c\xb0\xb2\xa1\xe1\x96\x33\x45\x28\x6e\x25\x8d\xc8\xe7\xd5\x67\x18\x03\x5f\x95\xf3\x13\x81\x1c\xfb\xd8\x52\xa0\xf8\xf4\x9a\x29\xef\x93\x3e\x7c\xda\x7e\xd9\xc7\xe8\xb1\x62\xcd\xba\x1a\x82\x26\x2c\xd4\xdf\x7c\xf8\xea\x4b\x58\x6d\xb4\x3d\xcc\x1e\x37\x64\x59\x8e\x9c\xa4\x66\x73\x82\x2b\xaa\x2a\xd8\x7f\xb1\x4b\x6f\xdb\x9e\x20\x32\xd0\xca\x51\xc2\x6c\x5e\xf3\xd9\xf7\x97\x85\xfa\xc2\x49\x1c\xdb\xf7\xc3\x99\xf3\xcd\x17\x74\xc1\xa6\xb1\xe4\xa6\x7f\x54\x36\xd8\x0d\xb0\x25\xf8\xfb\x64\x09\xe2\x75\xbd\x0e\xd5\x08\xb5\xe0\x39\xed\x2e\x4e\xec\x8b\x0f\x4d\x5b\xe9\x9d\xca\xfa\x6a\x14\x01\x25\x27\x32\xa6\x5b\x37\xc9\x43\xc0\x7e\xf3\xac\xbc\xfb\xb3\xdc\x06\xda\xd0\xa8\x8f\x2f\x5e\xb5\x51\xa3\x99\x7a\xd6\xc6\xee\xd9\x5e\xdd\x9a\x0a\xf4\xa2\x88\xd5\xe4\x32\x86\xb2\xac\x07\x29\x77\xc4\x36\xb7\xc5\xff\x7a\xb6\x1c\x94\x84\xf2\x57\xf5\x8e\x01\x0c\x9b\x6a\xd4\x15\x81\xd7\x42\xcd\x19\x75\x2c\xde\x54\xd2\xb4\x20\xd6\x43\x65\x4e\x90\x96\xa8\x1e\xb9\xdc\xf8\x04\xc7\xc2\xed\x0e\x38\xd1\x3a\x5c\xe3\x99\x78\xcd\xd0\x2b\x25\x35\x09\x45\xde\x78\xfe\xec\xc0\xc2\xc2\x2f\xfd\x70\x5c\x3b\xa8\x11\x32\x65\xc7\xb9\xa7\xc8\xdd\xb5\x91\x78\xbd\x21\xd7\xf6\xc3\x1c\x6b\xe2\xc3\x67\x49\xee\x0f\x9a\xb8\xbc\x1d\xcf\x5d\xa5\xcb\x2d\x2d\x59\x62\x35\x8f\x71\xf9\x6a\xb3\x79\x2a\x25\x2a\x51\x9e\x41\x53\x51\xf4\x3e\x7e\x12\x03\x5b\x03\x28\xf2\x82\x08\xcf\x4b\xe5\x29\xd2\x99\xaa\x5c\x12\x8c\x9d\x5e\xd5\x75\xbf\x90\xc5\x35\x05\x69\xea\xa6\xf2\xd5\x52\x1d\xe1\x18\x03\x09\xf6\x86\xc9\x7e\x9a\xd6\xfa\x1e\xc1\xdd\x86\x27\xae\x89\x51\x58\x1c\xf6\x04\xb8\xb9\x17\xc5\xba\x43\x4a\x63\x7b\xe1\xbc\x8b\x79\xf4\xac\xaf\x77\x95\xf4\xe5\x1a\xab\xdb\x88\x50\x77\xbc\x4f\x3c\x68\xfc\x33\x18\xde\x58\x23\xd7\xe0\x80\x4e\xe9\x95\xb7\x03\x87\x95\x0f\x79\x93\x53\x68\x23\x00\xd4\xe7\x97\xf3\xca\xd6\x11\xb4\xc5\x62\xc8\x64\x0f\xf2\xb3\xfe\x29\x29\x16\xa9\x70\xfb\x98\xc1\x47\x5c\x1f\x4e\x27\xb9\xb3\x3c\xfe\x0d\x3a\xd9\x32\xa1\xeb\xe6\xa2\x7f\xc3\xb4\x46\x62\x29\x54\xae\xe1\x68\x36\x68\xc8\xbd\x4a\x3f\x90\x3b\xe5\xc7\x7d\xfd\xb8\xe8\x91\x4c\xed\xc5\x1f\x65\xfe\xd2\xd9\xc4\xd0\x3e\x13\xa6\x68\xd4\xc7\xea\x5e\x31\x88\x3e\x1b\x3d\xb6\x43\x63\xe2\xac\x5c\xc5\x4b\x54\xce\x69\xc6\xad\x52\xf8\x74\x99\x9b\x5d\xd2\xc5\x78\x2f\x03\xc3\xd5\x15\x05\xdf\x53\x6a\x1f\xe0\xd8\x60\xd3\x3e\xab\xed\x64\x1a\x94\x00\x89\xf1\x29\x7d\xd0\xf5\x7f"}, +{{0xf8,0xff,0x97,0x03,0x2a,0x34,0xcf,0x99,0x99,0x08,0x80,0x58,0xaf,0x56,0xff,0x70,0xb6,0xac,0xb2,0xed,0xf7,0x59,0xe1,0x31,0xfa,0xec,0x84,0x40,0xfd,0xec,0xf6,0xc4,},{0x54,0x38,0xb4,0xe3,0x3f,0x1c,0x5e,0xa1,0x12,0xfb,0x1b,0xaf,0xef,0x40,0x59,0xbf,0x09,0x5a,0x11,0x40,0x9b,0x64,0xd4,0x6b,0xfb,0x4d,0x25,0x47,0x3c,0x1c,0x08,0x74,},{0x50,0x9e,0x9e,0xad,0xfe,0x8d,0xde,0x79,0x14,0xac,0x20,0xca,0xfc,0x0b,0x0a,0xf2,0x2b,0x84,0xdd,0x8a,0x21,0x0a,0x48,0x12,0xcd,0x8c,0xae,0x39,0xb0,0xa2,0x72,0xe5,0x3e,0x02,0x24,0x6d,0xc8,0x93,0x9e,0x92,0x26,0x92,0x03,0x36,0xe1,0x40,0xb3,0x15,0x32,0xd0,0x68,0x13,0x7a,0x34,0x16,0x1e,0x59,0x9a,0x86,0x94,0xa9,0x5d,0xdf,0x01,},"\xdf\xb4\x1f\xb9\xd5\x37\x02\xcb\x2b\x9e\x3f\xfc\xad\x4e\xa6\x02\x71\x6f\x71\x8a\x7e\xa3\x3e\x21\x84\x3e\x2a\x6c\x05\x2c\x70\xc6\xc5\x14\x85\xd7\x2b\x53\xa5\xbb\x4e\x34\xe0\x3e\x3e\x1d\x1a\x52\x51\x8e\xb3\xe7\xf1\x8f\x2a\x1e\x1c\xaf\x78\xac\xb2\x11\x60\x89\xbe\xd4\xc6\x17\x13\x8e\x71\x6a\x91\x43\x1f\x2c\xf6\x44\xa1\x21\x0f\x6d\x19\x20\xd2\x85\x99\x42\x64\xd6\x46\x6b\x0d\x8d\x2c\x62\x63\x80\x44\x61\x6f\x57\x6e\xdc\x7d\x0d\x93\xcb\x66\x01\x31\xd4\xbb\x50\x87\x5e\x15\x36\x40\x12\x3a\x96\xf1\x5b\x75\xa5\xbc\xee\x46\xd5\xcc\x5e\xb1\xa4\x31\xc5\x9d\x2e\xad\xdf\xd5\x53\x15\x02\xfe\xb1\x55\x1b\xf7\x79\x1c\xd5\x98\x9d\x17\xd1\x02\x96\xd0\x1b\xa3\xae\x3e\x38\x4c\x67\x45\x26\xca\xb6\x2a\x7c\x24\xc0\xff\x67\x7d\xe7\x1c\xa1\x72\x62\x1a\x28\xa8\x5e\x01\xee\xfe\x07\xf6\xee\xf9\xc3\xec\xfd\x7f\x94\x98\xac\x42\xf4\x6a\x43\x71\x6f\x61\x53\x18\xa3\xb2\x87\x57\xc3\xa1\x5f\x4f\x1c\x38\x22\xae\x7a\x75\xc2\x03\xa2\x98\x25\x8d\x75\x36\x38\xcf\x42\x5e\x15\xbb\xc4\x62\x02\xb0\x93\xb8\xe4\xf3\xe6\x70\xfb\xb6\x63\xdb\x2b\x69\xc8\xfb\x0f\x62\x50\x74\xd8\x5a\x44\xd3\x50\xe0\x42\xbb\x1b\x74\x02\x1d\x19\x29\x97\xa2\xc2\x7d\xd6\xc8\x63\x48\x41\xd1\x00\xa0\x34\x4b\xae\xd7\x50\xa3\x9f\xf5\xdc\xd9\x84\x8d\xfc\xf0\x9e\x5c\x8c\x47\x96\x7b\x96\x55\x6e\x23\x32\xca\x17\xd8\xe4\x2d\xd8\xf3\x93\xa5\x44\x5a\x37\x22\x44\x60\x0b\x30\x01\xb8\xfe\x86\xc4\x5e\xaf\xc6\xe7\x38\xaa\x7e\x11\x7b\x4a\x79\xfa\x2e\x6b\x00\xf4\x64\x92\x8d\x18\x56\xc8\x3e\xcf\xe8\x7d\xd3\x4d\x15\x8f\x5c\xb4\xe4\xf4\xd6\x10\xf5\x97\x17\xec\x79\x0b\xd3\xff\x87\x20\x40\xb6\x7e\x8d\x39\x39\xe8\x04\xe3\xb5\xdb\x98\x5a\x09\x56\x21\xcb\xcc\xd6\x86\xc0\x93\x4e\xce\x3e\x27\xab\x2c\x6c\xe3\x3f\xb5\x2b\x11\x1f\x48\xe4\xf2\x74\xbd\xf3\x20\xd0\xb0\x23\x84\xc8\x3c\x49\xe1\xa0\x41\xbd\x23\x19\x10\x9c\x85\xa0\x6d\x80\x48\xa9\x93\x35\x7a\xbf\xd8\x11\xac\x2f\x38\x05\x9d\x07\x7a\xcb\xc3\x6a\xa9\x66\xc0\x28\x90\x37\x48\x62\x5f\x92\xe8\xf7\x9d\x51\xbd\xa1\x0f\x78\x52\x29\x77\xf7\x6e\xc4\xe8\x85\xe4\x9a\x46\xc6\x8d\xe0\x9f\x3d\xa8\xf8\x6b\x71\xae\x64\x23\xbd\x29\xde\xef\x1c\xc6\xa1\x13\xea\xc1\x15\xa6\xcd\xe2\xcc\xd0\x11\xfc\x1c\x0f\x0e\x34\x27\xf4\x3c\x3e\x96\xfc\x41\x56\xed\xf6\x2d\xdf\xb7\xb0\x83\x6b\x88\x8b\xab\x3c\x43\x45\x05\x5a\x6c\x41\x78\xe9\xe2\x28\x29\xfd\x8c\xfc\xe3\x9b\x0b\x84\x44\xeb\x26\x48\x7c\xc9\xdc\x82\x60\x6f\xea\xad\xaf\x49\x78\x69\x4e\x65\x64\xf2\x72\x9c\x1b\x13\xab\x37\xc9\x07\x2d\xb4\xe9\xde\x94\x0e\xe5\xf1\xd0\x58\x84\xae\x7f\xd9\xd9\xec\x9c\xb7\xde\x56\x34\x76\x00\xa8\x8d\xea\x92\x08\xa6\x34\x19\xfc\xe2\x9e\xe5\x00\x55\xa3\x74\xa8\xf2\x2f\x9a\xe2\xbe\x98\x05\xa9\xf4\x76\x15\xaa\x59\x57\x6b\x44\x04\x2f\xf1\x26\xa8\x98\x24\xe3\x6a\xd6\xbc\x58\xe0\x6b\xb9\x0f\xbe\xef\xba\xe5\xd6\xd7\xd6\x24\x30\xf3\x73\xb6\x29\x6f\xbf\xcd\x4d\x66\x20\x16\x83\x53\x58\x3f\xbd\x3d\x5a\x29\x2b\x95\x72\x51\x75\x34\xe2\xfb\x0b\xee\xf2\xfa\x98\xa4\x64\xe5\x91\x03\xe7\xa0\x42\x87\xf1\x5d\xad\x0f\xac\x54\x97\x0e\x77\x15\x07\x8d\x63\xec\x26\x36\x2f\x6f\xba\xbc\xdd\xea\xf7"}, +{{0x2e,0x4c,0x39,0x21,0x9f,0xc9,0x2a,0x53,0x8e,0x48,0xe9,0x5f,0xbf,0xcf,0xef,0x30,0xf5,0xa2,0x1b,0x78,0x94,0x0b,0x81,0x05,0x3b,0xda,0xd4,0x60,0x2b,0x4c,0x96,0x90,},{0xf8,0xee,0xd8,0x92,0x17,0x66,0x20,0x43,0x4c,0x7f,0x0e,0xc5,0x3d,0xcf,0xf3,0x98,0x63,0x10,0x9e,0x7c,0xa4,0xd0,0xb3,0xc6,0xc4,0xb5,0x64,0x10,0xbe,0x01,0xe5,0x37,},{0x39,0x45,0x20,0x12,0x2b,0xb0,0xa5,0x64,0x64,0x8a,0x7a,0x8b,0xc8,0xdc,0x73,0x63,0x6c,0x51,0x77,0x46,0xa3,0xc8,0xa0,0x5b,0x90,0x1e,0x72,0x52,0xfe,0xf0,0xe5,0x02,0x3d,0x90,0x99,0x1e,0x31,0x1b,0x53,0x82,0xd4,0x91,0x00,0xe5,0x26,0x33,0xc7,0x0f,0xe9,0xc2,0x6c,0x14,0x50,0xe0,0x60,0x3e,0x6d,0x45,0x22,0x99,0xaf,0x4d,0xae,0x07,},"\xc8\x7d\x1f\xba\x9d\x94\xa6\xa5\x40\x89\x80\xfc\x80\x83\x98\x0f\xd2\xd2\x52\xfa\xe5\x40\xf6\xee\xc1\x9e\xd6\x74\x6c\x29\xe3\x39\xa1\xc2\x9f\x6f\x53\xbc\x23\xfd\x6b\xfa\x43\x85\x07\xef\xf5\xda\xf9\x03\x40\x3c\xda\x70\x7b\x4d\xc5\xe8\x44\x80\x5d\x6b\x1c\xeb\x4a\xff\xf4\xb2\x32\xe8\xe6\x9d\x7d\x27\x1f\x3c\x06\x7c\x48\x54\xf3\xd9\x4f\x27\xfe\x32\x55\x81\xfa\xca\x79\xd1\xf0\x2a\x26\x29\x0a\xd2\x3a\xf7\x11\x00\xc1\x2c\x09\x15\x76\x47\xca\x9d\xa4\x3d\x76\x90\xdd\xcd\x94\xdb\x65\xe0\x00\x98\x9c\x87\x8b\x75\xa0\xff\x22\xd2\xc7\x09\x62\x59\x4c\x9b\x08\x08\xf2\x78\x46\xcc\xac\x85\x67\xbc\xe5\xd2\xe3\xb7\x60\x28\x09\xf2\x3b\x59\xcd\x71\x8a\x08\x05\xd1\x08\xf3\x1a\x63\x2a\x05\xb8\xdf\xa5\x03\x5a\xb9\x46\x1a\xeb\xa4\x16\x00\x9d\x74\xfd\xf9\xe0\x07\x20\x28\x56\x89\x0d\x2c\xff\x80\xfa\x24\x0b\x97\x8a\x48\x27\x0f\xcb\x2f\x47\x36\x97\xbc\xba\x8e\x73\x0a\x55\xc2\x87\x61\x91\x9a\x23\xbe\x41\xda\x27\xff\xea\x09\xe3\x55\x9c\xaa\xab\xf9\x51\x9e\xc0\x8e\x1f\xfa\x86\x81\x7a\xa3\xe8\x87\x4f\xa8\x16\xe7\x71\x8c\x5b\x2f\x34\x49\x67\xba\x1b\xc2\x81\x9c\x4f\x04\x5a\x97\xb4\x05\x44\xea\x61\xd7\x17\x08\x3c\xca\xf1\x1e\x9d\xdc\x04\xa3\x59\x8e\xf1\x81\xe7\xbe\xf4\xac\xef\x45\xb6\x55\x1b\x47\x8a\x0d\x77\x31\xc4\xf0\x8c\xe5\x80\x2f\x78\x25\x8d\x41\x90\x17\x66\x10\x76\xd7\xd6\xd2\xef\x39\xe5\x7c\xf9\xcd\x93\x97\xdc\xc5\xde\xbf\x64\xab\x82\xb6\x61\x59\xf5\x78\x31\x6e\x74\xcd\x49\xf5\xad\x2c\x6f\xef\x83\xcf\x08\x68\x3b\x95\x70\xa9\x46\xad\x49\x03\xdf\x4e\x96\xec\x00\x8e\x14\xa5\x01\xfa\x93\x86\xbd\xaf\x2a\x63\x99\x3c\x6c\x9b\xdf\x23\x1f\xd0\x9e\xa6\xf9\x6e\xf4\xd4\xe2\x9a\x3a\x33\x27\xcb\xf7\x4e\xa8\x31\x05\x4e\x66\xca\x86\x68\x0c\x6c\xe5\x3b\x66\xf9\x46\x5d\x06\xb3\xfa\x07\x98\xbb\x69\x05\xae\x38\x45\x59\x34\xf2\xfb\x7e\x0b\xa4\x72\x32\x89\x89\xf0\x01\x30\x86\x71\xcc\xcb\x56\x6d\x22\x2c\x72\x16\x5b\xb3\xa7\x44\xfb\x98\xe2\x21\x0f\x96\x20\x68\x0d\xf3\xe3\xcd\x14\xa8\xbd\x94\xb5\x74\x5c\x00\x16\xdd\xa7\x7f\x05\x9f\x26\x05\x3b\x64\xcf\x45\x23\xc3\xd4\x29\x11\x2f\xb6\xb3\x28\x39\x8b\xc6\x30\xa2\xe9\x06\xb9\x5a\x6c\x57\x80\xcf\xdc\x06\x41\xbe\x47\x51\xbe\xbd\xdf\x77\x24\xdc\x9c\x27\xe7\x8d\x60\xed\x0f\xd7\x36\xd5\xab\xd8\x89\x29\xc1\x79\x5d\x47\x3a\xbd\x2b\x03\x20\xc5\x40\x47\x57\x28\x82\x18\x67\xa4\x09\xa2\xff\x13\xcc\x44\xce\x35\xe5\x98\x1e\x9f\x6b\x87\xa2\x8d\x4f\xa8\xb8\x67\x5e\x50\x3f\xae\xfc\xa7\xc1\xd7\x98\x47\x37\x87\x1f\xe9\x19\xac\x41\x4e\xea\x26\x5e\xe3\x1f\x9f\x78\xf5\x21\xf3\xf4\xf8\xd0\x0c\x3f\xb7\x91\x71\xf3\xc6\xa5\xdb\xf5\xe1\xac\x8b\xf6\x3b\x4c\x3d\x8d\x8b\xc1\x21\x03\x6e\x9e\x55\xbb\x70\x2e\xa6\xc8\x6e\x92\x5e\xc0\xb9\x84\xde\xd2\xc7\x1f\x3b\xfd\x49\x32\xe6\xc4\x1b\x58\x2f\xd0\x2c\xa5\x9f\x53\xce\x29\x74\x45\x78\x5c\xc4\xca\xc2\x47\xb0\xb8\x4e\x7f\xa0\xbc\xdc\xf7\x9b\x3e\x4a\x15\x5f\x98\x78\xc1\xf6\x43\xbe\x9c\x42\xf7\xa4\xf2\x72\x60\x44\x45\x05\xc1\x84\x5b\xd5\x3b\x55\x0a\x31\xd7\x95\x3c\xc7\x38\x86\x1f\x46\xbd\xf4\x87\x0f\x3a\x77\xac\xe1\x91\xab\xd6\x3c\x45\xad\xb1\x53\x90\x9f\xb5\x9a\xb5\xdb\x9b"}, +{{0xf0,0x92,0xe6,0xbe,0x8d,0x2d,0x9a,0xd0,0x69,0xa3,0xe2,0xb9,0x76,0xd2,0x44,0xe3,0x4c,0x15,0xc2,0x8c,0x48,0xd3,0x2f,0x55,0x60,0xa5,0x41,0x85,0xd1,0x50,0x15,0x02,},{0xcf,0xeb,0x3e,0x74,0xe4,0xb5,0xc8,0x35,0x6a,0x81,0x75,0x7b,0x8f,0x1b,0xe4,0xb4,0x29,0xfc,0x18,0xfc,0xaf,0x49,0x7c,0xbf,0x8d,0x8b,0xc0,0x48,0x0f,0xf9,0x78,0xf9,},{0x63,0xcd,0x4c,0x0b,0xa3,0xbe,0x93,0x97,0xcc,0x0f,0x3c,0x1a,0xf3,0x48,0xec,0x4b,0x8a,0x91,0xe4,0x2f,0xee,0x67,0x5d,0xa1,0xd0,0x59,0x00,0xb9,0xa8,0x6c,0x13,0x8f,0x91,0x74,0xeb,0x99,0x6b,0xbd,0xf3,0x1c,0x42,0x95,0xe0,0xc5,0x78,0xac,0x0f,0x9d,0x53,0x76,0x41,0xa2,0xaf,0xd5,0xdf,0xf9,0x3a,0x39,0xc5,0xcd,0x9d,0x3c,0x48,0x0b,},"\x2c\x25\x5f\xb2\x5d\x45\xb0\x86\xc0\x71\xe0\x3e\x52\x5b\x4d\x72\x85\x78\xfb\xb6\xb0\xc6\x0d\xa9\x41\xe6\xbf\x2a\x48\x98\xb2\xd5\xb6\x98\x8c\x53\x30\x27\x85\xab\x7a\x3b\xc4\xbb\x2c\x20\x5a\xcd\x27\xd6\xa4\xcb\xdd\x1a\x0c\x08\x89\xde\xd7\x84\x26\x4c\xb7\xc0\x28\x89\xc5\xc7\x11\x3f\xc9\x0b\xbb\xcd\x31\xff\x00\x14\x32\xc0\x53\xf9\x71\x07\x3c\xf6\x71\x2f\x66\x7f\xce\x46\x98\x77\x6b\x98\xcc\x54\x44\xc6\x92\xab\xd1\x28\x81\x98\xbe\x5a\xd5\x67\x46\x09\xf7\xe1\x39\xad\x1b\x9c\xcb\x94\x3f\x8d\xfd\x9d\x12\xc5\x4e\xce\xe2\x78\x34\x1b\x2e\xe1\x27\x79\x91\xca\x62\xcd\x3b\xfe\x12\x8d\x13\x92\x96\x4e\x95\x88\xe2\xf9\x7c\x32\x17\x04\xa3\xde\x10\x61\x88\xc5\xeb\x33\x5a\xa5\xa1\x9a\xcc\x90\x67\xb4\xa9\x41\x29\xb9\xd1\xa6\x16\x7c\x4b\xbf\xb5\x6f\xb9\x76\x84\xcb\xbd\x72\x0c\x86\x86\x9e\x00\x20\xab\x07\x76\xcd\xc9\x95\x4f\xeb\xa8\x62\x12\x4b\x07\x3f\xba\x8d\xe9\xea\x9a\x38\xea\xcf\xa0\x03\xae\x4f\x1c\xdc\xbf\x15\xc3\x2f\xb6\xb9\x70\xc7\x31\x15\xdd\xff\xcd\x4f\xa3\xb7\x18\x46\x11\x0e\xde\xc2\x57\xfc\xae\xd6\x11\x36\x04\xf7\x19\x25\x72\x57\x72\x64\xb9\x90\x5c\xa6\xae\xd8\xda\xec\x13\x84\x03\xca\x41\xaa\x95\x42\x78\xa5\x72\x0b\x26\x7b\x90\xca\x16\x3a\x9b\xdf\x44\x7e\xad\xe8\xde\xb7\x69\xa3\xb4\x92\x37\xa7\x35\x16\x97\x7c\x28\x73\x45\x55\xdd\x23\x4c\xa7\xde\x49\x99\x26\x1b\xc7\x96\x0f\x53\x6b\xa8\xa3\x5a\xd3\xd0\x2c\x75\xf1\xc2\xbe\xa0\xa0\x61\x2e\x7d\x49\xc4\x03\x97\xdd\x6a\xf5\xff\x58\xba\xe6\xa6\x4b\x6a\x77\xe9\x81\xf9\x2d\x15\x9e\x0b\x2b\xd2\x05\xab\x15\x70\x52\xf4\x70\x17\xa3\xe1\x8a\xec\x94\x4d\x04\x65\xee\x00\x17\xe9\x61\x48\xa6\x12\x9f\x74\xd3\xcc\xb4\x89\xfe\xa1\x3a\x15\xa9\xb9\xac\xed\x58\xc6\xee\x0e\x6e\x84\xe0\x5f\xda\xdf\xae\x07\xb3\x34\xa9\x8f\xc3\x7f\x7e\x51\x1c\xd5\xa4\x4e\x9c\x74\xe4\x78\xd3\x49\xe3\x0e\x29\xae\xb4\x6a\x4d\xf0\x1e\x43\x07\xfe\x65\xe1\x39\x4a\x75\x8f\x6a\xda\x2f\xb1\x20\x22\x5c\xcd\x50\xa4\x90\x13\xe6\xc9\xf1\x75\xaf\x90\xf3\xfc\x8c\x57\xe7\xa6\xa9\x69\xa9\x16\xc3\xf1\xaa\xcc\x22\xf3\xe0\x1a\x07\x0c\xc4\x8e\x6f\xd8\x78\xe2\xbd\x07\x3d\xf9\xee\x6f\x05\x9b\x98\x56\x84\x04\xfc\x7e\xae\x7d\x4b\xf6\xfa\x16\xc0\xc8\x03\xc6\xbe\x84\xe8\xb7\x9c\x67\xaf\xfc\x8c\x88\xca\xbd\xee\xbc\x11\x34\xbb\x23\x86\xe2\x2b\xa4\xd2\xe9\xe0\xf3\xe1\xab\x3a\x0d\xac\x7c\x80\xdd\xee\xd7\x73\xcd\xa0\xc4\x1d\xc9\xde\xfa\x67\xfe\xa3\x77\x69\xcb\x4a\x1e\x15\x22\xd7\xe0\xb3\xd7\xc4\x63\x8b\xcd\x98\x31\x53\xd4\x78\xbe\x5e\xcf\x2b\x6a\xb1\xb4\x01\x24\xe4\x22\x2b\x8c\xaa\x46\x47\xbd\x50\xd7\x4d\x20\x39\x43\xab\x20\x93\x8d\x5f\x27\xd9\x08\xa6\x73\x67\x40\x46\xce\x2e\xf1\x8e\x85\x8b\x0a\x01\xa7\xe7\x53\x0d\xed\x0f\x8c\xc8\x9e\xf0\x9b\x73\xca\x59\x7c\xf7\x3a\xfb\xc9\xa2\x71\xa4\xd2\x3c\x92\xfe\x59\x18\x83\xc4\x40\x10\x9c\x4e\xf4\x16\x67\x0b\x7f\x2c\x59\x05\xb7\x7f\x65\xf5\x6d\x09\xd4\x02\x50\x35\x6f\x9b\x1d\xbc\xaf\x1e\xe2\xc0\xb6\x36\x96\xf8\x4d\x68\xdd\xbe\xa1\x60\x08\x51\x51\xa9\x52\x62\x74\xd7\xb8\x46\xcc\xeb\x6c\x43\x48\x09\x84\x84\xde\x3b\xb7\x23\xae\x5e\x85\x27\x6d\xf4\x9f\x56\x34\x13\x0f\xf9\x05\x75\x4f"}, +{{0x01,0xa2,0x47,0x94,0x3a,0xfe,0x83,0xf0,0x36,0xb6,0xb6,0x0f,0x23,0xd9,0x77,0x74,0xfd,0x23,0x20,0x8e,0xdc,0x31,0xcf,0x3d,0x88,0x20,0xe9,0xdc,0x63,0x66,0x11,0x03,},{0x8c,0x97,0xa5,0x8b,0xe0,0xe8,0x47,0xc4,0x8a,0x6a,0x39,0x87,0xcf,0xe2,0x50,0xa8,0xd7,0xb0,0x7d,0x97,0xf9,0x61,0xf6,0xb7,0xb7,0x9e,0x7d,0x80,0x42,0xb8,0xbd,0x7b,},{0xed,0x2c,0xed,0x1a,0x4f,0xdd,0xb3,0x44,0x2a,0x63,0x73,0x48,0x17,0x9a,0x6a,0x5b,0xee,0xdc,0xb4,0x4c,0x8e,0x98,0x8c,0xa2,0x6f,0x78,0x93,0x6d,0x2c,0x8d,0xb5,0xc5,0x16,0xd5,0x4b,0x8c,0x4f,0x08,0xd9,0x1d,0xd7,0x04,0x2a,0xb6,0xab,0x26,0xd8,0x7f,0x23,0x0e,0xb2,0xb2,0x15,0x6f,0x3c,0xe2,0x99,0x4f,0xce,0x7c,0x2b,0x0f,0x10,0x0e,},"\x08\xd8\x14\x95\xda\x77\xf4\x07\x25\x5c\xc4\x1a\x81\x8e\xef\xa7\x27\xe2\xc4\x7a\xe4\x11\xf4\xb5\x41\xf0\x1f\x81\x1d\x90\x6d\x55\xfb\x1e\x3c\x9c\x48\x4d\xf3\x05\x65\x36\x4d\xe9\xdc\xb9\xfe\xa0\xaf\x66\x11\x2f\xe7\x5f\xd1\x1a\xe8\x1d\x26\x41\xb5\x47\x58\x9f\x8b\x97\x4a\x97\xe7\x97\x6e\xd6\x92\xaa\xd6\x40\xed\xd2\x88\xbd\x86\x3d\x11\xc4\xca\x98\x36\xf9\xd7\xc1\x15\xc3\xd9\x88\x30\xd6\x42\x47\xcb\x6f\x8f\xb6\x03\xc6\x98\x11\x33\x55\x2a\x32\x04\x04\x19\x61\xbd\xd8\x3e\x2f\x9d\xeb\xa7\x70\xc0\x39\x4f\x9b\x60\x2a\x45\x35\x51\x07\x49\x21\xa3\xde\x28\x32\x13\x69\xd7\xf8\xca\x64\x0c\x45\x10\x9e\x8f\x52\x2c\x97\xed\x9f\x35\xb9\x27\x7a\x35\x0e\x29\x59\x31\xb4\x2e\x01\x35\xe9\x4a\x92\xfe\xd3\x63\xd6\xca\xe3\x92\xf7\xc4\x51\x99\x32\x7e\x24\xb4\xcf\xa5\x89\x8a\xb5\x99\xae\x7b\xd5\x0b\xd3\xa0\x0c\x0d\x00\x7e\x95\xfa\xf8\xf2\xae\x10\x38\x02\xca\x7e\x53\xb2\x79\x18\x4d\x06\x90\x5f\x57\x48\xca\x8b\xe1\xf7\x2e\x66\x8c\xb8\x32\x83\xdd\x00\x40\x64\x91\xf8\xb9\xb4\xe5\xa9\xd4\xa5\x43\x8b\x2f\xa4\x37\x1e\x0b\x05\x68\x6f\x87\x57\x5b\xaa\x79\x6e\x30\x2f\x08\xff\xc4\x25\x66\x27\x50\xa3\x3a\x0c\x9c\xfa\xa4\xb4\xd7\x04\x1f\x92\x64\xfe\xd7\xbe\x4f\x9f\xde\x2c\xac\x68\xa2\x15\x82\x36\xf6\xac\x43\x04\x7e\x91\x1f\x4c\x4e\x8b\xc6\x63\xfd\xd5\x05\x17\xdf\xaa\x8f\xbc\xd2\x19\xdd\x7a\x0e\x93\x69\xf4\x3d\x0d\xd2\x5b\x4f\x0c\xf9\x30\xf2\x0b\x7b\x7c\x6d\xb9\xd5\xbe\x0c\x6e\x19\x60\x94\x1a\x3e\x04\xd1\x41\xc0\x3e\x59\x61\xaa\x33\xe9\x02\x44\x77\xd5\x33\xc9\x95\x37\x87\x96\xbf\x22\x92\xad\xe9\x22\x69\x5b\x14\x56\x9f\xc3\x39\xb3\xd9\x08\x5c\x63\xfc\x6e\x5b\xef\x4d\x99\x0c\x80\x33\x3a\x6b\x57\xaf\x47\x8f\x93\x8e\x3e\xe7\x38\xb1\xd1\x29\xbd\x97\x6a\xfe\x68\x61\x28\xbc\xac\x08\xcc\xbe\xb0\x34\x9b\x9b\x53\x73\x13\xbc\x7b\xf5\x91\xc6\x5d\x4a\x71\x23\xad\x30\xbd\xbe\x14\x86\xb4\x28\x08\x47\x48\xb6\x50\x7f\x6f\x5e\xf6\x7c\x26\xca\x86\x2c\xf7\x26\xaa\xc1\x40\xb8\x61\xae\x0d\xc7\x4b\xb3\xc0\xb4\x89\x78\x9f\x17\x14\x5e\x9a\x85\x5a\x3e\x2b\x5d\xaa\xc4\x18\xd8\x35\x37\x33\x23\x9e\xf6\x9c\x7b\x56\x5b\x53\x03\xeb\x87\xbd\x7f\x64\x9a\xbf\x40\xa2\xf1\x35\xa2\x9e\xd2\x7e\x3b\xe4\xc1\x2c\xd6\xdd\xd2\xe5\x41\x8a\x99\x97\x43\x83\x66\x3f\x58\x49\xbf\x3c\xe5\x53\x2b\xf6\x4a\x80\xaa\x52\x11\x91\xd2\x53\x90\xbc\x19\xa4\x5e\xed\x1d\x3f\xec\xa1\xd9\xfc\xc0\xdb\x03\x1b\xfb\x48\xe4\x50\xbe\x3d\x45\x93\x35\x6d\x5b\xa0\xf3\x10\x47\xb4\x57\x74\x5f\x21\xe3\x2e\xbe\xa3\xca\x6c\x35\xf0\x5d\x78\xd8\xc3\x16\x40\xb0\xfe\xcb\x94\x01\x16\x56\x75\xc7\xf9\xcb\xb1\x9b\xc4\xb5\x67\x7c\x2c\xce\xdc\x4e\x7a\xaf\xb8\x41\x84\xc1\x91\x99\xac\xa0\xdb\x21\xcf\x50\x67\xdc\x3a\xf7\x69\xbc\xc6\x29\x35\x5f\xf7\x25\x7a\x9e\xfd\x71\xa6\xa9\x2d\x13\x0d\x35\xab\xee\x6e\x70\x60\x5b\x5c\xab\x93\xc0\x28\xfa\xc3\xaa\x23\x44\xba\x86\x1a\xc1\xe8\xce\x9a\x4b\x07\x0c\x3d\xf7\x40\xd2\x8c\x5e\xce\x0f\x1b\xc3\x1c\x2d\x7d\x1e\x5e\xcc\x76\x10\x44\x80\x93\x91\x33\xa1\x86\x60\xe4\xa3\xe4\x84\x6b\x25\x17\xbe\x3b\x8e\x7a\xfa\xfe\x07\x83\x91\xd8\xaa\x8e\x5c\x30\x13\x7e\x85\xd9\x4d\x64\xa2\x79\xfb\xee"}, +{{0x91,0xfd,0xef,0xcd,0xbc,0x99,0x0d,0x3e,0x8e,0xeb,0x60,0x17,0x04,0x34,0xda,0x10,0x83,0x1b,0x03,0x08,0x1f,0x6a,0xfd,0x0d,0x7e,0x12,0xb1,0x00,0x11,0xe0,0x2a,0xef,},{0xc5,0x8d,0x3e,0x20,0xb8,0xd4,0x7b,0xa4,0x55,0xb9,0x12,0x57,0x2d,0xc8,0x40,0x81,0x5e,0x3d,0x88,0x5f,0xa5,0x91,0x7d,0x1d,0xa4,0x84,0x08,0xb9,0xa9,0x56,0x40,0x98,},{0x51,0x01,0x12,0x22,0x3b,0x33,0xa5,0xab,0x15,0x64,0xf7,0x53,0x71,0x91,0xcd,0x29,0x2a,0x9d,0xbd,0x5a,0x32,0x3d,0x7a,0xdd,0x05,0x84,0xc1,0xb0,0xad,0x00,0xd0,0xac,0x71,0x99,0xc3,0xfb,0x75,0x8e,0x91,0x3f,0xf3,0xd7,0x16,0xc2,0xe9,0x0d,0xd9,0x0d,0x4e,0x8f,0x59,0x95,0x1e,0x87,0xef,0x8b,0x78,0x21,0x4a,0x51,0x75,0xc4,0xe6,0x08,},"\x5b\x0c\x1a\x3a\x95\xe0\xba\x74\x74\x76\x6c\x9b\xad\xfa\xe3\x4a\xb8\x60\xe0\xa6\xc0\x33\xa2\x2f\xba\x72\x11\x27\xf5\xbb\xee\xe8\xe2\xcb\xde\x1a\x1d\xfe\xb1\x8d\x55\x1c\x95\x99\x4d\x21\xe3\xeb\xc6\x8a\xfa\xe6\x85\x44\x4a\x3a\x41\x95\xbc\x75\x55\x38\x90\x3a\xcf\xa6\x71\x55\x92\xdd\xe2\x56\xe7\xa1\xb4\xc3\x63\xec\xa7\x1e\xf0\xf3\xa4\x8a\xe3\x44\x2d\x50\xd5\x66\x1b\x39\x40\x96\xb7\xec\x27\xbb\xf5\x29\x53\xf3\x04\x0c\xd2\x5b\x78\xce\x47\x55\x27\xe0\xcc\x59\xf1\xef\x9a\xe2\xe0\x59\x04\x31\x58\x2b\x2d\xf8\x14\x14\x99\x82\x9a\x2c\x5f\x7b\xbe\x35\x98\xe4\xc9\x6c\xc0\x1e\xde\x2f\x43\xb6\x56\x05\xb4\x88\x59\x37\x09\xc0\x94\xb5\xa0\x42\xb2\x85\x55\xfb\x52\x27\xa6\xd1\x56\x37\x6f\x3f\xf0\x7b\xd5\xc8\xbc\x68\x04\xd3\x9a\x32\x82\xac\x59\x70\xba\x08\xae\xbf\x75\x42\xb8\x45\xf6\xb5\xc2\x38\xc2\xce\x20\x44\x3f\x7f\x77\x55\xd7\x5f\xe4\xfa\x16\xb9\x64\x4c\xa3\xe2\x1d\x91\xa9\xa8\x7c\x68\x61\x15\x74\x8a\x16\xc0\xae\x4a\xe4\xe1\x6d\x1c\x71\xae\x60\x0b\x39\xcd\x25\xe5\x63\x3b\x39\x9f\xee\x7f\xf2\xe3\x62\xbe\xd2\x51\x25\xc6\xfd\x5c\x7f\x5f\xfa\x2d\xa2\x35\x3f\xd3\x5b\x78\x4a\x1b\x1b\x03\x19\x77\x47\x58\xb7\x39\x0c\x44\xdc\xc9\x2f\xca\x42\x01\xdf\xe1\xa3\x75\x69\xde\x05\xf0\x66\x4d\x08\xb9\x0d\x6e\x2b\xad\xc2\x1b\x92\xf9\xce\x87\x21\x42\x35\x7b\x96\x15\x08\x0a\xb7\x65\x9a\x24\x6f\xf0\x85\x2a\xdb\x17\xdf\xda\x70\xcf\x17\x54\x15\x7b\x13\xbc\x03\x2b\x4c\x5d\xeb\x8e\x10\x68\xb4\x69\x2b\x93\x16\x5d\xa3\x5e\xfc\x9d\xa8\x6a\xcb\xe6\xf8\x0f\x01\xbb\xc2\x6f\x57\x5e\xc5\xaf\x5b\x05\x0e\x98\x28\xaf\xde\x6c\x3b\x78\xe7\x33\xeb\x5a\x91\x24\x92\xf7\x65\xbc\xad\x73\x1b\x95\xe3\xab\x88\x96\xb6\x17\x58\xbf\x91\x3b\x9a\x15\x68\xf9\xc5\xb4\x60\x33\xcf\x45\xdc\xc1\x75\x0d\xa2\x06\x6c\x60\x8d\xc3\xd3\x43\x73\x8e\x84\x8d\xc3\x90\xcd\x47\x44\x32\xe9\x91\xd7\xaa\x2c\x5b\x27\x81\x42\x1e\xfe\x55\xe3\x6b\x0b\x42\xc1\xf4\x9a\xe2\x77\x48\x0b\x0f\xc5\xff\x68\x5b\xb5\xa3\x1b\xe3\xa0\xfa\x44\x82\x38\x16\x07\x70\x37\x54\x8a\x5c\x9b\x0e\x1c\xc6\xc6\x35\x04\xa4\x07\x57\x9a\x36\x32\xb3\xc9\x6f\xcd\x0d\xe5\xea\x1e\x4d\x6e\x87\xc0\xca\xf7\xb6\xca\xe3\x12\x0d\xb8\xb1\xf4\x61\x5c\xe6\xa7\x5a\x81\x65\x4f\x39\x04\x28\xb6\x4c\x21\x3e\x72\x7e\xec\x3a\xe7\xf9\xf4\x2d\xb9\x06\xf4\xde\x1f\xda\xdd\x34\xa3\xda\x2a\xeb\x12\xb4\xd9\xa1\x85\xf4\xa6\x0c\xb0\xc2\x67\x45\xf5\x30\xb4\x81\xfc\x97\x6a\x09\x3c\xe2\x4a\x30\x91\x6a\xf6\x05\xee\x94\xb0\x87\x85\x19\x3a\x94\x9d\x56\x9c\x4b\x7e\xf5\x96\x03\xbb\x62\x43\x60\xe7\xb4\x08\xd9\x8c\xa5\x09\xda\xf5\xa9\x2a\x6d\x40\x15\xbd\xb6\xf9\x7a\xd4\xff\x0c\xf0\x5c\x8f\x0c\xd5\x47\x6a\x93\x44\x26\xa0\x59\xf2\x44\x44\x46\xe5\x86\x4f\x08\x9e\x0f\x06\x75\x61\x59\x10\x66\x2d\x7c\x1e\x79\xa6\xc7\x5f\xa3\x14\xb7\xba\x2c\x64\x3b\x0d\x37\x65\x3e\xef\xe5\x93\x17\x2d\x1d\x33\x2c\x8d\xd6\x44\x92\xea\xf1\x04\xfb\x19\x57\xba\xa5\x20\x49\x44\x2d\x10\xb5\x6a\xf8\xea\xe8\xff\x82\xcd\x8f\x46\xa0\x49\x4b\xec\x2f\xcb\x9f\xad\xf1\x0c\xf7\x1a\x6e\xec\xd0\x54\x7d\xaf\xdc\x7a\xdb\xaa\x45\x03\x78\x3f\x94\x3a\x46\xb4\xad\x0e\x6d\xd7\xf2\xca\xb5\x56\x17"}, +{{0xef,0x00,0xb3,0xc1,0x81,0xf6,0x32,0x7d,0x02,0x25,0x67,0x51,0xcb,0x51,0xc2,0xc3,0x6c,0x0c,0x0a,0x78,0x07,0x63,0x40,0x54,0x8f,0x5b,0xc0,0x70,0xd8,0x6d,0x9e,0x26,},{0xdb,0x14,0xcd,0x32,0x58,0x8f,0xd7,0x41,0xe8,0xf4,0x2e,0x51,0x21,0xcc,0x81,0x1a,0xd4,0x50,0x63,0xf2,0x81,0x41,0xe8,0x3c,0x66,0x8f,0x07,0xd9,0x12,0x28,0xf0,0x49,},{0x13,0x9f,0x9c,0xb9,0x9b,0x99,0x5b,0xe6,0x58,0x8c,0xdd,0xb5,0x05,0x16,0x94,0x83,0x8f,0x9d,0x82,0xa6,0x07,0x61,0xfd,0xe3,0x04,0xb0,0x02,0x7f,0xf8,0x65,0x84,0xbf,0x65,0xc7,0x3c,0xc6,0xd2,0x53,0xe5,0x60,0xf6,0x55,0x25,0xdf,0x04,0xbf,0xe1,0x46,0xc8,0x3b,0x42,0x26,0x9c,0xf3,0x78,0x0f,0x8b,0xc3,0x92,0x43,0x78,0x94,0xae,0x01,},"\x7d\x6a\xbe\xc7\xa1\x1a\xf6\x73\x24\xce\x17\xb1\xd2\x0b\xb4\x0c\x66\x8a\x21\x9b\xc9\x5d\xf0\x5e\x32\x5d\x86\xf8\x87\x95\xe2\x64\xd4\x54\xfc\x5f\xa7\xd9\xc8\xaa\xfe\x77\xe9\x0a\x6a\xf6\xb5\x74\x53\xd8\x5b\x97\x0b\x55\x2a\x85\x6b\xa6\x59\xab\x31\xbd\x8a\x66\x0e\xb7\xd3\x58\x7b\x45\x3e\x5c\x5f\xc6\xb7\x94\x72\xb2\x6e\x8f\xf7\xdd\x6d\xb6\xbe\x35\x72\x54\x8b\x0d\x75\x4e\xd4\xd9\x85\xb8\xd9\x96\x5f\x88\xb9\x52\xfc\x4f\xa3\xb7\x61\xcc\xff\xc3\x53\x54\xdb\x0e\xb9\xc5\xa1\x71\x71\x8a\x8a\x55\x92\x87\x02\x13\x82\x7d\x36\x91\xba\xe7\xfd\x9c\x63\xf2\x05\x03\xe0\x43\x19\xb5\xe9\x53\x57\x9d\xe4\x7e\x3e\xf8\xe1\x62\x85\x49\x50\x3c\xb4\xf6\x87\x1b\xa2\x5d\xb8\x73\x47\x08\x0e\x53\x1a\x51\x7a\x8b\x72\x21\xe6\xad\x84\xdf\xf8\x32\x56\xd9\xab\x9a\x43\x3d\xe8\x71\xb9\xcb\x9c\x50\x44\x58\x9e\x67\x20\x6b\x31\x7a\x52\x06\xae\xba\x96\xc9\x2f\xd6\x09\x40\x71\xc6\x44\xfe\x52\x65\x8d\xed\x92\x20\xcf\x6a\xbd\x50\xe2\x30\x5a\x1c\x90\xfd\x66\xaa\xcf\xb3\x8e\xb0\x5e\xaf\xf6\xca\x5f\x85\xf4\x29\xcd\x57\x71\x6e\xb8\x77\x39\xa0\x2b\x64\xcf\xfa\x08\xc4\xf6\x85\xb0\x03\x10\xb5\xb4\x84\x49\x20\xdf\x21\x5a\x9f\x24\xa1\x76\x13\xae\xf8\x5f\xec\x94\xf5\x11\xdc\x8a\x42\x94\xed\xdc\xea\x11\xc0\x8c\x0b\x39\x9a\x23\xd9\x16\x38\x3e\x29\xad\xeb\x98\xc6\x5d\x41\xc7\x05\xa5\x7f\x84\x05\x20\xfa\x80\x8d\x7f\xd2\x5f\xdc\xe1\x59\xf7\xa0\x84\xd0\x62\x97\x4b\x30\x13\x2a\x57\x12\x42\xba\xff\x41\x96\x24\x6d\x6d\x75\x7b\x31\x2e\x9d\x60\x85\x53\xd2\xdc\x53\xb6\x23\xb2\xe9\x5c\x75\x38\xfb\xc5\xde\xb6\x2b\xa7\x37\x76\xd8\x5e\x51\x18\xfa\x1a\x30\x2d\x4d\x07\x6d\x99\xe1\x00\xf0\xdf\x11\x9c\x33\xfc\x66\xcd\xfe\x6f\xd4\x4d\x71\x99\x7b\x78\xc8\xf7\x89\x0c\x70\x73\x46\x05\x62\x20\xd1\xe9\xde\x88\xbc\x17\x3c\xf0\xb7\x6c\xb3\x02\x87\x7e\xc1\x6a\xf4\x6e\x4c\x31\x63\x9f\x54\xee\xdc\x16\xda\x9d\x9e\xb0\xad\x95\xbd\xa5\x45\xdf\xc4\xa7\x32\xb6\xda\x98\x14\x13\x6a\xb1\xb9\x39\x2a\x07\x1b\x02\x24\x73\xb3\x49\x05\x57\x69\x8b\x77\xe7\x44\x7a\xc8\x59\x0d\xca\xf4\xf2\x42\xad\x3d\xfb\xc0\xdf\x71\x6c\xc0\xea\x75\x36\x26\x97\x3d\xf0\x8d\x93\x5d\x17\x8e\x33\x12\xfb\xe2\xa7\xba\x9c\x50\x93\xc5\x3b\x92\x55\xea\xca\x29\xb7\x25\x78\xe3\xba\x1b\xdf\xaf\x0c\x9e\xce\x21\xa5\xdf\xf6\xea\x42\x15\x24\xf7\x0f\xc1\x90\x4e\x9a\x2c\xf7\xc5\x18\xbf\xcc\x7e\x36\x73\xee\x87\xff\x27\xe1\xca\x2a\xc3\x2b\xcb\x40\x91\xcb\x34\xa8\x2a\x71\x56\x3f\xf6\xa6\xa1\x5d\xa0\xeb\xd5\xbd\x10\x25\x6c\xe9\x60\xf4\xea\xa7\xfe\x35\xe1\x28\x88\x60\x50\xd0\x49\xfe\xc3\xa4\xab\x16\xd5\xb0\xc1\x07\x26\x7e\xae\x1a\xb8\x01\xea\x5b\x91\x98\x38\x39\xda\x1c\x48\x8c\x12\xf8\x64\xd7\xc3\xa7\x7f\x2b\x6a\xe2\x7d\x54\x01\x09\xf6\x8d\x78\x36\x4b\xb6\x27\x18\x3b\xd5\x03\x91\x75\x47\xaa\xf3\xb3\xa1\x80\x9d\xa0\x25\x77\xb3\xf0\x3a\x9a\x3f\x5a\xf4\x8c\x88\x02\xe2\x97\xc8\xbb\x63\xdb\x6a\x86\xd3\xea\x72\x7a\x6d\x71\x48\xb3\xaa\x44\x4b\x8d\x16\x8f\x38\xc6\xc8\xf2\x40\x88\xa4\x9a\xf3\x31\x77\xa3\x44\xad\xab\x2c\xf6\xe0\x8e\x0c\xb0\x37\x1e\xd5\x2b\xde\xad\x13\x2f\x77\xe7\xae\x3e\xe5\xd8\xfb\x17\xaf\xc0\xa0\xbb\x73\x11\xb9\x56\x0b\x67"}, +{{0xd0,0x71,0xd8,0xc5,0x57,0x8d,0x02,0x59,0x49,0x93,0x2a,0xa6,0xbf,0x6a,0x80,0xb1,0xcc,0x41,0x2f,0x10,0x6f,0x91,0x57,0x4e,0xe2,0x46,0x54,0xb4,0x45,0xee,0x9a,0x97,},{0x9b,0xcb,0xf7,0xd2,0x21,0x2f,0xb6,0x2c,0xcc,0xf8,0xb6,0xc7,0x68,0x03,0xa5,0xea,0x24,0x40,0x9d,0xa6,0x28,0x7e,0xfb,0xb8,0xb1,0xf0,0xc7,0xb3,0x0e,0xbd,0xd9,0x3e,},{0x0c,0x29,0x7a,0xbe,0x0f,0xd8,0xeb,0xcc,0x6b,0x77,0x19,0x98,0x75,0x5e,0x2c,0x6b,0xe0,0x7c,0x81,0x2b,0x5a,0x80,0x54,0x49,0x57,0x06,0x31,0x70,0xca,0x69,0x43,0x2e,0x72,0xb6,0x0d,0xaa,0xe3,0x22,0x95,0x8a,0x22,0x38,0xcd,0x6a,0x46,0x28,0x94,0xa3,0x87,0xee,0xf6,0x5b,0xf9,0x6f,0x63,0xf5,0x4c,0x08,0x56,0x87,0xa5,0x02,0x75,0x0e,},"\x3e\x8e\xe7\x0e\x51\xe5\x6e\xf5\x7f\x6e\x66\xb3\xa8\x84\xaa\x04\xa7\xb4\xd4\x59\x9f\xb9\xb4\x39\x96\xb3\x93\xa8\x68\x09\x35\x12\xea\x74\x1a\x0c\x6a\x94\xf4\x0c\xe4\x98\x62\xd2\xfd\x1f\x75\x51\xf4\x64\x7a\xbd\x80\x75\xbc\x1b\x74\x2a\xd4\x0e\x29\xa6\x04\x61\x30\x12\x24\xfe\x8f\x76\x92\xb1\x47\x72\x78\x2b\x4e\x89\x6b\x63\xfe\x05\xab\xd5\xff\x53\x14\xf9\xec\x80\x75\xf2\x8d\x90\x8c\xca\xaa\xce\x5e\x90\x5e\xa7\xf5\x7a\x49\x1b\x99\xb3\x59\x1e\xea\x54\xa6\xb7\x81\x91\x67\x74\x9d\x38\xa0\x47\x62\x06\x76\xa1\xa7\xaf\x11\xf4\x85\xa5\x5b\x7c\x87\x9e\x68\x50\x38\x08\x58\xc8\xf4\x5c\x0c\x1c\xcb\xd7\x40\x6e\xd0\x99\xd8\x4a\x74\x71\xb9\x35\x0c\x4d\xdb\x28\x47\x0b\xf5\xbf\x32\x7d\x5b\x3c\x22\xd8\x99\xb4\xc6\x60\x83\x9e\x10\x4a\x06\x22\xae\x85\xc8\x4a\xa9\xfc\x7f\x0a\x2c\x7c\xeb\x6e\x69\x1c\x49\xc0\x64\xb5\x31\x34\x99\x68\x3e\x8e\x03\xb2\x11\x5e\xda\x7d\xda\xd5\x5a\x49\xf9\xfb\xe6\x25\x44\xf9\x14\x51\x1c\xfb\xec\x6b\x84\xdb\xde\x7e\x80\x90\x9b\x45\xfb\x10\x50\x2e\x2c\xaa\xa7\x21\x24\xfd\x94\x56\xa3\x87\x2f\x95\x92\x70\x7e\x9a\x4c\x50\x12\xda\xa9\x72\xea\xf6\x5f\xab\xe5\x53\xde\xbe\x82\x57\x01\xef\xef\x5c\x75\x6b\xb4\x65\xe9\x66\xab\x68\xdd\x52\xf3\xdd\x00\xa4\x5c\xf6\xdc\x3f\x19\xb8\x6b\xb0\xdb\x4a\x86\xe4\x66\x98\x85\xa0\x74\x69\x6a\x67\xd8\xea\x21\x18\xc7\x66\xef\x62\x5f\x8a\x98\x02\x6f\x9f\x4a\x3c\x5c\xcc\xf9\x84\x6f\xdc\x90\xed\x93\xec\x7c\x1f\x3c\x70\x86\x95\x4f\xa2\xf0\xa4\xca\x96\xd4\x01\x84\xaa\x57\x54\x55\x27\xa1\xf9\x65\xc1\x1d\x84\x3c\x90\xc5\xa5\xe0\x8d\x7c\x11\xf2\xd5\x61\x00\x4e\x90\x57\x48\x52\xeb\x50\x46\xaa\x1e\xa7\xb6\x10\x09\xfd\x5d\xd7\xd6\x24\x2a\x8d\xf5\x8a\x9e\x8e\x55\x5c\x7f\x4c\xdc\x13\x0d\x69\x01\xbf\xe6\x79\x7f\xdc\x6c\x39\xbe\xec\xfb\xba\xb6\x62\x5b\x2e\x4f\xb9\xd8\x00\x02\x76\xd4\xa9\x4f\xc6\xfc\x10\x51\xfe\xff\xf5\xad\xeb\x72\x4b\x87\x09\x0d\xb0\xa2\xc6\x97\xd0\x56\x66\x4d\x99\x1f\xad\x80\xdc\x80\xfa\xb7\x00\xb1\xf1\xf2\xee\x27\x73\x4e\xbc\x26\xb2\xa6\x41\xc3\x2a\x0c\x91\x1b\x27\x0a\xc7\x6b\x0d\xa5\xc0\x89\x14\x97\x1c\x91\x12\x46\x3a\x70\x70\x9c\x0d\xda\xc7\x91\x00\x16\xf9\x13\xf6\x21\x00\x86\xd7\x25\x5c\xef\x11\x95\x57\x10\xf6\x51\x88\x9c\x83\x62\x1d\xd8\xa4\xfc\xd5\x36\x63\x02\xd6\xc9\xb5\x6e\xef\xcf\xac\x85\xc1\x4a\x94\x78\xb6\xd7\x18\x07\x54\x28\x80\x07\x60\x51\x5c\xab\x5f\x3d\x44\x55\xe2\xb9\x70\xdf\x9f\xe4\xbe\x83\x83\xd7\x04\x83\xbb\xdd\x75\x60\x71\xf5\x3b\x2f\x9c\x27\x5c\x7c\x85\x12\xd1\x63\x51\x8f\xe5\x55\x83\x75\x14\xc8\x67\x76\xc9\x47\xf2\x9a\x77\x57\x02\x87\x44\x6b\x69\xbe\x40\xc8\xd4\xab\xbd\x65\xef\x25\x07\x24\x9b\x5a\xec\x33\xac\xb7\xb8\xbd\x3f\x35\xbc\x85\x9b\xa4\xe3\x7b\xdb\x49\xcf\x91\x3d\x93\x98\x9c\x44\x38\xd2\xab\xcf\xa3\x88\xcc\x89\xd7\x8a\xc0\x62\x70\x65\x64\x92\xe7\x52\x8f\x29\xbd\xfe\x8c\xbb\x9b\xfa\x9e\x73\xc1\xda\x01\x3f\xc3\xce\x21\x05\x65\x76\x13\xff\x62\xbb\x0c\x3b\xf4\xde\xe3\xb0\xd2\x65\x9c\x72\x6e\x7b\xcd\x9e\x97\xec\xce\x92\x47\xd4\x60\x0d\xfe\xaf\x60\x44\x4e\xd8\x62\xb0\x0b\xa1\x1e\x70\xea\x88\xd4\xf0\xb6\xb5\x39\xfc\x9f\x36\xbb\x2a\x1a\x9e\xd2\xb3"}, +{{0xe9,0xd4,0x86,0xc2,0x9a,0xe8,0x11,0xb9,0x42,0xe1,0x0d,0x81,0xf0,0xa6,0x71,0x63,0x17,0xb8,0x42,0xc2,0xc5,0xbf,0xde,0xf5,0x5c,0xc4,0x32,0xb7,0xfc,0xae,0xb8,0x18,},{0x43,0xa5,0x2d,0x15,0xb9,0xf7,0x31,0xd7,0x37,0xb1,0xc4,0xdb,0xc3,0x22,0x27,0xa4,0x80,0x96,0x30,0x91,0xd2,0xc6,0x28,0x6f,0x48,0x2e,0xf1,0xe8,0x36,0x70,0x54,0xe5,},{0x65,0x19,0x1a,0xa8,0x85,0xdd,0xab,0x9f,0x67,0x27,0x18,0x79,0x95,0x2f,0xc6,0xaf,0xfe,0x41,0xca,0x20,0xeb,0x3b,0xcd,0x86,0x67,0x31,0x61,0xb0,0x3b,0x53,0x26,0x94,0xd6,0xdd,0x88,0x90,0x8e,0xb1,0xb1,0xee,0xc0,0x03,0xcf,0xcb,0xe6,0x14,0x6b,0x45,0x38,0xe2,0x1d,0xf5,0x59,0x69,0x91,0x2a,0x0d,0x7d,0x88,0x18,0xad,0x79,0x59,0x0d,},"\x14\xfe\x1e\xd5\xbb\xbd\x76\xcc\x73\xdc\x56\x50\xbd\xa9\x2d\xe8\x63\x26\xe2\x4d\x2f\x1f\x62\x24\xba\x85\x68\x94\x4d\x6f\xe3\x44\x26\x75\xdb\x96\xf1\xd8\x49\x8f\x16\x34\xff\x9b\x6e\x50\xcb\xa9\xdb\x4e\xb0\xb0\xb0\x21\xb2\xbe\xcf\xce\x4b\xef\x33\xc4\xce\x0e\x32\xc8\xa9\x83\x89\xec\xa9\xe0\x59\xa6\x62\xd6\xf0\x37\xc5\x4a\xa4\x0c\x76\xcd\xee\xe8\x56\x50\xf0\x89\xea\x56\xe1\x38\x3a\xb0\xf5\xc3\x6f\x6d\x66\x45\xff\x7e\x87\x66\x73\x01\xf9\x44\xfd\xc2\xed\x35\xb0\xd2\xc3\x5c\xb2\xe4\xb4\x56\x36\xe7\x49\x8e\x92\x7f\x58\x46\xb3\xe1\xed\xfb\xd1\x60\xa4\xae\xf3\x32\x0c\x34\x28\x49\x6b\xda\xaf\x7d\x3e\xd5\x6e\xf0\xb7\x25\x4a\xc5\x97\xbe\x58\x9a\x70\x58\x44\x16\x30\x0c\x1a\xdc\xfb\xa4\xf2\x2c\xfd\x4c\xd6\x61\xe1\xf5\x0f\x15\x5d\x17\x2f\xa5\x74\x8d\x29\x6b\x29\xcd\xd7\xeb\x81\x21\x48\x3f\xf1\xd9\xfe\x95\x3f\x94\x51\xc7\xc7\xa5\x42\x00\x72\x85\xee\x72\x46\xbc\x0f\xde\xa9\x38\x81\x40\x29\xab\xce\x05\x7a\x0e\xcb\x97\x4b\x12\xd3\x60\xea\xb6\xaf\xd3\x07\x97\xd6\x14\x45\xad\x2b\xac\x7e\x52\xbc\xe4\x34\x63\x15\xf7\x8e\xb8\x75\x42\xd5\x95\x28\xb2\xf6\xc5\x6d\x66\x24\x1c\xb4\x42\x03\x3f\x64\x3d\x3d\x2a\x67\xcb\x63\x7d\x8d\xa9\x5d\x4f\xd1\x23\x4b\x03\x1a\x3e\x51\x72\x3a\x1d\x26\xe6\xf5\xca\x07\x98\x73\x21\xad\x11\xa9\x0f\xcc\x1d\x4e\x2b\x0b\x89\x66\x50\xc3\xa7\x51\x8d\x56\x55\x29\xbe\xa8\x06\xa0\x5d\x44\x7e\x08\xd2\xa6\xa3\xdb\xf1\xa3\x69\x15\xb2\x95\x7c\xa5\xb4\x0e\x58\xb9\x7a\xd0\x36\x97\x35\xc4\x28\xbd\x6d\x69\xbd\x21\x00\x44\xb6\x51\x41\x8d\x98\xb0\x59\xd9\x0c\x83\xe4\x60\x11\xf4\x1c\x03\x2c\x56\x55\xa5\xef\x21\xac\x2c\x8c\x2b\xc9\x4b\xe0\x7e\x45\x42\x6a\x7a\xe5\xd4\x7b\x45\xf2\x7c\xf4\x28\x9c\xa4\xdd\xab\xe0\x8a\x12\xb9\x10\x20\x7d\xab\xb3\x4a\x46\xab\x75\xce\x69\xb5\x8e\x7e\x17\x66\x4b\xf3\x35\x9a\x8f\xb6\x8e\xb0\x32\xc9\xea\xa6\xdf\x87\x38\x29\xf0\xe0\x84\x85\x53\xf7\x32\xe1\xc3\xc0\x84\xb3\x2b\x7a\xf7\x50\x74\xe7\xbb\xaa\x4e\xb5\xd7\xea\xd7\xaf\xf9\x75\x80\x10\x9b\x60\xf4\xc7\x92\xf9\xe2\xa6\x51\x37\xb0\xaa\x48\x17\x5b\x81\x15\xd9\x13\x05\xf4\xc7\x7e\x2d\x08\xe7\xe8\xd7\xe7\x78\x5c\x96\x68\x42\xc2\xe3\x50\xfe\xd4\xf9\xe3\x3b\xf6\xe1\x84\xc5\x50\xb4\xb0\x6e\x95\x74\x14\xed\xf5\x2f\xa0\x79\xe8\x19\x73\x45\x84\x61\xfb\xb9\xb7\xd7\xd3\x4b\xef\x15\x03\x57\xf4\x32\xca\xac\x3a\xe9\xf3\xdc\x96\xeb\x5a\x2d\x12\x3e\x09\xed\xa1\x70\x2e\x1d\x10\x70\x17\x7b\xb2\x20\xc4\x23\xc0\x96\xec\x24\x42\x43\x85\xc6\x79\xbe\x02\xef\x84\xd0\x9e\xd1\x02\xf4\x9c\xad\x3b\x1f\xd6\x70\x67\x9a\x39\x71\x4f\xf1\xd6\xe4\x22\x8d\x8d\x7d\x0e\x19\xed\x0e\xba\x13\x2f\x21\x28\xd4\x7b\xaa\x56\x9a\x8e\xcb\x7b\xd4\x8a\x82\x62\x82\xf9\xcf\xcb\xf6\x0d\xde\xce\xaf\x1d\x02\x13\x2c\x8a\xff\xed\x3a\x03\xd2\x34\x0d\xeb\x78\x7c\xd6\x49\xc5\x1c\x6e\xcb\x9f\xf7\x5d\x7a\x7b\x4e\xf9\xb1\x51\x39\xcf\xea\x27\x62\xab\x18\x61\x51\x97\xa6\xb5\x1f\x6e\x75\xdb\xd0\x45\x73\xa2\x44\x80\x94\xd0\xcd\xeb\x0f\xe4\x58\x58\x83\xff\x9b\x68\x82\x4a\x04\xb8\x3e\xc9\x1c\xf8\x4a\xcd\x6a\x74\x46\xcb\x1f\x5e\xe3\x7d\x5d\xf8\x0f\x17\xcb\x2b\xdc\x3f\x31\x22\xa8\xfa\xf7\x6e\xbd\x06\xcf\xe8\x17"}, +{{0xe6,0xfa,0x10,0xdb,0xb4,0x78,0xe1,0xe3,0x6b,0x35,0xdf,0xeb,0x02,0x50,0xf6,0x3c,0x08,0x51,0x50,0x70,0xae,0x79,0xb2,0x2f,0x04,0x7e,0x27,0x17,0x08,0xd6,0x4f,0x5c,},{0xe0,0x2e,0x1f,0x2b,0xd8,0x79,0x2e,0xf4,0x83,0x48,0x1c,0x6d,0x11,0xf7,0xc7,0xc9,0xdb,0xde,0xec,0xc9,0x85,0x94,0x32,0xe7,0xf2,0x79,0xe9,0xd1,0x73,0xd3,0x11,0x64,},{0xc0,0x3c,0x47,0x03,0x59,0x12,0x7e,0x9d,0xe3,0xaf,0x0e,0x0e,0xd7,0xd3,0xb1,0x9f,0xae,0xe0,0xec,0x14,0x0b,0x79,0xc2,0x99,0xe2,0xcb,0x6d,0xac,0x0a,0x3e,0x7e,0x31,0x41,0x41,0xcc,0x85,0x4b,0x45,0x96,0xce,0x4c,0x51,0xc7,0xb0,0xde,0xc8,0xa5,0xc8,0xcf,0x09,0x36,0x20,0x53,0x61,0xd5,0x36,0x5f,0x4b,0xcc,0x07,0xc4,0x28,0x7c,0x07,},"\xad\x31\x60\x75\x8d\x8c\x08\xa6\x61\x52\x5c\x95\x28\x0a\x37\x18\x87\x49\x69\x85\x9f\x1c\xc9\x18\xe3\x4f\xec\x00\x8a\xcf\x23\xb8\x89\x6e\x8d\x50\xc3\xc0\x51\x23\x31\xdc\x89\x78\x0f\x8b\x10\xfc\x34\x9c\x67\x5c\x4c\xd8\x2a\x5d\xf8\x58\x6b\x43\xc8\x64\x44\x8f\xac\x00\xb8\x47\xb9\xc9\x80\x54\xab\x79\x3f\x63\xc7\x1a\xa5\xe5\x24\x8e\x22\xd0\x69\xbd\x3f\x85\x2a\x3b\x8c\x6e\x2a\xc8\xef\x86\x1d\x90\xbc\xd9\x84\xbf\xca\x87\x58\x3e\x59\xe9\xa7\x46\x8f\x29\xb8\x08\xdc\x2f\xe5\x30\x2a\x98\x9d\x6f\x2e\xcd\xe7\x58\x5c\xd9\xbe\x4e\x4c\x76\x1c\x4d\x4b\x3e\xea\xf4\x69\x9f\x65\x56\xef\x03\x9a\xf2\xb8\x0f\x94\x07\x60\x5a\xc3\x97\x35\x1d\xd8\x55\x95\x58\x44\x95\xba\xa1\x77\xb0\x8c\x88\xd2\xec\x1f\xc4\xe3\x2d\x1c\x0b\x8d\x7e\x7a\xc5\x83\x9d\xfb\x92\x3f\x09\xb3\x23\xe7\x8e\xce\xb7\xe9\x6c\x06\x04\xb0\x1a\x19\xe4\x9c\x9b\xea\xf4\xf2\x5e\xc4\xa8\x4c\x1a\x08\xf2\x38\x0e\xdd\xc3\xa7\xf0\x12\x18\x49\x59\xcc\xd1\x9e\xcb\xba\xc6\x5e\xac\xa1\x55\xce\xe9\xec\xfe\xc1\x1e\x7f\xee\x05\x8e\x17\x4f\xc4\xed\x7c\x67\x9f\x2c\x15\x63\x1d\x4e\x15\x27\xbc\xdb\x0e\x3b\xb0\x81\x5f\xfd\xff\xc0\xc8\x56\xbe\xf0\xdc\x0f\x5c\x82\x37\xf7\x09\x8e\x26\xbd\xb6\x9e\x87\x82\xd1\xca\x51\x11\xec\x3c\x7e\xdb\x42\x5d\xff\x80\x32\x02\x6c\xba\x3d\x2e\x08\x1b\x71\x31\x0d\xb9\xba\xda\xd1\xad\x02\xf1\xec\xcc\x53\x7d\x87\x4c\xd1\x8c\x6b\xb0\x12\x21\xf7\x1e\xe6\x62\x50\xd9\x4c\xf8\xec\xce\xaa\x96\xd3\xc5\x7e\xea\x2b\x0a\x8e\xc7\x24\x29\xd7\x60\x64\x88\xbd\xf1\x9e\xc3\xbb\x16\xe5\x08\x67\xc7\x93\x7d\xef\x09\xfc\x78\x3f\x20\xa2\xa5\xec\x99\x25\x3d\x6b\x24\x0d\xf4\x67\x7d\xd2\xd5\x27\x7b\x01\xc5\xb8\xe5\xbd\x6c\x7d\xf0\x87\x42\x05\xbc\x8c\x2f\xff\xdb\xa1\x31\x46\x74\xd3\x1c\x9b\x2c\x91\x99\x22\x8e\x19\xe0\x42\x18\x34\xc1\x65\x7d\x06\x98\x28\x69\x16\xc7\xe3\x92\xf0\xab\xd5\x54\x5b\x96\x3a\xc1\xff\xa9\x97\x21\x61\x6c\x23\x79\x6f\x85\xc3\x4a\x5c\x66\x4a\xe8\x1d\x16\xb2\x16\xa5\xb0\xcf\x5b\xc6\xb5\xa9\x08\x29\x72\x85\xd6\x16\x44\x12\x8f\x88\x6f\x38\xaf\x9e\xdd\x25\x19\x3d\x7e\xcc\x77\xa7\x99\x94\x27\x8d\xa0\x71\xf5\x44\x95\x93\x7f\xee\xf5\xa5\x19\x57\x52\x7c\x3e\xec\x7c\xb0\xb4\xe8\xaa\x7a\x4e\x85\x6d\xef\xd5\x7d\xd9\x23\x34\x15\x1b\x98\x6a\xa6\x9c\xa6\x92\x60\xd1\xe2\xd7\xb5\x3c\x05\x67\x7e\xe0\xd2\x16\xb2\x8d\x03\x62\x52\xdd\x30\x06\xde\xbe\x1b\x65\x74\xa2\x5e\x6b\x19\xdf\xb4\x8f\xa6\x43\x16\xaf\x8f\xd6\x8d\x78\x93\xb3\x97\xe7\xdb\x57\x80\xab\x27\xbf\x87\x26\xff\xf6\x05\xd3\xb4\x6d\x80\x05\x95\xb4\x62\x4b\xee\x30\x2c\x96\x43\x26\x03\x4b\x52\x34\xd1\x75\xdf\xdc\xc2\xce\x88\x2e\x65\xb3\xd9\x3a\x04\x38\xf6\x92\xe9\x69\x5d\xe1\xf2\x4c\x70\xa7\x9b\xee\xd2\x54\x15\xec\x5a\xae\xcf\x33\x91\x95\x3b\x2f\xfd\x45\x3a\x8f\x04\x67\x56\x1a\x4a\x47\xee\x14\x4a\x43\xfd\xff\x83\xdf\x2b\xea\x5f\x66\xa7\x22\xb5\x2a\xbe\x86\x13\xf2\x0c\x59\x4a\xf0\x98\x2e\xb3\xf0\x45\x05\xa5\x24\x61\xdd\x03\x4d\xa8\x6c\x36\xca\x16\x21\x77\x05\xc0\x48\x23\x91\x1d\x72\xa2\x47\x69\x51\x76\x33\x56\x28\x86\xf2\x50\xf2\xcf\x78\x8b\x8f\x32\x86\x4a\x94\x74\xf5\x7e\x62\xe5\x7d\xe8\xfd\xaf\x95\x9a\x6b\x72\x28\x74\x40\xa8"}, +{{0x05,0x8e,0x36,0x80,0xb8,0xfc,0xc0,0xaa,0x14,0x90,0x08,0x9c,0x11,0x24,0x67,0x7f,0x98,0xd7,0x4b,0x1b,0xfb,0x71,0xee,0x86,0x63,0xf0,0x25,0xf0,0xd9,0x46,0xcd,0x20,},{0xec,0x72,0xce,0x0e,0x82,0xc6,0xa3,0xb2,0x12,0x43,0xd2,0xf0,0x0e,0x9e,0x88,0x3a,0xdb,0xc5,0xcb,0x63,0xb3,0xd9,0x36,0xef,0xa5,0x0c,0x07,0xcb,0x92,0x91,0x48,0xe2,},{0x57,0x34,0xec,0x50,0xa7,0xf8,0x2e,0x48,0x53,0x6b,0xdc,0x43,0x70,0xcf,0xef,0x2e,0x15,0x0a,0x63,0x1d,0xab,0xaf,0x89,0xed,0xcf,0x0f,0xda,0xbe,0x4f,0x58,0x39,0xf4,0xf5,0xfb,0xd8,0xdf,0x8e,0xc4,0xa3,0xac,0xd4,0x0a,0x8b,0xfb,0x96,0x3d,0x18,0x55,0xff,0x92,0x74,0xdb,0xc3,0x31,0x65,0xb5,0xe6,0xd3,0x7a,0x23,0x9d,0xac,0xe9,0x03,},"\xe6\x3d\x14\xf5\xbe\xa7\xa1\xab\xb8\xfe\xe6\x97\x74\x6c\x22\x80\xdf\xd0\x62\x2d\xe7\x35\x72\x26\xcc\x07\x42\x72\x2a\x32\x29\xbe\x12\x6b\x08\x3e\x86\x8a\xea\xf0\x7d\x2f\xc9\x7a\xdc\x33\x42\x70\x96\x74\x19\x3c\xa2\x81\x74\x4e\x85\x0e\xa1\x54\x40\x05\x0a\xec\x93\x0e\x45\xd7\xa8\x7b\x8a\xc8\x01\x5c\x89\x67\xc2\x00\x33\xa5\x32\xd2\x95\x91\xb1\x35\x58\x6c\xe0\xfd\xd2\xe6\x68\xb5\xc8\x64\xb3\xbd\xe7\x0c\x7e\x71\x9a\xd2\x41\x93\x12\x51\x86\x19\x33\xff\xbf\xa9\x64\x83\xff\x82\x85\x67\x48\xc5\x6d\xc2\x6e\x25\x7d\x69\x2e\x51\x34\xd8\x2f\xc7\x19\x1c\x11\x0d\x95\x90\xd3\xfc\x75\x1c\xd6\x36\xb0\xc4\x6f\x44\xf8\x80\x3e\x59\xe2\xf9\x3f\xa0\xcb\xe2\x47\xa1\xa6\x25\xb4\xbc\x2c\x7b\x1f\xdc\xeb\x5a\x2b\x22\x59\x1f\xa6\x13\x7c\x54\x04\xdf\xec\x6a\x69\x63\x9e\x3f\x63\x2b\x59\x76\xab\x9f\xe1\xc6\x3a\xa3\xda\x9d\x52\xb0\x44\x00\x8f\x3a\xe4\x4b\x7c\x36\x4f\x08\x56\x64\x32\x3a\x88\xeb\x45\x83\xe8\x71\x40\xf7\x63\x78\x2b\xff\x88\x19\xcf\x74\x1a\x87\x5d\x50\x6c\x92\x9d\x34\xbb\xd4\x30\x07\xde\x4b\x18\xf6\x87\xa7\x58\x11\x11\x28\xb1\xdb\x86\xfc\x5a\xd2\xfb\x9f\xca\xd1\x2c\x9d\xd2\x8f\xee\x5a\xd1\x0d\xe0\x73\x9f\x8e\xfd\x9b\xff\x66\xf8\x40\xb1\x1b\x3f\x91\xc5\xe0\x7c\x21\x45\x2c\xab\x24\x24\x2b\x6e\x32\x16\x5c\xd1\xe6\x95\x72\xbf\x21\x6e\x86\x04\x53\xda\xd2\xfd\x12\x9c\x33\x37\x58\x58\x0b\xb7\xd0\xf1\x95\x09\x74\x5e\x85\x14\x63\xd1\x27\xa5\xf9\xbe\x21\xfe\x54\x9c\xae\x55\xd5\x6b\x8b\xea\x80\xbf\xaf\xda\xc1\x0a\xcd\x83\x8e\xa8\xaf\x31\xc0\x07\xdc\x32\xbf\xd7\x40\x82\xd9\x11\x0a\x3e\x91\xe6\x1e\x03\x57\x58\x7e\x4e\xd3\x28\x27\xad\xe9\xb6\x91\x0a\x98\x8c\x1d\x3b\x2d\xd2\x2c\x0e\xe7\x6e\xf3\x5f\xe1\x5e\x09\x94\x04\xa4\x5d\x4b\x2a\xca\xb9\x12\x3e\xcc\x45\x55\x0a\x40\xfa\xf8\x33\x6b\x46\xc6\x30\xa9\x08\x03\x58\xff\x8b\x8e\x58\xaf\x0b\xcc\xbd\x35\x01\x0c\x1e\xcc\x12\x81\x66\x55\xa5\xec\xeb\xa9\x5a\xd3\xf5\x03\xa1\x8e\xc5\xbe\xce\x3a\x33\xf4\x69\xdf\xe9\x17\xe1\xc5\x5e\xf1\xd8\x1e\x5a\x75\x56\x1e\x6b\xbd\x99\xc6\x53\xa6\xd0\x95\xb9\xf3\x87\x91\x1e\x40\x33\x2f\x62\x16\xf9\x56\xa3\x5c\xf7\xd9\x9a\x9f\xdd\x0c\x44\xc5\x1e\x90\xa5\x64\xf1\xc3\x6b\xf3\xd4\x0a\x7f\xaf\x4b\xa2\x8b\x1a\x12\x0b\x32\x05\xfb\xac\x1a\x98\x56\x92\x90\xbe\x37\xc5\x8b\xbd\x74\x5c\xe0\xfb\x74\x83\x52\x70\xab\xa2\x25\x2a\xda\xec\x15\x7d\xc4\x24\x61\x22\x1a\x2c\xff\x68\x7b\x9e\x65\xce\xb5\x7c\x2d\x77\x70\x0a\xea\x63\x20\x48\x6c\x5b\x1b\xec\x9c\xc5\x3e\x7e\xf9\xe4\x8f\xcd\x1b\x77\x83\xac\xbe\x75\xa6\xbe\x02\x67\x27\x88\x12\xdb\xf3\xd2\x57\x6c\xf7\xad\x39\x11\x27\x1a\xce\xbe\x0f\x2c\x04\x60\x2a\x08\x0c\x8b\x96\xc1\x20\xfd\x86\xfd\xa2\x82\xaa\x4e\x1c\x13\x1f\xe9\x7c\x90\x7c\x15\x85\x5f\x87\x75\x5f\x51\x1c\x03\x7b\xef\xad\x0f\x56\xb3\x9f\x32\xa2\x13\x3a\x22\xf3\xd5\xa9\xbe\xc3\x44\x3f\x29\xa6\x94\xe9\x7f\xe0\x5e\x10\xfb\x8e\xf9\x99\x13\x02\xb9\xe0\xd8\x4d\x92\x9a\x19\xeb\x03\x47\x1f\x3a\x86\x13\xd3\x93\x68\xe1\x58\x83\xa7\xe4\x97\x0b\x53\xcb\xaf\x29\x29\xd8\xde\x43\x1b\x48\xb4\x35\xd7\x53\x3c\xaa\x2e\x36\xce\xab\x6c\xdd\xb3\x46\xe5\x35\xe5\x15\xc4\xb3\xdb\x76\xde\x07\xd9\x85\x54\x14"}, +{{0x51,0xba,0x3a,0x4f,0x3d,0x85,0xd1,0x54,0x8c,0x2f,0x24,0x94,0xa3,0x51,0x1f,0x3b,0x95,0x15,0x66,0x3d,0x7e,0x85,0x37,0x0f,0xb6,0x15,0x02,0x37,0xe9,0xbc,0x98,0x0b,},{0x77,0x49,0xde,0x02,0x10,0xbc,0xe0,0x6d,0x48,0xf5,0x9b,0x95,0xae,0xb1,0x52,0x8f,0xd9,0xb4,0xe5,0x2c,0xdd,0xe2,0x2f,0xb8,0x19,0x3b,0xed,0xd5,0xdf,0x12,0x81,0x7c,},{0x16,0xfb,0x29,0x0c,0x91,0x3b,0x20,0xeb,0x1c,0x3d,0x7b,0x79,0x82,0x49,0xeb,0x84,0x59,0xd4,0xbe,0xe8,0x12,0x5d,0xb2,0xb3,0xf1,0xda,0xab,0x8a,0xf9,0xd9,0xa7,0x00,0xed,0x79,0x8a,0xdd,0xd8,0x02,0xdf,0xcd,0x29,0x7a,0x41,0x25,0x93,0xcd,0xa7,0xbe,0x99,0x79,0xa1,0xf0,0x93,0x50,0xe8,0x6f,0x69,0x8a,0xc3,0x38,0x0e,0x34,0x1d,0x07,},"\xd1\x8d\x0c\xbf\xc1\x6d\x0f\x9b\x67\xf2\x53\x9a\xd6\x20\x7c\xd9\x21\x7a\xd5\xed\x03\x33\xcd\xdb\x10\x41\xe0\xac\x2b\xdd\x92\x02\x76\x62\x96\x52\xb4\x9c\xbc\x98\x02\x59\x3e\xc3\x64\xea\x79\x5a\xbc\xd1\x58\x20\x85\xf5\x5b\xc6\x6c\x48\xfd\x3e\xed\xe6\x18\xd6\x36\x96\x17\x10\x0e\xae\xcc\xc1\x5f\x24\x9d\x6e\xee\x5b\xb2\xc4\x3c\x01\xb0\x62\x3f\xe6\x03\xce\xee\xe4\x9b\x40\xfb\x7c\x53\xfc\x68\x47\x36\x73\xc0\x9b\x1a\xc7\x7e\xa9\xbe\xb7\xe8\x53\x03\x79\xa8\x6d\x69\xec\xd1\xff\x11\x81\x3f\xbb\x88\xf6\x92\xf0\x5e\xf1\x32\x07\x42\xb4\xfe\x7e\x06\xd5\xba\x71\x65\x66\x46\xcd\x75\x00\xde\x19\xbb\x93\xd8\x44\x53\x66\x03\xf4\x0b\xd4\xae\xea\xf0\xc4\xdb\xc0\xac\xfd\x20\x2b\x28\x6b\x64\xaf\xb8\x3d\x4a\x37\x8d\xd4\x5e\xe3\xc1\xdf\x6b\x3e\xf1\x6b\x8b\x1a\xcc\xbc\x04\x06\x32\x50\xec\x47\xb8\x6a\xe5\xa7\x1d\x1d\xab\x38\xb5\xeb\x80\xd6\x63\xfa\xa7\x88\xf8\xb5\x9a\x75\x4c\x0f\x9c\x9f\x6d\x90\x62\x52\xaf\x46\xab\x1f\xff\xed\x27\x6d\x23\x88\xdb\xe7\x0d\x96\xba\x67\x47\xd1\xfe\xd4\xfc\x0b\x55\x29\x3d\x5f\x78\x7b\xda\x0c\x0d\xf4\x6a\x73\xf4\xaa\x7d\x29\xe1\xc9\xcc\x85\xcd\x04\x3e\x3d\xff\xe0\x57\x46\x2c\xa5\xfe\x5c\x64\x70\xe7\x39\x27\x6f\x8b\x53\x4c\x01\x72\xe4\x60\xf3\x40\x48\x7a\x56\x94\x68\xaa\x58\x90\xcc\x14\xf2\x0d\x67\xd7\x9c\x66\x1e\x87\xfe\xba\xc6\x27\x59\x71\xc3\x73\x08\x07\xeb\xf1\x75\xe0\xde\x10\x49\xbe\xe6\x7c\x89\x5e\x57\xb7\x1a\xb8\xa2\xf3\xcf\x36\x41\xfd\x54\x8d\x09\x41\x4f\x5f\xc3\x02\x6a\x0a\x35\xf6\xba\x95\x16\x73\x94\x49\x41\xcb\x23\x6f\x3d\x19\x76\xdc\x69\x07\x7d\x95\x14\x50\xe7\x66\x03\x16\x98\x8f\x6f\x2a\x6f\xbb\xff\x3b\x37\xce\xaa\x02\xfd\x6f\x02\x73\xbd\x80\x31\x85\xa1\x09\x03\x9c\x63\xf2\x51\x9b\x98\x3d\xaf\x65\x54\x25\x3b\xed\x54\x97\xc0\xb0\xbd\xaa\x0b\xd4\xa1\xfa\xc9\x00\x26\xad\xe3\xe4\x0c\x55\x4c\xff\x2c\xcb\x36\x99\x0e\x71\x55\x67\x08\xc5\xc4\x03\x92\x56\xff\xc7\x33\x7e\x5f\xea\x11\xf5\xe9\x0d\x3e\x4d\x93\x35\x91\x79\x11\x6a\x85\xc2\x41\x36\xca\x34\x83\x5c\xd3\x40\x12\xe4\xd7\xdd\xc7\xb7\x21\xc2\x46\xc7\x37\x00\xe2\x76\xdc\x2f\xf9\xf2\x77\x0b\x43\xc8\xe8\x0a\x17\xf0\x1d\x32\x68\x0b\xae\x22\x8e\x64\x23\xa8\x80\xc3\xfb\x99\x6a\xb8\xd2\x21\xbc\x62\x74\xac\x5f\xa7\x70\xd2\x05\xfc\x87\x8f\xba\x9b\xbd\x77\x6a\x3d\x79\xed\x77\x04\x89\x50\xf3\x6d\xc0\xaa\x3c\xcd\x28\xe4\x75\x6a\x99\x19\x04\xae\x05\x1b\x8a\x4b\x7d\xe3\xa1\xf2\xad\x0f\xb4\x5a\x33\xd0\xc6\x82\x25\x84\x1f\x8e\xb6\x5b\x6a\x16\xe9\x5f\x89\x35\x91\xe1\xaa\x73\xa6\x4f\x0d\x2e\xe9\x38\xab\x69\xad\xcc\x8c\x59\x51\x8b\xec\x50\x1c\x39\xf1\x39\x17\x4b\xbb\x00\x69\x9e\x1a\x0f\x0e\x0d\x88\x9a\xae\x54\x3a\x55\xe6\xac\x56\xd5\x20\x4c\x1a\xde\x1f\x27\xd8\x2a\x6a\x95\xe1\x4b\x2d\x69\x09\xdd\xa7\xbf\xaa\x7f\x48\x7f\xb6\x19\x59\x01\x4b\x78\x79\x5c\xb4\x63\x9f\x09\xf0\xd3\x29\xfe\xb3\x5c\xcf\x52\xed\xc2\xdb\x72\x19\x14\xe4\x23\x30\x68\x89\xa4\x83\xfe\xe8\x76\x36\x0e\xe3\x26\x33\x53\x19\x07\x0c\x56\x4f\x3a\x8b\x95\x3f\x52\xf4\x15\x13\xa2\x26\x08\x83\xc3\x8d\xd9\x78\xa2\x48\x60\x4a\x41\xbd\x4b\xfc\x9e\x84\x18\x4d\xc9\xe8\x4d\x25\x89\xf4\xaf\xff\x84\x17\x82\x4c\xe5\xad\xba"}, +{{0x7d,0xde,0xc5,0x26,0xa4,0x97,0x1d,0x89,0x12,0xa6,0xbd,0x43,0xc6,0x9f,0x92,0xed,0x86,0x44,0x2b,0x15,0xf4,0x2f,0xba,0xbb,0xf2,0xd1,0x7e,0xff,0x98,0x99,0x31,0x61,},{0x0d,0xfe,0xff,0xb2,0x76,0x23,0x09,0xb4,0x73,0x4e,0x4c,0xe2,0x52,0x3c,0xf1,0x86,0x31,0x49,0xf7,0xe1,0x9a,0x7c,0x14,0x7e,0xc0,0x89,0x9e,0x11,0x0c,0xa9,0xd8,0x7d,},{0x9e,0x60,0x3b,0x01,0x5f,0x42,0x87,0x1b,0x78,0xeb,0x27,0x52,0x3f,0xbb,0x7c,0xe9,0x62,0xfc,0xa3,0x2a,0xe2,0x70,0xe8,0xe1,0x2d,0xca,0xdd,0x25,0xaa,0x85,0x2b,0x89,0x1f,0x6f,0xef,0x77,0xb5,0x9a,0x54,0x6c,0x9a,0x7a,0x7c,0xac,0xb5,0x5e,0x1d,0x32,0xad,0xc8,0x05,0xae,0x5f,0x61,0xa6,0x9e,0x67,0x64,0xc7,0xc0,0x82,0x92,0xeb,0x03,},"\xe8\x77\x4a\x45\xd4\xd8\xf8\x6d\xda\x5c\x08\x80\x2b\xa2\x47\x2e\xf3\xc8\xd3\x6c\x7f\x38\x3a\xc0\x46\x12\xa4\x64\x38\x2e\x9d\x6c\x07\xd8\xd3\x58\x22\xc5\x3f\x43\x88\xf5\x15\x36\x14\xfe\xfa\xf4\x63\x74\x74\x7b\x9d\x4f\xd4\x46\xa8\x64\x76\x9a\x4c\xad\xe8\x43\xc1\xea\xb8\x57\x43\x19\x11\x2f\x01\x79\xd2\xea\x9e\x3c\x19\x5d\xc0\x68\xf0\x69\x74\x62\xb9\xe0\x7c\x87\x94\x87\x0f\x8f\xb8\xff\xc0\x81\xe4\x58\x6a\xfb\xcd\xba\x7a\x4f\x59\x25\xe9\xfd\x9e\xc9\x42\xd8\x43\x47\x33\xc2\xdd\xd5\xe2\x9b\xbd\xfc\x73\x42\xb9\x28\x68\x71\x9b\x54\x40\x88\xa4\x8e\xba\x4c\x82\xf1\x87\xdd\xca\x8f\x47\x46\x25\xa7\x1c\xf6\xb7\xaa\x5f\x08\x1c\x74\xf7\x40\x8f\x53\xb7\x81\x63\x6e\x7e\x9d\x29\xb0\x7f\xdb\x6d\x9c\x35\xe5\xeb\x38\x2d\xb7\xa3\x1a\x8b\xa5\x16\x91\x5d\xf8\xde\xe9\xe1\xad\x3f\x18\x28\x43\x68\x3e\x8d\x1d\xc5\xd8\x66\x9d\xbf\xcf\x09\x54\x1a\x43\xc0\xa0\x46\x13\x38\x1a\x5b\x5e\x4e\x71\xb2\x3c\x5a\xd0\x9b\x8e\xaa\x51\xcb\x93\x8d\x0c\x75\x2c\xc3\xd3\xa1\x0f\x10\xb4\x2b\xe8\xee\x7f\x6b\xda\xc8\x07\x85\x68\x43\x49\x46\xbb\xf5\x6d\xa7\x0e\x7d\x54\x15\x7a\x6e\xfd\x48\x46\xeb\x15\x52\x78\xc9\x4c\x38\x88\x65\x8a\x7a\x2f\x8e\xa3\xba\xc1\x47\xaa\x89\x16\x92\xae\x8b\x23\xf1\xaf\xe7\x1e\xcf\xde\xca\xa6\xc1\x13\xb5\xca\xaa\xa1\x93\x98\xc7\xdf\xe7\x3f\xac\xb4\x15\x5f\xd6\xba\xc1\x8d\x5d\xf2\x12\x9e\x8b\x29\x07\xec\xee\x15\x1b\xdd\x14\x7a\x7c\x3e\x46\xea\x72\x75\x4d\xe3\x2c\xeb\x06\x6d\x9d\xb1\xc2\x6e\x80\xdf\x36\x31\x29\x2b\x16\x17\x4c\xfa\x6f\x1d\x9c\x08\x28\xb8\x49\xc2\x2d\x29\x65\x1a\x73\xe9\x10\xd9\x27\x58\x77\xf4\x64\xce\x93\x26\xc6\xe4\xed\x6b\x07\xdc\xb3\xa3\x53\x63\xc1\xaa\x64\x72\xe0\x2c\x5c\xd8\x55\xe3\x8a\xab\xe9\x65\xac\xe9\xf3\xf5\xa4\xf5\xde\x03\x00\x86\x94\xcb\x90\xaf\xe4\x16\xc9\xd4\x86\x88\xde\x7f\x75\xcf\xe2\x43\xff\x7f\x41\xe0\x59\x31\x09\x34\x90\x3d\xb5\x68\x84\x45\x08\x26\x2c\x89\x9d\xfa\x75\x0c\xd6\xa2\x82\x98\x24\xba\x02\x7a\xea\x1b\x6d\x01\x77\x72\x6a\x34\x3a\xdd\x4e\xcd\xc5\xf7\xe6\xe9\x09\xab\x7d\xe6\x15\xef\x28\x07\xf9\xe7\xd7\x1c\xe2\xf7\x8a\xcf\xf5\x7e\xba\x79\xc3\xf5\xe0\x7c\x8b\x66\x1c\x1e\x30\x27\xf8\x17\x6d\x28\xbf\xef\x76\x7d\xd6\x8d\x4e\x5d\x62\x8f\xec\x0b\xfe\x88\x79\x93\x41\xf3\x06\x12\x87\x34\xfa\xd2\x02\xaa\xfc\x9f\x11\x12\x3f\xb3\xe3\x63\xd1\x0a\xee\x0d\xb5\xe2\x7a\x15\x70\xdf\xae\xe4\x7e\x24\xda\x47\x3b\x07\xfe\xe5\x9a\x6c\x93\xf0\x98\x1d\xbe\x32\x5c\xd8\xcc\x2d\x2e\xd7\xdc\x17\x16\x6b\x26\x7c\x1b\x11\x05\x36\xf2\x63\x6b\xba\x34\x75\x1a\x78\xf7\xf6\x29\x81\x82\x44\x2d\x83\xc1\x23\xbb\xee\x4f\x50\xc5\xb0\xfa\xcf\xf0\x3e\x7c\x55\x6e\xd9\xe6\x4c\xa2\x7c\x4b\xca\x5a\xb0\xde\x0d\x5f\x9c\x2c\xbb\x54\xcc\x2d\x94\x73\xa3\x2d\xf9\x99\x39\x0a\xc2\xff\xee\xd3\xd4\xcb\xa3\x49\x73\xdc\xec\x3f\xba\xba\xfc\x4d\x54\xca\xe4\xe7\xe8\x5d\x4a\x6e\x8a\xfe\x45\xca\xcd\x71\xe0\xf2\xe6\xd0\x4b\x4f\x9d\x3b\xcf\x43\xd3\xfa\x41\xe9\x98\xcc\xbe\xd0\xf1\x50\xd5\xca\x1d\x52\x72\x93\x2d\x93\xec\xa1\x04\x95\xc6\x83\x34\xfa\x32\x68\xf3\x1d\xe5\x22\xcb\x12\xa7\x44\x9f\xfb\x5c\xb5\xe8\xf1\x46\x2c\xd9\xb5\x17\x70\xcc\xaf\x58\xb1\xe0\xd8\x2e\xf9\x29"}, +{{0x0b,0x65,0x90,0xdd,0x7c,0x2f,0x15,0xf9,0x4a,0x56,0xe2,0x40,0x16,0x93,0x63,0xc2,0x67,0x32,0x30,0x2b,0x9d,0x44,0x0b,0x53,0x27,0x23,0x00,0x2e,0x15,0x5d,0x02,0xd9,},{0xcd,0x18,0xe0,0x32,0x57,0x7c,0x55,0x76,0xf2,0x23,0xf3,0xe3,0xd8,0xa1,0xfa,0x8e,0x9a,0x87,0x0f,0xef,0x09,0xe9,0x40,0x9f,0xaf,0x40,0xd7,0x14,0x3e,0x52,0xfc,0x44,},{0x64,0x2d,0x81,0xac,0xf3,0x8c,0xf0,0x99,0xa8,0x33,0xa7,0x4f,0x2d,0x80,0xb8,0x54,0x48,0xec,0x2b,0x1a,0x5d,0xdc,0x64,0x47,0x0b,0x21,0x3d,0x54,0xb7,0xbe,0x61,0x33,0x68,0x9a,0x71,0x94,0xf5,0xd8,0x97,0x92,0xe1,0x6e,0x5d,0xf7,0x55,0xa4,0xfd,0x9e,0xf4,0x68,0x9e,0xa9,0x52,0x92,0x6e,0x0e,0x4e,0xcb,0x3b,0xd4,0x81,0xfd,0x91,0x02,},"\x71\xfe\x0f\xd5\x5d\x5e\xd1\x20\x6f\x28\xee\x16\xe4\x19\xfa\xb6\xfa\x66\xa2\x51\xfa\x6b\x06\x01\xda\x26\x1e\x42\x9f\x55\xb8\xd5\xae\x3f\x3c\x52\xa1\x7f\xe1\xec\x73\x4b\x81\x0a\xb6\x3a\xad\xe4\x44\x70\x39\xca\x0a\xe4\x68\x7c\x24\x35\xf5\x61\xe4\x6c\x5b\x30\x97\x17\xab\x31\xe0\xf6\x40\x76\xb2\x16\x92\x11\x57\x2b\x74\xe1\x8a\x1f\x45\x25\xa6\x4f\xa7\x17\xa5\xed\xf1\x49\x75\x81\x29\xcb\x04\x03\x5e\x7e\x20\xba\x40\x05\xb7\x48\x09\xde\xc6\x44\x50\x4c\x24\x54\xa7\x7f\x99\xb2\x0c\x53\x74\xf3\xce\xe7\xd8\xc6\xb6\x8b\x24\x3c\xaf\xb3\x00\x98\xdc\xe9\x04\x90\xfd\xc3\xb9\x2f\x54\x94\x8f\x42\x46\x39\xe1\x9f\x8f\x20\x20\xd1\x55\x13\xda\xef\xad\xd9\xe9\xb1\x2a\x84\x76\x1e\x5e\xce\xa0\x88\xad\x56\x1f\x06\x20\x9f\xd4\x42\x3f\xcd\x00\x3f\xbc\xd1\x87\x3e\xa5\x49\x63\xa2\xfa\x07\xc7\x47\x6b\x13\x88\xf9\x01\x5d\x9e\xac\x30\x5b\xea\x5a\x3d\xe1\x94\xf5\x5a\x17\xb4\x2d\x59\x9e\x5c\xe6\x2c\x8b\x7c\x19\xe7\xe7\x09\x61\x37\xb9\xd0\xa6\x5e\x63\xc1\xa3\xb8\x45\x38\xca\x65\x36\x9a\x20\xe8\x82\x2f\xff\x5e\xcb\x57\xfc\x09\xb4\xe6\x84\x5b\x4f\x24\xd4\x88\x69\x71\xac\x1a\xc2\x8c\x77\x58\x0e\xa5\x67\x2a\xd1\x4c\xe4\x44\x17\x19\xc2\x14\x54\x6d\x07\x36\xcb\x7a\xd0\xbd\x9f\xb5\xb2\x6c\x6d\x9c\x53\x6b\xf8\xc8\x57\xae\x42\x57\x7b\x36\x34\x1d\x39\x2b\x43\x32\x3b\xda\xe7\xdf\xaa\x49\x19\x86\x87\x2a\x23\xd8\x27\xc6\xef\x8b\x57\xe7\xd0\x0f\xea\xe3\x83\x4c\x46\x64\x00\xaa\xd1\xd3\x67\x82\x39\x84\xaa\x02\xd2\xef\x49\x29\x14\xae\x11\x27\xe7\x55\x1b\x81\x25\x59\x37\x83\x05\xe4\xfd\x52\xd8\xbc\x7e\x41\x57\xec\xca\x45\x1f\x43\xee\x9f\x54\xc8\x21\x53\xc7\xdb\xfa\xf7\xec\x35\x23\x87\x73\x05\x1b\x4e\x58\x7d\xb1\x36\x95\x7e\xc5\x71\x38\x2b\x90\x59\x0b\x5d\x10\x26\x02\x45\x80\x96\x6b\x72\x52\xd2\xcd\x3f\x4f\x16\x25\xc4\x85\xba\x90\x6b\xff\x17\x59\x92\x18\x89\x78\xf2\xd6\x27\x4f\x3a\x03\x17\x49\xba\x7e\x70\x2f\x56\x54\x7e\xdc\x96\xec\x26\x7b\x84\x89\x28\x80\xd7\x50\xd7\x31\x0e\xbf\x6d\xb2\x41\x25\x3c\xab\xe4\xb2\x5a\x97\x74\x58\xc6\xff\xc9\xe3\x53\xe6\x2a\xdf\x05\xe6\xef\xc0\xfc\x1e\xbe\x89\xf5\x27\x70\x5b\xcc\x26\xb7\x01\x28\x56\x10\xd9\x8a\xa3\xbf\x23\x87\x2b\x69\x96\xd3\xde\x48\x0e\x8d\x09\xd7\x83\xc4\xa0\x8c\xd3\x83\xc9\x01\x26\x35\xaa\x68\x97\x8b\x50\x06\x81\x8b\xbd\xe4\x4f\x29\x87\x47\x9b\xcb\x2b\x71\x1c\x1b\xee\xed\x27\xcf\x09\x97\x0a\x16\x4e\x45\x4f\x71\x08\x22\xee\xf5\x55\xc1\xc7\xbf\x9f\x76\xd5\x25\x4c\xe2\x20\xc9\xaa\xa7\x16\x84\x7a\x24\x94\x88\xf9\xcd\xb4\x4c\x48\xf4\x52\xab\x52\xc4\x0f\x6d\x03\xad\xc8\xbf\x3f\x19\x7b\x25\xe3\xd1\x27\x83\x0e\x74\xfd\x81\xeb\x14\xf7\x54\x20\x5b\x3a\x48\x44\xc5\x96\xb6\xe3\xa9\x93\x6a\xd6\xfd\x9e\x80\xa1\x63\x20\xb3\x81\xc3\xff\xc7\xb6\x9e\xab\x54\x53\x6f\x55\xab\xe2\x2c\x91\xd8\x98\x40\x8e\x88\x0c\x6d\xbf\x0f\xa5\x64\x8d\x51\x77\x72\xca\xa5\x35\x3b\x25\xdb\x60\x50\xd7\x53\xfa\xf1\x98\xec\x1d\x37\x5d\xe0\xfa\x72\x18\x0a\x93\xba\xb0\x3d\xed\x77\x16\xcb\x87\x50\x5b\x68\xac\x6a\x35\xe7\x3d\x0f\xcf\x34\x45\x7e\xff\x82\x17\x89\x52\x14\x2c\x7b\xac\x9d\xfd\x87\x2a\x9a\x82\xf8\x5b\x24\xb8\x8f\xa4\x2d\x4b\xe0\xa0\xca\x0b\x2c\x70\xf4\xc6\x22"}, +{{0xc6,0xd9,0xac,0xc5,0x17,0x5f,0xa2,0xb8,0x96,0x5c,0x15,0x8c,0x56,0xba,0x0a,0x5a,0x66,0x6a,0xd2,0xc7,0x40,0xcd,0x5b,0xb6,0x79,0xbb,0xa9,0xb1,0xdc,0x50,0x92,0x84,},{0xf5,0xcf,0xca,0x21,0x1b,0x02,0xfb,0xa7,0x72,0x03,0x47,0x70,0x3b,0xf1,0x63,0x1c,0xb3,0x08,0xfa,0xbc,0xda,0xa6,0x74,0x29,0x52,0x7c,0x5b,0x7b,0x67,0x6d,0xba,0xef,},{0x4d,0x2c,0xe7,0x07,0x09,0x0b,0x0f,0x3f,0x41,0x46,0x2f,0xd7,0x5b,0xd6,0x09,0xa2,0x72,0x4f,0xad,0xfe,0x5c,0xa3,0x90,0xe3,0x13,0xa4,0x2c,0xab,0x42,0x86,0x8e,0xd6,0xe9,0xa8,0x91,0x4d,0xc1,0x39,0x09,0xc0,0xd6,0xf6,0x1e,0x63,0x71,0x29,0x57,0xc7,0x6f,0x3b,0xd8,0xb7,0xf5,0x53,0x49,0x71,0x5a,0x3a,0x31,0x75,0x15,0xc0,0x71,0x08,},"\xf2\x45\x10\x0c\xd2\xd3\x16\x48\xf5\xf3\x51\xbd\xa5\x64\xc9\xdb\x4a\x35\x82\x0c\xc3\x0e\xf6\x51\x33\x7c\x4c\xd8\x88\x07\x05\x69\xd1\x17\xa9\x34\xb9\xc9\x18\xe5\xdf\x8b\x37\x44\xdd\x66\x20\xcc\xbc\x49\xf6\xb3\xe5\x78\x2a\x30\x33\x9d\xbb\x9c\xbe\xd0\x5d\xd2\xb3\xb8\xc5\xbf\x15\x46\xe7\x0a\xf6\x36\xe6\x61\x5c\x48\xb2\xc3\xc2\xd1\x9f\xe3\x54\x20\xdf\x53\x14\xf6\x3c\x48\x12\xb5\x8e\x82\xa2\xa6\x0b\x18\x02\xf3\x8e\x50\x5c\xe7\x48\x01\x7a\xfa\x97\x7d\x3f\x9b\x1b\x6b\xea\x21\x92\xac\xec\x73\xbd\xce\x12\xd6\x5e\x68\x4d\xa4\xd8\xb4\x1f\xa9\xa8\x6f\x11\x08\x6e\xdc\x2d\x52\x96\xf6\x7e\xfc\x53\xac\x84\x07\x0f\xde\x13\x69\x3e\xb2\x31\x8f\x5a\x8c\x3b\x11\x7c\x23\x34\x22\xad\xcd\xd3\x52\xf3\x28\xf0\xec\x69\x9a\x46\x50\xc9\x3f\x9b\x4a\x7d\x79\x5d\x7f\xc2\x62\x2a\x03\xd9\x9b\x64\xf7\xb3\xdc\x31\x94\xf6\xc3\xb1\xb6\x9d\x99\x07\xce\x09\x24\x01\x07\x3f\x47\xa2\x8f\x47\x99\xd2\x29\x09\x2a\x1b\x07\x41\x29\x95\x4b\xe8\x0c\xa4\xa3\xe6\x58\x2e\xe0\x5c\x30\x2c\xac\xb7\x43\x1d\x1c\xa6\xa4\x51\xaa\xed\x72\x78\xab\xc7\xf7\x85\x75\x24\x1c\x2a\x2e\xea\x2e\x84\xcb\xf9\xa3\x34\xdf\x40\x21\x09\xc0\x28\xe3\x45\x47\x3a\x13\xaf\x9b\x00\x8e\x20\xbc\x8c\xf0\xbc\xef\xbb\x7a\xa7\x27\xec\x85\x6e\x99\x25\xb4\xdd\xd9\x9d\xeb\xa8\xf2\x52\x91\x1a\x59\x01\x54\xb5\x79\xa8\xaa\xa3\x1f\x07\xdd\x50\x25\xdf\x5c\xd8\xa0\x9f\x74\x29\x64\xcc\x8c\x36\x5d\x8a\xff\x4e\xb1\xd7\x9f\x6e\x5a\x07\xda\xc5\xf4\xed\xe9\x2b\x4e\x2e\x61\xd3\x4c\xc2\xd4\xf0\xaa\xaa\xb0\x37\xad\x5f\xdb\x95\xde\x6c\xd5\x98\x4e\xba\xf7\xcc\xe7\xf0\x8d\x0c\xa0\xdb\xbe\x48\x3c\xe3\xcb\x35\xcd\x79\x0c\xa0\x42\x70\x65\xa3\x4d\xf7\xf4\xc2\xaf\x86\xef\xe9\xb7\x65\x71\x3a\xff\x25\x7f\x5c\x1d\x54\x70\x95\x27\xad\x18\xac\x33\xab\xcd\xee\xdb\x20\x80\x64\xeb\xae\xa4\x83\x5b\xe4\x94\x2b\x8f\xc6\x66\xad\x1b\x79\xb6\x65\x13\x09\xe5\xea\x1d\xa3\x02\xd7\xfb\xa2\xe9\x9f\x0e\x63\x19\xe8\x2b\x99\x05\xa1\xea\x48\x2b\xa0\x43\xb6\x80\x0b\x33\x0d\xc4\x8b\x33\x13\xf5\x9b\xb2\xf9\xe8\xa7\xf0\x7e\xb1\x80\x0a\x70\x27\x45\xdb\x14\xc6\x29\x9a\x98\x2d\xad\x89\x79\x54\x44\x5b\x7d\x98\xeb\x58\x37\xfd\x70\xbf\x19\x0c\x64\x95\x52\xc8\xe8\x6f\xeb\x7f\xf5\xb3\xed\x8e\x0a\x06\x70\x4d\x45\x53\xa3\xc2\xdd\x74\xf1\x8e\xa8\x23\x3a\xe0\xa5\x0d\x91\x4f\xe0\x8f\xbc\xd3\xa1\x43\x5f\xed\x56\xa9\xf3\xa7\xef\xfa\x14\x0f\xb5\x52\xdd\xd2\x1d\xff\xff\x7f\xa4\x73\x32\xdd\xfc\x1e\x53\x17\xf4\x17\x7d\x5e\x2f\x11\xa0\x6e\xc8\x4c\xcf\xb8\x9b\x65\x4e\xa8\x1b\xd4\x2d\x7e\x07\xa3\x87\x30\x1d\x0f\x40\x26\x4a\xbb\xf9\xf9\x10\x7b\x30\xed\xe8\x64\xcc\x76\x90\xc0\x6d\x2e\x24\x7a\x06\x0b\xb2\x24\x4a\xd7\x8e\xd5\xc5\x51\x5a\x1a\x2a\x61\x2d\x61\xe3\xd9\x31\xe2\x8b\xc9\x39\xb4\xd3\x43\x5e\xee\x4f\x73\x31\xb1\xf0\xf8\x53\x75\xd8\x2a\xc9\xa7\x7c\x43\x74\x00\x32\x05\x17\x46\xdc\x92\x69\x45\x8c\x14\x7d\x18\x8d\x84\x40\x19\x54\xa4\x89\xcb\x4f\xbf\x9b\xf8\x4b\xa7\xd8\xf1\x00\x90\x3c\xe6\x78\x31\xb4\x05\x4d\x0f\x58\xcd\x88\x3d\x54\x2c\x49\x33\x10\x3f\xf0\x70\xcd\xfc\x9d\xbb\x0f\xcc\x31\xef\xca\x46\x6e\x77\xa3\x3f\x1a\x81\x3d\xa6\xdc\x0c\x7c\x31\x58\x5e\x8f\x4f\xef\x1e\xbf\x42\xfb\xd1"}, +{{0x7d,0xfa,0xe4,0x16,0x41,0x9d,0x7b,0x0d,0x4f,0xc1,0xf8,0x23,0x84,0x0c,0x3e,0x4b,0xd4,0xad,0xcd,0x4d,0xc2,0xdc,0x17,0xb3,0x86,0x37,0xac,0xed,0xac,0xbd,0xbb,0x45,},{0xbc,0x51,0xd7,0x74,0x59,0x31,0x31,0x7e,0x1e,0x34,0x6e,0x2e,0x7c,0x92,0x03,0x91,0x81,0xb6,0xbf,0x38,0xee,0x2f,0x5a,0x44,0xfb,0xe2,0x33,0x9c,0x4f,0x95,0x2a,0xb9,},{0xda,0x34,0xb1,0x98,0x3e,0x8c,0x55,0xe4,0x1f,0xda,0x8e,0xc8,0xab,0xf2,0x3b,0x36,0x7a,0x0d,0xa6,0x06,0xc8,0xcd,0xbb,0x1e,0x8b,0x57,0xe0,0x34,0x3c,0x05,0x57,0xa5,0xf0,0xe8,0x15,0xe7,0xf2,0x2f,0x86,0x05,0xae,0x93,0xb2,0x7d,0x03,0x77,0x6a,0xc1,0xf7,0xde,0x3d,0x79,0x2e,0xa2,0x93,0x3a,0xc2,0x2d,0x2d,0xc2,0x3b,0x32,0x3d,0x0c,},"\xec\x84\x3d\xc4\xdd\xa6\xe9\x02\xe9\xbe\x31\xb7\x0f\x11\x76\x3b\x75\x7a\xb6\xce\x73\x34\xdc\x00\x76\x4b\x2d\x08\x4e\x9d\xaf\x24\x84\x48\x59\x84\xee\x28\xa2\x83\x0f\xcb\x94\xc5\x41\xcb\x46\x94\x40\x03\x67\x31\xde\x80\xff\x56\x0f\x53\x0c\x9d\x9e\x6e\x1f\x7d\x9c\x4c\x5b\xdf\x50\xb0\x4f\x54\x03\xc2\x9f\x76\xd7\xe3\x6e\x00\xbb\xea\x35\xdb\x1c\xc6\x0d\xa8\xd7\x76\x52\x62\x66\xc3\x32\x4c\xe7\xef\xec\x64\x50\x85\x96\x09\x26\x68\x56\xd7\x01\xa4\x7a\x48\xde\xe8\xbf\x37\x40\x95\x65\xc7\xfb\xfa\x99\xa2\x04\xe5\x53\x0c\x97\x1c\x60\x5b\x44\x30\x5d\x5c\x74\x67\x89\x41\x14\x25\x3c\xf4\x3c\xdd\xf1\x8b\x62\x96\xdd\x25\x4a\x4d\x96\xac\x70\x00\x91\x81\x86\xdf\xd4\xbf\x45\x4e\xd3\x09\x74\xc5\x53\xd0\xae\x15\x1a\xd4\xcf\x54\x0c\xec\xaa\xa0\xb5\x94\x8b\x09\x85\xa9\xc7\xb6\xe7\x81\x59\x32\xba\xc1\x17\x32\xfc\x7d\x10\x26\x7f\x6b\xf8\xf1\xe7\xc0\x8d\x65\x0e\x56\x7b\x4e\xdd\x15\xae\x79\x58\x41\x0e\x42\xf1\xf5\x37\xfa\x73\x2f\x72\x7a\x26\x83\x88\x32\x1d\x53\x44\xc4\xe7\x8b\xb9\xa7\x4e\xab\x9d\x6a\xbf\x96\x89\x65\xc6\x66\x93\xd5\xf1\x12\xdd\x4c\x14\xfd\xfd\xd9\x60\x05\xea\xa6\x75\x7f\xa2\xcc\x10\x13\xfe\x43\x27\xab\x09\x99\xd1\x17\xf3\xdb\xf3\x25\xb0\x7c\xd4\x54\xd4\xb1\x41\x99\x1e\xf7\xe2\x3d\xb5\xee\x24\xbe\xda\x35\x88\x4a\xa3\x70\x48\x08\x64\x8a\xa4\x3c\xd6\x25\x62\x59\xf7\xd3\xdb\x5e\x05\x53\x11\xf2\x53\xe8\xb5\x7a\x4c\xda\x5a\xfe\x0b\x0a\xdf\xc3\x64\xe1\x60\xca\x37\xe8\xde\xc6\xb9\x5a\xa6\x15\x2e\x5d\x5d\xa6\xeb\x91\xbe\x0e\x44\xff\xe8\xe4\x95\x33\x26\x7b\x7e\xb7\x95\xf5\xf8\xe0\xb2\xc3\x5b\x29\xdf\xbc\x87\x58\x5f\x22\xbd\x5b\x90\x9d\xfd\x6a\x5e\xdc\x0e\x3a\x9d\x97\xb0\xc4\xf3\xad\xc5\x1e\x96\x99\x37\xc0\x8f\xd6\x5f\x53\x7a\xac\xda\x8f\x11\x27\x5a\xf0\x2c\x33\x54\x54\x26\x30\xf3\x92\x0c\x39\x3f\x5c\x42\xb9\xfc\x63\x3d\xe9\xd9\x4c\x72\xe3\xf2\x00\x02\x34\x9a\xd0\x41\x80\x35\xb3\xf2\x5f\x02\xca\x92\x8e\x5b\x2d\x40\xa7\x7a\x1c\x3e\x56\x22\x1f\x4b\x9d\xb0\xc2\x5b\x09\x6d\x6e\x5d\x0f\xe7\x58\xda\x2c\x69\x05\x3e\x8d\x08\x6d\xef\x4e\xdc\x6e\x34\x53\x78\x3f\xfc\x63\xa4\x96\x01\x22\xd9\x23\x67\x1a\x90\x60\x08\xba\xc1\x05\x61\xae\x62\x19\xd2\xb5\x1d\x53\x67\xbf\x13\xcc\xab\xf5\x93\x1b\x9f\x18\x6e\xb1\x09\xba\xcd\xe4\x0e\x1a\xf2\xb5\x64\x81\xe0\xc6\xdc\x6f\x5c\x54\x73\xf8\x00\x1c\xf3\x71\x91\x9a\xcb\x40\xce\xc5\xb9\x62\xeb\xba\x80\xe3\x2d\x6e\xba\xc4\x80\x6d\x04\xd2\x47\x68\xc2\xad\x2e\x3f\x92\xa8\xcb\xe4\x77\x54\xf9\xbf\x61\x59\x53\x52\x2b\x26\x3d\xc2\x49\x37\xfb\xd9\x32\xc8\xc4\x59\xeb\x8b\x10\x94\x43\xaf\x6c\x19\x5a\x59\xfd\x27\x21\xb0\x12\x56\x28\xf2\xb8\x14\x3c\xf3\xc1\x28\xbc\xec\x13\x92\xef\xd1\x6b\x73\x4c\x10\x71\x6d\x96\xba\x7d\x1f\x41\x39\x17\xcc\xaf\xa5\xbf\x5f\x83\xf5\x24\xfe\x84\x06\xa1\x52\x11\x5e\xa7\x70\xe1\x74\x5e\x82\xe8\xb5\x1d\x75\x2b\x8b\xd7\x85\xdf\x48\xbf\xc1\x20\x41\xbf\x87\x4f\xc7\x3a\xfb\x42\xca\x5d\x69\xc6\x41\x64\x79\xce\xb4\xaa\xa0\x49\x2b\x6f\xf2\x1e\xe1\x2d\xb2\x21\x3a\x42\x86\xfd\x56\x05\xc9\x3a\x7b\xb8\xa3\xb0\x71\xb0\xb2\x5f\xb0\x1d\x77\xab\xbc\x87\x71\x48\x94\x70\xa1\x07\xaa\xda\xe9\xf6\x40\xc2\x4d\xfd\x53\x28\xf6\x0f\x4b\x7d"}, +{{0x70,0x94,0x16,0x07,0x49,0x97,0xb9,0xc9,0xaf,0x4d,0x37,0xa0,0x11,0x39,0xe8,0xa3,0xf9,0xf2,0xce,0x5d,0x72,0xa5,0x7d,0x80,0x5e,0x82,0x2a,0x81,0x18,0x6d,0x01,0x7e,},{0xae,0xe1,0x10,0xf1,0xf4,0xd4,0x6e,0xa6,0x06,0x49,0xd7,0x86,0xb1,0x50,0x05,0x2e,0x28,0x7a,0x9d,0xa6,0x01,0x22,0xc4,0x7b,0x09,0x08,0xfa,0x8b,0x2c,0xa2,0x8a,0x80,},{0x8e,0x4b,0x41,0xf0,0x97,0xd8,0x36,0x14,0x18,0x4b,0xa7,0xf5,0x2b,0xa2,0xfd,0x9f,0x05,0x65,0xf8,0xa6,0x37,0x21,0xef,0x55,0xf9,0x31,0x62,0x82,0x6b,0x9f,0x0a,0xc0,0x70,0xc0,0xe2,0x86,0x4b,0x5f,0xfd,0x8e,0xcc,0xc1,0x8e,0xfa,0xd1,0x8b,0x2c,0xe8,0x4b,0xe5,0x7c,0x0b,0x4a,0x41,0xc5,0x2e,0x20,0xef,0x37,0x72,0x23,0x77,0xc6,0x0f,},"\xed\xda\xa3\x69\xc0\xe3\x1a\x1f\xcc\x1d\xa4\x6f\x65\x36\x24\x42\xa0\xcc\x21\xc7\xdc\xdd\x5c\xd9\x0e\x0a\x2e\xe9\xf2\x51\x10\x81\x2b\xa1\x14\x93\x1c\x86\x8a\x70\x86\x07\xac\x16\x08\x4d\x79\x71\x5d\x13\xb3\x38\xc0\x5c\x6a\xef\x73\x43\xe7\xda\xd2\x82\xf9\x6f\xe2\x81\x93\x18\x8f\x0c\xc8\x93\xc7\xdc\xe8\x05\xfd\x3a\x7c\xd2\x68\xb7\x28\x94\x16\x0b\x52\x45\xfe\xd9\xfa\x99\x43\xb7\xc8\x0a\xdb\x3c\x2d\x1a\x35\x3d\x8f\x12\xdf\x25\xa3\x1d\xde\x7f\xa3\x85\xbb\xec\x35\x1d\xa6\x6f\x15\x30\x32\xe1\x77\x56\x27\x3f\x8d\x54\xe9\xa3\xb9\xea\x25\xae\x67\xd1\xe9\xc1\x8c\xc6\x8b\xe6\x01\xe3\xd6\x82\x82\x81\x8c\xe0\xe7\xcf\x88\xa4\xd1\x33\x64\x53\x02\x17\x32\xf0\x8d\x9e\x76\xcd\x23\x63\x79\x29\xb0\x91\x1d\x5f\x86\x14\xf4\x84\x2e\x67\x0c\x14\x28\x60\xaf\xc2\x65\xc5\x01\x72\xb1\x3b\xfd\x35\xad\x8f\xc5\x4b\x28\x65\x7d\xa3\x2b\xac\x15\x3b\xa9\xaf\xfc\x89\x7a\xfb\x3c\x72\x1f\x48\xca\xa4\x62\x40\x58\x57\x10\xb0\xf2\xd2\x4d\x5f\xf4\x96\x5d\x1d\x10\xf1\xa0\x7b\x06\xab\xea\x6a\x08\xe1\xd6\xf1\x50\x0d\xa1\x2c\x43\x4a\x6d\x77\x8c\x94\x10\x67\x10\x80\x00\x47\x5c\xe8\x31\xbc\xfe\x2d\x0a\xfe\x40\xb7\x41\x9d\x07\x05\x9b\xc0\xcd\x8d\xce\x4b\xe9\x58\x7f\xf2\x9a\xd8\xbf\x0b\x26\x8a\xe2\x3c\xe0\xda\x5b\xb5\xbf\x74\xff\x0b\x2b\x31\xb8\x21\x12\xa9\xfd\x5a\xbd\x9b\xfd\x0a\x90\xe6\xf4\x72\x35\x48\xc6\xbb\x2f\x99\xdc\x06\x1b\xa3\x2e\xba\x2d\x53\xe6\xbc\x79\xbf\x44\x1b\x23\xfb\x74\x60\xde\x04\xe8\xe8\xef\xbc\xd4\xd4\xcc\x73\x55\xde\x9e\x3b\x08\x61\xa6\x81\xb9\x83\x83\x9d\x44\x88\xe5\x51\x75\x1f\x23\xe9\xa6\xe2\xe4\xd4\x43\x27\x3b\x9e\x0f\xe6\x4d\x8a\xcd\x1c\x74\x8b\x55\x59\x43\x82\x23\xdd\x21\xb5\x18\x31\x89\xe0\xf3\xc0\xe8\xed\x41\x4c\x03\x56\xba\xb7\x7a\x65\x4d\xe1\xa5\x77\x14\x62\xef\x14\x34\x49\x70\xa4\x91\x51\x1a\x72\x29\x14\xf4\xa8\x9f\x4f\x1a\x82\x7e\x18\xcd\x84\x47\x9c\xc9\x25\x92\xea\xdf\x8d\xe2\xdf\x82\x4b\x97\x6d\xcb\xd2\x84\xa3\xba\x64\xbc\xdb\x0d\xf1\x5e\x8f\x41\xc0\xb2\x47\x15\x86\xb2\x6a\x06\x35\x3d\x90\x50\x28\x23\x5c\x1c\x6e\x5c\x45\x87\x22\x27\x25\xaf\x08\x3e\x11\xe7\x9c\x94\x3a\xa4\x44\xd4\xaa\x41\x21\x8d\x3e\x97\x43\x36\xe3\x72\x81\x3e\x99\xe2\xb0\xc5\xf0\xae\x81\x0f\xfe\xd9\xa7\xa3\xd6\xcb\x74\xc5\x47\x3d\x99\x0a\x59\x11\x32\x9b\x8e\x82\xec\x6b\xf2\xbd\x43\x21\xbb\x48\x73\x70\xf8\x73\x9e\x7a\x2a\x4a\x53\x43\x08\x33\xd4\x5b\x9f\xe3\xde\xb9\x3f\x79\xfc\x6a\x51\xd5\x63\x69\x5e\xcd\xb9\x78\x58\xd2\x13\xda\x58\x44\x34\xb7\xc7\x15\x46\xaa\xe8\xd9\x67\xe1\xc6\xd0\x08\x2b\x10\xd4\xa7\x2d\xe1\x74\x2e\x53\xc4\xb2\xf9\x2e\xb8\xb5\xc8\xc3\x5a\xb6\x53\x5e\xa8\x10\x0b\x37\x92\x4a\x0a\x91\xd2\xa7\x28\xd0\xf5\x64\x24\x37\xaa\x66\xc8\x2a\xb7\x4b\x5d\x07\x45\xec\x08\xf7\x70\x5c\xb8\x1f\xa0\x79\xd8\x9e\xcd\xc9\xaa\x1f\x8d\x7d\x82\xdc\x77\x46\xd3\x46\x15\x34\x3a\x69\x25\xdc\x31\x8f\x35\x2a\x2b\x45\x01\x24\x38\x42\x4f\x90\x98\xfd\xdf\x6e\x61\xfd\x1f\x8f\xb4\x9d\xa4\x0b\x3e\xec\xe8\x9a\x1a\xf1\x99\x6d\xe7\x0c\xd1\x69\x6c\xbf\xd9\xe3\x01\xea\x5f\x44\x37\xc7\x1a\xc2\xa0\x32\x25\x4c\x14\x0a\x90\xe8\x5f\xb8\xff\xc4\x66\x7f\xa1\x39\xc1\xee\x9b\xbf\x12\xee\xd9\x06\xa9\x67\xbc\x09\x21"}, +{{0x3d,0xcb,0x7a,0xe7,0xd9,0xf0,0xf1,0x41,0xf1,0xd9,0xf0,0x78,0x83,0x63,0x5b,0x91,0x3e,0xd2,0x9f,0xb6,0x1d,0x0f,0x74,0x1c,0x9a,0xfd,0x05,0xa2,0x7b,0x04,0x5b,0x06,},{0xae,0x62,0xb7,0xee,0x1b,0x8d,0xb5,0x76,0x4d,0xaf,0xdd,0xd9,0x72,0x4a,0xcc,0x10,0x6d,0x6c,0x0a,0x4d,0x1e,0x85,0xd8,0x90,0x6f,0x75,0x84,0xb5,0x58,0xf5,0x77,0xdf,},{0x09,0xa1,0xe6,0xfe,0xdf,0x97,0x1b,0x3e,0xdb,0xfa,0xef,0xbe,0xb8,0x9a,0xa5,0x39,0xca,0x0b,0x02,0xb3,0x7e,0x7a,0xc4,0xea,0x89,0x20,0xd6,0xd4,0x34,0x8e,0xe0,0xcf,0x9a,0x2d,0x5e,0x96,0xfc,0xe5,0x17,0xc6,0x65,0xe7,0xc3,0x83,0x68,0xba,0xf2,0x49,0x79,0x24,0x9a,0x95,0xb7,0x0e,0xa7,0x43,0x6c,0x00,0x78,0x5f,0x16,0xa3,0xae,0x09,},"\x38\x11\x6a\x57\x26\x69\x07\x0d\xd5\x86\x32\x18\xc9\x1a\x77\xa4\xab\x47\x55\x36\x88\x48\x8c\x79\x28\x38\x50\x9e\x9a\xba\x25\x06\x7a\xdb\x7e\xa4\x24\x98\x48\x00\x9d\x91\x4a\xe9\x87\xa6\x03\x23\x48\xc1\xc0\x68\x1c\xf9\x77\xa9\x55\x2d\xd6\xbb\xf4\xe6\xff\x32\xac\xc9\xfa\x61\xcb\xee\x25\xa3\x93\x07\x65\x0f\x8b\xa6\xa7\xce\x42\x1e\xf2\xf7\x1b\xcc\xc0\x95\x81\x38\xf9\x32\x4c\x86\xbf\x2e\x52\x8f\xa3\xe4\xd1\xb1\x9f\x9f\x2c\xa5\x26\x84\x09\xb8\xcc\x19\xc6\x2d\xd9\x79\xb8\x96\x97\xe4\x57\xed\x2d\x98\xbd\x20\x96\xf6\x2d\x3d\x9e\x24\x73\x88\x79\x59\x27\x80\x3e\x79\xab\x71\xd4\xf7\x2f\x56\x8e\x94\x5a\x8a\x16\x21\x59\xd9\xb8\x48\x36\xe4\x58\x56\x44\xd4\x97\x9f\x61\x4a\xad\xa7\x3a\xd4\x13\xa8\x33\x91\xe9\xcf\x88\x0c\x42\xac\x2a\x98\x34\x3b\x6a\x82\xcd\x2b\x61\x58\x14\x56\xf6\xde\x5c\xeb\x24\xfe\x46\xb7\x62\x5d\x52\xab\x2c\x2c\x32\x4a\xc7\x47\x03\xd1\x5e\x15\xf1\xae\xff\x80\x55\xd2\xf7\x39\xf7\x36\x3e\x16\xec\x1d\x78\xbe\x2c\x62\x99\x43\x6c\x8c\x8d\x33\x6b\xd2\x92\x71\xa8\x97\xa6\xec\x93\x2e\xd0\x87\x25\xbe\x21\xb2\x8f\x9a\xa1\x4e\xaf\x4f\x71\x85\x31\x54\xdb\x14\x58\x7c\x93\x0a\xb3\xeb\x02\x27\xad\x7f\xfb\x45\xb3\xba\xa6\xa9\x99\x49\x9c\xc8\xa6\xe4\x5b\x1a\xb4\xd0\xb3\x39\x78\x2b\xcd\x9c\xfb\xcf\x88\xcf\x7e\xae\x89\x1c\xc8\x41\xe9\xc8\x8a\x1f\x6a\x69\x1f\x39\x48\xa6\xbc\x85\xba\x7f\x46\x11\x64\x2e\x84\x22\x3c\x3b\x17\x89\x46\xdd\xbe\xdd\xcf\xcd\xef\x4a\xe4\xc4\xe1\xa8\x14\xb9\xb1\xf0\x2b\x1e\xaa\x82\x4d\xb9\x3f\x44\xb2\x7d\x14\x20\x6b\x34\x04\x65\xa1\xce\xfc\xf5\x35\xc6\x3e\x55\xc4\x28\x72\x24\x26\x27\x33\xd9\x8a\xaa\xa1\x54\xf3\xad\x42\xcd\x85\x46\xa4\x61\xce\x0d\x46\xd8\x86\xd3\x46\x1a\x21\x50\xcb\x45\xdb\xe5\x64\x73\xff\x63\xd3\xdc\x7a\x2b\x95\x7b\x82\x39\x69\xf1\x9b\x59\x68\xe8\xb4\x24\xc8\x79\x74\x19\x26\xd8\x2c\x63\x86\x75\x3b\x0f\xa1\xf0\x80\x28\x4e\x55\x78\x94\x23\x63\xaa\xde\xb2\x1f\x8e\x1e\x89\x09\xfa\x6c\x38\x07\x64\x14\x9b\xc9\x15\xb2\x28\x60\x4e\xfc\x56\xd9\x2e\x4b\xeb\x72\x0e\xdc\x74\xc4\xd7\x8f\x92\x5d\x6c\xfd\xf7\xba\x2f\x14\xb5\x62\x37\x75\x81\x0d\x2d\x07\xbd\x38\x8c\x57\x3e\x36\x52\x3f\x21\x57\x38\xe6\x91\x14\xdc\xf8\xd8\x0f\x17\x0b\xfa\x67\x6e\x31\xfb\x62\x6a\x7d\x44\x9e\xd9\x66\x47\x36\x34\x75\x97\x0c\x8c\x47\x80\x97\x09\xbc\xb5\xe7\x20\x0f\x2a\x22\x7c\x7c\x8e\x7b\x00\x0f\x30\xc0\xbd\xe6\x1d\x67\xbd\x68\x95\x36\x16\x29\xa3\x6c\x8f\xdd\x5a\x56\xb8\x1e\xfb\xac\xf1\x5c\x1b\x35\x30\xa0\x8c\xde\xd5\xb1\xfd\x45\x7f\xbd\x2f\x03\x04\x2f\x56\xf1\xb3\x7e\xd1\x5c\xdb\x91\x2f\xa0\x29\x8c\x27\x67\x25\x08\x7e\xe2\x7d\x3c\xf2\x55\x0f\xe6\xe8\xa0\x33\x0a\xf4\x17\xf4\xf5\xba\xf0\x36\x27\xed\x67\xc5\xf8\x32\x33\x63\xab\xac\x5a\x1f\xe3\x48\x23\x18\x0e\x3e\x0e\x20\x80\xf7\x5b\xfd\x91\xc2\x07\xcf\x6b\xaa\x9a\x22\x9c\xf4\x43\xdd\x44\x2c\x59\x02\xe0\x67\x3f\x32\x52\xb8\x52\x63\x46\x58\x58\x72\xf6\xcd\x36\x60\x25\xa5\x69\x92\xb7\x0e\xde\x39\xbc\x8d\x32\x2f\x9c\x22\xa1\xdc\x59\x9e\x9f\x0d\x52\x4c\xb6\xd2\xea\x5a\xe2\x87\x8e\xf6\xbe\xd4\xb7\x02\x80\x7f\x1e\x1e\x73\xeb\xf2\x90\xeb\x6c\x0e\xeb\x85\xc1\x37\x16\xf6\x26\xaa\x90\xd3\x64\xb4\x90\x48\x37\xce\x05"}, +{{0x29,0x73,0x11,0xdd,0xef,0xfe,0xc9,0xd2,0xbe,0x68,0xef,0x7b,0x2a,0x20,0xfe,0x2d,0x27,0x7e,0x1d,0x8e,0x51,0x64,0x8b,0x03,0x57,0x2a,0xda,0x27,0xec,0x1f,0x9f,0x43,},{0x6a,0x6c,0x28,0xe7,0x61,0x64,0x0c,0x40,0x08,0x33,0x3a,0xae,0x5a,0x33,0x66,0x30,0x2e,0x2f,0x46,0x77,0xa9,0x53,0xba,0x48,0x2a,0xb6,0xfb,0x4a,0x1d,0x70,0xb4,0x47,},{0x4b,0xf0,0xb9,0x2c,0x6e,0xe4,0xea,0xce,0x5e,0x8e,0xb1,0x03,0x70,0xff,0x9d,0x9c,0x68,0xa5,0x74,0x9d,0x59,0x89,0x9d,0x04,0x32,0x7a,0xaa,0x38,0xf8,0xf8,0x25,0xe0,0x32,0xe5,0x97,0x42,0xb3,0x7d,0xe2,0x31,0x07,0xa3,0xec,0xdd,0x3f,0x7a,0x0d,0x08,0x12,0x26,0x14,0xb7,0x8f,0xdd,0x37,0x29,0x3c,0x8d,0x05,0xe2,0x8f,0x5f,0x71,0x08,},"\x26\x52\xac\xfc\x3b\xdf\x09\xa5\x99\xec\x67\x86\xbb\xd9\x4f\xe5\x77\xcf\x57\x8e\x02\x63\xcc\x68\xd9\xf5\x7a\x6c\x83\x45\x8f\x80\xac\xd8\xa7\x5e\xf0\x30\x40\xa6\x35\x67\x2b\x96\x8f\xf2\xaf\xdb\x28\x8d\x28\xb9\x99\x6f\x64\x15\xb2\xf3\x17\x5e\x9e\xa3\x7a\xeb\x05\xdf\x81\x81\x2e\x38\xa4\xc9\x76\xeb\x92\x85\x6c\xed\xb9\x1a\x26\x9a\x46\xfc\xa5\xdf\x9b\xd7\x30\xfd\x84\x45\x2b\x4b\xd9\x35\x77\xc6\x1f\x42\xc1\x41\x13\x97\x98\x82\xa8\x6a\x9f\xe6\x32\xe4\x75\x6a\xfd\x89\x81\x6f\xc4\x67\x0a\x31\x05\x03\xfd\xaa\xd2\xdb\x76\x4c\x37\x21\x21\x3c\x3e\x60\xf2\x9c\x26\x68\xd4\xde\x8f\x42\xb0\x87\xf2\x5c\xd5\x6c\x69\xa4\xe4\x8f\x13\x4f\x55\x98\xcf\x14\x5b\xe6\x38\xa5\xc2\x31\x88\x63\x32\x90\x61\x72\x9a\xac\x91\xda\x6a\x19\x1f\xd7\x74\x88\x0c\xf9\xcb\x55\x5e\xec\x15\xb0\x04\x4f\x10\xe5\x43\x3f\xb4\x6a\x9b\x88\x92\xda\x8f\x6d\x24\xf1\x42\x58\x8b\x70\xff\x0b\x49\x20\x0c\x50\x6b\x88\xbe\xd4\x49\xad\x10\xd3\xf9\x2c\x2b\xae\xda\x6b\xbf\x58\x67\x6c\x5b\xbc\x67\xd3\x1f\x64\xfb\x12\xe8\xd5\xe7\x88\x76\xd5\xc8\x49\xfc\x31\x4b\x2c\xf8\x01\x0c\x51\x02\x04\xc8\x63\x3d\x0c\xc3\x18\x56\xec\x6a\x11\x4e\xa8\xa8\x9c\x48\x92\x7b\x07\xa3\x1a\xb8\x42\xc9\xb8\x35\x2d\x93\x67\x34\x51\x41\xa9\x9b\x40\x04\x9d\x5c\x48\xe7\xd2\x7c\xab\x42\x7a\xde\xfd\x1f\x0f\xc1\x13\x6b\x35\x3c\xb0\x1c\x3d\xef\x91\xff\xfe\xe8\xad\x91\xe8\x8f\x4b\xb7\xd2\x61\x5c\x0d\xcc\x95\x34\x4c\xd0\x19\x50\x93\x8e\xcb\x14\xb8\x44\x6b\x56\xa0\x6b\xf2\xf2\xf6\x5f\xb8\x73\x5e\x8a\x7b\xc9\x6b\xb4\x6c\xe9\xca\xc7\x1a\x88\xeb\x8f\xda\x5e\x69\xd6\x9e\xb2\x9a\xa4\x2a\x01\x6b\x85\x83\x89\x3e\x9d\x72\x77\xcb\x13\x59\xc5\x68\x7e\xed\xcd\x59\x9d\x8a\x46\xe6\xc1\x49\x63\x63\x7d\xb0\x4a\x92\x9f\x4b\xc7\x93\x04\xac\x2d\xae\x73\x3b\x3a\x83\x9e\xb7\x4f\xbe\x3d\xe5\x04\x2f\xd6\x55\xea\xec\xb1\x5f\x39\xb2\xfe\x16\xda\xd8\xa6\xff\x8d\xbc\x05\x4f\xed\x51\x28\x2a\x85\x6e\x9d\xa6\x31\x6f\xac\x6d\xb5\xd5\x6f\x77\xf1\x8d\xa8\x41\x2e\xb3\x77\xe5\xb1\xb8\xf4\xcb\x13\x54\xec\xfe\x8f\xe8\xfd\x54\xe6\x2d\x76\x7a\x80\xde\x04\xcb\x76\x20\x22\x9a\x88\x31\xdb\xc9\xec\xd4\x57\x8f\xfa\x2f\xf0\x6b\x54\x45\xe4\x40\xd6\x9a\xab\xc9\x4c\x47\xbd\x17\xf2\x2b\x69\xf5\x2e\xea\xe5\xcf\xcd\x01\xa5\xca\xfe\x05\x80\x07\x2a\xe9\x16\x6b\x95\x74\x3d\x68\xc3\x56\x4c\x5a\x7e\x46\xf2\x4b\xc4\x8a\x89\x8a\x1a\xb2\xeb\xe6\x3f\x36\x85\x1d\x2a\xac\xfa\x0c\x4f\x32\xd9\x93\x77\x1d\x31\x4e\x72\x5a\x43\xd9\x80\x5d\x13\x71\xcf\x72\x3e\xf1\x61\xd4\x2e\x63\xff\xca\x68\x8d\x7f\x0e\x21\xef\x5b\x3f\x9a\x56\x1a\x62\x10\x70\x2b\x85\xfb\xd1\xf8\xca\x75\x38\x9c\xc7\xa2\x27\x39\xba\xe4\xde\xd9\x37\x57\xf1\x52\x0d\xc3\x88\x44\xa1\xa8\x8b\xe8\xe0\x96\x45\x05\x91\x48\x80\x7b\x93\x37\x70\x87\x8c\xb8\xa9\xad\x92\x11\x31\x71\x31\xe6\x93\x24\x53\x2f\xd0\x27\x9b\x83\x18\x5b\x62\x8f\xc2\xf9\xe2\x15\x00\x38\x46\x93\xfa\x29\xf2\x6b\xd1\xb9\xc3\x01\x60\x13\x67\x66\x5f\x05\xf3\x72\xda\xb4\xe3\x10\x77\x26\xcd\x3f\x63\x9c\xa6\x2b\xf6\x3a\x75\xf7\x7e\xaa\x75\xf7\x13\x61\x57\xad\xa2\x37\x4e\x65\xfb\x4f\xd3\x49\xb4\x5e\x25\x44\x1f\xd2\x1b\x13\xe6\x91\x13\x66\xb9\x7c\xfb\x4d\x6a\xd5\x22\xb8\x50\xad\xf4\x0c"}, +{{0x4d,0xb2,0xb5,0x81,0x44,0xa8,0xd2,0xd0,0xec,0x03,0xbb,0x9b,0xc2,0x9b,0x4c,0xa8,0x93,0x85,0x4c,0x80,0xb6,0x4a,0xfa,0x4a,0xf7,0xa9,0xc9,0x36,0x93,0x5e,0xcb,0x04,},{0xfc,0x5c,0xd7,0x50,0xe1,0x74,0xed,0x71,0x8b,0xd9,0x38,0xfa,0x8e,0xd9,0x9a,0x1b,0x9d,0x55,0x6b,0xa7,0x67,0x0f,0x2a,0x77,0xda,0xf1,0xc7,0x20,0x11,0x37,0x32,0xa5,},{0x42,0x45,0x17,0xaa,0xdd,0x85,0x3c,0xe3,0x98,0x57,0x59,0xa3,0x27,0xe7,0x76,0x0d,0x91,0x56,0xd3,0xb2,0x73,0x45,0x38,0x3f,0x0e,0x4a,0xd6,0x66,0x1e,0xe4,0xa3,0x72,0x4d,0x18,0xd8,0x20,0xf6,0xc5,0x57,0xf8,0x27,0x97,0xbe,0xb6,0x2d,0x2f,0x08,0x54,0x33,0x74,0x4f,0x89,0xa2,0xd8,0x52,0x93,0x79,0x64,0x81,0x86,0x2e,0xf8,0xa4,0x0f,},"\xc8\xd1\xdb\xc9\x36\x91\x1e\x12\x2c\xee\x18\xf9\x2b\x16\xa3\x9a\x2e\xef\x08\x23\xb2\x27\xf8\x98\xcd\xf5\x84\x2b\x93\xd5\x9f\xc0\x02\xed\xb5\x49\x8a\x20\x87\x2e\x19\x55\x4e\xf7\x39\x99\xeb\x3a\x7b\x3e\x2f\xdd\x90\x70\xe1\xef\xa9\x22\x8e\x9e\x93\xb2\x9a\x86\x8a\xe3\x79\x9e\x4e\x57\x23\x24\x83\x6b\x1a\xd5\xaa\x81\x2b\xf0\x0f\x84\x5b\xc2\x17\xeb\xbc\x3f\xab\xdc\x4e\x1b\x6e\x51\xef\x9e\xfa\xc2\x77\x0a\xa0\xa4\xa1\x1e\xe5\x2a\xb9\x56\xac\x64\x48\xaa\x26\x29\xcb\x61\xdb\xb1\xf1\xed\xb3\xbd\xe9\x9b\x48\x76\xda\x39\x2a\x6e\x0b\x9a\x0c\x31\x84\x9a\x58\x90\xae\xa9\x52\x2f\x56\xd0\x15\xa1\x93\x50\x15\xb9\x1b\xf4\xc6\xa0\x01\x1d\x23\x77\xd6\x71\xc3\xd0\xd7\x53\xc2\x7f\x8c\x76\xe4\x05\xd0\x23\x0f\x1f\x4b\x9b\x88\xfc\xeb\xba\x1e\xaf\x13\x77\x72\x35\xe5\x53\x24\xb7\xd3\xf8\x1e\x68\x61\x09\xd9\x1c\xe6\x89\x53\x0b\x90\xd2\xc5\xc7\x1d\xd1\x87\x72\xb3\x85\xd6\x2c\xcb\xfd\x2e\x08\x9a\x1b\x67\x09\x83\xf6\x0c\x21\xc4\x45\x5c\xb9\xd1\xa0\xdc\xaa\x74\xc8\x74\xe3\x52\x11\xf8\x22\x7f\xf7\xc2\x34\xdf\xf8\x5e\xc0\xb0\x7e\x36\x8c\xfa\x50\xa3\x43\x57\x83\x95\xa1\x4c\x68\xf1\xf8\x9b\xd4\xec\xbc\x17\x2e\xf8\x05\xe5\x83\x1e\xc8\x94\x75\xfc\xc8\xd6\x85\xca\x92\x55\xa7\x7e\x3b\xa3\xc1\x47\x50\x8e\xc9\x2d\x7b\xcc\xe8\x79\xaf\x0a\xbd\xd2\x41\x6b\x67\xb5\xf5\x05\x07\x33\x79\x14\xf3\x90\xbb\xe0\xb4\x50\xb6\xa2\xf1\x15\x93\x72\xc4\xbc\xce\xa3\x82\xce\x3d\x6d\x9f\xb2\x51\x5e\xcf\x79\x30\x05\x9a\x05\x52\xb7\x5f\x97\x88\x62\xbf\x97\xe8\x32\x5a\xf2\x4d\x1b\x8c\xe9\x51\x2b\xfc\x7c\xef\x88\x42\x32\x04\x23\x41\xd8\x2f\x9b\x5d\xad\x2e\x50\x2a\xc6\xac\x79\x5f\x99\xda\xc7\xfc\x60\xe3\xb8\x63\x9d\x0e\x15\x00\xde\xad\x4e\x78\xac\xa1\x09\x95\x7d\x57\x7a\x13\xc1\x92\x5d\x74\x03\xc1\xac\xf9\x89\xa9\xde\x67\x11\xe2\x3c\x67\xbf\x87\x22\xf5\x51\xb7\x74\xca\xda\x93\x1b\x5f\xd9\x73\x43\x4e\x3b\x71\x72\x81\x98\x83\xe7\x0c\x52\x78\x5e\x3b\x49\xd3\x23\xd0\x56\x36\x64\x11\x58\x64\x0d\xcf\x6a\x4c\x20\x0e\xb2\xc1\x3b\x1b\xee\xb2\xdc\x36\x03\x52\x47\x0d\x15\x38\x6e\x59\xe6\xfa\x60\x36\x7e\x5e\x7f\x17\x2b\x21\x15\x9d\x5e\xe7\xca\xb0\xd7\xf5\x86\x82\x39\x85\x8e\x2a\x93\x55\x04\x80\xfe\x8f\xb4\xdc\xaf\x4f\x22\x4c\x4b\x2a\xd5\x44\x87\x91\x63\x2d\xf3\x0e\x8e\x5f\xb9\x98\xb3\x5e\xa9\xae\xc8\xc9\x34\xa4\x40\x3a\xef\x82\x18\x7c\xa1\xab\xf8\x2a\x34\x4d\x00\xff\xb9\x93\xd9\xff\x34\x61\xd6\xfe\xcd\xaf\x5d\x3b\x48\x1e\x0d\x31\x15\x3d\xbf\x6a\xed\x28\x8c\x8a\xdd\x06\x4e\x83\x31\x55\x01\x41\xbd\x5f\x7a\x7e\x04\x7b\x86\x07\xd8\x46\xa6\xbf\xb7\x2d\x68\x34\x46\xa4\x45\x11\x46\x06\x25\x0d\x8d\x2d\x3a\x8b\x95\x08\xbb\x07\xd4\x62\x3c\xdf\x17\x88\xb5\x49\x9e\x9c\xb9\xa1\x37\x98\x49\xbf\xa1\x9c\x9a\x9f\x4c\xd3\xd9\x25\x3a\xdf\xfd\xa2\x5f\x47\xc8\x11\xbe\x83\x3b\x02\xf3\x32\x7e\xbb\xa8\x37\x30\x19\x5d\x61\x4b\xae\x6f\xe4\xe7\xa3\x83\x08\x15\xd2\xaf\x40\x0d\x20\xa9\x41\x7a\x09\x5e\x7e\x8e\xea\x10\x44\x91\x7c\xbe\x51\x2c\x40\x18\xd6\x56\xe2\xdb\x67\xbb\x98\x9c\x00\xe1\xe5\x07\x62\x3e\x82\x78\xd7\x29\x92\x5b\x84\xfb\x5c\x18\x6a\x7b\xac\x18\x9e\x6d\x6a\xb1\x4f\xd7\xb6\x2f\xdc\x63\x2b\xeb\xb5\xf7\x7c\xb5\xcc\x2f\x70\x7d\xf4\x05\x30\x99"}, +{{0xc8,0x20,0x41,0x3c,0x24,0x56,0x74,0x71,0x04,0x66,0x2e,0xf4,0xdf,0xf3,0xac,0x23,0x3a,0xc4,0xb9,0x1a,0x76,0xd3,0xc4,0xea,0x75,0x44,0x90,0xbc,0x9b,0x1e,0x29,0x1f,},{0x89,0x93,0xce,0xa2,0xf7,0xf2,0x80,0x6c,0x77,0xb3,0x98,0x1b,0x54,0xbf,0xa9,0xbf,0x17,0x62,0x15,0x1b,0x41,0x8e,0x5e,0x72,0x53,0x71,0xca,0x2c,0x04,0xd2,0x23,0xee,},{0x7e,0xf7,0x0e,0x4a,0x14,0x95,0x4d,0x50,0x9f,0x11,0x7f,0x4b,0xd0,0x1b,0x22,0x0b,0xcc,0x19,0x2d,0x3b,0x5f,0xdf,0xc3,0x48,0x2f,0xbb,0xc3,0xb6,0x9d,0xc0,0x68,0xa7,0xc4,0x76,0x1d,0x1b,0xeb,0xc2,0x31,0x7d,0x6d,0xb7,0x4f,0x90,0x6a,0x15,0x56,0x42,0xb0,0xa3,0xc6,0x59,0x2b,0xdc,0x72,0xe6,0x4e,0xac,0x6f,0x20,0x3f,0xb7,0x4e,0x02,},"\xd2\x99\x2f\x83\x92\x4a\x59\x48\x87\xe6\xef\x13\xf2\xae\x80\x8f\xc8\x63\x9c\x7b\x2c\x99\x4f\xaf\x0f\x79\x5e\x36\x01\x6d\xab\x77\x00\xa0\xee\x53\x01\x70\xf0\xb9\xfe\x98\xab\x75\x88\xce\x03\xbc\x50\xc2\xba\xe6\x5e\x05\x26\x47\xe7\x56\x73\x5b\x35\xd0\xb5\x9c\x96\x4e\x91\x7d\x8c\x83\xe2\xf9\xfe\xcc\x4c\xb0\x55\x64\x28\x7f\x0e\x34\xc9\x49\x40\x05\xe2\x5b\x1a\x8b\x1b\x94\x2b\x54\xd8\x90\x35\xf1\xb1\xc3\xc9\x45\xfc\xc8\x4e\x4a\x39\xef\xa2\xca\x50\x95\x9b\x45\x9a\xf7\x4d\x21\xb6\x24\x2e\x2f\x56\x51\x8f\x70\xe8\x67\x92\x57\xc0\x89\xd2\x6c\x3b\xb7\x92\x68\x7c\x92\x33\x55\xb2\xc1\x8e\xe2\x13\x6d\x40\xcb\xa4\x5a\xcb\x64\x24\x0d\x96\x67\xf3\x9d\xba\x36\x39\xb6\x51\x6d\x4c\x49\x47\x57\x3e\xf4\xce\xd8\x76\xb5\xb2\xea\x34\x89\xea\xea\x53\x9f\x55\x7f\x58\xda\x20\x46\x91\xa7\x6e\x29\xc9\x4b\x8b\x05\x38\x23\x2c\x5f\x7d\x0b\xb0\xfd\xd0\x16\x91\x04\x31\x35\x4b\x3e\x1e\x7c\xe6\x2a\xd4\x36\x91\x7c\xd5\xc3\x15\xa5\xbe\x9b\x97\x1c\x80\xf9\x7b\xc9\xd5\xc1\x56\xff\xd6\x4f\xd4\xe3\x1d\xa5\x60\x83\xe0\x2a\x0c\x8f\xce\x55\x4d\xb6\x86\x74\xcb\x62\x70\x0b\xa9\x51\x75\x2b\x82\x9b\x03\xc5\x42\x32\x74\x12\xee\xc9\xcc\xc6\xa5\x0a\xdf\x47\xbb\xee\x15\x44\x66\x82\xda\x2f\xea\x42\x04\x89\x36\xd7\x63\x06\x0c\xd8\xf5\x39\x65\x26\x16\xdf\xa8\x08\xd6\x23\xff\x77\x7b\x41\x13\x65\x2e\x78\x9e\xc0\x25\xb8\x5e\x04\xef\xe8\xad\x4c\x96\x0b\x19\x0b\xf4\xa5\xa6\x32\x4d\x6f\x57\xc1\xad\x22\x01\x8c\x83\xcd\x7e\x7e\x09\x7f\xc6\x7b\x80\x26\x9c\x13\xb4\xdd\x97\x01\xca\x98\xf9\x87\x69\x58\xba\x76\x89\xc6\xf6\xf1\x0a\x73\x2a\x64\xbe\xf2\x2e\x8b\x98\xbd\x30\x4d\x5d\xbf\x4f\xb1\xf9\xe4\xca\x53\x9a\x5c\x4a\xa6\x19\xc4\x4d\x6f\x58\xf8\x24\xb2\xdb\xae\x77\xb7\xe8\x3b\x56\xdb\x5e\x5a\xa7\xb0\xae\x9c\xe1\xcd\x10\xa6\x9f\x04\xa8\x0f\x13\x79\xeb\x0c\x47\x4e\x47\x82\xdf\x0e\x3b\xa6\xa1\x48\x22\x6b\xd1\xa6\x62\xd9\x5e\xe2\xd6\x7c\x52\x07\x33\x3c\xb1\xd5\x41\x76\xd9\xe5\x06\x45\x94\x79\x02\x9f\x31\xdc\xac\xe2\x69\x93\x8f\x6b\xc5\x62\x78\x78\x41\xdc\xfe\x10\x1f\x4d\xb6\x0b\xd6\x60\x16\xe1\xee\xbb\x6b\xfb\xd9\xcd\x83\x04\x2d\xd1\x37\x9a\x46\x4f\x40\x5a\xaa\xe3\xc1\x18\x07\x84\x8c\xc4\xf9\x5c\x3c\xc6\xfa\x92\xab\x4e\xa5\x30\x58\x34\xeb\x86\xb8\x73\xfa\x30\xed\x1f\x7f\x47\x0b\xf6\x63\xf1\xa7\x0c\xf9\xe6\x0a\xb6\x80\xcd\x1d\xbb\xd0\x3a\xc0\x43\x3b\x3d\x4b\xb4\x82\xf8\xb3\x44\xd4\x6b\x3a\xa9\x34\xb8\x63\x3f\x57\x09\x0b\xea\x5f\xcc\xca\x64\x88\x79\x98\x35\xf1\x33\xf8\xbc\xf6\xe8\x87\xca\x59\xd1\x90\x76\xd6\xca\x19\xd4\xe2\x83\x49\x05\x1e\x01\x6b\x03\xe9\xa9\x20\xf4\x12\x0f\xb5\x23\xd1\x37\x1d\x0e\x38\x46\x73\x19\x54\x3f\x12\x7e\xd9\x14\xb4\x3a\xd0\x62\x22\x6a\x53\x65\x82\xdb\x72\x8c\xcd\x76\xe9\x83\xf1\x17\x66\xa8\x86\x3c\x2f\x42\x4f\x65\x50\x8d\xcb\x26\xfe\x0c\x5a\x80\x0c\x35\x09\x39\x60\xa1\x21\x97\x6e\x30\x51\xe2\xef\x1a\x2a\x99\xc1\x2f\xb7\xbd\x8b\xc0\x37\xa4\x39\x68\x68\x06\xeb\x72\x01\x7a\x07\x1a\x91\xb3\xe3\x9c\x90\xe8\x6b\xc3\x35\xf9\xbb\x54\x3b\x12\x7c\x98\x86\x73\x8c\xb5\x38\x06\xb9\xcb\x3c\x25\x94\xc7\xef\xfc\x2a\x59\x20\xaa\x83\x4b\xe6\x5c\x49\xf4\x79\x64\xe8\x9e\xec\x74\x72\x8d\xe7\x71\xf3\xd6\x75\xde\x9d\x1e"}, +{{0x67,0x69,0xcc,0x8e,0x12,0x56,0x17,0xc2,0x2c,0xe5,0x72,0x37,0xa4,0xfc,0xa1,0x50,0x7f,0x94,0x12,0x34,0x66,0x1d,0xf7,0x43,0x28,0xd0,0x4a,0xb6,0x2e,0xf8,0x6c,0x47,},{0x05,0x11,0x2c,0xa6,0x0b,0xaf,0xf7,0x9b,0x49,0x16,0xc1,0xbe,0xe2,0xb9,0x39,0x0c,0x04,0x7a,0xf0,0x8c,0x35,0xeb,0xb3,0xc3,0x81,0xb9,0x74,0x8d,0x1d,0xd4,0xc4,0xfd,},{0xd3,0x9d,0x85,0x3d,0x2c,0x2c,0x5d,0x21,0xb5,0x87,0x1e,0xa5,0xa7,0x5c,0x04,0x10,0x48,0xd9,0x3a,0x47,0xdc,0x59,0x9a,0x5f,0xdd,0xc0,0x85,0x62,0x85,0xce,0x63,0x6f,0xcd,0xfd,0x85,0x64,0x08,0x3d,0x06,0xff,0x28,0x4a,0x52,0x4b,0xc6,0x33,0xcf,0xdf,0xc3,0xb0,0x37,0x16,0x3d,0x67,0x4c,0xb9,0xbb,0x5b,0xa3,0xbc,0x25,0xbe,0xd0,0x0e,},"\x68\x54\x89\x73\x9b\x98\x56\x47\x49\x58\x7f\xf1\xac\x96\xba\x68\x2d\xa3\x0b\x40\xa4\xde\x24\xf5\x4e\xc8\xb0\x83\xdd\xa4\x53\x33\x16\x21\x67\xcb\x3f\x97\xb2\xc7\x31\x4c\xe7\xa3\xf3\xf3\xd3\x19\xcc\xc3\x5b\xb6\xa9\xf0\x07\x7d\x56\x31\x61\xe2\x81\x46\x9c\xf0\x89\x68\xd9\xdc\xf7\xae\x5f\xff\x83\x0a\x5d\xb0\x0b\xc3\x80\x10\xe6\x66\x2d\x49\x4f\x3c\x86\x47\xc4\xf7\x0c\xe2\xd2\x9a\x9d\xa8\x46\x10\xa0\x80\xb5\x75\x9a\x3b\x58\x20\x52\xdf\xde\x66\xe4\xa7\xfa\x5f\xb2\x7f\x06\x50\x73\xfe\x72\x3d\x83\x70\x1d\x5b\xac\x06\xca\x43\xb4\x6d\x1e\x58\x09\x76\x70\xc1\x94\xa1\x3a\xf8\xb5\x73\xa3\x79\x1a\x96\x61\x55\x7c\xbc\x04\x27\x57\xab\x8a\xdd\x0e\xf7\xcf\x4f\x35\x43\x5a\x42\x12\x35\x3f\xcb\x3c\x20\x3c\x73\xdb\xc9\xd2\x68\x52\xd0\xe9\x17\x32\xe3\x62\x1c\xe8\x28\x92\x9c\xdc\xa4\xd9\x19\x20\x48\x75\x19\x22\xed\x22\x5e\xab\x29\x00\xcf\xf9\x71\xa2\xa2\xd3\x42\x46\x36\x48\xbb\xb1\x94\x43\x19\xa8\xef\x6d\x43\xdb\x62\x48\x0f\xbf\x1d\x72\x57\xd2\x26\x94\x53\x97\x93\xf2\x5c\x92\x79\x17\xca\xab\x25\xc1\x19\x3a\x2d\x2b\x23\xbb\x5c\xb8\x56\x9a\xef\xff\x4f\x0c\xa4\x23\xd1\x9b\xbd\x46\xfc\x5e\xf7\x52\x4f\xf8\xcb\x70\x6f\xfc\x47\x07\x65\x09\xc0\x5a\x81\x58\xaf\x77\xf9\x8d\xf6\xa9\xb5\xcb\x32\x44\xab\xa4\xb5\xc5\xf9\xce\x59\x7e\x7d\x29\xba\x07\x01\x3d\xca\xc1\x91\x1b\x6d\xe7\x11\x3c\x73\x6a\x40\x05\xc4\x59\x99\x29\x79\x01\x9a\x45\xb2\xdd\x80\x2a\x07\x66\x09\x09\xeb\x4c\xe2\x05\x40\x81\x70\xd8\x25\x45\xda\xcb\xa8\x68\x6d\xbd\xe9\x27\xdb\xc9\xc7\xd9\x62\x05\x8e\x9a\x95\xea\x66\xb8\xdf\xd3\xea\x43\x53\x57\xa9\x3c\x73\x94\x8c\xd3\x55\xf6\xac\x65\x52\x32\x3f\x17\xc2\xa6\x78\x66\x2b\xc0\xe9\x72\x6a\xd5\xa5\x25\x1d\xd2\x76\x47\x40\x4c\xbf\xe6\x1c\xea\xaf\xdc\xfc\x08\xa4\x75\xff\xd8\x7c\xb7\xf5\x97\xe5\x6a\xc1\x67\x04\x09\xdd\x94\x08\xae\x47\x70\x42\x0c\x6e\x5e\x6d\xd8\xe7\x48\xfe\x03\xa7\x2d\xc1\x28\x03\xd0\x27\x71\xd9\x2f\x47\xe6\xe7\x17\xcc\xc1\x44\xfc\x03\x72\x75\xb6\xf7\x45\xdd\x30\xda\x1a\x45\xd2\x9d\xb6\xd9\x07\x3e\xee\x50\x09\xcf\xd5\x46\x27\x33\x41\x4a\x49\x5f\x34\x9d\xb0\xb6\xdb\xf2\xce\xa9\xcc\xd5\x72\x38\xed\x5e\xe9\x1a\xd8\xbc\x86\x17\x9a\xd5\x69\x5a\x85\xa5\x04\x84\xe6\x17\x75\x1d\xe5\xef\x7a\x7d\x8a\x8d\xb9\x50\xa9\x8a\x6b\x7f\x7d\xee\x9d\x42\xa5\xdf\x69\x2f\xcc\xf5\x55\xc9\x40\xdc\x39\xcf\x2e\xac\x48\xcb\x9d\x15\xcd\xa1\x4d\xd2\xa7\xec\xc0\xb7\x6e\xbe\xc6\x8a\xd4\x17\x7d\x11\x17\xe0\x77\x66\xc4\x85\x90\xd4\x3c\xa7\x66\x28\x68\xeb\x97\x90\xac\x29\xf4\xf2\x39\x2b\x9a\x93\xf8\x97\x59\xe7\xba\x54\x6b\x92\x5b\xd8\x6f\x80\x7d\x8d\x16\xc7\xe6\x37\xdc\xc6\x66\xe9\x05\x90\xbf\x43\x0d\x98\x6a\x67\xf1\xb0\xc7\xc2\xc9\x49\x30\x84\x58\x69\xed\x8d\x8a\xdd\xe1\x8f\xc1\x88\x74\x56\x88\x1b\x4b\x26\xb5\x3d\xcb\xa7\xa5\x26\xf0\xec\xa1\x4e\x8b\xb6\x89\xd6\x6f\x0a\xa1\xb2\x53\xc3\xdc\xfc\xf5\x95\x40\xd5\xd2\xf5\xad\x61\x7f\x52\xc3\x09\x38\xa5\xa9\x2e\xa3\x85\x07\x7d\x75\xaa\x4a\xc0\x7a\xfc\x2b\x35\xfb\x8c\x1d\x5e\x78\xeb\x29\x5f\xc2\x0f\xe3\x7c\x41\xac\x06\x95\x9d\x3a\x17\x97\x84\x3a\xd7\x05\x6c\x1b\x41\x2d\xd0\xb4\x80\xaa\x3b\x39\xbc\xc2\x05\x87\xd9\xa0\xfe\xf9\x2c\x6c\x95\x0e\xbc\x5b\xb8\xe1\x42"}, +{{0x1d,0xf7,0xac,0xfb,0x96,0x33,0x04,0xe5,0x1e,0xc4,0x71,0xca,0xf1,0x81,0x10,0x25,0x56,0x78,0x3c,0xb7,0xd9,0x1e,0xad,0x30,0xbd,0xc2,0x53,0x4d,0x07,0x8a,0x14,0x88,},{0x05,0xa3,0x1f,0xfc,0x70,0xe4,0xe3,0x56,0x9f,0xc2,0xbe,0x11,0x0c,0x64,0x3a,0xd5,0xf0,0x87,0x91,0x3c,0x7a,0xa4,0x76,0xdc,0xd8,0xd6,0xe4,0xbc,0x7e,0xc2,0x2d,0x24,},{0xb1,0x81,0x93,0x8d,0xe1,0x01,0x42,0xf3,0x24,0x07,0xb4,0xe7,0x86,0xcd,0xdd,0xe9,0x32,0xeb,0x11,0xdb,0xc0,0xbf,0x0e,0x5a,0xc5,0x09,0xfa,0xe7,0xa5,0xbc,0xc3,0x29,0x61,0xfe,0x34,0x48,0xf9,0x12,0xc8,0x50,0x0f,0xc6,0xdb,0x4e,0x1d,0x32,0x62,0xa8,0x3c,0x9d,0xbe,0x76,0x9b,0xb8,0xc3,0xa7,0x61,0x00,0x0f,0xe3,0x6c,0x0d,0x71,0x04,},"\xb0\xc3\xee\xb5\x7f\x14\x60\x6a\xb7\xab\xea\xb2\xee\x05\x73\x84\x3c\xa2\x2e\x6d\xb2\xfd\xf2\xc9\x06\x4c\xea\x51\x98\xdc\x58\x30\xeb\x15\x8d\xa8\xe2\xda\xa8\x88\x57\xaf\x8b\x8e\xef\xcc\xf0\xc2\x6c\x3e\xc0\xf3\x30\xe9\x2c\xff\x06\xbc\x05\xa2\x9b\xfc\x99\xf9\x40\xb6\x1f\x3c\xfb\x29\x64\xb3\x37\x09\x7a\x65\x50\xa3\xe9\xa3\x28\xc8\x5b\xe6\xf1\x60\xd2\xc0\xa5\x7f\xf6\xf1\xb3\xc5\xff\xcc\xa8\x90\x89\x42\x5a\xb6\xbe\x01\x72\xe1\x75\xba\xf4\x0c\xf1\x2b\x24\xa8\x15\xf7\x0f\x29\xa3\xa4\xcd\x0a\x6a\x13\x2f\x12\x00\x97\x75\x2f\x4b\xc7\x43\xed\xe0\x8f\x5f\x21\xd4\x2f\x28\x2f\x76\x71\xf7\x78\x3e\x27\xb2\xa8\xe2\xc1\x46\x92\xf1\xe0\xe5\xde\x82\x85\x5d\xab\xf9\x8a\x1a\x63\x97\x60\x06\xff\xbf\xe5\xf5\xa5\x79\xb4\x60\xe2\x6d\x06\xbd\x54\x28\x42\xa5\xf9\x26\x1b\xbf\x26\x04\x51\xd2\x32\x1c\x50\x89\x32\x01\x3c\xc6\xe9\x04\xf7\x9b\x5e\x46\x86\xd0\x33\xe1\x2c\x7b\xbd\x7e\xb1\xc9\x23\x79\xc5\xec\x34\x1b\xf6\x45\x7a\x3f\x17\x26\x4a\x7c\x27\x8b\x27\x50\x1e\xca\xed\xc3\x61\xeb\xa8\x44\x44\x23\x42\xb4\xb1\x0f\xa9\x4d\x26\x58\x65\x11\x6a\xcf\x43\xfc\xbe\xc9\x65\xd2\xab\x4b\xbb\xe6\x14\xc4\xf9\x0a\xb6\xb3\xe0\xd5\x38\x3f\xa0\x49\x88\xbf\xbb\x26\x03\x07\xdd\xe2\x2d\x84\x09\x8b\x63\x31\xd1\x55\x14\x1a\x92\x7b\xb7\x8d\x66\x4b\x34\x1d\x2f\x2a\x93\xe2\x91\xcf\x79\xba\xae\xcd\x26\x12\xf6\xb1\x04\xf3\xfc\x81\x37\x3a\x7c\x6a\x04\x5b\x59\x24\xbf\x95\x0c\xd5\x42\xf7\xb7\xac\xce\xf3\xaa\x7d\x72\x5d\xe0\x53\x05\x5d\x95\x1b\xd7\x68\x11\x13\x92\x59\x66\x38\xae\x09\x71\x70\xf4\x49\x2b\xa5\x0a\x46\x8f\x8e\x34\x77\x63\xdb\x61\x2d\x3c\x7d\xe7\xe5\x64\x59\xb2\x6e\xe0\x29\xc6\x30\x82\x7a\x35\x3a\xee\x73\xde\x68\xd6\xd7\x2b\x27\xaf\xd7\x5d\x22\x16\x45\x27\x94\x5c\x72\x26\x84\x4f\xab\x15\xb8\xdc\xc9\x14\x34\x9e\x31\x41\xc6\x13\x16\xad\xc8\x94\xde\xdc\xdc\x84\x39\x84\xd9\xc7\xfe\xae\x39\xdb\x33\x2d\xc3\x93\xe9\xe8\x96\x1b\xbd\xe0\x71\xc3\xd2\x85\x8b\x3c\xb5\xf3\x3b\x16\x4a\x15\x61\x6c\x6f\xe1\xbb\xc2\x4a\x35\xf2\x13\x36\xd2\x61\xc5\xd8\xcf\x75\x9e\x27\xe2\x2c\x91\x01\xc4\xae\xbd\xe3\xe1\x26\xcf\x64\x6c\xa7\xb2\xe0\x31\x28\x09\x5c\x59\x76\xbf\x3f\x6e\x49\x1a\xf0\xf0\xb6\x40\xc7\x31\x09\x66\xac\x59\xc5\x9f\xbc\x5b\xfe\x05\x48\xf8\x8e\xe6\x1a\xd9\xec\x40\xc1\xc0\x6d\xd2\x9d\x79\x4c\x44\xa3\xea\x22\xc3\xd4\x76\x26\x22\xec\x1e\x8b\x33\x3e\x45\x07\x4d\xb9\x37\x41\xfd\xa1\x93\xc9\x11\xf6\xdb\x58\x79\xe5\x5e\xe3\x6e\xf6\x02\x61\x4a\xe6\x4a\x5c\xde\x9d\x83\x06\xd2\x2f\xbc\x4a\xe9\xc8\x81\xa5\x94\xbd\xe6\x79\x61\x25\xfc\xb6\x28\xb9\xf3\xb6\xfb\x3f\xfd\x51\x1b\x35\x3f\x14\x6a\x27\x27\x2a\xfd\x3e\x5d\x28\xb7\x7f\x58\xa6\x7f\x1f\xd2\x72\x85\xc2\x5e\xcc\x1c\xcf\x64\xe3\x8d\x21\xf3\xb9\xff\x22\xe0\x0e\xe9\x00\x62\x9e\xf1\xa6\x3e\x71\x3f\x25\x88\x83\xdd\x91\x1f\x30\xc0\xd3\x98\xb7\x4b\xd7\x97\x14\x9b\xe5\xe2\x69\x67\x22\xda\x09\xd5\x2d\x4e\xbf\x3c\x67\x39\x29\xd2\x98\xaa\xc3\x4c\xe0\x5b\xea\x08\xea\x9a\x42\x4e\x93\x45\x9c\x2e\xb8\xfc\x22\x22\xc3\x1c\xc1\x3d\x80\x3b\x90\xa8\xa7\x0b\xcd\x0a\x30\xc2\x09\x21\x1d\xc2\xcc\xc8\x5b\x0b\xcd\x45\x82\xc6\x95\xf5\x8d\x80\xbf\x6e\xc4\x71\xa2\x50\x5f\x68\x84\x7a\x75\xf6\xe9\x11\xfd\x87"}, +{{0x7e,0xd8,0x7c,0x36,0xdf,0xdb,0xae,0x60,0xc9,0x40,0xa3,0xb3,0x25,0xc1,0x9f,0xde,0xd8,0x14,0xd7,0x6a,0x54,0x48,0x20,0xa3,0x2f,0x28,0x6a,0x5c,0x0a,0xd7,0x1d,0x72,},{0x3c,0x4a,0xc5,0x10,0xb3,0x62,0x22,0xc2,0x52,0xa2,0xdc,0x1a,0xfc,0xb4,0x0f,0xb0,0xeb,0x85,0xbc,0xa9,0x03,0x91,0x19,0x6a,0x58,0x83,0xaa,0x2c,0xc9,0x12,0xb2,0xdf,},{0x57,0x9b,0x38,0x12,0x4b,0xd0,0x59,0x1a,0x59,0x7c,0xc9,0xa3,0x89,0x12,0x7c,0xea,0xf5,0x51,0x56,0x07,0x73,0x63,0xed,0xb8,0x11,0xd0,0xb6,0x55,0x52,0xac,0xfc,0xc6,0x77,0xb2,0x72,0x94,0x21,0x99,0xca,0x25,0xab,0x79,0x0d,0xe6,0xe0,0x84,0x60,0x3a,0xd1,0x05,0x2e,0xc2,0x10,0xcf,0x6f,0xcb,0x14,0x17,0x28,0x90,0x67,0xce,0x3c,0x08,},"\x62\xd3\x13\x91\x2a\xbb\xb0\x06\xb7\x77\x4a\x67\x37\x71\x4a\x34\x99\x70\xce\x04\x21\x11\x2f\x40\x04\x63\xd3\xdb\x0e\x2f\x7f\x12\x8d\x7b\x96\x93\x9f\x43\xc1\xe7\x10\x7b\x51\x18\xa7\x7c\x11\x96\x83\xd8\x66\xb7\xe3\xd7\x2a\xc2\x1f\x6b\x42\x72\xb4\xbe\x92\x89\xb6\x55\x6f\xe3\x1b\x60\x51\xa0\xb4\x2e\xd5\xea\x0c\xf3\x47\x69\x6d\x30\xfb\x8b\xff\x6b\x8b\x57\x27\x19\xde\x19\xa2\x31\xcc\x85\x45\x9a\x99\x0c\x37\x80\x1f\x08\x37\x18\x6c\xef\xbb\x55\x21\x56\x96\x66\x96\x7c\xd4\x24\x3d\x73\x07\xf1\xb0\xb2\x4c\x8e\x2b\x9b\x69\x23\x17\x30\x4f\xbe\x3d\xd0\xa2\x63\x65\x01\x91\xb3\x52\x16\xf5\x29\x16\x57\x3a\xf9\x05\x24\xf9\x1d\xb1\xa9\x24\x71\xd7\x58\xc9\x2d\xc6\xd1\x4d\x1a\x4b\x26\xf4\x1b\x40\x40\x3c\xa8\x7d\xcf\xab\xdc\xa4\x7b\x9f\xc2\x53\x35\x78\xf1\x61\xf3\xb0\x19\x9b\x5c\x69\x8e\x08\x07\x04\xb2\x1c\x9e\x61\x52\x69\xfc\xd0\xd4\x04\x39\xed\x8b\xc3\xbd\xfb\xc9\xaf\xb4\x4c\x11\xfa\x89\x27\x5f\x0e\xaa\xa5\xd0\x8f\xa9\x59\xd6\x37\x8d\x0d\xb8\x99\x10\xd4\x8f\x2d\x86\xa1\xeb\xfc\x5c\xbf\x10\xeb\x2d\x5a\xad\xf5\x1b\xbd\x83\x44\xff\x8b\xbb\x5b\x8a\xfe\x05\xa4\x50\x11\xb5\xe4\xb7\x2e\xb8\x64\xad\x26\x3e\x8a\x03\xa6\xc7\xf9\x8a\xee\xb3\x54\xf7\x30\xa3\x18\xaa\x30\xfb\x56\xd3\x3d\x80\x74\x8c\x98\xeb\xec\x15\x87\x8c\xcf\x3c\xe8\x22\xf6\x9d\x34\x56\x84\x3c\x40\x0d\xc5\x6b\x48\x1a\x95\xe6\x88\xb8\xa4\x73\x5b\xf3\x84\x3f\x58\x33\xdd\xa0\xef\xe0\x9e\x71\x75\xb5\x67\xc6\x61\x38\x7a\xfd\x2e\xbc\x07\x9a\x48\xe3\x49\x67\xec\x97\xb9\x27\xdf\xa5\x81\x88\x8f\x23\x1a\x98\xa7\xed\x33\x10\x3b\xfa\x8e\x8f\x9b\xa6\x51\x35\x27\x90\x0b\x39\xb8\x62\x31\xda\x79\x11\xa2\xfc\x93\x58\x88\xa7\x5f\x11\x29\x58\x4a\xff\xf2\x02\x52\x49\xc4\x18\x8f\x09\x05\x2f\x85\x68\x77\x06\xd0\x5e\x29\x91\x44\xd4\x0d\xe8\x89\x8b\x7c\x8b\x2d\xfe\xf0\xc3\x70\x85\x73\xd8\xb0\x56\x3a\x6b\xd0\xa5\x04\xc0\xb6\x74\x57\x02\xb1\xb5\x71\x21\xc6\xf0\x40\xaf\xf2\x71\x98\x94\x8b\xa6\x9c\x21\x25\x3a\x28\xd3\x9e\xba\x72\x62\x19\xbe\xda\x1f\x82\x09\xfb\x83\xe9\xad\xb0\x7a\xd4\x09\xfb\xd6\xd2\x55\x65\x88\x9a\xb4\x51\x23\xf9\xd9\x45\xec\xd7\xd9\xca\x70\x28\xec\xe0\x92\xe3\x5f\xbb\x7c\xb3\xf3\x28\x12\x6e\xfd\xda\xc5\xd8\x59\xf2\xb2\xc6\xeb\x09\x01\x33\x69\x0e\x20\xc1\x7d\xea\xf3\x88\x26\x85\xf0\x7e\x9e\xd2\x65\x3b\x80\x3b\x9b\x38\x3b\x70\x74\x8a\x1f\xa9\x2c\x86\xf8\x6d\x6c\x47\xea\x87\xb1\x0b\x12\xe3\x63\xba\x50\x80\x60\xf4\x7c\xe2\xa2\xf3\xb6\xa3\xee\xfc\xd4\xda\xcf\xc7\x1c\x41\xf4\x36\xfe\x0c\x2b\xc3\x4d\x4b\xaa\xd4\x95\x74\xe7\x44\x3c\x12\x6a\x58\x9f\x6e\xf7\xbc\xa4\x49\x54\xf0\xbb\x28\xec\x71\x51\xb0\x51\x1c\x23\xc6\xbc\x42\xd5\xe8\x59\x83\xec\x16\xbb\x5f\x50\xa3\x82\xd6\x88\x15\x0a\x49\x60\x9c\xbd\xe5\x69\x8e\x86\xdc\xbf\x02\x12\xc2\x29\x22\x99\xdc\x4d\xcf\x87\x42\x9f\x6c\xd2\xee\xc8\x09\x48\xce\x86\x7e\x25\xc9\x45\x84\xcd\xc6\x4b\x09\x90\x29\xeb\x85\x4e\xdc\x26\xea\x21\x42\x1e\xff\x48\xcf\x4e\x41\xf4\x9e\x2d\x89\x47\x8d\xef\x06\xc4\x2b\xea\x22\x0a\x13\x3e\x50\xf5\xc7\x44\x64\xc7\xe7\x3f\xb1\xc1\xa7\x7c\x50\x7c\xf6\xcd\xa8\x5b\xe4\x02\xb7\xe6\xd6\xd2\x1e\x81\x0d\x6d\x0b\x59\x72\xb9\xfe\x77\xe5\x4e\x74\xae\xe1\xf3\xbb\xfd\x6e\x7d\xe6\xb5\xc0"}, +{{0x6a,0x29,0xf8,0x1b,0x8d,0x9a,0xa4,0x8a,0x1b,0x23,0x36,0x4e,0xac,0x8f,0x6a,0x4b,0xdd,0x60,0x7a,0x84,0xcf,0xe8,0xe8,0x8d,0x90,0x17,0x5d,0x80,0x64,0x3a,0x58,0xa8,},{0x4c,0x3b,0xe3,0xa2,0xa8,0x42,0x5f,0xf3,0x1c,0x3a,0x0d,0xb4,0xa5,0x2a,0x0c,0xb1,0x41,0x6c,0xeb,0x48,0xcc,0x3e,0x4c,0x28,0xa4,0xf2,0x28,0x4a,0xb3,0x46,0x07,0x15,},{0xdf,0x09,0xcb,0x9b,0x87,0x8d,0x3d,0xc9,0xe5,0x42,0xdb,0xac,0x28,0x94,0x3e,0x28,0xe4,0x1d,0xce,0xcb,0x92,0xcb,0x7e,0xa4,0x40,0x09,0x88,0x5e,0x46,0x49,0x97,0x43,0x33,0x05,0x61,0xba,0x1d,0x36,0xae,0xdd,0x46,0x76,0x75,0xfd,0xca,0x2b,0xaa,0xa4,0x70,0x1b,0x6f,0xad,0x97,0x9f,0xd8,0x39,0xc4,0x70,0xd1,0x3c,0x82,0xda,0xa9,0x05,},"\x78\x76\xa3\xf4\xeb\x69\xbb\x7e\x54\xe9\xff\x95\x4e\xbd\x3b\x10\xb9\x3a\x4c\x1a\xfe\xae\x92\xfa\x03\xc1\x03\xcb\x63\x13\xa2\x01\xc5\xb3\x3a\x9a\x72\x23\x75\x5c\xb5\x10\xe2\x5e\xc5\x82\xb5\x4e\x81\xb8\x49\x56\xf6\xc5\x3f\x1f\x08\xa6\x3b\xf0\xc4\xa2\x61\xaf\x45\x0e\x52\x3f\xe8\xf6\x1d\xdb\x3c\x0e\xea\xb8\x75\x10\x72\x68\x88\x01\xb2\xa4\x73\xb7\x1a\x2e\x38\x70\x8d\xa6\x8c\x2f\x37\x92\x5c\xb0\x5a\x20\xc4\x28\x3b\x3a\xf9\x7b\x6f\x0b\xa6\x5a\x54\x03\x55\x43\x75\xe2\x15\xd9\xe3\xaa\x1b\x0f\x9f\xdb\x0f\x84\x99\x23\xed\xbd\xaa\x0a\xb4\x81\xc5\x45\xa5\xdf\x8f\x51\xd1\xf6\x8b\x22\x35\x07\xea\x0e\xcc\xfa\xeb\xb5\xfc\xcf\x5e\x3d\xfa\x65\xa4\x4e\xea\x50\x45\x68\xa8\x81\x80\xa0\x60\xbb\x06\xc5\x15\x57\xb8\x1e\x66\x7b\x4b\x04\xe3\x21\x0f\xa4\xc3\x79\x87\x6c\x49\xf3\xe5\x6b\xf2\xbe\x1c\xf5\x19\xa7\x41\x83\x93\xd2\x40\xdc\x8a\x22\x4c\x6c\x38\xac\x2a\xb9\xd8\xfa\xdf\xc5\x36\x20\x30\xc7\x93\x0c\x3c\xe7\x79\x5b\x14\x7c\x26\xc8\xa2\x8c\x65\x34\x29\xd9\x0a\x17\x3a\x86\xa8\xb1\x8a\x00\x9e\x62\xae\xf6\xec\xa9\x5d\x39\xbd\xbe\x45\x64\x77\x78\xa2\x53\x2a\x41\x5a\xe1\x9b\xad\x23\x11\x29\x12\x78\x42\xfe\x1d\x0f\x11\xfa\xb4\xa1\xcf\x0b\x17\xe4\x98\xcd\x59\x52\xc9\x39\xe0\x90\x09\x02\x87\xb1\x44\x89\x5d\xff\x00\xce\xc8\xd6\xae\xda\xf6\x24\x81\xa4\x17\x83\xe0\x21\x08\x2c\xe3\x52\x06\x3e\x62\x81\x1f\xd9\x99\x90\x10\x4d\x8a\x46\xcd\xca\xee\x2b\xab\x45\x8e\x52\x47\xfb\x02\x3e\x92\x33\x30\xa4\x28\xc7\xbc\xfd\x20\xb0\x8f\x52\x0e\x89\x46\xdd\x65\x83\x47\x35\x2a\xe0\xc4\xbe\x73\xc3\xd5\xec\xcd\x11\x14\x9f\x3a\xb7\xb8\x05\x2c\xfd\x95\xc3\x5d\x41\x64\x54\x6f\x5d\x8f\x37\x75\x17\xa7\xf4\x32\xc0\xd5\x56\x3a\x7b\xcc\x7b\xd1\x19\xd3\x42\x1d\xfe\xba\xae\x84\x45\x99\xb2\x9b\x38\x3b\xb8\xd5\xdb\xf1\x40\xd9\xbd\x47\xa0\x78\xb7\xae\x7c\x6a\xa8\x7b\x1e\x29\x23\x6c\x9f\xcf\xd6\x54\xb7\xf8\x09\x79\x4c\xcc\xb2\x61\x58\x8e\x18\xde\xc6\xc4\x04\x6a\x93\x40\x67\xd0\xdf\xa0\x37\x91\xd0\x3d\x83\xb7\x18\xac\x4d\x24\xdc\xe7\x85\xa3\x02\x8d\xe0\xc9\x59\x2d\xba\x7c\x5c\x58\x45\x18\x4a\xfc\x9c\x0d\xfc\xf9\x40\x95\x86\x0f\x0e\xb8\x02\xeb\xea\x20\x17\x8e\x78\xb5\x64\x2e\x5d\xd6\x1c\x33\xb3\x97\x69\x05\x2d\x9d\x85\x4d\xce\x90\x2f\x47\x6e\x21\xf9\x6c\x65\x0b\x46\x3b\x7b\xc3\xd0\xff\x29\x96\xb6\x5c\x57\x83\x1f\x8b\x7c\x0f\xb9\x15\xf4\xdd\x72\x26\xac\x95\x5c\xbc\x7d\xfb\x03\xf9\xb7\x58\xdd\x3e\x0d\xfc\xe2\xe0\xe5\x80\xc9\x1a\x30\xc7\x83\xff\x56\x7b\x17\xf1\x2d\xfd\x5d\x31\x37\x64\x6e\x20\x01\x1c\xdc\xaa\xe1\x11\x02\xdc\x71\x68\x86\xcb\xf1\x23\xc0\x94\x88\xb1\x73\x63\x6a\xbd\x54\xe9\x62\xca\xee\xc9\x7d\x5e\xb9\x40\x68\x2e\x70\x3b\x73\x0f\x61\x56\x2c\xd1\x4b\x9e\x65\x61\xb5\xe9\x3f\x60\xcd\x0e\x1e\x86\xd1\xa1\xb4\x71\x9c\x5b\x50\x82\x42\xbd\x6b\x2d\x9a\x54\x8f\x59\xbb\xb8\x75\x07\x59\x69\xef\x20\x32\xf3\x19\x6b\x8a\xec\xcc\x45\xa4\x4d\x9d\xbd\xaf\x87\x8e\xd1\x6f\x1d\x85\x5e\x89\x18\xed\x65\xa4\x5e\xe5\xc7\xfa\x32\xa1\xec\x69\x32\xa1\x59\xcf\xb5\x0f\xfc\x87\xbe\x06\xdf\xcf\x72\x28\xae\x88\x70\xcc\xd3\x57\xfc\x65\x6e\x33\xfa\x4b\x6b\x8b\x7d\x1a\x72\x15\x55\x3c\xab\xac\xc7\x0a\x39\xc9\x80\xb9\x71\xe5\x1a\x17\xed\x63\x18\xb4\x3b\x29\xbb"}, +{{0xef,0x12,0xdf,0x47,0x9d,0x98,0x3a,0xd9,0x6e,0x8b,0xa6,0x53,0x30,0xb3,0x6d,0x49,0xaa,0xdb,0x98,0x31,0x64,0xe1,0xc0,0xb4,0x52,0xb5,0x60,0xde,0xd1,0xd0,0x8d,0x60,},{0xf7,0x61,0xcf,0x28,0x26,0x92,0x7a,0x7c,0xda,0x8c,0xb0,0x4f,0xaa,0x2c,0x59,0xf8,0x42,0x5a,0x8f,0x7d,0x39,0x8f,0x76,0xe8,0x67,0x02,0x1c,0x95,0x1f,0x07,0x38,0x09,},{0x4c,0x80,0x10,0x86,0x6d,0x91,0x15,0xf0,0x52,0x93,0xb9,0x34,0xca,0xc6,0x81,0x04,0xcc,0x2c,0x34,0x37,0x56,0x8c,0xb9,0xd5,0xc5,0x70,0xb1,0xa8,0xbe,0xe7,0x06,0x60,0x30,0x75,0x53,0x70,0x33,0xbd,0x70,0x8a,0x9c,0x9f,0x3d,0x1e,0x25,0x19,0xa9,0x15,0xb1,0xc4,0xae,0x4c,0xcd,0xdf,0xcf,0x0e,0xd0,0xc0,0x49,0xd3,0x42,0xa0,0x2e,0x02,},"\xe5\x8f\x34\xda\xea\x75\x5a\xc4\xe4\x13\x33\xd6\xf0\xed\x01\x35\xf7\xdb\xce\x50\x30\x9b\xb1\x95\x6b\xc7\x1a\xcb\x12\xc7\x70\x67\xa6\x47\xff\xd8\x6a\xa5\x87\x0c\x0c\x00\x07\xe8\xf9\x95\xa2\x2b\x88\xc4\x67\xde\x22\x54\x44\x54\x42\x01\xc5\x57\x49\x5e\x25\x3e\x33\x19\xcc\x5c\xa3\x76\xd3\xe7\xcc\x1e\xb4\x67\x34\x6e\x52\xad\x95\x6a\x6f\xa7\x33\x72\x0b\x17\x11\x7b\x5b\x75\x85\xe4\xd5\x59\x40\x9a\xae\xfa\x95\x58\x0f\x91\xe5\x02\x01\x5f\x49\x7c\x5c\xdc\xb7\xd4\xd5\x61\xf5\x44\xef\xa3\x5c\x1e\x2a\x53\xb7\x2b\xdd\xec\xee\xc2\xd1\x05\x0f\x17\x7d\x48\x0f\x68\x74\x05\x66\x4d\xfd\xde\xc0\x6e\xee\x4b\xd1\x47\xa9\x12\xfd\xbf\x74\xf2\xa9\x5d\x1f\xd1\xe1\x12\x68\x69\x4c\xe4\xd4\xec\x4f\xff\xd6\xdd\xb3\x25\x4d\x36\x0f\x23\x6f\xab\x4d\x1a\x17\xf8\xd0\xd1\xa5\x11\xf9\x44\x69\x2f\x23\x96\x39\xae\x03\xd6\x4f\xac\xec\x65\x38\x42\x7a\xb7\x1f\x71\x27\xf4\xa2\x76\xf9\xbc\x45\xbb\xa6\x11\xdf\xcc\xe6\x44\x6c\xc1\x39\x68\x97\x6c\x8b\xb6\xd6\xfe\x21\x06\xd7\x05\x92\x2d\xca\xc9\x56\x96\x6a\x76\xd4\x8f\x2a\xff\x4b\x86\x51\x4e\x39\xa6\x7e\x16\x43\xfc\xc3\x21\x85\x80\x24\xe6\x93\x18\x98\x33\xc8\xad\x59\xb4\xb6\x25\x29\x8e\xba\xfe\x64\x62\x6b\x48\x0f\x32\x6f\x13\x40\x72\x3c\xb3\xd3\x83\xf4\xfc\xcb\xfc\x23\x7a\x3f\x4c\x4f\x7e\xcf\x0b\xa4\x36\xb3\x2c\x2f\xe3\x51\x79\xda\x93\x11\x1b\x48\xcc\x9e\xa2\x42\x02\xbd\xc1\xb2\xfb\x60\xa4\x31\x9d\xfd\x98\x64\x47\x0f\x73\xf5\x41\x37\x20\x6e\x0b\xf0\x07\xf5\xae\x88\xa8\x87\x47\x00\x8a\x60\xf4\x78\x9a\xd1\x67\x72\x4f\x17\x9c\x02\xb6\x3a\xed\x00\x25\x73\xd2\x8a\x6b\xcf\x88\xe0\x7c\xe8\xda\xea\x5d\x5f\x1a\xcf\x48\x7b\x4c\x5c\x16\xc2\xbf\xe1\x12\x31\xea\x5e\xa7\x63\xe8\xf3\x32\xcc\x73\xda\x1b\x2f\x8c\x19\x8e\xa8\x17\x3f\xd3\x3d\x4b\x2a\xe6\x9e\x5d\x4d\x1a\xad\xdd\xf2\xfd\x82\x1b\x85\xbe\x45\x15\x19\x62\xd1\xf9\x9d\xf8\x13\x08\x61\x88\x52\xad\x7c\xf4\x1d\x72\xda\x08\xa1\xb3\x9d\xf7\xd8\xb9\x94\xb4\xdd\xff\x37\xf9\xdf\xe8\xf3\x8c\xe3\x0e\x91\x06\x1d\x95\xd5\x8f\x7a\xe8\x26\xb0\x23\x85\x27\x2e\xc0\x9f\x01\xa7\xb3\xe4\xb3\x91\xd0\x9b\xce\xd6\x65\xda\xd6\x95\x05\xb4\x19\xda\x84\x81\xbc\x37\x92\xbf\x8b\x8e\x7a\xd6\x4b\x63\xf2\x45\x66\x6c\x8c\x32\xfd\x5c\x1b\x1b\x48\xc9\x95\x1e\x1c\x21\xa1\xeb\x5f\x50\x7c\xff\x13\x7c\xfb\x86\x2c\x2c\xc9\x87\x66\xe8\x78\xc9\x30\xa0\x83\x82\x8c\x9d\x8d\xb1\x8b\xf1\x67\x16\x68\x5f\x39\xd6\x57\x2a\x8c\xa8\xb2\xa5\x14\xf7\x70\x03\xd4\xe7\x5b\xc1\x54\xae\xbf\x14\x10\x37\x78\xf3\x65\xb1\xc3\xf0\x35\x41\xdd\xbd\x07\xd6\xe2\x3e\x56\x76\x2d\x97\x1e\xb0\x29\x83\xe9\x3c\x4e\x01\xba\x4b\x8a\x21\x78\x92\x8c\x43\x37\xd3\x02\xf3\x1c\x9c\xcb\x75\xb2\x49\xa8\x2d\xc9\x68\x21\xe9\x5a\x03\xab\x6b\x77\x0d\xf2\xc3\xdf\xdb\xf1\xfe\x97\x73\xf8\xbc\x1b\xc5\xb3\xaf\xa0\x44\x0b\x10\x25\x78\xf3\xd2\x13\xc8\xd0\x19\xcf\xf1\x24\xf7\x5c\xe4\xac\xcc\x8c\x66\x7f\xeb\x27\xc7\x51\xa6\x12\x00\x74\x81\x31\x04\xe0\xcd\x07\x0c\x9f\x5e\x45\x1d\xcc\xff\x4c\x80\xd7\x11\x07\xc9\x75\xab\xfa\xc0\x7d\x4d\x27\x0c\x72\x7d\x8a\x2f\xec\x34\x9b\x53\x39\x68\xe2\x71\x89\x2d\x2b\x62\xc1\x25\xfb\x79\x74\x60\x3c\x30\x5e\xa3\xbf\xa3\x0f\xb6\x10\xfc\x5a\x23\xeb\x68\xa8\x40\x64\x44\x39\x1a\x52\x13\x37"}, +{{0xf7,0x31,0x31,0x7c,0xf5,0xaf,0xfe,0x58,0x70,0x4c,0x4d,0x94,0x97,0xae,0x86,0x0b,0xbf,0x73,0x9d,0x0f,0xd9,0x6b,0x7c,0x02,0xef,0xb6,0x77,0x7b,0x3c,0x85,0x8a,0x19,},{0xd7,0xd6,0x38,0xae,0xcc,0xe1,0x46,0x1e,0x31,0x42,0x55,0xaa,0x29,0xd9,0xa6,0xb4,0x88,0xae,0xa1,0x39,0x6e,0x96,0x82,0x69,0x5a,0x47,0x0e,0xff,0x23,0xf3,0xed,0x84,},{0x2a,0x4f,0xea,0x98,0xf9,0x24,0x01,0x71,0xa1,0x82,0x3f,0x2f,0x69,0x35,0x20,0x62,0x67,0x2e,0x6c,0x6e,0x66,0x52,0xd3,0x88,0xa8,0x77,0x14,0xd6,0x47,0x99,0x5d,0xf7,0x5b,0x6e,0x1e,0xd1,0x74,0x6a,0xf2,0xad,0xf4,0xe8,0x06,0x13,0x5d,0x60,0x75,0x4e,0x60,0xfe,0xa0,0x32,0x12,0x8e,0x35,0xab,0xc1,0xf1,0x61,0x51,0x81,0x12,0x5f,0x0b,},"\x16\xf5\x1c\x59\xe9\xae\xfc\x26\xb0\xda\x5e\x00\x85\xeb\x2e\x2f\x1f\x85\x6d\xef\x97\x25\x76\x9e\x3a\xf1\x2f\x86\x09\x05\xae\x13\x3f\x65\x07\x4d\xa7\x6d\xbf\x25\xc6\x7f\x62\x57\xd2\xdc\x66\xc0\x5f\x9b\x31\xae\x17\x7b\x69\x92\x9f\xc1\x83\xb5\x88\xc5\x19\xbc\xa1\x47\x96\xa0\x89\x6d\x29\x05\xfd\x94\x2d\x7a\xb4\xa3\xfd\x95\x41\xa5\x52\x9f\x72\x9c\x58\x51\x41\x9b\x5f\xbe\xf7\xb1\x34\xd6\x76\x2e\xb9\x7e\x8a\x95\x1a\x8f\xf5\x2a\xa0\xd7\xe6\x74\x44\xd0\x6b\x07\xaa\x55\xe4\xeb\x9a\xb8\x92\xf4\x7b\xfd\x11\x1d\xf5\xb6\x2f\x6f\x3f\xd1\xa5\xed\x84\x12\x5f\xee\xbb\x77\xda\x63\x7c\x05\xd5\x26\x5c\xed\x11\x3d\xfe\x87\x82\xdb\xd1\xce\xcd\x2c\x6c\x03\x2b\x8f\xa8\x85\x5b\x3a\xe7\x8d\xe7\x4f\xaa\x5a\xa2\x0a\x76\x14\x63\xc2\xa3\x0b\xe6\x6b\xd3\x8c\xde\xc7\x5f\x89\x57\xcb\x94\xc1\x13\xa4\x5d\x54\x6d\xaf\x47\x5d\x89\xaa\x14\x82\xf8\xd2\x80\x3a\x23\xc9\x39\x20\x20\x15\xa0\x8e\x94\xb1\x32\x72\x8f\xbe\x8f\x60\x19\xd7\x16\x8a\x08\xa5\x93\x01\x70\xe5\x63\x9d\x11\x0e\x47\x39\xdb\x85\xe6\x1e\x64\x49\x59\x44\xb5\x42\x3a\x74\xad\x5a\x8a\x0a\x51\x06\x12\xec\xe6\x55\xce\x18\x86\x40\x51\x52\x5b\x90\x8e\x0b\x19\x29\x0a\xbe\x8b\x11\x82\xc4\x8c\x70\x0d\x35\x05\x15\xfd\x34\x99\x56\xe8\x08\x73\x27\xf3\x0b\x6f\xc3\xf1\x31\xc2\x14\x4a\xbb\x3f\x0e\x9c\xa3\x31\x17\x2b\x35\x06\x4a\x82\x81\x1a\x68\xe2\xcf\x36\xb4\x3e\x3a\xd2\xe8\xdf\xa5\xb1\xce\xf5\x0e\x2a\x60\x29\x3f\xc5\xf6\x35\xc9\xa9\x99\x8d\x8c\x1a\xd2\x96\xe7\xc7\x8f\xc0\x58\x20\x22\xd6\x30\x67\x18\x6b\x65\xe7\x64\x82\x8c\xc0\xf5\xf7\x63\x2d\x5e\xef\x86\x3e\x6c\x6d\x90\xe3\x8c\xcc\x87\xd7\xb7\x47\xfa\xc8\x49\x1d\x63\x2c\xf7\xf5\x4b\x9a\x9e\xed\x16\xee\xbe\xc0\x1b\x6c\xc3\x3d\x24\x63\xf7\xf9\x50\xd8\x28\xb5\x5e\xe3\xf7\x7c\xbe\x97\x4f\x48\x94\x8e\xb7\x57\xae\xd4\xe0\xdb\xb0\x0a\xd9\x5e\xe0\x13\x23\x48\x6e\xba\x3c\x8d\xa8\x86\xed\x7f\x57\xbb\x40\x0d\x63\xa1\xb2\xeb\xea\xa2\xe7\x0a\xdf\x03\x79\xe3\x39\x30\x01\xba\x62\x6c\x0d\xd5\x4b\x7f\x0c\x9a\x25\xaa\xe6\xc9\x87\x5d\x4e\x76\x22\xf3\xed\x42\x8f\xb3\x12\x4b\x29\xc5\xdb\x9a\x7e\xf1\x6e\xbd\xdd\x68\x05\xf0\x95\xf5\xe7\x69\x82\x3c\x43\xf2\x62\x86\x8f\xf4\x3e\x3e\x05\x25\x74\x6d\x94\x97\xaf\x12\x4a\x01\xdf\xf6\x1e\xc7\x18\xaf\x3b\x5b\xb7\x46\xfc\xc0\x8a\xeb\xd1\x66\x84\xd4\x56\xae\x79\x32\xff\x5e\xd7\xd6\xb0\xf1\xb2\x5c\x7a\xde\xef\x59\x8b\x5d\x58\x87\x75\x90\xac\x1d\xc0\x59\x75\x15\x67\x96\x99\x87\x74\x08\x1e\x5b\x66\x82\x2a\x94\xa6\xa8\x02\xc3\xa2\xcd\x9f\x48\x9e\x16\x28\xaa\xf4\x65\x2b\xe1\x18\x4b\x0f\xc7\xc5\xee\x7f\x97\xce\x08\xb9\x23\x3b\x4b\x83\xd9\x36\x7b\xe5\xf4\xaa\xe9\x78\x25\x93\xa3\x52\x65\x15\x4d\xea\x4c\x37\x5c\x16\xf0\xca\xf6\xdc\x45\x94\xd2\xbd\xbf\xc3\x37\x5b\xb2\xa0\x43\x2c\x48\x2f\x13\x94\x1c\xe2\xaa\xab\x4d\x83\xe7\x4d\x11\x6f\x5d\xe4\xab\x28\xf8\xdc\x3d\x1c\xd1\x9d\x27\x1e\x56\xe1\x03\x98\xbd\x1d\xf5\xc8\x70\xfc\xbf\x93\xa7\xd1\xdf\x39\x39\x54\x7c\x10\x7b\xfd\x90\x64\x3f\x6f\x50\x01\xae\x7e\x06\x39\x7a\xe1\xa2\x71\xbb\x82\xa1\xf3\x8e\x09\x7b\xec\x66\x74\x66\xb8\x0e\xe3\xe5\x0d\xd4\xfc\x9d\x5d\x54\xf1\x8f\xaf\x7a\x5b\x55\xa8\x83\x45\x94\xef\x0c\xb7\xe5\x08\xbb\xd2\x8f\x71\xfd\x34\x23\x5b\xbf\xd3"}, +{{0x49,0x8e,0x5a,0x21,0xa9,0xb0,0xc3,0x47,0xba,0x83,0xa4,0x7a,0xc1,0x00,0x69,0x45,0x7f,0x57,0x83,0xc2,0xe1,0xe6,0xe4,0x64,0x00,0x45,0xe5,0x94,0xb1,0xc6,0x93,0x32,},{0xfb,0x39,0x48,0xc8,0x11,0x99,0x56,0x91,0x05,0xcc,0x1b,0x7d,0x9c,0xeb,0x3b,0x41,0xa3,0x43,0xbb,0x00,0x57,0x55,0x38,0x59,0x2e,0x09,0x84,0xf4,0xf4,0x71,0x0a,0xbe,},{0x28,0x60,0x83,0x0c,0xcd,0x1d,0x41,0xd9,0x50,0x76,0x81,0x6a,0x39,0x84,0x24,0xf7,0xb7,0x39,0xc4,0x9f,0xda,0xcf,0x56,0x54,0x52,0x9d,0xa8,0x5f,0xe3,0x56,0x55,0x84,0xf6,0xaa,0xc2,0x61,0x4c,0x63,0xf7,0x74,0xb6,0x1d,0xb9,0x08,0x1f,0x14,0x10,0xfb,0xa8,0xe5,0x0a,0xb3,0xb4,0xc3,0x9d,0xc0,0x63,0x14,0x24,0x3f,0x3f,0x0d,0x8e,0x0f,},"\xe4\xfb\xea\x86\x4a\xa5\x11\x90\x82\x66\x45\xd2\xf7\x72\xcb\x0f\x9e\xdd\xd3\x03\x44\x73\xfa\x31\x77\xc7\xaf\x9a\x5d\x41\xe1\xa7\x3a\xd5\x78\x4c\x70\x96\x55\x9f\xcd\xdb\x7b\x7c\x85\x89\x1c\xf2\x4e\x82\xc5\x88\xd7\x47\x74\xff\xca\xc0\xc6\xb4\xee\xbc\x2f\x3f\xa4\x3e\x9d\x45\xf2\x59\xd6\x75\x64\x03\x0c\xfe\xea\xb9\x23\x6c\x66\x5b\x65\x0a\xf0\xc9\x2c\x87\x51\x89\xf5\xf9\x38\x35\x04\xb1\x53\x60\xa0\xb9\xa5\xa0\x0d\xa3\x1f\x63\x5b\x96\xf6\xc7\x3e\xf4\x7b\x6b\x06\xf0\x28\x11\xd1\xd1\x9c\x2e\x8e\x53\x55\x0c\xe2\x2e\x42\xec\x50\xa1\xeb\x2e\xa2\xf4\xcd\x03\xc4\x42\xd4\xaa\x43\x68\x94\x23\x8c\xeb\x18\x35\xfe\x99\xb2\x40\x35\x8a\xa0\x56\x2c\x24\x96\x98\xa3\xf1\x23\xc2\xc1\x7e\x59\x10\x10\xbd\x6f\xdf\xcb\xd7\xdb\xe7\x0b\x04\x52\x05\x02\xec\xe3\x7a\x9a\x1d\xfa\x1a\xe3\x37\x04\x17\xb0\x04\x21\x7a\x5b\x8f\xe9\x90\x3c\x9a\x3b\x9f\x4b\x6d\x5c\x46\xc0\xed\x0c\x53\x8c\xec\x22\xf2\xdf\xcb\x2a\x28\x0a\x42\xad\xc4\x89\xcf\x2e\x06\x29\x12\xbe\x99\x28\xf0\xc0\x60\x89\x1e\x43\x20\x91\x17\x75\x26\xf1\xb3\xa9\x68\x06\x9d\x4a\x57\xad\xe8\x28\x55\x98\x10\xae\x03\x60\x68\x1f\xf9\x93\x29\xfa\x0f\x59\xe7\xe5\x9c\xdf\x87\xf9\xf3\x3c\x40\xe9\x70\x31\xb9\xf8\x1d\x48\xfc\x12\x28\x6e\xfb\xb3\xd4\xe5\xa6\x2e\xf5\x7b\xc0\xd5\x2d\x53\x3b\x99\xc5\x10\x6a\xa7\x9c\xfe\x17\x93\xa9\x08\x51\x85\x96\xc3\x83\x48\x3e\xc4\x9f\xf9\x8e\xc5\x57\xbf\xff\x74\x90\xa4\x6d\xaf\x67\x14\xf2\xc2\xc3\x2f\x57\x93\x2c\xa0\xd7\x30\xf0\x3f\x38\x1d\x69\xde\xcd\xbd\x9a\x7a\x6d\x4a\xfc\x62\x40\x65\x43\xc8\xeb\xe9\x0a\xc7\x6e\x6a\xfa\xbd\xb8\x24\x92\xa2\x06\xa3\x69\xe0\x42\x86\xd3\x13\xe1\x11\x07\xd8\xcd\x9b\x4b\xf6\x8f\x81\x5d\xba\x4e\x99\x0b\x04\x9d\x79\x21\x6d\x36\x53\x13\x83\x42\xcd\x11\x8b\x13\x0f\x66\xb0\x06\xf3\xd8\x9a\xc3\xcf\x89\x83\x70\x48\xb0\xf8\xa6\x2d\x94\x05\x1d\x2e\xab\x89\x1a\xc5\xf4\x78\x88\x87\x9d\x88\xe5\x46\x67\x6d\x1d\xae\xeb\x4d\x17\x5d\x3f\x04\xa9\xd7\x4f\xfc\xdd\x47\x74\x60\x16\xf8\x4a\xd0\xd1\x12\xaf\xb5\x9a\xd1\x21\x87\xe9\x4f\x22\x53\x5d\x77\xe9\xe0\x51\x6f\xa4\x21\x85\xc1\x97\xba\x77\x4b\x39\x32\x27\xf7\x41\xfe\x68\x27\x3f\x42\x3f\xb0\xe0\xe0\x47\x4b\xfd\xaf\x2d\xa7\x8a\xeb\x1c\xd5\xb9\x8c\x1d\xc0\x83\x21\x24\x74\x2a\x47\x54\x12\x5f\xc7\x8b\x19\xc5\x59\xa5\xb3\xf7\x71\x1e\x06\x8c\x44\x0c\xc0\x46\x9a\x1c\xfa\x5c\x18\x64\xbe\x18\x73\x5a\xa8\xbc\xd4\x06\xc4\x37\x1e\xb8\x57\x75\x4d\x90\x8b\xf3\x79\xb9\x1f\xcb\x24\xe3\x43\x96\xbf\x87\xc1\x9a\x04\xa8\x3d\x59\xda\xe7\x1f\x3f\x38\x39\x82\x9d\x06\x22\x13\x01\xef\x59\x56\x96\xe7\x19\xd5\x6b\x79\x52\x0a\x0e\x50\x99\x29\x83\x3b\x1d\x80\x4a\x6a\x0e\xa4\x04\x00\xbb\x45\x02\x8c\xe5\xd3\x69\x33\x88\x3e\x17\x40\x6e\x27\xa8\x10\x90\x57\xb1\xa1\xa5\xe5\xda\x21\x0a\x69\x21\x99\x4f\x46\x7a\xb4\x1a\xa8\xf0\xd8\x87\x75\xa8\xa8\xeb\xb4\xec\x77\xd7\xc8\x0e\x45\xa7\xbb\x42\x2a\x4c\x00\xc9\x05\x83\x91\x14\x65\xe6\xb5\xf0\xfd\xcd\xea\xb7\x28\x71\xca\x54\x2e\x1d\x1a\x2c\xa9\x4d\xf4\xed\x2e\xab\xf9\x0d\xed\x00\x45\x29\x03\x24\xa9\xff\xfb\x30\x14\x54\x70\x20\x9f\x38\x26\x58\x09\x89\x34\x91\x99\xdc\x5a\xb8\xd4\xa2\x5d\xf7\xa0\x52\x9c\xf9\x14\x71\xe3\x08\x42\xab\xfa\xcd\x44\xab\x78\x1d\xfc\x13\x95"}, +{{0xc2,0x4c,0xbf,0x40,0x1a,0xd0,0x3b,0xd8,0x8d,0xcc,0x7b,0x51,0x9e,0xcf,0x62,0x4d,0xb2,0x22,0x3e,0x99,0x02,0x89,0x30,0x9e,0x1e,0x9f,0x1f,0x8f,0x61,0x27,0xc6,0xc9,},{0xa7,0x46,0x66,0xf3,0x57,0x20,0x9f,0x71,0x89,0x90,0x37,0x88,0xf1,0x07,0x56,0x3e,0x50,0xc0,0x51,0xc3,0xd4,0x0c,0x3f,0x3d,0xad,0x10,0xd3,0xc3,0xcf,0xf1,0xe6,0x78,},{0x58,0x1e,0x6c,0x85,0xae,0xc6,0x23,0xb6,0x2b,0x3d,0x4c,0x9b,0xc9,0xc7,0x77,0x59,0xd5,0x49,0x27,0x22,0xe2,0x52,0xd4,0x4c,0x1f,0x8a,0xda,0x9d,0xa2,0xec,0xc6,0x7c,0x17,0x08,0x32,0x73,0xaa,0x09,0x1b,0xba,0xc0,0x46,0xae,0x63,0xc7,0x88,0x93,0x15,0x2e,0x14,0xd9,0x26,0xc4,0x1a,0xe3,0x5f,0x0e,0x6e,0x39,0x59,0x49,0x6b,0x13,0x06,},"\xe7\xfa\x35\x9e\x6a\x09\xb2\xc5\x4a\xab\xed\x3b\xba\xbf\xb7\x28\x53\xa8\x05\xaa\xbc\xf4\xd1\x8d\xda\xd3\x9f\x03\xf3\x46\x01\xe5\x5b\x6c\xe2\x63\xc9\xa3\xca\x6a\x3e\x5f\x14\x25\xc8\x21\x92\x8c\x61\xe7\xf7\x50\x91\x9b\xd3\xaf\x32\xbc\xb7\xb9\x4d\x45\x9a\x7a\x9a\x35\xf6\x1c\x94\x17\x92\xe2\xcc\x2e\x43\x27\xbe\xb3\x44\xa8\x41\xa0\x7f\x32\x06\x8a\xf1\x02\xb3\xde\x61\xea\xb6\x4e\xf6\xd5\xe6\x90\x62\xe3\x93\xab\x5e\xdf\x6a\xc9\xef\x7b\x38\xd4\x9a\x01\xbe\xf0\x00\x3f\x42\x11\x74\xc8\x88\x59\x75\xc0\x18\x32\x89\x9c\x31\x35\xe7\xa8\x6e\x5b\x55\xd9\xb1\x32\x8b\xb4\x28\x9b\x5c\x40\x20\x0f\x49\xe5\x52\x3b\x3c\x46\x1d\xc7\x17\x5e\x14\x65\x02\x22\x97\xc3\xd3\x80\xf2\xb1\xfe\xf3\x9c\xb8\x2c\x00\xfd\x16\x0f\x44\x7e\xb5\x12\x63\xfa\x25\xb4\xdf\x0f\xca\x41\xec\x0c\xa2\xec\xe7\x47\x22\x01\xaf\x86\xc3\x03\x8c\x49\xdf\x09\x9a\x9a\xef\xa1\xf8\x8d\x0e\xdf\xd1\x7c\x0b\x3c\x86\x04\x66\x29\xc0\x94\x54\x05\x4a\xa0\xfb\x2c\x69\x49\xdd\x9c\x13\x01\x85\xdf\xa5\xd9\x03\x89\x1e\x08\x74\x2c\xd0\x42\x94\x03\xf5\x7f\x40\x52\x15\x8b\x2f\x40\x1d\xa4\x75\x68\x54\xe4\xaa\xf0\x24\x22\x1e\x37\x51\x3c\xf6\x77\xee\x6a\x0b\x15\x9f\x50\x1d\x37\x7e\xa3\x2e\xb7\x1e\x77\x80\x04\xf2\x72\x03\xcd\x6d\x55\x3f\xda\x5d\x65\xe1\x87\x94\x77\x04\x6f\x3e\xa3\xd1\xd7\x5c\x9d\x0d\x30\x31\x14\x56\x70\x9c\xc7\xf6\xab\x68\xc7\xb0\xd5\x2b\xe4\x0f\x04\xcf\x65\x56\x55\x32\x32\x85\x31\x83\x29\xe8\x4c\x6a\x5b\x07\xe0\xce\xed\x5f\x78\xf7\xf1\xfa\x62\x29\xbe\xf8\x78\x79\x3c\x58\x47\x28\xab\xf4\x51\x0b\x7f\x27\x79\x4b\x59\x42\x91\x62\x54\xc5\x89\xa0\x9c\x8e\x91\x1f\x0b\x95\x42\x11\xa6\x36\x99\xa7\x52\x14\x7f\x2a\x4e\x1a\x18\x95\x66\x44\xbe\xa2\xca\x26\x92\xba\x18\x22\x80\xe0\x4a\x72\xdd\x89\xb0\xd1\x26\x85\x00\x93\x8f\x34\x7b\xf4\x3f\x2a\x24\x2e\xe9\xb9\xa6\xba\xac\x9b\x35\x0d\x65\x6f\xb1\x9e\xc8\x34\xab\xe3\x16\x44\x40\xf2\xd2\x07\x1f\xe5\xe3\x2c\x8e\x4c\xf9\x05\x53\x9b\x83\x9c\xee\xca\x26\x20\xfc\xb2\xa0\x87\xf7\x80\xe6\xc7\xf5\xe0\x5c\x50\x68\x88\x25\x0e\xa7\xc8\x56\xfb\x30\x98\x32\x00\xaa\x8f\x78\xfc\x17\x71\x05\x4a\xda\x0f\x3f\xac\x38\xae\x2f\x33\xdc\x4a\x4f\x85\x1b\x76\xed\x74\x0c\x09\x62\xa7\x6a\x4d\xe4\x40\x80\xdc\x62\x0a\x44\xad\x8f\x23\xd3\x46\x2b\x79\x2a\xb3\xaf\xb1\x9c\xb8\xa9\xf4\xd9\xe5\x9a\xd7\x65\xa7\x71\x89\x9d\xa8\xcb\xec\x89\xe5\x07\x7e\x85\xc0\xc9\x31\x26\x37\x6c\x94\x1b\xef\x1f\x8b\xb9\x92\xd3\xa3\x5f\x27\x07\x25\x84\x6f\xb2\x52\xf8\xb5\xfb\xb7\x56\x7e\x40\x6a\x1b\x53\xb6\x19\x76\x9e\x63\x2b\x2b\x40\x87\xcd\x4c\x27\x6e\x5d\x58\xff\x2b\x56\xe8\x9e\xde\xc4\x8c\xe5\x3a\x52\xe3\x29\xca\x15\x59\x53\x8f\x10\x90\x2c\x01\xa8\x5f\xbb\x3c\xd7\x2e\x6b\x82\x91\xe5\xfe\x63\x9b\xee\x9d\x47\xd3\x4c\x24\x9a\x7a\x07\xd7\xa1\x42\x7a\x01\xf6\x3d\x60\x98\x4c\x45\x0b\xef\x81\x9b\x19\xf6\x5e\x26\x14\xfd\x9c\x2f\xae\x7b\x92\x31\xa0\xbc\xa4\x14\xed\x94\xa5\xee\x7e\x66\x32\x7d\x2a\x99\xc8\x48\x78\xb7\xbe\xe0\x87\xe8\x91\xf2\x53\xfa\x1f\xec\xe3\x13\x64\x8c\x06\xc4\x5d\xb2\xd9\xf3\xbc\x85\x99\x93\x7b\x75\x2d\x38\xce\x50\x63\xd0\xed\x9a\x43\xec\x9d\x40\x15\x89\x3d\x43\xbf\x5b\x2d\x1c\x60\x47\x85\x10\x46\x89\x68\xb7\x96\xf0\x15\x37\x89\x59\x54\x41\x72\x2a"}, +{{0x8b,0x3d,0xcd,0xe4,0xab,0xbf,0x4e,0x62,0x11,0xc4,0xa5,0x1c,0x4b,0x02,0x68,0x00,0xa8,0xa2,0xa0,0x61,0xcb,0x38,0xa2,0xec,0xc7,0xc9,0xcf,0x11,0x3f,0x92,0x70,0xbf,},{0x51,0x45,0x35,0x58,0x0f,0x0d,0xe3,0x59,0xbb,0x0d,0x41,0xf2,0xef,0xdd,0xaa,0x04,0xc2,0xec,0x95,0x01,0x19,0xf3,0x16,0x34,0xb2,0xc1,0xa3,0x2f,0x19,0x5f,0x69,0x68,},{0x4f,0x3d,0x4d,0x22,0x85,0x03,0x01,0x7e,0x74,0xa6,0xbb,0x58,0xaa,0xfa,0xe3,0x5c,0x3f,0x37,0xbd,0xee,0x4f,0xf6,0xbe,0x2e,0x62,0x40,0xb5,0x08,0x2f,0xed,0xdb,0x22,0x27,0x35,0xe1,0x2f,0x31,0xe0,0x56,0xfa,0x68,0x54,0x47,0xe5,0x38,0x48,0x03,0x00,0x7e,0xa7,0x91,0x0e,0x60,0x5c,0x1b,0x78,0x11,0x8c,0xd5,0xac,0xc5,0x87,0xa6,0x06,},"\x48\x14\x25\x02\x7d\xa6\x72\xb6\xf2\x6c\x91\xb8\x0e\x55\x58\x2c\xae\xf4\x7b\xb1\x5a\x2d\xe8\xfc\xa8\x52\x22\x17\x85\x18\x0b\x20\xa7\xfd\x6d\x49\x07\xb5\x88\x1c\xc1\xd6\xe3\x9a\xb9\x61\x2c\xc7\x4d\x69\x77\xe9\x14\x1f\x70\x87\xbb\x27\xab\x30\x84\xa2\x62\x85\x58\x6f\x84\x11\xdb\x1f\x50\x3a\xdf\x52\xdc\xb2\x5a\xb8\xff\xfd\x2e\xc1\x50\x4c\x17\x77\xb9\xd6\xdd\x4a\x29\xe2\x01\x9e\x5c\xba\xe1\xb7\xeb\x26\xf9\x5b\xbe\x07\xd9\x0c\x2f\x6f\xb0\x88\x4a\x59\xa8\xd5\x8d\xde\x51\x16\xed\xc3\xbc\x34\x9d\x37\xc1\x60\xb2\x7b\xef\xbe\x5a\x5c\x18\x1c\xe7\x25\x63\x92\x35\x4d\x22\x1b\x58\xc4\x7e\xb0\xbb\x10\x92\x9e\x74\x21\x79\x5f\x4b\x7a\x7c\x27\x5e\xdd\x08\xc0\x88\x56\x87\x72\xe9\x93\x21\x8d\xd6\xf3\xc2\xcb\x4a\xc6\x57\xa0\xa3\xf9\x1f\x31\x26\xb9\x91\xad\xf6\xcb\xe7\xd1\xb1\x9b\x8c\xd8\x3b\xe3\x60\x2e\xd1\x8f\x03\x96\x33\xfb\xd2\x38\x7b\xda\x69\xe2\xcf\x03\x87\xd8\x64\x4d\x97\xb3\x03\xfb\x00\x63\x9a\xee\xe7\xae\x46\x3f\x6f\xe1\xa2\xc4\xb8\x9a\xeb\xa3\xe9\x09\x4c\x11\xfc\x29\x11\x4b\x20\x28\x3f\x28\x7c\x6d\xd2\x8c\xb0\x98\xda\xe8\xda\xbc\x48\xe8\x5b\xb5\x9c\x0d\xc6\xe7\x8c\x95\x66\x05\xcb\x7c\xf0\x69\x42\x35\x3e\x7a\x22\xe9\x6f\x80\xa3\x7a\x66\xf7\x18\xd9\xe4\xdb\x8c\x52\x45\x2a\xa0\xa3\x57\x72\xe8\x1b\xa2\xb3\x03\x20\x5b\x41\x2d\xd2\xbf\xc1\x5c\xe9\xb4\x36\xf9\x9f\xbb\x32\x12\x6b\x63\xce\x9c\xb4\x31\x99\xf1\x57\xd8\x17\x51\xa7\xc4\x93\x7d\x13\xaf\x4c\x58\x29\x52\xb5\xd6\x06\xb5\x55\xb0\x46\xbf\x1d\xe0\x6c\xf3\x9b\x63\xa8\x02\x87\x37\x18\x03\x60\x9a\x38\x7e\xe8\x0f\x3a\x5d\x88\xb9\xd6\x21\x96\x50\xed\x17\xd3\xcc\x18\x3b\x2c\x70\xd5\xeb\x94\xe3\xbc\x52\xae\xa7\xaa\x7f\x53\xbe\x0e\x20\xb8\x97\x2f\x14\x3d\x8e\x20\x16\x2e\x80\x3e\xdb\x4a\xa8\x3d\x55\x53\xfd\xd5\x53\x39\x8b\x0f\xa1\x76\xb9\x59\xcb\xa1\x40\xd6\xe9\x80\xc9\x25\x1b\x0f\xa0\xb6\x5e\x90\x84\x17\xf8\x2f\x45\x1f\xf9\xf2\xde\x6b\x9c\xa5\xe3\xb5\xf4\x1b\xa4\x0d\x05\xa5\x4f\x3d\xab\x48\x86\xaa\xcc\xa0\x5c\x9c\x27\x98\x13\x9a\x4c\xb3\x3e\x96\xa9\x14\x94\x74\x99\x10\xa1\x7c\xe8\xb3\x92\xfc\x0f\xc7\x76\x29\x74\xd7\x9d\x33\xdb\x92\x4b\xfe\xf8\x65\x5a\x72\x37\x76\xff\x87\xf9\x50\xfd\xc5\x68\xb1\xe5\x26\x53\x45\x41\xf5\x72\x72\x3b\x84\x06\x63\xc1\x91\x88\xc4\x24\xf7\xc4\x89\x23\x5a\x42\x4b\x09\xfe\x25\xc3\x07\x27\xea\x1c\xb0\x49\x53\xd7\x06\xd6\x8b\xfe\x12\x10\x0e\xf6\xf6\x4c\x35\xc6\xb8\xde\x67\xed\xf0\xe3\xad\x01\x4a\x40\x0e\x82\x1e\xa3\x40\x24\x32\x19\x99\x86\x7b\x43\xc8\x2c\x45\x01\x84\xb7\x8f\x74\x25\xce\xbd\x73\x19\xdc\x6f\x65\xd3\x60\x66\x5d\xfb\xe7\xc3\x66\x74\xda\xc3\xa5\x4e\x96\xda\x91\x0c\x02\xd3\x64\x07\x80\xb2\x2d\x51\x2c\xa0\xe3\xca\x35\x87\xb9\x4e\xa9\xfc\xd7\xa3\x1b\x4a\xf6\x9f\xd6\x20\x7c\x68\xfe\xd2\x5f\x89\x92\x1c\x1c\xdc\xde\xfd\x1c\x09\x02\x04\x49\x2b\xff\x9b\xbb\x52\xe0\x88\x85\x82\x9d\x01\x2b\xc2\xdf\xb4\xfe\x8c\x35\xe5\x9c\xd1\x3b\xcb\x8e\xad\x34\x19\x3c\x40\xb0\x3e\xe4\xd8\x25\xee\x13\x22\xff\x4e\xf0\x71\x27\x95\x74\xcb\xae\xe7\xc0\x7f\x14\xbe\x60\x6b\x9c\xd0\xe2\x61\x11\x1e\xf2\x0d\x96\x81\xd7\x6c\xf7\x8c\x89\xa8\xc3\x97\xd6\xb8\xdc\x77\x8f\x49\x84\x16\x6a\xd5\xdf\x3a\x81\xaa\xf2\xe6\xde\x09\xf7\x00\x19\x5a\xe2\xc1\xd4\x60\x96\x47"}, +{{0xd4,0xa7,0xa9,0x52,0x4d,0x30,0xa6,0x33,0x7c,0x0a,0x0b,0xe9,0x5c,0xa9,0x05,0x91,0xde,0x98,0x88,0x03,0x8e,0x3e,0x59,0xe1,0xb2,0x5a,0x41,0x81,0xef,0x94,0x66,0x29,},{0x9f,0xc3,0xeb,0xd1,0x39,0xcc,0x5b,0x7c,0x0e,0x05,0xaf,0x47,0xbf,0xf6,0x61,0x9b,0x81,0x28,0x15,0xbb,0x01,0xce,0xec,0x39,0x2a,0x3f,0xf0,0xae,0xc3,0x81,0x1d,0x2c,},{0xd1,0x57,0x88,0xbc,0xd8,0x8d,0x1d,0x81,0xb9,0xe6,0x1d,0x4f,0xe2,0x6e,0xa4,0x9e,0x66,0x81,0x9a,0x59,0xd2,0xae,0x48,0x32,0x32,0x1b,0x81,0x4d,0x50,0x62,0xfa,0xdb,0x87,0x80,0x7d,0xb6,0x85,0x2e,0x1d,0x82,0x95,0xe3,0x1a,0x29,0x1b,0x1e,0x78,0x5d,0x01,0xd8,0x34,0x89,0x5f,0x88,0xf4,0x00,0xdf,0x88,0x32,0xc1,0x60,0x7b,0x5b,0x0c,},"\x17\x19\x80\xc0\x3f\xdf\x7a\x72\x7b\xd5\xba\xb3\xba\x09\x45\xe6\xad\x5f\xaf\x0a\x7f\x50\x6a\x56\xd1\xd0\xed\xd9\xa3\x06\xb3\x15\x8d\x84\x32\x66\xd3\x09\x1f\xc1\xe4\x22\x81\xdf\x97\x55\x9a\x22\x01\xf5\xbd\xdd\xfe\x68\x3d\x0e\x10\x28\xd1\xd9\x5b\x2f\x31\x3b\x48\x4c\x39\x2f\xfd\xb1\xcd\xf8\x85\x08\xaf\xde\x3d\x6f\xd2\xa1\x28\x88\xba\xce\xde\xb7\x9f\xf3\xdb\x40\xc9\xac\x0e\xc3\xfb\x90\x1b\x22\x86\x98\xad\xf8\xd8\x45\xff\x4f\xce\x10\xde\x55\xd4\x24\x36\xdc\xe9\x30\x97\x3a\x34\xbe\x05\xd1\x40\x1f\x33\x4d\x4c\xe8\xe3\xa7\x93\x79\x9e\xaf\xdb\x94\xd0\xf2\xab\x09\x50\xb0\x79\xe6\x65\x3e\xeb\x49\x9f\xc7\x44\x7c\xcb\xee\xed\x8d\xbd\x54\x56\x80\x8c\xd7\xa3\x8f\x9a\x15\xa2\xa9\xc7\x38\xd6\x13\x34\xca\xb8\xce\xeb\xbb\xf4\xa4\x81\x4d\x94\xc6\x18\x59\x17\x87\x84\x60\x4e\x0c\x21\x54\x59\x7e\x72\xcf\x58\x7c\xd1\xf5\xda\xfe\x59\x22\x05\x18\x90\xe7\x6d\x61\x6d\x8c\xd5\xb0\x5d\x64\x78\xd0\x62\x6e\xa8\x3c\xe8\x08\xc4\x61\x43\xe6\xfb\x06\xb4\x18\x2d\x22\x8d\xa8\xf6\xd4\x13\x9e\xca\x5b\x8f\x3b\x1b\x98\xaf\x68\xc5\x9b\x4b\x5a\x53\xc1\x36\xee\x90\x43\x2a\xca\x2b\xb9\x15\x52\x9d\x26\x36\x79\x49\x82\x62\x33\xb4\x3e\x55\x80\x4b\x55\xfc\x9f\x21\x5e\xb0\xb0\xb7\x92\x91\x46\x5b\xb3\x4e\xda\xea\xdf\xfa\xbf\xe6\xcf\x41\xbc\x07\xb5\xdd\x4d\x01\x42\xf0\x36\x1f\x05\x8e\xe1\xb3\xb9\xfc\xc1\x96\xeb\x9b\x35\xb1\x34\xbe\x3d\x1d\x23\x20\x04\x48\x9e\x8f\x69\x93\xf6\x25\xa6\x30\x15\xbc\xd3\xf1\xe8\x75\x88\x32\x48\x58\xcc\xfb\x77\x0d\xdd\xd8\x94\xbf\x29\x7b\xd7\x63\xef\x58\x28\xe2\x1f\x5c\x89\xaa\x98\xcf\xbc\x1c\x08\x2d\xd7\xfb\xaa\x43\x07\xbd\xa4\x0b\x4a\x75\x8c\xa8\xf3\x9f\x4e\x4a\xae\xd3\x09\x04\x12\x68\xdb\xcf\x0a\xf3\x2d\xe0\xd7\xfa\x90\xa5\x23\x96\x3b\x78\x0b\x6a\x93\x2c\xf8\x94\x99\x02\x5f\x0e\x0d\x04\x74\xc7\x43\x48\x94\x75\x10\xe6\xc5\xec\x7c\x9e\x05\x06\x6e\xeb\x4a\x73\x52\x0c\x3d\x92\x7c\x39\xac\x26\xad\x75\x96\x32\x5b\x2c\xc4\x7c\x5e\x82\xa7\x75\x45\x5b\x7a\xf0\x31\x20\xb1\xcf\xbf\xd6\xec\x3f\xc0\xc3\xbe\x60\x78\xb0\x0c\xfd\xf8\x34\x2a\xe8\xbf\x14\x71\x59\xf5\x0e\x9d\x56\x4e\x2f\x68\x30\x6d\xae\x3c\xae\xdd\x10\x19\xf3\x23\xc4\x78\xa1\xe1\xf6\x75\x98\xdd\x83\x4b\xd1\xd1\xa8\x73\x3f\xd7\xfd\xd8\xa8\x76\x52\x6c\x53\x15\x18\x93\x6e\xdb\x72\xd0\x16\x56\xb3\x44\xc7\xd6\x5a\xc1\xce\xe3\x7c\xe5\x99\x7b\xa4\x8d\x3f\x4d\x06\x4d\x88\x05\x7e\xfe\x9a\x48\x2d\x9e\x00\xab\x5c\xae\xb5\xac\xa2\xd6\x60\xe3\x37\xbd\x15\x48\x73\x65\x69\x79\x56\xa5\xe4\x7b\x02\xab\xdc\x30\xd8\xe3\x53\xfe\xd4\xe1\xac\x41\xd2\xbc\x21\x20\x02\x11\x43\x63\x59\x35\xc6\x20\x18\x6a\x52\x2b\xde\x54\xbe\x04\x46\xfb\xd2\xdc\x88\xb5\x63\x04\xb3\xa6\x42\x27\xd0\xac\xd5\xf8\x5a\x6b\x67\x87\xa3\xad\xcf\x2d\x7c\xfc\x86\xc6\x34\xb4\xd7\xab\x43\x15\xb9\x7d\xe9\xe6\x66\xcf\xf3\xff\x1b\x88\xf3\x29\x5e\x7b\xab\x9e\x9f\xd4\x6f\xaf\xdd\xb4\xf5\xfa\xc5\x1c\xc0\x17\x01\x29\xc6\x51\xb4\xef\x4d\x39\x50\xd6\x94\x2f\xf0\x20\xd1\x66\x8a\x52\x8b\xde\x1d\xa9\x36\xc0\xec\x1a\xe0\x9e\x84\xf8\x20\x58\x61\xff\xf4\x91\x50\x2a\x87\x2c\x81\x54\xa9\x6e\x7e\xa2\x5e\xda\x95\x5a\x7f\xd2\xe4\xb4\xc7\xa8\xd2\x73\xf6\x0b\xc7\x4f\xab\x7b\x49\x68\xca\x6f\x75\xda\xea\x50\x40\xf8\x39\xfd\x56\xc2\xa9\x80"}, +{{0xd0,0x8f,0x4b,0xab,0xba,0x3b,0x53,0x65,0xfa,0xf7,0x38,0x79,0x5c,0x9d,0xa4,0x5d,0xb1,0x86,0x2c,0xb2,0x8b,0x93,0xeb,0x66,0x35,0xd1,0x32,0x0d,0xa0,0xf4,0xd9,0x37,},{0xef,0x31,0xb4,0x54,0xf7,0x34,0xe5,0x2b,0x34,0x38,0xee,0x2f,0x1c,0xbc,0x35,0x63,0x1b,0x19,0x69,0xde,0x54,0xac,0x98,0xfe,0x46,0x33,0xf2,0xf5,0x00,0xac,0x87,0x12,},{0xac,0xeb,0xe4,0xc8,0x6f,0xa9,0xfe,0x2c,0x1a,0x5c,0x57,0x6a,0xc0,0x50,0x1e,0x8a,0xb0,0xf6,0x40,0xfa,0x40,0x38,0x05,0x36,0xfc,0xf9,0x50,0x59,0xd5,0x3d,0x4a,0x35,0x55,0xd2,0x20,0xac,0x36,0x35,0x87,0x17,0x5e,0x4b,0xde,0x16,0x3c,0x0d,0x00,0x65,0x0a,0x12,0x96,0x3d,0x46,0x76,0x6c,0x99,0xbb,0x62,0xbf,0x75,0x73,0xe2,0x87,0x0c,},"\xa3\x94\xd8\x85\x4c\xeb\x5c\x43\xaf\xee\x1a\x48\x92\x6b\xbd\x66\x85\xaa\x8a\xec\xfd\xcf\x85\x41\x33\x33\x39\x74\xd6\x24\xbf\x2f\x1f\x9c\x30\xf0\x05\xbb\xf3\x4c\xee\x3a\xfe\x2b\x29\x06\x00\xee\xae\x6f\x1d\xd1\x2a\x0c\x34\x6f\xbb\x2a\xb9\xc9\x16\xc5\xd5\xd8\x0d\xcd\x87\x88\x78\x75\xa0\xac\x84\x76\x78\x03\x9f\xdc\xd3\xa9\x79\x35\x41\xf5\xd6\x75\x14\x3a\x6a\xba\xdc\x3b\x18\xf0\xfe\xf5\x10\x8c\x19\xc2\xdb\xfb\x59\x71\x0e\xef\x98\x66\xa4\xf3\xf2\x97\xa0\x9e\xe4\x8c\x68\x03\x00\x7d\xd6\xba\x8f\xd4\xbe\x84\x1c\xfb\x10\xff\x05\x14\xc3\x0f\xc4\xdd\x49\xa3\xcd\x43\xbb\xd1\x6e\x46\x04\x43\xa1\x1a\xfe\x64\x9e\x90\x1d\x63\xd8\x9a\xf5\x98\xaa\x68\x6b\x2f\x60\x7e\xc1\x1f\x35\xe1\x7a\x79\x8a\x42\x13\xb7\x5a\x38\x78\x8d\xa4\xf2\x7c\xf2\xb0\x2c\xad\xdf\xe6\x1c\x37\x29\xa8\x7e\xc6\xe6\xb0\x98\xf6\x8e\x7a\xed\x28\xa8\x00\xc4\x84\xdf\xa0\x13\x04\x01\x20\x8f\x98\x6d\x79\x2f\x54\x63\x5a\xdd\x28\x48\xe1\x51\x26\x2a\x36\x5e\xb2\x1e\x27\x27\x19\x1e\x1f\x70\x0f\x3b\xf5\xc7\x3b\x0f\xb4\xc5\x46\xd0\x04\x8a\x15\x5c\x18\x71\x79\x20\xfc\x04\x25\xc8\xc8\xfa\x8f\x16\x7c\x43\xa2\x77\xbb\x36\x6e\x0a\xd7\x02\xc8\x9b\xc5\xaa\x06\xfd\x47\x09\x43\xbe\x05\xcb\x9e\x32\x59\x78\x72\x29\x71\x4c\x30\xa4\xe8\x7b\x00\xa6\x33\xaa\xf7\xbe\x6b\x58\x75\x01\x0d\x12\xe1\x07\xc9\xa5\x26\x1c\xa5\x62\xd6\x70\x25\xbe\xa0\xfe\x22\x34\x63\xed\xb9\x2e\xa0\x1c\xca\x92\xc4\x4f\xf2\x4d\xa9\xd8\xa8\x0a\x64\x21\xf3\xd4\x13\x5d\x64\x7d\x1b\xb0\xfd\x98\x8c\x46\xc8\xa1\x70\xce\xb4\xf3\x3f\xff\x9c\x0f\xfb\x6a\xba\xd1\x09\x2c\x84\xdf\xad\x82\x90\x89\x8b\x24\x95\x16\xa2\x92\xe8\xda\x96\xfd\x51\xa8\x10\x05\xee\xcf\xde\xbb\x05\x93\x30\x99\x27\x7d\x07\x3a\x48\x0c\x3f\x9e\xb8\xaa\x11\x96\x8c\x4d\x8d\xc0\x78\x7a\x9a\xec\x3e\x05\x27\xb7\xfe\x4c\x06\x35\x41\x13\x35\xa1\x81\x16\x89\xe8\x8f\x6d\x5c\xed\x0d\x40\xd6\xb4\x8b\x7f\x2d\x99\x29\x52\x93\x48\x94\x15\x30\x76\xa8\xd3\x73\x72\xfa\x00\xd9\xce\xfc\x5c\xf8\xc2\x6a\xdb\x5a\xcf\x32\x5a\x01\xcd\x00\x5a\xb8\xd4\x74\xa5\x2d\x67\x11\x40\x78\xc6\x51\x6a\xef\x80\x4b\xba\x19\xb8\x87\xa2\x8e\xd5\xe4\x6e\xe9\x99\x5e\x5a\xd3\xa8\x2f\xb9\xcd\x93\x28\x34\x33\x68\x09\x21\x11\x4b\x4d\x9a\xf8\xfc\xb6\xb2\xb5\x35\x83\x9c\x36\xde\x8d\xf1\x2b\x17\xea\x6d\xdc\xfc\xb3\x33\x4f\xf4\x0e\x6c\xf0\x4c\xcd\x5c\xa6\x40\x3b\xa0\xb6\x2b\x4c\xb7\x1b\xbd\xe9\x1d\x8b\xab\xda\x69\x15\x2c\x9c\x93\xae\x76\x9b\x55\x29\xc8\xd5\x2f\xd9\xa6\x90\x9a\x15\xe1\xa0\x60\x1a\x71\x46\x49\xc9\x6e\xc9\x96\xc1\x70\x6d\x10\x21\xb9\x74\x87\x98\x0d\x7b\x2c\x2a\x39\xbb\xb0\xe4\x70\xd8\xe4\x6a\xc4\xaa\x60\x9a\x09\x22\xc9\xbd\xc0\x16\x12\xea\xde\xac\xcd\x5f\xa5\x23\xb2\xa8\xd0\xe6\x2f\xfe\x56\x28\x16\x47\xd6\x1f\xff\xbb\xc8\x40\x53\x57\x45\xd1\x44\x25\x9c\xc8\x13\x00\xfe\x99\xdf\xbf\xfe\xa6\xb0\xb9\xbc\xd2\x84\x73\x98\x2d\x32\xe9\x3e\xd4\x66\x34\xa9\x98\x79\x06\xd6\xf4\x89\x39\xd8\xdf\xbf\xb3\x7d\x33\xb8\x88\xdb\x60\x8c\xb2\xff\xe3\x9a\x8c\xf6\x7b\x72\x64\x46\x11\xc7\xd3\x2a\x4a\x8d\xf6\x12\x46\x8c\xd5\xe5\xd7\x5f\xbb\xa7\x9e\x63\x8a\xa1\xda\xa2\x8c\x4e\x0e\xeb\x9a\x63\x7f\xf8\xa0\x8b\x65\xf7\xa7\x61\x24\x14\xdf\x76\xbc\x7b\x0b\x56\xb5\x53\x7d\x66\x6f\xac\xfd\xda\xf6\x5a\xf1"}, +{{0x8f,0x47,0x4f,0x88,0xcf,0x86,0x3c,0x48,0x54,0x56,0xa5,0xa2,0x15,0x52,0x81,0xff,0x27,0xb2,0x84,0x59,0xf6,0x3b,0xc4,0xf1,0xdb,0x00,0xe0,0x03,0x10,0x64,0xf6,0x49,},{0x43,0x14,0x4a,0x32,0x9d,0x75,0x1d,0x04,0xe0,0x71,0x69,0xb7,0x79,0xee,0x92,0x0d,0xd0,0x29,0xcb,0x44,0x5b,0xf3,0x76,0xba,0x3a,0x66,0x85,0x72,0x18,0x23,0x44,0xa3,},{0xf6,0x1f,0x78,0x07,0xc3,0x3e,0x19,0x6d,0x0f,0xe1,0x82,0xef,0xa4,0xd4,0x51,0x6a,0x98,0x15,0xdd,0xd4,0x49,0x53,0x8b,0xba,0xa6,0xb8,0x6b,0x69,0x01,0xa0,0x5f,0x5d,0xdd,0xa0,0x60,0x1e,0xc9,0x0f,0x39,0xf1,0x55,0x47,0x79,0xdb,0x7a,0x09,0xa6,0x05,0x72,0xef,0xfd,0x4d,0x12,0x8d,0x0d,0x3c,0x2d,0xd4,0xe8,0x83,0x57,0x4b,0xc6,0x0b,},"\x84\x08\x91\xd9\x48\xec\x19\xc8\xc7\xf7\xc9\xd3\xc4\x77\x53\x62\xa5\x44\xa0\xec\x97\x45\x7a\xb5\xd1\x4e\x12\x5d\xc5\x4b\x59\xc8\xdc\x9a\x63\x5e\x7b\xad\xb6\xbe\x73\xc3\xa5\x8d\xc0\xe9\x92\x9f\x2b\x42\x0d\x83\x56\xd6\x17\xc3\xd4\x1b\xfe\x69\xb4\xe1\x58\xd4\xbf\x08\xfb\x17\xe6\x88\xd3\xcf\x3c\x94\x8b\x69\xb3\x5f\x0b\x6d\xb6\x62\x72\xa8\xeb\x2b\xd4\x10\xd6\x50\x9f\x6c\x82\x8b\x6a\x20\xd6\x58\x6e\xaf\x85\x76\x01\xed\x9d\x60\x54\x79\x9c\x25\x32\x0e\xba\x80\x77\xfe\x1a\xe2\x26\x71\xb3\x3a\x15\x88\xff\x2b\x23\x5d\x3c\x71\xa2\x7c\xe5\xc6\xc6\x6e\x18\x88\x91\x98\xd1\x16\x93\x36\x76\xbc\x4f\xb0\x71\x0d\xb7\xff\x1a\xc2\xf2\x0c\xe3\x69\xbe\xf5\x6b\x43\xcd\x1d\x40\x6c\xef\xda\xcf\x00\xf1\xf3\x48\xb8\xca\x7a\xa6\x14\xdb\x11\xa3\xa6\x40\xfd\xb5\x93\x89\xd1\xa6\xa3\x94\x75\x5c\x13\x3f\x1b\x01\x9c\x83\x08\xca\x5a\x95\x1e\x73\xb8\x10\xa1\x80\xf6\xff\x25\xb2\x9d\xbb\xcc\xef\x4c\x13\xa9\x75\x03\x39\x39\x07\xa2\xdb\xa0\x96\xa8\xce\x5c\x86\xc0\xee\x6f\x97\xc1\x44\x1b\x8d\x63\x31\xcb\xa5\x3b\x19\x60\x6b\x42\x1a\xf5\x2f\x65\xf9\xc6\x63\xe6\x3d\x39\x82\x71\x8f\x94\x8c\x6b\xae\x96\x1b\x8e\x4b\xf8\xcd\x9e\x31\xcd\x09\x92\x8e\x4e\x80\x61\x65\x97\xcc\xfa\xdc\xb8\xa6\x14\x15\x49\x33\xbc\x37\x58\x9c\x85\xc7\x76\xe3\x4e\x5a\x90\x66\x0f\x59\xa6\x5b\x5e\x93\xad\x43\x88\x42\xf9\x82\xd0\x2b\x04\x1e\x6d\xbd\xdf\x17\x10\x99\xf8\xdb\x70\x99\x57\x31\xa0\xdb\x8c\x46\x25\xc9\xbc\xa7\x10\x80\x59\x61\xfb\x17\x6d\xae\x81\x97\x68\xfc\xad\x7f\xf9\xbf\xce\x36\x40\x3c\xa7\xf7\x83\xe7\x61\x37\x26\xd7\xdc\x59\xf2\x4e\x24\x7c\xf1\x50\x68\xff\x3b\x19\xc7\x25\xfa\xd6\x5e\xa8\xe8\xa7\xf7\x22\xd5\x28\xc9\x5f\xce\xf1\xc0\xcc\x79\xd1\x8e\xf0\x7c\xee\x8b\x01\x1e\xea\xbd\x99\x21\x63\x4d\x76\xa6\x1a\x8a\x3c\x89\x31\xb8\x27\xe8\x18\x98\x81\xf8\x1f\x7a\x17\x5f\x21\xfb\x03\x78\xb8\x18\x8e\x58\xbd\xb2\x01\x7b\xef\x39\x0f\x18\x00\xd9\xd7\x4f\x26\x3a\x81\xdf\x8e\x67\x52\x2d\x09\x2e\x77\x5d\x01\xe0\x04\xe7\xf8\xd8\x28\x1a\xe2\xc2\xfd\xf8\xc3\xa4\x45\xf9\xef\xf7\xfd\xf1\x3f\x26\x1a\x77\x3d\xdf\x2d\xd9\xcc\x6b\xa5\x58\x5d\x99\x0c\x99\x5e\x6e\xb8\x9d\xff\xd9\xff\x0a\x9d\xbb\x76\xce\x5e\x10\xdd\x02\x72\xd5\x00\x14\x97\x88\x13\x66\xf5\xd6\x36\xa9\xcc\xea\xa2\x83\x22\x8d\x3a\xc6\x14\xdb\x21\x7a\xb8\x91\xd6\x68\x9d\xbe\xb9\x50\xe1\x20\x0c\x3d\xe5\x3b\xc5\xda\x07\xf1\xd3\x63\xda\xe9\xbe\x6e\xc3\x6e\xda\x6e\x68\x7d\x26\x29\x0f\x7a\xbc\xa2\x68\xa7\xfa\x03\xd9\x31\x88\x64\xed\xa9\xa1\x1e\x3b\x26\x14\x06\x05\x92\x0a\xc1\x3a\xde\xc1\xb5\x54\x8c\x9a\x7a\x32\x15\xa5\x87\x6b\x7e\x94\x1a\xfa\x1c\xb5\xd7\xf7\xf0\xc1\x16\x30\xcd\x42\x9f\x3b\x2b\x37\xdc\x76\xc6\xcb\xea\x4f\x3b\x72\x6a\xa8\xa5\xf8\xb9\xf7\x05\xb0\x5d\x7e\x94\x51\x95\x6f\x8a\xf1\x3c\xe0\xa8\x59\x55\xc7\x13\x5d\x64\xad\xe5\x49\x6e\xa5\x42\xe7\x0f\x8d\xa5\xb5\x73\xaa\xf1\x37\x08\x5d\xc9\x6c\x69\x27\x09\x96\x95\x67\x26\x68\xb3\xc7\xc6\xf9\x3c\x97\x7a\x4e\x8e\x9e\x77\x02\x95\xf2\x0d\x52\xdf\xf1\x87\xf8\xdb\xb2\x5e\xe7\xe7\x74\x02\x4e\xb9\xbe\x08\x12\x1e\xd7\x4b\x6d\x54\x62\xf4\xbb\x7d\xc2\x00\x38\x74\xca\xa3\x1b\xb7\x59\x5c\xd9\x3a\x99\xeb\xe1\xef\xf9\x28\xbb\x5f\xcb\x9e\x9c\x89\xdd\x31\xd4\x87\xfc\x0e\x20\xbb\xe1\x50"}, +{{0xe4,0x2b,0x30,0xd4,0x9c,0x43,0xc4,0xfa,0xd8,0x3d,0xd5,0x1f,0xdc,0x2a,0x4a,0xc5,0x90,0x13,0x27,0xad,0xd8,0x00,0xb6,0x69,0x72,0xc8,0xc7,0x0b,0xde,0x18,0x0a,0xdc,},{0xf7,0x34,0xaa,0xfa,0xa4,0xdb,0xaf,0x31,0x5c,0x25,0x8c,0xca,0x8b,0xbc,0x1d,0x4f,0x34,0xe8,0x36,0x01,0x10,0x98,0x74,0x22,0x2a,0xa0,0x55,0x89,0xf3,0xa6,0x63,0x5f,},{0xff,0x8e,0x07,0x6e,0x34,0x3c,0x8b,0x73,0xaa,0x45,0x3b,0xfe,0xe9,0xb2,0xba,0xb6,0xd5,0xc2,0xf7,0x4c,0x35,0xe1,0xba,0xd1,0xe5,0x2a,0xe7,0x77,0xd6,0x9f,0x79,0x76,0x40,0x83,0xf9,0x94,0x36,0x8a,0x1a,0xc8,0x51,0xa6,0x41,0xcd,0x24,0x70,0x08,0xa3,0x4f,0x3b,0x60,0x89,0x62,0xf4,0xdd,0x51,0x09,0xac,0x71,0xcc,0xe9,0x78,0xec,0x02,},"\x0d\x49\x70\x51\x86\x1e\x22\xd8\xa9\xc6\x0e\x5f\x7d\xe6\xc8\x95\xcb\xa3\x35\xb2\xe8\x2e\x60\x21\x18\xad\x83\x42\xb4\xd4\xed\xaa\x80\xf9\x5e\xfb\xb5\x9c\xfd\xa1\xfc\xc0\x29\x17\x25\x70\x0e\x8a\x81\xbb\x12\xa0\xb8\x62\x3b\x1f\xe2\x89\x1b\x8d\x98\xf7\xa8\x4c\x59\xfd\x92\xf8\xa7\xad\xfc\x06\x50\x42\xf7\xf4\xfd\x7e\x1a\x79\xf5\x5a\x1d\x4d\x5e\x54\xe0\x4e\x67\x2f\x1c\x9e\x4c\x4c\xd8\xd0\x00\x3f\x3c\xd5\x4b\x76\xe2\x16\x3d\xd7\x37\xac\xb2\xde\x5c\x26\x3a\xc1\x02\xa4\x8f\x69\x6b\x60\xca\xf9\xbe\x39\xc6\x65\xcc\xe1\xe0\xf3\xd4\x98\x55\x3f\x57\x90\x61\x88\x9a\x5e\xc5\x60\x3e\x4d\x14\x1c\xfd\xed\xe8\xe7\x31\x75\x72\xcf\xe7\x6a\x0f\x48\xe4\xae\x06\x06\x2c\x91\x57\xb5\xea\xac\x34\x68\x93\x81\x92\xdb\x4b\x16\x10\x5c\x73\x64\xa9\x44\x32\xb2\x15\xa7\x17\x97\xfe\xe1\x4c\x3c\x9c\xe2\xf7\x46\xed\x79\x03\x02\xfc\x41\xdc\x49\x2d\x37\xd9\xef\x02\x4a\xb5\x1d\xa3\xbd\xaf\x0f\x81\xd9\xa9\x30\xaa\x0e\x02\x5c\x04\xfd\x71\x02\x6b\x6a\xfe\xb7\xed\x01\xa9\x1a\x1e\xfd\x6c\x39\xf5\xe4\x47\xc6\x6d\xd3\x8a\x76\x56\xc6\x13\xd0\x21\x26\xf3\x58\x5d\xfa\xa0\x2d\xf9\x30\x25\x3f\x83\xbd\x42\x19\x64\x63\xeb\xc5\x0f\x8c\xfc\x94\x9e\xd3\x50\x39\x2e\x61\xce\xec\x13\x09\xda\x15\xa4\x32\xf8\x0d\xfe\x94\x8e\x26\x1c\xe6\xd8\x42\x1c\x54\x59\xcd\x21\xf3\xff\xa2\xed\xb5\x00\x98\x2b\x2a\xbf\xa5\x2e\x82\x43\x7c\xa2\x30\xf6\x09\x11\x63\x20\xd9\x89\x3e\xb8\x2a\x14\xdf\x72\xb7\x73\x66\x67\x51\x6f\xc0\x12\xb2\x8a\x03\xc9\xdd\x88\xea\x43\x08\xd8\xce\xea\x44\xcc\x60\x44\x54\xcd\xfa\x2c\x79\x76\x15\xbc\x0a\x6b\x3e\x00\x89\xaf\x0a\x81\xbe\x54\xd1\xb1\x10\xa1\x3a\xb9\x11\xb4\x52\xc3\x42\x80\x0c\xee\x2a\xd2\x39\xa2\xb1\x88\xa7\xfa\x87\x5e\x94\x1d\xaa\xeb\xcf\xc8\x8b\x70\xae\x4b\x1c\x57\x5c\xdb\x6e\x6d\x89\x44\x81\x36\xf6\x0e\xe8\x1c\x70\x3c\x47\x82\x2d\x2c\x0e\x50\xc7\xf1\xe8\xb7\xfc\x7e\xbd\x80\x78\x9f\xcd\x7e\x06\xc7\xe5\x0b\x5f\xc8\xb7\x76\xe8\xb9\xa4\xcd\x59\x05\xa2\x90\x69\xbc\x3a\x55\x8d\x7c\xab\xce\x2a\xf4\xf3\x10\x76\x7d\x5b\x11\x7e\x30\x76\xb3\xa0\xd5\x27\x17\x55\x43\xb2\xcc\xea\x28\xd5\xf7\x16\xfa\xc3\x2e\xfe\xd3\xd2\xe0\x27\x6b\xe4\x4a\x89\x56\xfc\x82\x40\xf2\xdb\x33\x97\x61\x4f\x2f\x2d\xa0\x21\x66\x69\x4e\xc6\xa7\xfe\xec\x6e\xce\x39\xd7\x2b\x64\xbb\xc6\xb4\x76\xa4\xf8\x4f\x8d\x87\x93\x80\xa3\x84\x88\xe4\xd6\xe5\x8c\xac\x03\x90\xae\x25\xa5\xfc\xb7\x3d\x47\x41\x4b\x4c\x26\xbb\xb9\xb4\xcc\x66\xe4\x25\x94\xbd\x56\xd8\x41\xa3\x60\x92\x34\x91\xd1\x17\xbe\x2c\x6e\xb2\x32\x0f\x3c\x61\x75\xe4\x4e\x27\xb6\x65\x3c\x5d\xac\x6f\xae\x73\x60\x0b\x67\x96\x0d\xca\x50\xaa\x85\x5a\x89\xe0\xff\x51\x1e\xa0\x4f\x14\x3e\x89\xf1\xda\x02\x84\x76\xbe\x4b\xf6\xd9\x4c\x80\xff\x72\x63\x39\xe8\xbc\xfb\x7d\xd9\xf8\xcf\x20\x22\x59\xc0\xac\xb6\x27\x6c\x28\x1e\x38\x47\xc2\xcc\x8d\x2f\xba\x84\x43\x8d\x2d\x3c\x60\x31\xf2\xa7\xb9\x5c\x1d\x8f\x9f\x3c\xc8\x6a\x5e\xff\x65\xcc\x01\x1d\xe9\x5a\xd8\x96\x85\x8e\x1f\x7f\x6d\x6b\x94\xbf\x49\xdf\xff\x5d\xe2\xd7\xfd\x71\xef\x10\x81\x34\x28\x5f\x61\xae\x47\x54\x83\x44\x2d\xc9\x0b\xf0\x13\xfa\xed\xf3\x77\x1c\x47\xc5\xb9\x6d\xc3\xcf\x8e\x48\x51\x00\x60\xad\x8d\x45\xfd\x54\x61\x62\x27\x80\xd8\x69\xd4\x61\x7b\x57\xfe\x3c\xb5\xcc\x02\x03\x15\x3a\xae"}, +{{0x5c,0xb5,0x14,0x21,0x74,0x82,0xbf,0x42,0xf6,0x11,0xfc,0xec,0x36,0xa5,0x28,0x68,0x07,0xc2,0xbd,0xbb,0x56,0x96,0x76,0x91,0x35,0x3f,0x54,0x31,0x0e,0x1a,0xd5,0x53,},{0x28,0x06,0x99,0x00,0x3d,0x5d,0x3e,0x1c,0x05,0xad,0x10,0xfb,0x10,0x95,0x9b,0xbc,0x59,0x5c,0xfe,0x21,0x30,0x69,0x96,0x5c,0xd8,0xcf,0x39,0xdd,0x42,0x6a,0x05,0x68,},{0xd5,0x3e,0xe2,0xe0,0xf0,0xfd,0x65,0x7b,0x20,0x52,0x47,0x8f,0xd1,0x5d,0xf1,0xd3,0x8f,0xe0,0xe9,0x3a,0x54,0x83,0xeb,0x4a,0x6e,0x7d,0xe9,0x3d,0x02,0xa4,0xcd,0x54,0x4d,0x8f,0xdd,0xdc,0xea,0x82,0x2b,0x71,0x57,0x6e,0xd0,0x28,0x53,0xd9,0xa6,0xb1,0x4e,0x1a,0x54,0x8a,0xef,0xe9,0x0d,0x92,0xf8,0x83,0x79,0x2b,0x7f,0x1d,0x86,0x09,},"\x2f\x57\x25\x8c\xca\x79\x32\xe5\x8b\xed\x54\x6c\xb0\x04\x11\x15\xbb\xad\x23\xd1\x83\x46\xef\x7a\xb5\xe3\x11\x00\x82\xb3\xa9\x71\x2f\x6c\xbe\x12\x70\xe6\xdc\x0c\xea\x33\x64\xa0\x6a\x5f\x2f\x28\x3e\xc3\x9b\x63\x05\x8d\x34\xd5\x99\x79\x07\x2f\xcb\xbd\x7a\x5d\x0f\x44\x2b\xbd\xf0\x82\xd5\xbf\xe2\x99\x8a\xeb\x51\xbd\x26\x12\x78\x03\xe5\xc7\x96\xc3\x88\x43\x20\x0a\xe2\xf6\xe6\x05\xaf\x31\x2f\x54\xfd\xff\x17\xed\x1d\xfa\xa8\x9d\x28\xfa\x67\xdc\xe4\x62\xde\x4f\xe2\x52\x68\x21\x2b\x28\x2e\x22\x2a\x44\x3e\x2f\x31\xe2\x69\x05\x41\x71\xaa\x73\xc7\x19\xa8\x96\xcd\xb7\xa5\x39\xdf\xd1\xd4\x29\x91\x97\x81\x97\xd7\xc4\xf2\xd3\x0a\x64\x1b\xe3\x4b\xf1\x38\x0a\x4f\x4d\xc6\xd9\xb1\x01\x63\x66\x36\xa4\x96\xbe\xb3\x57\xe3\x47\xc1\x66\x65\x16\xdf\x8e\xb5\x60\xa0\xe0\xd1\xe1\x52\x9c\xe3\x6a\x60\xe0\x0e\xd2\x78\xda\x38\x02\xbe\x19\x23\x42\x98\x9b\xb6\x11\xb4\xe3\xcb\xd9\xc3\x7e\x8c\xce\x07\xef\xc1\x2d\x29\xbe\xfd\x7e\x2f\x3a\xdb\x13\xd2\x8f\x70\x8d\x97\xb6\x3e\x10\x74\x82\xc8\x62\x95\x6d\x7c\xe8\xdf\xc2\xaf\x5c\xac\x8d\x51\x65\x92\x67\xb0\xbb\xed\xdd\x5e\xfa\x41\x4d\xde\xab\xd1\x7b\x23\xca\x6e\x84\x3f\xf4\x9e\xff\xc8\x2a\x5d\x07\xe3\x6a\x83\xb6\x7c\x2a\xd7\xe4\x8e\xb9\x99\x0b\x42\x1c\x55\x58\x00\x9b\xd6\x93\x4e\x86\xd5\x4a\x8a\x6a\xc4\x07\x87\x96\xe3\x05\xc7\xcc\x81\x0d\x3f\x66\xea\x6b\x95\x04\xfe\x0a\xe6\x75\x7c\x50\x4c\x55\x52\x53\x0a\x6f\x8b\xbb\x52\x40\x9b\xe0\x79\xd8\xe4\xa2\x8a\x6f\xd7\xdc\x89\x35\xf8\xeb\x94\x98\xad\xc0\xf2\x3d\x08\x07\xec\x86\x29\x5f\x48\x98\xf5\xd0\x5e\x15\x0b\xdc\x43\xaa\x8b\x7b\xdc\x89\x3a\x0a\x68\x4c\x30\x63\x89\x8b\x6c\x95\xe7\xd5\x6a\x4c\x10\x26\x90\x43\x8e\x9d\xf9\x97\x58\xa9\x0f\x47\xc6\x08\xda\xcc\x4c\xa2\x40\x26\x6f\xab\xa3\x5f\xa1\xeb\x2e\xaa\xbe\x28\x8d\x2c\x2a\xd5\x0b\x6c\xbf\x10\x7c\x00\x25\x75\xe9\x1f\xf4\x72\xa4\x41\x79\x40\x66\x7b\xe8\x18\x01\x73\x85\x4c\x93\xdf\x84\x46\x4b\xcd\x31\x2b\x7a\x7a\xe4\xdc\x2b\x90\x59\xfb\xe6\xf8\x3f\x53\x80\x64\x25\xbd\xff\x03\x1c\x6a\xed\x6e\xfa\xfd\x9d\xe8\xdc\xd0\xdf\xab\xea\x8e\x6f\xa6\x81\xe9\x91\x93\xfb\x3c\x64\x7e\x44\x21\x12\xc9\xa2\x3f\x59\x6e\x65\x41\x1d\x8d\x6b\xfc\x39\x23\x00\x4e\xce\x91\xea\x6d\xeb\x88\x11\x11\xb1\xdc\x29\x94\x3f\x57\x89\x81\xee\x8c\x3b\xce\x85\x25\xf7\x85\x65\xf3\x4b\x85\xff\x20\x01\x5f\xea\xe8\x46\xf9\x5b\x18\x70\x0b\xc5\xcd\xf1\x4b\x2d\xb6\xca\xc6\x98\x14\xd6\x3d\x74\xbf\x20\x32\x93\x03\xe5\xca\x9f\x04\x73\x1f\x68\x81\xce\xc6\xd3\xab\xf8\x7f\x5e\xac\x08\x73\x4f\xaa\x34\xcf\xf4\xd3\xcd\x9a\x4a\x11\xd7\xb1\x2f\x73\x25\x3b\x4d\xd0\xa4\x31\x78\xf0\xd3\xc1\x9c\x0c\x40\xd9\xed\x91\x8d\xd1\x76\x46\xf6\x16\xaf\x79\xfd\xf6\x19\x42\x62\xf0\xfa\x4f\x71\xb3\x18\x7d\xed\xca\x48\xd9\xcb\xcc\x19\x93\x1a\x15\x19\x67\x74\x56\x25\x6e\xd3\x83\x54\x56\x7c\x3a\x67\x57\x1c\xdf\x82\x17\x0a\x2c\x85\xbd\x2c\x5e\x68\xe0\x5a\x0f\x3b\x93\x90\x3f\x19\x1b\x89\x4f\x84\x94\x6f\x89\x00\x05\x68\x05\x4c\x1c\xea\x9f\xd0\xb8\xbb\x55\x01\x95\x06\xc5\x43\x41\xc2\x49\x31\x98\x45\x48\xba\x45\x8a\x4d\x81\x30\x89\x89\x6e\x86\xa2\xdc\x33\xd9\x46\x04\x00\x3f\x35\x4a\x7c\xc9\x41\xc7\x54\xaa\xea\x24\x25\x3c\xbe\x4c\xf2\x14\x7f\xfe\xc5\xe7\xb9\x50\xcb\xf2\x8e\x28\x44\x81"}, +{{0x87,0xd3,0xba,0x95,0xc4,0x0d,0xf8,0x00,0x69,0xb1,0x79,0x7d,0xdf,0x68,0xe8,0x66,0xe6,0x6d,0x46,0xc5,0x1f,0xde,0x60,0xe7,0x68,0xa9,0xdb,0xc5,0xc9,0x2f,0x57,0xa9,},{0x2b,0x81,0x2b,0x2c,0x9b,0x60,0xff,0x31,0x97,0x5c,0x42,0x9a,0x86,0x73,0x6d,0xcc,0x17,0xa5,0x8d,0x3d,0xc1,0xda,0xa3,0x46,0x23,0xa4,0xbb,0xcb,0xe2,0xcc,0x05,0x81,},{0xfa,0x0d,0x12,0xcd,0x53,0x23,0x6c,0x41,0x08,0x6b,0xea,0x8c,0x0c,0xc6,0x0b,0x77,0x64,0xa3,0xed,0x72,0xbd,0xeb,0x9d,0x1a,0xe5,0xee,0xac,0xb4,0x88,0x11,0xfe,0x52,0x97,0x62,0xa2,0xc6,0xf2,0xbb,0x06,0xd9,0xb3,0x18,0x21,0x8d,0x96,0x8f,0x64,0x44,0x35,0x49,0x7a,0x1b,0xd0,0xd0,0xd8,0xc1,0x61,0x2a,0xb8,0x99,0x6d,0x98,0xd7,0x07,},"\xe1\x12\x56\xf8\x2a\xd7\x6f\x3f\x4a\x49\xd7\xba\xd3\xce\xd8\x71\x8d\x36\xd2\xf2\xbb\x3d\x31\xbb\x61\xed\xd1\xec\xbc\xee\x66\x21\xfd\x2e\xee\xd3\xe3\xde\xb5\x97\xb1\x49\xff\x71\xb8\x51\xf6\x1c\x8c\x68\x19\xe1\x31\xf9\xa2\xaf\x76\x73\xc3\xf2\x07\x02\xac\xfd\xc8\xb8\xf9\x06\x4b\x41\x5c\x9a\x3e\x35\x56\x8e\x37\x1d\x74\x0a\x38\x12\x7c\x1f\x27\xb3\x91\xb4\x5d\x07\x04\x5a\xea\xf0\x0a\x54\xe5\xb7\xfa\x54\x8a\xfb\x5f\x96\xfe\xb5\xf5\xb4\x4f\x60\xcd\x17\x07\xe8\xfa\x95\x67\xf7\x80\x6e\x15\xf6\xa0\x1a\xa0\x20\x77\x73\x3f\xe7\x38\xb0\x8f\x21\xef\xbc\xf9\x8c\x19\xd5\xb9\x70\xe6\x16\x3e\x5f\xe8\xf4\x80\x0e\xf9\xed\x22\xa0\xf9\xb5\x12\x6f\xf1\xeb\x1c\x7d\x65\x01\x9c\x8b\x44\x03\x91\x92\x70\x29\xb8\x13\xda\xb7\xc7\xe8\x63\xd4\x82\x29\xf8\xdf\x85\x39\x43\x45\xfc\xc8\x8a\x30\x0f\x60\xa8\xd5\x16\xd8\x77\xa5\xa3\xa7\xe3\xc4\x9a\x9e\xb0\x6c\xd9\xf2\x66\x5c\xe2\xa8\x90\x22\x96\x2b\x1d\x49\x59\x2b\x09\xc7\x54\x3d\xa8\x35\xce\x63\xbc\x9a\xbb\x82\x21\x45\x76\x2b\x71\xcb\xe1\x50\x29\x2c\xe5\xc8\x70\x4e\x5a\xd3\x4f\xb4\x59\x2f\x97\x20\x44\xe4\x3e\x69\xf0\xe1\x67\x2d\x6c\x83\xcf\x25\xaa\xc6\x8e\xfe\x3d\x27\xaf\x2a\xd3\x42\x74\xb9\xd2\xb7\x77\x42\xd9\xc6\xdf\xbd\x57\xf9\x2f\xf6\x4d\x3e\x4c\x67\xc5\x41\xd8\x50\x2a\x7d\x03\x18\x95\xaf\x85\x31\x9a\x4e\xae\x2d\x25\x43\x35\x83\x5e\xff\x11\xe7\xa3\x67\x1a\x6a\x0d\x21\xb7\x2c\xe1\xfc\x2a\xcb\xa1\xa9\x20\x18\x38\x34\xbc\x0a\x4b\x73\xf6\x39\xff\xcb\x0f\x6b\x81\xcd\x92\x0f\x2e\x94\x20\xd6\x12\x16\x6d\x56\x82\xa0\x60\x60\xea\x0b\x6f\xa6\x95\xfe\xcc\x77\x04\xbb\xe4\xb0\x52\xaa\x3e\xc8\xf7\x20\xf7\xd4\xf3\x2e\x8a\xff\x86\xb8\x0b\x8c\x1c\xc1\x27\x64\xa0\x48\x74\x03\x7c\x31\x03\xe9\xdf\xec\xb8\xf7\xab\xcb\x0e\x07\x3b\x23\xe6\x7c\xa0\xa9\xb1\xfc\x72\x99\x3a\xbf\x31\xdb\xc2\x4a\x8f\xee\x09\x5b\x32\x51\xc2\x26\x26\xaf\x5d\xd1\xb6\xd3\x4b\xe5\xea\x06\xa0\x2a\xe1\x76\xc7\xb8\xcb\x9d\x06\x35\x01\xbe\x6f\x61\x20\x82\x88\x9f\xdb\xdc\xbf\xad\xc3\x3a\x0d\x31\x1b\x08\x0b\x8d\x64\xe4\x9f\x16\xb1\x6d\xd8\xed\xd3\xb2\xed\x11\x93\xa7\x4e\x5b\xe5\x07\x60\x9b\x04\x27\x27\xcc\xf0\x8a\xfb\x05\xcc\x6c\x50\x52\x4e\xf0\xe2\x66\x46\x21\xdc\x8b\x05\xb1\x5f\xfa\x81\xab\x6f\x7e\x3c\x8a\x5b\xb3\xea\xb1\xf6\x8e\x36\x56\xc1\x19\xd9\x69\xe4\x14\x4c\xf3\x28\x5a\xf2\x3c\x04\xdb\xec\xc0\x38\xae\xfd\x91\x83\xc4\xe7\x24\x47\xb2\xaa\xa8\x31\x5f\x46\x96\xce\x6d\x1e\xf4\x29\xba\x0e\x5c\x3d\x5f\xfa\x7f\x05\x0b\xe3\x9c\x7f\x61\x2f\x4e\x10\xf8\xef\x07\x0d\xf7\x2f\x8a\xdd\xbe\xaf\x33\x39\xc1\xad\x8b\x5f\xc3\x9a\x2e\xcf\x29\xa8\x7f\x82\xe2\x9a\x01\x17\xba\xac\x66\x25\xad\x5c\x80\xcf\xe7\x59\xfa\x1d\xbc\xfa\xa1\x2b\x37\x44\x77\xd8\x0b\xfc\xf0\x67\x96\xc3\x0f\x2c\x39\xcf\x03\x03\xd0\x0d\xc5\x6a\x32\xd1\xd0\x39\x59\x2d\xdb\x06\xc2\x2a\xa0\x68\x84\x1c\x0b\x46\xfd\x48\xdf\x8f\xbb\x74\x92\xcc\xbc\x59\x0c\x56\x3c\x8f\xec\xce\x42\x63\xc8\xc7\x53\x92\x18\xbb\x97\xb3\x57\x11\x53\x7e\x98\x81\x95\xdb\xf5\xbc\xd5\xcc\xaf\x06\xfa\xf5\x08\x47\x09\x77\xa5\x35\x8e\x6f\x02\x60\x83\x49\xfb\xb9\x9a\x23\xfb\xe3\x6b\x8c\x97\x15\x5a\xdc\x24\x6a\xd7\xd9\x3a\x8c\x20\x3f\x75\x44\x6c\x83\xc4\x34\x2c\x35\xba\x10\x4e\xcc\x67\xe6\x69\xdb\x4a\x95\x46\x6e\xe6\x8f\x45\x8a"}, +{{0x7c,0x27,0xae,0x47,0x07,0x2b,0x0c,0x9b,0x9c,0x2c,0x35,0x1f,0x13,0x27,0x89,0x98,0x95,0xef,0xa5,0x36,0xc9,0xc0,0x67,0xd0,0xe0,0xce,0x8e,0x82,0xe6,0x29,0x27,0x93,},{0xf9,0xfe,0xbd,0x12,0x1e,0x17,0xdb,0x72,0x29,0xb5,0x67,0x09,0x02,0x18,0x49,0xc3,0x5d,0x69,0xfa,0x08,0xb5,0x06,0x20,0xe6,0x67,0xf8,0x42,0xec,0x7a,0xc7,0x82,0xdc,},{0x32,0x71,0x96,0xdd,0xd4,0x3b,0xb6,0x02,0xd0,0x4d,0x19,0x64,0xcc,0xc0,0x59,0xed,0x62,0x7c,0xef,0x0a,0x88,0xd8,0xad,0x91,0xbe,0x49,0x31,0xf1,0x7c,0x25,0x0d,0x55,0x29,0xf5,0x52,0x79,0x4a,0x3e,0x26,0x9d,0x17,0xa6,0x3b,0xd3,0x29,0x33,0xeb,0x5e,0x51,0x9c,0x1d,0x50,0x65,0x74,0x77,0x0a,0xe4,0xa7,0x29,0x64,0xe0,0x6f,0x7d,0x00,},"\x15\x47\x87\x6a\x98\x8d\x1b\xe7\x14\xa4\x2f\xb9\x1c\xb0\x37\x63\xf1\x91\x3a\x89\x2e\xcb\xd4\xde\x2c\xcf\x83\x44\xd2\x07\x58\xb7\xb6\xd0\x02\x59\x10\x1f\xe9\x72\x25\xb2\x97\xf8\x7b\xfe\x22\x20\x04\x32\x5d\xb7\xf6\x32\xce\xaf\xfb\xd1\x34\xc9\x6c\xbd\x57\xe9\x85\xbe\xc8\x43\x4f\x81\xa4\xee\x6a\xf8\x5c\x3f\xad\xe5\x0e\x4c\x4e\xf2\x0c\xb0\x39\x35\x45\xe4\xd4\xa8\x6e\x1f\xa3\x9a\xaf\x33\x3f\xe4\xde\xd0\x54\xbf\xc0\x50\xa8\x98\x3a\x03\xdd\x1e\xcf\x2b\x5e\x95\x17\xba\xf9\xe1\x15\x21\x29\xa8\xa7\x59\x35\x71\x1e\xdb\x20\xaf\x5c\x8c\xf9\xc6\x94\xa3\x3c\xee\x45\x1c\xd9\x50\xb2\xff\xf0\x8e\x31\x58\xc5\xcf\xb7\xb1\x5c\xb3\xe9\x0d\x46\xf4\x94\xb6\xa1\x08\xd8\x88\x8d\x5e\xc2\x9a\x33\xc0\x66\x02\x3b\x49\x77\x09\xb2\xd9\x40\x1f\xea\xf2\xe7\x4f\xf2\x6c\x16\xd3\x6c\x39\xe6\x51\x7f\xf9\x54\xbd\x98\xbc\xe7\x70\x06\x71\x98\x8f\x66\xe8\x51\x07\x64\x4b\xa2\xea\x00\x7a\x13\x01\x8c\x1c\x14\x4e\x3c\x5b\xb8\x0d\xb9\x51\x1f\xcc\xa4\x10\x1b\xf4\x9f\x8c\x80\xff\x3c\xa7\xd2\x98\x25\x7c\xbf\xea\x62\x9f\x83\xd5\xe0\x66\x39\xd3\x1f\x63\x9d\xb4\xb8\x72\x6c\xbe\x22\x4d\x75\x88\x29\xba\xb1\x09\x05\x17\x1c\x9c\x0e\xc3\x70\xd5\x80\x31\xef\xe4\xcc\x5a\xe7\x2a\x49\x5a\xcf\xf6\xcb\x2e\xd9\xee\xc6\x58\xba\x11\x70\x88\xdd\x3c\x6e\xd1\xdf\x8f\x9c\xb1\x0b\xd4\xfe\x0e\x5e\x8a\xd9\xf5\x03\x4e\x34\x65\x2d\x98\x66\x8d\xb1\x5c\x85\x33\x39\x3a\x6e\x9e\xc0\x87\x0c\x35\x66\x6c\xe5\x4e\xfe\x2b\xcb\x45\xc3\x4a\x72\x30\xe6\xa7\x00\x67\x63\x49\xc7\xb3\xab\xf3\x1d\xe7\xb7\xb0\x52\x1f\x89\xb3\x0a\xc4\x03\x4c\x2a\x4b\xa8\x21\x8e\xef\xdf\x8d\x2a\x5c\x1f\x8e\xd9\xb7\x01\x57\x9e\x47\xaf\x8a\x52\x9a\x95\xa1\xff\x64\xd8\xfd\xb8\x85\xc3\x68\x39\xb4\xc5\xf6\xd7\x2a\x99\x25\x7e\x86\x78\xdc\xcf\x31\x27\x54\xb9\xd4\x61\x9b\xee\xce\xb8\x25\x52\x6d\xe6\x22\xbd\x96\x76\xfd\x5f\x35\x76\x93\xab\xab\x07\x8b\x9e\x03\xae\x21\xe8\x7c\xa1\x61\xe7\x78\xaf\x77\x09\x6e\xaa\xc2\xd2\xd3\x2b\xfe\xc8\xec\x94\xaf\x79\x65\xf6\x1d\x68\xef\x66\xa4\x52\x3c\x1c\xc7\x0c\x95\x19\xb0\x75\x0b\x3c\x9e\xed\x5a\xeb\xa9\xf0\xa9\xb7\xef\x52\xcd\x4a\x2d\xe2\x9b\x39\x5b\x70\x5f\xa5\x3f\x02\x8f\xa7\x66\x15\x9f\x20\xe7\x5f\x4d\x38\x4e\xc4\xfd\x66\xdf\x06\xe7\x44\xc9\x9a\xc8\x8c\xb8\x49\xc2\x85\x75\x7c\xc5\x57\xe2\xee\xdd\x86\x95\x9d\xa2\xc1\xb8\x1f\x5b\x27\x15\xa6\x51\x98\x48\x90\x1a\xe4\xf8\x9d\x09\x13\xc8\xde\x57\xc5\x3d\xad\xf2\xe5\xe1\xaa\x2a\x9c\x5f\x46\x4f\xc7\x61\x0e\x8e\xf5\xf5\xcd\xd8\x20\x3a\x67\xa9\x3c\x33\xa0\x6d\xab\x35\x8d\xc5\xae\x23\xed\xfe\xe6\x33\x42\x62\xf4\x7b\x19\xb1\x13\xd6\xca\xfe\xda\xc1\xb4\x39\x02\x53\x9d\x74\xfb\xa2\x9a\xaa\x7b\xce\x68\x88\x4b\x72\x61\x6a\x05\x42\xc9\xfc\x69\x54\x7c\xd1\x9a\xe1\xdf\x01\x72\x3a\xbd\xda\x65\xe9\xbf\xac\x5d\xa0\xd0\x42\x40\xc6\xa2\x17\x5c\x00\x62\xe4\xe1\xed\x8a\x5b\x39\x7a\xfc\xd4\xde\x38\xe8\x62\x09\x27\x2c\x7a\x42\x4b\x5a\xe8\xd5\xa4\x0b\x48\x4c\xe1\xb4\x70\x4a\xf2\x83\x16\x09\xad\x0f\x36\xe9\x0e\x07\xb2\xaf\xed\x01\xdc\x05\x57\x4a\xd3\x97\x17\x23\xc5\xb5\xc1\xdd\xd4\xfc\x8b\xd2\x63\xbc\xdf\x56\x8a\xf7\x5e\x73\xd8\xab\xd1\x00\x8c\x9e\xc7\x12\xf8\x0f\xfc\x65\xac\x34\xe2\xa7\x93\x04\xea\xde\x1d\x2a\x1d\xff\xec\x0e\x4c\x98\xc3\x58\x24\x68\xf3\x20\xbf\x8f\x66"}, +{{0x08,0xed,0xdc,0xb5,0x62,0x5a,0xe1,0x9f,0xfe,0x7b,0x49,0xa7,0xdc,0x82,0x9c,0x89,0x3c,0x75,0x38,0xb0,0x88,0x5e,0x18,0xf9,0x8d,0xb7,0x8c,0x8b,0xeb,0x56,0x9c,0x26,},{0x83,0x47,0x8b,0x1c,0x58,0x57,0x6a,0x0d,0x18,0x34,0xb2,0x8d,0x46,0xfb,0x80,0x51,0x6d,0x6f,0xb6,0xf9,0xf5,0x91,0x69,0x4b,0x44,0x35,0x2e,0xec,0xd1,0xe7,0xe8,0x9a,},{0xec,0xe7,0x53,0x22,0x99,0x51,0x54,0xb2,0x92,0x43,0x7e,0x47,0xd3,0x8a,0x6a,0x70,0xaf,0x37,0xe2,0x02,0x07,0x16,0xfd,0xe4,0x6b,0xfd,0x39,0x3b,0x3d,0x36,0x9b,0xdd,0xb5,0x32,0x53,0xb5,0x56,0x62,0x1c,0xfb,0x34,0xc8,0xa9,0x02,0x54,0xe1,0x32,0xfd,0x28,0xec,0xd0,0x98,0x43,0x34,0x13,0xa2,0x1b,0xd3,0xa9,0x79,0x8c,0xa1,0xf3,0x09,},"\x01\x5b\x1d\x3e\xeb\x00\x92\x9e\xa8\x0b\xd8\x68\x7d\x18\x28\x6f\x0a\xdf\xe6\x45\xcc\xf2\x5a\x22\xb5\x06\x19\x21\xe2\xa0\x30\xfc\x76\xd0\x33\xfb\x53\xd0\x93\x7c\x69\xb3\x1c\x5b\xe4\x99\x13\xca\x1f\x2c\x3d\xca\x12\x1b\x2b\x87\xc5\x9b\x3c\x84\xc7\xae\x52\xaf\x19\xc6\xb9\xfa\x1b\xd6\x75\xfb\x6d\xd8\xb3\x29\xd5\x66\x87\x86\xdc\x78\x83\xe2\xd2\xe8\x58\x6f\xf4\x12\x8b\x90\xde\xe8\x4b\xe0\xab\x54\xd6\x81\x3f\x7a\x8c\x61\x34\x75\x71\x73\x98\x17\x75\xde\x84\xc4\xdd\x39\xe3\x36\xf8\xa4\xef\x8d\xca\xde\xc9\x43\xe9\x0d\x42\x1b\x22\x9c\x11\x78\x5f\xcd\x3f\xe9\x63\x03\x74\x58\xe7\x6c\x82\x0b\x3b\xc2\xc9\x47\x60\x01\x26\x2b\x26\x1d\x28\xb6\x5b\x48\x9d\x76\xb4\xbe\x23\x65\xe4\xa8\x0f\xa8\x71\xb0\xa5\x3b\x6a\x5f\xb2\x43\x68\x82\x35\xac\xc5\xf4\x77\x4d\xb1\x5d\x47\xb4\x2d\xd6\xc8\xd9\xe1\x2d\xcb\x0b\x5d\x98\x0d\xab\x0f\x3a\xd8\xa4\x96\xf7\x6e\x50\x06\xc2\xca\x82\x67\x5f\xf1\x94\xca\xf8\x07\x0d\x04\xbd\x38\x4f\x97\xe5\x83\xe7\x3c\xbc\x4f\x7f\x25\x73\x10\xa6\x1b\x1c\x80\x62\x32\x2d\xce\x81\x15\xf6\xdd\x93\xee\xe8\xa9\x3f\xfa\x5c\xab\x66\x34\x11\x6e\x1a\xb7\x05\xfa\x86\xc4\xa8\xea\xa5\x56\xc6\xc8\x9d\xbc\xad\x01\x04\x36\xbf\xfe\x45\x18\x22\x49\x1f\x1e\xa8\x6c\x20\x20\x7e\x4d\x12\xdf\xa3\x62\x61\x6c\x58\x9f\x97\x10\x7e\xa5\xd8\xbd\x8a\x72\x15\xc6\x00\xff\xc7\x0b\x80\xe2\xab\xb1\x5a\xcb\xe4\xbe\xcc\xa2\x0d\x72\x15\x5a\xbc\x3d\xbe\x8e\x37\xcf\xd7\x3f\x74\x20\xf2\x1c\x9b\xcd\x0c\x32\x73\x51\x3b\x50\x49\x67\x08\x74\xd5\x51\x9b\x3b\xc1\xdb\x52\x3c\x1d\x7e\x90\xc1\x65\x96\x7c\x4c\xb2\x84\x5a\x2e\x8b\x47\xb5\x88\x92\x54\xf5\x8a\x9b\xbb\x82\x6f\x94\x52\x1c\xdb\xd0\x41\x6f\x5f\x18\xff\x78\xa3\xfd\x0d\x7a\xb8\x97\x90\x62\x64\x48\x3c\xde\x64\x2d\x8e\x70\x3f\xd8\x2e\x5a\xe7\x0a\x9f\x97\x8f\x64\xee\x80\x52\x05\x54\x85\x05\x28\x58\x1c\xa9\xa0\xb3\x8c\x19\x6f\xd1\x66\xda\xe5\x87\x9b\x3f\x72\xf5\x9c\xde\x91\xcc\xa2\xc8\xbf\xaa\x47\x8b\x98\xd6\x24\xcd\x34\x72\x44\x02\xde\x57\x8e\x57\x54\x82\x5c\xe2\x27\xd2\x87\x1b\x45\xa5\x11\x71\x49\x51\x5b\xff\x81\xa9\x23\x24\x6f\x3b\x72\xd0\x7b\xd4\x58\x12\x5c\x70\xa1\x4d\x87\xc3\xfd\x13\x39\x2a\x3b\xda\x65\x53\x01\x6e\x8b\x2d\x07\xbd\xe9\x03\xcf\x68\x7b\x44\x5c\xfd\x6f\x76\x14\x92\xeb\xa4\x65\x22\xad\xa8\x4a\x96\x15\xd8\xda\x34\x98\xb2\x58\x06\x72\x69\xb7\x88\xe5\x59\xb6\x59\xd4\xb4\x8a\x87\xd8\x80\xd6\x37\x8b\xe6\xa8\x87\x46\xf3\x5b\x32\x2b\x04\x78\x45\xaa\xdc\x52\x3b\xea\xff\x30\x70\xf7\x21\xc3\xc0\x71\xea\xa3\x19\xb7\xa4\x7c\x1b\x20\xd3\x00\xdc\x03\x21\x90\x9b\x66\x9e\x57\xd3\x9a\x1c\xe2\xfd\xbe\xaa\xfa\xc2\x13\x50\xec\x2d\x6e\x6d\x5b\x88\x01\x86\xc0\x28\xa8\x61\x47\x4d\x50\x76\xa4\xad\xc5\x03\x2f\xec\x91\x40\x78\x7c\x36\x80\x6e\xf7\x9c\x72\xe3\xa1\x9d\x8c\x8b\x70\xbd\xaf\x20\x72\x95\x54\x2d\x96\x82\x5a\x5d\xe7\xdf\xe1\x08\xef\x57\x45\x99\xb8\xf1\x84\xc6\x3a\x5a\x13\x1d\xb1\x9b\x3b\xe5\x3f\x69\x9c\x10\xfc\x4c\xa7\xc6\x3f\x35\x00\x21\x1b\x35\x6a\x0a\xc6\x64\xdd\xfc\x1a\x92\x52\x59\x00\x26\x39\x5b\x47\x9b\xe9\xa5\xe4\x75\x84\x23\x56\x0b\x65\xbb\xce\x5b\xba\xde\x49\x3b\x13\xd0\x0c\xf8\xc1\xd3\xb7\xe9\x22\x13\x67\xe8\xf0\xea\xda\xb6\xe6\xd1\xb5\xff\xfd\xe7\xb2\xd7\x41\xfc\x2c\x83\x02\x24\xff\xf7\xff\x14\xae\x5c\x07"}, +{{0x22,0x73,0x94,0x2d,0xb3,0xe5,0xd3,0x22,0x1e,0x80,0xd9,0x94,0xfd,0x5e,0x11,0x63,0xaf,0x55,0xf5,0x45,0x5a,0x8e,0x52,0xbe,0x85,0x2d,0xd3,0xad,0xf7,0x62,0xb4,0x40,},{0xbc,0x58,0x67,0x4e,0x99,0x6b,0x6f,0x3e,0x32,0x20,0xb3,0xe9,0x4f,0x00,0x67,0xbb,0x0e,0x9b,0x0d,0x97,0xd9,0xe1,0x05,0x9c,0xf1,0x39,0x97,0xa1,0x93,0xac,0x03,0x2a,},{0x87,0x4d,0xde,0xce,0x08,0xf3,0x0b,0x30,0xf0,0xd4,0xc8,0xb3,0xed,0x7c,0x61,0x51,0x49,0xb8,0xaa,0x74,0x0d,0xaa,0x34,0x7b,0x55,0x95,0x8f,0x1e,0x21,0x19,0x04,0x4f,0x69,0x5a,0x21,0x06,0x96,0x90,0x50,0x64,0x48,0xd8,0xe7,0x35,0x2b,0x90,0x46,0x51,0x1d,0x7f,0x39,0xa5,0x41,0x5b,0xb9,0xc5,0x70,0x50,0xfc,0x17,0x05,0x5c,0x38,0x08,},"\x8a\xa0\x50\x9e\x4b\x91\x41\x86\xff\xff\x07\xae\xb9\x7a\x04\xb5\x46\x27\x2d\xa2\xf9\xea\x7b\xfa\x65\x9a\x24\xcb\x50\x96\x6c\x23\xeb\x65\x42\xe4\xf2\x2d\xeb\xe3\x3b\x65\x76\x92\x45\xc4\xd1\xb5\xdc\xf3\xe6\x99\xc7\x0c\x5c\x2b\xaa\xd9\x73\x4e\x9d\x1e\xfe\x54\x48\xab\x71\xc8\x94\x6a\xec\xce\x52\x68\xd2\x6f\x19\xcf\x60\x5e\xb3\xbf\x38\xb0\xb3\x32\x26\x94\xac\x0d\xcb\x76\xb0\xf9\x46\x84\x2f\x6c\x5c\x68\xd7\x63\xfc\xe7\x47\x01\xbd\x6b\x78\xe7\x1c\x8c\x31\x42\xad\xd4\xed\x46\xe0\x96\x9b\xb9\x55\x5b\xe0\x36\x02\xd5\x62\xe4\xc8\x9f\x3a\x91\x99\x40\xe8\x83\xa9\x69\x40\x54\x2f\x27\x79\xfb\xf9\xec\x0a\x28\x5d\x9d\x8a\x72\x36\x01\x46\xe3\xff\xbd\xb7\x8d\x21\x03\x16\x03\x8d\x95\xd6\xab\x75\x71\x65\xaa\x94\x3c\x03\x3e\xeb\xb3\x21\xc0\x5a\x39\x95\x69\xbc\xf6\x6b\x4d\xdb\x0b\x2e\x0e\x33\xc4\x79\x3d\x81\x7c\xcf\xf5\x7f\x99\xb3\x18\x9c\x60\xd5\xd7\xb9\x41\x9d\x1e\xbc\x94\x3a\x79\xd4\xd8\xc3\x94\x56\x61\x80\x59\x4f\x55\x9a\x80\x52\x9c\xc1\xba\x28\x87\x7a\xf8\xf5\xc0\x50\x3e\x94\x3c\xd3\xaa\xd9\x98\x11\x64\x52\x72\xda\xfb\x49\xb9\xb3\xe6\x10\x7e\xb5\xe5\x18\x6e\x16\x08\x75\x71\x26\x05\x3d\xeb\xce\xc7\x5d\xd9\x56\x5c\xee\xa0\x6a\x13\x91\xa8\x22\x6d\x1f\x45\x93\x79\x22\x40\xcc\xd9\x7c\x67\xa6\xc2\xb1\x34\x4c\x22\xc9\x1f\x42\x03\x3a\xde\xf5\x28\x61\xf3\x2a\x4e\x07\x12\xa9\x17\x87\x9a\x0b\x05\x18\xb5\x42\x4b\xcd\xc0\x54\xb4\x4e\x97\x2e\xd2\x4d\x01\x68\x9f\x4f\x27\xf5\xf1\x76\xf0\xa5\x78\xab\x2d\x3c\x08\x78\x27\x2e\x8c\x08\xc2\x15\x82\x11\x86\x54\x12\x4d\xca\x39\x58\x53\x37\xc1\x3c\x18\x65\x81\x4c\xaf\x09\x96\xca\xdf\xa6\x5b\xe5\x80\xde\xe3\x22\xeb\xcc\xda\x70\x4b\x22\x80\x58\x26\x04\x06\x7d\xc3\xc6\xb1\xf7\xd8\xa2\x69\x78\xa6\x5c\xff\xd1\xed\x31\x96\xa2\xb0\x65\xfb\x3c\xaa\x79\xe6\xb5\xb6\x6c\x13\xd7\xbd\x7d\x0e\xc1\x4a\x3a\x4d\x58\x41\x3f\x21\x2f\x47\x1e\xca\xad\x3a\x84\xaf\x35\xe5\x98\xa8\x9f\xb3\x44\x7d\x33\x24\xf0\x20\xfb\xf1\xb7\x3e\x2a\x98\x6e\x0d\xa1\x6c\x01\x83\xbf\x92\xa3\x98\xc4\x19\xa0\xf9\xf3\x05\x37\xbe\xa0\xdf\x8d\xf2\xdc\x53\xc1\x54\xe8\xea\x16\x06\x89\xe7\xbb\x4d\x72\x9d\xd8\xab\x90\x03\x14\x27\xaa\x39\x45\x86\x3a\x85\xe8\x96\x52\xb9\x35\x38\x05\x16\x6f\x7c\x0a\x18\xc9\x39\x95\x4b\x27\x87\xc3\x70\x94\xf9\x25\x12\x72\x2e\x52\xb0\xc9\x76\xb9\xe4\x2a\xf4\x03\x9d\x2c\x05\x78\xff\x14\xfa\xe1\xd8\xc2\xd1\x39\x6b\xeb\x2d\x6a\xa6\xeb\xd5\x54\x74\xa9\x34\x98\x67\xa0\x3f\x3a\x99\xd7\x87\x80\x63\x4a\xb4\xb3\x5c\xfe\x1b\x87\xa9\x13\x32\x52\xa6\x98\xbc\x40\x7d\x63\x84\x28\x70\xe2\x2c\xcf\x39\x33\x62\x0a\xc0\x42\x3c\x3d\x1f\x68\x1d\xd7\x3c\x01\xd0\x6c\x3b\x94\x15\x06\xc9\x8e\xed\x9b\x78\x68\xe0\x17\xb7\xf9\x97\x16\xb0\xb7\x7f\x11\x32\x1e\x5a\xb2\x3d\xbf\xcf\xca\x93\x50\x84\x5e\xe1\x80\x44\x4c\x50\xff\x0a\x9c\x96\x5f\xcb\xf7\x77\x70\x8e\x4f\x34\xcc\xc6\x37\xc6\xa0\x8d\x85\x43\x84\xf8\xd3\xe2\x51\x69\x56\xc1\x51\xd0\x31\xbb\x1c\xbe\x71\x2a\x5e\xf9\xee\x16\x61\x92\x28\xbd\x29\x6f\x2a\xfe\x58\x2d\x99\x53\xd5\x90\xd1\x8b\xb2\x05\xf7\x0f\x84\x4c\x16\xc0\xa2\xd8\x31\x80\x37\xd4\x3d\xd8\x0f\x65\xc6\xa7\x53\xf2\xa8\xe2\x7c\x89\xc8\x3e\x7e\xd7\x0c\x52\xf7\x06\x2d\xfb\xb1\xf5\x44\xaa\x23\x6b\x5c\x70\x4e\x7b\x39\xce\x0a\x55\xfd\x46\x52\x80\x83\xca\x61"}, +{{0xdb,0xfa,0x45,0xab,0xaa,0x55,0x41,0x52,0x38,0xb1,0x28,0x76,0x34,0xd5,0xee,0xc4,0x02,0xda,0xdf,0x62,0x2e,0x27,0x0c,0x04,0xa8,0x91,0x4c,0xed,0x27,0x0a,0x72,0xbe,},{0xc0,0xfe,0x32,0x35,0x81,0xea,0x29,0x67,0x50,0x79,0x7e,0xb5,0x50,0x8c,0xa1,0x9a,0x58,0x3b,0x53,0x7f,0xa7,0xdf,0x45,0x29,0xf0,0x80,0x4a,0x33,0xc1,0xa4,0xbe,0xf4,},{0xa4,0x62,0xa9,0xba,0xa5,0x6d,0xc0,0xf7,0xa7,0x1b,0xf8,0x7b,0x95,0xf4,0x8d,0x64,0x20,0x22,0xd9,0xd1,0x73,0x3e,0xe3,0x68,0x37,0x77,0xa3,0x78,0x22,0x28,0xac,0x85,0xfc,0xd8,0x30,0x26,0xbe,0x4c,0xa9,0x7a,0x34,0x5b,0x08,0x4f,0x50,0x87,0x4e,0x91,0x24,0xe1,0x6b,0xa1,0x7d,0xea,0xd4,0xad,0x85,0xc0,0xe5,0x6f,0x16,0xef,0x18,0x04,},"\xe2\x6e\x8d\xcb\x44\xe6\x41\xfc\x20\x08\x0e\x95\x47\x4b\xd3\x9d\x71\x6c\x5a\xfe\x5a\x1f\xfb\x05\x6d\x1e\xaa\xb0\xc4\x9f\x85\x70\x71\x7d\xb6\x43\x7a\x03\x22\x8a\x9a\xd9\xf4\xbb\x0b\x34\x3b\x95\xe1\x60\x23\xc0\x80\x7e\xb2\xa1\x51\x06\xa6\xeb\x12\xdc\x76\x68\x3e\x69\xdd\xa3\x36\x31\x48\xc5\xd7\xdd\x97\x13\xaf\x6f\x87\xa0\x94\x10\xea\x8f\x76\xb6\xb7\x8a\x11\x44\x29\xbc\x85\xf7\x84\x81\x2f\xca\x31\xac\xb0\x30\x95\x52\xcc\x18\x8c\x6e\x96\x97\x09\x3c\xf4\x04\xc6\xf0\xf4\xab\xe8\xa1\x60\x86\x73\xfd\xfa\x5e\xb7\x8f\x65\xfc\x1d\x49\xcd\xec\x40\x94\xb1\xbd\x23\x4a\x46\xe0\xec\x62\xa4\xb6\xd3\x1b\x82\x96\x11\x54\x01\x27\x87\x6b\xff\x4c\x17\x3d\xe0\x58\xcf\x61\x00\x4b\x01\x4a\x7b\xdf\x79\x3d\xfd\x6b\x63\xc5\x07\xd2\xb2\x3e\x0f\x56\xbc\x2f\xe6\xba\xf6\x37\xce\xe4\x0d\x18\x99\x22\x95\xd8\x48\xef\x49\x8f\x8a\x16\x1b\xd8\x7e\x60\xc9\x1f\x97\xa9\x1e\x9e\xf3\xf6\xd9\x7f\x2b\x2d\x21\x04\xba\x6f\xdd\xd6\xc6\x80\x70\x62\x73\xda\xe8\x7e\x6e\xec\x1a\xf2\xa4\x59\x84\x98\x50\x69\xe8\x09\xe8\xde\x32\xc1\x28\x89\x29\x9a\x32\xd4\x0f\x38\x77\x45\x99\xac\x33\x24\xb7\xcb\x0a\x4e\xa6\x32\xc5\xf9\x10\xad\x87\xf5\xad\xbf\xa5\xc3\xbb\x20\x49\x82\x79\xfd\x53\xc1\xc2\x67\xfe\x0a\x84\x77\x30\x85\xda\x26\x6b\x25\x3c\xd8\x53\xdf\x7e\x96\x35\x58\xcb\x06\x88\x07\x80\x97\x34\x23\xc5\x64\xcd\x0b\xcd\x6b\x93\x33\x4c\x19\x59\x53\xd7\xcd\x89\x9f\x8a\x54\x7d\x1a\x1a\x0a\x8d\xef\xf1\x38\x1b\x43\x21\x57\x47\x28\xcf\x71\xb9\x6f\xf2\x09\xe8\x99\xda\xa8\xf1\x3f\x41\xb2\x30\xe1\x7b\xff\xdf\xdd\x2a\x89\x43\xaa\x5d\x21\xe5\xf3\x6e\x1d\xa0\x7e\xdd\x6c\xee\x92\xdc\x48\xb5\xb2\xa7\x58\x01\x46\xa9\xba\xf7\x13\x95\x0c\xe6\x76\x25\x5a\x89\xe3\x4f\x87\x87\x54\x7d\x62\x86\x8d\xb1\x4b\xa4\x65\x94\xda\x31\x0d\x7e\x2d\x9e\x7c\x7d\xbe\x17\xdb\xd7\x1e\xb4\x7c\x56\xc5\x72\x1d\xc9\x6d\x69\x64\x70\x57\x37\x94\x80\x94\x11\xcd\xfa\x27\x6b\x05\x9d\x00\x07\xc2\x5d\x74\xb2\xa6\x7d\x38\x24\x6d\xe1\x1e\xf4\x6d\xfe\x26\x70\x92\x6f\xe4\xb6\x36\x56\x23\x1b\xc7\x26\x8b\xba\x23\xf3\x78\xe8\x4a\x42\x8c\x3c\xbf\x45\xcc\x53\x96\x78\xfd\x46\x7c\xd3\x3d\xd0\x75\x7c\xfa\x02\x4e\x54\xda\x1f\xf5\x4c\xe8\x20\x22\x9b\x77\x8b\x18\x4b\xe1\xfa\x2e\x84\x68\xcc\x19\x95\x59\x40\x73\x5e\xaa\xa8\x84\x02\x2f\x64\x18\xb0\xb1\xf2\x6b\xcc\xf1\x69\xf1\xbc\xac\x7d\x82\xa3\x5a\xb6\xef\x84\x7e\x1d\xba\x53\x7d\xca\xff\x57\x25\x0a\x8d\x1c\x71\xfa\xcb\x13\x4c\xd0\x6b\x01\xc4\x53\x19\x13\x27\x45\xdc\x48\x88\x88\xa1\xd7\x76\x1b\x84\x86\xa3\x7e\x69\x88\xa1\x12\x0b\xcc\x16\x82\xdb\xfc\x89\x14\x3f\xc3\x5b\x46\x93\x5d\x8a\xcf\x6e\xf3\xc4\x2f\x0f\x4b\xf6\x79\xdf\xd6\xff\x44\xb6\xad\xa2\x6b\x01\xa9\xf8\x9f\x37\x4c\x7d\x2e\xe4\x8d\xfe\x1a\x41\x0e\x89\x7c\xdf\xd9\x7f\x62\x6d\x26\x68\x50\x28\x14\x40\x07\x93\xb3\xb0\x7c\x87\x20\xbb\xdd\xc5\x9c\xb0\xf9\xde\x96\x4a\xe0\x75\xb4\xaf\x3d\xd4\xba\xf6\xd0\xe4\xf9\x4f\x29\x4e\x81\x09\xd6\x57\x7c\x4f\x8a\x9c\x7a\x5f\x7d\x69\x4b\xf8\x8f\x1a\x5e\xa7\xeb\xa0\xa6\x6d\xa6\xc7\x70\xc0\x8b\x3a\xbf\xfc\x53\x4d\xf2\x19\xdc\x3e\x33\x23\xb0\x22\xe9\x6c\xc8\x60\x02\xb1\x89\x18\x1a\x1d\x2b\x52\x7d\x27\x95\x0b\x7f\x42\x5a\x47\xda\x40\x13\x77\x8b\xd0\x0b\x71\x10\x59\x22\x20\x49\x21\xe9\xdc\x69\x2c\x23\x3f\x7b\xaa\x04"}, +{{0xef,0x64,0xe1,0x7a,0x53,0xf7,0xfb,0xca,0xfe,0x3e,0xa4,0x68,0x76,0x84,0xa0,0xda,0xdb,0x18,0xd0,0x37,0x35,0xa4,0x0a,0x53,0xb3,0xed,0xb0,0x49,0x07,0xee,0x61,0x62,},{0x91,0x86,0xe6,0xbc,0x14,0x29,0x61,0xc4,0xd3,0xeb,0x36,0x9e,0x9e,0x11,0x57,0x82,0x92,0xde,0x5b,0x6a,0xf5,0x34,0xd4,0x23,0xff,0x24,0x0f,0xa2,0x6e,0x21,0xa7,0x81,},{0xf5,0x8f,0x39,0x6b,0xa2,0x7e,0x06,0x7a,0x5f,0xe0,0x03,0xe3,0x85,0x58,0x2a,0xe3,0x49,0x0e,0x05,0x95,0x77,0x15,0xd7,0x04,0xda,0x0d,0xa6,0x3a,0x64,0x19,0xd2,0xe4,0xf6,0xdc,0x66,0xb7,0xe8,0x8e,0x42,0x8a,0x6f,0x21,0xb9,0xea,0x20,0x22,0x99,0xa3,0xc3,0x6b,0x24,0x2b,0x0e,0xa0,0x64,0x76,0xff,0x12,0xd0,0xb6,0x58,0x0c,0x04,0x03,},"\x68\x82\x45\x6c\xc3\xd1\xad\x0d\xaa\x9b\x88\xef\xf0\x96\x9f\x15\xe9\x7b\x48\xd0\x51\x96\x7e\x13\x90\x84\x72\x25\xf2\x6a\xc2\x55\x59\xf0\x24\x6b\xf7\xd6\x83\xfa\x28\xec\xed\xad\x21\x49\x1d\x77\xbd\x26\x96\xfa\x83\x5d\x0f\xd1\x19\x88\x4f\xec\xe9\xd8\x03\x69\x1b\x2f\xd3\xde\x17\xee\x08\x7c\x74\x00\x7a\x7d\xe9\xbc\x65\x34\xbb\xfe\x95\xfd\x32\xe9\x7c\x37\x5f\x4c\xb6\x57\x31\xaa\x1e\x83\x46\xbe\xa2\x1b\xe9\xf2\xc3\xdc\x87\x4a\xf0\x43\x19\x06\xcc\xbc\x2c\x60\x01\x27\xf4\xd3\xb0\x69\xeb\x09\x1d\x16\x5e\xc4\x53\xe6\x72\xe9\x3c\xae\x8b\x72\xf0\x33\x71\xd8\xb8\xa8\x24\x4e\xc4\xec\x2e\x09\xf3\x1d\xf4\x02\x06\xa2\xb1\xc8\x4c\xaa\x1b\x99\x3c\xc6\x75\xfd\xe1\xc7\x9b\xd4\xa7\xd1\x59\x74\xfa\x29\xce\x2e\x89\x2c\x28\x99\xcf\x48\x2c\x3d\x96\x63\xf6\xd2\xa7\x97\x84\xf4\x1c\x1f\x58\x66\xd3\x7c\x85\x46\xf3\x57\xd5\x64\xd3\xc4\x21\x8d\xfa\x6d\x20\xb6\xc2\x82\xb4\x00\xfe\xdd\xe5\x24\x39\xd4\x72\x21\x2c\x57\x67\xa3\x5d\xa5\x20\x10\x32\xda\x87\x30\x96\x8b\x07\x20\xe8\xa6\x04\xde\x6c\x1b\xaa\x3f\x4e\x89\x6a\xc2\x61\x4f\xb1\xab\x6e\x3f\x6c\xf3\x87\xa8\xeb\x2f\xf8\xa9\x21\x47\xab\x34\x92\x38\x43\x2e\x50\x9d\x82\x9c\xb7\x5b\x2c\x17\x65\xc5\x12\x21\x84\x8e\x25\xaf\xff\x5f\x16\xe4\xdd\x0c\xd5\xc9\xf7\x13\xc4\xaa\xab\x2c\xe8\x36\xf8\x49\x45\x06\xb5\x30\x9d\xc2\xb0\xae\x74\x5b\xb9\xc4\x79\x80\x98\xfb\x86\x41\xd5\x20\xa0\x8b\x02\xf7\x5a\xd8\x0d\xbc\x2c\xe2\x9e\x89\x0b\x4d\x72\xa3\xff\xb2\xa1\xcb\xd5\x38\xe1\x22\x9f\x57\x9c\x29\xae\x66\xbc\xa8\x5e\x0f\xa0\x8c\x86\x47\xa1\xab\xcf\xe8\xa4\x9f\x5e\x50\x8d\x4d\x24\x95\x55\x66\x23\xd9\x26\xce\x49\xef\xa4\x35\x0a\xaa\xab\x5c\xec\x2c\xd8\x85\xbe\x1d\x63\x47\x5e\x3b\xab\x7c\x7c\xdc\x8d\x65\x61\x73\xb8\xd4\x56\x02\xf4\xb3\xd2\x81\x24\x1d\x17\x19\x03\x27\xb2\x4c\x38\x36\xb1\x93\x11\xa1\x93\xaf\x86\xa6\x76\x8f\x04\x85\x2a\xb0\x6e\x67\xc8\xea\xd5\x91\xcd\xcb\xf3\x78\x9c\x61\x32\x09\xcf\xe0\x3f\x58\xc0\x30\x5f\x63\x20\x3b\x48\x7f\x7c\x5f\xc0\x98\x87\x7e\xc9\x8a\x68\x9c\x9d\x35\xaf\x81\xe8\x40\x78\xd6\x6f\xe9\xe4\xec\xcb\xb1\xcc\x6c\x71\x99\x1c\x03\x01\x7b\xb8\x11\xf4\x1f\x07\xde\x68\xfa\xd1\x94\x14\x60\x61\x32\x4f\x3d\x0e\xf2\x17\xa5\x4c\xf3\x8f\x7a\x62\x5a\x38\x86\x9f\x67\xd0\xb7\x43\x1d\xf9\x37\xcd\xe3\x49\xc1\x75\xce\x8b\x26\xac\x88\xd3\x9a\x43\xe2\x79\xb0\x18\x76\x4e\xfa\x4d\xd6\x27\xcb\xf5\x91\xf6\x20\x9c\x4a\x5b\xb1\x9e\xbf\xa7\xc7\x13\x55\x92\xd0\x2e\x50\x1c\xae\x5e\x6b\x31\xc9\x0e\x72\xfa\xab\x47\xf7\xdc\xed\x2c\x48\xad\xf8\x84\x43\xb3\xed\xe6\x0c\xef\xb0\xd6\x37\x9d\x69\x22\xec\x43\x7f\x08\x6b\xad\x62\x17\xd4\xd4\xff\xef\x18\xe2\x25\x23\x66\x4b\xf4\xe9\xca\x1e\x65\xa2\x8c\x2a\x7a\x60\xc5\xf6\xbc\x90\x6b\x73\x7c\x29\x93\x5f\x90\x97\x46\x30\x48\x57\x5b\xef\xd1\xa2\x54\x9d\xc4\x74\xb1\x3e\x68\xae\xec\xf1\x66\x04\x3e\x07\x5a\xac\x51\x55\x40\xf8\x31\xb4\x30\x66\xce\xf9\x32\xe6\x3d\xcd\x5b\x37\xb6\x15\x78\xc3\x5b\x09\xe4\x5c\xc2\xa8\xde\xf5\x71\x03\xed\xfc\x5f\x64\x98\x31\xa8\x96\x1f\xe4\xa4\xb3\x72\x1f\x1d\x6d\xf4\xea\x9f\x03\x38\x81\xb4\x74\x30\x0e\x0f\x12\xcb\x9c\xd3\xba\xbd\xcf\xfb\xb9\x18\xdd\x9b\xb0\xe2\xf5\xb2\x10\x33\xe4\x30\x23\xa0\xd2\xe6\x6d\xa3\xab\x0f\x07\xee\x98\x8b\x16\x88\x9c\xa5\xd5\x1a\xbd\xc0\x5f\xde"}, +{{0x33,0x47,0xdc,0x47,0xbb,0x3d,0x2e,0x5d,0x02,0x86,0xac,0x06,0xa5,0x4f,0xd9,0x21,0xc9,0xe9,0x6b,0x68,0x99,0x86,0x2a,0x54,0xe5,0xcc,0x81,0x15,0xd3,0xd0,0xba,0x99,},{0xd0,0x0b,0x64,0x5d,0x86,0xdb,0xb7,0xe5,0x24,0x75,0x7e,0xc7,0x78,0xc6,0x2b,0x7e,0x60,0xd0,0xb6,0x57,0x68,0x83,0x33,0x8c,0x9b,0x67,0xc2,0xc7,0xe4,0x50,0x92,0x68,},{0x9a,0xb4,0x29,0x9b,0x17,0x72,0x93,0x44,0x75,0x0b,0x69,0xdc,0x60,0x37,0x36,0x8c,0x98,0xf4,0x7b,0xe6,0x27,0xfb,0xd9,0xad,0xfd,0x8d,0xb3,0x9f,0x99,0x64,0xdd,0xb7,0xbc,0x92,0xd6,0x74,0xc7,0xbe,0x74,0x07,0x56,0x39,0x6b,0xaa,0xee,0xac,0xbf,0x74,0x94,0x7b,0x61,0x91,0xc6,0xed,0x1f,0x5d,0x32,0xa6,0x3d,0xf3,0x6d,0x54,0x26,0x01,},"\xe2\xf4\x8e\xdf\x9d\x64\x33\x20\xab\x99\x1c\x8f\xf9\xf6\xaa\x75\xfe\x06\x6e\x7d\x88\xff\x1e\x47\x2a\x5a\xc9\xc5\x18\xde\x1f\xb6\x29\x83\xb1\x00\x7f\x64\x22\x80\x91\x17\xbd\xbe\x8a\x0e\x57\x87\xf6\x6b\xb0\x57\xd2\x7f\x12\x9a\x20\x0b\x40\x57\x6e\x17\x19\xcf\x9e\x98\xfc\xb7\x2a\xf9\x4b\xb8\x2e\xe7\x0f\x37\x19\xa2\xe2\xcd\x9b\x64\x77\x7c\xea\x5e\x44\x64\x59\x87\x4b\x74\xbf\xbf\x56\xb2\xd2\x52\x64\x00\x59\x2a\x9b\x45\xa5\xcb\x79\x80\x92\xb6\x0a\x81\xb7\x1d\x82\xf0\x68\x5f\xae\x7f\x81\x0b\x52\xd2\x26\xad\xac\x7a\xd8\xa9\x18\x3f\x09\xfe\xbe\xe9\xd2\x50\x46\xc0\xfe\x30\x66\x81\xac\xe2\xbf\xf9\x1b\x34\x82\xb0\xbc\x30\xb2\x02\x1c\x43\x41\x64\x5d\x67\x51\x34\xfe\x30\x81\xc5\x1e\x5c\x59\xe4\x0b\x37\x5a\x14\x34\xf6\x3b\x42\x6e\x30\x53\x0d\xa9\x35\x3b\xb2\xa9\x42\x32\x20\x43\x4a\xe5\x9d\x7b\x6f\xdc\x14\x3f\x49\x82\xeb\x8c\xfa\x77\x51\xb7\x5b\xf3\xe9\xc9\x13\xc7\x3b\x76\x0b\x07\xd3\x95\x31\x0c\x59\xf3\xb7\x7e\xbf\x12\xed\x2d\x7b\x03\x59\x0d\x33\x17\xaf\x17\xdf\x42\x1e\x78\xb0\x84\x9f\xd5\x6d\x94\x5c\x56\x96\xa0\x40\xfc\xaa\x78\xa9\x3e\xcc\x16\xd5\xac\x34\x45\x06\x36\x11\xf3\x01\x3e\x9a\x3a\xe2\xe1\xc2\x70\xdd\x01\xa8\xff\xe3\xe6\x12\x6b\xc1\xe4\xc9\x5f\x65\x47\xa8\x65\x1f\x26\xb6\x40\x4e\x39\xee\x4c\xe7\x61\x89\x18\xf3\xf9\x37\xa5\x25\x73\xec\x27\x7b\x77\x1e\x91\xad\x09\x6f\xa1\x5c\x7a\x34\x0a\x80\x9b\x47\x03\x18\xa4\x63\x64\x23\xeb\x48\x88\xa1\x21\x60\xc4\x66\x3f\xce\x29\x96\xd6\x38\x89\x6c\x83\x9b\x2c\x7a\xd4\xb3\xa9\xb2\xe6\xcb\x71\xe9\x12\xfe\x39\xb8\x43\xc6\xe0\x83\x2e\xca\x22\xde\x93\x8b\x50\xae\x86\x3e\x48\x58\x2c\x10\x85\x12\x32\xf7\x5e\x52\x25\xb8\x89\x6b\x5a\x47\x0f\x81\x8b\x6f\xa3\x9e\xb7\xbb\x59\x03\x57\x67\x86\x12\xd2\x5f\xe1\xa4\x0e\xa1\xb9\xd7\x1d\x88\x09\x09\xc1\xbd\x4a\xd1\x76\xcc\x0c\xef\xfd\xce\xe7\x09\x9e\x78\x82\xa7\xc9\x07\xe4\xbe\xc7\x98\x30\xc6\x77\x1a\xcb\x89\x94\x4b\xd5\x4a\x51\x65\xb3\x18\x70\x91\x69\x21\xb1\x98\xac\xd4\x43\x2e\x7e\xed\x8c\xe1\xde\xb3\x45\xb1\x07\xed\xa7\x60\x26\x6f\xcb\xda\x3b\xa5\x22\x94\x00\xa3\x03\x60\xa4\x64\x5c\xa8\xdb\x38\xc3\xd5\xf4\xa8\xde\xf1\x57\xbb\xdb\xbf\x2c\x1f\xa1\xdc\x6b\x05\x14\xa4\xf5\xa0\x36\x4f\x92\x83\x81\xb4\x0f\x95\x57\x9a\x26\x46\x7f\x22\x82\xa8\xa2\x55\x75\x84\x02\xac\x9c\xa8\x0e\x89\xb9\xcc\x68\x60\xa3\x4b\xb3\xf9\x0c\x32\x37\x65\x7c\x21\x29\xea\x48\xc8\x52\xb9\x25\x69\xe8\x11\x06\xbc\xe4\x61\xe2\x02\x44\x54\x82\x1a\x91\x75\x92\xd1\x99\x1b\x5b\x69\xf2\x7b\xbe\x01\x99\x77\x52\x8a\x2f\xc0\x11\x92\xc5\x6b\x4a\xea\x87\x3c\xf8\xc5\x8d\xfd\x7c\xb4\xb0\xe9\x17\xe8\x7a\x87\x04\xc9\x92\x82\x0f\x98\xd7\x74\x04\xd3\xf1\xd2\x05\x0c\x67\x43\xf6\xe9\x3c\xdb\x51\xa6\x1a\xa6\xf4\x5b\x35\x1b\x26\x46\x1d\x13\x29\xf3\x15\x12\x72\xac\x39\x62\x34\xd0\xd6\x7c\x17\x8a\xcf\x91\xfc\x51\x0d\x86\x42\x9c\x69\xa8\x7f\xdf\x10\x11\x55\xda\x8d\x94\xde\x67\x22\x23\x8a\x6f\xb1\x70\x16\x86\x2b\x11\xd5\x02\xc6\x67\xee\x9c\xa0\xaa\xbe\x1c\x20\xb9\x77\x89\xf1\x86\x7a\xdd\x78\xb8\xb8\x7e\x9a\xb5\x19\x34\xc0\xb4\xa1\x6c\x2c\xbc\x4d\x2e\xfe\xdb\x79\xc0\x5b\x23\xe0\xcf\x78\x92\x01\xac\x75\xfe\x07\x6d\x31\x5f\xcb\xac\x20\xba\x0d\x31\xe4\xdc\x61\x69\x27\xd6\xea\xb1\xb1\xc8\x7a\x1c\x9c\x77\x8e\x4b\xd2\x85\x29\x58\x74"}, +{{0xff,0x15,0xd6,0xe7,0x4e,0x28,0xe4,0x1d,0x05,0xa8,0x66,0x3a,0x70,0x2f,0x03,0x8d,0x5b,0x85,0x78,0xc4,0x27,0x5e,0x77,0x2b,0x73,0xba,0x44,0x0b,0xc5,0xf5,0x5a,0x06,},{0x47,0x47,0xe2,0xe9,0xb8,0x26,0x37,0xb3,0x84,0x4b,0x85,0xf7,0x5b,0x59,0xf7,0x13,0x6b,0x7f,0xdb,0x1a,0x62,0xe7,0xb7,0x0d,0x6a,0xac,0x17,0xb3,0xc5,0x75,0x2f,0x2f,},{0x42,0xc1,0x29,0x5f,0xaf,0xe2,0x6d,0xe3,0xea,0x34,0x92,0x6b,0xf1,0xef,0x80,0xbc,0xaf,0xe4,0x7b,0x21,0xb9,0x0e,0xae,0xd1,0x96,0x35,0xed,0x75,0x38,0xd7,0x67,0xcb,0xf3,0xa1,0xe5,0xde,0xda,0xab,0x82,0xad,0xf7,0x51,0x20,0x37,0x3e,0x92,0x32,0x02,0xf7,0xfd,0xa0,0x82,0x67,0x84,0x29,0x2e,0xba,0x8b,0x23,0x8b,0x6c,0xb8,0x83,0x04,},"\xce\x7b\xf9\x72\x84\x4f\x51\x84\xae\x8e\xac\x87\xb1\x2b\xe9\x20\x2c\x72\x39\x96\x1d\xc2\x3c\xd4\x1f\xf5\x5b\x9b\xfa\xac\x0c\xc0\x6f\x3f\x1d\xec\xfa\x95\x71\x09\x5c\x8e\x82\xb4\xeb\x6f\x8a\x1c\x52\xc8\xd3\xde\xaa\x61\xa9\xaa\x94\xe2\xec\xd9\xab\x5b\x80\x63\xf2\xda\x6d\x80\x15\xdf\x0a\x51\x44\xfa\x3a\x48\xe3\x05\xad\x9f\x41\xea\xa1\x1c\x4d\x74\x85\x43\x74\xec\xbf\x38\x2e\x30\x02\x57\x9a\x9a\x24\x9e\xfa\x1e\x1c\xa0\x4d\x33\x84\x47\xd7\xf2\x20\x67\x03\xe6\xca\xbf\x5b\xbd\x33\x2b\x42\x57\x3b\xcb\xd3\xb6\xf7\x1b\x7c\x3b\xf7\x3d\x4c\x77\x4a\xa0\x1e\x86\x68\x41\x43\x28\x29\xd0\x7f\x96\xe1\xf6\x1a\x20\x21\x6d\x96\x8c\x90\xe3\xed\x11\xf6\x63\xf7\xd6\x27\x16\x22\xfe\xfc\xf3\xab\x68\xf3\x44\x32\x85\x15\xd5\xcc\xe2\xce\x85\xe8\xbf\x3d\x1d\x09\x04\x36\x92\xe1\xfb\x8b\xbd\xdc\x07\xa4\xab\x0a\x3e\xef\x8c\xa6\xa4\x20\xe7\x4b\xff\x8d\x3d\x71\x55\x96\xaa\x82\x16\x82\x95\x4f\xe8\x96\x29\xae\x27\xc1\xbb\x03\xb6\xaa\x09\xf3\x6a\x39\xa3\xe3\x7b\xa9\x81\x32\xf4\xe2\x38\x88\xf9\xf3\x35\xe7\xbe\xaa\x2c\xb2\x72\x7a\xcc\x3d\x27\x77\x30\x9b\x85\x29\x52\x32\xe5\x4d\xa8\x8e\xbb\x6f\x10\x53\xd6\xde\x79\xac\x66\x09\x85\x2e\xb9\x3a\x0a\x35\xbc\x1a\x7b\xdc\x22\xd6\x28\xbc\x86\x12\x4d\x69\x6c\x3f\x98\x28\xb6\xf8\xb9\xaa\xde\x1a\x65\x21\x61\x77\x48\x6c\x25\x2a\x4b\x42\xd9\x0a\x4e\x0f\xea\x20\x93\x48\x9e\x24\x4d\x80\x8e\xf7\x02\x1a\x97\xd5\x60\x8c\x0a\xe1\xd6\x63\xc7\x75\xe8\xbb\x9e\x9a\x73\x15\xf1\xfe\xb6\xd1\x29\xb5\xa5\x41\xea\x59\x29\xa2\xc6\x33\xb6\xd8\xc3\xc4\x54\x41\x71\x79\x46\xcf\x87\x3e\x9b\x4c\x51\x21\x80\x13\x5d\x54\xf0\x53\xab\xe4\x4c\x6d\xf3\x9b\x7b\x06\x2e\xf7\x24\x01\x62\xcb\xd0\xb8\x51\xaf\xe5\xf9\x15\x36\xa9\x49\x94\x18\xe8\xbf\xf4\x99\x64\x73\xd8\x05\xeb\xc1\xae\x48\xda\x2d\x0b\x12\x9e\x8e\x82\x52\xf1\xd5\x3c\x32\x8f\x32\xdb\x25\x2d\xe3\xbe\xfb\xe5\xf3\x12\x80\x12\x11\x43\xa8\x00\x4a\x4c\xae\x63\x1c\x82\x74\x09\xe5\x20\xe3\x94\xcd\x0f\x89\x50\xcd\x4c\x3c\xf3\xf3\xdb\xd4\x95\x2a\x4d\xfe\x69\x87\x5f\x56\x53\x89\x06\x1a\xd0\xa0\xce\xe6\xb6\xaf\xf0\x9c\xec\xa2\x6d\x99\x0e\x89\x6a\x2a\xba\x9f\x3b\x26\x01\x5b\x63\x42\x37\x68\x68\x4c\x03\xed\x0d\xe6\xce\xe7\xac\x5b\xbd\xf9\xf4\x85\xc2\x27\x5c\xd1\x2a\xef\xa8\xf9\x07\xb8\x51\xa0\x2d\x51\xc3\x4f\x12\x1b\x77\xf3\xa5\x6a\x9e\xbd\x1d\x65\xff\xe8\x9b\xee\x38\x1f\xf2\xa7\x48\x0e\x89\x68\xcf\xf2\x5a\xc8\xd0\x4e\x14\x9a\x9d\x50\x27\xd1\x4b\x88\xf8\xae\x26\x04\xd2\xac\x22\xac\x67\xd1\x3e\x90\xad\xa6\x20\xc2\x04\x6d\x28\x29\x93\x84\xd0\x95\x9f\xb7\x6e\x22\x58\x87\x96\xce\x42\x7a\xae\xaf\x4e\x2a\x8a\xae\xc3\xe8\x7f\x84\xcc\xd0\x82\x52\x4c\x96\xd7\x66\xee\xc6\x6f\x0b\xec\x3e\x79\x95\x58\x14\x5f\x09\xd3\x30\x13\x4f\x1c\x63\xf3\x70\x53\xcd\x4b\xdc\x1c\x37\xfd\xe9\x72\x91\x85\x75\x51\xf5\x0a\xc8\xe1\x5f\x06\xac\x1c\x73\xda\xa1\xe8\xc5\xbc\x92\x77\xe3\xd6\x9c\xb4\x4a\x32\x37\xec\x57\xdb\xbc\xcf\xdf\x66\x85\xad\xa2\x0b\x74\xa1\xbc\x6b\x74\xab\x05\x69\x0e\xaf\x9b\xd0\xc4\xbe\x17\x04\x2f\x5c\xd3\x20\xcd\xd6\x13\xdc\x08\xd2\x9a\xf3\x46\xaa\x41\x91\xce\x0b\x4f\x85\xbb\x2a\xd7\xf3\xba\xc7\x38\xa9\x37\x7e\xc6\xb8\x40\x62\xcc\x70\xfc\xa9\xec\xfb\xe1\xf5\x7f\xe5\xb2\xce\x7a\x4f\x73\x9c\x81\xca\xbc\xde\x04\x64\x51\xdd\x61\xce\x1d\xbc"}, +{{0x1e,0xd3,0x7b,0x61,0x0b,0x8b,0x35,0x41,0x7d,0x04,0xe5,0x9a,0xaa,0xda,0xc6,0x88,0xff,0x81,0xf1,0xe5,0x07,0xc8,0x9b,0x4f,0x40,0x01,0x60,0x94,0x19,0x08,0xcb,0x8c,},{0x48,0xe8,0xcb,0xeb,0x12,0x40,0xbd,0xeb,0xf0,0xa2,0xd9,0x29,0x53,0xaa,0x89,0xb2,0x82,0xc4,0x9a,0xab,0x2c,0x38,0xae,0x69,0x04,0x4c,0x51,0x51,0x5c,0x33,0x00,0xd5,},{0x86,0x08,0x81,0x5e,0x10,0x59,0x0d,0x55,0x04,0x87,0x4d,0x89,0x99,0xfd,0x6f,0x09,0x62,0x6f,0x95,0x0b,0xe2,0x0c,0x91,0x2c,0x27,0xc9,0xde,0x6e,0x79,0xb0,0xfa,0xf7,0x77,0xa5,0x33,0xbd,0x5b,0xb6,0x67,0xab,0x51,0x3a,0x49,0x45,0x8e,0xcd,0x67,0x87,0xa0,0x9e,0xc0,0xdf,0x6c,0x9c,0x9d,0x63,0x33,0xc5,0xe3,0xae,0x61,0xea,0x37,0x0a,},"\x1e\x67\x67\xdf\x97\xdb\x1c\xfb\x40\x88\xda\x7b\x20\x0d\x9f\x59\xec\x8d\xd4\x53\x3b\x83\xbe\x30\x9f\x37\x65\x00\x31\x06\x57\x27\xcd\x52\x02\xce\xf4\x84\x26\xa5\xf3\xa1\x1d\x50\xb3\x81\xf8\xbc\x22\xff\x10\x18\x27\x35\x9f\x2d\x0a\x61\x0a\x4f\x75\x54\x64\xa0\xc8\x91\xcb\xd9\x8d\x2d\xcb\x41\xd9\x77\x9d\x28\x8f\xcf\x1f\xea\x62\xe5\x21\x63\xae\x67\xe9\x04\x28\xb8\x63\x98\xef\xa2\x18\xf1\xb9\x82\x08\x1f\xc5\x13\x30\x5f\xd3\xe8\xec\xe7\xf9\xac\xb0\xe1\x0e\x00\x1d\x2e\xd2\x99\xa4\x8a\x80\x87\x0b\x3d\x5d\x8a\xb9\x00\x63\x09\xb3\x15\x91\xca\xf0\x58\x33\x80\x07\x3a\x2d\xb6\x1f\x45\x25\x4a\xb9\x65\xb5\xe4\x67\x2c\x4b\xfa\xa8\x6e\x33\x6c\x49\x27\x85\x52\x72\x9f\xb2\xda\x76\xff\xe5\x02\xec\x61\xe1\x69\x6c\x7f\xc9\xef\x19\xf7\xcc\x2a\x27\x75\xb2\x97\x00\xcb\x38\x42\x94\x06\x3a\x17\xfe\xd4\xfc\x63\x5b\xc1\x32\x82\xa9\x0d\xad\x0c\x00\xaa\xdb\xcd\x56\x9f\x15\x6a\x85\x4f\x8b\xa9\xe7\xd6\x07\xd2\x0f\x2e\x9e\x53\x37\x98\x11\x61\xd8\x04\x64\x46\x68\xd0\x64\xfa\x63\xdc\xeb\x9f\x58\x01\x35\x3d\x0a\xb9\xf4\x1d\x1d\x8b\xdc\x76\xc1\x3a\xb2\xf0\x23\xea\x01\xad\xbc\x4c\x81\x68\xd9\x39\xe9\x8f\x64\xfd\x89\x19\x38\x4a\xbe\x76\x70\x92\x63\xc0\xcd\x7c\x3e\xfa\xdc\x28\x01\xcc\x4a\xbd\x80\xa0\x9b\xb3\xed\x6b\xb7\x8c\xd6\x20\x96\x9c\xd3\x5c\x6a\x3a\x5d\x01\x48\x5e\xad\x4c\x45\xeb\xb6\xac\x6a\x83\x21\x2a\x7c\x76\x67\x54\x27\xb2\x1d\xa8\xa7\xa5\x04\x7b\x30\xa6\x10\x0c\xda\x02\x47\x6c\x18\x6e\x6c\xe4\x0d\x27\x68\xa9\x42\xc9\xf8\x73\x05\xe9\xd3\x63\xb5\x24\xc0\x09\x4a\x9e\x2e\x29\xf5\x85\x89\x4c\x0a\xdb\xfc\xd6\x06\x90\xfc\x7f\xb0\xa9\xc7\x17\xcf\x43\xb4\x84\xfd\x45\x15\x1b\x13\x04\x16\x9c\x26\x92\x1d\xb2\x27\x6e\xc0\x5a\xd2\x2a\xd1\x66\x85\x4f\xd2\xf9\x40\x85\x77\x8c\x47\x0d\xc4\x52\xe5\xcf\xa4\xae\xe0\x4f\xac\xb7\x70\x52\x6e\x1f\x24\x8d\x3d\x15\xc2\x72\x80\xfd\xfa\x1f\xd2\xc1\x04\x4b\xcb\xc8\x81\xc3\xd9\x98\x15\xc9\x7f\xbe\xa4\x61\x10\xbe\x02\xda\xb7\x74\xf3\xa6\x10\xe5\x80\x2a\xbf\x36\xa4\x98\x75\xc6\x82\x63\x8e\x0a\xe4\xcc\x82\x77\xc5\xe9\xaa\x73\x07\x44\x5e\x6b\xbc\xbe\x54\x9e\xec\x2a\x45\xb1\x59\x7f\x74\x47\x10\x7b\x62\xe2\xce\xe0\xa5\xfc\x51\xbe\xae\x3e\x1f\xe9\xbe\xfb\x18\x85\xd9\xb3\x0f\x9b\x4f\x1f\x56\x20\x6d\xee\x0d\x67\x77\x9c\x57\xf4\x84\xc8\xc3\xc8\x99\xa5\x15\xa9\xd1\xc1\x0f\x60\x59\x84\x0c\x1c\x73\xd3\xf0\x5b\xcb\x88\x59\x0c\x52\xf7\xda\x39\x18\x38\xdc\x2e\x73\x22\x8f\x09\x81\xc2\x89\xa4\xc2\x7f\x0c\x75\x7f\xaf\x7b\x3b\x89\x14\x6e\x33\xda\xfa\x49\x0d\x9e\x0f\x92\x75\xb0\xcf\xa6\xa7\x71\x0a\x73\x83\x14\x59\x59\x5b\xf7\x32\x11\x2b\x62\xfc\x86\x4c\xa4\xc8\x29\x78\x4a\x3f\x16\xee\xc4\xe1\x8f\x93\x69\x18\xa7\xb9\x89\x16\x69\xe9\x33\x22\x3f\x74\x5f\xda\x56\x2b\xc0\xa4\xe6\x1e\x3d\x14\xea\x45\xdf\xc3\x27\xe2\xfc\x0c\xdf\xe6\xf2\xf9\x75\x46\xc9\x0f\xce\x82\xf5\x22\x29\x14\x80\x11\x1a\x1e\x6b\x93\x88\x27\x2c\x0b\xe2\x8d\x20\xed\x84\xbb\x84\xd4\x9b\xc1\x99\xcd\x59\x99\x48\xb8\xf2\x03\x9d\x07\x82\x7a\x3f\x40\x75\xd3\xa6\x7e\xe5\x72\xa0\x13\x79\xa3\x62\x13\xfe\x11\x6e\x76\x8b\x41\x14\xe8\xa4\xb3\x13\x4c\x38\x18\x96\x07\x72\xd7\x27\xb0\xca\x6f\x7c\x99\x7c\xa9\x98\x43\xb7\xeb\x02\xff\xc0\x13\x97\x1c\xbe\x0e\x6e\x60\xd4\x97\x73\xf1\xe8\xc0\xb3\x06\x06\x13\x1c\xb1\x0c\x3e\x04"}, +{{0x84,0x36,0x44,0x78,0xec,0x94,0xbd,0x25,0xc4,0xbd,0xb8,0x2d,0x29,0x62,0x29,0xe6,0xda,0xce,0x2b,0x13,0x59,0xd6,0xd2,0x1b,0xe2,0xb3,0xaf,0xcd,0x7b,0xda,0x19,0xc7,},{0xa1,0x81,0x4f,0x8c,0xe0,0xfc,0x3b,0x23,0x60,0x93,0xa5,0x0f,0x46,0x8c,0x13,0x16,0x21,0x1f,0xe6,0xc5,0x2e,0x23,0x45,0xd9,0xf0,0x76,0x6b,0x36,0x88,0xa0,0x3c,0xad,},{0xb4,0xc2,0x32,0x1a,0xde,0x3c,0x19,0xed,0x4e,0xd4,0xc6,0x39,0xd5,0xa4,0xd6,0xf2,0xbe,0x8e,0x2f,0xb1,0x3b,0xb7,0xbd,0x62,0x5a,0xd6,0xdc,0x87,0xe2,0xc2,0x0f,0x93,0xad,0x6b,0xe7,0xb7,0xe4,0x27,0x11,0xa8,0x78,0xdb,0x9d,0x76,0x05,0x4b,0xfd,0x7b,0xc2,0x5e,0x37,0x74,0xa9,0x3d,0xa1,0x54,0x3c,0x9b,0x4f,0x66,0x33,0xb0,0xbe,0x09,},"\x7b\xb7\x29\x3d\xe5\x5f\x05\x8f\xb2\xec\x22\xb6\x87\x26\x05\x43\xdc\xaa\x90\xf1\x40\xb9\xf4\x5e\xdd\xd4\xbc\x22\xe4\x09\x77\xe0\x0e\xd3\x3c\xd1\xef\x1b\xba\x13\xc1\xd0\x99\x08\x59\x00\x55\x69\xa8\x07\x67\xe4\x86\x4a\x2c\xd2\x88\xc8\x13\x93\xe0\x4a\xd9\x71\x78\x2e\x2b\xc4\x93\x10\x8c\xbe\x80\xda\xcf\x0b\x7b\x9c\xd5\x34\x98\x84\x07\xa4\xf9\x32\x7e\xc8\xe9\xc4\x04\x32\x84\xef\x6e\xe5\xa2\x6a\x5b\x41\x77\x65\xd3\xea\xbb\x48\xa0\x07\xe7\xc7\xf3\x29\x87\xd7\x0a\x13\x9a\xc4\x16\x78\xcd\xf7\xa5\x5c\xb8\x0c\xf9\xdb\x5e\xaa\x45\xf3\xde\x0f\xbf\xba\xdf\xfc\x40\x99\x63\x70\xe4\x8b\x1f\xf5\xed\xd9\x79\x40\xe7\x50\x79\x21\x64\x83\x6a\x4a\x5a\xc2\xe3\xff\x53\xe4\x8a\x1e\x55\x6d\xb9\xad\x0c\x5c\x0b\x94\x4f\x4a\xee\x51\x9a\x2b\x0a\x88\xbb\x1c\x1f\xc7\x45\x45\x24\xcd\x57\xaa\x53\x50\x98\x62\x43\xd3\x4f\xc5\x8e\x24\xe8\x19\xec\x0b\x85\x45\xd8\xdf\xcf\x6b\x20\x31\x14\x41\xd3\xa3\x5d\x3e\x71\xb3\xe3\xec\xd7\x88\x4d\xda\x84\x33\xa4\x05\xe3\xd9\x96\x90\x00\xc8\x20\xa8\x9b\x95\xd1\x97\x84\x1d\x98\xae\x73\x4a\x2e\x81\xda\xf6\xa7\xdc\xf5\x6c\xb2\xfc\x26\xf2\x16\x5a\x5f\x42\xb8\x6c\x7e\x9e\x5b\x11\x16\x17\x00\xa1\xab\x98\x31\xf3\xfa\xe5\x8e\x14\x20\x8b\xe1\xbf\x33\xb5\x8e\xcc\xe8\x1b\x0c\x6b\x7e\x02\xf8\x8a\xdf\x9a\xb0\x30\x26\x3e\x2c\xc9\xb6\xe3\x3e\xbc\xa3\xf4\x95\x49\x2e\x32\xbf\xe3\x72\x53\x7d\xe6\xc6\xb8\x76\x44\x82\x8f\x74\x94\x2a\x02\xb0\x07\xf1\x4c\x3f\xc5\xdb\xde\x76\x33\x3d\x36\xd0\x76\x31\xb7\xa9\x92\x4f\x71\x75\x50\x04\x06\x97\x92\x3f\xa7\xb9\x54\x6b\xfb\x02\x17\x02\x4e\xa3\xf2\x52\xb5\x15\xb5\xd6\x4a\x62\xc4\x8e\x02\x7c\xef\x67\x50\xbe\xda\x49\xa0\x24\x47\x03\x9b\x25\x0a\x0b\xda\x07\xdc\x06\x24\x91\xa6\x62\xe2\x68\x74\xc8\xd0\x0f\x80\xe6\xcf\xc8\xb3\x0f\x2c\x3b\xf7\x72\x0b\x57\xf2\x61\x5f\xc4\x78\xfe\xfa\xa6\xd3\x17\x05\xb4\x3c\x5a\x54\xf7\x58\x66\x6b\x30\x2a\x8d\x34\x95\x31\x31\x94\x1b\x79\x57\x73\x04\x76\x79\x4d\x0b\xd9\xd2\xdf\xa7\x2f\xd2\x03\xf2\x2d\xf5\xec\x6b\xba\xac\xe8\xb9\x39\x4b\xeb\xda\xea\xa5\x61\x46\x10\x11\xb4\xfc\xa6\x18\x5c\x9a\x38\x28\x3f\x54\x03\xfd\xac\x32\x6d\x1f\x73\x4c\x6a\x5d\xed\x67\x24\xd9\xf3\x84\xae\xbd\x6c\xab\xfc\xbe\xc1\x2a\xba\xb9\x82\x0d\x08\x07\x32\x51\x5e\x05\x00\xcf\x5d\x3e\x2f\x9e\xf8\x0a\x4d\x76\x46\xa7\xda\x9e\xff\x41\x0f\x50\x7c\x69\x87\x3b\x32\xd5\x40\xec\x32\xb2\x83\xef\x31\x79\xa4\xc6\x32\xb3\x66\x57\x6d\xff\x05\x8f\xaf\x8c\x8c\x70\xbc\x69\xbe\x80\x89\x82\xec\x14\x97\xae\x89\x11\xb0\x01\x65\xa6\x66\x95\xf4\xd3\xb9\x87\xe7\x39\x0b\x5c\xf8\x78\xe3\x5e\x67\x65\x41\x28\x5e\x4e\x13\xdf\xae\xb2\xf3\x68\xcb\x51\x1b\x77\x8b\x10\x6a\x42\x87\x78\xa1\xb8\xf2\xa7\xd2\xe0\x93\x51\x9b\xc9\xb5\x18\x8e\x38\xc6\x79\x3e\x96\xbd\x0d\x30\xe2\xa3\xdb\x9e\xe1\x46\x8c\x3d\xc8\x7c\xc3\x65\xc8\x10\xf9\xdb\xdf\x01\xa4\xb5\x14\x21\xf6\xfc\x8d\xfd\xa3\xa1\x6e\x2d\xa7\xca\x71\x59\xb6\x86\xa5\xe1\x67\x33\x89\x37\x88\x2f\xf7\x15\xd3\xe7\x50\xd9\x58\xfc\x9e\x4b\x1f\x05\x53\x12\x92\x99\xaa\x84\x30\x18\x3e\x50\x6c\xd7\xf2\xb2\x79\x07\x6e\x0e\x1c\xca\x97\x49\xcf\x12\x3c\xe5\x07\xfe\x07\xdd\xbb\xc4\xdc\xca\x6c\xdb\x9e\xf1\xb8\x33\xf6\x1d\x4b\xff\x00\xbe\xc0\x12\x15\x8f\x43\x2c\xeb\x75\xb4\xf2\xed\xb1\xbb\x84\xe5\xeb\xb9\x25\x9e\x09\xf9\x62\x5c\xe3"}, +{{0x00,0xdb,0x37,0xad,0x2a,0x19,0x5f,0x08,0xa0,0x84,0x40,0xd0,0x59,0x25,0x9e,0x53,0x9f,0xeb,0x40,0xb4,0x74,0x92,0x82,0x55,0xe7,0xc9,0x4e,0xbc,0x3b,0x05,0x03,0x8c,},{0x04,0xf8,0x8b,0xf6,0x39,0xe0,0xf7,0x1a,0x57,0xd0,0xd0,0xaf,0xff,0x5f,0xe9,0x7d,0xde,0x38,0x09,0xff,0x28,0xec,0x68,0xeb,0x6f,0xc4,0x23,0xf4,0xfa,0xff,0x43,0x90,},{0xf4,0xd1,0xc8,0x0f,0x5e,0x7b,0x91,0xc5,0xc7,0xa8,0x2a,0x68,0x2d,0x49,0xba,0x6f,0xb1,0x9d,0x40,0x0a,0x29,0x97,0x48,0xa0,0xc9,0x69,0xbb,0x99,0x81,0x69,0x98,0xbe,0x63,0x4e,0x84,0xda,0x78,0x58,0x1b,0x06,0xe3,0x47,0x0e,0xfe,0xc3,0x98,0x04,0xfe,0xd9,0x3d,0x29,0x73,0x9f,0x04,0x39,0xa8,0x09,0x5a,0xc4,0x0d,0x9d,0x38,0x5e,0x04,},"\x5a\x94\xf7\x29\xd3\x0d\xd8\xaa\xe2\xa5\xc8\xc2\x85\x47\xbf\x45\x06\x29\x5d\xc6\x1b\xfe\xad\x97\x27\x74\x60\x82\xd4\x3b\x0f\x81\x14\xc8\xc1\x8c\x5e\xda\xf2\xfe\xc7\xca\xe8\x19\x35\x63\x38\xf0\xbf\x11\x5a\x17\xb0\x38\xac\xfd\x7c\x96\xba\x62\x62\xca\xbd\x57\x10\xfc\x0e\xfb\x43\xd1\x3d\xf4\x06\x5b\xec\xbf\x1b\x9e\x27\x9c\x03\xec\x9b\xbf\xed\x54\xd9\xa1\x3f\xe0\x6a\x55\xa3\xbd\x05\xc8\x07\x85\x8b\x41\xe1\x8d\xbd\xe1\x3b\x09\x07\xd4\x03\x41\x32\x26\x2d\x9c\x2f\x4d\x2d\x37\x6e\x16\x09\xad\x28\x0d\xe2\x0b\xa7\x09\x84\x4d\xbd\x12\x95\x02\x57\xf1\xb0\x7e\xf8\xcc\x33\x37\xc0\x1a\x70\x26\x93\xfb\x4d\x92\xd0\x47\xe6\x98\xc3\xa6\xdd\x46\xc4\xa9\x2a\x10\xd4\xc7\x80\xe5\x2e\x50\x25\xe0\x9d\x56\x53\x5d\x7e\xeb\x9f\xe7\xf0\x33\xe6\xe9\x26\x0a\x68\xf9\xd5\x4b\x6f\x37\xcc\x06\x96\x56\xe3\xbc\xee\x06\x92\x2b\x34\x96\x81\xa8\xe7\x75\x1c\xde\xcb\xe1\xec\xb6\x63\xfb\xc6\xf7\xc8\x61\xf8\x53\xdc\x31\x0f\x33\xde\xfa\x98\xee\x34\x3a\x68\x63\x2e\xc2\x2c\xaf\xec\xb7\xf3\x21\x2f\x81\xe7\x0b\x71\x84\x3b\x9f\xe8\xc8\x6a\x68\xb5\xc8\x6f\x03\x22\xd3\x48\xa7\x6d\xa7\xf1\xba\x0c\xa3\xcd\x7b\x6f\xd1\x5f\xf8\x92\x92\xb3\xf6\x36\xcd\x08\xcf\x62\x5c\x74\xd5\x10\x2c\xab\xb5\x71\xa3\xdb\xa8\x6a\x1c\x92\xf4\x1c\x72\x03\xb4\x49\x42\xf5\xa2\x46\x25\xac\x37\xd7\x7e\x49\xa5\x7f\x11\x82\x38\x69\x9d\x80\x7c\x25\x0d\x5b\xf4\x6f\x7a\x3c\xec\x57\x79\xa6\xe5\xae\x1a\x6c\xa1\x60\xcf\xf3\x7f\xb3\xb7\x83\x88\xfe\x9c\x03\x0c\x40\xe7\x15\x46\x01\x08\x1a\x51\x7f\xc0\xaa\x18\x02\xcd\x3b\x84\x5b\x94\x6e\xfe\x94\xaa\x8b\x9e\x03\xf6\x8a\x80\xde\xd0\xdf\xbf\xad\x4d\xae\xe4\x0f\xa8\x38\xc1\x33\x84\x1a\xe8\xa3\xce\x0d\x79\xfa\x8a\x2b\x94\x34\xba\xc5\xe1\xda\x6e\x0c\x71\x93\xe8\xde\xa4\x35\xa0\x3a\x85\xf7\x61\x84\xf7\xeb\xe2\xaa\x74\x9b\xe9\x41\x31\x04\xa1\x78\x68\x9b\xa6\xd2\x7e\x94\xfc\xcf\x61\xeb\x3a\xba\x0e\x6a\x5a\x63\xaf\x0c\xa8\xf0\x5a\x35\xcb\x63\x70\x51\x94\xe4\x4d\x92\x93\xde\x39\x29\xb0\xd9\x2b\xe6\xf8\xe6\x27\xc3\x50\xa8\x3f\xc9\x00\x0a\xa9\x5b\x93\x82\x0b\xe9\x79\x5c\x80\xb5\x66\x2c\xd7\xb3\x48\x22\x32\x80\x61\x35\x6d\xc5\x80\x57\x8d\x1a\x35\xb1\x01\x40\xdc\xd2\x48\xe4\x85\x31\x04\xd2\xc5\xb2\xc1\x3f\xf6\x83\xdd\x5c\x30\x79\x4b\xe4\xa7\x68\x58\xaf\x1c\x0d\x9a\xf3\x47\xce\x1d\xcd\x97\x2e\xe4\x9a\xac\x12\xbb\xcd\x89\x9c\x93\x29\x87\x1d\x3e\x7a\x06\x83\xd1\x75\x77\x9a\xfe\x35\xf2\x6a\x2d\x24\x8f\xd7\x80\xea\x85\x1d\xc4\xba\x6d\x21\xf8\xa1\x71\xaa\x6c\xb8\x69\x7d\x9d\x11\x21\x61\x54\x03\x07\xcd\x54\xf9\x31\x77\x5d\x70\xb3\x3d\x3b\x6d\xe1\x09\x1f\xc1\x75\x05\x31\xc0\x8f\xa7\x0f\x7b\xe3\x8a\xa1\x10\xd6\x74\x6b\xb5\x65\xdb\x7b\x47\x0f\x90\x08\x50\xfb\xbf\x1c\x66\x2f\xd6\x13\xe4\xf3\xa5\x68\x95\x49\xe3\x10\x7e\x9b\x0f\x17\xde\xf7\xa5\xbd\x7f\xd7\x59\x6c\x4d\x04\xc7\xf4\x8c\x77\x9f\xc3\x5e\x09\x33\x5e\x1d\xf7\x84\x08\x4e\x55\xd8\x55\x1d\x1f\xf4\x9d\xe5\xb3\x11\xcd\x35\x0f\x34\x7a\x0b\xd2\x86\x3a\x2a\x30\xe6\xea\x18\x3a\xd2\xe3\xee\xde\xbc\x18\xdd\x28\xc6\xa5\x96\xe6\x93\xdc\x33\x89\xf7\xd9\x0b\x71\x3e\x3a\x85\xa6\x25\x16\x30\x5a\x70\x66\x7f\xc1\xfb\x3c\xb1\x0e\x8a\x95\x57\x50\x27\x39\x43\xc5\x68\xe1\x07\x69\xce\xf7\x81\x99\xdf\x44\x50\xdb\xc4\x90\xfe\xf1\xb3\x04\xb0\x52\x22\x1b\x2d\xb9\xc4\x4f\xe0\x03\x45"}, +{{0x6c,0xa1,0xa1,0x48,0x2a,0x07,0xf2,0xa6,0xc5,0x7f,0x04,0x11,0x97,0xb3,0x4a,0x51,0x19,0xe6,0x89,0x03,0xcf,0x6d,0xfb,0x51,0x71,0x1d,0x95,0x50,0x97,0x31,0x63,0xc0,},{0x80,0x34,0xa5,0x5e,0x3b,0x6e,0xd7,0x99,0xf4,0x9e,0x2e,0x70,0x3a,0x81,0xf4,0xac,0x02,0x57,0x3c,0x44,0x5d,0x76,0x5e,0x30,0x69,0xbe,0x42,0xf0,0x9c,0xbd,0x18,0xad,},{0xdd,0x9b,0xdb,0xad,0xd9,0xfd,0xc8,0x1c,0xe2,0x30,0x28,0x8c,0x4a,0x06,0x8d,0xf0,0x7e,0x18,0xb4,0xc7,0xcc,0x51,0xc0,0xca,0x48,0x11,0xdf,0xbd,0x04,0x76,0x5c,0x56,0xbc,0x88,0x32,0x40,0xe4,0x6e,0x3a,0x42,0xc0,0x1d,0x8d,0x24,0x24,0xfb,0xc3,0x32,0xb7,0xc5,0xa1,0x7b,0xce,0xb1,0xf6,0xe8,0xda,0xd0,0xbf,0xe5,0x62,0xca,0xd3,0x02,},"\x08\xfd\x84\x87\x50\x3c\x3f\x32\x96\xb6\xf1\xb6\x4d\x6e\x85\x90\x6f\xd5\x98\x6c\xf9\xc5\xd9\xfa\x8a\x59\xd9\x2f\x44\xe6\x47\x0a\xf3\x4b\xcd\xef\x33\x6f\xfd\xc8\x64\x56\xec\x7a\x7b\x57\x61\xf1\xad\xea\x02\x73\x26\x63\x0e\x68\xab\xc6\xb8\xcd\x5d\xdf\x40\xb6\x41\xa2\x59\xad\x02\x43\x21\xbf\x3e\xf9\x8e\x76\x32\x79\x71\x49\xc4\x92\xd5\x35\x94\x75\x2c\x55\x0d\xfb\xc4\xfa\x6b\xf4\x71\x76\xf4\x23\xa2\x70\x56\x93\x94\x7a\xa9\x0d\x68\xdd\xc8\xef\xb6\xcb\x9d\xbe\xca\xfd\x28\x30\xd0\x4f\xd9\x3b\x1e\x9e\x7c\x12\xb9\x3e\x0d\x0f\x3e\x26\x34\x90\x0f\x25\x86\x0d\xda\xdb\xae\xce\x17\x80\xff\x2d\x3f\x3d\x9f\xb8\x38\xfd\x0d\x5d\x66\xf8\xaf\xb3\x05\xff\x1a\x1a\xed\xca\x2b\x97\x4b\x63\xe4\x3f\x5b\x3c\xc9\xdf\xed\x1b\xcf\x11\x99\x91\x76\xed\x95\x85\xac\x82\x9b\xc6\x79\x4e\xf3\xac\xd8\x72\xe8\xd2\xe9\x26\x08\xb3\x20\xf8\x94\x99\x6a\x56\x2e\x1e\xb1\x77\xe2\x1b\xe5\x7c\x22\xc4\x1e\xc2\x59\xa3\xdf\xf9\xc7\xc9\x49\x1d\xb8\x38\xd7\x6c\xf9\xb0\x38\x31\x11\x59\x8e\x35\x7f\x44\xba\xbe\xbf\x12\x1b\xdb\x24\xee\x9d\x55\x7b\x7d\x5a\xf4\x91\xa0\xa0\x36\x5c\x90\x36\x1f\xe4\xf7\xe3\xd1\x3a\x17\xda\x3a\x39\xfd\x43\xf6\x90\xdf\xb0\xb2\xd8\x60\xca\xb4\x19\xf7\x75\xab\x71\x52\xcd\xc8\xf2\xaf\xdc\x50\xe8\xd5\xda\x5d\xa0\x17\x06\xee\xa2\xa2\xff\xad\x4b\xab\xee\x8b\x03\xda\x33\x6a\x4d\x84\x3d\x9d\x7e\x0a\x93\xf3\x6a\x92\xe6\x61\x0a\x36\x8b\x63\x13\x3f\x05\xa3\xfd\xc5\x5e\x3e\x1a\x44\x0b\x0f\x87\xa5\x33\x64\xc1\xd3\x72\x42\xc5\x7a\x10\x9e\x6d\xf6\x93\x45\xb0\x1c\x21\xc1\x08\x9e\x79\x0a\x66\xf4\xf3\x38\x0d\x3b\x76\xff\xb4\x20\xdf\xe1\xe6\x20\x0e\xac\xe5\x79\x26\x5a\x42\x7f\xbd\x35\x55\x14\xef\x95\x3e\x1a\x6e\x96\x8e\x37\x02\x1b\x3c\x6a\x29\x0d\xcd\x02\x93\xda\x67\x68\xda\xd7\xc6\x63\x11\x63\x30\x51\xc0\xac\xcb\x0b\x91\x65\x46\x4d\xfd\xdf\xde\xd2\x3b\xd1\x3e\xf9\x08\x74\x4f\x9c\x21\x11\xdc\x15\x31\x42\xd2\xf1\x05\x34\xd8\x93\xfe\x0b\x54\x5f\xec\x53\xfd\xb3\xb3\x5b\x51\x83\x98\xb0\x2a\xb2\x17\x91\xfa\x97\x7e\x30\xcf\x4b\x40\x4e\x7a\x29\x9d\x37\x87\x10\x8b\x83\x6a\xa0\xd5\x9c\x11\x4f\x1f\x36\x71\x9a\x7a\xcf\x85\xac\x99\x4d\x9c\xb7\x23\x06\xf2\x58\xf7\x8a\xc0\xa3\xb6\xc0\x53\x43\xe0\xb7\xa9\xaa\x72\x6e\x52\x26\x7e\xdf\x97\xf4\x97\x2f\x76\x64\xf4\x37\x20\xad\x33\xce\x6e\x61\x54\x40\xe3\x65\x37\xcb\xc5\x69\xbd\x6f\xf9\x4f\xfd\xae\xa5\x1e\x06\x02\x9d\xae\x78\xc5\xb9\x15\xc5\x37\xca\xea\x6f\x15\x04\x14\x79\x79\xb8\xaa\xae\x0b\xcd\x96\x18\x43\x7e\xbe\xd0\xb5\x5e\xfa\xec\x32\x0e\x84\xc7\x59\x59\xa3\x7a\x26\x0a\x02\xd4\xef\x1b\xb6\x26\x41\x52\x0f\x1a\x03\xdd\xea\x8c\x4c\x1d\xe8\xd7\xfa\xc5\x8d\xa4\x08\xb0\xab\x47\x57\xa1\x35\xf1\xd0\x75\xc9\xf7\xc9\x9f\xb9\x9d\xb9\x42\x7c\xe9\xb0\xd6\x26\xcb\x1a\xc1\x89\xad\x86\x63\xd7\xa7\x14\xfb\x5c\xd1\x58\x5c\x3b\xf9\x9a\x0a\xa4\x6d\x76\x39\x78\xd0\xb1\x2d\x65\xc4\x38\xbb\xb7\x3f\xea\xa5\x1b\xa2\x6a\x45\x9e\x7b\xea\x25\x43\x94\x66\xc0\x86\x13\xe4\x25\x40\xc8\xc6\xd5\x43\x67\xf2\x21\xfc\xce\x0c\x5e\xb6\xaf\x2f\xaa\x18\x1e\xa2\x15\x21\x80\x9b\xe7\x56\x49\xcf\x8d\xee\x76\x71\xdb\x7f\x94\x8f\x34\x6c\xbd\x03\x02\xbf\x9a\x06\xea\xbc\x72\xe2\xe5\x12\xb3\xdf\x88\x5f\x6d\xaa\x39\x8f\x93\xe3\x6d\xae\x2d\x6a\x04\x47\x81\x21\xf9\x77\x87\xd4\xce\xdf\xf6\xdb\x09\xaa\xf1\x0f\x27\xb1"}, +{{0x27,0x84,0xdf,0x91,0xfe,0xa1,0xb2,0xd2,0x1d,0x71,0x3d,0xe2,0xed,0xc6,0x65,0x24,0x51,0xa0,0xc1,0x59,0x54,0xb8,0x65,0x60,0x62,0xea,0x1d,0xed,0xc2,0x44,0x5b,0x2a,},{0x95,0x56,0xdb,0x53,0x70,0xf8,0xfb,0x3c,0x74,0x78,0xde,0x03,0xd2,0x3d,0xf1,0xcd,0xa9,0x6f,0x27,0x40,0x11,0x8e,0xfd,0xd3,0xd1,0xa9,0xfa,0x4c,0x3b,0xfe,0x88,0x49,},{0x17,0xd1,0x71,0xd9,0x46,0xde,0x35,0x16,0x15,0x84,0x07,0xe1,0x32,0xcc,0x1a,0xce,0xca,0xef,0xd6,0xd0,0x92,0x11,0x2b,0xe6,0x53,0x99,0x95,0x23,0xe2,0x0b,0xd4,0x95,0xf7,0xb7,0xf6,0x00,0xe8,0xd5,0xa6,0x71,0x33,0x0d,0x32,0x69,0x3d,0x60,0x19,0xc0,0x8d,0x2d,0x00,0x3b,0x17,0x6e,0x63,0x19,0xc3,0x53,0x94,0x20,0x0e,0x02,0x7d,0x0e,},"\x2e\x3b\xc5\x4d\xf4\x16\x74\x1d\xbe\x79\x16\xad\x25\xf0\x4e\x48\xd5\xa9\xd7\x7a\x62\x3e\x57\xf9\xcd\x61\xec\xb4\x4f\x09\xf7\x68\x33\xeb\x2a\x3e\x9a\xb7\xaa\x89\xff\x5d\x2d\x56\x0c\x07\x17\x7d\x85\x4d\x7c\x49\xcb\xef\x49\x2b\x7f\x4f\x7e\x56\x7d\xe1\x27\x51\x24\xe1\x6c\xa4\xa7\x98\x01\x62\xfa\x0f\xd1\x62\xa8\xe5\xfd\x6f\x35\x61\x70\x07\x03\x4b\xce\xec\x57\xc8\xfa\xf7\x66\x4f\x4b\x3b\xaf\xfd\xea\x8d\x8f\xc2\xba\x22\xd5\x85\xe9\xe2\xd7\x39\xf5\xff\xc9\x9b\x4e\x0d\xbe\x9c\x36\x86\x54\x7e\xa0\x48\x15\xa5\x9c\x4a\x25\xb5\xf2\x39\x06\x68\xe4\x18\xba\x0f\xcb\xdf\x4c\x4a\x51\xf3\x39\x05\xc7\x4f\xbb\x83\x0a\x19\xf9\xbc\x86\x36\xdb\xaa\xff\x20\x99\x95\x44\x79\x96\xd2\xe5\xb1\xc3\x77\xb4\xcb\x87\xa4\xe1\xef\xe1\x2d\xe3\x4d\x33\x59\x9f\xf3\x97\xb7\x40\x17\xd7\x11\xed\xd3\xe7\x72\x15\x5b\xe5\xa4\x40\x6e\x74\xcb\xe2\x93\x1e\xf5\x13\x59\xaf\xd5\x1b\x5b\x1a\x7b\x3e\xa2\x2e\xe8\xed\xa8\x14\x76\xbc\xc1\x7e\xa7\x68\x0f\x6f\x31\x04\x70\x3b\x9f\x2a\x35\xcf\x26\x27\xeb\x74\x1d\x1a\x30\xaa\x4b\xee\xf6\x57\x9e\xc7\xd0\xb0\x7a\x4e\xf3\x2a\xbc\xb4\xd7\x56\x97\x0f\x70\xa3\x67\x8e\x17\xe6\xe5\x73\x18\x90\xae\xbc\x8c\x92\xb9\x56\xd4\xb3\xb5\xfe\x2a\xdf\xd7\x9b\x21\x1a\x18\x83\xdf\xc8\xc9\xa4\xb1\xb9\xc8\xc1\xbb\x26\x5e\x1f\x3d\xd3\x92\x44\x5e\xa5\x9b\x59\x0a\x01\x95\x51\xf8\x12\x18\x49\xf4\x35\xb3\xac\x1b\x29\x90\x2f\xc8\x39\x25\x54\x05\x6b\x93\x90\x3d\x5f\x26\x3b\x3d\x54\x08\x43\xd6\xaf\xa7\x5a\x2a\xd8\x30\x4b\x76\x90\xde\x99\xa7\x34\xc3\xd1\x30\xb6\x95\x47\xb1\x8b\x09\xe9\x8c\xbf\x25\x27\x30\xe4\xae\xdb\x6d\xc4\xb5\x8b\x22\x43\xfe\x55\xe8\x09\x39\xd3\x7b\x0a\x59\xd7\x22\x26\xd8\xa2\xcc\x51\x53\x09\x5e\x15\x99\x4a\xd6\x21\x95\xaa\x31\x0f\x2a\x64\x26\x67\x6b\x66\x1e\x47\xb9\xfc\xff\xfa\x04\xd6\xdc\x62\x5f\x29\xf4\x4c\x7c\xf6\x20\xb3\x78\xa6\x5d\x23\x83\x44\xb3\x80\x44\x8c\xd1\x19\xcc\x7f\x37\x3f\x62\xcd\xfa\xd6\x41\x49\x90\x63\x53\xf3\xa5\x41\x07\xc5\xdb\xa6\x5e\x3c\xc4\x94\xb0\x53\x1f\x4d\x64\x74\x93\x63\xf2\x30\x73\x8b\x2c\xfe\xed\x98\x35\x20\x22\x7d\xd5\xbc\x43\xbe\x59\xb3\x26\x8e\x28\x32\x16\xf6\xe9\xc7\x5e\x0c\x1c\x71\x27\x2e\x54\xfd\xb2\x9c\x78\x58\xd2\x87\xd1\xef\xa1\x91\x7b\xe3\x7c\x8e\xea\xb5\xe4\x4c\x3a\xd7\xb3\x6e\x8a\xc9\xf6\x69\x91\xeb\x82\xa5\x14\x8e\x59\x72\x03\x4a\xd0\x1c\x62\x61\x5a\x45\x15\x45\x79\xfa\x50\x86\x9e\x7b\xe9\x87\x6b\x56\x56\xea\xad\x2e\x43\x02\x5a\x62\xdd\x13\x4b\x61\x2d\x8f\x4d\x5e\xbc\xf8\x05\x6e\x19\x8b\x71\x34\x38\xe8\xe0\xe3\x47\xca\xfb\xfc\xb8\x9e\x39\x4a\xa3\x30\xd4\xc7\x88\xd4\x9c\x65\x8f\xcf\xc8\x0b\x3e\x00\x78\xf0\xe8\xe1\x9a\xa9\xb8\xfe\x8e\xb0\xba\xb9\x3d\xe7\x85\xd0\x43\xe0\xf4\x75\xae\xb6\x0d\x62\xe3\x8f\xb1\xf8\x38\x4a\x00\xb7\xa9\x02\xda\xee\x13\xd2\x13\x62\x69\xe5\x08\x01\xb8\x0a\x65\xb2\xf9\x13\xcf\xe3\xff\xb3\x65\xd9\xaa\x2f\xd1\x93\x72\xa0\xb0\x22\x56\x95\x44\x4e\x4b\xc5\x48\x71\xd1\x08\xe0\x9c\x7e\x1c\x2b\x42\xdc\xbb\xac\xce\x24\xea\x5b\xd5\xbf\x1f\xcf\x4a\xc6\x97\xa3\xfe\x09\xa5\x46\x77\xb7\xa8\xdc\x8d\x5e\xec\xb8\x6c\xc7\x92\xee\x9b\x6f\xea\x2d\xe1\x6a\x47\x32\x69\xfd\xc6\x5d\xbb\x73\xc2\x58\xc8\x21\x44\x04\x07\xc6\x42\xf7\xd3\xd3\xf5\xc7\x08\xd5\x53\x32\xda\x83\x43\x10\x6c\x19\xb2\x30\xa5\x14\x27\xf3\xb7\x71\x91\x6a\xe3\x68\x8b"}, +{{0x4b,0xb7,0x92,0x36,0xfa,0xda,0x31,0x44,0xb6,0x82,0x96,0x49,0x9b,0xa4,0x4a,0xe5,0x34,0x07,0x4c,0xa9,0x4d,0x4b,0x58,0x1e,0x5e,0xdc,0xff,0xfe,0x13,0xb3,0xad,0x19,},{0x0a,0x83,0x99,0xf1,0xe5,0xa4,0x23,0xdc,0xf7,0xb2,0x5b,0x2f,0xb0,0xac,0x9e,0x1e,0x95,0x48,0x14,0x8b,0xea,0x84,0xd0,0x21,0xe0,0x42,0x87,0x60,0xe0,0x5d,0x58,0xbf,},{0x69,0x8f,0xab,0x68,0x51,0x0d,0xb8,0x12,0x1a,0x46,0x5d,0xb7,0x7e,0x4f,0x8b,0x58,0x6a,0xee,0x89,0x58,0x16,0xe6,0x3b,0xbf,0x0b,0xeb,0x24,0x2d,0xb4,0xe8,0x4c,0x15,0x7f,0x4b,0xe2,0x01,0xae,0x65,0x64,0x51,0x7a,0x87,0x0d,0x17,0xf6,0x0c,0x85,0x83,0x70,0xc0,0x1c,0xca,0x17,0x18,0x9c,0xb4,0x18,0x9e,0x81,0x43,0x91,0xd1,0x50,0x0d,},"\xad\x81\xab\xf6\x93\x7a\x7a\xcd\x7f\x18\x37\xf0\x4d\x3f\x10\xe7\x08\xc6\x1a\x5f\xbe\xde\xee\x4d\xb7\x6e\x15\x98\x57\x03\x84\xe6\xef\xec\xe9\x7c\x92\x5d\x2e\x5c\x34\x88\xca\xb1\x0b\x5b\x52\xb8\xa5\x48\x6e\x99\xd8\xff\xe8\x6c\x19\x81\xa1\xf1\xd5\x32\xdc\xd4\xd4\x89\xe5\x54\x6d\x86\x65\x32\x98\xe7\xa5\xf9\x6e\x81\x44\x55\x2d\xda\x8a\x18\xe7\x5b\x5f\x73\x55\xb1\x35\x41\x62\x11\x06\xe4\x97\xe5\x1a\x56\xd8\x65\x9d\x19\x8f\xe1\x00\x37\xe2\x21\x28\xaf\xc2\x71\x4a\x2c\xb5\xa1\x2c\xc5\xdb\x09\x68\xa3\x43\xef\x91\x8e\x87\x69\xdd\x6a\x3e\x5b\x9e\x32\xaa\xb6\x6c\xb0\x23\x9e\xbe\x4c\x17\xf1\x82\x18\xe2\x52\xeb\xa6\x16\x2e\x97\x70\x49\xeb\xac\x0b\x38\x04\x8b\x3a\xaf\xb7\xd4\xd7\x22\x63\xe9\x21\x28\x99\xa3\xbf\xe0\xa6\x9c\x99\xe2\x2a\xc6\x1c\x5e\x96\x12\x45\x63\x03\xd9\x24\x58\xb5\xc5\x02\x91\x6c\x34\xa8\xee\x5c\xd9\xa5\x82\xa5\x25\x76\xb6\xdc\x9d\x7d\x4c\x64\x2f\x21\x29\x98\xbf\x33\x58\xd4\xa8\xc2\xea\x67\x68\x6e\x55\xd4\x89\xf6\xa7\x6e\x6b\x07\x0e\x6e\x99\x5a\x74\x53\x26\xc9\xaa\x63\x63\x0a\x00\x33\xad\x30\x72\x1a\xa6\x5f\xac\x60\x4a\x6e\x58\xc7\x50\x72\x1a\x56\xca\x67\x60\xc9\x41\x34\xd6\x11\xfa\xb4\xd3\x54\xe4\xf6\x6a\x29\x67\x7b\x1a\x66\x66\x01\xe9\xda\x79\xf2\x13\xf5\x82\x03\x74\x33\xc0\x7f\x94\xd5\xf0\xde\x6a\xa9\xfa\xa0\xb3\x2f\x7b\x02\x3f\xb9\xfc\x13\x5a\x26\xf9\x70\x52\xac\x80\xb3\x9b\x30\x6a\xed\x13\x92\x6c\x28\x54\x19\xa2\x9b\x20\xe2\x37\x0d\x8a\x09\x5b\x32\x25\x8f\xa9\x89\x34\x89\xee\x21\x08\x9c\x75\x2e\xc0\x62\xe1\x20\x35\x9e\x2f\x35\x15\x12\x82\x54\xc8\x09\x8c\xca\x65\xa9\x1a\x02\x2d\xd0\x57\xa2\xc2\xa1\xb6\xb8\x5d\x13\x7c\x3c\x96\x7d\xcb\x70\xaa\x17\xa2\xff\x4b\x37\x67\x8b\x38\x29\x02\xf0\xf9\x31\xee\x74\x3f\xc3\x98\xac\x1b\x8c\x10\x46\x98\x67\x30\x84\x79\xe4\x0d\x7f\x2f\x04\xa4\xb0\x4c\x44\x89\x15\x84\x88\xdd\xb7\xbe\xc5\xa4\x7f\x20\xff\x35\x6d\x99\xa1\xb3\xe9\xd0\xb7\xfe\x9b\x0a\xd9\x49\xf2\x98\x96\x0e\xfa\x4d\x97\x28\xf8\x10\x1c\xf5\x3d\xa3\xbf\xfd\xd9\x52\x4b\xf4\x40\xa5\x8b\x32\x73\x8d\x0b\x62\x93\xe8\x53\xf4\x66\xff\xd4\x2c\x56\x07\xac\x9e\x35\x3b\xa0\x3e\xfb\x57\x8c\xc9\x96\x3d\x8a\xaa\x9d\x2e\x26\x6d\x1d\x2a\xe9\x29\x6f\x30\xc9\xef\x44\xec\x69\x10\x30\xd5\x96\xa4\x01\xb6\xce\xe7\x2a\x54\x0e\xf3\xc4\x2e\xc0\x17\x42\x66\xba\x54\x01\xf3\x54\xad\xc8\xe2\x54\x04\x43\x7e\x88\x8b\x08\x28\x69\x39\xbe\xde\x30\x8a\xcd\x30\x32\x7e\xbf\xf0\x62\x70\x09\x7c\xc2\x94\xf0\xa0\xf3\x9f\x9a\xa3\xc6\x65\x85\xca\x47\xe6\x0c\x4b\x8e\xa3\x60\x89\xeb\x8a\x90\x88\xbb\x18\xb0\x34\x31\x35\xbb\x6a\x45\x6d\x2f\x6a\x3b\xf3\x90\x72\x3e\x78\xb4\x2c\x03\x7c\x2d\xe2\xe1\x43\x2c\xaa\xd3\xa5\x94\x02\x12\x94\xd4\x3f\x5b\x15\xa2\xe8\x19\xdc\x74\x8e\x45\x1d\xe4\x00\x68\xc8\xf0\x32\xf1\x3b\x47\x11\x37\x70\x12\xed\xcd\x4f\x11\xde\xc1\x11\x1b\x12\xeb\x6e\x1b\x00\x63\x38\x18\x70\x6d\x71\x32\xd9\x91\xce\x20\xdf\x3b\x92\x1d\xb2\x18\x5e\xe2\x5b\xb6\xf5\x82\x75\x76\xec\x01\xad\x89\x0f\x79\x79\x3b\xaa\x35\x8c\x2b\xbf\xb6\xfa\xad\x11\xd8\xcb\x0d\x0d\x2d\x2b\x29\x81\xfb\xf4\xe3\x72\x34\x9f\xc6\xa0\x1c\x36\x07\x7b\x59\x32\x5f\x70\x2b\x38\x00\x59\xa6\x5c\xf2\xf5\xea\x98\xd6\xbd\xc8\x15\x20\x53\xb8\x5b\x28\xc8\x1e\x41\x3c\x4c\xac\x7e\x22\x6c\x13\xdb\x32\x67\xd2\x18\x30\xf0\xe5\x43\x11\x02\x91\x70\x05"}, +{{0xaf,0xd7,0x65,0xe6,0xaa,0xc0,0x14,0x6d,0x48,0x11,0xef,0x95,0x97,0xbc,0x3f,0x44,0x76,0x3f,0x03,0x37,0x8b,0x7b,0xe0,0x33,0xd6,0xe6,0x4c,0xa2,0x9d,0xec,0xae,0xf9,},{0x6b,0xb7,0x61,0x23,0xd9,0x25,0x89,0x22,0x68,0x6c,0x53,0xfb,0x69,0x17,0xb9,0xa4,0x59,0xca,0xbd,0x30,0xbe,0x8c,0x43,0x97,0x0d,0x80,0xf5,0x35,0x0c,0x2d,0x98,0xef,},{0x3d,0xc9,0x19,0x4d,0x50,0x81,0x14,0x19,0x04,0x9e,0xaa,0x07,0xb6,0x55,0xb7,0xd4,0x06,0x4b,0xcb,0x0e,0x7f,0xb5,0xf9,0xe5,0x32,0x6b,0x5f,0xc8,0x56,0xfc,0x0a,0xb8,0x70,0x59,0x73,0xae,0x10,0x01,0xdf,0x55,0x37,0x39,0x77,0xdd,0xe2,0xd9,0xb8,0x10,0x79,0x55,0x14,0x14,0xad,0xc7,0x1c,0xc8,0x52,0xd4,0x99,0xb0,0xcf,0x82,0x4f,0x07,},"\x18\x3b\x10\x92\xc7\x90\x4e\x47\xa1\x42\x03\x17\xa2\x5d\x0f\x59\x11\x0a\xa8\x4d\x6b\x34\x19\xad\x45\x68\x65\xc4\x3b\x29\xe9\xd1\xda\xcf\x75\x5d\x9e\x5c\xf9\x4c\x55\x91\xd5\xd9\x12\xd0\x5c\xa9\xa5\x2d\x01\x5d\x6e\x8f\x5d\xc9\x4e\xfd\xce\x0d\x7c\xf5\x65\x12\x03\xb1\x1e\x54\x27\xa9\xf6\x79\x42\x9e\x00\x41\x4a\x48\xea\xb1\x3f\xd8\xe5\x8b\x87\xeb\xa3\x9d\x10\x25\xd6\xa1\x8b\x2c\xdc\xbe\x14\x74\x36\xdb\xf3\x8a\x1c\xe8\x64\x13\xae\x31\x87\x65\xe1\xbb\x1d\xf7\xe2\xb3\xbe\x97\xe9\x04\x08\xb1\x17\x17\xcf\x45\x9b\xcd\x0f\x3c\xac\x58\xb4\xa0\xd3\x5b\xff\xb5\x33\xe2\x0d\xf3\x74\x51\xc1\x14\x01\xce\x1d\xab\x02\x05\x5c\x7e\x08\xc5\xec\x46\x39\x0c\xd6\x17\xa6\xb5\xf2\x2f\x65\x18\x30\xa1\x11\x2a\x06\xed\xe4\xc4\x0a\xb7\x95\x78\x51\xd6\xc6\x6f\x17\x1c\xd1\x62\x41\x59\x09\x00\xb8\x52\xa3\xd0\x19\x95\x7b\xe1\xb7\xbb\x7a\xcb\x89\x23\xf2\xa3\x57\xc3\x26\x44\x56\xcf\xca\x9b\x42\x9d\x71\xfe\xcb\x7e\xda\xe3\x9b\x25\x2b\x4e\xb6\x10\xe8\xc7\x18\x83\x56\x99\x75\x4b\x8d\x41\x24\xb4\x92\x48\x8e\xde\x62\x61\x0c\xce\x44\xb5\x92\x18\x66\x3b\x6c\x96\x46\xa1\x4a\x84\x17\xed\xdb\xb6\xf4\xfb\xe5\xa4\xbb\xbb\x48\x2b\x37\xa4\x45\xe3\xc1\x6b\x65\xa1\x41\xcd\x3e\x12\xa5\xb2\xc0\x48\x1d\x61\x4d\x6d\x20\x84\x79\xb9\xb2\x09\xb8\x28\x85\x4d\xae\x0e\xa1\xed\xed\x50\x65\x55\xfe\x18\xe1\x85\x40\x05\xcf\x00\x1a\x80\x77\x08\x34\x98\xd2\x7f\xad\xf1\x18\x28\x6b\x53\xb8\x97\x4d\x69\xfa\x28\x25\xbe\x8c\xa3\xd6\x03\x6a\x92\xca\x52\xf9\x1d\xde\x6d\x5b\x1f\xfe\x28\x88\xf4\xd6\x07\x79\xfa\xd1\xfb\x41\xd8\xc0\x71\x40\x49\xaf\x68\x1b\x75\x5f\x2d\x42\x04\xee\xcd\x09\xe0\x77\x21\x0a\x48\xa1\x95\xe7\x2c\x80\xe1\x27\xc3\xd4\x87\x50\x95\xc6\x57\x0a\x1f\x78\x09\x59\x07\x52\x8c\xf7\x74\x6f\x31\xd9\x71\x11\xc6\xf4\xcb\x25\xb3\x74\x12\x99\xa7\x57\x48\x22\xd4\x6b\x6e\x79\xed\x23\xc2\xfe\x05\x7b\x3a\xc7\x29\x0b\x46\x0b\x16\x6e\xe9\x0a\x45\x56\x2e\xff\xed\xcc\x6b\xa8\xf4\x79\x5f\x73\x95\x81\x8d\xb5\x6b\x6e\xdd\x59\xca\x2c\xc4\xae\xa1\x84\x1f\xd9\x56\x5b\xec\xd6\xc0\x81\x04\xcd\xee\x26\xba\x9d\xe2\x00\x77\x3d\x09\x1b\xc7\x7a\x57\xc5\x47\xf1\xa6\xba\x0a\x2c\xd7\x17\xab\x32\x56\x1d\x74\x22\xea\x72\x35\xad\xb0\xcb\x36\xbf\x5c\xbd\xf8\x8f\xca\xe0\x66\x30\xa1\x56\x47\xd9\xa3\x57\xb4\xe0\xe5\x02\xd2\x73\xf3\x79\x6a\x51\xe0\xbc\x3f\xed\xbf\x7a\x1e\x64\xaa\xd7\x22\xaa\xc5\xfd\x02\x2f\xa7\x9d\x60\xfc\x70\x73\x25\xf1\x27\xeb\x1f\x03\x86\x87\x95\xcc\xdc\x0b\x4c\xb2\x6f\x20\x23\xd1\x52\x15\x3a\x97\xa2\x60\xbf\xf1\x17\x45\xd2\xe2\xcc\x0b\xf8\x60\xd4\xa6\xe3\x58\xa6\xd8\x17\x6d\x2a\xc1\x78\xa9\xae\x1a\x2d\xc7\x5e\x8b\x49\x04\x08\xff\x7c\xdf\x99\x13\x29\xf3\x3c\xb0\xc0\x5e\x1e\x35\x69\x25\x08\x7e\x0b\x8d\x96\xa5\x23\x51\xd1\xd1\x77\x68\xeb\x13\x4c\xdb\x21\xa1\x54\x6a\xae\xdc\xc6\x87\xdf\xa1\xb2\x2e\x92\xfb\x52\x41\xa8\x36\x77\xa1\x53\x44\x5b\x77\xd5\xe7\x03\x50\x8e\x2a\xbc\x58\x8a\x9f\x42\xe5\xbc\x71\x06\x73\xe4\xdd\x8a\xd7\x03\xfa\xb2\xd7\xdb\x1e\xb8\x42\x26\xc8\x9d\x87\x62\xa7\x09\xe3\xe9\x13\x8a\x1f\xa7\x90\xf2\x92\x9b\xff\x61\xbc\x1e\xa6\xe8\xaa\x1a\xd0\xe3\x88\x7d\x70\xa5\x6d\x4e\x65\x47\xfc\x60\x6a\x50\xd3\xbe\x3b\xd6\xdb\x03\x66\x3e\x00\xca\x9e\x4f\x24\xfe\x8c\xbf\xd7\xd8\xc9\x73\x8d\x63\x67\x55\x4b\x7b\x60\x1f\x74\x19\x0b\x59\x70\xa3\x98"}, +{{0xeb,0x34,0x71,0x45,0xf3,0x39,0xed,0xd8,0x02,0x78,0x5b,0x6f,0xbe,0xcd,0x5c,0xb8,0x08,0x89,0xac,0x7c,0xe4,0xeb,0xad,0x2f,0x67,0x07,0x67,0x65,0xdb,0x93,0x9b,0xca,},{0x99,0x4a,0x45,0x6e,0xad,0xa0,0x30,0x20,0x92,0x1c,0x3d,0x10,0x9c,0x13,0x5e,0xb9,0x61,0xfc,0xd4,0xa0,0xa4,0x00,0xba,0xfd,0x32,0xca,0x06,0x1b,0xbc,0x86,0x25,0x43,},{0xfd,0xbd,0x15,0xe1,0xe6,0x46,0x9d,0xf7,0x20,0xd9,0x55,0x2c,0xb5,0xdd,0x17,0x7b,0xcb,0xd2,0x92,0xfc,0xda,0x83,0xcd,0x93,0xc8,0x8d,0x01,0x14,0x91,0x2d,0xc8,0x70,0x31,0x09,0xba,0xc0,0xd4,0x59,0xac,0xe9,0x95,0x7d,0xf2,0x29,0x3a,0xc1,0x6d,0x40,0xd5,0x14,0x89,0x35,0x56,0x85,0x32,0x99,0xb9,0x7b,0x4f,0xd4,0x13,0x7a,0x3d,0x00,},"\x5b\x8b\x31\xba\xf8\x84\x83\xf0\x95\xb5\xd0\x2e\x17\xd8\xb7\xb4\x6c\xf4\x64\x60\xe6\x4c\x6b\x02\xc5\x6d\x8d\xaf\xe3\x48\x23\x70\x6c\xb5\xc1\x5f\x33\x8a\xd9\xb5\x65\x86\xa9\x49\x71\x1a\xa7\x31\x2c\xc9\x34\x50\xd2\xfb\x9a\xf4\x61\x3f\xc3\x07\x93\xa6\x31\xa5\x5c\x14\xe5\x3c\x0c\xb1\x5f\x06\x11\x63\x99\x39\x8c\x8d\xd6\x18\x76\xc6\x29\x15\xf9\xf9\xe4\xcd\xf8\xf7\xd8\x9a\xde\x12\x9e\x6d\xde\x7d\x63\x67\x1a\x18\x63\xf5\xda\x8f\x42\xea\x64\xc0\x79\xec\xb9\xa2\xc1\xb1\xdd\x9a\xda\xe6\x0e\x96\xb9\xcb\xbc\x76\x24\x53\x2a\xa1\x79\x75\xeb\xa1\x7a\x7a\xf0\x2b\xfb\x21\x9a\xac\x02\xb3\xd4\x30\x6c\xd3\x89\x33\xa8\x50\x60\xcd\x62\xab\x51\x3a\x39\x65\xb0\x91\x50\xa4\x88\xc9\x2b\xf7\xca\xb0\x48\x2e\xee\x56\x46\x3f\x01\x39\x00\x9b\x9f\xbb\x3f\xf4\xec\xae\x21\x1f\x42\x8b\x5b\xfb\x88\x76\xf0\x04\x98\x3b\x90\xc4\x47\x84\x6c\xa4\xb7\x45\x66\xe9\x79\xbc\x30\xc9\x5e\x99\xfa\xab\x69\xa3\xeb\xbf\xe4\xda\x60\x34\xc8\x2d\x63\xe9\xc5\xcc\xaf\x84\x86\xaf\x3b\x5e\x0d\x38\x14\x22\x93\x8b\x0c\x22\xf5\x16\x95\x5b\xdc\x36\x94\x31\x73\xf5\x83\x27\x08\xa3\x3c\xf5\x2d\x88\x75\xd9\x7f\xde\x58\x5b\x49\x17\xe4\xad\xec\xdd\x1e\x79\x85\x67\x62\x03\x3a\xf2\x2f\x25\x4b\x50\xce\x9d\x0c\x70\x0e\x77\xa7\x31\x55\x4f\xa0\x11\x3a\x0c\x66\x66\x83\xf3\xfd\xb1\x9e\x3a\x42\x63\x02\x23\x0b\x63\xe3\x3a\x78\x5e\xf2\x4a\x92\x89\x45\x5b\x3b\x8f\xc6\x18\xff\xfe\xf4\x9c\x2c\x6e\x48\xfd\x4b\xb4\x22\xf5\x04\x14\x9d\xe2\xb4\xc0\x35\x5c\x36\x34\x08\xe6\x6d\xa8\x1c\xbb\x58\x15\x52\xa4\x11\xe3\x64\xfe\x3e\x4c\xa9\x6d\x70\x72\xab\x07\x2e\x75\x68\xc1\x3d\x35\xe4\x1c\x78\x25\xa1\x3a\x5c\x68\xfb\x9f\xb5\x98\x8b\xbb\xfb\x9a\x0b\x51\x16\x57\x64\x66\x0c\xdf\xa2\x41\x1f\x3d\x42\x16\x5d\xa1\x87\xc5\x8e\xde\xf0\x10\x5a\x6d\xb1\x77\x42\x05\x43\xe9\x58\xd5\xd5\xe8\xa3\x71\xf7\x98\x70\x51\xc4\xe1\x78\x6d\x01\x8e\xb3\xd7\x32\xc2\x10\xa8\x61\xac\xaf\x67\x1b\xe9\x5b\xb6\x3f\xbc\x88\xbf\x8b\xe7\xbe\x53\x90\x93\x9c\xd9\xfb\x2a\xcf\x39\x81\xdd\xa6\x1b\x78\x7a\x7b\xbd\x78\x46\x8e\x1d\x32\xca\x46\xaf\x8f\xb3\x2a\x18\x46\x3c\x18\x0f\x52\x4b\xe1\xda\x91\x0d\xa5\x50\x8d\x42\xa0\x05\x17\x41\x22\x7c\x9b\x62\xde\x6d\x19\xb3\x3c\x0b\xd4\x80\x67\xb0\x35\x85\x9a\xd9\xbd\xc2\xdd\xd9\x7b\xef\xca\x31\xe6\x5a\x88\x6c\xfc\x75\x3a\xfc\x4f\xf2\xa7\x21\x2a\x89\xd3\x7c\x04\x6c\xdf\x39\x99\xc0\x51\xff\x13\x96\xbd\x99\xcb\x54\x94\x56\x39\xeb\x64\x62\xdb\x9e\xce\x84\x07\x7b\x0b\x3d\x6b\x3d\xf3\x95\x2d\xd3\x67\x56\xc6\xda\xb2\xab\xc2\x5a\x51\xbf\x32\xc1\xe9\xcd\xd0\xa7\x28\xa7\x98\x5f\x7b\x7e\x0d\x9c\x1a\x6f\x66\xce\x12\x16\x37\x3d\x25\x2d\xaf\x59\x58\xf2\xe8\x97\x3f\xd2\x68\xfa\xd0\xef\xe2\x51\xce\x76\xfe\x47\xbd\x0a\x4d\x0c\x4f\x10\x17\x94\x9d\x4c\x2b\x16\x71\x72\x18\xe1\x49\x15\x4e\xd6\xfb\xe5\x6f\x86\xd8\x2e\x19\xef\x0a\x91\x63\x19\x12\xf2\xa8\xf3\xde\xbb\x00\x76\x6b\x61\x77\x80\x2f\x4b\x2e\x79\xf6\xe7\xbf\xa9\xc6\x2c\xfa\x2f\x75\xcd\xb6\x04\x92\x63\x0a\x85\xc9\xb4\x31\x77\xd2\xdd\x9b\xa8\xd0\x54\x8a\xbe\x24\x92\x3a\xe8\x44\x3e\xea\xdc\xd0\xf5\x8a\x7b\x82\xdf\xf5\x0d\x88\x40\x03\x88\x9c\xb5\x60\xf7\xac\x53\xe7\x10\xa7\x55\x75\x36\x24\x64\xb1\xaa\x43\xd2\xa9\xb2\x2f\x2b\xd2\x16\x2d\x30\x2f\xaa\x74\x52\x34\x4c\xe7\xad\xe9\x98\x36\x87\xb6\xc6\x8e\xca\x47\xdd\xdb\x28\x9b\x15"}, +{{0x32,0x08,0x83,0x7d,0x15,0x54,0xb6,0x51,0x1a,0xdd,0xa0,0x9c,0xba,0xe5,0x65,0xda,0x78,0x43,0x9a,0x47,0x2a,0x5d,0x1b,0x10,0x7c,0xe0,0xa9,0xb1,0xd7,0x75,0x7d,0xb7,},{0x9b,0x52,0x5e,0x35,0x36,0x8a,0x92,0x1e,0x3a,0x2e,0x9a,0x35,0xa4,0xde,0x9e,0xa4,0xc4,0x36,0xca,0xba,0x27,0x12,0x3e,0x5c,0x36,0x9e,0x2a,0x6c,0xf5,0xc9,0x0a,0xb6,},{0x70,0x9d,0x1c,0xa9,0xca,0x2f,0x74,0x2a,0xb9,0xdd,0x0b,0x04,0x93,0x35,0xf5,0x44,0xcf,0xfb,0x2f,0x1a,0x36,0x93,0xd5,0xf5,0x3f,0x8b,0xa0,0x83,0xb9,0xb0,0xd8,0x6e,0x52,0x08,0xfa,0x8e,0x1e,0x81,0x56,0xc9,0xcc,0x22,0x42,0x77,0x5a,0xbb,0x7e,0x15,0xaf,0x30,0x85,0x86,0x8e,0xf4,0x57,0x63,0x4e,0x99,0x26,0xc4,0x04,0xec,0xf3,0x0f,},"\x43\x6a\x3c\x31\x76\x3f\x93\xd4\xd5\x46\xc6\xd1\xec\xfb\x7a\xe4\x59\x16\xaf\x75\x4f\x83\x9d\xcf\xe9\x6d\x6b\x69\xc6\x12\x14\xd0\x16\xfc\x84\x2f\x56\x46\x2a\x3f\x07\xf6\x61\xb2\xe2\x50\x5a\xcf\xaf\x48\x2a\x0b\x0f\x4f\x55\x01\xee\xc4\xb2\xd2\xd7\xd4\x44\x54\x4d\xe0\x00\xb9\x90\xf4\x36\x3d\x3f\x98\x3f\x5d\x4e\x09\x30\x97\x52\xff\x57\x9c\x73\x20\xc9\x15\x95\x1c\xc3\xa1\xe3\x23\x8c\x1b\xa7\xa1\x91\x30\xea\xbf\x6a\x37\xf5\xf0\xbc\x56\xe2\x52\x42\xf7\x52\x06\x1f\x3c\x63\xac\xad\x99\x2a\x75\x01\xe9\x67\xde\xb9\x25\xb3\x0e\xd1\x05\x43\x1e\x58\x21\x02\xfa\x4f\x30\x8c\x2f\x06\x83\x61\x2b\x56\x68\x6d\x52\xda\xed\x69\x43\xa7\x21\x9f\x3b\xee\xa2\xe0\xa2\x92\x42\xe8\x6d\x55\x62\xff\xab\x83\xb5\x6b\x26\x33\x26\x66\x4e\x02\x9e\x96\x1e\x70\x17\xd8\xe8\x9f\x5e\x3e\x1d\x10\xf5\x93\x28\x54\x55\x0c\xe6\xe5\xcd\x76\x97\x1f\xd2\x35\xcf\x9c\x00\x27\xd0\xcf\xed\x33\x15\xc2\xcb\xf1\x85\x08\x62\x4d\x8a\xcf\x04\x7f\x9b\x96\x8f\x90\x7d\x9e\x6f\x4c\xfa\x5e\x45\xc8\x0a\x27\x2c\x2d\xbb\x62\xc5\xd4\x19\x45\x80\xdf\xab\xed\xd8\x2c\xb4\xd7\x64\x92\x34\x4b\xe9\x6c\xcf\x5d\xaa\xf6\x1e\x6b\x2b\x55\xef\xdb\x3f\x65\x21\x0a\x3d\x6e\x1f\x36\x98\x87\xca\x0e\xa0\xd5\x8c\x3d\x14\x6a\xe3\xcf\x9b\x00\x00\x76\x88\x41\x15\xfa\x51\xb5\xfd\x66\xbe\xc0\xcc\xbf\x0d\x29\x20\x19\x6a\x7d\x7a\x38\x44\x5f\xbe\xd2\x2d\xfc\x75\x64\xdc\x56\xf6\x0d\x6e\x29\xe5\x92\x48\x53\x74\xc6\xbd\x1e\x5b\x15\x93\x1b\x69\xca\x6e\xe6\xb3\xaa\x25\x25\xc2\x35\x85\xf0\x92\x9f\x31\xcb\xd1\x1f\xb1\xa5\x33\x02\x16\xb9\x0a\xe5\xa6\x56\xdf\x7a\x07\x4c\xec\x64\xe5\x98\x18\x4f\x50\x3f\xb2\x3c\xc0\x5e\x65\xda\x9a\xe7\xe8\x44\x1f\x40\xe2\xdc\x26\xb8\xb5\x6d\x2c\xb5\x23\xa7\xc6\x35\xdc\x08\x47\xd1\xcd\x49\x8a\xbf\x75\x6f\x5a\x13\xea\x14\xf8\xfa\xb2\xc4\x10\xb1\xa4\x70\xf4\x9a\xa8\xdc\xa4\xac\x02\x56\xb1\x18\x00\xde\x0d\xd0\xec\x42\xb1\x42\xc5\x61\x12\x8d\x35\x7e\x78\x3b\x12\xf6\x1c\x66\x8f\x5e\x6e\x06\xb7\xb4\x8b\x7b\x22\x54\xde\x5b\xdc\x18\x04\xb7\x23\xd5\xfd\x6a\x0f\x4b\xc7\xc5\x9e\x7c\x50\x54\x18\x26\x13\xbb\xd2\xfa\x92\xb4\xc1\xda\x16\xbc\x8c\x97\xe1\x6b\xcb\x0d\xbf\x8c\x92\xb7\x48\x99\xb3\x7f\x31\x87\x57\x14\x0b\x6c\x4f\xd5\x35\xe2\xe1\xe0\x57\x0a\x50\x81\x8c\xf7\x8f\xb9\x88\xe1\xf4\xce\x40\xe7\x6e\x8f\xe3\xd6\x97\xd7\xa4\x58\x50\xf2\x93\xce\x17\x0f\xd8\xab\x07\xcf\x15\x34\xea\x5f\xfa\xd3\x4f\x6f\xcf\xa4\x2d\x0d\x21\xa9\x1d\xfb\xfe\x05\x97\xc7\x3f\xd9\xb9\x76\x76\x14\xeb\xdf\xd0\x2c\x3a\xc0\xc4\x9a\xd1\x0c\x94\xbe\x59\x69\xee\x08\x08\xc0\xa3\x0b\x2a\x1e\xaa\x90\xea\x43\xb8\x57\x5c\x30\x56\xf4\x23\xcd\x4b\x6f\x34\xae\x51\xc2\x22\x37\x65\xa9\xea\x21\xf6\x45\x73\xc1\xa1\x39\x61\x32\x12\x46\xe3\xb5\x34\x9e\xe0\x48\xfb\x62\xd5\xfb\x61\xb1\x71\x43\x91\x18\x25\x62\xb9\x15\x98\x36\x0e\x5f\x9b\xf4\xac\x80\xdb\x24\x64\x32\xaf\xb3\xa4\x3d\x34\x96\x50\xde\x03\xd3\x43\xc2\xe9\x7a\x8e\xef\xd1\xbf\x30\xc1\x0c\x25\x86\x7f\x53\x26\x6b\xd1\xf0\xdc\x14\xae\x1a\x6b\xe9\xef\xde\xcf\xf6\x7e\x7d\x29\x2c\x6c\xdf\xc9\x0d\x80\xb8\x86\x66\x8f\x04\xc2\xa0\xf5\xad\x7f\xa1\x7c\x17\x8b\x6e\x9b\x45\xa1\x1f\x4d\xdf\xe2\xd6\x69\x60\xa3\xf7\x51\x35\xad\x5e\xd1\x54\xe5\x13\xe1\xa5\xd1\x38\xe7\x37\x1e\x84\xd7\xc9\x24\x53\xe6\xc6\x2d\xc5\x9b\x8e\x1f\xa9\x3d\x77\x3a\x25\x40\xd9\x1c\x25\x7c"}, +{{0x4e,0xc6,0x82,0x9b,0x43,0x99,0x70,0x56,0xd9,0x96,0x85,0x38,0x9b,0xd5,0x3c,0x52,0x8d,0xe7,0xe5,0xff,0x27,0x15,0xd6,0x5c,0x95,0x66,0x19,0x82,0x6e,0x3f,0xb5,0xb5,},{0x7d,0x92,0x2d,0x57,0xfd,0xb1,0x27,0x92,0x87,0x9a,0xec,0x4e,0x8c,0x65,0x14,0x63,0xec,0xe0,0x64,0x49,0x2c,0x72,0x17,0x53,0xd2,0x2e,0x11,0x55,0x09,0xfe,0xd7,0x06,},{0x15,0x9c,0xa4,0x04,0xf7,0xf7,0x41,0x17,0xc5,0x16,0x3c,0xf4,0x04,0x11,0x09,0x49,0xeb,0x57,0xae,0x2d,0x76,0x62,0xb1,0xff,0x41,0x78,0xcc,0x67,0x56,0xe9,0x0a,0xda,0xea,0xb7,0x1b,0x06,0x4c,0xe1,0xdf,0xf4,0x57,0xb2,0xdb,0xa7,0xe2,0xdc,0x13,0xc2,0x17,0xbc,0xae,0x8a,0x61,0xfc,0xf8,0xce,0x14,0x87,0xa6,0x49,0xc2,0x57,0xff,0x07,},"\xed\x26\xb4\x13\x0d\x4e\xbf\x3f\x38\x61\x49\x1a\xa3\xdd\x96\xa4\xeb\x69\x75\x21\x73\xfa\x6c\x84\xca\x65\xdf\xc9\x91\xc7\xfe\x44\xe0\x2b\xd6\x16\x50\x25\x2a\x1d\x23\x78\x66\x82\xec\x38\xc1\xfe\xe8\x2c\xc3\x50\xdb\x7c\x3c\x39\x49\xa1\xc9\x35\xff\xeb\xd7\xba\xa2\x4f\x35\xa3\x93\xfb\xd2\x7e\x7c\x34\xc2\xf9\xff\xda\x60\xa1\x8d\xf6\x6c\x3e\x46\x5d\x90\xed\x48\xfb\xba\xd3\xfa\x79\x47\xde\xe7\xe6\x59\xa3\xee\xad\xb8\x87\xf0\x96\x3f\x6b\xdd\x76\xc3\x6c\x11\xae\x46\xd0\x88\xee\x50\xbc\xa8\x18\x7a\x0a\x88\x32\xdb\x79\x84\xb7\xe2\x7c\xbe\x6a\xbf\x12\xd2\xc9\x4f\x33\x7e\xc7\x8c\xb3\x8b\x26\x24\x1b\xd1\xa3\xd2\xf5\xfa\x44\x07\xfd\xd8\x02\x27\xd2\xb1\x70\x14\x4b\x41\x59\x78\xe3\x72\x01\xd0\xfc\xf4\x31\x74\xb9\xd7\xb2\x11\x5d\x5e\xb8\xbc\xec\x27\x6a\x77\x5a\xea\x93\xf2\x34\x0d\x44\x25\xd3\x4d\x20\x47\x49\x4d\x91\x7e\x0d\xbe\x37\x85\x7e\x6c\x99\x85\x9b\x71\xc9\x14\xaa\xd5\xe5\x4f\x7b\x2b\x03\x3e\x59\x4e\x27\x2c\xc5\xcf\xe9\x19\xf8\x88\xe5\x5c\xb6\x15\x7a\xff\xcf\x35\x72\x46\xd0\x0b\x53\x2c\xc4\x71\xb9\x2e\xae\x0e\xf7\xf1\xe9\x15\x94\x4c\x65\x27\x93\x15\x72\x98\x53\xda\x57\x2c\x80\x9a\xa0\x9d\x40\x36\x5f\x90\x87\x5a\x50\xd3\x1c\xa3\x90\x0d\xa7\x70\x47\xc9\x57\xc8\xf8\xbf\x20\xec\x86\xbd\x56\xf9\xa9\x54\xd9\x98\x8e\x20\x6b\x44\x4c\xa5\xa4\x43\x45\x21\xbf\xc9\xc5\xf3\xa8\xa0\x61\x47\xeb\x07\xd1\x1d\xfe\x11\x71\xec\x31\xff\x55\x77\x15\x88\xb3\x33\xee\xe6\x21\x5d\x21\x6c\x47\xa8\x56\x6f\xbb\x2b\x18\x97\x46\x46\xac\x5a\x92\xc6\x99\xd7\x75\x84\xc0\xde\xfe\xfd\x2d\xfa\x58\xfc\xa2\x71\x99\xe4\x1e\xc5\x8a\x24\x63\x20\xb3\x5f\xaa\xb7\x5b\x97\x95\x19\x24\x22\x6d\xa4\xab\x28\xf0\x1b\x47\x07\x8e\x71\x2e\x4f\xd9\xf7\x7b\x25\x1c\x96\x67\x85\x8c\x28\xe3\x2e\xf1\xcd\x01\xfc\xbe\x43\x5c\x54\x2d\xba\xd0\xa8\x4a\x13\xcd\xbb\x57\x75\xe6\x2d\x81\x1d\xc6\x90\xd9\x55\x5c\x37\xf1\x5f\x91\x76\x7a\x56\x13\x57\xdf\x10\x6e\xef\xe0\x56\xe7\x36\x06\x70\x65\x0f\xb8\x18\xfc\x6a\xdc\x59\x97\x3e\x9a\xd5\xcd\xcd\x80\x98\x07\xab\x56\x39\x7f\x3c\x13\x94\x87\x32\xd9\x8d\x67\x6f\x4a\x44\x70\xa9\x5d\x8b\x51\x82\x37\xe2\x26\xf0\xcc\x5f\x47\x65\x16\x4a\x5c\x3e\xf0\x50\x71\x4b\xe0\x2a\x12\x6b\xe8\xf6\x65\x46\x48\x15\x81\xb9\xe9\x4a\x26\xaa\xd2\x4c\x69\x3b\x7f\xdb\xc1\x8a\xcd\x3e\xd7\xcf\xc4\x7d\x8a\xb2\x67\x45\xd7\x8e\x70\x1d\x0c\xf0\x5d\xd8\x44\xb5\xb3\x45\xa2\x9d\xab\x68\x4c\xbc\x50\x92\xba\x02\x2e\x3c\x58\x2d\xfc\x04\x4c\x31\x00\xad\x02\x75\x66\x97\xa8\x49\x82\x29\x15\xa1\x6e\x2a\x2b\x81\x0e\x68\x15\xf5\x44\x21\xd2\xf3\xa6\xff\xf5\x88\xc0\xd9\x01\x3c\x76\xf3\x3e\x09\xbe\xae\xef\x60\xd8\x77\x42\x30\xe8\xce\x71\x31\x28\x9a\xef\x2a\x40\x68\x6c\x81\x9f\xb2\x04\x0b\x06\x12\x4d\x3d\x9a\xa4\x19\xd5\x67\x88\xf1\x7f\xa7\xed\x9b\x9b\x57\xce\xaa\xd1\x33\x7a\x01\x01\xbe\xa0\x44\x0c\xff\x74\x5d\xdd\x97\x22\x05\x5d\x1f\x9b\xcf\xb0\x09\xce\x2c\x2f\x41\xa9\xe7\xe8\x68\x06\xb8\x72\xcd\xc2\x05\x9b\xc8\xec\x68\xf5\xee\x56\xc4\xba\xcf\x4b\xbd\x30\xea\x4c\x71\x55\x86\x4d\x60\x0c\x0e\x2e\xee\x73\xb3\x19\xbd\xa4\x37\x2e\x9c\x60\x3c\x77\x2c\x25\x89\x0c\x76\x10\x48\x99\x89\x47\x5d\x37\xa7\x7a\x45\x74\xa2\xba\x55\xbf\xd9\xc9\xcf\xd1\x46\xfb\x97\xe6\x16\x5d\xcc\x19\x55\x9f\x4f\x85\xdf\xca\x2f\x97\xf3\x70\x2e\xd8\xfa\x6b\x3c\x2a\x97\x41\x97\x4a\xa0\x7a\xb6"}, +{{0xb1,0x50,0xa7,0x89,0x29,0xed,0x1e,0xb9,0x32,0x69,0x21,0x3e,0x1e,0xbc,0x22,0xe2,0xe4,0x0a,0x60,0x1b,0xdb,0x00,0x54,0x99,0xb7,0xbe,0xb0,0x58,0x91,0x7c,0x53,0x40,},{0x28,0x86,0x6b,0x6d,0x1c,0x39,0x3c,0xb0,0x8e,0x46,0x4c,0xf5,0x57,0x14,0x40,0xa6,0x49,0xe5,0x06,0x42,0x38,0x0d,0xdf,0x4f,0xfb,0x7a,0xd1,0x50,0x48,0x5c,0x10,0x8e,},{0x27,0x6d,0xd0,0x96,0x2e,0x6e,0xe6,0x4f,0x05,0x92,0x44,0x1a,0x8a,0xf0,0xe5,0xef,0x8f,0x93,0xbf,0x0b,0xae,0xba,0x20,0x50,0x4b,0x9d,0xb4,0xf9,0x5a,0x00,0xb9,0x39,0xea,0x38,0xde,0xf1,0xc7,0x97,0x86,0x28,0x98,0xca,0xbe,0x9d,0xc4,0x64,0x4f,0x0e,0x67,0x7e,0x87,0xc0,0xa3,0x3b,0x87,0xb6,0xa4,0xd2,0x2a,0x80,0x7d,0x0e,0x1e,0x02,},"\x1b\xf5\x5d\x27\xf9\xdd\xe6\xc4\xf1\xc0\xdd\xd3\x60\xa2\x5d\x94\x93\xc0\xff\xdc\xa7\x4a\x7e\xd5\xe5\xa5\x14\xe9\x55\x15\xcd\xa4\xaa\xd8\xf4\x5c\xd6\xed\x79\x01\xf8\xf2\x24\xa6\x3b\x38\x12\x1c\xbe\xac\x2f\x56\xda\xe2\x10\xdd\x05\x37\x50\xcb\x20\x75\x14\xa8\x89\x1e\x24\x5a\x5d\x07\xe7\xde\x78\xa2\xe3\x81\x44\x63\xf1\x48\xd2\xac\xb7\xdc\x71\xf9\x95\xc9\x29\x9a\xd0\xd6\x26\x6c\xfe\xfc\x94\x26\x96\x57\xfd\x47\xcf\x53\x12\xb9\x2a\xf2\x75\x06\x51\xc4\x79\x63\x6c\x9d\x36\xae\xf0\x8f\x7d\x11\x95\xe7\xfa\x1b\xa3\xab\xb5\xdc\xb9\x01\x36\xb0\xfb\x9a\x37\x66\x8b\x87\xa2\xdb\x88\xd1\xe2\xb6\x44\x0d\x3e\x6e\x60\x1e\x6d\x4b\xc1\x0c\xf1\xcb\xdf\x1d\x61\x69\xc0\xdc\x2c\x4a\xec\xde\xb6\xcd\xd4\x56\x7d\x42\x50\xb2\xaf\xa7\x15\xb1\x66\xc9\x46\x7f\x90\x7d\x3f\xa5\xa6\xda\xf2\x00\xb3\x09\xc1\x09\x37\x68\x30\x49\x9c\xaf\x31\x49\x00\x1c\xf3\x33\x94\x48\xca\x3d\x76\x52\x25\xd6\xb3\xc1\xcd\x26\x7c\xba\x93\x6e\x7a\xa4\x83\x25\x39\x46\x6f\xd2\x0c\xbb\x38\x32\x3c\xbb\x22\x28\xa2\x71\xf2\xd2\x82\x56\x1c\x73\xed\x79\xa1\xad\x04\x69\x8e\x27\xef\xe3\x93\x23\x5f\x34\x56\xc2\x95\x40\x7d\xa0\x96\x0f\x00\x34\xd8\xde\xef\xd1\xc1\x85\x73\x6f\xd3\xea\xf1\xf9\xa1\xe3\x2f\x09\x17\x4c\x1f\xe1\x27\x20\xb7\xc9\x6f\xeb\xdb\x33\xe0\x1b\x1b\x6a\x1c\x63\x71\x50\x19\x4b\xe4\xff\xab\x15\x9e\x45\xb2\x45\x85\x57\x68\x46\xbb\x64\x27\x4e\xca\x7b\x39\xa3\xed\x93\x57\xde\x7b\x08\x42\x13\x02\x4a\x9e\x85\x89\x26\x36\x00\xa2\x86\x7c\x2a\x7c\xf8\xb9\x90\x76\xa1\x2a\x07\xbd\x7d\xf8\xd5\x27\x7b\xb0\x4a\xd7\x2e\x63\x9b\x77\xea\xca\x1e\xc5\x8e\xf9\x63\x7e\x9a\x23\x76\xba\x87\x8a\x45\x72\x35\xa0\x6f\x78\xfd\xf0\xe0\xd9\x25\xcb\x2f\xd2\xa3\x8c\x77\x18\x8f\x60\x37\x2e\xf6\x00\x97\x92\x42\x43\x99\xc9\xb6\x79\x28\xda\x2e\x3b\xa9\x1c\xbd\xe4\x07\xe7\xe8\x76\xba\x98\x13\x9e\xd2\x2c\xa3\xb9\x83\xbe\xde\x00\x00\x52\x87\x96\x44\x8e\x4a\x10\x55\xac\xb2\xde\xaa\x56\xbc\x30\x82\x54\xc5\xbd\x49\x8c\x27\x5e\xce\xdc\x13\x57\xef\xe1\xfd\xa0\x1d\x34\xd9\x16\xdd\x4d\x86\x47\xe5\x77\x19\x95\xa6\x53\xe0\xf8\xa5\x28\x4c\xc7\xbf\x73\x15\x7b\x33\x49\xd5\x9e\x6f\x92\x0c\xad\x6c\xdd\x17\x19\xf0\x38\x02\x5c\x43\x00\xe0\x21\x0c\xe2\x49\xfa\xf3\xc8\x2d\xe1\xfd\x1c\xda\xbe\x61\xc1\x4e\xcb\x1d\xf0\x0c\x5c\x46\x6a\xa6\xa0\x12\xa9\xc1\x0d\xcf\xe5\x9b\x7e\x9d\x3b\x15\x5d\xab\x6c\x7b\x7c\x16\x08\xc1\xed\xd5\x1d\xbd\xad\xf6\xba\x58\x76\xb5\xe6\x0f\xdf\x7f\x19\xe6\xef\x71\x2c\xd1\xa7\xdd\x3a\x06\x2a\x65\x74\xa7\x43\x6b\x31\x9e\xfb\x94\x4e\x42\x23\xf5\x42\xb2\x50\x2c\x1b\xa9\x76\xbe\x91\xe0\x5b\x0f\x85\xa0\x9f\xd7\x93\xbe\xca\x88\x33\x75\xfb\x67\xcd\x13\x3f\x52\x84\xd8\x99\x84\xff\x3c\xaf\xa7\xe1\x1a\x9d\x85\xe7\x89\x32\x32\xa5\x24\xec\x54\xb2\x0f\x97\x5d\x3c\x0a\x11\x43\xa0\xef\x41\x17\x6b\x70\x51\xea\x91\xd4\x0c\x5f\x44\xfd\x9e\x10\x05\x58\xbf\x12\x12\xa7\xb8\x91\xe6\x8b\x55\xca\x61\xf4\xbe\x94\x52\x66\xd9\xa1\x00\x7a\x14\xaa\xeb\x68\xc4\x8e\x25\x7f\x0f\x46\x31\x0a\xd1\x64\x81\x46\x7e\xc1\x77\x35\x35\xd5\xfc\x08\x49\x15\xf5\xd0\x04\xba\x0d\xc7\x59\x1d\x21\x23\xc6\x22\x07\x90\x9d\x84\xf2\xb3\x82\xf5\xef\x12\x75\x9a\x95\xcd\x3f\x51\x89\x80\x6e\x27\x39\x60\xae\xe1\x62\xc0\x0f\x73\xe7\xfa\x59\x36\x39\x57\x65\x4b\xb1\x91\x6b\x57\x09\xbb\x0a\x9d\x04\x05\x14\xae\x52\x84\x95\x1e\x6b"}, +{{0x9f,0xc7,0xc4,0x9c,0xb8,0xc4,0xf0,0x97,0x2d,0x6e,0xd9,0x70,0xae,0x2c,0x6a,0xc3,0x37,0xe6,0x75,0x42,0x5c,0xc8,0xdc,0xe7,0x30,0xfc,0x41,0x44,0x43,0x02,0x93,0x5d,},{0x47,0x82,0x52,0x0b,0x06,0xf9,0x33,0x44,0xaa,0x76,0x67,0x80,0xe5,0x44,0x01,0x36,0x3d,0xfd,0x7d,0x96,0x7c,0xc3,0xbf,0x06,0x48,0x8a,0xf9,0x09,0x20,0xa3,0x0f,0x85,},{0x5c,0x78,0x3a,0x86,0x0a,0xa6,0x68,0x18,0x4d,0xd2,0x2c,0x4f,0x9a,0x54,0x6b,0x5e,0xc9,0x6e,0xba,0xd2,0xe4,0xaf,0x00,0xf9,0x68,0xc6,0x88,0x67,0x13,0x54,0xe0,0xcc,0x9b,0x57,0x2c,0x73,0xbc,0x6f,0x19,0x93,0x7a,0x05,0xf1,0xba,0xf3,0x43,0x47,0x63,0x96,0x5c,0x96,0xe1,0x03,0x40,0x7f,0x0e,0xb6,0x42,0xc5,0x64,0x41,0x54,0x29,0x0b,},"\x82\xbc\x2c\x70\x0d\xb2\x22\xa4\xac\x91\x4a\xa2\xbe\x8f\xa2\x8e\x42\x20\x67\xf9\x4f\x33\x44\xf5\x36\x2b\xeb\xaa\xbe\xd7\x61\x2b\x0e\x46\x4a\x73\xa6\xc4\x56\x90\x35\x64\xb1\x53\x93\x48\x51\x40\xdd\x0f\x3a\xff\x90\xaa\x6e\x16\x61\xdd\xf6\x82\x85\x0d\x04\x90\xaf\xc3\xd7\x35\xde\xa0\x5b\xa4\x7c\x85\xd9\x7e\x83\x35\x33\x51\x4c\x19\x8b\x4c\xf6\xe6\x6d\x36\x0e\xe5\xbf\x00\xe1\x4a\x3a\xab\x1a\xd0\xe7\xb8\xab\x2a\xac\xc9\x64\xd4\x28\x30\xc7\x84\x53\xdf\x19\x55\xbb\xed\x1c\xd6\x8a\xda\x3d\xb0\xec\xdb\x60\x1a\xd7\x66\x7d\x5c\x5e\x2f\xd4\x9e\x36\xf7\x32\x8e\xaa\x33\x7d\xbd\x6f\xf7\x0e\x78\x98\xa3\xf9\x8c\x15\x9d\x04\x5a\x24\x27\xad\xe5\x33\x3c\x88\xfc\x4a\xfd\x38\x19\xdc\x82\xf4\xda\xa3\xc5\x23\xcb\x57\xe3\x5a\x2a\x5a\x72\x5d\x63\xd4\x02\xba\xef\x51\xe5\x1f\x1e\xf4\xf8\xf9\xa5\x95\xc9\x37\x9c\x9a\xba\x87\x3f\xb4\xe7\x65\xa9\x31\xda\x09\x14\x8a\xba\x6e\xc5\xb4\x48\x59\xb0\xe8\x1f\xf9\xfc\x22\x95\x98\xac\x9f\xbd\xb0\xbd\xbd\xdb\x56\x92\xa5\x22\x22\xdf\x52\xea\x38\x7b\xbb\xf3\x6a\xd6\x4d\x19\x46\xbd\x28\x2e\x32\x3f\xf4\x82\x2a\xd9\xda\x89\x7f\xf7\x3f\x01\xb3\x90\xcf\xe2\xe6\x4d\xe4\x92\xd5\x5d\xe7\x7f\x5d\x7d\x00\x60\xa6\x87\x2a\x01\x83\xcc\xba\x61\x0f\x53\x27\x4c\xcb\x29\xce\x6d\xce\x6a\x03\x6c\x53\x17\xa1\xed\x2a\x7c\x10\x68\xc1\xb2\x46\xfc\x1d\x58\x81\xd0\x0d\xe0\x6e\xb4\x01\xcf\xf9\x5e\x6b\x69\x14\x86\x99\xdb\x13\xe9\x4b\xb5\xb2\x80\x21\x2d\xff\x54\xc7\x0e\x56\xde\x23\x5a\x5f\x14\x00\xb5\xbe\xa5\x67\x72\xd0\x60\x17\x0f\x1d\x06\x57\x32\x15\x61\xe4\xb4\x91\x07\xeb\x96\xd9\xb3\xbc\x5a\xdf\x45\x1c\x2a\x52\x4e\xba\x4d\xb0\x03\xb7\x7b\x63\x2a\x5d\x89\x82\x7a\x62\x24\xcc\x79\x8e\x09\x6b\xa2\x7f\xb3\x3b\xf6\x1e\x3b\x8e\xaf\x18\xd0\x01\xae\x8e\xb5\x2f\x85\xc9\x0d\x9e\x12\x54\x48\x03\xe6\x7f\xf0\x20\x47\xe0\xd2\x3c\x22\xe7\xf8\xb9\x80\xc0\x1c\x3d\x48\x24\xb2\xa9\xa1\x4a\x2e\x8f\x67\x2a\x7b\x0c\xe0\x3b\xdb\xb3\xbd\x56\xd7\x54\xa0\x96\x4d\xb0\x1c\xa8\x99\xd4\x88\x00\x15\x08\x65\x7b\x7b\x02\x2c\xcf\x04\x2c\x38\xfc\x19\x49\xd0\xe0\x0a\xf4\xd3\x01\xd4\xf0\x0c\x3d\xea\x20\xe3\x08\xa0\xf9\xdc\xac\xb4\x32\x22\xb3\x82\x41\x44\xaf\x77\xbe\x18\xa5\x04\xaa\x8d\x26\x8b\x8a\x56\x00\x72\x5e\x7c\xc5\xf3\xa2\xe6\x25\x6a\x80\x74\xd1\xae\xbc\xa1\x23\xea\x53\xa0\x76\x7a\x92\xe1\x78\x3a\x49\x83\xc5\xef\x3d\x7d\xd7\xf0\x2a\xa9\xd1\xf4\xf9\xaa\xc6\xce\x25\x45\x93\xf0\x87\x92\x01\x4f\xb8\x67\xea\xf8\x79\xb8\x8a\x4e\xfb\x18\xe8\x9b\xa1\x10\x06\xad\x09\xd8\x54\x31\xcc\x26\x57\x5b\x53\x8d\x8e\x78\x90\x64\x6c\x59\x88\x64\x7c\xc1\x05\xd5\x82\x90\x7a\xe6\x25\xe0\x9c\xd0\x89\xf4\x72\x49\xe8\x18\x14\xda\x14\x04\x4c\x70\x14\xe8\x0e\x7a\x8e\x61\x9c\x7b\x73\x5f\x70\x16\x16\xb6\xa3\xc6\xf4\x92\xcd\xc6\xed\x46\x3e\x71\xa3\xd2\x22\x91\x48\x2d\x90\xa1\xde\x6f\x09\x7c\x4a\xe2\x54\x87\x61\x84\xc5\x62\xb1\x65\x75\xb9\xd0\xd1\x93\x13\xed\x98\x86\x4f\x49\xfe\x2e\x1d\x07\x4a\x21\x21\x1b\x2b\x2a\x6d\x27\xdd\xb2\x86\x11\x52\x0d\x5f\x71\x23\x05\x8f\xd0\x07\xbb\x01\x00\x1d\xef\x07\xb7\x92\xbb\x05\xbb\x74\x1c\x12\x9c\x6a\x36\x37\x6c\x38\x53\xb8\xbb\x4f\x66\xb5\x76\x0c\x8e\xb4\xec\xc7\x30\x6b\xa3\xa9\x0c\x70\xda\x47\xc9\x65\xf6\xdc\xcb\xdb\x61\xa7\xfd\xa1\x8e\xe9\x67\xcf\x8c\x5f\x05\x03\x11\x09\x2d\x0f\xde\xea\xed\xd1\x26\x5d\xef\xdd\x66\x0a\xbe\x70"}, +{{0x08,0xbf,0x05,0x9b,0x4d,0xa9,0xaa,0x7f,0xfc,0x70,0x2f,0x5b,0x23,0x04,0xc4,0xf9,0x6c,0xa4,0x9b,0x7d,0xab,0xb6,0xaf,0xb4,0x1d,0xc9,0x1c,0x0f,0x00,0xc6,0x5b,0x78,},{0xa6,0x28,0x9b,0xa2,0x8e,0x80,0xe8,0xd1,0xa3,0x19,0x22,0x3e,0x41,0x65,0xdc,0x0b,0xce,0x73,0x52,0xaa,0xf2,0x42,0xf7,0x0c,0xc9,0x68,0xd2,0x1d,0x77,0x75,0x28,0x32,},{0xe2,0x47,0x65,0x86,0x01,0x37,0x68,0x9a,0xad,0x50,0xeb,0xee,0xfc,0x8d,0x6d,0xb8,0xe9,0x36,0xa4,0xcb,0xa6,0x2c,0xe8,0x7a,0x7f,0x58,0x02,0x09,0x38,0x4a,0x9d,0x7e,0xec,0x90,0x70,0x90,0x5f,0x60,0xad,0x63,0xa7,0xbe,0xfd,0x7c,0x70,0xf0,0xae,0x7c,0x81,0x09,0x16,0x9a,0xee,0x4e,0x51,0x8f,0xce,0xbf,0xac,0xa7,0x23,0xc5,0xb2,0x07,},"\xbd\x4f\xb2\x8a\x1d\xd0\x8b\x07\xba\x66\xe1\x7f\x0c\x4f\x21\x85\x3f\xef\xef\x1c\x9d\x20\xba\x79\x77\xf1\x54\x64\x1e\xa1\xa1\x8b\xec\xf6\xbb\xb8\x03\x88\x88\x62\x94\xe0\x75\x6a\x3c\x50\x8f\xfd\xfe\x90\xb5\x1e\x13\x56\xd1\x12\xd8\xcd\xe5\xee\x2c\xc6\x33\x2e\x61\xd1\x69\xcc\xc8\xcc\x93\x49\x94\xf1\xbb\x56\x0f\xa4\x66\x0c\x0b\x0f\xd4\xe8\x14\x9a\x22\x5e\xd4\x88\x3e\x68\xfb\xb6\x9d\xa7\xaf\x8a\x52\x4b\x17\x14\x1c\xcb\x76\xb5\x0c\xd8\xe1\xb6\x7d\x3c\xe0\x37\xde\xd7\xdf\xa5\x9b\xc7\xc2\x67\x42\x26\xec\x7e\x07\xb7\x8e\xa3\xf7\x82\xfd\xa3\xe5\xf1\xe9\xca\xea\xb6\x08\xca\x38\x7c\x30\x46\x54\xf8\x01\xd0\x0e\x10\xa7\xc2\x9f\x4b\x0d\xa3\xe5\xf8\x95\x13\xa9\x80\x37\x71\x9a\x1a\xef\x4c\x25\x06\xc1\x77\xaf\x54\x51\xa0\x07\x57\xa5\x9f\x16\x22\x9c\x4f\x44\x14\xdf\x51\x58\x0d\x48\x21\x0d\xab\xc9\x37\x73\x70\xb6\x06\x8a\x88\xe8\x1d\x3a\xd1\xbe\xd4\x98\x51\x55\xc3\x60\x0f\xf4\x87\x68\xb9\x03\x02\x2f\xe0\x2a\xe4\x80\xf2\xe6\x32\x9f\x0b\xcc\x91\xd7\x5f\x5c\x6a\x09\xfd\xf7\x7b\xde\x90\x49\x9f\x3c\xa3\x95\xcb\x20\x06\x2a\x09\x84\xad\x6a\x01\x41\xfd\x01\xc2\xd5\x4d\xfb\xb1\xee\x58\x46\x10\x64\x07\x73\x43\x9a\x16\x58\xd2\xc9\xf8\x62\xf1\x83\xbf\xef\xb0\x33\xa3\xbe\x27\x18\x12\xf1\x3c\x78\x70\x46\x57\xe7\xfb\x4f\x85\x01\x75\xfc\xd6\x3d\x3e\x44\x05\xd1\x92\x24\x2c\x21\xf2\x7c\x51\x47\x7f\x32\x11\xa9\xce\x24\x8e\x89\x2b\x42\xfb\x6d\x85\x82\x0f\x41\xb8\x97\x83\x6f\x20\xf8\x5a\x13\x11\x53\x4b\x5c\x40\x4f\x8b\x7a\x4a\x03\x19\xbc\x6c\xec\xaa\x57\xfe\x4d\x4f\x20\x60\x7c\x99\xc2\xdf\x22\xfa\x06\x76\xf9\x9d\x1b\xd8\x78\x86\xc9\x28\xc4\x98\x8c\x6e\x78\xc5\x7d\x75\x83\x30\xe6\x92\x2c\xbe\x03\xc1\x03\x40\x25\x3d\x0d\xd4\x83\x79\x2c\xe7\x5e\x6c\xd0\x9d\x12\xfb\xbb\x04\x1f\x02\x05\xe6\x5a\xd2\x5c\xe7\xc1\xb2\x4e\x77\xee\x8d\x6f\x91\x5e\x3b\xc3\xe1\x0d\x09\xfb\xd3\x87\xa8\x4b\xda\xab\xfd\x1c\xed\xb5\x2c\x0b\x17\x33\xb5\xf4\x70\x88\xc0\xd3\x5e\x0e\xf4\x58\xc8\x54\x14\xc2\xb0\x4c\x2d\x29\xf6\x3f\x77\x58\x61\x31\xee\x65\x53\x0f\x20\x9b\x51\x8a\x0f\x25\x7a\x07\x46\xbb\xd5\xfe\x0a\x2e\x0c\x38\x8a\x6c\x48\x0e\x1b\x60\x71\x4f\xee\x1c\x59\x41\xbb\x4e\x13\xf7\x07\xea\xc4\x87\xa9\x66\x6a\x72\x3b\x57\x93\x13\x4a\x26\x8b\x77\x59\x77\x86\xc3\xa3\x19\x3b\x46\xd3\x55\xdd\x08\x95\xfc\x62\x16\xc5\x36\xa5\x42\xff\xd7\xd7\xb0\x80\x10\xc8\x6f\x54\x7a\x5d\xaa\x38\x33\x5a\x8b\xfa\x26\x55\xd5\xf7\x1b\x4d\x88\x07\xf5\x0c\x85\x45\xc5\x83\xdd\x0b\x69\x00\x22\xee\x65\x87\x3a\xea\x3e\x8f\x1a\x56\x5f\x3b\x0e\x4e\x02\x95\xfb\x0d\x32\x1f\x5c\x0b\x39\x7f\x2f\xd0\x52\x8f\x86\xa0\xd1\xb7\x07\xf7\x37\xb1\x75\xc6\x9e\x9e\x7a\xe3\xc8\x4d\x4b\x2c\xf3\xa3\x8a\x63\x1a\xa8\x03\x2b\x3e\x65\xbb\x45\x28\xf6\x6d\x0b\xfd\x34\x47\x3e\xd0\x10\x1d\x2a\x61\x25\x5b\x21\x5b\xc1\xcb\xab\x9a\x26\xd2\xb9\x69\x32\x4b\x77\xc8\xa5\x46\x4e\x5b\x23\xdf\x6c\x51\x12\xf9\xd1\x7c\x58\x7d\x95\x55\x9d\xe2\x12\xad\x24\x1d\x8b\x12\x60\x50\xe5\xfd\xdf\xcc\x83\x9a\x7e\x5a\xa2\xfd\xa1\xca\x20\xc0\x91\x0d\x86\x34\x18\xf1\x95\xb3\x8a\xdf\xcc\x36\xe9\x2f\x23\x96\xac\x31\x44\xb5\x37\xb3\x0f\xbe\x4d\xde\x61\x49\x02\xf8\x99\x78\xb7\xfb\x42\xcd\x99\xf1\x3d\x99\xc4\x5c\x73\x4f\xb8\x2c\x32\x59\xf9\x0b\x88\xfd\x52\xbd\xcb\x88\xf7\xee\xec\xdd\xe4\xc2\x43\xd8\x80\xba\xc7\x61\x4e\x15\xcf\x8d\xb5\x99\x3f\xfa"}, +{{0xdb,0xbd,0x0f,0x7e,0xcb,0x64,0x82,0xcb,0x01,0xc4,0xdb,0xdc,0x38,0x93,0xc0,0xdb,0x81,0xe8,0x31,0x35,0x3a,0x5b,0x01,0xcc,0x75,0xd3,0xb1,0x1f,0x2f,0xf3,0xc5,0x9c,},{0x2d,0x4e,0x58,0x8d,0x31,0xa3,0x84,0xb1,0x78,0x58,0xc0,0xd7,0x84,0xf6,0x71,0x2b,0xaf,0xd0,0xb4,0x12,0x04,0xcf,0x8f,0x0d,0x57,0x97,0x3e,0x59,0xc7,0x70,0xd3,0xda,},{0x96,0xc0,0x03,0x61,0xfb,0x71,0xc5,0x23,0x05,0xe1,0xab,0x77,0x07,0xe0,0x46,0x52,0x03,0xeb,0x13,0xdf,0x3e,0x06,0x55,0xf0,0x95,0xfb,0x33,0x19,0x42,0xa4,0x0b,0x15,0x58,0x41,0x43,0xb3,0x70,0xa7,0xdd,0x57,0x61,0xfb,0x03,0xc0,0x75,0xd0,0x4a,0x83,0x48,0x66,0x1c,0xce,0xa9,0xad,0xa5,0x33,0x65,0xb5,0x00,0x08,0x7d,0x57,0xec,0x0c,},"\xe0\xff\xf3\x59\x75\xeb\xa7\x8d\xa2\xb0\xff\xcc\x5c\x1b\x66\x36\x00\x88\x8e\x82\x55\xcd\x20\x8f\x6d\xce\x7e\x88\x95\x3b\x71\x42\x93\x73\x89\xa3\x37\xae\x82\xf4\xcf\xe3\x2f\xcb\x34\xf5\x52\xa4\x8f\xa8\x89\x9e\x1a\x65\x9e\x3e\xd3\xd3\xd2\x90\xef\xc9\xa0\xf7\xde\xdf\x33\xe2\x1d\x04\x8d\x8d\x91\x07\x57\x03\x7b\x76\xe8\xa7\xee\x9e\x4e\xca\x30\xf5\x29\xdd\xc0\x2c\xef\xfc\x26\xd6\x4f\xda\x73\x03\xcc\x0d\x89\x40\xe9\xef\x59\xdc\x98\x3c\x12\xcc\xd1\xd2\x71\x7e\x64\xd3\x00\x6a\xf8\x2a\xb1\x5b\xb8\x78\xbb\x89\xd1\x75\x8b\xe4\x43\x10\x42\x06\x38\xb9\x6a\x0b\x5e\x1e\x65\x00\x9d\x69\x39\x5d\x02\x7a\x5d\xa4\xa8\x5e\x90\x1b\xe9\xaa\x2c\x0b\x3a\xcc\x50\x8e\xe1\x85\x74\xc1\xb2\xfa\x9b\xd5\xd7\xae\x7c\x7d\x83\x07\x12\xda\x5c\xbf\x26\xbe\x09\xa3\x12\x84\x70\xa1\x2a\x14\x90\x9a\x80\xa2\x66\x65\x9b\xef\xda\x54\x8f\xd2\xb2\x2f\x24\xc5\xfd\xc2\x06\xed\x3a\x4e\x75\xf5\x32\x06\x82\xed\x0e\x4c\xe8\x17\xd6\x3d\x5c\x7f\x1e\xe2\xb4\x40\x64\x33\x55\xbe\x65\x42\xf5\x9d\xc6\xc4\x5a\xb1\x57\x72\xf2\x21\x9a\x81\x2e\xf7\x52\x76\x42\x01\x5b\xc7\x5f\xe4\x5b\xa9\x69\xe8\x10\x0c\x26\x8e\x24\xce\xef\x92\x05\xa8\x3a\x3f\x7b\x5a\xe8\x00\xad\x06\xe0\x95\xb9\xb1\x39\x21\x94\x89\x79\x3a\x7b\xce\x84\xeb\xeb\x65\x4a\xb6\x66\x9e\x28\x55\xcc\xbe\xb6\x94\xdd\x48\x65\x15\x05\xb9\x59\xd3\x2a\x77\x02\x0b\x86\x95\x33\xe3\x25\x6d\x40\x68\x5a\x61\x20\xba\xb7\x94\x48\x5b\x32\xe1\x16\x92\x56\xfb\x18\x8f\xe7\x6e\x04\xe9\xef\xa6\xd1\x0d\x28\x6a\xe8\x6d\x6f\x1c\x87\xe8\xfc\x73\xad\x9b\x59\xfe\x0c\x27\xee\x92\xa4\x64\x15\xb3\x9d\x78\x6d\x66\x32\x5d\x7f\xa6\xfd\xa7\x12\xf1\x99\xda\x55\x4f\xc1\xc8\x99\x44\xa4\xe8\x4c\x19\x6e\x97\x9a\x80\x75\x53\x71\x8c\xb8\x1c\x07\x6e\x51\x1e\x60\x9d\x5c\xac\x23\xd8\xf4\x5b\x38\xb9\x4b\xcf\xcf\x15\x8d\x0d\x61\x60\x22\x38\xd5\x2e\x3a\xe8\x4c\x81\x53\x22\xf5\x34\xf2\x54\xe6\x33\x89\xae\x15\x5d\xee\x2f\xa9\x33\x96\xf0\xea\x49\x9d\x5d\x08\xc2\x47\x59\x08\xc6\x48\xbd\xdc\xee\x59\x1e\x13\x37\xe9\x42\x1d\xc5\xa2\x57\xce\x89\xcc\xce\x4c\xee\xa8\x09\xd7\xe8\x71\x34\xe0\x39\xdb\x1b\xe5\x98\x19\x6d\x30\x89\xfd\xcf\xa8\x97\x8e\x02\xc1\x55\x58\x32\xda\x0a\x72\xb0\x8a\xd0\x7c\xdd\x07\x26\x27\x40\x9c\x87\x39\x37\xb0\xe8\x35\x71\x5b\xaa\xf2\x60\x8b\x23\x95\x32\x74\x67\xcf\x69\xa1\xcd\xcc\xe6\x37\x24\x18\x38\x3e\x7b\x89\xc8\xdf\x4d\x53\x1f\x58\x51\x49\x50\x9e\xad\x1e\x41\xb6\x62\x7f\xea\x81\xc7\x95\x8c\xb4\x9d\x2d\x3c\x3e\x2f\xc6\x91\xe0\xb8\xcf\x72\x67\x9c\x08\xb8\x90\x46\x54\x53\x1b\xc4\x36\x8f\xb6\x17\xac\x75\x57\xd9\xdb\x8d\x32\x9d\x77\xe4\x8d\x8f\xb4\xde\x73\xab\xe7\xcb\x93\x88\x27\x4a\xf5\x85\xf8\x75\xc0\xda\xb7\x93\xe4\x35\x35\x18\xbb\x24\x69\x53\x42\xaf\x0f\x5d\xf5\xbe\x4e\x9c\x7a\xd2\x15\xbe\x90\xe2\x55\x40\xda\x34\x89\x71\x7d\xd3\xd2\x92\x54\x58\x5a\x45\xc1\x3e\x6d\xcc\x7e\x9c\x8a\x3a\x79\xff\x75\x5c\xbe\x46\x5b\x25\xe2\x3a\x1d\xa6\x08\xe1\x08\x4f\xec\x83\xbf\xf8\x0c\xfb\x74\x42\xb1\x46\x01\x87\x30\x7a\xcd\x75\xe3\xf2\xd1\x28\x43\xa7\x70\x94\xac\xc3\x28\x88\xfb\xe5\xf1\xfc\x24\xc6\x15\xd1\x9a\x06\x53\x91\xd4\x17\x64\x74\x64\x42\x46\xb5\x34\x3d\xa7\x76\x26\xa2\xd4\x83\xfe\x20\x4f\x83\x93\x28\x77\x5b\x71\xa4\xcb\x56\x72\x73\xe1\x69\x64\x0a\xf9\x3d\xde\x3e\xca\x91\x16\xf4\x00\xe2\x3a\x7a\xd3\xd8\xfc\x3a\x28\xe5\x65\xf1\x25\xd6"}, +{{0x74,0x8b,0xb3,0xcd,0x47,0x71,0x37,0xbc,0x88,0x0e,0xa7,0xc6,0x1d,0xf2,0x5c,0x1d,0xac,0x6e,0xbe,0xc9,0xe6,0xc3,0x19,0x3d,0x81,0xff,0xa6,0xf7,0xa8,0x1e,0xc6,0x67,},{0x10,0x6f,0x28,0xcf,0xed,0xf0,0x96,0x45,0x42,0x26,0xb3,0xb0,0x1f,0xc2,0x4a,0xb1,0xc9,0xbb,0xd7,0xf2,0xb0,0x97,0x3e,0x56,0xfe,0x2f,0x4c,0x56,0xa0,0xb1,0x47,0x5b,},{0xe1,0x3c,0xa8,0xe5,0xce,0x7c,0x26,0x80,0x90,0x90,0x8d,0x61,0xcf,0x2f,0x0a,0x3e,0x45,0x72,0x41,0x2b,0xf5,0xad,0xfc,0x5a,0xdd,0xfe,0x88,0x55,0x6f,0x14,0x8b,0x5f,0xcb,0xe3,0xe1,0xbc,0x65,0xff,0x16,0x11,0x7d,0x35,0xc9,0xd5,0xdc,0x3b,0x11,0x71,0x98,0xf8,0x84,0x92,0x5b,0x40,0x35,0xb2,0xc0,0xde,0x6c,0x40,0x2e,0xd4,0x7a,0x01,},"\x00\xde\x6d\x99\x0c\x84\x33\x8a\x39\x8f\xda\x5f\x4a\x2c\xca\x73\x3c\x56\xb2\xa2\xea\x39\x6c\x2f\xe6\x67\xc2\x68\xe3\x81\x45\x87\x85\x39\xbd\x41\xbc\x14\x0a\x2c\xdf\xe7\xe1\x83\x60\x41\x10\x48\xcc\xa6\x0f\x35\xce\x51\x09\x91\xdf\x26\x1c\xbf\x66\x90\x39\xd9\xd2\x56\x87\xa0\x7f\xc0\x47\x6a\x41\xf5\x0e\xcc\xf3\x81\x53\xee\x6a\xe9\xff\xd3\x92\xb2\xbe\xc0\xcc\x67\x10\x1e\xc3\x69\x6d\x7a\x2e\xc8\xcb\xd4\x47\xb6\xa6\xea\x06\x3d\x33\xec\x12\x8a\xe8\xb5\x75\x77\xde\xe1\x7b\x97\x16\x25\x63\xf1\x5e\x42\xb5\x5c\xa4\xbe\xdb\xdf\xb6\x31\xa9\xf6\x26\x2f\x94\xae\x35\xbb\x35\xf7\x95\xc3\x5a\x01\xde\xdb\x46\x45\xa7\x3c\xfa\x6e\xd9\xee\x52\x1e\x46\x31\xfb\x17\xbb\xc0\x6e\xe5\x73\x16\xbe\x52\x74\x27\xc8\xaa\x55\xc6\x31\x18\x74\x62\xd4\xb2\xc8\x82\x2c\xa4\xe1\x8b\x7a\x5d\x4c\x11\x4c\x11\xdc\x22\x06\x9b\xc8\x32\x65\x6d\x5f\x4d\x39\x54\x87\x18\xc5\x1f\x5e\x4f\xc8\x28\xf6\x0e\x37\xf0\x13\x07\x50\x52\x65\xac\xb2\x2d\x5e\x8d\x76\x7b\x9a\xa7\xb8\x66\xa1\x57\xc6\x43\x87\x3e\x09\x08\x4a\x1a\x40\x4a\x7b\xb5\x8c\xcc\x4b\x5a\x39\x0f\xd3\x06\x01\xc8\x96\x93\x5e\x35\x56\xf6\x0d\x2d\xc6\xbd\xff\xe4\x7d\xa0\xa6\x87\xc8\xec\xe1\x24\x1f\xf6\xc0\x7d\x77\x61\x11\xca\x65\x98\xfc\xa9\x68\xcb\x6a\xfa\x0a\x14\xa3\x4a\xb8\xf5\x4b\x95\xd3\xd8\x47\x3a\x17\x4b\xc7\x25\x52\x3f\x86\x74\xdf\xb2\xb1\x0f\x87\x42\x07\xfe\xe1\xb0\x8b\x42\xda\x1f\x58\x65\x53\x05\xa3\x59\x75\x7a\xa0\x25\x1f\x14\x13\x8e\xed\xbc\x28\x0c\xbd\x38\x5b\xf4\xbb\xf5\x53\x01\x14\xcc\x43\xb0\x47\x47\x79\xe2\x04\x96\x2f\x85\x60\xd4\xaa\x42\x3e\x17\xe6\xae\xca\xce\x66\xc8\x13\x78\x4f\x6c\x89\x8b\x5b\x9c\xb7\x46\xa9\xe0\x1f\xbc\x6b\xb5\xc6\x60\xf3\xe1\x38\x57\x4f\x59\xb9\x74\x54\x45\x48\x6c\x42\x2b\xc0\x6a\x10\xcc\x8c\xc9\xbc\x56\x45\x8e\xf8\x5e\x0e\x8a\x02\x7c\xb0\x61\x7d\x03\x37\xdd\xda\x50\x22\x0b\x22\xc5\xc3\x98\xf5\xce\x05\xec\x32\xf0\x9b\x09\x0f\x7c\xf6\xc6\x0f\x81\x8c\x6b\x4c\x68\x30\x98\x3e\x91\xc6\xea\xdf\x1e\xae\x4d\x54\xbd\xe7\x54\xf7\x5d\x45\x0a\xe7\x31\x29\xf6\xc4\xff\x5c\x4c\x60\x6f\x7c\xad\xbf\x4f\x78\xa1\x8d\xb2\x96\x1c\xc8\xc8\xdd\xab\x05\x78\xcf\xed\xfc\xf9\x5e\xf0\x88\x8a\xfd\x38\x55\x37\xd1\xd0\xa0\x76\x48\xa5\xce\x25\x22\xd0\x63\x35\x07\xd7\x75\x93\xe1\xa0\x36\x6d\x1e\xce\x84\x3d\xe6\x98\x67\xd7\xac\x44\x2b\xa7\xda\xd2\xa9\x0b\x59\xd8\x98\x4e\x4a\x94\x6b\xbe\x5f\x17\x2d\xa4\x27\x63\x8b\x2b\x61\x20\x90\x41\xff\xf5\x0e\x60\xec\x02\xec\x2c\x0b\x1d\xc4\xbe\x2e\xdd\x13\xe8\x7b\x64\xd1\xd1\x66\x31\x14\x57\x3c\xf5\x8a\x17\x73\x9f\x46\x3a\x1c\x3d\x6b\x21\x23\x39\x01\x83\xb5\x05\xc8\xee\xff\xb2\x05\x39\xbd\xfe\xeb\x40\x77\x6d\x20\xc4\x59\xba\xc4\x56\x99\x68\xfc\xaf\xe4\x4e\xa4\xcd\x62\x4a\x84\xbf\xcc\xd7\x87\x6d\xd7\xbf\x55\xf8\x3a\xc7\x04\x0e\x30\xf3\x26\xdc\xe3\x25\x58\x8e\x1b\xa5\xbc\x07\x90\x26\x5d\xfd\xba\x09\x83\x9e\xef\x57\x16\x41\xe8\xa1\x23\x4b\x6c\xfc\x3a\x36\xa8\x66\xbd\x6b\x92\xcd\x71\xec\x74\xe0\xd4\xde\xb9\xe7\x4d\x15\x82\x01\xaa\x50\x2f\x07\xc8\xba\x34\x8a\xc2\x6a\xaf\x9b\x3d\x07\x0c\x9a\x40\xb5\x2a\x44\xe9\x32\x55\x2b\x67\xa2\xdf\x05\xa7\xf0\xf0\x3c\x61\x7b\x48\xdc\x27\x82\x36\x6a\x23\x1e\x0c\x4e\x39\x38\xa4\x27\x4b\x36\xaa\x94\x50\xff\x93\x6b\xe1\x32\xdc\xb6\x92\x83\x8d\x65\x4c\x94\x54\x2c\x6e\x04\x7a\x7f\x78\xba\x71\x19\x19\xf9\x08\xa1\x5b\x30\xb9"}, +{{0x39,0x3d,0x44,0xdd,0x0d,0xed,0x71,0xfc,0x08,0x47,0x7b,0xd2,0x5e,0xd0,0xe6,0x62,0x9f,0xa7,0xf8,0x8f,0x08,0x2e,0xbc,0xef,0x09,0x18,0x98,0xe5,0xc9,0xe3,0xd5,0xb8,},{0xc5,0x2a,0x99,0x3b,0x80,0x2d,0x84,0x54,0x0d,0x27,0x54,0x79,0xa1,0xaf,0x5e,0x28,0x7d,0x19,0xea,0x13,0xb3,0x80,0xfa,0x30,0x68,0xd2,0xf2,0xc6,0x8e,0xb9,0x7a,0x09,},{0x84,0xc7,0x16,0xe6,0x0d,0xe6,0x7b,0x02,0x0c,0xc1,0xa6,0xa2,0x4e,0x65,0x49,0xfe,0x56,0xc6,0xd9,0x41,0xa8,0xed,0xea,0xe4,0x07,0x62,0x66,0x66,0xc3,0x1c,0xb6,0x0d,0xee,0x6b,0xe5,0xa7,0x1e,0xbd,0x76,0xba,0xf7,0x1b,0x75,0x11,0x4b,0xcc,0xfd,0x37,0xd1,0x63,0xa9,0x68,0xbb,0xee,0xc1,0xf7,0x69,0x72,0x15,0x12,0x96,0xc4,0x7e,0x07,},"\x14\x2b\x6e\x82\x50\x13\x62\xd5\x5a\x04\xb8\x9d\x54\x1a\x79\x68\x63\xd7\x78\x38\x40\xd3\x4c\xbd\xfc\x51\x6a\x3c\x84\x77\x2f\x92\x44\x6f\x5f\x0d\xf4\xc4\x5c\x6e\x0d\xc8\xec\x1e\x9b\xb0\xff\x7e\xc1\x69\x6a\x09\xcd\x7a\xe3\x4c\x10\xf8\xe6\x1a\x9a\xca\xbd\x43\x03\xf0\xa9\x24\x72\x37\x62\x1c\x49\x0e\x8d\x9d\x0f\xe4\x44\x82\xc5\x60\xd0\x51\xb8\x2b\x07\x4a\xc3\xd8\xe4\x9b\xb2\xac\x71\x5a\xc4\xcd\xe3\xd4\x70\x9d\x0e\xa3\xaf\xc5\x1b\xfd\xef\x4b\x65\x67\x71\xfb\xd5\x5f\x89\xda\x9f\xa6\xdc\xaa\x62\xcb\xae\x56\x12\x08\xd9\x8c\xfa\x24\xcb\x81\x25\x2b\x89\x5f\x6a\x4a\x92\xc8\xe4\x07\xaf\x6c\x1f\x1e\xf4\x9d\x8d\xde\x15\x4f\xbc\xb1\xca\x45\x7a\x20\x4b\x5e\xa5\x43\x2e\x4d\x71\xfb\x7e\xb2\x4d\x43\xf6\xfe\x25\xe7\xb4\xc6\x59\xb0\xee\xbc\x4c\xbc\xc8\xb3\xcf\xde\x07\xc8\xf0\x7b\x18\xa5\x15\x70\xe7\x16\x3e\x33\xb3\x17\xb6\x13\x60\xf9\xce\x08\xd9\x5d\xe2\xc3\x15\x6a\xf1\xcc\xc9\xb5\x5b\xcf\x81\xea\xbf\x3c\x40\x43\x40\x46\xbb\xe8\x2e\x02\x99\x2a\x2a\xc8\xb3\xb4\x25\x68\x0a\x23\xd9\x34\x72\x6c\xb1\xb7\xbf\x26\xce\xb5\x2a\x39\x02\x2c\x00\xac\xf4\x25\x25\x71\x67\xb8\x21\x18\x5f\x68\xe3\xed\x17\x90\x3d\x8d\x22\x27\x54\x98\xc3\x9a\x9e\x8d\xf8\x84\xec\x00\x55\x8d\xcf\xa4\x3b\x8a\x11\x9c\x2e\x85\x3b\x9a\x03\x18\xbb\xea\x08\x7f\x9c\xec\x17\xca\x49\xb7\x08\x17\xb8\xd7\xc1\x70\xa8\x90\x6f\x3e\xe9\xe8\xf8\xcb\x27\xa1\xd0\xf5\x75\xab\xfa\x62\x7e\x88\xf0\x8c\xa4\xb9\x3c\x32\x97\xc4\xf3\x17\x07\x2f\x42\x1c\x5e\x60\x2e\x2f\x83\x1d\xfb\x82\x55\x1b\xdc\xe8\xd7\x12\x16\xf0\x5c\xf9\xa2\x77\x3b\x90\xfc\x93\xb9\xd8\x55\xa9\x1e\x35\xad\xe3\x32\xa5\x06\x1f\xdb\x82\xb3\x09\xba\xb4\xf5\x6e\x2d\x58\x6a\x84\xc6\x74\x81\xd1\x90\x2c\x26\x1b\x3f\x97\xdc\x30\xb1\x84\x61\x9d\xf9\xfd\xfc\x7a\x32\x9d\x06\x1a\x41\xdf\x33\x22\x02\x13\x3d\x8e\xae\xed\xdb\x4c\xfc\xee\x53\x53\x6e\x07\xaa\xd1\x15\x53\xdc\xf5\xed\x1e\x94\x9d\x45\x35\x5f\x9e\xf4\x2c\x78\x32\xb0\xde\x7c\x2f\x15\x26\xfb\xef\x86\xb6\x36\x49\xb6\xb8\x5a\xe5\xca\x86\xf0\xce\xa6\xdf\x9c\x12\x6c\x1d\x79\x48\x9c\xc3\xbf\xc6\xe8\xbf\x03\x46\xeb\x30\xd0\x16\x43\xc0\x10\x15\x0c\x5c\x8d\x0e\xb5\x01\x0a\x46\x11\x22\x15\x13\x79\x91\x08\x5e\x57\x49\x3b\x22\xe8\x35\x26\xb7\xb1\x72\xc6\xc7\x34\x1c\x40\x32\x1e\x9c\xeb\x7c\x82\xbf\xba\xa4\x8f\x3b\xd8\xf5\x13\x72\xd9\x6d\x47\x44\x4f\xf0\xd8\xbb\x2e\x5f\xd2\x65\x14\xeb\x63\x91\x05\xe3\x38\x95\xfd\xc4\x1f\x6d\xf1\xfb\xfd\xcb\x08\x46\x6e\xc2\xd2\x17\xfc\x99\xfb\x01\x2f\xe6\x54\x0c\x0c\x5a\x59\x66\xed\x3e\x66\xfa\xb1\x20\x2a\xb9\xda\xff\xe8\xe2\x7e\x8f\x74\x62\x82\x8d\x66\x26\x59\xea\x3b\x2c\x60\x8c\xf6\x8e\x30\xdb\xac\x62\xff\xd8\x22\x9f\x4a\x53\xf5\x9a\xe1\x68\x33\xb8\x1a\x15\x91\x61\xf1\x93\x69\xf6\x0f\x51\xc4\x3a\x21\x7e\xfc\x5e\xfd\x6a\xb7\xa9\x1f\xe2\x49\xc7\xb8\xa0\xc1\x4e\x9f\xae\xa5\x33\xde\x13\x38\x49\xa9\x24\x47\x67\x6f\x6c\xc1\x8b\xef\x4f\xec\x7f\x37\x31\x97\x59\xce\x80\xea\x3e\xac\x18\xfa\x2d\x9f\xa0\x23\x09\xe1\xce\x93\xac\x6c\xf4\xcd\x2c\xb2\xc9\x5f\x1e\x2a\xff\x7b\x2a\x88\x56\x40\x5a\x7b\x8e\xba\xbe\xb4\x90\x6d\x9b\x97\x34\xda\x9f\xb5\xe5\xd3\xf3\x22\xbb\x5b\x55\x9f\xa6\x1e\xc8\xf5\x15\xdb\x90\x65\xab\x4b\x91\xa7\xa3\x1d\x5c\x62\x50\x61\xc2\xfd\x2b\xcf\xe1\x7f\x94\xbb\xde\x47\x76\x30\x2b\x8a\xef\x3d\x5b\x52\xdb\x3b\xc7\x3a\xe4\xa3\x0c\xc4\x41\x7a\xcb"}, +{{0x71,0x19,0x36,0x40,0xa0,0xa2,0xb2,0x2f,0xb2,0x2d,0x00,0xa8,0x0b,0x33,0xa5,0x51,0x4f,0x3d,0x10,0x00,0x03,0x4f,0xcc,0xd8,0x85,0xd8,0xea,0x86,0x38,0xf0,0xb0,0xf8,},{0xb1,0xd3,0x6f,0x72,0x3b,0x70,0x86,0xd9,0x23,0x11,0x9f,0x46,0x75,0x9b,0x39,0xfa,0x1e,0x40,0x38,0xc6,0x41,0x8c,0x37,0x9b,0xa9,0x8b,0x58,0x40,0xc7,0xea,0x50,0x68,},{0xa9,0x70,0x2a,0x33,0x95,0xac,0xd2,0x0d,0x75,0x43,0x73,0x09,0x5d,0xc6,0x14,0x45,0x58,0x4d,0x8e,0x57,0x10,0x80,0xe1,0x79,0xad,0xcb,0xa3,0x10,0x6b,0xb0,0x6a,0x7c,0xe4,0xd4,0x60,0xf1,0x26,0x1a,0xef,0x86,0x43,0xab,0x16,0x34,0xf4,0x7c,0x94,0x14,0xa3,0x2e,0x18,0x3a,0x32,0x76,0x91,0xe6,0x58,0x43,0xdd,0x6c,0x05,0x50,0x72,0x07,},"\xe0\x28\x79\x48\xbb\x85\xa3\x98\xe6\xaf\xfa\x2d\x25\xfc\xff\x8b\xdb\x93\x26\xf5\xd1\x4f\xde\xb6\x05\x49\xf5\xfb\xf0\xc1\x81\x6f\x11\xcb\xdd\x4e\x90\xfe\xa0\x39\xdc\xa6\x0f\xaa\xd1\x69\x60\x03\xf9\x15\x15\xc9\xb2\x72\x88\x2c\x95\xc9\xa4\xab\x6e\x27\x77\xbd\x92\x7e\x7d\x84\x42\xae\xa6\xce\xa6\x19\xc9\xb1\x52\x55\xfe\xd6\x12\xb5\xcc\x31\x58\xfc\x70\x5b\xb7\xa5\x06\xf4\xaf\xec\xf4\xe3\x4e\xd5\x17\xb2\xc1\x2b\x83\x62\x61\x0e\x5e\xa2\x70\x48\x5c\xcc\xb3\xc9\xaa\x97\xec\xd6\xcb\x19\x63\x09\x00\xf0\x7d\x94\xcb\x29\x3c\xb6\xe0\x89\xa9\xa7\x7c\x01\x94\x07\x3a\x7f\x71\x77\xb0\x23\x0d\x25\x76\x3a\x2e\xf9\x8d\x47\x70\x4c\xb2\xc3\xaf\x4c\x3c\x1b\x49\x56\x31\xb4\xa5\xb2\x1b\x2e\x56\xbf\xf2\xed\xe0\x3e\xa4\xfe\x7c\xf8\x29\x17\x34\x7e\x3a\x9d\x4d\xbe\xef\x37\xd1\xcf\x17\x61\x5a\xda\xa0\xfd\x17\x05\x79\x69\x91\x7d\x47\x8d\x03\xcc\xd8\xf8\xb8\x8e\x5e\x5a\xca\xe6\x73\x2a\x81\x61\xdf\xb5\xf7\xd0\x21\x23\xc8\xd5\xa5\x65\xcf\x4d\xd9\x8d\xfc\x9a\xaf\x5a\x33\x50\x58\xa9\x41\xca\x43\x07\x3f\x26\x59\x61\x5a\x72\xfe\x78\xc1\x01\xc4\x1a\xed\x07\xf3\xbc\xf9\x80\xb0\xa5\xb3\xfb\xaf\xdb\xbe\xa9\x2f\xd8\x89\xcf\xd5\x3d\x40\x32\x78\xbc\x15\xa5\x9a\xa1\x40\xc2\xd7\x73\xb8\x88\x9b\x96\x3d\xce\xa3\x65\x36\x2e\x42\x6e\xf4\x60\x98\x45\xc9\xbc\xe9\xf8\xae\xb5\x91\xd1\xa4\x69\xb0\x72\xb4\x12\x09\xf5\xa8\xb6\xdc\x23\x95\xad\x90\x60\xeb\x2e\x37\x09\x78\xae\x33\x11\xd1\xcf\x0a\x8f\x20\x51\x42\xd4\x36\xba\xb6\xb9\x59\x43\xa9\x7c\x23\xe6\x1b\xd1\x4b\x2d\x95\x67\x2c\xb9\x32\x5e\x9a\xb1\xfc\x9e\xee\xaa\xcc\xd5\x8b\x9f\x4a\xc1\x55\x0b\xde\xc8\x44\x9b\x03\x60\x39\x49\x6c\x5f\x07\xa5\xed\x64\xd5\xd8\x51\x71\x69\x01\x44\xdb\x5c\x81\xc8\x1c\xbc\x4c\x16\x71\x8d\x52\xc4\xdf\xd1\x95\x8c\xa5\xc9\xc8\xba\x58\x2c\xd9\xd7\x06\xf2\x7a\x74\x74\x4c\x3a\x05\xbf\x1c\xcd\x51\xf1\x09\x20\x10\xd3\x6f\x15\x78\xb5\x78\xae\x0e\x9f\xfa\x47\x07\x90\x55\xef\x94\xfa\xbc\x9f\xf7\x2f\x73\x8b\xef\x68\x46\x1e\xb3\x40\x4c\xce\xe9\x53\xf5\xee\x86\x4c\x97\x4c\xe7\x0e\x90\x37\xe3\x38\x8f\xba\xf2\x88\x9e\x13\x66\xca\xa0\xf6\x51\xe2\x1b\x33\x9e\x3d\x56\xb9\xd9\x5a\xc3\x0b\x35\x92\xa9\x48\x91\x2c\x90\xbf\x54\x47\x3c\xeb\xc4\x67\xb0\x9a\x39\x43\xdc\xac\x48\x68\xac\xb5\xb3\x5e\xa6\x91\xef\xf4\xd8\xcc\x1c\xda\x0c\x6c\x0a\x9c\x16\x9a\x4e\xe1\x00\x41\xf3\x5f\x43\x3f\xb5\x3d\x26\x06\x7b\x29\x10\x56\xb1\xda\x69\xff\x46\xfb\xea\x1c\xa7\x21\x36\x59\xa9\x90\xd5\xd5\xdf\x14\x06\xb0\x93\xda\x2a\x33\xc8\xdf\x95\xab\x3c\xe8\x11\xaf\xb9\xc9\x8c\x5b\xfd\x7c\x4e\x98\x1b\x3e\xa9\x4e\xef\xd2\xe2\xfe\x95\x70\x7d\x89\xf3\x07\xfa\x76\x82\x8b\x5c\x67\x74\x95\x0a\xee\x80\x62\x67\x14\x25\x6e\x19\x7d\xc7\xda\x97\x21\x58\xc7\x68\xbb\xee\x7f\xbd\x16\x9e\xc1\x5b\x4b\xb7\xbe\x72\x97\x6d\xbe\xd3\xe5\x12\x76\x6e\xf2\x2e\xf3\xb8\x12\xbc\xac\x4a\xa3\x11\x5a\xfe\x83\xd3\x12\x84\xaf\x8e\xac\xea\x4e\xe4\x9a\xfd\x42\xd9\xc4\x4f\xff\x2d\x86\x1c\x08\x62\x9b\x55\xda\xe0\x0f\xf6\x74\xfb\x02\x8e\x73\x8b\x05\xdc\xb3\x8a\xea\xa6\x96\x3c\xc3\xfa\xaf\xc7\xb6\x92\x45\xa2\xa1\x22\xa9\x6d\xd2\xf0\x3a\x82\x4d\x72\xb0\xfe\x0d\xd7\x98\xdf\x5c\x4b\xb7\x5a\x87\x32\x4e\x76\x4a\x50\xa5\xff\x52\x54\x7a\xda\x8f\x8f\x88\xe6\xf3\x8a\xee\x49\xd5\x8d\xdb\x01\x26\x48\x85\x4c\xd5\x9d\x0e\xc9\x7b\xc3\xd5\x8d\x0a\xd4\x49\x1f\x08\x59\x07\x67\xce\xb1"}, +{{0xbf,0xc9,0x62,0x6c,0x91,0xf3,0x48,0xfd,0xaf,0x46,0x9d,0xef,0x23,0x02,0xe9,0xe3,0x8f,0x90,0x51,0xe7,0x34,0x9e,0x48,0xf8,0x50,0xcf,0x35,0x2a,0x83,0x31,0xa2,0x8b,},{0x4e,0x81,0x93,0x06,0x1c,0x9d,0x65,0xa8,0x2b,0xcb,0x25,0xda,0x08,0x9b,0x4a,0x80,0xba,0x41,0xb3,0xdd,0x2f,0x8e,0xd1,0xdc,0x81,0xe1,0xcf,0xd0,0x3c,0x84,0x91,0x15,},{0x66,0x02,0x42,0xc1,0xdc,0xf3,0x29,0x13,0x69,0xc6,0x5c,0x9d,0x7f,0x89,0x87,0x2e,0xab,0x48,0x22,0x00,0xe3,0x44,0xb2,0x96,0xe3,0x36,0xa0,0xa2,0xe6,0x31,0xfa,0x79,0x60,0x24,0xb6,0xe1,0x11,0x9c,0x27,0xd5,0x22,0x64,0xa4,0x98,0x15,0xdd,0x78,0x19,0x27,0xa7,0xdf,0x46,0x7e,0x88,0xb8,0x01,0xe6,0x84,0xfc,0x60,0x22,0x96,0x25,0x0e,},"\x2f\x11\xf4\x0b\x2a\x19\xf6\x40\xc0\x04\x4c\x7b\x13\x96\x80\xc3\xc3\xb6\x9f\x00\xff\x9f\x6a\x41\x86\xfd\x7d\xed\x56\x9c\x1d\x8c\x57\x20\xf1\x9d\xd3\x5c\x78\x16\xd0\x8a\x94\xc0\x82\x04\xe4\x76\x43\xe2\x64\xd4\x25\xe2\x1c\xef\xb8\x31\x29\xc9\x09\xa3\xd7\x8c\xaf\x72\xc4\x6b\xf1\xa7\x29\x76\x5e\xf4\xb8\xca\x80\x3f\xda\xf8\x05\x2f\xfc\x6c\xc4\xa6\xb5\x79\xa1\x60\xb7\x03\xb1\x53\x55\xc6\xfc\xd3\xb9\xa2\xec\xbc\x26\x7e\x60\xdd\x59\xf6\xa2\xb1\x94\x20\xe5\x57\x27\xa8\x0b\x0b\xb6\x41\x67\xc8\x3b\xa0\xc8\x05\xde\xed\x49\x1d\x93\xe7\x23\xf3\xb4\x32\x63\xd1\x74\x20\xb8\x5b\xe8\x6c\x16\x5c\x55\x27\x79\xdb\x96\x0e\x0a\xa9\xeb\x4d\x9f\x3a\x16\x4a\x5a\x21\xfa\xb3\xf5\x09\xa8\xf0\x19\x9a\x69\x43\xc4\xb2\x23\xcf\x9d\xac\xa7\xe1\x10\xe0\x56\xa8\x1d\x9c\xe0\xe0\xc0\x2a\xc2\x65\xee\xac\x05\xec\xd8\x44\x48\x46\x8a\x4d\x12\x2b\x87\xa3\xe0\x4c\x28\x37\xe4\x3d\x21\x27\x04\xfd\x41\xe7\xf3\xd1\x98\xa2\xe7\x6b\xec\xa0\xe7\x02\x9c\x43\x2a\x06\x54\xec\xd4\x4f\x98\x4c\x5d\xf0\x67\x41\x96\x4d\x83\x72\xc8\x6e\x16\x2a\x8c\x54\x18\x84\x9b\x41\xe5\x71\xfe\xb8\x3e\xb4\x2f\xbb\xcd\xdb\x8a\x08\x21\x43\x90\x9e\xaa\x50\x12\xb9\x79\x93\x1d\xc7\xe3\xcc\xcb\x44\xc7\x91\xe0\x4b\x80\x65\xee\x63\xf0\x56\x1d\xa1\xbb\xf3\x7b\xf6\x50\x34\x77\x87\x9c\xfb\xaf\x6d\x9d\x7d\x9a\x74\x75\x55\x3f\x53\x53\x5f\x84\x7a\x76\xdc\x3b\x2b\x7a\x3d\x1d\x47\x0b\xbe\x17\x12\x4a\x88\xe0\x3f\xe9\x94\xba\x10\xc2\x42\x21\xe3\x9e\x3d\x0f\xf5\x3c\x79\xe2\xfa\xaf\xa1\x90\x12\xd5\xef\x19\x2b\xc6\xd5\x26\x0b\x66\xf9\x97\xb6\x44\xcf\x48\xd9\x9f\x38\x99\xd7\xc4\x85\xe6\x84\xaa\x1e\x6e\x30\x85\x5c\xf7\x5c\x2d\x80\xc7\xa3\xee\x43\x54\xfe\x13\xc6\x76\x09\x1c\x86\x67\x37\x3d\x30\xe6\x0f\xf8\xe0\x9f\xed\xef\x17\x5a\x1a\x87\x39\x5f\xef\xa0\x72\x2b\xf6\xc0\x1c\x65\x55\xcf\xf0\x68\x89\x2a\xfe\x94\x86\xcb\x1f\xcc\x5f\xb6\x64\x1e\x82\xd8\x70\x79\xba\x5d\x7a\x9c\x13\x93\x55\xd6\xc1\x4c\x50\x7d\xbd\x59\x47\x24\xb5\x53\x51\x10\x09\x65\xbe\x9e\x5d\xbf\xa7\x70\x88\x78\xc4\xb2\x9f\x4d\x54\xc2\x17\x74\x6e\x32\x6a\xb2\xa5\x4f\x99\xb8\x81\xd7\xda\x5b\x11\xed\xb0\x8a\x6d\x79\xd8\x85\x69\x1b\x1f\x70\x85\x51\x73\x10\xb3\x09\xcf\x9b\x1b\x71\x4a\xab\xc5\xc1\x7a\x50\x9b\x14\x0b\x89\xb3\xf9\xdc\xee\x50\xca\xb4\x41\xbf\x5a\xd3\xbb\xc2\x99\x90\xf6\x27\x40\x61\x70\xa7\xa1\x0f\x2d\x47\xdf\xc9\x25\x61\x54\xf9\x62\x30\x8e\x76\x9a\x2a\xb1\xb2\xa0\x0e\x27\xe3\x27\xf0\xd1\xfa\x16\x4d\x1e\x38\xea\xd5\xce\xaa\xe2\x38\xba\x52\x6f\x54\xb8\x1b\x45\xde\xa6\xc8\x97\x41\x86\xb1\xb6\x72\x5f\xa4\xc8\x3e\x62\xf3\xe2\x54\xf7\x29\x87\x1b\xda\x4d\xc4\x44\xbc\xe7\x8f\x09\x03\xfa\x31\x8e\xaa\xc8\x22\xa9\x55\x32\xab\x01\x9e\x9c\xfc\x56\x19\xe2\xc2\x06\x7f\x25\x8f\x43\x75\xd2\xe0\x22\x2e\xa5\xbf\x96\xa2\x53\xa2\xa3\xfa\x9e\xea\x02\xc3\xee\xcc\xb0\x28\xc7\x6b\xc6\x0d\x38\x29\x8b\x95\xb9\xaf\xe6\x60\x31\xb1\xa2\xa2\x61\x52\xfd\xaa\x7e\xf4\xf8\x37\xab\xb5\x11\x85\xdf\x8b\x2e\xf8\x5a\xd2\xc9\xbe\x6d\xfb\xa7\x5e\x37\xdc\x7d\x12\xe1\x78\x7f\xc5\x5f\x86\x6f\xd0\x66\xf1\x22\x91\xdf\xf1\x97\x6a\xfc\x10\xda\x91\x31\x01\xe7\x04\x95\xd8\x78\x33\x48\xd6\x11\xb0\x11\xec\x67\x1c\x0d\xa7\x37\xbf\x96\x2c\xdc\xc9\xe4\xa8\x00\xb5\x13\x93\x5a\x56\xd0\x84\xea\x64\xa7\xd4\xe8\xe9\x9e\xe9\x44\x0a\x73\x61\x32\xe4\x2c\x90\x95\x03\xc2\x22\x4a\x14\x1b\x25\xce"}, +{{0x39,0x3b,0x76,0x94,0x82,0x37,0x5b,0x82,0x14,0x27,0xa6,0x6d,0x16,0xe4,0xf5,0x51,0x85,0xb7,0xa3,0xb7,0x33,0x8f,0x1a,0x06,0xf6,0x7c,0xdf,0xa7,0xe3,0x5c,0x54,0x1c,},{0x84,0xaf,0xd7,0x06,0x78,0xff,0xa8,0x5a,0x9f,0x65,0x74,0xcb,0xcf,0xe3,0xb1,0x5d,0x04,0xa9,0xfd,0x15,0x01,0x6f,0xf8,0x55,0x0a,0x98,0x7c,0x4b,0x95,0x1c,0x71,0x22,},{0x31,0xf9,0x8c,0x0a,0x08,0xfd,0xa8,0xe7,0x35,0xb5,0x73,0x66,0xaa,0x1b,0x83,0xb9,0x3d,0xae,0x63,0xb5,0x81,0x0c,0x82,0x1d,0x99,0xcb,0x39,0xdf,0x52,0x1f,0xea,0xc0,0x7f,0x3c,0x41,0x0b,0x27,0xba,0x33,0x07,0x75,0x7d,0x60,0x49,0xf2,0x24,0x54,0xfb,0x6d,0xe9,0xe2,0xc3,0xc2,0x43,0x8d,0x68,0x31,0x90,0x97,0xd1,0x12,0xcf,0xdb,0x07,},"\x8a\xe8\x05\x3e\x03\xbe\xbe\xae\x54\x40\x43\xb8\x41\x4b\x38\x53\x64\xad\xd1\x67\x37\x37\xcf\x8a\xb2\x01\x93\xd4\xaa\xbc\x8a\x78\xe1\xd6\x9b\x9c\x7e\x52\x72\x9e\x69\x30\x78\x06\xe9\x27\xce\x38\x07\xb0\x7c\x68\xc8\x33\xc4\xfc\xf1\x6d\xb1\x5e\x7d\xce\x60\x4d\x17\x98\x91\x5f\xd4\x21\x16\x89\xb4\x86\x46\x42\x50\x2d\x38\xe9\x1b\x19\x97\xb7\x18\x23\x31\x8b\x69\xab\xe5\xbe\xd6\xf5\xe3\x01\x5b\xfb\x22\xdf\x30\xdb\x37\x1f\x22\x60\xc5\xc2\x2e\xba\x60\xdf\x39\xb3\xed\xd3\xc4\xd7\xa1\xe1\x11\xcd\x9b\x8a\xa4\x6f\x67\xbd\x0c\xf3\xa7\x17\xaf\x06\xec\x0c\xe5\x67\x02\x8e\x06\xe4\x79\x79\x34\xad\x69\xb1\xf5\xbe\x44\x0f\xf3\x7a\x8a\x03\x4b\x15\x33\xfa\x94\x64\x24\xac\x59\x54\x00\xad\x27\xd3\xbe\x76\xdc\x89\xba\x9d\x6c\x49\x93\x9a\x09\xf2\xe4\x01\xc8\xf2\x0f\x7f\x7b\x4b\x9e\x63\xb9\xd5\x52\x01\x53\x4a\xb4\xcc\x7b\xe8\x85\xf0\x43\x2a\x2c\x66\x73\xd2\xe7\x65\x19\x4d\xff\xd9\xb6\x09\x6d\xd2\xb2\x84\x39\x18\x75\x09\x59\xa8\xdd\xe4\xa3\xab\x40\x7e\xb2\xf7\xe1\xa4\x9c\x25\x97\xe3\x08\x05\xf8\x48\x0d\xd0\xcc\x82\x72\xa3\x20\xc0\x0a\xa2\xb2\x10\xf5\x76\xe4\x25\x77\xd3\xaa\x41\x97\x03\x69\x7c\xa4\x06\xd4\x3a\x1a\x4f\x99\xb0\x73\x36\x64\xf6\xd6\xb2\x40\x3c\xba\x1b\xdc\xc5\x1f\x54\x1c\xf2\x42\x36\x07\x05\x70\x54\x07\x55\xc7\xa8\x63\x1f\xcc\x2f\x18\x93\x8f\xa1\x1b\xc2\x91\x15\x5b\x39\xd7\xa7\x62\xa1\xff\x4d\xca\x97\xb4\x48\xf7\x0e\x2d\x3d\xe4\x47\xcb\x08\xf9\x18\xea\x20\xcb\x43\x3f\xa1\x15\xe3\x08\x80\xc9\x6c\x8c\xf5\xf0\xeb\xbc\xf4\x82\x30\x9d\xb6\xdc\x1f\xb6\x4e\x17\xc0\x4d\x7c\xdf\x7a\x90\xf4\x01\x4d\x15\xae\x76\x96\xb4\x44\x23\xb0\xba\x08\x4e\xed\x4d\x3f\xb2\x8c\x1e\xfb\x39\x82\x8a\xca\x2f\x40\xca\x6d\xf3\x42\xc2\x0e\x95\xf8\x00\x6b\x27\x67\xa8\x3f\x50\xc3\x1f\xcc\x15\x81\xa0\x97\x53\xe7\x82\x91\xf0\xd9\x93\x1d\x99\x2a\xd3\x60\x44\x73\xce\xb8\x85\xec\xbe\x78\x57\xcc\x52\xad\x55\x85\x33\x4d\x14\x85\xd0\x22\xe1\x06\xb7\x1c\x29\xbd\xfc\xf2\x3e\xe8\xa4\x75\xdf\x2c\x09\x05\x32\x35\x6a\x6f\xfc\x02\x23\x23\x17\x98\x8a\x2c\xbc\xfb\xc2\xa3\x6b\x4b\x48\x3c\xb4\x45\x10\xe8\x55\x99\xb6\x12\x59\x6b\x62\x65\x72\xb0\x99\x6d\x8a\x61\xc0\xee\x3e\xff\xf1\xf7\xc7\x1c\x05\xfb\x5a\x8d\x8c\x5d\x09\xd9\x24\xeb\xaa\xc8\x80\x04\x51\xc9\xdb\x24\x56\x71\x0a\x27\x9d\xfe\x2d\x22\xf6\xae\xa9\xde\x31\x80\x1d\xc7\x42\x53\x43\x62\xb0\xe8\x10\xe9\x9e\x84\x1d\xbb\x7f\x0c\xf9\xaf\x1a\xef\x54\x2a\x52\xc7\x76\xcc\x51\xf2\x87\x36\x8f\xbe\x6a\xd6\x51\xfa\xd5\x78\x7e\xf7\x7c\x73\x53\x5f\x3d\xfb\x36\x18\xcc\x8f\x0d\xbb\x54\x9d\xdc\xa9\xb9\xbf\x91\x13\x5a\x34\x56\x00\x1a\x46\x21\x5a\xde\x38\x8e\x7c\xeb\x9f\xcd\xfd\x0d\x2d\x0a\x03\x56\xaf\xbe\x2c\xec\x1c\x2e\x78\xb4\xd9\x98\xd4\x55\x4f\x46\x21\xf1\x15\x1d\xd3\xff\xd3\xba\x4c\x0b\xc8\x52\xf3\x11\x75\x8c\x5d\xca\x42\x5d\x18\xba\x15\xa8\xd6\x7c\xa4\x01\xd0\xe6\xcf\x28\x0c\xb8\x83\x84\xa2\xda\xd4\x9f\xae\x39\xba\x2a\x77\xb4\x67\xb3\x23\x8a\xa2\x8c\xfd\x13\x7e\x5c\x5c\x0f\xf9\x00\x0f\x8b\x06\xa2\x19\x2e\x16\x29\x20\x69\x22\x65\xdb\x24\xab\x6a\xed\xe5\x35\xe3\x1c\x20\x93\xbe\x57\xeb\xf8\x80\x5d\xf1\x78\x89\x14\xf3\xa8\x84\xf8\x84\x17\x90\x15\x80\x8d\xb4\xd3\x02\x0f\x3e\x78\xbc\x34\x28\x5d\x23\x37\x62\xe8\x99\xeb\xff\x28\x42\x82\x15\xe2\x44\x40\x4d\xe2\x91\x72\x8f\xbf\x41\x24\xce\x5b\x24\x35\x26\x0a\x8e\x34\x11\x80\x07\x5a\x56\x51\xe6"}, +{{0x26,0xcb,0xc2,0x51,0x0e,0xe6,0xea,0x39,0x0a,0x2c,0xb9,0x48,0xa0,0x15,0xd1,0x31,0xab,0xf4,0xc0,0x95,0x49,0x15,0x62,0x0b,0x78,0x16,0xae,0xcf,0x4e,0x11,0xda,0x6d,},{0x14,0x5e,0x8d,0xd2,0x2b,0x44,0x00,0x28,0x9d,0xaf,0xb6,0x26,0xd9,0x5a,0x94,0xc2,0xf3,0xb6,0x9c,0x65,0x19,0x77,0x17,0xcb,0xdc,0xd8,0x50,0x98,0xc5,0x49,0x21,0x07,},{0x67,0x10,0xd0,0xdd,0x00,0x54,0x5b,0x44,0x4c,0xf7,0x14,0xb7,0x91,0x44,0xfe,0x79,0xf3,0x8c,0xb1,0xc0,0xf5,0xb7,0x42,0x48,0xd4,0xf0,0x1f,0xe3,0x60,0x11,0x7a,0x26,0xff,0xed,0x4a,0x3b,0xf2,0x13,0x23,0xb2,0x8a,0x39,0x3a,0xe9,0xde,0xe0,0x7d,0x69,0xe5,0x83,0xe3,0x16,0xc6,0xa5,0x73,0xd3,0x7c,0x64,0x4a,0x8d,0x62,0xc4,0x05,0x06,},"\x9c\xeb\xe2\x4b\x4f\x8a\xde\x86\x43\x0e\x27\x9a\x3c\x43\x3e\x4a\xe1\x7e\x00\x88\x52\xa2\x4f\x08\x69\x0c\xbc\x3d\x75\xe3\xb7\xf2\x00\xda\x89\x7c\x25\xf7\x48\x3b\x37\x63\x7d\x4b\xc1\x10\x08\xd9\x22\x4c\xd5\x81\xfb\xc0\x38\xad\xad\xa0\x2d\x27\x1e\xd2\xa5\xd2\x85\xd8\x43\xa0\xf8\xb7\x9e\x37\x94\x5d\xc3\x5b\xc2\x64\xbe\xcd\x80\x43\x07\xe1\xd4\x42\x18\xa6\x43\xe4\xb5\x9a\x93\x11\xde\x98\x5d\x24\xb4\xc2\x6f\xb1\x46\x03\xbe\x5d\xba\x18\x39\xee\x0c\x8d\x2e\xde\x6c\xb5\x0a\xf6\x7c\x80\x45\x19\x03\x7b\x1b\x16\x63\x31\x8c\xfc\x6e\x75\xd0\xf0\x51\xdb\xb5\xd3\xea\xf3\xaa\xd1\xf7\x8e\xf0\xcf\xf4\x8d\x5c\x55\xb2\xfd\x25\xdb\x15\x39\xd0\xf0\x2d\xae\x9f\x25\x14\x8a\x8d\x33\x8b\x97\x87\x9b\xbd\x39\xdf\x96\x1a\xa2\xc3\x96\x31\x5a\x2a\x86\xcc\x78\x35\x81\xe6\x7e\xa8\x44\xac\xfe\x86\x45\x42\x8a\x27\xb8\xd3\x2e\xa3\x06\x4e\x3b\xf6\x2d\xcf\x58\x01\x0e\xc4\x34\x88\x62\xfa\xc2\x5e\x3d\x9f\xcd\x4e\x5d\x65\xbe\x59\x90\x5d\x81\x6d\xfb\x96\x49\x92\xba\x7a\xce\xef\x8c\x20\x75\xa3\x12\xe5\xff\xc4\xf9\x53\x0e\xa2\x0f\x77\xf9\x3e\x81\xcf\x8a\x01\x9d\xc3\x94\x56\x34\x36\x4b\xab\xf7\x97\x72\x04\x5a\x0d\xba\xa7\x7c\x47\xa2\x2b\x77\x22\x3b\x70\x4d\xeb\xd2\xd0\x03\xf6\xa5\xc7\xbf\x6b\x19\xcd\x2c\x49\xb6\x14\xfd\x4d\x47\xfd\x25\x1f\xe6\x22\xcb\x98\x17\x85\xc1\x46\xbd\xb7\xc1\xd2\xea\x02\xb1\x16\x92\x3b\xf9\x8a\x1a\xfb\xb7\x85\x8a\xdf\x2d\xf9\x38\xa7\x90\xec\x1f\x90\x74\xad\xb8\xd1\xaf\xb5\x63\x3f\xa9\x61\xa8\x47\x64\x01\x0d\x3b\xde\xd1\xc0\x33\xd2\x5a\xbd\xb4\xb0\x0f\xb0\x5e\xd7\x64\x0f\xae\x61\x87\x9d\xf8\x8f\x0b\x09\xe3\xab\xd0\x57\xb9\xa5\x21\x08\xa9\xbc\x98\x5f\xb7\x3a\x5f\x29\xd8\x4d\x1c\xa6\x92\x1b\x62\xf1\xb7\x03\xc7\xee\xb4\x81\x5d\x9d\xd6\xd0\x66\x73\x8d\xb1\x18\xba\xf6\x1b\x04\x22\xf3\x88\xf1\xbf\xc9\xe3\xa9\xbe\xd8\x3a\x1a\x72\x7d\xcc\x26\x6a\x99\x88\x36\x48\x46\x80\x7f\x4d\x55\x18\xbc\x2e\xdd\x0e\xcb\x34\x13\xc2\x6f\xd0\xc7\x9b\x75\xd8\xcb\x5b\xcd\x85\xc0\x6f\xcc\xea\x4d\x03\xfb\x89\x88\xdf\xf3\xed\x0c\xc9\xdb\xae\x78\xd6\xae\x8d\x5f\xc4\x02\x46\x17\xa2\x3f\x52\xbd\x61\x53\x85\xd4\xee\xe0\x8f\x91\x34\xeb\x3b\x25\x0c\x8f\x82\x2b\x47\xd9\x1e\x8c\x4d\x4c\x29\x29\x80\x16\xe6\xfc\x81\xf1\xf1\x09\x92\x53\xd7\x94\x5e\x07\x98\x95\x5d\xa0\xdd\xe1\x4e\xbb\x93\x4e\xcf\xae\xea\xba\xe8\x78\x83\xe1\xcc\x39\x80\x67\x40\x0f\xe4\x62\xa2\xc4\xe9\xf2\x32\xdb\x5c\xdd\x61\xeb\xa9\x49\x18\x8c\xf0\x1b\x23\x8b\xe7\xad\xa9\x38\xf0\x02\xdc\x3a\xe3\x1f\xdf\xd4\x25\xc8\xd4\x6e\xa0\x32\x32\x3a\xaf\x20\xdd\x3d\xe2\x50\x7d\x36\xbb\x45\xfb\xb9\x1c\x40\x96\x9a\x9e\x5d\xa2\x0f\x7f\x93\x6b\x0f\x4b\x13\x7b\x62\xfe\x2b\xa3\xa6\x67\xbc\x03\x62\xd9\x3f\xc5\x0d\x3f\x22\x95\xe1\x67\xfc\xba\xb0\xfb\x3a\x39\xb7\xcb\x02\x4b\x57\x8f\x94\x90\xf7\x34\xb2\x8c\x9c\xcf\x71\x92\xf1\x83\x94\x7d\x5a\x51\x3e\xfa\x49\x16\xe4\xd8\x2b\x2a\xb4\xba\x7e\xc2\xff\xba\x21\x3c\xe8\x2a\xd6\xed\x3b\x10\xe4\x85\x53\xe7\x33\xc9\x40\xaa\x9b\x9c\xe7\x13\x37\xc6\xc2\x80\x5d\xfb\x8d\xd6\x61\x8b\x6d\x40\x90\xa3\xd6\xcc\x96\x3e\xce\xa2\x6d\x1c\xdc\x2b\xf5\xac\x99\x9c\x11\x27\x61\x68\xa9\x31\xd8\x16\x46\x9d\x79\x08\x3c\x24\x08\x1a\x50\xdc\xbd\x22\x27\x52\x38\x52\x67\xce\x1b\xfc\x1d\xb7\x6b\x15\x54\xad\x57\xe3\x47\x52\xb7\xf8\x98\x31\x47\xc1\x16\xd4\xa3\xfa\xe6\xf6\xd5\x7e\x65\x4f\xed\xd7\x37\x8d\x2b\x49\x89\xea"}, +{{0xb1,0xf5,0x9e,0x3c,0x23,0x80,0xd7,0xaa,0x41,0x4d,0x0b,0xf9,0x08,0x93,0xa3,0x8d,0xdd,0xfc,0x29,0x38,0x59,0x30,0x3d,0x16,0xf0,0x0d,0x9e,0xae,0x6c,0xb3,0x45,0x0e,},{0x84,0xe3,0xf5,0xf7,0x2f,0x19,0x09,0x5b,0x0f,0x53,0x38,0x48,0xa5,0xa9,0x1d,0x0f,0x07,0x43,0xb8,0xe3,0xa3,0xe2,0xf5,0x2f,0xcb,0xd7,0xeb,0xe7,0xc5,0xb5,0xa9,0x98,},{0x60,0xaf,0xc1,0xe9,0x91,0xfd,0xd2,0x7c,0xc4,0x72,0xb9,0xac,0xc9,0xd4,0x05,0xb4,0xd2,0xb9,0x13,0x08,0x92,0x90,0xb3,0x11,0xc4,0xfa,0x89,0x1a,0xe2,0xee,0xa0,0x56,0x71,0xfd,0xe7,0xa0,0xef,0x86,0x55,0x7b,0xd8,0x67,0xd1,0xc0,0xb7,0x47,0xca,0xf3,0x52,0x29,0xd6,0xef,0x52,0x8f,0xe3,0xe0,0xd0,0xbc,0xf6,0x30,0x38,0x0e,0xa9,0x0e,},"\xc6\x17\x4c\x9a\xd3\x68\x5d\xd6\x48\x63\x60\x17\x83\x7b\x8d\x99\x22\x00\x31\x9e\x9a\x5a\x0d\x26\xd9\x4d\x2d\xa7\x5e\x2c\x3a\xff\x46\xf4\x2d\x7b\x3a\xba\x47\x2b\x7f\x86\x0b\x0f\xe1\xf6\x95\x52\x97\x31\xfd\xc8\xcf\x0d\xa7\x05\xd1\xd0\x9a\xca\xd0\x4f\x01\x08\x37\xec\xef\x41\x9d\x57\xe9\xea\x6c\xac\xf1\x68\xc5\x21\x56\x96\xf4\x71\xf3\xca\xa8\x97\x60\x7c\x62\x9d\x44\x3d\xe0\x99\xd3\x17\x53\xc2\x46\x77\xd8\xd7\x5f\x4b\xf1\x72\x46\x81\x8b\x58\xad\xc0\x42\x4b\x76\x2a\x19\x1e\xf3\x9a\x70\x76\xa5\xad\x12\x61\x4c\xf5\x4c\x47\xeb\x09\x08\xbb\x86\x65\x18\xc5\xfa\xc1\xca\x2d\x2e\x5b\x65\x75\x20\xa2\xb3\x69\x5c\x6f\xb3\x60\xf1\x6f\x4a\xb3\x57\x99\x8e\x4c\x0e\x97\x23\x1d\x6f\x89\xc9\x68\xdc\x29\xec\xc1\xaa\x91\xfa\x0d\x75\x43\xb5\xd2\x24\x7b\x0d\x85\xe4\x87\x43\xab\x7c\xc8\x15\xcf\xda\xa8\x2b\xf6\x8c\xa6\xd3\xe2\x25\x0b\xfd\xa2\x70\x24\xd6\x1b\x47\x4c\x6b\x81\x54\xac\x8d\x1b\x5a\x36\x20\x97\x82\x51\x5c\x16\x46\x68\x0d\x37\x06\x9b\x8b\x44\x12\xf9\x51\xb0\x25\xa4\xd5\x43\x62\x5d\xd0\x22\x90\xbf\x03\xc6\x73\x46\x13\xf9\x9b\x7a\x4c\x3a\xf5\xc5\xf9\xe9\xac\x34\x74\x46\x5e\x64\x84\x23\x01\x8d\x40\xa6\xad\xbe\x88\xa3\x30\x1d\x3d\x25\x9b\x04\xee\x44\xcc\x05\x62\xee\x0d\xed\x4f\x5e\x26\xad\x97\x7a\xb5\x63\x1f\x85\x76\x8d\xbc\xe5\x3f\x61\x6c\x02\x9a\x8b\x8f\x93\x3e\x2a\x92\x64\xb1\xc8\x1f\x51\x7e\x9f\xf5\x8a\xb9\xf4\x5a\x23\xee\xed\x42\x04\x35\x8f\x8f\xff\x0c\x8f\x97\x5e\xf1\xdf\xa5\x77\x6a\x5f\x77\x93\xba\xe2\xf2\x81\xd7\xb0\xcb\xef\x24\x0b\x3f\xc6\xbe\x05\x88\x21\xea\x2b\x80\x0f\xff\xe5\x5a\x7d\xe0\xaf\xc9\x3e\xde\x9c\x60\xc8\xde\x00\x5a\xbb\x9a\x2c\x88\xf4\xe6\x1e\x8d\xeb\x31\x70\xf1\x07\x8a\x36\xe2\xd8\xf2\xa5\x82\x39\xbd\xee\x49\x6e\x90\xd1\x37\xd2\x11\x0f\x0a\xd8\x57\xa8\x8b\x35\x27\x66\x4f\x78\x19\x39\xe0\xb2\xf7\x66\x34\xff\x9f\x6c\x57\xe1\xc4\x3f\x58\x24\x31\x71\xcd\x86\x2e\xf4\x28\x45\x76\x17\x2a\xf1\xf6\xc3\xbd\x37\xd5\xd7\x4b\x28\xa7\xa9\x86\x98\xbd\x74\xe5\x7b\xbc\x14\x2e\x67\xf7\x03\xf9\xd6\x2c\xde\x76\x1a\x02\x26\x8f\xec\xb3\x43\xfc\x01\x41\x88\x36\x41\x4f\x12\x22\xca\x24\xbc\xdd\x69\xd0\x05\x90\x1d\xa2\xa0\xf9\x44\x65\xe4\xd4\xba\x68\x89\x88\x16\xbf\x7e\x3e\x4b\xb7\x9c\x8c\xa5\x99\x7f\xba\x9a\x8d\xf8\x4f\xaa\x2d\x24\xb0\x44\xc4\xea\x61\x02\x9a\x46\xcb\xa7\x03\x42\x1e\x36\x1d\xfa\x52\xca\xaf\xf3\xbb\xaa\xb7\xfd\x75\x3f\x28\x56\xd7\xc0\x83\xae\xb9\x76\x8d\xa1\x1d\x82\x1e\x2d\x30\x9f\x7a\x73\x5c\x39\x96\x92\xda\xc2\xf2\x62\x84\x6b\x89\x1b\xf6\x46\x1a\xf2\x3c\x8c\x7c\xe1\xd4\xd9\x03\x2c\x3c\x14\x0f\x73\x9e\x55\x84\xc3\x6f\x05\xea\xf4\x34\x9f\xf4\x54\x5f\x28\x3a\x4e\x0f\xea\x49\x43\x0a\x1b\x18\x0d\x08\x71\xe3\x74\x2b\x88\xcc\xb5\x91\x12\x4f\xc4\x27\xed\x67\x3b\x5f\x27\xb0\xb0\xa6\xf5\x4a\xf2\x2b\xa4\xa6\xd1\xc6\xc1\xdb\x2a\x1f\xca\xa6\xd8\xa0\x30\x8b\x77\xef\x2d\x0c\x61\xbb\xf5\x1b\x95\xf1\xe8\xb6\xab\xc5\x04\x1d\x97\xb6\xb6\xf1\xb5\x69\xb3\xf6\x3c\xec\x05\xcb\x56\x7a\xae\xa1\x06\x72\x70\x96\xee\x8a\x9e\xa8\x7b\x88\x04\x90\x1f\x7e\x88\xa7\x40\x9c\x66\xf1\x52\xde\x9d\xbf\xcb\xe3\x19\x52\xe6\xfd\x83\xb2\x87\x7a\x77\x5f\xae\x42\x5b\x38\x51\xe0\xef\xf8\x79\x2f\xfb\x38\x48\xf8\x4a\x65\xcc\x31\x72\x53\xb2\x72\x47\x5e\x71\x7e\x49\xe9\xc6\xff\x6b\x78\x59\xd1\x1b\xba\x7c\x44\x28\xc8\x2d\x17\x89\xe0\xdc\xa5\xbc\xad\xca\x2f\xdb\x25\x9e\x98"}, +{{0xdb,0x46,0x1b,0x9f,0x70,0x7e,0xb2,0xcd,0x77,0x48,0xc4,0x4c,0x99,0x56,0x2f,0x13,0x02,0x39,0x74,0x89,0x35,0x3d,0xf5,0xf3,0x03,0x79,0x7f,0xe0,0xd0,0xb5,0x8d,0xe1,},{0x63,0x51,0x16,0xda,0x8b,0xa5,0xa3,0x6a,0x37,0x77,0x28,0xe2,0x86,0x18,0xe7,0x5c,0x55,0x92,0xae,0xcc,0x18,0xe3,0x40,0x11,0xc4,0xc4,0x25,0x91,0x97,0x0b,0x73,0x66,},{0xdd,0x04,0x9c,0xa7,0x9b,0xeb,0x9e,0xac,0x32,0x5a,0xcf,0x44,0x67,0x2f,0xf5,0x78,0xa9,0x68,0x50,0x2f,0xe1,0xbc,0xf5,0xea,0x19,0xd5,0x2c,0x0f,0x67,0x78,0xc7,0xf1,0xc7,0xbb,0xf7,0x42,0x74,0x79,0x07,0x78,0x6e,0x60,0x81,0x23,0x91,0x1a,0x92,0x07,0x78,0xd2,0xf9,0x59,0x6f,0xe2,0x9b,0xe7,0xcc,0x28,0xfd,0x00,0x9d,0x7c,0x44,0x0e,},"\x1a\x2a\xc8\xc1\xb9\xea\x09\x9b\x83\x1a\x68\x12\xd2\xb4\x26\x13\x09\x05\x8e\xa5\x88\x3d\x70\xb1\xc6\x07\xb9\xcd\x3f\xdf\xdb\x86\xe7\x99\x02\xb0\xfe\x89\xe8\x0e\xa7\xc4\x78\x20\x76\x74\xb2\xd8\x03\xb0\xb9\xca\x14\x7f\xfe\x62\xe5\x94\xf5\x06\xc7\x96\xd6\x89\x97\xce\x48\x2b\x51\xa4\x6e\x49\xb4\xa5\xd8\x58\xcd\xea\xe2\xc6\xec\x9b\x69\x41\x98\xe6\x82\x2f\x0e\x33\xed\x57\xbe\xdb\x03\x35\xc7\x89\x0a\x72\xa7\xee\x3c\x23\x82\x3b\xe7\x9b\x7f\x94\x71\xe0\x33\xc7\x9a\xee\xd5\x2e\x57\x60\xfb\x0c\xcb\xb9\xd3\x8f\xde\xd8\xb4\x73\x83\xc1\x91\x03\xce\x44\x70\x58\x34\xc5\x9d\xdd\x86\xf7\x03\x39\x48\x61\x2d\x66\x62\xf5\x16\xce\x4e\x39\x9f\xf2\x03\x63\xcc\x72\x81\xa6\x9b\x2d\x5c\x30\x7b\x10\xb7\x04\x15\x01\x84\xec\xe3\x2f\x39\x0d\x77\x2c\xcf\xa7\x84\x83\xbb\x77\xa9\xfb\xa8\x44\x25\x36\x69\x84\x17\x1c\xc2\xbb\x60\xb0\xec\x6c\x62\x8d\x4e\x90\x30\x74\x6d\xac\x1c\xab\xca\x60\xf0\x56\x83\x81\x33\x46\xa1\xa5\xbc\x14\x72\x75\x49\x79\x5c\x1c\x92\x68\x69\xe1\xaa\x25\x09\x3d\x59\x1b\x43\xe0\x86\xe4\x3a\x04\xd1\x70\xd9\x42\xc4\x16\x5e\x1c\x5c\xe7\x6c\x3e\x64\x97\x3d\x91\x36\xf9\x32\x5b\xee\x82\x16\x82\xf1\x04\x3e\x95\x1b\x02\x76\x7f\x3f\xb4\x58\xd0\x24\x49\xad\xd3\xe8\xa6\x6e\x51\x6f\xdb\x1e\xd5\x80\xe0\x56\xe0\xf7\x8e\xe3\x3f\xd9\xee\x32\x80\x91\x2f\xae\x07\xfe\x1e\xa0\x25\x27\xcd\x00\x1d\x6f\x6f\x2f\x89\xee\x64\x9f\x51\x74\x14\xd5\x6f\x57\x35\x9a\x84\x68\x91\xf0\x22\x2c\x32\x1d\x7e\x70\x81\x79\x95\xa8\xcd\x8e\x94\x76\x0b\x6e\x74\x83\x2b\xab\x68\xd5\x5b\xc4\x64\x18\x84\x22\x1f\xd2\x9f\x12\x2d\x87\xa9\xa8\x68\xb6\xa6\x06\x0c\x87\xb2\x38\x2c\xf7\xbb\xdd\xa4\xcd\x6a\xaa\x1b\xbc\x8e\x6d\x63\x4a\xb5\x80\xc8\x65\xf5\xad\xd6\xa1\xd5\x4e\x61\xa6\x07\xdc\x2c\x37\xb0\x8a\x8c\xba\x6e\x61\x0c\x12\xcf\xeb\xef\x9c\x98\x9e\xef\x3b\x78\x2a\xcb\xd1\xbc\xec\x5f\x04\xe8\x35\xca\x10\x12\x98\xb5\xe9\xbd\xd8\x81\x3a\x71\xb0\xd4\x69\xfc\xf1\x27\x27\xd3\xde\x1c\x3f\x97\xdd\xbc\x6a\xb2\x65\x84\x40\xdd\x64\x21\x01\x9b\xc6\x8f\x35\x6d\x6f\x25\x53\x68\x65\x85\x1d\x92\xd9\x0f\xe9\x96\x9c\x3b\x7c\x35\xa2\xe8\x8c\xe1\x53\x47\x6e\xc3\x97\x3a\xf9\x35\x9f\x16\x77\xa4\xca\xf1\xcc\x48\x1c\x71\xbd\x90\x22\x8f\xf5\xfc\x6d\xd8\x3b\x8a\x69\x9f\xfe\x51\x49\x29\xf5\xc9\x5c\xb4\xf0\x4b\x00\xdd\x18\xa2\x87\x2c\x41\x86\x8d\x3b\xeb\x76\x49\x8d\xdc\x92\x34\xb6\x3f\x59\x9d\x70\x71\x80\x1d\xb2\xc2\x87\x8f\x7b\xef\x4f\xfd\xdd\x81\x32\x26\xf0\x6d\xb8\x4e\xb3\x02\x17\xa7\x18\x30\x82\xe3\xc1\x24\x2b\xb6\xd0\x1c\xd3\xa6\xce\x27\xbf\xf1\x6b\xfb\xfd\xd7\x5b\x7e\x51\x04\x31\x2c\x49\xc4\x3a\xad\xfc\xd5\xb4\xed\xba\x0f\xf5\x0d\x28\x90\xca\x3c\xd9\xcc\xa3\x3e\x4f\xc6\x94\xc0\x57\xc4\x7e\xbe\x1c\x20\xa4\xad\x11\x5f\x98\x5d\xc7\x44\x2c\x6f\x6d\xa7\xbe\x53\x0b\x69\x02\x28\x9c\xab\x9c\xa1\x39\xc6\xb2\x4c\xb8\x0f\xfd\xd7\x82\x32\x4e\x60\x2c\x45\x91\x0d\xb6\x3d\x8b\x5c\x44\xca\x29\xd2\x7f\x56\xdb\xf0\x01\x86\xba\x58\x3c\x34\xe1\x60\x31\xdf\x35\x75\x46\xb3\xab\x9a\x3d\xd6\x5e\x91\xd7\x12\x8c\x93\x91\x95\xe6\x46\xa0\xf0\xb8\x9b\xf5\xdf\x04\xba\x23\x3d\x6a\x12\xa2\x71\xf7\xe0\x4a\xa4\x5c\xda\x99\xb4\xa5\x5a\x21\xcb\xbb\x73\x85\x15\xe3\x2c\x56\xaa\xc2\x49\x62\x32\xb1\x00\x8a\x67\x61\xc8\x04\x5a\x1f\xe0\xf9\xa3\x64\x40\x47\xb5\x96\x6a\x58\xa6\x00\x46\x6c\x1b\x1d\x11\xdd\xad\x5a\xa5\x73\xc4\x3e\xbd\xa8\x87\xe1\x6a\x05"}, +{{0xf5,0xc0,0xa7,0xf8,0xf6,0x58,0x4c,0x5d,0x2f,0x2e,0x1d,0x08,0x10,0xe8,0xe8,0x61,0x03,0xe4,0xe2,0xd4,0x5c,0xf9,0xa7,0x21,0xd8,0xc4,0x7f,0x67,0x49,0x33,0x96,0xa4,},{0x3c,0x6d,0x6c,0xce,0x49,0x63,0x31,0x41,0x07,0x86,0x96,0x13,0x1a,0x8d,0x84,0xed,0x82,0x3f,0x30,0x66,0x4b,0x28,0x9a,0xf9,0xdd,0x30,0xc6,0x40,0x7f,0x6f,0x03,0x13,},{0xd4,0xc3,0x0a,0x48,0xc4,0x52,0x3b,0x1f,0x84,0xb1,0x4b,0x65,0x7a,0xf8,0xf8,0x59,0x75,0x5b,0xba,0x63,0x59,0x98,0x8b,0x67,0x5c,0x6d,0x85,0xdd,0xf3,0x54,0x62,0x82,0x0d,0xa4,0x76,0xd8,0x4f,0x6c,0x40,0x2e,0x65,0xb0,0x20,0xd9,0xe8,0xa2,0xc2,0x85,0xc1,0x67,0x08,0xae,0x58,0xd1,0xf8,0xdb,0xc6,0x57,0x82,0xa8,0x98,0xa6,0x65,0x08,},"\xd6\x8a\xbc\x60\x9a\x7a\x0c\xe2\x56\x69\x9e\xb1\x70\x43\xde\xfe\x1e\xb8\x22\xc9\x70\x8f\x65\x71\x8a\x06\x58\x1f\xab\x21\x10\xec\x2d\xb0\x92\x13\xbb\x9e\x0f\x36\x12\xce\x4a\x3f\x8f\xdb\xe7\x57\xa9\xf0\xeb\x2c\x3e\xba\x43\x8a\x90\x88\xb1\x8f\x6c\x5c\xaa\xbb\xe5\xc8\x2f\x7a\x9a\xb2\xfe\xcf\x0f\x58\x59\xd1\x75\xe1\x39\x26\x30\x33\x74\x24\x58\xf8\x2a\x6f\x38\x75\x6c\xd5\xbc\xdf\x9e\x07\x36\xdb\x2c\xab\x20\xa0\xcd\x3f\x0f\x1c\xdb\xea\x85\x56\xd8\x49\x09\x35\x8d\xd8\xf6\x9f\x0d\xac\xd4\x9a\xbf\x8a\xc1\xbf\xe7\x59\x40\xd6\x93\x9e\x6a\x55\x38\x5b\x5a\xce\x7c\xe1\xfd\xe1\x20\x67\x9a\xb6\xea\x7a\x89\xd1\x42\x68\xd2\x9f\xfb\x46\xdf\x10\x5b\xf3\x90\x92\x42\xc6\x60\x5f\x3e\x3e\x2a\xb7\x44\x89\x37\xd6\xdb\x2b\xa0\x54\xc7\xb1\x4f\x43\x2d\xb4\x1d\xc1\x8a\x5b\x95\x73\x36\xb7\xf5\x2d\x97\x8e\xc0\x3e\x7d\x57\x64\xe9\xbd\x2f\x4b\x68\x95\x8d\x93\x7b\xf2\x98\x23\xb2\x7e\xfb\x31\xe2\x5b\x43\x92\x5c\x4d\xac\xbe\x67\x18\xa6\x0f\xea\x3b\x32\x70\xe7\xb7\x6b\x0d\xe0\xe7\x0f\x7f\xa3\xc1\x2c\x21\x5e\xf7\x2b\x95\xdc\x1b\x52\x76\x23\x81\x79\xdf\xc5\x2f\xc4\x88\x59\x64\x9f\xa5\x82\xd0\x5a\x60\xdf\x68\x59\x9a\x1c\xee\xa6\x4f\x64\x12\xd3\xf8\x49\x8a\xe2\xce\xdb\x12\x42\x45\x88\x3a\x24\x0b\xc0\x85\x1f\x0e\x32\x49\x65\xbe\x12\x04\x86\xe1\xea\x89\xa0\x18\x2d\xfa\x8e\xab\xd3\xb8\xfa\x66\xa9\x9c\x51\x49\x13\x89\xf3\xc8\x3a\x3c\xdb\x42\x67\xf3\xe4\xdb\xc9\x8f\x0c\x44\x85\x6b\x04\x4d\xc8\x8d\x90\xee\xee\x84\x15\xbf\x73\xde\x17\x1a\xfe\x84\xbe\x90\x35\xe0\xdc\x4c\x80\xcf\x04\x22\x46\x9f\xe0\xc9\xbd\x1c\x6a\xa6\x54\xa5\x9b\x5e\x34\xee\xd3\x51\xcd\xa2\x87\x12\x69\xac\x47\x8e\x8d\x38\x2e\x74\x0e\x9a\xc7\xab\x4d\xdc\x4c\x0d\xef\x0a\xea\xb7\x97\xb6\xf1\xa4\x27\xb8\xe4\xa8\x49\x7a\x0b\x97\x97\xda\xdc\xd3\x5c\x41\x4f\xd5\x5b\x78\x31\x30\xf6\xcd\xed\x38\xa4\x4c\x1a\x89\x28\x83\x07\xeb\x84\x25\x48\x41\x37\xa8\xae\xdb\x03\x0d\x54\xb6\x16\xa8\x2e\x3c\x5a\xcf\xfb\x08\xd6\xcc\x1a\x61\x74\x5c\x29\xaf\xc6\x8a\x0c\x18\x38\xb1\x39\x15\x9c\x5f\xa6\x67\x4d\x66\xb9\xe3\x38\x11\x5a\xad\x4b\x1b\x47\x10\xaa\x5d\x95\x17\xbc\xf7\xe1\xcb\x12\xd4\xe6\xa5\x1c\x11\x78\x9f\xdc\xae\x9d\x9b\xbe\x78\xf6\x9a\x33\xe5\x2d\xf1\x83\x3c\x87\x6b\x02\x68\x7a\x40\x4f\xac\xad\x32\x84\x1c\xb2\xd5\x25\x54\xe7\xb8\xe2\x20\x9e\x3f\x88\xfd\x94\x8c\x1e\xcf\x83\x95\x7c\x96\xf4\x3b\x03\x4b\xed\xa6\xc4\x76\x09\x6b\xcb\x09\x30\x1a\xd6\x1f\x83\x67\xcc\x43\xe1\x56\x13\x18\x62\xb4\x2e\xce\x28\x5b\xec\x2d\xcc\x2d\x02\xd0\x94\xd0\x42\xa1\x60\x72\xeb\x22\xab\x98\x88\x01\x3b\xe8\x23\x71\x56\x94\x00\xec\x1f\x8e\xc7\xe7\x91\x08\xc4\x1b\x85\x33\x65\x26\x8f\xa4\xcf\xbc\x62\xc4\xac\x12\xcc\x98\xd2\xec\x38\xa8\x7d\x60\x85\x85\x95\x67\xc0\xf2\x7d\x6d\x43\x1a\x04\x6e\x88\xa9\x81\x55\x58\x66\x07\x05\xfd\x05\xeb\x06\xc6\xc0\x5e\x5b\x7d\x62\x34\x7c\xee\xe2\x7d\xff\xed\x71\x41\x54\x0d\x60\x8c\xb9\x75\x07\x5a\x96\x44\xac\xc6\x32\x84\x39\xf9\xfa\x68\x2b\x22\x6b\x18\x61\x54\x54\x90\x11\xc3\xb0\xf0\xff\x4f\x74\xca\xa7\x1c\x19\x44\xe4\xcb\x83\x6c\xe8\x51\xd9\xb5\xd9\xe7\x27\xc5\x53\xe3\xc7\x23\xcf\x98\xc2\x73\xe5\x67\x5c\xab\x89\x9b\xb6\x6f\x46\x33\xa7\x6d\xea\x35\x73\x41\xf9\x83\xc5\x3d\x91\x58\xad\x31\x9a\xda\x75\x40\x8b\x41\xc0\x6f\x26\xb7\x43\x5b\x80\xdc\x3b\xc0\xaa\xf2\x2a\x83\x3d\xde\xdc\xd6\x78\x5c\x87\xd1\x96\xb0\xaf\x2c\x9a\x43\xd1"}, +{{0x1a,0xb9,0x46,0xc0,0xc1,0xae,0xbf,0x9c,0xa3,0x7c,0x2f,0x4e,0x2a,0x4b,0x33,0x7d,0x5b,0x1e,0xbc,0xcd,0x24,0x73,0x4c,0x9c,0xb2,0xa1,0x60,0x8c,0x88,0x1e,0x57,0x57,},{0x9a,0xfc,0x63,0xdf,0xce,0x0d,0x48,0x9b,0x40,0x90,0x7a,0xee,0xd6,0xdf,0xfe,0x4c,0xd8,0xef,0x5a,0x6f,0xfa,0x22,0x98,0x95,0x56,0x44,0x5c,0xbf,0x9b,0x35,0x19,0xc2,},{0xbf,0xab,0xde,0xa4,0x18,0x10,0xa5,0x3f,0x8e,0x52,0x7a,0xcd,0x66,0xec,0x10,0x6c,0xe2,0xae,0x1a,0x67,0xff,0x6a,0x9b,0x52,0x2e,0x0f,0x08,0xfb,0xbf,0x12,0x52,0x68,0x2c,0xb3,0xa1,0xdc,0xc8,0x75,0x60,0x19,0x44,0xcb,0x88,0x00,0x0f,0x72,0xe1,0x39,0x07,0x00,0x79,0x03,0xa7,0x7c,0xd0,0xdb,0x03,0x16,0xd4,0x19,0xac,0x38,0xc2,0x04,},"\x9b\xb0\x71\xb6\x2c\x04\x06\x4b\x0c\x96\xe2\x43\xdd\x19\x8c\x39\x71\x7b\x25\xc9\x94\x48\xc2\xc0\x02\xb8\x4a\x99\x20\x4c\x5a\x6e\x23\xb4\xb9\x12\x02\x86\x75\xbf\xdc\x4d\xf9\x3c\x5b\x2f\xb8\x08\x81\xa2\x3e\x0d\x44\xba\x18\xbd\xe9\x91\x21\xee\xe8\x6a\xdc\x6f\x84\x28\x19\xd6\xeb\xc7\xa2\x88\x99\x2d\xa3\x28\x58\x05\xa8\xb8\xb6\xfb\xcd\x22\x67\xb6\x86\xb3\xe1\xbf\x79\x60\xb4\x5f\x24\x4f\x85\x2e\x82\x49\x29\x44\xe3\xd6\x18\xbc\xc4\x51\x4c\x17\xf7\x22\xba\x49\xac\xa7\xf2\xf3\xbb\x4e\x91\xf9\x40\xe9\xce\xf0\x15\x65\x0c\x3e\x40\xb0\xc8\x55\xa1\x7c\x42\xf1\x1e\x3a\x34\xac\xc8\x52\x87\xdb\xe0\xf9\x09\x3c\x00\x37\x3d\x50\xc0\xb3\x06\x4a\x5a\x5f\x2b\x1e\x89\x20\x65\x17\x52\x82\x95\xfd\x87\x17\x03\xa8\xe7\x62\xb5\xe7\x6f\xb9\xb7\x47\x3d\x21\x49\xb8\x5b\x94\x61\xf5\x58\x7e\xd7\xe7\xfc\x8b\x50\xaa\x09\x87\x6d\xee\xb6\xe2\x37\x07\x85\x02\x14\x2c\xec\x6b\xdd\xc7\x01\x40\xfe\x1d\x1f\x16\x58\xd5\xd3\xe9\x10\xfd\x70\x36\xa2\xf9\x24\xb4\x99\xdb\x17\x56\xf7\xc8\xce\x0d\x5f\x0d\x04\x5b\x39\xbc\x81\xc5\xc2\xf1\xa7\x61\xf5\x2f\xf3\x93\xe0\x64\x9b\x8d\xb0\xbd\x88\x54\xbd\x02\x6b\xe2\xc7\xc3\xcd\x63\x52\x6b\xa5\xa8\x0d\x48\x33\x5f\x03\x38\x32\xd6\x33\x76\x07\x1b\x63\x08\xf0\x59\x60\xcb\x3f\xc9\xfa\xc9\x32\xed\xd8\x37\x6d\xae\x51\xf2\xc6\x61\xf7\x5b\x7c\x6f\x4a\xc8\x56\x75\x3a\xca\x62\x06\x28\x77\x60\x9f\xc4\xa0\xff\x60\x67\x02\x82\xc0\x5e\x88\x2d\x1a\x03\x5b\xf9\x89\x0c\xab\x29\x6a\xc7\xa8\xdf\x24\x4c\x56\xf4\x90\x25\x0f\x02\x00\x54\xb8\xaf\x51\xbe\x4f\xc3\x18\xbe\xba\x50\x62\x32\xbf\x45\xe1\x7f\x5c\x74\x0c\xf0\x9d\x37\x51\x5a\x8b\xc8\x94\xbc\x95\x5c\x8a\x46\x08\x77\xc7\x85\x4f\x8b\xe3\x63\xb2\x19\x33\xe1\x62\x87\xae\x0c\xb7\x0f\x22\x2d\x4e\x36\xb8\xb4\x24\x97\x55\x59\xbb\x4b\xfc\x8d\xd1\xd5\x1b\x3c\x0f\xaf\x4a\x53\xe3\x02\x19\x6f\x9f\xed\xb5\x32\x87\xd0\x93\x15\xdf\xff\xa2\xbc\x4b\x3a\xcf\xf1\x37\xf9\xa7\x6d\x68\x56\x21\x7f\x79\xcb\xb2\x54\x33\xfc\x97\x89\x9f\xd6\x54\x0f\x18\x08\x8e\x84\x41\x7e\x48\x33\xe4\xa9\x1a\xab\xa4\x65\x8a\xe9\xad\x7f\x76\x0d\xd9\xc5\xb7\x19\x1a\x0d\x3c\x05\x54\x1b\x83\xc0\x25\xa7\x99\x21\x38\xe6\xd1\x08\x0d\xa1\x4c\x2c\x88\x7c\x6d\x67\x0a\xab\x37\x4d\x43\x6c\x27\x2f\x9e\x96\xf8\x5a\x9c\x42\x33\x79\xc0\xd4\x7c\x46\xdf\x6d\xe3\x34\xea\x20\x57\x15\x8d\x33\x23\x1e\x14\x26\xa6\x6d\x3c\x70\x82\x7a\xad\x55\x11\xb8\x46\xe0\x3b\x94\x92\x3d\x5f\x94\xba\xf1\xf8\xcf\x11\xa8\x61\x37\x3a\x5b\x80\xad\x5e\x31\x7e\xc2\xa5\x29\xe9\x4e\x63\x6c\xdc\x3a\xa2\x9e\x5d\xac\x20\x5a\x0c\x13\xf6\x8f\xb1\x98\xcf\x94\x56\xe6\x39\x0a\xea\xd4\xd9\x78\x2a\x10\x38\xf6\x47\x8d\x33\x9a\x81\xba\xe7\xaf\x2a\x04\x15\x1c\x2f\x22\xe8\xd3\x9f\xe0\x71\xe1\xa5\x21\x68\xd5\x7c\x84\xc3\x62\x93\x41\x3f\x8e\x6f\xf6\x93\x4f\x05\xe7\xef\xad\x6f\xa1\x20\xc8\xc1\xc3\x8a\xd1\x88\x6a\x3d\x00\xbf\xc3\x06\x45\x92\x03\xc0\x2c\xdf\x4f\x06\x65\x2b\xc8\xfa\x0e\x8b\x9c\xc7\x79\xd4\x3f\xbb\x78\x9e\x7d\xad\x5d\xc9\x9f\x41\xd4\xcc\x58\x8c\x1b\x65\x42\x6a\x4e\x77\x38\x9e\xdd\x04\x97\x75\x78\xf8\xf3\x16\xbc\xdd\x94\x61\xd6\x66\x47\x2c\xdd\x27\x6a\xa5\x69\x72\x1c\x65\x23\x22\x56\xba\x1c\xf0\xe7\xf5\xea\x55\x32\x17\x29\xbb\x0e\x03\x86\xa7\x7b\x86\x55\x32\x02\x46\x96\xed\xde\xf4\x85\xb7\xd7\xb2\x8c\x15\x73\xb9\x34\x7e\x41\x4d\x42\x61\x99\x54\x82\xe3\xb3\x12\xde\x13\x31\xf8\x4e\x75\x48\x60\x7a\x84"}, +{{0x04,0xbb,0x88,0x7a,0x8a,0x31,0x84,0xff,0xc7,0xea,0x09,0xc9,0xbc,0x7c,0x1f,0x7c,0x34,0x11,0x55,0x6a,0x7c,0x7c,0x39,0x8c,0xb8,0xb2,0xd9,0x8f,0xfd,0x9e,0xe8,0x66,},{0x6a,0xb1,0xe4,0xae,0x4a,0xa0,0xd3,0x89,0x89,0xae,0xef,0xa8,0x05,0xb5,0x78,0x80,0x6e,0x2e,0x97,0x1a,0xc7,0xac,0x05,0x40,0x99,0x58,0xbf,0xe6,0x00,0x71,0xf4,0xa7,},{0xcd,0x84,0xf5,0x5e,0x5e,0xf4,0x53,0x19,0x24,0xc5,0xa2,0x18,0x1e,0xc8,0x7a,0x64,0x54,0x13,0x88,0xc1,0x05,0x94,0x06,0xbc,0x07,0xd5,0x31,0x57,0xa1,0x68,0xe2,0x03,0xcc,0x8a,0xa0,0xf0,0x06,0x9d,0x53,0xff,0x58,0xa9,0x5b,0x8a,0x8c,0xaa,0xfd,0xad,0x26,0x36,0x3c,0x7d,0x0f,0x80,0x45,0xc4,0x35,0x9e,0x97,0xb4,0x36,0x02,0xc6,0x06,},"\xb7\xab\x0c\x81\x63\xf4\x78\xc6\xca\xbf\x2b\xbd\x7c\xa3\x7c\xb0\x24\x56\xd7\x6e\x52\x7e\xea\x1b\x0d\x26\xdb\x24\x2e\x37\x87\x76\x32\x98\x5a\x3e\x3c\xa4\x1b\x52\xe2\x1d\x79\x01\x7b\xff\x81\xee\x55\x1a\xd7\x2a\xf2\x77\xb4\x10\xe4\x2a\xf8\x22\xc6\x08\xcd\x69\xd0\x0b\xf4\x40\xb7\x5b\x78\x7a\x8c\x91\x5d\x70\xb6\xc6\x37\x6c\x3f\x67\xfa\x64\xd6\x12\xa1\xb4\x49\xa7\xe2\x13\x4d\x9c\x23\x23\x01\x57\xd5\x76\xe0\x6a\x66\xa8\x42\x2a\x61\x1e\x2a\x0f\x09\x72\x86\xc1\x99\xea\x2a\x16\x28\x61\x86\x4b\xd0\x35\x07\x6a\xb2\x0b\xba\xe2\xb4\x40\x8a\x2c\x64\x33\xcb\x23\x43\x3a\x88\x9f\xe6\x59\x8f\x47\xbe\x53\xbb\xd2\xc8\x0f\x07\xa8\xfc\xcb\x8a\xae\x51\x11\x61\xe6\x09\xda\x4d\x18\x0a\xce\xa5\x44\x81\x1e\x94\x49\xc5\xdc\x22\x50\xe3\xe5\xa0\xcd\x41\xda\x33\xa2\xda\x63\x2e\x60\x38\xbd\x86\xf1\x6d\x5b\x7c\x1b\xe4\x9f\xc6\xdb\x49\x90\x76\xca\x91\xf7\xaa\x02\x8f\xe3\x85\x29\x70\x0b\x21\xd0\x72\xd2\xb7\x5d\xcc\x8b\x43\x78\x1d\x4b\xc4\xd3\xbb\x58\x4d\x9d\xa0\x1c\x3e\xcc\x85\xb1\xe9\x3f\xce\x04\x5d\xad\xce\xea\x51\x06\x46\x8b\xdf\xe5\xf7\x0d\x66\xa4\xfa\xd6\x0e\x4f\xb8\x64\xec\x15\xea\x50\xf6\xcb\x79\x72\x23\xc8\xc7\x56\xf7\xa1\x93\x1a\x39\x46\x4e\xbb\xb9\x67\x9f\x6b\x01\x68\x7c\x17\x4e\xaa\x32\xb9\x68\xb9\xcf\xac\xe8\xc1\x67\x12\x0a\xa7\xbd\x02\x42\xf0\x03\xa0\xc3\x77\x70\x25\x51\xb3\x0d\xa2\x48\x8e\xb2\x94\x40\x52\x93\x4a\xef\x4b\xfe\x11\x5f\x0a\xb7\x40\x5a\x3d\x5f\xa9\xbd\x79\x6b\x37\x17\x42\xbc\x11\x4a\x9b\xf2\x8c\x5b\xd2\x56\x26\x29\x5c\xe2\x61\xa6\xa8\x3e\xf6\x0b\x77\xd2\xd3\x2d\xd7\x10\x5f\xc8\x36\x64\xaa\x89\x76\x5b\x3f\x81\x91\xee\xee\xd8\x78\xf2\xeb\xff\x2f\xb9\x76\x63\xa6\x18\x77\xc0\x93\x93\x3b\xbd\x07\x31\xe6\x37\x57\x57\x1b\x0e\x37\xca\xc9\x9e\xd0\x1f\xd2\x14\xcb\xd4\xfe\xb9\x77\xe8\x56\xe0\xa1\xa7\xef\x0c\x40\x8c\x20\xe0\xdd\xaf\x1f\xd8\xf0\x28\xcf\xa0\x8c\x85\x0f\xa7\x09\x0d\xca\x8c\xdd\xe0\xcb\x69\x03\xda\x18\xc6\x29\x0c\x66\xa1\xc0\xae\x0a\x08\x4b\xf2\x50\xc5\x1a\x9d\x03\x5e\x5b\x16\xec\x61\x66\x36\xaf\xb9\xb5\xbc\xe3\x6a\x77\x5f\xe2\x17\x5b\xcc\x2e\xe0\x72\x20\x83\x4e\xeb\x31\xca\xee\x50\xe9\xf8\x06\x3f\xb1\xfc\x84\x68\xae\x25\xe3\x96\x67\x89\xa6\xd8\xdf\xfe\x08\xa6\xf7\xa1\xe6\x72\x6f\x93\xae\x74\x82\xde\x02\x62\xbb\x1f\x8d\xe0\xc9\x5a\x99\xec\xb9\x56\x84\xd4\x4b\x3f\x1a\x33\x2a\x18\xd2\xcd\x3d\xcf\x25\x3c\x33\xd7\x35\x52\x2f\x79\x6b\x65\x1c\x9a\x63\x3a\x8e\xbe\x95\xd0\x2b\xc0\x46\x58\x25\xee\x54\x1a\x7d\x92\x7b\xb5\xb9\x0a\x6d\xb5\x49\x9f\x8d\x99\x3a\xb4\x04\xb1\x65\x0b\x75\xe7\x92\xa7\xc8\x34\xeb\x41\xf0\x47\x01\x38\xb0\xf5\x78\xa0\x4c\x9b\xa5\xad\x95\x0a\xc7\xc9\xb5\xd3\x28\xf3\x40\x8b\x64\x5a\xd9\xc6\xbf\x19\x6d\xd9\x61\x44\x55\x96\xbc\x78\xf2\x84\xb8\x91\x4b\x2a\x8c\xf9\xb7\xbd\x3a\x71\x6d\x8f\x14\x4b\xb6\xb1\x5d\x83\x10\x23\x71\x3b\x5e\x41\xfd\xa9\xb5\x87\xff\x9d\x6c\xc4\x3c\x08\xd3\x5a\x70\x7f\x49\x52\x83\xe1\xac\xe9\x60\x48\x7e\x7f\x02\xb7\x54\x3b\x68\xa7\x31\xa2\x9b\xf3\xbe\x14\xb6\xe9\xc3\x71\x74\xa9\xf4\x6f\x56\x11\x99\xdb\xd2\x7b\x46\xbf\xe6\x22\x43\xe0\xc1\x1c\x0e\xdf\x13\xb6\x4f\x41\x1c\x8e\x8e\xce\xd3\x5d\x84\x28\xf7\x9f\x10\xea\xcf\xfb\x72\x34\xe5\x46\x41\x3d\x1e\xb0\xfa\xd8\x8c\x0e\x93\x85\x93\xb4\x3b\x5e\xe0\xe4\x28\x5d\x4d\xdd\xf5\x29\x5d\xbf\x1a\x3d\xdb\xe9\xf4\x13\x4d\xd7\x6d\x3d\xe7\x04\x62\xc2\xf0\x4f\xe0\xae\xbd\xf5\x9a"}, +{{0x97,0x76,0xa4,0x67,0xfa,0x14,0x00,0x73,0x54,0x12,0xa7,0x9b,0x49,0x5f,0x9f,0xca,0x07,0x8c,0xe1,0xd8,0x7a,0x85,0x30,0xd8,0x5c,0x26,0x05,0x5d,0x3a,0x39,0x44,0x88,},{0xc7,0xdb,0xe0,0xe4,0x1c,0x0a,0x31,0xc0,0x94,0x27,0x93,0xff,0xd1,0x42,0xd8,0xb9,0x5c,0xc8,0x2e,0x5c,0xaa,0x92,0xa3,0x79,0xba,0x23,0xf6,0x44,0xed,0xf2,0x24,0xda,},{0xe1,0x31,0x7b,0xa2,0xa1,0x23,0xae,0x3b,0x29,0xe7,0xb6,0x0e,0x8e,0x93,0xbe,0xed,0xd7,0xa0,0x84,0x51,0xa0,0x13,0x69,0x5b,0x6d,0xcf,0x35,0x8e,0x40,0x34,0x02,0x6d,0xc7,0x40,0x37,0xaf,0xbd,0xd2,0x17,0xff,0x4b,0x14,0x8b,0x02,0x91,0x38,0xf4,0xbc,0xc8,0xf9,0x83,0x6a,0xbb,0xae,0x7e,0x62,0x76,0xe9,0xe7,0x69,0xdb,0xd8,0xf0,0x07,},"\xd7\x85\x53\xa1\xb7\x05\x5b\x58\xb2\x13\x10\x1b\x1c\x84\xc5\x3e\x16\x4e\x39\xc6\xe9\xd3\x6d\xb4\x3f\x30\xe1\x9e\x2a\x12\x5a\x9a\x67\x70\x9e\xaf\xef\x96\x4f\xa5\xba\xb7\x26\x1d\xdb\x3a\x8a\x01\x88\x45\x7d\xfb\xf5\x15\x9c\x40\xe5\x1d\xa8\x20\x84\x83\x24\x57\x81\xd7\x13\x1e\x23\xa8\xbe\xe5\xe5\x06\x33\x18\x16\xb9\xde\xee\xfe\x6e\x55\x6e\x3f\x0c\x95\xc6\x68\xd1\xbe\xdb\x7d\xa6\x35\x06\x54\x58\xad\x20\x46\x70\x12\xf5\x9f\x17\x13\x52\x06\x80\x20\xce\x3c\x75\x87\x86\x93\xf6\x43\x7b\xc4\xa0\x9f\x13\xb9\xb0\xf0\xcd\xda\xf1\x69\x1b\x87\x2f\x82\x00\x80\x93\xeb\xfb\xe2\x33\xd0\x31\x3e\x72\xc8\x63\x2d\x7d\x17\x93\xf0\xb8\x1c\x76\x88\xf5\x44\x70\x33\x0f\x04\xe6\x48\x60\xe6\x44\x6b\xfc\x6d\x96\xc8\x75\x69\xbf\x18\x2f\x0f\x43\x85\xaf\x48\x5d\x42\x99\xca\xc0\x4e\x06\xba\x47\x34\x65\x56\x6c\x47\x7f\x07\xb9\xdb\x27\x7a\xb4\xa9\xde\x2f\xb2\xde\xd0\xa5\x01\x1c\xd0\x6d\x67\x5c\x08\x00\xb3\x4f\x55\xbc\xf3\xec\x72\xd2\x1c\xa1\x50\xc8\xbf\x23\x61\x28\x7b\xe8\x1e\xfa\xbb\x96\xd8\x68\x8a\x1d\xee\x3f\x43\x0f\x06\xf6\x37\xdf\xd0\x6f\x15\x14\x64\xa0\x5c\x95\xf5\xfe\x76\xaf\x2e\x06\xd0\x12\x3f\x69\x48\xa2\x6b\x3b\xe8\x35\x04\x5a\xa2\x68\xcc\x1b\xe9\x76\x69\x71\x07\x77\x02\x08\xa7\x56\x8f\x02\x5c\x2d\x53\xc7\x19\xe5\x24\xcc\x36\x9d\x9b\x4a\x33\x7d\x8f\xd1\xef\x34\x5b\x9b\xca\x57\xfb\xd7\xb6\x5a\x6b\x99\x7c\xad\x3f\xce\x4c\xf0\x6f\x2c\xa4\x3e\xbe\x29\x86\xd0\x96\x82\xd4\x7c\x92\x2b\x2c\xb7\x56\x9d\x98\xde\x97\xa6\x16\x4f\x54\x70\xee\xc7\x1c\xed\xa5\x20\xcc\xec\x77\x32\xbd\x01\x68\x9e\xf8\x16\x56\xe9\xf6\xd0\xc5\x8a\x89\x55\x58\xae\xe8\x63\xf5\x46\x9e\x7a\xb9\x79\x15\xbf\xe0\xb8\x0a\x06\x4c\x65\x9b\x18\x30\x31\xf7\xf1\xa8\x6f\xb1\x1a\x9d\x52\x8c\x28\x15\xdc\xaa\x2f\x0d\xec\x3d\x21\xa8\x82\xe1\x06\xe2\x04\x93\xee\x0a\xcb\x77\x08\xea\xa2\x91\x25\x74\xae\x97\xbb\x28\x8b\x41\xfc\x09\x25\x05\x3a\x29\xb0\xbf\xbc\x0e\xba\xe8\xd6\x3c\xc0\xb4\x6e\x37\x38\x04\x6c\x5a\x20\x25\x30\xbc\xb1\x5b\x18\x7a\x72\x85\x4a\xa2\xd8\xa7\xa7\x6c\x89\xa8\x9a\x5d\xb4\x60\x32\x07\x4e\x1b\xd7\xde\x77\xef\x20\x65\xa0\x8f\x38\x9d\x78\x3c\xf7\x59\xeb\xd5\xa6\x3a\x44\xd9\x19\xf9\x48\xf5\x60\xc3\xe9\x4c\x42\x39\xe2\x74\xe0\x51\xa2\x04\x85\xa4\x30\xcb\xd5\x29\xf3\x13\xd9\xf7\xed\x67\x9a\x34\x18\x7b\x24\xf8\x41\x30\x87\xa9\x02\x1e\x47\x31\x73\x0f\x5f\x46\x1f\xc5\xaa\xd6\x65\x4d\xfa\x1c\x05\x04\xd2\x61\x24\x70\x7e\x63\xee\x57\xf9\x31\xb2\x78\x59\x08\xf8\x6b\x10\x4b\x3e\xcb\x96\x00\x02\x51\xd0\x6c\xe1\xfa\x45\xe4\xcd\x6d\xf9\x1a\xc1\x5b\xbf\x7c\xa3\xc3\xeb\x8e\xe0\x82\x76\x12\xa2\x9e\xcb\x7a\x36\xd5\x47\x0c\x40\x50\x51\x82\xfa\x9a\xc9\x13\x57\x0d\x0c\x10\x50\xd9\xa4\x34\x55\xcb\x7b\xdc\x17\xd1\x69\x80\x5f\x01\x89\x56\xf8\x54\xf8\x91\x9b\xbf\xb7\x19\xe1\x86\x7b\x36\xa6\x4a\xab\xcd\xb8\x07\xf4\x8d\xcc\xc0\x67\x2f\x67\x88\x74\x50\xb3\xf3\xe9\x58\xd7\x84\x99\xe0\xd1\xab\x36\x8a\xa4\x94\x42\xe5\xe8\xa3\x32\xbf\xfd\x44\xc1\x69\xea\x67\x62\x9c\x85\x72\x4d\xb6\xf1\x58\x6b\x6c\x6b\x5b\xe4\x86\x4d\xfd\x53\xda\x7c\x0f\x7b\x8b\xb3\x57\x31\x16\xbe\x50\x77\xd3\x32\xbd\x12\xa6\x30\x0f\x3a\x68\xa8\x98\x66\xb4\x79\xec\x2b\xaa\x27\x7f\x9f\x56\xf6\xe1\xd4\x9d\x74\x1e\xb3\x22\x03\x5f\xf8\xcb\x1d\xe8\x5c\x8d\xc8\x7a\xc8\xe6\xe4\xc5\xd2\x0b\xfb\x6d\x31\x7a\xb1\x25\x93\x0c\x42\x60\x9b\xe3\xae\x82\x24\x2a\x9e\xf0\x56\x88\x58\xd8"}, +{{0x09,0xd8,0x12,0x26,0x97,0x12,0x6d,0xfc,0x7e,0x11,0x68,0x5a,0x04,0x12,0x3f,0xdf,0xb4,0x7c,0xcd,0xdb,0x44,0x99,0xd8,0xa3,0xae,0xf4,0x18,0xcb,0x65,0xae,0xd7,0xa7,},{0xf8,0xdd,0xb1,0xc0,0x0f,0x6e,0x0f,0x4b,0xea,0xa6,0xfc,0x38,0xe5,0xd0,0xa5,0x77,0x5e,0xe2,0x8c,0x80,0xdb,0xde,0x3f,0x0c,0x79,0x30,0xa3,0x3a,0xad,0x71,0x50,0xf3,},{0x18,0xcf,0xaf,0x6d,0xc8,0xe4,0xe8,0x58,0x2b,0xce,0xfe,0x0c,0xdc,0x6f,0xce,0xfe,0x6a,0x4a,0x87,0xea,0x62,0x95,0x85,0xf3,0x7d,0x2f,0xba,0x44,0x6b,0x3a,0xeb,0xd4,0x52,0x42,0x63,0x82,0xda,0x0d,0x49,0x1c,0x39,0xcb,0x7d,0x54,0xd2,0x73,0x00,0x5d,0xc1,0x32,0x12,0x15,0x68,0xd2,0xab,0x67,0x45,0x20,0xad,0xda,0x75,0x23,0x84,0x0d,},"\xa0\xd8\xd8\x79\x8e\xba\x22\xf5\x67\x60\xc3\x06\x43\xe9\xfc\x67\x95\x54\x7e\xa5\xf2\xf2\xbb\xd1\x1c\x03\x92\xb2\xeb\xf7\x11\xac\xa2\x2f\x08\x24\x19\x9f\xc3\x18\x8a\x45\xbd\xff\xde\x70\xec\xe9\xab\x15\xa5\xea\x89\x62\x2a\x58\x71\xe0\xef\x76\x85\xd1\x0f\x12\x74\xcc\x19\x5b\x4f\xda\x81\xf8\x79\xd1\xe9\xbf\x42\xf8\x73\xb2\x0a\x85\x9c\x23\x3f\x9e\x49\xad\xbf\x05\x77\x31\xe1\x13\x35\xe9\xb6\xd8\xed\x0e\x06\x9e\x13\x4e\xc4\x61\xca\x88\x90\xd7\xb0\x47\x3c\x40\x5e\x8a\x9d\x95\xd1\x57\x11\xb1\x24\x76\x10\x37\x62\xc6\x26\xd9\xf2\xaa\x5d\xd5\x19\xbd\x82\x5b\x60\xb3\x23\x4e\xbf\x65\x1e\x0d\x19\x33\x37\x1c\x52\xbf\xd8\xce\x33\xfc\x36\xbb\xa3\x28\xf7\xf3\xf2\xcc\xc0\x10\x00\xa8\x99\x04\xaf\x37\xe4\xe1\xe9\xe1\x5f\xff\xab\x5c\x2b\x0c\x47\xf3\x7c\xdc\xb0\x68\xdb\x33\xac\x36\xa5\xf0\xd6\xde\x12\x03\xfb\xf8\x94\x93\x24\xbd\x3e\xfd\xa0\xf9\x88\x9d\xb0\x0d\xa2\x31\x7b\x49\xfd\x18\x69\x99\xdf\x7f\xcd\xc3\xcb\x4e\x1d\x18\xfa\xa2\x54\x56\x1c\x25\x11\x78\xb8\xd3\x3f\xdc\x9d\xcc\xd8\xd2\xd7\x21\xb9\x3a\x53\x6c\xcd\x3c\x0e\x9c\x85\x63\x37\xf1\x95\xee\xe7\xda\x9a\x7f\x6b\x0a\x42\xb7\xc5\x41\xc6\xa6\x8c\x59\x5b\xf3\x47\x04\xd9\xfe\x3a\x56\xd2\xec\x84\x81\xd5\x77\xc9\x6e\xcc\x08\xb8\xe4\x0a\xcd\xbf\x05\x0e\x20\xc6\x83\xf3\x9c\x41\x4e\x8c\xbf\xcf\x4a\x01\x52\x31\x4c\x05\x98\x7a\x83\xbd\xe3\x02\x5b\x73\x5c\xca\x30\x23\xab\xc5\xfe\xb7\xe0\x0d\x02\x36\xb4\xf2\x4b\x15\xe6\x79\xdb\x05\x2c\x8d\x2f\xdd\xb3\xbe\xf8\x66\x3a\x6d\xf8\x19\xa9\x81\x55\x27\xa1\xa2\xf6\x0a\x0f\xa4\xe5\x07\x8d\xdc\x6d\x43\x5f\xe8\x92\x87\xb3\x0f\xfd\xeb\x5d\x9a\xe0\x5d\x1a\x86\x90\xfb\xc7\x59\x0a\xad\x57\xd4\x3d\x22\xc1\x2a\xce\x2c\x81\x96\x88\x8e\x35\x4e\x9f\x78\x2f\x5d\xbb\x44\x14\x9e\x83\xfb\x8b\xbc\x9d\xa6\xd8\x9c\xe2\x06\xc1\xe2\xb6\xb2\xb2\x8f\x93\x3f\x3e\x5f\xf1\x17\x5a\x31\xa8\xff\x5d\x31\xe6\x5c\x8b\x00\xc5\xba\x46\x22\x24\xa1\xe0\x9d\x4f\x09\xcb\x40\xfc\x87\xc3\x6e\x7d\x28\x5c\x77\x4a\x96\x97\x62\x03\x65\x18\x28\xe7\x83\x62\x88\x47\xac\x51\x2e\x5d\x1c\x35\xb3\x5b\x03\x01\x71\xf9\x23\x96\xf5\xff\xaf\xf5\x85\xce\xad\x04\xb6\xae\x21\x0d\x80\x70\x7c\xc6\x83\x2d\x98\xa2\x0d\x3a\x94\x76\x48\xda\x26\x04\x93\x7f\xef\xd2\x5a\x9f\xe0\xfc\x5c\xac\x08\x3d\xdd\x7d\x20\x75\x30\x7f\x4f\x38\x26\x64\xf6\x87\xdc\xe8\xc6\x55\xde\xd9\xc1\x2d\x48\xff\x76\x01\xdf\x2a\x48\xd3\x7f\xe2\x14\x97\x08\x44\xc0\x75\xf2\xea\xb0\x02\x05\x9f\xc2\x27\x1e\x61\x7c\x96\x57\xa0\x1b\xec\x1d\xd3\x8f\x6c\x28\xba\x8a\x61\x7b\xd3\x08\x51\xe3\xf9\xdb\xac\x90\x44\x18\xdf\x1d\x02\x15\xad\x45\xdf\xc9\xf0\x2b\x5c\x5e\x9f\x9b\xbc\x6d\xe8\xb0\x7a\xf0\xbd\x1f\x7f\xa8\x92\x25\x44\xf1\x2d\x2a\x3e\x1a\xad\xff\x7e\x9c\x6b\x93\x32\x0c\x3a\x61\xef\x33\xda\x07\xeb\x87\xb1\x61\x7f\x9e\x77\xd7\x70\x2e\x55\x8b\xc7\xd8\x12\x2e\x0d\xfe\x2a\xe8\x3e\x83\x6c\x5b\x1a\x62\xaa\x58\x5c\x0d\xff\xe7\x16\xf7\x46\x3c\x0b\x33\xda\x5b\x1e\xda\x55\x6a\x1e\xf1\xe4\x50\x42\xc7\x9b\xdd\x3e\xc3\xcb\x88\x63\xa7\xbc\x1b\x0f\x7e\x1c\x05\xbd\x99\x20\xf0\x5b\x4e\xda\x86\x51\x77\x05\xed\x07\xf6\xdc\xa7\xbb\x00\xae\x04\x56\xe6\x78\x7d\x9f\xae\x8e\xde\x4e\xcd\x0b\xc5\x72\xeb\x5c\xc6\xd1\x9e\x89\x1f\x1b\xcb\x22\x9e\x94\x09\xe0\x65\x74\xc7\xdf\x05\x81\x73\xcb\x58\xc3\xfd\xf2\x0f\x3f\xf1\x7c\x37\x05\xaf\x62\xd9\xb7\x22\x5c\x57\x43\xf6\x00\x60\x7f\x77\xcb\xe7\xd6\xe7\x61\x8a\xbc\x79"}, +{{0x10,0x20,0x1b,0xf0,0x08,0x43,0x67,0x59,0x0d,0xe6,0x74,0xcc,0x0e,0xd2,0x64,0x8e,0xc2,0x5d,0x3b,0xa8,0xdb,0x40,0xd0,0x0e,0xde,0x15,0x33,0x98,0x50,0x8b,0xc1,0x26,},{0xba,0xdb,0xd0,0x5e,0x5f,0x79,0xe3,0x11,0x69,0xf7,0x40,0xba,0x46,0xa5,0x89,0x10,0xa1,0xb7,0x77,0x05,0xaf,0x45,0x71,0x7b,0x2a,0xf8,0x08,0x56,0x45,0x7c,0x58,0xc9,},{0xf1,0xd9,0x96,0x58,0x8b,0x29,0x8f,0x27,0x1e,0x97,0x0c,0xeb,0xd2,0xa1,0xb3,0x39,0x97,0x9c,0xd2,0x9d,0xdd,0xee,0x36,0x45,0xd0,0x7f,0xab,0x8a,0xb4,0x65,0xdd,0xe3,0xe9,0x86,0x67,0xec,0x01,0xad,0x7f,0x1c,0x0a,0x65,0x92,0xe0,0x69,0x7e,0x66,0x5c,0x72,0xfd,0x38,0x14,0xdb,0xe1,0x89,0xed,0x5f,0x4e,0x76,0xc7,0x94,0xe5,0x38,0x09,},"\x7b\xb1\x47\x06\x17\xd1\x1e\x45\xeb\x60\x2a\x82\x9a\xd7\x73\xee\x2b\xb7\xe6\xb8\x8d\xa4\xc0\x4a\x72\x16\xa4\x50\xf8\x49\x93\xa4\x98\xcb\xd3\xb9\x25\x40\x28\xf2\xf9\x9f\xc2\x1a\x23\x28\x8b\xdc\x1e\x15\x1a\x72\xa9\x13\x0c\x3d\xed\xda\x1b\xbb\xcc\xd4\xe6\xc0\xf4\x8a\xe9\xf3\x53\x18\xcb\xef\xc9\x59\xf4\x05\x04\x5e\x6e\x0b\x5f\xb2\xe7\x38\xf2\xb7\x65\xbe\x11\xb1\xb6\xa0\xf1\xe8\x31\x95\x49\xd9\x5f\xa8\xd1\xdf\x81\x67\xcd\x4a\x77\x17\xae\x16\x36\xa9\xdf\x54\xd9\x6e\xaf\x2d\x63\x23\x69\x00\xfd\x11\x33\x82\x52\xa5\x00\x8d\x5d\x48\x0e\x2b\x1e\x98\x61\xd1\xf7\x06\x88\xc4\x7e\xae\x46\x89\xda\x01\xa4\x7d\xa3\xdf\xb6\xd2\xba\xb3\xcd\xf5\x05\xee\x5d\x80\x1a\x15\x2c\x26\x70\x93\xd1\x7e\x9b\xf7\x13\x7a\x6e\xe7\xb8\x34\xd0\x08\x55\x00\xe4\x01\xc1\x7f\x32\x86\xc1\x57\x5d\x1c\x01\x00\xfa\x98\x07\x63\x0c\x4a\x99\x06\x54\xc1\xe7\x1a\x8b\x71\x56\x27\xbb\x13\xd4\x42\xc8\x4a\x44\x98\x44\xc4\x04\xb8\x72\xbf\xba\xc7\x18\xa4\x8d\x0e\xa0\x94\x5c\x77\x16\x6a\x53\x13\x9b\x0f\xf0\x09\x81\x34\x76\x4f\x9e\xcd\xb8\x8e\xab\xe0\x7c\xcb\x2c\xce\xd4\x95\x5e\x08\x24\x9b\x2f\x57\x70\xad\x41\xfc\xcd\x7b\x5b\xb3\x72\xe6\xc3\x37\x67\xe0\x7f\x5b\xe7\xd1\x07\x12\xde\x81\x84\x1b\x13\x4e\x19\x3d\xf0\x77\x6a\x0f\xc1\x56\xff\x5d\x0e\x96\xf4\x0a\x70\x47\x53\xe1\x14\x5e\x9f\xa0\x83\xc4\xdd\xee\xf4\x41\x62\x34\xf6\xe1\xa2\x38\x2c\x8e\x5b\x3a\xd4\x05\x45\x8e\x89\xd2\xf4\x93\xa4\xd7\xc2\x9a\x23\xde\x21\x07\x48\x5b\x7f\x56\x35\x01\x24\xe7\xe0\xd6\x95\xc5\x22\xb6\xde\x7a\x92\x47\xa2\x92\x4c\xe6\xf2\x86\x32\x36\xc1\x0c\xc2\x12\x64\xad\x54\x59\x0d\x31\x47\x63\xea\x1a\x19\xaf\xac\xd9\x0e\xba\x95\x58\x70\x40\x7e\x8c\x63\x65\xa1\x43\xa5\xc1\xb9\xa8\xbe\x5e\x4a\x4d\xca\xdb\x72\xe0\xd4\x76\x49\xbd\x53\xab\xd4\x6b\x5c\x69\x60\xea\xe2\xca\xb7\x73\x75\x3c\xc0\xe0\x4e\x99\x41\x4b\xc2\xcb\x30\xf4\x8b\xb5\x41\x39\xd0\x66\xe4\x3e\x2f\x0e\x1a\x4a\xe9\x63\x85\x8b\xef\x96\x7d\xf8\xc8\x41\x40\xd2\xd0\x92\x02\xb4\x06\xd5\xd8\x5c\xb7\xa9\x6c\xc5\x7f\x23\x3e\xb2\x18\x7f\xfd\x02\xf9\x4e\x92\x29\x7b\x5e\x69\xd9\x69\xd3\xa5\x93\x6e\xfe\x49\x29\x14\x4f\x25\x8b\xfb\x39\xdd\x0c\xe2\x63\x59\xc4\x54\x9f\xc2\x18\xa0\xaa\x54\xf3\x1b\xd5\x51\xb8\x78\x1a\xcb\xbf\x61\xcb\x3f\x73\x2c\xda\xf6\x22\xc6\xa6\x91\x88\xcf\x55\x7a\x3a\x92\xed\x15\x3e\x69\x12\x5a\x40\x90\xac\x45\x15\x36\xa0\xe9\xa6\x3a\x41\x78\x29\x10\xff\xcc\xb4\xe8\x50\x02\x11\x23\xff\xd1\xf3\xbf\x39\xc7\x34\x60\xa6\x5c\xcf\xe4\xdb\xa9\xbd\xef\xb5\xd5\xf4\xda\x6c\x46\x9a\xa1\x32\x2f\xa2\x70\x43\x23\x83\x63\xee\x72\x91\x86\x88\xd7\xca\x1c\x4c\x29\x52\xe4\x30\xd5\x63\x25\x6b\xb8\x6d\x35\x0a\x35\xee\x82\xe0\x15\x04\x74\x7f\x31\xd0\x2e\x03\xae\xdd\xa5\x46\xd0\xf1\xb2\xf4\x51\xb8\x70\x82\x16\x02\xd0\x0e\x81\x90\x36\xad\xe5\xa7\xc7\xfc\xd2\x1a\x6d\xe6\xaf\x35\xb1\xf9\x63\x2a\x70\xaf\x65\xdf\x64\x45\xf6\xfa\xdf\xbc\x0f\x41\x67\x55\xc8\x24\x66\x40\xe5\x6b\x85\x6b\x66\xdd\xd9\x2a\x60\xc0\x35\x38\x22\x1d\xc8\xfb\x14\x2c\xe2\xdb\xac\xdb\x74\x25\xf3\x3c\xb8\x5d\x85\x0c\xc0\x2c\x31\x5c\xfc\x11\x1f\x6f\x65\x1d\xde\x1b\xdb\x67\xfb\x20\x8e\x1f\x6b\xde\x78\x4d\xdc\xf7\xbd\x18\xc8\x05\x1a\x2e\x0b\xbf\x10\x18\xb8\xf3\x95\x36\xc5\x89\xde\x65\xea\xdc\x6c\xf3\x79\xb7\x7c\xad\x13\xf9\x08\x9c\xb3\x23\xfb\x2e\x94\x3d\x06\xcd\xd1\x07\x05\xc1\x21\x13\x4c\x65\x48\xdc\x53\x41\x5f\x8c\x37\x0e\xc6\x90"}, +{{0xc4,0xaa,0x42,0x52,0x46,0xb5,0x17,0x3f,0x5e,0xf8,0x98,0x15,0x2e,0xca,0x3d,0x09,0x2b,0xb4,0xc2,0xdd,0x02,0x85,0x3f,0xcf,0xc7,0x17,0x83,0x99,0xf4,0xe2,0xf7,0x58,},{0x29,0xb7,0x7a,0x30,0x75,0xf4,0x19,0x24,0x3c,0x0c,0x1b,0xc3,0x96,0x59,0xd7,0x31,0x17,0xac,0x00,0xe5,0x5e,0x8d,0xe3,0x8f,0xe9,0x82,0x9a,0x87,0x9c,0xc5,0xb8,0xa0,},{0x5d,0x85,0x45,0xa4,0xbe,0x3f,0xd6,0xda,0x25,0x78,0xc2,0xec,0xcb,0x64,0x8d,0x83,0xfc,0xfe,0x58,0x71,0x33,0xfa,0x7a,0xe4,0xa1,0xcf,0xca,0x9a,0xe6,0xda,0xa4,0x92,0x59,0xc9,0x52,0x04,0x4a,0x85,0xa2,0x0b,0x6f,0x53,0x24,0xf8,0x27,0xdb,0xa2,0xd1,0xa8,0x38,0x8c,0x40,0xa9,0x28,0xb9,0x50,0x91,0x3c,0x63,0x4f,0xb3,0x09,0x27,0x07,},"\x7d\xf9\x78\xa1\xf4\x97\x68\x38\xff\xed\x74\x49\xa4\xdc\x13\x8b\x60\x4f\x4b\x2a\x4a\xe6\x89\xce\x75\x01\x8e\xbc\xcd\xab\x2e\xaa\x0b\x60\x76\x8f\x72\x08\x25\x7f\x2b\x28\xe7\xaa\x09\xbf\x6c\x05\x88\x8d\xa4\x6f\xd3\x96\xd1\xc8\x03\x01\x17\x50\xe3\x0e\xb4\x84\x87\x0c\x88\x06\x97\x76\x96\xf1\x2e\xbb\x9f\xee\xb4\xca\xf9\x2a\x02\xdb\xaa\x22\xbb\xff\x63\xf8\x42\xc3\xba\x14\x7b\xca\x7c\x00\x31\x42\x78\xac\xd0\xdb\x17\x35\x69\xf4\xe3\x65\x27\x95\x8e\xf6\xf1\x00\x2b\xd3\xcd\x01\xf4\x07\xa8\x65\x31\xed\xcb\xd9\xf3\x1b\x3a\x4a\xb8\x80\xa4\xf5\xb5\x2b\x42\xd0\xd4\xa1\xba\x66\xa2\x09\x86\x51\xae\x3e\x6c\x91\x51\xf4\x02\x73\x28\x5f\x7f\x6a\x4e\x81\x60\x6b\xf9\x80\xf6\x89\x50\x4b\x42\x08\x0f\xdb\x97\xc7\x28\x46\xfb\xa9\x04\x7c\x7e\x66\x0b\xa5\xc6\xbf\x12\x6a\x9a\x59\x9e\x25\x71\xfa\x13\x50\x5a\xf7\x58\x1b\xfe\xbc\x16\x51\x3f\x5c\x94\xdc\x71\x93\x7e\x6e\x61\xb3\xea\x10\x93\x9b\x02\xea\x10\x85\x9f\x32\xd7\x91\x2b\x9e\x38\x06\xab\xef\x61\x85\xfc\xff\xa6\x88\x21\x47\x80\x05\xcb\xfc\x1d\x63\x7d\xd0\x20\x42\x56\x20\xa3\x18\x07\x48\x98\xbd\xc3\x09\x31\xc5\x9a\xc0\xc6\x6c\x4d\x12\x38\xb0\x97\xcd\x5b\x17\x0f\x08\x44\x35\xd4\xba\xe4\x8a\x03\xd9\x2f\xd4\x8f\xc2\xca\xa4\xff\xc5\x05\xf1\xbc\xa5\x16\xfb\xd6\xe4\xf8\x88\xcc\xed\x98\x2a\xe0\xdd\xb8\x8f\xc2\x8a\xa6\x97\xb7\x07\x1d\x01\x5b\x0a\xcb\x28\x09\xb0\x1d\x1d\x9c\x7e\x7b\x53\xee\xe6\x82\x4c\xc3\x7c\xce\x5b\x69\x93\xd8\x8d\x83\xea\xfc\x2e\x92\x8a\x6f\x14\x7d\xb6\xeb\x80\xb1\xa6\x9f\x01\x60\x5b\x04\x6b\xd2\xfd\x1d\x92\xc5\x45\x9d\x6d\x33\x98\xa9\xca\xa2\x99\xdd\xd0\xc3\xba\x2e\x08\x94\x13\x07\xb1\x20\xcc\x13\x99\x2f\x70\x03\xac\xed\x14\xa4\xa4\xd9\x23\xbb\xb1\x2f\xc3\x93\xff\xcf\x92\x0b\x9f\x6d\x47\x75\xe9\x4d\x4a\x51\x22\x67\xfd\x26\xa6\x99\x7c\x60\x62\xb4\xc9\x90\x0f\x98\x62\xb9\xea\x0c\x8d\x7d\xf1\x9f\x05\xc2\xb6\x04\xaf\x5b\x98\x64\xfb\x27\x54\xa8\x07\x3b\xbb\xfb\x18\x23\x3e\x6e\x15\x0f\x72\xa5\x25\xe3\xa5\x76\x0f\xcd\xa7\xd3\x2a\x60\x03\x4f\x95\x6e\x3c\xbd\x34\x36\xc2\x00\x83\x0b\x3e\x7a\x14\x57\x12\x20\xbc\xb6\x27\xd5\xa4\xbe\x72\xc2\x0b\x23\x35\x1b\x2d\x92\x06\x02\xa5\x1c\x3e\xb3\x2c\x12\x37\x03\x9d\xfb\xff\x43\xc9\x87\xfd\x85\x63\x77\x7f\x0e\x5a\x39\xf8\x14\x6c\x16\x4b\xdf\xfc\xe4\x4f\x3b\x13\xee\x74\xd6\x4b\xfd\xcf\x98\x03\xf0\x3d\xd0\x17\x2a\xc4\xfa\x4b\xf6\xc7\x83\x9c\xb1\x1f\x3d\x34\xba\xef\x0e\x32\xb5\x49\x42\xfc\x4f\xa3\x8f\x47\x3e\x29\x66\xf4\x91\x1c\x0e\x80\xd7\x69\x37\xb2\x5b\x76\x32\x27\x5b\xa8\x83\x09\x63\x5a\x60\xdf\x13\x54\x89\x20\x8d\x3e\x73\x4b\x67\x2e\xda\x7d\x2b\xa2\x15\x79\xab\xa8\xd8\x86\x0e\xa7\x64\xfd\x67\xea\xf9\xc3\x8e\xa7\x63\x7d\x1b\xad\x57\xb2\xf3\xd7\x82\xb9\x1e\x1d\x5d\x92\xac\x30\x0b\xdb\xa7\xab\x91\x13\xce\x91\x3d\x0c\x79\x3c\x12\xa9\xa7\x26\xe3\xfc\xab\x05\xcb\x47\x99\x77\x87\x16\x40\x63\x0d\x45\x9e\x69\xe8\x1c\xa5\xcf\x56\xdd\xb2\xa0\x61\x1d\x61\xd4\x81\xc1\xb8\xce\xf3\x80\x4b\xd4\xe5\x75\x4a\x61\xeb\x49\xb1\x7e\xf2\xb0\x3c\x83\x05\x7b\x5d\x20\xd8\x82\x05\x8c\x00\xf5\x4b\x6c\xca\x86\xbe\x95\x35\x0d\xd7\xbc\xb2\x5e\x4c\x1c\x46\x58\xf4\x52\x29\xc8\xbb\x9f\x5c\xdf\xcc\x44\x79\x5c\x97\x8e\x33\x88\xd3\x25\x76\x01\x06\xe5\x2b\xe9\x83\x4b\xd8\x1f\xfc\x5c\x62\x48\x6b\x6f\x33\xc2\x74\x59\xdf\x17\x8e\xb9\x46\xe7\xa8\x2d\xb9\xce\x0d\x29\x5b\x92\x5b\xb6\x12\x6d\xd5\x5c\x31\xf4\x9a\x68\xdc\xef\xc7"}, +{{0xf1,0x3c,0xaf,0xde,0x6f,0x39,0xb9,0x63,0xdc,0xa9,0x66,0x26,0x86,0x2f,0x4f,0xbc,0x5c,0x2e,0x00,0xdd,0xf0,0x8b,0xec,0xea,0xc7,0xa6,0xe2,0xfc,0xa9,0xe1,0xcc,0xf7,},{0xc1,0xb0,0x1a,0x91,0xe8,0xee,0x0b,0x9f,0x19,0xa7,0x2e,0x5e,0x7e,0x0a,0xef,0xcf,0xdc,0x44,0xa1,0x57,0x47,0x4e,0x99,0xfe,0xeb,0xd0,0xff,0x55,0x2d,0x73,0xb2,0xac,},{0x6c,0xa9,0xf8,0x0a,0x62,0x50,0x1f,0xaf,0x31,0x9f,0xb8,0x4a,0xf4,0x71,0xf6,0x76,0xae,0x3f,0xff,0x85,0x56,0x5c,0x97,0x98,0x1f,0x14,0x57,0xcb,0xb8,0xc4,0x9f,0x97,0xb2,0x66,0x31,0x6a,0x99,0x2d,0xb0,0xd4,0x2b,0xc5,0x02,0xf0,0x95,0xa5,0xf2,0xd9,0xa4,0xe1,0xcf,0xac,0x0c,0xc9,0x35,0xd3,0x88,0x2c,0x8a,0x3a,0x0e,0xa6,0xe1,0x0e,},"\x2b\xee\x73\xb7\x4f\x1b\x76\x22\xeb\x09\x6a\x28\xd8\x3a\x81\x9b\xce\xc2\x2d\x99\x99\xa3\x20\x62\x10\x3d\x60\x4a\xe6\xd7\x8e\xdf\x8f\x89\x38\x95\xd2\x22\x0a\xb7\x56\x90\x41\x0c\x58\xaa\xb5\x90\xa9\x8d\xdf\xf2\x3a\x94\xd2\x35\x0f\x88\x9e\x53\x46\x42\x00\xa5\x27\xd5\x4d\x62\x57\x11\x07\xb2\x7e\x57\x4f\x54\x2e\xba\xc2\x49\xb8\xe2\xe3\xce\x08\xd1\xbd\x27\xbd\x8d\x29\xf2\xe6\x12\x43\xde\xef\x0e\x69\x38\xe5\x2e\xe2\x99\x2f\xf2\x18\x7d\x7a\x7f\x52\x82\xed\xd9\x8f\xc4\x98\x5b\x61\x9a\xcb\x80\xaa\x9d\x03\xd6\xcb\x84\xb8\x21\x10\x6f\x40\xd6\xe5\xf4\xc3\x87\xab\x0a\xf6\xf2\x06\x61\x5d\x0a\x17\x5f\x7e\x60\xee\x27\x55\xae\xa3\x46\x75\xfd\xd8\x23\xeb\x24\x10\x9a\x9b\xd8\x18\xea\x2d\x9d\x9b\xd1\x99\xcf\x8d\xfe\x79\x62\x4b\x03\x72\xae\x85\xe9\x8c\x60\x20\x02\x34\xbd\x41\x3f\x4a\x62\xce\x68\xa4\x7b\x6c\x9b\x12\x85\x7c\x0d\x39\x9a\x44\x8e\x5a\x52\x80\xe9\xf2\x2f\x9b\x12\xea\x2c\xd3\xc6\x87\x13\xe7\x7d\x0a\x11\xf3\x62\x8d\x8e\xc5\xe0\x60\x63\x90\x31\xd3\xb6\x40\x02\x1c\x9c\x38\x80\x9d\xc5\xf4\x2d\x2e\x1c\x2e\x23\x46\xc8\x6e\x24\xee\xdc\x59\x84\xa1\x15\xa4\x2d\xe8\xde\x7e\x35\xc9\x91\x75\x39\xe8\x98\x85\xca\x91\x6e\x07\x2a\xfd\x5d\x46\x84\x6b\x2a\x93\x59\x61\xc2\xfe\x28\xe9\xeb\x3c\x8f\x89\x6b\x86\xfc\x12\x0c\xbd\x3a\xf2\xaa\x13\x9c\x49\x9d\x29\xcf\xc3\x69\x9d\xb7\x9c\x14\x48\x4e\x9e\xc2\x57\xa5\xf6\x43\x44\xb7\xad\x1e\x3d\xfb\x34\xee\xe7\x65\x4c\x6b\xf1\x2f\xd3\x8f\xbb\xa8\x0f\xe1\x76\x2a\xab\x57\x11\x2b\x3a\x94\xe2\xbe\xe7\x90\x41\xd1\xe8\x84\x40\xf8\x5f\xb7\x2d\xde\x68\xd4\x9e\x84\xbc\xed\x99\x8a\x2f\x63\x35\x44\x6e\x4a\x83\x5e\x70\xc5\xf8\x27\xfb\x3a\xd7\x82\x3d\x5f\xbe\x3b\xe5\xf6\xec\x7e\x43\x4e\xe5\x24\xcc\xd9\xff\x5b\x7e\x72\xa3\x2d\x09\x1a\x7e\x17\xc8\xb1\xae\x41\xa1\xaf\x31\x79\x3c\xce\x91\xd8\x4c\x36\x22\x67\x89\x69\xc8\xf5\x17\xdc\x26\xe3\xcd\x61\xd2\x44\x69\x12\x28\x3f\x93\x53\xbb\x5a\xd0\x3c\x11\x1c\x62\x33\xde\x31\x4c\x61\xb8\x31\xcb\xf3\x8b\x04\xfe\x58\xcf\x44\xf1\xd2\xd0\xb4\x5f\x25\xa6\xb4\xe0\x25\x68\x59\xcd\x5d\x83\x0f\xac\x5e\xc3\xc8\xd7\x63\x98\x55\x9e\x9b\x26\x01\x0f\x5e\x1d\xa5\xf2\x5d\x22\x00\x93\x54\x53\xff\xac\x5a\xea\x51\xf7\xe8\x1e\x72\xec\x8e\x5f\x04\xd2\xf8\x85\xc7\xb4\x5c\x63\xf6\x44\x56\xcf\xe2\x31\xb8\xcb\x24\xaa\x16\x20\xa9\x02\x63\x9c\xa7\x8d\xd3\x91\xaa\x4a\x3d\x03\xe1\x19\x75\xc8\x90\x7f\x96\x4f\xd5\x5d\xf9\xbb\xb1\x40\xe3\x8d\x6d\xb9\x32\x56\xb4\xb3\x9c\x2b\x7b\xcb\xe3\x5b\x11\x82\x6b\xbf\x8c\x08\xf1\xdc\xb4\x8e\xdc\x4b\xfb\x70\x46\x2a\x35\xea\x8c\xd8\xcb\xa7\x9f\xab\x8b\x4c\x44\xe7\x3b\xe7\xec\xfa\x11\x21\x66\xf6\xdc\xab\x70\xd8\xbb\x55\xd8\xb8\x42\x8c\x2d\xa7\x1a\xac\xa2\xfc\x3d\x90\xf3\xcc\x5e\xd0\x15\x51\x35\x8d\x60\x78\x9b\x9d\x57\x1e\xfe\x10\x89\x20\x27\xfa\x37\x40\x4a\xaf\x59\xec\x1c\x2d\x71\x11\xec\xc3\x59\x24\x67\xed\x1d\x9b\x8a\xba\x8e\x22\x9e\x32\xd2\xa0\x0c\x19\xdb\x71\x87\xfb\xcb\x12\x20\x61\x96\x1c\x1f\xda\xca\x30\x7e\x9c\x9c\x9d\xe9\x72\xad\x51\x40\x2f\xa6\x7d\xc1\xc2\xa4\x03\xb3\xc5\xe8\xb1\xe2\x46\x86\x2d\x6a\xd6\xa4\x98\xdb\x6d\x76\x1f\xb5\x66\xf6\x06\x59\x42\xb6\x0a\xd4\xb4\x30\x9d\x18\x2b\xc5\x15\x4c\xfc\x36\x86\x31\x85\xa8\x7e\x23\xab\xaa\x1d\x54\x1a\xb7\x63\xa4\xa1\x06\x6c\x0a\x7a\x8c\x3d\x82\x1a\xe3\x2f\xd3\x1c\x88\x92\x40\x10\x46\xd0\xa2\x0e\x91\xa6\x47\x79\xf4\xbd\xa8\x11\x20\xaf\x3f\xb3\x48\x6d\x3f\xc0\xa7"}, +{{0xc8,0x46,0x34,0x42,0x61,0xa3,0x48,0x65,0x39,0x38,0x34,0xbf,0xaa,0x3a,0x15,0xa3,0xf5,0x3a,0xc9,0xe1,0x38,0x33,0xb0,0xb2,0x87,0x12,0x27,0x81,0xb7,0x9d,0xe3,0x92,},{0xeb,0xad,0xe0,0x22,0x61,0x95,0xae,0x25,0x4b,0x61,0x15,0xe2,0x16,0x96,0xa9,0xc6,0x5a,0x19,0xd5,0xe0,0x40,0x44,0x31,0x31,0xc2,0x2b,0x89,0xf0,0x2f,0x69,0xab,0x78,},{0xd5,0xe4,0x1b,0x47,0xad,0x0f,0x34,0x00,0x70,0x97,0x70,0xed,0x43,0x91,0x9b,0xaf,0xdf,0x24,0x38,0x1b,0x66,0x15,0x44,0xe5,0x1d,0x8b,0x5c,0xee,0x9e,0x97,0xb3,0x67,0x6a,0x4c,0x0f,0xfa,0xeb,0xb2,0xcb,0xd2,0xdb,0x79,0x85,0x32,0xb6,0x5c,0xf6,0x54,0xa5,0xb6,0xc1,0x66,0xef,0x88,0x6c,0xb0,0xfb,0xbf,0x4a,0x4f,0x84,0x4c,0x44,0x0b,},"\x5a\xbd\x13\xe9\x5b\x6e\xe1\xd5\x51\x47\x68\x28\x22\x00\xa1\x4f\x7d\x1a\x57\x1f\x34\x68\xe2\x2e\xfe\xc9\x93\x46\x30\x66\xa3\x7a\xec\x83\x73\xe5\xfb\x49\x95\x64\x19\x1f\x32\x94\xa9\xb3\x0a\xfb\x5f\x1a\x34\xd4\xd8\x8a\xbc\x3e\x9b\xc3\x03\xc1\xab\xa0\x5b\xd8\xfa\xca\x90\xee\x35\xd9\x7a\xc3\xdd\x91\x06\xf6\xfa\x3c\xa8\x1a\x38\x10\xec\xce\xfa\x6a\x20\x9e\xa3\xf3\xfc\x30\x49\xdc\xb1\xb0\x03\xc7\x28\xf7\xf6\x37\x4c\xa9\x8c\x58\x2d\xe6\xdb\x1a\xf7\x60\xf0\xa0\x21\x33\xca\x4a\x01\x03\x24\x30\x4d\x26\xa0\xe5\x0a\xf0\xd1\x3c\x13\x4d\xa3\x4a\x03\xa4\x1e\x83\xec\x8f\x10\xea\x5b\x85\x9b\xec\x1f\x51\xb0\x1c\xab\xb2\xd1\x6c\x1f\xc5\x2b\x05\x8f\x8e\x5d\xef\xae\xde\x12\x81\x71\xc2\xe0\x26\x90\x23\x16\xf8\x71\xb3\x5e\x32\x92\x65\x6f\x0e\x5b\x39\xbb\xbc\x81\xd0\xc0\x83\x0e\x6a\xc0\x1f\xac\x9b\x45\x39\xf4\x7f\x9a\xcf\xbd\x58\xb7\xab\x9f\x5a\x12\x56\x00\xf2\x51\xa2\x71\xd7\xbf\x16\x7f\x29\x54\xca\x8e\x1e\x0c\x96\xe1\x6b\x06\xe8\x30\x7d\xf8\x8b\xb8\xe9\xd5\x7d\x5b\xa0\x44\xf2\x7f\x3e\xaf\xf8\x1d\x9f\x15\x05\x54\xaa\x71\x22\xfd\x10\xd1\x1f\x35\xd2\xbe\x2b\x16\x24\xe3\xe1\xa1\xd7\x7f\xea\x4c\x5c\x7f\x8b\x98\x3e\x94\x5b\xa8\xc0\x8d\xc1\x54\x5b\x3e\x6b\x29\x73\xad\x04\x1c\x44\xd0\x61\x7e\xcc\xc8\x71\xa3\x82\x1a\x9f\xfe\xa9\xdb\x7c\x2b\x0d\x05\x5d\xa5\x5d\xe0\xb3\x50\x63\xe4\x22\x5a\xee\x6b\x22\x5a\xb2\xa7\x90\x6a\x8e\xe3\x29\xd1\xb3\x97\x2e\x0d\x1f\x70\x81\x7c\x50\xcc\xfe\x94\x03\xd1\x2a\xd6\x2c\x94\x92\x3b\x9a\xa2\xd7\xf8\x5a\x8d\xda\x47\xbe\x4d\xce\xc0\xdc\x2b\x0b\x58\xf7\xac\x19\x0a\xe0\x57\x9b\x9b\x13\xbb\xb8\xb1\x6a\x31\xb0\xab\x4d\x6f\x27\x91\x25\x3a\xb4\x75\x1b\x53\x6b\x88\xd3\xb4\x93\x7c\xc3\xa1\x10\xaa\x82\xa6\xff\xed\x68\x53\x52\x4b\x66\xb3\xef\xfc\xd2\xf6\x3c\x6f\x96\x45\xce\xa1\x3a\xa2\x3c\xd1\xc9\x9d\x9f\xfd\xa4\xcd\x3a\x9c\x5d\xf4\x5e\xc7\x47\x26\xc3\x47\x11\x28\xb7\x08\x9f\xbd\x82\x69\x4d\x2d\x3f\x08\xdc\x93\x06\xc0\xfc\x9c\xe7\xc8\x01\x13\x8e\xb1\xec\xb7\x56\xe5\x71\xe9\x05\x9b\x75\xed\x03\xf9\x2a\x31\x50\x2f\xbe\xb5\xfe\xc5\x1d\xe9\x35\x90\x10\xc4\x39\x7d\x28\xb6\x5e\x35\x6e\x38\x00\x1d\x0d\x51\xac\x96\x00\x72\x8c\x78\xb5\x76\x6e\x0f\x21\x79\x38\xb4\x10\xe7\x85\xb4\xc0\x1e\x86\xa3\x45\x2b\xcb\x38\x84\xac\xa4\x75\x40\x85\x9c\xc4\x9b\x00\x0f\x0b\x61\xfd\xbe\x72\x75\x25\x74\xb2\x7a\x22\xd4\xc4\x04\x13\xa4\x3b\x31\x09\x24\xb1\xbb\x14\x0f\xc9\xfd\xaa\xe2\x66\xd6\x59\x30\xe3\xf2\x34\xfe\x84\x1d\x82\xb2\x61\x76\xff\x86\xc5\xd2\xbd\x8d\x96\x5c\x52\xd7\x28\x06\x4e\xbd\xf6\x8d\xc8\xe4\x83\x49\x41\x80\x1c\xca\x0b\x2f\x25\x6d\x4f\x6c\x3d\xd1\x9d\x35\xd5\x36\x2b\xbf\x9b\x8a\x3a\x1c\x86\x3e\x09\x26\x89\xdd\x28\x52\xad\xd4\x88\xbf\x42\x68\x5b\x11\xe1\xe1\xad\x57\x45\xd0\x75\x62\x8d\x73\x1f\x91\xcf\xd7\x49\x15\x9e\x2e\x1c\x83\x7f\x4e\xf8\x3d\x80\xea\x1d\xd9\xbd\xed\x5f\x88\x01\x8c\xe1\xd4\xb3\x37\x1f\x95\x43\x53\xf3\xd8\x94\x37\x00\x62\xc0\x96\x5d\x67\x98\x6d\xbc\x48\x17\x15\xf4\x2d\xd2\xc9\x16\x07\xab\x8b\x5f\x0d\x89\xf6\x6e\x68\xd7\x3d\x50\xd6\x40\x52\x4d\x72\xe6\x91\x34\xb8\x87\x29\x8e\x5c\xd8\xc4\xb9\x05\xba\x5e\xfa\x0e\x9d\x68\x52\x14\xb8\x42\xf5\x0a\x2a\x39\x83\xa1\xaf\x58\x5a\xf2\xca\x43\xdb\xcf\x02\xc4\x08\x97\xae\x2e\x1a\xb5\x1d\xbc\xe5\x70\x34\x5e\x8e\x13\x5f\xb7\xb4\xeb\x0a\x1d\x6a\x0b\xb5\xa8\xa1\x80\x7e\x42\x5b\x2d\x62\x83\x60\x76\x80\x58\xe6\x1a\xd1\xcf\xaa\x20\x99"}, +{{0xfa,0xaf,0x55,0xd3,0xc2,0x97,0x14,0xb6,0x5c,0x22,0x81,0xe2,0xc2,0x2d,0x61,0x34,0x97,0x1a,0x2e,0x74,0x00,0x8f,0xb9,0x40,0x89,0xa7,0x73,0xee,0xeb,0x44,0x83,0xa6,},{0x39,0x86,0x2e,0xac,0x6d,0xd5,0x2e,0x38,0x1b,0xb3,0x4d,0xc1,0x96,0xba,0x8a,0x37,0x4d,0xcb,0x7d,0xf6,0xcb,0x14,0x0f,0xd0,0xcf,0xa6,0xcf,0xa3,0x9b,0x8c,0x75,0x3f,},{0x5b,0x00,0x83,0xf7,0xa8,0x20,0x61,0xc6,0x5c,0xf6,0xc7,0x56,0x40,0xc8,0x1c,0x28,0xe8,0xd6,0xd2,0xe8,0x7f,0x6d,0x57,0x95,0xc9,0xaa,0x3b,0xb3,0xe3,0x90,0xe9,0x19,0x90,0xe8,0x2d,0xb6,0xf0,0x7e,0x61,0x4f,0x50,0x7a,0x56,0x0a,0xba,0xa1,0xec,0xa6,0x56,0xc6,0x78,0xdd,0xca,0xe8,0x19,0x82,0x51,0xe6,0xaf,0x0b,0x76,0xb8,0x8d,0x0d,},"\x94\xe6\x61\xc2\x52\x40\xa8\x9e\x82\x3d\x7f\x5d\xc0\xe6\x92\xed\xdd\x13\x70\xc3\x5a\xc4\x4d\x5a\x8c\x87\x98\xd0\xc9\xaa\xfd\xf0\xbb\xfb\x54\x92\x60\x56\x8d\xba\x1c\x69\x08\x6b\xee\x63\x6b\xe8\xed\xcc\xd3\xcb\xb2\x70\x16\x24\x4d\x54\xd7\xed\x2f\xeb\x7f\xa6\x46\x14\xd4\x54\x49\xd7\xe0\x58\xe7\x1b\x30\x6c\x22\xe6\x91\x1c\x2a\xc7\x42\x07\xba\xe5\xa8\x4d\x0f\xc2\x47\xbe\x49\xd3\x56\xe5\xd4\x35\x3b\xa5\x58\x6b\x6e\x4b\x2b\x97\xce\x9e\x23\x77\xb6\xee\xd9\x2c\x84\x9e\x67\x69\x44\xae\x90\xdc\x42\x08\xe3\x00\xe1\x9c\xc9\x1d\xc2\x6b\xbd\xd5\xa3\x0c\xfa\x92\x81\xa1\x5e\xfd\x87\x30\x66\xf8\x5a\xf3\xa2\x6f\x31\x06\x23\xe0\x09\x80\x48\x53\xcc\x68\x55\x90\x3e\xa6\x4a\x90\x98\x97\xe3\x15\xe7\x3d\x31\x29\x48\x98\x0e\xf6\x28\x9d\xb2\x1a\x5e\xbb\xec\x8c\x8e\xfe\x20\xd1\xd5\x3d\xfa\xad\x6d\x9f\x42\x96\x53\x2e\x88\x7c\x37\x35\x01\x05\xa6\x33\xab\xc7\x73\x18\x87\x51\xb2\x8c\x3a\x08\xf1\xb5\xee\x04\x72\xde\x46\x27\xe6\xb6\x1b\x68\x27\x8d\xd5\x1c\xed\x6a\x61\xec\xf3\x88\x86\xe4\x53\x39\xdc\x6c\x60\xc3\x1e\x85\x0e\xf8\x29\x6a\xe8\x0f\x9d\x31\x70\x17\x76\xeb\x9a\xf2\x16\x93\xf4\xc5\x2e\xc0\x62\x62\x57\x38\xd4\xe3\xaf\xbf\x71\xd1\xc8\x1f\xc4\x84\x63\x60\x36\x3e\xa5\x41\xa9\x76\x62\x3a\x5e\x4e\x6b\x6a\x67\x23\x7e\x92\x37\x17\x3f\x1a\x1d\x54\x33\x02\x85\x88\x85\x71\x4c\x2a\x59\x1d\x0a\x78\x62\x82\xa0\x28\x5a\x37\x11\xf7\xbc\x2b\x63\xca\x79\x87\xe9\xae\x7d\x02\x03\x55\x55\xcf\x3b\x6a\xd6\xf7\x1c\xa9\x8a\xa9\x28\x88\x3b\xf8\x1d\xd6\xf8\x64\x93\xea\xab\x56\x37\xb4\xdd\x56\x9d\x1e\xe8\xde\x6a\x44\xbc\xed\xb6\x2b\x97\x06\xb1\xdb\x89\xe3\xf0\x5d\xf1\x63\x10\x01\x7d\x89\xef\x3e\x4b\xc0\x99\xb7\x21\xa5\xc8\xd3\x80\x43\xd6\xe4\xa2\x2c\xf0\x40\x09\xc0\xfc\xee\x6b\xe6\x99\x37\x82\x99\x54\x94\x1b\x8b\x4a\x1e\xbf\x4d\xae\xa0\xd7\x74\xd0\x78\x2b\xe1\x76\xc8\xe5\x91\x90\x77\x56\xc2\xcf\x75\xde\xa6\xf7\x87\x7d\xd6\x87\x5b\x8f\xe1\x01\x2f\x30\x50\xcf\xb1\x28\x9c\xf0\x88\x66\x7e\x15\x22\xee\xed\xc9\x27\xac\x86\xbf\xe2\xc4\x07\x43\x2b\x4a\x81\x3a\x6a\x7a\x55\x04\xe9\x99\x20\x6d\xb1\x82\x7e\x25\xfa\xfd\x70\xce\xd3\x6d\xb3\xb2\x81\xb6\xf7\xb1\x4e\xd5\xba\xa0\x57\x23\x15\xa9\x39\xc5\xbf\x4a\xbb\x13\x3d\x2e\x7b\x16\xd5\x2d\xe2\x08\x17\xaf\x05\x5d\xf5\xf1\x41\x20\x77\x34\x61\x0a\x0c\x6e\xeb\xed\xaf\xff\xd9\xcc\x9f\x06\x9b\x67\xf9\xa1\xc0\x45\x4b\xe4\x1d\x54\xc1\x38\xbe\x54\x2e\x5e\x38\xcf\xe2\xf2\x93\xf7\xd2\xd3\xdf\x66\x97\x7a\xcb\x36\x6a\x42\xc1\x9b\x31\x85\xac\xfa\x1b\x36\x3c\x61\x31\xa4\xa8\x11\x1c\x3b\x1f\x4f\xd7\xac\x40\x6d\x0e\x69\x10\x3b\xa1\x5b\x8c\x4b\xf2\x9b\xc2\xed\x9c\x45\xcf\xd1\xd2\x79\xd8\xd9\x31\x44\x4b\x2b\x18\x49\x25\x2b\x8a\x70\xee\xd8\x0f\xd2\x60\xed\xf5\xa3\xc0\x1b\x96\x90\x16\x0d\x23\x11\x85\x1d\x21\xc9\x30\x2d\x98\x59\x86\xea\xee\xb3\xae\x2c\x07\xc7\xc7\x67\x20\x94\xf9\x1d\xb0\xbd\x50\xbe\x37\x7e\x4d\x1e\xb0\x7e\xe7\x6a\xf4\x9d\xc1\x36\xa1\x45\xa1\x1b\x17\x2f\x08\x11\xfe\x73\xd6\x25\x9b\xe3\x70\xc4\xdf\xca\xb6\xf1\x9e\x4a\x64\xb1\x51\xd0\xa6\xdb\x80\x50\xc3\xde\x2c\xc3\x25\xf5\xc5\xf6\x59\x4c\xf6\x24\x8e\xb0\x81\x20\x95\x39\xe0\x8c\xa3\x42\x29\x84\xe7\xbf\x80\x3d\xe3\xa4\x19\xb1\x44\x23\xf1\xe5\xa5\x42\x24\x04\x2c\xe4\xf0\x54\x88\xa6\x04\x4f\x40\x42\xbd\x64\x9b\x1a\x08\xce\x10\xc2\x00\x6e\xa7\x6e\xfa\xb4\x64\x1f\xef\x28\x97\xef\xd7\x24\xe6\x05\x4a\x3b\xd1\xa6\x9e\x39\xa4\xa5\xe2\xd5\x02"}, +{{0x6d,0x78,0x55,0xe3,0x0f,0x7a,0x13,0xe2,0x37,0xb0,0x67,0x14,0x43,0x46,0x43,0x4b,0xb4,0xb0,0x51,0x78,0xc7,0xd8,0x8d,0x49,0x2e,0x79,0x02,0x7c,0x4b,0x0f,0x3c,0xdd,},{0x72,0x73,0x29,0x38,0x28,0xef,0xa3,0x49,0x82,0x23,0x92,0xdb,0xba,0xb0,0x78,0x79,0x57,0x7e,0x1a,0x77,0xa6,0xfd,0x6a,0xfe,0x33,0x75,0x3a,0x9e,0xec,0x88,0xc4,0xaf,},{0x0f,0xe2,0x8e,0xad,0xd9,0xe5,0xdd,0x57,0x4b,0x3f,0xaa,0xea,0x81,0x0d,0x44,0x52,0x2c,0x8b,0x1b,0xfb,0xb3,0xe3,0xd5,0x7e,0xd8,0x89,0xfa,0xed,0xec,0x91,0xd0,0xe1,0x4a,0x86,0xb9,0x14,0xc4,0xc7,0x66,0xf1,0xbf,0x9b,0x8f,0x18,0xb0,0xdb,0x89,0x0d,0xb6,0xc1,0xb1,0x25,0xd5,0x78,0x04,0x33,0x36,0x19,0xb1,0xe0,0x72,0x0a,0x33,0x00,},"\xf8\xb9\x36\xe7\x93\xb0\x17\x58\x0c\xc0\xe9\xcb\xda\x2a\xcb\x64\x74\x50\x7f\x4b\xca\x3a\xfc\x87\x83\xec\x46\xee\xb8\x2c\xcd\x4d\xd2\x52\x56\x76\xaa\x6a\xb5\xc0\xdc\xf7\xd7\x5f\x7e\x03\x11\xe6\xfe\x6b\xf2\x72\x63\xf8\x57\x8f\xeb\x55\xc5\x61\x2d\x1f\x28\xe8\x88\xb7\x66\x56\xc4\x1c\xcd\x8a\x70\xb9\xbc\x60\x4b\x42\x72\x4f\xa2\xbc\x41\x1d\x44\xc3\x1a\xb6\x8c\xe8\x4f\x83\x93\x39\x9e\x34\xd5\x40\x85\x79\xc2\xba\x29\x21\xf2\xf8\xd1\x14\x87\xaa\x7e\x52\x55\x7f\xee\xd9\x67\x57\x19\x9d\x3a\xae\x63\x77\x77\x01\x54\xb1\x7f\x35\x77\xc7\xac\x3d\x8c\x76\xcf\x74\x61\xb5\xe8\xd4\x2a\x71\x85\x07\x8e\xd4\xf8\x62\xfc\x57\x50\x2f\x61\x50\x75\x30\x7b\x6e\x10\x3c\x77\xc1\xf6\xc8\xbd\xa7\xaa\x17\xe4\x35\xe2\x1b\x94\x9a\xf4\x4d\xff\x5a\xa3\x0a\x62\xda\x71\x2f\xa9\x96\x6a\x61\x2f\xfc\xa1\x48\x71\xfd\x6f\x86\x0b\x4a\x96\x14\x01\x2c\x53\x69\x91\x0e\x0f\xfd\x6f\x0f\xbd\x88\x9a\x9c\x25\x7c\x32\xbd\xcf\x90\xbb\x80\x62\x7c\xb2\x72\xec\xd4\x59\x98\x97\x55\x59\x55\xe1\xfe\x08\xcd\x7e\xbb\x21\xc0\x71\xbe\x0f\x48\x98\x96\x96\xcb\x39\xaa\x82\xad\x11\xba\xa5\xd4\xac\x61\x3a\xbf\x1b\x6d\xb8\xa2\x0e\x68\x68\x36\x22\x28\x33\xf8\xb6\xdd\x2f\x00\x06\x22\x7b\xe4\x8e\x85\x80\xdc\xc8\xde\x62\x0d\xac\xb2\xf6\x5a\x69\x36\x75\xd6\xcb\x45\xba\x5d\xd1\xaa\x70\xdb\x76\xbc\x64\x1d\x4f\xb5\x67\xec\xbc\x71\x11\x44\x2e\x29\x41\x58\xbe\x57\x5c\x71\xdd\xc2\x6e\x94\xf4\x12\x66\xa2\xfd\x3a\x0d\x43\x57\x81\xfc\x09\x46\x48\xfa\xdf\x5f\x17\xcd\x41\xab\x89\x58\x21\x89\x4e\xc0\x80\x6b\x26\x2c\x39\x35\x34\xfe\x66\xf2\x1e\x37\x83\xc1\x4a\x96\xc8\x8f\x2e\x06\x53\xfe\x32\xe7\x5d\xce\x8a\x46\x3b\xb9\x7e\xed\x6c\x16\xf3\xf3\x22\x81\x69\xab\xb5\xb4\xbf\x9e\xa3\x27\x8c\x1f\xf0\xf8\x6e\xae\x71\x38\x9b\x64\x33\xac\xd0\x97\xee\xfa\x9e\x6e\x05\xf4\x95\x5c\xd5\x17\x83\x0b\x8d\x98\x70\xcc\xb5\x22\x74\x15\xe5\x0f\x23\xf6\x47\x32\x17\xa7\x45\x09\x64\x70\xdc\xa9\x3d\x2b\x34\x67\x3c\x5d\x6a\x57\xed\x02\xc8\xe0\xca\xe1\x19\xb3\xf3\x29\xd8\xab\x64\x98\x49\x4c\x29\x21\xbb\x6f\x49\x6d\xd0\x83\x81\xe7\xd3\x9f\x2d\xb5\x76\x3b\x14\xa2\x82\x1b\xef\xcc\xa0\xa9\xfd\x31\x25\x45\xde\x68\xab\xf2\x06\xd1\x2d\x8e\x02\xe7\x3b\xc7\xe3\xcb\x79\x6e\x7e\xe2\x6c\xc6\x3d\x74\x1e\xfa\xfc\x53\x45\xf8\x13\x29\x51\xbc\xfb\xfd\xdf\x63\x1f\xb7\xcb\x43\xef\x35\xb9\x45\x3c\x93\x90\xeb\x23\xb1\xf9\xd8\xb1\xc7\x2d\xeb\xd2\x4f\x09\xa0\x1a\x9d\xc6\x0e\xe6\x81\x53\x06\x18\x83\x57\x78\x1a\xf6\xe1\x82\x0a\xa3\x5e\x4e\xc1\x21\xb7\xca\x34\xd7\xde\x76\x11\xb2\x46\xa3\xe7\x03\xed\x48\xc7\xeb\x03\xa6\xfe\x8f\x85\x2e\xe7\xd3\x25\x45\xc9\xd8\x52\xd6\x4d\x5d\x75\x93\x0e\x5f\x1e\xbe\x21\xa3\x07\xef\xa7\x62\x2e\xda\xce\xd6\xd8\x79\x02\x6f\x0f\x85\xa9\x11\x20\x12\x80\x37\x05\x58\x22\x69\xd3\x9f\x14\x32\x34\xdf\x89\x09\xab\x3d\x94\x8e\x76\xd3\xda\xaa\x24\x22\x6d\x9a\xc6\x01\xee\xf2\x77\xfd\x2c\xfc\x4a\x19\xae\xdf\x43\x87\xa2\x16\x17\xb0\x3e\xc3\xd3\x84\x5a\x38\x55\x4f\x5e\x97\x03\x6e\x56\xec\x1c\xe6\x60\xdf\x9c\x06\x2c\x2c\x99\x3b\x77\xc5\xba\x6a\x6d\x05\x23\x1d\xae\x37\x64\x18\x3c\x3e\x96\xaa\x53\x9c\xfb\x34\x15\xfb\x16\x3c\x64\x5b\x23\x03\xb2\xd6\xd4\xbd\xa8\xca\x6c\x72\xbc\x03\xd5\x30\x5f\x9b\x11\x8e\x92\x5e\x27\xd2\x9a\xb7\xdc\xb1\x96\x47\x0e\x63\x39\x63\x1b\x23\x80\x74\x4c\x04\xd1\xda\x34\x8f\xc0\xfe\x27\x42\x77\xf8\x2f\x95\xbd\xfb\x0b\x64\xb4\xcf\x3b\x51\xe5\x71\xc0\xdd\xb3\xb5\x3c\xa6"}, +{{0x7e,0xe4,0xe7,0xe9,0x8c,0x6a,0x40,0xf0,0xe7,0x44,0x13,0xf2,0x40,0x39,0xbd,0x22,0x0d,0xf1,0xf8,0xc7,0xf0,0x15,0x52,0x8d,0xbf,0x52,0x84,0xab,0x9f,0x7c,0x82,0xe2,},{0x4d,0x5a,0x80,0x0f,0x9b,0x22,0x07,0x0e,0x01,0x6e,0xe2,0x3a,0xf8,0xa3,0x10,0x90,0x2b,0x36,0x9d,0x58,0x9a,0x84,0x7f,0x34,0x5c,0x2e,0xa2,0x96,0x8d,0x6d,0x09,0x24,},{0xac,0x3b,0xfe,0x3a,0xdf,0x94,0x1c,0x93,0x4d,0x33,0x49,0xc4,0x92,0xde,0x70,0xd5,0x16,0x6b,0xe3,0x89,0xf9,0x55,0xbe,0x87,0xc2,0x88,0x3f,0x41,0xf2,0xda,0x14,0x6c,0x91,0x06,0x51,0xa3,0xb4,0x52,0xc2,0xd7,0x39,0xdc,0x9b,0x53,0x1c,0x57,0x45,0x56,0x5e,0x69,0xd9,0x83,0x59,0xf1,0xd7,0xd9,0x3e,0xbd,0x36,0xd7,0x0a,0xbb,0xf0,0x0d,},"\x8f\xb0\x13\x73\xc4\x2e\x69\x61\x4a\xea\x99\xaf\x49\x32\x37\x85\xf3\x38\x61\xb9\x4e\x90\xf5\x65\x38\x9e\xbf\x70\xe2\x19\xf5\xde\xc7\x32\xe0\x01\x0b\x58\xf7\x29\x05\x30\xdf\x22\x2a\xc9\xc7\x3e\x1c\x2e\x92\xa5\xe6\x06\x1d\xe5\x59\x0c\xaf\x9c\x0d\x50\x21\xd7\x29\xea\xa1\x15\x41\xfa\x1d\x08\x21\x60\xbe\xaf\x61\x1e\x7c\xfd\xc0\xeb\xb3\x15\xd3\x88\xe5\x38\xb4\xb5\x02\x8f\x9b\x30\xd3\xd9\x73\x34\x7f\xfd\x44\x26\x3e\xef\x08\x3b\x81\xb2\x1b\x82\xec\xa5\x75\x6a\x49\x4b\x1d\x81\xc0\x7d\xe8\x49\x50\x6d\x3e\x3b\x66\x87\x97\xa5\xc5\x44\x25\x4d\x4e\xbe\x5c\xf8\x17\x1b\x39\xf8\x72\x4c\xbc\x41\x89\x29\x1b\x3c\x53\xc2\x1e\xce\x49\xa1\xd7\x39\x56\x3c\x65\xb4\x90\x25\x93\x56\x47\xa7\x30\x3a\xe0\xef\x7f\x6d\x24\x55\x46\x45\xa4\x28\xdb\xbb\x42\x44\x9f\x53\x99\xe3\x6d\xc7\x87\xb7\xd6\x95\x8a\x02\xee\xbb\xb8\x36\xe5\xe5\x3e\x26\xe4\x87\x23\x9d\xe9\x4d\x1d\x25\x0e\x79\x43\xac\x0e\x22\xd9\x27\x50\xa0\xcf\x34\x73\xbe\x1a\x62\x25\xcb\xe7\x95\x45\x04\x82\x69\xf6\x23\x7e\xc9\xf9\xec\x30\x7e\x8a\x34\xb7\xbb\x34\xcd\x49\x06\xe4\x31\x62\xa3\x70\x8f\x32\x9c\x5b\x98\x9d\x7a\x7f\xcd\xe1\x09\x9a\x54\x25\x46\xfe\x9c\x33\x18\x2b\xa5\x1b\x84\x3e\x96\xd1\x1c\x79\xe9\x1a\xd2\x1f\x71\x70\xe2\x57\xfd\xc2\x81\x8e\x12\xf9\x16\x8a\x97\x4c\x96\x8a\x4d\x27\x3f\xa3\xff\xa9\xf3\x5f\xf9\x05\x98\x0e\xaa\xd3\x72\x1c\xae\x80\x2b\xee\x36\x21\x0b\x40\xb9\x93\x19\xbb\x66\x99\x82\xe9\x43\xb2\x70\xa4\xc4\xd0\xa9\x2e\xcb\x5b\xba\x2d\xd8\xb4\x0a\xc3\xd2\xf0\x32\x5c\x46\x9d\x5e\x9d\x48\x3f\x52\x41\x97\x40\x10\xc5\xc0\xda\x33\x5f\x16\xe9\x62\x19\x6c\x2e\xf1\x4e\xb2\x4a\xaf\xbb\x31\x1b\xfd\x5f\xa8\xdc\x8d\x2d\x61\xe6\x87\x8a\xd2\xcc\xe0\xdc\x99\x39\xe4\x45\x22\x72\x3d\x42\x7e\xf3\x2f\xb4\x3b\x96\x7f\x5e\x44\xfc\x66\x57\x92\x79\x6f\x8c\xf9\x34\xf0\x1c\x32\x5d\x63\xd5\x83\xdc\x3c\xa9\xd4\xfc\xc7\x57\xd9\x17\x85\x80\xda\xef\x53\xaa\x3a\xb2\x1d\x2c\xe4\x35\x95\x5d\x1c\x6d\x47\x63\x8c\x5e\xdb\x62\xff\x55\x61\x69\x3d\x1c\xbd\x10\xec\x9e\x39\x9a\x71\xbf\x9d\xb1\xc9\x96\x9f\xd5\x9e\x4e\xeb\x31\xaa\x59\xbf\x39\xe9\xf1\x84\x17\x8d\xef\x72\x46\xed\x4b\x8f\x4b\xe5\xba\xda\xa5\xdb\x4a\xf8\x67\xf4\xf2\xec\x39\xa1\x37\x04\x20\x2c\x87\x84\xfa\x16\x8c\xe9\x6f\x9c\xfa\xc7\x10\x17\x23\x62\x75\xfd\x85\x7c\xc3\xc5\x1a\x9c\x7a\xc2\x56\x21\x5e\x14\xb8\x43\xf7\x21\x4d\xc9\xf8\x24\xb9\x1d\x1a\x51\x70\xd0\xef\x1d\x37\x69\x6f\x93\xee\x96\x6a\x2b\x7d\xec\xe2\x2b\x4f\x3a\xfd\x39\xc1\x6d\x60\x1e\x5f\xf8\x40\x8d\x45\xc1\xa6\xce\x71\xf0\x60\x97\x6c\x5b\xe4\xc0\x42\xb1\xb7\x38\xdf\x95\x80\xba\x5a\xe7\x78\x80\xa7\x0c\x0b\x94\xf0\xe1\xc9\xf9\xaa\x34\xc0\x90\xd6\x12\xd5\x7a\x9b\x93\x1f\x50\xa1\x25\xfa\x35\xce\x40\xa2\xcb\x7f\xaa\xd5\x30\xf8\x09\x08\xc7\x3c\xb7\x82\x58\xaf\xd2\x63\x13\x90\x04\x1d\x92\x61\x7e\x9b\xf6\x4c\xe9\x6e\x8e\x4a\xc7\xf3\x12\x6d\x8a\xf8\xa0\x4c\x75\xff\xd4\x38\x76\x9d\xe0\x6f\x74\xc2\xfc\x20\xcc\x81\x92\xda\x35\x3e\x79\x06\x12\x83\xbb\xa0\x8a\x8d\x24\xe6\xe4\xe2\xe8\x3b\xa5\xb0\x8e\x42\x75\x22\x60\x62\x14\x8d\x8a\x02\xaf\xad\x65\xb6\xf6\x27\xcf\xbd\x29\xb7\x1c\xa1\x8a\xee\x5b\x1f\x97\x16\x9b\xf0\x22\x8b\x37\x6f\x41\x06\xb5\x0f\xd9\x1a\x38\xa6\x62\x11\xd6\x9e\xbb\x4a\x7a\xf0\xe1\xc2\x21\x7f\x1b\xa0\x14\xd1\xe0\xcd\x17\x50\x8d\x58\x15\x5d\x16\x3d\xd9\xde\x2f\xe1\xc6\x4c\x7f\x88\xd5\xb5\x53\xe9\xba\x1e\x1f\x25\x43\x0d\x7e\x12\x5b\x07\xa8\xc2\xed"}, +{{0x1f,0x28,0xd9,0x09,0x1d,0x19,0x6c,0xba,0x3d,0x45,0x52,0xe5,0xa3,0x37,0xa4,0xd8,0xaf,0x3f,0x29,0x5e,0x62,0x9e,0x4b,0xa6,0xfe,0x99,0x70,0x31,0x20,0xae,0x41,0xe0,},{0x81,0x4d,0x34,0xbf,0x28,0xee,0x6d,0x90,0xf0,0x39,0x59,0x90,0x41,0xdb,0x81,0x0f,0x7c,0x9d,0xaa,0x91,0x8e,0x03,0xe9,0x61,0x97,0x41,0x4b,0xc9,0xaa,0x31,0xec,0xdc,},{0x5b,0xe5,0x52,0xfa,0x73,0x1e,0x83,0x67,0x93,0xf6,0xdd,0xa8,0x95,0xdc,0x9b,0x1e,0x2c,0xcd,0x66,0x9d,0xe1,0xc8,0x43,0xe0,0x0e,0xa6,0xfa,0x3c,0x5e,0xbf,0x97,0xa3,0x4b,0x26,0xf1,0xf3,0xac,0x7f,0xf2,0x22,0x5e,0xe4,0xa7,0xe4,0x30,0x07,0x2c,0x13,0xda,0x40,0x66,0xdc,0xdc,0xc0,0x5b,0xa2,0xb5,0xf6,0x1a,0x6e,0x8d,0x21,0x07,0x09,},"\xa6\x94\x68\xbc\x33\xeb\xfe\xf0\x61\x5c\x64\x3c\x49\xda\xc6\xe0\x4f\xdb\x6c\xfb\x8e\xc4\x58\x57\xbb\xb7\xa2\x7e\x52\x8f\xd6\x31\xfc\x34\x11\xba\xee\x65\xcc\x1f\x94\xfc\xc9\x4a\xed\x4a\x43\x32\xfa\x68\x61\xe0\x65\xe0\x61\x63\x54\x17\x09\xd7\x97\x28\xe0\x1b\xe2\xb1\x40\xa0\x22\xc8\x3e\x7b\x23\xb9\xed\x2a\xd2\x83\x21\x69\xdf\xc9\x56\x90\x91\x3c\xf3\x72\x01\x30\x65\x70\x80\xc9\xd5\xa7\x82\x7e\x56\x60\x75\x74\x52\xc5\xfc\x3d\xcd\x80\xcc\x6b\xe0\x98\xc6\x29\x22\x6d\x54\x66\xe0\x2b\x97\x12\x6b\xe7\x4a\x14\x52\xee\x16\x81\x50\x95\xde\xb4\x2b\xf0\x65\x66\x71\x50\x28\xc1\x18\x25\x82\x0a\x8a\x23\xc6\x0d\xa2\xb6\x8d\xd9\xa5\x5d\xad\x2a\x29\xa4\x96\x44\x43\x81\x7c\x07\xd7\x76\xb2\x44\xb1\x51\x86\x81\x9a\x3b\xbe\xd4\x14\xab\xf4\x57\x9a\x3e\xce\x3a\x3d\xc7\xb1\x05\xd0\xa9\xdb\xa3\x7b\x9e\xaa\x78\xbe\x8e\x46\xe1\x69\x8b\x59\xb0\x94\x0b\x01\xf3\x8b\x28\x3c\x33\xa9\xa4\xb1\xd4\xf8\x14\x4b\x16\xee\xb5\xfc\x0a\x7a\xf0\xd0\x81\x69\x66\x45\xa1\xea\xb3\xa7\x87\xcb\xcf\x88\xfa\xd9\x3d\xd6\xcd\x46\xd2\x95\xa8\x79\xa1\x77\x50\x33\xa9\x85\x63\x82\x2e\xf1\xf6\xb6\x9a\x58\x1e\x49\x73\x6c\x8d\x70\x1b\x44\x53\x96\x93\x40\x52\x1e\x4a\xd4\xbf\x94\xb9\x11\xb0\xe2\xd8\x6f\x34\xee\xce\x4a\x63\x85\xff\x1f\xe6\x32\x20\xcd\x3c\xc5\x92\xf3\x6d\x6c\x49\x1f\xa1\x8f\x7c\x14\x04\x36\x0d\x2a\x77\x53\xfe\x07\x3e\x09\xa2\xfc\x42\xa4\xbb\xea\x55\xbc\x96\xd7\xf0\x5c\x98\xae\xd2\xcc\x4a\x9f\xae\x8f\xd4\xa0\x19\x7f\xf0\x1f\xa7\xf0\x04\x6e\x3c\x3e\xb5\x9a\xaa\xbc\xa3\x13\xa4\xdd\xaa\x5d\x20\xd2\x7c\x2c\x5f\x1a\xc6\xd8\x7f\xd3\xcb\x4b\xd3\x5a\x1e\xc7\x5d\x10\x4f\x7c\x36\x73\x31\xa3\xe2\x95\xe5\x3c\x4e\x80\xba\xe1\x4b\x97\x92\xd0\xd5\x26\xf7\x40\xd4\xff\x03\x6f\xaf\x54\x87\x96\x7f\xfa\xbe\x8e\x88\x3d\x3f\xb0\xd1\x6f\xaa\xdb\x28\xe1\x28\x5d\xed\x41\x57\x0c\x0b\x07\xc2\x55\x9b\x53\x1e\x0f\x92\x54\xef\x88\xe5\xb1\x0f\x64\xf4\x83\x9a\x9a\x0b\x6c\x3c\x7f\x1b\x78\x50\xf4\xad\x9b\xf0\x99\x9a\x7f\x2a\xe7\xc4\x5a\x65\x8e\xa5\x30\x36\xfc\x70\x19\x98\x42\xb8\xe4\x9e\x60\xf9\x67\xde\x1f\xf3\xab\xff\xf6\xcd\x73\x5b\x7c\xd8\xb8\xf9\xe2\x48\xf1\x56\xf6\xc6\x54\x38\x69\xeb\x99\x82\x3d\xae\xa8\x8d\xeb\xaf\x79\xf0\x1e\x65\x21\xec\x63\xfe\x72\x72\x4e\xe3\xc8\x22\xb8\x8b\x39\x68\xb2\x48\x52\x09\x15\x83\xc4\x9a\xb3\xc1\x5f\xa1\xf7\x9b\x18\xd9\x8f\x04\xd9\xb6\x84\x1c\x9a\x7c\xa0\xde\x2f\xcc\x02\xf9\x5d\xd6\x49\x49\x2e\x8b\x56\xa3\x1e\xc1\xe2\x44\x33\x7a\xf6\xaa\xae\xde\x8b\xf9\x9f\xc8\x14\xef\x57\xc0\xd5\xe0\x8c\x3c\x7e\xcc\x18\x97\x98\x0a\xa1\x69\xa9\x92\x6d\x20\x69\x8d\xf6\x93\x0e\x21\x10\xcb\x46\x0f\x49\x39\x01\x00\x74\x10\x95\xf8\xed\x00\x41\x2a\xe6\x96\xd9\x8e\xfe\xfd\x29\x0d\xa5\xf7\xd0\xb7\x28\xd2\x0a\x1e\xbf\xa6\xbd\x7d\x27\x0f\x28\x1a\x98\xc7\xb1\xe4\x08\x43\x51\x25\xaa\x48\x3c\x6b\x7d\x63\x3f\xf7\x58\x8a\x94\x16\x58\xf6\x12\x95\x44\xd6\x29\x45\xb9\xb8\xaf\x71\xa8\xc6\x2c\x0a\x50\x07\x6c\xb8\x54\x1b\xa7\xe4\xbd\xe4\xed\xe4\x41\x72\x2c\x6e\xb9\xdf\x8c\xfd\x06\x56\x33\x9e\x86\xd2\x26\xab\xae\xa0\x5e\xa0\x47\xf6\xb8\x30\x77\x01\xf6\xc9\xa4\x4c\xc9\xcb\x83\x7b\x8e\xb6\x24\x45\x92\x5e\x8a\x88\x81\xd2\x53\x8f\xcb\x2b\x24\x9e\x4e\xe8\xb6\x86\xec\xfb\x49\xc4\xdf\x86\x40\x1d\x24\x9a\xac\x35\x84\x1e\x91\x40\x04\xf9\x45\x5d\x3f\xde\x37\x5d\x20\xa0\x1f\xba\x27\xb1\x97\xa6\x98\xd3\x84\xc7\x65\x05\x10\x68\x01\x62\x7e\x83\x36\xbd\x2d\x76\xd7\x61\xa8"}, +{{0xc6,0x4d,0xd2,0x0d,0x42,0x62,0x75,0x26,0x19,0x8a,0x22,0x64,0x76,0x90,0xc8,0x95,0xb5,0xb4,0x5b,0x69,0x8f,0x57,0xa6,0x9d,0xfb,0xe4,0x8d,0xbd,0x42,0x6a,0xa4,0x70,},{0x2e,0x01,0xd4,0x04,0x16,0xf7,0x8a,0xcd,0xdb,0x34,0xb8,0x44,0x5e,0xa4,0xfd,0x0a,0xb3,0xfa,0x9e,0x66,0x43,0x04,0x47,0x52,0x21,0x3f,0x07,0xc7,0xf0,0xff,0x43,0xa0,},{0xde,0xac,0xc8,0xc2,0x32,0x18,0x72,0x76,0x76,0xd5,0x40,0xa2,0x3b,0xda,0xd7,0x81,0x02,0x11,0xe6,0xd5,0x7a,0xd2,0x94,0xc3,0x7d,0x4b,0x1c,0x9a,0xf6,0xb3,0x37,0xa5,0x3f,0x78,0x80,0xd2,0xba,0xfa,0x73,0xb3,0x05,0x08,0xc0,0x08,0x42,0x6b,0xf8,0xd7,0xc9,0x65,0xa1,0xf4,0xa4,0x22,0xa1,0xbc,0x7d,0x6a,0xd6,0x22,0x6f,0xd1,0x97,0x06,},"\x82\x1b\x9f\x7c\x16\x10\x4b\x53\x3b\xd1\x27\x18\x4f\xd7\x2a\xde\x09\x2b\x13\xbb\xd9\xac\xee\xd2\x9b\x8d\x10\xf1\x66\x88\x92\x2d\x16\x5f\x89\x31\xd5\x3d\xf5\x90\xfb\x71\x3b\x67\x4d\x80\x5c\xe0\xc9\xd6\xce\x6c\x43\xba\x69\x68\x19\x1d\x12\xbf\xa0\x8a\x8c\xe2\x2e\x8f\x33\x6b\x2b\x49\x1a\xf2\x5d\x1b\x16\x06\xf9\x30\xca\xeb\xe5\x22\x39\x2a\x87\xd4\x2c\xe7\xbc\x16\x7a\xa7\xb6\x10\x59\x72\x20\xaf\x31\xa6\x65\x35\x30\x71\xe8\xd9\xe5\xf4\x20\x78\xb9\xc3\x88\xbf\x04\x02\x58\xe2\x1f\x9c\x3a\xb3\x8c\x04\x27\x61\x8b\x2c\x28\xd3\x43\x0d\xf2\x79\x21\xbf\xc5\x84\x87\xb3\x46\x19\x78\xbf\xa8\xbf\x58\x6c\xfe\x83\x58\xe0\x92\xf8\xf4\x74\x66\xe7\x62\x45\x1d\x50\x16\x4a\x0d\x74\x36\x0f\x66\xb4\xcd\x3a\x35\x75\xda\x01\xda\x23\x75\x24\x30\xc0\x35\xda\x85\x9f\x57\x7d\xe2\x22\x90\xaa\xb4\xed\x7f\x34\xd2\x67\x40\x6a\xb5\x47\xeb\x44\x5c\xc6\x4d\xf5\x30\x19\x42\x7f\x4e\xb7\x2b\xca\x55\x39\x71\x53\xd0\x1c\xcf\x7e\xc9\x7d\x7a\x96\x7d\x9a\xff\x46\x23\x1d\x2e\x20\x27\xb3\x8f\x3b\x41\xbd\x2c\xb1\xb7\x98\xa4\xae\x88\xab\xf4\x89\x62\x16\xd3\x15\xbd\x53\x83\x02\x42\x59\xe5\x97\x42\x80\x2a\x91\x1b\xad\xcf\x84\x73\xdb\x91\xaf\x31\x97\x33\x32\x0c\xb9\x52\x1e\xf9\xce\x43\x72\x67\xb6\xea\x17\xbc\xaf\xe5\xd0\x90\x3b\x12\x3a\x35\xc9\x88\xf4\x98\x34\xf6\x1d\xd5\x52\x64\x0a\x32\x76\xda\x26\xaf\x17\xec\x21\xa2\x02\x96\x58\x6d\xd6\xf4\xb3\x6c\x7a\x4f\x0b\x89\x9d\x70\xb4\x2a\xf8\x9e\x29\x37\x01\x32\xed\xfb\x72\xd6\x83\x41\x94\xa1\x60\x93\x60\xb1\xf1\xfe\xab\x89\xb9\x6b\x8e\x8f\x0f\x68\x98\x7c\x57\xcc\xe0\xba\xb7\x68\x11\x37\x18\xfb\x17\x09\xde\x2d\xf3\x21\x77\xd4\x40\x85\xda\x5e\xfd\x9d\xa7\x0e\x1a\x85\x8c\x92\xf2\x45\xac\xfe\xe6\x4b\x71\xf3\xeb\x16\xe0\x4f\xc1\x39\x89\xe6\x93\x37\x99\x97\x01\xdd\x73\xab\xc2\x66\xc9\xfd\x4c\xff\x91\xa0\xfd\x04\xfb\xd8\xb1\x3b\x12\xe6\xf4\x50\x38\x57\x15\x84\x8e\x00\x7f\xa0\xd4\x63\x11\x9f\xd7\xde\x63\x25\xb6\x40\x04\x2b\x65\x42\x12\xe0\xdb\x8d\xa1\xad\xeb\xd2\xa7\x58\x9f\x77\xee\x4f\x75\x2d\x28\x2c\xa1\x11\x9c\x43\x1b\x17\xad\x0a\x02\x1e\xf2\xbf\x95\xe5\xac\x47\x04\xe6\x2d\x70\x39\xd0\xe6\x51\xe4\x56\xd6\x0e\x63\xba\xde\x40\x1c\xca\x77\xc9\xa8\x91\x63\x17\x4d\x50\x22\xd7\x45\xab\xdc\x76\xb9\xff\xe2\x54\x41\x55\x23\x5e\x30\x63\xe6\xe4\xae\xec\x44\xed\x5d\x8a\xb4\x08\xd9\x66\xfe\xc1\x20\x16\xc1\x30\x73\x0b\xbc\x55\x87\x32\x06\x5d\xa8\x00\xa7\x0c\xbf\xb0\xfc\xcc\xa4\x5d\x00\x28\xcb\xfd\x96\x32\xdd\xb2\xf0\xed\x12\xed\xae\x7b\x93\x0b\x10\x6c\x9d\x12\x85\xa4\xb8\x70\xde\x75\x07\x99\x9c\x74\x79\x3d\xd4\x97\x40\x87\x19\xc8\x98\xab\xe4\x9f\x7f\x33\xa3\x3e\x69\xb5\x0f\xa5\xaf\x94\x80\x06\x85\x66\xd1\xfd\xdf\x44\x82\xd7\x97\x04\xad\x8e\xf1\x1b\x88\xb4\x2c\xc6\x9f\xce\x8a\x55\x7b\x5b\xa5\x10\xe7\x08\xb9\x37\x51\x23\x03\x85\x68\x27\x0d\xe4\x07\x23\x2e\x95\x62\x1e\x2d\x04\x57\x0b\xec\x2c\x41\xec\xcf\xd8\x55\xb2\x1f\x0c\x9b\xba\xa2\x3b\x5c\x58\x15\xfc\x88\x8f\x7f\xbe\xd4\x82\xc3\x20\xff\xa1\xe0\x63\xe8\x7b\x55\xbc\x8f\x7e\xee\xa3\x74\x06\x3a\x9b\xe6\x5f\x7e\xd9\x22\x5b\xf6\xca\x34\xcf\xa3\x11\xb7\x9f\x3a\x25\x8c\x25\x2e\x63\x45\xed\x6a\xc8\x47\x48\xf4\x68\x07\xa5\x5d\x4b\xa4\x12\x66\x16\x9c\xd2\x62\xd4\xf7\x22\x79\xef\x0c\xaa\x77\xff\x44\x93\x35\x32\xbd\x13\x74\x75\x6c\x23\xec\x85\xf5\x5e\xfe\x9f\xc2\x33\x1f\x26\xf8\x81\x62\x9f\x80\xc2\x69\x2f\x7f\x53\xe4\xbc\x6f\x22\xef\xb4\x54\x57\xa2\x23\xf0\xd1\xc4"}, +{{0x0f,0x8e,0x9f,0x35,0x26,0xb4,0xfa,0xea,0x92,0x76,0xf2,0x2a,0x17,0x79,0xe6,0xf8,0x27,0x09,0x80,0x8f,0x6d,0x0c,0x61,0x2a,0xdf,0xe3,0x2a,0x6e,0x8a,0x06,0x10,0x05,},{0xd4,0x8c,0x3f,0x0f,0xde,0xf3,0x82,0xd1,0xd8,0x03,0x13,0xe8,0x46,0xfc,0xa9,0x5e,0x41,0x81,0x76,0xbb,0x5d,0xfa,0x9d,0x39,0x8c,0x1d,0x21,0x24,0x77,0x6f,0x69,0x0a,},{0x2f,0x59,0xa2,0x93,0x60,0x73,0x91,0x38,0x34,0xeb,0x15,0xa0,0xe0,0xbc,0xb9,0xaa,0x80,0x40,0x89,0x46,0x8f,0x24,0xdd,0x1b,0x2d,0x37,0xa1,0x93,0x4a,0xe9,0xba,0x10,0x20,0xff,0x64,0xb7,0x2e,0xec,0x03,0x26,0x8d,0x0a,0x7c,0x01,0x2c,0x4e,0x79,0x63,0x00,0xf6,0xdf,0x7a,0xdd,0xa0,0x1c,0x8b,0xc5,0xe9,0x01,0x5c,0xcd,0xee,0x1a,0x00,},"\x0c\xcd\x37\xc4\xcf\xd8\xe7\x0c\xa3\xbb\x39\x46\xd0\x9d\x70\xd0\xf6\xa4\xb8\x1d\x6d\xfb\x07\x9d\x78\x73\x74\x80\x71\x58\x98\x80\x92\x73\x82\xf7\x43\x6a\x6e\xf8\xf5\x1c\x25\x54\x73\xdd\x01\xfe\xb5\x2c\x8e\xdb\xe4\xd3\x25\x57\x13\xe6\x8d\x64\x0f\x3d\xcf\x15\x8f\x2b\xfb\x9f\xbe\xcf\x71\xf0\x71\x9d\xfe\x8c\xe6\xb6\x01\x28\x1b\xa6\xc2\x0a\x56\xb4\xf8\xe7\xca\xa4\xaa\x9f\x86\x8f\xbf\xc5\xe4\x32\x1c\x22\xd6\x5f\x03\x82\xc4\x89\x6b\xf9\xbe\xbe\x35\x46\x94\x9e\x81\x85\xa4\xd8\x17\xe4\x5b\x5d\x12\x93\x95\x38\x21\xbd\xd9\x8e\xc2\x59\xf6\x4a\x3d\xe5\x38\x65\xb1\x49\xea\x01\xc8\xf6\x83\xec\xda\x61\xda\x5d\xc1\x0e\x7e\xbd\xdd\xfe\x74\x84\xf5\xeb\x10\x31\xb7\x91\x65\x87\xca\xa3\x99\xa0\x6b\x6f\xea\x4c\x5e\x6e\x0b\xe6\x50\xfb\xdf\x06\xc1\x03\x6d\xf2\xcc\x35\xf6\x2e\xa0\xea\x71\x3f\x52\x80\x9d\x77\xf4\x7c\x2e\x55\xc9\x23\x92\x48\x16\x80\xb6\x33\x20\x56\x22\x69\x13\xb0\xce\x88\xa6\xc5\x5a\x26\xbd\xb5\xb8\xba\xb3\xcf\x46\x95\xa8\xc5\x22\x30\x2c\x4e\xba\x37\xd3\x1f\xf7\x7e\x58\x30\x1b\xcc\xfc\x7c\x7b\xe8\x58\x0c\x63\x42\x68\x79\x95\xf4\x4a\xcd\x19\x09\x65\xae\x0d\x7b\xf0\x66\x95\x92\xb6\xad\x88\x74\x3e\xbb\x36\x0c\x73\xe0\x48\x4a\x23\xd2\xf9\xe9\x9e\x9e\xb0\x38\xdc\xbd\x87\xca\x9b\x1a\x49\x8f\x1b\x2d\x35\xfe\xdd\x7f\x8e\x1f\x7f\xd8\xca\x52\x64\x86\x91\x1e\x07\x6a\xea\xb4\x87\x7b\xba\xcf\x37\x8a\x28\x55\xf9\xc5\xac\x03\x91\x30\xdc\x69\x0e\x17\x7d\x67\xb2\x44\xcc\x8a\xd0\x32\x37\x9e\xf7\x1f\xe0\x5e\x9c\x86\x13\xd8\xf5\xd6\xea\x3d\x4e\x3e\x47\x22\x20\x29\xcc\x00\x42\x53\xbe\x47\xf8\x7f\xb5\xe3\x31\x4c\x48\x98\x13\x4b\x87\xac\xf1\x0b\x25\x38\xba\xd8\x97\xbd\xc5\x01\x2d\x8f\x97\x62\xc8\x71\xb6\x53\xd4\x00\xfe\xe0\xce\xed\x5e\xf6\xbd\xd1\x6f\xaf\x3f\x0a\xbd\xbd\x72\xcd\x0a\x12\x94\x05\x46\xf0\x99\x5f\xf1\x4b\x0f\x1b\xd5\x48\x56\xff\x74\xc3\x6e\xb4\xf2\x2d\x72\x87\xae\xfd\xc6\x09\x99\x8c\x1f\x41\xbc\xc3\xbb\x3a\x5f\xa4\x92\x34\xf4\xfa\x8e\x92\x9c\xd0\xf5\x54\xb3\x15\x39\x5d\xae\x87\x3c\x61\xca\x70\xe0\x41\x0c\x2f\xd5\xa1\x15\xd2\xa6\xff\x1f\x1c\x94\xb2\x7b\xa4\x50\xb8\x19\x4b\x21\xf0\x95\xc6\x1a\x5f\x21\x5e\x3c\x84\xf5\xd4\x3f\x0e\x73\x62\x86\xd3\x3b\x8c\x47\x81\x4d\xb9\x79\xf9\xdc\x00\x91\x98\x46\xbe\xe6\x85\x33\x7d\x99\x55\x5a\x24\x47\x2e\x6b\x00\xb3\xf4\xa1\x43\x11\xa6\xc7\xc9\x04\xba\x58\x89\xda\x6c\x1d\xdc\xc1\x11\x75\x80\xf5\xfb\xc4\x1f\x2b\x8a\x42\x68\xcf\x0e\x9f\xa5\xbf\x41\x25\x34\xc9\xe4\x05\x2a\xac\xb5\x04\xcb\x86\xe2\x14\x7a\xb8\x02\x3d\x58\x80\x0b\x76\x3f\x9a\xbf\x9d\x04\x40\x78\x8a\x51\xdf\xe5\xcb\xd4\x42\x30\xba\x52\x28\xf1\xf5\x96\x0e\xa3\xa4\xe4\x04\x4d\x36\xda\xf8\x11\xcb\xdb\xec\x5d\x69\x64\x63\xd8\xe9\x41\xf2\x72\x17\x56\x3b\xb4\x4a\x21\x18\xa4\xf5\xac\xd6\xe7\x94\xde\x17\xe0\x28\xcb\xde\xef\xde\xf2\xcb\xf0\x3d\xd3\x2e\x78\x99\xe6\x5a\x1c\xf8\x39\xf5\xd9\x0e\x1f\x8c\x36\x4b\x57\x7f\xe3\x10\x53\x53\xf6\x67\x68\xdb\xf7\xaf\x0c\x52\x1a\xa8\xa4\x9f\x7a\x22\x08\x2d\x88\xf9\x01\x49\x8c\x90\xb9\xd7\x77\x7e\xd2\xf9\xf0\xe8\xa5\x52\xd8\xa1\xfa\x5e\x96\x32\xed\x85\x32\x58\xc9\xc2\x15\xb6\xdb\xb4\x11\x1d\xcf\xca\x55\x4b\xfb\xc9\xbb\xa2\x2f\x88\xbc\x55\x55\x2c\x6d\x86\x25\x56\xd7\x41\xda\xd5\x9f\x21\x5e\x37\x28\x83\x46\xca\x7d\x7f\xd8\xc6\x5a\x38\x0d\x72\x0c\xaf\xf9\xef\xa1\x49\xf3\xfd\xa2\x32\xda\xa5\xb1\x2e\xf1\x1c\x0a\xf0\x86\x2b\xd0\x22\x9e\x07\x5a\x3c\x6b\x60\xef\x0b\xbb\x3d\xad\x7f\x29\x08"}, +{{0xfe,0x7c,0xdc,0x79,0x66,0xd0,0xff,0xb9,0xc7,0x6f,0x4a,0x18,0xe7,0xf0,0xbf,0x90,0x69,0x0e,0xb7,0x6d,0xc3,0xd3,0xd5,0x08,0x84,0x64,0x8e,0x2e,0x39,0x37,0xd0,0x20,},{0xa1,0x2e,0xe9,0x81,0x2d,0x6a,0xf6,0xaa,0x48,0x79,0xfa,0x72,0xbc,0x0a,0x69,0x80,0x4e,0xa1,0xa8,0x5f,0x9b,0xc4,0xa2,0x6a,0x5b,0xa7,0xcf,0xbb,0x91,0x4d,0x0d,0xd9,},{0xb5,0x2d,0x03,0xfd,0xeb,0xcd,0x42,0x97,0x37,0xef,0x70,0x92,0x06,0x87,0x21,0x1f,0xbb,0x4c,0x04,0xf8,0x1e,0x35,0x5c,0xec,0x70,0x72,0xc5,0x05,0x41,0x75,0xd2,0xed,0x77,0xf3,0x8f,0x46,0x6f,0x00,0x14,0x22,0xda,0x8f,0xcd,0xf0,0x67,0xdb,0x14,0x51,0x00,0x7c,0xab,0x60,0x7f,0x04,0x9c,0x2e,0x26,0x07,0xb5,0x7d,0x44,0x71,0x3c,0x04,},"\xdc\xb9\x1c\xf1\x55\x46\x1a\x60\xdf\x07\xee\xc2\x9d\x98\x61\x6e\xd1\x72\x8b\x34\xef\xa9\xe1\xf7\x44\x5a\x91\x58\xa8\xf8\x8d\x7f\xaa\xae\x0e\x24\x72\x5a\xef\xf2\x63\xc3\xf7\x4f\x0c\x68\x4f\x18\x58\xf0\x5b\x69\x95\xd2\x84\x6b\x6a\x83\x2f\x67\x08\x5a\x42\x76\xd8\x66\x1a\xeb\xd3\xbf\xcc\x73\x18\x1f\x1f\x51\x02\x93\xb6\xde\x5e\x4b\xb2\x3f\xf2\xdc\xa1\xdf\x60\x8c\xb1\x4a\xe5\x22\xac\x4b\x51\xe1\xf9\xb9\x73\xab\x8b\xaf\xcd\x53\x4e\x71\xc5\x71\x81\xb1\x18\x96\xee\x10\x61\xfb\x36\x9c\xa4\xd2\x93\x9d\x1e\x57\x06\x0d\x9f\x4d\xb0\xa5\xc0\xb0\x7d\x52\x68\x7f\x15\x78\x17\xe6\x3e\x2f\xe7\xeb\xcc\x3e\x7c\x95\xef\xe0\x5b\x85\x99\x10\xc9\x5e\xed\xe8\x6d\x14\x39\x9e\x61\x62\x48\xa2\x8c\x24\xc4\x14\xdb\xb6\x93\xaf\x9b\xe4\x35\xa3\xa9\xcd\xc3\x3e\x0e\x2a\x58\x69\x18\xd9\x1b\x8a\x85\xce\xdd\x16\x12\xd7\xc1\xa2\x17\x92\xbd\xd4\x3a\x91\x5b\x15\x7e\x04\xbb\x3a\x44\xec\xbe\x23\xfa\x49\xcc\x55\xda\xab\xbe\xaa\x15\x5a\x73\x7f\x76\x5b\x8d\xdb\x0f\x3b\x15\xd4\xec\xf2\xce\xf7\x05\x4c\xa7\x3e\xc8\x7d\x91\x75\x2c\x2e\x99\x19\x5c\xdb\x19\x58\x84\x4f\x14\x4e\xda\xb8\x2a\x97\x54\x9f\xc9\xce\xc0\x8e\x87\x11\xcf\xf8\x63\xb6\x3f\xc2\x31\xa7\x7f\x76\x2e\x5c\xd9\xda\x9d\x59\x40\x92\x52\xe9\x9a\xb0\x4c\x42\xbc\x57\x09\x7e\x46\x4e\x3c\x6a\x48\xd8\x02\x41\xe6\x32\x5e\x3e\x40\x94\x98\x9b\x34\xc0\xe8\xb3\x2b\x1a\x78\x29\xd5\x4d\xf3\x2a\x05\x0e\xe8\x7d\x8f\x7c\x4f\xe3\xe4\xf4\xf7\x04\x9d\x1f\xee\xcd\xbe\xa6\x71\x08\x35\x0d\xb4\xe8\xed\xbe\x3c\x3f\xf8\xab\x2a\x25\xd1\x47\xb1\xc1\xc5\x82\x1b\x0f\x8c\x21\x04\x2d\x65\x5d\xb8\x31\x69\x1f\x59\x98\x3f\x27\xd2\xed\x1d\x49\x06\xc5\x44\xe2\x4e\x79\xbe\x68\x65\x3c\x9b\x22\x9a\x7f\xb6\x1e\xf5\x45\xba\xb1\x6e\x98\x81\xcb\x4d\x92\x65\xe2\x93\x59\x0a\x0b\xc2\xdc\x86\xba\xd2\x30\x07\xff\x40\xc9\x58\x61\x92\x3b\x49\x82\x41\xc1\x0d\x26\xbf\x48\x48\xf6\x2b\xa7\x38\x3f\x64\x9d\xc3\x8a\xf1\x84\x0d\x0d\xe9\x28\xa9\xbf\xee\x5e\x11\xb5\x14\x34\x16\x3a\x7a\xb1\xed\x53\x74\x15\xf1\xe9\x32\x85\xe3\x69\x92\x05\x72\x01\x58\xf9\x55\x7d\x86\x41\xed\x2b\xf4\x85\xb8\x21\x2c\x8f\x82\x66\x8b\xac\x3c\x22\x8e\x69\x24\xc1\x7d\x0d\x98\xf2\xe6\xd9\x23\x43\x71\xc4\x42\x5e\xb7\x58\x68\x9f\xdb\x0d\xc1\xce\xa1\x39\x4a\x28\x62\xe8\x7b\xb3\x8e\x62\x4c\x34\x79\x91\x68\x61\x32\x78\x22\x5f\xb5\xe1\x9c\x92\x47\xad\xa3\x55\x54\xf2\xc4\xad\xdb\xb6\x1d\x5a\x50\x2a\x70\x81\x27\xd6\xef\xbc\xa8\xf7\x35\x09\x0b\xdf\xdd\x88\xdb\x29\xfb\xd1\x4b\x69\xab\x12\x62\xf0\xc3\xe2\x6d\x26\x3a\x59\xc5\xae\x46\x39\x06\x53\x83\xd5\x25\x0b\x54\xcf\x59\x2b\xb7\xad\xfe\xaa\xe0\xd2\xfe\x81\x6b\x63\x81\xe8\x6e\xa2\xd1\xc7\x18\x13\xcb\xc3\xd8\xfe\x2d\x31\xde\x7b\x30\xfb\x6e\xc2\x29\x4f\xe4\x53\x6a\x36\xc6\xa1\x83\x5a\x71\x62\xab\x4b\xf8\x9d\x19\x46\x61\x19\x65\x7b\x0e\x46\x45\xae\xf5\x03\x50\x5b\x4d\x55\xdf\x97\x7b\xd2\xc9\x0c\x64\x40\x6f\x49\x70\xd5\xcf\xf2\x45\xb8\x35\x32\x2a\x6f\xbe\x23\x4e\x5e\xfb\xb5\xea\x45\xe8\xf0\xd3\x97\x3b\xe4\xaa\xa2\xaa\xda\xab\x07\x7d\x6c\x9b\x25\xbd\x44\x94\x40\x9e\x93\x47\x9d\x2d\x15\x07\xf6\x6b\xc8\xbe\xf8\x29\x99\xa1\x3c\x79\x43\xb4\x72\xb9\xe6\x1e\xc2\x9d\xeb\xef\xbf\x22\x41\x42\x3e\x0f\xaa\x42\xc1\xa3\x38\xa7\xa6\x13\x1d\xed\x93\x5b\xa0\x3a\x28\x66\x2e\x68\x59\x33\x68\xdd\xe5\x4b\x46\x2f\x2a\x5f\xb7\x46\x18\x5f\xf5\x50\x3e\x69\xba\x36\xbf\x16\xf7\x14\x58\xcd\xd0\x57\xe5\xc1\x72\x67\xf6\x74\x98\xd6\x52\x86\x0b\x46\x5e"}, +{{0xf6,0xc9,0xab,0x5e,0xa7,0x5f,0x29,0x4e,0x8e,0x0c,0x07,0xc4,0xc0,0x9e,0xd8,0xee,0xa3,0x11,0x3b,0xdf,0xc2,0xef,0x75,0x9e,0x20,0xa2,0x64,0x57,0x16,0x04,0x10,0x8d,},{0xb1,0x2f,0xf5,0x5b,0xd3,0xec,0x42,0x61,0x0e,0xac,0xea,0x28,0xb3,0x13,0xa1,0x6e,0x19,0xc9,0xe8,0xb4,0x7c,0x2b,0x15,0x17,0x09,0x91,0xbe,0x08,0x8d,0x65,0xcf,0x63,},{0xa7,0xf9,0xd0,0x8b,0xa1,0x41,0x83,0xef,0x24,0x7f,0x2c,0x25,0xfe,0xcc,0x2b,0x83,0xed,0xa6,0xde,0x58,0x02,0x2e,0x46,0x6c,0xe7,0x8f,0xcf,0x50,0xf7,0x1c,0xe2,0x61,0x62,0x44,0x65,0x62,0xee,0xa4,0x5d,0x63,0xa2,0x1c,0x3b,0x22,0x56,0x1f,0xd4,0x68,0x00,0x58,0xac,0xb8,0x25,0x40,0x7a,0x15,0x40,0x8f,0x27,0x13,0x61,0xa1,0x46,0x0f,},"\x71\x62\x3b\x39\x74\x3e\x39\xc7\xe0\x86\x38\x80\x6d\x46\x8a\x1a\x8a\x6f\x35\xc2\xae\x38\x8e\xef\xc2\x73\x74\xbb\x52\x53\x88\x14\xc4\xb3\x6c\x9b\x8e\x38\x9a\xd8\x31\x83\xde\x02\xa1\xbb\xd0\x32\x57\x34\xe4\x61\x87\x54\x09\x23\x37\xd3\xe7\xdc\x12\x56\x92\x8e\x35\x28\x87\x0c\xa7\xf0\x06\x13\xa2\x5b\x71\xbb\x15\xd1\xd9\xea\xaf\xf9\xf2\x26\x9b\x71\xc1\x97\x69\xe0\x03\xce\x84\x56\x14\xb2\xec\x95\xed\x28\xca\x85\x5b\x52\x21\xd4\xcb\x80\xa6\xca\x94\x66\xaa\x33\xe2\x51\x0d\xdf\xf7\xdc\xe1\x86\x15\x9d\xa7\x0f\xc8\xb1\xfb\xac\x12\xa2\x6e\x1f\xc0\x94\x22\x76\x89\x2a\xd6\xe9\xb0\x03\xf5\x69\x59\xbd\x31\x3a\xf2\x89\xe7\xa0\x53\x2a\x66\x4b\x76\xb9\x6b\x91\x98\x54\xe0\x65\x0c\xb8\xc5\x2e\xc4\xc5\xfb\x50\x53\xaf\x2f\x0c\xf8\xc0\xf2\x2a\x52\x3f\x9e\x2c\x64\x19\xdf\x8d\x0b\x71\x4e\xe3\x77\x68\x00\xeb\xfa\x70\x77\x60\x84\x66\x7d\x6d\xcf\x54\x1f\x14\xcf\x16\x62\x62\xe0\xf6\x4c\x42\x76\xae\x28\x88\x5e\x6c\xfd\x09\x7b\x70\xc0\xd6\x18\x6e\xa5\xdb\xd0\x33\x32\x3c\x98\x76\x13\xda\x08\x64\x5d\xe0\x72\x08\xba\xe1\x2a\x17\x8d\x8f\x7f\x65\x0a\x25\xaf\xbd\x70\x1c\x85\xa1\xba\x63\x9e\xf9\xf1\x21\xc4\x0c\x5c\x12\x9a\x47\x37\x34\x33\x86\xa4\x81\x83\xff\x3c\x59\x13\x89\xd8\x9e\xcd\xa5\x26\xcf\xfb\x26\x74\xf1\x7b\xb1\xc2\x30\x90\x55\x4b\x13\x40\x84\x97\x96\xa6\xd4\x44\x46\x0b\xb4\x19\x42\x7e\x93\xe6\x58\x5b\x0f\x4f\x06\x5a\xd8\x7e\xe6\xed\xf5\x4b\xe6\x18\x8a\x1d\xd5\xac\xe1\x36\x4d\xef\xa5\x61\xf7\x4e\x26\x76\x9c\x9b\x29\x1e\xe7\x55\x52\x76\x50\x1c\x6a\x49\x08\x0d\xa0\x92\x4f\x37\x92\xc2\xa7\x28\xa5\x20\x07\xb1\xc0\x7c\x95\x57\x8f\xed\xaf\x40\x39\x96\x23\x9e\x9c\x55\xa9\xa4\x4c\x3d\xfc\xc3\x7c\xdf\x03\xfb\x48\x5d\xb5\xa0\x8d\xff\x15\xa7\xa4\xf7\xb7\xf1\x54\x74\x2e\x84\x31\x56\x4d\xc1\x7d\xbd\x43\x2e\x10\x33\x7c\x22\x76\xfc\xfd\x9d\x70\xf7\xc3\xd5\x70\x39\x3a\x0c\x19\xf6\x40\x51\xc7\x3a\x87\x0e\x20\x55\x84\x10\x65\x31\xd1\xfd\x2a\x1d\xd1\xc9\xd0\xfc\xe1\x4f\xfa\xaa\x07\x7b\xb7\xe2\x60\x25\x1e\xed\x6c\x62\xbc\x6e\xdc\x24\x22\x51\x94\x40\xc2\x24\x4e\xba\x38\x40\x46\xb0\xed\xda\xa6\xcf\x2c\x1c\x7e\xee\xbf\xcd\x78\xfc\xae\x18\xb8\x22\x90\x55\x2b\x59\xc0\x46\x3d\xc4\x50\x61\x8b\xa6\x7c\x77\x0d\xec\x0e\x22\x9b\x84\x60\x93\x6c\xa8\x19\x56\x2b\xcb\x36\x96\x9c\x8f\xf7\x0b\xf1\x13\xc1\x16\x71\xe0\x0b\x94\x13\x55\xbf\x01\xad\x54\xb0\x5c\xfe\x2a\x04\x8b\x38\x72\x8c\xbd\xd1\xb4\x98\x09\xe1\xf2\x07\xac\xa3\x09\x8d\x99\x42\xee\xc4\x7d\x6c\x9d\x41\x3b\x37\xc9\x14\xfe\xdd\x38\xac\xd5\xff\xe4\x96\xca\xc7\x57\xc2\xef\x8b\x77\xbd\x84\x03\xd1\x4b\x1f\xc9\x8a\x90\x3f\xe2\xb9\x79\x46\x82\x33\xa7\xf2\xae\xd6\xf8\xd5\x09\xd8\x74\xe1\xdc\xe0\x51\x49\xaf\x9d\xf3\xfe\x45\x95\xc7\x1e\x8b\xc4\x63\xde\xe9\x38\x4d\x5e\x05\x05\xd2\xa6\xb0\xa2\xb8\xa1\xed\x62\x16\xaa\xae\x9d\xcc\x76\x02\x48\x7a\x4c\x08\x51\xfd\xf0\x96\x29\xc1\xe9\x91\x18\x80\x9a\x95\x44\xa6\x57\x7a\xf9\xf9\x15\xd1\xe6\x5d\x81\x62\x20\xc4\x8c\x84\x90\xfa\x9b\x70\xda\x42\x2a\xd6\x80\x02\x23\xd6\xd8\xc3\x40\xf9\xea\xb2\xcc\x7e\x14\x93\x62\x12\x4a\x30\x0b\x40\xcb\xb8\xc0\xa6\x5d\xa3\x01\xdb\xba\x93\x1b\xa5\x64\xf3\x59\x73\xca\x8b\xf2\xd1\xed\xb5\x6c\x19\x46\x61\x95\x5b\x3b\x68\x38\x1f\xa1\x5d\x4b\x8d\xc6\xad\xa1\xa5\xce\xbd\xa3\xa4\xcc\xc5\x51\x23\xe0\x05\x7f\x4f\x82\x10\x41\x93\x7d\xd5\x49\x20\x9c\x82\xe1\x16\x57\x0b\xc9\x08\xa2\x8e\x32\x99\xa9\x44\x14\x43\x49\x8f\x74\xb3\xcc\x88\xe1\xa6\x2d"}, +{{0x43,0x10,0x3d,0xf0,0x1a,0x48,0xa0,0x3c,0x57,0xf3,0x2f,0x52,0xd7,0x0c,0x68,0x49,0xee,0x44,0x58,0x0b,0x2a,0xb4,0xee,0x72,0xd5,0x48,0xd8,0x48,0x13,0x4f,0x7c,0xeb,},{0xa3,0xcb,0xe0,0xd6,0x4b,0x05,0x60,0xbc,0xb5,0xae,0x00,0x90,0x01,0xe3,0x14,0xd9,0xec,0x90,0x79,0x01,0xdd,0x74,0xa8,0x04,0xa0,0x05,0x90,0x22,0xed,0x9c,0x6d,0x04,},{0x19,0x54,0x47,0xbe,0xb1,0xde,0x4a,0x7e,0x36,0xea,0x89,0xa6,0xce,0x3c,0x99,0xbc,0xc8,0x94,0x11,0xdf,0x5e,0x0b,0x15,0xf7,0xba,0x0b,0x1d,0x11,0x0c,0x45,0x6a,0xbc,0x6b,0x3f,0x5f,0x1d,0xa6,0x10,0x6e,0xd8,0x87,0x86,0x4b,0xa5,0x6a,0xab,0x46,0x6a,0x8a,0x63,0xb3,0x35,0xcf,0xcf,0x4c,0x64,0xd6,0x5c,0x0e,0x6f,0xb4,0x80,0xb4,0x01,},"\x73\x8c\xbf\x06\xd0\x0d\x4d\xcd\x5e\x5f\x24\x3a\x1c\x18\xdd\x5e\xc2\x02\x78\x88\x46\x95\xa1\xcf\x3b\xea\x67\xbb\x5b\x05\xdd\x7e\x60\xa2\xa2\x4f\xd3\x25\xbe\x6b\xf4\x6b\x46\x28\x73\xec\x90\x7f\x9d\xe8\x8d\xc2\xc7\x62\x62\x0b\x7e\x0e\xf7\x27\x65\xd4\xbd\xa6\x62\x45\x49\x93\xc8\x28\xa1\x74\x6e\x9e\xd8\xd1\x9d\xff\x43\xc4\xc4\x85\x27\xac\x84\x5f\x21\x86\xa4\xad\x7c\x1d\x99\x2a\x16\x24\x5c\xd5\x73\x07\x3e\x09\x40\xdc\xee\xd3\x68\x11\x0b\xb5\xfd\x0a\x4c\x88\x34\xce\x88\xa7\x71\x25\xb9\x14\x73\x93\xc8\xb5\x8c\xb1\x6e\x5e\xbd\xc1\x82\x44\xeb\xfa\x48\xba\xba\x46\x97\x3f\xdc\xd4\x85\xb1\xb2\xe5\xf3\xb0\xe7\x09\x92\xcf\x19\x99\x58\x06\x38\xd8\x7f\x1f\x5b\x27\xc4\xd7\xf9\x1d\xec\xf3\x7d\xe2\xe7\x34\xe3\x19\x55\x35\xc6\x31\x08\x2b\x3e\xba\xa8\xce\x30\xa9\xc2\xc2\xdb\x01\x6d\x7d\x35\x47\xe6\x21\x61\x88\x50\xe2\x20\x40\x03\x8d\x0f\xe0\xfa\xea\x2f\x9b\xf5\x10\xb6\x82\xc4\xfd\x14\x75\x0e\x89\xb4\xc1\x99\xef\x0c\x99\x05\x00\x54\x3e\xee\xab\x5f\x0b\x50\x7a\x31\x31\x99\xc2\xa2\xa0\x26\x2d\x6d\x81\x4c\xbc\x09\x33\xc5\x92\xe2\x56\xc3\xe2\x9d\x52\x4b\x06\x6e\xa5\xa4\x54\x33\x61\xa1\x04\x50\xe0\xaa\x67\x5c\x61\x40\x8f\x30\x7f\x26\xee\x58\x96\x9d\x63\x27\x8f\x13\x5b\x7d\xcb\x66\x6b\x93\xf2\xca\xcf\xd8\x38\x73\x47\x1e\x97\x4a\x28\x6b\x09\x02\x3f\x50\x15\xfa\x1a\xaf\x18\xbf\xbf\xa5\xf7\x43\x85\xd0\xdf\x6b\x9a\xdd\x51\x6f\xfc\x0c\x31\x13\xe3\x7e\x09\x78\x38\x64\x6a\xc9\x30\x54\xff\x4d\x96\x02\x06\x67\x44\xba\x33\x96\x95\x3f\xd7\x81\x68\x13\x01\x70\xbb\x27\x5c\x15\x2b\xdd\x36\x6f\x73\x06\x5c\x0a\x7a\xd7\xad\x00\x75\x8c\xb9\x9a\x7a\xc1\xb7\x80\x9d\x26\xdf\xaa\xc7\x58\x46\x82\x01\xee\xb6\x0d\xea\x36\x8c\x33\xf2\x57\xaf\xe2\xf1\xb4\xc0\x2e\x37\xba\xfe\x40\xf5\xd7\xfd\x40\xc8\x7d\x1c\x56\xa0\xcb\x28\xe9\xd2\x83\x69\xa3\x92\x4b\xce\xf8\xb6\xd9\x99\xdc\xf4\x29\x4d\xd8\xc4\x14\x3d\x75\xc6\xc2\x5b\x5a\x45\x44\x48\x8d\xde\x72\x52\x48\xc7\x8d\x93\xc1\x5b\x81\x5b\x01\xcb\xd0\xf3\x1d\x1b\x00\xac\x04\x83\x7e\xf8\x5b\x40\x03\xfc\x96\xd4\x45\x7a\xc5\xa0\x23\x62\x3e\x67\xb6\x6d\xa4\x70\x0a\x08\x59\xf8\x3f\xdc\xcd\x3c\x7a\xae\x09\xde\x09\xa0\x57\xe0\x0d\xb4\x4a\x2a\x6a\xac\xaa\x21\x74\x6a\x49\xb8\x22\x46\x89\xa5\xcc\x18\x54\xba\x3d\xc4\xaa\x2a\xa3\x45\x24\xe7\xa5\xa8\x9d\x11\xee\xa3\x56\xaa\xea\x5e\xf5\xfb\xf5\x42\xc9\x9f\x54\x4d\xb9\x40\xf5\x08\x68\x38\xee\x2a\xb2\x18\xb8\xd3\xf2\xe1\x07\xd0\xb2\x9d\x4b\x04\x83\x0e\xed\x79\xc0\x76\x8e\x02\xc2\x84\x4b\x3c\xba\x32\x68\x95\xf4\xab\x38\xa3\x99\x4b\x83\xab\x30\x60\x0f\xf5\x11\xcc\xb5\x95\x99\x2f\x8c\xc0\xd2\x95\x48\x07\x97\x2d\xa3\x65\xb0\x6f\xbd\xab\x53\x9b\x2e\x03\x59\x8b\x34\xe5\x3c\xfc\xf9\x39\x90\xb9\x7a\xac\x1d\x32\x97\x83\x36\x6d\x45\x1f\x97\x2b\x8d\x8a\x00\xb6\xb8\xec\xdb\x37\x27\x96\x44\xce\xc1\x44\x7c\x09\x98\xee\x4f\x70\x90\xf3\x4c\x9c\xc8\x53\x05\x90\xca\xe7\x65\x36\x0a\xad\xb0\xab\x31\x35\x00\x49\x41\xc9\x23\x02\xcb\xb2\xb3\x50\xa1\x4e\x8f\x30\xaf\x53\x25\xc2\xb4\x38\x00\x5e\x3a\x9d\x45\x85\xe6\x32\x65\xc3\x27\xba\x72\x57\x54\xb3\x32\x56\x91\x7f\xb9\x65\xae\x9f\x02\xed\x21\x26\xb4\x81\x47\x3d\xc0\xe9\x31\xc2\x52\x2b\xf0\x0f\xe6\xa2\xec\x95\xc7\x92\x24\x7b\x1e\x03\x39\x61\x12\xf7\x83\x07\x0e\x2f\xe6\xc2\xcb\x98\x22\x50\xd1\x3f\x2d\x54\x60\xc7\x44\xfd\xe4\x53\x23\xe6\x31\xcc\xcb\x54\x0c\xd7\x25\xf2\xc5\x5a\x70\x58\xf2\x30\xe8\x2b\x79\xf3\x66\xaf\xcb\xb0\x25\xb4\x92\x55\x43\x95"}, +{{0xf9,0x13,0x9e,0x57,0x9f,0xa9,0x6e,0xbd,0x62,0x87,0xdb,0x3b,0xab,0xcd,0xa6,0x0f,0x92,0xe7,0x31,0x53,0x56,0x6f,0x92,0x4c,0xb5,0xde,0x04,0xde,0x44,0x93,0x48,0x1e,},{0xc0,0x6c,0xe3,0x35,0x53,0x3a,0xf8,0xd8,0xf3,0x37,0xf2,0xb3,0x8e,0x0a,0xaf,0xa2,0xce,0x9b,0x27,0x22,0x3c,0xd9,0xdd,0xc5,0xef,0x32,0x02,0x7f,0x04,0x88,0x9b,0x7f,},{0x05,0x1d,0x8d,0x7f,0x0b,0x68,0xd2,0xee,0xc7,0x2c,0x81,0xad,0xfc,0xfb,0x31,0xae,0x85,0x58,0xf6,0x0a,0xb6,0x3c,0x9f,0x56,0x52,0xa8,0xdf,0x63,0x8f,0x66,0x6f,0x1e,0xbc,0x0c,0x6e,0x0b,0x41,0x19,0x53,0xbc,0xda,0x6b,0x51,0x51,0xb2,0xb9,0x3a,0x39,0xe3,0xc5,0x33,0x0a,0x85,0x73,0xe1,0x68,0x79,0x22,0x72,0xab,0xd3,0x6c,0x81,0x0a,},"\xb3\x30\x76\x4d\xdc\x62\x8e\x4a\xd6\x7a\xa4\x98\x2a\xe8\x6d\x45\x81\x07\x1c\x19\x3e\xc3\xc5\x8f\x81\x3d\x79\x21\xb8\x4d\x2a\x54\x56\x2b\xd8\x74\x17\xae\x1d\xe5\x90\xa1\xa4\x8c\x4e\xc7\xd5\x56\xad\x93\x1d\x65\xc0\x54\x3f\xdf\x06\x07\xc7\x49\x85\x9e\xe1\x2f\x99\x52\x02\x0c\x19\x5c\xf8\x74\x60\x95\xe1\x08\x7c\xc6\xc3\xc8\xef\x9d\x24\x05\x25\x60\xce\x81\x3d\x61\x39\xb7\xa7\x5c\x8f\x4b\x8e\xa3\x0a\x9c\x4a\xb8\x88\xd0\xa6\x34\x1c\x99\xab\xd3\x5e\x09\x03\xbf\xe5\x6c\x93\x15\x23\x40\xc4\x12\x76\xd7\xf2\x4e\x09\x12\xb1\x2a\x4d\xb3\xd7\xee\x44\x84\xdf\xa5\x3a\xfc\x0b\x1a\xea\x14\x09\xd1\xe0\x32\x8a\xa1\xc8\x60\x41\x27\xca\x2e\xb1\xa5\xe8\x1b\xf3\x1f\x8c\x7a\x51\xc6\x05\x2c\x53\x4e\xfe\x6b\x3d\x0e\xe7\x4f\xf5\xa9\xb1\x1c\x61\x57\xe3\x64\x77\xef\xa9\x38\x2f\x57\x51\xbe\x8c\x8c\x64\x54\xc4\x46\xd6\xf8\xdc\x7e\x92\x95\x25\xcc\x3d\xe7\x8c\xb1\xba\x4a\xba\x9b\xd4\xbe\x15\x26\x10\x43\x75\x82\xc9\x65\xee\xa4\x8c\xbd\x4c\xaa\x6f\x30\x8f\x85\xf4\xf8\xd0\x06\xa0\x42\xf6\x19\x20\x07\x62\xe1\xbb\x9b\xa4\x22\xe6\x54\x75\xb3\x3a\x94\x94\x29\x8c\xfb\xb7\x5a\x15\x2b\x36\xd2\xa0\x55\x01\x80\x77\x05\xb9\x52\x76\x53\x50\xcd\x14\x14\x1d\x35\xd4\x98\x66\x92\xd6\xc3\xbc\xfc\x6d\x61\xdf\x00\x52\xa6\x20\xaa\xb8\xcc\x13\x20\x5e\x75\x4c\x16\xf9\x3e\xca\x79\x20\xbb\xea\x51\x57\xef\x11\x2f\x0b\x64\xc1\x05\x4f\x90\xa5\xdd\xc1\x75\xa8\x9e\x29\x24\x2f\x57\x64\x6e\x74\xcc\x88\x5e\x81\xa1\xcc\x14\x4c\x3d\x78\x2d\x11\x52\xa9\xe4\xcf\xe7\x6c\xb3\xff\xab\xe7\xdb\xe6\x03\xfb\x38\x69\xec\xa8\x69\x96\x98\x70\x9c\xc8\x7f\xc9\x61\xc1\xe2\x99\xcf\xca\x22\xe3\x24\x2e\xae\x78\x8c\xff\x11\xbf\xca\x61\x02\x67\x45\xf4\x97\x62\x25\xb2\x6e\xe2\x00\xc4\xf1\x91\x0c\x4b\x83\xdf\x5c\xe4\x6e\xf4\x87\xd7\x48\xd9\xc4\xc5\x02\x14\x1b\x78\x74\xca\xf4\x1e\x5a\x29\x7b\x24\x8c\x2b\xac\x69\x90\xa1\x5b\x07\xb4\xcf\x81\x0e\x59\x28\x74\x42\xd9\xa3\x69\x6c\x02\xe8\xd7\x32\x4d\x3c\xf7\x30\xdd\xa5\x40\x53\x6b\xeb\x13\xcf\xde\xae\x61\x80\xdd\x74\x84\x83\x2d\xfa\x94\xe9\x4a\xa6\xcb\xa1\x17\xaa\xe1\x72\x70\xf4\x8f\x93\xb2\xf9\x8a\xe9\x58\x17\x18\x16\x3f\x44\x63\x54\x6c\x0a\xe0\xf2\x79\xc3\x6b\x92\xbe\xe6\x6f\x1c\xa2\xd6\xa4\xf7\x26\xd2\xdf\xee\x0b\xc1\x1c\x1d\x8a\x1f\xa6\x2c\x3c\xc8\xab\xa2\x66\xb9\x87\x59\x28\x6c\x10\x68\x48\x3b\x23\x76\xb4\x03\xc8\x87\xfb\xb6\x57\xdc\x0f\x25\x5d\xea\x90\xdb\xd2\x33\x08\xf7\xe0\xe8\x42\xb4\x98\xa8\xdf\xc7\xc9\xcd\x5a\xef\x0e\x87\xd5\x6b\xe4\x0d\x50\xfc\x1d\xd4\xc0\xaa\x7d\xee\x55\xae\xbe\x4d\x6b\x6a\x52\x05\x39\x62\xb8\x7b\x0f\x2e\xe0\x9a\x90\x81\x61\x55\x33\x3d\x5c\x57\xa1\x47\x24\xe0\x01\xbc\x3d\xed\x17\x84\x3b\x76\xe2\xc4\x7a\x17\x63\x39\xc8\xde\xfc\x54\xb5\x5b\x23\x58\xae\x7d\x01\xb0\xf6\xe0\x8f\x31\x21\x6a\xe9\x03\x40\x69\x41\x68\xa5\xa7\x9e\xe8\x83\xea\x78\x58\x00\x7d\x17\xc3\x73\x59\xc9\x9d\x65\x97\xef\xe4\x60\xc1\xa2\xf7\x73\x8a\xc3\x2c\x5e\xb5\xe3\x9e\x50\x0c\x49\xc0\xdf\xf9\xc4\x65\x9e\x8c\x50\xcc\x5c\xa7\x9d\x8b\xa4\xe5\x97\x2d\x67\x22\x54\x68\xfb\xa6\x41\x67\xa6\xb2\xc6\xf3\x68\x93\x5c\x7a\x04\x9d\x35\xd3\x55\xc7\x67\x25\x20\xd3\xc9\xe4\xe4\x3c\x67\x1c\x3c\xb8\xde\xe2\x59\x04\x74\x95\xde\x0f\x56\xdd\x71\x91\xd5\xbd\x4b\xbd\x29\x51\x7e\x36\x47\x92\xff\x89\xd3\x37\x99\xb6\xe7\x81\xc2\x01\x93\xf5\xa3\x16\xfb\x40\xde\x74\xfe\xe2\xac\xc2\x5e\x47\xf5\x12\x21\x4d\xe3\xb1\xe9\xb3\x82\xa8\x69\x29\xc1\x57\x3d\x37\x24\xc2\x50\x17\xc0\xe5"}, +{{0xc8,0xee,0x95,0x4d,0xb5,0xa1,0x1b,0x29,0x2e,0xd9,0x77,0x64,0xfa,0xe6,0xb2,0x83,0x05,0x1d,0xb5,0x7d,0xcd,0xc0,0xaa,0x0d,0xf5,0x39,0x3b,0xb6,0x0c,0x11,0x2e,0xd3,},{0x5c,0x2f,0x81,0x82,0x4e,0x99,0x75,0xdd,0x7e,0xa3,0x53,0xbc,0x66,0x80,0x7d,0xed,0xc7,0x61,0x03,0x49,0x79,0x4e,0x2f,0xc0,0x8e,0x5a,0x31,0xe0,0x02,0xe3,0xfe,0x07,},{0xf3,0x07,0x7a,0x75,0x10,0x1e,0x12,0x1e,0x5c,0x3e,0x77,0xd8,0xed,0x97,0xb5,0x78,0xd2,0x39,0xbd,0x42,0x18,0x03,0xd3,0x45,0x5b,0x56,0x54,0x40,0x5a,0x4c,0x58,0x6a,0x60,0x92,0xe1,0x3a,0x85,0x29,0xba,0xce,0x46,0x8a,0x30,0x57,0x84,0xb3,0x73,0xe4,0x33,0xfe,0xe4,0xa3,0xdf,0x89,0x56,0xbe,0xfa,0x01,0x2f,0xd8,0xa8,0xee,0xd1,0x0c,},"\x7b\xa3\xfb\x56\x83\x15\xaa\x81\xe2\x1f\x19\x77\x80\xed\xc2\xc6\xea\x26\xd8\xd0\x6a\x43\x78\x91\x2f\xca\x23\x01\xcf\x1e\xab\x3d\x80\x3c\x84\x69\xde\xdd\xf3\x76\x70\x3d\xdb\x7c\xe0\x6a\x77\xda\xb2\x0e\x02\x34\x4f\xad\xcc\x50\x02\x2a\xb3\xc7\x13\xcd\x03\xc1\xda\xa9\x3f\x1c\x7e\xa5\x72\x62\x9f\x61\x0b\x5e\x3c\x51\x41\x1b\xb8\xc1\x96\x94\xbb\xce\x90\x3c\xac\x47\x05\xf9\xb5\xdd\x0f\x47\xbc\x5d\x0a\xa3\x25\x3f\x90\x88\x70\x29\x90\x27\xff\xbd\x34\x49\xee\xba\xd4\x53\x32\xb5\xd0\xc4\xf5\x33\xdb\xed\x18\xa9\x9a\x24\x98\xb9\x16\x4e\x24\x5f\xb6\x5c\x0a\xfa\x0b\x05\x37\x03\xa0\xcf\x95\x94\x0a\xc7\xa0\x19\x5d\x4f\x70\x46\x60\x9c\xf0\x43\x71\x33\x87\x06\xb9\xb1\x98\x6c\x0f\x11\x81\x75\xd2\xcd\xfc\xe7\x4a\x6f\x88\x65\x98\x25\x85\x4e\x94\xec\xe5\x8f\x51\x57\x63\x6d\x62\x35\xb7\x6d\x32\x74\x5a\x2a\x81\xa9\x67\x1a\x8f\x86\x02\x7b\xa9\xe0\x17\x63\x88\x8f\xc1\x71\xce\xf7\xc4\x51\xc3\x60\x72\xbc\x74\x99\x83\x9d\x43\x1c\xf1\x8c\xd7\xc6\xc9\xfb\xa3\xaa\x71\x2a\x05\x43\x28\xcc\xd6\x2b\xe4\x82\x0a\xbd\x5e\x78\x21\x62\x76\x46\x11\xd4\x53\x9b\xa2\xce\xbd\xc2\x09\xb3\xf4\xe4\xb6\x9c\x3d\x64\x07\x3e\x92\x0d\x21\x52\x14\xfb\x0f\xda\x44\x18\x5a\xad\xa5\xc3\x61\x27\xa1\x5b\xa1\x5c\xa2\x8a\x3a\xd0\x86\xe9\xd0\x33\x66\x86\x9c\x60\xc3\xfb\xce\xbd\x86\x9d\x2e\x40\x64\x3e\x83\x3f\x89\x48\x03\xf9\x80\xa2\xda\x7e\xa4\xe5\x9c\xe4\xd7\xc0\x6f\xd2\xaf\xf0\x87\xee\x7b\xcf\xdd\xaa\x3b\x32\x81\x7c\xe6\x3a\x63\x58\x7d\xba\xfe\xf3\x80\x01\x3a\x6f\x1e\xe3\x73\x4b\x94\xca\x3d\xf9\x64\x4d\xd0\x43\x43\x02\xec\xb3\x24\xaf\xe3\x5f\x46\x5c\x9c\x1c\x93\x1b\x27\x29\x4f\xc6\xee\x02\x72\xde\x22\x42\xae\x90\xd7\xf2\xe0\x67\x02\x7e\xf8\x64\x2e\x8f\x17\x1e\xd8\x80\xff\xab\xce\x8a\x20\xa1\xb3\xe3\x39\xad\x4e\x3f\x1a\x90\x01\xf2\x0f\x90\x02\x61\x88\xfd\xe3\x4b\x21\x7a\x6e\x26\xaa\xff\x18\x42\x2b\x7f\x84\x3d\x0f\xdd\xa3\x21\xc3\x19\xc7\x78\xf2\x31\x37\xf2\x0c\xcc\x1b\xda\x18\x90\xe5\xbc\x91\x6a\x54\x56\xd0\x68\xd3\x7b\x5a\xcc\x63\x47\x72\x0c\x56\xa5\xa4\x91\xbc\x34\x8d\x6c\x84\x8a\x9c\x8f\xec\xfe\x58\xc9\x2b\x1f\x30\x2f\xe1\x49\x19\x71\x8c\xd5\xe7\x8b\x7f\xd6\x01\xd0\x9d\xc0\x1e\x69\x04\x86\x1e\x8d\x68\xb3\xc5\x75\x35\xb6\x13\x66\x76\xcb\xc6\xe8\x39\xaf\x0d\xd7\x39\xdb\x89\xa7\xab\xd9\x13\xfd\xf6\xb0\x0e\x9c\xa0\x26\x02\xde\x6c\xa0\xaf\xd0\x91\x3d\x99\x2f\xba\xa8\xff\x82\x2b\x9d\x9b\x09\xdd\xa7\xa2\x9b\xe9\x19\x10\xd8\xfa\x3c\xaa\x2a\x5e\x51\x83\x46\xc1\x67\xc9\xf5\x19\x41\xcf\x73\x53\xf3\xf3\x4c\x1d\xab\x33\x48\x5d\x0a\x8c\x19\xda\xf9\x51\xfd\x3e\xf2\x0d\x0b\x11\x9d\x80\x38\xdf\x90\xc1\x14\xa2\x5a\x5b\x93\xae\x40\xec\x44\xb9\xa5\xd2\xbc\x1c\x65\x17\xc6\x82\x50\x0d\x4c\xdc\x19\x71\x42\xbe\xc3\xaf\x82\x32\xc0\x71\x42\x8d\xc5\x4c\x0d\x30\x45\x42\x72\xe7\x33\x6b\x0b\x58\x88\xa6\xe8\xfe\xcd\xe8\x59\xe2\xac\xcb\x7f\xb0\x94\xac\xc5\x4f\xfa\x48\x1f\x76\x23\xd9\x44\x69\x1f\x04\xfb\x36\x13\xa9\x95\x49\x80\xf1\x7e\x2a\xd2\x17\x3d\x68\xcf\x0e\xc1\xb6\x7d\x8a\x91\xd6\xec\x82\x94\x6b\xcf\x05\xcb\x90\x68\x1a\x71\x62\x7b\x59\x02\x38\x33\x4e\x3d\x5a\xb9\xda\x6a\x08\x9b\xd7\x26\x24\xdf\x90\x74\xcd\xd2\x30\x9e\x04\xdf\xca\xe0\x32\x81\x2f\xe8\x4f\x9d\xb8\x82\xcd\xea\xae\x69\xee\x5d\xaa\x5a\x66\xff\x42\x7f\xc4\x52\xed\xd0\x76\x9b\x6a\xab\xcc\x13\x9d\x0f\x70\xaf\x8b\x97\x43\x0e\x64\x4f\x58\xa4\x12\x87\xa9\x3f\x63\x1d\xed\xa8\x2c\xa0\x71\x6d\x79\x75\x4c\x5c\x50\x3e\x52\xa6\x65\xda"}, +{{0x6d,0xbc,0x55,0x9e,0x4a,0xb1,0x93,0xee,0xbf,0x70,0xc5,0xc3,0x2d,0x79,0x7b,0xe0,0x0b,0x73,0x11,0xe8,0xe6,0x69,0x1d,0xa9,0xaf,0xcc,0x18,0x72,0x91,0xf2,0x50,0x1c,},{0x38,0xa7,0x03,0x44,0x76,0xfb,0x93,0x82,0xf1,0x41,0x77,0x68,0xc4,0x21,0x62,0x95,0x1a,0x26,0x36,0x90,0x2c,0x38,0x98,0xc0,0x29,0xbe,0x27,0x8a,0xb4,0xc3,0x1f,0x31,},{0x31,0xf1,0x6a,0x7c,0xaf,0x2b,0x74,0xf6,0x5e,0x05,0x7c,0x93,0x33,0xa1,0xa2,0x63,0x3d,0xac,0x73,0x46,0x33,0x8f,0x79,0x85,0x10,0x73,0x0e,0xb8,0xd5,0xd3,0x25,0xfc,0x10,0x80,0xdd,0x5a,0xad,0x5f,0xce,0x05,0x34,0xe9,0x54,0x3f,0x3c,0x93,0x58,0x68,0x04,0x46,0x4a,0xf5,0x88,0x6e,0x86,0x44,0x12,0x9c,0x77,0xeb,0xaa,0x48,0x5f,0x01,},"\x88\xee\x23\x65\xf7\xcf\x9d\xe3\x3a\xcd\x53\x56\x49\x68\xb2\xdc\x7f\x73\x70\xb7\xe7\x03\x3f\x4c\x66\x3a\x88\xc2\x5f\x60\xf7\xf7\x11\xd6\x19\x08\xeb\xf1\xf5\xbb\x72\x83\x55\x53\xc8\xaa\x8c\x8e\x4f\xcd\xec\xd3\x79\x78\x23\x82\x89\xbf\x6c\xa8\x48\x76\xd2\x28\x21\x7a\x28\xd8\x1b\x0b\x45\x7c\x92\x2e\x91\xec\xba\x8d\x3e\x1d\x2e\x66\x59\xc2\xb0\xae\xa0\x51\xb9\xc2\xe0\x9c\x7d\xfe\xb5\x1d\x30\xed\xe7\x67\x57\x03\x41\xff\xac\x1e\xcf\x0d\xe2\x0c\x82\xd1\xe9\xed\x07\x75\xde\xac\x72\xda\x7c\x2d\xec\x23\x48\x65\xde\xc8\x3f\x67\x15\xe1\xc3\xc5\x9d\xe2\x03\x3c\xc2\x4d\x86\xbc\x2d\x31\xaa\x16\x64\x96\x86\xed\xe0\xdb\xbd\x89\x64\xc3\xa6\x4a\x3d\xca\x55\x88\xd7\x24\x8b\x1f\x24\xdf\x8d\x75\xf0\x9a\xac\x62\xc0\x78\x28\xca\x43\x1a\x3a\x2d\x77\xa6\x0c\xc9\x3c\xfa\x34\x95\xca\xbe\xb1\x90\x4e\xd5\xb5\x63\x98\x4e\x8c\x20\x77\x7b\xac\x87\x74\x10\x8a\x64\xed\xa5\x8f\xb3\x20\x24\x4a\x3a\xdd\x3e\x3e\x7a\x76\xcd\x13\x7c\xfa\x4a\x09\xb6\xe6\xe9\x30\x11\xea\x0a\xe6\x51\x71\xaf\x13\x07\x11\x76\x6c\xd2\x5b\x3c\x74\xec\x54\xc0\xbd\xfa\x02\xb3\x12\x0a\xc2\x90\x87\xeb\xac\x98\x37\xfc\xa6\x5b\xa9\x71\xbc\x42\x81\xdd\x55\x7c\x50\x0e\x22\x5e\xa6\x6c\x3c\x3f\xd5\x22\x06\xc1\x9a\x9f\x93\x95\x46\x31\x69\xf8\xc7\xa8\x46\xbd\x9f\x83\x4d\x7f\x33\x7d\x0b\x61\xfb\x30\xbc\xe2\x94\xf4\x78\xae\x1f\x1d\x97\x7e\x45\x4e\x43\x3e\xe8\x72\x9f\xb0\x65\xcc\xe0\x3f\xb2\xe4\x35\xdc\xbc\xbf\xba\x01\x53\x7e\x7a\x67\x62\xe5\x5e\x7e\xd2\x25\x28\x30\x37\x04\xbe\xb5\xae\x38\x1f\x2e\x18\x10\x56\xf2\x51\x33\x27\x3c\xf1\x7d\xdf\x2b\x06\xe2\xd9\x47\x7f\x2c\x09\x75\x5f\xc8\xd9\xc7\x3c\xb3\x31\x00\x46\x8c\x64\x13\x1c\x68\x6c\xac\x79\xfd\x38\x45\x01\xe5\x0f\x8b\x0b\xee\x28\xba\x39\x58\x3f\x42\xe4\xfd\x37\x99\xe2\x4f\x60\xda\x5f\xd3\xc7\x79\xaa\xbf\x69\x9f\xfd\x23\x21\xed\x04\x5a\x85\xbc\x64\x24\xf6\x0f\xdc\xc4\x9c\x1c\xb3\x1f\x24\x9a\x42\x36\xc0\x94\x91\x76\x81\x81\xb9\x21\xf5\x86\x02\xfd\x41\x5c\x1e\xde\xb2\x6f\x39\x32\x4a\xdd\xff\x14\x77\x13\x24\x73\x7c\x67\x20\xcc\x92\x39\x1b\x94\x9d\xcb\x42\x12\xbd\x69\x31\xd4\xde\x51\x40\x1e\x7f\x95\x3b\x7b\x03\x6b\x22\x3f\x0a\xf7\xa8\xe4\x08\xb0\x4e\xa6\x35\xa2\x3f\xa0\x70\x9b\xa0\x42\xa5\xd9\x92\x95\x4c\x09\xd8\x58\x1d\xcc\xcf\x52\x56\x8a\xd2\x7a\x1c\xc7\x1d\x18\xaa\x27\x40\xf6\x21\x21\x2e\x7f\x4c\x5e\x5e\x5e\x5e\x45\x32\xd9\xa6\x7e\xc2\x77\x3a\xc2\x1c\x8a\x4b\x00\x2d\x65\x24\xf6\x18\x2d\xd3\x71\x73\x5d\x2c\x2a\xbe\x6c\x95\xc2\x81\xc6\xfb\x1e\x97\x6b\xc1\x7e\x38\x3f\xd5\x2a\xea\xaa\x9f\xbd\x4a\xbb\x82\xa2\xcc\x65\x39\x5f\x8c\x2c\xc7\xd8\x18\x2a\x0d\x25\x0c\x68\x5c\xfc\xba\x93\xa9\x51\xee\x7c\x50\x3c\x6e\x3e\xec\x23\x6c\xe3\x3e\x08\x6c\x61\x07\x28\x73\x7c\x1c\x3b\x3a\x24\x25\x2d\xa7\xf2\x16\x72\xd9\x28\xeb\xda\x99\x3a\x94\xc4\x58\xab\x99\x0f\x5d\x19\xd8\x00\x23\xc3\x6a\xa1\x6e\xaf\xca\xb1\x43\xf3\x52\xe9\x7d\x64\x09\xf3\x24\x99\x41\x11\x9b\xfd\x9f\x5f\x90\x84\x72\x4d\x9e\xba\xd3\x83\xb1\x0f\x34\xd3\x3a\xc8\x30\xcc\xe9\xe5\xcb\x8a\xec\xee\x6f\x40\x30\x1c\xbb\xe3\x09\xfd\x06\x15\x34\xa7\xd0\xc3\xed\xaa\xea\x02\xa1\x71\xd8\xb2\x34\x9d\xbe\xec\x62\x85\x20\xac\x33\x4a\x5b\xfe\x28\xa9\xd5\xf4\xc0\xd7\x40\xf7\xc7\x2d\x4d\x72\xd8\x9a\x97\x32\x6a\x03\x00\x2d\x1e\xf3\x85\x22\xbc\xd3\x7b\x42\x84\x7a\x31\x4b\xd8\x43\xec\x88\xd1\xf2\xf9\xd3\x9f\x57\xf2\xf1\xa1\x3d\x01\x40\xa8\x84\x74\x50\x44\x8c\x88\x0b\x3a\xe7\x65\x31\xe9\x5c\x43\x92\x97\x32\x50"}, +{{0xc9,0xd4,0x16,0x83,0x0a,0xe2,0x02,0x8f,0x21,0x75,0xd2,0x2b,0x61,0x4c,0x79,0x19,0x8c,0x67,0x0c,0xfa,0xa0,0xe7,0xa3,0x61,0x50,0xef,0x0f,0xee,0x21,0xa9,0x5c,0xe6,},{0x6e,0x3e,0xb4,0xd0,0x18,0x73,0x07,0x2d,0xf9,0x46,0xf1,0x79,0x2f,0x71,0x06,0x33,0x08,0x95,0xe7,0xa7,0x6d,0xd9,0xae,0x27,0xf8,0xa9,0x88,0x03,0x94,0x90,0xfd,0x4b,},{0x47,0xfa,0xad,0x4e,0x65,0x52,0x93,0xed,0xa1,0x56,0xb2,0xa1,0xfa,0xbb,0xfb,0x7e,0x00,0x9f,0xc2,0x90,0xaa,0xfe,0xdb,0xd5,0x65,0x21,0x14,0xa4,0x78,0x53,0xbc,0x77,0xa8,0x23,0x3a,0x2b,0x17,0x9f,0x60,0x54,0x77,0xd7,0x87,0x87,0x8c,0xbb,0x15,0xea,0x61,0x24,0xdf,0x8d,0xc5,0x7b,0x2c,0xe7,0xbe,0x7d,0x18,0xb7,0x16,0x2f,0xb5,0x0d,},"\xff\x9a\xd4\x83\x7c\xd0\xbb\x77\xd6\x21\x0f\xdd\xdc\x75\x5e\x6c\x0f\x1a\x73\xc2\xbc\xd0\x3f\x7a\x58\x69\xe7\x34\x2c\xfd\x73\xcf\x70\x86\xf8\x65\x56\x15\x60\x27\x7b\xf6\xc3\x42\x1a\x91\x2d\x67\x65\x8b\x1f\xa9\x70\x57\xc4\x96\xf4\xbe\x8e\xdc\xbe\x18\xb5\xec\xd0\x8a\x1e\x7d\xb2\x52\x23\xab\xda\x20\x8f\xa5\x31\xf4\xb2\x80\xaa\x03\xb0\x4b\x60\x60\x34\x11\xd3\x74\xba\x7c\xbb\x02\x0b\xb9\xa8\xce\x4c\x0e\x45\xa7\xe1\x32\x14\x48\x43\xc3\x1f\x8b\x45\xc5\x8e\xb3\xea\x85\x3c\x2c\xeb\x61\x37\x6e\x9d\xf8\x1d\x97\x78\xe7\x21\xad\xac\x77\xb5\x03\x54\x93\x7f\x34\x37\x2f\xcc\xd5\x75\xe8\x8d\x9d\x05\x8e\x43\xdf\x94\x2f\x2c\x43\xb5\x23\xc8\x09\x8e\x6d\xd9\xe6\xbd\x21\xd5\xa6\x49\xb4\x72\xd4\x1e\x34\x5f\xcd\x5e\xfd\xdd\x49\xea\xb3\x02\x70\xcd\x87\x88\x40\x4f\x28\x51\x6e\x09\xd3\xac\xc4\x00\x48\xb3\x9d\x32\x46\xf7\x57\xe4\x82\xe1\x45\x9c\x62\x6b\x79\x9e\x04\xd0\x67\x27\x13\x73\x71\xe1\x20\xaf\xb9\xfe\xc3\x9a\x25\xf4\xe6\x76\x4b\xf9\x79\x2f\xe4\x92\xee\x0f\x21\x0b\x57\xdb\x9e\xbb\x9e\x8e\xf4\x1b\x02\xc7\xfe\xe9\xed\xd4\xb6\x17\x4c\x57\x0d\xe0\x20\xa3\x91\x28\x71\x33\xfe\x8c\xcb\x41\xa8\x3f\x91\xbd\x22\x38\x2b\x21\xe1\xd7\xeb\xc2\xc7\xe5\x01\x8e\xf5\x14\x2d\x82\x63\x7d\x02\x62\x0f\xbc\x05\x69\xcc\x09\xc4\x4e\x91\x11\x12\xbb\xae\x99\x06\x4d\x68\xd1\xc6\x9e\x77\xc9\x93\x0b\x0d\xe0\x30\xc8\xc1\xd7\x48\xc4\x14\x05\x9d\x5e\x29\x9b\x7e\xdc\x08\x94\x06\x51\x89\x4b\x30\x3a\x2b\x32\xdd\x2c\x36\x5a\x06\x7c\x97\x23\x58\x55\x94\x64\x4d\x3e\xe8\xde\x1a\x51\xfa\xea\x0e\x65\x0f\x21\x24\x88\x5a\x94\xcb\x99\xeb\x90\x3b\x7d\x45\x79\xbd\xe5\x91\x49\x7d\x95\x39\x30\xd3\x63\xdd\xdb\xda\xc6\x27\xb9\x7a\x91\xf4\x96\x82\xdf\x8e\x72\x50\xa7\x07\x3d\x38\x3a\x7a\x22\xcf\x11\x3f\x28\x58\xce\x6b\x63\x2a\x28\x92\xc4\xe8\x8a\xa9\xa0\xd2\x89\xeb\x57\x62\x9b\x00\x8d\x3b\x1b\x60\x81\xe6\xfe\x5d\x3c\x0a\x6c\x80\x21\x89\xb5\xf1\x08\xe7\x66\x31\x9e\x15\xb3\x3e\xaa\x5b\x8c\xed\x40\x27\xea\xec\x83\xb4\xac\x68\xb1\x4b\x82\x98\xbc\x51\xcd\x8e\xb3\x80\x9b\x7a\x2d\x68\x4f\xe3\x2b\xbd\x9f\xab\x5c\x91\x8e\xeb\x17\xcc\x44\x4d\x73\xf7\x30\xd4\xc8\xcc\x05\x7b\xd3\xa2\xf1\xf0\xae\xbb\x61\x63\x29\x34\xe6\x17\x02\x16\x88\x29\xcd\x7e\x91\xde\x81\x50\x96\x29\xd0\x1a\x8c\xde\xfe\x0d\x1a\xc4\x9e\x21\xf0\xc5\xfb\xe1\xb2\x24\x48\x27\x26\x8a\x0a\x27\x35\x7e\x15\x8b\xd7\x68\x84\xa2\x1e\x7f\x1f\xac\x1b\x62\x72\x16\x6d\x5a\x9f\x64\xf9\xb6\x72\x98\x9a\x87\x62\xf5\x12\xbf\x1d\xf4\xb2\xab\x69\x97\x65\xf2\xcd\x83\x96\xf4\x76\xe7\xf5\x99\x95\xde\xe7\xd8\x90\x20\x7e\xff\x0f\xd2\x72\x63\xec\x23\x2e\x37\xcf\xed\xfe\x7c\x44\x05\x55\xd4\xca\x74\xe5\x2d\xa2\x46\xc4\xb8\x37\x57\xbe\xaf\xd2\xab\x2a\x51\xef\xe1\x60\xbb\x02\xb9\x8c\x26\xd6\xb2\xc3\xf0\xc1\xaa\xcb\x2f\x3c\x34\xa5\xb2\xa3\xb6\x6f\xee\x17\x5b\x78\x75\x48\x07\x3d\x8b\x57\x77\xc6\xbe\x88\x0b\xdc\x19\x6b\x33\x74\xa2\x15\x4f\x94\xd9\x36\x0f\x77\x55\xac\x68\x15\xa2\x8a\xf2\x96\x27\x1e\x22\xa8\xf2\x35\x43\xc7\x49\x55\xa6\x09\x12\x5b\x02\xa5\x69\x21\x80\x11\x42\x02\x95\xcc\xf0\xd7\x35\x69\x99\xa5\xb8\x95\xcc\x88\x48\x3f\xad\xf7\x97\x0c\xec\x6c\x64\x24\x0f\x70\x79\xfd\xb1\x5f\xfc\x5c\x42\x27\xe5\x39\x26\xd2\x78\xba\x0f\xed\x3c\x39\x93\xbc\x86\x82\x28\x23\xdd\x58\x1a\x32\xab\x2e\x3a\x07\xf7\x94\x30\x22\x4b\x27\x4e\xad\xd8\x45\x59\x8a\x7d\x1d\x89\x67\x6a\xaf\x23\x67\x77\x74\xb7\xb0\x58\x3b\xcc\x83\x59\x9d\x15\x5d\x14\xb0\x9a\xdc\xf4\x9e\xd5\x05\xe8"}, +{{0x2d,0x27,0x7d,0xd5,0x5f,0x57,0x19,0x5e,0xc0,0x72,0xb4,0x7c,0xb1,0x44,0x8c,0xb5,0x82,0xc8,0x35,0x73,0x9e,0x6c,0x98,0xba,0x71,0xab,0x12,0x8f,0x70,0xce,0x6b,0x79,},{0xdf,0xa9,0x25,0x93,0xef,0x0f,0x0d,0x97,0x4a,0x11,0x37,0x83,0x0a,0xd1,0x38,0x48,0xaf,0xef,0x3b,0x81,0x0c,0x2a,0x21,0xbf,0x77,0x91,0x78,0xce,0x4b,0x3a,0xb9,0x74,},{0x73,0xc1,0x06,0x06,0x49,0xa7,0xc0,0x14,0xed,0x01,0x94,0x58,0x51,0xb5,0x3e,0x28,0x53,0x24,0xe6,0x0d,0x06,0x1c,0x83,0x1d,0xda,0x41,0xf0,0x33,0xb5,0x65,0x83,0x06,0xa1,0xf1,0x12,0x32,0x7a,0xfe,0x93,0xca,0xa9,0x21,0x02,0x07,0x30,0xaa,0xe0,0x06,0x9c,0x9a,0x2b,0x45,0xee,0xf5,0x5c,0xbb,0x4a,0x5a,0x9c,0xd4,0x6c,0xda,0x80,0x08,},"\x14\x54\x9e\xdd\xd5\xf2\xb7\x90\x5d\xda\x19\xd7\x4a\xb2\x07\xaa\xc6\xfb\x3e\x3d\xf3\x29\x5d\x84\x52\x31\xef\x3a\xea\x6e\x1f\x04\xee\x03\x3c\x90\x38\xdc\xb4\xbd\x3d\x5e\x45\x2c\x54\x83\x4d\x0f\xf2\xb7\xde\x3f\x32\x2e\x56\x26\x94\x9c\xd6\x1d\x6e\x89\x01\x38\xff\x0e\xa8\xad\x84\x6e\x8f\xe8\x87\xae\xe1\x5f\xc4\x8b\xbe\x4f\xba\x42\x45\x5f\x5c\x17\x45\x7a\xe7\x89\xb4\x05\xaf\x85\x96\x11\xfe\x1f\x87\x46\x18\x5a\x65\xae\xf2\x13\x4e\xa4\xd8\xf3\x98\xd4\x8d\xf7\xc1\xbb\xa4\x30\x44\x08\xae\x7e\xfb\x35\x29\x24\x09\xd5\x08\xdd\x55\xce\x21\xde\x8c\x28\x16\x0d\xc9\xe8\x77\x70\x0c\x76\x3d\x06\xb0\x1b\x85\x42\x05\x2d\x7d\xdb\x63\x35\x54\xe3\x58\x42\x79\xc7\x96\x93\x70\x23\xc8\xea\xc3\x72\x77\xbe\x2b\x82\x04\xff\x3e\x0e\x10\x31\x19\x0a\x01\x01\x4c\xf5\xf5\xb4\xd7\xad\x99\x67\x27\xf9\x75\x31\xe0\x35\x5b\x87\xc9\xe6\x11\x52\x5a\xad\x07\x99\x58\xe9\xaf\xe2\xab\x10\xe4\xa3\xe7\xa1\xb6\xba\x0a\xff\x81\x5d\xa2\xcd\x81\xea\x9e\xb9\xf5\x36\x98\x66\x33\xf3\x16\xdd\x06\xc2\x50\x3c\x6b\x19\x8d\xc5\x93\x04\x80\x7b\x98\xb4\x29\x35\xf5\x1f\x63\x7d\xdb\x59\xe2\x33\xfe\xd5\x66\x43\x9c\x1f\xe9\x6c\xda\xaf\xa4\x9f\x44\x12\xd0\xc1\xe6\x54\xd8\xc6\x90\x42\x47\x0b\x3a\x59\xac\xb6\xbf\x67\xe4\x0b\x38\xa7\x70\x67\xd5\x99\x7b\x8d\x35\xed\x61\xd6\xeb\x3c\xc7\x8b\x8b\xdc\xb9\x57\x4b\x1c\xed\x9f\x6f\x33\x9e\x9e\x38\xf9\x41\x46\xef\x63\xf0\x49\xe6\xb8\x02\xbf\xed\x2a\x51\xab\x42\xe7\xd4\x89\xf3\x16\xff\x4d\x1c\xd8\x98\xbc\xf8\x50\x56\x51\x68\x74\x40\x74\x9c\x0f\xb7\xa5\x7d\xbe\xff\x72\xe6\x46\x89\xfa\xa4\x1c\x07\xb4\xad\xe5\x99\x33\xd2\xfa\xc6\xd5\x73\xde\xb7\x39\x54\x9e\xb7\x5f\x1e\x6f\x73\x85\xd8\xc6\x14\x28\x94\x97\x3e\xd6\x85\xeb\x8e\xd0\x80\xc2\xa4\x9f\x3a\xc6\x57\x11\x61\xaf\x96\x63\x5a\xd0\x57\xdf\x14\x86\xd3\x96\x77\x3a\xc8\x98\x32\x10\x97\x89\x86\xe1\xbf\x21\xa2\x08\x06\xd6\x67\xa4\x8a\x55\x5a\x96\x32\x21\xd5\x06\x14\xa8\x97\x6b\x2e\xec\x97\x51\x2d\xb1\x1a\x35\x81\x94\x49\x2a\xb5\x45\x58\x01\xba\xa1\x4a\x51\x1b\x26\xeb\x0c\x68\x28\x9d\x79\x05\x23\x71\x2f\x2f\xf8\x70\x98\x92\x69\x5c\x4d\xb9\xad\x31\x0d\xf8\xc6\xee\x7b\xd8\x3c\x87\x1f\x05\xae\xc3\x3b\x7a\xd3\x26\xf4\x46\x69\x2a\x42\xf7\x22\x23\x76\x24\x6d\x53\x6a\x32\x6c\x4d\x73\xeb\x57\x2f\xea\xda\x11\xb8\xac\x71\x14\xf6\xcb\x44\x4c\xa2\x78\xfc\xf0\x7b\x97\x0d\x2a\xd4\x65\x37\x2a\x68\x7d\x36\xb7\xda\xac\x47\x87\x48\xec\x6a\x93\x2d\xa2\x08\x43\x94\x8e\xfa\x39\x30\x97\x81\x42\x72\xe5\xca\x1c\x73\xe7\x11\x97\x3a\x52\x68\x3f\x98\xc0\x1e\x55\x24\x1c\x15\x4d\x28\xe3\x8d\x3e\xdf\xad\xe2\x30\x3a\x4e\x7c\x45\xc2\xa7\xa1\xc9\x96\xee\x11\x37\xaf\x86\x4a\x98\xb6\x98\x09\xfc\x92\x14\xee\xa8\xcf\x3a\xfe\x84\x2f\xee\x3e\xb9\xa9\x32\x2c\x3b\x82\xfd\xdb\x05\xd4\xd1\xa2\xde\x09\xc1\xce\x72\x73\x44\x53\xa8\xdd\x3a\x89\x20\xd0\xd0\xac\x96\xef\x77\x8b\x9e\x02\xc6\xa3\xf1\x28\x72\xe1\x7d\x3a\x81\xba\x75\xfd\x23\x3b\xaa\xdb\xe2\x16\xea\x0a\x58\xe9\xdd\xa0\x08\x40\x87\x02\x08\xae\x41\x35\x40\x03\x0b\x3c\x05\xe5\xd0\xb8\x32\xdf\x87\xc8\xee\x7f\x15\x34\x87\xaa\x11\xba\xd9\xf1\x39\xc7\xdd\x4b\xcf\x41\x8f\x4b\xcb\x95\xbe\xe8\x57\xd0\xe9\x60\x84\x47\x23\x87\xcb\x39\x12\x7a\x94\x71\x34\x50\x19\x63\xa7\x07\x1b\xdb\x34\xde\x69\x61\xbe\x2b\x6b\x06\xe4\x03\xe7\x59\x18\xe6\xf6\x9d\x08\x02\x1c\xf2\xa8\xac\xb8\x0a\x01\x11\xf4\xd5\x06\x10\xc1\x52\xd3\x9c\x66\x21\xc0\x57\x8a\xc6\x89\x95\x9b\x1c\xe6\xf3\x76\xf4\x3d\x18\xaf\x06\x2e\x4a"}, +{{0x42,0x80,0x66,0xc5,0x24,0x45,0x72,0x6d,0x0e,0xa2,0x00,0x7e,0x50,0x46,0x37,0x27,0x4d,0x84,0xee,0x23,0x23,0x25,0xb5,0x05,0xf2,0xc5,0x16,0x35,0x7f,0x80,0x75,0x83,},{0xdd,0x40,0xfe,0x8f,0x67,0xc6,0x65,0x61,0x3b,0x3c,0x45,0x9f,0x6a,0xce,0x8d,0xc2,0x8d,0x34,0xe0,0xe7,0x7e,0x2f,0x6a,0xa0,0x60,0x59,0x28,0x19,0xbe,0x6a,0x9d,0x68,},{0xc9,0x38,0x82,0x9f,0x59,0x8b,0x1f,0xf1,0xb8,0x18,0x33,0x60,0xd2,0x23,0xf4,0x3c,0x59,0x47,0x30,0x60,0x68,0x76,0xa9,0x9a,0x3f,0x31,0xb2,0x06,0x5d,0x04,0xe6,0xf0,0x75,0xd1,0x39,0x6b,0x3c,0x8c,0xff,0xb0,0xe1,0xe2,0xea,0xab,0xda,0x7d,0xa5,0xe7,0x89,0xcc,0xd1,0xc0,0x20,0x83,0x5f,0xe3,0xa7,0x1d,0xcd,0xb6,0xaf,0x03,0x96,0x0c,},"\xe2\x79\x6c\x50\xd9\x3d\xf8\x12\xbc\xa4\x1b\xf2\xa1\xe1\xdd\x73\x7d\x8c\xf6\xf6\xb4\xf7\x62\x42\xe3\x91\x78\x18\x67\x58\xcb\xae\x08\x84\xe6\x0c\x6b\x4a\xaa\xdd\xae\xc9\xa8\x99\xa9\x12\xe5\xc5\xb9\x80\x4d\x7b\x04\x97\xba\xb4\x45\x8c\x58\x5d\x4f\x25\x92\x22\x49\x8c\xe9\xe8\x0e\xb6\xa7\x97\x9b\xbe\xd6\xd5\x2c\xc3\x80\x72\xf7\x45\xcb\x2c\x63\xe6\x63\xbc\x3b\x9d\x6c\xaf\x01\x2a\x60\x7f\x6d\x3b\x70\x6e\x15\x57\x57\x87\x17\xec\xbb\x97\x1a\xeb\x7c\x48\xe1\xdf\x95\x71\x1c\x55\x0e\x00\x69\x93\xbf\xfb\xa9\x11\xcb\x64\xad\x52\xd5\x17\xed\x18\xbe\x82\x36\x9e\x81\x58\x19\xd3\x17\x59\x47\xd4\xa3\x5b\x2c\xc7\xb9\xdc\x6c\x10\x05\x13\x26\xb3\xf1\xdc\x1e\xdb\x1b\x68\xba\x01\x5f\xf7\xca\x1d\xc3\x61\xd8\x96\x7a\xbc\xff\xd3\xc3\x1f\x7d\x6b\x0c\xb1\x39\x6a\xe5\x41\xf2\x97\x59\xc4\x13\x0b\xe5\x2e\xcc\x11\xd9\x92\x61\xc3\x65\xbf\x7c\xde\xc7\x81\x49\x4c\x5f\xa0\x52\x6d\xb4\xdb\xbe\x66\x0a\x43\x2b\xe5\x60\x43\xc6\x6e\xa0\x7c\x25\x62\x7a\x5f\x72\xb7\x81\x23\xdc\xf9\x86\xff\x71\xed\x1a\xff\xd1\x65\x9b\x13\x93\xd9\x62\x1f\x71\x1d\xfa\x63\xea\xda\x38\x34\x30\x79\x70\x58\xf1\x56\x6a\x00\x05\x2d\x67\xba\x53\xc1\x23\x7b\x56\x91\xde\x3b\x03\x9f\xd4\x47\x6f\x11\x51\xe5\xed\x5f\x5a\x98\x67\x2f\xa3\x3a\x1d\x85\x4f\xa0\x15\x66\xb3\x32\x31\xd4\x6a\xcd\x7f\x34\xb8\x03\x44\x79\x98\x18\x53\x76\x4d\xab\x87\xf4\x98\x44\xcb\x62\xc6\x3d\x53\x6f\xac\xa9\x20\x44\x7d\x8c\xd1\xe8\x11\x3e\xdb\xc8\x3e\x4a\x6b\x78\x15\xe1\x80\xcd\x78\xb9\x33\xd9\x68\x7f\xd5\xbe\x99\xd0\x51\x8a\x44\x66\x29\x89\xbc\x64\x01\x11\x24\xf1\x87\xd4\x39\x79\x99\x4a\x95\xe0\xc9\x03\xa0\x06\xc1\xc0\xbe\xf1\xc0\xf3\xdf\x1e\xb7\x00\xf9\x80\xc2\x8c\x3c\x1e\x99\x7d\x0c\x56\xd1\x13\xda\xe1\x96\x88\x2b\x05\x01\x8f\xca\xb3\x14\xd8\x11\x7f\xaf\xba\xbe\x77\x00\xb9\x32\xd4\x7c\x57\x36\x2b\x20\x35\xed\xdc\xe2\xd2\xef\x33\x64\x1e\xa9\x0c\x3e\xa3\xfe\xc6\xea\x5b\x87\xe1\x61\x01\x4c\x4f\x82\x14\xfd\x03\xce\xbf\x94\xab\xe1\x22\x53\x7a\x98\x70\x32\x39\xdf\x58\x21\xc5\xab\x63\x3f\x98\x36\x5c\xc6\x36\xe3\xf1\xd2\xf7\x4e\x0f\xf8\xf1\xfe\xe0\x6a\x3f\x73\x90\x7e\xe5\x04\xb3\x10\xfd\x52\x24\xad\x4d\x05\xcd\x23\xc3\x56\xdf\x8b\x34\x64\x72\x98\xc4\x98\x28\x72\x5b\xa5\xfd\x60\x61\x1e\x82\x9b\x63\x37\xbc\xc9\xdc\xf8\xe8\x97\x1c\xab\x3e\xe9\xc2\x63\x37\xd3\x8d\xfd\xfa\x03\x6b\xf6\x09\x6b\x63\x5a\xc1\xbd\x55\x25\xec\xd3\x77\xa1\x52\x72\xa8\xac\x9b\xbe\xf1\x33\x10\x7a\x42\x25\x8d\x8b\x19\xec\x69\xdc\x42\x61\xbe\x53\x00\xa2\xd2\xd5\xca\x99\xf3\x1e\xfd\xf2\x59\xf9\xd0\x79\x86\x9a\x34\x41\x37\x79\xf3\x02\x88\x24\xd7\x47\x68\x6c\x46\x0f\xfc\x49\x6f\x20\x10\xf4\x03\xe9\x03\xe2\x7a\x87\xdd\x07\x5a\xe0\xa7\xf1\x68\x94\x16\xd3\x1b\xcc\x15\xf4\x90\xca\xf9\x75\xc4\x0e\x71\x5d\x54\x99\x03\xe8\xbc\x0f\x7d\x91\x41\xe0\x20\xf4\x10\xf3\xca\x2b\x2c\x07\x97\xca\x0d\xc8\xd7\x39\x2b\xff\x24\x35\x28\xc7\xf3\xbe\x13\x89\x97\x18\x5a\x4b\x36\xf4\x53\x76\xd9\xfd\x70\xba\x20\x98\x9d\x2d\x1a\x91\x1d\x4b\x98\xd1\x60\xd2\xb8\xde\x59\x2d\xe2\xf4\xc0\x4f\x35\x86\x0d\xf3\x20\xc5\x48\x44\x0d\x5e\x3a\x34\x6a\x14\xd3\xa6\x3f\xe4\x85\xc2\x88\x91\x26\xb7\xf4\x1d\x55\xa6\xeb\x23\xd5\x62\x0b\xab\xf8\x56\x4a\xa7\x9d\x15\x6e\x98\x3f\x36\xd9\xed\x49\x8d\xa9\xca\x88\x8d\x94\x6b\x53\xcc\x47\x68\xa5\x89\x2d\x52\xd5\x41\x52\x69\x60\x28\x25\x24\xba\x61\x94\xda\x65\x94\x1d\x1e\xa3\x0f\x80\x6b\xb6\xd9\x7c\x74\x88\xb9\x3f\xd0\xa7\x70\xa9\xb1\x5e\xfc\xd1\x2c\x5c\x46\x94"}, +{{0x31,0x45,0xbc,0x68,0xd8,0x29,0x79,0x40,0x8e,0x46,0x57,0xb7,0x75,0xf1,0x50,0xc6,0xd2,0x8a,0x32,0x4d,0x74,0x6e,0xa6,0xde,0x90,0xfd,0x72,0xb1,0x7a,0x25,0x79,0x82,},{0xc7,0x76,0x18,0x6c,0xe4,0x7f,0x30,0xad,0x08,0xfa,0x1d,0x2c,0x61,0x6a,0x36,0x44,0x66,0x5b,0xa5,0x4f,0xf7,0x30,0xfc,0x2f,0x4d,0xb1,0xdb,0xa3,0x8d,0xde,0xed,0xca,},{0x24,0xa4,0x33,0x33,0x76,0x83,0xbc,0x71,0xa6,0xca,0x3b,0xcc,0xd8,0xcc,0x24,0x00,0xc2,0x44,0x64,0xfa,0x67,0x71,0x4b,0x46,0x51,0x5f,0x2a,0x14,0x32,0x71,0x27,0x05,0xd5,0x70,0x61,0x4d,0xb6,0xd2,0x6b,0xbb,0xd3,0xf0,0x26,0x7c,0x14,0x27,0xca,0x1c,0x2f,0x40,0xdc,0x9a,0x6f,0x1f,0xb0,0xf0,0xfc,0x71,0x4a,0x02,0xe2,0x4b,0x47,0x08,},"\x2e\xa8\xdc\xe1\x48\x7f\x45\xd6\xff\x8e\xb8\x3c\x54\xfb\x7e\xdd\x76\xad\x6e\x60\x8b\xb8\xda\xf1\xa1\x82\x3d\xa4\xf4\xe4\xe9\x86\x31\x73\x89\x7c\x19\x7a\xc6\x58\x04\x82\x3b\xca\x95\x09\x1f\x59\xe8\x6d\x63\xc1\x8d\xbc\xdb\x85\x74\x3f\x88\x93\xee\x69\x4d\x81\x56\x01\xf8\xf2\x2f\x4d\x7d\xf0\x87\xf0\x11\x4b\xb2\x6c\x37\x95\xe1\xfe\x4b\x7f\x4a\x8f\xa3\x1f\xd9\xf4\xff\x10\xfe\x5d\xd4\x52\xc5\x4c\x55\x78\xc7\x52\xf8\x88\x21\x30\x76\xbe\x46\x7b\xa3\x0d\x2e\x2f\xbb\xee\x87\x7c\x4b\xe9\xb6\xec\x4f\x04\x02\x1c\x00\x6f\x92\x66\x31\x19\x43\xca\xb7\xce\xa9\x9a\x2a\xce\xbb\x69\xee\xc3\xe6\x18\xc1\x31\xf9\x74\x30\x07\x5f\x79\x75\xe3\x9f\x26\xd5\x31\x51\x78\xb6\x9a\x1d\xdf\x73\x17\x61\x05\x1b\x93\xfb\x8d\xf7\xe0\xe8\xb4\x1e\x82\xe7\xf4\xf7\x5e\x91\xd6\xc8\x90\xb1\x4c\xa5\x33\xe0\x94\xeb\x8e\xa4\x48\x6d\x38\x71\x85\x96\x6c\x98\x29\x5d\x3f\x58\xb1\x7e\xef\x6c\xc3\xb4\xd0\x7e\x93\xa3\xd9\xf4\x77\x2e\xe5\x2f\x18\xa5\xbb\x30\xaa\x39\x72\x85\x0e\x65\x81\x70\xbd\xdb\x67\x6f\x33\x26\x6c\x9f\xd1\x0f\x59\x90\xba\xd8\x91\xf0\xce\xb7\x82\x73\x6b\x40\xf0\x1b\xd8\x65\x09\xb0\x63\x04\xa9\x6d\x93\xda\x23\x3d\xbe\xd1\x8a\xfa\x18\x18\xaa\xf5\x7a\xf9\xbd\xbc\x86\x7b\x39\x7f\xf2\x35\xa8\x3e\x85\x72\x24\xb1\x50\x65\x22\x5e\xec\x03\x9d\xd4\xe2\xd6\x9a\x04\xee\x10\xbe\xa0\x69\x50\x41\xed\xa5\x9b\x05\x8e\xc0\x5f\x49\x04\x8e\xe3\x24\xd1\x6c\x4d\x61\x07\xb6\xec\xd0\x48\x75\xeb\x74\x4e\x93\x65\x47\x1b\x4c\x5f\xe6\x61\x1b\x26\x18\x93\xf9\xd2\xb1\x28\xe1\x35\xf9\x2e\x47\x41\x56\xb2\x71\xb3\xc8\x2e\x9a\x76\x63\xda\xd4\x95\x3d\x30\xe1\x0e\xda\x08\x62\x60\x7d\xec\x33\x72\xb3\x99\x70\xf2\xa8\x4b\x12\xf6\x0e\x6d\xae\x7f\x31\x79\x90\x86\xd3\x8a\x7e\x34\x94\x84\x19\xc1\xb0\x7f\x44\xc2\x15\x9c\x86\xb8\xc0\xcf\xe8\x74\x7f\xc2\xba\xd5\xbf\x47\x53\x56\xcf\xe6\x9d\xe2\xdc\x6a\xd5\xa5\x19\xfd\x65\xc1\x25\x64\x70\x1c\x05\xf7\xc2\x77\xec\xaf\xcf\x4c\x87\xb1\x48\xdf\x1f\x98\x79\xa9\xae\x44\x3c\x55\xae\xa5\x21\x38\xc6\xfa\x01\xef\x0c\x3a\xbb\x5f\x2d\xf9\x0a\x57\xab\x66\x24\x17\x8c\x73\x7b\x54\x91\x5b\x7a\xa2\x9e\xa7\x8e\x8e\x49\xef\x5a\x81\x6d\x8a\x92\xc2\xf8\x1b\x8a\x19\x63\x27\x79\xc8\x92\xd6\x6f\x75\x3d\x51\x8c\x41\xcc\xcc\x9e\x59\x3e\x50\x74\x26\x25\xbc\xaf\xa4\x68\x80\x5c\x37\xa2\x1f\x8e\x29\xa6\x96\x0d\xdf\x5c\x5e\x5c\xa1\x4a\x7b\x05\x2a\x7b\x60\x15\x69\x7a\x02\x10\xed\x6f\x01\x43\xe6\xb4\x84\xc3\xf5\xb3\xb4\x72\x6c\x60\x7d\x07\xbf\xb3\xd5\x4a\x09\xc9\x80\x43\xf2\x1d\xcc\x5c\xc2\x0b\xb4\x75\x4e\x2e\x5a\x73\xb2\xf8\x06\xc2\x20\x4b\x72\xf3\x6a\xb9\xe9\x6a\x62\xc6\x27\x7c\x0a\xd6\x6b\xe7\xab\xff\xc1\x63\xb4\xe8\xfa\xfc\xef\xf5\xe2\x02\xe5\x94\x3f\x4f\x0e\x6b\x92\xb4\xdd\xb9\x53\xcb\xb7\x91\xf8\x31\x66\x03\x69\x38\xe6\xc4\x4a\xd9\x1a\x59\x6a\x55\x73\x44\x0f\xb3\x07\x41\xe6\x60\xb6\xcd\x5f\x86\xff\xa7\x46\xe6\xe9\x72\xb8\x05\xc1\x0b\x7b\x7b\x9a\x63\xc0\x55\x1d\xb8\xeb\x4f\x84\x00\xcd\xe2\x86\x8c\x0d\x0d\x4e\xb4\xcf\x11\x7f\x8e\xc4\xab\x97\x44\xfc\x58\x79\xde\xa7\xf0\xef\x16\xc2\x91\xd5\x5c\x17\xf0\x8b\x73\x1b\x7c\x65\xd0\xc4\x41\xb6\x3b\xc8\xff\x5e\x94\x90\x4c\x02\x6a\x13\x61\xda\xcc\x80\xa9\x3a\x9b\x9f\xba\x3b\x40\x36\x17\xae\xb9\x4a\x56\x85\x41\x84\x80\x11\x95\x42\x34\xae\xad\x70\x0f\x03\x4c\x47\xc7\xde\xf8\x77\x90\x52\x55\xf1\x8b\xdb\x9a\x25\x7c\xe5\xbd\xcf\x0e\x17\x67\x0c\xda\xaf\x13\xb1\xc7\xe0\x9d\x58\xf9\x2a\x96\x63\xaf\x23\x9e\x22\x07\x8e\x18\x0a\x23\xcc\xb6\xf6\x4d\x64"}, +{{0x5a,0x25,0xea,0x5e,0x18,0x2d,0x9b,0xf8,0xe9,0x30,0xa2,0x0b,0x6c,0xf5,0x5e,0x24,0xe8,0x38,0x62,0x78,0x9b,0x38,0x39,0xb1,0xce,0x9a,0x71,0xe9,0x38,0xc4,0x2d,0x37,},{0xc9,0x81,0xfc,0x36,0xf1,0xa6,0xd5,0xf7,0xd4,0x51,0xcd,0x5e,0xf3,0x9c,0xd3,0xab,0x02,0x08,0x7f,0xcc,0x6a,0xf2,0x7d,0xd7,0x8e,0xa8,0x27,0x49,0x7e,0x77,0x9e,0x21,},{0xa4,0xf3,0x5b,0x49,0xd7,0xe1,0x98,0xe5,0xd3,0x26,0xe3,0x53,0xfb,0xb0,0x1f,0xa1,0x3b,0x6a,0xe2,0x60,0xd1,0xe4,0x8e,0x30,0xc1,0xb9,0x67,0x73,0x7a,0x5e,0x79,0x93,0x6c,0x97,0xca,0x2b,0xa7,0x99,0xca,0x34,0xe5,0xe7,0x88,0xce,0xa5,0xac,0x8e,0xd1,0x0d,0x5c,0xd1,0x5d,0xae,0x53,0xe4,0x24,0x32,0x32,0x1c,0xc2,0x6d,0xc9,0x98,0x09,},"\x21\x4d\xd1\x92\x7f\x2c\xac\xd9\x88\x87\x14\x24\x9b\x85\x43\x46\x02\xac\x78\x45\x3b\x4a\xf5\x38\x6e\xee\x39\x29\x5d\x3d\x5a\x22\x67\x80\x6e\xb0\xcf\xf2\xc1\x32\xd3\x64\xc2\x42\x0d\x04\xe3\xf6\xcc\x0a\x96\x7b\xf0\x5a\x10\xff\xcf\x12\x17\xbb\xf3\x15\xe7\x5b\x98\x06\x0f\xd4\x58\xd6\x7e\xba\xad\x93\x80\xf4\xad\xc4\xdb\xdf\x74\xcb\xf1\xc6\x47\x92\x02\xbd\xd7\xfe\xd3\xa9\x46\x69\x7d\xc3\x84\x44\xd8\x8b\xfe\x51\xd4\x1d\x7a\x9b\x38\xda\x60\xb8\x50\xc5\x6b\x48\xba\x98\x4f\x6a\x18\x89\x51\x49\x55\xc0\xda\xdb\x69\xa8\xc7\x36\xcc\x76\xcd\xc4\x9f\x13\xf8\x5a\x8b\xfb\x79\x28\xff\x0a\x0c\x0c\x03\xf1\x7c\x74\xb5\xe1\x06\x2d\x75\x53\xfb\xeb\x9d\xd3\xd5\x08\x1d\xe1\xdf\xd8\xa6\xa9\x97\x66\x97\xc6\xa2\x59\xbc\xf7\xd4\xbe\xf1\xc2\x1e\x0a\xaf\x32\x98\xb0\x42\x1b\x91\x9f\xdd\xfc\x1d\xcb\x3e\xc6\x83\xd8\x6f\xf3\xd4\x23\xd7\x1c\x8f\x2d\x72\x3a\x42\xff\x68\xd8\x2e\x9f\x39\x17\x49\xb8\x29\x98\xdc\xfa\x11\x21\x60\xf5\x2a\x41\x3a\x23\xd9\x5f\xc4\x2c\x3b\xd2\x23\x84\xba\xd7\x77\x54\xa7\x10\xd8\xb9\xf8\x4a\xe0\xa8\x02\xfc\x46\x50\x9e\x7f\x2b\x07\x07\x90\x12\xb4\x3b\xfe\xea\xb7\x19\xbd\xe5\x6f\x00\xe5\x9b\x8e\xdf\x1c\x47\x28\x83\xb1\x98\x5b\x2f\xa6\x99\xa1\xae\x90\xcf\x45\xd7\xac\x58\x0c\xeb\x5f\x27\x97\xde\xf5\xb8\xbf\x4f\x2b\x9b\x35\x19\xa7\x27\xb9\xf2\xcd\x12\x56\xa2\xf0\x76\xed\x22\x96\x49\x5b\x5c\x2d\xf7\x88\x7f\xf8\x9e\x88\xe2\x36\xa1\x4c\xde\x63\x24\xf4\x3d\x68\xd9\x01\x72\xb0\xb8\x8b\xd2\x88\x03\xe9\x99\xdb\xed\xcc\x50\x1d\xb6\x54\x54\x4e\x17\x1e\xc1\xf9\xf3\x2d\x4d\x33\x21\xd5\x89\x39\x2e\x03\xca\x65\x9f\x96\x75\x2e\x1f\x08\xa5\x5d\xb5\x53\xd8\x66\x98\x55\x41\xf5\xbe\xf8\x4c\xe2\xee\x32\x3e\x17\xd1\xf7\xdc\x16\x4b\x50\x51\x5a\x28\x7d\x53\x05\xfc\x28\xc5\x98\x3b\x9e\x53\x98\xb2\x40\x7a\xe4\x72\x96\xfe\x4a\x48\x1d\x22\xff\xb4\xb8\x65\xa6\x6b\x97\xa6\xc2\x79\x35\xdd\x8e\xb8\x69\x94\xb7\x9d\x36\x83\x63\x71\x3f\x10\x1d\xc3\x7f\x42\x9e\xee\x0f\xee\x24\x41\xc2\xdc\x17\xbf\x43\x92\x4f\x0c\x04\x4f\x14\x32\x90\xea\xf3\xf9\xee\x4d\x94\x6d\xbe\x45\x83\x1a\x0d\x83\xc0\x76\xe7\x51\xc1\x4f\x3b\x1a\x72\x67\xf5\x44\x6c\x18\x86\x98\xd2\xb4\x6d\x87\xe6\xf3\xb2\x0b\xb3\xfd\xaf\xe2\x4c\xc0\x96\xbc\x31\x2d\x86\x78\xb3\x8a\x80\xc3\xf0\x52\xa0\xc9\x6d\x5a\xd8\x7a\x5d\xd8\xc1\x33\xcc\x9a\x15\xbe\x33\x57\x4c\xd9\x43\x08\xc2\x4d\xec\x1a\x9b\xdf\x18\x9b\xa6\x87\x19\x9f\x72\xef\x67\x09\x87\x8e\x10\xf8\x7b\xd8\xa0\x3d\xc8\x4c\x8f\xa9\x64\x20\x28\x58\x98\xca\x32\x11\xd8\xb0\xcc\xef\x64\x01\x1e\xc2\x4f\x38\xe5\x74\xda\x34\xda\xb9\xd2\xf0\x02\x10\x52\x27\x89\x0f\x92\x48\x8c\x62\x1e\x57\x13\xe4\x7d\xbc\xb1\xa8\x2a\x6d\xa6\x0d\x8b\x22\x01\xeb\x29\xd4\x94\x49\x33\x60\xed\x5a\x3f\x4b\x52\x25\xea\xe7\x70\x7e\xe0\xb4\xc0\x40\x73\x05\xc1\x67\x54\xc7\xf6\x30\xfc\x85\xc1\x3e\x49\x17\x04\x7b\xcf\xf3\xb2\xa2\x93\xfe\x95\x55\x06\xc7\x26\x4e\xa6\x5b\xf3\xa9\xb2\x5a\xcf\x34\x36\x00\xd8\xfa\x0c\x7c\x1a\x29\x0d\x02\x71\x10\x1b\x7f\x40\xb9\x6e\x7f\xda\xf2\x9d\xef\x9d\x93\x27\xa5\xae\x05\x44\x6c\xb5\xa6\xd3\x22\x45\x3a\x8b\x09\x8b\xcf\x3a\xee\x1f\x70\x4e\x14\xd0\x0b\xe3\x42\xb8\x93\x4d\x19\xe5\x29\x21\x88\x72\xea\x3a\x2f\xb2\x12\x4b\x52\x66\x7c\x01\xfc\xa5\x84\x1c\x66\xe1\xe6\x4a\x1e\x68\x0e\x09\xba\x18\x6e\x04\xd1\x05\x18\x6c\xf6\xeb\x72\x8b\x9d\x50\x2a\x66\xb8\x29\xfb\xc9\x92\xa3\x88\x10\x04\xec\xdc\x80\xad\xfd\x04\x4e\xda\x88\x0f\x8a\xf7\x2a\x14\xfb\x55\x0d\x7c\xc7\x41\x94\xa9\x45\x20\x7d"}, +{{0x42,0x33,0x5c,0x30,0xb3,0xf6,0xb3,0x59,0xce,0xf5,0xaa,0xb6,0xa3,0xce,0x28,0x58,0xa1,0x51,0xb7,0xa4,0xfd,0x78,0xd2,0xfd,0x3e,0xe3,0x6f,0xc2,0x9d,0x24,0x94,0x04,},{0x30,0x1c,0x51,0x5a,0x02,0xa4,0xc6,0x6b,0xc6,0x40,0x10,0x80,0xc6,0xca,0x79,0x23,0xb7,0x83,0x1e,0x3c,0x9a,0x72,0xb5,0x5b,0x14,0x02,0x7e,0xb2,0xe7,0xb3,0xb1,0x52,},{0x67,0xb0,0xf1,0x74,0x49,0x03,0x9e,0x8c,0x79,0x7b,0xf9,0x13,0xaa,0xe6,0xe4,0xf0,0xbb,0x99,0xc7,0x4d,0x6d,0x10,0xc9,0x73,0xb9,0x90,0xff,0xe0,0x3e,0x7e,0xe4,0xab,0x5b,0x35,0x80,0x6d,0xb1,0x5a,0x98,0xc0,0x84,0x6a,0x82,0x7e,0x7b,0xcd,0x53,0x9c,0xd3,0xbc,0x09,0xdd,0x11,0x8a,0xb3,0xe5,0x26,0x63,0xa3,0x57,0xb1,0x29,0x91,0x07,},"\x6d\xa2\x25\x1e\x6f\x55\x95\x36\xb0\x9b\xfa\xfb\x81\x60\xa2\xe8\x10\x2d\x31\xf8\xb5\x93\x24\x08\x3e\x52\x27\xb2\x0c\x3e\x5c\x3a\x06\xe2\x39\x67\x68\xdc\xa3\xec\x76\xdc\x7f\xc0\xeb\x3d\x14\x5e\x62\xed\x07\xfc\x1a\x8b\x1b\x2e\x34\x70\x13\xa0\x52\x72\x74\xd0\xb2\x34\xfe\x72\x50\x26\xa9\xd1\x28\xf8\xdf\x20\xdb\xfa\x3b\x65\x03\x81\x8e\xde\xbd\x7f\x24\x93\x40\x80\x94\x5a\x7e\x1e\xa0\x22\x73\xfe\x48\xb6\xed\x1e\x83\xfd\x16\x8d\x79\x73\xfb\xb7\x94\x1b\x40\x37\xd3\xcd\xa5\x55\xe0\xe8\x9c\x2b\x94\x3f\xb1\xe2\x07\x65\xac\x7d\x4f\xa3\x77\x7f\x35\xa0\xa8\xbc\x11\x8f\x59\x9c\x84\x7b\xe3\xfd\xb2\xd8\xe2\x01\xae\x12\xa3\x0b\xde\xfb\x03\x4f\xf2\x4e\x3e\x2e\x70\x1a\x0d\x17\x33\x73\x40\x78\xbd\x1f\x9a\x69\xbb\xc6\x67\xe4\x61\x21\x1f\x2c\x76\x9d\x29\xdb\x7c\x4d\x62\xd6\xb1\xb9\x2b\x56\xf5\xf1\x8a\x93\x1a\x92\x60\x64\xb7\x8d\xa1\x46\xe1\x8b\x48\x13\x9b\x9b\x39\x86\x2a\xec\x37\xbc\xce\x12\xcb\x78\x94\x29\xe6\x8e\xa3\x81\x12\xd0\xb5\xcc\xe3\x0b\xd2\xd2\x6c\x5f\x7f\xd4\x15\xda\xf7\xca\x31\x7b\x33\x68\xb7\x61\x7d\x45\x25\xe5\xbc\x97\xd9\x46\x1d\x5d\x64\xf6\xb5\xd3\x18\xd0\xbc\x3b\x76\xf2\x5b\x06\x05\x42\x69\x09\xf2\xaa\x0c\xd6\x67\xa4\xf0\xe0\x75\xb9\xa9\xfb\x2e\x9a\x6c\x82\x70\x4d\x8a\x9f\x16\x66\x84\x4e\xdc\x32\xf6\x3a\x3d\x4e\x0f\xd9\xfd\xba\x30\xb5\x1b\x33\x36\xb9\x6e\x9e\xae\x39\x2a\x34\x2d\xe4\x9e\x9b\x5f\xa0\xf9\xb9\x01\x71\xbd\xe0\x9c\xf1\xe9\x46\x49\x91\x40\x00\x81\x59\xeb\x18\x65\x56\x3c\x28\x39\x4b\x03\xa8\xd7\xa5\x52\x27\x1b\x28\x76\x68\x75\x66\xb8\x0f\xd3\xbe\x2b\x66\x33\x2f\xca\xd1\x96\xca\xb8\x52\x7c\x56\xe2\x15\x36\xa1\x41\x65\x2c\xdc\x7f\xa7\x45\xb2\x6a\x33\x1d\x78\x7b\x93\xe5\xe8\x16\xd8\xd8\x51\xa5\x8f\x6a\xc0\x7a\x58\x27\xfc\xdf\x47\x2e\x86\x85\x43\x3a\x40\xca\xc0\xc4\x9a\xa5\x69\x31\x9a\x2e\x57\xb4\x1c\x99\x98\x16\x5e\x69\x72\x3b\xa7\x7e\x5c\x04\x23\xc4\xb4\xca\x07\x18\x7b\xb7\x44\x2e\x7d\x31\xca\xac\xb2\x77\x00\xc7\x1a\xe4\x8c\xd0\x55\xed\x2f\xe4\xda\x36\x3f\x44\x82\x11\x24\xcc\xa1\xbf\x2e\x63\xd9\xb8\xab\xd2\xfa\x41\xb1\x42\x2f\x52\xd5\x58\xbc\x5f\x11\x0c\x86\x3c\xc6\x00\x86\x49\x84\xed\x25\x9b\x73\xcd\xdd\x57\x96\xb3\x29\x79\xed\xdf\x76\xa0\x7b\xc5\x9b\x73\x68\xc4\x8e\x12\x9e\xcc\x0d\x45\x35\xdc\xce\xe2\xc3\xb8\xe5\x6d\xe5\x0e\x6f\x5c\xc6\xea\x51\x5c\xd6\xa0\xeb\xdf\x1c\xa7\x9a\xa2\x79\x48\x21\xad\x2e\x10\x9e\xdd\xa4\x50\xc9\xfc\x3c\x84\xd8\xc9\x6b\xc3\x8d\x4b\x43\x7a\x73\x8f\x81\x8b\x4d\xdc\xb6\x84\x38\x3c\x09\xb1\x1b\x36\x05\x2e\x9d\x2f\x76\xa6\x1e\xb4\xd6\x20\x49\xce\xd5\xf6\x16\x62\xc4\xb9\xec\xd2\x4a\x67\xf4\x51\x9d\x46\x52\x8c\x5b\x2e\xb2\x10\x05\xf4\x9c\x73\xa3\x37\x0c\x68\xe3\x7a\xc2\xb1\x8d\x48\x1f\xa1\x0f\x96\x71\x4f\xe0\x5c\x16\x8d\xf1\x1c\xda\x54\xf1\x4f\x49\x37\xe9\xfc\xe1\xf5\x16\xc0\x37\x1b\x36\xa2\xc0\xa0\x50\xba\xc7\xfa\x51\x22\xa6\xe3\x5e\xc9\xc4\x04\x36\x58\x5f\x31\x6e\x6c\x91\x1b\xdf\xd7\xdb\x4b\x80\xb4\x30\x64\x79\xb8\x2a\x2b\x24\x3a\x52\xb2\xd2\xb6\x27\x42\xed\x11\x28\x27\x90\xcf\x6f\xdc\x7c\x9c\x82\x43\x64\xcf\x25\x63\x6a\x85\x51\x50\xbd\xdb\xdf\x7e\x64\x0f\x9f\x95\x2a\x94\x7e\xc7\x97\x49\x25\xe8\x24\x50\x68\xb2\x92\x10\x1b\x1f\x4b\x20\x18\xe8\x5d\x07\x8c\x2f\xee\xf4\x49\x23\x49\x72\x9a\xd4\xac\xb3\x8f\x1c\x7c\x02\x70\xb6\x1d\x3d\xfd\x76\x36\xc6\xcb\xf1\x81\xe4\xc8\xa0\xe6\x4f\xa0\x61\x32\x55\x3c\x2b\x9d\xb7\x01\x9e\x3b\x3c\x48\x5d\x8d\x5b\x7d\xfd\x5f\x51\x5e\x4d\x71\xed\xe5\x35\xae\x7f\x2a\xae\xdc\x23"}, +{{0xbe,0x6b,0x2b,0xab,0xdd,0xd2,0xdc,0xa1,0xb0,0xe1,0x0d,0x12,0xd2,0x0a,0x9c,0xe2,0x9c,0x67,0x85,0xda,0xc1,0xd6,0x0f,0x2e,0xdf,0xa9,0x4a,0xc2,0x78,0x4b,0xa7,0x66,},{0x39,0x8f,0x22,0xf0,0xef,0xbf,0x8c,0x38,0x35,0x5e,0x47,0x91,0xbf,0x67,0x08,0x98,0x95,0x1f,0xbb,0xd5,0x51,0x8f,0x0e,0x2a,0x60,0x5d,0x46,0x00,0x23,0xf6,0x13,0xf0,},{0x70,0x2a,0xb9,0xac,0xbf,0xa7,0x5e,0xa2,0xad,0xbe,0x4b,0xe2,0xb6,0x84,0x76,0x25,0xae,0xb4,0x09,0xee,0xf9,0x59,0x6f,0xab,0xe3,0x9d,0x2c,0x53,0x3a,0x03,0x43,0x1e,0x5e,0x57,0x95,0x52,0xe8,0xa6,0x4f,0xc4,0xfb,0x7d,0x92,0x6a,0xa8,0xff,0xfe,0x06,0x40,0x69,0x84,0x64,0xc4,0x45,0x4c,0xe3,0x5f,0xe8,0x3f,0xf2,0x63,0x05,0x1a,0x01,},"\x5c\x92\x95\x88\x1b\x7a\x67\x06\x69\xb0\x4c\xbe\x0d\xab\xd8\x96\x93\xb7\x7f\x7c\xce\x0d\x4a\x33\xf5\x2e\x02\xeb\x26\x95\x9e\x71\x3d\x9a\xef\x5f\x95\x44\x2b\xdf\x91\x72\x83\x83\x32\x52\x02\xaa\xcc\xc0\x37\x47\x7e\x36\x66\xfa\xca\xf2\x4e\xac\x95\x34\x87\x9a\xa3\xef\xe1\x8f\xfc\x1a\x5c\x54\xe3\x9c\x76\x87\xd0\x93\x7b\x24\x71\xba\xb3\x89\xb6\x46\xcb\xe6\xb3\xe5\xd5\x96\x1e\xa6\x3b\xd4\x52\xb4\x74\x33\x44\xce\x4c\x79\x33\x74\x52\x37\x95\xc7\x81\xee\x84\xd5\x11\xe2\x94\x11\x19\xba\xd1\xf4\xa7\x46\xed\x9d\xba\x89\xc8\xd0\x75\x1a\x64\x02\x71\x86\x35\xf6\xe3\x1d\x9e\x18\x68\x1c\x69\x56\xc5\x37\x32\x51\xd3\x5f\x53\xba\xa1\x98\x7c\xd4\x48\xc9\x03\x1a\x07\xf3\x2c\x80\x29\x11\x9d\xe3\xa9\x16\x31\xde\xde\x1d\x93\x3e\x0f\xa3\x26\x29\xaf\xe1\xb4\x2e\xb5\x91\xc2\x2f\x87\x33\x1e\x93\xcc\x08\x3c\x23\xf6\x4a\x6e\x5e\x58\x6f\xf3\x1c\xc0\x4e\x42\x3c\x56\xae\x3f\x6a\x73\x94\x6c\x48\xde\x4d\x85\xab\x00\x17\xba\x24\x45\x6d\x69\xb5\x9d\xca\x6d\x40\x3b\x64\xb0\x7c\x40\xd3\xb9\x0e\x12\x23\x21\x5e\x3f\x7e\x87\x6c\x67\x01\x11\x1e\x37\xe5\x17\x77\x08\x87\x31\x0c\xa8\x56\xf0\x09\xa0\xd6\x06\x54\x83\x5d\x94\xe6\x58\x7a\x43\x9d\xa5\xdb\x0a\x0c\x37\xd7\xc9\xd3\x7c\xa1\xd7\x03\xe1\xb3\x22\x76\x31\xad\xac\xaa\x79\x42\x1a\x1c\x43\x9d\x60\x34\x9a\xe5\x77\x41\xb7\xa8\xad\x09\xec\x29\x31\x23\x03\x0b\xf6\xba\xc0\x68\x9e\x53\x1c\xa7\xe7\x27\x18\x22\x3f\x9e\xa4\x3b\xec\xb0\xee\x9d\x9c\x1a\xb8\x45\xed\x1c\xae\x44\x3e\x3c\x5d\x4a\x9b\x1e\xde\x6d\xb3\x41\x7c\x3a\xce\x28\x11\x43\xf4\x2d\x85\xf5\x99\xb3\xb9\xd3\xd0\x5f\xa0\xed\x07\xc1\xec\x35\xff\xab\x03\x05\x16\x8b\x4e\x56\xe5\x8a\xfa\x06\x17\xf9\xa8\x6b\x1b\x5b\x20\x1d\xcc\xb0\x72\xb4\xce\xf0\xbb\x7b\x95\xc5\x2d\xae\xef\x9d\x9e\x74\x24\xa5\xc0\xf1\x48\xf9\xff\xe6\x0a\x5b\x23\xe0\xff\x82\xc7\x30\x99\x2a\xc9\xc1\x7f\x97\xf0\x65\xcf\x0a\xd5\x37\x7e\xac\xcb\x31\xd8\xbb\x92\x3b\xd2\x60\xea\x11\x9e\x6f\xa9\xbd\x69\x83\x48\x2d\x70\xd9\x21\x91\x02\x40\x2d\xc6\xa3\x49\x91\x93\xd0\xc1\xcd\x3e\xd2\xa6\x69\x21\xa9\x8d\xf6\x9b\x79\x14\x13\xf4\x97\x0b\xbc\xe0\x4f\x63\x9a\xf9\x09\xc6\x4f\x45\x60\xdb\x0a\xf6\x00\x3d\xc4\x62\x19\xe8\xad\x2b\x37\x2f\x8b\x5f\x81\xcf\xaa\x04\x1a\xb7\x1a\x34\x8c\x93\x1e\x8d\xfd\xbc\x40\x9c\x22\xd7\xee\x6e\x07\x62\x6e\x10\x4e\xc6\xcc\x7c\x6a\x41\x16\x17\x7f\x93\xaf\x16\xf1\x24\xf1\x96\xda\xb6\x19\xb6\xf6\x98\xc2\xd1\x91\x85\x8e\x96\x0c\x2e\x94\x7b\x51\xf3\xac\x48\x38\x75\x9c\x21\xfe\xf7\xeb\xae\x35\xda\x24\xf5\x5e\xbd\xa9\xb9\x87\x9a\xea\x17\xa6\xd8\xd9\x27\xde\x48\x7b\x17\x5f\xd7\xfa\xa2\x14\x38\xa2\x09\x23\xdd\xbb\xca\x72\xe6\x72\x69\x34\xbd\x6c\x21\xe8\x11\x80\x19\xf6\x5b\x38\x10\xa0\x7f\xa2\x7b\x1c\xba\x64\xd0\xf3\x9f\x0b\xfd\x49\xdc\xfa\xfd\xef\xe3\x79\xbd\xea\x82\xf3\x1a\x9c\x39\xf7\xe8\x1d\x29\x43\x37\xd1\x0f\x1e\x9d\x8b\x50\xeb\xa4\x58\xce\x7b\x75\x3d\x36\x96\x85\x38\x51\x3e\xdd\xb0\xe8\x45\x34\x41\x1c\x4a\xf3\xf0\x21\x46\x10\xee\x39\x01\xa0\xeb\xf3\x16\x17\x3c\xca\xf1\x5c\xd7\xee\x49\x6d\xbf\xc2\x46\x5e\xb8\x34\xdf\x62\x02\x9d\x62\x1f\xe9\x11\x82\x4d\x79\x87\xdf\x2d\x46\x34\x6b\x4d\xce\x1e\xce\x7d\x19\xd5\x51\x18\xc0\x37\xc9\x95\x51\x11\xd0\x7f\x1f\xc3\x62\xc7\x39\xf1\xea\x5b\x27\x5c\x71\xc0\xae\xbf\x59\x65\x5e\x2d\xef\x16\xe1\x23\xb3\xeb\x25\x26\xc3\xca\x5e\x83\xcb\x24\xd5\xb6\x8d\x7a\xc4\x0a\x67\x59\x33\x84\xc5\x63\xaf\xe0\xb5\x52\xad\xaf\x60\x80\x50\x35\xbe\x97\xb8\x06\x76\xad\xeb\x15\x76\x52\x08\x33"}, +{{0xb1,0xe4,0x7c,0xa3,0x1c,0x64,0xb6,0x8a,0xaf,0xaf,0xb4,0x43,0x51,0x2e,0x66,0x78,0x7c,0x65,0x92,0xf3,0x34,0xaa,0x78,0xfa,0x21,0x9a,0x3d,0x93,0xc3,0x3a,0x4a,0xb3,},{0x58,0x11,0x9b,0x38,0xe6,0xa1,0x48,0xa9,0x36,0xbc,0x5f,0x92,0xf4,0xf2,0x9b,0x98,0x2f,0xf2,0xcc,0xa6,0x4a,0x5a,0xff,0xa1,0x4c,0xa1,0xb6,0xa6,0x2f,0xe3,0x28,0xc4,},{0xdf,0xac,0x86,0xdf,0x58,0x6e,0xc3,0x4c,0x7c,0xfe,0xa5,0xd5,0xa6,0xcd,0x11,0x40,0xe5,0x0b,0x6b,0xf0,0x50,0xf8,0xe4,0x1a,0x19,0x0e,0xbf,0xd3,0xb1,0x43,0x2b,0x95,0xa5,0x7d,0x56,0x52,0xdb,0xae,0x8f,0x53,0xe0,0x37,0xae,0x32,0x6e,0x7f,0x18,0xcf,0xef,0x7c,0x77,0x9f,0x40,0x34,0x6f,0x7c,0x0d,0x86,0x44,0x61,0x05,0x93,0xf2,0x09,},"\x76\x7e\xc1\xb3\xda\xf2\x04\x38\x7f\x3f\xd3\xb2\x00\x10\x78\x1a\xfb\x1f\x38\xf6\x14\x47\x42\x13\x28\x7f\xff\x11\x30\x7f\x5f\xf5\xae\x7e\xc9\x45\xa2\xb9\xb4\x87\x00\x49\xd4\x53\x2f\x8f\x61\xc1\xa7\xb5\xf2\x11\xfc\xa2\xe6\x7c\x37\x4d\x96\x21\x9d\x8e\xa9\xde\x73\xf0\xe3\x87\x04\xfc\x94\xc0\xe9\xe7\x2f\x2e\x15\xda\xba\x3f\x88\xf7\x49\xb1\xed\x70\x26\x60\xdb\x1a\x35\x2a\x26\x67\xd4\xdf\xd4\xe0\x0a\x18\xef\xa4\xc6\x60\x9e\xe9\xc9\xa8\x8a\xda\xcb\xbb\x98\x5d\x3d\xe8\xdd\xd1\x7d\x4e\x4e\xb7\xcf\x74\xa1\xda\x91\xed\xb3\x90\x85\x2e\xa4\xcb\x9a\x42\x4f\x7f\xa2\x22\x9e\x08\x30\x33\xa3\x40\x59\x11\x7e\x5e\xfa\x7b\x66\x13\xd7\x5e\x58\xb7\x02\xc6\xce\xe5\xd0\x04\xe8\x59\x9b\x97\x50\x3a\x5f\x10\xc4\xc4\xe5\xb9\x57\x73\x71\xd3\xd0\x5b\x2d\xfb\xf7\xcb\xef\xe6\xd0\x92\xd6\x5c\xbd\x40\x51\x38\xd9\xb0\x4c\x51\x86\x23\x59\x83\xfa\xb6\xd4\xce\x85\xb6\x36\x27\x62\x06\xd7\x4a\x2e\xe7\xdb\x61\x64\xda\xc4\x7c\xce\x78\xf5\x0d\xb9\x9a\xf6\xac\x6e\x70\x64\xc1\x3a\xab\x79\x3b\xe8\x7e\x66\x28\x9c\x94\xa0\x9f\xb0\xa3\x1d\x97\x97\x1e\xdd\x74\xea\x9c\x0c\xe8\x74\xd2\xb7\xd6\xc4\xab\xae\xff\x07\xf8\x70\x22\x51\x51\x94\x6a\x5c\x47\x6f\x6b\x97\x89\x96\xb8\x7d\x8c\x98\x46\x06\xc7\x91\x28\x7d\xa6\xba\xd0\xaa\x44\xb0\x13\x0b\xe8\x86\x71\xa5\x56\xe2\xde\x35\xc4\xcb\x03\x8e\xe7\x81\x27\x35\x30\xac\xe0\xa1\x04\xc2\x78\x09\xae\xe0\x33\xc8\xbf\x90\x29\xd9\x0f\xe7\xba\x06\xaa\xa9\x4e\x16\xa5\x2c\x64\x3d\xfd\x92\xa7\x62\x4f\xbb\xee\x77\xa7\x15\x8b\x2c\xc1\x51\xbd\x3f\x61\xa1\xa7\x6f\x32\xb2\x84\x89\x30\x7a\xcf\x0d\xd8\xc2\x6c\xc4\xad\xbb\xb8\xde\x43\x0d\xb4\xe4\xf5\x83\x08\xb6\xab\x90\x45\x61\x11\xde\xac\x29\x78\x17\x2f\xe1\xfc\x0c\xe4\x98\x08\x8a\xdd\x4c\x31\xc2\x1f\x24\x27\x90\x25\xfe\xb4\x8c\xbb\x7a\x92\x0c\xff\x2d\x28\x71\x05\x87\xaf\x52\xc8\x44\xdb\x8a\x7a\xeb\x7d\xf1\x0d\x43\x41\x1a\x3c\x8e\xee\xbb\x40\x6d\x6e\xfc\xb1\x92\x48\x88\x7d\x45\x0b\x57\x3d\x90\x30\x5e\x1f\x23\x75\x3e\x89\x05\x11\xdc\xc7\x7c\x74\x0e\x31\x6a\xd7\xf5\x2d\x49\x02\x07\x3d\xb3\x99\x8e\x4e\x4a\xcc\x4e\x01\x88\x5b\xd1\x18\x8e\xcd\x61\x65\xae\xde\xd1\xe7\x78\x70\x2b\x6a\x6a\x79\xa9\x49\x99\x10\x2d\xf7\x20\x18\xf7\x92\xf8\xf1\x62\x00\x7e\x81\x2a\xef\x8f\x95\x6e\x12\x32\x82\xbb\xdb\xd0\xc3\x56\x12\xc2\xd3\x47\x3f\x94\x4c\x6d\x76\xbe\x9e\x86\xff\xfa\x46\xcc\xb1\xae\x13\x50\x5a\x4a\x81\xf3\x1b\x84\x26\xb8\xb6\x0d\xe8\xe8\xa7\xc1\x6d\x1e\x16\x65\xb2\x71\x43\x46\x65\xc4\x42\xa9\xc6\xa9\x77\xce\x98\x6f\x69\x93\xb7\x43\x9a\xf0\x3b\x40\x2e\xea\xff\xf1\x45\x6d\x15\x15\x26\xd9\xc5\x8f\x51\x5f\xd2\x48\x5e\x0c\xbb\x32\x4a\x50\x3a\x8d\x49\x13\x44\xcd\xb2\xaf\xf4\xc4\x1a\xa8\xe2\xed\x66\xe5\x80\x83\xbf\x0d\x2f\xbf\x48\x77\xc8\x5a\x4b\xcd\x6b\x9c\xbb\x82\x12\x42\xc9\x41\x47\xe5\xfd\x8b\x7d\xd7\x92\xad\x0a\x28\xd4\x9d\x41\x10\x0b\x43\x1b\xb4\xd8\xc7\x83\x3d\x85\x05\xdd\x9e\x26\x49\xf9\xca\x70\x51\xbe\x68\x71\x2e\xf3\x63\x71\x02\x03\x6b\x00\x26\x49\x47\x3c\xe2\x59\x67\x7d\x82\xc6\x06\x28\x95\xe1\x61\x92\x8b\x75\x2f\x13\xc9\x1a\x45\x95\x5e\x80\xf0\x07\xde\x69\x0e\xdf\x8a\x0e\x5e\xee\x44\x22\xe1\x62\xb9\xd2\xb4\xa9\x21\xd3\xa6\x48\x45\x79\x3a\xa2\x22\x9e\x9c\x23\x9e\x57\xa6\xb1\xa9\x0a\x52\x54\xc3\x51\x2f\x99\x34\x53\x15\xac\x7d\x34\x57\xf9\x15\x42\x96\xc6\x68\x22\xab\xe1\x84\xd6\x4e\x57\x2b\x9c\x38\x49\x29\x58\xe2\x1b\x02\x92\x67\x54\x10\xe7\x34\x8b\x2b\x71\x8a\x0b\x75\x92\xca\xee\x94\x58\x1a\x94\x8d\x2f\x41\xfa\x03\xc6\x1e"}, +{{0xfb,0xd5,0x5f,0xa7,0x43,0xc3,0xa5,0x91,0x0b,0x38,0x57,0xdd,0x0b,0x6a,0xa5,0x84,0xf3,0xb2,0x38,0xde,0x05,0x6b,0x76,0xab,0x76,0x17,0xae,0xb5,0x26,0x38,0xfe,0xf6,},{0xa7,0xa1,0x63,0xc4,0x18,0x3b,0xd8,0x4b,0x75,0x6d,0xf3,0xc8,0xaf,0xdf,0xb9,0xcd,0x5b,0x24,0x23,0x52,0xd9,0x49,0x9e,0xbd,0xab,0x90,0x78,0x5c,0x3b,0xd6,0xdb,0x2d,},{0xef,0xfb,0x29,0xda,0x69,0x85,0x97,0x1c,0x20,0x2e,0x24,0x50,0x30,0x1d,0x49,0x71,0x1b,0xed,0x25,0xfa,0xd8,0x5f,0x61,0x99,0xd1,0xeb,0x1e,0x71,0x91,0x4d,0x96,0x4c,0xbe,0x18,0xe3,0x4c,0xc3,0xe3,0x28,0x72,0xcd,0xec,0x02,0x6b,0xd1,0x19,0xa4,0x1c,0x1c,0x07,0xca,0x41,0xe8,0x2a,0xcb,0xa6,0x2f,0xb0,0xa7,0xc8,0x2a,0xed,0x80,0x0c,},"\xbf\x52\x52\xb2\xae\xca\x11\x63\x77\x1f\x76\x62\x78\x76\x80\x66\xf2\x19\x71\x35\x7e\xa7\x99\x61\x58\xa8\xd6\xe9\x08\xdd\x59\xb5\x99\x71\x34\x9f\xa1\x78\x82\xcb\x92\x24\xb9\x72\xd0\xff\xab\xe8\x55\x10\xdc\xf2\x5a\x9f\x9f\x9b\xde\xfa\xd2\xf4\xca\xdf\xbb\xda\xcc\x1f\xca\x9d\x94\x8c\xb5\x41\x2f\x47\x4c\xad\x23\xb5\xb9\x19\x9b\xf3\xc7\x37\x06\x41\x33\x9b\x75\x0e\x1f\x78\xc2\xad\xb4\x60\xaa\x5b\x21\xb1\xfa\x8f\x97\x71\x4a\xbb\x4e\xd5\xe9\xcb\x51\xd6\xde\x55\x81\x66\x18\xab\xd3\xfd\x2b\x28\x6b\xc1\x1c\x67\xba\x01\x12\x93\x73\xd4\x35\xb3\xe7\xe3\x91\xba\x37\x26\x14\xda\x83\x22\x87\x5e\x46\xa6\x75\xb6\x45\x15\x60\x24\xca\xd2\xdd\x13\xf9\xa0\x81\x61\x6b\xf1\x31\xa2\x43\x58\x89\x4e\x0e\xfa\x1d\x56\x64\x8f\xfb\x42\xef\xb5\x40\x31\xda\x7f\x37\xd1\x97\x61\x51\x55\xae\xdb\x69\xc4\xe7\x09\xc8\xbb\xbe\x7f\xbf\xcb\x59\x83\x47\xac\x5d\x0c\x63\x84\x07\x84\x7b\x28\x1c\xf1\x16\x43\x30\x97\xf5\x66\x21\x58\x71\x9f\xcd\xd3\x7b\xeb\x48\x92\x68\xce\x71\xde\x7d\x70\xed\x92\x5f\x74\x3f\xc6\x3a\x71\x5f\x7e\xee\x75\x49\xfd\xb9\x09\xcc\x45\x4c\x98\x8b\x30\xae\x4d\x77\xd6\x2f\x65\xa0\x7e\x2c\x8f\x93\x62\x38\x5d\x02\x8a\x60\x31\x08\xc9\x45\x87\x2f\x5e\x1a\x97\x41\x98\x78\xed\x49\x54\x2e\x28\x8e\xf0\x7b\x5c\x90\xf5\xc4\x15\x9e\x16\x23\x03\xd0\x80\xf6\xac\x2b\x05\x8d\xdc\xac\x60\x74\x6f\x9e\x1c\x9e\xc1\xdf\x8e\xda\x42\xd6\x27\x38\x58\x6d\x3f\xdd\x65\xdf\x55\xf4\x37\x4f\x32\x94\xe0\x86\x8d\x41\xef\x0b\xb1\xfd\x55\xe0\xcb\xf1\x95\xbb\xfc\xfc\xde\x5b\xdb\x41\xfa\xd9\xa0\x47\x7e\x4c\x90\xca\x27\xfa\x8c\xf5\x03\x36\x2a\x33\xfd\xec\xa5\xa4\xf0\xff\xea\x26\xe8\xd7\xe1\x34\xfa\xd3\xb1\xec\x3d\x05\x60\x55\xbb\xa5\xe6\x5d\x81\x15\x3e\xe8\x31\x87\x3b\x93\x8d\xf7\xd2\xc8\x3c\x2a\x52\xb3\xc2\x21\x82\x7f\x96\x1b\xd0\x08\x36\x22\x32\xd8\x82\xa0\x41\x2a\x04\x7a\xfd\xfb\x85\x97\xc8\x65\xa2\xaa\x2c\x2c\xf5\x18\x99\x34\xa8\x3e\xe6\xb7\x52\xa6\x26\x94\x1e\xdc\xe0\xc2\x0b\x6f\x7a\x69\xf1\xcf\x12\xf9\xa3\x31\xcd\xfa\x9e\xda\x24\xc8\xde\xfa\x76\x9c\xcc\xe2\xef\x74\x6c\x30\x7d\x8b\xb0\x48\x91\xfc\xef\xd4\x9a\xf3\xe6\xf9\x69\x91\xa7\xa2\x0f\x27\xb6\xc0\xaf\x12\x18\xbe\x31\x79\x1d\x1d\x02\x93\xe0\x81\xb9\x0a\xf3\xb9\x2e\xcb\x17\x5e\xc8\xc7\x89\xf7\xa8\x64\x2e\x04\x1e\xc3\xa6\x1a\xae\xfe\xf6\x2a\x80\x7d\x1a\x50\x54\xad\xf8\x32\x3b\xed\x94\x22\x41\x62\x37\x32\xa2\x05\x1d\xc0\x1f\x9a\x20\xa2\x9a\xa4\x8b\x3f\xdf\x26\x5d\x0b\xa6\xc1\x38\xfb\x57\x93\xe2\x87\x50\x02\xe7\xde\x3f\x5c\x3f\xf7\xe8\x3a\xd2\x7d\x11\x1c\x84\x8b\x7e\x6e\x2e\x5a\xd5\xf2\x8e\xb7\xc3\x63\xf9\x5f\x96\x0c\xbc\x42\x13\x36\xce\x98\x5f\x94\x6b\x05\x15\xb1\xbd\xd3\xa8\x32\xc3\xfe\x90\x3f\x7b\x44\xe2\x0c\x92\xea\x80\x82\x6f\xbf\x97\xe2\xa4\xfc\xaf\x2d\xb1\xa0\x86\x98\xdd\x62\xed\xd0\xa8\x45\x89\xd7\x46\x2c\x44\x7b\x4a\x89\x6f\xe0\x08\x60\x04\x24\x96\xbd\x51\xb1\x92\x5c\xb7\x9c\xc3\xb8\x29\x01\x6a\x4c\x7e\x62\x79\x0f\x80\x58\xc5\x46\xf2\x14\x5a\xaa\xef\x4d\x4b\x1e\x27\x3f\xf6\x13\x00\xf8\x00\x8e\x94\x6b\x62\x2f\x60\xe5\x05\xf5\xf6\x29\x0d\x51\xeb\x99\x7d\x20\xfc\x3f\xbb\x3e\x99\xed\xd6\x8f\xf5\xcc\xe9\xe8\xc2\x83\x88\x1c\x36\x4f\xf2\x15\xcb\x50\x04\x5e\x60\xf4\xa7\xee\x45\xb6\xc9\xd8\x64\x47\xf3\x81\x41\xd3\x42\xdb\xc5\x30\x8f\x8c\x66\xef\xc4\x7f\x7c\x45\xf6\xd2\x5e\x65\x64\x30\x9a\x86\x2d\xb9\x0f\x4d\xf3\x31\x78\x7e\xcd\xd8\x9d\x3a\xaa\x46\x05\x3e\x29\xf1\x02\x62\x4d\xdf\xe8\x0e\x8a\x3f\x99\x28\x7c\xec\x19\xfa\x83\xe4\x4d\x55\x7c\x04\x41"}, +{{0x5d,0x66,0xce,0xb7,0xc6,0xe5,0x8c,0xac,0x91,0xe2,0x88,0x27,0x91,0x70,0xe8,0x18,0xe7,0x87,0x18,0x0c,0x6b,0x42,0xdf,0xa1,0x68,0x78,0x7d,0xd0,0x7f,0x80,0x9f,0xa4,},{0xef,0xc9,0xb3,0x5d,0xb8,0x1f,0x34,0x61,0x98,0xa7,0xac,0xc6,0x9f,0x65,0xfd,0xfb,0xf4,0xc2,0x2e,0x68,0xdd,0x76,0x12,0xe3,0xb8,0xec,0x68,0xd3,0x78,0x55,0x3b,0x8d,},{0x6e,0xf2,0x64,0xab,0xf8,0xb0,0xe5,0xc2,0xd7,0x93,0xb2,0xc7,0x52,0x79,0x61,0x4a,0x39,0xc7,0x75,0xeb,0x2b,0xcc,0x08,0x91,0x06,0x7a,0xbc,0x61,0xf6,0xd6,0x44,0xa6,0x9f,0xf8,0xf8,0x14,0xa3,0x05,0x22,0xcc,0xa9,0x05,0x36,0xf0,0x12,0xc6,0x28,0x3a,0x76,0xc3,0x2b,0x89,0xee,0xe1,0xbd,0x9a,0x43,0x36,0xf4,0xfd,0xda,0xc8,0xdc,0x0b,},"\x94\xd7\x2f\x6d\xec\x4f\x7c\x92\x06\xb4\x15\x10\xce\x71\xa0\x29\x55\x60\x4f\x3c\x5d\xe8\xe4\x47\xd5\x87\x18\x65\xa7\x58\x98\xa4\xd2\x07\xa2\x6c\xf3\x3d\x10\xca\xf0\x5a\x0b\x6e\xd0\xd3\x89\xfe\xe9\xed\x49\x27\x50\x98\xa8\x8e\x1c\x0d\x83\x04\xe8\x1b\x40\x74\x21\x4c\x7a\x5c\xe1\x57\xeb\x26\x17\xef\x04\xe1\x32\x4b\xa9\x42\x12\x9f\xaf\x32\xc3\x1c\xb4\xaa\xe4\xa5\x91\x6c\x75\x08\x08\x72\x68\x56\xf7\x18\x0e\x57\x97\xed\xe4\x43\x62\xd7\x47\xd7\x0c\xec\x15\x9d\x3b\x6a\xce\xc6\x3a\x51\x4c\x7e\xf3\x1b\x2e\xcd\x16\xdb\x7f\xe6\x8e\xa9\xc5\xea\xd9\xd8\x70\x92\x18\x00\x34\x8f\x69\x54\x12\xf3\x09\x3e\x61\x98\x5a\x31\xea\xdb\x79\xb5\x9d\x91\xdd\x9a\x37\xf8\xd4\xef\x7a\x5d\xdf\x22\x3d\x4b\x24\x77\x4c\x2e\x44\xe3\xf2\x71\xff\xb8\x50\x0d\x59\x53\x81\xb3\xdf\x2e\x8e\x6b\x79\xee\x65\x53\x5a\x51\x9a\x43\xea\xa5\xe5\x2b\x25\x6c\x26\x43\x30\x5e\x31\x70\xcb\xe5\x76\x06\xa0\x54\x5f\x85\x86\x56\x5c\xfb\x75\xbf\x5e\x95\x64\xc6\x2a\xf0\x5f\x15\xee\x6e\x62\xaf\xee\xf8\xc2\xc7\xa9\xda\xe2\x35\xc9\xed\xd1\xd7\xc2\x5c\xf4\x9a\xdc\x03\x3e\xe7\xb5\x83\xf5\x18\xbc\x16\x8e\xa4\x88\x36\xb5\x0f\xfe\xdd\x20\x32\xb3\xf6\x30\xcc\x56\xda\xad\xd5\x13\xeb\xda\x86\x48\x23\x61\x0f\xc6\x7a\x72\xb9\xa7\xd8\x11\x71\x05\xc1\xc7\x1d\x85\xa9\x6b\x1d\x27\xa4\x41\xfa\x1e\x7c\x6c\xf8\x02\x33\xa4\x9f\xe0\xe7\x6a\x40\x27\x8d\x06\xe3\x43\x47\xd8\x7b\xe7\x7b\x98\xde\xd5\xe2\xa3\xea\x1a\xfb\x13\xbe\xe1\xe6\xcd\x6c\xa6\x3b\xe5\x4f\xcf\x88\xa2\x0c\xcb\x7a\x9f\xc3\x24\xbf\x61\x43\x20\x1b\x44\x48\x3b\xcc\x96\x40\x33\xda\xb7\x1c\xf8\xf2\xa5\x91\xfc\x05\x0d\x57\x24\xe9\x5a\xa5\x0d\x32\x89\x6e\xec\x0f\x3b\x34\x31\x1d\x2a\x99\x34\xe9\xf8\x52\x97\x7e\x25\x3f\x15\x30\x4c\xae\x24\x16\xc2\xc4\xfc\xd8\xf1\xfe\xcc\x3f\x1f\x64\xbb\x79\x75\x99\x29\xab\xb0\xe8\xe8\xf5\xf7\x29\x3d\x69\x1a\xf2\x2a\xbd\x3b\x2a\x67\x70\xb0\xcf\x14\x46\x08\xf2\xd6\x2c\xc7\xe5\x2b\xfe\x33\x3b\x2e\xd2\xde\x39\xb9\x9a\xfd\x37\xe3\xac\xf0\x7e\xda\x37\xdd\xf0\xdf\x02\x9b\xff\x2e\xc2\x25\x44\xb6\x0b\xd7\xdb\x23\x8d\xf1\x97\x5f\xfa\x00\x75\xa8\x2a\xbd\x8d\x6b\x05\xb2\x67\x18\x0b\x87\x0e\x21\xab\xf3\x69\x81\xae\x77\x68\xde\x53\x99\x3b\x30\x4f\x1c\x54\x53\x87\x2f\xdf\xa8\xed\xad\x45\xf8\x00\x1a\xa0\xe7\x34\x2b\x3b\x58\xec\x0f\x38\x9d\xcb\xc2\x71\xfb\x0f\x90\x00\x62\x87\x57\xab\xba\x58\xc0\x57\xe1\xa0\x89\x9f\x6f\xaf\x15\xf3\x74\x0f\x31\x43\xf5\xc0\xb7\xa9\x15\x96\x80\xde\x8c\x55\x72\x66\x44\x1b\x3b\x01\xca\xac\x12\xec\x27\x8f\x5a\x10\x25\xdf\x53\xed\xb6\x13\x4c\x96\x66\x3a\x96\x66\xae\x3b\xaa\x90\xfc\x83\x51\x11\xef\x05\x1b\xd9\x12\xf6\x79\x67\x44\x91\x13\xb6\xa8\x5f\x71\xdf\x8c\x60\x37\x72\x4e\xb8\xfc\x7d\x83\x19\xbc\x03\x85\xbe\x9b\x0e\x99\xe9\x5f\x9a\xed\xca\xe8\xd4\x5a\x51\x44\x76\xf0\x5b\xcd\x72\x35\xc0\x13\xeb\xc3\xae\xa9\x12\x3c\x67\xaa\x6f\x3b\x79\xc8\x5e\xa5\xdb\x15\x9e\xef\xad\xfb\x75\xa5\x0a\xc6\xb9\x5b\x49\x6b\x55\x72\x58\x1a\x76\x11\x2f\xf6\xdb\x26\x3f\xc1\x4c\x58\x18\xaa\xd5\xbc\xa3\xb2\xcb\x3a\xc8\x11\x6d\x42\x94\x82\x78\x1e\x06\xf6\x1e\x75\x63\xe6\x50\x5e\x51\xc8\xff\x99\x8b\xf8\x4a\xed\xb5\x20\x2e\x2f\x9f\xf4\xc2\x68\x98\x20\x29\x6c\xc6\x96\x03\x09\x1b\x8b\x81\x8f\xbe\xb2\xaf\x5f\x4c\x57\x06\x0d\x98\xc1\xa9\x04\x84\x3a\x70\xbf\x97\x5b\x3c\x3c\xa6\x03\x1a\x4c\xad\x5b\x4b\xbf\xba\x7e\x9b\x47\x49\x1a\xb7\x40\xd9\xeb\xe4\x1d\x76\x88\x10\xcb\x8c\xc5\x1a\x93\x7f\x7e\x3b\x22\xe3\xcf\x07\xce\xae\x0c\xe2\x08\x31\x49\x5a\xfc\xdd\x8c\x1a\x98"}, +{{0x62,0xed,0x86,0x82,0xbd,0x3a,0xb3,0x96,0x6e,0xba,0x3b,0xff,0xb7,0x75,0xa3,0x18,0xa0,0x3d,0x99,0x93,0x19,0x79,0xe9,0x9f,0xeb,0x2d,0xdb,0xd6,0x94,0x55,0xa0,0xef,},{0xd3,0x2a,0xda,0x17,0x8b,0x3e,0xc7,0x70,0x0c,0x47,0xdd,0x6d,0x36,0x53,0x22,0x03,0x3f,0xe4,0x31,0xc3,0x02,0xb4,0x6f,0x8d,0x58,0x79,0x8e,0xd8,0x33,0x71,0x56,0x6b,},{0x3d,0xa8,0xd1,0x4d,0xc4,0xe7,0x1f,0xe6,0xc3,0x2e,0xde,0x46,0x37,0x88,0xe4,0x1b,0x82,0x6b,0x4e,0x21,0x60,0xba,0x10,0xc9,0x5f,0x1c,0x8a,0x27,0x49,0xaa,0xd8,0xf1,0x2e,0x98,0xae,0x24,0x68,0x30,0x3b,0xaf,0x69,0x08,0xbd,0xb3,0x5e,0xf3,0x8a,0x5e,0xcd,0x77,0x74,0x1e,0x72,0xee,0x3a,0x42,0x7f,0xd9,0x04,0xda,0xe6,0x6f,0xcf,0x03,},"\x9e\xb1\x3b\xc7\xfa\xcf\x51\xa1\x80\x54\x1e\xc1\xdc\x5f\x5a\xcb\x14\x8c\x8d\x5e\xad\xcd\x2c\x4e\xf0\x68\xbc\xdd\x11\xb3\x49\x25\xea\xbf\xaf\xab\xfe\x82\xa2\x84\xbc\xba\xee\x13\x81\x15\x2a\xf8\xe5\xe0\x9f\x03\x7c\xf1\xbb\x64\x84\xac\x18\xe3\x73\x59\xbf\xaa\x4c\x87\xaa\x07\xd3\xd1\x4e\xd0\x89\xb0\x53\x91\x0d\x1f\xa4\x73\xf7\xbc\xe1\x43\xe2\xa5\x9c\x4d\xaf\x99\xb6\xc6\xe4\xe9\x29\x1d\x97\xc8\x64\x71\x2a\xf3\xea\xba\x53\xce\x25\x17\xa4\xf7\x5c\xd7\xec\xf2\x78\xf3\x4e\x22\xb7\xdf\xfd\x08\x8f\xa5\xec\xad\xc0\xdd\x22\x13\x5e\x42\xa5\x36\xc6\x84\xf2\x19\x5d\x31\x5f\x69\x24\x57\x1e\x46\x3f\x5c\xfc\x11\xb9\xf9\xd0\x5a\x7e\xa1\x1b\x98\xa1\x69\xa1\xe3\x93\x60\x97\x3c\x50\xad\x45\xc7\x49\x1b\x57\x13\x8e\xc0\x50\xf4\x3c\xbd\x5d\x17\xeb\x3f\xe0\x01\x3e\x3d\x28\xd5\x26\x05\x4e\x07\x63\x31\x52\x24\x6f\x16\x55\x4f\x30\x54\x74\x9e\xea\x68\x7b\x9c\x37\x1b\x40\x9c\xd3\xec\xef\xb1\x11\xa1\xd6\x00\x40\x73\x44\xe6\xd6\xec\x38\xc6\x0f\x6e\x54\x5a\x92\x38\x2e\x46\xc4\xd1\x13\x12\x5d\xbe\x5b\x98\x26\xe1\x27\xf1\x01\x81\xa3\x5a\xcf\xff\x28\xab\x37\x64\xca\x7f\x23\x8f\xf4\x79\xfd\xbc\x45\xb7\xa2\xad\x0f\xf5\x38\xc8\xac\xd0\x01\x8d\x44\x70\xfe\xbc\xc6\xa3\x07\x65\x1c\xb5\x83\x2f\x32\x6b\x19\x24\x1b\xe9\x86\x7e\x4e\xca\x6a\xe3\x6f\x0e\x2d\x83\xfd\x77\xb9\x72\x02\xb3\x64\x71\x6e\x36\xd1\x89\x5a\x36\x85\x3e\x7e\x76\xe8\x8f\x62\xdb\xbf\x77\x26\xc2\x18\x05\x69\xc6\x66\x73\x83\x7a\xd7\x2f\xf9\x36\xcf\x0e\x2f\xdb\x9e\xc6\xaf\xcc\x79\xf8\x82\x9e\x15\x7f\x95\x22\x88\xf4\xe0\x0d\x04\x10\xa7\x22\x53\xbf\x60\x5e\xdd\xce\xb0\x14\x40\xde\xe5\xdd\x32\xb5\xa8\x03\x43\x9f\x03\x8c\x06\xaf\x1c\x90\xb2\x7b\x5f\xe9\x84\x3c\x27\xae\x76\x60\x9c\xbf\x83\x28\x35\xc0\xe3\xc4\xbb\x59\x97\x6c\xce\xde\x44\x87\x86\xd9\x1e\x43\x8e\x07\x75\xc0\x6a\x92\xd0\xf0\xb8\xdc\x0e\xf6\x82\x60\xf7\xdd\x9e\x68\x71\xc4\xd0\xc0\xc0\x94\x63\x85\x26\x15\x21\x85\x16\xf4\xa6\xde\xbf\xdb\x46\x27\x3b\x28\x33\x82\xcd\x9c\xa7\x44\xab\xf9\xfd\x43\x91\x94\xb8\xcf\x1b\xdb\xb3\x17\x5c\xa9\xc5\x7a\x1c\x37\x3c\x41\xfc\xe9\x2b\xd5\xfc\x01\x2b\x19\xa0\x69\x8a\xef\x37\xba\xf8\x06\xae\x09\xad\xd8\xcb\x97\x2a\x9e\xf9\xa7\xa5\xa9\xb1\xfd\x9a\x41\xd8\x54\xc3\x0c\xca\x13\x96\x14\x0e\x20\xc2\xb9\x86\x54\xfe\x6e\x51\x1b\x62\x6a\x43\x91\x5b\x22\xfb\x2d\xad\x74\x7b\xa7\xfe\x74\x60\xd8\xce\xbb\x20\x06\xfe\xa1\x9b\x32\x84\xb0\x9c\x06\xa6\xf5\x2f\x17\x9a\x32\xbe\xb5\x63\x57\xb9\x29\xa6\x59\xf0\xfe\x6a\x26\xb6\x97\x03\x3d\xef\x58\xba\x60\x3f\x43\x0f\x74\xaa\x35\x07\x09\x81\xdb\x74\xcc\xf1\x91\x90\xa1\xfb\x05\x14\x4e\xc0\xa0\x9a\x51\xe5\x47\x65\x06\x97\x30\xb0\x9a\x7a\x23\x31\xff\xb3\xde\x2a\x7e\x02\xc5\xe1\x84\xda\x40\x13\xdf\xe9\x37\xc3\x71\x11\x75\x24\xf7\xb2\x10\xba\x60\xe2\x69\x2d\xcd\xce\xf3\x6a\xb2\x27\xb4\xc4\xf0\x2a\x9f\x48\x89\x72\xb8\x47\xf0\xd6\xb5\x9d\x02\xee\x54\xfe\xde\x88\x21\xdb\x6c\xf7\x31\xcc\x8a\xc8\x95\x35\x0a\xc5\xcd\x4d\x6b\xaa\x3a\xd0\x36\xf0\x6f\x20\xd1\x0a\x14\x0c\x4a\xd3\xd1\x0c\xa9\x85\x53\x2e\x31\x60\x46\x27\x73\x38\x5a\x2e\xb5\xe4\x64\xd5\x28\xe1\xe5\x9c\x29\xf6\x6b\x3d\xe5\x9e\x9e\xa2\x8a\xf3\xf9\x7b\xfc\x55\x89\x03\x57\x52\xa5\xa5\x52\x3d\xec\xd2\xdf\xf0\x1f\xc0\x0f\xf3\x1b\x30\x15\x2f\xf5\xda\xfa\x33\x1c\x6a\xb1\x58\x73\xaf\x41\xaa\x96\x0a\xac\xe7\xd2\xcb\x4f\x95\xc2\x3d\xf4\x4b\x9e\x6c\x6e\x2f\x86\x78\x8a\x87\x2f\xd3\xa5\xcb\xe4\xac\xc9\x58\x10\xda\xa0\x9d\xcc\x1d\xf9\x33\x46\x5e\xf0\x40\xc5\x3d\x9d\x95\x9f\x9d\xad"}, +{{0x4e,0x57,0xf0,0x31,0x1f,0xff,0x0e,0x5d,0x53,0x88,0x49,0xb1,0x21,0x6f,0x69,0x5b,0x1a,0x52,0x77,0x94,0x17,0x08,0x20,0x4d,0xb2,0xf0,0xc1,0x5b,0x3c,0x73,0xc8,0x2a,},{0xe3,0x37,0x1f,0xe2,0x36,0xad,0x2f,0x6f,0x42,0xf9,0xe1,0xfa,0x4e,0x1e,0xda,0x2c,0x3e,0x29,0xc3,0x6c,0x8a,0xd2,0x21,0x8a,0x3c,0x03,0x79,0x82,0xf0,0xb5,0x79,0xec,},{0x4f,0xdc,0x7b,0x6e,0x28,0x27,0xf6,0x4b,0xa3,0xc0,0x33,0xc7,0xfb,0x6d,0x1b,0x35,0xdd,0x68,0x0f,0x53,0x29,0x99,0xa0,0xd7,0x7a,0xeb,0x27,0x6c,0x31,0xbd,0x9e,0x39,0xc6,0x70,0x97,0x8b,0xe4,0x72,0x43,0xc1,0x13,0x22,0x3a,0x57,0xaa,0x10,0x23,0x31,0x50,0x67,0x8b,0x40,0xdb,0x78,0x59,0x1c,0x04,0xd0,0x8d,0xf5,0x7a,0x70,0xa2,0x09,},"\x05\x2a\x1f\x41\xeb\xfd\x4b\xf6\x5e\xfb\x0e\xc8\xe7\x4d\xd7\xb3\x06\x5e\x9c\x48\x2c\x49\xb9\x92\x62\xe6\xdf\xa8\x40\x7d\x9e\x31\xed\x34\xd2\x29\xba\x41\xfc\x49\xa9\x4a\x13\x09\xf9\x90\xa9\x9c\xb9\x90\x2f\xb8\x4f\x4e\xde\x91\xbb\x64\x71\x45\x64\xa9\x13\xd5\x74\xd4\xa3\xc2\x86\xf0\xa1\x92\xa7\x8c\xe2\xd5\x5a\xae\x5c\x9f\xb0\x57\xff\x36\x12\x00\x18\xb2\xa8\xb5\x4d\x98\x08\x55\x37\xea\x64\xae\xa9\x99\xd5\x32\x1c\x78\x80\xb3\x6a\xb4\x30\x18\xea\x2c\x92\xa5\xe6\x83\x50\xd3\xde\x85\x26\xe2\xc8\xbc\x91\x41\xf4\x34\x9a\x18\xa3\x4f\x21\xde\x0a\xbb\xf2\x93\x09\x87\x56\x7f\x0a\xaf\x8e\xb1\x91\x45\x58\x0d\x71\x30\x6c\xe8\xa6\x9e\x79\xf8\xee\xa2\x6c\xfa\x0b\x8b\xeb\x49\xcc\x5a\xa2\xbc\x77\xb7\x97\xd4\xf8\xd5\x03\x26\xff\xb9\x37\x39\x9e\x94\xfd\xec\x85\xe1\x92\xf1\x27\x2a\x80\xe9\xa0\xeb\xba\xf5\xd0\x1f\x1b\x97\x06\x08\x02\xbd\x4a\xf3\x4c\x0f\x7d\x7e\x98\x54\x3f\x9d\x66\xd6\x0e\x0e\x6b\xc0\xbf\x9c\x99\x0b\xe3\x1e\xea\x19\x78\xff\xd1\x67\x33\xa8\xab\xe4\x95\x58\xb3\xad\xd0\xdc\xe6\xde\xfd\x64\xdc\x04\x3f\x15\x19\xb1\xe9\xbe\x66\xe0\x6e\x41\xec\xab\x16\x8c\x83\x39\xa8\x5e\x0b\x91\x38\x18\x64\x4e\xa7\xc5\x33\x44\x68\xfd\x71\x96\xa0\x1e\x1d\x4c\xe8\xdd\x1e\x7e\xe3\x13\xdd\x53\x50\xb8\xdc\xe4\xf5\xd7\xa6\xac\x09\x85\x7c\x4d\x3d\x0f\x10\xa3\xd9\x06\x26\x09\x75\x45\x92\xad\x10\x77\xb2\xe2\x09\x6f\xc9\xe5\xb1\x97\x8c\x98\xb5\x66\x0d\xdf\x51\xb4\x6e\xde\x9f\x9d\xcd\x41\xb2\xef\x44\xe7\x9f\x6d\xaf\xf7\xd3\x62\x68\x70\xe2\x24\x3c\xaf\xb2\xf4\x36\x79\x39\x10\x9e\xd9\xc0\x14\x84\xb7\x9e\xaa\x30\xa1\x89\x1e\xa1\x8f\x98\x4e\x16\x1d\xcd\xd1\xbd\xa3\x71\x34\xbf\x67\x35\xd2\xb2\x14\x9b\x48\x98\xda\xcb\xfd\xa6\x1e\x60\x02\xd7\x2a\x6f\xc5\xd2\x1f\x10\x98\x21\x32\x31\x13\x2d\x56\xdf\x68\xd6\xa9\xbf\xdf\x4e\xdd\xc0\x52\x4d\xb8\xfd\x8f\x24\x88\x52\x04\x9a\x68\x25\xa5\xed\xd2\x36\x0c\x00\x9a\xf2\x4f\x0a\x94\xc5\x07\x9d\xdf\x6f\xe7\x96\x94\x5f\xf9\x84\xaa\xc3\x64\x11\xce\x80\xd9\x87\xc6\xed\x67\xb6\xb0\xdd\xb6\xd4\x17\xf6\xe8\x09\x99\x1e\x72\x9d\x14\x7d\xd0\xd2\x1a\x09\x32\x41\x36\x3c\xf4\xef\x3b\x8e\x3b\xa0\x2d\x48\x66\x33\xb6\xb2\x17\xf5\x49\x3e\x2e\x43\x2b\x8c\x2e\x27\xd0\x0c\x5b\x56\xc9\xb6\x5f\x9a\xed\x49\xce\x93\xd7\x7e\x7d\x0b\xf5\xf9\x2f\x92\xf5\xbb\x4b\x59\x5d\x66\xf8\x87\xa4\x88\x01\x33\xf9\x70\x46\x3a\xb8\xb7\xf3\xd8\xc7\x94\xc0\x40\x6e\x88\xe3\xea\xb9\xae\x65\xf1\xa1\x85\xd6\xe3\x9e\x2d\xd6\xab\xb8\xa9\x3d\x2a\xc4\xb9\x20\x83\x98\xda\xb8\x9d\xbc\x07\xa4\x1a\x50\x26\x40\x26\x41\x2d\xa0\x22\xb5\x8f\x48\x9d\x4d\xba\x31\xfb\x88\x2f\xec\xb1\xff\x8c\xa1\x82\x0d\xda\x18\x65\xaf\x15\x51\xe4\x6c\xd6\x18\xb4\x4c\x4e\x6e\xb3\x03\x7a\x93\x33\xfd\xcc\xef\x4b\x89\x51\x89\xe4\x39\x0e\x93\x14\x5d\x26\x4c\xa5\xf4\x52\x02\xa3\xeb\x28\x53\x59\x3f\xee\xd6\xc6\x6d\xbb\x28\x8f\xf3\xa3\xc0\xfa\x83\x2b\x2a\xa7\xe5\x29\xb5\x56\x88\x97\xb3\x14\x94\x02\xa9\x07\xe7\x41\xe1\x01\x1c\xe0\x73\x1c\x91\x5f\x91\x44\x6a\xa0\xd5\xca\xf0\x59\x5f\x18\x16\x43\x4f\xa4\x57\x6d\xb3\xbc\x31\xe1\x0c\xc2\xaf\x33\xf6\x13\xf0\x3c\xa7\xb9\x49\x1a\x0a\x34\x05\x25\x27\x1a\xb5\x37\xf6\x2a\x11\xa8\x4d\xa0\x1c\x7f\x55\x81\xad\x57\x38\xc3\x72\xb5\x33\x5b\xab\x9b\x2b\x9d\xc2\xfe\x91\xe9\x33\x30\x4d\x94\x01\xba\x8e\x1c\xe8\xdc\x55\xc4\xfb\x46\x6b\x3a\x8e\xd7\xf5\x3a\x12\x2b\x83\x81\xd8\xf2\x90\x47\xd7\x26\x4d\x06\xfb\x51\xec\x3e\x70\x07\x1f\x27\x36\xa4\xe7\xe1\x53\x7a\x52\xfa\x25\x6a\x04\xee\x86\xfa\xd2\x7a\xd2\xd2\x8a\x9b\x36\x29"}, +{{0x39,0xf0,0x55,0x6b,0x1c,0x5d,0xca,0xb3,0x87,0x10,0x41,0x81,0xbb,0x30,0x4d,0xe0,0xcf,0x81,0x59,0x20,0xb9,0x72,0xe8,0x71,0xd5,0xf0,0xfb,0x41,0x6d,0x8e,0x61,0x6a,},{0xd8,0x5f,0xb7,0x6e,0x78,0xc3,0xd5,0xbb,0x7c,0xa6,0xb0,0x5b,0x31,0x01,0x91,0x82,0x1a,0x4a,0x7d,0x2d,0x9b,0xdf,0x02,0x29,0x2c,0xc7,0xae,0xa5,0x64,0x2e,0x48,0x19,},{0x01,0x66,0xaf,0xed,0x5a,0x8f,0x7c,0x3f,0x7a,0xd6,0xf3,0xfd,0xd2,0x93,0x8e,0xff,0x00,0x89,0x8e,0xab,0x81,0x5c,0x54,0x55,0xac,0x90,0xfb,0x51,0xf6,0xe1,0x85,0x4f,0x0c,0x07,0x53,0x19,0x4b,0x76,0x29,0x59,0x4c,0xc1,0x27,0x1b,0x00,0x34,0x31,0x22,0x1c,0x57,0x4b,0x0c,0x0d,0x19,0x08,0x2f,0xee,0xda,0x51,0xb0,0x84,0xae,0x5e,0x03,},"\xa8\xd0\x34\xe1\x70\xfc\x22\xb5\x7a\x44\xaa\x62\x69\xed\x1f\x01\xcb\xa8\x01\xf3\x98\xdf\x1a\xdf\xe7\xdf\x04\x4d\x5f\xa4\x68\xbb\xfa\x8a\xf4\x74\x9a\xb5\x0d\x24\xd6\x2e\x31\x3a\xc0\xe7\x3a\x64\xb4\x28\x2b\x74\x62\x6a\xf2\xb4\xa4\xb5\x4c\x27\x4e\x5a\x6b\xc2\x80\xb6\xdc\x25\xdc\xfe\x07\x81\x4c\x9c\x81\x6d\x2f\x9e\x36\xc0\x5b\x9b\xfe\xdf\xf7\xc6\xb0\x3c\xdd\xeb\xd4\x73\x5e\x09\x93\xd3\xc3\xfd\xc6\x54\x04\x43\xc6\x00\x5e\x90\x0b\x40\x35\xe1\x40\x8a\x85\x01\x6a\xa1\xb8\x92\x02\x99\x0e\x5d\x84\xed\x99\x81\xc2\x9b\x77\x20\x6d\x7c\x11\x30\x52\xa2\x02\x98\x12\xc6\xea\x13\xaa\xe8\xbe\x0a\xca\x7a\x33\x06\xbf\x61\x72\x42\x29\x8e\x68\xbe\xcd\x0d\x5d\x16\xc8\x88\x7f\xd1\x95\x0b\x77\x85\xa4\x6b\xb0\x22\xb3\x9f\x76\x07\xcd\x89\x13\x71\x8b\x30\x17\xfc\x3f\x86\xd6\x93\x3f\x75\xee\xc5\x19\x1a\xd1\xf1\x98\x9a\x8d\x26\x17\x86\xf5\x6b\xe4\xa9\x88\x37\x0d\xb8\x29\x61\xa9\xfc\xc9\x53\x54\x2e\x51\xc2\xe0\x86\xdb\x0e\x02\xb4\xfc\x34\x66\x94\xab\xd9\x05\x9d\x5b\x11\x72\x26\x47\x66\x9e\x7f\x17\xb7\x45\xa6\x0b\x02\xf7\x33\x9f\xcc\x99\xbc\x35\xd5\x9f\xd0\xb9\x8b\x60\xc3\x14\xab\xd4\xbf\x8a\xa4\xb7\xea\xe0\x9d\xd0\x09\x7a\xcb\x91\x89\xf0\x2c\xf8\x5a\x25\x1a\xc9\x2a\xaf\x69\x1b\x15\xcd\x4a\x33\xb5\x8d\x76\x63\xab\xd0\xb0\x44\x43\x33\x04\x4a\xf5\xce\x20\xfd\x71\xcb\xaf\xfc\x0d\x29\x83\x58\x19\xf4\x92\x93\xfc\x26\xe7\xf9\x78\x7f\xc3\x68\xc4\xd3\x5c\xae\x92\x74\x7f\x21\xca\x1f\x3e\xfd\x87\xa0\xd8\x10\x41\x99\x41\x64\x82\xd0\x7b\xfe\xc1\x28\x1c\x66\xf5\x65\x28\x5b\xf6\x72\xd5\xe7\x48\x64\x00\x66\x0c\x01\x75\x55\xe9\xfa\x2b\xf6\xa4\xe7\x02\x7f\x0e\x7e\x5f\x44\x3e\xd6\x58\xb7\x5b\x59\x06\x12\xab\xde\x0d\x80\xd1\xa2\x6c\xb8\xbd\xe7\x6b\x99\x6e\xff\x6a\x74\xe3\xda\xfc\x59\xeb\x1b\x58\x4f\x45\x97\xa2\x39\xcd\x83\x9f\xa1\xf1\xb7\xbd\xa1\xa2\x4d\x15\x0c\x4e\x24\xb9\x1c\xec\x01\xee\x53\xa3\xac\x85\x2a\x91\x2d\xe1\x95\xa3\xc2\x9d\xd7\x07\x9a\xa7\xe8\x8a\xa8\x1e\x9d\x31\xb8\xfc\xcd\x43\x5e\xda\x11\x3c\x3f\x82\x45\x8b\x7f\x79\x33\x57\x2b\x77\x67\x53\xc9\x22\x40\xcc\x03\x61\x58\xa4\xba\x0e\x56\xef\xed\x53\xec\xb5\x3f\xc0\x93\xfe\xad\x14\x34\x34\x85\xae\x5d\x91\x05\xbb\x16\x3f\x26\x25\x14\xe4\x8b\xe7\x41\x59\xc9\xfa\xbc\xb7\x1d\x1a\x42\x80\xd9\xed\x70\xd7\xe4\x2b\x75\xf7\xfd\xad\xd0\x2d\x69\x19\x8f\x5f\x46\x5b\xf6\x04\xcb\x42\x54\x41\x7b\xac\x37\x14\xb3\xa9\x9e\x6f\x1a\xce\xc9\xe3\xb3\xd0\x97\xf9\x72\xfb\xc3\x6f\x2e\xda\x39\x26\xd5\x61\x12\xd4\xe9\x09\x7d\x89\xbd\xc3\x59\x37\xb9\xa3\x15\x8e\x7c\xdd\x5d\xa4\x01\xe1\x80\xd3\xed\xe6\xb1\xff\x02\x86\x41\x92\xeb\x72\x97\x81\x53\x4f\x49\x64\xdd\xf2\xaf\x11\x80\x0d\x8b\x5b\x6d\x01\xb2\x09\xaa\x33\x69\x36\x6c\x19\xa2\x8c\x79\xa8\x7d\x21\x74\xec\x22\xfb\x14\x89\xa6\x75\x5c\x34\x8a\x99\x6d\x0a\xa5\x6e\x0f\x60\xd5\x8e\x26\xbe\xfa\x23\xa8\x6b\xef\x4e\x35\x29\x51\x2e\x30\xa9\xd1\xc5\xe4\x88\x50\x18\xcb\x97\xae\xb7\xc9\x3c\x5c\x41\xca\xa3\x42\x36\x57\x5c\x22\x6f\x3b\x23\x5e\xdd\xba\x36\x4e\x28\x5b\x6e\x35\x27\x07\xbb\xb3\xb3\x39\xbb\xf2\xa6\x3a\x9c\xb9\xbd\x33\x3a\x77\xe7\x9b\xd5\x8a\x48\xe1\x4c\xe5\x88\x6e\xd0\xcd\x07\xc2\xd1\x65\xa8\x1b\x5e\x6a\x31\xa8\xae\x78\x06\xbc\xf2\xe0\xc4\xec\x29\xa9\x67\x72\x5e\x57\x7f\x17\x41\xee\x68\xf3\x45\xf5\xf7\xab\x0f\xad\x31\xc8\xb4\xb1\x8b\x43\x1c\x49\x77\xd5\xc5\x84\x00\x4b\x45\xf7\xcd\x19\x61\xaf\xfe\x87\x38\xe2\x4c\x38\x26\x10\xef\xe9\x98\x35\x3d\x7e\xba\xf9\x19\xb2\x79\xbb\xb6\x91\xc3\x05\x2b\x8b\x2c\x5f\x09\x80\x8e\xf3\xa6"}, +{{0xba,0xb3,0xff,0x7a,0x44,0x48,0xd8,0xa0,0x3d,0x8a,0xcf,0xdb,0x91,0x3f,0x77,0xfe,0x77,0x80,0x43,0x95,0xc3,0xe5,0x4e,0xc2,0x35,0x11,0x79,0x27,0xe3,0x2b,0x50,0xd5,},{0x54,0x97,0x5e,0x35,0xe5,0xb1,0xd0,0x32,0x3f,0x2d,0x6f,0xb5,0xc6,0x15,0x8b,0xf6,0x65,0x4b,0x08,0x4f,0x76,0xbb,0xdc,0xfd,0x72,0x34,0x92,0x29,0xe8,0xe4,0xa6,0xe8,},{0xd6,0xb4,0x13,0x5f,0xc7,0xac,0xb3,0xd7,0xcd,0xf9,0x87,0x89,0x6d,0x91,0xb8,0xa9,0x0d,0xb5,0x84,0xd8,0x93,0x3a,0x6f,0x30,0x29,0xe3,0x26,0x1e,0xc1,0xc3,0x90,0xcb,0xac,0xfa,0xaf,0xef,0xf4,0x43,0xb6,0xda,0x4f,0xdb,0x1d,0x84,0xc6,0x4a,0x54,0x56,0x0f,0xef,0xfa,0x2f,0x1c,0x7a,0x91,0xbd,0xe9,0x73,0x02,0x22,0x92,0x3b,0x67,0x03,},"\xb6\x47\xb6\x7c\xf0\x1c\x2c\xac\xc3\x9d\xe5\x96\x9e\x19\x9b\xe6\xd9\x32\x01\x67\xa4\xce\xbb\xf1\x62\x59\x50\xb1\xe6\xb7\xad\xf5\xca\x24\xd1\x34\x95\x68\x86\x5f\xbb\xfd\x90\xf5\x13\xf0\x5f\x79\xf7\x0a\x63\xa2\x38\x73\xdc\x7a\x19\x5d\x4b\x28\x5a\x08\xf3\x0e\xe0\x61\xd0\xb8\xe6\xb4\xd6\xbf\x9b\x2e\xcf\x2c\x69\xf3\xd5\xa0\x7a\x67\x30\x53\x7c\xca\x4a\x4e\x4c\x7e\xe6\x84\x70\x2b\xff\x88\x3f\xab\x8b\xca\xf8\x93\x11\xc5\x49\x8b\xcc\xb5\xa0\xf7\xc8\xd4\x9b\x54\xf4\x82\xff\xfb\xca\x6e\x7d\xa2\x62\x45\x2b\xa5\x9a\x57\xa6\x87\x9d\x81\xb7\x3c\xd7\xad\xf7\x2a\x3b\xe2\x8a\x37\x3c\xd6\x33\x10\x40\x84\x61\xc2\x1b\x90\x7f\x63\xe0\x86\xb2\x92\xff\x02\x83\x3e\x8a\x2f\x46\xad\xbd\x67\x1d\x02\xb0\x3a\x69\xac\xa2\xe1\x1d\x28\x7c\x52\x2a\x95\x45\x20\x44\x2e\xce\xfa\xa9\x05\xdb\xfc\xc8\x25\x4c\x58\xc3\x95\x4a\x89\xbf\x56\xcb\xe0\x1a\xd5\x63\x19\x71\xeb\x39\xeb\x43\x2a\x85\x4e\x69\x19\x29\xdf\x7e\x48\xb9\x00\xca\x6e\x74\x0a\xcc\xf5\x78\xb3\x17\x95\xb4\x9a\x6c\xa7\x74\xbd\x8b\x99\x31\x06\xa9\xc4\x94\x8c\x18\x71\x49\x48\x31\x59\x90\xa5\xf1\x91\x69\x24\x20\xf2\x89\x32\x8a\xb7\x13\xec\x19\xb7\xea\x89\x4d\x16\xe6\x47\x61\x00\x87\x1c\xf3\x16\x8e\x4f\x93\x5b\x55\x05\xd1\xed\x5b\x0a\xa2\x9b\xe3\x6f\xa3\xa3\x46\xac\x3e\x76\xf1\x43\xc4\x6c\xa6\x91\x23\xb7\x9c\x36\x39\x9a\x0d\x2e\xd3\x02\x77\x24\x94\xad\xf4\x42\xbb\xaf\xbc\x4d\x01\x53\x26\x92\xc7\x85\x9d\xf0\x4d\x2c\xa7\x8b\xa5\x5d\x77\xfd\xf3\xe5\xad\x99\x37\x86\xa2\x4c\xff\x21\x99\xbb\x49\x38\x78\x73\xcc\x41\x4b\x4c\xf1\x13\x7a\xbb\x7e\x94\xae\x3d\xdb\xf9\x7f\x53\x4a\x18\xfc\x5a\xe5\x85\x23\xa3\xcc\x52\x28\x3d\xc7\xb0\x16\xf3\x1c\xd6\x55\x79\x81\xc5\x07\x6c\x77\x4f\x30\x3a\x47\xc4\x27\x87\x0e\x20\x7e\xd8\xbd\x66\x64\x0f\xf0\x92\xdb\x50\x3f\xa1\x24\xbf\xdc\xf0\x20\x05\x1d\xad\xd1\x06\xdd\x24\x58\x40\xb3\x19\x10\xb8\xa9\x06\x0d\x59\x86\xf0\x2b\x60\xaa\x5e\x33\xb4\xd7\x55\x09\x12\xcd\xc5\x77\x6c\x77\x2a\xac\x93\xae\x19\xc7\x3b\x7e\xcf\xca\x38\x9e\x62\x76\x81\xa8\x78\x1e\xb4\x7d\x84\xe9\x34\x60\xba\x89\x1d\x3f\xf6\xea\xdf\x8f\x2a\x90\x3c\x38\x34\x74\xbe\xaa\x42\xb9\x0e\x03\x22\x36\xdc\xd8\x98\xd0\x2a\x40\xef\xb4\x4e\x47\xea\xd5\x2b\x75\xb0\x9c\x7d\xa1\xcd\x6a\x2d\xfd\x4d\x1c\x04\x52\xde\x69\xf6\xac\xac\x1a\x68\xdd\x78\xda\xf9\x72\xae\x26\x08\x21\xe2\xec\x52\x2f\xb5\x74\x9b\xeb\xe0\xad\xb4\x52\xbf\xa4\xfa\xa1\xe9\x79\x11\xc1\x29\x9f\x16\x56\x8d\x68\xee\xf4\x05\xf4\xb1\xcd\xac\xab\xed\x59\xf7\xb0\xfb\xce\xab\x71\x9a\x34\xb2\x99\xf5\x8a\x4a\xe8\x15\x4f\x98\xf4\xd9\xf4\xf1\x40\xb1\xf0\x85\x00\x69\x46\x72\x5e\x7c\x29\xbb\x0b\xc6\xcc\xf2\x53\x44\x97\xc6\x1d\x4c\x16\x12\x62\x4a\x61\xd7\x0d\x26\xc3\xef\xb7\xd7\xc3\x51\x84\x86\x57\xf7\xf8\xee\xbf\x8b\x99\x07\x47\x74\x0e\x6f\x91\x0c\x97\xce\xf1\x50\x37\x57\x65\xc8\xc0\xb3\xb4\x49\xc0\xd0\x9d\x66\xf0\x08\xe6\x7c\xfa\x76\xea\x2b\x68\x08\xb6\xfe\x63\x2e\xaf\xe0\x58\x7f\x37\xe3\x6b\xe9\x8d\xcb\x17\xa3\xf4\xa1\x5b\x65\xa9\xf6\xfc\xf9\x64\x2b\x52\x52\x20\x77\xb1\xfb\x4c\xc3\xc0\x8d\xf4\xb4\x67\xca\x71\x6d\xb1\x6b\x73\x7f\x78\x2c\xdf\x38\x71\x70\xa5\xf1\xf6\xa7\xae\x0a\xb3\xf5\xb7\xc5\x85\xe3\xb0\x65\x5a\x64\x56\xa5\x03\x59\x5c\xe8\xea\xea\x25\x37\x85\x5e\x7f\x0d\x50\x61\xbc\x29\xb4\xe6\x7d\xaa\x82\x46\x3c\x19\x0e\x9f\xdd\xd5\x2f\x83\x22\xdd\xb4\xe0\xf2\x6b\x68\x77\x82\x28\xeb\x57\xe1\xa1\x85\xb7\x02\x5d\xa1\x49\x87\xd4\x4b\xaa\x76\x7b\x22\xee\x7f\x4c\x84\x59\x10\x32\xe8\x8e\xc1\x2e\xb8\xc5\xa4\xb9\xe1\x57\xec"}, +{{0x48,0x6c,0x7b,0x43,0x6c,0x1d,0x43,0xd6,0xb7,0x03,0x51,0x22,0x83,0xc1,0x66,0xdc,0x86,0x3e,0x5a,0x33,0x80,0x2f,0x4e,0xa6,0x5f,0xc7,0x38,0x77,0x89,0x02,0xd0,0x14,},{0xb5,0xdc,0x94,0x7d,0x64,0x33,0x7c,0xae,0x82,0x12,0x2b,0xd6,0x8c,0xc8,0x08,0x40,0x59,0x6d,0xe3,0xbe,0x56,0xcb,0xd0,0xc8,0x33,0xaf,0x3f,0xaa,0x3a,0xdc,0x37,0x76,},{0x31,0xf9,0x5c,0xbb,0x74,0x63,0xb8,0x75,0x28,0x65,0x42,0x27,0xbb,0x13,0x97,0xbf,0x10,0x65,0xb4,0xf5,0x76,0x80,0x80,0x78,0x20,0x7d,0xfa,0xf0,0x6d,0x12,0x4b,0x41,0xf4,0xc3,0x18,0xf4,0xa9,0x31,0x5a,0x66,0x08,0x5b,0x9e,0x56,0x8a,0x71,0xe4,0x14,0xed,0x94,0x14,0x51,0x73,0x10,0xc6,0x99,0x94,0x6d,0xb0,0xc9,0x76,0x28,0x52,0x07,},"\xaf\x03\x60\x53\x67\x2d\xcf\x3a\xa2\x6e\x28\xec\x6a\xa6\x42\xce\x28\x4b\x89\x6c\x69\x88\x7d\xfd\xcf\x08\x24\x51\x5e\xb0\x84\x8d\x9d\x97\x0c\xa2\x72\xdf\x77\xa8\x6b\x3f\xf6\xdd\xaf\x3c\xba\xdd\x3a\xb6\x28\x3b\xc3\x7c\xdf\x7a\x56\x07\xd5\xdf\xc7\xcf\x96\x32\x92\x99\xcc\x53\xed\xbb\xe6\x57\xfd\xfa\x2c\xa2\x44\x67\x05\x0a\x0a\xeb\x8c\xff\xd7\xd3\x3d\x54\x3e\xc2\xc1\x91\xcc\x0b\xce\x89\xac\x37\xd3\x32\x93\xb1\x88\x8c\xcb\x76\xc2\x8a\xdc\x67\x1a\x49\x35\xa8\x46\xd9\x07\xe4\xad\xd0\x11\x0f\xeb\xbe\xe5\xae\xc8\x0f\x9d\x2f\xf7\x4e\x2a\xf4\xfd\xbe\xbb\xcf\x49\x10\x5a\x64\x69\xd7\x38\x00\x06\xb2\xca\x44\x36\x48\x14\x45\x4e\x44\x5e\x36\xdc\x00\x12\xf3\x39\xc9\x68\x54\xf8\x36\x44\x2a\x05\xa5\x0b\xec\x90\x73\x27\xf7\x4b\xa9\xf6\xfd\x79\x0f\xf0\xad\x37\x83\xd2\x97\xbd\xcc\xa7\x64\x60\x78\x37\x03\xeb\x5f\x2b\x1f\x51\xb0\xa7\x40\xce\x7a\x8f\x00\xa3\x87\xe3\x63\x62\x70\xa9\x71\xfa\x8f\x15\xb4\x49\x67\x30\xd8\x8a\xdd\x80\x7a\x7f\x7e\x98\x7c\xd4\x15\x95\xa2\xe7\x43\x5d\xf5\x19\x55\x76\xa3\x5f\x5e\x91\xb2\xfc\xfa\xc9\x4e\xd5\xd7\x76\x63\x78\x3b\x61\xe6\x67\x1d\x34\x83\x8b\x6b\x56\x44\xfb\xc1\xc5\x39\xfe\x15\x9b\x77\x92\xdb\x96\x7e\x83\x52\x61\x8d\xda\xca\x0c\xde\x73\x43\x7b\x59\xe7\x80\x1b\x49\xeb\x46\x09\xb1\x05\x77\xca\x26\x92\xdd\x6f\x9d\x5e\x9d\x4b\x5e\x5e\x62\xc5\x91\x3e\x7b\x87\xe6\xb3\x47\xbe\x61\x53\xb1\x71\x99\xc9\x16\xa1\x3f\x8a\x88\x5b\x37\x8e\xf0\x9e\x13\xca\xe4\xd8\xb0\x79\xd7\xd5\xcb\x90\x94\x19\x9b\x0f\x20\x53\x3c\x90\x08\x3b\xc3\xac\xb2\x66\x76\x97\xee\xd2\x2e\x36\x70\xab\xb4\xa5\x53\xe9\x95\xc9\xdd\x95\x94\xe5\x92\x39\x1a\x00\x04\xb6\x55\x65\x44\xf3\x56\x12\xc4\x97\x13\x59\x57\x7c\x47\x63\x82\xca\x53\xb3\xf2\x62\xa5\xe3\x3e\xd2\x6e\xec\x80\x9f\x4f\xdb\xa4\x89\x8a\x11\x36\x75\xcb\x6a\xf7\x17\xdb\x62\x57\x9f\x39\x80\xb2\x14\x63\xbe\x02\x9c\xb4\x16\x0f\xe5\xd2\x57\xc4\x6c\xd6\x66\x4f\x98\x61\xac\x50\xfe\x05\xc1\x44\x05\x7d\xce\x2f\x8d\xf1\x53\x2a\xa7\xaf\x58\x9f\x41\x27\x06\x01\xce\xf0\x6b\xbe\x4f\x35\xc3\x1c\x78\x2b\xb3\xcf\xff\x7d\x5a\xb6\x4a\x14\xec\x41\x73\x61\xf1\xd3\x2c\xbd\x38\xb6\xbd\x0e\x02\x50\x5d\x14\x16\x30\x2b\x85\x05\xae\x2a\x96\xe8\xd5\x33\x9c\x34\x6c\x2b\x06\x62\xd3\x50\x25\x9c\x50\xc5\xe4\x87\x95\x91\x4e\x6f\x88\xe9\x7c\x81\x1c\x39\x3b\xdf\x9a\xec\x7e\xf8\x20\x47\xca\x28\xee\x97\x1c\x17\x5c\x27\xe3\x6e\x10\x97\x27\x96\x0d\xdf\x1a\x1b\x97\x6a\xb4\x4f\x48\x51\x60\x7b\xd9\x66\x80\x8a\xc4\x6d\x54\x00\x31\x28\x29\x7f\x5f\x44\x87\x10\x8d\x6a\x02\xe7\xa1\x64\x13\xd2\xb7\x5e\xcb\x42\xfd\xdf\xb6\x69\xc8\x01\xd2\x3d\xe5\x0a\x6f\x7b\xf6\x58\xf7\x53\xc6\xb2\xb3\xb4\x7c\x06\x40\x10\x5d\x0a\x80\x1b\x32\xa1\x94\x3c\xdc\x15\xc8\x86\x55\x5e\xb7\x5b\xb7\x92\x7b\x93\xc3\x5c\x5b\xe1\xf9\x8b\x19\x6c\xaa\xc2\xda\xd9\x91\xb1\x04\x4e\xa8\x63\x94\x4d\x54\xd8\x83\xab\xc3\xc6\xde\x66\xed\x86\x8e\xe8\x4b\xcf\x9c\x34\xcc\xdb\x80\xfc\xd9\xcc\x04\x02\x74\x77\x32\xcd\x63\x0b\xbf\xa3\xbb\xe8\xb0\x38\xdc\x1d\xbd\xaf\x43\x6d\x9a\xc0\x0c\x02\xd5\x28\xec\xe2\xe7\x91\xee\x31\x2a\x86\x8f\xeb\x2f\x58\x7c\xa4\x4d\xb5\x73\x13\x84\xfa\x18\x31\x14\x20\x61\xb2\xea\xd2\xb8\x0c\x66\xbd\x2f\xa5\xdc\xca\xbe\x6a\x25\xf2\xa4\x93\xfe\xaa\xcd\x23\x1d\x2f\x40\x96\x46\xb9\x42\xa5\x78\x54\x5e\xa4\xfe\xea\x9a\x73\x47\x3f\x79\xdc\xf1\x3e\x0c\x9f\x1b\x49\xfd\x89\x12\xec\x48\x73\x28\x04\x5b\xd0\xfa\x22\x89\x22\xee\x6e\x97\x3e\x61\xf6\xe9\x33\x65\x29\x65\x78\xdc\xc2\x1c\x36\x14\x79\xee\x2d\x24\x87\x9f\x2e\x9b"}, +{{0xa6,0xe6,0xad,0x2c,0x37,0x9c,0x6f,0xcc,0xad,0xb4,0xa4,0x9b,0x23,0x2a,0x91,0x42,0x61,0x8e,0xa3,0x01,0x03,0xc3,0x3c,0x22,0x6f,0xf6,0x28,0xbc,0xfd,0x81,0xf4,0x26,},{0xf7,0xc4,0x32,0x3f,0x5c,0x41,0x9d,0x9b,0x3f,0x34,0xa8,0xeb,0x42,0xae,0x7f,0x1f,0xaa,0x23,0x33,0x07,0x90,0x30,0xc5,0xd6,0x4f,0x9f,0xfb,0x1e,0x9b,0x16,0x00,0x2d,},{0x07,0xd9,0xfc,0x24,0x4f,0xda,0xb0,0x01,0x59,0xeb,0xec,0xc5,0xa0,0x08,0x83,0x45,0x3f,0x08,0x31,0x01,0x71,0x76,0x9d,0x29,0x70,0x01,0xe8,0x77,0x01,0x0e,0x3e,0xce,0xd9,0xfb,0x60,0xec,0x91,0xcb,0x4d,0x88,0xe7,0xba,0x40,0xc5,0x30,0xb1,0xf9,0x23,0x79,0x78,0xcc,0xd9,0x6d,0x5c,0xba,0x9e,0x4f,0xa2,0x7e,0x2a,0x0a,0xd9,0xd6,0x0c,},"\x2e\x85\x76\x76\xa5\xbb\x1c\x6e\x9e\x94\x50\x7f\x83\xc6\x0a\x67\xf5\x47\xc5\xde\x9e\x94\x56\x6b\x19\x7a\x6a\xf6\xcf\x47\x52\xe9\x3d\xbd\xef\x6b\x9f\x66\xd1\xfe\xbd\x95\x7e\x42\xa7\xf5\xad\x64\xef\x1d\xbc\xc4\xfe\x69\xae\x95\x25\xd1\xa4\xde\x67\x05\x4c\x88\xf2\x9c\x06\x47\xba\xcf\x8b\x82\xf3\x21\xff\x99\xfe\x9e\xed\xc9\x92\xed\x34\xc1\x17\x7f\xc5\x42\x12\x27\xcc\xac\x10\xfe\xb9\xce\xd4\x08\x2f\x56\x58\xda\x63\x71\x47\x23\x97\x97\x37\xe7\xdc\xbf\xe2\xe8\xb5\xd5\x0f\x91\xdf\xca\x83\xe7\xf9\x5f\x35\xd1\xad\x8d\xd5\x11\x44\x50\x2f\x3d\xf6\x72\x43\x26\x11\xf0\xe7\x66\xa9\x0d\xcc\x2a\x57\x39\xc8\x05\xd9\x5f\xe5\xb0\x41\xde\x9d\x7f\xb4\x7b\x44\x04\xaf\xc8\x03\xa3\xbd\x48\x04\xc7\x81\x7e\xbc\x5b\xdf\xef\x8a\xdd\x9e\x25\x0b\x50\x96\x6c\xa8\x93\x9b\x22\xb3\xc6\xff\x93\x6e\xaa\x65\x9a\x24\x0c\x0c\x84\x8b\x81\x0a\xce\xcf\x61\x81\xe0\xe4\xdb\x8e\x4c\xf8\xfc\xce\x7d\xe5\x59\xcb\xe8\xaf\xa9\xdb\x84\x99\x57\x09\x11\xa3\x88\x7e\x85\x0e\x50\x9c\xdb\x70\xde\xbc\x34\x77\xd1\x21\x75\x01\x4f\x79\xf8\x1b\xa1\x13\xd0\xb7\xb3\x35\x11\x8f\x85\xcf\x59\x99\x6f\x80\x67\x58\xeb\x90\x3c\xc4\x50\xf5\x2f\xee\x10\x2e\xfc\x01\x44\x1e\x9a\xe5\xfa\xe7\x4c\x23\x1d\xfd\x85\xeb\x6b\xad\x17\xd6\xb7\x0e\x93\x85\x84\xfa\xcb\x21\x72\xcb\x03\xbd\x5e\xa0\x7b\x7f\x0d\x37\x1f\xfa\x35\x1c\x0e\xe4\xef\xe9\xba\x4a\x3f\xd5\x43\x87\x46\x55\xe7\xd3\x9c\x53\xae\x86\x32\x98\x02\xe5\xc3\x85\xe9\x28\x3a\x29\x73\xca\xb8\xcf\x7a\xc7\xff\x0f\x91\xd1\xd4\x8b\x58\xab\xfd\xad\x65\x8d\x81\x2f\x07\x88\x16\x76\xbd\x22\x6b\xfe\x95\x7d\x7d\xf3\x0c\x41\x30\xa4\x48\x35\x4a\x6b\x94\x40\x5a\x41\x16\x50\xa9\xc8\xfc\x85\x11\x55\xec\x5a\x8a\x3e\x3b\x67\xae\x0c\x4b\x5c\xb8\x9b\xb7\x3f\xc8\x29\x74\xbe\x62\xda\x73\xf0\xe2\x30\x92\x93\x7d\x40\x5b\xa4\xaf\x6c\xab\x94\x65\xea\x43\xa6\x25\x3f\x44\x57\x08\x2a\x06\xac\x12\xb7\x5e\x88\xec\x68\x44\x87\xf9\x07\x63\x73\xfa\xb8\x89\x28\x59\xd8\xe8\xba\x43\x14\x23\xaa\x80\x5a\x22\x0c\xbf\xda\x43\x1b\x32\xb1\xe0\x31\x21\xf7\xfd\x4d\xe1\x85\x91\xf2\x50\x5c\xc0\xf5\xb2\xb1\xa7\x60\x5f\xbc\xc6\x37\x57\xb0\x7e\x29\x9f\xef\x5a\x2b\x73\x65\x23\x0c\x2e\x92\xa2\x59\x62\xc2\xe8\x01\x2a\xd3\xfa\x9e\xe9\x48\x82\x70\x96\x25\xba\x68\xc7\xb2\x13\x66\x4a\xe2\x53\x2b\x60\x9d\x7c\x9a\xa0\xe8\x3d\x49\x3d\xbc\xe7\x63\x2f\x35\x58\x0e\x06\xd3\x11\x1c\xed\x32\x0d\xd0\x19\x04\x41\xf6\x2d\x9e\x35\xf5\x0d\xe5\x9c\x27\x2f\xb0\x0f\x56\x8a\x00\xb0\x74\x6c\x33\xa9\xbd\x24\x90\xc0\x74\xb9\x1c\xdd\xc4\x87\xef\x2e\x45\xa0\xf0\x30\xe0\x8f\xdc\x18\x17\xbc\xa8\xa9\xce\x29\xd2\x92\x79\xe7\x55\xde\xbc\x28\xdf\xad\xc3\xc4\xd1\xb4\x58\x48\x6e\x3c\x8d\x0c\x43\x18\xe7\xe6\xf9\xeb\x5a\x36\x53\xb3\xf7\xc4\x95\x07\x07\x7c\xd5\xeb\x81\xf1\x0b\x88\x10\x7c\xc0\xf9\x31\x69\x32\xab\xe9\xb6\x4e\x88\x86\xd0\x68\x56\xa8\x5b\xe6\x3b\x0c\x2b\x47\x5c\x0a\xfc\xb0\x69\x44\x26\x86\x0f\xb2\x4b\x5c\x17\xab\x6a\xb7\x73\x3d\x5e\x64\x1b\xe7\x4f\xd5\xf6\xa1\xff\x18\xd2\xf9\xa4\x27\x70\xfb\x30\x75\x0f\x56\xf4\x85\x4e\x38\xd5\x8a\xef\x18\xa2\xa6\x1c\xbf\xb4\x9e\xe5\x76\xed\x97\x73\x7b\xc2\x8d\xf3\x26\x8a\x33\x41\x75\x51\x3d\x97\xaf\x00\x9c\xbb\xcf\xdf\xad\x50\x39\xd6\x9b\xb4\x6f\x70\x88\x67\xd9\xb3\xce\x0b\xf2\xf5\x69\xe3\xcf\xbc\xf6\x13\x6f\x88\x70\xd2\x52\x08\xb2\x1a\x3e\xdc\xb7\x33\x93\xdf\xcd\x41\x72\xc1\x40\x2c\x41\xf3\x6e\x3f\x82\xa4\xea\x6d\xcd\x89\x16\x86\xba\x66\xe1\x43\x20\xaa\x0e\x22\xba\x0c\x1e\xf0\x33\xd6\x62\xcd\xb8\x60\xcd\xfa\x3a\x40\xf6\xcc\x53\x2a\x08"}, +{{0x9b,0x6d,0x7e,0x28,0xeb,0x05,0x15,0x97,0x32,0x4d,0xce,0xb7,0xa1,0x89,0x41,0x24,0x67,0x25,0xe8,0x8d,0x53,0xab,0x2c,0x34,0x77,0x11,0x05,0x33,0x0c,0xf1,0xf4,0xae,},{0x88,0x72,0xa5,0x0b,0x5f,0xe3,0x62,0xf8,0xea,0xd1,0xd4,0x0e,0x20,0x45,0xf0,0xd4,0x0b,0x2e,0x7b,0x50,0xb5,0x9d,0x80,0x90,0xbc,0x47,0xad,0x68,0xeb,0xee,0x09,0xed,},{0xc6,0xdc,0x5c,0xa1,0xe8,0x56,0x00,0x15,0xb4,0x93,0xaf,0xe2,0x66,0x6c,0xcf,0x6f,0xef,0xa8,0x03,0xd8,0x52,0x6c,0x83,0x7f,0xe7,0xf1,0x23,0xc7,0x99,0x14,0x27,0xab,0x03,0x0d,0x7c,0x77,0x0e,0x45,0xf6,0xde,0x84,0x81,0x52,0x3b,0x94,0xec,0xe9,0x7f,0x3f,0x16,0x1c,0xf5,0xb8,0xc7,0xae,0xa3,0x9f,0x5a,0xd8,0x26,0xbf,0x8d,0x0a,0x02,},"\xd1\xe1\x98\x7b\xff\x65\xf6\x2a\xd6\x76\x24\xc6\x65\x79\x24\xf5\xd6\x73\xb7\x82\x4e\xbe\x40\x40\x26\xc0\x56\x2d\xed\x31\x43\x44\x0b\xe6\x37\xf9\x8c\x9e\x01\xa6\xaf\xdf\xa9\xa4\x7d\xd4\x9c\x7c\xba\x6e\x3f\xd2\x3e\x45\x52\xf7\x63\x2b\x14\x38\x0b\x27\xcd\x3e\x96\x06\xcc\xe3\x50\xf1\x52\xab\x12\x6b\xea\xd0\xa5\xd3\xbc\xe4\xd4\x20\x92\xd9\x34\xc8\xca\x33\x7e\x98\x7e\x11\xd8\x6c\xfb\xfb\xd2\xac\xc3\x22\x3b\xd1\x67\x44\xa9\x27\x72\x8f\x48\x53\x72\x17\x5c\xc6\x94\xdf\x30\xa7\x3f\x9d\x33\x76\x5f\xf0\x14\xef\x00\x8d\x58\x63\x21\x03\x38\xcc\x34\x82\xcc\x27\xea\x31\x7e\xec\x92\x1b\x0c\x56\x8c\x38\xab\x27\xc4\xa5\x64\xe8\x02\xb1\xb9\x46\x68\xc6\x51\xe2\x0a\x0b\x55\xf3\xa7\x9d\x21\x5f\xc3\xa0\xd0\x49\x04\x01\x09\x32\xc4\xcc\x68\xc2\xa9\xe7\xd0\x0e\x5d\x38\xd8\x2d\xf5\x52\x06\xba\xb9\x5c\xf6\x97\xbe\xbc\x72\x06\xee\xde\xf6\xfd\x18\xd9\xa2\x0c\x2c\xbb\x28\x5b\x00\xef\xa7\x69\xa0\x8d\xab\x2b\x3a\xba\xdf\x00\xd1\x98\xb4\xf1\x92\xdd\x44\xbc\xb9\x14\x31\x82\x3a\xe6\xfd\xf9\x84\x58\xec\xa3\x9c\xd2\x92\x63\xf0\x99\x93\x03\xe7\x0d\xc6\x94\xfe\x01\xc5\x3a\x11\xc1\xd1\xc3\x4c\x1e\xe5\x06\x8a\x20\x1d\xbe\x7e\x10\x08\xd7\x64\x35\x89\x68\xb4\x02\xaa\x39\x85\x49\x50\x7f\x7b\xd1\x85\x08\x00\xe4\x11\xb1\xc4\xe2\x8d\xdc\x04\xa8\x59\xe1\x79\xbe\x8a\xd7\xe6\x67\x0e\x50\x9d\xb0\x27\xad\x7e\x51\x7e\x44\x25\x95\x4f\x5a\x80\x74\x14\xa6\xda\x26\x7a\x76\x4e\x71\x2a\x99\x84\x65\x06\x49\x82\xd8\x51\xa2\x65\xea\x3c\x4d\xfb\x74\xf9\x92\xa7\xcc\xcd\x9a\x82\x68\x7f\xa6\x1c\x32\x2c\x4f\x58\x9e\x86\xb8\x82\x52\x13\xbf\xa9\x51\xda\xe6\xaf\x35\x4a\xce\x18\xf0\x73\x99\x5a\xdc\x95\x83\x9d\xac\x01\x65\x51\x1d\x61\x75\x37\x91\xa5\x3e\x48\xe3\xa8\x27\x3d\x44\x82\x3d\x25\x96\xf2\xa2\xdb\x2e\x5f\x1a\xe5\x97\x22\x1b\xa7\xf3\xeb\xaf\x4a\x7b\x28\x88\x39\x50\x02\xbd\xaf\xf5\x1f\xa5\x4b\xfb\x97\x9d\xe1\x03\x14\x04\xca\x77\x89\xfe\x09\x5d\x4d\x17\xf0\x7a\x35\x55\x6b\x10\xfe\x8e\x14\x17\xc8\xa6\xa6\x31\xc2\xed\x36\xcb\x7a\x0e\x61\x81\x77\x62\x89\xc3\x44\x81\x4d\x42\x13\x1a\x73\xb1\x2f\xaa\x35\xd7\x78\x14\xc6\x81\xa6\x01\x37\x4b\xa7\x1c\xb9\xad\x53\x15\xfa\xd4\x2d\x3a\xcf\xc7\xc1\xd6\x28\x81\x02\x56\xda\xf7\xd8\xc3\xc9\xa2\xe5\xbd\xcf\xb7\x70\x08\x2f\xa6\x38\x16\x89\x58\x52\x3a\x1c\x3b\x03\x5d\xbc\x6d\x5a\xdf\x26\xdf\x89\xa7\xcc\xab\xed\x3e\x7d\xd3\x77\xc1\x6d\xa8\x41\xf1\x3c\x68\x94\xd4\x3c\xeb\xb4\xe3\x90\x22\xf1\xcc\xec\x22\x74\x44\x5c\x78\xb3\xad\xc7\xbb\xf7\x0d\x89\x0b\x80\x23\x6c\xc4\x46\x8f\x95\x69\xc5\x9a\x7e\x33\xb5\x70\xe6\x70\x38\x0d\x24\x4e\x4e\x31\x0e\x11\xc3\x92\xf1\xe3\x34\x05\x4b\x92\xc8\x38\x6c\x16\x1c\xe0\x41\x09\xb0\x37\xbd\x62\x8d\x91\x9d\xcb\x62\xda\x14\x35\xbf\x94\xe8\x8b\x0a\x88\x46\xd4\x86\xd1\x67\x78\xf7\xa3\xb8\x80\xe6\x60\xf4\x41\xfd\xf8\x6e\x56\xb8\xaa\x06\x61\xf5\x5a\xae\xce\x27\xf9\xdd\xaa\x0e\x2a\x22\xc2\x15\xb0\x40\x53\x97\x26\xb9\x85\x39\x15\xa1\x59\x2d\xff\xea\xe3\x2d\x7b\x5b\x67\xeb\x62\x05\xbb\x0b\xd7\x27\x9f\x78\x8d\x5f\x83\x3c\x40\x66\x78\x0c\xa0\xa4\x2d\x3e\x4e\x1a\xa2\x2b\xd0\x6b\xb5\xee\xd8\x9b\x94\x13\x77\x1e\xca\xb6\x44\xca\x72\xd1\x29\x1d\x00\xf7\x40\x90\x1a\x73\x11\xdc\x03\x67\x15\xd2\x3e\xbd\x9a\x59\x89\x16\x28\xf0\xd8\x7e\xd4\x89\x50\x2f\x06\xd7\x5b\xbd\x11\xcd\x16\x02\xa3\x5e\xe7\xe1\x33\x35\xd6\xa1\x44\xb0\x88\x30\xe6\x69\xc0\x2e\x65\x2f\x3f\x10\x0d\x39\x3e\xf9\xb4\xac\x05\x32\x14\x39\xbc\xe6\xce\x36\xff\xc5\xab\xca\x89\x0b\x87\x96\xcc\xb5\xe1\x63\x03\x55\x9c\x5d\x91\x17\xf0\xf3\x1d"}, +{{0x70,0x09,0xed,0xd0,0x79,0x50,0x96,0xed,0xc4,0xfe,0xd5,0x5a,0x17,0xcc,0xf4,0x84,0x13,0x1e,0x60,0x8c,0x6d,0x5d,0x66,0x96,0xbf,0x33,0x76,0xe2,0x69,0x24,0x95,0x9b,},{0x77,0x57,0x4b,0xf0,0x69,0x52,0x71,0x45,0xe7,0x2d,0x3e,0x85,0xce,0x7d,0x4f,0xcd,0x67,0x1a,0x33,0xe0,0xa7,0x1e,0x6b,0xf0,0xda,0x7e,0xa4,0x71,0xdd,0x6e,0x86,0xa4,},{0xb7,0x01,0xb8,0xf9,0xa4,0x34,0xe0,0x6d,0x71,0x9a,0xd2,0x5d,0xcc,0x54,0x06,0x0c,0x79,0x86,0x64,0x7f,0x44,0xf3,0x88,0x4b,0xcb,0x6e,0x5e,0xe1,0xd7,0xa4,0x46,0xcc,0x26,0x5c,0xec,0x02,0x9b,0x53,0x7d,0xa7,0xf2,0x52,0x33,0x26,0x55,0x8a,0xc9,0xba,0x34,0xf4,0xcc,0x2a,0x97,0xcc,0xa3,0x45,0x2e,0x70,0x56,0x2e,0x7a,0x8f,0x55,0x04,},"\xb1\x2c\x12\x47\x05\x39\x54\x7c\x2d\xe6\xbc\x4e\xea\xc7\xb6\x3e\x50\x8e\xd7\x10\xf3\x56\x37\xd9\xfd\xd2\xdc\xca\x32\x2a\x7a\x50\x71\xda\xb2\xb2\x84\x5e\x30\x79\x28\x06\x03\x5c\x9f\xcd\xaf\xe2\x78\x3e\x3b\x67\x7d\x6b\xe5\xaa\xc7\x0b\x33\x91\x0a\x2b\x95\xe8\xb5\xd5\x9b\xda\x61\x59\x35\xa4\x17\xb7\xae\x19\xa7\x85\x37\x74\xe8\x9a\x12\xaa\x54\x7b\x41\x92\x97\x9a\x01\xef\x6e\xf3\x2a\x40\xde\x79\xd6\x80\x05\x7a\x83\xa0\x74\x61\x7c\xa6\x50\x1f\x59\xe7\x35\x64\x92\x7c\x38\xb5\x8c\x19\x58\x5a\x2c\x03\x65\x9c\x02\x6e\x4d\xe3\x80\x6d\x6c\x1c\xa8\x95\x8d\xee\x47\xbc\xb8\x89\xe7\x6d\x2c\x3a\x9a\xb5\xb8\xb6\xaf\xb2\xe8\x42\x29\x80\x56\x56\x7b\xf9\xb5\x89\x57\x41\x54\x83\x33\x62\x33\xef\x49\x20\xfa\x57\xf4\x96\xe1\xf0\x34\x8c\xca\x20\x36\x64\x96\xfa\xb3\xa7\x5b\xf4\x21\x4e\xce\x47\xa4\x5f\xea\xa1\x39\x2d\xb3\xf2\x54\xd9\x6a\x7f\x37\x40\x2c\x98\x11\x14\x0d\x73\x58\xb4\xef\x8f\x20\xa2\x98\xee\xef\x90\x4e\x37\xd6\x8f\x37\x8d\x33\xcb\x96\xd0\x0c\x03\x10\x9f\xc8\x3f\xd0\x6a\x87\x6c\x92\x48\x2f\x61\xab\x79\x14\xeb\x7c\x2e\x5e\x84\x06\x6e\x0e\x91\xe2\x1e\x42\xe9\xbe\x23\xdf\x12\xb5\xc7\x47\x97\x3c\xb8\x64\x42\xc3\x22\x91\xd3\xd1\xae\x71\x9b\x36\xa6\x2f\xaf\x3a\xba\xa2\x05\x3a\x31\x3f\x62\x5d\x85\xc5\x1a\x51\x98\x57\x19\x15\xef\x8a\x2b\x19\x9b\xa3\x7d\x25\x88\x45\x75\xba\x1b\x72\x84\x4c\xab\x43\x28\xb5\x7f\xab\x1e\xc9\x74\xee\x8e\xa1\xdf\x7c\xa9\xc7\x8a\x4d\x3a\x03\xbc\xb0\xab\x41\x69\xbf\x06\xa3\xa4\x38\xd9\x56\x6c\x6c\x50\x1d\x8d\x9c\xcc\xcb\x1a\xc2\x6b\x4d\xa4\xae\x1a\x9d\x8e\x8b\x9d\xf6\x62\x82\x1a\xd9\x75\xc9\xb0\x15\xfe\x26\xf6\x89\x8d\x22\xab\x91\x2f\x0e\x40\x5a\x5b\x27\xcf\xd3\x9d\x65\x7d\xcd\x92\xcd\xeb\xe6\x79\x19\x02\x71\x34\x84\x40\x6d\xdd\xce\x71\x18\x87\x31\xe4\x43\x19\x38\x1a\xf2\x7d\xaf\x76\x79\x22\x73\xb8\xc3\x52\x51\xd1\x1b\x83\x6a\xfe\x8b\x3c\xe9\xb4\x02\x73\xf6\x91\x5e\xbe\x6b\xc9\x5a\x75\xbb\x94\x1a\x42\x92\x09\x86\x7f\xba\x87\x64\xbf\x6c\x40\xdb\x6e\xec\xb4\xf2\x17\x47\x83\x7c\xf6\xae\x7f\xbf\xe3\x6d\x50\x23\xdf\x7f\xce\x2c\x0c\x3c\x57\xaf\x28\x98\x88\x53\x13\xc5\xc4\xbd\xa3\x5c\x7d\xa6\xcb\x29\x93\x2f\xb1\x99\x1f\x62\xbb\xb0\x80\xb3\x2e\x20\x50\x61\x93\x11\xae\x69\xab\xb3\x02\x2d\x91\x3f\xa9\xea\xbd\x5d\x5c\xb4\xdc\x54\xd7\x5d\xca\x63\x8c\xda\x9a\xf3\x31\xc0\xcf\x4d\x20\x07\xb6\xca\x39\xf6\x55\xa6\x1c\x01\x03\x9f\x12\xa4\xb9\x78\x2b\xc3\x9a\xec\x4d\x22\xef\x00\x93\x38\x8d\xd7\xd5\xb5\x6d\xfb\x8a\x7f\x9d\x86\x69\x00\x4e\x28\x78\xdd\x8a\x6d\x76\x85\x7c\x08\x45\x24\x50\x68\xfe\xe1\xc5\x31\x96\x31\xe7\x8d\x37\x85\x16\x5c\x70\xaf\xd6\x52\x99\x30\x13\x78\x55\x1e\xbf\x61\x35\x84\xc6\xa7\x62\x0a\x0e\x3b\x67\x79\xf3\x8c\x09\x40\x06\x24\x97\x00\x8e\xb2\x33\x87\x08\x68\xc2\x1c\xcc\xac\x23\x95\x01\xb6\x3b\x74\x9a\x85\x60\x2c\x28\xa0\x95\xca\xfc\x74\x9b\x05\x11\xa6\xc8\x78\xed\xb3\xb7\x80\xea\x17\x4d\x07\xb1\x21\xe3\x15\xa8\x26\xdd\xa6\xec\x8d\xc5\x43\x63\xe2\xcd\x2e\x63\x05\xa1\x94\x82\x5c\x0e\xa9\x0e\xfd\x7a\x9f\xd8\x9c\xd9\x7b\x99\xc4\x30\x0b\xd3\xbf\x93\x53\xd8\x2f\xbc\xce\xea\x71\xb4\xee\x3f\x1a\xae\x95\x39\xb4\xcc\xe9\x0c\xa4\x77\x59\x7c\x17\x4e\xf2\x0f\x4b\x9f\x4e\x62\xd0\x9a\x57\x0d\x31\x35\xaa\xbe\xe9\x55\x1f\xa6\x09\x83\x95\x8c\x0b\x7b\x8c\x37\x44\x55\x3e\xe1\x4e\x7f\x3c\xd1\x03\xa1\x92\x51\xc9\x9b\xf6\x38\x4a\xbb\x60\xa7\x6a\xfc\x66\x58\xb8\x0d\xfc\x51\x10\xad\xc4\xc7\x32\xfe\x0e\xe3\x29\x33\xfb\x28\x48\x28\xe0\x08\x88\x7a\xef\x80\xf6\xf8\x13\x34\x04\x46\xc0\x21\x7c\x12\xee"}, +{{0x12,0xfe,0x8e,0x5c,0xe2,0x0c,0xaf,0xaa,0x32,0x79,0xda,0x7b,0x34,0xaa,0x87,0x75,0x2e,0xad,0x67,0x9f,0x15,0x61,0x28,0xaa,0xef,0xb4,0xaf,0xa5,0xdb,0x4f,0x2a,0x6f,},{0xe7,0x7f,0x44,0x20,0x6b,0xb0,0xc4,0xc5,0x9a,0x28,0x70,0xcf,0xc2,0xec,0xac,0x63,0x36,0x2d,0xee,0xcb,0xe8,0x11,0x5d,0xe5,0xcb,0x1a,0xfc,0x2d,0x9a,0x3d,0x47,0xf1,},{0x04,0xea,0xf9,0x00,0x96,0x6e,0x09,0x92,0xd3,0x6e,0x3c,0x22,0x0a,0x4b,0xd4,0xd8,0x2b,0xcc,0x6e,0xb9,0x98,0xed,0x05,0x1d,0xbc,0xb9,0x16,0x0b,0xcd,0x35,0x74,0x09,0x73,0x6b,0xcf,0xf7,0xe6,0x63,0x0e,0x96,0xf5,0x53,0x8a,0xec,0xa6,0xab,0x8b,0x0d,0x0b,0xd8,0x2c,0x0c,0xd7,0xc4,0x54,0x99,0x17,0xfe,0xbb,0x9c,0xba,0xda,0x08,0x0c,},"\x6b\x80\xcc\x6f\xbb\xd3\x32\xf8\xc6\x19\x7c\xdf\x2e\x6d\xc1\x9a\x21\x30\xfa\xa2\xec\x93\x8e\xf5\x58\xb8\x84\xba\x4f\xa5\xe1\x13\xe5\xb3\xe4\xb1\xaa\xf5\x1b\x69\x5f\x13\xef\xfe\x13\xf7\x7d\x39\xca\xb3\xc0\x7d\x04\xd6\x6d\x43\x0d\x99\x74\xb1\xda\x3d\x39\xdf\x12\x78\xc0\x0d\x6b\xcb\xfd\x4b\xae\x75\xb8\xc0\x76\x40\x4d\xbb\xb8\x34\x48\xfb\x49\x3d\xf6\x70\x00\xf9\x7d\x24\x7e\x8f\x23\xdc\x08\x1f\xce\x99\x2b\x65\xa2\x1b\x35\xd7\xbd\x7f\xa7\xdc\xcc\x54\xa5\x60\xaf\xd1\x4b\x1e\xc4\x36\xc1\x09\x46\xf6\xaa\x59\xea\xe1\xbe\x3e\xcf\x31\x1d\xef\x51\xe4\x6b\x6b\x4d\x1d\x08\x0d\x17\x84\xb2\x33\x4b\x80\xcf\xba\x72\xcd\x93\x1f\x55\xec\xd2\x98\xb0\x5d\xc8\x36\xab\x12\xd0\xad\x8b\x5d\x6e\x9b\x1e\x3c\xea\x3d\x84\x33\x68\xee\xf1\x9f\x5c\x14\xc6\xbb\xad\x94\x14\xcc\x7a\x4d\xb6\xa7\x26\xe4\xfc\xae\xd4\x44\x40\xa0\x19\xfe\x12\xa6\x05\x73\x40\x3c\x0e\x66\x2d\xc9\x02\xd1\xc8\x73\xff\x30\xc9\x31\xba\x7e\x43\xa3\xb3\xbf\x71\xd5\xb0\x94\xea\x50\x49\x71\x64\x7c\xa9\x43\x56\xf0\xa5\x3e\x44\x4b\x4c\x00\x8e\xe5\x97\x72\x04\x22\x1b\x40\x0d\xee\xc3\x7f\xc2\x73\x45\x25\x45\xf8\xf2\x18\xbe\x98\x87\x25\xbc\x38\xc8\x5d\xf2\x12\xea\x73\xdc\x0b\xc7\xcb\xba\xc9\x07\x98\x2f\xef\xad\x68\x0f\xbd\x97\x5c\x20\x93\xa7\xfe\x8e\x6b\x37\xc1\xcc\xed\x87\xf8\x1d\xaa\x57\x29\x1a\x5a\x18\x47\x6d\x11\xa1\x8e\xc4\xb5\xcb\xce\x5d\x55\xac\x9b\x62\x4b\x04\x84\x30\xf2\x54\xf6\x71\x07\x85\x06\xe6\x98\x9d\xf7\xc0\x92\x56\x52\x50\x39\x08\x5a\xb7\xc1\x30\xc2\x40\x00\x4a\xbb\xb3\xaf\x6b\x48\x1c\xc1\xa0\x61\x7e\x57\xe3\x88\xee\x4b\x1f\x05\x2f\x34\xa0\x03\xfe\x6b\xb2\x02\xcb\x87\xd2\x74\x1b\xd8\xe3\x45\x4c\xa7\x3d\x2f\x61\x20\x11\xec\xc7\x4d\x88\x34\x35\x10\xa6\x3c\x93\x13\xdd\xc3\x6c\x25\xd3\xfb\x03\xe1\x88\xf5\x60\xbd\x02\x9c\x80\x15\x85\xce\x55\x29\x88\xdc\x55\xb7\xd8\x52\x2a\x33\x96\xc0\x1d\x5e\x71\x5a\xe2\x6c\x62\x2c\x64\xfe\xd5\xb9\x8e\x9c\x55\x9e\x4a\xa7\x8d\x1e\xd3\xb7\xb8\x90\xd4\x77\xec\x8c\x50\xa0\xff\x10\x7a\x3f\x83\xb0\x7b\xd3\x5e\x9c\xe9\xa0\x8b\xcf\xc0\xf1\x68\xee\xc7\xaa\x31\x1f\x71\xc6\x6a\x71\xce\xb9\xd5\xa2\x19\x9a\x14\xbe\x36\x86\x5c\xa8\xd0\x7e\x18\x6b\x13\x92\xb9\x29\x0c\x57\x80\x04\xd5\x84\xf1\x91\xc8\x2a\x53\xd8\x50\x89\x0b\xcc\x0d\x12\xdf\xf8\x40\xe0\x43\xdd\xdc\x2e\x67\x0c\x83\x60\x20\x92\x4f\x58\xc0\x44\xb2\x18\x76\x3c\xa6\x19\x82\xbc\x33\x2d\x24\x7b\x2a\x00\x8a\xb5\x70\xb6\x56\x5a\x06\x89\x2a\x26\xcf\xb0\x85\x3d\x79\xda\x28\xef\x8b\x91\x0a\x93\x29\x54\x4b\x79\x2a\xe4\x45\x6b\xa7\x76\x50\x66\xb9\xd1\xb4\xa3\x00\x21\x04\x48\x66\x0a\xe4\x8b\x50\x44\x41\x01\x7c\xdd\xd1\xf6\xf0\x09\x38\xb1\x07\x2c\x8a\xb8\x24\xad\xfe\x8a\xe3\x49\x23\xc8\x2e\xec\x75\x4b\xee\x1a\x65\x50\xab\x1d\x3d\xa0\x86\xe3\xae\xbb\xf2\x11\x69\xc4\x44\x69\xe0\x3b\xba\xe0\xd7\x2c\xe8\x63\x45\x77\x84\xcf\xe1\xdf\xc2\x76\xf1\xaf\xad\x9e\xe5\x3e\xba\xb5\xa3\xc6\x57\x2e\xb1\xca\xe0\x99\xa4\xa5\xfe\x19\x31\x92\x90\xe6\xa1\xb8\xb0\xe7\x54\x1e\xd7\x35\xb3\xf2\x1b\x1e\x2c\x75\x09\xf8\x7f\xd1\xfe\xd0\x00\x07\x47\x9b\x3c\x1b\xb7\x84\x32\x46\x63\x02\xd2\x46\xd8\xd0\x31\x99\x63\x07\x26\x0a\x0c\x41\xa0\xe3\xec\xd1\xe7\xfd\x83\x4d\xac\x11\xa1\x3e\xb0\x36\xb3\x9c\x36\x99\x66\xfd\xef\x39\x4c\x18\x3e\x54\xe7\xb0\xcb\x3d\x0c\xeb\x19\x8b\xd0\xe6\x6c\x00\xd3\x8d\xb7\x03\xaa\xce\x30\xcb\xbd\xab\x36\x9d\xfd\x1d\x9e\x51\x4d\x09\x68\xf1\x00\xc9\xf0\x7c\x31\x50\x89\xad\xb3\xad\x02\xe5\x9c\x04\xb9\xbe\x46\xe9\x9f\xbf\x5a\x62\xc6\xbb\xec\xdf\xf5\xb3\x81\xe5\x51\x27\x82\x4d\xdb\x18"}, +{{0xee,0x9b,0x6c,0x2e,0x0c,0x9b,0x01,0x47,0x2c,0xe3,0x2d,0x54,0xd1,0x76,0x2a,0xb0,0x30,0x33,0x17,0xd7,0x6d,0x3a,0xa7,0x8f,0x5e,0x08,0xa9,0x02,0x4c,0xa1,0xe0,0x83,},{0x01,0x6d,0xf0,0xf7,0x17,0xbc,0xb7,0xad,0xf6,0x26,0x95,0x8d,0x83,0xbf,0x8a,0xa3,0x25,0xc7,0x05,0x18,0xc6,0x8b,0xc7,0xef,0xd8,0x42,0x53,0xb7,0x5d,0xb0,0x87,0x88,},{0x4b,0x00,0x1d,0x96,0x42,0x83,0x5d,0x72,0x13,0x8d,0x68,0x01,0x98,0xe6,0xaf,0x70,0xb5,0xde,0x7a,0xf0,0x15,0x13,0x1e,0xa7,0x26,0xf4,0xe5,0x1b,0x5e,0x8b,0x6d,0x48,0xc2,0xa6,0xca,0x8e,0x87,0x09,0xcc,0x82,0x22,0xa5,0x04,0x7c,0x09,0xa6,0x6e,0x51,0x8a,0xc5,0xe8,0xb6,0xe5,0x35,0x48,0x94,0x82,0x61,0xf0,0x70,0x1f,0x68,0x73,0x08,},"\x77\x2c\xc2\x5c\x3b\x69\xbb\x3f\xf5\x65\x56\x64\xef\xa4\x78\xac\x41\x4a\xdf\xae\xa7\x0a\xc4\xa2\xa8\x87\xed\x39\x68\xc5\x4d\x34\xdb\xf1\xbe\x32\xcc\x9a\x9b\x54\x20\xa4\xad\x3c\x9a\x87\x7b\xc8\xcc\xec\x94\xad\x47\x3a\xa7\xa3\xc7\xde\x08\xa0\xfd\xb5\xed\x1e\x89\x87\x2b\xe7\x81\x70\xbe\x22\x1d\x27\x97\x76\xbb\xc6\xed\x9c\x5a\x67\x16\x89\x80\xd5\xea\xf8\x95\xe1\x34\x0f\x5d\xfa\xa3\xdf\x62\x2d\x65\x44\xb3\x99\xd7\x49\x45\xfd\x13\xbb\x11\x73\x62\x1e\x05\x61\x51\x46\x40\x13\x7a\xa7\xbc\x9c\xb7\xde\xbe\xff\x2c\x62\x69\x77\xd4\x47\x26\x3b\x7e\x57\xd4\x3d\x69\xef\xb2\x30\xcd\x25\x86\x5e\x4d\x92\x48\x28\xf5\xe3\x6f\x96\x4e\x40\x3e\x34\x93\xf3\x0d\x6d\xfe\xa6\xca\x3b\x78\x10\x75\xb5\xe3\xb2\x5c\x05\xac\x50\xe5\x55\xf1\x5b\xa1\x2b\x0e\x05\x9b\xff\x99\x64\x84\x12\x9d\xb6\xea\xfd\x88\x99\x3d\x6f\x0b\x7e\xcd\x15\xdc\xe2\xfc\x99\xf8\xb8\xe4\x35\x16\x35\x2d\xdb\x46\x1a\x04\xb9\xff\x34\x86\x45\x2e\x6a\xa6\xa5\x4b\x2d\x10\x62\xa7\x71\x42\x50\xcd\x2a\x88\xff\x6c\x4c\x17\xb6\xcc\x66\x52\xd8\xc5\xac\x27\xd4\x44\x3a\xeb\xf3\xd5\xfb\xaa\xee\x45\x21\xec\x76\xf0\x41\x3d\xb6\x44\x21\xec\x8d\x69\x49\x62\x67\x25\xfe\x56\x16\x0a\xb3\x07\xc0\xe7\x39\x06\xc4\x51\x55\xef\xab\xb4\x72\x22\x02\x1f\x22\x0d\x32\xbd\x3d\xb0\x71\x2a\xbd\xe2\x59\x9e\xa4\xff\x79\x97\x17\x81\x1d\xcd\xf8\x18\x2d\xf6\x71\x6d\x2a\x03\x8a\xee\x15\xd7\x78\xda\x55\xac\x20\xf0\x1f\x25\x30\x9c\xea\xd5\xb5\xb7\xb2\x23\x22\xe1\x82\x8e\xa7\xc9\x1a\xe6\x66\xf2\xdc\xd6\x84\x07\x31\x48\xe3\x1b\xb2\x24\x7d\x5f\x93\x50\x6e\xa8\x08\x52\x27\xad\xc9\xae\x19\x82\xe9\x50\xf0\x06\xa9\xda\x15\x8b\x9c\xec\xff\x89\x29\x76\x1c\x84\xf9\xd9\x76\xfd\xcd\x31\x7f\xfe\xd3\x6c\xbf\x6a\xcd\xa3\xe5\x0c\x9b\x73\xbd\x2c\x80\x85\x40\x9d\x11\x9b\x64\xce\xd7\x34\x9a\x26\x74\x26\x2a\x83\x2b\xec\xb0\x3c\x2e\xdc\xca\xc0\xec\x54\x12\x4e\x82\xf8\x10\x18\x17\x92\xda\x49\xea\x10\xbd\x94\x1f\x98\x95\xa0\x69\x59\xfd\xe0\xd3\xb0\xae\x84\xc3\x9d\xf0\x53\x90\xab\x33\xc3\x6c\x79\xca\x22\xe6\x59\x4d\x7f\xc6\xe3\xf8\x69\x22\xd7\x8e\xb7\xf5\xc2\x54\x95\xd8\x22\xa3\xb4\x10\x51\xb2\x4e\x57\xa7\x6f\xcf\xc1\x65\xcd\xe6\xd0\x96\xcc\x7b\x7e\x9d\x05\x5f\xe8\x64\xd5\x29\x42\xd6\x29\xa8\xac\x26\x1b\xe1\xdc\xd3\xa2\x1f\x89\x5f\x49\xb6\x7e\xe4\x7e\xab\x7c\xf1\x64\x4d\x57\x1d\x5f\xf3\x8c\x17\x9f\x5c\x6a\x54\xa3\x61\x2f\xb3\x47\x53\x41\x2a\x1b\x95\xbf\x62\xff\x31\x79\x80\x4f\xfb\xb9\x90\x51\xf2\xb0\x80\x56\x3a\x4a\xe0\xf2\x7c\xf9\x96\xea\x8b\xe3\xba\xe0\xa4\x33\x9d\xcc\xdf\xf6\xb6\x67\x15\x59\x26\x6e\xaf\xf4\xef\xf6\x82\xb8\xde\xe8\x9c\x9d\x2d\x45\xac\xdb\xec\x4a\xa6\xce\xcd\xbd\xb1\xd2\x84\x60\x9e\x65\xef\xb7\x7b\xb8\xf1\xa5\x1f\xc4\xd4\x56\x8a\x70\x5f\xb9\xc9\x7b\x23\x03\xc1\x46\x7d\xff\x8c\x8c\x5e\xe2\x75\x59\xb9\x3a\xd1\xc5\xb9\xc5\xc6\xc7\xc5\x29\xfa\x8c\x55\xc7\x5e\xbb\x59\xb2\xa8\x18\xaa\x9b\xda\x1e\x9e\x79\xbc\x66\x02\x97\x72\xf8\xae\xa1\x1b\xad\xd3\x22\x65\x65\xd5\x4f\xd0\x1b\xda\x8c\xb2\x70\xe7\x0d\xc9\x33\x9b\x46\x90\x0b\x58\x18\xe9\x32\x07\x5b\xe6\xc2\x8e\x73\xa1\x91\xd0\x2c\xbd\xc7\x45\x4b\xe1\x23\x87\xb0\xd4\x7a\x1a\xb1\x42\x32\xd2\x34\x2a\x6f\x15\x18\xea\x97\x09\x8b\x81\x5a\x1c\xa3\xf9\xc7\x0b\x25\x72\x2b\x1b\xcd\x7d\xac\xda\x63\x56\x22\xfc\x8e\x72\x95\x9f\x57\xf7\x67\xea\x56\x3d\xa4\xc1\x58\xee\xf7\x20\x01\x09\xf6\x14\x16\xc2\xe7\x04\x39\x92\x30\x62\x43\x7b\x1d\x08\x2a\x8c\x7f\x43\x94\x71\x3c\x1b\x7b\xa0\x58\x7b\x84\x1c\x11\x44\x75\xee\x3f\xf0\x59\xdf\x8c\xfa\x12\xa3\x21\xd9\x01\xcb\x47\xf5"}, +{{0xa3,0xd2,0x35,0x05,0xd0,0x7c,0x5f,0x93,0x7f,0x13,0x63,0x9d,0xbd,0x81,0x8e,0x85,0x14,0x52,0x34,0xee,0x70,0x17,0xec,0xee,0x86,0x36,0xc7,0xba,0x76,0xeb,0xef,0x5b,},{0xfd,0x7f,0xdb,0x3d,0x02,0x2b,0xa3,0x6e,0xad,0xfe,0xd0,0xda,0xaa,0xe5,0xbf,0xf0,0x45,0x05,0x40,0x3f,0x17,0x14,0x73,0xe4,0xd3,0x61,0xee,0x8d,0x15,0x0a,0x0e,0xb4,},{0x67,0xa6,0x67,0xee,0x0d,0x62,0x54,0xca,0x0a,0x8f,0x21,0x25,0x82,0xc0,0xcb,0x8b,0x6e,0xd9,0x7c,0xc9,0x67,0xdb,0x02,0x12,0x96,0xad,0x6a,0xa9,0x9f,0x0a,0xd3,0xa9,0x44,0x97,0x8c,0xfd,0xaf,0xf1,0x3f,0xe5,0xf8,0xc6,0xe8,0x8c,0xbd,0x83,0x1a,0x54,0x73,0xd0,0x74,0x2e,0x37,0x34,0xb3,0xe2,0xdf,0x00,0xff,0x32,0x40,0xa5,0xde,0x02,},"\xbc\x29\x8e\xd6\x98\x92\x90\x40\x28\x72\x5e\x21\xb1\x14\x46\x2d\x89\xd8\xc0\x06\xdc\x88\x4b\x17\x87\x56\x83\x8a\xf4\x95\x4f\xf0\xf1\xb7\x95\x17\x30\x7a\x25\x8a\x0e\x76\x81\xe8\x79\xac\x47\xd7\x92\x02\x30\xb0\xcc\x1d\x66\x17\x1e\xb2\x14\xd7\x7c\xd9\x7f\x61\x7c\x40\x5e\x6c\x21\x72\xfc\x58\x9f\x16\x25\xcc\x5e\x1b\x59\x31\x10\x53\x1f\x6e\xb5\x3f\x1e\x6f\x48\x6d\x19\x64\x61\x24\x47\x75\x0a\x04\x1f\xe5\x1b\x33\x2e\xb3\xfb\xc7\x11\x61\x6c\xe3\x5f\x04\x04\x42\xb4\x31\x63\xb8\x0b\x75\x1e\x21\xec\x12\x45\xf1\x2e\x48\x83\xc7\x9d\x3b\x41\x32\x82\xc6\x9b\xfc\x6a\x46\x5d\x1e\x78\x96\xba\xb0\x38\xdc\x89\xb4\xcf\xc0\x32\xfc\xcd\xfc\x87\xb0\x7f\x06\x11\x0e\x1f\x50\x6a\xcc\xa8\x15\x7a\x32\x25\x43\xbf\x1e\xd8\x90\x67\x27\xf2\x8d\x0d\x68\x9b\xcd\x7d\xd3\xdf\x85\x93\x52\x04\xa9\x04\xab\x3f\x7a\x0d\x99\xc1\x6e\x5a\x54\x2c\xc2\xbc\xde\xbf\x5b\x50\x2d\xba\xbe\x33\xb9\x72\x48\x0e\x02\xe7\x1a\x43\x8a\x19\x80\xa8\x76\x6f\x10\x8b\xd8\xad\x51\x10\x42\x23\x99\x4d\x9b\xfb\x3c\x3a\x4b\x7a\x59\x23\x8c\xe2\xef\x7d\x72\x88\x38\x3f\xfb\xf2\x91\xe1\x60\x2b\x38\x4a\xf6\x07\x00\xd7\xda\xf0\xe8\xfe\x60\xf8\xca\xed\xe4\x3d\xb0\x6b\x3f\x4c\x8c\xff\xf7\x49\xae\xaf\xa4\x6f\xc6\x1c\x49\xb2\xd5\xa4\x12\x04\xcf\x86\xf0\x49\x25\x4d\x80\x9e\x94\x98\xaa\x9d\x4c\xfd\xb9\x4a\xcb\x2b\xab\xfc\xf7\x86\xdd\xfb\x03\x69\x15\x16\xb3\x83\x8b\x0d\x4f\x20\x1c\xb2\x59\x1e\xdb\xb0\xb0\xf6\x74\xe1\xe2\x82\x03\x16\xb7\x2e\x81\xb4\x8c\xc5\xa6\xb2\x93\x38\xbc\x36\x68\x1f\x8f\x7d\xca\x43\xee\x6c\x0b\xd2\xe4\x02\xaf\xbf\x96\x77\x97\x51\x64\x53\xbc\x01\xbe\x86\xbf\x42\x29\x9d\x1b\x73\x6a\x0d\x97\xbb\xc9\x22\xf5\xa7\x8a\xf2\xdf\x42\xe6\xf8\xc2\x8e\x95\x3f\x2c\xea\xda\xff\xc5\xe9\x30\x64\x04\x1e\x42\x5a\xd6\x97\x5f\x88\xc7\xaa\xdf\x81\xc3\x68\x69\x1a\x58\x1e\x88\x5f\x2a\x6b\xa7\x2e\xd6\x8b\x8f\xef\xbc\xd6\xce\x36\x86\x26\xd4\x48\x92\xa2\x02\x70\xb5\xf7\x09\xc2\xe3\x4b\x83\x35\xd4\x2e\xeb\xd6\x7a\x24\xdf\x73\xf4\x54\x55\xc4\x19\x44\x18\x7b\x66\x92\xf0\x54\xb2\xfc\x95\x91\x37\x3f\x19\xfc\x71\xaa\x7f\xa2\x7d\xf6\x00\x6a\x1d\x54\x9b\xbf\xae\x7d\x3c\x3e\xb3\x6e\x5a\xb2\xaa\xa1\x0a\xa5\x53\x8d\xa7\xef\x36\xc8\xff\x35\x4b\x60\x58\x13\x40\x04\xd6\x60\xa4\x03\x63\x21\xca\xad\x00\xa3\x0b\x1c\x49\x8b\xa3\xd8\x08\xc4\x40\x5e\xf7\x96\x18\xfc\x22\x12\xa7\xb8\x33\x96\xa3\xd7\xce\xdc\xeb\x86\x3c\x66\x37\x4d\xc4\x69\xae\x18\x3c\x7e\xd7\x4b\x3e\x70\xd6\x37\x4a\x06\x2d\xe0\x37\x9b\x21\xcf\x25\xd3\xc4\xc5\x76\x21\x15\xcd\xfe\x75\x55\x45\xe8\x9a\xd4\x05\x2b\xb0\x27\x9d\x93\x8e\x90\xde\x3a\xbf\x50\x44\x10\xca\xad\x72\xb7\xc2\x9f\x53\xd0\x1d\x9d\xd7\xf2\xec\x5e\x45\x9a\x04\x59\x2b\xdd\x66\x41\x66\x13\xe6\xed\xd0\x04\x56\x9e\x0e\x6c\x98\x82\x7b\x8c\x1d\x70\x02\xa6\xd1\xbf\x30\x3e\x18\x25\x95\x01\xdd\x89\xf6\xee\x94\x76\x6d\x18\xaf\x81\x04\x63\xeb\x13\xb2\xef\xdd\xf1\x72\x3a\xf7\x35\xa8\x87\x16\xe1\xfc\xb4\xb7\xb4\x3c\xb9\x7e\x1c\xc9\x03\xb2\x40\x8e\xf4\x53\xad\xa4\x16\x47\x86\xf0\x08\x45\xfb\xfa\x1f\xfc\xa5\xcc\x3e\x1c\x4b\xd9\x94\x0e\x7d\x99\xae\xf9\x19\x16\x6d\x05\x8b\x51\x45\x3c\x9c\x14\xfb\x9f\x32\x51\xec\x5f\xe4\xf1\x53\xc7\x0a\x44\x92\xdc\x34\x96\x29\x61\x86\xf2\x3a\xd4\x7e\xba\xd1\x3c\x66\xe6\x87\x27\xce\x50\xba\x94\x87\xf1\x80\x18\x90\xb6\x93\xef\xeb\xfc\x37\xbb\x5d\x95\xf8\xaf\x54\x8e\xc8\xd6\x49\x82\x89\xe5\x5f\x98\x83\xfc\x5b\xe8\x4c\x25\x6d\x2b\xc5\x48\x49\x38\xc7\x09\x82\x0d\x9b\x6b\x80\x59\xc0\xaa\x42\x67\xdd\xe6\x90\x78\xe4\x87\xc8\x86\x5c\x0b\x13\x0a\x0c\xa8\xca"}, +{{0x6e,0x26,0x51,0x05,0xee,0x71,0x71,0xd1,0xbd,0x79,0x3e,0xff,0xd8,0x7d,0x1e,0x2c,0x79,0x45,0x0d,0x5e,0x18,0x8b,0x57,0xbe,0x3a,0xa1,0x62,0xe2,0xa5,0x25,0x28,0xad,},{0x1f,0x40,0x3c,0x7a,0x75,0x50,0x31,0xc1,0x3c,0xa6,0x3a,0xf5,0x76,0x35,0xdc,0x6e,0x2c,0x4f,0x23,0xbd,0x6b,0x1d,0x67,0xca,0x65,0xda,0x68,0xb0,0x99,0x43,0xc5,0x54,},{0xb5,0xa8,0x3a,0x11,0x7a,0x60,0x34,0x5a,0x67,0xe4,0xa6,0x65,0xf3,0x7d,0xe7,0x22,0xa6,0xec,0x03,0x91,0x38,0x29,0x38,0x99,0x59,0xf3,0x76,0xee,0x62,0x64,0x77,0xe6,0x54,0xac,0x8d,0x72,0x0f,0xc7,0x27,0xd4,0xbb,0x8f,0xe1,0x54,0x4f,0x5d,0x0b,0x0b,0x85,0x05,0x14,0x29,0x0b,0x24,0x27,0x3c,0x4c,0xd4,0xb7,0x3a,0xca,0x4a,0x53,0x00,},"\xf8\xb9\xd4\xb0\x27\xeb\xb1\x0e\xe5\x11\x81\x9e\x6e\x56\xfb\x1b\xa9\x58\x40\x18\x41\x8d\x82\x88\x5a\x38\xa4\x49\x08\x60\x07\xb8\x78\x5b\x51\x05\xca\xf7\x82\xbf\x9b\x36\xda\x03\x9c\xc6\x0e\x22\x7c\x7e\x16\x14\xf2\x9b\x64\x0b\x1e\x9b\x22\x74\x7e\xea\x7a\x67\x25\x61\x4e\x89\xe0\x78\x3e\xbe\xbb\xb7\xee\x55\x7e\xf3\x6b\x2b\x46\xcf\x64\x61\xe5\xbe\x2a\xd1\xd7\xa7\xc2\x71\x1a\x47\x5c\xa4\xfb\xc3\x30\x92\xba\x42\x56\x67\xe3\x4d\x09\x00\x60\x51\x8f\x2f\xec\x63\x6b\x04\x91\x23\x87\x6a\xb2\x1c\x8b\xd9\xc5\x0d\xcc\xb9\x84\xca\x01\x1a\x02\xee\xa0\x20\x56\x4f\xa8\x21\xfc\x36\x2b\xfe\x39\x2a\xab\x50\xc2\x73\xfc\x7b\x5a\x04\x21\x88\xe3\x31\x62\x1b\x9d\x2f\x74\x3e\x5c\x8c\xf3\xab\x1f\xaf\xfa\xfe\x2a\x00\x04\xc8\xef\x7c\xdf\x5e\x6d\xbb\x5e\xb5\x44\xe4\x28\x9f\x71\xa6\xfd\x15\xc6\x38\xce\x29\xd2\x8e\xfb\x9c\x03\x9e\x47\x74\x29\xa3\x49\x7a\x83\x82\x7e\x76\xce\x77\xa4\x98\x16\xd9\x0b\x41\xa8\xe1\x52\xf3\x7a\x09\xe6\x34\x0d\xfe\x06\x9a\x4a\xc6\xf2\x7d\xd2\xea\xc7\x47\xfd\x21\xe3\x15\x20\x88\xc1\xb1\xec\xd3\x2a\xc6\x79\x92\x74\x90\x75\x04\x88\xc2\x91\x78\x51\x47\xb6\x3b\x0b\x8f\xf1\x1d\x18\x9b\x90\x49\xb8\xa3\x96\xb6\x93\x2f\x85\xbd\x6a\x15\xef\xf9\xf0\xce\x18\x08\x41\x1a\xf0\xf9\xc8\xe6\xe9\x7b\x81\x4f\x11\x0b\xd4\xdf\x13\x86\xa9\x79\x7d\xc5\x11\xf0\xaa\xb6\xab\x65\x07\x1d\x9e\xa8\x36\x53\x2c\xec\x51\xb9\x2c\xa7\xfb\xdb\x8d\xe1\xc8\x43\x66\x58\xde\x2e\xb6\x5e\xdd\x86\x04\x4f\x6c\x1a\xba\x31\x78\x64\x7a\xd6\x78\x61\x2e\xe7\x4f\x04\x6c\xa3\xc7\xfe\x2f\x39\xc0\x9d\xd2\xe0\x7d\xf2\xb4\x22\x70\x85\xfe\x93\x6e\x79\x4d\x22\xfd\x5f\x40\xa2\x5f\x08\x77\x15\x80\xac\x80\x1d\x98\x89\xf5\xa7\x6a\xea\xe1\xf0\xcc\x4a\x9e\x1e\xdb\xdd\xa3\x75\x0c\x74\xc8\x50\x52\x4b\x32\xf4\x49\x33\xfd\x88\x3b\x53\x72\xbf\xb7\xe7\x61\xe0\x69\xfe\x7c\x1c\x0e\x7f\xbd\x4a\x7f\x58\x46\x7e\xa6\x88\x3f\x9d\x5b\x7f\x66\xd3\x86\xb0\x49\x9b\xb6\xfb\x5e\xad\x89\xc9\xa1\xfd\x2c\xce\xb9\x73\xe2\x87\x9b\x5d\x03\xea\xa4\x52\xe1\x60\x22\xd5\x96\x17\xda\xa0\x48\x6f\x4d\x4c\x11\x78\x07\xfd\xa8\x49\x9d\xfb\x7a\x28\x6f\xd2\xf7\x1a\x8e\xb5\xfe\x64\x06\x5c\x41\xe4\xe1\xe2\x36\x2a\xb4\xe4\x77\x96\x9e\x3a\x40\x8a\x24\x7e\x3a\x56\xfc\x86\xf2\xb0\x1e\xf8\xd3\xcd\xda\x87\x25\x82\x34\xbc\x7f\x25\xb6\x69\x07\xf3\x64\xb3\x7b\x62\x45\x29\x6c\x4f\xdf\x49\x9f\x20\x23\x7f\x48\x64\x85\x2f\xc5\xd8\xcd\x5d\x05\x41\x8b\xe8\xb1\x38\x59\xee\x9a\x43\xe1\x7e\x1f\x57\xa4\xc3\x5e\xa2\x82\xed\x68\xeb\xcd\xa6\x82\x81\x74\x24\x5a\x49\xc6\xcb\x65\x90\xeb\x1f\x2d\xcf\xb0\x07\xbf\xa1\xc3\x20\x77\x95\x6d\xa9\xac\xbe\x3e\xf0\x72\x37\x99\xfd\xb8\x69\xd8\xde\x30\x70\x6a\x9c\x02\x68\x14\xd1\x6a\x01\xe0\x33\xc9\x1b\x59\x07\x0d\xfe\x44\x5c\x5b\x84\x8a\x51\x66\x12\xe5\x13\x1f\xe8\x48\x69\x21\xe3\x6b\x8e\x7e\xf1\x57\xa8\x88\x22\x88\x6c\x68\x1b\x5d\xa7\x1f\xea\x94\xd9\x57\xda\xfe\xc2\x6f\x41\x47\xa3\xb2\xac\x38\x3a\x5f\x47\xc8\x58\x5e\xb1\x7a\x8a\xc6\x57\x90\x64\x1b\x42\x18\xd7\x55\xf8\xbe\xa4\xd9\x7a\xe2\xa4\x5b\xdc\xdc\x23\x23\x62\x94\xd8\x52\xc9\x5d\x08\x40\x6d\x2e\x9b\xd3\x0c\x32\x64\x52\x53\x8c\x1f\x5e\x50\x04\xd4\xa1\xa8\x27\x20\xda\x32\xe5\x9d\xc3\xab\x18\xea\x08\xa0\x58\xf7\x91\xd2\x44\x18\x55\x60\x86\xc1\xe4\xed\xce\x89\x82\xaa\x23\xb1\x18\xfb\x26\x6e\x60\xb5\x42\x78\x0a\x69\x33\xad\xd9\x13\x26\x55\x12\xc0\x7b\x11\x49\x78\xd4\x4a\xf7\x3b\x20\x30\xec\x47\xb0\x6f\xd0\x9d\xda\x8c\x4f\x1d\x4e\x31\x37\x75\x46\x8c\x45\x1f\x9e\xe6\x11\xe9\xcd\x4c\x08\x45\xc2\x50\x19\x48\xa7\xb1\x4e\xf1\xd4\xb5\xcf"}, +{{0xc4,0x37,0x0d,0x2a,0xaf,0x35,0xac,0xd1,0x58,0xfc,0x0d,0x16,0x22,0xa3,0x99,0xc9,0x9f,0x41,0xb9,0xda,0x4e,0x97,0x0b,0x35,0x4e,0x5b,0xa0,0x5c,0xbe,0x84,0x4c,0xa8,},{0x35,0x45,0xd7,0xd4,0xc9,0x5c,0x3d,0xb6,0xa5,0x45,0x30,0x53,0x7a,0xfa,0xfa,0x4d,0x86,0xdd,0xec,0xf9,0xcc,0x7e,0x66,0xc3,0x19,0xba,0x9f,0x7d,0xd7,0xd0,0x7e,0xe7,},{0x9f,0xeb,0xab,0x5a,0xe1,0x61,0xd6,0x92,0xa6,0xa3,0x94,0x50,0x0a,0x28,0x90,0xd2,0x1c,0x7f,0x0e,0xe2,0x6f,0x46,0x40,0xaa,0xba,0x4f,0xe6,0x6b,0x90,0xb8,0x9e,0xdc,0xb8,0x0e,0xa4,0xcd,0xca,0xbb,0x4d,0x2c,0x3a,0x5c,0x41,0x54,0xe8,0xff,0x20,0xd0,0xe2,0x37,0xfe,0xfd,0x00,0xc7,0xba,0x97,0x82,0xe1,0x74,0x8f,0x64,0x88,0xac,0x01,},"\x61\x9f\x57\xde\x2b\x1d\xba\xee\x20\x9a\x82\x5d\x8c\xa9\x7f\x84\xee\x49\xeb\x12\xa0\xb1\x3d\xcd\xd2\xb3\xa4\xee\x45\xe0\x17\x6d\x47\x4c\xf0\x94\x60\xc8\x31\xa8\xae\x1d\x3f\x39\xbe\xeb\xd0\x88\x08\xb3\xed\x17\x61\x21\x3b\xa9\x53\x42\x18\x60\xcc\x07\xe2\xdb\x31\x2e\x68\x0d\xf0\x3e\x60\xa6\x87\x02\x64\xab\xca\x8f\xd5\x13\x01\xe1\xc1\x56\x20\x23\xd8\x02\xcc\xd5\xc7\xd1\x96\xdb\x39\xfb\xb8\x30\x4b\x0e\x59\xe3\x33\x16\x41\x92\xec\xc3\x33\x38\x7e\xef\x69\xc7\xa7\x8a\x5d\x11\x25\x88\x62\xd6\xc2\x81\xb1\x9c\x0b\xd3\x36\xcd\x3e\xdb\x2f\x9f\xaa\xd4\x02\x1a\xc2\xf2\x05\xc1\x68\x14\xb3\x85\x48\x43\x3f\xf9\xed\xdf\xd6\x11\x33\x77\x97\x69\xdc\x69\xaf\xac\x65\x8a\xfc\x1d\x1b\x41\x6d\x39\x0a\xd5\xb4\x5a\x1a\xd5\xcc\x4b\x00\xb4\xb2\x78\xfb\xe4\xb5\x9d\x52\xe6\x1a\x6a\x5f\xd0\x02\x41\xc6\xcb\xc3\x82\xd2\xd6\x21\xa3\xde\xd0\x02\x01\x9b\x33\x05\x60\xe3\x61\xfa\xab\x28\xf4\x1d\x1a\xf9\xc9\xc0\x02\x0f\x2b\xaf\x99\xe8\xd8\xee\x58\xe3\x12\x22\x02\x14\x7c\x0a\xdc\x57\xd6\x70\xc5\xb3\x80\xaf\x59\x4c\xc7\xed\x57\xb8\x7e\xc6\x67\x4a\xb6\x3f\x3a\x98\x49\x75\x3b\x94\x62\xaa\xb5\xde\x88\xc9\x48\xa8\xb1\x09\xaf\x4d\x49\x54\x92\x7a\xac\x58\xbe\xe9\x53\xbe\x0d\x8d\x7d\x71\xaa\x11\xd1\x1f\x1a\x87\xb1\x47\x7b\x91\x70\xbd\x73\x5c\xfc\x24\x49\xf0\x51\xb8\x2b\xc5\x9b\x0b\xee\x76\xa1\x72\xe8\xd3\x26\x70\xf5\x1d\xdd\xdb\x80\x4a\xd1\x10\xa5\x65\xe3\x84\xcd\xb7\x6f\xad\x04\xcf\xf6\x78\x93\x09\x1e\x41\xe6\x9c\xfd\xf7\x0e\xa9\x26\xc2\x63\x69\xa5\xb6\x19\x3b\x19\xab\x0a\x62\x55\x8d\xa5\x5f\xfa\xfe\xb8\x78\x97\x57\x71\x06\x44\xaa\x19\xf4\x74\xbe\x4a\xda\x9d\xc1\x84\x9b\x07\xd5\xe1\x7b\x85\xf9\x21\xe1\x01\x6a\x54\xaa\x60\x95\x77\x72\x53\xa7\x34\x26\xfc\x78\x64\xb9\x95\x5f\x04\x90\x70\x23\xdb\x20\x7f\x85\xdd\x21\xa6\x51\x06\xcf\x0d\x62\x23\x85\x87\x0c\x34\xc2\xda\x9a\x11\xe4\x72\x63\x95\x12\x1e\x4a\x67\x61\xfb\x52\x22\x29\xd9\xe5\xcc\x9d\xab\x35\xae\xb8\x7d\x0d\x79\x69\x3c\x00\x6f\xde\x1c\xfa\xf1\x16\x20\x8b\xba\x96\x20\x59\xcf\xc0\xd2\xd6\x37\x0a\xac\x77\x48\x36\x2e\xe6\xa0\xa3\xca\x7b\xf1\x33\xeb\xcf\xa2\x0f\x1c\x4e\xd8\x30\x7f\x80\x0c\xca\x7e\x6c\x4b\xea\xa3\xfb\x2a\xb0\x86\x12\x53\x64\x28\x5c\x44\xed\x1a\x73\x7a\x67\xcb\xf3\xb7\x63\xc9\xf8\xb1\x42\x7e\x89\xdf\xa9\x6d\x29\x0e\x9d\x48\x42\xfe\x63\x16\xaf\xef\x83\x4c\xd8\xcd\x1f\xdc\x1f\x12\x4c\xa3\xfe\x26\x26\x6d\xa6\x2e\x27\x5c\x0b\xf7\xfc\xc8\xe5\xf9\xbb\xa6\xc0\xd3\x8e\x23\xfa\xfa\xb1\xe0\x49\x48\x17\x94\xc1\x4f\x4a\x8c\x53\xbe\x1c\x96\xf7\x69\xc9\xb1\x3e\xac\xa3\x9a\x0e\x49\x36\x6d\x2c\x9f\xfe\x8f\x20\x63\x60\xa9\xd5\x03\xde\xc5\x98\x62\x11\x12\xe3\x77\x67\x13\xe7\xfc\x06\x49\x43\x3e\x25\x7e\x50\x3a\x54\x60\x59\xa9\x89\xda\x89\x15\x7d\x76\x47\x60\x05\xfd\x90\xe4\xb0\x7a\xaf\x0d\xb0\xbc\x0b\xc0\xb6\x7d\xb8\xdc\xba\xdf\xf3\x93\x74\xe1\xaf\xae\x55\x16\x34\xe0\xe3\x28\x31\xad\x0e\x5f\xa7\xd5\x21\x6f\xa7\xc6\x44\xf7\x3e\x1e\x8e\x07\x23\x83\x94\xa4\x16\xc1\x69\xaa\x9d\x53\x03\xf4\x69\xa5\xd4\x07\x43\x08\x72\x1f\xfd\xde\xff\x65\x59\xe5\xad\xf0\xc2\x77\x3b\x3f\x52\x64\xe7\xaa\xa8\xc2\xdb\x88\x8e\x28\xe8\x15\xc7\x10\x69\xc3\xb4\xce\x6c\x29\x03\x4c\x0a\xb3\xb5\xc1\x9a\x80\xa9\xd8\xc2\xe8\x74\x81\x35\x31\xc4\x22\x75\x2a\xd6\x2b\x3c\x5a\x1a\x3d\x6c\x5a\x5d\xb5\x87\x27\x06\x93\xaa\x75\xd5\xf1\x72\xee\xdd\xf4\xeb\x83\x9b\xd7\x93\xaf\xfb\x1c\x79\x6a\x1d\xf0\xe4\x42\xdd\xf9\x9b\x78\x0a\xa4\x1e\xea\x0f\xe6\xf8\x65\xbb\x53\x9c\xa5\x3a\xa4\x5d\xb9\xa8\x56\xcb\x75\xd0\x15\x1d\x35\xed\xea\x80\xf2\x94\x6d"}, +{{0xbd,0x3d,0xe1,0xa1,0xd1,0x64,0xbd,0x6e,0x9b,0xe0,0xa6,0xd1,0x07,0xf7,0x03,0xa6,0xdd,0x91,0x4c,0x86,0x67,0xcd,0x34,0x1d,0x13,0x9f,0x19,0x57,0x8d,0x93,0x3b,0x16,},{0x9b,0x02,0x49,0x64,0xbd,0xfa,0x85,0x2e,0xb2,0xd4,0x14,0x4f,0x35,0xb7,0xcd,0xc2,0x67,0x81,0x14,0x3c,0x2b,0xd7,0xf6,0x60,0x23,0x3f,0x8b,0x8a,0xa3,0x60,0x71,0xee,},{0x13,0xcc,0x15,0x8f,0xd0,0x61,0x79,0x2f,0xce,0xd1,0x56,0x87,0x95,0x98,0x25,0x1d,0xd0,0x1d,0x57,0x5b,0x40,0x0f,0xe3,0xe3,0x9a,0x70,0x08,0x63,0xaa,0xe8,0xdb,0x1f,0x91,0x97,0xfa,0x50,0x1c,0x0c,0xf9,0x93,0xe4,0x4d,0x6a,0xc5,0x51,0x80,0xb8,0x69,0x83,0x8e,0x8a,0xe2,0x4b,0x21,0x4f,0xa3,0x5e,0x24,0x4b,0x7a,0x6c,0xff,0x6d,0x0d,},"\x17\x69\xfc\xdb\xf5\x12\x47\xed\x4c\x83\xa0\x0b\xbb\xf0\x2f\x44\x28\xda\x6f\xce\xdd\xd0\x16\x1a\x02\xfc\xcd\x15\x00\x97\x06\x65\xe1\xc7\x63\x0a\xd2\x2e\x3d\x97\x49\xc7\x92\xe7\x1a\x26\x0c\xff\xf6\x05\x32\x56\xe0\x2f\x5b\x47\xbb\xa1\x4b\x76\x1a\xe5\x3c\xa7\x21\x9e\xd2\x80\x1d\x2d\x78\x8e\x26\x41\x9f\x36\xc8\x1e\xf9\x2c\x23\x03\x68\x37\x35\xc8\xa1\x75\x6a\xda\xb6\xa4\x87\x92\x31\x53\xe4\x35\x60\x3c\x96\xb2\x39\x55\x3e\xdf\xde\xb0\x93\x29\x8f\x7a\xe7\xdc\x90\xf1\x6a\x7e\x56\x64\xb9\xe4\xc0\x2b\xa7\x31\xa2\x3c\xf2\x23\x4e\x25\x0a\xc9\x74\x26\x33\xa9\x32\xa9\x48\xbb\x83\xdc\x3d\x79\x4d\x05\x9f\xed\xf4\xec\x86\x18\xc7\x43\x3c\x5d\x8f\xe5\xe6\x2c\xf0\x7b\x57\x68\xc4\xd9\xb2\x61\xc7\x15\x36\x80\x4f\xe2\xe7\xca\x70\x98\x87\x65\x21\xd5\x76\x77\x36\x14\x24\xe4\x7f\x1b\x95\x92\x37\xf9\x07\x10\x42\x1f\x5b\xc4\xf1\x09\xf7\xd4\x89\xc7\x55\xe9\x4e\xef\xdf\xb3\xc8\x5b\x90\xec\x01\x31\x81\xa2\x3b\xb9\x53\x5f\xee\xa4\x94\x1d\x0a\x06\xa5\x40\xbd\x6b\x58\x8e\x55\xb7\xf3\x57\x57\x14\x9c\xa3\xe6\x40\x96\x5e\x1a\x0f\xf7\xf3\xc8\x25\x92\x59\x95\x7f\xf5\xda\xb9\xfb\x87\x32\xea\xe7\x19\xb6\x24\xa4\x49\x28\x78\x17\x9b\x5a\x83\xab\xe5\x1c\xaf\x02\x08\x3d\x73\x7c\xeb\x4f\xcf\x04\x2f\x2e\x60\xba\x02\x97\xac\x72\xb8\x7f\xe3\xe1\x4b\xa5\xfb\xc5\x4b\x48\x09\x10\x73\x89\x68\x23\xbf\xa2\x89\xce\x8e\x16\x87\x3b\x48\x81\x2c\x32\xbf\xea\x5f\xf6\xbb\x22\x1d\x1e\xa5\x46\x3d\x32\x5b\xbe\x31\x1e\x7f\xd1\xe7\x83\xde\x65\x0b\x79\x52\xea\xe4\x61\xd6\x3b\xc7\x47\x05\x22\xaf\x5b\x77\x89\xf8\xfc\x2e\xb1\x92\xd2\xcf\x77\x6c\x5c\x24\xb4\x4e\x29\xcd\xb0\xcc\xcb\x1d\x90\x36\x14\x38\xe4\x95\x0f\xf3\x4d\xbc\xb3\xcb\x0e\x81\xcc\x45\xf8\xd0\xff\x57\x09\x49\xf7\x80\x84\xe1\x06\x0f\xf5\x59\x4a\xd5\x16\xf5\x0f\x1c\xb0\xa7\x65\xe1\xc0\xe0\x38\xd5\x94\x3b\x93\x6e\x4a\x8b\x49\x33\x54\xe7\x9a\xbc\x91\x7b\xb9\x27\x12\x66\xee\xba\x77\xa9\x3a\x65\x7f\x9a\xd8\x7b\x29\x1a\xc7\xea\x38\x6f\x5d\x4f\xcb\xc5\x82\xe7\x2d\x5c\x23\xd9\x2b\xa9\x44\xb0\x06\x4c\x20\xe3\xe2\xdc\xf5\x04\xbc\xc7\xc6\x96\x6c\x63\xf2\x08\x08\x43\x60\x0b\xa3\x13\xec\x27\xcb\xa9\x5e\x7e\xf3\x18\x16\x8c\x90\x67\xdc\xe8\x6c\x1e\xf0\xd5\xd9\xeb\x7a\x61\x58\x48\x9d\xf3\x2e\xd5\x8b\x69\x31\x03\x08\x18\xf0\x07\x05\xa0\xdc\x55\xd3\xdb\xf8\x00\x6a\x85\x46\x64\x1b\x18\x65\xd9\x19\xbc\x24\x22\x02\xcb\x3a\xe3\x00\xbf\x86\x53\xe3\xb3\x78\x94\xc3\xdc\x0e\x47\x7b\x9d\x7c\x41\xba\xf8\xd3\x88\x7c\x2e\xb5\x9b\x1e\x4d\x50\xbb\xb6\xf1\x79\x2a\x1c\x93\x67\xc6\x5c\xdb\x45\x0c\x2d\xfa\x21\x45\xe6\x11\xa9\x7a\xd8\x1c\xff\x1f\xd8\x3c\x6c\xf7\x23\x09\x47\xea\xff\x4c\x21\xdc\x1b\xaf\xb7\x1e\xc4\x1e\x5b\xc7\x2b\x37\x45\xec\x3e\x38\xbf\x59\x30\xc1\x26\xd0\x60\xf0\xc5\x0a\x89\x5f\x00\x9a\xa1\x8e\x87\xf2\x17\x4f\x58\xab\x53\x79\xa7\x21\xfd\x83\xaa\xd5\x51\x7f\xd9\x9d\xff\x14\x6e\xde\xea\x61\x52\x12\x35\xe2\xf1\xa1\x6e\xe5\x83\x03\xe0\x91\xbe\x8d\x57\x90\x94\xc1\xd8\xa2\x0b\xc7\x4a\x55\x0d\x77\xc0\x0d\x08\x75\x71\x51\x7a\x63\xcd\x41\x26\x93\x3a\x4f\x09\xa0\x70\xbf\x8e\xa4\xff\xb8\x46\xa9\x78\x0e\x97\x34\x04\x3b\xac\x4c\x0f\xf4\x7b\x1a\xfc\xcf\x52\x93\xac\x14\xbc\x73\xeb\xf6\x71\x29\x65\x7e\x4b\x8a\x8b\x33\xdd\xac\x7b\x0f\x4d\x71\x9d\x2d\xc6\x5d\xf6\xea\x0a\x3f\x24\xcf\x44\xc8\x33\x8e\xd6\x01\xa3\x93\x9c\xa3\x58\xfc\x4b\xe1\x3e\x8e\xde\x02\x75\x39\x71\x2c\xa2\x3e\x3f\xfb\xa7\x06\xe8\xfd\xd6\x2a\x07\x4e\xe0\xad\x74\x20\xf7\x80\x60\xcc\x96\xfb\x2a\xbf\x30\xe9\xea\xa2\x41\xc0\xf8\x7e\xbb\xe3\xec\x73\x51\x75\x96\xf7\xc3\xc5\xa8\x0c"}, +{{0xf6,0xae,0x51,0x6a,0x51,0x29,0x6f,0xc5,0x23,0xce,0xa5,0xf0,0x08,0xcf,0xbd,0x09,0xe7,0x3f,0x78,0xb6,0xfd,0xd3,0xb6,0x94,0x26,0x12,0x80,0x41,0xa5,0x60,0x4c,0xf9,},{0x37,0x6c,0x82,0xba,0x7b,0x87,0xaa,0x77,0x41,0x87,0x27,0xdb,0x33,0xd3,0x26,0xae,0x75,0x8b,0xf7,0xa1,0x35,0xc1,0x04,0x60,0xcd,0x8b,0xf8,0xfe,0xb8,0x3c,0x2b,0x10,},{0x0f,0xe4,0xdd,0x7e,0x1f,0x60,0x8e,0xe8,0x2b,0x7f,0xe8,0x63,0xd1,0xb0,0x3a,0x81,0x84,0x3c,0xe2,0x0c,0x76,0x2c,0xd8,0xbb,0x24,0xef,0xd4,0x6b,0xa0,0x25,0xff,0xf3,0x33,0x1d,0x87,0x57,0x52,0xca,0x72,0x20,0xc5,0x3d,0xd3,0xc7,0x1f,0x2b,0xc1,0xe2,0xc6,0x4a,0x2f,0x9c,0x58,0x86,0x5a,0x2a,0x24,0x48,0x09,0xf4,0x13,0x4e,0x53,0x07,},"\x83\x42\xf2\x5a\xc4\xb1\x7e\xba\xd6\xf7\x9b\x9a\x03\x31\x75\xc7\xf2\x8a\xf0\x9e\x65\x8e\x8c\xb9\x8c\x29\x4f\x15\xc3\xc8\x34\x26\x29\xcb\x2a\x32\x47\xdf\xc8\x75\xb8\x2f\x5b\x38\x0c\x5d\x11\x42\x6a\x2e\xeb\x62\x45\x0b\xd8\x85\x65\x01\x07\xc6\x83\x62\xa3\xb7\x2c\xe8\x23\xf2\xd1\x59\x42\xb7\xdd\xa3\x01\xd2\xfb\x63\x8f\x30\x2a\xa9\x57\x0b\x47\x91\x1d\xad\xd3\xbd\xdb\xfe\xd5\x54\xc1\xc8\x0b\xd7\x18\x07\x8b\x8b\xd2\xc9\xc3\x14\xa5\x16\x6f\x26\x5e\x82\x66\xee\x2d\xb3\x57\x56\x1a\x55\x85\xc4\x14\xa7\x84\x0b\xfa\xe6\x09\xd7\xcd\xdd\xe1\xfa\xde\x85\x56\x0f\x23\xd6\x38\xef\x3d\x52\xe5\x1f\x5c\xf3\x13\xa0\x72\xc5\xea\x0f\x81\x7f\x72\x81\xe2\xcb\xa5\xc5\xc8\xd2\x6c\x92\x85\x92\xb8\x1f\x0f\xf8\xcd\x18\xdb\x5a\x2c\x41\xd8\x80\xd7\x44\x73\x86\x3c\x7b\xbd\x00\x56\xfa\x4d\x4a\xfa\xbd\x17\xa3\xb8\x9d\x97\xd3\xfe\x5d\xc0\x6b\x0f\x61\x2a\x1d\x66\x42\x39\x23\xba\x8d\xfb\xb8\xec\x82\x46\x62\x4d\x83\x78\x4e\xba\x4f\x57\x36\xba\x38\x5e\x44\x22\x96\xc8\xcb\x0f\x1b\x68\xe0\x33\x42\xb2\xc6\xc1\x03\x34\x6f\x6d\xd7\x40\xe2\x6c\x3d\x13\xca\xef\x80\x1d\x1b\x26\x21\xd8\x9f\x06\x93\x91\xa0\x78\xd4\x3a\xe6\xff\x12\xee\xca\x66\xbc\x32\x63\x7b\x45\xf0\xac\x62\x7c\x2d\x7b\xbf\x8a\x49\xd9\x46\x81\x75\xe2\x68\x85\xe0\x28\x21\xd3\xa3\xba\xa2\xc3\xe3\xa6\xbb\x96\xb5\x75\x26\xe2\x24\xcf\x3d\x85\x9f\x66\x95\x73\xcb\xd5\xc8\x73\x93\x74\x61\x56\xf3\xd1\xc7\xa8\x03\x08\xdc\x1f\x24\x05\xbf\x0d\x40\xbe\x1c\xa7\x3b\x76\x7d\xed\xf4\x03\x13\x37\xc0\x81\xbf\xa3\xae\x6e\x54\xf6\x02\x3f\x42\xf0\xcb\xd8\x77\x62\xdb\x55\x91\x3c\x70\x72\x06\x03\x40\x10\xdf\x2a\xa8\x75\x3d\x03\x0f\x03\xc2\x67\xe7\x1a\x9d\xd2\xc6\xc1\x9d\xe3\xe1\x85\x1a\xbf\xac\xbb\xd5\xdd\x5b\xf8\x96\xfa\xb8\xe4\x15\x31\x7b\x49\xf1\xe4\x09\x6e\x3d\xa9\x9a\x5b\x5d\x0a\x3c\x42\xda\xf9\xde\x94\x84\x7c\x1e\x53\xc8\x81\x8a\x5b\x84\x33\x23\xf5\x01\xe3\xa7\xfa\x68\xdf\x89\xa5\xf4\x1f\x2c\x62\xc3\x8d\x17\xf2\x50\xb0\x2a\x67\xfa\xe4\x7d\xaf\x06\x3f\x55\x89\x42\x37\x7e\xf8\xa8\x90\x52\xf1\xa2\x15\xd7\x68\xf7\x91\x3a\x7e\xc1\x4e\x98\xb8\x1e\x4b\x2c\xcf\x26\xba\xca\xd6\xf3\x96\x64\xaf\xc0\xe9\x1a\x3c\xad\x69\x1d\xb2\xbf\x56\xa7\xab\x66\x77\xb4\x95\x96\xdb\x88\x7c\x97\xde\xf4\x35\x08\xa7\xa2\xec\x2a\xb7\x55\xec\x36\x8e\x2e\x53\xd1\xe1\x6b\x60\xff\xf0\x9c\x3b\x52\x26\x3f\x0f\x7c\x1e\xa9\xcc\x35\x37\x31\x97\xe9\x5c\x11\xe6\xd2\x2f\xa9\xd8\x29\x9c\x42\x37\x36\xf5\x81\x4f\x1e\x79\x8d\x22\x75\x18\x60\x0d\xf6\xa7\x90\x35\x8d\xea\xe3\x8d\x56\x39\xe1\x98\x3f\xe0\x18\x43\x6e\xa5\x8b\xa8\x46\x75\x48\xc9\x29\xef\xbb\x16\xdf\xea\x41\x02\x25\x3a\x35\x0f\xb8\x4d\x98\x31\xc4\xc2\xcb\xcb\x76\xe1\x8d\x7f\x3e\x95\x36\x41\xad\xa4\x14\x21\x39\x30\x91\xe6\x3d\xfe\x66\xde\x24\xc9\x92\x32\xc7\xd6\xa2\x83\x7a\x48\x98\x3c\xf5\xb1\x63\x31\xce\x00\x05\x0d\x1c\x71\x39\x58\xff\xce\x5f\x2e\x93\x48\xc5\x2f\x53\x12\x05\x79\xa7\xc9\xa1\x60\x08\xd1\x34\x83\x8e\x59\x61\x29\xc7\x02\xfc\xd2\x11\x48\xbd\xf9\x17\x4d\x48\xe2\xda\x0a\x8a\x66\x35\x9e\xde\xe0\x1c\x50\x09\xef\x67\x42\xfe\xc4\x1c\x1a\xce\xcd\x03\xef\xe1\xcc\xc9\xb1\x30\xd6\xe5\xac\x92\x57\x6a\x85\xcc\xb7\xcf\xc7\xd0\xe4\x23\x31\x06\x17\x29\x31\xa0\x86\x99\x79\x0b\xc4\x1a\xcf\xbb\x73\x1a\xdb\xb2\x6d\x56\xb3\x9a\xaa\x5b\x33\x3b\xc1\xa1\x0e\x2c\x70\x64\xca\x86\x11\x9d\x8c\x71\x71\x48\xf9\x24\x41\xaf\x24\xcd\x2a\xa8\xf5\x7c\x86\xba\x38\xa5\x9a\x10\x0b\x92\x76\xdf\x38\x27\xec\x7f\xb4\xd3\xfa\xf5\x8b\xe3\x1c\x6e\xca\xfd\x69\xcf\x1c\x64\x10\xa4\x9c\xd7\x08\x1f\xf6\xe9\xfc\x39\x7c\x2d\x20"}, +{{0x83,0xf7,0x89,0x90,0x0f,0x04,0x0d,0xc6,0x2f,0x4d,0x18,0x78,0x4c,0xb6,0x4b,0x63,0xc8,0x8e,0x8d,0x18,0x00,0x16,0x96,0xbb,0xeb,0x47,0x07,0xc4,0x69,0xd1,0x1a,0x5b,},{0xed,0xfc,0x2b,0xab,0x7e,0x79,0xf4,0x00,0x37,0xfe,0x4d,0x90,0x41,0xde,0x48,0xda,0x9a,0xee,0x8f,0x97,0x80,0x98,0xd7,0xb0,0xae,0x17,0x92,0x90,0x25,0xe4,0x27,0x3d,},{0xea,0x65,0x82,0xcc,0x23,0xe0,0x46,0x09,0x17,0xf7,0x82,0xd9,0x64,0xe3,0xbb,0x6d,0xcd,0xe0,0xae,0xea,0xc4,0x2c,0xc1,0x49,0x19,0xd3,0x6c,0xe7,0x8a,0xa0,0xaf,0xd9,0x80,0x72,0xf5,0x4c,0x79,0x5f,0xbf,0xd7,0xa4,0x1d,0x99,0xd7,0x06,0x06,0xc2,0x8a,0x5d,0xcf,0x19,0xbe,0x38,0xa0,0xce,0x2d,0x09,0xbb,0x8f,0x84,0x4c,0x31,0xbf,0x00,},"\x6c\x11\x2a\x20\xd3\x06\x57\xab\x5f\x8c\x5c\x04\x47\x8d\x6c\x42\xd1\xc6\xbd\xef\x38\xcd\x4f\xe0\x06\xac\x2a\x57\xe2\x90\xff\x29\x28\x78\x96\xee\xa8\xc3\x0a\x01\x39\xc1\x8f\xc8\xc9\x75\x64\x56\x3e\x86\xc8\xd3\x40\x56\xa6\x71\x9b\xfe\x47\x9d\x9e\x87\xe8\x1b\x19\x45\x23\x31\xbf\xa1\x54\x80\x68\x82\xe5\x03\x9a\x20\xc9\xe9\x54\xb1\xfc\x7c\x01\x5d\xcf\x58\x15\xbd\x7c\xf7\xb6\x35\x7d\xf9\x28\x0b\x9b\xd4\x3f\x89\xff\xc9\x19\x45\x32\x3b\x5a\xcb\x2a\xe0\x02\x54\xd4\x16\x28\x68\xd1\xc8\x3e\xc6\xe0\xfc\xbe\x7a\x8a\xb9\x25\x41\x92\x14\x9c\x6b\xc9\xe5\xfe\x35\x06\x94\x16\x5d\x66\x38\x33\x1e\xb2\x4e\x3b\x13\x90\xc6\x98\xc4\x83\x83\x78\xc0\x1b\x2c\x61\xa3\xeb\xe2\xc0\x60\xb9\x8b\xa6\xee\x02\xb5\x19\xb4\xea\xc1\xe0\xbc\xc0\x9b\x23\x24\xcc\xf5\xb1\xa7\xfe\x8f\xd0\xb1\x54\x5a\x94\x27\x83\x2a\xbb\x25\x74\x4e\xeb\x36\x32\x6b\xe6\x4e\xfe\xd3\xa7\xb0\x7d\x63\x0a\x21\xc3\x08\x1b\x55\x26\x1c\x35\x32\x87\xc6\x6c\x57\x66\x3a\x99\xdb\x46\x6a\x5d\xee\x22\x74\x6b\x81\xc7\x50\xef\x85\xbe\x51\x14\x3e\x22\x1e\xcd\xf1\x14\xfe\xf1\xb3\x08\x2f\xf5\x4f\xd0\x44\xbc\x88\x4b\xfb\x3c\xc5\xc5\x33\x59\x97\x00\x98\x67\xce\x94\x91\xa8\x0f\xe6\x96\x82\x5f\x99\x42\x6d\xef\xab\x6a\x49\xba\xdc\xde\x40\x3f\x58\xe8\x31\x79\x66\x21\x07\x47\xb5\x67\x75\x4d\xe5\x30\x76\xb3\xec\xbf\x65\x34\x6c\xb8\x39\x05\x83\x2e\x16\xd0\x1b\x50\xb9\x3d\x37\xeb\x9b\xfe\x20\x17\x2a\x31\x63\x0d\x25\xf3\x21\x7d\x87\xd9\x34\x65\xfd\x8a\xc5\x54\xcb\xbb\x39\xd9\x82\xea\xd7\x21\x93\x91\x23\x4c\x88\x9f\x0b\x92\xa2\xe0\x41\x3d\x86\x6c\xac\x08\x7d\x62\x8c\xe3\x1c\x61\xc6\x32\x3e\xcb\x8e\x68\x95\x55\xaf\x10\xde\x2b\x65\x6e\x6a\xea\x2c\xde\x93\x2e\x24\x1f\x6d\x1f\x8a\x9e\x33\x16\xcf\x13\xf1\x35\xac\xef\x83\xa0\xc0\xcf\x22\xf9\x5c\xa8\x18\xe6\x1f\x92\x76\x87\x74\xc6\x30\xe0\x92\x5b\xe9\x9d\xbd\x32\xb4\x99\xc0\xfe\x7d\x84\xa4\x2e\x39\x32\x87\xf6\xf5\xce\x3d\x0b\x27\x1f\x17\x00\x45\xa6\xd4\x8e\xab\x31\x6f\xe1\x7b\x18\x58\xb1\xff\xee\xe9\x08\x88\xf3\xa3\x7a\x24\x80\xdf\xd0\x4a\x4a\x86\x29\xf8\x68\xb5\xc0\xa8\x0e\xe1\xf0\x37\x19\xf3\xa4\x7d\x40\x95\xbe\xf1\x0e\x02\x34\xfc\x30\x0e\x2a\xf4\x82\x28\x5d\x78\x93\x79\x68\x31\x9d\xa9\x4b\xeb\x6c\x40\xe0\x78\x57\x7c\x02\x4f\x3a\x5c\xda\x00\x84\xe2\xf8\x55\xa9\x39\x6a\xaa\x9e\xe9\xbf\xaf\x2c\xc7\x71\xfe\x68\xc4\x0b\x62\x9e\x8d\xcf\x11\x5e\xf0\x3e\x75\x7a\x2a\xc9\xee\xf0\x73\xf1\xbd\xf9\xc5\xa4\x41\x00\x31\x55\x8a\x6d\x38\x2b\x5f\x16\x02\x4b\x15\x1b\x1c\x01\xee\x78\x17\x41\x3a\x3c\x4d\xe9\xdd\x64\x78\x78\x5b\x81\x10\x1d\xf5\x52\x24\x30\x05\x87\x80\x20\x7e\x79\x0f\x61\x2d\x78\xe5\x70\x5c\xee\xd4\x6b\x0e\xc0\x75\xe7\xc1\xdc\x07\x3b\x17\xb2\xb4\x3d\x72\x53\x59\x27\xbf\xd2\x71\xe9\x2e\x3c\x93\x63\x8e\x40\xa9\x60\x1d\xc2\xc1\xab\x76\xd9\x1a\x41\x03\xdf\x65\x7d\x91\x1c\x82\x9e\xe8\xa5\xf7\x47\xf7\x64\x2f\x5a\x91\x5a\x5f\x40\xf6\x30\xb4\x30\x39\xc7\xd4\xbd\x2a\xd2\xb3\x21\x29\xd9\x4e\x5b\x2f\x03\xad\x4a\x3d\x45\x57\x7e\xb8\x1f\x36\x9c\x9e\x3e\x2a\x4f\x6a\x8e\x41\xac\xf8\x28\x3b\xe5\x84\x25\xea\x99\x3b\x8e\x98\xee\xa6\x33\x05\x56\x64\x86\x18\xda\xd9\x8f\xa2\x55\x62\x0d\x83\x6d\x3c\x7f\x29\xb9\x07\x89\x58\x49\x28\x61\x67\xc7\x18\x1e\x2c\xaf\x55\xc2\xc1\x84\xa9\xa9\x11\xf8\xe4\x1c\xb0\x42\xe2\xcd\x48\xb0\x54\x4e\xa7\x9f\xe2\xef\x38\x1e\xbc\x5b\x15\xe3\x9a\x9b\x5c\x6d\x99\x8f\xae\xaa\xa7\x77\x3c\xfe\xc0\x84\xc0\xbf\xae\xd1\xbc\xab\x96\x3a\x4e\xf3\xd9\x4d\xbb\x3d\xfe\x72\x4c\x04\x0c\xe4\xd1\xe2\xee\x7f\xc2\xda\x4b\x25\x12\x7c\xe3\xa5\xdf\x69\x3f\xcf\x5a\x6e\xd1"}, +{{0x43,0xbf,0xf3,0xcd,0xd5,0x30,0x7e,0xd7,0xd2,0x5c,0xf9,0x6f,0xdb,0xba,0x64,0xab,0x18,0x11,0xc8,0xbb,0x93,0x4e,0x21,0x87,0xea,0x7f,0xfc,0x01,0x8d,0x85,0xe0,0xf2,},{0x00,0xf1,0xb5,0xd3,0xca,0xc6,0xe5,0x6c,0xa5,0xf8,0x94,0xd4,0xcd,0xbf,0x9b,0xeb,0xd9,0x68,0xd2,0x4d,0x5e,0xff,0xa5,0x05,0x8b,0x0e,0x20,0xbb,0x08,0x98,0xf6,0xf1,},{0xa6,0xb5,0x6b,0x76,0x86,0xdf,0x1d,0xc5,0xf4,0xed,0x54,0x4a,0x4d,0x97,0xe6,0x70,0x36,0x19,0x5a,0x32,0xb2,0x2e,0xcd,0x5d,0x31,0xea,0x17,0x30,0xe6,0xed,0x8f,0x81,0x0d,0x25,0x8b,0x44,0xc0,0x8e,0xa4,0x5f,0x03,0x2b,0x93,0x74,0x41,0xb7,0x2c,0xd0,0xdc,0x37,0x55,0x6f,0xd7,0x87,0x4e,0x9f,0xe6,0x4f,0x15,0x76,0x5c,0x52,0x10,0x03,},"\x64\x6f\x8b\x34\x18\x2d\x5e\x60\x2b\x51\xca\x73\x29\x34\x7c\x0e\x19\x8c\xb7\x47\xe4\xda\x0a\x6b\x80\xf3\xf6\xf9\xf3\x36\xf6\x70\x8d\x85\xcb\x42\x9a\xb2\xd6\xbe\xd3\x5d\x50\x13\x12\x9c\xd1\x00\x14\x2c\xdd\xce\xe8\x63\x51\x79\x02\x1b\x3e\x24\x92\x2b\x81\xae\xf1\x3c\x13\x70\x28\x69\x39\xd6\x3d\x6b\x6a\x41\x95\xed\xa1\xd8\x12\xca\x51\x82\x04\x76\x8f\x87\x34\x8c\x68\x89\x55\x2c\x63\xd1\x37\x2c\xde\x6a\x5e\x9d\xaa\x7f\x84\x45\xec\x8d\x61\x30\xa3\xf5\xae\xf0\xed\xea\xce\x01\x0b\x6c\x7f\x0b\x9d\x24\x16\x2a\x8d\x04\x45\x4b\x81\xd4\x8e\xa9\x09\x7b\xd8\xdf\x09\x34\x59\x71\x9c\xcb\x54\xaa\x10\xf5\x1c\x24\x6a\xa9\x9c\x58\x0b\xea\xf9\xc9\xc5\xbc\x60\xfa\xf0\xae\x5c\xec\x7f\x51\x37\xf6\xc5\xc1\x44\xdf\x45\xd1\x2e\xe9\x95\xad\xcc\xf2\x5a\x9d\xb8\x1b\x85\x58\xbd\xfb\x65\x83\x01\x86\xe7\xb9\xd4\xee\xd9\xf6\xb4\xd7\x32\xb1\xb5\x82\x2d\x03\xeb\x01\x7c\x07\x24\xf4\x8f\x87\xba\xaa\xe1\x04\x5d\x6f\xdb\x12\x5c\x91\x34\x06\x4f\xaf\x18\xdb\xed\x58\xd8\xfb\xac\xea\xcd\x4f\x09\x7d\xf9\xb3\x42\xe5\xc4\xa5\xbc\x85\xb2\x95\x97\xd4\xb6\x40\xf1\x55\x1c\x5b\x62\x4a\xb2\x1b\x48\xe9\x4a\x90\x30\x04\x9b\xe1\xf0\x5a\xa8\x51\xd0\x82\x7e\xaf\x87\x00\xdf\xe1\x47\xfd\xcd\xee\xdb\xc9\x8c\x4f\x15\x77\x4f\x01\x20\xfb\x59\x70\xa2\xf8\xb2\x17\x94\x34\x0b\x62\x83\x79\xa8\x02\xb9\xf7\xc0\x68\xb0\xdf\x63\x19\x3e\x51\x0f\xc7\xb2\xaf\x97\xee\x38\xde\x47\x92\x97\x85\x53\x55\x28\xd3\x50\xd8\x86\x20\x61\x0c\xfd\xb5\x5d\x24\x9e\x38\xfb\x73\xc8\x28\x71\x13\x91\x9c\xe3\x32\x67\xd7\xdb\x92\x4e\x49\x19\xa4\x4e\x6e\x29\xa9\x0d\xbe\x3b\x7b\x0d\x39\x21\x16\x3f\xeb\x5a\xc1\x05\x62\x4e\xd8\x52\xbe\xce\x35\x38\xe9\x91\x93\x30\x0c\x89\x33\x45\x69\x93\x50\xa8\xf9\x9e\x8c\x6a\x41\x09\x5f\xc9\xfc\x08\xda\x07\xf7\x57\x11\xf7\xdf\x03\x44\x06\xde\x14\xed\xd8\xe2\x2a\x63\x3a\x86\xe4\xa5\xa5\xc9\x75\xac\x5d\x34\x89\x1c\xcc\xfc\x85\x43\x77\x1f\xfa\x08\x0e\x0b\x45\xd6\x5a\xb8\x30\xa3\x61\xac\x4c\x42\x62\x94\xd3\x68\x5e\xa8\xc2\x60\x39\xc7\x1c\x90\xfc\x3f\xb5\x12\xbe\x9f\xc9\x48\x07\xd7\x6d\xbd\xaf\x8f\xfa\xa4\xfb\xf9\x84\x9d\x68\xe8\xa5\x7d\x30\xc4\xa0\xb9\x73\x5c\x23\xf0\x8e\xf2\xe2\x84\x45\x84\x67\xe1\x5d\x66\x53\x62\xcb\x64\x6f\xde\x69\x37\xec\xba\x53\x09\x12\x64\x63\x83\x57\xa7\x22\x42\x5b\xc6\x2d\x1e\x30\xec\x5f\x0d\xd8\xfe\xa2\x6b\x2e\xa4\xa8\x49\x00\x35\xde\x43\xf2\x74\x84\x6f\xb0\xcf\x02\x09\xec\x74\x37\xf3\xc3\xd0\xa5\x60\x37\x3d\x03\x4e\x5f\xd7\x9e\x25\xb6\x42\x4d\x9b\x2c\x17\x61\x63\x2b\x35\xa1\x21\x32\x52\x18\x27\x34\x5c\x55\xe4\xe7\x14\x2d\xd6\xfe\x94\xd6\x20\xfe\x51\x5c\x15\x3e\x83\x95\xb5\xd1\x30\xc7\x44\x13\x9b\x6a\x92\xef\xd3\x7f\x22\xba\x13\xfe\x4c\x09\x53\x73\x55\x0e\x2e\x4f\xcb\xa0\x32\x5b\x3e\xa3\xb9\xfe\x25\xcc\x7d\xd9\x2c\xbf\x42\xe1\x5f\x45\x54\xb7\x7a\xc2\x7a\x4a\x34\x63\x82\xff\x61\x00\x45\x15\x08\xd6\x02\xcf\x64\x3f\x60\xb6\xca\x42\x86\x35\x6f\x21\xa3\x11\x0d\x4e\x2c\x8a\x89\x62\xa7\x80\xfc\xff\x43\x9b\x3a\xa8\x04\x99\xdf\x27\x0f\xc3\xe6\xca\xd8\x89\x33\x48\x87\x2f\x0f\x70\x2f\x93\x90\x00\x0c\x7f\x6e\x06\x27\xd2\xbb\xb7\xb7\xce\xf5\xc4\xda\x25\xda\xdf\xea\x80\x32\xe5\x02\x32\x97\xa7\x0a\x65\x8e\x9a\xe7\x3b\xdd\xc3\xb2\x27\xa1\xc1\x17\x41\x13\x3f\x01\x2f\x0f\x48\xfe\x26\x44\x6f\xa6\x7e\x64\x72\x0f\xc8\xdc\x97\xf3\x0d\x0d\xd0\x26\xf6\xdc\x21\x64\xea\xd8\x57\x82\x4a\x0a\x7a\xeb\x20\xf1\x15\xd5\x0d\x1b\x65\xdd\x5d\x82\xe0\x9a\xbe\x83\x4e\x8c\xa8\x89\x57\xe3\x99\x84\x82\x49\x55\xa1\xa1\x3e\x3b\x94\xa0\x01\x57\x18\x6d\xcd\xc2\x89\xe3\x4b\x67\x8c\x91\xcb\x2a\x1a"}, +{{0x06,0x3b,0x90,0x25,0xe3,0x21,0xe9,0x72,0xd6,0x53,0xa0,0x62,0xbe,0x34,0xf9,0x93,0x65,0xaf,0xfd,0xcc,0x98,0xec,0x9f,0xf4,0x3e,0xf4,0x22,0xbe,0x0f,0x80,0x44,0x60,},{0x10,0xd0,0x1a,0x63,0x01,0x2a,0xc0,0x99,0x56,0xba,0x9e,0xd6,0x1d,0xf3,0x5b,0xb7,0xaf,0xe3,0x65,0x8b,0xb3,0x00,0x48,0x52,0xe4,0x71,0x74,0xbd,0x07,0xdd,0x4d,0xe7,},{0x85,0xc8,0x1d,0x6b,0x0d,0x85,0x78,0xfa,0x58,0xe1,0x3a,0xb3,0x91,0x00,0x15,0x28,0xb4,0x6a,0x1d,0x63,0xa0,0x32,0x7c,0x7a,0x4a,0x04,0x08,0x7f,0xc6,0x68,0x75,0x8a,0xa6,0x5c,0x01,0xd5,0xa1,0x50,0xf9,0x35,0x67,0x4e,0xf3,0x07,0x50,0x7e,0x6f,0x4c,0x91,0xe1,0xfc,0x35,0x00,0xb2,0x6f,0x64,0x9b,0xee,0xa8,0x7d,0x27,0x56,0x37,0x04,},"\xa7\xee\xd2\x96\x52\x84\x4e\xe0\x04\x9b\xaf\xb2\xcf\x63\x40\x29\x71\x02\x0d\x7e\x65\xc1\x0b\x91\xac\x57\x26\xee\xa8\x6f\x40\xdb\xc5\x3c\x3f\x0a\xbe\xde\xba\xf6\xcc\x44\x9b\x4f\xea\x48\xc0\x15\xfe\x4d\x90\x7b\x3e\x55\x05\xcf\xf5\x0a\x12\x18\x19\xa2\xe4\xa8\xa2\x96\xd5\x75\x10\x15\xbb\xcd\x7e\xf6\xfb\x7c\x27\x27\xbb\x00\x0b\xe1\x34\x2a\x7d\x14\xbc\xa9\x79\x04\xed\xfe\x8b\x18\xdd\xb6\x39\x33\x41\x83\x27\xa5\xaf\x81\x7e\x95\xba\xd7\x4e\xb7\x90\x20\x36\x15\xd0\x82\xe7\x14\x93\xea\xd4\x7c\xcc\x09\x01\xa2\xca\x9f\x50\x13\x3c\x44\xef\x85\x08\xd5\x1f\xb7\x3c\x61\x6f\x01\x47\x53\x22\x45\x82\x2d\xd1\x02\xb3\x37\xa1\xb2\xaa\xe2\xef\xc7\x2d\xca\x7a\x94\x19\xd5\x98\xa6\x47\x52\x33\xdc\x1a\x4e\xe0\xec\x6d\x05\xda\x12\xa2\xb2\x87\xcb\x77\xff\xaf\xdd\xe2\xd0\xac\xc2\x81\x99\x93\x3e\x66\x21\xee\xc1\x6a\xb4\x24\x51\x70\xcf\x02\xda\x80\xd4\x92\x26\x31\xa2\x32\x72\x91\x51\x65\xad\x88\x72\x27\x50\x03\x5d\x2a\x09\x77\xbc\x79\x1d\x14\xfb\x3d\x8c\xb0\x2b\xc7\x7f\x7c\x71\xbe\x52\x42\x62\x9a\x4c\x9a\x58\x8d\xfd\xde\x95\x78\x49\x4d\x8b\xaa\x4e\x68\xf5\x19\x4b\x80\x02\xc8\xe3\x78\xa0\xe8\x33\xb7\xc1\xa9\x69\x81\xc4\xfb\x05\xe4\x57\xff\x48\x26\x0b\x72\x49\x3c\xbc\xb8\x2a\xe1\x16\x73\xd1\x4c\xee\x85\x28\x8f\x63\x70\xbd\x4b\xca\x92\x51\xa7\xe2\x14\xc3\xeb\x79\xe7\xbb\x6f\xce\xbb\x16\xc9\xe0\x56\xf2\x9b\x62\x72\x74\x3e\xfa\x6f\xe8\xbf\xd2\x55\x97\xce\x86\x89\x8a\xb3\x05\x9e\xb0\x23\x1c\x73\xb5\x30\x59\x03\xfd\x13\x19\xbd\xf4\x9e\x59\x9d\x8b\xbc\xd7\x4a\x8b\x97\x67\x30\x8b\x61\x56\x3c\xcb\xac\xd3\x8f\xc5\x0c\x83\xab\x44\xca\x75\x9d\xc9\xb6\x5b\x2a\x4b\x54\x7c\x50\x97\xf2\x20\xc1\xc8\x8b\x2b\x0a\x48\xf6\x5f\x91\xfe\x78\xb1\x50\x12\x78\xe1\xe3\x04\xde\x58\xb4\xc8\x2a\x5c\x39\x99\x81\x09\x8a\x17\x84\xeb\x90\x42\x50\x18\x59\xf2\xa9\x3f\x31\x7e\x41\x77\x2f\xd5\x2f\x97\x2e\x51\xb0\x7e\xd9\x4d\x31\x4e\x1d\x1a\xf4\xed\x82\x90\x9a\x0b\xef\x67\x1f\x54\xb5\x5d\xb7\xb7\x0d\xa1\xf7\x18\xc8\xe6\x48\xae\xdd\x6d\xa6\x4b\x05\x77\x05\x26\xf1\x2b\xc4\x3f\x68\xb9\x55\x48\xda\xc5\x08\x09\xa6\x87\xdb\x97\xd7\x3f\x06\xf4\x7e\xd0\x88\x31\xb6\x0a\x28\xe9\x82\x92\x06\x32\x05\x8f\x0e\x6c\x90\xc0\x18\x7f\xf4\x45\x64\xf8\x1e\xfd\x8f\xd9\x3e\x32\x7b\xc6\xd8\x0b\x49\x0e\x08\x8b\x9a\x10\x03\x6c\x80\xdc\xda\xd4\x9d\x2b\xe0\x74\xfb\xba\x31\xe0\x6f\x71\x80\xe5\xad\x1c\x88\x23\xd6\x09\x66\xa9\xce\x15\x50\x3c\xe6\x0d\xd4\x0e\x91\xee\xf2\x35\x9d\x83\xd7\x0d\x98\x40\x1d\xde\x7b\xe3\xc6\xb0\x7e\x57\xd4\xe4\x7d\x04\x21\x76\x33\xd8\xe2\x63\xca\x34\x8f\x81\xfb\xe9\xa4\xa6\x2f\x45\xd7\x7c\x84\x3b\x6b\x1a\xd2\x84\x66\xd9\xda\xfb\x1b\x91\x0b\x34\x8e\xd8\x7c\x68\x6c\xab\x29\x2d\x48\x0c\x19\x1d\x18\x7b\x40\x4a\x9b\x1d\x13\x2b\xa4\xe2\x93\xd3\xad\xa9\x91\x72\xac\xc1\x21\xfe\x66\xb8\x45\xb9\x8b\x16\x0c\x58\x23\xf6\x01\xc7\x75\x8f\xb2\x6c\xae\xe8\x57\x01\x59\x5b\x2d\x52\xca\xa2\xf5\x68\x8a\xa2\xbf\x2f\x6c\x4b\xb6\x37\xf8\xe0\x0f\x49\xab\x6c\x26\xbc\x6a\xd8\x9e\x13\x67\xfd\x28\xe4\x91\x7d\x25\x08\x93\xa7\xb3\x2d\x39\x66\x0b\xde\x8d\xb4\x9f\x08\x6f\xb7\x39\xe5\x60\x12\xc3\x6b\xea\x0b\x26\xcf\x6d\x93\x57\x94\x0b\x00\xd5\xa4\x52\x8f\x90\x59\xaa\xf0\x86\x69\xe5\xf4\x6c\x99\x5e\x60\xf8\x87\xb5\xc4\xab\x88\xac\x74\x42\xed\x01\xa1\x4c\x6a\x42\x00\x6b\xaf\x1f\x34\x3f\xef\xe3\xe4\xac\xa8\x43\xa3\x24\xe1\x76\xb2\xfe\x7e\xc7\x88\x3d\x1c\xbd\x06\x8b\xc2\xfc\x96\x2f\xfa\x60\x24\x4f\x65\x4c\x77\xac\x56\x50\x81\x7d\xc0\x84\x46\x55\x45\xa9\x23\x0a\x74\x82\x6b\x0c\x50\xeb\x85\x25\x2a\x88\x6f\xf2\xb1\xaf\xea\xf8"}, +{{0x88,0x3c,0xc1,0x38,0x17,0x57,0xb0,0xfe,0x04,0x55,0xb7,0x7b,0xc9,0xcd,0x0d,0xd4,0x64,0xd2,0xb4,0xbf,0x0c,0x7a,0x3c,0x0c,0x2d,0xc7,0x75,0xfb,0x78,0xaa,0x37,0x32,},{0x83,0xa8,0xb6,0x69,0xcc,0xd0,0x12,0x45,0xce,0x3b,0x81,0x8d,0xcb,0x1b,0x58,0x8f,0x86,0x53,0x58,0x50,0xe6,0xc7,0x10,0xc7,0x92,0x17,0xfe,0x43,0x98,0x24,0xf3,0xfa,},{0xc7,0xcf,0xd5,0xc9,0xfe,0x93,0x0d,0x15,0xa1,0x1e,0xbb,0x34,0xe3,0x43,0x1f,0x48,0x9d,0xa0,0x10,0xeb,0x19,0x3e,0xdb,0xfa,0x6f,0x23,0xd5,0xd1,0x4d,0xd8,0xfe,0xab,0xd7,0x88,0x0d,0x2d,0x5a,0x56,0x00,0xd3,0x85,0x46,0xce,0x3b,0xc6,0x4a,0x86,0x29,0x1a,0x1c,0xe3,0x1f,0x27,0x2f,0xf0,0x20,0xdf,0x8c,0xb6,0xa0,0xfd,0x4d,0x3a,0x0d,},"\xff\xec\x29\x3d\x12\xea\x63\x6c\xa4\xc4\xa0\xa5\xe2\xdb\x15\x34\x26\x39\xc4\x76\x67\x4d\x2e\xbd\xab\x4a\xef\xd4\x04\x6b\x5d\xdb\x56\xae\xb2\x10\xc1\x19\xaf\xdf\xb8\xa8\x91\x28\xa3\x4f\x6d\x77\xf2\x61\xed\xea\x07\x72\xa2\xf8\xdb\x14\x0a\x26\x40\xfd\x8e\xca\xdb\x0b\x47\x92\x16\x9b\x6b\x28\x10\xae\xe2\xc5\xcd\x83\x52\x88\xbf\xf4\x93\xbc\xeb\xee\xea\x28\xa7\xa2\x48\xc3\x61\x16\x54\x0f\xa7\x17\x36\xd6\x6b\x0a\x47\x5b\x5f\xa9\x2c\x0d\x46\x00\x2f\xca\x7a\x1e\x69\xd1\xb5\x9e\x81\xa3\xa6\xd4\xf3\x39\x76\x9d\xae\xb2\x0b\x5f\x9d\x75\xc4\xc2\x8f\x69\x21\x32\xd2\x8d\x3c\x56\x4c\x09\xfe\x3d\xcc\xa0\x35\x9c\x3c\x63\xec\x37\x7a\x33\xf9\xee\x87\x4d\x8a\x78\x9d\x77\xc9\x6a\xc0\x5f\xdf\x3a\xb3\x8b\x2c\x82\x74\xa9\x02\xef\x8b\xb7\xf4\x67\xfc\x7e\x07\x3c\x77\xb1\xdb\x5f\xc8\xef\x96\x6c\x12\x0c\x4d\xae\x3f\xb7\xf5\xb7\x4a\xbb\x99\x01\x66\xc8\x12\xa5\x25\xd1\x23\xf7\x6e\xd5\x12\x12\x50\x80\xa1\x53\x4f\x3d\x8b\xdc\xcc\x54\x1f\xc9\x75\x90\x28\x75\x46\x09\x6f\xc8\x80\xbf\xcf\xdd\x00\xe6\x5c\x0e\xbf\x4a\x09\xfd\x64\x76\xce\x1b\x7c\x8f\xaa\xa5\xa1\xcc\x27\x86\x71\x9a\x30\xd8\x25\x58\x11\x18\x47\x52\xa8\x8b\x08\xac\x9f\x0f\xf1\xd6\x26\x2f\x25\x86\x94\x0a\xfe\x1f\xe4\x5e\x0b\x56\x34\x48\xa5\x5f\x30\x30\xe4\xc3\x9c\x1f\x3f\x86\xa7\x33\x67\x03\x80\xea\xb0\x88\xe3\x93\xde\x09\xd1\xf5\x08\xd2\xfb\xca\xfc\x64\x9a\xea\xe6\xb8\xc3\x0e\x32\x9e\xc3\xfd\x28\x29\xbe\x6d\xb0\xab\x8e\x63\x7e\xa1\x09\x5b\xdc\x3d\xf3\xac\xc2\x3d\x3c\xf7\x05\xa9\x54\x2c\x19\xe5\x90\x92\xec\x41\x3a\x4e\x2b\xd5\xde\xd2\x8c\xd3\x4d\xdb\x3d\x32\x94\x9a\xa4\x87\xf1\xc3\x37\xd6\x97\x9c\xf5\x12\x62\x2d\xbf\xb7\xda\x1c\xbb\x1c\x7e\x5a\xbe\xea\x70\x09\xe2\x94\x3f\xfb\xa2\x25\x2e\x1d\x86\xec\xa9\xd6\xd5\xc2\x46\xcd\x2e\x13\x4a\x3e\x5d\xad\x37\xef\xef\x71\xce\x39\x7a\xda\xfb\xd9\xe7\x2b\x3f\x9a\x86\xff\x0f\x5d\x81\x2c\x46\x22\x5b\xeb\xd0\x70\x3b\xc5\xcc\xe9\xc6\x45\x82\x00\x8f\x7e\x55\x8c\x40\xa3\xb3\x52\x20\x96\xd1\xaa\x2b\x61\xbc\x90\xcd\x88\xc6\x28\x5d\x94\x20\x87\xd8\xa4\x66\x5a\x0e\x64\xd3\x57\x2f\x74\x68\x9b\x4f\x24\xef\x40\x0d\x74\x1b\x57\x14\x06\x13\x47\x14\x44\xde\xcc\x65\x4a\xf0\xff\xb2\xed\xfd\xf9\xfd\xd0\x75\x09\x81\x90\xb3\x4c\xde\x28\xdd\x16\x68\x72\xc6\x08\x65\x67\xa6\x87\x61\xce\xf2\x5d\xa4\x0b\xd4\xc3\xd3\x4f\xdd\xd7\x2e\xe5\x65\xb0\xb9\x37\x67\x8e\xe8\x43\x49\xd1\x16\x0f\x5f\x07\x05\xf8\x95\xd0\xf1\x41\xce\x8f\x51\xa1\xe4\xfd\x2d\xc4\x70\x4b\x52\x7a\x40\x25\xa9\x39\xcb\x2b\xb7\x88\x57\xeb\x18\xd7\x88\x72\xed\xc9\xee\x70\xe6\x0b\x2a\x42\x70\x0a\x19\x8f\x4f\xff\x6c\x31\x92\x51\x68\xbe\x07\x7d\xc2\x3c\x32\x2a\xbb\xca\x97\x36\x1f\xec\xaa\x3f\xcb\x19\x6e\x65\x6c\x12\x8f\x39\x82\xfe\x11\xe5\x51\xa4\xa0\x88\x5d\xa6\x0d\x39\x7d\x0e\x40\xd0\xd8\x97\x26\x2f\x1b\x4b\x67\x2f\x78\xa2\xd2\xad\xfc\xdd\x6e\x15\x25\xc2\x6e\x71\x95\xfb\x9a\xc6\x06\xbb\x1b\xa4\xa9\x89\x08\x03\xb4\xbd\x84\x34\x6a\xe8\xd8\xc7\x19\x6c\x90\xae\xcc\xb2\x96\xa4\xc3\xeb\x4e\xfa\xcb\xfc\xb6\x2e\x38\x3b\x8a\x49\x4a\xc7\x23\x56\x2d\x0d\x8c\x37\x91\x87\xa9\x2e\x3b\xda\x6b\x15\x69\x47\x6a\xed\x21\xae\xd7\xa0\x56\xb4\xa5\x82\x67\x44\x01\x7c\xc0\x06\x0b\x4d\x55\xfa\x87\x72\xb5\xb1\xc1\x5f\x57\x48\xad\x72\x98\x00\x5a\xec\xbc\xbd\x90\xa3\xe5\xc6\x15\x9a\x86\x74\xab\xbb\xa3\x79\x14\x41\x50\x02\xb5\xa6\xef\x5d\xf3\xc6\x49\x42\x6e\xa1\x27\x5a\x01\xd8\x0a\xdf\x49\x0a\xc5\x46\x06\x2d\x93\x99\x9a\x6d\xcc\xac\xb9\x6a\x09\x04\xad\x33\xd9\x05\x76\xdc\x6a\x21\xb6\x72\xe8\xff\xb0\x66\x13\xfb\x3f\x14\xe6\xcb\xdd\xe8\x8c\x24\x37\xc9"}, +{{0x5e,0x40,0xa7,0xaa,0xbb,0xb0,0x83,0x0a,0x9a,0xb0,0xfd,0x79,0x69,0x0e,0xe0,0x43,0x39,0x01,0xc6,0xcb,0x06,0x76,0xab,0xe4,0xbb,0xa0,0x6f,0x5b,0xbe,0x58,0xfa,0xc2,},{0x4d,0x4f,0x28,0xfe,0x09,0xc4,0xaa,0xbf,0xca,0x01,0xef,0x6e,0xe7,0xfd,0x63,0x72,0xfb,0x62,0xdb,0x61,0xaa,0xee,0x82,0x7c,0x43,0xfd,0x1a,0x6d,0x1c,0x25,0x90,0x32,},{0x59,0x76,0x72,0xab,0x8d,0x3a,0x60,0xde,0x54,0x56,0xfc,0xc9,0xc3,0x82,0x53,0xf5,0xf3,0x7b,0x80,0xe7,0x4a,0x00,0x7c,0x9f,0x6d,0xb9,0x09,0xd2,0x7d,0x0e,0xad,0x16,0x27,0x89,0x24,0x49,0x94,0xf3,0x5b,0x80,0xd6,0x1b,0xe1,0x99,0xc4,0x17,0xc7,0xea,0x90,0x1b,0x98,0xcc,0x63,0xfe,0x3c,0x50,0xfc,0x3c,0x63,0x38,0x49,0x0f,0xa2,0x06,},"\xfd\x4e\xc8\xb3\x4f\xc6\xb7\x43\x81\x3f\x59\xe2\xfd\x1f\xef\xa8\x70\xf5\xa9\x70\xe2\xeb\x75\x16\xef\x7c\x30\x6f\x4b\x82\x3f\xfe\xe9\x2d\x60\x1f\x76\x5d\x79\xca\x14\x6a\xba\x8b\xc6\xe7\x98\x44\x55\x99\x35\xcd\xdc\x24\x26\x49\xc0\x59\xec\xf2\xdb\x84\xfd\xc2\x19\x36\x66\x88\xa8\x8f\xc2\x5b\x85\x1c\x36\x61\xe5\x19\x88\xc2\xbf\x73\xbb\x8e\x3d\xc1\x6d\x22\x41\x5a\xb1\xa7\xb3\x55\x79\xda\xac\x73\x25\xe3\x19\x15\x7d\x7d\xa5\xfe\xe8\x7c\x93\xa4\xdf\xcb\xaf\xc9\x2f\xba\x7e\x17\xcc\x68\xe3\x90\x37\x33\xc6\xc8\x01\x57\x2d\x90\x73\x20\xb2\xfe\xb5\x17\x10\xe8\x56\xa1\xf7\x6f\x85\xa7\xee\x1a\x11\xe6\x2d\x2e\x45\xa3\x52\x93\x8d\xd8\xcf\xc2\xbc\xcb\x90\x2d\xea\x44\x4f\xaa\xae\x6d\x84\xc5\xf3\x91\xe1\x0a\xef\x76\x92\x8a\x45\x15\x3d\xb6\xcd\x25\xa2\xbf\x35\x3d\x80\xd9\x7b\xf4\xb3\x80\x86\x05\xe8\x98\x00\xd2\x98\x40\xea\x60\x97\x8d\x9e\xc9\xb2\xc3\x02\x74\x98\x88\xf9\xde\xbc\x84\xdd\x1e\x2a\x79\xaa\x0b\x6b\xa0\x2a\x03\x91\x93\x08\x1b\xdb\xff\x05\x99\xa1\x4d\x91\x8c\x0c\x8d\xea\xc4\xf6\x0b\x6e\x99\x47\x4a\xb5\x30\x11\x74\x10\x34\xfe\x2a\x20\xcf\xf4\xe0\xf0\x23\x42\x4c\x8e\x57\x97\x76\x8a\xd5\x3d\xf6\xd0\x1a\x24\x01\x1f\xa9\x0f\x0b\xb1\xd5\x06\x9c\xdb\x36\xb4\x50\xf4\x33\x11\x0c\x2c\x56\xf3\x4a\x1d\xe4\x26\x09\x14\xcd\x46\x96\xb1\x4a\x09\xc0\x26\x8b\x2a\xe2\xe9\x8e\x6b\x4e\x99\x2b\x91\x25\xf8\x78\xf1\xac\x09\x82\x31\x70\x62\x83\x88\xf0\xf6\xe2\x56\x25\x9c\xa7\x86\xbb\xe1\x44\x88\x4c\xb2\x98\xcc\x04\x3d\x02\xf5\xc3\xdc\x68\x4f\x78\x7f\xaf\x16\xc1\x0f\xdd\x84\x37\xa8\xc3\x09\x74\x63\xbd\xb9\x9b\x78\x03\x0f\x94\x74\xfc\x5c\x99\x51\xdc\x75\x26\x49\x05\x86\xfe\x1c\x2d\xb0\x54\x11\x34\x14\x60\x23\x9d\x5e\x8b\xc5\x30\x65\x90\x2b\x95\xfb\xa2\x82\xc2\x76\x65\xe8\x69\xa1\x9d\xae\x84\x60\x6d\x17\x26\x67\x51\x55\xd3\x80\x39\xb9\xe5\x5d\xb4\xd5\xce\xec\x95\xcd\x6d\x87\xf8\x5e\x99\xdd\xe5\x4a\x04\x76\x1e\x6e\xad\xa6\x61\x9d\xa8\x95\xb6\x54\xfe\x38\x45\xe8\xa6\x0f\x3a\x3b\x32\x48\x3d\x6d\x27\x97\x8a\xf5\x45\x02\xb2\x20\xe4\x78\xdb\x78\xcf\xf7\x7a\x9c\x97\xfb\x79\xfb\x5a\xcf\x56\x28\x9f\x38\x1a\xcb\x10\xde\x64\xc3\xf2\x38\x42\xb1\x2b\xf5\xf1\xb2\x83\xbd\x25\xd4\x8d\x09\x12\x8f\xb5\x5d\xda\xe2\x55\xbe\xb7\xc6\x6a\x74\xcf\x6f\x06\x95\xa4\xf8\x28\xcb\x29\xe4\xaf\xdb\xb3\xb4\x2a\x23\x5d\x4f\xdb\x66\xb9\x63\xac\x8f\x68\xe8\x2b\x00\xa1\xc4\x50\x08\x63\x29\x62\x47\x17\x8c\xfd\xef\x80\x3b\xb7\xb1\x14\xf0\xc0\x32\x76\xf6\x71\x66\x9a\x08\x7d\x92\x28\xa3\x7a\xe7\xb9\x9b\x06\x15\x49\xc1\xcf\x8e\xc1\x72\x46\xea\x1e\xe0\x3d\xbc\x88\xbf\x42\x64\x16\xd5\x86\x57\x2f\xf1\x0a\x31\x45\x60\x6f\x27\x84\xe4\x35\x7b\xe4\xed\xee\xc6\xc3\xa7\xbf\x11\xbb\x5b\x0e\x90\xcf\x50\xed\xaf\x89\x1e\x51\xd2\x63\x57\xbf\xc8\x53\xce\x23\xb2\x99\x15\x5c\x82\xc1\x03\x1d\xfa\x64\x07\x4d\x72\xa0\x9d\x29\x72\x0e\xad\x6e\xbb\xbf\x75\xd5\x73\x8e\x32\xcd\xa6\xb6\x46\x6a\x8d\xef\x6b\x50\xa1\xed\x9b\x86\x5a\x9a\x88\xa0\x80\x18\xac\xb5\x01\xa4\xde\x9d\xb5\x4d\x05\x22\xce\x9c\xec\x7a\x06\xbd\x9a\x5f\x86\xb0\xb4\x6c\x07\xbf\x3e\x7f\x5a\x42\x6f\xf6\xb4\xbb\xe1\xe0\x03\x13\xa5\xac\x27\x19\xa9\x59\xed\x44\xee\x0a\x44\xbd\x97\xda\x6d\xb2\xcb\x97\x1b\xd6\x83\x34\x90\x89\x49\xed\x85\x0f\xbf\x73\xd0\xe0\x20\x49\xda\x18\x1c\xce\x9c\x2d\x9c\xa1\xb6\x24\xc8\xd8\x7c\xf9\x04\xeb\x82\x1d\xc7\x95\x92\x95\xda\x57\x77\x92\x06\x60\xb4\x3c\xcc\x25\xcd\x38\x9f\x15\x7f\x67\xfa\x03\x90\xfe\xac\x97\xa7\x52\xc1\xac\x20\x4c\x21\xdf\x56\xbb\x0f\x4f\xc0\x16\x41\xb4\x80\xaf\x2b\x89\xb5\xd1\x6d\x4a\x0b\xcb\x0a\x50\xb8\x2b\x0e\x04\x84"}, +{{0x3a,0x34,0x13,0x6a,0x97,0x34,0x80,0xd9,0x70,0x06,0xdc,0x27,0x93,0x58,0xe6,0x60,0x62,0x93,0xd8,0xcb,0xc1,0xa4,0x4e,0xe5,0x52,0x33,0xaf,0x2b,0x52,0x64,0xb9,0x0c,},{0xe5,0xef,0xfd,0x92,0x1b,0xe8,0xee,0xc5,0x30,0x75,0x2f,0xcc,0xc5,0x76,0xef,0x0d,0x9b,0xcd,0xe4,0xb3,0x2c,0xc6,0x49,0xd3,0xf7,0x95,0x47,0x17,0x56,0x28,0x60,0xcc,},{0x42,0x5f,0x27,0x22,0x12,0x83,0x57,0x55,0xad,0xcc,0x05,0x22,0xc6,0xf6,0xe0,0x5f,0x68,0x00,0x8a,0x3b,0xe9,0xba,0x59,0x74,0xe4,0x20,0xc4,0xc5,0xcb,0x56,0xe6,0xc5,0x5d,0xec,0x0d,0xe3,0x47,0xb1,0x6c,0xae,0xf8,0xbd,0x33,0xb7,0x1b,0x44,0xc8,0x35,0x7d,0x05,0xb6,0x32,0x1d,0x7b,0xf4,0x93,0xd2,0x58,0x61,0xdb,0x48,0x7b,0xd6,0x03,},"\x98\x1c\x8e\x10\x90\xe3\x96\x95\x1b\x07\x2e\xf8\x49\x70\x62\x02\x08\x97\xbf\x7d\xd7\xad\x50\x5b\x4d\x6d\xc1\x1b\x3e\x1d\xbc\xb0\xda\x24\x99\x84\xa1\x40\xe1\x64\xfc\x2e\x02\xb3\x1d\xa3\x98\x46\x55\x4a\xa8\x90\x5b\xc8\xb3\xdf\x8a\x76\xbf\x60\xeb\x5f\xfc\xf2\x2c\x97\xb6\x71\x22\x7d\x24\x90\x71\xda\x8f\xf6\xbb\xa7\x5b\x2f\x76\x68\xce\xc1\x9a\x89\xe6\x47\x5a\x12\x46\x3d\xab\xf3\x68\xb3\xca\x24\x45\xbb\x30\x35\xcc\x00\xfa\xe8\x5b\x70\x72\xfb\xcf\x59\x54\x01\x75\x5b\x80\x51\xe6\x09\x70\x65\xae\x42\x9f\x18\xee\xb1\x3f\xfa\x6d\xde\x59\xdf\x6f\x3c\x20\x6b\xfd\x9c\xe1\xf8\xa8\x00\xc8\x59\x0a\x40\x21\xd1\x60\xf6\x6d\x67\x40\xa3\x69\xae\x83\x56\x17\x53\x8b\x58\x90\x23\x1f\x13\xc5\x66\x7b\xaf\x51\x0a\x60\x6b\xda\xa8\x4b\x8d\x10\xee\x60\x15\xe1\x2a\x4c\x1e\xc0\xbd\x04\x21\xa2\x94\xc5\x1c\xf6\x3b\x5d\x1f\x05\x8e\x11\x53\xdc\x42\x5d\x10\xce\xe8\xb1\xb0\x84\xd6\xc2\x93\x47\xe9\x6f\x0f\x31\xb8\x39\x60\x7d\x07\x8b\x79\xa9\x0c\xa3\xd1\xf0\x63\x80\x7a\x46\x3b\x7c\x32\xf4\x5a\x53\x44\x98\xd7\x1d\x47\xed\xc3\xb1\x7a\x4d\xff\x27\xfe\xdc\xff\xab\x30\x1f\x34\xf1\xa6\x4c\x02\x78\xa5\x35\x89\x34\x9a\x23\x3a\xf3\x0b\x1e\xc1\xae\x41\x0f\x7b\x16\x30\xc7\x14\x5c\xa4\x2c\x96\x63\xf5\x12\xe8\xa5\x78\x26\x7d\xc9\x5e\x83\x28\x9c\x17\x03\x2e\x09\x78\x2e\x2f\xe8\xe1\x6e\xfb\x87\xf0\x3c\xa0\x3b\x11\x95\x61\x4f\x89\x96\x1c\xa3\x93\x9d\x3b\xdf\x73\x72\x21\xa2\x2d\x7a\x18\xec\x30\xfc\x12\x6d\x0c\xa6\x63\xe8\x8d\x60\x60\xd0\x4c\x6a\x44\xe5\x61\x6e\x55\x6e\x07\xd6\xd4\xa8\x47\xf1\x71\x1c\xf4\x37\x17\x81\x0c\x70\xaa\x4b\xe7\x30\x27\x8b\x3b\xd6\x55\x5c\x95\x4d\xc6\xed\xb0\x9d\xb0\x8f\x0e\x21\x18\x03\x59\x62\x80\xf3\xc7\x86\x8d\x23\x42\xcc\x23\x08\xea\xae\x4d\xa1\x91\x35\x14\x66\x4b\x1d\xb9\x62\xe9\x9c\x8a\x8c\xff\xe5\x79\x31\xf5\xdf\xcd\xdb\xc1\xcb\xb3\x6c\xe1\xc8\x42\xe2\xdd\xde\xad\xfd\x7e\x7d\x0a\x50\x48\xcd\xcb\x96\x1b\x14\xf3\x5f\x43\x5e\x73\xa6\x83\xc8\xce\x25\xc8\x16\x81\x25\x66\xfd\xf8\x17\xe0\xd3\x36\xae\x0b\xd2\x47\x32\x85\x12\xb2\xa8\x56\x76\x32\xbf\x20\x55\x3d\x9b\xd6\xfe\x15\x7f\x22\x0f\xfb\x0b\x46\xeb\xae\x89\xa7\x04\x59\x72\x8a\x57\xee\xd1\x79\x62\x56\xf1\xbd\x50\xb6\xd5\x47\xea\x3e\x25\xfa\x59\x13\xd3\x89\xa2\x25\x83\xe9\x15\xeb\x49\xde\x35\xa9\x7b\x5a\xcc\x52\x1d\xb0\xd0\x05\xc2\x95\x75\xe1\x66\x11\xa7\x55\xf2\x1a\x3a\x5a\x82\xa2\x0a\xa9\x00\xa7\x07\xce\x36\x82\x54\x92\xc3\xca\x15\x39\x5f\x17\x00\xb4\xaf\xab\x94\xda\xa7\xa0\x2f\x14\x53\xb1\xf9\xa6\xbd\x36\xef\xb2\x04\xd9\x28\xee\x1f\x4d\xcc\x86\x0f\x3a\x85\x9b\xad\xc0\x06\xfb\x30\x5f\xa1\x23\xd4\xc7\x9b\x23\xa2\x0e\x32\x29\x5d\x04\x0a\x7f\x8f\x6c\xac\xa2\x5d\x83\xf7\x1c\x62\xe3\xaf\x78\x36\xef\x76\xb9\x3a\x83\xd3\xc3\xb4\x93\xaf\x14\x17\x53\xda\x19\xe4\xcd\xcb\xa5\x66\x17\x27\x10\x34\xb4\xf4\xf3\x94\xc7\xc6\xb7\xd7\x96\x66\xf3\xaf\xb6\x92\x24\x4f\x06\x1c\x69\xa8\x88\x1d\x1b\x52\xb8\x84\x9f\xb5\x34\x99\x0a\xc2\x39\x19\x09\x47\x1e\xbb\xb7\x28\xe2\x9c\xd2\x0f\x42\x23\x54\xc4\x30\x97\x17\xeb\xff\x3e\xfd\x18\x33\x37\x08\x06\xd5\xbf\xb5\x3c\xa2\xda\x31\x6d\xac\xb5\x0a\xb7\xfb\x73\x96\x73\x23\x5a\x1d\xc5\x3a\xa8\x89\x30\x72\xd5\xb9\x1c\x9f\x6d\xb8\x3f\xc4\xea\x41\xd1\xee\xf4\x9a\xc2\x8a\xfc\x1c\xed\x8f\x36\x18\x90\xab\x9f\x77\x9d\x19\x30\x82\x83\x1c\xb8\xc4\x2f\xb2\x79\x2b\xee\x3b\x26\x29\x6b\x62\x95\xeb\x78\xa8\xd8\x53\x11\x76\x61\x62\x4e\x11\xf7\xf5\x7a\xfd\x60\x85\xa7\xb9\x12\x36\x79\xfd\xac\xa1\xcf\x2a\x78\xd3\x80\xbc\x4c\x36\x0a\xa7\xc3\xcb\xfd\xe0\xc0\x09\x1f\xe5\x3e\x22\x19\xc0\x70\xf2\xf0\x2f\x14\x83"}, +{{0xcf,0x33,0xe7,0x97,0x4d,0x8f,0x0b,0xf8,0x99,0xac,0x5b,0x83,0x4c,0x7c,0xf9,0x64,0x79,0xce,0x1c,0xfd,0x45,0x3a,0xf0,0x7f,0x97,0x05,0x27,0xf3,0x6a,0xa8,0x5c,0x1f,},{0x57,0x8f,0x60,0x33,0x8b,0x1f,0x04,0x1a,0x97,0xd3,0x19,0xfe,0xcf,0xa3,0x0c,0xfa,0xed,0x36,0x93,0x03,0xcc,0x00,0xb3,0xec,0x8c,0x5c,0x99,0x04,0x11,0x58,0xe2,0x0c,},{0x97,0xa5,0xb6,0xd2,0x68,0xa5,0xb4,0x17,0x5f,0xb0,0x6f,0x1f,0x37,0xd0,0xa6,0x33,0x51,0x92,0x96,0xed,0xc3,0x00,0x11,0xc9,0x54,0xd8,0xf0,0xb9,0xbb,0xe2,0x64,0x18,0x00,0x39,0x6c,0x4b,0x35,0xd4,0xb0,0xd7,0xd2,0xa1,0xd1,0x7c,0xbb,0xeb,0xdc,0x55,0xa8,0x09,0x46,0x2d,0x6c,0xc1,0x9a,0x6f,0xad,0xbe,0x1b,0xd1,0xba,0xe8,0x8a,0x01,},"\xe8\x13\x14\x4b\xd1\x16\xf6\xac\x36\x38\x92\x17\xb5\x17\x1a\x90\x2f\x06\xb7\xdd\x7b\x14\x4d\xf4\xf9\x09\x15\x53\xc7\xc7\x83\x57\x53\xa2\x96\xcb\xb0\xd7\xfa\xb9\x9c\xef\x77\xb6\x1f\x34\xa0\x4c\x8a\xf0\x4e\x7d\x5d\x1f\x96\x13\x02\xde\x89\xe2\x00\x5f\x29\x9f\x5a\x4a\xa1\x79\x24\x61\x7d\x00\x66\x93\x93\x77\x45\x53\x9c\x30\x48\xee\x36\xb8\xc2\x3a\xfe\xc0\xaf\x9f\xea\xa0\x06\x6c\x8a\xf8\xe0\xa7\xf0\x90\x93\x49\x82\x10\xf6\xd8\xdc\xc0\xaa\xad\xa5\x66\x87\x86\x91\x0f\xf7\xc5\xb3\x48\xd4\xcc\xd6\xee\xef\xfa\x3a\xcd\x18\x16\xd9\x01\x1a\x4c\x40\x25\xf6\xc2\xfd\x2c\x02\x0a\x10\x59\x36\x27\x52\x0d\x4d\xd9\x9e\x07\xc6\x2d\x2d\xbe\xbe\x84\x13\x9e\x1c\x7d\x86\x7c\x09\x35\x74\xfa\x60\x1e\x4e\xe3\x07\xac\x92\x6e\x5d\x36\xb6\x2d\x7e\xd8\x4a\x26\x15\x88\xb7\xe2\x88\x3c\x79\x26\x61\x2b\x4c\xc6\x7e\x2b\xb7\x25\x44\xa1\x0d\x6b\x49\x29\xc8\x8e\xf6\xc4\x7c\x26\x25\xd2\xf6\x81\x6b\xd7\x3c\x3b\xae\x89\xd2\xe0\xc8\x61\x71\xac\x4b\xd0\x80\xae\x55\x5d\x62\x74\x0d\x1d\x2a\x76\x1c\xed\x86\xdf\xc3\x28\xec\xc2\x7e\xe3\xdb\x6d\x40\x41\x08\xef\x4e\x0b\x64\x90\x62\x53\xb4\xc0\xa7\x71\xad\xef\xed\xc8\xa2\xc5\xb5\x3c\x42\x5a\x70\xcd\x6f\x63\x95\x6f\x7a\x0a\x61\x9f\xdf\xbf\xd0\x0a\xa0\x78\x41\x8e\xb4\x65\x2f\x8b\xc6\xf3\xc2\x53\xbe\xec\x98\x38\xb7\x7f\x9c\xbe\x2e\xf2\xb8\x05\x5c\x57\x73\x53\x9e\x35\x6b\xd8\x19\x26\x06\xec\x10\x1e\x3f\x60\x58\xb1\xdd\x08\xa6\x8f\xdb\xc5\x49\xdf\xe6\xb7\x72\x5d\xc2\x54\x9e\x8e\x3f\x90\xdc\x5b\xe3\xcc\xfb\x0a\x38\xba\xf9\x37\x7c\xb3\xf6\x50\x1d\x2e\x15\xcc\xb3\x55\x6a\x89\x5c\xcb\x23\xf0\xb6\xdf\x9f\xe5\x93\x11\xcf\xf5\x53\x74\xc3\xfb\x3a\x32\x98\x1c\xa2\x6a\xb4\x26\xf3\x66\x3d\x04\xe3\x16\x7e\x53\xa5\x37\xb7\x58\x9a\x9f\xb7\x36\x79\x09\x0a\x20\x55\x32\xc1\x32\x90\x66\x34\x33\x4a\x7e\x87\x49\x79\x3f\x8c\x59\x3f\x3f\xd6\x27\x8c\xe0\x05\x03\x83\x48\x7f\x3b\x24\x50\x67\xaf\x94\x88\x1a\xa1\xae\x96\x8d\x0c\xae\xba\x5f\xa5\xc7\xbe\x5f\x4e\x4b\x72\x57\x51\x86\x95\xd8\x9b\xcc\xde\xc5\x07\xb9\x67\xb4\xfd\x64\xb6\x89\x3b\x3e\xe7\x80\x3c\x1d\x36\xea\x8a\x02\xfc\x42\x6f\x9a\xfc\x8e\x9f\x24\x32\x15\x27\xec\x98\x44\xbc\x3c\x54\xa0\xf7\x66\x7e\x03\x43\x00\xbb\xb4\xfb\x02\x0f\x6d\x5b\xb9\x54\xe7\xb5\xa3\xa7\x06\xa4\x93\x9d\xb3\x3c\x15\x48\x92\x64\x34\x76\xa2\x91\xd4\x7d\xc1\xe6\xf7\x2c\xe9\x1d\x13\x6f\x11\xdb\x26\xb9\xc9\xba\x73\x6e\x40\xdf\x0a\x15\xc1\xa8\x91\x49\x99\x6b\x25\x1d\xd9\x88\xb3\x90\x04\xe6\xef\x41\xbd\xc0\x61\xdb\x58\x0b\x7b\x74\xde\x2a\x65\x18\x10\xbd\x89\x17\x53\xb9\x73\x86\xd7\xf8\xcb\xdb\xb6\xec\x38\x6f\xa2\xc3\x42\xf5\xef\x20\xe6\xe3\xa8\xbb\x4d\x51\x49\xa7\xd4\xde\x12\x24\xdf\xf1\xd1\x72\xc8\x75\x70\xf7\x76\xd5\xef\x45\x95\x9b\xe0\x93\x8a\xd7\x9f\x5d\x33\x95\xcb\x27\x21\x62\x71\x22\x88\x7b\xd7\xa8\x98\x3b\x64\x77\x97\xbd\x41\xd8\x82\x64\x1c\x81\x43\x1c\xe8\xd9\xb3\x06\x7a\xde\xc4\xcd\xe9\x26\xc5\x13\x13\xf0\xcf\x84\xc5\x29\x25\x62\xdd\x49\x08\x64\x2d\xd2\x45\x28\x84\x84\xc5\x56\x8a\x78\x7d\x0c\xed\x36\xa3\x52\xf0\x32\xda\x4f\x7e\x4d\xe0\x6b\x11\x47\x3f\x65\x0e\xec\x65\xdd\xa9\x96\x39\xaf\x2d\x42\xd8\x4e\xe2\x30\xf4\xf8\x36\x23\xd9\xc9\xaa\xa3\xb1\x6b\xda\x10\xdd\xaa\xd2\x5a\xf5\xc1\xc1\x0f\x81\xc8\xc5\x1c\x81\x1a\x3a\xa3\xe3\xdb\x58\xa7\x02\x5e\x43\x80\xe2\x85\xda\x47\x4a\x61\xba\x59\x17\x3f\xf0\x42\xa4\x6a\x79\xab\x18\x4b\x07\x01\x08\x41\x6f\x9d\x61\x58\xcf\x96\xd0\xe6\xdb\x44\x76\x14\xa0\xd9\x08\x9e\xbb\x6a\xee\x4e\xf1\x07\xbe\x45\x93\xd7\x1e\x79\xf6\x79\x86\x68\xa7\x40\xae\x4b\xac\x5a\xc7\x59\x4e\xcb\xd5\xdc\x82\xe7\xd0\xf9\xcb"}, +{{0x51,0xb1,0xad,0x0f,0xfc,0x21,0x49,0x7a,0x33,0xdb,0xdb,0x85,0xea,0x2b,0xc1,0xce,0x3d,0x0c,0x2d,0x95,0xd9,0x46,0x1a,0x39,0x09,0x73,0xfe,0xe3,0x77,0xfc,0x75,0xf4,},{0xba,0xd0,0x41,0x25,0x75,0xd3,0x80,0x13,0x01,0xed,0xee,0x6b,0xc0,0xf2,0x76,0xe7,0x87,0x35,0x7b,0x41,0x22,0xf5,0x2d,0xe9,0x81,0x88,0x58,0x51,0x88,0x42,0x49,0xcb,},{0xcf,0xb6,0x5b,0x6f,0xf0,0x37,0x7c,0xef,0x51,0x1f,0xd9,0x7b,0x90,0xc3,0xec,0xb8,0x08,0x33,0xf1,0x42,0xa7,0xcf,0x50,0x22,0xce,0xd3,0x0b,0x3f,0xb7,0x86,0x20,0x86,0xd0,0x13,0x39,0xb8,0x86,0x6a,0x23,0x8c,0xb0,0x70,0x27,0x6e,0x19,0x44,0xb5,0xfe,0x32,0xcc,0x40,0x99,0x47,0xcb,0x91,0xde,0xb1,0x43,0x2c,0x29,0x1b,0x60,0xfb,0x0d,},"\x78\x82\xe8\x6e\xf3\x40\x2f\x6d\xbc\x65\xcc\xe8\x31\x5b\x39\x76\x5f\xaa\x4b\x1f\xc8\x76\xfa\xd5\xf8\x22\x0c\xb2\x2a\x7d\xf2\xe3\x58\x0e\xab\x3a\x7e\x8f\xa7\xfb\xb6\xb5\x94\x82\xca\x0e\x36\x4a\x13\x13\x96\xdf\x79\x2a\x32\x41\xa0\x60\xe4\x41\x43\xb6\x76\x74\x93\xc6\xbf\x75\xf1\x87\xa9\x64\x3a\xa1\x1e\x11\xeb\xa7\xb0\xa8\x0f\x0a\x68\xb9\xf1\xb7\x9f\x75\xb6\x6c\xc5\x9d\x9d\xa7\x79\x55\xfd\x7e\x87\x99\xf9\x9d\x6e\xb0\x8f\x90\xd3\x18\xf4\xef\xcb\xfe\x71\x15\x9b\x10\xa8\x3a\xa5\xfd\x69\xbb\x75\x33\x6f\x5d\xf2\x96\xea\x06\x0a\x42\x6c\x95\x45\xdf\x94\x0b\xc1\x45\x4e\xfc\x1f\x9d\xc9\x65\xf1\xf2\x2d\x94\x73\x03\xfb\x8e\xc1\x24\x07\xff\xf6\xb1\xdb\xe4\x7e\x34\x21\xc3\x17\x64\xfd\x90\xc8\x3a\xc7\x11\xd1\x99\x26\xe2\x29\xa0\x64\xc6\x1f\xe3\x67\x6a\xf3\x00\xa1\x71\x6f\xab\xe4\xe3\x84\x22\x64\xad\xb3\x2e\x0d\x9c\x9f\x5d\x4a\x65\xd0\xd7\xb5\xc3\x77\x0d\x73\x7e\xe1\x3c\xbe\xd2\x1d\x7a\x1d\xa3\x6a\xaf\x7e\xc0\xf3\x6f\xcc\x47\x6f\x65\x96\x81\xe5\x16\x0a\x5a\x1f\x49\xe7\x59\xb9\xd0\xfc\xd4\xfd\xb8\x54\xec\xcd\x99\x17\x2a\x47\xd2\xc4\xef\xbe\x0b\x37\x57\x63\x1d\xf1\xba\xe1\x75\xf0\xfa\x74\xdd\x04\x8b\xb6\xa5\xfe\xd8\x43\x02\x84\x34\x9d\xa3\xd6\x7d\xf2\xa6\xf7\xe8\x26\x9b\xc7\x9f\xb2\xc5\xd5\xed\x60\x84\xe9\x07\x6f\x45\x5a\xb6\x38\x91\x90\x46\x36\x9a\x44\x6d\x57\xfc\xad\xa7\x01\x1c\xc7\x71\xbf\x6d\x87\x4a\x8e\x5d\x23\xc6\x87\x74\x7d\xe4\x1d\xd0\x4b\xff\xc7\x17\xd6\x12\x81\x83\x84\x6e\xb5\x94\xb3\xcb\x1c\x1a\x8a\xa0\x4f\x0d\x7e\xba\x53\xaf\x39\xcb\x1d\x4e\x6f\xec\xf3\x11\x3b\xd8\x42\x24\x16\xf4\xc4\x40\x37\xae\xee\x9e\x0f\xdc\x51\x7c\x48\x73\x1f\xd0\x4e\xe9\xc9\x9f\x5d\xbc\xa3\xd5\x74\x50\x9d\x7b\xaf\x32\x88\xf2\xc2\x30\xa0\x2d\x17\x03\xbd\xb1\x61\x1c\xde\x2a\x76\x6d\xac\x19\x3d\xe1\x67\x44\x3d\x20\x09\x0d\xc3\x4d\x29\x27\x7a\x86\xb1\xe9\x98\xb2\x45\x64\x51\x17\xe5\x11\x1f\x12\xf1\x46\x06\xc5\x54\x46\xdd\x91\x2d\x34\x75\xc1\x98\x76\xe1\x9a\xc5\x36\xd3\x17\x87\x6c\x4b\x0a\x2e\x0f\x98\x61\x61\x29\xa5\x68\x37\x32\xa4\x23\x17\xc5\xe8\x09\xdc\xa9\x56\xb2\xab\xb4\x84\xad\xa8\x10\xa1\x5c\x81\xcc\x85\x62\xb5\x55\xda\x94\x58\xf9\xb4\x43\x38\x49\x02\x30\xc7\x40\x4f\x3d\x48\x61\x1f\x84\x12\x7e\x73\xe2\x77\xd8\x8c\x62\x21\x2d\x2a\x3a\x35\x1f\xc6\x76\x65\xb1\x8d\x77\x21\x62\x30\x63\x2c\xbc\x78\x12\x88\xe1\x5c\xeb\xf3\xec\x33\xa7\x20\x5e\xb2\x2b\x9a\xbe\x4c\xdb\xc7\xdd\xba\xaa\x53\x64\x08\x75\xeb\x76\x3f\x52\x2c\x36\xcf\xff\x2e\xb2\x3e\xe5\x86\xd7\x75\x28\x62\x59\xfa\x94\xa4\x4f\xa7\xec\x01\x50\x96\xa2\xa4\x46\xb6\x73\x2b\x80\x02\x42\x67\xfe\x3d\x5d\x39\xd1\xc4\x85\x09\xb3\xec\xaa\x2e\x24\xe5\x4d\xe4\xd6\x1c\x09\x7b\x70\xf7\x53\xb5\xaf\x9a\x6d\xb6\xf9\x75\xd2\x5f\x4f\x83\xd0\x6f\x87\x9e\x17\xef\x7c\x50\x9a\x54\x14\x44\xba\x3e\xb6\x86\x78\x38\x09\x0e\x22\xda\xfd\xbb\x0e\xb3\xb0\x56\x5b\xe1\x57\x9c\xee\xcd\xed\x20\xf5\x44\x25\x6c\x7c\x4e\xde\x3b\x62\x84\x3c\x65\xb0\x46\x6b\xe6\xb7\xe2\x73\x05\xb9\x63\xca\x91\x4e\x3b\x7d\x21\x73\x61\x18\xed\xb3\xd6\x58\xd9\xd7\x6f\x50\x9d\xb3\xb9\xca\x2e\xae\x28\x96\x4a\x4b\x3b\x3c\x38\x4a\x81\xa4\x89\x0e\xe9\x6f\xbe\x93\x4a\x6f\x2a\xec\x8e\xeb\x6c\xfe\x59\xac\x9d\x3b\xbc\x16\x46\xba\x32\xa1\x14\x2f\xee\x59\xfe\xd6\xfb\x7b\xbc\x04\x98\xcc\x27\xde\xad\x41\x3b\x7b\x43\x51\xec\x20\x63\x43\xc0\xab\x89\xfc\xf8\x72\x43\xb1\xab\x45\x0e\x58\xff\x11\xa1\x14\x0a\x38\x3f\x19\x6a\xa3\x97\x6c\xe1\x7c\xf3\x45\x30\xf0\x49\xa1\xde\x90\xe3\x17\x53\xcd\x85\xe7\xf1\xfd\x5c\xf2\x04\x26\xc9\x37\x9f\xeb\x8c\x31\xb4\xbf\xec\x35\xea\x5a\x78\x95\x3d\x75\xc5\xcf"}, +{{0xfa,0x2f,0x46,0x1c,0xe8,0xc7,0x12,0x62,0x18,0xc4,0x7c,0x91,0x56,0x9e,0x87,0x99,0x79,0x7c,0x83,0x36,0x8f,0xc8,0x42,0xb6,0xe1,0xc2,0x2f,0xd5,0x2a,0xec,0x70,0xbf,},{0x6b,0x89,0xb2,0x3f,0x1e,0x11,0xa7,0x5a,0x53,0xf9,0x92,0xf6,0xca,0x57,0x75,0x00,0x8c,0x6e,0x9e,0x7e,0x49,0xc0,0xd8,0x51,0x0b,0x0e,0x83,0x69,0xb7,0xa2,0x0b,0xcc,},{0x84,0xf7,0x9d,0x9e,0x8f,0x30,0xe5,0xbb,0x63,0x62,0x23,0x97,0x14,0x55,0x6b,0x04,0x73,0x6f,0xa4,0x44,0x65,0xca,0xba,0xad,0x23,0xbe,0xaf,0x5a,0x99,0xfc,0x45,0x1a,0xd4,0xae,0x5a,0x18,0xc7,0xf6,0xf9,0x64,0xfa,0x41,0x03,0x92,0x16,0x01,0x8e,0xc5,0xa2,0xac,0xca,0xe1,0x07,0x5a,0x6b,0xb3,0xa6,0xec,0xbc,0x1f,0xca,0x02,0xb9,0x04,},"\x79\x9b\x39\x80\x2a\x18\x27\xe4\x5c\x41\x12\xfe\xe0\x26\x03\x4c\x0e\x59\x8a\xff\xce\x2c\x55\x0c\x19\x3f\xee\x73\xf1\xdf\x8c\x30\xc8\xd3\x87\x33\x40\x08\x8c\xe8\x59\xde\x34\x71\xe9\xd0\x57\x68\x6c\x82\x9b\x54\x08\x79\x5e\x08\xb3\xdc\x7a\xa3\xb6\x37\xc7\xde\x9d\x21\x72\xad\x03\x33\xc1\xbe\xa8\x61\xa6\x23\x2f\x47\xf0\x5a\x10\xbf\x5d\xf8\x08\x15\xa2\x71\x25\x6e\x37\xe8\x08\xa0\xe6\x2f\x1f\x07\xd9\xe1\x0e\xbb\x94\x7d\x3e\xfa\xbf\x8a\x28\xfa\x9d\xcc\xd9\xa1\xd5\x99\xf5\xfd\x61\x65\x50\x8e\xfd\x67\x9c\xf3\x56\x01\x50\x58\xbf\x4b\x34\x11\x8f\x83\xaa\x3e\x5b\xc2\xce\x19\xec\xa8\x4f\x71\x83\x98\xad\xbc\x0a\x52\x76\xcf\x9d\x8c\xaf\xfc\x27\xe3\xe6\xab\xbe\x34\x5b\x0e\x9e\xcf\x89\xc6\x77\x1b\x0e\x75\xd4\x08\xba\x2f\xbb\x90\xfc\xfd\x70\xc5\x3f\x2e\x4d\x52\xba\x54\xd9\x78\x4c\xf7\x1c\x34\x9e\xf6\xf1\x4a\xe4\x97\x0d\xef\x6e\xfb\x5f\x30\xe9\x84\xd6\x01\x6a\x19\x6d\xea\xec\x7e\x04\xb4\x76\x19\xc4\x8b\xf4\x9d\xc0\x2f\x7f\xef\x3e\x13\xb7\x56\x17\x4e\x90\xd0\x5f\xcb\xdd\x5e\x13\xf0\xe4\x34\xef\xd5\x42\x1b\x09\x1d\x51\x79\x00\xed\x0d\x57\x85\x96\x88\x62\xb4\xbf\xe5\x09\x3a\xb6\x72\x17\x18\x0d\x97\x55\x4c\xcd\x9c\xc3\x14\x29\x32\x6c\xab\x42\xf3\xf8\x39\x80\x60\xc1\x9d\xb4\x88\xb5\xd1\xc8\x0b\x29\x09\x0a\xfd\x1c\x6b\xac\x36\x42\x26\x48\x00\x21\x1b\xc2\x78\xfc\xb9\x9d\xae\x9d\xbf\x49\xda\xf1\xb2\x4a\xb5\x69\xdc\xbb\x87\xd4\xd3\x54\x73\x35\xe3\x5d\xb9\x84\x00\xcd\xfc\xe6\x79\x06\x82\xe9\x36\x00\x22\x0e\xc4\x99\x24\x5f\xa4\xee\x15\xd8\x43\x83\x1b\x56\xcc\x26\x41\x80\x25\xbf\x87\x00\x16\x05\xc6\x69\x1c\xa6\xbd\x40\xa4\xe2\x48\xc3\x09\x80\x1b\x76\xa7\x95\xed\xe8\xad\x53\x08\xbc\xb6\xd1\x75\x4a\xb3\x37\x1f\x00\x03\xbb\x8c\x4e\x4e\x47\x19\x54\xe2\x8b\x1e\x98\x66\x37\x9f\x82\xe1\xfb\xac\xb7\x9d\x50\xad\xdd\xad\x5b\x97\x78\xb5\x58\xcd\xdb\xb0\x03\x8a\x5f\xf3\xd5\xc9\x55\x7b\x96\x5d\xe3\xa7\x08\x2c\x45\xa8\xec\xf3\xe7\x72\x1e\xb6\x90\xb6\xc7\x1f\x3d\x89\x75\xd5\x30\x0f\x67\xc4\xdc\x4a\x73\x68\x46\xe4\xcc\xd2\x6f\x93\x46\x3d\x5b\xc6\xf4\x6e\xdc\x48\x86\x64\xbe\x96\x96\xbe\x12\xb0\x2d\xd1\x04\xd1\x0c\xc6\xb1\xd8\x2e\x81\x17\x81\x12\x14\xa6\x48\x7d\x17\x36\x7e\x39\x5a\xde\x2e\xf6\xb2\x6a\x17\x83\xa7\xe2\xf2\x45\x21\x3b\xc0\x3a\x75\x5d\xf3\xee\x8e\xf9\xf1\xef\xf9\x72\xc6\x91\x90\x65\xcb\x7b\x75\x66\x78\xd4\xdd\xfd\x19\x3e\xdd\xc0\xb4\x2e\x86\x89\x61\x36\x43\x14\x6d\x74\x28\xca\x37\xbf\x31\xbd\xf1\x4e\x31\x86\x78\x58\xf3\x9d\x23\x23\x70\x9e\xb3\xb7\xd7\xf4\xe3\x97\x02\x23\x78\x42\x4b\xde\xe9\xbc\xb7\x4e\x9d\x5d\xfd\x37\x1f\x47\x34\x99\x8f\xc1\x8d\xf4\xcd\xfb\x4b\x5c\x21\xc2\xe5\x0f\x8d\x6c\x15\xbc\x14\xbf\x4f\xda\x6c\xeb\x9d\x80\x82\xca\xe4\x32\xdf\xc9\x8b\xfb\x3e\xcd\x16\xb8\xd7\x4f\x83\x0b\x64\x2b\x04\x28\x75\xe9\x21\xb0\x54\xbd\x1a\xaa\x58\x1f\x60\xd7\x18\xdf\x66\x9f\x56\xdc\x2f\x10\xd4\x78\x99\x77\x22\x16\x2e\x83\x94\x0e\x61\xa1\xb6\xe4\x2d\xf2\xa4\xa3\xa7\xcb\xcd\xd6\x11\xce\x96\xcb\xcf\xb5\xa9\x5c\xc4\x73\x23\x1c\xa1\x3c\x06\x09\xd0\xce\x1a\xe5\xdd\xb5\x46\x6d\x6d\x65\xee\xfa\xd9\xda\xf2\xa3\x69\x01\xbc\xc9\x45\x84\x7d\xa1\xed\x6e\x2e\x24\x0e\x84\x8b\x23\x1b\x7d\x0e\x1a\xcd\x06\x54\x3e\xc9\x3e\x76\x8e\x59\x98\x5d\x7e\x96\xc8\xc3\x1f\xcd\x12\x10\xf0\x96\x42\x71\xe2\x18\x77\x52\x5c\xb1\x34\xbc\x35\x36\x25\x7d\xbb\x11\xd3\x0a\x3c\x4f\x94\x9f\xb8\x2a\xe0\xc3\x1c\xcd\xfe\x41\x94\x32\x51\xe5\x0a\xa4\x35\x53\x92\xac\x30\x9e\xf6\x0f\xc1\x74\x32\xa2\xbe\x4b\xdb\x2f\xcb\x28\x60\x7c\xc4\x5a\x52\xb6\x00\x16\xbb\x1d\x2e\x23\x97\x2f\xf2\xc2\xa2\x47\xd7\x25\x58\x5b\x1e\xf2\xb1\x5f"}, +{{0x1b,0xe2,0x94,0x9d,0x51,0xe7,0x20,0x81,0x75,0x82,0x62,0x13,0xee,0x6a,0xe3,0xc0,0x91,0x17,0x27,0x42,0xe8,0x8c,0xaa,0x02,0xed,0x0f,0x31,0x3e,0xcb,0xe5,0xd9,0x10,},{0xd7,0xbf,0x47,0x48,0xd6,0xdd,0xed,0x5b,0x57,0xa2,0xab,0xf7,0x97,0xfa,0xcc,0x56,0x0b,0x48,0x56,0x3d,0xfd,0x9d,0xcf,0xf4,0xbe,0x52,0x2c,0x71,0x7a,0x6c,0xfd,0xa9,},{0xf4,0x1f,0x2e,0xf6,0x59,0x5f,0x17,0x66,0x0b,0xb2,0xfe,0x93,0xe5,0x1f,0xc6,0xfa,0x9c,0x31,0xda,0xdc,0x9d,0xb9,0x0c,0x3f,0x46,0x60,0x7a,0x7f,0xb4,0x80,0x0b,0xb7,0x5a,0xd9,0x63,0x25,0xdc,0x7e,0xab,0x78,0x24,0x72,0xb0,0x4d,0xa6,0xd8,0xe6,0xfe,0x64,0x65,0x5d,0xea,0x55,0x1f,0xbd,0x50,0x49,0xe8,0x76,0xce,0x5a,0x40,0x5f,0x02,},"\x04\x5e\x2b\x0e\xc7\xbb\x20\x3a\x49\xbd\xcb\xa9\x41\xe2\xb7\x3c\x23\xc1\xfe\x59\xa1\x7d\x21\xa0\x12\x4e\xa2\x4b\x33\x7f\x92\xab\x9c\x92\x3a\x20\x57\x6b\x62\xd5\xd0\xf6\x24\xe7\x93\x2c\x11\x5b\x54\x74\xe0\xa4\x6a\x4d\xc9\xec\x51\xf6\xa0\xce\x8d\x54\x74\x4d\x1d\x52\x09\x33\x20\xe3\x9b\xe2\x03\xf7\x4a\x0f\x5d\xfa\xc5\x2c\xf0\xf9\x95\xc6\x6d\xf2\x91\x4b\x68\xad\x87\x1f\xbe\x81\x52\x5a\xd2\xd8\x8a\xc6\x99\x33\xa7\x5a\xea\x74\xac\xe4\xe3\x63\x43\xdd\xc0\x6d\x32\x08\xf1\x6d\x80\x5f\x5d\xd7\x86\xb4\xda\xaa\x16\x67\x48\xcf\xee\xc5\x71\x4c\x85\xc1\x04\x78\xb5\x97\xac\x7f\x6a\xe2\xc9\x88\x91\xe3\x8f\xd4\x14\xaa\x81\x1b\x76\x21\xd8\x05\xeb\x8f\xcc\x46\xcf\x4d\x56\x8a\x8a\x92\x58\x7c\xbb\xc1\xae\xcc\x12\xf1\x0d\x90\xac\x1e\x01\xae\x98\x6d\x14\xfe\x82\x95\x1c\x68\x2c\xea\xc8\xc9\x25\xfc\x66\x54\xd8\x38\xac\x93\x53\xae\x2f\x93\xf3\xc8\x8b\xf7\xb8\x2c\xbc\x43\xb1\xe4\x9e\x5c\xeb\xfb\x19\x49\xad\xe4\xb2\x2e\x4b\xcf\x1b\x40\x0c\x0a\x8f\xa8\xa6\xfe\x76\x70\xf6\x9f\xc3\xfa\xec\xd4\x80\x5b\x8c\x95\x4c\x01\xa5\x40\xd1\xa1\xe7\x88\x43\x6e\xae\x07\x3a\xe9\x56\xda\xe3\x17\x69\x05\xa8\xf0\xa3\xc6\x0f\xd9\x80\xda\xb4\x19\xd4\x1e\xc0\x6e\x52\x73\xfb\xb1\x3d\xb9\x38\x1f\x89\xb6\x63\xcc\xc4\xbd\x75\x3f\xd9\x0f\x14\xa7\x7b\x3d\x81\xc4\x5d\xd3\x56\x1c\xd1\xfa\x0e\x94\xd2\x34\xce\xf9\xd7\x85\x9a\x2e\xc9\x42\xbf\xc1\x88\x49\xd7\xf2\xad\xa3\xa5\xd6\x57\xbc\x19\x3d\x2e\x14\x91\x68\x2f\x16\x65\xa5\x34\xb1\xac\x20\x83\xb7\x38\xbe\x8f\x9e\x96\x3f\x59\x41\xed\x48\x3c\x6a\xcc\x82\xe9\x59\xb8\x1b\x8a\xf0\x2f\x47\x1c\x08\xf5\xf8\xb1\x2e\x10\xe0\x08\x19\x28\x98\xa4\x45\x02\x02\xaf\x73\x15\x92\xe7\x4e\xfe\x2a\x94\x8e\x51\xd0\x6e\x44\xde\x9b\x95\x6b\x7b\xc9\xa6\x9b\x6e\x74\x68\x7a\xb2\x06\xde\xc4\xd3\x5b\x31\x73\xfb\xc4\x38\x82\x9d\x50\x64\xbf\xbc\xf7\x43\xc1\xe2\xd4\x6f\x62\x8f\x2e\x51\xc6\x26\xd8\xe4\x16\xd7\xbe\x6e\x55\x5a\x24\x96\x91\xab\xb1\x67\xf1\xd9\x2f\x4f\xa3\x39\x2f\xde\x24\xe9\x93\xce\x7f\xf5\xc1\xb8\xe1\x57\x7a\x7c\x0e\x73\x02\x5c\xc6\xfc\xd7\x27\xa8\x2e\xf0\xc1\x29\xe9\x1e\x55\x33\xe0\x21\xa3\xcd\xbb\x99\xd5\x4b\xf7\xcd\xcd\x3f\xf1\x19\x15\x4f\x3f\xad\x92\x42\xb6\xed\x35\x0d\x10\x37\x2c\x97\x6f\xf3\xa4\x37\xd0\x97\x86\x7d\x9b\xfb\xa9\x1d\x84\xbd\xa5\x5a\x6b\xcd\x6e\x36\x41\xb2\x13\xa2\x18\xb3\x04\x15\x89\xc5\x5a\xfb\xb3\x44\xde\x6e\x97\xd8\xc3\x5b\x5c\x86\xcf\x3b\xe0\x63\xf9\x01\xff\xee\xa8\xcc\x91\x06\x99\x67\xd2\x34\x60\x35\xa9\x1e\xb5\x70\x6a\x3b\x53\xf6\xd1\xc3\x4d\x4d\x21\x16\x70\x6b\x65\xc2\x98\xec\x57\xde\x82\xab\xc4\x00\x3c\xe8\xcc\x5e\x0b\x88\xff\x71\x0d\xda\x1d\xce\xf6\xf1\x54\x27\x71\x06\xb8\x3e\xb4\x6c\x04\x5b\x08\x2d\x11\x3b\x36\x1d\x6a\x62\x58\x08\xc9\x13\x05\x84\xdf\xc9\x67\x07\xef\x89\x55\x90\x7b\xaa\x61\xcf\x88\xc6\x6b\x6d\x1f\x60\x58\x11\x19\xcb\x62\x17\xa8\x52\x15\x73\x36\x17\x8c\x68\x5e\x6e\xd4\x85\x26\xed\x5c\x4e\x3b\x79\x67\xd5\x1f\x99\xdf\x68\x76\xa1\xac\xfb\x84\x5c\x57\x1b\x89\x86\x56\xe5\xe3\xbc\x73\x98\x0b\x9b\xed\x11\x98\x86\x63\x59\xc9\xe9\xb1\xef\xa9\x15\xf8\x10\xd1\xef\x8a\xd6\xcb\x3f\xc2\x1f\xbf\xe6\x54\x30\x6d\xe6\xca\x13\xa3\xa6\xa4\x8e\x7a\x13\xed\x87\x46\xac\xbd\x07\xf4\x8e\xb0\x0c\x36\x37\x4b\x1e\xb4\xf3\xf0\x1c\x19\xe2\xe8\xd3\x7e\x9f\xc0\x64\xb3\x3c\x0d\x66\x9b\xba\x55\x4d\xdc\x68\x21\xa7\x7b\x40\x89\xca\xbd\xca\xfc\x97\xf6\x0e\x60\x50\xbc\xa4\x44\xae\x8c\xfc\x44\xd9\x3c\x40\xef\x53\x18\xbe\xe6\xf8\xcf\x0c\x06\x7b\x85\xcd\xdd\xc4\x59\x74\xa4\xea\xcf\xc3\xef\x51\x31\x5b\xa0\xf3\xf6\x29\x68\xc7\x00\x3a\x7f\xf4\x44\x61\x24\x00\xb1\x59"}, +{{0x3b,0x6b,0xa6,0xd5,0xcc,0x9c,0xd6,0x24,0x1d,0x8b,0x00,0x97,0xa3,0x72,0x2e,0x4d,0x06,0x6f,0xea,0x3d,0x56,0x0a,0xea,0xb4,0x67,0x3e,0x86,0xf1,0xf8,0xec,0x60,0x26,},{0x8c,0xa6,0x52,0x07,0x17,0xcf,0x36,0x3c,0x4c,0xef,0xfa,0x76,0x32,0x8a,0x0a,0x16,0x6f,0xf8,0x3e,0x45,0xca,0x7d,0x19,0x1c,0xc8,0xef,0x6c,0xa6,0xe5,0x24,0x33,0x67,},{0x78,0x8c,0x9f,0x45,0x54,0xdd,0xba,0x5c,0x7d,0x64,0xba,0x75,0x9e,0xc4,0x56,0x94,0xec,0x79,0xfb,0x85,0xe8,0x23,0x68,0xa0,0x74,0xbd,0xd8,0xdf,0x34,0x42,0x13,0xa5,0x6d,0xd0,0x9f,0x33,0x4c,0xd9,0xac,0xb9,0x41,0xbe,0x28,0x3d,0x98,0xc4,0xb1,0x5d,0xcf,0xec,0xd1,0x4e,0x93,0xf6,0xa2,0xe3,0xcb,0x0c,0x1a,0xa2,0xde,0xe7,0xd9,0x0b,},"\x36\xde\x93\x0c\xc8\xe1\x88\x60\x83\x6a\x0c\x82\x9d\x89\xe9\x63\xa5\x8b\xdd\x9c\x6b\x6e\xf5\xbc\x61\xf7\x59\x92\xd2\x07\x52\x42\xdc\xa2\x3e\x28\xde\x20\x5a\x33\xdf\xea\x86\x1f\xc4\x4a\x32\x62\x8e\x8e\x7c\xdd\x3e\xd7\xff\x49\xea\x6a\x70\x97\xe0\x09\x0c\xfd\x9f\xf5\xec\xab\x1d\xe8\x22\xfc\x0a\x4c\x37\x76\xdd\x56\xc1\x91\x92\x04\x51\x6a\x94\xce\xc5\x63\x8d\xa1\xd9\x9e\x52\xb8\x66\xf5\xec\x41\x62\xa9\x12\xed\xb4\x1c\x1e\x92\xed\xfc\x35\x3f\x67\x05\xe1\xc1\x2c\xd4\x1c\xb6\x2d\xed\x4a\xd8\x15\x79\x40\x05\x9b\xfc\xf5\x07\x19\xd3\xf2\xad\x00\x84\x85\x40\xce\x89\xf3\xf9\xaf\xa6\x10\xcc\xba\x5e\xcc\x37\xe3\xe2\xc1\x53\x4f\xcb\x38\xfc\xd3\x9a\x2d\x14\xd5\xb5\xda\x6f\xea\x24\xe0\x06\x65\x4e\x30\x90\x47\xa2\x9c\xad\x0a\xe4\xda\x8e\x70\x8f\x97\xa1\x8c\xad\x5f\xbd\xc9\xac\x84\x40\x0c\x53\x2c\xed\x54\x88\x86\x53\x9e\xdd\x6c\x54\x10\x74\x79\x0a\xe4\x50\x2f\xdf\xe9\xf3\x27\x3a\x87\x6a\x21\x86\x23\xa2\x57\x06\xa1\x52\x5e\x67\xe5\x7a\x16\xd2\x2c\x21\xb6\xa4\x5e\x23\x84\xe2\x87\xac\x44\x52\xae\xc4\xe0\x63\x05\x6b\x4c\x17\x8a\xb0\xe5\xb2\xa5\xba\xd3\xf4\x63\xc4\x72\xc4\xea\x1f\x9c\x1a\x66\xe5\x27\x04\x73\xa8\x35\x09\x4e\x8f\x0e\xef\x68\x0c\xd7\xb2\x0d\x0e\x70\xf4\xd6\xc9\x58\xfe\xe0\x8a\x93\x60\xaa\x60\x66\x88\x8f\x4d\xd7\xce\x5e\xc2\x22\x59\xfa\x0b\x53\xfe\x92\x71\xc0\x83\xc6\xfc\xdb\x72\x83\xb0\x90\x61\x08\x8c\x52\xf7\x1b\xfd\xd2\x77\x7c\xe0\x80\x1f\x41\xa6\xc4\xce\x90\xef\x13\x1d\xe1\xe1\x83\xcb\x89\x49\xce\x32\x3c\x9e\xb1\x3a\x4b\x0c\xac\xf9\x9d\xef\xdf\xdb\x68\xd5\xed\x1f\x68\x91\xb4\x8e\x21\x04\x76\x68\xd6\x9d\xe8\xa8\x0f\x8e\x56\x34\xde\xd0\x87\x36\xa4\xfb\x54\x10\xcd\xea\x9c\x72\x59\x6e\x36\xdf\x68\x41\xf2\xee\xa4\x68\x50\xc8\x74\x73\xc8\x95\x54\x02\x05\xb0\x92\x19\x60\xff\xa5\xd9\xd8\xff\xb8\xe2\x9c\xde\x96\xa3\xed\xe0\x15\xac\xbc\x26\x97\x40\x04\xd3\xe4\x38\xa8\x5b\x2e\x33\x85\xf6\x4d\x18\x14\x00\x39\x41\xff\xd3\x63\x99\x2d\x39\x40\xc6\xe6\xd8\x1f\xf8\xe4\x5f\xce\xd6\xd3\x6c\xe1\x98\xd8\xcc\xbe\xfe\xe4\x32\xa7\x7d\x8f\xca\xdd\x73\xfb\x79\x9f\x6b\xaf\xef\xb5\x1a\x2d\xa7\x98\x72\x1c\x3d\x46\x5b\x16\x3e\xf1\x3e\x6e\xcc\x65\xe6\x03\xb2\x89\x3e\xe4\xcc\x9e\x1c\x6d\x1d\xe7\xa6\x5c\xab\x5c\xbd\xf5\x36\x85\x5e\x28\x8c\x3c\xcd\xa8\xd2\xfa\x3c\xe1\x0c\xf4\x93\x58\xa2\xef\x4e\xf0\x76\xe5\xbf\xa9\x1b\xbc\xf3\xd9\x66\xdf\xa3\xdc\x6e\x71\x2f\x19\x56\xd4\xe5\x8a\xa3\x6e\x71\x2d\xd3\x34\x71\x69\xb1\x9c\x8d\x44\xbe\xc5\xbc\xb7\x30\x77\x8f\xcc\xcc\x58\x9e\xd5\xd3\x50\xd4\x4c\x17\xbd\xe2\xee\xbb\x6f\x5e\xc5\x9f\xb2\x40\xd6\x7d\x81\xae\xa9\x26\x7f\x34\xf1\x5e\xee\x2d\xe3\xf4\xfa\x67\x39\x14\x79\xbd\xbb\x43\x0f\x48\x43\x70\xfb\x0e\x08\x95\xb9\xae\x06\x5b\xbd\xd4\x3e\x23\x0c\x62\xac\x07\x18\x4e\x8b\x06\xb2\x4b\x8b\x97\xec\x02\xdc\x6f\x37\xef\x61\x64\x1e\xd5\x6e\x3f\x5e\xb8\xd2\x08\x0b\x51\x44\xef\x76\x0b\x51\x87\x52\xe1\x97\x54\x79\x2e\x19\x34\x3a\x38\x55\xe1\xe2\xf7\xa7\xdc\x62\x35\x17\xee\xd2\xf5\xd2\x65\x48\xa6\x8e\xb8\xff\xd7\xbf\x70\xf7\x8f\xd1\x86\xdb\x63\x49\x28\xbb\x98\x13\x8f\x2b\x8f\xe8\x44\x81\xcc\x53\xf5\xaa\x35\xe2\x66\x6c\x63\x25\xe1\xd2\xb8\xac\x5e\x2d\xf2\x93\x5b\x7f\x64\x13\x95\x2d\x10\xd6\x07\x6f\xfc\x75\xbb\x6a\xf6\x3b\x29\xb0\xb9\x66\x3b\xec\x37\x24\x7b\x66\xb5\x08\xdd\xe4\x1f\x2f\x11\xb8\x43\x33\x55\x9d\xfa\xc7\x3f\x76\x1b\xcd\xa8\x4a\x48\xd2\x66\x07\x3a\xef\x16\x38\x46\x08\x49\xe7\xa1\x72\x06\xa2\x5f\x68\x00\x77\x0b\x91\x4c\xc0\x26\xba\xf9\xe3\x25\x59\x14\xe1\x32\x58\x44\x1c\xef\x35\xad\x1d\x66\x83\x3e\x98\x7e\xbe\x44\x31\xe6\xa6\xbb\x22\x2c\xbb\x65\xaf"}, +{{0xdd,0x99,0x87,0xb1,0x8f,0x9a,0x92,0x2c,0x0f,0x6f,0xea,0x18,0xeb,0x00,0xb8,0x96,0xc7,0xa2,0xd3,0x09,0x3d,0xb3,0xea,0x31,0xd3,0x84,0x21,0xda,0x0d,0xe5,0x12,0x31,},{0x57,0x39,0x21,0xa9,0x55,0xfe,0xb6,0xdd,0xe4,0x1b,0x05,0x5c,0x8d,0xac,0xac,0xcd,0x1d,0xb7,0xfe,0x9e,0x36,0xb5,0x09,0xd3,0xc9,0xe3,0x6f,0x97,0x35,0x75,0x23,0x24,},{0x3e,0x9f,0x2b,0x00,0x7c,0x0e,0x29,0xec,0x87,0x59,0x95,0xa6,0x30,0x9b,0x97,0x3d,0xeb,0x8b,0xaf,0x11,0x3d,0xed,0x13,0xf1,0xe0,0x00,0x3e,0x9b,0x9b,0xf9,0x39,0x16,0xa4,0xdf,0xe4,0x79,0x37,0xda,0xdf,0xc7,0x8a,0xa6,0x63,0xc5,0x5f,0x67,0x4e,0xc3,0x5c,0x38,0x46,0x25,0x8f,0x18,0xe7,0xbb,0x93,0xfb,0xba,0x3e,0x82,0x6a,0x1f,0x0d,},"\x48\x16\x2f\xdc\x3a\xbf\x73\x19\xc6\xca\xab\x60\xcb\x8d\x05\x20\x87\x5c\xb4\xee\x8a\x07\x09\x27\x83\x16\x7d\x47\x33\xff\xe5\x20\x4e\x5f\xeb\xe7\xd2\x91\xe9\x53\x6b\xde\xa3\xdf\x06\x37\x15\x9a\x65\x3e\x09\xfd\x99\xaf\x66\x1d\x83\x00\xae\x74\x1a\x3e\x91\xa8\xbd\x85\xea\xd0\x5d\xc7\xd9\xe6\xf9\x29\x32\x33\x16\xed\xc4\xca\x62\x4e\xa7\x81\x8b\x25\xbd\xc0\x61\xf7\x14\x92\xfd\x22\xd4\x65\xab\x22\x6f\xd9\xa1\x0d\x8b\xab\xfc\x07\x4c\x68\x6c\x43\x6c\x24\xa3\xa5\x3f\x8f\xf3\x89\xce\x9c\xa1\xdb\xc8\x90\x74\x45\x88\x92\x41\xf8\xfd\xa3\xa7\xa3\xf5\x02\x4f\xa8\xcb\x0d\x04\x4b\xda\xf6\x71\x6d\x98\x3a\x6d\x83\x98\x14\xff\xe7\x0d\xdc\x55\xbb\xba\x11\xac\x97\x88\x7b\xdb\x4d\xad\xa9\x65\x65\xbb\x07\x5d\x5f\xc1\xd3\xc5\x24\x4b\x9f\xff\x77\xde\x58\x72\x9a\x05\x9a\x91\x1f\xb3\xe0\xeb\x16\x4f\xb8\x42\x9e\x26\x56\x85\xd1\x4a\x63\x23\x30\x46\xd2\x0e\xcf\x28\x9c\x55\x72\x31\x69\xa9\xd6\x3d\xda\x0d\x52\x55\x15\x3d\x9e\xf4\xa6\x1b\x92\x12\xf4\xb8\x20\x69\x7a\xe7\xc3\x08\xcf\xab\x40\x3b\x2c\x34\x31\x90\x62\x26\xe4\x5c\xe2\x19\x20\xdf\x52\x01\x60\x9d\xaf\x83\x0f\x28\xad\x79\x60\x05\xa9\xbd\x8e\xba\x62\x0c\xf8\x39\xc3\xba\x22\x7b\x96\x3c\x7b\xd0\x91\x48\x22\xdf\x2c\xa0\x3c\x22\x54\xd0\xcb\x8a\xca\xe0\xd5\x9e\x4c\x3e\x0e\xc2\x15\xc8\x36\x96\x9d\xcd\x1d\x49\xbf\xe1\x97\xe2\xf3\xee\xa3\xfa\x8a\x37\x3b\x55\x8d\x0f\xb9\x06\x3c\xf1\x56\x8e\x73\x9a\xad\x8f\x09\xfb\x43\x7c\xaf\xb5\xa2\x72\x37\x5f\x43\x60\x64\xee\xe1\x1b\xd9\x03\xd3\xaa\xea\xb4\xe3\xfd\xcd\x36\xbd\x20\x76\xee\xa1\x79\xa4\xf0\xd4\xfb\xc8\xdf\x42\xbf\x26\x60\xf0\x8d\xe7\xd5\xc6\x39\x7c\xae\x10\xb7\x27\x74\x58\xaa\x6c\xfa\x01\xe8\xa6\x73\x7e\xb1\x26\x22\x78\x56\x64\x66\x91\x68\x1c\x10\x6a\x15\x7a\x26\xae\xd2\x1b\x1a\xaf\x0e\xd2\x76\x64\x21\xcf\xc3\xd1\xc7\xdd\xfb\x72\xfc\xdf\x4b\x8b\x49\x0f\xc0\x9a\xce\x49\xae\xdd\x77\x12\xb2\x1a\xc5\x6f\x86\x01\xf6\x25\x56\x3c\x78\x43\x06\xf3\xb9\x17\x4a\xdd\xf7\x64\xe0\x51\xaa\xdf\xe1\x28\x31\xaf\x96\x69\xe6\x2c\xab\x12\x1c\x74\xdf\x34\x37\x24\x42\x9d\x6c\x26\x66\x02\x71\xc3\x2f\x40\xcf\x7c\x2d\x08\xbd\x0a\xfc\xc7\x28\xde\xf4\x13\x5d\x4e\xb5\x5b\x6a\x3e\x76\x29\xd8\x06\x86\x4a\x85\xb3\x6a\x32\xb9\xb2\x1a\xc0\xd3\x96\x80\xa2\xae\x4e\xc4\x18\x97\x09\x17\x8e\x34\x94\x97\xf3\x93\x99\xfb\xc7\x8b\x3c\x6c\xfa\xca\x6e\xde\xa7\xc3\x3d\xda\x3c\xc1\x1e\x43\x84\xf1\x58\x3d\x6c\xfc\x6b\x58\xf4\xea\xa2\xbc\x56\xab\xa4\x2f\x73\x8a\x42\x9b\x93\x58\x08\x50\xde\xe3\xfd\x25\x39\x94\xf8\xb0\xfa\x66\xee\x8e\x27\x3d\xec\xab\xd5\x32\x09\x5f\xb0\x4a\x4a\x3c\x34\x0a\xf0\xe5\x5b\x57\xef\xab\x43\x63\x0f\xc0\x2e\xf2\x0b\x42\x5c\xa2\x18\x7e\x3c\x6c\x5e\x10\xf1\x2d\x61\x8f\xd2\x43\xa2\x24\xf6\x50\x1e\xbe\xb9\xd3\x21\xc6\x38\x5b\x81\x27\xef\x9c\xdc\xd0\x97\xce\x7f\xa0\x21\xcf\x40\xd2\x1c\x39\x91\x23\x43\xf6\x7a\xcc\xe1\x82\x5e\x3a\x51\xb8\xa7\x18\xe8\xc3\x40\x62\x2f\xff\x65\xfe\x00\x53\xd2\x4a\xa3\x35\x1b\x6a\x24\x00\x18\x5d\x7a\xeb\x88\xe8\x7a\xc4\xa1\xd3\x94\x90\x9d\x49\x41\x4a\xef\xc2\x2b\xa0\x09\xaf\xf6\x96\x2c\x92\x17\xd7\x55\x69\x4e\x4d\x6a\xa8\xa5\xd6\xa8\x03\xce\xbb\x15\xde\x8f\x54\x16\x34\xb6\xfc\xeb\x0c\xac\x79\xdd\xa8\xa1\x8e\xef\xbb\x53\x7e\x70\xff\xe9\xaa\x5a\x6a\x6a\xaf\x92\x40\xfa\xc2\xea\xcb\xfb\xef\x01\xad\x6b\xdf\x50\x75\x87\x80\xf8\x6a\x4e\x48\x89\x85\x36\x2d\x58\x25\x01\x1f\x5e\x8b\x66\x42\x5a\x61\x6b\x7e\x10\x4e\xb2\x3f\xe8\xf1\x00\xcb\x02\x49\x82\x36\x62\xbd\xa3\xda\x47\xa4\xc3\xc1\xca\x2f\x91\x4b\x25\xb9\x73\x85\x34\x02\x60\x47\xdf\x6d\x7f\xf6\x31\xdf\x2c\x41\x31\xf6\x80\xe1\x37\x43\xc9\xcc\xf2"}, +{{0x38,0xd2,0xef,0x50,0x9f,0x93,0x05,0x1f,0x14,0x51,0x67,0x73,0x7c,0x22,0xe1,0xa5,0xbf,0xe8,0xf4,0xa9,0x1e,0xba,0x0b,0xb8,0x7c,0x39,0xce,0x04,0xa8,0x9b,0xae,0xc6,},{0x01,0x11,0x5f,0x6d,0x89,0xa5,0xda,0xab,0x54,0xf8,0x92,0xbb,0x4a,0x4b,0xda,0x1c,0xe5,0xd8,0xf6,0xc9,0xc8,0x8a,0x50,0xce,0xe8,0x3b,0xd9,0x87,0xa2,0xc0,0xdd,0xf7,},{0xde,0xc4,0x62,0x53,0x50,0x9b,0x11,0xe4,0xb5,0x2a,0x6a,0xe4,0xf3,0x66,0xb6,0x80,0xdf,0xfc,0x28,0x0d,0x0a,0x04,0x4f,0xc0,0xcb,0x79,0x0b,0x6e,0x75,0x13,0x81,0x46,0x1e,0x1e,0x60,0x2a,0x89,0xe3,0xb3,0xd3,0x06,0x4c,0x40,0x7f,0x60,0x2f,0x1c,0x22,0x40,0x4b,0x68,0x23,0xbd,0x24,0x67,0x54,0x93,0x14,0xa0,0x00,0x01,0x66,0x4a,0x08,},"\x42\x7b\x5a\x01\xe8\x59\x7f\x04\xfd\x42\x2f\x0a\x66\x2d\x0b\xe2\xdf\xa8\x53\xed\x5f\x9d\x3f\x60\xff\x90\xf2\xc5\xee\x08\xbb\x59\xfd\x03\xd4\x02\xb7\x54\xca\xf5\x4d\x00\x58\xf5\xa2\xcf\x87\xaf\x4f\xef\x21\x77\xd5\x9e\x18\x22\x62\x93\xfd\x2a\xf3\x76\xbc\x98\x7b\xf7\xb3\x20\xb9\xd1\xe2\x49\xab\x9e\xfb\x75\x07\x8e\x6d\x3d\xf2\x9e\x03\x50\x47\x76\x35\x43\x44\xaa\x69\xe7\x2e\x1e\xbc\x52\xa3\xc3\x8a\x4c\x2a\x16\x73\xb4\xe9\x74\xa2\xe4\xe1\x2a\x2e\x78\xea\x3e\x3f\xe5\x0c\x53\x63\x0d\x09\x6d\xa3\xe2\xfe\x82\x99\xf7\x1a\x1b\x44\x1b\x4c\xf0\xca\xeb\x93\x7a\xfa\x4a\x0e\x39\x15\xcc\xab\x39\x96\xc9\xf6\xa8\xf4\xfd\x37\x54\x3e\x8f\x75\x90\x0c\xfd\x47\x17\x53\x70\xef\xb8\x52\xa5\xf6\x9d\x67\x36\x83\xf9\x98\xfd\xcf\xf8\x5f\xf8\xf3\x2b\xaa\x80\x70\x66\x60\x44\x22\x02\x7d\x51\xa4\x35\xdd\xf9\x88\xed\x2f\xd8\xeb\x19\x1f\x10\xb4\x68\x07\x42\x00\x08\x75\x6e\xb4\xe3\x00\xc4\x09\x9c\x2d\x64\x50\xbc\xc6\xa4\xe7\xd0\x67\x31\x56\xb8\x37\xf0\x50\x63\x38\xf3\xd1\xb5\x73\x4b\x16\x6c\xa5\xcc\x2f\x24\xa4\xef\x02\x6c\xda\x2c\x4a\xe3\x10\x5b\x63\xca\x85\x70\xd1\x85\x46\xcf\xac\xb8\x60\x42\x96\x6a\x00\xef\x52\xc7\x29\x90\x19\xf6\x8a\x2d\xf0\x8c\x8b\x70\x4e\x85\xe7\x13\xc3\x48\xd7\xf1\x67\x76\x60\xe1\x8e\xba\xb5\x9b\xf4\xe1\x2e\x6f\xf2\xd7\x83\xd8\xd5\xd4\x2a\xab\x6e\xf0\x17\xb7\xa1\x96\x6a\xee\x8d\xc1\x4d\xda\xbe\xd4\x9b\x4b\x64\x3d\xf4\xe9\xb0\xb6\x03\x83\xc7\xd8\xb4\xb8\x8c\x65\xa8\x98\xc1\xc7\x7d\x43\xd6\xbd\x68\xb2\xa5\x74\x3f\x1f\xed\xd6\x54\xdc\x84\x49\x6d\xa0\x2c\xeb\x69\xb9\xb4\xd3\xa8\xe0\x0c\xcd\x72\xe7\xc7\x5f\xc5\x0a\x8d\xd0\x87\xe1\x83\xe6\xc1\xf5\x79\xba\xeb\xc5\xc6\x3f\x28\x07\x93\x67\x91\xb5\xfe\x48\x47\xcd\xcf\x15\x17\x74\x23\x52\x05\xcd\x2d\x7b\x8b\xf4\xae\x88\x19\x22\x5e\xa7\x08\xb7\xba\xac\x66\x99\x8f\x0c\xba\xb2\xc7\xdd\xf2\x51\xf3\xb1\xde\x10\x17\xd3\x97\x69\x22\x05\xee\xa6\x39\xf1\x2d\x77\xbe\xef\x6c\x13\xbb\x12\x10\x0f\xf8\x90\x64\x70\xbc\x7b\x21\x29\x80\x53\xbe\x1a\x61\xb7\xb3\xa4\x99\xed\xc3\x10\x99\x6c\x8b\xc0\x87\x19\x07\xca\x46\x8e\x89\xed\x31\x1a\xdc\xa2\xe2\xb8\x29\x30\x97\x5b\x3e\xfb\xbf\xc0\x3c\xdd\xf4\xd9\x48\xc4\x76\x5e\x8c\x10\x59\x08\x82\x16\x9a\xcd\xdb\x8f\x8c\x36\xd8\x4c\x2d\xac\x3b\x79\x8e\x7a\xbf\x84\x47\x12\xfa\x45\x8d\x27\x7c\x24\xe8\x14\x04\x7d\x74\x23\x19\xa8\x34\xdd\x9f\x92\x7a\x2b\x44\x85\xef\x13\x74\x5f\x7a\x60\xdd\x6b\xb3\x37\x93\x63\x04\xc9\x7d\x3f\x9f\x14\x4e\xb2\x9b\xb6\x95\xb8\xdc\x31\xb9\xd8\x49\x10\x61\x1d\x28\xd5\x81\xca\xa9\x36\x5d\x6d\xff\x52\xd4\x10\xa4\xad\x52\xbd\x12\x17\x29\xff\xf5\x28\x88\xf4\xda\xae\x17\x07\xf6\xf5\x6d\xac\x61\xff\xb9\x96\x1c\xda\x71\x76\xaf\x44\x60\xa6\xd5\x54\x2a\x20\x44\x6f\xb5\x14\x7f\xce\x72\x72\x04\xce\xc6\x89\x9b\x9a\x3d\x4f\xf6\x22\x6b\xb8\xa1\xc7\x8e\x36\xfc\xdd\x9e\x50\xc0\x40\xd7\x2d\x0f\x40\x07\xd3\xfa\x9a\xa7\x67\xe4\xab\xd0\xad\xd6\x2f\xdb\xcc\xde\xff\x67\x21\xeb\x25\x9e\x00\xa7\x21\x63\x20\x06\xbe\xde\x0d\x17\x3d\x38\x34\x4d\xea\x44\xf9\x6b\x67\xd9\xa2\xee\xa1\xd2\xaf\x5f\x74\x8e\x8e\xbd\xb4\x41\xbf\xb4\xe5\x8e\x2d\x42\xfe\xc7\x40\x56\x6a\xcf\x73\xa3\x03\x35\x8f\x7d\x89\xc8\x15\x8c\xf2\x1f\xe8\x5b\x0d\x4a\x41\x7e\xbd\xc8\x6d\x04\x69\xf6\xb9\x1c\x24\xad\x61\x0d\x48\x6d\xed\xc2\x18\xb2\xce\x7a\x8b\x96\x75\x47\x23\x15\x1f\x0d\x00\x76\xff\xf9\xf1\x9d\x11\x2d\x9c\x05\x92\xfb\x8d\x92\xc9\x9d\xcb\x8d\xdf\xaa\x46\xfb\xe0\xd9\x2d\xf4\x6b\x8c\x00\xca\x43\x45\xad\xb6\x9a\x5a\xca\x69\x4a\x86\xcf\x30\x64\x64\x51\xbb\x17\xba\x6e\x60\x7a\x91\x2b\xf1\x09\xd5\xfc\x2d\x3e\x27\xd0\x0d\x94\x56\x00\xa8\xa5\x7c"}, +{{0x43,0xbf,0xb3,0xdb,0xe4,0xd9,0xbd,0xaa,0x82,0xb3,0x54,0xdd,0x59,0x63,0x34,0xe6,0x60,0xd7,0x6f,0xc0,0xb2,0xeb,0x69,0x89,0x93,0xae,0xf3,0x76,0x7f,0x1c,0x7c,0x7f,},{0xd0,0x0a,0xec,0xef,0xf0,0xce,0xb8,0x32,0xc2,0x51,0xd1,0xfe,0x6b,0xcb,0xea,0xea,0xcb,0xb4,0x11,0x3f,0x52,0x81,0xba,0xba,0x4e,0x87,0x8f,0x7b,0x95,0xf9,0x3f,0x07,},{0xa9,0x99,0x55,0x23,0x02,0x0a,0x0d,0x22,0x2b,0xc4,0x8f,0x98,0xd0,0x55,0x04,0xe3,0x06,0x8f,0x30,0x4a,0x6d,0x19,0x70,0x06,0xcc,0x9c,0x03,0x5e,0xea,0xde,0x09,0x9e,0x7a,0xa9,0x7e,0x90,0x89,0x4e,0xad,0x17,0xe8,0xc3,0x0b,0x0a,0xa4,0xa9,0x80,0x88,0xf0,0x38,0xb9,0x22,0x44,0xc4,0xb2,0x0f,0xde,0x96,0x4f,0x85,0x34,0xe8,0xfb,0x03,},"\x3f\x3e\xed\xdc\xae\xf4\xe1\x66\x2a\xdb\x66\xbb\x1b\x20\x7d\x79\x3f\xcb\xef\x81\x50\x05\xe8\x26\x43\xed\x70\xc9\x85\x54\x03\xda\xc2\x8b\x52\x07\x27\xa9\x01\xa5\x32\xd2\x8b\x9b\xd1\x34\x8d\xb2\xf8\x96\x7b\xbb\x8c\x90\x98\xb0\x7f\x57\x0a\x2e\xae\x1e\xe4\x82\x64\x0c\x0b\x67\xa5\x2a\x38\x61\x21\x33\xa1\x5e\x25\x8e\xde\x38\xcd\xa8\x78\xff\x36\xed\x32\x1d\xff\x87\xcc\x6a\x01\x38\x3b\xa8\x40\x67\xd6\x0a\xf4\x17\x76\xac\xf8\x0a\x8a\x4e\xac\x77\xf7\xd8\x7c\x37\xa7\x04\xa3\xe2\xac\xa1\xe8\x81\x5e\x49\xfb\xca\xb7\x97\xc8\x56\x52\x95\x38\xbe\x07\xd5\x16\x96\x32\x1f\x69\xb0\x9b\x5d\xc5\xa1\x5e\x5f\x0e\x4c\x22\xd2\x28\x37\xf6\x2e\xe4\xc8\xbc\x7f\x25\xa9\x48\x7b\x96\x2c\xc2\x0f\x13\x3f\xcb\x87\x0e\xd1\x25\xcc\xa5\x85\xd1\x81\xbd\x39\xf9\xdf\xa6\x61\xf1\x9b\xe7\x6d\xa7\xf6\x5f\x22\xfb\xbc\x80\x75\x2a\xeb\x39\xe8\xd5\x9e\xd9\x6e\x14\xf5\x95\xd0\x49\x29\x40\x2b\x50\x29\xc6\x0c\xee\x37\xc0\x21\x7b\xc5\x31\xd8\x0d\xb3\x41\xda\xce\x3c\xce\x76\xe6\x43\xaa\xc5\x38\x87\x47\x3e\xdc\x6e\x19\xcb\x39\xfe\xcf\x6a\xf4\x24\xa2\x06\x63\x93\xd1\xc3\x3f\xc7\xb9\x36\x76\xd7\xe6\x10\x5b\x9b\xfc\x96\x7d\x1e\x29\xaf\xdc\x4c\xf1\x5b\xca\xfa\x09\xc2\x95\xa6\xf9\xde\xee\x33\x1a\xb3\xb0\xd4\x93\x12\x6e\x2b\x2f\xff\xb4\x2a\x6b\x68\xe7\x9e\x13\x8d\xb5\x50\x82\x72\x62\xe4\x87\xa8\x3f\x37\xf0\x1d\xd7\x92\x2b\xe7\x5e\x92\xfc\xf5\xd9\xd4\x80\x3b\x3a\xc2\xf3\x5d\xa2\x10\xfb\x38\xb2\x63\xb0\xff\xb6\xc2\x70\x8d\x4b\x55\xb7\x57\xaf\x52\x07\x7a\x7e\x31\x84\xd0\x1e\x82\xf6\x4d\x32\xcc\xe4\xfd\xee\x0f\x8d\x4e\x36\x4b\xcf\xb9\x58\xeb\xbf\xdb\xb6\x22\xb3\x8b\x51\xe9\x30\x27\x1c\x7b\x1b\x70\xaa\x9d\x4b\xb3\xaa\x4b\x99\x7c\x52\x14\x4d\x3a\xa6\x21\x62\x57\x3a\x3a\x1d\x9c\xe4\x6c\xdb\xee\xb8\x44\x9f\x12\x25\xc4\x49\x63\x1e\x88\x97\x52\x1c\xd0\xf6\x37\xb7\x21\xa1\x25\x2b\x8a\x10\xab\x0b\xe8\x70\xaf\xbc\xd8\x9d\x58\xb2\xeb\xb6\x32\x11\x95\x0c\xad\x7a\xb8\x2c\x81\x95\x02\x6b\x50\xea\x8b\x77\xb9\xe9\x0e\xd5\x59\xaf\x44\x84\x30\x88\x51\xa3\xa1\x56\x71\x68\x53\xa8\xac\x4e\xcb\x8c\x5c\xc7\xd9\x35\xb0\xf4\x66\x12\x41\x43\xb1\x17\x7f\x05\xd0\x8b\x97\xd1\xad\x54\x2e\xd2\xc2\x46\x5a\xf1\x85\xe7\xdb\x42\xb6\x9c\xb8\x02\xa7\x17\x94\xa3\x13\x98\x83\x02\x96\x70\xc9\x56\x74\x2a\xaa\xd7\x90\x7a\x71\xd9\x59\x85\xfc\x1d\x45\xb6\x59\x97\xb4\xec\x6c\xe8\x25\x5d\xe9\x59\x27\x0a\xfa\x7d\xe9\x0f\x29\x29\xde\x63\xf9\xb1\x72\x11\xd7\xf1\xae\x82\x0a\xda\x9c\xe3\xe4\x86\x49\x17\x9d\x60\xb0\x14\x94\x93\x48\x1f\x01\xd4\x59\xdb\x7d\xad\x05\x26\xb5\xbd\x9f\x4b\x33\x80\xd2\x5b\xa2\xc5\x02\xba\x8f\xa3\xc4\xd4\x13\x1b\x46\x62\xad\xde\xfb\x41\x82\x7f\x75\x9f\xa7\x1d\x44\x7d\x5f\x02\x92\x45\xf4\x8c\x62\x2e\xb7\xc6\x8c\x8e\x71\x08\x1f\x7f\x78\x9d\xe7\xa2\x83\xd2\xed\xa8\x3a\x7d\x17\x22\xa0\x5f\xb7\x2e\x17\x60\xc2\x40\x40\xc4\xd8\x34\xde\xf5\xdf\x5f\x74\x2e\x02\xb3\x04\x51\xc8\x93\xbc\xf7\xd7\x71\xdb\x78\x4c\xbb\xda\xec\x87\x6d\x8a\xc8\x67\x43\xb5\x29\xa2\x92\x00\x7a\xc7\x53\xc9\x9a\x57\x99\xcc\x32\x4f\xe5\xeb\xb5\x44\x8a\xb5\x54\xb1\x0d\x41\x36\x97\x4a\x12\x54\x2d\x25\xc6\x14\x7c\x67\xc5\xd2\x33\x6c\x9d\xb7\x5c\xba\x2f\xd6\x08\xcd\x43\xab\x95\xbe\xac\xd0\x43\xa1\x34\x9c\xef\xa8\x28\xe2\x3b\x5f\x0b\x6e\x0e\x29\x51\xf3\x35\x3b\xb9\x2b\xfd\x1f\x0a\x49\xc3\x3f\xb3\xcf\x37\x99\xa0\xb5\x43\x19\x8a\xd5\xd0\x3d\x26\x3c\x1a\x06\xc3\x5a\x26\xad\xe1\x51\x84\x91\xc8\xc1\xd2\x7a\x2d\xb0\x33\x80\x89\x32\xcd\x1c\x47\xb5\xa1\x26\x98\x5a\xcb\x8d\x88\x83\x60\xee\xcc\xfe\xb3\xbf\x51\xb0\xd1\x89\xb4\x19\x04\x40\x40\x4d\x12\xfb\xa6\x5d\x0a\x7a\x14\xc6\x20\xc5\x55\xf8\x22"}, +{{0x51,0x4e,0x07,0x0b,0x01,0x90,0xd1,0x8c,0xbe,0x98,0x1a,0x5a,0x15,0x1e,0x77,0x53,0x39,0x8a,0x27,0x2b,0xcf,0x01,0x48,0x13,0xad,0x37,0x97,0x22,0xc3,0x6e,0x13,0x3d,},{0x6f,0xbd,0xe0,0x47,0x4c,0xc4,0x81,0x0e,0xff,0xa5,0x0a,0x07,0x82,0x0c,0x96,0x5a,0xa0,0x03,0x95,0xff,0x3a,0x5b,0x3e,0x2e,0xdd,0x7d,0x35,0x6b,0x7d,0x6a,0xef,0x2b,},{0xb6,0xc3,0x55,0xc9,0x58,0xb5,0xba,0xa7,0xeb,0xe9,0x77,0xa9,0x3f,0xcf,0x53,0x95,0x89,0xa3,0x66,0xd4,0x01,0x60,0xe4,0xe0,0x31,0xb8,0x8a,0xb9,0x64,0x02,0xc7,0xbd,0x57,0x7f,0xf6,0x35,0xfc,0x07,0x78,0x24,0x23,0x59,0x8d,0xca,0x43,0x66,0x81,0x24,0xa8,0xb2,0x87,0x51,0x0e,0x2c,0xfd,0x07,0xa1,0xe8,0xf6,0x19,0xf6,0xc8,0x54,0x0a,},"\x83\x14\x55\x76\x2a\x5d\x80\x09\x7b\xb2\x84\x50\x42\xf4\xc8\x76\xe7\x10\x85\x35\xbe\xd6\x83\xe8\xc4\x46\x19\xd0\x81\x54\xa2\x29\x44\x4b\x10\x1e\x3e\xd7\xc0\x15\x07\xe8\x70\x94\x14\x46\xaf\x97\x8c\x0f\x53\x41\xd1\xac\x1d\xd1\x5b\x14\xe8\x96\x67\x12\xdf\x19\xf5\x2f\xeb\x51\x03\xcf\x62\xb6\x63\x27\x56\x44\x6c\xc7\x54\xdf\x00\xa3\xf6\xdd\x71\x99\x68\xa2\xce\xf6\x6c\x3a\xdf\xb7\xd1\xfc\x49\x1f\xbb\xf3\xd5\x92\x94\xab\x34\x61\x9e\x17\x6d\xb0\xd4\x46\x15\x1e\x37\xea\xa3\xda\xf1\x72\x40\x6e\x98\x3d\x9d\x23\xa6\xb6\x9e\x92\x97\x60\x30\xf5\xac\x70\x40\xad\x51\x14\x12\x9f\xea\xf9\x7a\xf1\x5b\x22\x96\xfa\xe7\x04\x92\xdb\xbe\xb2\xb4\x82\x76\x87\xfb\x79\x87\x15\xc9\xbb\x2c\x32\x55\x7a\x81\xd8\x91\xb8\x97\x05\x29\x00\x70\x71\x59\x75\x1f\x07\xdb\x07\x4c\x77\xf0\x71\x96\x71\xf1\x76\x66\x89\x02\x9a\x3c\xdd\xf3\x9d\xf3\x48\x3c\xf2\xb0\x4f\x71\xc2\x5d\xe0\x5f\xc2\xd0\x2b\xb4\x8e\x53\x9e\xaf\x1a\x32\x16\x46\xcd\x80\xef\x2f\x0a\xc7\x03\xf4\x5e\x73\x89\x53\x08\x00\xe5\xd4\x17\xcc\xea\x8a\x5c\x08\x66\x82\xf0\x47\x45\xd5\x0b\x5d\xfc\x8f\x6e\xdc\x87\xa9\x5c\x7d\x20\x2a\x9c\xfd\x99\x87\x14\xb7\x46\x92\x0e\xbb\xe2\x33\x5b\xca\x1a\x01\x71\x76\x20\x16\xf5\xe4\xbd\xa8\x9c\x57\xd0\xed\xc6\x91\x0c\x6d\x22\xc8\xf9\x09\xda\x3d\xb1\x35\x2f\x0c\x8b\xd1\x8f\x3b\x5a\xac\x25\xf1\x93\xb8\x94\x70\xf9\x76\xbc\x4f\x1a\xff\xb3\xc6\x6b\xc5\x87\x6c\x6f\xe2\xac\x75\x08\x53\x3d\x97\xbb\xcf\x77\x11\x9d\x9a\xae\x19\x3f\x07\xe0\xb6\x4b\x46\x1c\x9c\x6c\x3b\x9d\x29\x3b\xd3\x7d\xe3\xd8\xe1\xab\x1e\x8d\x87\x2c\xd9\x4e\x6c\xf0\xeb\x68\x43\x9f\xdc\xd3\xb2\x5c\xe8\x48\x34\x60\xbd\x8b\x7c\xce\x88\x9f\xb7\x22\xb4\x36\x1e\x11\x8d\xa9\x83\xef\x4a\x9e\x45\xce\xbc\x0c\x1b\x82\x29\xea\x53\xe6\xf5\x55\x05\xf6\x44\xe0\x9a\xca\xa4\xc4\xb8\xcc\x64\x0b\x2c\xd2\xb3\x12\xe1\xc3\xa2\xc0\x26\x69\xe1\xf9\xc0\x63\x11\xc7\x8d\x36\x00\x09\xdb\x9e\x67\xc3\x9b\x49\xd1\xe5\xd7\x70\xc0\x1d\x28\x4b\x0a\x17\xa4\x1b\x4e\x7c\xa7\x45\xd6\x65\xec\x07\x50\x0e\x4d\x9f\xc8\xeb\xc1\xcc\x6a\xf5\x3a\x3f\xc7\x6b\x0c\x3f\x14\x31\xd4\x98\x43\xf2\x0e\x18\x27\x82\xc8\x2b\x3b\x5a\xae\x36\xfe\x20\xca\x64\x26\x18\x06\x8b\xe2\x33\xd4\xb5\xef\x9e\xae\xff\x40\x15\x36\xdc\x59\x3a\x2b\xc1\x83\x44\xf5\x5a\xc5\xd5\xfc\x7b\x3e\xb5\x06\xd1\x1c\xb3\x75\x33\x00\x63\xc6\x20\xc5\x33\x4d\x72\x3c\x7d\x1f\x04\x28\x16\xbc\x47\x85\xb3\x5a\xc0\xe6\xf1\x74\xf7\x36\x87\x8b\x7b\x49\x16\x58\xca\x67\xd8\xfc\xab\x53\x8f\xc6\xec\xd2\x77\xea\xd9\x0d\x95\x4b\x46\x0d\xa4\x25\x3a\x1c\x3a\x30\xb3\xd8\x92\x8f\x69\xac\x98\x76\xa2\x89\x19\x69\xfc\x2d\x06\xa6\x68\x99\x2b\x8e\x21\x15\xdf\xe5\x35\x8a\x71\x24\xba\x7c\xcf\x42\x1d\x80\x54\xea\x04\x34\x44\xcd\xeb\x40\xb7\x16\xdc\x7a\x36\x59\xa3\xca\x94\x34\x72\x93\x48\x90\x60\xe2\xcf\x67\x12\xa2\xa6\xc7\xb8\xad\x14\x67\x85\xfc\x40\xcc\xb9\xda\x28\x78\x30\xd0\x11\xd0\xd2\x4d\xf3\xe7\xaf\xbe\x97\x2d\x6f\x41\x7d\xe5\xcd\x75\xf2\x59\xea\x07\xca\xfd\xde\x20\x5f\xc0\xa3\x65\x13\x5c\x23\x2c\xbd\x7c\x1b\xc5\x39\xfa\x4b\x7e\x1c\xce\x35\x18\x52\x37\xc2\x3f\x80\xae\x97\xc1\x86\xd0\xd3\xb1\x05\x03\xd5\x98\x4a\x20\xec\x41\xc3\xcd\x04\x2c\x28\xa4\xc3\x1f\x95\x74\xb0\x6a\x87\x2b\xf9\x59\xab\x0a\xdd\x1f\x5d\xee\x14\xa1\xe7\x41\xef\x23\x8d\xfc\xde\xc0\x85\xaa\x08\x8d\xcf\x39\xa3\x6d\xda\x8f\x2a\x85\xed\x0d\x36\x2c\xcb\x00\x5d\x02\xe5\xac\xcc\x09\x2a\x37\x6d\xc1\x1a\x56\x61\x70\xd5\x83\xdb\x35\xf1\xde\x0b\xe3\xf1\x59\x08\x59\x6e\x9b\x78\x1a\xc8\x1b\xe0\x7b\x9b\xd2\xaf\x46\xc5\x6f\xb4\xd9\xd8\x42\x76\x01\x1e\x46\x18\xb7\xf7\x6f\x96\x79\x4c\xd0\xfd\x57\xed\x41\x4b\x63"}, +{{0xbc,0x79,0x0a,0x73,0x85,0xdd,0x1d,0xdd,0xc7,0x62,0xe3,0xb2,0x02,0x21,0xdc,0x07,0x8b,0x6c,0x3d,0xa8,0x98,0x6d,0x41,0x80,0x94,0x07,0x27,0x25,0x7c,0xfd,0xcd,0xf1,},{0xc9,0x26,0x46,0x26,0xf6,0x8f,0xed,0xb5,0xb3,0x9c,0x28,0xf0,0x30,0x45,0x3b,0x54,0xd0,0xd5,0x1a,0x98,0xb1,0x77,0x21,0xf2,0x61,0x1d,0x7f,0x27,0x7e,0xf4,0x8b,0x81,},{0x6d,0x6b,0xd6,0x5f,0x37,0x26,0x79,0xfe,0x9d,0x94,0x5f,0xf5,0x65,0x16,0x33,0x3e,0xce,0x0b,0x7a,0x25,0xb1,0x5a,0xd2,0x48,0x73,0x81,0x67,0x0e,0x53,0x6f,0x52,0x46,0x77,0x5e,0xb3,0x9a,0x11,0x4d,0xb2,0xb9,0xcd,0x50,0xf3,0x12,0xb3,0x60,0xd9,0xd0,0xbe,0xa2,0x95,0xdc,0x37,0xb8,0x17,0xb3,0x32,0x89,0x0a,0xdb,0x65,0xe4,0xc4,0x01,},"\x14\x3d\xd7\xbf\xbf\xf2\xad\xc7\x1f\x5d\x12\x3d\x47\x4e\xa0\x69\xdf\x14\xae\x92\x3e\xd9\xbf\x8f\x98\x91\xe6\x0b\xae\x43\xf0\xc9\xf5\x55\x37\xac\x9d\x1a\xe5\x23\xce\x4e\xcf\xd3\x3b\x20\xae\x44\x5e\x9c\x42\x63\x72\x05\x0f\xa5\x21\x7c\x1e\x4f\xb0\x13\x53\xeb\xf2\xe3\x29\x04\xef\x7e\xef\xcf\x72\xe8\x02\x3b\xae\x06\xbb\xb6\x40\xcf\x77\x7d\x5b\x0e\x11\x52\x7b\xc8\x35\x49\x3a\xd6\x98\x0a\x15\x7b\xb2\xd5\x0b\xe2\x33\x65\xe7\x2c\xbf\x0b\x3f\x20\x9e\xf0\xc4\x4a\x00\xb4\x1a\x62\x26\x24\x88\x09\x6c\xae\x5a\x69\x6b\x4d\x64\xcb\xad\x34\x50\x0d\x41\xfb\x4e\x4b\xc7\x0f\x8b\xf6\x21\x44\xd0\x1c\x22\x75\xd6\xd2\x9f\x5d\xe7\x5b\x17\x21\xd5\x04\x6b\x68\x29\x16\x44\x43\xeb\xfd\x9c\x17\x81\x31\x9d\x88\xf5\x40\x10\xed\xc2\x96\xab\xbe\xd0\x2b\x7d\xad\x9b\xa5\x85\xb5\x52\xe0\x00\x5d\xcc\xa4\x00\xbf\x4f\x45\x9e\xed\x7d\xb8\x6e\xa8\x61\x2b\xe9\xe9\x18\xdf\xd4\xe2\x70\x0c\x47\x10\x08\x32\x83\x62\x6f\xac\x75\x44\x17\xe0\x08\x7d\x26\xba\x14\x5d\xfc\x45\xb1\xc9\xbf\x7b\x4d\xd7\x0e\x6c\x50\x87\x47\xef\x80\x5c\x9a\x02\x42\x5a\xeb\xc6\x42\x1e\x0d\xeb\x6a\x79\xd8\x9a\xce\xee\xe0\x1e\xce\xcc\x9f\x3c\xa3\x65\x38\x38\x26\x58\x4c\x43\x0e\xbd\x39\xec\xf0\xa7\x28\x66\xae\x0a\xce\xca\x5a\xd4\xf0\x40\x5b\x67\x77\x9c\x04\xc5\xde\x03\x30\x61\x4d\xa3\x47\x0b\x80\x5d\x78\x7c\xe7\x9a\xc5\xa6\x96\xdd\x6f\x6b\x55\x39\xb1\xa6\x51\xb4\x24\xce\xfb\x19\x49\x1d\xa6\xe0\x88\x92\x23\xcc\x98\x39\x8b\x42\xc0\x04\x14\xff\x8d\x6c\x06\x27\xeb\x97\xcf\xf2\x0a\x8c\xbe\x7f\xcc\xb4\x1d\x81\x0f\xcf\xe8\x58\xca\x74\x75\x24\x7e\xf6\x28\xe8\x4a\x09\xd0\x12\xfe\x12\x23\x5b\x38\xc1\xcc\x9d\x82\xe2\xb6\x9d\x01\xd6\x21\x8c\xfd\x48\xe8\x5f\x26\xae\xad\xd1\x95\x40\x8c\xdd\x4c\x2f\x80\x6a\x89\x04\x1f\xd0\x31\x7f\xb1\xa7\xb6\x20\x9f\x90\x42\x70\xd3\x4e\x60\x61\x95\x04\x72\x88\xb0\xfb\x11\xa5\x72\x29\x38\xf6\x7c\x22\xb3\x13\xf7\xf7\x4b\x20\x25\xc7\x5b\xcd\x1e\xcc\x5a\x9a\xdd\x4a\x64\x0a\x41\xf2\x99\x6e\xb6\x6e\x5a\xf1\x96\x19\x8d\xb5\x8a\x3f\xb9\x93\x8f\x34\x9f\x92\x2a\x24\xd8\x6f\x4e\xd8\xa9\x6a\x09\xa1\x96\xc2\x4d\x6d\x01\xed\x76\xf3\x81\x6c\x05\xc4\xf2\x6b\xac\xa9\xb9\xd6\xdc\xc7\x9b\x58\x0d\xfb\x75\xd6\xc9\x05\xd4\x80\xda\xd7\x69\x51\x85\x4b\xda\x1c\xaa\x7f\x4a\x81\x95\x43\xae\xd0\x1a\xe9\x56\xbf\x30\x58\xfe\x8b\x3c\x7d\x5d\x72\x49\x62\xf1\xa6\xa8\x31\x43\xdd\xad\x27\x4f\xda\x3a\xd5\x78\xe9\x8a\xa9\x67\xc4\x10\xee\x57\x57\x5e\xf0\x1c\x02\x58\x56\x0f\x0a\x1f\xa4\xb7\x93\x27\x79\x6d\xe9\x94\x20\xcf\xd0\xa4\x15\x50\x63\x60\xf1\x24\x2c\xcc\x58\xa6\x88\x09\x27\x75\x0d\xbb\xff\x13\xd7\xc1\xb4\xed\x51\x9c\xda\x35\x72\x10\xf1\x2f\xb0\xd1\xc4\xd4\x8f\x04\x11\xbd\x7e\x05\x8c\xc4\xcb\x93\xd3\xc7\x75\x97\xe2\x65\x3f\xfa\x28\x2d\x3c\x2f\x12\x8a\xc3\x3a\x23\x7a\xf2\xfc\xbc\x9e\xf9\xc8\x11\xf3\x78\x14\xba\x2b\x0b\x85\x09\x3d\x0f\xd1\x8b\x8c\x6f\xb0\x9a\x43\xce\x52\x25\x4d\x23\xd5\x5f\x32\xe1\xd3\x24\x2a\xed\x1f\x23\xd9\xcf\x20\x4a\xa0\xdf\xd4\x4a\x34\x6f\xe0\x9e\x55\xa4\xa0\x6c\xf1\xbe\xf8\xbb\xf3\x7b\xa1\xf1\x59\x8a\x58\xae\xf8\x95\x01\xec\xba\xc0\x45\x35\x43\xe4\x80\xed\x0a\xdd\xe9\x0c\x84\x1d\x95\xeb\xd6\xeb\x23\xba\xa9\xf7\x0f\x83\xc1\x49\xea\xb3\x2d\x09\x13\xc7\x9b\x09\x93\xd0\xe1\xd3\x57\x4f\x0f\x54\x2e\x56\xa2\x06\x16\xcf\xe4\xa8\xbd\x7a\xae\xeb\xe0\xb0\x83\xdc\x2c\xe0\x14\x61\x78\xc0\x74\x82\xa0\x11\x29\xbc\x6f\xef\xdc\x81\x41\xc1\x38\x48\x94\xb6\x9c\xbe\x2f\x29\xda\x18\x8f\x7f\xd4\xac\x34\x1a\x2d\xf6\xfd\x90\xde\xe6\xa4\x46\xd2\x74\x63\x24\xc7\x5c\x1e\xf5\xb1\xac\xe1\x87\xd3\xbc\x16\xd7\x05\x59\x89\x29\x75\xd7\xe4\x71\x38\xf0\x40\x63\x85\xea"}, +{{0xdb,0x3a,0x44,0xdf,0x40,0xd2,0x55,0xa2,0x5c,0xf2,0x3f,0x53,0xc4,0x52,0x23,0xb7,0xd8,0xf1,0xf1,0xf1,0x11,0xba,0x07,0x40,0x6b,0x71,0xe1,0x84,0xa8,0xcd,0x06,0x12,},{0x6b,0x12,0xbd,0x95,0x80,0xae,0x20,0x7a,0x9b,0x0b,0xaa,0x82,0x87,0xb8,0xbb,0x86,0x66,0x93,0x73,0xee,0x5e,0x5a,0x62,0x5a,0xb4,0xa6,0xef,0x2d,0x08,0x71,0x25,0x97,},{0xcc,0x28,0xb5,0xef,0x4b,0x97,0x73,0x63,0x7f,0xae,0x7e,0x5f,0x08,0x4b,0x69,0x94,0xaa,0x35,0x98,0xf8,0xf4,0xa6,0x5d,0x0b,0xb2,0x01,0xd1,0x72,0xd8,0x61,0xa3,0x01,0x49,0xb3,0x33,0x8d,0x3c,0x3a,0xb7,0x5b,0x32,0xb2,0x55,0x95,0xcd,0x8b,0x28,0x96,0x30,0xc3,0x37,0x6a,0xcd,0x10,0xba,0x2a,0xb2,0x6b,0xc1,0xab,0xa9,0x00,0x84,0x0e,},"\x52\xdd\x8b\xa4\xff\xfa\x34\x4d\x1e\x08\x11\xd9\x67\x5c\x31\x3f\x9c\xc0\xe5\xa1\x38\x47\x86\x91\x98\x9d\x2b\x7f\x73\x89\x02\x50\x68\xfa\x35\xf7\x4f\x9a\xea\xf1\xe9\x56\x65\xec\xf8\xd5\x70\x7f\x75\xf6\x5f\x22\x56\xee\xa9\x33\x98\xbe\x59\xc0\xd5\x38\xf5\xe8\x58\x4b\xfb\xb3\xa2\x40\xf5\x01\x6d\x79\x27\x23\x4c\xb3\xea\xc3\x5b\x39\x1b\x8b\x53\xf2\x0e\xd8\xba\xe0\xba\x11\x08\x96\x94\xbf\xea\xde\x11\x07\x16\x56\xd4\xcf\x18\xef\x2d\x36\x81\x92\xe0\x4e\x08\xe3\x02\x4f\xc1\xd2\xfd\xa6\x31\x2a\xfc\xa6\x8d\x10\xc9\xc3\x36\xa0\xe3\x68\x50\xbe\x1a\x4f\x35\xb0\x33\xa8\x5a\x2a\x95\x49\xf2\x67\x3a\x99\x5f\x2a\x9a\xb4\xbd\x46\xc8\xfd\x2d\x83\x8e\x64\xf7\x61\x71\x34\x27\x32\x9c\x9a\xf5\xe4\x21\x1a\x22\xab\x20\x8a\xaa\xb8\x0e\x19\x4c\xd0\xf6\xa5\x02\xb3\x08\xfe\xd6\xc5\x83\x51\x78\x01\xa4\x8e\xd4\x33\x0e\x2f\xad\xdc\xd4\x18\x09\xc3\x91\x9b\x30\xe8\x4d\xb3\xc6\x87\x31\x03\x1e\x79\x85\x7d\xd9\xf9\x7f\xfd\x12\x54\x7d\xa7\x06\x67\x98\x07\x41\x51\xec\x88\xa5\xfa\x96\x3b\x9d\x9d\x83\xba\x2f\xee\x13\x58\x33\x95\x0e\xf7\xbc\x62\xb3\x40\x1e\xa1\x1b\xb3\x6f\x25\x56\x1b\xc0\x52\x2b\xb0\x2d\x8d\xad\x05\x43\xf6\x3d\x54\x7b\xe7\x7d\x0a\x4c\x9b\xf6\x5d\x42\xf3\xa2\x76\x14\x4d\x2e\x47\x4e\x29\x42\xf3\x79\x02\x21\xe2\x6f\xba\xe7\xca\x91\xef\xd8\x59\x21\x99\x08\x35\xfa\xfb\x6d\xc6\x74\x63\x5c\x96\x01\x82\x10\x38\xb5\x27\x11\x34\x3d\x1a\xa2\x5f\x1c\x46\xba\x4e\x3c\x6e\x71\x2b\xac\x19\xe5\x3e\xae\x30\xe5\x24\x6e\x4f\x04\xdd\xf2\xac\xdb\xb3\x41\x63\xc2\x43\x67\x76\x90\xbe\x0b\xf2\xe3\xfa\x16\x48\x70\xb5\xe6\xf5\x36\xb2\x2f\xb8\x9e\x5e\x8e\x1d\x87\xcd\xb3\x40\x44\x97\x7e\xd2\x83\x6e\x54\x4d\x7b\xa4\x93\xdd\x42\xa2\xb6\x49\xbc\xf3\x13\xc5\xb3\x9a\x1d\xbf\xff\x3e\x7f\x2a\x59\xad\xe8\x7d\x3e\x7b\x25\x8f\x58\xe5\x65\xfd\xba\x3e\x4d\x92\xb1\xed\xb8\xbf\xf5\x4d\xc4\x9d\x86\xc5\x3c\x03\x0c\xf5\x8b\x97\xef\x06\x6d\x24\x1b\x54\x05\x30\x21\x39\x05\x73\x9d\x8e\x1a\xa7\x2e\xd9\x0f\x68\x5d\x39\x58\xea\xa2\x42\xb0\xcb\xf7\xa2\xeb\x97\x6e\xe9\x6a\x63\xe6\x67\x86\x46\x41\x69\xa7\x42\xd4\x57\xe4\xd9\x11\x7c\x7d\x66\x42\x84\x45\xa4\x69\x30\xc2\x8b\xa7\xa2\x65\x82\x41\x80\x5e\xbe\x72\xc7\x8e\x02\x03\x5d\x26\x3a\x21\x1e\x59\x0b\x49\x0c\xdb\x84\x41\x50\x62\xee\xd1\x4f\x13\xb8\xa1\xa9\xe7\x7c\x8d\x7b\x75\x51\x5b\x18\xfb\x85\x38\x6e\x4a\x7e\x05\x39\x80\xd3\x0f\x48\x99\xe8\x38\x63\xbe\xe8\x75\x58\x58\x87\xc5\xf4\x8b\x51\x6c\xcb\x73\x1c\x4b\xca\xa3\xdf\x07\xd0\x47\x95\x81\x40\x96\xc7\x9d\x7c\x5f\xdc\x4d\xab\xf5\xe2\x6a\x4c\xa1\x83\x8e\x0e\x5d\x87\xdb\x71\x30\x9b\x81\xea\x7c\xe4\x61\xe5\xe4\x4c\x7a\xb2\xf1\x05\xad\x75\xc5\x43\xc1\xe9\x17\x9c\x36\xa5\xfa\x55\x5e\xc9\x22\xff\xed\x1b\x76\xd2\x58\x01\xdd\x74\xf8\x0c\xd0\xa6\xba\x7b\xc2\x0d\xb0\xad\x58\x0b\x7b\xbb\x9d\xdc\xfd\x93\xad\x1c\x5f\x20\xf3\xe2\x7c\x3e\xa3\xa1\xe7\x1e\xb7\x4f\xf5\xf9\x44\xcd\x3b\x98\xf6\xd0\x45\x29\x59\x30\x11\xc4\xae\xce\xf6\xdc\xaa\x60\xfb\x18\x36\x8c\xb1\x2b\x6e\x39\x1b\x3f\x5d\xf7\x65\xcb\xab\xff\x15\x89\x8c\x84\x79\x6f\xc2\xb5\x3f\xa4\x90\x0d\xad\x03\x4a\x13\xb0\xce\x14\x45\xad\xda\x4e\xf7\x19\xbe\x74\x14\x19\xe2\x31\xe9\x2f\x1f\x66\x7a\x32\x84\x2a\x42\xdb\x79\xbd\x7a\x01\x4a\x80\x9c\x81\x59\x6e\x82\x62\x73\xd1\x6f\xe5\xd4\x04\x58\x24\x2a\xe1\x0e\x12\xe6\x0b\x34\x89\x53\x0c\x66\x22\xb5\xbb\x44\x45\x4f\x29\x61\x6e\x47\xe9\xa2\x97\xce\x1c\xa0\x74\x13\x7f\xd9\xae\x13\xe3\xee\x8e\xdb\xcf\x78\xaf\x26\x54\x59\xdb\x1a\xf3\x42\xdc\x0b\x2f\xc8\x09\xbd\xa0\x15\xb5\xa8\x2b\x2b\x7c\x54\xef\xe4\xe5\xfc\x25\x2e\xb1\x3d\x66\xe8\x08\x93\x6f\x19\x10\xf4\xc4\x8b\xe0\xef\x7a"}, +{{0x77,0x96,0x4d,0xad,0x52,0xb5,0x79,0xb8,0x96,0x67,0x53,0xda,0x31,0x86,0xd1,0xc5,0xe9,0xd3,0x3d,0x33,0xa4,0xdb,0x38,0xbc,0x0d,0x7a,0x1a,0x6c,0x11,0x2c,0x13,0xc2,},{0xfc,0x25,0x12,0x5e,0x78,0x29,0xf6,0x42,0x34,0x37,0x5e,0x52,0xae,0x9f,0x77,0xae,0x10,0x13,0xf9,0x9d,0xf5,0xf9,0x96,0x5a,0xd2,0xaa,0x16,0x58,0x95,0x96,0xd0,0x91,},{0x3d,0x1b,0x4b,0x4e,0x82,0x0d,0x25,0x0b,0xe2,0xa8,0xfa,0x97,0x1e,0x59,0x9e,0x1e,0x98,0x97,0x75,0x28,0xb2,0xf9,0x30,0x18,0x96,0x81,0xa9,0x3b,0x05,0xe1,0xa7,0x06,0xfc,0x80,0xef,0xfa,0x94,0xe9,0x29,0xbc,0x43,0x92,0x16,0x56,0x89,0x73,0x88,0x28,0x8a,0x9b,0x29,0x27,0x1f,0x37,0xa1,0x4b,0xe0,0x14,0xb8,0x73,0xc6,0x8f,0xc9,0x04,},"\xc3\x39\xe7\x18\xa7\x57\xf3\xf3\xbd\x1b\xab\xdd\x2e\x00\xaa\xa5\xcd\x7f\xc9\x00\x5e\xe3\x4b\x6f\xdc\x09\xd7\x1f\xbd\x9c\x92\x89\xab\x1d\xd1\x4d\xba\x2c\xad\x58\xcb\x80\x51\x16\x77\x7b\xd8\x0c\x85\x96\x64\x33\xad\x46\xf9\xca\x6e\x54\xf1\x3d\xd3\xca\x7e\x56\xe4\x7f\xea\x41\xe5\x48\x8a\x45\xad\x53\xbc\x5d\x65\x74\x27\xe1\xd7\x93\x8f\x55\x19\xf1\xb0\x9f\x5b\xdd\x98\xaa\xe5\xac\x96\x43\xef\x78\xeb\xa4\x93\x49\x25\x33\x9a\x15\x5d\xc6\x68\x28\x57\x10\x02\x09\x7a\x11\xa5\xce\xe7\xb5\x1a\x44\x1b\x75\x6b\x0c\xe6\x5b\x77\x9a\xfe\x19\xda\x6a\x18\xef\xc1\x45\xf6\x09\x0c\xe7\x70\xde\x9e\x0e\x91\xf5\x43\x27\x0a\x09\x85\xea\xb4\x75\x29\x3c\xcf\xdd\x31\x41\xc4\x14\x2e\x47\x22\x23\x3b\x26\x74\x99\x44\x76\x41\x23\x5d\x72\x8b\xd7\x5c\xd1\xad\xc0\xdb\x14\x2f\x73\x31\xad\xdd\xf8\xc5\xee\xa3\xd5\x76\x40\x5d\x86\x99\x15\xb5\x60\xf9\x64\xe3\xe0\x00\x3c\x91\xf5\xe9\x6b\xff\xbe\xee\xc7\x3e\x51\x02\x4e\xf5\x2c\x55\xc6\xdc\xb5\x4d\x58\x20\x3e\x62\xf4\xdd\xb6\xe1\x37\xeb\x08\xe1\xbf\x13\x26\x01\x8a\xfd\x1a\x86\xca\xb6\xc8\x41\xe0\x66\x1c\xe0\xa1\xa7\xae\x96\x7f\x24\xc1\xa7\x7f\xc7\xca\x50\x5f\x72\xe5\xf7\x93\x6e\x39\xc6\xf4\x83\x7e\x25\x95\x19\x5a\x69\xcd\x67\x65\x10\xa7\x16\x1a\x4d\xc5\xe3\x18\xf3\xd4\xf3\xac\x0a\xf0\x3f\x8c\x4a\xe5\xbc\xe3\x93\x24\xe9\x73\x8a\xea\x49\xf0\x02\xd3\x2d\x16\xde\x23\x17\xe9\x5a\x9f\x32\xee\x60\x4e\x13\xdb\x80\x38\xb2\x64\xcf\xc1\x7a\xed\x29\xc9\xde\xbf\x81\x91\xde\x9e\x0e\xfc\x95\x1a\xd6\xd5\x48\x67\x06\x8c\xf5\x0a\x26\x9c\x37\xa2\x41\xf8\x52\x06\x78\x8d\x23\x14\x31\x77\xf6\x59\xcc\xa6\x6c\xfc\xe0\x3b\xc0\x50\x22\x55\x33\x7f\x16\xb3\xda\xd6\xf7\x91\x32\xab\xf8\x0f\xf1\x2b\x6d\x22\x81\xe6\x37\xeb\x6c\x71\xf7\x6e\x26\x33\xa1\x14\x56\x52\x40\xee\xd0\x0f\xab\xea\x9e\xd8\xde\x28\xc8\x32\x21\xf8\xcb\x48\x5f\x51\x2d\x90\x08\xbf\xc7\x4a\x36\x6d\x4c\x2b\x4e\xd1\x72\xd3\x67\xe0\x24\x7c\xb6\x50\x98\xc1\x10\x28\x2e\x83\x1d\xf8\xe9\xbd\x4f\xbd\x5f\x4d\xd2\xb7\xf2\x42\x0c\x23\xb8\x5a\x63\x7a\xa2\x26\x2c\x3c\xb8\x84\x05\xf7\x07\x30\xc9\xab\x4c\x9d\x0f\x22\x7e\xe4\xfa\x4e\xf9\x1e\xfe\x9a\x59\xb3\xe6\xd8\x43\xdb\x87\x9f\x56\x50\x05\x9e\x99\xf0\xe4\xa0\x38\x68\x38\xe6\xf9\x87\x6f\x67\xd5\x0f\x89\x83\x2d\xda\x5f\x30\xa9\xcb\xfd\x71\x01\x34\xf9\xb5\xb5\x46\x27\x49\x6a\xa3\xa4\x32\x12\xb0\x7f\x03\xdb\x11\xd3\xd4\xf8\x75\xd4\x1d\x1f\x4a\xc4\x59\x69\xdd\xef\x69\xf8\x1a\x06\xd2\xb0\xc6\x46\xc9\xcd\x93\x1c\xf2\x50\x2f\xef\x0d\xd3\x2a\xbb\xf0\x95\x1e\xd3\x03\xf5\x28\x48\x25\x93\x43\x97\xfc\x22\xe7\x86\x98\xd3\x5a\xd8\x1d\x82\x25\x6b\xf9\xe1\x54\x00\xa1\x09\x16\x23\xa9\x82\x6f\x1e\x57\x79\x23\x67\x41\x7e\xf0\x25\x86\xd6\x4e\x65\x0d\xa9\xac\xe2\xf1\x8a\xa0\xa1\x26\xd8\x67\xca\xc4\xb5\xd4\xc9\x1b\xf5\x20\x9e\x53\x59\x55\x63\x86\xf8\x27\x08\x3e\xb5\x3e\x8b\x47\x09\xff\xfa\xbe\x92\xc6\x1d\x78\xff\xb5\xda\xf1\x02\x74\xe2\x42\xa7\x00\x91\xf3\xf9\xb9\xd5\x96\xc1\x25\x8c\x9a\x63\x38\x4f\x4b\x05\xb0\x28\x66\x12\x22\x18\x1c\x0f\xca\x96\x5f\x0a\x2c\xb5\x6e\x4b\x55\x6d\x6f\xbf\xf7\x1b\x64\xd9\xb3\x58\xda\x31\xaa\x37\xc7\x4f\xf5\x96\x2f\xb8\xd9\x6a\x38\x3d\x04\x97\x24\xc1\x9e\x24\x9c\x9e\xdb\xb2\xa3\x75\xb2\x3c\xe3\x10\x4d\xa0\xec\x58\xd2\x63\x5b\xa0\x3b\x55\x42\x3f\xa2\xdb\x7e\xb3\x49\xa4\xfc\x58\xa1\xef\x54\x0e\xe9\xa0\x2c\x2e\x70\x3c\x68\xd7\xf8\x47\x5f\x43\x4d\xdd\x32\x00\xdb\x1f\x06\x74\x57\x91\xa3\xac\xc3\x16\x0d\xba\x50\xa3\x93\x44\x7f\xfe\xef\x6d\xc7\xb9\x8f\xb0\x66\x84\xcc\x90\xfd\x85\x20\x3d\x11\x9d\xcd\x81\x99\xe4\xd9\xa8\x9a\xe3\x46\x7a\xe4\xbb\x19\xfb\x71\xcf\x74\x70\x29\xc2\x40\x96\xf9\xa5\x0e"}, +{{0x5c,0xaf,0xd8,0x17,0xa4,0x41,0x0c,0xcb,0x27,0x12,0x17,0x23,0xef,0x32,0x07,0xc1,0x73,0x1a,0x08,0x61,0x94,0x5b,0xe9,0x62,0x71,0x4c,0x0e,0xd9,0x50,0x38,0xa1,0x95,},{0x4e,0xa0,0x86,0xbe,0x43,0xec,0xe1,0xc3,0x2d,0x08,0x05,0x9b,0xba,0xdc,0x9e,0x9a,0x2b,0x2f,0x4f,0x3f,0xe3,0x70,0xf1,0xf5,0xcc,0xd7,0xdb,0xde,0xc0,0xaa,0xf3,0x03,},{0x28,0x85,0x15,0xfa,0x72,0x59,0xf1,0xeb,0x58,0x7f,0xe8,0xa2,0xc4,0x03,0x43,0x4c,0x46,0xf8,0xd7,0xe7,0x5b,0x6d,0x22,0xbb,0x38,0x96,0x56,0x6c,0x01,0x7d,0x09,0xb6,0x98,0xc2,0xc8,0x07,0x79,0x9c,0x2f,0x65,0xf9,0xcd,0xb4,0xeb,0x58,0x15,0x1c,0xcf,0xc4,0x8d,0x10,0x80,0x61,0xa6,0xb3,0x14,0x84,0x32,0xb2,0xbf,0xc1,0xcd,0xab,0x05,},"\x50\xb2\xf0\x53\x42\x41\x80\x46\xd1\x6a\x30\xbe\x4f\xc6\x2b\x67\xda\xf6\xc1\x8d\x2a\x74\x24\x2b\x7c\xb5\x5b\xa9\x0a\xd2\x0b\x6c\xaf\xdd\x60\x15\x57\x37\xc2\x9d\xe4\x8a\xa5\xd7\x99\xfe\x54\x95\xfe\x59\xdf\x5a\x9b\x8c\x0a\x8e\x54\x18\x90\x47\x63\xfb\xad\x83\xea\x69\x86\x65\x1b\xac\x31\x11\x79\x39\xce\xf4\xe0\xc7\x99\x30\xd5\x2d\xfd\x7d\xb4\x3c\x31\xad\xda\xe3\xcf\x93\xe3\xef\xc5\xa9\x16\xef\xd0\xd6\x5f\xdc\x30\x90\x9f\xa3\x56\xcc\xbc\x52\x47\xd7\xaa\xa0\x67\x13\x1b\x6b\x48\x20\xfd\x02\xf8\xe3\x95\xf5\xa9\x70\x4c\x9b\xdd\x75\x60\xa6\x11\xd6\x25\x59\xa8\xdf\xe1\xd2\x85\x9c\x52\x48\x6c\xc1\x1e\xd3\x33\x19\x92\x48\x8f\x41\x75\x20\xd9\x20\xdc\x73\xa3\x2d\x4f\x08\x11\x00\x82\x50\x0f\x5a\x96\x2a\x30\x69\x32\xc6\xa7\x80\x29\x55\xce\xda\xd7\xab\xf5\x3b\x0f\x19\xfe\x47\x94\xa3\x1d\x6b\x85\x53\x80\x28\x43\x06\xcc\xff\x71\xa4\x00\x78\x59\xa2\x32\x8b\xb1\x90\x24\xc4\x3e\x10\xd7\x70\x64\xd8\x66\xd9\x62\x2d\x14\x2c\x27\x35\x4b\x84\xac\x3b\x4f\x82\x32\xf7\xa2\xf8\xaf\x64\x09\xd5\xcc\x75\x7a\x18\xef\x81\x3d\xfa\xf4\xb9\xbc\x04\x0c\xb0\x06\xd7\x7f\x14\x36\x41\xaa\x20\x36\xac\x7b\xc9\x28\xdc\x96\x58\x5d\x9e\x36\xc7\xbc\x9c\x56\x4d\x25\xf1\xc2\xcc\x0b\xea\xb9\xd5\xf2\x07\xe8\x4b\x21\x5f\x1e\x7a\xa6\xfc\x32\x82\x37\xb7\x9c\x39\x92\x3a\x4e\x09\xc7\xc7\x3d\xc6\xb2\x4b\x14\x16\x29\x4d\x79\x8a\x4e\xd5\xf7\x58\x33\x6d\x91\x5a\x87\x0a\x7d\x6b\x75\x92\xb5\xb8\x8a\xac\xe2\xdc\x5f\x26\x7b\xdb\x49\x11\x41\xcb\xba\xe2\xa6\x77\x40\x7c\xc0\x95\x5f\x96\x19\x62\x59\x93\x04\xba\x0b\x83\x96\x71\xa5\xc0\x00\xe9\x20\x10\x8a\x05\x29\x80\x87\xe4\x97\x70\xae\xee\xaa\xb3\x63\x27\x24\xcb\x0f\xc2\x28\x57\x96\xdc\x41\x48\x14\xfd\xa7\x8a\x54\xe6\x7f\x00\xa0\x2f\x77\xd3\xcc\xde\x1e\xd9\xd7\xb1\xde\xf1\x4e\xa1\xf6\x19\x10\xbd\xf3\x0a\x11\x96\xfc\x63\x51\xb6\x22\x54\xd6\x44\x5e\x6c\x90\x44\x5b\x16\xef\xaf\xe2\x89\xa2\x78\x4b\x92\xe4\x2b\x78\xa4\xa9\x00\xc3\x5f\x55\x63\x0b\xbb\x77\x62\xff\x9e\xb7\xfe\xf7\xd0\x4c\x90\xb9\x57\x1c\x4f\xc7\x60\xa4\x10\xdb\xfc\x25\x29\x91\xd0\xba\x27\xf2\xd4\x14\xfe\x64\xee\xfd\xff\x4a\xbc\x18\x81\x7c\x97\x06\xc6\x31\xbf\xa2\x03\x82\x1d\x3b\x92\xcb\x33\x8b\xaa\xf5\xd1\x23\x2b\x46\x26\x47\x95\x4d\x09\x02\x46\x2f\xb1\x69\x6e\x99\x1f\x07\xfa\x9c\x3d\xbc\xf2\x87\x29\x60\x83\x1b\x4d\xed\x92\xa4\x21\xcf\x21\xb7\x53\x16\x5f\xf3\x09\xef\xe2\xef\x54\x38\xc0\x12\x70\xd1\x0c\x6a\x03\xd3\x4f\x71\xeb\xc2\xda\xb1\xda\x90\xda\xa3\x57\x98\x4d\x24\x62\xbc\xb3\x5e\xe3\xde\x55\xc3\xa5\x5f\x8b\x98\xae\xc2\x11\x4f\x74\xc8\x43\x41\xa6\x41\x27\x86\x3c\x12\x0b\x5e\xca\xd9\xe3\x29\xa5\x75\x6a\xe4\xa2\x55\x5d\x84\x92\xcd\xa8\x35\x22\x5a\x8d\xeb\x3f\x9c\x15\x58\xf0\xd4\x25\xbc\x17\x2f\xf7\x64\x0c\xc7\x9d\x97\x80\x04\x16\xfd\x62\x94\xcc\xcc\x70\xcd\x1c\xf5\xb6\xa8\xe2\xaa\x07\x28\x9b\xd5\x22\xbf\x99\xdc\x96\xc3\x6b\xfe\xe8\x0e\x84\x6f\x5d\xd7\x46\xdd\x4c\x50\x03\xe4\xbf\x7d\x29\xef\xee\xa7\x50\x8a\x01\x61\x23\x68\x82\xc9\xa8\x2a\x56\xaa\x2c\x25\x74\x66\x96\x52\xc6\x30\x92\x3a\xb4\x70\xdd\xb9\x5d\x45\x6f\x7b\x8e\x8f\x07\x59\x9b\xa0\xd1\xd3\x8b\xc7\xf8\x17\x6e\x3f\xdf\x02\x09\xbd\x6f\x75\xd4\xcc\x11\x80\x3a\xfb\x18\x56\xcb\xc0\xe9\x1c\x73\x73\x0e\x4f\xb9\x8f\x3c\x94\x8a\x87\xd5\xa7\xed\xcc\x0a\x6a\x8a\xc8\x10\xea\x3e\xaa\x6e\x06\x3c\xec\x5f\x55\x66\xcd\x6d\xed\xc5\x37\xdb\x6d\x68\x6b\x80\x21\xf6\xea\x82\x5a\xd7\x47\x5e\xc7\xf1\xc5\xdb\xde\x45\xd3\xff\x4b\x5e\xe5\x1c\x0d\x04\xf1\xd7\x40\x18\xeb\x91\xe5\x04\x0d\x01\xc8\xb7\x1a\x4a\xab\xbd\xe6\x09\x4d\x4a\xfe\xcc\xb1\x8d\xfc\xde\xd7\x3e\xa7\x5e\x3b\x9f\x8c\xe1\x67\xdf\x62\x09\xae"}, +{{0xd5,0xca,0xc8,0x55,0x21,0xaf,0x78,0x1f,0x3d,0x5f,0x66,0x86,0x2a,0x04,0xb0,0x87,0xd0,0xcc,0xdc,0xac,0x92,0x6c,0xfe,0x9e,0x74,0x7b,0xe8,0xd5,0xc2,0x63,0x3f,0x78,},{0x10,0x0d,0xcc,0x53,0x03,0x9b,0xf0,0x5e,0xa0,0xa9,0xf5,0x88,0x82,0x12,0x69,0x3d,0x4f,0x9e,0x0e,0x75,0x25,0x95,0xbb,0xcd,0x02,0x06,0x10,0xe0,0xae,0x21,0x35,0x96,},{0x5d,0xc0,0x33,0x63,0x41,0x4e,0xea,0xc0,0x08,0x6f,0xb6,0xfe,0xba,0x44,0x21,0x7c,0xef,0x4c,0x52,0x0d,0xb6,0x19,0x26,0xdf,0x68,0x0c,0xa6,0x02,0xdc,0x11,0x00,0x3c,0xe6,0xaf,0xbf,0x3d,0x13,0xc8,0xc5,0xb0,0x52,0x73,0xd2,0x14,0x15,0xe6,0x7c,0x14,0xa2,0xee,0x5d,0x0b,0x1d,0x53,0x52,0x41,0x9a,0xb9,0xb3,0x9c,0x00,0x3a,0x51,0x0c,},"\xd5\xe7\xdd\x59\x49\x09\x37\x5a\x4b\xe0\x8e\x74\x82\x5d\x59\x8d\x53\x5b\xf4\x6e\xc0\x84\xde\x52\xb5\x73\x91\xc1\x27\xef\xf5\x22\x4a\xb2\xd1\x94\xdf\xb2\x66\x33\x47\x8d\x02\xfb\xda\x74\xd1\xdc\x58\x21\xf7\x91\xbf\x96\x2d\x8d\xad\x9e\x4e\xf2\x42\x24\x89\x19\x07\xb0\x18\x9c\xcc\xc8\xb1\x33\xd3\xaa\x20\x78\x92\x6d\xae\xf2\x89\x8c\x19\xc2\xe0\xbf\xe0\x20\x41\xa9\x04\xb9\xf0\x4b\xe7\xcb\x50\xae\xd0\xd9\x62\xd1\xad\xd2\x0b\x40\xa8\x8a\xb7\xab\xad\x62\x6c\xf4\xda\x0a\x78\xf9\xf5\x36\x85\x50\x1f\xdf\xa5\x85\x43\xdd\xf2\xea\x0e\xea\x69\xe7\xba\x16\x0f\x8a\x17\x7a\x25\xfc\x21\xe8\xa2\x9c\x66\x16\x33\xe3\x0e\x52\x3b\x0e\xc0\x1b\x2a\xee\xe2\xd4\x26\xe4\xae\xad\x45\x74\x88\x10\x8f\xe5\xf5\x69\xcf\x6e\x2f\xdb\x68\xc2\x8f\x2b\x30\x52\x82\x35\x77\xcd\x93\x4e\x7b\x06\x2c\x8a\x34\x24\xcd\x43\x67\xfb\x31\x5b\x74\x4c\xa3\x52\x55\xd7\xf1\xaf\x4e\xdc\x9b\xc9\xd8\x83\x71\x23\xd9\x79\x03\xb4\x3d\xf3\x67\xc7\xd4\x18\xc7\x93\x47\xff\xaf\xe7\xc7\xb1\x72\x4b\xba\x34\xed\xe8\xd3\x56\x8d\xb5\x05\x98\x3e\xad\x47\xf6\x2b\x56\xe3\x61\x8c\x11\xdb\x8f\xf0\xbf\x49\x2a\xc6\x75\x97\xd2\xf9\x6a\x6f\x42\x0f\xf9\x85\x34\x1b\x78\x6a\xd6\xce\xae\xdd\x10\x5d\x0d\x15\x63\xb2\xd5\x35\x43\xd7\x8e\x72\x56\x72\x5d\x20\x4e\x82\xed\x3a\x2e\x6a\x6e\x83\xdf\x61\xfc\x28\x2a\x62\xca\x06\xe6\x21\x74\xb5\x5b\xef\x40\xa0\xbd\xf8\xd2\x3d\x1c\x33\x0c\x71\x44\x14\x85\xee\x85\xe7\x0c\xed\x12\x1e\xac\x60\x7f\x58\x06\x78\x16\x3e\x4b\xd7\x5c\x67\x09\xff\x3b\x41\xde\x80\x59\x4b\x9e\x2f\x2a\xa2\x78\xfe\xfc\x21\xd7\x3e\xe3\xf7\x28\x54\xb9\x58\xd9\xa8\xf6\x3e\x3d\x70\xf7\xfe\xad\x8c\x3d\xca\x8e\x71\xbf\x4b\x9c\x2a\x36\xf2\x12\xb3\x2e\xb3\x29\x2e\x63\x55\x80\x38\x65\x59\xee\x1a\x11\xdf\x15\x29\x3a\x0c\x21\xcd\x73\x60\x86\x98\x46\xba\x5b\x7b\xa8\x5c\x99\x4f\x5b\x2f\x9c\xc5\x0e\x5e\xea\x8e\x4b\x36\x91\xd8\x86\x06\x2a\x18\xcf\xb1\x82\xf1\xe8\xb6\x11\xfe\x1b\xc2\x63\x15\x9c\xb8\xa0\x86\x78\x7c\x81\x1b\xea\x48\x12\x53\x00\x08\xc7\x0c\xa0\xc4\x7e\x64\xeb\x2f\xba\xd5\xb0\x27\x27\xa6\x6f\x2c\xdd\x6d\xde\x86\xf5\xd2\xa9\x64\x5a\x1e\x9a\xa6\x6e\xe0\xe1\x5b\x97\xf5\xfd\x22\x95\x96\xee\x02\xe6\x61\xca\xb9\xa5\x4e\xee\x1b\x81\xf9\x8f\xe2\x56\xed\x6c\x54\xfe\xaa\xa0\xba\x04\x7e\xea\x35\x33\x44\xf6\xe5\xc6\x2b\xe1\xe9\xd5\xc0\x9a\x2a\x69\x94\x11\x11\x0c\x56\xd1\x94\x9e\x90\xc0\x7b\x19\x38\xba\x95\x55\xac\x1b\xe8\x51\x1b\x51\x02\x18\xd7\xcd\xe7\xe1\xd7\x4a\x68\xaf\xb6\x42\xf8\x17\x15\xfe\x9e\x6c\x96\xc5\x03\x81\xae\x5a\x9d\xf3\x06\x51\x87\x85\xdc\x4d\xbc\x3a\x64\xf6\x0f\x24\x5c\x56\x4b\x80\x29\x51\x2f\x38\x1b\x56\xee\x78\x77\x03\x42\x68\x03\xc8\x0a\xb1\xc3\x11\xf4\x77\xb8\x91\x70\x8b\x59\xfa\x74\x8f\x32\xde\xbf\x54\xd2\x41\x37\x71\x97\x8c\x26\x5c\x9b\x87\x11\x4a\xdf\x25\xb8\x33\x7a\xa9\x3b\x0e\x63\x2a\x5b\x6e\xda\x47\x4b\xec\x16\x32\x81\x59\xfb\xed\x06\x7b\x00\xb8\x7a\xdd\x61\x96\x54\x92\xec\xcc\x6f\xd3\x46\x1c\x10\x00\xe4\x03\x7a\xb1\xe8\xac\x89\xa8\x52\x4f\x78\xae\x09\xd3\x08\xea\x6c\x94\xff\x88\x37\x32\xb7\x12\xee\xc0\xef\x07\x71\x8d\x33\xc0\x11\xb9\x39\x8f\x8c\xfe\xa7\x33\x07\x5a\xf3\x31\xfb\x3f\x97\xcd\xc1\xe8\xc9\x9f\x6a\x10\x72\x5a\x68\xc5\xc5\x8f\xdd\x8b\x0b\xaa\x50\x22\x7f\x34\xd7\x3d\x23\x90\x52\x03\x69\x8e\xaf\xf6\x26\x65\x4c\xe8\x3d\x86\x51\x08\x49\x9b\xe6\x86\x1f\x61\x41\xbf\xa6\x21\x9d\x7a\xb8\xb5\x84\x51\x91\x99\xf8\x80\xcf\xa1\xb2\x6d\x91\x94\xd3\x01\x71\x1c\x30\xfb\x44\x6d\x6e\xa7\x64\xa4\x31\x0f\x70\xe4\xb8\x59\xcf\x95\xfd\x44\xaa\xf8\xc1\xe2\x40\xe8\x0a\x71\x61\x1d\xbc\xf5\x2d\xa5\x8e\xdc\x32\x03\x11\xde\x38\x8d\x5d\x9d\x76\x9e\xb5\x9b\xe0\x93"}, +{{0x15,0x9a,0x9e,0xdd,0xea,0x5d,0xe6,0x34,0x03,0x98,0x7b,0x56,0x70,0xdb,0x6f,0xac,0x98,0xff,0xe5,0xec,0x3a,0x6c,0xf0,0x15,0x16,0xee,0x2c,0x70,0xce,0x3b,0x3b,0xe0,},{0xf6,0x1f,0x4a,0x04,0xa5,0xa1,0x2c,0xca,0xec,0xfa,0xf4,0x4c,0x1c,0x9c,0x18,0x88,0x47,0x5a,0x2c,0x89,0xfb,0x02,0xf2,0x6b,0xb8,0x1a,0xb5,0xf7,0x8f,0x4c,0xe3,0xa8,},{0x05,0x43,0x71,0x2c,0xef,0xa2,0x9a,0x22,0x0d,0x90,0xf8,0x1b,0xaa,0x4e,0x4c,0xf7,0x7a,0xc6,0x52,0x08,0xb2,0xd5,0xce,0x9f,0xd1,0x7c,0xe2,0x14,0xad,0x4a,0x93,0x7b,0x7f,0xc5,0xc7,0x86,0x41,0x3b,0x58,0x05,0x1c,0xca,0x3b,0xb8,0xb2,0xeb,0x55,0x65,0x7d,0x89,0x57,0x2b,0xc5,0x0e,0xa2,0xe5,0xec,0xdc,0x55,0x50,0x88,0x49,0x16,0x03,},"\xd1\x95\xe5\x90\x0d\xd3\x93\x14\x81\xbc\x01\x2e\x77\xbf\x06\x0a\xaf\x31\xcc\xcb\x0f\xe1\xa6\xc4\x0e\xaf\x28\x6a\x61\x66\xa1\x66\xb1\xea\x37\x05\x34\x26\x28\x4b\x92\x0c\x67\xfe\xe1\xd4\xb9\xd8\x6f\xb8\x61\xcc\x6e\xdd\x34\xe1\x0c\x52\x23\x37\x34\xd9\xcd\x92\xf5\xdb\xf4\x33\x51\x2e\xd2\x55\xac\x6b\x26\xe5\x6f\x5c\x66\x4b\xcc\xb2\x60\x69\x2c\xf4\x9d\x08\x36\x3e\xe9\x4e\x33\x6a\xcc\x48\x96\x00\xa6\xaa\x51\x2a\x04\x0f\x10\xeb\xf1\x8f\x7d\x2c\xbe\xe9\xca\xd1\x4c\x4f\xf8\x73\x77\xa3\x26\x34\x19\xd8\x29\x75\x29\x40\x1f\x15\x33\x7a\x4c\x4d\x23\x25\xed\x7d\xef\x76\x3a\x0d\x47\x9c\xaa\x40\x82\x66\x83\x4d\xa2\x42\xf3\xa1\x6b\x79\xa4\x58\x66\xb9\xd9\xd7\x1a\x48\x29\x31\x76\x74\xcf\xf7\xae\x6c\x8c\x58\x7b\xa4\xd4\x98\x0e\x81\x86\x13\xd3\xad\x82\x50\x7a\x7a\xb0\x32\xbb\xf9\x9c\x5e\x9b\x64\x03\x71\xbb\x41\xb9\x1e\x96\x5d\xc3\x1e\x8c\x7d\x4b\x3b\xaf\xd4\x95\x70\x52\x7f\xaa\xa8\x7a\xbb\xf6\x41\x6c\x47\xb1\xb1\xb0\x9d\x34\x01\x25\x31\x26\xcb\x24\x6a\xe4\x5a\xcf\x5f\x10\x0b\xb1\xf9\x2f\x11\xa5\xc6\xc9\x37\xe0\x58\x8d\x8b\x14\x6b\x3e\x4d\x3c\x7e\x5b\xf5\x74\x84\xe9\x84\xfe\x3a\xfc\x47\x72\xf2\x4e\xbf\x89\x4c\xdb\x39\x83\x7f\xbd\x46\x9a\x92\x1a\x96\xac\x5a\xf5\xe0\x70\xf6\xc9\x62\x4c\x58\x8e\x9d\x4f\xe6\xdd\xfe\xed\x1f\x8f\xe2\x0e\xb9\xc4\x60\xce\x6e\xe3\x8b\xf4\x71\xdd\x56\xdc\xf2\xe3\xee\x99\x8b\x8e\x7f\xdc\xf6\x12\xe7\x8a\x2e\x7c\x71\x73\xc0\x16\x09\x82\xbe\xde\xcc\x2c\x62\x1e\x5f\x66\x11\xb4\xef\x21\x02\xe3\x2e\x7c\x29\x80\x3a\x7e\x25\xfe\xe1\x51\x24\x31\x58\xa7\x6e\xe5\xd8\xc1\xbb\x2e\x7d\x8c\x88\x87\x1b\xa4\x33\xc5\xe5\x41\xc2\x60\x26\x93\xd9\x01\x10\xbe\x79\x5b\x52\x3a\x8f\xad\xb6\x05\xd8\xe3\xd7\xe4\x93\xfe\x24\x5d\x9c\xc5\x32\x0d\x32\xb8\x5d\x61\x35\xa4\x4b\x11\x68\x72\x94\x14\xc2\xca\x21\x56\x0f\xb4\xfe\xec\xde\xef\x0c\xf7\xd8\xe0\x71\x27\x4e\x88\x56\xc0\x04\x03\x3e\x80\x01\x3c\x73\xaf\x71\x77\xc3\x19\x78\x16\xa5\x03\x2d\x90\x59\xb1\xb6\xe4\x15\x2c\x38\x61\x92\xdd\x54\xb9\x0f\x9d\x30\x8b\xe9\x8e\xd7\xd0\xca\x9d\x12\xe8\xaa\xf6\xf9\xd8\x69\x38\x6a\xa9\xdb\xb0\x15\x93\xd3\x7e\x72\xf0\x90\x12\x4d\x34\x55\x29\x8e\x9b\x4c\x9e\xc3\xca\xe7\x3b\xb8\xee\x41\xeb\x63\xe3\x8c\x56\x13\x3e\xfd\xba\xf4\x49\xb8\x4e\x1e\x49\x1e\x49\x6f\x1c\x70\xa4\x4d\x06\x99\x86\xba\x88\x18\x42\x20\x69\x06\x1b\xb6\xeb\xcb\x7b\x20\x54\xe6\x3d\xf3\x81\xba\x03\xc6\xa7\x67\x4a\xbd\x61\x05\x0d\x69\x3d\x41\xbf\xe3\xca\x50\x46\xc6\x5f\xfb\x06\xa0\x74\x98\x09\xe5\x8d\x4c\x93\xa9\xff\x69\xed\x30\x95\x0b\xde\x1f\x99\x21\x6f\xff\x29\x9f\x22\xf1\x6b\x07\xc2\x54\xc2\x65\xae\x0b\x12\xe3\x13\x16\x3c\xcd\xf5\x03\x6d\x49\x05\x5f\x9a\x96\x67\xb0\xb7\x12\x92\xbc\x3b\x62\x60\xcb\x87\x56\x8f\xd2\x67\x17\x0b\xc9\x40\xc3\x33\x29\xd7\x29\xc9\xe3\x2d\x0f\x91\x80\xb1\x34\xbf\xf8\xae\x93\xb1\xbf\xeb\xfa\x38\x42\xfe\xf2\x0b\xc0\x4a\x29\x7b\x00\xa8\x4a\x0f\x42\x8d\x5f\x42\xfa\xb8\x61\x42\x99\x6d\x4a\xd9\xef\xab\xc4\x98\x52\xf8\x81\x2f\x3b\xfb\x5e\x57\x53\x9e\x21\x86\xeb\x8a\xe2\x29\x58\x0b\xc6\x04\x48\xac\xde\xf5\x72\x3c\x88\x15\x88\xb5\x37\x89\xf0\x5b\x91\xe0\x22\x89\x22\x32\x52\xd7\x53\xf7\x98\x13\x77\x9a\xce\x70\x5e\x04\xae\xd1\x52\x65\xd3\xbd\xf2\xa2\xe4\xb1\x56\x54\x77\x0a\x27\x58\x54\xe6\x4c\xf4\x43\x90\x60\x7a\x45\xd7\xbb\xa9\xaf\x3e\x1a\x2e\x28\x30\x67\xfc\xd6\xe6\x33\xaa\x2d\x24\x03\xbd\x81\xf7\xc7\x92\x76\x55\x10\xb5\x98\x41\x2f\x6b\xda\x07\xb2\xa9\x45\xb9\xf6\xd4\x6a\xb2\xf7\xc3\x20\x07\x5b\xc6\xb6\x0a\x80\xda\xa4\x4a\xf3\x91\xf4\xcd\x56\x21\x31\xbb\xdd\x40\x7d\x66\xf8\xdb\x12\x59\xbd\x76\xfa\x7e\x4d\x52\x64\xe1\x45\x54\x6c\x94\x2d\xfe\x90\x07"}, +{{0xed,0xa0,0xfe,0xac,0x0f,0x2a,0xfe,0x01,0x74,0x49,0x15,0x52,0x48,0x7f,0x39,0x62,0x17,0x13,0x32,0xb8,0x22,0xdc,0x3d,0xa4,0x26,0xf9,0xa5,0xf6,0x2b,0xef,0x7b,0x8d,},{0xef,0xf2,0x7c,0xb5,0x1f,0x4d,0x39,0xc2,0x42,0xf3,0x23,0x01,0x9a,0x12,0x34,0x81,0x8e,0xf2,0xe4,0xcd,0x1b,0xda,0xbc,0x0f,0x2d,0x8d,0x21,0x34,0x58,0xdc,0x47,0x1a,},{0x6c,0xbc,0x7e,0x6f,0x5e,0x12,0x14,0x5b,0x01,0x68,0x7a,0xd9,0xca,0x6b,0xf6,0xe4,0x7f,0x94,0x17,0xc2,0xce,0xfa,0xd3,0xfb,0xd6,0x8f,0xd6,0x5d,0xd7,0x4f,0xaa,0x97,0x50,0xcb,0xa9,0x92,0xde,0x4c,0xeb,0xcf,0xcd,0x35,0x80,0x8c,0xbb,0x3f,0xf1,0x2c,0x8d,0x93,0x07,0x99,0xaf,0x36,0xef,0xe7,0x97,0x6b,0xf2,0xfe,0xa7,0x9e,0x3e,0x0e,},"\x90\x11\x19\xda\x4e\xd1\x81\xaa\x9e\x11\x17\x0b\x20\x62\x6e\x00\xab\xf0\xb5\x48\x24\x5e\x3d\xeb\xf9\x4b\xf5\xed\x50\xae\xef\xe9\x42\xb4\x02\xcc\x99\x48\x94\x78\x52\xde\xdf\x2b\x53\x04\x01\x76\x65\x74\x9c\xd4\x7c\x21\xfc\x65\x2e\xe9\x95\x67\x9f\xf9\x31\xe3\x0e\x94\xaf\x98\xb4\xa9\x8f\xd4\x4e\x84\x9e\x98\x47\x0f\xe0\xa7\x6c\xe8\x0c\x61\xf8\x3f\xb4\xe8\x5b\xa5\x23\xee\x3f\xd2\x5d\xb0\x00\x05\x3b\x49\xd0\x93\x0e\x3b\x07\x9e\x86\x6e\x15\x3f\x7d\x86\x36\x7f\x23\xa4\xc4\xab\xc6\x3b\x30\x75\x46\x1e\x90\xe4\xfd\x89\x6d\xa0\x49\x2e\x27\xd7\x14\x94\x1e\x96\x7f\x52\xc9\x3f\xfa\xec\x44\x80\x3f\x57\x87\x7d\x86\x6e\xb5\xf8\xc5\x28\x17\x85\xaa\x48\x26\x79\x2e\x39\x64\xc6\x65\x90\x82\x1e\xea\x66\x75\x20\x74\x26\x40\x18\xa5\x71\xf5\xb0\x13\xb3\x8e\x15\x2c\x95\xc0\x24\x8a\xe6\x03\x68\x22\xa6\x7a\xfc\x9e\x02\x69\x45\x73\x15\x2b\x86\x4c\x56\xc2\xf7\x30\xa0\x82\x10\xf8\x5e\xc4\x6f\x98\x4a\x64\x3d\x51\x6a\x15\xfc\xfa\xa8\x48\x40\xf5\x12\x04\x7d\x11\x0e\x07\x18\xd2\x93\x95\x5f\x01\x58\x25\x7f\xba\x0d\x78\xeb\x7d\xf2\xf0\xb7\x7e\x6e\xeb\x76\xdb\x5e\x71\x70\x73\x10\xe8\x27\x36\x1c\xd4\xe1\x19\x74\x0e\x63\x92\x2d\xb4\x2c\x2c\xeb\x5e\xe1\x75\xd5\x0d\xec\xc7\xb7\x49\xfd\x23\x25\xbc\xe1\xe6\xa8\xf7\x10\xff\xcc\x1e\x1c\x9b\x33\xc3\x80\xe5\x2a\x64\xda\xa9\x58\x5f\xab\xe4\x06\xd9\xcf\x24\x48\x8f\xe2\x6f\x3a\x49\x5f\xb0\xab\x50\xe1\xe2\xba\xd8\x23\x81\xaa\x22\x43\x10\x99\xcc\x8a\x56\x98\x13\xd7\x9c\x9d\x78\x56\x9c\x0d\x95\xda\x9a\xad\x2b\xfb\x57\x75\x8d\x52\xa3\x75\x27\x52\xe0\x23\xd6\x51\xc9\xcb\x66\xa4\x12\xa5\xc8\x0f\x6b\xa5\x47\x93\xf7\xec\x87\xb4\xc5\x98\xfe\xd2\xce\x24\xab\xd7\x60\x87\x08\x89\x5c\x46\x72\x73\x59\xff\xec\xa6\xd6\xc6\x2e\x10\xa6\x78\xca\xa7\x18\xb4\xcd\x26\x32\x92\xcf\xef\x53\x5b\x9f\xbe\x27\x56\xb7\x39\x6d\x69\x7b\x31\x46\xc5\x51\xe6\xaa\xc1\xf5\xf1\xc2\x4b\xe9\xb6\x7a\x1e\x2a\x2a\xff\x74\x53\x01\xba\x6a\x21\x22\x17\xc5\x3d\x68\x16\x81\xbb\xb4\x01\xbf\x4a\x43\x65\x6f\x5d\x15\xcd\xe9\x69\xc1\x78\x00\x99\xa3\x32\x37\xeb\x19\xa3\xb8\x58\x5d\x6b\x5d\xea\x2f\xb5\x77\x84\x5f\x25\xee\x2a\x82\xcc\xf4\xb2\x85\x02\xf9\x0f\xe8\x0b\x8c\xdc\xdf\x2c\xcf\x93\xc4\x34\xc0\xe6\xaa\x5d\x87\x52\xa4\x43\x43\xc2\xb1\x8d\x20\xfe\x40\x04\xc4\x70\x38\x65\x93\x56\xf8\x7a\xbe\xd5\x44\x50\x34\xd8\xe2\xd3\xd1\x47\x68\xf5\xef\x31\x2c\xf1\x02\xa9\x88\x46\x83\xbc\xc0\xcd\x8a\x71\xe3\xec\x36\xfb\xb6\x33\x4a\x1b\xba\xed\x5d\x2b\xf1\x04\x16\xd8\x2b\xd6\x53\x04\x75\x38\x0a\xb6\xe2\x57\x7b\xbc\x69\xce\xbd\xa7\x5f\xaf\x02\xad\x82\x7b\x54\x51\x82\x13\x20\x6f\xd4\xcd\x66\xf2\x52\xb2\x34\xac\xa9\xee\xde\x7e\x3e\xeb\x81\x5d\xdc\xd8\xd5\x19\xc5\xd7\xf5\xd9\xd1\xfb\x9c\xa0\xfa\x44\x67\x99\x00\x95\xfa\x46\x22\x0c\x20\xa2\x07\x1d\xfc\xaa\xd5\xf0\x24\xda\xe3\x41\x6f\x7c\x49\x2d\x75\x74\x88\xc4\x9a\x2e\x4d\xf4\x83\xbc\x9b\x80\x09\x8e\x0d\x5d\x68\x3f\xac\xb8\xc9\x60\x82\x9d\xff\x09\xb3\x03\x36\x9d\x46\xcb\x57\x33\x1f\xf2\x17\x91\xee\x25\xd6\xbe\x7d\xec\x7e\xba\xf1\xb3\x24\x79\xa7\xf5\x14\xdc\x64\x71\x05\xc9\x44\xc3\x6f\x7d\xbf\x0a\x5b\x58\x91\x28\xdb\xaa\xa4\x21\x71\xd6\x42\xf2\x5a\x98\x1c\xe1\xf8\x37\x9f\x91\x69\x0b\x36\xaf\x77\x46\x48\xd5\x62\x4c\x08\xdb\xd0\xa9\x0f\x70\x87\x16\xdf\xab\x20\x24\xda\xe8\x65\xb9\xc4\x9a\xb2\x74\x73\x82\x6c\xd4\xa0\x10\xbf\xdb\x52\x01\x1d\x8c\x7c\xb3\xf4\x21\xca\x8c\xa3\xcd\x04\x86\x88\x91\x88\xe6\x7d\xf0\x0f\xb8\xc2\xa6\x43\xe7\xad\xb2\xf8\x27\x9f\x76\x3e\x5b\x9a\x81\xb6\xdf\xc3\xf7\x21\xfc\x5f\x68\x49\xf6\x67\x36\x78\x8c\xc5\x57\xc4\xeb\xc6\xfc\x68\xd6\xf6\xac\x77\xbe\xdd\xa8\xac\xb3\x62\x24\x3b\xda\x74\xe7\xb2"}, +{{0xec,0x05,0x9f,0xc6,0xbe,0x98,0x3c,0x27,0xec,0xa9,0x3d,0xdc,0xdc,0xb5,0x3a,0xf7,0x28,0x62,0x55,0xda,0x91,0xe2,0xa5,0x6a,0x68,0x4f,0x64,0x1e,0xc2,0xd0,0x9d,0x6e,},{0xff,0xc6,0xcb,0x75,0x1c,0x70,0x07,0x1b,0x65,0xec,0x2a,0xc6,0xb4,0x5f,0xd1,0xd5,0x5f,0xe8,0x36,0x96,0x5f,0x80,0xb3,0xe7,0xc7,0x84,0xfc,0x70,0x4a,0xcb,0xdf,0x69,},{0xa7,0xb8,0x8e,0x5a,0xbf,0x13,0x28,0x24,0xbd,0xde,0x77,0xc5,0xf8,0xdf,0x94,0xab,0x26,0x48,0x1f,0x6b,0xee,0x66,0x0e,0xa1,0x62,0x24,0x70,0x82,0xa2,0x50,0xd3,0x90,0xc7,0x1d,0x32,0x0a,0xd0,0x60,0xd8,0xef,0x34,0x1f,0xb6,0x9a,0x48,0x32,0x94,0xf0,0xd6,0xde,0x72,0x6f,0x0c,0x86,0x2f,0xa3,0x7e,0xa4,0xbc,0x6d,0xab,0x52,0x15,0x09,},"\xd1\xac\x63\x25\xa4\xe6\x90\xfa\x79\x53\x68\x83\xd5\xc2\x0e\xac\xb7\xd9\x64\xc0\x17\x8f\x74\x2c\x2b\x23\x72\x7d\xeb\x62\x64\x5a\xf7\xc8\x19\x22\xa0\xe7\x2e\x5e\x30\xb5\x83\x9a\x2e\xd5\xe5\x67\xec\x31\xce\x22\x41\x15\xb8\x2d\x2b\xf2\x51\xb7\x39\x3f\x01\xb0\xd0\x3a\x60\x2b\xc1\x20\xae\x62\xaf\x7f\xbc\x37\x9d\xfc\xf9\x5b\xbb\xba\x98\x4a\xab\xa3\x4f\xe2\x12\xac\x99\x00\x33\x28\xb8\x32\xc3\x53\x2d\x42\xee\xe1\xe1\x87\x4d\xc2\x2a\xd6\x7d\xb6\xc9\x1d\xbb\xfb\x2b\x45\x78\x5d\xbc\xd3\x99\x17\xd3\x6f\xb4\x8c\x1b\x5d\x6f\x38\xbd\xda\x5d\x28\xfb\xba\x64\x17\x55\x75\xaf\xea\x46\xc8\xed\x67\x57\xff\x30\x16\x4e\x0d\xf2\xe7\x21\x76\xe8\xb6\xc9\xdb\x5b\x5e\xf3\x90\xb7\x2f\x2d\x4d\x94\xe3\xb6\x6f\x0d\x44\xa7\xe0\xf0\x6e\x89\xde\xbc\xdf\x13\x63\xc0\xe7\x5d\x50\xdb\x5b\xb7\x01\x90\xd1\x9f\x66\xa3\x9c\x6f\x7d\xba\x70\xdf\xcd\x4a\x9f\xed\x02\xc2\xf1\xd0\x67\xe7\xc7\x88\xc5\x8f\xdb\x3e\x17\xa2\x37\x7c\xe4\x86\xec\x65\x82\xf3\xba\x99\x7b\xb5\xf7\x0c\xd6\x21\x00\x29\x56\xf5\x13\x1a\xa3\xa1\x61\x7c\x0c\xeb\xcc\xd9\x39\x1d\xe1\x30\x7c\x85\x97\x0a\x8b\xc1\x55\xf5\x19\x87\x26\x68\x45\x0c\x91\x48\x86\x89\xf5\x3c\x2c\x1a\x7e\xd5\x3f\x38\x8c\xb1\x3a\x2c\x38\x96\xfe\x5b\x7d\x3a\x0d\xc1\x68\x3f\x27\x66\x4c\x8b\xea\xea\x68\x0c\x8c\xc5\x4a\x90\xe4\xc6\xf9\x9f\xbf\x05\xf2\xc2\x2d\xf6\x0d\xe9\xae\xc8\x0c\x79\xb7\xd6\x62\x07\x05\x06\x67\xb4\x52\xd7\x85\x7f\x9a\x8c\xa7\x23\x28\x0d\xac\x79\x92\xe2\x07\x92\x67\xec\x3a\xd9\x11\x40\x46\x42\xc4\xe3\x26\xbf\xb9\x6b\x43\xc8\x94\x34\xba\x4b\xc7\x8c\x25\x2f\x4d\x4c\xa8\xd1\x3a\x88\x74\xc6\xfc\x82\x52\xea\x0b\x56\xc6\xbc\x78\x68\x47\xd4\x31\x83\x06\xe1\xc6\x52\xc4\x52\x58\x5e\xef\xd0\xbd\x9d\xd3\xc1\x48\xa7\x3b\xa8\x6e\xed\xea\x94\x5f\x01\x67\x13\xed\x7d\xf0\x85\xd0\x06\x66\x89\xe7\x92\xda\xcb\x2b\xfc\x1e\xb5\xc8\x24\x37\x2a\x26\xc5\xe9\x44\xaa\x74\x44\xac\x97\x73\xd4\xa1\x92\x1e\x49\xbd\xd4\xf8\xf6\xd7\x88\xc2\x63\xfe\xe0\x4c\x7b\x44\x4c\x53\x05\xed\xb6\x33\xe1\xff\xe0\xba\x4e\xa8\xda\x01\x1a\x62\xf2\xbb\xfe\xf4\xb8\x95\xad\x3f\x22\x4c\x3b\xa3\xbf\xf0\xc9\x5d\x75\x75\x0c\x9b\xcc\x66\xff\x8a\x20\xb6\xc2\x4b\xde\x75\x81\xa7\xec\x38\x66\xf8\x71\x6f\x78\x1f\x46\xdc\xad\x45\xa9\xeb\xcb\x6e\xd4\x69\x53\x36\x83\x97\x01\x17\x35\xd4\xb5\x2d\x00\xe8\xdb\x39\x79\x95\xdb\xdb\x3d\x4f\x42\x54\x68\x7f\x04\x68\x8a\x26\x8c\x30\x5b\x2b\x1f\x62\x2c\xf5\x1b\x17\x47\x75\xba\xd7\xf6\x67\x4a\xdc\x2e\x58\xe0\x5c\xce\x86\x5f\x12\xd7\x56\x9c\x8e\x9b\x35\xbc\xdf\x3c\xcc\xe6\x33\x0d\x08\xce\x53\x40\xa7\xc6\x30\xf2\x7a\x6c\x80\x86\xb5\x14\x6b\x29\x2f\xcb\xf5\x0f\xf6\xaa\xae\xf8\x84\x8a\x70\x7b\x25\x43\xc6\x18\xd1\x7b\xd9\x76\xc2\x40\xbc\x79\xd3\x3e\x00\x4e\x49\x53\x48\x29\x15\xe7\xe6\xef\x94\x96\x4b\xde\xa4\xe0\x2d\xd7\xc2\xf4\x75\x23\x5f\x2b\x99\xe4\x32\x29\xc9\xac\x3a\xba\x0d\xb5\x9a\xc2\xda\x03\xa9\xee\x4f\x37\xdb\xf2\x47\xa3\x3e\x6d\xfe\x5b\xe7\xc7\xf8\x25\x84\xf0\x4a\x46\xd4\x9f\x66\x21\xda\x31\xb9\x1a\xc3\xda\xa4\xd6\x8d\x48\xa5\x66\x59\xb4\x48\xc0\xed\x36\x5c\xb4\xaa\x0c\xfd\x90\x88\x53\xdf\x5b\xbf\xa8\x8e\x60\xe1\x0a\x5a\x00\x2c\x32\xab\x33\x33\xf2\xc3\x9b\xbf\x3e\xe0\x1a\x4a\xa6\x0d\x2d\x01\x42\x3e\x60\x97\xdc\x54\x30\x5f\x81\xa2\xd9\x3e\x2f\x6b\x4e\x8b\x35\x19\x71\xcb\xf2\x45\x7d\xc7\x6e\x1f\xb8\x92\x93\x38\x47\x98\xef\x28\x23\x4e\x9b\x1a\x47\xde\xdc\x23\x36\xf8\x6b\x8e\x13\xc4\xae\xf7\x90\xf5\xa1\x12\x39\xc7\x47\xd9\xd8\x65\xc9\xa1\x5a\xde\xb0\x71\x07\x02\x67\xe5\x34\x62\x56\x64\x8a\xdc\x0f\xa4\xdb\xdf\xd7\x87\xca\x14\x65\xfc\x24\x0a\x32\x4c\x3c\xaf\x29\x31\xda\x41\x49\x9e\x27\x5f\xd4\xb3\x5f\x6d\x08\xdb"}, +{{0xf1,0x6a,0xbd,0xbc,0xc0,0xbc,0xc6,0x1a,0x1a,0xee,0x3a,0xbd,0x87,0x67,0xab,0x52,0xe5,0xf7,0x99,0x99,0xbb,0x77,0xa3,0x97,0x6c,0xbc,0x82,0x67,0x0d,0xfd,0x2f,0x73,},{0x10,0xf4,0x51,0x71,0x9d,0xb0,0xfd,0x21,0x37,0x6e,0x22,0x8a,0x41,0xc3,0x03,0x5c,0x8c,0x2b,0xc4,0x2e,0x5a,0xaa,0x92,0x6f,0xe6,0x08,0x87,0x8d,0xbb,0x0d,0xc7,0xab,},{0x33,0xd8,0x05,0x29,0x08,0x69,0xb8,0xe0,0x4f,0xf0,0x89,0xfa,0xa2,0xd1,0xfa,0xb8,0x37,0x43,0xba,0xda,0x68,0xad,0xe5,0xb3,0x8a,0xe5,0xf0,0xcc,0x58,0xc3,0x37,0x4e,0xba,0x43,0x94,0x3c,0x1f,0x51,0x10,0x67,0x8e,0xb3,0x9b,0x46,0x58,0x61,0x18,0x22,0xa2,0x6d,0x35,0xff,0xe1,0x9e,0x9c,0xfc,0xb9,0xba,0x95,0x89,0xe4,0xec,0x31,0x05,},"\xbf\xac\xd7\xdd\x4e\xea\x46\x7d\xcc\xe4\x04\xf4\xa3\x52\x0a\x45\xb9\x4e\xba\xa6\x22\x19\x7d\x02\xd6\x15\x29\xd2\xb3\xbf\x27\x3c\x4e\xe1\xfb\x95\xa1\x80\xc8\xf8\x7d\xe1\x90\xa2\xe5\xea\x70\xb8\x4a\xe1\xeb\x6f\xd4\x44\x7d\x8a\x3a\x8d\xed\x10\xf6\xed\xe2\x4f\x0e\xb9\x2b\xd3\x0b\xc6\x5d\x48\x71\xe8\xf5\xda\x08\xcb\xe8\xcd\x3c\x0a\xc6\x4f\xd5\xa5\x7a\x6b\x06\x4a\x89\xd5\x15\x9b\x42\xf8\xb3\xe5\xa1\x83\x8c\x9c\xb1\x9d\x88\x10\x6c\x07\x73\xa2\x75\xcd\x2a\x1d\x60\x99\x30\xbf\x6b\x30\xae\xca\x62\xb9\x7e\x31\x9b\xbf\xa9\x34\xf4\xd0\xa1\xe6\xac\x80\xba\xeb\xcb\xa2\xd8\xea\x4b\xed\x9c\xa8\x56\x2b\x4a\xcb\x56\x97\x9b\xf8\x85\x32\x4a\xc4\x0a\xb4\xa5\x0b\xfb\x9f\x34\x90\x49\xfc\x75\xa0\xe0\x3d\xe4\xcc\x43\xea\xe3\xc6\xa6\xcf\xfb\x5f\x6a\xe6\xc9\x45\x04\x41\x5e\x6c\x7e\xd3\x04\x5a\x93\x2f\x47\xfd\x20\xb9\xf3\x48\x3a\x77\xb6\xd4\x49\xd8\xdf\xd4\xa6\x38\xdb\xf5\x6f\x03\xf0\xf0\x31\x87\x90\x59\xb2\xfb\x49\x76\x79\x43\xf4\x6b\x38\x72\xe2\xde\x56\x7d\x5f\xef\x80\xb0\x29\x25\xe9\x86\x3e\x0f\x1d\x31\xa8\x0f\x4e\x64\x51\xc3\x25\x69\x4b\x80\xcf\x1f\x19\x18\xc6\xe4\x98\x87\x8e\xdc\x47\xc4\x53\x0c\xac\x46\x6f\x1a\x29\x4d\x55\xdf\x09\xaf\x4f\xdc\x80\x72\xad\xb1\xbf\x26\xca\x8c\x92\xf9\x12\xa2\xb9\xfe\xbc\x8b\x97\xb5\x8c\x1e\x9d\x32\xc7\x80\x32\x30\x52\x97\x2b\x6f\xbd\x53\x30\x4c\x05\x19\x3c\xae\xb6\x7c\x5b\xd3\xe6\x74\x79\x72\x5d\x29\x7d\xff\xb0\x68\x90\xab\xf8\xcd\x9e\x42\x45\x8e\x16\x8a\x61\x18\xf9\x05\xb1\xd5\x34\x86\x01\x6f\x85\xdc\xd9\x8d\xd3\x39\xe3\x46\x05\x33\xd0\xb8\xa4\x9f\xae\x6d\xc1\xa0\x71\x72\x5e\x6a\xe5\xf2\x94\x47\x9e\xe3\xbd\xca\xeb\x74\x06\x18\x41\xfb\x26\x08\xe8\x8a\x49\xfd\x0f\x38\x95\xb1\x8f\x85\xb9\x0f\x72\x41\xdd\x13\x87\x71\x00\x53\xfa\xa6\x2b\xae\x75\xe9\xae\x39\x36\x9c\x1c\x02\xde\x5d\x19\x24\x2e\xfa\x16\xe1\x1d\x44\xa4\xba\x57\x78\xce\x77\x22\xa9\x1c\xec\x0b\xc0\xa0\x8c\x06\x9b\xdf\xa1\x30\xd1\xc6\xc4\xb5\x6c\x6e\x93\x54\x24\x03\xcc\xf2\x76\x84\xde\xf5\x7d\xef\x26\xdf\x86\xce\xd5\x71\x28\x2d\xc9\x60\x97\x46\x18\xf0\xa7\x4a\x0c\xde\x35\xb6\x53\xcc\x6e\x77\x30\x43\x1b\x82\x5f\xfb\x9b\x8a\xaa\xb3\xc7\xa3\x97\xc9\x92\xbc\x2f\xa2\x32\x70\xfb\x11\xee\x43\x1a\xfd\x5f\x9a\x64\x44\x83\x01\x11\x73\x99\x3f\x19\x48\x5d\xd3\xcb\xdd\x18\x7b\xd3\xd9\x95\xeb\xf0\x03\x1b\x1b\x0d\xe4\xa8\xde\x9c\x14\xeb\x6f\x78\x0e\x36\xb8\x92\x57\x56\xb9\x79\x06\xa1\x96\x9d\x85\xe9\x67\xd8\x80\xe6\xe7\xdd\xa4\x2f\xd3\xc3\x00\x19\xf1\x1d\x70\x81\x07\x1e\xee\x66\x26\x42\x28\x36\xbb\xed\x27\xd4\x6d\xd0\xdf\x1f\xeb\x66\x10\xdc\x85\x9f\x51\x3c\x0b\xc6\x53\xd7\x02\x20\xfe\x04\x8d\x2e\x97\xc2\xe0\x6a\xf5\x30\xe1\x1b\xdc\x70\x29\xbc\xcc\x5c\x92\xed\xec\xef\x5e\x4a\x2e\x0b\xe2\xd2\x51\xf4\x41\x5d\xca\x3e\x55\xb3\xa8\x50\xf2\x63\x0b\x87\x9e\x4e\x03\x6c\xe8\x63\x3b\xf2\x09\x20\xb6\x80\x94\x21\x59\x29\xac\xcc\x7b\xe4\x0c\x57\x78\xbc\x55\x4e\x6e\xdd\x7e\x54\xc9\xe1\x45\xb2\xee\x07\xb6\x5d\x06\x1c\x11\xde\x0e\x83\xf3\x81\xce\x4f\x57\xc6\x48\x3f\x51\x06\x93\x63\x51\x10\x74\xc7\xa5\x77\x35\x3b\x45\xc6\xeb\x71\x19\x9d\xce\x50\x59\xfd\x2c\x46\x11\xb0\x54\x23\x8a\xaa\xdf\x2b\x6b\xa5\x34\xbf\xff\xc2\x72\x2a\xe3\xe3\x1f\xf7\x9a\xe2\xeb\xca\x99\xcc\x35\x07\xf8\xa0\x33\xcf\x4f\xea\x70\xc5\x2f\x7d\xb5\xde\x44\x2b\x42\xb8\xd4\x1e\x99\x01\x2e\x42\xca\x0e\x85\xa9\xfb\x6d\x4f\x16\x5b\x33\x0d\xe6\x38\x3c\x57\x26\xef\xca\x2f\xe9\x71\x34\x00\x02\xf5\x62\xdc\x6c\xb8\xf2\xfa\xf0\x66\x57\x25\xe0\x97\x79\x9d\x09\x60\x91\x86\x4d\x66\xa9\x50\xa5\x79\x09\x53\xee\x16\xb9\xea\x58\x20\x09\x21\x87\x08\xc4\xac\xcd\x81\x38\x13\x58\xa2\xc6\x89\xa0\x41\xd0\x2d\x78\x61\x21"}, +{{0xbe,0x79,0xd1,0xae,0xea,0x86,0xe8,0x6f,0x39,0x81,0x37,0xe6,0x2f,0xfd,0x79,0xe5,0x0e,0xff,0x9f,0x31,0x3f,0x25,0x19,0x2f,0x89,0xe5,0x2f,0x0b,0x4b,0xbd,0x5d,0x32,},{0x18,0x7d,0xac,0x85,0x5c,0xa4,0x42,0xfd,0x9a,0x3d,0xdc,0x32,0x89,0xc2,0x4e,0xb2,0xd2,0x6f,0x7a,0x40,0xfb,0x29,0xd8,0xe7,0x44,0x31,0xb2,0x50,0x22,0xc3,0xa0,0xcc,},{0x6d,0xab,0x59,0x3b,0xb1,0xd4,0x48,0xc9,0x74,0xa6,0x5c,0x6a,0x0b,0x6f,0xad,0x22,0xb4,0x73,0x26,0x32,0xd0,0x04,0x89,0x17,0x6e,0xf1,0x26,0xaa,0x59,0x01,0x09,0xe0,0xa7,0x23,0xa1,0x13,0x10,0x7b,0x53,0xe1,0x7d,0x69,0x0a,0x0d,0x40,0xb0,0xfa,0x33,0x6c,0xc8,0x7f,0xd5,0xfc,0xe8,0xf5,0x41,0xac,0xce,0xc6,0x7f,0x7d,0x1e,0xbc,0x06,},"\x6d\x63\x2a\x7d\x3c\x9b\xe5\x36\x49\xd0\xd1\xa5\xee\xdf\x51\x9a\x41\x3b\x13\xac\x64\xe9\xad\x85\x4d\xfa\x04\xf2\xe1\x73\x29\xd8\x22\xbe\x57\x3d\x9e\x35\xac\x06\x6f\x02\x22\x13\xa3\x44\x62\x0b\xba\x28\x9f\x53\x31\x69\x55\x84\xd1\x34\x3e\x81\x54\x05\xae\xab\xe3\x86\x1d\x63\xb3\xa5\xb9\x2b\x8c\xd8\xee\xed\x22\x80\x22\x2a\xbd\xe3\x0a\x1b\xcc\xd3\xf3\xe4\x11\xaa\xb9\x22\xfa\x1b\xaa\x09\x7a\xa5\xc7\x80\xd0\xea\xef\x94\xea\x10\xfe\x21\xf7\xd6\x39\xb7\x6d\x47\x88\xae\xb5\x92\x4a\x9d\x26\x2d\xcb\xc5\x68\x8a\x3e\x43\x54\x4b\xec\x08\x8c\xa2\xe0\xd0\x6d\x77\xa7\x1f\xb6\x41\xd5\x52\x26\x61\x44\x52\xb1\xe0\x80\x7a\x9f\xcd\x3c\xa6\x9b\xf7\xf2\x5d\x80\x41\x47\x0c\xeb\x7b\x21\xea\xd0\x3e\xc0\x37\xa1\x62\x9b\xd5\x00\xaa\x23\x3b\x59\xbe\x44\x97\x82\x10\xb6\xa3\x66\xf2\x23\xac\xfa\x07\x97\x95\x40\x07\xb0\x0e\xfb\x4f\xfa\xdb\x5f\xc9\x2b\xdb\x37\x86\x3e\x50\x2d\x7d\x70\x68\x10\x39\xed\xf3\x37\x70\xdf\x3d\x1d\xe3\x43\xdc\x35\xf2\x26\xd5\xe7\x39\x44\xba\x02\x55\xe2\xa8\x8e\xf6\xc4\x1e\x47\x2b\x21\x45\x67\xc2\x49\x59\x4a\x50\x87\x8b\x67\x31\xc1\xae\xb5\xb1\x0f\xa9\x1f\xa7\x6a\x37\xe1\xf9\xf1\xc0\x0f\xdb\xfe\x34\x85\xde\xd5\x4a\x00\x9a\xb6\x13\x39\x27\x11\x56\x68\xb5\x9f\x51\x15\x50\x8d\xa9\x37\x0f\x6b\xc9\x2a\x11\x85\xc0\xd5\xca\x01\xd2\x91\xe1\x8c\x54\xac\xfa\xca\x73\x8b\xd7\x19\x68\xa3\x42\xa0\xcb\xa6\x2e\x4b\xb1\x04\xa5\xbb\x37\x9f\xc8\x3e\xe1\x82\x0d\x1d\xb9\x80\x25\x3d\x6c\xb3\x83\xe9\x5a\xf1\x5f\x53\xc8\x5d\x17\x58\x90\xdd\xe5\xe4\xed\x03\xd2\xd0\x13\x5e\x3d\x60\xb1\x82\x93\xf5\xb5\x64\x1e\xf8\x3c\x6e\xce\x3d\x52\x59\x8f\xc6\x35\x36\x86\xe6\xf7\xb0\x9f\xde\xc1\xf6\xf1\x53\x67\x2d\x34\xb4\x89\xb4\x8a\x0d\xb9\xe4\x2c\xed\xa7\x17\x55\x48\x1c\x04\x70\x16\xc2\x25\x34\xe9\x0c\x6d\x20\x1e\xd7\x85\x96\x02\x63\x6e\xa7\x7a\xe8\xc6\x73\x4b\x7c\x4c\x5b\xd9\x95\x79\xc5\x08\x73\x1c\x72\x46\xa2\x95\x86\xe4\x06\xe1\xd9\x32\xf6\x71\x30\x71\xd4\xbe\xa6\x3d\xc5\xe2\xa3\x76\x1e\x16\x02\x4d\x2c\x32\x84\xf7\x09\xa1\xf2\xba\x08\x5e\xad\x32\x00\xc7\x04\x62\x75\xcb\x96\xb6\x1a\x60\xb5\xac\x55\x9b\xc4\x88\xbd\x10\x64\x67\xc3\xde\x50\xbf\x5d\x74\x0d\x05\xc9\xcd\x70\x1d\x65\xb7\xda\xea\x29\xe6\x4d\xd5\xa9\x7a\xdb\x6b\x5c\x82\xcf\x7f\x23\x01\x7a\xa7\xca\x1a\xc9\xa3\x9e\x58\x27\xeb\x47\xe2\x0d\x35\x9b\x67\xc7\xd4\xe1\xa8\xe3\xe2\x7c\x52\xd3\x3d\x93\x03\xa5\x92\x62\x34\x84\xd7\x97\xb4\x02\xcb\xb4\x58\xd1\xac\x2e\xa5\x3e\x1c\x4f\x7a\xbb\x70\xcc\x02\x95\x54\xa2\x34\x57\x4d\xef\x9b\xc3\xb0\xd3\x83\x5d\xc3\x14\x90\x2e\x25\xab\xb2\x2d\xfd\xed\xdc\x67\x9a\x3c\xc8\xf0\x73\x40\xb1\x5f\x57\x62\xf4\x40\x7f\x38\x03\x42\x55\x4e\xd0\xc6\x2f\x73\xb6\x18\x16\xea\x8c\x52\x94\x61\xe1\xbf\x0e\x9d\x1c\x2d\x5e\x4c\x57\x46\x33\x6b\xc0\xe1\x32\x87\x3c\xde\x0d\xc2\x15\x8b\x54\xfa\x1b\x67\x8a\x00\x6b\x4d\x95\xed\xa8\xa9\x55\x71\x42\x73\xb7\xcc\x5c\xf2\xad\xd9\x09\x4d\x46\xe4\x9a\xbc\x09\x6a\x45\xf4\x18\xe2\xed\xbe\x99\xdd\x85\x29\x11\x68\x80\x64\xdf\x7c\xf0\x61\xd0\x7a\xee\xf4\x27\x95\x69\x0f\x48\xc9\xba\x19\x56\x54\x75\xd5\x46\x8a\x9e\xf4\x5d\x7b\xf7\x5f\xd7\x11\x82\xdd\x6e\x64\x01\x38\xf1\x82\xa6\xa0\xc6\xcb\xbd\x00\xc4\x95\xc4\x38\x95\x30\xac\x8e\x67\x96\x0e\xb5\xc5\x76\x3f\x54\x84\xea\xb1\xc1\xab\x85\x01\x40\xda\x04\x2b\xa4\x7e\xd8\x52\x88\x00\xd4\x17\x87\xf0\x75\xfe\x0d\x85\x50\x1a\x7a\xb7\x66\x35\xd0\x34\x10\xd2\x86\xc0\xe1\x7d\xb4\x02\x3a\x76\x39\x74\x68\xcc\xb0\x91\xcc\x5a\xc1\xf6\x43\x45\x87\x91\x3e\xab\x92\x2b\x50\xca\x55\x67\x01\x6d\xde\xa3\x2f\xb5\x32\x55\xbe\x67\xf2\xdc\xf9\xff\xa8\x5d\x11\x7f\x1a\x65\x5f\xa7\x0d\xd3\xa5\x4c\xf9\x91\x53\x1f\x19\x13\x0e\xaa"}, +{{0x26,0x99,0x52,0x17,0x2c,0x3f,0xa9,0x76,0xde,0xfb,0xf4,0x0b,0xd6,0xed,0xd8,0xf1,0x5c,0xfd,0x4b,0xe1,0x0c,0x75,0x8e,0x37,0x41,0xd7,0x41,0x62,0xd8,0xea,0x22,0x9a,},{0x4a,0xea,0x57,0xc7,0x21,0xe3,0xdc,0xca,0x82,0x39,0xe9,0xad,0x9b,0x22,0xc1,0x9b,0xab,0x8d,0xf7,0x2c,0x88,0x79,0x3b,0x24,0xd8,0xdc,0x47,0xcf,0x97,0x40,0xfc,0xf8,},{0x3a,0xc8,0x0d,0x1e,0x8f,0x68,0xb4,0x05,0x8c,0x3a,0x04,0xda,0xd7,0x18,0x73,0x73,0x95,0x9f,0x26,0xa2,0x70,0x02,0x49,0x6f,0x8a,0xfa,0xac,0xcd,0x8b,0xea,0x09,0x01,0xc5,0x4c,0xab,0x87,0xb2,0xa2,0x30,0x2e,0x1f,0x36,0x25,0xc2,0xb0,0x6c,0x7e,0xbc,0xf3,0xce,0x96,0xde,0x3a,0xfd,0xf0,0x0f,0x51,0x94,0xa3,0x5e,0x05,0x52,0xc7,0x0e,},"\x7c\xcb\x6a\x05\x70\xc5\x33\x73\x7b\x9a\x53\x4a\x34\x1a\x7a\x96\xdc\x76\x52\x8b\x99\x7a\x9b\x48\xe6\xe0\xfd\xe1\x0f\x47\x4b\x27\xec\x98\x99\x12\xd1\x76\xca\xb7\x42\xd8\x9a\x84\x8b\x36\x66\xe9\x27\x7d\x69\x5b\x02\x2f\xd5\x3a\x9e\xb8\x9e\x88\xc7\x20\x39\x9e\x24\xed\x25\xdb\x9e\xb3\x5d\x6d\xa0\x09\xe9\xf0\x24\xef\x8e\x65\x51\x65\xbd\xef\x1c\x0d\x79\x7c\x74\xf0\x19\xcd\x59\x1a\x04\x42\xa1\x2d\x1c\xa8\x93\x83\x6c\xa2\x62\x8b\x33\xe8\x54\xf3\x42\x8e\xec\x4a\xa5\xed\x84\xf4\xbd\xd2\xee\xf8\xb6\xd2\x25\xca\xf9\x49\x6d\xf9\xed\xff\xd7\x35\xea\x54\xdb\x1b\xde\xa8\x83\xad\x5d\x47\xeb\x0b\xd4\xa6\x65\x3f\x0a\xb0\x37\xf0\x40\xa4\x15\x17\xa7\x74\x1f\x91\xe8\x2f\xdb\x6f\xda\x04\xf0\xdf\xa1\xbc\xf8\xb9\xb3\x7b\xf2\xbf\xbd\x87\x32\x7a\x63\x6f\x90\x7f\xdf\x96\x8d\x01\x89\xd1\xa1\x18\x09\xc4\x23\x0b\xa6\x9d\x5c\xbd\x84\xf5\x61\xbc\xac\x3a\xd0\x02\xe5\x58\xc5\xb9\xb0\x97\xa0\x19\x02\xf2\x9c\xe3\xf1\xec\x26\x41\x53\xd6\x68\xc7\x8b\x84\x51\x05\xb9\xcd\x2e\xf3\xc9\x43\x53\x1b\x75\xaa\x42\x8f\x17\x9e\x4b\x34\x18\xb1\xd5\xa4\xaa\x7a\xb1\x20\x3e\xfa\x49\x5c\x87\x69\x62\x8e\xb1\x06\x3a\x93\x7b\x73\xe4\xb5\xcd\x0c\xda\x33\xda\xb0\x1a\x50\xc6\x4f\xeb\xd9\x75\xc5\x7a\x1e\x84\x15\x08\xe8\x60\x60\x94\xd0\x82\x4f\xdd\x96\xcc\x6c\xfa\x18\xfa\x82\x09\xb3\x0f\x0a\x2a\x78\xea\xc9\xa7\x67\x17\x6f\x57\x3e\x78\xc0\x68\x80\x9b\x19\x9a\x69\xac\x6d\x33\x5d\x7c\x92\x09\x99\xc4\x0c\xba\xd8\x7c\xf4\xcc\x7c\xa5\xc6\x44\x29\x1d\x75\xad\x7a\x74\xbc\x1e\x63\x92\xd1\xce\x31\x1e\xcf\xd2\xeb\xc9\x16\xe3\x9e\xb6\xaa\x3e\x7d\x89\xfb\x80\x5a\x27\xa5\x5f\x17\x89\x12\xb1\x57\xbc\x01\xa0\x55\xf6\x7a\xef\xa7\x8e\x55\xc8\x06\xcb\xd9\xc0\x1b\xaf\x8e\xf9\x2c\xad\x22\x60\xb4\xbb\x14\xcf\xe6\x17\x82\xde\xe5\xc5\x99\x72\x50\x69\x41\xc4\x62\xa4\xda\x7e\xb8\x99\x53\x1c\xf9\x96\xbc\x98\xba\x36\x29\xef\xfe\x6f\xcd\x17\x06\xd1\xb4\xee\x4f\x2a\x14\xe9\x21\xbd\x40\x8f\x30\xe1\x2e\x73\xfb\x7a\xa8\x60\x53\x6b\x03\xe7\x7c\xa9\x37\x82\x32\x81\xa1\x64\x53\xfe\x82\x79\x35\x94\x32\x01\xe6\xec\x14\x3a\x67\xee\xfa\x4f\x94\xe9\xab\xf9\x4f\x7e\x3d\x41\xb7\x0a\x82\xbe\x69\xde\xd8\xa5\x30\x60\xc2\x30\x5f\x42\xf6\x2f\xe6\xa2\xf7\x04\xb6\x7a\x1e\x8f\xdd\xc7\xd9\x8b\xa7\xf3\x45\x71\x19\xb3\x11\xd4\x49\x66\x3e\xd9\xe3\x20\xd6\x18\xdc\x23\x68\xd4\x95\x08\x75\xb9\xc3\x8c\x5d\x8c\x03\x10\x4e\x2e\x32\xc4\x32\x5d\xed\xd2\xbc\x26\x7e\x2a\xcc\xb0\x11\x20\x18\xe9\xc5\xa8\x00\x7c\xca\xb2\xf6\xd7\xc7\x37\x79\x20\x02\xac\xb7\x30\xd7\x2e\x9f\x73\x08\x29\xeb\xc4\x2c\xa5\x64\xc1\xd9\x27\x1b\xf1\x86\x9c\x4d\x35\x83\x55\x89\xb7\x43\x1e\xf7\xa3\x1a\x07\x00\x60\xfe\x4a\x08\x9f\xb1\x1f\x2d\xd3\xdc\xe6\x5a\xe0\xfb\x45\xbc\x3a\x28\x60\x91\x7d\x93\x3b\xa2\xd0\x90\x56\x9e\xf5\xed\x43\xbc\x25\x32\xdb\x87\x9e\x0f\x1f\x22\x5e\xad\xcb\xef\x1c\x03\xd9\xed\x78\x29\x9e\x23\x3e\x4c\xf0\x7b\x06\x4a\x7b\xaa\xc3\x4c\x5a\x0c\x19\xfc\x3a\x55\x42\x08\x9f\x70\x16\x7b\xe2\xf8\x5b\x4a\x10\xe7\x78\x52\x52\x23\xbe\x8f\xfd\x5c\xff\x96\x48\xb1\x00\x5a\x09\x8b\x4b\x39\x24\x39\x8f\xb0\xbc\xab\xcc\x6e\xdf\x30\xc0\x61\xec\xe7\xae\xa3\x5f\xe9\x8a\x92\x03\xf8\x71\x13\x69\x53\x0f\xeb\x5e\x67\xbb\x2d\x4f\x59\xd9\xc8\xbc\x99\x38\x54\xdd\x47\x47\xcd\xe3\x99\xbd\x0e\x63\x74\x0c\x1c\xc8\x39\xad\x0f\x09\x8a\x38\xa8\x0b\xea\xdd\x64\x8e\x14\x36\xde\xee\x60\xe9\x31\xe6\x8f\x52\x97\x9c\xe4\x9f\x30\x1f\xe3\x9a\xfb\xb6\x15\x35\x20\x91\xc8\xb6\x58\x5f\xe8\x84\x47\xed\x6e\x59\xa0\x20\xb2\xbb\xe6\x6a\x94\x23\xae\x52\x28\xc2\x03\xbf\xd4\x84\x7b\x51\x81\xe2\xc3\xb4\xda\xd8\x3a\x6d\x4f\xa7\x69\x85\xee\xf7\x6a\xdd\xe3\xb3\x4e\xdb\xdd\x28\xd6\xa0\xb4\xa4\xee"}, +{{0xcc,0x31,0x38,0xe5,0x02,0xa5,0xff,0x6f,0x80,0xd2,0x46,0x36,0x6e,0x84,0xd6,0x5c,0x59,0xf1,0x2d,0x4f,0x49,0x63,0x97,0xe6,0xeb,0x99,0xb5,0x26,0x7b,0x8c,0xbe,0x2a,},{0x9e,0x2d,0x3e,0x88,0xaf,0x7b,0x52,0xdd,0xcf,0x00,0xe6,0xd0,0xc7,0x75,0x9c,0x12,0x38,0xb8,0xfb,0x3e,0xb1,0x44,0x21,0xfe,0x82,0xc3,0x48,0x33,0x43,0x78,0x35,0xbd,},{0xa2,0x70,0x0e,0x38,0x95,0xed,0x0c,0xc2,0xaa,0xf0,0x12,0xa4,0x0b,0xc7,0xbd,0x0b,0xd2,0x9d,0xd7,0x9c,0x69,0xc0,0xb4,0xa6,0xed,0xd0,0x53,0x0c,0xf3,0xe2,0x67,0xc0,0xf8,0x2d,0xd8,0x4e,0xda,0xf1,0x74,0x4d,0xc4,0x11,0xd6,0x2c,0x00,0x28,0x71,0x52,0x58,0x82,0x2d,0x7b,0x63,0xd3,0x97,0x05,0x61,0x2b,0x3f,0xad,0x4b,0x5e,0xfb,0x04,},"\x58\x5e\xcf\x2f\x09\xeb\x92\x3d\xf2\x0a\x85\x55\x64\x2a\x2b\xc0\xb6\x8c\x6a\x5f\xcf\xd6\xb8\x40\x1c\x4a\x0c\xba\xbb\x4c\x6e\x6a\x20\x67\x62\xb7\xa3\x9f\x2c\x54\x55\xd7\x80\x8e\xbf\xbe\xd5\x6d\x67\x60\xa4\x31\xc7\xd2\x0c\x2d\xc6\xef\x1b\x73\xca\xa3\xc4\x94\x88\xe3\x0b\x1c\xa2\x52\x0a\xd2\x0b\x26\xa1\x97\x00\x78\x0e\x5e\xf3\xce\x01\x44\x38\x8d\x84\x07\xb6\xa7\x0c\x1c\xda\x37\xdb\x7f\x12\x09\x1d\x89\x2f\x2e\x91\xad\x40\x78\xbb\x4d\xb1\x76\x2e\x46\x28\x5a\x7b\x66\x4b\x2a\xd3\xa3\x4d\x26\xd8\xa9\x4d\x64\x58\x7a\x84\x52\x77\x22\xea\x83\xcb\x8a\xa8\x89\x84\xe1\x48\x97\x43\xb4\x21\x4e\xa6\x04\x1a\xa1\x8e\x55\x20\x09\x54\xef\xc7\xed\xb3\x19\xdf\x94\x7e\xfb\xfc\x6c\x8d\x0f\xea\x48\xa1\x31\x61\x34\x65\xd8\xf4\xc4\x94\x98\xf2\x26\x91\x45\xc6\xda\xe5\x04\x78\x05\x25\x98\xe1\xca\x3b\xe0\xe3\x36\x11\x57\x1f\xa3\x84\x77\x1e\xee\x40\x2c\xc2\xb1\xd8\x48\x36\xc8\xf1\xad\x28\xf2\xad\x23\xde\xe9\xff\x1d\x7e\x1f\x25\x21\x63\x58\x74\x11\x5d\xef\x4d\x93\xe8\x9b\xe7\x61\x80\xbc\x55\xf7\x61\x14\x43\x60\xa8\xb2\x22\x89\x2d\x64\xd1\x57\xcc\xb5\xd8\xf4\x85\x5d\xca\x56\x70\x14\x95\xa0\xe1\x00\x2d\x34\x0a\x4a\x46\x15\x6b\x9b\x7f\xe0\x6b\x7c\x07\x59\xe0\xb6\xdf\x55\x9b\x69\x1e\xde\x78\xb5\x5a\xf6\x4e\x7c\x8d\xd9\x08\xb7\x88\xdd\x6b\xa3\x5a\x90\x2c\x81\xdc\xeb\x37\x88\xb6\x15\xde\x22\x5a\xfa\x58\xa8\x11\x81\xab\x24\xa7\x37\x05\xee\x83\x8b\x6e\x86\x3f\xe1\xbc\xc2\x6c\x1b\x94\x32\x39\x23\x0c\x27\xc6\xb3\x97\xb2\x3d\x13\xde\x6a\x02\xc9\x7f\x36\x45\xda\x91\xd4\x13\xf9\x16\x47\x3b\x01\x8a\x61\x59\x4b\x6f\x51\xce\xa4\x44\x57\xda\x1e\x3d\xbb\xba\x6d\xe1\x68\x66\x65\x7e\x92\xef\x02\x02\x71\x8a\x84\xad\x03\x33\xe8\x33\x6b\x05\x2b\x00\x47\x33\xe8\xe9\x5e\xc1\x3e\x5f\x91\xb3\x80\x6a\x98\xd3\xdb\x72\x9f\xb7\x35\xb8\x14\x7c\x4a\x98\x2a\x2d\x5b\x4e\xfa\xe9\xc0\x9d\x0a\x9b\xf8\x91\xcb\xbc\x3c\x8f\x53\x1e\x76\xe4\x04\x4e\xc9\x1f\x4d\x7c\x5c\xf7\x73\x10\xe2\xb2\xcd\xe2\xe0\x7c\xcf\x3e\x0a\x19\xdd\x6a\xe1\xb3\xfc\xb2\xdf\x42\x18\x6e\x9c\x72\x92\x2d\x2d\x4c\xe5\x1b\x30\x6e\x81\xb1\x6c\xfc\xf8\xf0\x0d\x51\x3f\xbd\x2c\x52\x39\xb4\x5a\xfc\x65\x4f\x6f\xe2\x1a\xcb\x7e\x8a\x0c\x9a\xa8\x7b\x0b\x60\x50\x74\xdf\x95\x76\xa6\xdd\xd9\x00\xac\xa5\x67\x61\x7c\xb7\x96\x56\xb3\xb5\xec\xb9\xff\x68\xb2\xf6\x24\x1e\xd0\xd0\x24\xac\x27\xaa\x6e\xb4\x86\xb6\x9f\xdc\x0a\x0d\xb9\x20\x96\xab\xf8\x60\x02\xde\xc7\xaf\xd8\x47\xa0\x06\xa3\xf6\x95\x5b\x49\x56\x90\x53\xbe\x9f\x1d\x0a\x49\xb7\x93\xa5\x41\x1e\x59\x16\xf4\x18\xec\xab\x95\x32\x43\x55\x3b\x66\xe6\xba\xdc\x4e\x90\x9b\xe0\xef\x5c\xc7\xc6\xd2\x71\x99\xec\x3f\x21\x42\x3b\xc4\x57\x73\xfb\x40\xb9\x7b\x61\x18\x5b\x57\x08\x0e\x8f\x0b\x89\xa3\xea\x57\xc8\x44\x4a\xb2\x7e\xcf\x70\x06\xa7\x66\x04\x7e\xef\xf5\x4d\x85\x56\xcf\xed\x23\xde\xf1\xda\x2c\xc8\xae\xbb\x48\xc9\x4e\x77\x9e\x82\x03\xae\x2c\x90\x2b\x51\xde\x0e\xde\x04\x56\xfb\x73\xfb\x4d\x5f\x51\x4a\x4c\xeb\xc4\x7f\xec\x3f\x94\x84\x69\xa5\x45\xc6\xbc\x57\xb4\x13\x8d\xb3\x4e\x7c\xc0\x06\xde\x26\xef\x50\x7b\x54\xd2\x81\x47\x56\x7a\x8c\x29\xac\x1e\xce\xf5\xbb\x84\xfb\x99\xac\xeb\x23\xa2\x02\x94\xd7\x4a\x85\xae\x36\xb3\x34\x50\x66\x8a\x5c\x26\x09\xd3\xa9\x39\x34\x58\x6f\xf9\x0c\x3b\x6d\x27\x32\x9e\xee\xf3\xa7\x54\xe9\xa9\xcb\xd5\x61\x7e\xf3\xb0\x93\x97\xbd\xc9\x71\x37\x07\x66\x58\x9a\x12\xd8\x90\x05\x0d\x16\x51\x45\x8b\x3f\xc5\x33\xc8\x43\xbf\xfd\xf9\x75\x4d\x93\x2c\x4e\xd7\x61\x1d\x4d\x27\xc3\x2a\x08\x75\x55\xb5\xea\xa3\x7a\xe9\x0c\x49\x79\xef\x54\x29\x9c\x42\x0a\xb5\xe2\x9a\xe2\x84\x5d\x4d\xcf\x21\x78\x92\x0a\x86\x51\x75\xfb\x9c\xc0\xe6\xb8\xc5\x24\xb1\xee\x49\x58\x05\xd5\x17\xbf\xe0"}, +{{0x5c,0x69,0x2c,0x68,0x11,0x98,0xb1,0x72,0xdf,0x2f,0xac,0x2a,0xec,0x3f,0xcf,0x70,0x15,0xc2,0xbb,0x68,0x30,0xf2,0xa9,0x8e,0x30,0xa3,0x96,0xb6,0x4a,0xf4,0x28,0x0e,},{0x33,0xb1,0x69,0xd4,0xca,0x27,0x10,0x40,0x92,0x6e,0xa8,0x78,0x35,0xe5,0x06,0x6f,0x9f,0x05,0x78,0x2f,0x08,0x7f,0xca,0x7a,0x55,0x6f,0x7b,0xf4,0xcb,0xa2,0xe8,0x86,},{0xad,0x8f,0x37,0x9c,0xaf,0x41,0xf7,0x2d,0xcc,0xad,0xc3,0xe9,0x15,0x35,0x7a,0xb0,0xcd,0x30,0x4e,0x10,0xf4,0x12,0x0e,0x0d,0xbb,0xfa,0xac,0x01,0xbf,0xfa,0xf2,0xbe,0x89,0x3f,0x70,0x07,0x2d,0xc9,0x64,0x06,0x91,0x81,0xbe,0xc1,0x7f,0xe0,0x25,0x10,0x55,0xb2,0x1e,0x23,0xde,0xe4,0x36,0x3b,0x27,0xef,0x1f,0xff,0x67,0xaa,0xfe,0x06,},"\xb1\x60\xee\x3a\x93\xcf\x6b\xc3\x45\x6e\x5b\xd0\x19\x7c\x09\xaa\x76\xc2\x25\x80\x52\xf9\xa3\x4d\xbc\x2e\xd5\x89\xf8\xdb\xe5\xff\x99\x69\xa6\x1c\xfe\x84\x6b\x2f\x67\x39\xdc\x7d\x4a\x14\x96\xe9\xad\x58\x60\x5b\x5a\x27\x58\xca\x07\x8c\x55\xa9\xfc\x1c\x4e\xeb\x54\x91\xa8\x4b\xfd\x46\x8a\x2c\xeb\x14\x1a\x77\x34\x93\xa9\xb3\xee\x82\x8b\x5d\xde\x9c\x00\xc2\x36\xff\x01\x56\xe4\xe2\xe4\x5f\xa0\x79\x31\xda\x68\xbb\xd2\x03\x0a\x88\x14\x05\xc4\xf7\x87\x28\x81\x3a\x5e\x04\x81\x24\x04\xc2\xa1\x9c\x9b\x87\xb1\xcf\xe9\xaf\x95\xe2\x73\xec\xf9\xc5\x18\xc5\x39\x35\xf8\x42\x56\x3b\x19\x2f\xae\x12\xa7\x3c\xef\x08\x5f\xe1\x9e\x89\x9e\x5b\xa0\x89\x79\xe3\x11\xfb\x28\x6f\xbf\xc7\xb2\x48\xaa\xbd\x40\xdc\x61\x61\x0e\x1d\x4f\xc9\x80\x6d\xd2\x12\x92\x39\x2d\xb2\xdb\x40\x42\x6c\x5d\x19\x6a\x48\x9c\x5d\xb7\x7e\x3e\x9c\xf0\xbd\x04\x1e\x3c\x23\xb5\xba\x1d\xb7\x81\xa1\x07\x90\xbe\x1f\xe0\x7a\x2b\x00\xca\x3a\xf8\x9c\xbd\x46\xef\xce\x88\x0e\x1e\xf2\x8b\x0c\xd7\x9d\x53\xb4\x2c\xd8\x0e\xaa\x13\x7e\xff\x7d\xf9\x0b\xcb\xcf\x95\xc9\x85\x8d\xc0\xcc\xc6\xd8\xca\x8a\xe3\x54\x7b\xdb\xf9\xff\x90\x24\xf3\xcf\x17\x01\x15\xeb\x28\xbf\x12\xb7\xd3\xb7\x01\x46\x0f\x48\xd1\xb4\xb2\x3d\x7f\x6f\xf7\x2f\xfd\xc9\xa6\xc5\x26\x24\xd1\x53\x12\xd7\xf1\x9d\xdb\x60\x26\xa1\x5e\xb5\x42\x95\xd3\x31\xfd\x79\x50\x91\x03\xbc\x59\xa3\xb6\xe1\xba\x7a\xc8\xc1\x12\xe4\xde\x28\x17\xe5\x1c\x1e\x16\x50\x7b\xa6\x6f\x25\x47\xbc\x89\x9f\x69\xc1\x20\x7a\xe5\xe3\x7b\xdb\x0e\x16\x1b\x15\xb6\x12\x30\x5b\xc0\x94\x0f\x9d\x1b\x38\x2a\x37\xec\x2d\xa6\x39\xa6\xec\xba\x1b\xcd\xfc\x51\x21\x4c\x32\x23\xc1\x1b\xba\xb7\x9f\x3f\xae\x3d\x55\xe2\xd4\xbe\x58\x4f\xd7\x60\x1e\x4e\x2e\x55\x8b\x3b\xe5\x70\x71\x15\xa6\x1f\x5a\x81\x5e\xc2\x4a\xac\x18\x09\x34\x57\xbc\x46\xc0\x5c\xfb\x7a\x3f\x25\x33\xea\xda\xdc\x9e\x6c\x1f\xe3\x10\x77\x9e\x69\x7f\x68\x30\x35\xce\x57\x87\x3d\xf5\x5d\x79\x1f\x6d\x2f\xb0\xe2\x10\x7e\x68\x66\xf8\x39\xc3\xa1\x26\xe9\x02\x38\x65\xce\xd1\xbc\xf6\x77\x99\x55\xaf\x54\x7e\x1d\x87\xeb\x32\xa9\xbf\x32\x28\x57\xfd\x12\x6b\x0c\xdc\x5d\x5e\x90\x4e\xb7\x6c\x67\x06\xe3\xc8\x97\xae\xfd\x6e\x47\x56\xfb\x8a\xca\x81\x70\xca\x5b\x39\x66\x90\x89\xaf\x1b\xb1\x41\xa2\x5d\x6b\x8b\x06\x03\x4d\x8b\x11\xab\xf1\xff\x8f\x8d\x43\x37\x58\x46\xfa\x8f\xa8\xa3\x4b\x5f\x26\x48\x20\x74\x4d\x31\x14\x9b\x7d\x57\x32\x6c\x59\xb1\xdb\x74\x13\x16\x78\xf6\x34\xe7\x23\x2c\xa5\xea\x51\x88\x76\x0a\x70\xdc\x35\xdc\x89\xf8\xe4\x53\xb4\xc6\x5b\x77\x2c\x2b\x6b\x62\x76\x8d\x83\x73\x23\x65\x51\xba\xaf\x24\xd3\xc3\x04\xc4\x1b\x62\xc3\x6e\x6a\x33\x83\xb3\xa1\x63\xb7\x3e\x78\xd8\xba\xdb\x75\x74\x1e\x50\x01\xd4\x19\xd3\x0e\x2e\xd7\x7c\x30\x96\xe8\xd8\xdf\x71\x3b\x93\x76\x2c\x97\x07\xbd\xd0\xf3\x65\xa8\x74\xb9\xda\x8a\xb7\x10\x49\x5d\xd5\x6a\xea\x93\xbb\x77\xfb\x22\x26\x35\xc6\x3b\xce\x9f\x63\xaf\x91\xfa\xc8\x9c\x66\x98\x6b\x8e\x21\x76\xdd\x45\x1d\x58\x33\x94\xc1\x90\x7c\xba\x17\x25\xf0\x6d\x25\xd1\xd0\x91\x2b\x3e\x5c\x6c\x7d\xcd\x34\x35\x8f\xad\x59\xdb\xc6\xf6\xb1\xc2\xef\x33\xd3\xca\x82\xf4\x35\x18\xfe\x4f\xf3\x13\x78\x01\x6e\x57\x8a\x7b\xab\x0b\x77\x67\x6e\xba\xe0\xd4\x8d\x08\x89\xd6\x90\x29\xd2\x09\xf2\x83\xce\x8f\xe0\xec\x23\xcd\x83\x2a\xdc\x12\xa9\xc3\xe3\xae\xc2\xd6\x03\x66\x95\x55\x6d\x93\x13\xf1\x2a\x89\x9d\xd5\x9a\x66\xbe\xf2\x8e\xde\x17\x5f\x8a\xae\xee\xb2\x94\x2b\xb9\x08\x92\xa0\x4b\x44\x0d\x04\xb6\x6f\x5e\xef\xf6\x1a\xda\x72\x79\x02\x94\xce\x55\xc8\x6c\x6d\x92\x78\x5d\xdd\x26\xc7\xa7\x31\x60\x3b\x06\x9c\x60\x3c\x92\xe4\xfe\x8f\xf7\x82\x54\x4c\x8e\x89\xb4\x0b\x8b\x55\xf9\x0e\x2a\x5e\x9a\x0f\x33\xc7\xfe\xc7\x7d\xad\x81\x52"}, +{{0x9d,0x5f,0x85,0xd2,0xe7,0xdf,0xd0,0x3b,0xb6,0x89,0xd9,0x00,0x28,0x5f,0xd4,0x46,0x15,0x38,0xa5,0xf2,0x71,0x0a,0x13,0xed,0x21,0xc7,0x75,0xf6,0xef,0xf6,0xb3,0xff,},{0xb8,0x67,0x97,0xe4,0xbe,0x02,0x86,0xae,0x39,0xe4,0x4d,0xf0,0xa0,0x0c,0x01,0x6d,0xb4,0x55,0x5e,0xf8,0x6f,0x2f,0x05,0xd0,0xa3,0xed,0x89,0xd8,0x9a,0x4c,0x3e,0x5e,},{0x17,0x6b,0x95,0x92,0xf8,0xc2,0x51,0x35,0x29,0x2a,0xdd,0x4d,0xaa,0xcc,0x9c,0x4f,0xaa,0x21,0xd4,0xf4,0x9b,0x27,0x84,0x80,0xc4,0xe8,0x88,0x1c,0x01,0x62,0x4d,0xf9,0xa3,0x7e,0x23,0xe1,0x8e,0x84,0xca,0x32,0xd0,0xd8,0xcb,0x85,0x10,0x54,0x22,0x2f,0x10,0xa4,0x95,0x41,0x9f,0x19,0x7e,0x7b,0x3d,0x18,0xdf,0x0a,0xdf,0xb1,0xb3,0x07,},"\xf7\x0b\x5b\x05\x3a\x46\x72\x51\x2c\x24\xb3\x16\x83\x92\xf6\xa1\x7d\xd7\x7d\x86\x89\xc2\x1c\x86\xef\xc2\x58\x29\xa1\xa0\x4f\xab\x4f\x76\xc8\x52\x16\x84\xd3\x20\x10\x45\x59\x07\xa2\x69\x08\x67\x7b\x40\xdc\x69\x47\xd6\x54\xf2\x91\x4c\x30\xec\xee\x72\x4f\xa6\x84\x46\xb5\x9d\x09\x1e\x25\x8f\xc8\x62\x41\x1c\x96\x4d\x66\x8d\xef\x83\x03\x4b\x62\x7e\xd4\x16\xdc\x19\x0b\xb5\xa2\x63\xa6\xff\x8d\x55\x9e\x13\xb8\x93\x62\x25\xfb\x4d\xab\x4f\x7b\xda\x04\x68\xe5\x47\xe7\x08\xcb\x04\xce\xbe\x1e\x5c\xfc\x69\xf7\x6a\x1d\x28\x3f\x28\x16\x82\x86\xf2\x4e\xce\xa5\x53\x5e\x44\x90\xa0\xc5\x55\x67\xa7\x34\x5e\xf9\x53\xce\x42\x6b\x20\x9a\x3d\xe3\xdf\x59\x5e\x80\xee\x61\xe5\x72\xa2\x78\xab\x02\x21\x95\x51\xb7\x3d\xa4\x19\x84\x80\x82\x85\xa8\x35\x98\xa0\x2d\x9b\x28\x67\x12\x10\x00\x4e\x31\xd8\xaf\x92\x42\xc1\x6f\x90\xd5\xea\x8f\x63\xa1\xff\x66\xcf\xe6\x0e\xcb\xe5\x37\x24\x5f\xa1\x2a\x9b\x15\x41\x15\x29\x58\x06\xea\x2d\x11\xf3\x67\x17\x82\xb9\xaf\x4f\xa8\x6a\x12\x88\xe1\x23\xcf\xd2\x40\x9a\x5d\xc9\x8f\x41\xb8\xf6\xdf\x29\x9b\xbc\xc4\xbb\x64\x47\xdc\x03\xa6\xd6\x0e\x9b\x2c\x5b\x8f\xfc\x40\xd9\x83\x95\x6b\xe9\x77\x68\xdd\x06\x12\xd4\x7c\xbf\xa7\x57\x1c\x99\x69\x85\x6c\x15\x2c\xd3\xb4\x73\xac\xe0\xb8\xa1\x44\xaa\xc2\x09\x5c\x0f\x72\xf1\xd3\x14\x71\x52\xb9\x08\xef\x66\x26\xd5\x22\x28\x19\xb2\x0b\xb3\x35\x0a\x46\x45\x2f\x67\x54\x90\xc2\xa8\x21\x50\xee\xc4\x0d\x75\xb6\x6a\x32\x5d\x6e\x92\x9a\x90\x5a\xde\x1e\x31\x60\xab\x95\x01\x81\xef\xc6\x6e\x59\x23\x08\x65\xd5\xe5\x99\x69\x8a\x8a\x3f\xf5\x60\xc4\xc6\x01\xa7\xa9\xa5\xda\x3b\x5d\x89\xbc\xa9\x3f\x7c\xf5\xbc\xf5\xbd\x5e\xcf\xf8\xf1\xa1\x85\xc8\x22\x0e\x4c\x77\x82\x1e\x62\xad\xf9\x5a\x03\x7f\x2d\xf7\xce\xf4\x3a\x4c\x60\xac\x75\x80\x1e\x9f\xcc\xdc\x5b\x08\xee\xd3\x28\xdd\x93\x10\x09\x04\x11\x56\x45\xec\x1e\xe0\x85\xcc\x77\x8b\x0f\x4e\x46\xe1\x72\x98\x98\x4a\x70\x2e\xce\xb3\xe1\x52\x83\xd8\x20\x00\x4f\x74\xa0\x79\x52\x0d\x63\xa7\x5f\xae\x33\xec\x3f\x4b\x83\x64\x69\xe1\xaa\x99\xea\x24\x4a\xf1\xfb\x08\xb0\x0a\x8c\x9d\xfd\x03\x30\x8d\xfc\x20\x23\x5e\xa9\xc8\x28\x3f\x4d\xa4\x7c\xfb\xcd\xbd\x03\x1a\x02\xd1\x64\x16\x0f\x2a\x58\x98\x67\x00\xb1\x95\x26\xd4\x1e\x4d\x7f\xd4\x58\x43\x4d\x72\x64\xbc\x8e\xb6\x42\xe6\xd8\xdd\x27\x59\xce\x2b\x85\xc9\x7b\x37\x02\xe7\x0d\xa7\x1f\x18\xed\xc5\x3e\x91\x40\xa6\x45\x62\x7e\x02\x78\xe8\xe7\x05\x39\x03\x74\x84\xdc\xd1\x8c\x62\xfa\x33\x07\x17\xd6\x14\x8a\x0d\x62\x3f\xf8\xb6\x5e\xa8\x56\x7e\xc7\xfa\x04\xc8\x92\xe3\xa1\xec\xee\x96\xe8\x32\xf4\x15\x50\x74\xc8\x3c\xbc\x93\xe9\x8c\xc6\x7f\x1f\xa1\x12\xaa\x06\xe9\x91\x5f\xa4\xd2\xde\xa9\x31\x55\x1e\x7c\x62\x3a\xa8\xa3\xa7\x61\x9e\xa2\x4f\xf9\x14\xe2\x64\xf3\x1f\xc7\x3d\xfa\x8c\x43\x0a\xc4\x6c\xe1\x6d\xc9\x68\xc5\xa4\x08\x5d\x5c\x38\x0d\x30\xcd\xc6\xf4\x3d\xee\x80\x6f\x38\xd1\xdf\x42\x0a\x06\x55\x74\x14\x47\x37\x05\x6d\xaa\x62\xf0\xc0\x98\xc9\xc5\x2f\xcc\x04\xcc\xa6\x42\xc4\x5d\x68\x73\x45\xa0\x94\x61\x3d\x4a\x3c\x6c\x87\x88\xbf\xa2\x18\x53\x8a\xd7\xec\xe1\xbd\xb6\xc9\x39\x24\xee\xc4\xba\xaa\x3e\xb1\x5d\xc1\x49\x4d\x65\xff\xa1\xa2\x3f\xf8\xe9\x85\x26\x34\x08\xfb\x02\xbf\xe3\x9a\x8c\x55\xb3\x00\xb1\xa0\x2e\xd3\x6c\x67\x14\xdd\x5a\xb7\x50\xd4\x7f\x02\x1f\x65\xe0\x8c\x63\x5f\x1d\x6b\x7b\xaf\x39\x6c\xb4\xf9\x3d\x56\xc1\xca\x46\x1b\xb1\x2e\x94\xde\x7e\x5d\x98\x65\x9a\x8a\xf0\xbf\x01\x9f\xc4\x22\x80\xe1\x11\xe0\x48\x00\xff\x80\xe0\xc1\x57\x15\x0e\x16\x56\x09\x45\x42\x81\xb2\x00\x07\xe3\xed\xfa\xa1\xea\x85\x44\x65\x54\x7a\x00\x6a\x4c\x32\x36\x41\x14\x95\xda\x16\x60\x98\xaf\x28\x23\xa4\x59\xcf\x10\x0a\x1f\x3c\x92\xc6\x39\x0c\x60\x66\xcd\xbf"}, +{{0x4a,0xaf,0x2d,0x13,0x28,0x84,0xf3,0x0d,0x11,0x27,0xcf,0x18,0x7e,0xe0,0x93,0x88,0xb4,0xa5,0xc4,0x4a,0x9a,0x92,0x67,0xe6,0x72,0x83,0x17,0x39,0x89,0x51,0xfb,0x61,},{0x83,0x72,0x7e,0x92,0x57,0x34,0x91,0x28,0x55,0x9e,0xbf,0x75,0x9f,0xdc,0x82,0x12,0x2c,0xce,0x76,0x74,0x66,0x39,0xc0,0xad,0xa9,0x76,0x1f,0x0d,0x60,0xb9,0x40,0xb1,},{0x5f,0x11,0xdf,0x39,0x06,0xa7,0x12,0xa9,0x53,0xf4,0x7c,0x85,0x98,0x06,0xb5,0x23,0x73,0x58,0xd0,0x8b,0xa9,0x5e,0x49,0xf9,0xe5,0x30,0xa3,0x71,0x65,0x83,0x5e,0x93,0x59,0xd9,0x76,0x9d,0xc2,0x1f,0xbb,0x4d,0x44,0x49,0x7b,0x93,0x90,0x5b,0xca,0x8d,0x99,0x17,0xc7,0x28,0x49,0x3f,0xee,0x3a,0xcd,0x5b,0x52,0x1d,0xbd,0x1e,0x24,0x08,},"\xd7\x3e\xaf\x11\x41\x3b\xf4\xd5\xbc\xcf\x6a\x2e\x80\x9c\xd6\x83\x2a\x51\x82\x3a\xa2\x2b\xd1\x6e\x09\xcf\x56\xff\x04\x5e\xef\x2d\x1a\xda\xdd\xa5\x0c\x2e\xbd\x67\xbb\xc4\xd7\x0e\x49\x3c\x96\x8c\xb4\xde\x49\x77\x06\x5d\x44\x63\x30\x06\x94\xc9\xca\xa5\x72\x06\xd6\x66\x46\x93\xd8\x46\x2c\x3c\x57\x6b\x52\x5c\xc7\xac\xf7\x9f\x26\xf9\x05\x5a\x1b\xcf\xa7\xd0\x77\xf4\x5e\xbe\x0b\x2d\x48\x1e\xbd\x63\xf7\x34\x0a\x33\xe4\xab\x68\xf1\x60\x49\x75\xec\x1d\xfe\xc4\x5a\x79\x1a\x2a\xbb\x10\x44\xd7\x5a\x4d\xb5\x5a\xdf\x59\xb8\x39\x4e\xbd\xe6\x82\x4c\x21\x14\x5b\x00\xef\x3b\x1b\x08\xed\x11\xfd\x51\xdd\xa5\x14\xed\x7e\x21\xe5\x4d\xba\xf6\xab\xb6\xd9\xe3\x17\xfc\xf9\xfd\x37\x5b\x18\x76\x4e\x64\xac\x9b\xe5\xb0\x8f\xec\x3b\x78\xab\xba\xb1\xd1\x2a\x2a\xb0\x9d\x55\x9a\xcd\xc7\x13\x3f\xb2\xe0\x00\x8e\x0c\x11\x4b\x7c\xad\xb4\xbf\x76\x30\x78\x67\x4d\x03\xe9\xc8\x07\xbe\xc1\xe2\xca\x71\xad\xcd\xaa\x31\x0d\x58\x7f\xa5\x69\x50\xfc\x0f\xb2\xe9\x79\x04\x3d\x50\xf9\xae\x23\xfa\x8f\x82\x1c\xd9\xd6\x23\x27\x89\xd0\xee\xcc\xfc\x4f\x47\xe3\xad\x80\x4e\x25\xcf\x5a\x42\x5f\x94\x37\x7d\x17\x87\x48\x33\xe6\xae\x36\x38\x17\x8c\x78\xb7\x95\x19\xd6\x4d\x97\x93\xf4\x50\x46\x06\xa0\xea\xb6\x87\x07\xf6\xe1\xf7\xcc\xcb\x51\x5b\xe3\xd1\x20\x1b\xcd\x19\xf2\xf0\xe2\x55\xc7\x22\xea\xb1\x2b\x43\xaf\xf8\xc8\xc5\x56\x11\x25\xfb\xca\x1f\x65\x42\x07\x6a\x06\x15\x2e\xb7\xe4\xb0\x78\x63\x24\xc2\x49\x5e\x79\xd7\x9c\x0a\x8e\x29\x5b\xb2\xe3\xdf\xd0\x5a\x90\x33\x19\x00\x65\xa2\x84\x55\x2a\x6e\x73\x60\x06\xac\xe4\x1f\x97\xcc\x43\x4a\x25\x12\x05\x1b\x72\x7c\xe5\xbc\x9c\x4a\x75\x52\x9e\xc5\x3d\xd7\xd1\xf1\x26\xe7\x93\x85\x77\x47\xb5\xba\x8d\x03\x15\x5d\x45\x55\xf5\x9e\x8b\xaf\x2f\x0c\xdb\xa8\x71\xac\x16\x0e\x75\x19\xa8\x52\xdb\x00\x4f\x70\x16\x41\xa4\x0a\x42\x2d\x4c\x38\xb6\xc0\xc3\xcc\x8f\xbb\xd0\x53\x22\xdd\xc0\x00\x1f\xb8\x67\x28\x6e\x29\x6c\xbd\x69\x86\x2c\xbc\xcc\x74\x47\x03\x8e\xb3\x0f\x8a\x81\x23\xb7\xb3\x13\x73\x98\x47\x02\xc3\xbe\x45\x7a\x4b\x8c\x54\xe6\xe5\x28\x04\x85\xa2\xc4\xff\x84\x52\x1f\x29\x8d\xde\xb3\xb3\xb2\xbc\x91\xf1\x14\xdd\xce\x67\x03\x02\x48\x04\x44\x69\xdc\x06\xf3\x62\xf2\x91\x9a\x3f\xec\xe5\x08\x23\x75\xd0\x40\x80\x37\x6f\xe2\x19\xd9\xb4\x57\x5b\x1c\xf1\xc9\xec\x4d\xca\xc5\x74\x9f\xc7\x78\xf5\x15\xdd\xa1\x3f\xa0\xd5\x86\xc2\x64\xb9\xbb\x61\x50\x33\x10\x76\x2c\x78\x9c\xa1\x16\x08\xd2\xfe\xe6\x74\xc7\x0a\xc4\xfc\x6d\x5e\xbc\xf6\x8c\x4a\xb8\x9b\xd8\x45\x55\xfc\x00\x75\x23\xc2\x8a\x7e\x1d\xd0\x8a\x98\x62\x04\x4d\x52\x45\xb9\x1a\x87\x78\xec\x9e\xe9\x84\xa4\x1a\x9e\x13\xb7\xab\xd6\x57\xae\x2a\x46\xae\x86\x01\x52\xc6\x44\xac\xd9\x53\x67\x67\x8f\xf6\x4c\xc5\x40\x06\xe3\x66\x14\x80\x5e\xd6\x18\xa7\xc6\xd0\xfd\x33\xa9\x08\x52\x30\x90\x84\x1c\x23\x0a\xf0\x98\x46\xd1\x32\xbb\x4c\x6b\x60\xe2\x44\x1f\x9d\x3c\x49\x87\x14\xf4\x70\xf6\xbc\x03\xa8\x0d\x14\xa2\x94\xb5\x65\xd1\xd5\xe7\x81\xcf\xfc\xb1\x30\x4e\xfd\xbb\xc7\xbf\xea\xbd\xed\xc8\x57\xac\xc4\x2e\x27\x62\xbb\xf9\x7a\xf8\x39\xa1\x66\x75\x2d\xa2\x95\x67\x28\x17\xf1\x0d\xbd\x47\x2d\x38\x1f\x53\x16\x55\x55\xac\x82\x22\xa7\x85\x35\xa8\x68\x05\xf1\xbe\xd4\x22\x88\x9f\x20\x61\x09\xaa\x74\x77\x2e\xdc\x0b\xb5\x1e\x8a\x98\x40\xcf\x62\xc9\x2f\xa6\x35\xb9\x0c\xae\x07\x6d\xd5\x0e\x5a\xed\x9d\xea\xc8\x43\xfa\x8a\x6b\x53\x99\x88\x28\x5f\xf1\xad\xab\xe4\xc7\xb8\x3d\x9e\x29\xac\x2d\x94\x09\x2d\xaa\xfe\xc9\xf6\x67\x36\x89\xba\x9e\x92\x52\xd8\x64\xd7\x57\x7a\xa8\x95\x05\xd3\x31\xfe\x78\x09\x86\x12\x77\x00\x2a\x0b\x44\xa9\x6b\xa6\xae\x4a\x52\xb3\x54\x8b\xf2\x68\xe7\x77\x78\x0c\x00\x20\x9b\x24\x5f\x8b\x14\x17\xee\x5e\x70\x1a\x12\x33\x4a\xd5"}, +{{0x4b,0xc7,0xda,0xab,0xc5,0x40,0x7c,0x22,0x6d,0x19,0x20,0xdb,0x4a,0xfd,0x21,0xb2,0xa5,0xb3,0xe5,0x9b,0x8e,0x92,0x46,0x05,0x3f,0x6a,0x1a,0x6a,0xfa,0x54,0xe7,0xe7,},{0xdc,0x53,0x98,0x85,0xfc,0x7b,0xee,0x00,0x2a,0xc5,0xde,0xba,0xe1,0x6b,0xdd,0xbe,0x4b,0x55,0x3f,0xa1,0x5e,0x81,0xee,0x79,0x88,0x76,0x94,0x0f,0x38,0xcf,0xc4,0xc5,},{0xa7,0xa6,0x48,0x88,0x39,0xbb,0xae,0x04,0xde,0xc9,0x2f,0x96,0xd7,0x28,0xc4,0x64,0x68,0x5d,0x7a,0x96,0xdf,0x51,0x2b,0x00,0x51,0x16,0x3d,0x22,0x53,0x8f,0x74,0x54,0x6f,0xa9,0x86,0xb1,0xb6,0x0a,0x6d,0x8c,0xc7,0x66,0xa2,0x6c,0x69,0x84,0xc9,0xcd,0x26,0x88,0x39,0x58,0x98,0xe2,0xb2,0xae,0x72,0xdc,0x6a,0x2d,0x5a,0x9f,0x75,0x0e,},"\x6a\xcc\xe9\x98\x43\xb2\x41\xaf\xe6\xed\xd5\xd0\xab\x78\xd0\xfb\x21\xc8\xc3\x5a\xff\x88\x13\x89\xd5\x05\xf2\xf1\xdd\x91\xaf\x1e\xb2\xad\x22\x92\x54\x92\x7c\x7f\x0e\xcf\xb7\xa8\x14\x16\x90\x57\x3a\x65\x5d\x69\x85\x3d\x74\xd0\x70\x8b\xf8\xb1\xe6\x0a\x03\x96\x30\x28\xa6\x25\xb7\x9f\x3d\xfe\xa2\xb1\x13\xff\xca\xb4\x6f\x3c\xfd\x4a\x62\x1e\x8f\xd8\xff\x0a\x96\x81\x43\xb0\xae\x03\xcc\xb6\xf4\x2e\x25\xe2\xd7\x4d\xbf\x51\x5b\xc3\x58\x69\x9b\x63\x50\x09\xb0\x1d\x61\xfe\x59\x7f\x1d\xc2\xc3\x5a\x7b\xa4\x55\x52\x78\xee\x0e\xa4\x56\xc7\xd3\x5f\xa8\x75\x7a\x41\x79\x24\xb1\xd0\xa8\x35\x1f\x22\x6a\x13\xec\x29\xd0\x25\xb4\x26\x96\xec\x1d\x99\x25\xb7\x69\xcd\x59\xc8\xe2\xf9\xcd\x3c\xe4\xe5\xc0\x20\xe0\x51\xe7\xa3\x6f\x3f\x97\xc1\xe8\xec\x71\x97\x4b\xc1\x6a\xc4\xde\x46\x51\xad\x4d\xf2\xe9\xc0\xee\xd6\x86\x92\x42\x24\xfe\x6d\xe6\xc6\x0d\xd4\xac\xc2\x6e\x0a\xab\xd8\x0c\x21\xd5\x09\xd9\x59\xb8\x0b\x43\x53\x95\x8d\x00\xe4\x4c\x51\x1d\x23\xbc\xf4\x45\x52\x60\x8b\xfa\x56\xa9\xc5\xae\x79\xde\x62\xbb\x23\xf1\x1d\x74\x0f\x48\x24\x0c\x27\xe1\x01\x99\x97\x51\xf2\x53\x47\x42\xc0\xa6\x91\x3f\xf6\x4b\x68\x3a\x18\x99\x5a\xbc\x39\x3f\xeb\x9d\x57\xc7\x1f\x49\xa0\x80\x55\x72\x98\xcc\x40\x5d\x11\xb7\x98\x8d\x71\x16\x84\x0c\x5a\xda\xf5\x3b\xc6\x72\xb4\x69\x23\xcc\x45\x7c\x70\x39\x94\x0a\xd4\xd5\xbf\x07\x3c\x6c\x88\x6b\x13\x39\x52\x59\x26\xd2\x81\xdb\xd1\xa7\x97\x39\xb2\xe3\x64\x14\xcb\xd3\x21\xb1\x85\xfc\x88\xf1\x8d\x2f\x81\xc8\x09\x97\x5b\xe9\xa0\x93\x64\x4c\xc5\x59\xed\x2a\xe5\xcc\x0e\x35\xcb\xdd\x18\x11\xf7\x02\x86\x05\x7a\x3f\x70\x30\x67\xed\xdd\xf5\xeb\x16\x90\xa7\x42\x7b\xb7\x3f\xe3\x02\x4e\xd0\xdb\x82\xa5\xce\x8f\x17\x16\x42\x8a\x76\xfd\x29\x2b\xa9\x9a\x30\x0c\x4b\x2f\x36\x0d\xa2\x12\x46\x17\x59\x0b\x10\xe3\xb1\x62\xa6\xe6\x7d\xd5\xd5\xa5\x9b\xcc\xa1\x0f\x61\x0f\xa0\x64\xaf\xfd\x55\xf8\x48\x3b\x98\xa6\x8d\x07\x6f\x27\x8a\xbf\x88\x8a\x08\xa0\x14\xe0\xea\x49\x91\x80\xfb\xc7\x98\x40\xce\xed\x13\xcc\x6b\x24\x58\xbf\xab\x9b\x0d\xd7\xae\x9d\x86\x46\x1f\xe2\x15\xe7\xc9\xf6\x3f\x76\x8c\xee\x4a\x88\x2d\xf0\xdd\x84\xe3\xeb\x4f\x2d\x7f\x6b\x18\xfa\x57\xd8\xbc\x7d\x9a\xfb\x63\xc2\x1a\xc4\x65\xe7\x90\x3b\x9b\xfb\x86\x38\xa2\x93\x61\xf7\xeb\xfc\x6e\x54\xe5\x46\x5a\x6c\xef\x46\x3a\xe2\x26\x43\xae\x41\x02\x58\x77\x9c\xa7\x4b\x70\x40\x1a\x94\x55\xa4\xd1\x57\xd7\x4a\x70\x29\xef\xe6\xb5\x19\xa8\xc4\xbe\x69\x67\x56\xe0\x45\xae\x40\x81\xb7\x7d\xd6\x03\x1f\x0d\x25\x0f\xa7\x61\xe6\x0f\x85\x9d\x90\x63\xfc\x10\x5a\xa0\xa1\xa7\x45\x0a\xf1\x53\xe7\x05\x47\x77\x77\xc4\x42\x58\x6d\xf4\x07\x40\x2b\xa2\x38\x75\x2f\xae\xf7\x4f\x33\x45\xc2\x6a\x45\x33\xbe\x9a\x61\xf5\xfc\x6b\xde\x48\xe3\xcb\xa7\x5c\x04\xd6\xf7\xb3\x33\xe3\x70\x06\xdd\x0c\x94\xfd\x3b\x6a\x13\x0b\xd6\xfc\xdb\x3c\x6a\xbe\x21\xca\x60\xeb\x43\x1c\xc2\xd8\xa2\xec\xe7\x16\x9d\x2d\xcf\xce\x27\x60\x82\x56\x57\xfd\x4c\x26\xf3\xc3\xb8\x30\xac\xdf\xd5\x08\x01\x1d\x14\x76\x4b\x3b\xe9\x17\x15\x57\x1a\x31\x83\x01\x8e\x0d\x22\x1f\xb9\x53\x2b\xb2\xe1\x71\x1e\x72\x5a\x27\x3a\xe0\xcc\x2f\xac\xcb\xa7\xd5\x50\x49\x29\x45\x9c\x99\x25\x17\xb0\x5c\x1d\xdd\x03\xaa\xcc\xd9\x37\xb8\x6e\xb6\x7b\xc8\x20\x2d\x01\xca\xb3\xd4\x89\x58\x6e\xea\x1a\xcc\xa7\xdc\x20\xcd\x0b\x64\x75\xc2\x58\xff\x67\x36\x61\x49\x6a\x22\xea\x96\xb8\x9d\xb4\xbf\x3f\xca\xae\x3b\xb0\x4f\x67\xdb\x09\x6a\x47\xff\x7e\x1e\xe2\x39\x56\x2d\xc1\x0d\x40\xf0\x53\x94\x4f\x3d\x7b\xcc\x3f\xf4\xc0\xff\x76\x56\x54\xba\x5e\xa6\x4f\x0e\xa6\x3e\x45\xa2\x1d\x9b\x12\x94\x9f\x14\xf7\xea\x70\x74\xe9\xb6\x59\xc5\xc5\xd4\x48\x16\x84\x2d\xe8\x96\x98\xa8\xfc\xca\xce\x43\xeb\x6b\x41\x35\xe0\xb3\x33\xac"}, +{{0xf2,0x6a,0xf2,0x10,0xe3,0xb2,0x01,0x73,0x99,0x0c,0x77,0x45,0x92,0x2c,0xdf,0x94,0x24,0x77,0x3a,0xbb,0x37,0x4d,0x77,0x7a,0x51,0x2c,0xf5,0xb9,0x7b,0x3a,0x00,0x0d,},{0x54,0x58,0x6a,0xbf,0x04,0x11,0x76,0xe0,0x6a,0xec,0x5b,0x60,0x10,0xe1,0x90,0x91,0x6d,0xa5,0x4a,0x8c,0x4b,0xde,0x28,0x8c,0xf2,0x4d,0x8c,0x10,0x7c,0xb3,0xb7,0x30,},{0xce,0x45,0x45,0x30,0xb9,0x22,0xba,0x5e,0xa1,0x62,0xf1,0xa4,0x52,0xe0,0x5c,0x00,0x36,0x3a,0x49,0xa9,0xdb,0x8a,0x56,0x94,0x97,0xc0,0x0c,0xaf,0x1c,0xbe,0xa9,0x91,0x80,0x77,0x05,0x54,0xed,0x4e,0x31,0x40,0xdf,0xca,0x45,0x55,0x15,0x9e,0xbf,0x48,0xef,0x5d,0x2a,0x50,0xf3,0x94,0xae,0xbd,0x78,0x21,0x16,0xed,0x65,0x69,0xa4,0x09,},"\x88\xe2\x6d\xa3\x5c\x54\x88\x4b\x47\x14\x6f\x4e\x3f\x01\x4a\xb6\x5b\x3d\x71\xaa\x7e\x3c\x33\x91\xad\xbe\xb1\x9e\xf2\xe7\xb9\x30\x2e\x28\x19\x91\xb2\x61\xb6\xa0\x99\x2e\x2e\x89\xa4\x9f\x48\x0c\xa2\xd8\xe6\x84\xb1\x2f\x9b\x15\x09\xb3\x8f\x6a\x7a\x98\xa5\xdd\xb4\xc2\xd8\x69\xfd\x03\x18\xe9\x8e\xcd\x8f\xd9\xdf\x49\x1b\xaf\x99\xa9\x29\x4d\xe4\x9e\x1c\xf8\xdd\x41\xee\x85\x73\x0a\xf0\x25\xa7\x01\x14\x3e\x4f\x0c\x8e\x3d\x92\xd5\x5b\x59\xca\x7d\x4a\x6c\x89\xad\x76\x0d\xff\xc0\xc2\x18\x92\x09\x50\x8e\xf6\xc2\x21\x4e\xdf\x99\x67\xb1\x7d\xef\x12\x3d\x86\x92\xc9\xe4\xe2\x0b\x1e\x98\x26\x88\x08\x70\x4f\x5f\x9f\xe1\xa6\xd6\x05\x5e\x32\xc8\x72\x56\x4b\xd1\x7e\xdb\x73\x59\x57\x86\x29\x01\x7f\x0c\x30\xfe\xab\x8b\x50\x4e\x22\x89\x23\xad\xc7\xe8\x1a\xe2\x0a\x85\x2d\xb0\xad\x67\x6a\x78\xe0\x81\x33\x6d\x6b\x04\x02\xf9\xcd\xc5\xd5\xe9\x01\x28\xca\x94\x5d\x10\x51\x5c\xa0\xc5\xef\x03\xf7\x31\xb1\xd4\x0a\x71\x07\x41\xd4\x1c\x1d\xd1\xca\x16\xb1\x06\x0f\xeb\xf2\xa0\x53\x2e\x6f\x5d\x76\x51\xef\x44\x63\x75\xec\x18\x09\x0c\xb8\x41\x8b\x82\x02\xf2\x5a\x03\x89\x03\x1b\x30\x7f\x22\x3c\x5b\x5f\x6a\xfe\x36\xa9\xad\xc1\x06\x8f\x2c\x6e\x0e\xa5\xb2\xb6\xcf\xeb\x8d\xc0\x04\xf7\xb8\x29\xc8\x04\x39\x06\x9b\x81\xa7\xbd\x90\x74\x77\xc6\x13\x5e\xf2\x82\xb7\x71\xf1\x41\xdb\xe7\x5a\x0f\xa0\x56\xe0\x6b\x8a\x1a\x1f\x98\xc2\x5f\xa5\x4d\x14\xc8\xfd\xb4\x2d\x65\x02\x59\x5c\x59\xd2\x5b\xac\xf1\xa1\x9a\xde\xfc\xc1\x31\x70\xf7\xa4\x31\x7b\x6a\xb6\x10\xb6\x09\xd4\x14\xb0\x07\x3e\xa0\x4a\xc2\x9e\xb1\x0e\xe7\x3c\xd7\x1a\x4c\xa6\x04\x09\xf8\xe7\x60\xe6\x0f\x93\x95\x10\x10\x0d\x0c\x8c\xd7\x6f\x26\x4b\xb3\x78\x11\xf9\x7a\xa5\x29\x9a\xc0\xb1\x2d\x41\x68\xff\x38\xec\xdf\xa8\x0b\x1e\x5c\x1b\x3b\xbd\x4d\x40\xd3\x54\x47\x35\xdf\x71\x67\xeb\x15\x8a\x9a\x9a\x23\x4d\x44\x5f\x1d\x66\x3d\xed\x71\x71\xed\xc6\x8d\x17\x2c\x92\x21\x4b\x82\xef\x13\xfe\x6b\x8c\x43\xaa\x89\xb7\x39\xb4\x99\x0a\xe9\x47\xa3\x4f\x02\x0a\x8d\x89\x43\xb0\xf7\xa5\xd6\x1d\xfa\x76\xad\xde\x02\x72\xe9\x8c\x11\x59\xc0\xfd\x8a\x1d\xe3\x3f\x2c\xef\x8e\xdd\x32\x85\x7b\x21\x89\xed\x96\x12\x80\x57\xeb\xde\xa8\x1f\x7a\x3a\x3d\xff\xe1\x89\x3b\x5b\xa8\x77\x55\x6c\x90\x38\x3f\xa2\xc5\xa6\xfd\x68\x0e\x8a\x67\xde\xe4\x80\x2d\x90\xdf\xe9\x71\x62\x3a\x7b\xe2\x2a\xb3\xca\x56\x06\x7b\x1e\x5c\x69\x4a\xa8\x4c\x19\xf1\x6d\x69\xe2\x84\xdd\xfa\x03\x9c\x10\x8d\x04\x35\x81\x38\x12\x39\x0d\x8e\xbc\x1e\x50\x13\x81\x76\xf2\x59\xdc\x0f\x26\xbc\xa1\x3b\xc9\x43\xf5\x0d\x5a\x35\x00\xb1\x8d\x59\x35\x74\xc6\x20\xfc\x09\x7a\xce\x43\x0f\xb8\x07\x28\xd3\xa1\xaa\x64\x4e\x50\x4b\x10\x09\xad\x67\x53\x6c\xeb\x01\x1f\x2a\x35\x7d\xbd\x00\x9e\x4a\x63\xf5\x24\xd5\xb5\x95\x7f\x33\x15\x67\xc5\xb4\xd1\x85\xa6\x1d\xf2\x2d\x70\x71\xd3\x1a\xe9\x21\x41\xe1\x99\xc1\x22\x89\x51\x5a\xed\x80\xc9\x10\x21\x45\x6b\xcd\x45\xcc\xc6\x34\x03\x7d\xcf\x69\xb4\x1d\x6b\x1f\xf5\x34\x71\x01\x0d\x99\xf1\x87\xf0\x46\x54\xf4\x36\x22\x28\x78\x71\xfe\xe6\xdc\xf5\xf3\x02\x3c\xbd\x09\x13\xd9\x9a\xff\x43\xfa\x95\xb3\x2e\xa2\xb1\x33\xb4\xc9\xac\x4b\x01\x7b\x7c\xf8\xf9\xbe\x50\x86\xfe\x92\xb4\x2c\xb8\xdb\xed\x5b\x63\x0b\xf0\x97\xc1\x8e\x2e\x55\xc3\xdd\x93\x27\x1e\x09\xc2\xd1\xcc\x6a\xf8\x7d\x83\xfd\xef\x3c\x3e\x3c\x4c\xba\xfb\xea\x9b\x60\xfd\x5e\x9c\xf0\x01\x1d\xe2\xe9\xe2\x6f\xbf\x09\xaf\xee\xf5\xc6\x98\x02\xa6\xc4\x6b\xdf\x54\xc1\x45\x86\x29\x44\x17\x3e\x01\x7e\x30\x14\x9e\xa5\xc0\x3c\x7a\xef\xa2\x8a\x9c\xac\x77\x67\x00\x2e\xa3\xfe\xfb\xde\xae\x5b\xae\x00\x5c\x37\x0d\xbc\x06\x42\x44\xd5\xb9\xbe\x55\x00\xa3\x57\x26\xa9\x9b\xc9\xe8\xc2\x75\x2d\x51\x0e\x13\x9a\xf2\x25\x58\x00\x98\xc8\x18\x9a\xa9\xc5\x20"}, +{{0x39,0xbf,0xfe,0x00,0x7f,0x8d,0xf7,0xce,0x4e,0x56,0xfd,0x17,0x6b,0x10,0x2b,0x92,0x3b,0xa4,0x8a,0xeb,0x82,0x69,0xfd,0x0c,0xd5,0x20,0xc2,0x3a,0x7b,0x23,0x6e,0x6c,},{0x95,0x32,0x63,0x68,0x00,0x01,0x0b,0x3d,0xd4,0x01,0x2e,0x34,0x1f,0xca,0xd6,0xd2,0x9a,0xfa,0xd4,0x84,0xe6,0xfd,0x73,0x6e,0x89,0xd5,0xbc,0x02,0xba,0x0a,0xc8,0x53,},{0xa2,0x7c,0xca,0x4b,0x9f,0x5b,0x95,0xad,0x0e,0x44,0xe4,0x74,0x0c,0x15,0xde,0xae,0xb9,0x3f,0x22,0xa9,0xb2,0x54,0xeb,0xbd,0x23,0x29,0x36,0x5a,0x00,0x96,0x6c,0x9f,0x4e,0xc1,0xe5,0x5c,0x58,0x94,0xe7,0xbf,0xc2,0x3d,0x39,0x8d,0x39,0x70,0xb9,0x46,0x5e,0x98,0xa8,0xd2,0x3e,0x72,0xda,0xe8,0xe3,0x50,0xda,0x35,0x31,0xae,0x69,0x08,},"\x7a\x8c\x20\xbf\x2e\xff\x69\xaf\x8b\xad\x6b\xdf\xab\xc7\x90\x9c\x58\xce\x74\x6c\xc4\xdf\x78\xb6\x9b\x33\xc1\x05\xba\x3b\xd8\xda\x75\x24\x47\x58\xb5\x17\x2d\x5c\x45\x01\xbc\x39\x97\x01\x85\xee\x3d\x43\x70\x83\xa9\x95\x9f\x81\xe7\x66\x5b\x82\x9a\x69\xa5\xd7\x2e\x03\x4d\x35\x1a\xdd\xdc\xeb\x3d\x3f\xff\x58\x99\x88\xdf\x18\x2b\x46\xfa\x53\xd2\x6e\x7c\x9e\xac\x06\x22\x15\x78\x8f\x23\x37\xbf\x90\xf0\x17\x7d\x8c\xa7\x44\xf9\x5f\x28\xfe\xa8\x54\x59\x3c\x43\x62\xc8\x2e\x9d\xed\x19\xb9\x04\xff\x99\xd2\xbe\xa8\x24\x32\x82\x2e\x52\xc3\xda\x6d\x46\x2d\xa7\x54\xff\x1f\x8b\xd1\x09\x94\x2d\xf5\x1d\xba\x25\xb7\xcd\xe8\x38\xd5\xf5\x24\x23\x9f\x13\x31\xf4\x63\x19\x4e\x10\xff\x56\x79\x5b\x29\x68\x78\xfe\xb1\xf5\x5d\x43\xec\x7d\xaf\x0c\xa5\xab\x3d\x68\x4b\x55\xbb\x0a\xa4\xc7\x20\xd4\xb5\xc2\xe8\x30\xc8\x58\x69\x4d\x3d\x0f\xdb\xaa\xd0\xbf\x67\xd8\x73\x18\x2d\x95\xb2\x41\x2f\xce\x5e\x7b\x00\xfa\x6b\xfc\x38\xb1\x32\xef\xb9\x6f\x87\xbc\x6c\x10\x07\x0a\x57\x16\xec\x9b\x33\xa2\x69\x2c\xdf\x5b\xc4\x1c\x7f\x73\x7e\x28\xc4\x22\x03\x17\xa4\x89\xb7\x32\x3d\x5e\x20\xf6\x5d\x37\x5d\x76\x9f\x9e\x79\x37\x6f\xd0\x2d\x85\x36\x86\x71\xe7\xe0\x81\xeb\x75\x3f\x88\x85\x45\xeb\xe5\xc0\x00\xb2\xf8\x01\x43\xeb\x35\x8d\x43\x18\x5e\x2f\x1c\x29\x4b\x9f\x29\xc8\xbb\x91\x48\x2d\x43\x87\x49\x4a\xad\x17\x6d\xeb\x85\x54\x0f\xd0\x05\xc9\x7d\x13\xe6\x66\x3f\x09\x94\x4e\xb4\x3a\x46\xe6\x23\x67\x94\xbf\x6e\x21\xf8\x1d\x0a\x42\x09\x0f\x9c\xce\xf9\x0a\x6c\x48\x07\xb5\xff\x54\x13\x00\xe5\x93\x48\x81\xa8\xd9\x21\x96\xb4\xce\xe8\x5d\x28\x09\x2a\x82\x8e\xa3\xbf\xc6\xb7\x45\xad\x21\x9b\xe9\xf5\xe9\x57\x41\x17\xd0\x79\xe0\x2f\x4b\x74\x8e\x2c\xc0\x1a\x32\x82\x6a\x37\x08\x23\x19\x14\xd2\x77\x2c\x76\x41\x19\xfd\x99\xd5\x3a\xb5\xb5\xa2\xe9\xd8\x91\xa4\x8a\x9a\xaa\xac\xc2\x63\x38\xb1\x82\x48\xdb\x8a\xb2\xd5\x25\xda\xf1\x5f\xf5\x3a\xcb\xc3\xaa\x98\xd4\xf2\xd4\xa3\x37\xbb\xaf\x6d\x1b\xe2\x19\x85\xa4\xaf\x60\x0e\x29\xbb\xb4\x2c\x8d\x89\xe6\xb3\x89\xc6\x6f\x42\x27\x0c\x3a\x0b\x05\x1b\xdb\x62\x38\x81\xe0\x2f\x2f\x42\x94\xce\xc3\x47\x63\x86\x74\x7a\xba\xe6\xc7\x70\x0b\x8f\x9b\x03\x87\xcd\xdf\xb7\x36\x68\xfb\x57\x69\x3d\x84\x74\x19\x6b\x33\xab\xd1\x2d\xce\x59\xa5\x7c\xf7\x2e\xe6\xcc\x1d\xdb\xaa\xdf\xb1\x9e\x90\xaf\x81\x31\xb3\xa9\x0f\x98\x67\xf4\xc7\xe1\x5b\xdf\x9e\x21\x84\x77\x01\x6b\xd0\xad\x3b\xe8\xdd\x05\x96\x71\xff\x65\x6c\xbd\x4e\xd8\x98\x08\x6d\xe4\xd4\x23\xf3\xdf\xb2\x70\xbb\xf1\x9d\x9f\x53\xf7\xf6\xf2\xd2\x2c\x6a\xc9\x02\x5c\xba\xdb\xa4\x42\xe3\x1d\x98\x11\xe3\x7e\x84\x7d\xbd\x48\x4d\x80\xcf\x74\x30\x39\xff\xa7\x04\x84\x70\xfb\xdc\x60\x80\xf6\xd3\x81\xdc\x7e\x3f\xa2\x71\x22\xdf\x53\xcc\x06\x39\x4e\xa6\xfc\x44\x6e\x1b\xa7\x25\x38\x73\x3e\xd3\xab\xb6\x85\xf1\x6d\xfd\x5c\xcf\x58\x5a\xe8\xfb\xf9\x95\x4b\x50\xf1\x0b\x7e\x54\x32\xa2\x2b\x36\x94\x06\xa9\xb7\x08\x89\x61\xf0\xae\x20\x74\x95\xae\x71\x85\x39\x6d\xcc\xf2\x92\xdc\x46\x3f\x41\xf3\x76\xa1\xca\x89\xee\xfb\xae\x19\x26\x91\x52\x03\x1b\xfd\x81\x52\x88\xe8\xb5\xba\xf3\x48\xc4\xf8\xff\x3d\xff\x4f\xd6\xd1\x08\xf8\x71\xda\xa3\x52\x11\x0f\xa6\x41\x88\xb0\x1b\x85\x26\xa8\x45\xaa\xed\x13\x3e\x45\x6b\x4c\x83\xc4\xfd\x4b\xbb\x16\x5b\x40\x90\x30\x7e\x8e\xb1\x7d\xf1\x76\xc3\x22\x52\x0f\x37\x59\x9c\x21\x05\xaa\x81\x20\x75\x83\x94\xa4\x22\x24\x73\x47\x67\x64\xcf\x0a\xf7\xc5\x51\x83\xeb\xa9\x68\x3d\x72\x70\x63\x14\x43\xf3\xc5\x1f\xb8\xab\x0c\x13\x0a\xc4\x36\xab\x60\x3f\xf4\xf1\xd8\x65\x6c\xdb\xed\x22\x9a\x20\x2b\x40\x00\x8e\xa1\x0b\x17\x15\x42\xf7\x4a\x70\xb7\xbb\xac\xc4\x01\x6b\x7f\x63\x6a\xa8\x96\x33\xb7\x66\x80\x58\xf1\x33\x12\xf5\x7c\x51\x62\xd1\x8e\x39\x9e"}, +{{0x3c,0x40,0x80,0xcd,0xa0,0xfc,0x3c,0x03,0xb6,0x14,0xd9,0x80,0xf2,0xff,0x83,0x1f,0x5b,0xe0,0xe7,0xa9,0x81,0xd5,0x38,0x1a,0x16,0x18,0xe0,0xb8,0xfd,0x00,0x17,0x76,},{0xf1,0xc3,0x26,0x9d,0x87,0x04,0x02,0xca,0xa4,0x38,0x82,0x13,0x5d,0x9d,0xba,0xdb,0xbb,0x16,0x2d,0xfc,0xa0,0xb3,0xda,0xd1,0x97,0xe6,0xb8,0xa7,0xee,0x67,0x9a,0x70,},{0xc9,0xd4,0xa4,0x72,0x8b,0x8f,0xdd,0x24,0x0d,0x9c,0x49,0x8a,0xa3,0x5d,0xe9,0x5a,0x4b,0xbd,0x51,0x78,0x5b,0x73,0xc8,0x40,0x3f,0xdf,0x04,0x0d,0xfa,0xed,0x94,0x47,0xef,0xad,0x00,0x69,0xb6,0x7c,0x78,0x3d,0x4b,0x81,0xd9,0x66,0xbe,0xf6,0xe3,0xd9,0xa8,0x08,0xa0,0x58,0x4b,0x98,0xec,0x2b,0x18,0x32,0x2c,0x4c,0x92,0x0e,0xb0,0x0a,},"\x0c\xee\xbc\x0e\x8a\x47\x72\x0f\x25\x83\x5e\x2b\x9a\xcf\x89\x1b\xcc\xa4\xbd\xa3\x86\x37\xf3\x63\x27\x44\x58\xba\xa9\xe2\xbb\xaf\xed\xd0\x93\x8f\x56\x88\x73\x4e\x22\xac\x50\xfb\x12\x0f\x66\x5f\x6c\x4c\x61\xc6\x53\x17\x39\xb9\x29\xac\x83\xcd\x77\xf8\x96\x3b\x75\x44\x88\xb9\xb8\x59\xc1\x38\x53\x63\x7c\xf0\x25\xc1\x4e\x8f\xdd\x11\x8f\xaa\x14\xcf\x39\x30\xce\xb3\x5f\x10\x4d\x95\x44\x1e\x56\x48\x94\x40\xf6\x20\x41\xef\x1a\xa7\xc4\xb0\x8b\x28\x07\xe3\x2b\xb9\x58\x4b\x90\x04\xd7\x6e\x76\x53\x33\x48\x50\x6d\x64\xf1\x12\xe1\xff\x6f\x93\x8f\x64\x22\x30\xbf\x38\xaf\x01\x0e\x41\x98\x72\x70\x24\x8b\x13\x63\x5a\x35\x67\xb3\x55\xbb\xa5\xb5\x74\x48\xc6\xd1\x3b\x74\xf3\xbe\xbf\x61\x79\x15\x82\x10\x28\xfc\xa5\xde\xfa\x4c\xe5\x42\x4c\xa1\x91\xcd\x54\xa2\x29\x44\xa3\xd9\x40\xe4\xee\x2e\x2b\xa5\xd5\x04\xc8\x5f\x95\x9b\x51\x4c\x4f\xab\x41\xcc\xb5\x74\x3d\x9c\xb2\xf9\xbf\x33\xd1\xd8\xc2\xa5\x86\x9e\x9f\x46\x60\xc3\xfb\x22\x4b\x39\x14\x1e\x31\x10\xc9\xee\x8a\xeb\x87\x1e\x14\xc6\x2c\x6b\xe3\x8f\xb9\xa4\x56\x8d\x73\x68\x10\xbb\x9d\x20\x73\x17\x8b\x6c\x7e\x87\xe3\x58\x2e\xfc\x62\xb5\x3c\x23\xc5\xd4\x65\x20\xba\x33\xff\xb3\xa9\xca\x64\x9e\xf2\x6f\xe7\x4a\x3c\xff\x61\x88\x42\x73\x26\xb8\xc9\x6f\x74\x35\x4c\xb3\xec\xaa\x61\x1b\x12\xcd\xed\x56\x5e\x59\xfe\x1f\x8f\x40\x00\x97\xe9\x3e\xa8\x59\x51\xb5\xb4\xe9\x00\x9e\xea\x7d\xb9\x37\xe4\x34\x9c\x4e\x5e\x00\xc4\x45\x6c\x6c\x5f\x4e\x57\x41\x1b\xaf\x4e\x46\xe7\x00\xac\x40\x02\x57\x76\x5f\x48\xda\xb0\x3e\x43\x9f\x76\xc1\x49\x9b\x51\x08\x04\x7c\x83\x01\x09\xdc\xe7\xf7\x40\xd1\x39\x37\x87\xe2\x9d\x37\x16\xd3\xc4\x7e\x75\x5c\xb8\x28\xe7\xd4\x40\xa9\x71\x97\x51\x97\xeb\xdb\x3f\x9b\x73\x7b\xa1\x1f\x7f\xd0\x38\x6a\x95\x92\x49\x01\x7d\xe7\x23\x4d\x5e\x5a\x9b\x47\x3b\xb9\x58\x3a\x37\x42\xc7\x74\xee\x55\x2a\x12\xa1\xf3\x6e\xb3\xf2\x6c\x88\x5b\xed\x22\xe9\x1c\x74\xcf\x32\xa8\xdd\x3e\xdb\x08\xb6\x74\xbf\x38\x6e\xf4\x27\x72\x79\x12\xd5\x7c\x5f\xaf\xaa\x1c\xfe\xb7\x40\xcd\x52\xb9\xde\xe9\x95\xe3\xd0\x16\x1c\xd9\x21\x3f\x38\xfd\x68\x1d\x53\x8a\xb8\xbf\x97\xb7\x45\xf5\x49\x80\x03\x0e\xf8\xb7\x26\x96\xd4\xe2\x74\x73\xfb\x0f\x1a\xcd\x5d\x0a\xae\x02\x97\x21\x16\x80\xea\x0f\xc5\x9d\x7b\x6d\x51\xc6\x32\x92\x58\x5a\x1d\x55\x3d\x0c\x89\x54\xb4\x2a\x4b\xd6\xfc\xd3\xa4\x95\x75\xbf\x5c\x88\x95\x3f\x1f\x4e\xa7\xfe\x0e\xd7\xa5\x79\xd1\x69\x7e\x64\x5e\x2a\x61\xc6\x9d\x1a\x56\xbc\x60\x5b\xb0\x40\x60\xa2\x77\x8d\x50\x9a\x8a\xad\xbf\x35\xd9\x46\x97\xcc\xee\x9d\x35\x43\xdd\x01\x28\x1a\x03\x1f\x2a\x0e\xb3\xa9\xeb\x13\xae\x56\xff\x44\xfa\x0a\xed\x4f\x34\x88\x74\x7d\x6a\xf8\x20\xf3\x98\x9b\x71\x33\xf4\x49\xea\x56\xd3\xa7\xf7\x31\xe7\x91\xb7\xed\x2a\x5d\xb9\x39\xbb\x75\x35\x2d\xe7\xda\xec\x50\x66\xfd\x57\x55\x71\x65\xad\xff\xa6\x31\xcd\x3f\x96\x7c\x3c\x7c\xfc\x11\xcc\x1f\x14\xfa\x23\xde\xfe\xc3\xeb\x02\x39\xb4\x5e\xd6\x01\xa3\xa8\x07\x8c\xcf\xc7\xf8\x38\x09\x02\xa8\x59\xee\x9c\xe2\xdb\x79\x5e\xfa\xca\x0a\x01\xdc\x08\x79\xd5\x06\xac\x97\xd1\x07\x04\xd7\x75\x7b\x3c\xcf\x3b\x37\xc3\x39\xb4\x2d\xb2\x37\x82\x27\x80\x23\xe4\xc2\xe7\x7d\x74\x24\x6c\x9e\x54\x41\x49\xa5\x5c\x0c\x92\x0e\xbf\x29\x86\xb4\xc5\xb4\xb3\x57\x2f\x74\x8c\x4b\x15\xc7\xf8\x63\x99\x9b\xc5\x13\x2a\xda\xd0\x97\x61\xeb\x76\x50\x50\x19\x76\x9f\xb5\x54\x22\xf6\x03\x18\x4e\x24\xc0\xd4\xf3\x76\x19\x87\xb5\xc5\x0f\xea\xfc\xce\x53\x30\x2a\x3a\x41\x5e\x20\xf5\x6a\x05\x48\x03\xe5\x53\xba\xcd\x24\x2a\x5e\x13\x64\xaa\x3b\x2d\x7c\xb3\xbc\x1e\x1b\x86\xa4\x74\x31\xcb\xd3\x96\x95\xb6\x7f\x55\x4c\x46\x45\xb7\x23\x69\x04\x09\x4c\x11\xaa\x1b\x40\x32\x6b\xa9\x1b\x8b\xf4\x87\x3e\x9a\x4d\xe0\x4e\x2b\xf4\x62\x59\x72"}, +{{0x45,0x43,0x8f,0x91,0x46,0x5d,0x74,0xa2,0x82,0x5b,0x0f,0x66,0xa3,0x5b,0xd7,0xc8,0xd0,0x05,0x86,0x54,0x79,0xb3,0xdc,0x10,0xa9,0xb5,0x6f,0x29,0x7d,0x31,0xb9,0x26,},{0xf0,0x92,0xb5,0x88,0x03,0x30,0x87,0x1e,0x5a,0xaf,0xdd,0x3c,0xeb,0x38,0x50,0xee,0x7e,0x09,0x41,0xa2,0xa1,0xdc,0x89,0xf4,0xfb,0x47,0x71,0xd7,0x5a,0x22,0xf6,0xf2,},{0xd9,0x28,0x7b,0x7f,0xec,0x01,0x7f,0x2e,0xa4,0x0a,0x14,0xa1,0xf6,0x2d,0xca,0x78,0xb0,0x2a,0x3d,0x66,0x32,0xdf,0x7c,0x60,0xeb,0xd9,0x0f,0xc5,0xe4,0x92,0xc5,0xc6,0x2c,0x43,0x16,0x6b,0xf8,0x56,0x58,0xfb,0x30,0xa0,0x8b,0x57,0xa5,0x81,0x31,0x21,0xb8,0x03,0x97,0x57,0x1a,0x31,0x2b,0x6d,0xd1,0x1b,0x65,0x39,0x20,0x54,0x16,0x02,},"\x30\x71\xd4\xb7\x20\xdf\x10\x93\x65\x99\x67\xcd\x4e\xef\xef\x2e\xf9\x67\x84\x75\xf7\xde\xc5\x8f\xec\xec\x1d\x92\x8d\xea\xf8\x02\x45\x7a\x19\x34\xe6\x04\x55\xf4\x96\xcf\x42\x51\x82\x0e\xd6\x0a\x3d\x81\x33\xb6\x24\xd3\x3a\xf2\x6a\x26\x27\x84\xb5\xa2\xfb\xa7\x3c\xca\x2a\xa5\xe5\x19\xe1\xf5\x39\x58\x47\x80\x64\x98\x64\xba\x5f\xbc\x1f\x01\x1d\xdd\xac\x38\x1f\x8d\x48\xd0\xd6\x0c\xe8\x23\x17\x01\x17\x3c\x9d\x2a\x30\x7a\x76\x30\x2e\xbc\x69\xdc\xbc\x93\x0d\x28\x43\x14\x75\xb5\x16\xf9\x8f\x77\x8e\xd2\xe1\xff\xf2\x72\x90\x9a\x27\x2c\xc3\xfb\xb6\xb3\x1c\x80\x41\xa3\x7c\xb7\x77\xe0\x62\xe4\x96\x49\xaf\xad\x12\xc1\xb5\xf7\xfc\xb8\x06\x5a\x99\xe7\x42\x33\x62\xad\x16\x90\x60\x31\x26\x5d\xb7\xe8\xb8\x97\x51\xf8\xa4\xa4\x07\xf2\x50\x26\x50\xfe\xd7\x53\xe4\x2c\x8c\x91\x1e\x50\xb9\x4b\x38\x00\x69\x5b\x0e\xba\x7d\xff\x06\xb7\xa7\x10\x11\x7e\x49\x20\xd4\xb1\xc6\x05\xa3\xeb\xf3\x2e\x06\x96\x67\x16\xed\xa1\x4b\x30\x42\x99\x8a\x3c\x7a\x5e\x9f\x83\x54\x2d\x7d\xde\x65\xe5\x28\xbe\xd6\x10\x1d\xeb\x33\x1d\xeb\x94\xcd\xd4\x60\x44\xbe\xf8\x8c\x09\x7b\xaf\xd4\x0d\x69\x21\xa7\xc4\x84\xc8\xf9\x66\x84\xdc\x37\x16\x71\xd9\x4e\xee\x7c\xbe\x5d\x58\x77\x15\x31\x4c\xff\x0d\x18\x77\x27\x2d\x81\x90\xa9\x0e\x18\xbf\xb3\x21\xd5\x2b\xf7\x47\x05\x13\x7b\x2a\xbf\x91\x65\x73\x17\x67\xa1\x3a\xdc\x9c\x85\xe0\x39\x7b\x47\xae\xf9\x6b\xad\xb2\xca\x7f\xcb\x82\x93\xb0\x1f\xd1\xde\x31\x6e\xe1\xe6\x5f\x35\x6b\x9d\x6e\x8e\xa1\xfd\xd8\x37\xbd\x96\x08\x11\x49\xea\x2d\xcd\x73\xc4\x88\x1f\x32\xb7\xde\xeb\xc3\x71\x5e\x2d\x7c\xdb\x64\x3e\x0d\x98\xf4\xe8\x46\x50\x8b\x04\xb3\x24\x39\xff\x14\xb1\x16\x4f\x46\x84\x6d\xf9\xaf\xae\x44\x46\x4c\xf5\x50\x10\x4c\xd3\xaa\xb3\x81\x75\x40\x47\x0a\xaa\x2a\xb9\x55\x9a\x68\xb7\xff\x6b\x1b\x9c\x0c\xe9\xf5\x86\x9c\xbd\xcd\xd6\x17\x09\x09\x42\xe3\x53\xb4\xc7\x7f\x09\x39\x58\x96\xbe\xcd\xdf\xf1\xab\x7f\x07\x58\x6a\x51\x4d\x81\xfb\x09\x63\x61\x55\x75\x66\x87\x0f\x16\x91\x98\x34\x85\xa8\x0c\x34\x13\xda\x98\xb8\xd1\x9c\x78\xe6\x37\x9f\x94\x3e\x5b\xd5\xa5\x69\x7a\xa3\x3c\x5e\x6b\xfc\xfb\x7b\x8d\xf1\xe1\x57\x4e\xe4\x16\xfa\xb3\xc8\xa7\xd0\x88\xb3\xa0\x57\xcf\x86\x53\x21\xb7\x4e\x61\x03\x52\x6d\xd9\xad\x15\xca\x5a\xd3\xc0\xf6\x97\x18\xe2\x70\x81\xd4\xb3\x4a\x7c\x6d\x1a\xab\x6b\x96\xc0\xa7\x54\xb9\x89\xb4\x94\x06\x38\xc9\xed\xe3\xd1\x7b\xd4\x9f\x65\xbf\x78\x3d\xc8\x5f\x1c\x4b\x14\x48\x76\xcd\xbd\xb2\x28\x2a\x95\x64\xaa\x81\xb5\x70\x92\x08\x0d\x64\x48\xfb\x65\x80\xec\xf0\x9f\x82\xa7\x55\x01\x0d\x55\xd4\xa5\xe4\xf3\x05\xe2\x59\xdb\xe9\x95\x08\xb4\x79\x25\x0d\x80\xec\x17\xc8\x76\x0a\x93\xe0\x5a\x29\x57\x1f\x68\x56\x07\x30\x22\xc8\x70\x69\x13\xc4\x6a\x2e\xfd\x2e\x9c\xaa\xe4\xff\xa1\xb4\x22\x2e\x3d\x70\xe9\x79\xe8\x1a\x71\x95\x1d\x7c\xb8\x30\xbc\xbc\xf9\x01\xaf\x24\x4f\x64\xe4\xad\x9f\x52\xfa\x3b\x62\x03\x1e\x35\x16\xda\x50\xbc\x2b\xce\x78\xeb\x9d\x61\xbf\xed\xd9\xb3\xf5\x7e\x89\x35\x5f\x17\x7d\xb6\x16\x2b\xf6\x1d\xa0\xe4\x54\xc3\x42\x88\xb9\x67\xc3\xfb\x4c\x34\x1b\x32\xd4\xd1\x3a\x31\x98\x69\xb8\xe3\x60\x46\xf9\xe3\x38\xb5\xf3\x6a\x1f\xc1\xa7\xed\xa7\xd7\xb0\xd4\x38\xe0\xa7\x5d\x84\xbb\xe4\xd6\x8c\x87\x9a\xda\x80\xdd\xe2\x3f\x71\x55\xb5\x32\xcc\xcf\x7a\x63\xf1\xbe\xdf\x84\xf8\x2f\x44\x0c\x9e\xc3\xcb\x0e\x45\xf3\x2c\x92\xf7\x64\x38\xf5\xb4\xb9\x10\x44\x1e\x67\x38\xaf\x3f\x5d\x20\x50\xd5\x79\xee\x96\xb8\x8f\x3b\x00\x81\x0a\xb1\x26\xff\x3a\x8f\xef\xd9\x71\x04\x43\x24\xdd\x4e\xb3\x44\x7d\xac\x5b\x77\x80\x9c\xda\x8c\x71\x68\x25\x49\xd7\xcf\x2d\xce\xe3\x40\xed\xcf\x94\x94\xac\xa4\x29\x01\xe2\xc1\x1e\xd9\x77\x90\xaf\x48\xbc\xea\x29\x52\x1e\xf0\xe3\xd0\x3c\xda\xde\xcd\xc8\x94\xdd\x07\x56"}, +{{0x72,0xcf,0xce,0xf4,0xc9,0xd6,0xa1,0x98,0x6d,0x19,0x03,0x11,0x84,0x0e,0x55,0xcb,0xaf,0xac,0xc8,0xa6,0xeb,0x5e,0xcc,0x72,0x93,0x4f,0xda,0x53,0x5b,0xdc,0xff,0xb2,},{0xa9,0x44,0x64,0xd8,0xcc,0x8f,0x3e,0x43,0x39,0x39,0x47,0x64,0x9f,0x91,0xc2,0x75,0x23,0x27,0xe4,0x0d,0xac,0xa1,0x1a,0x99,0x70,0xc5,0x18,0x1e,0xda,0x37,0xd6,0x06,},{0xdb,0x72,0x70,0xac,0xce,0x78,0xd7,0xfb,0x09,0x08,0x0a,0x32,0x79,0x41,0xbc,0xe7,0xeb,0x14,0x5b,0x9e,0x36,0x61,0x86,0x6a,0x86,0x83,0xf9,0xa1,0xa3,0xde,0x97,0xfb,0x02,0xb0,0x25,0xdb,0x9e,0xc7,0x6f,0xf3,0x25,0x60,0xfe,0x63,0x88,0x27,0x74,0x2e,0xa2,0xf4,0xeb,0xef,0x6b,0x7c,0xce,0x44,0xf9,0xaa,0xee,0x43,0x4f,0xd7,0xc1,0x08,},"\x66\xa6\xcb\xe8\x8a\x8a\xb9\xa3\x38\x47\x79\x7f\xc4\x80\xb2\x44\xe8\xa2\xb8\xec\x79\xe8\x0b\xc2\x63\x77\x53\xde\xb3\x6f\xa3\x01\x4f\x84\x3e\x22\xa4\x7d\xb0\xa3\x17\x78\x38\x5e\xc1\xf4\x55\x67\x2e\x0d\xff\x6c\xa2\x1c\xa4\xcf\xd2\xb9\x89\x47\x1b\x7f\xfc\x30\x78\x28\x13\x8b\x0a\xd4\xe6\x47\xc2\xd1\x3c\xef\x72\x44\x69\x05\x4a\xbd\x37\x40\x24\x5a\xea\x4b\x78\x9e\x24\x4e\x95\xcf\x9e\xcf\xd0\x8a\x0d\x13\xc7\xce\xd3\x93\x33\x27\x27\xa7\xf3\xd8\xfb\xda\xbd\x93\x9d\xe2\x8c\xaa\x41\xcc\x96\xc7\x08\x11\x98\xe2\x26\x53\xd9\x4e\x02\x4a\x61\xf5\xf3\xdc\x5a\xa3\x7f\xa9\xad\xdd\xc9\x6c\xf1\x69\xd3\x50\x62\xa0\xa2\x9b\xa4\x5a\x53\x9c\x87\xa6\x8a\x3a\x03\x04\x36\x13\x09\xd2\x13\xe6\x14\xee\x83\x73\xda\xfb\xa2\xa7\xd6\xed\x7d\x2a\xd3\x77\x04\xc0\x94\x6e\x4d\x09\x3e\x2d\x94\xd0\x61\x36\x4c\xc1\x23\x10\x63\x72\x91\x03\xa7\x7c\xcb\x50\x18\x91\xbb\xc3\x18\x54\x57\xbb\xd2\x86\x9e\xb6\x3d\xc6\x0f\x19\x6f\x10\xa3\x8b\x7b\x36\xcb\x3f\x64\x3d\x35\xdd\xbf\x43\x8a\x44\xbf\x0c\x8f\x57\x0f\xad\x41\xbd\xde\x26\x7f\x0f\xfc\xf1\xf2\xf9\x27\xd6\x26\xd1\xb0\xd9\x80\xa0\xce\x22\x3f\x2f\x00\x54\x84\x5a\xfe\x41\xd3\x9d\xe5\xa4\x57\x21\x9f\x27\x6c\x67\xe6\x9b\xe2\xd5\xc9\xe0\x70\x13\x16\x39\x56\x1c\x26\x75\x1f\xb0\x64\x35\xe0\xe4\x2e\x25\x08\xc5\xf4\x9c\xd1\x2b\x51\x7c\x98\x33\xff\x97\xf5\xe5\x1e\x1d\xce\xaf\xa9\x42\x6d\x3d\xc5\x2f\xd1\x37\x9c\x64\xcc\xaa\xbb\x26\xdb\x1a\xf6\xde\xd7\x15\x36\x28\x84\x2f\x0c\xbd\xbb\xbd\x6a\xa0\xcf\xa5\x40\x7f\x40\x94\x96\xc0\x65\x32\xdb\xea\xc9\x4d\xab\x9b\xab\xa0\xb3\xc9\x88\xfa\x03\xd3\x6f\x91\x1d\x80\xe4\x9b\x37\x0b\x68\x37\x03\x7f\xf2\x49\xe7\x6d\x69\x2c\xd1\x77\x37\xe0\xd0\x79\x65\xd3\x3f\x17\x04\x2b\xbc\xd1\xe9\x90\xe0\x40\xf7\x19\x36\xf6\xfc\xa2\x54\x2a\xe3\x37\x48\x36\x77\x87\xc0\x1b\xde\xa7\x5c\x9a\x0e\x66\x15\x02\x81\xc4\x68\xfe\x5c\x73\xaf\x9e\x5b\xec\x37\x2d\x50\x20\xc3\xd3\x7f\xa1\x03\x5a\x67\xe2\x24\xd0\x95\xf0\x66\xa5\x1f\xe1\xf6\x81\xc3\x07\x39\x39\x27\x2f\x6a\xf7\x75\x0e\xd8\xd1\x83\x49\x17\x8a\xb4\xa2\xee\xb4\xe9\xca\x82\xbb\x67\x29\x6e\x98\x90\xf3\x16\xc9\xd9\x49\x59\x53\xd6\x84\x36\xeb\x1c\x1a\x2f\xb6\xa1\xcc\xa4\x5a\x8e\x88\xa0\x9b\xdd\x65\xa5\x55\x80\x25\x61\x8b\x36\xd7\xf3\xcb\x38\x9d\x2e\x2a\xb1\xed\x23\x32\x28\xec\x92\xa3\x27\x97\x8c\x0a\xdc\xed\xdb\x6c\x96\x32\xd3\xab\xd7\x97\x16\x21\x71\x37\x54\x75\x8e\x21\x01\x3a\x0c\x3d\x00\x9b\x6e\x31\x93\xcc\x15\x2c\x57\xef\x73\x10\x7b\xd4\x35\x7d\x52\x8b\xe4\x08\x73\x02\x7b\xf1\x84\x0f\x68\x55\x36\x08\x0f\x12\xc5\xff\xa9\x3c\xa6\x29\x73\x67\x80\xe0\x15\xe8\x6d\x19\x09\xf0\xd8\xf3\x72\x01\x0c\x9c\xb7\x2c\x09\x89\x84\x5f\xc8\x83\x15\xe6\xb9\x37\x0d\xc9\x2d\x36\x83\xef\x44\xd3\xf7\x5f\xc9\x6c\x4b\x0e\x89\xe1\x3d\x68\x2d\x19\x88\xb6\x85\x71\x3e\xad\xa8\x42\xbe\x9d\x2b\xbe\x2a\x76\xbb\xa1\x5d\x38\xcb\xaf\xb6\x5c\x40\xc2\x15\x9b\x0c\xee\xb0\xd7\x69\xb9\xbe\x35\x55\x40\x73\x4f\xf3\x77\x36\xc0\xf0\xfa\xcb\x95\x15\x93\x09\x36\x5b\x96\x46\xbc\x4b\x34\x4f\xb1\x9a\x5c\x16\x39\xa8\x8e\x87\x31\x7b\xfb\x3b\x5e\x7b\x51\x30\xfa\x7d\x56\x43\xed\x4d\xa0\x64\x30\xc8\xa0\xc1\x85\x8c\xcf\x2f\x9a\x6e\x3d\x62\x01\x22\x53\xf0\x12\x2d\xba\xb4\xa3\x54\x75\xa6\xf6\x55\x89\xb2\xb0\x95\x99\x28\x26\xe4\xf1\xb5\x8f\xa0\x50\xb8\xf9\x5c\x4f\xeb\xa3\xfb\xaa\xdd\x2c\x22\x44\xad\x4a\xbd\x41\x01\x39\xad\xf4\xc1\x53\xcb\x5e\x69\x33\x7a\xf1\x76\xa7\x83\x7e\xea\xea\x99\xbd\xcd\x59\x38\x5a\xfd\xed\x34\xff\xba\x80\x63\xa3\x5f\x4f\x55\x8e\x4e\xeb\x48\xf1\x48\x7b\x56\xb1\xf8\xd1\xf7\x30\x67\x62\x1c\xb5\x48\xc8\x08\x75\x3e\x35\x26\xa2\xf2\xaa\xbd\xe1\x26\xbe\xa5\x21\xcf\x67\x3d\xea\xfa\x79\x2c\xa5\xbd\x22\x12\x79\x5b\xd6\x6b\x86"}, +{{0xa6,0x33,0x7e,0x4d,0x3b,0x1a,0x49,0xb1,0x26,0x31,0x67,0x78,0xc6,0x13,0x51,0x6c,0x03,0xac,0x88,0xc9,0x6d,0x92,0xff,0x5c,0xc7,0xe0,0xc8,0x52,0x7c,0xce,0x1a,0x62,},{0xf5,0xea,0xc4,0xfe,0x0e,0xa1,0xa5,0xf2,0x36,0xb4,0x9d,0xa3,0x3a,0x24,0xe2,0xf3,0xa8,0x3d,0x4b,0x26,0x0c,0x54,0xd3,0x41,0x6c,0x64,0x4e,0x05,0xc8,0x38,0xbf,0x51,},{0x78,0x13,0x76,0xc9,0x51,0x2f,0xa3,0x3c,0x45,0x70,0x47,0xa1,0xf4,0xf0,0xda,0x31,0x76,0xe6,0x0e,0xe4,0x77,0x82,0x86,0x9b,0x7e,0x9f,0xa5,0x84,0x1d,0x96,0x4f,0x3c,0x1a,0xd6,0x6b,0x70,0xc1,0x14,0xb1,0x77,0x1c,0x32,0x4c,0x83,0xff,0x6c,0xd9,0x97,0xae,0xfc,0xcd,0xc5,0x9c,0x11,0x4d,0xb9,0xf2,0xf3,0xca,0x7d,0x84,0xa7,0xb6,0x0f,},"\xe3\x34\x30\xc3\x8c\x4a\x40\xb3\xc6\x6e\x20\xcf\x3b\x70\xe9\xfe\xa8\xcc\x50\x76\x1f\x2a\xfe\x24\x9e\xc0\x59\xc0\x7b\xc3\xb3\x7e\x5b\x94\xf4\xa4\x3e\x31\x00\x99\xb1\x9a\x85\xf5\x9d\xff\x73\xa7\xe4\x95\xc4\xdf\x31\xf7\x47\x80\xcd\xef\x7b\xd6\xe4\x7c\x39\x4c\x18\x91\xea\x30\x52\xe3\xcc\xf5\xd8\x4b\xae\x08\x2d\x24\xba\x71\x78\xac\x65\xd2\x29\xad\x18\xa8\x49\x40\xf6\xb4\xdb\xc5\x96\xee\x63\xc1\x81\xb5\x7b\x5b\x49\x69\x89\x79\xc1\x86\x32\xfa\x82\x1c\xa6\x1e\x35\xa0\xd0\x35\x1f\xe1\x3d\x69\xe0\x6d\xdc\xc8\xd6\x66\xdc\xa2\x45\x02\x17\x7f\x34\x4e\x2f\x44\x05\x75\xd3\x9e\xbf\xe5\xe7\xf1\x06\x53\xb6\x5b\xef\x29\x1d\xc8\x13\xa0\x43\x4c\x97\x5d\xe1\x64\xc1\xa7\x6b\xf6\xfc\xef\x98\xf2\x31\x81\xc0\x09\xb9\x18\x30\xb6\x18\xe4\x87\x48\x47\xd2\xe2\x1b\xbd\xb9\x3f\x20\xcd\x8b\x1f\x4b\xaa\xdf\x99\x42\x8a\x22\x67\x43\x86\xa6\x68\x15\x2b\x4b\x90\x39\xff\x06\xab\xcf\xe3\x34\xa0\x62\xf7\x94\x05\x61\x72\xec\xbc\x07\x94\xdf\x98\x27\x1b\x9a\xcf\xe4\xb7\xda\x55\x3a\x87\x63\x42\x37\x63\x00\x09\xa0\x5b\x25\x7c\x18\x4c\xbe\x23\xd9\xcd\x5a\x03\x86\x58\x01\x0f\x57\x48\x99\xf3\xb2\xd1\x54\xd1\x85\xee\x67\x23\x09\x13\x65\x0c\x3a\x05\xb5\x4a\x2e\xdc\x24\x3a\x42\x87\x39\x8e\x37\x69\x28\xea\x9c\x6b\x2c\xba\xf3\x71\x25\x25\x40\xe2\xb8\x04\x3f\xcf\x55\x68\x13\x19\x6a\xe5\x72\xc2\x7c\xfb\x5a\x46\xab\xb9\x72\x9a\xf2\xdc\xfc\x29\xe0\x33\xdd\x11\xf3\x3e\x86\xcc\x6a\xc3\xbc\xe6\xf3\xf9\x57\x7d\x36\x78\x1a\x69\xed\x7e\xaf\x8c\x82\x63\xa0\xf1\x8e\xba\x0f\xe8\xa4\x81\xf3\xe1\x5a\x55\x59\x94\x34\x19\x5f\x7c\xb0\x57\xdd\x36\x4e\xaa\x07\xdd\x0d\xfd\x26\x6b\x80\x7f\x53\xa2\x07\x0f\xd7\x91\xe8\x72\x42\x2f\xd9\x07\x13\x4f\x4a\x8a\x78\xa8\x76\xbd\xcb\x03\x1a\xc8\x60\xdf\xe0\xbb\x57\xe1\x05\xdb\x82\x87\xb3\x1a\x60\x4e\xb7\x12\x69\xbe\x5b\xa2\x29\x98\x5c\xea\xbc\x2b\xdf\x16\x5a\xc7\x41\x65\x0b\x1f\x01\x3a\x66\xc9\xbd\x24\x3d\x03\xa8\xb1\xc5\x08\x13\x81\xcb\x92\xe2\x3f\x90\x57\x77\x1f\xc0\x7c\xa3\x2d\xff\x1d\xb9\x4f\x5a\xdf\xd2\xf4\xff\x9a\xf3\x1d\x25\x0d\xd4\xf8\x6b\x22\x59\x2f\x60\xa7\x45\x75\x15\x62\x13\xf1\x08\x46\xc7\x46\xa9\x20\xfe\x39\x85\x1b\x32\xfe\x4c\x8b\x87\x58\x76\x5b\xc5\xb8\xb9\xd5\xb9\x92\x63\xdf\x36\xf9\x78\x88\x05\x3f\xd1\x0f\x1d\x68\xf5\x77\xae\xd5\x59\xbc\xfd\xe7\x44\xbc\x65\x11\x07\x6c\xaf\xd6\x89\x44\xa0\xed\x10\x55\x2d\x11\x34\x4b\xc7\xe4\xd9\xef\x93\x6d\xac\xce\xd5\x27\x43\x31\x32\x95\x9b\x1c\x73\x24\xad\x1c\x4c\xbc\x3a\x1a\x73\x6b\x1f\x02\xaa\xe8\xe0\x61\x1a\xe2\x3f\xdd\x47\x4f\x5b\x8e\xe7\x05\x6f\xcb\x5a\xf6\x13\x3e\xcc\x08\x4b\xb9\xf1\xf5\x0c\xbd\xac\x66\x24\x44\x37\xb4\x34\x8f\x4e\xdf\xe2\x37\xfc\x3c\x38\x29\xab\x94\xeb\x4f\x14\xca\xb1\xcc\xd6\xca\xee\x36\xfa\xdc\x20\xa3\x10\xcf\x06\x90\x62\x2c\xdc\xa8\x48\xae\xd0\x3f\xf4\x03\xa6\x63\x3f\x4f\x65\x79\x94\xb7\x80\xdd\x60\x48\x14\x9c\x3b\xfb\xc1\x78\x89\xe3\x7d\x90\xb1\xe5\x42\x0e\xb3\xd4\x59\x6b\x91\xba\x11\xbc\x02\x29\xc6\x5d\x05\xb9\x3c\xd7\xe0\x45\x4d\x1f\x3c\x6e\x1e\x80\x71\x98\x37\x92\xc4\xd4\x36\x8d\x07\x78\xae\xf4\xe1\x23\x33\x5f\xd2\x96\x2c\x65\x7b\xd0\x51\x35\x71\xa5\xfc\xe2\x11\xde\x62\x87\x4f\x27\xca\x10\xdc\x15\xba\x2d\x44\x5f\x1c\xf4\xbe\x5f\x83\x3c\xf0\xb5\x64\xc0\x22\x57\x6b\x98\xc0\xa2\x43\x49\xb6\x70\x85\xf9\x22\x02\x67\x5d\x7d\xac\x48\xb9\x5e\x3b\xfd\x65\x55\xa9\xec\xb7\xc7\x2f\x08\xbf\xec\x0d\x22\x02\x22\x49\x2f\xdc\x96\x36\xf0\x36\xec\x45\x08\xa3\x65\xb7\xb7\x09\x79\xf9\xeb\x4a\x72\x63\xa8\xba\xcb\x1c\x1d\x01\x55\x73\x86\x46\xcd\xd4\x6a\xb9\x23\x4a\x17\x03\x11\x50\x0d\x0b\xae\x6e\x55\xa8\x63\xbd\xaa\x56\xf5\x16\x45\xad\x85\x29\x7a\x73\x81\xf8\xd2\x0c\xf9\x6c\x47\x4d\x1b\xb8\x1f\xce\x13\x2b\x14\x55\x5d\x1a"}, +{{0x10,0x7d,0xa9,0x8d,0x0e,0xe8,0xe7,0xc0,0x0f,0x6d,0x41,0xec,0x26,0x59,0x44,0xce,0x67,0xef,0x8c,0x8f,0xfb,0x51,0xf4,0xf1,0x1f,0x4e,0x5f,0x1a,0x27,0xfb,0xe8,0x05,},{0x3b,0xec,0x34,0xb1,0x61,0xb1,0xbc,0xff,0x00,0x9f,0x8c,0xfc,0x50,0xd8,0x4c,0xeb,0x6a,0x2d,0x5b,0x20,0x3b,0x52,0x38,0xa8,0xaa,0xd8,0xa8,0x36,0x18,0xb4,0x42,0xe7,},{0x53,0x25,0x2b,0x92,0x3a,0xd1,0x9c,0xc3,0x97,0x84,0xd3,0xa9,0xae,0x59,0xd6,0x2a,0x63,0x00,0xdc,0xc5,0x0a,0xc8,0xfd,0x07,0x13,0xcb,0x58,0x84,0x45,0x01,0xd8,0xd3,0x80,0x5a,0xfa,0x0f,0xda,0x64,0xc7,0x3e,0xa0,0xf6,0x0e,0x6a,0x8b,0x34,0x45,0xbf,0xff,0xe6,0xca,0x6b,0xfd,0xc8,0x7e,0x12,0x8b,0xaf,0x99,0xbf,0x62,0x68,0xfc,0x09,},"\x1a\x7b\x7f\x3e\x1c\x7c\x41\x49\x2a\x7c\xe7\x99\xef\xdb\x2d\x9d\xc2\xf2\x48\x9c\x84\xae\x28\xbb\x7d\x08\x4f\x32\xec\xa8\xfb\xb0\x66\x88\x5a\xc6\xf2\xef\x74\x49\xe7\x12\x26\xa8\x2e\x9f\x15\x37\x72\xa9\x93\xeb\x6b\x6b\xca\x64\x91\xd2\x6a\xca\x5d\xee\x98\xb7\x7a\x1d\xdc\x59\x92\x2b\x31\x45\xc4\x47\xde\x73\x7f\xaf\xac\xba\x5a\x75\xf2\xa8\x01\x37\xb5\x59\x46\x97\x22\x0d\x19\x61\x76\x74\xa6\x91\x13\xfd\xf7\x7c\x34\x3a\xf2\xb7\xe3\x86\x1b\x5b\x78\x22\xf5\x8d\x60\x08\x9c\x3c\xa5\x4c\x74\x9d\x27\xf8\x83\x79\xc0\x67\x59\x8f\x06\x39\x39\xba\x86\x31\xd1\xf5\x2d\xc9\xab\x45\x50\x45\xfb\x36\x0c\xc2\xa5\xb6\xb0\x12\x7f\xac\xfc\xf5\xb1\xb4\xc3\x3e\x3f\x19\x4f\xc9\x24\xb8\x54\x16\x8c\xb1\x16\x9a\xb1\x09\x97\xb4\x38\xb7\x1c\x80\x87\x83\x47\xbe\x88\x7a\xf4\x48\x10\x13\x4b\x51\x4c\x80\x69\x08\x20\x1a\x3d\x3e\x6d\x0c\x56\x12\x0c\x43\x14\x87\x4d\xc2\x94\x4d\x84\x44\xf0\x1b\xaf\xa3\x4a\xa6\x2e\xce\xf0\x98\x15\x45\xe5\xd0\x2f\x40\x16\xc0\xb1\x64\xfc\x05\xae\x18\xf5\x35\xc3\x1b\xf2\x0b\x86\xf3\x1f\x7a\x79\x4a\xba\x14\x89\x84\xc3\xff\x43\x3d\xc2\x22\xc4\x43\xb5\xd2\x6c\x1f\x66\xe6\xc5\xf1\x9d\x19\xcd\x6e\xad\xd4\xdc\x94\x10\x1b\x2f\x52\xb5\x8c\x9d\x45\x90\xcb\x10\xdb\xc5\xd6\xea\xcd\x11\xd4\x2e\xd0\x9f\x15\xbd\xe4\x4e\xe9\x27\x1d\xef\x29\x2f\x73\x1b\xf3\xb4\xac\x6c\xd1\x27\xe4\x88\x4c\x2c\xb3\x0b\x28\x5f\xc9\x24\x76\x38\xa2\x99\xe4\x16\x52\x06\x24\xd1\xec\x8d\x0d\xf2\x49\x89\x39\xc7\x19\xa9\xe7\xbd\x29\xa3\xc5\xc3\x2a\x3e\x82\x41\x36\x8d\x6e\x4f\x90\xfe\xa2\x9d\xc3\xa3\xf1\x47\xea\x9f\x76\xc5\x78\x0e\x73\x14\x3f\x55\xd3\xde\xc7\xb6\x63\x41\xd3\xf3\xea\xc1\xd9\x8f\x8e\x7d\x4e\x87\x75\x09\xb4\x43\x8c\x3a\x52\x46\x6d\x24\x2a\x10\xb4\xc2\x7c\x4a\x0d\xb9\x23\x2d\xad\x01\x14\x14\xeb\xfb\xd5\x79\x06\xf1\xa4\x10\x20\x7b\x52\x6b\x0d\x1f\x1b\x69\x86\xb3\xeb\xd7\x55\x0a\x2b\x3c\x15\xfc\x24\x09\xc7\x62\x6e\x0d\xd3\x30\xef\x67\x22\xe3\xba\x48\xb1\xd9\x20\x56\x52\xac\x19\x4c\x21\x47\x3c\xe2\x58\x55\x9d\xb5\x11\xef\xad\x3e\x5d\x55\xf2\xa7\x96\xd6\x5a\x6a\xb9\x7d\x86\x31\x06\x2a\x59\x3a\x13\xaa\xa0\x95\xdb\xc9\x3e\x62\x17\xce\xd6\x19\xcb\x16\xa5\x7e\x74\x43\x55\xa1\x6b\x15\xe7\x7d\x49\x79\x11\x92\x99\xbb\x04\x3e\x48\xfa\x3e\x61\x54\x60\xe1\x64\x88\x29\x84\xa2\x23\xd4\x18\xca\x95\x34\x0c\x5b\xfc\xda\x67\x3f\xcd\x13\xb2\x9f\x2c\x47\xd2\xf9\x7e\x3e\x8c\x61\x3b\x6c\x58\xdf\x0e\x62\xcf\x23\x06\x1d\x6f\x54\x5b\x75\x50\x33\xfd\x3d\xc1\x40\x5e\x5f\xef\x35\xa1\x3e\x01\x5f\x98\xb1\xcc\x42\xf7\x1b\x99\x68\x1f\x96\x81\x25\x82\x29\xa4\x47\x3d\x86\xea\xbb\x0c\x17\x92\x79\x41\xe5\x0c\x08\xf3\x4a\x76\xb4\x3b\xcc\x6d\x04\x2e\x56\x32\xef\x9c\xcc\x91\xb6\xe6\x95\x0f\x5d\x30\xf6\x70\xfb\x39\x02\xc3\xd4\x09\x31\x5a\x40\xb0\x82\x1c\xe8\xa9\x9a\x97\xfe\xca\x54\x78\xbf\xd7\x82\xe7\x87\x67\xb3\x11\xf3\x74\x16\x3f\x58\x96\xb0\xbe\xb9\x58\x38\xe6\x45\x87\x8c\x64\x99\x03\x85\x12\x3b\x61\x57\x5d\xd8\x42\xdc\x76\x35\x4b\xac\x9c\x6d\x5a\xcd\x99\x35\xb6\x09\xbc\xcc\xb8\x46\x3d\x39\x22\x5d\xa1\xaf\xb8\x91\x1d\x36\xe6\x09\x89\x2d\xd1\x72\x38\x52\xab\x9f\x82\x75\x8f\x3f\x1e\x4d\x28\xdc\xf0\x2c\xb0\x6e\xed\x26\x84\x4a\xae\x68\x82\xed\x44\xbc\xe4\x4a\xbc\xd1\xdf\xba\x63\x34\x18\xc9\xf1\x55\x87\x9c\x97\xab\x27\xf8\xae\x23\x83\x30\x39\x2b\xe5\x49\x1a\x07\x86\x62\xda\xaa\x02\xa3\xd5\x45\x8b\x77\xc5\x49\xc4\x9b\xe2\x01\x24\x5e\x7a\xae\xc0\xd9\x4e\x54\x37\xbe\xca\x6e\x5a\xb0\x46\xd6\x94\xe9\x6b\xf5\x1e\x04\xfb\x44\x37\x9b\x2b\x9b\x80\x16\x75\xfe\x14\x77\xf3\xe0\x89\x87\x4a\x60\x11\x71\xd8\xb6\x8f\x02\x02\x01\x46\x01\xa5\x3f\x81\x2f\x53\xe5\x81\xc3\xb9\x63\x12\xb3\x6b\x9e\xe0\x4f\xff\x11\xd9\xea\xb4\xe4\x51\x48\xdc\xc8\xf0\xfa\xb1"}, +{{0x8b,0xc2,0x29,0xfc,0x23,0x46,0x53,0xb1,0x3c,0x92,0x47,0x10,0xcb,0x46,0x8b,0x8f,0xa9,0xb2,0x80,0xe2,0xad,0xb4,0x9c,0xb4,0xb3,0x6b,0xf5,0x9d,0x6f,0xa4,0xa6,0x39,},{0x46,0x14,0x69,0x75,0xdf,0x67,0x04,0xcb,0xf4,0x53,0x20,0xa5,0xe6,0xcb,0x6d,0xe8,0x13,0x46,0x9f,0x31,0x31,0xe6,0x1d,0x44,0x7b,0xbc,0xa1,0xa4,0x77,0xa0,0xc5,0x57,},{0xd2,0x43,0xb8,0x7d,0x13,0x97,0xd5,0x94,0x13,0x9d,0x83,0xc3,0x9a,0xcf,0x85,0x01,0xd0,0x73,0xbd,0x4b,0xe7,0x18,0xb4,0xc2,0x06,0x98,0x07,0x29,0xe7,0x20,0xa4,0xc5,0xb0,0xea,0x91,0xa2,0x8e,0xa1,0x26,0x04,0xa9,0x87,0xe6,0x95,0x91,0xc5,0x43,0x04,0x9f,0x29,0x73,0xbb,0x91,0xc1,0x70,0x21,0x3c,0x32,0xa6,0x4a,0x0f,0xac,0x82,0x04,},"\xba\xe2\xdc\x7f\x94\xab\x5c\xcd\xca\xa8\xcf\x49\xed\xbe\xf0\xf6\xd7\xae\xb1\xfa\x89\x07\x80\x05\x33\xaf\x44\x92\x61\x11\x94\xe5\x6c\xef\x37\xb1\xf0\x33\x30\x37\x38\xae\x2c\x3b\xc4\x58\x8f\x5c\xb3\xd5\x5f\x34\x5b\x9a\x40\x7e\x78\x77\x42\xa0\x6a\xf0\xb6\xee\x20\xde\xe3\xdf\xe9\xc9\x1d\x76\x2a\x3e\xbd\x19\xae\xd0\x79\x07\xbb\xb9\x1c\xd7\x76\x32\x65\x40\xde\xd9\xf7\xff\x7d\xda\x76\x61\x5f\x97\x8e\x94\x90\xf4\x06\xed\x2d\x91\x16\xe2\x09\x3f\xa7\x85\xe9\x71\xb5\x06\x2d\x31\xcb\x40\xff\xf9\xe3\xc5\x51\xa7\x3b\x20\x24\x5d\x46\xdf\x4d\x7f\xd1\x30\x3a\x28\x18\x01\x72\xd9\xa2\xbf\x55\x93\xc4\x79\x17\xb5\x86\x90\x91\x7c\x1f\xb0\xe1\xe2\x99\x4d\x1f\xa9\x77\x35\xae\x37\x8d\xe6\xea\xfd\x5c\x1a\x25\xab\xaf\xa3\xcf\xd2\xdf\x7a\xea\xbd\x6e\x68\xfc\x44\xed\xf8\x2f\xc8\x36\x94\xe5\xd8\x41\xa1\x5b\x14\x56\x8b\x61\x10\xbe\x64\x4b\xf2\x2b\x71\xfc\x47\xd7\xf0\x7e\x16\x66\x95\x7d\x0f\x87\xda\x17\xf1\x3f\xcd\x63\xc1\xc2\x96\x6f\x68\x7d\x25\xdc\xbd\x99\x63\xf0\x1e\xff\x13\x2d\x5f\x2b\x86\x67\x78\x16\x58\x8c\x12\x3e\x94\x57\xbe\xfc\xce\xd2\xd3\xcd\x1d\x1b\xeb\xe8\xdd\x8f\xbb\x15\x87\xe5\x53\xcb\xcc\x4c\x87\x62\x06\x4c\xd3\x2e\xf7\xa1\x70\x24\x10\xf7\x7f\x15\x24\x0d\x7e\x2b\xb5\x82\xc6\x78\xc0\xda\x88\xef\x45\x22\x83\x0b\x14\x36\x60\xac\x9c\x43\x4d\x95\x77\x2e\x6e\xee\xed\x60\x14\xae\x16\x82\x4c\xcd\xc4\xdf\x2d\xf6\x4a\xeb\x69\x80\xb5\x1d\x11\x89\x85\xdc\xbb\xd1\x96\x1f\x31\x5e\x6a\x94\x33\xf0\xb9\x6b\x1e\x63\x51\x25\x7e\xad\x83\xe0\x5b\x4c\xc8\x9c\x92\x4b\xf8\x35\x58\xba\x7d\x2e\x7c\xa3\x7c\x03\x17\x9a\x8f\x85\xb8\x31\xe7\x21\x7b\xf4\xc5\x53\x83\x87\x61\xd3\x26\x02\x85\x3b\x81\x59\x3b\x0e\xbf\x8e\x4b\x9f\xfa\xf0\xec\x40\x5b\x2a\x83\xaf\x7d\xe5\x55\x4d\xaa\xd2\x8b\x58\x2e\xe0\x8b\xd8\x4b\x37\x55\x50\xca\xe0\x8a\xe4\xa5\xbd\xa7\x15\x81\xfc\x3b\x7b\x54\x49\x8c\x4e\x1a\xfb\x96\x6b\x4a\xf1\xd9\xc8\x43\xa6\xb2\x5b\x34\xe0\x4c\xfd\x9b\xd2\x37\x42\x44\xf1\xfe\x20\xec\x62\xbe\x3c\xcf\xab\x4e\xde\xf7\x9e\xd6\x4e\x6b\x71\xaa\x92\x28\x12\x7c\x63\x59\xea\x1c\x4a\x80\x87\x89\x08\x96\xff\xa4\x6e\x00\x92\xde\xc7\xef\xbc\x96\x0a\x17\xb7\x70\x91\x6f\x95\x40\x70\x13\x2e\x26\xd9\x8d\x97\x74\xa2\xac\xdf\x80\x9d\x58\x6d\xf0\x25\x2f\x67\xcf\xe8\xd9\x85\xa3\xe2\x48\xdb\x0f\x90\x73\x1a\xce\x7a\xbd\x99\x9c\x74\x6b\x69\x64\x8d\x5c\x3b\x4b\xd6\x11\x37\xe0\x8f\xcc\x8b\x2e\xfc\x56\x76\xbc\xd8\x56\xa1\x3b\x36\x21\x51\x47\x4c\x4a\x1e\xfd\xed\xc5\x92\xcf\x3e\xad\x1a\xba\xbc\xd4\x8e\xe2\x04\xd2\x77\x26\xad\x1b\xda\x4f\xe4\xb0\x9a\xb5\x10\x89\xd0\x16\xde\x6b\xa2\x59\xea\x81\x80\x7f\xaf\x21\x1c\x87\xe4\xc9\xef\xbf\x6a\x4c\x75\x3e\x08\xf7\x80\xed\x55\x33\x8c\x0f\xde\x14\xfb\x99\xb3\x07\x22\xb5\x59\x4b\x3a\xbe\x02\x04\x7f\x46\x62\x42\x42\x1f\xb8\x11\x76\xc9\xc4\xf0\xfd\x2b\x5e\x7c\x5a\x0f\x65\xa0\xc5\x9a\xa8\xc3\xa9\x86\x08\x7d\xe7\xba\x40\xba\xca\x77\xbd\x36\xac\x21\xce\x34\xe9\xfe\x97\xfa\xcc\x4e\x29\x83\x30\xee\xce\x1c\x8e\xc6\x23\xe6\x6a\x4b\x0f\x23\x42\xd2\xc5\xa0\x2c\x5f\x5a\xbd\xdc\x5f\xf1\xf1\xf2\xd0\x3c\x1d\x4e\xe9\xb4\xb3\x42\xed\x3b\x1c\xc2\x65\x61\xf3\x21\x7b\xf8\x50\x0e\x08\xf0\x27\x57\x1c\x53\xc9\x23\x26\x05\xa5\x3f\x2b\xda\x02\x4e\x39\x92\x91\x63\xa8\xe0\x07\x91\xac\x06\x56\xbb\x07\x83\x82\x5e\x71\x05\xff\xa9\xd9\x09\x69\xdc\x09\x4a\xf4\x6f\x70\x2e\x85\xcc\x11\xe4\x42\xb3\xd5\x53\x4c\x1d\x32\x75\x20\x7d\x6d\x29\xa9\x42\xc3\x58\xed\x5f\xa0\x75\x57\xc3\xc0\x14\xcf\x54\x1f\x9a\xae\xea\x60\x25\xb4\x1e\xcd\xd8\x48\x51\x2b\xa2\x5e\x72\x1e\x43\xd3\x29\x18\x5f\x8f\x94\x89\x2e\x9e\x2d\x5e\x7c\xbb\x99\xe7\xad\x25\xf6\x9e\x5b\xef\x73\x2c\xfc\xeb\x07\x86\x11\x55\x3c\xc7\x83\x77\x37\x5e\x74\xe6\x6f\x1b\x9d\x8d\x20"}, +{{0x3e,0xdb,0x50,0xff,0x07,0x4e,0xf9,0x71,0x7f,0x4f,0xb0,0xb6,0xce,0x25,0x2b,0xf4,0xbd,0x04,0x9c,0x90,0x83,0x77,0x5f,0x52,0x9e,0xaf,0x51,0xe9,0x75,0xcb,0x32,0x45,},{0x4b,0xc2,0x1f,0xe0,0x3e,0x67,0x9a,0xbb,0xfc,0xd8,0xc5,0xea,0x2b,0xcc,0x4d,0x83,0x8a,0x78,0x7d,0x48,0x40,0xc3,0xbc,0x39,0xde,0x4b,0x04,0xc4,0x17,0xc7,0x68,0xa5,},{0xde,0xb3,0xd9,0xfc,0x7b,0x2d,0x86,0xab,0x4b,0x92,0x6f,0x99,0x52,0x79,0x70,0xab,0xb5,0x18,0x38,0xbc,0xc2,0x91,0x9e,0x94,0xcd,0xa3,0x37,0x1f,0xd0,0xe7,0x69,0x3f,0xe3,0x7e,0x0c,0x40,0xe1,0x23,0x3b,0x09,0xff,0xa9,0x03,0xa0,0x34,0xdd,0xe2,0x87,0xc0,0x23,0x7d,0xc5,0x94,0xf5,0x3a,0xbc,0x87,0x84,0x48,0x69,0xdc,0xe9,0x20,0x02,},"\x97\x5e\xce\x4e\x81\xf0\x01\x5f\x5a\xc3\x04\x46\x09\xd0\xac\x3a\x8d\xf9\x14\x5b\x50\xc4\x28\x89\xdd\x31\x2f\x56\x3c\xf6\x12\x6e\x36\xff\xfa\xf2\x1e\xb6\xb8\x4f\xbd\xa1\x5a\xa8\x5c\x66\x14\x5f\x75\x41\xe5\xb4\x1a\x8e\x81\x70\x0b\xe3\x56\x22\x4f\xc1\x09\x32\x7a\x69\x19\x66\x56\x73\x53\x4f\x5c\x8a\x4a\x00\x17\x50\xb1\x99\xdb\xfd\x63\x06\x91\xaf\x55\x2d\x4d\x26\xa9\xd9\xaf\xb3\x3a\x16\xaf\x39\x11\x54\x12\x4b\x53\x42\x6c\x9f\x69\x50\x57\xb1\x81\x4f\xd6\xd3\x10\x29\x8a\xf6\xc8\x30\x68\x6a\x4a\x00\x7a\x14\xe0\x05\x7b\x72\xfb\xad\x5b\x80\x3a\xd3\x53\xd1\xc3\xfd\xb8\x90\xa9\xc8\x18\x08\xe8\x9f\x22\x91\x87\xbc\xb4\x4f\xee\x16\xa4\xeb\xca\xd5\xeb\xa4\x59\xb0\x28\x27\x2a\x56\x2c\x05\x07\x9f\xa7\xae\x3e\xca\xe8\x04\xa9\xe8\xc4\xf3\xf3\x15\x81\x3c\x5e\xe0\x84\x1b\xbc\xcf\xe4\xa9\x56\x23\xb5\x17\xa4\xb4\x2b\x2c\x6d\x97\xa3\xbf\x26\xac\xdb\xe2\xe9\x79\x63\x3f\x02\xaa\xc4\x66\x52\x6a\x3e\xbb\x14\xda\x19\xbc\x95\xf2\xc3\xfd\xf6\xbd\xb0\x8b\xe8\xbd\xe9\x7a\x86\x4c\x90\x7e\x91\x8c\x67\x9a\xb7\x26\xf8\x01\x77\x14\x58\x40\x21\x6b\x9d\xc3\xf9\x81\xef\x17\x87\x4f\x08\xb2\xfc\x66\x11\xa6\x34\x6c\x3d\xa6\xa5\x5e\xcf\xa7\x53\xc9\x91\x9f\x4f\x19\xe3\xc7\x90\x93\xbf\xd7\x8f\x86\x15\x98\xe4\x66\x6e\x1c\xab\x68\x8e\x46\x04\xd4\x6c\x9c\x58\x2e\xad\xb9\x2c\x98\x8f\x47\x8d\x16\x0f\x5a\x15\x18\x2b\x33\x40\x20\x17\x97\xd0\xb9\x55\x28\x2e\x4a\x21\x7b\x50\xb1\x4b\x10\xc9\xf4\x90\x67\xea\x3e\x84\xe5\x27\x4d\xca\xec\x74\x47\x4c\x57\x07\xc2\x8b\xba\x0d\xb8\xcd\xe3\xe8\x38\xd7\x31\x3c\x17\x1b\x85\xff\x2b\x9a\x3d\x2b\x16\x7e\x90\x61\xf8\x4d\xf3\xb1\x3b\xdd\x08\xb2\xd5\x01\xe5\x37\x92\xd6\x80\x54\xd0\x48\xab\xfe\x3b\xce\x98\xd9\x78\x25\x6f\x2f\xd2\xc6\xc4\xe7\x6f\x39\x68\x8c\xcc\xf0\xfe\x14\x9a\xf9\xd3\x47\xe7\xb0\x40\xef\x24\x1d\xd5\xa5\x3e\xaa\x5e\xab\x35\xa1\x8c\x68\xc7\x54\xa0\x6b\x03\x39\x9b\xbe\x56\xa2\x52\x68\xc8\x29\xa5\xba\x82\xb2\x81\x92\x04\x1d\x3b\xd2\x44\xeb\x08\xbf\x78\xe7\x6d\xef\x87\xcd\x09\xf3\x2b\xea\xc9\xbb\x63\x98\x23\xb3\x69\x67\xa5\x74\xd8\x96\x0d\x1b\xd0\x34\x35\x67\x9d\x93\xed\xdc\x55\x80\x63\xc5\x40\xb9\xc2\xf6\x09\xfe\xd2\xe2\xe3\x57\x6d\x19\xe6\x20\x9e\xab\x46\x6c\x20\x67\x91\xc3\xaa\x19\x96\x23\xfb\xae\x7d\x34\x97\xe8\x0f\xdd\x3f\xcb\xaf\x5b\x89\x11\x0e\xd7\x22\x44\x23\x4b\xe8\x5c\xca\x4b\x27\xa0\x9b\xb7\x0a\x26\xec\xe4\xeb\x8d\xd9\x70\xa2\x6e\x5b\x04\x36\x1f\xa5\x0e\x90\x38\x0e\xd6\x5f\x41\x4c\x1b\xe9\xf5\x06\x4f\x71\x42\x91\x16\x26\x7e\xdd\x69\x76\x42\x2a\xd9\x2d\xeb\x2b\x80\x4a\x92\xe8\x1c\x9f\x65\x22\xa0\xf3\xb5\xd8\xad\x36\xb4\xf8\x7d\xb5\x16\xa2\x28\x73\xe6\xf2\x72\x84\xf2\xca\x36\x0a\x2f\x40\xff\x3d\x8e\x23\xde\xc8\xef\x8a\x17\xa4\x3a\xcb\xb6\x12\x71\xa7\x27\xcb\x86\x90\xd2\x9b\xb8\x20\x16\x73\x6b\x31\x02\x62\x01\xdd\x3d\x38\x8d\x2c\x64\x3a\x73\xcf\xbd\x0a\x94\xe2\x05\x51\xfb\x5f\x8e\x1f\xfc\x39\x74\x12\x72\xaa\x23\x08\xdc\x8d\x21\x33\xa3\xfa\x9c\xf1\x09\x79\x6d\x69\xd2\xcc\x8a\xdd\xc4\x4a\xe2\x52\x77\x81\xee\x99\x3a\xf2\xa6\x37\xa8\x72\xf0\x2a\xff\x47\x4a\x70\x73\xf2\x9d\x9c\x89\x50\x77\x01\xfe\xcb\xbf\xd5\x10\x13\x53\x53\x7e\xba\x17\xc2\x96\x69\xda\xc0\x42\x7e\x38\xe2\x2d\xfa\xac\x91\xfc\x20\xd9\xe3\xfe\xe7\x91\xf4\x62\xa8\x63\xbb\x19\x08\xfb\x1e\x42\x04\xb6\x88\x80\x31\x4d\xda\xca\xaa\x35\xa1\x7a\xf5\xf5\x7a\x39\x9f\x19\x31\xe7\x8f\x5a\x37\x45\x4f\xd3\x8c\x57\xa6\x8e\x8d\x36\x78\x48\xa9\x73\x45\x18\x9c\x70\x07\x7f\xd1\xaa\x07\x54\xe7\x03\xe3\x52\x61\x80\x63\xb9\xe3\xfa\xf3\xb1\x4b\x5f\x0b\x27\x11\x36\x33\xc5\xd1\x73\x63\x74\x1e\x96\xa6\x7e\x81\x64\x01\xe8\x09\x8c\x17\xbf\xfe\x9c\x6f\x35\x87\x64\x6f\x40\xe9\xfd\xb6\x81\x9f\xd2\x2a\x74\x3a\x7a\x6e\x10\xfe\xba\x11"}, +{{0xcd,0xa4,0xba,0x93,0x94,0x0a,0xa0,0xc0,0xc3,0x15,0x0b,0x39,0x29,0xb9,0x5e,0xe7,0x76,0x9c,0xe4,0x3f,0xd9,0x8e,0xca,0xff,0x9c,0x4a,0x50,0x9e,0x73,0x6d,0x5c,0x8e,},{0xf4,0xc7,0xa2,0x5f,0x1a,0x74,0x3d,0xaf,0x41,0x41,0x7e,0x47,0xe0,0x27,0x53,0x7f,0x24,0xf4,0x81,0xbd,0x1a,0x75,0xe6,0xb1,0xd3,0x3e,0xc4,0xc8,0x2c,0x55,0xa2,0xd3,},{0x31,0x04,0x8d,0x33,0x4a,0xf0,0x5a,0x4f,0x27,0x5f,0xf8,0x27,0x54,0x4e,0xa2,0x96,0xa4,0xa7,0x75,0xfa,0x59,0xef,0xa0,0x00,0xc5,0x76,0x13,0xfa,0x6e,0x5c,0x49,0x3c,0x3a,0x9b,0x79,0xe8,0xce,0x56,0xe7,0x22,0x5b,0x0f,0xa3,0x26,0x20,0x4f,0x03,0x36,0xc2,0x13,0x53,0x5a,0xe5,0x89,0x17,0x7a,0x8e,0xae,0xdb,0x6d,0xf8,0xb2,0x02,0x03,},"\x3a\x1d\x66\x8c\x66\x88\x41\x48\x96\xa7\x69\x7f\x3c\x2e\x43\x10\x98\xed\xfc\x45\x7e\x04\xd2\xda\x86\x95\x68\xad\x5b\x33\x10\xe5\x9e\x4c\x72\x7c\x90\x3c\xbf\x18\x17\x40\x88\x02\x31\x9a\x8c\x23\x1b\x58\x02\x3d\xfa\xe4\x94\xc0\x13\xaf\x0f\xdb\x78\xc9\x1d\x5b\x45\x7f\x8c\x47\xa3\xdc\x31\xd8\xc8\x59\x4a\xa0\x8f\x14\x62\x03\xfa\x2c\x28\xb3\xdd\x79\x6a\x11\xa9\x7a\xde\xde\x6a\x7a\x70\x9b\x5a\x19\x18\xef\x1b\xea\x83\x53\x3c\x78\x34\x73\x70\x33\x56\xf5\xbe\xea\x7f\xd1\x8a\xc4\x4e\xc6\x89\x04\x95\xed\x17\x0d\x03\xf1\x5b\x41\x86\x08\xa7\xd9\xef\xd5\x2f\xa1\x09\x18\x63\x80\x51\xc4\x48\xd9\x8d\x57\x24\xf5\x67\xc8\xc6\x7f\xd5\xb6\xec\x8c\x3d\x63\x60\x08\xb9\xba\xe5\xe8\xb1\xe9\x84\xf8\xff\xb8\xb6\x4b\xee\xbd\x63\x45\xa1\x05\xc1\xc1\x08\x31\x32\xfd\x45\x08\xd6\xac\x0d\x4e\x91\x45\x50\x12\x10\xe5\x17\xd9\xb2\x24\x78\xe2\x15\xb6\x02\x59\x9f\x80\x37\x62\xdc\xd5\xa4\x09\xb3\x46\x0e\x7f\x34\x0f\x47\xef\x77\x28\x1a\xd2\x38\x3d\xe0\x8c\x5b\x80\x95\x38\xaa\xec\x92\x2b\xfc\xa0\xd6\x75\x2f\x14\x79\x72\x64\x6d\x0a\x8d\x83\x40\x77\x2c\x87\x1d\x3b\x34\xab\xc0\x60\x37\xde\x3a\xb4\xe3\x71\x29\x86\x5d\x5b\xa7\x0b\x6f\x3c\xc9\xa0\x59\xef\xb7\xdd\xdc\x38\x82\xf4\xfc\xfe\x13\xf4\x48\xc9\xbc\x66\x48\x88\x58\x96\x03\xba\x98\x68\x3a\x93\xb4\xb3\xb1\x01\x49\x92\xa5\x5c\x8e\x4e\xa1\xba\xf9\xcc\x00\xd1\xba\xdf\xf5\xfd\x7f\x5d\xa5\xe3\x07\xfb\xd1\xb4\xc9\x84\xe0\xfa\x0e\xde\xc5\xd3\x0b\xfe\xf5\xf4\x77\x30\x12\x63\xb5\xd7\x52\x00\x1b\x85\xdd\x52\xdf\x3b\x4a\x7a\xc2\x3b\x93\x0a\x91\xc0\xa4\x57\x65\xa6\x64\x88\xd8\xeb\x59\x01\x85\x70\x60\x06\x7b\x82\x37\x81\x88\x54\x92\x88\xdd\xc6\x18\x31\xe5\xb6\x84\x1b\x34\x4c\xae\x22\x50\x04\x22\x19\xcf\xb4\xac\xe0\x23\xe6\x91\xf9\xe4\x8d\x00\x6e\x9a\x07\xc6\x7d\x24\x68\xf9\x35\x93\xb4\xaf\xc1\x61\xc0\x76\x8b\x6c\xeb\x74\x4c\x24\xc9\x23\xda\x34\xaf\x3d\x5e\xd5\x77\xcc\x7f\x85\xd4\x91\x56\x0f\x4c\x0b\xcb\xcd\x1d\x5e\x34\x21\xbd\x1c\xcf\xaf\xb3\x73\xd6\x51\xbd\x61\xed\x71\xc0\x9e\x99\xf6\x12\x00\x17\x04\xd0\xc6\x30\xd8\x54\x7b\xd9\x70\xb6\x6e\x7f\x5c\xe7\xa0\x14\xe0\xff\x5a\x33\x7d\xc5\xc5\x6a\x99\xf1\x31\xb9\x12\x91\x40\xee\xea\x39\x39\x7c\x48\xca\xa9\xa8\x08\x6f\x9f\xd9\x91\x50\xbe\x7e\xf8\x7b\x6d\x4b\x94\xb1\xbd\x52\x87\x8b\xf3\xbb\xfc\xce\xac\xc2\xcc\x45\xe8\x97\x1c\x3a\x4d\x4a\x3e\xb8\x6a\xf9\x87\x4d\x4f\xa5\xe7\xca\xa7\xf4\x5d\x15\x53\xff\xbb\x41\x64\x5b\xf0\xf5\xe9\xb2\x97\x72\xe3\xdc\x08\x1b\x25\xb5\x2e\x1c\xb7\xe2\x16\x74\x83\xd5\x4f\xba\x69\x0d\xdb\x29\xd5\x46\x2d\x2a\x27\xa3\x5d\x85\xf0\x07\xad\xed\xe2\xa3\xdd\x72\x81\xf6\x54\x33\x6a\xfa\xfb\x73\x70\x78\x2b\x29\xca\xd6\x43\xd9\xd9\xdb\x2f\x05\xf2\x81\xb5\x3e\x13\x3e\xc3\x0e\xec\x09\xfb\x0d\x06\x1b\x74\x58\x1a\x2b\xd2\x79\x0b\x13\x73\x91\xf1\x93\x28\x88\x0f\x64\xc5\x3b\xe7\x00\xd0\xfa\xdd\xb7\x0d\xc1\x65\xd2\xd6\x2e\x67\x1e\xb9\x44\x9a\x2e\x6e\x9d\xf2\xc1\x6d\x8f\x49\xfa\x4b\x5b\x84\x30\x9f\x73\x35\x13\x3d\xbe\x87\x2c\x5a\x8f\xdc\xfb\xc4\x98\x0a\xbf\xb3\xc9\x59\x7d\x5d\x66\x7a\xd2\xf6\x88\xc7\xab\x24\xc9\xe4\x40\x29\x8d\x72\xb2\x8b\x0f\xcd\xe9\xc6\xf0\x71\xbc\xcc\x93\xe8\xdd\xbb\xa7\xb6\x0a\x0b\x54\x4a\x2e\x06\xc3\x9c\x67\x23\xd4\xf7\xdc\x18\x5c\x21\x13\x5f\xd1\x3a\x72\x77\x0b\x97\x61\x19\xe4\x9a\x1f\x81\xed\x47\x6b\xe0\x7c\x44\x3d\xe0\xb0\xee\x76\xfb\xd9\x19\x38\x93\x28\xb3\xeb\x86\x07\xbc\x2f\xe3\x8f\x85\x74\x5e\x28\xad\xb7\x48\x2b\x70\x1c\xcc\x66\x90\xe4\xae\x5a\x93\x32\xea\x44\x61\x31\x79\x38\x7d\xc6\xfc\x47\xc1\xd1\xec\x36\x60\x35\xe9\x91\xe1\x40\x43\x23\xbd\xbb\xf5\x35\xf1\xc3\x3c\xf5\x7b\x67\x23\xf1\x3c\xa6\xca\x32\x9e\x2a\xaa\x4b\x46\xb4\x26\x07\x33\x99\x06\xc7\xef\x49\xb3\x2d\xb8\x2c\xdf\x6a\x87\xad"}, +{{0x21,0x7e,0xcd,0x6a,0x7f,0xcc,0x98,0x71,0x92,0x10,0xc3,0x4c,0xc2,0xe1,0x4f,0x5e,0x2d,0x6b,0x5a,0x22,0xf2,0x68,0xc1,0x4b,0xc4,0xd8,0xa7,0xf2,0x81,0x72,0x00,0xc3,},{0xd5,0x91,0x91,0xce,0x28,0x2d,0x72,0xfe,0x3a,0xc4,0x58,0x78,0xe2,0x4b,0xb2,0xf2,0x8c,0x40,0x9b,0xa0,0x5d,0x76,0xce,0x9b,0xcf,0x22,0xf5,0x0b,0x0c,0x77,0x86,0x75,},{0xa0,0xb1,0x69,0xe8,0xe9,0xce,0x55,0x75,0x55,0xe0,0x33,0x4a,0x0d,0xe7,0x43,0x8e,0x55,0x36,0x75,0x48,0x9e,0xa4,0xba,0x9c,0xc6,0x3a,0x23,0x4d,0x00,0xde,0xd8,0xab,0x69,0x67,0xa3,0xbe,0x90,0xef,0x69,0xe0,0x76,0xdb,0x9e,0xa3,0xd5,0xca,0x23,0xb3,0x24,0x8d,0xd2,0x59,0x91,0xee,0x1f,0x4d,0x80,0x62,0x0b,0xf4,0xdb,0x43,0x8f,0x0e,},"\x9b\x53\x37\xe7\x8f\xb3\x82\xf2\x2e\xa6\x0e\x03\xc0\xbf\x3e\xe4\x70\x0b\x69\x78\xa9\x1e\xe6\xac\xdf\x6a\x40\x9e\x49\x18\xd1\x68\x48\x81\xfa\x1d\x11\x8c\x08\xc9\xf6\xf2\xca\x0c\xab\x56\x74\x02\xc9\x50\x10\xe7\xab\xdf\xe8\x48\xae\x79\xba\x24\x9a\xdc\xb9\x6e\xae\x1d\xfa\x08\x43\x95\x21\x39\xcf\x49\xb5\x88\x64\x78\x95\x69\x1a\x2e\x98\x80\x46\x6b\x7e\x77\xe5\x4f\x6f\x60\x81\x5e\xbf\xd5\xe5\x74\x8f\x41\x3c\x0e\x15\xf9\xd5\x76\x79\x9b\xcf\x31\x28\x47\x10\x63\x6f\x6e\x9d\xc7\x87\x85\x00\x79\x6e\xed\x80\xc8\xaf\x4b\xe2\x96\x19\x52\xea\x80\xbb\xed\x14\x04\xbd\x5d\xae\x9e\x6d\x05\xfd\x4f\x32\x5a\x3b\x83\xcd\x45\x28\xa0\x86\x9c\xef\x84\xb4\xd3\x0e\x02\xf9\x41\xd7\x49\xa8\xda\xc9\x7b\xb3\xfa\x83\x9d\x25\x73\x9b\x97\xec\x37\x45\x36\xbd\xea\x50\x04\x84\xa9\x41\xdb\x9f\x22\x99\x97\x06\x58\xd4\x11\x48\x29\x5c\xa0\x84\x6c\xa2\x36\x62\x38\xb6\x20\x1a\x48\xb3\xe4\x47\xed\xbe\xa7\xa4\xc8\xf7\x10\x20\x14\x27\x69\xe1\x5f\xa7\x2a\xe5\xf2\x87\x14\x0b\xc5\x95\x3b\x8a\x9a\x24\x2d\x20\x5f\xc0\x19\x09\x1f\x2a\xbe\xd0\xfd\xa4\x7f\x52\xd5\x9a\x02\x04\xce\x74\x01\xc1\x82\x9b\x58\x57\xb9\xa0\x91\x6f\xce\xbe\x2e\xef\x99\x1c\x41\x3a\xcd\x71\xb1\x8d\x85\x90\xd6\xb6\xd0\xfb\x39\x94\x30\x26\x78\xc2\x9f\x2b\x6a\x53\x02\x3f\x91\x87\xe4\x6c\x36\x79\x0b\xce\x73\x87\x3c\x54\x5a\x72\xbe\xb5\x53\x29\x4b\x1e\xe5\xd0\xd0\xdf\xf2\x39\xe2\x8e\xc6\x3b\x01\xe4\xd8\xfe\x0d\x6e\x69\xb1\x60\x1e\xfa\x24\x11\xf0\xc0\x60\x1e\x7e\x4f\x65\xc9\x84\xf8\x29\xf0\xdc\x2a\x84\x21\xe7\xf6\x6d\x93\x30\x53\x71\x51\xc7\x24\x3c\xa5\x24\xd7\xa5\x47\x35\xc6\xe3\x44\xf1\xfc\x93\x8e\xae\xea\x27\x79\xc9\x40\x89\x1d\x6d\x01\xaa\x55\xf4\x0c\xc1\xad\xba\x12\xe8\xa6\x7a\xd9\xa2\x7f\xe6\x3f\xb4\xf3\x8d\xc0\xf0\x18\x41\x92\x57\x18\x42\x72\x55\xbd\x66\x5d\x5e\xb3\xbc\x86\x98\x96\xdb\x86\x25\x20\x4a\xd4\xb0\x2f\x5a\x22\xaa\xee\xad\x6e\x30\x04\x71\xfe\xa6\x1d\xbb\x1b\x55\xc0\x71\x36\x5c\x58\xb1\x51\x1f\x38\xb0\x9a\x46\x71\xbd\x66\xb3\xfe\xdd\xa9\xc8\x7e\x43\xd1\xeb\xf3\x01\x76\x4e\x18\xfc\x0c\xf1\x6b\x2d\x2d\x67\xed\x23\x9b\x39\x3a\xc7\x19\x68\xa9\x03\xc0\x24\x77\xfb\x2d\xf9\xef\x01\xdb\xfc\x31\x67\xde\x72\x65\xf8\x91\xe4\xfd\x24\xd0\x2c\x63\x10\x35\x19\xb8\x6a\x70\x85\xb1\xec\x2f\xb4\x19\xdb\x76\x6b\xee\x7a\x64\x1a\x4b\xe4\x29\x61\x4a\xb8\x9f\x20\xf9\x75\x34\x10\x72\xbf\x04\x41\x9f\xb6\x9b\xe7\xa9\xee\x71\xa5\xb4\x9a\xf8\x3e\xd3\x22\xba\xc6\x8a\x42\x9f\xf5\xc5\x20\x67\x73\xbe\x54\x38\xb6\x5e\x53\xf6\x09\x72\x9f\x4f\x6a\x21\xc1\x33\x39\x11\x26\x4d\x63\x92\x70\x17\xe8\x13\x6b\x47\x25\xcd\x1c\xc9\x64\xe0\x8c\xa0\x93\x3a\x56\x1e\x7e\x3f\x59\x87\x76\x83\x30\xe2\xe5\x4f\x8d\x72\x8f\x59\xed\xfe\x2c\x91\xc4\xf9\x9a\xef\x97\xd1\x85\x59\x19\x5a\x3d\x8e\xb3\x15\xdf\xf9\x6f\xe2\x76\xda\x71\x37\xef\xf9\x30\x57\xac\x73\x1e\x06\xa6\x0a\x58\xbd\x8a\x9a\xe8\xc7\xcb\xaf\xf0\xcb\x33\x72\xc6\x8d\xaa\x17\x5c\x42\x8d\x52\xf1\x07\x3a\x38\xbf\x29\x46\x5d\x2a\x71\x28\xbb\x40\x07\x40\x06\xed\xcb\x72\x5a\x83\x1d\x81\x28\x64\xef\x43\xf3\xb8\x66\x7c\x9f\xb7\x10\x93\xa1\x67\x30\x49\xde\xc0\x5e\x09\x16\x9d\x86\xfe\xe9\x2d\xf2\x86\x00\x8a\xd9\x90\x65\xa2\x92\x97\x97\xa9\x13\xd0\x23\x3f\x4d\x1a\x95\xa2\x20\xbd\x91\xc1\x1d\xd9\xc4\x56\x85\xdc\xad\x38\x57\x80\xa0\xc4\x8b\x9c\x4a\xd2\xd6\x63\x03\xe8\xde\x4a\xf1\xdb\x3c\x04\xe4\xa3\xdd\x42\x19\xfe\x77\x3f\x83\xa8\x92\x4b\x0f\xcb\xff\xfc\xf2\x64\xab\xce\x32\x83\x29\x24\x03\x6b\xfa\xbb\xa6\x54\x6b\x1d\xf4\xe3\xf7\x88\xed\x8a\xd5\xc2\xcd\x92\xb2\x64\x1b\x47\x09\x0a\x10\x3c\xf5\xbd\xc4\x6d\x8b\x21\x43\x17\x47\x57\xda\x80\x1c\x36\x0a\x7a\xa1\x07\xfa\xc6\x54\xb3\x4c\x86\x0b\xd5\x4f\x76\xbb\xf4\x3c\x48\x47\x8d\xf4\xfe\x7a\xa5\x9c\xf9\x1d"}, +{{0x08,0xd1,0xd0,0x6f,0x3e,0xc2,0x9e,0xb5,0x22,0x93,0x90,0x7b,0x70,0x5e,0xc5,0x6c,0x5a,0xb3,0x54,0xfb,0x78,0x67,0x37,0x73,0xae,0x61,0x25,0x30,0x94,0xb8,0x9e,0x82,},{0xc1,0xb9,0x9a,0x87,0xad,0x15,0xbd,0x46,0xf6,0xc8,0x48,0x45,0x2a,0xf0,0xfa,0x3c,0xcc,0xcb,0x5c,0xdf,0x6e,0x34,0x8d,0x81,0x6e,0x36,0xc5,0xd0,0xfc,0xa6,0x6e,0x66,},{0x0b,0x8e,0xdc,0xb8,0xb1,0x5a,0x8c,0xd0,0x74,0xc4,0x1d,0xc2,0xa1,0xba,0x29,0xd9,0x64,0x8d,0x6a,0xcb,0xdc,0x33,0x83,0x14,0x70,0x7e,0xca,0x6f,0xb4,0x71,0x4c,0x99,0x54,0x3b,0x49,0x07,0xb9,0xf8,0x5e,0x57,0xee,0xcf,0xfe,0x0f,0x7a,0x6b,0x70,0x73,0xa8,0x09,0x46,0xf8,0x08,0x75,0x53,0xf4,0x68,0x31,0x09,0x27,0x3a,0x60,0x4a,0x08,},"\x12\x0b\x35\x57\x3c\x34\x91\x4b\x37\x30\x51\x88\x0d\xa2\x7e\xd2\x41\x37\x7f\x0e\x78\x97\x2c\x98\xd0\xfa\xeb\xaa\x76\x7e\xb7\xa7\xc7\xe7\xc6\xfc\x34\x05\xa4\x33\x6e\xf9\x5b\xc5\xda\x92\x25\xbb\xd0\x9e\x9e\x11\xf2\xa1\xbf\x14\x2a\xf4\xe8\xa0\xf9\x24\xd3\x23\xdd\x5a\x49\xdf\xe5\x84\xf0\x90\x43\x9c\x08\xe5\x15\x11\x34\x4d\x47\x0c\x62\x00\xac\x7e\x7c\xa1\x50\xd0\x88\xa9\x1e\x47\xc4\xc9\xff\x74\xe3\x8a\x42\xa3\x32\x15\x5d\x81\x52\xae\x4a\xbd\x11\x61\xad\xca\x93\x4c\x23\x4c\xe4\x60\xaf\x87\x89\xe5\x3f\x10\x9d\x7d\x31\xee\xde\x0a\x90\x9b\xd1\x93\xfc\x8d\x3c\x2c\xfe\xc1\x0b\x14\x3c\x31\x47\x67\x11\xbb\xec\x27\xe1\x96\xa5\x49\x85\xbc\x34\x71\x67\xac\xd2\x33\x50\x88\x27\xba\xd3\x6e\x54\x8c\x88\x06\x42\xb8\x6a\x28\xc6\xd3\x40\x4b\x51\x1d\xa2\x4f\x11\xdf\xaf\x6a\x8f\x46\xdd\xcb\xc9\xde\x9e\x39\x15\x97\x66\x9b\xdd\xfc\xa6\x56\x0f\x91\xac\xd3\x45\x9f\x32\x9b\xb0\x71\xdd\x80\xda\xdf\x35\xf0\xe5\x0d\xf5\xb1\x0f\x88\xd2\x67\xac\x9d\x30\x62\x33\x0d\xd9\x9a\x6b\xcf\xa1\x31\x87\xf4\x5c\x0c\x21\x4d\xcd\xe2\xcd\xf9\xc3\xba\x4d\x59\xe6\x33\xa3\x54\xa4\xe2\x77\xc6\x77\xbb\xdf\xa2\x41\x91\x17\x9c\xbc\xaf\x05\xa1\x0d\x40\x78\xd8\xad\xd9\x3b\xc9\xed\x8f\x6c\x6c\x49\x97\x57\x40\x36\x55\x34\x1f\x90\x4e\x37\xd9\x27\x75\x0c\x69\x9c\x26\x9d\xc9\x0d\xc2\x6d\x00\x56\x25\xc3\xf4\x12\x4b\xff\x66\xfe\xca\x59\xd4\xab\xff\x41\x72\xba\x3d\xf4\x5a\x87\x43\x02\x23\x10\x30\xfa\x78\x33\x84\xf5\x09\x99\xe3\xc4\xba\xa5\xea\xdb\x45\x14\x52\xc8\x88\xb5\x19\x27\x2e\x90\xf7\x3c\x68\x72\x76\x8e\x0d\xe2\x0e\xe2\xe5\xf9\x50\x2f\x35\xe4\x9f\xec\xc2\x8b\x75\x20\x18\x87\xfe\xd2\x81\x8e\xff\x54\x53\x98\x39\x2f\x5e\x5b\x68\x76\xbc\x55\x6a\xc1\x3a\x19\x03\xad\xa1\xb9\xd7\x25\xb0\x4a\x14\x20\x4b\x59\x9e\xc3\x3d\x62\xb7\xdc\xae\xea\x8c\x52\x87\x7b\x2c\xfd\xc3\x55\x8a\x91\xd2\xc9\x15\x75\x00\xa3\xbb\x6d\x45\x2e\x5e\x2f\xf0\x93\x29\x4f\xc4\x33\xcb\xd6\x34\x65\xbb\x19\x13\x07\xed\x80\x1a\x15\xb8\x5d\xc2\xff\x0b\xb3\x83\x12\xf8\xb8\x17\xa4\x36\xd4\x22\xcf\x46\x07\xc6\x4e\xe7\x03\x59\x23\xdb\x6b\x96\xa3\x89\x99\x10\x14\x9b\x0d\xa4\xaa\x3e\x96\x68\x5d\x71\x63\xaa\xcf\x9e\x61\x9d\xc6\x08\x13\xce\x4f\x34\x4f\x30\x79\xb4\x3f\x18\x7f\xa3\x1b\xda\xcb\x9a\x1d\x77\x20\xb9\x39\xd5\xbd\x24\x1b\x96\xa1\x77\xd7\xb7\x76\x8f\xfe\xbf\x79\x04\x4c\xd2\x95\x6d\x6f\x88\xdb\x1c\x24\x3a\x10\xfe\xde\x68\x14\x85\x2c\xf4\x04\xb2\xcd\xcf\xa7\x74\x07\x6d\xc1\x25\xc7\x0a\x57\xc6\x90\x7e\x99\xaf\xe3\x96\x22\xae\x11\xf5\x57\xe7\xd3\x4b\x39\xaa\xaf\x45\xf8\x34\x05\x8d\x2f\xe5\xf1\x5b\x5e\xb7\x0a\xc1\x5a\x90\xa3\xde\x58\x50\xab\x1d\xcb\x48\xb0\x6b\x6c\xca\xa4\xb4\x2f\x85\x7e\x71\xec\x00\xb8\xa3\xd8\x97\x4b\x0b\xea\x68\xfa\x0f\x66\x55\x92\x11\x5b\x4f\xa5\x55\x72\xcf\x0b\x07\x38\x64\x1f\xc8\x68\xd4\xa2\xe7\x14\xdb\x3a\xd7\x21\x9a\x82\x3d\x54\xb7\xf7\xc2\x65\x6b\xa5\xc5\xee\xbe\x35\x94\xc7\xdb\x12\x29\x8c\x16\x25\x1d\x98\x45\xbf\x2f\x78\x00\xb4\x19\x0b\x74\x6e\x21\xb0\xc1\xa5\xc4\x7a\x3d\xf9\xa0\x59\xce\x09\x56\x67\x4e\xb7\x03\xde\xcb\x0a\x00\x45\x43\x7d\xa4\xda\x10\xf2\x86\xd7\x20\xd1\xb9\xdf\x05\xfb\x24\x41\x5d\x68\xe0\x65\x57\x0e\x6b\x31\x50\x31\x42\xd0\x33\x35\xa8\x07\xbd\xca\x30\x89\x2e\xdb\x5f\x55\xf8\x98\x9d\x9e\x64\x96\x59\xc0\x74\x4c\x54\x33\xbf\xb4\xde\xeb\x11\xc2\x62\x6a\x86\x50\xe5\x4d\x4d\x39\x8b\xa1\x9b\x64\xf6\x8b\xed\x06\xd7\xfc\x40\x8f\x47\x0a\xc7\x04\xe2\xac\x92\x2a\xc1\x41\x1f\xee\x24\x54\x3e\x56\xf2\xf5\x0b\x6b\x08\x95\x3d\xc5\x6a\x7a\x75\xed\xae\x43\x0a\x6d\xf2\x8a\x22\x7a\xda\xc9\x1b\xa2\x6f\x0e\x19\x85\x95\x32\x77\x39\xcb\xa3\x03\xe9\xaa\x39\x3e\xa6\x61\x8a\x84\xf8\xf5\x03\xd0\x05\x6e\xe8\xd8\x7e\x37\x96\xe0\x36\xcc\x51\xcc\xb7\x91\xde\xb7\x95"}, +{{0xf0,0xc8,0x5c,0x76,0xb1,0x53,0x2e,0x89,0xae,0xa9,0x75,0x15,0x6d,0xdd,0xb1,0xd3,0xd0,0x66,0xf6,0x40,0x9f,0x84,0x1b,0xb4,0x41,0x09,0x22,0x72,0x5f,0x26,0x9d,0x86,},{0xfd,0x75,0xfc,0x75,0xc3,0x6f,0x83,0x49,0x8d,0x8f,0x08,0x27,0xf0,0x1d,0x3b,0x45,0x7f,0x8b,0xc4,0xd9,0xdc,0x55,0xe4,0xa4,0x62,0x74,0xdd,0xf0,0x03,0x4f,0xe1,0x6f,},{0x42,0x18,0xfe,0x4c,0x1d,0xce,0x79,0x5c,0xa9,0x2a,0x49,0xa6,0xf4,0x79,0x8e,0xb5,0x41,0x2d,0xc8,0x25,0x86,0x03,0x14,0xec,0x46,0x9f,0xed,0x45,0xde,0x3a,0x7b,0xf8,0xea,0x55,0xe8,0x53,0xa3,0x49,0x58,0x4b,0xd9,0x5a,0x82,0x6a,0x58,0x5a,0x50,0x3f,0xd5,0x0b,0xfe,0x4c,0x63,0x5e,0xf1,0x83,0xd0,0x73,0x01,0x36,0x7e,0x90,0x10,0x0a,},"\xae\x2e\xb0\x18\xd4\x8d\xbd\x4f\x21\x0b\x16\x77\x8b\x5b\xd2\xfd\x14\xc9\x4e\x6b\xbf\x2b\x3f\xf8\x55\x18\xe5\x60\xab\x8d\x3e\x72\x20\x1f\x43\x34\x20\xf0\x0f\x11\xbc\x78\xe0\xe9\xf3\x72\x08\x75\xb2\xe9\xdc\x11\xe0\x43\x25\xb8\xb3\xf0\xd4\x65\xdd\xab\x21\x51\x1c\x45\x7d\x6a\xca\xd8\xf2\xfd\x5f\xdc\x0d\x28\x23\xfe\x6c\xaa\x66\xa1\x91\xa3\xb6\x32\x6b\x32\xa1\x6b\xef\xd6\x4d\x15\xb3\x61\xa4\x15\x13\x64\x1b\xce\xba\x26\xbf\xe9\x3b\xdf\x85\x4a\x4f\x8f\x8a\x0b\x29\xf7\xe2\x82\x62\xe2\xd6\xe9\x8a\xa2\x4a\xc2\x7f\x6f\x78\x83\xac\x01\xa7\x4c\x40\xcc\xe9\x47\xeb\xac\x70\xe9\xfe\xf2\xa1\x6e\x62\x89\xe4\x68\x95\x0e\x39\x1e\x9e\x24\xef\x58\xe8\x8a\x44\x37\x72\x69\xce\xba\xfe\xd8\x98\x7d\x22\x0d\xca\xe2\xd8\xb1\x26\xb6\xbf\x81\x21\x67\xd0\x23\xd9\xba\xac\x95\x0d\x9d\xb8\xcf\x52\xde\x63\x06\xbd\x48\x99\x96\x10\xc0\xa4\x33\xfa\x9e\x17\x71\xcb\x83\x2d\x41\x97\xaa\x34\x0d\xd0\xcc\xd0\x74\x4f\xc6\xb6\x2f\x90\xbd\x3e\xbb\x53\x08\xca\xb5\xf9\x40\xe2\x91\x64\x23\xcf\x0f\x3b\xf0\x80\xc0\x6a\x94\xf0\x26\x91\x04\x60\xdd\xa8\x09\x37\x4e\x64\x57\xf0\x64\xf1\x78\xe3\x08\xe7\xa1\xb5\xaf\x4d\xef\x31\x90\x07\xd0\x41\x77\x8c\x3d\x6a\x41\x9f\x51\xba\xdf\x87\x66\x38\x79\x30\x2b\x53\xff\x26\x9d\xf4\x42\xd0\xe0\x5c\x95\x8d\x5b\xaa\xcc\xee\xd7\xf5\xf8\xaf\xc8\x11\xc1\x89\x00\xee\x3b\x0f\x61\xe5\xdc\xcf\xd5\xda\xc8\x53\x32\xd3\x2e\xbb\xa3\x71\xaa\x2d\x47\xa6\x06\xf5\x95\x46\xe4\xbb\xb6\x05\xa7\x46\x77\xb1\x9a\x0f\xe8\xe9\x5f\x9f\x77\xc0\xb8\xb7\x1d\x07\xe9\x83\x00\x4d\xc2\xab\x2c\xb3\x79\x3a\x32\x3c\x10\x8d\xfa\x79\x70\xda\x00\xdb\x19\x86\x74\xbd\x34\xbf\x73\x10\x76\x7f\x76\xa2\x24\xe0\x7b\xdb\xc6\x2b\x9d\x07\x8c\xbc\x75\x36\x7e\x2e\xba\xa2\xc5\xd2\x74\xbf\x34\x27\xf2\xa0\xcc\x5d\xbe\xf0\xaf\x4e\x63\xad\x88\x9e\x13\x1b\x12\xbc\x8c\xa3\x2d\x82\x7f\x72\x60\xb0\x44\x9d\x04\x43\xfa\x28\x84\x40\xef\xd1\x36\x4e\x3c\x98\x49\x47\x7e\x73\xee\x0b\xa4\x24\x0d\x49\x2a\xf5\xce\x13\xc3\x45\x61\xb4\x50\x10\xc1\x09\xd8\x42\xc1\xfe\xd1\xbe\x3f\xa9\xe1\x84\xaa\xa1\x40\x64\xf4\x3f\x6d\xea\x0b\x65\x9c\x5b\x97\x89\x3c\xf2\xa4\x33\xbc\xfb\x1d\x2a\x87\xeb\x56\x4b\xd9\x09\x2c\x26\x66\x70\x47\x31\xf8\x3e\x56\x43\x4b\x2a\x42\x99\x65\x0c\x70\x60\xf9\xff\x7e\x8a\xad\xcb\x45\x93\xf6\x09\x18\x8d\x8b\x46\x76\x46\xcf\xe9\x52\x70\x06\x7a\x1d\x35\xcd\x75\x9f\xe5\x81\xaf\x4e\x62\x60\x2c\x02\xef\x14\x74\x41\x43\xeb\x42\x4f\x2d\x9f\x33\xa6\x02\x88\xc1\xb2\x5f\x08\xe4\xb2\xf5\xfe\xae\x06\xcb\xcc\x2b\x20\x52\xbf\x38\x4e\x1a\x6f\xcd\x84\x71\xce\x5e\x56\x58\xd7\x7f\x40\xc3\x5c\x41\x5e\x2a\x9e\x09\xfb\x58\x3b\xb7\x47\x12\x58\xe7\xc8\x06\xf3\xc2\x18\x22\xdd\x10\xf5\x6a\x64\x0c\xdc\x00\x12\x8d\x3b\xa5\x56\xba\x51\xdc\xaa\xb4\x7c\x3b\xaf\x9f\x01\x97\xd3\x66\x3d\xe8\xd0\x93\xe8\x31\x73\x32\x5d\xef\x1e\x83\xa2\xf5\xf5\xac\xf1\x2a\xe0\x9f\x3c\xe9\x6c\xd8\x88\x03\x4d\xcb\xe6\x14\x7d\xc5\x99\x83\x62\xa4\xbc\x40\x6d\x28\x84\x6a\xb1\x50\x3c\x17\xc9\x4f\x9a\xfd\x90\x3c\x9a\x58\xe1\xce\xbb\x4a\xbb\x4f\xf6\xf2\xa4\x10\x24\xe0\x6d\xca\xad\x14\xf5\xb7\x0c\x1b\x26\xe6\x9f\x96\xec\xf1\x4b\x8d\xa3\x1c\x62\x1f\x9a\xd4\xe3\x0a\xeb\x98\x23\x78\x67\x1f\x7d\x1f\x2c\x4b\x57\x2c\x41\xbb\x88\x30\x84\x0a\xc5\xdd\xce\xd8\x81\xf8\xff\xf2\x10\xc3\xc7\xf2\x36\xd8\xc5\xf2\xcf\xda\xcd\xa2\x98\x93\x30\x2f\xde\x15\x28\x2d\xb5\x40\xcb\x54\x37\x37\xdd\x77\x85\x25\x69\x22\x1f\xdd\xcd\xd6\x8d\x87\xe2\x40\x21\x79\xd3\xa5\xa7\x77\x34\xc2\x75\xa1\xd5\x60\xa4\x62\xf4\x03\x18\xbb\x68\x19\x83\x7d\xa3\xd3\x05\xeb\x49\xb3\x86\x50\xef\xdc\x8f\xe4\x09\xd4\x0f\xb9\x4c\xd5\xdc\x3e\xb0\x27\x38\xf3\x88\x52\xf6\x71\xa0\xc4\x14\x14\xb7\x6f\xb4\x36\xf3\x41\x7b\x8e\xf3\x00\x92\x1c\x00\x9e\xbb\xd7\xcf\x8e\x11"}, +{{0x18,0xe2,0x68,0xb1,0x5a,0x25,0x01,0xdd,0x4c,0x97,0x9d,0xc1,0x03,0xca,0x6a,0x84,0x22,0x16,0x13,0x2b,0x3b,0x50,0x81,0xd7,0x75,0xf8,0x86,0x40,0xf8,0x9c,0x80,0x41,},{0xb3,0x4e,0x19,0xc1,0xe2,0x08,0xfb,0x48,0xa8,0x85,0x07,0x9d,0x9f,0xbf,0x37,0xc7,0x4f,0x92,0x71,0x09,0x60,0xf8,0x32,0x15,0x4f,0xab,0x18,0x57,0x0c,0xfb,0x4c,0x1d,},{0xf2,0xdc,0xfc,0x06,0xef,0x1d,0x8e,0xcc,0xd8,0xe4,0x0b,0xdf,0x01,0x30,0x7d,0xd1,0x96,0x83,0xf2,0x14,0xd4,0xf0,0x84,0xe6,0xb6,0x93,0x4f,0x63,0x72,0x78,0x30,0x0d,0xbb,0x18,0x89,0xf2,0xd3,0x7f,0x53,0xb3,0xae,0xf2,0x6f,0xbb,0x3e,0x36,0xbd,0x75,0x98,0x5f,0xa7,0xc8,0xea,0x6d,0xdf,0xfa,0x72,0xc8,0xe4,0x06,0xf2,0x4b,0xb2,0x0e,},"\x42\x4b\xdc\xf0\xb2\x56\x00\x14\x39\xd1\x69\x58\xff\xf6\x48\xcf\x7a\x86\x04\xaf\x22\xcf\xa5\xb4\x43\x31\xb4\xdc\x35\x6d\xff\x25\xcc\x05\x63\xda\x9d\x64\x01\x33\xac\xb7\x0b\x6a\x11\x76\xc4\x82\xdb\xc9\x40\x8c\xd6\x79\x3d\x56\xbc\x29\xcc\x40\x88\x23\xd3\x88\xed\x88\xb2\x4c\xeb\x66\x21\xdb\xac\x00\x23\xee\x69\xf7\x6f\x82\x96\xa7\x39\x52\x11\x68\x5b\x3c\xea\xa9\x95\xf0\x35\x5d\x9a\xad\x3d\x97\x35\x8f\x4a\x37\x9e\x59\x20\xec\x54\x5f\x46\x96\x21\xcf\x76\x8a\xbf\x55\xd2\xa5\x54\xc9\x49\xb0\xed\x70\x18\x7c\x22\x05\xad\x03\x29\x85\xc9\xb5\xb2\xe4\xba\x57\xe0\xb4\xa4\x7d\x34\x45\x12\xb8\x4b\xfe\x9f\x3a\xa5\x60\xfe\x6e\xcf\xc5\xbd\xf8\xc3\xb4\x18\x45\x29\x35\x73\xf8\x1e\xd3\xb7\x0e\xdc\x63\xa3\x0c\x70\xcd\xa3\xf4\x55\x90\x13\x13\xf6\xd2\x3d\xb3\x09\x47\x8f\x03\xe3\x4e\x71\x35\x6d\x83\xfa\x5d\xb9\x28\x0c\xc2\xb4\x36\x9c\x3d\x24\xdd\x90\x38\xf2\x47\x59\x6c\x39\x1e\x48\xb2\xf3\xf8\x90\xa1\x41\xca\x1d\x12\x07\x7c\x69\x34\x47\x35\xa5\x9b\x1d\xd4\x07\x6b\x22\xe1\x61\x89\x99\x1e\x5f\x1b\xe4\xfb\x76\x95\xaf\x90\xeb\xea\x5d\xf2\x86\x13\x5c\xec\x2a\x6e\x99\xaa\x1d\xda\x32\x8e\x62\xc0\xdf\xb6\x37\x42\x20\x2d\x63\x62\x4d\xcc\x0c\x5c\xf1\xa5\xdf\x79\xe2\x87\x8d\xbc\x71\xfa\x96\x57\x66\x01\xaf\x22\x84\x4f\x54\x57\x33\x12\x6a\xf7\xd3\x98\x4c\x3e\xd2\x52\xe6\xa8\x76\x44\x5c\x92\x25\x9f\xbb\x47\x0a\x10\x56\x9b\x49\xe5\x79\x1f\xd0\x18\x2c\xfe\x1c\x3f\x88\x29\x7f\xac\xc8\xc3\x1a\x53\x32\xf1\xf4\xeb\x49\x58\xdb\x13\xb6\xc0\x79\xaa\x9c\x94\x94\x87\x26\x34\x03\x19\x0c\x83\xc1\x1a\x43\x19\x1f\xfe\xc6\x02\x3f\xb3\x4c\xfa\xb2\x52\x5b\xeb\x54\x6c\xf9\x20\x0a\x96\xf5\x85\x4b\x2f\x78\xec\xb2\xd9\xa5\x3a\xa9\xd2\x87\xa9\x0d\x4d\x41\x0a\x63\xad\xa0\xe9\x75\xd3\x04\xd5\x14\x83\x53\x46\x3f\xa8\x05\xb4\x80\x5f\xb4\x68\x7e\xd8\x85\x7d\xfc\xe4\xbc\x6e\x80\x83\x3c\x8f\x9a\x79\xcd\x4f\x02\x9a\x2d\x80\x2b\xfd\xc8\x19\xed\x0c\x0a\xc8\xf2\x10\x23\x28\x7f\x2b\x4b\xaf\xbc\xc8\x99\x93\xfe\x46\xd5\x2a\x9c\x62\x46\xde\xad\x61\x7d\xf7\x97\xd4\x8e\xe9\x85\xf0\xf0\xdf\x9a\xa8\x2e\xa2\x0e\x0d\x0d\xb2\x8a\x25\x4a\x9a\x25\x3f\x39\xf9\xcf\x01\xe3\xdb\x8f\x3e\xbc\xf7\xcb\x97\xce\xc5\x8c\x4e\xfe\x03\x12\x69\xb4\xb3\x7e\x4c\xbb\x36\x1f\x73\xab\x4b\x49\x80\xbd\x90\x08\x49\x53\x88\x44\xc5\x2c\xb3\xac\x75\x83\xb8\xf8\x96\x53\xa0\xde\x65\xa8\xbe\x91\x58\x2c\x55\x23\x9c\xb8\xf5\xd5\x31\x8a\x88\xd1\x60\xe1\xc8\x71\xe5\xea\x7e\x75\xf5\xa6\x9c\xba\x85\x38\x22\x1a\xb4\x2c\xe2\xa2\xc4\xd9\xc3\xb7\xec\x85\x7f\x23\x0d\x57\x37\x31\x13\x36\x86\xae\x8a\x7e\xd6\x40\xf4\x2f\x31\x02\x94\x89\xe4\xe6\xaf\x2b\x3e\xa4\xc7\x94\x8e\xd5\x37\xc0\xc5\x90\x67\x26\xc2\xb6\x25\xfd\x5f\x94\x9e\x3a\x7c\xf3\xb6\xe9\x98\xec\x76\x1d\xd6\xe2\xb5\x17\x1a\x68\x74\x97\x52\xe7\x21\xb7\x88\xc3\x47\x7f\xa1\x90\xcd\x6e\xa8\x1d\x57\x9d\xce\x64\x62\xd9\xc6\x62\xad\x89\x62\xe7\x93\x38\x71\x0c\xc8\xd2\x73\x8a\x5f\xb0\x4a\xdf\xdb\x3f\x14\x32\xcf\xd8\x0e\x2e\x96\x7d\xa0\x00\xd8\x3a\x0f\xa8\x5a\xba\xe2\x95\x2f\x3f\x36\x83\xe2\x54\xd8\x68\xf4\xbf\x80\x9e\xb2\xe3\x00\xe7\xb2\x09\x73\x4a\x3c\x89\x4e\x96\x6b\x16\x08\x8d\x5e\xd3\x54\xbf\xfb\xff\xbb\xf2\xec\x2b\xe9\x3a\x32\xa8\xbe\x5c\xfa\x18\xfa\x56\x53\x01\x2e\xda\xe5\xaf\xd8\x70\x9c\xa5\x5c\x0c\xf2\x3a\x55\x0d\x34\xca\x0f\x32\xd8\xf6\x66\xfb\x47\xa1\x2f\x2b\x73\x53\xa4\x0c\x53\x79\xf7\x53\x66\xc1\x3f\x4a\xb9\xf1\x4c\xf8\x0a\x94\xe1\xf1\x3d\x8b\x09\xb7\x6f\xd8\xd1\x4f\xfa\x53\x8f\x31\xfd\x8a\xeb\x49\xd3\x34\x33\xf4\xdf\x7c\x2c\xa6\x73\x99\x57\x9f\xe9\x90\x78\xaa\x72\x1d\x6b\x6f\xc0\xc5\x0e\x8a\x91\xfc\x71\xca\x25\xea\xc1\x37\x6f\xc6\x71\xbf\x61\x53\xe7\x20\xb2\x5c\x7e\x97\xa3\xd4\xef\x84\x42\xac\x67\xac\xf5\x8b\x50\x4b\x67\x15\x8f\x91\x30\x25"}, +{{0x3c,0x39,0x3f,0x9d,0xf1,0xfb,0x0b,0x1e,0xec,0x09,0xb7,0xf2,0x70,0xb8,0x59,0x82,0xba,0x0f,0xd5,0xe4,0xb1,0x79,0x5e,0x1a,0x7f,0xa9,0x91,0x37,0xfe,0xe2,0x4d,0x7d,},{0x97,0x4f,0xe2,0x37,0x30,0xfc,0x17,0x94,0x56,0x70,0xfb,0xc1,0xf8,0x0b,0x93,0xf9,0x45,0x93,0xc8,0xd4,0x4b,0xc7,0x5d,0x18,0x9a,0x6b,0xbf,0xaa,0xba,0xf5,0xdb,0xd9,},{0x22,0x33,0x3e,0x56,0x41,0x0f,0xdc,0xbf,0x84,0xf6,0xa8,0xde,0x74,0x13,0x37,0x69,0x16,0x84,0x49,0x5b,0xa6,0x9e,0xff,0x59,0x6d,0xb9,0xc0,0x3a,0x28,0x12,0x10,0x88,0x1e,0x6c,0x91,0xef,0xa9,0x1b,0x21,0x83,0xc0,0xea,0xc9,0x16,0x15,0x28,0x17,0xa7,0x8c,0xa7,0x24,0xba,0x7c,0x8b,0x51,0xbb,0x4c,0xaa,0xde,0xa9,0xa3,0x41,0xeb,0x0e,},"\x54\xd8\xb8\xd5\xfa\xc2\x8c\xff\xa7\x7a\x09\x16\xd6\x33\x3c\x16\xed\xbc\x8b\xb7\x4a\xa0\x6e\x56\xdc\x00\xe4\x7e\x39\x29\xe4\x08\x64\xb8\x84\x0d\x91\x20\x79\x59\x7e\xac\xd8\x1d\xae\x43\xe2\x78\x5d\xfc\x68\x9f\x3e\x85\xf8\xc6\x65\x81\xef\xc5\xe8\x53\xd1\xfa\xaa\xc7\x44\x40\x0a\xb0\x8c\xbd\xb5\xd1\x61\x46\xfa\x60\xf9\x99\x05\xed\x84\xfd\x29\x36\xdd\x73\xf4\xbc\xa2\x57\x2b\x7c\xf5\x16\x05\x60\xff\xaa\x68\xda\x7a\x67\xe4\x0e\x08\xa7\xbb\x7a\xef\xc4\x04\x3e\xbe\xd5\xfe\x80\xa4\x14\x81\x7e\xdf\x2c\x63\xf6\x2f\xac\x0d\x47\x44\x6e\xd0\xbb\x58\x40\x58\xf4\x87\x2f\xec\xff\x62\x15\x59\x31\x1a\x27\x0a\xea\x37\xa6\x29\x68\x64\xe8\xd1\x68\xbf\x1e\x2f\x55\xcd\x3b\x27\x6e\xdf\xa6\x12\xb5\xd9\xc3\x36\x2e\x61\x8b\xe6\xe8\x2a\x6e\x5f\x82\x66\x79\x24\xf3\xd1\xd3\xdf\x82\x5f\x9d\x23\xf4\xd6\x14\x2d\x31\x00\xdf\xc7\x0f\x70\x60\x3a\xbf\x3f\xda\xda\xca\x69\xef\x6a\x18\xef\x90\x92\xb3\xc4\x1e\xc6\x58\xab\x27\x21\x6f\xc6\x14\x7a\x08\x0a\xcd\xa6\x0a\x84\x19\x84\xee\x83\xf4\x1a\xc4\x2a\x80\xea\xac\x91\xff\xfc\x82\x28\x39\x1e\xf5\x83\xab\x3e\xdd\xcf\x87\x65\x23\xc2\x02\x81\x35\x53\x00\xd8\x6c\x11\xa4\xe7\xc1\xad\xe8\xe5\x05\x60\xf4\x39\x06\xc9\xbc\x8c\xa5\xfb\xf8\x33\x9f\xbe\xbd\x02\xe3\x3e\x85\x18\xbe\xe5\xe8\x06\xb8\xc1\x0f\x82\x77\xf4\x10\x66\x47\x35\xa2\xbf\x55\x68\x39\x63\x54\x92\x45\x2e\x6c\xa0\x79\xde\xb9\x75\x1c\xfc\x67\x97\xf4\x9b\xca\x96\x13\xff\x2e\x7f\xdd\x36\x46\xf7\xc5\x23\x6a\x36\xbd\xf0\x05\x17\x45\xe5\x95\xdc\x00\x72\xfd\x66\x51\xd5\x76\x27\xa6\x00\x4c\x0f\x0c\xfa\xe8\x56\xbb\xc2\x8a\x12\x31\xcb\x83\x96\x65\xff\x04\x15\x2e\xc3\x1c\x00\x7b\x3e\x2e\xd0\xa9\x73\xb2\x4c\x93\x14\x9c\xe7\x01\xe6\xfd\x65\x39\x20\x6a\xe9\x1b\xec\x4c\xe6\x5a\x89\xdb\x26\xc7\xd3\x8c\xec\xb8\x91\x9f\x96\xfb\x6c\xb8\xf6\xc1\x93\x9d\x90\xfb\x3f\x90\xb8\x87\x78\x9f\x29\x57\x5a\xb2\x0e\x0b\x08\xbc\x35\x81\x53\xd8\xc0\x35\x21\xdc\x89\x18\x70\xb5\xf7\xee\xdc\xc1\xe6\x2b\xee\x7d\xa0\x63\xae\x66\xff\x0a\x4b\x7d\x98\xd1\xcb\x75\x8f\x69\x74\x3c\x3d\xb3\xae\x2a\x2c\x9b\xe1\xbe\x09\x4f\x17\xcd\x28\xf9\x2d\x8c\xcb\xca\x98\x3c\x74\x9c\x75\xc6\x10\xf8\x40\x83\x6e\x2c\x43\x0c\xcd\xef\xf0\xaf\xa5\x44\x44\xf1\x2b\x4a\x4f\x00\x2c\x60\x94\x51\x83\x42\x44\xc0\xc0\x7d\xf8\xe1\x22\x02\xa6\x5f\x94\x44\x7c\xd4\x90\x3a\xcb\x60\x6d\x77\x25\xa8\x6e\x4a\x23\x43\x98\x4e\x67\x9c\x4a\xf1\xb3\x67\x9c\x75\x5e\xa5\x0d\x0a\xbe\x2f\xcc\x0c\x1c\x33\x51\xa9\xee\x19\x6b\x46\x44\xc4\x24\x22\x2b\xe9\x9e\x2f\xb3\x73\xf9\x64\x1e\x3f\xae\xbf\xf4\x31\x70\xeb\x03\xfb\x8e\xc4\x55\x7d\x15\x1a\x55\xfa\xb6\xc4\x99\xd4\x44\xc8\x4b\xe8\x9f\x24\x47\x68\x2d\xe4\xe6\xf6\x35\x34\x75\xef\xcb\x8f\xc5\x32\x56\x76\x3a\x94\x8d\xc7\x5c\x51\x5f\xa3\x53\x54\x5d\x0c\xba\xd2\x9d\xf5\xe9\xdb\x5c\xc4\x57\xed\x30\x86\xcf\xfb\x3d\x75\xe8\x46\xc4\xe8\xd8\x81\x47\xfc\xd0\xd8\xaa\x5a\xba\xb4\x9b\x5e\x05\xc3\xd7\xfe\xef\x63\x79\x43\x34\x7a\xd3\xf4\x92\xee\x35\x6e\xf3\x48\x81\xcf\xd8\x5a\xbc\xe8\xa1\x44\xce\x77\x61\xe2\x84\xe8\xb8\xcb\x08\x96\x60\x49\x04\x7a\x99\x6e\x23\x55\x9f\x77\x6b\x1a\x9f\x41\xcb\xa3\x95\x41\x08\x48\x6e\x29\x27\xbe\xb6\x43\x3a\x36\xff\x8b\x2f\x03\xaa\x74\xb3\xd2\x09\xc4\x88\xe0\x77\xf9\x24\xf2\x31\xe2\x83\x45\x94\x2c\x7d\xcc\x2e\x61\xd7\xc9\xb5\x22\xb6\x59\xfc\xb5\x36\x62\xaf\xf3\x64\x8f\x66\xda\x3e\x83\xe5\x9b\x0d\xaa\x90\xb9\x4c\x51\x5d\xad\xab\x10\xd5\xa8\x39\xcb\x3a\x2f\x1d\x3c\xd0\x92\xde\x55\xd9\x95\x13\x8c\x3a\xc0\xb9\x07\xaf\x15\xac\x63\xec\x18\x74\x11\x43\x27\xe2\x19\x71\x34\x5e\xf1\x70\x31\xd5\x26\x17\xe7\x84\xda\x37\x71\x43\x9b\xe2\xe8\x41\x48\xbc\xfe\xa1\x32\xbd\xe1\x0e\x6f\xda\x54\x7d\xcb\xb1\xc4\xd8\xf7\x4d\xdc\xe1\xfc\xcf\x82\x13\xe0\xda\x6e\x97\xb8\x1f\x75"}, +{{0xf8,0x66,0x9c,0x88,0xf1,0x68,0x5b,0xbf,0x04,0x80,0xcc,0x92,0x21,0xac,0x2e,0xad,0x8f,0x55,0x1b,0xfa,0x87,0xec,0xba,0x2f,0xd4,0xdd,0xf3,0xba,0x34,0x76,0xeb,0xda,},{0x34,0x72,0x3f,0xb8,0xe2,0x53,0xad,0x9c,0x71,0xce,0xfd,0xe0,0x36,0x28,0xd2,0x04,0xe5,0x35,0xde,0x47,0x9e,0x10,0x48,0xe5,0x18,0x87,0x62,0xa1,0xf3,0x37,0xfe,0x5f,},{0x37,0x46,0xda,0x6c,0xd8,0xca,0x10,0x8b,0xee,0xf0,0x64,0x87,0xbe,0xe6,0x35,0x84,0xf8,0x12,0xc8,0xe0,0x69,0x5f,0xc8,0x63,0xb8,0x6e,0x5d,0xb1,0x32,0x38,0x0b,0x62,0xff,0x85,0x44,0xf6,0xf3,0x74,0x82,0x5b,0x0e,0x3e,0xa0,0x62,0x0e,0xf8,0x54,0xc1,0x33,0x11,0x14,0xd6,0x67,0xdf,0x1f,0x9e,0xa7,0x76,0xc3,0x96,0x38,0x70,0x29,0x0d,},"\x5b\x49\x41\xbe\xec\x22\x41\xc9\xfb\x76\xd8\x48\x4f\x4f\x3f\x3a\xb4\xff\xe8\xec\xc8\xe7\xae\xc7\x6d\xe2\xab\x8c\x36\x85\x84\xd7\x51\xb0\xd3\xfe\xb8\xa1\xdc\x81\x68\xcd\xc6\x94\x96\x8f\x66\xb2\xa0\xb0\x52\xaf\xbf\x8b\xe3\xa7\xd9\x51\x63\xe9\xda\x91\x41\xc5\x9c\xa5\x59\x76\xc2\x92\xc5\xc7\x4d\x31\x31\x8d\x6a\x91\xe7\x81\x7c\x5a\x8b\x2f\x81\x21\x18\xcb\xeb\xa3\xa1\x33\x23\xcd\x97\x48\xbf\x86\xed\x1a\x85\xdd\x4e\xbc\x0d\xf4\x95\xcf\xa3\xd4\x62\x74\x34\xbf\x14\xaa\xe8\xab\x67\x81\x46\x7a\x56\xd9\x65\xd1\x0e\x63\x71\x98\x9d\xfa\x0f\x6b\xc0\xf7\x85\x9f\x37\x71\xeb\x90\x04\xb3\x43\x67\xdb\x27\x05\xdb\xd6\x0f\xa8\xf7\x89\x5c\x1e\xad\xf5\x9f\x53\xda\xb1\x68\xb4\xf9\x36\x39\x79\x02\x55\x01\xdd\xd9\x68\x0d\xeb\xc0\x7c\xd1\xca\x4a\x09\x97\x87\x6e\x92\x11\xf3\x07\xd9\xb7\xb9\xd9\x04\xe4\x8d\x28\x61\xa7\x78\xb8\x79\xad\x59\x0a\x9a\x2f\x14\x1b\xd5\x68\xe3\xa1\xbb\x24\x94\x62\x8e\x9e\xc0\xc6\x42\x55\xae\xea\x6f\x0e\xed\xca\x30\xad\x38\xa1\xf3\xff\xec\x3b\x2b\x5e\x94\x2e\x21\x94\x01\x04\xe9\x14\xd1\x1a\x44\xc0\x0f\xdd\x47\xda\x3e\x55\x13\xaa\x85\x30\xae\xe2\x47\xc9\x5c\xa6\x6d\x08\xa2\x60\x8c\x75\xba\x98\x58\xda\x14\xf9\xa8\xa3\x2b\xe7\x13\xd3\x09\xe0\xf5\x84\xc8\x1e\xf5\xbe\x04\x0e\x00\x65\xf0\x7b\x77\x5a\xe1\x75\xdf\xe2\xc8\xb9\x0a\x88\xcc\xda\x17\xfa\x4f\x21\xc7\x7e\xad\xf5\xd2\x5b\x6e\x40\x4b\xf0\x04\x47\x9e\x05\xa0\x1a\xc0\x04\x2b\x89\x93\x7e\xb2\x78\xc1\xc3\x4f\x33\x02\x8d\xb7\x80\xba\x3b\x61\x79\x18\x59\x5a\x39\xc0\xfc\xad\x67\x4b\x85\xc4\x0c\xac\x8d\x34\x5b\x7c\xa0\xbb\x48\xa2\x8e\x66\xc4\x4d\x8b\xb5\xf2\x79\x41\xe4\x0b\x0e\x9c\x70\x97\x97\x6c\x62\xdf\xef\x50\xc9\x8f\x17\x56\x6c\xcb\xac\xc8\x7c\xb0\x3b\x94\xdf\xdf\xaf\x32\xf1\xe5\x6f\xfa\x63\x9d\x63\x61\x1e\x21\x3c\xeb\xf5\x4c\xd0\xa3\xe2\x17\x2d\x81\x1c\x0e\xbd\x75\xb1\xa8\x64\x62\x64\xdd\x8b\x1a\xbd\x46\xe5\x48\x97\x2a\x1b\x26\x2c\xd9\x5d\x51\x15\x36\xdd\xdc\xb4\x97\x29\xfe\x7b\xd0\x0b\x38\x38\xbd\x2f\x20\xa1\x42\x64\x0e\xdb\x1b\x6e\x76\x5b\x65\xda\x72\xe7\x23\x32\x61\xc8\x89\x2e\x2f\x49\x49\xbb\x51\xf3\x2a\x1a\x5a\x3e\xe1\x49\xbe\xa2\x6f\xdc\xed\xb9\x91\xd2\xcd\x12\x66\x37\xe2\x97\x1e\x9b\x6f\x0b\x78\x5d\xf2\x8a\x48\xf3\x01\x70\x73\x49\x42\x3f\x44\xe8\x46\x22\x89\xd7\x25\x49\x82\x30\x48\x9d\xf1\xb5\x1b\xe3\x0f\x08\xd7\xe3\x25\x05\x65\xc6\xef\x82\x4b\xc5\x3a\x1b\xa7\x4a\x57\xa2\x5c\x06\x86\xad\xcb\x6c\x82\x5a\xb1\xca\x70\xc8\xa5\xd4\x6d\xbb\xc6\xfa\x60\x74\x61\xe2\x6d\x16\xfe\x93\xbb\x3d\x3a\x94\x3a\x3d\xc0\x5f\x30\xea\x6d\xc8\xbb\x12\xd7\x08\x21\xd3\x20\xf1\xad\xf1\xce\xba\x4b\xe6\x57\x19\x4f\x7f\xcc\xd2\x19\x90\xf8\x62\x9d\x74\x46\x01\xcf\x52\xea\x6d\x94\x05\xaa\xa2\x87\x8f\x1e\xec\x40\x03\xb4\x5a\x42\x18\xd8\xf8\x0b\xb0\xf5\xaf\x04\x73\x26\x48\x77\x52\xe2\xb7\x6d\x68\x87\x25\x20\xbb\xea\xe7\xb3\x09\xd7\x82\x82\xa0\x73\xfe\x0b\x1a\x1a\x7a\x98\xda\x23\xdf\x68\xca\xf8\xc2\x69\x9b\x1c\x7d\x0f\x47\xbd\x7d\xe2\xc0\xbb\x23\x36\x99\x63\xe6\x8a\x69\x74\xc8\xe2\xb5\x95\xb8\x29\x3a\x9f\x4d\x98\xdf\x7e\x9a\xe3\xad\xd2\xa3\xf6\x4e\x83\x03\x97\x39\x64\x2d\x19\x22\x04\xe8\x5e\x6c\x48\xd5\xd6\x71\xf6\xc7\x5a\x0a\x89\x57\xed\xbb\x74\x18\x76\x20\xf2\xab\xa9\x9c\x1c\x62\x58\x4c\x59\xac\x00\x64\x7e\x3f\xb4\x02\x92\xb9\xdc\x1a\x33\x46\x86\x85\x53\x39\x2f\xd3\xf1\x1d\x6d\xc6\xf5\xf2\xf4\xe8\x5e\xe2\x51\x25\xcd\xd6\x44\x74\x3c\x7d\x45\x28\x1e\xda\xc6\x38\x4c\x77\xcb\x98\xa6\x7d\x9a\xe6\xfc\x9a\x0a\x76\xb9\xf6\xfa\x69\x6f\xdf\x4a\xce\xab\x5f\x79\x4e\xe5\x21\xb1\xe5\xa0\xee\x57\xaf\x53\xbd\xf1\x76\x80\x1b\x4f\x45\xcf\xb3\xca\xe3\x28\x72\x34\x23\x4b\x77\xce\x21\xed\xf8\x68\x0d\x68\xc4\xa8\xee\xcf\x1b\x03\x53\x7e\xa5\x69\x9a\xcb\x56\x27\x77\xe4\x2a\x48\x6f\xe7\xcd"}, +{{0xce,0xcc,0xc6,0x83,0x11,0xfc,0x45,0xb6,0xc2,0xa2,0xf1,0xff,0x9c,0xdd,0xe0,0x07,0xec,0x78,0x7f,0xdf,0x25,0xd0,0x2c,0xcd,0x2a,0x1c,0xad,0x9d,0xe3,0xfb,0x4c,0xff,},{0x6f,0x80,0x47,0x34,0xef,0x92,0x82,0x41,0x80,0xda,0x71,0xe5,0x5c,0xf3,0xbf,0x1a,0xfe,0xf6,0x5b,0xcf,0x56,0x09,0x62,0xe0,0xb0,0xac,0xbb,0x2d,0x8c,0xca,0x59,0x84,},{0x3c,0x44,0x62,0xaa,0x47,0x01,0x01,0x32,0xdb,0xb2,0x63,0x11,0xe4,0x44,0x72,0x72,0x79,0xed,0xad,0xe1,0x5a,0x4d,0x66,0x2c,0xf6,0x47,0xf3,0x27,0x5c,0xf3,0x25,0x3e,0x6d,0xe9,0x33,0x38,0x30,0xe0,0x51,0x7a,0xa5,0xfa,0x7b,0xc2,0xd0,0xe6,0x3e,0xa2,0x59,0x7a,0x94,0xb0,0xfe,0x92,0x70,0x6e,0xcd,0x17,0x2c,0x5e,0xc5,0xc7,0xf0,0x06,},"\xba\xc1\x86\xd9\xfe\x5a\xbd\xa7\x9c\x3a\x35\xa7\xa3\xc2\xea\xe6\xae\x6a\xb2\x82\x47\x91\x27\x70\xc8\x4e\xfd\x04\x8e\xbd\x3a\xba\x57\xc3\x7c\xf4\xc6\xc7\xf3\x0a\x79\xf6\x8a\x3f\x76\xb2\x0c\xd8\xc6\x63\x1f\xcc\x96\x67\x05\x22\x08\x0e\x6b\x62\xe8\x87\xae\x6f\x44\x36\xd4\xca\xf5\x69\x43\x13\x1c\x52\xdd\x28\x2b\x25\x1c\xd0\x75\xf1\xf7\xf8\xe0\xbd\xb6\xbe\xdf\xc9\xa0\x79\x6f\x55\x79\x04\x2b\x56\xe6\x93\x74\x96\x1b\x11\xdf\xd6\x1b\x12\xde\x2b\xb7\xd4\x9b\xfc\x50\x9c\xdb\x31\x38\xf3\x35\x6a\x0d\xde\xd9\x8f\x53\x01\xb7\xc4\xa7\x48\xbf\x89\xb2\x3d\xf4\xf7\x47\x2f\xf8\xb1\xf5\x05\xd7\x65\xc6\xff\x82\xdb\xad\x74\xb9\xd7\xae\xf2\x2f\xbc\xca\x0b\x7f\x35\x04\x2f\x9a\x76\x2b\xd0\x69\x02\xbb\x21\xc7\xf9\xf7\xf6\x6b\xef\x38\x90\x1d\x75\x01\x2d\x61\xd7\x44\xde\xe7\xaf\xd8\x9f\xc7\xe9\x08\xc4\x06\x85\xbd\x44\x0a\xed\xa4\x20\x4d\x00\x6f\x26\x30\x7d\x82\xa4\x96\x96\x31\x15\xf9\x0e\x09\xf7\x66\x88\x29\x1f\x4a\x67\xd6\x41\x1f\x76\xd1\x66\x17\x87\x5b\x2b\x99\x82\xdf\xdc\x5e\xe9\xb8\x3b\x98\x17\x00\x93\x19\x11\x0b\x54\x04\xc6\x31\x16\xfb\x6e\x94\x64\x84\x6f\xa0\x09\x55\x56\x32\xf0\x76\x98\x4c\x15\xe1\xf6\x08\x17\x33\xa0\xd4\x6f\x2d\x6a\x3c\xeb\xf7\x9e\xd9\x02\x0c\x9d\xec\x8d\xf1\x58\xa3\x34\x1f\x39\xea\xa5\xfc\xf1\xcf\x42\xa9\x48\x49\xb2\x35\x2c\x1a\x1e\xcd\x4f\xb8\x14\xc2\x0d\x07\xdf\xda\x31\x2b\xd4\xf2\xf5\x8c\x15\x76\xb4\xaa\x31\x5c\x96\xc8\x78\x6a\x4c\xfb\xb7\x36\xb2\xd2\x3c\x38\xb1\xd8\x1c\x46\x44\xea\x36\xaf\xa0\x76\xe0\x55\xbe\x59\x17\xcd\x7a\x92\x35\x0a\x7e\xd6\x6a\x5a\xb2\x25\x3f\x55\xc4\xfd\x1a\x0d\x0e\x6d\x4e\xda\xb5\xf7\x12\xed\xb4\x40\xc0\x6f\xac\x8f\x07\xe6\xd7\x3c\xc9\x0b\x2b\xa7\x13\xd7\x3c\x73\x80\x23\x61\xce\x46\xa4\xeb\x5e\xd1\x06\x0c\x4c\xf5\x32\x07\xd3\x01\xf0\xfc\xd4\xf0\xc9\xd1\x58\x0d\xb2\xfc\x10\x59\xd3\x72\x07\x64\x38\xa0\x11\x92\xa7\xf9\xfd\x6f\x78\x83\xf5\x64\x22\x86\x6f\xd9\xf0\xaf\xe5\x3f\xdc\x91\x0a\xfa\x5a\x75\x1c\xbf\xa3\x77\x59\x25\x79\x16\x5c\xb5\x6d\xc3\xeb\x4d\xce\x67\xe3\xdb\x33\xa9\x81\xa5\x6b\x7d\x9f\x7b\xde\xa7\x4f\xba\xea\x34\x78\xe6\xab\x2c\x64\x4f\xd7\x77\xb8\xbf\xa7\x2a\xa0\xf0\xa5\x21\x98\xd3\x6e\x5b\x63\x4d\x2c\x9a\x11\xb7\xfe\x0a\xb2\xf9\xa4\x09\x01\xc5\xb1\x48\xa0\x19\x2e\x95\xa1\x70\xba\xf7\xd5\x35\x0f\xe0\x1e\x56\x95\x42\xb9\x34\x85\xa4\x19\x71\x44\x34\x85\xfa\xf5\x7f\x67\xf5\x6d\xfe\x2c\x58\xe5\x39\xc9\xf9\xb4\x49\xc3\xf9\x12\x49\xa1\x0c\x1a\x1b\xe7\xe0\xb3\xea\xbe\x8e\xe0\xba\xb1\xf1\x1f\x89\x61\x4d\xce\xd4\x18\xc6\x2a\x07\xa0\xb5\x9a\x13\x70\xd6\x53\x1b\xa1\x77\x09\x1c\x6a\xd5\x95\xfb\x59\x48\x82\x04\xf6\x33\x44\x73\x6e\xa1\x01\x7a\xff\xbe\xb7\x53\xa9\x97\x86\xb1\xeb\x64\x51\x0e\x2e\x71\x7e\xc9\x0e\x02\x74\x4b\xc3\x52\xd3\xf1\xb2\xab\x7b\xe0\xeb\x65\x62\x3d\x04\xfb\x3a\x04\x6c\xe7\xf4\xda\x69\x7d\x82\x98\x28\xa5\x2c\x7b\x04\x3b\x2a\x82\xec\x97\xfb\x04\x1b\xf5\x19\xb4\xde\x31\x6f\x4e\x2f\x5b\x0d\xb6\x2a\xed\x0e\xed\x95\xca\xd4\x32\x0c\x19\x47\xc3\x5f\xd8\x84\x7a\x58\x67\x87\x28\x83\x56\x11\x19\xc0\x1b\x00\x89\x21\x3d\x84\xdb\x99\xd4\x39\xf0\xf6\x44\x4d\x87\x83\xdd\x4b\x64\xbe\x35\x77\xcd\x46\x1c\xf7\x53\xc8\xe6\x1c\x91\x2d\xe2\xe5\xd7\xa7\xe2\xba\xef\xa2\x58\x97\x5d\x16\xef\x31\x17\xda\x59\xa6\xc8\x93\xf3\x33\x91\x87\xdf\x31\x68\xb8\x9f\x0f\xb0\xb2\x19\x8b\xb6\xf1\x59\x4b\xb8\x8f\x3d\x61\x0f\xce\xc3\xe3\x6d\xe0\x4a\xe1\x03\x28\x11\x2e\x6f\xf7\x4f\x5a\x8c\xe6\x8d\x40\x71\x74\xb4\xc0\x69\x1c\x76\x02\xea\xb1\xbb\x10\xf3\xc4\x9d\xd2\x2b\x84\x50\x78\x2d\xea\xe9\xa7\x31\x5e\x3b\x88\xde\x79\xcd\x15\xe6\xc9\x26\x81\x65\xed\x3a\x0f\xb3\xf8\x9b\x18\x3e\x1a\x21\x21\x52\x00\x3f\x32\xa2\x66\x5d\x37\xcd\xd7\xf6\xb5\x6c\x24\x53\xe5\x58\x0c\x4d\x21\xf9\x98\x3f\x38\x79\x8e\x9b"}, +{{0x7b,0x30,0xb4,0x2d,0xc2,0xc6,0x70,0xa1,0x95,0xfe,0x2a,0xf8,0x79,0xfc,0x5d,0xe3,0x74,0x02,0x45,0x88,0xfe,0x3d,0xe4,0x3e,0x2d,0xd5,0x08,0x44,0xf4,0x8f,0x42,0xbe,},{0x82,0xa2,0xac,0x60,0x79,0xf2,0x12,0xb5,0xee,0xdd,0x0c,0x19,0xe9,0x39,0x4f,0xaf,0xac,0xd7,0x4d,0x71,0x6f,0xde,0xfb,0xfc,0x6c,0xb8,0xa7,0xea,0xf4,0x1c,0x03,0x62,},{0x0a,0x63,0xb8,0x4f,0x46,0x93,0x5f,0xaf,0x3e,0xa1,0x64,0xb0,0x0a,0xf2,0x27,0xb0,0x08,0x68,0xa0,0x3f,0x56,0x12,0x93,0x5e,0x18,0x61,0x9a,0x84,0xa2,0xe5,0x7b,0x88,0x51,0xd7,0x46,0xe6,0x3f,0xd9,0x10,0x07,0x87,0xf5,0x33,0x8d,0x51,0xc1,0x07,0x3c,0x2f,0xc5,0x30,0x30,0x99,0xe1,0x87,0x3e,0x5e,0x3d,0x3e,0x5c,0x03,0x6f,0xbe,0x01,},"\xc6\x68\x7a\xef\xeb\xc5\xc8\x16\xd1\xa3\x34\x53\xbe\xca\x50\x20\xd3\xa9\x7c\xda\x1d\xac\x56\x62\xf0\xaf\x72\xba\xd4\x44\xe2\xfd\x11\x76\xa7\xb0\x4c\x1b\xd0\x9d\x83\x26\x18\x20\x9b\xf3\xe3\x3e\x52\x35\x38\xd6\xda\xa7\x53\x04\x6e\x87\x1d\xd3\xb3\xc7\xac\xad\x33\xe7\x9c\x1b\xb7\x89\x64\x07\x86\x5d\x16\x8d\x4b\xc3\x75\x7b\xde\x4f\x82\x3c\x08\x77\x86\x26\xf8\xc7\x1f\xb7\xcf\xcf\xdf\x03\xa8\x24\x97\xbd\x8b\xe7\xd8\xf8\xef\x64\x90\x30\xb5\xf3\x6a\x33\x94\x59\x96\x8e\x24\x6a\x1e\x42\x08\x53\xda\xce\x41\xca\x85\x0a\x4e\xea\xe8\x34\xae\x11\x96\x10\xca\x4c\xd0\x66\x2a\xac\x39\x62\x15\x86\x99\x80\x27\xef\x2f\x61\x48\x5c\x02\x85\x06\x71\x4a\xe0\x9c\x76\x39\x9d\x87\x3e\x80\x81\x58\x57\x8a\xa5\x9e\x82\x12\xf5\x88\x65\x31\x9f\x9e\x0d\x2b\x8d\xa7\xad\x52\x9e\x0a\xc1\xf1\xeb\x43\x5a\xec\xfd\x35\xf5\xab\xb9\x2b\xea\x50\x73\x49\x6b\xf4\xc0\xbf\x15\xba\xa2\x73\xbf\xc5\xc3\x10\x44\x74\xa2\xdc\xf1\x32\xc3\x33\xeb\x36\xec\x2c\xbf\x04\xfa\x95\x80\xb7\x68\xf5\xce\xa7\xb5\x61\x7e\x58\x80\xaf\xf6\x32\x01\xc2\x74\xd6\x69\x74\x3e\x1b\xc5\x56\xb0\x67\x90\x2e\xee\x29\xd2\x91\x11\x28\x89\x69\xcf\xfa\x87\x9f\xc9\xcb\xf6\x6f\xbf\x93\x26\xd9\xd9\x25\xac\x41\x02\xfa\x9f\x1a\x06\x08\x1a\xde\xc0\x79\xcb\xc9\x67\x46\xd7\x9b\x63\xa0\x12\xed\x77\xd8\x2c\x9f\xfd\x4e\x3f\x16\x1f\x6c\xea\x28\xcc\x23\xfa\xc2\xa5\x43\xf5\xb1\xd0\x64\x4e\xc0\x48\x38\x32\x7b\xcc\x65\x2b\x85\x8f\x93\xff\x46\x3f\x7e\x94\x9e\xec\x8c\x9d\xb6\x56\x9a\x86\x98\x4f\x83\x1d\xf6\xac\x6d\x95\xf3\x8f\x46\xce\xbb\x6e\x65\x83\x65\x7f\xac\xd2\x10\x8d\xbc\xd0\xaf\x23\xab\x01\x01\xa1\x30\x1b\xeb\x48\xa4\x4c\xac\xcb\x91\x09\x44\x73\xd7\xe5\xa5\xc8\x8c\x64\x4f\xd3\x42\x05\x73\xb6\x78\xf1\x7b\x51\x74\xcb\x14\xe9\x0f\xac\x69\x4d\x1d\xbc\x6c\x96\x32\xb5\x97\x4a\xef\x28\xac\x08\xd7\x20\xb2\xea\x30\x44\x0d\x2a\xfb\x04\x93\xb4\x0d\xb2\x4e\xfb\xdb\xf5\x3c\x43\x09\x21\xe5\x2a\x10\xb5\x46\x61\xe1\x49\xd1\x65\x59\x1a\x7c\xf9\x1d\x65\x08\xea\x47\x2f\xb3\xbe\x16\x39\x5e\x30\x31\x2f\x19\xb8\x7c\x47\xe4\x68\x04\xa0\xfa\x29\xb5\x6b\x5a\xc9\x50\x67\x7b\xc6\x02\x38\xb5\xe9\x9e\x03\x0b\x1e\x55\x21\x46\xa0\xe8\x8c\x29\x4c\xfc\xa8\x35\xc1\x01\xc5\x5f\x34\x23\x87\x4c\xc1\x28\x75\x6e\x73\xa5\xde\xbe\x8e\x97\xfe\x21\x66\xb6\x5c\xb4\x46\x42\x77\x0c\x6d\x1d\x23\x90\xaf\x1b\x0f\x31\xb9\x58\xc8\x30\xe9\xac\x4f\xe2\xf5\xad\x59\x05\x82\xfb\xb8\x92\xbf\x94\x95\x84\x47\x7e\xf7\xbd\xe2\x3f\x7d\xd0\x2b\x63\xf7\xc2\x90\x88\xa5\x72\x51\x00\x91\x32\xff\xbb\x78\xed\x14\xde\xfb\xef\xd9\xfd\x31\xfd\xca\xb0\x3b\xa8\x0a\x23\xf3\x33\x98\x37\x60\xab\xad\x4f\x16\xdd\xf9\xdd\x44\x14\xf0\x4d\x00\xdb\x56\xba\x72\xd6\x3a\x3a\x13\xd2\xc4\x42\xf5\x49\xfd\x66\xc9\x88\xd2\xe4\x60\x1d\x13\xb5\x2f\x77\x50\x0d\xd6\x92\xbe\xc9\xd6\xbd\x3b\xaf\xa9\x24\x2f\xdc\xfa\xeb\x69\xb9\x8b\x0b\x57\x89\xb2\x80\x38\x40\xde\xc6\x37\xb4\x9a\xf4\x38\x1a\xe3\xfa\x42\x9f\xb5\x34\x61\xa0\xc6\x74\xeb\x5a\xa1\x8d\xbd\x60\x7a\x2b\x77\xa9\x6d\x3a\xb4\x64\xec\xd9\x74\x92\xf6\xde\x46\x0c\x9f\x11\xb5\xc1\x75\x6c\xb5\x9c\xb1\x34\x8d\xfd\x77\x95\x6b\x71\x90\x7c\x54\x82\x1e\x30\x3c\xb8\xb1\x49\x06\xc0\x03\xe3\x48\x4b\xe4\xea\x05\xa6\x90\x1d\x69\xb0\x74\x85\xe8\x58\xf7\xb4\x71\xc6\x35\xf9\x03\x95\xb9\xa3\xe2\x24\x7f\x1a\xd1\x2b\x11\x8f\xfa\xfc\x72\x21\xa5\x7b\x10\xe3\x19\xb6\x1a\xf1\xc1\x36\x06\xa8\x16\x16\xce\x3f\x1d\x62\xba\x93\x2f\xf4\xe6\x3e\x74\xb8\x42\x55\xe3\xaf\x52\x10\xbb\xd5\x71\xbd\xa4\x4c\xbf\x44\xb7\x14\x42\x2c\xb4\x5c\x2e\xf2\x1f\x98\x13\x1b\xa9\x6b\x7e\xdb\x9b\x03\xe3\x3d\x7d\x18\x8d\x5b\x8d\x90\x4c\xb4\x13\x6f\xe2\x69\xdb\x14\x69\x88\x16\x8e\x7e\xe2\x45\x35\x63\x54\xf0\x02\xa5\xea\x8b\x35\xa3\xa9\x9e\x83\xa1\x32\x72\x27\x41\x44\xb3\x3a\x60\xca"}, +{{0x66,0x56,0xf4,0xd4,0x71,0x81,0x57,0xc4,0xba,0xc3,0x8f,0xf7,0xab,0xe5,0xeb,0x1f,0x81,0x2c,0x0b,0x98,0x6d,0x9c,0x01,0x4a,0xba,0xd5,0xb0,0x9a,0xa6,0xc8,0xee,0x4a,},{0xf3,0x08,0x78,0x98,0xe4,0x52,0xbe,0x9e,0x30,0xae,0xcc,0x4e,0x8f,0xfe,0x0c,0x01,0x16,0x98,0x88,0x68,0x3f,0x62,0xa4,0x5b,0x8d,0xa3,0x82,0x99,0x01,0x4f,0x5b,0x4a,},{0x9c,0x2c,0x39,0x91,0x5a,0xed,0x6a,0xdd,0x00,0x4e,0x7d,0xd6,0x84,0xee,0x3d,0xcd,0xd1,0x0d,0x87,0xa4,0x87,0xf6,0x77,0xe7,0x3c,0x2b,0xce,0x0f,0xca,0x7d,0x50,0x87,0x96,0x46,0x41,0x50,0xa5,0x2a,0x44,0x0f,0x52,0x37,0x85,0x0a,0x00,0x9c,0x72,0x16,0x2d,0x9d,0x29,0x85,0x47,0x0a,0x33,0x49,0x0e,0x66,0xd3,0xc4,0x01,0x70,0x4c,0x05,},"\x94\xd9\xe5\xe5\xa7\xb7\x05\xd9\xd9\x76\xfe\x71\xe9\x4d\x3f\x7f\xa7\x86\x6a\xfb\xf7\xec\xe4\x24\xf1\x36\x32\x77\x99\xb2\xb2\x06\xce\x4e\xf4\xc3\xf3\xe7\x05\x55\x3a\xfc\x8f\xd5\xc1\x95\x2a\x4c\x16\x65\x8d\x4a\x78\xaf\xbb\x9a\x97\xf2\x71\x93\xc6\x5b\x65\xb8\x2e\x8f\x3b\x71\x51\x5f\xac\x82\x64\x0e\x0f\x8a\x5f\xb3\x5a\xe6\xfc\x6a\x3d\xb0\x51\xa2\x2d\x4a\x53\x00\x41\x3e\x6e\x33\xd1\x9c\x20\x13\xc2\x98\x3a\xca\x8a\xd6\xce\xc2\xce\x64\xa8\x14\x16\x4f\x06\x1a\x1a\x3c\x5a\x86\x10\xa7\x65\x0b\xfb\x54\x23\xd4\x36\x2c\xe0\x22\x06\xdb\xe4\xa6\xfa\x82\x6f\x03\xb4\x2a\xc3\xcd\x9e\xa4\xc6\x51\x40\x1b\x3c\xea\x82\xc3\x99\x3f\x6a\xf8\xb2\xc9\xe2\xe6\xff\xe6\x92\x80\xab\x3f\x09\xfb\xe9\x0d\xd5\x47\xcc\xda\x9d\x9e\x8e\x8a\x53\x7b\x3b\x36\x05\x54\x22\x7e\xd0\x70\x9f\x29\x31\x98\x98\x2e\xfb\x5e\xfb\x0e\x73\xe0\x00\x42\xd1\xa0\x63\xb5\x74\x52\x02\x7d\xce\x1a\x39\xe4\xb0\x06\x8f\x58\xb1\x11\xec\x5d\xc1\x42\xbf\x41\x9a\xd8\x93\xd5\x4f\x42\x60\xcb\xde\x76\x28\xf7\x83\xde\x84\x96\x38\x03\x06\xa4\xef\xf6\xd8\x28\x69\x10\x42\x59\xc9\x4c\x54\xad\x5a\xa8\xb0\x67\xc4\x24\x96\xcb\x88\xdd\x31\x15\x0e\xa0\x4d\x49\x9b\xfa\xc9\x1f\x4b\xb3\xe6\x8a\xf5\xaf\x7a\x56\x8a\x3e\x4c\xe7\xf1\x70\xd9\x86\x01\x16\x3f\x49\x52\xf1\xd2\x5e\x12\xe0\x0e\xf0\xa2\xd8\xf1\x11\xaf\xdb\x0f\xaf\xba\xd2\xbf\x8e\x8b\x9d\x49\x36\x3f\xca\x68\x18\x36\x17\xb5\x41\x27\x0d\xda\x46\x09\xb2\x61\x67\x29\xab\x1b\x8c\x42\xdb\xdd\x7b\xf9\x86\xaf\x8f\xba\x52\xe7\x33\xe4\x2b\xa0\x3c\x89\x2e\x1e\x1e\xc0\x6a\x90\xb1\x63\xf5\xa7\x9f\x61\x65\xeb\x73\x16\x97\x2a\xc1\xad\xbf\xcf\x1d\xca\xb0\x78\x47\xef\x82\xc2\xca\xb1\x01\x5d\xbb\x50\xaa\xdc\x79\xfe\x11\xc8\x32\x09\x8c\xac\xc3\x98\x20\xab\x08\x5b\x69\x63\xbd\x42\x16\x0e\xd6\x61\x3b\xae\x5e\x20\x1f\x17\xc0\xfd\x7f\x32\x35\x7a\xe3\x50\xce\x9c\xbb\xe9\x26\xfa\x42\xdc\xbd\x42\x2a\xc1\xbf\x09\xa1\x9a\xd1\xf6\x94\x69\xe4\xd1\xdc\xb1\x24\x11\x8e\xd4\x52\x2d\x35\x3c\x17\x42\x98\x65\x0f\xf8\x83\x82\xfa\x2f\xdb\xb2\x86\xc4\x5b\x18\xa9\xba\xf6\xf6\x76\x3a\xc2\x0c\x9c\xa4\x76\x7d\x34\x8c\x4b\x8d\xed\x63\x00\x76\x65\x7b\x85\xb1\x4c\x11\xae\x27\x37\xea\x29\xa4\x35\x15\xb7\xf0\x56\x74\xa0\xcd\x3e\xd4\xbf\x6a\x3d\x18\x9a\xe9\x72\x21\x8f\x87\x7c\xd8\xaa\x69\x49\x9d\x5a\x08\xc9\x9e\x44\x06\x94\xcc\xac\xcd\xf1\xf6\x42\xe1\x4e\x90\x10\x5b\xee\x6d\x98\xed\xee\xab\x3b\x4f\x33\x9f\x30\x01\x88\xae\xc0\xc1\x6b\xd6\x45\x21\xd9\x28\x73\x98\xe6\x48\xdb\x94\x33\x0e\xd8\xf6\xb9\xab\x6c\x7a\xd9\x3f\xfc\x43\xe8\x79\x2e\x63\x7c\x61\xbf\xf7\xd8\x56\xe5\x4e\xf4\x98\x73\x84\xe3\x12\xcb\x57\x01\x7a\x50\xea\xe5\x95\x2a\xbe\x19\xd8\x99\x9c\x8c\x82\xdf\xc4\x57\x98\xcc\x17\xc8\xd9\x49\x6b\xf5\x20\xec\xc5\xb7\x7f\xe2\x84\x91\x55\x66\xc4\x56\x85\xc3\x04\xa2\xac\xd5\x25\xef\x12\xc8\x6f\x38\xae\xf5\x54\xd8\xa2\x38\x47\x37\xcc\x41\x33\xfb\x7e\x2b\x65\xc1\x3b\xef\x31\x66\x8a\x6c\x2f\x60\xee\xcd\x84\x12\xee\xff\x7f\x6b\x60\x5c\xbe\x95\x08\x3e\x23\x3e\xc1\xa7\xbb\x36\xde\x23\x6c\x8a\x71\xba\x28\x72\xbe\x94\x6c\xd3\xb3\x89\x35\xf5\xda\x64\xc8\xfe\xc8\xe1\x4f\x45\xcc\xf6\x12\x4b\xab\x7f\x70\x56\x7c\x2f\x2b\xfd\xd5\x66\x67\x60\x95\x72\x03\x7c\x76\x14\x6c\x99\x17\x07\x65\x9b\x57\x09\xb0\x74\xe3\x45\x1f\x92\x1a\x2d\xf2\x83\xb9\x6a\xa2\x6a\xb4\x76\x62\x50\x16\xf1\x81\xad\x64\xc9\x91\x9c\xf4\x1d\x71\x4a\x1a\x9a\x5e\x2b\xb2\x6b\xaf\x87\x70\xb2\xeb\xa7\x7b\x77\x8a\x33\x26\x77\xa7\x57\x2e\xe3\xa2\xb1\xdc\x05\xf7\x35\x6b\xdc\xae\x5f\x55\xe3\x53\x29\xe3\x4c\xaa\x79\x43\x0b\x27\x0c\x03\x61\x60\xdc\x9f\xca\xab\x5b\x25\x45\x43\xac\x94\xb2\x46\x81\xf1\x71\x72\xb6\x15\x9d\x16\x62\x1d\x7a\xd0\xee\xbd\x89\x5a\x1e\x1d\x09\xb9\x16\xa8\x6f\xb4\x8e\x4c\x91\x66\x10\x57\xee\xe9\x5c\x08\x70\xed\x54"}, +{{0x14,0x38,0x3e,0x6e,0x56,0x04,0xc9,0x9c,0x24,0x8d,0x39,0xbe,0x51,0xd1,0x64,0xb1,0x34,0x42,0xb0,0x5e,0x51,0xd7,0x8e,0xcd,0x99,0x93,0x64,0x22,0x1a,0x45,0x03,0x6b,},{0x2f,0xc1,0x61,0x38,0x22,0x0a,0xb7,0x4b,0x3b,0xd4,0x46,0xf8,0xa7,0x14,0xb5,0x8d,0x54,0x63,0xd4,0x0d,0x43,0x67,0x92,0x50,0x07,0x47,0x4c,0x5b,0x9e,0x35,0xd4,0x94,},{0x45,0xe8,0xed,0x1a,0x75,0x1d,0xfc,0x3b,0x9b,0x7b,0xd7,0xa1,0x0b,0xf5,0xbd,0xcf,0x8c,0xa4,0x61,0x86,0x5a,0x49,0x0c,0x10,0x5f,0x10,0x45,0x29,0x41,0xcf,0x87,0x72,0x12,0x14,0xbf,0xbf,0x3a,0x35,0x60,0x6b,0x7c,0xe3,0x5d,0x6f,0x70,0xaa,0xf2,0xd5,0xea,0xdc,0xc0,0xde,0x03,0x5e,0x9b,0x2f,0x6d,0x7b,0x86,0x2f,0xc2,0x84,0x90,0x04,},"\xc4\x75\x3b\x7f\x7a\x6f\x6d\xea\x25\x15\xc6\xe3\xd2\x95\x61\x50\x6f\x4f\x36\xe0\xde\x84\x99\x92\x21\xf2\x28\xe2\x0b\xd5\x12\x8e\xd9\x3b\xdb\x8d\x11\x93\x23\x7d\x8e\x29\x41\x69\xa2\xbc\x44\x8a\xf9\xdd\x36\x06\x63\x01\xef\xb7\xfe\x12\x31\x35\x3c\x06\x23\xff\xe1\x11\x5d\xeb\xb6\x90\x5a\xc6\x94\x6e\xe3\x82\xa2\x7c\x3c\x09\xe1\xb1\xf5\xc1\x14\x93\xdb\xa3\x7d\xa0\xff\x6e\xea\x75\xd9\xfa\xb0\xee\x92\x6d\x70\x1d\xac\x2f\xc5\xb7\xef\x57\x88\x80\xa5\xd5\xee\xec\xad\xc1\xf4\xbc\xc4\xcd\x4e\xc6\xf2\xf1\x4f\x52\xa8\xc1\x64\x07\x2e\x6f\xde\x5a\xb2\xee\x9c\xee\x0b\x48\xe5\x1a\xf0\x55\xf9\xfe\xc7\xc6\x37\x50\xfe\xdf\x72\x33\x2b\x23\x86\x3a\x1e\x54\xc5\x2b\x46\x1a\x21\x50\x6d\xfd\xfc\x63\x88\x0e\x22\xd8\x9c\x89\x44\x12\x66\x6c\x92\x98\x21\xc0\xe4\x39\xe7\x45\x41\x5f\x71\x79\x69\xe6\x05\x85\x54\xd6\x4b\x94\x7a\x4f\xc9\xd1\x6a\xca\xe3\xe4\x9a\xec\x08\x80\x1a\x09\xd9\x72\xf7\x9e\xad\x68\xd5\x29\x76\x80\x69\x73\x5c\xaa\x74\x2b\x45\xa5\x83\x05\x81\xb8\x0c\xa0\x61\xa6\xc1\x51\x5e\x3f\x7d\x5a\x93\x37\x87\x8c\x19\xfc\x94\xee\xf2\x26\x98\xea\x6c\x4d\x05\xf9\xed\x41\x1b\x6b\x8f\x05\x2b\x5f\xf1\x5d\xc2\x3a\x64\xbe\xea\xae\x99\xf8\x48\x93\xde\x3d\xf9\x40\xa4\xe0\xb8\xe9\x93\x93\x01\x39\x05\x2d\x99\xbe\x47\xbc\xa8\x77\x5f\x85\x63\xbd\x40\x26\xb7\x13\x43\xd5\x19\x68\xf2\x33\x75\x28\xf4\xc9\xdb\x8b\xbd\x0a\x29\x8a\xf0\x4b\x27\x69\x5d\x86\xb7\xf7\xba\x6c\x4c\xcc\x62\x73\xfe\xbc\xd8\xf7\x5c\xff\x26\x69\x95\x24\x4f\xc1\xfa\x13\xd8\xd8\x43\xf0\xbf\xf4\x9c\xc2\xd5\x08\xf4\xa2\xb3\xaa\xd1\xd9\x5f\xb2\x2a\x2b\xc6\xad\x1b\x96\x6b\x08\x12\xd9\x90\x70\xbb\xa0\x7c\x92\x3e\xe4\xd0\x81\x07\x48\x6d\xc0\x1a\x06\xdb\xa6\xf1\xd5\xf1\x05\xac\xea\xde\x33\xb1\x66\x51\x0e\x42\x7e\xbb\xce\x52\xa3\xe7\x83\x1f\x0f\x78\xa3\xc6\xe0\x72\x60\x83\x34\xd8\x02\x1c\x33\x8a\x73\xcc\x0c\x47\xf1\x9c\x9f\xae\x40\x3b\x97\x16\xd0\xd1\x5f\xbd\xf6\x46\x6b\x08\xf6\xac\xce\x3f\x50\xa7\x03\xb1\xde\xa8\xd8\x26\xdf\x84\x2c\xa1\xba\x20\xd2\x9f\x45\x48\xac\xfc\x75\x4c\xf0\x11\xf5\x70\x68\x1b\x59\xe4\xda\x25\x38\x5e\xbd\x6d\x5c\x3a\xdc\x93\x05\x29\xe1\x66\xce\x67\x05\xf6\x01\x02\x10\xdb\x10\x64\x62\xb3\x33\x32\x04\xe7\xad\xad\xee\x66\x06\xa5\x62\x06\xb4\x7e\xef\x20\x74\xb1\x16\xe2\x2a\x61\x54\x18\xec\x2c\xdc\x33\x1f\x1e\x19\xe0\x7e\x8a\x37\xb9\x2d\x69\xdf\x07\x34\xe0\x85\xda\xee\xb9\x01\xec\x6e\x8c\x35\xf1\x03\xf1\xd8\x6e\xf0\xd2\xa2\x65\x2b\x01\xd1\x83\x59\x7e\x4c\xfd\xee\xdf\xe5\xdf\x9a\x7e\xf6\x6a\x1c\x79\x6a\x37\xa2\x71\x13\xb9\x44\xdd\x7b\xa1\x7c\x46\x00\x15\xab\x8a\xce\x45\x1c\x57\x85\x0e\xc6\xc2\x90\xc5\x4e\x51\x13\xf5\x5e\x99\xa8\xe6\xe4\x71\x1e\x3b\x78\x17\xbf\x91\xa5\xad\xb3\x7f\xb9\x46\x1b\xe6\xb1\xb5\x5d\x58\x60\x46\xe4\x2a\x54\xc5\xde\xf4\x07\x6f\x1f\xf6\xc3\x1b\x80\x6f\xc6\x02\x47\x43\x56\xaa\x28\x99\xea\xe7\x0f\x5e\x5a\xbf\x1f\x75\xa7\xf2\x4c\x13\x4c\xde\x11\x79\x3b\xb1\x62\xe0\x3a\x58\x3d\x5b\xe0\x46\xac\xc7\x34\x56\xd1\x2d\x50\x9d\x92\xf7\x70\x57\x68\x68\x6f\x6c\x71\x4a\x4e\x57\xec\x88\xb7\x13\x98\xe2\x3e\x83\x5d\x6d\x65\x47\x22\x59\x96\xb7\xed\x08\xf3\xb7\x44\x3b\xb1\x7c\x89\x94\x09\x49\x3d\x0e\xfe\x84\x55\xbe\xc8\xe8\xc2\x84\xa3\xb1\x49\xa5\xb4\xca\x63\x1e\xa6\x20\xb1\xbb\x81\x7c\xed\xab\xa5\x0b\x04\x44\x11\x84\x9d\x26\x0a\x6f\x2a\x0d\x3f\x2c\xce\xec\x38\x42\x71\x9a\x5e\xa4\xfe\x18\xdd\xe0\xd4\x2d\xcb\x33\xad\x21\xe6\x45\x33\x25\xaf\x6f\x3c\x00\x9f\x2b\xb9\x78\xd3\x0c\xee\xae\x9a\xa4\x92\x8b\xf7\x37\x67\xcd\xa9\x29\x2a\xb8\x93\xce\x5f\xa3\xaa\x4c\x23\x21\x63\xb4\x5c\x64\xed\x79\x77\x77\x9b\x1c\x0c\xaf\xcf\xc2\xb9\xfa\x08\x4a\x32\x4f\x11\x3a\xde\xec\x21\x8b\x47\x35\xb6\xb4\x64\xdb\x6d\x46\xc2\x79\x1a\xf3\x45\x5f\x1c\xa5\xea\x1e\x9a\x04\x8c\x05\x1a\x54\xdf\xa0"}, +{{0x59,0xb0,0x72,0x63,0xb2,0x2c,0x0a,0x38,0xbb,0xc5,0x91,0x05,0x95,0x94,0xb2,0xbd,0x92,0x7e,0x80,0x59,0x61,0xdd,0x07,0xe1,0xf9,0x42,0x45,0xb2,0x3a,0xa2,0xe0,0x16,},{0x0b,0x1e,0x4c,0xf5,0xaf,0xf2,0x78,0xec,0x65,0xb4,0x05,0xf5,0x10,0x8e,0x1b,0x5b,0x18,0xa9,0x69,0xad,0x1f,0x1e,0x63,0x81,0x91,0x2c,0x82,0xd6,0x98,0x90,0x7c,0xba,},{0x88,0x6d,0xa3,0x3e,0x35,0x53,0x28,0x5e,0xa5,0x9c,0x14,0x31,0xb6,0xe8,0x6e,0xa4,0x9b,0xb6,0x8b,0x2e,0x0e,0xfd,0x2b,0x15,0x7e,0x77,0x91,0xb7,0x4f,0x35,0xa2,0x42,0x1b,0xb3,0x59,0xf3,0xdc,0x1e,0x4c,0xe5,0xf1,0x1f,0x73,0x65,0x2e,0x03,0xbf,0xc0,0xb4,0x29,0xc5,0x8f,0x0f,0x2d,0x74,0x18,0xc7,0xc2,0x0b,0xce,0x2e,0x2d,0x19,0x01,},"\x08\xce\x0d\x4d\xb5\xc2\xaa\x50\x0a\x19\xef\xbc\x8d\xc8\x54\x92\x50\xf7\xdd\x46\xa7\xa9\xa5\x40\x74\x17\xb3\xd5\x18\x20\xe4\xb0\xd6\x12\x75\x58\x3f\x56\xf8\x97\xfd\x94\x2b\xdd\x73\x11\xad\x6b\xaf\x73\x81\x28\x56\x7a\xf6\x55\x8d\x75\x90\x6a\x02\xc4\x34\x3a\x99\x55\xd5\x9b\x11\x08\x8c\x58\x8d\xc7\xdd\x08\xf6\x79\x65\xc5\x60\x2a\x56\x92\x8d\xda\x4a\xe1\x64\x29\x31\x63\xb5\x17\xca\x17\xde\xd0\x4f\xe4\xab\x2f\x97\x89\x13\x0a\xe9\x6a\xb2\x31\xf0\x7e\x09\x01\x5b\x78\xf3\x84\x8c\xef\x43\x5d\xb0\xad\x9f\x35\xe0\xfb\xc9\x85\x1e\x3e\xcf\xc9\xfb\x18\x6d\x14\xd8\xda\x4d\xda\x45\xd0\xb3\xeb\x3e\xe4\x50\x0c\x10\x1e\x31\x94\xb5\x72\x14\x06\x89\xcd\x75\xda\x12\x87\xb2\x54\xf3\x74\xe3\xd9\x33\x26\xae\x5f\xaf\x11\x40\x18\xac\x71\x4b\xd0\x03\x75\xd9\x2a\x8b\xb6\x59\xc3\x29\x12\x83\x1f\x4f\x20\x77\x6e\x9e\x2c\x25\x02\x9f\x0a\xff\x39\xfd\xda\xc7\x24\x15\x43\xa0\x36\x6b\x84\xde\x7b\x1f\xf2\x3e\x8e\x4d\xc0\x93\xdf\x0d\x2d\xd5\xe5\x3e\x68\x47\x94\x8c\xf3\xd0\xff\x3f\x56\x4a\xd9\x4d\x9c\xc0\x0a\x5e\xa5\xb6\x95\xe4\x08\xbf\x50\xf5\xba\xb2\xf6\xea\x87\xba\x8a\xd3\xa1\x94\x01\x95\xcf\x1b\xc2\xb5\xb3\x48\x47\xad\x3a\x5e\xff\xb8\xa7\x82\x3d\xe9\x1e\xf1\x63\x38\x69\xd1\xf0\x46\x43\xaf\x4d\x82\x6a\x59\xe7\x8b\x9d\x18\x63\x12\xb3\xd9\x72\x26\x36\x54\xac\x55\x87\xb8\x0b\x71\x76\x46\xf3\x10\x03\xdb\x81\xac\x70\x86\x0d\x3f\xc8\xcd\x3a\x6a\x0a\x0d\x57\x6d\x25\x73\x1e\xf7\xb8\x96\x62\x63\xd7\xa0\x5b\x55\x00\x9e\x8a\x23\xda\xc0\xf9\xa2\x1a\x24\xb0\x6e\x13\x90\x0e\x44\x44\x46\xfd\xfe\x56\xcb\xc1\xa0\x26\xdf\x41\x06\x6b\x20\x1b\x14\x81\xe5\x61\x58\x92\x6c\x0c\x9e\xa9\x0f\x0c\x64\x5a\xab\x4b\xef\x12\xd4\xe0\x72\xcb\xfd\xc3\xc3\xd5\xe0\xc7\x2c\xf8\x8f\x16\x6d\xe0\x48\x87\x4f\x35\x34\xe0\x40\xc6\x2b\x16\x62\x82\x1b\xdd\x16\xb0\xe8\x58\x28\x17\x46\x1c\xb2\x68\x92\x79\xb4\x46\xd7\x0c\x8a\xc2\x0a\xd0\x3e\x59\x8c\xad\x49\x08\xc5\x2c\x35\x0d\x42\x43\xee\x8a\xed\xb8\x7a\x4a\xf9\x77\xf7\xdb\x57\xcd\x94\x7b\x47\xd6\xbb\x51\x40\x9d\x80\xd8\x1f\x6d\xb0\x3c\xb9\xa6\xa6\xb7\x98\x12\xf4\x70\x69\x0a\xfc\x18\x36\xa5\x31\x33\x80\x94\xcf\x26\xd3\xc1\x23\x2f\xd5\x60\x5d\x8f\x8c\x55\xb6\xf8\xa2\xa7\xef\x1e\x0c\x78\x15\x55\x94\xb2\x37\x95\x6d\x2a\xba\xd6\xa9\xad\xcd\x58\xe1\x1c\xcd\x35\xcc\x99\x5b\x9a\x0a\xec\xbf\x7f\x57\x41\xac\x05\x1b\x04\xef\x6b\x97\x44\xb5\x6f\xcc\xb4\x63\x98\x52\x8b\xb3\x1f\xbe\x84\xe0\x78\x84\x3e\x69\xbf\x33\x88\x98\xcd\xef\x69\xad\x41\x87\x23\x95\xe4\x6b\x59\x39\x04\x82\x55\x47\xe0\x0b\xda\xf2\x21\xf8\xfa\x58\x7e\xa2\x03\x7f\xfb\x9a\xc9\x30\x7d\xd3\xf8\xf3\x5e\xc5\x38\x6b\xa9\x66\x33\x3e\x2a\xc8\x72\x7b\x0e\x1b\x80\x61\x2d\x3c\x7f\x2c\xb8\x8b\xaa\xca\xdf\xe2\x16\x3b\xc3\x8c\x88\x84\x2e\x76\xa3\x94\x57\x1d\x40\x61\x0e\x8a\x29\x76\x02\x79\x37\x63\x29\x6e\x3e\xab\xf7\x20\xe9\x84\xb2\xed\xd2\x8c\xf5\xc4\xe0\xf9\xa0\xf7\x6a\xce\xba\x28\xcc\x1f\x1b\x69\xff\x1d\x35\xb4\xbd\x33\x47\xb7\xf9\xa9\x5a\x4c\x1e\xa1\x07\x34\xe1\xc9\x18\xeb\x96\x24\x9d\x0c\xc7\x0b\x47\x7f\x6f\x23\x80\x9b\xbd\xa9\x01\xd5\x3f\x48\x5a\x71\xf5\x08\x60\x02\xc1\xb7\x1e\xfc\xc4\x1c\xb1\xae\xb5\x12\x2a\x3f\x3b\xfc\x96\xc5\x1a\x55\xd7\x5c\x02\x98\x42\x88\xbe\x65\x78\x87\x85\x4c\xfa\x73\x89\x74\xbc\xd5\x44\x01\x46\xf9\xbb\x14\x04\x0d\xe5\x4f\x54\x44\xad\x43\xb7\x9a\xf9\xbd\xb2\x4e\xd6\xa4\x8e\xb2\xfd\xee\xd7\x1f\x31\xf0\xec\xe1\x02\xe9\x18\xe9\x56\x35\xc7\xa0\x38\x63\x3e\xe3\x48\xd8\xb5\x78\x16\x52\xd5\x05\x9d\x21\x5a\xc9\x7f\x30\xea\x20\xd2\x77\xeb\xbf\x15\x24\x69\x05\x42\x8a\x7b\xec\x02\xb8\xf9\x26\x31\x5b\xad\x67\x23\xfd\x64\xd7\x1f\xc9\x5f\x33\x33\x64\xcb\xe9\x0d\x46\x46\x33\x3c\x40\xdd\xa6\xd1\xd4\x33\xb7\xc1\x95\xa7\x58\xdb\xb4\x03\x8a\xf5\xdc\xc7\x23\x2d\x45\x47\xf5\x40\xe3\x94"}, +{{0x5c,0xc1,0x15,0xd8,0x39,0xe0,0x58,0xcd,0xb6,0x51,0x8e,0xe9,0xc1,0x61,0xc0,0x04,0xd8,0x8b,0xd3,0x90,0x8d,0x3c,0xf6,0xd5,0x2c,0x8f,0x29,0x6a,0x1a,0x07,0x6b,0x9b,},{0x1e,0x8f,0x33,0x05,0xbf,0x2f,0xa1,0x1b,0x17,0xd9,0x24,0x16,0xab,0x0e,0xa7,0x62,0x39,0x6d,0x88,0xf2,0xf9,0x70,0xef,0x0b,0x10,0x0e,0xd3,0xbf,0x5c,0xc1,0x34,0x40,},{0x03,0x71,0xc2,0xd6,0x4c,0x5e,0xc0,0xc8,0x27,0x6c,0xa5,0xff,0xa6,0x15,0xef,0xf4,0x2f,0x9e,0xff,0xfc,0x58,0xdd,0x8e,0xcf,0xcf,0x67,0x62,0x0a,0x9b,0xcb,0x38,0xfa,0xf1,0x18,0x93,0x2b,0xf2,0xcd,0x5b,0x92,0x05,0xfa,0x55,0x13,0x34,0xdf,0x2a,0x75,0x7c,0x59,0x77,0x44,0xf7,0x91,0xf3,0x71,0xfb,0xed,0xd9,0x8b,0x21,0xf7,0x34,0x05,},"\x53\x3e\x49\xc1\xd5\xf3\x3c\x5e\xc4\xbe\x84\xc6\x19\xf4\xec\x64\x9c\x25\xfd\x70\xbd\xcf\xe2\x57\xa6\x3c\x33\x73\xa4\xd0\x89\xc8\x9a\xf6\xee\xb7\x16\x0d\xd7\x7a\xb6\x6b\x1e\xe7\xe1\x08\x50\xab\x4f\xc1\xf3\x51\x32\x33\x2b\x53\x78\x9b\x2b\x01\x40\xc4\xf2\x0f\x97\xf2\x14\x20\x72\xd6\x24\xaf\xf7\xaa\xd3\x24\xaa\xcd\x06\x8c\x03\x5a\xff\x52\xfa\x71\x2f\x4e\x74\x83\x2d\xe0\x31\xb2\x64\x23\x14\xd1\x71\x10\xde\xe6\xfb\x85\x76\x2d\xc3\x0d\x7e\x97\x78\x2f\xd1\xfb\xff\x71\x79\xf0\x09\x17\xf5\x5a\xf7\x50\x3a\x5b\x7e\x23\xc6\xea\xdb\x65\xe1\x04\xf1\x51\x7b\x66\x24\xc9\xe5\x20\x4b\x3f\xd2\x9a\x65\x85\xe9\x2c\xe3\xa3\xee\xe2\xc5\xae\x17\x79\x20\xf7\xb4\xab\x2c\xac\x87\xd6\x72\xab\x6b\xaa\xc1\x18\x6d\x90\x4a\xea\x34\x98\x53\x4e\xb5\xab\x23\xe4\xac\x4c\x0d\xdb\x0d\x82\xa5\xae\x53\x1d\x76\x54\x9d\x36\x76\x28\x57\x7b\xac\x42\x35\xe8\x97\xd9\xfe\x20\x55\x22\x04\x7d\x21\x4f\xf6\xcc\xf3\x11\xc4\xe3\x97\x82\x7d\x97\xf2\x86\x8e\x70\xac\x17\xd2\x8e\x33\x49\x99\x74\x4d\x35\x93\x76\xa4\x82\xfd\xcb\x41\x4b\x02\xb2\x68\x7b\x96\x2e\xe8\x08\x6e\x57\x3f\xe0\x00\xdc\x51\xde\xe0\x68\x79\xc6\x84\xe2\x5f\x94\xce\xe5\xe8\x61\x34\x7e\x7b\xe7\xfc\xa5\x49\xa0\xf7\x65\x13\x6a\x2f\x4b\x88\xfe\xde\x07\x02\x4d\xd2\xfc\xe1\xf6\xd0\xc0\x35\x4d\xa1\xa1\x6e\xf3\x66\xb3\x15\xb3\xf7\x23\x30\x31\xf9\x79\xb7\x0e\xac\x6e\x23\xbf\x3b\x34\x9e\xfb\xd0\xe4\xf5\x3f\x4d\x5c\x41\xfc\x00\x42\x76\xa5\x96\x70\x65\x9f\x69\x05\xef\x03\xd2\xfc\x09\x8d\x58\x9f\xcb\xc1\x32\x82\x82\xfa\x22\xb1\x0d\xb8\x3c\x5d\x70\x86\x59\x94\xfd\x19\xd7\x60\xa3\x9d\x47\x6e\x02\x33\x0d\x2c\x6d\x19\xe7\x42\x26\x7d\xd3\x65\xbb\xe1\xfe\x5c\x71\x1a\x95\xb1\x84\x50\x8c\xe4\x8c\x1c\x96\xd7\xe6\x39\x90\xb4\x08\xd4\x50\x89\xbe\x79\xe3\x2f\x9c\xb0\x16\x2f\xd1\xe7\xd0\xd1\x9d\x97\xd0\xae\x78\xff\x82\x4c\xc6\x98\x94\x86\xc0\xbd\x03\x83\x52\x55\x1f\x37\x49\x9e\x9e\x98\x26\x80\x4e\x9d\x26\x24\xad\x0c\x7b\x75\x34\x56\x0f\x45\xfd\x7d\x32\x4b\x8e\x51\x7e\x01\xc9\xb2\x74\x3c\x14\x97\x9c\xfd\x51\x2b\xc3\xfe\x66\x72\x79\xb3\xa2\x77\xfb\x46\x3e\x9d\x73\x49\xb6\x4f\xfc\x9f\xe6\x08\x84\xc2\x1e\x48\x10\x81\xed\x70\xe6\xda\x5a\x35\x39\xc4\x48\x97\x1f\x0d\x97\x87\x28\x9f\xcb\x00\x80\xf2\x19\xe9\x94\x49\xf8\x29\x8c\x42\x47\x5f\x87\xfd\x10\xae\xb5\x09\xc5\x30\xcf\x6a\x57\x74\x8e\xb8\xf3\x56\x21\x61\xfa\x48\x75\xea\x95\x3f\x09\x65\x9c\x7d\xf7\xa9\x95\x0f\x03\x17\x46\x7c\xb4\xe5\x36\x6e\x19\x6e\x32\xf5\xe2\x69\x67\x33\xa2\x5e\xac\xbd\xe4\x92\x10\x49\x07\x62\x06\x0e\xa2\x31\x37\x0d\x40\x90\x42\x9b\xb0\x6b\xb8\x67\x39\x9e\x8d\x37\xbf\x5d\x21\xa0\xe7\x21\x47\xe4\x96\xcf\x3b\x7d\xd6\xfe\x6e\x5e\xde\xa9\x66\x8d\x80\x21\x90\xa9\x1c\x60\x0e\x29\x52\x3f\x8e\xb9\x04\xe4\x8b\x70\x41\x2b\xc1\x0a\x70\x20\x98\x4c\x5f\xf0\xf5\xf3\x83\xf2\x14\xae\x59\x4d\xc8\x59\x71\xe4\x80\x37\x28\x48\xd0\xd7\xe7\xcc\x5c\x18\xff\x88\xba\x9b\x26\x2d\x78\x84\x69\x8a\x41\xc6\xc7\x81\x9c\x03\x19\xfd\xc6\xbb\x07\xb9\x1d\xc1\x69\x4d\xaf\xe3\xaf\x37\xa5\x38\xbf\x2b\x2d\x8c\xac\xb2\x7d\x24\xcd\xc6\xea\xdb\x8c\x6a\x2e\x6b\x7d\xf8\xa4\x65\x4a\xe9\x37\x85\x0c\x89\x0a\xd9\x30\x98\x0a\xfc\xc1\x49\x2d\xb8\xa0\x16\x8c\xbc\x9f\x10\x65\x7e\xb4\x8d\x2a\xc8\x7f\x51\x75\xd2\x3c\xae\xd4\xb5\xe6\xf1\x0b\xbe\xaa\x5e\x33\xfc\x5f\x64\x18\xd6\x3b\xa3\x74\xab\x1a\x3c\xbd\x36\xb7\x29\xdd\xbd\xab\xa9\x89\xd4\x64\x5e\x3a\x66\x13\x0b\xae\x41\x7c\xad\x08\x6d\xad\xd3\x08\x43\x35\x25\x14\xc3\x75\xf2\x57\x1a\xba\xf9\x3e\x9a\x07\x71\xfa\x10\x3a\xe9\x25\x85\xb0\x4f\x55\xc4\x34\x76\x9b\x43\xd6\xd2\x2f\x75\x3f\x93\x06\x03\x6e\x53\x52\x4f\x6f\x4d\x9c\xcb\xd2\xc3\x03\x17\xa8\xe8\x99\xf3\x16\x14\x90\x35\x89\x4d\xa9\x45\xb7\x6d\x90\x82\xbf\xee\x32\x8e\x7a\x31\xb6\x63\x28\xee\x8b\x94\xe0\x68\xc7"}, +{{0x75,0xa5,0x03,0xf4,0x8f,0xfc,0x22,0x16,0x17,0x67,0x25,0x19,0x11,0x1b,0xf9,0x0d,0xa3,0x9d,0xa9,0xea,0xb2,0xe2,0x91,0x4f,0xd3,0x75,0x5f,0x10,0xf5,0x39,0x36,0x68,},{0xf6,0x80,0xcc,0x0f,0x63,0x58,0xcd,0xcf,0x53,0x7a,0xa7,0x11,0x28,0xcf,0xad,0xfc,0x0f,0x3a,0x89,0xc1,0x00,0xaa,0x34,0xbc,0xd2,0x42,0x7e,0x24,0x8b,0x6e,0xd5,0x0b,},{0xdf,0x28,0xe3,0xe6,0x30,0x36,0x08,0x67,0x86,0x4b,0xc4,0x1e,0x43,0xfd,0x7d,0xde,0xb5,0x28,0x76,0xdc,0xe9,0xb2,0x34,0xa3,0xfc,0xc3,0xd8,0x54,0x9d,0xb0,0x11,0x2e,0x17,0x63,0x90,0xa6,0x85,0xeb,0xd4,0x84,0x93,0x6e,0x25,0xc0,0x8c,0x8a,0x38,0x78,0xa3,0x7b,0x3c,0x4e,0x23,0x9a,0xd0,0xa0,0xe5,0x01,0x99,0x37,0xff,0xbc,0xd4,0x07,},"\x7b\x01\x09\x04\x23\x23\x6c\xb4\xb1\x3c\x41\x77\xfc\xe5\x2a\x7f\xf6\x58\x05\x88\xcc\x2e\xb5\xa3\xf3\x9f\xf5\xd0\xc7\x3e\x01\xe0\x1b\xf7\xbd\x74\xaf\xe4\x15\x12\x50\xc3\x91\x42\x6e\xa5\x07\x27\x1b\xea\x1d\x6d\x85\xf0\xb2\xfe\x35\xc4\x05\x00\xf9\x8d\x06\x56\xc6\x38\x8f\xc9\xef\xba\x18\x37\xdb\x22\xdf\xa2\x9d\x89\x26\x76\xf5\x0e\x57\x5f\xe8\x9f\xd2\x93\x89\xd0\x9d\x08\x0b\xad\x67\xba\x54\x4c\xac\xab\xf5\xa7\x73\x82\x37\xc5\x5e\x28\x75\xed\x49\x16\x30\x2a\x2b\x4d\xc4\x96\xe7\x42\x73\xbf\x05\x19\x11\x37\x81\x0e\x50\xe4\x81\x95\x26\x0b\xab\x6d\x81\xf9\xc8\x05\x62\xee\x73\xcc\xb9\x33\x3c\xd9\xb6\x1d\xaf\x5b\x00\x38\xa4\xe6\xc5\xc9\x58\xa9\x1f\x68\x50\x8c\x1d\x88\x25\x19\xc1\xaa\x4f\xfc\xc5\x35\x62\x46\x3a\x0a\xe3\x01\x63\x69\x6f\x84\xb9\x7c\xcb\xd8\x67\x98\x20\xed\xd3\x61\x7e\x7b\x89\x6e\xef\xfe\x34\x1e\xc6\xb5\xb0\x3f\x73\xb6\x25\xd7\x41\xc6\x55\xfe\x6e\x82\xd1\x1d\x47\x8a\x7d\x54\x3f\xf6\xc0\xfa\x3a\x3a\x8c\x94\xa6\x16\xfb\x84\x70\x70\xd1\xfb\xdd\xe6\x01\x0f\x02\x6b\x08\x9c\xd8\x63\xc3\xbd\x29\xb1\xc4\x26\x9f\x77\x65\x9e\x51\x57\x28\x89\x0c\x97\x3b\xe8\x7f\x0b\x83\x3c\xa5\xaf\x6b\x4c\x31\x33\xad\x4f\xa4\xf9\x16\x55\xc6\xad\xb5\xb7\x23\x5c\x27\xfe\x34\x82\x84\xf3\xf1\x33\x66\xa6\xa0\x3a\xd2\x2b\x87\xc6\xf5\x58\x4b\xde\xae\xa4\x8c\x70\x32\x5d\x6e\x33\xa4\x75\xf5\x05\x11\x06\x38\x75\x19\x2a\x87\xed\xc3\x88\x08\x9b\x84\x39\x53\x90\xc2\xa3\xad\x89\xa2\x25\x95\xdc\x4a\x71\x5a\x42\xa2\xc0\xef\xde\xf6\x7b\x35\x4b\x34\xfc\x75\xca\x98\xdf\x91\x3e\x75\x9e\x51\xc7\xf6\x25\xdd\xd5\x98\xac\x22\xd4\x21\xde\xcb\x57\xbe\xbd\x54\x22\x0e\xc6\xda\xa5\xec\xe7\x69\xd2\xe0\x1b\xe7\xb6\xbe\xe2\xff\x5a\x0b\x06\xb3\x2d\x6d\xa1\xd7\xbc\x05\x7e\x3a\xbf\xaa\xb2\x42\xa3\xf7\xe6\x64\x6a\x15\x9e\x4f\x50\x5e\x46\x62\x98\x2b\x13\xd0\xcc\x1f\xba\x91\xd1\x03\x09\xa4\x2d\xc1\x08\x7c\xf1\x0d\x36\xe3\x1f\x17\x06\x15\xa0\xac\xb5\x08\xbf\x68\x3e\x2d\xe0\x0c\x87\x64\x0d\x30\x4a\x94\x7b\xc4\x97\x1f\xf3\x61\x9c\x72\xab\xd8\x3c\x7b\x2c\xbb\x34\x64\xc4\x04\x0c\x26\x62\xb5\x85\x08\xb7\x46\x80\xcf\xa6\xde\x06\xe8\xd2\x1e\x3b\xec\x85\x11\x19\x93\x12\x68\x00\x09\x07\x1f\x70\x6b\x7b\x13\x3a\x24\x87\xd5\x74\x5f\xfa\xdd\x5d\xc0\xeb\x2b\x55\x3d\xf4\x40\x78\x7f\x01\x1d\xda\x37\x71\x9f\xa7\x13\x15\xe8\xb2\x91\xef\xd7\x7d\xa3\xba\x14\xfb\x99\x5f\x03\x57\x1a\x3d\xb5\x22\xb6\x3c\x60\xbe\x56\x19\x94\x16\x99\xb3\x92\x22\xb5\x9d\x0f\x23\xe5\xeb\x37\xea\xd4\xb7\xf7\x50\xed\x4a\xbf\x4d\xb8\x7c\x70\xda\x66\x5b\xef\x4d\x7a\x29\x21\xb2\xc9\x98\x97\xf2\x32\x1c\x9b\xe6\x07\x5e\x74\x4c\x82\x28\x63\x9a\xb7\x36\xdb\xeb\x2b\xea\xb4\x40\xc1\x56\xa3\x9a\x2e\xfd\x26\x1d\xb5\x08\x55\xe3\x04\xd9\xcf\xeb\x99\x14\x1c\x61\x35\x58\x10\x9f\x21\x47\x4d\x27\x2a\x2d\x90\x6d\x48\x93\x93\x4a\xff\x8e\x08\xa4\xfc\xee\x96\x4a\x5c\xd0\x07\x32\xfd\x33\xaf\x29\x84\x9c\x8d\xfc\xa6\x59\x79\x42\x18\x57\x18\x5c\xf6\x29\xf8\x68\x07\xa8\x59\x73\xd3\x44\x0a\x6b\xf8\x11\xa5\x8d\x04\x13\x87\x24\x98\x11\xec\x04\x7e\x5e\x8b\x34\x3b\x23\x87\xd0\x18\x1e\x0d\x0b\xd4\x61\xef\x10\xe8\x16\x4a\xae\x35\x7d\x9b\x29\xdc\x0a\xce\x3e\xc6\xd7\x43\xae\x34\x54\xab\x9f\x84\x2a\x28\xd5\x71\x02\x17\xdf\xfe\x50\x34\x4e\x8d\x93\x2f\x18\x01\xb0\xe8\xf9\x66\x19\x8e\xf1\xc9\xcc\x69\x69\xf3\x47\x34\xaa\x6a\x63\xae\xaa\xb4\x33\x9f\x75\xd3\x4f\xfa\x8a\xcb\x93\x7e\xd9\xc7\x30\x92\xa3\x09\xa9\xb8\x4a\x25\x01\x1e\x31\x14\xc2\x65\xe4\xf6\x02\x33\x7e\xb6\x99\xb5\xa2\x2d\x57\x2b\x03\xe4\xda\xd0\x3b\x04\x61\xc0\x0d\xb9\x67\x9b\x72\xfc\x5b\x49\x3e\xf4\x48\x6f\x85\x53\x5d\x81\x3a\x58\x08\x03\x85\xaf\xd4\xe8\xd8\x71\x82\x80\x34\x33\x4b\xfe\x44\x1d\x18\x98\x4e\x4d\xfc\xde\x02\x44\x03\xb5\xae\x66\xcc\x50\xa4\x73\x01\xb5\x7f\x9a\x32\xf7\x40\xbd\xc7\xff\x1d"}, +{{0xd8,0xaa,0x2a,0x0a,0xa5,0x14,0xfd,0x84,0x5f,0x7a,0xa6,0x6b,0x83,0xc0,0xea,0xbb,0x9c,0x16,0x02,0x3a,0xbc,0x16,0x95,0x77,0x34,0x50,0xb2,0xbb,0x33,0x25,0x22,0xf2,},{0xe4,0xe8,0xd6,0xb2,0x98,0x24,0x8c,0x15,0xfe,0x08,0xf8,0x7a,0x3b,0xc6,0x08,0x4b,0xf2,0xd6,0x4d,0x7f,0x1e,0x4b,0x2d,0x51,0x59,0x9e,0x9f,0xad,0x9c,0xc9,0x10,0x92,},{0x14,0x6f,0x65,0xd4,0x3e,0x71,0x55,0x42,0x89,0x4b,0x79,0x00,0xa2,0xf8,0xcd,0x4b,0x17,0xd3,0x87,0x0a,0x61,0x00,0xe3,0x7d,0xe0,0x05,0xb0,0xdb,0x5d,0x81,0x51,0x24,0x6d,0xe4,0xee,0x38,0x42,0xd3,0xeb,0xca,0x20,0xa5,0xda,0x22,0xa3,0x63,0xa7,0x57,0x5e,0x7a,0x55,0x12,0x82,0x95,0xf2,0x72,0x11,0x48,0x4a,0xf5,0x7c,0xd5,0x31,0x09,},"\x08\xde\xb3\xb8\x32\xf5\x2d\x65\x56\xf7\x8c\x3f\x0a\xbe\x46\xf1\xef\xe4\x5e\x3d\x5d\x88\xe7\xf8\xed\xf8\x03\x67\x0c\xe4\x61\x29\x21\x74\x9e\x9e\xce\x63\xfd\xc9\xbe\xf2\xba\x48\x38\x12\xbb\x62\x2b\xe7\x44\xd4\x04\x04\xfd\x6e\x09\xc9\xe1\xcb\x7c\xe1\x9d\xe8\x1a\x9d\xad\xf5\x56\x35\x2e\xe8\x98\x10\xc7\x6a\x9b\x10\x47\xac\x62\xb1\x6e\xbb\x7d\xa2\x3d\xdc\x2d\x4a\xb7\x6a\x02\x05\x61\xd0\x2d\x41\xb5\x8b\x94\x95\x3a\x23\xfa\xaf\xdd\xd7\x81\xb7\xdc\xa7\xb7\xfb\xee\x70\x6e\xc1\x0a\x73\x12\x5b\xf7\x44\x36\x05\x6b\xf3\xb4\xf2\xa0\x70\x1c\xfe\xf0\x5b\xeb\xd3\xdd\x8e\xef\x30\x6c\x1a\xc1\xb0\x09\x50\x88\x1f\xf0\x5a\xb5\xc8\x24\x8a\xd1\x09\x6a\xc9\x1d\x52\x6a\xe5\x9b\xa0\x58\x3b\x27\xdb\x7d\x1e\x39\x0f\x57\xa5\x88\x9e\x27\x99\xa4\xa1\x51\x9b\x15\xd9\x3d\xbf\x0b\x21\xd4\x50\x87\x3c\x76\xba\x52\x04\x61\xe8\xbb\x5c\x83\xc9\x01\x2e\xac\xd5\x57\xbe\xa6\x40\x58\x6e\xfc\xb8\x69\x00\x76\x47\xd4\x49\xf9\x1c\xcd\x52\xaf\xe3\xa8\x94\x77\xde\x7c\x2b\x64\x7e\xcc\x9b\xf9\x67\xfb\xf5\x76\x9d\x74\x88\x94\x47\xd9\x52\x2d\x9e\x80\x69\xc3\x49\x9a\xf6\xa8\xa1\x09\x7a\x95\xd3\xbc\xc5\xf8\x34\x33\x93\x44\x84\x31\x4c\xb3\x07\x58\xb5\x25\xfe\x53\xe9\x07\x21\xdf\x5c\xbe\x03\xd9\x6f\x0d\x0f\x98\x52\x1f\x01\xa5\xfb\xe5\x7c\xe8\x80\x4d\xbd\x18\xf8\xf5\xea\xc8\xf7\xdb\xb5\x8c\x41\x78\x9a\x44\x43\x3f\x8a\x8d\x12\x45\xd2\xad\xda\x8c\x78\xd8\x81\xc6\x5e\xa6\x61\xab\x17\x8d\x4f\xc2\x63\x4c\xd6\xcb\x51\x4a\xb6\xf2\x54\x3e\x91\x12\x18\x3f\x3f\xf7\x3a\x3f\x45\x01\x06\xb0\xee\x8a\x34\x7a\x80\xcb\x82\x4a\xc1\xf8\x01\x64\xe3\xbb\x51\x23\x69\x8d\xe0\xe7\x47\x35\x9c\xa3\x5a\xca\xa3\xba\x0c\x94\x3b\xea\xcd\x7a\x9b\xdf\x8f\xf7\x39\x78\xe9\xfb\x00\x20\x45\xe8\xfe\x56\x48\xcc\x0f\x9c\xfa\x88\xb0\xd8\x12\xe8\x1a\xa6\x2e\x0d\x9c\x73\xfe\x61\x3a\xfd\x95\x39\xbc\xb6\x15\x72\x1f\xb4\x97\xd6\x2f\x65\xc8\x3b\x87\xa6\xd2\x14\x3f\x9b\x1c\x88\x0e\xc8\x67\x1b\xd4\x2c\x8d\xe9\x57\xb1\xa6\x8e\xe4\x92\x26\xff\x71\x7c\xcc\x6e\x74\xf2\xee\xe4\x9c\x30\xde\xa5\x3f\xec\x3c\xd4\xd9\x0f\x2c\xcc\xd8\xf9\x7c\x55\xd5\xc7\x52\x45\x4b\xe2\xba\x7b\x6f\xf2\x03\x0b\xe6\x7e\x0d\xf5\x0c\x5e\x88\x38\x43\xe7\x16\x12\xf2\xb9\x53\x59\x54\x3e\x2b\xa1\xbf\x2e\x98\xde\xbc\xf5\x76\x8f\x2b\xe6\xfd\x50\x4d\x97\x83\xce\x92\x1a\x81\xe0\x94\x16\xdb\xcf\x2b\xb6\x55\xa9\x24\xb1\xef\x01\x12\xd6\x71\xf0\x84\xa5\xb6\x90\xb0\xb6\x4a\x8b\x9b\xf5\x03\x33\xc3\x59\xff\x3f\xef\x19\x96\x94\xf9\xb6\x29\x24\x24\xf0\x06\x66\xce\xf6\xd0\x6d\x16\x1a\x79\xe3\xa1\xb9\xb9\x62\x9e\xea\x53\x50\x5f\x5e\x36\xae\xad\xfe\x0d\x75\x96\x72\xb0\xff\xe4\x98\x39\x7d\x90\xa5\x5d\x99\x44\xb3\x05\x41\xa7\xe1\xbd\xac\x53\x02\x06\x40\x13\x7d\xc2\x52\xae\xf6\x22\xf3\x81\x9d\x36\xab\x49\x8d\x76\x3e\x43\x27\xba\x85\x80\xdd\x9f\x7e\x5f\x47\xc2\x4c\xc9\x92\x87\x34\xb7\xe6\x21\x12\xc5\x7e\x3e\x0c\xfe\xde\xcd\xcb\xac\xcb\x0c\x45\xaf\x82\x19\x45\x5e\xe7\x22\x3c\x71\xe7\xe2\x04\x10\xc5\x24\x4e\xb8\x27\xaf\x2f\x39\x35\xce\x47\x55\x44\x47\x47\xaa\x94\x5f\x4c\x26\xdb\x3a\x29\x85\x19\xe7\x5f\xc6\xba\xce\x91\x52\x99\x72\xe8\x69\x1b\x69\x4d\x30\xaa\x8b\x5e\xc4\xc1\xa0\x28\xd3\xbd\x10\xbd\x0c\x8a\x40\x8f\xb7\xd9\xd7\x03\x49\x55\x53\xec\xea\x59\x8d\x06\x22\xdc\xc7\x4d\xe4\x89\xba\x71\x95\xcd\xae\x8d\x5c\xff\x98\x55\x92\x18\x37\xb5\x28\x43\x3e\xe5\x5c\x0b\x70\x90\x85\x7a\x0c\x27\x84\xd9\x31\x0b\x48\x25\xa7\x99\x3a\xd9\xc6\xf1\x8f\x83\xbc\xa5\xcc\x6a\x25\x04\x71\x68\xa8\x37\x6b\x06\x2e\x3a\x48\xea\x90\xca\xd8\x8e\x33\x11\x87\xc2\xb6\xf2\x81\x42\x6f\x81\xf7\x88\x04\xa8\x95\xc4\xec\x06\xc3\x41\xfe\x84\x6a\xf4\x52\x7e\xa2\x60\x69\xdc\xf6\x1d\x81\x3f\xdd\xf0\xfc\x43\xc7\x07\x35\x0b\xfb\x2f\xc1\xcf\xfc\xee\x7d\x7c\xcd\x7d\x75\xf7\xa4\x65\xa3\xd1\x4d\x57\x30\x2c\x14\x6a\xba\x3e"}, +{{0xde,0x8f,0x1c,0x99,0xe7,0xf8,0x55,0x6d,0xf2,0x0b,0x59,0xb8,0x50,0x4c,0xff,0x7c,0x6c,0x52,0x41,0xa8,0xae,0xeb,0x30,0xb9,0x2e,0xab,0x97,0xbf,0x48,0x1d,0x0f,0xe9,},{0xe4,0x63,0x79,0x1d,0x0f,0x56,0x7e,0xe7,0x3a,0xbb,0xf4,0x7d,0xd5,0x71,0x67,0xa5,0x35,0x61,0x3b,0x05,0xcd,0x48,0xd9,0x2e,0xbc,0x7d,0x24,0xe6,0xeb,0xff,0x95,0x73,},{0x30,0xab,0xc4,0xe4,0xe4,0xb3,0x88,0x58,0x1e,0x66,0x8b,0xd4,0x09,0xee,0x18,0xa6,0xed,0xe8,0x1a,0x13,0x6c,0x28,0xa2,0x92,0x4d,0xf5,0xfc,0x00,0xd7,0xc2,0x80,0xd9,0x78,0x62,0xae,0x3a,0x67,0xa9,0x35,0xce,0x49,0x23,0x64,0x13,0x5e,0x65,0x9a,0xdb,0x5f,0xba,0xbe,0x68,0x98,0x16,0x59,0x1f,0x49,0xac,0x50,0x22,0xa3,0x87,0xcc,0x09,},"\x38\xd9\x3e\x5c\x98\x01\xdb\x90\x17\x97\xec\x75\xc6\xdd\xdc\x65\xae\x79\x80\xde\x21\x0b\xed\x43\xb3\x3e\xb4\x4c\xdc\x6d\xc9\x93\x3f\xb6\xbe\xc7\x42\x1d\xb1\x0f\x0a\x59\x32\x0b\x9e\x64\x2a\x21\xf1\xdd\x23\x56\x01\xfc\xd6\xc5\x3b\xe4\xa8\x77\xf4\xfe\xd3\xfa\x4a\x0a\xd4\xdc\x6e\x9b\x39\x1b\xcf\xa4\x34\x90\x69\x25\xba\x45\xec\xc5\xb4\x35\xd9\xab\x8c\xfa\xfc\x39\x4b\xdc\xca\x9b\x07\xd5\x66\x83\x93\x44\x6e\x34\x00\xe9\x03\x94\x35\xa1\xdc\x78\xcb\xc0\x88\x07\xa3\xfb\x24\xca\x8b\x19\xf6\x4e\xa0\x8b\x8b\xf6\xc2\x0a\x19\x5b\x51\xff\x80\x15\xf3\xe7\xc9\x1d\x08\xe4\xbc\x62\x41\x55\x95\xa5\xa8\x82\xfb\xa6\x51\xdc\x3a\x67\x51\x87\xaf\x61\x82\x49\x74\x7b\x46\x80\xd1\xd1\x5a\x20\x2e\xa9\xdf\x48\xb1\xc2\x14\xfd\x40\x34\x66\xfd\x1a\x26\x5f\x2d\xef\xaf\x8e\xd5\xa6\xbf\x0e\xb0\x8d\x18\x64\xf2\xa2\x8e\x94\x72\x14\x3c\x6f\xd1\x03\xb6\xb1\x08\xc0\xd1\xd1\x36\x3b\x99\xf9\x20\x2d\x11\xf0\x20\x56\xc2\x79\xcc\xa3\x15\xdb\x1a\xb6\xd3\x10\x18\x45\x8f\x57\xba\x33\x16\xcd\x27\x38\xe8\x0c\x49\x2d\x85\x7c\xb1\x74\x99\x25\xe3\x31\xc6\x58\x58\xb5\x09\x83\xcd\x98\x38\xcf\xd2\x18\x8a\x5e\x8f\x05\xb4\x71\xfd\x3c\xdd\xcd\x30\xd9\x69\x01\x19\x40\x20\xf1\x15\xfb\x46\x9a\xb5\x84\x90\x06\xdf\xfa\x2d\x54\x3a\x13\xb3\xb5\x06\xed\x65\xcc\x45\x75\x32\xb8\xaa\x3e\xe3\x1d\x9d\x8d\x9e\x52\x98\xd7\xac\x70\x7a\xc1\x5b\x82\x7a\x57\x8c\x81\xd4\x34\xf8\x4c\xb1\xb5\x61\x20\xd6\x67\xb2\xaf\xe6\xd1\x53\x0a\xfd\xdf\xb9\x66\xd9\x53\xbe\x7e\x32\xdf\x07\xde\x38\x9e\x2d\x04\xb2\x32\xd3\x51\x2c\x7d\xb9\x35\x8f\xc9\x44\xd1\xb1\x18\x07\x8e\x69\x99\xe8\x91\xbb\xfa\x4a\x43\x29\xf6\x5d\x80\x71\x88\xb5\x98\x58\xc4\x31\x21\x1b\x29\x57\x6f\x44\x96\x13\x8b\x7c\x0c\x12\x8f\x7b\xef\x5f\x79\xb0\xf4\x46\xfc\x6b\x4a\x0e\x20\xbc\xa4\xc4\x0a\x83\x57\x1a\x36\x64\x4a\xbf\xfa\xbd\x49\xcb\x58\x5f\xd0\x64\xc8\xe5\x09\xd9\xa0\xfc\xff\x46\x26\x76\xf0\xeb\xcb\x61\xce\xc6\x1e\x51\x2b\xe6\xf1\x82\xab\xd5\x9e\x09\xf6\x42\xaa\x61\x96\x34\x85\x34\x82\xec\xe8\xf8\x98\x00\xf9\xc5\xbc\xfb\x84\x14\x31\xca\x06\x91\xed\x8d\x80\xe0\xa2\xfc\xb7\x97\xa0\x36\x89\x7c\xfb\x65\x37\x58\x6b\x31\xc0\x0b\x79\x65\xef\xdd\xfd\xa7\x28\x61\x84\x50\x26\x45\x91\x57\xf7\x9e\xba\x1b\xca\xf6\xcd\x41\xd6\x18\xae\xb1\xbd\x8d\xa1\xbe\x98\xf0\xcd\xc7\xf2\xe0\x9b\x90\x3d\xe4\x9c\x0c\x1b\xe9\x1d\xcc\x17\x7b\x29\x80\x96\x83\x6d\xce\xa4\xf6\x01\xdd\x86\x69\x15\x55\x12\x83\x25\x43\x8b\xd9\xcc\xbf\xc0\xe7\x77\x92\x0a\xe8\xbb\xd5\x76\x34\xc6\x10\x4f\xe6\x9a\x3a\x72\x01\x2a\x23\x60\xb6\xe5\x52\x55\x0c\xff\xb4\xe2\xf0\xb4\x1f\xe1\x55\x37\xee\x0e\x6f\x37\xe7\x88\x0f\xb4\xd1\x2b\xef\x6c\xad\x26\x6c\xe5\x8d\xf9\x81\x6b\x35\x96\x0c\xd0\xbf\x86\x52\x86\x2e\xe7\x89\xcc\xc3\x1a\x7e\xfc\x21\xa8\x1b\xda\x46\x14\x6b\x11\x1f\xcf\xd9\x4f\x04\x85\x6a\xb6\x1a\x55\x7b\x1f\xf7\xc8\xe4\xea\x6d\x9c\x4b\xcd\xd9\x3b\x15\x1a\xa0\x84\x61\xc5\x68\xde\xfb\x2a\xef\xdf\xce\x96\x39\x4d\xc8\x22\xd4\xef\x6c\xc4\xb9\xa3\xe6\xc3\x32\x03\x9f\x65\x38\xaa\x0d\xf8\xde\x81\x26\xd9\x0c\x31\x2f\xf4\x96\x88\x74\x86\x11\x15\x65\x53\x43\x46\xa7\x46\x26\x25\xd6\x3d\xf6\x9f\xcb\x57\x41\x90\x6f\x19\xe0\x0f\xc8\x00\x3f\x08\xb9\x59\x85\xc3\x8b\x86\x74\xaf\x42\x3c\xa5\x6d\xe5\xf8\x81\xb5\x9c\x46\x62\x43\xa7\xad\xba\xdb\xa2\x9c\xaf\x57\xfa\x77\x71\x22\xe6\x18\x23\xb4\xe7\x08\x18\x2a\xaf\x37\x20\x6d\x7d\x5e\xd0\x51\xc1\x2a\x5c\x0f\x6b\x43\x71\x04\x3f\x56\x2c\xdc\x02\x9d\x5e\x1b\xa9\xb2\xbf\x5f\xfb\xf1\xf5\xf5\x23\xdb\x06\xfe\xca\x42\x7d\xb7\xa0\x88\x19\xff\xb2\xd0\x58\x52\x42\xe2\x0d\xa5\x8e\x32\x0b\x16\xb1\x6e\x44\x8d\x8b\xe0\xef\x74\x02\xd2\x4a\x71\x94\x25\x71\x33\xbd\xc9\x82\x31\x4d\x83\xad\xbc\xd1\x2e\x8a\xf3\x13\x03\x42\x6c\x59\xff\xd8\x26\x9c\xe4\xb9\x87\xca\x9b\x6f\x0f\xfd\xbb\x4d\x1d\x12"}, +{{0x07,0x36,0xf8,0x01,0x72,0x0a,0x94,0x7c,0x5c,0x2f,0x32,0x58,0xce,0x0d,0x51,0x1c,0x3e,0x17,0xe9,0x4e,0x37,0xb3,0x0a,0xdf,0xa5,0x20,0x95,0x92,0x11,0x71,0xd4,0x00,},{0x4f,0x69,0x42,0x55,0x92,0x0d,0x0c,0x38,0xde,0x6e,0x72,0xe1,0x65,0xc3,0x3a,0xee,0x76,0xb1,0xcb,0xf6,0xf4,0x83,0x7a,0xa5,0x90,0x14,0x75,0x66,0x7a,0xcd,0x28,0x26,},{0xc0,0x3c,0x03,0x14,0x85,0x12,0x79,0xed,0xcd,0xe9,0x70,0xc2,0x3e,0xfa,0x23,0x6f,0x23,0x5e,0xda,0x96,0x0d,0x2c,0x27,0xd3,0xca,0x94,0x6f,0x65,0x0c,0x20,0x0b,0x4e,0xba,0x04,0xbe,0x66,0x8f,0xf6,0x2e,0xaf,0xfa,0x6c,0xea,0x35,0x1a,0xbd,0xfc,0x54,0x40,0x1d,0xcc,0xce,0x3d,0xba,0x78,0x00,0x4a,0xec,0x95,0x81,0xa2,0xcc,0xf4,0x0f,},"\x7f\x87\xb5\x1f\x6e\xad\x2d\x44\x02\xa3\xbd\x3c\x37\x69\xa2\x67\xac\x8e\x82\xf7\x79\xad\x7b\x98\x6d\xec\x82\xcb\xfc\x1e\xa5\x12\x91\x88\x43\x26\xd9\x22\x69\x67\xcb\x66\xa9\x68\x73\x18\x4f\x0e\x83\xb3\xab\x25\xa5\xab\x2f\xa8\x05\xfe\x3a\x0e\x7b\x19\x0a\x62\x2d\x46\x1b\x78\x30\xa3\xf6\x97\xc8\x31\xc2\x9e\xa7\xc0\xcd\x4b\x68\xd8\xe7\x7a\xa6\x97\x11\xcf\x86\x4d\xc1\xd5\x39\x4f\x48\x45\xe2\xfb\xb5\x07\x64\x04\xe0\x9a\x88\xb7\x9f\x05\x67\x05\x51\xbc\xe2\xef\x54\x68\xb7\x9d\x57\x88\x8b\x98\x52\xa4\xbb\x47\x9a\x4f\xd0\xbe\xb6\x81\xfd\x52\x3f\xc5\xbf\x44\x58\xab\xbc\x38\xec\xe7\x2e\x10\x6e\x00\x22\x20\x15\xa5\x7e\xbe\xc5\x5b\xf4\x75\x13\xe2\x5c\x3c\x45\x54\x84\x3b\xda\xcb\xcf\xe9\xf1\xb8\xd0\xae\x35\x4e\x48\xd0\x3f\xde\xbd\xf2\x0d\x65\x5b\x52\x68\xd8\xbb\xbf\x33\xb1\x28\x89\x10\xf0\x44\x4f\xcd\x56\xc0\xda\x7b\x89\x03\x36\x2b\x7e\x37\xa8\x64\x65\x42\x77\xcf\xfb\xe6\xc6\x08\x57\xf0\xb3\x51\x4d\x22\xa4\x0b\x9d\xd2\xd3\xfe\x5c\xae\xa5\x50\x7a\x0d\xe3\x05\x1b\xb3\xa4\x01\x5f\xa0\xfe\x4c\x46\x2b\x98\xfe\xf2\x35\x7d\xcf\x6b\x97\xdc\x75\xde\xf3\x82\xf9\x01\xf9\x6f\x4a\x04\xa3\xef\xc6\x02\x54\x20\x0a\x2c\x4c\xdc\x8a\x58\xb2\x5d\x94\xe3\x29\x54\xea\xff\x15\x11\xac\x46\xe3\x60\x66\x63\xb6\x87\x5f\x13\x64\x99\xda\x6a\x76\x90\x97\x87\x9a\x6e\x08\x34\xd5\x64\xfa\x7f\xdb\x99\x58\x11\x83\xed\x0c\x9d\x48\xfd\x19\x5d\x7e\xcd\x9f\x4d\xd4\x86\x55\x65\xfd\x17\xa0\x08\x71\x8d\xcd\x76\xf6\x8a\x54\xe5\x16\xa2\xb7\x30\xed\x3d\xba\x5c\x2c\xf4\x06\x30\xbb\xfe\x7f\xa0\x3b\xb7\xcd\xd9\x67\x69\x54\x95\xa7\xc8\x6e\x2e\x84\xcb\x01\x7e\xc6\x96\x01\x92\x46\x31\x59\x5a\xff\xaa\x8c\xfd\x04\x8d\x14\x26\x7c\x73\xe5\x4c\xfa\x53\x90\x47\xe7\x17\x69\x1e\x39\x97\x37\xfa\x50\xcc\x48\x44\x96\x12\x57\xc9\x3d\x72\x53\xd2\x32\x26\xb7\xcd\x0d\x1b\xd3\x1f\x3f\x0d\x2d\x89\x2d\x07\x3d\x8c\x50\x73\xc6\x02\xf6\x1a\x04\xd6\x43\x7c\x39\x03\xeb\x4a\x64\xa0\x1f\xbc\xc0\xc7\xe1\x59\x20\x1c\xdc\x4a\xa4\x2e\xf3\xb1\xff\x9c\x78\xfc\x27\x5c\xfb\x11\xa0\x5f\xfe\xd8\xf9\xf2\x2d\x85\xba\x92\x4d\x8d\x32\x23\x1c\x25\x4d\x89\x8d\xa7\xf0\x67\x9a\x64\xca\xb8\x40\x26\x90\x6e\x9e\x85\xf9\x5e\xfd\x8e\xe2\xa1\x72\x56\x33\xf4\xde\x2b\xa6\x7d\x99\xaa\x7f\x05\x50\xaf\x13\x9e\x9f\x8c\x52\x93\x78\x67\x27\xd8\x26\x30\x29\x6d\x5d\xaa\x9e\x83\x0a\xa1\xb3\xb5\xb3\x02\xb8\xb6\x62\xac\x83\x2e\x92\x13\x01\x6b\xa4\x93\xa0\x3a\x28\xcc\x3e\x95\x40\xd0\xd6\x5a\xcd\xdb\xfe\x12\x52\xb5\xc1\x6a\x84\xa4\x45\xce\x75\x41\x5c\x6c\xd8\xab\x16\xfe\x5e\xef\x11\x70\x97\xd7\x1e\xb5\x67\x6b\x9a\x95\xb3\x58\x82\xa7\xc3\x50\x6b\xc5\xd0\x2f\x03\x91\x0a\x63\xd4\x68\x46\xb2\x13\xc3\xc9\xbb\x2f\xc3\x4e\x6c\x69\x01\x7d\x20\x65\xa1\xad\x3c\xe3\xfd\x14\xab\x00\x14\xf5\x84\xe5\x7e\xa9\xd9\x03\xe4\x0a\xce\xb2\x30\xa8\x69\x3f\xa2\xe6\x36\x41\xc2\x54\x38\xff\x7a\x16\x38\x76\x04\x38\x84\x4c\xdf\x00\x11\x80\xf5\xb1\x77\xbe\x69\xed\xf7\xef\x66\xb3\x93\x12\x80\x52\x14\xcb\x17\x70\x6c\xef\xe5\x45\xbe\x5a\x77\x01\x9a\x5e\xc5\x2b\xbf\x78\x85\x0f\xa3\xd9\x7d\xe2\xd4\xd7\x4a\xa6\x8b\x58\xca\x81\x2a\x1b\x15\x6a\x0c\x40\x01\x12\x9f\x06\x72\x32\xa6\xec\x91\xa5\xed\x42\x70\xf2\xa4\xc6\xef\xee\xe7\x87\x00\x47\x70\xc8\x59\xe4\x50\xe8\x37\xef\xb0\x4d\xc9\x98\xbd\x27\x3c\x27\xa0\x98\x55\xe4\xec\xa1\xa2\x2a\x9b\x88\xc1\x7b\xdb\xf2\x53\xa7\x97\x61\x07\x0a\x76\x81\x7a\x7f\x74\xff\x3f\x07\xfb\x71\x8b\xff\xa0\xb4\xf3\x26\xf2\x84\xe6\x2f\x83\x68\x32\x42\x7b\xe8\x2f\x48\x33\x73\x51\x5b\x9b\xf5\x9a\xf4\xa7\x6a\x57\xe2\xf4\x0b\x91\x03\x4d\xd5\x68\xec\x14\xac\x10\xe2\x30\x9b\x87\xe2\x92\x2f\x9c\xd9\xfc\x1a\x46\xa4\x7e\xd3\xbc\x7e\x1b\x9f\xeb\x9e\xe0\x67\x07\x3f\xa5\xdc\xe2\xa6\x75\x30\x52\x6d\xe6\x7e\xe0\xe5\x09\x66\x3c\x44\x46\x7e\xeb\x59\x42\x01\x03\xeb\xcd\xff\xa7\x09"}, +{{0xfa,0x75,0x65,0x04,0x91,0x04,0x74,0x28,0xd3,0x63,0xb5,0x82,0x22,0x22,0x12,0x2d,0xff,0xb5,0xa9,0xfd,0xdc,0x60,0x3c,0x33,0xc8,0xa6,0x08,0x61,0x83,0x75,0xdc,0xf3,},{0x98,0xc9,0x64,0x1f,0xa9,0xdf,0xa8,0xea,0x13,0xe0,0xd1,0xc7,0x16,0xb8,0x67,0x9e,0x26,0x4b,0xe1,0x5d,0xd2,0xd4,0xc0,0x6a,0xb4,0x3c,0xbe,0xe4,0x79,0x16,0xee,0x01,},{0x1e,0xff,0xbf,0x92,0x99,0xa1,0xb9,0x35,0x4f,0xe1,0xf1,0xde,0xc1,0x76,0x65,0x95,0xea,0x76,0x7a,0xb8,0xe4,0xda,0x9b,0xb5,0x7b,0x4f,0x69,0xbc,0xbd,0x8c,0xb3,0xd8,0x6f,0x76,0x83,0x92,0xf5,0x9b,0x39,0xfa,0xfa,0x8a,0x21,0x0a,0x65,0x09,0xfe,0x0d,0x60,0x08,0xd6,0x35,0x61,0x11,0xad,0xfb,0x37,0x99,0xc1,0xd5,0x59,0xc2,0x63,0x09,},"\xf5\x4e\x41\xb9\x39\xe3\x7d\xf1\x7c\x7d\x60\x43\xfd\xed\x14\xa9\x15\xd9\x34\xe8\x67\xc3\x45\x26\x9f\xdc\x01\x77\xf5\xbd\x10\xc4\x34\x8f\x31\x9e\x0a\xb9\xa6\x4c\xc0\xb7\xd4\xe0\xc9\x1c\xa9\xaa\xda\xab\x2e\xdc\xba\x54\x4f\x14\xed\x2c\xb5\x39\xca\x89\x75\x09\x7d\x87\x92\x70\x95\xb4\xeb\xd4\x90\x34\x43\x40\x06\x1e\xd9\x3c\x38\x16\x7e\xda\xa0\x96\xa2\x30\xdb\x59\x62\x4c\x67\xfb\x9a\x1e\x1d\xda\xc4\x02\x13\x3f\x4d\x47\xcf\xc1\x1e\x2f\xae\x6b\x3f\x3c\x50\x01\xcb\xa9\xa8\xae\xd9\x00\x73\x10\x32\x40\x22\x7e\x71\x6f\xf7\x1b\xf6\x8a\x59\x1b\xa2\xce\xff\x2d\x31\xb8\x6e\xf2\x1a\xb0\x12\xec\xcd\x40\x9a\xd5\xc2\x9d\x65\x9a\x1b\x37\xc4\xd8\x55\x05\x30\x41\x40\xfb\x2c\x34\x37\xa2\x06\x86\x8b\x13\x52\xc1\x02\xbb\xfa\x3b\x9a\x76\x52\x2a\x2b\xfc\x54\x06\xb2\x57\x69\x6d\xe7\x4e\xe7\xd3\x15\xc8\xe9\x9c\xaa\x96\xbd\x83\x80\x06\xc6\xda\x2a\x42\x33\x31\x5a\x85\x6a\xcb\x8e\x80\xc3\x31\x68\xb3\x33\x55\x1d\x91\xd0\x74\x05\x57\x34\x13\x0b\xd7\xd1\x4c\x56\x81\x1e\xba\xbf\x7d\x5a\x25\x0e\x60\x72\x59\x3d\x9f\x2f\x8b\x97\xc1\x2a\x70\x3c\x2c\x47\x9c\xb0\xb1\x5b\x7a\x27\x75\xc9\xdc\xd2\xca\x46\x24\x67\x23\x68\xa2\xe6\x14\x54\x67\xf3\xbe\x66\x15\xf9\x3b\x81\x20\xa0\xa1\x2d\xa1\x56\x06\x63\xa2\x6a\x61\x73\x19\x66\xb4\x4b\x29\x9e\xbf\xad\x2a\x95\xc6\x23\x60\xf3\x9c\xe0\x5d\x95\x58\xe3\x05\xee\x23\xa5\x2f\xa5\xce\x20\xf6\xbe\x5e\x26\x2a\xff\x3a\x86\x4d\x5d\xda\xbe\x23\xff\x94\x3f\x71\xd5\x99\x84\x93\xd9\x9f\xe2\xac\x23\x74\xb4\x64\xa6\x91\x83\xc3\xbc\x4f\x1d\xdb\x88\x36\x11\x14\x9d\x7d\xdb\xf1\xe8\x38\x0b\x54\x43\x35\xe2\xb8\x93\x95\x05\x4c\x9f\x25\x58\xdf\xc5\x6e\xa9\x3f\xf1\x4d\x0f\x15\xd2\xe0\xbd\x89\x37\xa5\x56\x38\x7d\xe9\x6e\x41\x8d\x8b\x3a\x7d\x66\x6f\xb1\x90\x36\x4b\x2c\x21\x90\xd3\xc2\x5f\x17\x52\xd5\x48\x3d\xcb\xb5\x96\x00\x64\xf0\xc8\x7f\xcf\x8f\x31\x3d\x28\x78\x1c\x11\x4a\x16\x9b\x69\x0a\x87\x01\xc5\x0d\x89\xc7\x73\x24\x53\x1c\x0f\x84\x9d\xba\xd1\x63\x3d\x92\x5a\xcd\x06\xc1\x6a\x9c\xea\x19\xa4\x34\xeb\xc4\x2a\xeb\xb1\xfd\xb9\xb0\xba\xcc\x93\xce\xc3\x99\x19\x94\x36\x64\xea\x1a\x95\x84\x06\xff\x9e\x49\x35\xc9\x2c\xa7\xc3\x97\x08\xf9\xca\xb7\x10\xa5\x83\x09\x6b\x4e\xd9\xf4\x8d\x9e\x09\x06\x47\x24\x0d\x76\xec\xcb\xab\xa5\x91\xf5\x5f\xe7\xe3\x6d\x72\xc2\x17\x27\xac\xba\x0f\x80\x30\x95\x4e\x62\xbc\x58\x0b\x8b\x67\x0c\x44\x57\xc3\x40\x3e\x36\x9a\xc2\x0e\x66\x0d\x66\x2f\x7f\x6a\x41\x42\x13\xea\x43\xf7\xc0\x10\x50\x09\xc1\xde\x81\x7a\xdf\x6f\xfd\x9c\xca\x3b\x45\xa6\x3a\x82\x22\x81\xc6\xe2\x77\x2f\xd7\xb7\x80\x96\x03\x18\x4b\x48\x79\xb1\x8c\x88\x79\x03\xf0\xfc\x8d\x8e\x1e\x2d\xbf\x6e\x77\x2f\x0b\x2d\x9b\x8a\x29\x92\x7a\xcc\x81\x71\x4a\x22\x56\xad\x8d\x7b\x73\x30\x52\x7d\x7d\xbf\x8b\xef\xd8\x2f\x8c\x9b\xb4\x01\xcf\x0a\x90\x24\x9a\x64\xca\x6f\x88\x33\xdb\x31\xbd\x03\xb9\xe7\x94\x6d\x06\xdd\x04\x38\x3d\x7c\x08\x2d\x70\xae\xb3\x7f\xf8\x4c\x2b\x05\x7d\x97\x3b\x89\x4b\x4a\x03\xec\x7b\xf0\x31\xae\xa6\x56\xa1\x90\x84\x88\x89\x4a\x4a\xda\x3f\xd7\xfa\xdf\x91\xed\xe9\x55\x0d\x38\x41\x5f\x82\xa0\x94\x55\xc0\xf4\x32\xfb\x55\x98\x71\x32\xf0\x00\x42\xaf\xd6\x0e\xa5\x1d\x1f\x1c\x6c\x1a\xfe\x0c\xf8\x7c\x34\x6e\x31\xe6\x3e\x26\xf4\x9b\x13\x71\x77\xb2\xd4\x7a\xb3\x0f\x07\xce\xa0\x71\x93\x12\x74\xcf\x01\x08\x36\xd6\x83\xff\xf3\xbe\x71\x34\xc7\x8b\x8b\xfd\x8b\x1b\x8f\xc2\x04\x9e\x18\xcc\xb1\xe1\x8a\x0a\x95\x85\xa7\xd8\xa1\xe2\x54\x92\x60\x86\x68\xc9\x6d\x62\xa0\xac\xa8\xef\x90\xe0\x48\xd2\x03\x78\xc1\x08\xd0\x6b\x03\xfe\x3e\xc4\xad\xb2\x75\x28\xae\x08\xf7\xde\xd9\x48\x78\x93\xae\x64\xca\x4b\x93\x92\x02\xaa\x4c\x17\xaf\xe7\x18\xcd\xca\x49\xff\x96\x16\xd0\xcd\xf8\x33\x4b\x6a\xee\x2d\x6d\x20\x94\x7c\xa4\xbd\x7d\xf5\x31\xdd\x1d\xa9\x95\x81\xff\x72\xea\x56\xfe\x62\xca\xa2\xc9\x5e\x35\x87"}, +{{0xe1,0xc1,0x29,0x46,0xd2,0x21,0xa1,0x94,0xf2,0x2f,0x27,0x62,0xc0,0xe5,0x1c,0xbe,0x3f,0x98,0xb9,0x14,0xa4,0x7d,0x3d,0xc4,0x1a,0x1f,0x45,0xc5,0x43,0x70,0x63,0x7c,},{0x10,0x40,0x81,0x36,0xa6,0x8f,0xc5,0x6c,0x7d,0x3b,0x36,0xb7,0xfe,0xf1,0x22,0x09,0x4d,0xe0,0x81,0x03,0x11,0x89,0xcc,0x84,0xa4,0x88,0x06,0xaa,0xf6,0xcb,0x91,0x85,},{0x8f,0xd7,0xfa,0x40,0x0c,0x03,0x2f,0xcf,0xbc,0x40,0x29,0x42,0xfc,0x78,0x63,0x75,0x26,0xbe,0x97,0xab,0x82,0xf2,0x37,0xbb,0x39,0x3e,0xa3,0x9e,0x35,0x73,0x8c,0x67,0xd7,0x54,0x09,0x54,0x3a,0x8b,0x3c,0x05,0x5f,0x08,0xbf,0x69,0x19,0x9a,0xf6,0x3b,0x69,0x11,0xa4,0x82,0xfb,0x4f,0x65,0x80,0x80,0x2e,0xc9,0xd2,0xdc,0x3c,0x11,0x06,},"\x87\x0f\x4c\xd9\x7c\xfc\x0a\xaf\xad\xa4\x00\x72\x31\x2f\xb5\x4b\xcc\xc0\x76\x28\x71\x4e\x49\x62\xd4\xbe\xf4\xee\xb5\xde\x40\xa1\x9a\x24\x6b\x5b\x7d\x52\xd4\x87\xb7\xe5\x2d\x65\x6f\x2c\x64\x03\xb9\x16\xd0\x2e\x02\xa6\xd2\x91\xc1\xe1\x82\x8d\xd9\x45\xa5\x83\xb4\x38\x52\x8d\x1c\x39\x76\x5a\x57\x20\x31\xff\xa9\x16\xb6\x83\x21\xf3\x2e\x66\x46\xf0\xdc\xc1\xc6\x02\x35\xff\xaa\x32\x35\xf4\x84\xa5\xc4\x97\x8f\xa3\xe6\xbf\x14\x30\x1d\x53\xe1\x2f\x4c\xc5\x21\x18\xb1\xf6\xf0\x7f\x53\x36\xf5\xd0\xa9\x37\x89\xbb\x01\xd1\x62\xfb\x31\x26\xdc\xd7\x56\xe0\x64\x2e\x7e\x69\x89\x63\xc0\x34\x59\x11\xa5\xcf\x3c\x99\x53\xf7\x73\x19\x42\x6c\xea\x2c\xde\xda\x3e\xfe\x98\x9e\xcb\x63\xcb\x9e\xb8\xb9\x20\xde\x76\x6c\x4f\xcf\x63\x36\xe5\xbc\x43\x71\xa0\x68\x37\x1f\xed\x95\xc8\xc2\xb6\x1e\xe9\xb7\xc3\xe3\x83\x1c\x20\xbf\xfe\x87\x07\xc0\xc9\x8b\xe9\x61\x53\xc8\xa8\x73\xd7\xf2\x8a\xfc\xa1\xbf\x71\x08\x5c\xe0\xe3\x89\x9e\xef\x55\x91\xbd\xd6\x66\xdc\x2d\x07\x64\x17\x72\xd7\x45\xc5\x16\x44\xa2\x60\x81\x5b\x20\x8c\x4d\xd3\x05\xf0\x5f\xe4\x63\xd0\xd9\xd5\xa9\xee\xff\x97\x79\xf5\xb1\xd4\x4f\x26\x08\x30\x78\x56\x6d\x0e\x5f\xf5\x6b\x3a\xf0\xe6\x4c\xc3\x87\x08\xaf\x5a\x65\xf6\x54\x35\x2d\xf1\x04\x37\xf1\xdd\xf9\x45\xa0\xda\x1f\x4d\xef\x6a\x71\xa0\x60\xe0\xc4\xad\xec\xca\xac\xf8\x5e\x09\x0f\x70\x90\x37\x0a\xe2\x4e\x52\x38\xd7\x68\xa0\x8f\xe6\xb4\xbb\x5e\xc4\x97\xa6\x60\x31\x98\x60\x84\x15\xc7\xc6\x49\x00\x48\xaa\x36\x73\x7c\x08\x50\x30\x08\xae\xce\x0f\x49\x42\x19\xdd\xf8\x9b\x72\xea\x77\x17\x1c\x6d\x31\x17\x08\x9e\xb8\x89\x07\xe8\xc3\x3f\xb9\xe7\x0b\x0d\xc2\x81\xf6\x64\xb5\xf9\x65\xb5\xd2\xad\xb1\x25\x07\x10\xef\x23\x52\x02\x5f\xb2\x93\x39\x5a\xe1\xd2\x3e\xe3\xb5\x92\xb4\xc5\xf2\xd5\x55\x69\xa5\x45\x86\x54\xce\x3f\xc2\x5d\xd0\xe3\xf7\xe6\x75\x7a\xa7\xb3\x47\xc1\xff\xd3\xba\x4d\x4f\x2c\x4b\x6d\x36\xaf\xd5\x98\x63\xa3\x2a\x59\x4e\x74\x53\x7e\xce\x9b\x8b\x1e\xc2\x69\xbb\xc4\xcb\x54\xd7\x62\x38\x21\x1f\x62\xa9\x8a\x46\xa4\xaf\x66\x2f\xa8\x1e\xba\x6f\x30\xf5\x14\xb8\x66\xb7\x94\x2b\xc1\x73\xf7\x21\x1a\x6c\x01\x4d\xa1\x4e\x74\x13\x27\xa5\x68\x62\x3d\x14\xb8\xf8\x35\xef\x1d\x5d\x62\xb2\x52\x3c\xfe\x6a\x85\xbc\x69\xfa\x05\x20\x0d\xea\xc1\x56\x8b\x94\x6a\x81\x6b\x75\xc5\xd7\x60\x31\x74\xfd\x4e\x2f\x91\x01\xa7\x90\x63\x79\x1b\xc3\xd5\x92\x97\xcd\xc1\x0b\xda\xa6\x63\xab\xf3\xc1\xbe\x2f\xda\x17\xe4\xe5\xce\x39\x4e\x90\xbd\x76\xb1\xf9\xe0\x40\x5f\x56\x75\xb9\x9d\x63\x8a\xbc\x2c\x1b\x2d\x8b\x53\xa6\xfd\x3d\xc8\x37\x58\x55\xec\x54\xcc\xbd\xa2\x4e\x67\x25\x27\x72\x3b\x07\xbb\x59\x9d\xb5\x4e\x38\x79\x33\x91\xcf\x09\xef\x3b\x1f\xd7\x61\x49\x90\x06\x5b\xbd\x4a\x19\xe8\xd3\xd1\x04\x82\x53\xba\x4c\x97\x1c\x2f\x98\xd2\xb3\x59\xdf\x50\x90\x87\x32\x3a\xa6\x90\x50\x29\xf5\xcc\x5e\x1a\x0a\xaf\x2f\x7c\x01\x08\xdd\xb1\xa4\x0f\x56\x2b\xe6\x4e\x57\xe6\x95\xed\x21\xdc\x7d\xb1\x7d\x53\x36\x77\xef\x12\xfc\xbb\xe2\x9f\x3b\x23\x7b\xb6\x34\x4b\x11\x09\xb3\x2a\x94\x62\xab\xc3\xad\x3c\x07\x10\xb0\x4f\x38\xc6\xf5\x95\x2d\xb2\x75\xe7\x7e\x2f\x37\xe9\x5d\x55\x09\x6b\xba\xf3\xe3\x05\xd5\xd7\x43\xd3\x65\x95\xbf\x05\x67\x89\x2c\x21\x0a\xc7\xba\xe7\x37\x1d\x16\x45\x84\x78\x5d\xd8\x90\x17\x41\x59\xb3\x93\x0a\x9a\x6c\xe3\xa1\x66\xdd\xa2\x38\x3e\x6e\x2a\xf2\x8c\x1b\xf3\x19\x24\x47\xe9\x05\x11\xdc\xd8\x0e\xbd\xf9\xee\x2c\x9b\xde\xdd\xee\xb6\x10\x55\x86\x41\x53\x2d\x07\xcd\x13\xda\x61\x25\x41\x54\xcc\x0f\xd9\xd4\x81\xe3\xb0\xa2\x37\xaf\x2e\xc2\x62\x56\xd4\xab\x21\x9f\xaf\x15\xad\x2b\x7e\x8e\x57\xab\x72\x6f\xf2\x72\x32\x16\xa5\x74\x58\x5e\x2a\x63\x9d\x94\x8c\x2c\x4f\x69\xee\xaa\xd2\x83\xe3\xa4\x4f\xf2\x68\xea\xef\xd7\xe6\x6b\x73\xed\xe4\x73\xa8\x39\x7c\x76\xb4\x8d\x56\xcb\x3c\xcd\xab\xc9\x1a\x89\x29\xcf\x42\x99\x83\x50\xe0"}, +{{0x76,0x2f,0x06,0xca,0x01,0xe3,0x14,0x71,0x5f,0x92,0xc9,0x0b,0xbe,0x72,0xa2,0x5b,0xf2,0x62,0x12,0xc8,0x1e,0xb1,0xd1,0xa0,0xda,0xe2,0xc3,0x11,0x30,0xf7,0xcd,0xbb,},{0xf9,0x62,0x6f,0xfd,0x69,0x27,0x31,0x92,0x5e,0x5a,0xac,0xfa,0x1b,0xde,0xd0,0x1a,0xa8,0xf7,0x30,0xb7,0x72,0xd5,0xe4,0x6a,0xdb,0xc3,0x15,0x56,0x5b,0x9b,0xf2,0xc9,},{0xe8,0x42,0xb4,0x9e,0x53,0x3d,0xbc,0x92,0x99,0x8d,0xc0,0x78,0xe5,0x97,0x93,0xa2,0xc2,0xfa,0x63,0x6b,0xdf,0xaf,0xdb,0x48,0x93,0x4c,0x93,0xcf,0x34,0x79,0x71,0x02,0x93,0x8d,0x13,0x7a,0xb7,0xea,0xd1,0xa0,0xf7,0x0e,0x94,0xa6,0x7d,0x57,0xef,0x6a,0x02,0xc9,0xec,0x77,0xd7,0x1f,0x70,0xcc,0x57,0xf1,0x53,0x3b,0xec,0x87,0x73,0x0e,},"\x94\x97\x48\x3a\x4f\xba\x78\x43\x3b\x38\xe9\xde\xb8\x91\x5c\x75\x0b\x6d\xa0\xf7\x8a\xf4\xa6\x8b\x62\xf9\xfc\x03\x91\xe3\x38\x87\x3b\x1d\x64\xb1\xb7\xf0\x9f\x12\xf0\x56\xa3\xc9\x16\x53\x49\x8a\xd5\x6e\x06\x9b\x8b\x16\x08\x87\xe8\xe3\x78\xa7\x6d\x8b\x3c\x66\x70\x83\xc0\xa2\xb2\xd2\x31\x7d\x3b\x87\x48\x57\xe5\x78\x62\xef\x0c\xb7\x04\x36\xa9\x02\x8f\x01\x91\xcc\xc6\x16\xe9\xd7\xc9\xbd\x86\x98\x08\xcf\x09\x48\x35\xff\x51\x86\x77\xb3\xfb\x08\x9f\x4c\x9d\x07\x7c\xc7\x74\x24\x05\xb4\x86\x3a\xc7\xa5\x96\x45\xc9\xcf\x54\x0d\x57\x39\x9d\xa6\xae\x9d\x07\xfd\x19\xfc\xa9\x5b\xc8\xa8\x6d\x8b\x8e\x24\xe4\x87\x33\xf3\x21\x58\xfd\x19\xa8\xa1\x11\x1d\x1d\xa1\xf9\xb5\x80\xa3\x9c\x10\x48\x46\x16\xcf\x2b\xc0\xec\x29\xf6\x3f\x77\xc8\x53\x56\x15\x8e\x16\xda\x59\x4b\x5a\x89\x0e\x55\xd0\xb6\x45\x99\xb3\x02\x93\xe9\x00\xed\x92\xad\x26\x19\x69\xe7\xdf\x4c\x4b\x1d\x0b\x60\x24\xbd\xce\xb6\x90\x67\xef\x48\x6c\x20\xfd\xcd\x22\xa1\x0d\x5d\xa4\x5f\xbf\x90\x5b\xa1\xe9\x35\xc9\x6f\x50\xaf\xb6\x35\x71\xbc\xff\x31\x30\x68\x4e\xda\x0b\x56\xe6\x0b\x26\xcf\x4c\x0e\xf9\x93\x8a\x92\x76\x8f\xc8\x63\x1f\xe3\x08\x23\x6b\x01\x2f\x92\xaf\x24\xa8\xf6\xe6\xec\xbe\x76\x62\x9b\xba\xf8\xff\xe5\x4c\xdb\xe8\x67\x1d\xe2\xba\x62\x4a\x7c\x0f\x61\x93\xbb\xa4\x11\x04\x12\x90\x2b\xac\x29\x90\x92\x2a\x9e\x5a\x81\x05\x3c\xf8\x76\xa4\xc8\x05\xa0\x4c\x56\xa8\x13\x9d\x34\x19\xe4\x54\xa6\x22\xd0\x34\x2b\xf4\x26\xe9\x80\x2c\x3d\xc1\xb4\x08\x0c\x75\x49\x2a\xfe\x9d\x7b\x15\x45\xfe\x08\x6d\x96\x35\x41\x32\x4f\xf5\x2a\x48\xc6\xbf\xae\xa2\x66\x68\xb3\xe0\x1e\x52\x36\xfd\x45\xfe\x54\x59\x45\x35\xc0\xb2\x3e\x28\x7e\xbd\x14\x28\xc8\xbe\x0a\xd1\x41\x60\x0e\x91\xcb\x51\xe1\xea\x66\x27\x1a\x64\x21\xfb\x68\x9e\x88\xa0\x79\x0a\x65\x1d\xbd\x21\xee\x20\x89\xb2\x74\x66\x6f\x66\x0c\xa0\x9c\xe2\xd6\x0e\x39\xe2\xee\x5f\x03\xb6\xeb\x82\xd1\x99\x76\x96\x6e\x79\x90\x0a\x81\x0f\x6d\x5b\x5c\x1a\x54\x8e\x50\x64\xf5\xc3\xd8\xa9\xf2\xde\xf0\x17\x9d\xf9\x9d\x14\x3f\xde\x69\xb0\x71\x2c\x09\x1c\x29\xe9\xb2\x5f\x40\xca\xfd\x57\xa0\x24\x65\x8d\x77\x74\x03\x76\x10\x34\x2f\x38\x00\xfd\x51\xf4\x9e\x79\xa5\xb3\xde\xcc\x11\x2f\x58\xd0\x3e\x3d\x29\x58\x75\x85\x88\xbc\x4b\x1c\x6a\x6c\xda\x7b\xc5\xf5\xbe\x18\x3e\x41\x51\x3c\x1f\x23\x0f\x3c\xc3\x64\x30\x4b\xf8\x24\x84\xb7\xcf\x19\xa0\x02\xe1\x50\xf9\x8c\x5e\x97\xc6\x16\x6e\xa1\x5b\x86\x34\x0b\x8c\x5e\xbe\x5c\x1a\x18\x3e\x55\x88\xe6\x6f\x55\x90\x50\x86\x31\x3f\x37\xa4\x09\xe8\x9b\x47\xdb\x31\xae\x97\x45\x3e\xdf\x69\xfe\xd7\xbe\x08\x11\x30\x71\xf3\x74\xb2\x6e\xc6\x04\x3f\x2a\x0e\x9c\xf8\xba\xd8\x02\xab\xad\x69\xe6\x17\xe7\x62\x43\xb3\xcc\x03\x4b\x09\x9d\x87\x29\xee\x40\x7a\x53\xeb\x03\xbd\xc6\x41\x0a\x03\x95\x04\xb3\xb1\x2c\x81\x9b\x64\x54\x5d\x40\x5c\x6a\x4f\x08\x49\x21\x93\x5b\xdf\xf4\x13\x0a\xe6\x29\xd9\x09\x62\x6b\x06\x26\x76\xe5\x38\xea\xfd\xff\xb1\xd6\x22\x9c\x08\x89\xd3\xcd\xdd\x33\x65\xdc\x3d\x65\x36\xf7\x24\x8c\x49\x31\x7c\xb5\x0c\x56\xfb\x57\x85\x55\x41\xd6\xfe\xeb\xac\x81\x6c\x99\x28\xfa\x66\x2d\x0a\xe8\x0a\x0f\x39\xe5\x70\xbb\x7d\x22\x41\x6f\x98\xf3\x71\xb6\x42\x47\x96\x89\x51\xa8\xa2\x46\xf7\x4b\x30\x61\x74\x3c\x9a\xf7\x68\x4b\xbb\x96\x6a\xe0\xbd\x78\xa8\x10\x49\x3e\xa4\xcc\xd7\x11\x74\x87\x1c\x82\xbb\x65\x2b\x27\x48\xe5\xbc\xcb\x0a\xb6\x38\x8a\x50\xf0\x53\xa0\x48\x08\x7f\xd9\x7e\xb1\x5c\x1a\x21\xb1\xee\x18\x25\xe5\x4a\xa1\x30\xd6\x63\x18\xaa\xf6\x61\xbb\xb2\x47\x63\x57\x7e\xb3\x7d\x31\x0e\x21\x9b\x0a\x9b\xba\x03\x75\xeb\x9c\x9b\x4a\xf8\xc4\xb9\x9a\x36\x99\xe0\xd3\x26\x67\x33\xb6\xe4\xe9\xc5\x34\x49\x0a\x13\x41\xcb\x19\x90\xca\x5b\x1c\x84\x7b\xc8\x12\x60\x26\xfe\xa9\x03\xa1\xf5\x49\xd6\x5a\xf8\xfe\x02\xa9\x16\x3f\xf8\xea\x28\x1e\x72\x26\x24\x3e\x2a\x15\x3b\x92\x18\x51\xde\x10\xf7"}, +{{0xc5,0xcc,0x0b,0x95,0x81,0x8c,0x4b,0xf3,0x8d,0xa1,0xd6,0x5f,0x02,0x16,0x27,0xe9,0xe5,0x7d,0x26,0x2b,0x02,0xec,0x6d,0x91,0x7a,0x7d,0x46,0xb1,0x1c,0x7f,0xe4,0x8a,},{0x45,0x7d,0xa4,0xef,0x14,0x51,0x9d,0x54,0x1e,0xdf,0x92,0xca,0xbe,0xd9,0xb0,0x4d,0x8a,0x2f,0x2a,0xfd,0x15,0x10,0xa9,0x2f,0x00,0x9b,0xb4,0xe8,0x75,0x4f,0x1e,0xba,},{0x3b,0xa0,0xaf,0x8a,0xf1,0x27,0xc4,0x58,0x48,0x26,0x09,0x0e,0xcd,0xaf,0x48,0x5e,0xbd,0xf0,0x7b,0x82,0xbc,0x49,0x9c,0x9a,0x2b,0xef,0xca,0x28,0xd4,0x93,0x44,0x97,0x4a,0xdd,0xbc,0x8d,0x80,0xa5,0x25,0x60,0xe0,0xf3,0xd7,0x3f,0xf5,0xcc,0xcc,0x72,0xc7,0x4b,0x5b,0x47,0xad,0x2e,0x6d,0xe9,0x61,0x2d,0x1a,0x00,0xae,0xc9,0x27,0x01,},"\xd6\x60\x8b\xf5\xac\x00\x0e\xca\xf9\x5f\xc0\x9f\x9c\xb7\x49\x8c\x51\x8a\x6e\x02\x55\x58\x6e\x63\x37\x85\x3b\x1d\x7d\x9d\x7d\xe4\xdf\xe1\x24\x5d\x59\x03\x1a\x31\x7d\x4e\x2b\x6a\x73\xc4\xc3\xf9\x5b\x58\x2e\x72\xa6\x42\x02\x21\x58\x7b\xac\x12\x0f\xb8\xed\x73\x48\x07\x0f\x28\x60\xd8\x58\x66\xa0\x9f\xe7\x56\x74\x34\x97\xf2\x11\x9b\xc1\xbf\xdf\x57\x3b\xe3\x5d\x10\x91\xbe\x37\xf1\x8b\xcd\xa6\x74\x1c\x90\xd5\x66\xcc\x92\x4b\x72\x16\x4b\x74\x9a\xf9\xa6\xf4\x0f\x71\xd3\xea\x5d\x87\x64\xcd\xc8\x17\x14\xbd\x73\x95\xe5\xf6\x79\x97\x36\x36\xef\xf1\xdb\x1c\xf0\x01\x29\x83\xf7\x1a\x2f\x2b\x12\xd4\x5a\x29\x4e\x5a\x38\x9f\x4c\xd2\x48\x3e\xb3\x9d\xa0\xdf\x26\xb7\x36\xc7\xaf\x6e\x41\xdd\x35\xa7\x8e\x45\x29\x2c\x39\x4e\x34\x68\x95\x32\x88\x87\x21\xf8\x63\xc5\x6d\xb9\x7d\xa1\xcd\x10\xa6\x6a\x20\xa6\x70\xb2\x7f\xe8\xce\x55\x68\xa4\x2b\x89\x37\x79\x0c\x7b\xe1\xaa\x42\x0d\x20\x3d\x7a\x88\x5c\x17\x29\xcd\x6b\x8e\x19\x71\x89\xe4\x79\xd5\x42\xcb\xcb\x9b\x53\x65\x6f\x2b\x9f\x53\x9c\x32\x5c\x34\xaa\x59\x8f\xd9\x1e\x7d\xf7\x0f\x9a\x74\xab\xec\x46\x76\x54\xb1\xc9\xa3\xd1\x44\x38\xe7\xc0\x83\x60\x40\xb7\x93\x87\x1e\xcb\xe9\xe5\xf6\x68\x0c\xcc\xcd\x5d\x46\x96\xa8\x7e\x37\xe8\x9e\xab\x28\xb6\xbd\x67\x9e\x8f\xe1\x62\x7b\xdc\x9d\x37\x3b\x82\xf5\x2c\xd8\xc4\x9b\xe9\xba\xcd\xc6\x30\xa3\x2f\xd1\x28\x35\x25\x5a\x54\x2f\xb7\xb1\x23\x93\x77\x9d\x44\x98\xaa\x06\xa0\xe7\xe1\xa4\x97\x79\x39\x81\x7e\xb2\x08\x8a\xf1\xe1\x9b\xb0\xe5\xac\xa8\x54\xc1\x25\xdc\x60\x3d\x83\x57\x36\xa0\x3d\x93\x80\x51\x53\x0c\x9a\xb1\xaa\x3b\xc7\x79\xb3\xba\xe7\x45\x0e\xf5\x7d\x1b\x3f\xc0\x93\xa3\x7d\xbe\x9d\x1b\xd6\xd0\x40\xf2\xf8\xee\xba\x77\xf7\xfa\x88\xc1\x49\xf0\x65\xc7\xac\xe3\x32\x77\xaa\x99\x69\xc2\x66\xea\x6d\x85\xca\xd6\x2c\xfa\xf5\x50\x8e\x70\x32\x71\x6b\xe6\x84\xa2\x28\x56\x41\x3e\x0e\x65\xe4\x2b\x6e\x9e\x6d\x86\x5a\x87\x36\x3c\xbb\x62\xd5\xbb\xb6\xa3\x73\x1d\xdd\xa0\xfa\x6a\xd0\x29\x3a\xf9\x89\x3c\x09\xa9\xe7\x43\x09\x0f\x2c\xee\x2f\x44\x37\x73\x6d\xd4\x33\xe2\xac\x74\x28\xbd\xc8\xc7\x7c\xb9\x96\x43\x55\xfa\x44\x15\xcc\x38\x31\xd8\xc7\xca\x5a\xf9\x3d\x51\x75\x2e\x71\x8c\x60\x66\xec\xa1\x42\x6a\x87\xc2\x98\x08\x28\x1a\x85\xac\x7e\x0b\x40\x44\xff\x6e\x28\x0e\x28\x01\x4b\x93\x83\xd1\x9c\x9d\x38\x7d\x29\xdc\x14\xde\x43\x3d\xa2\x60\x78\x4a\x49\x44\xca\x76\xc2\xfe\x8a\x08\x0d\x09\x96\xd9\xa6\xc2\xa3\xd3\xa7\x07\x72\x80\xed\xce\xe0\x38\x9a\xa8\xe5\x36\x5d\x1d\x9b\x34\x6e\xca\x09\x47\xb0\xff\x52\x65\x94\x3c\xcf\x09\x93\x9a\x4b\x4a\x8f\x98\x5f\x6a\x5e\x72\x72\x3c\x79\x5d\xa0\xbc\x36\x0d\xce\x50\x1f\x67\x3a\xb6\xea\x84\x43\xf1\x29\x42\x79\x52\x45\x3e\xb7\x2b\x3a\x8d\x0d\x97\x6c\x27\x8c\x5b\xd1\xa9\x85\x3c\x91\x8e\x0c\x24\x0c\x3c\x73\x49\x32\x95\x3f\xdb\x50\x39\xfb\xb0\x46\x87\x93\x7c\x9f\xf0\xab\x74\xa1\x6e\xae\x21\x2b\xc6\xf2\x0e\x70\x0a\x77\xc0\x92\xd2\x3d\x2e\xfb\x58\x0e\x0c\x19\xd6\x5f\x30\x41\x29\xab\x8e\x6c\xc1\x2e\x58\x05\x22\x57\xba\x09\x44\x9f\x30\xd3\xd9\x74\x39\x1a\xff\xf5\x63\x3d\xef\x2f\x5c\x4e\xbd\x57\x3a\x9e\x44\x4b\xf3\xa3\xdd\xac\xed\xf0\x2c\x05\xf3\xcc\x2e\x75\x06\x64\xa8\x4a\x1d\x24\xc5\xd2\x8b\x49\x67\x0d\xe8\xa2\xf2\x09\x08\x39\x48\x3c\xa3\x89\x59\x99\x1a\x7d\x37\x27\xe2\x1a\x15\xe8\x20\x16\xc1\x5a\x09\xee\x71\xf4\xf4\x3c\x0a\x60\x8b\x48\x48\x5c\x99\x34\xa3\x86\x14\x79\x4d\x62\x91\xda\xa3\x9c\x01\xc4\x5d\x3d\xeb\xe5\x79\xb5\x82\x3b\xf3\x40\x64\x04\xb4\xc8\x0e\xe6\xff\x34\x2b\x46\xb3\x34\xb0\xb8\x83\xb4\x0b\xfd\x2f\x9a\x53\x59\x5a\xb6\x2f\xd1\x35\x1e\xbc\x88\x30\x83\x70\x49\x72\x18\xdf\xc9\x8c\xe0\x81\x40\x7d\xa8\x12\xa4\x6d\x64\x97\xd7\xaf\x9e\xc6\xd8\x3e\x1c\x60\xee\xb7\x12\xd8\x89\xdf\xbe\xd0\xc8\x05\xaa\x11\xcf\x81\x7d\xd8\xf0\x43\x96\xef\x87\x1a\x26\x11\x2d\xcb\x7c\x0e\x1d\x2e\x68"}, +{{0x61,0xfa,0x86,0x77,0xee,0xda,0xde,0xd6,0x9b,0x16,0x5c,0x8d,0x27,0x7c,0x97,0x82,0x49,0x66,0x30,0x28,0x30,0x1d,0xf6,0x16,0x3e,0x39,0xb0,0x6a,0xc2,0xf5,0x62,0x5f,},{0x87,0x33,0x9e,0xb5,0x72,0x38,0xdb,0x2e,0x4e,0x60,0xf3,0xc2,0x8a,0x3f,0xd5,0xfb,0x61,0x1c,0x65,0xfd,0xdc,0x81,0xee,0xd7,0xcf,0x77,0x71,0xdf,0x34,0xd9,0x22,0x67,},{0xc0,0x4e,0xbd,0x11,0xc3,0xeb,0x09,0x39,0x6f,0xe8,0xd6,0x82,0x79,0x51,0x0a,0x9e,0xfe,0xe3,0x91,0xab,0xee,0x40,0x81,0xf0,0xd2,0x75,0x67,0x4a,0x30,0x47,0x94,0x83,0x5a,0xad,0x7f,0x3e,0x34,0x5b,0xcf,0x0a,0xf8,0x02,0x7f,0x97,0x47,0x7e,0x79,0xe6,0x79,0x2b,0x8f,0x29,0x98,0x46,0xae,0x28,0xcb,0x13,0xbd,0x88,0x75,0x37,0x99,0x0d,},"\x02\xc5\x81\xde\xe0\x3f\x2c\x60\x39\x35\xaf\x5e\xce\xec\xfa\x67\x71\x34\xa3\xe0\xae\xa5\x4f\xec\xaf\x42\x71\xfb\x52\x95\x1a\x27\xb7\x68\x77\xcc\xd4\x9a\xb4\x86\xdf\xc2\x27\xcf\x31\xc9\xd9\x57\xcc\x97\x30\x65\x73\xfc\x7f\xe1\xd3\x1b\x6c\x7d\xf3\xd7\x80\xf3\xa0\x5c\xa6\x39\x56\x57\xa9\x42\x43\x42\xc9\xc6\xb7\x03\x12\x7e\x03\x8d\xf0\x79\x21\x54\xe3\x0a\x49\x47\x61\x12\xcb\x92\xd0\xd5\xa2\xd2\x2e\x89\x57\x52\xa8\x6e\xdd\xdd\x91\x2f\xdc\x81\xb1\xe6\x4a\x7b\xb7\x50\xf0\x99\x18\x21\x32\xee\x48\x23\xfd\xe8\x45\x80\x2a\x94\x45\x39\xd4\x12\xb2\xa8\x1a\x15\xb0\x00\x71\xa9\x50\x50\x4c\x5b\x55\xa7\x1b\xdb\x8c\x5a\x58\x26\x39\xe8\x55\xe8\xbe\x24\x1c\xda\x1b\xa6\xb3\xb4\xf6\x45\x54\xd1\x78\x24\x90\x4c\xb3\x0c\xd7\xef\xd9\xac\x04\x9e\x39\x0b\xb7\x9f\x53\x59\x8e\xf1\xe8\xfc\x27\xdd\x7b\xf5\x99\xc9\x02\x8c\x9e\xbf\x92\xfc\x3b\xe1\x1d\xf3\x29\x61\x2a\x22\x8e\x0f\x56\x84\x68\x7b\xf4\x1f\xf2\x03\xe9\x7a\x76\x86\x12\x6a\x39\x36\x6b\xdc\x26\xd5\x0b\xe0\x25\xd5\x18\x7c\x6b\xa0\x66\x6e\x37\x9b\xe4\xa8\x0a\x9e\x62\xef\xfc\xd9\x16\xd7\xf9\x8d\xe6\x51\xe0\x0b\x97\xad\xf5\xd2\xd5\x3d\xaa\x7f\x8d\x69\x5a\x29\x15\x60\x75\x5c\x74\x44\x82\x36\x4c\x4f\x1f\xa4\x7e\xc0\xb1\xda\x16\x1a\xa3\x88\xf9\x59\x79\x89\xa9\x77\x26\xd3\xed\x2c\xec\x82\xf1\xa1\xbb\xc4\xac\x0b\xe0\xa0\x0c\xb4\xa8\xdb\x1f\xb7\xc1\x4b\xa0\x5d\x89\x63\x48\xdc\x05\x59\xd2\xa9\x0b\xea\xc2\x04\x1d\xd7\x7f\x82\xd6\xb1\x2a\xeb\x22\x43\xca\x0f\x41\x9a\x57\xd3\xca\x9c\x7d\x25\xa3\x0f\xf0\xe8\xbb\x0d\x94\x51\x55\xd1\xb3\x6a\xd1\x07\xb5\x5b\xea\xa9\x5b\x7d\x5e\x32\x00\x34\x07\x62\x9f\x15\x15\xf8\xa7\x08\x9e\x24\x88\xd0\xd7\x54\x4c\x2f\x7c\xc7\xc7\xf0\x98\x5d\xa4\x28\x40\xd4\x36\x8f\xf4\xf0\xfa\x4f\xa2\x98\xe3\xb7\x22\x93\x03\xab\xa5\x14\xae\x94\xe7\x02\x65\x35\xa3\xf4\x26\xff\xbb\x4e\x00\x1c\xd5\x0e\xd1\x2f\x21\x4b\x3a\xbe\xf9\x6e\x30\x16\x35\xc9\x87\xb1\x33\xfc\x5e\x61\x84\xe7\xb7\x57\x2b\xc3\xd9\x9a\x45\x23\xcb\xd5\xaf\xe5\x93\xce\xdf\x4c\x9c\xd0\x2f\xf2\xe3\x62\x37\xe4\xee\x12\xef\x1a\x22\xd1\x6d\x7c\xf4\xc0\x72\xdc\xed\x91\xcd\xd2\x6e\xe1\x44\xcc\x2b\xef\x49\x50\x02\x63\x49\xe9\x44\x47\x84\x08\x1f\xe4\xe0\x49\x8b\xc7\x5f\x72\xe6\x81\x8f\x45\x9b\xba\x90\x49\xc5\x61\x31\x6c\x9f\x49\x8e\x7b\x1a\x99\x4b\x0e\x93\x05\x5f\xe7\x3e\x44\x4c\xbd\xf9\x6a\xc3\x5e\x9c\x4e\x92\xe6\xb4\x9e\x3b\xc0\xe9\x9d\xe1\x71\x6d\xf8\xea\xca\xeb\x8d\x2f\xd7\x48\x70\x04\x4c\xb3\x9c\x0e\x36\x7a\x1f\xe3\x2a\x9b\xb2\x97\x44\x16\x36\x4e\x73\x0d\x52\x48\xdf\xb1\xdf\x16\x4a\x8d\x58\xca\xa1\x00\x5f\xdc\x91\xba\xc2\xbc\x01\xcc\x77\xde\xcc\x14\x89\x3e\xf9\x46\xfb\x3c\x81\xbe\x08\x32\xc7\x2f\xba\x37\x20\x62\xf8\x36\x0f\x4d\x8e\x6d\x5b\x74\x1c\xf7\x03\x2d\x8d\x89\xde\x2e\xdf\x4c\x71\x4a\x29\xf7\x5a\xbd\x8f\x5f\xf4\x3e\xcd\xd4\xb7\xa0\x4d\x7d\xb0\x88\x2d\x16\xe7\x44\x73\xa0\xfb\x79\xdb\x44\x4a\x78\xea\x44\xaa\x26\x31\xb8\xc0\xd7\xb0\x30\x0d\x55\xcb\x6a\xc4\x85\xf2\x4c\x0a\xcc\x64\x77\x47\xc4\x3d\xb3\xb2\xa8\x67\x7b\xaf\x65\x6f\xa7\x35\xa5\x75\xf1\x81\x3f\x36\x68\xa2\xac\xa9\x17\x57\x11\xb5\x25\xeb\x49\x6e\x9e\xf9\x71\x1d\x75\xf5\x90\xc7\xd9\xef\x99\xe0\xf5\x9e\x84\x83\xcb\xf9\xf2\x84\xe3\xf5\xa3\x3e\xe7\x78\x1e\x62\xb8\xb0\x55\x51\x77\x7e\xfe\x0f\xbf\xd1\x9e\x54\xb6\xbb\xd1\x42\x94\x4b\xc2\x95\x9a\x82\xeb\xd2\x95\xd2\x3d\x34\x43\xb6\xce\x65\x8c\x2d\x57\x9a\x76\x37\xb5\x49\x52\x04\x91\x90\x8e\x34\x28\x2e\xc2\x71\x69\x72\xe6\xf0\x35\x39\x29\x54\x7e\xf1\x53\x7a\xec\xc9\x6b\x2d\xf6\x16\x14\x85\x99\xb0\x9d\x9b\x81\x39\x4a\x13\xfe\x7d\xb8\x67\x60\xb1\xe2\xa0\x60\xef\xd4\x84\xe8\x18\x99\x39\xeb\xdf\x6f\x21\x64\x0d\x89\xd8\xe7\x36\xde\xe0\x82\xad\x72\xa0\x18\x4a\xde\xdd\x8d\xf2\x14\x74\xc9\xf5\x26\xbc\xfd\xf7\xe8\x56\x58\x19\x4b\xb6\xd9\x42\xe7\xf3\xfe\x96\xc2\x3f"}, +{{0x70,0x48,0xc6,0x52,0x1a,0xef,0xaf,0xa4,0xea,0xc6,0xd6,0xc3,0xa7,0x02,0xb9,0x52,0x54,0x80,0xa6,0x64,0x82,0xe4,0x96,0x98,0x96,0x75,0x7f,0x2c,0xd1,0xac,0x7d,0x5b,},{0xed,0x93,0x11,0x3c,0x16,0x43,0xa5,0x3a,0xa0,0x64,0xca,0xa6,0x31,0xce,0xb6,0xe2,0x0f,0x6d,0x6e,0xc2,0xfc,0x6c,0x07,0x11,0xcb,0x8a,0x1f,0xe7,0x31,0x39,0xaf,0x93,},{0x7c,0x45,0x70,0x3e,0xd3,0x94,0x2e,0x44,0x04,0x1c,0x7f,0xa1,0x85,0x8a,0xa5,0xf1,0xdc,0x38,0x1f,0x49,0x3a,0x45,0x2d,0xfb,0x52,0x70,0x80,0x17,0x89,0x8f,0x71,0x0e,0x31,0x11,0x8e,0x33,0x1f,0x00,0xaa,0x64,0xcb,0x73,0x88,0x36,0x68,0x2b,0x7d,0x17,0x7e,0x97,0x95,0x5c,0x00,0x31,0x9a,0xbd,0x79,0xa4,0x9e,0x0f,0xcd,0x16,0xfe,0x00,},"\x53\xf7\x4c\x72\x4d\xb1\x57\x8a\x1a\x29\x6a\x7c\xca\xc9\x04\xa2\x50\x4d\xd9\x00\x53\x89\xb4\xf8\xd4\xea\x4b\x63\x07\x29\x8f\xc6\xdc\xce\x98\xa6\xbc\x07\x28\x0d\x20\x36\x4e\x40\x5a\x46\x7e\x73\x65\x78\x96\x52\x69\xc8\x14\x61\xd6\x1f\xc6\xb7\xe4\xba\xd6\x8d\x2b\x6d\xd0\x00\x58\x50\x10\x5f\x0a\x67\xbb\xc6\xee\x22\x3e\xc1\x75\x4a\xf4\xe3\xb9\xaf\xa5\x06\x2d\x1c\x18\x61\x04\x8f\x18\x5b\x12\x8f\x1a\x5c\x0f\xb2\x5c\x39\x19\xb4\x83\x3e\x29\xe2\x02\xbc\x94\x1a\x90\x5e\x63\xc2\xc0\x5b\x10\x14\x64\x7b\xd7\xed\xe5\xbe\x9f\x99\x66\x15\x18\x7a\x3d\x3b\xb2\xc7\xdc\x4c\x28\xf7\x05\x3d\xef\x9b\x28\xb2\x9e\x23\x31\xf1\x62\x96\xdc\xe8\xf1\xed\xe4\x84\xca\xec\x99\x67\x02\xbd\x99\x02\xe5\x26\x84\xc8\x12\xc8\x74\x40\xf6\x9b\xd1\x41\xc7\xe0\x0c\x69\x47\xd1\xfc\x7c\x3b\xdc\x0b\xc5\x50\x6b\x6e\xa4\x62\xe6\x5f\x9e\x74\x3b\x72\xc0\x07\xdd\xc7\xa3\x77\x49\x37\x77\xd4\xeb\x12\x62\x0c\xa6\xc0\x19\xc8\xbf\xc4\xc2\x9e\xc8\xaf\x38\x2f\xc3\xea\xc8\x41\x02\x1a\x74\xe4\x67\x4b\xa3\xe4\x3e\x5d\x7b\x41\xe3\xfe\xeb\x17\xda\x00\xa7\xce\x45\x5a\x1c\xec\x70\xb0\xbe\x6e\x56\xf8\x5f\xc3\x7f\x64\xcf\x07\x33\xb7\xe3\x12\x41\xde\x64\x1a\x8a\x8e\x5b\x91\x89\x7b\xc1\x58\xfe\x93\xd1\x02\xc0\x1d\x1f\x5e\x16\x6d\x40\x81\x65\xfe\x3f\xcb\x13\xd5\x30\x45\x90\xab\x8e\xf0\xdc\x8d\x5a\x8c\x1d\x8a\x93\xfc\xeb\x85\x4f\xc1\xfa\x36\xd0\xcc\x48\x0c\xf8\x51\x2d\x80\xbe\xe6\x9b\x06\x50\xa9\x57\xda\xed\x28\x3c\xd7\x63\x81\x55\xed\x77\x30\x86\xe8\x6a\x8f\xfb\x19\x8a\xcc\x74\x23\xb5\xd1\xa6\x09\xa1\x75\xa5\x6b\x94\xc9\x6b\x73\x18\x51\xb9\x3a\x94\x97\x71\x01\xe2\x55\xf1\xce\x92\xe2\x32\xa0\x5e\x2e\x33\x87\xfc\xb4\xdc\x13\xa3\x1b\xee\x6e\xe2\x55\x07\x32\x2c\x73\xc9\x88\x30\x80\xa7\x4c\x00\xf8\x03\xa9\x98\xdd\x53\x0a\x79\x12\x6b\xb1\x44\xed\x55\x74\xc4\xb2\x31\x80\xe3\x4e\x09\x92\x83\xb4\xbb\x1d\x28\x82\x2f\xce\x37\x17\x04\x6f\xf3\x2e\xf9\xe2\xcd\xf9\x67\xe3\x18\xea\x72\x6a\x2a\xee\xc5\x78\x06\x64\x3a\xd4\x80\x1d\x3e\x0d\xa5\x2a\x1d\x77\xbf\x04\x3f\x5a\xe9\xf3\xae\xa9\xe4\xbc\x4f\xa7\x95\xd0\x84\x01\x08\x5c\xa9\x4c\xfc\x4c\xe7\x19\xda\xbc\x7b\x23\x90\xd0\x3d\x29\x4a\x65\xb7\xaf\x9b\xc3\x90\x72\x28\x5b\x77\x7b\x2f\x13\x3d\xc1\x1a\x70\xc0\xa9\xf0\x60\xe1\x04\x41\xf4\x02\x16\xac\xb6\x41\x63\x7a\x2e\xad\xf1\xf7\xb8\xd2\x62\xfe\xc1\xb4\xd0\xf0\xf4\xfa\xa9\x3f\x3f\x73\x2c\xac\x38\x2d\x8a\xc4\x2e\x17\x8e\x22\x44\x99\x9d\x76\x4a\x9d\x0e\x98\x17\x14\x68\x6e\xb4\x92\x44\x97\xe5\x6b\x50\x15\x7e\x99\x39\x03\x2c\x9f\x88\xeb\x65\x7c\xfd\xe4\x4a\xd3\x47\x14\xaf\x4a\x51\x32\x4e\x5e\x77\xd0\xde\xea\x99\xc9\xf2\x44\xd2\xe0\x9e\xa4\x25\x82\x0a\x74\x6d\x88\x3a\x0c\xf4\xb7\x05\xc2\x9d\xf8\xc0\x37\x44\x81\x54\xdc\x08\xa4\xd4\x33\x74\x05\xfb\x87\x65\x82\x31\x14\x37\x0b\x37\xed\x86\x08\x6e\xc5\xf8\xbd\x6c\x72\xab\xf1\x3f\x51\x84\x30\x71\x0f\x59\x7b\x06\x10\x8f\x65\xb3\x0a\x48\x34\x96\xe2\xed\x81\xda\xb1\x0f\xee\x94\x7f\xe0\x4b\x54\x85\xf2\xe3\x07\x40\x49\xd2\x22\x84\x26\x66\x51\xad\x10\xdd\x08\x6a\xaa\x5d\x45\x2e\x0d\x1a\x61\x12\x9d\x1e\x77\xc6\x63\xc2\x6d\x08\x89\x62\xb5\x54\x56\x45\xb7\xa1\xa8\x71\x3d\x51\x32\x7a\x7a\x35\x9b\x12\xda\xad\xb8\x5a\x2c\xd4\xb5\x41\x0d\x5c\x20\x26\x7f\xa7\x66\xb8\xc4\x2a\x84\xdc\x42\x66\x45\x88\x87\x9b\x3e\xae\xfd\x4c\xc8\xdc\x69\x3f\x98\xac\x20\x56\x09\xe5\x70\x66\x5b\x01\xea\x46\x55\xe3\x94\x29\xa7\xa7\xe5\x42\xef\xb4\xf7\x89\x0d\xbf\x4e\x34\xc6\xcf\xf0\x7e\x4d\x35\xbd\x3e\xee\xdf\x5b\x46\x28\x0f\x4a\x0d\xa0\xc2\xe7\x3c\x94\xea\x81\xcf\xea\xe7\xf9\xbd\x04\xfe\x2d\x45\x97\x65\x00\xf7\xdc\xac\xb0\xdf\x2a\x5d\xc7\x36\xa8\x23\x67\x1d\xb6\x79\xbe\x66\xcb\x33\xc1\x62\xfd\x2c\x74\xae\x71\xfb\xf4\xd2\xb0\x5a\xf0\x42\xb3\xa9\x77\xf5\xb9\x44\xb9\xfd\xb6\xc3\x44\x24\x42\x1b\xcf\x4f\x62\x23\x76\x84\x28\xfa\x14\x0f\xd4"}, +{{0x3e,0x63,0x73,0xb2,0x65,0xb9,0x67,0x89,0x00,0x7a,0xd2,0xa1,0x0c,0x30,0x9a,0x56,0x76,0x38,0xf2,0x55,0x87,0xd7,0x7e,0x28,0xb0,0x82,0x3a,0x4f,0x17,0x9a,0xe4,0xfe,},{0xa3,0x23,0x4e,0x5d,0x13,0xb0,0x34,0x72,0x16,0x50,0x36,0x40,0x4f,0x6d,0xe8,0x0e,0x70,0x28,0x39,0x50,0x0f,0x13,0xd9,0xc9,0x85,0xa0,0x77,0xd4,0x5c,0x69,0xff,0x45,},{0xf5,0x1e,0x0f,0x87,0x8a,0x5a,0x70,0x96,0x47,0xe8,0x5f,0xea,0x83,0x9f,0xd5,0x66,0xe6,0xf3,0x5c,0x8a,0x61,0x85,0xd0,0xc9,0xeb,0x13,0xe0,0xd5,0xb9,0xe6,0xe8,0xaa,0x95,0xc3,0x33,0xa8,0xf5,0x06,0x32,0xa4,0xd6,0x65,0x7b,0x51,0x8c,0xe4,0xcf,0xde,0x40,0xb8,0xf5,0xa0,0x5b,0x2d,0x9f,0x84,0x41,0xfc,0xc9,0xd2,0xd6,0x92,0xd5,0x09,},"\xb9\xd0\x68\xbb\xca\xe7\x72\x2f\x82\x8b\x0f\x8c\x98\xa7\x38\xe3\x6a\x7d\xf4\xc9\x97\xc7\x24\xba\x27\x53\x1a\xf3\x4a\x2f\x10\x6c\x75\x13\xa4\x4a\x46\x1a\x9a\xa4\x30\x9b\xc1\x5c\x4e\x0d\x42\x75\x91\x93\xea\x1c\xde\xa9\x56\xbb\x81\x59\x85\xf5\x78\x67\x14\x5e\x9e\x2c\x75\x85\xfc\x8d\x61\x02\x7e\x47\xd2\xd7\x35\xe2\x44\x8a\xf3\x78\x29\x09\x40\x4e\xde\xaa\xc0\xfd\x73\xf6\x04\x5d\xcd\xb0\x4f\x03\x77\x75\x8f\x02\x20\x4a\xae\x3a\x72\x20\x31\x1c\x0f\x47\x23\x58\x27\x10\xcc\x44\x0c\x36\xc9\x58\x7b\x5c\x9e\xbc\x40\x63\xfe\xa8\xca\x3f\x43\x19\x58\x94\xf7\x9a\x36\x50\x87\x13\x72\x82\x30\x2d\xbf\x2e\x7a\x0d\x41\x1a\xb5\x8b\x70\x26\xcc\xde\x19\x88\x69\xaa\x73\x43\x34\xc0\x52\x38\xe2\x75\xe3\xc3\xab\x21\x70\x83\x49\x57\x69\xe2\xfa\xd3\x74\x05\x14\x52\xd7\xf5\xb1\xdb\x0e\x78\x58\x36\xd4\xbd\x5e\x29\x78\xa3\xe9\x91\xaf\x0f\xf7\x16\xf4\x38\x89\xa0\x7f\x5d\xf2\x99\x60\x36\x21\xc3\x9e\x2c\xde\xe0\x89\x98\x5d\x9e\x6b\xf7\xb2\xfb\xd0\x23\x73\xae\x1b\x5e\x9b\x88\xf5\xb5\x4a\x07\x6e\x67\x6d\x77\x90\xbf\xc8\xf5\x7d\xcc\x59\xef\x52\x85\x0c\xe9\x92\xa7\x3b\xa7\xbc\x99\x1d\xeb\x4d\xde\x5e\xb0\xb2\x16\x70\xb1\xb3\xd4\xb6\x4f\x36\xcc\xa8\xe3\x07\x09\x85\x68\x49\x7d\x89\x16\xf6\xb5\xd0\xe9\xe8\x9f\x99\xf8\x60\x06\xf3\x9b\xd3\xa8\x10\x76\x9c\x8f\x78\x01\x77\x3c\x96\x38\xab\xcf\x5e\x27\x11\xb1\x9d\x11\x67\x59\x3a\xcb\xe8\x5e\x41\x61\x42\x89\x97\xa2\x19\x4d\xc5\xe7\xb7\x64\x0f\x0d\x2c\x1e\xb2\x05\x55\x3b\xe9\x16\x7f\xfb\xc2\x2b\x7c\x2e\x76\x98\xf3\xaf\xa1\x07\x54\xcb\x44\xd4\xb1\xd4\x5b\x83\x73\x03\xb1\x66\x90\x73\x41\x5a\x22\x60\x6b\x50\xf2\x1f\x82\x65\xe1\x39\xf2\x30\x5a\xc0\xe0\x12\x7a\xe0\x56\xce\x8a\xbe\xab\xa2\x0e\x1d\x26\x9a\x2b\x2e\x89\x9c\x49\x54\x72\x68\xa0\x69\x6a\xe4\x50\xdc\x02\x67\xf7\xf6\x3a\x8e\xdf\x07\x4c\x47\xd3\xc2\xdb\x1d\xa3\x63\x93\x73\x73\x04\xe6\xdd\x4f\xac\xcd\xb6\xab\x55\xe5\xf8\x52\x0c\x3d\xff\x5f\x6b\xea\xc3\x0b\xa8\x5b\x86\x08\x23\x51\xe3\xde\xd8\x40\x0a\xa5\x7f\x65\x0c\x0c\x33\x03\x6d\x65\xb3\x9b\x7d\x2f\xb6\x11\x28\x63\xd5\x9b\x72\x55\x82\x42\xe8\xb0\x45\xad\xdd\x35\x7d\xe6\xfd\x37\xa8\xf6\x61\x17\x65\xc9\xb5\xff\x19\xcc\x4d\xb7\xe1\x17\xc6\x5a\x00\x45\x89\x08\xb0\x24\x5d\x04\xf7\x90\x8f\xc7\x3b\x16\x5d\xff\x6e\x4b\xe4\xb4\x20\x32\xd8\xcf\xd7\xd6\xf7\x77\x2c\x1b\xfe\x72\x1d\x4b\xcf\xe2\xfc\x52\x79\x98\xf3\x4f\xb4\x41\x8a\x1f\xae\x1e\x6c\x37\x67\xc4\xd0\x78\x06\x21\xf9\x23\xda\x1f\x0a\x0d\x3d\x21\x9c\x03\x6a\xcf\xd3\x70\x9d\xad\x4c\xf2\x4d\x90\xbc\x69\x1d\x70\x0e\x6a\x9c\x80\xcc\xfd\x10\xbd\xe8\xe7\x91\xc0\xfe\xa8\x28\x80\xc0\x7b\xaa\xaa\x31\x1e\xef\x79\x24\x07\x84\xf6\x28\xa7\xd2\xa0\x91\x84\xe0\x16\xf8\x10\x08\xe7\x74\x29\xa8\x65\x8b\x15\x3e\x44\xe7\x9a\x98\xad\x24\x8f\x7f\xda\x23\xb5\x90\xd6\x46\xd7\xc1\xd8\x41\xf4\x92\x7d\x6e\x8b\xc7\x32\x14\xd1\x0a\x7f\x3c\x29\xc8\xf8\x39\xa8\x90\x8d\x20\xa7\x4e\x82\x7a\xf4\x67\xac\x5a\xbf\x0f\x1d\x0e\xd3\x9c\xdd\xd9\x69\xdd\xe9\xee\xb4\xa4\xb7\x52\x7a\xb3\xe2\x47\x5a\x19\x5e\x24\x47\x4a\x4e\x36\xb0\x90\x52\xe2\xda\xd4\xa5\xeb\x46\x91\xe2\x63\xb8\xc6\x1b\xbd\xe8\x77\x72\x20\x7e\x01\x1c\x4c\x1e\x14\x23\x5f\xb2\x4e\x4d\xa4\x38\x87\x5d\x18\x53\x0f\xef\x90\x26\x19\xdd\x48\x5d\x77\xb5\x45\xab\xb5\x6b\x69\xc7\x55\xaf\xe7\x58\x60\x69\x71\xab\x97\xdd\x3a\xce\x1c\x1a\x34\xa3\x37\x94\xc8\x15\x6d\xa7\x99\xe8\x22\x4d\x88\x5e\x18\x68\xf9\xcb\x46\x6d\x80\x2c\x82\x7c\xc3\xe1\xec\xd0\xae\x6e\x0b\x01\xf8\xf7\x91\xb1\x22\x08\xfc\xc0\xfe\xd3\x85\xb7\x96\xeb\x2f\x29\x08\xb5\x8d\x30\xb3\x73\x3f\x14\x70\xf2\xe2\xef\x12\xad\x43\xfe\xb7\x2d\x08\x16\xde\x3c\x13\xa8\xb5\xa5\x23\xe1\x4c\xdf\x5f\xf3\x72\x0b\xf8\x77\x69\xcd\xe7\x49\x5d\x22\x6b\xf3\x82\x38\xa8\x25\xf7\x5a\x09\xf6\xbb\x9a\xfc\xe5\x16\xa7\xbc\x70\x11\x43\x70\xbb\xc4\x0f\x17\xc7\xbc"}, +{{0xf5,0xe8,0x59,0x7e,0xac,0x0e,0xbf,0xa9,0xd3,0x85,0xde,0x85,0xa1,0xfb,0xaa,0x35,0x14,0x63,0x95,0xb1,0x34,0x57,0xb5,0xb1,0x4d,0x36,0x70,0xda,0xca,0x69,0x05,0xe7,},{0xce,0x93,0xe6,0x42,0xc2,0xf1,0x50,0x84,0xbc,0x83,0xba,0xfd,0xaa,0x19,0x67,0x63,0xde,0x2a,0x3c,0x51,0x3b,0x0e,0x44,0xf6,0x8d,0xdb,0xde,0x37,0x85,0x14,0xc4,0x41,},{0x57,0x65,0x43,0xfc,0x21,0xab,0x0a,0x7c,0x5f,0x63,0xb1,0xcf,0xf0,0x1b,0xf8,0x45,0xdf,0x91,0x79,0x2e,0x7a,0x97,0x50,0xc5,0x50,0x8b,0x51,0x66,0x5e,0x7f,0x89,0xf1,0x7c,0x6e,0xc3,0x35,0x5a,0x0a,0xed,0x87,0xdb,0x8c,0x77,0xbd,0xb2,0x71,0xfb,0xed,0xc7,0x14,0xff,0xad,0xb7,0x8b,0x5e,0x0f,0x97,0x81,0x16,0x77,0x1b,0xa7,0xcf,0x0b,},"\x27\x33\x41\xf2\x19\xff\x5c\xf3\x81\xc7\x7b\x2d\xd2\x26\xc5\x8f\x8f\x33\xc4\x52\x70\x48\xcb\x00\x6a\xff\xef\x8c\xee\x15\x1e\x30\x0e\xfe\xf6\x29\xfe\xd2\x1b\x70\x45\x1f\x72\x92\x92\x62\x7d\x1f\x3f\x1b\x52\x57\x35\x9e\xe5\xa6\x71\xcf\x62\xae\x57\x32\x49\x40\xf2\xd0\xb1\x5a\xac\x76\xff\x39\x82\x20\xc0\x80\x24\xe2\x9a\x8c\xf3\x65\x04\xe1\x2a\x4e\x96\x43\x8f\x42\xc3\xda\x0c\x00\x05\x41\xbc\x11\xf0\x91\x38\x1b\x0b\x72\xb5\x8a\x92\x08\x3f\x44\x6e\xca\x19\x91\x99\x68\x78\xde\x35\x08\x1c\xc4\xab\x90\x95\x8c\x96\xcf\x5c\x99\x79\x6c\xba\x79\x51\xee\x18\x6f\x26\x52\x7a\xed\xe6\x9d\xb3\x04\xce\x29\x41\xba\x15\xcc\x00\xba\x2f\x14\x11\xf2\x08\xda\xd4\x5e\x87\xbc\xf6\x38\x79\x2d\xe0\xa6\x86\x24\xb6\x67\x29\x7c\x27\xa3\x43\xdb\x4b\xaf\x34\xa0\x22\x8e\xaf\x0d\x10\x22\x00\x9b\x5d\x06\x8b\x25\x34\xd9\x20\x30\x2e\x71\x31\x0f\xeb\xf0\xdf\x1b\xb0\x2c\x2e\xf0\xad\x1a\xe1\x49\xde\xad\xf8\xc1\x84\x37\x3c\x0f\x7e\xb6\xb2\x56\x95\xbe\x82\xd1\x2c\x71\xb6\xc8\x32\x67\xd9\xa2\x33\x66\x7e\x77\xbc\x20\x59\x83\xf8\xb8\xd8\x77\xd8\x5a\xea\xd3\xf6\x0e\x82\x0f\xfc\xb1\x7a\xdd\xdd\x92\xa7\x71\x2b\xbe\xb3\x4e\xe7\x19\x66\xda\xfd\x99\x07\xd1\x93\xdd\x9d\x72\x5a\x31\xa6\x13\xd2\x9e\x32\xbe\x72\x13\x28\x08\x92\x6d\x94\x37\x47\x7f\xee\x25\xed\xa6\x10\xae\xb1\xdc\xe1\x2e\xa3\x16\xc6\xae\xc6\x68\x9e\x50\x1c\x55\x19\x23\x82\x5a\x34\xb4\x2c\x4f\x06\x75\xb8\x6a\xb2\x6a\xde\xea\x2e\x60\xda\xe6\xc6\xd1\xcd\xd0\xcb\x3c\x34\x7b\x16\x38\x40\x39\xa8\xe3\xfd\x60\x87\x38\x13\x87\xcb\x4b\xc7\x2d\xdb\x5f\x25\xb3\x74\x85\x9b\x02\xe5\xbb\x1b\xa0\x6d\x3c\xc6\x9e\xc4\x4c\xec\x4b\x98\x5c\x84\x76\xe3\x50\x32\xe9\x9a\xbf\x00\x1a\x1d\x44\xdd\xc6\xe2\x88\x9c\x3c\x2c\x3e\xca\xce\xd6\x09\xb2\xb2\x68\x0e\x00\xb1\xef\xa7\xe9\xd2\x6d\x62\xf2\xb3\xab\x36\xf9\x21\x04\x47\x90\xab\xbd\x49\x36\x07\x56\xdc\xff\xcc\xf2\x30\xf6\x6d\xbb\x70\x1a\xa1\x64\xda\xd6\x06\x9a\xa2\xb8\xb3\x30\x9f\x2f\xe4\x4d\x5e\x0b\x25\xbd\x55\x64\x31\xf0\xdf\x4c\x2e\xa9\x7a\xe7\x9e\xd4\xa5\x75\x78\xd6\x6f\xc6\x93\x9c\x57\x62\x8a\x90\xca\xc9\x7a\xdf\xa8\x70\x2a\x4a\x1c\x89\x65\xba\x1a\x90\x26\x25\x67\x28\x66\x64\x00\x30\x03\x53\x3c\xc9\x31\x4c\xaf\x7d\x3b\x98\x2e\x0a\x43\x2f\xf5\xaa\x4e\xd5\x74\x19\x83\xd9\xb5\x43\x23\xac\x7e\x29\x9b\x2b\x49\x56\xc1\xa2\xc1\x91\x55\x7b\x27\xd8\x6b\xe7\x14\xb5\xb6\x8f\xcb\x1d\x41\xf7\x8c\xa5\xdd\xb6\xb5\x3b\x3d\xfc\x8e\x7d\x6b\x3c\x3d\xb0\x59\xaf\x9f\x2d\xd7\x65\xef\x04\xb6\xd1\x6e\x67\x37\xc7\x27\xaa\x11\xf3\xdf\x37\x74\xa3\xfc\x96\x18\x2e\x28\x2a\xcc\x3d\x23\x3e\xea\xbf\x8c\x72\xd3\xf2\x46\xae\x18\x45\x05\x28\x8f\xef\x39\xb3\x67\x66\xb1\x0d\xd1\xbf\xbf\xbf\xa7\x0f\x97\xb3\xc9\x01\x72\x6d\x1e\x0d\x0a\x83\x7d\x11\xf0\x12\x3a\x34\xab\xad\x1a\x79\xaa\xbe\x80\xb1\x25\xb1\x28\xee\x16\x0b\x51\x18\x48\xf7\xf0\x4c\x49\xc8\xd5\xc2\xf2\x04\x1d\xa7\xd9\x59\x9c\x29\xb1\xda\xc8\xc6\x80\x77\xef\xac\x3e\xca\x58\xbb\xc1\x63\x7a\xad\xce\x21\xc7\x74\xfe\xa4\x2d\x2b\xcf\x4a\x0b\x98\x92\x30\x7e\x36\xfa\x25\x0a\xce\xe7\x95\xad\x2b\xfe\xcf\xbf\x60\x31\x9b\x81\x66\x3e\x2a\x26\x57\x19\x46\xf7\x5a\x8d\x96\x9a\xf1\x6b\x3b\x57\xc3\xec\x3e\x66\x15\x8a\xaf\x42\xcc\xf5\xe5\x8b\x93\x7a\xae\xf6\x13\x31\x86\x06\x60\x33\x17\xe5\xaa\x31\x8b\xe7\x0f\x8d\xa3\xc0\xc1\x6b\xe6\xc2\x9e\x3e\xc9\xfe\xf4\xe4\x6e\x8c\xa2\x41\xd9\x41\xd5\x80\x49\xa0\x63\xd9\x0a\xfc\x95\x3c\xa3\x2e\x8a\x50\xa6\x47\x36\x32\x58\x8a\xc4\x1e\xae\x97\xf2\x0c\xe9\xb7\x41\xed\x41\xc9\xa4\xaa\x65\x51\xfd\x82\x3c\xe0\xc8\x11\xa5\xbb\x5a\x17\x1c\x1e\xa4\x23\x8a\x02\x46\x81\x1e\x46\x9c\xf4\x98\xb7\x96\x21\xc3\x23\xeb\xa7\x98\x53\x44\xfe\x11\xe6\x74\x99\xed\xf4\x96\x74\x91\xaa\x74\x9f\x8f\x3f\xe3\x99\x61\xd7\x68\x92\xc9\x3a\xac\x3b\x19\xfa\x4b\x4f\xc1\x74\xd7\xd4\xd4\xd8\xbd\x6e\xe4\x75\x47\x50\x08"}, +{{0xcd,0xad,0xc5,0xb8,0x9c,0xb2,0xb6,0x30,0x8a,0x00,0x6f,0x2f,0x4e,0x95,0x5a,0x91,0xaa,0xf3,0xba,0x70,0x16,0x5f,0x2d,0x44,0x4e,0xf1,0xff,0xeb,0xbd,0xaa,0xa2,0x21,},{0x05,0x41,0x41,0x5f,0xf5,0x46,0x7f,0x28,0xce,0xac,0x83,0x9b,0x13,0xa1,0x76,0x6e,0x72,0xc9,0x9e,0x65,0x45,0x20,0x7d,0x9d,0x5d,0x96,0x97,0x41,0x1e,0xb6,0xbc,0xa7,},{0xff,0xed,0xe7,0x01,0xeb,0x18,0x29,0xce,0x23,0x61,0xcd,0xa2,0xc8,0xbb,0x63,0x33,0x85,0x39,0xd8,0xad,0x2f,0x66,0x77,0x58,0x55,0x31,0xe7,0xbf,0x1d,0x39,0x22,0x38,0x26,0x79,0xa1,0xae,0x84,0xff,0xeb,0x75,0x3f,0xc9,0x75,0x4e,0x50,0xc0,0x18,0x52,0xf9,0x55,0xe3,0xfd,0x60,0x9f,0xf6,0x4b,0xf0,0x5b,0xbe,0x70,0x75,0xcd,0xbe,0x00,},"\x91\x17\x27\x03\x6d\xb3\x09\xd6\xe2\xe3\x36\x9e\x4f\x17\xd9\x8d\x99\xec\x07\x0c\x33\x28\x3b\xb1\x24\x4e\xfd\x62\xe7\x6b\xd7\x0a\x69\xb9\x72\x3b\xd2\xb5\x20\x47\x2b\x98\xaa\x06\x59\x24\x36\x6d\xe7\x80\x90\x0b\xcd\x8b\x77\xb5\x0f\x87\xc3\xc3\x61\x87\x02\x4b\xbc\x59\xcc\xf4\x48\x2c\x7b\x4a\xad\xb5\x6e\x2e\x5e\xcc\x00\x03\xd9\x89\xd6\xaf\xc6\x3e\xc1\x02\x42\xe5\x74\x82\xfe\x39\x21\x52\x61\xd5\xfc\x95\xa0\x18\x5f\x95\xe9\x54\x0c\x55\xf7\x4d\x69\x60\x48\xbc\xa7\xab\x11\x26\x81\xa5\x55\x8e\xa9\x3c\x3b\x1f\x1c\xd3\x64\x65\x9e\x94\x33\xce\xee\xbe\x05\x4e\xe7\x13\xc4\x77\x60\xd7\xad\x13\x2a\x7f\x3f\x8f\xe3\xd5\x04\x1b\x81\x1a\x26\xb6\x5e\xfb\x1f\x34\x0e\x18\x1a\x4e\xc7\x20\xea\x13\x6b\x3a\xf3\xd9\xe5\x46\x1d\xd2\x43\x70\x33\x6f\x10\xe6\x35\x4c\x8c\x17\xac\xf9\x99\x85\x44\xce\xc0\x87\x3e\xfa\x68\x7c\xb1\x32\xae\xcf\x70\xae\xbb\xc5\x67\xba\x03\xc5\x36\x49\x9e\xf9\x6c\xc8\x41\x2e\x7a\xaa\xd5\xbf\x96\x42\x2b\xe4\x7c\xb9\x41\x36\x45\xdf\x2c\x17\x03\x19\x23\x47\xdc\xbb\x12\x31\x27\x45\x59\x71\xae\x15\x7e\x9f\xa2\xdb\xff\x88\x74\x5a\x96\xc6\x58\xb8\x65\xe4\x1f\x55\xae\xbf\x98\x39\x50\x05\xdd\xcb\xd5\x98\x3e\x6a\xe0\x2c\x4f\xbb\x5e\x17\x91\x67\x96\x32\x5f\x76\xed\xf5\xb6\x4a\xfa\x4e\xc5\xa7\x41\x8a\xfe\xd2\x3a\x97\xef\xad\xe6\x8b\x6a\x5b\x31\x45\xf0\x8a\x5d\x3d\xb9\xc2\x98\xa5\x12\xfa\xbd\xac\x68\x56\x2b\x3f\x55\x37\x7f\xf4\x4b\x00\xc1\xc2\xf3\xef\xd1\x81\x32\xda\x71\xf9\x71\xa9\x53\xa9\x31\x8c\x57\x52\x33\x61\xa1\x60\xf9\xb7\xe3\xb5\x1c\x52\x4e\x95\xdd\x5e\xf4\x56\x8e\xf1\x8a\x80\x07\x75\xe9\xd2\x6e\x07\x13\x19\x42\xd2\xbe\x4e\xf2\x2c\x0c\xbc\x13\xdf\x01\xc6\x8b\x1b\xcd\x3b\xce\x9b\xd5\x1c\x4c\xed\x65\x2a\xdc\x40\x07\xbe\x43\xb3\x7c\x67\xa5\xc5\x5e\xd4\x02\x9e\x8a\xd1\x5d\xef\x83\x05\xc9\x68\x62\x1a\xed\x4c\xd4\xbf\xe0\x79\xa6\xf4\x88\x84\xd8\x56\x80\x39\x2c\xa9\x2b\xa6\xe1\x2f\xea\x6f\x4a\x05\x6f\x79\xd6\x7b\x19\xb0\x5f\x90\xd6\x84\xbe\x7d\x45\x72\x5f\x79\x67\xc6\xa4\x67\xaf\x43\xb8\x6a\x6b\x1b\x9d\x9e\xed\x3a\x42\x48\x97\x1c\x76\xa7\xac\x29\xc2\x92\xdf\xba\x4d\x75\xc5\xf7\xba\x70\x9a\x39\x05\x8e\x96\xad\xf6\xdb\xd7\x60\xd3\xce\xf4\x02\x4b\xf3\xed\xc4\x41\xef\xbf\x11\x47\xa2\xc1\x08\xbd\x6f\x9e\xb4\x39\xc1\xc5\xc4\xd3\xa6\xea\x4e\xc3\xd9\x2c\xef\x38\x13\x61\x88\xbe\xc9\xe0\xb6\xc0\x51\x8d\x8b\x79\xba\x59\xc5\xdc\xba\x39\x3a\xed\xfd\xff\xb0\xb7\x0d\x77\x9c\x2b\x97\x65\xce\x44\x52\xe7\xe3\xb0\x8c\x44\x02\xb1\xa6\x08\x32\x08\x40\xfb\xe9\x6d\x1e\xb8\x65\x6e\xb1\xc2\x0d\x95\x51\xdd\xf5\x33\xb9\xf1\x5e\x4e\xb5\x78\x37\x56\xc5\x3d\xdd\x3b\x14\xd8\x07\xf8\x38\xac\x96\x80\xf8\x9f\x1a\xdf\xb7\x8d\x68\xcc\xb0\x67\x31\xa9\x0b\xea\xc5\xf0\xd7\x09\xd5\xb8\x8c\x75\x43\x7a\x66\x3c\xb9\x62\xd3\x7f\x96\xb8\xe8\x92\x84\x77\xb5\x61\x12\x28\x01\x5d\x33\x7f\x04\x9e\x8b\x62\xe4\xdf\xf8\xd0\xbb\x6c\xda\x24\xa5\xdf\x90\x83\xe3\x48\xbe\xf1\x25\x85\xf5\xf4\xc4\xd3\xbb\x3c\x7e\x78\xd5\x50\x19\x4a\x45\x25\x1a\x08\x79\xa1\x62\x4b\xf9\xdd\x35\xeb\x65\x5c\x39\x39\xfe\xa8\x90\x9f\x6d\xf3\x95\xbe\xbd\x02\xb6\x8a\x17\xa8\x97\xc9\xaa\xdd\xd6\xe2\xe2\x04\x61\xe3\x03\xf5\x7c\xde\xb0\x0a\xe0\xf2\x3e\x60\xa9\x4c\x19\xc7\x71\xd8\xaa\x60\x53\x3b\x93\xce\xdc\x1b\x76\xd2\x29\x0a\x01\xbf\x43\xb2\x72\x5f\x12\x5b\xef\xa5\x75\x15\x4e\x98\x6c\x9c\x62\x05\xa1\x59\x6c\xba\xa2\xd1\x34\x70\xc2\x34\x22\xf2\xdf\x7b\xec\xe4\xe6\xeb\xd7\x52\xe9\x38\x9a\xe6\x08\x57\xb5\x29\x69\xd2\xdd\xef\xa9\xc0\x34\xf1\xbf\x35\xae\x33\x16\x30\x4e\x94\x9c\x89\x90\x82\x0e\x26\xe6\xcf\xfa\xe4\xb3\x88\xd1\x50\x5f\x92\x37\x06\x29\x7f\x8d\xb5\x56\x53\x79\x19\xeb\xbe\x30\x86\x02\x3f\x12\xf4\xde\xd3\xb1\x1a\xcf\x2a\x6d\x97\x3d\xdd\x8e\xb2\x7b\x07\xc5\x80\xbf\x44\x8c\xaa\x5a\x2e\xa1\x16\xc5\xea\xf3\x6f\x7a\x6b\x17\xa8\x5b\x39\x55\xdc\x8a\x44\xa6\x20\xd8"}, +{{0x2d,0xdd,0x79,0xe7,0x60,0x64,0xc2,0xe6,0xb3,0x22,0xaf,0xb0,0xc5,0xc6,0x85,0xcd,0xbe,0xc6,0x28,0x21,0xcd,0xfc,0x0c,0xb1,0x4d,0xb7,0xd0,0x1b,0xa3,0xbf,0x21,0xa5,},{0xf5,0x5b,0x4a,0xb6,0x4a,0x25,0x82,0x21,0x2b,0x96,0xcc,0xac,0x06,0x40,0xe2,0x71,0x94,0x4a,0x34,0xa2,0x86,0xd0,0x35,0x83,0x30,0x45,0x81,0x0e,0x34,0x18,0x24,0xbb,},{0xa4,0xc3,0x96,0xe1,0x9d,0xd4,0x2e,0x03,0x91,0x84,0xcd,0x25,0x11,0x88,0xff,0xa2,0x45,0xf0,0x36,0x7c,0x69,0xc0,0x2d,0x12,0x47,0x4e,0x5c,0xa9,0xe5,0xc7,0x68,0xa7,0xee,0x3a,0x3d,0x47,0xeb,0x22,0xd1,0xac,0x9e,0x04,0xb7,0x04,0xa7,0x4f,0x41,0x69,0x47,0xf3,0xf4,0x9a,0x32,0x42,0x59,0x4e,0x7b,0x63,0x90,0xe8,0x2b,0x60,0xd5,0x05,},"\xa5\x66\x74\xa1\xe1\xf0\x97\x95\x25\x1a\xbe\x54\xab\x43\xc2\x98\x20\x8f\xef\xc9\xbb\x91\x76\xfd\xb2\x3e\x1e\x9f\x60\xf0\x32\x64\x79\x15\x56\x7e\xbd\xcc\x2b\x86\x9e\xdb\x70\x55\xf4\xab\xa6\x7e\xcf\xe7\xfa\x19\xed\xa4\x5c\x06\x04\x7c\x7a\x51\x84\x8b\xe9\x97\x32\x51\xf8\x5f\xf7\x6f\x1c\x59\xe3\x65\x43\x82\x85\x8c\x9b\xe1\x23\xdb\x8a\x94\x90\xc6\xc9\xb3\x09\xb8\x2d\x1e\x2c\xa6\xf4\xa0\x7d\x00\x12\x02\x83\xc6\xc2\x95\x64\x49\x95\xa9\x66\x28\x61\x2b\x8d\x67\x91\x57\x35\x18\xe2\x55\x6a\x68\x8a\x09\xf1\x49\xbc\x84\x6a\x68\xbd\x0e\xf7\x92\x79\x03\x57\x10\x03\x1e\xf0\xa8\xfe\xd1\xdd\x0b\xf0\x26\x12\x5d\xc6\x64\x8f\x86\xf6\x43\x09\x94\x2e\x18\xf2\x3b\x12\xd1\xdc\x68\xc6\xf2\x77\x0c\xa8\xb5\x48\x5b\x36\x9b\x0c\x92\x00\x7a\x94\x61\xc1\x39\xfc\xbb\x41\x17\x5f\x31\x6d\x44\x67\x06\x0a\xb4\x3d\x12\x22\xf5\x80\x24\x04\xbf\x63\xc2\xdf\x7e\x00\x4b\xdc\x40\x0c\xa8\x0f\xe0\xd2\xcb\x68\xa2\x10\xfb\xc3\xfc\x0b\x90\x32\x09\xd5\x47\x6e\x7a\x56\xba\xef\xb8\xfa\xd7\xf3\x28\xb7\x2f\x32\x71\x13\xe1\x39\x41\x4b\xa6\xf3\x4e\x99\xc2\xec\xcd\xe0\x44\xe7\xa3\xac\x70\xc5\x80\xcd\x26\xc7\x45\x01\x92\xca\x4c\x82\x3c\x7a\xc5\xea\xe8\x76\xc0\xd1\xc8\xc7\x68\xc1\xcb\x0b\x7e\xa4\x1f\xc9\xb7\xd2\x94\x37\xbb\xad\xab\x18\xe0\xf5\xed\x1d\xef\xe0\xcf\x6c\x0e\xba\xa6\xb6\xd7\x77\xf4\xda\xd9\xab\xdd\xbf\xc0\xfd\x6a\xb5\xee\xea\x80\x3c\xfa\x01\xc0\xbd\x46\xf6\x5f\xef\xa4\x69\x01\xab\xbe\x0d\x89\x10\x4e\x3b\xc4\xae\xe1\xf0\x59\x9c\x69\xb6\x7b\xa5\x45\xab\x9b\x54\xf5\xde\xe3\x40\xac\x69\xd8\x82\x99\xe8\x68\x22\xac\xdd\xdd\xce\x60\x11\x22\x01\x2f\x99\x29\x97\x74\xaa\xf1\x7c\x96\x4e\xde\xcb\x95\xe1\x27\x7d\x46\x2d\xe6\x4e\x91\x15\xa6\x1a\xd9\x8a\xa3\xd2\x2e\x3b\xa6\xf8\xf1\xcd\x69\xb6\xb5\x2b\x83\x38\x28\x23\xf3\x0e\x96\x6b\xda\xd1\xff\x5f\xc1\x98\xae\x32\xe9\xb6\x80\x55\xd4\x39\x2b\xc7\xc3\xdf\x10\x15\xf1\x28\xae\xe1\xe4\xfa\x3d\x49\x99\xe3\x29\xf2\x2f\x0f\xf6\xaa\x77\x8b\xae\x02\x94\xa1\xdf\x74\x36\xcb\x16\xa2\xbf\xcd\x74\xb4\x63\xab\xe7\xcb\x4b\xac\x53\x62\xc8\x9c\x9d\x1a\x37\x8a\x2c\xb8\x85\xcc\x3b\x26\xab\x4b\xe8\x81\xef\x1a\xfc\x14\x43\x0e\x10\xd2\x65\x39\xca\x35\x8c\x36\x76\x28\x6a\xd8\x1c\xe1\xc9\xe7\x85\x92\xaf\x66\xf1\x82\xbb\x1f\x7f\x86\x2f\xe7\x55\xbf\xfb\x5b\xe5\xc5\xf2\xb7\x31\xc1\x32\xe2\x38\x8a\x76\xa1\xa7\xb1\xcd\xdf\x05\xae\xd2\xac\x9e\xc4\x08\x47\x52\x71\x94\x2c\xca\xdd\x32\xe4\x9d\x87\x91\xed\xf8\xb8\xde\x11\x75\x51\xce\x26\x4a\x60\xb8\x41\x05\xea\xe8\x7e\x66\xf6\xa4\x01\xd1\x32\x2b\xb2\x1a\x98\xe8\xac\xd2\x77\x49\x32\x54\xe5\x04\x00\x4f\x72\xc7\x6e\x79\x03\xd2\xfa\x38\xfa\xb7\x17\xe9\x4c\xe6\x27\x94\x7c\x4e\xa3\x26\xbd\x25\x75\xc3\x73\x10\xf3\xb4\xd8\x43\xb9\x0f\xa7\x7d\x32\xd9\x95\x21\x94\x15\x0b\x62\xf8\x50\x18\x7a\x4f\xdf\x38\x46\x6d\xfa\x06\x56\xc0\xa2\xe0\xb3\xf0\x74\x92\xac\x8e\x37\xe5\xd0\xdf\x95\xcc\x89\xdf\x30\x85\xa2\x69\x29\x1d\xc2\x51\x22\x10\xd3\xfe\x44\x24\x8d\x7a\xb9\x96\xbe\x09\x9a\xf6\x4c\x22\x75\x66\x66\xf8\xde\xa5\x6c\x00\xb9\x06\x77\xd1\x18\x25\x00\xdd\x27\x4f\xd0\x76\x92\x53\x82\x6d\x67\x7a\xb1\x6a\x55\x7b\x08\xb3\xc5\x22\x65\x49\x8d\x85\xc4\xcb\x2b\x60\x0e\xe0\x48\x1b\x7c\x1c\x47\x6a\x9d\xaa\x8b\x88\xc7\x1f\xc2\x1b\x6f\x89\xbf\xdf\xec\xe5\x8d\xa9\xe8\xd5\x65\x65\x2e\x43\x95\xbd\xf4\xc8\x11\xb4\xf4\xf2\x2d\x2b\x96\x13\x26\x1f\x88\xc6\x04\xc2\x97\x4d\x3e\x97\x7d\x14\x0d\x04\x6e\x1b\x66\x25\xb7\x07\x16\x40\xd3\x52\xcb\x7e\x7e\x65\xd4\x6c\x61\x34\x47\xbe\x8d\xc5\xa2\x00\xaa\x9a\xca\xb4\x6a\xfc\xcf\xeb\xb6\xb1\xc3\x19\x73\x24\x6c\x34\xfa\xaf\x8d\x26\xea\x5e\x83\xbe\x15\x71\x8f\x8f\xdb\x0c\xfc\x44\x4e\x2e\xb6\x0f\x36\x59\xb0\x20\x16\x1c\x22\x8e\x6b\x92\x40\xb7\xac\x39\x4c\xab\x81\x2d\xe1\x05\x15\x76\x6f\x22\x47\x3e\xcc\xa5\x35\x59\x4c\xe5\x28\xa5\x7c\xf5\xda\xb2\xeb\x32\xab\x84"}, +{{0x3a,0xbb,0xdb,0x0b,0xa1,0x1a,0xa1,0x06,0x3b,0xd2,0x6b,0x02,0xc1,0x16,0x03,0x78,0x62,0x28,0x5b,0xab,0xd2,0x15,0xd2,0x40,0xbc,0x9c,0x09,0x26,0xf4,0xec,0xea,0x81,},{0xb8,0xfc,0x59,0x43,0x8f,0x8c,0xe9,0xe3,0x78,0x5a,0x47,0x3b,0x22,0xc8,0x89,0x2c,0x51,0xea,0xc2,0x56,0x8c,0x68,0x1d,0xcc,0x77,0xb6,0xf0,0xe0,0x79,0x9c,0x4e,0x33,},{0x98,0x1f,0x20,0x05,0x5a,0x45,0x75,0x25,0xae,0xe5,0x61,0x62,0x64,0xe6,0xaf,0x42,0xe8,0xb3,0x87,0xcb,0x08,0xf8,0xb4,0xa7,0x3f,0x9b,0xe0,0xb3,0x66,0xf1,0x03,0x5b,0xb3,0x0a,0x1c,0x87,0x48,0x94,0xcb,0xec,0xe0,0xa8,0x46,0xd8,0x49,0xb7,0xec,0xc5,0x56,0x58,0x5d,0x0d,0x3d,0x39,0x56,0x45,0x80,0x7f,0xf2,0xa3,0xca,0x5a,0x59,0x0c,},"\xdc\xcd\x55\xf9\x22\xcd\x27\x4f\x69\x75\x00\x0a\xdc\x8d\x98\x63\x0c\x6d\x75\x2c\x12\x02\xa9\xdd\x12\x10\x48\xb9\x39\x45\xaf\x2b\x11\x10\x96\x77\x88\xf9\x9e\xc0\x28\xe3\xd3\xb4\xcf\x82\xfb\x07\x17\x3e\xa4\x40\x1e\x3b\xb4\xb0\x7b\x7b\x0b\x24\xb0\x59\xa7\x66\x33\x95\x32\xd9\xdf\x3e\x31\xb7\x2c\x95\x8c\x11\x9d\x8d\xfa\x15\xa5\x07\xaf\x6c\x5f\x7e\x78\xfe\x27\x0f\xa8\x1b\x9d\xf0\xf2\xe4\xaf\x24\xbd\x99\xfb\xeb\x14\xe0\x03\x30\x84\xd7\xfb\xf8\x4d\xde\xdf\xd5\xce\x56\x75\x1d\x15\x90\x84\x75\xdf\x8a\xf0\x13\xd0\x91\x17\x3c\x13\x86\xb9\x13\x94\x26\xcc\x60\x81\xea\x16\x5b\x8c\xe4\x81\x94\xb8\xe1\x8a\x9b\x91\xa4\x63\x13\x44\xfe\x29\xc8\xe7\x28\x18\xb7\x1f\xa1\x5c\x92\x92\xd1\x3f\xdf\x5f\x9d\x18\xe2\x9b\xd0\x29\x1b\x81\x38\xde\x73\x8f\xd3\xa3\x6c\x35\x23\x90\x22\x36\x8b\x45\x6f\x1f\xac\xba\x90\xa0\xd8\x0d\x6e\x31\x1c\x5f\x6c\x6f\x04\x67\x7e\x92\x37\x3a\x5f\xc4\x73\x88\x94\xdb\xed\x20\x6c\x30\xda\x34\x1b\x3b\x19\x6c\x94\x78\x58\xa6\xd2\xad\xc6\x8a\xac\x3f\x20\xcf\xdb\xe0\x49\x79\x61\xda\xe3\x34\x70\x26\x6d\x17\xec\x71\x9a\x59\xf0\x58\x6f\x82\xf9\x9f\x1c\x90\xed\x70\x05\xa2\x07\x21\x9a\x55\xed\xc7\x60\xf4\xeb\x8f\x24\x02\x64\x7f\x6f\x77\x97\x1f\xf7\xb6\x34\x35\x7b\x6b\x29\xbb\xd7\xea\x05\xe2\xe2\x58\x54\xe9\x9c\x62\x0f\x4b\x8b\x64\x73\x90\x22\xff\x0b\x33\x8a\xfe\xf3\x5f\xb6\xf4\x1a\x53\x62\x9a\x51\x8e\xb9\x3d\x66\x02\x0f\xb3\x53\xae\xf8\xdd\x07\x1e\x09\xc9\x16\xd4\x70\x4a\xcd\xf7\x76\xb3\x8c\xa9\xc5\x9f\x21\x1f\xf8\x8c\x43\x0a\x57\xe8\xf1\x71\x39\x23\xb3\xf3\x0c\xa8\x69\x70\xa1\x4a\x52\xdb\x4b\xcb\xe6\x0d\xf4\xbc\x3c\xfd\xf2\x54\xbf\x10\xf8\xaf\xae\x87\xbd\x61\xb3\x58\xf4\x3c\xc2\x96\xc0\x41\x29\x64\xc4\xe0\x0f\x71\x21\x33\x97\x46\x85\x17\xcb\x01\x37\x9c\xb7\x29\xc7\xb9\xe3\x5b\xd5\x0b\xdd\x98\xc3\xd3\xb7\x62\x97\xa1\x38\xb5\x7c\xeb\x6c\x77\x74\x2d\xf0\x88\x1d\x07\x66\x8c\x08\xa6\x30\xa4\x4e\x6e\xd7\xeb\x20\x6d\x6a\x56\x44\x07\x10\x43\x8a\x51\x11\x42\x4b\x61\xaa\xee\xce\x40\xe9\x00\xf5\xe3\xc4\x57\xe9\xd6\xe3\x1a\x79\xec\x5b\x4b\x42\xb6\x8e\x66\xe1\x99\x30\x92\x87\xca\xd6\x53\x36\xfc\x7f\xe4\x3f\x43\xcd\x8c\x77\x3d\x3c\x65\x80\xd7\x21\x7e\x2c\xab\xec\xd3\xea\xbc\x48\x5c\x4a\xcf\x47\x71\x8c\x39\xb0\x2c\x78\x58\xff\x34\x7c\xec\x75\x35\xed\xdc\xd4\xfc\x81\x5d\xf8\x14\x56\x9a\x88\xae\x70\xf2\x73\x3a\x65\x39\xf2\x08\xc7\x9c\xf4\xe7\xc4\xf9\xea\x24\x1a\x92\xe9\x51\x51\x71\x36\x14\x18\xa4\xc2\xe5\x3c\x07\x6a\xaa\xbc\x47\xe4\xc9\x71\xbd\x04\xb1\x00\xc2\x62\x82\x30\x88\x57\xe0\x6e\x7e\x5f\xbc\x43\x42\x56\x4f\xb3\xb1\xea\x4a\x17\xa9\x25\xe9\x1e\xe6\x91\x22\x32\x1d\x39\x2b\x24\x69\x65\xb8\x6b\x54\xfd\x5c\x83\xfa\x5c\x47\x41\x63\xf9\x8a\x9f\x44\x7d\x88\xcb\x59\xfe\x2c\xdf\x9f\x54\x12\xfc\xbe\xb3\xef\xfa\xc8\x97\x67\x91\xc6\xa4\x7b\x66\x9a\x2f\xc5\x5a\xbe\x8e\x09\xe7\x41\x57\xef\xcd\x1c\xa7\x8f\xc1\x0f\xa6\x87\x01\x0c\x68\x26\xc6\xe8\x96\xef\x5c\xd7\x1d\x0f\xe4\xd1\xbd\x07\xc1\x0d\xac\x3b\x03\x48\x5e\xdd\x25\x69\xa7\xee\xcf\xbc\x4e\x5d\x2e\xe2\x37\x98\x59\xe2\x65\x26\x7b\xed\xaa\xd6\x9d\x93\xb7\xc1\xbd\x18\xf2\x7e\xa4\x24\x83\xc7\xe4\x10\x0e\xe0\x5b\x28\x30\x39\xbf\xb9\x89\x1d\x37\xc4\x67\xed\x83\xb8\x8c\x79\x4e\xab\x6b\xab\x9d\xc6\x77\x89\x26\x50\xe2\xd8\x96\xfb\xfe\xc1\xb1\xcd\xb7\x21\xbe\x30\xb0\xb8\xe5\x35\x87\x09\xe1\x65\xcb\xe3\xa1\x82\xc9\x3b\xc0\xa0\xce\xa2\xf8\xcf\x3a\x62\x57\xad\xf7\x64\x53\x40\x41\x20\x22\x41\xa5\x27\x9b\x66\x8e\x40\x12\x5f\xc0\x94\x58\x5a\x3c\x58\x8a\xba\x82\xb6\x7c\xd9\x1d\x48\x3e\x54\x30\x04\x28\x42\x68\x63\xa4\x23\x64\x04\x9d\x7c\x45\xa1\x69\x38\x5a\xa8\x9b\xf3\x77\xf0\xd3\x2b\x07\x80\x9b\x58\x71\x39\x5e\xc0\x53\xa2\x57\xd9\x3e\x48\xbb\xf4\x07\xeb\x60\x91\x40\x1e\x25\x65\x46\xe3\x1f\x9f\xcd\x24\xd2\xc5\xb3\x33\xcf\x65\x78\x50\x02\xf0\x8d\x54\x8d\xb2\x6a\xd1\xf3"}, +{{0x8a,0x44,0xd6,0xaf,0xc6,0xc8,0xee,0xe1,0xbc,0x7d,0x5f,0x69,0xe4,0x95,0xb0,0xb1,0x8c,0xa7,0xae,0xe0,0x07,0xde,0xa7,0xcf,0x0d,0x17,0x14,0xd7,0x85,0xa9,0xf4,0xed,},{0xd4,0xf3,0x66,0xb3,0x37,0x7f,0xa3,0x9b,0x36,0xf9,0xae,0x14,0xda,0x40,0x4e,0x22,0x40,0x49,0x0d,0xbd,0x8d,0x79,0x6b,0x1a,0xb8,0x72,0xdf,0xcb,0x83,0xa5,0x95,0x40,},{0xe0,0x72,0x7e,0xb7,0x2e,0x84,0xd2,0xb8,0x2c,0xdb,0xd0,0xa6,0xbd,0x2f,0x49,0x49,0x63,0x16,0xaa,0xe8,0x35,0x1e,0x49,0x02,0xac,0xd5,0xe3,0xcc,0x57,0x34,0x6e,0x7e,0xba,0xfd,0xd9,0x2a,0x90,0xde,0xd7,0x6f,0xd0,0xc6,0x69,0x0d,0x68,0xbb,0x2f,0xed,0xd6,0x13,0xe4,0x4f,0xa2,0x22,0xbe,0x01,0x26,0xda,0x52,0x0a,0xcc,0x2c,0x41,0x05,},"\xde\x80\x32\x69\x66\x53\x6c\xe9\x49\x96\xaf\x2d\xe7\xa0\x76\x05\xcc\x4f\xcb\x9e\x75\xee\x0a\x67\xa1\xe2\x09\x32\x11\x1d\xe9\xb3\x56\xd5\xbe\xea\xe8\x6c\xc5\xf5\x64\xc1\x0d\x66\xe3\xde\x95\xa5\xb9\x9e\x84\x49\x28\xea\x8e\x77\x58\x6c\xf3\xc1\x0a\xd3\x63\x3d\xde\xeb\x1d\x9d\xcf\x3f\x94\xb7\x0b\xf1\xef\x63\xd2\x38\xdf\x20\x4d\x70\x5c\x0b\x17\x4f\x83\x28\x25\x45\xf5\xe4\x07\x5f\x8d\x69\xa4\x81\x79\xc2\x9e\xab\xf5\xc1\x74\x2e\xf3\x9e\x1a\xd9\x63\xbe\xbb\xb6\x6f\xce\x94\x91\xa9\x84\x65\x12\x15\xc2\xe7\x50\xe6\xee\x83\x65\x76\x64\x40\xa8\x44\x19\xe5\x2d\xcf\x67\x1f\x1c\x52\xea\xa2\xb9\x90\x2b\xcc\xa4\xb3\x7c\xff\xdb\xac\x8e\x7e\x7e\x6b\x0a\x5c\x87\x48\xef\xbf\x45\x2d\xf6\x16\x3f\x4c\xa0\x7b\x61\xf9\xa0\x5e\xc2\x0a\x2b\xd6\x33\x38\x9e\x67\x0b\xb5\x45\x4a\xcd\x6f\x3a\x06\x33\x5b\x5d\xa9\xec\x32\x62\x64\xe9\x62\xc7\xd9\xd0\x6c\xe7\xe9\xff\x04\xa0\xa5\xbb\xdf\xaa\x4c\x41\x08\x66\xa5\x72\x01\x16\x51\x43\x9f\x2d\xbc\xe5\xde\xe6\x67\x92\x4a\xc4\x93\x4d\x20\x54\x96\xbd\x1d\x4d\xf0\x8b\xd0\xcb\x3f\xd2\xde\x73\xa2\xef\x34\x2f\xf0\x09\x1e\x10\xe1\x5b\x3b\x76\x0a\x57\x5d\xf9\x3c\xf1\xc9\x7c\x01\xc5\xab\x11\xc0\x94\xbf\x34\x87\x82\x06\x71\x8f\x6b\x28\x5a\xa5\xcc\x51\x27\xbd\x7f\x98\x8b\x84\xa9\x04\x95\x30\x6f\xd9\xe9\x9d\x89\x55\xe6\x68\xd1\xa3\xff\x10\xf6\x5b\x7c\x47\x9f\xac\x24\x11\x9a\x3c\x10\x12\x2d\x4d\x18\xa8\x05\xb2\x47\xdf\x16\x8c\x0a\x51\x00\x16\x9b\x55\x72\xd1\x70\x12\xd7\x51\xa4\x2e\x83\x37\x61\x15\xe1\x15\x61\xc1\x60\xc1\x5e\xfa\xd7\x6d\x21\xf7\xab\xb4\x30\x36\x64\x75\x23\x86\x31\xf8\x4c\x88\xf8\x38\xb0\xac\x40\x4c\x91\x3d\x2f\xa1\x24\x50\x23\x84\x85\xc3\x02\xfc\x20\x1f\x44\x15\x1c\x19\xbc\xbd\xc1\x19\x0c\x12\xd1\x54\x08\x31\xfb\x19\x58\x1c\xb9\x31\x72\xb0\xd2\xff\x5c\x65\xf3\x1c\xaf\xf2\x0f\x81\x38\x81\xf8\x4e\x5e\xf9\xd5\xc1\x65\xe0\x96\xd2\x54\xca\xdf\x89\x52\x49\xaa\xb8\xd4\x49\x6c\x94\x0a\x40\xf9\x07\xbd\x40\x93\x5a\x94\xf5\xe5\x5b\x6d\xd0\x51\x15\x41\x00\xfe\x33\x17\x70\xef\xf2\xba\xd6\x54\x56\x19\xb8\xa3\x3e\xf6\x46\x2a\x50\xc0\xb2\xc4\xed\x2f\xba\x4e\x4e\x38\x3e\xbf\x29\x32\xe6\x19\x27\x66\xa4\xaa\xd1\xd6\xe2\xb6\x92\xd9\xf2\xbd\xc2\x33\x93\xe8\xaa\xcf\xba\x32\x3b\x53\x4f\x84\xed\xf2\xdc\xed\x7c\x94\xd5\x16\x87\xda\xa2\x71\x98\xa9\x14\x4b\x31\x2b\x71\x6f\xe1\x70\x14\xa7\xbe\xd0\xc1\x4a\x24\x38\x73\x3d\x55\x5c\x65\x64\xc8\xc1\xa3\xd9\x97\xeb\xae\x7b\x3d\xe8\x87\x7a\xf5\x3c\x1d\x1a\x50\x29\x15\x8a\x80\xaa\x0c\x87\x48\x9f\xef\x27\x0c\xdf\xfe\x10\xd3\x4b\x15\xc1\xa9\x69\x3a\xe0\x39\x02\x43\xe3\x14\xcf\xac\x06\xef\x6e\xef\xeb\xcc\xf4\x3d\x42\xea\xc2\x4c\xe9\x87\x94\x29\xd2\xfc\x72\x53\xb3\xed\x17\x58\x25\xbc\x4d\xa0\x76\x2b\x49\x33\xa9\x8a\xfd\xb9\x4b\x06\xf4\xfc\xd2\xad\x36\x11\xaa\x99\x9d\x7c\x1c\x8d\x85\x2d\x01\xdd\x9e\x52\x64\x84\x55\xa0\x4e\xb2\x33\x0a\x76\xfd\x94\x2c\x53\x1e\x51\x4b\x5e\xc0\x72\x8a\x89\xd3\x4c\xa5\x90\xea\x99\xc8\x8f\xaa\x20\xdf\xb7\xbb\xf6\x56\x54\xaa\x6c\x21\x2b\xeb\x8a\xd6\xbf\x7c\x77\x73\x91\xcd\x49\xc3\x9c\xf8\xab\x51\xb9\x5b\x41\x9e\x3d\xfc\x8d\x94\xa9\x3a\x1e\xf0\x22\x3c\x6d\xe9\x0b\xf9\x62\x18\xd8\x04\x5b\xd4\x95\x2a\x0d\x83\x72\xa5\x57\x8c\x6a\xaf\xa7\x4b\xa6\x62\xe3\x18\x8e\x6a\x6e\x56\x7e\x4d\x2f\xe8\x22\x7d\x07\x43\x98\x2a\x41\xeb\xfa\x0d\x31\x0f\xe7\x9f\xed\x27\x04\x17\x90\xef\xd5\xaf\xac\x22\x43\xe1\xd1\x50\xb1\x45\x01\x5d\x9d\xea\xb0\xed\xed\x63\x94\xac\x36\xfc\x5f\xb2\x01\xf5\x20\x4f\xbd\x42\x2a\x36\x04\x23\x30\x15\xbb\x0a\x48\xa9\x20\xe2\xe5\xe0\xd4\xde\xed\x67\x20\x25\xf2\x3c\xfb\xa9\x38\x89\x59\x7e\x50\x4c\x88\x87\xad\xd4\x6c\xfe\xf4\x02\x4a\xfb\x8a\x26\xee\xb7\xdc\xdd\xb2\x39\x7b\x44\xa1\x79\x63\x67\x34\x00\x42\x13\x70\x28\xc3\x30\x76\x26\x81\x6c\x29\x31\xe6\x1e\xbb\x6b\x69\xed\xcb\xcb\x61\x2c\x9b\x18\x1a\x28\x53\x01\xce\x46\xf8\x2f"}, +{{0x8a,0x97,0x2d,0xd0,0xf1,0x19,0x0c,0x2b,0x9d,0x54,0x8f,0x4b,0xa5,0x82,0x64,0xbb,0x04,0x82,0x67,0x75,0x50,0x2a,0x8d,0x5c,0x2b,0x20,0x9e,0xe8,0x8d,0xce,0xa5,0xfb,},{0x6d,0x80,0x37,0x5f,0x3c,0xf1,0xaa,0xb2,0x83,0x55,0x1d,0xf4,0x45,0xd1,0x7e,0x7d,0x3b,0xaf,0x9b,0xcb,0xec,0xbb,0xb2,0x67,0x05,0x2e,0x02,0xfd,0xb6,0x91,0x44,0xd3,},{0xbd,0x45,0xb3,0xc0,0x45,0x85,0x0e,0xbe,0xf7,0xb8,0x0d,0xd1,0xde,0xab,0x48,0x03,0x7b,0x13,0x46,0xc7,0x1d,0xea,0xf1,0xe5,0x8f,0x2a,0x7b,0x16,0x26,0x74,0xf9,0x4d,0x1e,0xf3,0xd4,0x23,0x90,0x37,0x33,0x0b,0xd6,0x33,0x5f,0xe4,0xf0,0x14,0x92,0x50,0x90,0x1f,0x00,0xa8,0xe4,0x6b,0xe5,0xfa,0x0a,0xae,0xc6,0x9d,0xe0,0x6d,0x73,0x04,},"\x30\xb2\x89\x48\x93\x9a\xa2\x63\x43\x7e\x45\xc5\xc0\x25\x4f\xb2\x0e\x61\x7e\xd0\xf3\xfa\x7d\xac\xe5\xa0\xa8\xe0\xfe\x3c\x1f\xc4\xad\xb2\x80\x9b\x61\xc5\xe8\xd9\x2c\xd2\xf3\xde\x93\xb1\x73\xbe\x70\x7b\xad\xa9\x42\x40\xc6\x26\x2c\x16\x0e\x8c\x78\x21\x65\xbe\xef\x99\xd0\xbe\x8e\xcd\xad\x63\x16\xdc\xd7\x34\xbb\xb9\x0a\x66\xcb\xd5\xb1\xcb\x4f\xd8\xf2\x22\x6c\xea\x94\x8e\x4d\xf7\x6b\xbe\x25\x1d\x47\x8f\x5c\x3f\xe0\xd6\xde\x4b\xe5\x4f\x67\xf5\x02\xb2\x80\x4f\x62\x8b\x79\xa5\x50\xfb\x1a\xc4\x83\xad\x2b\xa1\x66\x37\xc4\xbc\x9d\xa6\x7f\xb4\xf9\x86\x59\xc4\xc4\x39\x4d\x16\xb6\xd1\x4b\x3e\x0b\x0c\x1e\x62\x5d\x71\x0d\xcc\x1c\x11\xdf\x5d\x34\x14\x7b\x1e\xc5\xa4\x17\xb9\xe2\x1f\x90\x8c\xfc\x52\x3d\x43\xe3\xf1\x81\xc7\x20\x9c\xc5\x6b\xdb\x5a\x21\x62\x86\x95\xed\x32\x0f\x8d\x4c\x07\xfd\x6d\x84\xaa\x03\x42\x6f\x21\x64\x4a\xae\xfe\xee\xc3\x11\xc7\x4e\x94\x99\x93\x60\x47\x35\x0a\x9b\xf5\xb7\x03\x96\x2e\x77\xce\x55\x13\x36\x83\x5f\xc3\x2c\xcb\xd2\xc9\x0a\xe5\x2e\x24\xd4\x7d\x8d\xcb\x98\x7a\xbd\x12\x1d\x3f\x74\x6b\x5d\xe2\x30\xf2\x64\x69\x60\x3f\xb0\xc4\xa8\xf6\xcd\x79\x73\xd7\xda\x88\x2e\xd1\xd6\xe4\xd9\xc5\xa4\x6e\xc2\xc2\x19\x40\xad\x33\x89\xa1\x86\x01\x4e\xe9\x72\x78\xe5\x35\x09\x88\xb1\x5e\xcd\x9e\xa7\x45\x6b\x3c\xb5\x5e\x4d\x30\x93\xf1\x3a\x87\x5b\x50\xd6\x51\x63\x78\xec\xaf\x58\xd7\x52\xc6\x37\x4e\xd1\x56\x38\x40\x93\x11\xfc\xd3\x79\xd1\x22\xc8\xd8\xc5\x9b\x86\xf4\xe8\xdc\x46\xad\xb7\x30\xa9\x33\x84\x6e\x0b\xd2\x48\xd3\x60\x82\x52\xd9\x70\xb5\x04\xc8\x13\xc6\xde\xa9\xfc\x88\xa3\xde\x64\x19\x56\xdc\xa2\x91\x20\x4d\x39\x0b\x6b\x39\x98\x1f\x8c\x0a\x6b\xcf\xc3\x1c\xa0\x74\x44\x20\x66\x2a\x9b\x35\xeb\x3f\xc2\x11\xf8\x10\xa3\xe8\x06\x25\x00\xb1\xe4\x9b\xdf\x85\x76\x65\xff\x32\xa9\xba\x76\x19\x4b\xbb\x77\xfb\x9c\x15\x41\x29\x64\x24\x4b\x98\x65\xf7\x3d\xed\x9f\x25\xb4\x9b\x42\x5a\xa2\x53\xd8\x07\xd9\x81\x82\x92\x76\x3a\x51\x3e\xc8\x07\x47\x34\x4f\xba\x0a\xcf\xe5\x93\xcc\x26\xb1\x33\x0b\xb9\xad\xe6\x6c\x4e\x88\xcf\x1b\xae\xd6\xd6\xe7\xb7\x50\xe6\xc7\x23\x9d\x7b\xcb\xfa\x3f\xbe\x45\x40\x5a\x63\xb9\x6d\x50\x34\xcc\x0c\x07\xff\xc3\xb5\x08\x58\x08\x1d\x19\x55\xe2\xd2\xfe\x5b\xe5\xfd\xa7\xa8\x99\x69\x43\x76\x8b\x05\x51\x70\xb7\xfd\x52\xf0\xa3\x20\x97\xfe\x1b\x7a\x94\xf1\xbf\x87\x9a\x0c\xba\xbe\x10\xac\x9a\x7c\xc1\xf9\xf5\x50\x68\xc4\x8e\x3c\xcc\x06\x51\x36\x43\x10\x18\xd3\x8d\x20\x10\x9d\xc9\x5d\x99\xcc\x2b\xbe\x7c\x62\x7a\xb1\xa8\xaa\x5f\x43\x16\x13\xb7\x90\xc2\xe6\x52\x6c\xf0\x4f\xdc\x9e\x55\xf5\x1c\x05\x5f\x3c\x20\x45\xa6\x75\xe3\xa1\xe5\x4b\xa4\x09\xf7\xae\xfa\x7e\x4a\xa0\x7a\x2b\xbd\x5e\x4a\xb1\x63\x21\xa9\xf0\x99\x69\x43\x91\xfd\xa6\x8a\x74\x58\x1e\x2f\x1f\x11\xdd\x9a\x6d\x52\x4b\x1b\x83\x26\x0d\xb5\x7b\x72\xef\x29\xc2\x8c\x8d\xb5\xc3\x7f\xd1\x85\xb7\xc2\xd8\x45\x50\x90\x65\x3a\xf3\x32\xdb\xc8\x2b\xfb\x0d\xb5\xdc\xca\xbf\xb6\xb2\x8c\xaa\x35\x05\x25\xcb\x54\xcc\x84\xe5\x53\xe1\xcf\x39\x54\xb6\x12\x39\x3e\x79\x93\xff\x7e\x8b\xf5\xec\xe3\xf1\x45\x09\x4d\xd7\xa2\x7c\xb4\x7f\x22\x74\x76\xf2\x89\x23\x52\x51\xf7\x72\xb3\xba\x77\x6b\xb7\x73\xaf\x0c\xc5\xf7\x86\xa3\xfb\x9e\x93\x1a\x53\x0c\xfb\xd8\x91\xcb\x5a\x5d\xfe\x25\x16\x9e\xf9\x33\xcc\x82\xc9\x08\x0f\x32\x39\x61\xa1\x20\x15\x8e\x4b\xbd\x71\x13\x4e\xf1\xf9\x01\x08\xb8\x15\xc2\x89\xd4\xe9\xa9\x58\x9e\xc6\x4c\x05\xfb\xb4\x2a\x21\xb2\x3d\x16\xe2\xa6\x46\x78\xae\xcf\xab\x65\xcd\x9a\x80\x6c\x59\x81\x03\xd4\x1f\x70\x09\x77\x63\x17\x83\x1f\xed\xdd\x1c\x90\x02\xd4\xa9\x22\x04\xf9\x7b\xa9\x49\x0c\x61\x46\x98\x03\x07\x21\x02\x52\x4b\x9d\xf5\x19\x00\x5f\x98\xaf\x54\xd6\x0c\xa5\xba\x60\xb5\x5b\x09\x6a\x4a\xc2\xb1\x6e\xb9\xcc\x81\x97\x3c\x31\x35\xd3\xfb\x68\x73\xdd\x96\x53\x80\x0a\x22\xbb\x5d\x0d\x61\x17\xca\x5d\x91\x65\x53\xbe\x39\xc9\xa3\xb5\x11\xeb\x3d\xb7\x30"}, +{{0x12,0x38,0x0c,0x45,0xa7,0x9a,0xde,0x0f,0x48,0x3c,0x88,0x1a,0xaa,0x37,0x30,0x43,0x8b,0x08,0x35,0x90,0xf4,0x04,0xdc,0x9e,0x60,0x1f,0x76,0x15,0xf3,0x75,0xa6,0x28,},{0xd6,0x6f,0xc5,0x9a,0xe9,0x17,0xf7,0x6d,0x24,0xce,0x8a,0xb8,0xee,0x03,0xfb,0xcb,0x71,0x5d,0x5e,0xea,0x4b,0x08,0x39,0x2b,0x59,0x1e,0x64,0x85,0x91,0xc7,0x3c,0x89,},{0x02,0xb2,0x51,0x74,0xa3,0xdd,0x52,0x19,0xed,0x48,0xb2,0xc9,0x4c,0xa2,0x12,0xb6,0x3a,0x6a,0x3a,0x25,0x97,0x70,0x3c,0x07,0xb7,0xf0,0xc9,0x65,0xc3,0xc6,0xac,0x2e,0xb4,0x50,0xef,0xe3,0x87,0x16,0xa2,0xa2,0x8b,0x3f,0x89,0x84,0x6b,0x06,0xeb,0xdc,0xa4,0xbd,0x09,0xaa,0x58,0x1f,0x24,0xe8,0x4d,0x80,0xfc,0x10,0xac,0x1a,0x00,0x0a,},"\x68\x45\x23\xc2\xe7\xfa\x8b\x4b\xd7\x54\x8c\x4b\xac\xaa\x86\x78\xa3\x30\xdb\xbb\x96\x06\x32\x94\x01\x66\xb2\xcc\x9a\xfc\x15\x35\xc8\x0c\x11\x2c\x8d\xc4\xad\xa7\x62\x92\x33\xfe\x90\x90\x55\x23\x7d\x51\x3e\x29\x2a\xf1\x5a\xd7\x69\x2f\x11\x5a\xa0\x92\xda\x65\x75\x32\xf5\x18\x99\xc3\xf7\xf5\xd9\xd4\x07\xed\x5c\x16\x3e\xb3\x95\x04\x80\xa4\x12\x2a\x09\x92\x98\x1f\x07\x7b\xc8\x67\xf9\x06\x07\x54\x07\xba\x98\x49\xc4\xea\x04\x73\xce\x54\x0a\x79\x67\x44\xef\xa3\x86\x03\x78\xe1\xb8\x93\x43\xe5\x83\xd0\x80\x7e\x5a\x67\xc4\xd5\xbd\x7c\xe6\x41\x29\xfe\x90\x2b\x8c\xfa\xbd\x2c\x21\xfa\x3d\x2a\x10\xe9\xbf\x9e\xa5\xe5\x47\x3a\xe2\x50\xc9\x16\x05\x09\x97\x26\x78\xf9\xa7\x40\xe6\xca\xdb\x3b\x52\xf5\x02\xfa\x61\x6c\xff\xae\x1d\xef\x89\x3d\x54\xe4\x1e\x54\xd3\x26\x46\x4c\x9f\x43\x5c\x63\x50\x5f\xb1\x5e\x3e\xea\xf5\x02\x1c\x65\xdc\xd0\x10\xf8\x40\xaa\xb3\x17\xc8\x60\x5d\xfb\x1a\x0c\x8a\x3d\x55\x49\x86\x1b\x69\xaf\x2c\x93\xd8\x6c\x98\x1d\xf3\xa5\x1c\x5b\xf5\x78\x5c\x2f\x85\x26\x10\xe4\x4f\xa4\xff\x1c\x71\x61\x15\x2e\x56\x18\x38\x47\x44\xfe\x83\xba\xbf\x0b\xcb\x75\x61\x78\x9a\x02\x31\x25\xf6\x24\x2a\x18\x3c\xac\x95\x49\xc9\x32\x73\x3a\x86\x8a\xa1\x82\x65\x6e\x2b\xa0\xa8\xc0\xbe\x10\x69\x96\xa8\x5c\xeb\xf1\xbd\xad\x12\x3b\x98\x2b\x4e\x05\x55\x10\x87\x94\x82\x02\x1d\xae\xa9\xd8\xf2\x6c\x58\x8e\x6c\xd1\x01\x26\xcb\x31\x96\x88\x03\x56\xbe\xe8\xf2\x98\xbc\xa3\x06\xec\x56\x99\xc7\x57\x6b\x76\x50\x87\xc2\x53\xa6\x02\x14\x01\x0c\x6e\xd7\x0d\x87\x1c\xfc\x87\x38\x01\x8a\x0e\xdb\x57\xf1\x06\xb4\x21\x8d\x85\x5e\xab\x2c\x91\xf3\x9f\x85\x8b\x3f\x25\x90\x56\x31\xa0\xee\xe2\x98\x56\xfd\x34\xf7\xb8\xc9\xba\x51\xc1\xc4\xc6\xa7\x35\xd6\xc7\xa1\x3d\x22\x0d\x7a\x56\x6c\x3f\x50\x6c\x72\xbc\x74\x17\xab\x37\xf0\xd6\xd7\x96\xff\xc7\x1d\xf9\xdc\x7c\x6e\x13\x7d\xa5\x6b\x7a\x3e\x10\xcf\x0b\x1a\xbb\x3f\xfb\x70\xbc\x66\x29\x3b\x5d\x75\xb4\x05\xed\x8b\xec\x0d\x6f\xcd\x06\x92\x5c\x38\x11\x68\xac\x18\x8d\x0b\x8a\x1a\xf0\x83\x9f\x5b\xde\x84\x3b\x69\x91\xe5\xa5\xd6\xcd\x66\xfe\x6b\x0f\xde\x86\x7c\x08\x6e\xd4\x38\x76\x91\x9a\x1b\x72\x33\xd8\xd7\xe1\xd2\x74\x2f\x61\xc7\x7d\x8e\x59\x91\x68\x9c\x83\x28\x67\x66\x55\xb7\x6a\x37\x50\x56\x0e\x75\xd1\xc7\xe8\x5e\x3c\x00\x85\x05\x93\x31\x09\x4b\xba\x57\x10\x03\x2c\xf6\x79\xa5\x25\xc7\x8b\x31\x70\x0e\x6d\x91\xf7\x52\x94\xc4\x22\x48\x92\x97\xe1\x73\x59\x43\xe4\x17\xfc\xd3\x55\x80\x58\x2f\xdd\x02\x39\xb5\x11\x46\x53\x0c\xc0\x9d\x83\xb2\x8f\x0a\x1d\x64\x22\x20\xdf\xb9\x9b\xad\x62\xf3\x95\x41\x03\x50\x81\xd6\x5d\x77\x8d\xdf\x32\x39\xba\x0e\x6f\xa9\x91\x4b\x17\xb3\x97\xa5\x34\xcb\x8f\xd3\xb4\xff\x42\xa8\xd8\xc8\xee\x66\x15\x3f\xbb\x1f\xf0\xfa\x54\xf7\xbd\x03\x27\x85\x16\xe6\x34\x1a\xf8\x0f\xcd\x1f\xce\xe7\x0c\x35\x9d\x20\x53\x68\xac\x49\x0d\x75\xa3\x54\x51\x2d\xa4\x6b\xa7\x63\x4c\x15\xb2\x84\xb2\x44\x77\x80\x8f\x17\x63\x33\x60\xa4\xb4\x9f\xb3\xbc\xaa\x84\x18\x41\xcf\x92\x41\x7e\xb2\x4c\xe4\x82\xd5\xa2\x4b\xfd\x2d\xac\x37\x22\x31\xda\x53\x9a\x05\x42\x00\x02\xff\x7a\x20\xc4\x76\x09\x7d\xa0\x6f\x59\xf0\x33\x14\xe6\x05\x9f\xad\x88\xc5\x0c\x3b\xaa\xc0\x3c\xef\xa7\xcd\x82\x11\xd2\x46\x1b\x16\x60\xea\x6b\xcf\x47\x68\x38\xc9\x1a\x10\x07\x4e\xb4\xb4\x0e\x6e\x97\x4a\x94\x5a\x67\xf6\xee\x69\x04\x23\x1e\xf0\x41\x88\xf1\xea\xd5\xba\xf3\x56\x94\xef\xe3\x01\xed\xc7\xe8\x66\xda\x23\xb5\xa6\xc5\x8f\x01\xb2\xa5\x2c\xf3\xab\x80\x5e\xdc\x5c\x13\x68\x62\x6b\x95\xb9\x4e\xb4\x64\x5b\x69\x3e\xc8\x80\xf2\xb8\x11\x7a\x69\x3a\xfb\xdc\xd2\x48\x24\x31\x89\x0f\x41\x0b\xc5\x80\x53\x0f\xef\x37\x58\x79\xc2\xe4\x60\x49\xca\x89\x1a\x2c\x3e\xcd\x60\x43\xae\x80\xd8\xaf\x34\x66\x34\x67\x4c\x6d\xfe\x90\x59\x97\xde\x5d\x05\xd6\x20\x09\xee\xed\x27\x75\x02\xfb\x5a\x5a\x31\x55\xee\xee\xb6\x73\x48\xb6\x0d\x89\xa3\x4a\x78\x12\x63\x9f\x54\x1f\xfe"}, +{{0xd1,0xb3,0x43,0x0d,0x4e,0x63,0xaa,0xbf,0xa9,0xef,0x96,0xbc,0xba,0xf1,0xfa,0x6a,0x9e,0xb5,0x21,0x9d,0xd4,0x4d,0xf3,0xb1,0xa6,0x15,0x63,0xdf,0xfe,0x1c,0xcb,0x28,},{0xc2,0x8a,0x05,0x19,0x52,0x45,0x29,0x0e,0xcd,0x38,0x53,0x55,0x85,0xce,0x51,0xf3,0xc2,0x35,0xc5,0xd6,0x50,0xc8,0xc5,0x7c,0x2f,0x79,0xbb,0x0a,0xc0,0xe8,0x08,0x34,},{0x4c,0xb6,0xff,0x5d,0xd7,0x06,0xb1,0xae,0x81,0x6c,0xdb,0xaf,0x9e,0x9e,0x1e,0xdc,0x80,0xa6,0x62,0x84,0xf9,0x46,0x52,0xd5,0x0e,0xc1,0x4e,0x28,0x3b,0x2a,0xdc,0x59,0x2f,0xd0,0x84,0x33,0x71,0x44,0xff,0xa7,0x12,0xdc,0x34,0xce,0x8e,0x61,0x06,0x68,0xa6,0x5e,0x96,0x9f,0x05,0xce,0xb5,0x47,0x86,0x30,0x4d,0x0d,0x58,0xd3,0x1a,0x08,},"\x07\x6c\x0c\x87\x62\xe4\xbc\x00\x3c\x36\x0a\x12\xa1\x95\x98\x05\x05\x51\xd1\x6b\x4b\x8d\xa0\xfb\x9c\x4a\xfc\xc8\x1a\xdb\xe6\x19\x95\xf2\x5c\xbc\x28\xdc\xa4\x20\xbf\xa9\x46\x10\x54\xd3\xee\x00\xad\x78\x18\x3e\x7f\x26\xdf\x68\x98\xaf\x9a\x4d\x22\x5f\xca\xb6\x7c\x04\x2e\x9a\x13\x52\x5d\x1f\x75\xff\x0e\x3d\x8d\xa8\x08\x96\xb7\x28\xf3\xe2\xdb\x65\x94\x4a\xe0\x71\x7d\x77\x59\x90\xb5\x9e\x5b\x70\x43\x4b\xd4\xb3\xee\x45\x2f\x10\xac\x06\x10\x57\x0b\x38\x22\x08\x32\x96\x8f\x54\x4d\x3e\x4d\x11\x9b\x1d\x4b\x50\x15\xc6\xcd\xf4\xcf\x22\x0b\x56\xb5\xc0\xcc\xd8\xe3\x98\xd5\xe4\xa5\x8d\xa3\xb0\xe2\xb2\x70\xa5\xd3\x9b\x82\xab\xb7\xf9\xd2\x7a\x41\x90\x18\x55\x0b\x62\x00\xae\x51\xc8\x48\x82\xf0\x86\xae\x7e\xa5\x35\x16\x71\xb6\xdd\x96\x09\x23\xad\x6b\xef\xc1\x34\x09\x87\x9a\x8d\xf6\x19\xbd\xf6\xc8\x8a\x6f\xe1\xec\xc0\xf0\xf3\xaa\x21\x9f\xb6\x19\x02\xbe\x48\xa5\x3d\xf2\xbc\x66\xc5\x6f\x1c\x1d\x17\xf7\xe6\x16\x7d\x25\x51\x65\xf1\x74\xba\xa9\xca\xf5\x3c\x73\xcb\xbb\x7c\xc2\xc7\xc0\x87\xf4\x3a\xbe\x2a\xed\x5a\x21\xfe\x42\x90\xb8\xd6\x79\x60\xa8\xa9\xcb\xc2\xa5\x7a\xbe\x22\x65\x4d\xc1\x84\xcf\xf9\x16\x8b\xb6\x97\x27\x03\x75\xfe\x88\xd5\xc4\x9c\xf9\x5b\x06\xcf\x9d\x0d\xac\x81\xfb\xd9\xc0\xd7\xb8\x2d\x05\xed\x2c\x3f\xd4\x9c\xcc\x29\x40\x44\x41\x71\x25\x45\xf9\xa9\x91\xe4\xf0\xdd\xb6\x21\x90\x83\x82\x96\xf9\x67\x29\x9a\x38\x60\x72\x26\xd8\xa6\x81\xf0\xa8\xf3\xc4\x38\x4f\xd1\x8b\x30\x25\x7c\x46\x3c\x0a\xbd\x0f\x4f\x6f\x12\x25\xa5\x1b\x76\x2d\x6d\x0a\xc7\xd5\x9c\xd2\xef\xd6\x98\xb8\xd1\x3e\x23\xd7\x04\x09\xf6\xb0\x7d\x69\x5c\x16\x71\xcd\x6f\x59\x44\x3b\x1d\xb0\xab\x35\xb9\xdc\x06\x40\xe4\xc6\xd1\xac\x50\x47\x5d\x28\xef\x94\xf8\x17\x90\xe2\xe5\xb2\x54\x55\x14\xb2\xa4\x9c\x5c\x21\x53\x45\x9b\xe5\x40\x89\x0f\x53\xbc\x18\xe4\xa1\x6d\xcb\x5d\xcf\x50\xf3\x7a\x95\xc6\x06\xfd\xf4\x85\x98\xe5\x2a\xf3\x17\x9a\x20\x48\x61\x5d\x93\xd9\x7e\x05\x99\xb7\x08\x8c\x11\x74\xbb\x9f\x15\xe3\x70\x18\xf9\x9a\xcb\xce\x5b\x13\x02\xf8\xd8\xce\x2a\xb8\x54\x37\xfe\xeb\x0c\xaa\x77\x84\xdc\x83\xc9\xe7\xc3\x6f\xe0\x59\x90\x6b\x03\x0a\x86\xa3\xde\xd0\xab\x9d\x8b\x73\x52\x9d\x47\x5e\x66\x1a\x08\x08\xd6\xd3\xf0\x90\x7f\x85\x28\x87\x3f\x08\xd5\x74\x8b\xe1\xd6\x97\x12\xe8\x52\x62\xd7\x7b\xdf\x13\xbf\xd1\x8a\x5c\xde\x6f\x71\x46\x26\x73\xab\x29\xb1\x61\x73\x15\xa9\xa6\xe9\x36\xa8\xe8\x1a\x8e\x43\xbd\x0f\x66\x44\xa5\xc6\x9e\xaa\xac\x89\xbd\xaa\x99\xcc\xa8\x03\x83\x37\x05\xe5\xaf\xa6\x9b\x3b\xd1\xd0\x25\x2b\x85\x46\x50\xf2\x19\x97\x91\xe6\xac\xa7\xc7\x5a\x86\x12\x83\x21\x62\x33\xa2\x63\x3a\x6a\xef\xf9\xd3\x01\xee\x5c\xb4\xdd\x72\xc0\x8a\x45\xcd\xae\x8f\x54\x58\xc0\x95\xb2\x2e\x75\x9c\x43\xb4\x9b\x98\xe9\xf4\xcb\x33\xd5\xde\xa8\x79\x44\x9e\xae\x73\xcb\x87\x4c\x73\x59\x43\x25\xeb\xf6\x8c\x1e\xd4\x06\x4b\x6f\x61\xab\x2f\x01\x4a\x2f\x19\xf3\x2e\x12\xb3\x3c\x5e\xaa\x8a\x29\x20\x4d\x5e\xba\x58\xdc\x07\x50\x72\xfe\x39\x9b\xe7\xd1\xab\x18\x08\x20\x8f\xb4\x08\x12\x3b\xdc\x0b\x4a\xb3\x13\x0f\x9f\x70\x6d\xc3\xeb\x19\x4b\x60\x5e\x73\xa3\x2f\x12\x5a\xe4\x91\x28\x5c\xe6\x03\x9f\xb6\x23\xc3\x8b\x81\xd5\xab\xa0\xf5\x59\x9f\x6c\x86\xe8\x72\x48\x6b\x4e\x96\x49\xda\xff\xe3\xa3\xd0\x6c\xb0\x73\xdd\x3b\xc6\xf4\xe1\x0a\x18\x70\x0e\x45\x72\x2d\x78\xa6\xb0\x97\x2d\xc9\x4d\x5c\x7a\x7b\x66\x41\x75\x7b\x79\x60\x75\x71\x9d\x7b\x8e\xc3\x6a\x1e\x79\x6f\xb5\xf8\xfe\x6f\x1b\x79\xa0\x85\x9c\xb4\xd6\x7c\xec\x05\xed\x91\x4c\xfa\x32\xc1\xdd\xfe\x21\x8e\xf9\x63\x43\x6c\x3a\x11\x48\xac\x2c\xf9\x09\xdf\x73\x59\x89\x06\x57\x46\x3a\x4e\xa2\x5f\xed\x59\x61\x8a\x06\x81\xa1\x21\x7e\x22\xd6\x4e\xf9\xd9\xb4\x55\x9d\x0a\x0f\x6b\x3c\xe8\xd8\x47\x93\x0b\x23\x23\x01\xca\xf4\x4c\xdf\x7a\x3f\x18\xa2\xac\x13\x0b\x92\xcf\xd9\xc0\x33\x60\x55\x7b\x5f\x7c\x47\x75\x46\x2a\x10\x71\xf7\x03\x44\xc7\x18\x37\x4b"}, +{{0x03,0x3e,0x00,0x3d,0x7a,0xab,0x7b,0xc7,0xfc,0x8a,0xc2,0x04,0xc7,0x33,0x79,0x9a,0xe5,0x53,0xc3,0xfe,0xc5,0x3f,0x10,0xdb,0xf7,0x95,0xb5,0xf4,0xb8,0x7f,0x1c,0x95,},{0x68,0x2f,0x46,0xf5,0xc0,0x56,0xdd,0x45,0xba,0x0b,0x5a,0x78,0x20,0x31,0xf9,0x59,0x6a,0x73,0xaa,0x29,0x2c,0xa2,0x32,0x6b,0xed,0xa7,0x4a,0x52,0xfc,0x32,0xb7,0x16,},{0xed,0xb4,0xe0,0x20,0xd6,0x76,0xfa,0xc6,0xa8,0x45,0x53,0x48,0x80,0xbf,0x61,0x36,0x37,0x4a,0x8b,0x7f,0x2c,0x53,0x85,0xbb,0x9e,0xe2,0x25,0x38,0x1f,0x49,0x4e,0xfb,0x74,0xa5,0x5b,0x41,0x3a,0xe0,0xea,0x70,0xad,0xd6,0x1b,0xfd,0xfb,0x87,0xfb,0x42,0xd5,0xbc,0x0c,0x53,0x59,0xdd,0xdd,0x57,0x3d,0x53,0x8a,0xe9,0x3a,0x6b,0x36,0x09,},"\x59\x6a\xa2\xc4\x0b\x33\x18\x87\x89\x38\xeb\xc1\x38\xdb\x27\x4b\xb3\x8a\x52\x01\xeb\x7c\xaf\x87\x5e\x6c\x64\x57\x91\xda\xe0\x12\xbd\xef\xd4\x85\xe6\xbd\x9d\x84\x99\xc4\x2a\x2a\xe8\x6c\xf3\x2b\x18\x00\x2e\x76\xbb\x58\x2c\xca\x0d\xec\x48\x15\xde\xd8\xa1\x21\x1f\x8f\xc8\x85\x7f\xce\x1d\x57\xf6\x15\x1d\x88\x78\x7b\x97\x8f\xab\x56\xbf\x92\x6b\x15\x33\xe1\x94\x99\xe8\xbb\x99\x15\x8c\xdd\x6e\x98\x0f\x6b\xa5\x43\xae\x83\x1f\x9d\xd1\x34\xb0\xfe\x6d\x5c\x24\x88\x7d\xc7\xa8\xd4\x78\x1d\xd9\xb7\xfc\x5d\xc9\x46\x4b\x04\x5c\xbf\x9d\x1e\xf5\x03\x6b\x5b\xf2\x8b\x54\x9a\xc7\xaa\x8f\xaf\xb9\x1a\xdc\x9f\xec\xa7\xa1\x45\x54\xd1\x10\xe3\x10\xc7\x49\xe4\x85\x33\xf3\x59\xc7\x0f\x05\xfb\x7a\xed\xef\x13\x66\x36\xb8\xef\x72\x23\x88\x65\x39\x86\x4e\xe5\x2d\x34\x11\x8b\x4b\x8b\x74\xe0\x8f\xe6\xb6\x58\x96\xe4\xb1\x9b\x6d\x7c\x3f\x25\x28\x26\x55\x85\x48\x17\x10\xd2\xd7\x49\x48\xeb\x4b\x17\x08\xa5\x0f\xa7\x40\x21\xbd\xa4\xb3\x61\xbc\x68\xd2\xa5\xd2\x02\x10\x9f\x8d\x28\xd8\xaa\x67\xd7\x8c\x11\x36\xcd\x2e\x90\x3c\x8d\xfa\x17\x5a\xf7\xbd\x96\x3b\x73\xda\xe4\x95\x87\x3c\xcd\xae\x62\xbf\xef\x88\x56\x36\xdd\x83\x55\x0f\xf9\xc0\x5c\x37\xba\x33\x89\xd1\x54\x36\x85\xd8\x94\x83\xb0\xc1\x04\xe7\xef\xbb\x77\x02\xc5\xa0\x39\x8a\xc7\x20\x48\x4c\x50\x93\x68\x35\xee\x9d\xf2\x53\xf0\xef\x8c\xbe\xf3\xe0\x7d\xe9\x69\x51\x1c\xcb\xf8\x75\x57\x49\x3a\x0b\x97\x2e\xf0\xe8\xe6\x29\xcf\x38\x22\xdb\x21\x28\x6e\xd7\x27\x66\x1b\xd3\x17\x86\xfc\xa1\x42\x11\x06\xda\xcd\xee\x1c\xaa\xf4\x94\x54\xe8\x54\x79\x4f\x70\x4d\x22\xa9\x5a\x4c\x8e\x6b\x1c\x2f\xee\xa5\x7e\x56\x23\x8c\x20\x96\xf1\xcc\x57\x86\x47\xfe\xa5\x44\xd6\x76\x44\x82\xbd\xf5\x14\x88\x79\xa2\x5f\x94\x3d\xb1\x6f\x29\x02\x1b\x9e\xcf\xe3\xe0\x90\xb4\x25\xc8\x1c\x70\x09\x84\x2e\x1c\x7a\x02\xd9\x1c\xa6\x0c\x12\x01\xc3\xbd\xae\x9c\x53\x73\xaf\x03\xf2\xf4\xdb\xef\x40\xde\x8d\x9b\x21\xfe\xd6\x8d\xee\x51\x0d\xe0\x42\x72\x34\xca\xa1\xc2\x0a\x3a\xe5\x49\x95\x48\x34\xc9\x33\x73\xd9\x13\xb8\x75\x0f\x23\xa0\x37\x80\xd7\xa9\x45\x4e\xd6\xfe\x51\xfd\x2d\x27\x6b\x9d\x4a\xa3\x2d\xe0\x5e\x03\x81\x6e\x64\xe9\x46\x6f\x4f\x0e\x22\x46\x51\x42\x8d\x34\x2c\xbc\xc6\x97\x17\x0a\x47\xef\x99\x6b\xda\xcb\xce\x91\x11\x7c\xa1\xf8\x45\x5b\x25\xb2\xb0\x84\x43\xe9\x91\x4e\x3d\x90\xc4\x89\xee\xaa\x77\x31\xdd\xea\x21\x23\xd5\x5d\x67\xb1\x66\x83\xfb\x7c\x82\x36\xaa\xa5\xa1\xb0\xfc\xaf\x8d\x17\x00\x11\xdb\xe9\xaa\x28\x57\xbe\x61\x2c\xbb\x85\xef\x69\xe5\x68\x31\xb4\xda\xcf\xbc\x7a\x59\xb4\x65\xa6\x6d\xc7\x41\x2d\xdb\x3d\x6a\xf4\xeb\xfd\x70\x58\x64\xe7\xd4\xfb\x99\xa6\xcc\xb4\x8b\x11\x83\x68\xfe\xab\x02\xa3\x40\xc4\x32\x76\x8d\xe0\xe0\x67\x87\x1e\x9e\xa8\x08\xd6\xd9\x93\x81\x58\x29\xe7\x1f\x6c\x04\x2b\x66\x49\x95\x09\x8f\xee\x94\xd5\x43\xdf\x15\xe5\xb1\x69\x57\x03\x1b\xd2\x38\xbc\xad\xbb\xdc\xc5\x76\xaf\xfb\x64\x03\x03\xd6\x9c\x5b\x25\x0b\x3a\x53\x9a\xfd\x12\x7f\x7e\xe2\x60\x9e\x52\xe5\x15\x4f\xbd\xff\x3e\x45\xf9\xc4\x40\x66\x65\x6d\x56\x1e\x0f\x64\xdf\xf2\x80\x5d\xf8\x8e\x30\xa3\x80\x53\x08\x22\x41\x3a\x7a\xb7\x6a\x1b\x9a\x86\x53\x78\xd2\x47\x63\x06\x9a\x81\x40\x02\xa9\xa9\xd0\x37\x95\xca\x8d\x2b\x5b\xd1\x09\x03\x93\xe9\xe4\xb1\xff\x7d\x7f\x0e\xb8\x4e\x71\x2a\x01\x8f\x68\xc9\xe3\x84\xf0\xa0\xae\xf3\x96\x78\x79\x28\x4f\x40\x9e\x30\xd2\x36\x50\x86\xe6\x69\x52\x27\x8c\xa9\xb6\xf9\x0e\x8f\x69\xa4\x8d\x9b\x28\xbb\x4c\x4e\xd6\x32\xab\xca\x3a\xf4\x14\x4d\xa7\x42\x2b\xf5\x19\x92\xf7\x34\x73\x14\x53\xc7\xa3\x3e\x15\xe5\x9f\x53\x08\x12\x9d\x6a\x77\x4a\x94\x58\x6f\x72\x33\x11\x17\x91\x76\xc0\x94\x8f\xff\x4e\x30\xc1\xb9\x59\x81\x2c\xac\x97\x7c\xc7\x43\x47\xb0\x07\x94\x0f\x2f\xb9\x62\xa9\x0d\x66\x06\x6a\x6d\xe8\x80\x19\x84\xde\xe4\xa5\x32\xd4\xb0\xac\xd6\xdc\xaf\x06\x72\x7b\xab\x70\xb3\x86\x62\x32\x23\x4c\x91\x00\xbf\xdc\x66\x9f\x77\xca\x49"}, +{{0xee,0x55,0xfc,0xf7,0x0a,0x27,0x5c,0x72,0x6b,0xd4,0x85,0x66,0x83,0xb3,0x47,0xde,0xcf,0xd4,0x22,0xf1,0x82,0x6c,0x07,0xa9,0x32,0xcb,0x85,0xbe,0x9f,0xa4,0xef,0x3c,},{0xdf,0xcf,0xfb,0x5e,0x15,0x53,0x78,0x9d,0x56,0xa9,0xf3,0x91,0x4b,0xce,0x50,0x0d,0x07,0xc5,0xac,0x31,0x1f,0x92,0x78,0x54,0xb2,0xcf,0x1e,0x58,0x33,0xc0,0x32,0x37,},{0x9d,0x8c,0xb2,0xea,0xf3,0xff,0x3e,0x0c,0x2b,0xc6,0x72,0xe1,0xd2,0x55,0xc5,0xb8,0xe8,0x07,0x31,0xbf,0xf6,0xf6,0xab,0xa5,0x17,0xe1,0x33,0x54,0xe8,0x51,0x08,0x0f,0x4a,0x8b,0xb8,0x12,0x1b,0x26,0x24,0x24,0x4c,0x9e,0xe9,0x5c,0x8a,0x09,0x2f,0x10,0x37,0x03,0xfb,0xe6,0x6f,0x9c,0xba,0x10,0x0d,0x2e,0x91,0xed,0x77,0x4a,0xc9,0x07,},"\xb8\xc8\x45\xcf\x7c\x54\x85\xf0\x62\x2d\x1d\xdc\x17\xf7\xa0\xf6\xf0\xfd\x70\x74\xfe\x19\x4b\x0e\x0c\xd4\x26\x50\xcf\xc8\x17\xf5\x7f\x09\x5f\x8c\xdf\xad\x1e\xbe\x0d\xfb\xc1\xbd\x76\x17\xab\x4f\x20\x4e\x9d\x55\xd8\x1a\x7c\x8a\x43\x39\x40\xec\x6f\x17\xc8\xa8\xe3\xd5\x6c\x1a\xfb\x0a\xf3\x74\xbd\x32\xd5\x4e\xf7\x13\x2d\x26\xb8\x9c\x47\x0c\x2a\xb5\xbe\x16\xfa\xbb\x4c\x75\x19\x3d\x6d\xa5\x9b\xa2\xfd\x15\x7e\x9e\xa4\xe0\xc5\xc0\x8a\x52\x02\xf5\xed\xc6\xa6\x17\x01\xf0\x8b\xb3\x44\xca\x64\x55\xd7\x5d\x14\x5a\xdb\x24\x4c\x53\x4c\x8c\xfc\x62\x3f\x4d\x4b\x67\x67\x59\x4b\x39\xa7\x69\x0b\xee\xec\x4d\xf9\x74\x6a\x57\xff\xee\x05\x14\x54\xc4\x27\x8e\xa4\x3c\x81\x0f\xf1\x3c\xd7\x69\x61\x5f\x9d\x05\xd4\xfe\x4a\x51\x58\x3e\x80\xc0\x15\xdc\xfe\xd9\xaf\x05\xf9\x3d\x05\x4d\x34\xff\xd9\x39\xbd\xd8\xf0\x51\x8f\xa3\x03\x0a\x96\x4d\xc9\xd8\x0d\xf0\x0f\x16\x35\x82\x40\x72\xcd\xf2\x9b\xc8\x02\x59\x20\x9d\x50\xf5\x6f\xca\x9f\xbd\x6a\xe1\x51\x4a\x67\x19\x89\xce\xa4\xf6\x84\x6b\xc1\x91\x79\x09\x7c\xca\x40\xc6\x24\xd7\xed\xbf\x91\xfb\x5b\x25\x39\xeb\xbd\x50\x2d\x36\x46\x71\x14\x30\xba\xe4\x23\xfd\x11\x58\x48\x09\x33\x18\xb7\xd0\x87\xef\x1e\x3b\x89\x4b\xc3\xb9\xea\x27\xaf\x85\x3f\xca\x85\x95\xd3\x6f\xb7\x29\x99\x69\x16\x2f\x2e\xd6\xa2\xb5\x50\x75\xb2\xc6\x30\x80\x28\x57\x17\x6d\xec\x4c\xb5\xac\xf2\xb1\x3a\x35\xa9\x94\x9b\x91\x2b\xb5\x7d\x81\xeb\x0c\x8a\x8a\xdf\x3c\xf6\x4c\xb5\x71\xbf\x5f\x3d\x71\xf9\x87\xd6\x4d\x74\xe9\x19\xa0\x03\x36\xe5\x7d\x35\xee\x4e\xec\xfc\x65\x70\x00\xdd\x5b\x12\x99\x5e\xe1\xb1\x16\x59\x1c\xe5\x8e\x56\xde\x25\xb2\x9c\x94\x82\x9d\x1d\x68\x52\x1b\x95\x58\xe4\x72\x5e\xc7\x70\x39\x06\x9c\x0c\xd1\x7b\x2a\x00\x33\x59\xe9\xe1\xe1\x12\xc7\x59\x01\x76\xce\xbc\xe7\xf0\x01\xf1\xd1\x36\xe8\x18\xf4\x81\x8c\xfd\x94\x74\x5a\xfa\xab\x56\xf1\xa4\x06\xf9\x7d\xd9\xe6\x1b\x73\x52\x66\xd6\x82\xad\x7d\xf2\x6d\xd7\x0c\xde\x0b\x57\xfe\xa7\xdb\x2d\xf8\x32\xfa\x88\xa3\x5f\x53\x97\x94\x88\x4d\xdc\x41\x21\x84\x03\x01\x6c\xb6\xd5\x22\x1f\x3f\xeb\x5d\x3a\xee\x4a\x98\x40\xa9\x13\x07\x2d\x29\xf8\xd1\xa9\x36\x7b\xb0\xbb\xf5\x45\xf7\xda\xe7\xc0\x0a\x0d\x0c\x03\x42\x23\x1a\xe4\x62\xbb\x74\x2e\x14\x98\xee\x58\x4a\xe6\xc8\x3f\x2f\x1f\x2d\x04\x52\xbe\xad\x98\x22\x68\xcd\x3c\xfd\xe7\x8f\xf4\x22\xe2\x26\xbf\x7b\x2a\xf1\x13\x77\x57\x79\x7f\xb0\x2e\x52\x75\xc3\x48\x09\xd5\x4c\xa9\xee\x2a\x65\x27\x5e\x6e\x5c\xff\xdd\x20\xad\x1f\xa1\xee\x0b\xd8\xb2\x1e\x04\xce\x82\x9e\x02\xcd\xb6\x3c\x48\xbf\xcd\xd8\x6d\x3a\x08\xc5\x97\x89\xc9\xd7\x8e\x36\x18\x1d\xef\xeb\x72\x27\x10\x72\x75\xed\x6b\x5c\xcb\x12\x7c\xd7\x2b\x37\x4e\x17\xf5\xee\x0b\x5e\x47\xb4\xb3\xe1\x4a\x8e\xc6\xd8\x6b\xb7\x50\x71\x87\xf2\x8d\xb3\x2b\x3f\x3f\xa1\xca\x13\x44\x6f\xe5\x25\x3e\xe7\x83\x64\x5e\x79\x42\x72\x79\x9a\x86\x3b\x4f\xca\x99\xe4\x43\xcb\xaa\x05\xde\x3c\x50\xed\xf3\xd5\xcd\x7c\x10\x52\x9c\x6c\x09\xa0\xc1\x45\x34\x06\xac\x7e\xca\xfa\x9b\x3a\x1f\x36\x9d\x68\xf3\xc6\x18\xf5\x8e\xfc\x35\x9d\xf2\xf3\xfc\xd2\x47\x8b\x55\xa4\x1a\x11\xf2\x48\x7e\x7f\x70\xec\x29\x3b\x3e\xcc\xc7\x00\xef\x44\x4a\x33\xd1\xea\xe9\x84\x9c\x5b\x76\xd2\x9a\xfd\x5a\x23\x86\x1a\xef\x4f\x2a\x7b\xa3\xf6\x66\x30\x1f\xde\xb5\xd3\xd8\xf0\xdc\x9e\xe2\xe0\x14\xb2\x4c\x74\x65\xde\xe3\xc0\x96\x4e\xdd\x49\xed\x49\xed\xab\xb5\xca\x7a\xfb\x99\x57\x4d\x00\x1e\x58\x12\xa0\x85\x23\x1f\x24\x1b\x6b\x08\xc7\x3e\x80\xfb\x44\xbb\x2a\xdf\x55\x4f\x14\xfd\x6d\xce\x94\xa6\xf6\x36\x23\xd9\xc1\xde\xb4\x1a\xd1\x01\x65\x1a\x6b\x67\xae\x52\x34\xda\xae\x81\x97\x9f\xbd\x82\x33\x89\x64\x9a\x3b\x0a\x06\xc6\x8b\x80\x46\x8a\x99\x1d\x30\x07\x74\x87\x51\xfa\x69\x28\x1d\xb1\xb9\x4d\x6c\x16\x0a\x1c\xab\x50\x94\x3c\xdb\xb8\xde\xa5\x75\x09\x06\xb3\xc6\x59\x5b\xb5\x80\xde\xdb\xfa\xe5\x74\x64\xcc\x7a\x65\x1d\x4c\x51\xdb\xb5\xfa\x98\x05\x97\xd1\x76\x69"}, +{{0x49,0xc2,0x98,0xa2,0xdb,0x3d,0x25,0x89,0xc9,0xfe,0x16,0xa4,0xe5,0x71,0xe5,0xaa,0x23,0xcb,0xaa,0x77,0x7b,0x86,0x47,0x02,0x90,0xa3,0xed,0xa7,0xa5,0xd3,0xe9,0x6b,},{0xda,0xc5,0x23,0xd6,0x37,0x4c,0x8f,0xf1,0x5f,0xc4,0xdd,0xc7,0x13,0x71,0x5a,0xc3,0x5c,0xf5,0x54,0x7f,0xc1,0xb1,0xb2,0x64,0x6b,0x63,0xfb,0x41,0xa7,0xf2,0x16,0x21,},{0x2a,0x43,0x9c,0x73,0xc9,0x81,0x17,0xfb,0x29,0x52,0xe2,0xb1,0x61,0xf7,0xf3,0xb9,0x9e,0x7d,0x39,0xbc,0x69,0x7f,0x79,0x40,0x75,0xdb,0x7b,0x63,0x4d,0x29,0xf1,0xff,0x57,0x24,0xf6,0x77,0xf8,0x31,0x2a,0xd5,0x15,0xb0,0x97,0xcc,0xa9,0xdf,0xc3,0x0e,0x79,0xee,0x8a,0x7c,0x9d,0xd7,0x28,0xbd,0xd4,0x5d,0xf8,0x59,0xc7,0xbd,0xe3,0x0a,},"\x35\x82\xee\xb0\xd3\x71\xdf\x38\x5d\xe8\x8b\xaa\xd3\x80\xcb\x0c\xdb\x60\xea\xb2\xba\xeb\xb3\xc7\x98\x37\x75\x3d\x08\xe1\xcb\x78\xc0\xbd\x76\xdd\x11\x04\x45\x49\x56\xd5\x71\xce\xb7\xe6\xb5\x71\xa5\x23\x68\x35\xd7\x84\xb5\x0f\xf6\x60\x57\xb1\x35\x95\xe7\xd0\xc8\xf2\x5d\x08\xae\x8b\x54\xb6\x12\x3b\xa0\x81\x51\xac\x7d\xb0\xc5\x6a\x98\x0f\x7f\x0b\xb3\x9a\x54\xb4\x37\xf5\x48\x51\x97\x99\x86\xab\x13\x67\x83\x5e\x5c\x4f\x3a\x3b\x3d\x76\x0d\x38\x27\xe7\x6c\x56\x8a\xe7\xae\xbb\xb6\x12\xe7\x75\xbd\xde\xcc\xd3\x34\xac\x6b\xcd\x32\x53\xab\xc2\x9d\x4b\x7c\x3f\x10\x36\x26\x66\xf6\xae\x75\x08\x03\x70\xa3\x6c\xba\x55\xdb\x3a\x91\xcb\x57\x89\xe4\xd6\xf9\xef\xea\x4d\xf1\xdd\x77\x30\xa5\xe2\x79\x60\xd5\x3b\x51\x21\x94\x8c\xce\x5a\xf6\x53\xff\xf1\xd5\xb4\xe5\xb0\xa8\x8c\x71\x8c\x49\xb3\x1c\x79\x3d\x88\xc1\xcc\x45\xab\x8d\xa2\x9d\x05\xe9\x06\xcd\x05\x94\xb5\xf6\x63\x8c\x8e\xc3\xf1\x76\x0b\xa4\x23\xb5\xab\x1d\x08\xa5\x87\x70\xaf\xb0\xf1\x39\xab\xd3\x49\xc1\xbf\x16\x0d\x89\x02\x23\x9c\xe2\x4f\x19\xb4\xe1\xbe\x09\x5f\x7e\xd1\x65\xf3\x93\x1e\x3c\xbc\xc3\x07\xe9\xfc\x5c\x65\x80\x31\x22\x8e\x55\xcb\xbe\xec\x0d\x0b\xcf\x8f\x69\x51\x54\xa9\xee\xd1\xbe\xf3\x52\x28\x78\x9b\xfc\x0d\x23\x8b\x83\x72\xd3\x18\x32\x8c\x13\x39\xfe\xa0\x88\x14\xdb\x86\x21\xab\xca\x3a\xeb\x82\x09\x8b\x5a\xa8\x7b\xb9\x8f\x5e\x40\x52\x2a\x08\x88\x53\x2c\x17\x48\x45\x3d\xb2\xd2\xb3\x94\x3e\x4a\xbb\x31\x2d\xe3\x19\xae\xc4\x8c\xc1\xc9\x47\x75\x97\x29\x53\xfb\x64\x96\xb8\x16\x89\x37\x62\x35\x10\xcd\x48\xc8\xb2\x47\x95\x6d\x31\x68\x48\x6c\x17\x6a\xe7\xa4\xcb\x38\x4e\xac\xfd\xab\xfa\xdd\x9f\xba\x30\xa2\x3b\x81\x1b\xd7\x79\xf3\xcb\xa5\x43\x38\xc2\x8b\xb3\x38\x22\x38\xed\x3b\x8d\xd2\x1b\xea\xb2\xf5\xca\xde\x28\xc5\xe0\x9b\x31\xa4\x54\x80\x8a\x53\x48\x12\x2e\x3a\xe3\x81\x22\x96\xf7\x86\x9c\x38\x65\xc3\xc9\xd8\xfe\x18\xbd\x81\x2f\x2e\x60\xe9\x14\x97\x5c\xfe\x1b\xef\x8d\xbb\x80\x97\x00\x6f\x0d\x7c\xf3\xfc\x15\xeb\x95\xc2\x78\x54\xb1\x43\x12\xb8\x8d\x52\x80\x15\xaf\x69\xfb\x75\x05\xb8\xf3\x27\x03\xf6\x4e\xb1\xc9\x58\xf0\x46\xdd\x25\x12\x42\xf8\xbe\xa7\x46\x7f\xc7\x29\x1d\x09\x5e\x96\x96\xe1\x1a\xa4\x5a\xbe\x79\x24\xe8\x56\x35\x15\x35\xaa\x07\x73\xd3\xd9\xe6\x1c\xc9\xa2\xd8\x9b\x5b\x07\x74\xd7\x64\x5e\xe1\xaf\x7e\xb6\xfc\xd4\x40\xbc\x69\xd4\x3e\xde\xaa\xf9\x35\xfd\x2a\x52\x95\xac\x19\xa9\x7d\x70\xaf\x92\x98\x83\x0f\x81\xc0\xa5\x09\xf2\x42\xf4\x73\x37\x24\x78\xfa\x58\x79\xfb\x2c\xb8\x51\x10\x80\xfc\x2e\xcd\x82\x59\xb8\xc3\xce\x9e\x8b\x64\x07\x61\xdc\x79\x27\xc3\x2e\x7f\x5b\xae\x97\xa8\xb8\xac\x93\x56\x62\xe5\xf4\x5d\x14\xca\xd6\xd3\x4a\xff\xc9\xa1\x94\x14\xc4\x56\x6f\x45\xf9\x77\x39\x67\x10\x89\x4c\x53\x99\xed\x44\x80\xf1\x8e\x90\x95\x7f\xaa\x76\xcc\xb5\x12\xa2\xd0\x75\x73\x05\x8a\x95\xb4\x2f\xe1\x81\x02\x49\xd1\xc8\x5e\xc4\x31\xa0\x49\xd1\xae\xcb\x0f\x11\x83\x79\xbd\xc3\xf1\xee\x49\x0b\xc8\xa0\x54\xc3\x2c\x3d\xac\x76\x59\x96\x6c\xdb\x66\xf9\x95\xac\x40\x3d\x5e\x79\xeb\x6b\x25\xb3\xf3\xf6\x5a\x6c\xee\xc2\x20\xd6\x6c\x05\xf8\xa8\xa9\x8b\x80\x79\x9b\xa4\xf2\xc6\xdb\xbb\x4d\xfb\x58\x62\xc9\xa4\x6b\xca\x01\x3e\xbd\xfa\xba\x74\x94\xa3\x0c\xe1\x46\x06\xaf\xc0\xb0\xf9\x93\x14\x3f\xed\xee\x78\x96\xd9\xa6\xbb\x81\x49\x91\x66\xed\x02\xe9\x41\x86\xaa\xf3\x21\x87\xae\xb6\xe2\x82\x50\x1b\xca\x43\xb5\x7b\x7e\xfa\x09\x39\xc9\x34\xbc\x8f\xbb\xd2\x6c\x44\xb6\x18\x33\x5a\x35\xc6\x92\xff\x99\x6a\x5b\x95\xd3\x27\xdf\x9b\x2a\x66\x21\xb3\xb0\xf1\x90\xdb\x1f\x36\xd9\x11\xd1\xa6\x63\xa4\xeb\xf9\xa2\x85\x4b\xb4\xf4\x06\x10\x95\xb6\x98\x12\xc8\x2c\x2f\xfe\x3f\x92\xe9\xb4\x4d\x2e\xa6\x31\x69\x88\x1c\xae\x84\x53\xd6\xee\xf7\xcf\x69\xc2\x5a\x28\xb3\xf8\xdd\xc7\x01\x48\xef\x26\x72\x1a\x3c\x1f\x2e\x62\xd9\xd1\x0c\xea\x42\xfc\xa3\xfa\xcd\x74\x67\x3a\x4e\x7f\x33\x50\x73\x64\xaa\x28\x6c\x0f\x38\xd7"}, +{{0x82,0x3f,0x0c,0x29,0xfb,0xfd,0xd3,0xd1,0x82,0x8f,0x30,0x55,0xe9,0xec,0x01,0xff,0xd1,0xb5,0xa3,0x75,0x11,0x8d,0xdd,0x7e,0x4e,0x0c,0x43,0x71,0x9f,0x57,0x3f,0xf7,},{0x73,0x12,0x5f,0xc8,0x3a,0xbb,0x8b,0x7c,0x65,0x85,0x59,0xfc,0x12,0x73,0x93,0x23,0x1d,0x03,0xca,0x58,0x46,0xe0,0xc8,0x81,0x18,0xd1,0x3d,0x55,0xca,0x44,0x78,0x9d,},{0xfa,0x74,0x7b,0x6f,0xe3,0x38,0x1a,0xd6,0xbc,0x82,0xa9,0x56,0x43,0xc1,0xf4,0xa2,0x0b,0x76,0xba,0x73,0xbf,0xf0,0x0e,0x63,0x5d,0x64,0x20,0x2d,0x8b,0x0d,0xf0,0x3d,0xbc,0x56,0xb0,0x13,0x8b,0x3a,0x6d,0x41,0x98,0xff,0xaf,0x58,0xcc,0xd3,0xd3,0x88,0xed,0x25,0xeb,0xcf,0x77,0x04,0x43,0xe4,0x1e,0x9d,0x21,0x47,0x95,0x0a,0x30,0x0b,},"\x80\x2c\x39\xce\x7f\x2a\x50\xbd\x81\x62\x2a\xdd\x0d\xf4\xe0\xfe\x03\xec\x3d\x2d\x30\x5a\x45\xa6\x16\x52\x71\xed\x79\xad\xd2\x43\xb9\xa0\x0e\x52\x18\x31\x92\xfe\xb2\x4c\x4f\xdb\xd2\x2c\x80\x7a\xe1\x00\xef\xcf\x16\x5b\x9c\x99\x61\x94\xe0\x0f\xa8\x17\x76\x5e\xa9\x4a\x03\x07\x0e\x48\x66\x86\xb4\x45\xfc\xb2\x63\xcc\xfe\x1f\x58\x62\xf3\xb8\x4b\x10\xf3\x90\x08\x0b\xfc\xae\x44\x7a\xe0\x06\x97\x42\xb8\x61\x8f\xa9\x57\x5f\x7e\x63\x7a\xd5\x4e\x83\x4c\xaf\x03\x94\xd7\x45\x03\x2c\xe1\xe2\x55\xc0\x27\x32\x50\xf1\x50\x4b\x37\xa0\xad\xd9\x4a\xa2\x45\xc7\xde\x52\xc8\x0e\x05\xd6\xe0\xa9\x6a\x14\x41\x05\x43\x82\x6a\x49\xe9\xb9\x45\x62\x6d\x4e\x89\xf5\x50\x27\x16\x3d\x4b\xd6\xd0\xe9\xbd\x1a\x24\x77\xf6\x7d\x3d\x56\x68\xa4\x2e\x94\xd8\xb6\x11\x93\xd8\x21\xe0\xd1\xb2\x30\xfc\xad\xc5\x36\x13\xb7\x5b\x02\xcf\xb8\x15\x84\x56\x07\x7e\xbd\xf5\xa5\xf0\x0c\x3b\x5b\x18\x63\x70\xca\xfe\xc4\xa2\x1c\x69\xdc\xe1\xf0\x1e\xfe\xf2\x3c\x37\xab\x90\xf8\x58\x23\x8a\xef\xbe\x21\x2b\x55\x6d\x2f\x07\x34\x06\x55\x9f\x1a\x51\xd8\x4e\xff\xfd\xce\x07\xb0\x0d\x01\xbb\xf3\x37\x71\xcc\x12\xc9\x60\xac\x89\x36\x5a\x9c\x82\xc5\x23\x43\xf7\x60\x33\x81\xb8\x90\x23\xc1\xa6\xe7\x02\xa5\xb1\xe4\xbd\x19\x1e\xa6\x97\x0b\x5e\xa4\x51\xea\x05\xb5\x9b\xf8\x3e\x55\xf2\x9a\x1f\x80\x32\x12\xbb\x2e\x58\xf0\x61\x63\x33\xd9\x11\x47\x08\x52\x9e\x8b\x6c\x60\x81\xde\xeb\x7c\x29\x9a\x5a\x2a\x53\xcc\xd2\x4e\xd5\x8f\xfb\xfe\x50\x3d\x80\x61\x4a\xdb\x05\xca\x11\xcf\x29\xde\xd0\x09\x04\xea\x12\x39\xf8\x2b\xa4\x0c\x79\x3e\xbc\x33\x97\x75\xf8\xb0\xfe\x39\x01\xf5\x48\x2e\x31\x0c\x79\x3c\x6e\x2c\xf0\x1d\xc1\x57\x72\x7a\xf2\x38\xf4\x9c\x98\x62\x80\x4b\x04\x75\x51\xfd\x88\x6f\x4a\x48\x99\xe2\x2a\x6a\x65\x70\x11\x17\xa3\x85\x80\x55\xbb\xfe\x96\x6e\x37\x0e\x73\x3e\x17\xef\xad\xa2\x85\x9f\xd8\xff\xa9\xe0\x1f\xce\x56\x06\xa2\x55\x36\x76\x78\xf4\xbd\x4e\x21\xe5\xda\x0f\xef\x30\x75\x7f\x34\xe3\x89\xf7\x6b\x7d\x57\xc4\xe4\x10\xa0\x02\xe9\x00\xe4\x8f\xb2\x18\xc8\xf2\x77\x8f\x14\x8f\xee\x56\x96\x5f\x5b\x47\x3e\x25\x25\x6c\x23\xa7\xaf\x19\x83\x42\xcf\x3e\xf0\x2b\x84\xdf\x2c\xd5\x80\x0a\x46\x1c\x1b\x07\xbd\xa2\xf4\x26\x28\xa6\x8a\xd2\x9d\xbb\x82\xa4\x70\x96\x7d\x73\x02\xc9\x93\xb2\x34\x13\x6e\x5b\xf2\x55\xe6\x24\x8b\x10\x2c\x2b\xff\xb2\x01\x72\x37\x1f\x1c\xa3\xe1\x0b\x08\x10\xe8\x64\x95\x03\x54\x6d\x9a\x73\x1c\xf1\x9b\x08\x33\x57\xd4\xcf\xec\xc8\x9b\xed\xb5\x35\x06\xfe\x19\x9b\x67\x03\x91\xa6\x20\x06\x9a\x30\x81\xf2\x53\xb4\xd7\x90\x88\x0a\xa2\x3b\x53\xe9\x7c\x75\xdc\x0c\x36\x05\x40\xe5\xb0\xa3\xef\xb1\xac\xcf\xfd\x13\x74\x14\xff\x84\x23\xd5\x46\x46\xfc\x56\xba\x5f\x53\xbd\x84\xc7\x26\x7c\x2f\x7e\xe3\xe3\x76\x07\x54\x41\x54\x36\x5f\x9f\x85\x08\x1d\xd7\xd2\xee\x75\xd3\x02\x27\x5c\x79\x9e\xf2\x42\x7c\xa6\x49\x63\x55\xdc\xda\x1d\x44\xe0\xd9\x77\xbf\x68\xdb\x30\x06\x50\x0a\xe3\xf4\x00\xd6\xa8\xc7\xcf\x47\x05\x7d\x4f\xc8\x7e\xee\xcb\x02\x11\x6b\x73\xee\xd6\xce\x1f\xcc\xef\x6e\x8f\xb8\xae\xa3\x63\xb2\xf6\xf5\x32\x2a\x5f\x07\x53\xf4\x58\x99\x53\x76\x46\xd5\x86\x51\xbe\x90\x37\xbf\x91\x42\x3c\x29\x86\xf5\xcc\x2b\xcb\xce\x4f\xae\xc9\x03\x49\x8b\x40\xfc\x2d\xea\xb6\x60\x3d\x6e\xea\x58\x5d\x27\x20\xd2\x1b\xb2\x72\x2b\xc0\x5b\x35\xae\xd2\xbc\xc0\xe8\x04\xfe\x9d\x23\x9f\xaf\xda\x7d\xda\xfe\x1d\x78\x60\xab\xb0\xfb\x28\xf4\xbf\x2b\x1f\xbb\x62\xa7\x86\xe4\x55\xbe\x02\x4b\x19\x3b\x78\x30\xbe\x0d\x55\x8f\x02\xc9\xf3\xae\x31\xdc\x10\x7e\xe9\x42\x1d\xc5\xf0\xb0\xf8\x94\x02\xb7\x1a\x45\x81\x40\x15\x36\xbc\x47\x30\x85\x06\xd9\x69\x39\xa2\x06\x36\x27\x44\xe2\x7d\xde\x94\x4f\x40\x96\xa1\x2b\x5f\x63\xda\xb6\x4d\x04\x14\x84\xd3\xfd\x91\xa6\x2c\x2f\x0e\xf9\xae\x78\x74\x22\xeb\x27\xfe\xd0\x80\x2e\x25\xf9\xbc\x77\x5c\x49\x15\xa8\x37\xfe\x3e\xb7\xb9\xd5\x84\x3e\x4d\x82\x10\xc6\xb4\x94\xb6\x12\x81\x63\x7a\x6b\xe3\x20\x52"}, +{{0x65,0x67,0x66,0x33,0x37,0x42,0x14,0xc4,0xac,0x4b,0x7b,0xce,0xa9,0xf1,0xcc,0x84,0xb1,0xb7,0xe7,0x94,0x11,0xe3,0x10,0x52,0x5a,0xce,0x38,0x5f,0x45,0x66,0xc1,0xd5,},{0x0e,0x6e,0xc5,0x80,0x1d,0x8b,0xd6,0xb1,0xeb,0x42,0x14,0x21,0xa1,0x40,0x8f,0x13,0x4c,0xf7,0x12,0x33,0x8e,0x0f,0xfc,0x24,0xcd,0xcc,0xdc,0x4f,0x7f,0xa3,0x1d,0xbe,},{0xe0,0xb8,0x67,0xc9,0xdb,0xda,0x35,0x32,0x34,0x33,0xc0,0x46,0xe0,0x83,0x0c,0x25,0x1b,0x43,0x46,0xc5,0x39,0x59,0x72,0x28,0x6b,0x3a,0x72,0x31,0x0e,0xd4,0x52,0x6e,0x54,0x5d,0xc0,0x9d,0x39,0x18,0xf2,0xeb,0x99,0x20,0xbc,0x9b,0x24,0x1e,0x90,0x50,0xd8,0x48,0xd3,0x83,0x02,0x88,0x65,0x15,0x91,0xf9,0x36,0xd3,0xba,0xe4,0x53,0x01,},"\x9d\x62\x2c\x20\x67\x87\x69\x40\x93\xc6\xf2\x9f\x93\x61\x9f\x21\xbb\x64\xc0\x39\x41\x6d\x20\xdc\x70\x8a\x08\x4a\x9d\x2e\x49\x0c\xf5\x65\x8e\x13\xd6\x2c\xb0\xd2\x1e\xab\x00\xe4\x2d\x85\x1b\xc6\xec\x75\xda\xf4\x05\xd2\x37\x32\x46\xee\xa4\x15\xe8\x66\x29\x1b\xab\xf7\x64\x97\x68\x0a\xaf\x04\x42\x5a\x42\x55\x2b\x10\x7d\x58\xcd\x18\x56\x1c\x8c\x94\x83\xf7\x40\x74\x4c\xbf\xa6\x05\x4c\x1b\x12\x6f\x5a\x76\x65\x9a\xc1\x9d\xdd\xad\x4a\xb5\xa0\x91\x55\xd8\xc0\x50\xb5\x35\x4e\x06\xa4\xdd\x3e\xe3\xa6\xf9\xc9\x1e\x8b\x4c\x7a\xf2\x74\x96\x64\xe7\xab\xe9\x70\x61\x58\x9e\x15\x3c\x58\xe2\x7c\xf2\x99\xa2\x5f\x2b\x53\x0c\x06\x07\x31\xec\x0f\x43\x66\xbd\x1d\xeb\xeb\x4d\x4e\x91\x2e\x76\xe5\x08\x53\x4d\x43\x3e\xc4\x8f\x96\xb6\x2e\x15\x0d\xe9\x39\x63\xa1\xb3\xe6\xc8\x09\x1b\x49\x5a\x96\x51\x8c\xe3\xd3\xb9\xa8\xdb\xdc\x2a\x13\xfd\xd0\x77\xf2\x23\x1d\xe8\xd7\x6f\x56\xd9\xab\x1c\x2f\x9e\xfa\xbc\xe4\x63\x83\x64\xf8\xfb\x2a\x2c\x68\x3c\xa8\x19\xb7\x03\xab\x45\x3b\x11\xd3\x7a\x69\xfa\x4b\xcb\x80\x23\x98\x08\x34\xf7\xb9\x02\xad\x18\x19\xfc\x02\x92\x12\xfd\xea\x0a\xbf\x11\xde\xc8\x8c\x55\xd6\x8e\xf8\x7a\x26\xdb\xb1\x5d\xc3\xd3\xdf\xbc\xdd\xdd\x5e\xd7\x1b\xe8\x6f\x32\xc7\x6e\xe2\x22\x1d\x92\x43\x68\x3d\xf9\x51\x65\x64\xb2\x6b\xab\x5c\x84\x5d\x4d\xfe\x0a\xdc\xc7\xcb\x9f\xe1\xee\x2c\x05\x1a\xf5\x90\x8c\xe0\xcc\x3a\x90\x90\x4d\xbc\x0d\x36\x80\xed\x49\x92\xf4\x6c\xe2\x5c\x2e\xe8\x51\xc4\x14\xf0\x18\x7d\x89\x3e\x5c\x3b\x01\x89\xa7\xbb\x68\x93\xd6\x83\xf5\xe3\x39\x4c\xc0\x46\x29\x9a\x16\xa1\xc1\xb5\x69\x59\x33\xa8\x9b\xb1\x30\x30\x85\x5b\x81\xb3\xc7\x46\x85\xf7\x19\xde\x01\x60\x57\x5a\x0f\xf0\xa9\x1f\xd9\x43\x47\xb8\xbc\xbe\x12\x5d\x1d\x3f\x9c\xe7\x72\xa8\x12\x6e\x00\xf5\x63\xb3\x18\x96\x56\xd5\x52\x2c\x18\x7a\xb8\x31\xa7\xad\xe7\xac\x06\xfd\xca\xc7\xf1\xd4\x58\x82\xe5\x1f\x9b\xf5\xb4\x4a\x2d\xab\xa4\xa5\x3d\xbb\x31\x97\x0b\x4a\x0f\x12\x72\xfe\x14\x08\x7e\x0c\x3c\x7e\x45\x42\x31\x2f\xe7\x4d\x76\x7f\x21\xe7\xea\x48\x7d\x52\x84\x28\x4f\x46\xf2\x0f\x32\xc5\xb1\x6e\x1e\x0a\xc8\xd7\x96\xab\x2f\x80\xb3\x44\xe7\xa8\xd8\x4d\x5d\xe8\x23\xa5\x08\x97\x75\x2d\xc5\x49\xa4\x8f\xc1\x0b\xcd\x43\x6a\x7a\x93\xe9\x7c\xd0\x5d\x78\x30\x13\x8f\x32\x38\x79\x68\x0c\x34\x3c\x16\x46\x7d\x26\x4d\x74\x9b\xf4\x5e\x40\xf3\x9f\xbc\x3a\x00\xc4\x3b\x00\x69\x3b\x01\x56\x76\x8f\xf2\xe3\xf8\xad\x9e\xb6\x40\x50\x22\xf5\xca\xda\x66\x94\xe8\xa3\x3c\xdc\x59\xc6\x67\x3c\x44\x11\x72\x44\xeb\x03\xfd\x7f\xd6\x75\x93\x0c\x29\x4e\xdd\x29\x40\xf5\xf1\x80\x95\x3d\x91\x0c\x55\x48\x5b\x20\x57\xae\x0c\x93\x02\xf4\xa8\xe8\x31\xa5\x53\x0e\x3c\xbb\xf6\xf4\x72\x22\x40\x83\xa9\x52\xa8\x39\x0a\xb0\x0d\xc0\xf6\x9d\xfd\x88\x0e\xea\x2d\x73\x9d\x21\x8d\x6a\x66\xf2\x37\xf1\x0d\x44\x01\xaa\x75\x8f\xf8\x12\x0c\x0a\xe2\x76\x61\x27\x84\x90\x24\xf5\xa4\xcc\x57\x4a\x5b\x02\xb9\x35\x96\x68\x12\xcd\x1f\xb6\xd7\x9d\x0c\x4f\x59\xff\x80\xf0\x35\xa0\xb1\x09\xcc\xcb\x22\xfb\x08\x53\x5b\x87\x41\x49\xed\xf2\xa0\x97\x0c\x14\x88\x84\x27\xd0\x7d\x1e\xaf\xa6\x84\xa6\xd3\x45\x4e\x49\xb2\x25\x18\x4c\x6b\x99\x3e\xc8\xdd\xb8\xb5\xa3\x5e\xe4\x5f\x87\xf6\x92\x66\xd4\x90\x96\xa3\x17\xd8\x6a\xde\x27\xf4\x52\x9f\xe7\x23\x64\xd0\xb9\x58\x00\x72\x99\xd9\xde\x87\xd6\xff\x9f\xb0\x4d\x57\x3a\xea\x46\xba\xc8\xeb\x76\x47\x52\xeb\x46\x5c\xaa\xab\xa6\x89\xa6\x46\x0c\x11\x07\x30\xbd\xd0\x8b\x16\x89\xde\x7b\x05\xde\x59\xaf\x9f\xe2\x44\xac\x36\x3e\x95\xc9\x8b\x66\x93\x59\xaf\x90\x31\xa3\xa9\x3b\xa6\x31\xab\xf1\xf6\x1d\x20\xef\x7f\xc6\x88\x3b\x48\x40\xfc\x92\x67\x12\xe1\x3d\x87\x4b\x72\x2f\x6a\x79\xb1\x60\x70\xc0\x31\x13\x25\xe9\xa7\x0f\xcd\x86\x91\x6c\xfa\x1d\xa7\xf9\xd0\x56\x3a\x22\xfe\x9b\xfe\x85\x4b\x0c\x18\x6c\x86\x63\xb0\x61\xb6\x5b\xc0\x71\xe8\x39\x93\x8d\x8f\xdd\x7c\xf8\xf6\x95\x2a\x64\x67\xfa\xd8\xe5\x84\x90\xed\x2b\x26\x81\x33\x01"}, +{{0xd2,0xed,0xed,0xcd,0x85,0x32,0x06,0xcb,0xf5,0x9b,0xd7,0x4a,0x25,0xa3,0x03,0xfa,0x2d,0x6c,0x39,0x36,0xbb,0x48,0xeb,0x42,0xf6,0xd9,0x00,0xcb,0xe8,0x07,0x72,0xbe,},{0x22,0x44,0x11,0x1e,0x2e,0x76,0x9e,0xab,0x81,0x87,0x1e,0x06,0xc5,0x80,0x17,0x8c,0x23,0x5c,0x7b,0xf4,0xa5,0x2d,0x2e,0xcc,0xe1,0x18,0x87,0xa9,0xb4,0x6c,0x45,0xc8,},{0xbe,0x3c,0x2b,0x56,0x7f,0xe8,0xc2,0x08,0xc9,0x8e,0x71,0x97,0x11,0x7e,0xb0,0x1b,0x3c,0x19,0x7b,0xdf,0xc8,0x58,0x56,0x2d,0xc5,0xcd,0x90,0xf8,0xe2,0xc0,0x35,0x70,0x42,0x30,0x39,0x95,0xba,0xba,0x2f,0x40,0xb7,0x34,0x5c,0x56,0xdb,0x0b,0x46,0x25,0x58,0x0a,0xa8,0xdc,0xc4,0x8d,0xf6,0x01,0x9d,0x23,0xa8,0x38,0xea,0x71,0x72,0x02,},"\x80\x70\xbc\x0d\xb0\x89\xa5\x92\x54\x46\x01\x9b\x7e\x40\x3c\x74\xec\x78\x90\x3e\x4b\xd5\x4b\xc1\xd0\x8a\x54\xa6\xf0\xed\x75\xa8\x5b\x76\x3f\xf5\x4d\xc3\x3a\x26\x00\xcc\xb4\x57\xfd\xba\xea\xe5\x48\x47\x7f\x6d\x69\x47\xae\x26\xde\xb7\x1e\xac\xd1\xd2\xd6\x22\x82\xa0\x83\x84\x3b\xe4\xe5\x93\x1d\x91\xc9\x3b\x62\x82\xc5\x88\x07\xce\x8f\x0d\x88\x0b\x14\x38\xda\xd8\xfd\xcb\xa8\x61\x2d\xf7\x3b\x9f\xaf\xf3\xa9\xf7\xdb\x30\x05\x25\x05\x36\xaa\xbd\x98\xae\x02\x7a\x89\x5e\x10\xb5\xcb\x7b\x69\x87\x5c\x0f\x39\x93\xaf\x24\x51\x92\xf4\x39\x3e\x9c\x4d\x34\x05\x74\x6e\x31\x1d\x3a\x91\x44\x7f\xcd\xbd\x73\x06\xb6\x02\x0c\x93\x3b\xba\xb9\xe3\x9d\x13\x49\x16\x25\x03\x5c\x9c\x63\x6e\xfa\x17\x39\xc3\x58\x87\x10\xa8\x79\xd9\xe3\xce\x17\x64\x61\x6f\x10\x82\xe8\xdf\xf5\x75\x59\xc3\xf5\xa5\xd7\x6d\xd3\x01\x12\x4f\xa4\x89\xfb\x94\x9e\x9e\x03\x9d\xd4\x62\x1b\xda\x60\xf0\xb8\x6b\x31\x1e\x78\xed\x0a\xb3\xb5\x28\x96\x50\x44\xb2\x3d\x78\xee\x2f\x81\x06\x1f\x8e\xdb\xd6\x92\x99\x33\xd1\x8c\x02\x07\xde\xc4\xb5\xb6\xb2\xfa\x4a\xca\x27\x47\xcf\x5b\x11\x0d\xf0\x0b\x0c\x98\x27\xbd\xb3\xd9\xdb\x2c\x7b\x03\x28\xd4\x0d\x99\xe1\xf6\xb2\x28\xe4\x0d\xad\xae\x78\xae\xda\x02\x89\xb6\xa2\x3d\x4e\xb5\x83\x70\x88\xe5\xd8\x84\x13\x63\x2c\xcc\x22\xe2\x1a\x73\x76\x8c\x67\x32\x01\xe9\xa8\xd8\xdc\x6e\xb6\xf7\x39\x7f\xed\xbd\x39\x8d\x26\xf9\x69\x2c\xa7\x2f\x6d\x6c\xf0\x56\xaa\xac\x50\xac\x2f\x3b\x26\x6d\xbe\x5e\x7b\xe7\xa0\x24\x77\x45\x78\xea\xd5\x85\x24\x5d\xaa\xa7\x3e\x0a\xaf\x83\x3c\x07\x0b\xa4\xb2\x04\x4c\xcb\x5e\x5c\xd1\x6f\x9c\x0a\xd9\x2e\xa8\x44\x80\x55\xdd\x82\x8c\x79\x93\x5a\xa6\xc0\x74\x1f\x9e\x2b\x81\x03\x24\xfd\xc6\xe6\x1e\x84\x2f\x94\x57\x22\x68\xbf\x7d\x5a\xdf\xa7\xab\x35\xb0\x7f\xb1\x9e\x78\x15\xa8\xaa\x5d\x81\x13\x01\x30\xac\x5c\xda\x8a\x47\x51\xee\x76\x03\x8c\x0a\x6b\xc2\xfa\xba\x4c\x49\x7e\x62\xb9\xf1\xf1\x94\xb8\xa5\x99\xb0\x77\x01\x81\x4b\x6d\xfb\x7d\x84\xbc\xdd\x5b\x7b\x5b\xc2\x24\x9f\x1d\x38\x45\xef\xf9\xef\x8c\xc7\x32\x85\x35\xd7\x0d\x53\xc7\xaa\x0c\x73\x05\x90\x1d\xe7\xc4\xed\x2f\xe1\x83\x82\x65\xd4\xa4\x17\xb8\x76\xad\xbd\x88\xeb\x93\x3f\x27\xc9\xaa\x48\xc8\xc7\xe3\x4e\x48\x14\x7c\xcf\xfb\x2f\xb6\x1a\x34\x8f\xea\x13\xef\x67\xcd\xf2\xe0\x39\xe3\x3f\xd8\x9e\x2c\x1a\xd2\xa4\x25\x4e\x3b\xf7\x48\x45\x2a\xa8\x3e\xfe\xca\x46\xe7\x80\xed\xe1\xd1\x3f\xf4\xcc\x5e\x7d\x01\xed\x45\xeb\x8c\x74\x81\x8d\x48\x60\xaf\x47\x59\xa8\x3e\x14\x88\x96\xab\x68\x73\x43\x95\x76\x0e\x00\x14\x6b\x79\x3c\x3e\x72\x89\x8a\xa0\xb3\xc5\xe0\xc1\xd3\xfd\xf1\x21\x58\xd2\xe8\xff\x11\x23\xa3\xa0\xc6\x4c\xf6\x37\x4a\x7f\x44\xf1\x1a\x57\x5e\x48\xa3\x79\x18\x1b\x30\xa4\x86\x5c\xfd\x02\x2a\xa9\x83\x27\x56\x35\xce\x4f\x2c\xc4\x0b\xfe\x06\x60\x67\xec\x4f\xe2\x41\xfa\x04\x7b\x55\x27\x0a\x1a\xd0\x77\x6c\x5f\x96\x86\x10\x14\xcb\xf4\x0a\x04\x32\xc5\x59\xf2\x2d\x79\x34\x2b\x79\xf8\xe7\x04\x2d\xcc\xfb\x1c\xf5\x0f\x83\x08\x5f\x80\x63\xfb\x18\x87\xed\x2d\xfc\x9d\xb7\xef\xc9\x6d\xaa\x0f\xf2\xbc\x4f\x52\x33\x5b\x02\x11\x2d\x16\x39\x2e\x13\x4c\x02\x23\xde\x45\x8f\xc0\x72\xcc\x22\xbf\x9e\x7e\xab\xc0\x62\x08\x18\x0a\x57\xe7\xce\x48\x05\xee\x4e\x0f\xc0\x15\x84\x09\x98\xfd\x56\x86\x44\xa0\x38\x6b\x3d\x8e\x7d\xda\x52\xab\xf6\x4f\x7d\xd0\x08\x68\xfc\x84\xf0\x36\xca\x8a\x78\xe9\xba\x81\x71\xca\x90\x26\x7c\x74\xe6\x15\x9a\xca\xc7\xaf\x5b\xf2\x37\x59\xab\xc5\x3d\x82\xe7\x93\xdb\x87\xfd\xad\xe1\x36\x33\x54\xff\xdc\xb0\xbd\x4c\xc9\x21\x3f\x5c\x84\x54\x45\xfc\x64\x9b\x2a\x1f\x32\x9f\x9d\x41\xd8\xa0\x31\xab\x46\xb4\x72\x16\x0f\x03\x43\x4b\x4b\x6b\xc5\xa4\x01\x52\x4d\x61\x79\xad\x66\xf9\xe2\x21\xc9\x06\x7f\xc8\x7f\xe4\xa7\x7e\x21\xe8\x02\x3b\x61\x69\xeb\xf1\x09\x0c\xd5\x56\xa9\xbe\x50\xb9\x18\x7f\xe4\x60\x7c\x59\x25\xe6\x0b\x41\x4f\x6a\x5c\xbf\x8a\xfa\x15\xed\x0e\xb3\x4b\x67\xb4\xc9\xc5\xd5\x4a\xdb\xe6\x40"}, +{{0xb5,0x69,0xf7,0xc1,0xaa,0xdf,0x56,0xed,0x1b,0x5f,0xa1,0xb6,0xfa,0xd6,0x48,0xd0,0xdc,0x54,0x4f,0xf8,0xfc,0xd1,0x73,0x78,0x0d,0xe4,0x1a,0x7d,0x4d,0xe6,0x0c,0xb6,},{0x9e,0xff,0xa4,0xae,0xd9,0xc6,0x58,0xe4,0x34,0x60,0x71,0x43,0x44,0x68,0xa0,0xb8,0xa0,0x4e,0xcf,0x78,0x41,0x69,0x9d,0x63,0xe8,0x88,0x7c,0xe2,0x05,0x57,0x0c,0xea,},{0x2e,0x32,0xba,0x05,0x56,0xbd,0xe9,0x74,0xd7,0xa1,0x9b,0x3b,0x9a,0x1e,0x92,0xf1,0x83,0x92,0x4c,0x4b,0x74,0xc5,0xd7,0x51,0xb5,0xab,0x3d,0x00,0x79,0x67,0x01,0x6e,0xc0,0x3a,0xfe,0x91,0xd7,0x42,0xfb,0x22,0xb6,0x3e,0x5e,0x55,0xb2,0xfc,0xb6,0xc6,0x1a,0x46,0xe9,0xdc,0xe7,0xfe,0x9f,0xa3,0x0b,0xbf,0x66,0xae,0xf4,0xb8,0x5f,0x09,},"\x7c\x5a\xa4\xdc\x80\x78\xaa\x77\xe8\xb3\xb7\xfe\xe6\x10\x84\xcf\xad\x76\x47\x62\xf1\xef\x26\xd8\xde\xb7\xf2\xf3\xb1\x86\xdf\xc7\x72\x48\x75\x50\x19\x78\x45\xfb\xa2\xf4\xc2\x3c\x83\x5b\x9b\x58\xdd\x0b\x63\x5c\x64\x91\x35\x13\x7f\x24\x8f\x5e\xf7\x13\x56\x4d\xe3\xc9\x66\xef\xa5\xf6\xdb\x6b\xea\x9e\x30\x97\x07\x49\xf8\xe8\x72\xd8\xd7\xae\x45\x35\xb7\x5e\x17\x6e\xa0\x48\x9b\x91\x5f\x34\x71\xd8\x27\xeb\x5b\x44\x45\x86\x48\x8c\xfc\x3f\xa6\xa4\x50\x82\xda\xcb\x82\x64\x95\xe5\x0a\x3b\x5d\xc6\xbb\x93\x0a\x33\x1f\x30\xc3\x85\xbc\x3b\x24\xce\x70\xb8\x95\x96\xdb\x6b\xfb\x68\x7d\x99\xa5\x81\x98\x7c\xa8\x76\xea\x0e\x75\x76\x96\xb3\xfc\x03\x77\x9a\x65\x81\x30\xc4\x10\xb3\x44\xed\xac\xc4\x27\x7d\x44\x84\x54\x99\xd6\x78\xe1\x41\x4f\x15\xf3\x6e\x16\x63\x35\x18\x95\x69\xce\xf3\x56\x7a\xc2\xe3\xab\x82\x1c\x91\xc9\x32\x74\xf5\xc2\x8a\x5d\x1f\x7c\x1b\xf5\x09\x9b\x10\xf8\x4e\xcb\x13\xa4\xe4\x53\x8f\x66\x49\xbf\x74\xf7\x39\x4b\x70\x3e\xf5\x36\x49\xd8\x15\x16\xcb\x1d\xb5\x21\x41\x60\x65\xcf\x9f\x27\x6a\xb8\x0c\x93\x08\x89\x7a\x27\xdf\xe3\x7e\x5e\x14\x2f\x18\x19\xb8\xd3\x48\xdf\x50\xa0\x46\xa1\x28\x88\xe3\xb7\xf2\xdc\xc7\x0f\x52\x18\xd1\x5e\xbb\x9a\xa7\x29\x1a\x1a\x92\xac\x44\x5c\x51\xd3\xa5\x3d\xd6\x91\xef\xff\xcf\x5a\x01\xe8\x76\xa7\x2a\xa4\x81\xeb\x4f\x12\x1a\x07\x23\x97\xd8\xcc\x93\xbb\xc2\xc9\xa6\xc2\x8c\xc8\x9b\x11\xff\xc0\xe9\x10\xd8\x2d\x9d\x62\x98\xa3\x67\xa0\xe1\xe3\xe8\xc8\x65\xe4\x32\x6a\x31\x9b\x22\x66\x6e\x52\x9f\x19\x98\xf1\xb3\xc8\xef\xb5\xfc\x21\xcc\xe9\x70\x40\xfb\x62\x47\xda\xa0\x00\x0a\xc5\x55\x4d\x89\xe7\xb2\x71\x59\xdd\x0b\x18\x00\xb7\x60\xb7\x9c\x91\xef\x6e\x97\x0b\x1e\x6c\x5f\xf4\x24\x42\xb1\xb3\xae\x4d\x3c\x43\x9e\x08\xec\x2f\x6b\x94\x17\x73\x87\xca\x5c\x01\xdf\x6f\x07\xf8\xe3\x4d\x25\xed\xbd\x49\xd8\xb7\x4e\x31\xa5\xe6\x5d\xec\x1f\x87\x60\xfa\x22\xc0\x0e\x6f\xb1\xcd\x55\x5b\xe6\x8b\x0a\xb4\x35\x99\xf0\xb9\xf4\xa5\x4a\x7c\xcb\x06\x26\x83\x89\x5d\x5e\xf6\x6d\x24\xdf\xb1\x67\x8c\xb0\xd0\xe8\xc8\x01\xd8\xe5\xff\xe7\x9b\x91\x39\xfc\x96\xd1\x18\xeb\x39\xb9\xc8\xd4\x40\x44\x89\x32\x5d\x45\xb4\xa3\x20\x2b\xea\xdc\xa6\x6f\x83\x1c\x68\xef\xb8\x15\x94\x15\x81\x93\x0e\xad\x29\xfd\x5f\x21\x1b\x90\xe7\xa3\x9f\x0d\x4f\xf4\x8c\x62\xa5\x45\xe2\x8a\xc2\xce\x29\xbe\xdc\x35\x6d\x92\xfc\x00\x34\x71\x76\xd7\x76\x23\xe0\xe1\x80\x9e\xff\x3f\xe6\x2b\x75\xa7\xd9\xde\xb7\x27\xd8\x61\x72\xd1\x4e\xdb\xf2\x78\x9a\x57\x14\x3c\x69\x92\x5c\x91\x7d\x43\x3b\x46\x83\xb0\x69\x3b\x3c\xd9\xe7\xe3\x77\x99\x64\x10\x72\x7f\x5e\x6f\xb8\xf5\xcc\xd1\x86\x0a\x20\x29\x4e\xcf\x33\xfa\xf9\x7a\x1e\x0f\x85\xb7\x61\x44\x7d\x47\x61\xb9\x6e\x4d\xf1\xb3\x12\xbd\x41\x4c\xab\xcf\x49\x84\x97\xb0\xea\xd6\x7c\xd1\xe5\x90\x1b\xbf\x3a\x16\xa8\x89\x1c\xcc\xed\x8a\x90\x7d\xf8\x87\x26\x95\x2d\x4a\xb3\x70\xa6\xb7\xdf\x29\x42\xcf\x13\x61\x5a\x5b\xc1\x2b\x4e\x10\x6d\xc3\x01\x3c\x68\xb8\xfb\x90\x63\x99\xdf\x15\xf1\xaa\x90\xd5\x6a\xa9\x74\xb1\xd2\xb2\x8c\x1a\x84\x53\xb9\xbf\x07\x92\xa5\x1c\x97\xce\x8a\x12\xaf\xc9\x34\x1b\xb4\xc0\xc3\x7b\x12\xdc\xb1\x2c\x63\x94\x49\x77\x5d\x9a\xc5\xc2\xec\x49\x67\x3d\xa5\xaa\xf7\x49\x3e\xd5\xf1\xf2\x11\x6e\xae\xf7\x2b\xb7\xfb\x1e\x09\x3e\xde\x2c\x26\x31\x7f\x4f\x4b\x6a\xd5\x85\x34\x62\x05\xdf\x91\xa6\xe9\x6b\xc6\x6d\x30\x64\xbc\xe9\x52\x39\x8f\xfc\xe8\x80\x71\xed\x9f\xf2\x75\x0c\x65\xc0\xc3\x04\x12\x5a\xc2\xca\xdc\x4f\xef\x71\xa8\x18\x73\x24\x96\xa8\x4c\xa5\x74\xd4\x82\xd5\xa3\xbb\xa2\x0e\x16\xdd\x2f\xa2\x4d\x32\x70\xf6\xc6\x09\x92\xf7\xf6\x3e\x88\xf5\x2e\xff\x62\x22\x99\x8e\xb4\x41\x67\x27\x38\x43\x75\xf5\x9f\x00\xe4\x75\x12\xee\x46\x4c\x31\x84\xac\xea\xff\x3c\xcf\xb0\x6b\xd1\x5c\x18\x3c\x5e\x48\x59\x26\x28\x8b\x99\x7b\xfa\xaa\xec\xf6\xec\xbb\xf7\xd2\xab\xf4\x90\x6d\xf7\x6b\x12\x77\xc5\xf5\xa8\x7e\x68\x17\xb1\xc6\x36\xe9\x1e\xfd\x7e\xcc\xf6\x4f"}, +{{0x32,0x34,0x65,0xd0,0x31,0x3d,0x10,0x01,0xa2,0x61,0xab,0xfd,0x44,0xfe,0x65,0xc3,0x8c,0x9a,0x00,0xca,0x0f,0x20,0x33,0x5d,0x65,0x53,0xde,0x49,0x26,0x99,0xfc,0x46,},{0xe2,0x2f,0x16,0xbd,0x4c,0xc7,0xe9,0x4c,0x46,0xba,0x31,0x96,0x1a,0xf8,0xc5,0x83,0xf9,0xd2,0x71,0x8c,0x68,0xf7,0x3d,0x85,0x06,0x9f,0x60,0x8e,0x15,0xba,0x87,0x66,},{0xda,0x3a,0xad,0xb3,0x43,0x60,0xb2,0xda,0x0c,0x26,0x54,0x2e,0xa7,0x1d,0xef,0xa8,0xa0,0xbf,0x7f,0xbd,0xae,0x3e,0xe9,0xe1,0x1c,0x84,0x08,0x4a,0xd0,0x5c,0xce,0x7b,0xa7,0xd9,0x4d,0xe2,0x5d,0x85,0x63,0x98,0x26,0x16,0xbc,0xdb,0x5b,0xb6,0x39,0x5f,0xac,0x4a,0x7e,0x84,0xbc,0x77,0xe2,0x1e,0xd3,0x6d,0xf7,0x5d,0xec,0x99,0x0b,0x06,},"\xbb\x10\x82\xe1\xcf\xdc\xd2\x9b\xfc\xa2\x46\x4d\x5c\xe4\x46\xb5\xba\x65\x4b\xa5\x8c\x22\x53\x8d\xa9\x26\xb8\x30\x3c\xab\xfd\x28\x4a\x7b\xd5\x99\x4a\x78\x6f\xa6\x6a\xed\xf0\xe1\x5f\x20\xc3\x82\xcd\xac\xf3\xd1\x45\x57\xff\x7a\x82\x67\xfa\x04\x67\x2c\xac\xab\x76\x70\x08\x65\x0a\xa9\xb4\xa7\xc9\x07\x1c\x47\x99\xf1\xff\xa4\x5c\xa4\xd5\x86\xe0\x20\x47\x44\x4c\x14\x23\x19\x43\x46\x7a\x3a\xba\xef\xa5\x39\x59\xda\x22\x6e\xb0\xc1\x53\x92\x01\x97\x60\x15\x96\x97\x74\x82\x93\xc0\x25\x56\x87\x83\x58\x8a\x39\x10\xe7\x8e\x5e\xa4\x27\xc4\x40\x7a\x89\x01\x06\x1b\x8b\x99\x2b\x82\xa2\xdf\x58\xc0\x4a\x1b\x2c\x5f\xad\x11\xc6\xb3\x79\x85\x6c\x2e\x0f\xef\x8a\x95\x0d\xe7\xe0\xfc\x22\x31\x03\x09\xe0\x8b\x13\x2b\x0c\xce\x4f\xc1\xec\xbf\x94\x57\x4a\x38\x8d\x4a\xe3\x66\x75\xd3\x29\x9a\x95\x15\x54\xeb\xf1\x80\xeb\x38\x1e\x1b\x5d\xf9\x77\xd9\x38\x43\x38\x91\xbc\x47\x8d\x76\x81\x85\x0b\x9d\xc9\xc5\xc7\x69\xd4\x05\xf5\xd8\x83\x9f\xc9\x73\x61\xd6\xcb\x30\x6c\x20\x30\x26\xcf\x2e\x2b\x3d\x39\x84\x9e\x1f\x4b\x12\x25\xeb\x25\xef\x8a\xcd\x40\xb0\x06\xf2\x0c\x64\x4d\xb6\x50\xc7\x5d\x38\xc0\xfc\xdd\x48\xf5\x98\xc7\xb4\xa6\x01\x06\xe6\x9e\x19\xcd\x71\x25\x89\xce\xdc\xcf\x50\x86\x4e\xa5\xf9\xe9\x5e\x01\xf1\xdd\x85\xc7\x51\x4f\x2c\x94\xb2\x83\x59\xde\x41\x32\xb8\x8c\x3e\xe1\xd1\x0a\x80\xa9\xfa\xdf\xb6\x90\xe3\xd8\x86\x41\xb3\x16\x8f\x0b\x89\x6a\xf8\x99\x0a\xdb\xf0\xe4\xf8\xe9\xd3\xf9\xd4\xcd\x31\x4e\x12\xc3\xbc\xe0\xcc\x87\x38\xe0\xcf\xc1\x90\x5b\xe5\xef\xa0\x71\xf7\x10\xb3\x2f\x8e\x58\x98\xc6\x0e\xb1\xbb\x8f\xee\xb7\x40\x00\x56\x0f\x41\xcb\x2e\xbc\x32\xb2\x60\x0b\x69\x80\xa2\xa4\x06\x4d\xfa\xa3\x79\x7e\xc4\x4c\xfb\x72\xd3\x79\xf8\x09\x73\x79\xca\xd6\x7e\xcd\xc0\xc3\x24\x14\xfa\x41\xc7\x2b\x1b\x9e\x4e\xdf\x55\x18\xcb\x39\xfe\x90\x92\xb4\x39\xaf\x3a\x4e\xbd\x5a\xfe\x79\xbe\xdc\x0e\xa8\xbf\x17\x47\x9a\x28\x21\xf5\xe9\xbd\x91\xd7\xf4\xaa\x5e\x38\x46\x99\x52\x37\x19\xb6\x95\x7f\x82\x36\x7c\xd8\x5f\xea\x9d\xed\x62\x36\xa2\x07\xc9\x4c\xb3\x73\xe3\x39\x3c\xb4\xfe\x11\xf9\x0a\x1b\x87\x79\xe4\xab\x4c\x34\x66\x13\x6b\xf2\x1e\x2a\xab\x78\xf7\xd2\x72\x6d\xb6\x41\x4f\xa5\xc4\xa3\xf7\x31\x3a\xd2\x11\x6a\x6d\x7c\xe4\x0a\xaa\x10\x01\xc2\x70\x4d\x5b\x05\xae\x54\xc7\xcc\x6f\x56\x72\x17\xf1\xa4\x7b\xfd\x0e\xe7\x38\xea\xea\x5e\xad\xb5\x37\x10\x75\xbe\x07\x6c\x87\x50\xae\xce\xfc\x41\x7e\xa7\xbf\xda\xac\x3c\xc3\x8b\xf1\x6c\xc2\x6d\xf7\x60\x0e\x3c\x7e\x8e\x43\x1f\x26\x76\xfc\x2a\x8c\x43\xa6\xa1\x43\x68\xba\x62\xbb\x32\x43\x9a\x06\xbe\xac\x38\xa0\x47\xb3\x74\x5e\x26\xf4\x07\xad\x82\x3d\x6a\xd1\xc0\xb6\xa4\x43\x41\xe1\x5f\xc9\xb3\x31\x21\x4f\xfc\x89\x69\x82\x11\xb0\x51\x33\xd6\xd3\x43\x3b\x5d\x59\xf7\xab\x4d\x10\x9e\x54\xe4\xc5\xd6\xf3\x2f\xcf\x72\x30\xfa\x4e\x25\x28\xc8\x61\xbb\x21\xcc\xc9\xe3\x10\xe9\x49\x7e\x07\x7e\xa6\x75\x51\x0d\xa7\x12\xb1\xa5\xdf\x57\x5c\x5d\x1b\xf7\x36\x2d\x07\x11\x80\x03\x9a\xec\xfa\xa5\xc8\x57\x3c\x24\xc0\xf4\xeb\xe8\x1c\x2f\x88\x9a\xed\x3d\xe5\xa0\x00\xbe\x12\xfe\x3d\x0a\xf2\xdc\x2c\xd4\x24\x0e\x31\x4a\x17\x6c\x55\x3e\xfd\x5c\xba\x79\x8d\x9f\xf1\xe3\xd4\xbd\x9e\x90\xbb\x81\x13\xe3\x84\x9d\x73\x5a\xfa\x4a\xf6\x94\x5c\xc5\x7d\x4c\x37\x8d\xb8\x4f\x20\x6e\xf7\xea\xb1\x1c\x63\x7a\x7f\x72\x60\xf1\x22\xa9\x7d\xff\x67\x47\xe9\xb4\xc1\x74\xed\x0d\x64\xf9\xef\xd7\xfc\xcc\xf9\x81\x51\x9e\xc5\x80\xa8\x18\x25\x47\xd1\x79\x68\xc4\x01\x51\xfd\xf6\xd5\x4b\xc5\x7a\x91\x15\xf0\x40\xfa\xb5\xc1\x00\xde\xb0\x39\x12\x2b\x7d\x2b\xfd\x98\xb6\xad\xf3\x8f\x42\xb2\x96\xea\x3b\x37\x8a\x90\x42\x59\xb7\x5d\x60\x70\x3b\x48\x40\xb3\xf5\xda\x09\x62\x0a\x54\x77\x62\x80\xe9\xca\x9e\x8c\xd9\x24\xae\xd2\xb5\xdd\x2b\x49\x83\x4e\x58\x1c\xae\xd5\x27\x1c\xd7\x8c\xe0\x8e\x4b\xba\x49\xb5\x9c\xd7\x7c\x1b\x62\x76\x64\x91\x48\xab\x72\x47\xf9\x7f\xc0\x13\x16\x35\xde\x47\x4d\x3c\x23\x49\x3c\xa9\x8d"}, +{{0x60,0xff,0xdb,0xae,0x00,0x3f,0xa2,0x79,0x4f,0xca,0xbb,0xf8,0xf5,0xb4,0x16,0x44,0xfe,0x3a,0x7f,0x44,0xed,0x6c,0x83,0x41,0x93,0xda,0x07,0xa9,0xdc,0x5e,0x26,0x65,},{0x35,0xb5,0xeb,0x31,0xab,0x55,0x64,0x92,0x57,0x8b,0x3d,0xbd,0x6c,0xf1,0x68,0x7d,0x1f,0xdb,0x21,0x6a,0x72,0x58,0x18,0x07,0x96,0x63,0x48,0x2f,0x22,0x1c,0xe4,0x21,},{0xb8,0xf3,0xe1,0xf3,0x78,0x5a,0x2a,0x39,0xbb,0x08,0x6c,0xa4,0x65,0xc0,0xab,0xf0,0xa3,0xe8,0x74,0x43,0x22,0x5a,0xc6,0xe9,0x66,0xed,0x9b,0x45,0x31,0xc5,0x4a,0x89,0x4a,0x9a,0xbd,0x01,0xac,0x31,0xb8,0x57,0x57,0xfe,0x75,0x30,0x8c,0x95,0x94,0xff,0x65,0xf9,0x7c,0xdd,0x91,0xe8,0xd8,0xa9,0x3c,0xf1,0x2b,0x9e,0x6d,0xbe,0xe9,0x0b,},"\x3f\x8f\xf2\x0b\xb4\xf0\x08\x34\xc8\x0f\x2e\xe6\x89\x3d\x6f\x73\xbf\x7a\xce\x27\x29\x60\x1b\xb2\x6a\x0f\xb2\x72\xa4\xd0\xee\xa1\xfa\xe1\xd3\x06\xac\x2c\x5f\x32\xad\xd6\x01\x35\x85\x1d\xa2\x7e\x4f\x12\xe6\x4e\xa5\xe9\xe9\x96\x0b\x13\x83\xb0\x4c\xe0\x5a\x98\xb0\x41\x4d\xad\x97\x1e\xa9\x89\x44\x87\x1d\x41\x5c\xc2\xc4\x6d\xa4\x03\x97\x6d\x9f\x21\x93\x89\x58\xd4\xea\x8c\x79\x03\xb1\x4f\x2a\x44\x85\xfd\x69\xaf\xb2\x4a\xbe\x10\x2d\x8f\xec\x26\x6f\xb4\x68\xb4\x11\xeb\x20\xa3\x39\x67\x7d\x88\xeb\x31\xc9\x97\xb4\xdc\x88\x56\x13\xf0\xbe\x7c\x70\xda\xf8\x56\xa3\xdf\x92\xda\x96\x02\xfb\xa2\xe6\x74\x9d\x2f\x42\x6b\xee\xf6\x86\x62\xd5\xb0\xc2\xfd\x31\x32\x1b\x22\xb5\xec\x59\x7d\xa5\xd7\xe6\xa2\x88\xeb\xd9\x44\x3c\x5f\x39\xeb\x87\xdc\xf4\xa5\xad\x9d\x56\xc6\xba\xf6\x08\x09\x96\xa7\x79\x36\xbd\x87\xdc\x3c\xb4\x2e\xd4\xc4\xd4\x26\x88\xa9\xe1\x93\x82\x9b\x76\x1f\xf3\x20\xe2\xa6\x6c\xc6\x76\x48\xe7\x0e\xea\x3a\x1f\x2f\x9b\x9d\x5b\x42\x02\xfb\x5a\x39\xe9\xad\xc6\x09\x08\x6a\x9b\xe2\xa8\x32\x3a\xc6\x69\x31\xbd\xf6\xc5\x04\xd3\x33\x62\x11\xe4\x6f\xde\xfc\x48\x1f\xbf\x17\xf6\x13\xda\xb1\xfc\x5c\x09\x7c\x92\xdb\x06\x09\x90\x6d\x78\xb2\x5a\x45\x5a\x30\x45\x71\x8e\xfd\x3e\x3b\x14\xe2\x52\xb1\xae\x59\xc7\xc3\x89\x3e\x31\x91\x3b\x2c\x26\x4c\x0f\xfc\x3b\x60\x6c\xa1\xb0\x1d\xc4\x7e\xe8\x28\xa0\x8e\x46\xaf\x60\x4e\x59\x0d\xef\x44\xd2\x7a\xab\x93\xa4\x03\x25\x1f\xca\x07\x72\xe9\xdf\x0f\xab\x7a\xf0\xcb\xc5\x18\x1e\xfd\xa4\xda\x91\x3d\x8e\xb6\x45\x2f\x6c\xec\xbd\xa2\x04\xbc\x72\xd7\xc9\x90\xf6\x0c\xe0\xdd\x83\xc6\x34\xe9\x12\x23\x60\x91\xb0\xa6\x67\x3a\x7c\x89\xea\x59\x30\x8d\x55\xbd\x7e\x63\xa8\x52\x67\x74\xcb\xdd\x7a\x13\x39\xfa\xc2\x12\x4c\x90\x22\xab\xd6\xfe\xce\x7f\x2d\xae\xdf\xd8\x7f\xa6\x83\xdc\x0e\x3e\xf4\x08\x06\xa0\xab\x19\x87\x69\xd3\xa9\x9f\xe8\x1a\x99\xb6\x86\x00\x31\x90\x87\xaf\xa4\xea\x79\xd7\xee\x45\xda\x9c\xd4\x08\x09\xf4\xee\x8f\x4e\x25\xa0\x17\x75\x21\xee\x9d\xba\x8b\x56\x21\x2e\x88\x71\x9b\xb7\x36\x73\x36\xf4\xa7\xbc\x71\x22\xb4\x1a\x7d\xfa\xa2\x67\x2f\x92\xf2\x34\x03\xa1\x0c\x4f\xb2\x53\x88\xc6\xb2\x00\x81\x09\x3d\x49\xf3\xbe\x8a\x9e\x1c\x63\x4e\xf7\xba\x96\xb6\xd5\x23\xdd\x6f\xf6\x13\xc0\xa2\x3b\x60\x45\x70\x26\xcd\x48\x5b\xa8\xdb\x61\xd8\x0a\x0d\xc6\x59\xd9\xaf\x42\xa3\x8c\xae\x77\x7f\xec\x68\xe3\x9c\x52\x98\x6f\xf9\xfc\x20\x78\x9c\x10\x58\x51\x07\xc0\x40\x47\xb6\x6b\xa1\x4e\x93\xfb\x90\x4e\xa9\x0d\xf7\xac\x9f\x01\x54\xc9\x6f\x32\x36\xac\xf6\xdc\x8b\x44\xf5\x54\xc0\xcd\x51\x31\x93\xe5\xdf\xd8\x7e\x08\x5a\xd4\xb3\x8a\xa4\xc5\xe3\x6b\x24\x27\x72\x20\x88\x81\x6e\xcd\x2b\xc3\xa3\xdd\xa0\x1e\x4f\xb3\xff\x5e\xec\x7a\x64\x17\x32\x2b\xa6\xa2\x77\x73\xd2\x44\x95\xa8\x39\x19\x4a\x4a\x58\x2f\xe5\xab\xdb\x8b\x5d\x53\x3a\x24\x26\x25\x89\x24\x1f\xc8\x1f\xdf\x5e\x79\xfd\x26\x77\x64\x28\xf8\xe1\xce\x9e\x92\x6c\xf2\x72\x71\x6e\x75\x83\xab\xfc\x67\xa9\x4a\xae\x08\x16\xc1\x00\x0a\x19\x61\x70\xbb\xff\x1f\x45\xe5\xed\x9e\x26\x7a\xce\x1e\x4d\x91\x5d\xce\x72\x16\xc5\xf4\x04\xde\xf6\xfe\x2b\xd8\xb2\x8b\x2e\xcc\xf3\xe2\xae\xa0\xc0\xd6\x62\x63\x90\x27\x4e\x47\xe7\x45\xed\x3a\x23\xbc\xfd\x21\xd2\x84\xc3\x95\x37\x9d\xc0\x20\x80\xf0\x79\x36\xbc\x15\x4e\x7b\x99\xee\x73\xdb\x18\x8b\xd2\xa3\x94\xe0\x3a\x01\xff\xe2\xd1\xb3\x30\xce\xb7\x21\x58\xf9\x58\xc7\x16\xa8\x17\x11\xdb\xf6\x5a\xff\x8c\xd1\x2f\x5d\xfa\x53\xb3\x76\xeb\xb8\xb9\x8f\x86\x28\xf1\x7e\xf8\xb2\xab\x9c\x0b\xb6\x84\x12\xf4\xe3\x47\xa6\x33\xe2\xf8\xda\x1a\x55\x6d\x96\xf4\xaf\x72\x11\xc0\x78\x07\x9c\x10\x54\x1c\x07\xdc\x37\x22\xd1\x8d\xab\x8f\xa8\xbc\x49\x25\xab\xa5\xc9\x66\xf8\x05\x04\x03\x22\xdf\xbb\xbe\x87\xfb\xfe\xb1\x96\x1f\x5c\xcd\x40\xa9\x1b\x99\x7e\x54\x31\x5a\x7e\xef\xc3\xa4\x7b\xb0\xc8\x7d\xc2\x37\x55\xce\x72\x27\x57\x49\x96\xf4\xbe\x7a\xa3\x44\xfe\x0d\x17\xb9\x7b\xc5\x0c\x58\x38\xf9\x92\x92"}, +{{0x17,0x4e,0x99,0x3d,0x9b,0x81,0xf2,0xaf,0x67,0xe9,0xff,0xb8,0xeb,0xd5,0xda,0x41,0x79,0x66,0xa9,0xe7,0x7f,0x66,0xc6,0x5c,0x76,0x77,0x38,0xfe,0x83,0x57,0xd0,0x7c,},{0x3b,0xb7,0x38,0x6f,0x1b,0x1c,0xbf,0xae,0x55,0x37,0x03,0x83,0x3e,0xbc,0xbf,0xe2,0xdf,0xff,0x8c,0x89,0x9a,0x07,0x92,0xd7,0xce,0x23,0x22,0xb5,0xba,0x64,0x5a,0x5f,},{0xe6,0x07,0xbc,0x9a,0x53,0x60,0xb3,0x1d,0xa5,0x6b,0xe1,0xc5,0x44,0xc2,0x00,0x02,0x84,0x95,0x1d,0x86,0x89,0xf4,0xb7,0x22,0xbc,0x46,0x73,0xa0,0xc8,0x48,0x9b,0x84,0x48,0x3e,0xd8,0xe7,0x6e,0x29,0x7e,0xa0,0x46,0xe8,0x5b,0x37,0xba,0x56,0x30,0x58,0x5e,0x53,0x75,0x56,0x6a,0x18,0x7a,0xfb,0x56,0x96,0x66,0x1e,0x5b,0xfd,0xc1,0x0e,},"\xa4\x01\x75\x0a\xfc\x48\x37\xdf\xe3\xaa\xcc\x28\x4a\x59\x71\x45\xdf\xef\x02\x62\x9e\xf8\x7b\xd0\x93\x8d\x44\x39\x79\xdf\x76\xf2\x9f\xcd\x66\xa5\xb7\x1e\xa8\xab\x78\x72\x77\xe3\x05\x6f\x6e\xa1\x1b\x08\xbd\x23\x89\x79\xf9\xd3\xb0\x62\x53\x8c\x4d\x60\x40\xa8\x6b\x6e\x32\x04\x7a\xec\xc5\x9c\x23\x77\xad\x0e\xa4\xc4\x0c\x79\xff\x9f\xe9\x8c\x95\x8b\x2b\xf2\x5f\x2f\xd6\x34\x24\x32\x63\x6f\x5f\x7d\x5b\xb0\xd2\xec\xf1\x81\x83\x42\x6c\x73\x14\x79\x84\xd9\x5b\xbe\x16\x2e\x11\x97\x2d\xdb\x78\xa2\xa7\xc3\x45\xc5\xc0\xbb\xba\xba\x9c\xf3\x8a\x2d\x5d\xd5\x09\xa7\xdf\x8b\x84\x28\x74\xa9\x6e\x64\xb5\xd6\x4f\x5c\x41\xa2\x1d\x20\x8d\x14\xce\xa7\x06\x6c\xf2\x2d\xee\x0c\xa4\x1a\xa4\x6a\xb9\x21\xd4\xce\xec\x89\xec\x87\x3f\x77\x96\x0e\xda\x60\xd9\x67\x6c\xfd\x0d\xbf\xae\xc8\x72\xc2\xad\xe8\xfb\xa4\x28\x5a\xac\xd5\x27\x14\x3a\xe0\x34\x1d\x67\xd0\x07\x81\x19\x65\x3b\x5d\x23\xd4\x6e\x6e\xf7\x02\x64\xb1\xb0\x91\x38\x70\x87\x76\x23\x71\x6d\x0f\x1a\x59\x02\x1b\xe7\x4c\x91\x4b\x43\x24\x71\xa4\x3a\x29\xf2\xb6\xdb\xeb\x6a\x22\x3e\x2d\xba\xab\xb8\x20\xb4\xad\xbe\x33\x78\x29\xe1\xde\x0c\x18\x4d\xd0\xd0\x9f\x9d\x01\xd4\x25\x27\xe5\xd4\x0a\xbb\xda\xcc\x8a\xc0\xf1\xb2\xc5\xc1\xcb\x2f\x23\x87\x6d\x2d\x1b\x6b\x43\xdf\xe4\x82\xf9\xd4\x5a\x18\xf5\xc2\x2b\x15\xf1\xfe\x52\x1e\xf5\x7b\x08\xae\xc6\xa3\x03\x39\x25\xc7\x45\x4c\x93\xe6\x31\x9e\x77\x8a\xc4\x94\xfb\x14\x0a\xe5\xf1\xa3\x1c\xc8\x32\xca\x24\x88\x65\x10\x04\x06\x3b\xcf\xf8\xfd\x9a\xe9\x26\x6a\xf5\x27\xf2\xc3\x1f\x6a\xcb\x8f\x3d\xeb\xd9\x97\x8e\xf9\xdf\x01\x08\xe3\xd5\x0c\x49\x19\x90\xc9\x0d\xd8\xee\x9d\x64\xea\x4e\xbf\xd7\x11\xc9\x9d\x90\x44\xec\x11\x34\x2c\x53\x83\xca\x39\x23\x2e\xd9\x7a\x07\xe4\xdc\x51\xdb\x4c\x1f\xe9\x47\x34\x8d\xff\xe7\x0a\x95\xc9\x9d\xb1\x47\x51\x31\x48\x01\xf1\x3f\xa2\xbf\x42\xd8\x67\x37\x5a\x08\xee\x9b\x3b\x79\x9e\x0b\x15\x27\x8e\x95\xe9\x1a\x89\x68\x06\x4d\x6d\xfd\x8f\x51\x15\x43\x8c\xcb\x8b\x51\x6c\xa0\xc4\x1d\xbb\x19\x87\x3c\x6e\x10\xa2\x36\xec\xc2\xda\xd5\x22\xf8\x0f\x01\xc1\x4e\x2f\xa1\x4a\x0d\x79\x2b\x9f\xc4\x86\xc6\xfb\x0e\xfb\xdf\x21\x30\xf0\x2d\xf1\x49\x7d\xb5\xab\xa8\xbe\x61\xca\x70\xb2\x93\x88\xe4\xee\xc7\xe0\x69\x4a\x38\xc0\xd0\x3c\x59\xbb\x6a\x2d\xc3\xcc\xd6\xdd\xe1\xe2\x9e\xe2\xc1\xb3\x25\xac\x72\xaa\x8e\x6f\xab\x91\x38\xf8\xb6\xf5\xd3\x24\xd4\x6a\xf3\xa3\x54\x2c\x8b\xd8\x7c\xb0\x4f\xaf\xc5\x4b\x5d\xb8\x27\xde\x60\x67\x62\xa0\x97\xb6\x22\x79\x9c\xa8\x27\xbd\xa9\xc1\xc0\xbb\x26\x7e\xba\x82\x54\xa8\x1c\x6b\x85\x8a\x37\x5b\x94\xbd\x09\xf3\x9e\xeb\x88\xcb\x14\xb8\xd4\x6e\x47\x40\xdc\x1a\xb4\x2a\x89\x5f\x86\xd2\xc5\x7f\xc2\x8b\x07\xb7\xf6\x0f\xc4\xf8\x84\x7b\x8b\xc8\xad\x83\xa2\x48\x1a\x28\xf2\x9b\xca\x35\x10\xff\x8b\xf1\xdd\x75\x81\xe3\x35\x71\x64\xf4\xfe\x92\x0f\x9d\xe8\x39\x37\x6d\xe0\x64\x90\x0d\xc7\xf8\xbc\xf5\x11\xdc\x57\x2e\x0f\x0f\x6a\x75\xb9\x29\x79\x7d\xa4\x1c\x52\xea\xe6\xfe\x13\x75\x0c\xe3\x51\xe8\x76\x76\x30\xba\xdf\x6d\x7d\x4e\xab\x90\xcd\x19\x04\xc9\x6c\x04\x8a\x9a\xcb\x21\x3a\x9e\x5b\x86\x46\x15\x73\x8a\x84\xf2\x22\x98\x6a\xc2\x35\x54\xcf\x4c\xe5\x4e\x80\xab\x57\x33\xc0\x65\xb8\x04\x59\x92\x1d\xd3\xd8\x37\x2d\x0e\x85\x94\xd4\x36\x43\x51\xbf\x04\x1c\x14\x6f\xa8\xd2\x3a\x19\x3e\xb8\x07\xec\xe2\x3f\x24\xab\x65\x95\xe9\x32\xc9\xce\x1a\x75\x9b\xf7\x88\x91\x4d\xb0\x08\xe8\x70\x98\xdd\x81\x46\x5e\x26\x10\x64\x7a\xc3\x8e\x08\x86\x66\xf6\x0e\xc5\xd0\xe2\x17\x33\x20\xa4\x0c\xd9\x85\xf0\xe0\x0d\xbc\x2b\x45\x70\x72\x74\x83\xa8\xc2\x5f\x6f\xc1\xe0\x93\xbb\x57\xcc\xaf\xd1\xca\x20\x2f\x29\x86\xc7\xc5\x54\x0a\x7c\x3e\x10\xc4\xa6\xfc\x26\xd1\xd6\x2c\x2c\xa5\xaf\x83\x05\xce\xeb\xe4\x2f\xf9\x6e\x7d\xc5\x48\x21\x43\x75\xe8\xa7\xf9\xf7\x12\xba\x8b\xd8\x75\xe4\x3c\xa1\x0c\xf9\xb1\x83\xf0\xc8\x51\x95\x12\x92\x85\x38\xa4\x78\xcb\x98\x25\x9b\xd8\xb3\xe3\x34\xbc\xc4\x63\x55\x95\xca\xd3"}, +{{0xe5,0x37,0x15,0xfe,0xc9,0xd3,0xb2,0x0e,0x9c,0x29,0x91,0xe5,0x4b,0x5e,0xb0,0xa8,0xcc,0x81,0x87,0x55,0x69,0xc9,0x5e,0x22,0xa2,0x00,0x13,0x60,0x02,0x17,0x60,0x04,},{0x53,0x51,0x89,0x9b,0x69,0xb2,0x11,0x6b,0xc7,0xf8,0xa8,0x81,0x4d,0x1e,0x5b,0x9f,0xc7,0x85,0x69,0x8b,0xeb,0xd9,0xab,0x14,0x27,0x7c,0x3e,0xcc,0x01,0xef,0x8b,0x1d,},{0x3d,0x0a,0xdc,0xe7,0x7a,0x4e,0x04,0x6f,0xcb,0x9b,0x49,0xad,0x5e,0x6c,0x68,0x09,0xc8,0xac,0x33,0x6c,0x73,0x34,0x04,0xe5,0xd3,0xf0,0x15,0xc9,0x22,0x5c,0x3d,0xf4,0x6e,0xf2,0x1e,0xa3,0x4c,0xff,0xb3,0xaf,0x69,0x97,0x4f,0x8b,0x7e,0xab,0x2d,0x23,0xfc,0xd5,0xa1,0xe1,0x75,0x3a,0x40,0x23,0xde,0xb3,0x81,0x86,0x29,0xa9,0x8a,0x0b,},"\x84\x31\xcd\x16\xd5\xc0\x93\x77\x5e\x18\xc0\x82\x52\xc4\x3f\x95\xb1\x01\x7e\xb7\x11\xfc\xaf\x73\xe1\xe0\x0c\x0c\xd6\xf3\x44\x87\x44\xab\x9b\x0e\x64\x33\x55\x18\xc4\x83\xae\x94\xde\xb9\x76\x77\xf8\x18\xf0\xe8\x1a\x74\x90\x61\x5b\x71\x41\xb9\xc3\x5f\x80\x55\x6e\x69\x71\xce\xa2\x8e\x9a\x32\xc3\x28\xcc\x26\x69\xfc\xa5\xb1\x23\xcb\x66\x2d\xeb\xab\x2b\x98\x15\x77\x64\x66\x80\x70\xe1\x8e\xdf\x76\x1a\xe1\x96\xbd\x4b\x24\x4f\xea\x7b\x74\x98\x45\x16\xbe\x2c\x00\x73\x9e\x76\xe6\xc4\xb6\x21\xcb\x39\x83\x76\x5a\x20\xd8\x47\x78\xd5\xa4\x35\x0b\x16\x8f\x6a\x0f\x71\x2a\x98\x20\xa8\x5a\x63\x6f\xaf\x92\xc7\x89\xc4\x28\xcf\xd2\x96\x2e\xd2\x07\xc3\xac\x88\x99\xc2\x58\xca\xc1\xad\xb5\x15\x9f\x76\x4b\xa3\x72\x29\xc5\xcb\xf7\x83\xfc\x9a\xa4\xd1\xea\x46\xec\xc8\x5f\xe0\x96\x14\x85\xd4\xfc\x5c\xb2\x1d\xf0\x01\x2a\xc9\xb9\x55\x37\x3b\x14\x22\xe5\x1a\xfa\x1c\x55\x09\x88\x86\x2c\x86\x13\x3b\x76\x0a\xa6\x30\xfc\x0a\xce\xe8\x98\x91\x17\xd1\xdd\x96\xe3\xe6\x28\x7b\x69\x28\x7c\x59\x0b\xdc\xa9\xcb\xc8\xee\xce\xf2\x81\xee\x6d\x1c\x8d\x88\x82\x2b\xfe\xa5\xfa\x0f\x53\x0f\x23\x27\x80\x93\xc7\xc8\x5a\x0d\x44\xc3\xa7\x74\x04\xee\x79\xf1\xc8\x36\x8c\xd7\x32\x1b\xf1\x48\xfd\xa4\xdc\xf2\xeb\x07\xe4\x63\x0e\xa4\x22\x58\x75\x86\x37\x17\x80\x51\x45\x36\xb8\x94\xc5\x24\xe6\xb8\x3d\x5a\x76\xa1\x5c\x83\xe9\x5a\xb3\x14\xe0\x7b\x34\xb9\x8c\xd9\x9e\x07\x70\xb4\xeb\x9b\x3f\x3f\x50\x5b\xae\x8a\x06\xf7\xf9\x50\x25\x8d\x79\x07\x48\x10\x71\x95\xeb\x4f\x6b\x84\x84\x0f\x8c\x05\x90\x72\x73\x96\xed\x14\xe3\xf5\x32\x39\x47\x6c\x4d\x2a\x72\x69\xb2\xe1\xf9\x72\xfb\xff\x33\xe4\x72\x44\x26\x74\x5e\xc8\x86\xa3\x29\x16\x29\x5e\x70\xd4\x68\xd0\x6c\x7d\xbb\x5f\xf9\xa3\x54\xe1\xac\x90\x3b\xb4\x5c\xa5\x26\xf0\x8b\x49\xa6\x5e\x82\x29\x7d\x8d\xd3\xfb\x25\xaa\x42\x8f\x64\x34\x5b\xca\x97\x40\xd9\x07\x8d\xac\x9e\x11\x38\xc9\x21\xbd\xd7\x48\x81\x67\x3d\x49\xd0\xcd\x20\x06\x81\x17\x23\xde\x28\x7c\x6c\x95\x83\xe4\x56\xa0\x1a\xb1\xa3\x4d\xfa\x1e\xaa\x96\x3b\x71\xe8\xbc\x7f\xa8\xa9\x8c\xad\x4f\x94\x1e\x4b\x37\xb6\x0e\xef\x92\x3b\x32\x94\x88\x23\x50\xb3\x8e\xa4\xea\xc0\xe9\x23\x2e\x93\xc5\x32\xdb\x5d\x7e\xec\x8e\xcf\xae\x65\xe0\x80\x47\x30\x78\x77\x7d\xdf\xdd\x11\x50\x8a\x6e\x59\xf0\xeb\xaa\x3f\x60\x44\x1f\x82\xa7\x1a\x73\xc8\x4b\xca\x06\xa3\x71\xff\x5c\x9f\x77\x21\x3a\x2d\xb7\x95\xd4\xa8\x89\x78\x23\xd8\x8f\xd9\x2a\xe3\xe0\x57\xe8\xbb\xd8\x0c\x99\x0a\xf8\x38\x6b\xdf\x26\xf1\x2d\x97\x3c\x8c\x5f\xf9\xed\x6f\x7b\x2d\x8e\x61\x83\xcf\x6e\x68\xf3\xbb\x89\x8f\x59\xa9\x3e\xc4\xde\x3b\xea\x60\x5a\x5d\x8b\x15\xdf\xab\x71\x3f\x35\x85\xc4\x8d\xc9\xa5\x76\x82\x42\xb3\x31\x01\x43\x80\x30\xe7\x04\x48\x80\xd1\x7c\x2e\xe8\x4f\x89\xd2\x6a\x1f\x7b\x19\x86\x19\x3f\x96\x63\xc5\x87\xd5\x0c\xa9\xdd\xf6\x18\x6a\x51\x76\xaf\xef\x1a\xdb\x24\x81\xb7\x92\x54\xb7\x8d\x3b\x34\xc6\x97\x90\xeb\x28\xb9\x0b\x14\x61\x17\x0c\x3d\x73\x81\x83\x76\xcd\xf3\x71\xaf\x0a\x0f\xea\xf1\x4f\xdf\x70\x16\xed\x6e\x7f\x08\xc0\xc1\x4b\x52\x70\x5c\x86\xd4\xf0\x00\x3b\x5e\x45\xf9\x74\xc0\x64\x16\xcc\xb5\xca\x3e\x9d\x52\x9a\xa9\xd4\x15\xc2\x5a\x44\x6f\xa2\xd6\x9e\x82\xf4\x99\x4e\x57\xe9\x22\xc1\x7c\x1c\x34\x2d\xd7\x28\x1e\x41\x00\x52\xd9\xe4\xaa\x1b\x30\x9b\x7d\x47\x0d\x45\x8c\x66\x3e\x17\xff\x25\x00\xd0\xbb\x8e\x46\xa9\xc4\x36\x7e\x09\x1c\xaf\x87\xdd\xfc\x06\x2a\xae\x08\xa6\x5c\xb9\xe0\xea\xa7\x1c\x99\x45\x9c\x5e\x7c\xb1\x12\xa2\xee\x98\xa5\xe4\xcb\xee\x0d\xc5\x20\xf8\x7c\x30\x22\xda\x65\x49\xbe\x1e\xe7\x0a\x0a\x73\xad\x84\x99\xc9\x7d\xd0\x6a\xa1\x4c\x9f\xd8\x62\x8a\x92\xca\x6d\xb4\x87\x32\x2d\xb9\x59\x8a\xda\x1f\xce\x28\xf4\xb9\xfc\x1d\x3c\xc3\x9d\xcf\x2e\xd1\xdf\x3d\x86\x2d\x87\xf5\x5c\xc1\x01\x6f\xb9\xe7\x3e\x7c\xc8\x97\xb9\x70\xd5\xff\x35\xac\xfe\xb0\x5c\x1c\x89\x19\x28\x08\xae\xeb\xfb\x2c\xd1\x7c\xb1\xc9\x4f\xab\x05\x98\x98\xfe\xdc\x2f\xbd\x44\xcc\xef"}, +{{0xab,0xfd,0x69,0x7b,0xfb,0xc5,0xb6,0xff,0x2b,0xdf,0xf3,0xbc,0xe1,0xd7,0x77,0xe0,0x5f,0xbe,0x3e,0xc8,0xb9,0x5c,0xe6,0x93,0xd6,0x23,0x93,0x12,0x09,0x31,0x3d,0x4f,},{0xa7,0x09,0x32,0x1a,0x02,0x10,0xcb,0x80,0xab,0x58,0xbf,0x95,0x5e,0xcd,0xeb,0x8a,0xaf,0x9e,0xe4,0xc3,0x75,0xf9,0x59,0xc5,0x30,0x89,0xd4,0x37,0x48,0x8c,0x08,0x2d,},{0x8c,0x36,0xb5,0xa1,0x11,0xc5,0xa8,0x11,0x9f,0x2d,0x9d,0xb5,0x7e,0xbb,0x59,0x2d,0xae,0x86,0xad,0x4b,0xf6,0x78,0xc1,0x49,0x2e,0x26,0xf3,0xc1,0x0f,0xbe,0x03,0xf1,0x05,0xca,0xe0,0xdc,0x68,0xb5,0x52,0x59,0xb9,0xb5,0x98,0x92,0x89,0xdb,0x33,0xd9,0x5d,0x2e,0xe6,0xb7,0x56,0xc7,0x60,0xf9,0xd3,0xaa,0x0e,0x68,0xa1,0x89,0xde,0x02,},"\x89\x6b\x7a\xb8\x41\x3f\xfe\x43\x9a\x2f\x44\x87\xec\x49\xd6\x4e\x31\xc7\x4f\x50\xac\x83\xf5\x5d\xa6\x1a\x70\x03\xaa\x71\x6c\x2a\x9d\xf6\xb4\x38\xe6\x2f\x53\xd8\xf0\x19\x2f\x37\x36\x32\x47\x60\xd7\xe8\xc4\x4a\xc0\xba\xca\x3a\xe2\xa6\xfb\x93\xf1\x3d\x96\x88\x67\x99\xfd\x2c\x45\x51\xb0\xab\x36\xf1\x73\x08\x55\x55\x12\x65\xa5\xa3\xc3\xc2\x1d\x95\x16\xa2\x37\xf5\xdb\xc1\xc8\xe7\x29\x99\xb7\x82\xc5\xca\x41\xa4\xf6\xe9\x30\x8e\x64\xaf\xde\xe0\xbf\x47\x9e\x54\x6b\x89\xc5\x1b\xc5\xe4\xf7\x1e\x57\xfb\x24\xce\x43\x7a\x8b\x81\xb9\x1d\xc7\x98\xb5\xab\x36\xf2\x9a\xfd\x5b\x48\xe8\x1c\x17\x6a\xe5\xed\xf9\x53\x71\xba\x32\x46\xfb\x43\x94\x05\xbd\x10\xee\xd3\x67\x8e\x3e\xc6\x23\x07\xa3\xb3\xdc\x1b\xad\xba\x05\x1f\x16\x77\x4b\x85\x08\x81\x88\xc2\xa9\xe3\x20\xa1\x61\x8d\x5f\x26\xce\x94\xee\x2b\x93\x3c\x30\x5f\x6d\x95\x84\x95\x8e\xea\x31\x56\xc3\xd1\xe0\xef\x39\xa1\x86\x27\x5e\xe6\x2c\x40\xf3\xc1\xac\xd1\x5d\x8b\xe6\xe0\x74\x35\x1f\x53\x49\xce\x3d\xf6\x95\x17\x50\x5f\x45\xfa\x06\xa8\x15\xc6\x9c\xa1\x8f\x45\x0f\x42\xb5\xcf\x4e\xbd\x99\x26\x84\x45\xe0\xf6\x81\x04\xa7\xde\xeb\x0a\x11\x5b\x81\x7b\x99\xe1\xa7\x3e\x0f\xa9\xd8\x7d\xb7\x1f\x8e\xc9\x4f\x87\x08\xc9\xbc\x2e\x62\x2b\x96\x33\x65\xeb\xcf\xb9\x7c\xfe\x73\x32\x63\x00\x70\xe9\x65\x4e\xaa\x60\x36\x1a\x45\xd4\x02\xdc\x0a\xb2\x97\x66\x52\x42\x66\x7f\xbd\x99\x40\xf6\xcd\x33\x19\x52\x46\xa8\xc2\x86\x9a\xf7\x59\xa8\x62\xd4\xb6\x41\xdb\x14\x4d\x57\x32\x36\x6b\x20\x63\x6c\x40\x27\x78\x7f\x55\x80\x27\xd7\x6f\xcb\xf8\x43\x2e\xb9\x3e\x6d\x14\x56\x7d\xf8\xdb\xf2\x11\xda\xeb\x56\x55\xdb\x10\xac\xdd\xd0\x5e\xca\x06\xac\xce\xe9\xfd\xa8\xd3\xb7\x0c\xa1\xe6\xdc\x58\x7f\xa4\xb7\x8f\x63\xcd\x66\x3f\xf0\x24\x38\x70\x57\x0f\x4d\xcb\xaa\x3f\xb6\x26\xb4\xe1\x13\xbd\xe4\x7d\x5c\x9d\xb2\xb4\xba\x6e\xc6\xdb\xf9\x18\xac\x05\x69\x49\xef\x3c\xfc\xb1\x15\x56\x16\x15\x77\x1a\x03\x5a\x43\xd3\x3b\xa2\x65\x1d\xbe\xb4\x63\x48\x26\x1c\xe3\xc4\xc9\xf2\x46\xd2\x3f\x94\xdb\xc2\xd0\xc1\x9b\x92\x1e\x24\xc7\x7d\xa5\x99\x2f\x1b\x4b\xdf\x2e\xde\xa4\x99\xf5\x41\x11\x68\xac\x0c\x12\xe9\x6f\x3b\x15\xd2\xe1\x2a\xc8\xd7\xb3\xed\x8d\x1e\x07\xc4\x26\x7a\x25\xd3\xa3\xc3\x53\xa4\x20\x8b\x74\x06\x27\x8a\xab\x9e\x70\x0f\x7b\x20\x6f\x48\xe6\xea\x7c\xc9\x7e\x55\x4f\x15\xc9\xbe\x34\x9d\xd9\x15\x14\xdb\xe8\xd8\x89\xf2\xdc\xbb\xfa\x18\x2c\x9f\xaf\x58\x07\xa6\x9b\x2e\x97\xfa\x77\x1a\x6f\x23\x1a\x4c\x7b\x31\xd1\x17\xb8\xed\x0e\x63\x0c\xdf\x13\xe0\x82\xbb\x4f\x63\xc3\xf9\xac\xb3\x55\x32\x04\xcc\xd7\x6e\x18\x35\xc4\x6e\xec\x3d\x43\xc5\x61\xbb\xf1\x7c\x92\x21\x4a\x6d\xb1\x21\x2b\x60\x03\xcf\x2c\xc2\x6c\x7a\xe6\x75\xfc\xd0\x53\xb9\x47\xe7\x22\xf9\xe8\x57\x62\xce\x8a\x16\xe4\x65\x4e\xc6\x34\x2f\xc6\x46\xe5\xca\xb4\x72\x79\x7e\xab\xf6\x58\xba\x4a\xfd\x14\x2f\xc8\xfc\x4c\x8f\x98\xf2\x3c\x24\xdc\x99\x84\x7a\xe8\xce\xf0\x87\x9e\x1a\xb3\xbb\x80\x97\xe4\xc3\x52\x9a\xdd\x2d\x8e\x8e\x2c\x20\x69\x21\x0f\x50\xac\xe1\xae\x32\xa6\xc8\xe6\x38\x4a\x2b\xf7\xd7\x9c\x66\xc7\x46\x14\x9c\x84\xad\x75\xa3\xa1\x76\xe4\x5e\x13\x6d\x94\x69\x5a\xed\x4b\xfd\x08\xb4\x26\xea\x8c\x4b\x93\x79\xf3\x74\x25\x50\xe1\xcf\x5a\xc8\x4c\x18\x17\x4d\x68\x0e\x92\xaf\x2c\x18\x74\xac\x1c\x13\xd2\x82\x32\xde\x19\x37\x68\xe5\x61\x94\x7c\xbd\x6b\x79\xe9\xb9\x9d\xa6\x5c\xfb\x74\xff\xb3\x2f\x7d\x3d\x20\x25\xc6\x07\x63\xdc\x07\xf5\x55\x39\xb4\xd2\x53\xde\x1e\x6c\x25\x82\x3a\x62\x58\xc7\xa9\xce\xd1\x50\x1d\xce\x27\x86\x89\x8a\x3e\x05\xc9\xbf\xf8\xfc\x5b\x21\x25\xd0\xf4\x71\x08\x8a\x13\x4b\x48\x73\xc8\xd5\x5c\x04\x45\xf6\xca\x39\x6b\x3d\x7b\x4b\xc2\xbf\x5c\x4d\x22\x40\xda\x41\x82\x93\xaf\x6a\x3e\xd8\x53\xde\xdd\x3b\xf6\x68\xd9\x37\xb3\x5a\xa0\xc2\xac\xbf\x23\x76\x6f\x9f\x3e\x96\x82\x84\x75\xab\x08\x64\x96\x61\x7a\x6e\x81\xd6\x53\x58\x9b\x2f\xe5\x0b\x7b\xa8\xf0\xcf\x1e\x5a\x44\xd8\xd6\x2f\x08\x37\x7a\xbf\xc2\x62\x97"}, +{{0xdc,0xfa,0xd5,0x9f,0xc6,0xb6,0x97,0x10,0x9e,0x72,0x7f,0xf6,0x6a,0x5f,0xe9,0x3a,0x6a,0x22,0x6f,0x63,0x1a,0x64,0xe5,0x79,0x7a,0xd8,0xd8,0xc8,0xb6,0x35,0x87,0x34,},{0xe7,0x9f,0x4f,0x51,0x13,0x72,0xe3,0x55,0xe7,0xe9,0xe0,0xe8,0xb5,0x34,0x6f,0xdb,0xcd,0x2d,0xf1,0xfc,0x5c,0x3a,0x18,0x90,0xd2,0x7f,0xa1,0xfa,0x92,0x8d,0x27,0xa6,},{0x05,0x2f,0xf7,0x95,0x40,0x73,0x74,0x56,0xc6,0xa4,0x2c,0x41,0xc9,0x7d,0x6b,0xf5,0x17,0xb8,0xcf,0x28,0x9b,0xc7,0x8b,0x50,0x3d,0xee,0x6a,0x30,0xef,0x51,0x68,0xb3,0x8f,0x75,0xbe,0xac,0xa1,0xe1,0x4d,0x97,0x1f,0x87,0x73,0xe3,0x94,0x1b,0xd6,0xdf,0x5c,0xb9,0x77,0x8d,0xea,0x12,0x5a,0x4c,0x4f,0xe0,0x11,0x6b,0x70,0xee,0x84,0x0b,},"\x7d\x92\xdd\xd8\x13\x3c\x61\xc6\x10\xc1\x30\x8c\x23\xae\xaf\x99\x38\x84\xa4\xe6\x7f\x7b\x94\xbb\x88\x6d\xad\x50\x98\x69\xa9\x32\xec\x4a\x27\xd4\x10\xd2\xc2\x9c\xa7\xae\xae\x6f\x92\x80\xcf\x6c\x4b\x06\x7e\xc7\x51\xe5\xe8\xc3\x9f\xf4\x44\xd4\x22\xce\xab\xae\x14\x5d\x42\xf0\x47\x45\x3d\xd4\x02\xd1\x79\x74\x05\x03\x34\x09\xe7\x2c\xc1\x9f\x79\x3d\x5d\x26\x8f\xb3\xfd\x2c\x11\xea\x2c\xb0\xd7\x04\x36\xe1\x8f\x9e\x88\xa0\x15\x15\xdc\x86\x5f\x6a\x1e\xb2\x36\x90\x32\x8f\xd7\x5d\xe2\x63\x21\xa3\x8f\x12\x19\x7a\x97\x20\x1b\x1d\x84\x52\x94\x4f\xbc\x54\x1c\xb6\x8c\x77\xd4\x95\x15\xdb\x53\x26\xf2\xb1\xd0\x76\x3e\xda\x06\xd2\x50\xce\x2a\x5e\x0b\xbd\x7d\x16\x76\xd7\xd4\x1f\xb3\xab\xe8\x8b\xdb\xe3\x72\xf9\x6b\xf7\xbb\x52\x6d\x6b\x65\xa2\x51\x5e\x83\xa5\x77\x04\x5b\x54\x79\xb3\x8b\x85\x2f\xe4\xab\x01\x1c\xbf\x21\xc0\x85\xef\x5f\x0a\x7c\x1b\xed\x76\x57\x2b\x0f\x86\x02\x28\x06\x7a\x89\x9f\x89\x5a\xe7\xf6\x25\x6e\xb6\x51\x40\x87\xf9\xd6\xf5\xc3\x55\x96\xc1\xf4\x80\xc7\x31\x13\x54\x6c\xb9\xcc\x30\xf5\x6a\xb0\x74\xa9\xff\x28\xac\xab\x7e\x42\x65\x0a\x96\x1d\xa3\x25\xac\x5b\x65\x94\xb8\x1c\x93\x25\x0a\xe7\xd3\x92\x67\xa1\x9c\x97\x62\x54\x07\xed\xda\x04\x04\xcb\xe5\xa3\x6e\x95\x9f\xc8\x20\xb2\x7e\xf5\xca\xd7\x96\xc1\x1e\xaf\xf1\xc0\xe2\xf9\xd4\xb3\xc6\x49\x15\x02\x19\x5d\xe0\x36\x59\xb3\x64\xe4\xe8\x7b\x2b\x2d\x73\x3e\xc2\x5e\x6f\x9b\x63\xd5\xf6\x91\x79\xe0\xd2\x7b\xd4\xae\xcc\x8f\x12\xa5\x07\xa9\x1b\xaa\x48\xd9\x9b\x3a\x42\x6c\xec\xeb\xae\xf3\x7d\x73\x61\x10\x6a\x84\x90\x64\x43\x09\xf6\xeb\x4d\x25\x96\x44\x3b\x6b\x01\x18\xb9\x45\xac\xec\xc6\x44\x3e\xa6\x1f\xcd\x15\x5b\x54\x32\x5b\xc2\xc3\x1b\xe0\x25\x0f\x94\x82\xe1\x3f\xd8\xeb\x44\xe2\xae\xd7\x6b\xe8\x12\xaf\x54\x53\xcb\x7f\x86\x32\x45\x8f\xc8\xa0\x2a\x2f\x45\x48\x0d\x79\xb0\x6c\x7d\xda\x38\xb4\x69\x5d\x08\xb5\xa4\x30\x50\x4f\x1a\xe2\x27\x5b\x05\xc9\x1e\x79\x9d\x44\x70\xf3\x8a\xbe\x77\x73\x6d\xfa\x89\x5c\x19\x7e\xa4\xb6\x3c\x2d\xf1\x8e\xfe\xb1\x41\x84\x83\x7b\x8d\xdf\x48\x90\x95\x20\xd9\x10\x45\xb9\xd9\x65\x5c\x22\x5a\x83\x17\x39\x60\xb4\xd7\xcd\x0d\x8b\xae\x30\x23\x75\x57\xf8\x69\x70\x8b\xe1\x38\xad\x52\x46\xc8\x66\xc6\xc0\x59\xdc\x59\x7a\xbf\xd4\x94\x32\x37\x37\x68\x96\x73\x6b\x97\xb7\xe0\x28\x9e\xf9\xbb\xd2\x94\x77\x74\x5c\xb6\x0f\x46\x20\x2f\x1d\xe9\x84\xf5\x09\xb1\x80\x88\x33\xf5\x80\x18\xcd\xe8\xc2\x6b\xef\x4c\x00\x5b\xdc\xa3\x85\xb0\x57\x35\x11\x0c\xa0\x2e\x56\x2b\x50\xed\xdf\xf6\xfd\xe9\xfb\xb8\xd0\x30\xce\xdf\x70\x31\xbb\xeb\x32\xb1\x2b\x24\x2b\xe4\x9f\xde\x01\x60\xc1\xfb\xde\x99\xb0\x3c\x06\x2a\x1a\x47\x06\x23\x45\xc9\x2e\x0b\x60\x4d\x08\x0f\xac\xce\x92\x43\x48\x15\x29\xc7\x05\x97\xdf\xd6\x43\x82\xcb\x54\x06\x91\xb5\x9b\x71\xb0\x94\x33\x2b\xaf\x0b\xbb\x12\x5b\x63\xa4\x46\xbb\x97\x49\x1c\x04\x64\x32\x8c\xab\xd7\x62\x7c\x46\xf3\x92\xf3\xb1\x24\x82\x2f\x20\x13\xc6\xe1\x6d\x3c\xa8\x7c\xc5\xbe\xcf\x56\xb0\xfc\x6e\xb2\xbf\x99\x23\xb3\x01\x2b\xa2\xb6\x12\x50\xa6\x33\xa4\xd2\xee\x39\x12\x56\xc5\x20\x95\x73\x82\xaf\xf9\x70\xc5\xd2\x23\x85\xc3\x34\x4c\x6d\x4b\x45\x61\x57\x1c\x96\x32\x9b\xf7\x56\x15\x29\x75\x16\xb9\xf2\xce\xb9\xf9\x97\xa3\x95\x23\xaa\x0f\x58\xb4\x88\x77\x2d\x82\xfc\x0d\x78\xc5\xdd\x52\xec\xfa\x6b\xfa\xc6\x3a\x76\xe1\x48\x08\x8b\x36\xf2\x4a\x88\xe6\x83\x85\x49\x6d\xda\xdf\x30\x23\xf7\x2d\x87\xc2\xef\xa2\x6e\x87\x7d\x32\xf1\xda\x97\xcd\xb4\x2c\x8f\x15\x71\x89\x88\xe4\x28\xcd\x02\xf4\xd0\x95\x43\xbd\x0b\xd5\xb2\xf4\x09\x96\x3d\x0f\xa3\x73\x53\x1f\x78\xb5\x92\xbd\x13\x7e\xea\xea\x0b\x4e\x7f\x91\x82\x08\xe1\xd5\x90\x08\xa8\xaf\x50\x58\xf5\xd9\x23\xc4\xf3\x2d\xf1\x99\x90\xf1\x0d\xd3\xf0\xeb\x20\x62\x93\xb2\xb3\x44\x3f\x4a\x5d\x2d\xcc\x5f\x7d\x3b\xba\xf6\xaf\x43\xfe\x45\xf5\xdb\xbe\x53\xec\xf4\xbf\x1b\x4a\x13\xe2\xd4\x6e\xf8\x02\x98\xd4\xf0\x1c\x40\x2e\x21\x0f\xcb\x9f\xf2\x08\x4e\xc0\x3e\x42\x00\x8d"}, +{{0x69,0x6d,0xc4,0x81,0xf6,0x19,0xa9,0x49,0x85,0x63,0xc8,0x3d,0x0d,0x0e,0x55,0x56,0x5c,0x14,0xa0,0x78,0x45,0xfe,0x4a,0x66,0xab,0xa2,0x24,0x7b,0x11,0x3f,0xf8,0xef,},{0xc9,0xd7,0x37,0xab,0xc4,0xa9,0xe7,0x3c,0x14,0x9e,0xad,0xc1,0x95,0xa8,0x37,0x89,0x9f,0x2c,0xd5,0x01,0x93,0x73,0xc3,0x0e,0xca,0xf6,0x2e,0x5f,0x8e,0x14,0xb6,0x45,},{0xde,0xd5,0xd9,0x91,0x93,0x5c,0xd1,0xf9,0x39,0x0f,0x1e,0x85,0x92,0x9c,0xa1,0x6d,0xab,0xfc,0x83,0xe6,0x5e,0x43,0x27,0x2e,0xb1,0x75,0x16,0x71,0xaa,0x31,0x93,0x0c,0x72,0x85,0x55,0x34,0x14,0x30,0xce,0x7c,0x80,0x48,0x5d,0xe5,0x80,0x06,0x42,0x71,0x29,0xa4,0xd3,0x4f,0xd6,0x81,0xd5,0x2d,0x84,0x0a,0x16,0xba,0xfa,0x15,0x30,0x02,},"\x2d\x4b\x3a\xd0\xcc\x99\xf9\x83\xe4\x1f\x9b\x48\xc4\xa8\x18\xef\xf7\x5f\xcf\xb9\x3a\x12\x29\xec\x27\x40\xed\x19\xc1\x07\xd6\x21\xdf\x78\x05\x8d\xe7\xc2\xdd\x72\x51\xf5\xff\x45\x43\x40\x86\x5f\x6c\x86\xda\x65\x83\x1f\x66\x72\xdb\x23\x17\x26\xfd\xfe\x4b\x9e\xe3\x15\xd9\x3c\x72\x44\xa9\x20\xdf\x37\x05\x4c\x82\x44\x9d\x31\x0f\x89\x29\x32\xdd\xba\xd9\x4c\xc9\xbb\x39\xac\x89\x37\xcc\x76\xc9\x65\x21\xd3\xfd\xc0\x28\xba\x23\x41\x0b\x29\x02\x3e\x81\x38\xfd\x3f\x52\x43\x19\x88\x4e\xe5\xda\xd0\xd2\x34\xc8\xdf\x66\x1f\x88\x24\xbe\x47\x7e\x21\x69\x9f\x63\x69\xb1\x5f\xf3\xff\xef\xc1\x51\xaa\x55\x5b\x3c\x3d\x76\xad\xb4\x5f\x25\x67\x2d\x38\x0d\x47\x2b\x31\x48\xda\xbd\xef\x42\x45\xb6\x8e\x82\x85\x62\xf2\x5c\xc5\xb8\x1d\x9b\xbb\x24\x1b\xca\x9d\x19\x34\xea\x35\x3f\x95\xf7\xdb\xf3\x64\x64\x33\xe8\x1a\x35\x4e\x1e\x20\x56\xb8\x1c\x15\xaa\x1f\xa8\xed\x7a\x9d\x1a\xf9\x92\x38\xcd\x5a\x5a\xe9\xe8\x41\xc4\x8d\xc3\x48\xae\x1d\xe7\xc4\x1a\xca\x23\x32\x82\x36\xbc\x38\xb4\x7f\x47\xc7\x36\xb2\x57\xa3\x07\x8d\x57\xd5\x74\xb6\x47\xa7\xfc\x8c\x4d\x01\xbc\x50\x30\x21\x50\xd5\x03\x2b\xfa\xcb\x04\xbb\x0f\xd1\x55\xd9\x4d\x92\x06\x66\x77\x20\xe1\x80\xa6\x45\xaf\x46\x24\x59\xe3\x32\x6d\x46\x0d\xa3\xc4\x8e\x75\x72\x67\x8e\x19\x19\x26\x8d\x3e\x47\x40\xd6\x2a\x26\xf7\xc8\x55\x9c\x1c\x43\x9b\x4b\x0b\x0c\x59\x42\xa6\x20\xcf\xdb\x93\xcc\x68\xaa\x15\x52\x0f\xf2\x86\x42\x69\xd7\xa0\xc1\x55\x78\x0a\xdc\x6c\x18\x8e\x0b\x56\x5f\xb9\x59\x43\x19\xe6\xf5\x1d\x15\xca\xf6\xb2\x80\xe7\x15\x8f\x25\x79\x94\x07\xf3\xba\x0d\xd1\xce\xea\x64\xb9\x32\x6d\x2c\xfd\xef\x01\x7e\x1f\x17\x2f\x4d\xde\x0f\x7e\x46\x13\x50\x1a\xf0\x1e\xe0\xac\x30\x09\x5f\x48\xb5\x95\x90\x90\x2b\x1a\xec\xfe\x09\x34\x13\x91\x8d\x83\x5a\xdf\x96\x2e\xcf\x18\x58\x0d\x16\xf9\xfd\x4f\x6f\xa1\x09\x8a\xf1\xd8\xa2\xbc\x24\xdc\x86\xf7\x1d\x0a\x61\xff\x15\x00\x10\x86\x7d\x08\x69\x87\xb5\x1d\xd0\x30\xf5\x0a\xb6\xe3\x74\xb8\xe0\x11\x84\xb3\xe2\xb2\x14\xab\x1c\x7f\xdf\xae\xdb\xc5\x45\xe3\x8c\x3c\xd2\xf6\x98\x29\x79\x54\x1f\xe0\xff\x88\xbe\xd6\x75\x06\xda\x95\x72\x7a\xf1\xa2\x03\x8f\x32\x40\xae\x5b\xfd\x30\xee\x09\x21\x0e\x00\xfd\xcf\x2a\x06\x4d\x5d\xb4\x61\x49\x46\xbd\xa9\x72\xc6\x70\x08\x1a\x6e\xe6\xa1\x0b\x63\xf6\x73\xc8\x3c\x91\x5c\xa5\x57\x3e\x0e\xd6\x87\xb0\x06\x7c\x40\x07\x92\xa9\xbc\xc3\x34\x4e\x0e\x43\xf5\xdf\x63\xfe\xd5\xef\xa8\x5e\x9a\xaf\x85\xe4\xd7\xa2\xc5\x3a\x6c\x92\x82\x8e\x07\xfe\x63\xe2\xd2\x3f\x1b\xdf\x97\xd8\x4a\xdc\x36\xe9\xfc\x95\xfa\xad\xf0\x3e\x06\xd6\x5a\x19\xc5\xe2\x85\xef\xfd\x0e\xa0\xcf\xa8\x39\xd5\x5a\x0a\x0d\xbf\x6d\xa2\x87\x85\xc7\x7f\x5c\x04\xbf\xd5\x99\x74\xef\x37\x93\xcd\xc3\x98\xdf\x7a\x1b\xbc\x9c\xfc\xfc\x3a\x51\xff\xa9\xa2\x0d\x60\xc4\x7b\x24\x5d\xaf\xa3\xe4\x46\x23\xcd\x71\x1d\x77\x62\xc5\x0a\x67\xd6\x50\xc7\xe8\xc4\xfd\x3b\xeb\xc0\xc4\x98\xd2\x15\x2a\xb9\x82\x7c\x70\x0c\x7b\x28\x61\x56\x57\x49\xb5\x86\x4f\xec\x95\xb7\xf6\xb1\x99\x4e\x78\xd8\xf8\x5d\x06\x9c\xc1\x1f\x85\xbe\xd9\x71\x2f\x7a\x9f\x06\x0b\x0b\xf6\x75\x32\xe8\x8e\xb9\xdf\x3e\xb4\xa8\xd2\xfb\xba\xa8\x5e\xda\x92\x6d\x81\xc4\x9f\xb8\x6e\x73\x73\x1b\x7e\xd2\xa1\x90\x50\x78\x51\x3f\x7c\xa0\xfd\xcc\x3b\x1d\x57\x6e\x6a\x60\x12\x4c\x44\x61\x8d\xf1\x89\x0e\x16\x97\x94\x95\x6c\xb1\xec\x50\x1b\xa2\x04\x99\x70\xc8\xe7\x4c\xc1\x80\x06\x4c\x18\x44\x68\xbe\x4f\x08\x9a\x3a\xe2\x26\x3c\x85\x58\x63\xb6\x2c\x28\x31\x3d\xdf\x9c\xa8\x5b\xf6\x6b\x08\xa2\x64\x15\x5a\xd7\xc3\x28\x23\x8d\xfe\x61\x4a\x07\xed\xe9\x15\x5a\x09\xcc\xaf\xf9\x22\x92\x24\x93\x41\xba\xed\xcb\xe0\xe6\x46\x6e\x2c\x76\x04\x5e\x46\xda\xd2\xfc\x89\x9a\x17\x82\xe0\x09\x98\xe7\x9a\x83\xab\xfa\xe9\xb7\x06\xf7\x07\xf5\x8e\x73\x02\x03\xe1\xd2\xcc\xa0\x28\xc9\x22\xbe\xb6\xd1\x57\xfa\x7a\x98\x13\x2a\x92\x1a\x3d\xa2\x1f\x2f\x76\x9b\xb6\xc1\xf5\xf1\x9e\x9e\x85\xa1\x3b\x78\x1a\xf1\x41\x03\x9d\x51\x4e\xe1\x07"}, +{{0xf3,0xf8,0xd6,0x2f,0xee,0x3a,0xf3,0x75,0x66,0x96,0x30,0xcb,0xf0,0x63,0xbf,0xa9,0x30,0x18,0x9a,0xf1,0x36,0xcd,0x75,0x91,0xe2,0x4d,0x57,0x8d,0x73,0x66,0xbf,0x61,},{0x47,0x14,0xc6,0x04,0xaa,0x95,0xe1,0x82,0x8a,0x28,0x36,0x7b,0xa7,0x87,0x60,0xb5,0x89,0x64,0x31,0x68,0x3e,0xe9,0x96,0xcf,0xf9,0x68,0x71,0x77,0x32,0x91,0x95,0x3c,},{0x8d,0x6f,0x7c,0xee,0xb9,0x30,0x8b,0x4a,0x30,0x38,0x79,0xfc,0x6c,0xfa,0x5c,0xa8,0xe0,0x5d,0xfc,0x3d,0xef,0xc2,0xb2,0xcd,0x29,0x10,0xdd,0x4b,0x17,0xc9,0x4e,0xae,0xe8,0x45,0xab,0xe6,0x5f,0xd7,0x15,0xdf,0x05,0xb0,0x12,0x8e,0x43,0x16,0xe2,0x33,0x47,0x99,0xc6,0xe8,0xfa,0x74,0x7e,0xbc,0x8a,0x04,0x0c,0x74,0xf5,0xa1,0x48,0x0c,},"\xe1\xdd\x1f\xfd\x73\x7a\xc6\xdc\x24\xb3\xb9\xce\x3b\x79\xe8\x35\xbf\x69\x8e\x93\x13\x03\xd8\x09\xce\xa1\x78\x2d\xc3\xaf\x63\xa0\xd5\xe6\x73\x92\x82\x3d\x14\x39\xe7\xb6\xe3\x37\xb0\x1c\x8b\x21\x54\x34\xc2\x78\x2b\x3b\xe7\x44\x3c\xb5\xc8\x81\xe5\xfb\x6c\xf3\xbb\x24\x41\x28\xb4\xda\x6a\x6f\x42\xb2\xbb\x2c\xd7\x51\x29\xd5\x64\x18\x85\x43\x48\xc3\x39\xdc\xd9\x12\xb4\x55\x57\xa9\x15\xe9\xfd\x7f\x37\x91\x62\x36\x51\x0c\xb6\xc3\x31\xc1\x40\xb8\x7d\x22\x53\x11\x60\x0b\x8d\x13\x2a\xc4\x74\x73\x83\x9c\x72\x0f\x9f\xf0\xf9\xc1\xdc\xaa\x85\x81\x5a\x9d\x27\xb9\x75\x8c\xd9\x1d\xc5\xd3\xe5\x33\x26\xfc\xdf\xb2\x73\x0e\x52\xbe\x31\x03\x95\x7a\xc8\x91\x49\xa4\xc3\x00\x4c\xb6\x03\x8c\x0d\x80\xfa\x72\xac\x63\x0d\x33\x3b\xe5\xad\x4a\xdb\x58\x5a\xeb\x71\xae\xf1\xcd\xfd\x57\xb9\x15\xfa\xc4\xf1\xaf\x78\xe7\xa5\x97\xf8\xd1\xba\x06\x67\x2b\x19\xc0\xb6\x58\x08\xa8\xa0\x71\xff\x84\x09\x03\x43\x79\x58\x9f\x3d\x41\x30\x2d\x2d\x39\xb3\x31\x8e\x8c\x00\x90\xfa\x36\xcb\x95\x88\x57\xff\x5b\x21\x1c\x96\x66\xe2\x7b\xc8\x95\xab\x9d\x00\x6a\xba\xf5\x95\x0a\x03\xff\x17\xea\x98\x21\x78\xa4\x46\xdd\xa2\x46\x6f\x5a\x40\xb8\xf8\x95\x50\x9e\x4f\x4d\x4a\x6a\x27\x39\x99\x7f\xbd\x49\x68\xf8\x94\x36\xce\xe3\xd8\xed\xb8\xa6\xda\x9b\xd3\xd5\x5b\x06\x64\x90\xe8\x33\x9c\x78\x93\x5b\x77\x88\x3f\x95\xb9\x32\xfa\x5e\x6b\xb7\xdf\x30\x3b\xe3\x0f\xa5\x67\x24\x9f\xff\xb4\x73\xa1\xe4\x64\x32\x2d\x7c\x10\x3f\xe8\x22\x4c\x7e\xc5\x7b\xd3\x9b\xcd\x03\x0b\x96\x78\x7a\xeb\xcd\x20\xe9\xad\x65\x1c\xfa\x2b\xf0\x4b\xa7\x0a\x1c\xf6\x48\xe0\xa5\x44\x95\x67\x20\x2a\x93\x7a\x45\xbe\xcb\xb6\xfc\xde\xd3\x0c\xf9\xb5\xc7\x48\xf8\x82\xb5\xdc\x2a\x4d\x65\xbe\x69\xfd\x7d\x9c\x38\x1e\x83\xd0\xdc\x2a\x34\xb6\xde\xe9\x12\x20\xba\x90\x6e\x51\x2f\xcd\x63\x36\x8e\x2c\xe7\x33\xe4\x66\xb4\xb8\x2b\x84\xfb\x0c\x71\x7d\xc8\x94\x5c\xaf\x6d\x46\xac\x1c\x2f\x64\x18\xf7\x72\x9e\xf4\xc3\x5e\x40\x24\x22\xd6\x4b\x1c\x3e\xbd\x1b\x32\xa3\x0f\xc4\xc5\xee\xce\x7d\x44\x08\xff\x67\x9f\xf0\x1a\x1c\x7b\x03\xca\x51\x7b\xe5\x2e\x6a\xe7\x65\x0f\x7b\xad\x38\x90\x1e\x34\x8a\x55\x93\xbc\x99\x8f\x7c\xf2\xea\x97\x72\x9c\xb0\x04\xf5\x61\xb3\xb5\x8f\xe5\x98\x09\xa4\x1f\xd4\xb3\xb7\x66\x60\x90\x6a\xd9\xed\xa2\x3b\xf9\x25\x43\x7e\xf4\x52\xb1\x6f\x54\x0b\x3b\x80\xa3\x5a\x70\x93\xc2\x73\x4e\xef\xe6\xfa\x97\xd8\x81\xd7\x9e\xf5\xb7\x67\xd9\x88\x9f\x11\x84\x77\xb7\x3f\x58\xa4\xc0\xcb\x15\xe0\xac\x81\x01\x12\x05\x71\xca\x32\xce\x87\x1f\x30\x8a\xd9\x05\x7a\x80\xc8\x28\x15\x4f\xb1\xbc\x2b\x20\x1d\x0c\xd1\x00\x6e\x02\x2d\x44\x4d\xc9\x3f\x1b\xcf\x22\x4d\xb7\x4a\x5b\x37\x3e\x15\x3e\x85\x18\x54\x94\x8b\x6d\xa1\x47\xb7\x32\x87\xcf\x17\xd1\xfb\x72\xb4\x82\x76\x11\x10\x36\x09\xca\xb2\xa1\x77\x9e\x97\x93\xb9\xa7\x08\x20\xfc\x6f\x38\x28\xa6\x4c\x9e\xac\x35\xef\x7a\xa7\xb1\x76\x09\xd8\xef\xf8\xa9\xe5\x2e\x4e\xbc\xd8\x6b\x1e\x14\xfd\x14\x0b\xea\x47\xc6\xb8\xdd\xc4\x1e\x8c\xd2\x71\xeb\x92\x28\x7c\xbd\x06\x10\x51\x22\x42\xf7\x6a\x1e\xf3\xea\xc1\xe4\xbb\xbc\x1a\xda\xe5\x00\x34\xa7\xa2\x64\x7e\x08\xb2\xfd\x20\xaa\x93\xa9\x3c\xb2\xff\xde\xbf\x2e\x46\x1e\xcc\xef\xbb\xd1\xfe\x89\x4c\xe7\x0a\xdf\x79\x01\x73\xba\xe9\x6f\x5a\x55\xa1\x88\x7e\x9a\xe0\x9f\xce\xd1\xd4\x30\x6c\x29\x1c\x6b\x19\xec\xac\x47\x07\xe9\xef\x71\x3e\xa1\x8a\x75\x62\xc6\x67\x83\x26\x22\x89\x92\x07\x7a\x46\x69\x73\x49\x66\x10\x80\x00\xb4\x14\x4f\x45\xa0\xc3\xa2\x86\x3a\x4c\x6a\x3c\x07\x63\x2c\xb9\x3e\xb1\x97\xd2\x94\x88\x4d\x9c\xa3\xdd\x4b\x21\xf3\x9d\xb7\x07\xf6\x3a\x7f\x9a\x57\x0f\x7f\x0f\xeb\x99\xb2\xca\x7d\xa7\xdf\x92\xa1\x77\xab\xcf\xe8\x6e\xc6\x61\xd3\x0b\xcd\xcf\x15\x22\xbd\xb1\xfe\x11\x67\x32\x58\xdf\x7e\x46\xef\x4d\x32\x66\x65\x09\x31\x56\x55\x3f\x28\xb3\x56\x3f\xe7\x19\x2f\x72\xf5\xf9\xb3\x90\x3d\x79\xfe\xa0\x4e\x2c\x48\x8b\x46\x5b\x49\x78\xd6\x9f\x26\xe0\x5a\x59\xd5\xed\x4e\xf4\xca\xb2\x32\xac\xfd\x56\x4f\xc6"}, +{{0x86,0x5a,0x43,0x2e,0xcc,0xe7,0xe7,0x8c,0x42,0x70,0x9f,0xc1,0xe5,0x31,0xdf,0x5e,0x39,0x59,0x13,0x2b,0x2b,0x6f,0x31,0x8f,0xd1,0xc3,0x45,0x21,0xf9,0xa2,0x6e,0x3b,},{0xc7,0xa8,0xca,0xf8,0x93,0x0b,0x62,0x2a,0x50,0x13,0x37,0xf9,0x28,0x40,0xed,0x96,0x61,0x1a,0x32,0x20,0x80,0xfd,0xe5,0xe4,0x9f,0x0a,0x2f,0x6e,0x33,0xb8,0x82,0x83,},{0x32,0xbb,0x75,0x20,0xe2,0x63,0x9c,0x6c,0xca,0x19,0xa2,0xb9,0x83,0x6b,0x08,0xf8,0xb0,0x83,0xca,0x33,0x36,0x9d,0xdf,0x5f,0x9a,0x87,0x7d,0x4c,0x7a,0x9e,0xb0,0x5f,0x9c,0x3d,0xc3,0x4e,0xd4,0xcf,0xa4,0xb2,0x83,0xe5,0x19,0x22,0xb0,0x94,0x06,0x6c,0xe9,0xff,0xa4,0xd9,0xdf,0x62,0x19,0x10,0xca,0x37,0xb0,0xb3,0x7f,0xba,0xbb,0x0e,},"\xb2\x31\xb6\xd2\xec\xde\x49\xf5\x13\xb0\xdf\x25\xaa\xfc\x3e\x5d\xa4\x5b\x6a\x99\x58\xd6\x0f\x54\x64\xca\x59\x3c\x03\x00\x5e\xcf\x36\x1e\xf1\x69\x6b\xb6\xe5\x5d\x65\x38\xe3\x4b\x38\xf3\x24\xc2\x1c\xea\x5c\xc8\x1a\x00\x73\x27\x8b\xb9\x27\x27\xef\xf8\x1a\xf5\x61\x80\x2d\xce\xf3\x3b\xec\x10\xad\x65\x94\xe2\x2d\x9c\x44\x18\xaf\x39\x88\xa4\x3e\xd0\x87\xb9\x95\x4b\xf8\xd6\x28\x3e\x4b\xea\xe8\xc0\x96\xde\x66\x06\x75\x1c\xbe\xd6\x85\x84\x6c\x66\x30\xb9\x52\x8f\xf3\x64\xa7\xc4\x84\x64\x11\x34\x72\xc9\x86\x0b\x33\x71\x96\x3c\x91\x14\x95\xa9\xc6\x28\xa3\xe3\xe4\x7a\xb0\x99\x1f\x10\xdd\x1d\xd3\x31\x61\x52\x52\x62\xd6\x3b\xab\x64\x88\x19\xd5\x7d\x12\x69\xe1\x14\x82\x5c\x54\x34\xe6\xb2\x84\x5f\x42\x79\x5d\x4f\xb0\x83\xad\x79\x40\x1f\x2a\x07\x61\xc6\x34\xa5\x45\xae\xc7\xcd\xb1\x3b\x5b\xe4\x49\xf1\xd8\x29\x32\x63\x78\xed\x1f\x49\x3f\xe8\xc8\xe9\xb0\x68\xcc\x1d\xbc\xf1\x65\x55\x0b\x81\x32\xc3\x19\xda\xc4\x87\xb8\x7b\xb2\x2a\x54\xcd\xf6\x0a\xac\x71\x51\x61\x82\xa4\xe6\x9b\xa0\x83\xf6\xe8\x6d\x1a\x4f\x05\x08\x3a\x77\x61\x9e\xf2\x39\xf7\x02\x39\x6d\x7e\x46\x96\x8c\xc0\x4a\x3b\x34\xdf\x32\x65\xec\xf1\x61\x57\xab\xe1\x5c\x64\x2c\xd7\x42\x70\x96\xd8\xd4\x0d\xb0\x02\xd1\x96\xca\xb1\xbe\x30\x4b\xcf\x32\x2d\x9d\x1a\x24\x51\xb6\xc1\x1e\xea\xf3\xe8\xe3\xd9\x29\xf4\x80\xb6\xb7\x78\x04\xfe\x84\x49\x6c\xa7\x57\xe0\x43\x37\x91\x4c\xe9\x44\x75\xd7\x99\x0c\x74\x57\xc8\xe6\x06\xf8\xbc\x20\x7d\x2d\x48\x11\x9c\x80\xa6\xb4\xa9\xe0\x7b\x22\x92\x26\x57\x0d\xcd\x99\x49\x89\xfe\xcc\x69\x4c\x6c\x2f\xb5\x97\x5c\x9a\x6a\x9b\x74\xe8\x15\x9c\x27\xdd\x36\x77\xdf\xd5\xcb\x65\x1f\x1e\x32\xad\xfa\xfd\x81\x0b\x6e\x5d\x5e\xfb\xac\xe3\x1a\xe6\xd9\xb1\x21\x91\xe8\x93\x98\xda\x06\x3f\x13\x8b\x75\x84\xc5\x8e\x77\xe7\xf9\xfd\xd7\xfb\x9e\xf5\xd6\x8a\xe4\x9c\x6c\xca\xd2\x8d\x18\xbc\x60\x09\xd4\x18\x7e\xd1\x42\x02\x24\xa5\x65\x8a\xad\xf1\x35\xb5\xa9\x53\xf2\xdc\x3c\x8b\xfc\xaf\x66\x9e\xd5\xda\x38\xd0\x14\x4f\xd9\x66\x5e\x6f\x06\x77\xd3\xfc\x88\x04\xe2\x1c\xc2\x5f\xd5\xe0\x1a\x3f\x3f\xa8\x3e\x57\x1e\xb2\xf8\x82\xa7\x65\x9c\xe5\xd8\x64\xd8\xbb\x54\x07\x2b\x09\x86\xa8\x54\xf1\xa7\xf2\xd2\x72\x0d\xf8\x57\xe6\xd4\x21\x96\x30\x84\x1b\x1c\xcd\xcf\xc6\x72\x6b\x91\xbf\xc1\x7e\x18\xc3\xe3\x48\x0c\x23\xa2\xc0\x5e\x4b\xfe\xdd\xd4\xdb\x9e\xf4\x23\x88\xf2\x34\xfd\x3e\x4f\x3d\xad\x66\x60\x26\xe2\x78\x06\x12\x37\x41\x61\x31\x6a\xfc\x76\x65\xf9\x41\x1b\x6c\x5a\xa7\x89\x33\xb1\x80\x21\xc0\x12\xb0\x84\xf3\x24\x47\x60\xa4\xea\x1b\xcf\x31\xcc\x9f\x5c\x40\x44\xa9\xbc\xc7\x5a\x98\x67\x07\xf3\x8f\x45\xac\x1c\x7f\xa1\x39\xee\x95\xa6\xd8\xf1\x6c\x3c\x1e\x12\x76\x4c\x4b\x0b\x11\x94\xc0\xfc\x5f\x7e\xef\xf9\xa8\x48\xc4\x05\x0b\x0e\x65\x16\x84\x71\x9d\x43\x8a\xad\x56\x01\x91\x64\xfa\xe4\xf4\x88\x82\x20\x5e\xce\x0b\x99\x73\x67\x91\x08\x4a\x75\x3b\xa7\xd5\x6e\x88\xfc\xee\xa5\x33\x56\x6c\x3a\x2c\xa4\x8d\xd6\xef\xc4\x9b\x27\xdb\xf1\x4f\x26\x16\xce\xd6\x52\xe1\x38\x33\xab\x90\x28\xad\xa4\x54\x43\x1c\x89\xb3\xcb\x74\x41\xfd\xb8\xf2\x3e\x12\xb6\x0a\x1a\x10\x4a\x2a\x8c\xf4\xa6\x4e\x87\x8a\xa2\x6f\x54\xe8\x88\x1a\x4b\x15\x1a\x16\xa9\x6d\xe8\xb9\x80\x7e\x72\x93\x96\xeb\xe3\xe3\xd3\x94\xf8\x08\xbd\x74\xb7\x31\x2f\xe6\xb8\x4b\x13\x12\xaf\x8a\x1e\x41\x33\x59\x9d\x07\xbd\xf3\x3d\xb2\x1e\x01\x6b\x5c\x19\x6c\x1b\xa3\x11\x57\x08\xf5\x81\xbb\x82\xf4\xb5\x7a\x6c\xa1\xa5\x29\xe6\x4d\x19\x30\x42\xc1\xdc\x5f\xaa\x0a\x03\xab\xf5\x38\x49\xe1\xbd\xef\xba\xb6\x4b\x1c\xb6\x0f\xe1\x0a\x3f\xc1\x82\x3a\x23\x4c\x45\xf3\xb0\xdc\xe6\x6a\x46\x73\x9c\x01\xae\xad\x12\xde\x6f\x03\x13\xc7\xbe\x71\x40\x5f\x3f\xdc\x4a\x50\x7a\x9d\x84\xe8\x68\x6f\x6f\xc9\x26\x35\xdb\x0f\x78\x56\xc7\x37\x3a\x61\x8a\x72\x52\xc1\x29\xa7\x76\x0e\x20\x29\x54\x3d\x72\x62\x28\xc2\x1d\x00\xad\x4a\xc5\x2e\x5b\x1a\x6e\x31\x20\x09\x17\xf1\x5a\xf5\x15\x85\x9e\x08\xf2\xa7\x9a\xce\x67\x99\x1e\xd6\x90\x44"}, +{{0x2b,0xe1,0xf9,0x8c,0xe6,0x55,0x3c,0x91,0x5b,0x6a,0x09,0x33,0xec,0x0d,0xe3,0x47,0xb3,0x70,0xe2,0x9c,0xa2,0x94,0xe8,0x00,0x55,0x41,0x23,0x9f,0x63,0xb4,0x30,0xd0,},{0x7a,0x6f,0x44,0x69,0xc3,0x0a,0x63,0xf5,0x60,0xf9,0x87,0x34,0xfc,0x19,0x06,0xeb,0xd1,0x37,0x1e,0xd8,0x01,0x25,0xfa,0x3e,0x4c,0x86,0xb4,0x3f,0x26,0x2c,0xab,0xbc,},{0x8e,0x65,0x9a,0x3f,0x53,0x5a,0x58,0x9a,0x5f,0xd2,0xd2,0x17,0xcb,0xcb,0x8b,0x77,0x7e,0x5a,0xf2,0x0b,0x23,0x44,0x32,0xf7,0xda,0xc2,0x9f,0x81,0x0a,0x2b,0x47,0x37,0xc5,0xca,0xb1,0x0b,0x59,0xdf,0xd0,0x14,0x4f,0x30,0x90,0xf5,0xf9,0xe0,0xe6,0x67,0xf0,0xe2,0x1a,0x9f,0x57,0x3f,0xe1,0x3b,0x1c,0x28,0xec,0xcb,0xb5,0x31,0xa2,0x05,},"\x62\x68\x20\x1f\x93\x2a\x7c\xd3\xf8\x79\xae\x6a\xb8\x38\x55\xa2\xf5\x02\x91\xde\x78\x4d\x7d\x9e\x9a\xda\xa1\xb9\xaf\xed\x6f\x5a\xea\x20\x24\x0e\x59\xfe\x93\xe5\xa7\x08\x8c\x95\xec\x8e\x15\x74\x5f\xb8\xfd\xeb\x91\xdf\x01\x51\xc7\xb4\x60\x50\x67\x56\x1e\xa0\x8d\xbf\x00\xc4\xff\xe1\xfd\x0a\xcf\x10\x36\x56\xa7\xb5\x4f\xad\x0f\x25\xab\x16\xb4\xbd\xa3\x47\x17\x9e\xd1\xca\xdb\x7b\x98\xbe\x08\x95\xe0\x50\xdc\xbc\x37\x9d\x1f\xd5\x53\xe9\x97\x95\x92\x8b\x67\xa7\x52\xf8\xd2\xec\x1b\x9d\x66\xbf\x6a\xc9\x97\xe7\x44\xdc\x32\x7f\x24\x22\x30\xf9\x2e\x79\xae\x31\x27\x45\xa5\xab\x6d\xde\xc1\x99\x8f\xb6\x3d\xc4\xf6\xb0\x5f\x14\x72\x22\xd4\xb6\x5a\xce\x90\x17\xdc\x1b\xcd\x67\x5e\x49\x5f\x9e\xab\xb5\xf6\x02\x13\x3f\x6c\x72\xe0\x53\xe9\xf4\xae\x30\xd8\x72\xd7\x8b\xf7\x1f\xeb\xa3\x7a\xcc\x59\x50\x55\xc3\xbe\xa5\x3a\x05\xef\x0c\x7f\x21\x2d\xcf\x4e\x0a\xf8\x38\xea\x29\x28\xf4\xcd\xc9\xfd\xc8\x37\xda\x25\xf2\x69\x66\xb2\x45\x6a\xbe\xa6\x6a\x5d\xfb\x8f\xaa\x8f\xa0\x91\xf7\x33\x1d\x54\x36\xe9\x8a\x8d\x63\x23\xcc\x9e\x9a\x91\xd5\xa0\x2a\x49\x51\x17\x14\x84\x9b\x47\x45\x4b\xaf\x99\xc5\xf8\x50\xa0\x8d\x3d\x98\x41\x0e\x93\x9a\x9e\x89\xb1\x50\x53\x82\x5f\x3e\x9a\xee\x71\x44\x74\x16\x14\x07\x82\xe1\xbf\x3b\x0d\x8b\x4f\xf6\x2e\x77\xa4\xa0\x3f\x71\x0a\x8a\xb7\x6c\xf6\x35\x92\xc0\x5c\x44\x0c\x8f\x06\x47\x70\x09\x91\x63\xc1\x22\x70\xf3\xd5\xec\x9a\x6b\xc9\x71\x5b\xff\xfe\xc7\x69\x61\x1d\x21\xfa\x00\x3c\x3c\xc8\x35\x6c\x97\x5d\x37\xb6\x2b\x88\xaa\xbb\x85\x97\xda\xca\x19\x6c\x96\x48\xa3\x1d\x15\xbb\x0b\x86\xcf\x07\x0e\xe0\x1e\x51\x1e\xf3\x73\xb4\xa4\x4c\x6a\x00\x16\x0a\x79\x7f\x2e\x82\x0b\x71\x6f\x5c\xa6\x44\x64\xe4\x18\x9a\x00\xfe\xe9\x78\xd3\x5b\xf2\x04\xf7\x1d\xb1\xf5\x01\xf9\xb6\xe5\xdf\xc8\x21\xa8\xaf\x5d\xbf\xef\xd3\x53\xad\x36\x81\xf9\xbc\x3c\x22\xc6\x7c\xb2\x11\xb4\x30\xb6\xa5\x5f\x3e\x73\xda\x7c\x3a\x07\xce\xb7\xd2\xfe\x25\x4b\x10\xc2\x70\x3a\xb2\xe2\x29\x4d\xd0\xd3\x15\x2d\xc7\xb2\x1a\xab\x87\xb1\x50\xf7\x37\xa9\x47\x46\x3f\xb2\x04\x17\x5d\xe8\x54\x32\x36\xfb\xb0\xda\x5c\x7d\x48\xc5\x7f\x61\x74\x4d\xe6\xf9\x84\xaa\x8e\x61\xb9\x70\xc6\x2d\x0e\xeb\x84\x9d\xa7\xe8\x9a\x61\x22\x2d\x43\x20\x79\xcb\xcf\x5f\x8a\x2b\xa9\x30\x30\x16\x83\xc0\x78\x5c\x26\xfd\xf8\x5d\xa3\x02\x08\x74\x60\x45\x99\xac\x6c\x84\x7e\xc2\x60\x86\x58\xb5\x78\x8c\x7b\x8d\x3a\x37\x44\xfd\x54\x42\xe2\x4c\x8e\xec\xcd\x42\x07\x56\xbd\xd8\xb8\xa7\x7c\xfd\x80\x58\x96\x05\xdc\xed\x9a\xfd\xa2\xbd\xb6\x30\xa0\xcb\x61\x2f\x73\x9c\xe6\x17\xd5\x4e\xde\x6c\xcf\x36\xaa\x31\xe7\xe3\x73\xd8\xa0\xfb\x1b\x7c\x99\x06\xf7\x6b\x5f\x9d\xe8\xc2\x68\x91\xde\x00\x6e\xb7\x97\xea\xd4\xa8\x6f\x70\x16\xf3\x4b\xcd\xe9\x2f\x94\xac\x3e\x92\x0b\xa5\x8d\x6d\xff\x77\x20\x78\xd8\x02\xa9\x4f\x56\xcb\x26\xbf\x79\x4f\xd9\x0c\xa0\xad\x4f\x2e\x7a\xcd\xc5\x92\x9b\xc7\x36\x49\x97\xde\xd9\x8c\xa6\x9c\x57\x39\x91\xbb\x9a\xb8\x5f\x23\x5b\x63\xe7\x6f\x77\xe0\xab\x45\xe7\x89\x12\x38\x98\x69\xaf\x21\xe7\x4e\x66\xf7\xc4\x56\xb8\x27\xe6\x70\xbe\xb0\xf0\x72\x66\x88\xbb\x1f\x90\x36\xd3\x8d\xa0\x7d\x69\xea\x36\x66\xf7\x6b\xd6\x05\xd8\x2e\x2d\xd6\x38\x7e\xce\x6e\x82\x4a\x56\x97\x00\xf0\x1b\x19\x5d\x1a\x9b\xdc\xb0\xf9\x6a\xb5\xc5\x4e\x06\xc2\x11\x9b\x40\x6b\xc4\x88\x84\x80\x66\x04\x18\xbb\x42\x88\xea\x2f\xda\x96\x63\x1b\x0e\x1f\x60\xac\x86\x1d\x6c\xcc\x4c\x84\x4b\x64\x7a\x7d\x74\x03\xbc\x2d\x15\xba\xfe\x4a\xf6\x77\xe8\x56\xfe\x0d\x2b\x5f\x66\x3b\xe4\xe4\x80\xb3\x8f\x6b\x76\x6a\xdc\xd3\xd0\x52\x98\xef\x13\x98\xd0\x4d\x15\x23\xa6\x8b\x91\xdd\x31\xcf\x5d\xc4\xb7\x3d\xec\xbf\xd7\x21\x3f\x98\x1b\x20\x7e\x1f\x6e\xf2\x25\xd7\x94\x8a\x1a\xa1\x7d\x8d\x57\xa1\x12\xf1\xd4\x46\x8d\x2d\x28\xf7\xec\x2e\x54\xb7\x4a\x69\x2c\x59\x58\x02\x2e\x82\x03\x1a\x41\xb3\x15\x09\x0e\xd4\xd5\xbd\x7b\xd0\xb4\x51\x47\x63\x38\xf7\x39\xa7\xd7\x03\x1a\xf2\xd3\x6c\xaa\x09\xff\xdb\xb7\xc3\x96\x50\x7c\x75"}, +{{0x10,0xbb,0xe6,0xe7,0x61,0xa7,0x5c,0x93,0x5b,0x51,0x7f,0x09,0x36,0xfe,0xcb,0x9e,0xc6,0xfc,0x21,0x5e,0x58,0x13,0x08,0x00,0xea,0x18,0xd1,0xff,0x44,0x2a,0x4f,0x13,},{0x86,0x43,0xdd,0xf8,0xaa,0x8d,0x9c,0x8a,0x78,0xb6,0xeb,0x69,0x9f,0xd2,0x0a,0x57,0xf6,0xf1,0x86,0x36,0xb0,0x6c,0xe6,0x9d,0xac,0xdc,0xa1,0x26,0x7a,0xcb,0x39,0x54,},{0xf0,0xf3,0x57,0x41,0x03,0x73,0x31,0x3b,0x7c,0x62,0x52,0xd6,0xd9,0x66,0x00,0x36,0x0c,0x23,0x75,0x2d,0x43,0x1c,0xa8,0x07,0x5b,0xcf,0xb7,0x72,0xd4,0x9c,0xd6,0x09,0xb6,0x5c,0x9c,0xd8,0x38,0xd6,0x34,0xd8,0xd9,0xb9,0x5d,0x1e,0xe3,0x0e,0xde,0xcc,0x13,0xe3,0xca,0x99,0x7b,0x24,0x37,0x30,0x3f,0x8a,0x33,0xa1,0xff,0xc8,0x33,0x06,},"\xe8\x10\x8c\x6d\xe4\x13\x37\x33\xdc\x19\x9a\x73\x39\x2e\x22\x6f\x71\x2c\x36\xa2\x4f\xa9\x1d\x6f\xb0\x9f\x92\xdf\x21\x8d\xeb\x2d\x28\x30\xa6\x68\xfd\x69\x4b\x48\x09\xd0\x25\x35\x07\x23\x12\x47\xc7\xf2\x58\xb4\xd6\x5c\x56\xbb\x69\x34\x5e\xf6\xaa\x97\xe7\xc5\x9e\x81\x53\x77\x5a\x5a\x3c\xf1\x09\xc4\xbc\xa9\x81\x55\x69\xda\x69\x32\xe8\x21\x83\x42\x5b\x42\xd7\x48\x3c\x9d\xbf\xcb\xd8\xeb\x38\xc8\x47\x29\x57\x1e\x8e\xc9\x39\x82\xc3\x17\x71\x67\x59\x59\x8c\x4f\x6a\x1b\x7f\x8d\xa7\x30\x6a\x78\x15\x72\x1c\xaf\x02\xe7\x02\x46\x71\x23\x14\xf7\x66\xbe\x9c\xb1\x77\xcd\x2f\xa3\xbd\xa2\x2c\xd6\x76\xc5\xd2\xe8\x6e\x8d\x79\x8f\xd3\x4f\x54\x3c\x9b\xe3\x12\x96\x51\xf2\x73\xf4\x84\xf0\xb9\x46\x7b\x14\x09\x55\xcd\x29\x81\xff\x26\x03\xc0\xbd\xbb\x43\x6a\xc0\x95\x5a\x11\x6c\x5e\x5f\xc3\x04\x25\xe1\xfe\x78\xf6\x41\x0f\x6e\xf7\x57\xf6\x04\x66\x88\x54\xba\xe7\x9b\xfe\x22\xe1\xa8\x5c\xe5\xee\x5d\x64\x34\xb4\x61\x01\x20\xea\x7e\x5d\x3d\x13\x7c\xe2\x07\x51\x4f\x85\x34\xad\x9b\xf3\x92\xb7\xdc\x53\x55\x51\x4b\x59\xf8\x35\x46\x6c\x8e\xb5\x6f\x44\xed\xdc\x5b\xad\x20\xcf\x0b\x48\x0b\x2e\x82\x2a\x6f\x46\xfd\x95\xf3\x0f\x18\x3c\x7b\xb3\x14\x3e\x4e\x61\x00\xe2\xdb\xc9\xf2\xbf\x0d\x43\x07\x3e\x0f\xe6\x5f\x01\xbc\xce\x6a\x1a\xe4\x01\xc1\x25\x41\xbe\x3a\xe6\x8c\xde\xac\x2a\x4a\xc7\x1f\x16\x63\xb5\xfd\xfc\x2e\x50\xf0\xe0\x77\xfb\x3a\x0a\x8b\x8e\xee\xad\x62\x7c\x1c\x3e\x79\xdd\x73\x61\x04\x6f\x7e\x57\xc1\x74\x36\xc3\x2d\xc4\x43\x2f\x05\x00\x28\xcc\x7a\xa4\x40\x8c\x2d\x29\xd1\xd7\x99\x8f\xdc\xdd\xa3\x2b\xb3\x2f\x70\x4d\xc2\x63\xdb\x9b\x8e\x06\xc5\x76\x30\x87\x0f\x8b\xb6\xec\x66\x1f\xde\x1b\x7d\xa9\x4d\x53\xb0\x47\x70\x1a\x45\x88\x47\x8c\x1c\x66\x23\x46\x74\x1a\xea\xc4\xc2\x53\x38\x55\x6a\x3d\x84\x8d\xe5\xb2\xa2\x3e\xce\xa6\x1b\x77\x6b\xd0\xe8\x03\x7e\xfb\x85\x01\xef\xf2\x39\xc7\xfa\xcc\xa6\xc8\x36\x7e\xd7\xc8\xad\xce\x91\x9f\xef\x1a\x15\x5a\xe0\xd5\x47\x8a\x98\x00\x2c\x95\xa1\x6f\xbf\x4c\x0e\xd0\x16\xea\x5d\x38\x66\xfe\x1d\xe4\x54\x83\x2a\x4e\x95\x65\x97\x6b\x60\xb3\xdd\x2e\xaf\x7f\xee\x61\x2f\x2b\xc0\x40\xd9\x39\x75\x43\x5e\xeb\xd1\x2f\x06\xeb\x09\xec\xea\x2c\x66\x76\x83\x08\xf5\x8c\x77\xac\x51\xed\x7b\xd2\x16\x36\xfc\x9c\xc3\xfd\x14\x87\x0b\xd0\x6b\xdf\x12\x8a\x81\xb1\x47\x92\xe6\x08\xc4\x7e\xa2\xd5\x35\xca\x7a\xa2\x1e\xb8\xa8\xa5\x6d\x76\x99\x16\x63\xa8\x19\x0a\x95\x05\x7d\x33\x67\x1e\x73\xc7\xcb\xce\x5a\x98\xd3\x1e\xf0\xd7\x3b\xd0\xb1\x63\x78\x7b\x7f\xdc\xd2\xdd\xfc\x72\x96\x0f\x2b\xe3\x20\x84\x6d\x4b\x29\x08\x0d\x7a\xeb\x5b\x7e\xa6\x45\xa2\xad\x5a\x59\xc0\x12\xbf\x7b\x95\x15\xd8\x59\xe1\xc1\x47\x2e\xf8\xa4\xd3\xc9\x5e\x71\x1a\xf9\x7a\xe4\x61\x8e\xfb\xab\x3d\xff\xe8\x8c\x9f\x6a\xf4\xa0\x9b\x0e\x73\x38\x7e\x25\x1b\x77\xd7\xbf\xf5\x21\x4f\x79\x18\x62\xdb\x69\x88\x41\x1e\x2a\xe2\xc7\x5b\xf2\x8d\x28\x60\x2a\x63\x7c\x26\xf4\x9c\x18\xd3\x09\xd2\xfc\x58\xa1\x26\x66\x7a\xd3\xc2\xec\x16\x0c\x99\xba\x40\xfb\xda\xc1\x7e\x7e\x4c\x21\xa5\xd5\x07\x85\x97\x62\xeb\xa0\x9c\x41\x60\xdf\x66\xf5\xfe\xef\xe6\x71\x5a\x28\xc5\x29\x6c\xf4\x3e\x5e\x77\x1f\x31\xfc\xe5\x13\x3b\xe9\x7c\xab\x57\x30\x1b\x4c\x9d\xf9\xcd\x9a\x4a\xcf\x1c\x33\xfa\xc9\x46\xfa\x15\x96\xfa\x65\xc8\xf3\x65\x8b\xe4\x7a\x47\x3a\x62\xc5\x21\x81\xec\xa1\x83\xe4\x24\x6c\xd6\x24\xd8\x78\x3d\xcc\xe5\xfd\xcc\x1f\xea\x17\x3f\x80\x71\xf7\x07\x4f\x55\x89\x7d\xe9\xbf\xe8\x4a\x6c\x4f\xdf\x80\x2d\x50\x26\xb8\x14\x5e\x6c\x8c\x89\x50\xaf\xc5\xb4\x0f\xd0\x35\x6f\xc5\x5e\xe1\x7e\x1f\x85\x3a\x4c\x2f\xcc\x34\xa1\x36\x9b\x87\xd2\x8d\xc2\xfd\x20\x10\xf1\x99\x03\xaf\xf8\xe4\x6d\xe0\x49\x38\xf4\x94\x82\x45\xd5\xb4\x25\xd0\x74\xac\xdf\x2b\xd8\x0b\xfc\x37\x35\xcc\x34\xa2\x25\x90\xf1\x94\xaf\x93\x13\xee\xf4\xab\x5f\xde\x61\xf1\xf9\xb5\x85\x78\x63\x8f\xcb\x4f\x28\x50\xb2\xfc\xe6\xe0\x3d\xb4\xd0\xa8\x34\x84\x81\x63\xc4\xb2\x7e\x12\x9f\x5c\xc7\x4f\x67\xf0\x08\xa2\x71\x2d\x1d"}, +{{0x18,0x6d,0xcc,0x7e,0xfc,0x5e,0xd7,0xe6,0x1a,0xe5,0x3d,0xc4,0x20,0x93,0xba,0xe8,0xf1,0x5d,0xd9,0x9f,0x0f,0x03,0x33,0x26,0xc5,0x76,0xff,0x75,0x69,0x50,0xd0,0x6d,},{0xc8,0xd1,0x41,0xac,0xb6,0x42,0xaa,0x9b,0xfb,0xd5,0x43,0x27,0x7c,0x2d,0xca,0x8a,0xa9,0x88,0x8e,0xef,0xf0,0x45,0x43,0xb3,0x78,0x9b,0x21,0xf2,0x6a,0xeb,0x0f,0x71,},{0x89,0x45,0x06,0x97,0x87,0xc1,0xc6,0x76,0xa8,0x4a,0x70,0x3c,0xae,0x1e,0x0b,0xac,0xae,0xff,0xd3,0x3e,0x91,0xbe,0xc3,0x60,0x3e,0x1f,0x13,0xfb,0x17,0x0e,0x31,0xe6,0xd7,0x04,0x9e,0xda,0x2b,0xf6,0x27,0x18,0x0f,0x45,0x6c,0x3f,0x7a,0xab,0xfc,0xd3,0x6c,0x49,0xa8,0xc0,0x4f,0x8a,0xe6,0x92,0x9e,0xc5,0xad,0xa0,0x7b,0x65,0x72,0x08,},"\x97\x43\x64\xd6\xc8\x38\x84\x2c\xcc\x4e\x74\x9e\x6a\xfd\x53\x71\x70\xdc\xd8\xcc\x50\xd6\x66\x54\xd1\x05\x48\x23\x39\xca\xbd\xf7\x4e\x32\x93\x5e\xe2\x19\x27\x2e\xa1\x68\x4f\xb9\x3c\x1f\xab\x42\xb5\x63\x18\x39\x24\x35\x91\xbd\x07\xd3\xbe\x94\x9b\x0d\xd1\x5e\x31\x96\xdf\x19\x6b\xa7\x52\xad\x11\x21\xac\x71\x12\xd5\x66\x94\x4e\x15\x3a\x4e\x06\x19\xb3\xa2\x32\x24\x1f\x02\x0b\xe0\x71\x9f\x6b\xec\x91\x8b\x26\x82\x8e\xb1\x67\x0e\xcf\xc7\x3c\x66\x84\x4e\xa3\xe4\x04\xc6\xa2\xfc\x01\xbe\xb4\x03\xc9\xd6\xca\x55\x1a\xd8\xa6\xe7\x1f\x46\x64\x7f\xa6\x05\x3f\x03\x14\xf8\x12\x4d\x8d\x2b\xc1\x2c\xc8\xfa\x8d\xb9\x5f\x2b\x73\x53\x75\x20\x1b\x81\x6a\x9c\xf4\x0f\x83\xee\x4b\x86\x71\x61\x80\x32\xde\x22\x9c\xe7\x62\x71\xd0\x3d\x26\x72\xa1\xae\x4a\x28\x8c\x85\xdc\xd2\x7f\xb8\x45\x2a\x81\x32\xe9\xff\x29\xe1\xe8\x9b\xf1\x1b\x1c\x83\x51\x92\xc0\x4b\x13\xbe\x14\xf3\xcd\xe5\xd3\x7c\xe9\x6f\x1d\xc2\xa9\xcc\xda\x0c\x4d\x73\x7b\xca\x1f\xa2\x20\xd2\x1b\xf3\x60\xb9\x05\x15\xbb\xd2\x26\xbb\x2a\x6c\x8d\x5f\x2a\xb0\x18\xd4\x08\x4e\x24\xee\x33\x3c\xe4\xe3\x9b\xcb\x6b\x46\xe7\xae\xb4\xdb\x9b\x6c\x65\xb2\x44\xd9\x82\x82\x3a\x77\x0f\x9c\x62\xa0\xbd\xe2\xcb\xb7\xec\x36\x84\x0d\x45\x51\x87\xfa\xff\x4e\x48\x8a\x5c\x60\x8e\xbd\xb7\xdb\x84\xd8\x7d\xad\x38\x67\xe3\xb0\xd0\x4b\x64\x71\x5e\x16\x56\x0a\x62\xf1\xee\x03\xdf\x61\x83\xfd\x5e\x37\x55\x5d\xa1\x97\x2f\xca\x06\x2d\x12\xbb\x84\x20\xe0\x82\xda\xcb\x8d\xeb\xb9\xc1\x43\x85\x41\xd0\xda\x24\x64\xef\x7e\xc5\x22\x63\xfb\x9b\x9a\x4c\x46\x9c\x83\x32\x3e\x48\x19\xdf\xdf\x4f\xa0\xa7\x70\xc3\xa7\x09\x25\x4e\x05\x31\x48\x30\xe8\x7f\xbb\x67\x36\xc7\x2d\x9d\xab\xe0\x1a\x31\x0e\x91\xeb\xbf\xae\x76\x7a\x1f\xcb\x62\xf6\x4f\xa3\xba\x8d\x53\x40\x0d\x64\x69\xad\x1c\xcb\x81\x1f\xb9\xe1\x15\xf1\x41\x27\xb1\x3e\x83\x64\xaa\x2f\xe8\x0b\xbc\x88\x6a\x10\xdf\x1b\x9c\xc4\xae\x46\x01\xf5\x46\x1a\xf0\x91\xf5\x26\xd2\x72\xda\x9b\x20\x38\x57\xa4\x44\x7e\xab\xde\xf4\x39\x83\x04\x96\xa5\x75\x9c\x21\xde\x65\xba\x3a\x3c\x8b\x8e\x93\x9c\x46\x13\x32\xa9\x24\x85\x2c\x20\x5c\x77\x11\xf3\xa6\x8a\x23\x67\xa9\x45\xde\xf4\xfb\xe5\xf8\x1c\x60\xcb\xb7\xe3\x94\xa2\xa4\x9b\xe9\xec\x2a\xae\xb1\xf3\x30\x57\x59\x79\x44\x6a\xd9\xd0\xd5\x4a\xbd\x43\x6f\x28\x60\xf0\x42\x34\x26\xf4\xbb\xc2\x6b\x3b\x9f\x65\x0d\x69\xb1\x00\x72\xd7\x47\xa3\x9e\x47\x8f\x45\x5e\xaa\x12\xc7\xc6\xe1\x2b\xfc\x45\x36\xa3\x59\x43\x44\xbd\x02\xb6\x20\xe3\xe2\xb4\xe0\xd5\x34\x08\x9d\xd7\xb0\x4f\xa6\x34\x80\x45\x67\x58\x6c\x62\xbe\x03\x91\xc7\xbd\xb0\xa9\xfb\xc1\xef\x3b\x33\x21\x1e\xdb\xf8\xef\x58\xc2\xb7\xa4\x9d\x06\x66\x79\x59\xd7\xe5\xd4\x46\x71\xee\x73\x57\xa1\x0b\xa0\xcb\x1a\x44\x5a\xe5\xd7\x09\xce\x25\x5e\x92\xde\x71\x59\x75\xaf\x94\xb8\x9d\x4a\x29\xc7\x1f\x9d\x88\xc8\x5b\x6c\xd1\x1d\x8b\x33\x5b\xf8\xf2\xc6\x58\xe6\xdd\x7c\x3f\x6c\x80\xad\x4d\x0e\x5a\x6c\x87\xdb\xa7\xb5\xb8\xa8\xa4\x7e\x72\xf4\xd1\xd3\xc7\x43\x63\x1d\xf9\xad\xfc\xfa\x45\xce\xe0\x49\x8d\x5a\x44\xa9\xf7\x5c\x83\xb7\x5b\x2a\x3c\x23\x0f\xf0\x76\x7d\x38\x88\xf9\x41\xee\x1b\x66\x24\xdd\x0e\x12\xd0\x6e\xd1\xab\x8b\xb1\x35\xff\xd3\x79\xe9\xde\x37\x88\xbe\x54\x1a\xad\xb2\xd6\xa7\xcc\x60\x13\x16\xf2\x1e\xb9\xaa\xa9\x22\xf5\x6a\x8e\x35\x26\xc9\xbd\x11\x77\xfe\xfc\x2f\xbe\x3e\x43\x0b\x62\x8e\xeb\xd6\x66\x1e\x3b\xa2\xd6\x31\xc6\xa8\x42\x2c\x24\x1e\xcd\x96\x99\x72\x41\x2f\x74\xda\x6b\x12\x43\xbf\x0f\xbe\xe8\xa8\x4d\x52\xe4\x0a\xee\x3f\x1e\x4f\xc8\x31\x40\x2c\x62\xf3\x57\x6b\x22\xe8\xe3\xc3\xdc\x4e\x16\x0b\xc3\xb6\xb9\xd2\xce\x00\x58\x53\x81\x2e\xaf\xc0\xa4\xe2\x5b\xa7\x12\x27\x9b\x00\xba\x3f\x91\x30\xff\x36\xe3\xef\x19\x71\xdd\xe7\x50\x8b\x27\x92\xfe\x64\xd4\x75\x68\x8f\xc6\xf3\x31\x3a\xad\xb7\x85\x30\x2e\x6b\x7f\x9a\x84\xf2\xdb\xc2\xf3\xcf\x06\x0e\xe0\x8b\x46\x37\x36\xf8\x36\xdb\xb2\x62\xd3\x29\x68\x4c\x20\x84\x92\xd1\x7d\x81\x12\x21\xbe\x02\xb6\x5e\xe2\x8e\x11\xb5\x46\x92"}, +{{0x07,0x05,0xb3,0x36,0xc8,0x9c,0xa3,0x5f,0xfd,0xde,0x0a,0xf0,0xf9,0x06,0xea,0xcf,0x62,0x3c,0x56,0xc3,0xf7,0x67,0x38,0x16,0x8e,0x76,0xfc,0xd5,0x88,0x2d,0xf7,0x9e,},{0xea,0xaa,0xf2,0xa1,0x5f,0x44,0xb6,0x34,0xce,0xf1,0x5a,0x63,0x8b,0x80,0x20,0x7f,0x61,0x09,0x9a,0x07,0x96,0xf5,0xd4,0x3f,0x3e,0x9d,0x04,0x8e,0x6a,0xe7,0x96,0xc1,},{0xd4,0xa9,0xba,0xe8,0xec,0xc4,0x72,0xc3,0x76,0xba,0xb8,0x05,0xc2,0xce,0x0c,0x1c,0x2e,0xd5,0xfc,0x77,0x37,0x15,0x46,0x8c,0xb1,0xa4,0x93,0x45,0x64,0xda,0xce,0xcf,0x43,0x8b,0x1d,0xd2,0xac,0x1b,0x5c,0x5e,0x33,0x6a,0x1e,0x20,0x70,0x1d,0x5d,0xcf,0x3c,0x8e,0xe3,0xad,0x22,0x3b,0x13,0x9f,0xa9,0x0a,0x1b,0x55,0x2e,0x1b,0x77,0x07,},"\x61\x6f\xe1\x5f\xcc\xb3\x31\x0f\x9e\xc7\x45\x64\x47\xda\xda\xf8\xe0\xa5\xfb\x26\x9b\xe1\x69\xb0\xc3\xea\x2c\xfd\xaa\xa5\x5d\x37\x93\x7f\xe7\x5b\x78\x32\x4a\xc2\x78\xa6\x50\x47\xe0\xae\x4f\x32\x7e\x97\xef\xfc\xb7\xbe\xd9\x1d\x09\xda\x72\x0b\x0a\x10\x1b\xe9\xe9\x6d\x0b\xa8\x5b\x1f\xf4\x9d\x8d\x1d\xf3\x62\xd3\x45\x4f\x0d\xb6\x82\x55\x96\x10\x1c\x97\xe5\xda\xca\xd0\x7e\xc4\x92\xd3\x0f\x2d\x0c\xb7\xe7\xde\x4e\x74\x4b\xb6\xa6\x10\x0b\x75\x4d\xa8\x47\x41\x1d\x09\xaa\xce\x8d\x5d\x41\x07\x58\xb8\x30\x87\xdb\x4b\x5e\x62\x97\x97\x9a\x21\xfb\x65\xaf\x39\x09\x52\xc4\xf9\x36\x26\x0e\x72\xd7\xc7\x83\x27\xb9\x4a\xa6\xcd\x61\x72\x78\xb0\xce\x9e\x1b\xd3\xfb\xed\x93\xb6\x9b\xc6\x49\x85\xdd\xe0\xe2\xc4\x35\x7b\x50\x2f\x05\x5e\xe7\xb0\xa0\x38\x84\x74\xda\xe0\x2d\x6c\x1a\x73\x1f\x87\x78\x5d\x75\x3a\xeb\x0d\x9c\xfd\xf8\x50\x02\xdf\x56\x6f\xc2\x50\x7d\xe7\xba\x6f\xd0\x35\xbe\xe1\x7a\x2e\x80\x8b\x4a\x75\x88\xc5\x83\x37\x5c\x82\x40\x7a\x40\xae\x9e\xeb\xdf\x94\xdf\x2f\xb8\xca\xbf\x17\x60\x6c\x43\x9e\xa7\x04\x59\xb2\x12\xaa\xe4\xa3\xf5\x30\xec\xad\xc5\xe8\x8e\x25\x48\xfa\x64\x3c\x7d\xdf\x50\x63\xb2\xe1\x06\x73\xe5\x9d\x07\xfe\x90\x68\x92\xb6\x7e\xb5\x8f\x93\x88\xa5\x6b\x37\x04\x52\xe9\x97\x77\x55\xfc\x04\xdf\xbc\x77\xda\x6c\x05\xbe\xdd\xeb\xf0\x36\x52\x56\xb5\x2c\x9a\xef\x8a\x82\x17\x3b\x8c\x89\xfb\xd9\x8c\xea\x36\xa8\xb8\x96\xfe\x66\xd3\x7c\xa7\x9b\xec\x7f\xbf\xe9\x58\xfe\x89\xf6\x76\x50\x85\xb3\x35\xdc\x77\x03\x43\xe2\x30\xca\xdd\xfa\x28\x33\xda\xa6\x62\xfe\x82\x08\xdd\x88\x5a\x6f\xdf\x72\xe3\x6e\xcf\x22\xbb\xbb\xcb\xe7\x9d\x37\x06\x50\x23\x69\x40\xbc\x2e\x6d\x4a\xc7\x4f\xe4\xd5\x54\xc9\xbc\x23\x2f\x07\xd2\xaf\x62\x20\xd1\x57\xbd\x2d\xa6\xa6\x61\x2a\x08\x1b\x4c\x99\x04\xa2\x86\x9b\x13\x7e\xe3\xa0\x85\x6f\x12\xb2\xeb\x87\x62\xdb\x94\xed\x0b\xa1\x36\xf2\x3e\x7f\xb4\xbd\x1f\xcd\xee\x10\xdd\x84\xe2\xcd\x3b\x0a\x49\x14\x8a\xc7\x4d\xb4\x66\xdb\xee\xf8\x1e\x6a\x8c\xe0\x86\x11\x02\xde\x9b\x1a\x3e\x1d\xcf\x5c\x6b\x03\x08\xa8\x2e\x3a\xc7\xc2\x28\x3c\x7c\xc2\xf3\x4f\xfa\x14\x5b\x9f\x74\xb7\x99\x04\xb3\x2b\x79\xe9\x60\xb8\x14\xaa\xde\x63\xa0\xdf\x01\x67\xdc\xd2\x4e\xd9\x0a\x8d\xa7\xb9\x34\xc7\x72\x93\x2f\x5a\x47\x8f\xe2\xa7\x2f\x94\x5a\x13\x09\x6e\xc3\x7c\xe7\x64\xb5\x81\xeb\x89\xe5\xf6\xb2\xbd\x7e\xb8\x8b\x85\xa8\x95\x87\x77\x4d\x45\x8c\x58\xcd\x87\x94\x57\x97\x3d\x64\x8e\xf7\x71\xc5\xf1\xde\xb2\x7a\x0c\xc5\xb2\x92\x46\xac\x2f\xa1\x2d\x18\xdd\xc6\xb9\xf9\xac\x9c\xf1\x46\xc3\xf2\x2b\x1e\x44\x99\xad\xee\xfb\xcd\x22\x49\x74\x0e\x13\xa2\x24\xe7\xb6\xb3\xef\x15\x60\x5e\x7e\x74\xe6\x8d\x7b\x72\x64\x24\x09\xb9\x0c\x4e\xc1\x61\xeb\x24\xc9\xb4\x0f\xf9\xc7\xe6\xe5\xda\x98\x32\x2a\xca\x52\xc4\x6a\x8d\xdc\x19\x0f\x1c\xab\x15\x7c\x4c\x76\x19\x60\x1a\x6b\x33\xdf\x6a\x50\xda\x66\x1b\xc7\x53\x60\xdf\xf6\x97\x50\xd3\x45\x74\x09\xcc\x02\x41\xc3\xe8\xc4\xb3\xe5\x06\xd4\x26\xaf\x52\xb7\x02\x31\xcd\x6c\x91\x26\x0c\xc4\x31\xe4\xcc\xfd\x49\x6c\xa1\x4c\xea\xae\x1c\xda\x78\x72\x1e\x16\x33\x9d\x52\x68\x2b\x69\x51\xf9\x66\xc7\xda\x5c\x6e\x10\xd9\x19\xae\x66\xa9\xf5\x2d\xec\x10\x86\x75\x38\xd3\xdf\x6d\x59\x3a\x32\xdb\x69\x5a\x8d\x77\x45\x70\x35\x16\xea\x56\xf8\xc1\xc8\xf0\xef\x53\xbd\xeb\x7f\x53\xc2\xd9\x44\xf5\x11\x94\x0c\xcb\x90\x62\x49\x22\xac\x59\x9f\x46\x19\xc3\x04\x62\x07\xd6\x05\xf6\xff\x94\xde\x78\x8d\x25\x34\x22\x29\xdc\x8a\xf9\x2b\x5f\xdf\x0d\xd7\x1d\xf2\xb4\x46\xcd\xf1\xd9\xa2\x05\x24\x33\x9e\xe1\xc3\x18\x26\x28\x7e\xf7\x27\x81\xa7\xa3\x52\x89\xf8\x5a\x15\xba\x57\xc7\xfd\x5d\x88\x5b\xd0\x55\x3a\xb4\x08\x05\xf5\x17\xe8\xf1\xb1\xb3\xc4\xfc\x67\x71\xe6\xf2\x24\xbc\x03\x11\x24\xb9\xc9\xae\xb1\x9c\x5a\x96\xbf\x14\x88\xe1\xe6\x6c\x6e\x88\x80\x92\x30\xc8\x3a\x74\x15\x55\x54\xa2\x19\xec\x37\x9a\xe5\x4a\x9f\xe7\x9d\xbe\xde\x3d\x57\x60\x42\xa6\x35\xd1\x97\xf4\xd8\x18\xc7\x78\x75\x5b\x8b\x45\xe5\x13\xde\xac\x88\xf6\x04\x25"}, +{{0x95,0x17,0x4a,0x09,0x15,0x68,0x4c,0xdb,0xb6,0x19,0xb0,0x55,0x49,0x5b,0x00,0xf1,0x92,0x82,0xcf,0xfc,0x3b,0x05,0x01,0x9e,0x6a,0xb7,0x09,0xa4,0xa1,0x74,0x2b,0xab,},{0xaa,0x8c,0x87,0x2d,0x7e,0x10,0xb6,0x7f,0x7f,0xf2,0x41,0x72,0xc3,0x63,0x7e,0x80,0x82,0x5a,0x0a,0x71,0xee,0x0c,0x48,0x86,0x3a,0x2a,0xcd,0xcb,0xe8,0xda,0x45,0x9a,},{0x78,0x0f,0x40,0xc2,0x0f,0xea,0x3b,0x11,0xc9,0x42,0x2a,0x43,0xb9,0xa6,0xf7,0x96,0x11,0xe7,0xf1,0xf5,0x9d,0x14,0x88,0xc1,0x5a,0x5f,0xd2,0xd3,0x2c,0x07,0xda,0xdc,0x39,0x1c,0x38,0x95,0x3e,0xdf,0x0d,0xe4,0x8b,0xe5,0x2d,0xa2,0xaf,0x33,0x5c,0x47,0xb8,0xd2,0xe4,0x4a,0xb9,0xd3,0xdf,0xb7,0x6b,0xa5,0x38,0xb0,0x66,0x49,0x52,0x08,},"\x5e\x1a\x74\x00\x45\x6c\xad\x4f\x9b\xa8\x66\x43\xbc\x7c\xbf\x3b\x35\x68\xdc\xb5\x22\xb3\x70\x55\xe8\xc3\x9d\x3c\x80\xf2\x28\x42\x38\xe5\x72\x7f\xd7\x51\x3c\xc8\xb3\x1c\x57\xae\x7b\x40\x50\xaa\x81\x9f\xc2\x36\x09\x30\xeb\x0d\xd6\x77\xa5\xb2\xc7\x29\xfe\xb2\xda\x3a\xd7\x9a\xe7\xfc\xcd\xdd\xb6\xc0\x84\x46\x26\x1e\xc9\xbb\xe5\x9c\x64\xe9\x9a\xbb\xc8\x6d\x3c\x48\x35\xf0\x0f\xef\xe5\x27\x43\x3a\x50\x1a\x3b\x6d\x57\x2c\xf5\xe1\x2a\x88\x01\x0b\x46\xa4\x72\xb9\xbd\x86\x91\xa4\x07\xc3\x65\xf9\xf7\x16\x34\xb4\xd9\x7e\xdf\xdf\xf0\x63\x14\xc0\xc1\xb4\xeb\x93\xc7\x60\x7f\x1d\x6f\xa3\x54\x65\x93\x22\xc2\x84\x07\x3f\x42\x60\x25\x18\xc5\x4f\xdf\x26\xea\x2c\x27\xc8\x0a\x6d\xfa\x20\x56\x83\x91\xab\x35\x72\x82\xc0\x6b\x23\xbe\xdc\x1d\xf1\x26\x4b\x61\x1c\x1e\x9c\xf1\x8a\xeb\xe2\x49\xfd\x86\x17\xc6\xe3\xee\x98\xc5\x3c\x0f\x6f\x21\x75\xc5\x7e\xf8\xe2\x06\xbd\x3c\xf1\x05\x62\x7a\x98\x92\xeb\x68\x99\x20\x21\x3a\xae\xb6\x3d\x87\x66\x3d\xbf\xa5\x3f\x0f\xb2\x81\x62\x69\x48\x29\x6b\x2d\xbc\xdd\xe1\xc5\x1a\xf8\x62\xee\xcf\x1c\xfe\x8a\x46\xa2\xc4\xb2\x8c\xfe\x71\x30\x33\x0a\xd1\x73\xf8\x71\x27\xaa\xca\xff\x43\xc0\xbd\xde\xa4\x8b\x00\x38\x97\x6e\x66\x2c\x04\xb6\xb0\x4a\xd0\x3d\xe1\x24\x62\xc2\x76\x5d\xb5\x35\x04\x95\x20\xcc\x11\x4a\xfd\xb6\xc9\x25\x49\xb0\x54\x6a\x90\x27\xd4\x49\x75\x5b\xeb\x8d\x4c\x17\xe6\xa2\xa4\x75\xf9\x67\x6a\x33\x7b\x4e\x86\x6d\x96\x32\x5e\x38\x9a\x52\xc1\x6c\x51\xe1\x8e\x0d\x81\x03\x34\x0c\x84\x17\xb2\xc5\x7a\x55\xd0\x42\xff\x5e\x5f\xc6\x5d\xf4\x23\xe0\x09\x2b\x0e\xa8\x8b\x96\xa9\x07\xc9\x51\x21\xc5\x47\xa6\x80\x61\xf2\x7b\xcf\xb5\x8c\xe6\xc0\x77\x28\xd4\x84\x6b\xdc\xbf\x0c\x62\x54\x10\xed\xf8\xde\xa8\xcb\x4c\x9d\x0b\xbe\xef\xcd\xe1\x92\x73\x36\x5f\x48\xd7\x5a\xec\x07\xd1\xc2\x2c\xcd\x23\x06\x8a\x97\xc3\xfe\x75\x2e\x87\xa3\x01\x18\xfe\x2d\xfd\x52\x18\xb6\xb1\x25\x15\x4e\x0e\xa3\x86\xcf\x23\x9e\x31\x37\xf8\xca\x6d\x8b\x74\x6b\x6a\x67\xd5\x08\xcf\x8c\x1a\xb6\x3e\x57\x15\xe6\x72\x1e\xda\x5c\x2b\xc3\x93\xa4\x93\xdb\xd2\xf9\xa1\xfa\x92\x6b\x9a\x59\xe4\x5a\x18\x0a\xee\xb0\x25\x99\xa8\xcd\xd6\x86\xf8\x89\xb4\x85\x27\x23\xcb\x6d\xbf\xb5\x01\x4c\xab\x5f\x65\x8a\x30\x9a\x47\x22\x39\x36\x0e\xea\xf6\x4f\xc8\x20\x3a\x3c\x70\x89\x70\xe1\x5c\xbc\xf1\x36\x25\x5d\x96\x44\x6c\x39\xa9\x27\x03\x1d\x26\x7d\x69\xec\xd5\x1d\x7a\xf6\xe9\x1f\xb4\xae\xf9\xd7\x8c\x33\x35\xe9\x07\x11\x33\xcf\xb8\xe2\x12\x99\x90\xc6\x46\x37\xc7\xad\xf1\xda\xef\x2d\xc2\x6c\x11\x63\x39\x9f\x3f\xe1\xe7\x92\x33\x80\x92\xef\x6f\x8d\xfa\xf2\x57\x30\xdd\x2f\xe8\xd9\x78\xf6\xf7\x70\xf5\x2b\x68\x23\x81\x76\x56\x4c\xee\x5f\xbb\x98\x50\xb3\xb3\xa0\x4d\x94\x84\x60\x41\x78\x26\xeb\x2e\xb2\x4f\xcc\x5f\xe3\x53\x34\xbb\x95\x21\xe8\x7b\xc4\xdb\xde\x2a\xc9\xe1\xc9\x89\x49\xdc\x2d\x29\xad\x27\x9e\x38\x84\xb9\x05\x26\x8e\xbd\x08\x08\xbf\x41\x82\x57\xe7\x5e\x26\x2b\x4d\x01\xb0\x24\xa6\xe9\xaa\x7b\xd5\x01\xdb\xa9\x4f\xf5\x06\x39\x4b\x4b\x0a\xe6\x08\x1e\xa7\x30\x30\xc4\x3a\x6a\x91\x76\x6e\x80\xf9\xf4\x2c\x0b\x68\xb9\x84\x19\xad\x4e\xee\x4e\x9a\x72\x8a\xde\xfb\xd7\x9e\x83\x1f\x70\xf4\x1e\x62\xb4\x3f\x0b\xf4\x2b\x3b\x2c\xd5\x3b\x55\x89\x11\x76\x64\xbc\xeb\xc4\x09\xa7\x64\x5b\x1e\xed\xda\x48\x2f\x6b\x68\x95\xa6\x57\xba\x78\x9b\x89\xe5\x02\xd6\x99\x87\x51\xd6\x30\x3d\xed\x5f\xa1\x56\xee\x7c\x7e\xaf\xe5\x46\x26\xd1\x03\x2c\x4d\x7d\xff\x97\x7f\x1d\xcc\x86\xaf\x89\xb1\xe6\x46\xa4\xaf\xc2\x42\x7e\xd0\x2c\x0a\xf5\xd3\x28\x90\xf9\x5f\x13\xf9\x8c\x1a\x5b\x1d\x9f\xbb\x78\x1a\x9a\x89\xb2\xd7\x90\xc1\x46\x5c\x2d\x15\x20\x92\x6f\xdf\x28\xc1\x7d\x9b\xa1\x58\x7a\xd7\x61\xf0\x65\xd3\x39\xbd\xbe\x38\xf4\x13\x3f\x45\xbb\x59\x78\x74\x26\x42\xf9\x0c\x06\x5e\xe4\x89\x25\x73\xf6\x05\x9f\x8b\x4c\xe2\xc1\x3e\x73\xb8\x91\xcd\x05\xf2\x37\x31\xed\x9a\x07\xe2\xb8\xff\xdc\x96\x3b\x06\xa5\x10\x20\x9c\x32\x99\x80\x94\x9f\x40\xd8\x07\x3a\x01\x3e\xf8\x43\xdf\xcc\x4a\x33\x94"}, +{{0x5a,0x84,0xaf,0x28,0xa5,0xdf,0xbb,0x32,0x33,0xa1,0x2f,0x08,0x37,0xf6,0xe8,0x65,0x4e,0x7b,0x0d,0xe1,0x6b,0x02,0xab,0x3c,0xd1,0x78,0x64,0x43,0x1e,0x27,0x46,0x67,},{0x80,0xd4,0xba,0x78,0x9f,0x8a,0x4b,0x20,0x47,0xad,0xaf,0xa5,0xed,0x26,0xcd,0x8c,0x54,0x67,0x33,0x29,0x2e,0x8b,0xf6,0x93,0xcf,0xd1,0x7e,0x28,0x4e,0xfc,0x68,0x71,},{0xa0,0xb8,0x4c,0xa5,0xaf,0x76,0x46,0xe6,0xf6,0x2a,0x69,0x35,0x37,0x94,0x73,0xfa,0x6e,0x4c,0x27,0x69,0x58,0x51,0xfc,0xbd,0xae,0x29,0x17,0xb2,0xdc,0x68,0xd7,0x96,0xe2,0x78,0xd7,0x0c,0xd6,0x7f,0xce,0xdf,0x6c,0xa6,0x29,0xb8,0x81,0xf7,0xc4,0xf2,0xaa,0x25,0x59,0xb2,0x0d,0x67,0x06,0x11,0x76,0x6b,0xd6,0x5a,0xa4,0xfe,0xf2,0x04,},"\x8a\xac\xd1\xb8\xa3\x9b\xf0\x8f\xd5\xc9\x18\x44\x6b\xe5\x76\xe6\xa3\xf2\x7f\x36\x11\x16\x07\xf2\x7b\x56\xa9\x12\x14\xe7\x63\xf9\xa8\x7f\xb1\xd1\x84\x48\x98\x96\x17\x97\x64\x44\x60\xbf\xf5\x48\x8c\x10\x3a\xf6\x05\xe8\x74\x0e\x46\x58\x8f\xb9\x3e\x44\x3c\x3b\xb2\x3b\x92\xc0\x98\x70\xa5\x57\x65\x3a\x1f\x22\xc2\x18\xcc\xbc\x2f\x07\x3a\x27\x2d\x17\xa8\x42\x23\xef\x14\x3f\x4c\x7c\xa2\x58\x46\x0b\x79\x81\x69\x67\x3d\xa1\x07\xd7\x1d\x53\x56\xce\x9f\x75\x59\xa9\xb0\x38\x39\x99\x51\xf5\x75\xc7\x7e\x5b\x9d\x05\x29\x57\x8e\xca\xa2\xe2\x08\x92\x66\xfc\x52\x6c\x5d\x40\x9f\xbd\x46\xbb\x86\x84\x1c\xb5\x54\xf5\xbd\x3c\x99\x71\x3b\x04\x3e\x40\x46\x53\xa7\xd0\x13\x44\xd4\xdb\x83\x1a\x21\x72\x82\xc4\xb3\x36\x40\x56\x53\xb8\x5d\x27\xa4\x6b\x25\x9c\x85\x5c\xdd\x85\xad\x6f\x7a\xed\xd8\x35\xff\x55\x00\xcc\x8b\xaf\x0f\xb2\xf0\x18\x09\x10\xc6\x46\x72\xb8\xa8\xd4\x9d\x98\x4a\x78\x29\x3c\xf5\x77\x9c\x91\x0c\x3a\xcb\xbc\xa4\x55\xa8\x54\x66\xe5\x35\x04\x4f\x34\x80\x26\x2c\x09\x0f\xbf\x4e\x0b\x0d\xb4\xd1\xef\x87\x59\xda\xaf\xdd\x8d\x05\x90\x74\x82\x46\x1f\xf9\x10\xc4\x37\x19\x5d\x5c\x7f\xed\x9d\x82\xcb\x94\xe7\xe4\xec\x24\xda\x05\x3e\x47\xf6\x2b\x48\x8e\xb7\xb2\x44\x65\x5c\x7d\xbb\x20\xed\x60\x7e\xed\x45\x31\x44\x9e\x07\x80\xe6\x1c\xfd\x57\x40\x86\xff\xc5\xdc\x52\x42\x83\x77\x5c\x44\xf7\x54\x7c\xda\xb0\x4a\x51\xee\xe4\xe1\xb7\xb6\x5a\x57\x57\x3a\x92\x48\x4a\x35\x90\x0a\x90\x9f\x81\xe4\x15\x02\x9d\x22\xca\x93\x7a\x3a\xcd\x9e\x61\xf8\xc0\xe6\x86\xb2\xd2\xad\x03\x77\xaf\x8e\xe1\x66\xe4\xa2\x0a\x82\xaf\xf4\x51\xe1\x51\x10\x3e\x0a\x17\x67\xb2\x71\xfa\x9c\x2b\x1d\xd1\x20\xf8\x05\x85\x3b\x3b\x8a\x56\x0f\xc8\xb9\x37\x62\x83\xb5\x11\x24\x32\x4a\x28\x4a\x0e\x9a\xc4\x9d\xf6\x9f\x52\x4c\x8e\x04\x2d\xf8\x2e\xfb\xcd\x16\x88\x1e\xc1\x31\xa1\x52\x10\xdf\x73\xde\x02\x94\x34\x47\xf2\x2a\x2e\xa1\xdc\x8b\xf9\x68\x29\x8e\xe9\x7f\x3a\xd5\x46\xd7\x8b\xc6\x60\x89\x7e\x08\xd2\xa2\x8b\x2b\xa6\x8b\x54\xb9\x54\xf1\x47\x64\x51\xc6\x92\x07\xe5\xdd\x24\x8a\xe4\x7e\xf3\x56\x94\x99\x0e\x6f\x05\x8b\xc0\x01\x7b\x74\x95\x10\x5c\xc8\x73\x90\x66\xaf\xb1\x1e\x1f\x26\x60\x19\x42\x54\x6a\xe8\x49\xff\x2f\x56\x73\x0f\x13\x26\xbb\xee\xa6\x40\xee\x17\x8f\xa2\x47\xad\xff\xef\xc0\x46\x49\x4f\xc7\xff\xc0\x77\x7d\x5d\xbe\x8a\x55\xda\xee\x61\x40\x6f\xe3\xc7\x08\x8d\x43\xd9\xe1\x4d\xa2\x1c\xa5\x2f\xd8\xc1\x60\x09\x1c\x8f\x99\xa6\x7d\xad\x65\xc6\x4f\xea\x9d\x18\xb1\x53\x7d\x06\x1f\x5d\xce\x87\x9e\x0b\xc4\x26\x48\xd2\xea\xa0\x2d\x97\x21\x85\x75\x3c\xb2\xf6\x22\x5d\x8d\x03\xbb\x07\xf9\x44\xb1\x0c\xf4\xea\x22\x27\x5c\x3d\x70\x84\x80\x20\xf3\x0c\x82\x3b\x76\x14\x3a\xcf\x54\x59\x99\xa2\xcc\x4b\x58\x98\xd9\x4b\x4a\x25\xef\xbe\x5a\x60\x33\x1c\xc0\x09\xfe\xc0\xa2\x5b\xc9\x89\x47\xb1\xb7\x13\x9e\x22\xd2\x32\x80\xff\x88\x54\xa1\xec\x76\x22\x1b\x1b\xf3\xd1\x08\x32\x8c\x8a\xc4\x63\xc6\x52\x63\xa2\xd7\xca\x74\x33\x48\x29\x31\xa1\xd8\xfc\x14\x4b\xbe\x9b\xef\x67\x8c\x92\xe1\xc2\xd1\x09\x21\xb6\xad\x43\xa7\x5c\x53\xbc\x07\x58\x54\xed\x2d\x99\xd8\x25\xf3\x0a\x5e\x10\xd5\x17\x43\x8e\x4d\x4f\x71\x13\x42\x9f\x1e\xdb\x38\x7d\x6b\xd7\xaa\xd2\x92\x74\xf8\xd2\xdc\x88\x9b\x7e\xfb\xeb\x58\x68\x6f\x8d\x66\x9c\xea\xef\x92\xc7\x5e\xd5\x30\x7f\x0c\x03\xf5\x90\x01\x81\xce\x57\x3c\x8f\xa2\x86\x75\x20\x5f\xb1\x05\x7f\x62\x6a\xa2\x30\xd0\x3e\x2e\xaa\x8c\xff\xcd\xe2\x00\x81\x47\x5d\x80\xb2\x45\xa1\xca\x60\x45\xba\x20\x4a\xb0\x00\x69\x07\x9c\x63\x7f\xc3\xfb\x3e\x80\xca\x04\x62\xe7\xa4\xcd\xd9\x28\x3f\xf9\x00\x85\x30\x36\x48\x16\x79\x2f\xdf\x3b\x9a\x4e\x4d\xc8\x37\x92\x28\xed\xcb\xb1\x54\xbe\xf3\x87\xd3\x77\x60\xd7\x9a\xfb\xb7\x36\x26\x0a\x1d\xb1\x01\x38\x36\x1f\x24\xb8\x26\xdb\xcd\x5f\x0f\xc9\xe7\x83\x0d\x26\xd8\x0c\x52\xa7\x92\x18\x92\x76\xbc\xe3\x47\x60\xfb\x77\xbe\x13\x12\xac\x8c\xf9\x7d\x92\xcb\xf3\xd0\x77\x80\x28\xdb\x5e\x8e\xae\x89\xe0\xb9\xbc\x87\x78\xae\xb1\x27\x8f\x04\x71\xcb"}, +{{0x79,0x3a,0xc8,0x8d,0x7d,0x3b,0x6f,0xa7,0xf4,0x7d,0xee,0xc3,0x1f,0x68,0xdd,0xcc,0xb7,0x01,0x82,0x0f,0x1b,0x13,0xdd,0xc6,0x52,0xf7,0xc6,0xa8,0x5b,0x60,0x52,0xa5,},{0x91,0xb6,0x22,0x7a,0xcd,0xd1,0x83,0xda,0x62,0xc5,0x19,0x65,0xc6,0x35,0x35,0x8b,0x20,0x4d,0x68,0x3e,0xe0,0x64,0x43,0xcb,0xd4,0x0e,0x71,0xc1,0xf7,0x6a,0xd1,0x02,},{0xa8,0x4f,0x55,0x2b,0xf4,0x43,0x22,0xa6,0xdb,0x24,0x5c,0xa0,0x06,0xd1,0xcf,0x78,0x0c,0x61,0x68,0x0f,0xe7,0x42,0x9a,0x89,0x47,0xc3,0x5f,0x21,0xbc,0x4b,0x44,0x22,0x8b,0xa3,0x0a,0xea,0x0c,0x74,0x4b,0x86,0x64,0x59,0xd3,0xb8,0xac,0xad,0x45,0x3b,0x06,0xac,0xe2,0x47,0xba,0x69,0x52,0x8c,0x6b,0x3b,0xc4,0xb2,0x0e,0x75,0x63,0x0e,},"\xec\x50\xaf\xad\x8a\xde\x74\x05\xe2\xc6\xf5\xc6\x24\x7b\xbb\xcc\xfb\x2c\x17\x16\x6f\x78\x84\xfe\xae\x10\xd9\x0f\x5d\x83\xc4\xb6\xf0\xbf\x76\xde\x2f\x78\x97\xba\x11\x94\xd6\xd3\x44\x9d\xdb\x80\xae\x74\xeb\x8e\xd6\x8f\x04\x9b\x35\xc6\xf2\x19\x16\xdb\x4d\xfc\x27\x24\xdc\x3a\xf7\xad\x8d\xd5\xc4\x4f\x60\xd2\xf4\x9f\xad\xd7\x00\x4d\xa1\x59\x30\x93\x94\x2c\xae\x52\x08\xbf\x54\xcf\x90\x3b\xee\x64\x69\x05\xfc\xe2\xeb\x2e\x37\x0d\x0d\xca\x48\xd8\x20\xad\xea\xb1\x6a\x3b\x67\x5e\x5a\x4a\x8e\x26\x7e\x34\xff\x96\xf3\x12\x2b\x18\xde\x0c\xad\x92\x92\xab\x63\xd2\x6e\x5f\x31\x0f\xa2\x16\x8c\x29\x66\xbd\xb6\x3b\x0d\xe0\x86\x26\x76\x7b\x37\x9d\xe4\x63\x3b\x9f\x3e\xda\x79\x17\x28\x1d\xad\x66\x1e\x9f\x77\x2b\x84\x4a\x79\xe8\x00\xfd\x84\x27\x02\x44\x6e\x4a\xa7\x31\x75\x71\x07\xf3\xfd\x65\x47\xbf\x40\x75\x96\x3d\x5f\xd5\xf5\x8e\x80\x85\x3f\xc4\x27\x51\xdc\xa0\x78\xa9\xfa\x8d\x5b\xb3\xd9\xa3\x4a\xbc\xab\x02\x93\xd6\xce\xae\xc4\x89\x67\xa1\xe6\x22\x43\x98\xca\xd0\xf6\x05\xa3\xbe\x8e\x67\x58\xea\x8f\x29\x20\x9d\x8e\x4c\x4c\xa1\x89\x3b\xaa\xd9\x1e\x37\x9b\xa3\xb1\x73\x30\xc1\x2a\x5b\x6f\x21\x9b\x38\x4a\x8a\xb9\x78\xbf\x1b\x37\xc3\x73\x1a\x1b\x47\x4b\x24\xb5\xd6\x7d\x4c\xec\x28\xaa\xc6\x51\x0b\x11\xf2\xcf\x21\xbc\x16\x96\x3d\x51\xf5\x53\x87\x27\x71\x8f\xc4\xe2\xe5\x17\x2e\x3c\x0c\xda\xbc\x27\x7f\x0d\x70\x37\xc3\x4c\xa6\x8f\x73\x28\x88\x48\xb9\x26\xbd\xe0\xcf\x47\xab\xfa\x66\x60\x09\x16\x94\x6f\x07\x65\x1c\x28\x0a\x20\x86\xb1\x4d\x52\x57\x0c\xc8\xa4\xb7\x43\x58\xb5\x9c\x30\x2b\x9d\x00\xe1\xb4\x98\xf3\xbc\x33\xee\x4e\xcf\x2b\xce\x2c\x65\xed\x7e\x8b\xa7\x4d\x35\xb7\x51\xd3\xc9\x9f\x40\x86\x19\x68\xc2\xb7\xf3\xa5\xbe\x34\x8c\x57\xd9\x3b\x40\xff\xd0\x51\xed\xd7\xca\xca\x6e\xe6\xbc\xa7\x21\xdc\xba\x8d\xb8\xd0\x06\x4f\x54\xd3\x6e\xc5\xe8\xd6\x2a\x71\xfd\x1c\x90\xf1\x49\x24\xf4\x1c\x16\x3f\x00\x7a\xfc\x6f\xbb\xfe\x86\x45\xfa\x47\xc3\xc9\x80\x24\x6d\x1b\x92\x27\x43\x85\x95\x3c\x53\x41\xcd\x64\xc3\x4a\xe9\x71\x7c\xc2\xc3\x7f\x58\x35\x9c\x0a\x99\x91\xc2\x3f\xe6\x37\xde\x6c\xdf\x08\x62\xf7\xd0\x32\x9f\xe7\x58\xaa\x89\x2a\xd4\x58\x3b\x9d\xf2\xf3\x33\x7d\x5b\xe5\x70\xba\x65\x49\x98\xed\x29\x2f\x11\xf0\x17\x72\x38\x2a\x04\x34\x2f\xdd\x99\xe6\x9e\x0d\x97\xc4\x3f\x10\xac\x9b\x96\xf1\x40\xa6\xf8\x3c\x47\x29\xe7\xa9\x00\x47\x1f\x2b\x1d\xf2\x40\x1b\xc5\xc6\x80\x42\x2b\x13\xb0\xc8\x00\x7d\x63\x68\x1f\x66\xa0\x59\x5a\x1c\x5d\x3a\xcd\xe5\xb7\x79\x42\x6e\x73\x6b\xc1\x00\xc5\xe6\xf5\x26\x08\xdc\x39\x1e\x3e\xf9\xb1\xbb\x6a\xf1\x3d\x24\x9b\x7d\x32\xce\x06\x80\xc3\x68\xf5\x4d\x5f\xe0\x39\xcf\xe1\x01\x30\x25\x1e\x4d\xb1\x4c\x79\xc8\xd0\x44\x06\x04\x65\x82\x29\x90\xd8\x80\x93\xcd\x73\x65\x32\x85\x2e\x44\x78\x89\xdb\x89\xcc\x60\x05\x29\x96\xa3\x2a\x64\x36\x5c\x07\x26\x05\x1c\x11\x9e\xda\x90\x1d\xe5\x76\xb3\x34\xfc\x70\x49\x48\x23\x92\xe2\x62\x0b\x0a\x3a\x13\xfa\xb1\xd3\x6f\xc0\xa5\xf2\x3d\xb1\x47\xfd\x85\x7b\x26\xa6\x98\x04\x8f\x8b\x81\x1e\x23\xd7\x22\xe2\xe9\x02\x7e\xd4\x12\x4b\x48\xdc\x5e\x57\x8a\x7a\xeb\x19\xa1\xb4\xf9\x48\xee\x5b\x46\xf6\x5b\x97\x96\x46\xe2\xbe\x07\x47\x14\x11\x8b\xaa\x4b\xfc\x15\xb0\x89\xa0\xe0\x66\x27\xda\x46\xe4\xbb\x06\xaa\x3c\x7c\x5d\xd6\x48\xe0\x3c\x9c\x2d\xec\x3f\xac\xd9\x56\x26\x56\x2f\x30\x00\x88\x32\x30\xd2\xb0\xa1\xf8\xa7\x47\x8c\xb7\x7f\x93\x9a\x5f\x18\x8f\x45\x8d\x10\x37\xb9\x01\x76\x66\x4d\x86\xea\x85\x0b\x8a\xf5\x08\x7f\x86\x60\x5a\x77\xe0\x25\xef\x6c\x7e\x6a\x2a\x59\xf0\x06\xcb\xa1\x89\xfa\xd9\x33\xf4\x2c\x53\x27\x08\x10\x9b\xc1\xaf\x81\x48\x19\x59\x5f\xfc\xb9\x5f\xbf\x5b\x7e\x93\xa7\x11\x97\xe4\x77\xee\x7c\x04\xb8\x51\xc1\xc3\x66\x22\xcd\xd8\xe6\xc8\x60\xd9\xab\x2c\xac\x56\xd2\xdc\x98\xfa\x69\x12\x4f\x2b\xb2\xa6\x47\x1e\x1c\x73\xb6\x61\xf0\x71\xf5\xd8\x6d\xe7\xd1\xde\xaf\xa4\xed\xcd\xc7\xbf\x1f\x70\x5c\x56\x30\x0a\xff\xd0\x58\xb9\x69\x77\x91\x41\x9e\x5f\xb2\xa5\xb7\xf7\x8c\xe3\x40\x1f\xf5\x50"}, +{{0x89,0xde,0x74,0x42,0xd7,0x4b,0xa9,0x38,0x59,0x69,0xc9,0x65,0x1a,0x88,0xfe,0x28,0xe0,0x40,0xd5,0x93,0x90,0x7d,0xac,0x1a,0x39,0x87,0x41,0x8b,0xdf,0xdb,0xad,0x89,},{0xfd,0x3b,0xa9,0xfa,0xd3,0x20,0xeb,0xa4,0x5d,0x07,0xb8,0x4a,0x49,0x7b,0xe1,0x7d,0x3f,0xc7,0xdd,0x99,0x99,0xc9,0x68,0x88,0x3c,0xd6,0xac,0x13,0xb0,0x66,0x9b,0x17,},{0xba,0xb5,0x72,0x84,0xd2,0x0e,0xe5,0x4c,0xc7,0xf9,0x70,0x8d,0x71,0x77,0x06,0xd8,0xfa,0xf6,0xe4,0x63,0x32,0xb0,0x69,0x1d,0x6f,0x21,0x3a,0x8d,0xb8,0x01,0x15,0x5b,0x4e,0x33,0x8c,0x13,0x61,0xb5,0x92,0xbe,0x75,0x85,0x01,0xb1,0x82,0x17,0x93,0xae,0x52,0x27,0xcc,0x3b,0xa8,0xdf,0x8a,0xdf,0xc6,0xed,0x9a,0xca,0xb5,0x4c,0xc4,0x01,},"\x9d\x52\x72\xf0\xb7\x84\x88\x2b\x94\xc7\x6d\xfb\x9d\x46\x0c\xa4\x95\x02\x5e\x0a\xec\x5d\x52\xcc\xff\xfe\xce\x9f\x81\x73\xc1\x05\x58\x26\x6c\x49\x85\x25\x89\x1a\x97\xbf\x38\x78\xe3\x3c\x3d\xe2\xfc\x2e\x52\x55\x0b\x43\x15\x62\xcb\xe4\xa3\xd0\x11\xec\xc9\xe7\x7e\xc3\x6a\xd3\x83\x41\x35\x8c\x88\x32\x1c\x03\xd0\x8b\xb4\x26\xa7\xd5\x85\x41\x71\xc0\x27\xec\x48\xd5\x78\x19\xa9\x1a\xfd\x02\xa6\x18\xcc\xbc\x25\xe6\x8e\x53\x09\xd0\x47\xb1\x56\xe3\x57\x05\x37\x3a\xda\x2e\xb8\x31\x32\x1a\x20\x3e\x1b\xd8\xf0\xef\xec\xc0\x96\x18\x64\x7b\x41\xdf\xf2\x2b\x39\xd0\x22\x35\xf8\x71\x53\x2f\x60\x85\xe9\xcc\x52\xec\x00\x9b\x33\xee\xbc\xdc\x26\x7d\x77\x67\xc9\x0c\x92\x7e\x15\x4f\x72\xf3\xf4\x8a\x34\x95\x63\x19\xb2\x93\xc8\xa8\xb3\xe3\x4e\xfc\x5f\x62\xf2\xb4\xe8\x01\x9b\x50\xa0\x8f\x5c\xcf\x95\xbc\x83\x1b\xaf\x40\x81\x1d\x87\xe5\xed\xbd\x2f\xd5\x36\x5b\x26\xa4\x31\xae\x95\x80\x0f\xf3\x81\xcd\x62\xca\x40\xe1\x86\x6d\x95\x0d\xce\x14\xf0\x30\x91\x8a\xba\xc6\x8e\x79\x16\xdd\xb9\x5a\xdc\x19\x71\x28\x78\x74\xd0\x7e\xb0\xed\xef\x64\x29\x66\x52\xc4\x80\x44\xb0\xc5\x52\x1a\x8d\x27\x0d\x53\xd7\x4e\xc6\x3b\x89\x0f\x33\x63\xf9\x20\x7f\x66\x52\xae\x8e\x78\x35\xc3\x82\x0a\xd6\xd9\xe3\x63\x3f\x4b\xfd\x53\x79\xa4\x4f\x29\xd6\x5f\x36\x09\xfe\x35\x58\x17\xdc\xa5\x51\x8d\xfe\x3b\xd7\x69\x32\x0a\x03\x19\x02\xe9\xcf\x66\x69\xc2\x4f\x88\xb0\x1e\xb3\x69\x95\xbd\xb8\xdb\xed\x6e\xe0\xc9\xb7\xf3\x22\x95\xc6\x1b\xa8\x90\x5e\x55\x98\xf3\xc9\xe1\xc8\xbf\x72\x64\xf9\x82\x93\xfa\xea\x17\x74\x7f\x88\x44\x0c\x31\x81\x8c\x43\x3e\xa3\xd2\x3c\x01\xf4\xf7\xe9\xc3\xdd\x3d\x5f\x32\xec\x9e\xac\xd7\x1a\x09\xe3\xa9\x97\x38\x1f\x1c\xbf\xfd\xf4\xb5\xba\x49\x79\xde\xb7\xb0\x98\x41\xaf\xa3\xb0\x3d\x1c\x93\x11\x09\x7b\x86\x2c\xae\x11\x70\x7c\xbd\x3a\x4a\xe6\xc8\xa2\x6a\x30\x6a\x68\x7c\x41\x4a\x4e\xa1\xe8\x12\xf1\x15\xf6\x0f\x70\xbd\xa7\xf8\xfb\xe7\xbc\x2d\x50\xcc\x55\x0b\xba\x29\x1d\x5e\xc5\x23\x22\x9a\x08\xed\x56\x8b\x5c\xee\x18\xfe\x6f\x46\x78\x2c\x17\xcd\x82\x88\x01\x63\x92\x15\xbc\x5e\x9b\xe4\x55\x5c\x9a\x18\x00\x97\x67\xa6\xc5\xc7\x4a\x82\x29\xd2\xff\xaa\x39\x9d\x8e\x64\x32\x4e\x88\x42\x23\xd5\x07\x0f\x73\x5a\x75\xd8\x5f\xf6\xc9\x4a\x9f\xbc\x2b\x36\x51\x38\x6d\xe5\xa2\x3c\xce\x95\xc8\x78\x81\xc7\x93\x99\xae\x71\xf0\x90\x73\x7e\x21\x87\xfe\x90\x4a\xab\x1d\x92\xd6\x18\x67\x95\xc9\xb4\x6c\x62\xa5\x91\x4f\x36\x30\xfd\xcb\xac\x3b\xd4\xb0\xda\x4e\xc3\x13\x6a\x1f\xb2\xba\x40\x32\x2d\x7c\xc4\x08\x5e\x16\x70\x09\xcf\x74\x50\xfc\x6a\x28\x6c\x2f\x79\x51\xd5\x1a\xae\x23\xb8\xf3\x30\x20\xef\xb5\xe3\x24\x5b\xa6\xa3\x54\x3a\x2b\xde\xc4\x47\xd5\x1a\xe0\x0b\x5e\x16\x78\xb7\x60\x93\xcf\x21\x6b\x95\x07\xc9\x63\xeb\xfc\x02\x4c\xcd\x6e\xf6\xc7\x8c\x45\x72\x27\x3b\xea\xaf\x55\x07\x6d\xc4\x4a\x22\x4b\x58\x61\x57\x05\x79\x19\x65\x30\x7c\xef\xd4\x86\x72\xc0\x81\xbc\xcf\xbc\x1d\x15\xb0\x62\xb3\x8b\x4f\xba\x9b\x9b\xec\x95\x6c\xd1\x44\x44\xee\x43\x7e\x79\x60\xcc\x60\x1e\xdd\xc0\x2f\x1a\x76\xb6\x85\x74\xd5\xf8\x84\x31\x50\xc0\xb9\x00\x99\x34\xa2\xbf\xaf\x60\x57\x70\xc1\x36\xba\x29\xf3\xdc\x7e\x29\x59\x7a\x24\x80\xdb\x23\xe2\xb2\x67\x7e\xc6\xc5\x1b\xd3\x01\xf2\xb5\xa3\x9d\xfd\xa7\xb4\x77\xbe\xdd\x1c\xda\xed\x10\xe2\x9d\x29\x54\x62\x9b\x98\x76\xf8\xee\x54\xe4\x04\x73\x69\xd5\x34\xca\xb5\x4a\xea\x44\x1d\xc9\x47\xeb\x3f\x59\x38\x2b\x21\x83\x60\x57\x2f\x26\x59\x58\x31\x53\xc0\xe2\xb9\x12\xcf\x30\xc8\x15\xb2\x6f\x05\x85\x3d\xd3\x05\x51\xee\xcf\x64\xb8\x58\xa4\x41\xbb\x8c\x6d\xb8\xa9\xfd\xe7\x7a\x32\xa7\xb4\x6a\xf6\x6f\x8c\xb9\xf3\x5e\xe0\xfa\xfb\x0b\xd4\x2d\x9e\x65\xb2\xa9\x05\x82\x41\xa3\x1b\x8c\xa1\x11\x54\x34\x23\x76\x70\xaa\xb4\xef\xf3\x60\x10\xed\x03\x71\xf4\x65\x95\xda\x1b\xdd\x57\x9b\xbb\x67\xaa\xdb\x68\xe7\x7a\xd3\xa3\x8c\x8f\x26\xd2\xaf\x5a\x71\x03\xba\x5f\x22\xb4\x2c\xc1\x2a\x8c\x3c\xe5\xc9\x21\xc9\x1c\xfc\x0e\x63\xdf\x90\x27\xd2\x62\x29\xb1\x04\x7c\xbc\x18\xf6\xb0"}, +{{0x26,0x22,0xbd,0x9b,0xbe,0xf7,0xff,0x4a,0x87,0x62,0x9e,0xa0,0x15,0x3d,0xc4,0xd6,0x08,0xc3,0x1f,0xa5,0x84,0x79,0x88,0xff,0x50,0x0d,0x88,0x06,0x81,0xf1,0x13,0x72,},{0x19,0x97,0x58,0xa9,0xc3,0xd0,0xee,0x3e,0xeb,0xcb,0xbd,0xa3,0xe1,0xef,0x54,0x55,0xff,0x46,0xd7,0x36,0xbb,0x4e,0xf0,0xc0,0x6a,0x73,0x9f,0x9a,0xc5,0x84,0x83,0x95,},{0x43,0x78,0x96,0x6b,0x78,0x31,0xde,0xf4,0xae,0xcb,0x49,0x89,0xbc,0xaf,0x9c,0xae,0x99,0x46,0x1c,0xb9,0xb5,0x9d,0x19,0x51,0x8c,0xc1,0xec,0x7b,0x83,0x51,0xbc,0xd1,0xf7,0x23,0xaa,0xc5,0xf0,0x61,0xb3,0x83,0x63,0x57,0x4f,0xf9,0x6b,0xa1,0x0e,0x19,0x6b,0x1b,0x05,0x31,0xe1,0x18,0x30,0x36,0xa4,0x25,0xe6,0x9c,0x45,0x98,0x04,0x0c,},"\x89\x1e\x82\x12\x25\x47\xd6\x1e\x83\xb0\xab\xaf\x27\xc7\x30\x3f\x05\x22\xa2\xec\x4a\xf4\x4e\xf0\xac\x19\x6a\x99\x78\xb1\xc6\x23\xef\x1f\xa7\x2b\xaf\x70\x91\x0a\x5c\x51\xc4\xf7\x8e\x0f\xe9\xfe\x37\xe2\x43\x9c\x47\x95\x91\x6c\xfa\x22\xab\x47\x1a\x25\x57\xcc\x7b\xa6\xb6\x69\x56\x06\x3d\xde\xb3\x9c\x50\xf1\x4f\x06\x34\x8f\xa6\x6b\x60\x64\xdc\xff\xca\x50\x43\x96\x7f\x05\x25\x4d\x57\x7a\xbf\x22\xae\x8c\x90\x00\x0c\xe2\xe6\xa1\xa8\xb2\xe3\xa6\xb3\xab\xc5\x63\xeb\xff\xb2\x04\x45\xf0\x91\x1c\xc4\x2a\x98\x7f\x84\x56\xef\xba\x41\x30\xe6\x8f\x01\xfc\xdf\x7b\xf7\x71\xfc\x1d\x35\x37\x1a\x0d\x75\xdd\x5f\x90\x00\x2c\x90\xb6\xcb\xad\xe4\x0d\x5b\x23\xfd\xb4\x9a\xba\xcb\x72\x19\xae\x27\x56\x1a\xa2\xa8\x79\xda\x88\xdf\x34\xa8\xc5\x81\xf0\xc6\x71\x98\xff\xc6\x08\xfe\x91\x95\xb5\x55\x5c\x8a\xe9\x34\xc8\x30\xaa\xe2\x88\x5b\xea\x87\x48\x74\x48\xe1\x1b\x4f\x2f\x17\x2e\x4d\x5c\xfe\x4f\xd1\x13\xf9\xd2\x01\x6c\x24\xa7\x34\x51\x2b\xb9\x18\xf5\x75\xe7\x54\x13\x97\x18\xe3\xd2\x0e\x79\x0a\xbb\x94\x2c\xba\x3e\xc8\xb2\xdb\x59\x07\x96\xdc\x43\x5f\x13\x9f\xc6\x4d\xdc\x85\xa2\x24\x94\xef\x2b\xfa\x1f\x5c\x0f\x18\x75\xea\x58\xe8\x4e\xb3\x74\xec\xf8\xce\xc6\x46\x8b\x6b\x09\xd1\xe7\x4f\x15\x41\xed\x45\x4a\x28\x07\xd3\xf4\x05\x35\x66\xb0\xe4\xe2\xc6\xae\xce\xd1\x0d\xc0\x07\xe9\xdf\x41\x6f\x26\x7f\xcb\x3f\xe1\x7b\x8b\xac\xe0\x3f\x07\x43\xe0\xe6\xd4\xa4\x8c\xe7\x6e\xdf\xf6\x0c\x0e\x3a\x30\x84\x56\x99\x54\x13\xc1\x07\x6f\xf3\x7e\xcf\x23\x81\xa0\xd4\xe9\xe4\xa9\x13\xa2\x58\xd9\x83\xb9\x69\x6b\x5c\x45\xaf\x37\xc8\x68\x40\x70\xe4\x00\xb8\xf8\x65\xa5\x04\x04\x3f\x45\xd7\x8b\x97\x13\xf3\x35\xaa\x41\x6a\x46\x16\x64\x10\x73\x5f\xb5\xd8\x22\x10\x45\x8d\x5a\x08\xa1\x04\xd4\x00\x2a\xb6\x11\x88\xf9\xdf\x45\x7d\xd7\xed\x59\x37\xca\x50\x77\x60\x6b\x41\x8b\xbc\x86\x84\xa1\xd5\x25\xbf\xa5\x51\x08\x76\x40\xb1\xd1\x77\xca\x6d\x4f\x64\x71\xb3\x9b\x2c\xe4\x3a\xfb\xf8\x28\x5e\xcd\x68\x7e\x43\x8f\x44\x25\xdf\x56\x8a\xb8\x6f\xa2\x31\x63\x49\xa1\x10\x2b\x41\x43\xd7\x1e\xf4\xe2\x4f\x5c\x53\x0c\x77\xaf\xb0\x10\x07\x88\x63\x64\x40\xe7\x40\x67\x5a\x61\x74\xc5\xf0\x57\x10\xb2\x53\xa4\x11\x17\x3f\x9e\x82\xce\x6e\x22\xf4\x09\x5e\x77\x14\xb8\x73\x7e\x14\x7a\xa0\xf2\x31\x91\x57\x8f\xfd\x93\x82\x3c\xe4\xbf\x91\xc1\xd1\x10\x98\x2a\x5d\xa0\xe4\xb8\x1b\xd2\x5b\x9b\x9c\x21\x42\xa7\x67\x1e\xe9\x37\xc9\x0f\xd0\x71\x5e\xc9\xaf\xa4\x4d\x86\x04\x68\x98\xb4\x2f\x75\x35\x89\xd2\x26\x8d\x2a\xaa\xa9\x85\xcc\x90\xe0\xf9\xe8\x27\xa3\x92\x3e\x77\x16\x34\x6f\x4f\x89\x31\xc7\x28\x21\xb3\xeb\x64\x5d\xaa\x74\x52\xc8\xaf\xc8\x98\xd7\x97\x55\x45\xc1\x2d\xa1\xbd\xb2\x09\x04\x5c\xb0\x0f\x4b\xfd\x53\x83\xdf\x01\xf0\x03\x68\x0b\x97\x34\x40\xf1\xa3\x9c\x9d\x82\x09\x59\xef\x6f\x85\xbd\x33\x63\x90\x65\xae\xfd\xc8\xbc\xfe\xcb\xd9\xb9\x55\x40\x49\x73\x8a\xf2\x9f\x12\x94\x63\x9d\x39\x15\xd6\x32\x99\x5e\x8f\xaf\x71\x3e\xf2\xee\x3c\x29\x8b\x55\x96\xfa\x10\xc9\x9f\x94\x6d\xdb\x32\x34\x06\x95\xdf\x1c\x19\x45\x94\xea\xf3\x77\x8d\x73\xc8\xba\x60\x40\xc0\x4e\xb3\xa4\xff\x86\x77\x93\x6b\x88\xe0\xc5\xf0\x44\x14\x80\xd1\x07\xd7\xac\x22\x02\xb3\xb6\x94\xe5\x7c\xcc\xa6\xd8\x25\xe2\xa0\x7e\x81\x2e\xd2\x9b\x2c\x20\xd5\xc6\x05\x47\x15\x79\xe3\xed\xff\xc2\x23\xf2\x42\xc5\x93\x91\xdb\x41\xe9\x8d\x5f\x3d\x6c\x5b\x1e\x32\xac\x82\x37\xfc\xfd\x10\x20\x54\x3a\x40\x41\xe0\x3d\x92\xad\x3e\x2e\xc5\x52\x91\x47\x07\xc7\x7c\xd0\x1f\x3e\x48\x01\x14\x44\x28\x3f\x09\x68\xfa\x4d\xee\xee\x55\xc4\x56\xed\x1f\x87\x7a\xde\x04\xac\x8e\x8d\x2c\xb6\xc8\x58\x20\xb4\x92\x9b\x25\xbf\x31\xe9\x25\x43\x5d\x6b\xcc\x50\xd3\xe2\xe9\xb8\x51\x02\xe9\x70\xd7\x89\x5c\x25\xad\xe5\x21\x61\xa3\xb6\xbf\x50\x1a\xb0\x19\x61\xcb\x63\xed\x99\x0a\xeb\x93\xed\xa3\x82\x8b\xf0\x4c\xa5\x28\x53\xc7\xb6\xb8\xe9\xe4\x9e\x34\x9d\x69\xb5\x3b\xe0\x74\x85\xf5\x42\xb7\xcd\xd0\x6b\x52\x7d\x41\xdd\x11\x9c\x70\xb5\x64\xf1\xa9\x3a\xec\x62\xae\x74\xe6\xe8\xf8\x55"}, +{{0xae,0xb1,0x3c,0xcb,0x90,0xc8,0xcb,0xef,0x90,0xd5,0x53,0xda,0x3f,0x69,0x01,0xb3,0xd7,0x5c,0x13,0x01,0x1f,0x02,0x49,0x74,0xda,0xf7,0x9a,0x17,0x89,0xc8,0xc6,0x32,},{0x5f,0xaa,0xfe,0xb5,0x95,0xf1,0x6d,0x33,0x8f,0x1c,0x72,0xa9,0xf3,0xe4,0x98,0xf3,0x8b,0xab,0x69,0xa8,0x1b,0x37,0xd2,0xd0,0x92,0xb7,0xbf,0x7e,0x50,0x5d,0x82,0x0d,},{0x06,0x11,0xb1,0x9a,0x74,0x72,0xa4,0x43,0xe8,0x7e,0x54,0xd7,0xc6,0x64,0x7f,0xaa,0xb1,0xb7,0x9a,0x83,0xfd,0x43,0x71,0xc9,0x2b,0x97,0x54,0x00,0xfd,0x62,0x8a,0xcf,0xc3,0x25,0x77,0xcc,0xbb,0xaf,0x03,0xd8,0x8f,0x89,0x3c,0x88,0xf2,0xca,0xc7,0x84,0xc7,0x22,0xa0,0x8f,0x38,0x7a,0xbc,0x31,0x9a,0x70,0x2c,0x86,0x84,0x79,0x65,0x0b,},"\x86\x1a\x10\x18\xd6\xbd\xc4\x80\x5a\x5c\x4d\xf8\x7e\xfa\xa4\x62\xc6\x8b\x4b\xf4\x06\x5c\x68\x4c\x2a\xf1\x31\xc6\x37\x73\x88\xba\xee\x58\xc6\xc8\xf8\x84\x23\x62\xec\x6e\x3b\xce\x07\xc8\xaf\x55\x88\x5e\x82\xdb\x87\xa1\x52\x27\x80\x0d\xd3\x3a\xfc\x5e\x5f\xd1\x57\x01\xe9\x5f\x53\x50\x1b\x1a\x6f\xf8\x3c\x64\xe8\x51\x71\x49\xbf\x3f\xf0\x11\xb0\x94\xa0\x9c\x67\x3d\x0f\xc4\xa3\x9e\xe5\x5e\x69\xf0\x71\x17\x7b\x8a\xa3\x64\xe1\xe2\x56\x06\x4c\xf7\x02\x79\xcc\x76\x69\x5a\xe4\x9d\xaf\xcd\x80\xca\x0a\x14\xe1\x69\x1d\xb9\x46\x42\x2e\xc7\x5a\xb4\xf7\x86\x59\x15\xa6\x9b\xd4\x8d\x89\xb1\x2a\xdf\x48\x7d\x4d\xb9\xbe\x87\xcd\xdc\xa2\x11\xaa\x88\xe9\xbb\xe8\x49\xda\x21\x39\x89\xeb\x08\x44\x59\x2a\xd6\x3e\x28\x1b\x2e\x4a\xfe\x6a\x88\x36\x00\x66\x09\x92\x6c\x0f\x78\x7e\x84\xf2\xa9\x5b\x46\xb6\x6f\x0e\x45\x55\xc9\x48\x3c\xe2\x17\x6f\xc6\x3f\x7c\xc9\xf4\xf2\xa2\x2d\xb0\x55\xaa\xe2\xe6\x8b\x30\xa0\xda\x5f\xeb\x80\xc2\xa6\x0e\xa1\x0d\xbf\x67\xfb\xbc\xdb\xe0\xbe\x33\xf2\xe9\xc1\x3c\x46\x9e\x77\x68\xf2\xff\x59\x60\xa5\x5e\xb4\x82\xec\x11\xd4\x7e\x15\x4b\x7c\x42\xa5\xfb\x75\x6c\x8a\xd5\x39\xb3\x3d\x12\x5a\x4a\x65\x19\x2c\x6c\x9b\xd5\x76\x23\x8c\xa7\x2a\x73\xcd\x17\x9e\x8c\xf5\xcd\x04\x8e\xd3\x30\x21\x38\x23\xab\xba\xfc\x36\x82\xb2\xb7\xf6\x8c\x5b\xc4\x6f\xd0\x9a\x8c\xb2\xa3\xfd\x09\x95\x73\xee\x2e\x6f\x28\xc8\x2e\x27\x1b\xb5\xef\x93\x4b\x0b\x0c\x38\x1c\xfa\xae\xc6\x66\xd7\x17\x10\x6a\x87\x4a\xf3\x0a\xa7\x41\x25\xea\xe9\xac\xc2\xf1\xf2\x41\x18\xcb\x4e\x68\x3a\x73\x1e\x37\xe5\xe4\x64\xa1\xea\x3d\x2a\x53\xcc\x0d\xca\xd4\xc1\x7c\xea\x9a\x43\xe2\x36\x5f\x3a\xe3\xdd\x89\xeb\x39\x97\x74\x20\x04\x55\x50\x74\x5f\xc2\x67\xfc\x7d\xcc\x56\x02\xe9\x14\x97\x2a\x4d\xa6\xeb\xeb\x68\x7f\x68\xa0\xcd\x7d\x8b\x4f\xdd\x73\x72\x21\x06\xa8\xe4\x36\xb9\x3e\x5b\x58\xf5\x98\x2a\xce\xcd\xec\xfd\xb3\x82\xfe\x98\x53\x82\x61\x42\x6b\xa6\x40\x52\x55\x76\x43\xce\x9f\xec\x71\xea\x43\xcf\x5b\x6c\xba\xde\xb4\x95\x31\x93\xff\x3e\xd1\xa1\xf9\x22\xa9\xaf\x2e\xc6\xf3\x38\xe7\xfb\x0a\xff\xe3\xd1\x3c\x33\xe3\x95\x87\x3e\x4a\x7a\x7f\xb0\x44\x98\x1e\x05\xa6\x71\x97\xb9\x96\xb1\x99\xb4\x30\x11\x11\x93\x63\xe5\x61\xd5\xb8\xa5\x17\x84\xfd\xff\x58\xab\x80\xed\x4c\x49\xe9\x3f\x0c\xf4\x19\x24\xf9\x83\x5e\xfb\x09\xf6\x44\x63\xb6\x55\x17\xb6\x7b\x15\xdc\x3f\x28\xad\x9a\x9b\x2d\x29\x46\x8d\xe2\xc6\x3e\x62\x00\x4b\x6a\x3f\xd0\xc5\xc2\xe2\xaa\xa6\xcf\xa1\x5e\x4f\xaa\xfa\x1e\x2c\x71\x3e\x98\xd3\xfd\x25\xca\xb9\xe5\x17\x03\x59\xc8\x36\x51\x52\xb4\x74\x27\x6e\xd0\x03\x7c\xdf\x77\x18\x28\xe2\xfb\x7c\xce\xc4\x89\x5f\x21\xad\xcc\x5b\x68\x87\xc8\x6e\x51\xad\x05\xf2\x55\xf6\xe9\xda\xd2\xc4\x1f\x56\xb9\x8b\x7b\xbb\xf9\xfc\xb6\xba\x8c\xad\xfd\x38\xad\x8c\x62\xf9\x2d\xd8\x77\x40\xfa\x1e\x1b\xd1\x70\xc0\x0b\x20\x49\xc5\x13\x0f\xe7\x33\xf1\x6b\x1f\x2c\x7f\x00\xb2\xef\x97\xb3\xa9\x54\x58\xc5\x3f\x19\x9d\x46\x53\x36\xd5\xff\x59\x77\x80\x6e\x1a\xfd\xe3\xea\xa2\x46\xd8\x5c\xab\xf7\xe1\x23\x48\x1e\x23\x92\x99\x76\xed\x19\xc4\x0e\x29\xff\x33\xd8\x0e\x7d\xea\xb1\x92\x71\xde\xcd\x5e\xe0\x61\x72\xb0\xb0\xa1\x39\xbd\x62\xa2\xe7\xc8\x3a\x8a\x65\x60\x1d\x0a\x05\xd6\x1a\xf9\xc6\x03\x2d\xf5\x80\x01\xd4\x73\xe2\x0d\xd6\xc6\xaf\xd7\x8d\xdb\xd7\xcd\x17\x8e\x9c\x27\x1e\x05\x72\xf8\x59\x82\x82\x3c\xe6\xc4\x02\x93\x0c\xf8\x0f\x5e\x0c\x7c\xda\x85\x12\x2a\x76\xd1\xce\x02\x1b\x1e\x3d\xe2\x55\x6d\x1b\x45\xac\x7b\x01\xb5\x9c\xad\xa2\x52\x91\xd6\x38\xa5\x2a\x5e\x7d\xbc\xdd\xf9\x6b\xb1\x77\x4a\xb0\xb0\x77\xe4\xb3\xda\x5a\x95\x8f\xe1\x1d\xee\x4a\x02\xe6\x9b\x91\x8d\xdb\xfa\x1c\x5b\x3b\x7d\xca\x9f\x87\x84\xbb\x6b\x0b\x9d\x5a\x7f\xee\x74\xbb\x03\x74\x7f\x61\xc2\xb2\xf1\xb4\x92\x45\x2d\x3b\x56\x0b\x48\xd3\x9d\x87\x21\xe9\x83\x75\x25\x56\xd4\x4d\xa6\xb0\x28\xd9\xae\xf8\xbf\xf9\xaa\x37\x9c\x8e\x2b\x0a\x63\x6d\x74\x88\x60\xab\xd8\xe6\x4f\xc8\xe9\x65\x20\xa3\x4a\x27\xf7\x67\xaa\x97\xa8\xf7\x7b\x60\x95\x21\x8e\xad"}, +{{0x73,0x87,0x2b,0x14,0x76,0x2f,0x68,0xda,0xe4,0xfc,0x10,0xdf,0xd6,0xf4,0x2d,0x3f,0x96,0x22,0xbf,0x2a,0xfe,0x6b,0x34,0xa9,0x56,0x49,0xaa,0x38,0x74,0x24,0xee,0x6c,},{0xdf,0xab,0x2c,0xe1,0xab,0x99,0x81,0xaa,0x7c,0xbf,0x32,0x07,0x35,0x00,0x07,0xfa,0x6c,0xe6,0xca,0x60,0xa2,0xed,0x7b,0x59,0x0f,0x3c,0x2f,0x62,0x92,0x2d,0x8f,0x61,},{0x85,0x25,0xc3,0x46,0xca,0x3a,0x6a,0x6c,0x5f,0x65,0xc4,0x17,0x78,0x59,0x93,0x77,0x65,0x98,0x70,0xcb,0x6d,0xf9,0xa4,0xa0,0xe5,0x5b,0x40,0xc3,0x5b,0xeb,0xa5,0x5c,0x8e,0x00,0x9e,0x56,0x00,0xb6,0x44,0x7d,0xc7,0x40,0x2b,0xa2,0x77,0x49,0x29,0x7e,0x8f,0x95,0x28,0x69,0x18,0x56,0xf7,0x2d,0x2a,0xd7,0x61,0xed,0x1b,0xc1,0x53,0x09,},"\x43\x3d\x71\x78\x1c\xea\xb2\xb4\x7d\x82\x6e\x67\xd3\x9f\x9b\x80\xd2\xff\xd7\x25\xf8\xc5\xae\xb4\x0c\xbe\x4f\x9b\x5f\x48\xef\x93\x52\x1c\xce\xc6\x04\x36\x0b\x96\x47\x32\x31\x90\xbf\xef\x75\xac\x93\x15\x62\xd2\x7f\x4a\x4e\x31\xf4\x6e\x57\xbc\x99\xfa\x51\x58\xc8\x2e\x12\xb7\x37\xe4\x5c\x5d\xe9\xf7\xdd\x7c\x86\x22\xd4\xa7\xea\xad\xf7\x20\x2f\xb4\x9d\x81\x9c\x9a\xd2\x4f\x88\x07\x31\x3c\x5f\x37\xdc\x20\x45\x3b\xdf\x05\xc9\xbf\x1a\x3c\x21\x17\xc9\x3e\x7f\x3c\xc8\xa2\x54\x20\x98\xe8\xfc\x1c\x64\x2f\xa4\x7b\x05\x54\x36\x57\xb8\x5f\x48\x0b\xc8\x6e\xc4\x28\x00\xbb\x14\x22\x35\x9c\x7c\x3e\x8f\xf4\xbe\x59\x8b\xd5\x4f\x1d\xc5\x86\xac\xae\x45\xa4\x74\x06\x22\xb9\x62\x74\x2b\xc8\x6e\x17\xcf\xa6\x3e\x77\x53\x54\xe7\x70\x7e\x50\x79\x58\x9e\x8d\x10\x8b\x1f\x11\xda\xce\x05\x75\xcb\x9a\x6d\x26\xb5\x9f\xce\x98\x14\x65\xd9\xbc\x34\x4e\xa6\x94\x5a\x95\xb8\x62\x79\x63\x84\xfa\x81\x70\x56\x08\x57\x45\x7b\xef\xf9\x5a\x9b\x5a\xc3\xd6\xad\x28\x2d\x44\x92\x9a\x30\x30\x26\xb4\xbb\xed\xd6\x0e\x2e\xf0\x55\xa3\x1f\x52\xd7\xce\x8d\xf2\xca\x5d\x18\x51\xc5\xb1\x67\xdb\x08\x09\x25\x9b\xb8\x12\x56\x90\x74\x10\x5c\x73\x4c\x85\xd6\x23\x12\x73\x75\x5f\x3a\x8b\x56\xdc\x50\x8d\xb5\xc2\x3d\xac\xb7\xa0\x61\x67\xbd\xa5\x1b\xc0\x13\x50\xf0\x16\xcd\x41\xb2\x1e\x8c\xc5\xbc\x93\x34\x3a\x9b\xb6\xea\x47\x38\xc5\xc8\x4b\x78\xfa\x96\x3c\x41\x0e\x43\x3d\xc5\x98\x19\x6c\x22\xe5\xb7\x91\xe1\x2a\x4b\x34\x3f\x7c\xd4\x7b\xbb\x0e\xb0\x78\x2b\xdb\x1a\x4e\x46\x68\x46\xa0\x30\x52\x8e\xeb\x89\x05\x6f\x73\x25\x71\x93\xad\xaa\xbc\x1b\x22\x98\x62\x03\x48\x78\xc3\x25\x8a\x53\x25\x48\x76\x2e\x29\xec\xc0\x01\xab\xd9\x89\x64\x9d\xa5\xe1\x44\xcf\x35\xd4\x86\x99\xf2\x3b\xc4\x6c\x5b\x34\xe0\x4a\x53\xe7\x27\x24\xb2\xb0\xb8\x78\x98\x25\x75\xd6\x88\xe2\x3c\xbe\x3a\x34\x06\x7f\x49\x71\xe5\x55\x97\x2e\xc2\x90\x8a\xe5\xf0\x3e\x88\x31\xec\x67\x75\x5b\xe9\x56\x87\xce\x63\x72\x93\x9e\x1e\x2f\xb6\x95\x1e\xc9\xec\xf4\xbf\x7d\x15\x35\x43\x1e\x25\x9f\x29\xad\x43\x12\x22\xb5\x4b\x65\xaa\x7d\x07\xcf\xb5\xdf\x16\x2a\x87\xc4\xd0\x34\x81\xeb\x44\x1f\x22\x1d\x7f\x58\x62\x7a\x14\x16\x4e\x7f\x4c\x2e\x3a\x1d\x50\x7e\x89\x9d\x53\x58\xe0\x08\x29\xb0\x8c\xf3\xae\xcb\x8a\x75\xb2\xa3\x1c\x31\x85\xa5\x80\xe1\x2b\x13\xf0\x64\x28\x69\xff\xfb\x05\x67\x23\xe9\x61\xaa\xf6\xfe\xfe\x67\xb4\xa7\xc4\xc9\x3d\xb3\xfe\x1f\x61\xad\xcc\x76\x55\x69\xa9\x9c\x09\xa3\xc8\x24\xed\x4a\x98\xba\xbe\xae\x43\xef\xb1\xf3\x51\xba\x13\x0e\x22\xaa\x97\x81\x19\x86\xbe\x92\x3c\xc4\x18\x0a\x7c\x4b\x78\xbc\xc1\x40\xce\xc1\x55\x74\x65\x4a\xa6\xd6\x5a\x06\xb9\x7e\xcf\xa5\xf3\xa9\x35\x5f\x96\xe4\xee\xaa\x76\x89\x21\x7b\x66\x3f\xba\x4d\xab\x0d\x99\xb1\x9c\x8d\x8d\xbf\x47\xa1\x57\xe5\xd5\x96\x9a\x35\xef\x84\xdf\xf9\x56\x2e\xdd\x43\x4e\x73\xae\xe7\xd0\xd8\x92\xdd\xa7\x2a\x36\x2a\x22\xa7\xe9\xfa\x86\x34\xa5\x7e\xeb\xd1\xa9\x07\x48\x5c\xa8\x92\x1b\xdc\x19\xee\x9e\xe5\x88\xf3\x95\x68\x7d\x3f\xc8\xf8\xc2\x5f\x2e\x95\x76\xca\x60\x31\x3f\xbb\x2c\x26\x5a\x99\xf2\xcd\xd5\x57\x5b\x1d\xd5\x30\x60\x4e\x9a\xd6\x69\x5c\x9f\xb3\x59\x94\xa8\xb8\x7d\x5c\x85\x70\x54\x9a\x4d\x32\x9b\x9f\xe0\x87\x06\x9a\xb7\xeb\x0d\x71\x4a\x94\xe1\x92\x61\xf8\x6e\x44\x8f\x2d\xa9\xb1\xcb\x0c\x0d\xbe\x41\xd4\x4c\x3a\x82\x47\x83\xd1\xbd\xbd\x73\x26\x05\x1a\xeb\x10\xad\xab\x80\x5c\x5c\x59\xd0\xe8\x3b\x1c\x11\xa2\xfd\xd3\x5e\x44\x4a\x49\x9e\xd1\x5d\xaf\xd8\x38\x62\x77\x5f\x6c\xdf\xc6\x75\x95\x81\x84\x07\xbe\x55\xec\xbf\x7b\xf8\x6c\x73\x06\x9a\xac\xe5\x77\x62\x6a\x85\x63\x53\x6f\x60\x50\x42\xcf\x7c\xaa\xf6\xfc\x8e\x3b\x54\x5b\x77\x41\x4d\xf8\xd9\xf6\x49\xb9\x9e\xe4\x25\x41\xda\x38\xc3\xaa\xe6\x27\x20\x78\x45\xb8\xf4\x14\xa8\x07\x4d\x70\x86\x8a\x5c\x0b\x07\xb0\x70\xc3\xc6\x53\xbe\x04\x07\x6b\x83\xca\xd7\xb0\x30\x5d\x95\x00\xaa\x44\x45\x5c\xb8\x60\xdc\xc7\x64\x00\xaf\x93\xc3\xd2\xef\xb4\x2a\xe0\x56\xf1\x42\x8b\x65\xf1\x22\xe1\xc7\xb9\x58\x4d\x81\x4d\x50\xac\x72\xef\xdb"}, +{{0x67,0xcf,0x27,0x15,0x52,0x87,0xbe,0x6b,0xfa,0xb6,0x62,0x15,0xe0,0x17,0xc3,0x46,0x63,0x22,0xf2,0x1e,0x6e,0xb1,0x40,0xbe,0x4f,0x1b,0xde,0xcf,0x55,0xab,0xfd,0xc1,},{0xd0,0x70,0xaa,0xb2,0x95,0xa8,0xaf,0x93,0x57,0x27,0xc3,0xbe,0x44,0x2b,0x25,0x1d,0xb9,0xe7,0x74,0xd2,0xf4,0x4b,0x3c,0x24,0x24,0xc5,0x2f,0xc8,0x96,0x56,0xe1,0x69,},{0xc9,0x34,0xa3,0xa1,0xaa,0xab,0x78,0xd9,0x26,0x9d,0x1e,0x9d,0x13,0x39,0x2f,0x72,0xc6,0x37,0xbc,0x5d,0xe5,0x4f,0x04,0x69,0x1e,0xfc,0x29,0xd4,0x73,0xb4,0x75,0x02,0x5d,0x8d,0x8f,0xe3,0xc5,0x23,0xd2,0xd2,0x9c,0x41,0xc5,0xf3,0xde,0xc6,0xca,0x38,0xce,0x6d,0x68,0xd7,0xff,0x09,0xb6,0x13,0x5b,0xa2,0x4d,0x0d,0x32,0xcc,0x15,0x02,},"\x0f\xf0\x52\x97\x03\x1c\x89\x27\x74\xcb\x2c\x01\xe8\xca\x60\xdd\xd0\xce\xac\xc0\xb8\xd5\x91\xa8\x91\xe3\x3b\x19\xe1\xbe\x9e\x36\x3b\xc6\x42\x0d\x6f\x52\x9f\x04\x84\x0b\x3b\x08\x85\x3c\x83\x5a\x03\xe0\x36\x97\x8b\x04\xa4\xf9\xec\x6b\xe4\xae\xf3\x31\x95\x61\x90\x99\x6d\xea\x27\x26\x19\xf1\x68\x6d\x33\xbe\xf0\x3d\xbc\x08\x5a\x92\x3a\x0f\x11\x5b\x78\xf6\x53\xfe\xeb\x60\xbb\x9e\x45\xf3\x4f\xb8\xbe\x5a\x4c\xbb\x64\x8c\x7d\x29\x95\x6f\x0d\x0e\x96\xbd\xd3\xc8\xd0\x64\x97\x20\x62\x4c\xbc\x20\x79\xe8\x4f\xd6\xd0\x10\x24\x11\x24\x09\x84\x59\xf1\x2a\xf2\x99\x1d\x38\x28\x77\x0f\x50\xb1\x04\xea\x6e\x5f\x51\xfd\xad\x30\xa9\xb8\x07\x9d\x21\x59\xe4\x6d\x64\xaf\x91\xd0\x7c\x10\xed\x19\x81\x4d\xf2\xaf\xe6\x60\xd7\xd8\xf2\x40\x35\x34\xe9\x2c\x62\xe1\xea\x6d\x68\x82\x03\xbc\xa3\xd9\x7c\x2a\xfd\xa8\x3b\x25\x55\x20\xff\xe9\x2a\x33\x62\x57\x72\x51\x3b\x1f\xe3\x4f\xaf\xe3\x2b\x6a\x9b\x8c\xf9\x94\xdf\x7e\x63\x4e\x68\x65\x91\xe5\xf0\x07\x3a\xba\xbc\x64\xa8\x92\x10\xba\x53\xa4\x99\x1c\x11\x55\x7e\x03\x34\xe6\xc6\xa5\x03\x6c\x64\x2a\x31\x8f\x22\x95\x11\x71\x39\x08\x5f\xb3\x40\x75\x64\x70\x06\x75\x8e\x32\xbc\x00\xad\x10\x9f\xe8\x03\xf7\xee\x9f\x5e\xc2\xaf\x4d\x25\xc3\x07\x0a\xbc\x51\xcf\x4d\x78\xe1\x3a\x7c\xe2\x83\xd4\xfb\x4e\xb4\x1d\x3e\x8c\xe9\x02\x38\x50\x0a\xe0\xce\xda\x32\x0e\xc5\x92\x2e\xfa\x10\xb9\x03\x74\x8e\x1e\x85\x3a\x37\x29\xd2\x4c\x10\x54\x39\xdf\x2f\x70\x00\x12\x3d\xb9\xb2\xc0\x15\x33\xbb\xf0\xd0\x28\xeb\xb2\xfc\x00\xdc\xe3\x8a\xd0\x63\x28\xee\x9e\xcd\x84\x9a\x6e\xfc\x3a\xe8\x84\xef\x69\x33\xcf\xeb\xed\x05\x5b\xb2\x96\x8a\x0b\x06\x76\xb5\x72\x92\x16\x17\x8c\x75\x19\xef\x07\x88\x59\x3f\xc0\xdc\xff\x50\xd7\xe0\xb1\xeb\xb3\xcf\x49\xbb\xd1\xbf\xa5\xc3\x0e\xa7\xb8\x8c\x36\xe1\xa1\x59\x3a\xef\x0b\xb3\xf9\xe2\x09\x1c\x85\x89\xf7\x41\x4b\xee\xd8\xdf\x46\x6a\x2e\xd8\x7b\x2c\xb5\xf3\x5f\x1d\x31\x24\x6c\xeb\x96\x86\x09\x25\x36\x15\xd7\x80\x43\x51\x73\x79\xee\x69\x74\xa6\x69\xcb\x48\xda\x6a\xc2\xf9\x6d\x70\x0b\x7e\x44\xa4\x35\xcf\xef\xec\x40\x2a\x1e\x31\x10\xe7\x69\x81\x92\x4f\x26\x01\xc0\x1d\xc0\x35\x46\xfd\x4f\x51\x16\x49\x30\x2f\x06\x33\xdf\xbd\x25\x65\x1c\x5a\x59\x9c\x90\x95\x44\x89\xc7\x6a\x65\xec\x05\xa7\xe4\xcc\x74\x61\x6c\xe2\x56\x01\xcc\x37\xb8\x04\xe1\xf0\xbc\xc8\x65\x10\x23\xb1\x2e\x13\x56\x84\x41\xe8\xb8\xef\x4c\x30\x5f\xcd\xad\x3d\x2b\x13\xfa\x08\x03\x24\xb2\xfd\x6b\x61\x99\x8c\xf8\x64\xb6\x58\xbc\x7f\xef\xcc\x48\xa5\xa7\x68\x1d\x7c\x86\x6c\x34\x2c\x7f\x5d\x6c\xf1\x08\x81\x52\x2c\xc7\x10\x25\x7d\x25\xa4\xc1\xe3\x52\xd2\x70\xe9\x02\x08\x2a\xb9\x54\x1d\x59\x00\xce\xff\xa0\x91\x4b\x16\xb5\x5e\x0d\xd3\x78\x6e\x98\xd4\x17\x20\x87\x5a\x14\x8e\xb4\xab\xdb\x01\x53\x85\x66\x79\xfb\x98\xc0\xec\x48\x5e\x5f\x45\x8d\x63\x5b\x78\x61\xa2\xb3\xa8\xba\x5e\xc2\xc1\x44\x4d\x35\x39\x80\x20\x0e\x5e\x07\x18\x08\x85\x4a\x26\x8c\xc7\x6c\x60\x5c\x94\xf3\x73\x29\xc3\x61\x87\xa4\x1f\xdd\xf9\x2a\xab\xdb\x49\x96\xa0\xe1\x0b\x31\x55\x26\xaf\xea\xc8\x0e\xb2\xfa\x32\xaf\x78\x6a\x34\x31\x6b\x36\x11\x1e\xe9\x35\x21\x08\x14\x4d\x70\xf7\xd1\x72\x3b\x32\xf4\xdb\xaa\x82\x20\x13\x53\x41\x1d\x65\x77\x13\xe5\x5e\x35\xdf\x78\x58\x0b\x1b\xc0\x86\x80\xf0\x15\x9f\xa1\x16\xfa\xf4\x63\x56\x6a\xaf\xe8\xae\xa6\x98\x57\xe7\x2e\x44\xac\x80\x9a\xc4\x3f\x5c\x45\x93\x9d\x85\xa1\xa5\xf4\xa3\x70\xa1\x89\x96\xc8\x51\x4a\x46\xf3\x43\x71\xef\x9e\x5f\xb2\x04\x42\x2c\x93\x4a\x1d\x29\x3d\x10\x1b\x8c\x16\xf9\x9c\xc0\x73\xea\x36\x6a\x13\xa4\x5c\x43\x7d\x62\x0d\x13\x2b\x74\x40\x9c\xbf\x8b\x9c\x07\x5b\x41\x63\xf7\x26\xaa\x67\xe5\x09\xa2\x48\x74\xfc\x1b\x1f\xb6\xfb\x7c\x73\x55\x15\x9c\x02\xaa\x13\xe6\x4b\xad\xf1\x50\x35\x6b\x18\x41\xb3\x21\xf8\x04\x1e\x13\xed\x77\xe8\x46\x1c\xfb\xb8\xe8\x28\x48\x8b\xf5\x17\xa5\xd2\x9f\xf8\x2e\x73\x67\x48\x0a\x8e\xdd\xde\xb5\x35\x0e\x7a\x83\x42\x3b\xd0\xb1\xc5\x5f\x7b\xb4\x24\xca\x04\xc2\x05\x72\x3c\xd5\x40\x56\x71\xe7\x33\xf3\x91\x60\x0a"}, +{{0x18,0xc2,0x1c,0x0d,0x0d,0xe1,0x3d,0x4c,0x64,0x49,0x7e,0xf0,0x26,0x0d,0x66,0xcf,0xd3,0x42,0x16,0x98,0x1a,0x1b,0x49,0x39,0x1a,0xe5,0xcb,0x0e,0x41,0x43,0x6e,0x9f,},{0xf7,0xd4,0xdd,0x1e,0x05,0x9c,0x36,0xf6,0xd1,0x21,0xc0,0xaf,0xfe,0xb2,0x1f,0x0c,0x57,0x2b,0x45,0x99,0x2f,0x84,0x94,0x8b,0x09,0xaa,0xfb,0xcd,0x86,0xbb,0x53,0x5c,},{0xc9,0xc0,0x99,0xe2,0x1d,0x09,0x5a,0xfa,0xdd,0x4e,0x71,0xc9,0xab,0xf6,0xb7,0x08,0x33,0x24,0x77,0x62,0x25,0xb5,0x87,0xb6,0x0a,0x0e,0x60,0x92,0xec,0xb3,0xd3,0x3c,0xff,0x39,0xc6,0x7d,0x34,0x77,0x6a,0xe9,0x9d,0xda,0x75,0x4a,0x3c,0x2b,0x3f,0x78,0x11,0x35,0xa3,0x8c,0x78,0xed,0x64,0x55,0xaa,0xf0,0xae,0x0c,0x31,0x3b,0x62,0x05,},"\x68\xab\xca\x7c\x16\x6a\xfe\x06\x3e\x47\x7b\x80\xe3\x7d\xb2\x24\xe1\xa2\x35\xde\x8f\xcd\xeb\x7f\x42\x7a\xf6\x7e\x00\x12\x47\xcc\x5e\x05\x71\x82\xfd\x9b\x6d\xb8\xba\xba\xa6\x58\xcf\x3b\x3f\xe4\xb0\x76\x3b\xf8\x8d\x67\x31\x1b\x11\x90\xbe\x83\x40\x18\xcf\x57\xa3\x32\x92\x24\x13\x76\x46\x20\xac\xe0\x54\x45\xee\x01\x9a\x06\xdf\xf9\x8b\x23\x89\x79\xad\x6d\x30\x90\x1b\xef\xa3\xc6\x4f\x6b\xd8\xc6\xeb\x09\x2c\x2e\x62\x84\x13\x88\xfd\x8c\x4e\x84\x19\xe2\x77\x89\x84\x89\x67\x37\xed\x90\xa2\xcd\xb2\x19\x96\xae\xf7\xc2\x16\x38\xd6\xcb\xe6\x80\x32\x2d\x08\x99\x65\x97\xa9\xe3\x03\xf6\xf5\xf4\x79\x40\xf8\xc5\xba\x5f\x5f\x76\x38\x3e\x7e\x18\x06\x4a\x3d\x2d\xff\x5f\xdf\x95\xe9\x0c\x5e\xb3\x0f\x4d\x8d\x45\x9e\xe1\xd5\x06\xa8\xcd\x29\xcd\xc6\x9b\x67\x54\x96\x3b\x84\xd6\x74\x94\xb3\x53\x05\xd1\x0d\x12\xb9\x48\x74\x17\xb2\xce\x28\xad\xcb\x10\xb6\x5c\xc9\x31\xfb\x33\x81\xae\x02\xe7\xaf\x79\xa0\x2b\xf9\x9e\x25\x8a\x56\x36\x10\x90\xe0\xb7\x12\x22\xb3\xac\x60\xbf\x2f\xb7\xba\x83\x2d\x03\x4f\x5b\x6b\xc6\xfa\x66\x3a\xe7\x41\xf7\x6d\x97\xc1\xac\x32\xbc\xb7\x41\x15\x07\xd5\x18\xd2\xf6\x05\x4b\x57\x83\x28\xc5\xf6\x7f\x75\x8a\xc0\x1b\xfe\x6f\x4d\x35\x90\x0f\x50\xa5\xdc\xd3\x0d\x2f\x92\x61\xb6\xbb\xec\x4c\x1d\x1f\xc1\x8d\x2a\x7e\x70\xc4\xd3\x6c\x21\xfa\xf8\xcf\x94\xa5\x87\xc3\xa0\xd1\xa9\xcd\xe7\x83\x1a\xe6\x26\x77\x54\x68\xdd\xcd\x40\xa8\xba\x18\xf4\x2b\x34\x18\x8d\xe5\x74\x1e\x1b\xe8\x30\x7b\x10\x84\x58\x65\x15\xec\x01\x5e\x4e\x37\x1d\x29\x44\x3a\x40\xb0\xc0\x69\xc6\x41\xd8\xce\xe5\xe4\x61\x18\x62\x98\x7c\x3e\x35\x6b\x12\x93\xb0\x51\x8b\x4a\x4c\x8e\xa9\x7f\xc5\xa4\xdb\x1f\x01\x29\xab\xee\x72\xfb\x80\x92\xea\x35\xc2\xda\xb6\x75\x73\x85\x02\x07\xb8\xe8\x27\x18\x99\x9a\xd9\x9c\x4c\x83\x9e\xac\x14\x63\x6b\xd5\xe4\xd8\x43\x6a\x27\x0d\xd9\x0b\x8e\x32\x13\x02\xe5\x2a\x92\xd8\x91\xff\x18\x91\x54\x2a\xe2\xca\xa0\xd6\x6e\x0f\x66\x1e\xae\x37\xb2\x5b\x08\xbb\x2e\x0e\xee\xc4\x83\x80\x09\x77\x8c\xd5\x25\x98\x43\x80\x98\x3b\x2b\xaa\xdd\x71\x02\xa1\xe3\x56\x73\x4e\x41\xd7\x61\x83\x82\x9e\xa9\xab\x82\x44\xc3\x36\x59\x7c\xa2\xd6\x79\x88\xf2\x81\x43\x84\x67\xe4\x53\xf5\x62\xc6\x7b\x22\xd0\xa4\xdd\x9f\xcb\x46\xa5\xf8\x0d\x29\x9d\xb5\xf0\x1f\x59\x16\x0a\x19\xd7\x4c\x64\x4f\xa5\xa9\x40\xe3\x2c\x9d\x8d\x98\x3b\xab\x7e\xfb\x0d\x7c\x7d\xa4\xe3\xfd\xa1\xcd\x0d\x18\xa4\x55\x8e\xb9\xfe\x46\x40\x8a\xab\x50\x85\x91\x2b\xf2\xf4\x6a\xb6\x3a\x93\x54\xf9\x02\x7c\x93\x69\x12\x23\xff\xaa\xb8\x46\x3b\xac\x4c\x4b\xc3\xb1\x1a\xbc\x46\xba\x68\x71\x7c\x91\x78\x0d\x3f\x30\x47\x0d\xbd\xd8\x8b\x37\x80\xa1\x94\xc8\xa4\x0a\x2c\x0a\x81\xa4\xd5\x6d\xec\x2d\x89\x62\xc3\x4d\x2a\xb7\x33\x69\x02\x8e\x1b\xfe\xaa\x6b\xb5\x82\x41\xff\x4f\x89\x8f\x80\xad\x3b\xb1\xc6\x91\xb8\x64\x7f\x2c\x69\x83\x95\x4c\x1c\x77\x95\x74\x58\xee\xbf\x1c\x50\x55\xc3\x16\x93\xab\xce\xd0\x53\x84\x73\x5a\x4f\x74\x19\x68\xbd\x6a\xc3\x15\x65\xcf\xee\x71\xc8\x84\xc1\xe2\x9e\x9e\x7a\xe0\xf7\xec\xd0\x4d\x46\x3b\x1d\xc3\x89\xc3\x60\x37\xe8\x14\x58\xdc\xec\x61\xd0\x76\x40\x32\xdd\x58\x9b\x92\xaf\xda\x2f\xc9\x02\x8f\x41\xab\x53\xcc\xa2\xd0\x4e\xc6\xa9\x56\x59\x55\xcb\xcf\x1a\x34\x63\x98\x9c\x71\x39\xbb\x90\x2a\x59\x21\xe8\xb2\xc9\x9c\x48\xe1\x37\x11\xf0\xbc\xc3\x99\x25\x95\x16\xc8\x1a\xe9\x42\xa6\x79\xd4\xba\x33\x97\x9e\xb1\x2f\xcd\x28\x60\x60\x2e\x47\x24\xb1\x33\x0f\x1c\xd2\x57\xb5\xb2\x89\x1d\xae\xe8\xef\x4c\x92\xfc\x3b\xfd\xb3\x4e\x53\x2d\x58\x70\xf3\x80\x59\x86\xac\x97\xb5\x03\xfd\x85\x87\x35\x48\xe3\x09\x50\x00\x0f\x8a\x70\xbe\x51\xfa\x75\x76\x03\x50\x1f\x2d\x30\xe8\x52\xef\xea\xc4\x82\x68\x62\xae\xd7\xf6\xd2\x0c\x9a\x8c\x8d\xbe\x36\x2d\xfe\xe4\x18\x93\xf2\x7e\x6f\xd5\xe9\x1d\x0e\x7e\x3d\x4f\xd8\x15\x5f\x44\xfd\x8e\xf1\x7a\xf1\x4a\x84\x8d\x44\xa8\x76\x31\xae\xee\x75\x14\x62\xb2\xa5\x40\x87\x06\x8d\xae\xab\x3e\xa3\x28\x9e\xce\x62\x12\xb3\xb5\x2c\xe7\xa8\x88\x6d\xf2\xa7\x27\xb7\x2a\x57\x0c\x2f\xb9\xc5\x03\x41"}, +{{0xdb,0x9a,0xae,0xe1,0x98,0xcd,0x26,0xa5,0x2b,0x11,0x81,0xfa,0x3f,0xd9,0x2a,0xbe,0x42,0x5e,0x66,0x6d,0x89,0x0b,0xf9,0x69,0x46,0x7d,0xd2,0xce,0x28,0x0e,0xd4,0xa7,},{0x3c,0x89,0x7c,0xaf,0xe2,0xb4,0x99,0xec,0xb2,0xe1,0xdd,0x01,0xea,0x55,0xf3,0xfc,0x88,0xf6,0x8c,0x25,0xb6,0x4a,0x63,0x6b,0x31,0xa1,0xfd,0x1c,0x78,0xf3,0x7f,0x3f,},{0xb2,0xe3,0xd9,0xc5,0xd0,0xff,0x32,0x99,0x96,0xbc,0x89,0xd2,0x6f,0xb3,0xac,0x12,0x6b,0xde,0xd3,0x13,0xcb,0xf8,0xdf,0x86,0x71,0x86,0x38,0xc1,0x99,0xe0,0x57,0x27,0x3d,0x09,0xeb,0x16,0x3c,0x6c,0x18,0x1f,0xd8,0xbc,0xe5,0x1f,0x72,0xd4,0xd9,0xd2,0xe8,0x4a,0xbb,0xe0,0x83,0x30,0x77,0x3b,0x9f,0xcc,0x21,0x66,0xf1,0x40,0xd6,0x0e,},"\x47\xfb\x62\x15\x61\xf8\xb7\xee\xce\xc6\x03\x3f\x2b\xcb\x6f\x43\xac\x68\xc9\x58\xdf\xd2\x65\x6f\x52\xa0\xc2\x9b\x4a\xcd\x44\xf4\x30\x4c\x6b\xf7\x7e\xea\xa0\xc5\xf6\xd3\xb2\x2d\xb1\x96\x99\xc3\xdc\xde\xde\x69\x8a\xbd\xe6\x23\xec\x4b\x2b\x90\x91\x0c\x80\xac\x3a\xf3\x9c\x55\x0b\x6d\xd4\x09\xe6\x3d\x77\x70\x66\x55\xa9\x19\x9c\xb5\xc0\x25\x8f\x5b\xa3\x82\x85\xff\xdc\x64\xb8\xa8\xf3\x73\xd1\xfb\x29\xba\x87\xf8\x4d\xdf\x5f\x34\xd8\xf1\x40\xbb\xc1\x7b\x39\x61\x68\x2d\xf5\xd0\xa8\xf9\x10\x2e\x37\x9a\x99\x98\x13\x9d\xfe\x40\xab\x8c\xe7\x53\xbf\x56\x26\x10\x82\x37\x77\x1a\x7d\x8e\x10\x9e\x9e\x0a\xfe\x9b\x66\xd0\x42\x09\x42\xe1\x63\xa4\xf3\xc0\x3f\x71\x81\x3e\xe0\x78\xbd\x09\x0a\xc3\xd0\x77\x2e\x26\x22\xc2\x59\xe6\x82\x55\x2c\x75\xb0\x8d\xd0\x55\xa4\xa5\xeb\x5e\x60\x94\x40\xbc\xd3\xf3\xa6\xfe\xb8\x76\xfd\x16\x92\x15\x20\xc6\xcb\x68\x84\x71\x0d\x2e\x15\xcd\xad\x6d\xaa\xee\xd9\x59\x62\xdd\xa2\x1c\x67\x88\xf7\x84\x91\x79\x17\x98\x2e\x1c\xcb\xb5\xfd\xd9\xbd\xc1\x76\x9d\xb6\xb6\xdb\x57\xca\x35\x4e\x01\xa1\x33\x9d\x8e\x77\xe9\xdb\xbb\x58\x12\xfb\xab\x6a\x14\xc5\x40\x85\xc0\x65\x95\x99\xf1\x50\xe2\x24\x72\x47\x0f\x1e\x5e\x67\x2c\x42\x5f\x37\x5f\x9e\x0d\x6e\x8d\x52\xfa\x17\xb7\xa8\xd7\xa4\xd7\xca\x3e\x12\xf4\xdb\x53\x83\x6a\xed\x2b\xeb\xd7\x45\x89\xba\xca\x8c\xe9\x10\x02\x91\xbf\xb7\xe4\x56\xdb\x7f\x2f\x0a\x84\xdc\x0a\x74\x88\x85\x13\x66\xa9\xa5\xfe\xa0\xe3\xef\xc7\x4b\x9c\xdd\x4b\xd9\x7b\x65\xab\xf3\x61\x39\x3c\xe1\x70\x3d\x85\x71\x80\x5e\xe6\x8a\x13\xd3\x65\x4f\x03\xdc\xec\xfb\x77\xa5\x34\x30\xd0\x94\x96\xad\x73\xec\x01\x75\x99\x57\xe5\x10\x46\xaa\x73\x96\xf5\x92\x33\x86\x50\x11\x7a\xc7\xb4\xdd\x35\x73\xeb\x53\xd9\xc9\xf9\xdf\xa6\x2e\x23\x69\xc7\x7a\xf9\xc0\xd4\x2f\x61\xba\xe7\x4b\x28\x7d\xdf\xa2\x7b\x7f\x1c\x1b\xe9\x88\x3a\x04\x46\x91\xd5\x6d\xc1\x37\x34\xad\x4e\xe3\xa3\x2a\x9f\x40\xe3\x28\xc5\x00\xd0\xfe\xd8\xea\x05\x10\xe9\x38\xf2\x75\x80\x04\x02\x2b\xca\xa6\x90\x2b\xda\x10\x14\xb8\xae\x33\x65\x27\x28\x29\xed\x94\xfa\xba\x63\xcb\x14\xa3\x6c\xf8\x13\x90\xec\xa8\x3f\xc1\xc6\x27\x17\x20\x13\x26\x1b\x39\x93\x77\x9a\xa0\x76\xa5\xc5\xd8\x1d\x90\xd2\x70\x62\xe1\xa6\xd9\x0b\x5c\xf1\x00\x5c\x70\x19\x17\xb7\xad\xac\x18\x0c\xb7\x5b\xbc\xe0\xf2\x7f\x2f\x18\x0e\x2c\xb9\x01\x40\xc1\x4c\xc6\x00\x9d\x2d\x41\xaa\xb1\xdb\x94\x18\xf9\x1d\x4c\xf3\x94\x00\x2c\xd7\x0a\xc9\xdc\x11\xce\x86\x53\x47\xfa\x3f\x56\xf8\x7c\x14\x9e\x2b\x17\xd2\xc7\x2b\x66\x3a\x58\xe3\x18\x7b\xb1\x9b\x9b\xac\x2d\x11\x48\x3b\xa1\x2f\x77\x0a\xc0\x4d\xc4\x6d\x38\x85\x18\xfa\x54\xdc\x15\x2e\x9a\x9d\xfb\xff\x14\xf1\x4c\x61\xcb\x37\x58\x97\xe3\x0c\x53\xe6\xde\x42\xd5\xe1\x40\x1d\xae\x1b\x22\xba\xaa\x0e\x8a\x41\xc6\xaf\x9d\x0e\x0b\x13\xa9\x1a\x23\xd9\xb7\xd5\x55\x20\x47\x02\x9a\x35\x21\x94\x6c\x71\x20\xd3\xd2\x58\xb3\xae\xfc\xf7\x54\xd1\x95\x94\x87\xa1\xfe\x77\x43\xac\x7e\x1c\xc8\x9e\x36\x8b\x19\x78\x09\xc3\xa2\x73\x17\xe0\xec\x48\xd5\x46\xdb\x1e\x21\xeb\x62\x9a\x29\xbc\x62\x47\xcd\xd4\xa1\x37\x14\x37\x56\x3e\xdd\x12\xfa\xea\x2c\x5c\xb7\x7e\xed\xed\xbf\xc5\x80\x08\xfa\xd1\xf6\x5a\xf3\x58\x43\xfa\x27\x4c\x73\x4e\x3f\xbb\xaa\x9c\xc5\x0d\x68\x37\x48\xb7\x5a\x48\x5f\x94\xd6\x30\xb0\x32\xa5\xf1\x06\x7d\x1d\xeb\x30\xe9\xd2\x21\x8c\x93\x5c\x98\x1d\x01\xc0\xc5\x47\xfd\x68\x41\x31\x36\xed\xf4\xc0\xc7\x70\x28\x6e\x82\x34\x42\xe1\xc5\x13\x65\x19\x29\x21\x3c\x12\x1c\x1d\xe7\x00\x98\x91\x41\xab\x4a\xf3\xb3\xfe\x74\x04\xb4\xd2\xa3\x8c\x53\x0b\xaf\xb4\x98\xe6\x49\x53\xce\x1c\x0f\xb7\xd3\x40\xe2\x11\x35\xbf\x8a\xfd\xd8\xdd\x65\xb1\xb1\x8c\xf1\xc8\xfb\x9f\x40\x2b\x26\x70\x40\x0b\x86\xdd\xaf\xb1\x84\xcc\x51\xd5\xfd\xa2\x73\xb8\x0c\x26\x52\x1f\x91\x2f\x35\x83\xb4\xae\x30\x1d\xae\x15\x1c\xb5\x5c\x75\x70\x3a\xad\xef\x03\x24\x15\x22\x7d\x53\xe3\x95\xdb\x6c\x15\x0a\x1e\xe8\x39\xad\x26\xba\xe5\x52\xe1\xab\x73\x62\x14\xdc\x04\xb0\xf3\xc4\x1b\x7c\xfb\xd0\x49\x68\x1b\xc8\x4c\x3d\x16\x53\x07\x68"}, +{{0xa8,0x04,0xc3,0x3b,0x4d,0x38,0xcb,0x3c,0xe3,0x1c,0xf3,0xba,0xc1,0x04,0x9e,0x0d,0x4e,0xc6,0x3a,0x1a,0x0b,0x7b,0x59,0xfd,0x8a,0x36,0xee,0x37,0x54,0x16,0x56,0xaa,},{0x60,0x72,0x25,0x6d,0x65,0x74,0xa2,0x93,0xbd,0x7c,0x22,0x1c,0x55,0x1c,0x32,0xcf,0x2f,0x77,0x15,0xe1,0x9e,0x43,0x3a,0x49,0xd9,0xb8,0xb0,0x49,0x0e,0x56,0xef,0x62,},{0xb1,0xb4,0x4a,0x14,0x2a,0x7c,0x4c,0x3d,0x0b,0xf4,0x66,0x1e,0xda,0xc5,0xb7,0x67,0x00,0x57,0x26,0xc1,0x4a,0x27,0x69,0xb7,0xc2,0x14,0xfb,0x58,0x73,0x7e,0xc2,0xe4,0xbc,0x51,0xc3,0xa1,0x95,0xd2,0xba,0x1b,0x74,0xa5,0x4e,0xff,0x4c,0x33,0xa9,0x0f,0x41,0xcc,0xde,0xfa,0x9e,0x93,0x65,0xfd,0xe8,0xdd,0x85,0x9f,0xd3,0x97,0x8c,0x0a,},"\xdb\xfe\x30\x7f\x2a\xae\x9e\x07\xec\x7c\x4b\x68\x21\x06\xd2\xc9\x36\x7b\x0c\x4a\xaa\x58\xae\x80\x4e\x0a\x39\x04\x75\x4e\x6c\xf8\xfe\xe7\x3c\xf9\xe2\xd4\x5d\x02\x89\xe5\x07\x82\x93\xdf\xc4\x69\xd4\x6e\xa6\x70\x26\xc5\xaa\x69\x2d\x2f\x2c\x9f\xb4\xec\x57\xcd\xab\x4c\x04\x3f\xf9\xae\x61\x85\xf2\x7a\x70\x44\x54\xe5\xf5\x39\x50\xaa\xbd\x25\xc9\x91\x04\x74\xd4\x5a\xf8\x83\x68\x62\x72\x3e\x0e\x6a\x27\x82\x3d\x82\xbc\xbb\x68\xa9\x60\x52\x42\x2a\x18\x19\x51\x2e\x3b\x43\x40\x8c\xf4\x89\x57\xad\x6a\xe2\x35\xb7\x23\x3d\xf1\x82\x84\x74\x91\x53\xdf\xa5\x7d\xe3\x50\x74\xa3\x0e\xdf\xab\x8a\x56\xdf\x28\xab\x2e\x29\x40\x30\x6c\x22\x1a\xa5\x54\x90\xcc\x66\x4e\x14\x68\x3f\x30\xee\x61\x5e\x2d\x93\xfd\xf9\x71\xf5\x96\x66\x34\x65\x84\x3b\x3a\xdd\x63\x92\xba\x33\x90\x31\x1e\xf8\xdc\x59\xf2\x51\x44\x5d\x66\x9e\x10\xa0\x06\x19\x91\xe1\x13\x56\x19\x23\xaa\x21\x52\x44\x46\x3d\x82\x64\x19\x9a\xc5\x88\x92\x4e\x23\x1e\x84\x19\xd8\x68\x5f\x33\x8e\x59\x9b\x5f\x40\xbf\x9b\xd1\xae\xce\x77\x25\x35\xbb\xbc\xb8\xf6\x88\x1c\x2e\x80\x04\x91\xab\x3b\x57\xb4\x4b\x8a\xe4\x3a\xeb\x5c\x4a\xe5\xe7\xed\xeb\x22\x8f\xed\xc9\xf6\xb9\xca\xde\xa1\x76\xe1\x34\x93\x6d\xed\x60\xaf\x1c\x22\x87\x34\xfb\x00\x57\x0f\x23\x74\xbb\xbf\xa1\xbb\x17\x07\x85\x80\x5d\x6b\x6c\x70\x1e\x82\x09\x52\xea\xe4\x5b\x8c\x23\x66\x11\x3a\x1d\xfb\x2e\x35\x85\x2a\xf4\x19\xb7\x54\xf9\xcf\x7a\x08\x1c\x3d\xde\x6c\x80\x53\xbf\x1c\xe0\xc8\x53\x39\xd5\x69\x9c\x42\x24\x76\xfc\x21\xf2\x6c\xe7\x5d\x2a\x7f\xed\x09\xfc\x0f\x41\x75\x78\x98\x47\xd8\x76\xc5\x1a\xa4\xe0\xbf\x7c\xe8\x42\xb8\x30\x8d\xc7\xa2\x8c\x82\x39\x52\x07\x14\xdc\x23\x31\x36\xe0\x9f\x55\x7c\x7e\xf3\xe0\xf8\x3b\xad\x63\xcb\x28\xac\x61\x6d\x39\x28\xf3\x83\x7d\xce\x1d\xd5\x8a\xcb\x8d\xdb\xc7\x2e\x82\x2d\xee\xe4\x5f\x00\x77\x6a\xcc\x88\xe0\x0c\xd3\xa9\xdb\x48\x6d\x92\xd5\x35\xa5\x7a\x0f\xdc\x4f\x90\x3b\x62\xe5\x17\x22\x1c\x30\x8c\xba\x2e\x30\xff\xe7\xb9\x19\x37\xa9\x94\x17\x72\x1f\x56\xfe\x6d\xf4\x48\x40\xe9\xe4\x11\x36\x92\x9c\x0c\xa3\xdc\x28\xdd\xf2\x37\x9e\x4d\xcf\xde\x83\x72\x3e\x2d\x4c\x9e\x23\x29\x9c\x05\x6a\xfb\x31\xd3\xe7\x0d\x08\x5d\x0a\x31\x2c\x5c\xd5\x70\xb6\x99\xde\xa8\x71\x74\x58\x53\x13\x48\xc9\x6f\x6e\xb5\x2d\x7e\xe6\x1d\x56\x60\xf6\x5e\x90\x9a\x14\xce\x10\x33\xdc\x85\x3f\x2f\x25\xd0\x9c\xf4\xe4\x0d\x07\xef\xf7\x2e\x15\xa3\x90\x56\x4a\x2b\xe3\xc0\x42\xd8\x9a\x68\x66\x0a\x97\xff\xac\xec\x49\x67\xa4\xb6\x18\x71\x2d\x70\x60\x75\x65\x20\xc2\x9e\xe8\xd9\x22\x0a\xd8\x61\x5c\x4f\xcf\x39\x69\xbd\x3b\x2e\x09\x47\xe1\xf0\xbe\x7e\x2d\x80\xe0\xa6\x14\x80\xc3\x16\x6d\xb5\x58\x22\x18\xbb\x0a\x8b\xe9\x84\x8e\xfd\x41\xb6\xce\x0c\xd7\x95\xc4\x86\xab\xb6\x72\x10\xbe\xb6\x0c\xd0\x78\xb4\x6a\xeb\x7f\x4f\x48\x50\x31\x90\x2b\xcd\x71\x31\xe0\x0b\x70\x35\xaa\x2d\x43\xfe\xe0\x63\xf7\xf3\x0b\xd5\x70\xda\x1d\xbb\x65\xc0\xca\x92\xa4\x81\x26\x32\xe4\x32\x77\x85\x53\xe3\x5e\x85\x6c\xaa\x82\x18\x22\x1f\xd6\x31\x6a\xb0\x86\x91\x73\xb3\x84\x09\xbc\xef\xe6\xd2\xdb\x92\x10\xf9\x02\x41\x73\xb6\x6d\xbb\x92\x67\x7c\xbc\x71\xc8\xa1\xcd\x58\x3f\xa6\xf3\x54\xd3\xc9\x3f\xa8\xb1\x6c\x71\x37\x4f\x25\xa0\x0c\x33\x2f\x85\xa8\xbe\xfd\x54\x03\x88\xfb\x50\xdb\x9f\x5d\x96\xe4\xe4\xe6\x98\x83\x3c\xe3\xd6\x3c\x10\xb8\xee\xc7\x0a\x24\x3b\x90\x15\xdb\x45\x94\x31\xb6\x2f\x56\x68\xbb\xa6\x0f\x07\x04\xf6\xbd\xfe\x95\x46\xea\x47\x5c\xef\x2e\xbc\xcb\xa4\xb7\x68\x08\x48\xe8\x2b\xef\xf5\x85\x4e\x49\xf6\x5b\xb7\x73\xa4\x92\x2e\x90\xf9\xb8\xaf\xc7\xcf\x81\x87\x30\x58\x8e\xd5\xaa\x7b\x39\x98\x26\xaa\xdd\x54\x37\x2f\xcb\x76\x14\x58\xb6\x4d\xe6\x68\x57\xf4\xad\xac\xd4\xc3\x29\x00\xcb\x77\x13\x6a\x53\x5d\x7b\xbb\xb5\x54\x59\x7a\xec\xf3\x9f\xf6\x98\xb4\x5e\x6a\x21\x8d\xf1\xd2\xab\xe6\x15\xeb\x8d\x9e\x18\x24\xc0\xbe\xcc\xe9\x07\x67\x89\x9e\xbf\xd2\xc7\x30\x14\x4b\x32\xc7\x46\x04\xc0\xe5\x3e\x25\x05\xbb\x15\xd2\x80\x07\xa8\x7b\x99\x31\xd6\xee\xc0\xa6\xcb\x5b\x0f\x96\xd3\x19\x4b\x24\x23"}, +{{0xf8,0x20,0xe6,0xf2,0x4a,0x84,0x18,0xb6,0xac,0xda,0x16,0x5f,0x29,0xa3,0x60,0xf7,0x67,0xcd,0xed,0xde,0x8f,0x64,0xd7,0x68,0xb9,0x5f,0xc2,0xa5,0xf3,0xf4,0x04,0xe7,},{0x79,0xc4,0xb2,0x63,0xb2,0xe5,0x8f,0x67,0x86,0x28,0xd4,0xea,0x82,0xb1,0x75,0xac,0xa2,0x30,0xb9,0xa2,0x02,0x85,0xc8,0x28,0xf9,0x4e,0x1f,0xfd,0x63,0xd7,0x5b,0x23,},{0xf9,0xfd,0x72,0xf3,0x21,0xca,0x21,0x33,0xbf,0x85,0x85,0x90,0x8d,0x9c,0xa7,0xb8,0xe3,0x36,0x22,0x7e,0x3f,0xfb,0x37,0x49,0xa1,0xfb,0xe8,0xc9,0xb1,0xe5,0xd5,0x0e,0xf0,0x1f,0x9d,0xb5,0xf0,0xd2,0xa7,0xc7,0xc1,0x39,0x9b,0x97,0xc9,0x04,0x4e,0x1b,0xc1,0xad,0xc3,0x2b,0x8b,0xea,0x46,0xda,0xd7,0xb8,0x10,0x26,0x46,0x96,0x03,0x03,},"\xab\x6b\xd4\x5b\xb0\x6d\xfb\x90\x69\x11\x8f\xf9\x98\xf3\xbd\x39\x3e\xa8\xe9\x44\x97\x9e\x89\xe0\x49\xf2\x50\x5c\xd8\x93\x1b\x93\x08\x6b\x7e\x9d\x8e\xe7\x64\xe9\xb4\x47\xea\x4e\xa1\x21\x38\xbb\x45\x27\x5a\x21\xa1\x98\x43\xf7\x5d\xc5\x42\x1d\x61\xff\xd8\x61\x83\x8e\x58\x33\x82\x5d\x67\x16\x2f\x32\x59\xc2\x64\x47\xbe\x51\xdc\x18\x02\xef\x5a\x04\xba\x73\xb7\x83\x93\x57\x06\xab\xb4\x2c\x51\x3b\x65\xf2\xbb\xc4\x4f\x83\xda\x10\x61\x24\x2f\x2d\x5e\x51\x98\xf3\x8c\x10\x71\x7a\x86\xa3\xa1\x97\xe7\xcd\x90\x34\xf6\x36\x11\x44\x99\x03\x72\x77\xac\xb4\x72\x2c\x06\xa9\x1c\xb2\xf6\x5e\x21\xeb\x8d\x22\xd3\x6a\xd7\x3b\x42\x65\xf7\xa7\x94\x7e\x00\xe7\x22\xbd\xa6\x70\x43\xcd\x12\x81\xbc\xd8\x7e\x76\x3f\xc9\x7b\x54\xc8\xf8\x68\x36\xcd\xbf\x08\xc9\xa1\xf7\x00\xf4\xea\xed\x9e\xa5\x9a\x6f\xc1\xbc\x0d\xf8\xc9\xec\x1f\xc2\x97\x7c\xad\x60\xf9\x78\xab\xc0\xc8\x38\x1a\xa9\xfb\x06\x0e\x3f\x99\x37\x8a\x51\xb2\xd9\xaf\xbe\xf3\x58\xd5\x51\x62\xa3\x89\x22\xeb\xb8\x7d\x2a\x3e\x0f\x0f\x40\x00\xb1\xc3\x9b\x15\x02\xe9\x59\x45\xe8\xac\x9f\x4a\x3e\xa7\xc9\xdd\xb5\x81\xa5\xec\x06\xc0\x0b\xa8\x7a\x73\x70\x84\xb3\x84\xfa\xba\x09\xc8\x48\x71\xdd\xd6\x7d\xc1\xbe\xbb\x2f\x7f\xbd\x94\xa5\x59\x7d\x01\x9f\xe6\x29\xe5\xbf\x12\xbe\xa2\xe3\x3c\xa8\x4c\x68\x0d\xc5\xa3\x98\x9b\xbf\x3a\xf9\xee\xec\xe8\xab\x8f\xc8\x61\xe3\xb8\xbf\xc1\xe6\x7e\x2a\xee\x32\x6b\x37\xfb\x9b\x51\xcf\xa0\xb5\xf5\xfc\x16\x00\x69\xb4\x50\xb7\x04\xe0\xfa\xb7\xfb\x6c\x5a\xb3\xc4\x0b\x8f\x0b\x3d\x09\x30\xb9\x11\x2d\x64\xb9\xda\xca\xb4\xdd\x87\x5f\x29\xd8\xc5\x8c\x5d\x20\x53\xad\x91\x48\xff\xde\x22\xd9\x0b\xc0\xd5\x0f\x5d\xec\xa6\x8d\x3e\xa2\x5c\x5b\x4c\x76\x88\x87\x1c\x0c\x77\xdb\xce\xea\xcb\xd0\xa4\x22\x9f\x49\x70\xec\x87\xb3\x44\x99\xe2\x78\x30\x3c\x06\x69\x4c\x30\xac\x68\x52\x4d\x11\xb1\x72\x79\x4b\x48\x12\x73\xa5\xda\xc4\x61\x22\xd2\x47\x20\x95\xa5\x63\xa4\x35\xd1\x85\xd5\xe9\x1d\xa7\x26\xe7\x45\x92\x99\x9c\xda\xc6\x88\xa3\x3f\x38\xf7\xc0\x35\x58\x8f\x62\x5d\xc6\xac\x73\xd0\x04\x7a\xb3\xd6\xd1\x2f\x1a\xe3\x3d\x8b\x62\xd6\xd6\xc6\xca\xcf\xf0\xbd\xd8\x94\xb5\x7e\x31\x89\x12\xac\x0c\xf4\xa5\x34\x76\x2b\x2f\x6d\x26\x3c\x93\x58\x04\x42\x3e\xd8\x68\xcf\x8c\xfb\xb8\xbe\x8f\x6d\x8a\x71\x4a\x26\x8a\x39\x0e\xdc\x2d\xd5\x09\xd2\xdc\x96\x85\x1d\x1b\xd4\x32\x49\xbd\x0f\x69\xb0\xc4\xcb\x2f\xf4\x08\x0d\x1f\xd5\x62\x2b\xc2\x38\xdd\xa6\xe9\x30\x02\x5d\x8a\x2b\x12\xb9\x72\xf9\xeb\xa1\x74\x21\xd4\xce\xa6\x42\xf4\x0a\xd9\xea\x85\x47\xae\x59\x49\x8c\x3a\xd1\xb9\xa0\xc3\x4e\xd8\xc0\x1a\xae\x3b\xd2\x1a\xc1\x77\x43\xb5\x77\xf9\x51\x5c\xfb\xdd\xe2\x70\x4d\xc5\x7e\x80\xf1\x25\x32\x3d\x55\x10\x0b\x9f\x69\x79\x27\xd4\x31\xdf\xe7\x36\x31\xb5\x8e\x52\xaa\x6a\xeb\x04\x78\xbf\x45\x95\x52\x43\x86\x89\xfb\xeb\x9c\x60\xd8\x7a\xae\x09\x95\x43\x62\xcd\x02\xa2\xb0\xb4\x79\xef\xd3\x8f\x17\x82\x1a\xf3\x9b\x21\x92\x6e\xe0\x2f\x7d\x97\x2a\xd0\xf5\x4e\xa6\x57\x2c\xc3\xeb\xd0\x20\xb1\xee\x26\x88\x25\x33\xbd\x19\x11\x43\x23\x81\x5f\x67\x2e\xc8\xc9\x05\x68\x73\x0a\x58\xe4\xe1\xe3\x5f\x68\x21\x21\x9a\x32\xb8\xa6\xc5\x2c\xed\x6f\x95\x73\xd9\xf3\xbe\xb2\x85\x13\xba\x62\xfb\x20\x1f\x7f\xd4\x1b\xb1\x0c\xa3\x4b\xb1\xc7\x0f\x2f\xd7\xbb\x92\x99\xa7\xc5\xf7\xf2\xe0\xfa\x1d\x1a\xf0\xe9\xae\xf5\xed\xe7\xc1\x69\x50\xe8\x60\xec\xd6\x1f\x18\x42\xa1\xa2\x2c\x98\x31\xc0\xc0\xd4\xed\xa8\x40\xb0\x88\xa5\x45\x20\xc9\xb1\x8c\x76\xeb\xa9\xbe\xbc\xd5\x91\x38\x1c\x18\x0d\x7f\x86\xa0\xe5\x8a\xdd\x92\xb9\xb0\xc8\x07\x6a\x7c\xdc\xab\x60\xde\xa4\xc1\xaf\xb1\x8c\x8b\x94\xb1\xb3\x92\xcc\xfb\x4d\xae\x27\x11\xe7\xd1\x2d\x2b\xc7\xc7\x82\x5f\x63\x99\x2e\xc3\x24\x71\x63\xc2\x83\xb1\x07\x5e\x32\x24\x5f\x69\xcf\x47\x24\x0a\xef\x0d\xb4\x3e\xfa\xe8\x6f\xc1\xfd\x3b\xb9\x9c\xf5\xb7\x89\xf5\xbc\xba\x95\x04\x65\x7d\x9e\x62\x2a\x4a\xa1\x6f\x01\xd4\xd8\x44\x41\x31\x24\x44\x7d\x6d\x1a\x44\x23\xe7\xb5\x5d\xb7\xe6\xa3\x1a\x31\x9f\x4b\xac\xae\x43\x0a\x33\xa9\xbd\xd4\xef\x36\x80"}, +{{0x0a,0x05,0x6b,0xe0,0x39,0xfd,0x55,0xda,0xda,0x44,0x1d,0x03,0x73,0x61,0x27,0x3f,0x20,0x6e,0x00,0x0a,0x74,0xa0,0x5c,0x51,0xc0,0xcb,0xb6,0x27,0x43,0xf1,0xf3,0x40,},{0x73,0x14,0x02,0x17,0xa4,0x93,0xa1,0x78,0x66,0xff,0xf5,0x15,0x48,0x32,0x27,0x3d,0xf7,0x9d,0x58,0x11,0x54,0x3c,0x22,0x2a,0x39,0xd0,0x56,0xb8,0xc9,0x70,0xdb,0xfa,},{0xfa,0xb8,0xe5,0xd9,0x3d,0x7d,0x46,0xc6,0x5e,0xe1,0x17,0xc5,0x37,0x5e,0x73,0xc9,0x70,0x5f,0x87,0x54,0x17,0x7f,0xdd,0x46,0xef,0xed,0x47,0x37,0xc2,0x87,0x68,0xcc,0x4b,0x95,0xa9,0xc8,0x4c,0x52,0x9b,0x4b,0x91,0x6b,0x28,0xda,0xbd,0x87,0x41,0x18,0x31,0x44,0xbc,0xdb,0x48,0x3d,0xf9,0x8a,0xf8,0x9d,0x82,0x40,0xcf,0x09,0x46,0x04,},"\xa5\xab\x14\x76\x84\xe4\xd4\xa7\xbc\xb5\xa9\x6f\xb3\x98\x18\xe2\x3f\x56\xc2\xd8\xa7\x44\xe9\x12\x3d\x62\x08\x39\x30\xab\x1d\x0b\xb5\x32\xe6\x87\x14\xfc\xec\x7e\x6c\x41\x13\x4b\x6b\x19\xdd\xd8\x67\xfe\x63\x5c\x9e\xd6\x53\x93\xee\x39\xc5\xe8\xfa\xb4\x56\xcb\x5b\x32\x79\x78\x83\xf3\xcd\x9a\x09\x02\xb9\x79\x63\x48\xee\x66\xc6\x91\xfb\x4f\x2b\xb1\x47\x64\x41\x06\x57\xc7\x4a\xb3\x64\x56\x78\x79\xb6\xfa\x0a\x6f\x4d\xaf\xd9\x30\xd9\x23\x4c\xd7\x83\x4f\xb9\xd0\xee\xdf\xbb\x5a\x39\x4b\xf0\x84\x6e\xc6\x96\x9c\x2e\xf7\xce\x39\xe3\x85\x38\x95\xff\x5b\x4d\xa3\x1e\x54\x34\x1b\x42\x72\xe4\xa2\x60\x49\x18\x9f\xf2\x82\x41\xce\xef\xfb\x7d\x2e\x1f\xaf\x4f\x77\x9f\xa6\x5c\xac\x0f\x57\x83\xc6\x0a\xe7\x7d\xe3\x0a\xd4\x46\x5f\xdb\x39\x0d\x42\x57\x1e\xff\x4a\x63\x13\x63\x49\x93\x7d\x6c\xae\xef\xcd\xae\x22\x9e\x2f\x28\xce\xa8\xab\xf3\xff\xae\x3c\x3e\xcc\xd9\x06\x70\xa4\x21\x2a\x2b\xee\x1c\xa6\xa5\xb5\x4f\x09\x4f\xc3\x23\x10\x58\xf5\xcb\x9e\xce\xb9\x99\x3b\xe4\x70\x27\xd5\x1c\x18\xde\xca\x41\xcd\xda\xf4\xe8\xbc\x56\xa9\x9f\xd2\x70\x35\x5f\xf4\x59\x71\x95\x0e\x34\x37\xa1\x98\xcc\xc3\x25\x41\x68\xdf\xc1\x57\x40\x80\x80\x2e\xe1\x01\xa6\x17\xfb\x60\x4e\x86\x8f\x8f\xa8\xfb\x30\xda\xeb\x43\x07\x4d\xe1\x1f\x24\x83\xd9\x16\xde\x56\x43\xb7\xca\xc2\x3d\x93\x40\x50\x8a\x3f\xd6\x21\xec\xd2\x50\x04\x35\x6a\x53\x55\x4a\xd3\xad\x7d\x5d\x25\x81\x7a\xd7\xc9\xa6\x10\x00\x8c\x67\xac\x16\xba\x42\x11\xc4\x2f\x5d\xad\xf8\x6c\x2c\x3a\xed\x82\x5c\xf2\xa9\xb5\x23\xbf\xc0\x3d\xd7\xde\x40\x0c\x67\x80\x7e\x13\x9e\xa5\xdb\xce\x4e\xe1\xf7\xd3\x18\x88\x9b\x01\xa9\xf4\x48\x03\xc3\x22\xac\x3b\x61\xe2\x0e\x63\x12\xd0\xa0\x3b\xf9\x92\x7f\xa3\x3f\x04\xed\x7e\x20\x7b\x16\xf2\x65\x02\xc2\x98\x3a\x3a\x96\x1f\x22\x44\x61\xfe\x9b\x64\x92\x3b\x1d\x09\x18\x94\x76\xae\x8d\x00\x1d\x0e\xca\xae\x4d\xf6\x0d\xb3\x5f\x44\x8b\xb6\x12\xf9\x65\x5a\x5f\xb1\x44\xdf\x11\xd8\x3a\xa6\x93\x68\x86\xc3\x04\x94\x9e\x59\xaa\x46\xdf\x65\xc2\x2c\xe7\xbf\x28\x9b\x3c\x77\xc2\x5d\x89\x6b\xe6\xd5\x1d\xee\x10\x74\x82\x61\x68\x8c\x8b\x07\x1c\x85\x6f\x99\x62\xc6\x67\x75\xdd\xf1\x60\x83\xda\xe0\x65\x87\xe3\x2a\x63\x61\x19\x9d\x72\x09\x7e\x38\x3a\xd7\x43\x94\x91\xb5\xa5\x63\xa3\xe6\xd5\x8d\xa3\xd5\xab\xb1\xde\x84\x89\x0a\x36\xb4\x21\xce\x03\xd4\x84\xdf\xd6\x00\x39\x63\x8d\x46\xed\xfb\x60\x65\x9e\x3a\x25\xac\x6e\x9a\x93\x5a\xd6\xda\xd5\x0f\x92\x7b\xcc\x2f\xf9\x9f\x99\x24\xa5\xb7\x99\x5d\xc2\x3c\x8f\x30\x1c\xcc\x77\x69\xf7\x1c\x18\x26\x09\x04\xa3\xdc\xfb\x81\x7d\x2d\x80\x5c\xb1\xf1\x96\xbe\x8b\x6e\xcf\x35\x2b\xc2\x96\xbc\x3f\x76\xea\x91\x35\x3f\x8c\xf3\x5b\xcd\x2b\x57\xeb\x59\x42\x77\x3d\x68\x34\xac\x50\xee\xad\xc7\xe6\x64\x61\xd1\xda\x09\x8c\xce\xc7\x5f\xf7\x20\x52\x15\xf5\x24\x59\xd9\x76\x20\xf9\xf0\x28\x9e\x93\x91\x1d\xb3\x9b\x21\xdf\x81\x8f\xdf\x0b\xed\x45\x50\x92\x44\x63\x3d\xf0\x1c\xdd\xdb\x4b\x75\x97\x2f\xa7\xea\x6f\x73\x28\x1c\xbd\xbb\xd1\xbc\xb0\x0c\x3b\xc1\xb1\x72\x8e\xea\xe0\xbb\xa1\x72\xb1\x31\xf5\xd3\x08\x90\xa3\x41\xe6\xb7\x2f\x7e\x89\xdd\x4b\x6d\xb3\xe7\x9b\x69\x27\x58\x6c\xf2\xc8\xac\x38\xdd\x14\xf3\x74\xd7\xf5\xbb\xa9\xf4\x35\x3d\xef\x10\xdd\xc9\x4d\x3d\x11\x18\xc5\x69\x9e\x38\xb6\xb5\x04\x91\x8e\x58\x9e\xfe\x3f\x7e\x97\x3f\xb4\x0e\x2e\xbd\x05\x7d\xe1\x38\x5e\x39\xd6\x99\xa8\xf6\x83\xb9\x62\xfa\xe4\xf3\x90\x28\x81\xf1\xaf\xbe\xd7\xc7\x83\x82\x35\x58\xc3\x6d\x68\xc6\x87\x5d\x16\x6f\xa2\x43\xeb\x2a\xe1\x4f\x7e\x63\x15\xa6\xd2\xab\x4e\x79\xea\x8e\x16\xe6\x9d\x30\xed\xc7\x08\xf1\xe7\xaf\x7a\xda\xfe\xdc\xd3\x16\x88\x98\xb3\x31\x87\x81\x78\xc4\xba\x88\x33\xd2\x0b\x3c\xac\x9d\x32\xb8\x88\x8c\xc6\x78\x32\x06\x39\x74\x70\xa2\xe7\xcc\x4c\x98\x09\xff\x79\xce\xac\x9d\xc2\x4c\xa1\x43\x8c\x91\x9c\x8a\x41\x5e\x82\xf0\x90\x2b\x4d\x9c\xf4\xcc\xd5\x76\x96\x8d\x5b\xee\x81\xc5\xf1\x9c\x7d\x57\xb9\xba\xda\x8e\xab\x47\x56\xea\x27\x0d\xd2\x61\x29\xe6\x12\x2e\xe2\xd6\x15\x24\x2b\xc7\xfa\xbf\xf4\xf8\x31\x2e\x68\x6c\x8f"}, +{{0x22,0x05,0x24,0x86,0x0c,0xb8,0x9a,0xb2,0x95,0xbd,0x88,0x4f,0x98,0x8a,0x57,0x91,0x18,0x68,0x69,0x3d,0x6b,0x10,0x5a,0x80,0xb2,0x30,0xf2,0x1e,0x57,0x80,0x5a,0x7d,},{0x4a,0xb3,0x2b,0xc1,0x56,0x6a,0x76,0x77,0xe7,0x99,0x73,0x4d,0xc8,0x41,0x81,0xfb,0xb6,0x54,0xb8,0x13,0x37,0x91,0x80,0xf1,0xdd,0x35,0xae,0xf2,0xd3,0x24,0xc1,0x2c,},{0xdb,0x1c,0xc0,0xc5,0xdb,0x77,0x3e,0xc5,0x16,0x89,0xbe,0x28,0x84,0x2f,0xa6,0x79,0x1a,0x7d,0x75,0xe2,0x9c,0x22,0x8a,0xe9,0x59,0x3a,0x58,0x0e,0x08,0x75,0xb1,0x67,0x0f,0x09,0xb0,0x34,0x42,0x92,0x9a,0x18,0xf1,0xe9,0x41,0x4e,0xa3,0x43,0x15,0xff,0x09,0xd9,0x1d,0x92,0x2e,0xe4,0x7f,0x10,0xf7,0x1d,0xa4,0xab,0x13,0xb7,0xd9,0x01,},"\x02\x4a\x54\xac\x5e\x01\x63\xb3\xa4\xfd\xd0\x2f\x59\x36\x88\x8a\xe2\xf9\xb7\x4a\x64\x14\xb5\x3c\x63\x81\x17\x3b\x09\x5a\x4d\xda\xcf\xc3\xa6\x9f\x19\x16\x7d\x0f\x1a\xe0\xc1\x20\xbb\xa7\xe9\xfc\xb7\xcc\xfc\x79\x6d\x89\xea\x46\xef\x80\x58\x86\x6e\xf6\xda\x7d\x01\xa6\xa1\x42\xea\x69\xd7\x20\xc4\xf8\x05\xac\x54\x05\xa8\x01\x2c\x3c\x2a\x82\x63\xb5\x37\x2d\x59\xbf\x7f\x40\x99\x29\x90\x13\xd2\x62\x59\xdf\xd5\x19\x3e\xce\x56\x17\x97\x77\xbe\x51\xb8\x6b\xd1\xce\x5f\x1f\xc9\x15\x6f\x2b\x3a\x32\xc0\x9d\x86\xbc\x61\x32\xde\x57\x61\x02\xe2\xf0\x3c\x71\x6d\xb5\x36\x6c\xcb\xe7\x42\xae\xe3\x55\x2a\xc3\xb3\x9d\x0e\xc7\xd4\xe4\xe9\x62\x6b\xf8\xec\xe0\x31\xd6\x78\xd3\x48\x09\x05\xc0\xe3\x38\xfb\x7c\xc0\x26\xe3\xe7\x9c\xf2\xc2\x78\x1a\xc2\xa5\xa4\x0d\xf4\x28\x4e\x23\x5a\x03\x89\xe9\x28\xfc\x63\x55\x7d\xc6\xf1\x99\xfc\xec\x5f\x36\x1e\xa2\x47\x59\xfa\x7c\x5f\x71\x97\x8c\x0b\xa2\x45\xe4\xb0\x3a\xe4\x35\x94\x1c\x86\xc8\x1a\x51\x43\x0c\x2d\xc9\x92\x7e\x3b\x0f\x4e\xc4\xeb\xa7\xc2\x74\x5b\x49\x39\x87\x15\x4d\x7d\xa8\x5b\x67\xde\x21\xc5\x98\x40\x7f\xb2\xa7\x60\x80\x4a\xd0\x5b\xfd\xfa\x45\xa6\x13\x22\x4b\x22\xa0\x85\x88\xcc\xea\x3c\xbd\xf4\x7a\x19\x8b\xeb\xf8\xcf\xed\x86\x49\xd6\xd5\xf3\xfa\x50\x13\x76\xbd\xfb\xa4\x00\x3d\xac\x22\x37\xdc\xac\xe5\x31\x5b\x7f\xef\xb8\x79\xa8\x9a\x85\xbc\xe6\xda\x52\x6f\xc3\x60\xcb\xb4\xfd\x55\x4e\xf0\x13\xf3\x3b\x73\x84\xcd\x2b\x22\xa8\x85\x77\xf3\xa2\xd3\x66\x42\x2a\xae\x46\x41\x7b\xa9\x16\xe1\x64\x6e\x24\x40\x4a\x88\xb5\xd5\x3f\xf1\xae\xd2\xa4\x7b\xaf\x81\xfc\xb4\x28\x63\x97\x99\x13\x94\xb2\xec\xc3\x96\x67\xac\x46\xc2\xbd\xb6\xd0\x23\xb3\x3d\xb0\x13\x45\x7c\x40\x05\xd8\x39\x01\x5d\x88\x51\xf0\x28\xac\x33\x4f\xb2\x4b\xba\xd2\x90\x2a\x4d\x63\xae\x68\xe0\xec\xa7\xea\xea\x1e\x85\x65\x29\x64\x7b\xaf\x14\x12\x21\x37\x54\xed\x50\xaf\x3f\x43\x6e\x9b\xaf\xc1\x60\x16\x39\xb3\x9d\x3e\x52\xa9\x3a\x89\x8f\xb6\x01\x9f\xd5\xed\x6e\x7d\xfc\x05\x0e\x7c\xe5\xf3\xd3\x5c\xeb\x50\x67\x02\x1c\x0f\xbd\xc7\x08\xd3\xf2\x6b\xd6\x05\x68\xd1\xed\x2b\x61\x2b\x69\x62\x35\xd5\x33\x33\x18\xf9\xa6\xc9\x87\x23\x5a\x7a\x07\xf8\xc6\xa9\x35\x4f\xb8\xe7\x34\x76\x30\x65\xaf\xcd\x4d\x93\x77\x64\xa4\xf0\x37\xcc\x7e\x7e\x2b\x93\x21\x7f\x16\x41\x68\x4f\xa8\x1b\x7f\xf7\x98\x6a\x28\xb3\x8e\x95\xb3\x32\xe7\x46\x49\xe8\x3d\x0d\xed\x79\x5c\x57\xf2\x4c\xf2\x76\xe0\x14\x39\x01\xba\xfe\xf0\xf1\x69\x3f\xe7\xcf\x10\x90\x4f\xb0\xd8\x80\xd7\x2e\x44\x71\x6a\x70\x69\xda\xaa\xe7\x42\xcf\x0f\xf3\xed\x92\xf5\xf7\xd1\xe1\x0e\x04\x9d\x8d\xf0\x43\x63\x1e\xd0\xed\x4c\x4a\xc4\x02\x2d\x84\x03\xcb\x04\x21\xb4\x54\xcb\xfb\x6f\x48\xa3\x0e\x9e\xe1\x60\x9a\xd7\xb6\x82\x11\x97\x7a\xcb\x33\xb9\xc1\xa1\xbe\x73\x58\x14\xc5\x8f\x66\xdb\x5f\x0b\x8a\xc7\x73\xb1\xd5\x8d\x4e\x6b\xc4\x5d\xfd\x48\xa2\x94\xbb\xd2\x5e\x92\x67\x1f\x56\xf3\x02\xf2\x9b\x50\xd8\x04\x31\xc8\xf2\xea\x33\x99\x62\x57\xb2\x08\xe0\x57\xea\x76\x72\xcc\x2d\x1c\xd4\x20\x4b\x85\xb2\xab\x50\x90\x27\x13\x13\x59\xae\xb4\x2e\x3e\xcc\xdb\xae\xcf\xe2\xcd\x3e\x5a\x33\x13\x26\x6e\x76\x11\x94\xff\x69\xca\xe9\xe3\x7e\x51\xcc\x0a\x54\xf0\x86\xdd\xe1\x3c\xb3\x31\x18\xe3\x4f\xe3\x3c\x74\xd7\x35\x58\x27\x52\xd6\x8d\x21\xc7\x9e\x5c\x3a\xae\xa9\x4b\xa1\x07\xcb\x7e\xe8\xa7\x0a\x3f\x9a\x01\xe9\x80\x8c\x0a\xeb\xa6\x66\x53\x15\xb4\x56\x25\x84\x0a\x03\x3a\x6e\x2a\x87\x54\x95\x05\x79\x42\xed\x9b\xb2\xce\x6e\x4e\xe6\x0b\xed\x47\xcd\x9d\x58\x4b\xc2\x45\x24\x39\x7a\x10\x94\x98\xee\x2a\x97\x3a\xad\x6a\x29\xb7\x0a\x1c\xfb\xfe\x9a\xa5\xc7\xcb\x9f\x35\xf0\xfa\x00\x22\x7f\x43\x98\x8d\x07\x61\x9b\x6f\xb2\xf6\xd3\xbe\xe2\x8e\x10\xee\x70\x53\x47\x01\x5a\x92\x2e\x2e\x88\xd3\x4f\xb0\xce\x51\x5b\x08\xdf\x3a\x1b\x63\x4f\xf9\xec\x15\xd0\x59\x41\x82\xc8\x6e\xbb\x0d\xb7\x83\x61\x2a\x7d\x19\xe4\xb2\x2e\x82\x2d\x56\x62\x45\xae\xd7\x2e\x69\x4c\x3d\x10\x1b\xfa\x4c\xa8\x79\x86\x2e\x5f\x99\xc2\x3a\x5d\x66\x08\x3c\xe0\x6d\x87\xf3\x99\xaa\x78\x88\xab\x83\xb8\x66\x44\x72"}, +{{0x4e,0xf6,0x0f,0x06,0x91,0xd7,0x37,0xe6,0x4d,0x43,0x7b,0xfd,0x33,0x98,0x33,0x0e,0x55,0xe3,0xc0,0x94,0xcf,0x41,0xfc,0x55,0x7b,0x0f,0xe0,0xb6,0x43,0x90,0x9a,0xb8,},{0x30,0x6a,0xb1,0x46,0xe5,0xc8,0xcd,0x63,0x0f,0x9b,0x48,0xbf,0x8b,0x68,0x5d,0xb0,0xb6,0xb5,0x53,0xef,0x69,0x68,0x68,0x53,0xb6,0xb5,0x31,0x96,0x01,0x18,0x54,0x8c,},{0xcb,0xf7,0xcf,0x22,0x08,0x1c,0x5f,0x23,0x5d,0xba,0x35,0x63,0x0f,0xb3,0xf0,0x40,0x8f,0xce,0xcc,0xef,0xeb,0x28,0xb9,0x9d,0x74,0xdb,0xd9,0x8c,0x90,0x2c,0x7d,0x99,0xba,0x9c,0xa7,0xfa,0xb3,0x74,0x7c,0x50,0x4c,0xc2,0x19,0xf4,0xdd,0x10,0x10,0x81,0xf5,0x8c,0xe6,0x16,0xe2,0x92,0x80,0xe3,0x62,0x53,0x9f,0xe4,0x9f,0x34,0xd7,0x05,},"\x0a\x18\x8a\xc2\x6f\x3c\x5d\x89\xf3\xd5\x88\x37\x4f\xac\x5e\xcf\x9a\x46\x7e\x21\x65\xb3\x1d\x0b\x0f\x23\x50\x1b\xd2\x2e\x62\xbf\x35\x55\xff\xba\x94\x63\x1d\xe7\x4a\x6a\x3c\x3c\xf6\x3b\x03\xac\x1b\xbb\x37\xd2\x33\xec\xa5\x99\x3b\x09\x70\xa0\x22\x0d\xe8\xd6\xc4\x1a\x97\x03\x07\x30\x9a\x52\xda\x05\x76\xdc\x33\x4d\x80\x64\x47\xaa\x09\xd0\xb2\x45\xea\xcd\x0b\x42\xc4\xe1\x9f\xa3\xd6\xfb\xdc\x22\x94\x30\xeb\x3c\x75\x58\xaf\x53\x31\xc6\xe7\xfc\xc2\xe5\x52\xce\x35\xd5\x79\x07\x3b\x54\x8d\xc1\x15\xbb\xd2\x7e\x5a\x33\xce\x1c\x47\xfc\x84\x61\xe3\x91\xb6\xd7\x67\x95\x34\x87\xcc\x52\xee\x67\x3b\xc4\xbe\x96\x56\x9c\x85\x57\x36\x9e\xbb\x6e\x02\xf7\x92\x38\x10\x8c\x3b\x58\x56\xee\x38\x1a\x79\xff\x46\x4c\x8f\x60\x09\xfd\x47\xe6\x7b\x4c\x80\x20\x1e\x11\xe6\x1a\xb8\xf5\x9b\xa5\xd0\x7b\x15\xac\xe3\xfb\x37\x4c\x64\xb6\xb4\xc3\x45\xe2\xb0\x0e\x91\x51\xab\x8e\x1c\x5c\x98\x56\x8b\xc5\x8d\xd0\x81\x2a\xaa\x3b\xee\xe1\x65\xe7\xea\xe5\x8f\xbd\xe6\x30\x77\x20\x3c\x4f\xd6\xe1\x60\x68\xd7\x6e\x3d\x3a\x13\xf1\xcd\xd7\x32\x88\xbd\x5e\x4d\xa4\x4e\xb1\x19\xa0\x4c\x4d\x32\xef\xa2\xf1\x3e\x74\x26\xa2\xf4\x1c\x56\x23\xc9\xb0\x66\xb1\x30\x36\x39\xb8\xfc\xea\x0d\x87\x74\xcc\x08\x04\x5f\x7e\x34\x63\x65\xff\x31\xd3\xb1\xed\x99\xe9\x7b\xca\x5f\x25\xc9\x2b\x28\x43\xac\x58\x5d\x02\x19\x3a\x2f\xd3\x94\x66\xf7\x3a\xaa\x98\x9b\x1f\xa0\x5b\x9a\x15\x7f\xd0\x27\x7c\x5e\x74\x5d\x25\x8e\x02\x78\x03\xa5\x24\xad\x94\x30\x94\x25\xc3\xf4\xde\xc3\x1c\x0e\xfc\x54\x77\x52\xf4\xc7\x19\x4c\xbb\x27\x2f\x84\x9a\x52\x16\x9c\x6a\x07\x8d\x20\xed\xe1\x43\x20\x16\x52\x84\x77\xb5\x8c\x2b\xdf\x60\x63\xf9\x44\x7e\x33\x83\x7c\xcb\x43\x7d\x8d\x6b\x95\xcf\x4c\x44\xbe\x70\xc8\x19\x3a\xd9\x80\xa1\x05\xf3\xdb\x6f\x99\x30\xba\xb4\x67\x8c\x77\x63\x42\xfa\xf1\x70\xed\xf7\x42\x48\xd3\xb1\xca\x96\xf7\x31\xb9\xd0\x26\xd8\xf0\xf7\xc3\x4e\xd3\x72\xc1\xcd\xe1\x76\xf5\x5f\x55\x86\x75\xcc\x31\x80\xc2\x39\x02\xf4\xba\x95\x08\xd1\xc9\x1c\x3c\x9e\x68\x87\x30\x32\x7f\x3f\x7b\x63\x7a\x8f\xee\x54\x37\x37\x59\xfc\xb1\x7c\x92\x17\xea\x44\xce\x43\x69\x1a\x8f\x64\x63\x64\x0a\x4a\x5e\x15\x1e\x62\x54\xc4\xef\x12\x62\x3b\x49\x39\x4d\xa7\xcc\x79\x45\x26\x93\x81\x7d\x6b\xae\xa9\xa0\xa7\x58\x76\x94\x8b\x1f\x8d\x3b\x71\x7f\x9e\xc3\x67\x53\xf5\x32\x63\x71\x03\x83\xb9\x82\x62\xae\x63\x54\xff\x2a\x22\x83\x22\x0a\xd4\x2c\x5c\xb2\xcb\xbd\xf1\x2c\x87\x95\x13\x71\x0b\x16\xbe\x85\x6f\x3b\x13\x55\xb3\x6f\x4b\x80\xc0\x17\xc2\x1b\xe8\x5e\x96\x05\x3d\xa0\x50\xc4\x03\x12\x10\x0a\xbb\x64\x0b\x87\x3d\x88\xfb\x6e\xe0\xd1\x9e\x9e\x61\xb0\x4c\x97\x0b\xd1\xf0\x60\xdd\x31\x1b\xbb\x9a\x6e\x35\xb9\x85\xfd\xca\x17\xca\xee\x8c\xd5\xdb\x63\x7a\xcd\x90\xcb\x8e\x82\x32\x55\xc0\x56\x01\x8f\xef\x59\x20\xdb\x64\x0d\x22\x01\xc5\xed\xdb\xd8\xa9\xc9\x47\x4d\xa8\xde\xf7\xe1\x32\x5b\x3c\xc4\x36\xc7\x4f\x81\x5d\xb1\xe4\x2b\x42\x1f\xaa\xb6\x26\xa4\x37\x8c\x2d\x84\x26\x1b\xf6\x49\xa5\x3b\x32\x1f\x59\x8c\x44\xbb\xd3\x00\x2b\x06\xcf\x7f\x1f\xde\xf8\x4a\xb3\x5f\x73\xed\x7d\xc6\x50\x96\xcb\x1d\xc0\xcc\x0e\x34\xc5\x61\xc8\xa1\x5c\xf5\x27\x9a\xbb\xed\x9b\x16\xff\x24\xa9\x74\x4e\x3f\x5e\x64\x9c\xc9\xd8\x88\x4f\x89\x1c\x3f\xb7\x89\x02\x03\x1f\xfe\x0e\x01\x21\xc7\x20\x80\xad\x10\xc2\x47\xb7\xc9\x3a\x9e\xbb\x2d\x84\xd4\xf8\x77\x75\x0d\x7b\x34\x16\x39\x3d\x03\x04\x52\x26\xbb\x79\x94\xee\xa5\x8e\x27\x2d\xc1\x8c\x46\xb3\x82\xd1\xf9\x7b\x23\x76\x5f\xda\x7a\x8c\xe2\x1f\xc6\xb9\x8d\x72\x3f\xfc\xcd\x99\xac\x46\x55\xcc\x5d\x10\x10\x5a\x2a\x5b\x7c\x8c\xfb\xfb\x90\xe2\x7a\x9a\x80\x9e\x41\xae\x64\x00\x63\x28\x64\x05\xa9\xbe\x83\xac\x5d\x29\x07\xa4\x5f\x16\x3c\x77\x64\xb0\x9f\x99\xa5\x55\x93\x22\x0d\x69\x01\x29\x2b\x9b\x58\x03\xa0\xfe\x71\xb0\xe4\x44\x1c\xbf\xef\x84\x1c\x33\xce\xbc\x98\x36\x4d\x66\x6e\x5a\x9f\x5e\x7e\x69\xa1\x50\x8e\x43\x80\xed\x36\x13\x45\xb7\x24\x8a\x4c\x1c\x1c\xe0\x87\x69\xbc\x71\x52\xdd\xb3\x32\xfb\xa1\x76\x20\x0f\x5a\xbb\xae\x38\x12\xf4\x06\xda\x72\xdd\xe5\xdb"}, +{{0x19,0x7e,0x15,0xdc,0xe4,0xc4,0x7d,0x73,0x4d,0xbc,0xe4,0x68,0x8a,0x7a,0xd5,0xfe,0x41,0xeb,0xf2,0xaa,0x29,0xa2,0xbd,0xdb,0x2b,0xee,0x62,0x84,0x29,0xc1,0xbc,0x02,},{0x30,0xfa,0xc3,0x23,0x04,0x8b,0x0c,0x78,0x1a,0x9f,0x63,0xc1,0xee,0x69,0xf2,0xb9,0xe7,0x5a,0x27,0x06,0xd2,0x49,0x51,0x2a,0x27,0x39,0x60,0x7f,0x26,0xdb,0x13,0x8f,},{0x2c,0x3c,0x8c,0xd2,0x99,0xc9,0x06,0x0b,0x65,0x99,0x9b,0x03,0xa6,0x57,0x9b,0xc5,0x0e,0xf1,0xfe,0x0d,0x85,0x1f,0x23,0xbe,0x9c,0xb5,0x8f,0x8f,0xb8,0xc6,0x72,0xee,0x08,0x6a,0x53,0x9e,0xad,0x94,0x9e,0x08,0x7d,0xf0,0x91,0x12,0x2d,0x26,0xfa,0xaa,0xd2,0x06,0xa5,0xc5,0x2f,0xcd,0x58,0xb5,0x14,0xd7,0xa9,0x35,0xbe,0x01,0x79,0x08,},"\xfd\x97\x1d\x48\x94\x6b\x51\xff\xed\x7b\x62\xc5\xd0\x99\xc1\xe5\x6b\x13\x58\xb9\x22\x35\xe1\x01\x0e\x3f\x23\x84\x4d\xdb\x73\xbc\xee\x8d\x2e\x1c\x99\x77\x35\x3b\xc9\x6a\x22\x1c\x05\x60\x29\x31\xfa\x16\xcc\xc2\xab\x6d\x0f\x01\xc8\x46\xc2\x92\x0e\x99\xde\x02\x6d\xc2\x89\x7f\x3d\x5f\x3c\xee\x17\x4c\xe7\x51\xd4\xa8\x05\xee\x19\x59\xa3\xc6\x9c\xfd\x42\xd7\xc9\xaf\xd3\x1f\xa9\xb1\xcf\x05\x78\x6d\x8f\x90\x42\xa4\xf9\xf8\x1c\xf7\xac\x9c\x1c\x39\xb3\x6f\x1e\xe9\x5b\x98\xcf\x7e\xe3\xf4\x3e\x2c\x34\x37\x33\xd1\xd8\x2c\xc0\x8b\x2c\xde\xb7\x8d\x98\x20\x34\x08\x5f\xf4\xdc\x65\x36\xcd\x15\x4a\x79\x0c\x85\xc8\x61\x3e\xc4\xe5\xe1\xdc\x37\x7d\x38\xa7\x45\xd9\x38\xcf\xb1\x5c\x8b\x8a\xa8\x61\x21\x83\x5f\x2e\x25\xe9\xe6\xd0\xde\x68\x02\x5d\x81\x0c\x3d\xc9\xdf\x99\x1d\xad\xad\x39\xdc\x69\x81\xfd\xba\xc1\xff\x9b\x7a\x79\x1c\x39\x60\xd8\x56\x43\x66\xe5\xaa\x39\xa9\xe9\xc7\xcb\xf1\xd3\xf0\xf8\x20\xd1\xb9\x01\x08\x75\x1a\xc7\x64\xda\xbe\x05\xc5\x1c\x18\x52\x9d\xa1\xb0\x34\x96\x14\x66\x84\x24\xab\x4e\x93\x64\x40\xc4\xa2\x51\x3b\xe5\x28\x53\x93\x72\xee\xe7\x87\x54\x58\x9d\xbe\x79\x94\xfa\xa1\xf6\x22\x91\x24\xf8\x39\x95\x0e\xd0\x92\x3f\x43\x23\x31\x5a\xc9\x63\xbb\xe4\xc8\xe1\x77\xda\xc5\x16\xe7\x34\x22\x38\xf1\xcd\xf1\x40\xbe\xfc\x8a\xcd\xca\x3d\x00\x2b\x16\xc1\x39\x8d\x86\x86\x00\x30\x4c\x7e\x98\x53\xb2\x3a\x51\xb1\x7d\x9f\xd0\x61\x56\xe1\xd1\xd0\x8a\x28\x46\x09\x09\xfa\x20\x9c\xcc\xcc\x4c\xec\xbd\xb1\xa4\x63\x48\x08\x91\x15\x31\x86\x81\xa9\x5a\xe5\x80\xab\x67\x66\x04\x13\x84\x65\x1c\xc4\xe6\x14\x51\x03\x92\x3b\xdf\x4a\x32\xa9\x3d\x93\xee\xd3\x18\x79\x1f\x20\x80\x5f\x7e\xa8\x4b\x74\x3e\xe1\x1e\xad\x9e\x4c\xa0\x3d\xa7\x6d\xdd\x24\x9f\xd4\x47\x5f\xc1\xa3\x53\xc7\x0a\x83\x38\x9b\xfa\xc5\x20\x98\xdb\x06\x6d\x10\x29\xc4\xef\xfb\xed\x86\x4e\xbe\x7f\x10\x7e\x01\x03\xb3\xa8\xf3\xfd\x1d\x6a\xb4\x36\x0b\x99\xe8\xb1\x40\xc5\xea\x13\x3e\x92\x3c\x39\x2b\x8e\x40\x63\xaa\x6e\x52\x26\x38\xf6\x1d\x7a\x71\xc9\x22\x58\x97\xd9\xf8\xa1\xe1\x6c\xfc\xc8\x01\xe7\xd5\x41\x04\xeb\x10\xe6\x1a\x5a\xe6\x3c\x5c\x85\xa5\xb2\x93\x92\xab\x3a\xb8\xe5\xc0\x39\xf1\x00\xd0\xf4\x60\x0c\x61\x0e\x02\x09\x43\x6e\xf2\xec\xe4\xd0\xbd\xb0\xba\xb4\x37\xb2\xdb\x5f\x37\x08\xfd\xdf\x96\x66\x0f\x6f\xb1\xa9\x0d\x60\x48\xd3\x95\xaf\xaf\xa7\x60\xcc\xaf\x15\xde\xaa\x0e\xff\xeb\x26\xec\x17\x68\x1d\x17\x2c\x13\x30\xf7\x8e\x78\xa8\x73\x6b\x28\x5f\x61\x5f\x15\xd4\xf2\xc3\x13\xd2\x5f\x30\xae\xe9\xd1\xdb\x39\xf5\x35\xfc\xdd\x0e\xbc\x8e\x71\xb8\x9c\xe6\xb3\xfc\xb5\x67\xcd\x0f\xa2\x88\xf4\x8e\xd3\xa7\x59\xbb\x2e\xd2\x00\xfd\xc2\x30\x91\x50\x2f\xd9\xca\x65\x1c\xe5\xe3\x42\x2a\x98\x33\x5a\x81\xd7\x4a\x65\xcc\x15\x00\xe9\x07\x0a\xbb\x60\x9c\x1c\x1f\x68\xfc\x2c\xa9\x4c\xdd\x55\x0f\x99\xbc\xb2\xd0\x92\x41\x6b\x9b\xd3\x88\x41\x0b\x8f\xe7\x48\xfb\x8c\x9a\x5a\xb8\x61\x5f\x2e\xd9\x68\xf8\x5d\xcb\x27\x27\x72\x69\x84\xbe\xad\xa7\xa1\x8a\xfd\xb0\xc7\x2a\xa6\x5d\xe7\xab\xb7\xa8\x6f\x11\x16\x9a\x6e\xad\xf1\xc2\x1d\x61\x4e\x52\xc0\xc8\xf0\x19\x74\x7d\x34\x1a\x05\xd8\x5e\x37\xbf\x58\xd8\x32\x7e\x99\x39\xc2\x38\x7c\x27\x44\xed\xf8\x38\x56\x3c\xb3\x7f\x0b\x16\xe8\xa0\x6f\xc6\x28\xa9\x72\x30\x50\x6f\xa4\x18\x39\x54\xdc\x74\x81\x5f\x3b\xe2\xeb\x2a\xff\x4a\x13\xc0\x65\xf7\x43\xb7\xd8\x5d\xe8\x04\xeb\x28\xef\xe5\x70\xed\x5e\xcc\x71\xab\xa9\x7f\x97\x63\xb4\x36\x17\x32\x47\xf3\x8e\x0c\xf6\x29\x72\x09\xb6\x51\x28\x46\x5a\x38\x26\x64\xce\xd8\x01\x1f\xcc\x3d\x0e\x56\x3f\x15\x5b\xc6\x3c\x94\xdd\xe7\x3c\x7b\x17\x24\x7b\x8c\x3a\x4e\x80\x34\xeb\xd4\x36\x46\x35\x18\x5c\xe9\xc7\x08\x1d\xbd\xbe\x85\x45\xf7\x9d\x01\xaa\x53\x2a\x0d\xc5\x2c\xb7\x90\xa3\x1f\xc2\xff\x41\xac\xeb\xad\x27\xcc\xe9\x24\x45\x54\xdb\x65\x2f\xa2\x87\xba\xe7\xde\xcb\xcc\x8c\xe9\xe0\x1d\x1a\x88\xab\x41\x2b\x6c\x65\x78\x20\x3b\x42\xde\xc9\x82\xb7\xf3\xb8\x23\x14\xdb\x2c\xc7\xc5\xc3\xdc\x1d\x3d\x8b\x17\x14\x4d\xa7\xfe\x60\xe7\xa8\x72\x5f\xd0\xa9\x7c\x61\x06\x07\xcf\x41\x3c\x72"}, +{{0x08,0xb5,0xfd,0x4e,0x41,0x9d,0x23,0x70,0xc0,0xfc,0xd6,0xc3,0xb9,0x2f,0x8d,0xb3,0xaf,0xd4,0x22,0x68,0xf5,0x33,0x08,0x5d,0x9f,0xce,0x32,0xb5,0x22,0x82,0x4e,0x34,},{0xcd,0x0d,0xa6,0x99,0x37,0x9e,0x4f,0x94,0x25,0xe8,0x4b,0x97,0x57,0x30,0x0a,0x51,0xa1,0x63,0xf3,0x58,0x73,0x4c,0xc3,0x7a,0x91,0xff,0x0e,0xa4,0x88,0xd2,0x97,0x79,},{0x42,0xa1,0x37,0x56,0xb7,0x5c,0x67,0x22,0x48,0x5f,0xa3,0xf6,0x94,0x04,0x1b,0x39,0xb7,0xd7,0xc5,0xfd,0x40,0xeb,0xc0,0x6a,0x52,0xe0,0xff,0x34,0xce,0x14,0xd8,0xd4,0x0f,0xa8,0x2a,0x95,0x08,0xb5,0x68,0x53,0x7d,0x26,0xd0,0xdd,0x7c,0x0a,0x31,0xbe,0x71,0x0d,0xa8,0x0a,0xab,0x35,0x19,0x6a,0x03,0x9b,0x60,0x64,0x1d,0xb1,0xe1,0x01,},"\x3c\xee\xee\xa3\x0f\xa4\x01\x56\x3d\xf3\x6b\x19\x8b\x9b\x59\x69\x8c\x10\xe1\x00\xa2\xf3\x0e\x6f\x78\xfe\x62\xb9\x2e\xca\xc9\x89\xe8\xaa\x09\xec\x76\x0e\x89\xca\xc0\xa1\x6b\xde\x3c\xac\x73\x62\x2a\x86\x27\xef\xed\xfa\x4e\xc0\x9b\x87\x3f\x7e\x10\x00\xe7\x69\x82\x91\x0c\xa0\xaa\x4a\xfb\x1f\xf5\xa8\x44\x8b\x76\xf7\xb0\xd2\xa2\xd5\x2a\x7f\x40\xde\xde\xfc\x68\xd6\x0c\xe6\x62\x2c\xa0\x80\xd6\x69\x8e\xa6\xc3\xbd\x72\x10\xb3\xb6\x48\xf5\x32\x52\x29\x14\x94\xb3\x5a\x55\xff\x40\xfa\x1a\x63\x1a\x57\xc5\x10\x01\x1a\x46\xbf\xb9\xe2\x71\xba\xe1\xe7\x8c\xe6\xc6\xea\x60\xc5\x5b\xa0\xcc\xe3\x60\x59\xbf\xb0\x1e\x39\x45\x56\x98\x7f\x74\x4b\x72\xae\xbb\xdb\x4b\x1b\xdb\xb3\xbb\xaa\xee\x1b\x8b\x2f\x31\x74\x50\x6a\x79\x3f\x0a\x51\x1b\x2b\x56\x90\x49\xb3\x0a\x2e\x08\x41\x42\x41\x84\xa4\x8e\xca\x9e\x2d\x83\x78\x3a\xc5\xb6\x1e\xb9\x47\xcb\xd8\xba\xb7\xad\x38\xb0\xc6\x84\x27\xd8\xf9\x4a\xe2\x85\x19\x0d\xbb\x6e\x0c\x6d\x58\x0a\x25\x14\x23\x94\xbe\x94\x81\x58\xd8\xda\x83\xb4\xf3\x4a\x8d\x25\x8b\x97\x07\x56\x32\xb3\xc2\x8b\xfa\xe3\x10\x5e\xd1\x87\x2e\x35\x6e\x43\xae\xd5\x93\x97\xb9\x11\x0b\xbf\x9d\x8c\xa2\xa0\x44\xd5\x27\x1e\x6c\xc3\x61\xe1\x4e\x69\xa9\x32\x51\x76\x83\xec\x81\x81\x8f\x02\xcf\xa0\x29\x5e\x56\x61\xce\xa3\xe5\x86\xaf\xc0\xdb\x41\xba\x95\x55\x3e\xe7\x5b\x20\x0b\x0f\x97\x90\x11\x1d\x37\x57\xa7\x39\xe5\x63\x55\x7a\xff\x9b\x70\xca\x14\xe8\x7b\x79\x54\x37\xba\x91\xa9\x5d\xd0\x7e\xa6\x9a\x11\x35\x9f\x36\xca\x03\x29\x8e\x0b\xfa\x4f\x91\x2f\x64\xa2\x92\x4a\xd9\x01\x97\x5a\x2a\x96\x0b\xa1\xbe\x89\x92\x1b\x1f\x54\x85\x49\x6b\x7e\xa5\xda\x6d\x8a\x69\x37\xac\x10\x5b\xf3\x76\x0e\x48\x76\x99\x0a\x0f\x5c\x5a\x63\x4f\x74\xcb\x57\xdf\x7c\x17\x2c\x8a\x41\x53\x72\xe6\xd9\x03\x29\x87\x17\x49\x96\x16\xf8\x97\x1c\x68\xbb\xec\xe9\x2e\xa8\x78\xa1\x8e\x23\xf3\x27\xc3\x64\x9b\x6a\x85\x2e\xf2\x3b\x7b\x3e\x60\x3c\xdf\x80\x45\x2d\xbf\x1b\xe2\xfb\x77\xe8\x14\xd2\x52\x54\x96\xbb\x31\xfb\x6e\x4e\xd2\x53\x32\x48\xb3\x9d\x5f\xbe\x23\x90\xa9\xb6\xfc\xca\xba\x99\x7e\x8b\x49\xb5\x98\x36\xe3\xe0\x95\x29\xea\x5e\x41\x13\xee\xe4\x51\xc9\xc6\xbb\x26\x74\x1d\x0e\x4c\x58\x6f\x53\xd6\x04\xc6\xea\x0c\x0e\x60\xdb\x02\xe5\x10\x9f\x37\x34\xf5\x1c\xdd\x89\x85\xaf\xeb\x3e\xca\xff\x65\xe0\x59\xe3\x12\xcd\x50\xfa\x34\x9f\xf2\x8b\xdc\x9b\x70\xb7\xf5\x32\xdb\xab\x1d\xf4\x3b\x03\x16\x7c\x1d\x2e\x3f\xa6\xee\x8c\x9b\x17\x4a\x0b\x2c\xf8\xaa\x9f\xfa\x40\x6b\xf5\xbd\x72\x88\x78\x0c\x9c\x4a\x6b\x69\x79\x49\xb4\x86\x38\xd4\x20\x79\xc8\xc6\x6e\x14\xd9\xb5\x72\xa2\x10\xa0\x93\xea\xf1\xd2\xf7\xa7\x03\xb5\xcd\x20\xad\xc4\xf9\x92\x7a\x6e\xa8\xea\x78\xfa\xa6\x1b\xc6\x2b\x3c\x5c\xbd\x3a\x53\x25\x25\x66\xd0\x43\xba\x55\x65\x90\xd9\xa7\x63\xbe\x7f\xea\x4b\x20\xe1\xe9\xcf\xbe\xbf\xae\x15\x43\x9b\x33\x4d\xc5\x39\xb1\x7d\xad\xa2\xe4\x34\xe9\xc8\x32\x25\xb1\xe8\xf6\xbe\xb7\xd5\x56\xb4\x7d\x7f\x69\xf7\xeb\x7d\xf5\xed\xe2\xee\xbd\x84\xe2\x50\xb7\xc9\x46\x8c\x21\xfd\xc0\x17\x0e\xa8\xdf\x66\x2d\x61\x80\x58\x1f\x65\x7f\xe7\x6c\xef\x18\x58\xb6\xb0\x2f\x73\x25\xc7\x21\x96\x43\xfb\xa2\xf7\xe9\x96\x3a\x33\x32\x2d\x65\x04\xab\x91\xbf\x10\xa9\x78\xfa\x07\xb4\x7d\x5d\xb0\xbe\x00\x0d\xcd\x00\x2b\xdd\xaf\x67\x6b\x77\x25\x9c\x9f\x60\xad\x0b\x11\x67\x1c\xd5\x77\x7c\x1e\x80\xb1\x3f\x82\xeb\x0f\xb6\xa1\x80\xb5\x66\x62\x93\xa4\x32\x40\x86\x2f\xbf\xa3\x97\x8d\x95\x31\x19\x71\xaf\xab\x9e\x1c\xc8\xab\x14\xa8\x76\xb6\x57\x2a\xc8\xa4\xb7\xe0\xb4\x0a\xaf\x6b\x52\xa1\xcf\x4c\x1e\xbc\x6c\x1c\x48\x7d\xf5\xa3\xcb\xc4\x00\x5a\x0e\xe3\x29\xca\xbc\x28\x6d\xb1\x0f\x17\xd0\xf1\x78\x2e\x07\xd3\x32\x4f\x0c\x73\xef\xbd\x3c\x2f\xb5\x2b\x71\xf9\x8a\xd9\x5d\xb9\x50\x62\xd9\x14\x25\xe7\x34\x67\xbc\x1e\x4e\x9b\xf5\x52\xe8\xa2\x44\x29\xd9\x7d\xb1\xd6\x6d\xd4\xd9\x95\xe5\xf8\xd2\x4e\x9c\x91\x0b\x2e\xb1\x75\x8e\xf7\x55\x25\xc3\xd6\x5a\x3f\x43\x0a\x02\x73\x48\x82\x0c\xe3\x05\x3b\x6f\x3a\xf4\xec\x96\xd0\x49\x37\x31\xc8\x18\xc6\xb1\xa7\x0c\x25\x0a\xc6\x86\xa4\xfc"}, +{{0x1e,0x85,0xc9,0xe4,0x51,0xb7,0xac,0xf8,0x01,0xd1,0x6b,0xc8,0x26,0x8e,0xb4,0x2a,0xe8,0x5c,0x72,0xc6,0x8e,0x9f,0x90,0x92,0x7a,0xa0,0xf3,0xb5,0x0b,0xef,0xd2,0x29,},{0xa6,0x9d,0x05,0x7f,0x4b,0x74,0x38,0x11,0xe0,0x7a,0xc7,0x45,0x61,0xc2,0x25,0xbe,0x03,0x81,0xc7,0xd5,0x84,0x9e,0x60,0x18,0x79,0x37,0x01,0xa8,0xcb,0x6c,0x99,0xb5,},{0x6c,0x36,0xda,0x9a,0xd6,0xc4,0x56,0x34,0x3c,0xe6,0x42,0xac,0xa4,0x54,0x92,0x3a,0x52,0xa2,0x84,0x4c,0xe5,0xee,0x58,0x94,0x7c,0x8d,0xf7,0xba,0xb2,0xeb,0xe4,0x67,0x82,0x3c,0x56,0x33,0xe5,0x30,0xb1,0x67,0xd7,0x1c,0x47,0xad,0x95,0x49,0xdf,0x05,0x94,0x3f,0x99,0x42,0x1e,0x17,0x47,0x5c,0x4d,0x4f,0x08,0xde,0xdf,0x6f,0x32,0x05,},"\x18\x9e\xa9\xc8\xd9\xed\x14\xb0\xde\x82\xb4\x4c\xbd\xd5\x87\x57\xa2\x7c\x68\x38\x3f\xba\x59\x77\x61\xf9\xe8\x62\xe0\x8d\xe1\x5b\x1e\x44\xc3\xdb\x1b\xad\xbd\xe7\x69\x80\xee\x39\xe6\x99\x62\x9f\x6f\xcf\xef\x32\xd3\x6b\x33\x93\xda\x2c\xa5\xa8\x1f\x95\x9c\x8b\x0f\x1b\x80\x1b\x5f\xa4\xc4\x7c\xa3\x95\x91\xe6\x12\xa2\x43\x5c\x5b\xaf\xd7\x7a\x5c\x7a\xb7\x43\x59\x21\x09\x06\xf4\x75\x33\xb1\x87\x9e\x2a\x5a\xf5\x86\x4d\x96\x1c\x81\x46\xe2\x5d\xac\x77\x25\x55\xe0\x42\xa8\x87\x26\x14\x19\xab\x8c\x9f\x6f\x62\x56\x25\x48\x1d\xa5\xb9\x35\x26\xa1\x31\xf3\x7b\x53\x4a\x00\x50\xa8\xa4\x62\xb3\x3f\x20\xa7\xe9\x4b\x89\x15\x30\xb1\x9b\xf6\x54\xee\x95\x34\xc9\xa8\x36\x1d\x03\x63\x5d\x8d\x27\xd4\x6b\xe7\xbf\x84\x78\x1a\xd0\xd4\x2d\x1e\x7c\x48\x54\xa4\x9b\xa1\xba\x45\x82\x62\xfe\x5e\xa1\x90\x21\xb9\x35\xa6\x94\x94\x92\xd7\x0b\x60\x5e\x15\x19\x89\xef\x26\x41\xb2\xbf\x81\xec\x4b\x92\x02\x0f\xc7\x07\x4c\x2a\x63\x22\x9d\x51\xa9\x44\x18\x6a\x28\x89\x5e\x8e\xa9\x52\x92\xc2\xf8\x72\xbb\x21\xa3\x14\x93\x99\xe2\x3c\xcd\x8e\x2f\xc4\xf1\x7a\x46\xb5\x9c\x28\x2c\x51\xb5\x8d\x00\x26\x6a\x5c\x16\xb1\xce\x35\x0d\x54\x85\xe8\xd8\x01\x6d\xd0\xa5\x0a\x59\x84\xcc\x94\x81\x54\xcd\x5c\xe7\xcd\xa0\xee\x0a\xb1\xd7\x25\x1b\xdc\x70\xa1\x78\x5b\x8e\x91\x03\x91\x7f\x4b\x91\x7a\xb2\xb4\x94\xf3\x48\x33\x89\xa2\xf9\x23\x75\x41\x84\x9e\xd3\xbd\x56\x5c\xff\xac\x9e\x75\x6d\xb5\x6e\xf5\xe2\x34\x95\xbc\x77\x1e\x88\xbf\xfa\x87\x07\xce\xea\x5c\x09\xbe\xca\xdd\x05\x9a\xb8\x89\xd1\xdf\x7e\x88\x7b\x71\xa9\xe6\xc2\x38\x37\x8f\xbe\x0c\x36\x30\x38\x66\x16\x36\x3f\x20\x7b\x16\xc3\x27\x0d\x39\xac\xde\xd5\x11\x52\x99\x92\xf4\xe5\x98\x78\x91\x21\xd3\x16\x13\x58\x10\x63\x6b\xaa\xde\x8a\x28\xed\xc6\x6b\xbf\x5e\xde\x3f\x40\x4a\x70\xb4\x7d\x35\x98\x8b\xe7\x06\xb4\xea\xa0\x30\x23\xa3\x90\x93\xd5\x83\xcd\x4c\xd8\xbf\x4c\x74\x34\x1a\x02\x8c\x19\xd6\x0d\xa3\x1b\x6a\x7a\x03\x4c\x08\x1a\x2b\x03\x0f\xeb\x3c\xd2\xf0\x3d\x0f\xaa\xbf\xfb\x58\xe3\xfc\x36\xc0\x06\xcf\xb9\x29\x47\xa7\xde\x5b\xa8\x74\x76\xc1\xb0\x51\xe1\x82\x83\xc0\x3e\x9c\x6e\x5a\x5c\x3c\x27\x77\xd9\xa0\x75\x73\x72\x37\x96\x64\xe8\x2f\x84\x85\x82\x4f\xed\xb7\x0a\x4b\xc4\xe3\x56\xed\xd1\xb5\xce\x0f\xb6\xe4\x1d\xe0\x17\x16\x21\xb8\x4f\xaf\xa0\x01\x89\xaf\xa8\xa6\xa9\x00\xb1\x4c\x70\x75\x8f\x7a\xa4\xfb\x82\x40\x0e\x0d\x18\xab\x3c\xd7\xe4\x8a\xcf\xd4\x89\xca\xb0\xe7\x2e\x71\x9f\x79\xa0\x7d\x06\x6c\x53\x1a\x89\x1c\x55\x29\x1f\x22\x45\xdb\xbe\xe4\x4e\x52\xb1\xdf\xc8\x72\x7a\xae\x38\x7a\xb9\xe7\x19\x94\xa3\x85\x4e\x1a\xdd\x73\xd9\xa7\x96\x5c\x77\x55\x21\xc2\xf5\x40\x84\x22\x76\xdd\x30\x9e\x2f\x6a\x34\x1e\x7f\x0f\x37\xf2\x2b\xb6\x62\x7b\x6e\x9c\xb2\x5b\xa2\x4c\x6c\x4f\x4e\xb9\xf5\xe7\x62\x2d\x88\xda\x19\x84\xe2\x9c\x5d\xa0\x01\x03\x9c\x44\x04\x2b\x59\x35\x14\x06\xa4\x13\x36\xdd\x77\x2d\x49\x7d\x3f\xc8\xaa\xc4\x11\x72\xeb\x5a\xa6\x41\x7f\xe4\x22\xec\x7c\x15\x0b\x96\xb0\x45\x4e\xe3\x31\x24\x7c\xb1\x53\x8a\xef\xf3\xec\xa2\xd5\x0e\x53\xd6\xd1\x31\x70\xa7\x6a\x00\x49\xea\x0c\x05\x90\x4a\x63\x90\xed\x14\xce\x74\x91\xe9\x7f\x75\x4c\x52\x22\xda\xc4\xb6\x11\x8b\xa3\x81\xf5\x52\xe7\x3e\xa8\x49\x1e\x3b\x7a\xc9\x49\x56\x9b\x56\x9c\xf2\xd2\x9a\x80\x41\x0e\x06\x5b\x5c\xc4\xa4\x66\xbb\x04\xeb\x7a\x15\xf5\x96\x79\x2e\x84\x90\xba\x70\x02\xec\x36\x15\x71\xaf\x5d\x8f\x57\x67\x5c\x95\x64\x49\x47\x0a\x2f\x99\x55\x40\x73\x67\xe4\x09\xa2\x32\x89\x95\x53\x12\x0a\x27\x7d\xb8\x63\xe9\xa8\x2d\xda\xba\xe8\x7b\x78\x91\x45\xba\x89\x8d\xf3\xc2\x8b\x96\xfb\xe3\x01\x4c\xd0\x85\xc6\xe6\x0e\xe8\x83\x17\x01\x03\x6d\x99\xc5\x42\x5d\x58\xe8\xbc\xc9\xfd\x92\x71\xd4\x6a\xec\x1e\xb9\x55\x13\x01\x02\xea\xaa\xb4\x4e\x07\x70\xc3\x0b\x2b\x12\x7e\xfb\x0e\x5f\x8a\x3f\x7a\x0c\xa3\x4e\xc9\x98\x4a\x46\x01\x1b\xc2\x6b\xfd\xe0\xc0\x81\x9b\xb5\x47\x06\xb5\x65\x63\x8b\x75\x42\xdc\x4b\x8b\xf8\x09\x8d\xc0\x1f\x16\x1b\x3b\x12\x96\x18\xb5\x9a\xde\xd3\x3c\xb5\x9c\xe9\x18\x9a\x67\x62\xdb\xae\x5b\x0d\x34\xb7\x1c\x8d\xbf"}, +{{0x51,0xcf,0x86,0x8f,0x82,0x0e,0xed,0xa0,0xdb,0xd1,0x01,0x80,0xf7,0x77,0xe6,0x06,0x5c,0x93,0xa4,0x83,0xc5,0x8a,0x77,0x8b,0x67,0xe7,0xd8,0x42,0x30,0x2f,0xb7,0x67,},{0xab,0x08,0x8f,0x50,0x2f,0xbc,0xf2,0x15,0x0e,0x48,0x46,0xb3,0x4d,0x2c,0x80,0x97,0xff,0x01,0x3c,0x02,0xa8,0xb9,0x7c,0xfc,0xf2,0xb9,0x5a,0x1c,0x72,0xdf,0x3e,0x24,},{0xe1,0x53,0x42,0xa1,0x1c,0xaf,0x89,0x28,0x95,0xe4,0x66,0x22,0x88,0x63,0xd0,0x83,0xb0,0x69,0x2f,0x01,0x06,0x10,0x74,0x8c,0x23,0xdf,0x2f,0x11,0xd2,0x94,0x75,0xba,0xfc,0xe9,0x27,0xca,0xfe,0x7f,0x07,0xef,0xb8,0xc3,0x47,0xed,0x56,0x63,0xe7,0x3b,0xea,0x89,0x53,0x1c,0xed,0xc0,0xc3,0x48,0xe7,0x9b,0x6e,0x58,0xa7,0x57,0x49,0x07,},"\x7c\x2d\x8e\xe8\x2d\x9a\xbf\x8a\xa9\xc7\x24\xc7\x5b\x90\x99\x04\x73\xf1\x31\x76\x3f\xe9\x3b\x30\xcb\x04\x72\x35\x88\x62\x1d\xa2\xa3\x27\x92\x8b\x22\x64\x9f\xa0\x62\xcd\xea\xbd\x77\x76\x15\x38\xb2\x70\x9b\x8f\xb7\xa2\x00\x6e\x50\x35\x09\x13\x4c\x92\x9c\x30\x11\xe1\xd7\x28\xa5\x7a\x4e\x17\x51\x98\x07\x5e\x21\x42\x53\xf3\xf3\x0e\x01\xb6\xe0\x4e\xab\xd4\xde\x06\x78\x95\x58\xe6\x98\xb1\x86\xef\xe3\x4b\x32\x12\x95\x68\xb3\xe8\xd0\xd7\xea\x3f\xf0\x0b\x3f\x25\xa4\x22\x36\x89\x3a\xa8\xa4\x1b\x67\x4a\x0a\xb5\xf4\x1e\x7b\x28\xcf\x5a\x7c\xb7\x65\xe1\x8e\xad\x6d\xe6\xa3\x53\xa7\x82\x4a\x3c\x49\x78\x60\x38\xd6\xf4\x93\x7f\x32\x64\xd6\xcc\xf0\xc0\xa2\x46\x5b\xb6\x93\xe5\x2b\x3d\x1e\x6e\xb9\xae\x4c\xb6\x5d\x09\xcf\xf5\x48\x42\xe8\x53\x62\x85\x7a\x59\xf7\x19\x8a\x68\x8a\x3d\xf3\x85\x13\xcd\xd6\x1e\x21\xdf\xd8\x59\x14\x2c\x83\x44\xa3\xb8\xb2\xa7\xc7\xdb\x17\x0f\x39\xf8\x7c\xa3\xff\x8e\xd4\x27\x96\x2b\x2b\x1a\x14\xd1\x22\xfa\x2d\x5a\xea\x2a\x66\x40\x11\x7d\xd2\x58\xfa\x0f\xc5\x4a\xc6\xe9\x40\xbc\x16\xd2\x11\xec\x9a\xdf\x91\x4a\xb1\x65\x78\xf5\x21\xf6\x55\xd2\x12\x7e\x79\xe8\x71\xbf\x7f\xa7\x54\x47\x19\xd5\x8e\xd8\x47\x85\x0c\xb2\x7b\x99\xeb\x8f\x29\xb1\x6c\xdc\xc2\x8b\x15\xc1\x25\x9a\xb4\xd5\x89\x70\x5a\x40\x66\x88\xf6\x05\xa2\xeb\xf5\x80\x51\xc4\x3a\x77\xc4\xe0\x1f\xd6\xf7\x49\xd3\x2d\xb4\xe8\x9f\x26\x3c\x2c\x16\xde\x18\x1f\x0e\x6b\xdd\x0a\x6a\x64\xff\xe6\xf1\x82\x94\x44\x09\x6d\x9f\x3e\x2b\x67\xe4\xbb\x00\x66\x50\xb5\x92\x9d\x1f\x82\xeb\x11\xbb\xed\x24\xe8\xf1\x01\x8a\x73\x84\x60\x5a\x3c\xf2\x9a\xb5\x98\x33\x79\x39\xc7\x6a\x3b\xe8\x61\xe4\x83\xc5\x80\x5e\xc3\xce\xe4\x5e\x34\x24\x84\x7a\x08\x55\x8d\xcc\x99\x49\x9f\xb9\x38\x2a\xca\xe5\x6c\xdc\x87\xfb\xd5\xb2\x6f\xf9\x4c\x86\xf2\xe1\x08\x79\x43\x83\x50\x1c\x8b\x33\x36\x68\x50\xa7\x6a\x0d\xfc\x0a\x7c\xd7\x89\xa0\x3f\x01\xa3\xe9\xd9\xe9\xae\x39\xfd\x72\x45\xdc\x29\x29\x9d\x24\xf3\xb4\xb1\x67\xca\xcc\xd2\x23\xa9\x9b\x6b\x20\xa3\xb6\x73\xdc\x5f\x74\x66\xd0\xb2\xf8\x15\x09\x8a\x49\x7c\xca\xf8\x04\x20\x16\x8e\xdd\xbf\x4d\xa5\x7b\x86\x66\xe9\xd3\x3c\x48\xeb\x30\x4b\x4c\xfc\xf4\x57\xcd\x76\x59\x54\x3f\x6d\x1e\x66\x18\x90\xf5\x62\xb4\x3b\x8b\x6d\x1c\x4d\xcc\x07\x7b\x60\xbf\xa5\x33\xff\xab\x92\x8d\xbf\xd9\x55\xdc\x51\x16\xd7\x70\x95\x0b\x69\x0e\x21\x06\xad\x52\xd4\x2c\x31\xc2\x2b\x88\x48\x89\x43\x32\xb5\xc6\x99\xe5\xc3\x31\xfb\x38\x1e\x58\x12\xe7\x52\x6f\xdf\x4b\x8a\xa2\xda\xaa\x2c\xa2\xcf\xb9\xc9\x21\x11\xb6\x1c\xbc\x3d\x1e\xef\x6c\x8c\x67\x37\xf0\x55\x88\xf0\x44\x67\xdb\x83\x30\x84\x3a\xcc\x98\xdc\x1a\x16\xfb\xd9\xd9\xd9\x4b\xd8\xbf\xde\x26\xc3\xf7\x1d\xee\x72\xb5\x09\x10\xc3\x6b\x24\x0f\x80\x2a\x61\xca\x16\x37\x2f\x6f\xfa\xad\xb2\xbe\x4e\x85\x3c\x5e\xd6\x9a\x3d\x1f\x6c\x7b\x2d\xe5\x13\xc5\x3a\x3f\xdd\x0a\x67\x6f\x83\xd0\x9d\x5c\x51\x17\x60\x47\xd9\x20\x07\x16\xbf\x22\xba\xe4\x5f\xe0\x1b\x3e\x0c\x2c\x51\xc1\x6e\x46\xad\x06\x37\xf7\x9f\x9b\x4d\x83\x86\x77\x04\xfe\xda\x9f\x22\x78\x31\xde\xa2\x63\x39\x9c\xa2\x77\x1a\x4e\x78\xb4\xdf\x8a\xc0\xde\x6a\x94\x1e\xab\x37\x0b\x1f\xdb\x47\xda\xf6\x64\x2a\xae\xaa\x63\x17\x0f\xa9\xb3\xd1\xe1\x62\x8f\x7c\x4e\x7c\xf0\xea\x8b\x8a\x8e\x51\x8c\xba\xce\xf9\xad\xe8\x4d\xf0\x32\x48\x48\x47\xff\xb6\x1b\xbd\x07\xe8\x72\x7c\xc4\xc2\x5d\xa5\x77\xb2\x64\x51\x9b\x49\x99\xfa\x7c\x0b\xc3\x23\xd4\xf3\xf9\x73\x9f\x78\x0b\x9b\x2c\x23\xc7\x78\x55\xee\x5f\x6d\xcc\x40\x15\x44\xd6\xb6\x4b\x27\x70\x15\x8f\xdc\x6c\x12\xf4\xd8\x9b\xeb\x04\x4e\x0e\x85\xac\x7a\x68\xd4\x29\x17\xb1\x34\x51\x14\xb9\xa6\x72\xd1\x23\x1b\x2c\x6c\x0f\x96\x9f\x20\x35\x31\xe7\x1b\xbb\x40\x05\xb1\x03\xa7\xdc\x3a\x58\xb5\xb8\x24\xa7\xe0\x1b\x6e\xb9\xf4\x96\xdf\xa6\x4d\x64\xd8\xc6\x77\x7f\x53\xaa\x58\xd5\xda\x04\x6d\x72\x6f\x55\x45\x4c\x88\xb6\xd7\xd4\xab\x0d\x21\x98\xa8\x97\x09\xf1\x18\xa6\xb3\x24\x60\xb9\xeb\xce\xff\x3f\xdd\xc6\x05\xda\x77\xef\x3d\x1b\xa3\x0f\xec\xf0\x7b\xe2\xf5\x31\x3f\x4e\xe6\x35\xaf\x5e\x95\x61\xd8\x77\xe9\x9c"}, +{{0x54,0x3d,0x5f,0x1d,0x4a,0x6e,0x10,0x29,0xb1,0x91,0x41,0x38,0xfb,0x1f,0x46,0x59,0xe6,0x94,0x56,0x55,0x72,0x07,0x40,0x66,0x88,0xa2,0x03,0x5c,0xbb,0xb2,0xa6,0x8a,},{0x3c,0x83,0x79,0x0c,0x3b,0x45,0x53,0xde,0xae,0x4f,0x84,0x3b,0x50,0x1d,0x26,0xf6,0x16,0x70,0x93,0xee,0x54,0xe2,0x79,0x75,0x9f,0xfa,0xd8,0xcb,0xc0,0x61,0xe7,0x20,},{0x55,0x20,0x11,0x94,0x02,0x6f,0xd6,0x44,0x8b,0x1d,0x52,0xf8,0x3e,0xd2,0x0a,0xc2,0x84,0xe7,0xe7,0x7f,0xa9,0x2d,0x52,0x95,0xd3,0x38,0x25,0xce,0xa3,0xac,0xa4,0x7e,0xc7,0xaa,0xca,0x2f,0xc0,0x86,0x79,0xf9,0xac,0xfc,0xed,0xb3,0x76,0xfd,0xa4,0x61,0x9b,0xe3,0x27,0x2c,0x74,0x45,0xe8,0x70,0x5c,0x30,0x61,0x41,0xcd,0xe1,0x6c,0x0f,},"\xfe\x00\x57\xf0\x62\xfc\x87\x13\x24\xb8\xbd\x5d\x42\x7e\x9a\x52\x76\x23\x1b\xd3\x09\x90\x7e\x58\x81\xd7\xae\x53\xb1\xf3\x70\xc2\xa4\x33\x02\xa1\x65\x10\xb4\x60\x64\xa3\x07\x36\xba\xc9\x09\x51\xf1\xd9\x88\x1a\xf6\x2c\x70\x14\x83\xeb\xb9\x27\x2a\xd7\x72\x12\xee\xb5\xfc\xbc\x7e\xc2\x28\xd9\x69\xf8\x90\x27\x32\x11\x3b\x98\xe3\xbf\x82\xdf\xea\xdd\x0d\xe5\xe7\x65\xd2\x87\x0b\x12\xd1\xf9\xb5\xa2\x82\x97\xc9\xfd\xd1\x49\x5c\xf8\x77\x89\x19\x6a\x7d\x64\x4e\xec\xd9\x35\x87\xdb\xf2\x0c\x28\xeb\x09\xda\x28\x66\x03\xc5\x82\xd2\x12\x9a\x65\x7d\xb2\xd1\x7a\xdd\x35\x58\xdd\xe0\x29\xce\x27\xb8\x83\x52\xde\x3f\x95\xab\xa1\x7e\x1e\xd1\x91\x37\x22\xdb\x08\xa7\x95\xdf\xbb\x70\xd6\x2a\x88\x02\x72\x4c\xb0\xf5\x35\xf8\x48\xd0\x52\xaa\x3d\xde\x91\x66\x96\x3a\x80\x41\xfc\xcc\x4e\x60\xbf\xb1\x1d\xe2\xbf\x28\x6e\xb6\x02\xa4\xaf\x84\x2f\x4d\x1a\x34\x0d\x78\xbb\xbc\xb2\x85\x7f\x0c\x30\x8f\x44\xbb\x10\x1e\x7b\xc8\xb7\x41\xd5\x06\x09\x4e\x27\xbb\xaf\xa7\x24\x28\xef\x66\x6e\xa6\xea\x16\xf7\x99\xb4\xee\x58\x27\x8f\x04\x59\x74\xd8\x6d\xc7\x2c\xf5\x26\x0d\x96\xf9\xc0\x9b\x2f\x11\x81\xe1\xa4\x50\x0f\x92\x83\xdc\x67\x7f\x38\x4f\xf6\x4e\x51\xe8\x9f\x76\x58\x20\x20\x32\x6c\x38\x8c\x08\xa0\xfd\x00\xde\x73\xd5\xd4\x9c\x06\xc0\xc6\x84\x19\x1a\x26\x4f\xff\x72\x6d\x87\x2d\xc3\xae\x49\x6c\x7b\x47\x8c\xfc\x61\xb5\x17\x14\x19\x2f\x76\x46\x3e\x3d\x0a\xab\x41\x0e\xa1\x15\xe8\xbe\xfe\xdb\x99\x7d\xdd\x16\x99\x21\xb3\x20\x7e\xa6\x6c\x1f\x59\x45\x0b\x76\x23\x12\x9f\xd1\xe2\xdd\x3d\xa8\xf5\x20\x63\x91\x17\x13\x38\xea\x0e\xc8\xef\x3c\x59\xed\x8a\xfc\x69\xf3\x86\x5c\x29\xa0\x72\x3a\x9b\xbe\x95\xa7\x42\x68\x1e\xf9\x85\x7e\x81\xab\xc8\x0c\x92\xd2\xa7\x18\xa8\x04\xf5\x30\x4f\xef\x3c\x63\xd7\x99\xa6\xef\x87\x82\xa7\xdb\x46\x68\x1d\x0d\xe3\x50\x64\x46\x98\x22\x67\xb2\x15\x2b\x0c\x32\x18\x69\xe2\x3c\xce\x8c\x4e\xbe\xbe\xaf\x4a\xa1\xeb\xe9\x28\x3b\x69\x26\x05\x26\x0f\xf6\x21\xb0\x3c\x10\x82\x2a\xa5\xf6\xd0\x3b\xde\xf4\x9c\x46\x2a\x68\xd4\x71\xe8\x49\xe1\x64\xe3\x87\x4f\x6e\x9f\x6c\xb3\xb5\xf2\x93\xeb\x38\xae\x52\x45\xa1\x59\xec\x42\x61\xa9\xbf\x6b\x5f\x7b\x76\x15\xfd\x33\x9e\xa1\x27\x33\x11\x3c\xe7\x67\xf8\x83\xae\x66\x75\x41\x7f\xc7\x70\xb5\x0b\xd6\x0e\x6f\x20\xad\xdb\x29\xc1\xf7\x50\x62\x33\xe3\x2a\x7e\xbf\xad\xab\xff\x98\xcf\xd0\x9b\x2b\x3b\xbd\x3e\xae\x00\x69\x54\x8b\x9d\x89\x87\xaf\x46\xca\x98\xeb\x09\x5b\xac\xbd\x87\x47\x24\xba\x10\xf3\x63\x3a\xa0\x8a\xb6\xec\x26\x49\x4d\xdf\x68\x54\x30\x9b\x55\xd4\x3b\xdb\xd2\x9a\x75\x56\xf1\x2d\xfb\x23\xcd\x0d\xb4\xeb\x39\x37\xa6\x5c\x4a\xed\x96\xe8\x7b\x34\x65\x55\xf9\xfc\x68\x97\x94\x3a\x0f\xae\xe6\x5c\xcf\x39\x4b\xd8\x9b\x38\x1b\xee\xce\x25\xd1\xba\x68\xf8\xfe\x32\xc2\x3b\x33\x54\xf5\xbe\x7e\x3e\xa3\xc0\xde\xc0\xf7\xec\x2d\xd8\x3f\x92\xb7\x30\x58\x89\x2b\x63\x8d\x4c\x3b\x72\x42\xbb\x8f\x55\xbf\x08\x7b\xa4\x5a\x19\x0a\x69\x8b\xae\x67\x5e\x0c\xd5\xe8\x44\x6f\x2b\x21\xae\xb6\x3d\x2c\xae\xa0\xf6\x79\xa8\x37\xe7\x93\x57\x30\x8d\x9f\x0b\x8a\xf3\x1f\x9d\x08\x00\x8c\x39\xee\x8d\x34\x75\x28\x71\x3c\x88\x50\x01\x7a\x7f\x4a\xb9\x8a\x35\xc7\x53\x19\x40\xfa\x76\x21\xe6\x72\x03\xee\x78\x2d\xb3\xa2\xfa\xa3\x0f\x3a\xa8\x50\xa5\xff\x7a\xae\xd8\x4c\x00\xff\xd2\x14\xf2\xc9\x26\x17\x35\xfa\xc3\x25\x9d\x50\xe0\x3c\x26\x52\x50\x52\x79\xd9\x12\x51\x92\x7d\xe5\xe5\x6a\x8b\x90\x64\xcc\xf9\xf4\x5d\xcb\xef\x46\xe1\x18\x9c\xed\x2b\xc7\x9e\x6f\xf6\x52\xe6\x90\x97\xac\xe5\x56\x8b\xb2\xd5\xbe\xf3\xce\x21\xa2\x5b\x3f\x79\xee\x27\x5e\xa3\x4e\x62\x13\x80\x56\x6d\x70\x4c\xd9\x3f\x24\xdd\x90\x20\x93\x2c\xc0\x52\x18\xc2\x3b\x5b\x22\xff\xfa\x7e\x99\xee\x7f\xe4\x57\x87\x6a\x5e\x33\x64\xc9\xa8\xe8\xb0\x49\xcf\xa2\x09\x69\x77\x4f\x50\x6d\x19\x96\xcb\xe6\xef\x5a\x37\x79\x3e\xcd\xb0\x4c\xfd\xea\xed\x7d\xcf\x79\xab\x27\x84\x74\xdd\x77\x08\x22\xd4\xb3\x6f\xc6\x8e\x4b\x2d\xd6\x61\xef\x99\xde\x01\xde\x6e\xec\x57\xfa\x57\x3e\xde\x10\xfb\xbd\x5a\xc6\xfd\x6c\xd8\xbb\x4e\xee\x50\x9d\xbb\x46\x10\x37\x44\x01"}, +{{0xf8,0xd2,0x57,0xfd,0xfc,0xf9,0x97,0x96,0xf8,0xce,0x4d,0x8a,0xad,0xe3,0xb2,0x25,0xa5,0x3c,0x26,0xfe,0xec,0xef,0x39,0x5b,0x95,0x61,0xd9,0xd5,0x87,0xf5,0xa3,0x3c,},{0xf6,0x6b,0xd4,0x87,0x7d,0xf7,0x8a,0xec,0x04,0xca,0x7e,0x77,0x73,0x28,0x99,0xde,0x06,0x77,0x7e,0x69,0x86,0x29,0xf2,0x99,0x69,0xf8,0xfa,0x9c,0x2f,0x47,0xab,0x9e,},{0x92,0x35,0xd4,0x48,0x07,0x86,0x98,0x16,0xe2,0x8e,0x42,0xc8,0x1c,0x80,0x1f,0xfb,0x12,0x1d,0xe8,0x26,0xc0,0xd3,0x3d,0xcc,0x4a,0x4e,0x1c,0x93,0x2d,0x52,0x28,0xb6,0x39,0xbb,0x29,0x4e,0x16,0x09,0x0a,0x93,0xd1,0xf6,0x90,0x4a,0x70,0x04,0x22,0x2f,0xda,0x0a,0x55,0x44,0x6d,0x99,0x01,0xc7,0x23,0x40,0x00,0x7b,0xb4,0x5a,0xe1,0x03,},"\x23\x3e\x1e\xf9\x01\xab\xcb\x69\xfb\x48\x60\x85\xd8\xdb\x02\x33\xff\x78\xf3\x7b\x13\x6f\x0a\xfe\x24\xf7\xda\xc1\x94\x4c\x36\x78\xe7\x4f\xed\x58\xa1\xad\x54\x83\x5b\x7d\xbc\xb4\x6f\xff\x6c\x35\x24\x31\x22\x73\x30\x0b\x6d\x87\x8a\x93\xe0\x60\x8a\x4a\xba\xca\x4e\x31\x94\x72\x2b\xb9\xe2\x3d\x17\x19\x4d\x86\x67\xb8\x4f\x2d\xb0\x38\xc2\x4e\xfb\x8f\x53\x40\x9c\xf5\x59\x4f\xdd\xb8\xbc\xd6\x1f\x74\xcf\x07\x26\xb5\x1c\x65\x1c\xe0\x1e\xb6\x6a\x59\xb4\x55\xf7\xd8\xa7\xd6\x0d\x39\x27\xe0\xc6\xc5\x4b\x13\x8e\x01\x92\x53\x71\xd2\xd9\xd9\x62\xaa\x98\x2f\x5e\x60\x85\x28\x0c\xc0\x5f\x35\x69\x93\x91\x1f\xd2\x03\x9d\xfc\x34\x21\x17\x97\x02\x91\x38\x1d\x82\x02\x7d\xb3\x6c\x79\x91\x00\x05\x7d\x93\x52\xb2\xcd\x87\x9d\x9c\x82\xaf\x73\x4b\x7f\xa2\x97\xd2\x11\x49\xc9\x78\xaa\x5e\x12\x5b\x20\x37\x2a\x9b\x2e\x0e\xd3\x57\x33\x7e\xfa\xea\x13\x91\xf3\xb9\xef\x11\xe3\xe5\x13\x5b\xb7\x0b\xdb\xe3\x2a\x9b\xdb\x7c\x3c\x42\xd5\xd5\x7c\xc8\xda\xb6\x81\x16\x28\xa0\x10\x89\x49\x5c\xb8\xa4\xa7\x6a\x48\x29\x6c\xd8\xdf\xaf\xc0\x05\xad\x49\xd7\x0b\xb1\x9f\xac\xa2\x08\x4a\x1b\x6f\x5e\x48\xd2\x3c\x03\xfb\xcf\x6f\x10\x6d\xb7\x70\xf0\x7c\x33\xe8\xe7\xf4\x75\x7d\xa9\x04\xa4\x4d\xd0\xe7\x38\xf3\xd5\x73\x3a\x32\x93\x75\xce\xd7\x4f\x3c\x42\xbf\xcd\xbb\x91\x01\x00\x45\x5d\x6a\xa7\xd2\xe3\xe3\xaa\xa5\x8a\x82\x96\x30\xd3\x76\xb0\xb4\x66\xdc\x85\xaa\xc4\x8f\xe2\x69\x94\x6a\x7b\xc7\x2d\x91\xeb\x37\xde\xd2\xf4\xa7\x7c\x68\x4b\xe0\x10\x93\xfd\x12\xde\x9d\x9d\x83\x19\x9c\xcc\x50\x95\x9a\x48\xd6\xe9\xa4\x14\x27\x56\x60\x92\xf0\x4a\x0f\x95\xca\x52\x37\x2e\x07\x62\xb9\x66\xce\x62\x32\x05\x5a\x4f\xd7\x57\xc6\x1b\x8b\xad\x83\xba\xef\x91\xa3\xc2\x77\x2f\xb3\x2e\xad\x8f\x59\x1a\xc1\xe0\x2b\xbf\x90\xa7\xf6\xc3\x90\x79\xb8\x6f\xb8\x14\xcc\x24\x2e\x98\x0f\x0b\x8b\x1a\x2c\xec\xb8\xe6\xd4\xe8\xa5\x21\x1b\xf8\xba\xbf\x38\xe8\x29\xab\x98\x83\x60\x8b\xd6\xd5\x9e\xa5\xe8\x36\xa9\xb4\xa4\xfb\xed\xed\x1b\xea\x2f\xfe\x97\x7e\x8c\xf3\x61\x5c\xa4\xa5\x0f\xea\x1f\x05\xf1\xfe\x53\xc8\xea\xc5\x00\x32\x3e\x1f\x52\xa8\x06\x83\x15\x39\x95\x79\x88\xd7\x9a\xcc\x7b\x54\xf7\xd0\x2b\x48\x0c\x46\x9f\xd6\x95\x40\xfe\xa4\xbd\xd6\x8c\xbd\xc6\x8c\xf9\xc7\x87\x2f\xd7\x92\x59\x1b\x01\xe9\xd9\x90\x2d\x8a\x61\x4f\x4c\x21\x82\x3f\x23\x50\x8f\xfd\x49\xff\x21\x8b\xea\x92\x2e\xc1\x41\xef\xf6\x0d\xa1\x77\xcc\xad\x7d\x7b\x9d\x44\x4f\x3b\x03\x45\x81\x15\xf1\x16\xcc\x6e\x37\x62\x5c\x39\xcb\xad\xf0\x93\x62\xf3\x1d\x33\xf4\xc1\x3c\x33\xb6\x29\x20\x07\xf2\xca\xfd\x19\x4f\x62\xc6\x43\xe7\xa2\x55\x71\x56\x4f\xeb\xad\x7d\x33\xe3\x64\xb6\x33\xd0\x08\xb0\x90\xd7\xa0\x91\x35\x8b\xc6\x9c\x56\x7b\x95\x22\xb5\xc1\xcd\x01\x21\x8d\x38\x52\x9a\xeb\xb0\x3d\x9c\x2a\x5e\xb2\x28\x5a\x71\x76\xf9\x8c\x28\x03\x6f\x21\xe1\x9e\x92\xb4\x06\xe9\x48\x95\xfa\x28\x1b\x35\x22\x8f\xbf\x76\xe7\x3e\x17\x58\xaf\x1b\x43\x4a\x4d\xf9\x8e\x8c\xc5\x56\xb9\xd8\x3f\x6b\x0b\x7f\xf5\x2c\x68\x0f\x65\xef\xe4\xe0\x0c\x59\xb4\x6c\xe5\x93\xbf\x98\x89\x98\x05\xd0\x2b\x91\x65\xb7\x42\x98\x49\xe7\x39\x53\x77\x0a\xe3\x93\xe4\xf1\xf9\x7c\xb9\x0c\xd6\x15\x9c\xc9\x39\x52\xae\x8a\x4d\x3d\x56\xa9\xa9\x5d\xf7\xcf\xab\xac\xd4\xd0\x30\xd7\x36\xea\x45\x4d\xfa\x4b\x4a\xed\x1b\xcd\x88\x5d\x2f\xbe\xa5\xff\xa2\xcf\x29\x27\xc1\x37\xc8\x6b\xe4\xfe\x01\x64\x12\x62\x8f\xe7\xa0\xa0\xf0\x2b\x6b\x6a\x9a\x21\x68\x93\x2b\x94\x3f\xf8\xb2\x8d\xd5\x87\xe7\x72\x87\x79\x0a\xaa\xa6\x9a\x98\x50\x6c\x76\x4e\x6f\x5b\xa6\x33\x8c\x09\xf3\x82\xe1\xb9\x87\xd9\x9f\x14\xa3\xe1\x95\x8c\xb6\x2a\xe6\x70\x5a\x57\x7f\x9f\xfc\x67\x30\x64\x01\x12\x87\x41\xa8\xd0\xaf\x03\xc0\xaa\xaf\x6a\xf0\x6b\xd8\x8e\xe4\xb0\xaf\x67\x03\xe0\xea\x60\xb0\x40\x9a\xce\x24\x57\x2f\xb3\x86\xe0\x7e\x9c\x22\xc9\x68\x6b\xdc\x66\xd4\xfc\xf3\xc7\x46\x1d\x38\x33\xa4\xc3\x01\x32\x43\x60\x7d\x4d\x15\x82\x17\x18\x73\x26\xdf\x51\x72\x5a\x6b\xc5\x11\x6e\x99\x0b\xef\x8a\x5a\x95\x79\x60\x02\x07\x20\x6b\xfc\x3a\x6d\xcf\x07\x46\xef\x75\x6f\xd9\x39\xe1\x87\xf6\x68\x75\x07\x16\xc0"}, +{{0x8d,0xa9,0xf5,0x4d,0xa0,0xb6,0xa5,0xa3,0x89,0x85,0xb8,0x8b,0x71,0x33,0x9d,0xc7,0x38,0x4c,0xfd,0x5a,0x60,0xbe,0xe1,0x59,0xc3,0x94,0xc2,0x23,0x63,0xbc,0x7e,0xdd,},{0x1a,0xc1,0xa8,0xed,0xeb,0x21,0x7a,0xe9,0xb3,0xa3,0xde,0x53,0x0d,0x24,0xd8,0x3e,0x11,0xfb,0x65,0x38,0xcc,0x70,0x9b,0x52,0x99,0x4f,0xa9,0xc3,0xf1,0xfa,0xdd,0xc8,},{0xf6,0xdc,0xc2,0xd2,0x7b,0xaf,0x16,0xc4,0xf4,0x81,0x7f,0x87,0x49,0x91,0x57,0xd3,0xac,0x1f,0x84,0xed,0x39,0x8a,0x5e,0x8b,0x0d,0x50,0xf4,0x2e,0xdd,0x73,0x85,0xcf,0x06,0x33,0x7a,0x02,0x36,0x10,0x99,0x70,0xb7,0x9c,0xa0,0x9d,0x7c,0x98,0x31,0xc8,0x76,0xa8,0x02,0x79,0x94,0x21,0xc2,0xab,0xd0,0x75,0x87,0xf5,0xeb,0x66,0x16,0x0f,},"\xbd\x53\xba\xba\x66\x57\xd8\xdb\x8b\xec\xae\x6e\xab\xff\xa5\x2b\x01\x5a\x5a\x05\xfd\xd2\xe0\x70\x64\x7d\xe9\x6f\x9c\xa4\xdd\x21\x9f\xe0\xda\x60\x8f\xa0\x44\x7f\x46\xd1\x7c\x9a\x35\x82\x44\xcd\x54\x08\x59\x65\x82\xcc\xd3\xcd\xd0\x15\x1d\x6f\x09\x23\xe6\x3d\x16\x68\x37\x84\x5f\x27\x3f\xca\x7a\xf6\xc8\x9d\x8d\x52\x46\x17\x5c\x21\x67\xfb\xb9\xc2\xeb\xf6\xa7\x59\x54\x91\xf9\x7a\x97\x13\xb0\x2b\xdf\x41\x3e\x20\x9a\xb2\x2d\xb7\xdd\x2b\x37\xfc\x49\x43\x69\x18\xcc\xeb\xe5\x74\x6b\xc6\x4d\xdd\x6d\xce\x19\xec\x45\x58\xc4\x0e\x08\x96\xe2\x19\x09\x28\x0c\xba\x06\xd1\x6b\x72\xf3\x1d\x98\x76\x85\xd0\x71\xdb\x81\x55\xe9\x9e\xbc\xc6\xc8\x21\xd9\x26\x83\xfd\xce\xe0\x86\x68\xa5\xed\x58\xf8\x39\xd9\xed\xaf\xb9\xf1\x45\x9d\x48\xde\x8e\x1b\xb6\xf7\xce\x84\xda\x0b\xe4\x11\xc8\xf7\xbe\x1b\x9a\x24\xbc\x5d\x0f\xe3\xa9\x6b\x02\x35\x07\x50\xa5\xcb\x25\x0b\x49\x55\x5a\x48\x76\x72\xbd\xff\x3c\x3f\x78\x4e\x3f\xb6\x3c\x1c\x97\xba\x6a\xe4\x3a\x10\xe1\x96\xf1\x88\xdc\xc6\x35\xe2\x14\xe2\x9d\xf5\x09\xe5\x60\x8a\x53\x67\xaa\x28\x00\xc1\xa9\x6a\xd9\x36\xa9\xe2\xa5\x79\xb8\x59\x2e\xc1\x3a\x35\x93\x36\xa6\x27\x88\xc3\xec\x55\xc0\xff\xd6\xa7\xd4\x9e\xcb\x7c\x68\x2e\xfa\x30\x81\x99\xf7\x08\xd7\x9d\x0e\x88\x56\x36\x6d\x26\x9f\xab\x24\xeb\x1a\x07\x5c\x96\xc8\x81\xca\xb8\x97\x08\xce\xd2\x79\x23\x0d\x3f\x1f\x3e\xe1\x73\x67\x22\x83\xeb\x8d\x8a\x82\x40\x38\xf6\x48\xac\x43\x72\x75\xd7\x5a\x0e\x15\xf7\x1c\xe5\x6a\x8a\xeb\x77\x1f\x07\xa7\xf3\x2a\xfc\x9d\x61\x2a\x13\xbd\x83\xb7\xf9\x39\x90\xd3\x8f\xc3\xf4\xf4\xab\x8a\xa9\x43\x0c\x65\x73\x6e\xb6\x4b\x16\x80\x6e\x99\x5c\x1c\xe9\xdc\xf4\xc5\x54\x4e\x7b\x3d\x01\x54\x1c\x57\x21\xbb\x4b\xe4\xcf\x0a\xe3\x82\xa0\xc1\xb1\x69\xd8\xe4\x18\xde\xfd\x55\x94\x42\xac\xea\x14\xb0\x0d\x70\x5b\xcf\xa7\x8b\xe0\x75\x6a\x8f\x37\x7c\xbf\x18\x3b\xf2\x59\x06\x87\x41\x15\xd8\xce\x4c\x3b\xa8\x74\x10\x29\x38\xa4\xea\x16\x03\x6d\x91\xa4\x2c\x5f\x8f\x18\x86\x55\xca\xcb\x00\xc8\x8e\x3a\x68\x50\x88\x16\xe5\xe1\xc3\x1d\x27\x18\x0b\xbb\xa9\x51\x8a\x96\x30\x72\x6d\x7d\x04\x7d\xd8\xd2\xc0\x40\x12\x19\xe1\x4e\x6b\xad\xfc\x9b\x95\xb7\x7a\x6a\xce\x9b\xea\x71\xd1\xb4\x7c\x21\x89\x03\xa1\x15\xad\x02\x9e\x7f\x20\x39\xea\x23\xcf\xd1\xfa\x6a\x44\xd0\x89\xfc\xac\xb6\x78\x15\x3d\x67\x4c\x0e\x08\x17\x64\x99\x55\x95\xcb\x68\x94\x89\x5f\x08\xe2\x5b\x98\x4e\x3a\x69\x4c\x92\xfc\x7c\xbe\x0f\xfc\x46\x97\x23\x0b\xcb\x0c\xa4\x08\xc2\xd7\x08\x5c\x11\xba\xde\xb3\xe6\xc0\xe7\x5e\x6c\x49\x8d\xb1\xbe\xc1\xed\x2a\x3e\x24\x45\xc3\x2b\x19\x13\xa8\x95\x00\xf6\x9e\x7f\x23\xf4\x1d\x62\xe5\xc1\x89\xf3\x9a\x05\x6c\xb9\xfc\x68\xa4\x52\x02\x3a\x33\x3f\x75\x22\x0c\xb9\xb9\x44\x84\xac\xac\x6b\xbc\x67\x1f\x59\xff\xa0\x72\xb7\x1a\x18\x96\xa1\xb3\x06\xe9\xdc\x55\x8d\xa0\xec\x20\xf3\x73\xe4\xc3\x55\xe0\xc5\xec\xcb\xbf\x13\x50\xc8\xc0\x79\x14\x89\x2c\x45\x4d\xef\xce\xfb\x71\x7b\xe3\x4d\x08\x7a\xeb\x24\x4a\x86\xff\x49\xa6\xc4\x70\xaf\xb3\x6b\x40\xfe\x8b\x71\xc5\x05\xa4\xff\x7a\xf2\x98\x4c\x65\x28\x49\x38\xec\x0e\x40\x52\x31\x52\x1f\x48\x10\x14\x7d\xc4\xe3\x73\xfd\xab\x66\x47\xb8\x6f\x79\x82\x75\x02\xfd\x08\x7e\x27\xf3\x10\xd6\xb3\x12\x36\x31\x13\x84\x21\x55\xc5\x7a\x32\xba\x03\xb6\xcf\xf9\x65\x53\x0b\xd7\x95\xfc\x29\x2e\x24\x1c\x9b\x6c\xa0\x85\x14\x00\x32\xef\xe7\x46\xf3\x7d\x57\xe9\x58\x42\x11\x84\xb8\xa4\xc1\xa6\xa1\xe3\x7d\x45\xe0\x77\x31\x98\x33\x06\x8d\xdc\xb8\x9d\x38\xc7\x5b\xeb\xa1\xa6\xe8\xe4\x05\x28\x88\xec\x18\x16\x2d\xd6\xff\x0c\x59\xa2\xfd\x0b\x47\xf3\x11\x91\x95\x68\x0f\xfc\xcd\xdf\x5f\x76\xb3\x5f\x02\x2a\xa6\x6b\xd1\xac\x56\xf1\xae\x33\x3e\x9b\x9d\x04\x6f\x0b\x79\xa8\x92\xec\xc4\xf8\xd2\xf3\x1e\x17\x53\x6c\x4c\x62\xa9\xb5\xe0\x63\xdd\x2d\xce\x37\xd3\xd0\xac\xb4\x20\x23\xeb\x2f\x2e\xa3\x29\xd3\x87\x6c\x23\x86\xa0\x22\x76\xff\xf9\xd3\x08\xab\xba\xdb\x72\x74\x30\x1a\x69\x62\xec\xae\xeb\x20\xbe\xf5\xe3\x6a\xff\xfc\x38\x7c\xa8\xe1\x85\xe5\x62\xb8\x65\xb4\x92\x04\xc1\x7b\x2a\x70\x11\x9b\x06\x1c\x29\xc0\xfe\x90\x04"}, +{{0x7a,0x2e,0xfd,0x39,0x01,0x24,0xd3,0xfb,0xef,0xc5,0x4a,0x57,0x71,0x06,0xe7,0x4b,0x2d,0x1f,0x5d,0xd5,0x04,0xc0,0x50,0xd0,0xd3,0x59,0xe5,0x3c,0x0f,0x5c,0x87,0x2b,},{0xef,0xc3,0x03,0xd9,0x22,0xe8,0x8f,0x70,0xf3,0x8c,0x1a,0x2b,0x92,0x06,0x84,0xef,0x66,0x30,0x34,0xa1,0xb2,0x3a,0xb9,0xd6,0x9b,0x6c,0xe8,0xed,0x87,0x06,0xf7,0xf7,},{0xc2,0x8b,0x34,0x80,0x48,0x05,0xd8,0x1f,0x7a,0xef,0x78,0x49,0x70,0x67,0x0e,0xda,0xa4,0x17,0x23,0x2b,0xcc,0x67,0xda,0x9b,0x51,0xe9,0xc3,0xd7,0x4f,0xc4,0x99,0x1b,0xde,0x97,0xa0,0x6b,0xd5,0x3f,0xa0,0x0b,0xb4,0x40,0xfd,0x56,0x16,0xcd,0x0d,0xe6,0xe9,0xb0,0xd1,0x9f,0x2f,0x68,0xbf,0xaf,0x9d,0x4c,0x51,0x72,0xc4,0xe5,0x20,0x0a,},"\x23\x8f\xbe\x9f\xb3\x5c\x72\x5c\x6c\x1f\x32\x92\x48\x09\x4b\xc7\xda\x1b\x27\x3e\xdc\x76\x99\xa7\xe3\x45\x2b\x57\x88\xd8\x78\x67\xde\xfc\x40\xa0\x05\x90\xe8\x75\x80\xd2\xc0\x27\x5d\xf5\xab\xcc\xe0\xe1\xaa\xa1\x82\x90\xbf\x93\xb4\x4e\x5a\xd9\xd7\x60\xdd\x21\xf1\xaa\xca\x38\x31\x78\xf9\xff\xf9\x13\x0f\x73\x18\x7b\xa9\xd3\x1e\xa3\x60\x4a\x1c\xdf\x39\x11\xe1\x43\x77\xa0\xce\x8b\x44\x18\x9a\xda\xa7\xaa\xc2\x3b\x6c\xdc\x7a\x42\x5b\x7e\xa7\x45\x50\x84\x55\x70\x4f\x9a\xd7\xa8\x95\x27\x18\xc3\x98\xb4\x21\xb6\xe0\x9c\xb7\x8c\xb5\x2a\x18\x14\xee\x2e\x96\x39\xec\x68\xd3\x61\xf0\xa3\x20\x41\xd6\xe7\x42\x5b\x4b\xb3\x3c\x70\x19\x6e\x24\x00\xeb\x81\x2d\xb8\x50\x6c\x9f\x32\x45\xbd\x98\x8f\xbc\x89\x1b\xe2\x0c\xb0\x69\x15\x59\xfc\x91\x6b\x57\xff\x96\xc9\xb1\x44\x89\xe0\x99\x3c\xb7\x39\xa3\x9d\xa2\x46\xd0\x1a\x6e\xbd\x07\x58\x35\x81\xf2\x50\xbf\x48\x0b\xc4\x4b\x2c\x33\x91\x54\x2d\x59\x5e\x4d\x39\x94\x90\x19\x5f\x84\x45\xdf\x63\x8f\x34\x69\x8f\x1a\x96\xed\x27\xb3\x53\x3e\x3e\xb6\x7e\x8f\x86\x58\x65\xfa\x95\x55\xed\x34\xdf\x11\x15\x76\x41\xa0\x0e\x6d\x60\xcf\x62\x3f\xec\x1a\x92\xb8\x7a\x15\xd7\x65\x18\x5f\xd9\x05\x5a\xcb\x38\xd7\x5c\x99\xdb\x4f\xce\x7b\x0e\x39\xfd\xc3\xf8\x51\xda\xf6\x5c\x7a\x33\xf4\x64\x81\x69\x31\x83\x9f\xef\xe8\xe5\x8d\x9a\xb7\x42\xb8\x61\x87\x3f\xd2\x29\x18\x9e\x59\xcd\x4c\xe8\x23\x9f\xc9\x54\x3f\x53\x9d\x2d\x29\x61\x14\x26\x6e\xa8\xc6\xfd\x15\x2a\xc6\xb3\x42\xe5\xd1\xa5\x57\xab\x35\xca\xc5\x1e\x2d\x12\x12\xee\x31\x7c\x4d\x26\x71\x68\x29\xe2\x57\x46\xdf\x17\xd2\xa6\x22\xc2\x43\xf3\xec\xbb\x65\xf5\x7a\xb0\xf4\x27\x0e\x3d\x06\x68\xa9\x62\x50\x22\x45\xb9\x4c\x06\xdf\x0c\x5e\x39\xe3\x53\xaa\x84\x2e\xa0\x80\xcf\x50\x27\x08\xb1\xdd\xa2\xd0\x01\x82\x4d\xe4\x58\xd3\x77\x62\xaf\x2c\xdf\xd5\xa6\xd3\xf3\x5e\x08\xa1\x8e\x14\xaa\x7a\x64\x2c\x51\xe4\x04\x7e\x63\x75\x17\x84\x6d\xf6\x46\xd0\x73\x36\xfb\x17\x24\x34\xe0\x88\x3e\x2b\x77\xd8\xed\x1c\x52\xc9\xcc\x63\x6a\x56\xa1\x9e\x57\xa5\xf1\x61\xb9\x2d\x1d\xcb\xfa\x49\x6f\x34\x4a\xe6\xd4\xdf\xdc\x95\x69\xad\xe4\x57\xa4\x90\x91\x36\x2e\x5a\x0c\xdd\x81\xb3\x75\x32\x43\xfd\xac\x30\xa2\xd2\x7e\xa0\x26\xa5\xe6\x01\x44\x1e\xcd\x55\x37\xa7\x20\x1b\xdc\xb7\xfd\x58\xb2\x40\xd0\x22\x9f\xdd\x9b\xab\xf1\x12\xb5\x69\x48\x12\x25\x0e\x76\x8d\x7c\x0c\xe6\xca\x56\x5a\xd0\x6a\xb8\xf7\x8a\x5c\x99\x50\xee\xf5\x38\x72\x6f\x57\x6c\x4b\xd2\xe0\x75\x5c\x7f\x98\x39\x29\x37\x2a\x5f\xe1\x1c\x73\xf9\xe1\xfa\x45\x3a\xb5\x4b\x58\x17\xaa\xd3\x59\x67\x56\x12\x7d\x84\xe3\x11\x94\x53\xe8\x82\x5b\xb8\x46\x0d\x85\x1f\x1f\x7e\x4a\x28\x38\xa2\xbe\x78\x6b\x23\x35\x04\xa6\x91\xdb\x0f\xa2\x2a\x5f\x41\xfe\x3f\xd3\xc9\xb5\x38\xb0\x4f\x40\x9e\x09\x18\x09\x48\x6b\x28\xad\x0d\xed\xa7\xb3\x8a\x42\xce\xfc\x48\xde\x7d\x86\x79\xc0\x3b\xf8\x77\x23\x85\x11\x82\x0d\x07\x70\xcc\x8d\x7b\x41\x72\x37\x78\x23\xa0\xb9\x91\x49\xab\xb8\x91\x8b\xfb\x66\xd5\xab\xfc\xd1\x00\x60\xb0\x5c\xb4\xf2\x39\xdd\x42\x81\xd9\x34\x83\x50\x4b\x73\x1e\xaf\x5a\xdd\x51\x5f\x1f\x3c\x3b\x52\xb4\xe3\xbd\xaf\x97\x6a\x17\xb3\xc9\xec\x61\xbf\xc8\xe7\x71\x16\x71\x58\x04\x53\x2c\xf2\xdb\xf2\x0b\x7b\xa5\xea\xd8\x5a\xfb\x95\x2b\xee\xc2\xfc\xcf\xf8\x5f\xf5\x07\x2b\xa4\xed\x6b\x54\x38\xab\x15\x20\xc6\xef\x4b\x0b\x26\xf1\x2e\x84\xae\xdd\x65\xce\x5c\x7b\xbe\x6a\xcb\x67\x72\xf5\x93\xa6\xb4\xf8\x1d\xdd\x9d\x50\x27\x46\x50\x50\x47\xc8\x12\xa0\x06\x7a\xfc\xeb\x8d\xc9\xbf\xf3\x0d\x40\x87\xf8\xd5\xa3\x75\xec\xa6\x05\xa0\x62\x27\x84\xd8\xfe\xa2\x78\xcd\x1a\x52\x41\xad\x4b\x3f\x1b\x91\x4f\x74\xf7\x3b\xc3\x6e\xe7\xcc\x82\xd9\x6e\xfd\xa6\x3a\x3b\x67\x99\x73\x0f\x20\x65\x6c\x12\x35\x6c\x79\x06\x9b\x2b\xe6\xf9\xb7\x7b\xe1\x01\x98\x31\x18\x82\x3e\xa6\x6e\x7c\x20\x98\xfb\xc7\x2f\xc9\xc0\x39\xdf\xe3\x0f\x2d\xab\xa1\x3c\x3b\xde\xfb\x8a\x78\x0b\xeb\x5c\xb1\xb6\xc2\x86\xa6\xb3\xef\x48\xfd\x15\xc6\x6c\x04\x5b\xa2\x9f\x09\x70\x41\x3b\x98\x8d\x0e\xa0\x04\xab\x84\xc9\x39\x19\xf0\x4f\x9b\xf8\xca\xf5\x8c\x4e\xb4\x78\xf3\x58\xef\x8b\x68"}, +{{0xef,0x36,0x48,0xcb,0xe7,0x34,0x02,0xab,0x45,0x0c,0xd6,0xec,0x37,0xe5,0x45,0xd0,0xcd,0x2c,0x99,0x9e,0xcc,0x1f,0xa3,0x81,0xa4,0x5c,0x66,0x0e,0x18,0x53,0x30,0x32,},{0x52,0xa1,0xa4,0x52,0x73,0x87,0x26,0x76,0x58,0x2c,0xc7,0x67,0x33,0x99,0x26,0x41,0x4c,0xd5,0xd0,0x3d,0x98,0x0c,0xf6,0x29,0xdd,0xa2,0xd1,0xa2,0x05,0xe9,0x83,0x0a,},{0xf6,0x70,0x79,0x29,0x42,0xec,0x41,0x44,0x28,0x47,0x56,0x38,0x85,0x3c,0x42,0x72,0x8e,0x86,0xba,0x12,0xbb,0xe8,0x59,0x48,0xb3,0x91,0x34,0xcf,0x6e,0x2b,0xd1,0x28,0x13,0xe0,0xd8,0x3e,0x51,0xe6,0x57,0xc9,0x01,0x07,0xad,0x93,0xa4,0x78,0x8a,0xa3,0x83,0x13,0xfa,0x96,0x2f,0x67,0x67,0xa8,0xf7,0x80,0x5b,0xde,0x65,0xca,0x42,0x0d,},"\x6a\x93\x37\x8f\x88\x0c\xf0\xff\xdb\x8e\x07\xd6\x83\xcc\x35\x2e\x2a\x10\x33\xc4\x50\xba\xa0\xe8\xc4\xe1\x62\x05\xfd\x0c\x02\x74\x3b\x0e\xa0\x64\x97\x1d\x91\x1e\x49\x47\x13\xe6\xd9\x4a\x02\x17\x2e\xd0\x14\xd5\x06\x59\x2e\xc6\xc7\x0a\x9c\x97\x85\x52\x46\xbf\x3d\x26\xf3\xcf\x74\xf4\x93\xc1\xb6\x97\xa0\xc4\x14\x16\x0c\x34\x14\x12\x83\x09\x85\x43\x08\x06\xa0\xcb\x3c\x84\x75\xe7\xe5\xa9\x73\x68\x6c\x24\xd5\xef\x1b\xe7\xd0\x06\x50\x96\xfe\xb5\x2e\xab\x26\x0b\x5c\x48\x8a\xf0\x92\x70\xde\x6d\xec\xd3\x3f\xea\x85\x89\xdd\x10\x21\xba\xf4\x1e\x3f\x25\x5f\xb8\xfa\x19\x16\xeb\xd8\x53\x1e\xeb\x2f\x88\x6b\xb3\xb3\xb0\x4f\x9a\xf6\xb2\x76\xc3\x59\x23\xf1\x0d\x3a\x0a\xf1\xe3\xf5\x8b\x0d\x15\xae\xd1\x65\x04\x5f\x20\x6f\x3f\x43\x0a\xbd\xff\x09\x44\x90\x97\xe4\xb2\x6d\x00\xa8\xf9\xf1\xe8\xf7\xa1\x9f\x38\x58\x81\x24\xc3\x28\xec\x43\xa9\xcf\xb4\x3d\x3b\x2c\x6b\xdf\x6a\x3c\x1a\x10\x2e\x0e\x33\x3d\xe1\xac\x21\x4a\x6d\xf7\x6d\xab\x44\xba\x76\xbf\x03\x52\x73\xb7\xff\x62\x38\xec\x82\x48\x3b\x2d\x2d\x9d\x54\x29\x1a\x72\x27\x0f\x88\x93\x3b\x78\x6c\xac\x05\x1d\x99\x0b\x3c\xf7\x40\x84\x5f\xed\x3a\x67\x86\x7d\x7c\x7c\x05\x67\x4e\x7c\xb0\x2c\xa5\xb7\xac\xdf\xba\x38\x52\x80\x3a\x3d\x56\xc4\xd5\xc1\x3b\xb1\xd7\x72\x34\x67\x74\x1e\xac\x1f\x2a\x7a\xcd\x3a\x95\xf3\xa5\x16\x10\xa4\x86\xfc\x53\xa9\x85\x16\x28\xc5\x57\xd3\x6d\x8a\x4c\xd3\x7a\xae\x9c\x41\x74\xdb\xbd\xb6\xbd\x88\x5c\xf4\x0b\x38\x2b\x8d\xed\x24\xa4\x52\x2a\x27\x8f\xef\x76\xc4\x53\x19\x06\x7e\x55\x28\x6e\x7b\x08\xc6\x03\x48\x6e\x38\xa0\xac\xf4\x7e\xde\xf8\x48\xec\xbe\x94\x2e\xce\xad\xb8\x63\x6c\x83\x3f\xeb\x88\x2a\x51\xa4\x59\x5e\x24\xf6\x07\xca\x3c\x9d\xa1\xb2\x40\x4c\xe5\xc7\x47\xe0\x62\x64\x17\x4d\x64\x50\x43\x31\x70\x9b\xef\x30\x05\x5a\x5d\x69\x5e\x09\x53\x7c\x8f\x8c\x1e\x5a\x3a\x5d\xb0\x65\x99\xe3\x19\xdf\xdb\x28\x72\x96\x65\x27\x3b\xf8\x68\x95\x5e\xa5\x64\x27\xf0\x8b\xac\xd7\x77\xf1\x79\xb3\x02\xf3\xf6\x8d\x04\xf3\xf3\x88\x3d\x34\x49\x55\xb6\x55\xdd\xc6\xd5\x28\x2b\x6d\x4d\xf1\xd8\x36\x30\x21\x0e\x69\x91\x78\xe1\x1f\x72\x2e\x9e\x5c\xda\x67\x28\x92\xae\x9b\x23\xe8\x16\x9c\xbb\x54\x80\x93\xb8\x3e\x64\x3e\xb4\x99\xd9\x37\xd2\x8f\x38\x11\x59\x7b\x64\x84\x10\x2f\x0c\x8e\xb8\xc8\x88\x8c\xda\xc2\x29\xae\xbf\x89\x08\x6a\x64\x95\xac\x55\x1f\x3b\xbd\xf2\xd1\xc9\xa9\x3e\xd1\xd3\xa8\x61\xee\xcd\x9e\xb8\x39\x94\x9b\xfb\xe6\xa4\xf6\xe6\x48\x6e\xde\xda\xb5\x22\x9d\x53\x2b\x58\x97\x6d\x67\x51\x2f\x9f\x71\xae\x79\xb4\x14\x5c\xa2\xfa\x49\x7a\x16\x5f\x11\x07\x17\x66\x6c\xa3\x34\x0b\xbd\xa8\xdf\x1f\x82\xb8\xc0\x54\xcf\x76\x54\xc3\x56\x90\x16\x8f\x96\x27\x7d\x41\xc1\xc2\x36\xb6\x81\x98\x17\x3c\x6e\x2b\x0a\x20\x8e\xf8\x3c\x02\xa4\x3e\x47\x3d\x90\x68\x6a\xce\x75\xb5\xbd\x32\x1b\x3f\x54\x28\x13\x27\xa6\x73\xca\xd4\xd4\xad\x30\x40\xd4\x8c\xf4\x93\xea\x23\x1b\x3f\xec\x06\xf3\x99\x32\xd7\xf7\x0a\x38\x42\x8d\xf8\xfe\xe4\x37\x05\x32\xae\x5f\xb1\x12\x05\x9f\x0a\x1d\x4f\xbe\x11\xb5\xa2\x3b\xb8\x76\x35\x42\x9e\xd3\x3a\xd1\xf6\x14\x80\x14\xcb\xc1\x60\xd9\x3c\xa2\x59\x20\x53\xa6\xe9\x53\x78\xd6\xcd\x3f\x50\xdb\x52\xbe\x92\x8e\x40\x92\xfe\x5d\x2b\x70\x95\xa9\x56\x68\x64\xad\xfd\xa5\x9f\xd5\xf2\xfb\x62\x54\xbd\x59\x17\xb7\x0f\xa1\x46\x99\x66\x5a\x37\x29\x7c\x98\x3c\x1b\xb9\xef\xe1\xc6\x7b\x41\x3d\xd1\xa8\x53\x0c\xbf\x22\x72\x97\xa8\xbb\xf9\x3a\x8a\x02\x45\x4e\x8e\x46\x1a\xc2\x12\xb8\x46\xa7\x0d\x5d\x56\xd6\xc3\xa6\xe6\x5a\x03\xbe\x05\x80\x21\x9b\xdd\xec\x88\xd4\x03\x89\x11\xfd\x95\x74\x56\x3f\x33\xe0\xf9\xe6\x04\x46\x88\xd3\xdd\x48\xfa\xc7\x03\x86\x9a\xa0\x9d\x96\xef\xee\x7d\x6c\x68\x07\x1d\x99\x22\xd5\xe8\xed\x8d\xc4\x0f\x1b\x79\x8f\x1c\x58\x0f\x78\x59\xcb\x84\xf1\xe1\x4b\x5e\x74\xdd\xea\x16\xad\x5c\xbe\xea\x4c\x48\xfb\xcf\xfd\x29\x53\x1a\xcc\xc0\x63\x39\x38\xe3\xbc\xb2\x21\x26\x76\xb6\x1e\xf9\x01\xe9\xc8\x31\xa4\x17\x74\xd8\x31\x7e\xf3\x5a\xf7\x69\x90\xbd\x24\x93\x1f\xde\x6d\x40\x7e\x22\xe7\x63\xcf\x6a\x57\x90\xb2\x37\x61\x90\x8e\xee\x60\x96\x37\xa2\xc1\x10\x59"}, +{{0x2c,0x8e,0xe7,0xfa,0x9b,0xa2,0x8c,0xe7,0x04,0x96,0x76,0x08,0x7b,0x11,0x63,0xb2,0x41,0x11,0x8d,0x34,0xcd,0xf5,0x34,0xae,0xbe,0x8b,0xa5,0x92,0x82,0xa6,0x2a,0xc2,},{0x24,0x4c,0x24,0xf5,0xec,0xb2,0xdd,0x1d,0x14,0x63,0x51,0x22,0x21,0x32,0x5d,0x73,0xc8,0x1e,0xe4,0xd8,0xad,0xb8,0xe0,0x1e,0x23,0x34,0x5c,0xaf,0x9c,0xa5,0x35,0x3b,},{0xca,0x0b,0xb6,0xc1,0x23,0x56,0x55,0x5f,0x6e,0x1d,0x8f,0x5c,0x8a,0xa7,0xb5,0xe8,0x0c,0xd2,0x80,0xe8,0xb1,0xb9,0xba,0x2e,0xc9,0x55,0x0f,0x62,0x2f,0x48,0x2c,0x3a,0x9a,0xd3,0xbe,0x03,0xa4,0xc9,0xdf,0xc1,0x0d,0x01,0x12,0xb0,0x18,0x9d,0xe9,0x4b,0xff,0xaf,0xd7,0x03,0x41,0x14,0xe0,0xe0,0xd4,0x2c,0x23,0xf3,0x2d,0xc8,0x18,0x07,},"\x07\x66\x9a\x89\x64\xf0\x63\x80\xd2\xd4\x98\x2c\xb6\x34\x9d\xe5\x50\xb3\x8c\xbc\x35\xdb\x2c\xe5\x72\xde\x88\x7f\x66\x30\x55\x73\x6f\xaa\xc7\xec\x07\xc3\x2d\xf6\x0e\xe2\x59\x84\x22\xbf\x37\xe7\xcf\x31\x9a\xb3\xc9\x05\x56\x08\xca\x0c\x49\x75\x7d\x76\x88\xe2\x01\x3b\x82\x44\xf3\x54\x04\xf4\x5a\xc2\x19\x49\x7f\xe9\x24\xde\x93\xa5\x8d\x0f\x72\x1a\xed\x78\x25\xf6\x3b\x26\x67\x07\x7c\x16\x1e\xb4\xdd\x8b\xf7\xdd\xbd\xbb\xc1\x9a\x9e\xae\x59\x78\x97\x8d\x5a\xeb\x33\xa0\x6d\xde\x18\xe6\x12\xe0\x5b\xdb\xca\xe0\x16\x1a\xa2\x38\x90\x38\x02\x64\x29\x96\x0d\xda\x3a\xa1\x7e\x96\x7d\x10\x77\x3c\xa4\x97\x35\xd8\xec\xd7\x40\x9b\xe1\x65\xc0\x9b\xb0\xb5\x09\x69\x1d\x59\x1c\x18\x5c\x93\xcd\xee\xae\x95\x35\x23\x16\x54\x46\x80\x52\x38\x21\x45\x8c\xac\xcf\x52\x8a\xc0\x45\x4e\x4c\xdd\xc6\xdf\x0d\x1e\xa5\xf1\xf5\xcc\x1e\xee\xe0\x5e\x19\xa2\xad\x0b\x6a\x49\x73\x6e\xd8\x55\x23\x36\xfc\xfc\xad\xbd\x93\x1b\x0b\x8e\x96\x3b\xe0\x5c\x8e\x70\x37\x38\x85\x52\x51\x2b\x68\x23\x58\x3e\x4a\x14\x38\x4c\xef\x50\x29\x23\x2d\x3e\x0b\xaf\xe4\x66\x35\x1b\x4b\xb3\xf5\x67\x54\x5a\xb4\x1f\xa4\x6b\xff\xaf\xa8\x77\xa1\x2b\x38\xa2\x7a\xbd\x64\xf7\x7f\xbb\x4d\xb4\x66\xff\x7f\x70\x65\x04\x14\x1d\x3a\xdd\x0d\x73\x72\xf1\x6f\xe3\xd8\xc6\x9f\x62\x99\xd9\x39\x66\xd6\x24\xa3\x07\x0e\xad\xb8\xb4\x9f\x29\xfa\xb4\x84\x4c\x75\x28\xa2\xa4\x0b\x66\x98\x70\x60\x69\x5c\xaa\x66\xb8\x67\x18\xc5\x10\x49\xac\xf4\xcf\xad\x38\x53\xed\xb4\x92\xe3\x68\xcb\xd0\x73\x96\x8e\xca\xa4\xa1\xee\x60\x46\xb5\xe8\x26\xe9\x01\xf4\xa8\x08\xc0\x42\x7c\x02\x6f\xe2\xf7\xb2\xe1\x96\x86\x67\xb5\x3a\x7d\x36\xd7\x02\xf2\xff\x82\xc6\x42\xd3\x49\x19\xf8\xe9\xaa\xaf\xe4\x62\xa3\xd4\xf9\x26\x92\xde\xac\x75\x2b\xe3\x48\xf5\x4c\xf0\x89\xdd\x9c\xd0\x51\x84\x6b\x04\xb7\x19\x31\xe1\x9e\x89\xd1\x25\x86\x4b\xfa\x89\x48\xac\xe0\xef\xf3\x3c\x45\x11\x05\x69\xa0\xdf\x37\x53\xf4\xc5\x8d\x80\x02\xb5\xbc\x38\x10\x2e\xc2\xec\xf6\x95\xfa\xfa\x89\x16\xda\x90\x02\x38\x7e\x44\xf9\x6d\xab\xf8\xa9\x82\xc5\x3c\x9b\xad\xbc\x37\xbd\xe4\x37\xf1\x46\xf7\x7d\x8f\x7b\xaf\x12\x87\x31\x96\xb0\xc3\x61\x93\xaf\x55\xf5\x42\xd9\x96\x8a\xed\x80\x69\xab\x9f\xbc\xd6\x81\x4e\xc4\x72\x79\x9a\xd0\x9c\x73\x0d\x41\xed\xde\xca\x3b\x62\x69\xd3\x1a\xb5\x23\xb5\x95\x47\x07\x73\x76\x34\x5b\x05\xf2\xae\x69\xb4\xee\x72\x8c\x86\x3d\x1b\xc0\x4e\x9b\x7d\x3d\x0f\xcc\xeb\x35\x9c\xbd\x08\x58\x59\x7a\xf2\xd6\x06\x3e\x25\x3f\xae\x2c\x3f\x25\x03\x4c\x33\xed\x59\xed\xd2\x78\x28\x68\x29\x86\x81\xca\xf5\x64\xdb\x8d\x19\x36\x6f\x34\xea\xe8\x5b\xa7\x3c\x1e\x23\x89\xb0\xdd\x78\xa9\xd2\xca\xa0\xf2\x3c\x9a\xd5\xf6\xcd\x9f\x2c\x4a\xd5\xd5\x89\x46\xad\xb7\x18\xcb\x83\xda\x58\xe2\xfc\xbb\x60\x25\xbe\xf4\x66\x0a\x83\xe0\xaf\x55\xe2\x03\x08\x02\x93\x2f\x2a\x89\x6a\x09\x60\x79\xb7\x54\xc9\x9f\x7b\x64\x23\xb4\x5a\x86\x47\x2e\x67\x23\xef\x88\x96\xc4\x32\x4c\x73\xd3\x4a\xd5\x8a\x4c\x01\xb3\x8a\x97\xc7\x3b\xe5\xaa\x7f\x74\xa2\xfa\x4d\x07\x95\xaf\x6d\xbf\xcd\x6d\x4e\xb4\x42\xa7\xe2\x04\xdb\x4e\xcb\x1f\x8a\x22\x6b\xdf\xa2\x1b\x6e\xb1\x71\xc9\xe5\x9f\x1a\x19\x2e\x23\xa7\x6c\x35\x2b\x04\xd8\xa8\x02\x33\x98\x5b\x77\xa2\x9c\x02\x01\x19\xce\x65\x1c\x7f\x41\x83\xd0\xe9\xc1\x9f\xe1\x8a\xa1\x02\x0c\x25\xe4\x58\x9d\xee\x34\xb9\x01\xbd\xaf\x9f\xf9\x45\x0c\x91\xaf\x3c\x1d\xb6\x70\xb4\x77\xe0\xac\x21\x07\x69\x6c\x9e\xc0\xd3\x1d\x82\x64\x7b\x68\xea\x19\x49\x9f\xe3\x4a\x8e\x2e\x7b\x37\x8d\xc7\xe7\x54\x24\xe8\xc4\x56\x45\xb0\xc2\x81\x8e\x9f\x88\x5a\x1c\x58\x41\x5b\xba\x1c\x3f\x2a\x77\x54\x9b\xdc\x46\x80\xdb\xcd\x16\x50\xc7\x5d\x0f\x45\x2a\x6b\x20\x85\x91\xdf\x0f\xa6\xe1\x81\xda\x2a\xbf\xab\x44\x46\x21\xd5\xf7\x7c\x2c\xd7\x95\x56\x46\x72\x46\x44\x7a\x89\xf0\xaa\xac\xad\x66\x0c\x9a\x92\x5e\xba\xfb\xad\x43\xc4\x78\xa3\xc8\x50\xa2\x7e\x01\x01\x9d\x88\xa5\xb1\xdc\x81\xb5\xd2\xe9\xf7\x40\xa0\x28\xcc\xb7\x2c\x1a\xcf\x89\x7e\xa5\xad\x89\xe0\xf9\x44\x88\x88\xd5\xb1\x5c\xe6\xe4\x29\x77\xf7\xa7\x29\x15\x5a\x28\x4d\x11\x87\x58\xac\x65\xf3\xfb\xb9\x8d\xeb\x65"}, +{{0xdd,0xd8,0xe9,0xff,0x85,0x56,0x79,0x89,0x6a,0x13,0x97,0xb4,0x27,0xdb,0x85,0x43,0xab,0xe8,0xbb,0x5d,0xd1,0x22,0xe3,0xe3,0x02,0xcc,0xfc,0xe5,0xfd,0xc6,0x3e,0x12,},{0x5a,0x9a,0x31,0x2e,0x89,0x2a,0x10,0xb9,0x8d,0x0d,0xcd,0xd2,0x8d,0xb3,0x48,0x1c,0x3c,0x28,0xad,0xd5,0xad,0x0b,0x19,0x46,0x16,0xda,0x4a,0x3d,0xf7,0x66,0x01,0x09,},{0xdf,0x84,0x9b,0x7b,0xd2,0x97,0x45,0xf8,0xbe,0xcd,0xdd,0xf6,0xc9,0xba,0xf0,0x94,0xd7,0xa9,0x8c,0xc9,0x33,0x8c,0x34,0x4e,0xca,0x17,0xfd,0xe0,0x75,0xfd,0xa8,0xd1,0x54,0x32,0x99,0xf6,0x25,0x98,0x23,0x17,0xdb,0x7b,0x3c,0x77,0x3b,0x64,0xf7,0xd1,0xf2,0x86,0x92,0xac,0x45,0x3b,0x81,0xd7,0xec,0x7b,0x7e,0xc3,0x41,0x7a,0xce,0x04,},"\x5e\x8f\xee\xc5\x09\x35\x0d\x2e\xe7\x95\x5b\x6f\x3e\x27\x82\x78\xa4\xcb\x48\xae\x72\xb4\x65\x89\xe4\x78\xbe\x59\x74\x7d\xf5\x39\x4a\x16\x9f\x19\xe1\x0d\xb5\x32\x02\xa6\xa5\x23\x20\xb6\x3a\x9a\x2b\x72\x3f\xd3\x1a\xa2\xdb\x6d\x58\xc5\x73\x32\xda\x31\x78\xbc\xf9\x66\xc5\x3a\xbd\xa3\x5f\x12\xda\xef\x9e\xdc\xf3\x99\xe4\xa8\xc5\xf8\x3d\x36\xf4\x4a\x17\xd7\x98\x46\xbf\xc9\x6c\xe6\x90\x19\x4c\x21\x9a\x29\x89\x2f\x03\x67\xa7\xab\x38\x44\x83\x78\x79\xe3\x81\x8d\xb8\xd7\x0c\x4e\x3f\xba\x4d\x28\x07\x34\x64\xdf\x20\x85\x95\x10\x38\xfe\xa4\x32\x81\xb6\xb6\x06\xdc\x88\x46\xb3\x0b\x07\x63\xf2\xca\x82\xbd\x50\x21\xf9\x11\x70\x35\xa7\x7b\xcd\x10\x75\x47\x7c\x5f\x43\x21\x43\x34\xd4\xd4\xce\xdd\x18\xf7\x38\xd6\x76\xc7\xb5\x1a\x18\x5f\xfa\x8d\x04\x10\x11\x86\xa4\x95\x2b\xbd\x87\x22\xf5\x39\x90\xb6\x06\x37\x04\x1e\x11\x4a\xeb\x8c\xe7\x11\x11\x31\xd4\xdb\x3f\xb4\xd3\x5d\x99\x5a\xd8\xd6\x65\x0c\x0c\x4c\xcd\xce\x9d\xcc\x39\xdb\x18\x8a\x68\x78\x55\x62\x74\x06\x26\xb3\xae\x3e\x02\x3f\x40\x77\x2d\xed\x87\x6a\x45\xcb\xef\x74\xa0\x58\xfd\x78\xc1\xa1\xff\x2c\x24\x51\xe1\x11\xac\x1b\x4b\x7e\xe4\xc8\x1c\xd7\x63\x10\xd4\xd2\x98\xfb\x3c\x49\xf5\xe6\x40\x19\x08\xa6\x30\xfa\x85\xdb\x74\x71\x80\x4f\xe9\x90\x84\x7f\x0f\x75\x94\x72\xf5\x93\xdc\xf0\x2e\x11\x3e\x15\xe5\x64\xd3\x0d\x59\x84\x69\x2d\xa5\x5b\x0b\x7f\x22\x19\xc4\xac\x16\x26\x51\x1a\xcf\x19\x4d\xc7\x02\x6e\xb9\xd3\x67\xa4\xa2\xf1\xdf\xb5\x15\xcb\x2c\x08\xda\x4f\xe5\x95\xc8\x58\x11\x12\x0c\xba\x2a\xe7\xb6\x6e\x67\xc9\x1f\xb8\xfb\xcb\x9d\x99\xf1\x3e\x50\xfd\x67\x46\x4d\x90\xc8\xdc\xf6\x93\x55\x23\xcf\x6d\x13\xfd\xd1\x06\x35\xb9\x23\x2b\x7a\x61\xdc\xec\x9a\x2b\x92\x10\x61\x41\x0d\xf1\xde\x6a\x45\x16\x7f\xb9\xf6\xf1\x09\xdc\xc0\x88\x91\xf2\x03\xb2\x74\xa3\xb6\x82\x71\xb3\xf3\x5e\x74\xf9\x4b\xdc\xed\x0c\x5f\xf8\x63\x71\x73\xa1\x76\xe7\xda\xcc\x81\xf2\xcd\xc4\xfb\x0d\x52\xd1\xdf\xa7\xf2\x7b\x55\x2f\xd8\xd8\x7a\x1c\x55\xd6\x94\x7f\xd9\x2e\xd3\x25\x3f\x95\x94\xdb\x7d\xf1\x7a\x7f\xc6\xa7\x5e\xcf\x4f\xaa\x4d\x1e\x21\xb6\x76\xb3\x72\x7d\x77\xfb\xd4\x3f\xa7\xbe\x76\xbf\xb5\x8f\xc3\x09\xe5\x67\x5f\x0a\x85\x9c\xc4\x7f\x37\xb1\xbf\x45\x59\x32\xd8\x24\xe8\x63\x78\xde\x7a\x7e\x8c\x40\xce\xd2\x20\x90\x04\x4d\xbb\xf9\x1c\x70\xe5\x28\xea\xcd\xef\x37\x85\xba\x3c\x69\xa3\x73\x5a\xf6\x70\x9c\xd7\x6a\xab\x28\xa6\xac\xa6\xe8\x44\x97\x4b\x10\xb3\xfb\x7b\x09\x86\x00\x7a\x72\x7c\x2c\x8f\xc9\x5b\x25\xf3\x1f\x14\x6b\x36\xac\xd4\xc5\x37\x07\x49\x20\xaf\xf2\x47\xde\x0f\x17\x9c\x13\xca\x57\x79\x0a\x6a\x71\xd6\x2e\x23\x32\x1c\xcc\x75\xb7\xf3\xb0\xaf\xa0\xd0\x35\x27\xc9\x11\x4a\x7d\x4e\x30\xc1\xac\xe6\xd7\x71\x20\x13\xde\xe6\x66\x99\xaf\x9c\x56\x1c\x44\xae\x61\x98\xed\x39\x10\x4e\x60\x61\xae\x2c\x45\xa9\xa3\xc7\x4b\x5d\x0f\xbc\x4a\x33\xe8\xdf\xe2\xa8\xac\xc9\x51\x1e\xf7\xe6\x56\x71\x33\xf9\xfe\x35\x54\x28\x4a\x75\xa0\x59\xa6\x49\xdd\x24\xec\x04\xa5\x77\x30\xc6\xd2\xe9\xbf\x11\x4e\xa5\x8a\x89\x94\xab\xdb\x0c\x19\x43\x24\x15\x72\xc7\x9e\xad\x04\x3a\xd1\xc8\xca\xaf\x5c\x9d\xa5\x3d\xd0\x55\x22\xfe\xbc\x40\x33\x54\xd6\x2f\xe3\xff\x93\x88\x2d\xf7\x5f\xb2\x94\x58\xd2\x2e\x69\x96\xc3\x5b\x69\xfa\xae\xf2\xe0\xc4\x16\x38\x86\xcb\x3c\x3d\x0f\x60\xe1\x50\xd3\x63\xd6\xdb\x59\xfe\xfc\x62\x6b\x1b\xbb\x1e\x05\x2a\x62\x41\x4c\x4b\x78\x56\xd7\x20\x93\x43\x2b\x08\xf8\x21\xbc\x78\x4a\x5a\x6b\x0b\xc2\x64\x9c\x2d\xaa\x50\x86\x58\x98\x0d\x80\x22\x91\xe7\x34\xab\xaf\xf0\x6a\xfb\xf2\x79\x5e\x4e\x35\x4d\x52\x21\xdc\x4f\x52\xcc\x96\xd6\xb8\xcf\x18\x08\xb1\xa8\x20\x8d\xb7\xda\xa8\x0a\xb7\x10\xc5\x6a\x8b\x0e\x9c\xb8\x08\x1d\xee\x93\xf5\xf0\x15\xf0\x76\x64\x46\x3a\x3d\xcc\xff\x7c\x8a\xd1\x99\x23\xa9\x7e\x39\x04\x5b\xcc\x4d\xce\x0a\x73\xd4\x9c\x56\xd5\xe9\x37\xbd\x11\xe6\x18\x23\x40\x1c\x06\x62\x06\xe3\x13\xe6\x0b\x47\x53\x7e\x34\x70\x4d\x7d\x35\x15\x55\x9b\xb9\xd0\x53\x2d\x02\x8e\x28\xa5\x7a\x87\x9f\xd6\x17\xcc\x61\xf7\xf7\x76\xbd\x6a\x00\x8c\xd4\xf8\x12\x37\x8e\xd3\x7f\x39\x4b\xb9\x7e\x6e\x75\x6d\xa8\x19"}, +{{0xa8,0x86,0xf4,0xd3,0xf3,0x4e,0x32,0x0e,0xc6,0xd5,0xf4,0xca,0xa8,0x63,0xf8,0x14,0x77,0xdf,0x77,0x2e,0xff,0x97,0xe6,0x4a,0x37,0xa0,0x5f,0x42,0x11,0xd1,0x90,0xa8,},{0xe9,0xbc,0x96,0xc8,0x1e,0x87,0x81,0x10,0x26,0x8b,0x55,0xde,0xf7,0xea,0x40,0x07,0xa4,0xef,0x9f,0x54,0xd3,0x83,0xd5,0xfb,0x0f,0x6d,0x43,0x43,0xe1,0x01,0x0f,0x38,},{0xab,0xf2,0x83,0xdb,0x1f,0x80,0xc5,0x4c,0x58,0x3b,0x49,0x9d,0xbe,0x20,0xaa,0x04,0x24,0x8c,0x1d,0xce,0x12,0x1f,0x39,0x11,0x67,0x78,0x13,0xac,0x3e,0x01,0x1f,0xd1,0x59,0xad,0x0b,0xf7,0x6b,0x1a,0xa7,0xcc,0x7b,0x14,0xd7,0xb5,0x50,0x84,0x86,0x88,0x25,0x2a,0xcc,0x7f,0xec,0xe9,0x04,0x87,0x24,0x0c,0x3d,0x39,0x9d,0xd3,0x43,0x08,},"\x8b\x83\x1b\x87\x7b\xc3\xa9\x9f\x61\x3c\x89\xcd\xa6\x98\xb3\x75\x9d\x64\x38\x22\xb5\xa8\x8f\xaf\x38\x22\xec\xb2\xce\x98\xf6\x71\xd7\x55\x43\x21\xb2\x4b\x74\xb4\xe3\x0a\x66\x3f\x7a\x55\x70\xae\x91\x7f\x47\x9b\xda\x29\x89\x4b\x1a\x8c\x02\x8c\x9d\x19\x3e\x4e\x7a\xc1\x19\x16\xdd\x8e\x9c\x3f\x0e\xc0\xef\x80\xbd\x27\xfd\xfe\xee\x80\xc1\x70\xc7\x81\x40\xb2\x4c\x15\x27\x14\x15\xac\xf7\x5c\x26\x95\x6a\x4d\x4b\xf9\x9d\x40\xe8\x61\xe9\x07\x83\x20\xd0\x97\xe1\x25\x9e\x5e\xc1\x7b\x58\x3a\x95\xe5\x24\x30\xdd\x8c\x00\x8e\xd8\xc7\xdd\x1d\xe1\xbe\xcd\xd1\xe6\xbf\xec\x4b\xf3\x34\x7a\x22\xdd\x24\x9f\x3a\xc3\x07\xa2\x94\x5e\x91\x37\xfa\x4a\x8c\x26\xc8\x02\x10\x77\x23\x9c\xb3\x24\x81\x6a\x8d\xad\x32\xb0\x1e\xe3\x4a\x08\x90\x30\x98\xcb\x9c\x42\x45\x29\x1b\x90\x3c\x96\x27\x07\x40\x95\x24\x9e\x78\x28\x13\x47\x70\x32\xba\x32\xef\x04\x1a\x07\x48\x6e\xb4\x47\x8c\x57\xb9\xd5\x32\x26\x9a\x4a\x47\xcb\x5e\x97\x4d\xf7\xe0\x10\x96\xfb\xe4\xf1\xcc\xd4\xe6\x63\x66\x34\x87\x97\x4c\x62\xcd\xd9\x4d\x77\x71\x6c\x84\x79\xd7\x9f\x6b\x6a\x7d\x9c\x15\x59\x88\xcf\x39\x02\xfb\x69\x74\x24\x96\x3e\xc4\xec\x34\xff\x2a\x35\xd7\x42\xc4\x45\x5a\x59\x3b\xac\xff\xc4\xd9\x69\x9b\xa7\x62\x6c\x76\xcb\x1a\x61\x62\x53\x75\x18\x87\xf6\xff\xe2\xbe\x20\x8c\x71\x3d\xf1\xab\x63\x6d\x72\x2e\xa0\x6c\x1c\x03\xa5\x7f\x2c\xec\x08\x03\x86\x6c\xca\x33\x35\xc2\x8b\xf4\x1c\x7d\xef\x81\xac\xb3\x88\x58\xdc\x10\xe5\x94\x67\x20\x86\x24\x96\x7e\x2e\x22\xd9\xe5\x66\x1b\xb9\x45\xf9\xe0\x51\x76\x87\xdc\x80\xf9\xb8\xfd\xec\xc8\xa9\x76\x00\xb6\xc2\x19\xa3\xb2\x3a\x90\xb6\xd1\x8a\xaa\xce\x2c\x78\x40\x0f\xf3\x8c\x8c\x05\x96\x7f\x54\x4b\x6a\x60\x6c\x71\xac\x19\x9e\xaf\xd0\x7e\xb5\x84\x8d\xf1\x65\x7e\xfb\x23\x3f\xba\xba\xe6\x3a\x05\x63\x81\x91\xa0\xaf\x74\x84\xa1\xba\xe1\x58\x13\x75\x67\x2c\x57\x1e\x26\x4f\x60\x42\x25\x17\x3a\x54\xa3\x8d\xd6\x2a\xe7\x13\x0d\x05\xdd\x29\x1a\xd1\x23\x54\xde\x86\xa6\xe1\x13\xe8\x3f\x6d\x66\x85\x16\x15\x7b\x79\x67\x02\x0d\xc6\x51\x7d\x8c\xf4\x2d\xd7\xb1\xa8\x97\xfe\x1b\x4e\x04\x55\x3c\xe2\x6e\x29\x99\x80\xaa\x5f\x7c\xe0\x17\x9b\xf4\x95\x4f\x01\xc2\xa2\x36\x54\xe5\xe9\x73\x1e\x14\x47\x34\x7f\xa4\x3a\xa8\xb2\xcb\xd6\xd4\xb2\xdf\x93\xfa\x54\xaf\x71\xe5\x02\x8a\x6d\xa8\xc7\x1e\xf3\xc5\x0c\x0d\xe2\x4d\xca\xee\x78\x56\x78\xe9\x2a\xaf\xab\xeb\x23\x3b\x01\x1f\x45\xc1\x06\x49\x65\x08\x5d\x25\x47\x05\x0f\x21\xc6\x52\xaa\x53\x3a\xfe\x91\x8a\xa0\xf9\xbd\xaa\x26\x07\xb8\x73\xcc\xd3\xdb\xd1\xd3\xa8\xcc\x62\x17\x2c\xeb\x43\xb9\x21\xef\x6b\x25\xc0\x6b\x09\x92\xe4\xdf\x2b\x91\xe3\x71\xb0\xef\x2b\x39\x47\x38\x8d\xae\xc8\xec\x6f\x7e\x38\x67\xd1\xf6\x10\x72\xaf\x59\x01\x54\xfa\x61\x9a\x07\xf8\x7e\x02\xbd\xdc\x74\x06\x31\x42\x70\xaf\x1c\x15\xe8\xee\x88\xb3\x9c\x01\xbe\x60\x2e\x4f\x0b\x52\xd9\xa0\x72\x4e\x71\xed\xdd\x7f\xa9\x13\x41\x69\xc5\xfa\xab\x91\x59\x79\xee\xa9\x36\x2d\x0f\x1f\x91\x60\x26\x81\x62\xdd\x38\xdb\x02\xfc\xfb\x41\x35\x0a\xa0\x8e\x1e\x14\x09\xb2\x28\x8d\xb1\xfe\x4a\x0e\x58\x6b\x59\x10\xf4\xde\x89\x4b\xf9\x97\x4f\x6a\x49\x83\x01\x3a\x19\x0e\x7a\x73\x6d\x14\xec\x54\xc3\x64\x4a\x3e\xe9\x58\xa5\xbd\xfb\xcb\x62\x97\xab\xa4\x3a\xf6\xc7\x27\x46\xbb\x13\x54\x10\x50\x7d\x8f\xdd\xe7\x3a\x2a\x48\xb7\x46\xf9\x18\xbe\xf9\xed\x92\xc5\xbe\x62\xdd\x55\x23\xfe\x14\xb1\x6d\x63\x84\xca\x46\xef\x59\xb2\x18\x5f\xe9\x33\x38\x3a\x2c\x7a\x9b\xf0\x2d\xa9\xd0\xfd\x8b\x0c\x7d\x7b\xde\x6b\x43\x9f\x99\x60\x15\x5e\x34\x5d\x68\x5d\x4d\xc3\xc7\x14\x04\xd6\x56\x81\x19\x23\xaa\x3c\x47\xd4\xb0\x9a\x0b\xae\xf0\xa1\x2e\x75\xb6\x43\x9b\xa8\x13\x5d\xb1\x58\x65\x87\x42\x22\xcd\x7a\xa4\x28\xf5\xca\x5c\xe5\x14\x0e\x22\xff\x92\x69\x7f\x37\xfc\x70\xb5\xb4\xc9\x4d\x33\x14\xe6\xaa\x16\xb2\x14\x6b\xca\x4f\xc9\x41\x57\x95\x1f\xc4\x92\x45\xda\x53\xf6\xc4\x3d\x1b\xeb\xd8\x94\xe3\x1a\x13\x49\x88\x4d\x71\x1b\x55\xdb\xe7\x78\xff\xa7\x27\x16\x5c\xf7\xcb\x67\x64\x35\x86\x6c\x2d\x2c\xb8\x39\x74\x5c\xa4\x01\x66\xa2\xf7\xcf\xc7\x7a\x84\x24\x68\xb5\x1a\x8e\x76\x57\x5f\xc9\xdd\xfb\x5f"}, +{{0x49,0x7e,0x3e,0xbd,0x9e,0x4c,0xaa,0x81,0xc5,0xa8,0x97,0x3d,0x52,0xf1,0xd2,0x3f,0x60,0xc1,0x34,0xca,0x53,0xf6,0x2a,0x85,0x3a,0x0a,0xc0,0x43,0xe5,0x1c,0xb5,0x17,},{0x71,0xc0,0xca,0x7c,0xfa,0x05,0xca,0xfa,0xbb,0x14,0x3d,0x84,0xae,0x41,0xde,0x83,0x84,0x6f,0x42,0xc7,0x7c,0xaa,0x7a,0x91,0xa2,0xe3,0x48,0x39,0x7d,0x07,0xd5,0x2f,},{0x12,0x74,0x08,0x39,0xb3,0xc9,0xf1,0xba,0x87,0x98,0x96,0xdf,0xf6,0xd7,0x25,0xe8,0x4e,0x04,0x43,0xef,0x96,0xc3,0x49,0xef,0xf9,0x4d,0xc4,0x83,0x31,0x43,0xe5,0xb4,0x19,0x80,0x4d,0xa9,0xdb,0x11,0x8a,0x95,0x92,0xb1,0xb1,0xca,0x48,0xaf,0x18,0xf7,0x5b,0xef,0x1c,0xa4,0x68,0xa1,0xa5,0xc7,0x4c,0x7a,0xc8,0x13,0xbb,0x2c,0xf3,0x06,},"\xe1\x32\xf9\xd6\x7b\x17\x29\x38\x9b\x82\x8a\x9f\xae\x05\xa6\x7a\xa5\x7f\x0e\xf7\xe7\xd4\xd1\xba\x24\x4d\xec\x87\x04\xdb\x96\x95\x65\xd1\xca\xb8\x09\xe4\x8f\xc0\xab\xf9\x50\xbc\xd4\xa3\x7d\x97\xae\xac\xe6\xda\x54\x6d\x49\x14\xcb\x5b\x86\xd6\xab\x18\x1d\x83\x18\x70\xc3\x09\xbc\xa6\x16\x46\x8f\x2a\x34\xd3\xdf\xaf\xcd\xbb\x75\x80\xb0\xc5\xd9\xff\x98\xe2\xc5\x4e\xc8\x03\xbe\x0d\x3f\xda\x1d\x4b\x8c\x0d\x77\x09\xc8\x9e\x68\x0b\x00\x8b\xf9\xb8\xd9\x03\xb5\xe9\x34\xb0\x19\x70\x5f\xe0\xb0\xc8\xcf\xbc\x3c\x09\x67\x84\x3b\x0a\x1f\xa1\xb3\xf1\x62\x77\x6e\xbe\x96\xb7\x40\xed\xd6\x4a\xd7\xc3\x5b\x3f\xd1\xa0\x85\xc9\x9d\x16\xf5\x41\x67\x82\xde\x17\x35\x85\x87\x47\x0d\xd1\x3b\x51\x94\xf2\x0f\x23\x23\x2b\x2f\x70\x2f\x10\xaa\xfc\xaa\x59\xc7\x06\x6f\x24\xc4\xc4\x71\xe4\x2f\xa8\x6c\x6b\x9c\x5c\x3e\x1e\x8f\x83\x65\xf4\xdd\x75\xac\xb3\x2f\xff\xc0\x53\xc9\xaf\x41\xc6\xfd\x2e\xfa\xc3\x0e\xcf\x6a\x2d\xd0\x08\x5d\xe9\xb1\xd8\xcd\xc5\x0b\x16\x60\xa8\x66\xdf\x77\x67\x19\x8b\xd9\xc8\x73\x70\x61\x5d\x2b\xca\x99\xf7\x7b\x84\xd9\x8d\x7b\x24\xc9\xc2\x0f\xd7\x76\x8f\xd0\x38\x0d\x6b\x37\x36\x03\x40\xd1\x35\x98\x04\x78\x20\xdc\xed\x88\xa8\xd4\x2d\x57\x29\x37\xb6\xef\xa1\x69\x21\xa1\xb2\xb2\xd0\xeb\x93\x16\x73\x07\x08\x38\xe6\x11\xe6\xc0\x23\x29\x0d\x86\xfe\x90\x2f\x14\xac\x3a\xcd\x02\x9e\x33\x97\xfe\xb9\x7b\x17\x16\x62\x45\xab\x40\x7a\x76\x6d\x2e\x09\x04\x42\x4d\x33\xcd\x3d\x6e\x2e\x62\xa5\x2c\x65\xdf\x7c\xf0\x04\xd1\x41\x5c\x0b\x43\x0c\x11\x27\x62\x3d\xab\x27\x2a\x2c\x2e\x2b\x43\xe0\x2b\x48\x1b\xe9\x28\xe8\x99\x54\x27\x28\x32\xbe\x09\x8b\x50\x2b\x8b\x56\x43\xc6\x74\x82\xf5\xde\x44\x03\x03\x25\x81\xf0\x8a\xfb\x0a\xea\x48\x86\x85\x82\x60\x7b\xb3\x91\x98\xc1\xbf\x13\xa8\x69\xb6\x32\x58\xa7\x58\x90\xb6\x94\x45\xff\xd3\x45\x64\x02\x3e\x47\xf8\xb1\x88\x4a\x5e\x49\xb7\xd9\x42\x5f\x28\xd5\x15\x30\x13\xfe\x37\x55\xc6\xcb\x11\x4d\xb1\x80\xe6\x0b\x3d\xc4\xad\xb3\x6a\x21\x42\x81\x28\x00\x5a\x77\x2f\xb5\x71\x89\x34\x55\x65\xbb\xd1\x75\x98\x13\x52\x3b\xad\x62\x85\x5e\x79\x28\xee\xf5\x88\x0d\x3b\xff\xf1\xd0\xec\x65\xc2\x45\x92\x33\x5c\xda\x47\xcf\xcc\x5b\x5f\xa6\x52\xb4\x72\x63\x22\x52\x24\x84\x6a\x20\x9a\x3d\xd7\x76\x66\x61\xfc\xa4\xcc\xca\x59\xc4\x56\xfc\x9c\xc3\xe1\xcf\x80\x42\x55\xaa\x5f\x39\x7b\xab\x19\x98\x04\x33\x6b\xde\x29\xe5\x5c\x6c\x37\x7d\x58\x3f\x08\x2c\xe6\x47\x23\x73\x9e\x4f\x02\x46\x06\xf9\x06\xc1\x10\xd0\xa5\xb6\x10\xe5\xfe\xd9\x6d\xab\x5f\x08\xf4\xcb\x3c\xfc\x40\xa3\x55\x57\xe1\xa7\x40\xb8\xc7\xc0\x1f\x7d\x32\x79\xdd\x9c\x4e\x87\x64\xc9\x0b\xc1\x4f\x41\x61\xdb\x5a\x37\xf0\x98\x9b\x7b\xd8\x03\x5f\x8b\xea\x39\x4e\xa1\xd6\x00\x2c\xe9\xc3\x4f\x1e\x9c\x52\xc6\xa1\x5d\x15\xbc\x5b\x25\xc6\xc1\x5a\xb0\x0d\xfd\x6a\x5b\x1b\xc9\x17\xaf\x0b\x1b\x05\xfd\x10\xd0\x61\xb3\x68\x3d\x75\xb5\xf9\xef\xfb\x22\xae\x72\x08\x5b\xe4\xf6\x79\x7b\x58\xcb\x0c\xab\x56\x18\x44\x12\x1f\x98\xbf\xd9\x58\x3e\x0b\xcc\xb7\x0f\xad\x76\x98\x0a\x7a\x73\xb2\x3c\x70\xb3\xfd\x02\xf7\x75\x7c\x11\xa3\xc2\x1d\x19\xe0\x56\x50\xff\xb8\x2b\x9e\x0d\xf8\xa6\x73\x5d\x48\x01\x56\xf4\x79\x49\xd4\x45\x85\x1b\xae\xaa\x5e\xe2\x38\x14\xa4\x1b\x25\x23\x4f\xb9\x2c\xc0\xdf\x19\x80\xd0\x23\xd5\x1b\x5c\xf4\xc3\x11\x85\xc1\x18\xe3\xee\x3c\x0c\x0a\x46\xe0\xa2\xbe\x6f\x1d\x3a\xe4\x52\xcb\xb6\x6f\x0f\xd9\x19\x71\x34\x2d\xa7\xb1\xb9\x96\x58\x9d\x94\x09\x67\x81\x55\x21\x95\xc4\x33\xca\xf1\x9c\x37\xf9\xf1\x4f\xa0\xae\x15\xae\x0b\x02\xb9\x39\xe4\x02\x03\x4f\xf8\x18\x85\x93\x9d\x94\x4e\x60\x4f\x47\x4f\x21\x52\x43\x89\x39\x0f\xda\xda\x06\xe3\x0d\x69\x06\x8c\x88\x48\xcf\x0a\x95\x1e\xab\x25\xc4\x91\x25\x62\x94\x4f\x40\x24\x68\x18\x7a\x23\x23\x9d\x33\x63\x2f\x29\x12\x3d\x49\xb7\xde\x13\x08\x33\x98\xdb\xa9\x7d\xed\xe1\x2f\x79\x59\xb9\x52\x47\xa0\x8f\xc8\xe4\xb5\x39\x9d\x1c\x03\x5c\x08\x94\xcc\x75\xae\x98\x1c\x2d\xd4\x93\x54\x13\xbb\xeb\x68\x53\xfe\x04\x65\x5c\x77\xd1\x58\xc1\x23\x7b\x3e\x0d\xec\xa5\x63\x6d\x69\xe0\xdb\xc5\xac\xaf\x72\xb6\x0c\x10\xbb\x98\xcc\xdd\x60\x09\x8a\x03"}, +{{0x85,0xb4,0xd7,0x64,0x16,0x91,0x28,0x62,0x6f,0xd9,0xc7,0x82,0xad,0x61,0x16,0x22,0x9e,0xdd,0x77,0x63,0x1c,0x2b,0xc9,0xb8,0xee,0x54,0xb3,0x65,0x42,0xc1,0x49,0xeb,},{0x6a,0x09,0x89,0x7e,0x62,0x9b,0xb4,0x37,0x04,0xde,0xbb,0x67,0x15,0xc9,0xde,0xa5,0xd8,0x92,0xb6,0x34,0x30,0x64,0x40,0x99,0x7c,0x3c,0x9e,0x94,0xbe,0x8a,0xb5,0x47,},{0x4a,0x79,0xc4,0x42,0xa4,0xc3,0x9c,0x62,0x89,0x26,0x17,0xef,0x8e,0x80,0xb4,0x09,0x11,0xc4,0xb9,0xd3,0xff,0x0a,0x56,0x73,0xb5,0x7b,0xdb,0x84,0x54,0xad,0x73,0x67,0x69,0xdf,0x27,0xc7,0x8a,0x4b,0xf7,0xad,0x56,0x60,0x40,0xe7,0x47,0x27,0x8b,0x11,0xeb,0x65,0xcf,0x9e,0xc7,0xeb,0xa8,0x66,0x12,0x0a,0x36,0x54,0xf4,0x71,0x6e,0x00,},"\xb2\xa0\x49\x3d\x47\x1c\x33\x91\xf7\xad\xd1\xe2\xcf\x0b\xfb\x32\xab\x05\xdb\xcb\x14\xf6\xe4\xf5\xf3\x46\x3a\xa8\xd9\x95\x52\xf4\x33\x02\x20\x46\xd2\xf8\xeb\x76\x3c\x01\x71\xfc\xb1\xe7\x4a\x04\x9f\xfe\xb4\xb8\xf0\x10\x0b\x82\x10\xfc\xe8\x56\xb2\xe1\xa8\xe7\x39\xd2\xf9\x36\x73\xef\x8f\x8f\x40\x49\x8b\x30\x81\xfa\x1f\xd7\x85\x19\x8c\x6d\x37\x0e\x16\x2d\x41\xab\xe8\x31\x86\xf2\x32\x97\x83\x40\x8b\x9b\x88\x0d\x00\xf8\x1d\x53\x10\x0b\x42\xd2\x7a\x26\x1f\x20\xcd\xee\xd1\x9c\xc5\x8c\xb8\x63\x12\x81\xd8\x0d\xb1\x92\x53\x10\xe2\x35\xe4\x49\x66\x30\x9b\x87\x9b\xdf\xc2\x32\x22\x14\x33\xba\xe5\xca\xe4\x66\x90\xcb\x52\x7b\x67\x79\xe1\x1f\x1b\xd2\xa5\x6b\x59\xc5\x6e\xd4\xd9\x4f\xdf\x7a\xa8\x9d\xfa\x9b\xf2\x0d\xbf\xa6\xa4\x39\x8b\x98\x38\x45\x17\xe1\xdd\x5d\x2c\xd9\xce\x52\x4a\x47\x36\x2e\xf3\x2a\xc7\x92\x74\x2a\x12\x9c\x9e\x06\x13\x08\x76\xab\x5a\xd5\x51\x8e\xab\xc5\xe8\x0b\x02\x2d\x8f\xa1\x3e\x50\xd5\x5d\xed\x58\x95\x33\xe6\xea\x32\x24\x2c\x1b\x3f\xd7\xe6\x5f\x80\xde\xe7\x20\xb6\xd8\x7d\xcf\xf3\xe3\xdf\x04\xc8\x02\xd2\xe9\x14\xa8\x7a\x36\x29\xc9\x0b\xb6\x9e\x0a\x6f\x8b\xbb\x5e\xe5\x05\xf1\x43\xc9\x97\x73\x75\xad\xb0\x65\xc3\xe3\xd3\x91\xf9\x05\xfa\x3c\x33\x6c\x9d\xa4\x1e\x4a\x23\x20\xbc\xf4\x60\x97\x6f\xc7\xeb\x1f\xb6\xc6\xa3\xc3\x95\xdb\xd1\xd2\x8a\x1b\x09\xcd\xb9\xae\x9f\x9a\xae\xe4\xd9\xc5\x66\xa2\xac\x40\xad\xd8\x70\x47\x9f\xaf\x54\xad\x1b\x76\x97\x71\x0b\x4e\xb6\xf7\x32\x02\x44\xb5\x97\x57\xd1\xea\xc3\xd9\x22\xb7\xa7\x30\xb1\xac\xf0\xde\x9a\x45\xd4\xac\x87\x9d\x21\xfc\x61\x6e\xf3\x96\x5d\x74\x34\x5e\xd7\x07\x79\xeb\x68\x32\x80\xce\xe2\x5b\xf3\x73\x9b\xeb\x6b\x4c\xdf\xa2\x5d\x20\x2d\xa1\x3a\x4a\x67\x30\x40\xd9\x70\x48\x65\x8b\x92\x05\x47\x95\x05\xd0\xbe\xe4\x88\x0a\x73\x99\x7c\x70\x82\x5a\x6e\xc5\xfd\x9f\x95\x2e\x65\xfa\x02\x22\x54\x45\xfc\x3b\xdf\x4a\xde\xa3\xd4\xd2\x25\x51\xcb\xac\xeb\x38\x74\x79\x8d\x6a\x33\xa6\x66\x3f\xe3\x75\x70\x81\xd6\x24\x3d\xfd\x7c\xd2\xee\xbf\x60\xa3\x89\x9f\xa1\xf8\xf6\xc9\x56\xa3\xb1\x83\xf8\x9b\x9e\x7d\x2c\xa3\x64\x48\x58\x4d\x53\xaa\x8b\x44\xe6\x5a\xd3\xe5\x27\xf7\x87\x23\xfa\x6f\x59\x22\x42\x98\xdf\x31\xd5\xe8\xad\xa5\x67\xc8\xd1\xb1\x1f\x3b\x13\x14\x75\x53\x31\xc1\x73\x2d\xc5\x4a\x12\xa4\x35\x6e\xdd\xa4\x7e\x3c\x13\x0b\x32\x52\x82\xa3\x54\xbf\xe1\x5c\x30\x00\xd2\x07\x82\x29\x31\x79\x41\x87\xe0\x97\x3a\xb8\xef\x87\xbf\x89\xc3\x54\xa0\x35\xa8\x1f\x45\x91\x12\x23\x56\x3b\xfd\x99\xf9\x0a\x75\xe5\x3d\x01\x0d\x89\x29\xf4\xf8\x5a\x5a\x5a\x4f\x9f\xcc\x1c\x78\xf0\xa2\xfc\x46\x6f\x5f\x1c\x65\x22\xcf\x62\xa7\xbe\x37\x88\x07\x96\xe9\xb3\xca\x09\x11\xec\xca\x3f\x22\xc3\xb2\x4d\x5d\x9d\xaa\x68\x88\xf8\x9a\x8f\x71\xa1\x58\x59\x35\x9c\xea\x46\x8e\xf2\x38\xec\xf6\x46\x19\x27\x83\xa2\x57\xad\xda\xde\x90\x47\xe1\x3e\xdd\x8b\xcc\x1f\xd4\x17\x7c\xb2\x0f\x88\xd1\x19\x98\xd9\xc7\x26\x2d\x64\x8c\x2b\xf6\x6f\xb2\x27\xb9\xb3\xa9\xed\x46\x96\x2d\x22\x57\xa4\x20\xf6\x4b\xea\xd9\xe2\x86\x57\xb5\x21\xdb\x2e\x22\x16\x52\x87\x79\x1f\x3a\x1b\xec\x4c\x78\x22\xa6\xca\xbd\xe5\xec\x77\x01\x88\xcb\x74\x49\x8a\x4f\x08\xe5\xa3\xa7\x63\x9d\x24\x0a\xe3\xf4\xfd\x03\x53\xc0\xdd\xa8\xae\x41\x0b\x9f\xa7\xf4\x3f\xee\xd1\x3e\x9f\x13\xe6\xc9\x41\x0a\x1d\x24\xcd\xfc\x2c\x8e\x64\xa1\x5a\x12\xf7\x55\x45\xb0\xa5\x75\x71\x35\x23\xd4\xdf\xa1\xa4\x74\x27\xa8\x85\x1b\xa9\xac\xcc\xad\x78\xb4\xef\x6a\x18\x5f\x5c\x3b\x00\x11\x90\xdd\x8f\x37\x08\x8a\x00\x0a\xcc\xf4\x48\xbe\x8d\x49\x37\x1d\x9d\xa2\xe1\xcb\x5f\xfe\x07\xd4\x1a\x5c\x22\xe9\x46\x60\xac\x37\x13\x5a\xc8\x58\xcb\x17\x69\xcb\x66\xe8\x26\x9f\xd5\x33\x58\xec\xac\xf5\xdd\x92\xc7\xeb\x61\x86\xb4\xd4\xd6\x13\x0a\x73\x2d\xc1\x0b\xbb\x2b\xe3\x2f\x9b\x1d\x69\x51\x01\x4a\x63\x5c\x12\xd2\x2f\x0d\xc5\xbd\x5c\x2a\x3f\x96\xae\xc6\x2e\x77\x77\x94\x7e\xaa\x02\x28\x12\xca\xce\xd3\x3a\x5b\xef\x9f\xf8\x83\x5f\x88\x03\x67\xa3\x7b\x0b\x76\xd2\xdd\xe3\x96\xc6\x14\xe1\xa4\x72\x1e\x00\x0c\x00\xf1\x61\x93\x5b\x14\xa7\x38\xa1\xb7\x0f\x6e\xa5\x42\x55\xb7\x95\x18\x69\x64\x62\x12"}, +{{0x33,0xd4,0x77,0x60,0x2f,0x29,0x63,0x05,0xa6,0x71,0x9e,0xa6,0x94,0xc0,0x44,0xe9,0x0d,0x23,0x3c,0x2d,0xea,0x85,0xc4,0x6a,0xbe,0x19,0x20,0xe8,0x8c,0x31,0x78,0x49,},{0xff,0x6f,0xee,0xa0,0x28,0xec,0x34,0x6d,0xd4,0x91,0x07,0xbb,0x71,0x3f,0xdd,0xbb,0x28,0x2e,0xbc,0xd0,0x34,0xe2,0xea,0xfc,0x7c,0xdb,0x1c,0x5a,0xdf,0x92,0x63,0x90,},{0xca,0xa2,0x87,0x98,0x95,0xd4,0xf6,0x20,0xb9,0xeb,0x5f,0xed,0x22,0xb4,0x56,0x2e,0xeb,0x1a,0xd6,0x38,0x22,0x96,0x8f,0x76,0xad,0x91,0x07,0x6b,0x16,0x6c,0x05,0xee,0x20,0x86,0x4d,0x98,0xbb,0xbc,0x6e,0x79,0xdd,0x03,0x62,0xca,0xcf,0x7a,0x21,0xb4,0xcf,0xc2,0x30,0xd6,0x35,0x5d,0x43,0x12,0x0c,0xff,0xfb,0x94,0x8b,0x8f,0x6c,0x0e,},"\xcf\xea\x07\xa7\x79\xf1\x53\x7e\x49\x81\x23\xc6\x76\x29\x05\x73\xef\xcc\x5d\xb7\x02\x45\xd9\x3d\xea\x5c\x05\x72\x6f\x87\x13\xd0\x02\xae\x66\xc1\xc9\x69\x07\x47\xca\x92\x30\xb1\x62\x9d\x36\x62\xab\x73\xd6\x6b\x94\x98\x79\x16\x4b\x21\xa3\x5f\x40\xcf\x37\x99\x04\x19\x08\xed\x6f\x92\x29\xec\xb3\x90\xc5\xf2\x22\x34\xe1\xc5\xf2\x6b\x3a\xb5\xba\x59\xe7\x8c\x64\x96\x98\x71\xb4\x28\xb7\x85\x16\x77\x75\x55\xaf\x4e\x89\xc6\xfb\xc1\x93\xa9\x46\x95\x22\x6c\x6d\x32\x99\x91\xa1\x1b\xd5\x80\xd1\x89\x56\x08\x9b\x58\xa0\xe4\x2c\xa3\x5f\x6c\x6d\x26\x09\xad\xe0\xd0\xb6\x19\xd4\x89\x25\xc6\x8c\xd9\xd2\x25\x0d\xff\x27\xcf\x2f\x0d\x44\x44\x87\x09\xb6\x79\xf3\x5b\xbd\xce\x0f\x49\x6b\x0a\x16\xca\x67\xea\xce\xec\x25\x8b\x1a\xec\x91\x77\x5a\x3a\x2e\xe8\x01\xb1\xc9\xa2\x26\xa6\xb0\x01\x92\x6a\x05\x7a\x06\x30\x67\x27\xee\xda\xe8\xc5\x77\x53\x1d\xf0\x4a\xc0\x9b\x5b\x49\xbc\xde\xab\xde\xb8\xac\x4e\x8e\x82\xcf\x1e\x7a\xf8\x35\xfc\x61\x1c\xa7\xa6\x84\xb8\x35\x26\x04\x24\x15\xb1\xd6\x65\x2e\x86\x34\x31\x1e\x19\x46\x27\xea\xe7\x8d\x01\x1e\x6f\x40\xf6\x45\x79\x4e\x36\x89\x5a\x23\xe1\xbd\x84\x88\x3a\x39\x3e\xcf\xe5\xa2\x48\x02\x6a\xea\x86\x44\x70\x59\xf7\xa4\x29\x36\x8f\x21\xc8\x9e\x01\x45\x20\x79\x78\xb9\x13\xc8\x0a\x22\xd7\xca\xf2\x67\x3f\x7c\x76\xf6\xc2\x6c\xf8\x84\x41\x2e\x17\xd0\xc2\x55\x43\x0f\x50\x2b\xce\x74\xe3\xa3\x10\xd1\x7f\x6f\x4d\x48\x5d\xa2\x80\xed\x5b\x5e\xea\x6c\x49\xba\x74\x8d\x76\x48\x14\xb9\xe3\xda\xf6\xfc\xc2\x18\xc2\x74\x0c\xa7\x70\x18\xf7\x13\x44\x51\x9d\xa8\x2a\xda\x31\xe0\x01\x92\x4f\xc7\x76\x79\xe3\xe9\xff\x9f\xab\x67\xdd\x09\xa6\x19\x24\xc8\x21\xa1\xfd\x99\x9f\x74\xdf\xa3\xf8\x19\xad\xb3\x1d\x15\xe5\xed\x8a\xaa\x52\xc1\xbd\x7c\xca\x26\x67\x11\xa7\x4d\xd6\x21\x04\xef\x3c\x2b\xf7\x37\xfc\xe6\x94\x2b\x34\x8a\x33\xc3\xdf\xd6\xd9\x2a\x72\x4b\x6d\x58\x78\x42\x1a\xeb\x23\x0a\x53\x3f\xe2\x1c\x8b\x2f\xd3\xda\x59\x6a\x61\x80\xa4\x5c\x98\x6d\x7e\xce\x4c\xdc\x8a\xd6\x81\xea\xd6\x90\x64\xbb\xdd\xfc\x20\xf3\xc5\x21\x25\xf8\x33\x95\xbe\xd1\x55\x7f\x67\x18\x2b\x9f\xe9\x91\x38\xaf\x3c\x35\x6c\x5e\x65\x29\x78\xdd\x23\x8b\x76\x1c\x74\x2f\x81\x58\xe2\x31\x4b\x96\x42\x08\x33\x09\x78\xb0\x62\x0a\x13\xa1\x6d\x76\x1d\x52\xf0\x6e\x46\x6a\x40\x94\xb6\x5c\xd6\xf2\x68\x54\xae\xd6\xf9\xa8\xc2\xa8\x84\xa0\xd0\xbf\x4e\xe5\x87\xee\xb8\xb6\x02\x48\x72\x39\xa7\xe5\x81\x72\xc8\x09\x98\x3a\x8d\xb1\xc1\xfc\x7c\xe8\xc4\x8b\xc8\xa6\xfb\x81\x2d\x6a\xa9\xe8\x3a\x3a\xb4\xdd\xf7\xa8\xd4\x0d\x3f\xe0\x0e\xa1\x6e\x04\x06\x2b\x8a\xce\xb9\xc9\x9e\xef\xa4\x1f\x4f\x87\x44\x78\x28\x12\x6d\x0d\x9c\x9f\x86\x05\xe8\x46\x7c\x5e\x4d\x67\x1d\x5c\x6d\x9f\xa7\x0d\x74\x70\x98\xd9\x41\x21\x12\x23\xb9\xbc\xf2\x61\x93\x8d\x67\x04\xa3\x2d\x22\xc6\x1e\x30\xf3\x57\x0a\x1f\x5d\x09\x98\xb4\x79\x10\x80\x88\x2a\xa5\x62\x31\x67\xb6\x3a\x23\xf3\x40\xf0\xe7\xc6\xf9\xa8\x30\xa7\x5b\x74\x63\x1f\xa5\xb5\x7a\xfd\xb1\xe6\xbc\x22\x69\x9b\xb0\x31\x56\x67\x5d\x59\x83\x53\xa5\xd1\xb5\x58\x97\xe4\xc1\x10\x61\xdd\x14\x5f\x23\xe8\x53\x7c\x63\x2f\x75\xc1\x0d\xf0\x5b\x25\x54\x72\x38\x57\x40\x17\xfe\x7b\x64\xb8\xe9\x98\x69\x15\x7f\xee\x35\xf7\xad\x7e\x63\xe9\x95\x93\x30\x29\x29\x50\x3a\x96\x76\x80\x23\xb4\x12\x5a\xd7\x49\xdf\xf4\xb9\x92\xee\x5c\x2b\x4f\x3a\xda\x48\x89\xe4\xae\x62\xec\x15\xd2\xdb\x59\x69\xd7\x30\xdb\x30\x75\x47\xf6\x38\xc3\x18\x50\x32\xb1\x2f\x75\xfb\xb3\x17\xe4\x7d\xf7\xb9\x29\x2a\xe9\xe7\x6a\x2c\x0a\x06\xfc\xad\x10\x8c\xdd\x23\x5f\x6e\x38\xd9\x67\xb6\x37\x95\x11\xff\x69\x65\xc2\x2f\x2c\x66\x80\xa1\x2b\x03\x04\xeb\x2b\x29\x6c\x99\xa7\x6c\x27\x29\xd9\x8e\x0a\x78\x24\xb6\x7f\x3f\xe8\x42\xd6\xf6\xab\x27\x3e\x89\x48\x45\xb3\x2d\xc6\xdd\xfc\x7a\x22\x0f\x76\xbd\x96\x5c\x69\x85\x81\x83\xc8\xf3\x57\x39\x5f\xc5\x7d\xc8\x29\xde\xfa\xac\xb5\x60\x3a\x75\x78\x68\xd5\xe5\x62\xf9\x78\x1e\xe3\x9e\x0e\x94\x68\x8a\xd3\x54\x5b\x32\xdd\x73\x66\xb6\xb0\x47\xe8\xd1\xd3\xd5\x65\x99\x7b\x23\x6e\x7f\x75\x96\xc5\xf8\xd7\xc1\xc1\x1b\xcf\x4a\x24\x46\x20\xcb\xd2\x1d\x55\x9a\x7c\x9b\x3f"}, +{{0x70,0x74,0x56,0x86,0x11,0xa6,0x6d,0xfc,0xa8,0x30,0x7c,0xae,0x60,0x8b,0xb2,0x69,0x95,0x84,0x4d,0xf4,0x35,0xe5,0x30,0x0e,0x5b,0x4d,0x72,0x91,0xcc,0x22,0x90,0x7f,},{0xdd,0xab,0xdd,0xd1,0x5e,0xaf,0x83,0x11,0x5d,0xdd,0x06,0x5d,0x7e,0x22,0x0b,0x1e,0xfc,0x26,0x2a,0x61,0xc5,0x2e,0x91,0x43,0x47,0x44,0x2b,0xde,0x6d,0x00,0x25,0x06,},{0x7f,0x65,0x31,0x34,0xc0,0xb9,0x0f,0x44,0xa4,0x89,0xf0,0xb0,0x5f,0xc4,0x07,0x07,0xad,0x9f,0x13,0x98,0xf3,0x40,0xb4,0x47,0xa3,0xc9,0x86,0x1f,0x51,0x1c,0x9f,0x15,0x68,0x80,0x3b,0x76,0x84,0xa0,0x4a,0x89,0x8c,0x45,0x15,0x4d,0xd4,0x86,0xbd,0x50,0x75,0x89,0x98,0xe1,0x26,0x43,0x93,0x78,0xb3,0xf5,0x9f,0xf3,0x67,0x49,0x2a,0x0a,},"\x6c\x13\x74\x23\xea\xc7\x90\xb8\xe8\xe4\x18\xb2\x90\xe0\x57\x9c\x7b\x86\xb1\x4a\xed\x81\x8d\xe8\xce\x53\xce\xa3\xf3\x40\xa1\xa9\x53\x91\xf9\x84\x96\x8f\x2b\x42\x29\x28\x2a\x81\x61\xc0\x9a\xb1\x49\xcd\xac\xd6\x69\x70\xb4\x01\x3f\x52\xe5\xe6\x8e\xa8\xc9\xdb\x68\x5b\x2c\x53\x07\x35\x00\xe5\xb3\x5e\x29\xea\x0b\xa1\xf4\xd1\x59\xa5\x58\xd3\x61\xb0\x65\x16\x83\x6c\xf7\xb9\xea\x50\x1f\xa0\x50\x6b\x98\x5f\x03\x6a\x82\xd9\xe0\x84\x48\x9d\x3b\xfe\xd3\x40\x93\xe2\xd6\xd9\xed\xf5\x57\x85\xed\x35\xa9\x0c\xe5\x6c\x76\x16\x86\xcc\x3e\xa1\xa2\xc7\x6a\xda\x5e\xc8\xc1\x45\xd8\x18\xb0\x47\xcc\x51\x6e\xec\x5d\x2d\x6a\x93\xa5\x55\x92\xd8\x92\xe3\xd5\xcd\x10\xc2\x50\xc0\x4b\x04\x9b\x38\xfc\x7e\xc0\xf3\x9a\xba\x15\x82\x40\x07\x33\x6c\x2b\x0f\x7f\x81\xd6\x4d\x5c\xa3\xe2\x9d\x6f\xda\x4c\x23\xd9\xba\x65\xd9\xfe\x3c\xb4\xe0\x39\x13\x69\x72\x87\xb4\x6a\x0b\x1f\xcc\xd2\x62\x4e\x39\x7a\xe9\x5c\x52\x54\xbc\xd8\x8d\x2c\x7c\x8f\x70\xfd\xc8\x17\x3f\x64\xc1\xde\x32\x28\x1a\xb4\x18\x46\x93\xb4\x8a\x34\x9e\x67\x82\xbc\x89\x92\xb4\x3c\x7d\xe7\xcb\x9d\x33\x92\x9b\xf9\x53\x06\xc2\xaf\x7e\x93\x8d\x84\x86\xb3\x86\xf9\xfd\x3f\x0f\x71\x61\xe0\xe6\x86\x2d\x4f\x92\x81\x44\x68\x65\xa1\xc9\xbe\x24\x60\xef\xbc\x20\x15\x1b\x06\xe7\x9d\x01\x46\x17\xd0\x30\x0e\x67\x1d\x48\x76\x74\x58\x59\x66\x25\xb7\x6d\xff\xc5\x58\xaa\x9b\x40\x61\x21\x96\xec\x82\x7e\x1c\x6f\xff\x51\x8f\xb7\xad\x4b\xf8\xc4\x6f\xcb\x27\x88\x85\xaa\x49\x1b\x77\xa2\x89\x95\xcf\xb9\xd7\x96\x40\xaa\xd1\x74\xc6\xdf\x43\x93\x8e\x3f\x13\x85\x20\x5c\x54\x59\x5b\x33\xde\xde\x50\x14\x37\x46\xa1\x70\x5e\x7e\x0b\x69\xaf\x4a\x26\xc3\xb7\x65\x15\x05\x18\x92\xb1\x5c\xa6\xe4\x8c\x3d\x91\xfb\xc7\x5e\x8f\xe4\xa0\xfe\x8e\xd2\xc2\x6c\x10\x73\xbe\xb7\x0e\xa3\x8d\x09\x27\x02\x92\x78\x40\x67\x55\xae\x6e\x11\xda\x37\x86\x53\x64\x95\x15\xe0\x08\x5b\x5e\xa7\xdb\x32\x49\x20\x8e\x33\xa6\xc8\xb6\xae\x8c\xd8\x0c\x9b\xd6\xb9\x83\xe7\x3e\x9b\x91\xdb\xec\x09\x1f\xae\x99\x5f\x80\x32\x42\x7e\xde\xc0\x2c\xad\x90\x55\xeb\x8b\x7d\xbc\xfa\x80\xd4\xf6\x4f\x57\x27\xa1\x52\xf1\x1c\x47\xe5\x2d\x75\x3a\x57\xb6\xe5\xfd\xdf\x77\x4c\xea\x4d\xa9\x10\x02\x68\x19\xc4\x1e\x32\xb4\xf1\x99\x72\x7e\x23\xc5\x4a\xb5\xd7\x01\x42\xb8\x54\xa2\x7b\x04\xe6\x4c\xf4\x4a\xf2\xa8\x99\x5e\x12\x00\xbd\x11\x7c\x7a\x16\x74\xed\xef\x59\xbc\x53\xf7\x3a\xda\xf6\x38\xe0\x77\x3b\x85\xb5\x63\x34\xaf\xf6\xe1\x17\x43\xe3\xa3\xd3\x61\x4a\xa8\xa3\x75\xb3\x78\x1e\xc8\x14\xcc\x08\xe7\x1e\xfa\x78\x18\x51\x9c\xb2\x4a\xf8\x2c\x33\x1d\xfd\x6a\xc7\x8e\xc1\x7f\xd7\x17\x4b\x61\x02\x1e\x8c\xf9\x01\xa2\xaa\xa6\xad\xbc\x90\x2a\x91\x6b\x2a\x2f\x4f\x79\xe5\x51\x50\x1f\xbf\x01\xdf\x6b\x85\x18\x50\x4c\x1e\x94\x64\x69\x38\xbe\xd1\xa8\x50\x9c\x2a\x38\xfb\x6a\x79\x8a\x78\x58\xf4\x09\xb0\xf2\xfb\x9b\x3f\x48\x17\xe5\x68\xc5\x2d\x9a\xbf\xe2\x16\x8c\xc3\x65\x0f\xc4\x3e\x0f\x99\x75\xfe\x29\xe3\x3a\xed\x1a\x7b\xf3\x0d\x86\x31\x15\x07\x90\x65\x0a\x3c\xb7\x8c\x36\x8f\x1a\xea\x9a\xc6\x0c\x5e\xeb\x96\x9a\x45\xf8\x4a\xa3\x73\x66\xa8\x39\x77\x19\x0f\x41\xae\x42\x1e\x0c\x46\xfd\xa3\xfa\x01\xb9\x26\xfc\xef\x82\x24\xfd\xa3\x6d\xf4\xf8\xa8\x77\x01\xfe\x79\xfe\x06\x28\xef\x0c\xc0\x2d\xf2\xbd\x78\x32\x07\xc7\xdb\x87\x11\x9a\x03\x69\xfe\x16\xee\xb3\x8f\xdc\x9f\xb3\x5d\x9e\x19\x5f\xe1\x4f\x8c\x10\x38\x20\x8a\xb9\x77\x00\xaf\x79\xf2\xe2\xe0\x54\x96\x83\x02\x07\xc7\xda\x8d\xbe\x8e\x9b\xb7\x3b\xc4\x71\xa4\x3f\x1b\xe6\x50\xfa\x92\x81\x9a\xeb\x5d\xc7\xee\xd7\xee\xd8\x17\x12\x70\xd2\x19\x25\x7d\x19\x61\x0b\x89\xd2\xd6\x2d\x3f\x5b\x64\x8e\x13\x9e\xed\xf1\xff\x74\xbe\x01\xa5\xef\x1d\x95\xf8\x12\x92\x26\x01\xee\x92\x51\x51\x57\xc4\xec\xad\xfa\x3e\xef\x9f\x2a\x67\x7c\x00\x3c\xa4\xab\x9b\x2c\x45\x47\x2c\xe5\x5e\x18\xf4\x0a\x21\xfe\x1b\x0d\x45\xb5\x0b\x50\xc5\x2a\x0b\x1a\x5d\x7c\x37\xd8\xeb\xc1\x5e\x02\x05\x84\xd9\xed\xd7\xb5\x65\x05\xf8\x20\x78\xe0\xf8\x99\x38\x91\x35\x01\x4c\x86\xd1\xe2\xed\x49\xf9\xcd\x31\x90\x76\x94\x35\x53\xa3\x12\xae\x05\xab\x33\x35\x26\xe1\x36\x71\x4f\x09\xa4\x02\xb3\xc8"}, +{{0x7d,0x7c,0xa8,0xe8,0xd3,0xb8,0x43,0x44,0xa5,0xe4,0xde,0xa0,0x8b,0x33,0x8d,0x8f,0xaa,0x5f,0xfc,0x11,0x9c,0xe5,0x66,0xef,0x65,0x6f,0x0f,0x45,0x84,0x77,0x5b,0x21,},{0x0b,0xde,0x34,0xb7,0x46,0xd2,0xc5,0x49,0x08,0x53,0x06,0x4d,0x48,0xc6,0xb4,0xc1,0xcb,0xbc,0x3e,0xe7,0xbe,0xff,0x5e,0x8f,0x68,0x4c,0x12,0x0f,0x31,0x5d,0x7e,0x4e,},{0xd0,0xc3,0xe2,0x48,0xa8,0xcb,0x2d,0xdc,0x7e,0x9f,0x21,0xc9,0xc5,0xb0,0x09,0xf7,0x0e,0xa2,0x9d,0xa6,0x89,0x7c,0xd9,0x2c,0x26,0x0f,0x04,0x7e,0xd6,0x8a,0xa1,0xc8,0xb9,0x65,0x7f,0x9d,0x82,0x6e,0x88,0xf4,0xa5,0x12,0xc5,0x00,0x3b,0xe6,0x40,0x68,0x80,0x74,0x12,0x63,0xae,0x7c,0xe6,0x86,0x0e,0xfe,0x73,0xad,0x54,0xd4,0x82,0x04,},"\x0b\x72\x70\x75\x34\x5d\x61\x9f\x5c\xdc\x7f\xc4\xc4\x3c\xdc\x19\x10\x58\x11\xd9\x5d\x06\x9f\x81\xc0\xa6\x2f\xe1\xe1\x17\x8c\xf1\xc3\x5d\xb0\x5e\x2d\xe8\x7d\x11\xae\x1a\x6f\x53\xef\x38\xb3\x9b\xf4\xed\x8f\xbf\x56\xef\x01\x7a\x1d\x3c\x15\xb6\x4f\xe4\xb2\x61\x0b\xf6\x9b\xd1\x9a\xc7\xaf\xd4\x6a\x2b\x87\xb4\x88\xb6\xc7\x8a\xd4\x56\x81\x1c\x1d\xd6\xbd\x4a\x6b\x5d\xa6\x98\x73\x9f\xd1\xa1\x4c\xeb\x9f\x27\xf1\x24\xb6\x9f\x6b\xd1\x6d\xe5\x53\x7a\xad\x80\x68\x1c\x56\x33\x58\x03\x94\xda\x3b\x84\xe9\xb7\xa5\x5e\xba\xb8\x52\x2d\x2d\x6b\xf1\xaa\x4e\x7b\x15\x9c\xbf\x4e\x20\xb5\x0b\xfe\x9c\x71\x1a\xa0\x47\x11\x9f\x1d\xad\x87\x49\x26\x0b\x87\x63\x9e\x9c\x14\x1d\xef\x62\x02\x6a\x99\x03\x73\xdc\xfd\x99\xf7\x7b\x0f\x5e\xa6\xad\xfd\x8f\x59\x4b\x9c\xe4\x10\x64\xa5\xed\x30\x7b\xf2\xd8\xd1\x73\x70\x49\x8a\xd7\xf4\x5f\x9c\x4d\xd2\x6c\x42\x0f\x45\x0f\x53\x62\x3b\xb6\xd7\xf3\xf4\x6a\x14\x9d\x8f\x13\x5b\xc2\x91\x33\x10\xfb\x8f\x90\x43\xd0\x99\x27\x8b\xbe\xba\x39\x17\x9f\xa3\x67\xb0\x16\x73\xe1\xc9\x53\xef\xfd\x2c\xae\xa7\x31\x1c\x47\xc0\x37\x27\x44\x09\x5b\x1c\x8f\x90\xee\xf5\xf1\x92\x9d\xb1\x99\x6c\xd5\x84\xf6\x15\xd5\x6f\xae\x3a\xec\xac\x3e\xe8\x8b\xd0\xb2\x96\xf4\x49\xcc\x27\x13\xc5\x2d\xa6\x95\x24\x8f\xaa\x8e\x38\x9b\x05\xa0\xbc\xac\x69\xdc\xe9\x71\x97\x23\x19\x4f\x43\x3b\x02\x97\xeb\x08\x59\x01\x9f\x14\x1a\x20\x7c\xe8\xcc\xb5\x98\x82\xca\xa6\xe1\x8f\x0b\x43\xbd\xdd\xb9\x0a\x0a\x85\xff\xd5\x77\xd6\x39\x4a\x1d\x80\x48\x94\x10\xf9\x2a\xfb\x85\xba\x50\x6a\xa9\xf3\xf4\x27\x44\x5d\x21\x22\x4b\x9c\xb0\x46\xc0\x5f\x1b\xac\xd7\xb7\x49\xfb\x7b\x10\x24\xd0\x92\xe4\xee\x4b\x30\xa4\x6e\xdf\x71\x84\x70\xc9\x94\x91\xc6\x8f\x48\x79\xd6\x2b\xfc\xe7\x04\x6d\x81\x38\xcb\xb9\xe7\x21\x29\x99\xa4\x49\x8b\x45\x5f\xc9\x0a\xc2\x83\xe9\x35\xde\x04\xdf\x6f\xc9\x99\xe4\x43\x4b\xe1\x10\x63\xd6\xe4\xee\x9e\x09\x6a\x87\xbc\x71\x6d\x2c\x81\x99\x16\xc3\x7a\x4e\x62\x98\xc4\x99\x45\x36\x6e\xc3\xf5\x00\x72\x0b\x06\xdc\x99\xd3\xd8\xac\x30\x3e\x6c\x26\x4e\x28\xa7\xc2\xd4\x19\xec\x62\x2a\x97\xa7\x11\x54\x4f\xb1\xf4\x73\x5b\x11\xf8\xbb\x1d\x7e\x2c\x81\x6a\x15\x62\x87\xb4\xcc\x0c\x65\xaa\xa2\x80\xb8\x37\x73\x7f\x0a\x84\xe3\x6d\xe2\xdf\x2f\xc3\xa5\x0d\xf9\x80\x91\x8f\xb9\xe5\x83\x4b\x42\xac\x0e\x0c\x72\x78\xd7\xfe\x8d\xb4\xdb\xde\xca\x01\x41\xd5\xfe\xf5\xdc\x61\x51\xf8\x7b\x86\x34\xc2\x41\xa8\xfa\x0a\x82\x71\x78\x99\x77\x3a\xe8\x9f\x53\x78\x90\xb9\x15\x5a\x7a\x05\xbc\xe4\x78\x66\xec\x20\x28\xa4\x78\x98\xd4\x85\x82\x3a\x2e\x99\x23\x19\x68\x0e\xb6\x99\xb0\xdd\x53\x58\xf5\x46\xfc\x53\x7c\x73\xd3\xa4\xb2\x23\xa0\x94\x15\x18\xb6\xd1\xe6\x6b\x27\x67\x6c\x1b\x1f\xc7\x6a\x08\x32\x05\x24\xa7\x2e\x29\x7f\xce\x17\xaa\x80\xd8\xea\x7b\x38\x8a\x55\x16\x8e\x7d\xad\xb8\x36\xe9\xde\xe7\x07\xed\x25\xc0\xee\x4d\xb2\x5b\xee\x3c\x48\x5b\x39\x64\x92\x04\xef\xaf\x28\x20\xb2\x73\x63\x68\xfc\x77\x3c\xe0\x90\xc3\x85\x37\x80\x02\xc4\x71\xb0\x94\x79\x5c\xb2\x66\xd3\x9e\xb7\x58\x0d\x70\x1b\xe4\xc8\x91\x6f\x6b\x38\xbf\xe2\x5f\xdf\x36\xd6\xc4\xad\xaf\xa9\xae\x98\x64\xc5\x7b\xb7\x37\xb4\x95\x06\xed\x38\xd6\x2d\xe6\x0c\xc0\x59\x9e\xc6\xbb\x1a\xcf\x24\xb1\xd3\x7d\x60\xef\xde\xb7\xd9\x42\xc5\x36\x03\xa2\xf0\x47\x6e\x95\x12\xc9\x38\xb2\x8d\x49\x5a\x6f\x26\xa9\x07\xc3\x96\xb8\x41\xae\xdd\x8e\x14\xac\x44\x7b\x49\x5d\xf1\xf6\x76\xda\xcc\xd5\xa7\x40\xc0\x42\xf5\x77\x2b\x7d\xb1\x7f\x4f\x1a\x3a\x1c\x8e\x7c\x48\x83\x70\xe7\x36\xb5\x1e\x69\x0f\xd2\xdd\xcb\x5a\xa6\x19\x57\xa7\xc7\x97\x5a\xcb\x2d\xcb\x91\x5d\x07\x4d\x74\x42\x79\xea\x1c\x41\x69\xf8\x68\x87\x3a\xc5\xc2\x08\x90\x16\x2c\x1d\xf9\x65\x64\x19\x97\x5a\x43\xd3\x19\x8e\x18\xc3\x09\xa1\xeb\x7c\x1d\x87\x87\x3f\xb1\x5c\x6d\xa4\x7f\x54\x8a\x01\xf6\x9b\xda\xb9\xc3\x9e\xf0\x0d\x41\x8a\x6f\x61\x9d\xd7\x3d\x7d\xb4\x5c\xbb\x6a\xd2\x25\xa2\xde\x78\x7b\xa7\x77\xbc\x73\xd2\x8f\xc3\x04\xf1\x00\x09\xf4\x02\x2c\x2c\xf8\x4d\xe0\x08\xd7\x0f\xcd\xc8\xba\x7f\x10\x7c\x36\x98\x59\xe9\xc9\x0c\xa8\xa3\x93\xb5\x53\xf2\x66\x05\xff\xd7\x23\x0c\x92\x14\x90\x70\x0f"}, +{{0xd2,0x1f,0xdd,0x7b,0x10,0xe5,0x4a,0x8b,0x6b,0xe9,0x5a,0x02,0x24,0xad,0x70,0x66,0x4d,0xd9,0x21,0x12,0xe2,0x68,0x3a,0x4f,0xd2,0x79,0xc4,0x07,0xdb,0x38,0x71,0xbb,},{0xf8,0x9c,0x27,0x2e,0x7d,0x1c,0xc9,0x3d,0x69,0xf6,0x94,0xde,0xc9,0xcc,0xe0,0x5a,0xc2,0x47,0x73,0x45,0x04,0x82,0x9c,0x56,0x99,0x74,0x13,0xc8,0x95,0x8b,0x93,0x30,},{0x6d,0x69,0xe8,0x3b,0x3e,0x7e,0xd5,0x5a,0x85,0xf9,0xfc,0x9d,0x25,0x19,0xda,0x0b,0x0a,0x1e,0xb4,0xda,0xae,0xe9,0x91,0xa6,0x65,0x1f,0x5c,0x89,0x19,0x0c,0x0d,0xe7,0x23,0x73,0xcd,0x98,0x9d,0x46,0xbe,0x13,0x67,0xf9,0xda,0xf1,0xb9,0x2f,0xed,0x3b,0x52,0xbb,0xa5,0x4a,0x1e,0x4c,0xca,0x5b,0xc8,0x72,0x6e,0xd0,0x7f,0x30,0x25,0x01,},"\xb8\x64\x4a\xdb\xef\x9c\x7c\xab\x91\x20\xac\xed\xc8\xe7\x5c\x43\x3d\x03\x6f\xfa\xe0\xf9\x55\xbe\x6a\x48\x8f\x1f\x42\x7a\x68\xa8\x90\x2d\x02\x6e\x63\xdd\x6c\x9b\xf9\xd9\x7d\xe7\x86\xb3\x1d\xd4\xf4\xc9\xa4\xf8\xa6\x22\xf1\xff\xc8\x4d\xa6\x96\x7c\xa7\x74\x33\xc3\x98\xf4\xd3\xf1\xc4\x43\x49\x89\xb7\xac\x9d\x0f\x3b\x1b\xe0\xc8\xb3\x52\x82\x4f\x4e\x7a\x08\x3f\x34\x2e\xc1\xbe\x1d\xa8\xfb\x75\x52\x42\xa6\x54\x88\x0e\xf2\x98\xf0\x59\x79\xff\x02\x6d\xdc\xc0\x44\x86\x0e\x67\x57\xa2\x9c\xfa\xa2\x22\xa3\x59\x7e\x38\xf1\x77\x99\x62\xa4\x1a\x4c\x8c\xe6\xa6\x5b\x87\x81\x99\xb4\xd8\x0f\x4a\x03\x90\xca\xc1\x9c\x22\x6e\xea\x4b\x60\x36\xe5\x7a\xd8\x30\xec\xfc\x00\x69\x3e\x26\x13\xd3\xed\xf4\x65\xfc\x8c\x4f\xa2\x93\xfd\x8c\xfc\x36\xdc\x8e\x37\xbc\xeb\xab\xec\x03\x49\xeb\xd8\x84\xe1\xb2\x8b\xce\x82\x4e\x0d\x55\xb6\xd0\x15\x38\x38\x01\x66\x8b\x34\xf5\xba\x72\x3d\x2a\xc0\xa2\x64\xfa\xb2\xc7\x28\x60\x8f\x16\x2d\xe0\x11\x79\x25\x9b\xe2\xcc\xb0\x81\x50\x02\xfd\xed\x8e\x0d\x78\xb0\x28\x07\x31\x3e\x91\x0e\xb3\xa7\x33\x7c\x53\x4e\x84\x6f\x9e\xe1\x55\x42\x6e\x4a\xef\x64\x36\x61\xb0\xed\xb4\x45\x96\xfd\xdc\xd0\xb3\xe8\x14\xc1\x37\x81\x7a\x42\x2b\xaa\x40\xc9\x05\x3d\x03\x86\xc6\xec\xdb\x58\x90\x52\x59\x47\x42\x67\x7c\x48\xdc\xfc\x8c\xd4\xa9\x36\x67\xed\x4d\x87\x64\x60\x01\xed\xa0\x79\xe8\xb9\x9d\x52\xba\x21\xc5\xec\x56\x69\xfe\xdf\x6f\x40\x44\x7a\x7f\xf8\x90\x1d\xb0\xef\x18\x47\xd3\xca\xcf\x01\x98\xa2\xf3\xbd\x7b\xcf\x2d\xd8\x11\xa0\x97\xfc\x5e\x51\x88\xb0\x3f\xdf\x54\xe5\x17\x63\x7a\x14\x50\x10\x00\xd0\xd3\x55\x16\xca\xf0\x69\x94\x02\xb4\x8f\x8d\x8c\xc3\xaf\xb1\x7a\x56\x13\x2d\x08\x23\x70\x35\xa0\xc9\x54\x90\xbf\xe5\xd7\xb7\xfb\x40\x17\x8f\x28\x1e\x4d\x87\x2e\x47\xa0\xe9\x55\xce\x97\x36\xf3\xc3\x33\xa6\xad\xf5\x0a\xd3\x19\x94\xeb\x9f\x45\x32\x7f\xac\xc8\xc5\xd1\x13\xfa\xd4\x71\x3f\xe7\xf1\x98\x01\x0d\x42\x04\x6b\xbf\xe6\x8b\x0d\xaa\x79\xdc\xb8\x75\x59\x29\xbe\x92\xf9\xca\xa1\x50\xdf\xbd\xe3\xfc\x9e\x39\x2b\x2b\x70\x1c\x30\x21\xc2\x40\xe4\x67\x9d\xe4\x11\x24\xb1\x88\x8e\x5d\xb5\xa8\x3d\x05\xce\xaf\x49\xeb\x44\x0d\xc4\x50\x26\xd4\x50\xbc\x98\x4b\x8d\x6f\x02\x85\x0e\xcb\x57\x0e\xee\x0a\x38\x19\xb1\x2b\xc2\x63\x67\xb5\xb9\x8e\x1b\x14\x1c\x9b\x0a\x96\x90\xea\x4a\x37\x00\xda\xd1\x23\x95\xf9\x75\xd1\x1c\xd7\x7f\x96\x36\x88\x31\xf2\x1f\x4e\x96\x8c\xc5\xba\x9e\xf8\x24\x74\x03\x8b\xc7\xaa\x26\x12\x2d\x21\x8b\x74\x30\x41\x50\x6a\xeb\xbd\x1f\x98\x79\x59\xfd\x16\x0d\x6e\xb7\xd5\x8d\x4f\x57\x6f\x8c\x0c\xa8\xaf\x86\x8e\x39\xb5\xea\x87\x20\x39\x37\xe0\x30\x8a\xcb\xea\xe9\x1e\x10\x60\x7e\x44\xe8\xab\x49\x5b\xc0\x1d\xd5\x73\xfb\xad\xc9\x44\x79\xff\x92\x08\x2c\x7b\xb7\x51\x34\x79\xc7\x0f\x04\x07\x76\x90\x25\xd3\x4d\x72\x14\x0c\x25\xd8\x21\xf0\x34\xa3\x98\x51\xa9\x3c\x62\x3b\x71\xc9\x40\x0e\x94\x26\x39\xf2\x8b\xbd\x03\x2e\x1d\x8d\x3c\x05\x9f\x7c\x2c\xd3\x1d\x74\x76\x46\x2d\x27\x76\x03\x5d\x07\x88\x02\x02\xdb\xfe\x9e\x07\xd1\x54\x62\x2d\x7a\xc6\x17\x5a\x5a\xfa\x79\xfe\xd4\xdc\xc1\x37\x12\x62\x0c\x41\x99\x4e\x11\xd9\x24\x30\x8f\xb2\xff\x3a\x1e\xda\x44\xc7\x61\xbc\x73\x6f\x34\x51\x22\xf0\x2a\x40\xae\x6f\x7d\xbd\x03\xd9\xfe\x96\xee\x3d\x7a\x3b\x4a\x5e\xef\xbf\xcc\x56\xdc\x42\xef\x27\xbd\x80\x85\x17\x60\x38\xb9\xeb\xae\x63\xaa\x75\x03\x52\x75\xec\x34\xe4\x18\x57\x39\xd6\x36\x24\x67\x70\xac\xcc\xc6\xdc\x62\x0e\x2f\xc9\x15\x6f\xa9\x48\x3e\x0d\x9c\xae\x0e\x8c\x46\x39\x48\xa3\xd9\x7a\xe8\xdd\xa5\x96\x6c\x88\xf0\x70\x93\x29\x2c\xce\x22\xbb\xda\x06\x2b\xaa\xfa\x7f\xe8\x4d\x0b\xa2\xd2\xdd\x29\x5b\x23\x45\x8b\xca\xeb\x2e\xf7\x42\xa2\xed\x1c\x83\x44\x83\xcd\x70\x93\x85\xaf\xea\xdc\xbc\x0a\x9c\x6a\x4f\x38\x7b\xab\xf7\xe3\xdc\x36\xc8\x10\xdb\x20\x9b\xeb\x66\xc8\x66\x64\x04\xc6\x61\xdf\xe9\xd3\x2c\x4c\x08\xaf\xc6\xf3\xb1\x25\x7d\x64\x84\xa7\x55\xf5\xac\x70\x1e\xb1\x3f\x87\x76\x3f\xee\x33\x0f\xfa\x04\x22\xcd\x80\xa9\x20\x38\xc6\xf4\x52\x92\xbd\xee\x5f\x89\xe9\x4c\x7a\x65\x21\x97\xfc\x19\x06\xb4\x82\x58\x37\x24\x49\xb1\x08\x1c\x6b\x97\x13\x4c\x43\xc8\x9e\xe2"}, +{{0xd3,0x36,0xfd,0x84,0x08,0x19,0x6d,0x22,0xfb,0x69,0x8e,0xb2,0x5b,0x76,0x54,0xfd,0xa4,0x6f,0x5d,0xe4,0xc9,0xb4,0xd0,0x49,0x50,0xc3,0x98,0xb5,0x9a,0x44,0x29,0x0a,},{0xf3,0xcd,0x96,0x34,0x7c,0xea,0x63,0xe5,0x00,0xa4,0xc9,0x2c,0x3b,0xf2,0x15,0x66,0x2d,0xd0,0x40,0x07,0x84,0xdb,0xf8,0xb5,0x95,0xdd,0x3d,0x39,0x5f,0x90,0xcc,0x12,},{0xaf,0x7e,0x2d,0xf7,0x52,0x9f,0xd1,0x8d,0x1b,0x21,0xb8,0xfd,0x4c,0x06,0x81,0x50,0x59,0x18,0xe2,0x51,0x14,0x34,0xfe,0x4e,0x49,0x54,0xe7,0x43,0xc1,0xcf,0xa4,0x5e,0x41,0x09,0xd3,0x6c,0x3e,0xec,0xf2,0xe2,0x5d,0x20,0x9b,0x9b,0x5d,0x25,0xf7,0xcb,0xc3,0x80,0x29,0x6d,0x64,0x77,0x52,0xe3,0x0d,0x3b,0xea,0x3b,0x92,0x9b,0x09,0x03,},"\xfb\x49\xc1\x9b\xc4\x44\x4c\x28\xeb\x26\x25\xf3\x1d\x99\x6d\x5e\x36\xc5\x7f\xa6\xfd\xd7\x72\xe6\x7b\x71\x99\xce\xc6\x7e\xda\x54\x51\x71\x2d\xf7\xa6\x9d\xbb\xd5\x6e\x7c\x39\x87\x96\xb2\x00\x1d\xef\x65\x1c\x4b\x9c\x05\xee\x31\xd9\x56\x79\x53\x5c\x81\x2a\x37\xd3\x1d\xdb\x30\x73\x19\x9c\xd7\x04\xff\x7c\xa2\x98\x1f\x7b\x9c\x92\x7a\x7f\x7d\x77\x6f\xb6\xf6\x09\xf7\x27\xe6\xea\x70\x9c\xe7\xf4\x3a\x60\x79\x35\x04\x16\x9a\x89\x05\xd9\xb2\x31\x09\xf0\xd8\x67\x96\x6a\xa3\xe3\x00\xc7\xe1\x1d\xde\xdb\x9c\xc1\x17\xb9\x04\xf6\x29\x27\xe4\x8e\x4d\x73\xfe\x1a\x6c\xec\xcc\x4c\xeb\x08\xe6\x4a\xb5\x5f\x25\xc9\x82\x16\xce\xc9\x37\x60\x8a\xd7\x93\x14\x69\x98\xf1\x4c\x29\x85\xe6\xc2\x91\x0d\xf7\xb1\x38\x8f\x9d\xd8\x63\xf1\xe4\xd7\xd1\x62\x14\x79\xb8\x51\x2c\xdb\x34\xe6\x73\xeb\x02\xa4\x89\x34\xe3\x9c\x2d\x18\xd7\x0f\x96\x6d\x67\x6a\x2b\xd7\x5d\xb5\x43\xd2\x5c\x5d\xcd\xc3\xef\x3b\x8b\xc8\x20\x18\x48\xc3\x09\x61\xe9\x15\xd9\x68\xbd\xc3\x19\x46\xb0\xd1\x8e\xde\x7c\xb0\x16\x6d\xbe\x1f\xfe\xff\x94\x39\xc9\xc3\x40\x4a\xf6\x01\x6c\x73\xed\xeb\x25\x3d\x93\xf5\x62\xa1\xa6\xcd\xd5\x78\x98\xa9\xb3\x42\x25\x87\xd5\xf5\x6a\xf3\xd0\x6b\x3f\x6c\x25\x75\x1f\x44\x46\x0f\xb3\x29\x96\x56\xdc\x11\x22\x7e\xf4\x83\x7a\xab\xdd\xee\x40\x0f\xa5\x3f\x69\xe5\xce\xd0\x53\xc7\x6d\xce\xcd\xf0\xad\xc9\xef\x80\xf4\xb3\x30\x54\x2f\xf1\xfa\x2d\xf0\xb8\xd4\x3c\xd1\xc3\x11\xb1\xb9\x95\x5c\x63\x2c\x8e\x5f\x04\x91\x93\x1c\x04\xde\x43\x4d\xf8\xf7\xa3\x94\xe5\xfe\xf0\x16\xdb\x2e\xb7\xc8\x7b\x2a\xc7\xa4\xa7\x30\x43\xbd\x7f\x98\xad\x0a\x4d\x45\x3a\xbf\xb0\xbe\x8b\xe4\xcb\x14\x57\x42\xaa\x56\xaa\x5e\xf2\xdf\xf1\x22\x30\xa5\x10\xe3\xb7\xf8\x2f\x78\x47\x70\x0e\xee\xa5\x90\x5b\x02\x89\x69\x6c\x4c\x14\x2b\xf3\x4b\xcf\x81\xa9\x62\xd7\x5b\x8d\x09\x10\x55\x73\x37\x79\x33\x5b\x7f\xd4\x7a\x20\xd1\x7c\x94\x8a\xb7\x32\x94\x78\x32\x67\x43\x71\xe2\x2e\x71\x11\x34\xf5\xc9\x19\x79\x23\x57\xf7\x9b\xf7\x0c\x44\x70\x78\x75\x28\x43\x4f\xc0\xb4\xca\x09\x3e\xe9\x25\x43\x42\x0d\x1c\xa8\x11\x24\xf5\x58\x53\x17\xe2\x50\x82\x1a\x4f\x3d\x8c\xe0\xf9\x19\xde\x9f\xbf\x01\x27\x08\x7e\x67\x69\x03\xf6\xcb\x39\x02\x5b\xcc\x73\xa0\x76\x29\x54\xb7\x2e\x66\xa6\xbe\x9b\x96\xc9\x7b\x6f\x60\x30\xbf\x5c\xa0\xbc\x27\x27\xa9\xa1\x79\xcf\x9d\x94\x05\xf3\xfe\x18\xf3\x49\x23\x89\x07\x9a\x5b\x65\xbc\xb1\x3a\x0d\x5e\xf4\x1c\x2c\xd9\x7e\x70\x2c\xee\x4a\x2f\xeb\x1e\x67\x02\xbd\x4c\x63\xfe\x0a\x4a\xe9\x94\xc4\x28\x7a\x83\x7b\xc3\xf6\x4c\x2d\x89\x88\x57\xcd\xb3\x2a\xcd\x4b\xd1\x33\x67\x6e\x51\xf7\x7b\xc7\x11\x0e\x3c\xe5\x2d\x92\x04\xfd\x26\x91\xa6\xd3\x70\x78\xf6\x8e\x7b\xce\xf3\x0f\xc9\xc4\x83\x98\x58\x22\xb6\x61\x11\x92\x38\xe4\x0f\x9c\xfd\xca\xbe\xf2\xd7\xb1\x6b\x05\x9a\xb2\x4a\xdc\x05\x00\x37\x12\xbb\xb1\x28\x09\x6e\x37\xf9\x1b\xc4\xc5\xc8\x15\x08\xbe\x27\xfa\x0b\x84\x94\x0b\xe3\x6b\xce\xd2\xe6\x5c\xd3\x6b\x39\xfb\xdc\x5e\xa6\x86\x14\x15\x92\x28\xca\x65\xc5\xd8\x40\x7b\xaf\x66\x3b\x52\x8e\x7d\x87\x73\x4c\x7b\xc7\x7d\xc8\x43\x1a\x1d\xd6\x87\x3c\xfd\xdf\xc3\xe7\x57\xd9\xad\x1f\xed\xd3\xc7\x98\xf1\xfe\x60\xe7\x15\xee\x48\xa6\xbc\xbb\x13\xb6\x16\xa8\x9a\x38\xe3\x36\x48\x9d\x3d\x6c\xcb\x72\x69\x14\x11\x2a\x1b\xc5\xd9\x77\xc9\xb2\xa3\xfa\xc1\x07\xad\x09\x4b\x03\x8a\xb7\x54\x68\x26\x3c\x34\xbd\xa8\x17\xc0\x56\xe0\x7a\x6c\x56\x69\x7c\xb6\x4a\x0b\x1f\x96\x6f\x6d\xe0\xbb\x1c\x0a\x71\xc8\xa5\xfe\x13\x3b\xa2\x03\x6d\x24\xda\xcc\xad\x3f\xa0\x3b\x39\xcd\x27\xf8\x32\x75\x27\x51\x05\x5a\x81\x55\x91\x3d\x04\x0f\x51\xda\xe7\x8d\x71\x94\x6c\xa0\x4d\x83\xc7\xc8\x94\xc2\x80\xaa\xec\x28\x55\x43\xe5\xfd\x5e\x32\x7a\xcc\xca\x9a\xbe\xf1\x56\xa1\x3b\x95\x71\x44\x6b\xd8\x00\x7f\xf9\x2d\xbc\x0f\xba\xf2\x3a\x94\x41\xb5\x3c\x1c\xd7\x40\xc3\x4c\x28\x29\x29\x10\x1a\xd2\xea\x8b\x85\xd7\x00\x52\x99\x1b\x77\x4e\x92\xff\x75\xcc\x85\x11\x3e\x09\x00\xb5\x1b\x86\x3e\x1f\x2a\xda\xab\x2d\xbc\xf4\x6a\xf4\x79\xea\x24\x8e\xc2\x88\x9a\xfb\xfe\x73\x74\x08\x39\x3a\x2b\x1b\x33\x01\xf6\x5c\x1f\xac\x8b\x67\x67\x95\xab\x5b\xf4\x47\xf0\x5e\x0d\xaf\x67\x76"}, +{{0x65,0x73,0x22,0x78,0x41,0xf6,0xf9,0x28,0x31,0x14,0x6c,0x44,0xc0,0xe4,0x80,0xcd,0xf5,0x44,0xbb,0x87,0x65,0x52,0xcc,0x5f,0x9d,0x42,0xf1,0x5b,0xdc,0xc0,0x44,0xb8,},{0x19,0x22,0x57,0xa5,0x4c,0xe5,0xd0,0x4c,0x19,0x43,0x9f,0xdc,0x9e,0xde,0x18,0xec,0x85,0x6e,0x29,0x87,0x0e,0x24,0xd3,0x73,0x1f,0xe2,0x22,0x47,0x99,0x94,0x9b,0x7e,},{0x53,0x8e,0xac,0xe4,0x93,0xde,0x53,0x38,0x4b,0x1e,0x98,0x5b,0xb9,0x07,0xc0,0x94,0xf8,0x16,0x84,0x30,0xda,0xb1,0x4d,0x37,0x79,0x1b,0xe6,0xe7,0x8f,0xf3,0xf5,0xa3,0x06,0xec,0x70,0xdc,0xac,0x86,0xd9,0x93,0xa4,0xc1,0xf7,0x58,0x50,0x78,0x6d,0x79,0x5f,0x02,0x2b,0x79,0xbe,0x6a,0x54,0x77,0x69,0xe4,0x15,0x69,0xc5,0xa9,0xa3,0x0a,},"\x6e\x7c\x6b\x12\x2a\xb3\x6b\xd1\x35\xf6\x9e\x2b\x85\xe7\xfc\xce\xfb\x07\x2c\x12\xcf\x08\x8a\x32\x29\xd8\x76\xef\xf5\x32\x38\x9f\x05\x77\x11\x6f\x7a\xf2\x9f\x11\x95\xe3\x82\x88\x39\x38\x13\x80\x46\x71\x78\xb2\x29\xc5\xa1\x8d\x7c\x49\x43\xec\x97\x0d\xd1\x8b\xce\x72\x3b\xd0\xca\x91\xff\xa9\x55\x63\x54\x6a\x32\x4f\xe0\xb9\xbf\x6c\x04\x55\xd4\x27\x60\x39\xe8\xd2\x91\xfc\x72\x76\xaa\x55\xa1\xcd\x3e\xa0\x52\x82\x65\x4a\x7f\x97\x00\xad\xcb\xc7\x80\x77\xc5\xdd\x0f\xc8\x6e\xce\xd4\x8f\x4a\x60\xcc\xb7\x6b\xfb\x8b\x45\x62\xba\xc2\x2a\x02\xd1\x9e\x44\x89\x39\x4a\xb9\x71\x9f\xc1\x44\xf5\xdb\x2e\xf0\x39\xb3\x7f\x3b\x51\xd1\xd6\x57\xa0\xcf\x83\x5d\x71\xf1\xa4\xaf\x01\xeb\x9f\xd8\x85\xc6\x04\xa6\x24\xcb\xe9\x10\xbf\xde\x09\x3a\xd3\xf0\xcb\xfd\x9a\x48\x30\x73\x29\xd4\x42\x34\xbd\x01\x19\x1d\x56\xe5\x22\xd7\x2b\x54\xe1\xfe\x47\x33\xda\x3a\xec\x68\x27\xea\xb3\x55\x48\x98\xe0\x3e\x57\x7b\x4e\x7b\x9d\xd3\xf3\x08\xe6\x16\x80\x8d\x02\x94\x49\x9f\x28\x86\x29\x5e\x54\xc3\x60\x19\x9c\xa8\x3a\x83\xff\x46\x19\x5e\xa3\xc4\x84\xa6\x68\x38\xd5\x1a\xcb\xe9\x61\x1e\xee\x03\x6a\xe2\x81\xc6\x79\x3c\xbd\x45\x1f\x92\x71\xfb\x5d\x25\xea\x7c\x18\x99\xab\x5d\x43\xed\x8b\x9d\x06\x7b\xc5\x6d\x8d\x4a\x15\xf1\xda\xb8\xd8\xd9\x5d\x1b\x17\xaf\x64\xcb\x18\xc1\x14\x75\x51\x14\x7a\xdd\xcb\xdd\x53\xfb\xcc\xd9\x02\x6f\x85\x55\x47\x13\x1b\xee\x95\x07\x16\x39\xf6\x49\xf2\xd0\x35\xa2\x5a\x3e\x42\xe3\x8e\x22\xbb\xf0\x38\x10\x6c\xe8\xbc\x4a\xd6\x76\x8a\xb9\x2c\xd5\x7a\xfa\xcd\x04\xee\x55\xcf\x07\x14\xb7\x68\x95\x2d\xac\x24\x0b\x1e\x9b\x28\x35\xec\xf7\xb0\xd6\xc4\x07\xc8\x25\x24\xa9\x23\xb9\xf5\x4d\x1b\x8f\x12\x56\x4a\x87\x21\x44\xef\xad\x3f\x3a\x7d\x23\x97\xcd\x12\x17\xdc\x5a\x9c\x96\xe4\x3b\x29\x60\xa8\x42\x5e\x97\xe0\x7a\x02\xb0\xda\xc9\x0f\x34\x6b\x91\xa3\x46\xa2\x3e\xd2\xbb\x7f\xe6\x91\x9c\x22\xdf\xf0\x3f\x62\xda\x7d\xba\x17\x6e\x8d\xdb\x22\xf3\xf3\xa6\x68\x89\x1d\x3f\x4e\x69\x54\x8d\x0a\xc4\xe7\x1e\x6d\x28\xed\x5a\x67\xab\x5a\xc6\x11\xd4\x60\xb6\x7a\x20\x1f\x4f\x56\xa5\x00\x3c\xa7\xa7\xd1\xcd\x1d\xb6\xc1\x00\x75\xb0\x92\x27\xcb\x8c\x5d\xc1\x66\x6f\x8b\xe7\x10\xb4\xb7\xbc\x2b\x95\xae\x60\xda\x4f\x64\x17\x9a\x50\xd2\xf8\x87\x44\x36\x15\x91\x67\x1d\x36\xb7\x29\x63\x15\xf6\x99\x64\x39\xad\x79\x82\x1d\xa8\xe7\x72\xdf\xbf\x55\xa9\x0d\x5d\x52\xef\x7d\x76\xb3\x5f\xfe\xbd\x42\xe3\x52\x5f\x45\x30\xc5\x4a\x0f\x23\xb4\xd0\x7c\x5f\x59\x74\x47\x0e\x89\x40\x4d\x17\x6e\xef\xf9\xef\x23\x33\x61\x96\x91\xc5\x9b\x7a\xad\xd4\x2c\x29\x6b\x1d\x0d\x32\x8d\x9a\x3b\xd5\x9a\x54\xbb\xa9\x3a\x0c\x1f\x1d\x62\x41\x8c\x21\x90\xc3\x81\x74\xb6\xab\xea\x02\xdb\x66\xe8\x18\x32\x0e\xc4\xb8\xba\xc1\xc1\x2f\x18\xf3\x0d\xad\xe2\x7e\x63\xc5\x8f\x9e\x7c\xaf\x4b\xf6\x9b\x26\x5a\x2f\x9d\x91\x80\x08\x61\xac\xf4\x79\xe6\x5e\xc1\x7e\x68\x05\x77\xe0\x58\xcb\x16\xc1\x09\xbc\xf9\xb2\x90\x9f\xce\x33\x61\xa2\xc2\x68\x5c\x10\xbe\x85\x40\xa1\x22\x2d\xb5\xec\xf0\xcc\x4d\x53\xa4\x21\x4b\x7b\xf6\x24\x8a\xdc\x3a\x86\x1e\x34\x84\x1a\x37\x79\xc4\x60\x46\xc5\x36\x4f\x1e\xa9\x1a\x78\xc9\x70\x0d\x46\x2e\xcf\xaa\xe3\x6b\xa7\x60\xc1\xbd\x6a\x23\x7c\x96\x1e\xdf\x40\x22\xce\xde\xfe\x5e\x93\x7b\xbe\xd7\x05\x1a\xe6\x1b\x96\xd0\x8b\x04\x87\xce\x05\x68\xff\x0d\x32\x74\x0b\xbd\x49\xad\x0d\xb8\x6e\x09\x10\x2a\xb2\x1a\x91\x56\x16\xe9\xdf\xdd\xc8\x1e\xbf\xb3\x6c\x90\x3e\x07\xa4\x0c\xd2\xdd\x11\x9f\xf4\xa5\x0b\x93\xfc\x6f\xdf\xc0\xf3\x6e\x59\xe0\x14\x8f\xcf\xf3\xfe\x8e\x2c\xd6\xd3\x0a\x9e\x4b\x8f\x01\x55\x67\xd1\x18\xb6\x27\x4e\x1e\xd7\x5b\x22\xe4\x4c\xa9\xd9\xdb\xfc\x16\x07\x42\xcf\xac\x58\x1e\x1a\x0b\xf5\xff\x33\x26\xbc\x5f\x78\x96\xb9\xca\x05\xa8\x11\xd5\x5e\x97\xc8\x34\xd3\x7a\x64\x95\xcc\x26\xcf\x44\x2b\xd2\xd9\x01\x29\x89\x5e\x9c\xc0\xed\x01\xe2\x15\x52\x93\xf4\x7a\x07\xab\x58\x80\xc6\xca\x29\xed\x44\xd9\xcc\xbc\xaa\xda\x7f\x3e\xb6\x04\x02\x18\x14\x88\x65\x4e\x04\x91\x15\x78\xb1\xaa\x9c\xdd\x4b\x86\xb0\xdd\x24\x50\xdf\x3a\x43\x08\x1e\x41\x10\xab\x58\xde\x76\x39\x24\xd3\xc8\x91\x52\xe9\x92\x93\xe6\x38\xf9\xac\xd8\xd7"}, +{{0xa6,0x3c,0x1f,0x54,0xb2,0xca,0x05,0x8f,0xed,0x2e,0xe2,0x50,0x4b,0x98,0x3f,0xf3,0x3d,0x57,0x0a,0x9b,0xab,0xa5,0x83,0xc0,0x86,0xce,0xfe,0x19,0xf4,0x3e,0xc4,0x9d,},{0x32,0x9b,0x86,0x6b,0xca,0x41,0x94,0x29,0x7f,0xc1,0xad,0x5a,0x0e,0xba,0x0d,0xf9,0x56,0x69,0x9c,0x74,0xab,0x7d,0xa5,0xfa,0x54,0x62,0xbd,0x06,0x61,0x47,0x10,0x20,},{0x28,0x33,0x59,0xbe,0x41,0x29,0x0a,0x51,0xe6,0xa7,0xc5,0xd5,0x72,0x5c,0xa4,0xea,0x0a,0x68,0xf1,0x4a,0xca,0x14,0xb0,0xf0,0x25,0x66,0xde,0xe2,0x1f,0x49,0x0d,0xa3,0xc7,0xe9,0x5f,0x7a,0xb7,0x39,0xbc,0x35,0xa7,0xf4,0xf2,0x32,0xe9,0x71,0xaa,0x15,0x76,0x57,0xa6,0x33,0xeb,0xa0,0xe7,0x2d,0xc9,0x7a,0xf3,0x2c,0xdb,0x92,0x87,0x02,},"\x79\x1b\x86\xfd\x58\x77\x13\x47\x8f\x92\x34\xff\x30\xce\xfc\x12\x3c\xd7\xc3\xeb\x12\x5f\xa7\x4e\x4c\x6d\xb6\x4e\x78\x44\xf7\xc8\x5b\x16\x86\xe7\x1e\xd0\x8d\x1a\x6a\x04\xe0\xeb\xbd\xff\x4a\xb1\x60\xc9\x76\xc8\xab\x9b\x50\x5f\x6a\x7e\xb0\xa1\x84\x27\xe9\x99\xa8\x82\x8d\xf1\x06\x84\xf8\xc7\x5b\x6a\x6b\x0a\x64\xc0\xaf\xa4\xbb\x22\xbe\xd1\xcb\x93\x25\x35\x9c\xac\x3b\x8c\x50\x8d\x98\xbc\xb0\xeb\xcd\x74\x8d\xc1\x32\xf1\xd6\xa3\x60\xa4\x45\x0d\x12\x92\xa1\xfe\xfc\x4e\x57\xe4\x10\x7a\x22\x3f\x42\x1e\x7d\x14\xa3\x84\xb8\x5c\x18\x84\x4d\x0b\x9e\xed\x2e\xcb\x81\xbb\x74\xe8\xa1\x26\x52\xd9\x85\x05\x79\x5a\x01\x31\x16\xa7\x07\x6c\xcb\x54\x93\xd6\xa7\x11\xf7\x63\x7e\x97\xa7\x80\xe7\x4d\xa1\xb3\x9b\x15\xcc\x7b\xbd\xe2\xe6\xc4\xd0\xd3\xe8\x30\x05\x97\xc8\x36\xe8\x0b\xcb\x8d\x80\x81\xd9\x74\xe0\x24\x32\xea\xc8\x83\x68\x21\x1d\x3a\xaa\xe8\x9a\x14\x41\x71\x08\xe1\xff\x67\x37\x08\x38\x49\xc6\x25\xb4\x0d\x63\x1f\x6c\x83\x57\x22\x0c\x7f\x37\x38\x0b\x3b\x2c\xc5\xd0\xe2\xdf\x6b\x4d\x11\x96\x57\x9d\xbc\x57\xb6\xc9\xea\x0d\x41\xf4\xfa\x0e\x55\x6f\x94\x3c\x94\x48\xef\x42\xfc\x78\xdf\x59\x96\x64\x8c\xe2\xf3\xde\x04\xd8\xa6\x63\xf9\x67\xf3\xd9\x33\xd4\xf6\x53\x57\xab\x29\xba\x5b\x64\x05\xfb\x16\x29\x72\x57\x8d\xdb\xb2\x36\x7b\xed\x14\x3c\x85\x4c\x10\x88\xde\x92\x1d\x79\xf5\xa9\x2a\x85\x48\x37\xeb\x77\x02\xe1\xba\x92\x5c\x6e\xac\x23\xd1\x34\xba\x1b\xaf\xc5\xd4\x6d\xe2\xa1\x94\x2c\x7f\x36\x6f\x70\x1b\x0a\xfa\xbb\x75\xcb\x1d\x80\x8e\x1a\x1e\x4e\x3a\xe5\xde\x88\xe8\xe9\x98\x97\x57\x45\x8b\xdd\xd8\xa8\x06\xc1\x10\xcc\x3a\x73\x3d\x1d\x4a\xc5\x8a\x40\x5c\x4d\x81\x13\x4f\xbc\x24\xcc\xde\x7d\x5a\xfe\x42\x0f\x9f\x17\x85\xf0\xa5\x02\x0f\xaf\xbb\x22\x61\x22\x25\x08\xaa\x05\x28\xb7\xb4\x8b\x56\x72\x00\x95\x84\x25\xef\xcb\x42\x93\x4a\x88\x0b\x13\x34\x44\xbb\x10\x9f\x2a\x95\x4c\xfa\x35\xa2\xd1\x7c\xb0\x5e\xe3\xf1\x6d\x06\xb3\x21\xa1\x5f\x91\x33\x9a\xbe\xda\x24\x3a\xd6\xc0\x91\x9f\xac\x51\xe9\x07\xe0\x53\xfd\xee\xd1\xcf\x03\x00\x37\x34\x13\x77\x93\x94\x1b\x8a\xdf\x9a\xb6\xaf\x81\x9c\x24\x5d\x6d\x56\xf1\x69\x64\xc8\xa7\x5b\x07\x56\xa8\xcb\x0c\xa8\xc1\x2a\xc6\xe6\xb3\x94\x2e\xeb\xec\x2f\x86\x88\x35\xf8\x1b\x10\x9d\xb4\x98\xa4\xca\x2e\x02\x1f\xa7\x65\x60\x8d\x23\xd8\x03\xde\xdc\x9e\x51\x45\x3f\xc1\xd2\xa6\xa3\x8a\x4a\xab\x25\x7c\x0f\xe7\xd6\x7d\x32\xa5\x41\xe0\x14\xb6\x0e\x10\x13\xa9\x2c\x1b\x3a\xd9\xe6\xf1\x1b\xe2\x93\xb2\x46\xf9\xa0\xc6\x44\x0b\x0b\x54\xfe\xe7\x5f\xed\x2f\xb7\x5c\xc9\x1e\xcb\x32\x73\x8c\x49\x58\x31\x58\x6a\x11\x24\x2d\x87\xdc\xb4\x88\x3e\xdf\x67\x57\xa5\x0b\x18\x84\x37\x59\xb9\x8d\xd0\xce\xf4\xa3\xfe\x10\xd7\x63\x70\xec\xda\x8c\x83\xfa\xb8\x7e\xee\x26\x56\xc5\xf2\x61\xc3\x40\xea\x91\xa5\x60\xd0\xe2\xc6\x42\x89\x26\x7f\x00\x36\xba\x35\x94\x48\x00\xa5\xa0\xae\xf3\xf1\xdf\x83\x9a\x72\x4e\x18\x1d\x79\xb8\xa3\xc1\x6f\x65\xae\x27\x95\x3c\x4a\xae\x8c\xcd\x30\xff\x5a\xcc\x4b\x31\xe4\x76\x5c\x68\xfb\x38\x31\x9f\x10\xac\xf8\x92\x47\xb5\xa3\x9b\x3b\x08\xa1\x91\x75\x4a\x24\xac\xa9\x59\x6a\x1f\x8a\x70\xb6\xe4\xf0\x3a\x20\x04\xa9\x08\x6f\xf6\xed\x07\x65\x2a\x92\x6e\x1e\x2d\xf7\xbd\xcc\xd5\xbe\xc1\x6e\x5c\x4e\x96\x83\x64\xa0\x9a\xbf\x9d\xed\x93\xdf\x5f\xca\x0b\xcc\xa5\xc8\x12\x97\x6e\x5c\xfb\x3c\x34\x93\xfc\x17\x5d\x1d\x92\xee\x8d\x1c\x98\xfb\x33\x82\xb3\xab\x90\xc5\xc0\xe4\xbd\xf6\xa3\xac\x94\x76\x7b\x68\xd4\x7e\x6b\x9c\x24\x42\x65\xe3\xb1\xab\x06\x23\xa8\xf0\x10\x02\x73\xf2\xc6\x07\xde\x89\x61\x2c\x72\xd3\x9b\xe4\xc0\xb4\xd7\x7a\x3c\x61\x36\x8d\xf4\x0b\x36\x08\x65\x29\x89\xd1\xe1\x9c\x0a\xaf\x0e\x3c\x25\x3e\x56\x2c\x64\x09\xfe\x64\x48\x92\x9b\x33\x75\x3d\xe1\x62\xe6\xde\x5b\xd4\x66\xa5\x11\x4f\xc0\xe5\xf5\x71\x02\x75\x5e\x29\x54\x4f\x03\xb2\x8d\x4f\x78\xde\x9a\x02\x4d\xd4\xc4\xe8\xc3\xc2\xd4\x41\x15\xa7\xae\x15\xed\xb4\xf5\x58\xaa\x7d\xba\x64\x26\xe7\xe3\x72\xc5\x4f\x79\x40\xbd\x77\x14\x46\x7f\x8c\x3a\x1a\xdd\x3c\x64\x01\x89\xc3\x16\x60\xd8\xcc\x01\xd3\xc5\x38\x2e\x42\xab\xc1\x04\xc7\x23\xf9\x48\xa8\x04\xca\x85\x30\x47\xb6\xb8\x7b\x5b\x6e\xf4"}, +{{0x5b,0x67,0xa6,0xd7,0xc6,0x50,0xdd,0x92,0xdd,0xd0,0x36,0xce,0x7a,0x30,0x5b,0xc9,0x59,0xa4,0x97,0xc5,0xe5,0x15,0xa6,0x84,0x93,0x03,0x5c,0xb3,0x85,0x0e,0xe0,0x3d,},{0x4c,0x6f,0xc1,0x64,0x05,0x05,0xfb,0x46,0x66,0x9f,0x93,0x04,0x8f,0x8e,0xf5,0x57,0x09,0x9f,0x3f,0xd9,0x2a,0x53,0x06,0x4b,0x16,0x33,0x63,0xa3,0x1b,0x7f,0x00,0xaa,},{0x0f,0x07,0x3c,0x9a,0x58,0x6f,0x6f,0x5e,0x08,0x38,0x9a,0x2a,0x5e,0x18,0x08,0xe2,0x70,0xf0,0xed,0xb6,0xaf,0x10,0x44,0x96,0xf9,0x37,0x57,0x62,0x3f,0xea,0x53,0x13,0x3a,0x73,0x1c,0x44,0x5a,0xc2,0x35,0x78,0xcd,0x56,0xa3,0x88,0x3c,0x08,0x95,0x86,0x68,0x63,0x1f,0xed,0xf1,0x44,0x6c,0xe3,0x4f,0x85,0x7f,0x90,0x82,0x2b,0xa8,0x0a,},"\x62\xcc\xde\x31\x77\x2c\x57\xe4\x85\x3a\xaf\x2a\x81\x81\xfd\xb5\x3f\xb8\x27\x90\xea\x65\x01\xbf\xc8\xf5\xd4\xae\x8d\xbd\x52\xde\x42\xce\x2e\x89\x61\xac\x17\x31\xf4\xbc\x08\x5f\xb5\x61\xef\x09\xa2\x44\x29\x70\xb6\x29\x79\x01\xae\xaa\x2e\xe5\x55\xb7\xd5\xe3\x95\x1c\x7c\x35\x12\x39\xdd\xee\x95\xff\x54\xf9\x24\xda\x95\xca\xe7\xb1\x5b\xa6\xa9\xa1\x33\x7b\x8c\xe4\x92\x1e\xd9\x13\xcd\x79\x1c\x1c\x69\x41\x08\x0e\x54\x8f\x3c\x36\xe8\x45\xac\xbf\xd8\xd8\xce\x35\xe2\xfd\xc2\xa2\xad\x6c\x7e\x24\x61\xbf\xcb\xf1\xaa\xbc\x55\xcf\x0f\xae\x42\x88\x85\xbe\x5e\x86\x53\x33\x08\xc9\x75\x68\x05\x21\x9a\xbd\x7f\xfc\x16\x57\xb6\xf4\x63\x29\x20\xa0\xc1\x0e\x0e\x36\x33\x19\xd9\x00\xfc\xd6\x1e\x7d\xdb\xcd\x6e\x76\x2a\x7d\xb9\x24\x80\xc3\x63\xb2\xc0\x64\x0c\x6b\xf3\x2d\x69\x0d\xd8\x29\xd8\x40\x5f\xa6\x6e\x47\x83\xeb\xe1\xcb\xde\x95\x47\x95\x4a\x90\xba\xad\x9f\x77\x4e\x94\x54\x9a\xbb\xff\x2c\x1f\x5c\xae\xc2\xbf\xd2\x8e\x41\x5d\x36\x42\x9d\x58\x51\x8c\x3e\x17\xe8\x69\x9e\x19\x89\xd4\x7b\x8d\x62\x7e\xf9\xab\x4d\x1e\x7d\x12\x0b\x37\x2c\x21\x41\x30\x4f\x7f\xab\xd0\x26\x5b\x8b\xe4\x1f\x54\x67\xf4\xde\x9e\x65\xc1\x25\xee\x1f\x27\xa2\x89\xc4\xf7\xc9\xa1\xfb\xf2\x5b\xfc\x2f\x8d\x30\x8e\x7f\xf5\x21\x91\xcb\x76\x44\xc6\xaf\x20\x45\x22\xf2\xac\x87\xb5\xf4\x05\x25\xfd\x43\xd3\x08\xc8\xdb\xc6\xa8\x61\xd2\x5d\xb2\x3e\xe2\x76\x67\x8a\x1b\x6e\x8e\x91\x28\x3b\xe0\x24\x70\x48\x2e\xd6\xcc\x9f\x6e\x39\x63\x51\xd1\x1b\x1c\x7e\x22\x32\x9c\x09\x1f\xe7\xd3\x68\xf6\x06\x53\xf9\x3b\x0f\x6a\x3f\x71\x2c\x20\xf9\xd2\xd8\xa9\xa0\x81\x98\x72\xf0\xc7\x1d\x7b\x1c\x0b\xc1\x68\x3a\x15\x2b\x48\x4b\xc2\x1c\xf5\x56\x09\x3a\xb4\xc0\xac\x16\xd3\x22\xff\x0b\xf4\x52\xe5\x58\x1e\x1e\x72\x41\x67\x38\x84\x02\x3c\x7d\x6e\x17\xe2\xde\x80\x59\xf6\x0e\x4c\x18\xe1\x3b\xd5\x5f\xcf\xee\x62\x3f\xd0\x46\x9c\x0d\x09\x11\x61\x1d\x09\x9a\x25\x70\x20\xf2\xf3\x1b\xf5\x07\x8e\x6e\x65\xa1\x35\xd5\xbf\x40\x76\x20\x23\x6d\x6c\xc7\x59\x31\x0f\xa7\x28\xff\x8b\xb5\xec\x56\xab\xbe\x1a\x3c\xd1\x51\x53\xf8\x92\xd9\x58\xd3\x0d\x16\x2d\x01\xee\x66\x5f\x5b\x56\x27\x81\xd8\xdc\xf8\x42\x80\x59\xe5\xfd\x22\x5a\xd7\x8a\x99\xea\x76\x0f\xe5\xd9\xee\x82\x19\xc9\x5a\xcb\x18\xd0\x56\x22\xe1\x0a\x9b\x6c\x67\xf6\xd4\xf6\xed\x11\x63\x5c\x5e\x2e\x0f\x85\xdd\x5d\x3c\xbd\xa6\x5a\xa4\x23\xd5\x94\xa8\x0b\x40\x42\x7b\xc3\x21\xe0\xee\xf9\xaf\xd2\xbc\x87\x46\xab\x73\x99\xff\x6d\x0e\x12\x87\xb6\x61\xdd\xc4\x06\x2d\x07\x20\x18\xf4\xc1\x0e\x86\xcf\xae\xd7\x2d\x9e\x68\x6e\xd0\x9d\x52\x55\xd3\x60\xe3\xee\xa2\xc2\x9b\x9e\xae\xa0\x5f\xc7\x8c\x8c\xdb\x8c\x9d\x4a\xfc\x7a\xdc\x6d\x4a\xa0\x67\xb7\xab\xfb\x0a\x4e\x94\x0a\x77\x58\x0e\xc2\x06\x45\x6c\xb9\xe9\xf9\x5f\x6d\x56\x5d\x53\x6e\x53\x5a\x16\x7e\xde\x8e\x20\xec\x36\x08\x1e\x2f\xc5\x5a\xef\xaf\x24\xd2\x27\xff\xfe\x5e\x6c\xb0\x30\x93\xf4\x43\xb4\xc5\x16\x55\xd9\x1c\xa6\xf2\x75\x95\x9d\x1a\x80\x2a\xde\xab\x44\x70\x1b\x31\xe8\xb0\xfd\x02\x22\xc4\x99\x96\x6c\x72\xd1\x02\x0a\xd9\x37\x0e\x28\x02\xbe\x04\xc9\x93\x3f\x6b\x77\x4f\x6e\x8c\x69\xfc\x0b\xfd\x31\x59\x39\xa1\x27\xb4\xe0\x6d\x0f\x6f\x5e\xde\x67\x1c\xe1\x16\x12\x12\x6b\x51\x87\xb5\x33\x29\xb0\xa9\xcb\x7d\xa3\xb1\xcc\xd6\x7b\x8c\x07\xba\xb9\x9a\x66\x2d\xf8\xce\x85\x1f\x50\x2f\xc4\xe1\xed\x16\x32\xb6\xba\x55\x55\x44\x01\x8f\x75\x27\xe3\x62\xef\xc7\xe3\xb2\xba\x6f\x75\xa1\x25\x4f\x42\x8b\x3b\x7e\x0b\xea\x69\x54\x9e\x7f\x9c\x73\x62\x75\x55\x00\x80\xae\xe3\xaf\x59\x14\xe3\xa3\x4b\xe6\x56\xc7\x7f\x6b\x29\x42\x0e\x54\x33\xf3\xdf\xf3\x81\x1f\x35\x28\x20\x8e\x9d\x85\x0a\xa3\xc2\x9b\x0f\x77\x8a\x24\x27\xd5\xfd\xe3\x07\x32\xdf\xe5\x04\x43\xa9\xc1\xad\x55\xc7\x2a\x08\xab\x26\xff\xaf\x8e\xfb\x90\xbc\xaf\xd3\x72\x6b\x00\xc0\x05\xc8\xc0\xf0\xdb\xf2\xa1\x35\x30\x86\x72\x1e\x44\x65\x45\xb8\x13\x44\x11\x94\xa7\x55\xfd\x26\xb9\x63\xaf\xd9\x77\x27\x8d\x1b\x10\xf0\x90\x01\xc7\xed\x97\x54\x03\xc1\x5c\xbe\x7f\x99\x2a\xb0\x7b\x84\x70\xc9\x39\xf8\x66\xf4\x20\xf7\x7d\xb7\x79\xaf\x83\x97\x00\x32\x9e\x07\x77\xa6\x11\x63\x65\xd7\x6c\x36\xd0\x9d\x86\x04\x72\xa5"}, +{{0x26,0x31,0xc8,0xc3,0x4d,0x29,0x48,0xdd,0xd5,0x99,0x6b,0x41,0x49,0xce,0xfd,0x23,0x8e,0xa7,0x45,0x2e,0xc2,0x2e,0x24,0x61,0x24,0xdf,0xa2,0x79,0xcc,0xc2,0x7d,0xb8,},{0xc3,0x90,0x67,0x86,0xff,0xb8,0xa7,0xc2,0x7c,0x44,0xc2,0x44,0x7f,0x9d,0xde,0x7d,0x66,0x6d,0xfe,0x58,0x8c,0xfc,0x54,0xf2,0xd2,0x50,0x40,0x51,0x2a,0x37,0x1b,0xc1,},{0x0a,0xdc,0x6f,0xa4,0x0f,0xfb,0x81,0xf6,0xef,0x4e,0x41,0x87,0x55,0x49,0x17,0x77,0x5c,0xf4,0x65,0xe7,0xb5,0xe8,0x57,0xf2,0xe1,0xe7,0xf4,0x00,0x97,0x71,0x06,0xd2,0x37,0x7e,0xbc,0x76,0xab,0xb1,0xdb,0x92,0x4c,0x64,0x86,0x7e,0x3c,0x6f,0xe3,0x8c,0x0b,0x4f,0xcb,0x1d,0x0f,0x94,0x68,0xe8,0xfb,0x23,0x50,0x29,0xa8,0x1c,0xe6,0x04,},"\x6f\x9b\xdc\xe1\x44\x3f\x28\x56\xd4\xa2\xf2\x27\x82\x83\x50\x12\xb7\x81\x8a\x0e\x02\x0d\xbc\xc2\x2a\x82\x16\x58\x30\x5f\x13\x42\x34\xd1\x4c\xea\x63\x61\x00\xed\x89\x6c\x2a\x8f\xb0\xe8\x70\x48\xec\x6f\x8b\x31\x48\x4f\x78\xeb\x17\x10\x45\xad\xd7\x2c\x85\x71\x0e\xc9\xf9\xb5\xd4\x36\x23\x41\x7b\x56\x53\xbe\x86\xe7\xfb\xf8\xb4\xff\x91\x11\x0a\x80\x8c\xb4\x1a\xcf\x66\xd4\x36\xe8\x9a\x73\x7f\xae\xa4\xef\xf3\x54\x49\x60\xf1\x14\xb8\x33\xb0\xb4\xeb\xc2\xc1\x40\x70\xb0\xbf\xb7\xb0\x05\x7e\xeb\xb8\x42\xbd\x1c\x1e\xd4\x58\xad\x34\x28\xf8\xf7\x2a\x1d\x1d\xb3\xc4\xcb\x47\x97\xa3\x99\xd4\x7a\x1e\x6d\xb7\x4d\xcb\x2e\xe2\x4a\xe8\x15\x85\xcf\x66\xef\x6d\x9b\xd2\x23\xf0\xf5\x4b\xc8\xc1\xce\xc1\xbb\x44\x60\xbe\xf4\xff\xd3\x2e\xe8\x05\xc3\xca\x5e\xe9\x76\xff\x9c\x14\x55\x9f\x8d\x75\x66\x62\xa2\xbc\x19\xe4\xc5\x98\x54\x06\xa0\x73\x05\xc9\x95\x0d\x86\x6c\x9a\x79\xa3\xe5\xf6\xc5\x96\x97\x53\xa1\x70\xe0\xfc\x4c\xc0\x9c\x6d\x87\xa1\x2b\x44\xcd\xf3\xbe\x16\x23\x15\x9e\x90\xca\xb7\xa8\xa3\xe6\xf0\x1f\x26\x85\x95\xb0\x21\xb1\xef\x7d\x00\x76\x94\x77\x27\x0d\x55\x84\xc9\x12\xe2\x2a\x36\x74\x38\x27\x7f\x59\xdf\x20\xc5\x62\x0d\xd5\xbe\xaa\x9b\xb6\x0b\xee\x47\xf4\xaf\x52\x7d\x89\x29\x57\xb2\xd1\x2b\x67\x8b\x52\x79\xa3\xf8\x32\x64\x65\x4c\x0a\x0f\x8d\x21\xe7\x09\x66\x8f\x30\xfb\x6e\x68\xf0\x47\xd0\xd9\xa7\xc2\xae\x9a\x28\xf7\xcb\x9d\xbf\x18\xf6\x3f\xc1\x66\x1f\x07\xd3\x10\xe5\x40\xc7\x76\x31\xf5\xbd\xac\x58\x24\x68\x5d\x7c\x9a\xba\x0f\xe1\xd0\x94\x07\xa9\x66\x2e\xf1\x8e\xb3\xe2\x8f\xd1\xe8\xbc\x89\x26\x57\xbc\x38\x24\x3a\x2e\x64\x53\xbd\xae\xab\xb2\x79\x1f\xc5\x48\x95\x21\x29\x54\x57\xad\x04\x18\x0c\xa8\x71\xf6\x31\x87\x92\xbd\x15\xfd\x18\x00\xce\x59\xdd\x3e\xcc\x7e\x0b\x72\x97\x92\x67\xd8\x18\x3e\x80\x4f\xdd\x45\xda\xad\x84\xfc\x4c\xaf\xeb\x56\x1e\xa8\xd6\xa7\x4a\x7c\xde\x72\x2d\x96\x25\x3a\xb3\xe7\x5f\x0a\xdd\xe0\x2a\x61\xfd\x5e\x1f\x59\xcb\x1f\x5f\x1b\x2e\x05\x26\x43\x58\x9a\x9e\x4b\xe4\xdd\x6e\xe6\x45\x38\xcb\x0b\x10\x9a\x11\x3f\x30\xa5\x8b\x35\x65\x62\x40\x43\x66\x2a\xbe\x17\xf6\x0e\x31\xe8\x9c\x36\xc9\x95\xe0\x0a\xe0\x7f\x56\xa9\x11\x8a\x31\xae\xc2\x4a\xd5\x44\xbc\x96\x58\x11\x21\x8d\xf8\x27\xc1\x73\x0b\xb9\x04\xbb\x79\xb6\x86\x13\xf6\xc9\x94\x67\x9b\x69\x90\xd7\x75\xb5\xcb\x32\xdb\x97\x19\x4b\xd8\x10\x19\xbe\xa4\x1f\x3a\x7e\xef\x50\x1b\xf8\x49\x1b\x0e\xa8\x59\x38\x84\x52\xe3\xec\xbe\x16\xaa\x7d\x56\x91\x51\x0a\x66\x06\xc4\x93\xe4\xc2\x93\x96\x1b\xf4\x0b\x4c\xd3\x00\xd9\xd2\x2e\xa1\xa7\x72\x4c\x07\x8b\x8b\xab\x1f\xd1\x65\x04\xe9\x89\xb1\x36\xd9\x25\x1a\xc9\xf1\xed\x94\xa5\xe9\xac\xbd\x9c\x04\xf8\x05\x8a\xfe\x03\x04\x9a\xed\x8b\xa2\x9f\xa2\xe8\xfb\x44\xf8\xe8\xc0\x4e\x87\x27\xf3\x99\xe7\x35\xe6\xc1\x49\x6a\x91\xa9\xb2\xcd\x2a\xb0\x2d\x43\xb2\x85\xe9\xd7\x61\x02\x93\xb6\x74\x9d\xf1\x04\x4b\x30\xe2\xda\x99\xa5\x64\x42\x9a\x23\xe6\x8c\x96\xfc\xe9\x2b\x08\xa0\x0b\x7b\x74\x2b\xa9\x7a\x62\xee\x58\x77\x6d\x7d\xd5\x65\xa4\x90\x07\x1d\x4b\x19\xdc\x64\x8e\x03\x32\x9c\xc5\xc8\x25\xd3\x87\xeb\xa4\x9e\x2e\xff\x6c\x43\x41\x86\x5c\x46\x4f\x13\xf1\xbe\xb1\x82\x7a\x7f\x26\x8c\xc1\x5a\x98\x24\x80\xbf\x08\x4f\xe3\x65\x2c\x1b\x0e\x0b\x4a\xd2\x62\x55\x85\x9a\xbf\x1c\x8a\x7f\x9b\x3b\xef\x09\x8a\x94\x07\xfd\xea\x0a\x53\x9e\xb0\x08\xfd\xd7\x49\xfa\x01\x86\xcc\x01\x69\xd9\xd9\xe6\x8f\xe5\xe5\x4c\xac\x32\xce\x57\xb5\xc8\x4c\x2d\x80\x5e\xca\x39\xc2\xdb\xbd\xd2\xe0\x2f\x7d\x22\x88\x26\x71\x2f\xf4\xa6\x14\x11\xca\x0a\xeb\x6f\x01\xa1\xf8\x0e\xf2\x9e\xeb\x07\x1a\x43\x22\x2d\x94\x97\x18\x4b\xd8\x5d\x9e\x44\xb1\x66\xbe\x97\xcf\xd2\xa7\x32\xaf\x4a\x23\x34\x63\xd3\xab\x54\x3a\x7a\x3c\x7a\xec\x55\x56\x56\x56\x88\x40\xf4\xdf\xea\x21\x7f\x65\x53\xaa\x98\xaf\x32\x4c\x12\xb2\xc3\x21\x4e\xe7\x6e\xec\x70\x06\x70\xaf\x68\xc8\xc1\xf3\x69\x46\xef\xd7\xff\x09\x33\xe5\x45\x3f\x12\x8e\x97\x15\xfd\xb3\x34\x4a\xc1\x0c\x4b\xb7\xec\x8f\x10\xdd\xf5\xdb\x71\xf1\xcf\x0e\xfe\x40\xf7\x5e\x5b\x63\x34\xef\x8c\xf8\x42\x9b\x32\x91\xe6\xe4\xce\x37\x9c\x17\x8a\xff\xcb\xc6\x10\x30\xeb\x89\x6d\x74\x4d"}, +{{0x39,0x76,0x9a,0x66,0xf0,0xca,0x12,0x90,0xfd,0xa1,0x43,0x75,0xb3,0x5c,0x66,0x3f,0x6a,0x4b,0x2a,0xb3,0x60,0x71,0x79,0xab,0xd9,0x90,0x63,0xe2,0xef,0xa2,0xc6,0xa8,},{0xf9,0xfd,0x4c,0x19,0x1f,0x38,0xf1,0x21,0x90,0xd3,0x28,0x5e,0x20,0xc6,0xce,0xe5,0x4c,0xfd,0x6f,0xf3,0x15,0x30,0x0a,0x4e,0xfd,0xc8,0xa9,0x0e,0x80,0xaf,0x40,0x83,},{0x14,0x42,0xde,0xa2,0x80,0x7e,0x03,0x11,0x59,0xec,0x6a,0x41,0x2d,0x8e,0x07,0xbb,0x3e,0x29,0x93,0x08,0x09,0x0f,0x21,0x8f,0xa7,0xc1,0x0a,0x9c,0x50,0x68,0xef,0x9b,0x64,0xef,0x11,0xca,0x9f,0xb9,0x2b,0xe1,0xd0,0x21,0x6b,0x99,0x31,0x8f,0xf0,0xf0,0x3c,0xb8,0x71,0xcd,0x7d,0xd6,0x3a,0x38,0xae,0x17,0x02,0x31,0x3e,0x5b,0x25,0x0c,},"\xff\x4d\x89\x87\xe3\xfa\x36\x01\x2b\x75\x86\x73\x6b\x79\x3d\x65\x97\x54\x69\x8c\xd1\x2b\x65\xe5\xba\x9d\x75\x8c\xac\x16\x49\x28\x8d\x20\x22\x43\x77\x28\x3e\xa5\x42\x5d\xec\x10\xab\x99\x17\xd1\x8c\xd1\x3d\x1b\xdf\x4a\x76\x9f\x37\x04\x4c\x84\xfa\xa2\xa4\x49\xc6\x89\xe0\x04\xc1\x4e\x00\x5c\x49\xda\x41\x06\xff\x75\xce\x13\x03\x36\x1c\x6e\x3e\x34\xcc\xfe\xe7\x5e\xe9\xc3\x1c\xbd\x06\xa4\xbc\xdb\xb4\x2f\xd6\x49\xbe\x4d\xfc\xd6\x64\x00\x6d\x6a\x5f\x61\x07\x7c\x04\xa6\xa8\x1d\xb3\x6b\xe8\x6b\xa4\x2c\x29\x51\xf0\x51\xae\xda\x64\xac\xea\x49\x6c\xb9\x24\x98\x2b\x9f\x7d\x23\x4a\xc9\x72\x3f\xef\x98\xa8\xe1\x27\x55\xe3\x26\xa5\x2f\xbe\x35\x85\x1f\x41\x1e\xeb\x86\x76\x06\xd4\x5b\x51\x3f\x54\x52\x63\x91\xc5\x54\x63\x5c\x18\x0b\x8f\xd0\xee\x45\x1a\xfc\x96\xe4\xef\xd3\x60\xb6\x1e\x6b\xaf\x03\xdd\x6d\x19\xba\x51\x5c\x31\xec\x1c\xdd\x3a\xff\xff\xdb\x27\x35\x4e\x3e\x6b\x56\xe9\xe1\xa1\xa1\xb7\xd4\xb5\x7d\x9d\x76\x89\xbb\x2f\xea\x6c\x8d\x3f\x9c\xe0\xdf\x2d\x9e\xe9\x19\xc4\x23\x0a\x1f\x20\xb8\x5d\xfe\xfe\x1e\xa3\xd7\xf7\x7d\xb4\x70\xe4\x02\x24\x29\xef\x60\x9b\x0f\xf4\x49\x46\x44\x0a\xcb\x44\xcd\x13\x44\x5b\xcf\xa3\xf2\x05\x03\xc2\x6c\x2f\xb6\x63\xc8\x90\x65\xfb\x93\x34\xa6\x03\xeb\x9a\xb7\x15\x2e\x62\x62\x92\x33\xc4\x4c\xb0\x0e\x77\x71\x6d\x9b\x72\xc8\x4f\xd1\xb3\x40\x63\x4f\xf1\xce\xa3\x47\x50\x15\x76\x10\x0e\xcb\x0f\xd1\xbb\x76\xae\x0d\xff\x1c\x2b\x09\x48\xeb\x71\xee\x2c\xc3\x1e\x79\xd3\x01\x5d\x72\xdb\xee\x22\x4a\x98\x0e\x0f\x95\xa6\x9f\x79\x3d\xa8\x3a\x2d\xaa\x56\xef\xe5\x7b\x2f\x8c\xea\xac\x9e\x55\xf4\x43\xca\x9e\x73\x2b\x48\xc7\x5f\xac\x21\xc3\x6f\xa7\x72\x73\xc3\xf3\x48\x35\xff\xd8\x3c\x96\xf0\x0a\xc6\xe8\x6c\xff\xed\x08\x15\x36\x46\xc1\xce\xa2\x23\xda\x9c\xa3\x60\xca\xb9\x7e\x03\xb2\xb6\xc8\xfb\xa7\xc1\x95\xa3\x9a\xe5\x2e\xb2\xee\x86\x43\x00\xae\x56\xa1\x0f\x54\x7f\x99\xa3\x16\x98\x72\x24\x9f\x97\x77\x4b\x17\x98\x93\x55\x36\xf2\xf5\xf0\x11\xce\x57\x61\x3a\x94\xfc\xb7\xe7\x28\x6a\x6d\x49\xc1\x0f\xd9\x29\xd7\x67\x1c\xbb\x8c\xf1\x7d\xfc\xad\x4b\x24\x85\xc3\xd8\xfd\x79\x12\x87\x21\xe5\x5d\x84\x80\x87\x63\xc2\xaf\xa9\xc5\x5e\x3b\x0c\xd7\xbf\x2f\x0a\x66\xb5\xe4\x67\xbe\xc5\xee\x89\xad\x57\x0b\x60\xf1\x88\xb3\xf7\xb4\xa5\x11\xff\x85\x93\x12\xde\xd0\x78\xd8\xd0\x09\x11\x34\xfd\x49\xbc\x79\x2d\x2d\x7d\x60\xb3\x04\x94\x1c\x7f\x23\x20\x6f\x99\xe8\x63\xb1\xe2\xd8\xc9\xec\xff\xd2\xff\x0a\x3a\x3c\x75\x49\x85\x61\x5a\x9a\x92\xed\xce\xad\x00\xfe\x0e\x05\x49\x3b\x19\x8d\x1f\x7c\x90\x08\x84\x46\xbb\xa4\x60\x38\xa7\x1f\x32\x65\x3b\x59\x12\xb2\x4f\x43\x13\x77\x48\xb7\x5a\xec\x2c\x15\xfe\x4b\xf5\xa6\xf8\x6b\x8a\x6c\xdd\x9c\x74\x47\xf2\xeb\xb0\xf4\x3b\x01\xca\x15\x23\xe0\xd4\x96\x24\x00\x06\xad\x7f\xff\xfa\xfe\x0d\xf5\x75\x4b\x34\x2c\xaf\xf3\x55\x5d\x72\xa2\x7d\x0b\x92\xca\x16\x67\x66\x5c\xec\x43\xbf\xb5\x83\x07\x7a\x9c\x17\x41\xfa\x49\x2c\xe3\xdc\x2c\x75\x29\xcd\xed\x81\xb8\x28\x1a\x3f\x37\x59\x48\xb8\xa7\xce\xd0\x96\xb2\xfa\xcc\x25\xe3\x90\x29\xe2\x21\xb6\x6a\x53\xd3\x97\x9e\x1f\x40\x5f\xd8\x8a\xfc\x06\xec\x6e\x43\x09\xdc\x85\xe6\x9d\x6e\xf2\xb4\xb4\x92\x66\x16\x4a\x9d\x9d\x1c\x31\xee\x39\x21\x12\x7b\x13\x38\x1b\xfb\x74\x0d\xd3\x8d\xc1\xc7\x31\x59\x21\xf9\xc2\xfe\x58\xb6\x1b\x63\x1a\x7d\x9f\xde\x2d\xd8\xa4\xbe\x3d\xed\x04\x90\xae\x3b\x83\x76\x79\x19\x55\xc1\xc4\xb4\xfe\xd0\x0b\x9f\x4c\x38\xab\x73\x50\xfc\x2e\x37\xa3\x15\x0c\x18\x16\x2b\x1f\xaf\x03\x37\x89\x4b\xc2\x3e\x74\xf5\x95\xe4\xbe\x33\x46\x6d\xea\xb3\x54\x58\xbe\x97\xb4\xf7\x56\x58\x97\xf0\x68\x52\xf7\x1c\x60\xfe\xf9\x10\x1d\x72\x6b\x72\xe0\x10\x2a\x97\xb2\xca\x52\x11\xe3\x80\x68\x34\xb0\xac\x1a\x7d\xf8\x7c\x2a\x07\x8d\xf2\x63\xef\x8b\xa4\x57\xdc\x89\x1b\x7f\x2e\x62\x78\x11\xab\x62\x2b\x99\x46\xf8\xc6\xb7\x31\xf2\x40\x78\xd1\x7b\x06\xb2\x00\xc3\x44\x7f\x80\x32\xaa\x3e\x7a\x24\x3e\xe4\x22\xdd\xa2\xe6\x52\xfd\x75\x71\x3a\xfb\xce\x8a\x59\xef\x85\x36\x65\x3a\x48\xdc\xf4\x2a\x70\xe7\x62\x1f\x9b\x28\x02\x40\x9b\xe1\xc1\xa6\x1f\x32\xe3\x67\x89\xa5\xc5\x05\x5e\x1a\x82\x68\xe9\xdc\x43\x8c\x2e\x15\x27"}, +{{0x0c,0x80,0x8b,0x06,0x6f,0x0c,0x8e,0x8d,0xbb,0x1c,0x23,0xd6,0xc2,0xce,0xdd,0x0b,0xe8,0x66,0xd8,0x42,0x5f,0x24,0x1a,0x92,0x85,0x70,0x0e,0xa5,0x45,0x36,0xcf,0x6d,},{0x44,0xee,0x72,0x90,0x04,0x50,0xc5,0x6a,0xb2,0x1f,0x26,0x86,0xd2,0x95,0x25,0xd0,0x66,0x3e,0x0b,0xdd,0x87,0x72,0x5b,0xea,0xc5,0xd6,0x8b,0xac,0xeb,0x69,0xf1,0xd2,},{0x38,0xc6,0x82,0xce,0xde,0xfb,0x13,0xe4,0x6b,0x11,0xf7,0xb5,0xf8,0x00,0xcc,0x81,0x20,0xd4,0x5a,0x83,0xcd,0x8d,0x8d,0xec,0x10,0xc5,0x77,0xbb,0x01,0x53,0xd5,0x09,0xba,0x4f,0xdf,0x40,0x09,0x98,0x78,0x8b,0x70,0x60,0x07,0xce,0x16,0x2b,0x96,0x94,0x5c,0x71,0x40,0xbe,0xee,0x74,0xe1,0x9d,0x07,0x43,0xaf,0xa4,0xec,0xfd,0x25,0x0a,},"\xc9\x45\x71\x41\x00\x58\x1f\x4e\x24\xda\x11\xfc\x0f\x6c\x6d\x02\x10\x43\x3f\x97\x77\x52\x51\x24\xc5\x5e\xe0\x72\xd8\x5d\x79\x8b\x70\x5f\x9d\x31\xc8\xf9\x77\xdb\x6e\xdf\xb7\xa6\x5c\x78\xad\x2d\x7d\x31\xd6\xb7\xb5\xbe\x40\xff\x11\x78\xd3\x03\xb6\x83\x9b\xb0\xc6\x32\x10\xc1\xd3\x38\xc1\x03\xaf\xa0\xd4\x53\xec\xa1\xbc\xa2\x77\xd9\x30\x77\x8a\xd5\x08\x02\x27\x2f\x03\xdb\xe2\x18\x4f\xc3\x1e\xf8\xea\x6a\xbe\x21\x69\x97\x19\x9f\x7c\x1b\x33\x77\x37\x96\x89\x07\x27\x2a\xa5\x1b\xd4\x9c\x07\x38\x9c\x95\x46\x8c\xef\x4f\xd9\x9a\xe7\x8c\xa4\x54\x2a\x2b\xbc\x0e\x8a\xa9\x52\x14\xad\x1c\xff\xf9\xd5\x08\x5a\x43\x43\x94\x47\x3b\x84\xb7\x4b\xe9\xbf\x2f\x02\x02\xad\x1e\xe4\x61\x66\x04\xca\x1d\xd7\x5f\x4a\x19\x53\x42\xeb\xbf\x8f\xc5\x9f\x3f\x79\x61\x65\x54\xdc\x7b\xfd\xd5\x56\xbe\x43\x72\x21\xc1\x0b\xfa\xd3\x9e\x11\x9e\x06\x04\x5b\xe5\xfe\xd6\x83\xd3\x53\x4f\xb6\xcf\xed\x33\x89\x1c\x96\xf9\xc3\x30\xf2\x8b\x68\x4f\x8f\xba\xd4\x7c\x01\x41\x8e\xab\x6c\xee\xcc\x2e\xd7\x77\xf4\xc2\x18\xa2\x7a\xc2\x25\x82\x39\x23\x15\xc5\x3a\xa7\x30\x9e\xc5\x4c\x61\x75\x23\x6e\x44\x24\xdc\x97\x84\x65\xab\x62\x8d\x95\x44\xb0\xbe\x84\x10\x3e\xb5\x6f\x1b\xaf\xe5\xe5\xea\xed\x04\xc9\x8b\xfe\x2e\x8a\x24\x18\xc6\xc5\x2a\x61\xea\xce\x85\x23\x6b\x66\xc7\xb3\xb8\x70\x7e\xd5\x56\x41\xdd\x9d\x5d\xa9\x7c\x99\xc1\x1c\xbe\xb9\xaa\x2d\xb1\x47\x82\x0d\xc7\x24\x80\x0a\x9d\x80\xf5\x05\xfa\x5a\xf2\x09\x21\xca\xd2\x43\x56\x83\xbb\x4f\xc6\x0b\xdd\xd4\x75\xf8\x63\xe2\xf5\x95\x0d\x23\x63\x99\xd8\xd7\x5b\x40\x4b\x39\x4a\x54\x67\x37\xf9\x3a\x62\x40\x87\x00\xb3\xab\x3c\x1e\x92\x2b\x1a\x85\x9a\x29\x15\xc2\xd3\x53\x68\x81\x5c\xd4\x5b\x85\xb2\xac\x08\x31\x21\xff\x00\x0f\x05\x0d\xcd\xf4\x15\xe5\x27\x5a\x5c\x42\xda\xe3\xb1\x54\x00\xf3\xdd\xaf\x93\x39\xf2\x0a\x12\x61\xa8\x8c\xd9\x02\x05\x63\x97\x63\x21\x11\x52\xdf\x41\x4a\x9a\x6a\x62\x18\xf5\x6b\x35\xa2\xde\x9e\x84\x82\x44\x9f\x6d\xa7\x7c\x9e\x3d\x4a\xf0\x49\x30\x15\xa7\x26\x21\x7f\x82\xac\x58\x95\x4f\xe3\xe2\xe3\x44\x40\x35\x6b\x11\x2e\x06\xa6\xf6\x71\xfb\x5a\x6e\xf4\x61\x9a\x6e\xa7\xb4\xe0\x4d\xb3\x75\x7f\xb6\x64\xc3\x96\xb3\x41\xca\x89\x00\x1d\xc1\x60\x4b\x51\xfa\x91\x53\xf9\x13\x0c\x10\x20\xff\x88\x90\x92\x87\x82\x3a\xb3\x91\x5c\xcc\x85\xc4\xe3\x5d\xf6\xc2\xf8\xe6\xf9\x02\xbe\x82\xba\x21\x29\x7f\xd3\x83\x5a\xff\x5c\xe0\x2f\x3c\x07\xdc\x09\x3f\xcb\x1a\xba\x26\xe0\x6d\xfe\x6f\x02\xdf\x79\x29\x1a\xac\xa0\x69\xec\xab\x93\x81\x40\x4c\x9c\x3e\xa1\xad\x40\x9a\xdf\x29\x2a\x91\xe3\xa5\x82\xd5\xa7\xb6\x8f\xfb\xe1\x0a\x03\x05\x24\x8e\x09\x67\xe6\xdf\x37\x2f\x28\x1b\xd1\x92\xe1\x39\x97\x9c\x98\x66\xca\x8f\xe1\xe1\x0e\x06\x16\xdc\x2d\x4f\x85\xe1\x19\xe0\xcb\x4b\xfe\x8c\xc3\x1d\x9f\x5c\x01\x8b\x65\x40\x85\x24\x00\x0a\x30\x16\xa2\x3d\x99\x14\xd5\x7e\x95\x55\x76\xe2\x66\x0b\x0e\x0d\x96\xc8\x49\x5a\x12\xc3\xd7\x31\x22\xd2\x00\xb0\xf0\xe5\xeb\xd4\x46\x56\x2b\x08\xf4\x79\x34\xab\x49\x9a\x96\x99\x1d\xcf\x99\xc9\x6a\x62\x88\x07\x39\x84\x5d\x29\x82\x01\x50\x55\x3e\xae\x9b\xe0\xbb\x41\xd5\x3d\x3a\xf0\x1d\x98\x67\xbb\x47\x32\xc9\x0b\xf6\xe1\x37\x31\x6e\x3b\x1e\xdc\xc2\x09\xa8\xa0\x9f\xb0\x62\xa6\xef\x05\xf3\x7e\x57\xf2\xc5\xd1\xd0\xca\xba\xf0\x7a\x8e\xd7\xd4\x14\x55\x40\x7b\x09\x67\x54\x18\x0a\xa9\x6d\x3d\x96\x59\x19\x45\xdd\x7a\x10\x40\xa2\xde\x60\xd8\xe1\xc0\x54\xf7\x85\x46\x52\xb7\x32\xe7\xa8\xf5\xb6\x47\x4c\x3b\xaa\x18\x40\xfb\xe8\x1b\x1e\x6b\x54\xe2\x01\xef\x0b\xc8\xd0\xf2\x13\xd7\xce\xc1\xd8\x24\xd2\x22\x09\xac\x72\x52\x5a\x64\xb9\x03\xe7\x73\xb8\x3f\x1b\x68\xf6\x40\x27\x9f\x15\x05\x3d\x21\xec\x15\xce\x2f\xf7\x59\x22\x17\x6b\x75\x84\xa1\x6b\xf1\xa1\xf0\xd6\x36\xb7\x94\x2a\x3d\x61\x86\x2f\x6f\xd1\x30\x99\x72\xd3\x14\x1e\xb7\x69\x31\x4c\xa9\x75\xd0\x20\xbf\x02\xbf\xdd\xf1\x7d\x14\xb6\x0e\xb7\x86\xbf\x9f\x55\x98\x9f\xe4\x73\x32\x0d\x44\x29\x67\x7e\x30\x1c\x68\x26\x33\xf8\x13\xff\x26\xc0\xa3\xda\x92\xf6\xd0\x68\x06\x16\x10\x5b\x04\x25\xaf\x33\x8c\x2e\xa6\x15\x3b\xdd\x52\x16\xfa\xe2\xaf\xe4\x61\xe9\x24\x9c\x05\xe3\x2f\x76\xad\x7c\x42\x9d\x92\x53\x4b\x68\x6d\xd1"}, +{{0x04,0x9d,0xac,0x3c,0x97,0x7d,0x9d,0xf5,0x03,0x49,0x6b,0x43,0xd7,0x6e,0x55,0x40,0xe3,0x15,0x00,0x1a,0xd5,0x7f,0x15,0xea,0x9f,0x08,0x70,0xca,0xd2,0xd4,0xf9,0xe9,},{0xfc,0x6f,0x4b,0x7e,0xb3,0x9a,0x71,0x16,0x80,0xf9,0x66,0xd4,0x68,0xa6,0x1a,0xbb,0x13,0xa9,0xb6,0x44,0x9b,0xb9,0x9f,0xda,0x3d,0x12,0xce,0x1b,0x50,0x6d,0x1b,0x4b,},{0x75,0x32,0xd1,0xa6,0x1a,0x98,0x1f,0x30,0x3d,0x7c,0x24,0x54,0x35,0x4f,0x99,0x54,0x0c,0xd4,0x84,0xcd,0xe9,0xab,0x33,0x7d,0x6f,0x7b,0x51,0xf1,0x79,0x22,0x0f,0x7f,0xa2,0x07,0x34,0x76,0xb4,0x1c,0x71,0x52,0x9f,0x98,0x36,0xdb,0x6b,0x1d,0x0f,0x5a,0x48,0x2b,0xbb,0x4c,0x68,0x36,0x61,0x76,0xed,0x14,0xd4,0xd8,0xee,0xfa,0xde,0x0d,},"\x7f\x31\xe3\x46\xf6\x8d\xa7\x37\x16\xaa\xcb\x16\xee\xa1\x9b\xb2\x41\x42\xdc\x28\x3e\x72\x63\xff\xc3\xf7\x04\xa2\x2a\xe5\x27\x5a\x0e\xf9\x5f\x06\x69\xba\xe5\xa5\x4c\x7f\xeb\x84\xbc\x74\x87\x3c\xca\x0f\x33\x5d\x6c\xff\x3d\x8b\x4a\x20\x05\x6c\x64\xf5\xe8\x82\xcb\xbb\xd2\xac\x74\x20\x76\x76\x46\x7e\x54\x66\xdd\xd5\x6a\xed\xf5\x6e\x09\x7c\x7f\x59\xd9\x45\x91\x5e\xb0\xeb\xd0\xc3\xc8\x3d\x48\x88\x8d\x3e\x9e\xde\x51\xad\x2d\xd8\xa0\xee\x1e\xab\x4c\xf8\x7f\xfa\x78\x63\x5a\xfc\x4d\x6e\xf3\xe8\x7d\xda\x3b\x65\x56\x5c\x29\x85\xa4\xad\x0a\xcf\xdf\xb8\x1c\xb0\xe6\x1c\x67\x82\x6a\x6e\xa0\xbe\xd4\xc0\x8a\xa1\xa5\x41\xde\x60\x45\x87\x04\xac\x21\xca\x12\xf1\xc8\x11\x8b\xb3\x09\x2c\x35\xa4\x0c\x92\x1e\x68\x45\x64\x56\x2c\x2c\x10\x49\xdc\xdc\x2b\x8d\x6a\x97\xe3\x56\x7d\x35\x6b\xff\xb5\x69\x2a\x41\xd8\x9d\xdd\xa0\xec\x35\x52\x15\x2a\x27\x57\x7f\x1c\xce\x57\xd0\x09\x86\xdc\xa7\x7e\xdf\x5e\x25\x18\x15\x82\x00\xad\xf6\x90\xaf\xfb\x31\xaa\xf2\xb5\x74\x83\x68\x39\x44\x09\x99\xf1\x57\x91\xce\xa8\x53\x42\xac\x94\xa9\x6c\x7a\xf7\xa1\x9e\x49\x43\x10\xae\x26\x67\x5f\x43\xc3\x52\x58\xe8\x5b\x68\x40\xb9\x9c\x6b\x09\xcf\xa5\x8d\x19\xf1\xe4\x3a\x77\xe3\x97\xb0\x8c\x0d\xb1\x83\x0b\xca\x67\xb3\x9e\xcd\x87\x52\xda\x61\x1e\x08\x32\xc6\xca\xe7\xbb\x8c\xe7\x4a\x82\xe7\xe7\x33\x0b\xe5\x06\x2e\xd0\x5a\xa5\xc8\x44\x57\xb0\x07\xfb\x5c\xcd\xc2\x0a\x55\xd5\x4d\x8e\x04\x09\xc8\xbd\x83\x88\x3d\x2e\x02\x9d\xff\x26\xea\x5d\xb2\x75\xdc\xe0\x99\xe4\x18\x65\x9a\x04\x00\xf1\x3b\xe9\xff\xdc\x14\xe7\xd6\x45\xa9\x46\x77\xca\x84\x69\x70\xb7\xe6\xac\x52\x7f\xa0\x09\xa3\x59\x45\x4b\x3c\x49\x36\x49\x05\x18\x9f\xb4\x9c\x9b\xac\xb6\x50\xc0\x3c\xd8\x28\x75\x89\x4e\x35\x46\xba\x03\xc3\x2e\x33\x6f\xc6\x51\x6a\x87\x67\x6c\x50\xd5\xb8\x0b\x30\x54\x27\x3b\x15\x7c\x5d\x76\x75\x14\xe5\x45\x74\xb8\xa1\x01\x98\x5a\x8e\x96\x7e\x95\xda\x8f\x92\x98\x00\x26\x0e\x08\x14\x8b\xee\xe2\xd7\x78\x1e\x9e\x85\xd4\x63\xa9\x4f\xfe\xfd\xbb\x75\xc2\x8f\xa8\x89\x80\x15\x68\x09\x99\x42\x9c\xee\x79\x8b\x3f\xd2\xd9\x67\x37\x86\x8a\x26\x3f\xba\x9f\xb6\xf4\xaa\xd5\x6a\x15\xc6\x41\x2f\xf8\x5e\x7d\x37\x52\x10\x2d\xaa\xf2\x5e\x74\x5f\xa5\xf6\xf1\x74\xa2\x31\xfc\xce\x86\x24\xdd\x70\x85\x6f\x9b\xab\xcc\x20\x91\x44\xff\x68\x64\x64\x8d\xea\x0d\x68\x84\x56\x6a\x4c\x39\x14\x78\x05\xbe\x08\x4e\x47\x40\xbc\x50\x93\x09\xbc\xb1\x42\x96\x4b\xb0\xcf\xcf\x67\x26\xa0\xe0\x4b\xbf\x32\xae\x68\x34\x73\x2b\xda\x03\x84\xce\xa8\xf4\xa4\x84\x9b\xba\x0d\x18\x64\x6c\x1c\x34\x47\x18\x96\xb5\xbe\xf1\x49\xf8\xca\xb9\xec\x83\x72\x2b\x0f\xb2\x09\xef\xe8\xa0\x4c\x4a\x23\x5d\xc8\xdd\xb2\x0a\xcd\x92\x76\x5a\xfb\xf3\x05\x87\x40\xea\x70\xb9\xc1\x0d\x9c\x5a\xef\x86\x06\x29\x8f\xe4\x15\x15\x93\xb2\x1f\x79\x7d\x92\xae\x9f\x1e\x08\x81\xb0\xd2\x71\xb0\xd5\xb1\x0c\x6e\xd8\x3c\x34\x9e\xc2\x47\x3f\xbf\x2f\xf7\x80\xdc\xd0\x76\xd8\xcf\x0a\xea\xfa\x71\xfe\x2b\x8c\x51\x28\x01\x5f\x8f\xbb\xcf\xec\xd5\x28\x1c\xd5\xea\xcb\x6f\xe9\xac\x6e\xaa\x6e\x47\xd6\x67\xb9\xad\x4b\x7e\x41\x1e\x6c\xb7\x46\x3d\x56\x76\x07\xaf\xbf\xd0\x41\x8c\x4e\xb0\x6a\xfe\x84\x7f\x5e\x40\xb4\x99\x44\x38\x28\xd5\xa2\x73\xa4\xa8\x7e\x46\xde\xf2\x1a\x91\x9d\x73\x86\x3a\xf0\x05\x4a\x09\x9e\x3a\xdc\x54\x50\xb8\xe3\x2f\x51\xea\x52\xc5\x99\xa4\xa2\xa3\x53\x51\x78\x8a\xf7\xcb\x71\xe5\xc4\x4b\xcb\x8d\xf5\x4a\x60\x1e\x6e\xc2\xc1\x82\x8b\x48\xc4\xb1\xae\x44\x63\x10\x6f\x10\xef\xa5\xca\xf3\x09\x1a\xbf\x99\xaa\xba\x52\x52\xf4\x84\xd3\xbb\xc6\x2b\xfa\x6b\x2a\x80\x6d\x23\xc6\x33\x1a\x62\xfc\x46\xbc\x62\x76\x79\xe7\x3e\xc8\x2d\xcc\x08\xf7\x91\x43\xf4\xb7\x1e\xcf\x35\x7e\xa2\xf0\xd7\x4e\x6d\x30\x58\xe6\x06\x04\x3f\x6e\x8f\xed\x70\x42\x82\xc1\x6b\x1f\x98\x8f\xfa\x36\x5c\xfa\xe9\xa3\xcf\x79\x2e\x0c\x5b\xaa\xd7\x0c\xa7\xe2\x57\x76\x01\x8b\x5e\x7f\x0e\x95\x44\xe1\xd7\x3f\x3e\x5d\x1e\x41\x6a\x5e\x50\xfb\xed\x29\x6d\xc1\xbf\x4b\x29\xa3\xfb\xe3\x2e\xfb\xd7\xe9\x9c\x83\x01\x5d\x27\xf5\x35\xad\xec\xf1\x75\xfc\x36\xc1\xea\x4f\x44\x23\xb3\x6d\xcd\xc0\x54\xba\x99\x32\x78\xe8\x5a\xc3\x62\x2d\x43\x5f\x52\x37\xba\x61\xb4\x9a"}, +{{0xf0,0x7d,0x61,0xb5,0xca,0x1c,0x27,0x00,0xcb,0x50,0xf9,0x00,0xc2,0x6b,0x7c,0x28,0xf6,0xc6,0x94,0x08,0x08,0xc7,0xba,0xff,0xf7,0x4f,0xca,0x4b,0x11,0xf4,0x25,0xd4,},{0xeb,0x24,0x3d,0xfa,0xcc,0x2d,0xc6,0x43,0x57,0x76,0xd5,0x54,0xec,0xed,0x8b,0xf9,0x23,0x90,0x60,0x4b,0x35,0x55,0x7c,0xda,0x51,0xfd,0x20,0x3e,0xdd,0xb4,0x93,0xfa,},{0xc1,0x9b,0x53,0x2b,0x82,0x48,0x56,0x39,0x32,0x63,0x97,0x01,0xbf,0x15,0xbc,0x01,0x5f,0xae,0xbb,0x17,0xbb,0x98,0xd8,0x71,0x61,0x6e,0x10,0x48,0xd6,0x4c,0xa5,0xf9,0x55,0xf5,0x58,0xf6,0x3b,0x53,0x53,0xa1,0x57,0x6f,0xa1,0xac,0xae,0xf3,0x9b,0xcb,0xc9,0x02,0x17,0x56,0xdf,0x5d,0x1a,0xb3,0xbc,0x74,0x1a,0xcc,0xf9,0x05,0x9b,0x04,},"\xc1\xc6\x78\x43\xd6\x9a\x0e\x62\xe7\xbf\x71\xf9\x02\x06\xa3\xd5\x59\x5c\xa3\xc4\x82\xaa\xa7\x67\xe9\x31\xb0\xd6\xc2\xf4\x75\x2a\xb8\x69\x91\xf0\x35\x83\xbb\x13\x8e\x9f\x72\xfa\xb5\x8f\xd6\x02\xa4\xb6\xb2\x96\x02\xcf\x89\x14\x08\xaf\x5a\x1b\xfd\x33\x98\xc0\x17\x8c\x44\x14\x61\xe3\xf4\x9b\xc8\x1d\x64\xc0\xd9\x7f\x5d\xed\x69\x2c\x75\xd4\xd6\x4d\xac\x5d\x80\xd6\x3b\xd4\xdc\x52\x10\xc1\xd9\x35\x0b\x14\x2b\xa6\xe7\x68\xf1\x50\x80\x7a\xb8\xa8\x6c\xac\xdb\x59\xd8\x4d\xdf\x66\x0b\xe5\x62\x03\xc0\x14\xfb\xa1\xe0\xdc\x16\xfa\x6d\x32\x69\x4e\x14\xb1\x28\xed\xd1\xf6\xc6\xab\x44\x5a\x3a\xd3\x41\x74\xfa\x9e\x4b\x01\xf2\x5b\x1d\x5e\x6e\xb7\x69\x83\xb4\x29\x5c\xe4\x91\x4d\x3a\xe4\x8c\x70\x4a\x30\xe5\x54\xfc\x1f\x86\x8b\x62\x72\xef\xf0\x6d\xa2\x4b\xfe\x17\xe4\xe0\xf0\xfa\x46\xbb\x08\xff\xb9\x07\xcb\x61\xbe\xbe\x52\xdf\x31\x1a\x64\xcb\x57\x8b\x30\xfd\x62\x7d\xf1\x12\x21\xae\x40\x03\xa0\xb0\xc6\x8e\x3c\x6f\x95\xa2\x1c\x85\x00\xd4\x1b\x2c\x58\x9c\xc4\x6a\x13\x9c\xac\xff\x57\xdc\xf0\x07\x59\xf5\x2e\x9c\xa3\xda\xbd\xb1\x78\x8a\xb6\xb3\x8a\x50\x48\xf5\x8e\x08\xe0\x5c\x39\x4f\x9d\x3c\x72\x11\x3d\x45\x2b\x70\x84\xc5\x19\xf8\x6c\x16\x89\xff\xdb\xae\x50\x6e\xd8\x45\x05\x22\xcb\xe4\x3d\xe2\x7a\xa3\xbf\xdd\x92\xa9\x1b\x71\xe5\x2a\x3c\xbf\x77\xc1\xbd\x28\x93\xea\xbd\x40\x7a\x57\xfe\x5e\x14\x68\x73\xbf\xb2\x04\x3f\x4a\x61\x47\xdf\x08\x3e\x54\xa2\x20\x8d\x19\x25\x81\x3f\xa4\x04\xe4\xc4\x74\x06\xe7\x72\x86\x43\xeb\xfb\x0b\x10\x14\x2f\x90\x9e\xf8\x56\xfd\x3a\x91\x6b\xc0\x85\x15\x43\xb8\x2a\x55\xf8\xcd\x52\x9b\xd2\x1d\x9e\x29\x09\xd6\xd7\xe7\x7b\xdc\xea\x46\x73\xe5\x45\xff\x4a\x67\xfa\x37\xd6\x5f\x1f\x63\xf1\x1d\x5d\x0d\x55\x97\x4a\x30\xab\xe1\x88\x33\x5d\xb5\xdc\xbd\x35\x66\x58\xf9\xb7\x76\x82\xd9\x6d\xab\xb2\x58\xea\x95\x95\x1a\x05\x59\xae\xa4\x06\x4d\x5e\xa1\x68\x05\x01\xdc\xb4\x22\x8f\x2c\x95\x6f\x81\xd2\x10\x11\x44\xaf\x74\xc7\x16\xbc\x8b\xf4\x29\x6d\xc3\xb8\x31\x72\x5c\xc1\x7d\x3b\xfd\x90\x66\xa2\x99\x53\xb2\xec\xd7\x50\x59\x43\x5b\x49\xa2\x5a\xc5\x25\xb4\xfb\xab\x17\x79\x02\x2d\xfb\x6d\xe5\x25\x14\x9d\xcd\x90\x2a\xc8\xa7\xe2\x1f\x34\x4f\x5f\x01\x01\x48\x06\x92\xd6\x16\x08\x95\x2c\x71\x41\x3e\x30\x03\x79\x45\xe2\x06\xc5\xee\xad\xfc\x3e\xdc\x4b\xae\x0d\x79\x6c\xa0\xc5\xf5\x6d\x6f\xfb\x3f\x09\x69\xdf\x9d\xf8\xa7\x94\xf5\xdc\x83\xa3\xb2\xf5\xc3\xab\x36\xbb\x90\x1b\xcc\x31\x55\x1c\x55\x0c\x63\xfa\x41\xd6\xa8\xd5\x7b\xdb\x9b\x5c\x65\xbc\x61\x0c\x3a\x98\x97\x52\xab\x28\xa0\x15\xe7\xc2\xf6\xb2\xfb\xf1\x99\xa7\x6b\x97\x50\xc0\xd3\xd5\x92\x11\x9c\x8b\x40\x22\xfa\x45\xba\xde\x2f\xbb\x41\x43\x26\x79\xb5\x2a\xcb\x46\x08\xa9\x5c\x34\xaa\x40\xbf\xfe\xc1\x0b\xc9\x8f\x47\x29\xdf\xcc\xb6\x50\xb2\xa0\x52\xdf\xb0\x68\x95\x9e\x64\x8a\x92\xd5\xaa\x4d\xd2\xd1\x7d\xde\x67\xcd\xf2\xe6\x37\x7a\xf0\xd4\xae\x37\x96\x07\x38\x9d\x7e\x35\x96\x44\x1b\x9f\x42\x22\xcf\xf6\xaf\x73\xb3\x30\x02\x70\xce\x54\x80\x0b\xd9\x34\xa9\x10\x9a\x02\x56\x3a\xdc\x56\xae\x46\x58\x44\x51\xcd\xaf\x4a\x77\x53\x81\x57\xe5\x87\x0f\x4a\xe1\x2d\xbc\x81\x87\x0f\x5d\xb4\x1a\x2c\xb5\x5e\x00\xdb\x3d\x22\x31\x62\x8f\x17\x27\xc3\xac\xb9\x9e\xd3\xac\xd8\xb6\x71\x56\xa8\x00\x5a\x4c\xc8\xf3\xd3\x55\x5b\x79\xa0\x37\x73\xa9\x31\xf1\x4e\xeb\xce\x40\xb9\xfe\x46\xed\xe5\xda\x08\x81\xfb\x22\x07\x17\xe4\x18\xe8\xb5\xa0\xfe\x5e\x47\x7e\x72\x85\xc5\x54\xe8\x59\xe1\x64\x41\x67\x2b\x48\x99\x34\xa3\xa9\xee\xb8\x8d\x78\xfc\xc5\xc1\xdb\x2d\x1f\xbd\xde\x39\x27\x73\xf6\xc9\x39\x97\x2e\xe8\xfa\x31\x89\xf4\xe9\x87\x2b\x4a\xbd\xc8\x3b\x37\x9c\x0c\x10\xe8\x18\xdc\xff\x75\xc8\x3d\x68\x70\x72\x92\x84\xce\xd4\x1f\x2f\xf5\x5a\x87\xc9\x60\xe6\x3d\x12\x11\xf0\x80\x71\x29\x3f\x6a\xc6\x3f\x9b\xde\xf3\x8f\xd5\x91\x9c\xa9\x0b\x3f\x5e\x25\xa6\xc0\xc6\x64\xc4\xec\xf8\x31\xc6\x4e\x2d\x4c\x6e\x79\x8a\x98\xa3\xa0\xf7\xbe\x7a\x24\x63\xea\xda\xa6\xa2\xa3\x48\xf9\xa4\x94\x71\x71\x23\xcc\x0a\x28\xc0\xa5\xea\xe3\xf5\xb5\x85\xf2\xcb\x8c\xb2\x60\xc2\xc5\x03\xe4\x15\x78\x57\x3c\xd9\xb7\xcb\xa1\x40\x8d\xca\x9d\x86\x0a\xe4\xf8\xc3\xd3\xf3\x22\xa4\x5b\x58\xa2\xc4"}, +{{0x50,0x86,0x4a,0x75,0xaa,0x0c,0x69,0xb5,0x93,0x50,0x07,0x7c,0x20,0x4b,0x20,0x75,0x7f,0x2b,0x8b,0x68,0x55,0xc3,0x7e,0xd7,0x21,0xb4,0x9f,0x2a,0xc9,0x17,0xd6,0xb2,},{0xcf,0xf3,0xeb,0xd5,0xea,0x0c,0x8b,0x55,0x31,0xd9,0x21,0x1e,0x22,0x19,0xe4,0xcf,0xe5,0xde,0xd9,0x91,0xd8,0xec,0x42,0x4d,0xf5,0x4c,0xf5,0x3c,0x83,0x76,0xf9,0xbd,},{0x17,0x74,0x55,0xa7,0x16,0x94,0xf1,0x2b,0x76,0x2f,0xd1,0x7e,0x08,0xbd,0xf0,0x10,0xa7,0xfc,0x91,0xd1,0x91,0x41,0xd7,0xae,0x23,0x99,0xbd,0x24,0x1a,0x99,0x8a,0x6a,0x50,0xa9,0x72,0x2a,0xc1,0x23,0x2c,0x59,0xe4,0xe2,0xaa,0xa8,0x28,0x07,0x8b,0x2b,0x92,0xf4,0xa5,0x4c,0xdf,0x0e,0xfe,0xbb,0xa2,0xc1,0x6d,0xbe,0xaf,0x07,0x22,0x03,},"\xb3\x65\xf4\x76\xac\x92\xe7\x60\x12\xa7\xff\xd8\x78\x2a\xf1\x5a\x3f\x5e\xe1\x47\xf6\x03\xa3\x67\xad\xf2\xf9\x72\x46\x13\xe8\x76\x5b\x03\x7a\xc0\xeb\x1f\x67\x37\x36\xe1\x13\x63\xe3\x52\xed\x5a\xe9\xeb\x5a\x67\x12\x5e\xd8\x18\x90\x03\x42\xae\x93\x37\x1c\x43\x3b\x91\xf6\x02\x1d\x4b\xe2\xa0\x52\xb0\xda\x43\xb3\x68\x2e\x7f\x74\x0a\xe8\x01\xd0\x54\x10\x57\x85\x8e\xb0\xc9\xc2\x8d\x98\xf0\x3b\x45\xe1\x28\xaa\xa3\x42\xc6\xb6\x02\x77\x67\x92\xaa\x81\x24\x1c\xad\x06\xf1\x33\x8f\xa0\xc7\x17\x57\x18\x0f\x58\x8c\x83\x01\xd9\x1c\x27\x67\x9b\x50\x21\xcd\x75\xd7\xf6\x17\x1e\xe9\xf8\xd5\x6e\x43\x77\x67\x98\x12\xf6\xec\x5e\xd4\x65\x38\xca\xed\x50\x0c\x1d\x15\xf5\xfc\x86\xea\xf9\xed\x9c\xf9\xa0\x60\x6b\x22\x61\x4f\xaf\x67\x64\x62\x13\x4e\x3d\xb3\x58\x23\x32\xb4\x83\xdf\xa5\x4c\xa2\x9a\x5e\xb0\xd6\xba\xe3\x38\x0e\x19\xd0\x60\x11\x34\x53\xf3\x2b\xba\xb7\xe1\x18\x62\x7b\x40\xbc\xab\xf1\x71\x1b\xcf\xea\xb8\x95\x7d\xe3\x39\x43\x6c\x70\x88\xbb\x88\x31\x01\x53\x9a\x09\xd3\xbe\xf0\x88\xfc\x1f\x84\x07\x64\x03\x6f\xfb\xb3\x3d\xec\xd1\x2a\xac\x57\xfd\x26\xf8\x48\x23\xe1\x95\x53\xd4\xd6\x7e\x00\x0e\x94\x36\xca\x32\x3d\xe0\x99\xbc\x1c\xe7\x5e\xbf\x5d\xdc\xcb\x44\x8c\xd7\xa2\xe4\xbb\xd6\xb3\x2e\x3f\x20\x24\xf9\x6c\xc5\xc7\x15\x2b\x8b\xe8\xed\x0b\xd8\xe4\x36\xd3\x24\xd1\xce\x1d\xd3\xcf\xcc\x45\x2a\x28\xc7\x3a\x95\xaf\x84\x82\xaa\x77\x2a\xe5\x3d\x5b\xe1\x29\x2e\x39\xd1\x71\x6b\x43\x75\x8f\xe5\x63\xc8\xaa\x3b\x74\xbb\xa5\xc0\x2d\x04\x77\x8d\x91\xe3\xd4\x3d\xcc\x72\xbb\x7c\x7b\x04\x3c\x05\xc8\x74\x5b\x70\x5e\xe7\x5b\x5a\x4e\xc7\xb9\x5b\x65\x43\x59\xfb\x5e\x85\x33\x38\x21\x98\x51\xd4\x0a\x8a\xfb\xb4\xf9\x1e\xcb\xb4\x1e\xb8\x15\x34\x19\x6c\xc0\xcc\x9d\x3e\xb7\x14\x39\x6c\xaf\x04\x5b\x23\x17\x22\xd4\x48\x65\x03\x64\x04\x19\x98\x84\x80\xa7\x81\x58\x08\xbe\x97\x42\x87\x37\x2c\xfc\x48\x99\x65\xaa\xc5\xb8\x09\x5c\x63\x75\x81\xeb\x91\x0f\x90\x55\xcd\x1c\x0a\x0a\x3b\x0b\x33\xac\xa9\x0f\x7c\x5b\x8e\x6e\xf6\x83\xab\xf0\xce\x53\xae\xba\x51\xbe\xc4\xfc\x7b\x42\x7a\x23\x47\x36\x0f\xca\x86\x36\xd3\xf1\x46\x92\x84\xf2\x69\xa9\xab\xf0\xcb\x1a\x24\x4a\x15\xd6\xb4\x04\x65\xe7\x5c\xf8\x90\x92\x47\x4a\x8b\xed\xa0\x33\x39\x1d\xd3\x11\xc4\x99\x51\x9a\x08\xc4\xf0\x34\xe7\x19\x18\xd7\xca\xd4\x18\x45\x32\x7c\x89\xe7\xb1\xe9\x4a\xfb\x07\x23\x78\x2c\xe5\xc5\x53\xef\x36\x79\x1b\xba\x63\xde\x17\xd7\x46\x49\x18\x94\x01\x2c\xeb\xd8\x7b\x18\x37\xa8\x21\xef\x5c\x62\x4b\xbc\x84\xcc\x50\x35\xf5\xe7\x0c\xd9\xf2\x1b\x42\x21\x9a\x2d\xce\x30\xe0\xe6\x5c\x25\x0d\x0d\x19\x4d\x2b\x52\x48\x6b\x03\xee\x66\x33\x29\x81\xa5\x22\x51\x74\xdb\x17\xe5\xa8\xbb\x4a\x10\xed\x9c\x8a\x44\x5c\x41\x44\x2f\x3b\xcd\xb6\xb4\xf4\x9e\x4e\x1d\xc8\x76\x61\xa7\xb6\xe4\x1f\x35\xf5\x5d\xd6\x7b\xd4\xcb\xc6\xff\x58\xbf\xbf\xfa\xff\xd2\xc3\x82\xfc\xad\x0c\xae\x8f\x0d\xf9\xaf\x6a\xcf\x09\x40\x00\x76\x18\xa5\x4a\xee\x31\xd9\x32\xcb\xd8\xe8\xb4\x1c\xa0\x38\x21\xc4\x28\xa0\xef\x8e\x58\xd2\x43\x5e\xec\xd5\x03\xc5\x4d\xa9\xc1\x62\x8f\x3c\x74\x9b\x77\x05\x19\xf5\x3b\xf2\xd5\x7e\xd7\x12\xd0\x75\xd3\x73\x37\xb7\x7a\x2b\x10\xa7\x2d\x2d\x59\x0c\x20\xd5\xce\xc2\xca\xcc\x6c\x3a\x8d\xc1\x13\xe2\xd1\x6e\xf2\xd1\xb3\x90\xed\x96\xe4\x03\x6a\xcd\x30\x4e\x0c\x7c\xef\x9d\x43\x1f\x88\x21\x8a\xa1\xf8\x38\x28\xdd\xa6\x36\xb9\x4a\xa7\x61\xc7\x31\x7e\xcf\x11\x6c\xbf\xc6\x11\xe5\xba\x6d\x94\xc5\x0e\x99\x46\x93\x02\x3b\xdf\x2d\x24\x8e\xd6\x03\xf8\x5b\xe7\x3a\x00\x08\xb7\x5a\xde\xf9\x51\xdc\xcf\xa3\x0e\x42\xe9\xf5\xbb\x05\x02\x3a\xde\x79\x75\x06\xcb\xf9\x0b\xb6\xdc\xe4\x3c\xf3\xa1\xc3\x14\x1a\x5c\xc5\xfd\x9a\x4f\x3c\xc5\x57\xb9\x0e\x18\x04\x9b\x3c\x13\x0f\x46\x1e\x4f\x32\x29\x9f\xa1\xd1\xcf\x9c\x7f\x2e\xa2\x05\x35\x65\xe8\x16\x0a\x34\x1c\xdd\xf9\x9a\xcd\xdd\x49\x16\x97\xfa\x70\x51\x24\xab\xda\xb4\x2a\x5e\x8f\xcf\x04\x8d\xd9\xf1\x79\x38\x4e\xc9\x2a\x46\x9a\xeb\x11\xe8\xbc\x62\xb6\x9d\xbc\xfc\xec\x66\x81\x75\x47\x57\xe4\xc5\xd0\xfd\xd9\xb9\xcf\xda\x49\xaf\x09\xb8\x3a\x5a\x4a\x10\xae\xd9\xa4\xcf\x7d\xdf\xa2\x89\x20\x9d\x47\x5a\xb3\x31\x8c\xd4\xb9\x65\xe0\x07\xdc\xe1"}, +{{0xe5,0x5f,0x22,0x0f,0xff,0x80,0x79,0x14,0x8b,0x25,0x41,0x89,0xbb,0x29,0x41,0x74,0xf8,0xe2,0xc5,0x75,0xe5,0x7f,0x39,0xd4,0xba,0xc8,0x16,0x5c,0x5e,0x56,0xe7,0x69,},{0x7f,0xd5,0x07,0xd0,0x3f,0xe1,0xd6,0xe3,0xf9,0x11,0xf0,0x59,0x59,0x7b,0x0e,0x29,0x2e,0xa0,0x96,0xf5,0xbc,0x85,0x18,0x52,0x91,0x6b,0xf1,0x21,0x7c,0xaf,0xdc,0x6c,},{0xc1,0x02,0x3a,0x70,0x68,0x74,0x3e,0xc4,0x66,0x8f,0x49,0x5e,0xb7,0xbd,0x4d,0xb5,0x81,0x29,0xc1,0x1e,0x58,0x29,0x9e,0xa8,0x7d,0x6f,0xac,0xd3,0x02,0xbf,0x29,0x6a,0x98,0xe2,0x98,0xfd,0xb4,0x8e,0xdd,0xf9,0xc4,0x4e,0x79,0xae,0x86,0x41,0xf7,0x34,0x50,0x3b,0xb8,0x3d,0xc0,0xb3,0x1f,0x61,0x0d,0xf1,0xd1,0xe9,0xd6,0x19,0xa7,0x05,},"\x1e\x2c\xe8\xbf\x0e\xa7\x87\x5d\xf2\x85\xb1\xdb\xd3\x4b\xbe\x67\x30\x7f\x2e\x8a\xc8\xbc\x14\x2c\x3b\xa3\x14\xc1\x64\x2c\x65\xa2\xd6\x2e\xb2\xc7\x83\xf9\x16\x28\x3c\xa4\xec\x3e\x53\x6d\x3e\xeb\x65\xcf\xdc\xc0\x54\x9a\xc4\xf6\xa4\x5f\x53\x9a\xc5\xdf\x79\xa6\xd5\x76\x82\x19\x73\x9d\x0c\x9a\x0c\xdb\xb3\x12\x42\x29\x6c\x33\x12\xb7\xed\x56\x00\x43\xf5\x36\xcd\x1d\xe9\xa9\xc2\xb2\x89\x64\x1a\x1c\x2d\x84\xf9\xa6\x8b\x7c\x03\xb8\xb8\x56\x7e\x5d\xc7\x13\x8c\x2c\xb9\x67\xc6\x28\xaa\x25\xb2\xea\xb4\x34\xd4\x49\x0b\x23\x50\x74\x09\x71\x7c\xde\x94\xda\x59\xdc\x1d\xc2\x5c\x7b\xe4\x2a\x8a\xa0\x2e\xdc\xf4\xd9\x95\x36\x8e\x6b\xa0\xee\x1f\x95\x36\x00\xdb\x98\xd2\x2d\xe0\xf8\xd2\x57\x02\x0e\x0a\x40\x6e\xe1\x66\x9b\xd5\x27\xb9\xfe\x1c\x61\x1f\x9b\xe5\xa3\xd7\x52\x8e\x8b\x61\x51\x67\x0a\x86\x63\xd2\xed\x1a\x58\xd3\xe3\x69\xbb\x72\x2a\x63\x02\xd7\xc1\x72\xa1\x9b\xda\xf3\x57\xee\xdb\x02\x27\x91\x56\xe3\xb9\x03\x44\x31\xa7\xd6\x8a\x39\x52\x8e\xb4\x02\x35\x87\x57\x3e\xb8\x8f\x30\xf9\x4e\x83\x3e\x8a\x23\xb9\xd0\xac\x7b\x5c\xa8\x78\x24\x59\x6b\xbb\x0a\x3d\x0c\xa1\xb1\x6a\x68\x78\xfd\xf7\xe2\xce\xa3\x4a\x6f\xfb\x95\xa9\xff\x4e\x88\x8a\x97\x59\x37\x35\xb8\x68\xda\x75\xd8\x70\x7b\xbf\xdb\x1d\x93\xeb\x86\xa5\x1e\x2d\x21\x5f\x1d\xd9\xdc\xf7\x83\x88\x72\x9a\x3e\xb0\xf0\x66\xdd\xc9\x41\xe9\x50\xc9\x21\x27\x19\x8b\xce\x63\xa5\x48\x68\xd9\x97\x02\x95\x72\xff\xa6\xf6\xfe\xa1\xd3\xa6\x91\x64\xc9\x99\x69\x53\xdc\x8b\x6f\x9d\xad\x06\x35\xc9\xb0\x81\xf5\x5f\x98\x33\x40\xf0\x81\x4b\xf5\x47\x08\x03\x09\x0e\x79\x97\xf7\xab\x79\x6c\x2b\x15\xad\xaf\x40\x21\xd6\x7c\xff\xaf\x6e\x1e\xf6\x28\x67\x50\x39\x45\xc2\x1a\x32\x96\x64\xe0\x8a\x95\xa4\x15\x82\x30\x0d\xa9\xbe\xd2\x08\x44\x4c\xe6\xaa\x12\xb3\xf8\x67\x79\x5c\x6e\xe4\xc4\xc9\x25\x70\x18\x62\x73\x61\x29\x3b\xd5\x27\x82\x1a\x29\xa3\x39\xb4\x04\xa2\xda\x4b\xd9\x94\x4f\x87\x70\x40\x79\x8b\xb5\x4a\xbd\x2d\x76\xcb\xb1\x8d\xf4\x29\x7f\x4c\xe3\x33\x7f\x64\xd2\x05\x80\xaa\x64\xbd\xec\xac\x37\x6a\x6a\x4f\xf7\x4d\x01\x44\xb2\xfe\x74\xce\xf8\x2d\x50\xa5\xe6\xbd\xd7\x99\xe5\x5f\xf6\x96\x62\xba\xc5\x37\xad\xcb\x68\x81\x22\x8c\xb6\x37\x04\x50\x0c\x14\x3a\x4f\x4d\x1d\xb2\x8d\x45\x56\xbe\xe6\x04\xa3\x99\xff\xd2\x06\x54\x65\x97\xde\xe9\x22\x52\x54\x7f\x6c\x65\x7f\x36\x84\x1a\x87\xd5\x65\xf6\x55\x27\x16\xc2\x5a\x21\x15\x14\x77\xbe\xe9\xef\x96\x18\x55\xfb\x1a\xf2\xda\x80\x68\xf2\x8c\xe9\xff\x70\xd5\x25\x2c\x7a\x63\xa2\xe1\x4d\xed\x6b\x89\x77\xb1\xd7\x69\x1a\x77\xed\x2e\x57\xd2\x2f\xf2\xe1\xfc\x4c\xdb\xce\xb5\xe8\x05\x85\x8d\x90\x38\x96\xea\x67\x07\xe4\x8b\x34\x5f\x60\xe2\x81\x8b\x2f\xce\xc4\xdb\xa4\x8c\xae\xa9\xef\xa3\x82\x79\xfb\x83\xd5\xb0\xf4\x6a\x45\xe4\x2c\x41\x76\x5d\x01\x71\xba\xac\xd8\xd6\xdd\xa7\x99\x13\x14\xb3\x4e\x15\xfd\x36\x12\x7c\x46\x7d\x1d\xe0\x1c\x01\xa3\xa7\x8a\x8c\x1b\x10\x3b\xee\x17\xa7\xa0\xb7\xac\x55\x76\xfd\xc2\x26\xdd\x24\x59\x77\x31\x46\xcf\x38\x26\x14\x17\xca\x19\x13\x5d\xbd\xa9\xbd\xbe\x54\xcd\x17\xaa\x7d\xdd\x38\xfd\xca\xc2\xab\xa3\x96\xb3\x65\xce\xae\x98\x91\x9f\x6c\x51\x77\xfc\x58\x3f\x5b\xee\x3f\x48\x70\x49\x14\x30\x6a\xa1\x9e\xe9\x0e\x3f\xd0\xde\x55\x91\xc6\x69\xff\x35\xab\x16\xfe\xf3\x8d\xee\x18\x7b\xae\x1e\x5a\xaa\x56\x6d\xf1\x05\x44\xb7\xd6\xd4\xeb\x00\xda\x7e\xbe\xb4\xec\xdc\xc4\xd8\xe3\x2b\x49\xcb\xbd\xc6\xe6\x66\x40\xbd\xb0\xf7\x2e\x05\x91\x8a\x05\xc3\x5d\x9b\xff\x7e\x0e\x88\xf2\x41\xd7\xc6\xc8\xcb\x2f\xed\xcc\xdf\x65\x56\x0a\xf0\xe7\x83\x3e\xfe\x34\xaf\x79\x0d\xb6\x31\x89\x02\x2c\xfd\x71\xfc\x8a\xcf\x88\x86\x01\x27\xbd\x4f\xbf\x02\x6b\xcb\xe3\x60\xe3\x3a\x89\x95\xe6\x36\xd0\x3b\xb8\x6d\xfd\x01\x98\xad\xa9\x59\x34\x2d\x8e\x9c\x9e\xd9\x3e\x23\x29\x7d\xa9\x8d\x66\xa0\xd4\xfc\x96\x51\x62\x73\x3b\xc8\x65\x41\xb9\x5a\x6c\x90\x97\xcb\x55\xa9\x73\xc6\xfa\xc1\x94\xe8\xf8\xa1\x64\x27\x4c\x47\x9c\x51\x0e\x62\xd8\xa0\x35\xeb\x75\x11\x81\xb5\x02\xaf\xb6\x14\xd8\xc4\x46\x7b\x54\x45\xc2\x68\xdc\x3d\xd0\xab\xbd\x57\x70\x04\xc0\xbc\x47\xb1\x5f\xcb\x80\x1b\x79\x35\x97\x57\xb5\xea\x89\xcf\x8c\xf7\x7f\xc6\xd1\x60\xe6\xcd\x73\xc4"}, +{{0xd5,0xe3,0xa4,0x06,0x71,0xbd,0x45,0xf0,0x88,0x42,0xdd,0xc7,0x8a,0xbe,0x57,0xde,0x3b,0x9c,0xe5,0x64,0x6b,0x73,0x0d,0x2e,0x59,0xfe,0xcf,0x5a,0x7d,0xf8,0x0f,0x40,},{0x41,0x6c,0x37,0xae,0x1a,0xd1,0x5b,0x63,0x2b,0x0e,0xa4,0x39,0x32,0xc1,0x76,0x37,0x28,0x2c,0xd9,0x1d,0x59,0x79,0x55,0x2e,0x5e,0xeb,0xb9,0x9a,0x41,0x9d,0x5c,0x97,},{0x63,0xde,0x6a,0x98,0x11,0x42,0x36,0x5a,0x3e,0x59,0x26,0x31,0xc8,0x27,0x72,0x37,0x80,0x97,0x39,0xd1,0xc9,0x8f,0x5a,0x1c,0xb2,0xcc,0xcd,0x34,0x06,0x7d,0x1c,0xa5,0xdc,0x8f,0x2f,0xc6,0x3b,0x8a,0xe1,0xa6,0x89,0xdc,0xaa,0x29,0x1b,0xa6,0xb6,0x9b,0x1a,0x67,0x95,0xc5,0x79,0xa5,0xdb,0x6d,0xcc,0xee,0x73,0xf6,0xa4,0x20,0xac,0x0a,},"\x09\xfe\x6f\xfa\x8b\xf0\x94\x2a\x64\x92\x13\x57\x65\x9d\xbc\x6e\x4f\x8b\x63\xca\x3b\x9e\xa4\x75\xea\x39\xd7\x92\x52\x90\xa1\x48\xd8\x7b\xb1\x55\x74\x1d\xfa\x28\xae\x1b\xea\xdc\x1f\x3e\x1a\xb7\x67\x37\xeb\x5d\x5d\xda\xde\xd0\xbb\x38\x2d\x7e\x11\xea\x81\xa5\xe7\x80\x16\x12\x69\x62\x60\xba\x3b\xd0\x9c\x80\xb6\x23\xf6\x36\x38\x0a\xa0\x20\x8f\xee\x0a\xff\x70\x81\x2d\x53\x07\xb2\x71\x83\x83\x23\x43\xde\xba\xa3\x60\x5d\xda\xd1\x7d\xdd\x70\xd6\x11\x40\x0d\xdd\x10\xd6\x38\xaa\x3d\x6c\x68\xa2\x8c\xf0\xe9\x7c\x1d\xed\xf6\xcc\xd9\xc7\x31\xa8\x4f\xf0\x40\x5a\x3a\x22\xdc\xba\x00\xab\x44\xd5\xb2\x18\x44\xf1\x4d\x13\x74\xac\x0c\xb1\xe5\x8d\xf4\xa9\x0c\x41\x25\x63\xcf\xe6\x9d\x88\x2d\x35\x0f\x6a\xaf\xbf\xa6\x4f\xa2\xf9\xff\x82\x60\x32\x32\x67\x80\xae\xcf\x93\x05\xd8\x21\x7c\x17\x9d\xbb\x63\xc1\x51\x54\x12\x32\xeb\x65\x97\x92\x65\xd8\x76\xc4\xbc\x43\x05\xc0\x2f\x40\xbc\x1d\x05\xdb\xaf\x7d\xcf\x4f\x7d\xd9\x23\x2c\x17\xee\x0f\x7a\x05\x55\xf5\x04\xba\x37\x74\x54\x84\x88\x93\x3e\x75\x71\xeb\x3f\x71\xc4\xcb\xb2\x0c\xc4\xe4\xa7\x32\x2f\x35\xac\x0e\x79\xa5\x91\x55\x79\x8d\xd0\xf5\xb3\xc1\x13\x19\xb7\xd8\xf3\xea\x79\xee\x3a\xcc\x68\xbd\xb9\xf3\x7c\x7d\x4c\x8f\x9c\xab\xa1\xeb\xf8\xeb\x7f\x43\xb4\x62\xae\xfd\x38\xe8\xc0\xd4\xc6\x39\x79\xcf\x66\x31\xde\xc3\x1a\xb5\xce\xd3\x93\x7e\xf5\xb2\x36\x2c\xb0\x9c\x71\xdd\x09\x66\x57\x70\x0f\xd9\x6b\xda\x55\x5e\x22\x71\x2f\x71\xae\xc1\x1a\xe5\xe9\x1b\x24\xbd\x16\x49\x49\x8b\x8d\x9f\x86\x7f\xb6\xc4\x1e\x07\x60\x80\xf7\x40\xd0\x74\xc2\xa2\x55\x72\xd3\x4e\x66\x6b\x63\x67\xbf\x7c\xbb\x3d\xd4\x2a\x23\x82\xdc\x19\x73\x96\x12\x68\x60\x53\x96\x81\x0a\x45\x6a\xc0\x81\xbb\xfd\x3a\x54\xb4\x48\x81\xfc\xfc\x45\xb4\x24\x5e\xe7\x24\x65\xb4\x87\xd0\x7f\x2e\xf3\xf7\x4a\xdd\x71\xcd\xfd\xd1\x6e\x92\xfe\x25\x7d\x33\x46\x45\xb0\xa9\xbc\x7d\x07\x26\x13\xfb\x9c\x0c\xde\xa9\xdb\x4c\x72\xbc\x87\x10\x9e\x10\x2d\x7c\xba\xf3\x66\xec\xd6\x7f\xbe\x3d\xed\x32\x74\x73\x07\xa7\xae\xef\x61\x73\x5a\xd3\xaa\x5c\xe9\x5d\xee\xcc\x16\xa1\x6e\xb2\xa0\xbc\xc7\xad\xc0\xa1\x1d\x88\x80\x32\x26\x0e\x7c\x7e\xc9\xe5\x4f\x5a\x25\x31\x70\x2a\x7e\x5d\xfb\x87\xc3\x6c\xe3\x13\xa3\x14\x75\x88\xae\xf9\x62\xc7\x2f\xa9\x66\xd2\x41\x63\x7c\x38\x8b\x83\xdd\xec\x93\x43\xbb\x86\x34\x3e\x92\x0b\x12\xce\x1c\xc9\x15\xc8\x3b\x31\xe9\x98\x62\x69\x06\x74\xea\x49\x35\xa4\x88\x09\xd4\xd2\x79\x05\x41\x37\x54\x63\x92\xad\x9f\x08\xe7\xb8\xde\x61\xae\x73\xe8\x1e\x48\x3d\x3c\x63\xb5\xae\x73\x4e\x18\xe7\xa2\x2f\xee\xd1\x23\x3d\x0c\xa6\x33\x55\xf3\xa4\x8a\x33\x06\x7e\x1a\x0e\x19\x71\xf3\x6a\xa9\x29\xfe\x06\x13\xc2\x1c\x4a\xef\xf9\x41\x84\x29\xc3\xb0\x72\xa5\x98\x49\x59\x28\x7a\x5e\x5c\x40\xbe\x02\xbd\x22\xb9\xa7\x9c\x7f\x3f\x53\x59\xd2\xbb\xe4\x93\xf5\x56\xda\xcb\xb0\xcb\x4c\x29\x3c\x7d\x94\x12\x65\xe7\x77\x39\x2d\x14\x8d\x68\xc0\x7a\x13\xc8\xde\xc8\xe5\xd1\xe1\xc7\xf0\x41\xe8\x98\x3e\xdd\xda\xa4\x64\x9d\xac\x15\x72\xa3\x9a\xe4\xc6\x48\x0c\xa5\x50\xe2\xe4\x46\x2d\xcc\x84\x9c\x1b\xab\x78\x1d\x28\xa3\x55\x2b\x2d\x98\xe0\x2e\x15\x18\xe6\x55\x53\x40\xfb\x76\xd6\x8d\xb5\x89\x16\xd5\x56\xa7\xb8\x15\x63\xab\xa8\x1d\x9a\x57\xae\x50\xf0\x4c\xf5\x68\x60\x21\x84\x7d\x79\xb6\xbb\x3d\xa8\x01\x7a\x60\xb1\xc3\xbe\xef\xd4\x8d\x2b\x3c\xd3\x9c\x6f\x53\xc0\x8b\xcc\x96\x7d\x93\x06\x9f\x56\x2b\xb3\x6e\x0c\x4f\x4c\xa6\xbc\xcc\x5e\x57\xd3\x59\x03\xcd\x80\x0a\x61\x78\x5a\x93\x77\x0e\x37\x7f\x4f\xe8\xe9\xf4\xb6\x66\x80\x98\x49\x68\xf9\x64\x9e\x10\x5e\x7a\x11\x9d\x97\x63\x6f\x3a\x05\xca\xea\xb1\xd7\xea\x0b\xc8\x13\x34\xb4\x2d\x5c\xc0\x80\x83\x0e\xc2\x4d\x36\x9c\xf8\x67\x3a\x49\x0d\x59\xeb\x4c\xb0\x81\x81\xda\x39\xa4\x6d\x96\x6e\x23\xfe\xd8\xd3\x8a\x5f\xab\xc7\xe8\x43\xbc\xfb\x01\x5a\x44\x74\xbf\xd4\x6d\x4a\x43\xff\x4a\x51\xa9\x56\x76\x61\xe2\x69\x6d\xb8\x7c\x37\x58\xd3\xb5\x4c\xe7\x84\x6d\x13\x91\xd7\xf4\x65\x26\xef\x30\x84\x4d\x49\x32\x00\x18\xd7\x49\xb5\xd4\xdf\xd3\x0d\x38\x0c\x6e\x57\x3f\xc4\x14\xd8\xfe\xfc\x5d\x71\x04\x70\x75\x6b\xec\x00\xd8\x8a\xc4\xaf\xc9\x25\xd1\xed\xe3\x7e\xae\xe6\x00\x4a\x23\xea\x0e\xf8\xb6\x0e\x48"}, +{{0x4e,0xd7,0x04,0x8a,0xa1,0x28,0x4d,0xbb,0xcc,0x24,0x89,0x38,0xb4,0x0c,0x35,0x74,0x21,0x93,0x59,0x7a,0xdd,0xaf,0xdd,0xe0,0x64,0x13,0xb8,0xd4,0xcc,0xfb,0xe1,0x37,},{0xbf,0x84,0x1f,0xe4,0x44,0xad,0xd1,0xf7,0xc3,0xea,0xcd,0xfd,0x07,0x84,0xb4,0xe8,0x55,0xd2,0x40,0x5f,0x40,0x21,0xcd,0x9d,0x82,0x66,0x07,0x1c,0x32,0xc8,0xa2,0x73,},{0x10,0x6a,0x9d,0xeb,0x23,0x27,0xf3,0x38,0xcc,0xb7,0x1b,0xcc,0x94,0xe2,0xfe,0x3d,0x2e,0x97,0x3c,0xe6,0xdd,0x8f,0xa7,0xba,0xca,0x80,0x8b,0x41,0x11,0x81,0x3e,0x3b,0xc3,0xb4,0xd8,0x8e,0xfa,0x6a,0x00,0xc4,0x71,0x0b,0xbf,0xe5,0x31,0x96,0xf9,0xab,0x3a,0x15,0x0b,0x16,0x54,0xb9,0x08,0xfe,0xac,0xf9,0xc1,0x3d,0xf2,0xd6,0x38,0x02,},"\xdc\xff\x95\x87\xd6\x04\x6c\x11\x32\xbe\x07\xdf\x26\xdf\x63\x82\xff\x92\xcf\xc8\xeb\x53\x45\xc5\x1d\xd5\x0d\xd1\x88\xee\x76\x9f\x10\xa4\xde\x5e\x88\x83\xd1\x16\x96\x7b\xea\x97\xd3\xb3\x2b\xc8\xae\xbb\x9f\x01\x3d\x6d\xf9\x52\xf2\x51\xc1\xa3\x12\x34\x6e\x72\xce\xe1\x35\xa1\xbf\xd7\x6b\xf3\x08\x0a\x35\xc8\x38\xb4\x4d\x75\x5f\x26\x3d\x21\x03\x10\xfa\x8d\x28\xc4\xca\x52\xf0\x8c\xac\x5b\x83\xa8\xa3\xb1\xdf\xc4\x6d\x9b\x75\x2d\x9f\xc7\x36\x49\xd0\x0b\xb9\xee\x99\x26\x50\x63\x9c\x22\x5d\xea\xc1\xf3\x9b\x9e\x80\x36\x89\xd1\x9e\x6d\x9f\x8e\xf4\xf5\x1f\x1d\x11\x60\x1f\xac\xf4\x10\xdb\x64\x8b\xcc\x82\xbf\x64\x87\x69\xa7\xdd\x59\xc6\xe8\xa2\x37\xdb\x23\x9d\x3f\x66\x1d\x78\x52\xc4\x26\xd3\x94\xa9\x05\x09\x52\x6a\x85\x9b\x47\x64\x59\xde\xdb\xe6\xd8\x99\x36\xc0\xf3\x98\x99\x95\x51\x1d\x4a\x57\x6e\x54\x2c\xce\x5e\x0d\xd7\xee\xef\xeb\x03\x26\xd3\x3f\x25\xc2\x2a\xb6\xe7\x69\x06\x33\xf4\xc9\xed\x2a\xad\xf1\xd2\x4f\x94\x86\x21\x23\xa4\x64\x04\x2c\xea\x19\x3a\x2f\x04\x79\xd3\x9b\xcd\x1b\xbd\x1c\x7a\x0c\xa7\xe6\x25\x8e\xd3\x73\x23\x72\xf5\x4e\x0e\xd5\xe3\xf1\xe2\xe4\xd4\xa0\x4c\x51\x0b\xee\x08\xd1\xc6\xd5\x70\xcf\xd6\x3a\xbf\x14\xb4\xee\xf0\xb9\x6f\x39\xca\x29\xe4\x3c\x52\xf2\xca\x3d\xfd\x46\x0f\x66\xe3\x02\x35\xb1\x59\xaa\xef\x2c\xc1\x56\x01\x29\x69\xfd\x3d\x15\x99\x78\xd6\xca\xa0\xa9\x45\x22\x29\x1f\x79\x89\xd8\xaf\x10\x83\x19\x96\x13\x7b\x68\xd9\x7f\xc1\x7f\x6a\x9b\xc2\x84\x5e\xf3\xdd\x47\xcb\xc3\x86\xe8\x97\x7a\x86\x54\x36\x34\x12\xda\xc3\xac\x51\xc6\x38\x17\xb7\xc0\x51\x87\x8d\xcf\x45\x8a\xb3\x63\x0d\xd7\xae\xf6\x8d\x27\x0f\x8d\xa7\x88\x0a\x46\x7b\x33\x04\xf5\xba\xed\xfb\xa9\x17\x3e\x7e\xfd\x00\x7c\x41\x2d\x17\x20\x9c\x56\xd2\x39\x68\xe3\x40\xb8\xa0\xed\xb4\x1b\x7e\x2a\x40\x88\xbe\xc0\x1b\x53\x2d\xf8\x9b\x52\x15\x81\x31\x31\x10\x7b\x7b\x47\x4f\x03\xc2\xe4\x7d\x43\x17\xf1\x1c\x4f\x51\x60\x90\x43\x04\x99\x7e\x76\xa1\x21\xa9\x56\x02\x35\x20\x8d\x79\xb2\xda\xb4\xf7\xe1\x96\x79\x32\x02\xc0\x90\x2c\xe9\xc4\xbf\xc1\x0b\x8f\xe3\x97\xe3\x5c\xa0\x25\x64\x54\x66\x2a\xe8\x78\xef\xb0\xa0\xa6\x06\xfa\xc0\xa9\x52\xc9\xf6\xba\xae\xb2\xd4\x5b\x25\x8c\x61\x75\x59\xc0\xed\x25\x28\xa8\x8b\x49\xaa\x44\xee\x43\x03\x5b\x0d\x79\x3a\xad\x39\x53\xc1\xa5\xa3\x46\x38\x66\xbc\x81\x5b\x1f\xfc\xe2\xff\x2b\x65\xe0\xfd\x47\xdb\xc1\x5f\x4e\x7a\x06\xbf\xab\xc2\x90\xfc\x62\x09\x0b\xf7\xd9\x48\x53\xf7\x7c\x04\x44\xa9\xb9\x0e\xfe\x77\xd1\xce\xb4\xbd\x39\xe2\x03\xbc\x88\x40\x11\x62\x4e\x68\x46\xe2\xa3\x71\x05\x8d\xab\xa6\x3c\x23\xf8\x6c\x42\xc3\xe3\x1e\xaa\x4b\xd7\xd7\xa4\x2a\xf2\xd5\x24\x89\x6e\x31\xba\xa3\xe2\x07\x63\xf8\x5d\xcf\xd5\x27\x75\xf2\x80\x72\xd8\x9f\x0b\xd4\xfa\xe3\x0d\x0b\x13\x7e\xe3\x7a\xb0\x63\xba\x06\xfe\x9d\x4e\xc6\x2a\xbb\x2f\xea\x0f\x81\xb8\xcb\xee\xfc\x03\x00\x80\xb8\x02\x6a\x58\xfd\x18\x67\xf6\x6b\xe1\x15\x4e\x65\xbf\xea\x7d\xce\xc5\x5f\xe3\x2d\x51\xfb\x0b\x4a\x8a\x5a\x8a\x04\x42\x63\x94\x3d\x6a\xc8\x01\x1c\x6e\x67\x01\xbe\xec\x3a\x88\x65\x58\x40\xc4\x89\x2d\x45\x0d\x31\x2b\x76\x52\xd2\x51\x47\x69\xf2\x3b\xfd\x6e\x70\x46\x46\x7d\xf2\x9a\x28\x7f\xf3\xc4\xc9\xd0\xe6\x4e\x6d\x9e\x4e\xde\xe1\xb9\x35\xd0\x76\x81\xd4\x70\x04\x35\x28\x86\xe8\x47\xb0\xc6\xd5\x76\x2f\xd4\x5a\x81\xa5\x3c\xce\x94\x76\xc8\x87\x22\x1a\xea\x6c\x0c\x82\xbb\xf3\xb2\x97\x93\x2e\x5b\x11\xe5\x38\xa3\x24\x5d\x63\xd7\xb7\xb0\x91\xdf\xa1\xd7\xb9\xa0\xe2\xdb\x66\x98\xa4\xc5\xe9\xfe\x93\x16\x62\xd7\xc6\xec\x6d\x9d\x5b\x92\xbc\x7e\x04\x15\x55\xdf\x4d\xf0\xca\x11\xca\xbc\x48\x5f\x9c\x55\x61\x38\xa7\x17\x45\xf0\x3b\x97\x83\xbb\x20\x0b\x72\xd2\x33\x69\x7e\x8b\xcf\x6b\x41\x17\xee\x67\x63\xd7\x92\xd7\x42\x22\x64\x85\x2f\x4f\x30\xf8\xd1\x89\x0e\x2e\xa0\x80\x98\x04\x0f\x7f\x28\x8e\x4a\xbe\x90\xb6\x3c\xab\x2c\x14\x37\x30\x60\x84\x0e\xf8\x27\xec\xc8\x46\xcd\x56\x0e\x90\xa2\x0b\x83\x05\xf4\x63\xc3\x6e\xa0\x38\x84\xa5\xdf\x4c\x25\xf1\xba\x9e\xa1\x25\x95\x2d\xc0\x91\xb9\x75\x16\xde\x1d\x28\x7c\x0e\x2b\xf5\x29\x77\x5b\xa6\xd2\xf8\xed\xe0\x3c\xb4\x2c\x1e\x40\x0e\xc8\x04\xa9\xdf\x08\xe4\x6f\x44\xb5\x06\x63\x46\xe3\xf7\xc7\xa1\xa8"}, +{{0xc7,0xec,0xa8,0x3e,0x94,0x85,0x76,0xbd,0x9f,0x27,0x8f,0xd7,0xb8,0x28,0x00,0xa4,0x1d,0x92,0xda,0x9b,0x72,0xd5,0xa1,0xcc,0xdb,0xbc,0x65,0x58,0x10,0x52,0x56,0x8b,},{0x07,0x6b,0x83,0x52,0xdc,0xa8,0x03,0x1e,0x85,0x3c,0x8d,0x90,0x99,0xc2,0xef,0x57,0x93,0x37,0xcc,0x7b,0x2b,0x4c,0x75,0xd1,0xa0,0x63,0xea,0x3e,0xc7,0x25,0xb7,0xfd,},{0x86,0x99,0x6a,0x1b,0x8e,0x49,0x5d,0x42,0x52,0x77,0xe9,0x7c,0xc0,0x83,0x05,0x49,0x34,0x9b,0xc2,0xb6,0xf3,0xdc,0xda,0x60,0xf3,0xb7,0xd3,0x50,0x1b,0x8b,0x50,0xb5,0xb4,0x58,0xcd,0xa5,0x8b,0x43,0x6e,0x23,0xc0,0x2c,0xd4,0xa2,0x2b,0x23,0x48,0x13,0xaa,0x9b,0xcc,0x3c,0x61,0xf9,0x83,0xc0,0xb7,0xef,0xec,0xa0,0xf1,0xbe,0xc2,0x0d,},"\x8d\x8c\xef\xd6\x73\x85\x5c\xcd\x8e\xb8\x53\x4c\x31\x2d\x33\x80\x05\xbb\x05\xf5\xb9\x50\x7d\x58\x85\x9e\x1e\x95\x3b\x0a\x4d\x91\x3b\xe7\x59\xd8\xed\xfa\x92\x89\x8c\x6e\x70\xa5\x3f\x81\x95\x4f\xc3\x44\xb4\xad\x62\x46\xb0\x10\x94\x81\xba\x6f\x73\xae\x63\x31\xab\xf2\xdf\x10\x8e\xb2\xe8\x5c\xeb\x08\x7c\x1f\x6f\xcf\xc9\xde\x2c\x1f\x13\x9b\xa1\x77\x1b\x72\x68\x03\x02\xd8\x11\xcc\xd0\xcc\xd4\xe0\xc7\xfe\xb0\x13\x2e\xb2\x0b\x33\x4e\x5a\xab\xe5\xf6\x11\x9f\xd8\x94\x7d\x9e\x88\x52\xe1\xeb\x1b\x74\x10\x7e\x17\x41\x00\xe3\xe6\xdf\x0c\x3a\x68\x13\x0c\xa6\x30\x94\x02\x59\x4b\xb5\x0c\x1c\x8e\x27\x74\xf1\x32\x14\x49\x6a\x7b\x1f\x34\x83\x85\xea\xbf\xbc\xcb\xac\x16\x5a\x5a\x2e\x7d\x9d\xea\x5f\xfd\x58\xb0\xbd\x88\xb4\x9c\xb3\x31\xec\xb7\xf4\xe9\xd6\xba\xe9\x79\x1a\xd7\x88\xe6\xab\x89\x26\xc1\xcc\x16\x15\xde\xaf\x4c\xc4\x00\xc7\x7a\x31\x61\x97\xbc\xa1\x90\x49\x95\xe1\x36\x5d\x1b\x97\x02\x64\x83\x76\x11\x69\x30\xf6\xf9\x11\x66\xe6\x14\x86\x29\xe7\x5b\xe2\xd0\x68\x95\xf6\xa8\xd1\x5d\x5a\x94\xca\x69\xb7\x12\xf3\x3b\xcf\x95\xbe\x0c\x1b\xe6\x90\x2b\xb7\x8b\x8a\x23\x0d\x7a\x85\x60\xc4\xd8\x4e\x23\x89\x55\x2a\x81\x57\x1a\xa6\x65\xc1\x9c\x2e\x93\xb0\xd4\x3e\x8c\x2c\xbd\x9e\x88\x5d\x70\x52\x51\x8b\x77\xc4\x7e\x84\x1d\x11\x9d\xc2\x8b\x65\xa7\x50\x4f\x66\x42\x71\xf0\x6c\x7f\xf3\x93\xf8\x25\xb1\xe5\x93\x0d\x02\xb9\xc7\x00\x35\xe2\x92\x41\x1c\x4a\xed\xf6\x60\x47\x00\x69\x70\xe3\x49\xdf\xca\x7f\xb4\x1c\x10\xfd\x53\x7e\x35\x25\x2e\x10\x9e\x33\x36\xd7\xa8\x2a\x14\xde\x5d\x55\x40\xc6\xfc\x65\x71\xd5\x77\x4f\x39\xb7\xc4\x03\xe7\xb8\x87\x5e\xc2\x15\x87\x7e\xfc\x6c\xc8\xea\x48\xb1\x86\xb4\x68\x21\xea\x5e\xf2\xba\x8b\xac\xd4\x0d\x79\x7e\x6a\xdd\x06\x41\x32\x83\x14\x5b\x60\x46\x2b\x35\x03\xc5\xb8\x81\xd7\x9a\x59\x29\x55\xd1\x8a\xfa\x08\x96\x9e\x31\x45\x7f\x5b\x27\xda\xec\x01\x03\x38\xed\x86\x7f\x30\x08\x78\xfd\x87\xce\x32\x18\x80\xb8\x60\xa0\xc6\x42\x84\xca\x2d\xc1\x5f\x5e\x53\x10\xe1\x0e\x6a\x73\xa7\xea\x65\x0e\xa9\xd3\x73\x69\x4d\xa4\xdd\x42\x9a\xe7\x41\x2e\xf9\xb2\x9c\x83\xb3\xb0\x68\xc7\x47\x69\xf4\x31\xce\x06\x15\xf9\xff\x4f\x82\xba\xac\x47\xb4\xbc\xe9\x04\x49\xec\x41\xc2\xa2\xd5\x73\xd9\x2b\x92\xe0\x56\x31\x48\x61\x65\xbc\x71\x0e\xf5\x84\x0f\x80\xda\xe9\xf9\xdd\x5c\xff\xd4\xeb\xf5\xd1\x07\x46\x51\x0c\x5f\xcb\xfe\x62\xcb\x97\x03\xc0\xb1\x54\xc8\x6f\x10\x81\x66\x72\x49\x76\x70\xa3\xb0\x15\x0b\xb4\xe1\xb0\x3b\x3b\xd5\x44\xc1\x2a\x90\xc3\xed\xcc\xd7\x90\x0e\xbb\x5b\x31\xc9\x11\x17\xcc\x82\x81\xa3\xc4\xed\x04\x99\x8e\x99\xae\xd4\x1b\xb4\x1f\xce\x99\x90\xa4\x06\x48\x5b\x14\xdb\xe3\xbc\x1a\x5f\xcf\x77\x19\x50\x79\x90\xda\x3b\x0b\x3c\x68\xad\x40\xd8\x95\x0c\x0d\x49\xce\xd1\x01\x93\x19\xa3\xf3\x6a\xff\x6c\xaf\x75\xd7\xf9\xa0\x93\x3d\xd3\xab\xdd\x76\x92\xa1\x56\x2f\x06\x13\xfe\x4a\x27\x8d\x5c\xe4\xc8\xda\xfb\xb5\x5b\x2e\xc2\xaf\x2b\x24\xe8\x39\x6f\x58\x7b\x17\x0c\x9c\xa6\x54\x75\x08\xfa\xcd\xe7\x34\x90\xdf\xb0\x1e\xb6\x65\x7e\x3f\x4f\x27\x23\x04\xb7\x0b\xf0\x47\xa4\x3a\x2b\x58\xe5\x56\x8b\xc5\x2b\x2c\x8d\x4c\x03\x21\x9a\x5a\x8b\xd3\xdc\x06\x43\x18\x59\x13\xc0\xaf\x74\x11\xf8\x1b\x77\xbe\x2a\x9b\xfd\x5c\xb2\x69\x77\x11\x3d\x26\x58\xa9\x71\x92\xb4\x1c\xf6\xc7\x01\x1b\x0f\xf6\xa1\x1c\xbf\xf3\x50\x55\x46\x32\x2f\x0b\xef\x60\x97\xe4\x6b\x36\x49\x2b\x01\x6a\x45\x62\xe0\x92\xb6\x7c\x3f\xcc\xc7\x78\x0e\xa2\x74\xd9\x6d\x59\x58\x49\xf7\xe2\xa5\x6d\x79\xed\xcb\x32\xd7\x84\x04\x9f\xc1\x32\x4a\x5b\xee\xfc\x24\x19\x3a\x66\xe1\xca\xc4\xa1\x3a\x81\x1b\x90\x95\x83\xcc\x91\x0c\xf0\x8d\x4b\x10\x4d\xbd\xb8\xa6\xf2\xb2\x1f\xbc\x1d\xb1\x17\x5a\x1a\x23\x56\xa6\x3d\x3e\xea\x9d\xbb\x85\x37\xd2\xc6\x86\x27\x54\x3d\xf0\xd1\xf8\xfd\x8d\x57\xa1\x8b\x0d\xbd\x69\xb9\x20\xcb\x9b\x28\x6e\x3c\x07\xae\x44\xae\x2e\x1b\xee\xc0\x1c\xee\x6b\xa9\x88\xb5\xd1\xaf\xb9\x97\x90\xb1\xdd\x91\x06\x55\xc4\x3d\x7f\x2a\x3e\xd3\x75\x4b\xa4\x65\x16\xd2\x78\x70\x55\x59\xf5\x74\x16\x22\xa9\xab\xb5\xc8\xf2\x3f\xa9\x76\xa9\xd1\x46\x94\x8a\xde\x6b\xa6\x60\x8a\x35\xe4\xe0\xd3\x30\xe8\x2e\x96\xa2\xbe\x6c\x78\xad\x0c\xd4\xd8\x70\x4e\x57\xce\xa1\x46"}, +{{0x7b,0x46,0x9d,0xf9,0xc8,0xf7,0x84,0x89,0xab,0x47,0xcc,0x70,0xa8,0x85,0x03,0xf1,0xb8,0xf3,0xd9,0x29,0xc3,0x3f,0xea,0xb1,0xc5,0x03,0xf0,0x96,0x9a,0x3a,0xc3,0x7b,},{0xa8,0x14,0xc7,0xe3,0x73,0xd0,0x11,0x3b,0x90,0x62,0x4a,0x8a,0xb2,0xbc,0xa5,0xcf,0x53,0xbf,0x52,0x8e,0x39,0xfc,0x3d,0x36,0x7d,0xe1,0x54,0xb9,0x4b,0xb2,0x2f,0x1d,},{0x18,0xfa,0xf8,0x2d,0x08,0xe1,0x06,0x8e,0x9f,0x98,0x3d,0x81,0x2f,0x05,0xfd,0xb6,0x92,0x9d,0x27,0x23,0xdb,0x1f,0x77,0xc4,0x5a,0x74,0xbb,0x09,0xcf,0xf2,0x77,0x73,0xb5,0x4c,0xe8,0xf4,0x3b,0x30,0x15,0x41,0x91,0x12,0xe7,0x25,0xea,0x7a,0xcd,0xa4,0xb2,0x3b,0x81,0x20,0xe7,0xb0,0xcf,0x42,0x01,0x53,0xe5,0xb0,0x3d,0xd0,0x61,0x09,},"\x1c\x0f\xd7\x45\x0e\x29\x67\x5c\x93\x09\x16\x38\xc2\xac\x93\x3c\xa9\x97\x76\x6e\x38\x0e\xc3\x3a\x92\xb8\xa7\xe1\xa1\xed\x98\x21\xc7\x5f\xcc\xb5\xc5\xf3\x76\x0e\x76\xd0\xe8\x81\x03\x11\xdd\xc6\x24\xea\x87\x42\x13\x1c\x1c\x43\x08\xf4\x17\x8e\x04\xd0\x49\x60\x69\x3d\x84\x6c\x1f\x51\xd8\x77\x3b\x6d\xeb\x34\x43\xd8\x74\xb9\xe2\xde\x3b\x77\x78\x51\x85\x51\x8b\x2e\x9e\xe7\x36\xc6\x3a\x39\xc8\x21\x2c\xa8\x66\x9e\x16\x1d\x13\x1b\x1a\xb2\x26\x4f\xdd\x72\xdc\x56\x28\xb1\x1c\x06\xf2\xaf\x9f\x07\x89\x04\x7b\xdd\x4e\xbb\x5d\x55\x89\x9f\x74\xdc\x4e\x12\xe7\x97\x53\x63\xf6\x3a\x8d\xa7\x6b\x55\x85\xc1\x6b\xb6\xd5\x5b\x05\xfa\xde\x87\x13\xd1\x9c\xad\x1a\x21\x16\x40\x26\x26\x91\xaa\xc9\xb4\x37\xa9\xec\xf8\x9a\x92\x46\xec\xdb\xa1\xff\x0b\xea\x78\x49\x4c\xee\x15\x29\x62\x16\xea\x6b\xb8\x82\x47\x9d\x24\x37\xc9\x49\x4a\xc7\xfa\x4f\x30\x15\xd1\xd3\x14\x9d\x55\x64\xd7\xc1\x1a\x7e\x7b\x61\x4f\x7d\x3e\x9d\x45\x4f\x0a\x05\xb0\x40\xa1\xe0\x6f\xe7\x83\x7c\x2a\x9d\xa2\x79\x4d\x91\x8b\xff\xa9\xe6\x1a\x0c\x3f\x08\x9f\x6c\x9f\x7e\xea\xc5\x86\xe3\x4b\xf9\x44\x70\xd9\x13\xda\x41\x37\x1c\xac\xdf\xc7\xee\x8b\xd1\x13\x56\x55\x56\x69\x24\xea\xdf\x09\x6a\xc0\x30\xa6\x59\x02\xc1\x03\xb1\x72\xd1\x2e\x88\xf0\x53\xfc\x56\xee\x73\xf3\x18\x70\x81\x70\x83\xaf\xa8\x02\xf7\x66\x8b\x81\x5e\xe7\x90\xf7\xd4\x0b\x43\x7a\x2e\x6d\xb2\xf0\xfb\x26\x83\x6b\x4b\x23\x31\xeb\xa5\x55\x39\x61\x4c\x0f\xe1\x72\x40\x24\x2d\xd3\xaf\x73\x83\xbc\xff\x7d\x3f\x47\xd6\x54\x4b\x08\x72\x0c\x0a\x52\x44\x1f\x74\x11\x93\x5d\xd4\xa9\x52\xd3\x86\x51\xa8\x00\x05\xfa\x3e\xb0\xea\xec\xc7\x35\xd2\x90\xe8\xbd\x5e\x31\xb7\x40\x14\x0e\x13\x6b\x2c\x00\x25\x23\xd8\xeb\x2a\x0a\xb5\xbd\x68\x70\x02\xb3\xb9\x26\xf7\x5e\xb6\x90\xd1\xda\x73\xad\x23\x58\x92\xf3\xb2\x3a\x75\x6b\x60\x5a\x43\x7c\x00\xe0\x62\x13\x04\xe8\x10\xf9\x9e\x31\x4c\x4d\x63\xe3\x22\xd9\xb6\x98\x15\xf3\x82\xff\xa1\xec\x62\x80\xfc\x0e\x64\x1c\x8a\x6f\x6f\x7f\x61\x98\x5b\xd3\x56\x7e\x0f\x44\x0d\xe9\xf7\x62\x17\x15\xda\xcd\x07\x42\x8c\x00\x90\x15\x4d\x59\xce\x6d\xb4\x01\x69\xc6\x58\xac\x5b\xf4\x4b\x67\x67\x1f\xe1\x9e\x4b\x5b\x38\xaa\xd2\xd3\xd4\xe1\x90\xa5\x50\xaa\xd4\x18\x83\x52\xf7\x98\x1a\x6d\x88\x06\x25\x02\xdf\x86\x79\x13\x50\x39\x2d\x41\xce\xfa\xcb\x24\xe3\x7b\xc7\x00\xcb\x02\x91\x90\xc3\xb1\x82\x14\x77\xe1\x17\xd5\xa4\x62\xfb\x3e\x79\x13\x3b\x10\x73\x59\x89\x66\xf5\x2b\x63\x25\x6d\xbf\x32\x6a\xce\x14\xdb\x0c\x80\x05\x8c\xf0\x0d\x68\x9a\x0a\x58\x11\x1a\xf1\x69\x27\x44\xbf\x79\x1b\xcb\xb4\x27\xa3\x72\x24\x6e\x95\x01\xa8\x5c\xd5\x20\xc6\x1a\x1e\x59\xee\x18\x0e\x8c\x97\x19\x2f\x60\xfa\x5d\x3a\xb0\x5d\xf8\xd8\x55\x1c\x1a\xc6\xca\x0a\x9a\x01\x2f\xfe\xce\xb3\xc1\xf5\x21\x41\x1e\xdb\x65\x09\xbc\x27\x8a\x65\x1e\x12\x9e\x96\xb0\xad\xc7\xae\xd7\x07\x22\x1c\xae\xac\x22\x98\x84\x41\x3d\xaa\x10\x59\x5d\x22\xd1\xdb\x70\x82\x12\x5f\x4f\x96\x95\x00\xa1\xd4\x8d\xac\xda\xe8\x0f\x40\x29\xc1\x63\xdc\xd7\x9d\xdc\x64\x68\xfc\xda\x16\x37\xb8\x7d\xdc\xf2\xa3\xd9\xb4\xd2\x99\xa0\xe5\x39\x4d\xf9\x0e\xd0\x3b\x62\x13\x7b\xa6\x7b\x9f\xea\x8a\xe1\xf0\xd2\x2f\x91\xc6\x3a\x24\xb5\x93\x4f\x74\xc2\x65\xc4\x3f\x1b\x92\x3d\xb9\x80\xad\xfc\xee\x83\x13\xda\x52\x01\x76\x73\x0e\xf9\x73\x6b\x27\xe6\xba\x32\xd1\x7e\xa6\x9d\xca\xc6\xf4\xa0\x16\xed\xfe\x2d\xb5\xa5\xbb\x3b\x64\x93\x2f\x70\x11\xf1\xc4\x53\xbb\xe8\x8b\xba\xc8\xc7\x03\x5f\x93\xfe\x39\xb5\x81\xfc\xaa\x7a\xaf\x08\x2f\xbe\xd0\x04\xfd\x1f\xd5\xa4\xe2\xd9\xc1\x97\x16\x60\x4b\x19\xce\x19\x9e\x21\x69\xa7\xbe\x51\x8d\x5f\xad\xd2\xac\x31\xb9\x54\x78\x08\x2a\xc9\x13\x06\x00\x8d\xe4\xec\x0e\xf4\xc9\xf9\xd6\xf9\x6d\x2f\x66\xd6\x2f\xaf\xc2\x19\x40\x82\x80\x8a\xf0\xd6\x7b\x9f\xba\x0d\x18\x9b\x05\x5f\x06\x1c\xca\xc2\x4b\x27\x61\x0b\xfb\xd5\xa2\x23\x2d\xd6\xf3\xc8\x90\xa9\xb1\x26\x64\x71\xb3\x22\xe9\xe1\xbf\x97\x75\x7b\xef\x72\xab\xce\xe9\x3b\x05\x1f\xc9\x23\xcf\xd4\xe7\x23\xbe\x3e\x17\x14\x3f\x38\xee\xbb\x90\x0b\x5b\xbc\xf7\x30\x47\x32\xb9\xc0\xa1\xc5\xfc\x95\x09\xa6\x93\x58\x0a\xe7\x3a\x4c\xdf\xc5\xfb\xf2\x0c\xe8\x1e\xbc\x83\x5c\x6c\x90\x9d\x83\x11\x41\xb1\x94\xf6"}, +{{0xdf,0xec,0xde,0x7a,0x56,0xa1,0x8c,0x1f,0x19,0xd8,0x0a,0x19,0xa4,0xf1,0xda,0xdd,0xd0,0xbc,0xec,0xb0,0x1e,0xec,0xad,0x6d,0xfc,0xa0,0xf9,0x57,0xa9,0x14,0xed,0x7a,},{0xaf,0xba,0xa6,0xe7,0x3e,0x85,0xb0,0x2b,0x25,0xa4,0xb5,0x87,0xec,0xb8,0xc4,0xdf,0xb7,0x9a,0xa9,0x20,0x27,0x61,0xef,0xa8,0xd1,0xdf,0x2c,0xd0,0xaa,0x63,0x16,0xc4,},{0xb4,0xfd,0xe5,0x5b,0x91,0x6c,0xf6,0x00,0x68,0xf1,0x9b,0x25,0x35,0x1c,0x14,0x10,0xdc,0xf6,0x6b,0xfc,0x40,0xf9,0x6d,0x1b,0xa2,0x36,0x8b,0xc2,0xb9,0x11,0x5a,0xaa,0x5b,0x2d,0x1c,0xf0,0xe3,0xdf,0xca,0x02,0xac,0x90,0x2a,0x94,0x3e,0x24,0x89,0xa5,0x68,0x1b,0xba,0xfe,0xd3,0x9c,0x6e,0x33,0x21,0x1a,0x9c,0xb2,0xff,0x6e,0x54,0x09,},"\xae\x6e\x8f\xf6\x5c\xcd\xe6\xf2\x64\x84\x95\x08\x26\xb4\x36\x23\x05\x8a\x5e\xfe\x02\x0b\xb1\x9b\x7d\x8b\x4e\x25\x76\x8b\x69\x27\x34\xfe\x07\xc9\x13\xb9\xe8\x81\x26\xbe\xcb\xf1\x4a\x0f\xd0\x20\x5b\x39\xfc\xc2\xae\xc3\x73\xf8\xc1\x84\xc6\xa9\xbb\xbb\x84\x44\x9a\x7c\xa3\xb9\x20\xad\xa0\x88\x01\xdf\xc6\x6f\xf1\x9a\xeb\x92\xf2\x55\x53\x99\xa4\x30\x27\x7a\xe2\x2d\x23\x75\x4e\xaa\xce\x3c\x73\x84\x67\x97\x53\x6d\xd7\x1a\x56\xf4\xb5\x84\x2c\x0f\x41\x0d\x19\x89\xac\xac\x5d\x80\x5d\x26\x57\x2c\x0f\x3a\x64\xdd\x20\x71\x66\x22\x12\xd5\x2f\xe9\x9e\x59\xd9\x66\x04\x77\x77\xf9\x03\x0f\xa4\xfd\x2e\xe7\x4b\x7a\x7c\x9f\x7c\x34\xa6\xdc\x7e\x03\x59\x3a\x13\xd6\x4c\xe6\x24\x53\xee\x3c\xa3\x0d\x84\x67\x28\x39\xf1\x9f\x1c\x15\xd0\xc4\x5d\x27\x55\xbb\x39\x4a\xcf\x4d\xcb\x7f\x7f\x07\x11\xac\x40\xea\x46\x61\x2e\xa3\x7a\x76\x07\xad\x32\xe8\x18\x26\x5f\xab\x19\x33\xf5\x09\x4e\x2d\x03\xbc\xfa\xa5\xf6\x16\x67\xf3\xb3\x7f\x00\xc4\xc5\x8d\x9b\x41\xb9\xaf\x39\x00\x48\x2b\x0f\xfb\x4f\xa4\x37\x6a\xa0\x40\x00\x9d\xec\x2f\x45\x25\x79\x9c\xb0\x05\xf3\x9d\x74\xcb\x2d\x8d\xce\x8c\x20\xc2\xc3\xf5\x40\x97\x03\xaf\x15\x6c\xfb\xa2\x8a\x9d\x91\x64\x39\xcb\x29\xf8\x3d\x24\x29\xce\x62\x23\x51\x9e\x75\xe1\x5c\x7c\x7f\xa2\x15\x11\x9e\x07\x3f\xa7\x97\x4d\xb1\x4f\x7a\x01\x09\x3f\xaa\x94\xad\x52\xab\x1e\xad\xce\x1a\x89\x36\x6c\xa1\x3a\xdb\x89\x06\x64\x38\xa2\xbe\xb7\x30\x34\x17\x0a\xa4\x2d\x9c\x2d\xdb\x97\xc1\x4a\x17\xc3\x09\x43\x76\xd2\xa3\xff\xd8\x09\x5f\xc4\x05\x3d\x91\xd1\x6e\x06\xd2\x76\x93\xa1\x31\x0f\x01\xa7\x51\x11\xcf\xed\xa8\x92\xc3\x97\x2a\x13\x3a\x09\xad\xda\xa8\xf7\x41\x45\xf8\x86\x81\xb6\xd2\x77\x96\x4b\xfe\x38\x55\x1a\x2c\x61\x9f\xa3\xca\xe3\x94\xac\xb2\x9c\x94\x10\xb4\x5e\x10\x1b\x17\x40\xe8\xb2\xaa\x6f\xeb\xc3\xa4\x5d\xad\xb9\xd9\x58\x9d\x59\x7e\x57\xcd\x94\x7b\x68\x4c\xc3\x55\x24\x6c\xe6\xc3\x26\xdd\x98\xcf\x92\xb6\xee\xa3\xba\x5a\xb0\x37\x00\x62\x26\x36\x32\x4d\xc1\x22\x2c\xd7\x48\xfa\x07\xbf\xd3\x9a\x1e\x06\x98\x09\xe5\x67\x14\x1a\x61\x3e\x2e\x8b\xe9\xdd\x39\x8a\xb6\xbe\xaa\xfd\x85\xff\x36\x28\xee\x2a\xa3\x2d\x0a\x57\xbb\xac\xf9\x56\x19\x0b\x5c\x42\x42\xeb\x5b\x85\x87\xd2\xfd\xcb\x07\x41\xb9\x41\x6a\x05\xf5\xfe\xcb\x1f\xb2\xd6\x47\x88\xdc\xe7\x83\xc1\xf6\x3e\x60\x64\x1f\xce\x5e\x1d\x2b\x18\xa9\x50\x0c\xd6\xa1\xfd\x33\x5c\xc1\xdb\x46\xef\x04\x75\x2b\x2d\x22\x07\x2e\x6d\xfc\xfc\xfa\x56\x9b\xb2\x5e\x45\x7a\xfe\xb6\x3a\x4f\xbe\xdc\x29\x3a\xd9\xd1\xab\xa4\xe3\x94\xaa\x10\x97\xe1\x2b\x0f\xc9\x0c\x89\xf7\x6d\xf0\xd6\x44\x1f\xa9\x98\x08\xb6\x0b\xe0\x7d\xfc\xc7\xf9\x01\x0b\xbf\x90\x33\x55\x6d\x5e\xe2\xd4\x48\x93\x7b\x78\x34\x93\x92\x0f\x68\x1e\x4d\xa7\x08\x67\x10\x97\xe1\x99\x48\x1b\x8e\xf0\xe0\x15\x0d\x7c\x28\x51\xdf\x44\xc5\x45\x12\x2f\x9b\x0e\x5b\xa2\xee\xff\x2d\x98\x8d\x56\xd9\xbb\xb5\x5d\x98\x96\x11\x11\x51\xa4\x36\xaf\x06\x5e\x0c\xad\x17\x8a\x2c\x9f\xa8\xf6\x97\x4e\xcd\xf0\x9a\xdf\x01\x33\x00\xcf\xfe\xda\xf4\xb8\x79\x1b\x46\x7b\xa7\x93\x3a\xda\x5d\x63\x2d\xb4\x4e\xd6\xdc\xf2\xaa\x64\x89\x17\xbe\x63\x37\xd2\xe2\xd2\x06\x85\x6d\x08\xf9\xee\x7b\x5e\x2f\x14\xdd\xc6\xd3\xac\x42\x92\x15\xa8\x79\x23\xad\x32\xd5\xdc\xfe\xe3\x68\x63\x16\xdd\xd1\xb2\x7b\xb1\x93\xa5\xfc\x05\xc8\x93\xa9\x39\xa5\xb9\x89\x87\x36\x6c\x82\x9e\x39\x2f\x48\x5e\xa1\x5e\x22\xcd\x8f\x85\x7a\x13\x4a\xfa\x98\xf3\x72\x15\x57\x6d\xdc\x5a\xab\x4f\x2d\x10\xca\xaf\x05\x00\x59\xa3\x35\xf2\x4b\xcd\xcb\xac\x81\x9f\x66\xdb\x07\xaa\xbd\xfb\x76\x27\x1d\x17\xbc\xe2\x2c\xba\x46\x3a\x80\xaa\x89\x2d\x0d\x8e\x05\x5f\x94\x8d\xf7\xf6\xe6\xc3\x00\xda\xef\xfd\x3a\x23\x6d\xdd\xcf\x23\x8f\xe1\x06\x66\xa5\x7c\x6e\x3a\xe7\xe3\x67\x3d\x35\x57\x8f\x8b\x8e\xa6\x9d\x3c\x08\xe0\x14\x0a\xfd\x3e\xe0\x30\xb2\x2a\x37\x21\x60\xf9\x08\xa3\x78\xf8\x10\x1b\x5f\x59\x69\xfe\xa3\x10\xee\xd3\x7a\x00\xd9\x73\x02\xd5\xc2\xdb\xe8\xcc\x60\x00\x75\xdc\xcd\x33\xad\x63\xd2\x65\xaa\xf6\x0e\x24\x1c\xe3\x11\xbe\xd7\xdd\x5e\x27\x45\x24\x1a\xe0\x2a\xe5\x32\xd1\x5c\x18\x88\x6e\x81\x81\x38\x75\x1a\xfc\x51\x85\x0e\x50\x6c\x6d\x31\xa8\xee\xf4\x51\xad\xfd\x4b\x3d\x26\x6b\x41\x5a\x7e"}, +{{0x07,0x82,0x8c,0x58,0x0e,0xbf,0x9e,0x1d,0x82,0x5a,0x59,0xc3,0xbf,0x35,0xf0,0x72,0xae,0x12,0x33,0x55,0xbd,0xcc,0x24,0x9e,0xec,0x7f,0x2f,0xc5,0x75,0x5e,0x29,0xb5,},{0x58,0xe5,0xed,0x85,0x10,0x0b,0xbd,0x9b,0x22,0x21,0xaf,0xc9,0xc9,0x31,0x84,0x33,0x0a,0xd5,0x9e,0x13,0x85,0x60,0x62,0x44,0xbf,0x00,0x3b,0x8d,0x20,0x18,0x50,0x1b,},{0xbb,0x09,0x36,0x04,0x39,0xa8,0x2d,0xee,0x5c,0x7d,0x85,0x77,0x9e,0x54,0xc1,0x3f,0x88,0xe0,0x6d,0x38,0xf4,0xb9,0x49,0x60,0xfe,0x17,0xa1,0xeb,0xca,0xa3,0xee,0x2f,0x33,0x0c,0x64,0x91,0x54,0xbb,0xc8,0x75,0xa4,0x07,0x6c,0xf0,0xbb,0xf7,0xee,0xbf,0x7b,0x8d,0x08,0xd5,0xaa,0x4b,0xe7,0x41,0x38,0x81,0x24,0x5f,0xc2,0xd2,0xb6,0x01,},"\x0e\xda\xd5\xca\xe6\xed\x98\x43\xe9\x1c\x50\xd9\x34\xcf\x55\xdd\x65\x8f\x3d\x25\x20\x39\xcd\x6c\x75\xbe\x4f\x6b\x86\x6f\xb7\x5f\x35\xc8\xf9\x8f\x17\x21\xd7\xe6\xd9\xd9\x8a\x22\xe0\xb4\x93\x4d\xcc\x12\x92\x61\xbf\x67\x23\xb2\xfa\x7a\x99\x5e\x35\xc4\xbd\x79\xc5\x81\x6a\x32\x16\x07\xd9\xdc\xce\x39\xfe\xfa\x1d\x55\xde\x4e\x76\x17\x54\x8e\xc3\x85\xc3\xde\x01\xe3\x66\xbf\x50\xc4\x57\xa5\x55\xe9\x32\x07\x0e\x2a\x5a\x01\x97\xb7\x9e\xfb\xe7\x00\x6f\x0c\xec\x78\xb6\x0e\xbb\x8f\xa8\x78\x1d\x8e\xb7\x32\x6e\xdc\x30\xe6\x2d\x32\x97\xa1\xe0\xa1\x11\x71\x08\xc4\x6e\xe5\xdb\xef\xc6\x59\x42\x89\x33\x5e\x78\x0d\x55\xa0\x84\xf5\x52\xda\x3f\x36\xd3\xc4\xc6\x17\x8b\xa7\x4d\x4d\xec\xef\xc5\xa3\xb8\xc4\x7c\x16\xf5\x34\xbd\xb6\x08\x95\xd3\xd5\x4c\xd2\xbb\x26\x6b\x39\x9e\x4d\x4f\xb4\x8d\x7a\x8c\xde\x17\xf4\x24\x12\x56\x07\x37\xd3\xc0\x6e\x29\xdf\x52\x4d\x0c\xbd\x30\x93\xef\xca\x1c\x8f\xed\xca\xa1\x24\xab\xb2\x7a\xbd\xac\x6a\x29\xe0\xe8\x24\x6a\xbd\x6f\x5f\x53\x19\x50\x03\x7f\x76\x32\x3a\xa5\x6c\xc3\xfe\xfa\x60\x30\x41\xd5\x5f\x19\x29\xe2\x77\xe7\x2c\xda\x1f\x96\x54\x1d\x2a\xf3\xe9\x0c\x0f\x0e\x28\xbe\x19\x6d\x8f\x69\x21\xf3\xcd\x57\xa7\x92\x6b\x86\x0a\xa1\xbc\x40\x35\x76\x89\x2a\x96\xb9\x31\x90\xae\x38\x3f\x63\x1b\x72\x80\x26\x58\xb2\xe8\x45\x1d\x52\xa2\xf4\x5d\xb4\xf8\xbc\x3b\x0e\x4e\x50\xb6\xd6\x03\xa5\xbd\xd3\x0c\x23\x42\x00\xad\x7d\xeb\xb9\x63\xf5\x8a\x4f\xa2\x03\x30\xb3\x69\x64\x49\x44\x5a\xa3\x71\x82\x48\x42\xfb\xf3\x26\xd9\x01\xdf\xe3\xbe\x04\x54\x52\xa3\x74\x0d\xd1\x60\xe7\x27\x33\xf6\xe2\x73\x35\x25\xa2\x9a\x86\x5f\x6f\x50\xd5\x3b\xf7\x19\x1c\x59\x9c\x87\x6f\x5c\x9c\xa1\xe3\xfa\xd7\x96\x06\x48\xe0\xd4\x71\xf7\xd5\xc0\x1c\x67\x3f\x42\xd6\x59\xbc\x3d\x98\xdb\xf0\x7d\x8f\xeb\xfb\x99\x5d\x17\xf9\xa0\x2c\xd6\xc3\x9f\x2d\xdc\xd0\xf1\xd2\x22\xb9\xe1\x1f\x2d\xd7\xd3\xc7\x51\x82\x24\xbb\x6b\xfb\x8b\x7c\x58\xfe\x8a\xc1\x05\x40\x59\x03\xa1\xb9\xda\x75\x16\x71\x5b\x7a\xfc\x38\xa5\x55\xe6\xbb\xcd\xba\xd4\x6e\x34\xe5\x76\xfe\xa3\x4c\xe3\x57\x34\xed\x20\xaf\x5d\x88\xee\xb1\x04\x7a\x26\x60\x64\x8b\xbb\x11\x3a\xd9\xdb\x8c\x53\xed\xb6\xed\x98\x71\xa1\xe4\x4c\x9e\xd2\xdf\x56\x56\xfb\x2b\x28\x06\xec\xf0\x3b\x1e\xca\x9e\xab\x50\xa6\xea\xab\x55\xb9\x33\xb2\xdd\x1f\x21\xd4\x50\xde\x9d\x5c\xb2\x23\x2f\x07\xa3\x92\x08\x1b\x0b\x4b\x88\x5d\x54\x78\x9e\x2f\x75\xbf\x2c\x4c\xda\xd8\x78\x98\x9b\x1d\x6d\xab\xd9\xed\x23\xc7\xc5\xb0\x35\x6a\x7d\x9e\x73\x35\x29\x0d\x7c\x85\xb9\x66\xe8\x01\x84\xbd\x07\x99\x86\x02\x88\x6d\x70\x76\x19\x35\x65\xc8\x1c\xcc\xda\x4c\xc7\xd3\x3c\x85\xd9\x05\xb1\xbe\xb6\xe8\xe7\x41\x8e\x8a\xca\xed\xf0\xd9\xa3\x2a\x7d\x29\xd0\x7c\xf4\x4d\x31\x19\xd4\xe7\x89\x68\x20\xb7\x7d\xe6\x4b\x65\x5e\x4f\x14\x88\x00\x43\x4a\xf7\xbd\xb2\xa5\x6b\x25\xeb\x94\xea\x39\xf2\x16\x95\x96\xbb\x2b\x11\x76\x1f\x08\x2b\xae\xc0\x88\x85\xf4\xa0\xeb\x6c\x95\x76\x71\x35\xa7\xf7\xcd\x72\xe7\x43\xd2\xdf\xf1\x44\xdd\x8b\xaf\xb1\xb3\x18\x00\x6e\x58\x76\xf8\xe2\xcb\x44\xaa\x58\x8f\x90\x62\x66\xac\x67\x11\x9c\x17\xf5\xde\x11\x4e\x72\xe4\x2a\x1f\xb3\x99\x44\x32\x1a\x11\x1f\xa7\x95\xff\x70\x17\xf2\xfb\x8c\xaf\x48\x2f\x55\xd7\x7a\x80\x85\x54\x28\xde\xd7\xec\x20\xac\xec\xca\x83\xf8\xd1\xeb\x13\x7b\x58\x8c\xcb\x74\x5c\x10\x5f\x2b\x2c\xa4\x1c\x3a\x9f\x49\xd3\xc6\xe9\xd7\xc6\x48\xb0\x03\xb9\x70\x7c\x90\x64\x62\xed\xad\x61\x7a\x8c\xfb\xf9\xbc\xc6\xc5\xfb\x6f\xa9\x84\x32\x5d\x65\x82\xe2\x8f\x62\x00\x53\x83\xf3\x38\xdf\x5b\x38\xfa\x9d\x19\xc2\x2a\x2a\x7e\xa1\xd6\x8a\x92\xd1\xd9\x3b\x7f\xb0\xb8\xf3\x3b\xc8\x76\x0f\x28\xae\xb1\x43\x9a\x8b\x07\xf3\xda\x58\xdd\xb1\x55\xb4\x98\xcb\x09\xc7\x5a\x55\x96\x83\x8a\x65\x01\x3e\x24\xd5\x64\x0d\x08\x42\xa7\x69\x93\x22\xcf\x3f\xfc\xb5\x70\x3f\x41\x4f\xfd\x16\x88\x60\xba\xd3\xe3\x08\xb2\xb5\xbf\x3c\xdf\x7f\x36\x3b\xf9\xaa\xf4\xb3\xbc\x42\x4c\x14\x6c\x6f\x54\x21\x43\x0f\x9f\x47\x6a\xa3\x4a\x0c\x6e\xe8\x01\x31\xfc\x4d\x4d\x97\x07\x23\xa2\x18\x6a\xe3\x62\x5e\x28\x6d\x17\xdd\xdc\x43\x5c\xcb\x00\x83\x16\x78\xab\xa5\x84\xa6\x2d\xbf\xf0\x02\xbe\xad\x6e\x11\xe2\x3c\x54\xd3\x3c\xf3\xa4\xb2\x31\xa9\x08"}, +{{0xf0,0x8e,0xe8,0xda,0xa7,0x3e,0x1f,0xeb,0x61,0xa8,0x8e,0x06,0x2d,0xfb,0x10,0x03,0xc8,0x57,0x8a,0x0d,0x53,0xbd,0x3b,0xc9,0xe5,0x89,0xef,0xb9,0x2f,0x68,0xbe,0x14,},{0x76,0x69,0x2c,0xe8,0xd1,0x16,0xec,0xcb,0x89,0x70,0x77,0xed,0xca,0xaf,0xdd,0x3e,0xb4,0x4e,0xa1,0xa4,0x86,0xb9,0x0e,0x49,0xe9,0x7f,0x96,0x69,0x01,0x01,0x55,0x02,},{0x66,0xdf,0xa4,0xc1,0x57,0x5b,0xef,0xf2,0xf5,0xa2,0x30,0xb2,0x8c,0x58,0xc3,0xee,0xa0,0x73,0x6d,0xf3,0x79,0xd7,0x55,0x59,0xbc,0x9d,0x37,0xa9,0x57,0x9d,0x12,0x1c,0x05,0xc3,0x73,0xe8,0x48,0x4c,0x97,0x47,0xef,0x44,0x77,0xe8,0x0c,0x4b,0x2c,0xb4,0xdd,0xf1,0x6a,0xe9,0xfd,0xfa,0x08,0xa0,0x75,0x47,0xd1,0x07,0xdc,0xea,0x12,0x03,},"\x64\xde\x90\x04\x4d\x0e\x76\xbc\x02\xfc\xff\xcb\x75\x26\x36\x67\xb3\xbd\x73\x3b\x40\xbf\xb2\x6c\x6c\x52\xfd\xb4\xb0\x78\x22\x78\xca\xba\xe4\x1e\x21\x29\xea\x40\x17\xe9\x4d\xe8\x60\x87\x96\x4f\x66\xd8\x62\x07\x98\x74\x67\xa1\x68\x8f\x9f\xab\x3f\xfb\x2f\x1d\x00\x63\xbf\x62\x6c\x94\x13\x67\xc1\x2e\x31\x9a\xb7\xca\x30\x20\xc9\xb3\xa7\x21\x5a\x19\x30\x3e\x2d\x0e\x89\x88\x79\x1d\xe0\xd8\xe1\x63\x2d\xaa\x38\xc7\xf3\xe7\xf6\xe4\x8c\xe1\x22\x14\x3d\x1e\x2c\xb6\x61\xba\x77\xc6\x9e\x6a\x71\x09\x11\x64\x4b\xc1\x10\xff\x58\xbb\x00\xb5\x29\x08\x20\xce\x30\x97\x0e\x7f\xde\x18\x9e\x14\x0e\x5c\x70\xc7\x83\xee\xd5\x3f\x0e\x2a\xc7\xec\xae\x4f\x27\xdb\x81\xd1\x5b\x86\x46\xfa\xa9\xc5\xa3\xae\x2b\x7f\x47\xcd\x58\x0d\x77\x07\xb0\x02\x49\x9b\x4c\xfe\xb8\xc5\x91\xaf\xdf\x1c\xc6\x2a\xf2\x59\x5c\x18\x4a\xbc\xf0\xb2\x62\x3a\x1b\xae\x60\xaf\x70\x26\xb2\x8d\x05\x40\xb4\x15\x26\xe3\x02\x0f\x81\xb8\x94\xeb\x3f\xe3\x1b\x72\xb2\x1a\x32\x60\xda\xe3\x21\x0c\x4c\xe4\xfd\x69\xe2\xe5\xea\x0c\x86\x32\xa5\x83\x26\x2a\x12\xb3\xa8\xb1\x6c\x9c\x12\x06\xad\x73\x02\x30\x37\xcf\x30\x65\x3c\xb8\x0a\xa7\xdf\x83\x14\xb0\xf5\xbc\x6e\x9d\x5f\xa0\x0b\x00\x9d\x55\x52\xd8\x3b\x79\x70\xb5\xbc\x4b\x99\x84\xf6\x9d\x1c\xca\x9c\xe4\xcb\x74\xdd\xd2\xd8\x79\xd3\x73\x12\xa0\xe1\x59\xd7\xa6\xaf\xb7\x7a\xc5\x85\xe6\xb4\x59\xc5\x51\x30\x4e\x1e\xeb\xfb\xca\xb4\x3a\x10\xb5\x05\x92\x4e\x03\xea\x33\x2f\x5d\x02\x0a\x55\xc7\xaa\x68\x3c\x54\x1d\xcf\x77\x90\xa2\x40\xaf\x07\x9b\xab\xa9\x40\x96\xb4\x60\x60\xfd\x7a\xfe\x90\x56\xca\x99\xe6\x88\xdf\x28\x0a\x9b\xe8\xc8\xc7\x3e\x6e\x6f\xb0\x52\xa3\x3e\xb3\x32\x8a\x7f\x60\x25\x42\xfe\x28\x0c\x89\x0e\x3c\xca\xf2\x2c\x7f\x34\xf8\x7b\x5e\x5b\xa7\x84\xb4\x72\xb1\xe1\xa9\x93\x47\xa9\xe0\xd2\x40\x85\x8d\x12\x77\xa5\xc6\xb3\x49\x38\x3f\xe4\xfd\x55\xcf\x92\xe6\x9f\xaa\xd3\x26\xb8\xd6\xdb\x46\x23\x30\x26\x22\x1e\xe6\xd0\xa1\xc4\x24\x65\x33\xc4\xa0\xe5\xbd\x17\x2e\xb8\x93\x6a\x9c\x0d\x30\x06\x65\x38\xe3\xeb\x4a\xd5\xcb\x98\x77\xfd\x86\x1b\x48\x2b\x30\x15\x0a\x06\x10\x41\x61\x64\x7e\x01\xd0\x04\xd9\x97\x40\x3e\xe0\x67\x26\xcb\x97\xe2\xe2\x5f\x18\xc6\x68\xee\xe4\xc5\xbf\x72\x52\x98\x03\x18\x9e\xe6\xa7\xae\xc2\x38\xd5\x90\x6e\xa5\xae\x10\x72\x2c\x9a\x61\xa7\x8a\xea\x52\xaf\x33\xea\xac\x75\x40\x6b\x1a\x60\xbe\xfb\xaa\xd4\x84\x76\xd9\xff\x88\x7f\xd2\x83\xeb\x16\x55\xbc\xc0\x7c\xf7\x53\x33\x14\x36\xdb\x5b\x3b\x13\x03\x2f\xf9\xc3\xd6\x96\x38\x0e\x9f\x5a\xbf\x50\xd3\x55\x6f\xda\x0d\xf0\xb5\x38\x97\xa7\x37\xac\x7a\x3b\x87\xc2\xa8\x32\xb0\xc7\x27\x3e\xa9\xfc\x54\xa7\x67\xf1\xa8\x12\xbf\x01\x64\xbf\x75\x21\x63\x0b\x81\xb9\xdd\x93\x0d\x92\xee\x2c\xa2\x8e\x32\x03\xb7\x7b\xc0\x82\xce\xb3\x7d\x55\xed\xbc\xb7\x1d\xf0\xb7\x92\x36\x78\x9a\x25\xd4\x18\xcb\xb9\x55\x44\xe2\xce\xf3\x3b\xbd\xeb\x27\xa3\xf7\x90\x9c\x1f\x49\x8f\x47\x13\x5a\xe9\x03\x3a\xdf\x25\x0a\xd4\xf6\x57\x53\x61\xe4\xcf\xcc\x9b\xcf\x4b\x90\xc3\xad\x47\xa3\x44\x22\x97\xa2\x23\xcc\xa8\x43\xd7\x20\x5e\xd0\x8a\x9b\x87\x16\x0a\x6d\x01\xb4\x6a\x7d\x1c\x84\x4e\x8d\x1f\x18\xf6\x18\x68\x2b\xfb\x22\x95\x5f\x39\x5b\x2a\x57\x90\xa5\x1a\x69\x64\x99\xd9\xe7\x1a\x50\x1f\x3f\xa5\x46\xde\x9b\x10\xae\x47\xbc\xee\x42\xba\x7f\x86\x9f\xb9\xce\x4e\xd7\xc6\x45\x33\x26\xc0\x34\xcf\x05\xd9\xf1\xe3\xc2\x00\x70\x1b\xa7\x52\xda\xbb\xd8\x68\x52\x1c\x3d\x8f\x80\x67\x2d\x42\xf6\xcf\x45\x64\xf0\x8c\xd7\xb3\x90\xe6\xd4\x9d\xd9\x00\x90\xaf\xdb\x84\x48\x6f\xfc\xaa\x4e\x84\xd8\x86\x82\x74\x4d\xc0\xa8\x78\xfa\xa7\xcd\x44\x0a\x8b\x27\x67\x10\x90\x20\x81\xf4\xdc\x84\x17\x46\x19\xa6\x6e\xa3\xa3\x71\xf9\x55\x05\x40\x0d\x99\xfa\x99\x90\x17\x71\x0c\x8e\x27\x14\xbe\x60\x94\x9d\x46\x13\x10\xf7\xd4\x3a\x0d\xc1\x23\x51\x6d\x77\xd3\x62\x21\x3f\x9f\x75\xa5\xa1\xc3\x93\xaf\xfc\x49\xea\x15\x1d\x46\xa8\x1f\xfa\xd2\x39\xf2\x8c\x07\xf6\x5f\x59\xea\x07\x7d\x9a\x4d\x9c\x75\x2d\xe4\x9b\x9e\xf3\x6b\xe6\x0d\x11\x2d\x79\x5f\x58\x8b\x00\xef\x6e\x77\x30\xde\xa6\x5e\x10\x16\xda\x0d\xd4\x62\x37\x0e\x0b\xa5\xc6\x60\x00\x1e\x45\x7c\x08\xb4\x36\xda\x29\x03\xb6\x29\x06\x93\x20\x84\x72\x8c\x81\x67\x1c\xbf\xb0\x79\xbb\x29"}, +{{0x27,0x2d,0x64,0xde,0x50,0xb1,0x31,0x2b,0xee,0x23,0xd7,0xf4,0xce,0xa5,0x08,0xa8,0xfc,0xcf,0x3e,0x9b,0x32,0x4e,0x97,0xb1,0xc8,0xe7,0x25,0x02,0xf6,0x1f,0xbf,0x45,},{0x33,0x49,0x8c,0x3b,0x71,0x2a,0xb9,0xc0,0x1e,0xc7,0x6b,0x2e,0xfe,0x2b,0x83,0xad,0xd1,0xe1,0xf2,0xb5,0xeb,0x78,0xf2,0x16,0x92,0x32,0x34,0x51,0x82,0x0c,0xbe,0x10,},{0x33,0x81,0x4c,0x6e,0xf3,0x75,0xab,0x96,0x37,0x69,0xb2,0xde,0x4a,0x25,0xe7,0x02,0x0f,0xcd,0x97,0xf7,0x8f,0x8f,0xc9,0x34,0x55,0xc4,0xb1,0xc2,0xbd,0x45,0xd4,0xb0,0x1e,0x19,0x29,0x00,0xe3,0x12,0x22,0x65,0xfc,0x55,0x2c,0xd5,0xc5,0xf0,0x0e,0x93,0x1e,0x3a,0x18,0x3c,0xca,0x5b,0xa0,0x80,0x2d,0xaf,0xde,0xbb,0x79,0xeb,0xeb,0x03,},"\xd6\x26\x0d\x7e\xec\x5d\x43\x62\x08\xe7\xe7\x37\x65\x5e\x09\x71\x81\x42\x70\x19\x44\x05\xe3\x6e\x39\xf8\xf1\x7b\x64\x9f\xbc\x16\xc0\xf3\xd7\xf2\xbe\xf5\xeb\xc0\x2b\xb1\xc4\xdf\x48\xe8\x47\x0a\x3e\xae\x8a\x3c\xca\xf6\x40\xab\xcc\x09\x4a\xa9\x11\x50\xff\x1a\x8c\xf1\x16\x96\x93\xeb\xf5\xac\x00\x34\xb9\xb9\x19\xec\xf1\x7d\xb7\x91\xdf\xe5\xfe\xdc\x90\x91\x8b\x23\xe5\x4e\x90\x04\xa1\xae\x77\x1c\x21\x3e\xd7\xed\x73\x34\x43\x4e\x5b\xc0\x2c\x0d\xda\x2b\xd1\xa8\x76\xfb\x82\x4a\x19\x7b\xc9\x96\x13\xb1\x40\x9e\x70\x52\x31\x0b\x08\x20\xda\x71\x44\x69\x29\xae\x7c\xfd\x3a\xfb\xa0\x42\xde\x54\x57\x8a\x5b\xfd\x94\xc1\x54\x43\x91\xa3\xd9\xac\xbd\x56\x63\xef\x65\xc6\x92\x0d\x78\x51\x6d\xec\x1c\xd5\x5f\x6e\xb7\x29\x0b\xa0\xaa\xf9\xa1\x71\x65\x82\x00\xb2\x4a\x47\xa0\x71\xb9\x6f\xea\x03\xc6\xca\x7e\xd0\xd6\xfe\x67\x5d\xd6\x37\x61\x83\x3d\x75\xbc\x5e\x58\xa9\x58\x58\x2d\xb0\x2a\x60\xc6\xce\x0a\x63\xf4\x2b\xa8\x37\xae\x77\xc1\x7a\x32\x70\x5f\xd9\xca\xfa\x58\x7b\x55\x5d\xd4\x61\x98\x51\x07\x97\x94\xe2\x4e\xb4\x46\x08\x83\x5a\x6f\x48\x24\x92\x0d\x57\x7a\x27\x03\x96\xc9\x57\x3b\xc7\xd8\x2f\xe2\xaa\x04\x65\x95\x66\x13\xa2\xc5\x08\xcf\x24\x32\x33\x7a\x36\x5e\x6c\x98\x4c\xba\x91\x7f\x0c\xf8\x42\xaf\x12\x2d\xc8\x9d\xea\x95\x8d\x41\x8c\xae\x44\xa6\xe4\xed\x26\x3a\x41\x5f\xf9\x94\xa5\xff\xb2\xff\x13\x91\x3d\xf2\x14\xbb\xfe\x90\xa3\x4b\x24\x7e\x71\xab\x73\xf7\xff\x00\x4c\x23\xac\xfd\x90\xc7\x67\x61\x1a\xa5\x58\x14\xc6\x69\x64\x16\x8e\x56\x8b\xa7\x5b\xf3\x49\x03\x59\x7c\xdc\xac\x78\xc2\x4b\xb9\xf1\x4f\x5c\x86\xa5\x1f\x36\x4f\x9a\xb4\x1e\x46\x4a\xee\x64\xfa\x50\xa1\xc1\x59\xcb\xd8\x50\x83\x2c\x50\x4a\xb4\x2a\x58\x4a\x96\xd5\xae\xe0\x82\xd8\x2c\x1e\xdd\xa1\x93\x38\x16\x0b\x8d\xcf\xa3\x41\x9b\x3a\xf6\x4d\x9c\xfb\x10\x4f\x98\xf9\xd3\x5e\x53\x94\xe2\x32\x28\xe2\x75\xc8\x7d\xb5\x0c\xa8\x67\x54\x0b\x88\x0c\x7a\xf2\x9f\xbf\x53\x42\x94\x58\x1c\x22\x24\x0b\xcd\x4d\x7d\x2c\x20\xff\xc3\x67\x33\xad\xa2\x76\x53\xd3\xae\x1a\x8c\x22\x03\xea\xc6\x26\xe2\xe9\xbb\x4b\x52\xce\x52\x3e\x5a\xdb\x3b\x2c\x10\xdc\xf7\x8c\x2a\x1e\x62\x6a\x16\xeb\xfa\x1b\xdb\x8c\x16\x14\x93\xa5\xaa\xa2\xd8\x4b\xfa\xa0\xf2\x02\x7f\xfe\x4e\x9e\xae\xb3\x32\xeb\xda\x7c\xbb\xb6\x77\x76\x9d\x78\x51\x7a\xdf\x72\xf8\x23\xa7\xf8\x44\x16\x5a\x07\x98\x78\xd2\x58\xfd\x95\x22\x5c\x21\x17\x78\x37\xe6\x9c\x19\x68\x5a\x05\x1c\xa9\x2b\x12\x0b\x7d\x86\xd7\x85\x95\x47\x1f\xfc\x42\xa5\xe6\xe6\x43\x1b\xe7\xb6\x4f\x80\x76\x45\x8b\xac\xd6\xc7\x29\x03\xcc\x34\xfc\x63\xa4\x0c\xf3\xdf\x00\xef\xf9\xd6\xee\x9a\x8f\x39\xd2\x5e\xad\x81\xa8\x12\x88\x88\xb0\xa1\xac\x0e\x5e\x3a\xd9\x27\x71\x2c\x14\x14\x6a\xdf\x82\x87\x70\xff\x95\x87\x09\xeb\x19\x28\x8e\x77\xbb\x70\x73\x48\x81\xe9\xe0\x16\xcd\x29\xe7\xd0\x89\x93\x41\xff\x6b\x29\x7a\xc7\x96\xbb\xde\x48\x6e\xc3\x59\x49\xf6\xa3\x2b\x2c\xa6\x47\x38\x59\x15\xec\xba\x3b\x9f\x02\x25\x08\x71\x45\xc1\x8d\x65\x59\xd3\xa3\x1d\x6f\x22\xfc\x49\xf8\xa6\x31\x5f\x1d\x32\xab\xee\xb7\xcf\x2c\x2c\x77\x6e\xa7\x35\x0f\xd5\xeb\xc0\xe0\xf2\x65\xba\xcc\xc2\x69\x7a\x7c\x8c\xa4\x0c\x13\x5f\x6c\xfc\xb0\xb5\x8a\x61\x43\x19\x60\xff\xa9\x06\x57\x09\xa9\x61\xa6\x33\xd5\x70\xb7\x3f\xb4\x49\x1d\xe5\x2a\xd0\xd7\xb2\x04\xb6\xe9\x97\xb0\x37\xed\xe3\xf7\xec\xa8\x20\xa7\xcd\xb2\xc6\x9a\xc2\x91\x48\xbe\x35\x23\x50\x8a\xe7\xe4\xc3\xd1\xa7\x17\xf5\x5a\x82\x1d\x14\xc3\xb6\x4f\x08\xca\x9a\xe4\x96\x13\xb1\x15\x77\x3e\xf6\x18\xd3\x21\xc9\x08\xbd\x21\x56\x71\x7a\x43\x4e\x50\x89\xa5\x94\x8c\x04\x5c\x8d\xa8\xa4\xbd\x86\xed\x5f\xab\xc6\xb1\x34\x66\xe6\xde\xda\x58\x32\x07\xd2\xad\xa2\xb2\xab\x9c\xb1\x54\x3d\xf7\xa3\x73\x4d\xfb\xc6\xfc\x42\x81\x06\xd4\x84\x47\x24\xa1\x3d\xf4\x2f\xaa\xb1\x8c\xa8\x9d\xb2\x0a\xc9\xbc\x27\xb8\x53\x94\x66\x7c\x5a\x27\x79\xca\x63\xed\x7a\xc2\xb7\xc0\xd4\x12\x23\x91\xee\x46\x02\xd6\x1e\xa0\x38\x17\x64\xfb\x72\xdc\xc2\x24\xe6\x5e\xae\x2b\xc4\x50\x6b\x0f\x09\xe2\x32\x05\xd0\xbb\x21\xc7\x7d\x82\x87\xc1\x65\xe0\xb4\x2c\x55\x15\x79\x77\x8a\xcb\x72\x58\xa2\x47\x9d\x7c\xf2\x5b\x90\x2e\x8d\x0d\xa4\x29\xbd\xe3\x6b\x45\x90\xda\xe9\x6f\x52\x54\x81\xac\x83\x78"}, +{{0x0c,0x9f,0xe5,0x59,0xad,0x1e,0xd3,0xba,0x16,0x4d,0xac,0xea,0xcb,0x02,0x35,0x67,0xb2,0x43,0x03,0x20,0xb6,0x71,0x5d,0xe7,0x32,0xa0,0x3c,0x59,0xc7,0x30,0x31,0x30,},{0xe7,0x0f,0xc4,0x66,0xfb,0x2a,0xcd,0x74,0xe0,0x99,0xc3,0x6e,0x2c,0x22,0xfa,0x51,0x29,0x0b,0xdd,0xe9,0x6d,0xf9,0xc3,0x1b,0x6d,0xfb,0xfd,0xc2,0xe2,0xc1,0x4a,0x40,},{0x6c,0xd8,0xae,0xd9,0x7d,0x9c,0x62,0xd5,0xfd,0xae,0x59,0x7d,0x06,0x1c,0x0c,0x2b,0xc3,0x7e,0x42,0xdf,0x06,0xb8,0x32,0x7a,0x46,0x8f,0x92,0xb3,0xf4,0x38,0xa1,0xe6,0xb6,0xb1,0xef,0x2b,0xe7,0x85,0x49,0xa2,0x89,0xfd,0x3f,0xc1,0xa6,0x29,0x9e,0x5a,0x33,0xd5,0x39,0x6c,0xb4,0xfa,0xc1,0xe8,0xe9,0x98,0x2f,0x0c,0xb3,0xd2,0x0d,0x07,},"\x26\xeb\xc6\x48\xcf\x8c\x79\x65\xec\x6e\xbe\x96\x5d\x9c\x79\x2b\xed\x90\x65\x5a\xd4\x40\x18\x3c\x6d\x70\xea\x64\x67\xbb\x8e\x6f\x04\xec\x84\x3f\x33\x31\x56\x91\x7b\xf4\xc5\x1d\x0e\xd0\xf2\x8b\x7c\xd3\x1b\xc1\x2c\xf8\x40\x68\x6b\x82\xb0\xc2\xc3\x50\xbb\xda\xc8\x05\x33\x37\x25\xd6\xb6\x9c\x2a\xb7\xf3\x4e\xe5\x93\xfa\x1c\xcc\xed\xf3\xf0\x64\x2a\x68\x8f\xcc\x1c\xd9\x8b\x09\x87\xd0\x1f\x71\x3a\x2f\xa6\x41\x6c\x96\x19\x21\xde\x0c\xc2\xc9\xec\x7a\x55\x58\x55\xe7\xfc\xd4\xc7\xdd\xaa\x14\xfd\x91\xec\xb0\x42\x24\xe1\x76\x1b\x7d\x6b\x35\xf4\xaa\x56\x18\xa5\x00\xca\x00\xd1\xca\x24\x51\xb5\xd3\x68\xaf\xde\x3a\x40\x7e\x78\x31\x35\xf3\x90\x19\xa5\xb9\x84\xe8\x2a\xc2\x79\xc0\x5e\x48\xc2\x95\xeb\xd1\x56\x38\x21\xa0\x74\x3c\x52\x24\x6b\x5d\x2b\x20\x34\xe3\xae\xb6\xce\x7c\x5c\xf9\x19\xe7\x4a\x9c\x7b\xbc\x9e\x25\xda\x30\x43\x0e\xb1\x6e\xcf\x38\x37\xeb\x38\xa0\xf5\x59\x79\x2a\x72\x98\x90\xba\x83\x10\x26\x0f\x8a\xeb\x9b\x5a\xf0\x0e\xb6\x33\xc1\x2d\xee\x02\x26\x28\xba\x41\x8d\x75\xcf\x18\xde\x2f\x2e\x65\xe4\x9b\x1a\x69\x68\x4d\x61\x27\xef\x48\x1c\xa8\x61\xec\xbc\xe3\xbe\x86\x49\x7e\x65\xdf\x4c\x5f\xcd\x08\x17\xc9\x71\x6b\x59\xf2\xa2\x63\xd5\xe9\xeb\x60\x68\x39\xf8\x5c\x5a\x36\x58\x37\xb0\xfb\xe2\xc4\x27\x4d\x66\xcb\x2c\x65\xed\x36\x5f\xab\xf5\x8f\x15\xbe\x52\xb5\x1c\xb6\x01\x18\xca\x4f\x73\x0d\x44\x73\x59\xf7\xef\x34\x6b\x75\x02\x17\xd4\x7b\x2e\x79\xc8\x6c\x0c\x62\x81\x6a\x0c\x7c\x18\xa2\xce\x2b\x68\x8e\x0c\xce\x0d\x75\x23\x21\xe7\x9b\x42\x38\x57\xda\xc5\x9f\x8f\xbe\xb0\x94\x11\xe7\x16\x69\xef\x9a\x26\x43\xf2\xe9\x9f\x38\x7a\xc1\x83\xe0\xb0\xac\x72\xc5\x9a\x0c\x3c\x18\xc0\xde\x8b\x01\x08\x78\x07\x4a\xcc\x1a\x2b\x39\xf9\xdf\x99\xd9\xf8\xf8\xb5\x2f\xef\xe4\x94\x3c\x52\x5f\xd4\xd0\x6a\xd8\x78\xe4\x66\x08\xab\xf2\x7a\x54\xbc\x50\x06\xf6\x47\xdb\x72\x48\x51\xdb\x7c\x45\x78\xae\x66\x58\x3d\xc4\xbb\x51\x8e\xf0\x28\x89\x03\x47\xe8\xfc\xe0\x92\x7d\x7d\x9a\xf3\xab\x5d\x0d\x2d\x20\x2a\x40\x26\xaa\x2e\xa7\x48\x79\x62\x67\x6a\x60\x32\x98\xe7\xd2\xe7\xb9\x09\x21\xee\x1b\x52\x80\x6d\x71\xa7\x64\xe0\x3e\x25\xdd\xd6\x84\x8f\x61\xd4\x6f\xad\x3d\x00\x8e\x10\xee\x5c\xd5\xa3\x39\x0f\x9d\x15\x8a\x44\x37\xef\x61\x5f\xc9\x0a\xc5\xbf\x3a\x9d\x68\x2e\x12\xc3\x39\x8a\xc7\x76\x80\xd2\x2c\xd1\xa6\xa5\x6e\xc3\xb2\x5c\xed\xe8\x67\xed\xd3\x83\x15\x9c\x61\x64\xd6\x3e\x9c\xd1\xc9\x56\xac\x72\x35\xff\xfa\xe9\x36\x16\x6c\xcd\x35\x89\x8e\x29\xc9\xb4\xca\x4e\x29\x25\xda\x32\x3b\x6f\xbf\x67\xcf\xd5\x96\xc8\x8a\x1a\x35\xa8\x35\x98\x51\xdd\xcb\xa8\xf6\x13\x4a\x9f\xaa\x24\x4d\xcb\x47\xe6\x91\x27\x6e\xe6\x25\xcc\x20\xad\xce\xc2\x1c\xbe\x77\xa3\xac\xb9\xba\x72\xf0\xc9\xd3\xda\x7e\x9c\xd5\xbe\x3b\x95\x99\x0b\xa5\x4a\x9f\x31\xaf\x17\x1f\x95\xae\xea\xd3\x33\x1c\xb1\x88\xa5\xb2\xc6\xf5\x39\xac\xb4\x8b\x98\xb3\xf7\x34\x1f\x60\x25\x1c\xb6\x04\x29\xcc\xd9\xcf\x32\xf0\x09\x20\x5f\x27\x53\xfb\xbb\x26\xaa\x53\x17\x43\x42\xad\x18\x4d\xab\x68\x70\xc0\xfb\x52\x93\x01\x19\xd9\xf9\x7d\x84\x89\xa6\x00\x76\xaa\xdb\x2e\x96\x05\x4a\xc7\xcb\x7f\x84\xe1\x3c\x75\xbb\xf9\xe4\xd9\x24\xd2\x27\x2a\xfe\xf0\x87\x19\x15\xe2\x43\xce\x66\xfc\x2a\x88\x88\x51\x35\x35\xb1\x0b\xb4\x07\x9c\x80\x6b\xd9\x49\x28\x1e\x28\x28\x35\x23\xd0\xd2\x10\xb3\x1e\xf6\x2a\x95\xdc\xae\x0c\xd2\x52\x90\xc7\xed\xf2\xc2\x4b\x43\x28\x22\xde\xbe\x34\x7f\x1c\xae\x94\x5f\x57\x28\xc7\x1b\x54\x03\xef\x14\xe7\x2c\x3d\x83\x42\xe1\x98\xb3\x62\xee\x20\xf8\x09\xe4\x6a\xca\x01\x5f\x35\x47\x7f\xf8\x9a\xc4\xb3\x7e\x66\x15\x85\x6f\x7e\xa2\x51\xfb\xfe\x13\xf9\x06\x52\x59\xb0\x94\x6a\xae\xf2\x49\x43\x27\x0a\x85\x4d\xe8\x89\x78\x00\x33\xd6\x3d\xda\x54\x47\x99\x8a\x3e\xd7\xe5\x06\xae\xb5\x1e\xa3\x7b\x68\x1a\xc3\x07\x67\x97\xac\xdb\xfc\xc2\x78\x83\x63\x0a\xdb\x72\x26\x0a\x46\xaf\x0a\x60\xd5\x3f\x66\x54\x56\x6e\x20\xd6\x08\x8c\xd4\x8e\x23\xb2\x8d\x81\xf0\xee\xd2\x05\xb9\x2a\xaf\xd9\x61\x64\xd6\xd3\xca\x3f\xc8\xb1\x71\x80\x4e\xe9\xfc\xe7\xab\xae\xd2\xea\x4d\xdf\x9c\xb2\xb3\xae\x73\xa7\x0e\xd6\x3d\xe4\x5e\x14\x10\x14\x28\xd0\xa7\xa2\x26\xdb\x39\xab\x6c\xd0\x43\x74\x08\x0e\x69\x83\xf0\x18\xce\x93\xda\x4c\x89\xac"}, +{{0x15,0xd7,0x5a,0xd8,0xe4,0xaf,0xb1,0x26,0x34,0xcc,0x8e,0x60,0x0f,0x1a,0x42,0x67,0xef,0x95,0x84,0xf4,0xc4,0xac,0x44,0xff,0xfe,0x4b,0x9f,0xcb,0x88,0x5c,0x9d,0x2a,},{0x09,0xd1,0x26,0xf0,0x17,0xe0,0x16,0x97,0x74,0xe8,0xc3,0x7a,0xb3,0x79,0x26,0x3a,0x80,0x75,0x74,0x61,0x27,0xc2,0xd1,0x1e,0xcb,0x0e,0x4c,0xb4,0x54,0x70,0x9f,0xf1,},{0xa8,0xf2,0xf4,0xb9,0xe2,0x07,0x2c,0xa9,0xfa,0xde,0x37,0xfd,0xd6,0x2d,0x8d,0x02,0x42,0xfd,0x4d,0xaa,0x09,0xfd,0x85,0x6e,0x75,0xf4,0xe3,0x43,0xc7,0x26,0x0e,0xa6,0x77,0xf7,0x53,0xa6,0x27,0xae,0xd0,0x8c,0xb9,0x6c,0x44,0x4e,0x29,0xbd,0xb5,0xb5,0x38,0x5d,0x43,0x84,0x3b,0xbe,0x79,0xa3,0xdd,0xa3,0x6e,0x1e,0x11,0x01,0xc5,0x0f,},"\xd1\xce\xa2\xb7\xe9\xaf\xc1\xf0\xfa\xb8\x90\xd2\x70\x0a\x5a\xe4\x1e\x15\xe7\xd3\x4d\x3b\xf1\x9d\x0f\x34\xd9\xf9\xf0\xab\x98\x12\xdc\x7c\x2a\x8d\xc4\x4c\x8e\xe7\xf3\x78\x87\x61\xec\xd9\x88\xee\x72\xc7\x36\xb6\x2a\x7c\xac\x3c\xc9\xb7\x38\xe9\x38\xdf\x77\x87\x37\x7e\xb9\xff\xd1\x20\xd4\xff\x58\xcf\x1c\x06\x75\x63\x3f\x7e\x83\xc4\xb1\x15\x54\x8f\x14\xd2\xf7\x0c\x6d\x48\x22\x11\x44\x3a\x84\x99\x59\x95\x58\xc1\x42\x77\x98\x0f\xa4\x2a\x78\x42\x79\x07\xf7\x3a\x41\xf5\xf6\x69\x3b\x2f\x75\xfe\x5e\x7a\x6f\xf0\xa6\xc3\xa4\xe2\xed\x1d\x0d\x96\x8d\x5c\xc9\xd6\xf1\x3d\x41\xc3\xd2\x91\x39\x6a\xe7\xe4\x34\xe6\x64\xb2\xff\x24\x3e\x7f\x6d\x88\x01\x02\x10\x07\x8c\x39\xb5\xa5\x76\xca\xf4\x09\xbb\x47\x11\xb3\xee\xfc\x48\x6b\x67\xb7\xff\xea\xe0\xcb\xac\x6a\x0f\xbd\xf5\x34\x3f\xb2\xae\x4e\x05\x7e\xdc\x8c\x9d\x2e\xd3\x1e\xae\x9e\xc8\x3d\x2b\xed\xd2\x19\xeb\x98\x9b\x2d\x44\x19\x61\x8c\x2d\x3c\xe4\x49\x0e\x35\xfb\xca\xd4\x32\xb0\x12\x47\x95\xf9\xc5\xcb\xdc\x1e\xb0\xc3\x07\x2b\x4a\xa8\x01\xd2\x6f\xbc\xc7\xb0\x7b\x82\x57\xf5\xfe\x47\xac\xd9\xbc\x58\x7b\x56\x57\xcf\x07\xca\x54\x5b\xb5\x68\xc9\xe4\xe7\x3c\xdd\xf6\x25\x4e\x22\xf7\x8a\xb2\xf8\x06\x45\x19\xf8\xab\xfd\x16\xfc\xfa\x90\xf8\x76\x87\xdb\x0c\x42\x09\xbe\x2c\x6c\x79\xa5\x52\x1f\x44\x18\x96\x78\xd9\x32\xc5\x45\x85\x70\x0a\x24\x37\x70\x2e\x56\xaa\xb5\x88\xa1\x7c\xb2\xcc\x94\xc0\x0e\x87\x57\x0e\xf3\xac\x51\x33\xd7\x53\x03\x8a\xa4\x65\x10\xa2\x60\xc1\xfe\x80\x47\x9b\xc0\x2e\xed\x9a\x8d\x1d\xe9\x93\x54\xac\x26\x48\xb4\x8b\x96\xab\x1b\x80\xcc\xa6\xca\xe1\x87\x7f\x37\xd7\x04\x28\xbb\x50\x85\x0e\x03\x08\xdb\x0b\x42\x30\x87\xbf\x7d\xde\x27\x9e\x09\x67\x66\xf2\xab\x3a\xb2\x38\x5b\x04\x64\xa5\xbe\xd7\xbb\xd8\xd4\x57\xe9\x35\xe2\x00\xaa\xaa\x8d\x95\x15\x70\xe0\x53\x07\x6d\xb1\x8a\x6a\x62\xf7\x2b\x31\x95\x79\x88\x4a\x08\x26\xba\x2b\x43\x63\x71\xdd\x21\x8b\x01\xa0\xc5\xe5\x8d\x0c\xd5\xff\x98\x25\xe4\x46\x6f\xe9\x66\xdf\x05\xcc\x31\xc8\x03\xe5\x21\x21\x83\xdd\xf2\x9c\xef\x7f\xb9\x16\x48\xa4\xf8\xee\x19\xfd\x5f\x8d\xbd\x8a\x56\xbe\x7a\xbf\x33\x65\x9a\x92\x24\xa1\xe2\x7a\x10\x24\xef\xfd\xfb\x88\xe8\x80\x61\x48\xd0\xd1\x78\x09\x06\xaf\x1e\xbe\x3e\x5f\x14\x36\x31\x90\xd8\x8c\xc6\xe5\x08\x94\x44\xf1\x25\xd0\x63\x15\x5d\xcf\x86\xca\x92\x63\xf2\xf5\xf1\x83\xc2\x69\x74\xfe\x00\x0b\x93\x42\xd2\x4c\x78\x1e\x20\x58\x28\x7c\xb6\xf3\xf1\xe3\x27\x0c\x22\xb7\x70\x7b\x83\x23\xa5\xcc\x8d\xb8\x1a\xa9\x06\xbb\x59\xd6\x96\xcb\x97\xcc\x74\xe3\x59\x59\x5f\xfb\x83\x73\xca\xd3\x71\x0e\xa0\x9e\xa9\x74\x4c\x20\xe9\xa1\x2e\x05\xbe\x5a\x95\xf0\x85\xac\x56\x16\x78\xd7\xda\x43\x2e\x4c\x7c\xb5\x3e\x12\x71\xdf\x5c\xd5\xa3\x39\xd2\xd7\x52\x0f\x1c\x18\x48\xd1\x50\x71\xd8\xc6\x98\x46\xb2\x3c\x5d\x24\x32\xc7\x38\x90\xf2\xed\xed\x37\xc3\xd2\x96\x4a\x4b\x5b\x55\x22\x58\x88\xe8\x92\xf5\x26\xd1\xca\xc3\x1e\xac\x35\x6f\x36\x1c\x2b\xf3\x36\xc4\x62\xd6\x0c\x82\xe8\x2b\x61\x6f\x2a\x51\x9c\x2f\x67\xbf\x01\x29\x03\x69\xbe\x9b\x55\xe9\xf5\xc8\xce\xc4\xf2\xe1\xb2\xab\x30\x25\x06\xc9\x03\xdc\x3e\x7b\x9c\x97\x81\x41\xdc\x90\x4b\x01\xb1\xc2\x3d\x25\x00\x43\x99\xbf\x8b\x73\xd6\x9c\xd5\x39\xc7\x9a\xf5\xe9\xa0\xa5\x11\xec\xa2\x21\x07\x8a\x1f\xf7\xb0\xf6\x04\xae\xa8\x42\x46\xc3\xcb\x32\xdb\x93\x81\xbe\x12\x17\x67\xe0\x97\xbe\xa5\x17\xbf\xcd\x82\xdf\xe9\x21\x37\x98\x40\xef\xb4\xb6\xf0\x2a\x48\xec\xda\xf1\x2d\x2c\xd3\x89\x30\xd4\x47\x3a\xdf\x97\xcd\x71\xdc\x4e\xa1\x03\x82\xf4\xf5\xd1\xdd\x75\x62\xcd\x4b\xf5\x11\x59\x32\xf6\xc4\x70\x0a\xa8\xfe\x8d\xec\xa9\xd5\xe7\x27\x79\x02\xb8\xf8\x86\x52\x97\x65\xdb\x24\x86\x07\x4b\x23\xa1\x9f\xd4\xb0\x43\x56\xbf\xa6\x22\x6c\x82\xba\xf6\x9a\x08\x7d\x9c\xa1\x88\x23\xf8\xe3\xe6\x83\x08\xe1\x6b\x80\x4c\x36\x3d\xf5\xb6\x30\x7e\x76\x24\x0d\xb1\xed\x84\x1b\x61\x2d\x65\x54\x8d\xdf\xbe\x83\x67\xda\x60\x77\x2c\x6a\xff\x55\x4d\xc8\x5d\x04\x19\x48\x34\x5e\x56\x7d\xa9\x33\x31\x51\x85\x8f\xdf\x69\x93\x27\x39\x25\xbf\xdc\x71\x81\xb5\xf6\x46\xd0\x63\xa8\xc8\xf3\x10\x56\x9b\x0e\xd0\x93\xbd\x9d\xff\x04\xfe\xbf\x0b\x41\xc6\xdc\x55\x16\x9a\x14\xa3\xc8\x62\xe5\x41\x6f\x1e\x58\x2f\xde\xe8\xfe\x87\xdc"}, +{{0xbf,0x3c,0x0c,0xbb,0xbe,0x20,0xbe,0x2a,0xcf,0xaf,0xb2,0x7a,0x36,0x11,0xb4,0x89,0x21,0xa7,0x28,0xab,0x17,0x33,0x4b,0x8a,0xfd,0xee,0x83,0x05,0x17,0x8f,0x61,0x3b,},{0x45,0x00,0xa0,0x3c,0x3a,0x3f,0xc7,0x8a,0xc7,0x9d,0x0c,0x6e,0x03,0xdf,0xc2,0x7c,0xfc,0x36,0x16,0xa4,0x2e,0xd2,0xc8,0xc1,0x87,0x88,0x6d,0x4e,0x6e,0x0c,0x27,0xfd,},{0x8f,0x87,0x03,0xbc,0xf4,0xc0,0x32,0x94,0x17,0x33,0x9e,0xb0,0x26,0xf2,0xb7,0x2d,0x31,0x4d,0x92,0x2e,0x9a,0xcc,0xb5,0xd8,0xbb,0x7e,0xec,0x87,0xe0,0x7e,0x61,0x38,0x55,0x16,0x72,0xa6,0x13,0x2c,0xb4,0xf8,0x75,0x50,0x8e,0xd3,0x29,0x95,0x67,0xb4,0xa7,0x41,0x34,0xd2,0xbd,0xf0,0xd8,0x57,0xf9,0x80,0x86,0x1d,0x18,0xbe,0x7e,0x01,},"\x8f\x30\xba\x2f\x79\x2e\x9a\x97\xf6\xea\xfe\x29\xf9\x76\xa4\x80\x28\xcb\x88\x57\xb5\xc7\x98\xbc\x2b\x61\x68\xc4\x64\x44\xc0\xce\x69\x60\x70\x37\x4c\x5e\x6a\x40\xc3\xd1\x8a\x5d\xc7\x66\x9f\xc4\x1d\xb9\xa8\x1c\xff\x75\x9b\x8c\xa0\x15\x98\x71\xc3\x44\x2e\x8c\x75\x12\x69\x8f\xa4\x47\xb5\x78\x3e\xe0\x1d\x1b\x61\x14\x49\xab\xad\x23\x71\x62\x92\x2b\x02\xd1\xae\xc5\xde\x1d\x66\x6f\x17\xda\x16\x13\x10\x63\x01\xd3\x05\x86\xd1\x16\xe2\xac\x09\x00\x7d\xd7\x1e\x81\x23\xed\xe4\xc5\xa6\xa9\xac\x07\x7f\xe3\xd9\x39\x09\xda\x62\x8e\x86\x58\x70\xa4\xe2\x5c\xb3\x55\x91\x67\x5a\x06\x90\xbe\xc4\xaf\x02\x81\x71\x4f\xe6\x66\x1b\xd5\xc0\x0a\x27\xd7\x9f\x95\x9f\xb4\xd4\xfb\x16\x36\xa6\xa3\x57\x5f\x4f\x01\x47\x06\x63\x89\x9d\x73\x74\x72\xb0\x96\xbe\x4d\xb7\x23\x71\x53\x67\xa4\x1a\x3a\x4c\x13\xf7\x42\xd9\x08\xf4\xd9\x21\xcf\xdd\x15\x6e\x75\x86\x82\x61\xba\x9c\x10\xd8\x58\x74\xca\x2d\x6c\x0c\x9e\x72\x95\xe5\x66\x2b\xd9\x16\xa3\x63\xc7\xa7\x96\xea\xd6\x17\xc4\x25\x1e\x67\x94\xda\x06\xc3\xd0\x8f\x2f\xdc\x38\x86\x94\x4a\x75\x09\xe6\x40\x9c\x90\x6b\x59\x31\x13\xb4\xb1\xf9\x85\x01\x32\x96\x0d\x9f\x3a\x4e\xeb\x73\x86\xfa\x59\x2f\x61\x93\xbe\xab\x8e\x0f\xf0\xf2\x89\x08\xa0\xd5\x48\xdb\x87\xba\xe9\x78\xb0\x5a\xbb\xca\x9b\x3e\x96\xd8\x79\x5b\x88\x07\x7f\x62\x0f\x21\x24\xe3\x15\x90\xeb\x09\x9e\x94\xe0\xe6\xe3\xcd\x62\x0a\xe6\x29\x0f\x3e\x2d\x01\x46\x7e\x5b\xef\x4f\xab\xde\xf7\x9d\x9a\xb9\x23\x9e\x75\x3e\xc4\xfa\x0b\xb1\x10\xff\x1d\x39\x3f\xca\x02\x24\x35\x02\xd7\xe9\x87\x99\x1e\xb7\x6d\x08\xf8\xbe\x7e\xb2\xb1\xee\x00\xc3\xb6\x8b\xbf\x72\xa6\x23\xba\xa1\x5b\xe8\x96\xb3\x21\x5e\xbe\x8a\x82\x31\x31\x09\xfc\x62\x9b\x0c\xce\x64\x91\xf8\x13\xc2\x49\x70\xe4\xff\xe6\x86\x9e\x40\xb4\x6b\x4e\xd2\x29\x86\xd0\x04\x21\x55\x27\x6c\x23\x0d\xe4\xc0\x5d\x67\x85\x52\xf2\xe8\x51\xca\xcf\x5a\x47\x21\x57\xdb\xb1\xa9\x9a\x2b\x42\xff\x40\x37\xf0\xdc\x63\x80\x67\x29\x21\xc9\x09\x20\x6e\x80\x05\x0e\x61\xa6\xb3\x05\x6b\x17\xe3\xae\x83\x50\x09\xb2\x04\x19\xa3\xb9\x84\x6d\x37\x48\x92\xe7\x19\xf1\xb3\x5b\xc1\x25\x7d\xa9\x3c\xcc\x6d\x8f\x8f\xca\xa8\xe6\x09\xa8\xd2\x04\xdf\x10\x8b\xe7\x19\x34\x67\xe7\xf1\x05\x93\x52\x82\xc3\xfe\x66\x70\xa5\x32\x94\x42\xea\x3e\xdd\xa2\x37\x6a\x03\xa1\xcf\xe8\x72\x3a\x90\x9c\x06\x4d\x30\xfe\x9b\xb0\x21\x2c\x33\xaf\xe2\xbe\xa3\x0c\x91\x43\xc0\x01\xda\x01\xc7\xed\x50\x45\x59\xb9\x7f\xe2\xce\xa0\x9b\xeb\x9d\xb5\x19\x00\xdc\x13\x67\x05\x92\x1e\x20\x29\x78\x45\xba\x72\xa9\x7a\xa7\xc9\x53\x81\x45\x71\xbe\x3f\x08\xce\xf9\x68\x04\x5a\x5a\xc3\x40\x04\xf6\x7f\xbf\xa5\x4e\x99\x6b\x31\x1b\xd8\xdc\x52\x7d\x89\xe1\xd4\xf5\x34\x53\xa6\x71\x37\x20\x10\x1c\x45\xa6\x0e\xe3\xa0\x5c\x2e\xe6\x6f\x13\x4b\x5a\xf4\x0e\x4b\x70\xef\x37\xba\x3f\x0a\xfd\xef\xc0\x39\xf3\x42\xc2\x8a\xf9\x19\x82\x51\x38\x1a\x10\x79\xa5\xdd\x03\x5a\x8c\x28\x97\x6c\x6b\x7f\x4d\xb0\x9e\xa3\x83\xa3\xa8\x7f\x0f\x85\x1f\xd3\x31\xae\xa7\xfa\x4b\xfc\xd9\x56\x31\xd6\x52\xfa\x2f\x50\xf1\xc2\x3f\xf2\xbc\x13\x7a\x06\x04\xe3\xd9\xf3\x9c\xcb\x96\x51\x45\xbc\xa4\x8b\x06\xdc\x8a\x81\x75\x47\xb6\x25\xef\xfa\x79\x6d\x00\x0c\x37\x74\xba\xd1\x98\xdb\x12\x41\xbe\x7a\x2c\x0d\xc4\xa4\x64\x1b\x9a\x8c\xb9\xcb\x8c\x8c\x38\x87\x57\x6f\x52\x72\xc3\x3a\xaf\xfe\x45\x61\x5f\x51\xa9\x6f\xae\x76\xcf\x51\x25\xbc\x69\xad\x0a\x40\x38\x79\x07\x99\xb5\xc2\x62\x44\x21\xa6\x43\x3d\xba\xb3\x9c\xcc\xb0\xb1\x78\x7b\x5b\xce\x28\x95\x94\x48\x9d\x17\xed\xb5\xf9\x31\x03\x74\x80\x7d\x36\xc6\xe6\x73\x47\x26\xbb\x33\x00\x4e\xca\xe8\xbb\x69\x1d\xcd\x38\x76\x01\xf4\xea\x91\x1b\x4b\x90\xeb\xff\x75\x6d\x7d\x8d\x9e\xb4\x22\xcb\xb9\xaa\xf7\xf4\x77\x2e\x0a\x54\x36\x43\x06\x85\xe5\x7b\x69\x74\x54\xe8\x2e\xea\xdc\xe4\xab\xa0\x62\xb7\x76\x82\xcf\x21\x9b\xe1\xfd\x9b\x00\xf1\xcb\x11\x35\xa1\x02\x13\x49\x53\x9a\x4b\x93\xae\x21\x3f\x19\x3d\x29\x32\x73\x8e\xf7\x29\x20\x49\x9b\x7b\xe2\xa8\x1c\x9b\xaa\xed\x17\xc5\x46\x41\xa5\x97\x4d\x27\x22\x32\x41\xe3\xc6\xa0\x95\x22\x6b\xd2\x37\xe0\x59\x1e\x00\x2b\x3a\xf0\x56\x5d\xf3\xe9\x76\x42\x0f\x97\x64\xa0\x9a\xe8\xbf\xa2\x79\x5f\x8f\xad\x7f\xc6\x87\xbd\x2d\xe2\x3d\x14\x88\xf4\x49\xd8"}, +{{0x28,0x7f,0xaf,0xd2,0x13,0x74,0x57,0x2f,0x57,0x81,0x00,0x47,0xd0,0xd9,0x8c,0xb1,0xff,0x3d,0x01,0x20,0xfa,0xa4,0x88,0x61,0x32,0x24,0x57,0x32,0xc1,0xa6,0xab,0x78,},{0xe8,0x25,0x20,0x63,0xf5,0xad,0x7e,0x95,0xbd,0x05,0xc5,0x02,0xa8,0xbc,0x4a,0x17,0x55,0x63,0x60,0x86,0x9b,0x9d,0xe0,0xa3,0xb8,0x58,0x93,0x8e,0x11,0x11,0x76,0x19,},{0x62,0x01,0xe3,0x05,0x91,0xd3,0x6b,0x7b,0x22,0x6e,0x36,0xfd,0xf5,0x64,0x34,0xc4,0x7c,0xd3,0x05,0x18,0x37,0xaf,0x31,0x31,0x3a,0x99,0x17,0xfd,0x02,0xdd,0xed,0x2b,0x5b,0xbb,0x4b,0xbc,0x36,0x8b,0x3b,0xd1,0x5d,0x06,0x20,0x45,0xf1,0x05,0xb6,0xe7,0x34,0x1b,0x15,0x15,0x0d,0x36,0xf9,0x00,0x87,0x59,0x1d,0x83,0x99,0x01,0xb8,0x01,},"\xb3\xc4\x43\xe4\xe5\x89\x9c\x16\xd3\x9e\x81\xb4\xf8\x07\x40\x42\xa9\x04\xa7\x35\x07\x4b\x27\x95\xd9\xac\x06\xb1\x37\x9e\xf7\x61\x8d\x2a\x53\x4b\x6b\xef\x81\x56\x9e\x60\x71\x92\x67\xbf\x29\xcd\x9d\x16\xac\xc9\xa1\x74\xd8\x02\x6b\x14\xb1\x27\xd0\xd2\xd8\xb4\x58\x39\x98\x89\x5a\xd7\xef\x72\xfe\xdc\x53\xb8\xf0\x8a\x22\x50\x10\x0e\x1f\x1f\x0a\xab\x48\xbc\x70\x74\x64\x34\x88\xe6\xb6\x70\xe1\xb0\x72\x7c\x38\x5a\x34\xff\x65\xa0\xd7\xe8\x3b\xa8\x60\x83\xb8\x73\xdf\xf0\x55\x92\x09\xb1\x4b\x2a\xc4\x2b\xf7\xc5\x72\xd0\xc5\x91\x7a\xc4\x2e\x4a\xe4\xda\xe1\xdd\x42\x35\x79\x52\x76\xa0\x76\x13\x2c\xfe\x3e\x0c\x35\x0b\x26\x58\x0f\xbb\x3a\xf8\x17\x77\xb9\x3a\xd9\x5c\xb7\xff\x17\xc2\xd9\x80\xce\x0d\x49\x2f\x6d\x40\xfa\x90\xba\x3f\xca\xa2\x1b\xb6\x87\x35\xee\x1e\xf2\x08\x49\x5e\xbf\x7b\x02\x27\x6f\xfa\x1e\xfc\x08\x16\x58\xbb\x44\xcd\x27\x61\xef\x5e\x3e\x1c\xa6\x0e\xc8\xb5\xd8\x16\xd4\xab\xac\xd0\xbc\xc8\x02\x68\xd8\xf4\xdf\x8b\x3a\x52\x04\x9d\xb0\x15\x7e\x2b\x6e\x81\xac\xd6\xf3\xf2\x89\x47\xc0\x76\x27\x95\x5c\xda\xc9\xea\xa1\xde\x17\xd4\xb9\xda\xa3\x61\xfb\x49\x78\x26\x64\xd7\xd6\xd2\xca\x5c\xec\x6d\x14\x89\x3c\x3e\x80\xb6\xd1\x6d\xaa\xcf\xfc\xc0\xb7\x59\x37\xe8\xbe\xf6\xf9\xe1\x12\xa8\x7f\x4b\x03\x5f\x90\x36\x07\x0a\x2c\xcc\x55\xc2\xaa\xd9\x39\xdf\x67\x4f\x7e\x4e\x12\x68\x5e\x01\x6e\xa0\xe4\x90\x2a\xaa\xaf\xaf\xfe\x38\xdd\xb2\xf9\x0d\x9c\xf7\x85\x37\xf6\x13\x91\x69\x6f\xf0\x33\x0a\xe8\xf7\x9a\x1c\x1e\xd5\xd5\x2b\x4e\xe2\xa6\x2d\x90\xfb\x82\xd9\xa4\x83\x93\xfa\x33\x81\x0b\x40\xd0\x45\x59\x02\xd5\x74\xff\x05\x20\x03\xe0\x16\x0c\x0f\x47\xb5\xe5\x80\xa0\x78\xbc\xee\xf0\x60\x73\xdd\xa8\xb2\xd1\xf1\x04\xa5\x95\xe9\x0b\xb6\xa4\x8e\xdd\xd8\x65\xf1\xca\xe4\xf1\x78\xfe\x22\xe7\x5f\x2f\x61\x24\xa9\xda\x06\x82\x44\x71\x12\xb3\xdb\x5b\xe8\xc4\x24\x72\xb2\x41\xe9\x44\xfd\x23\x70\xc2\xdc\x27\x15\xc0\x5a\x41\xbd\xbc\x89\x0c\x41\xc6\x5f\xb0\x8c\x2f\x59\x31\x74\x39\x1a\xc8\x80\xf3\xcb\x67\xd1\xb7\x4f\xf8\x02\xef\x96\x2a\xfe\xf7\xb9\xf3\xea\x32\x6f\x95\x27\xe7\xfb\xa6\x98\x18\x79\x24\xb6\x4c\xcd\xd0\x86\x62\x48\xc7\x6e\xe6\x4c\x79\x06\x9b\xe0\xa0\x57\xb1\x0a\xe1\x90\xf3\x8f\xf5\xab\xa8\x44\xe3\x93\x31\xcf\x1d\xb1\x3c\x90\x09\x06\xbe\xe0\xd7\xe7\x54\x6e\xf5\x23\x24\xe3\x7c\x59\x06\x75\xf1\x39\xf5\x8f\x57\x3a\x49\x4f\x4a\xe8\x2c\x4e\xc8\x10\x66\xa6\x8e\x2d\x92\x90\x01\x91\xc4\x7d\x30\x62\xf0\xf9\xaa\xed\x19\x11\x37\xcd\xa9\xb8\x3c\xd1\x30\xe8\x26\x29\x60\xe6\x24\x4f\x8f\x6e\xf3\x9f\x15\xa4\xfe\xd1\x3c\xb6\x69\xed\xc1\x9f\x5c\xe1\x62\xce\xb8\xd2\x42\xb9\xad\xdb\xfb\xa8\x77\x2c\xe7\x49\x85\xa5\xf3\x72\x0d\x59\x0a\x92\x0e\x1d\xca\x75\xa8\x79\xb1\xaa\x45\x9f\x74\x62\xff\xf2\xe9\x50\x72\x76\x1b\x20\x92\x54\xfe\x38\xc5\x4d\x83\x3a\x8e\x2c\xb8\xfc\x40\xc5\x98\xf3\xc7\xf7\xd6\xc5\x70\x57\x15\xd0\x30\x8d\xc3\x0e\xaa\x84\x67\x6d\x20\x9d\x7b\x7b\x31\x34\x47\x56\xe6\x9a\x9a\x4c\xb4\xe4\xa2\x51\x81\x7a\x37\x86\xfe\xa6\x72\x8d\xd6\x08\x22\x33\x6b\x45\xae\x5d\x47\xc7\x04\xb4\x5c\x4c\xad\x38\xc1\xe0\x1a\xb9\x3d\x14\x16\x92\xd5\x5d\x12\xfd\xb9\x74\x0f\x1d\x18\x15\x82\xf1\xc4\x8c\xe5\x43\x48\x60\xd9\x30\xf0\xe7\xe7\x0e\xdc\xff\xb8\x55\x60\xa5\x3d\xba\x95\xd5\x7b\x31\xe8\x92\x41\x37\xbc\x2c\x19\xe3\x4b\xb9\xc9\x86\x68\x77\x17\x42\x80\xe8\x0c\x23\x97\x8d\x57\x79\x58\x64\xa7\x37\x4a\xef\x38\x3f\x3b\xf6\x37\x53\x59\xbf\x63\x56\x47\x40\x09\x84\x61\xa6\xc7\x6e\x8f\x23\x89\x13\x28\x87\x69\xa1\xcb\x1c\x95\xb2\x2c\x32\xa9\xeb\xb3\xec\xeb\x04\x8e\xe3\x24\xcf\x0d\x7e\x85\xa3\x89\xb0\x4d\xed\xbb\xcb\xee\xf2\x98\xd0\x52\x78\x16\x08\x5c\x0c\x83\xef\xaa\x29\x85\x46\xe8\x39\x0b\xd1\xbf\xe4\x65\xec\x1b\xaf\xae\x69\xee\x52\x18\xe7\x2c\xae\xdb\x9b\x64\x9c\xf7\x3e\xec\x45\x4a\x2b\x48\x49\x65\x17\x96\x72\xde\xbc\xf9\x44\x13\x63\x99\x5a\x8a\x90\x7d\xe1\x7d\xc0\x68\x4f\x2a\xea\x57\x9a\x2f\xb4\x48\x41\x95\xdb\x41\x15\xca\x32\xe9\x70\x52\x6d\xc0\x0a\x5c\xac\xaf\x58\x87\x11\xdb\xd4\x69\xce\x80\xbd\x29\x7c\x4f\x41\xd6\xfa\x28\xa5\x97\xc6\x37\x2c\x0d\x21\x49\x60\xb5\x45\x98\xcd\x8b\xc8\x49\xeb\xdc\xa3\x6d\x62\x25\xb2\x0d\xec\x0d\x03\x11\x69\xce\xbb\x36\xea\xdc\x3a"}, +{{0x9a,0xd0,0x49,0x10,0x08,0x51,0xd0,0xf7,0x9b,0x71,0x12,0x25,0xc9,0x88,0x47,0x79,0x5a,0xcf,0xc3,0x60,0x1c,0x14,0xb8,0xa9,0x77,0x8d,0x62,0x70,0xcd,0x4c,0x05,0xed,},{0xe7,0xca,0xcf,0x4f,0x37,0x14,0x54,0x3c,0x27,0xa3,0xe9,0xed,0x83,0x3b,0xaf,0x3b,0xde,0x4c,0x09,0x56,0x3b,0xef,0x59,0xe7,0x63,0xfa,0xb7,0x1f,0xb5,0xe4,0xff,0x56,},{0xfe,0xc0,0xaf,0x34,0xcb,0xc5,0xcf,0xfc,0x56,0xe9,0x6d,0xd5,0xed,0x59,0x68,0xe5,0x2c,0xbd,0x42,0x69,0x84,0x4f,0xc3,0x0e,0x3a,0xb0,0xd3,0x47,0x2b,0x5d,0x18,0x0c,0x8d,0x1b,0x76,0x90,0x51,0x8f,0x41,0xf1,0x44,0x38,0xe7,0xf3,0xa8,0x3d,0x5e,0x89,0x76,0xcb,0x9a,0x26,0x15,0x1f,0xc4,0x14,0x9a,0x32,0x98,0xd7,0xe4,0x2c,0x05,0x03,},"\xc2\x84\xbd\xd8\xf8\x27\x5b\x49\xac\x80\x8c\x39\x04\x5e\x50\xe1\xed\x50\xc8\xa1\xaf\xd0\x11\xaf\xe5\xdb\x3d\xda\x62\x0b\xe8\xae\xc3\x7f\x45\x60\x57\x62\xe2\x25\xd0\x41\x11\xf2\x1b\x49\xfc\xef\xca\x3f\x3d\x5f\x81\x3b\x20\x20\xa5\x2c\x49\xf9\x5c\x4a\xd6\x1c\xa2\x14\x61\x8a\xde\x7e\xed\x6c\xd8\xd3\x14\xdc\x4c\x63\x55\x95\x52\x77\xd4\x57\x46\x2f\x03\xb9\xfb\xa2\xe2\x25\xb1\xb5\x37\xcd\x4b\x52\x37\x50\x5c\x90\xd4\x32\x05\xe1\x71\x5c\x39\x63\xcc\xfb\xec\x37\x9e\x6c\x17\x05\xe0\x80\x34\xa3\x1a\xfc\xe6\x46\x72\x7e\x78\xa2\x0e\xed\x88\xae\xb0\xdc\xda\xbc\x5c\x86\xe8\x69\x79\xe6\x3a\x5c\x26\xc3\xe2\x17\x79\x73\xb6\x98\x3c\xeb\xfe\xda\x9f\x31\x47\x93\x61\xb6\x61\x76\x3a\xa7\x26\x1c\x09\x39\xca\xd4\x8b\x71\x90\x8e\xa9\x07\x68\xbb\x6c\x95\x83\xd8\xea\xeb\x9e\x03\x38\x51\x5a\xca\x12\x42\x62\x6d\xc6\xbe\x04\xec\xc4\x42\x9e\x4c\xbb\x4f\xf3\x36\x09\x61\x92\xf7\x50\x1e\xc4\x71\xb5\x96\xa9\x9d\x4c\x02\x75\x82\xcc\x69\xe2\x04\xb6\xfb\xcd\xdf\x59\xf5\xbf\x74\x62\xdd\xcd\x59\x89\x12\x1f\xd1\x0f\x11\xa0\x67\x5b\x6c\x4e\x4f\x65\x20\xd2\x7d\x7c\x61\x43\x1b\xa7\xd1\x74\xf5\x73\x95\xa0\xbf\x72\xd3\x8c\x11\x42\x73\x6d\xed\x6b\x91\xe4\x81\x1c\x0e\x85\x41\xa6\xc0\xd9\x96\xc5\xa1\x7d\xc9\x7d\xb3\x88\xf7\x21\xd2\x35\x7d\x3c\x6a\xf5\xc8\x6b\x1d\x5e\x47\x6e\xa0\xac\x0b\x1c\x11\xd4\x38\x7f\x76\x90\x39\xbd\xf5\x38\xa0\x21\x6e\xdd\x00\x45\xee\x6d\xd8\x9e\xef\x82\xa4\x25\xa8\x3f\xaa\x1b\x12\x80\x70\x38\xca\x19\xeb\xec\x00\x2e\x8b\x3c\x15\x34\x4c\x61\xcf\xd1\xe5\xf0\xe3\xb0\x27\x3d\xeb\x37\x27\x8c\xf1\x97\xd8\xa8\x3b\x13\xd9\x92\x30\x8a\x51\x37\x3e\xb3\x81\x14\xc9\xe4\x5b\x43\x87\x80\x27\x7d\x1e\x32\xf3\x97\x29\x62\xa3\xe1\x4a\x8d\x08\xdb\x9f\x09\xae\xc3\xdd\x32\xa5\xb9\x94\x23\xe6\x1f\x5e\x79\x94\x4a\xb5\x7a\x36\xf6\xec\x07\xcc\x32\x04\xf9\x16\x5e\xe0\x21\xad\xa9\x3e\x6f\xec\xb7\xec\x45\x6a\xa0\x28\x8c\x37\x8a\x75\xaf\xd6\xe9\xda\xd6\xc6\xf8\x8e\x95\x9a\x2c\xf2\x8b\xfe\x56\xd2\xe6\x1b\x2a\xda\xec\xf0\xd8\x6d\xd8\x92\x8b\xce\xda\x26\xb0\x54\x02\x46\xb7\x33\x7f\x5c\xdc\xec\x11\xfb\x0c\x1a\x59\xd6\x31\xfc\xca\x19\x40\x8f\x95\x22\xb6\x8a\x39\xf8\x6e\xf9\x70\xb8\x83\xa0\xf0\xbd\x6b\x7b\x14\x15\xec\x9a\xa0\x43\xb5\x2e\x19\xba\xc1\x76\xd6\x7b\x79\xe2\xa5\xdc\xa8\xbf\xd2\x91\x02\xac\x60\x8e\x47\x3e\x9f\x98\x2c\x3e\xc8\x93\x2d\x8a\xa8\xcd\x56\x52\x84\x49\x1d\xe5\x2f\x51\x6b\x9e\xbf\xb7\xdb\xe1\x29\x95\x11\xae\x73\x2c\x2a\xd1\xee\x49\x92\xb0\x77\xfa\xff\xc6\x5f\x48\x8f\x1b\xa2\x15\xda\x69\x79\x60\x09\x71\x19\x6d\x0f\xf3\xa0\x8a\xd9\xf0\x0e\x82\x9c\x1d\xe1\xaf\xca\x10\xca\x47\x6b\xe6\x64\xaa\xd2\x61\x88\x9b\x0e\xb7\xae\xb6\xed\x86\x37\x61\x89\x00\xac\xf4\x81\xe2\xd2\x24\xec\x64\xa6\xe6\xcf\x4f\xa4\xdf\x73\x1b\x7a\x4f\xee\xff\x25\x80\xc9\x9b\x6d\x75\xb4\xdc\xd0\x97\x69\x65\xcb\x2b\x0b\x56\x35\x22\x78\x42\xd0\x8a\x7d\x90\x7a\xae\xbc\x2f\xde\xd8\x00\x98\x11\xdc\xdd\x73\x35\x49\x21\x75\x3b\xc5\xde\xc0\x17\x68\x93\x35\xf5\x6d\x0f\xb7\xae\x21\x3b\x41\x79\x2b\x1f\x4e\xb1\x4a\x24\x53\x59\x77\xa3\x05\xb1\x9e\xb9\x83\x8d\xc6\xb5\x15\x28\xb9\x8a\x39\xbd\xa0\x60\x10\x71\x7a\x20\x8c\x34\x7a\xa1\x58\xee\xcd\xfd\x9a\x04\x72\xd3\xb8\xd9\x20\xf9\x69\xe1\x2b\x65\x91\x9b\xda\x38\xb4\x61\x94\x98\x50\xcc\x9c\xc1\x8d\x8e\x3b\xaa\x8c\x88\x6d\x93\xcd\x09\x6a\x20\x9d\x54\x3c\xa3\x37\x5f\xc4\xe7\xd6\x51\x03\xcb\x64\x24\xbe\xab\x44\xe8\xbc\x4a\x5b\x62\xc2\x9a\x01\xbc\xf4\x4d\xcc\x61\xe7\x67\x5c\x02\x5d\xec\x07\x24\x20\x01\x94\xbd\xe7\x4d\x72\xc0\x2e\x94\xa9\x46\xa7\x52\xf3\x60\x84\x57\xfd\x91\xf2\x92\x71\x57\x71\x48\x7d\x26\xca\xd4\xe5\xcf\x6e\xf7\xc6\xf7\x16\x27\xa4\xda\xf8\xa4\xc9\xb8\x91\xc1\xee\x8f\x04\xae\xaa\x99\xfe\x0c\x8b\x4e\x83\x3b\x76\x09\x06\x6b\x61\x32\xa9\x68\x89\x0e\x26\x95\xda\x22\xb2\xd8\x57\xc8\xc0\xad\x91\x87\xc9\x60\x69\xe4\x76\xe2\x7e\x46\x32\xc4\x47\xee\x76\x71\x4a\x31\xd1\xe5\x14\x9e\xcb\x33\x7e\xe1\x32\xf3\x55\x2d\xa3\x3a\xb2\xd6\xfa\x9d\x7e\x93\xf6\x8a\x77\xcb\xf1\x91\xcb\x06\xbc\x22\xf3\x47\x0a\xf6\xd7\x58\x1e\x3a\xcc\xbe\xca\x0b\x6f\xeb\x08\xa1\x4b\x9a\x80\xc1\xef\x59\x37\x4c\xcd\xc0\x52\x3c\x36\x84\x50\x4c\x01\x04\xbb\xa2\x2c\x10"}, +{{0xde,0x54,0xe1,0x3f,0x9e,0x2c,0xc7,0x54,0x54,0x6c,0x99,0xb3,0x3b,0x3d,0x72,0xf4,0xd1,0xf7,0x71,0x50,0x38,0xa9,0x65,0x9f,0x33,0x63,0x65,0x77,0xbb,0x52,0x6a,0xdb,},{0x36,0x33,0x8d,0xb3,0x32,0x6b,0x00,0x5e,0x5c,0x61,0xff,0x78,0x2b,0xe2,0xea,0xb1,0x66,0xd4,0xeb,0x72,0x34,0xa9,0x8e,0xa1,0xcd,0x85,0x5e,0x1a,0xd5,0x35,0xe9,0x4c,},{0x37,0xac,0xa8,0xf2,0x48,0x39,0x4a,0x9e,0x04,0xd0,0x6a,0x7d,0xa8,0x4a,0x7d,0xef,0xa3,0x9d,0xe4,0xda,0x2b,0xcb,0x18,0xd5,0xf6,0x4c,0xc3,0x4d,0xb0,0x86,0x51,0xaf,0x4a,0xbb,0x19,0xfa,0x2a,0x92,0xa7,0xdd,0xa5,0x6e,0xc9,0x93,0x0b,0x81,0xae,0xbd,0x23,0x99,0x05,0x11,0xf6,0x84,0xc6,0xd1,0x5b,0xa5,0x95,0xf7,0xd4,0xa2,0x74,0x0e,},"\xdc\x40\x41\xad\x61\x42\x3a\x12\xa0\x41\x13\x18\xa6\xe6\x2a\x5e\xf6\x4a\x19\xab\xe2\xd9\x85\x22\x97\xbe\x2d\x4a\x35\xeb\x86\x70\xca\x36\xc5\x21\x53\x1b\x30\x38\xac\xda\xee\xa2\xea\x01\xa0\xb6\x18\x78\x62\xa4\xe1\xa8\x9d\x4b\x81\xc5\x31\x8e\xd4\xd6\x71\x31\xbc\x38\xf8\x41\xa1\x42\xa2\xf6\xf3\x16\xdf\xf0\x76\x93\x9d\xc0\xeb\x81\xb2\x30\xfe\xa9\x88\x1f\x8f\x0f\xf7\xed\x0b\x29\x3f\x69\xb2\x89\xfe\x77\x08\x81\xfb\x37\x10\x80\x8e\x8e\x59\xe6\x4e\x19\x0c\x1e\x37\x9b\x9d\xd3\x48\xb0\x2c\x23\x47\xd7\xe2\x06\x96\x79\x0b\x62\x77\x6a\x2e\x82\x5b\xed\x69\x17\x03\x7c\xb6\x35\xc9\x2f\xbc\x76\xb4\xc5\x85\x10\x27\xe7\xf1\x38\x52\xee\x7e\x7c\x52\x57\x3a\x90\x30\xb7\x9f\x22\xb6\x0d\x58\x69\xef\xe6\x80\xc0\x16\x64\x92\x9f\xe9\xa0\x6f\xa3\x33\x05\x2b\xe1\xd6\xaf\x3a\x0b\x48\x2c\x33\x2e\x18\x05\x1e\x78\xb3\x33\x83\x9d\x6c\xb9\x3d\x93\xeb\xfb\x27\x7e\x42\x68\xfb\xee\xee\xba\x1e\x8f\x96\xa5\xc9\xe3\x28\xc4\x26\x72\x12\xca\xc2\x51\x21\x5b\xfa\xa7\x8f\xd8\x8a\x87\x41\x7a\x80\x60\x2d\xcd\x88\x28\xe8\x04\x00\xda\x30\x4e\x98\x98\x62\xd1\x32\x01\x08\x2d\xe3\x53\x09\x25\xe0\xed\xc2\xc1\x30\xa9\xa4\x19\x07\x1b\x31\x08\x8d\xa6\xf6\xff\x40\x56\x30\x1c\x12\x9f\xc2\x13\x52\x33\x62\x8d\x16\xd8\xbf\x16\x0f\x6c\xe8\x6d\x83\xcd\x4e\x29\xae\x0c\x73\x84\x3d\x70\xb5\x30\x56\xc5\xaf\x3f\x3d\xc5\x61\x27\x1c\xb5\xaf\xf3\x93\xf0\x80\x3a\xde\x07\x2d\x9c\xeb\x74\x5b\x61\x87\xb2\x8d\x24\x69\x67\x67\xd5\xc2\x1f\x4d\x4a\xc5\x8d\x5b\xb6\x6c\x5c\xad\xfe\xfb\x16\x26\xef\x93\xf7\x14\xc7\x82\xb6\xef\x3c\xcf\x4b\x44\xee\x75\xf0\xbb\x75\x7a\x25\xd9\xb4\x6a\x9d\x93\x1a\x03\x72\x7d\x49\x6a\x22\x81\x0c\x63\x4f\x5c\x1a\xe6\x0c\xbd\xf2\xf1\xea\x29\xb5\x46\x07\xcf\xf5\x0d\x9f\x8e\x03\xa0\xa4\x51\x3c\xf6\x8d\xfb\x61\x97\x73\x41\x1b\x61\x80\x95\x9a\x8a\xac\x30\xb2\xee\xe4\xad\x32\x79\x15\xf6\x0a\xe5\x2b\x90\xe0\x4a\x9b\xce\xf8\xdc\x67\xe7\x1e\xa1\x0a\xca\x55\x3d\xb9\x89\x5c\xd8\x00\x84\x57\xd7\x6f\x02\xce\xb5\x35\x00\x21\x11\x09\xe8\x96\x03\xf3\x04\xd8\x80\xaa\xf0\x28\x61\xfe\x37\xc9\x53\x4a\x9d\x67\x2d\x83\x71\x3c\xd3\x26\xc9\xab\x81\xc3\x53\x76\x4c\xa5\xad\x5a\xc0\xe7\xf1\xff\x88\x0f\xb4\x8a\xcd\x9c\xbb\x94\x90\x64\xe2\x11\x83\xbc\x38\xfb\x1d\x90\xcf\xe6\x19\xa8\xb8\xfb\xf5\x32\x18\x89\xbb\x15\xc0\x2a\x53\xe4\xd3\x67\xfc\x66\x88\x77\xb6\x62\x28\x1c\x4a\x2a\xf6\x78\xf8\x6e\x69\x1d\xaa\x8a\xfd\xca\xc1\xb8\x20\x18\x9f\xe5\xc2\x50\x8c\xe3\x6e\xdd\x9c\x6f\x8f\x51\x57\x50\x71\x83\x94\x39\xa0\x03\x35\x2c\x15\x73\xe1\x27\x68\xdd\x6d\xeb\xdf\x1e\xd4\xf9\x4a\xc7\x9d\xf1\xab\x6a\x0b\xc2\x50\x79\xc0\x93\x54\x77\xd9\x14\x99\x88\xec\x3b\x87\x93\xef\xcd\xa8\x59\xac\xc3\x92\xab\x3f\xa9\x94\x93\xd7\xae\x0a\x65\x75\xb6\x95\xa1\xce\x07\x65\x32\x86\x02\x87\xdd\x49\x89\x67\xc4\x6f\x7a\xdd\x49\x49\x4c\x02\xe7\x44\xc4\x02\x80\x19\x57\x82\xe2\x42\x44\x76\x16\x5e\x72\xce\xe2\x36\x42\xe5\x1c\xec\x43\x21\x91\x11\x6a\xec\x59\xb5\x9f\xcf\x0a\x36\x83\xb9\x5f\x76\x07\x60\xa2\x0b\xd6\x74\x54\xd8\xde\x64\x7c\x0f\x9f\xfc\x4f\x90\xf6\xe4\x5a\xc9\x3d\x80\x2f\x33\x82\x99\xef\x28\x0d\x3b\xb7\xa4\xa8\x9d\xb8\xc5\x9a\x12\x52\x6f\x27\x83\x02\x4c\x8a\xde\x90\x02\xf0\x0e\x3d\x52\x9b\x78\xdc\xdd\x49\x03\xda\xf5\x76\x7a\x2b\xed\x75\x14\x53\x96\xef\xb6\x97\x90\x71\x2d\xe6\xa5\x90\x1e\x6d\x8c\x15\x28\x01\x82\x38\x82\x85\x02\x1d\x0e\x70\x92\x92\x15\xd9\xf2\xb7\x99\xbb\x92\xf2\xca\x56\xf4\x8e\x8c\xbb\xa2\xf1\x9b\x08\x58\x45\x12\x65\x67\xcf\xaf\xa6\x03\xc2\x94\x6e\xa1\xe7\xd2\x74\x55\x4a\x38\xbf\x7d\x86\x51\x1f\x3e\x47\x4f\x9f\xa5\xcb\x11\x10\x5f\xb5\x2f\xc6\x81\x77\xf3\x38\x5f\xe1\x39\x7b\xe5\x84\xa7\x00\x89\xdc\x74\x1b\x4b\x00\x95\xbf\x7e\xb2\x99\x3b\x41\x8d\xf8\x7b\x14\xa1\xf9\x79\x26\xe8\x68\xdf\x6e\x56\x8b\xec\xa2\x21\x5f\x2d\xd7\xce\x8a\x3c\x9e\xe8\x49\xcb\x41\x34\x6c\x68\x4f\x7f\xfe\xf0\xa7\x92\xed\xf4\x33\xca\x99\xef\x34\xc7\x3f\x92\x72\xa7\xeb\x97\x58\x7c\x8f\xce\x4a\x51\x36\x44\x47\x37\x13\x8d\x53\xea\xdf\x3a\x84\xf5\x01\xbb\x10\x45\x6e\x8e\x4a\x40\x47\x08\x2c\x9e\x14\x35\xf5\x76\x52\x6c\x21\x64\x71\x4d\x70\xb3\xd0\xa6\xe9\xc0\x8a\x53\xe3\x23\x84\x0f\x4d\xcf\xe8\xf2\xd1\x9f\x0b\xe2\xc8\x8e"}, +{{0x85,0x04,0xfb,0xca,0xab,0xa6,0x76,0x83,0xf8,0x15,0x49,0x92,0x82,0xb6,0xeb,0xd4,0x97,0xa8,0x1a,0x91,0x56,0xf5,0x3e,0x02,0x5c,0x2d,0x3e,0xce,0xe0,0xdb,0x65,0x59,},{0xe6,0x2d,0xa8,0x64,0x93,0xa0,0xca,0xf5,0x29,0x21,0xd5,0x60,0x2f,0xbd,0xc3,0xdd,0x3a,0x84,0x36,0x94,0x1f,0x6b,0xe2,0x40,0xb3,0x15,0x09,0x68,0x12,0x38,0x74,0x6d,},{0xc0,0xea,0x07,0x4b,0xf9,0xad,0xde,0xe2,0xe3,0x35,0x0a,0x96,0x9e,0x7c,0x56,0x9e,0x3a,0xea,0x1a,0x41,0x88,0xee,0x5a,0xf3,0x4c,0xb7,0x3f,0x38,0x82,0x98,0x65,0x3d,0x29,0x9b,0x5d,0xbd,0x94,0x16,0x3f,0xba,0x20,0x9e,0x8f,0x7d,0xc2,0xe2,0x63,0x4d,0x3a,0x52,0xa0,0x28,0x10,0xa8,0x8c,0x61,0x52,0x94,0x5b,0xc1,0x6b,0xbd,0xfb,0x0c,},"\x6c\x63\xed\xbd\x40\xa0\x38\x74\xec\xae\xf8\x16\x02\xcd\x68\x50\xc0\x9f\x49\x15\xb7\xaa\xf4\x18\x25\x8c\x56\x83\x64\x53\x8e\x83\x92\xa8\xc3\x79\x83\x8b\x0c\x95\x34\x5b\xf6\x4c\x3d\xbc\x17\x58\x53\xfb\x64\x1f\x35\x0f\x0b\x53\xa0\x5a\x8e\xc2\x90\x28\x8c\x03\x26\xd4\x35\xff\x77\x6f\x86\x83\xa2\x73\x33\x3f\x9b\xb2\x80\x21\x84\xec\xc5\x3b\x06\xb2\x8c\x2c\x40\x2a\x54\xbf\x13\x4c\x1a\x23\x29\x97\x49\xa6\xce\x2b\x51\xa7\xba\x22\x23\x21\x48\x79\x7e\x99\x3f\xf2\x58\x28\x6e\x94\x77\x78\xa8\x74\x2d\x3f\x36\xcc\x78\x42\x97\x60\x43\xfc\x23\xda\x8a\x97\xec\xb9\x71\x5f\xc0\x5f\xb0\xf2\x3f\xa7\x32\x1d\xdc\x19\x32\x86\x16\x31\x60\x4e\xba\x2e\xf2\x5d\x8b\x75\x6c\xe4\x73\x36\x56\xbf\xd1\xe1\x47\x08\x92\x3a\xc7\xc6\x0a\x79\x84\x61\x36\xd7\x41\x97\x3b\xa5\x51\x41\x89\x72\x0b\xc0\xf7\x77\x4b\x7b\xd3\x57\x45\x95\xbd\xe2\x51\x50\x31\xb2\x5b\x62\x65\x4b\x16\x10\x35\x77\x80\x70\xac\xe1\x49\x71\xdf\x1f\xe0\xbe\x4e\xa1\xef\x55\xcf\x87\x47\xd3\x71\x6c\x1c\xe7\x07\xb1\xa7\xc8\x52\x0e\x6d\xeb\x33\x4e\xb1\x86\x33\x8f\xc9\x30\x00\x76\x8e\xb2\xbe\x40\xc6\xe0\xdc\x3f\x5d\xf8\x31\xb3\x2c\x3a\x2c\x33\xe2\x88\x98\xd6\x76\x2a\x15\x22\xd3\xd4\x8d\xae\xe5\x6a\x02\x69\xbd\xdf\x6c\xfc\x9d\x73\xf8\xd1\x78\xae\xcc\xbf\xfe\xf7\xce\x16\x4f\x98\xaf\xea\x22\x4a\x9b\x60\xed\xe4\x6a\x95\xfa\xdc\x9f\xc5\xd9\x4d\x20\x9c\x16\x6d\x9b\x8d\xe2\x53\x38\x1e\xa2\x24\x88\x62\x94\x6b\x9c\xf5\x34\x94\x74\x55\xc2\x44\x58\xcf\x56\x68\x3a\x0e\xc4\x7a\x2c\x65\x07\x5c\x69\x4c\x7c\x3d\x6a\xdf\x9a\xe5\xe8\xad\x31\xac\x76\x9f\x83\xaa\x26\xe3\x12\xc5\xb0\x1a\x9a\x09\x40\x4b\x15\xb8\x14\xba\xa7\x66\x6b\x3e\x03\xf0\x6a\x8d\x63\x48\xab\x8c\xcb\x9b\x60\xa4\xa4\xfa\xf8\x6f\x71\x35\xdf\x03\x9d\x95\x5c\x07\xbd\x92\xe7\xb8\xe3\x27\xee\x6c\x1b\x40\x19\x6a\x28\xb4\x44\x6a\xa5\xa9\xb2\xb9\x77\x3a\xb7\x6e\x3c\xe2\x11\x80\xf0\x9d\x6c\x08\xd2\x77\xc6\x77\x1d\x67\xe2\x2d\x84\x54\x0f\xa4\x3b\x38\xf6\x34\xcf\xc4\x6e\x5b\x8c\x33\xf1\x5a\x56\x8a\x77\xe4\x91\x4a\xad\x9a\xb8\xc9\xf7\xfe\xa4\x7f\x76\x77\xc0\x18\x80\xb3\xe8\x5d\x2d\x0e\x3f\xbd\x6d\xc6\xe9\x9e\x43\x7d\xdc\x73\x6f\x92\xb5\xa2\xff\x29\x27\xe0\xb4\x42\x14\x2f\x08\x97\xd0\xb8\xa1\x9a\xc2\x03\x63\x3d\xf4\x13\xfe\xaf\x8e\xf5\x0a\x5f\x76\x7b\xed\xaf\x20\xf1\xc1\x3f\x3b\x89\xd1\xe8\xb7\xbd\x18\xd5\x91\xf9\xde\x11\x6e\xe3\x4f\x98\x24\xe4\xea\xd1\xae\x9d\xa2\xe8\xca\xae\xf8\x8b\x29\x51\x6a\xa9\x42\xde\x77\xa7\x46\x7b\x6f\xb2\x6a\x66\x6f\x30\x64\x8c\x71\x5a\x2e\xe9\xf9\x46\x74\x3b\x54\x3a\x44\x28\xe0\xdf\xd0\x61\x78\xe7\xe9\x3e\xc6\xf2\x6e\x00\x3e\x05\x8b\xec\x14\xa4\xaa\x2e\x3b\x8d\xe1\x12\x95\xa7\x64\xca\xb3\x0b\x31\x3f\xcc\x57\x43\xb2\xfb\x89\x96\x2d\xdc\x5c\xdc\x6a\xa0\xd2\xe4\xa3\x06\xe7\x7a\xf7\x6a\x05\xa5\x98\x92\x3f\x62\x8a\x85\xdf\x1c\xc7\x3a\xd3\xbc\x01\xc4\xb9\x79\xbd\x7c\xb2\x96\x59\x0a\x88\xb0\xa4\x1b\x44\x5d\x50\xa0\x84\x23\xe4\xed\x80\xf1\x76\x3c\x71\x6b\x6c\x45\x7d\x84\x5d\xfa\xa6\x8d\x12\xb0\xd0\x3c\x55\xfd\xe8\xae\x6b\x2b\x92\xbc\x63\x22\x94\x3d\xbe\x54\xc7\x06\xbc\x8e\x5f\xce\xe7\x06\x54\xb2\x6f\x3b\xfd\x87\x7f\x5f\x53\x39\xac\x18\x2d\x54\x17\xbd\x4c\x07\x35\xd8\x25\xbf\x70\xe8\x5e\xab\x82\x16\xed\xda\x63\x2a\xe7\xe2\x2b\x3e\x53\xd0\x78\xa8\xb2\x0b\x5a\x7e\x23\x85\x33\x7c\xf9\x2b\x3c\x16\xb0\x23\x56\x3e\x11\xcb\x50\x43\xb7\x04\xd3\x7e\xb5\xed\x9e\x85\xfc\xdc\x95\xcf\x7a\x6e\xad\xe4\x08\x03\x17\x5a\x00\x8e\xf6\x53\xac\x61\x36\xf1\x61\x29\xab\xae\x11\x37\xc5\x82\x34\x00\x74\x8a\x81\x25\x62\x54\xd3\x17\xcf\xc9\x39\xe2\x6e\xa0\xce\xf9\xf6\x54\x8d\xb4\x28\x90\xc4\x8b\xeb\x04\x79\x10\x3b\xa0\x89\xe5\x14\x11\x80\x38\xb1\xb9\x09\x43\xd7\x16\xf7\xa8\xd4\xcd\xa5\x98\x3a\x67\x4b\x83\xa0\x02\xd8\xac\x9c\x65\x73\x4a\x28\xb7\x7b\x76\x0c\x8e\x38\x03\xf8\x78\x1e\xa9\x19\x9f\x79\x7c\xe7\x29\xe0\x6b\xff\xfe\x8c\x29\xb2\x0b\xc8\x52\x27\xc0\x9c\xc0\x52\x19\xff\x2b\xa3\x8e\x18\x05\x10\x83\x73\x2f\x83\xcb\xfc\xcc\x31\x07\x56\x45\x0b\x26\x1d\x5b\xe1\x83\xd9\xfb\x44\xec\x18\x52\x9f\x2c\xc9\x84\x8c\x40\x11\x9c\x60\x76\x76\xbc\x4d\x90\x15\xfd\x4b\xd2\xfc\x91\x8d\xc8\x03\x1e\xc1\x9a\x05\xff\x36\x2c\x18\x40\x43\xbe\x7f\xe0\x66\x01\x9a\xc5"}, +{{0xea,0xc0,0xf0,0x6c,0x2c,0x14,0xf3,0x7d,0x43,0x4b,0xc9,0x98,0x97,0x22,0x5d,0xd2,0xe3,0xf1,0xed,0x74,0xaa,0x74,0x42,0xc5,0x50,0x33,0x9d,0xf7,0x7d,0x0b,0x7b,0x32,},{0x43,0xe6,0x20,0x55,0xdb,0x6e,0x13,0x49,0xc9,0x4d,0x89,0x02,0x91,0x87,0x88,0x20,0x20,0xcb,0xcf,0x9d,0x75,0xe0,0x3e,0xb6,0x56,0xfa,0x0a,0x15,0xb1,0x90,0x02,0xd7,},{0x45,0xf2,0x80,0x3a,0xfe,0xb0,0xfc,0x44,0xd3,0xaa,0x96,0x5b,0x12,0x65,0x9b,0xf5,0x02,0xe4,0x72,0x95,0x70,0x61,0x84,0xb2,0xa1,0xc6,0xf1,0x6d,0x05,0x06,0x13,0xf5,0x96,0xa2,0x00,0x13,0x94,0xe0,0x0e,0x2a,0x44,0xc4,0x6c,0xf6,0x50,0x5d,0x5c,0xf5,0xb8,0xab,0x84,0x12,0xf0,0x7e,0xda,0x95,0x1a,0x15,0x00,0x5e,0x33,0x8f,0x3c,0x0e,},"\x27\xb7\xfd\x0e\x71\xad\xf1\x94\xcf\x54\x07\xb6\x77\x17\x93\x06\x0d\xe0\xfc\xa7\xca\x0a\xe6\x48\x35\xc4\x31\x87\x40\x8a\x70\x4f\x53\x3d\x5e\xa0\xc8\x3a\x65\x43\x87\xba\x7d\xb1\x6e\xd5\x8e\xc8\x37\x22\x6d\xf5\x7c\x1f\xe6\x38\x2c\x59\x19\xe9\x22\x13\xf6\xf1\x8c\xbb\x57\x35\xd1\x78\xa4\x76\xaf\x35\xd3\x90\xb7\xcd\x25\x56\x21\x7c\x53\x0f\x3a\x1f\x8a\xb2\x33\x9c\x1a\x5e\x8d\x96\x93\x87\xef\xd3\x94\x14\xb5\x6b\xb7\x84\xdf\xd5\xeb\x89\xb8\x59\xe1\xf4\x03\xa2\x38\xec\xa2\xa9\x41\xe6\xdb\x56\xac\x45\x6b\x73\x45\x06\x98\xd1\x45\x5e\xc1\xe9\xb3\x9a\x1e\x90\x7d\x6b\xc7\xe6\xcf\xf4\x24\xa2\x8e\xed\x57\x9a\xf1\x63\x10\x11\x5b\x67\xf5\xfc\xf7\xf8\x34\x6b\x3f\xa0\x26\x0c\x6d\xa2\xe2\x77\x55\xac\xa5\x70\xba\xbb\x3d\x30\x3c\xc8\x32\x46\x0c\x96\x3b\xfd\xd5\xc1\xff\xb2\xfc\x19\x92\x19\x29\xdd\xa2\xa7\x17\xfb\xcb\xeb\x2b\x85\x25\x76\x1b\xd6\x60\xce\x4a\x0f\x76\x85\x28\x5d\x7f\xad\x61\x15\xab\x09\xf8\xe6\x3f\x5f\x77\x39\x14\x49\x4e\x20\xbe\x1b\x51\x2d\x11\x14\xcc\xe3\xf0\xf6\x8c\x7d\x94\xf5\x48\x57\x69\x4f\x22\xaf\x4c\x69\x8d\x78\x2c\xe8\x37\xb0\xc1\x72\x2b\xb7\x31\x3b\xb2\xc4\x1f\x6d\x3d\xd1\xa0\x28\x77\xfb\x42\x96\xd8\x66\x2a\x9e\x86\x25\x98\x4d\xc1\xfd\x1a\x95\x10\xeb\xa9\xd6\x43\xac\x58\xa8\x86\xa0\x45\xcd\x0e\x53\xc0\x56\xa8\x33\xf9\x68\xb3\x5d\x01\x32\x0e\x9c\xc0\xb4\x35\xd3\xf6\xbf\xad\x26\xf9\xeb\x57\x54\xd3\x8d\xdf\x6d\x5c\x4b\xf6\x15\xa7\x64\x4a\x23\xf9\x82\x6b\xcc\x97\x60\x92\xd8\x2d\x81\xd5\x47\x00\x0d\xe0\x08\x1b\x7a\x40\xa9\x3f\xbd\xda\xc1\x3f\x7d\x99\x70\x8c\xcd\xee\xb9\x40\x5c\xd6\x34\xca\x07\x48\xca\xd2\xc1\xd8\xf1\x64\xf5\xd7\x7a\x4f\x36\x4a\xe4\x88\xbe\xdc\xf1\xf2\x0e\xb9\x54\xbc\x8a\x27\x8a\xf8\x14\x32\x41\x78\x56\xa9\x00\xf8\xf1\x52\x92\x1a\xfb\xe1\x79\x14\x22\x9a\x51\x3b\xd7\x1a\xb7\xe6\x61\xcd\xe1\x29\xaf\x93\xe2\x50\x94\xc5\x61\x18\xed\x1f\x22\xdb\x64\x44\x28\xb4\x74\x65\x1f\xe3\x6b\xe8\x2f\xa3\x69\x5c\x41\xfc\x86\x99\x66\x7e\x05\x37\x43\xb0\xa4\x11\x55\xc3\x1f\x1e\x26\x79\xc6\xe8\xcb\x9c\x9d\x1f\x5f\x4b\x40\xa3\x20\xa9\xfd\x9f\x47\xda\x9b\x94\x21\x1b\xa6\x01\xb2\x2a\x11\x52\x10\xd9\xf5\x59\xc4\x49\x6f\x01\x73\x24\x58\xf4\x9a\xc3\x4e\xb3\x86\x63\x6c\x8b\x6c\x68\xc7\xbb\xc0\x07\x8a\xb6\xf3\x98\xa6\x24\xb8\xba\xfb\x1c\x62\x29\x58\x56\x2d\x23\x1d\xff\xd4\xdb\x09\x61\x96\xbb\x87\x47\x9e\x42\xea\x22\xac\xbd\xcd\xe8\xde\xb1\x0e\x31\x16\x32\xf0\x2f\xca\x14\x78\x7f\xd3\x14\x05\x69\xb9\x42\x89\x91\x54\x3e\xc6\xe8\x34\xe1\x0b\x14\x9f\x23\xc7\x4b\xb9\x9a\xc7\xb3\x79\x9a\x20\x96\xd2\x2e\x38\x7a\x71\x2b\x6f\x90\x11\xea\x34\xc5\xbe\x4c\x46\x85\x81\xac\x62\xce\x66\x20\x63\x25\x2e\x06\x6a\x9a\x3b\x15\xc9\x57\x0d\x06\x5d\xc1\x61\x99\x29\xf0\x6b\xc7\x5a\x31\x79\x46\x8b\xc8\xa1\x6e\x3d\xdc\x4f\xe1\x85\xce\xba\x0a\x92\xa5\x46\xb8\x67\x5f\xc1\xad\xe5\x63\x07\x15\x0c\x7e\x4c\x84\x4f\x6a\xa5\xf1\xed\xbf\xb5\x4a\xc6\x32\xca\x2b\x25\x9c\x32\xa3\x3e\xe2\x86\x78\x56\xc3\x39\x0a\x67\x40\x36\x4c\xb0\xdf\xb9\x76\xe5\x3d\x0c\xc6\xc4\x2a\x10\x6a\x1c\x26\x91\x8c\x8a\x6a\x03\x3b\x2a\xa3\xc7\xf2\xe4\x39\x2e\x79\xf8\xec\xa5\xb3\x36\xba\xc5\x06\x1d\x76\x98\xa3\xbf\xe7\xc2\xc2\x92\x89\x25\x54\x03\x0d\xe6\xce\x7c\x0d\x06\xee\xfc\x54\x90\x6f\x81\xe0\x09\x7f\xcf\xf2\x7d\x14\xb9\xb7\x99\x4a\x79\x70\xe1\xa5\xf5\xc6\xb6\x40\x5d\xca\x22\x03\x3d\xff\x0e\xae\x13\x8a\xd8\x99\xf6\xee\x68\x12\x0b\x8f\x22\x74\x4b\x02\x69\xa9\xa8\x98\x9b\x6f\x7e\x08\xaf\xfa\xe7\x7b\xca\x21\x68\xad\xe2\x40\x58\xae\x68\xa7\xf8\x00\xe0\x2e\x7c\x38\x39\x1b\xaf\x56\x5d\xd4\x0b\x55\xfa\x3a\xb3\xc2\x47\xb9\xce\xb4\xd9\x67\x47\x17\x75\xe6\x63\xd6\xa1\xc6\xc7\xe1\x73\x50\xbb\xd6\xb9\xa3\xeb\x1e\x48\x4a\xc2\xe7\xa7\xa5\xc8\x4f\x50\x83\xe5\xac\xe8\x73\x0d\xe8\x9c\x47\xe8\xdc\xf8\x34\x1e\x40\xba\x34\x5d\xbd\x66\xba\xe0\xf7\xf0\x76\xa7\x05\xb1\xbb\x7f\x47\x0e\x3e\xdf\xb2\xb7\x8e\x4d\x63\x59\x41\x3d\x18\xd3\x32\x80\xb4\x54\xa0\xdb\xb8\x81\xd8\x60\x67\x26\xfa\x9b\xea\x27\x24\x75\xe7\x9f\xea\x6a\x54\xcb\x4c\x06\x19\x54\x1b\x4e\x77\xc1\x70\xc8\x61\x68\x74\xb9\x54\xbe\xb8\xd1\x05\xb8\x6b\xd1\x91\x7e\x25\xcf\xba\x92\x67\x18\x7e\xe2\x03\x8b\x3f\x00\x78\xf4\xc3\x18\xb5\x87\xcf\x44"}, +{{0xe6,0x08,0xd5,0xde,0x97,0x97,0x90,0x7d,0xb6,0xd9,0x8e,0x03,0x45,0xd5,0xca,0xf2,0xad,0x33,0xe0,0xed,0xde,0xbf,0x18,0xb8,0x1d,0x61,0xe8,0x37,0x3e,0xcf,0xb4,0x99,},{0x60,0xe0,0xc1,0x6a,0xda,0x58,0x6e,0x36,0x46,0x91,0x2a,0x5f,0x2b,0xb3,0x18,0xfb,0xc3,0xd5,0x0b,0x57,0xd3,0x6f,0xab,0xb6,0x37,0x69,0x6f,0x9d,0x8d,0x4d,0xc7,0x61,},{0x0d,0x8f,0x09,0x5e,0x42,0xa2,0x73,0x0a,0x3c,0x7b,0xed,0xf4,0x2d,0x5c,0x83,0x39,0x8b,0x5c,0x0e,0xe9,0xc7,0x7c,0x5a,0x61,0xd9,0x82,0x29,0x13,0x96,0xa9,0x18,0x2a,0x08,0x02,0xa3,0x7f,0x32,0x4b,0xc4,0xfb,0x5d,0x4a,0xa4,0xed,0x60,0x44,0x4b,0x66,0x14,0x4b,0xac,0xbc,0x86,0x51,0x05,0xd7,0x69,0x0f,0x14,0x06,0x50,0x69,0x1d,0x03,},"\xe6\x10\xfa\x7d\x83\x85\xc0\x9c\x78\x98\x9e\xd5\xef\x7a\x23\x05\x47\xf0\x13\xcb\x7e\x8d\xdf\x31\x74\x9f\xfc\x31\xce\xe1\x0a\xb3\xef\xac\xa3\xf1\x4e\xa1\x94\x51\x0f\x09\x85\xa8\x18\xef\x8b\x04\x0e\x10\xc3\xa5\x11\x4d\xe1\xac\x08\x0f\x14\xc3\xd6\x5d\x3c\x24\x4f\x92\x42\xf7\x54\x92\xca\xba\xe8\x00\xfc\xfc\x9b\xc2\x75\xea\x1f\x27\x72\x8c\x92\x0c\x25\x8f\xe7\xaa\x73\x94\x80\x60\x29\x9c\xb8\x78\x35\x79\x2e\xdc\xc0\x72\x15\x0b\x73\xce\xfe\xb0\xd5\x15\x62\xe5\x3b\x46\x81\x0e\x27\xa4\xd7\xf6\xab\xd3\x2e\x95\x9f\x7d\x73\x1d\xde\x01\xd9\x4b\xc4\x1e\xd8\x35\xef\xcd\x42\xc9\x22\x43\x70\x37\xa8\x7d\xd3\x66\xff\xad\x2e\xec\xab\x6a\xba\xeb\x4f\xcf\x07\x39\x2b\x3a\xb4\x0c\xfa\xef\xea\xa4\x26\x6b\xc5\x37\x67\x16\x93\xc9\x09\x3d\xab\xe8\xa0\x53\x8c\xaf\xd1\x2c\x63\x9a\x04\xbd\x2b\xa8\x0c\xe0\xf2\x9a\xdb\xfc\x66\xbd\x46\x37\xca\x05\x43\xa5\x3b\x0e\x37\x1d\x0e\x2e\x47\x0d\x31\xba\x36\x06\x42\xa4\x5a\xb4\xcf\xe3\xe7\x90\xf5\x87\xf6\xc5\xa5\x58\x3f\xd1\x5b\x18\x99\x78\x38\xa2\x00\x92\x1c\x1c\x39\x9c\x0b\x16\x27\x8b\x7d\xd6\xd3\xaa\xab\x6f\x32\x5b\x16\xaf\xdf\x76\x1a\x1b\xbf\x86\x7d\xe2\xbd\xd4\x86\x15\xf1\x5b\x52\x67\x70\xed\x20\xd7\x9f\x0f\x30\x71\x4b\xee\xed\xa5\x8f\x52\xa3\xcc\x0c\x5a\x61\x83\x15\xe5\x22\xb9\xeb\xe7\xcd\x99\xb6\x5e\xd5\x32\xa6\x2e\x0f\x0d\xf7\x27\x64\xd6\xec\x6d\x6d\x1b\xa4\x0e\xf4\x0e\x05\x42\x63\x60\x79\x5d\x6d\xd8\x5b\xb3\x9f\x73\x21\xd3\xfb\x06\x27\x5d\xe0\x96\xaa\xe4\xa2\xfa\x22\x93\xf3\x1b\x33\xf4\xad\x4d\x7c\x25\x1a\xc1\x3e\x8e\x15\xc2\xbf\xb1\xf9\x8f\x49\x62\xc5\x4b\x6c\xe0\x33\xb0\x8a\xa6\x26\xf2\x90\x5d\x46\x3f\x55\xb7\x1c\xbd\xad\xec\xdb\x3e\x0b\x36\x5d\xae\x07\xb1\x70\x30\x19\x83\xae\xb8\x3b\x1e\x9f\x2f\x28\xcf\x65\x41\x9f\xd6\xb0\xa1\xa9\xc2\x6c\xb5\x4b\x59\x49\xf4\xbc\x01\xa9\x86\x81\x84\x4b\x43\x03\x4c\x37\x2a\x45\x3d\x38\xf0\x47\x3d\x0d\xdc\x70\x9d\x9f\x49\xc8\x75\x3a\x75\xb8\x56\xc7\xe9\x77\x55\x17\xdf\x57\x4a\x09\xa3\x95\x3b\xde\x5d\xae\xdf\x8e\x4a\x8d\xa9\xd7\x73\xa2\x15\x12\x0e\x26\x9f\xa1\x86\x11\x33\xcd\x4c\xea\xeb\x91\xd5\xcc\xa2\x60\x63\x25\x45\x8e\x50\xcb\x96\x6d\x14\x05\x5b\x22\x44\x7e\xb6\x5d\xc1\x01\x18\xda\x08\x31\xdf\x28\xc3\xb4\xee\x8b\x11\xf0\x73\x2f\x15\x21\xbb\x94\x82\xb1\x1f\x5a\x86\xb2\x2f\x18\xe8\x3d\xd1\xd9\x67\xd3\x94\x42\x85\xe5\xd6\x3a\x5a\x98\x98\x17\xab\x24\x18\xbc\x7e\xd8\x91\xa3\x73\x84\x67\x47\xa1\x2b\x52\x7c\x2f\x44\xee\x01\x97\xb9\x46\xc6\x7e\x67\xfa\x4a\xa1\xc2\x9f\x33\x79\xd4\x6f\xe0\x7d\x3a\xab\x83\xda\x17\xf9\xd7\x6b\xed\xd3\x84\x36\xa0\x55\xe3\x4c\xa1\xd3\xaf\x5a\x87\x54\xd3\x8c\x17\xb9\xba\x4e\x64\x19\xcb\xab\x51\x5f\x43\x1a\x25\x95\x95\x4e\x42\x8c\x26\x70\xfa\xe3\xbe\xd6\x2b\x45\x96\x17\x9c\xb5\x9e\x21\x10\x87\x08\xd0\x71\xbc\xf9\xc6\x21\xc6\xdf\xf0\x3d\x3c\xdc\x92\x02\x02\x94\x54\x01\x3b\x9d\x13\x38\x47\xf2\x65\x44\x81\x1c\x01\x69\x77\x0f\xdc\x6f\xe5\x63\x8b\xfd\x7a\x72\x0d\x8b\x38\xf7\xe3\x0a\x7e\x68\x79\x06\x0b\x5f\x28\xc8\xab\x17\xb0\x02\x00\x71\x32\x07\xe8\x63\x7b\xff\x48\x44\xd8\x42\xd9\xca\x78\x83\x91\x34\x01\x98\xa3\xfe\x01\x72\xdf\xa7\x4d\xe1\xe5\x5a\xde\xfb\xc2\xe9\xbc\x7e\x88\x54\x76\xd1\xb9\xc0\x55\x81\x34\x08\xa4\x75\x28\x43\x43\x55\xbf\x03\xfd\xd4\xe2\x7d\x8b\x34\x61\xb0\xfb\x66\xab\x3e\x15\xa8\x79\xa1\x84\x45\x7e\x9e\xd9\xea\x6c\x51\xb6\x63\xb3\x1e\xdc\x8c\x4a\x3c\xd4\x54\xf6\x9d\x9c\xe5\x18\xd1\xb8\x78\x88\xee\x3d\x9d\xd5\x41\x6e\x43\xe1\x14\xac\x05\x72\x13\x52\xdf\xfc\x2c\xa8\x85\x97\x37\x7b\xbc\x41\x40\x09\xb0\xc2\xfd\x36\x9b\xe5\xba\x35\xa6\xdc\xe3\x47\x8b\x6c\x11\xb3\x3c\x0a\x33\x91\x8b\x6e\xe5\xac\x4c\xd4\xc2\xf1\xca\x6b\xd1\x90\xa0\x00\xa8\x38\xda\x38\xf5\x30\x77\x56\x03\x35\x59\x6d\x13\x58\x93\x77\x93\x96\x38\x10\xa7\x9a\x21\xb8\xd4\x61\x40\xe7\x68\x89\x8d\xcd\xa8\x8a\x0f\xaf\x8d\xdd\x0d\x63\x38\x47\xaa\xea\x0e\x03\x0b\xe6\x45\x5b\x41\xe3\xed\xe1\xe2\x87\x37\x30\xeb\x84\x81\xac\xaa\x7a\x51\x9c\xf9\x19\x58\x47\xa8\x6a\xfa\x57\xf9\x07\x1d\x44\xf4\xaf\x4c\xa0\xd3\x43\xc9\x0c\x0d\x22\xd9\x46\x14\x65\x85\xf0\x0e\xf3\xae\xf5\x7f\x0f\x9e\x55\xe8\x18\xc0\x12\x8a\xe2\x55\xdb\xc3\x11\x6c\xf0\xfe\x02\x16\x6d\x54\x85\x9d\xec\xbf\xdc\xcc"}, +{{0x0e,0x86,0x87,0x2c,0x78,0x62,0x0f,0x10,0xcb,0x6d,0xfc,0x46,0x3d,0x2c,0x28,0x72,0xc4,0xda,0x66,0x07,0x48,0xc9,0xcd,0xa0,0x1a,0xb1,0x45,0x69,0x58,0xaf,0xba,0x7f,},{0xde,0x49,0x89,0x98,0x92,0x69,0xca,0xbd,0x8f,0x4f,0x40,0x9c,0xf1,0xa4,0xd9,0x74,0x03,0x8b,0x27,0x55,0x02,0x27,0x35,0x57,0xf3,0x12,0xd5,0x55,0x3f,0xab,0x93,0xc3,},{0x20,0x37,0xe9,0x77,0x41,0xc3,0xe6,0x40,0x9c,0x66,0xfc,0x67,0x82,0xaa,0xb3,0x89,0xc5,0xd7,0x78,0x09,0x7a,0xc7,0x78,0x99,0x9e,0x85,0x76,0xe4,0x9e,0xf4,0xf6,0xa0,0xc7,0x73,0x0b,0xd9,0xe0,0x93,0xdd,0x3c,0x0a,0xe7,0xec,0x76,0x20,0x33,0x80,0xda,0x65,0x71,0x47,0xd3,0x3a,0x8d,0x9d,0xd6,0x5e,0xd0,0x0c,0xf7,0x62,0x24,0xd6,0x01,},"\xa9\x00\xf3\xe9\xc6\x43\xa5\x64\x9b\x07\x6f\xb6\x9c\x3b\x2a\xc0\x84\xd5\x2c\xcb\xaf\xcd\xca\x5a\x9d\xb1\xda\xa7\x05\x00\xde\x99\x33\xd2\x3d\x15\x3f\x74\x95\x4e\x1b\xd5\xf5\x7b\x89\x9f\xe8\xa4\xb1\x34\xc1\x95\x41\x2b\x49\x83\x3b\x6e\x50\x95\xa6\x55\x4e\xaa\x6d\x84\x4b\x11\xf1\x58\x4c\x85\x05\x5b\x87\xf4\x1c\x99\x96\x69\x04\x6c\x71\xae\xb5\xc0\x45\x3f\xd6\xa3\xc4\x37\xf8\x15\xf0\x68\x98\x7c\x38\x68\xcc\x07\xaa\x2a\xf6\x58\x19\x04\x6c\x30\x7b\xaf\xb7\x53\x0d\xe8\x4f\x71\x30\xae\xa7\x8e\xf0\x05\xd5\xff\xf5\x2f\x8d\xea\xf1\xd5\xe9\xc3\x26\xd3\x21\x7f\xc5\x5b\x94\xf6\x28\xaa\x10\x4f\x6a\x24\xa3\x95\xe6\x2d\x1b\x62\xbd\x9c\x0d\x82\x43\x63\x19\xc5\xd7\x3e\x57\x65\x43\x5f\x3b\xa8\x56\xa4\x73\x4f\xd6\x0a\xe6\x17\xf7\xf0\xc3\xba\x57\x22\xa7\x33\x66\xc8\x8a\x6d\xfe\xca\x85\xc4\x44\x63\x9f\x44\x1f\x2c\x55\xfd\xc4\x64\xec\xb2\x99\xee\xe3\x6d\x8e\xae\x06\x3b\xb9\x4b\xb2\x43\x9d\xa0\x4f\xa5\xeb\xc5\x09\x23\x38\xa5\x03\x5e\x48\x0f\x08\x34\xae\xee\x8d\x71\x1f\x28\xc4\x6d\xc9\x60\xde\x1b\xe9\xdf\x30\x7c\x18\xc5\xc1\x78\xb2\x62\x96\xdc\x56\x7f\x15\xbf\x60\x86\x3a\x36\x71\x08\x67\xe9\x2f\xd5\x10\x48\x86\x56\x74\xc2\xaf\x0c\x53\xb2\xe7\xa2\x48\xae\x5b\xd0\x9a\x49\xaa\x03\x06\x18\x49\x5f\x82\x48\x0c\x42\x0a\xe1\x06\x88\x9b\xec\x00\x62\x78\xb9\x22\x72\x07\x57\x09\xfe\xc9\x54\x87\xcf\xb1\x00\x61\xe6\x72\x2b\x93\xee\xbf\xc0\xbc\x58\x7b\xf7\xba\x5f\x66\x92\xb0\x74\xf5\x5a\x98\xd5\xc3\x02\x76\x0b\x1b\xf1\xd0\x9f\x7e\x86\x68\x47\x9c\xa6\xf0\x1e\xed\xa2\xfd\xaf\x58\x4a\xc2\x05\x8f\xbf\x7c\xf3\x10\x0d\x06\xb8\x09\x1b\xfe\xab\x51\xc0\xc0\xb1\xd4\xee\x3a\x82\x57\xf6\x9b\x16\x17\x60\x4f\xce\x95\x3b\xb5\xf7\xf2\x71\xc6\xa1\x88\x0e\xa1\xb3\xf6\x62\x67\xe2\x43\x9f\x34\x58\x06\x28\x91\x78\x77\xc6\x6e\xc0\xfe\xd7\x6e\x44\xe8\xbb\x2b\x91\xa8\x80\x6d\xf4\xba\xca\x6c\xc9\x28\x89\xb8\x80\x50\x70\xc9\xa6\x17\xf8\x07\x15\x75\x30\x75\x1c\xc1\x7c\x47\xb0\x9e\xeb\xa9\x4d\x22\xb4\xe5\x47\xc3\x70\xce\x7a\x49\x6f\xca\xa3\x41\x2a\xff\xff\xb8\xc9\xb4\xde\x89\xb9\xf1\x21\xaa\xec\x5f\x54\x4b\x0c\x72\x5e\xc5\xee\x9d\x4b\x34\x76\xad\xc9\xd0\x50\xed\xb0\xfd\xba\xf0\x2c\xa9\xe3\x8a\xf1\x5f\x51\x50\x15\xa2\x67\x29\x2e\xc9\xaa\x54\x44\xed\x1d\xec\xd9\xcd\x9e\x1e\xad\x64\x87\xa0\xcc\xef\x99\x5b\x1c\x60\x0a\x03\x69\x35\x83\x86\x60\xac\xab\x27\x6d\x8b\x0e\x5b\x07\xd9\xf3\x63\x53\x21\x4b\xf8\x0f\x94\x1a\xc8\x8c\xf4\x0a\x08\xaf\x91\x79\x26\x23\x41\x12\xec\xcd\xaa\x16\x2d\xc9\x9d\xe3\xe2\x5b\xaf\xf6\x5b\xb0\x1e\x49\x89\x89\x86\x33\x2b\xdc\x2d\x70\x5d\x5a\xea\x40\xf9\xbc\x4f\xbb\x28\x06\x89\x44\x96\x03\x8d\xa2\x36\xe9\xdc\x29\x60\x0c\x9c\xed\xea\xc3\xb6\x16\xcc\x56\xd8\x9e\xc2\xfa\x67\x38\x96\x66\xc6\xc4\xfe\x23\x3b\x63\x91\x05\x02\x3e\x10\x1b\x87\x4a\x63\x30\xfe\x57\x3f\x80\xac\xe5\x5d\x03\x7c\xc6\x12\xe6\xdf\xd5\xa6\xe6\x86\xf9\xa8\x30\x54\xfc\x46\xe1\x5b\xb6\xda\x45\x3d\x81\x0c\xf1\x38\xa1\x78\xbf\x03\x9d\x1e\x18\x16\x14\xff\x40\xcb\xe6\xbb\x3b\x47\x36\x63\x75\x2e\xa8\x02\x5f\xf7\xf7\x39\xee\x4b\x67\x11\x0f\x96\x80\x89\xb2\x47\x3c\xd0\x44\xd4\x8b\x00\x9d\x06\x77\xf7\x91\xf5\x4e\x2d\xf6\xaf\xdc\x3a\xcb\x9e\x99\xdd\x69\x58\xa4\x50\xc0\xe1\xb6\xdd\x5e\x97\xa2\xcc\x46\x29\x8b\x4f\x48\xac\x6a\xda\xf0\x13\xd7\x5b\x2c\x42\x07\x2d\x2e\xe1\x3f\x73\x36\x87\xee\x83\xc3\xf7\x0c\x4f\xdd\x97\x20\xfd\x17\x98\xc6\x62\xfe\xf3\xba\x01\x2b\xed\xd4\x45\xc4\x72\x9f\x21\x30\x48\x4f\xe7\x7a\xc1\xb4\xc4\xdd\xeb\x81\xfa\xf6\x0f\x76\xe3\xbd\x7d\x21\xa9\xa6\xc5\x7a\x69\xa9\xcd\x9c\xc2\x03\xfc\x63\xb5\x9e\xe8\x4b\x89\x15\xb3\xc1\x8a\x59\x54\xe2\x27\xc8\x6e\xbb\xb7\xd4\xc4\xc1\xa0\x8d\x0c\x5e\x46\x7c\x68\xa0\x69\x70\x75\x1e\xf5\x84\xbd\xd6\x11\xe1\xdd\x1b\x48\x90\x0a\xb3\x54\xb9\x9c\xec\x6e\x1d\xf3\xbd\x41\x46\xea\x07\x55\x35\x0d\xc1\x1c\x3a\x3f\x60\x0d\x47\x0a\x74\xf4\x75\xe4\xfe\xed\xaf\x08\x65\x27\x6f\xa8\xa9\x77\x13\x47\x1d\x0c\xa9\x95\x5c\x71\x35\x88\x33\x9d\xee\x79\x65\x6e\x56\x7e\x6a\xb1\xdb\xf9\x83\x07\x03\x81\x7a\xe6\x20\x92\x9a\x06\x84\xa5\xca\xf2\x0f\xef\x81\xa8\xee\x89\x7b\xe7\xe5\x05\xad\xe6\x49\x6b\x9a\xef\x02\x72\xbd\x8f\x35\x08\x60\x23\x3b\x33\x8c\x2e\x36\xd3\x13\x8d\xb6\x95\x38"}, +{{0x52,0x03,0x54,0xd8,0x5a,0x87,0xd7,0xc2,0x2c,0xa6,0xf7,0x84,0x71,0x44,0x10,0xec,0x98,0xbf,0x6a,0x65,0xf8,0x03,0xef,0x93,0x79,0xbd,0xc8,0x04,0x35,0x9b,0x23,0x49,},{0xd8,0x51,0x1c,0xea,0xc2,0xfd,0x66,0x1a,0xcb,0xff,0xb0,0x1b,0xa2,0x74,0x1c,0xad,0x88,0x99,0x34,0xde,0x63,0x92,0x96,0x1b,0xde,0xc6,0xfa,0x46,0x12,0x3b,0x7f,0x0f,},{0x75,0x4e,0x60,0xd3,0xf6,0xf4,0xab,0x4f,0x5d,0x0d,0xdb,0xb0,0x01,0x53,0x20,0x09,0x16,0x63,0x88,0x48,0x7f,0x78,0x0b,0x76,0xf6,0x0b,0xd0,0xbc,0x9f,0xef,0xab,0xfa,0xab,0x6b,0xe2,0xae,0x78,0x69,0x57,0x3a,0x64,0x79,0x6e,0xf2,0x84,0x6e,0x85,0xe5,0xcd,0xae,0x52,0xdb,0x10,0x44,0xfe,0xfa,0x79,0x6b,0xac,0xf4,0x8b,0x96,0x8b,0x0d,},"\xa1\xd4\xad\x48\x6e\xbb\x7c\x1a\x0a\xcb\x8f\x11\x70\x13\xe8\xe4\x74\x67\x89\xc6\x24\x4a\x56\xc9\xed\xfb\xf1\xef\x37\xac\x13\x09\xaa\xf5\x1c\x93\x75\xfc\x12\xca\xcd\x68\x97\xa4\x47\x95\x45\xf2\xbf\x39\x0a\xb7\xc0\xc0\xe5\xc5\x92\xf5\x50\x6e\x99\x38\x37\x8a\x11\xb6\x36\xbf\x85\x70\x29\xb9\x68\x54\x7a\xa5\x06\xc4\xa0\x82\x9a\x15\xfd\x39\x95\xfe\xad\x4f\x86\x0f\xd7\xc6\x23\xc6\x3e\x86\x95\x43\x6e\xae\x55\x81\x64\x14\x77\x83\x47\x09\x2f\x5f\x4d\x42\x2b\xb1\xb5\xe5\xa0\x69\x66\x24\x1e\xfe\xc1\x4f\x1e\x4f\xca\x06\x63\x91\x14\x71\x8c\x30\xeb\xca\xdd\x4c\x6d\x8a\xbe\x7f\xe9\x3b\x25\xd1\x71\x73\x53\x39\x54\x18\x8b\x1a\xb0\x3f\xcb\x77\x92\xcb\x63\x5c\xe3\x6e\x9b\xdb\xdd\xe7\xa5\x61\xc5\xf6\x69\x20\xd9\x10\xcb\x26\x9c\x8c\x1c\x3f\x59\x32\x65\x09\x00\x72\xc4\x89\x32\xe6\x92\xa9\xc7\x38\xc7\x04\x89\x74\x89\xa7\x15\xc2\xb3\x94\xd5\xa8\x6f\x70\x36\xa4\xca\xc5\xdc\xb5\xb8\x5c\xfa\x16\x21\x56\xe0\xbc\x6b\xfe\x02\xfb\x4c\x38\x60\x8c\xfb\x23\xc9\x2b\x8b\x6a\x3c\xb4\x6e\x48\x7d\x60\xe0\xdc\x97\xaa\x2e\x33\xe3\xda\xda\x92\x5e\x4e\x66\x12\xcc\x5a\xf1\x25\xe5\xac\xa4\x58\x17\xa2\xfd\x6c\x3f\xf1\x0b\x18\x93\x8b\x44\xbd\x4d\xd2\x0d\x7f\xcc\xf7\xf2\x6b\x40\xa6\x6f\x48\xaa\xff\xc9\xa5\x41\xe6\xd3\x71\x38\xfc\x55\x46\x98\x68\xe2\xd1\x03\x65\xef\xf3\x7f\xac\x36\x0f\xab\x3d\xc5\x54\x37\xac\x2d\x8f\xea\x74\x74\x40\x5f\xb3\x63\x0f\x79\x63\xd2\xd4\x59\x58\xf9\x09\xd1\x48\x30\x28\x6f\xf1\x52\xaa\x75\x2f\x51\x0c\xe9\x80\xbd\x57\x54\xe3\xfa\x32\xc6\x99\x24\xdd\x95\xd5\xc1\x52\xa7\x37\xa8\xfa\xdc\xfd\x0a\x45\x60\xe0\xb1\x14\xf8\xe8\xaa\xa6\x18\xd4\x38\xb9\x87\x71\x11\xda\x17\x40\xef\x81\x7c\x44\x19\x39\xec\xec\x79\x9b\xa1\x6b\x1b\x17\x1c\xa9\xb6\x49\xb7\xd7\x8f\xa0\x52\xd1\x49\x7a\x50\x76\x88\xbe\xde\x49\x00\xab\xc5\x3a\x96\x48\xda\x59\x17\x03\x5c\xef\xfe\x0d\xa2\x1c\x25\xc0\x9b\x06\xd6\x18\x5b\xdd\xa2\xd7\x78\xf7\xed\xe6\x15\x3e\x3e\xaf\xf4\x95\xc9\x79\x6d\x4d\x16\x6d\x2d\x2e\xa4\x18\xe4\xa4\xaa\x6e\x67\x8f\xaf\x06\x96\xe7\x52\xa0\x9e\x02\xea\xad\xe7\x63\x07\x0e\x08\x8e\x99\x64\x91\x9f\xf4\xaa\x4c\x82\xf8\x62\x9a\x3d\x5c\x79\x7c\x2a\x64\x59\x4d\x20\x68\x35\xda\x0b\xfa\x43\xcc\xd9\xdd\xfc\xdb\x6a\xac\x4d\x48\x6e\x03\xc8\x41\x22\x37\x59\x39\xa5\x27\x0b\xc1\x51\x9e\x07\x07\xe5\x1c\x3f\x46\xf1\xe5\xc5\x66\xb3\x3a\x24\x5f\xa0\xc2\x02\x83\x84\x72\x36\x3d\xe9\xf0\xed\xde\x2e\x79\x1d\x82\x29\x30\x95\xf7\x50\xbf\xf5\x45\xe6\xc3\x47\x39\xdc\xc5\x4d\xb0\xa3\x6a\xe2\xe2\xaa\x39\xb0\x7c\xb4\xf6\xa9\x64\x62\x40\xd2\xd3\x14\x88\xf6\x78\x15\xb2\x95\x45\xd2\x20\xbe\x92\x9e\x33\x39\xf8\x28\x1a\x93\x7e\x05\xa8\xc5\xc3\x88\x7e\x06\x04\x8e\xa7\xb1\x8a\x48\xf8\xd9\x1b\x1e\x3a\xf5\xca\xb5\xce\xda\x0e\xbd\x71\xbf\x54\xed\xec\x20\x3d\x37\x16\x5e\x4c\x9f\x9f\x80\x46\x1c\xd2\x9f\xcd\x99\xdd\xea\x43\x96\x93\x94\x1b\x5d\x53\xff\x94\x37\x9c\xf6\x42\x57\x1d\xd5\x59\xa1\x1f\x8f\x38\x3d\x94\x3f\x22\x55\xcf\x71\x58\x00\xaf\x77\x6b\x10\x45\xbf\x19\xa9\xc9\xbb\x09\x51\x55\xdf\xb6\x46\xb6\x5f\x4a\x28\x0f\x2a\x97\xef\x92\x7d\xda\xbe\x24\xa2\xf9\x71\xa8\x17\x0d\xd4\x2a\x08\x92\x76\x82\x5c\xb9\x14\x8c\x01\x5a\xae\x1e\x9d\xad\xf2\x2c\x10\xe7\x54\x8c\x59\xbf\x6b\x86\x8b\x20\xe8\x6c\x83\xa9\xe7\x34\x3a\xec\x27\x54\xee\x62\x25\xf9\xfd\xce\xaf\x8e\x51\xc4\x0e\x95\x5b\xda\x49\xc3\x5d\xed\x38\xfa\x8b\xcc\x1e\x6c\x8f\xc9\xc2\x41\x2e\x91\x04\xc5\xc2\x36\x8b\x1f\x99\x23\xe0\x10\xfa\x2e\xde\x91\x1d\x42\xb1\x39\xf4\x00\x7e\x34\x26\x92\x2f\xfb\x61\x58\xec\xa9\x7b\x47\xcf\xc9\x97\x85\x35\x12\xbb\x9d\x4c\xa2\xf0\x17\xc2\xc2\x63\xdc\x19\x9f\x3b\xf1\xeb\x4f\x15\x08\xef\x82\x8b\x0e\x00\xdb\x21\x00\x27\x36\xa7\xf2\x2e\xc9\x12\x98\x19\x45\x83\x13\x9a\xd7\x5f\x58\xe2\x1b\x51\x8d\xaa\x49\xa4\x07\x6c\x63\x75\xfa\xa6\x08\x91\xa6\x9e\x52\xa6\x56\x69\x9d\x80\x34\xa7\xab\x7f\xcb\xe4\x21\x75\x49\x14\x41\xfe\x61\xb1\x78\x3e\x83\x78\x57\x52\x22\x15\xa5\xfa\xc5\x59\x0b\xed\x2e\x9d\x20\x66\x06\x09\x6d\x3b\xe8\xee\x92\x87\x3b\xfc\x30\xca\xb1\x5c\xe9\xf9\x91\x0d\x01\xa1\x17\xf8\x99\x26\xcc\x3a\xfa\x8d\x10\x4f\x79\x9f\xf3\x80\x98\xde\x28\xb8\xff\x0f\x03\x87\x25\xc2\x90\x3b\x24\xc1\x42\x9c\xea\x49\x25\x24\x9d\x87\x81"}, +{{0x06,0x1b,0xcf,0x1a,0xa6,0xfd,0x98,0x98,0x97,0xb3,0x22,0xe5,0x91,0xcc,0xef,0x54,0x54,0xef,0x4a,0x5a,0xdb,0x1a,0x48,0x00,0xf3,0x26,0x11,0xcf,0xf2,0xb5,0xbc,0x78,},{0x73,0xc8,0x0b,0x73,0x4b,0xfc,0x94,0x17,0xd5,0x76,0x89,0x0c,0x20,0x16,0x6d,0xa5,0xc7,0xfa,0xbd,0x61,0x3f,0x75,0x47,0x4f,0x76,0x49,0x73,0x2e,0x00,0x29,0x5b,0xe2,},{0x5a,0xda,0xa9,0x43,0x30,0xa0,0x35,0x37,0x12,0xa3,0x4d,0xbe,0x97,0x3b,0x75,0x18,0xf9,0xa2,0xc7,0x13,0xf8,0xaa,0xd1,0x00,0x25,0x1b,0x08,0x6a,0xe8,0xde,0x26,0xf6,0xd2,0xb6,0xcc,0xf0,0x52,0x8c,0xc5,0xde,0xdc,0xa3,0x18,0xdf,0x19,0xcc,0x7e,0x45,0xde,0xae,0x28,0x1e,0x13,0x24,0xb9,0x6e,0x32,0xfe,0xf4,0x5a,0xaf,0x60,0xb1,0x0c,},"\xd6\x3b\xb9\x20\x8c\x1f\x4c\x7d\x43\x32\x6c\xf3\x5f\xa5\xd8\x39\x33\x15\x18\x04\xab\x89\x1d\x49\xb0\xbd\xaf\x42\x9e\x4c\x39\xa3\x21\x42\x8e\x0d\x90\xaa\x00\x31\x8b\x97\xe0\x8c\x70\x24\xc9\x12\xcf\x38\x88\x79\xf3\xcf\x97\x4b\xb2\x53\xa1\xe7\xa4\xc8\xee\xc1\x93\xbf\x4c\x14\xaf\x6f\xb9\x79\x4d\xf0\xd4\x97\x85\x0e\xdb\x04\xd5\x74\xc9\x7e\xd7\x6c\x70\x21\x39\x96\x84\x01\xb4\x0e\xb5\x43\x94\xef\x4c\xfa\xa7\xe5\xd3\xcd\x94\x3a\xf1\x21\x92\x53\x8d\xde\xe5\x93\xc2\xa2\x4a\x26\x7a\xfa\x13\x71\xfd\x77\xfe\xee\x20\x71\xf4\x36\x9f\xbe\xf8\x79\x76\xe7\xeb\xd8\x1d\x1e\x5b\x31\xd6\xe0\x9e\x02\xd8\x30\x35\x7d\x36\xbf\xf8\x59\x67\x03\xe4\x14\x6d\x08\x27\xbe\xc9\xc0\xf8\x7b\x26\xf3\x11\x95\xc9\x6c\x93\xb6\xd8\xc4\x67\x67\xec\x1b\xc6\xde\x39\xf0\x00\x8a\x41\xff\x87\x5d\xa0\x50\xa3\xf8\x65\xab\x92\xcb\xf2\x9c\x38\xa2\x80\xf3\xbf\x69\xf6\x8e\x92\xb5\xf4\x30\xcd\xee\x35\x01\x98\x1d\x0b\x3d\x18\x90\x96\xe0\xae\xac\xd6\x4c\x33\x10\x24\x21\x34\x88\x12\x15\x8b\xb6\x1e\x51\xae\x93\x65\x92\xb2\xf8\xf1\xb9\x10\x94\x9e\xf3\x72\x32\x58\xa9\xb4\x4e\x4e\x1b\xda\xdf\x1a\xe2\xcf\xc1\x8e\x37\xd2\xed\x0d\xd1\x73\x44\x04\xb8\xba\xa5\xf3\x93\xcd\x56\x06\x9e\xce\xbf\x7e\xdd\x7c\x06\xcf\x6c\x8a\xa3\xe8\xe1\x2f\xbf\x94\x6d\x7b\x32\xd8\x45\x3b\x6f\xbb\x65\x35\x52\x6c\x8f\xb8\xfc\x1d\x58\x15\x56\x0b\xb3\x1b\x99\x5d\xf2\xad\xbd\x83\x6a\xdd\x92\x9a\x56\xfd\xd9\x3a\x17\x47\xd9\x3a\x40\xc0\x5e\x12\x9e\xb6\xf8\x58\x3c\x29\x21\xcc\x9d\xbd\xda\x42\x25\xe1\x76\xdb\x38\x6a\x02\xec\x40\xaf\x10\x32\xc9\xb6\x2e\x95\x14\x70\x25\xf4\xac\x8d\xd5\x84\x33\xb6\x4a\xc0\x73\x15\x0c\x69\xb9\xc4\x15\x4d\xcb\xb0\x03\x44\xf3\x08\x11\x3c\xd9\x19\x9c\xcf\xb5\x07\x58\x01\xc7\x05\xb8\xfc\x43\xb7\xc8\xbc\x16\x73\x65\xe4\x62\x93\xd0\x6c\x4f\x48\x35\xc6\x4e\xe5\xd5\x38\x3f\x68\x90\xca\x35\xa8\x0a\xf9\x17\x74\x81\x62\xdf\x25\x18\xab\x14\x68\xf1\x53\x62\x98\x99\x40\x6c\xde\x66\xce\x07\xfa\x7d\x29\x93\xda\xbe\x0c\x60\x08\x9c\x91\x89\x24\x88\xf3\xbc\xaa\xec\x40\x8a\x0c\xd0\x8c\x9a\xa9\x8e\x09\x37\xe0\x2c\x41\xad\x52\xd2\x41\xa9\x98\x33\xe3\xb8\x3f\x7d\x3f\x1b\x07\x8c\x31\xd4\x5c\x34\xfa\x01\x75\xab\xbd\x0f\x32\x2b\x8f\xd2\xdc\x83\x49\x1d\xa2\x92\xad\x00\x76\x2e\x3e\x57\x7b\x9e\xee\x0a\xae\x08\x72\x90\x70\xac\x25\xe3\x3b\xc9\x45\x25\xbc\x0d\x2a\xb5\x97\x04\xef\xec\x5c\x01\x48\x42\x1a\x47\x92\x8d\x34\xb1\xe4\x5c\xe7\x21\xee\x64\x47\xfb\x08\x2a\xc4\x00\xb3\xe6\x84\x6d\x20\x4f\x7f\x9d\xb6\xf0\xa3\x2b\x2a\x69\x73\x8b\x3e\xe9\xdd\xbb\x0d\xbd\x7e\x0f\x04\x1d\x7e\xa5\x3a\x5d\x64\x7f\xb5\x0b\x39\xae\x24\xd7\x8c\x8b\x07\xcf\xc4\xe0\x52\x71\x1f\x0d\x46\x39\xe7\x21\xd5\xc3\x6f\x31\xb5\x88\x86\x67\x12\xb7\x57\x10\x8a\x40\xcc\x7a\xbb\xb9\x91\x30\x83\x30\x3a\xae\x05\xa0\xf1\xaf\x0e\xc6\x87\x84\x41\xa2\x5c\xf8\x72\x9a\xba\x42\xa3\xa9\x4c\xe9\xb7\x38\x88\xa0\xf5\xc9\xe4\x0c\x9f\xc4\x54\x10\xf0\x68\x1f\xa7\xf9\x08\x98\x56\x2c\xcb\x4b\xbc\x55\xf0\xab\x1f\xe9\xc7\x0e\xa6\x60\x26\xdd\xa8\xd7\x09\x0f\x7b\x38\xed\xb5\xae\xc1\x55\x7b\x11\x66\x98\x7c\xd4\x1a\x70\x59\xcd\xee\x60\x9b\x74\xd8\xfe\x06\xb7\x05\x9b\x77\x24\xbf\xf5\x30\x07\xf7\xe1\x10\x46\x2f\x06\xad\x14\xd0\x7e\xe1\xb4\xd6\x9a\xc8\x23\xbc\xf5\x76\xd2\xfa\x9e\x2e\x8e\xd7\xf3\x19\x80\x40\xd4\x71\x29\x60\x63\x13\x7c\x98\x1a\xdb\xf3\x64\xcb\x20\xf0\xa1\xad\x20\x54\x47\x2f\x7c\xee\x25\x27\xf9\x98\x09\x61\x5d\x2e\x4b\x73\x4b\x06\xf3\x5d\xee\xcb\xd6\x26\x19\x66\x3d\xde\x81\xd6\xe2\x35\x28\xb0\xc9\x71\x32\xaf\x0a\x23\xba\xd6\x3d\x9c\x08\x14\x2a\x26\xe2\x74\x3f\x86\x18\xec\xfe\x72\x3b\x19\xff\xdd\x0b\x19\xab\xd9\xa3\xf4\xfe\x21\x0b\x1e\x71\xac\xdf\xe3\x8a\xbe\xbe\x23\xf7\xfd\xef\x66\x38\x1c\xbc\x75\xf3\x07\xe5\x57\x72\x35\xb0\x2e\x4c\xd9\xcf\xaa\x15\x03\x08\x68\xed\x14\x53\xda\x58\xf7\x83\xb7\x35\x2b\x04\x65\x68\x44\xc0\x42\x44\x1e\xfe\x6a\x3b\x4f\x8f\xec\x8f\x7d\xe8\x07\x44\x54\x0c\x4f\xc7\xa1\x07\xf4\xe1\xbf\xcb\xd9\x9d\xa2\x5b\x97\x46\x09\x5d\xdf\x01\x25\xd5\x6d\xa7\xe7\xf8\x60\x3f\x04\xd3\x59\xa0\x88\xb4\xc0\x44\xf9\x36\xcc\xb7\xd8\xf8\x9e\xd5\x3c\xc9\x91\xa3\x49\x7c\xa9\x52\x09\x4f\xf3\xc3\x30\x46\xf2\x60\x9d\x07\xb2\x9b\x63\x39\x81\x36\x9c\xb2\xf0\xee\xcd"}, +{{0x2e,0x19,0xcd,0x44,0x2f,0x22,0xa4,0xa9,0x9d,0xff,0xc5,0x5e,0x7b,0xf6,0x25,0xf8,0x9d,0x13,0x44,0xb5,0x63,0xf6,0x78,0x53,0x13,0xa7,0xee,0xe9,0x73,0xb4,0xaa,0x36,},{0xee,0x3d,0xa7,0x6a,0x8f,0xcf,0x40,0x3a,0x29,0x58,0xd4,0x55,0x1d,0xa0,0xa7,0x2b,0x2e,0x73,0x85,0x22,0xb2,0xe6,0xb2,0x0f,0xba,0x6a,0xa2,0x6b,0x32,0x30,0x73,0x57,},{0x28,0x32,0x6b,0x5b,0x97,0x8e,0x0d,0xbd,0xab,0x5d,0xde,0x70,0x37,0x85,0xa6,0x67,0xa7,0xef,0x43,0x9d,0x81,0xea,0x47,0xe0,0x66,0xb0,0x89,0xd1,0x16,0xc2,0x5a,0x34,0xbb,0x63,0x3f,0x26,0x0d,0x55,0xf4,0x5b,0xdf,0x6b,0xcd,0xa7,0x48,0x03,0xd7,0x62,0x4b,0x19,0x27,0xce,0xc1,0x8e,0xb1,0x99,0x22,0x60,0xbe,0xef,0xc3,0x99,0xd9,0x0e,},"\x1b\xfc\x5c\x6a\xa6\xa5\x35\x4f\xbb\x86\x14\x69\x79\x63\x48\xac\x63\x19\x12\x4d\xa3\xf1\x0d\x20\xd5\x0b\xbd\xc7\x15\x9d\x41\xb5\xab\xb1\x36\xc7\x99\x6a\x77\x37\x97\x12\x2b\x52\x5e\x8e\x2d\xca\x19\x54\xf6\x39\x17\x07\x30\x1d\x90\xf2\x10\x1b\x46\xc7\xb0\x86\xef\xa1\x58\x77\xca\xdc\xd0\x58\x12\xdb\x34\xb9\x96\xcb\x4f\x53\x1a\xbc\xd1\xe9\x8d\xb0\x8a\x5c\xf1\x36\x8e\x8f\x4b\x11\x09\x14\x2e\x95\x62\xbd\x00\x85\xff\xae\x5e\x66\x0f\x59\xc9\x30\x79\x3e\xbd\xb6\xe8\x0b\x0a\x2f\x4f\x3f\x59\xbf\x9d\x39\x5c\x48\xd2\x6e\x0a\x72\xa6\x0f\x9d\x1f\xf8\x7f\xd2\xd7\xa3\xf5\x38\x3a\xa9\x02\xad\xed\xed\xeb\xc6\xcd\x1b\xef\xd0\x38\x33\x61\x62\x74\x9d\x91\xa9\x57\xca\x2e\x3d\xd4\x70\x91\xc5\x59\x31\x13\xda\x87\xc3\xd6\x6a\x02\xc8\x0a\x6e\xdd\xb5\x35\xc4\x8c\xa1\xf3\x4a\x97\xfd\x1c\x95\xeb\xc2\xe5\x70\xfc\x8f\xaf\xe6\xe5\xd6\x54\x6d\x1f\x3a\x9b\xa8\xda\xac\x33\x4c\xf4\x7b\xf1\x17\xe1\x28\x0d\x0e\xbd\xf1\x4b\x0f\xcd\xbb\x43\xb8\xd2\x48\xcc\x6b\x61\x32\x0f\xdb\x04\x49\xed\x5f\x5d\xe8\xba\xb1\x21\xaf\x0d\x85\x54\x95\x6e\x6a\x12\x01\x6b\x42\x67\x7b\x44\x36\x78\x92\xc3\xb2\x0a\xfc\xc2\xcb\x9c\xfb\x5b\x10\x0a\x95\xb5\x1e\x8b\x07\xda\x9f\x51\x41\x5f\x4c\xd7\x78\x1a\x31\x37\x65\xe2\x0d\xb2\x7f\x23\x43\xe0\xf7\x19\xec\xea\x9a\xf0\x26\x95\x6f\x33\x87\xe9\xea\x7e\xd0\xa2\x93\x75\x9b\x4a\x26\x22\x02\x80\x7b\x41\x30\x9f\xb8\x0f\x50\x18\x5d\xb6\xa5\xf8\xbd\xca\x17\x88\x41\xbe\xc0\x6a\xdd\xc7\x61\x0d\xf7\x60\x17\xb5\x14\xbc\x41\x42\xf2\x6a\x36\xbf\x5b\xac\xec\xb0\x12\xfa\x41\x71\x0d\xd8\x49\xbe\xf7\xa7\xe4\x51\x43\x28\x36\xfe\x9b\x32\x65\xfd\x5b\x59\xee\x40\xb0\x4d\xad\x85\xcf\x48\xf8\x91\x46\x5a\x84\x2c\xd4\x50\x0a\x10\x24\xee\xfd\xf0\xf5\x54\xf0\xca\x17\xec\x9f\x7b\x71\x52\x56\xa9\xb9\xdb\xe2\x79\x66\x38\x6d\x8a\xc3\x7d\x3c\x51\x58\x96\xde\x0f\x7c\xdf\x7c\xf5\xb3\x20\xff\x7a\x8e\xf6\xb3\x4b\xa8\x20\xab\xa9\x06\x6d\xd2\x53\xc5\xb7\x76\x37\x77\xf9\x4b\x2d\x6a\xd8\xc7\x10\x22\x1e\x11\x37\x53\x5d\xff\x8a\x1b\x75\x65\xec\x81\xbd\x8d\xde\xb5\x02\xe3\xd5\x8f\xf8\xf1\xfe\x6e\x86\xb8\xdc\x15\xa3\xaa\xec\x68\x8b\xbb\xec\xd4\x68\x82\x81\xdb\x0f\x81\x8d\xe0\xf7\x26\x1b\xa9\xcc\x58\xc8\xbc\x0d\x02\xe0\x66\x32\xef\xe7\x28\x7a\xd7\xa8\x43\x31\xa8\x24\xd9\x28\x73\x44\xef\xaa\xa7\x4f\x1f\xc5\x76\xd0\x26\x94\x30\xf8\x56\xa8\x56\x52\x65\xb9\xd6\xef\x71\xfe\x13\x4d\x25\x10\xab\x06\xb6\x0b\xf3\xc1\x53\xb5\x7e\xcf\xd2\xe6\x34\x24\x03\xfe\x67\x8b\x58\x86\xb6\xb7\x34\xb7\xd3\x69\x06\x62\xb6\xc8\xc6\xf6\xe2\x50\xe5\xaf\x6a\x81\x83\x16\x6d\xdc\xd0\xa1\x7f\x0c\xdd\xc8\x63\x6e\xf1\xa6\x84\x98\xbe\x50\xb6\x59\x95\x39\xd4\x6b\x4c\xea\x97\x13\x0e\x08\xf9\x4c\xa5\x3e\x88\x46\x44\xed\xa7\x5d\x23\xcd\x2c\x03\x8a\x5f\x17\xb5\x91\xe2\x13\x69\x37\x8c\xd3\xfb\x57\x62\xd1\xa7\xc3\xe6\x6a\x11\xae\x6e\x91\xcb\xae\x61\x6a\xd0\x55\xe3\x9d\xc4\x1e\x15\x4f\x4f\xce\xd7\xb2\x69\x6d\x9d\xc6\x73\x80\xbb\x8e\xef\x47\x4e\x9a\xa8\x3c\xec\x47\xfa\xfa\xfb\x94\x1d\x62\x65\x64\xb2\x07\x5b\xcc\x08\x56\xda\x8d\x6e\x1b\x0b\x8f\x18\xba\xf7\x51\x3b\xbd\x14\xe4\x91\xed\x51\x79\x68\xc4\xf7\x24\x1a\xf2\x50\x98\xee\x8d\xf1\x30\xb7\xa3\x4d\x59\x73\x6d\x78\x36\xd3\x23\xfe\x3f\x43\xf5\x08\xcd\xcb\x75\x58\x95\xf5\x9a\x00\xc8\x04\xed\x16\x4c\xc3\x39\x92\xf3\xae\xe9\x62\xae\x9e\x99\x0b\x74\x27\x2e\xb9\x87\xb1\x2d\x90\xb2\x73\x14\xd5\x74\x00\xe7\x37\xd1\x34\x3e\x97\x09\x85\xc4\x27\x10\x60\x87\x6a\xbc\xd7\x04\x9e\x7c\x9f\xe2\x44\xff\x3e\xf9\x85\x60\x99\x5b\x74\x82\xd3\x1b\xc7\xc0\x9d\x99\x69\xf7\xcd\x41\xf4\xe4\xe2\x52\x75\x0d\xc1\x6c\xcd\xb2\x9b\x98\x53\x14\xa0\xb6\xe7\x49\xc9\x5f\x9b\xd2\x83\x8d\x5a\xc4\x9e\xe0\x31\xfd\x07\x9b\xec\x30\x28\xdd\x9d\xd0\x7d\xb6\xfa\x62\x2a\xd6\x21\xb3\xb1\xe1\x27\xe8\xfc\xa3\x7b\xd1\x46\xe3\xcf\x70\x3e\x91\x17\x01\xb7\xa1\x6c\x2d\x30\x36\x9c\x94\x64\x8e\xcc\x03\xdf\x10\xd7\xdd\x5c\x05\x58\xfa\x95\x93\x42\x5d\x94\x87\x27\xd6\x86\x0c\x3a\x14\xf8\x11\x24\x51\x06\x61\x6d\x2a\x5f\xa9\x81\xc6\xb7\xf4\x7e\xc9\xde\xf6\x54\x12\xd1\x32\xac\xc6\x91\x9d\xa4\xe8\x85\x97\xaa\x91\x90\xca\x61\x4b\x21\x80\x66\xa0\xf7\xb1\x69\x97\xee\x74\x7c\x5a\x09\x78\x5e\x50\xd0\xa8\x91\xd9\x59\x37\x86\x3d\x61\x3c\xef\xf7"}, +{{0x82,0x10,0x90,0x99,0xd1,0xea,0xfe,0xed,0x5a,0x85,0x20,0x60,0x46,0x49,0x1b,0x34,0xd0,0x6d,0xcd,0xe3,0x3f,0x08,0x09,0x60,0x28,0x7b,0x10,0xfb,0x23,0xff,0x9f,0x78,},{0x08,0x1c,0xfd,0xf2,0xd7,0x58,0x65,0x4c,0x41,0xc4,0x47,0xe1,0xe6,0x27,0x38,0x10,0xf8,0xa7,0x38,0xa7,0x33,0xaf,0xc4,0x22,0x94,0xa2,0xb1,0xbb,0xb7,0x69,0xef,0xce,},{0xb3,0x98,0x7f,0x32,0x4b,0xc7,0xe7,0x76,0xc0,0xf2,0x87,0xfa,0x13,0xad,0x28,0x74,0x16,0x95,0xe2,0xe7,0xbc,0xe8,0xd1,0x43,0xe2,0x9f,0xad,0x5d,0x00,0x99,0x47,0x58,0xe2,0x25,0xfb,0x80,0x21,0x00,0xd2,0x3f,0xd6,0xcc,0xaf,0xee,0x8e,0x0a,0x95,0xbc,0x47,0x9b,0xe8,0xc2,0x3a,0x11,0x31,0x97,0x45,0x76,0x5b,0x7c,0xd4,0x7e,0x70,0x06,},"\x84\xf4\x7d\xd7\x94\x97\x7a\x6c\x15\x05\xac\x8c\x05\x68\x0c\x56\x15\xa2\xd5\xb0\x57\xe3\x9b\x04\xf8\x5e\x3f\x9f\xf0\x49\x60\xe0\xe0\x16\x68\x5a\x86\xee\xbc\xec\xf6\xfb\xce\x5f\xdd\xcd\xac\x1a\x47\x4c\x8a\x0d\x50\x2c\x40\xe1\x0f\x94\x86\x46\xfd\xac\x6c\x81\xf1\xff\xbb\x17\x7a\x2a\x49\x63\xb6\x78\x25\x90\x3c\xde\x65\xb5\xdb\xe0\xd8\x94\x1d\x54\x6c\xff\xa2\xbf\x8a\x8c\xa8\xd6\xc6\x40\x85\x30\xa6\x29\x0f\x5d\x08\x82\xf1\xa1\x67\x2d\xbf\x97\x8e\x10\xc5\xc8\xaf\x5e\x0a\x62\x39\xf0\x65\x5e\xe7\xfd\x9e\x66\x96\x30\x77\xa0\xe8\x47\x13\x73\x97\xd1\xf0\x69\x99\xdc\x6f\x8a\x94\x5c\x60\x03\xea\x4e\xa7\xfd\x58\x37\x8a\xcb\x44\xed\x57\x80\xea\xa3\x67\x79\x6b\xee\xa3\x7d\xdc\x23\x69\x99\xd0\x12\xd6\xa7\x16\xd7\x91\x56\x49\xcc\x28\xe5\x88\x75\x64\x7e\x9f\x5a\xc0\x55\x3c\x0f\x54\x4d\xf5\x64\x69\xc6\x70\x81\xd5\xe3\x03\x95\xf3\xe9\x60\xe6\xa5\x2f\x08\x33\x19\x2c\x54\x8c\xd5\x7c\x92\x6b\x82\xdb\x48\xc3\x61\xbd\xe7\x03\x33\xa3\x70\x08\x3e\xaa\xa0\x68\xdc\x2a\xe4\x52\xd2\x1e\xf1\x33\x1a\xed\x19\x0b\xd3\xe1\x28\x9a\x10\x4c\xf6\x67\x83\x43\x77\xcf\x7b\x5a\x29\x77\x48\x07\xc3\xf1\xea\x9e\x7b\x28\x83\x1d\x0f\x6c\x42\x94\x78\x58\x67\xb1\x37\xb6\x50\x28\xc1\x4f\x93\x2a\x1b\xa8\xe6\xf9\xf5\x96\x24\xfe\x0c\x39\x68\x43\xea\x19\xe4\x6f\xba\x09\x14\x2c\xf9\xd4\x24\x97\x31\x2f\x36\x02\x44\x03\x2f\x1e\x00\xf3\x8d\xd0\xde\x29\xf9\x63\xb5\xcc\xc1\xef\x12\xb2\xcc\x62\x04\xb9\x94\xaf\x1f\x3b\xaf\x19\x6d\x9e\x21\xe8\xfa\x4f\x09\x73\x20\xc6\x44\x04\xd0\xb7\xd5\xab\x38\x56\x0c\xa0\x65\x53\x64\xb0\xb0\x9c\xd6\xdc\x0f\x0e\x05\xb8\xc9\x11\x03\x64\xf1\x42\x4a\x96\x72\xb7\xef\xdf\x7e\x1f\x37\x8e\x23\x45\x50\x56\x6d\xbe\x13\xb0\x15\x78\xb0\x41\x53\xe9\xc3\x7b\x55\x3e\x32\xa4\x44\x1b\xc9\x7e\x29\x53\xbe\xc2\xe4\x14\x55\x51\x0f\x98\x02\xef\x94\x8d\xcb\xf1\x3f\xad\xdd\x72\x2e\xde\x57\x36\x27\xb2\x58\xd5\x5e\x83\xc0\x89\x5b\x22\x91\x9e\x4b\xe5\xce\x8d\x81\x9c\xe6\xad\x84\x3b\x2d\xd0\x9d\xf6\x40\x04\xc8\x26\xc1\xdd\xe7\xce\x64\x80\xa2\x71\xa8\x58\xa1\xdb\x16\x9e\x14\x94\xd4\x46\x90\x32\xbc\xc1\xcc\xd8\x96\x53\x19\x8b\x7c\x07\x3f\x76\xa2\x6a\x29\x99\xb5\x64\x8c\xba\xdc\x15\x74\xc7\x8e\xad\x8e\xec\xe8\x3b\x91\xe1\x29\xc4\x37\xf9\xee\xec\x04\xc8\x07\x45\x90\x02\xe6\x6d\xcc\xa9\xbf\xc2\xca\xed\x9e\x6c\x0b\xa2\x3d\x23\x55\xde\xf7\x56\x65\x74\x94\x30\xee\x92\xc5\x32\xa6\x95\x47\x9f\xec\x92\x91\x74\xf4\x40\xec\xb6\x1a\x5a\xe8\xb2\xb7\xe9\x58\x92\x05\x58\x26\x89\x78\xf7\xfb\x4d\xa1\xb3\x8b\x12\x01\x4f\x5d\x61\xb0\xfd\xd7\xf6\x13\x6b\xa4\x28\x1b\x41\xa3\xa3\xcd\x18\x80\x52\xb6\x98\x76\x5b\x6f\x05\xe4\x1e\x78\x37\x3e\xa8\x30\x46\x97\x87\xa3\x75\x10\x99\x3d\x12\xf9\x3e\x96\xc7\x2d\x72\xf4\x46\x19\x84\xf6\x91\xa4\x1c\x7d\x33\x97\xdd\xd5\xa1\xb3\x92\x37\xd1\x30\x88\x64\xd4\x15\xfc\x6c\x22\xb6\x3f\x37\x6c\xed\xde\x37\xf5\x25\x2b\x51\xec\x72\xe5\x15\x5f\x3b\xdb\x4f\xcd\x54\x12\x49\x8b\xd2\xe0\xc1\xf9\x85\x0b\x3a\x85\xd1\xdf\xd2\x51\x67\xa3\xcd\x77\x1e\x8e\x4c\x9d\x86\x8c\x95\xa7\x17\x5e\x37\x75\xf6\xce\xf1\x7e\x4e\x36\x49\x7c\xe9\xe4\x55\x32\xbd\x7f\x44\xb2\x77\x6e\x40\xf9\x1a\x07\xca\x4f\xa1\xb9\x5d\xbe\x81\xcf\x8f\x49\xe4\x6b\x6c\x82\xa6\xee\x43\x47\x91\x8a\x76\x43\xb0\xd9\xa3\x88\x57\x21\x2c\x69\x3e\xad\xac\xfd\x37\xa5\xf1\xd9\x15\x58\xf5\x45\x4d\xcd\xd0\x59\x35\xf2\x90\xe6\x2d\x7e\x65\x00\x6c\xd5\x49\xf6\x55\x3c\xe7\x41\xdf\x44\xd3\x96\x44\x00\x1e\xb4\x79\xca\x69\x56\x8a\xd1\xf2\x3b\xba\x09\x9a\x41\xa4\x72\x94\xdb\x93\x87\x31\xc5\x30\xaf\x1c\xeb\x92\x17\xd2\x9b\xc2\x70\x56\x13\xc1\xa1\xfe\x9c\x20\x8d\x0b\x01\xba\x6f\x4d\x9b\x4c\x7b\xa8\xf0\x21\xdf\x91\xea\x2d\x57\x8c\xe0\x83\x12\x3e\x83\xba\x4b\x9c\x50\x40\x7f\x66\x66\xfb\xe6\x11\x58\xb0\xd1\xb9\x57\x77\x72\xe3\xea\xff\x8f\xb4\x29\xd0\xf6\xd2\xe3\x84\x12\x61\x30\xf2\x1b\x44\x9f\xb1\xdc\x17\x0d\xb4\x5a\xf5\x05\xbd\x31\x82\x67\x8a\x9b\x5f\x9f\xdf\xf6\x5f\x04\x13\xb6\x72\xc4\x78\x63\x40\xfc\xf2\x52\x2e\xa7\xf3\xd8\xad\xe8\xa0\x59\x52\x96\x49\xdb\xda\x9c\xe5\x1f\xf0\x5a\x2a\x2a\x3d\x66\xd2\x16\x6b\xf2\xc9\xc6\x77\x2b\xa0\xef\x41\x05\xe6\x8c\x05\x5e\x02\x13\xd4\x2c\x1e\xe1\x23\xb3\xc1\x21\x78\x43\xe6\xec\x57\x5d\x75\x4d\xf3\xc9\x0a\x75"}, +{{0x65,0xfc,0xbd,0x62,0x6d,0x00,0x21,0x11,0x33,0x4b,0xaa,0xd4,0xe6,0xa8,0x00,0x6e,0x47,0xa1,0xf9,0x13,0x97,0xbe,0xe6,0xdd,0x6c,0xd7,0xda,0x5a,0x0e,0x02,0x48,0xa4,},{0x20,0x40,0x9a,0x14,0x6b,0x42,0xc9,0x6b,0xea,0xb0,0xb4,0x2e,0xa7,0xf2,0xc2,0x51,0x93,0x11,0x9d,0x0d,0xf4,0x4d,0xc2,0xbf,0x14,0xd1,0x1a,0x32,0xfd,0x73,0x36,0x15,},{0xbc,0x78,0xe1,0x6b,0xa6,0x74,0xe0,0xa7,0xdb,0xa5,0x7a,0x19,0x09,0x4f,0x97,0x33,0xc5,0x5d,0x74,0xb9,0xd1,0x5f,0x8a,0x44,0xd1,0xbb,0xc0,0xa0,0x23,0xf7,0x01,0x55,0xde,0x29,0x77,0x11,0x1a,0x41,0x7e,0xef,0xa8,0xcb,0x30,0xec,0x12,0xab,0xc8,0x38,0x42,0x28,0x16,0x7c,0x70,0x98,0x2a,0x82,0x06,0xb1,0xff,0xb7,0x21,0x74,0xaf,0x01,},"\xe4\xc0\x94\x7f\xc8\xca\x78\xfa\x88\x63\xf4\xd0\x44\x49\x9d\x03\x6e\x2e\x7e\xf8\xc1\x7e\x83\x8f\x2f\xac\x02\x67\x5b\x7b\x53\x81\xe5\xf9\xab\xce\xaf\xd0\xd8\x88\x6a\x92\x9d\x9d\x9b\x49\xfc\xb7\x38\x61\xb2\x9d\x15\x18\xac\x5f\x83\xf7\xf8\xfc\x26\xbd\x1c\xeb\xc2\x2d\x87\x3a\x9a\x08\x23\x14\x06\xfb\x03\x2e\x48\x66\xe5\xf5\x5c\x7c\x04\x41\xc5\x19\x04\x1b\xb2\xcc\x73\xf9\x22\x6d\xd5\xd0\x7e\xce\xb6\x60\xd6\xc9\x67\xdb\x23\x36\x55\x74\xbe\xe8\xfc\x10\x22\x29\x28\x76\x77\x13\x57\x1a\x71\xc9\x3a\x85\x27\x8d\x42\x29\x9a\x70\x59\x9c\xa9\x93\x26\xcc\x86\xf6\xd9\x8d\xaa\xc0\x00\xfd\xfa\x71\x05\x62\xf4\x81\xfa\xa0\x20\xc7\x2a\x76\xe2\x06\x7d\x15\x4c\x23\x5a\x7a\x4f\x29\x70\x8c\xc5\x44\x53\x3b\xd7\x99\xed\x63\x63\xeb\x3b\x56\xaa\x4a\x6d\x0e\x37\x9b\xbf\x07\x60\x05\x95\xc2\x3a\xb1\xf3\xf9\xf1\x70\x8e\x00\x70\x26\x1b\xbb\xf4\xbf\xea\xf6\xd6\xce\xd4\xd7\xff\x72\x2c\x9c\xc5\x2d\x91\x33\xea\x68\xd4\x95\xdc\x94\x89\xc3\xed\xf6\x83\x02\x31\x35\x1f\x65\xcb\x52\x72\xf5\x39\x6e\x2c\x4a\x1a\x5c\x88\x66\x1a\x10\x18\x92\x24\x9e\x23\xd6\xce\x9f\xdb\x6a\x9a\xbf\x74\x27\x2c\x2f\x59\xc3\xd8\xfd\x87\x43\xcc\xe4\x61\x12\x6c\xa0\xa8\xb8\x32\xb4\xb2\x18\x33\x6b\x1a\xe1\x4d\xa6\x77\xba\x7f\x1b\x2c\xc5\xca\x3c\x71\x58\xf7\x27\xa9\xe1\xb8\xfd\xd9\xed\xf5\xc2\x18\x7f\xcb\x83\xdb\x86\x2a\xd0\xc6\xb3\x92\x16\xde\x31\x16\x91\x95\x56\x46\x51\x00\xad\xe0\xa4\x2b\xd6\xba\x10\xd9\x54\x18\xb6\x9a\x3e\x00\x5e\x9f\x10\x45\x89\xea\x59\x48\xb2\xb5\x1b\xc7\xb1\xa9\xa0\x74\x9d\xa8\xf0\x13\x78\x1b\xc0\x5c\x80\x5b\xb5\x1e\x18\x77\x61\xac\x24\xc7\x64\x14\xf6\x68\xeb\x45\xfb\x0a\x50\x24\xdf\xe5\xa5\xca\x06\xf0\x40\x3a\x02\xe3\xb2\xfe\xf7\xa2\xc4\xbc\xfb\x1d\x07\x5d\x31\x0d\x51\x97\xe6\x59\xcd\x14\x02\x3f\xae\xc2\x0e\x04\x5c\xab\xcb\x86\xb2\x21\xa1\xd4\x82\x71\x13\xff\x32\x67\xa6\x4d\xeb\xe9\x93\x90\x04\xca\xba\xc8\x5e\x5c\x74\x61\xe7\xe8\x2a\x97\x5a\xcf\xae\x0b\x6c\x51\x6a\x1c\x60\x53\x74\xcf\xea\x7d\x81\x90\x44\xef\xd6\xd7\x46\x54\x42\x4f\xd5\xc9\x0f\xf2\x57\x4f\xcd\x8e\x00\x77\x40\xd9\x75\x86\x1d\x0d\xf5\x25\x9f\xe4\x3e\x43\x63\x9e\x36\xe5\x28\x95\x43\x9b\xa2\xc2\x7c\x1e\x88\x9c\x93\x09\x41\x04\xfe\x91\x49\x21\xbd\x6f\x25\xd3\x98\x5a\xb1\xf2\x2c\xa5\x57\xb0\xe4\x9a\xfc\x73\x75\x24\x3c\x52\x1c\x6d\x5f\xaf\xe0\x38\x1c\xce\xa8\x28\xe8\x8e\x64\x7f\xd9\x09\x76\xb3\xfb\xec\x19\xfe\x9a\xdb\x11\x3c\x64\x04\xbd\x35\x2b\xfc\x00\x04\x46\xd2\x10\x05\xb5\xf9\x50\xae\x07\xe5\x1c\x76\x8c\xa3\xff\x61\x77\xb2\xea\xc5\x0f\x10\xdd\x2e\x64\x61\x0f\xa8\xab\x57\x88\xfa\xee\xe2\x9d\x12\x90\x09\xd7\xfe\x46\xaa\x3d\xa6\xb9\xd8\x6c\x73\x06\x5e\xb5\x16\x1f\xbd\xbd\xfa\xc5\x77\x7c\x4e\x75\x45\x2e\x6e\x16\xae\x9f\xd6\x6b\xb7\xd9\xaa\xa4\x26\xbc\xb7\xa6\x91\x5f\x0f\xf4\x4a\x1f\x8e\xc7\x13\x94\xe9\x35\x2f\xdf\x20\xe0\x2f\xaf\xe1\xe0\xce\xfe\x50\x74\x4c\x31\x94\x95\x6f\x92\x8f\x82\x53\x37\x55\x37\x38\x38\xdc\xc1\x29\x6a\x89\x1a\xdf\x64\x1c\x73\x82\xd6\x9b\x4f\x5a\x43\xd4\xaf\x77\x72\xa4\xa1\xee\x87\x92\x92\xd7\xa4\xf3\x2a\xc3\x5e\xe1\x21\xc6\xc3\x4c\xa5\xf9\x84\x87\xa9\x41\xfc\xb1\xe6\x5b\x44\xd4\x45\x61\x27\xee\xdb\x2f\xcc\x1c\x3f\x48\xef\xf9\x30\x09\x81\xe5\x2a\xc3\x8b\x49\x6a\xb8\xbb\xce\x14\x4a\x85\xeb\x9c\x07\x63\x8b\x31\xfd\xaa\x78\x17\x44\xbc\xe1\x7e\x8d\x93\xdc\xdc\x60\xaf\xed\xa4\x88\x80\x76\x17\xf8\x8d\x6a\xa5\x44\x22\xfd\x34\x7d\xda\xdd\xef\xf3\x7a\x56\x3d\xbf\x19\x97\x4b\x2a\x23\xbe\x30\x0f\xbf\xa6\xc7\xfc\x41\xf8\x4c\x69\x05\x41\x52\x69\xf1\x95\x99\x0b\x5b\x4d\xe1\x26\x68\xc7\x1c\x87\xb5\x04\xf4\x11\x24\xbf\x94\x43\x6f\x33\x30\x45\x63\x15\x18\x15\x2c\x51\x62\xa2\x47\x5c\x40\xef\xb6\xcb\xda\xaf\x9a\xf4\x28\xfe\xd3\x25\xb3\xa7\xd9\x4c\x17\x52\x0f\xd8\x9e\x00\xdd\xf0\x8b\x22\xad\xf6\x61\xf0\xac\xd7\x23\xb3\x96\x9d\xc6\x43\x4e\xa6\xf9\x2e\xf5\x8e\x8d\xfa\xe5\xb0\xcc\x28\x85\xba\x98\x7e\xa1\xd1\x6c\x39\xb3\x4e\xf6\x50\x23\x00\x9d\x63\x45\xe4\x8e\x36\x91\xa4\x1f\x02\xa7\x7b\x7f\xe1\x33\xea\x9d\xe7\x56\x5f\x15\x7a\x20\x78\xae\x98\x8b\xbb\x26\x6d\x22\xd5\xfa\x91\xa7\xb2\x63\xe9\x8a\xd2\xdc\x07\x31\xfe\x5a\x29\x02\x5a\x0c\xb4\x36\x86\x4a\x5a\x60\xdb\x25\x7f\x1e\x76\xb5\xc6\x08\xf2\x5c\xde\xcc\x87\xea\xe6"}, +{{0xb5,0x00,0x76,0x8a,0x28,0x23,0x91,0x5c,0x4a,0x68,0x48,0xd3,0x5f,0x64,0x87,0xd4,0x3b,0xd7,0x66,0xd2,0xce,0x09,0x45,0xf8,0xa3,0xcc,0xdb,0x8d,0x82,0xa3,0x89,0x2b,},{0xb8,0xce,0xa2,0x15,0xa0,0x12,0x4e,0xed,0x27,0x00,0x57,0x25,0xd8,0x97,0x78,0x1e,0xa0,0x64,0xdc,0xef,0xb2,0x14,0x22,0xc8,0xbd,0x24,0x02,0xc5,0x6a,0x10,0x57,0x1c,},{0xe3,0xdb,0x47,0xa1,0x1e,0x10,0xe7,0x88,0x92,0x5d,0x14,0xb1,0xe2,0x8b,0x54,0xc9,0xfc,0xf9,0xb6,0xac,0xc1,0xdf,0x8c,0x14,0xf6,0x83,0xa5,0x67,0x2f,0xd5,0x04,0xdd,0x4a,0x47,0x5a,0x33,0x93,0xb3,0xef,0x8b,0xce,0xac,0x23,0x61,0xdb,0xba,0x35,0x30,0xaf,0x25,0xc2,0x46,0xc3,0xec,0x4c,0x05,0x89,0x9b,0x51,0x7f,0x6c,0xd3,0x4f,0x0a,},"\x0a\x9f\xda\x8b\x8c\xfc\xa7\xa5\xb0\x5d\x78\x11\x6f\xce\xe1\x9a\xb8\x03\xc1\xc6\x01\x0c\xe1\x1d\xaa\x8e\x93\xa6\x6d\x12\xc1\x2e\x47\x4e\xb9\x1c\x26\x40\xd9\x7a\x81\x3d\x9a\x83\x0d\x26\x88\x68\xeb\x2e\x37\x70\x42\x5f\x10\xc7\x58\x40\x46\x8e\x66\x9d\xc7\xf6\x1d\x3b\xe2\xde\x88\xae\x0e\x54\x2b\xc8\x09\x67\x91\x13\x95\x7a\x14\xda\x4e\xaf\xf5\x49\xbf\xde\x63\x7d\x7c\xaf\xdc\x6a\xa8\x39\x94\x83\x73\x97\xf8\x6e\x4f\xde\x86\xd4\x02\xfa\x9a\xef\x7f\x65\x54\x9a\x21\x43\x73\xe5\x60\xe6\xd7\xa1\xc2\x76\x9e\x0c\x7d\x5a\x01\x71\xe7\xcc\x00\xdf\xf3\x6e\x04\x29\x79\x8b\x53\xaa\x62\x16\x24\xbd\xa7\x4d\x6d\xf0\xbf\xff\xfb\xd8\xfd\x7b\xef\x1a\x64\xf3\x6c\x00\x07\x82\xf6\xed\x03\x1a\xf5\xc2\xa7\x4a\x18\x96\x35\x98\xc9\xba\x06\x23\x92\xde\x96\x02\x03\x67\x94\xb7\xb5\xe6\x8c\x25\xc9\x3f\xe7\xcf\xad\x47\xa7\xc5\xb9\x79\xd4\x76\xcd\x51\x3a\x12\xbf\x03\x07\xcb\x16\x31\x74\x00\x42\xa9\xfb\xf3\xeb\x0b\xe5\x17\x06\x20\xda\xfd\x5f\x16\xed\x89\x34\x2c\x26\x25\xd7\x83\xe7\x4e\xe0\xd7\x84\xbf\x05\x19\x43\x74\x0c\x88\xb0\xbe\xf7\xbc\x85\xe1\xa6\xa4\xa5\x17\xd4\x92\xfb\x73\x7e\x77\x66\x99\x59\x0c\x93\x22\x4c\xd4\xd9\x24\x5d\x4e\x93\x71\xa3\x67\xc0\x71\x2f\x87\x49\x0f\x92\x47\xc4\x9a\xdd\x93\x13\xf2\x77\xa4\xd9\xf2\x6b\x75\xaa\xe4\xde\xd6\xa3\xde\xf8\x5f\x83\xfc\x99\x59\x10\x40\x55\x48\xaf\x67\x0e\xd8\xaa\xa3\x05\x24\xab\x82\x9c\xcb\x56\xa5\x00\x5b\x58\xbc\xe8\x68\xc9\xe8\x07\x4f\x07\xdd\x7f\x38\x18\xf2\x99\xe4\xe0\x86\xbe\xd9\xea\xb9\x02\xcf\x11\xb3\x98\xd5\x31\xb8\x63\x2e\x7d\x52\x3a\x8f\x87\x76\x95\xf4\x6c\xcf\x9c\xe2\x4e\x62\xca\xb2\xc7\xcd\x0a\xae\xe1\x7d\xb5\x26\x76\xa4\xb5\x05\x8e\x9c\x1d\x7c\x47\xbf\xfc\xb6\x41\xb0\xea\x2b\x09\x44\xf3\x9a\x75\x66\x5a\x7e\xf2\x9b\x7f\x02\xa8\x78\xdb\x82\x38\x83\xbd\xac\xfb\x0f\xbe\x5d\xfe\x5a\x9b\xed\x9f\xda\xc7\xe4\x14\x2e\x3e\xb5\x0d\x5e\x84\x0b\xd0\xac\x0b\xec\xf4\xfa\x97\xe1\xfc\x48\x27\xc3\x97\xa5\x24\x65\xd9\x16\x88\x99\x54\xb3\x70\x1b\x0f\xac\x61\x15\x9b\x23\x09\x2f\x46\x85\xf4\x78\x8b\xad\x35\xd0\x0d\xa2\x67\x9e\xcc\x54\x92\x1f\x1a\x86\x47\x10\x16\x57\xab\x49\x47\x74\x20\x56\x7a\xed\x67\xc8\x60\x59\x30\x44\x4b\x5d\x07\x92\x7c\x17\xef\xf1\xf8\x57\x0c\xf2\xaf\x29\xe7\x19\xf8\x5c\xa7\x84\x9b\x89\x55\x49\xf1\x3d\xfe\xca\x68\xbb\xef\x71\xe3\xce\x8b\x6c\xed\xd2\xff\x68\xd3\x2b\x02\xca\xf5\x95\x1a\x0b\x3e\x6b\x0b\xae\x6a\x96\xc0\x20\x58\x19\x1f\x30\x5e\x09\x07\x11\xc4\x6d\xad\xdc\xd5\xae\xee\x76\x9c\x3a\x10\x5e\x9a\x82\x7b\xbd\x19\x5d\x32\x92\x31\xc2\x62\x38\x47\x9a\x9b\xb0\x07\x1a\xfb\x16\x0e\xf9\x55\xe8\x74\xd7\xa4\x20\xc5\x67\x85\xf4\x4a\xe0\xa1\x8c\x52\xd8\x28\x0c\x59\x98\xcf\x38\x88\xfe\xaf\x89\x89\x81\x34\xbc\x8d\x41\x1f\xc9\xf6\xc5\x76\x8e\xa7\xa2\x49\x72\x94\x13\x73\x9e\x53\x2b\x64\x39\x37\x15\x2c\xdf\xb8\xd2\xff\x87\xfd\x48\x08\x4d\xd8\xae\xeb\xea\xf0\xf7\xb1\x0d\x87\xb6\xe4\x42\x32\x28\xc9\xfc\x8d\xc5\xe3\x85\x2a\xa8\xb8\xac\xc5\x45\xd1\x8f\x25\xc5\x5d\x73\xda\x1b\xb8\x2e\x3e\xb3\x76\xf9\xef\x05\xb2\x74\xd7\xec\xb1\x84\x5d\x65\xca\x0c\xd2\x62\x9f\x03\x8a\x2d\x66\x4d\x7a\x69\x78\x1c\x84\xe9\x8d\xe2\xc2\x09\xc4\x6e\xfc\x51\x16\x21\x72\x85\x66\x49\x46\x9e\x67\x33\x08\xdc\xc1\x45\xea\xf7\x83\xf5\xcb\x5b\x4b\xe7\xd9\xfd\x58\xee\x09\x74\xc9\x81\xa3\x8f\xea\x8e\x31\x26\x7a\xbf\xa4\x10\xe6\x9e\x46\x48\x2f\x51\x34\xf3\xda\x1f\xfe\x38\x1b\xd6\x9d\x8d\x0b\x78\xea\x90\x9b\x4a\xf9\x39\x6d\xca\xff\x89\x96\x0a\x04\x9e\xda\x69\x46\x61\x6f\xc2\x7c\xcf\x9a\x9e\x5b\xa1\xa0\x13\x57\x64\xf3\x77\x19\xda\x4d\x28\x07\x81\x85\xd0\x4d\x72\x41\x9c\x2c\x70\xf2\x90\xd9\x7e\x1f\x82\xb8\x79\xf7\x1b\x9e\x19\xd5\x04\xd3\x64\xcd\x3b\xa2\x2c\xf9\x05\x25\x0f\xd3\x7d\x58\xe5\xfe\x40\x20\x9f\x60\x72\xa0\x6d\x8b\x5b\xa7\x01\x96\x23\x05\x77\x87\x7e\xc4\x61\x53\x16\x7a\x7c\x7a\xea\x27\x0f\xa1\x09\x8a\xba\x9e\x3a\x74\xac\xb3\x6a\x11\xb0\x9b\xd0\x7a\x3b\x88\xea\x65\x4e\x26\x83\x65\x62\x5b\x58\x9b\x22\x06\xc7\x10\xd9\x60\xf4\x2e\xa4\x19\xb7\xe4\xe3\xda\x47\x59\xfc\xbc\xa5\x0e\x4b\xf4\xcc\x55\xcf\x88\xf7\x0b\x31\x80\xc8\x05\xa7\x04\x50\x86\xaf\xa0\x4c\x6b\xe2\x32\x23\xec\xae\x5f\x82\xc1\x46\xd5\x43\x11\xd1\x80\x7c\x2e\x4a\x53\xf9\xe0\xa4\x48\x2b\x4e\x1e"}, +{{0x9e,0xb5,0xc9,0xef,0x13,0x53,0x5f,0x80,0x81,0x09,0xf4,0xa4,0x3c,0xfa,0xd5,0x68,0x4f,0x80,0xda,0xf0,0x2e,0xed,0x54,0x10,0xac,0x0b,0x0a,0x09,0xa6,0x08,0x2d,0x69,},{0x36,0x7e,0xea,0x1e,0xcb,0x4e,0x5e,0xec,0xdf,0x7e,0x47,0x1b,0x90,0xbb,0x34,0xf9,0xb7,0x98,0x2c,0x8c,0xd6,0x6d,0x42,0x55,0x5c,0x24,0x0b,0x41,0xcd,0x87,0x39,0xdb,},{0x42,0x9c,0xe1,0xfe,0x84,0x6d,0x25,0x08,0x49,0xec,0xa7,0xd4,0x56,0xf8,0xc5,0x9f,0x86,0x75,0xb1,0xf4,0xc1,0x3f,0x2b,0xe4,0x16,0x88,0xdf,0xb8,0xca,0x2a,0x3b,0x24,0xae,0x29,0xd5,0xb6,0xbf,0x47,0x11,0x57,0xbc,0xb6,0xe2,0xec,0x9d,0x4a,0x26,0xb0,0x38,0xe6,0xec,0x28,0x58,0x4c,0xc2,0x3f,0x2a,0x03,0x55,0x6d,0xbb,0x37,0xe9,0x00,},"\x2d\x7c\xb0\x5e\x61\xdb\xae\x26\x25\x8e\x38\x61\xc6\x39\xef\x0e\x1d\x17\xfc\x71\x1a\x00\xf3\x35\xba\x3c\x02\x71\x37\xe0\x07\x08\xd7\x08\xc1\xff\x45\x7f\xf2\xc6\x51\x12\xf7\xdc\xd7\xd0\x2f\x24\xd5\x6f\x07\x21\x58\xea\x1c\x71\x83\x25\x50\xa5\x83\x66\xfd\x91\x97\x29\x6b\xbe\x61\xaa\x4d\x00\xde\x18\xa4\x53\xef\x91\x74\xfa\x81\x96\x83\x05\xc4\x1c\x34\x55\xf4\x2d\x44\x7a\x92\x34\xf0\x6e\x13\xbf\x8b\xca\xa1\xba\xbb\x11\x69\x5f\xaf\xdc\x08\xf7\xa5\x84\xb2\xea\x1f\x61\xe9\x38\x92\x60\xce\x73\x35\xa0\x7d\xe7\x2c\x89\x11\xa5\x8a\x31\x3f\x10\x88\xdc\xdf\x5c\x8d\x4c\x45\x6c\xba\x2d\xcb\x4f\x2d\x15\x6b\x49\x43\xb9\x5b\xd4\x93\xea\x4f\xe1\xa8\x2d\x4e\x3e\xa0\x2a\xa0\x29\x72\x40\x0b\x5e\xe1\x78\x42\x83\x2d\x59\x97\x9f\xc1\x79\xf8\x43\xc4\x4b\x03\xeb\x3c\x30\x24\x16\xd0\xcd\xaf\x11\xc4\xca\x8a\x66\xcc\xbb\x69\x97\x39\x5e\xdf\x6f\xca\x2e\xa0\x04\xcf\x34\x86\x97\x10\x04\xa4\x20\x42\xaf\x8e\xce\x00\x5b\x94\x46\x1d\x86\xdc\xde\x21\x2a\x2e\xb1\xbe\x3b\x91\x4c\x78\x3e\x48\xac\x1a\xd4\x6c\xac\xd7\x3e\x1e\xb4\x48\x36\x83\x22\xd2\x67\x8e\xfc\xb2\xab\xff\x52\x09\x3d\xb0\xf2\x59\xdc\xe5\xc1\xe1\x9a\x51\x28\x20\xf2\x35\xd6\xae\xaf\x0e\x1a\x72\x3c\x2c\x65\x0c\xff\x1e\xe3\xb6\xb4\xf4\xcc\x98\x9c\x0b\x7d\x6d\xe3\xcd\x7e\x6d\xaa\x39\xbb\x69\x07\x10\xdf\x00\xa7\x19\x4c\x17\x20\x1f\x0e\x81\xbe\x64\xb6\x73\x9e\x1c\x1e\x81\x76\xb7\xe1\x2a\x35\x34\x27\xc0\x67\xc1\x93\x14\xdb\x64\x2e\x5c\x76\x26\x6b\x64\x0e\xb1\xcc\x0c\x73\xf8\x4f\xc0\x22\x7e\x5a\x96\x06\x0d\x81\x40\x71\xcd\xe2\xfe\xd9\x44\x76\x7b\x74\x66\xf9\x00\x1d\xfc\x22\x36\x85\x42\x9b\xc4\xe5\xe4\x8f\x5c\x13\xa6\x3a\x4e\x0d\x82\x61\x33\xad\x92\x0d\x11\x77\x21\x45\xad\x6e\x13\xc9\x38\x97\x39\x8a\x8a\x40\x1f\x93\xdb\xd1\x03\x00\x5c\x7d\xae\x44\x38\x7f\x3e\x80\xb7\x93\x60\x7d\x05\xd2\xd8\xbc\x0d\x03\x51\xa3\xa4\x52\xb8\xce\x75\x9c\x1a\xd4\x8d\xf7\xb9\xba\x9e\x4a\x17\xdf\x61\xfd\xab\xb9\xb5\x77\xb5\xce\xc3\xe9\x46\x1f\xbb\x5e\x12\x81\x55\xa3\xc9\xc8\x9f\x8f\x6b\xeb\xb7\x32\x2a\x16\x67\x8e\x8e\xcb\x98\x95\x3d\x95\x83\x10\xdb\x1b\x06\x34\x48\xc3\x49\xf3\x6e\x16\x8f\xac\x48\x4c\xb3\xc0\xd4\xcb\x2c\x25\x1b\xd9\x2e\xf8\xe9\x26\x2b\x44\x09\x3d\x7e\x65\x0a\x7d\x3b\xed\x37\x91\xfa\x88\x10\x0f\xee\x6e\xf0\xd5\xe2\x3d\x1e\x9a\x80\x99\xcc\x03\x35\x20\x2a\x4f\x10\x6c\x24\x77\x7e\x98\xf8\x1d\x26\xef\xba\x15\xc9\xad\x15\x41\xe0\xad\xbf\x1d\x1d\x76\x07\x6b\x0d\xfd\x7b\x7d\x6c\x8b\x82\xf9\xc0\x93\x46\x8c\xd1\x96\x67\x2d\xc5\x47\x8e\x91\xce\x70\x1c\xdd\x7b\x68\xb3\x53\xc9\x71\x11\xf0\x42\x97\x60\x63\x57\x62\xf8\x68\x3a\xe9\x70\x56\x4b\xce\xba\x91\x20\x51\x76\x42\xe8\xb3\xa2\xba\xaa\x85\xc2\x5b\x54\xa9\x43\x76\x61\x84\x90\x4c\x72\xd9\x29\x63\x4e\xc5\xf0\xc2\x84\x73\x41\x5f\x12\x53\x89\x06\xc6\x78\xfc\xa4\xe6\x82\xdb\x48\x79\x75\x84\x92\x53\x7e\x78\x50\xb9\xbf\xef\x3e\xb9\x05\x3b\x43\x92\x0d\x81\x0e\x55\xbe\x96\x6a\xec\x68\xc9\xdd\x3b\x62\xcc\xf5\x7e\x81\x78\xcb\x5e\xf6\xd1\x6d\x17\x2a\x56\xdd\x92\x4f\x00\xf2\xd3\xb5\xe9\x3a\xaa\x92\xb2\x9f\xb8\x33\x6d\x73\xe2\x9e\x59\xd1\xc4\x7e\xa6\x23\x0c\xda\x1d\x5b\x03\xbb\xa5\xdf\xdb\x33\x1f\xeb\x19\x44\x3f\x12\x3d\x2a\x03\xff\x4f\x10\xec\xa1\x66\xc2\x99\x85\x88\xf1\xe5\x84\xed\x19\x4d\xd6\xf7\x3c\x8a\xca\x84\x66\x31\x90\x4d\x9f\xe4\xa9\x8b\x36\x78\x23\xe4\x6e\xdb\xa2\x88\x51\x29\x87\x9e\x92\x77\xe1\x50\xf0\x29\xb8\xfa\x7b\xd1\x1e\xab\x9c\xe1\x33\x67\x77\xc8\x0b\x56\xb3\xa1\xf0\x81\x1a\xdb\xca\x0f\x5b\x40\x25\xa5\x50\x3c\x81\x96\x66\x1a\xee\x90\x00\x6e\x9c\x85\xbb\xfa\x4c\x5a\x0e\x90\x28\x85\xc8\xce\x51\x21\x2e\xe6\x7f\x0f\xe0\xb6\xaf\xbc\x8b\xad\x45\x37\x27\x54\x3b\x3c\x68\xb8\x90\xdd\xab\xa2\x69\xd2\x5f\xc1\x64\x3f\x54\x83\x51\x36\xa1\xa2\x5b\xa1\x8d\x91\x6c\xed\xd6\xa4\x7f\xc0\x7a\xdf\x6f\xc6\x9f\xa5\x08\x94\x9d\xc1\x0d\x9d\xc5\xe0\x26\x1b\x52\xf3\x65\x71\x70\x38\x4e\xcc\xd9\xc8\x05\x41\x35\x4b\x1c\xe0\xf6\xfb\x5e\xd3\xe8\xd5\x4a\xf0\xb5\xbf\x0a\x92\x83\x51\x25\xc7\xd9\xbc\x4f\x09\x2f\xf3\x80\xe5\xe8\x96\xfb\xf3\x02\x55\x2b\x14\xd5\xb6\x1a\x22\x4d\x86\xe3\x01\xc7\xa6\x6a\x66\xe4\xe4\x32\x9a\xac\x0a\x66\xb1\x56\x77\x23\x74\xdc\x1c\x71\x68\xd5\xb5\x61\x65\x2f\x8f\x43\x87\xe4\xf2\x89\xb6\x36\x6a"}, +{{0xef,0x09,0x48,0xe1,0x32,0x81,0xf3,0xcf,0x35,0x2c,0xbf,0xaf,0x8d,0x89,0xd1,0x17,0x76,0x85,0x52,0xd5,0xa1,0x54,0x8e,0xcb,0xaf,0x37,0x41,0x2e,0x97,0x67,0x0f,0xac,},{0x58,0xc2,0x45,0x7f,0x5a,0x5e,0x3c,0xfb,0xf4,0x71,0x19,0xa8,0x7f,0x2a,0xff,0x19,0x18,0xf1,0xe6,0x7a,0xe6,0xfa,0x91,0x71,0xd3,0xf4,0x1e,0xee,0x07,0xa8,0x68,0x72,},{0xcc,0x12,0xf6,0x9d,0xb6,0x3a,0x67,0x8e,0xc4,0x77,0xa6,0x05,0xa5,0x05,0xc5,0x7d,0xc2,0xb8,0x10,0xef,0x85,0xe3,0xe3,0x45,0x19,0xcb,0x25,0xc5,0x10,0x63,0xaa,0x66,0x35,0x5d,0x3f,0x1e,0x29,0x74,0x69,0x58,0x66,0xed,0xf6,0xf1,0x71,0x71,0xce,0x37,0x84,0x2f,0xba,0xb5,0x07,0x5f,0xc8,0x95,0xd1,0x8e,0xd7,0x43,0xc5,0x46,0x08,0x0c,},"\x7e\xc4\x7f\x2f\x1f\xe3\xb7\x0a\x6d\x1d\x82\xc7\xcd\x92\x4b\x4b\xf9\xb2\x02\x9f\xc1\x2c\x52\xa6\xe1\xcc\x06\xcf\x5a\xbf\xc0\xa4\x42\xe7\xcf\x14\x5c\x15\x42\xb9\xb1\x35\x04\x96\x65\x71\x10\x35\xe3\xc2\x9a\x91\xd4\xfd\xae\xd6\x12\x70\x57\xa8\x12\xc2\x2c\xd7\x5a\xd1\x87\x9b\xe1\xd2\xc6\x11\x0e\x79\xe9\x87\x52\x4e\x4e\x8f\x27\xf1\x6e\xda\x90\xcb\xd4\x73\x3f\x11\x18\x25\xb5\x16\xd1\x06\x7f\x81\xec\xa5\xe6\x94\x85\x76\xd5\xbf\xed\xb3\x27\x7c\x1a\xbc\x1e\x60\xf3\x74\xd0\x70\x1b\x32\xcc\xfd\x6a\x5e\x9c\x8d\x16\x59\xaa\xf3\xd0\x81\x86\x13\x61\x3b\x7e\x28\x8d\x84\x5e\x9a\xaa\xba\x2e\x3e\x9b\x41\x1d\x50\x1d\xff\xe8\x56\xfd\x31\x3e\x9f\xcc\x9e\x74\x30\xb9\x98\x3f\x20\xab\x4e\xbf\x4e\xb6\x16\xbd\x63\xe2\xc5\x77\x43\x65\x89\x95\xed\x0a\x14\x9a\xe6\x20\xa3\x95\x61\x37\x19\xb3\xed\x7c\xed\x45\x88\xd5\x91\x5d\x70\xa2\xf0\xc6\x87\x68\x0e\xc3\x4f\xe3\xe9\xf7\x23\x92\xe1\x89\xe1\x3a\x47\x49\xd5\xca\x9f\xac\x65\x1b\x92\xc0\x84\xc4\x06\x6f\xdf\x98\xa8\x69\x22\x3e\x4e\x0c\x9b\xec\x58\x12\xb5\xc1\x90\x0e\x6e\x60\xd3\xa1\x88\xd4\x8a\x74\xdf\xd4\x15\xb5\xca\xd2\xe9\x1f\xf7\x6d\xf7\x50\x89\xd2\x0a\x75\x5f\x26\x07\x56\xc8\xf1\x38\x2a\x29\xf7\xb9\x37\x26\xe7\x31\x07\x1c\xd4\x77\x45\x8c\x6f\x20\x22\xdf\xad\x7d\x4f\xc7\xab\x23\x80\x54\x18\x64\xf6\xb5\x87\x74\xf9\xae\x8e\x5f\x07\x7c\x1a\x8d\xa0\x73\xc3\x98\x53\xeb\x2f\xd4\x77\x22\x0b\x45\xa3\xd9\x22\x63\xdc\x7e\x14\xd3\xbb\x2b\x36\xfc\xa4\x66\xc7\xef\x8a\x24\x75\x38\x72\x5f\x2f\xce\x5c\x72\x21\xbc\x75\x1c\xde\x13\x94\x60\x4f\x59\x31\xd7\x33\x36\x0c\xcd\x47\xce\x08\x77\x12\x95\x81\x80\xad\x84\xfa\xe7\x13\xb5\x43\xf0\x5e\xef\x6a\xbc\x06\x61\x43\x31\x21\xed\x3b\x45\x06\xa1\x46\x50\x25\x31\x6f\xb8\xf9\xd6\x45\x35\xcc\x45\x38\xac\xd4\x06\x4d\xd5\x76\xb0\x74\x0e\x1b\xeb\x13\xbc\xea\xf1\x55\x54\x3d\xc8\x90\x97\xca\x5c\xa1\xcf\xfa\x0a\xd6\x5a\x10\xbc\xb7\x59\x35\x4e\xab\x8a\x42\xde\x73\x4a\xf9\x09\xc2\xfe\xba\x38\x0d\x66\x40\x9f\x32\x5d\x5f\x17\xaf\x9c\xa7\xf8\xcb\x41\x34\xfd\x6a\x2b\x6a\x52\x8d\x9e\x60\xd9\x61\x2b\x8e\x8b\x40\x62\xf8\xe0\xfa\xd1\xe7\xee\xb9\xcb\xfe\xf6\xe9\x73\x8e\xc7\x97\x3e\x1c\xb2\xba\x23\x27\xde\xca\x4e\xa4\x65\x68\xf3\x1e\x12\xf7\x30\xe2\x47\xc1\xd0\x70\x29\xfd\x44\x22\xb2\x98\xff\x23\x98\x02\x3b\x41\x20\xa3\xa4\x25\xff\xb6\x52\x88\x0c\x19\xea\x69\xf3\x63\x9e\x0f\x6d\xf4\xf0\x08\x76\xcc\x45\x28\xe2\x67\xe8\x1d\x59\x43\x19\x9d\x0f\xeb\x6c\xb4\xe1\xba\xf4\x04\xbb\x6f\x8b\x39\xb1\x2d\xbc\xe9\xfd\xc3\x5d\xc1\x58\x06\x6e\x99\x75\xae\x5b\xd3\xb5\x5f\x2a\x41\xa7\x91\xba\xf3\xe8\x35\x1e\xc6\x04\x94\x47\x90\xa2\x2c\x93\x3c\x80\xb1\x59\x0b\xa1\x97\xa4\x70\x6f\x7f\x51\x28\x68\x2e\xdc\xd7\x4d\xd7\x8d\x43\x5e\x78\x7c\x2b\x76\xa5\x7b\x3f\x4e\x7d\x7b\xe2\xef\xd2\x6d\xa5\xf9\xa8\x29\x11\x9b\x01\x50\x8b\x70\x72\xc7\x69\x9c\xe5\x2b\xb5\x78\xcc\x5b\x1b\x93\x66\x1b\x51\x72\xfb\x84\xda\xf1\xba\x36\x4d\x2c\xbd\x80\xe2\xc9\x9b\xca\x9c\xae\xa8\x73\xcc\x0a\x16\x29\xea\xc3\x84\xe9\xb2\x06\x84\x2a\x6e\x61\x83\x38\x75\x91\xb4\xaa\x34\xa9\x5f\xd8\x9b\x49\xd8\xd1\x5d\x91\xe2\x19\x40\xe1\x7d\xca\xf1\xef\xf8\xa0\xa4\x7a\x0d\x7a\x95\xda\xea\xd8\x2a\xa3\xdf\x82\x04\xa0\xcd\x20\x69\x24\xae\x51\x0f\xec\x8a\x9c\x4e\x8d\x85\xd4\x66\xfd\xb4\xdd\x36\x5d\xc9\x93\x36\xb2\x2c\xe0\xb9\x56\xb5\xee\x00\x17\xf2\x9d\x25\xee\x66\xfb\xdc\xec\xb0\xd9\x96\xff\xb9\x7c\x8d\xef\xde\x40\xa9\xff\x99\x93\x19\x3c\xa8\xf1\x68\x50\x67\xc1\x9c\x52\x6e\x0e\xfe\xd2\x36\xf8\xed\xb8\xde\xf6\xc2\xa0\x3e\x21\x95\x2c\x86\x12\xd6\x24\xe6\x88\x6a\x31\x1f\xfb\x9e\x2f\x15\xda\x44\xab\xe1\x80\xd2\x6a\x14\xb1\x5f\x63\x56\x1e\x09\x7a\x73\x0e\xca\xbb\x79\x2c\x7c\x23\x5f\xdd\x36\x0f\x57\x1f\x27\xef\x68\x67\x7a\x7d\x63\xbe\xb4\x97\x59\x82\xcb\x19\x9a\x56\x0f\x81\x6e\xe1\x29\x89\x44\x5f\x7f\x75\xb8\x3e\xb2\x78\xd6\x28\x25\x94\x7d\x84\x09\x9a\xf2\xa6\xff\x2e\xad\xbb\xf5\x89\xb5\xeb\x2f\x72\xed\x11\x4c\x73\x15\x11\x53\xae\x00\x22\xbc\x95\x64\xd1\x5c\x2d\x5c\xdb\xba\xab\xbe\xf6\x38\xf0\x30\x95\xf5\x3e\xeb\xac\x96\x83\x40\x9a\xd3\x06\x0c\xfb\x7c\x70\x37\xb9\xb0\xbe\xfe\x06\x9c\x92\xa0\x2b\xe9\x53\x38\x8e\x9e\xa4\x5d\x36\xdd\xf4\xf5\xa8\x38\x94\x32\xcc\xf5\x04\xc5\x08\x08\xb0\x7f\x69"}, +{{0x90,0x3f,0x3b,0x53,0x99,0x89,0x2e,0x29,0xcc,0xfa,0xfb,0xaf,0xbd,0x7c,0xc4,0x53,0x3c,0x15,0x4a,0x62,0x56,0x82,0x40,0x6c,0x89,0xbf,0x89,0x4c,0x88,0x9e,0x43,0xf4,},{0x8f,0xa5,0xff,0x5b,0x6b,0x26,0xbd,0x67,0xdf,0x86,0x40,0x46,0x42,0x9d,0xf1,0x24,0xb5,0x23,0x00,0x5d,0xd8,0x94,0x44,0x27,0x5c,0x8a,0xb7,0xeb,0xdd,0xb6,0xf4,0xdb,},{0x49,0x5a,0x8f,0x99,0x19,0x41,0xc6,0x29,0xbd,0x64,0x1a,0x67,0x47,0x1a,0xb8,0x60,0xbf,0xd3,0x9b,0x72,0xf2,0x33,0x55,0xf7,0x27,0x09,0x09,0xd5,0x30,0x7c,0x77,0xb1,0xb9,0x4b,0xae,0x3e,0xd1,0x94,0x50,0x78,0x0e,0x90,0x85,0x30,0x5f,0x31,0xb1,0xe1,0x68,0x3f,0xac,0xf0,0xd1,0xfc,0x88,0x40,0xae,0xc7,0x7d,0xf6,0x7a,0xea,0xb3,0x02,},"\xa2\xc1\x1b\x5f\xb8\x84\xa8\x22\xfa\xe6\x4d\xa8\xdc\xb4\x45\x2c\xfd\x7a\x04\xca\x6d\x7a\x5a\xbc\x8d\x82\x71\xe9\x3f\x93\x44\x9e\x1f\xeb\x8e\x02\x97\x5f\x49\x6b\x90\x34\x40\x0d\x35\x99\xab\x97\xaa\x39\x97\xda\xd1\xc9\xff\xab\x5b\x9f\x8d\xf4\xaa\xa5\xb8\x40\xd9\x0d\x86\x2f\xff\x7f\xf0\xcf\x73\xa6\x0c\x66\x15\x00\x09\xe0\x1c\x93\x7b\xd1\xaf\x68\x07\xb5\xba\x2e\xf6\x12\xee\x13\xd6\xde\xf4\x0b\xb0\x9c\x46\x81\x1a\x2d\x4e\x46\x8e\x03\x8b\x32\x30\x55\xf9\xdf\xbd\x01\x82\x9a\xe2\xf1\xa5\x35\xef\x02\x95\xca\x1e\xd1\x76\xe4\x6d\xe9\x96\xcc\x87\xba\xce\x45\x35\x62\x33\x21\x18\x35\xb6\xf4\x75\x7c\x99\xbd\x52\x7e\x76\x6a\x5f\x0b\x12\x7c\x8c\xff\x8e\x6d\x66\xf8\xba\xb8\x6d\x00\x00\x45\x2c\xd7\xf6\x7b\xe5\x57\x78\x85\x13\xec\x07\x09\xb5\x37\xb0\x07\xb4\x20\x16\xe7\xa8\x96\x83\x46\x9b\xd8\xff\x8d\x21\xeb\x10\xc1\x49\x17\xd4\x7f\x2d\xc4\xf8\x26\x32\x4f\x7c\x01\xb2\x4f\x8d\xcf\xf0\x4a\xa6\xd8\x50\x95\xd9\xab\x15\x4b\xa5\xc3\xbd\x91\x9c\x9d\x72\x8d\xbd\xc9\x90\xd1\x9c\xeb\x23\x7b\x45\x29\x07\xbd\xbe\x21\xf9\xf0\x8c\xdd\xae\x5b\xe4\x79\x27\x67\x09\xb8\xae\x73\xf8\x97\x4c\x4b\x11\x38\x41\xad\x53\x5d\x6f\xf6\x22\x3e\xea\x47\xd1\x85\xc8\xe8\xa6\x5f\xde\xe2\xc2\xd4\x58\x00\xc1\x7c\xb5\x56\xea\xfd\x67\x66\x47\xd9\x96\x8e\x55\xca\x9c\x59\x23\x2b\x97\x70\xad\x10\xf9\x55\xfc\xb5\x85\x8e\xdf\x0b\x74\x83\xad\xc1\x81\x7c\x0f\x8d\x02\x24\x04\x82\xca\xa7\x6f\x43\xc6\xd2\xe9\x6a\x4f\xf9\x59\x1c\xd7\xb8\x78\xea\x61\x9e\xa5\x6d\x1b\x58\x86\x31\xe7\x63\x3c\x5e\xcb\x2b\xa6\x99\x83\x98\xcb\x06\xe3\xcf\x75\xae\xb3\xe0\x8d\xab\x19\x63\x2d\x45\x4f\xf7\xdc\x0e\x2a\x41\xf0\x97\x37\xe8\xee\x82\x3d\x1b\x9e\x24\xdd\xa8\x4a\x2c\xe0\x31\x3c\xb9\xfc\xe3\x1c\xb6\x63\xc5\x5c\x05\x64\x5e\x63\x40\x17\x56\xe8\xad\x38\xf5\x17\x4c\x02\xa6\x63\xd8\x15\xad\x64\x42\x2f\xf7\x72\x7d\x4f\xda\x16\xe4\x8d\x4b\xf8\xf6\x60\x2e\x72\x60\xda\x62\x33\x0e\x68\x78\xc3\x47\x64\xe1\x29\xaf\xbd\x55\x22\x08\xf6\xbe\xd4\xf7\xce\xe9\xb6\x71\xf4\x88\x38\x88\x15\xd7\x4b\x49\x51\xb8\x68\x2c\xe7\x6c\xfe\x31\xe9\x38\xc4\x70\xb8\xf7\xa4\x5f\xd6\x3a\x96\x91\xf4\x26\xa7\x5c\x58\xed\x3d\xbc\xe3\xae\x8f\xd9\xd1\x0a\x83\x52\xe4\x7c\xc1\xb1\x2c\x91\x92\xac\x86\x26\xd1\xb3\x84\xb7\x7a\x18\xb9\x86\xe7\x1a\x99\x86\x46\xc1\x37\x99\x2b\x67\xc4\x81\x7e\x34\x63\x45\xfa\xf5\x0a\x26\x59\xfd\xc5\xca\xd5\xc7\x19\x64\x8e\xfe\xe3\x84\x7c\x0f\xf6\xbd\x70\x95\xc2\x8b\x4c\x51\x95\x96\x7c\x90\xcf\x84\xe1\xef\x68\xa1\xad\xa0\x1f\x62\x74\xed\xe3\x63\xfb\x82\xe0\xb5\x49\xa8\x70\x24\x5d\x60\x8c\xae\x82\x34\xf6\xd8\x4a\xbe\xb6\x1b\x71\x84\x66\x09\x36\x20\xd8\x5c\x58\x4a\xb0\x1e\xed\xa0\x91\xee\x8a\xff\x1c\xf6\x7a\x46\x75\x67\x9a\x1f\x40\x03\xe6\x6a\xaf\x43\x87\x1b\x88\xec\xda\x6a\x16\xdc\x5a\xcb\x05\x39\x5f\x2d\xa9\xdf\x70\xd3\xbd\xb6\x14\x38\xe1\xc3\xd4\x09\x81\xe0\x34\x62\x7d\x02\x6e\xe1\xd2\xe7\x9f\x65\xcb\xb8\x18\x9f\xcb\xb3\xcc\x8b\x5c\x2e\x7e\x79\x6b\x5d\x28\x89\x41\x1d\x56\x41\xfb\x86\x9c\x7b\x0a\x58\x9c\x43\x25\x4f\x8c\x54\x38\xaa\xf5\xac\x42\x38\x32\xf0\x18\xd7\x9a\x51\xb9\x6f\x24\x2e\x2d\xe0\xc8\x51\xcc\x5f\xc2\xb2\x06\xbc\xa4\xb5\xbe\x83\x61\x25\xac\xa1\x44\xbb\xc3\x8c\x8c\x63\x8b\xe0\xd3\xbb\xe0\x25\xa1\xbe\x8b\x3d\x03\xd5\x92\x9b\xaa\x64\x9c\x35\x44\xa3\x2a\x91\x5e\x92\x6a\x38\x79\x1b\x13\x4a\x97\x1b\xc5\x2d\x1b\x6c\xa6\x25\xef\xb7\xc2\xf3\xbb\x47\xab\x51\xd4\x3c\x8e\x37\x4d\x16\xcd\xa8\x82\x20\x4b\x71\xca\xfe\x90\x93\xcb\x60\x78\xef\x2b\xdf\xad\x59\xed\xea\xf3\x6d\x0c\x1a\x4d\xc4\x25\xb9\xe7\x18\xc4\x51\x85\x22\x5a\x9c\x30\x84\xb7\x82\xbf\xe1\x63\x49\x2f\x8e\x84\x82\xec\x9a\xa0\x73\xf6\x90\x1f\xf3\xd1\x11\x7c\xe9\x17\xe1\x91\x22\xfa\x67\x65\x0d\x85\x8f\x8f\x82\xb3\x76\x69\x72\x3c\x22\x6d\x72\x16\x97\xe7\xae\x33\x59\xf5\xa6\xb0\x24\x24\xee\x87\x94\xcb\xea\xa6\x41\xed\xbb\xf7\x53\xb1\x03\xa5\xfe\x15\x8b\xe0\xba\x60\xd8\xa2\x12\xd4\x2f\x8c\x5c\x2a\xf2\x54\xbf\x1b\x9c\x80\xdf\x6f\x1c\xf0\x9d\x70\x79\x3c\xae\x1a\xbb\x46\x27\xb1\x78\x0f\x1b\xce\x7f\x61\x7e\xe5\x0f\x6b\xd4\xb0\x83\xb2\xfc\x7c\xd8\x44\xaf\xb7\x23\x80\xd5\xcb\x6b\x25\x5b\xf4\x7e\xa7\x1c\xad\x6c\x6c\x4d\xf0\x21\xf8\x1b\x54\x8f\x43\x2c\x18\xac\x36\x6c\x6a\xec\xd0\x3b\x6c\x8c\xe2"}, +{{0xee,0x81,0xe0,0xfb,0x05,0x2e,0x23,0xad,0x75,0x9d,0xe6,0xaa,0x98,0x38,0xde,0x98,0xe3,0x6d,0x48,0x20,0xdc,0x0e,0x1b,0x7b,0x3e,0xf1,0x14,0x1a,0xb9,0xde,0x33,0x40,},{0x98,0xf3,0xc9,0x88,0x07,0x94,0xde,0x64,0xfa,0x26,0x9b,0xdf,0x33,0x60,0x95,0xe0,0xe0,0x1b,0x1a,0x3b,0x37,0x5f,0x96,0x5b,0x93,0x70,0x0b,0xbd,0xf4,0xb9,0x68,0x69,},{0xf0,0xd8,0x73,0xbe,0x15,0xcf,0x45,0x4c,0x74,0x34,0xde,0xab,0x71,0xde,0x25,0xcf,0xe9,0x9e,0x81,0xa4,0x8d,0x2d,0xce,0x6a,0x35,0xd1,0x63,0x37,0x14,0xdf,0x0f,0x8b,0x40,0x29,0xe0,0x58,0x25,0x11,0xef,0xc4,0xd0,0x68,0x92,0xf6,0x72,0x85,0x02,0x46,0xbc,0xf0,0x70,0xc4,0x6f,0xad,0xc2,0xfa,0xab,0x44,0xdc,0x43,0x50,0x45,0xde,0x00,},"\x28\xd9\x9e\x95\x18\xb8\x82\x83\xc2\x20\xe7\x6d\xe2\x05\xd7\xb6\x16\x23\x59\xb1\xdf\xec\x1f\xba\xab\x98\xec\x0e\xf1\xdf\x8d\xa4\x0b\x6b\x7a\x77\x5e\x97\x28\x45\x0a\xeb\x23\x51\xfe\x5c\x16\xaf\xda\x3a\xec\x0d\x71\x04\x9d\xa4\xcb\x7d\x4c\x63\x71\x3a\x24\x10\xab\xb0\x22\xf8\x16\x11\xcc\x06\x45\x87\xc8\x04\x7d\x43\x83\xc0\x0c\x3c\x56\x2e\x9c\xee\xa3\x57\x75\x09\x53\x91\xb5\xf3\xdd\xa0\xe3\x73\xc4\xa7\x7f\xf6\x18\xa2\x8e\xf6\x87\x87\xeb\xfc\x3e\xbc\xcc\xc5\xd1\xce\x32\xdd\xf4\x3b\xfc\xe5\x72\x03\xda\x76\xa8\x66\x4b\x3c\x61\x6a\x88\x69\x28\x2d\xb0\xb7\x28\x11\xb5\xfd\x5a\x2a\x03\xa4\xff\x66\x72\x4b\x04\x89\xea\x2e\x10\x73\xd7\x81\xc3\xf1\x89\x11\x5d\x79\xba\x20\xa4\x6d\x1d\xfa\xf5\xb1\xa5\x84\x7b\x2a\x2e\x31\xb2\x80\x87\x37\x56\x9e\x60\xb5\x72\x31\xe6\xa9\x9a\xf2\x6f\x58\xaf\xeb\x15\x77\x08\x10\x47\x48\x12\xfe\x4a\xfa\xcf\x88\x45\x06\xb8\xc3\x14\xbc\x67\x51\xbb\x42\xb4\xbd\x6e\x87\xd2\xe5\xde\x70\xfe\xc5\xf0\x01\x4c\x42\x57\xb1\x34\x72\xa3\xb0\x11\x1a\x7a\x8c\xf8\x3b\x1d\xc0\xcf\x96\x20\x22\xcd\x44\x46\x8a\x3a\xb1\xf0\x01\x6b\x70\xca\xfb\x1d\x02\x46\xac\xd7\x05\x39\x37\xc9\xac\x40\x20\x7c\xf1\x3b\x50\xdd\x15\xe2\xa2\xe1\x5f\x50\xa0\x5b\xca\x2f\x28\xe7\x70\x26\x23\x71\xda\xce\xe0\x2e\x25\xb2\xa5\x96\x58\xed\x90\xc0\x60\x0f\xa2\x65\xb7\xde\x3d\x44\xf8\xef\x07\x21\xbf\x39\xec\x4d\x4e\xca\x58\x88\x52\x7b\x77\x80\x67\xb1\xd6\x59\xc0\x05\x14\xc8\xd7\x05\x62\x73\xa2\x94\xcb\xaf\xe4\x50\x90\xd0\x69\xbb\xd0\x9f\x92\xf4\x61\xe6\x48\xf3\xe6\x82\x88\x2c\x71\x57\x6e\x97\x4d\xeb\xb0\xcb\x7e\x0e\x83\x16\x40\x66\x60\x15\x0d\xab\xb5\x8e\x76\x24\x66\x14\xa2\x91\xc1\x2c\xe9\xe0\x34\x6c\x02\x77\x4d\x4d\x09\xce\xcc\x23\x69\x67\x12\xfe\xe2\x50\xc0\xbb\x5d\xf7\xa2\xa4\xc4\x3a\x55\x63\x33\x1b\xcb\xbf\x84\xbe\x3f\x2e\xeb\x06\x54\x53\x2e\x85\xec\x59\x7b\x53\xb3\x2f\x39\x54\xcc\xaf\x0c\xd4\x26\xde\xf9\x1e\xc4\xb2\x08\x41\x69\x48\xaf\x27\xde\x04\xd8\x32\x70\x58\x97\xa0\x4c\x5e\x24\xa2\xe8\x8b\x20\x04\x0f\xd4\xec\xa3\x08\x9f\xdb\x91\x8a\x92\xe3\x5c\x4d\x31\xda\x26\x85\x0b\x9d\xd3\x41\x18\xc7\x44\x49\xa8\x55\xff\x4b\xc9\xff\xf0\xd1\x44\x78\x39\x65\x4b\x00\x41\x79\x99\xfa\x4e\xb8\x91\x02\x13\x3c\xd3\x20\x40\x91\x53\x58\x49\x57\xc1\x04\x89\xdb\x4b\x72\x44\xc9\x59\x07\x98\x8e\x83\xdc\x82\x12\x71\xdc\x1a\xb6\x43\xd6\x99\x2d\x0f\xd8\x20\x49\x2a\xe6\x42\xe2\x4d\x19\xa1\x79\xfa\x75\xd9\x36\x3b\x32\x16\x62\x60\x6f\xd9\x4a\x47\xfd\xb2\xe6\x8d\x3f\x30\xc0\x46\x73\xf8\x09\xde\x01\x44\x94\x5e\xa4\xd4\x18\x3d\x48\xf1\x75\x07\x9e\xed\x50\x32\x3c\x6b\x19\x2e\x02\x0e\x16\x2a\x35\x03\xaa\x58\x2f\xb0\x8b\x40\x36\x24\xa2\x3e\x35\x7e\xed\xa0\x8d\x90\x43\x86\xf3\x58\xc3\x6c\x64\xd3\x14\xc7\x7c\xd9\xd4\xd2\x3d\x58\x1e\xe5\x3d\x81\xff\x97\xad\xa0\x19\xcf\xcf\x04\xeb\x9d\xcc\x1d\xe9\xb7\x4c\x3d\xb6\xb8\x11\x57\x8b\xd4\xf2\x19\xc5\xca\x48\xef\x4c\x82\x6b\x09\xe6\xc9\x6d\x03\x1f\x65\xdd\x48\xb6\xe7\x3d\x0c\x10\x05\x86\xb2\x1d\xf0\x29\x3a\x03\xd2\xed\x7e\x50\x09\xad\x02\x53\x40\xc2\x1d\x09\x06\x06\x91\xf5\xcd\x8a\xf2\xab\x12\xf9\xb8\x60\xee\x87\x81\x5e\x1a\x9f\x40\x0c\x2a\x6f\x63\x4e\xa8\xf9\xb3\x42\x5a\x08\xd1\x0b\x3c\x81\x53\x67\x38\x8f\x4d\x1b\xe3\x56\x31\x8e\xcf\x90\x35\xd0\xee\x97\x5a\xff\xa8\x59\xca\xac\x28\xeb\xcc\xd0\x59\x9b\xb2\xf6\xf3\x52\x36\x61\xbd\x17\x8f\xc9\xe4\xca\xc3\x78\xbb\x9d\xd4\x71\x6b\xb0\x69\x23\xfd\x2b\xbd\x56\xc9\x59\xc4\x2b\x95\xd5\x01\x93\xf8\xbf\x29\x9f\xcc\xa3\xb2\xee\xa9\x4e\xc5\xf9\x85\x83\x92\x4c\x08\x04\x16\xe2\x8b\x54\xfe\x57\x65\x84\x58\xb0\x55\xce\x4d\xe8\xa7\x5f\xc8\x27\x15\xca\xe9\x1d\x37\x5c\xf6\x92\x81\x37\x80\x51\xbb\x61\xfd\xd7\xbb\x00\x68\xf6\x3e\xfa\x6d\x6e\x83\xd8\xfd\x42\x57\xaf\x80\x97\x0f\x4a\x9e\x69\x24\xb2\xde\x0a\xd9\x66\xdf\xfe\x6f\xa4\xa1\x13\xb0\xe7\x72\xf1\x76\x87\x85\xb3\xb4\x20\x49\xf7\x6c\x48\xad\x80\xf2\xc6\x7f\xb0\xf9\x1a\x5f\xc4\x10\x79\x12\x52\x0d\x8d\x68\x3c\x06\x2c\x3a\x22\x2b\xcd\xa7\xe7\x10\xba\xcd\x47\x8e\xe8\x83\x67\xb6\xa0\x59\xa4\x52\xfd\x26\xf1\x14\xa5\xac\xbd\x69\x79\xba\x01\x9f\x7d\xa6\x8a\xc0\x4a\x19\x30\x26\xbc\x1c\x27\xe4\x83\x7b\x1d\xe2\x9c\xce\x09\x0e\x33\x80\xd5\x05\x1a\x58\x64\x09\xe6\x28\xe3\x14\x56\x65\xbb\x1d\x84\xec\xd8"}, +{{0x69,0xd0,0x1d,0x82,0x91,0x13,0x08,0x1c,0xbf,0x5d,0x0c,0x6e,0xf7,0x7b,0x21,0x77,0x5c,0x8d,0x9b,0x68,0x00,0x00,0x05,0x6f,0x03,0xc7,0x5a,0x7d,0x0a,0x05,0x87,0xd2,},{0xee,0x84,0x69,0xdd,0x61,0xcf,0x5d,0xe4,0x00,0xda,0x7d,0x7a,0x47,0x9a,0x44,0x18,0xe6,0x77,0x2e,0x69,0xff,0x53,0x30,0xce,0x5c,0xa7,0x78,0x59,0xfe,0x27,0x17,0x55,},{0x40,0x8c,0xef,0xcf,0x01,0x41,0x7e,0x2d,0xc6,0xa8,0xa1,0x82,0x84,0xe4,0x11,0x65,0x7f,0x03,0x92,0x50,0xc3,0x12,0x78,0xdb,0x28,0x19,0xf9,0xea,0xea,0x42,0x93,0xfb,0xf6,0x83,0x1a,0x28,0x01,0xfc,0x1e,0xa6,0x87,0x16,0x57,0xb8,0x41,0xe1,0x73,0xf4,0x51,0xb0,0xd5,0x75,0xa9,0x37,0x9e,0x35,0x85,0x7e,0x8c,0x72,0x97,0xfa,0x14,0x04,},"\x0b\x9e\x11\x0f\x29\xd1\x98\x16\xa1\x7b\x2c\x75\x47\x8f\x13\xce\xe9\x53\x81\x1a\x19\x83\x01\x4c\xb7\xeb\x0f\x75\x52\x69\x12\x04\x4c\x3e\xa6\x82\x97\x80\xe6\x57\xf8\x17\xc5\x59\x7d\x46\x61\x08\x0d\x90\x34\xc9\x77\x87\x22\x41\x8f\x2c\x3a\xee\xca\xef\x6b\x69\x0c\x5b\xd3\xb5\x93\x70\x10\x86\x98\x8e\x43\x40\xae\xc3\x4e\x01\x72\x75\x8e\xb2\x40\x87\xd0\x3a\x8f\x76\xe7\xcb\xca\x53\xaa\xaf\xc4\xd2\x15\x5c\x75\x32\xab\x54\xbe\x48\x87\x26\x53\x06\x6f\xa1\xfd\xd5\x4a\xcf\xe9\xda\xae\xca\x35\x6c\x29\x0e\x6b\xe6\x33\x55\xb6\xd9\xfc\x52\xeb\x5e\x4f\xcc\xbb\xc6\x08\x35\x07\x13\x2d\xe4\x85\xbf\xae\x9f\x42\xe1\x97\x12\x23\x2b\x71\x64\x02\xc2\x3f\xea\x74\xef\xa6\x9d\x73\xc8\xc2\xe3\xa8\x66\x2b\x8b\x65\xb0\xfd\x00\x77\x41\x01\x3e\x1f\x6e\x3c\xfe\x43\x45\xd5\xc8\x30\x68\x2f\xe6\x00\x21\xd7\x08\xe1\x0a\x9e\x9f\x40\x52\xff\x7a\x6a\xbf\x28\xac\xb1\xd6\xb5\xfb\x03\x8e\xed\x3f\x72\x51\x3c\x35\x5b\xbf\xd5\xc2\x27\x4f\xa8\x5f\xc4\xf4\x46\x97\x4b\x2d\x1b\xc0\x36\x50\x7a\x1e\xb5\xfc\xf5\x5d\xbd\x44\x21\x0e\x53\x82\x74\xde\x80\x8b\x90\x0b\xf1\xc0\xfc\xc0\x24\x12\x70\xdb\x8d\xbd\xcd\x88\x34\x9d\x67\x22\x4f\x08\x7e\x5f\x07\xf6\x99\xb0\xba\xe6\x8b\x2e\xbc\x9a\x4e\x27\xc7\x0d\x3a\xc7\xd9\x96\xfa\x7d\x4d\xab\xd5\x68\x37\x8e\x3f\x93\x90\x5b\x1c\x89\xc6\x52\xd3\x84\xc1\x6c\x2b\xcb\x1c\x98\x44\xc3\x8f\x71\xbb\x13\xe0\xc6\xa2\xea\x95\xb6\x12\xe3\x90\xc5\xf8\x6d\x24\x8e\xa5\x31\xf2\xec\x6f\x63\x9a\x40\x2d\xfa\xcc\xf3\x72\x17\x00\x53\x44\x03\x07\x45\xd1\xf1\xe5\x20\xcc\x19\x5d\xaf\xdd\x7f\x29\x5f\x37\x7b\x8d\x61\x47\x16\x70\x38\x36\x21\x9b\xb7\xb0\x9f\xea\x7a\xae\x9a\xc3\x3e\x42\xdc\xab\x65\xcc\x61\x42\xfc\xd8\xce\x15\xe9\x77\x17\xfd\xb3\x3e\x95\x38\xc4\x4f\x6c\xd9\xc1\xc6\x5d\xb6\x27\x51\xf5\x52\xf8\x70\xf1\x01\x42\xc9\x6f\x9d\xf1\x85\x5a\xbb\x39\xe4\x27\x06\xa5\x63\xab\x15\x45\x11\xfd\xce\x68\x7c\x95\x76\xf9\xed\xc3\xb4\xba\x55\x34\x6c\xe6\x68\x02\xff\xfe\xf4\xb1\xb5\xe1\x20\x15\xce\x8b\x57\xde\x54\x58\xca\xa0\xda\xf3\x41\x96\x81\x28\x58\x42\x88\xc2\xf2\x7c\xbf\xb7\x6e\xab\x28\x6b\xac\x5f\x66\xaa\xd0\x04\x9e\x0c\xa6\x0a\x90\x14\xe1\x79\x01\xc4\x13\x0e\x83\xce\xae\xb4\xc2\x71\x3e\x97\x1a\x23\x5e\xff\x99\x5a\x81\x3a\xe4\xea\x64\xa5\x83\xff\xde\xfd\xac\x82\xac\x76\xea\xf4\xd4\x7c\x4a\xc8\x25\x0f\xcb\xaf\xd6\xb8\x8f\xae\xb4\x80\x15\xf5\xb4\x2b\x53\x34\xa5\x0b\x31\xd4\x50\x2e\xa4\x91\xda\x90\xdc\xe9\x3c\x08\xfd\x56\xf5\xc5\x8e\xed\xb3\x79\x16\x6a\x23\x76\x2b\xe5\xe4\xad\xea\xa6\xf4\xae\x1c\x24\xe0\xca\xc4\xdd\xca\x03\x83\x45\x85\x60\xcd\xc4\x8b\x8c\xd1\xf4\x2a\x3b\xa2\xf6\xff\xb6\x07\x79\x09\xfc\xb2\x94\xad\x1e\xf4\xa4\x4c\x22\xec\x4b\x39\x87\xdd\xbe\xef\x32\x5b\x98\xce\xd5\x68\x15\xea\x7d\x5f\xcc\xf5\xaf\xdf\xe9\x8e\x0e\x6d\x92\x0f\x7a\xda\x2e\xb5\xc9\x16\x24\xc7\x6c\xbb\xa2\x99\x3a\x9c\x7a\x55\x02\x1d\x12\x7a\x66\x7b\x39\xe2\x35\xdf\x4f\x81\xde\xe7\xdd\x14\x28\x98\x77\x8d\xbd\x92\x13\x5b\x70\xb3\xac\xf5\x9f\x6c\x29\xa2\xc9\xd4\xa7\x00\x6e\xf1\x1a\x91\x8b\x3a\x29\x06\x26\x4a\x15\xd6\xb5\x29\x30\x8c\xbc\x89\xf8\x56\x01\xfc\x1e\xa1\x31\x4d\x67\xf7\x56\x6c\xf1\x09\x16\x5c\x7f\x92\xde\x1a\x18\xd7\x0d\xeb\xe0\x24\x34\x9d\xb3\x56\x0a\x6e\x52\x7e\x2a\xc3\xe0\x67\x89\x46\x87\x04\xe6\xb8\xf1\x87\x1f\x16\xba\xe9\x82\x73\x92\xb4\x18\xf1\x08\x6c\xc4\x97\x08\x6c\xed\x14\xb1\x24\x9d\x6d\x87\x94\xf2\x3b\xb8\x77\x9d\x41\x86\x48\xf2\x15\x56\x56\xa6\xfd\xa7\x44\x0c\x56\x28\x4d\x9b\x21\x88\xfa\x7d\x17\x36\xbc\xcc\x9c\xff\x0b\xe5\xb1\xe1\xf5\x51\xff\x81\x37\xff\x59\x66\xed\x9d\x0f\x7f\x01\xc3\xdf\xf2\x98\xe9\x10\x2f\xfb\xd3\x24\xbf\xca\x5f\xfe\x09\x68\xe6\x6f\x9d\x82\xf4\x87\xd3\x03\x93\x4f\x27\xf7\x8b\x28\x37\x8e\xb7\x2c\x38\x27\x29\x62\xa5\xf7\x35\xd7\x39\x2e\x5d\x33\x3f\xd8\x6d\xe1\x67\x26\x9c\x17\xa1\x65\xb9\x2d\x31\xa4\x88\x0a\x41\xe1\x36\xf7\x18\x96\x0a\x91\x9b\x3d\x7c\x4e\x74\xcb\xd7\x3c\x73\xf9\x21\xbe\x51\x3f\x73\x9a\xff\xb2\xe4\x1f\x80\x42\x6b\xb8\xcf\xb4\x56\x4b\x98\xfc\x4d\xe5\x32\x55\xce\x3f\x98\xb4\xd2\x2a\xe6\xfc\xe9\x19\x0b\x55\xbf\x2c\x93\x86\x1c\x1d\xca\xc1\x01\xb5\xe1\x6c\xf0\x99\x91\xc5\xde\xfa\x33\xf8\xd5\x10\x56\xd9\x34\xbb\x4b\x47\x7b\x65\x20\xd4\xc7\xae\x22\xea\x7f\xb3\x10\x9d\xe7\xf4"}, +{{0x4b,0x8e,0xd2,0x97,0x31,0xf1,0x04,0x79,0x5e,0x97,0xde,0xe7,0xc8,0xb4,0x01,0xa0,0x2a,0xfa,0xa9,0xa7,0x95,0xe6,0x13,0x35,0x3d,0x2b,0x95,0x00,0x17,0x65,0x02,0x7a,},{0xf2,0x22,0x98,0x21,0x0b,0x09,0xfd,0x61,0x7f,0xc8,0xb3,0x50,0x74,0xca,0x18,0x01,0xe6,0x07,0x5d,0xc9,0x2a,0x8f,0x50,0x34,0x4b,0x80,0xe8,0x54,0x05,0xa0,0x38,0xf5,},{0x23,0x45,0x88,0x66,0x86,0xeb,0x39,0xb5,0x19,0x9c,0xaa,0xa9,0x61,0x5b,0xc6,0xb4,0x89,0x6f,0x07,0x6e,0x8b,0xd7,0x36,0xc0,0x03,0x8a,0x65,0x17,0xf9,0xc2,0xb1,0x67,0xe7,0x59,0xf3,0x73,0x72,0x26,0x8a,0x69,0x7e,0x9b,0x78,0x60,0x5f,0x2e,0xd9,0x47,0x25,0xf6,0x90,0x5a,0x79,0x00,0x15,0x3f,0xc9,0xe8,0xbe,0xed,0x31,0xff,0xae,0x05,},"\xcb\xb5\xf1\x3a\x0e\xf2\x83\x7b\x80\x5d\x3b\x78\x51\x09\xf9\xf2\xe0\xd0\xa0\x17\xbf\xe7\x69\x2d\x91\xec\x23\xdd\xab\x78\x17\x33\x0b\xef\x24\x7f\xd9\x1a\xb2\xc7\x7d\xd4\x41\x25\x19\xcb\xd3\x84\x75\xce\x0c\xb3\x9b\x14\x80\x09\x2b\xc7\x38\xd4\x15\x2b\x8a\x6d\x55\x24\x8e\x3b\x9f\x32\xcd\xcd\x15\xec\x5d\x05\x9e\xc3\xc8\x84\x75\x54\xee\x47\x00\x53\x94\x97\x4d\x8e\xb2\x35\x92\xd1\x7f\x5a\x39\x6e\x3c\x19\xf8\xe8\x98\x37\x06\x79\xfe\xf5\x31\x8c\x4d\xd2\x99\xc6\x21\x7d\x6a\xbc\xc9\xb6\x1a\x5b\x2d\x0c\xfe\xf6\x95\xd1\x70\xca\x20\xa8\x3d\x6f\xd3\xc6\x66\xc8\xfd\x1c\x10\xad\x97\x0e\x2f\xa6\xaf\x10\xff\x0e\xd0\xcb\xfe\x75\x22\x46\xd0\x3f\x3a\x3c\x60\x32\xdb\xb3\x19\xbc\xfd\xac\x4d\xaf\xc5\x0b\xc3\xe6\xbf\x59\x5f\x49\x1d\xec\x38\x8b\x34\x41\xb8\xce\xe0\xdf\x91\xf5\x5c\xc7\x80\x7d\x07\xf8\xf5\x41\xed\x73\x22\xff\xc3\x9d\x18\xf8\x95\x60\xe4\x12\x3a\xec\x1d\x77\x96\x9c\xf1\x87\x77\x86\xf4\xcf\x94\xb1\x77\x0b\x10\x90\x65\x5e\x8c\x72\xee\xce\xa4\x57\x2e\x46\xf5\x80\xf9\x63\x96\x6d\xb2\xa1\x08\x5e\xea\xbc\x57\xbf\x4a\x84\x72\x4b\x9c\x85\x99\xa4\x33\xab\xf5\x8b\xca\x80\x40\x91\xd3\xd5\xe6\xe5\x04\x8e\xc2\x7b\xf8\x12\x9b\x67\x0c\xc2\xc8\x8d\x9c\xac\x47\x18\x59\xf4\x69\xb9\x18\xf3\xf6\xd7\x0f\x7d\x66\x63\x50\x1f\xfb\xef\xef\x02\x6d\x79\xea\x70\x92\x7c\xcf\x60\x75\xee\x51\x05\x42\x33\x21\xe1\x1a\xee\x9a\xd1\x6f\x98\x7e\xfb\xdd\x00\xb6\x2a\xff\x69\x8e\x52\x1a\xdf\x92\x03\xb1\x5e\x9f\x0f\x3a\xd0\x7d\xca\xd9\xdd\xcc\xaa\xe9\xb4\x90\x24\x7f\x12\xc3\x11\xde\xe6\xb7\x3b\x8f\x91\x24\xfd\xce\x12\x99\xb4\x7f\xb1\x91\x4c\xee\x7e\x3a\x07\x81\x4e\x31\x2c\x3c\xe5\x69\x27\x67\x2c\x51\xb3\x18\x59\x80\xcd\xe5\x7f\x3a\x75\x9b\x50\xbc\xfc\x4c\xb0\x75\x3b\x95\x4d\x97\x13\x5d\xeb\x2a\x05\x32\xe9\x8b\x66\xf3\x9a\x7c\x08\xcf\x4d\x54\x85\x39\xe2\xeb\x9f\x42\x2f\x66\x49\x65\x88\x93\xa7\xc3\xc2\x5a\x4f\xc9\x01\xf8\xc3\x98\xb8\xc7\x27\x33\x91\x1a\x00\x72\xed\x6b\xd2\xf4\x18\x93\x89\xae\x10\xa8\x14\xf6\x48\xd7\x1f\x69\xc3\x7e\x82\x95\x78\x44\x28\x18\x3b\x93\xc8\x01\x3b\x96\x4a\x9f\xef\x86\xb4\x8f\x48\x93\x16\xbc\x22\x2e\x96\xb3\xbd\x15\xff\x14\x9b\x96\x82\x03\x29\x55\x1c\x15\xe0\xd0\x95\xd1\x56\x9b\x1e\x21\x31\xc7\x87\x51\x56\x5c\x30\x41\xf2\x97\x85\x39\x5b\x97\x15\x13\x17\xf6\x2e\x35\x82\xe4\x07\xb1\x64\x9e\x60\xd0\x3a\x85\x99\x12\x0a\x30\x2a\x46\x95\xfa\x86\x2b\x41\x20\xf9\x4d\x22\xec\xae\x72\x39\x8d\x20\x94\xd1\x08\xad\x2d\xbc\x1b\x95\x97\x35\x90\x21\x42\xaa\x5f\xe6\xe7\x99\x65\x59\xf6\xf6\x01\x44\x8a\xea\x02\xf3\x56\xf8\xdc\xdd\x14\x43\x40\xeb\x36\x19\xf9\x86\x5b\xf7\x67\x2a\xea\x32\x6c\x4e\x93\xc9\x9f\x0e\xd1\xf9\xed\x86\x6b\xe1\x5d\x3a\xf2\x67\x5f\x6d\xd6\xe2\x96\x60\x2c\xa3\x73\xa8\x15\xb0\xbe\x46\xbc\x2a\x3f\xbb\xa0\x6b\x88\x05\xc7\x31\xfe\x08\x00\x7d\xaa\x06\x05\x09\x61\xb2\x4d\x14\x69\x3a\x72\x89\x8c\xcf\xb8\xb8\xfe\xdc\x60\xa4\xee\xf8\xff\x79\xb6\xdd\x75\x92\x59\x18\x33\xb5\x76\xef\x48\x29\x4e\x5e\x04\x85\x94\x2e\x57\xc1\x19\x60\x2e\xdd\xf8\x8b\x1f\xae\xa5\x17\xf2\xfc\x2e\x3d\x14\xd2\x46\xa5\x2c\xbd\x71\xa1\x08\xc6\x6b\x6c\xc4\xf2\xd4\x58\x04\xa2\x82\xec\xed\xb1\xb0\xad\x3d\xc3\xb4\x88\x0a\xb2\xff\x78\xb8\xdd\xde\x48\xf7\x46\x6c\x14\xfe\xd3\x49\xe9\x5b\x50\x53\xab\xf1\xbf\x09\x91\x12\x60\x31\xd9\x75\x47\xd1\x43\xc2\xae\x16\x49\x28\xb6\x1c\x07\x08\xaf\x8c\xa3\xe4\xf5\x51\x54\xd1\x3d\x75\xe9\x7d\xb4\xba\x3e\x69\xd3\x6e\x9b\x37\x08\x23\x68\xc2\xf7\x21\xbd\x3f\x95\x12\x6a\x1e\x00\x4e\xb2\xa1\xbf\x26\x83\x43\xae\x21\xd2\x99\x50\x44\xa2\xca\xdd\x67\xff\xac\x9e\x15\x38\x17\x5b\x3c\xc4\x4d\xb5\xd2\x6f\x1d\x5c\xc8\x9c\xa0\xe1\xc1\xee\x85\x37\xa8\xa9\x1d\x32\x4c\x2e\x02\xe1\x8b\x9f\xb9\x73\x0d\x6d\xda\x55\xf7\x2d\x84\x33\x89\x69\x3e\xbf\xcb\xa7\xfb\xe1\xa0\xbc\xff\xb9\xaa\x28\x4f\x4a\xe6\x6f\x44\xa8\xb8\x93\x02\x98\x3b\x22\x73\x6d\x0c\x72\xd6\xa0\x44\xe4\x29\x16\x24\x24\x3a\x4e\x0c\xe6\x5d\x5e\x53\x46\xd6\x7f\xed\x37\x60\xdd\xb0\xc5\x10\xb5\x0f\xf3\xee\xf0\xa1\x8a\x26\x7d\xe7\x30\x47\x6d\xd8\x2d\xff\x70\x72\xcb\xa0\x98\x48\x25\xa0\x04\xdd\x4b\xcd\x8c\x37\xfd\xaf\x1f\x68\x3d\x1d\x93\x80\xe1\x35\xa9\x5d\x24\xb8\x9f\xad\x0b\xe9\x41\xc5\x48\x25\x1b\xec\x90\xcc\xae\x01\x5b\xc0\x56\x7d\xa8\x4b\x37\x1e\x50"}, +{{0x08,0x0d,0x7f,0x76,0x18,0x2e,0xe6,0xbc,0xea,0x89,0x4b,0x1e,0x00,0x60,0x55,0x8b,0x3b,0x12,0x5a,0x34,0x99,0xdf,0x39,0x73,0xb8,0xdd,0x66,0x93,0x40,0x8e,0xe4,0x69,},{0x41,0x24,0x71,0x3d,0x7c,0x2d,0xf5,0x0f,0x93,0x05,0x57,0x30,0xd1,0xb2,0x81,0xda,0xec,0x30,0x28,0xcf,0x2c,0x1e,0x48,0x58,0xd1,0x28,0x70,0x7a,0x23,0xd6,0xde,0xb0,},{0x18,0x5f,0xb1,0xb6,0xd8,0x6d,0xc4,0x44,0x48,0x10,0xcf,0x5e,0xc6,0xfe,0xf0,0xab,0xda,0xfa,0x2a,0x6f,0xcc,0xb4,0x5d,0x11,0xcf,0xb5,0x4b,0xa1,0x6a,0x68,0x43,0xf2,0x80,0xd3,0x80,0x47,0x10,0x02,0xae,0x0d,0x71,0x50,0x85,0x56,0xc7,0x8e,0xd5,0x41,0x5e,0x42,0x33,0x8c,0x16,0x1f,0x2b,0x62,0x1e,0x74,0xcb,0xa4,0xf6,0xa1,0xd4,0x02,},"\xab\x0a\x6d\xe2\x35\x1b\x9a\x84\x98\xf6\x82\x72\xd9\xa0\xa7\xa0\x57\x36\x5d\x34\xef\xa0\xfd\x34\xcc\x3b\xf8\x62\xe4\x9c\xdc\x30\x2b\x2b\xd5\xa3\x0d\x60\x1a\x13\x0e\xc4\x03\x2f\x54\x1a\xe6\xcb\x7b\xa9\x7f\x84\x18\x3d\x2d\x25\x81\x28\x7c\xa7\x01\xd7\xd7\xa9\xab\xa1\x10\xce\x58\xb9\x46\xac\x08\x24\x30\x5d\xf7\x92\x9f\x3d\xd7\xfc\x9c\x87\x32\x23\x86\x37\xe2\xb1\x81\xd6\xe1\x16\xc7\xf6\x6e\x32\x26\xaa\xe3\xce\xd1\x61\x02\x62\xda\x1a\x0a\x4a\xa5\x0a\x1b\x94\x43\xec\x82\x83\x29\xe4\x73\x4d\x28\xfc\x25\xab\x9c\x1d\xe9\xb8\x98\x7e\x5d\xc0\xc8\x13\x19\x16\xc5\xf1\x89\x28\x70\x4a\x71\xe8\x06\x22\xb1\x49\x2b\xf2\xfe\xc5\xd4\xb6\xdb\xe4\x15\xc8\xaf\x2c\xe3\xef\x10\x9b\x34\xdd\x5e\x64\xd5\x68\x46\xf0\x85\x93\x5a\x4a\x5d\x10\x73\x49\x7f\xb3\xfb\x8f\xb7\x7e\x8f\x5d\x5e\x3f\xd0\x0c\x30\x65\x2e\x3c\x5c\xde\x40\xa3\x35\xd1\x4e\x54\x25\xff\xba\x94\x28\x85\xed\x17\xbd\x36\xdf\x50\x69\x24\x23\x7e\x75\xbe\x84\xda\x82\x19\x50\xb9\x14\x24\xfd\x9f\x16\xc1\xb2\xc7\x83\xe9\x0f\x8c\xc2\xcc\xc7\x98\x0c\xe9\x15\xc7\x69\x6b\x06\xa5\x86\x73\x02\x59\xe6\xd1\x45\x88\x58\x2b\xab\x9d\x2a\x39\xf6\x9e\x98\xe7\xf2\xae\x9b\xc0\xc2\x61\x0d\x7e\x04\x57\xf2\x6a\x5d\x66\x54\x3b\xe1\xd6\x5b\x79\xc4\xb7\xc0\xd8\xee\x73\xd0\xc2\xb6\x7b\xf5\x0d\x80\x82\xf0\x06\xf9\x6d\x11\x95\x05\x87\x31\x93\xdf\xdb\xd4\x32\xbb\x1c\x9e\xe0\xd0\x3e\xe5\x4c\xf9\x5d\x20\xe9\x1f\x7f\x3a\x06\x9b\x62\x56\xf4\x21\x59\xcd\xc1\xe6\x00\xa9\xa1\xc2\xf5\xa8\xe4\x67\xd5\xc2\xa9\xdf\xf8\x73\x0e\x6b\xe8\x26\xfb\x2a\x1e\x64\x48\xbf\xc4\xfc\xaa\xaa\xcd\xaa\x76\x62\x35\x1f\xaa\xdc\x91\xf7\xca\xa7\x73\x7d\xc8\x2e\xc3\xd4\xb2\x19\x36\xbc\xa1\xbd\x7c\xe3\x73\xad\x66\x26\x4a\xf1\x32\x41\x16\x75\x49\x31\x8c\xdd\x78\xe5\x63\x82\x7f\x85\xea\xb2\x0e\x0b\x42\xbc\x55\x4a\x71\x2c\x00\x51\xa5\x01\x0d\xc2\xf2\xc7\xdb\x85\xac\xf6\x54\x9f\x9d\x10\x2c\x90\x3c\x1b\xe5\xa0\x52\x92\xc3\x0f\x21\xab\x1b\x2b\x8a\xbc\xbb\xf1\x04\x72\x3c\x63\xf0\xeb\xc5\x54\xfb\xee\x42\x02\x0c\xcb\x14\xf4\x43\x47\x8d\xf7\x7c\x6a\xa4\x4d\xb9\xa5\x7f\x8f\xd4\x4d\x97\xea\x09\x9e\x47\x74\x82\x3e\xbe\x12\x3f\xcf\x50\x16\xa6\x6e\x83\x7b\x2f\x65\xc1\x84\x5e\x68\x1e\xe2\xa7\x05\x9f\xb1\x29\x0c\xd0\xa9\x33\x12\x98\x55\xcc\x83\xc8\x7e\x0b\x3b\xb6\x1e\x44\x13\x4a\xdd\xd3\x63\x78\x50\x24\x6c\xdc\xda\xa2\x9f\x15\xc4\x1a\x3d\x4d\xd2\xc1\xd7\x60\x06\x21\x24\x33\x31\x24\xcf\x09\x14\x35\xfd\xce\x71\x1f\x52\x31\x63\x68\x99\x9b\xef\xa4\xc8\x0a\x39\xb3\x75\x0e\x4e\x38\x62\x89\xe4\xe2\x85\x5e\x97\xb6\x19\xb0\xa2\x57\x99\x91\x24\x08\xb7\xd5\x8a\x4d\xd9\x81\x95\x71\xe9\x01\x43\x0f\x6d\x55\x55\x29\xdd\x63\x0a\x18\x67\x45\x9b\x80\x22\xd0\xe0\xad\xd6\xab\x4f\x12\xf6\x0b\xaa\xc7\x59\x79\xbb\xff\x7f\x62\x58\xd2\x8d\x67\x60\xb1\xff\x24\x3c\x39\xe4\xbb\xd6\xcf\x9b\xea\x57\x2a\x9c\x08\x2d\x05\xad\xcf\xd4\xcc\xf9\xfa\x02\x6f\x2c\x90\x4b\x6e\x78\x2e\xd7\x09\xdf\x77\x48\xa3\x07\xcd\x2d\xc3\xa0\xfc\x41\x23\xdf\x58\x0c\xbf\x49\xe0\x5c\xee\xab\xc9\xf3\x9e\x57\xb7\xf3\x00\x90\x5d\x8b\x31\x00\x91\xfb\x95\x3f\x3d\xef\x36\xde\xb3\xe8\xbf\x37\x2f\x59\x16\xb5\x15\x97\xdf\x02\x4c\xe8\x5c\xc4\xc3\x6e\xab\xdc\x58\x0b\x5c\xf1\x52\x99\x46\x48\xf1\xd7\xf3\x5f\xed\x5c\xd1\x0f\x6e\x29\x49\x16\x1a\x33\x59\xb3\x03\x4d\x45\x0e\xa6\xf6\x1c\xdf\x1d\x5a\xf7\x6d\x40\x10\x2b\x60\x29\x4f\x4e\x49\x07\x82\x49\x02\x6d\x62\xfe\x35\xfd\xf2\x24\x92\x8b\x0c\x49\xba\x2b\x53\x39\xeb\xb1\x92\xc5\xab\x7f\x05\xcd\xb9\x46\xe3\x7d\x67\x1a\x4a\x5e\xf2\xa5\x82\x72\x20\xb4\x43\x8c\xbd\xa0\x57\x36\x29\x28\x06\x64\x8f\x5b\xdd\x52\x42\x0f\xa7\x6b\x84\xa6\xad\xdb\x12\x63\xeb\x0c\x50\x0e\x81\x56\x6d\x71\x8d\x50\x66\x02\x6d\xa0\x97\x05\x4a\x86\x63\x10\x16\xdd\xfb\x70\x6a\x56\x77\xd5\x02\xef\x84\xaa\x73\xb5\x86\x3b\xc4\x0f\xdc\x42\xcb\x73\x21\xac\x5f\x00\xe2\x92\x8f\xed\x7b\x04\x18\x59\x6d\xb4\xb6\x15\x1d\xd6\xbc\x6e\x81\x8f\x02\x53\x55\x2b\xf1\x37\x41\xe6\x96\x80\xe9\x66\xc9\x2c\x29\x3e\x13\xc9\x0f\x7c\x99\x99\xbd\x1e\xc6\xaf\xe3\xb4\xaf\xfb\x47\x34\x0c\x89\x85\x98\x29\xfe\xb5\x99\xdb\x3a\x8c\x3d\x33\xfc\x8d\x45\xfa\x53\x81\x07\x8a\xe9\xf7\x5d\x85\xc1\x49\x6f\x5f\xb5\xad\xdf\x4e\x40\x09\xb7\x64\xbc\xc9\x11\x8e\x92\x75\xdc\x72\x19\xf2\x81\xd0\xd1\xef\x71\x58"}, +{{0x49,0x84,0x6a,0xda,0x7a,0xe6,0x84,0x97,0x1d,0xd9,0x17,0x10,0x79,0x90,0x90,0xb3,0x7f,0xe5,0xad,0x56,0x1d,0x72,0xa3,0x5f,0x2e,0xfb,0x40,0x5f,0x19,0x6a,0xb0,0xec,},{0x4d,0x37,0x0a,0x81,0x94,0xa3,0x04,0x5b,0x09,0xb3,0xbd,0xaf,0xa2,0x7f,0xb9,0xac,0xd5,0x99,0x43,0xa5,0x4a,0xe1,0x4c,0xba,0xaa,0x22,0x00,0xeb,0x0f,0x3d,0xa7,0x1b,},{0xa5,0xc8,0x09,0xd1,0xca,0x4c,0xfb,0xb3,0xdc,0x70,0xa2,0xa3,0xa1,0xf2,0x67,0xc2,0x73,0x30,0x42,0x07,0x19,0xe3,0x60,0x62,0x18,0xa1,0x47,0x1c,0xac,0x57,0xcb,0x67,0x4b,0x9b,0x42,0x82,0x7c,0x5e,0x9a,0x7b,0x25,0xc8,0x13,0x9c,0x13,0xdf,0xf6,0x0b,0xde,0x6c,0x2d,0xba,0xd3,0xa8,0x36,0x11,0x97,0xc1,0xfb,0x19,0xd2,0xcd,0x52,0x0b,},"\xab\x39\x8d\x94\xf9\x28\xb1\xd4\x21\x02\xa3\xe5\x13\xcc\xd1\xcb\x10\x89\x90\x11\x03\x94\x10\xa8\x88\x8b\xba\x26\xdf\x1a\x03\x72\xbd\xba\x0c\xe8\xd8\x54\xaf\x51\xe9\x33\x0a\x8d\xaa\x93\xc1\x05\x80\x90\x6a\x8a\xc7\x2d\x29\x4a\xeb\x95\x66\xfe\x1c\x78\xba\x84\x71\xc0\x6c\x4a\x8a\x75\x11\x3b\x34\x89\x3f\x62\x76\xed\x81\x32\x92\x05\x3b\x95\x6a\x46\x5d\x84\x7d\x2e\xce\x86\xe2\xda\x8a\x9f\x0f\xe3\xdb\x52\xa5\xaa\xc7\x46\xef\x96\x48\x5e\xf8\x1f\x13\x62\xb5\xa4\x2e\xaa\xee\x1f\xbb\x06\x46\x70\x44\x71\xa2\x1b\xf7\x63\x67\xbe\xaa\x07\x81\x2b\x3d\x32\xad\xcd\xed\xde\xd7\x53\x9e\x3a\x50\x1b\x83\xc0\x5b\x19\xa4\x9b\x52\x0e\xde\xdc\x9a\x78\xa5\xfc\x2d\x50\x12\xf1\xd4\xe3\x81\x84\x4e\x79\x2e\xd9\x0b\x0f\x57\xbc\xe3\x75\xc7\x5a\x65\x8b\x2c\x78\xc6\xff\x7d\x9e\xfc\xd4\xbf\xa3\x5c\x47\x68\xcb\xb1\x95\xe4\x82\x3d\x9b\xbd\x83\x5a\x37\x4f\xa0\x4c\xa1\xea\xae\x9c\x56\x6d\x8f\xd5\xaa\x7c\xa5\xef\xe0\xdf\xc3\x17\xff\xfa\x40\x9e\xf1\x02\x2f\x1c\x3b\x37\x6a\x93\x5a\xf5\x57\x08\x3e\x95\x28\x7b\x07\xa9\x8a\xc6\xc1\xb7\xbd\x8b\xb2\x6b\x60\xfa\x7c\x4b\xc9\x19\x73\xb2\x01\xb2\x99\x22\xb4\xb9\xd0\x3d\xd6\x88\x2a\x0b\xd3\xb7\xd9\xe5\xb8\x1e\xe7\x4c\x36\xbe\xc6\x65\xe4\x34\x3c\x8c\x9a\xd3\x36\xda\x38\x50\xc9\xb2\x69\x7f\xe1\xcc\xe2\x9c\x37\x86\x22\xa3\x3c\x24\x8f\x44\x8c\x88\xf4\x8d\xf0\x26\x01\x43\xb2\xa3\x42\xf1\xdd\xee\x74\xd3\xb9\x7c\xa3\xe1\x16\x6b\x15\x69\x93\xda\xd3\x0c\x49\xd8\x10\xd7\x40\x48\xbc\x6d\x46\x76\x52\x00\x4d\x7e\xdb\x65\xc6\xda\xc3\xa2\xc5\xd3\x00\xb9\x7e\xe3\xa1\x0a\x9e\x14\xb6\x9f\x3c\xad\x67\x59\x72\x96\x2e\x1f\x8e\xd9\x75\x47\xad\xed\xc4\x7d\x1c\xf3\x47\x1e\xf3\xb2\x2f\xdb\xf7\x8e\x34\xf3\x1a\x3b\xb7\x66\x9c\x41\xbd\x92\x92\xc3\x80\xbc\xe9\xa4\x2d\x84\xbc\x27\xac\x92\x8b\x8b\xfc\x3c\x63\xd2\x0c\xcd\xb4\x78\xdf\x7d\xdf\x42\x1f\xb1\xcd\x90\x5f\xfc\x4c\x04\x78\x6f\xd9\xae\xf0\x6b\x89\x38\xab\x8e\xf5\x22\x21\x7b\x2c\x04\x51\x5f\x61\xa1\xc3\x12\xea\x83\x25\x3f\x84\x58\xc0\x91\x8f\xcf\xe8\x74\xe6\xe7\xfb\x11\x27\x5d\xb2\xa2\xec\x79\xa2\xd8\x68\x30\x32\x33\xc1\xb6\x97\x95\x2a\x3b\xfd\x3a\xd0\xa6\xf6\xcd\xd5\xe7\x2c\xc9\x40\x9f\x74\x10\xa4\x0d\x5b\x45\x36\xdd\x46\xeb\x16\x11\xae\x86\x70\x36\x71\xb3\xa0\x51\x5a\x03\x77\xbe\xa1\x56\x54\xba\x0a\x0d\x1e\x4e\x96\x02\x63\x28\x42\xf2\xac\xd4\xef\x99\x32\x36\xe9\x93\xf2\x65\x0d\x59\x92\x3f\x24\xe2\xcd\x30\x93\x2d\x8b\xf8\xae\xec\x64\x44\x72\xba\x46\xa0\x78\x81\x49\x6c\x92\xa0\x13\x5c\x67\x5a\xeb\x0c\xe6\x18\x10\x88\xdb\x8f\x15\x6c\xfe\x74\x35\xca\xc6\xc9\x7d\xa6\x37\xdb\x4a\x89\xf5\x13\x31\xda\x13\x73\x1e\x74\x1f\xcc\xc0\x35\x55\x42\xce\x11\xef\xa6\x9d\x05\x38\xd3\xef\x12\x7a\xa6\x87\x45\xed\x30\x85\xd2\x9d\xa9\x0d\xc5\x83\x70\x1b\x6b\x3a\x70\xa3\xef\x3e\x16\xa9\x24\xb3\x32\x03\xb9\x23\x96\xc4\xb9\x45\xf1\x27\xa7\x88\x8f\xa0\x50\x15\xc0\x60\x30\x07\x56\x67\x29\x23\x7c\xc0\x78\x2b\x30\xc0\x20\xd9\x95\x95\x47\xfe\xec\x9f\x4d\x67\x64\x60\xbf\xe0\xc5\xc1\x9c\xea\xba\xee\x06\x82\xdb\x8b\xe6\x91\x35\x18\x1e\xc0\xfd\xd9\xf7\xa6\x6d\x50\xbd\xc3\x79\xe4\xa2\xc5\x98\x17\x8f\x95\x93\x94\x6a\xca\x64\x05\xb1\x77\xfc\xad\xe0\xf8\x64\x21\x58\x3e\xd6\x7e\xba\x18\x72\x22\xa1\xe4\x44\x95\xb3\xae\x54\x4f\xdc\xa2\x8e\x2c\x14\x48\x5e\xab\x04\x71\xaa\xa8\x03\xc2\x9a\x9d\x8a\x48\x92\x67\x64\xfc\xa1\xdf\x51\x40\x7a\xd3\x3e\xc1\x7e\x94\x1e\x6e\x26\x17\x23\x7a\x84\x30\x98\x73\xdc\x71\x36\x55\x87\xbd\xe4\x27\x4b\x5d\xc3\x27\xcc\xb1\xe1\xe9\xc8\x57\xe0\x42\xcc\xca\x8d\x85\x52\xba\x28\x8c\x97\x8c\xfa\x0a\xf9\x9d\x67\xcd\x03\x40\x60\x62\x8e\x23\x52\x5d\xbc\xa2\x07\x67\x9c\xe2\x96\x90\x87\x84\x48\x55\x3c\xd3\x86\x75\xbc\xe0\x7b\xf9\x7b\x93\x17\xdc\x44\x46\x8b\x76\x8b\x15\x8b\x0c\x11\x1d\x63\xa5\x72\x23\x56\x55\xc4\x0e\x16\x59\x7c\xa0\x59\xf4\x0c\x3d\x8a\xc5\xbd\x61\xa4\x87\xc1\x53\x13\x84\x6a\x70\x4a\x78\x11\xb8\xbc\x0c\xee\x61\xe3\x47\x62\xb6\xc1\xb7\xce\xa1\xc4\x6e\x60\x87\xe9\xa3\x6f\x89\x91\x8a\x25\x8b\x3f\xa7\x76\x20\xbe\x10\xc1\x84\xc3\xfc\x39\x73\x90\x24\xe9\x82\x78\xfd\x65\xb8\x2c\xad\x83\x69\x9f\x3a\xd8\xc6\xec\xcb\xec\x8b\x7b\x1b\xd7\x91\x4d\x3f\x6c\x3d\x02\xbf\x40\x28\x3b\x1c\x1f\x1e\x98\xe3\x08\xbe\xae\xbb\xf8\x94\xb8\xf5\xe9\x1b\xbb\xc6\x25\x35\xf9\x23"}, +{{0x83,0x34,0x3e,0x37,0xad,0x09,0x1a,0x85,0xee,0xc3,0x70,0x70,0x1b,0x81,0xa5,0x8f,0x93,0x70,0xa4,0xb0,0x42,0x3a,0x07,0x0d,0x60,0xf9,0x2d,0x8d,0x18,0x09,0x84,0x4e,},{0x50,0xb6,0x8b,0xf7,0x26,0xea,0xbc,0xa5,0x3a,0xc6,0xc9,0x0d,0x4e,0xac,0x55,0x47,0x03,0x71,0x2d,0x22,0x10,0x55,0x54,0xf0,0x5b,0xf7,0x9f,0x9d,0x08,0xfc,0xc4,0x93,},{0x9c,0x69,0x89,0xcb,0xe1,0x7e,0x16,0xca,0xa2,0x53,0xff,0xb1,0xa6,0x4a,0x10,0x6f,0xb0,0x17,0x82,0xc9,0x9b,0x17,0x22,0xba,0xf1,0xac,0xaa,0x42,0xae,0x5b,0x36,0xb7,0x9b,0x2a,0x2c,0xd8,0xfc,0x91,0xf5,0xad,0x89,0x23,0x81,0x70,0x25,0xa7,0x78,0x25,0xa0,0x5d,0xf8,0xc4,0x17,0xec,0x53,0xc4,0xa3,0xaa,0x1c,0x0e,0xfd,0x5b,0xbe,0x0f,},"\xc7\xda\xdc\xac\x5d\x87\x95\xe1\x74\xb6\x91\x38\x91\x2e\x70\xff\x41\xe7\xa7\x25\xfa\xf3\x85\xb7\x73\xed\x15\x09\x89\x72\xb3\x0d\x9b\x73\x93\x72\xd9\x75\xb4\x80\xcc\xfd\xfc\x58\x0e\x2e\x2d\xdf\x5e\x3c\x27\xee\x79\x12\x79\xab\x95\xe4\x38\x2b\x14\x59\xdd\x8d\x41\xae\x36\x0d\x4a\x87\x88\x46\x69\x29\x24\xfe\xef\x39\x0c\x0d\xbb\xfa\x35\xe4\xb8\x2d\x7c\xbc\x33\xee\x15\x81\xc5\x2b\xd9\x49\x38\x5b\x2e\xe4\x02\x63\xa5\x7d\xa1\x17\x4b\xb4\xac\xad\x37\xcd\x8a\xe2\xa6\xb4\x5f\x7a\x6d\x6b\xbe\xf5\xa7\x98\xce\x85\xb9\xe0\x5e\x76\x47\xe3\x34\xec\xfc\x77\x63\x78\xde\x17\x4c\x49\x7c\x0f\x40\x75\xe6\x25\xaf\x7a\xed\x50\x2c\xd1\xcf\x7f\x58\x8d\x0d\x80\x7f\x02\xe3\x2f\x43\x00\xf2\x28\xa5\x0a\x66\x7b\x5a\xd1\xfb\xbc\x17\xe0\xb3\xc5\x70\x51\xdd\xc6\x02\xf5\x76\x07\x9f\x6f\xc5\x88\x9b\x7f\x29\x00\x71\x13\x34\x42\x0f\xc6\x66\xf6\x6d\xba\xff\x41\x26\x33\x6c\x35\x3f\x1e\x5b\x56\x4a\x66\x45\x37\xf8\x37\x86\xda\x5c\x56\x27\x74\x54\x06\xd7\xb2\xfe\x32\x33\xbf\xd5\x8e\xf4\x64\xa0\x6c\x95\xcf\xd0\xb9\x88\xa7\x6d\x05\x3a\x64\x4b\xcc\x15\x9c\xad\x53\xa7\xc5\xdb\xb4\x0e\xef\x5c\xd0\x47\x05\x6a\x3f\x09\x26\x5b\x13\x25\x69\x9c\x7d\x15\x9d\x5c\x90\x24\x40\x17\x33\x57\xff\xab\x8f\x7a\x5e\x38\x9f\x46\x8c\x33\x3b\x78\x2f\x80\x17\x0a\xe9\x09\x83\xaf\x15\x3f\x2e\x73\xbd\x2b\xef\x12\x5e\x3d\x38\x68\xc2\xab\x9e\xcf\x03\xaf\xf7\x6e\xcb\xeb\x18\x16\x7c\xa2\xf7\x11\xcd\x56\x58\x51\xd7\xf0\x4e\xe9\xd9\xb0\x1b\x6d\x83\xa7\x60\x57\x22\x62\x0d\x28\xc8\x4d\x6c\x1a\xf4\x2f\x6a\x76\x92\x58\xf5\x3c\x1f\x66\xda\x36\x66\x6d\xa5\xca\xa9\xbd\x9e\x8f\xbc\x16\x92\x11\xb1\xae\xd9\xc2\x55\x8f\x6a\xaf\x5b\x14\x5a\xbc\x72\x1a\xbb\x00\x72\x01\x94\xe0\x27\x03\x54\x68\xbd\xe3\xfe\x0b\x88\x88\x4f\x4e\x9b\x26\xe7\x71\xe6\xc7\xa0\xa5\x5e\xa3\x6f\xc5\x0d\xec\x8c\xef\x16\x2f\x9b\xba\x5b\x4b\x16\x10\x5a\xfd\x6e\x37\x4e\x03\x8d\x5c\x85\x87\xcf\xd7\xdd\x88\x29\x0b\x2c\x9c\xab\x45\xa2\x64\xd6\x54\x0e\xa1\x41\x6e\x6e\x4e\x74\xa1\x2f\x45\xa2\xef\x13\xcc\x8a\x36\xe7\xb0\xa2\x6b\x90\x2c\x3d\x96\xe2\xe2\x22\x92\x02\xe2\x57\x65\x69\x4b\x94\x33\x73\xd1\x6e\x60\x0b\xd7\x86\xd9\x55\xa4\xb3\xf1\x02\x16\x40\xc3\x9a\x0b\x6c\x69\x15\x00\x28\x1a\xe0\xd0\x98\xcc\x7f\x38\x5e\x18\xa0\x7e\x62\xfa\x4a\x10\x1e\xf5\xb7\x85\x51\xfa\x29\xbd\x15\xee\x03\x53\xa1\xa5\xef\x9b\x21\x6e\x8b\x0f\xa5\x07\x50\xa3\x41\x62\xb6\x35\xa0\xbc\x5e\x5d\x72\x30\xaa\x19\xaf\xa1\x28\xab\xa6\x42\x2d\x38\xeb\x77\xa3\xf0\xbb\x9d\xd8\xe4\x65\x2f\x12\x07\x0a\x37\x36\x1c\x37\x25\x50\x3c\x9d\x22\xe2\xfa\xce\x2e\xa7\x4a\x70\x02\x40\x62\x47\xdd\x86\x97\x5f\x07\x57\x5c\x9e\x7c\x6f\x41\xb5\x3b\x26\xd5\xcf\x52\xc5\xac\xc2\xc5\xd9\x82\x71\x43\x4e\x9f\xa5\x09\xc6\xdf\xbd\x72\x43\x72\xaa\x5c\x13\x45\x1a\xae\x39\x3d\xe0\xa1\x86\x46\x4f\x5d\x33\x7e\x9f\x62\x7b\x4f\x1c\x29\x09\x46\x70\x65\xe8\x9a\x42\x2e\xc4\x0e\xe1\xd8\x0a\x13\x39\x00\xa6\x2f\x4e\x4f\x7e\x94\xeb\x72\x61\x5e\x7e\xc2\x99\x6c\x6c\x24\x30\xc3\xe9\x57\xce\xae\x21\x05\xa1\xe9\x0e\xae\xac\x0d\x31\xaf\xfa\x9f\x57\x92\x6d\x71\xd9\x72\xa9\xa2\xde\x11\x25\x8c\xc1\xe7\x28\x59\x9c\x9f\xb3\x87\x24\x91\x84\x7e\x10\xc6\x7e\xfa\xef\x6b\x69\x6a\x03\x0f\xf0\x53\x3a\x58\x3b\xea\x1d\x04\xdf\x25\xf7\xee\xf3\xa1\x3b\x8e\x31\xaa\xd1\x33\x85\x7d\xf1\xb4\xe5\xff\xbd\xee\x37\xf4\x0f\x38\xd2\x24\xc7\x0a\xe0\x4e\xf3\x3b\x41\xb0\x2e\x71\x91\xa8\x66\x56\xb0\xd7\x2b\x2c\xbb\x53\xc4\x90\x8c\xa2\x06\xf7\x57\x34\xb2\x77\x08\x15\x4f\xcd\x8a\x97\x42\x9c\xfd\x1f\x2d\xa2\x42\x97\x78\x43\x80\x03\xf5\xb5\xb9\xc2\x1d\x9e\xd2\x3b\x8a\xd8\xa2\x28\xeb\x4f\x65\xc2\x4c\x1c\x59\x69\x9a\x5c\x90\xaf\xf7\x73\xe5\xc6\x76\xdb\x36\x2a\x19\x30\xba\x16\xab\xa7\x6e\xf8\xda\xa4\x2b\x3e\xb2\xcc\xc4\x5c\x93\x4d\x23\xd4\x92\x9a\x7a\xd9\xe3\xef\x46\x8b\x06\xa4\x99\x5c\x80\xdd\x23\x6a\x7b\xcf\x38\x79\xd8\xb7\x94\x67\xf7\x2b\x33\x84\xc1\x60\xcc\x18\x17\x14\xe9\x2f\x20\x35\xe7\xb9\x72\xa2\xcc\x52\x42\xd9\x32\x52\x5e\xae\x7c\x50\xbd\x26\x3b\x0f\xa0\x9c\xbd\x9d\x6f\x98\x4b\x9c\xf6\x15\x2d\x9a\x13\x3c\x27\x84\x32\x02\xd1\xe8\x7f\xa5\xa6\xe1\x23\x5d\x9c\x75\x6b\xb8\xe6\x8b\x05\xb9\x8d\xa5\x41\x95\x22\x3f\xdf\x02\x10\x25\x32\x50\x63\x3c\x11\xc5\xf6\x0b\x5e\x67\xd7\xee\xfc\xaa\x6c\x2d\xaa\x52\x31\x37"}, +{{0xda,0x01,0x32,0x21,0xb2,0xf5,0x88,0xaf,0x40,0xe2,0x11,0xa0,0xf9,0x75,0xd4,0x4f,0x9d,0x65,0x02,0x81,0x60,0x51,0x4c,0x39,0x61,0x89,0xf2,0x7c,0x7b,0x06,0x66,0xea,},{0x07,0x11,0x7c,0x6b,0x0d,0xb5,0xb6,0xfd,0xa1,0xed,0xc4,0x39,0x6c,0x47,0xc2,0x2b,0x54,0xee,0x0c,0xe5,0x37,0x5c,0x3e,0xc6,0x33,0xc8,0x3a,0xfc,0x53,0xad,0x6c,0xe4,},{0x10,0xcb,0x52,0xd6,0x10,0xe4,0xa8,0x1d,0x32,0x86,0x9b,0xff,0xce,0x38,0x07,0xe6,0x39,0x1f,0x78,0x2f,0xcd,0x53,0x8b,0x55,0x4d,0x09,0x03,0x7f,0xda,0x72,0x28,0x5b,0x96,0x62,0xb1,0xb1,0x10,0x7c,0x40,0x81,0x78,0xac,0x00,0x9f,0x05,0x25,0x96,0x73,0x88,0xa7,0xd8,0x5f,0xa1,0x23,0x59,0xd3,0xce,0x38,0x75,0x03,0x7d,0xcf,0x6a,0x04,},"\xbc\x93\xee\x1e\xc4\x72\x8a\xc6\x36\xa6\x24\x8f\xcc\x45\x51\xc9\xd1\x59\x80\xdb\x8e\x5f\x54\xb0\xef\x07\x5a\x71\x97\x0e\x17\x6a\x3c\xb9\x18\x2e\x32\xda\x7a\x8c\x2a\xc0\xcd\x7e\x59\x57\x74\x57\x5f\x9c\x83\x50\x6a\x60\x6f\xac\xe8\x95\x12\x13\x5d\x03\x2a\xb0\x5e\x39\xff\xf9\xc8\xca\x6c\x25\xcd\x5d\x78\xec\xc3\xac\x32\x32\x90\xc9\xc8\x16\x26\x73\x5e\x19\x0e\xb5\xae\x34\x5c\xa7\xa9\x58\x40\x9f\x77\x43\xb0\xb1\x61\x49\x16\x83\x22\x17\xc5\x7e\xee\x1b\x4f\x8e\x62\x2a\xc0\x52\xa9\x3d\xd5\xb3\x9d\x07\x61\xe4\x0e\x9f\xbd\x83\x96\xf6\x0a\x3b\xf6\x66\x0c\x5f\xa9\x9c\xd8\x13\x9f\x68\xcb\xe0\x89\x4e\x5c\x67\xe1\x68\xcc\x74\xb2\x72\x4e\x9d\x91\xd6\x00\x0a\x0c\xec\x58\x7a\x11\x46\x3f\x72\xee\x6e\xd2\x55\xbd\x87\xeb\x30\xfd\x45\x75\x96\xf6\x88\xca\x0e\xa7\x3f\x30\x49\x72\x38\xde\x21\xc9\x3f\xbb\x12\x94\xdb\x61\xe4\xa5\x60\x89\x10\x6d\x1c\xf7\xce\x5a\x65\xec\x3d\x12\x17\x0c\xe7\x84\x0f\x08\x8a\x8d\x0e\x3a\xef\x17\xe5\x31\xde\x47\x80\x03\x57\x02\x58\xe9\x27\xf1\x56\xe7\x96\x10\x65\xaf\xa6\x66\xaf\x38\x58\x2b\x35\x3c\xc4\x77\xba\x77\x5c\xae\x45\x94\x6d\x08\xdb\x75\x21\x59\x14\xda\x32\x61\xb6\x22\x94\xe9\x2a\xfb\x38\x14\x59\xc2\x1d\xda\x4e\xa6\xed\x79\x5f\x79\x25\x7c\x09\x4d\xd6\x08\xdc\x8e\x1b\x7c\x40\xcd\x29\xfe\xa2\x22\x08\x8f\x65\x69\x7e\xa8\x88\x95\xd1\x0a\xce\xa8\x79\x73\x60\xdc\xba\xce\xe2\x69\xc6\x06\x60\x0a\xdf\xfd\xcf\x9c\x7c\x38\x1d\x0a\xd6\x69\x69\x67\xd9\xff\x03\xe6\x1a\x24\x90\x65\x02\xb2\x95\xe7\x6f\x4d\x08\x75\x65\x5b\x01\xe6\xff\xca\xcc\x8e\xf0\x11\x29\xc7\x2a\x58\x46\xb6\x0e\xc8\x00\x17\x37\x4e\x75\xd3\x06\x40\x3d\x9e\xcc\xf2\x64\x95\xd2\x98\x12\x0a\x06\x33\x83\x5c\x5d\x1e\xff\x17\xc9\xc6\x24\x76\xf7\x52\xc8\x97\x10\xad\xfa\x4d\x51\x61\x7b\x59\x18\x17\x3c\xba\x72\x25\x40\xe3\x88\xff\xbf\xfb\x96\x68\x74\xdb\x00\x40\x4d\x06\xb0\xce\x11\x39\xba\x74\x14\x3c\x76\xb8\xf4\xd3\x3b\x21\x16\xe1\xcc\xe1\x75\x17\x3a\x96\xfc\x15\x1e\xa2\x39\xbf\xc2\x0d\x66\xfb\xb6\xf5\x2a\x66\x6c\x0e\x81\xcc\x2b\x80\x20\x91\x06\xe2\x48\x0e\x41\x11\xc7\x0e\x7b\xe4\xaa\xbb\x68\x42\x2f\x0b\x8c\x6b\xa1\x5c\x14\x2f\x82\xe6\xc7\xf3\x78\xd7\x80\x0a\x09\xea\xa4\xda\x25\x3c\x2f\xd9\x1e\x12\x63\xc6\xb6\x55\xbf\x70\x25\x5d\x7e\x3b\xb4\x77\x55\x23\xa0\xa9\xe7\xff\x03\x79\x7e\xe3\xff\xca\x8a\x50\xd1\x0f\x20\xd5\xe5\xa8\x89\xec\x5e\x33\x4e\xf2\x6c\xf7\x99\x8b\x08\x36\xf6\x56\x45\x68\x88\xe1\x37\xf3\x9d\x3e\x43\xe2\xce\x3c\x6e\xf5\x40\xd9\x5d\x9a\x20\xc4\x2c\xb8\xae\x2d\x9d\x0f\x25\xa8\x91\xc3\x63\xea\xd9\xcc\x42\x3f\x9a\x32\x3f\xe2\x32\x28\x1f\xb6\x7f\x5b\xe1\xc0\x78\x43\x61\x46\x04\x68\xa8\x7e\x95\xdf\xa3\x5d\x7f\x0f\xfa\x22\x11\xbe\x6b\x5f\xb3\x2d\x42\xba\x65\x18\xab\x6e\xa9\x37\x80\xf4\x31\xd3\x00\x67\x31\xbe\x44\x40\xe7\x12\x97\x4f\x74\xba\xea\x41\x9f\x40\x22\xfa\x25\x02\xe1\xb2\x39\x8e\x93\x86\x16\x7d\x93\xec\xa9\x2c\xa6\x0d\xd7\xd9\x1f\xe8\x23\x24\xf6\x82\xd9\x4a\xa7\xa8\x6a\xb0\x34\xf8\xa9\xe9\x52\xe8\xfc\x95\xbf\xf4\xdf\xed\x6a\x43\x31\x3a\xbb\x92\x40\x1b\x30\xc3\x3c\x79\xa7\xba\x3e\xfd\xbe\x16\x28\x04\x0f\xba\xf4\x43\xf3\xf9\x80\x84\x6f\xdb\x28\x3d\xcc\xd9\x3f\xab\x09\x70\x8b\x7d\x54\x86\x1d\x74\xb1\xfe\x8f\x10\x70\x1f\x21\x1b\xa3\xd3\x90\xe8\xa6\xae\x40\x77\x39\x64\x6a\x79\xa5\x83\x37\xa7\x17\xa8\x72\x00\x9c\x2d\xf6\x76\x1c\x24\x25\xa3\x2a\x00\x18\xaa\xf9\x64\x64\x70\xcb\xc8\x7c\x3a\x65\xc0\xe0\xef\xfb\xaa\x52\x8f\xe4\x78\x3c\x77\x2a\xb2\x66\xb8\xf2\x82\x68\xcf\x14\xaf\x23\x4b\x15\x81\x6d\x1a\x3a\x49\x1a\xf5\xf2\x97\xe3\x3d\x57\x29\x71\x5d\x51\x2c\x37\x3f\xef\x5e\xcc\x3f\x39\x54\xa6\x0a\x2a\x0f\x64\xd8\x29\x47\x41\x19\xca\x1a\x18\xf1\x05\x78\xd0\x4d\x63\x8d\x5e\xea\xfc\x37\x1a\x94\x6f\x6c\xe7\xef\xbd\x2a\xcc\xe3\x4e\x20\x44\x1c\xde\x9a\x37\xd5\xa8\x7d\xc6\x19\xb0\xa7\x27\x59\x6c\xd1\x2e\x15\xcd\x97\x84\xbb\x91\xf1\x39\x9a\x59\xfc\x0a\x7a\x4a\xf6\x8b\x0d\x57\x5d\x93\x38\x71\x72\x97\x33\x75\xc4\x65\xdf\x5d\x2d\x5e\x06\x1a\x2a\x9b\x23\xb4\x91\x5a\x0a\x8b\x8c\x1f\x09\x42\x09\x4a\xf7\x28\xc8\xc3\x11\x45\xfa\x7a\xaf\x74\xa2\x1a\x3b\x03\x2b\xb0\x9c\x39\x22\x05\xbf\x09\x5b\xda\x98\x6e\x5d\xd6\x62\x7c\x1e\x41\x7f\x65\x03\x26\xdf\xe3\xa9\xc9\x99\x4c\x6e\x0e\x01\x27\x6f\x91\xf2\x98\x7d\x2b\x85\xde\xda\x96\x54\x91"}, +{{0x5a,0x86,0x8f,0xb7,0x5e,0xa0,0x72,0x1f,0x7e,0x86,0xc7,0xbc,0x10,0x6d,0x74,0x13,0xc8,0xcf,0x4d,0x03,0x3c,0xe1,0x40,0x05,0xdf,0x23,0xce,0x4c,0x15,0x5b,0xbd,0x27,},{0x6d,0x1e,0x29,0xf3,0x9d,0xed,0xa2,0xbb,0xfb,0xb5,0x7c,0xb0,0x1c,0xb3,0x9e,0x58,0x80,0x82,0x78,0xe5,0x19,0x6a,0xda,0x1c,0x02,0x76,0x46,0xf2,0x04,0x87,0xd2,0x52,},{0x38,0xc4,0x8d,0xba,0x99,0xa6,0x52,0x4a,0x18,0x8d,0x5c,0xd7,0x8a,0x98,0xe6,0x77,0xdd,0x26,0x3e,0xf6,0xb4,0xdf,0x44,0x6b,0x31,0x0b,0x3d,0xd8,0x9c,0xaf,0xdd,0xb9,0xb1,0x7a,0x65,0xbb,0xa8,0xe1,0x39,0x68,0xbd,0xc2,0x5b,0x1d,0x84,0xb6,0xe2,0x43,0x6e,0xdf,0x31,0xaa,0x75,0x6e,0x3a,0x48,0x72,0x6d,0x6f,0x91,0xc8,0x08,0xee,0x0e,},"\xd5\xaa\x11\x82\x5b\x99\x44\x8c\x80\x63\x06\x23\xd8\xc7\x46\x01\x7c\xfe\x3d\xe6\xfa\x8a\x0c\x6e\xd6\x62\x71\x27\xcf\xc1\xf8\x4d\x4e\x0a\x54\xe6\xa7\xd9\x08\xd3\x71\x9f\x14\x21\xd1\xd4\xc7\x8b\x3c\xdd\x94\x76\x9a\xb6\x03\x3b\xce\x97\x9d\xd9\x0e\x10\x68\x02\xeb\xa9\xa0\x32\x95\xd4\x8f\x9b\x9a\x95\xd5\x7e\xe7\x74\x54\x02\xa4\x80\x23\xbf\x3b\xdd\xd5\xc6\xb9\x1c\x77\x3e\x49\x19\x13\xa3\x8a\xc3\x46\x26\x05\xcf\x28\x2d\xea\xc7\x57\x42\xfb\xd2\x75\x29\x27\x6e\x81\xdc\xce\x8d\xff\x96\x05\x03\x5e\x8c\xf0\x5d\xf6\xa4\x3d\xb1\x51\xf0\x41\x57\x65\xbc\xbd\x1f\x1b\xb6\x68\xad\x62\x73\xb8\x91\xc0\xdc\x4f\x3d\xba\x59\x0e\xa8\x2f\x83\x63\x76\x9b\x9c\x77\x51\x19\x47\x11\x73\x75\xdc\x49\x04\xd4\x8b\x88\xb6\x8a\x25\x5b\x28\x01\x1b\x11\x04\x81\x94\x09\x3e\x98\x20\x7a\xb1\xcf\x75\x6a\xb8\x33\x1f\x8d\x6f\x9d\x5b\xe2\xe1\x19\x05\x73\xe9\x5e\x71\x0f\x2a\x35\x01\xb5\x3a\xa0\x82\x5d\x6c\x12\xdc\xfb\x94\xac\x80\xdc\x10\x82\xcb\x4a\xd2\x62\xe6\xd4\x93\xad\xce\xb6\xbc\x19\x14\x5f\xbf\x73\x8d\xf7\x6f\x21\x34\xfa\x04\xcb\xbe\x44\xff\xc5\x5f\xfe\x5f\x9d\x3e\x9b\xeb\xd1\x59\xa0\x01\xaa\x9b\xf7\x88\x92\xa1\x65\x38\xa5\x20\x82\x3c\xde\x5d\x61\xe2\x9a\x56\xa7\x7a\xb9\x6e\x49\xe3\x00\xd9\x86\x59\x62\xc7\xe7\xfb\x8b\xcf\x5d\xe0\xb9\x38\x29\x7c\x3f\x4d\x6f\x60\x21\xe2\x4d\xfd\xad\x98\x61\x65\x2f\x34\x0f\x42\x1e\x7a\xf2\xc7\x1e\xd9\xa7\x15\x87\xfc\x75\x3b\x11\x55\x49\xb2\xf7\xf7\xcb\x29\x69\x0e\xa2\xb1\x58\xa9\x4c\xd2\xbc\x42\xe7\x06\x3d\x61\x9b\x93\x9d\x52\x3e\x3c\x23\x7e\xb1\xf4\x08\x10\xde\x0b\x44\xaa\x69\x37\x86\x3d\x62\x9e\xdd\x55\x75\xe6\xc0\x47\x52\x61\xb6\x27\x47\x30\x92\x77\x5c\x84\x36\x00\x11\xd5\x7c\x57\x20\x9c\x2e\x87\x5a\x3f\x89\x63\xe8\xb2\x41\xa7\xaa\x75\xef\x30\xc4\xa7\x18\xac\x4d\xd4\x66\xdc\x7a\x3e\x40\xe5\x87\x4f\x15\x7a\x84\x9e\xd3\xa3\xa9\xd4\xae\xb7\xd9\x4d\xf0\x9b\xb5\x5a\x0b\x2b\xc9\xf8\xb6\x95\xc3\x71\x79\x30\x23\x67\x60\x63\x67\xc5\xf3\x24\x82\x8c\xe7\x5a\x94\x4f\x50\x70\x3a\x47\x90\x6a\x80\x88\xf3\xa1\x1c\xfe\x4a\x85\x4e\x01\xf1\x74\x12\x52\xc4\x86\x33\x7d\x06\xb1\xcc\x6c\x6b\x9b\x12\x95\x43\x1e\xe0\x73\x59\x35\x7b\x3a\x78\xef\x50\x75\xb6\x5d\x7f\xed\x5e\xb7\x42\xe5\x10\x15\x98\x44\x4b\x46\x62\x3f\x89\xa3\x03\xac\xc1\x0c\x73\x24\x49\x51\x3b\x70\xdc\x45\x6a\x79\xd3\x7c\x48\xe5\xe7\x26\xc2\xf5\x58\xda\x0a\x1c\x46\xef\xbd\x2d\x92\x03\x26\xa6\x78\xb8\xa2\x2f\x09\x44\xbe\x4a\xf5\x5b\x6c\x71\xf4\x53\xfb\xae\x40\x0e\x6a\xcc\x04\xe0\xe9\x5c\xa2\x00\x16\x7e\x96\xee\x98\xea\x83\x93\x16\xda\x93\xa1\x2c\x2d\x76\xf1\x1a\xee\xbe\xb7\x8e\x65\xea\x48\xf7\xfe\xeb\xbb\x13\x7b\x2a\xc6\x7e\xae\xf0\x2a\x2d\x9e\x64\x71\xdd\x63\x4a\x03\x7d\x4f\x5d\x35\xa2\xf7\x8a\xf4\x1a\x8e\xa5\xaf\x5b\xc8\x15\x0a\x99\xed\x68\xa6\xa0\xcc\xff\x2b\x1d\x79\x65\xd8\xbc\x3e\xf9\x28\x5b\xa6\x42\x1d\x87\xc3\x3a\xad\x81\x03\xa5\x87\xbe\x01\x92\x68\x45\xbf\xbd\xdb\xaf\xc6\x9c\x4b\x92\x52\x88\x67\x20\xd4\x18\x50\x9f\x40\xf3\xdc\xf5\x57\x65\xdc\xcc\x3d\xee\xd8\x27\x72\x15\xe6\x9f\x05\x6b\xa3\x1b\x8a\x30\xb5\x00\x94\xea\x8f\x14\x47\x20\x76\x0c\x8f\x8c\x05\x5c\xf1\xa8\x69\x64\xff\xcb\xb8\xee\x1b\xb2\x18\x12\x76\xea\x99\xa7\xb8\xe7\x10\x67\xfa\x31\x0b\xa4\x47\x1e\x84\x27\x90\x37\xbc\x49\x2a\x55\xde\x20\x55\x48\xe7\x7b\x01\x45\x04\xee\x66\x64\xc4\x98\x8c\xbb\x9e\xd9\x1f\xf3\x2e\x22\x59\xed\x4c\xfd\x61\xa1\x97\xd0\xdb\xc3\x2c\x68\xf6\x54\x9c\x0d\x29\xfc\x45\xf3\x6a\xcb\x26\xb1\x64\xde\x97\xcc\xdc\x37\x90\x0d\x93\xcd\xbc\xf9\x68\x7e\xf5\x3f\x1f\x4d\xa1\xb1\xae\x42\x25\xb8\x84\x20\x9e\x81\xba\x43\x11\x52\x04\x77\xed\x42\x11\xb0\x92\x40\xbd\x7b\x82\x5e\x54\x73\x9f\xe2\x5d\x86\x24\xaf\x04\xb8\x6f\x6d\x11\x06\xd1\x81\x70\xe5\x06\x4d\x1a\x73\xc1\xfb\x1a\x27\xb2\x89\xa9\x48\xd7\x71\xa2\xf6\xb8\xb0\x9a\x63\x5d\xb9\x6c\x62\x51\xc3\x5a\x18\x76\xd3\x69\x62\x66\x99\x41\x6c\x0e\x40\x29\x8a\x68\x1f\xda\xf5\x25\x5f\x58\xc2\x55\x77\x59\xd8\xf5\xdf\x14\x8d\xec\x9d\xbe\x1c\xe6\xdf\x04\x1c\x36\xf8\x3e\x69\xcc\xfb\x4a\xac\xa5\xcb\x48\xfa\x6a\x85\xc8\xff\x66\x06\x15\x24\xd8\xb1\x1b\xd7\xff\xae\xd9\x9d\x0c\xd4\x5c\x42\x01\x0f\x21\xd3\x6c\xc3\x16\xca\x86\x09\x55\x63\x5b\xff\xaa\x7d\x9a\xac\x57\x2d\xcc\xf3\x15\x3d\x42\xee\x8a\x2b\x12\xba\xa5\x7c\x16\x0b\xd0\xad"}, +{{0xc5,0x4b,0xd3,0x43,0x1f,0x26,0x59,0x28,0x1d,0x31,0xe9,0x3b,0x30,0x78,0x76,0x68,0xbc,0xba,0x6e,0x5e,0xe4,0x7d,0xb4,0x6e,0x50,0xde,0xab,0xe3,0xf4,0x8c,0x9e,0xd8,},{0x1e,0xba,0x6e,0xb3,0xf7,0xf2,0x4c,0xdf,0x80,0xab,0xf8,0xa1,0x9d,0x30,0x8c,0x24,0xf1,0xe2,0x5b,0xa1,0x59,0x70,0xed,0xa7,0x11,0x67,0x07,0xb0,0xf1,0x2c,0xf9,0x32,},{0xdf,0x45,0x41,0xdf,0xf1,0xa9,0x79,0x7f,0xeb,0x61,0x7f,0x98,0xe4,0xb5,0x7a,0xa7,0x71,0x41,0x31,0xee,0x8f,0xf5,0x45,0xed,0x50,0x82,0xe3,0x56,0x8e,0xfd,0x1c,0x39,0x9c,0xdc,0x56,0xf5,0x58,0x29,0x91,0xeb,0x87,0x85,0xfb,0x33,0x86,0x4e,0xef,0x7f,0x55,0x3f,0x3e,0x24,0x82,0x62,0xed,0x54,0x8a,0x1a,0x68,0x88,0xf9,0x2e,0x92,0x0e,},"\x6f\x8c\xdd\x75\xe1\xb8\x56\xbb\xbe\x9c\xdc\x25\x53\x7f\xdf\x7e\x82\x36\xcb\x02\x9a\xcd\x39\x84\x49\x21\x10\xd0\xc3\x04\x41\xd4\x21\x84\xb5\xfb\x18\x3d\xa9\xf3\x14\x03\x78\xdf\xa7\xd7\x4c\xcc\x9e\xf5\x00\x19\x3c\xc9\x57\x9f\xff\xa6\x0b\xd2\xa8\xab\x9e\x09\x58\x15\x00\xcf\x06\xcd\x35\xab\xc1\x71\xd9\xd1\x2c\x65\x80\xd9\x68\x2f\x9f\x49\xfe\x36\xd0\xa3\x17\x72\x38\xfa\x50\xe7\xeb\x4c\x27\xe4\x60\xf5\xe4\x58\x0a\x56\x56\x8a\x19\xe0\x3d\x95\xb0\xff\x4f\x4a\x23\x18\x24\xcd\x2f\x34\x42\xe0\xba\x40\x0b\xc1\x1b\x7a\x98\x9d\x50\x1f\x5d\xf3\x5e\x43\x01\x50\x8f\x72\xa8\x52\x01\x4b\xfb\xf4\x00\x1e\x28\x09\x54\x73\xd9\x65\x9e\xed\x60\x67\xba\xf6\x8f\x92\xbe\xf3\x12\xc0\x9b\x19\xaa\xf7\xc4\xfb\xa3\xd9\x02\xb9\xf6\xcf\x95\x2e\xb9\xb9\xa5\x3c\xa8\xbc\xbd\x04\x2d\x84\x2e\x98\x53\xb6\x72\xa1\xd0\x09\xd8\x23\x83\x8b\xeb\xe5\x63\x7c\x4c\x07\xed\x1b\x19\x48\x55\x4b\x23\xb3\x2d\xe1\xd6\xc1\x16\xf9\x33\xb3\x54\xf2\x8b\xbb\x77\x9f\xa6\x54\x8c\x48\x29\x2b\x61\x2c\x7f\x55\x1a\x75\xfb\xc4\x6c\x02\x73\x6b\xf9\x9e\x9c\x8e\xad\x56\xf0\x5a\xb0\x42\x7a\x6e\xc6\x16\xe3\xdc\xc7\x75\x7e\xfd\xb7\x62\x8d\x4e\x96\x32\x5f\xe0\xae\x25\x4c\xef\x5c\xb7\xa7\x04\xb3\x5a\x92\x0c\xb3\xfa\x2a\x03\xe9\x61\xda\xf3\x71\x82\x1b\xe0\xb3\x0f\x19\xae\x49\x52\x44\x1e\x08\xa7\xd2\x2f\x54\x31\x39\x0a\x5b\xe8\x09\x7f\xd5\x79\x7a\x1a\x62\x97\x66\x4d\xa4\x2c\x20\x08\xd0\x32\x10\x60\xeb\xe3\x18\x1e\xb7\x95\xa7\x28\x92\x58\x08\xda\x78\x67\x29\x3b\x72\x08\xf3\x77\xd3\xa7\x71\x18\x5e\x6d\x2c\x1c\x8c\xe1\x83\x76\xfe\x3c\x0c\x14\x58\xc7\xf5\xbe\x34\xf4\x28\xa0\xd5\x75\x93\x10\x74\xc9\x7c\xbf\xce\x8a\xd8\x13\x13\xec\xca\x73\xa9\xf3\xdb\x43\x4f\xba\xd4\xbb\xbf\xf5\x02\xbf\x72\x97\xe1\x7a\x97\xa8\x86\x42\x11\xe6\x78\x9b\xa1\x92\x03\x6e\xa5\x9a\x34\xd8\x4f\xf2\xa1\x11\x07\x4c\x3f\x23\x73\xb1\x01\x11\xb5\xda\xa7\x89\x56\x0c\xb3\x54\x90\x95\x4c\x88\xea\x00\xc4\x10\xdf\x85\x0a\xd0\x0c\xae\x2f\x28\xe7\x19\xfb\x06\x71\x69\x88\xa9\xbb\x0b\xfc\x6c\x98\x9d\x58\x7e\x56\x85\xae\x88\x3c\x2c\x2e\x74\xdd\xbf\x91\x5c\x98\x56\xaa\xe8\xf3\x28\x8f\xc6\x25\xbf\xb2\xfe\x26\x8d\x74\xf5\x9f\x8b\x7d\x83\x63\x74\x97\x69\x16\x90\x07\xd5\xe6\x7b\x7d\x0b\x8c\x8f\x5a\x9d\x9f\x9c\x7b\x74\x5c\x0a\x42\x94\x76\x2c\xbe\xca\x42\xd5\x38\x49\x61\xe9\x21\xa7\xef\xb6\x5d\xa8\xd1\xe0\x3b\x67\x45\xcd\xf3\x08\x09\x7f\xb1\x3d\x64\xfd\x2f\x8c\x10\xfa\x95\x09\xeb\x2d\x91\x38\x7f\x00\x64\x5c\xa7\xd0\x48\x3b\x2c\xd1\x4c\x20\x6b\x8d\x7a\xe0\xa3\xfb\x7c\x09\xbc\x68\x43\xd1\x02\xad\xcd\xa1\x9f\x8b\xbd\x85\x1e\xb6\x83\xc4\x43\x5c\xeb\x4b\x3d\x23\xd3\x8f\x56\xd4\xd1\x11\x4e\xef\x0f\xc6\xf2\x4d\xf5\x27\x70\xd8\xf1\xf3\xf8\x2f\x47\x20\xe8\x92\xb3\x15\x24\x4e\xf5\x6c\x36\xb2\x3f\xcd\x40\x79\x78\x52\x41\x40\x38\x2e\x11\x74\x0f\xd4\x6f\xe4\x29\x99\x23\xf5\x2b\x88\xb4\xa9\xcf\xf4\xb2\xb4\xb2\x3a\x2e\x76\x0a\xd8\x1c\x78\xba\x87\x69\x31\xd9\xaa\xa4\xbe\xed\x40\xfb\x10\xa7\x99\xeb\x30\xd3\x7f\x75\x47\x78\xba\xc8\x5b\xf0\x63\x1d\x85\x2b\xe7\xd7\x4a\x64\x31\xf3\x84\xa4\x02\x5c\x10\x91\x42\x1d\x67\xa4\xe9\xc9\x4c\x1b\xe3\x69\x0c\x6b\xf8\x1d\x06\xbd\xaf\x32\xfe\xab\xba\xf1\xdc\x26\x3f\x27\x3a\x0b\x9e\xd6\x54\x60\xba\xef\xce\xfc\xf6\xac\xcc\xda\x0e\xdd\x23\xdf\x9e\x05\x12\x8e\x29\xd6\x61\xc4\xb4\x4b\xd9\x2d\x64\x0f\xaa\x85\x3a\xfd\x83\x70\xe5\x63\xb4\x0a\xe0\x14\x9a\x14\x28\xe0\x6e\x3d\xd8\xe6\x6b\x79\xda\x21\xcc\x75\x3d\xdc\x47\x6e\x3d\x76\xe2\xf3\x6f\x2b\x6c\x6b\xc1\xb6\x50\x87\xd5\xf8\x6c\x8a\xc3\x54\x71\x1a\x8c\x08\xf3\x48\x6e\x47\x9d\x6a\xe9\x43\xf8\x84\x63\x32\xd4\xe5\xb4\xbb\x2e\x82\x57\xe3\x08\x3d\xf4\xf8\x1d\xd4\xf0\xc1\xee\x1d\x97\x18\x21\x66\x16\x1a\x18\x59\x7e\xe0\xb9\x59\xde\x1c\x45\x59\x1a\xbf\x7c\x51\x03\x3d\x7c\x66\x35\x2d\xee\xb6\x82\xe7\x77\xae\xae\x2f\xa8\xd3\xa7\x7f\x47\x0d\xb7\x8d\xdc\x1b\x1f\xc8\x28\x40\xc4\x06\x57\x76\xd9\xbf\xca\x9d\x39\x2d\x92\x88\xee\x91\x32\xaa\x3e\x4f\x2d\x19\xd0\xd9\x3e\x01\xb6\x66\xf3\x64\x7a\xba\xf2\x25\xc2\x92\x41\x9c\x8a\x82\xeb\xa3\xe1\x1a\xb1\x03\x84\x6f\xcd\x49\x35\xf4\x12\x41\x47\x7c\x0f\x15\x2b\x79\x65\xad\x54\xbb\x72\xbc\x3d\xe2\xe0\xb7\x9d\x62\x25\xe8\xfa\x7a\x62\x86\xb5\xfc\xcb\xb3\x58\x22\xe8\x0c\x8b\xfe\xa7\x4c\xb4\x8a\x22\xd2\x41\x38\x53\x95\xc2"}, +{{0xea,0x60,0xda,0x01,0x79,0xbc,0xaf,0x6b,0x21,0x81,0x42,0xb1,0x11,0x90,0x46,0xff,0xe6,0xd8,0x5a,0x74,0x1b,0x0d,0x16,0x62,0x30,0xbc,0x6d,0xe3,0x30,0x4f,0x67,0x73,},{0x50,0x6b,0x2e,0xbb,0x49,0xbd,0x9b,0x9f,0xf6,0x6e,0x6b,0x7b,0x1f,0xab,0x96,0x68,0xcb,0x18,0x1b,0x4f,0xb5,0xe4,0x34,0x3d,0xdd,0xd3,0xf8,0xa9,0xd7,0x02,0x03,0x1c,},{0x27,0xfb,0x6b,0x5f,0x06,0x52,0x8a,0x64,0x19,0x8a,0x3e,0x7d,0x67,0xc7,0x38,0x84,0x0a,0x8c,0xff,0x4b,0x48,0x2b,0x4d,0x52,0x4b,0x12,0x2d,0x17,0xd2,0xae,0xbc,0xc0,0x38,0x9b,0xe2,0xc6,0xe2,0x8e,0x2c,0xdf,0xc4,0x84,0xc1,0x8d,0xe4,0x25,0xdb,0x56,0xcd,0xfa,0x56,0x1c,0x50,0x7c,0xd9,0x70,0x60,0x2d,0x3a,0x38,0x5d,0x3a,0xea,0x0f,},"\x61\x2d\x6e\xf6\xe4\x34\x9f\xfa\xe5\x16\xe9\x83\xe8\xfa\x7b\x52\xd9\xfd\x13\x42\x82\x24\x0d\x95\x14\x38\x24\xbd\x4a\xae\x03\x23\x4b\x76\xa8\xcd\x6d\x40\x68\xcf\x00\x9e\x48\x1c\x26\x85\x36\x1c\x75\x50\x42\xc4\xe6\xab\x87\x03\xec\xbf\x8f\x02\x0c\xf5\x73\x9a\x4c\x2a\x03\xc3\x73\x1e\x9c\xf7\x5a\xee\x25\x96\x61\x53\xb9\x71\x15\x15\xc6\xc3\x9a\xfa\x95\xf2\x21\xac\x33\x95\xb0\x89\xc9\x7a\xc9\xb5\x14\xe1\x7d\x55\xf7\x96\xa3\xec\xc1\x35\xfa\xaa\xee\x90\x7a\xab\x10\x29\x64\x7b\x48\xac\x81\x74\x9b\xab\x26\x62\x7c\xf7\x09\x5d\x74\xc2\xfc\xee\x35\x67\x1c\x8b\xb4\x60\x53\xf5\x15\x1b\x0c\x2e\x5d\xab\xe0\xf2\xd6\xaa\x20\x41\x33\x05\x02\x0b\x2a\xfd\x9e\xe3\x38\x7b\x2c\x9e\xd0\xbc\x3f\xe2\x90\x2a\xf4\x10\x0c\xec\x23\x32\x7b\x0f\x1e\x4c\xa3\x9e\xf6\xea\xf6\xfd\xf5\xd5\xac\xf9\x3f\xc8\x68\x53\x6d\x8c\xba\x40\x17\x69\x32\x9f\xbe\x93\xef\xfc\x7e\xe6\xbf\x93\xa6\xe5\x88\xbd\x55\x1e\xaa\x51\x28\x53\x95\x2c\x81\xb2\x45\xe5\xd2\x29\xd2\x94\xe4\x13\x70\xb8\x67\x80\x86\x67\x88\x7a\x6f\x9e\xba\x2a\x8d\x56\xa7\xa7\x04\xe6\x6b\x1c\x02\xf9\x6e\x73\x89\x5f\x48\x3e\x44\xa5\xc5\x66\xcb\x1a\xf2\x65\x73\xbf\xe2\xaf\xce\x06\xb1\xfb\x58\x77\xe5\x1e\xf3\x12\x6a\x3f\x21\x0f\xbf\x21\x3e\xd6\x5d\x5c\xa4\x6c\x46\xce\x4a\xa9\x45\xbd\x8c\xa6\x11\xe3\x83\x62\x50\xf5\x64\xf7\xea\x35\x42\x39\x82\xf9\x70\x5f\xcd\x6b\xef\x46\xae\x16\xcb\x0f\x6b\xc9\x12\xc3\xf2\x86\x42\xb8\xd8\x77\x75\xb8\x18\xe4\xe4\xe8\x06\x11\x67\x89\x9b\xd2\x7a\x7e\x2f\xb8\x18\x7e\xe9\x91\x7d\x2d\x58\x6b\xf9\xd4\x99\xe8\xfa\xbc\xa8\x3d\xdf\x58\xc7\x43\x7e\xaa\xce\xc4\xf4\x44\xfb\x2b\xf7\x45\xdc\xcd\x8c\xae\x38\x94\x45\x71\xde\xde\x20\x37\xdc\x41\xf0\x81\x8a\x3d\x91\xe3\x02\x0a\x72\x74\xc6\x67\x42\x47\x87\x60\x83\xd0\xe3\x97\x46\xc9\x68\x40\x61\xbf\x74\xad\x58\x84\x36\xce\x1b\x76\x3d\xbf\x4b\xfc\xf8\xde\x6e\x35\xc5\xa7\x62\x66\x75\xc1\x27\x29\x2b\x21\xdf\x3c\x16\xf8\x10\x63\x32\x2a\x75\xf3\x43\x88\x86\xf1\xf0\xce\xbf\xc1\xa9\x6f\x41\x38\x4c\xbd\xd8\x61\xb0\x4f\x51\x9f\xf6\xa9\x34\x4d\x94\xf3\xd3\xa0\xab\xa8\x40\x9d\xfc\xf1\x8d\x01\xf2\xb5\xb4\x55\x17\x16\x39\xee\xa7\x7d\xee\x70\x6e\xa8\x3d\xcd\x2b\x8b\x1f\xc5\xec\x0d\x74\x07\x61\xa5\xf0\x5f\x7e\xc8\xd8\x7a\xd1\xf2\x92\xa5\x0c\x8b\xae\x0a\xd3\x2b\x03\x41\x9a\x95\x0d\x9f\xe3\xb3\xec\xc4\xd8\xd3\xaa\x95\xe0\x2b\x51\xb1\x83\x1d\x83\xea\xde\xaa\x44\x23\x86\x35\xf9\xc6\x5e\xfe\x2f\x67\x44\xa7\x0b\x9a\xe4\x1e\xf1\x5d\x97\x90\x8c\x05\x33\x93\x44\x12\xf7\x95\x83\xd0\xe9\xb3\xd7\x06\xa1\x28\xe8\x8f\xb5\x1e\xed\xb6\x5e\x46\xd8\xa2\xb3\x8b\xbd\xd6\x45\x55\x54\x96\x7a\x8d\xc0\xc6\x8b\xdd\xfe\xae\x0f\x8f\x72\xf0\xb8\x86\xc3\xc7\x41\xfa\xc4\xf9\x1e\x5c\x49\x1d\xba\xe9\xda\x45\x94\x83\x6c\xf1\xd9\xfb\x6e\xe1\x30\x02\x50\x89\xae\xd3\x50\xef\x24\x7b\xc9\x88\x7a\x20\x50\x15\x9d\xde\xd1\x42\x8f\xfd\x9b\x07\xb9\xec\x2e\x3d\x4b\xbd\xc2\xdd\xb5\x4e\x87\x3b\x63\xf2\x47\x52\x33\xe1\x91\x33\xa1\x4b\x66\x58\x50\x94\x57\x00\x81\x86\xd6\x22\x59\x95\xa9\x67\x26\xb5\x29\xf4\x42\x81\xaa\x24\xfe\xfd\x1c\xff\x8f\x81\x5d\x93\xa5\x98\x69\x31\x66\x22\x90\xb3\xee\x16\x83\x3c\x60\xf0\xaf\xce\xf2\xcb\xc0\x00\x62\x3f\x39\x31\x90\x9c\xa9\x76\xa0\x94\xe2\xb0\xfd\xb7\xdc\xf7\xc4\x85\xe1\x49\x88\xa3\x6f\x19\xb6\x64\x25\x38\x5f\x56\x32\xce\xf6\x5d\x1d\x34\x14\x62\x3a\xe3\xee\x81\x6e\x76\x3a\x5f\x60\x64\x66\x62\x2b\xe6\x60\x21\x14\x50\x29\x51\xcf\x0c\x09\x7c\x16\x48\xa7\x2e\x2c\x43\xd9\xaf\xa9\x68\x9f\x2c\x3c\xfe\x02\x6c\xdc\xe3\xbd\x1b\xf9\xeb\xf7\x77\x56\x2e\xcd\x8f\xf1\xb0\xd7\x75\x30\x6d\x90\x04\x43\xf3\x0a\x84\x33\x10\xb8\xde\x6a\x38\xff\x10\x8b\x72\x39\x13\xd7\x89\x9b\x9f\xbe\x7c\x3d\x76\x6e\xf8\xbd\xfb\x6d\x8b\x0b\x52\x95\x6c\xb1\xce\xc9\x93\x6d\x70\xb4\x87\xc0\x14\x40\xa8\x42\xb2\xfa\xbe\x38\xe7\xb8\x85\x1a\x38\x7d\x35\x8b\xe7\xef\x12\xa7\xe4\xf2\xb5\x27\xe8\x30\x90\xd6\x7e\xb0\x13\xc9\xc2\xcf\xd3\xde\x5a\x1a\x3f\x99\x74\x8a\x41\xf4\x81\x9d\x90\x36\xe5\x00\xc5\x04\xc9\x88\xbf\xd2\x4f\x61\x7d\x6e\xbd\xca\xb2\xdd\xea\xa6\x15\x79\x41\x4f\x36\x0b\x46\x9a\x33\xa6\xde\xd9\x6b\xa1\xd8\xc1\x40\xc4\xff\xc9\x49\x90\xd8\xad\xf7\x8c\xd3\x87\x80\xbd\x68\x66\x3d\x1a\x0e\xe3\x3f\x53\x7c\xdf\x89\x2d\x56\x2e\x82\xdc\xd1\xd9\x12\xca\xd3\x8d\x65\x56\x7d\x29\x14\x06"}, +{{0xb6,0x2c,0x24,0x18,0x78,0x27,0x35,0x13,0xe0,0xbf,0x6f,0x33,0xd2,0x10,0x43,0x65,0xb2,0xce,0x9c,0x5a,0x1b,0x78,0x60,0x58,0xe9,0xc5,0xb4,0xd1,0xd1,0x92,0xf8,0x7f,},{0xbb,0xf6,0xfc,0x51,0x98,0xf3,0xfb,0xa5,0xab,0x00,0x7f,0x8a,0x63,0x2d,0x28,0xd1,0xaf,0x86,0x5d,0x29,0x0f,0xa0,0xa9,0x0f,0xaa,0x9a,0x9b,0x5b,0x9c,0x13,0xf3,0xfb,},{0xc5,0x90,0x39,0x58,0x7b,0x38,0xdc,0x14,0x1e,0x05,0x5a,0x93,0x85,0x01,0x04,0xd6,0x29,0xe3,0x80,0x70,0x5b,0x8f,0xc9,0x18,0x84,0x7c,0x5e,0x2a,0x35,0x2d,0xa3,0xa0,0x2f,0xce,0x7f,0x71,0x99,0xf4,0xae,0x2b,0x1e,0x2a,0x59,0x48,0x34,0x18,0x93,0x2e,0x18,0x5f,0x7e,0x45,0xb5,0x05,0x0c,0x64,0x2c,0xec,0xc7,0xe7,0x81,0x99,0x85,0x07,},"\x26\xa3\xc2\x6a\x5a\x18\x9c\xad\x40\x7c\xba\xa3\xa6\x86\x7a\xc0\xa2\x60\x88\xc7\x5f\x9d\x0f\xa1\x9b\xd5\x02\x74\xce\xc5\x75\x5a\x49\x71\x09\xa4\x73\x28\x4d\x6f\xc8\x1a\xd4\xb9\xec\x29\xfa\x7e\xc9\x76\x4f\xd3\x09\x9f\x06\x0e\x36\x83\x65\x52\xff\x24\x13\xe3\xd5\x09\x5f\xe0\xb1\xa8\xbf\xcf\x67\xee\x06\xaa\x90\x32\xe7\xbb\x32\x49\x69\x80\x47\x71\x4d\x28\x14\x15\x27\x3c\x98\x34\xad\x9e\xb6\x65\xa7\xd9\x72\x20\xe7\x2d\x9c\xa7\x3f\x31\xaf\xa7\x73\x86\x75\xba\x31\x62\xef\xef\xe7\x47\x9a\x5b\xc4\xbc\xe2\xe8\xb7\xaf\x47\x41\xd7\x03\xdc\x9b\xbd\x60\xb4\xcf\x4b\x90\x87\xf6\xcf\x86\xcf\x53\xae\xd0\x2b\xf4\xca\x6a\x18\xf6\x07\xcb\x52\xa3\x03\xd7\x8e\x85\xad\x88\xfd\xfc\x86\xdc\xb7\x18\x77\x27\xb0\x3b\xe2\x27\x74\x5b\xea\x74\x4f\xd0\x06\x52\x5b\xc5\x9a\x4d\xdd\xab\x91\x5c\xef\x40\xa8\xf3\x08\x02\x91\x3b\x79\x13\xea\xf9\x74\x33\x65\x52\xe2\xf1\x45\x6a\xd8\x03\xdc\x58\xc9\xb4\xb1\x8e\xfa\xf7\xf7\xe3\x57\xe2\xcd\x77\xd1\x38\xd9\x00\x80\xe2\x96\xd1\x36\x4a\x2f\x32\x4d\x3e\x0d\x6e\xdc\x20\xb8\xbd\xaa\x9d\x2e\x87\x1f\x5e\x7b\x05\x1f\xb6\xfc\xdb\x55\x95\xf2\x1d\x3f\x8d\xe2\x9f\xb7\x86\x78\xfa\x47\x9e\xaa\x32\x57\x9c\x78\x4d\x51\x3a\xc5\xf8\x36\xd9\x54\xd0\xd3\xfc\x0e\x5f\xc8\xa6\xee\xab\x90\x20\x2b\x4c\x4a\x2b\xec\x24\xcf\x63\xea\x67\xc4\x70\x09\x62\x18\xcd\x43\x1e\x88\x31\x05\xfc\x9c\x27\xf9\xea\x77\xc1\x8e\xda\x69\xbc\x00\xa2\x24\x2b\xd4\x20\xf0\x95\xc9\xb9\xa9\x2d\x95\x6c\xcc\x5a\x85\x72\xb0\x57\xa7\xfe\x17\x3e\xeb\x2a\x31\x66\xcb\x20\x89\xd1\x13\xa8\x16\x46\x2b\x25\x80\x5b\x8a\xba\xff\x5b\x0b\x22\x87\xc5\x08\xec\x2b\x8c\x34\xb2\x19\x5c\x33\x28\x70\xd3\xcc\x39\x60\x17\xa1\x6b\x9e\x0d\xa6\x18\x2d\x07\x1d\x3b\xf3\x63\xd3\xf1\xe7\xb7\xda\x11\xd7\x11\x25\x0a\x58\xaf\xd7\x4e\xd3\xe3\x15\x8d\x47\x18\xba\xd4\xd2\x74\xbb\x34\x44\xcf\xc3\x18\x07\x4b\x53\xbe\xba\x44\xa2\xa3\x4f\xf8\xeb\x72\x6e\x4a\x1d\xaa\x91\x10\x51\x62\x16\x51\x89\x8b\x88\x71\x69\xf6\x2b\x9c\x0f\x40\x20\x48\x3e\xf5\x44\xf8\xf5\x72\xfa\x6a\x66\x40\xa4\xcf\xfc\xe9\x76\xcb\x70\x24\xf8\x47\xbd\xc9\x5d\x1d\x7c\xe6\x53\x50\x5d\xeb\xfc\x69\x88\xed\x28\x9d\xd4\x7a\x9e\xb2\x61\x25\x9e\x3e\x65\xe4\x5f\xc9\xd7\x14\x94\x69\x35\xcd\x8e\xa1\x3b\xc6\xdb\x5e\xaa\xb9\xe8\xb1\x0d\xae\x0f\xdd\x69\x79\xc2\x03\x5c\xfb\x80\x98\x25\x2f\x22\x05\x44\x3b\x80\x88\x16\xbf\x77\x87\xb7\xf1\xe7\x8b\xc9\x8a\x72\x85\xe7\x33\xd4\x5f\xc4\x61\x0c\x20\x97\x7c\xa3\x22\x98\x89\xbb\x8c\xd2\xb6\x94\xce\x9e\x3f\xe7\x83\x03\xaf\x83\xe1\x06\x42\x25\x42\xfb\x79\x61\xd3\x2e\xb1\xd2\xc5\xfb\xe6\x07\x51\x67\x4b\x07\x47\x73\xee\x06\x16\xe0\x29\x73\xf6\xa7\x4a\x3a\xe4\x66\x4a\x26\x50\x91\x5a\x3e\x10\x49\x3b\x9e\x66\xa3\x9f\xa5\xc8\x9c\x61\xd4\x47\x35\xf1\x07\xd3\x37\x57\xae\x67\x9b\x43\xa8\xd4\x3a\x01\x75\x7a\xe1\xf3\x27\x9e\x86\x24\x42\xe1\x50\x71\x55\x50\xee\x82\xe4\x9c\x0d\x49\x43\xfa\xf1\x3f\x22\x79\x1f\x0e\x66\xf2\x4a\xc5\x0a\xb3\xc0\x03\x85\x2b\x21\xe1\x5b\x2f\x00\x6e\xdc\x2c\xd6\xa8\x79\xc4\x76\xab\x5b\x35\x2e\xb1\x09\x9d\xad\x4c\x50\x37\x24\x00\xfa\xa5\x49\x8d\x78\xc6\xb8\x57\x03\x4c\x25\xca\xf7\xb9\x33\xfa\xf6\xbd\x7c\x59\xfa\x3d\xa5\x73\x97\xb6\x03\xde\x9c\xb9\xd8\x0e\x51\xf7\x99\x7b\xaa\x46\x2a\xcd\x53\x7e\x2c\x41\x94\xc7\x6c\x7e\x0b\xe6\x51\x2b\xce\x4d\x63\x66\x0b\x36\xc7\xcc\x46\x63\x1f\xb9\x67\x1a\xd8\xc5\xd2\x8e\x2f\x2e\xe2\xed\xce\x81\x95\x44\x21\xb8\xa3\xd9\xff\x6f\x66\x69\x9f\x4b\xce\x88\xbc\xb8\xef\x19\x2c\x26\x2a\x74\xab\x7e\x19\x1e\xee\x91\x01\xa2\x8d\x4b\x66\x28\x2b\x51\x22\x09\x3d\x14\x1c\x64\x96\xc7\xab\xa4\xd3\x52\xe4\x72\xee\x74\x40\xe0\x5a\xf6\x0d\xa0\xcf\xc9\x3e\x30\x36\x42\xba\x8f\xb8\xe5\xc5\x68\x68\x7a\xbd\x63\xaf\xb3\xed\x6a\x32\xb6\xda\xe5\x6a\x7e\x5d\x73\xde\xba\xf4\x1d\x35\xca\x36\xad\xb9\x7a\x22\xc0\xad\xbe\x71\x8b\xec\x1f\xa5\x19\x98\xde\x9b\x4b\x96\xa7\x9c\x5b\x96\x55\xb0\x16\x5d\x5e\x1b\x9a\x8c\xc5\x52\xe8\xc9\x32\x9e\xde\x58\xdf\x74\xc6\x7b\x2b\xa1\xa8\x42\xfd\x3e\x81\x58\xc1\xfe\xa3\xa9\x9b\x56\xa2\xc2\xa9\x62\x07\x85\x3d\x26\x02\x2c\xec\x17\x0d\x7e\x79\x94\x4d\x2f\x56\xaa\xb1\xf1\x91\xbf\xd4\x8d\x72\x54\x90\xca\x82\xb8\xd9\x06\xf0\x68\x0e\x69\xee\xb9\x57\x57\x74\xfb\x9d\x60\x45\x13\xfb\xc2\x6f\x5d\x30\x3b\x68\x85\xca\xc0\xbf\x8e\xfe\xe0\x53\x8f\x92"}, +{{0x0f,0x77,0xf7,0x7a,0x1c,0x7e,0x04,0xbd,0xa8,0xe5,0x34,0xf4,0xe3,0xef,0xf9,0xa2,0x38,0xcc,0x14,0x87,0x6b,0x7e,0x3e,0xca,0x8b,0xed,0xe1,0x92,0x3a,0x33,0x64,0x06,},{0x10,0x45,0xea,0x9f,0xe2,0x14,0x58,0x3a,0x0c,0xdb,0xc4,0x94,0x93,0x2b,0xc4,0x4a,0xfe,0xeb,0x08,0x0b,0xec,0x48,0x5c,0xc2,0x34,0xfd,0xdc,0xff,0x13,0x9c,0xce,0x00,},{0xb2,0x0b,0x9c,0x42,0x46,0xf0,0xd2,0x97,0x01,0x38,0xaf,0x7d,0xc9,0xaf,0x62,0x9b,0x68,0xfb,0xc3,0x7d,0xf8,0x7a,0xfd,0xca,0xdc,0xb5,0x45,0xc1,0x76,0x83,0x76,0xa0,0x9c,0x3b,0xab,0xc3,0xeb,0x1a,0xf3,0xb7,0x51,0x98,0x52,0xf7,0x5f,0xab,0x1c,0x9c,0x11,0x9c,0x66,0x2c,0x58,0x77,0xfb,0x2f,0x72,0x99,0xca,0xb5,0x7f,0xad,0x3d,0x0e,},"\x0e\xcb\x74\x6d\xbd\xb0\x16\x14\x21\xaf\xeb\x7a\xde\xa7\xa3\x7c\x2e\xa4\x40\x8a\x59\x2c\x9d\x78\x1e\xd6\xac\x6f\x4e\xe5\xcc\x65\xd5\x27\x0e\x4c\xf2\x76\x32\xf7\xc5\xc1\x33\xd4\x39\xb7\x8d\x1f\x71\xaa\x6d\xd8\x07\x13\xd9\x0b\x15\x1e\x19\x12\x1b\xfa\x87\x71\x0e\x84\xa4\x85\x0a\x3b\x5b\x02\x65\xba\x26\x03\xd0\x71\x6e\x9b\x7e\x11\x22\x10\x9c\x39\xc6\xf1\x02\x7f\xce\x18\x79\x8c\xbb\x4f\x6b\xc5\xe4\xd7\xac\xa4\x70\x46\x90\xf5\xc9\x81\x51\x08\x71\xc3\x13\x59\x57\x98\x33\x86\x81\x10\x7f\x2b\x57\x94\xd4\x6f\x6e\x0b\xde\x2c\xd0\x64\xb3\xb1\xfc\x00\xca\x47\x18\x8b\xbb\xc1\xf4\xa0\xce\x30\x5c\xc6\xd8\xa8\x96\x92\x0e\xb9\xeb\xae\x57\x9f\xd3\x38\x5f\x8f\x1f\x35\x97\x62\x88\xf4\xc5\x8f\xfc\x47\x60\xf3\x59\xb0\x03\xc8\x72\xe9\xa2\x40\x55\x35\x5e\xa9\x58\x5e\x95\x10\x69\xdc\xa2\x5f\xd0\xcc\x0b\x9d\xb5\x2a\xae\xaf\x19\xd4\x3f\x2e\xab\x4f\x83\x56\x03\xad\x12\xd2\xdc\x49\xb3\x10\x25\x6b\x94\xbe\xd5\x48\x96\xa1\x6b\x69\xb0\x9c\xb4\xc8\xff\x5c\x23\xcc\xe5\x59\x3d\x87\xad\xe2\xa8\x2a\xda\x50\x85\x9e\x15\x44\xc1\x86\x18\xa6\x5c\x00\x7e\xf4\x24\xc9\x85\x4a\x17\x5b\x6e\x6c\x0e\x64\xb2\xc8\xeb\x8a\xd4\xd2\x8b\x97\x7d\x68\xe7\x81\x69\x91\x51\x98\x97\x53\x94\xd3\xb9\xb2\x69\xca\xb0\xd3\x26\x1b\x2b\x56\xcd\x2c\xc4\xbd\xdb\xd4\xf1\x43\x9e\x0d\xbe\x2c\x9b\x3f\x3f\x75\x14\xed\xac\x5e\xbb\x46\x22\xb9\x2a\x69\xa8\x40\xa9\x02\x85\x50\xb2\x21\xdb\x59\xdd\xfb\x00\x13\x96\xf8\x63\x92\xa1\x7f\x08\xcc\xb1\x94\xcd\x9e\x1a\x00\x81\xd7\xdd\x9c\xca\x23\x57\xfe\xb8\xb7\x95\xe5\x17\x02\x9f\x79\xc8\x2a\x3b\xe6\xf9\xa0\x31\xdd\x1a\xf1\xe7\x9e\x49\x82\xbf\x8e\x76\xb3\x10\xf9\xd3\x55\xef\xcd\x5b\x1e\xfa\x9f\x35\x9c\x17\xcf\x3b\x51\x0d\x51\x3e\x8c\xd5\x78\x6a\x0d\x34\x45\xdc\x59\xa8\x43\x3a\x46\x48\x86\x87\xb0\xf5\x8b\x1b\xd6\x56\x7c\x2a\xf4\x87\x3b\x51\xfc\x84\x5e\x76\x7e\x24\x30\x05\x19\x2f\x8f\x06\x74\xf2\x81\x26\x5a\x55\xd7\x6c\xea\x32\x22\x60\xc9\x32\xce\xa6\x71\x7a\xdb\x98\xa2\xdd\xa8\xc6\x98\xe2\xe8\x92\x55\xfe\xb7\x7d\xa7\x64\x81\x67\xbc\x1e\x58\x87\x7f\xeb\x72\xd1\xd1\x4b\x0c\x30\x4f\x07\x37\x2d\x95\x56\x75\x23\x7c\x49\xf7\xa6\xdb\xc9\x15\xe6\x81\x4a\xba\xe6\xcc\xe4\xca\xf9\xf4\x80\x87\xe9\xdf\xb2\x82\xd8\xf3\x40\x37\x7c\x1e\x29\xc6\x73\x1c\xcc\x26\x67\xda\x66\x95\xb7\x12\xbe\x03\x12\xd8\x65\x11\x19\x34\xf1\x68\xd5\x54\x43\x65\xdd\xae\x27\xab\xc6\x4a\xef\xbc\xb3\x22\xdb\x7d\x97\xd9\x0d\x95\x7a\x63\x7b\xd8\x26\xc2\x27\xe9\xeb\x18\x0b\x45\xa4\x31\x62\x6a\x6f\xd8\x90\xc0\xe5\xf4\xed\x7e\x85\x64\x74\x75\x2f\x80\xb5\xae\xf6\xe7\x3e\xfd\xaa\x6c\x2c\x45\x1b\xd7\x4c\x1e\xf4\x66\xca\x3a\xaa\x25\x73\xbb\x52\xcb\x2b\x1c\xa9\x6a\x1b\x57\x44\x03\xce\xae\x1c\xf0\x5f\xfc\x53\x43\x0e\x1e\x4c\xd5\x59\x3b\xd1\xef\x84\xbc\xbf\xe2\x19\xf0\x81\x60\xd1\x66\xf2\x73\x1d\x99\xb8\xd7\xa3\x2b\x12\x99\x1f\x77\x77\x5a\x26\x7e\xc0\x82\x97\xec\x51\x2d\x7b\x72\x43\x56\x32\x52\x5c\x04\x00\x0f\xb0\x0a\x79\x3f\x8b\x5f\x8f\x37\x47\xb5\x53\x59\xdf\x21\xb7\xe2\xc4\x9f\x2b\x0b\x9a\xe0\x82\xaf\xc7\x0a\x14\x68\x71\x37\x0b\x8d\x50\x08\x6d\xe0\x0f\x94\x48\xbe\x89\x02\x17\x4b\xa2\xcc\x85\x1f\xa3\x79\xdd\x70\x31\xca\x45\x7a\x88\x69\xaf\x4b\x6c\x27\x29\xda\xc5\x19\x55\x6b\x8b\xb4\xab\x51\x9e\xf1\xbb\x02\x4e\xa8\xb7\xf0\x17\x71\xc9\xaa\xb7\x48\xe5\x73\x81\xa0\x19\x2a\x6e\x39\x8c\xbe\x6d\xd9\xf3\x67\xcc\x7b\x33\x54\xf8\x3b\x79\xbc\xda\x46\xb7\x93\xa4\xad\xa8\x55\x49\xc8\xd6\xbd\xd6\x16\x81\x24\x36\x2f\xf9\x08\xaa\x1a\x0c\xb7\x8a\xa3\x30\xc4\x2d\x5a\x5d\x48\x12\x35\xac\xac\x3a\x91\x9b\x96\x9c\x50\x98\x72\x66\xd4\x04\xd1\x5d\x0e\x70\x6f\xd9\x00\x76\x34\xf6\x9e\x13\xc5\x6e\xc4\x71\x33\x88\x4f\xca\xdd\xc1\x6b\xee\xee\xd1\x9e\x0c\xd9\x17\xaa\x49\x63\x67\x86\x7d\xfc\xea\x27\x4e\x1a\x47\xda\x77\x4f\x3c\x93\x63\x02\x1e\x7c\x8d\x6b\xf8\xf0\x00\x53\xfa\xcc\x11\xcb\x68\xa9\xd6\xe1\xfc\x2d\x6d\x19\x17\x5d\x63\x24\xff\x7c\xa6\xc2\x30\x58\xb8\xb6\x93\xd8\xfd\x4e\x0b\x51\xdc\xbb\x11\x35\x43\xf2\xfc\xc0\x45\x2e\xb9\xd9\x67\xac\x0f\xa9\xb2\x3e\x9e\x0b\x1d\xa8\xd8\x3a\x3c\x1f\xc9\xe9\xec\x97\x1f\x0f\x67\xfc\x74\x5b\xb1\x73\x76\xbc\x46\x24\x5f\x52\x8c\xb6\xe5\xfe\xe1\x1b\xcd\xda\x86\x7b\x7f\x79\x01\x9c\xf9\xdb\x59\x18\x58\x23\x0a\xec\xb4\xd1\xe9\x3d\x16\x7c\xd8\x6b\x42\xdd\x87\x9a\x13\xfa\x0e"}, +{{0xc5,0xa5,0x05,0x34,0x77,0xae,0x31,0x15,0x8e,0x74,0x69,0xdd,0x15,0x04,0x86,0x76,0x50,0xd4,0x6f,0x15,0x89,0x06,0x7f,0x5c,0xd8,0x81,0xca,0xf2,0x5c,0x26,0xcb,0x21,},{0x70,0xf8,0x5d,0xb9,0x80,0x7b,0x26,0xfc,0xf3,0xe6,0x69,0x0b,0x91,0x72,0x4f,0x7a,0xe3,0xd2,0x0e,0xc3,0x60,0x4a,0xb7,0xd6,0x30,0x8d,0x90,0x94,0x30,0x8b,0x2d,0x59,},{0xf5,0x19,0x1b,0x44,0xbd,0x6c,0xc3,0xea,0x28,0x17,0x71,0xdf,0x12,0x54,0x9b,0xa2,0xbe,0x22,0x8b,0x51,0xeb,0x79,0x1b,0x9e,0x5e,0xd2,0x81,0x5f,0x86,0x2a,0xa6,0x30,0xb5,0x69,0x67,0xcd,0xef,0x8b,0x6a,0xf0,0xb9,0xd2,0x1a,0xb8,0xc9,0x7a,0x6d,0xff,0x68,0x1c,0xce,0xd9,0xf5,0x01,0x97,0x13,0xd4,0x35,0x7c,0xb3,0xe5,0x4c,0x0d,0x08,},"\x85\x71\xff\x39\x03\x48\x6a\x43\xa6\x12\x6c\x32\x3e\x7b\x3a\x74\x14\x1d\x13\x85\xd4\xbd\x70\x3f\x19\xe2\xd1\xb6\x4b\x50\x28\x1d\x27\x16\x8a\xe3\xe7\x69\xc6\xdd\x9d\xf7\xd9\x78\x64\xfb\x37\x82\x2f\x00\x21\x85\x2e\x31\x68\xab\x7d\x84\x5a\x65\x45\xed\x0c\x37\x7d\x9f\x7c\x04\x8a\x2b\x96\xe8\xdc\xf4\x45\x77\x96\x84\xa0\x58\xc2\xb9\xc2\x1a\xc6\x8a\x0c\x34\x1d\x1d\x6c\x09\x81\x45\x64\x57\x45\x8e\xb7\xce\xbf\x66\x67\x87\x40\x77\x7e\xca\x26\xe0\x1e\x1c\x8f\x53\xb5\xd4\x75\x6c\xc5\xf0\xb9\x0f\x0c\x5d\xb0\x53\x93\xcd\x4b\x8e\x44\xf6\x81\x0c\xaa\x5a\x11\x6a\x33\x57\x77\x24\x39\x5d\x41\x3a\xf6\x19\x63\x2a\x6f\xed\x14\xe2\x15\xc2\xf1\x9d\x10\x5c\xe2\xbf\x14\x98\xe6\xd2\xab\x4f\x65\x0f\x61\xba\x5c\xf6\xd0\xc7\x3b\xbb\xde\x98\xe3\x04\x29\x91\x0a\x4e\x67\xdf\xbc\x71\x7c\xb0\x91\x18\x2d\x59\x70\x58\xb5\xd7\x65\xd0\x97\xe6\x87\x58\x31\xb5\x88\xaa\xeb\x3e\x73\x27\xe8\x56\xb4\x2f\xa9\x83\xfd\x25\x4e\xf1\xf9\x18\xb0\x43\xd1\xdd\x3d\x7b\x7e\x30\xb3\x15\x38\x6e\xec\x91\xe7\xf9\x4d\x59\x8f\x4b\xeb\x3b\x27\xb4\x2f\x4e\xe1\xfb\xf7\xaf\xb4\x86\xbd\xcc\x60\x81\xcc\xb8\x67\xf0\x41\x11\x04\x4f\x4b\xbb\xe3\xc8\x12\x2e\xde\xad\xef\xa9\xd6\x93\x90\x6e\x0d\x6e\x13\x3b\xf6\xf2\xda\x61\x58\xfe\xed\xbd\xa0\x24\x41\x0f\x12\x08\x6e\x7a\xcc\xf1\xc6\x8e\x15\x57\xf0\x0c\x14\xe9\xc7\xea\x76\xa5\xed\x13\x37\xa0\x54\xac\x2c\x94\x9c\x05\x97\x7e\x03\x02\x74\xf6\xa4\xf2\xa6\xb3\x0a\x15\xc5\x70\xec\x94\x33\xf7\x4f\x47\x52\x80\x87\xc9\xce\x9a\x62\x92\x95\x1c\x54\x35\x49\x96\xfb\x28\x3c\x0d\xc4\xcf\x33\xc0\x01\xbc\x96\x87\x5e\xa6\xe1\xf4\x6f\x83\x7f\xf1\x8d\xd9\x54\x5f\xb9\x93\x46\x55\x34\x2b\x12\xc2\x99\x0b\x9f\x1c\x6f\xf4\xd6\x64\x89\xd6\xae\xdc\xe7\x5c\x7c\xb0\x3a\xc1\x34\xbf\xd3\x9b\x18\x1d\xfb\x7f\x9a\x97\xce\x73\x7f\xe5\x70\xad\x5f\x81\x34\x59\x39\xa6\xde\x5a\x40\xa3\x3a\x0e\x44\xbf\x95\x75\x03\xd5\xca\x02\x83\x51\x2e\x57\xfb\xa8\xa3\xa6\xf2\xc3\x90\x68\x7b\x1b\x77\x08\x67\x6e\x0f\xd0\x3b\x7c\x18\x8d\x45\x61\xc1\x87\x91\x63\xea\xf2\xb5\x96\xdd\xd5\xf3\xc1\xf4\xda\xdb\xc1\x39\xc2\x16\x48\x92\x82\x0b\x2f\xe0\x9c\xbc\x3d\x19\x08\x80\x76\x36\x45\x10\x25\x4f\x2b\x6d\x41\x03\x29\xe7\x0f\x2e\x5a\x94\x5b\xba\xcd\x2c\xa8\x9b\xd4\xb6\xe1\xf5\xe2\xe1\xd4\xf4\xed\x2f\xe0\x11\x3b\xcf\x32\x96\x2f\x00\xd5\xc3\x3b\x1d\xf9\x88\x40\x2b\xa0\xdc\x88\x04\xc1\xaf\x66\xcc\xae\x26\x70\xef\xa3\x13\x4c\x67\xfc\x90\xfe\xed\x8d\x8d\xee\xdc\xcf\x6a\x46\xf2\x29\x40\x45\x4a\xf2\xbb\x67\x54\xcf\x23\x5d\xdb\xb0\x00\x1c\x6c\x74\x1b\xf8\x74\xbc\xd8\xd4\x1d\x9d\xba\x81\x62\x58\x1c\x37\x46\xd7\xf3\x0e\x73\xde\xf6\x94\x15\xaf\x51\x81\xc1\x49\x91\x42\x95\x12\x2d\x45\x98\x2f\x94\x94\x3e\x20\xb0\xff\xc7\xfe\x6d\xdf\x19\xa0\x22\xe8\x7a\x52\x13\x33\x57\xa1\xe8\x0f\x37\xf2\x8a\x4c\x4a\x8a\x61\xc1\x48\xdd\x87\x5c\x1e\x8e\xcd\xcd\x84\x0d\xd8\x63\xe4\x4d\x9b\xcb\x16\xb6\xe5\xaf\x01\x47\xb3\x4a\x7a\x90\x52\xc8\xd3\xf4\x52\x01\x3d\x2d\x35\x4f\x68\x03\xf9\xea\xf6\x05\x6f\x3b\x01\x3c\x61\x6e\x47\xf3\x98\x81\x91\x46\x32\x0a\x5e\x3d\xbd\xf1\x68\x43\xea\x29\xde\xf2\x62\xcc\x9a\x34\x36\x72\xcf\x96\xbc\xcc\x6e\x87\xe6\xa6\xba\xf0\x71\x2e\x6e\xe8\x9a\xa6\x04\x89\xf1\x7c\xb7\x2d\xdc\x44\xba\xd1\x61\x58\x7d\x87\xf5\x4d\x67\xcc\x0a\x27\x78\x49\x7d\x83\x10\x88\x31\x5f\xfe\xee\x3d\x26\x8c\x59\xbe\xfe\x88\x4c\x3a\xa0\xe0\xae\x22\x96\xbb\xb6\x0e\xac\x90\x97\xcd\xf8\xdc\x09\x87\xce\xb1\x74\x2b\x05\x86\xdf\xce\x79\xec\x10\x42\x5b\x28\xf4\xe6\x45\x20\xd7\x12\xe3\xf4\x6e\xa8\x3b\xe2\xde\x6a\x15\x74\x07\x3b\xc5\xc7\x55\x7b\x8e\x25\xb6\x41\x11\x84\xea\x28\x3d\x88\x00\x23\x2c\x79\x06\x94\x21\x81\x1f\x88\x3c\x29\x94\xe7\xb7\xe2\xad\x9f\x8d\xc4\x89\xc9\x34\x77\x24\x39\x46\x09\xc9\x89\x09\xa6\xc2\x60\x17\xb5\x0f\x20\xd5\x0c\xca\xcb\xde\x36\xb7\x6b\xa6\x46\xa7\x6d\xc6\xa5\xb0\xf5\x06\x49\xc5\x65\x8b\xbd\xfd\xd3\xb5\xca\xfc\x54\x79\xa2\xf4\x8e\xe5\x15\x42\xf2\x3e\x9f\xc9\x21\x32\x06\x0f\xd6\x35\xef\xf4\x52\x11\x1c\xda\xf3\xef\xbd\xb7\xdb\x9e\x7d\x47\x16\xd0\xd6\x01\x1c\x29\x11\x8a\x55\xd4\xc1\xa4\x36\xab\xe2\x4e\x3c\xbf\x40\x23\x5b\x76\xdd\x19\x23\x50\x3c\x5f\x35\x98\x12\x4e\x2d\xf5\x5a\x2d\x1f\x24\x6e\x90\xde\x4b\x71\x64\x5d\x51\x75\xb6\x1b\x01\x74\xe7\xe5\x7d\xf1\x28\x5c\xcf\x8c\x86\xb8\x38\x2c\x25\x80\x79"}, +{{0x05,0xc7,0x19,0xca,0xe0,0x6e,0x2b,0xb7,0xd8,0x78,0x63,0xab,0x31,0x50,0x27,0x2c,0xb2,0xf8,0xc3,0xaa,0x24,0x21,0x91,0x2d,0x87,0xf9,0x8e,0x75,0x89,0x63,0x8c,0xe9,},{0x90,0x21,0x17,0x96,0xfe,0xd3,0xd5,0x3b,0x81,0xf8,0xfe,0xeb,0x1b,0xad,0x1f,0xfc,0x93,0x3e,0x5f,0x10,0xd3,0xbc,0x1b,0x36,0xdd,0xf2,0x10,0xa4,0x79,0x23,0xdf,0x03,},{0xba,0x6e,0xb7,0x51,0x37,0x1d,0xf7,0x21,0xb7,0x70,0x7a,0x5b,0x33,0x39,0xed,0xb5,0x5f,0x13,0x86,0x40,0xb9,0x7b,0xe6,0x33,0x4d,0x6c,0xda,0x51,0x91,0xa3,0xff,0x63,0x67,0x91,0x17,0x61,0x88,0x2a,0x4a,0x00,0x7f,0x16,0x1b,0x74,0x8c,0xec,0x95,0xb1,0x9e,0x99,0x5f,0x28,0x58,0xc2,0x57,0xcd,0x61,0x69,0x25,0x66,0x62,0x30,0x11,0x02,},"\xec\x24\x19\x18\x41\x8e\x60\x52\x20\x42\xe6\x73\x39\xe6\x64\x94\x99\xf3\x1a\x6c\x7c\xf8\x92\x5f\x1f\x61\xdd\xe8\x94\x60\x36\x02\xae\x8b\xb5\xf5\x88\x09\x82\x1f\x83\x34\x4f\x23\xcd\x31\xe6\x4e\xc9\xff\xe7\x9a\x98\x6b\x7e\x29\xe4\x31\x9a\x63\x41\x43\x16\xbd\x6e\xe2\x0e\x02\xa5\x0d\xa4\x40\x12\xbd\x2d\x6f\x9f\x67\x9e\x88\xed\x0c\x8b\xb1\xe2\xca\xd5\x5e\x56\x57\x89\x88\x33\x45\xb7\x54\x6f\x3d\x54\xb1\xb3\x62\xb1\xc6\x50\x50\x2c\x01\x9d\x73\x13\xaf\xbc\x82\x68\x9b\x23\xa3\xa5\x2d\x8f\x1a\xf9\xf8\x1e\x18\x8d\xbd\xf2\x03\xfb\x53\x00\xb4\x22\x5b\xfb\x67\x73\x33\x7b\xe6\x75\x0b\x3d\xb8\x8c\xe0\x97\x34\x3f\x62\xee\x2c\x11\x85\x74\xef\x15\x0c\xbd\x4c\x62\x76\x0c\x3e\x43\xdc\xbc\x39\x21\x8b\xd6\xd9\x85\x65\xfa\x38\x98\x11\xb1\xa6\x74\xf6\x17\xfd\x75\x67\x33\xdc\xb5\x67\xa9\x2d\xbf\x38\x55\xb5\x7b\x1f\x4a\x46\xd5\xb8\x97\x4b\x39\xac\x0d\x0e\x24\xd9\x9d\x20\x37\xc0\x4f\x60\xd9\x14\x0f\x64\xb0\x7a\x77\xd7\xea\xa1\xce\x8a\x78\xe8\x44\xb1\xdc\xf0\xe3\x74\x24\xf3\xf9\xd2\x53\xa5\x48\x56\x1a\x03\x75\xa8\xd4\x34\x12\x97\xbf\xed\xb7\x04\x8c\x79\x35\xe1\x48\x14\x18\xf9\xbb\xa9\x27\x1f\x9f\xd6\x02\x62\x24\xe7\x8e\x05\x5d\x8a\x09\x39\xfa\x2f\xe1\xdb\xc0\xfc\x7b\x58\x3e\x4c\xff\x34\x90\xe1\xd0\xf6\x10\xb2\x52\xe3\x0d\x84\x97\xd0\x0e\x4a\xac\xb3\x75\xf1\x9a\x47\x19\xf7\x9c\xa1\xea\x58\x3a\x2f\x8b\x14\x06\xa4\xaa\x5c\xb5\x5c\x08\xb6\x59\x3b\x67\x6e\xb5\xc3\x4a\xbe\x89\x39\x2d\x62\xd2\x33\x08\xa3\x34\x8b\x57\xaf\xfb\xba\x77\x39\xcd\xe8\xe1\x90\x9d\x34\x25\xee\xb2\x09\x26\xa9\x77\xd3\xa9\x4a\x86\xe0\xba\x10\xb3\x86\x92\x66\x98\x82\x7e\x86\xb4\xfd\x6c\x61\x80\x04\x7c\x87\xec\x3b\x31\x61\x9d\x05\xa9\xdf\x34\xef\xd3\xd7\x6a\x83\x69\x62\xb2\xef\x60\x4d\x07\xaf\x09\x75\xeb\x8f\x3d\xd2\x25\x94\x32\x38\x02\x56\x4c\x92\x9b\x3f\x65\xda\xcb\x57\x2b\x32\x55\x3d\x69\xb3\x1a\x19\x76\x90\xa9\xbb\x86\x0b\x08\x0a\x77\xcf\xbb\x3c\x17\x5a\xaf\xce\x01\x46\xa8\x2a\x4d\x06\xe8\xc7\x50\x52\x1b\x72\x6e\xf1\xcb\x29\xd0\x21\xe5\x91\x5e\x5e\x84\x62\xed\xe5\x39\x54\x45\x24\x5c\x9a\xe8\x82\xee\xc4\xb1\x74\x5e\x11\x79\x1f\x76\x21\xd3\xfe\x70\x2c\xac\x15\x25\xe1\xf7\xb4\x6e\x11\x05\xcd\xd0\x6d\xa2\xaf\xde\x26\x47\x5d\xc1\xf7\x8d\xf8\xe2\xd7\x2b\x0e\xc3\xef\x7d\xd9\x56\x19\x3c\x99\x68\x42\xa4\x32\x69\x65\x38\xcf\x12\x3d\x76\x87\x21\x1f\xfc\xd0\x90\xb9\x38\x1e\xab\xec\x87\x9f\x76\x9a\xac\x0d\x35\x64\xe1\x6d\xf7\x94\xfa\x24\x72\x8d\x71\x72\xfd\x07\x73\x2e\xab\x07\x7e\xd8\x1c\x22\x08\x4f\x6f\x78\x1b\x62\x6d\xac\x67\x42\x8a\x9d\xdf\x3b\x0d\xb0\x46\x52\x51\x22\x0d\x18\xb8\xbf\x62\x04\x64\xc5\x1a\x57\x8d\xec\xcc\xbb\xab\xa5\x45\xed\x44\x2c\xf1\x2c\x4c\x66\xf6\xcb\x6e\x69\x01\xea\x54\xae\xda\x23\x6e\xc4\x5e\xef\x88\x6a\x7d\xdd\x2c\x04\x1c\xab\xa3\xa6\xce\xe3\x39\x71\x5b\x6c\xe9\x7e\x76\x5e\xc3\x47\x9f\x3d\x52\x82\x4a\x81\x94\xbe\xc2\xa8\x96\x47\xe8\xc6\x3f\xf7\x64\x5f\xf6\xd0\x53\x67\xc7\x67\xbc\x48\xcc\x96\xba\xf0\x5d\x6a\x41\x5b\x2a\x5a\xff\x9b\xfb\x21\x79\x48\xfa\xd3\x57\xb9\x8f\x47\xdf\xed\x62\xff\x12\x85\xeb\x9f\x46\x8f\x0f\x29\xed\xd7\x5a\xdc\x0c\x8c\x2f\xf6\xa5\x65\xed\xb8\xed\xfb\x48\xbe\xa0\x3b\x70\xc4\x47\x36\x9c\x52\xd8\x81\xee\xa0\xee\xdb\x08\xc3\x15\xcd\xf0\xbf\xeb\x97\x9c\x1c\x02\x50\x94\x6b\xb1\x00\xc2\x86\x6b\x41\x69\xb8\xcb\xd4\x4d\x65\x8f\x02\x36\xe1\xe9\xf3\xaa\x13\xbb\x8e\x80\x22\xa3\x8c\xe9\x97\xc9\x4b\x5b\xaf\x97\xe0\xba\x62\x1f\x7e\x09\x67\x1c\xe6\x38\xc2\xa3\x9e\xe6\xc6\xe2\x5a\x68\x80\x19\xdd\x16\x76\x75\xce\xae\xc2\x1c\x6b\x42\xa7\xc8\xc4\x76\xd1\x29\xdc\xc6\x93\xc3\x92\xa0\x2b\xe9\x1b\x87\x43\x7a\x08\xa0\xeb\xf1\xa7\xbd\x97\x6b\xa2\x37\x74\x76\x68\x38\xb8\xd6\x02\x4f\x5b\xb9\xb0\x7f\x3c\x6b\x71\x9b\x4d\xe1\x5b\x72\x44\x80\x48\xab\x70\xdb\x3d\x4b\xea\x77\xba\x35\x9b\x51\xb1\xec\x17\xdb\xe8\x01\x0a\xef\x02\x44\xa8\x07\x9c\xa8\xb9\xa2\xa7\x97\xf3\xb1\xfe\x04\x7c\x8d\xd5\xca\xb7\xfb\x48\x68\x29\x23\x9c\x4e\xf6\xd9\xa3\x83\x70\xd4\x88\xc4\x7b\x7c\x03\x0e\x49\xa5\x50\x0c\x9a\xbb\x39\xa9\xa5\xab\xfe\x72\xe9\x18\xb7\x63\x84\xec\xaa\xfe\x16\x27\x26\x6c\xd1\x4e\x69\x6c\x09\xd2\x51\x2e\x31\x25\x82\xa8\xa9\x11\xe7\xb7\xbf\xa0\x4c\x21\x81\x9a\xf6\x87\xf0\x4c\x5e\x0c\xbe\x9a\x2c\xe2\x4d\x4d\x3f\xd1\x21\x90\xb2\x53\xda\xbc\x12\xc6\x3c\xab\xfa\x94"}, +{{0x53,0x11,0xf3,0xc9,0x61,0x01,0xcb,0x8b,0x7a,0xbc,0x62,0x2b,0xb9,0x32,0x6b,0x8f,0x51,0x3c,0x2b,0x16,0xd2,0x94,0xdf,0x79,0x7f,0x56,0xdf,0xd8,0x20,0x3d,0xda,0x27,},{0x23,0x0b,0x70,0x02,0xf5,0x7c,0x79,0xae,0x2e,0x6b,0xfd,0xb8,0xdf,0x30,0xdb,0x3e,0x90,0x07,0x56,0xb5,0x4a,0xf3,0x96,0x8c,0x67,0x0e,0xe2,0xf3,0x2b,0xb1,0x1e,0x0a,},{0x3c,0xbb,0xb2,0x60,0x88,0x70,0xde,0xa1,0xef,0xee,0xbb,0x3f,0xbf,0x68,0x1e,0x27,0x70,0x5c,0x35,0xe4,0xdd,0xee,0xa8,0x6c,0x1b,0x34,0x2a,0x77,0xdc,0x29,0x6b,0x49,0x84,0x19,0x80,0x8e,0xac,0xbc,0x78,0x85,0x56,0x11,0xff,0xbc,0x92,0x65,0xa7,0x47,0x98,0xe5,0x18,0x27,0xe6,0xe5,0xd8,0x11,0x81,0x6d,0x3c,0xa2,0x1e,0x8b,0x9c,0x06,},"\x61\xb1\x5b\xe3\x7c\x4e\xb3\x97\xd9\xe7\x7e\x00\x15\x1a\x28\xed\x3e\x86\xd5\x0a\x95\x52\xbb\x48\x50\xb6\x21\x76\x3f\x01\x2e\x7e\x77\xbb\x5d\xb8\xf3\xdf\x7d\xcf\x76\x9f\x2d\x1d\x46\xd8\xd6\x0b\xae\x40\xc8\xca\x6e\x25\xc6\x41\x0b\x60\x07\x8a\x93\xfd\x05\x90\x21\x14\xbd\x91\x04\x5c\x06\x19\x2c\x70\xc4\x2c\x9f\x41\xf8\x16\x1c\xa4\x65\x64\xeb\xc2\x1a\x4b\xdd\x81\x90\xeb\xa2\xae\xb3\x09\x82\x30\x72\xec\x2c\x02\x00\xce\x64\x98\xf9\xd7\x2b\x37\xb3\xfb\x46\x67\x74\x32\x6d\xf3\x7a\xd8\x80\xd8\xed\xdb\x32\xaf\x67\x3e\x45\xd8\x8e\xec\x49\xb1\x57\x7b\x43\xb8\x63\x91\x11\xc2\xe0\xb9\x41\x87\xd2\xd4\xe0\x17\x3c\x00\x0f\x4c\x37\xbe\x84\x5d\x68\x81\x0b\x78\x89\xff\x2a\x04\x9f\x3f\x9f\x24\x5e\xc7\x0f\x21\xde\xf9\x77\x80\xb6\x11\x40\x0a\x83\xc3\x1a\x79\xd9\x3a\x8e\x98\xb6\x08\xfd\xcf\x24\x88\xb0\x68\xfe\x1a\xe4\x21\x72\x93\xa9\x36\x7b\xb7\x34\xb5\xbc\x7b\xd8\x81\x9b\x37\x7f\x09\x0b\x4f\x8f\xdb\xff\x50\x79\x9c\x76\x88\x0d\x19\x13\x35\x80\xe1\xdd\xfc\x2b\x9b\xaa\xdd\xba\xb3\x4f\xc6\xfd\xc0\x78\x01\x4b\xd1\xff\x73\x9d\xaa\xfe\x54\x76\xf3\xf7\x9d\x4d\xbe\xc2\x16\xfa\x76\x80\xee\x8e\x84\x00\x2d\xcb\x9d\xdb\xc7\xfc\x1e\x1c\x8e\xf4\xf1\xb2\xa2\x08\x1b\x92\x82\x24\x3d\xa6\x15\x3c\x1f\xce\x09\x05\xcf\x35\xf8\x3a\x68\x4c\x01\xb0\x45\x57\xec\x84\xf7\xe9\xa9\x4f\xc2\x88\x2e\x2f\xf1\x9f\xea\x21\xd2\xce\x61\x67\x86\x1c\xe0\x1d\xf8\xb8\xd3\xc3\xe8\xd2\x55\x61\x0b\x7a\xf2\x59\x6c\xd5\xcf\x00\x16\x73\x49\x42\xcc\x71\x4c\x27\x2c\x05\xfd\xa9\xd3\x47\x23\x62\x66\x46\xa4\x61\x30\x18\x2c\xeb\xcf\x17\x9e\xc0\x0a\x6a\x17\x3b\xd8\x57\x7f\xa8\x45\xc4\x4d\x19\xc6\x99\x79\x44\x75\x5f\x2b\x4e\x46\x85\x63\xa7\x5e\x90\x16\x52\x3b\x87\xdd\xac\x3e\xee\x21\xbc\xbc\xa0\x8f\xcc\x29\x54\x6a\x43\xcb\xe0\xd8\xd1\x0a\x0e\x8d\xdc\xba\x17\x2d\x1d\xed\x15\x03\x78\xe1\x8b\x36\x8c\x77\x63\x91\x3e\x4b\x40\x70\x12\xfd\x76\xa8\x72\xd2\xcb\x04\x93\x0b\x8e\x22\xb3\x08\x24\x3d\x4c\xc2\x78\xfd\xf2\xe1\xf9\x40\xae\x89\xac\x89\x1b\x9e\x06\x61\xae\xe5\x53\x93\x7b\xf3\x50\xb4\x07\x07\x0a\x1b\xdf\xc4\xf7\xa3\x78\x7e\xf3\x99\xd2\xca\xf4\xec\x74\x43\x9c\x58\x73\x76\xc7\x7b\xe0\xc3\xde\x53\x9d\x3a\xc2\x60\x89\x76\x5b\x9b\xe1\x0b\x90\x38\x69\x46\x36\xe2\x62\xd7\xba\xa0\xb3\xa8\x94\x1a\x20\x15\x96\x76\x39\xf6\x04\x4c\x67\xe5\x9b\xc8\x1c\xf2\xfb\xa7\x04\xac\x0d\xf4\x8d\xa6\x03\x74\x05\xa8\xe8\xb8\xa7\xce\x3c\x58\xef\x38\xa8\x83\x53\x8b\x24\x7f\xfe\x18\x09\x7a\xf0\x95\x24\x2b\x05\x8b\xdd\x1e\x3e\x24\x5e\xec\xe0\xa7\x1b\x75\xb9\x7d\x52\xf2\x0d\x6d\x51\xbb\x97\x66\xb0\xda\x0f\xc0\x9c\x8a\xc2\xa3\x0f\xb6\xe7\xb3\x2e\xe0\x6d\xad\xf4\x6d\x73\x59\xcc\x06\x6a\xa9\x47\x85\xd8\xa8\x82\xff\x09\x7d\x78\xa8\x6b\xe2\xd4\x56\x00\xdd\x3d\x30\x60\x12\x5f\x01\xc0\x63\xe4\x88\xd5\xc3\xef\xee\x1b\xca\x1e\x58\x51\x64\x55\xff\xca\xec\x1b\x81\xef\x43\x38\x76\xbf\x09\xff\xa5\x1d\x6f\x50\x18\x58\x52\x24\x57\x9c\xb6\x7b\x56\xce\x1c\x21\x6e\xc0\xa8\x83\xe0\x6c\x8e\x15\x63\x42\x1e\xa7\x2b\x0c\x10\xd4\xbb\x31\xe4\x91\xc2\xae\x2f\xe8\x13\x9f\x24\x9e\xc9\x27\xd8\x06\xba\x08\xdb\x52\xb1\xb5\x06\x66\x90\x47\xf0\xc1\x16\xff\x37\xac\x5b\xa6\xcd\xb1\xea\xaf\x33\xfd\xad\xb0\x70\x5c\x79\x9d\x35\xac\x6d\x9c\x80\xda\x90\xc1\x43\x8b\x58\x5f\xfd\x59\x35\x0a\x26\x86\xb1\xec\x35\x16\x6c\xb9\xb6\x9a\xd0\xf5\x65\x86\xaa\x03\x27\x4d\x78\x2e\x3f\x85\x8d\xb6\x4a\xdf\xbf\x04\xd5\x22\x8a\x7b\x1c\x4a\x20\x48\xbb\xcd\xb9\x41\x15\x3a\x43\x6d\x74\x2c\x38\xb5\x8b\x4d\x7d\x13\xc9\xf1\xd6\x0e\x15\x2a\xa2\x79\x23\x49\xa3\xd9\x4e\x7e\x6b\x11\x04\xaa\x1b\x87\x09\x98\xc1\x8d\xd7\x06\x56\x54\xa8\x52\x81\xbb\x6f\x02\x7f\xaa\xd5\x56\xb1\xf5\x32\xe7\xa1\xe2\x2d\x56\x40\x69\x28\x95\x87\xa0\xef\xc9\xc1\x58\x5d\x13\x5f\x31\x23\x3c\x41\xf4\x40\x46\x6e\x71\xfe\x90\x12\xe5\xf9\xa0\xd7\x4a\x72\x82\xee\x39\x2f\xb0\x16\x5d\xb7\x9f\xf1\xd3\x17\x6e\xd0\x8a\xfe\x1d\xaa\x66\xcf\xbf\x43\x05\xae\x16\xac\x17\x92\x33\x43\x99\xf7\x1b\x19\x17\xdd\xec\x27\x0a\xcf\xf6\x65\xea\x05\xd1\x84\xc2\xc5\xcd\x2c\xcd\x90\x2b\x22\xf9\xb7\x19\x5e\x66\xa6\x55\x56\xca\x88\x4b\xa6\xf5\xda\x04\xdc\xd4\x61\x7f\x33\xdc\x2b\x44\xa0\xea\x74\x2a\xeb\x2b\x93\xf3\xa4\x1d\xf7\x95\x7a\x02\x67\x97\xa5\x85\xce\xee\x81\x4b\x19\x75\xf5\x23\xd2\xdb\x5d\xbb\x9b\xe0\xca\x64\x9d\x1d\x45\xdc\xfd"}, +{{0xd2,0x90,0xff,0xd9,0x33,0x95,0xbd,0x5f,0xc5,0x87,0xd1,0xab,0x51,0x18,0x66,0xe7,0x2b,0x37,0x1a,0x17,0x35,0x73,0x2d,0x9d,0x5c,0x6a,0x18,0xdd,0x46,0x5e,0x93,0x63,},{0xfd,0x4a,0xad,0x73,0xb0,0x32,0x46,0x1c,0xa0,0xaa,0xe8,0x71,0xca,0x70,0x16,0x38,0x3b,0x2b,0xe0,0x16,0x90,0x53,0xfd,0xbf,0x6c,0x59,0x14,0xfd,0xd6,0xdd,0x6f,0x92,},{0x21,0x70,0x4d,0x5e,0x62,0x6d,0xcf,0x6a,0x9d,0xcd,0xef,0x93,0x54,0x29,0xeb,0x7f,0xb5,0xb2,0x57,0xee,0xcd,0x7b,0xf7,0x4a,0xcb,0x0c,0xd3,0x0e,0xcf,0xcf,0x60,0x8d,0x0c,0x5b,0x63,0x3a,0x4a,0x8a,0x9b,0xa2,0xcc,0x82,0xa2,0x1e,0x03,0x35,0x5e,0x01,0xd8,0x5d,0xae,0x7e,0xca,0xc8,0x89,0x6d,0xc1,0x5d,0xae,0x04,0x85,0x70,0x71,0x04,},"\xeb\xd9\x00\xbc\x91\x0c\x5e\xcc\x4d\x97\xda\xf7\xcb\x5e\xbb\x54\x91\x50\x0b\x7a\xd1\x16\xe3\x06\x60\x95\x07\x09\xd8\x08\x4b\xb6\x43\x4c\x5b\xea\x4a\x8c\xcc\x1e\xd5\xa8\x01\xbe\xbb\x1a\x11\x78\x78\xc0\x37\x47\x00\x3e\x14\x8e\xd9\x14\x34\x83\x2e\x89\x66\x24\x1a\x7f\xff\x22\xfe\x1d\x6d\x8c\x3c\x3d\xdd\x72\x15\xa1\xef\xaf\x4b\x07\xaf\xee\x1b\x25\x67\x3a\x14\x39\xea\xac\x32\x4e\x89\x5d\x4b\xe8\x39\xe9\x76\xc0\x3a\xc0\x01\x25\x48\x76\x88\x8c\xca\xaf\x39\x12\x72\x7a\x60\x10\x6a\x87\xbe\x69\x24\x7c\x9e\x43\x8c\x31\xfc\xa8\xd9\xc6\x1b\xae\x36\x8c\x83\xe4\x09\x01\xa9\x97\x00\xdf\xf8\x39\xb5\x13\xba\x8d\xc4\x2d\x93\xce\x09\x87\xa2\x33\x34\x70\xa9\xf9\x83\x31\x3f\x91\x98\x86\x59\xda\x54\x03\x9e\x49\x9c\xd1\xaf\x2b\x8f\xa0\xeb\xe7\x50\xe2\x4d\x55\xc2\xa5\xbd\x1a\xde\x3f\x68\x00\x92\x54\x2b\xd1\xbe\x0b\x97\x35\xba\x39\x3a\xd5\x69\x7d\x24\x1e\x8e\x8b\x28\x64\x6d\xb2\x7d\x2f\xb5\xa9\x40\xe8\xfa\xea\xf0\xb6\xc9\xef\xda\x88\x61\x5d\xec\x89\x1c\xe7\x32\x93\x08\x13\xbf\xbb\xd0\xbc\x5f\x82\x10\xab\xe8\x43\xbe\xb5\xe4\xf0\x28\xf4\x9b\xea\x34\xf1\xe5\xb0\x9e\xac\x4c\x66\x62\xc7\x4f\xba\x39\xde\x4a\x96\x02\xa9\x69\x4a\x85\xc7\xc1\x37\x5f\xda\xdf\xda\x6a\x19\x57\xfc\x5b\x59\x87\xa6\x87\xb0\x39\x95\xe5\x16\x97\xa1\xab\x5b\xb6\xcb\x11\xb6\x63\xc1\x37\x2f\xad\xe4\xc0\xac\xa8\xfb\xeb\xb4\xeb\x54\xce\x7c\xe3\x6c\x69\x04\xea\xf6\xea\xb2\xf3\x4f\xac\xd8\xc7\x68\xc8\xd3\x6d\xa2\x39\x7b\x1a\x02\x73\x5a\xea\x72\xcf\xaa\xd0\x39\x34\x10\xdb\x52\x7a\x8a\xb2\x36\xd4\xcd\xab\xdc\x88\x8f\xac\x6f\x18\x21\x48\xb1\x32\x61\x44\x25\xd3\x90\xff\x03\x6e\x54\x85\x5e\x42\x03\xc5\x12\x03\xc1\xf4\x3e\x37\xbb\xf6\xb9\xbf\x27\xf5\xb7\xe7\xc6\x65\x15\x14\x65\x40\x1a\xc3\x2c\xbe\x9e\x33\x50\x53\x5e\xdf\x48\xa7\xbc\x36\x03\xe2\x23\x2e\x93\x8f\x9a\x81\x5a\xc4\xd1\xde\xec\x99\x1e\xf9\x62\x09\x48\x44\x1f\x7a\x2f\x4a\x46\xe2\xc4\x00\xab\x91\x4c\x4b\xe5\x1d\xca\xad\x8e\xd8\x23\x9c\xbb\xe9\x77\xa9\xf0\x9c\x02\x69\x83\x19\xd9\xfe\x2a\x8c\x6e\xb6\x0b\x79\x9f\x29\xae\x76\x59\x97\x0d\x2e\xbd\xff\x3c\x6c\xf7\x09\xbb\xf6\xf4\xbb\x55\xb9\xdf\x4f\x61\xa2\x41\xde\xc1\x44\xb5\x99\x3f\x08\x7e\x78\x4b\x97\xbe\x1e\x53\x60\x8c\x2e\x81\x7c\xe3\xd9\xaa\xf9\x14\xe6\xb7\x23\xf5\xb4\xaf\xff\xd2\xa6\xb9\xfe\x9d\x2d\x73\x91\x5c\x7a\xd1\xff\xb1\x3e\xfc\xb7\x3c\x56\x23\x81\x95\x64\x52\x03\x98\x4c\x99\xaa\xfd\x02\x35\xf7\x3b\x3f\x88\x2e\x07\x39\x39\xbf\x78\x66\x57\x28\x01\x38\xdb\x05\xb8\x6f\xcc\x94\x60\xb3\x85\xef\x45\x59\x20\x4e\xcd\x81\xe2\xf1\x2f\x5f\x06\x2a\xa4\x48\xdc\xcc\x82\xea\x8d\x89\x46\x6d\xd1\xbe\x46\xf8\x2c\x4f\x87\xbf\x0d\xb2\xb8\x78\xac\xbb\x0d\x91\x12\xc8\xdb\x6f\x51\xd3\x5f\x6d\x42\xf7\x49\x85\x6b\x99\xe5\x50\xb6\xc4\x54\xe9\xe8\xbe\x4d\xa1\x75\xf0\xb5\xe8\x6b\xe6\x6c\x97\x9f\xd8\x78\x23\x7e\x57\xf6\x91\xf0\xd2\xac\xd0\x28\xfb\xff\xa5\xb0\x66\x87\x75\x03\x4d\xb1\xf2\x1d\xdb\xe7\x11\x4e\xe3\xdc\x0b\x44\xda\xca\x64\xc5\xa0\x3a\x2f\xee\xae\xab\xeb\x70\x63\xbf\xcc\xcc\x55\x9b\xaf\x27\xf1\xcc\xb2\x20\x2f\xa4\xd1\xb2\xbf\x44\xc0\x4b\x2c\x2f\x81\xf9\x4e\x28\x1b\x1a\x5a\xdc\x85\x0d\xa1\xb9\x47\x9f\xca\xbd\xda\xde\xa5\x6a\x11\x5b\xb5\xf0\x6c\xc0\x16\xf1\x41\xc0\xfc\xb5\xe8\x3a\xb2\x48\xea\xec\x90\x15\x8d\x8b\xe6\x47\xaf\xf1\x2e\x7e\xeb\x5e\x57\xdb\xcc\x29\x3c\xb3\xb6\xaa\xcb\x55\x23\x6d\x4a\x83\x9a\x06\x20\xf4\x76\x23\x87\xdd\x17\x14\xdf\x5c\x13\x5e\x3d\x9d\x68\x24\xf9\x3b\x7c\x90\xd3\xae\x38\xc5\x18\xd6\x07\x12\x0c\x83\x95\x70\x41\x3b\x46\xb8\xcc\xd7\x37\x04\x92\xd8\xae\x5c\x60\x9e\x00\xcf\x82\x51\xe2\xe7\xdf\x81\xe5\xb4\xf9\xc1\x6a\x5a\x53\x9f\x0a\xfc\xce\x41\xbb\x43\x62\xe5\xea\xa5\xf9\x40\xa1\x70\x6f\x4a\xfb\x6b\x14\x43\x2c\x81\xd4\xba\x1a\x33\xd3\x22\xdb\xf1\x06\x45\xab\x63\x73\x7e\xad\xc8\x6f\xe6\xe0\x97\x6f\x76\x33\x97\xfb\x89\x86\x37\x59\x5d\xfd\x36\x93\x47\x92\xd7\x79\xe2\x4c\x2a\x3f\x0b\xac\xf5\x3e\x04\x73\xc5\xfd\xa9\xc6\x12\x84\xe4\x41\x9b\xdc\x0e\xef\x5d\x22\xf4\xd9\xbf\x42\xe8\xc0\x49\x33\xbb\x93\xb5\x3c\x29\x5d\x7a\xc9\x39\x5a\xbb\x6d\xcb\xd7\x42\xb1\xe1\xbc\x3b\x0e\xa4\x43\x4e\xa2\x1b\x8e\xca\x9a\xe6\x82\xd3\x31\x5a\x41\xe9\xc3\xc3\x37\x18\x40\x76\x1d\xc5\x9c\xac\x45\xda\x7e\x38\x13\xe2\x87\x88\xdc\x89\xde\x35\x5b\x5a\xee\x08\x80\x90\xa3\x8d\xd3\x9d\x83\xe5\xe4"}, +{{0xd7,0xfd,0x73,0xd1,0xd2,0x29,0xa6,0x58,0x94,0x42,0x0e,0x4b,0xa7,0x34,0x27,0x0d,0x5a,0x20,0x75,0x83,0x64,0xde,0x89,0x7d,0x85,0x55,0xe2,0x41,0x97,0x45,0x3c,0x19,},{0x3c,0x22,0x77,0x2a,0xec,0x0a,0x0c,0x15,0x59,0x07,0x7f,0x2c,0xfd,0x1f,0x24,0x65,0xd4,0xb4,0x84,0x95,0xc5,0xd0,0x5f,0x1f,0x83,0x7c,0x31,0x84,0x5f,0x34,0xca,0xd1,},{0x40,0x0c,0x35,0x05,0xf1,0xdf,0xa8,0x0d,0xf4,0xb2,0x6d,0xb2,0x4c,0x02,0x7e,0xb8,0x19,0x77,0xf0,0xfb,0x9b,0x5a,0xca,0x52,0x4a,0xd5,0x12,0x00,0xf4,0xbf,0xb1,0x33,0xdb,0x83,0x48,0x23,0x31,0x41,0x95,0xf4,0xed,0xc2,0x92,0xd5,0xf5,0x30,0xd0,0x85,0x56,0xe7,0x80,0x9c,0xaf,0x23,0x39,0x76,0x8a,0xa3,0x80,0x29,0xfd,0xbc,0x28,0x0f,},"\xc9\x22\x58\x59\xd5\x55\xbc\x42\x01\x1a\xf1\xb4\xf1\x49\x98\xe6\xe9\xb0\xa6\x5e\x21\x72\x71\x3e\x96\x83\x80\xfb\x6c\xee\xdd\xa2\x2e\x02\x2c\x51\x30\x30\x31\xd9\x93\x1c\xce\xf2\xf7\xbc\x70\x5c\x9e\x21\x5c\x1d\x08\x9d\x48\x8d\xad\xda\xee\x15\x5c\x93\x9b\x62\x02\xca\x53\xbf\xc7\xf6\xe8\x8e\x15\x29\xd8\x2f\xb4\x5e\x02\xb5\xd0\x5a\x82\xbb\xb9\xdb\x5f\x41\x5c\x58\xba\x8b\xd5\x6c\xff\xd9\x22\x70\xb2\x47\x49\xe5\x6d\x12\xc9\x9a\xe9\x0c\x78\x00\xf5\x4f\x55\x25\x4e\xa4\x2d\xa5\xdc\xfb\xe0\xe1\xd9\x89\xcd\x2f\x68\x97\xe2\x32\xdf\x04\x70\x7b\x34\xaf\x75\xfa\x7f\xec\x33\xe5\x5e\xd5\x6a\xee\x39\xc2\x2b\x04\x5b\xed\xd1\x61\x08\x3b\xc5\x51\x4c\x1f\x81\xca\x90\x7b\x7c\x76\x03\x17\xa7\xfd\x5a\x5a\x02\xa5\xd4\x0e\x2e\x82\x3e\x24\xad\x96\xae\xf6\xda\x8e\xa9\x82\xb5\x16\x1c\xc3\x9d\x84\xaa\x2f\xfd\x95\x44\xc1\x1b\x63\x40\x37\xab\x0a\x1c\x8e\x36\xac\x63\x01\x9d\xa1\xb2\xd9\x95\xcb\x7b\xd3\xd6\x2f\xe5\x74\xde\xab\xcc\xbd\x0d\x3a\xe7\xa5\x6e\x5b\xec\x91\xe4\xba\x3f\x3d\xb8\xbf\xea\x88\xe6\x7d\xa6\x2e\x88\x27\x8a\x6e\x3b\x41\x8d\xce\xea\x05\x89\xf2\x5f\x7d\xd8\xad\x19\xdd\x84\x50\x89\x41\x9b\x47\x2e\xfc\xcc\x87\x9c\x17\x2b\x32\xee\x4a\x4d\xbc\x2e\x6c\x2e\x86\x5b\xb3\xb8\xca\x0a\xdc\xb7\x1f\xdf\x89\xe1\x97\x39\x10\xef\x24\x29\x15\xf3\x3e\x23\x6d\x2f\x7c\x8e\x9f\x1e\xe5\xb0\x7c\x6e\x3c\x25\x36\x0f\x8c\xb1\x46\x0b\xe8\x7d\xb3\x1a\x29\x1d\x4d\xee\x34\x95\x3e\x75\xc6\x75\xbf\x18\x1b\xb7\xa0\xb7\xb5\xc1\xbe\xfd\xc8\x6a\xda\x07\x2a\x48\xf6\xac\x75\x5d\x49\x9b\xd6\x8d\x62\x5d\x85\x14\x52\x5c\xc3\xab\x8f\x54\xce\x15\xa8\x71\x29\x17\x78\xde\x13\x05\xd2\x21\x93\x61\xaa\x30\xe3\x32\xa2\xe0\x69\x07\x7c\x5c\x53\x45\x75\x20\x37\x9d\x8b\x90\xd2\x4b\xd8\xa3\xa7\x70\x0f\xf7\x66\x23\x1c\xb5\x69\x7f\x9a\xce\x52\x1a\x99\xe8\x96\xda\x54\xc4\x07\x93\xbc\x7c\x1f\xb1\x58\x4b\xb1\xc8\x61\x94\xd2\xfb\x7a\x4b\x80\x2f\x30\x88\x5e\x0e\xe8\xaf\x88\xd6\x88\x6e\x3a\x3a\x4d\x4c\x85\x46\x49\xcc\x01\xab\xdf\x35\x31\x9a\x08\x56\xcc\x65\xd0\x92\xa3\x86\xf8\x86\x96\x25\xcd\x0a\xca\xc0\x87\xe9\x35\x17\x90\xcc\xb4\xa8\x65\xf6\x51\xa8\x81\xc3\xeb\xf1\x09\x07\x27\x74\xf9\x40\xf5\xaa\x98\xa2\xa2\xaa\x3d\xd3\x66\x47\xd0\xde\x83\x00\x1a\xa7\xcd\xc0\x31\xcc\x4a\x4d\x75\xdc\x11\xce\x55\x16\x76\xa2\xad\x43\xa3\xf6\xa1\x6a\x4b\xc5\xae\xe8\x0e\x53\x64\x20\x60\x87\x36\x4e\xb8\xb2\xb1\x5f\xb7\x05\x38\x0a\x07\x2d\x7c\x8b\x51\x99\x59\x43\xaa\x76\x2e\x8d\xeb\x4c\x56\x8c\xda\xa1\x41\x1a\xb6\x8f\x28\x48\x9e\x13\x23\xbb\x61\x56\xce\x25\x00\xb0\x6e\x77\x93\xc5\x10\xa3\xde\x29\x15\x08\x40\xbf\xdb\x0b\x2b\x7b\x21\xc2\xbb\x8a\x77\x46\x16\x7c\x92\x9d\xd0\xad\xad\x44\xfe\xd8\xf3\x6e\x83\x81\xb3\x42\x08\x0b\x2a\x7d\x82\xa3\xf8\x1f\xf7\x26\x30\xcb\x78\xdf\x91\xf7\xb6\x5a\x44\xef\xf6\xed\x64\xd4\x8a\xfe\xd1\x09\xdd\x7a\x69\x3a\x1b\xa8\xc3\x7e\x00\x8f\xcb\x15\x7e\x37\x29\x7d\x32\xeb\xa7\x65\xa6\xc7\x19\x3e\x73\xbd\x97\x64\x79\x85\xb1\x60\x38\xc7\x4a\x08\x4a\x8f\x25\x65\x4c\xd8\xcd\x2c\xdd\x27\xff\x17\x33\x4e\x06\xad\xaa\x05\x82\x64\x01\x7a\x3b\x2d\xa7\x8e\x57\x38\xa2\x7e\x35\x0d\x88\x2f\x5f\xae\x19\x92\x78\xd4\xe5\x0b\x8b\xad\xf5\x7c\x21\x41\xdf\xdc\x3c\xff\x99\xdf\x5d\xe8\x6f\xec\x29\x3c\x76\xcb\x94\xb6\xb1\x9b\xa3\x03\x4e\x46\x0f\x84\xc2\x80\xa2\xe6\x41\x2f\xab\x56\x98\xce\x89\x02\x07\xca\xba\xbc\xa0\xa9\x5b\x5a\xd5\x33\xce\x11\x4b\xf7\x1a\x40\x4a\x87\x59\x0d\x35\xfa\x7c\xed\xba\x43\x13\x1c\x4e\xe9\x23\x44\x83\x9f\x25\xcb\xfa\xeb\x12\xae\xeb\xc8\x04\x08\x93\x95\x1a\x34\x6b\xd2\x8f\xdd\x16\x7b\xd2\x0f\x71\xa1\xe5\x9f\xb6\x0d\x55\xe1\xc5\x67\xf4\x78\xf0\x27\xcf\x67\x9a\x37\xd1\xd9\xdb\x86\x7e\x17\xbf\xdd\x60\xb3\x47\xd8\x9d\x32\x26\x39\xd3\x15\xbb\x7a\x2c\x91\x34\xf0\x0e\xa0\x3a\x36\x7f\x30\x5e\xa4\xd6\x0d\xc9\xd5\x67\xcf\x92\x48\x51\xe4\x69\xea\x95\x4e\xd3\xea\x63\xea\x86\x06\xf7\x9f\x07\x73\x39\xbf\xa2\xb5\x1a\xe4\x9b\xaa\x0f\xb2\x53\x77\x82\x1d\x7c\x11\xef\x9a\xd4\xbb\x4c\x0f\xe4\x89\xac\xba\xb0\xef\x00\x0d\x61\x8c\x7a\xf5\xef\xd2\x05\xd6\x85\x99\xfc\xbd\xd9\x5e\x28\xf8\x36\xe0\x91\x6f\x9f\xf5\x48\xd0\xba\x17\xda\x62\x53\x6e\x74\x64\x68\x01\xee\xb6\x12\x2b\xa3\x2c\x41\x07\x3a\xe0\x4e\x42\xc6\xc1\xd5\xd8\xd2\x29\x76\xa5\x62\x26\xdd\xf4\xb6\xac\x95\x45\x5f\xb5\x30\x99\xf2\x02\x15\xb2\xeb\xc9\x07"}, +{{0xfd,0xa7,0xcb,0x08,0x40,0x16,0xba,0x51,0x3c,0x7c,0x4f,0x8f,0x71,0x80,0x48,0x0b,0xb1,0x81,0xe9,0x56,0x95,0xea,0x68,0x73,0x7f,0xa3,0x4a,0x40,0xec,0xbd,0xf3,0xef,},{0xa2,0xde,0x3a,0x0e,0xf9,0x72,0x98,0xfd,0x71,0x61,0x06,0xe2,0xf3,0xf5,0x45,0x13,0x05,0x7a,0x40,0x07,0x2d,0x23,0x4c,0x35,0x18,0x15,0x4c,0x1b,0xd1,0x2d,0xe0,0x37,},{0x33,0x61,0x4b,0x7a,0x94,0xf7,0x5e,0x03,0x65,0x34,0xd7,0x6e,0x30,0x14,0x7e,0xcc,0xdd,0x2a,0x04,0xe0,0x0c,0xd4,0x70,0x4a,0xb6,0xe8,0x07,0xd6,0xa2,0xac,0xc1,0xe1,0xd9,0x63,0xb8,0xee,0xe0,0x81,0x0d,0x41,0x2d,0x9d,0x56,0xe5,0x45,0x56,0x30,0x2b,0x10,0x73,0x0c,0x15,0xab,0xf8,0x9c,0x29,0xa0,0x27,0x30,0x3e,0xa8,0x8a,0xe7,0x01,},"\xc2\x1b\xb3\xf8\xe3\x7b\xef\xa3\x67\xc9\x13\x67\x31\x01\xba\x30\xd3\xb5\xc7\x4b\xd8\xbd\xb0\x9c\xd2\x86\x40\x01\x2d\xb4\x11\x20\xc2\xbc\xc4\x08\x5d\xe2\xa0\xf9\x5c\x92\x15\xdd\xef\x8c\xb5\xfc\x8d\x8b\x12\x51\xb4\x15\x27\xc6\x7d\xfa\xa3\xf9\x5b\xa3\x57\x83\x91\xea\x5a\x66\x29\xa7\x33\x09\x5f\xd0\xa4\x3f\xdb\xa4\x0f\xfe\x26\x0f\xff\x82\xac\xee\x2e\xbe\x98\x0e\x9e\xce\xcc\xfe\x7e\x10\xb2\xed\x8c\x2e\x6b\x41\x0d\x54\x7a\x12\x86\x57\x1d\xf3\xd7\x01\x17\x4e\x57\x9f\xcf\x19\xd3\xbd\x80\x86\xc0\x42\x3f\x37\x11\x77\x89\xf3\x05\xd9\x67\x0a\xd2\x8c\x99\x67\x4f\x52\xcf\x64\x21\x1a\x08\x1d\x0c\x6c\x30\x96\xda\x2c\x71\xbf\x5f\x57\x99\xa7\x91\x0e\x6f\x38\x10\x4a\x37\xa6\x55\x7c\x2d\xae\xf3\x40\x81\x4a\x1f\x83\x0d\x59\x37\x73\xc6\xcf\x48\xd8\x3e\xa0\x72\x94\xb9\x4e\xb0\x80\xb8\x5d\x69\x70\xe2\x8f\x40\x51\xd5\x06\x6d\xb1\x0e\x96\x19\x73\xa6\x26\xa8\x26\xae\xaf\x8a\x06\xec\x0d\x56\x6b\x7e\x0c\x4e\xf6\x0f\x0c\x56\x78\xfc\xbb\x5b\x2a\xc6\x3f\x7b\xed\x06\x44\x8a\x24\x7b\x3d\x42\x7b\x87\x08\x6d\x33\x57\x3f\xb2\xd7\x22\x8c\x5c\x34\xea\x66\x40\xee\xfa\x95\x64\x48\x5a\x79\x63\x8e\x9c\x97\xc0\xaf\x84\xcf\xee\x7c\xe4\xa7\x39\x22\x0c\x84\x29\xe0\x67\x14\x39\x53\xd5\x50\x66\x8d\xad\xc8\x4e\x7b\xed\x9a\xb0\x70\xa5\x94\x33\x90\xc6\x11\xd7\x5b\x1c\xb1\x28\x73\xa3\x7d\x98\x50\x66\x1a\x00\x77\xbf\xa9\xca\x9b\x8b\x26\x37\x66\xc1\x49\xff\x0e\xe4\xb4\xad\xba\x25\xea\xf7\xd7\xf5\x01\xf3\x62\x45\x42\x56\xbc\x12\x69\x37\x8e\xf3\x35\x9a\x8e\xd6\xb9\x60\xb8\x66\x21\xfa\x3b\x61\x3e\xb1\x32\x12\x2f\x49\xf2\xeb\x2c\xeb\x68\x32\xa3\x99\x1e\x96\x1c\xb0\xe7\x8b\x74\x2e\xf4\xd6\x5e\x8d\xe3\x46\x96\x66\xfe\xc7\xc5\xb8\x74\x78\x95\x71\xc5\xc9\x9a\x2c\x02\xa0\x53\xff\x7d\x2f\xc9\x00\x76\xba\xfe\x1f\x26\x7f\xa8\x1a\x39\x90\xf2\x7f\xf1\x4f\x03\x00\x0a\xf0\x0c\x59\x28\x6c\xb9\xbb\x98\xe2\x04\xe9\x01\x90\xae\x2a\x50\xed\xef\x04\x9e\xa9\x2a\x1f\x78\x50\x88\xf9\x4a\xdf\x65\x88\xfb\x43\xbb\x40\xfb\xe2\x32\x42\x35\xcc\x7e\x16\x8b\x80\x26\x4b\x06\x9f\x94\x4f\x50\x36\x92\xc9\x49\x23\x4d\x5b\x76\xbc\xff\xab\xe2\x9f\xf9\x06\x4b\xd7\xcb\xed\x9e\x00\xe5\xb7\xfd\xda\x43\x12\xeb\x80\x14\x65\xf1\x27\xd0\xca\x68\x83\x2a\x7f\x4e\xd0\xea\xed\x8f\x55\x9c\x16\x31\xcd\x4d\x34\xf0\xdc\x41\x4d\x9f\xcf\xe8\x49\xa9\x1e\x25\xf3\xe0\xff\x01\x3a\x8c\xff\xa8\x06\xed\x8e\x93\xd0\x8a\x1e\x5a\x75\x76\x82\xca\x3d\x26\xab\xc8\x69\xc7\x6f\x1c\x79\x00\x7d\x55\x9d\xfe\x67\xe7\x8d\x8a\xf0\x19\x58\x08\xb0\xe7\x71\xc7\x1e\x64\xb5\x71\x6f\xb3\x63\x09\xc2\x50\x25\xfa\xe6\x41\x4c\x28\xbb\xdb\xd4\xde\x59\x7a\x74\x99\x6c\x9d\xa9\x74\x92\x0d\x59\xe6\xf4\xc2\xed\xfe\x11\x0f\xf8\x17\xfd\x48\x0a\x50\x80\x97\x80\x48\x86\x57\x12\x05\x8c\x5f\xe7\xb5\x60\xb1\x2b\x67\xf7\x37\xea\x6e\x2a\xf9\x24\x2c\xf0\x7a\xd0\xa8\xa6\x79\xf2\x64\x30\x04\x6a\xdc\x3e\x70\x66\x4c\xc9\xc0\xee\x5a\xbc\xef\x6d\x72\x6b\x4e\x04\x17\x60\x48\xb7\x95\xbe\x12\x85\x1b\xdb\x74\x00\x3a\x13\x20\x41\x19\xb8\x68\x64\xd6\x53\x5b\xa0\x95\x04\x0a\x85\xd9\x78\x1c\xf4\xf3\x48\x0a\x30\x4e\x22\x7f\x78\x7a\xd5\x38\xe6\x8f\x4b\xab\x01\x41\x79\xe3\x0d\x3f\xde\xf9\xef\xf1\x1b\xcf\x47\x1f\xa3\xa0\xbc\x74\xb5\x57\x6f\x30\x2d\x3a\x6b\x49\x9f\x11\xf2\xef\x32\x6a\xc0\x26\xc9\x8d\xb1\x0e\x27\x41\x41\x3f\x32\x22\x28\xb3\xcf\xf0\xf3\x37\xba\x2f\x29\x4c\x78\xef\x73\xf0\xe8\x77\x87\x8f\x8f\xc7\xff\x6d\x10\xbc\xe6\x6a\xd6\x28\x43\x79\xb8\x0c\xa8\x93\x27\xd4\xdb\x0b\xf1\x4e\x6d\x8f\x01\xb2\x2a\xb2\x02\xb7\x16\xcc\x07\xe3\xc8\x86\x6d\x16\x8a\x50\x94\xba\xc5\xa4\x95\xe7\x38\x68\xee\xdc\x27\x22\x2e\x64\x44\xf8\x3b\xcf\x65\xac\xdc\x3e\xc8\x91\x20\xbb\x50\xe8\xab\xfc\x28\xb7\x8e\x6d\x98\x0c\x77\x5f\x48\x49\xa0\xe8\xca\xda\x80\x24\x0b\xca\x24\x5e\x39\x96\x6e\x89\xa0\x34\x4d\xf8\x36\x3a\x7d\xcc\x81\xb2\x01\xce\x9c\x75\x3a\xd5\x44\xe1\x12\x4e\x21\x02\x0d\x4c\x62\xde\xda\x9e\xd9\xb9\xd1\xf2\xfb\x7c\x54\xca\x7a\xb0\x9f\x38\x3b\xef\x48\xcf\xc6\x84\x8c\x27\x13\x02\xa1\x0f\xa6\x87\xf5\x6e\x00\xe0\xa7\xd0\x93\xc9\x27\xb4\xfd\xd8\xf1\xbe\xdf\x62\x88\xa0\xe3\x02\x84\x8a\x80\x12\xf1\x27\xa7\x9d\x2d\x30\xa0\x6c\xe1\x7d\x94\xaa\x6f\x7f\x8a\x1e\x6e\xb9\xd0\x68\x1c\x37\x74\xf6\x14\xcc\x6d\xbc\xb2\xa8\x13\xf9\x25\xc6\x30\x6a\x63\x05\x72\xa8\x3e\xc1\x09\xd5\xf5\x33\xc0\x58\x4c\xb4\x21\xd9\x19"}, +{{0xa1,0xac,0x48,0xaa,0x5f,0xfa,0x3d,0x80,0x08,0x19,0xd0,0x3b,0x7f,0x62,0xba,0xbf,0x29,0x1f,0x20,0x90,0x4c,0x11,0xa6,0x40,0x0e,0x4f,0x45,0x20,0x5f,0x10,0x3e,0x38,},{0x08,0x54,0xe0,0x34,0x0f,0x81,0x49,0x85,0xfb,0x12,0x2b,0x78,0x72,0x94,0x79,0xe3,0xfd,0xe8,0x55,0xc2,0x11,0xca,0xde,0xae,0x56,0xf0,0xd4,0xdc,0x08,0x28,0xd5,0xfa,},{0xc5,0x7e,0x3c,0x09,0x1e,0xd2,0x4e,0x5e,0x84,0x66,0x5b,0xd9,0xbb,0x10,0x2d,0xb4,0x97,0x97,0xdf,0x90,0x08,0xf0,0x55,0x57,0xfa,0x0d,0x5a,0xd7,0xa2,0x95,0xe5,0xe4,0xd2,0xa4,0x71,0x6b,0x17,0xf8,0xc9,0x1c,0xb1,0x2f,0x5a,0xbf,0xb1,0xaf,0x02,0x7f,0xb0,0x41,0x11,0x99,0xac,0xc5,0xd2,0x85,0xd8,0x42,0xa4,0xb6,0x5b,0xde,0x49,0x02,},"\xd6\xf1\x24\xed\x75\x20\x21\xc1\x09\x26\x97\x2a\x0c\x26\xf3\xb1\x83\x8b\x3c\x7a\xf2\x47\xc1\x80\x09\xa2\x31\xec\xce\x96\x4b\xf6\x69\x86\x37\x83\x3f\x60\x7d\xca\x83\x6f\x8a\x60\x6c\x72\xae\x3c\xb1\x70\x17\x44\x47\xa2\xcc\xe5\x83\xf6\xe2\x44\xdb\xc1\x63\xe2\x15\xb9\x82\x0d\xe7\x49\x6f\xfc\x5b\x70\x50\xc4\x8f\x28\x30\x24\x66\x78\xcb\xa4\xdc\x5c\xaa\x07\xc1\x45\x85\x63\xaa\x2d\x10\xdc\xb7\x77\x0e\xf8\xfe\xde\x02\x7d\xd7\xf2\x0d\xdc\x8c\xc7\x8c\x3a\x2e\x2e\x95\x8b\xd1\x8c\x00\x06\xcf\x8f\xb8\x2d\x44\xe5\x3e\x1d\xa7\xaa\x80\xfd\x10\x06\xf3\xb2\x30\x0c\x9b\x07\x9d\x8a\x66\xf1\xe4\xa3\xf4\x70\x61\xf9\xe2\xf4\x5d\xae\x35\xdc\x29\x52\x04\xb1\x94\x60\xca\x57\x07\xab\x57\xce\x21\x5a\x24\xc1\x0f\xaa\xb3\xfa\x20\xbc\xcd\x10\x1e\x7a\x7d\x70\x07\x75\x99\xf3\xd6\x72\x57\x07\x55\x21\x29\xca\xd7\x57\xd6\x51\x4c\x1b\x28\x99\x7e\x47\x1f\x94\xb0\xfd\xed\x8f\xbb\xd0\x65\xde\xad\x19\x6d\x2c\x07\xd3\xdf\xa7\xb9\xfb\x3b\xae\x76\x80\xf7\x66\x21\x20\x0d\x09\x9e\xeb\xeb\xbe\xa0\xe8\x95\x7d\xf5\xb5\xe2\x04\xca\x3e\x9e\x29\x52\xb8\xa3\x0f\x0a\x13\x1a\x68\x67\xb1\x38\x1e\x39\x4b\x1b\x44\x43\x10\xf0\x76\x32\x66\x56\xcf\x93\x41\x67\x80\x08\xe9\x52\x51\x47\xd8\xd6\x1c\xe9\x3d\x3b\xf5\x39\x00\xca\xb9\x12\x66\x37\x17\xe0\x98\x72\x93\x83\x3d\x19\x02\xd7\xfb\x04\x7b\x99\x7b\x86\x02\x6c\x46\x7d\x7b\xb1\x7c\xf4\x57\x96\x73\x8f\x7a\x77\x4a\xc1\x26\x76\x4e\xd4\xeb\x45\x12\x43\x09\xf4\x58\x62\x60\x17\x6b\xa4\x65\x91\x8d\x48\x33\x0a\x9c\xc1\x8c\x4e\xce\xa0\xdd\xaf\x38\x94\x6a\xcc\x0e\x36\x1d\xd4\x0a\x7e\x91\x33\xce\xb5\x0e\x1c\x31\x7e\xa4\x2b\xd0\x98\x0a\x72\xb8\xba\x3d\x8a\x6c\x76\x93\xdd\x56\x02\xf3\x74\xf2\x66\x4d\xf4\xba\x56\xdf\x01\xe8\x82\xfc\xa4\x2c\xb4\xdb\x62\x1f\x47\x6c\x76\xe1\xea\x9f\xd1\x05\x91\x1a\x74\xb7\x79\x52\xd9\x91\x4a\x5a\xc0\xf9\x8a\x90\x0c\x1b\x2e\x1a\x56\xc4\xea\x85\x18\xa9\xee\x47\xc4\xed\x14\xd0\xbd\x35\xec\xa5\x60\x31\x9c\x8e\xa2\x47\x55\xd7\x1a\x4e\x03\x08\x50\xbc\x4d\xc6\x03\x89\xf3\x25\x80\x40\x21\x20\x4c\xce\xbc\x25\xfe\xdb\xd3\x2e\xdd\x8d\x84\x46\xaa\x23\xce\x56\xa8\x5f\x77\x9e\x85\x8d\x36\xaf\x7c\x07\x3c\x11\x5e\x34\x1f\x41\x2c\x66\x0f\xab\x80\x0f\xe7\x4c\x50\xe7\x14\xee\x08\x6e\x2f\xbc\x8d\x7a\xbb\xf3\xe9\x8f\xb4\x0c\xa2\x7f\x1f\x01\xa9\xaa\xdd\x8c\xc2\x27\x5c\x2d\xd3\xf7\x6e\x4c\x1d\x81\xc4\xb7\x92\xda\xec\xc9\xfe\x66\x04\x49\x41\xb8\xb2\x91\x84\x86\xdd\x4a\xcb\x56\x2a\x7b\x58\xad\x8c\x60\xc2\x1b\x83\xcf\x48\xae\xfa\x72\x56\xa1\xed\x80\x9e\x66\x98\x11\xf4\x84\x36\x49\x70\xbc\x56\x95\x08\x99\x19\xbc\x32\xd2\x8e\xa7\x52\xe8\xe3\x18\xce\xff\x46\x7f\x77\xae\x19\x77\xc5\xff\xd7\x9c\x17\xc2\xda\x8b\xc7\xf8\x23\xdd\x94\x39\x86\x83\x18\x99\x45\xf8\xb7\x92\x38\xa4\xe8\x15\xb1\x42\xb8\x66\xac\xbd\xbc\xb7\xae\xa7\xf1\x43\xff\xfb\x7c\xc2\xb4\xb5\x4b\xbf\x36\x1a\xfd\xa9\x13\xad\x6d\xf1\xe4\x9d\xfd\x6b\x53\x26\x42\xe6\x3f\x55\xd8\x93\xa4\x70\xd4\x03\x70\x66\x5c\xfb\x74\xef\xd3\xf5\x9c\xb0\xff\x60\x06\x17\x4c\xa3\x5f\x53\xb9\x7c\x54\x3e\x08\xaf\x4b\xf5\xbb\x75\xff\x90\x31\x61\x06\x52\xa3\xf6\xf2\xa0\xcf\xe9\x7e\x7a\x52\x1f\x3d\x2a\x28\x91\x14\xde\xd3\x47\x72\xb0\xe4\x98\x17\xbd\xe1\xcb\x92\x4f\xf5\x14\xe2\x86\x6a\x09\xe3\xed\xe0\x78\x2d\x2c\x0c\x98\xe6\x81\x4b\x8c\x1e\x77\x8c\xf8\x30\x63\x48\xc9\x33\xad\xb2\xe4\x72\xdb\xa0\x9d\xb9\x54\xff\x49\x64\x83\x73\x39\x5a\x2f\x01\x81\x95\x8f\xeb\x1e\xa2\x83\x4c\x99\x53\x28\x73\xdb\x5c\x88\xeb\x52\x89\xc7\x7e\x90\x01\x52\x03\xef\x50\x2a\xc8\xe1\xc4\x8f\xa1\xa0\x6d\xaf\xa6\x51\x9d\x52\xda\xe3\xc5\x56\x75\x70\xdd\x24\x34\xe6\x71\x92\x7c\x66\x36\x3f\x78\x31\x56\x89\x3f\x13\x8a\x84\xc7\x56\x64\xb3\x0a\xe4\x27\x51\x12\x73\x6d\x53\xd4\xf3\x99\xdd\xda\x3d\x23\x06\x7c\x07\x3f\x52\x1a\xfb\xa1\xf7\xbe\x58\x55\x13\xc2\xce\xc9\xc8\xf0\x8d\x2a\x22\xc3\xc8\x53\x92\xcd\x2a\xe5\x0f\x39\x28\x25\x1f\x86\xb3\x10\xc6\x9a\x0f\x8c\x4e\x85\x3a\xb3\xf3\xe8\x12\x9b\x05\x66\xef\x4b\xbb\xe8\x0b\x8c\x02\xc8\x92\x8a\x4d\xe5\x6c\x0d\x11\x9a\x45\xbb\xf5\xaf\x18\x08\xd4\x88\x85\x2d\x8a\x45\xbe\xb0\xd6\x83\x24\x8a\x4d\x65\xde\x15\x26\xb3\xd1\xd2\xff\xc1\xf2\x22\x15\xb6\x08\x46\x8c\xbc\x3b\xd3\x95\x14\xb3\x97\xfc\x0d\xb0\xf1\x13\xdb\xe6\xfc\xe4\x65\x2e\x82\xff\x89\x5b\x2b\x43\x87\xe0\x41\xd7\xe4\xe7\xbd\xe4\x69\x47\x69\x66\x5e\x81"}, +{{0xf5,0xe5,0x76,0x7c,0xf1,0x53,0x31,0x95,0x17,0x63,0x0f,0x22,0x68,0x76,0xb8,0x6c,0x81,0x60,0xcc,0x58,0x3b,0xc0,0x13,0x74,0x4c,0x6b,0xf2,0x55,0xf5,0xcc,0x0e,0xe5,},{0x27,0x81,0x17,0xfc,0x14,0x4c,0x72,0x34,0x0f,0x67,0xd0,0xf2,0x31,0x6e,0x83,0x86,0xce,0xff,0xbf,0x2b,0x24,0x28,0xc9,0xc5,0x1f,0xef,0x7c,0x59,0x7f,0x1d,0x42,0x6e,},{0x0a,0xab,0x4c,0x90,0x05,0x01,0xb3,0xe2,0x4d,0x7c,0xdf,0x46,0x63,0x32,0x6a,0x3a,0x87,0xdf,0x5e,0x48,0x43,0xb2,0xcb,0xdb,0x67,0xcb,0xf6,0xe4,0x60,0xfe,0xc3,0x50,0xaa,0x53,0x71,0xb1,0x50,0x8f,0x9f,0x45,0x28,0xec,0xea,0x23,0xc4,0x36,0xd9,0x4b,0x5e,0x8f,0xcd,0x4f,0x68,0x1e,0x30,0xa6,0xac,0x00,0xa9,0x70,0x4a,0x18,0x8a,0x03,},"\x08\xb8\xb2\xb7\x33\x42\x42\x43\x76\x0f\xe4\x26\xa4\xb5\x49\x08\x63\x21\x10\xa6\x6c\x2f\x65\x91\xea\xbd\x33\x45\xe3\xe4\xeb\x98\xfa\x6e\x26\x4b\xf0\x9e\xfe\x12\xee\x50\xf8\xf5\x4e\x9f\x77\xb1\xe3\x55\xf6\xc5\x05\x44\xe2\x3f\xb1\x43\x3d\xdf\x73\xbe\x84\xd8\x79\xde\x7c\x00\x46\xdc\x49\x96\xd9\xe7\x73\xf4\xbc\x9e\xfe\x57\x38\x82\x9a\xdb\x26\xc8\x1b\x37\xc9\x3a\x1b\x27\x0b\x20\x32\x9d\x65\x86\x75\xfc\x6e\xa5\x34\xe0\x81\x0a\x44\x32\x82\x6b\xf5\x8c\x94\x1e\xfb\x65\xd5\x7a\x33\x8b\xbd\x2e\x26\x64\x0f\x89\xff\xbc\x1a\x85\x8e\xfc\xb8\x55\x0e\xe3\xa5\xe1\x99\x8b\xd1\x77\xe9\x3a\x73\x63\xc3\x44\xfe\x6b\x19\x9e\xe5\xd0\x2e\x82\xd5\x22\xc4\xfe\xba\x15\x45\x2f\x80\x28\x8a\x82\x1a\x57\x91\x16\xec\x6d\xad\x2b\x3b\x31\x0d\xa9\x03\x40\x1a\xa6\x21\x00\xab\x5d\x1a\x36\x55\x3e\x06\x20\x3b\x33\x89\x0c\xc9\xb8\x32\xf7\x9e\xf8\x05\x60\xcc\xb9\xa3\x9c\xe7\x67\x96\x7e\xd6\x28\xc6\xad\x57\x3c\xb1\x16\xdb\xef\xef\xd7\x54\x99\xda\x96\xbd\x68\xa8\xa9\x7b\x92\x8a\x8b\xbc\x10\x3b\x66\x21\xfc\xde\x2b\xec\xa1\x23\x1d\x20\x6b\xe6\xcd\x9e\xc7\xaf\xf6\xf6\xc9\x4f\xcd\x72\x04\xed\x34\x55\xc6\x8c\x83\xf4\xa4\x1d\xa4\xaf\x2b\x74\xef\x5c\x53\xf1\xd8\xac\x70\xbd\xcb\x7e\xd1\x85\xce\x81\xbd\x84\x35\x9d\x44\x25\x4d\x95\x62\x9e\x98\x55\xa9\x4a\x7c\x19\x58\xd1\xf8\xad\xa5\xd0\x53\x2e\xd8\xa5\xaa\x3f\xb2\xd1\x7b\xa7\x0e\xb6\x24\x8e\x59\x4e\x1a\x22\x97\xac\xbb\xb3\x9d\x50\x2f\x1a\x8c\x6e\xb6\xf1\xce\x22\xb3\xde\x1a\x1f\x40\xcc\x24\x55\x41\x19\xa8\x31\xa9\xaa\xd6\x07\x9c\xad\x88\x42\x5d\xe6\xbd\xe1\xa9\x18\x7e\xbb\x60\x92\xcf\x67\xbf\x2b\x13\xfd\x65\xf2\x70\x88\xd7\x8b\x7e\x88\x3c\x87\x59\xd2\xc4\xf5\xc6\x5a\xdb\x75\x53\x87\x8a\xd5\x75\xf9\xfa\xd8\x78\xe8\x0a\x0c\x9b\xa6\x3b\xcb\xcc\x27\x32\xe6\x94\x85\xbb\xc9\xc9\x0b\xfb\xd6\x24\x81\xd9\x08\x9b\xec\xcf\x80\xcf\xe2\xdf\x16\xa2\xcf\x65\xbd\x92\xdd\x59\x7b\x07\x07\xe0\x91\x7a\xf4\x8b\xbb\x75\xfe\xd4\x13\xd2\x38\xf5\x55\x5a\x7a\x56\x9d\x80\xc3\x41\x4a\x8d\x08\x59\xdc\x65\xa4\x61\x28\xba\xb2\x7a\xf8\x7a\x71\x31\x4f\x31\x8c\x78\x2b\x23\xeb\xfe\x80\x8b\x82\xb0\xce\x26\x40\x1d\x2e\x22\xf0\x4d\x83\xd1\x25\x5d\xc5\x1a\xdd\xd3\xb7\x5a\x2b\x1a\xe0\x78\x45\x04\xdf\x54\x3a\xf8\x96\x9b\xe3\xea\x70\x82\xff\x7f\xc9\x88\x8c\x14\x4d\xa2\xaf\x58\x42\x9e\xc9\x60\x31\xdb\xca\xd3\xda\xd9\xaf\x0d\xcb\xaa\xaf\x26\x8c\xb8\xfc\xff\xea\xd9\x4f\x3c\x7c\xa4\x95\xe0\x56\xa9\xb4\x7a\xcd\xb7\x51\xfb\x73\xe6\x66\xc6\xc6\x55\xad\xe8\x29\x72\x97\xd0\x7a\xd1\xba\x5e\x43\xf1\xbc\xa3\x23\x01\x65\x13\x39\xe2\x29\x04\xcc\x8c\x42\xf5\x8c\x30\xc0\x4a\xaf\xdb\x03\x8d\xda\x08\x47\xdd\x98\x8d\xcd\xa6\xf3\xbf\xd1\x5c\x4b\x4c\x45\x25\x00\x4a\xa0\x6e\xef\xf8\xca\x61\x78\x3a\xac\xec\x57\xfb\x3d\x1f\x92\xb0\xfe\x2f\xd1\xa8\x5f\x67\x24\x51\x7b\x65\xe6\x14\xad\x68\x08\xd6\xf6\xee\x34\xdf\xf7\x31\x0f\xdc\x82\xae\xbf\xd9\x04\xb0\x1e\x1d\xc5\x4b\x29\x27\x09\x4b\x2d\xb6\x8d\x6f\x90\x3b\x68\x40\x1a\xde\xbf\x5a\x7e\x08\xd7\x8f\xf4\xef\x5d\x63\x65\x3a\x65\x04\x0c\xf9\xbf\xd4\xac\xa7\x98\x4a\x74\xd3\x71\x45\x98\x67\x80\xfc\x0b\x16\xac\x45\x16\x49\xde\x61\x88\xa7\xdb\xdf\x19\x1f\x64\xb5\xfc\x5e\x2a\xb4\x7b\x57\xf7\xf7\x27\x6c\xd4\x19\xc1\x7a\x3c\xa8\xe1\xb9\x39\xae\x49\xe4\x88\xac\xba\x6b\x96\x56\x10\xb5\x48\x01\x09\xc8\xb1\x7b\x80\xe1\xb7\xb7\x50\xdf\xc7\x59\x8d\x5d\x50\x11\xfd\x2d\xcc\x56\x00\xa3\x2e\xf5\xb5\x2a\x1e\xcc\x82\x0e\x30\x8a\xa3\x42\x72\x1a\xac\x09\x43\xbf\x66\x86\xb6\x4b\x25\x79\x37\x65\x04\xcc\xc4\x93\xd9\x7e\x6a\xed\x3f\xb0\xf9\xcd\x71\xa4\x3d\xd4\x97\xf0\x1f\x17\xc0\xe2\xcb\x37\x97\xaa\x2a\x2f\x25\x66\x56\x16\x8e\x6c\x49\x6a\xfc\x5f\xb9\x32\x46\xf6\xb1\x11\x63\x98\xa3\x46\xf1\xa6\x41\xf3\xb0\x41\xe9\x89\xf7\x91\x4f\x90\xcc\x2c\x7f\xff\x35\x78\x76\xe5\x06\xb5\x0d\x33\x4b\xa7\x7c\x22\x5b\xc3\x07\xba\x53\x71\x52\xf3\xf1\x61\x0e\x4e\xaf\xe5\x95\xf6\xd9\xd9\x0d\x11\xfa\xa9\x33\xa1\x5e\xf1\x36\x95\x46\x86\x8a\x7f\x3a\x45\xa9\x67\x68\xd4\x0f\xd9\xd0\x34\x12\xc0\x91\xc6\x31\x5c\xf4\xfd\xe7\xcb\x68\x60\x69\x37\x38\x0d\xb2\xea\xaa\x70\x7b\x4c\x41\x85\xc3\x2e\xdd\xcd\xd3\x06\x70\x5e\x4d\xc1\xff\xc8\x72\xee\xee\x47\x5a\x64\xdf\xac\x86\xab\xa4\x1c\x06\x18\x98\x3f\x87\x41\xc5\xef\x68\xd3\xa1\x01\xe8\xa3\xb8\xca\xc6\x0c\x90\x5c\x15\xfc\x91\x08\x40\xb9\x4c\x00\xa0\xb9\xd0"}, +}; + +static const unsigned char non_canonical_p[32] = { + 0xf6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f +}; + +static void add_l(unsigned char * const S) +{ + static const unsigned char l[32] = + { 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, + 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 }; + + sodium_add(S, l, sizeof l); +} + +int main(void) +{ + crypto_sign_state st; + unsigned char extracted_seed[crypto_sign_ed25519_SEEDBYTES]; + unsigned char extracted_pk[crypto_sign_ed25519_PUBLICKEYBYTES]; + unsigned char sig[crypto_sign_BYTES]; + unsigned char sm[1024 + crypto_sign_BYTES]; + unsigned char m[1024]; + unsigned char skpk[crypto_sign_SECRETKEYBYTES]; + unsigned char pk[crypto_sign_PUBLICKEYBYTES]; + unsigned char sk[crypto_sign_SECRETKEYBYTES]; + char sig_hex[crypto_sign_BYTES * 2 + 1]; + char pk_hex[crypto_sign_PUBLICKEYBYTES * 2 + 1]; + char sk_hex[crypto_sign_SECRETKEYBYTES * 2 + 1]; + unsigned long long siglen; + unsigned long long smlen; + unsigned long long mlen; + unsigned int i; + unsigned int j; + + memset(sig, 0, sizeof sig); + for (i = 0U; i < (sizeof test_data) / (sizeof test_data[0]); i++) { +#ifdef BROWSER_TESTS + if (i % 128U != 127U) { + continue; + } +#endif + memcpy(skpk, test_data[i].sk, crypto_sign_SEEDBYTES); + memcpy(skpk + crypto_sign_SEEDBYTES, test_data[i].pk, + crypto_sign_PUBLICKEYBYTES); + if (crypto_sign(sm, &smlen, (const unsigned char *)test_data[i].m, i, + skpk) != 0) { + printf("crypto_sign() failure: [%u]\n", i); + continue; + } + if (memcmp(test_data[i].sig, sm, crypto_sign_BYTES) != 0) { + printf("signature failure: [%u]\n", i); + continue; + } + if (crypto_sign_open(m, NULL, sm, smlen, test_data[i].pk) != 0) { + printf("crypto_sign_open() failure: [%u]\n", i); + continue; + } + add_l(sm + 32); +#ifndef ED25519_COMPAT + if (crypto_sign_open(m, &mlen, sm, smlen, test_data[i].pk) != -1) { + printf("crypto_sign_open(): signature [%u] is malleable\n", i); + continue; + } +#else + if (crypto_sign_open(m, &mlen, sm, smlen, test_data[i].pk) != 0) { + printf("crypto_sign_open(): signature [%u] is not malleable\n", i); + continue; + } +#endif + if (memcmp(test_data[i].m, m, (size_t)mlen) != 0) { + printf("message verification failure: [%u]\n", i); + continue; + } + sm[i + crypto_sign_BYTES - 1U]++; + if (crypto_sign_open(m, &mlen, sm, smlen, test_data[i].pk) == 0) { + printf("message can be forged: [%u]\n", i); + continue; + } + if (crypto_sign_open(m, &mlen, sm, i % crypto_sign_BYTES, + test_data[i].pk) == 0) { + printf("short signed message verifies: [%u]\n", + i % crypto_sign_BYTES); + continue; + } + if (crypto_sign_detached(sig, &siglen, + (const unsigned char *)test_data[i].m, i, skpk) + != 0) { + printf("detached signature failed: [%u]\n", i); + continue; + } + if (siglen == 0U || siglen > crypto_sign_BYTES) { + printf("detached signature has an unexpected length: [%u]\n", i); + continue; + } + if (memcmp(test_data[i].sig, sig, crypto_sign_BYTES) != 0) { + printf("detached signature failure: [%u]\n", i); + continue; + } + if (crypto_sign_verify_detached(sig, + (const unsigned char *)test_data[i].m, + i, test_data[i].pk) != 0) { + printf("detached signature verification failed: [%u]\n", i); + continue; + } + } + printf("%u tests\n", i); + + i--; + + memcpy(sm, test_data[i].m, i); + if (crypto_sign(sm, &smlen, sm, i, skpk) != 0) { + printf("crypto_sign() with overlap failed\n"); + } + if (crypto_sign_open(sm, &mlen, sm, smlen, test_data[i].pk) != 0) { + printf("crypto_sign_open() with overlap failed\n"); + } + if (memcmp(test_data[i].m, sm, (size_t)mlen) != 0) { + printf("crypto_sign_open() with overlap failed (content)\n"); + } + + for (j = 1U; j < 8U; j++) { + sig[63] ^= (j << 5); + if (crypto_sign_verify_detached(sig, + (const unsigned char *)test_data[i].m, + i, test_data[i].pk) != -1) { + printf("detached signature verification should have failed\n"); + continue; + } + sig[63] ^= (j << 5); + } + +#ifndef ED25519_COMPAT + if (crypto_sign_verify_detached(sig, + (const unsigned char *)test_data[i].m, + i, non_canonical_p) != -1) { + printf("detached signature verification with non-canonical key should have failed\n"); + } +#endif + memset(pk, 0, sizeof pk); + if (crypto_sign_verify_detached(sig, + (const unsigned char *)test_data[i].m, + i, pk) != -1) { + printf("detached signature verification should have failed\n"); + } + + memset(sig, 0xff, 32); + sig[0] = 0xdb; + if (crypto_sign_verify_detached(sig, + (const unsigned char *)test_data[i].m, + i, pk) != -1) { + printf("detached signature verification should have failed\n"); + } + assert(crypto_sign_detached(sig, NULL, + (const unsigned char *)test_data[i].m, i, skpk) == 0); + + sodium_hex2bin(pk, crypto_sign_PUBLICKEYBYTES, + "3eee494fb9eac773144e34b0c755affaf33ea782c0722e5ea8b150e61209ab36", + crypto_sign_PUBLICKEYBYTES * 2, NULL, NULL, NULL); + if (crypto_sign_verify_detached(sig, + (const unsigned char *)test_data[i].m, + i, pk) != -1) { + printf("signature with an invalid public key should have failed\n"); + } + + sodium_hex2bin(pk, crypto_sign_PUBLICKEYBYTES, + "0200000000000000000000000000000000000000000000000000000000000000", + crypto_sign_PUBLICKEYBYTES * 2, NULL, NULL, NULL); + if (crypto_sign_verify_detached(sig, + (const unsigned char *)test_data[i].m, + i, pk) != -1) { + printf("signature with an invalid public key should have failed\n"); + } + + sodium_hex2bin(pk, crypto_sign_PUBLICKEYBYTES, + "0500000000000000000000000000000000000000000000000000000000000000", + crypto_sign_PUBLICKEYBYTES * 2, NULL, NULL, NULL); + if (crypto_sign_verify_detached(sig, + (const unsigned char *)test_data[i].m, + i, pk) != -1) { + printf("signature with an invalid public key should have failed\n"); + } + + if (crypto_sign_seed_keypair(pk, sk, keypair_seed) != 0) { + printf("crypto_sign_seed_keypair() failure\n"); + return -1; + } + crypto_sign_init(&st); + crypto_sign_update(&st, (const unsigned char *)test_data[i].m, i); + crypto_sign_final_create(&st, sig, NULL, sk); + sodium_bin2hex(sig_hex, sizeof sig_hex, sig, sizeof sig); + printf("ed25519ph sig: [%s]\n", sig_hex); + + crypto_sign_init(&st); + crypto_sign_update(&st, (const unsigned char *)test_data[i].m, i); + if (crypto_sign_final_verify(&st, sig, pk) != 0) { + printf("ed5519ph verification failed\n"); + } + crypto_sign_init(&st); + crypto_sign_update(&st, (const unsigned char *)test_data[i].m, 0); + crypto_sign_update(&st, (const unsigned char *)test_data[i].m, i / 2); + crypto_sign_update(&st, ((const unsigned char *)test_data[i].m) + i / 2, + i - i / 2); + if (crypto_sign_final_verify(&st, sig, pk) != 0) { + printf("ed5519ph verification failed\n"); + } + sig[0]++; + if (crypto_sign_final_verify(&st, sig, pk) != -1) { + printf("ed5519ph verification could be forged\n"); + } + sig[0]--; + pk[0]++; + if (crypto_sign_final_verify(&st, sig, pk) != -1) { + printf("ed5519ph verification could be forged\n"); + } + sodium_hex2bin(sk, crypto_sign_SECRETKEYBYTES, + "833fe62409237b9d62ec77587520911e9a759cec1d19755b7da901b96dca3d42", + 2 * crypto_sign_SECRETKEYBYTES / 2, NULL, NULL, NULL); + sodium_hex2bin(pk, crypto_sign_PUBLICKEYBYTES, + "ec172b93ad5e563bf4932c70e1245034c35467ef2efd4d64ebf819683467e2bf", + 2 * crypto_sign_PUBLICKEYBYTES, NULL, NULL, NULL); + memcpy(sk + crypto_sign_SECRETKEYBYTES - crypto_sign_PUBLICKEYBYTES, + pk, crypto_sign_PUBLICKEYBYTES); + crypto_sign_init(&st); + crypto_sign_update(&st, (const unsigned char *) "abc", 3); + crypto_sign_final_create(&st, sig, &siglen, sk); + if (siglen == 0U || siglen > crypto_sign_BYTES) { + printf("ed25519ph signature has an unexpected length\n"); + } + sodium_bin2hex(sig_hex, sizeof sig_hex, sig, sizeof sig); + printf("ed25519ph tv sig: [%s]\n", sig_hex); + + crypto_sign_init(&st); + crypto_sign_update(&st, (const unsigned char *) "abc", 3); + if (crypto_sign_final_verify(&st, sig, pk) != 0) { + printf("ed25519ph verification failed\n"); + } + if (crypto_sign_keypair(pk, sk) != 0) { + printf("crypto_sign_keypair() failure\n"); + } + if (crypto_sign_seed_keypair(pk, sk, keypair_seed) != 0) { + printf("crypto_sign_seed_keypair() failure\n"); + return -1; + } + crypto_sign_ed25519_sk_to_seed(extracted_seed, sk); + if (memcmp(extracted_seed, keypair_seed, crypto_sign_ed25519_SEEDBYTES) + != 0) { + printf("crypto_sign_ed25519_sk_to_seed() failure\n"); + } + crypto_sign_ed25519_sk_to_pk(extracted_pk, sk); + if (memcmp(extracted_pk, pk, crypto_sign_ed25519_PUBLICKEYBYTES) != 0) { + printf("crypto_sign_ed25519_sk_to_pk() failure\n"); + } + sodium_bin2hex(pk_hex, sizeof pk_hex, pk, sizeof pk); + sodium_bin2hex(sk_hex, sizeof sk_hex, sk, sizeof sk); + + printf("pk: [%s]\n", pk_hex); + printf("sk: [%s]\n", sk_hex); + + assert(crypto_sign_bytes() > 0U); + assert(crypto_sign_seedbytes() > 0U); + assert(crypto_sign_publickeybytes() > 0U); + assert(crypto_sign_secretkeybytes() > 0U); + assert(crypto_sign_messagebytes_max() > 0U); + assert(strcmp(crypto_sign_primitive(), "ed25519") == 0); + assert(crypto_sign_bytes() == crypto_sign_ed25519_bytes()); + assert(crypto_sign_seedbytes() == crypto_sign_ed25519_seedbytes()); + assert(crypto_sign_messagebytes_max() == crypto_sign_ed25519_messagebytes_max()); + assert(crypto_sign_publickeybytes() + == crypto_sign_ed25519_publickeybytes()); + assert(crypto_sign_secretkeybytes() + == crypto_sign_ed25519_secretkeybytes()); + assert(crypto_sign_statebytes() == crypto_sign_ed25519ph_statebytes()); + +#ifdef ED25519_NONDETERMINISTIC + exit(0); +#endif + + return 0; +} diff --git a/external/src/libsodium/test/default/sign.exp b/external/src/libsodium/test/default/sign.exp new file mode 100644 index 0000000..1c4285f --- /dev/null +++ b/external/src/libsodium/test/default/sign.exp @@ -0,0 +1,5 @@ +1024 tests +ed25519ph sig: [10c5411e40bd10170fb890d4dfdb6d338c8cb11d2764a216ee54df10977dcdefd8ff755b1eeb3f16fce80e40e7aafc99083dbff43d5031baf04157b48423960d] +ed25519ph tv sig: [98a70222f0b8121aa9d30f813d683f809e462b469c7ff87639499bb94e6dae4131f85042463c2a355a2003d062adf5aaa10b8c61e636062aaad11c2a26083406] +pk: [b5076a8474a832daee4dd5b4040983b6623b5f344aca57d4d6ee4baf3f259e6e] +sk: [421151a459faeade3d247115f94aedae42318124095afabe4d1451a559faedeeb5076a8474a832daee4dd5b4040983b6623b5f344aca57d4d6ee4baf3f259e6e] diff --git a/external/src/libsodium/test/default/siphashx24.c b/external/src/libsodium/test/default/siphashx24.c new file mode 100644 index 0000000..8ece23e --- /dev/null +++ b/external/src/libsodium/test/default/siphashx24.c @@ -0,0 +1,33 @@ + +#define TEST_NAME "siphashx24" +#include "cmptest.h" + +#define MAXLEN 64 + +int +main(void) +{ + unsigned char in[MAXLEN]; + unsigned char out[crypto_shorthash_siphashx24_BYTES]; + unsigned char k[crypto_shorthash_siphashx24_KEYBYTES]; + size_t i; + size_t j; + + for (i = 0; i < crypto_shorthash_siphashx24_KEYBYTES; ++i) { + k[i] = (unsigned char) i; + } + for (i = 0; i < MAXLEN; ++i) { + in[i] = (unsigned char) i; + crypto_shorthash_siphashx24(out, in, (unsigned long long) i, k); + for (j = 0; j < crypto_shorthash_siphashx24_BYTES; ++j) { + printf("%02x", (unsigned int) out[j]); + } + printf("\n"); + } + assert(crypto_shorthash_siphashx24_KEYBYTES >= crypto_shorthash_siphash24_KEYBYTES); + assert(crypto_shorthash_siphashx24_BYTES > crypto_shorthash_siphash24_BYTES); + assert(crypto_shorthash_siphashx24_bytes() == crypto_shorthash_siphashx24_BYTES); + assert(crypto_shorthash_siphashx24_keybytes() == crypto_shorthash_siphashx24_KEYBYTES); + + return 0; +} diff --git a/external/src/libsodium/test/default/siphashx24.exp b/external/src/libsodium/test/default/siphashx24.exp new file mode 100644 index 0000000..7218445 --- /dev/null +++ b/external/src/libsodium/test/default/siphashx24.exp @@ -0,0 +1,64 @@ +a3817f04ba25a8e66df67214c7550293 +da87c1d86b99af44347659119b22fc45 +8177228da4a45dc7fca38bdef60affe4 +9c70b60c5267a94e5f33b6b02985ed51 +f88164c12d9c8faf7d0f6e7c7bcd5579 +1368875980776f8854527a07690e9627 +14eeca338b208613485ea0308fd7a15e +a1f1ebbed8dbc153c0b84aa61ff08239 +3b62a9ba6258f5610f83e264f31497b4 +264499060ad9baabc47f8b02bb6d71ed +00110dc378146956c95447d3f3d0fbba +0151c568386b6677a2b4dc6f81e5dc18 +d626b266905ef35882634df68532c125 +9869e247e9c08b10d029934fc4b952f7 +31fcefac66d7de9c7ec7485fe4494902 +5493e99933b0a8117e08ec0f97cfc3d9 +6ee2a4ca67b054bbfd3315bf85230577 +473d06e8738db89854c066c47ae47740 +a426e5e423bf4885294da481feaef723 +78017731cf65fab074d5208952512eb1 +9e25fc833f2290733e9344a5e83839eb +568e495abe525a218a2214cd3e071d12 +4a29b54552d16b9a469c10528eff0aae +c9d184ddd5a9f5e0cf8ce29a9abf691c +2db479ae78bd50d8882a8a178a6132ad +8ece5f042d5e447b5051b9eacb8d8f6f +9c0b53b4b3c307e87eaee08678141f66 +abf248af69a6eae4bfd3eb2f129eeb94 +0664da1668574b88b935f3027358aef4 +aa4b9dc4bf337de90cd4fd3c467c6ab7 +ea5c7f471faf6bde2b1ad7d4686d2287 +2939b0183223fafc1723de4f52c43d35 +7c3956ca5eeafc3e363e9d556546eb68 +77c6077146f01c32b6b69d5f4ea9ffcf +37a6986cb8847edf0925f0f1309b54de +a705f0e69da9a8f907241a2e923c8cc8 +3dc47d1f29c448461e9e76ed904f6711 +0d62bf01e6fc0e1a0d3c4751c5d3692b +8c03468bca7c669ee4fd5e084bbee7b5 +528a5bb93baf2c9c4473cce5d0d22bd9 +df6a301e95c95dad97ae0cc8c6913bd8 +801189902c857f39e73591285e70b6db +e617346ac9c231bb3650ae34ccca0c5b +27d93437efb721aa401821dcec5adf89 +89237d9ded9c5e78d8b1c9b166cc7342 +4a6d8091bf5e7d651189fa94a250b14c +0e33f96055e7ae893ffc0e3dcf492902 +e61c432b720b19d18ec8d84bdc63151b +f7e5aef549f782cf379055a608269b16 +438d030fd0b7a54fa837f2ad201a6403 +a590d3ee4fbf04e3247e0d27f286423f +5fe2c1a172fe93c4b15cd37caef9f538 +2c97325cbd06b36eb2133dd08b3a017c +92c814227a6bca949ff0659f002ad39e +dce850110bd8328cfbd50841d6911d87 +67f14984c7da791248e32bb5922583da +1938f2cf72d54ee97e94166fa91d2a36 +74481e9646ed49fe0f6224301604698e +57fca5de98a9d6d8006438d0583d8a1d +9fecde1cefdc1cbed4763674d9575359 +e3040c00eb28f15366ca73cbd872e740 +7697009a6a831dfecca91c5993670f7a +5853542321f567a005d547a4f04759bd +5150d1772f50834a503e069a973fbd7c diff --git a/external/src/libsodium/test/default/sodium_core.c b/external/src/libsodium/test/default/sodium_core.c new file mode 100644 index 0000000..a3985b0 --- /dev/null +++ b/external/src/libsodium/test/default/sodium_core.c @@ -0,0 +1,42 @@ + +#define TEST_NAME "sodium_core" +#include "cmptest.h" + +static void +misuse_handler(void) +{ + printf("misuse_handler()\n"); + exit(0); +} + +int +main(void) +{ + sodium_set_misuse_handler(NULL); + sodium_set_misuse_handler(misuse_handler); + sodium_set_misuse_handler(NULL); + + assert(sodium_init() == 1); + + (void) sodium_runtime_has_neon(); + (void) sodium_runtime_has_sse2(); + (void) sodium_runtime_has_sse3(); + (void) sodium_runtime_has_ssse3(); + (void) sodium_runtime_has_sse41(); + (void) sodium_runtime_has_avx(); + (void) sodium_runtime_has_avx2(); + (void) sodium_runtime_has_avx512f(); + (void) sodium_runtime_has_pclmul(); + (void) sodium_runtime_has_aesni(); + (void) sodium_runtime_has_rdrand(); + + sodium_set_misuse_handler(misuse_handler); +#ifndef __EMSCRIPTEN__ + sodium_misuse(); + printf("Misuse handler returned\n"); +#else + printf("misuse_handler()\n"); +#endif + + return 0; +} diff --git a/external/src/libsodium/test/default/sodium_core.exp b/external/src/libsodium/test/default/sodium_core.exp new file mode 100644 index 0000000..68a17b0 --- /dev/null +++ b/external/src/libsodium/test/default/sodium_core.exp @@ -0,0 +1 @@ +misuse_handler() diff --git a/external/src/libsodium/test/default/sodium_utils.c b/external/src/libsodium/test/default/sodium_utils.c new file mode 100644 index 0000000..844e16c --- /dev/null +++ b/external/src/libsodium/test/default/sodium_utils.c @@ -0,0 +1,224 @@ +#define TEST_NAME "sodium_utils" +#include "cmptest.h" + +int +main(void) +{ + unsigned char buf_add[1000]; + unsigned char buf1[1000]; + unsigned char buf2[1000]; + unsigned char buf1_rev[1000]; + unsigned char buf2_rev[1000]; + unsigned char nonce[24]; + char nonce_hex[49]; + unsigned char *bin_padded; + size_t bin_len, bin_len2; + size_t bin_padded_len; + size_t bin_padded_maxlen; + size_t blocksize; + unsigned int i; + unsigned int j; + + randombytes_buf(buf1, sizeof buf1); + memcpy(buf2, buf1, sizeof buf2); + printf("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1)); + sodium_memzero(buf1, 0U); + printf("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1)); + sodium_memzero(buf1, sizeof buf1 / 2); + printf("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1)); + printf("%d\n", sodium_memcmp(buf1, buf2, 0U)); + sodium_memzero(buf2, sizeof buf2 / 2); + printf("%d\n", sodium_memcmp(buf1, buf2, sizeof buf1)); + printf("%d\n", sodium_memcmp(buf1, guard_page, 0U)); + printf("%d\n", sodium_memcmp(guard_page, buf2, 0U)); + printf("%d\n", sodium_memcmp(guard_page, guard_page, 0U)); + sodium_memzero(guard_page, 0U); + + memset(nonce, 0, sizeof nonce); + sodium_increment(nonce, sizeof nonce); + printf("%s\n", + sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + memset(nonce, 255, sizeof nonce); + sodium_increment(nonce, sizeof nonce); + printf("%s\n", + sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + nonce[1] = 1U; + sodium_increment(nonce, sizeof nonce); + printf("%s\n", + sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + nonce[1] = 0U; + sodium_increment(nonce, sizeof nonce); + printf("%s\n", + sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + nonce[0] = 255U; + nonce[2] = 255U; + sodium_increment(nonce, sizeof nonce); + printf("%s\n", + sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + for (i = 0U; i < 1000U; i++) { + bin_len = (size_t) randombytes_uniform(sizeof buf1); + randombytes_buf(buf1, bin_len); + randombytes_buf(buf2, bin_len); + for (j = 0U; j < bin_len; j++) { + buf1_rev[bin_len - 1 - j] = buf1[j]; + buf2_rev[bin_len - 1 - j] = buf2[j]; + } + if (memcmp(buf1_rev, buf2_rev, bin_len) * + sodium_compare(buf1, buf2, bin_len) < 0) { + printf("sodium_compare() failure with length=%u\n", + (unsigned int) bin_len); + } + memcpy(buf1, buf2, bin_len); + if (sodium_compare(buf1, buf2, bin_len)) { + printf("sodium_compare() equality failure with length=%u\n", + (unsigned int) bin_len); + } + } + printf("%d\n", sodium_compare(buf1, NULL, 0U)); + printf("%d\n", sodium_compare(NULL, buf1, 0U)); + memset(buf1, 0, sizeof buf1); + if (sodium_is_zero(buf1, sizeof buf1) != 1) { + printf("sodium_is_zero() failed\n"); + } + for (i = 0U; i < sizeof buf1; i++) { + buf1[i]++; + if (sodium_is_zero(buf1, sizeof buf1) != 0) { + printf("sodium_is_zero() failed\n"); + } + buf1[i]--; + } + bin_len = randombytes_uniform(sizeof buf1); + randombytes_buf(buf1, bin_len); + memcpy(buf2, buf1, bin_len); + memset(buf_add, 0, bin_len); + j = randombytes_uniform(10000); + for (i = 0U; i < j; i++) { + sodium_increment(buf1, bin_len); + sodium_increment(buf_add, bin_len); + } + sodium_add(buf2, buf_add, bin_len); + if (sodium_compare(buf1, buf2, bin_len) != 0) { + printf("sodium_add() failed\n"); + } + bin_len = randombytes_uniform(sizeof buf1); + randombytes_buf(buf1, bin_len); + memcpy(buf2, buf1, bin_len); + memset(buf_add, 0xff, bin_len); + sodium_increment(buf2, bin_len); + sodium_increment(buf2, 0U); + sodium_add(buf2, buf_add, bin_len); + sodium_add(buf2, buf_add, 0U); + if (sodium_compare(buf1, buf2, bin_len) != 0) { + printf("sodium_add() failed\n"); + } + for (i = 0U; i < 1000U; i++) { + randombytes_buf(buf1, bin_len); + randombytes_buf(buf2, bin_len); + sodium_add(buf1, buf2, bin_len); + sodium_sub(buf1, buf2, bin_len); + sodium_sub(buf1, buf2, 0U); + if (sodium_is_zero(buf1, bin_len) && + !sodium_is_zero(buf1, bin_len)) { + printf("sodium_sub() failed\n"); + } + sodium_sub(buf1, buf1, bin_len); + if (!sodium_is_zero(buf1, bin_len)) { + printf("sodium_sub() failed\n"); + } + } + assert(sizeof nonce >= 24U); + memset(nonce, 0xfe, 24U); + memset(nonce, 0xff, 6U); + sodium_increment(nonce, 8U); + printf("%s\n", + sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + memset(nonce, 0xfe, 24U); + memset(nonce, 0xff, 10U); + sodium_increment(nonce, 12U); + printf("%s\n", + sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + memset(nonce, 0xff, 22U); + sodium_increment(nonce, 24U); + printf("%s\n", + sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + + assert(sizeof nonce >= 24U); + memset(nonce, 0xfe, 24U); + memset(nonce, 0xff, 6U); + sodium_add(nonce, nonce, 7U); + sodium_add(nonce, nonce, 8U); + printf("%s\n", + sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + memset(nonce, 0xfe, 24U); + memset(nonce, 0xff, 10U); + sodium_add(nonce, nonce, 11U); + sodium_add(nonce, nonce, 12U); + printf("%s\n", + sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + memset(nonce, 0xff, 22U); + sodium_add(nonce, nonce, 23U); + sodium_add(nonce, nonce, 24U); + printf("%s\n", + sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + sodium_add(nonce, nonce, 0U); + printf("%s\n", + sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + sodium_add(nonce, guard_page, 0U); + printf("%s\n", + sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + sodium_add(guard_page, nonce, 0U); + + sodium_sub(nonce, nonce, 0U); + printf("%s\n", + sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + sodium_sub(nonce, guard_page, 0U); + printf("%s\n", + sodium_bin2hex(nonce_hex, sizeof nonce_hex, nonce, sizeof nonce)); + sodium_sub(guard_page, nonce, 0U); + + randombytes_buf(buf1, 64U); + randombytes_buf(buf2, 64U); + memset(buf_add, 0, 64U); + sodium_add(buf_add, buf1, 64U); + assert(!sodium_is_zero(buf_add, 64U)); + sodium_add(buf_add, buf2, 64U); + assert(!sodium_is_zero(buf_add, 64U)); + sodium_sub(buf_add, buf1, 64U); + assert(!sodium_is_zero(buf_add, 64U)); + sodium_sub(buf_add, buf2, 64U); + assert(sodium_is_zero(buf_add, 64U)); + + for (i = 0; i < 2000U; i++) { + bin_len = randombytes_uniform(200U); + blocksize = 1U + randombytes_uniform(500U); + bin_padded_maxlen = bin_len + (blocksize - bin_len % blocksize); + bin_padded = (unsigned char *) sodium_malloc(bin_padded_maxlen); + randombytes_buf(bin_padded, bin_padded_maxlen); + + assert(sodium_pad(&bin_padded_len, bin_padded, bin_len, + blocksize, bin_padded_maxlen - 1U) == -1); + assert(sodium_pad(NULL, bin_padded, bin_len, + blocksize, bin_padded_maxlen + 1U) == 0); + assert(sodium_pad(&bin_padded_len, bin_padded, bin_len, + blocksize, bin_padded_maxlen + 1U) == 0); + assert(sodium_pad(&bin_padded_len, bin_padded, bin_len, + 0U, bin_padded_maxlen) == -1); + assert(sodium_pad(&bin_padded_len, bin_padded, bin_len, + blocksize, bin_padded_maxlen) == 0); + assert(bin_padded_len == bin_padded_maxlen); + + assert(sodium_unpad(&bin_len2, bin_padded, bin_padded_len, + bin_padded_len + 1U) == -1); + assert(sodium_unpad(&bin_len2, bin_padded, bin_padded_len, + 0U) == -1); + assert(sodium_unpad(&bin_len2, bin_padded, bin_padded_len, + blocksize) == 0); + assert(bin_len2 == bin_len); + + sodium_free(bin_padded); + } + + sodium_stackzero(512); + + return 0; +} diff --git a/external/src/libsodium/test/default/sodium_utils.exp b/external/src/libsodium/test/default/sodium_utils.exp new file mode 100644 index 0000000..c97a1db --- /dev/null +++ b/external/src/libsodium/test/default/sodium_utils.exp @@ -0,0 +1,25 @@ +0 +0 +-1 +0 +0 +0 +0 +0 +010000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000 +010100000000000000000000000000000000000000000000 +020000000000000000000000000000000000000000000000 +0001ff000000000000000000000000000000000000000000 +0 +0 +000000000000fffefefefefefefefefefefefefefefefefe +00000000000000000000fffefefefefefefefefefefefefe +00000000000000000000000000000000000000000000fffe +fcfffffffffffbfdfefefefefefefefefefefefefefefefe +fcfffffffffffffffffffbfdfefefefefefefefefefefefe +fcfffffffffffffffffffffffffffffffffffffffffffbfd +fcfffffffffffffffffffffffffffffffffffffffffffbfd +fcfffffffffffffffffffffffffffffffffffffffffffbfd +fcfffffffffffffffffffffffffffffffffffffffffffbfd +fcfffffffffffffffffffffffffffffffffffffffffffbfd diff --git a/external/src/libsodium/test/default/sodium_utils2.c b/external/src/libsodium/test/default/sodium_utils2.c new file mode 100644 index 0000000..bd72f36 --- /dev/null +++ b/external/src/libsodium/test/default/sodium_utils2.c @@ -0,0 +1,107 @@ + +#include +#include + +#include +#ifdef HAVE_CATCHABLE_SEGV +# include +#endif + +#define TEST_NAME "sodium_utils2" +#include "cmptest.h" + +#ifdef __SANITIZE_ADDRESS__ +# warning The sodium_utils2 test is expected to fail with address sanitizer +#endif + +#undef sodium_malloc +#undef sodium_free +#undef sodium_allocarray + +__attribute__((noreturn)) static void +segv_handler(int sig) +{ + (void) sig; + + printf("Intentional segfault / bus error caught\n"); + printf("OK\n"); +#ifdef SIG_DFL +# ifdef SIGSEGV + signal(SIGSEGV, SIG_DFL); +# endif +# ifdef SIGBUS + signal(SIGBUS, SIG_DFL); +# endif +# ifdef SIGABRT + signal(SIGABRT, SIG_DFL); +# endif +#endif + exit(0); +} + +int +main(void) +{ + void * buf; + size_t size; + unsigned int i; + + if (sodium_malloc(SIZE_MAX - 1U) != NULL) { + return 1; + } + if (sodium_malloc(0U) == NULL) { + return 1; + } + if (sodium_allocarray(SIZE_MAX / 2U + 1U, SIZE_MAX / 2U) != NULL) { + return 1; + } + sodium_free(sodium_allocarray(0U, 0U)); + sodium_free(sodium_allocarray(0U, 1U)); + sodium_free(sodium_allocarray(1U, 0U)); + + buf = sodium_allocarray(1000U, 50U); + memset(buf, 0, 50000U); + sodium_free(buf); + + sodium_free(sodium_malloc(0U)); + sodium_free(NULL); + for (i = 0U; i < 10000U; i++) { + size = 1U + randombytes_uniform(100000U); + buf = sodium_malloc(size); + assert(buf != NULL); + memset(buf, i, size); + sodium_mprotect_noaccess(buf); + sodium_free(buf); + } + printf("OK\n"); +#ifdef SIG_DFL +# ifdef SIGSEGV + signal(SIGSEGV, segv_handler); +# endif +# ifdef SIGBUS + signal(SIGBUS, segv_handler); +# endif +# ifdef SIGABRT + signal(SIGABRT, segv_handler); +# endif +#endif + size = 1U + randombytes_uniform(100000U); + buf = sodium_malloc(size); + assert(buf != NULL); + +/* old versions of asan emit a warning because they don't support mlock*() */ +#ifndef __SANITIZE_ADDRESS__ + sodium_mprotect_readonly(buf); + sodium_mprotect_readwrite(buf); +#endif + +#if defined(HAVE_CATCHABLE_SEGV) && !defined(__EMSCRIPTEN__) && !defined(__SANITIZE_ADDRESS__) + sodium_memzero(((unsigned char *) buf) + size, 1U); + sodium_mprotect_noaccess(buf); + sodium_free(buf); + printf("Overflow not caught\n"); +#else + segv_handler(0); +#endif + return 0; +} diff --git a/external/src/libsodium/test/default/sodium_utils2.exp b/external/src/libsodium/test/default/sodium_utils2.exp new file mode 100644 index 0000000..f796351 --- /dev/null +++ b/external/src/libsodium/test/default/sodium_utils2.exp @@ -0,0 +1,3 @@ +OK +Intentional segfault / bus error caught +OK diff --git a/external/src/libsodium/test/default/sodium_utils3.c b/external/src/libsodium/test/default/sodium_utils3.c new file mode 100644 index 0000000..3bba037 --- /dev/null +++ b/external/src/libsodium/test/default/sodium_utils3.c @@ -0,0 +1,74 @@ + +#include +#include + +#include +#ifdef HAVE_CATCHABLE_SEGV +# include +#endif + +#define TEST_NAME "sodium_utils3" +#include "cmptest.h" + +#ifdef __SANITIZE_ADDRESS__ +# warning The sodium_utils3 test is expected to fail with address sanitizer +#endif + +__attribute__((noreturn)) static void +segv_handler(int sig) +{ + (void) sig; + + printf("Intentional segfault / bus error caught\n"); + printf("OK\n"); +#ifdef SIG_DFL +# ifdef SIGSEGV + signal(SIGSEGV, SIG_DFL); +# endif +# ifdef SIGBUS + signal(SIGBUS, SIG_DFL); +# endif +# ifdef SIGABRT + signal(SIGABRT, SIG_DFL); +# endif +#endif + exit(0); +} + +int +main(void) +{ + void * buf; + size_t size; + +#ifdef SIG_DFL +# ifdef SIGSEGV + signal(SIGSEGV, segv_handler); +# endif +# ifdef SIGBUS + signal(SIGBUS, segv_handler); +# endif +# ifdef SIGABRT + signal(SIGABRT, segv_handler); +# endif +#endif + size = 1U + randombytes_uniform(100000U); + buf = sodium_malloc(size); + assert(buf != NULL); + +/* old versions of asan emit a warning because they don't support mlock*() */ +#ifndef __SANITIZE_ADDRESS__ + sodium_mprotect_noaccess(buf); + sodium_mprotect_readwrite(buf); +#endif + +#if defined(HAVE_CATCHABLE_SEGV) && !defined(__EMSCRIPTEN__) && !defined(__SANITIZE_ADDRESS__) + sodium_memzero(((unsigned char *) buf) - 8, 8U); + sodium_mprotect_readonly(buf); + sodium_free(buf); + printf("Underflow not caught\n"); +#else + segv_handler(0); +#endif + return 0; +} diff --git a/external/src/libsodium/test/default/sodium_utils3.exp b/external/src/libsodium/test/default/sodium_utils3.exp new file mode 100644 index 0000000..37e114f --- /dev/null +++ b/external/src/libsodium/test/default/sodium_utils3.exp @@ -0,0 +1,2 @@ +Intentional segfault / bus error caught +OK diff --git a/external/src/libsodium/test/default/sodium_version.c b/external/src/libsodium/test/default/sodium_version.c new file mode 100644 index 0000000..2a8fddb --- /dev/null +++ b/external/src/libsodium/test/default/sodium_version.c @@ -0,0 +1,18 @@ + +#define TEST_NAME "sodium_version" +#include "cmptest.h" + +int +main(void) +{ + printf("%d\n", sodium_version_string() != NULL); + printf("%d\n", sodium_library_version_major() > 0); + printf("%d\n", sodium_library_version_minor() >= 0); +#ifdef SODIUM_LIBRARY_MINIMAL + assert(sodium_library_minimal() == 1); +#else + assert(sodium_library_minimal() == 0); +#endif + + return 0; +} diff --git a/external/src/libsodium/test/default/sodium_version.exp b/external/src/libsodium/test/default/sodium_version.exp new file mode 100644 index 0000000..e8183f0 --- /dev/null +++ b/external/src/libsodium/test/default/sodium_version.exp @@ -0,0 +1,3 @@ +1 +1 +1 diff --git a/external/src/libsodium/test/default/stream.c b/external/src/libsodium/test/default/stream.c new file mode 100644 index 0000000..87ef371 --- /dev/null +++ b/external/src/libsodium/test/default/stream.c @@ -0,0 +1,84 @@ + +#define TEST_NAME "stream" +#include "cmptest.h" + +static const unsigned char firstkey[32] = { + 0x1b, 0x27, 0x55, 0x64, 0x73, 0xe9, 0x85, + 0xd4, 0x62, 0xcd, 0x51, 0x19, 0x7a, 0x9a, + 0x46, 0xc7, 0x60, 0x09, 0x54, 0x9e, 0xac, + 0x64, 0x74, 0xf2, 0x06, 0xc4, 0xee, 0x08, + 0x44, 0xf6, 0x83, 0x89 +}; + +static const unsigned char nonce[24] = { + 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, + 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8, + 0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, + 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 +}; + +int +main(void) +{ + unsigned char h[32]; + char *hex; + unsigned char *output; + size_t sizeof_hex = 17 * 64 * 2 + 1; + size_t sizeof_output = 4194304; + int i; + + output = (unsigned char *) sodium_malloc(sizeof_output); + hex = (char *) sodium_malloc(sizeof_hex); + + randombytes_buf(output, sizeof_output); + crypto_stream(output, sizeof_output, nonce, firstkey); + crypto_hash_sha256(h, output, sizeof_output); + sodium_bin2hex(hex, sizeof_hex, h, sizeof h); + printf("%s\n", hex); + + assert(sizeof_output > 4000); + + crypto_stream_xsalsa20_xor_ic(output, output, 4000, nonce, 0U, firstkey); + for (i = 0; i < 4000; i++) { + assert(output[i] == 0); + } + crypto_stream_xsalsa20_xor_ic(output, output, 4000, nonce, 1U, firstkey); + crypto_hash_sha256(h, output, sizeof_output); + sodium_bin2hex(hex, sizeof_hex, h, sizeof h); + printf("%s\n", hex); + + for (i = 0; i < 64; i++) { + memset(output, i, 64); + crypto_stream(output, (int) (i & 0xff), nonce, firstkey); + sodium_bin2hex(hex, sizeof_hex, output, 64); + printf("%s\n", hex); + } + + memset(output, 0, 192); + crypto_stream_xsalsa20_xor_ic(output, output, 192, nonce, + (1ULL << 32) - 1ULL, firstkey); + sodium_bin2hex(hex, 192 * 2 + 1, output, 192); + printf("%s\n", hex); + + for (i = 16; i > 0; i--) { + memset(output, 0, 17 * 64); + crypto_stream_xsalsa20_xor_ic(output, output, 17 * 64, nonce, + (1ULL << 32) - (unsigned long long) i, + firstkey); + sodium_bin2hex(hex, 2 * 17 * 64 + 1, output, 17 * 64); + printf("%s\n", hex); + } + + sodium_free(hex); + sodium_free(output); + + assert(crypto_stream_keybytes() > 0U); + assert(crypto_stream_noncebytes() > 0U); + assert(crypto_stream_messagebytes_max() > 0U); + assert(strcmp(crypto_stream_primitive(), "xsalsa20") == 0); + assert(crypto_stream_keybytes() == crypto_stream_xsalsa20_keybytes()); + assert(crypto_stream_noncebytes() == crypto_stream_xsalsa20_noncebytes()); + assert(crypto_stream_messagebytes_max() == crypto_stream_xsalsa20_messagebytes_max()); + + return 0; +} diff --git a/external/src/libsodium/test/default/stream.exp b/external/src/libsodium/test/default/stream.exp new file mode 100644 index 0000000..68ff67b --- /dev/null +++ b/external/src/libsodium/test/default/stream.exp @@ -0,0 +1,83 @@ +662b9d0e3463029156069b12f918691a98f7dfb2ca0393c96bbfc6b1fbd630a2 +0cc9ffaf60a99d221b548e9762385a231121ab226d1c610d2661ced26b6ad5ee +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +ee010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101 +eea60202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202 +eea6a703030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303 +eea6a725040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404 +eea6a7251c0505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505050505 +eea6a7251c1e06060606060606060606060606060606060606060606060606060606060606060606060606060606060606060606060606060606060606060606 +eea6a7251c1e72070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707070707 +eea6a7251c1e72910808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808 +eea6a7251c1e72916d09090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909090909 +eea6a7251c1e72916d110a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a0a +eea6a7251c1e72916d11c20b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b +eea6a7251c1e72916d11c2cb0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c +eea6a7251c1e72916d11c2cb210d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d +eea6a7251c1e72916d11c2cb214d0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e0e +eea6a7251c1e72916d11c2cb214d3c0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f +eea6a7251c1e72916d11c2cb214d3c25101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010 +eea6a7251c1e72916d11c2cb214d3c25251111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 +eea6a7251c1e72916d11c2cb214d3c25253912121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212 +eea6a7251c1e72916d11c2cb214d3c25253912131313131313131313131313131313131313131313131313131313131313131313131313131313131313131313 +eea6a7251c1e72916d11c2cb214d3c252539121d1414141414141414141414141414141414141414141414141414141414141414141414141414141414141414 +eea6a7251c1e72916d11c2cb214d3c252539121d8e15151515151515151515151515151515151515151515151515151515151515151515151515151515151515 +eea6a7251c1e72916d11c2cb214d3c252539121d8e23161616161616161616161616161616161616161616161616161616161616161616161616161616161616 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e1717171717171717171717171717171717171717171717171717171717171717171717171717171717 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e6518181818181818181818181818181818181818181818181818181818181818181818181818181818 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d191919191919191919191919191919191919191919191919191919191919191919191919191919 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a1a +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651f1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b1b +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa41c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c1c +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c81d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d1d +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cf1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e1e +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff81f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff8802020202020202020202020202020202020202020202020202020202020202020 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff8803021212121212121212121212121212121212121212121212121212121212121 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e222222222222222222222222222222222222222222222222222222222222 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e642323232323232323232323232323232323232323232323232323232323 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a24242424242424242424242424242424242424242424242424242424 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74252525252525252525252525252525252525252525252525252525 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e92626262626262626262626262626262626262626262626262626 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e027272727272727272727272727272727272727272727272727 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a6282828282828282828282828282828282828282828282828 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d2929292929292929292929292929292929292929292929 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d822a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a2a +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d82432b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243ac2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c2c +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd92d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d2d +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9172e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e2e +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177a2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f2f +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab530303030303030303030303030303030 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a313131313131313131313131313131 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a1b3232323232323232323232323232 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a1beb33333333333333333333333333 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a1beb8d343434343434343434343434 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a1beb8d5a3535353535353535353535 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a1beb8d5a2f36363636363636363636 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a1beb8d5a2f5d373737373737373737 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a1beb8d5a2f5d703838383838383838 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a1beb8d5a2f5d700c39393939393939 +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a1beb8d5a2f5d700c093a3a3a3a3a3a +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a1beb8d5a2f5d700c093c3b3b3b3b3b +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a1beb8d5a2f5d700c093c5e3c3c3c3c +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a1beb8d5a2f5d700c093c5e553d3d3d +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a1beb8d5a2f5d700c093c5e55853e3e +eea6a7251c1e72916d11c2cb214d3c252539121d8e234e652d651fa4c8cff880309e645a74e9e0a60d8243acd9177ab51a1beb8d5a2f5d700c093c5e5585573f +b46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44 +e825afc24db1b82ca241ef61bbd68003af106fbc07c41df1493b963b5ce45b72540ababca323c71ca3c903e1eec355121fbe9fad8bef90721c819eeba906ef7300b84696929a86d2a95aacebef2f38c489617398a39bc36762b5de6ccf544dde7fa47a839e3bf36903e3b7e9539c5c1c1794cfc991a414e2eef16bcf1b16d07cfb1ff0d77e5940a858f9025563334efeea808e3a82a54a0998e5587fddcb8b48e05de4cdb6ed1df7ddfca886d7122590844bc060178e13ba22a3c60f6fd53bb48f12931a32c81cbdde25e2fe3141682ff0443a9fb890e0520d328f91e19c4c0b0d05bd391351459dd5b15da237cfb3c36c95cfbfb076637b9181d9d9b42ae8ee3655eef4662a0c8737e5620ed7760a577afac32aa37baa35323a52287dfba632abcbff3e40aee172648c3d6f8e468262a49bbc2fb7876e97bb9d06ce6038e9eb425927287fb9ac67e41be494a883668602f4fcf76cc2c6bc62c3240bb63c233316630a645d5309af5c49813b8cc23e149ce40db089c7124431935e93fcc34dd1326fc6b1b8e71c37a3ee97a334f2c6bf579c5e986858a88b07136dd6b254543b16e14f38c7cb22cdb41a9028e3a6af9233c45ba06d1667746d48fc7b5c47601237fb2bde1e5a5551a1b4bf848734310103edb75a815e4ced8be43163ca13b3e399e91bf32b28de0b37c17d155f7129e23aec3deb2416122d7008a5684d5d0080f15e5eef787d292097cd781b3f95449b5f5a059a2cfbcd2cb10cc88a4759f2227f20d550c4cee567ab3e297191e8f1c3d537f1fc265c93ce900ae588d7d6a971cb0f0ae663a41347797bc4384568e439e10fa3cb24fefddf51202b17e35e5e3aba42fb067d15854bdeb400e8e96dfd097d5ffa793f3135cc819edefbf18c26c7e7a830988e8e1612a06c2d1f3bc03efb7ce5ca6538c4be7ba033a8f369fc479d527ca82cbc8198ef815ba7946fb7f4e7f503d280bddc767e39c4fb0ed54c86065a301ce502d083eeabcbcfd79dfc0de676d444c500d83d123367639d741e4fc4d87eea89f203fadd7e38f9a17b01a34ffe48f2469565751aca063c59614007c41aff83247f8daae106f5cd50177b4b98388e6963cf51baaa1de17e90831b5977016aa71973485b4d8524b7aa4f6b7e0a8d994662b922aaab519ab0f8e0d1513ccf9906615f1bb36a01a9916b27484414e3f3b559e52cf3380b422df71eda463fd1ef24a8d84e82d9718fb46d51d13687352ea76737209d618e77119b066161e2d93cc6ac5cb77a7a0d14988e3355e07a2f02bed2f8cec08807c544efd8ccc5ca3475e8be3143997d402aecfb56e80697f57179e6d631e38741ff3ef57a7ff80cb46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe +00b84696929a86d2a95aacebef2f38c489617398a39bc36762b5de6ccf544dde7fa47a839e3bf36903e3b7e9539c5c1c1794cfc991a414e2eef16bcf1b16d07cfb1ff0d77e5940a858f9025563334efeea808e3a82a54a0998e5587fddcb8b48e05de4cdb6ed1df7ddfca886d7122590844bc060178e13ba22a3c60f6fd53bb48f12931a32c81cbdde25e2fe3141682ff0443a9fb890e0520d328f91e19c4c0b0d05bd391351459dd5b15da237cfb3c36c95cfbfb076637b9181d9d9b42ae8ee3655eef4662a0c8737e5620ed7760a577afac32aa37baa35323a52287dfba632abcbff3e40aee172648c3d6f8e468262a49bbc2fb7876e97bb9d06ce6038e9eb425927287fb9ac67e41be494a883668602f4fcf76cc2c6bc62c3240bb63c233316630a645d5309af5c49813b8cc23e149ce40db089c7124431935e93fcc34dd1326fc6b1b8e71c37a3ee97a334f2c6bf579c5e986858a88b07136dd6b254543b16e14f38c7cb22cdb41a9028e3a6af9233c45ba06d1667746d48fc7b5c47601237fb2bde1e5a5551a1b4bf848734310103edb75a815e4ced8be43163ca13b3e399e91bf32b28de0b37c17d155f7129e23aec3deb2416122d7008a5684d5d0080f15e5eef787d292097cd781b3f95449b5f5a059a2cfbcd2cb10cc88a4759f2227f20d550c4cee567ab3e297191e8f1c3d537f1fc265c93ce900ae588d7d6a971cb0f0ae663a41347797bc4384568e439e10fa3cb24fefddf51202b17e35e5e3aba42fb067d15854bdeb400e8e96dfd097d5ffa793f3135cc819edefbf18c26c7e7a830988e8e1612a06c2d1f3bc03efb7ce5ca6538c4be7ba033a8f369fc479d527ca82cbc8198ef815ba7946fb7f4e7f503d280bddc767e39c4fb0ed54c86065a301ce502d083eeabcbcfd79dfc0de676d444c500d83d123367639d741e4fc4d87eea89f203fadd7e38f9a17b01a34ffe48f2469565751aca063c59614007c41aff83247f8daae106f5cd50177b4b98388e6963cf51baaa1de17e90831b5977016aa71973485b4d8524b7aa4f6b7e0a8d994662b922aaab519ab0f8e0d1513ccf9906615f1bb36a01a9916b27484414e3f3b559e52cf3380b422df71eda463fd1ef24a8d84e82d9718fb46d51d13687352ea76737209d618e77119b066161e2d93cc6ac5cb77a7a0d14988e3355e07a2f02bed2f8cec08807c544efd8ccc5ca3475e8be3143997d402aecfb56e80697f57179e6d631e38741ff3ef57a7ff80cb46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44 +fb1ff0d77e5940a858f9025563334efeea808e3a82a54a0998e5587fddcb8b48e05de4cdb6ed1df7ddfca886d7122590844bc060178e13ba22a3c60f6fd53bb48f12931a32c81cbdde25e2fe3141682ff0443a9fb890e0520d328f91e19c4c0b0d05bd391351459dd5b15da237cfb3c36c95cfbfb076637b9181d9d9b42ae8ee3655eef4662a0c8737e5620ed7760a577afac32aa37baa35323a52287dfba632abcbff3e40aee172648c3d6f8e468262a49bbc2fb7876e97bb9d06ce6038e9eb425927287fb9ac67e41be494a883668602f4fcf76cc2c6bc62c3240bb63c233316630a645d5309af5c49813b8cc23e149ce40db089c7124431935e93fcc34dd1326fc6b1b8e71c37a3ee97a334f2c6bf579c5e986858a88b07136dd6b254543b16e14f38c7cb22cdb41a9028e3a6af9233c45ba06d1667746d48fc7b5c47601237fb2bde1e5a5551a1b4bf848734310103edb75a815e4ced8be43163ca13b3e399e91bf32b28de0b37c17d155f7129e23aec3deb2416122d7008a5684d5d0080f15e5eef787d292097cd781b3f95449b5f5a059a2cfbcd2cb10cc88a4759f2227f20d550c4cee567ab3e297191e8f1c3d537f1fc265c93ce900ae588d7d6a971cb0f0ae663a41347797bc4384568e439e10fa3cb24fefddf51202b17e35e5e3aba42fb067d15854bdeb400e8e96dfd097d5ffa793f3135cc819edefbf18c26c7e7a830988e8e1612a06c2d1f3bc03efb7ce5ca6538c4be7ba033a8f369fc479d527ca82cbc8198ef815ba7946fb7f4e7f503d280bddc767e39c4fb0ed54c86065a301ce502d083eeabcbcfd79dfc0de676d444c500d83d123367639d741e4fc4d87eea89f203fadd7e38f9a17b01a34ffe48f2469565751aca063c59614007c41aff83247f8daae106f5cd50177b4b98388e6963cf51baaa1de17e90831b5977016aa71973485b4d8524b7aa4f6b7e0a8d994662b922aaab519ab0f8e0d1513ccf9906615f1bb36a01a9916b27484414e3f3b559e52cf3380b422df71eda463fd1ef24a8d84e82d9718fb46d51d13687352ea76737209d618e77119b066161e2d93cc6ac5cb77a7a0d14988e3355e07a2f02bed2f8cec08807c544efd8ccc5ca3475e8be3143997d402aecfb56e80697f57179e6d631e38741ff3ef57a7ff80cb46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44a8d40ce05f73fa3de1a92f948c38fe88a296db696a16742c5073aed1f26c6289675c28c763ab90a070b643ecf1c50f4165b82cf5b8eda4137903765f42cbaef5 +8f12931a32c81cbdde25e2fe3141682ff0443a9fb890e0520d328f91e19c4c0b0d05bd391351459dd5b15da237cfb3c36c95cfbfb076637b9181d9d9b42ae8ee3655eef4662a0c8737e5620ed7760a577afac32aa37baa35323a52287dfba632abcbff3e40aee172648c3d6f8e468262a49bbc2fb7876e97bb9d06ce6038e9eb425927287fb9ac67e41be494a883668602f4fcf76cc2c6bc62c3240bb63c233316630a645d5309af5c49813b8cc23e149ce40db089c7124431935e93fcc34dd1326fc6b1b8e71c37a3ee97a334f2c6bf579c5e986858a88b07136dd6b254543b16e14f38c7cb22cdb41a9028e3a6af9233c45ba06d1667746d48fc7b5c47601237fb2bde1e5a5551a1b4bf848734310103edb75a815e4ced8be43163ca13b3e399e91bf32b28de0b37c17d155f7129e23aec3deb2416122d7008a5684d5d0080f15e5eef787d292097cd781b3f95449b5f5a059a2cfbcd2cb10cc88a4759f2227f20d550c4cee567ab3e297191e8f1c3d537f1fc265c93ce900ae588d7d6a971cb0f0ae663a41347797bc4384568e439e10fa3cb24fefddf51202b17e35e5e3aba42fb067d15854bdeb400e8e96dfd097d5ffa793f3135cc819edefbf18c26c7e7a830988e8e1612a06c2d1f3bc03efb7ce5ca6538c4be7ba033a8f369fc479d527ca82cbc8198ef815ba7946fb7f4e7f503d280bddc767e39c4fb0ed54c86065a301ce502d083eeabcbcfd79dfc0de676d444c500d83d123367639d741e4fc4d87eea89f203fadd7e38f9a17b01a34ffe48f2469565751aca063c59614007c41aff83247f8daae106f5cd50177b4b98388e6963cf51baaa1de17e90831b5977016aa71973485b4d8524b7aa4f6b7e0a8d994662b922aaab519ab0f8e0d1513ccf9906615f1bb36a01a9916b27484414e3f3b559e52cf3380b422df71eda463fd1ef24a8d84e82d9718fb46d51d13687352ea76737209d618e77119b066161e2d93cc6ac5cb77a7a0d14988e3355e07a2f02bed2f8cec08807c544efd8ccc5ca3475e8be3143997d402aecfb56e80697f57179e6d631e38741ff3ef57a7ff80cb46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44a8d40ce05f73fa3de1a92f948c38fe88a296db696a16742c5073aed1f26c6289675c28c763ab90a070b643ecf1c50f4165b82cf5b8eda4137903765f42cbaef571f6303486a899aef83ca9c8c1e53af717293a6e219675aa1f479eac02d30df16649fc1c83b24855617385b5330b054c13f8fe8670ea2383552fe7fa096a6ff0 +3655eef4662a0c8737e5620ed7760a577afac32aa37baa35323a52287dfba632abcbff3e40aee172648c3d6f8e468262a49bbc2fb7876e97bb9d06ce6038e9eb425927287fb9ac67e41be494a883668602f4fcf76cc2c6bc62c3240bb63c233316630a645d5309af5c49813b8cc23e149ce40db089c7124431935e93fcc34dd1326fc6b1b8e71c37a3ee97a334f2c6bf579c5e986858a88b07136dd6b254543b16e14f38c7cb22cdb41a9028e3a6af9233c45ba06d1667746d48fc7b5c47601237fb2bde1e5a5551a1b4bf848734310103edb75a815e4ced8be43163ca13b3e399e91bf32b28de0b37c17d155f7129e23aec3deb2416122d7008a5684d5d0080f15e5eef787d292097cd781b3f95449b5f5a059a2cfbcd2cb10cc88a4759f2227f20d550c4cee567ab3e297191e8f1c3d537f1fc265c93ce900ae588d7d6a971cb0f0ae663a41347797bc4384568e439e10fa3cb24fefddf51202b17e35e5e3aba42fb067d15854bdeb400e8e96dfd097d5ffa793f3135cc819edefbf18c26c7e7a830988e8e1612a06c2d1f3bc03efb7ce5ca6538c4be7ba033a8f369fc479d527ca82cbc8198ef815ba7946fb7f4e7f503d280bddc767e39c4fb0ed54c86065a301ce502d083eeabcbcfd79dfc0de676d444c500d83d123367639d741e4fc4d87eea89f203fadd7e38f9a17b01a34ffe48f2469565751aca063c59614007c41aff83247f8daae106f5cd50177b4b98388e6963cf51baaa1de17e90831b5977016aa71973485b4d8524b7aa4f6b7e0a8d994662b922aaab519ab0f8e0d1513ccf9906615f1bb36a01a9916b27484414e3f3b559e52cf3380b422df71eda463fd1ef24a8d84e82d9718fb46d51d13687352ea76737209d618e77119b066161e2d93cc6ac5cb77a7a0d14988e3355e07a2f02bed2f8cec08807c544efd8ccc5ca3475e8be3143997d402aecfb56e80697f57179e6d631e38741ff3ef57a7ff80cb46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44a8d40ce05f73fa3de1a92f948c38fe88a296db696a16742c5073aed1f26c6289675c28c763ab90a070b643ecf1c50f4165b82cf5b8eda4137903765f42cbaef571f6303486a899aef83ca9c8c1e53af717293a6e219675aa1f479eac02d30df16649fc1c83b24855617385b5330b054c13f8fe8670ea2383552fe7fa096a6ff0d90d3922c26b77fb632041df8a3c585f295488aa98d73bc6a3a43eac5644b59440e02ed8a6b9a8acb9f33e732c1850ed6f811975a84b65cb8775df2f55f15f58 +425927287fb9ac67e41be494a883668602f4fcf76cc2c6bc62c3240bb63c233316630a645d5309af5c49813b8cc23e149ce40db089c7124431935e93fcc34dd1326fc6b1b8e71c37a3ee97a334f2c6bf579c5e986858a88b07136dd6b254543b16e14f38c7cb22cdb41a9028e3a6af9233c45ba06d1667746d48fc7b5c47601237fb2bde1e5a5551a1b4bf848734310103edb75a815e4ced8be43163ca13b3e399e91bf32b28de0b37c17d155f7129e23aec3deb2416122d7008a5684d5d0080f15e5eef787d292097cd781b3f95449b5f5a059a2cfbcd2cb10cc88a4759f2227f20d550c4cee567ab3e297191e8f1c3d537f1fc265c93ce900ae588d7d6a971cb0f0ae663a41347797bc4384568e439e10fa3cb24fefddf51202b17e35e5e3aba42fb067d15854bdeb400e8e96dfd097d5ffa793f3135cc819edefbf18c26c7e7a830988e8e1612a06c2d1f3bc03efb7ce5ca6538c4be7ba033a8f369fc479d527ca82cbc8198ef815ba7946fb7f4e7f503d280bddc767e39c4fb0ed54c86065a301ce502d083eeabcbcfd79dfc0de676d444c500d83d123367639d741e4fc4d87eea89f203fadd7e38f9a17b01a34ffe48f2469565751aca063c59614007c41aff83247f8daae106f5cd50177b4b98388e6963cf51baaa1de17e90831b5977016aa71973485b4d8524b7aa4f6b7e0a8d994662b922aaab519ab0f8e0d1513ccf9906615f1bb36a01a9916b27484414e3f3b559e52cf3380b422df71eda463fd1ef24a8d84e82d9718fb46d51d13687352ea76737209d618e77119b066161e2d93cc6ac5cb77a7a0d14988e3355e07a2f02bed2f8cec08807c544efd8ccc5ca3475e8be3143997d402aecfb56e80697f57179e6d631e38741ff3ef57a7ff80cb46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44a8d40ce05f73fa3de1a92f948c38fe88a296db696a16742c5073aed1f26c6289675c28c763ab90a070b643ecf1c50f4165b82cf5b8eda4137903765f42cbaef571f6303486a899aef83ca9c8c1e53af717293a6e219675aa1f479eac02d30df16649fc1c83b24855617385b5330b054c13f8fe8670ea2383552fe7fa096a6ff0d90d3922c26b77fb632041df8a3c585f295488aa98d73bc6a3a43eac5644b59440e02ed8a6b9a8acb9f33e732c1850ed6f811975a84b65cb8775df2f55f15f58af8a27936cf507dcc7ec480ffce410373c81374fddcbad758a1976894d58e68d84f3da8a0bbbfd3d62d09679378ee94686866e0ef101e05ccb7cc8fdf6f31cbb +326fc6b1b8e71c37a3ee97a334f2c6bf579c5e986858a88b07136dd6b254543b16e14f38c7cb22cdb41a9028e3a6af9233c45ba06d1667746d48fc7b5c47601237fb2bde1e5a5551a1b4bf848734310103edb75a815e4ced8be43163ca13b3e399e91bf32b28de0b37c17d155f7129e23aec3deb2416122d7008a5684d5d0080f15e5eef787d292097cd781b3f95449b5f5a059a2cfbcd2cb10cc88a4759f2227f20d550c4cee567ab3e297191e8f1c3d537f1fc265c93ce900ae588d7d6a971cb0f0ae663a41347797bc4384568e439e10fa3cb24fefddf51202b17e35e5e3aba42fb067d15854bdeb400e8e96dfd097d5ffa793f3135cc819edefbf18c26c7e7a830988e8e1612a06c2d1f3bc03efb7ce5ca6538c4be7ba033a8f369fc479d527ca82cbc8198ef815ba7946fb7f4e7f503d280bddc767e39c4fb0ed54c86065a301ce502d083eeabcbcfd79dfc0de676d444c500d83d123367639d741e4fc4d87eea89f203fadd7e38f9a17b01a34ffe48f2469565751aca063c59614007c41aff83247f8daae106f5cd50177b4b98388e6963cf51baaa1de17e90831b5977016aa71973485b4d8524b7aa4f6b7e0a8d994662b922aaab519ab0f8e0d1513ccf9906615f1bb36a01a9916b27484414e3f3b559e52cf3380b422df71eda463fd1ef24a8d84e82d9718fb46d51d13687352ea76737209d618e77119b066161e2d93cc6ac5cb77a7a0d14988e3355e07a2f02bed2f8cec08807c544efd8ccc5ca3475e8be3143997d402aecfb56e80697f57179e6d631e38741ff3ef57a7ff80cb46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44a8d40ce05f73fa3de1a92f948c38fe88a296db696a16742c5073aed1f26c6289675c28c763ab90a070b643ecf1c50f4165b82cf5b8eda4137903765f42cbaef571f6303486a899aef83ca9c8c1e53af717293a6e219675aa1f479eac02d30df16649fc1c83b24855617385b5330b054c13f8fe8670ea2383552fe7fa096a6ff0d90d3922c26b77fb632041df8a3c585f295488aa98d73bc6a3a43eac5644b59440e02ed8a6b9a8acb9f33e732c1850ed6f811975a84b65cb8775df2f55f15f58af8a27936cf507dcc7ec480ffce410373c81374fddcbad758a1976894d58e68d84f3da8a0bbbfd3d62d09679378ee94686866e0ef101e05ccb7cc8fdf6f31cbbf757c4d17aa607bc1decad9a65b8120adb7ef3b9d18a9c07226adf6f73f93c2ff79956f5e19b7c613dff1e907a8381863eb9ca536b44a3034cd522d6caa1766e +37fb2bde1e5a5551a1b4bf848734310103edb75a815e4ced8be43163ca13b3e399e91bf32b28de0b37c17d155f7129e23aec3deb2416122d7008a5684d5d0080f15e5eef787d292097cd781b3f95449b5f5a059a2cfbcd2cb10cc88a4759f2227f20d550c4cee567ab3e297191e8f1c3d537f1fc265c93ce900ae588d7d6a971cb0f0ae663a41347797bc4384568e439e10fa3cb24fefddf51202b17e35e5e3aba42fb067d15854bdeb400e8e96dfd097d5ffa793f3135cc819edefbf18c26c7e7a830988e8e1612a06c2d1f3bc03efb7ce5ca6538c4be7ba033a8f369fc479d527ca82cbc8198ef815ba7946fb7f4e7f503d280bddc767e39c4fb0ed54c86065a301ce502d083eeabcbcfd79dfc0de676d444c500d83d123367639d741e4fc4d87eea89f203fadd7e38f9a17b01a34ffe48f2469565751aca063c59614007c41aff83247f8daae106f5cd50177b4b98388e6963cf51baaa1de17e90831b5977016aa71973485b4d8524b7aa4f6b7e0a8d994662b922aaab519ab0f8e0d1513ccf9906615f1bb36a01a9916b27484414e3f3b559e52cf3380b422df71eda463fd1ef24a8d84e82d9718fb46d51d13687352ea76737209d618e77119b066161e2d93cc6ac5cb77a7a0d14988e3355e07a2f02bed2f8cec08807c544efd8ccc5ca3475e8be3143997d402aecfb56e80697f57179e6d631e38741ff3ef57a7ff80cb46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44a8d40ce05f73fa3de1a92f948c38fe88a296db696a16742c5073aed1f26c6289675c28c763ab90a070b643ecf1c50f4165b82cf5b8eda4137903765f42cbaef571f6303486a899aef83ca9c8c1e53af717293a6e219675aa1f479eac02d30df16649fc1c83b24855617385b5330b054c13f8fe8670ea2383552fe7fa096a6ff0d90d3922c26b77fb632041df8a3c585f295488aa98d73bc6a3a43eac5644b59440e02ed8a6b9a8acb9f33e732c1850ed6f811975a84b65cb8775df2f55f15f58af8a27936cf507dcc7ec480ffce410373c81374fddcbad758a1976894d58e68d84f3da8a0bbbfd3d62d09679378ee94686866e0ef101e05ccb7cc8fdf6f31cbbf757c4d17aa607bc1decad9a65b8120adb7ef3b9d18a9c07226adf6f73f93c2ff79956f5e19b7c613dff1e907a8381863eb9ca536b44a3034cd522d6caa1766eda2dadd40a0f32380a30c0a0be3ad991007c8778ec855f0c2e9869718f07562ef2bce1d6fa7b551454eda2f86a514d0cd754188715d5f73cbe47d940b8a98a2d +f15e5eef787d292097cd781b3f95449b5f5a059a2cfbcd2cb10cc88a4759f2227f20d550c4cee567ab3e297191e8f1c3d537f1fc265c93ce900ae588d7d6a971cb0f0ae663a41347797bc4384568e439e10fa3cb24fefddf51202b17e35e5e3aba42fb067d15854bdeb400e8e96dfd097d5ffa793f3135cc819edefbf18c26c7e7a830988e8e1612a06c2d1f3bc03efb7ce5ca6538c4be7ba033a8f369fc479d527ca82cbc8198ef815ba7946fb7f4e7f503d280bddc767e39c4fb0ed54c86065a301ce502d083eeabcbcfd79dfc0de676d444c500d83d123367639d741e4fc4d87eea89f203fadd7e38f9a17b01a34ffe48f2469565751aca063c59614007c41aff83247f8daae106f5cd50177b4b98388e6963cf51baaa1de17e90831b5977016aa71973485b4d8524b7aa4f6b7e0a8d994662b922aaab519ab0f8e0d1513ccf9906615f1bb36a01a9916b27484414e3f3b559e52cf3380b422df71eda463fd1ef24a8d84e82d9718fb46d51d13687352ea76737209d618e77119b066161e2d93cc6ac5cb77a7a0d14988e3355e07a2f02bed2f8cec08807c544efd8ccc5ca3475e8be3143997d402aecfb56e80697f57179e6d631e38741ff3ef57a7ff80cb46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44a8d40ce05f73fa3de1a92f948c38fe88a296db696a16742c5073aed1f26c6289675c28c763ab90a070b643ecf1c50f4165b82cf5b8eda4137903765f42cbaef571f6303486a899aef83ca9c8c1e53af717293a6e219675aa1f479eac02d30df16649fc1c83b24855617385b5330b054c13f8fe8670ea2383552fe7fa096a6ff0d90d3922c26b77fb632041df8a3c585f295488aa98d73bc6a3a43eac5644b59440e02ed8a6b9a8acb9f33e732c1850ed6f811975a84b65cb8775df2f55f15f58af8a27936cf507dcc7ec480ffce410373c81374fddcbad758a1976894d58e68d84f3da8a0bbbfd3d62d09679378ee94686866e0ef101e05ccb7cc8fdf6f31cbbf757c4d17aa607bc1decad9a65b8120adb7ef3b9d18a9c07226adf6f73f93c2ff79956f5e19b7c613dff1e907a8381863eb9ca536b44a3034cd522d6caa1766eda2dadd40a0f32380a30c0a0be3ad991007c8778ec855f0c2e9869718f07562ef2bce1d6fa7b551454eda2f86a514d0cd754188715d5f73cbe47d940b8a98a2de9cb66cba3830b2e732aa836df30b279f434ac98182114990d0b8d423813f75b5527dfa7982a167712380786bda08836976c21358a0d50e735f3efcb59ff69ac +cb0f0ae663a41347797bc4384568e439e10fa3cb24fefddf51202b17e35e5e3aba42fb067d15854bdeb400e8e96dfd097d5ffa793f3135cc819edefbf18c26c7e7a830988e8e1612a06c2d1f3bc03efb7ce5ca6538c4be7ba033a8f369fc479d527ca82cbc8198ef815ba7946fb7f4e7f503d280bddc767e39c4fb0ed54c86065a301ce502d083eeabcbcfd79dfc0de676d444c500d83d123367639d741e4fc4d87eea89f203fadd7e38f9a17b01a34ffe48f2469565751aca063c59614007c41aff83247f8daae106f5cd50177b4b98388e6963cf51baaa1de17e90831b5977016aa71973485b4d8524b7aa4f6b7e0a8d994662b922aaab519ab0f8e0d1513ccf9906615f1bb36a01a9916b27484414e3f3b559e52cf3380b422df71eda463fd1ef24a8d84e82d9718fb46d51d13687352ea76737209d618e77119b066161e2d93cc6ac5cb77a7a0d14988e3355e07a2f02bed2f8cec08807c544efd8ccc5ca3475e8be3143997d402aecfb56e80697f57179e6d631e38741ff3ef57a7ff80cb46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44a8d40ce05f73fa3de1a92f948c38fe88a296db696a16742c5073aed1f26c6289675c28c763ab90a070b643ecf1c50f4165b82cf5b8eda4137903765f42cbaef571f6303486a899aef83ca9c8c1e53af717293a6e219675aa1f479eac02d30df16649fc1c83b24855617385b5330b054c13f8fe8670ea2383552fe7fa096a6ff0d90d3922c26b77fb632041df8a3c585f295488aa98d73bc6a3a43eac5644b59440e02ed8a6b9a8acb9f33e732c1850ed6f811975a84b65cb8775df2f55f15f58af8a27936cf507dcc7ec480ffce410373c81374fddcbad758a1976894d58e68d84f3da8a0bbbfd3d62d09679378ee94686866e0ef101e05ccb7cc8fdf6f31cbbf757c4d17aa607bc1decad9a65b8120adb7ef3b9d18a9c07226adf6f73f93c2ff79956f5e19b7c613dff1e907a8381863eb9ca536b44a3034cd522d6caa1766eda2dadd40a0f32380a30c0a0be3ad991007c8778ec855f0c2e9869718f07562ef2bce1d6fa7b551454eda2f86a514d0cd754188715d5f73cbe47d940b8a98a2de9cb66cba3830b2e732aa836df30b279f434ac98182114990d0b8d423813f75b5527dfa7982a167712380786bda08836976c21358a0d50e735f3efcb59ff69ace37ddc48ef2b83bcc1931cf6673dfa726ac5229b83be548b60416ed5c7daf3a3201db9aadd1ffe632a7d3012d94668d5191010dd35d8ba9dc881005e112f2808 +e7a830988e8e1612a06c2d1f3bc03efb7ce5ca6538c4be7ba033a8f369fc479d527ca82cbc8198ef815ba7946fb7f4e7f503d280bddc767e39c4fb0ed54c86065a301ce502d083eeabcbcfd79dfc0de676d444c500d83d123367639d741e4fc4d87eea89f203fadd7e38f9a17b01a34ffe48f2469565751aca063c59614007c41aff83247f8daae106f5cd50177b4b98388e6963cf51baaa1de17e90831b5977016aa71973485b4d8524b7aa4f6b7e0a8d994662b922aaab519ab0f8e0d1513ccf9906615f1bb36a01a9916b27484414e3f3b559e52cf3380b422df71eda463fd1ef24a8d84e82d9718fb46d51d13687352ea76737209d618e77119b066161e2d93cc6ac5cb77a7a0d14988e3355e07a2f02bed2f8cec08807c544efd8ccc5ca3475e8be3143997d402aecfb56e80697f57179e6d631e38741ff3ef57a7ff80cb46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44a8d40ce05f73fa3de1a92f948c38fe88a296db696a16742c5073aed1f26c6289675c28c763ab90a070b643ecf1c50f4165b82cf5b8eda4137903765f42cbaef571f6303486a899aef83ca9c8c1e53af717293a6e219675aa1f479eac02d30df16649fc1c83b24855617385b5330b054c13f8fe8670ea2383552fe7fa096a6ff0d90d3922c26b77fb632041df8a3c585f295488aa98d73bc6a3a43eac5644b59440e02ed8a6b9a8acb9f33e732c1850ed6f811975a84b65cb8775df2f55f15f58af8a27936cf507dcc7ec480ffce410373c81374fddcbad758a1976894d58e68d84f3da8a0bbbfd3d62d09679378ee94686866e0ef101e05ccb7cc8fdf6f31cbbf757c4d17aa607bc1decad9a65b8120adb7ef3b9d18a9c07226adf6f73f93c2ff79956f5e19b7c613dff1e907a8381863eb9ca536b44a3034cd522d6caa1766eda2dadd40a0f32380a30c0a0be3ad991007c8778ec855f0c2e9869718f07562ef2bce1d6fa7b551454eda2f86a514d0cd754188715d5f73cbe47d940b8a98a2de9cb66cba3830b2e732aa836df30b279f434ac98182114990d0b8d423813f75b5527dfa7982a167712380786bda08836976c21358a0d50e735f3efcb59ff69ace37ddc48ef2b83bcc1931cf6673dfa726ac5229b83be548b60416ed5c7daf3a3201db9aadd1ffe632a7d3012d94668d5191010dd35d8ba9dc881005e112f28083f085c8094de717acd2516b631760110c176bff91d3e8cd4d2df79f79d450e54a5007e34caf791d9ac10aa98f45e52d987addf59f4beb5e62ef59e2e1b199413 +5a301ce502d083eeabcbcfd79dfc0de676d444c500d83d123367639d741e4fc4d87eea89f203fadd7e38f9a17b01a34ffe48f2469565751aca063c59614007c41aff83247f8daae106f5cd50177b4b98388e6963cf51baaa1de17e90831b5977016aa71973485b4d8524b7aa4f6b7e0a8d994662b922aaab519ab0f8e0d1513ccf9906615f1bb36a01a9916b27484414e3f3b559e52cf3380b422df71eda463fd1ef24a8d84e82d9718fb46d51d13687352ea76737209d618e77119b066161e2d93cc6ac5cb77a7a0d14988e3355e07a2f02bed2f8cec08807c544efd8ccc5ca3475e8be3143997d402aecfb56e80697f57179e6d631e38741ff3ef57a7ff80cb46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44a8d40ce05f73fa3de1a92f948c38fe88a296db696a16742c5073aed1f26c6289675c28c763ab90a070b643ecf1c50f4165b82cf5b8eda4137903765f42cbaef571f6303486a899aef83ca9c8c1e53af717293a6e219675aa1f479eac02d30df16649fc1c83b24855617385b5330b054c13f8fe8670ea2383552fe7fa096a6ff0d90d3922c26b77fb632041df8a3c585f295488aa98d73bc6a3a43eac5644b59440e02ed8a6b9a8acb9f33e732c1850ed6f811975a84b65cb8775df2f55f15f58af8a27936cf507dcc7ec480ffce410373c81374fddcbad758a1976894d58e68d84f3da8a0bbbfd3d62d09679378ee94686866e0ef101e05ccb7cc8fdf6f31cbbf757c4d17aa607bc1decad9a65b8120adb7ef3b9d18a9c07226adf6f73f93c2ff79956f5e19b7c613dff1e907a8381863eb9ca536b44a3034cd522d6caa1766eda2dadd40a0f32380a30c0a0be3ad991007c8778ec855f0c2e9869718f07562ef2bce1d6fa7b551454eda2f86a514d0cd754188715d5f73cbe47d940b8a98a2de9cb66cba3830b2e732aa836df30b279f434ac98182114990d0b8d423813f75b5527dfa7982a167712380786bda08836976c21358a0d50e735f3efcb59ff69ace37ddc48ef2b83bcc1931cf6673dfa726ac5229b83be548b60416ed5c7daf3a3201db9aadd1ffe632a7d3012d94668d5191010dd35d8ba9dc881005e112f28083f085c8094de717acd2516b631760110c176bff91d3e8cd4d2df79f79d450e54a5007e34caf791d9ac10aa98f45e52d987addf59f4beb5e62ef59e2e1b1994131fa61652a5574f50fa159d47f8f28776e25e21b51103b91afc8345cfbedf46586e17269bfb521ae07f2cd202d308110abcb2b6f0157a55bc6aa6936812c1074d +1aff83247f8daae106f5cd50177b4b98388e6963cf51baaa1de17e90831b5977016aa71973485b4d8524b7aa4f6b7e0a8d994662b922aaab519ab0f8e0d1513ccf9906615f1bb36a01a9916b27484414e3f3b559e52cf3380b422df71eda463fd1ef24a8d84e82d9718fb46d51d13687352ea76737209d618e77119b066161e2d93cc6ac5cb77a7a0d14988e3355e07a2f02bed2f8cec08807c544efd8ccc5ca3475e8be3143997d402aecfb56e80697f57179e6d631e38741ff3ef57a7ff80cb46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44a8d40ce05f73fa3de1a92f948c38fe88a296db696a16742c5073aed1f26c6289675c28c763ab90a070b643ecf1c50f4165b82cf5b8eda4137903765f42cbaef571f6303486a899aef83ca9c8c1e53af717293a6e219675aa1f479eac02d30df16649fc1c83b24855617385b5330b054c13f8fe8670ea2383552fe7fa096a6ff0d90d3922c26b77fb632041df8a3c585f295488aa98d73bc6a3a43eac5644b59440e02ed8a6b9a8acb9f33e732c1850ed6f811975a84b65cb8775df2f55f15f58af8a27936cf507dcc7ec480ffce410373c81374fddcbad758a1976894d58e68d84f3da8a0bbbfd3d62d09679378ee94686866e0ef101e05ccb7cc8fdf6f31cbbf757c4d17aa607bc1decad9a65b8120adb7ef3b9d18a9c07226adf6f73f93c2ff79956f5e19b7c613dff1e907a8381863eb9ca536b44a3034cd522d6caa1766eda2dadd40a0f32380a30c0a0be3ad991007c8778ec855f0c2e9869718f07562ef2bce1d6fa7b551454eda2f86a514d0cd754188715d5f73cbe47d940b8a98a2de9cb66cba3830b2e732aa836df30b279f434ac98182114990d0b8d423813f75b5527dfa7982a167712380786bda08836976c21358a0d50e735f3efcb59ff69ace37ddc48ef2b83bcc1931cf6673dfa726ac5229b83be548b60416ed5c7daf3a3201db9aadd1ffe632a7d3012d94668d5191010dd35d8ba9dc881005e112f28083f085c8094de717acd2516b631760110c176bff91d3e8cd4d2df79f79d450e54a5007e34caf791d9ac10aa98f45e52d987addf59f4beb5e62ef59e2e1b1994131fa61652a5574f50fa159d47f8f28776e25e21b51103b91afc8345cfbedf46586e17269bfb521ae07f2cd202d308110abcb2b6f0157a55bc6aa6936812c1074dcd3dc1365d431608687e158b5b3622375e0ddda9cfccb2f16b4a966fc3ecababaa3ea4f8311b37c4578c4692a0d2bdd251c18a886c9b48671531db2759828959 +cf9906615f1bb36a01a9916b27484414e3f3b559e52cf3380b422df71eda463fd1ef24a8d84e82d9718fb46d51d13687352ea76737209d618e77119b066161e2d93cc6ac5cb77a7a0d14988e3355e07a2f02bed2f8cec08807c544efd8ccc5ca3475e8be3143997d402aecfb56e80697f57179e6d631e38741ff3ef57a7ff80cb46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44a8d40ce05f73fa3de1a92f948c38fe88a296db696a16742c5073aed1f26c6289675c28c763ab90a070b643ecf1c50f4165b82cf5b8eda4137903765f42cbaef571f6303486a899aef83ca9c8c1e53af717293a6e219675aa1f479eac02d30df16649fc1c83b24855617385b5330b054c13f8fe8670ea2383552fe7fa096a6ff0d90d3922c26b77fb632041df8a3c585f295488aa98d73bc6a3a43eac5644b59440e02ed8a6b9a8acb9f33e732c1850ed6f811975a84b65cb8775df2f55f15f58af8a27936cf507dcc7ec480ffce410373c81374fddcbad758a1976894d58e68d84f3da8a0bbbfd3d62d09679378ee94686866e0ef101e05ccb7cc8fdf6f31cbbf757c4d17aa607bc1decad9a65b8120adb7ef3b9d18a9c07226adf6f73f93c2ff79956f5e19b7c613dff1e907a8381863eb9ca536b44a3034cd522d6caa1766eda2dadd40a0f32380a30c0a0be3ad991007c8778ec855f0c2e9869718f07562ef2bce1d6fa7b551454eda2f86a514d0cd754188715d5f73cbe47d940b8a98a2de9cb66cba3830b2e732aa836df30b279f434ac98182114990d0b8d423813f75b5527dfa7982a167712380786bda08836976c21358a0d50e735f3efcb59ff69ace37ddc48ef2b83bcc1931cf6673dfa726ac5229b83be548b60416ed5c7daf3a3201db9aadd1ffe632a7d3012d94668d5191010dd35d8ba9dc881005e112f28083f085c8094de717acd2516b631760110c176bff91d3e8cd4d2df79f79d450e54a5007e34caf791d9ac10aa98f45e52d987addf59f4beb5e62ef59e2e1b1994131fa61652a5574f50fa159d47f8f28776e25e21b51103b91afc8345cfbedf46586e17269bfb521ae07f2cd202d308110abcb2b6f0157a55bc6aa6936812c1074dcd3dc1365d431608687e158b5b3622375e0ddda9cfccb2f16b4a966fc3ecababaa3ea4f8311b37c4578c4692a0d2bdd251c18a886c9b48671531db27598289593cf82813da4f43eb854142ef39c4e5950f86b29e291737413396ae4c62f4472fe12659e12b61b84619a96b03a386dd6adb6b74ce09bc11330482e01564d3eb1a +d93cc6ac5cb77a7a0d14988e3355e07a2f02bed2f8cec08807c544efd8ccc5ca3475e8be3143997d402aecfb56e80697f57179e6d631e38741ff3ef57a7ff80cb46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44a8d40ce05f73fa3de1a92f948c38fe88a296db696a16742c5073aed1f26c6289675c28c763ab90a070b643ecf1c50f4165b82cf5b8eda4137903765f42cbaef571f6303486a899aef83ca9c8c1e53af717293a6e219675aa1f479eac02d30df16649fc1c83b24855617385b5330b054c13f8fe8670ea2383552fe7fa096a6ff0d90d3922c26b77fb632041df8a3c585f295488aa98d73bc6a3a43eac5644b59440e02ed8a6b9a8acb9f33e732c1850ed6f811975a84b65cb8775df2f55f15f58af8a27936cf507dcc7ec480ffce410373c81374fddcbad758a1976894d58e68d84f3da8a0bbbfd3d62d09679378ee94686866e0ef101e05ccb7cc8fdf6f31cbbf757c4d17aa607bc1decad9a65b8120adb7ef3b9d18a9c07226adf6f73f93c2ff79956f5e19b7c613dff1e907a8381863eb9ca536b44a3034cd522d6caa1766eda2dadd40a0f32380a30c0a0be3ad991007c8778ec855f0c2e9869718f07562ef2bce1d6fa7b551454eda2f86a514d0cd754188715d5f73cbe47d940b8a98a2de9cb66cba3830b2e732aa836df30b279f434ac98182114990d0b8d423813f75b5527dfa7982a167712380786bda08836976c21358a0d50e735f3efcb59ff69ace37ddc48ef2b83bcc1931cf6673dfa726ac5229b83be548b60416ed5c7daf3a3201db9aadd1ffe632a7d3012d94668d5191010dd35d8ba9dc881005e112f28083f085c8094de717acd2516b631760110c176bff91d3e8cd4d2df79f79d450e54a5007e34caf791d9ac10aa98f45e52d987addf59f4beb5e62ef59e2e1b1994131fa61652a5574f50fa159d47f8f28776e25e21b51103b91afc8345cfbedf46586e17269bfb521ae07f2cd202d308110abcb2b6f0157a55bc6aa6936812c1074dcd3dc1365d431608687e158b5b3622375e0ddda9cfccb2f16b4a966fc3ecababaa3ea4f8311b37c4578c4692a0d2bdd251c18a886c9b48671531db27598289593cf82813da4f43eb854142ef39c4e5950f86b29e291737413396ae4c62f4472fe12659e12b61b84619a96b03a386dd6adb6b74ce09bc11330482e01564d3eb1a688a80b912ad6d8ce2b939e06e7ecc18c358772ea0c92e82ef26d9bbe342a18babc0d54f676ed9c380fc990a7d576c958d19f6e15fda4fe08752bb8d1eedb05f +b46af0bf761b78533e01a0dd7e07216c9710ef35f09a28d1e5fa469b602472ca5085f6dbcc6a6b51fb89986f8feca85658d05701f5677d0bb340a1f2c769547219f5420c62ffff7d1304dad82b6dec2bdc59ec12a9e18a774eed128c2c90610a9d4c75c0817d64817a76bbc12746971ae897af210a072c1bc9fb044e086b7bfe85fad95d5c2bbb28c12de5755b1ccde63e93cc892b4d2bcbd7dc0706b094c2492e329e3b9a98a9cbc7d01031cf1d5861f576e1291df6286c28146b0b4df9ad44a8d40ce05f73fa3de1a92f948c38fe88a296db696a16742c5073aed1f26c6289675c28c763ab90a070b643ecf1c50f4165b82cf5b8eda4137903765f42cbaef571f6303486a899aef83ca9c8c1e53af717293a6e219675aa1f479eac02d30df16649fc1c83b24855617385b5330b054c13f8fe8670ea2383552fe7fa096a6ff0d90d3922c26b77fb632041df8a3c585f295488aa98d73bc6a3a43eac5644b59440e02ed8a6b9a8acb9f33e732c1850ed6f811975a84b65cb8775df2f55f15f58af8a27936cf507dcc7ec480ffce410373c81374fddcbad758a1976894d58e68d84f3da8a0bbbfd3d62d09679378ee94686866e0ef101e05ccb7cc8fdf6f31cbbf757c4d17aa607bc1decad9a65b8120adb7ef3b9d18a9c07226adf6f73f93c2ff79956f5e19b7c613dff1e907a8381863eb9ca536b44a3034cd522d6caa1766eda2dadd40a0f32380a30c0a0be3ad991007c8778ec855f0c2e9869718f07562ef2bce1d6fa7b551454eda2f86a514d0cd754188715d5f73cbe47d940b8a98a2de9cb66cba3830b2e732aa836df30b279f434ac98182114990d0b8d423813f75b5527dfa7982a167712380786bda08836976c21358a0d50e735f3efcb59ff69ace37ddc48ef2b83bcc1931cf6673dfa726ac5229b83be548b60416ed5c7daf3a3201db9aadd1ffe632a7d3012d94668d5191010dd35d8ba9dc881005e112f28083f085c8094de717acd2516b631760110c176bff91d3e8cd4d2df79f79d450e54a5007e34caf791d9ac10aa98f45e52d987addf59f4beb5e62ef59e2e1b1994131fa61652a5574f50fa159d47f8f28776e25e21b51103b91afc8345cfbedf46586e17269bfb521ae07f2cd202d308110abcb2b6f0157a55bc6aa6936812c1074dcd3dc1365d431608687e158b5b3622375e0ddda9cfccb2f16b4a966fc3ecababaa3ea4f8311b37c4578c4692a0d2bdd251c18a886c9b48671531db27598289593cf82813da4f43eb854142ef39c4e5950f86b29e291737413396ae4c62f4472fe12659e12b61b84619a96b03a386dd6adb6b74ce09bc11330482e01564d3eb1a688a80b912ad6d8ce2b939e06e7ecc18c358772ea0c92e82ef26d9bbe342a18babc0d54f676ed9c380fc990a7d576c958d19f6e15fda4fe08752bb8d1eedb05fbb420713aa2c9df64fc3fcb136d739466a36b38c515e44b1fd8e04717ab838bb8ad38ee6613c173d1d973f478cb0abcd6e69ac2570b8c9b78264ceb9d4a975c8 diff --git a/external/src/libsodium/test/default/stream2.c b/external/src/libsodium/test/default/stream2.c new file mode 100644 index 0000000..1e178a4 --- /dev/null +++ b/external/src/libsodium/test/default/stream2.c @@ -0,0 +1,59 @@ + +#define TEST_NAME "stream2" +#include "cmptest.h" + +static const unsigned char secondkey[32] = { + 0xdc, 0x90, 0x8d, 0xda, 0x0b, 0x93, 0x44, + 0xa9, 0x53, 0x62, 0x9b, 0x73, 0x38, 0x20, + 0x77, 0x88, 0x80, 0xf3, 0xce, 0xb4, 0x21, + 0xbb, 0x61, 0xb9, 0x1c, 0xbd, 0x4c, 0x3e, + 0x66, 0x25, 0x6c, 0xe4 +}; + +static const unsigned char noncesuffix[8] = { + 0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 +}; + + + +int +main(void) +{ + unsigned char *output; + char *hex; + unsigned char h[32]; + size_t sizeof_hex = 32 * 2 + 1; + size_t sizeof_output = 4194304; + int i; + + output = (unsigned char *) sodium_malloc(sizeof_output); + hex = (char *) sodium_malloc(sizeof_hex); + + crypto_stream_salsa20(output, sizeof_output, noncesuffix, secondkey); + crypto_hash_sha256(h, output, sizeof_output); + sodium_bin2hex(hex, sizeof_hex, h, sizeof h); + printf("%s\n", hex); + + assert(sizeof_output > 4000); + + crypto_stream_salsa20_xor_ic(output, output, 4000, noncesuffix, 0U, + secondkey); + for (i = 0; i < 4000; i++) { + assert(output[i] == 0); + } + + crypto_stream_salsa20_xor_ic(output, output, 4000, noncesuffix, 1U, + secondkey); + crypto_hash_sha256(h, output, sizeof_output); + sodium_bin2hex(hex, sizeof_hex, h, sizeof h); + printf("%s\n", hex); + + sodium_free(hex); + sodium_free(output); + + assert(crypto_stream_salsa20_keybytes() > 0U); + assert(crypto_stream_salsa20_noncebytes() > 0U); + assert(crypto_stream_salsa20_messagebytes_max() > 0U); + + return 0; +} diff --git a/external/src/libsodium/test/default/stream2.exp b/external/src/libsodium/test/default/stream2.exp new file mode 100644 index 0000000..23054b7 --- /dev/null +++ b/external/src/libsodium/test/default/stream2.exp @@ -0,0 +1,2 @@ +662b9d0e3463029156069b12f918691a98f7dfb2ca0393c96bbfc6b1fbd630a2 +0cc9ffaf60a99d221b548e9762385a231121ab226d1c610d2661ced26b6ad5ee diff --git a/external/src/libsodium/test/default/stream3.c b/external/src/libsodium/test/default/stream3.c new file mode 100644 index 0000000..afc8e69 --- /dev/null +++ b/external/src/libsodium/test/default/stream3.c @@ -0,0 +1,32 @@ + +#define TEST_NAME "stream3" +#include "cmptest.h" + +static unsigned char firstkey[32] = { 0x1b, 0x27, 0x55, 0x64, 0x73, 0xe9, 0x85, + 0xd4, 0x62, 0xcd, 0x51, 0x19, 0x7a, 0x9a, + 0x46, 0xc7, 0x60, 0x09, 0x54, 0x9e, 0xac, + 0x64, 0x74, 0xf2, 0x06, 0xc4, 0xee, 0x08, + 0x44, 0xf6, 0x83, 0x89 }; + +static unsigned char nonce[24] = { 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, + 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8, + 0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, + 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 }; + +static unsigned char rs[32]; + +int +main(void) +{ + int i; + + crypto_stream(rs, 32, nonce, firstkey); + + for (i = 0; i < 32; ++i) { + printf(",0x%02x", (unsigned int) rs[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + return 0; +} diff --git a/external/src/libsodium/test/default/stream3.exp b/external/src/libsodium/test/default/stream3.exp new file mode 100644 index 0000000..9cd7879 --- /dev/null +++ b/external/src/libsodium/test/default/stream3.exp @@ -0,0 +1,4 @@ +,0xee,0xa6,0xa7,0x25,0x1c,0x1e,0x72,0x91 +,0x6d,0x11,0xc2,0xcb,0x21,0x4d,0x3c,0x25 +,0x25,0x39,0x12,0x1d,0x8e,0x23,0x4e,0x65 +,0x2d,0x65,0x1f,0xa4,0xc8,0xcf,0xf8,0x80 diff --git a/external/src/libsodium/test/default/stream4.c b/external/src/libsodium/test/default/stream4.c new file mode 100644 index 0000000..a0a7656 --- /dev/null +++ b/external/src/libsodium/test/default/stream4.c @@ -0,0 +1,51 @@ + +#define TEST_NAME "stream4" +#include "cmptest.h" + +static unsigned char firstkey[32] = { 0x1b, 0x27, 0x55, 0x64, 0x73, 0xe9, 0x85, + 0xd4, 0x62, 0xcd, 0x51, 0x19, 0x7a, 0x9a, + 0x46, 0xc7, 0x60, 0x09, 0x54, 0x9e, 0xac, + 0x64, 0x74, 0xf2, 0x06, 0xc4, 0xee, 0x08, + 0x44, 0xf6, 0x83, 0x89 }; + +static unsigned char nonce[24] = { 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, + 0x2b, 0x73, 0xcd, 0x62, 0xbd, 0xa8, + 0x75, 0xfc, 0x73, 0xd6, 0x82, 0x19, + 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37 }; + +static unsigned char m[163] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0xbe, 0x07, 0x5f, 0xc5, + 0x3c, 0x81, 0xf2, 0xd5, 0xcf, 0x14, 0x13, 0x16, 0xeb, 0xeb, 0x0c, 0x7b, + 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4, 0x4b, 0x66, 0x84, 0x9b, + 0x64, 0x24, 0x4f, 0xfc, 0xe5, 0xec, 0xba, 0xaf, 0x33, 0xbd, 0x75, 0x1a, + 0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29, 0x6c, 0xdc, 0x3c, 0x01, + 0x23, 0x35, 0x61, 0xf4, 0x1d, 0xb6, 0x6c, 0xce, 0x31, 0x4a, 0xdb, 0x31, + 0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d, 0xce, 0xea, 0x3a, 0x7f, + 0xa1, 0x34, 0x80, 0x57, 0xe2, 0xf6, 0x55, 0x6a, 0xd6, 0xb1, 0x31, 0x8a, + 0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde, 0x04, 0x89, 0x77, 0xeb, + 0x48, 0xf5, 0x9f, 0xfd, 0x49, 0x24, 0xca, 0x1c, 0x60, 0x90, 0x2e, 0x52, + 0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40, 0xe0, 0x82, 0xf9, 0x37, + 0x76, 0x38, 0x48, 0x64, 0x5e, 0x07, 0x05 +}; + +static unsigned char c[163]; + +int +main(void) +{ + int i; + + crypto_stream_xor(c, m, 163, nonce, firstkey); + + for (i = 32; i < 163; ++i) { + printf(",0x%02x", (unsigned int) c[i]); + if (i % 8 == 7) { + printf("\n"); + } + } + printf("\n"); + + return 0; +} diff --git a/external/src/libsodium/test/default/stream4.exp b/external/src/libsodium/test/default/stream4.exp new file mode 100644 index 0000000..0d3d8e9 --- /dev/null +++ b/external/src/libsodium/test/default/stream4.exp @@ -0,0 +1,17 @@ +,0x8e,0x99,0x3b,0x9f,0x48,0x68,0x12,0x73 +,0xc2,0x96,0x50,0xba,0x32,0xfc,0x76,0xce +,0x48,0x33,0x2e,0xa7,0x16,0x4d,0x96,0xa4 +,0x47,0x6f,0xb8,0xc5,0x31,0xa1,0x18,0x6a +,0xc0,0xdf,0xc1,0x7c,0x98,0xdc,0xe8,0x7b +,0x4d,0xa7,0xf0,0x11,0xec,0x48,0xc9,0x72 +,0x71,0xd2,0xc2,0x0f,0x9b,0x92,0x8f,0xe2 +,0x27,0x0d,0x6f,0xb8,0x63,0xd5,0x17,0x38 +,0xb4,0x8e,0xee,0xe3,0x14,0xa7,0xcc,0x8a +,0xb9,0x32,0x16,0x45,0x48,0xe5,0x26,0xae +,0x90,0x22,0x43,0x68,0x51,0x7a,0xcf,0xea +,0xbd,0x6b,0xb3,0x73,0x2b,0xc0,0xe9,0xda +,0x99,0x83,0x2b,0x61,0xca,0x01,0xb6,0xde +,0x56,0x24,0x4a,0x9e,0x88,0xd5,0xf9,0xb3 +,0x79,0x73,0xf6,0x22,0xa4,0x3d,0x14,0xa6 +,0x59,0x9b,0x1f,0x65,0x4c,0xb4,0x5a,0x74 +,0xe3,0x55,0xa5 diff --git a/external/src/libsodium/test/default/verify1.c b/external/src/libsodium/test/default/verify1.c new file mode 100644 index 0000000..68257c9 --- /dev/null +++ b/external/src/libsodium/test/default/verify1.c @@ -0,0 +1,76 @@ + +#define TEST_NAME "verify1" +#include "cmptest.h" + +int +main(void) +{ + unsigned char *v16, *v16x; + unsigned char *v32, *v32x; + unsigned char *v64, *v64x; + uint32_t r; + uint8_t o; + int i; + + v16 = (unsigned char *) sodium_malloc(16); + v16x = (unsigned char *) sodium_malloc(16); + v32 = (unsigned char *) sodium_malloc(32); + v32x = (unsigned char *) sodium_malloc(32); + v64 = (unsigned char *) sodium_malloc(64); + v64x = (unsigned char *) sodium_malloc(64); + for (i = 0; i < 10000; i++) { + randombytes_buf(v16, 16); + randombytes_buf(v32, 32); + randombytes_buf(v64, 64); + + memcpy(v16x, v16, 16); + memcpy(v32x, v32, 32); + memcpy(v64x, v64, 64); + + if (crypto_verify_16(v16, v16x) != 0 || + crypto_verify_32(v32, v32x) != 0 || + crypto_verify_64(v64, v64x) != 0 || + sodium_memcmp(v16, v16x, 16) != 0 || + sodium_memcmp(v32, v32x, 32) != 0 || + sodium_memcmp(v64, v64x, 64) != 0) { + printf("Failed\n"); + } + } + printf("OK\n"); + + for (i = 0; i < 100000; i++) { + r = randombytes_random(); + o = (uint8_t) randombytes_random(); + if (o == 0) { + continue; + } + v16x[r & 15U] ^= o; + v32x[r & 31U] ^= o; + v64x[r & 63U] ^= o; + if (crypto_verify_16(v16, v16x) != -1 || + crypto_verify_32(v32, v32x) != -1 || + crypto_verify_64(v64, v64x) != -1 || + sodium_memcmp(v16, v16x, 16) != -1 || + sodium_memcmp(v32, v32x, 32) != -1 || + sodium_memcmp(v64, v64x, 64) != -1) { + printf("Failed\n"); + } + v16x[r & 15U] ^= o; + v32x[r & 31U] ^= o; + v64x[r & 63U] ^= o; + } + printf("OK\n"); + + assert(crypto_verify_16_bytes() == 16U); + assert(crypto_verify_32_bytes() == 32U); + assert(crypto_verify_64_bytes() == 64U); + + sodium_free(v16); + sodium_free(v16x); + sodium_free(v32); + sodium_free(v32x); + sodium_free(v64); + sodium_free(v64x); + + return 0; +} diff --git a/external/src/libsodium/test/default/verify1.exp b/external/src/libsodium/test/default/verify1.exp new file mode 100644 index 0000000..2c94e48 --- /dev/null +++ b/external/src/libsodium/test/default/verify1.exp @@ -0,0 +1,2 @@ +OK +OK diff --git a/external/src/libsodium/test/default/wasi-test-wrapper.sh b/external/src/libsodium/test/default/wasi-test-wrapper.sh new file mode 100644 index 0000000..8e0c5d7 --- /dev/null +++ b/external/src/libsodium/test/default/wasi-test-wrapper.sh @@ -0,0 +1,85 @@ +#! /bin/sh + +MAX_MEMORY_TESTS="67108864" + +unset LDFLAGS +unset CFLAGS + +if command -v wasm-opt >/dev/null; then + wasm-opt -O4 -o "${1}.tmp" "$1" && mv -f "${1}.tmp" "$1" +fi + +if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "wavm" ]; then + if command -v wavm >/dev/null; then + wavm run --abi=wasi "$1" && exit 0 + fi +fi + +if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "wasmtime" ]; then + if command -v wasmtime >/dev/null; then + wasmtime run --dir=. "$1" && exit 0 + fi +fi + +if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "wasmer" ]; then + if command -v wasmer >/dev/null; then + wasmer run "$1" "--${WASMER_BACKEND:-cranelift}" --dir=. && exit 0 + fi +fi + +if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "wasm3" ]; then + if command -v wasm3 >/dev/null; then + wasm3 "$1" && exit 0 + fi +fi + +if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "iwasm" ]; then + if iwasm | grep -qi wasi >/dev/null 2>&1; then + iwasm "$1" && exit 0 + fi +fi + +if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "ssvm" ]; then + if command -v ssvmc >/dev/null && command -v ssvm >/dev/null; then + ssvmc "$1" "${1}.so" && + ssvm --dir=.:. "${1}.so" && + rm -f "${1}.so" + fi +fi + +if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "node" ]; then + if echo | node --experimental-wasi-unstable-preview1 >/dev/null 2>&1; then + { + echo "import fs from 'fs'; import { WASI } from 'wasi';" + echo "const wasi = new WASI({args: process.argv, env: process.env, preopens: {'.':'.'}});" + echo "const importObject = { wasi_snapshot_preview1: wasi.wasiImport };" + echo "const wasm = await WebAssembly.compile(fs.readFileSync('${1}'));" + echo "const instance = await WebAssembly.instantiate(wasm, importObject);" + echo "wasi.start(instance);" + } >"${1}.mjs" + cat "${1}.mjs" >/tmp/a + node --experimental-wasi-unstable-preview1 "${1}.mjs" 2>/tmp/err && + rm -f "${1}.mjs" && exit 0 + fi +fi + +if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "wasmer-js" ]; then + if command -v wasmer-js >/dev/null; then + wasmer-js run "$1" --dir=. && exit 0 + fi +fi + +if [ -z "$WASI_RUNTIME" ] || [ "$WASI_RUNTIME" = "lucet" ]; then + if command -v lucetc-wasi >/dev/null && command -v lucet-wasi >/dev/null; then + lucetc-wasi \ + --target-cpu native \ + --reserved-size "4GiB" \ + --opt-level speed \ + "$1" -o "${1}.so" && + lucet-wasi --dir=.:. --max-heap-size "${MAX_MEMORY_TESTS}" "${1}.so" && + rm -f "${1}.so" && exit 0 + fi +fi + +echo "WebAssembly runtime failed" >&2 +exit 1 diff --git a/external/src/libsodium/test/default/wintest.bat b/external/src/libsodium/test/default/wintest.bat new file mode 100644 index 0000000..e50fb49 --- /dev/null +++ b/external/src/libsodium/test/default/wintest.bat @@ -0,0 +1,56 @@ +@ECHO OFF + +if "%1" == "" ( + echo "Usage: wintest.bat NUL 2>&1 + if not exist %%f.exe ( + echo %%f compile failed + goto :END + ) + %%f.exe + if errorlevel 1 ( + echo %%f failed + ) else ( + echo %%f ok + ) +) +REM Remove temporary files +del *.exe *.obj *.res +:END diff --git a/external/src/libsodium/test/default/xchacha20.c b/external/src/libsodium/test/default/xchacha20.c new file mode 100644 index 0000000..07eafcc --- /dev/null +++ b/external/src/libsodium/test/default/xchacha20.c @@ -0,0 +1,428 @@ + +#define TEST_NAME "xchacha20" +#include "cmptest.h" + +typedef struct HChaCha20TV_ { + const char key[crypto_core_hchacha20_KEYBYTES * 2 + 1]; + const char in[crypto_core_hchacha20_INPUTBYTES * 2 + 1]; + const char out[crypto_core_hchacha20_OUTPUTBYTES * 2 + 1]; +} HChaCha20TV; + +static const unsigned char small_order_p[crypto_scalarmult_BYTES] = { + 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56, 0xe3, + 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb, 0x9c, 0x32, + 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49, 0xb8, 0x00 +}; + +static void +tv_hchacha20(void) +{ + static const HChaCha20TV tvs[] = { + { "24f11cce8a1b3d61e441561a696c1c1b7e173d084fd4812425435a8896a013dc", "d9660c5900ae19ddad28d6e06e45fe5e", "5966b3eec3bff1189f831f06afe4d4e3be97fa9235ec8c20d08acfbbb4e851e3" }, + { "80a5f6272031e18bb9bcd84f3385da65e7731b7039f13f5e3d475364cd4d42f7", "c0eccc384b44c88e92c57eb2d5ca4dfa", "6ed11741f724009a640a44fce7320954c46e18e0d7ae063bdbc8d7cf372709df" }, + { "cb1fc686c0eec11a89438b6f4013bf110e7171dace3297f3a657a309b3199629", "fcd49b93e5f8f299227e64d40dc864a3", "84b7e96937a1a0a406bb7162eeaad34308d49de60fd2f7ec9dc6a79cbab2ca34" }, + { "6640f4d80af5496ca1bc2cfff1fefbe99638dbceaabd7d0ade118999d45f053d", "31f59ceeeafdbfe8cae7914caeba90d6", "9af4697d2f5574a44834a2c2ae1a0505af9f5d869dbe381a994a18eb374c36a0" }, + { "0693ff36d971225a44ac92c092c60b399e672e4cc5aafd5e31426f123787ac27", "3a6293da061da405db45be1731d5fc4d", "f87b38609142c01095bfc425573bb3c698f9ae866b7e4216840b9c4caf3b0865" }, + { "809539bd2639a23bf83578700f055f313561c7785a4a19fc9114086915eee551", "780c65d6a3318e479c02141d3f0b3918", "902ea8ce4680c09395ce71874d242f84274243a156938aaa2dd37ac5be382b42" }, + { "1a170ddf25a4fd69b648926e6d794e73408805835c64b2c70efddd8cd1c56ce0", "05dbee10de87eb0c5acb2b66ebbe67d3", "a4e20b634c77d7db908d387b48ec2b370059db916e8ea7716dc07238532d5981" }, + { "3b354e4bb69b5b4a1126f509e84cad49f18c9f5f29f0be0c821316a6986e15a6", "d8a89af02f4b8b2901d8321796388b6c", "9816cb1a5b61993735a4b161b51ed2265b696e7ded5309c229a5a99f53534fbc" }, + { "4b9a818892e15a530db50dd2832e95ee192e5ed6afffb408bd624a0c4e12a081", "a9079c551de70501be0286d1bc78b045", "ebc5224cf41ea97473683b6c2f38a084bf6e1feaaeff62676db59d5b719d999b" }, + { "c49758f00003714c38f1d4972bde57ee8271f543b91e07ebce56b554eb7fa6a7", "31f0204e10cf4f2035f9e62bb5ba7303", "0dd8cc400f702d2c06ed920be52048a287076b86480ae273c6d568a2e9e7518c" } + }; + const HChaCha20TV *tv; + unsigned char *constant; + unsigned char *key; + unsigned char *in; + unsigned char *out; + unsigned char *out2; + size_t i; + + constant = (unsigned char *) sodium_malloc(crypto_core_hchacha20_CONSTBYTES); + key = (unsigned char *) sodium_malloc(crypto_core_hchacha20_KEYBYTES); + in = (unsigned char *) sodium_malloc(crypto_core_hchacha20_INPUTBYTES); + out = (unsigned char *) sodium_malloc(crypto_core_hchacha20_OUTPUTBYTES); + out2 = (unsigned char *) sodium_malloc(crypto_core_hchacha20_OUTPUTBYTES); + for (i = 0; i < (sizeof tvs) / (sizeof tvs[0]); i++) { + tv = &tvs[i]; + sodium_hex2bin(key, crypto_core_hchacha20_KEYBYTES, + tv->key, strlen(tv->key), NULL, NULL, NULL); + sodium_hex2bin(in, crypto_core_hchacha20_INPUTBYTES, + tv->in, strlen(tv->in), NULL, NULL, NULL); + sodium_hex2bin(out, crypto_core_hchacha20_OUTPUTBYTES, + tv->out, strlen(tv->out), NULL, NULL, NULL); + crypto_core_hchacha20(out2, in, key, NULL); + assert(memcmp(out, out2, crypto_core_hchacha20_OUTPUTBYTES) == 0); + } + + sodium_hex2bin(constant, crypto_core_hchacha20_CONSTBYTES, + "0d29b795c1ca70c1652e823364d32417", + crypto_core_hchacha20_CONSTBYTES * 2 + 1, NULL, NULL, NULL); + sodium_hex2bin(out, crypto_core_hchacha20_OUTPUTBYTES, + "934d941d78eb9bfc2f0376f7ccd4a11ecf0c6a44104618a9749ef47fe97037a2", + crypto_core_hchacha20_OUTPUTBYTES * 2 + 1, NULL, NULL, NULL); + + crypto_core_hchacha20(out2, in, key, constant); + assert(memcmp(out, out2, crypto_core_hchacha20_OUTPUTBYTES) == 0); + + sodium_free(out2); + sodium_free(out); + sodium_free(in); + sodium_free(key); + sodium_free(constant); + + assert(crypto_core_hchacha20_outputbytes() == crypto_core_hchacha20_OUTPUTBYTES); + assert(crypto_core_hchacha20_inputbytes() == crypto_core_hchacha20_INPUTBYTES); + assert(crypto_core_hchacha20_keybytes() == crypto_core_hchacha20_KEYBYTES); + assert(crypto_core_hchacha20_constbytes() == crypto_core_hchacha20_CONSTBYTES); + + printf("tv_hchacha20: ok\n"); +} + +#define XCHACHA20_OUT_MAX 100 + +typedef struct XChaCha20TV_ { + const char key[crypto_stream_xchacha20_KEYBYTES * 2 + 1]; + const char nonce[crypto_stream_xchacha20_NONCEBYTES * 2 + 1]; + const char out[XCHACHA20_OUT_MAX * 2 + 1]; +} XChaCha20TV; + +static void +tv_stream_xchacha20(void) +{ + static const XChaCha20TV tvs[] = { + { "79c99798ac67300bbb2704c95c341e3245f3dcb21761b98e52ff45b24f304fc4", "b33ffd3096479bcfbc9aee49417688a0a2554f8d95389419", "c6e9758160083ac604ef90e712ce6e75d7797590744e0cf060f013739c" }, + { "ddf7784fee099612c40700862189d0397fcc4cc4b3cc02b5456b3a97d1186173", "a9a04491e7bf00c3ca91ac7c2d38a777d88993a7047dfcc4", "2f289d371f6f0abc3cb60d11d9b7b29adf6bc5ad843e8493e928448d" }, + { "3d12800e7b014e88d68a73f0a95b04b435719936feba60473f02a9e61ae60682", "56bed2599eac99fb27ebf4ffcb770a64772dec4d5849ea2d", "a2c3c1406f33c054a92760a8e0666b84f84fa3a618f0" }, + { "5f5763ff9a30c95da5c9f2a8dfd7cc6efd9dfb431812c075aa3e4f32e04f53e4", "a5fa890efa3b9a034d377926ce0e08ee6d7faccaee41b771", "8a1a5ba898bdbcff602b1036e469a18a5e45789d0e8d9837d81a2388a52b0b6a0f51891528f424c4a7f492a8dd7bce8bac19fbdbe1fb379ac0" }, + { "eadc0e27f77113b5241f8ca9d6f9a5e7f09eee68d8a5cf30700563bf01060b4e", "a171a4ef3fde7c4794c5b86170dc5a099b478f1b852f7b64", "23839f61795c3cdbcee2c749a92543baeeea3cbb721402aa42e6cae140447575f2916c5d71108e3b13357eaf86f060cb" }, + { "91319c9545c7c804ba6b712e22294c386fe31c4ff3d278827637b959d3dbaab2", "410e854b2a911f174aaf1a56540fc3855851f41c65967a4e", "cbe7d24177119b7fdfa8b06ee04dade4256ba7d35ffda6b89f014e479faef6" }, + { "6a6d3f412fc86c4450fc31f89f64ed46baa3256ffcf8616e8c23a06c422842b6", "6b7773fce3c2546a5db4829f53a9165f41b08faae2fb72d5", "8b23e35b3cdd5f3f75525fc37960ec2b68918e8c046d8a832b9838f1546be662e54feb1203e2" }, + { "d45e56368ebc7ba9be7c55cfd2da0feb633c1d86cab67cd5627514fd20c2b391", "fd37da2db31e0c738754463edadc7dafb0833bd45da497fc", "47950efa8217e3dec437454bd6b6a80a287e2570f0a48b3fa1ea3eb868be3d486f6516606d85e5643becc473b370871ab9ef8e2a728f73b92bd98e6e26ea7c8ff96ec5a9e8de95e1eee9300c" }, + { "aface41a64a9a40cbc604d42bd363523bd762eb717f3e08fe2e0b4611eb4dcf3", "6906e0383b895ab9f1cf3803f42f27c79ad47b681c552c63", "a5fa7c0190792ee17675d52ad7570f1fb0892239c76d6e802c26b5b3544d13151e67513b8aaa1ac5af2d7fd0d5e4216964324838" }, + { "9d23bd4149cb979ccf3c5c94dd217e9808cb0e50cd0f67812235eaaf601d6232", "c047548266b7c370d33566a2425cbf30d82d1eaf5294109e", "a21209096594de8c5667b1d13ad93f744106d054df210e4782cd396fec692d3515a20bf351eec011a92c367888bc464c32f0807acd6c203a247e0db854148468e9f96bee4cf718d68d5f637cbd5a376457788e6fae90fc31097cfc" }, + }; + const XChaCha20TV *tv; + char *hex; + unsigned char *key; + unsigned char *nonce; + unsigned char *out; + unsigned char *out2; + size_t out_len; + size_t i; + + key = (unsigned char *) sodium_malloc(crypto_stream_xchacha20_KEYBYTES); + nonce = (unsigned char *) sodium_malloc(crypto_stream_xchacha20_NONCEBYTES); + out = (unsigned char *) sodium_malloc(XCHACHA20_OUT_MAX); + for (i = 0; i < (sizeof tvs) / (sizeof tvs[0]); i++) { + tv = &tvs[i]; + + sodium_hex2bin(key, crypto_stream_xchacha20_KEYBYTES, + tv->key, strlen(tv->key), NULL, NULL, NULL); + sodium_hex2bin(nonce, crypto_stream_xchacha20_NONCEBYTES, + tv->nonce, strlen(tv->nonce), NULL, NULL, NULL); + sodium_hex2bin(out, XCHACHA20_OUT_MAX, + tv->out, strlen(tv->out), NULL, &out_len, NULL); + out2 = (unsigned char *) sodium_malloc(out_len); + crypto_stream_xchacha20(out2, out_len, nonce, key); + assert(memcmp(out, out2, out_len) == 0); + crypto_stream_xchacha20_xor(out2, out, out_len, nonce, key); + assert(sodium_is_zero(out2, out_len)); + crypto_stream_xchacha20_xor_ic(out2, out, out_len, nonce, 0, key); + assert(sodium_is_zero(out2, out_len)); + crypto_stream_xchacha20_xor_ic(out2, out, out_len, nonce, 1, key); + assert(!sodium_is_zero(out2, out_len)); + crypto_stream_xchacha20_xor(out, out, out_len, nonce, key); + assert(sodium_is_zero(out, out_len)); + sodium_free(out2); + } + + out2 = (unsigned char *) sodium_malloc(0); + crypto_stream_xchacha20(out2, 0, nonce, key); + crypto_stream_xchacha20_xor(out2, out2, 0, nonce, key); + crypto_stream_xchacha20_xor_ic(out2, out2, 0, nonce, 1, key); + sodium_free(out2); + sodium_free(out); + + out = (unsigned char *) sodium_malloc(64); + out2 = (unsigned char *) sodium_malloc(128); + randombytes_buf(out, 64); + randombytes_buf(out2, 64); + memcpy(out2 + 64, out, 64); + crypto_stream_xchacha20_xor_ic(out, out, 64, nonce, 1, key); + crypto_stream_xchacha20_xor(out2, out2, 128, nonce, key); + assert(memcmp(out, out2 + 64, 64) == 0); + sodium_free(out); + sodium_free(out2); + + out = (unsigned char *) sodium_malloc(192); + out2 = (unsigned char *) sodium_malloc(192); + memset(out, 0, 192); + memset(out2, 0, 192); + crypto_stream_xchacha20_xor_ic(out2, out2, 192, nonce, + (1ULL << 32) - 1ULL, key); + crypto_stream_xchacha20_xor_ic(out, out, 64, nonce, + (1ULL << 32) - 1ULL, key); + crypto_stream_xchacha20_xor_ic(out + 64, out + 64, 64, nonce, + (1ULL << 32), key); + crypto_stream_xchacha20_xor_ic(out + 128, out + 128, 64, nonce, + (1ULL << 32) + 1, key); + assert(memcmp(out, out2, 192) == 0); + hex = (char *) sodium_malloc(192 * 2 + 1); + sodium_bin2hex(hex, 192 * 2 + 1, out, 192); + printf("%s\n", hex); + + memset(key, 0, crypto_stream_xchacha20_KEYBYTES); + crypto_stream_xchacha20_keygen(key); + assert(sodium_is_zero(key, crypto_stream_xchacha20_KEYBYTES) == 0); + + sodium_free(hex); + sodium_free(out); + sodium_free(out2); + + sodium_free(nonce); + sodium_free(key); + + assert(crypto_stream_xchacha20_keybytes() == crypto_stream_xchacha20_KEYBYTES); + assert(crypto_stream_xchacha20_noncebytes() == crypto_stream_xchacha20_NONCEBYTES); + assert(crypto_stream_xchacha20_messagebytes_max() == crypto_stream_xchacha20_MESSAGEBYTES_MAX); + + printf("tv_stream_xchacha20: ok\n"); +} + +typedef struct XChaCha20Poly1305TV_ { + const char key[crypto_secretbox_xchacha20poly1305_KEYBYTES * 2 + 1]; + const char nonce[crypto_secretbox_xchacha20poly1305_NONCEBYTES * 2 + 1]; + const char *m; + const char *out; +} XChaCha20Poly1305TV; + +static void +tv_secretbox_xchacha20poly1305(void) +{ + static const XChaCha20Poly1305TV tvs[] = { + { "065ff46a9dddb1ab047ee5914d6d575a828b8cc1f454b24e8cd0f57efdc49a34", "f83262646ce01293b9923a65a073df78c54b2e799cd6c4e5", "", "4c72340416339dcdea01b760db5adaf7" }, + { "d3c71d54e6b13506e07aa2e7b412a17a7a1f34df3d3148cd3f45b91ccaa5f4d9", "943b454a853aa514c63cf99b1e197bbb99da24b2e2d93e47", "76bd706e07741e713d90efdb34ad202067263f984942aae8bda159f30dfccc72200f8093520b85c5ad124ff7c8b2d920946e5cfff4b819abf84c7b35a6205ca72c9f8747c3044dd73fb4bebda1b476", "0384276f1cfa5c82c3e58f0f2acc1f821c6f526d2c19557cf8bd270fcde43fba1d88890663f7b2f5c6b1d7deccf5c91b4df5865dc55cc7e04d6793fc2db8f9e3b418f95cb796d67a7f3f7e097150cb607c435dacf82eac3d669866e5092ace" }, + { "9498fdb922e0596e32af7f8108def2068f5a32a5ac70bd33ade371701f3d98d0", "a0056f24be0d20106fe750e2ee3684d4457cbdcb3a74e566", "b1bc9cfedb340fb06a37eba80439189e48aa0cfd37020eec0afa09165af12864671b3fbddbbb20ac18f586f2f66d13b3ca40c9a7e21c4513a5d87a95319f8ca3c2151e2a1b8b86a35653e77f90b9e63d2a84be9b9603876a89d60fd708edcd64b41be1064b8ad1046553aaeb51dc70b8112c9915d94f2a5dad1e14e7009db6c703c843a4f64b77d44b179b9579ac497dac2d33", "4918790d46893fa3dca74d8abc57eef7fca2c6393d1beef5efa845ac20475db38d1a068debf4c5dbd8614eb072877c565dc52bd40941f0b590d2079a5028e426bf50bcbaadcbebf278bddceedc578a5e31379523dee15026ec82d34e56f2871fdf13255db199ac48f163d5ee7e4f4e09a39451356959d9242a39aea33990ab960a4c25346e3d9397fc5e7cb6266c2476411cd331f2bcb4486750c746947ec6401865d5" }, + { "fa2d915e044d0519248150e7c815b01f0f2a691c626f8d22c3ef61e7f16eea47", "c946065dc8befa9cc9f292ea2cf28f0256285565051792b7", "d5be1a24c7872115dc5c5b4234dbee35a6f89ae3a91b3e33d75249a0aecfed252341295f49296f7ee14d64de1ea6355cb8facd065052d869aeb1763cda7e418a7e33b6f7a81327181df6cd4de3a126d9df1b5e8b0b1a6b281e63f2", "6d32e3571afec58b0acabb54a287118b3ed6691f56cc8ead12d735352c9a050c2ca173c78b6092f9ad4b7c21c36fb0ce18560956395bab3099c54760a743051ac6a898a0b0034b5e953340c975cf7a873c56b27e66bca2bff1dd977addefc7935bb7550753dd13d1f1a43d" }, + { "6f149c2ec27af45176030c8dd7ab0e1e488f5803f26f75045d7a56f59a587a85", "952aff2f39bc70016f04ac7fb8b55fd22764ba16b56e255d", "8fde598c4bde5786abdc6ab83fce66d59782b6ce36afe028c447ad4086a748764afa88a520e837a9d56d0b7693b0476649f24c2aa44b94615a1efc75", "9bccf07974836fa4609d32d9527d928d184d9c6c0823af2f703e0e257a162d26d3678fa15ab1c4db76ac42084d32cefca8efaf77814c199b310999e327a3e3daa2e235b175979504ede87b58" }, + { "b964b7fdf442efbcc2cd3e4cd596035bdfb05ed7d44f7fd4dce2d5614af5c8c4", "2886fbfa4b35b68f28d31df6243a4fbc56475b69e24820a4", "", "b83fbdd112bf0f7d62eff96c9faa8850" }, + { "10c0ad4054b48d7d1de1d9ab6f782ca883d886573e9d18c1d47b6ee6b5208189", "977edf57428d0e0247a3c88c9a9ec321bbaae1a4da8353b5", "518e4a27949812424b2a381c3efea6055ee5e75eff", "0c801a037c2ed0500d6ef68e8d195eceb05a15f8edb68b35773e81ac2aca18e9be53416f9a" }, + { "7db0a81d01699c86f47a3ec76d46aa32660adad7f9ac72cf8396419f789f6bb1", "e7cb57132ce954e28f4470cca1dbda20b534cdf32fbe3658", "ee6511d403539e611ab312205f0c3b8f36a33d36f1dc44bb33d6836f0ab93b9f1747167bf0150f045fcd12a39479641d8bdde6fe01475196e8fe2c435e834e30a59f6aaa01ebcd", "ae8b1d4df4f982b2702626feca07590fedd0dfa7ae34e6a098372a1aa32f9fbf0ce2a88b5c16a571ef48f3c9fda689ce8ebb9947c9e2a28e01b1191efc81ad2ce0ed6e6fc7c164b1fc7f3d50b7f5e47a895db3c1fc46c0" }, + { "7b043dd27476cf5a2baf2907541d8241ecd8b97d38d08911737e69b0846732fb", "74706a2855f946ed600e9b453c1ac372520b6a76a3c48a76", "dbf165bb8352d6823991b99f3981ba9c8153635e5695477cba54e96a2a8c4dc5f9dbe817887d7340e3f48a", "ce57261afba90a9598de15481c43f26f7b8c8cb2806c7c977752dba898dc51b92a3f1a62ebf696747bfccf72e0edda97f2ccd6d496f55aefbb3ec2" }, + { "e588e418d658df1b2b1583122e26f74ca3506b425087bea895d81021168f8164", "4f4d0ffd699268cd841ce4f603fe0cd27b8069fcf8215fbb", "f91bcdcf4d08ba8598407ba8ef661e66c59ca9d89f3c0a3542e47246c777091e4864e63e1e3911dc01257255e551527a53a34481be", "22dc88de7cacd4d9ce73359f7d6e16e74caeaa7b0d1ef2bb10fda4e79c3d5a9aa04b8b03575fd27bc970c9ed0dc80346162469e0547030ddccb8cdc95981400907c87c9442" } + }; + const XChaCha20Poly1305TV *tv; + unsigned char *m; + unsigned char *nonce; + unsigned char *key; + unsigned char *out; + unsigned char *out2; + size_t m_len; + size_t n; + size_t i; + + key = (unsigned char *) sodium_malloc + (crypto_secretbox_xchacha20poly1305_KEYBYTES); + nonce = (unsigned char *) sodium_malloc + (crypto_secretbox_xchacha20poly1305_NONCEBYTES); + for (i = 0; i < (sizeof tvs) / (sizeof tvs[0]); i++) { + tv = &tvs[i]; + m_len = strlen(tv->m) / 2; + m = (unsigned char *) sodium_malloc(m_len); + sodium_hex2bin(key, crypto_secretbox_xchacha20poly1305_KEYBYTES, + tv->key, strlen(tv->key), NULL, NULL, NULL); + sodium_hex2bin(nonce, crypto_secretbox_xchacha20poly1305_NONCEBYTES, + tv->nonce, strlen(tv->nonce), NULL, NULL, NULL); + sodium_hex2bin(m, m_len, tv->m, strlen(tv->m), NULL, NULL, NULL); + out = (unsigned char *) sodium_malloc + (crypto_secretbox_xchacha20poly1305_MACBYTES + m_len); + out2 = (unsigned char *) sodium_malloc + (crypto_secretbox_xchacha20poly1305_MACBYTES + m_len); + sodium_hex2bin(out, crypto_secretbox_xchacha20poly1305_MACBYTES + m_len, + tv->out, strlen(tv->out), NULL, NULL, NULL); + assert(crypto_secretbox_xchacha20poly1305_easy(out2, m, 0, nonce, key) == 0); + assert(crypto_secretbox_xchacha20poly1305_easy(out2, m, m_len, nonce, key) == 0); + assert(memcmp(out, out2, + crypto_secretbox_xchacha20poly1305_MACBYTES + m_len) == 0); + n = randombytes_uniform(crypto_secretbox_xchacha20poly1305_MACBYTES + (uint32_t) m_len); + assert(crypto_secretbox_xchacha20poly1305_open_easy + (out2, out2, crypto_secretbox_xchacha20poly1305_MACBYTES - 1, + nonce, key) == -1); + assert(crypto_secretbox_xchacha20poly1305_open_easy + (out2, out2, 0, + nonce, key) == -1); + out2[n]++; + assert(crypto_secretbox_xchacha20poly1305_open_easy + (out2, out2, crypto_secretbox_xchacha20poly1305_MACBYTES + m_len, + nonce, key) == -1); + out2[n]--; + nonce[0]++; + assert(crypto_secretbox_xchacha20poly1305_open_easy + (out2, out2, crypto_secretbox_xchacha20poly1305_MACBYTES + m_len, + nonce, key) == -1); + nonce[0]--; + assert(crypto_secretbox_xchacha20poly1305_open_easy + (out2, out2, crypto_secretbox_xchacha20poly1305_MACBYTES + m_len, + nonce, key) == 0); + assert(crypto_secretbox_xchacha20poly1305_open_easy + (out2, out2, crypto_secretbox_xchacha20poly1305_MACBYTES - 1, + nonce, key) == -1); + assert(crypto_secretbox_xchacha20poly1305_open_easy + (out2, out2, 0, nonce, key) == -1); + assert(memcmp(m, out2, m_len) == 0); + assert(crypto_secretbox_xchacha20poly1305_open_detached + (out2, out + crypto_secretbox_xchacha20poly1305_MACBYTES, out, + m_len, nonce, key) == 0); + assert(crypto_secretbox_xchacha20poly1305_open_detached + (NULL, out + crypto_secretbox_xchacha20poly1305_MACBYTES, out, + m_len, nonce, key) == 0); + crypto_secretbox_xchacha20poly1305_detached + (out2 + crypto_secretbox_xchacha20poly1305_MACBYTES, out2, m, + m_len, nonce, key); + assert(memcmp(out, out2, + crypto_secretbox_xchacha20poly1305_MACBYTES + m_len) == 0); + sodium_free(out); + sodium_free(out2); + sodium_free(m); + } + sodium_free(nonce); + sodium_free(key); + + assert(crypto_secretbox_xchacha20poly1305_keybytes() == crypto_secretbox_xchacha20poly1305_KEYBYTES); + assert(crypto_secretbox_xchacha20poly1305_noncebytes() == crypto_secretbox_xchacha20poly1305_NONCEBYTES); + assert(crypto_secretbox_xchacha20poly1305_macbytes() == crypto_secretbox_xchacha20poly1305_MACBYTES); + assert(crypto_secretbox_xchacha20poly1305_messagebytes_max() == crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX); + + printf("tv_secretbox_xchacha20: ok\n"); +} + +static void +tv_box_xchacha20poly1305(void) +{ + char hex[65]; + unsigned char *pk; + unsigned char *sk; + unsigned char *m; + unsigned char *m2; + unsigned char *mac; + unsigned char *nonce; + unsigned char *out; + unsigned char *pc; + unsigned char *seed; + size_t m_len; + int i; + + pk = (unsigned char *) sodium_malloc(crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES); + sk = (unsigned char *) sodium_malloc(crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES); + nonce = (unsigned char *) sodium_malloc(crypto_box_curve25519xchacha20poly1305_NONCEBYTES); + mac = (unsigned char *) sodium_malloc(crypto_box_curve25519xchacha20poly1305_MACBYTES); + pc = (unsigned char *) sodium_malloc(crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES); + for (i = 0; i < 10; i++) { + m_len = (i == 0) ? 0 : randombytes_uniform(150); + m = (unsigned char *) sodium_malloc(m_len); + m2 = (unsigned char *) sodium_malloc(m_len); + + out = (unsigned char *) sodium_malloc + (crypto_box_curve25519xchacha20poly1305_MACBYTES + m_len); + randombytes_buf(nonce, crypto_box_curve25519xchacha20poly1305_NONCEBYTES); + randombytes_buf(m, m_len); + assert(crypto_box_curve25519xchacha20poly1305_keypair(pk, sk) == 0); + assert(crypto_box_curve25519xchacha20poly1305_easy(out, m, 0, nonce, + pk, sk) == 0); + assert(crypto_box_curve25519xchacha20poly1305_easy(out, m, m_len, nonce, + pk, sk) == 0); + assert(crypto_box_curve25519xchacha20poly1305_open_easy + (m2, out, crypto_box_curve25519xchacha20poly1305_MACBYTES + m_len, + nonce, small_order_p, sk) == -1); + assert(crypto_box_curve25519xchacha20poly1305_open_easy + (m2, out, crypto_box_curve25519xchacha20poly1305_MACBYTES - 1, + nonce, pk, sk) == -1); + assert(crypto_box_curve25519xchacha20poly1305_open_easy + (m2, out, 0, nonce, pk, sk) == -1); + assert(crypto_box_curve25519xchacha20poly1305_open_easy + (m2, out, crypto_box_curve25519xchacha20poly1305_MACBYTES + m_len, + nonce, pk, sk) == 0); + assert(memcmp(m2, m, m_len) == 0); + sodium_free(out); + + out = (unsigned char *) sodium_malloc + (crypto_box_curve25519xchacha20poly1305_MACBYTES + m_len); + assert(crypto_box_curve25519xchacha20poly1305_beforenm(pc, small_order_p, sk) == -1); + assert(crypto_box_curve25519xchacha20poly1305_beforenm(pc, pk, sk) == 0); + assert(crypto_box_curve25519xchacha20poly1305_easy_afternm + (out, m, 0, nonce, pc) == 0); + assert(crypto_box_curve25519xchacha20poly1305_easy_afternm + (out, m, m_len, nonce, pc) == 0); + assert(crypto_box_curve25519xchacha20poly1305_open_easy_afternm + (m2, out, crypto_box_curve25519xchacha20poly1305_MACBYTES - 1, + nonce, pc) == -1); + assert(crypto_box_curve25519xchacha20poly1305_open_easy_afternm + (m2, out, 0, + nonce, pc) == -1); + assert(crypto_box_curve25519xchacha20poly1305_open_easy_afternm + (m2, out, crypto_box_curve25519xchacha20poly1305_MACBYTES + m_len, + nonce, pc) == 0); + assert(memcmp(m2, m, m_len) == 0); + sodium_free(out); + + out = (unsigned char *) sodium_malloc(m_len); + assert(crypto_box_curve25519xchacha20poly1305_detached(out, mac, m, m_len, + nonce, small_order_p, sk) == -1); + assert(crypto_box_curve25519xchacha20poly1305_detached(out, mac, m, m_len, + nonce, pk, sk) == 0); + assert(crypto_box_curve25519xchacha20poly1305_open_detached + (m2, out, mac, m_len, nonce, small_order_p, sk) == -1); + assert(crypto_box_curve25519xchacha20poly1305_open_detached + (m2, out, mac, m_len, nonce, pk, sk) == 0); + sodium_free(out); + + out = (unsigned char *) sodium_malloc(m_len); + assert(crypto_box_curve25519xchacha20poly1305_detached_afternm + (out, mac, m, m_len, nonce, pc) == 0); + assert(crypto_box_curve25519xchacha20poly1305_open_detached_afternm + (m2, out, mac, m_len, nonce, pc) == 0); + sodium_free(out); + + sodium_free(m2); + sodium_free(m); + } + sodium_free(pc); + sodium_free(mac); + sodium_free(nonce); + + seed = (unsigned char *) sodium_malloc + (crypto_box_curve25519xchacha20poly1305_SEEDBYTES); + for (i = 0; i <(int) crypto_box_curve25519xchacha20poly1305_SEEDBYTES; i++) { + seed[i] = (unsigned char) i; + } + crypto_box_curve25519xchacha20poly1305_seed_keypair(pk, sk, seed); + sodium_bin2hex(hex, sizeof hex, pk, crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES); + assert(strcmp(hex, "4701d08488451f545a409fb58ae3e58581ca40ac3f7f114698cd71deac73ca01") == 0); + sodium_bin2hex(hex, sizeof hex, sk, crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES); + assert(strcmp(hex, "3d94eea49c580aef816935762be049559d6d1440dede12e6a125f1841fff8e6f") == 0); + sodium_free(seed); + + sodium_free(sk); + sodium_free(pk); + + assert(crypto_box_curve25519xchacha20poly1305_seedbytes() == crypto_box_curve25519xchacha20poly1305_SEEDBYTES); + assert(crypto_box_curve25519xchacha20poly1305_publickeybytes() == crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES); + assert(crypto_box_curve25519xchacha20poly1305_secretkeybytes() == crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES); + assert(crypto_box_curve25519xchacha20poly1305_beforenmbytes() == crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES); + assert(crypto_box_curve25519xchacha20poly1305_noncebytes() == crypto_box_curve25519xchacha20poly1305_NONCEBYTES); + assert(crypto_box_curve25519xchacha20poly1305_macbytes() == crypto_box_curve25519xchacha20poly1305_MACBYTES); + assert(crypto_box_curve25519xchacha20poly1305_messagebytes_max() == crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX); + + printf("tv_box_xchacha20poly1305: ok\n"); +} + +int +main(void) +{ + tv_hchacha20(); + tv_stream_xchacha20(); + tv_secretbox_xchacha20poly1305(); + tv_box_xchacha20poly1305(); + + return 0; +} diff --git a/external/src/libsodium/test/default/xchacha20.exp b/external/src/libsodium/test/default/xchacha20.exp new file mode 100644 index 0000000..0ac74c6 --- /dev/null +++ b/external/src/libsodium/test/default/xchacha20.exp @@ -0,0 +1,5 @@ +tv_hchacha20: ok +3e34c160a966ddfbd52d38f6a440a77256c1134ad54653db427dfdfc72f0f995768039052ec2ec4e6fe02c655d7d95681fabd417c087ad17f177510ba09d4cfe7beb8f7c9b8330d746310f9e29583e9ef240156015faafeb24a4d002d6337b7bcec8b54a64ef704e1ae3247d79625d267cbacd1c90e4a2df2f72d4090babf88c90e65a086c464ec1753c49d3b8ad02f2a3c0808e1695c5d77cec6f6f12578ae4ed077a2046e06644d14af65ae90f2869a6f1f910b83a7a3cfec8dd390621a511 +tv_stream_xchacha20: ok +tv_secretbox_xchacha20: ok +tv_box_xchacha20poly1305: ok diff --git a/external/src/libsodium/test/quirks/quirks.h b/external/src/libsodium/test/quirks/quirks.h new file mode 100644 index 0000000..69fe369 --- /dev/null +++ b/external/src/libsodium/test/quirks/quirks.h @@ -0,0 +1,34 @@ + +#include + +/* C++Builder defines a "random" macro */ +#undef random + +#ifdef __EMSCRIPTEN__ +# define strcmp(s1, s2) xstrcmp(s1, s2) + +static int +strcmp(const char *s1, const char *s2) +{ + while (*s1 == *s2++) { + if (*s1++ == 0) { + return 0; + } + } + return *(unsigned char *) s1 - *(unsigned char *) --s2; +} +#endif + +#ifdef _WIN32 +static void +srandom(unsigned seed) +{ + srand(seed); +} + +static long +random(void) +{ + return (long) rand(); +} +#endif diff --git a/external/src/libuv/.gitattributes b/external/src/libuv/.gitattributes new file mode 100644 index 0000000..89297cb --- /dev/null +++ b/external/src/libuv/.gitattributes @@ -0,0 +1 @@ +test/fixtures/lorem_ipsum.txt text eol=lf diff --git a/external/src/libuv/.github/ISSUE_TEMPLATE.md b/external/src/libuv/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..43934de --- /dev/null +++ b/external/src/libuv/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,13 @@ + +* **Version**: +* **Platform**: diff --git a/external/src/libuv/.github/stale.yml b/external/src/libuv/.github/stale.yml new file mode 100644 index 0000000..d0ba3a4 --- /dev/null +++ b/external/src/libuv/.github/stale.yml @@ -0,0 +1,24 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 21 +# Number of days of inactivity before a stale issue is closed +# Set to false to disable. If disabled, issues still need to be closed +# manually, but will remain marked as stale. +daysUntilClose: 120 +# Issues with these labels will never be considered stale +exemptLabels: + - v2 + - enhancement + - good first issue + - feature-request + - doc + - bug + - not-stale +# Label to use when marking an issue as stale +staleLabel: stale +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false diff --git a/external/src/libuv/.github/workflows/CI.yml b/external/src/libuv/.github/workflows/CI.yml new file mode 100644 index 0000000..c384123 --- /dev/null +++ b/external/src/libuv/.github/workflows/CI.yml @@ -0,0 +1,69 @@ +name: CI + +on: [push, pull_request] + +jobs: + build-android: + runs-on: ubuntu-latest + container: reactnativecommunity/react-native-android:2020-5-20 + steps: + - uses: actions/checkout@v2 + - name: Envinfo + run: npx envinfo + - name: Build android arm64 + # see build options you can use in https://developer.android.com/ndk/guides/cmake + run: | + mkdir build && cd build + $ANDROID_HOME/cmake/3.10.2.4988404/bin/cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk/20.0.5594570/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_PLATFORM=android-21 .. + $ANDROID_HOME/cmake/3.10.2.4988404/bin/cmake --build . + + build-cross-qemu: + runs-on: ubuntu-latest + name: build-cross-qemu-${{ matrix.config.target }} + + strategy: + fail-fast: false + matrix: + config: + - {target: arm, toolchain: gcc-arm-linux-gnueabi, cc: arm-linux-gnueabi-gcc, qemu: qemu-arm-static } + - {target: armhf, toolchain: gcc-arm-linux-gnueabihf, cc: arm-linux-gnueabihf-gcc, qemu: qemu-arm-static } + - {target: aarch64, toolchain: gcc-aarch64-linux-gnu, cc: aarch64-linux-gnu-gcc, qemu: qemu-aarch64-static } + - {target: riscv64, toolchain: gcc-riscv64-linux-gnu, cc: riscv64-linux-gnu-gcc, qemu: qemu-riscv64-static } + - {target: ppc, toolchain: gcc-powerpc-linux-gnu, cc: powerpc-linux-gnu-gcc, qemu: qemu-ppc-static } + - {target: ppc64, toolchain: gcc-powerpc64-linux-gnu, cc: powerpc64-linux-gnu-gcc, qemu: qemu-ppc64-static } + - {target: ppc64le, toolchain: gcc-powerpc64le-linux-gnu, cc: powerpc64le-linux-gnu-gcc, qemu: qemu-ppc64le-static } + - {target: s390x, toolchain: gcc-s390x-linux-gnu, cc: s390x-linux-gnu-gcc, qemu: qemu-s390x-static } + - {target: mips, toolchain: gcc-mips-linux-gnu, cc: mips-linux-gnu-gcc, qemu: qemu-mips-static } + - {target: mips64, toolchain: gcc-mips64-linux-gnuabi64, cc: mips64-linux-gnuabi64-gcc, qemu: qemu-mips64-static } + - {target: mipsel, toolchain: gcc-mipsel-linux-gnu, cc: mipsel-linux-gnu-gcc, qemu: qemu-mipsel-static } + - {target: mips64el,toolchain: gcc-mips64el-linux-gnuabi64, cc: mips64el-linux-gnuabi64-gcc,qemu: qemu-mips64el-static } + - {target: alpha, toolchain: gcc-alpha-linux-gnu, cc: alpha-linux-gnu-gcc, qemu: qemu-alpha-static } + - {target: arm (u64 slots), toolchain: gcc-arm-linux-gnueabi, cc: arm-linux-gnueabi-gcc, qemu: qemu-arm-static} + - {target: aarch64 (u64 slots), toolchain: gcc-aarch64-linux-gnu, cc: aarch64-linux-gnu-gcc, qemu: qemu-aarch64-static} + - {target: ppc (u64 slots), toolchain: gcc-powerpc-linux-gnu, cc: powerpc-linux-gnu-gcc, qemu: qemu-ppc-static} + - {target: ppc64 (u64 slots), toolchain: gcc-powerpc64-linux-gnu, cc: powerpc64-linux-gnu-gcc, qemu: qemu-ppc64-static} + + steps: + - uses: actions/checkout@v2 + - name: Install QEMU + # this ensure install latest qemu on ubuntu, apt get version is old + env: + QEMU_SRC: "http://archive.ubuntu.com/ubuntu/pool/universe/q/qemu" + QEMU_VER: "qemu-user-static_4\\.2-.*_amd64.deb$" + run: | + DEB=`curl -s $QEMU_SRC/ | grep -o -E 'href="([^"#]+)"' | cut -d'"' -f2 | grep $QEMU_VER | tail -1` + wget $QEMU_SRC/$DEB + sudo dpkg -i $DEB + - name: Install ${{ matrix.config.toolchain }} + run: | + sudo apt update + sudo apt install ${{ matrix.config.toolchain }} -y + - name: Build + run: | + mkdir build + cd build && cmake .. -DBUILD_TESTING=ON -DQEMU=ON -DCMAKE_C_COMPILER=${{ matrix.config.cc }} + cmake --build . + ls -lh + - name: Test + run: | + ${{ matrix.config.qemu }} build/uv_run_tests_a diff --git a/external/src/libuv/.github/workflows/sanitizer.yml b/external/src/libuv/.github/workflows/sanitizer.yml new file mode 100644 index 0000000..51e1479 --- /dev/null +++ b/external/src/libuv/.github/workflows/sanitizer.yml @@ -0,0 +1,17 @@ +name: Sanitizer checks + +on: [push, pull_request] + +jobs: + asan: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Envinfo + run: npx envinfo + - name: ASAN + run: | + mkdir build + cd build && cmake .. -DBUILD_TESTING=ON -DASAN=ON -DCMAKE_BUILD_TYPE=Debug + cmake --build . && ./uv_run_tests_a + diff --git a/external/src/libuv/.gitignore b/external/src/libuv/.gitignore new file mode 100644 index 0000000..7eb4932 --- /dev/null +++ b/external/src/libuv/.gitignore @@ -0,0 +1,76 @@ +*.swp +*.[oa] +*.l[oa] +*.opensdf +*.orig +*.pyc +*.sdf +*.suo +.vs/ +*.VC.db +*.VC.opendb +core +vgcore.* +.buildstamp +.dirstamp +.deps/ +/.libs/ +/aclocal.m4 +/ar-lib +/autom4te.cache/ +/compile +/config.guess +/config.log +/config.status +/config.sub +/configure +/depcomp +/install-sh +/libtool +/libuv.a +/libuv.dylib +/libuv.pc +/libuv.so +/ltmain.sh +/missing +/test-driver +Makefile +Makefile.in + +/build/ + +/test/.libs/ +/test/run-tests +/test/run-tests.exe +/test/run-tests.dSYM +/test/run-benchmarks +/test/run-benchmarks.exe +/test/run-benchmarks.dSYM +test_file_* + +*.sln +*.sln.cache +*.ncb +*.vcproj +*.vcproj*.user +*.vcxproj +*.vcxproj.filters +*.vcxproj.user +_UpgradeReport_Files/ +UpgradeLog*.XML +Debug +Release +ipch + +# sphinx generated files +/docs/build/ + +# Clion / IntelliJ project files +/.idea/ +cmake-build-debug/ + +*.xcodeproj +*.xcworkspace + +# make dist output +libuv-*.tar.* diff --git a/external/src/libuv/.mailmap b/external/src/libuv/.mailmap new file mode 100644 index 0000000..7be85ab --- /dev/null +++ b/external/src/libuv/.mailmap @@ -0,0 +1,60 @@ +A. Hauptmann +Aaron Bieber +Alan Gutierrez +Andrius Bentkus +Andy Fiddaman +Bert Belder +Bert Belder +Bert Belder +Brandon Philips +Brian White +Brian White +Caleb James DeLisle +Christoph Iserlohn +Darshan Sen +David Carlier +Devchandra Meetei Leishangthem +Fedor Indutny +Frank Denis +Imran Iqbal +Isaac Z. Schlueter +Jason Williams +Jesse Gorzinski +Jesse Gorzinski +Justin Venus +Keno Fischer +Keno Fischer +Leith Bade +Leonard Hecker +Maciej MaÅ‚ecki +Marc Schlaich +Michael +Michael Neumann +Michael Penick +Nicholas Vavilov +Nick Logan +Rasmus Christian Pedersen +Rasmus Christian Pedersen +Richard Lau +Robert Mustacchi +Ryan Dahl +Ryan Emery +Sakthipriyan Vairamani +Sam Roberts +San-Tai Hsu +Santiago Gimeno +Saúl Ibarra Corretgé +Saúl Ibarra Corretgé +Shigeki Ohtsu +TK-one +Timothy J. Fontaine +Yasuhiro Matsumoto +Yazhong Liu +Yuki Okumura +cjihrig +gengjiawen +jBarz +jBarz +ptlomholt +tjarlama <59913901+tjarlama@users.noreply.github.com> +zlargon diff --git a/external/src/libuv/.readthedocs.yaml b/external/src/libuv/.readthedocs.yaml new file mode 100644 index 0000000..e53b9f3 --- /dev/null +++ b/external/src/libuv/.readthedocs.yaml @@ -0,0 +1,11 @@ +version: 2 + +sphinx: + builder: html + configuration: null + fail_on_warning: false + +python: + version: 3.8 + install: + - requirements: docs/requirements.txt diff --git a/external/src/libuv/AUTHORS b/external/src/libuv/AUTHORS new file mode 100644 index 0000000..741bcc7 --- /dev/null +++ b/external/src/libuv/AUTHORS @@ -0,0 +1,481 @@ +# Authors ordered by first contribution. +Ryan Dahl +Bert Belder +Josh Roesslein +Alan Gutierrez +Joshua Peek +Igor Zinkovsky +San-Tai Hsu +Ben Noordhuis +Henry Rawas +Robert Mustacchi +Matt Stevens +Paul Querna +Shigeki Ohtsu +Tom Hughes +Peter Bright +Jeroen Janssen +Andrea Lattuada +Augusto Henrique Hentz +Clifford Heath +Jorge Chamorro Bieling +Luis Lavena +Matthew Sporleder +Erick Tryzelaar +Isaac Z. Schlueter +Pieter Noordhuis +Marek Jelen +Fedor Indutny +Saúl Ibarra Corretgé +Felix Geisendörfer +Yuki Okumura +Roman Shtylman +Frank Denis +Carter Allen +Tj Holowaychuk +Shimon Doodkin +Ryan Emery +Bruce Mitchener +Maciej MaÅ‚ecki +Yasuhiro Matsumoto +Daisuke Murase +Paddy Byers +Dan VerWeire +Brandon Benvie +Brandon Philips +Nathan Rajlich +Charlie McConnell +Vladimir Dronnikov +Aaron Bieber +Bulat Shakirzyanov +Brian White +Erik Dubbelboer +Keno Fischer +Ira Cooper +Andrius Bentkus +Iñaki Baz Castillo +Mark Cavage +George Yohng +Xidorn Quan +Roman Neuhauser +Shuhei Tanuma +Bryan Cantrill +Trond Norbye +Tim Holy +Prancesco Pertugio +Leonard Hecker +Andrew Paprocki +Luigi Grilli +Shannen Saez +Artur Adib +Hiroaki Nakamura +Ting-Yu Lin +Stephen Gallagher +Shane Holloway +Andrew Shaffer +Vlad Tudose +Ben Leslie +Tim Bradshaw +Timothy J. Fontaine +Marc Schlaich +Brian Mazza +Elliot Saba +Ben Kelly +Nils Maier +Nicholas Vavilov +Miroslav BajtoÅ¡ +Sean Silva +Wynn Wilkes +Andrei Sedoi +Alex Crichton +Brent Cook +Brian Kaisner +Luca Bruno +Reini Urban +Maks Naumov +Sean Farrell +Chris Bank +Geert Jansen +Christoph Iserlohn +Steven Kabbes +Alex Gaynor +huxingyi +Tenor Biel +Andrej Manduch +Joshua Neuheisel +Alexis Campailla +Yazhong Liu +Sam Roberts +River Tarnell +Nathan Sweet +Trevor Norris +Oguz Bastemur +Dylan Cali +Austin Foxley +Benjamin Saunders +Geoffry Song +William Light +Oleg Efimov +Lars Gierth +Rasmus Christian Pedersen +Justin Venus +Kristian Evensen +Linus MÃ¥rtensson +Navaneeth Kedaram Nambiathan +StarWing +thierry-FreeBSD +Isaiah Norton +Raul Martins +David Capello +Paul Tan +Javier Hernández +Tonis Tiigi +Norio Kobota +æŽæ¸¯å¹³ +Chernyshev Viacheslav +Stephen von Takach +JD Ballard +Luka Perkov +Ryan Cole +HungMingWu +Jay Satiro +Leith Bade +Peter Atashian +Tim Cooper +Caleb James DeLisle +Jameson Nash +Graham Lee +Andrew Low +Pavel Platto +Tony Kelman +John Firebaugh +lilohuang +Paul Goldsmith +Julien Gilli +Michael Hudson-Doyle +Recep ASLANTAS +Rob Adams +Zachary Newman +Robin Hahling +Jeff Widman +cjihrig +Tomasz KoÅ‚odziejski +Unknown W. Brackets +Emmanuel Odeke +Mikhail Mukovnikov +Thorsten Lorenz +Yuri D'Elia +Manos Nikolaidis +Elijah Andrews +Michael Ira Krufky +Helge Deller +Joey Geralnik +Tim Caswell +Logan Rosen +Kenneth Perry +John Marino +Alexey Melnichuk +Johan Bergström +Alex Mo +Luis Martinez de Bartolome +Michael Penick +Michael +Massimiliano Torromeo +TomCrypto +Brett Vickers +Ole André Vadla RavnÃ¥s +Kazuho Oku +Ryan Phillips +Brian Green +Devchandra Meetei Leishangthem +Corey Farrell +Per Nilsson +Alan Rogers +Daryl Haresign +Rui Abreu Ferreira +João Reis +farblue68 +Jason Williams +Igor Soarez +Miodrag Milanovic +Cheng Zhao +Michael Neumann +Stefano Cristiano +heshamsafi +A. Hauptmann +John McNamee +Yosuke Furukawa +Santiago Gimeno +guworks +RossBencina +Roger A. Light +chenttuuvv +Richard Lau +ronkorving +Corbin Simpson +Zachary Hamm +Karl Skomski +Jeremy Whitlock +Willem Thiart +Ben Trask +Jianghua Yang +Colin Snover +Sakthipriyan Vairamani +Eli Skeggs +nmushell +Gireesh Punathil +Ryan Johnston +Adam Stylinski +Nathan Corvino +Wink Saville +Angel Leon +Louis DeJardin +Imran Iqbal +Petka Antonov +Ian Kronquist +kkdaemon +Yuval Brik +Joran Dirk Greef +Andrey Mazo +sztomi +Martin Bark +Dave +Alexis Murzeau +Didiet +Nan Xiang <514580344@qq.com> +Samuel Lorétan +Nándor István Krácser +Katsutoshi Horie +Lukasz Jagiello +Robert Chiras +Kári Tristan Helgason +Krishnaraj Bhat +Enno Boland +Michael Fero +Robert Jefe Lindstaedt +Myles Borins +Tony Theodore +Jason Ginchereau +Nicolas Cavallari +Pierre-Marie de Rodat +Brian Maher +neevek +John Barboza +liuxiaobo +Michele Caini +Bartosz Sosnowski +Matej Knopp +sunjin.lee +Matt Clarkson +Jeffrey Clark +Bart Robinson +Vit Gottwald +Vladimír ÄŒunát +Alex Hultman +Brad King +Philippe Laferriere +Will Speak +Hitesh Kanwathirtha +Eric Sciple +jBarz +muflub +Daniel Bevenius +Howard Hellyer +Chris Araman +Vladimir Matveev +Jason Madden +Jamie Davis +Daniel Kahn Gillmor +Keane +James McCoy +Bernardo Ramos +Juan Cruz Viotti +Gemini Wen +Sebastian Wiedenroth +Sai Ke WANG +Barnabas Gema +Romain Caire +Robert Ayrapetyan +Refael Ackermann +André Klitzing +Matthew Taylor +CurlyMoo +XadillaX +Anticrisis +Jacob Segal +Maciej Szeptuch (Neverous) +Joel Winarske +Gergely Nagy +Kamil Rytarowski +tux.uudiin <77389867@qq.com> +Nick Logan +darobs +Zheng, Lei +Carlo Marcelo Arenas Belón +Scott Parker +Wade Brainerd +rayrase +Pekka Nikander +Ed Schouten +Xu Meng +Matt Harrison +Anna Henningsen +Jérémy Lal +Ben Wijen +elephantp +Felix Yan +Mason X +Jesse Gorzinski +Ryuichi KAWAMATA +Joyee Cheung +Michael Kilburn +Ruslan Bekenev +Bob Burger +Thomas Versteeg +zzzjim +Alex Arslan +Kyle Farnung +ssrlive <30760636+ssrlive@users.noreply.github.com> +Tobias Nießen +Björn Linse +zyxwvu Shi +Peter Johnson +Paolo Greppi +Shelley Vohr +Ujjwal Sharma +MichaÅ‚ Kozakiewicz +Emil Bay +Jeremiah Senkpiel +Andy Zhang +dmabupt +Ryan Liptak +Ali Ijaz Sheikh +hitesh +Svante Signell +Samuel Thibault +Jeremy Studer +damon-kwok <563066990@qq.com> +Damon Kwok +Ashe Connor +Rick +Ivan Krylov +Michael Meier +ptlomholt +Victor Costan +sid +Kevin Adler +Stephen Belanger +yeyuanfeng +erw7 +Thomas Karl Pietrowski +evgley +Andreas Rohner +Rich Trott +Milad Farazmand +zlargon +Yury Selivanov +Oscar Waddell +FX Coudert +George Zhao +Kyle Edwards +ken-cunningham-webuse +Kelvin Jin +Leorize +Vlad A +Niels Lohmann +Jenil Christo +Evgeny Ermakov +gengjiawen +Leo Chung +Javier Blazquez +Mustafa M +Zach Bjornson +Nan Xiao +Ben Davies +Nhan Khong +Crunkle +Tomas Krizek +Konstantin Podsvirov +seny +Vladimir Karnushin +MaYuming +Eneas U de Queiroz +Daniel Hahler +Yang Yu +David Carlier +Calvin Hill +Isabella Muerte <63051+slurps-mad-rips@users.noreply.github.com> +Ouyang Yadong +ZYSzys +Carl Lei +Stefan Bender +nia +virtualyw +Witold KrÄ™cicki +Dominique Dumont +Manuel BACHMANN +Marek Vavrusa +TK-one +Irek Fakhrutdinov +Lin Zhang +毛毛 +Sk Sajidul Kadir +twosee +Rikard Falkeborn +Yash Ladha +James Ross +Colin Finck +Shohei YOSHIDA +Philip Chimento +Michal Artazov +Jeroen Roovers +MasterDuke17 +Alexander Tokmakov +Arenoros +lander0s +Turbinya +OleksandrKvl +Carter Li +Juan Sebastian velez Posada +escherstair +Evan Lucas +tjarlama <59913901+tjarlama@users.noreply.github.com> +å¸å¾’çŽŸç… +YuMeiJie +Aleksej Lebedev +Nikolay Mitev +Ulrik Strid +Elad Lahav +Elad Nachmias +Darshan Sen +Simon Kadisch +Momtchil Momtchev +Ethel Weston <66453757+ethelweston@users.noreply.github.com> +Drew DeVault +Mark Klein +schamberg97 <50446906+schamberg97@users.noreply.github.com> +Bob Weinand +Issam E. Maghni +Juan Pablo Canepa +Shuowang (Wayne) Zhang +OndÅ™ej Surý +Juan José Arboleda +Zhao Zhili +Brandon Cheng +Matvii Hodovaniuk +Hayden +yiyuaner +bbara +SeverinLeonhardt +Andy Fiddaman +Romain Roffé +Eagle Liang +Ricky Zhou +Simon Kissane +James M Snell +Ali Mohammad Pur +Erkhes N <71805796+rexes-ND@users.noreply.github.com> +Joshua M. Clulow +Guilherme Ãscaro +Martin Storsjö +Claes Nästén diff --git a/external/src/libuv/CMakeLists.txt b/external/src/libuv/CMakeLists.txt new file mode 100644 index 0000000..148d0e6 --- /dev/null +++ b/external/src/libuv/CMakeLists.txt @@ -0,0 +1,670 @@ +cmake_minimum_required(VERSION 3.4) +project(libuv LANGUAGES C) + +cmake_policy(SET CMP0057 NEW) # Enable IN_LIST operator +cmake_policy(SET CMP0064 NEW) # Support if (TEST) operator + +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") + +include(CMakePackageConfigHelpers) +include(CMakeDependentOption) +include(CheckCCompilerFlag) +include(GNUInstallDirs) +include(CTest) + +set(CMAKE_C_VISIBILITY_PRESET hidden) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_C_EXTENSIONS ON) +set(CMAKE_C_STANDARD 90) + +cmake_dependent_option(LIBUV_BUILD_TESTS + "Build the unit tests when BUILD_TESTING is enabled and we are the root project" ON + "BUILD_TESTING;CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF) +cmake_dependent_option(LIBUV_BUILD_BENCH + "Build the benchmarks when building unit tests and we are the root project" ON + "LIBUV_BUILD_TESTS" OFF) + +# Qemu Build +option(QEMU "build for qemu" OFF) +if(QEMU) + add_definitions(-D__QEMU__=1) +endif() + +option(ASAN "Enable AddressSanitizer (ASan)" OFF) +if(ASAN AND CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang") + add_definitions(-D__ASAN__=1) + set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") + set (CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address") +endif() + +# Compiler check +string(CONCAT is-msvc $, + $ +>) + +check_c_compiler_flag(/W4 UV_LINT_W4) +check_c_compiler_flag(/wd4100 UV_LINT_NO_UNUSED_PARAMETER_MSVC) +check_c_compiler_flag(/wd4127 UV_LINT_NO_CONDITIONAL_CONSTANT_MSVC) +check_c_compiler_flag(/wd4201 UV_LINT_NO_NONSTANDARD_MSVC) +check_c_compiler_flag(/wd4206 UV_LINT_NO_NONSTANDARD_EMPTY_TU_MSVC) +check_c_compiler_flag(/wd4210 UV_LINT_NO_NONSTANDARD_FILE_SCOPE_MSVC) +check_c_compiler_flag(/wd4232 UV_LINT_NO_NONSTANDARD_NONSTATIC_DLIMPORT_MSVC) +check_c_compiler_flag(/wd4456 UV_LINT_NO_HIDES_LOCAL) +check_c_compiler_flag(/wd4457 UV_LINT_NO_HIDES_PARAM) +check_c_compiler_flag(/wd4459 UV_LINT_NO_HIDES_GLOBAL) +check_c_compiler_flag(/wd4706 UV_LINT_NO_CONDITIONAL_ASSIGNMENT_MSVC) +check_c_compiler_flag(/wd4996 UV_LINT_NO_UNSAFE_MSVC) + +check_c_compiler_flag(-Wall UV_LINT_WALL) # DO NOT use this under MSVC + +# TODO: Place these into its own function +check_c_compiler_flag(-Wno-unused-parameter UV_LINT_NO_UNUSED_PARAMETER) +check_c_compiler_flag(-Wstrict-prototypes UV_LINT_STRICT_PROTOTYPES) +check_c_compiler_flag(-Wextra UV_LINT_EXTRA) + +check_c_compiler_flag(/utf-8 UV_LINT_UTF8_MSVC) + +set(lint-no-unused-parameter $<$:-Wno-unused-parameter>) +set(lint-strict-prototypes $<$:-Wstrict-prototypes>) +set(lint-extra $<$:-Wextra>) +set(lint-w4 $<$:/W4>) +set(lint-no-unused-parameter-msvc $<$:/wd4100>) +set(lint-no-conditional-constant-msvc $<$:/wd4127>) +set(lint-no-nonstandard-msvc $<$:/wd4201>) +set(lint-no-nonstandard-empty-tu-msvc $<$:/wd4206>) +set(lint-no-nonstandard-file-scope-msvc $<$:/wd4210>) +set(lint-no-nonstandard-nonstatic-dlimport-msvc $<$:/wd4232>) +set(lint-no-hides-local-msvc $<$:/wd4456>) +set(lint-no-hides-param-msvc $<$:/wd4457>) +set(lint-no-hides-global-msvc $<$:/wd4459>) +set(lint-no-conditional-assignment-msvc $<$:/wd4706>) +set(lint-no-unsafe-msvc $<$:/wd4996>) +# Unfortunately, this one is complicated because MSVC and clang-cl support -Wall +# but using it is like calling -Weverything +string(CONCAT lint-default $< + $,$>:-Wall +>) +set(lint-utf8-msvc $<$:/utf-8>) + +list(APPEND uv_cflags ${lint-strict-prototypes} ${lint-extra} ${lint-default} ${lint-w4}) +list(APPEND uv_cflags ${lint-no-unused-parameter}) +list(APPEND uv_cflags ${lint-no-unused-parameter-msvc}) +list(APPEND uv_cflags ${lint-no-conditional-constant-msvc}) +list(APPEND uv_cflags ${lint-no-nonstandard-msvc}) +list(APPEND uv_cflags ${lint-no-nonstandard-empty-tu-msvc}) +list(APPEND uv_cflags ${lint-no-nonstandard-file-scope-msvc}) +list(APPEND uv_cflags ${lint-no-nonstandard-nonstatic-dlimport-msvc}) +list(APPEND uv_cflags ${lint-no-hides-local-msvc}) +list(APPEND uv_cflags ${lint-no-hides-param-msvc}) +list(APPEND uv_cflags ${lint-no-hides-global-msvc}) +list(APPEND uv_cflags ${lint-no-conditional-assignment-msvc}) +list(APPEND uv_cflags ${lint-no-unsafe-msvc}) +list(APPEND uv_cflags ${lint-utf8-msvc} ) + +check_c_compiler_flag(-fno-strict-aliasing UV_F_STRICT_ALIASING) +list(APPEND uv_cflags $<$:-fno-strict-aliasing>) + +set(uv_sources + src/fs-poll.c + src/idna.c + src/inet.c + src/random.c + src/strscpy.c + src/threadpool.c + src/timer.c + src/uv-common.c + src/uv-data-getter-setters.c + src/version.c) + +if(WIN32) + list(APPEND uv_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0602) + list(APPEND uv_libraries + psapi + user32 + advapi32 + iphlpapi + userenv + ws2_32) + list(APPEND uv_sources + src/win/async.c + src/win/core.c + src/win/detect-wakeup.c + src/win/dl.c + src/win/error.c + src/win/fs.c + src/win/fs-event.c + src/win/getaddrinfo.c + src/win/getnameinfo.c + src/win/handle.c + src/win/loop-watcher.c + src/win/pipe.c + src/win/thread.c + src/win/poll.c + src/win/process.c + src/win/process-stdio.c + src/win/signal.c + src/win/snprintf.c + src/win/stream.c + src/win/tcp.c + src/win/tty.c + src/win/udp.c + src/win/util.c + src/win/winapi.c + src/win/winsock.c) + list(APPEND uv_test_libraries ws2_32) + list(APPEND uv_test_sources src/win/snprintf.c test/runner-win.c) +else() + list(APPEND uv_defines _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE) + if(NOT CMAKE_SYSTEM_NAME MATCHES "Android|OS390|QNX") + # TODO: This should be replaced with find_package(Threads) if possible + # Android has pthread as part of its c library, not as a separate + # libpthread.so. + list(APPEND uv_libraries pthread) + endif() + list(APPEND uv_sources + src/unix/async.c + src/unix/core.c + src/unix/dl.c + src/unix/fs.c + src/unix/getaddrinfo.c + src/unix/getnameinfo.c + src/unix/loop-watcher.c + src/unix/loop.c + src/unix/pipe.c + src/unix/poll.c + src/unix/process.c + src/unix/random-devurandom.c + src/unix/signal.c + src/unix/stream.c + src/unix/tcp.c + src/unix/thread.c + src/unix/tty.c + src/unix/udp.c) + list(APPEND uv_test_sources test/runner-unix.c) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "AIX") + list(APPEND uv_defines + _ALL_SOURCE + _LINUX_SOURCE_COMPAT + _THREAD_SAFE + _XOPEN_SOURCE=500 + HAVE_SYS_AHAFS_EVPRODS_H) + list(APPEND uv_libraries perfstat) + list(APPEND uv_sources + src/unix/aix.c + src/unix/aix-common.c) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "Android") + list(APPEND uv_defines _GNU_SOURCE) + list(APPEND uv_libraries dl) + list(APPEND uv_sources + src/unix/android-ifaddrs.c + src/unix/linux-core.c + src/unix/linux-inotify.c + src/unix/linux-syscalls.c + src/unix/procfs-exepath.c + src/unix/pthread-fixes.c + src/unix/random-getentropy.c + src/unix/random-getrandom.c + src/unix/random-sysctl-linux.c + src/unix/epoll.c) +endif() + +if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "Android|Linux") + list(APPEND uv_sources src/unix/proctitle.c) +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD") + list(APPEND uv_sources src/unix/freebsd.c) +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|NetBSD|OpenBSD") + list(APPEND uv_sources src/unix/posix-hrtime.c src/unix/bsd-proctitle.c) +endif() + +if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|NetBSD|OpenBSD") + list(APPEND uv_sources src/unix/bsd-ifaddrs.c src/unix/kqueue.c) +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + list(APPEND uv_sources src/unix/random-getrandom.c) +endif() + +if(APPLE OR CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") + list(APPEND uv_sources src/unix/random-getentropy.c) +endif() + +if(APPLE) + list(APPEND uv_defines _DARWIN_UNLIMITED_SELECT=1 _DARWIN_USE_64_BIT_INODE=1) + list(APPEND uv_sources + src/unix/darwin-proctitle.c + src/unix/darwin.c + src/unix/fsevents.c) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + list(APPEND uv_defines _GNU_SOURCE _POSIX_C_SOURCE=200112) + list(APPEND uv_libraries dl rt) + list(APPEND uv_sources + src/unix/linux-core.c + src/unix/linux-inotify.c + src/unix/linux-syscalls.c + src/unix/procfs-exepath.c + src/unix/random-getrandom.c + src/unix/random-sysctl-linux.c + src/unix/epoll.c) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD") + list(APPEND uv_sources src/unix/netbsd.c) + list(APPEND uv_libraries kvm) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") + list(APPEND uv_sources src/unix/openbsd.c) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "OS390") + enable_language(CXX) + list(APPEND uv_defines PATH_MAX=1024) + list(APPEND uv_defines _AE_BIMODAL) + list(APPEND uv_defines _ALL_SOURCE) + list(APPEND uv_defines _ENHANCED_ASCII_EXT=0xFFFFFFFF) + list(APPEND uv_defines _ISOC99_SOURCE) + list(APPEND uv_defines _LARGE_TIME_API) + list(APPEND uv_defines _OPEN_MSGQ_EXT) + list(APPEND uv_defines _OPEN_SYS_FILE_EXT) + list(APPEND uv_defines _OPEN_SYS_IF_EXT) + list(APPEND uv_defines _OPEN_SYS_SOCK_EXT3) + list(APPEND uv_defines _OPEN_SYS_SOCK_IPV6) + list(APPEND uv_defines _UNIX03_SOURCE) + list(APPEND uv_defines _UNIX03_THREADS) + list(APPEND uv_defines _UNIX03_WITHDRAWN) + list(APPEND uv_defines _XOPEN_SOURCE=600) + list(APPEND uv_defines _XOPEN_SOURCE_EXTENDED) + list(APPEND uv_sources + src/unix/pthread-fixes.c + src/unix/os390.c + src/unix/os390-syscalls.c + src/unix/os390-proctitle.c) + list(APPEND uv_cflags + -q64 + -qascii + -qexportall + -qgonumber + -qlongname + -qlibansi + -qfloat=IEEE + -qtune=10 + -qarch=10 + -qasm + -qasmlib=sys1.maclib:sys1.modgen) + find_library(ZOSLIB + NAMES zoslib + PATHS ${ZOSLIB_DIR} + PATH_SUFFIXES lib + ) + list(APPEND uv_libraries ${ZOSLIB}) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "OS400") + list(APPEND uv_defines + _ALL_SOURCE + _LINUX_SOURCE_COMPAT + _THREAD_SAFE + _XOPEN_SOURCE=500) + list(APPEND uv_sources + src/unix/aix-common.c + src/unix/ibmi.c + src/unix/no-fsevents.c + src/unix/posix-poll.c) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") + list(APPEND uv_defines __EXTENSIONS__ _XOPEN_SOURCE=500 _REENTRANT) + list(APPEND uv_libraries kstat nsl sendfile socket) + list(APPEND uv_sources + src/unix/no-proctitle.c + src/unix/sunos.c) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "Haiku") + list(APPEND uv_defines _BSD_SOURCE) + list(APPEND uv_libraries bsd network) + list(APPEND uv_sources + src/unix/haiku.c + src/unix/bsd-ifaddrs.c + src/unix/no-fsevents.c + src/unix/no-proctitle.c + src/unix/posix-hrtime.c + src/unix/posix-poll.c) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "QNX") + list(APPEND uv_sources + src/unix/posix-hrtime.c + src/unix/posix-poll.c + src/unix/qnx.c + src/unix/bsd-ifaddrs.c + src/unix/no-proctitle.c + src/unix/no-fsevents.c) + list(APPEND uv_libraries socket) +endif() + +if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|Linux|NetBSD|OpenBSD") + list(APPEND uv_test_libraries util) +endif() + +add_library(uv SHARED ${uv_sources}) +target_compile_definitions(uv + INTERFACE + USING_UV_SHARED=1 + PRIVATE + BUILDING_UV_SHARED=1 + ${uv_defines}) +target_compile_options(uv PRIVATE ${uv_cflags}) +target_include_directories(uv + PUBLIC + $ + $ + PRIVATE + $) +if(CMAKE_SYSTEM_NAME STREQUAL "OS390") + target_include_directories(uv PUBLIC $) + set_target_properties(uv PROPERTIES LINKER_LANGUAGE CXX) +endif() +target_link_libraries(uv ${uv_libraries}) + +add_library(uv_a STATIC ${uv_sources}) +target_compile_definitions(uv_a PRIVATE ${uv_defines}) +target_compile_options(uv_a PRIVATE ${uv_cflags}) +target_include_directories(uv_a + PUBLIC + $ + $ + PRIVATE + $) +if(CMAKE_SYSTEM_NAME STREQUAL "OS390") + target_include_directories(uv_a PUBLIC $) + set_target_properties(uv_a PROPERTIES LINKER_LANGUAGE CXX) +endif() +target_link_libraries(uv_a ${uv_libraries}) + +if(LIBUV_BUILD_TESTS) + # Small hack: use ${uv_test_sources} now to get the runner skeleton, + # before the actual tests are added. + add_executable( + uv_run_benchmarks_a + ${uv_test_sources} + test/benchmark-async-pummel.c + test/benchmark-async.c + test/benchmark-fs-stat.c + test/benchmark-getaddrinfo.c + test/benchmark-loop-count.c + test/benchmark-million-async.c + test/benchmark-million-timers.c + test/benchmark-multi-accept.c + test/benchmark-ping-pongs.c + test/benchmark-ping-udp.c + test/benchmark-pound.c + test/benchmark-pump.c + test/benchmark-sizes.c + test/benchmark-spawn.c + test/benchmark-tcp-write-batch.c + test/benchmark-thread.c + test/benchmark-udp-pummel.c + test/blackhole-server.c + test/dns-server.c + test/echo-server.c + test/run-benchmarks.c + test/runner.c) + target_compile_definitions(uv_run_benchmarks_a PRIVATE ${uv_defines}) + target_compile_options(uv_run_benchmarks_a PRIVATE ${uv_cflags}) + target_link_libraries(uv_run_benchmarks_a uv_a ${uv_test_libraries}) + + list(APPEND uv_test_sources + test/blackhole-server.c + test/echo-server.c + test/run-tests.c + test/runner.c + test/test-active.c + test/test-async-null-cb.c + test/test-async.c + test/test-barrier.c + test/test-callback-order.c + test/test-callback-stack.c + test/test-close-fd.c + test/test-close-order.c + test/test-condvar.c + test/test-connect-unspecified.c + test/test-connection-fail.c + test/test-cwd-and-chdir.c + test/test-default-loop-close.c + test/test-delayed-accept.c + test/test-dlerror.c + test/test-eintr-handling.c + test/test-embed.c + test/test-emfile.c + test/test-env-vars.c + test/test-error.c + test/test-fail-always.c + test/test-fork.c + test/test-fs-copyfile.c + test/test-fs-event.c + test/test-fs-poll.c + test/test-fs.c + test/test-fs-readdir.c + test/test-fs-fd-hash.c + test/test-fs-open-flags.c + test/test-get-currentexe.c + test/test-get-loadavg.c + test/test-get-memory.c + test/test-get-passwd.c + test/test-getaddrinfo.c + test/test-gethostname.c + test/test-getnameinfo.c + test/test-getsockname.c + test/test-getters-setters.c + test/test-gettimeofday.c + test/test-handle-fileno.c + test/test-homedir.c + test/test-hrtime.c + test/test-idle.c + test/test-idna.c + test/test-ip4-addr.c + test/test-ip6-addr.c + test/test-ipc-heavy-traffic-deadlock-bug.c + test/test-ipc-send-recv.c + test/test-ipc.c + test/test-loop-alive.c + test/test-loop-close.c + test/test-loop-configure.c + test/test-loop-handles.c + test/test-loop-stop.c + test/test-loop-time.c + test/test-metrics.c + test/test-multiple-listen.c + test/test-mutexes.c + test/test-not-readable-nor-writable-on-read-error.c + test/test-not-readable-on-eof.c + test/test-not-writable-after-shutdown.c + test/test-osx-select.c + test/test-pass-always.c + test/test-ping-pong.c + test/test-pipe-bind-error.c + test/test-pipe-close-stdout-read-stdin.c + test/test-pipe-connect-error.c + test/test-pipe-connect-multiple.c + test/test-pipe-connect-prepare.c + test/test-pipe-getsockname.c + test/test-pipe-pending-instances.c + test/test-pipe-sendmsg.c + test/test-pipe-server-close.c + test/test-pipe-set-fchmod.c + test/test-pipe-set-non-blocking.c + test/test-platform-output.c + test/test-poll-close-doesnt-corrupt-stack.c + test/test-poll-close.c + test/test-poll-closesocket.c + test/test-poll-multiple-handles.c + test/test-poll-oob.c + test/test-poll.c + test/test-process-priority.c + test/test-process-title-threadsafe.c + test/test-process-title.c + test/test-queue-foreach-delete.c + test/test-random.c + test/test-ref.c + test/test-run-nowait.c + test/test-run-once.c + test/test-semaphore.c + test/test-shutdown-close.c + test/test-shutdown-eof.c + test/test-shutdown-simultaneous.c + test/test-shutdown-twice.c + test/test-signal-multiple-loops.c + test/test-signal-pending-on-close.c + test/test-signal.c + test/test-socket-buffer-size.c + test/test-spawn.c + test/test-stdio-over-pipes.c + test/test-strscpy.c + test/test-tcp-alloc-cb-fail.c + test/test-tcp-bind-error.c + test/test-tcp-bind6-error.c + test/test-tcp-close-accept.c + test/test-tcp-close-while-connecting.c + test/test-tcp-close.c + test/test-tcp-close-reset.c + test/test-tcp-connect-error-after-write.c + test/test-tcp-connect-error.c + test/test-tcp-connect-timeout.c + test/test-tcp-connect6-error.c + test/test-tcp-create-socket-early.c + test/test-tcp-flags.c + test/test-tcp-oob.c + test/test-tcp-open.c + test/test-tcp-read-stop.c + test/test-tcp-read-stop-start.c + test/test-tcp-shutdown-after-write.c + test/test-tcp-try-write.c + test/test-tcp-try-write-error.c + test/test-tcp-unexpected-read.c + test/test-tcp-write-after-connect.c + test/test-tcp-write-fail.c + test/test-tcp-write-queue-order.c + test/test-tcp-write-to-half-open-connection.c + test/test-tcp-writealot.c + test/test-test-macros.c + test/test-thread-equal.c + test/test-thread.c + test/test-threadpool-cancel.c + test/test-threadpool.c + test/test-timer-again.c + test/test-timer-from-check.c + test/test-timer.c + test/test-tmpdir.c + test/test-tty-duplicate-key.c + test/test-tty-escape-sequence-processing.c + test/test-tty.c + test/test-udp-alloc-cb-fail.c + test/test-udp-bind.c + test/test-udp-connect.c + test/test-udp-create-socket-early.c + test/test-udp-dgram-too-big.c + test/test-udp-ipv6.c + test/test-udp-mmsg.c + test/test-udp-multicast-interface.c + test/test-udp-multicast-interface6.c + test/test-udp-multicast-join.c + test/test-udp-multicast-join6.c + test/test-udp-multicast-ttl.c + test/test-udp-open.c + test/test-udp-options.c + test/test-udp-send-and-recv.c + test/test-udp-send-hang-loop.c + test/test-udp-send-immediate.c + test/test-udp-sendmmsg-error.c + test/test-udp-send-unreachable.c + test/test-udp-try-send.c + test/test-uname.c + test/test-walk-handles.c + test/test-watcher-cross-stop.c) + + add_executable(uv_run_tests ${uv_test_sources} uv_win_longpath.manifest) + target_compile_definitions(uv_run_tests + PRIVATE ${uv_defines} USING_UV_SHARED=1) + target_compile_options(uv_run_tests PRIVATE ${uv_cflags}) + target_link_libraries(uv_run_tests uv ${uv_test_libraries}) + add_test(NAME uv_test + COMMAND uv_run_tests + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + if(CMAKE_SYSTEM_NAME STREQUAL "OS390") + set_tests_properties(uv_test PROPERTIES ENVIRONMENT + "LIBPATH=${CMAKE_BINARY_DIR}:$ENV{LIBPATH}") + endif() + add_executable(uv_run_tests_a ${uv_test_sources} uv_win_longpath.manifest) + target_compile_definitions(uv_run_tests_a PRIVATE ${uv_defines}) + target_compile_options(uv_run_tests_a PRIVATE ${uv_cflags}) + if(QEMU) + target_link_libraries(uv_run_tests_a uv_a ${uv_test_libraries} -static) + else() + target_link_libraries(uv_run_tests_a uv_a ${uv_test_libraries}) + endif() + add_test(NAME uv_test_a + COMMAND uv_run_tests_a + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + if(CMAKE_SYSTEM_NAME STREQUAL "OS390") + set_target_properties(uv_run_benchmarks_a PROPERTIES LINKER_LANGUAGE CXX) + set_target_properties(uv_run_tests PROPERTIES LINKER_LANGUAGE CXX) + set_target_properties(uv_run_tests_a PROPERTIES LINKER_LANGUAGE CXX) + endif() +endif() + +if(UNIX OR MINGW) + # Now for some gibbering horrors from beyond the stars... + foreach(lib IN LISTS uv_libraries) + list(APPEND LIBS "-l${lib}") + endforeach() + string(REPLACE ";" " " LIBS "${LIBS}") + # Consider setting project version via project() call? + file(STRINGS configure.ac configure_ac REGEX ^AC_INIT) + string(REGEX MATCH "([0-9]+)[.][0-9]+[.][0-9]+" PACKAGE_VERSION "${configure_ac}") + set(UV_VERSION_MAJOR "${CMAKE_MATCH_1}") + # The version in the filename is mirroring the behaviour of autotools. + set_target_properties(uv PROPERTIES + VERSION ${UV_VERSION_MAJOR}.0.0 + SOVERSION ${UV_VERSION_MAJOR}) + set(includedir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}) + set(libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) + set(prefix ${CMAKE_INSTALL_PREFIX}) + configure_file(libuv.pc.in libuv.pc @ONLY) + configure_file(libuv-static.pc.in libuv-static.pc @ONLY) + + install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR}) + install(FILES ${PROJECT_BINARY_DIR}/libuv.pc ${PROJECT_BINARY_DIR}/libuv-static.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) + install(TARGETS uv LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(TARGETS uv_a ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() + +if(MSVC) + install(DIRECTORY include/ DESTINATION include) + install(FILES LICENSE DESTINATION .) + install(TARGETS uv uv_a + RUNTIME DESTINATION lib/$ + ARCHIVE DESTINATION lib/$) +endif() + +message(STATUS "summary of build options: + Install prefix: ${CMAKE_INSTALL_PREFIX} + Target system: ${CMAKE_SYSTEM_NAME} + Compiler: + C compiler: ${CMAKE_C_COMPILER} + CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS} +") diff --git a/external/src/libuv/CONTRIBUTING.md b/external/src/libuv/CONTRIBUTING.md new file mode 100644 index 0000000..d37c51d --- /dev/null +++ b/external/src/libuv/CONTRIBUTING.md @@ -0,0 +1,171 @@ +# CONTRIBUTING + +The libuv project welcomes new contributors. This document will guide you +through the process. + + +### FORK + +Fork the project [on GitHub](https://github.com/libuv/libuv) and check out +your copy. + +``` +$ git clone https://github.com/username/libuv.git +$ cd libuv +$ git remote add upstream https://github.com/libuv/libuv.git +``` + +Now decide if you want your feature or bug fix to go into the master branch +or the stable branch. As a rule of thumb, bug fixes go into the stable branch +while new features go into the master branch. + +The stable branch is effectively frozen; patches that change the libuv +API/ABI or affect the run-time behavior of applications get rejected. + +In case of doubt, open an issue in the [issue tracker][], post your question +to the [libuv discussions forum], or message the [libuv mailing list]. + +Especially do so if you plan to work on something big. Nothing is more +frustrating than seeing your hard work go to waste because your vision does not +align with that of the [project maintainers]. + + +### BRANCH + +Okay, so you have decided on the proper branch. Create a feature branch +and start hacking: + +``` +$ git checkout -b my-feature-branch -t origin/v1.x +``` + +(Where v1.x is the latest stable branch as of this writing.) + +### CODE + +Please adhere to libuv's code style. In general it follows the conventions from +the [Google C/C++ style guide]. Some of the key points, as well as some +additional guidelines, are enumerated below. + +* Code that is specific to unix-y platforms should be placed in `src/unix`, and + declarations go into `include/uv/unix.h`. + +* Source code that is Windows-specific goes into `src/win`, and related + publicly exported types, functions and macro declarations should generally + be declared in `include/uv/win.h`. + +* Names should be descriptive and concise. + +* All the symbols and types that libuv makes available publicly should be + prefixed with `uv_` (or `UV_` in case of macros). + +* Internal, non-static functions should be prefixed with `uv__`. + +* Use two spaces and no tabs. + +* Lines should be wrapped at 80 characters. + +* Ensure that lines have no trailing whitespace, and use unix-style (LF) line + endings. + +* Use C89-compliant syntax. In other words, variables can only be declared at + the top of a scope (function, if/for/while-block). + +* When writing comments, use properly constructed sentences, including + punctuation. + +* When documenting APIs and/or source code, don't make assumptions or make + implications about race, gender, religion, political orientation or anything + else that isn't relevant to the project. + +* Remember that source code usually gets written once and read often: ensure + the reader doesn't have to make guesses. Make sure that the purpose and inner + logic are either obvious to a reasonably skilled professional, or add a + comment that explains it. + + +### COMMIT + +Make sure git knows your name and email address: + +``` +$ git config --global user.name "J. Random User" +$ git config --global user.email "j.random.user@example.com" +``` + +Writing good commit logs is important. A commit log should describe what +changed and why. Follow these guidelines when writing one: + +1. The first line should be 50 characters or less and contain a short + description of the change prefixed with the name of the changed + subsystem (e.g. "net: add localAddress and localPort to Socket"). +2. Keep the second line blank. +3. Wrap all other lines at 72 columns. + +A good commit log looks like this: + +``` +subsystem: explaining the commit in one line + +Body of commit message is a few lines of text, explaining things +in more detail, possibly giving some background about the issue +being fixed, etc etc. + +The body of the commit message can be several paragraphs, and +please do proper word-wrap and keep columns shorter than about +72 characters or so. That way `git log` will show things +nicely even when it is indented. +``` + +The header line should be meaningful; it is what other people see when they +run `git shortlog` or `git log --oneline`. + +Check the output of `git log --oneline files_that_you_changed` to find out +what subsystem (or subsystems) your changes touch. + + +### REBASE + +Use `git rebase` (not `git merge`) to sync your work from time to time. + +``` +$ git fetch upstream +$ git rebase upstream/v1.x # or upstream/master +``` + + +### TEST + +Bug fixes and features should come with tests. Add your tests in the +`test/` directory. Each new test needs to be registered in `test/test-list.h`. + +If you add a new test file, it needs to be registered in three places: +- `CMakeLists.txt`: add the file's name to the `uv_test_sources` list. +- `Makefile.am`: add the file's name to the `test_run_tests_SOURCES` list. + +Look at other tests to see how they should be structured (license boilerplate, +the way entry points are declared, etc.). + +Check README.md file to find out how to run the test suite and make sure that +there are no test regressions. + +### PUSH + +``` +$ git push origin my-feature-branch +``` + +Go to https://github.com/username/libuv and select your feature branch. Click +the 'Pull Request' button and fill out the form. + +Pull requests are usually reviewed within a few days. If there are comments +to address, apply your changes in a separate commit and push that to your +feature branch. Post a comment in the pull request afterwards; GitHub does +not send out notifications when you add commits. + + +[issue tracker]: https://github.com/libuv/libuv/issues +[libuv mailing list]: http://groups.google.com/group/libuv +[libuv discussions forum]: https://github.com/libuv/libuv/discussions +[Google C/C++ style guide]: https://google.github.io/styleguide/cppguide.html +[project maintainers]: https://github.com/libuv/libuv/blob/master/MAINTAINERS.md diff --git a/external/src/libuv/ChangeLog b/external/src/libuv/ChangeLog new file mode 100644 index 0000000..11492c5 --- /dev/null +++ b/external/src/libuv/ChangeLog @@ -0,0 +1,5209 @@ +2021.07.21, Version 1.42.0 (Stable), 6ce14710da7079eb248868171f6343bc409ea3a4 + +Changes since version 1.41.0: + +* doc: fix code highlighting (Darshan Sen) + +* test: move to ASSERT_NULL and ASSERT_NOT_NULL test macros (tjarlama) + +* zos: build in ascii code page (Shuowang (Wayne) Zhang) + +* zos: don't use nanosecond timestamp fields (Shuowang (Wayne) Zhang) + +* zos: introduce zoslib (Shuowang (Wayne) Zhang) + +* zos: use strnlen() from zoslib (Shuowang (Wayne) Zhang) + +* zos: use nanosleep() from zoslib (Shuowang (Wayne) Zhang) + +* zos: use __getargv() from zoslib to get exe path (Shuowang (Wayne) Zhang) + +* zos: treat __rfim_utok as binary (Shuowang (Wayne) Zhang) + +* zos: use execvpe() to set environ explictly (Shuowang (Wayne) Zhang) + +* zos: use custom proctitle implementation (Shuowang (Wayne) Zhang) + +* doc: add instructions for building on z/OS (Shuowang (Wayne) Zhang) + +* linux,udp: enable full ICMP error reporting (OndÅ™ej Surý) + +* test: fix test-udp-send-unreachable (OndÅ™ej Surý) + +* include: fix typo in documentation (Tobias Nießen) + +* chore: use for(;;) instead of while (Yash Ladha) + +* test: remove string + int warning on udp-pummel (Juan José Arboleda) + +* cmake: fix linker flags (Zhao Zhili) + +* test: fix stack-use-after-scope (Zhao Zhili) + +* unix: expose thread_stack_size() internally (Brandon Cheng) + +* darwin: use RLIMIT_STACK for fsevents pthread (Brandon Cheng) + +* darwin: abort on pthread_attr_init fail (Brandon Cheng) + +* benchmark: remove unreachable code (Matvii Hodovaniuk) + +* macos: fix memleaks in uv__get_cpu_speed (George Zhao) + +* Make Thread Sanitizer aware of file descriptor close in uv__close() (OndÅ™ej + Surý) + +* darwin: fix iOS compilation and functionality (Hayden) + +* linux: work around copy_file_range() cephfs bug (Ben Noordhuis) + +* zos: implement uv_get_constrained_memory() (Shuowang (Wayne) Zhang) + +* zos: fix uv_get_free_memory() (Shuowang (Wayne) Zhang) + +* zos: use CVTRLSTG to get total memory accurately (Shuowang (Wayne) Zhang) + +* ibmi: Handle interface names longer than 10 chars (Kevin Adler) + +* docs: update read-the-docs version of sphinx (Jameson Nash) + +* unix: refactor uv_try_write (twosee) + +* linux-core: add proper divide by zero assert (yiyuaner) + +* misc: remove unnecessary _GNU_SOURCE macros (Darshan Sen) + +* test: log to stdout to conform TAP spec (bbara) + +* win,fs: fix C4090 warning with MSVC (SeverinLeonhardt) + +* build: some systems provide dlopen() in libc (Andy Fiddaman) + +* include: add EOVERFLOW status code mapping (Darshan Sen) + +* unix,fs: use uv__load_relaxed and uv__store_relaxed (Darshan Sen) + +* win: fix string encoding issue of uv_os_gethostname (Eagle Liang) + +* unix,process: add uv__write_errno helper function (Ricky Zhou) + +* Re-merge "unix,stream: clear read/write states on close/eof" (Jameson Nash) + +* unix,core: fix errno handling in uv__getpwuid_r (Darshan Sen) + +* errors: map ESOCKTNOSUPPORT errno (Ryan Liptak) + +* doc: uv_read_stop always succeeds (Simon Kissane) + +* inet: fix inconsistent return value of inet_ntop6 (twosee) + +* darwin: fix -Wsometimes-uninitialized warning (twosee) + +* stream: introduce uv_try_write2 function (twosee) + +* poll,win: UV_PRIORITIZED option should not assert (twosee) + +* src: DragonFlyBSD has mmsghdr struct too (David Carlier) + +* cleanup,win: Remove _WIN32 guards on threadpool (James M Snell) + +* freebsd: fix an incompatible pointer type warning (Darshan Sen) + +* core: Correct the conditionals for {cloexec,nonblock}_ioctl (Ali Mohammad + Pur) + +* win,tcp: make uv_close work more like unix (Jameson Nash) + +* doc: more accurate list of valid send_handle's (twosee) + +* win,tcp: translate system errors correctly (twosee) + +* unix: implement cpu_relax() on ppc64 (Ben Noordhuis) + +* docs: move list of project links under PR control (Jameson Nash) + +* test: wrong pointer arithmetic multiplier (Erkhes N) + +* doc: switch discussion forum to github (Jameson Nash) + +* idna: fix OOB read in punycode decoder (Ben Noordhuis) + +* build: make sure -fvisibility=hidden is set (Santiago Gimeno) + +* illumos: event ports to epoll (tjarlama) + +* illumos,tty: UV_TTY_MODE_IO waits for 4 bytes (Joshua M. Clulow) + +* doc: add vtjnash GPG ID (Jameson Nash) + +* linux: read CPU model information on ppc (Richard Lau) + +* darwin: fix uv_barrier race condition (Guilherme Ãscaro) + +* unix,stream: fix loop hang after uv_shutdown (Jameson Nash) + +* doc,udp: note that suggested_size is 1 max-sized dgram (Ryan Liptak) + +* mingw: fix building for ARM/AArch64 (Martin Storsjö) + +* unix: strnlen is not available on Solaris 10 (Claes Nästén) + +* sunos: restore use of event ports (Andy Fiddaman) + +* sunos,cmake: use thread-safe errno (Andy Fiddaman) + + +2021.02.14, Version 1.41.0 (Stable), 1dff88e5161cba5c59276d2070d2e304e4dcb242 + +Changes since version 1.40.0: + +* mailmap: update contact information for richardlau (Richard Lau) + +* build: add asan checks (gengjiawen) + +* unix: report bind error in uv_tcp_connect() (Ben Noordhuis) + +* doc: uv_tcp_bind() never returns UV_EADDRINUSE (Ben Noordhuis) + +* test: fix pump and tcp_write_batch benchmarks (Santiago Gimeno) + +* doc: mark IBM i as Tier 2 support (Jesse Gorzinski) + +* doc,poll: add notes (repeated cb & cancel pending cb) (Elad Nachmias) + +* linux: fix -Wincompatible-pointer-types warning (Ben Noordhuis) + +* linux: fix -Wsign-compare warning (Ben Noordhuis) + +* android: add system call api guards (Ben Noordhuis) + +* unix,win: harmonize uv_read_start() error handling (Ben Noordhuis) + +* unix,win: more uv_read_start() argument validation (Ben Noordhuis) + +* build: turn on -fno-strict-aliasing (Ben Noordhuis) + +* stream: add uv_pipe and uv_socketpair to the API (Jameson Nash) + +* unix,win: initialize timer `timeout` field (Ben Noordhuis) + +* bsd-ifaddrs: improve comments (Darshan Sen) + +* test: remove unnecessary uv_fs_stat() calls (Ben Noordhuis) + +* fs: fix utime/futime timestamp rounding errors (Ben Noordhuis) + +* test: ensure reliable floating point comparison (Jameson Nash) + +* unix,fs: fix uv_fs_sendfile() (Santiago Gimeno) + +* unix: fix uv_fs_stat when using statx (Simon Kadisch) + +* linux,macos: fix uv_set_process_title regression (Momtchil Momtchev) + +* doc: clarify UDP errors and recvmmsg (Ethel Weston) + +* test-getaddrinfo: use example.invalid (Drew DeVault) + +* Revert "build: fix android autotools build" (Bernardo Ramos) + +* unix,fs: on DVS fs, statx returns EOPNOTSUPP (Mark Klein) + +* win, fs: mkdir really return UV_EINVAL for invalid names (Nicholas Vavilov) + +* tools: migrate tools/make_dist_html.py to python3 (Dominique Dumont) + +* unix: fix uv_uptime() on linux (schamberg97) + +* unix: check for partial copy_file_range support (Momtchil Momtchev) + +* win: bump minimum supported version to windows 8 (Ben Noordhuis) + +* poll,unix: ensure safety of rapid fd reuse (Bob Weinand) + +* test: fix some warnings (Issam E. Maghni) + +* unix: fix uv_uptime() regression (Santiago Gimeno) + +* doc: fix versionadded metadata (cjihrig) + +* test: fix 'incompatible pointer types' warnings (cjihrig) + +* unix: check for EXDEV in uv__fs_sendfile() (Darshan Sen) + + +2020.09.26, Version 1.40.0 (Stable), 4e69e333252693bd82d6338d6124f0416538dbfc + +Changes since version 1.39.0: + +* udp: add UV_UDP_MMSG_FREE recv_cb flag (Ryan Liptak) + +* include: re-map UV__EPROTO from 4046 to -4046 (YuMeiJie) + +* doc: correct UV_UDP_MMSG_FREE version added (cjihrig) + +* doc: add uv_metrics_idle_time() version metadata (Ryan Liptak) + +* win,tty: pass through utf-16 surrogate pairs (Mustafa M) + +* unix: fix DragonFly BSD build (Aleksej Lebedev) + +* win,udp: fix error code returned by connect() (Santiago Gimeno) + +* src: suppress user_timeout maybe-uninitialized (Daniel Bevenius) + +* test: fix compiler warning (Vladimír ÄŒunát) + +* build: fix the Haiku cmake build (David Carlier) + +* linux: fix i386 sendmmsg/recvmmsg support (Ben Noordhuis) + +* build: add libuv-static pkg-config file (Nikolay Mitev) + +* unix,win: add uv_timer_get_due_in() (Ulrik Strid) + +* build,unix: add QNX support (Elad Lahav) + +* include: remove incorrect UV__ERR() for EPROTO (cjihrig) + + +2020.08.26, Version 1.39.0 (Stable), 25f4b8b8a3c0f934158cd37a37b0525d75ca488e + +Changes since version 1.38.1: + +* unix: use relaxed loads/stores for clock id (Ben Noordhuis) + +* build,win: link to user32.lib and advapi32.lib (George Zhao) + +* unix: squelch harmless valgrind warning (ssrlive) + +* include: fx c++ style comments warnings (Turbinya) + +* build,cmake: Change installation location on MinGW (erw7) + +* linux: use copy_file_range for uv_fs_copyfile when possible (Carter Li) + +* win,tcp: avoid reinserting a pending request ( + +* docs: improve the descriptions for get memory info (Juan Sebastian velez + Posada) + +* test: add udp-mmsg test (Ryan Liptak) + +* udp: add uv_udp_using_recvmmsg query (Ryan Liptak) + +* doc: add more error constants (TK-one) + +* zos: fix potential event loop stall (Trevor Norris) + +* include: add internal fields struct to uv_loop_t (Trevor Norris) + +* core: add API to measure event loop idle time (Trevor Norris) + +* win,fs: use CreateDirectoryW instead of _wmkdir (Mustafa M) + +* win,nfc: fix integer comparison signedness (escherstair) + +* win,nfc: use + +* win,nfc: removed some unused variables (escherstair) + +* win,nfc: add missing return statement (escherstair) + +* win,nfc: disable clang-format for + +* darwin: use IOKit for uv_cpu_info (Evan Lucas) + +* test: fix thread race in process_title_threadsafe (Ben Noordhuis) + +* win,fs: avoid implicit access to _doserrno (Jameson Nash) + +* test: give hrtime test a custom 20s timeout (Jameson Nash) + +* build: add more failed test, for qemu version bump (gengjiawen) + +* unix: handle src, dest same in uv_fs_copyfile() (cjihrig) + +* unix: error when uv_setup_args() is not called (Ryan Liptak) + +* aix: protect uv_exepath() from uv_set_process_title() (Richard Lau) + +* fs: clobber req->path on uv_fs_mkstemp() error (tjarlama) + +* cmake: fix compile error C2001 on Chinese Windows (å¸å¾’玟ç…) + +* test: avoid double evaluation in ASSERT_BASE macro (tjarlama) + +* tcp: fail instantly if local port is unbound (Bartosz Sosnowski) + +* doc: fix most sphinx warnings (Jameson Nash) + +* nfci: address some style nits (Jameson Nash) + +* unix: don't use _POSIX_PATH_MAX (Ben Noordhuis) + + +2020.07.04, Version 1.38.1 (Stable), e8b989ea1f7f9d4083511a2caec7791e9abd1871 + +Changes since version 1.38.0: + +* test: use last matching qemu version (cjihrig) + +* win, util: rearrange uv_hrtime (Bartosz Sosnowski) + +* test: skip signal_multiple_loops test on QEMU (gengjiawen) + +* build: add android build to CI (gengjiawen) + +* test: extend fs_event_error_reporting timeout (cjihrig) + +* build: link libkvm on netbsd only (Alexander Tokmakov) + +* linux: refactor /proc file reader logic (Ben Noordhuis) + +* linux: read load average from /proc/loadavg (Ben Noordhuis) + +* android: remove patch code for below 21 (gengjiawen) + +* win: fix visual studio 2008 build (Arenoros) + +* win,tty: fix deadlock caused by inconsistent state (lander0s) + +* unix: use relaxed loads/stores for feature checks (Ben Noordhuis) + +* build: don't .gitignore m4/ax_pthread.m4 (Ben Noordhuis) + +* unix: fix gcc atomics feature check (Ben Noordhuis) + +* darwin: work around clock jumping back in time (Ben Noordhuis) + +* udp: fix write_queue cleanup on sendmmsg error (Santiago Gimeno) + +* src: build fix for Android (David Carlier) + + +2020.05.18, Version 1.38.0 (Stable), 1ab9ea3790378f9f25c4e78e9e2b511c75f9c9ed + +Changes since version 1.37.0: + +* test: skip poll_duplex and poll_unidirectional on PASE (Xu Meng) + +* linux: make cpu_times consistently be milliseconds (James Ross) + +* win: DRY uv_poll_start() and uv_poll_stop() (Ben Noordhuis) + +* win: DRY uv_poll_close() (Ben Noordhuis) + +* unix,win: add uv_library_shutdown() (Ben Noordhuis) + +* unix: yield cpu when spinlocking on async handle (Ben Noordhuis) + +* win: remove dep on GetQueuedCompletionStatusEx (Colin Finck) + +* doc: correct source lines (Shohei YOSHIDA) + +* build,android: fix typo (twosee) + +* doc: uv_cancel() handles uv_random_t requests (Philip Chimento) + +* doc: fix unescaped character (Philip Chimento) + +* build,cmake: fix compilation on old MinGW (erw7) + +* build: remove unnessesary MSVC warnings (Bartosz Sosnowski) + +* win: make uv_udp_init_ex() accept UV_UDP_RECVMMSG (Ben Noordhuis) + +* unix: simplify uv__udp_init_ex() (Ben Noordhuis) + +* win: remove MAX_PATH limitations (Bartosz Sosnowski) + +* build, win: add long path aware manifest (Bartosz Sosnowski) + +* doc: check/idle/prepare functions always succeed (Ben Noordhuis) + +* darwin: fix build with non-apple compilers (Ben Noordhuis) + +* win: support environment variables > 32767 chars (Ben Noordhuis) + +* unix: fully initialize struct msghdr (Ben Noordhuis) + +* doc: add uv_replace_allocator thread safety warning (twosee) + +* unix: fix int overflow when copying large files (Michal Artazov) + +* fs: report original error (Bartosz Sosnowski) + +* win, fs: add IO_REPARSE_TAG_APPEXECLINK support (Bartosz Sosnowski) + +* doc: fix formatting (Ben Noordhuis) + +* unix: fix memory leak when uv_loop_init() fails (Anna Henningsen) + +* unix: shrink uv_udp_set_source_membership() stack (Ben Noordhuis) + +* unix,win: fix wrong sizeof argument to memcpy() (Ben Noordhuis) + +* build: check for libraries not provided by libc (Jeroen Roovers) + +* doc: fix the order of arguments to calloc() (MasterDuke17) + +* unix: don't abort when getrlimit() fails (Ben Noordhuis) + +* test: support common user profile on IBMi (Xu Meng) + +* build: test on more platforms via QEMU in CI (gengjiawen) + + +2020.04.20, Version 1.37.0 (Stable), 02a9e1be252b623ee032a3137c0b0c94afbe6809 + +Changes since version 1.36.0: + +* timer: remove redundant check in heap compare (Yash Ladha) + +* udp: add flag to enable recvmmsg(2) explicitly (Saúl Ibarra Corretgé) + + +2020.04.16, Version 1.36.0 (Stable), 533b738838ad8407032e14b6772b29ef9af63cfa + +Changes since version 1.35.0: + +* build: add aix-common.c for AIX cmake build (Jesse Gorzinski) + +* zos: explicitly mark message queue events (Irek Fakhrutdinov) + +* zos: move mq check out of loop to save cpu cycles (Irek Fakhrutdinov) + +* zos: add checks to ensure behavior of epoll_wait (Irek Fakhrutdinov) + +* src: add uv__reallocf() (Ben Noordhuis) + +* build: ibmi support for cmake (Jesse Gorzinski) + +* build: fix gyp build for Android API >= 28 (Lin Zhang) + +* udp: return recvmmsg-ed datagrams in order (Saúl Ibarra Corretgé) + +* zos,test: fix spawn_empty_env for shared library build (Richard Lau) + +* zos: fix non-Release builds (Richard Lau) + +* zos: fix return value on expired nanosleep() call (Richard Lau) + +* build: fix z/OS cmake build (Richard Lau) + +* test: add a bunch of ASSERT macros (Santiago Gimeno) + +* test: remove unused extern declaration (Ben Noordhuis) + +* test: canonicalize argv[0] in exepath test (Ben Noordhuis) + +* test: simplify platform_init() (Ben Noordhuis) + +* ibmi: Fix isatty EBADF handling and refactor (Kevin Adler) + +* test: Test EBADF tty handling (Kevin Adler) + +* build: make cmake build benchmarks (Ben Noordhuis) + +* win: use RtlGenRandom from advapi32.dll directly (Ben Noordhuis) + +* android: fix OOB write in uv_interface_addresses() (Lin Zhang) + +* test: pass test when hostname is single character (毛毛) + +* ibmi: set the highest process priority to -10 (Xu Meng) + +* build: remove support for gyp (Ben Noordhuis) + +* doc: add note to README on cross-compiling (Ben Noordhuis) + +* fs: add uv_fs_lutime() (Sk Sajidul Kadir) + +* unix: implement cpu_relax() for arm (David Carlier) + +* linux: fix uv__accept4() (twosee) + +* win: handle file paths in uv_fs_statfs() (erw7) + +* unix: fix uv_os_environ() null pointer check (Rikard Falkeborn) + +* win: fix uv_os_environ() null pointer check (Rikard Falkeborn) + +* unix: fix compilation on macOS 32-bit architectures (Brad King) + +* win: replace alloca() with stack-based array (Ben Noordhuis) + + +2020.03.12, Version 1.35.0 (Stable), e45f1ec38db882f8dc17b51f51a6684027034609 + +Changes since version 1.34.2: + +* src: android build fix (David Carlier) + +* build: make code compilable for iOS on Xcode (ssrlive) + +* ibmi: skip unsupported fs test cases (Xu Meng) + +* ibmi: ensure that pipe backlog is not zero (Xu Meng) + +* test,udp6: fix udp_ipv6 test flakiness (Jameson Nash) + +* test: fix fs_event_watch_dir_recursive flakiness (Santiago Gimeno) + +* pipe: disallow listening on an IPC pipe (Witold KrÄ™cicki) + +* build,cmake: improve buil experience (Isabella Muerte) + +* unix: remove support for FreeBSD < 10 (Saúl Ibarra Corretgé) + +* linux: simplify uv__accept() (Ben Noordhuis) + +* linux: assume presence of SOCK_CLOEXEC flag (Ben Noordhuis) + +* linux: simplify uv__dup2_cloexec() (Ben Noordhuis) + +* freebsd,linux: simplify uv__make_socketpair() (Ben Noordhuis) + +* unix: fix error handling in uv__make_socketpair() (Ben Noordhuis) + +* freebsd,linux: simplify uv__make_pipe() (Ben Noordhuis) + +* unix: fix error handling in uv__make_pipe() (Ben Noordhuis) + +* linux: simplify uv__async_eventfd() (Ben Noordhuis) + +* linux: assume the presence of inotify system calls (Ben Noordhuis) + +* doc: strip ICC profile from 2 jpg files (Dominique Dumont) + +* unix: make uv_tcp_keepalive predictable (Manuel BACHMANN) + +* docs: uv_setup_args() may take ownership of argv (Ben Noordhuis) + +* unix: fix error path in uv_setup_args() (Ben Noordhuis) + +* unix: fix size check in uv_get_process_title() (Ben Noordhuis) + +* doc: add erw7 to maintainers (erw7) + +* test: fixed udp4_echo_server implementation (Marek Vavrusa) + +* test: added udp ping benchmark (1,10,100 pingers) (Marek Vavrusa) + +* freebsd,linux: add recvmmsg() + sendmmsg() udp implementation (Marek Vavrusa) + +* win,pipe: DRY/simplify some code paths (Jameson Nash) + +* win: address some style nits (Jameson Nash) + +* win,pipe: ensure `req->event_handle` is defined (Elliot Saba) + +* win,pipe: consolidate overlapped initialization (Elliot Saba) + +* win,pipe: erase event_handle after deleting pointer (Jameson Nash) + +* build: fix android cmake build, build missing file (Ben Noordhuis) + +* test: skip some UDP tests on IBMi (Xu Meng) + +* test: skip some spawn test cases on IBMi (Xu Meng) + +* src: fix wrong method name in comment (TK-one) + +* test: add UV_TIMEOUT_MULTIPLIER environment var (Ben Noordhuis) + +* unix: fix uv_cpu_info always returning UV_ENOTDIR on OpenBSD (Ben Davies) + +* test: skip the pwd_shell test on IBMi (Xu Meng) + +* win,tty: Change to restore cursor shape with uv_tty_reset() (erw7) + +* win,tty: Added set cursor style to CSI sequences (erw7) + +* test: handle EINTR, fix EOF check in poll test (Ben Noordhuis) + +* unix: use socklen_t instead of size_t (Ben Noordhuis) + +* doc: fix header file location (TK-one) + +* unix: fix signal handle closing deferral (Ben Noordhuis) + +* ibmi: set the amount of memory in use to zero (Xu Meng) + +* zos: return on realloc failure in scandir() (Milad Farazmand) + +* zos: fix scandir() error path NULL pointer deref (Ben Noordhuis) + + +2020.01.24, Version 1.34.2 (Stable), f868c9ab0c307525a16fff99fd21e32a6ebc3837 + +Changes since version 1.34.1: + +* misc: adjust stalebot deadlines (Jameson Nash) + +* test: fix env-vars flakiness (cjihrig) + +* test: avoid truncating output lines (Jameson Nash) + +* darwin: stop calling SetApplicationIsDaemon() (Ben Noordhuis) + +* ibmi: implement uv_interface_addresses() (Xu Meng) + +* osx,fsevent: fix race during uv_loop_close (Jameson Nash) + +* osx,fsevent: clear pointer when deleting it [NFCI] (Jameson Nash) + +* Revert "aix: replace ECONNRESET with EOF if already closed" (Jameson Nash) + +* unix: handle uv__open_cloexec return value correctly (Anna Henningsen) + + +2020.01.13, Version 1.34.1 (Stable), 8aa5636ec72990bb2856f81e14c95813024a5c2b + +Changes since version 1.34.0: + +* unix: fix -Wstrict-aliasing compiler warning (Ben Noordhuis) + +* unix: cache address of dlsym("mkostemp") (Ben Noordhuis) + +* build: remove -pedantic from compiler flags (Ben Noordhuis) + +* Revert "darwin: assume pthread_setname_np() is available" (Ben Noordhuis) + +* Revert "darwin: speed up uv_set_process_title()" (Ben Noordhuis) + +* darwin: assume pthread_setname_np() is available (Ben Noordhuis) + +* ibmi: fix the false isatty() issue on IBMi (Xu Meng) + +* test: fix test failure under NetBSD and OpenBSD (David Carlier) + +* test: skip some test cases on IBMi (Xu Meng) + +* test: skip uv_(get|set)_process_title on IBMi (Xu Meng) + +* doc: remove binaries for Windows from README (Richard Lau) + +* unix: fix -Wunused-but-set-variable warning (George Zhao) + +* unix: pass sysctl size arg using ARRAY_SIZE macro (David Carlier) + +* test: disallow running the test suite as root (cjihrig) + +* unix: suppress -Waddress-of-packed-member warning (Ben Noordhuis) + +* misc: make more tags "not-stale" (Jameson Nash) + +* test: fix pthread memory leak (Trevor Norris) + +* docs: delete socks5-proxy sample (Jameson Nash) + +* ibmi: fix the CMSG length issue (Xu Meng) + +* docs: fix formatting (Jameson Nash) + +* unix: squelch fchmod() EPERM on CIFS share (Ben Noordhuis) + +* docs: fix linkcheck (Jameson Nash) + +* docs: switch from linux.die.net to man7.org (Jameson Nash) + +* win: remove abort when non-IFS LSP detection fails (virtualyw) + +* docs: clarify that uv_pipe_t is a pipe (Jameson Nash) + +* win,tty: avoid regressions in utf-8 handling (Jameson Nash) + +* win: remove bad assert in uv_loop_close (Jameson Nash) + +* test: fix -fno-common build errors (Ben Noordhuis) + +* build: turn on -fno-common to catch regressions (Ben Noordhuis) + +* test: fix fs birth time test failure (Ben Noordhuis) + +* tty,unix: avoid affecting controlling TTY (Jameson Nash) + + +2019.12.05, Version 1.34.0 (Stable), 15ae750151ac9341e5945eb38f8982d59fb99201 + +Changes since version 1.33.1: + +* unix: move random-sysctl to random-sysctl-linux (nia) + +* netbsd: use KERN_ARND sysctl to get entropy (nia) + +* unix: refactor uv__fs_copyfile() logic (cjihrig) + +* build: fix android build, add missing sources (Ben Noordhuis) + +* build: fix android build, fix symbol redefinition (Ben Noordhuis) + +* build: fix android autotools build (Ben Noordhuis) + +* fs: handle non-functional statx system call (Milad Farazmand) + +* unix,win: add uv_sleep() (cjihrig) + +* doc: add richardlau to maintainers (Richard Lau) + +* aix: fix netmask for IPv6 (Richard Lau) + +* aix: clean up after errors in uv_interface_addresses() (Richard Lau) + +* aix: fix setting of physical addresses (Richard Lau) + +* fs: add uv_fs_mkstemp (Saúl Ibarra Corretgé) + +* unix: switch uv_sleep() to nanosleep() (Ben Noordhuis) + +* unix: retry on EINTR in uv_sleep() (Ben Noordhuis) + +* zos: fix nanosleep() emulation (Ben Noordhuis) + + +2019.10.20, Version 1.33.1 (Stable), 07ad32138f4d2285ba2226b5e20462b27b091a59 + +Changes since version 1.33.0: + +* linux: fix arm64 SYS__sysctl build breakage (Ben Noordhuis) + + +2019.10.17, Version 1.33.0 (Stable), e56e42e9310e4437e1886dbd6771792c14c0a5f3 + +Changes since version 1.32.0: + +* Revert "linux: drop code path for epoll_pwait-less kernels" (Yang Yu) + +* build: fix build error with __ANDROID_API__ < 21 (Yang Yu) + +* win: fix reading hidden env vars (Anna Henningsen) + +* unix,win: add uv_random() (Ben Noordhuis) + +* win: simplify mkdtemp (Saúl Ibarra Corretgé) + +* docs: fix literal-includes in User Guide (Nhan Khong) + +* win, tty: fix problem of receiving unexpected SIGWINCH (erw7) + +* unix: fix {Net,Open}BSD build (David Carlier) + +* win,mingw: Fix undefined MCAST_* constants (Crunkle) + +* build: Add link for test/fixtures/lorem_ipsum.txt (Andrew Paprocki) + +* fs: use statvfs in uv__fs_statfs() for Haiku (Calvin Hill) + +* fsevents: stop using fsevents to watch files (Jameson Nash) + +* fsevents: regression in watching / (Jameson Nash) + +* build,cmake: don't try to detect a C++ compiler (Isabella Muerte) + +* build: fix build warning on cygwin (MaYuming) + +* unix: set sin_len and sin6_len (Ouyang Yadong) + +* test: fix order of operations in test (cjihrig) + +* doc: improve uv_fs_readdir() cleanup docs (cjihrig) + +* build: remove duplicated test in build files (ZYSzys) + +* android: enable getentropy on Android >= 28 (David Carlier) + +* android: fix build (David Carlier) + +* darwin: speed up uv_set_process_title() (Ben Noordhuis) + +* darwin: assume pthread_setname_np() is available (Ben Noordhuis) + +* unix,udp: ensure addr is non-null (Jameson Nash) + +* win,tty: add uv_tty_{get,set}_vterm_state (erw7) + +* win: fix uv_statfs_t leak in uv_fs_statfs() (Ryan Liptak) + +* build: install files on windows via cmake (Carl Lei) + +* darwin,test: include AvailabilityMacros.h (Saúl Ibarra Corretgé) + +* darwin,test: update loop time after sleeping (Saúl Ibarra Corretgé) + +* doc: remove old FreeBSD 9 related note (Saúl Ibarra Corretgé) + +* doc: improve uv_{send,recv}_buffer_size() docs (Ryan Liptak) + +* build: move -Wno-long-long check to configure time (Ben Noordhuis) + +* unix: update uv_fs_copyfile() fallback logic (Stefan Bender) + +* win: cast setsockopt struct to const char* (Shelley Vohr) + + +2019.09.10, Version 1.32.0 (Stable), 697bea87b3a0b0e9b4e5ff86b39d1dedb70ee46d + +Changes since version 1.31.0: + +* misc: enable stalebot (Saúl Ibarra Corretgé) + +* win: map ERROR_ENVVAR_NOT_FOUND to UV_ENOENT (cjihrig) + +* win: use L'\0' as UTF-16 null terminator (cjihrig) + +* win: support retrieving empty env variables (cjihrig) + +* unix,stream: fix returned error codes (Santiago Gimeno) + +* test: fix typo in DYLD_LIBRARY_PATH (Ben Noordhuis) + +* unix,signal: keep handle active if pending signal (Santiago Gimeno) + +* openbsd: fix uv_cpu_info (Santiago Gimeno) + +* src: move uv_free_cpu_info to uv-common.c (Santiago Gimeno) + +* tcp: add uv_tcp_close_reset method (Santiago Gimeno) + +* test: fix udp-multicast-join tests (Santiago Gimeno) + +* test: remove assertion in fs_statfs test (cjihrig) + +* doc: clarify uv_buf_t usage in uv_alloc_cb (Tomas Krizek) + +* win: fix typo in preprocessor expression (Konstantin Podsvirov) + +* timer: fix uv_timer_start on closing timer (seny) + +* udp: add source-specific multicast support (Vladimir Karnushin) + +* udp: fix error return values (Santiago Gimeno) + +* udp: drop IPV6_SSM_SUPPORT macro (Santiago Gimeno) + +* udp: fix uv__udp_set_source_membership6 (Santiago Gimeno) + +* udp: use sockaddr_storage instead of union (Santiago Gimeno) + +* build,zos: add _OPEN_SYS_SOCK_EXT3 flag (Santiago Gimeno) + +* test: add specific source multicast tests (Santiago Gimeno) + +* include: map EILSEQ error code (cjihrig) + +* win, tty: improve SIGWINCH performance (Bartosz Sosnowski) + +* build: fix ios build error (MaYuming) + +* aix: replace ECONNRESET with EOF if already closed (Milad Farazmand) + +* build: add cmake library VERSION, SOVERSION (Eneas U de Queiroz) + +* build: make include/ public in CMakeLists.txt (Ben Noordhuis) + +* build: export USING_UV_SHARED=1 to cmake deps (Ben Noordhuis) + +* build: cmake_minimum_required(VERSION 2.8.12) (Daniel Hahler) + +* aix: Fix broken cmpxchgi() XL C++ specialization. (Andrew Paprocki) + +* test: fix -Wsign-compare warning (Ben Noordhuis) + +* unix: simplify open(O_CLOEXEC) feature detection (Ben Noordhuis) + +* unix: fix UV_FS_O_DIRECT definition on Linux (Joran Dirk Greef) + +* doc: uv_handle_t documentation suggestion (Daniel Bevenius) + + +2019.08.10, Version 1.31.0 (Stable), 0a6771cee4c15184c924bfe9d397bdd0c3b206ba + +Changes since version 1.30.1: + +* win,fs: don't modify global file translation mode (Javier Blazquez) + +* win: fix uv_os_tmpdir when env var is 260 chars (Mustafa M) + +* win: prevent tty event explosion machine hang (Javier Blazquez) + +* win: add UV_FS_O_FILEMAP (João Reis) + +* win, fs: mkdir return UV_EINVAL for invalid names (Bartosz Sosnowski) + +* github: add root warning to template (cjihrig) + +* win: misc fs cleanup (cjihrig) + +* unix,win: add uv_fs_statfs() (cjihrig) + +* test: avoid AF_LOCAL (Carlo Marcelo Arenas Belón) + +* unix,win: add ability to retrieve all env variables (Saúl Ibarra Corretgé) + +* Revert "darwin: speed up uv_set_process_title()" (Ben Noordhuis) + +* doc: add %p to valgrind log-file arg (Zach Bjornson) + +* doc: fix typo in basics.rst (Nan Xiao) + +* ibmi: support Makefile build for IBM i (Xu Meng) + +* OpenBSD: only get active CPU core count (Ben Davies) + +* test: fix gcc 8 warnings for tests (Nhan Khong) + +* ibmi: use correct header files (Xu Meng) + +* unix: clear UV_HANDLE_READING flag before callback (zyxwvu Shi) + +* unix: fix unused-function warning on BSD (Nhan Khong) + +* test: fix test runner on MinGW (Crunkle) + +* win: remove try-except outside MSVC (Crunkle) + +* win: fix uv_spawn() ENOMEM on empty env (Ben Noordhuis) + + +2019.07.03, Version 1.30.1 (Stable), 1551969c84c2f546a429dac169c7fdac3e38115e + +Changes since version 1.30.0: + +* doc: fix incorrect versionchanged (cjihrig) + +* test: allow UV_ECONNRESET in tcp_try_write_error (cjihrig) + +* unix: add uv_get_constrained_memory() cygwin stub (cjihrig) + +* build: fix android cmake build (Ben Noordhuis) + +* unix: squelch -Wcast-function-type warning (Ben Noordhuis) + +* build: fix compile error with uClibc (zlargon) + + +2019.06.28, Version 1.30.0 (Stable), 365b6f2a0eacda1ff52be8e57ab9381cfddc5dbb + +Changes since version 1.29.1: + +* darwin: fall back to F_BARRIERFSYNC (Ben Noordhuis) + +* darwin: add 32 bit close$NOCANCEL implementation (ken-cunningham-webuse) + +* build, core, unix: add support for Haiku (Leorize) + +* darwin,linux: more conservative minimum stack size (Ben Noordhuis) + +* threadpool: increase UV_THREADPOOL_SIZE limit (Vlad A) + +* unix: return actual error from `uv_try_write()` (Anna Henningsen) + +* darwin: fix build error with macos 10.10 (Ben Noordhuis) + +* unix: make uv_cwd() report UV_ENOBUFS (Ben Noordhuis) + +* unix: make uv_fs_read() fill all buffers (Ben Noordhuis) + +* test: give hrtime test a custom 10s timeout (Ben Noordhuis) + +* fs: fix uv_fs_copyfile if same src and dst (Santiago Gimeno) + +* build: add cmake option to skip building tests (Niels Lohmann) + +* doc: add link to nodejs.org (Jenil Christo) + +* unix: fix a comment typo in signal.c (Evgeny Ermakov) + +* unix: remove redundant cast in process.c (gengjiawen) + +* doc: fix wrong mutex function prototypes (Leo Chung) + + +2019.05.22, Version 1.29.1 (Stable), d16e6094e1eb3b0b5981ef1dd7e03ec4d466944d + +Changes since version 1.29.0: + +* unix: simplify uv/posix.h include logic (cjihrig) + +* test: increase test timeout (cjihrig) + +* linux: fix sscanf() overflows reading from /proc (Ben Noordhuis) + + +2019.05.16, Version 1.29.0 (Stable), 43957efd92c167b352b4c948b617ca7afbee0ed1 + +Changes since version 1.28.0: + +* ibmi: read memory and CPU usage info (Xu Meng) + +* doc: update the cmake testing instruction (zlargon) + +* unix: fix race condition in uv_async_send() (Ben Noordhuis) + +* linux: use O_CLOEXEC instead of EPOLL_CLOEXEC (Ben Noordhuis) + +* doc: mark uv_async_send() as async-signal-safe (Ben Noordhuis) + +* linux: init st_flags and st_gen when using statx (Oscar Waddell) + +* linux: read free/total memory from /proc/meminfo (Ben Noordhuis) + +* test: test zero-sized uv_fs_sendfile() writes (Ben Noordhuis) + +* unix: don't assert on UV_PROCESS_WINDOWS_* flags (Ben Noordhuis) + +* linux: set correct mac address for IP-aliases (Santiago Gimeno) + +* win,util: fix null pointer dereferencing (Tobias Nießen) + +* unix,win: fix `uv_fs_poll_stop()` when active (Anna Henningsen) + +* doc: add missing uv_fs_type entries (Michele Caini) + +* doc: fix build with sphinx 2.x (FX Coudert) + +* unix: don't make statx system call on Android (George Zhao) + +* unix: fix clang scan-build warning (Kyle Edwards) + +* unix: fall back to kqueue on older macOS systems (ken-cunningham-webuse) + +* unix,win: add uv_get_constrained_memory() (Kelvin Jin) + +* darwin: fix thread cancellation fd leak (Ben Noordhuis) + +* linux: fix thread cancellation fd leak (Ben Noordhuis) + + +2019.04.16, Version 1.28.0 (Stable), 7bf8fabfa934660ee0fe889f78e151198a1165fc + +Changes since version 1.27.0: + +* unix,win: add uv_gettimeofday() (cjihrig) + +* unix,win: add uv_fs_{open,read,close}dir() (cjihrig) + +* unix: fix uv_interface_addresses() (Andreas Rohner) + +* fs: remove macOS-specific copyfile(3) (Rich Trott) + +* fs: add test for copyfile() respecting permissions (Rich Trott) + +* build: partially revert 5234b1c43a (Ben Noordhuis) + +* zos: fix setsockopt error when using AF_UNIX (Milad Farazmand) + +* unix: suppress EINTR/EINPROGRESS in uv_fs_close() (Ben Noordhuis) + +* build: use cmake APPLE variable to detect platform (zlargon) + +* distcheck: remove duplicate test/ entry (Jameson Nash) + +* unix: remove unused cmpxchgl() function (Ben Noordhuis) + +* unix: support sockaddr_un in uv_udp_send() (Yury Selivanov) + +* unix: guard use of PTHREAD_STACK_MIN (Kamil Rytarowski) + +* unix,win: introduce uv_timeval64_t (cjihrig) + +* doc: document uv_timeval_t and uv_timeval64_t (cjihrig) + + +2019.03.17, Version 1.27.0 (Stable), a4fc9a66cc35256dbc4dcd67c910174f05b6daa6 + +Changes since version 1.26.0: + +* doc: describe unix signal handling better (Vladimír ÄŒunát) + +* linux: use statx() to obtain file birth time (Ben Noordhuis) + +* src: fill sockaddr_in6.sin6_len when it's defined (Santiago Gimeno) + +* test: relax uv_hrtime() test assumptions (Ben Noordhuis) + +* build: make cmake install LICENSE only once (Thomas Karl Pietrowski) + +* bsd: plug uv_fs_event_start() error path fd leak (Ben Noordhuis) + +* unix: fix __FreeBSD_kernel__ typo (cjihrig) + +* doc: add note about uv_run() not being reentrant (Ben Noordhuis) + +* unix, win: make fs-poll close wait for resource cleanup (Anna Henningsen) + +* doc: fix typo in uv_thread_options_t definition (Ryan Liptak) + +* win: skip winsock initialization in safe mode (evgley) + +* unix: refactor getsockname/getpeername methods (Santiago Gimeno) + +* win,udp: allow to use uv_udp_open on bound sockets (Santiago Gimeno) + +* udp: add support for UDP connected sockets (Santiago Gimeno) + +* build: fix uv_test shared uv Windows cmake build (ptlomholt) + +* build: add android-configure scripts to EXTRA_DIST (Ben Noordhuis) + +* build: add missing header (cjihrig) + +* sunos: add perror() output prior to abort() (Andrew Paprocki) + +* test,sunos: disable UV_DISCONNECT handling (Andrew Paprocki) + +* sunos: disable __attribute__((unused)) (Andrew Paprocki) + +* test,sunos: use unistd.h code branch (Andrew Paprocki) + +* build,sunos: better handling of non-GCC compiler (Andrew Paprocki) + +* test,sunos: fix statement not reached warnings (Andrew Paprocki) + +* sunos: fix argument/prototype mismatch in atomics (Andrew Paprocki) + +* test,sunos: test-ipc.c lacks newline at EOF (Andrew Paprocki) + +* test: change spawn_stdin_stdout return to void (Andrew Paprocki) + +* test: remove call to floor() in test driver (Andrew Paprocki) + + +2019.02.11, Version 1.26.0 (Stable), 8669d8d3e93cddb62611b267ef62a3ddb5ba3ca0 + +Changes since version 1.25.0: + +* doc: fix uv_get_free_memory doc (Stephen Belanger) + +* unix: fix epoll cpu 100% issue (yeyuanfeng) + +* openbsd,tcp: special handling of EINVAL on connect (ptlomholt) + +* win: simplify registry closing in uv_cpu_info() (cjihrig) + +* src,include: define UV_MAXHOSTNAMESIZE (cjihrig) + +* win: return product name in uv_os_uname() version (cjihrig) + +* thread: allow specifying stack size for new thread (Anna Henningsen) + +* win: fix duplicate tty vt100 fn key (erw7) + +* unix: don't attempt to invalidate invalid fd (Ben Noordhuis) + + +2019.01.19, Version 1.25.0 (Stable), 4a10a9d425863330af199e4b74bd688e62d945f1 + +Changes since version 1.24.1: + +* Revert "win,fs: retry if uv_fs_rename fails" (Ben Noordhuis) + +* aix: manually trigger fs event monitoring (Gireesh Punathil) + +* unix: rename WRITE_RETRY_ON_ERROR macro (Ben Noordhuis) + +* darwin: DRY platform-specific error check (Ben Noordhuis) + +* unix: refactor uv__write() (Ben Noordhuis) + +* unix: don't send handle twice on partial write (Ben Noordhuis) + +* tty,win: fix Alt+key under WSL (Bartosz Sosnowski) + +* build: support running tests in out-of-tree builds (Jameson Nash) + +* fsevents: really watch files with fsevents on macos 10.7+ (Jameson Nash) + +* thread,mingw64: need intrin.h header for SSE2 MemoryBarrier (Jameson Nash) + +* win: fix sizeof-pointer-div warning (cjihrig) + +* unix,win: add uv_os_uname() (cjihrig) + +* win, tty: fix CreateFileW() return value check (Bartosz Sosnowski) + +* unix: enable IPv6 tests on OpenBSD (ptlomholt) + +* test: fix test-ipc spawn_helper exit_cb (Santiago Gimeno) + +* test: fix test-ipc tests (Santiago Gimeno) + +* unix: better handling of unsupported F_FULLFSYNC (Victor Costan) + +* win,test: de-flake fs_event_watch_dir_short_path (Refael Ackermann) + +* win: fix msvc warning (sid) + +* openbsd: switch to libuv's barrier implementation (ptlomholt) + +* unix,stream: fix zero byte writes (Santiago Gimeno) + +* ibmi: return EISDIR on read from directory fd (Kevin Adler) + +* build: wrap long lines in Makefile.am (cjihrig) + + +2018.12.17, Version 1.24.1 (Stable), 274f2bd3b70847cadd9a3965577a87e666ab9ac3 + +Changes since version 1.24.0: + +* test: fix platform_output test on cygwin (damon-kwok) + +* gitignore: ignore build/ directory (Damon Kwok) + +* unix: zero epoll_event before use (Ashe Connor) + +* darwin: use runtime check for file cloning (Ben Noordhuis) + +* doc: replace deprecated build command on macOS (Rick) + +* warnings: fix code that emits compiler warnings (Jameson Nash) + +* doc: clarify expected memory management strategy (Ivan Krylov) + +* test: add uv_inet_ntop(AF_INET) coverage (Ben Noordhuis) + +* unix: harden string copying, introduce strscpy() (Ben Noordhuis) + +* linux: get rid of strncpy() call (Ben Noordhuis) + +* aix: get rid of strcat() calls (Ben Noordhuis) + +* aix: fix data race in uv_fs_event_start() (Ben Noordhuis) + +* win: fs: fix `FILE_FLAG_NO_BUFFERING` for writes (Joran Dirk Greef) + +* build: don't link against -lpthread on Android (Michael Meier) + + +2018.11.14, Version 1.24.0 (Stable), 2d427ee0083d1baf995df4ebf79a3f8890e9a3e1 + +Changes since version 1.23.2: + +* unix: do not require PATH_MAX to be defined (Brad King) + +* win,doc: path encoding in uv_fs_XX is UTF-8 (hitesh) + +* unix: add missing link dependency on kFreeBSD (Svante Signell) + +* unix: add support for GNU/Hurd (Samuel Thibault) + +* test: avoid memory leak for test_output (Carlo Marcelo Arenas Belón) + +* zos: avoid UB with NULL pointer arithmetic (Carlo Marcelo Arenas Belón) + +* doc: add vtjnash to maintainers (Jameson Nash) + +* unix: restore skipping of phys_addr copy (cjihrig) + +* unix,win: make uv_interface_addresses() consistent (cjihrig) + +* unix: remove unnecessary linebreaks (cjihrig) + +* unix,win: handle zero-sized allocations uniformly (Ben Noordhuis) + +* unix: remove unused uv__dup() function (Ben Noordhuis) + +* core,bsd: refactor process_title functions (Santiago Gimeno) + +* win: Redefine NSIG to consider SIGWINCH (Jeremy Studer) + +* test: make sure that reading a directory fails (Sakthipriyan Vairamani) + +* win, tty: remove zero-size read callbacks (Bartosz Sosnowski) + +* test: fix test runner getenv async-signal-safety (Ben Noordhuis) + +* test: fix test runner execvp async-signal-safety (Ben Noordhuis) + +* test,unix: fix race in test runner (Ben Noordhuis) + +* unix,win: support IDNA 2008 in uv_getaddrinfo() (Ben Noordhuis) + +* win, tcp: avoid starving the loop (Bartosz Sosnowski) + +* win, dl: proper error messages on some systems (Bartosz Sosnowski) + +* win,fs: retry if uv_fs_rename fails (Bartosz Sosnowski) + +* darwin: speed up uv_set_process_title() (Ben Noordhuis) + +* aix: fix race in uv_get_process_title() (Gireesh Punathil) + +* win: support more fine-grained windows hiding (Bartosz Sosnowski) + + +2018.10.09, Version 1.23.2 (Stable), 34c12788d2e7308f3ac506c0abcbf74c0d6abd20 + +Changes since version 1.23.1: + +* unix: return 0 retrieving rss on cygwin (cjihrig) + +* unix: initialize uv_interface_address_t.phys_addr (cjihrig) + +* test: handle uv_os_setpriority() windows edge case (cjihrig) + +* tty, win: fix read stop for raw mode (Bartosz Sosnowski) + +* Revert "Revert "unix,fs: fix for potential partial reads/writes"" (Jameson + Nash) + +* unix,readv: always permit partial reads to return (Jameson Nash) + +* win,tty: fix uv_tty_close() (Bartosz Sosnowski) + +* doc: remove extraneous "on" (Ben Noordhuis) + +* unix,win: fix threadpool race condition (Anna Henningsen) + +* unix: rework thread barrier implementation (Ben Noordhuis) + +* aix: switch to libuv's own thread barrier impl (Ben Noordhuis) + +* unix: signal done to last thread barrier waiter (Ben Noordhuis) + +* test: add uv_barrier_wait serial thread test (Ali Ijaz Sheikh) + +* unix: optimize uv_fs_readlink() memory allocation (Ben Noordhuis) + +* win: remove req.c and other cleanup (Carlo Marcelo Arenas Belón) + +* aix: don't EISDIR on read from directory fd (Ben Noordhuis) + + +2018.09.22, Version 1.23.1 (Stable), d2282b3d67821dc53c907c2155fa8c5c6ce25180 + +Changes since version 1.23.0: + +* unix,win: limit concurrent DNS calls to nthreads/2 (Anna Henningsen) + +* doc: add addaleax to maintainers (Anna Henningsen) + +* doc: add missing slash in stream.rst (Emil Bay) + +* unix,fs: use utimes & friends for uv_fs_utime (Jeremiah Senkpiel) + +* unix,fs: remove linux fallback from utimesat() (Jeremiah Senkpiel) + +* unix,fs: remove uv__utimesat() syscall fallback (Jeremiah Senkpiel) + +* doc: fix argument name in tcp.rts (Emil Bay) + +* doc: notes on running tests, benchmarks, tools (Jamie Davis) + +* linux: remove epoll syscall wrappers (Ben Noordhuis) + +* linux: drop code path for epoll_pwait-less kernels (Ben Noordhuis) + +* Partially revert "win,code: remove GetQueuedCompletionStatus-based poller" + (Jameson Nash) + +* build: add compile for android arm64/x86/x86-64 (Andy Zhang) + +* doc: clarify that some remarks apply to windows (Bert Belder) + +* test: fix compiler warnings (Jamie Davis) + +* ibmi: return 0 from uv_resident_set_memory() (dmabupt) + +* win: fix uv_udp_recv_start() error translation (Ryan Liptak) + +* win,doc: improve uv_os_setpriority() documentation (Bartosz Sosnowski) + +* test: increase upper bound in condvar_5 (Jamie Davis) + +* win,tty: remove deadcode (Jameson Nash) + +* stream: autodetect direction (Jameson Nash) + + +2018.08.18, Version 1.23.0 (Stable), 7ebb26225f2eaae6db22f4ef34ce76fa16ff89ec + +Changes since version 1.22.0: + +* win,pipe: restore compatibility with the old IPC framing protocol (Bert + Belder) + +* fs: add uv_open_osfhandle (Bartosz Sosnowski) + +* doc: update Visual C++ Build Tools URL (MichaÅ‚ Kozakiewicz) + +* unix: loop starvation on successful write complete (jBarz) + +* win: add uv__getnameinfo_work() error handling (A. Hauptmann) + +* win: return UV_ENOMEM from uv_loop_init() (cjihrig) + +* unix,win: add uv_os_{get,set}priority() (cjihrig) + +* test: fix warning in test-tcp-open (Santiago Gimeno) + + +2018.07.11, Version 1.22.0 (Stable), 8568f78a777d79d35eb7d6994617267b9fb33967 + +Changes since version 1.21.0: + +* unix: remove checksparse.sh (Ben Noordhuis) + +* win: fix mingw build error (Ben Noordhuis) + +* win: fix -Wunused-function warnings in thread.c (Ben Noordhuis) + +* unix,win: merge timers implementation (Ben Noordhuis) + +* win: fix pointer type in pipe.c (Ben Noordhuis) + +* win: fixing build for older MSVC compilers (Michael Fero) + +* zos: clear poll events on every iteration (jBarz) + +* zos: write-protect message queue (jBarz) + +* zos: use correct pointer type in strnlen (jBarz) + +* unix,win: merge handle flags (Ben Noordhuis) + +* doc: update Imran Iqbal's GitHub handle (cjihrig) + +* src: add new error apis to prevent memory leaks (Shelley Vohr) + +* test: make test-condvar call uv_cond_wait (Jamie Davis) + +* fs: change position of uv_fs_lchown (Ujjwal Sharma) + + +2018.06.23, Version 1.21.0 (Stable), e4983a9b0c152932f7553ff4a9ff189d2314cdcb + +Changes since version 1.20.3: + +* unix,windows: map EFTYPE errno (cjihrig) + +* win: perform case insensitive PATH= comparison (cjihrig) + +* win, fs: uv_fs_fchmod support for -A files (Bartosz Sosnowski) + +* src,lib: fix comments (Tobias Nießen) + +* win,process: allow child pipe handles to be opened in overlapped mode (Björn + Linse) + +* src,test: fix idiosyncratic comment style (Bert Belder) + +* test: fs_fchmod_archive_readonly must return a value (Bert Belder) + +* win,pipe: fix incorrect error code returned from uv_pipe_write_impl() (Bert + Belder) + +* win,pipe: properly set uv_write_t.send_handle in uv_write2() (Bert Belder) + +* test: add vectored uv_write() ping-pong tests (Bert Belder) + +* win,pipe: support vectored uv_write() calls (Bert Belder) + +* win,pipe: refactor pipe read cancellation logic (Bert Belder) + +* test: improve output from IPC test helpers (Bert Belder) + +* test: add test for IPC deadlock on Windows ( + +* win,pipe: fix IPC pipe deadlock (Bert Belder) + +* unix: catch some cases of watching fd twice (Ben Noordhuis) + +* test: use custom timeout for getaddrinfo_fail_sync (Ben Noordhuis) + +* Revert "win: add Windows XP support to uv_if_indextoname()" (Bert Belder) + +* win,thread: remove fallback uv_cond implementation (Bert Belder) + +* src,test: s/olny/only (cjihrig) + +* unix: close signal pipe fds on unload (Ben Noordhuis) + +* win: allow setting udp socket options before bind (cjihrig) + +* unix: return UV_ENOTSUP on FICLONE_FORCE failure (cjihrig) + +* win,pipe: remove unreferenced local variable (Bert Belder) + +* win,code: remove GetQueuedCompletionStatus-based poller (Bert Belder) + +* win: remove the remaining dynamic kernel32 imports (Bert Belder) + +* test: speedup process-title-threadsafe on macOS (cjihrig) + +* core: move all include files except uv.h to uv/ (Saúl Ibarra Corretgé) + +* win: move stdint-msvc2008.h to include/uv/ (Ben Noordhuis) + +* build: fix cygwin install (Ben Noordhuis) + +* build,win: remove MinGW Makefile (Saúl Ibarra Corretgé) + +* build: add a cmake build file (Ben Noordhuis) + +* build: add test suite option to cmake build (Ben Noordhuis) + +* unix: set errno in uv_fs_copyfile() (cjihrig) + +* samples: fix inconsistency in parse_opts vs usage (zyxwvu Shi) + +* linux: handle exclusive POLLHUP with UV_DISCONNECT (Brad King) + +* include: declare uv_cpu_times_s in higher scope (Peter Johnson) + +* doc: add uv_fs_fsync() AIX limitations (jBarz) + +* unix,win: add uv_fs_lchown() (Paolo Greppi) + +* unix: disable clang variable length array warning (Peter Johnson) + +* doc: document uv_pipe_t::ipc (Ed Schouten) + +* doc: undocument uv_req_type's UV_REQ_TYPE_PRIVATE (Ed Schouten) + +* doc: document UV_*_MAP() macros (Ed Schouten) + +* win: remove use of min() macro in pipe.c (Peter Johnson) + +* doc: add jbarz as maintainer ( + + +2018.05.08, Version 1.20.3 (Stable), 8cfd67e59195251dff793ee47c185c9d6a8f3818 + +Changes since version 1.20.2: + +* win: add Windows XP support to uv_if_indextoname() (ssrlive) + +* win: fix `'floor' undefined` compiler warning (ssrlive) + +* win, pipe: stop read for overlapped pipe (Bartosz Sosnowski) + +* build: fix utf-8 name of copyright holder (Jérémy Lal) + +* zos: initialize pollfd revents (jBarz) + +* zos,doc: add system V message queue note (jBarz) + +* linux: don't use uv__nonblock_ioctl() on sparc (Ben Noordhuis) + + +2018.04.23, Version 1.20.2 (Stable), c51fd3f66bbb386a1efdeba6812789f35a372d1e + +Changes since version 1.20.1: + +* zos: use custom semaphore (jBarz) + +* win: fix registry API error handling (Kyle Farnung) + +* build: add support for 64-bit AIX (Richard Lau) + +* aix: guard STATIC_ASSERT for glibc work around (Richard Lau) + + +2018.04.19, Version 1.20.1 (Stable), 36ac2fc8edfd5ff3e9be529be1d4a3f0d5364e94 + +Changes since version 1.20.0: + +* doc,fs: improve documentation (Bob Burger) + +* win: return a floored double from uv_uptime() (Refael Ackermann) + +* doc: clarify platform specific pipe naming (Thomas Versteeg) + +* unix: fix uv_pipe_chmod() on macOS (zzzjim) + +* unix: work around glibc semaphore race condition (Anna Henningsen) + +* tcp,openbsd: disable Unix TCP check for IPV6_ONLY (Alex Arslan) + +* test,openbsd: use RETURN_SKIP in UDP IPv6 tests (Alex Arslan) + +* test,openbsd: fix multicast test (Alex Arslan) + +* Revert "win, fs: use FILE_WRITE_ATTRIBUTES when opening files" (cjihrig) + + +2018.04.03, Version 1.20.0 (Stable), 0012178ee2b04d9e4a2c66c27cf8891ad8325ceb + +Changes since version 1.19.2: + +* unix,spawn: respect user stdio flags for new pipe (Jameson Nash) + +* Revert "Revert "unix,tcp: avoid marking server sockets connected"" (Jameson + Nash) + +* req: revisions to uv_req_t handling (Jameson Nash) + +* win: remove unnecessary initialization (cjihrig) + +* win: update uv_os_homedir() to use uv_os_getenv() (cjihrig) + +* test: fix tcp_oob test flakiness (Santiago Gimeno) + +* posix: fix uv__pollfds_del() for invalidated fd's (Jesse Gorzinski) + +* doc: README: add note on installing gyp (Jamie Davis) + +* unix: refactor uv_os_homedir to use uv_os_getenv (Santiago Gimeno) + +* unix: fix several instances of lost errno (Michael Kilburn) + +* win,tty: update several TODO comments (Ruslan Bekenev) + +* unix: add UV_FS_COPYFILE_FICLONE support (cjihrig) + +* test: fix connect_unspecified (Santiago Gimeno) + +* unix,win: add UV_FS_COPYFILE_FICLONE_FORCE support (cjihrig) + +* win: use long directory name for handle->dirw (Nicholas Vavilov) + +* build: build with -D_FILE_OFFSET_BITS=64 again (Ben Noordhuis) + +* win, fs: fix uv_fs_unlink for +R -A files (Bartosz Sosnowski) + +* win, fs: use FILE_WRITE_ATTRIBUTES when opening files (Bartosz Sosnowski) + +* unix: use __PASE__ on IBM i platforms (Jesse Gorzinski) + +* test,freebsd: fix flaky poll tests (Santiago Gimeno) + +* test: increase connection timeout to 1 second (jBarz) + +* win,tcp: handle canceled connect with ECANCELED (Jameson Nash) + + +2018.02.22, Version 1.19.2 (Stable), c5afc37e2a8a70d8ab0da8dac10b77ba78c0488c + +Changes since version 1.19.1: + +* test: fix incorrect asserts (cjihrig) + +* test: fix a typo in test-fork.c (Felix Yan) + +* build: remove long-obsolete gyp workarounds (Ben Noordhuis) + +* build: split off tests into separate gyp file (Ben Noordhuis) + +* test: check uv_cond_timedwait more carefully (Jamie Davis) + +* include,src: introduce UV__ERR() macro (Mason X) + +* build: add url field to libuv.pc (Ben Noordhuis) + +* doc: mark IBM i as Tier 3 support (Jesse Gorzinski) + +* win,build: correct C2059 errors (Michael Fero) + +* zos: fix timeout for condition variable (jBarz) + +* win: CREATE_NO_WINDOW when stdio is not inherited (Nick Logan) + +* build: fix commmon.gypi comment (Ryuichi KAWAMATA) + +* doc: document uv_timer_start() on an active timer (Vladimír ÄŒunát) + +* doc: add note about handle movability (Bartosz Sosnowski) + +* doc: fix syntax error in loop documentation (Bartosz Sosnowski) + +* osx,stream: retry sending handle on EMSGSIZE error (Santiago Gimeno) + +* unix: delay fs req register until after validation (cjihrig) + +* test: add tests for bad inputs (Joyee Cheung) + +* unix,win: ensure req->bufs is freed (cjihrig) + +* test: add additional fs memory management checks (cjihrig) + + +2018.01.20, Version 1.19.1 (Stable), 8202d1751196c2374ad370f7f3779daef89befae + +Changes since version 1.19.0: + +* Revert "unix,tcp: avoid marking server sockets connected" (Ben Noordhuis) + +* Revert "unix,fs: fix for potential partial reads/writes" (Ben Noordhuis) + +* Revert "win: use RemoveDirectoryW() instead of _wmrmdir()" (Ben Noordhuis) + +* cygwin: fix compilation of ifaddrs impl (Brad King) + + +2018.01.18, Version 1.19.0 (Stable), effbb7c9d29090b2e085a40867f8cdfa916a66df + +Changes since version 1.18.0: + +* core: add getter/setter functions for easier ABI compat (Anna Henningsen) + +* unix: make get(set)_process_title MT-safe (Matt Harrison) + +* unix,win: wait for threads to start (Ben Noordhuis) + +* test: add threadpool init/teardown test (Bartosz Sosnowski) + +* win, process: uv_kill improvements (Bartosz Sosnowski) + +* win: set _WIN32_WINNT to 0x0600 (cjihrig) + +* zos: implement uv_fs_event* functions (jBarz) + +* unix,tcp: avoid marking server sockets connected (Jameson Nash) + +* doc: mark Windows 7 as Tier 1 support (Bartosz Sosnowski) + +* win: map 0.0.0.0 and :: addresses to localhost (Bartosz Sosnowski) + +* build: install libuv.pc unconditionally (Ben Noordhuis) + +* test: remove custom timeout for thread test on ppc (Ben Noordhuis) + +* test: allow multicast not permitted status (Jérémy Lal) + +* test: allow net unreachable status in udp test (Ben Noordhuis) + +* unix: use SA_RESTART when setting our sighandler (Brad King) + +* unix,fs: fix for potential partial reads/writes (Ben Wijen) + +* win,build: do not build executable installer for dll (Bert Belder) + +* win: allow directory symlinks to be created in a non-elevated context (Bert + Belder) + +* zos,test: accept SIGKILL for flaky test (jBarz) + +* win: use RemoveDirectoryW() instead of _wmrmdir() (Ben Noordhuis) + +* unix: fix uv_cpu_info() error on FreeBSD (elephantp) + +* zos,test: decrease pings to avoid timeout (jBarz) + + +2017.12.02, Version 1.18.0 (Stable), 1489c98b7fc17f1702821a269eb0c5e730c5c813 + +Changes since version 1.17.0: + +* aix: fix -Wmaybe-uninitialized warning (cjihrig) + +* doc: remove note about SIGWINCH on Windows (Bartosz Sosnowski) + +* Revert "unix,win: wait for threads to start" (Ben Noordhuis) + +* unix,win: add uv_os_getpid() (Bartosz Sosnowski) + +* unix: remove incorrect assertion in uv_shutdown() (Jameson Nash) + +* doc: fix IRC URL in CONTRIBUTING.md (Matt Harrison) + + +2017.11.25, Version 1.17.0 (Stable), 1344d2bb82e195d0eafc0b40ba103f18dfd04cc5 + +Changes since version 1.16.1: + +* unix: avoid malloc() call in uv_spawn() (Ben Noordhuis) + +* doc: clarify the description of uv_loop_alive() (Ed Schouten) + +* win: map UV_FS_O_EXLOCK to a share mode of 0 (Joran Dirk Greef) + +* win: fix build on case-sensitive file systems (Ben Noordhuis) + +* win: fix test runner build with mingw64 (Ben Noordhuis) + +* win: remove unused variable in test/test-fs.c (Ben Noordhuis) + +* zos: add strnlen() implementation (jBarz) + +* unix: keep track of bound sockets sent via spawn (jBarz) + +* unix,win: wait for threads to start (Ben Noordhuis) + +* test: add threadpool init/teardown test (Bartosz Sosnowski) + +* test: avoid malloc() in threadpool test (Ben Noordhuis) + +* test: lower number of tasks in threadpool test (Ben Noordhuis) + +* win: issue memory barrier in uv_thread_join() (Ben Noordhuis) + +* ibmi: add support for new platform (Xu Meng) + +* test: fix test-spawn compilation (Bartosz Sosnowski) + + +2017.11.11, Version 1.16.1 (Stable), 4056fbe46493ef87237e307e0025e551db875e13 + +Changes since version 1.16.0: + +* unix: move net/if.h include (cjihrig) + +* win: fix undeclared NDIS_IF_MAX_STRING_SIZE (Nick Logan) + + +2017.11.07, Version 1.16.0 (Stable), d68779f0ea742918f653b9c20237460271c39aeb + +Changes since version 1.15.0: + +* win: change st_blksize from `2048` to `4096` (Joran Dirk Greef) + +* unix,win: add fs open flags, map O_DIRECT|O_DSYNC (Joran Dirk Greef) + +* win, fs: fix non-symlink reparse points (Wade Brainerd) + +* test: fix -Wstrict-prototypes warnings (Ben Noordhuis) + +* unix, windows: map ENOTTY errno (Ben Noordhuis) + +* unix: fall back to fsync() if F_FULLFSYNC fails (Joran Dirk Greef) + +* unix: do not close invalid kqueue fd after fork (jBarz) + +* zos: reset epoll data after fork (jBarz) + +* zos: skip fork_threadpool_queue_work_simple (jBarz) + +* test: keep platform_output as first test (Bartosz Sosnowski) + +* win: fix non-English dlopen error message (Bartosz Sosnowski) + +* unix,win: add uv_os_getppid() (cjihrig) + +* test: fix const qualification compiler warning (Ben Noordhuis) + +* doc: mark uv_default_loop() as not thread safe (rayrase) + +* win, pipe: null-initialize stream->shutdown_req (Jameson Nash) + +* tty, win: get SetWinEventHook pointer at startup (Bartosz Sosnowski) + +* test: no extra new line in skipped test output (Bartosz Sosnowski) + +* pipe: allow access from other users (Bartosz Sosnowski) + +* unix,win: add uv_if_{indextoname,indextoiid} (Pekka Nikander) + + +2017.10.03, Version 1.15.0 (Stable), 8b69ce1419d2958011d415a636810705c36c2cc2 + +Changes since version 1.14.1: + +* unix: limit uv__has_forked_with_cfrunloop to macOS (Kamil Rytarowski) + +* win: fix buffer size in uv__getpwuid_r() (tux.uudiin) + +* win,tty: improve SIGWINCH support (Bartosz Sosnowski) + +* unix: use fchmod() in uv_fs_copyfile() (cjihrig) + +* unix: support copying empty files (cjihrig) + +* unix: truncate destination in uv_fs_copyfile() (Nick Logan) + +* win,build: keep cwd when setting build environment (darobs) + +* test: add NetBSD support to test-udp-ipv6.c (Kamil Rytarowski) + +* unix: add NetBSD support in core.c (Kamil Rytarowski) + +* linux: increase thread stack size with musl libc (Ben Noordhuis) + +* netbsd: correct uv_exepath() on NetBSD (Kamil Rytarowski) + +* test: clean up semaphore after use (jBarz) + +* win,build: bump vswhere_usability_wrapper to 2.0.0 (Refael Ackermann) + +* win: let UV_PROCESS_WINDOWS_HIDE hide consoles (cjihrig) + +* zos: lock protect global epoll list in epoll_ctl (jBarz) + +* zos: change platform name to match python (jBarz) + +* android: fix getifaddrs() (Zheng, Lei) + +* netbsd: implement uv__tty_is_slave() (Kamil Rytarowski) + +* zos: fix readlink for mounts with system variables (jBarz) + +* test: sort the tests alphabetically (Sakthipriyan Vairamani) + +* windows: fix compilation warnings (Carlo Marcelo Arenas Belón) + +* build: avoid -fstrict-aliasing compile option (jBarz) + +* win: remove unused variables (Carlo Marcelo Arenas Belón) + +* unix: remove unused variables (Sakthipriyan Vairamani) + +* netbsd: disable poll_bad_fdtype on NetBSD (Kamil Rytarowski) + +* netbsd: use uv__cloexec and uv__nonblock (Kamil Rytarowski) + +* test: fix udp_multicast_join6 on NetBSD (Kamil Rytarowski) + +* unix,win: add uv_mutex_init_recursive() (Scott Parker) + +* netbsd: do not exclude IPv6 functionality (Kamil Rytarowski) + +* fsevents: watch files with fsevents on macos 10.7+ (Ben Noordhuis) + +* unix: retry on ENOBUFS in sendmsg(2) (Kamil Rytarowski) + + +2017.09.07, Version 1.14.1 (Stable), b0f9fb2a07a5e638b1580fe9a42a356c3ab35f37 + +Changes since version 1.14.0: + +* fs, win: add support for user symlinks (Bartosz Sosnowski) + +* cygwin: include uv-posix.h header (Joel Winarske) + +* zos: fix semaphore initialization (jBarz) + +* zos: improve loop_count benchmark performance (jBarz) + +* zos, test: flush out the oob data in callback (jBarz) + +* unix,win: check for bad flags in uv_fs_copyfile() (cjihrig) + +* unix: modify argv[0] when process title is set (Matthew Taylor) + +* unix: don't use req->loop in uv__fs_copyfile() (cjihrig) + +* doc: fix a trivial typo (Vladimír ÄŒunát) + +* android: fix uv_cond_timedwait on API level < 21 (Gergely Nagy) + +* win: add uv__once_init() calls (Bartosz Sosnowski) + +* unix,windows: init all requests in fs calls (cjihrig) + +* unix,windows: return UV_EINVAL on NULL fs reqs (cjihrig) + +* windows: add POST macro to fs functions (cjihrig) + +* unix: handle partial sends in uv_fs_copyfile() (A. Hauptmann) + +* Revert "win, test: fix double close in test runner" (Bartosz Sosnowski) + +* win, test: remove surplus CloseHandle (Bartosz Sosnowski) + + +2017.08.17, Version 1.14.0 (Stable), e0d31e9e21870f88277746b6d59cf07b977cdfea + +Changes since version 1.13.1: + +* unix: check for NULL in uv_os_unsetenv for parameter name (André Klitzing) + +* doc: add thread safety warning for process title (Matthew Taylor) + +* unix: always copy process title into local buffer (Matthew Taylor) + +* poll: add support for OOB TCP and GPIO interrupts (CurlyMoo) + +* win,build: fix appveyor properly (Refael Ackermann) + +* win: include filename in dlopen error message (Ben Noordhuis) + +* aix: add netmask, mac address into net interfaces (Gireesh Punathil) + +* unix, windows: map EREMOTEIO errno (Ben Noordhuis) + +* unix: fix wrong MAC of uv_interface_address (XadillaX) + +* win,build: fix building from Windows SDK or VS console (Saúl Ibarra Corretgé) + +* github: fix link to help repo in issue template (Ben Noordhuis) + +* zos: remove nonexistent include from autotools build (Saúl Ibarra Corretgé) + +* misc: remove reference to pthread-fixes.h from LICENSE (Saúl Ibarra Corretgé) + +* docs: fix guide source code example paths (Anticrisis) + +* android: fix compilation with new NDK versions (Saúl Ibarra Corretgé) + +* misc: add android-toolchain to .gitignore (Saúl Ibarra Corretgé) + +* win, fs: support unusual reparse points (Bartosz Sosnowski) + +* android: fix detection of pthread_condattr_setclock (Saúl Ibarra Corretgé) + +* android: remove no longer needed check (Saúl Ibarra Corretgé) + +* doc: update instructions for building on Android (Saúl Ibarra Corretgé) + +* win, process: support semicolons in PATH variable (Bartosz Sosnowski) + +* doc: document uv_async_(init|send) return values (Ben Noordhuis) + +* doc: add Android as a tier 3 supported platform (Saúl Ibarra Corretgé) + +* unix: add missing semicolon (jBarz) + +* win, test: fix double close in test runner (Bartosz Sosnowski) + +* doc: update supported windows version baseline (Ben Noordhuis) + +* test,zos: skip chown root test (jBarz) + +* test,zos: use gid=-1 to test spawn_setgid_fails (jBarz) + +* zos: fix hr timer resolution (jBarz) + +* android: fix blocking recvmsg due to netlink bug (Jacob Segal) + +* zos: read more accurate rss info from RSM (jBarz) + +* win: allow bound/connected socket in uv_tcp_open() (Maciej Szeptuch + (Neverous)) + +* doc: differentiate SmartOS and SunOS support (cjihrig) + +* unix: make uv_poll_stop() remove fd from pollset (Ben Noordhuis) + +* unix, windows: add basic uv_fs_copyfile() (cjihrig) + + +2017.07.07, Version 1.13.1 (Stable), 2bb4b68758f07cd8617838e68c44c125bc567ba6 + +Changes since version 1.13.0: + +* Now working on version 1.13.1 (cjihrig) + +* build: workaround AppVeyor quirk (Refael Ackermann) + + +2017.07.06, Version 1.13.0 (Stable), 8342fcaab815f33b988c1910ea988f28dfe27edb + +Changes since version 1.12.0: + +* Now working on version 1.12.1 (cjihrig) + +* unix: avoid segfault in uv_get_process_title (Michele Caini) + +* build: add a comma to uv.gyp (Gemini Wen) + +* win: restore file pos after positional read/write (Bartosz Sosnowski) + +* unix,stream: return error on closed handle passing (Santiago Gimeno) + +* unix,benchmark: use fd instead of FILE* after fork (jBarz) + +* zos: avoid compiler warnings (jBarz) + +* win,pipe: race condition canceling readfile thread (Jameson Nash) + +* sunos: filter out non-IPv4/IPv6 interfaces (Sebastian Wiedenroth) + +* sunos: fix cmpxchgi and cmpxchgl type error (Sai Ke WANG) + +* unix: reset signal disposition before execve() (Ben Noordhuis) + +* unix: reset signal mask before execve() (Ben Noordhuis) + +* unix: fix POLLIN assertion on server read (jBarz) + +* zos: use stckf builtin for high-res timer (jBarz) + +* win,udp: implements uv_udp_try_send (Barnabas Gema) + +* win,udp: return UV_EINVAL instead of aborting (Romain Caire) + +* freebsd: replace kvm with sysctl (Robert Ayrapetyan) + +* aix: fix un-initialized pointer field in fs handle (Gireesh Punathil) + +* win,build: support building with VS2017 (Refael Ackermann) + +* doc: add instructions for building on Windows (Refael Ackermann) + +* doc: format README (Refael Ackermann) + + +2017.05.31, Version 1.12.0 (Stable), d6ac141ac674657049598c36604f26e031fae917 + +Changes since version 1.11.0: + +* Now working on version 1.11.1 (cjihrig) + +* test: fix tests on OpenBSD (Santiago Gimeno) + +* test: fix -Wformat warning (Santiago Gimeno) + +* win,fs: avoid double freeing uv_fs_event_t.dirw (Vladimir Matveev) + +* unix: remove unused code in `uv__io_start` (Fedor Indutny) + +* signal: add uv_signal_start_oneshot method (Santiago Gimeno) + +* unix: factor out reusable POSIX hrtime impl (Brad King) + +* unix,win: add uv_os_{get,set,unset}env() (cjihrig) + +* win: add uv__convert_utf8_to_utf16() (cjihrig) + +* docs: improve UV_ENOBUFS scenario documentation (cjihrig) + +* unix: return UV_EINVAL for NULL env name (jBarz) + +* unix: filter getifaddrs results consistently (Brad King) + +* unix: factor out getifaddrs result filter (Brad King) + +* unix: factor out reusable BSD ifaddrs impl (Brad King) + +* unix: use union to follow strict aliasing rules (jBarz) + +* unix: simplify async watcher dispatch logic (Ben Noordhuis) + +* samples: update timer callback prototype (Ben Noordhuis) + +* unix: make loops and watchers usable after fork() (Jason Madden) + +* win: free uv__loops once empty (cjihrig) + +* tools: add make_dist_html.py script (Ben Noordhuis) + +* win,sunos: stop handle on uv_fs_event_start() err (cjihrig) + +* unix,windows: refactor request init logic (Ben Noordhuis) + +* win: fix memory leak inside uv__pipe_getname (A. Hauptmann) + +* fsevent: support for files without short name (Bartosz Sosnowski) + +* doc: fix multiple doc typos (Jamie Davis) + +* test,osx: fix flaky kill test (Santiago Gimeno) + +* unix: inline uv_pipe_bind() err_bind goto target (cjihrig) + +* unix,test: deadstore fixes (Rasmus Christian Pedersen) + +* win: fix memory leak inside uv_fs_access() (A. Hauptmann) + +* doc: fix docs/src/fs.rst build warning (Daniel Bevenius) + +* doc: minor grammar fix in Installation section (Daniel Bevenius) + +* doc: suggestions for design page (Daniel Bevenius) + +* doc: libuv does not touch uv_loop_t.data (Ben Noordhuis) + +* github: add ISSUE_TEMPLATE.md (Ben Noordhuis) + +* doc: add link to libuv/help to README (Ben Noordhuis) + +* udp: fix fast path in uv_udp_send() on unix (Fedor Indutny) + +* test: add test for uv_udp_send() fix (Trevor Norris) + +* doc: fix documentation for uv_handle_t.type (Daniel Kahn Gillmor) + +* zos: use proper prototype for epoll_init() (Ben Noordhuis) + +* doc: rename docs to "libuv documentation" (Saúl Ibarra Corretgé) + +* doc: update copyright years (Saúl Ibarra Corretgé) + +* doc: move TOC to a dedicated document (Saúl Ibarra Corretgé) + +* doc: move documentation section up (Saúl Ibarra Corretgé) + +* doc: move "upgrading" to a standalone document (Saúl Ibarra Corretgé) + +* doc: add initial version of the User Guide (Saúl Ibarra Corretgé) + +* doc: removed unused file (Saúl Ibarra Corretgé) + +* doc: update guide/about and mention new maintainership (Saúl Ibarra Corretgé) + +* doc: remove licensing note from guide/about (Saúl Ibarra Corretgé) + +* doc: add warning note to user guide (Saúl Ibarra Corretgé) + +* doc: change license to CC BY 4.0 (Saúl Ibarra Corretgé) + +* doc: remove ubvook reference from README (Saúl Ibarra Corretgé) + +* doc: add code samples from uvbook (unadapted) (Saúl Ibarra Corretgé) + +* doc: update supported linux/glibc baseline (Ben Noordhuis) + +* win: avoid leaking pipe handles to child processes (Jameson Nash) + +* win,test: support stdout output larger than 1kb (Bartosz Sosnowski) + +* win: remove __declspec(inline) from atomic op (Keane) + +* test: fix VC++ compilation warning (Rasmus Christian Pedersen) + +* build: add -Wstrict-prototypes (Jameson Nash) + +* zos: implement uv__io_fork, skip fs event tests (jBarz) + +* unix: do not close udp sockets on bind error (Marc Schlaich) + +* unix: remove FSEventStreamFlushSync() call (cjihrig) + +* build,openbsd: remove kvm-related code (James McCoy) + +* test: fix flaky tcp-write-queue-order (Santiago Gimeno) + +* unix,win: add uv_os_gethostname() (cjihrig) + +* zos: increase timeout for tcp_writealot (jBarz) + +* zos: do not inline OOB data by default (jBarz) + +* test: fix -Wstrict-prototypes compiler warnings (Ben Noordhuis) + +* unix: factor out reusable no-proctitle impl (Brad King) + +* test: factor out fsevents skip explanation (Brad King) + +* test: skip fork fsevent cases when lacking support (Brad King) + +* unix: factor out reusable no-fsevents impl (Brad King) + +* unix: factor out reusable sysinfo memory lookup (Brad King) + +* unix: factor out reusable sysinfo loadavg impl (Brad King) + +* unix: factor out reusable procfs exepath impl (Brad King) + +* unix: add a uv__io_poll impl using POSIX poll(2) (Brad King) + +* cygwin: implement support for cygwin and msys2 (Brad King) + +* cygwin: recognize EOF on named pipe closure (Brad King) + +* cygwin: fix uv_pipe_connect report of ENOTSOCK (Brad King) + +* cygwin: disable non-functional ipc handle send (Brad King) + +* test: skip self-connecting tests on cygwin (Brad King) + +* doc: mark uv_loop_fork() as experimental (cjihrig) + +* doc: add bzoz to maintainers (Bartosz Sosnowski) + +* doc: fix memory leak in tcp-echo-server example (Bernardo Ramos) + +* win: make uv__get_osfhandle() public (Juan Cruz Viotti) + +* doc: use valid pipe name in pipe-echo-server (Bernardo Ramos) + + +2017.02.02, Version 1.11.0 (Stable), 7452ef4e06a4f99ee26b694c65476401534f2725 + +Changes since version 1.10.2: + +* Now working on version 1.10.3 (cjihrig) + +* win: added fcntl.h to uv-win.h (Michele Caini) + +* unix: move function call out of assert (jBarz) + +* fs: cleanup uv__fs_scandir (Santiago Gimeno) + +* fs: fix crash in uv_fs_scandir_next (muflub) + +* win,signal: fix potential deadlock (Bartosz Sosnowski) + +* unix: use async-signal safe functions between fork and exec (jBarz) + +* sunos: fix SUNOS_NO_IFADDRS build (Ben Noordhuis) + +* zos: make platform functional (John Barboza) + +* doc: add repitition qualifier to version regexs (Daniel Bevenius) + +* zos: use gyp OS label "os390" on z/OS (John Barboza) + +* aix: enable uv_get/set_process_title (Howard Hellyer) + +* zos: use built-in proctitle implementation (John Barboza) + +* Revert "darwin: use clock_gettime in macOS 10.12" (Chris Araman) + +* win,test: don't write uninitialized buffer to tty (Bert Belder) + +* win: define ERROR_ELEVATION_REQUIRED for MinGW (Richard Lau) + +* aix: re-enable fs watch facility (Gireesh Punathil) + + +2017.01.10, Version 1.10.2 (Stable), cb9f579a454b8db592030ffa274ae58df78dbe20 + +Changes since version 1.10.1: + +* Now working on version 1.10.2 (cjihrig) + +* darwin: fix fsync and fdatasync (Joran Dirk Greef) + +* Revert "Revert "win,tty: add support for ANSI codes in win10 v1511"" + (Santiago Gimeno) + +* win,tty: fix MultiByteToWideChar output buffer (Santiago Gimeno) + +* win: remove dead code related to BACKUP_SEMANTICS (Sam Roberts) + +* win: fix comment in quote_cmd_arg (Eric Sciple) + +* darwin: use clock_gettime in macOS 10.12 (Saúl Ibarra Corretgé) + +* win, tty: fix crash on restarting with pending data (Nicholas Vavilov) + +* fs: fix uv__to_stat on BSD platforms (Santiago Gimeno) + +* win: map ERROR_ELEVATION_REQUIRED to UV_EACCES (Richard Lau) + +* win: fix free() on bad input in uv_getaddrinfo() (Ben Noordhuis) + + +2016.11.17, Version 1.10.1 (Stable), 2e49e332bdede6db7cf17fa784a902e8386d5d86 + +Changes since version 1.10.0: + +* Now working on version 1.10.1 (cjihrig) + +* win: fix anonymous union syntax (Brad King) + +* unix: use uv__is_closing everywhere (Santiago Gimeno) + +* win: add missing break statement (cjihrig) + +* doc: fix wrong man page link for uv_fs_lstat() (Michele Caini) + +* win, tty: handle empty buffer in uv_tty_write_bufs (Hitesh Kanwathirtha) + +* doc: add cjihrig alternative GPG ID (cjihrig) + +* Revert "win,tty: add support for ANSI codes in win10 v1511" (Ben Noordhuis) + + +2016.10.25, Version 1.10.0 (Stable), c8a373c729b4c9392e0e14fc53cd6b67b3051ab9 + +Changes since version 1.9.1: + +* Now working on version 1.9.2 (Saúl Ibarra Corretgé) + +* doc: add cjihrig GPG ID (cjihrig) + +* win,build: fix compilation on old Windows / MSVC (Saúl Ibarra Corretgé) + +* darwin: fix setting fd to non-blocking in select(() trick (Saúl Ibarra + Corretgé) + +* unix: allow nesting of kqueue fds in uv_poll_start (Ben Noordhuis) + +* doc: fix generation the first time livehtml runs (Saúl Ibarra Corretgé) + +* test: fix test_close_accept flakiness on Centos5 (Santiago Gimeno) + +* license: libuv is no longer a Node project (Saúl Ibarra Corretgé) + +* license: add license text we've been using for a while (Saúl Ibarra Corretgé) + +* doc: add licensing information to README (Saúl Ibarra Corretgé) + +* win,pipe: fixed formatting, DWORD is long unsigned (Miodrag Milanovic) + +* win: support sub-second precision in uv_fs_futimes() (Jason Ginchereau) + +* unix: ignore EINPROGRESS in uv__close (Saúl Ibarra Corretgé) + +* doc: add Imran Iqbal (iWuzHere) to maintainers (Imran Iqbal) + +* doc: update docs with AIX related information (Imran Iqbal) + +* test: silence build warnings (Kári Tristan Helgason) + +* doc: add iWuzHere GPG ID (Imran Iqbal) + +* linux-core: fix uv_get_total/free_memory on uclibc (Nicolas Cavallari) + +* build: fix build on DragonFly (Michael Neumann) + +* unix: correctly detect named pipes on DragonFly (Michael Neumann) + +* test: make tap output the default (Ben Noordhuis) + +* test: don't dump output for skipped tests (Ben Noordhuis) + +* test: improve formatting of diagnostic messages (Ben Noordhuis) + +* test: remove unused RETURN_TODO macro (Ben Noordhuis) + +* doc: fix stream typos (Pierre-Marie de Rodat) + +* doc: update coding style link (Imran Iqbal) + +* unix,fs: use uint64_t instead of unsigned long (Imran Iqbal) + +* build: check for warnings for -fvisibility=hidden (Imran Iqbal) + +* unix: remove unneeded TODO note (Saúl Ibarra Corretgé) + +* test: skip tty_pty test if pty is not available (Luca Bruno) + +* sunos: set phys_addr of interface_address using ARP (Brian Maher) + +* doc: clarify callbacks won't be called in error case (Saúl Ibarra Corretgé) + +* unix: don't convert stat buffer when syscall fails (Ben Noordhuis) + +* win: compare entire filename in watch events (cjihrig) + +* doc: add a note on safe reuse of uv_write_t (neevek) + +* linux: fix potential event loop stall (Ben Noordhuis) + +* unix,win: make uv_get_process_title() stricter (cjihrig) + +* test: close server before initiating new connection (John Barboza) + +* test: account for multiple handles in one ipc read (John Barboza) + +* unix: fix errno and retval conflict (liuxiaobo) + +* doc: add missing entry in uv_fs_type enum (Michele Caini) + +* unix: preserve loop->data across loop init/done (Ben Noordhuis) + +* win: return UV_EINVAL on bad uv_tty_mode mode arg (Ben Noordhuis) + +* win: simplify memory copy logic in fs.c (Ben Noordhuis) + +* win: fix compilation on mingw (Bartosz Sosnowski) + +* win: ensure 32-bit printf precision (Matej Knopp) + +* darwin: handle EINTR in /dev/tty workaround (Ben Noordhuis) + +* test: fix OOB buffer access (Saúl Ibarra Corretgé) + +* test: don't close CRT fd handed off to uv_pipe_t (Saúl Ibarra Corretgé) + +* test: fix android build error. (sunjin.lee) + +* win: evaluate timers when system wakes up (Bartosz Sosnowski) + +* doc: add supported platforms description (Saúl Ibarra Corretgé) + +* win: fix lstat reparse point without link data (Jason Ginchereau) + +* unix,win: make on_alloc_cb failures more resilient (Saúl Ibarra Corretgé) + +* zos: add support for new platform (John Barboza) + +* test: make tcp_close_while_connecting more resilient (Saúl Ibarra Corretgé) + +* build: use '${prefix}' for pkg-config 'exec_prefix' (Matt Clarkson) + +* build: GNU/kFreeBSD support (Jeffrey Clark) + +* zos: use PLO instruction for atomic operations (John Barboza) + +* zos: use pthread helper functions (John Barboza) + +* zos: implement uv__fs_futime (John Barboza) + +* unix: expand range of values for usleep (John Barboza) + +* zos: track unbound handles and bind before listen (John Barboza) + +* test: improve tap output on test failures (Santiago Gimeno) + +* test: refactor fs_event_close_in_callback (Julien Gilli) + +* zos: implement uv__io_check_fd (John Barboza) + +* unix: unneccessary use const qualifier in container_of (John Barboza) + +* win,tty: add support for ANSI codes in win10 v1511 (Imran Iqbal) + +* doc: add santigimeno to maintainers (Santiago Gimeno) + +* win: fix typo in type name (Saúl Ibarra Corretgé) + +* unix: always define pthread barrier fallback pad (Saúl Ibarra Corretgé) + +* test: use RETURN_SKIP in spawn_setuid_setgid test (Santiago Gimeno) + +* win: add disk read/write count to uv_getrusage (Imran Iqbal) + +* doc: document uv_fs_realpath caveats (Saúl Ibarra Corretgé) + +* test: improve spawn_setuid_setgid test (Santiago Gimeno) + +* test: fix building pty test on Android (Saúl Ibarra Corretgé) + +* doc: uv_buf_t members are not readonly (Saúl Ibarra Corretgé) + +* doc: improve documentation on uv_alloc_cb (Saúl Ibarra Corretgé) + +* fs: fix uv_fs_fstat on platforms using musl libc (Santiago Gimeno) + +* doc: update supported fields for uv_rusage_t (Imran Iqbal) + +* test: fix test-tcp-writealot flakiness on arm (Santiago Gimeno) + +* test: fix fs_event_watch_dir flakiness on arm (Santiago Gimeno) + +* unix: don't use alphasort in uv_fs_scandir() (Ben Noordhuis) + +* doc: fix confusing doc of uv_tcp_nodelay (Bart Robinson) + +* build,osx: fix warnings on tests compilation with gyp (Santiago Gimeno) + +* doc: add ABI tracker link to README (Saúl Ibarra Corretgé) + +* win,tty: fix uv_tty_set_mode race conditions (Bartosz Sosnowski) + +* test: fix fs_fstat on Android (Vit Gottwald) + +* win, test: fix fs_event_watch_dir_recursive (Bartosz Sosnowski) + +* doc: add description of uv_handle_type (Vit Gottwald) + +* build: use -pthreads for tests with autotools (Julien Gilli) + +* win: fix leaky fs request buffer (Jason Ginchereau) + +* doc: note buffer lifetime requirements in uv_write (Vladimír ÄŒunát) + +* doc: add reference to uv_update_time on uv_timer_start (Alex Hultman) + +* win: fix winapi function pointer typedef syntax (Brad King) + +* test: fix tcp_close_while_connecting CI failures (Ben Noordhuis) + +* test: make threadpool_cancel_single deterministic (Ben Noordhuis) + +* test: make threadpool saturation reliable (Ben Noordhuis) + +* unix: don't malloc in uv_thread_create() (Ben Noordhuis) + +* unix: don't include CoreServices globally on macOS (Brad King) + +* unix,win: add uv_translate_sys_error() public API (Philippe Laferriere) + +* win: remove unused static variables (Ben Noordhuis) + +* win: silence -Wmaybe-uninitialized warning (Ben Noordhuis) + +* signal: replace pthread_once with uv_once (Santiago Gimeno) + +* test: fix sign-compare warning (Will Speak) + +* common: fix unused variable warning (Brad King) + + +2016.05.17, Version 1.9.1 (Stable), d989902ac658b4323a4f4020446e6f4dc449e25c + +Changes since version 1.9.0: + +* test: handle root home directories (cjihrig) + +* unix: implement uv__fs_futime for AIX 7.1 (Imran Iqbal) + +* test: skip early bind tests if no IPv6 is supported (Saúl Ibarra Corretgé) + +* win: fix var declaration to be C89 compliant (Michael Fero) + +* unix: use POLL{IN,OUT,etc} constants directly (Ben Noordhuis) + +* doc: add ability to live reload and regenerate HTML (Saúl Ibarra Corretgé) + +* Revert "win,build: remove unused build defines" (cjihrig) + +* linux: fix fd leaks in uv_cpu_info() error paths (Ben Noordhuis) + +* linux: don't abort on malformed /proc/stat (Ben Noordhuis) + +* linux: fix long lines in linux-core.c (Ben Noordhuis) + +* test: fix fs_event_watch_file_current_dir for AIX (Imran Iqbal) + +* unix,fs: code cleanup of uv_fs_event_start for AIX (Imran Iqbal) + +* unix: delay signal handling until after normal i/o (Ben Noordhuis) + +* android: pthread_sigmask() does not set errno (Oguz Bastemur) + +* win: work around sharepoint scandir bug (Ben Noordhuis) + +* unix: guard against clobbering errno in uv__free() (Ben Noordhuis) + +* unix: remove unneeded SAVE_ERRNO wrappers (Ben Noordhuis) + +* test: skip fs_event_close_in_callback on AIX (Imran Iqbal) + +* win: add maxrss, pagefaults to uv_getrusage() (Robert Jefe Lindstaedt) + +* test: set a big send buffer size for tcp_write_queue_order (Andrius Bentkus) + +* unix: error on realpath if PATH_MAX is undefined (Myles Borins) + +* unix: fix bug in barrier fallback implementation (Kári Tristan Helgason) + +* build: bump android ndk version (Kári Tristan Helgason) + +* build: always compile with -fvisibility=hidden (Ben Noordhuis) + +* test: fix -Wformat warnings in platform test (Ben Noordhuis) + +* win: clarify fsevents handling code (Saúl Ibarra Corretgé) + +* test: fix POLLHDRUP related failures for AIX (Imran Iqbal) + +* build, mingw: set LIBS in configure.ac (Tony Theodore) + +* win: improve uv__convert_utf16_to_utf8 (Saúl Ibarra Corretgé) + +* win: simplified UTF16 -> UTF8 conversions (Saúl Ibarra Corretgé) + +* win: remove unneeded condition (Saúl Ibarra Corretgé) + +* darwin: work around condition variable kernel bug (Ben Noordhuis) + +* darwin: make thread stack multiple of page size (Ben Noordhuis) + +* build,win: rename platform to msbuild_platform (João Reis) + +* gitignore: ignore VS temporary database files (João Reis) + +* test: skip emfile on AIX (Imran Iqbal) + +* unix: use system allocator for scandir() (cjihrig) + +* common: release uv_fs_scandir() array (cjihrig) + +* win: call uv__fs_scandir_cleanup() (cjihrig) + +* win,tty: fix read stop in line mode (João Reis) + +* win,tty: don't duplicate handle for line reads (João Reis) + +* win,tty: restore cursor after canceling line read (Alexis Campailla) + + +2016.04.08, Version 1.9.0 (Stable), 229b3a4cc150aebd6561e6bd43076eafa7a03756 + +Changes since version 1.8.0: + +* win: wait for full timeout duration (João Reis) + +* unix: fix support for uClibc-ng (Martin Bark) + +* doc: indicate where new test files need to be added (Dave) + +* test,unix: fix logic error in test runner (Ben Noordhuis) + +* fs: don't nullify req->bufs on EINTR (Dave) + +* osx: set the default thread stack size to RLIMIT_STACK (Saúl Ibarra Corretgé) + +* build: invoke libtoolize with --copy (Ben Noordhuis) + +* test: fixup eintr_handling (Saúl Ibarra Corretgé) + +* osx: avoid compilation warning with Clang (Saúl Ibarra Corretgé) + +* test,win: fix compilation with shared lib (Alexis Murzeau) + +* test: fix race condition in pipe-close-stdout (Imran Iqbal) + +* unix,win: add uv_os_tmpdir() (cjihrig) + +* ios: fix undefined PTHREAD_STACK_MIN (Didiet) + +* test: fix threadpool_multiple_event_loops for AIX (Imran Iqbal) + +* unix: report errors for unpollable fds (Ben Noordhuis) + +* win: fix watching root files (Nicholas Vavilov) + +* build,win: print the Visual Studio version in use (Saúl Ibarra Corretgé) + +* build,win: remove unneeded condition from GYP file (Saúl Ibarra Corretgé) + +* test,win: fix compilation warning (Saúl Ibarra Corretgé) + +* test: use uv_loop_close and assert its result (Nan Xiang) + +* build: map 'AMD64' host arch to 'x64' (Ben Noordhuis) + +* osx: protected use of potentially undefined macro (Samuel Lorétan) + +* linux: fix compilation with musl (Saúl Ibarra Corretgé) + +* doc: describe how to make release builds on Unix (Saúl Ibarra Corretgé) + +* doc: add missing link in README (Saúl Ibarra Corretgé) + +* build: python 2.x/3.x consistent print usage (Rasmus Christian Pedersen) + +* test: assume no IPv6 if interfaces cannot be listed (Nan Xiang) + +* darwin: replace F_FULLFSYNC with fdatasync syscall (Saúl Ibarra Corretgé) + +* doc: add missing write callback to example (Nándor István Krácser) + +* build: compile with -D_THREAD_SAFE on AIX (Imran Iqbal) + +* test: fix threadpool_multiple_event_loops on PPC (Imran Iqbal) + +* test: reduce timeout in tcp_close_while_connecting (Imran Iqbal) + +* unix, win: consistently null-terminate buffers (Saúl Ibarra Corretgé) + +* unix, win: count null byte on UV_ENOBUFS (Saúl Ibarra Corretgé) + +* test: fix deadlocks in uv_cond_wait (Katsutoshi Horie) + +* linux: fix cpu count (Lukasz Jagiello) + +* unix: fix uv__handle_type for AIX (Imran Iqbal) + +* linux: call fclose(), fix fdopen() memory leak (Ben Noordhuis) + +* win: remove unneeded condition (Saúl Ibarra Corretgé) + +* unix: fix compile error in Android using bionic (Robert Chiras) + +* linux: add braces to multi-statement if (Kári Tristan Helgason) + +* doc: add @cjihrig as a maintainer (Saúl Ibarra Corretgé) + +* unix: add fork-safe open file function (Kári Tristan Helgason) + +* linux: replace calls to fopen with uv__open_file (Kári Tristan Helgason) + +* linux: remove redundant call to rewind() (Krishnaraj Bhat) + +* win: remove duplicated code when processing fsevents (Saúl Ibarra Corretgé) + +* test: fix poll_bad_fdtype for AIX (Imran Iqbal) + +* linux: fix error checking in uv__open_file (Saúl Ibarra Corretgé) + +* poll: add UV_DISCONNECT event (Santiago Gimeno) + +* fs: realpath: fix string size before converting (Yuval Brik) + +* win: use native APIs for UTF conversions (cjihrig) + +* doc: clarify uv_loop_close() (Ben Noordhuis) + +* unix: retry ioctl(TIOCGWINSZ) on EINTR (Ben Noordhuis) + +* win,build: remove unused build defines (Saúl Ibarra Corretgé) + +* win: fix buffer overflow in fs events (Joran Dirk Greef) + +* win: fix uv_relative_path and remove dead branch (Joran Dirk Greef) + +* unix: use open(2) with O_CLOEXEC on OS X (Kári Tristan Helgason) + +* test: add missing copyright header (cjihrig) + +* aix: fix 'POLLRDHUP undeclared' build error (Ben Noordhuis) + +* unix,win: add uv_get_passwd() (cjihrig) + +* process: fix uv_spawn edge-case (Santiago Gimeno) + +* test: use %ld for printing uid/gid (Ben Noordhuis) + +* aix: fix ahafs implementation (Imran Iqbal) + +* aix: do not store absolute path to ahafs (Imran Iqbal) + +* process: close process pipes safely (Santiago Gimeno) + +* unix: open ttyname instead of /dev/tty (Enno Boland) + +* unix: remove outdated comment (Kári Tristan Helgason) + + +2015.12.15, Version 1.8.0 (Stable), 5467299450ecf61635657557b6e01aaaf6c3fdf4 + +Changes since version 1.7.5: + +* unix: fix memory leak in uv_interface_addresses (Jianghua Yang) + +* unix: make uv_guess_handle work properly for AIX (Gireesh Punathil) + +* fs: undo uv__req_init when uv__malloc failed (Jianghua Yang) + +* build: remove unused 'component' GYP option (Saúl Ibarra Corretgé) + +* include: remove duplicate extern declaration (Jianghua Yang) + +* win: use the MSVC provided snprintf where possible (Jason Williams) + +* win, test: fix compilation warning (Saúl Ibarra Corretgé) + +* win: fix compilation with VS < 2012 (Ryan Johnston) + +* stream: support empty uv_try_write on unix (Fedor Indutny) + +* unix: fix request handle leak in uv__udp_send (Jianghua Yang) + +* src: replace QUEUE_SPLIT with QUEUE_MOVE (Ben Noordhuis) + +* unix: use QUEUE_MOVE when iterating over lists (Ben Noordhuis) + +* unix: squelch harmless valgrind warning (Ben Noordhuis) + +* test: don't abort on setrlimit() failure (Ben Noordhuis) + +* unix: only undo fs req registration in async mode (Ben Noordhuis) + +* unix: fix uv__getiovmax return value (HungMingWu) + +* unix: make work with Solaris Studio. (Adam Stylinski) + +* test: fix fs_event_watch_file_currentdir flakiness (Santiago Gimeno) + +* unix: skip prohibited syscalls on tvOS and watchOS (Nathan Corvino) + +* test: use FQDN in getaddrinfo_fail test (Wink Saville) + +* docs: clarify documentation of uv_tcp_init_ex (Andrius Bentkus) + +* win: fix comment (Miodrag Milanovic) + +* doc: fix typo in README (Angel Leon) + +* darwin: abort() if (un)locking fs mutex fails (Ben Noordhuis) + +* pipe: enable inprocess uv_write2 on Windows (Louis DeJardin) + +* win: properly return UV_EBADF when _close() fails (Nicholas Vavilov) + +* test: skip process_title for AIX (Imran Iqbal) + +* misc: expose handle print APIs (Petka Antonov) + +* include: add stdio.h to uv.h (Saúl Ibarra Corretgé) + +* misc: remove unnecessary null pointer checks (Ian Kronquist) + +* test,freebsd: skip udp_dual_stack if not supported (Santiago Gimeno) + +* linux: don't retry dup2/dup3 on EINTR (Ben Noordhuis) + +* unix: don't retry dup2/dup3 on EINTR (Ben Noordhuis) + +* test: fix -Wtautological-pointer-compare warnings (Saúl Ibarra Corretgé) + +* win: map ERROR_BAD_PATHNAME to UV_ENOENT (Tony Kelman) + +* test: fix test/test-tty.c for AIX (Imran Iqbal) + +* android: support api level less than 21 (kkdaemon) + +* fsevents: fix race on simultaneous init+close (Fedor Indutny) + +* linux,fs: fix p{read,write}v with a 64bit offset (Saúl Ibarra Corretgé) + +* fs: add uv_fs_realpath() (Yuval Brik) + +* win: fix path for removed and renamed fs events (Joran Dirk Greef) + +* win: do not read more from stream than available (Jeremy Whitlock) + +* test: test that uv_close() doesn't corrupt QUEUE (Andrey Mazo) + +* unix: fix uv_fs_event_stop() from fs_event_cb (Andrey Mazo) + +* test: fix self-deadlocks in thread_rwlock_trylock (Ben Noordhuis) + +* src: remove non ascii character (sztomi) + +* test: fix test udp_multicast_join6 for AIX (Imran Iqbal) + + +2015.09.23, Version 1.7.5 (Stable), a8c1136de2cabf25b143021488cbaab05834daa8 + +Changes since version 1.7.4: + +* unix: Support atomic compare & swap xlC on AIX (nmushell) + +* unix: Fix including uv-aix.h on AIX (nmushell) + +* unix: consolidate rwlock tryrdlock trywrlock errors (Saúl Ibarra Corretgé) + +* unix, win: consolidate mutex trylock errors (Saúl Ibarra Corretgé) + +* darwin: fix memory leak in uv_cpu_info (Jianghua Yang) + +* test: add tests for the uv_rwlock implementation (Bert Belder) + +* win: redo/fix the uv_rwlock APIs (Bert Belder) + +* win: don't fetch function pointers to SRWLock APIs (Bert Belder) + + +2015.09.12, Version 1.7.4 (Stable), a7ad4f52189d89cfcba35f78bfc5ff3b1f4105c4 + +Changes since version 1.7.3: + +* doc: uv_read_start and uv_read_cb clarifications (Ben Trask) + +* freebsd: obtain true uptime through clock_gettime() (Jianghua Yang) + +* win, tty: do not convert \r to \r\n (Colin Snover) + +* build,gyp: add DragonFly to the list of OSes (Michael Neumann) + +* fs: fix bug in sendfile for DragonFly (Michael Neumann) + +* doc: add uv_dlsym() return type (Brian White) + +* tests: fix fs tests run w/o full getdents support (Jeremy Whitlock) + +* doc: fix typo (Devchandra Meetei Leishangthem) + +* doc: fix uv-unix.h location (Sakthipriyan Vairamani) + +* unix: fix error check when closing process pipe fd (Ben Noordhuis) + +* test,freebsd: fix ipc_listen_xx_write tests (Santiago Gimeno) + +* win: fix unsavory rwlock fallback implementation (Bert Belder) + +* doc: clarify repeat timer behavior (Eli Skeggs) + + +2015.08.28, Version 1.7.3 (Stable), 93877b11c8b86e0a6befcda83a54555c1e36e4f0 + +Changes since version 1.7.2: + +* threadpool: fix thread starvation bug (Ben Noordhuis) + + +2015.08.25, Version 1.7.2 (Stable), 4d13a013fcfa72311f0102751fdc7951873f466c + +Changes since version 1.7.1: + +* unix, win: make uv_loop_init return on error (Willem Thiart) + +* win: reset pipe handle for pipe servers (Saúl Ibarra Corretgé) + +* win: fix replacing pipe handle for pipe servers (Saúl Ibarra Corretgé) + +* win: fix setting pipe pending instances after bind (Saúl Ibarra Corretgé) + + +2015.08.20, Version 1.7.1 (Stable), 44f4b6bd82d8ae4583ccc4768a83af778ef69f85 + +Changes since version 1.7.0: + +* doc: document the procedure for verifying releases (Saúl Ibarra Corretgé) + +* doc: add note about Windows binaries to the README (Saúl Ibarra Corretgé) + +* doc: use long GPG IDs in MAINTAINERS.md (Saúl Ibarra Corretgé) + +* Revert "stream: squelch ECONNRESET error if already closed" (Saúl Ibarra + Corretgé) + +* doc: clarify uv_read_stop() is idempotent (Corbin Simpson) + +* unix: OpenBSD's setsockopt needs an unsigned char for multicast (Zachary + Hamm) + +* test: Fix two memory leaks (Karl Skomski) + +* unix,win: return EINVAL on nullptr args in uv_fs_{read,write} (Karl Skomski) + +* win: set accepted TCP sockets as non-inheritable (Saúl Ibarra Corretgé) + +* unix: remove superfluous parentheses in fs macros (Ben Noordhuis) + +* unix: don't copy arguments for sync fs requests (Ben Noordhuis) + +* test: plug small memory leak in unix test runner (Ben Noordhuis) + +* unix,windows: allow NULL loop for sync fs requests (Ben Noordhuis) + +* unix,windows: don't assert on unknown error code (Ben Noordhuis) + +* stream: retry write on EPROTOTYPE on OSX (Brian White) + +* common: fix use of snprintf on Windows (Saúl Ibarra Corretgé) + +* tests: refactored fs watch_dir tests for stability (Jeremy Whitlock) + + +2015.08.06, Version 1.7.0 (Stable), 415a865d6365ba58d02b92b89d46ba5d7744ec8b + +Changes since version 1.6.1: + +* win,stream: add slot to remember CRT fd (Bert Belder) + +* win,pipe: properly close when created from CRT fd (Bert Belder) + +* win,pipe: don't close fd 0-2 (Bert Belder) + +* win,tty: convert fd -> handle safely (Bert Belder) + +* win,tty: properly close when created from CRT fd (Bert Belder) + +* win,tty: don't close fd 0-2 (Bert Belder) + +* win,fs: don't close fd 0-2 (Bert Belder) + +* win: include "malloc.h" (Cheng Zhao) + +* windows: MSVC 2015 has C99 inline (Jason Williams) + +* dragonflybsd: fixes for nonblocking and cloexec (Michael Neumann) + +* dragonflybsd: use sendfile(2) for uv_fs_sendfile (Michael Neumann) + +* dragonflybsd: fix uv_exepath (Michael Neumann) + +* win,fs: Fixes align(8) directive on mingw (Stefano Cristiano) + +* unix, win: prevent replacing fd in uv_{udp,tcp,pipe}_t (Saúl Ibarra Corretgé) + +* win: move logic to set socket non-inheritable to uv_tcp_set_socket (Saúl + Ibarra Corretgé) + +* unix, win: add ability to create tcp/udp sockets early (Saúl Ibarra Corretgé) + +* test: retry select() on EINTR, honor milliseconds (Ben Noordhuis) + +* unix: consolidate tcp and udp bind error (Saúl Ibarra Corretgé) + +* test: conditionally skip udp_ipv6_multicast_join6 (heshamsafi) + +* core: add UV_VERSION_HEX macro (Saúl Ibarra Corretgé) + +* doc: add section with version-checking macros and functions (Saúl Ibarra + Corretgé) + +* tty: cleanup handle if uv_tty_init fails (Saúl Ibarra Corretgé) + +* darwin: save a fd when FSEvents is used (Saúl Ibarra Corretgé) + +* win: fix returning thread id in uv_thread_self (Saúl Ibarra Corretgé) + +* common: use offsetof for QUEUE_DATA (Saúl Ibarra Corretgé) + +* win: remove UV_HANDLE_CONNECTED (A. Hauptmann) + +* docs: add Windows specific note for uv_fs_open (Saúl Ibarra Corretgé) + +* doc: add note about uv_fs_scandir (Saúl Ibarra Corretgé) + +* test,unix: reduce stack size of watchdog threads (Ben Noordhuis) + +* win: add support for recursive file watching (Saúl Ibarra Corretgé) + +* win,tty: support consoles with non-default colors (John McNamee) + +* doc: add missing variable name (Yosuke Furukawa) + +* stream: squelch ECONNRESET error if already closed (Santiago Gimeno) + +* build: remove ancient condition from common.gypi (Saúl Ibarra Corretgé) + +* tests: skip some tests when network is unreachable (Luca Bruno) + +* build: proper support for android cross compilation (guworks) + +* android: add missing include to pthread-fixes.c (RossBencina) + +* test: fix compilation warning (Saúl Ibarra Corretgé) + +* doc: add a note about uv_dirent_t.type (Saúl Ibarra Corretgé) + +* win,test: fix shared library build (Saúl Ibarra Corretgé) + +* test: fix compilation warning (Santiago Gimeno) + +* build: add experimental Windows installer (Roger A. Light) + +* threadpool: send signal only when queue is empty (chenttuuvv) + +* aix: fix uv_exepath with relative paths (Richard Lau) + +* build: fix version syntax in AppVeyor file (Saúl Ibarra Corretgé) + +* unix: allow nbufs > IOV_MAX in uv_fs_{read,write} (ronkorving) + + +2015.06.06, Version 1.6.1 (Stable), 30c8be07bb78a66fdee5141626bf53a49a17094a + +Changes since version 1.6.0: + +* unix: handle invalid _SC_GETPW_R_SIZE_MAX values (cjihrig) + + +2015.06.04, Version 1.6.0 (Stable), adfccad76456061dfcf79b8df8e7dbfee51791d7 + +Changes since version 1.5.0: + +* aix: fix setsockopt for multicast options (Michael) + +* unix: don't block for io if any io handle is primed (Saúl Ibarra Corretgé) + +* windows: MSVC 2015 has snprintf() (Rui Abreu Ferreira) + +* windows: Add VS2015 support to vcbuild.bat (Jason Williams) + +* doc: fix typo in tcp.rst (Igor Soarez) + +* linux: work around epoll bug in kernels < 2.6.37 (Ben Noordhuis) + +* unix,win: add uv_os_homedir() (cjihrig) + +* stream: fix `select()` race condition (Fedor Indutny) + +* unix: prevent infinite loop in uv__run_pending (Saúl Ibarra Corretgé) + +* unix: make sure UDP send callbacks are asynchronous (Saúl Ibarra Corretgé) + +* test: fix `platform_output` netmask printing. (Andrew Paprocki) + +* aix: add ahafs autoconf detection and README notes (Andrew Paprocki) + +* core: add ability to customize memory allocator (Saúl Ibarra Corretgé) + + +2015.05.07, Version 1.5.0 (Stable), 4e77f74c7b95b639b3397095db1bc5bcc016c203 + +Changes since version 1.4.2: + +* doc: clarify that the thread pool primites are not thread safe (Andrius + Bentkus) + +* aix: always deregister closing fds from epoll (Michael) + +* unix: fix glibc-2.20+ macro incompatibility (Massimiliano Torromeo) + +* doc: add Sphinx plugin for generating links to man pages (Saúl Ibarra + Corretgé) + +* doc: link system and library calls to man pages (Saúl Ibarra Corretgé) + +* doc: document uv_getnameinfo_t.{host|service} (Saúl Ibarra Corretgé) + +* build: update the location of gyp (Stephen von Takach) + +* win: name all anonymous structs and unions (TomCrypto) + +* linux: work around epoll bug in kernels 3.10-3.19 (Ben Noordhuis) + +* darwin: fix size calculation in select() fallback (Ole André Vadla RavnÃ¥s) + +* solaris: fix setsockopt for multicast options (Julien Gilli) + +* test: fix race condition in multithreaded test (Ben Noordhuis) + +* doc: fix long lines in tty.rst (Ben Noordhuis) + +* test: use UV_TTY_MODE_* values in tty test (Ben Noordhuis) + +* unix: don't clobber errno in uv_tty_reset_mode() (Ben Noordhuis) + +* unix: reject non-tty fds in uv_tty_init() (Ben Noordhuis) + +* win: fix pipe blocking writes (Alexis Campailla) + +* build: fix cross-compiling for iOS (Steven Kabbes) + +* win: remove unnecessary malloc.h + +* include: use `extern "c++"` for defining C++ code (Kazuho Oku) + +* unix: reap child on execvp() failure (Ryan Phillips) + +* windows: fix handle leak on EMFILE (Brian Green) + +* test: fix tty_file, close handle if initialized (Saúl Ibarra Corretgé) + +* doc: clarify what uv_*_open accepts (Saúl Ibarra Corretgé) + +* doc: clarify that we don't maintain external doc resources (Saúl Ibarra + Corretgé) + +* build: add documentation for ninja support (Devchandra Meetei Leishangthem) + +* doc: document uv_buf_t members (Corey Farrell) + +* linux: fix epoll_pwait() fallback on arm64 (Ben Noordhuis) + +* android: fix compilation warning (Saúl Ibarra Corretgé) + +* unix: don't close the fds we just setup (Sam Roberts) + +* test: spawn child replacing std{out,err} to stderr (Saúl Ibarra Corretgé) + +* unix: fix swapping fds order in uv_spawn (Saúl Ibarra Corretgé) + +* unix: fix potential bug if dup2 fails in uv_spawn (Saúl Ibarra Corretgé) + +* test: remove LOG and LOGF variadic macros (Saúl Ibarra Corretgé) + +* win: fix uv_fs_access on directories (Saúl Ibarra Corretgé) + +* win: fix of double free in uv_uptime (Per Nilsson) + +* unix: open "/dev/null" instead of "/" for emfile_fd (Alan Rogers) + +* docs: add some missing words (Daryl Haresign) + +* unix: clean up uv_fs_open() O_CLOEXEC logic (Ben Noordhuis) + +* build: set SONAME for shared library in uv.gyp (Rui Abreu Ferreira) + +* windows: define snprintf replacement as inline instead of static (Rui Abreu + Ferreira) + +* win: fix unlink of readonly files (João Reis) + +* doc: fix uv_run(UV_RUN_DEFAULT) description (Ben Noordhuis) + +* linux: intercept syscall when running under memory sanitizer (Keno Fischer) + +* aix: fix uv_interface_addresses return value (farblue68) + +* windows: defer reporting TCP write failure until next tick (Saúl Ibarra + Corretgé) + +* test: add test for deferred TCP write failure (Saúl Ibarra Corretgé) + + +2015.02.27, Version 1.4.2 (Stable), 1a7391348a11d5450c0f69c828d5302e2cb842eb + +Changes since version 1.4.1: + +* stream: ignore EINVAL for SO_OOBINLINE on OS X (Fedor Indutny) + + +2015.02.25, Version 1.4.1 (Stable), e8e3fc5789cc0f02937879d141cca0411274093c + +Changes since version 1.4.0: + +* win: don't use inline keyword in thread.c (Ben Noordhuis) + +* windows: fix setting dirent types on uv_fs_scandir_next (Saúl Ibarra + Corretgé) + +* unix,windows: make uv_thread_create() return errno (Ben Noordhuis) + +* tty: fix build for SmartOS (Julien Gilli) + +* unix: fix for uv_async data race (Michael Penick) + +* unix, windows: map EHOSTDOWN errno (Ben Noordhuis) + +* stream: use SO_OOBINLINE on OS X (Fedor Indutny) + + +2015.02.10, Version 1.4.0 (Stable), 19fb8a90648f3763240db004b77ab984264409be + +Changes since version 1.3.0: + +* unix: check Android support for pthread_cond_timedwait_monotonic_np (Leith + Bade) + +* test: use modified path in test (cjihrig) + +* unix: implement uv_stream_set_blocking() (Ben Noordhuis) + + +2015.01.29, Version 1.3.0 (Stable), 165685b2a9a42cf96501d79cd6d48a18aaa16e3b + +Changes since version 1.2.1: + +* unix, windows: set non-block mode in uv_poll_init (Saúl Ibarra Corretgé) + +* doc: clarify which flags are supported in uv_fs_event_start (Saúl Ibarra + Corretgé) + +* win,unix: move loop functions which have identical implementations (Andrius + Bentkus) + +* doc: explain how the threadpool is allocated (Alex Mo) + +* doc: clarify uv_default_loop (Saúl Ibarra Corretgé) + +* unix: fix implicit declaration compiler warning (Ben Noordhuis) + +* unix: fix long line introduced in commit 94e628fa (Ben Noordhuis) + +* unix, win: add synchronous uv_get{addr,name}info (Saúl Ibarra Corretgé) + +* linux: fix epoll_pwait() regression with < 2.6.19 (Ben Noordhuis) + +* build: compile -D_GNU_SOURCE on linux (Ben Noordhuis) + +* build: use -fvisibility=hidden in autotools build (Ben Noordhuis) + +* fs, pipe: no trailing terminator in exact sized buffers (Andrius Bentkus) + +* style: rename buf to buffer and len to size for consistency (Andrius Bentkus) + +* test: fix test-spawn on MinGW32 (Luis Martinez de Bartolome) + +* win, pipe: fix assertion when destroying timer (Andrius Bentkus) + +* win, unix: add pipe_peername implementation (Andrius Bentkus) + + +2015.01.29, Version 0.10.33 (Stable), 7a2253d33ad8215a26c1b34f1952aee7242dd687 + +Changes since version 0.10.32: + +* linux: fix epoll_pwait() regression with < 2.6.19 (Ben Noordhuis) + +* test: back-port uv_loop_configure() test (Ben Noordhuis) + + +2015.01.15, Version 1.2.1 (Stable), 4ca78e989062a1099dc4b9ad182a98e8374134b1 + +Changes since version 1.2.0: + +* unix: remove unused dtrace file (Saúl Ibarra Corretgé) + +* test: skip TTY select test if /dev/tty can't be opened (Saúl Ibarra Corretgé) + +* doc: clarify the behavior of uv_tty_init (Saúl Ibarra Corretgé) + +* doc: clarify how uv_async_send behaves (Saúl Ibarra Corretgé) + +* build: make dist now generates a full tarball (Johan Bergström) + +* freebsd: make uv_exepath more resilient (Saúl Ibarra Corretgé) + +* unix: make setting the tty mode to the same value a no-op (Saúl Ibarra + Corretgé) + +* win,tcp: support uv_try_write (Bert Belder) + +* test: enable test-tcp-try-write on windows (Bert Belder) + +* win,tty: support uv_try_write (Bert Belder) + +* unix: set non-block mode in uv_{pipe,tcp,udp}_open (Ben Noordhuis) + + +2015.01.06, Version 1.2.0 (Stable), 09f25b13cd149c7981108fc1a75611daf1277f83 + +Changes since version 1.1.0: + +* linux: fix epoll_pwait() sigmask size calculation (Ben Noordhuis) + +* tty: implement binary I/O terminal mode (Yuri D'Elia) + +* test: fix spawn test with autotools build (Ben Noordhuis) + +* test: skip ipv6 tests when ipv6 is not supported (Ben Noordhuis) + +* common: move STATIC_ASSERT to uv-common.h (Alexey Melnichuk) + +* win/thread: store thread handle in a TLS slot (Alexey Melnichuk) + +* unix: fix ttl, multicast ttl and loop options on IPv6 (Saúl Ibarra Corretgé) + +* linux: fix support for preadv/pwritev-less kernels (Ben Noordhuis) + +* unix: make uv_exepath(size=0) return UV_EINVAL (Ben Noordhuis) + +* darwin: fix uv_exepath(smallbuf) UV_EPERM error (Ben Noordhuis) + +* openbsd: fix uv_exepath(smallbuf) UV_EINVAL error (Ben Noordhuis) + +* linux: fix uv_exepath(size=1) UV_EINVAL error (Ben Noordhuis) + +* sunos: preemptively fix uv_exepath(size=1) (Ben Noordhuis) + +* win: fix and clarify comments in winapi.h (Bert Belder) + +* win: make available NtQueryDirectoryFile (Bert Belder) + +* win: add definitions for directory information types (Bert Belder) + +* win: use NtQueryDirectoryFile to implement uv_fs_scandir (Bert Belder) + +* unix: don't unlink unix socket on bind error (Ben Noordhuis) + +* build: fix bad comment in autogen.sh (Ben Noordhuis) + +* build: add AC_PROG_LIBTOOL to configure.ac (Ben Noordhuis) + +* test: skip udp_options6 if there no IPv6 support (Saúl Ibarra Corretgé) + +* win: add definitions for MUI errors mingw lacks (Bert Belder) + +* build: enable warnings in autotools build (Ben Noordhuis) + +* build: remove -Wno-dollar-in-identifier-extension (Ben Noordhuis) + +* build: move flags from Makefile.am to configure.ac (Ben Noordhuis) + + +2015.01.06, Version 0.10.32 (Stable), 378de30c59aef5fdb6d130fa5cfcb0a68fce571c + +Changes since version 0.10.31: + +* linux: fix epoll_pwait() sigmask size calculation (Ben Noordhuis) + + +2014.12.25, Version 1.1.0 (Stable), 9572f3e74a167f59a8017e57ca3ebe91ffd88e18 + +Changes since version 1.0.2: + +* test: test that closing a poll handle doesn't corrupt the stack (Bert Belder) + +* win: fix compilation of tests (Marc Schlaich) + +* Revert "win: keep a reference to AFD_POLL_INFO in cancel poll" (Bert Belder) + +* win: avoid stack corruption when closing a poll handle (Bert Belder) + +* test: fix test-fs-file-loop on Windows (Bert Belder) + +* test: fix test-cwd-and-chdir (Bert Belder) + +* doc: indicate what version uv_loop_configure was added on (Saúl Ibarra + Corretgé) + +* doc: fix sphinx warning (Saúl Ibarra Corretgé) + +* test: skip spawn_setuid_setgid if we get EACCES (Saúl Ibarra Corretgé) + +* test: silence some Clang warnings (Saúl Ibarra Corretgé) + +* test: relax osx_select_many_fds (Saúl Ibarra Corretgé) + +* test: fix compilation warnings when building with Clang (Saúl Ibarra + Corretgé) + +* win: fix autotools build of tests (Luis Lavena) + +* gitignore: ignore Visual Studio files (Marc Schlaich) + +* win: set fallback message if FormatMessage fails (Marc Schlaich) + +* win: fall back to default language in uv_dlerror (Marc Schlaich) + +* test: improve compatibility for dlerror test (Marc Schlaich) + +* test: check dlerror is "no error" in no error case (Marc Schlaich) + +* unix: change uv_cwd not to return a trailing slash (Saúl Ibarra Corretgé) + +* test: fix cwd_and_chdir test on Unix (Saúl Ibarra Corretgé) + +* test: add uv_cwd output to platform_output test (Saúl Ibarra Corretgé) + +* build: fix dragonflybsd autotools build (John Marino) + +* win: scandir use 'ls' for formatting long strings (Kenneth Perry) + +* build: remove clang and gcc_version gyp defines (Ben Noordhuis) + +* unix, windows: don't treat uv_run_mode as a bitmask (Saúl Ibarra Corretgé) + +* unix, windows: fix UV_RUN_ONCE mode if progress was made (Saúl Ibarra + Corretgé) + + +2014.12.25, Version 0.10.31 (Stable), 4dbd27e2219069a6daa769fb37f98673b77b4261 + +Changes since version 0.10.30: + +* test: test that closing a poll handle doesn't corrupt the stack (Bert Belder) + +* win: fix compilation of tests (Marc Schlaich) + +* Revert "win: keep a reference to AFD_POLL_INFO in cancel poll" (Bert Belder) + +* win: avoid stack corruption when closing a poll handle (Bert Belder) + +* gitignore: ignore Visual Studio files (Marc Schlaich) + +* win: set fallback message if FormatMessage fails (Marc Schlaich) + +* win: fall back to default language in uv_dlerror (Marc Schlaich) + +* test: improve compatibility for dlerror test (Marc Schlaich) + +* test: check dlerror is "no error" in no error case (Marc Schlaich) + +* build: link against -pthread (Logan Rosen) + +* win: scandir use 'ls' for formatting long strings (Kenneth Perry) + + +2014.12.10, Version 1.0.2 (Stable), eec671f0059953505f9a3c9aeb7f9f31466dd7cd + +Changes since version 1.0.1: + +* linux: fix sigmask size arg in epoll_pwait() call (Ben Noordhuis) + +* linux: handle O_NONBLOCK != SOCK_NONBLOCK case (Helge Deller) + +* doc: fix spelling (Joey Geralnik) + +* unix, windows: fix typos in comments (Joey Geralnik) + +* test: canonicalize test runner path (Ben Noordhuis) + +* test: fix compilation warnings (Saúl Ibarra Corretgé) + +* test: skip tty test if detected width and height are 0 (Saúl Ibarra Corretgé) + +* doc: update README with IRC channel (Saúl Ibarra Corretgé) + +* Revert "unix: use cfmakeraw() for setting raw TTY mode" (Ben Noordhuis) + +* doc: document how to get result of uv_fs_mkdtemp (Tim Caswell) + +* unix: add flag for blocking SIGPROF during poll (Ben Noordhuis) + +* unix, windows: add uv_loop_configure() function (Ben Noordhuis) + +* win: keep a reference to AFD_POLL_INFO in cancel poll (Marc Schlaich) + +* test: raise fd limit for OSX select test (Saúl Ibarra Corretgé) + +* unix: remove overzealous assert in uv_read_stop (Saúl Ibarra Corretgé) + +* unix: reset the reading flag when a stream gets EOF (Saúl Ibarra Corretgé) + +* unix: stop reading if an error is produced (Saúl Ibarra Corretgé) + +* cleanup: remove all dead assignments (Maciej MaÅ‚ecki) + +* linux: return early if we have no interfaces (Maciej MaÅ‚ecki) + +* cleanup: remove a dead increment (Maciej MaÅ‚ecki) + + +2014.12.10, Version 0.10.30 (Stable), 5a63f5e9546dca482eeebc3054139b21f509f21f + +Changes since version 0.10.29: + +* linux: fix sigmask size arg in epoll_pwait() call (Ben Noordhuis) + +* linux: handle O_NONBLOCK != SOCK_NONBLOCK case (Helge Deller) + +* doc: update project links (Ben Noordhuis) + +* windows: fix compilation of tests (Marc Schlaich) + +* unix: add flag for blocking SIGPROF during poll (Ben Noordhuis) + +* unix, windows: add uv_loop_configure() function (Ben Noordhuis) + +* win: keep a reference to AFD_POLL_INFO in cancel poll (Marc Schlaich) + + +2014.11.27, Version 1.0.1 (Stable), 0a8e81374e861d425b56c45c8599595d848911d2 + +Changes since version 1.0.0: + +* readme: remove Rust from users (Elijah Andrews) + +* doc,build,include: update project links (Ben Noordhuis) + +* doc: fix typo: Strcutures -> Structures (Michael Ira Krufky) + +* unix: fix processing process handles queue (Saúl Ibarra Corretgé) + +* win: replace non-ansi characters in source file (Bert Belder) + + +2014.11.21, Version 1.0.0 (Stable), feb2a9e6947d892f449b2770c4090f7d8c88381b + +Changes since version 1.0.0-rc2: + +* doc: fix git/svn url for gyp repo in README (Emmanuel Odeke) + +* windows: fix fs_read with nbufs > 1 and offset (Unknown W. Brackets) + +* win: add missing IP_ADAPTER_UNICAST_ADDRESS_LH definition for MinGW + (huxingyi) + +* doc: mention homebrew in README (Mikhail Mukovnikov) + +* doc: add learnuv workshop to README (Thorsten Lorenz) + +* doc: fix parameter name in uv_fs_access (Saúl Ibarra Corretgé) + +* unix: use cfmakeraw() for setting raw TTY mode (Yuri D'Elia) + +* win: fix uv_thread_self() (Alexis Campailla) + +* build: add x32 support to gyp build (Ben Noordhuis) + +* build: remove dtrace probes (Ben Noordhuis) + +* doc: fix link in misc.rst (Manos Nikolaidis) + +* mailmap: remove duplicated entries (Saúl Ibarra Corretgé) + +* gyp: fix comment regarding version info location (Saúl Ibarra Corretgé) + + +2014.10.21, Version 1.0.0-rc2 (Pre-release) + +Changes since version 1.0.0-rc1: + +* build: add missing fixtures to distribution tarball (Rob Adams) + +* doc: update references to current stable branch (Zachary Newman) + +* fs: fix readdir on empty directory (Fedor Indutny) + +* fs: rename uv_fs_readdir to uv_fs_scandir (Saúl Ibarra Corretgé) + +* doc: document uv_alloc_cb (Saúl Ibarra Corretgé) + +* doc: add migration guide from version 0.10 (Saúl Ibarra Corretgé) + +* build: add DragonFly BSD support in autotools (Robin Hahling) + +* doc: document missing stream related structures (Saúl Ibarra Corretgé) + +* doc: clarify uv_loop_t.data field lifetime (Saúl Ibarra Corretgé) + +* doc: add documentation for missing functions and structures (Saúl Ibarra + Corretgé) + +* doc: fix punctuation and grammar in README (Jeff Widman) + +* windows: return libuv error codes in uv_poll_init() (cjihrig) + +* unix, windows: add uv_fs_access() (cjihrig) + +* windows: fix netmask detection (Alexis Campailla) + +* unix, windows: don't include null byte in uv_cwd size (Saúl Ibarra Corretgé) + +* unix, windows: add uv_thread_equal (Tomasz KoÅ‚odziejski) + +* windows: fix fs_write with nbufs > 1 and offset (Unknown W. Brackets) + + +2014.10.21, Version 0.10.29 (Stable), 2d728542d3790183417f8f122a110693cd85db14 + +Changes since version 0.10.28: + +* darwin: allocate enough space for select() hack (Fedor Indutny) + +* linux: try epoll_pwait if epoll_wait is missing (Michael Hudson-Doyle) + +* windows: map ERROR_INVALID_DRIVE to UV_ENOENT (Saúl Ibarra Corretgé) + + +2014.09.18, Version 1.0.0-rc1 (Unstable), 0c28bbf7b42882853d1799ab96ff68b07f7f8d49 + +Changes since version 0.11.29: + +* windows: improve timer precision (Alexis Campailla) + +* build, gyp: set xcode flags (Recep ASLANTAS) + +* ignore: include m4 files which are created manually (Recep ASLANTAS) + +* build: add m4 for feature/flag-testing (Recep ASLANTAS) + +* ignore: ignore Xcode project and workspace files (Recep ASLANTAS) + +* unix: fix warnings about dollar symbol usage in identifiers (Recep ASLANTAS) + +* unix: fix warnings when loading functions with dlsym (Recep ASLANTAS) + +* linux: try epoll_pwait if epoll_wait is missing (Michael Hudson-Doyle) + +* test: add test for closing and recreating default loop (Saúl Ibarra Corretgé) + +* windows: properly close the default loop (Saúl Ibarra Corretgé) + +* version: add ability to specify a version suffix (Saúl Ibarra Corretgé) + +* doc: add API documentation (Saúl Ibarra Corretgé) + +* test: don't close connection on write error (Trevor Norris) + +* windows: further simplify the code for timers (Saúl Ibarra Corretgé) + +* gyp: remove UNLIMITED_SELECT from dependent define (Fedor Indutny) + +* darwin: allocate enough space for select() hack (Fedor Indutny) + +* unix, windows: don't allow a NULL callback on timers (Saúl Ibarra Corretgé) + +* windows: simplify code in uv_timer_again (Saúl Ibarra Corretgé) + +* test: use less requests on tcp-write-queue-order (Saúl Ibarra Corretgé) + +* unix: stop child process watcher after last one exits (Saúl Ibarra Corretgé) + +* unix: simplify how process handle queue is managed (Saúl Ibarra Corretgé) + +* windows: remove duplicated field (mattn) + +* core: add a reserved field to uv_handle_t and uv_req_t (Saúl Ibarra Corretgé) + +* windows: fix buffer leak after failed udp send (Bert Belder) + +* windows: make sure sockets and handles are reset on close (Saúl Ibarra Corretgé) + +* unix, windows: add uv_fileno (Saúl Ibarra Corretgé) + +* build: use same CFLAGS in autotools build as in gyp (Saúl Ibarra Corretgé) + +* build: remove unneeded define in uv.gyp (Saúl Ibarra Corretgé) + +* test: fix watcher_cross_stop on Windows (Saúl Ibarra Corretgé) + +* unix, windows: move includes for EAI constants (Saúl Ibarra Corretgé) + +* unix: fix exposing EAI_* glibc-isms (Saúl Ibarra Corretgé) + +* unix: fix tcp write after bad connect freezing (Andrius Bentkus) + + +2014.08.20, Version 0.11.29 (Unstable), 35451fed830807095bbae8ef981af004a4b9259e + +Changes since version 0.11.28: + +* windows: make uv_read_stop immediately stop reading (Jameson Nash) + +* windows: fix uv__getaddrinfo_translate_error (Alexis Campailla) + +* netbsd: fix build (Saúl Ibarra Corretgé) + +* unix, windows: add uv_recv_buffer_size and uv_send_buffer_size (Andrius + Bentkus) + +* windows: add support for UNC paths on uv_spawn (Paul Goldsmith) + +* windows: replace use of inet_addr with uv_inet_pton (Saúl Ibarra Corretgé) + +* unix: replace some asserts with returning errors (Andrius Bentkus) + +* windows: use OpenBSD implementation for uv_fs_mkdtemp (Pavel Platto) + +* windows: fix GetNameInfoW error handling (Alexis Campailla) + +* fs: introduce uv_readdir_next() and report types (Fedor Indutny) + +* fs: extend reported types in uv_fs_readdir_next (Saúl Ibarra Corretgé) + +* unix: read on stream even when UV__POLLHUP set. (Julien Gilli) + + +2014.08.08, Version 0.11.28 (Unstable), fc9e2a0bc487b299c0cd3b2c9a23aeb554b5d8d1 + +Changes since version 0.11.27: + +* unix, windows: const-ify handle in uv_udp_getsockname (Rasmus Pedersen) + +* windows: use UV_ECANCELED for aborted TCP writes (Saúl Ibarra Corretgé) + +* windows: add more required environment variables (Jameson Nash) + +* windows: sort environment variables before calling CreateProcess (Jameson + Nash) + +* unix, windows: move uv_loop_close out of assert (John Firebaugh) + +* windows: fix buffer overflow on uv__getnameinfo_work() (lilohuang) + +* windows: add uv_backend_timeout (Jameson Nash) + +* test: disable tcp_close_accept on Windows (Saúl Ibarra Corretgé) + +* windows: read the PATH env var of the child (Alex Crichton) + +* include: avoid using C++ 'template' reserved word (Iñaki Baz Castillo) + +* include: fix version number (Saúl Ibarra Corretgé) + + +2014.07.32, Version 0.11.27 (Unstable), ffe24f955032d060968ea0289af365006afed55e + +Changes since version 0.11.26: + +* unix, windows: use the same threadpool implementation (Saúl Ibarra Corretgé) + +* unix: use struct sockaddr_storage for target UDP addr (Saúl Ibarra Corretgé) + +* doc: add documentation to uv_udp_start_recv (Andrius Bentkus) + +* common: use common uv__count_bufs code (Andrius Bentkus) + +* unix, win: add send_queue_size and send_queue_count to uv_udp_t (Andrius + Bentkus) + +* unix, win: add uv_udp_try_send (Andrius Bentkus) + +* unix: return UV_EAGAIN if uv_try_write cannot write any data (Saúl Ibarra + Corretgé) + +* windows: fix compatibility with cygwin pipes (Jameson Nash) + +* windows: count queued bytes even if request completed immediately (Saúl + Ibarra Corretgé) + +* windows: disable CRT debug handler on MinGW32 (Saúl Ibarra Corretgé) + +* windows: map ERROR_INVALID_DRIVE to UV_ENOENT (Saúl Ibarra Corretgé) + +* unix: try to write immediately in uv_udp_send (Saúl Ibarra Corretgé) + +* unix: remove incorrect assert (Saúl Ibarra Corretgé) + +* openbsd: avoid requiring privileges for uv_resident_set_memory (Aaron Bieber) + +* unix: guarantee write queue cb execution order in streams (Andrius Bentkus) + +* img: add logo files (Saúl Ibarra Corretgé) + +* aix: improve AIX compatibility (Andrew Low) + +* windows: return bind error immediately when implicitly binding (Saúl Ibarra + Corretgé) + +* windows: don't use atexit for cleaning up the threadpool (Saúl Ibarra + Corretgé) + +* windows: destroy work queue elements when colsing a loop (Saúl Ibarra + Corretgé) + +* unix, windows: add uv_fs_mkdtemp (Pavel Platto) + +* build: handle platforms without multiprocessing.synchronize (Saúl Ibarra + Corretgé) + +* windows: change GENERIC_ALL to GENERIC_WRITE in fs__create_junction (Tony + Kelman) + +* windows: relay TCP bind errors via ipc (Alexis Campailla) + + +2014.07.32, Version 0.10.28 (Stable), 9c14b616f5fb84bfd7d45707bab4bbb85894443e + +Changes since version 0.10.27: + +* windows: fix handling closed socket while poll handle is closing (Saúl Ibarra + Corretgé) + +* unix: return system error on EAI_SYSTEM (Saúl Ibarra Corretgé) + +* unix: fix bogus structure field name (Saúl Ibarra Corretgé) + +* darwin: invoke `mach_timebase_info` only once (Fedor Indutny) + + +2014.06.28, Version 0.11.26 (Unstable), 115281a1058c4034d5c5ccedacb667fe3f6327ea + +Changes since version 0.11.25: + +* windows: add VT100 codes ?25l and ?25h (JD Ballard) + +* windows: add invert ANSI (7 / 27) emulation (JD Ballard) + +* unix: fix handling error on UDP socket creation (Saúl Ibarra Corretgé) + +* unix, windows: getnameinfo implementation (Rasmus Pedersen) + +* heap: fix `heap_remove()` (Fedor Indutny) + +* unix, windows: fix parsing scoped IPv6 addresses (Saúl Ibarra Corretgé) + +* windows: fix handling closed socket while poll handle is closing (Saúl Ibarra + Corretgé) + +* thread: barrier functions (Ben Noordhuis) + +* windows: fix PYTHON environment variable usage (Jay Satiro) + +* unix, windows: return system error on EAI_SYSTEM (Saúl Ibarra Corretgé) + +* windows: fix handling closed socket while poll handle is closing (Saúl Ibarra + Corretgé) + +* unix: don't run i/o callbacks after prepare callbacks (Saúl Ibarra Corretgé) + +* windows: add tty unicode support for input (Peter Atashian) + +* header: introduce `uv_loop_size()` (Andrius Bentkus) + +* darwin: invoke `mach_timebase_info` only once (Fedor Indutny) + + +2014.05.02, Version 0.11.25 (Unstable), 2acd544cff7142e06aa3b09ec64b4a33dd9ab996 + +Changes since version 0.11.24: + +* osx: pass const handle pointer to uv___stream_fd (Chernyshev Viacheslav) + +* unix, windows: pass const handle ptr to uv_tcp_get*name (Chernyshev + Viacheslav) + +* common: pass const sockaddr ptr to uv_ip*_name (Chernyshev Viacheslav) + +* unix, windows: validate flags on uv_udp|tcp_bind (Saúl Ibarra Corretgé) + +* unix: handle case when addr is not initialized after recvmsg (Saúl Ibarra + Corretgé) + +* unix, windows: uv_now constness (Rasmus Pedersen) + + +2014.04.15, Version 0.11.24 (Unstable), ed948c29f6e8c290f79325a6f0bc9ef35bcde644 + +Changes since version 0.11.23: + +* linux: reduce file descriptor count of async pipe (Ben Noordhuis) + +* sunos: support IPv6 qualified link-local addresses (Saúl Ibarra Corretgé) + +* windows: fix opening of read-only stdin pipes (Alexis Campailla) + +* windows: Fix an infinite loop in uv_spawn (Alex Crichton) + +* windows: fix console signal handler refcount (æŽæ¸¯å¹³) + +* inet: allow scopeid in uv_inet_pton (Fedor Indutny) + + +2014.04.07, Version 0.11.23 (Unstable), e54de537efcacd593f36fcaaf8b4cb9e64313275 + +Changes since version 0.11.22: + +* fs: avoid using readv/writev where possible (Fedor Indutny) + +* mingw: fix build with autotools (Saúl Ibarra Corretgé) + +* bsd: support IPv6 qualified link-local addresses (Saúl Ibarra Corretgé) + +* unix: add UV_HANDLE_IPV6 flag to tcp and udp handles (Saúl Ibarra Corretgé) + +* unix, windows: do not set SO_REUSEADDR by default on udp (Saúl Ibarra + Corretgé) + +* windows: fix check in uv_tty_endgame() (Maks Naumov) + +* unix, windows: add IPv6 support for uv_udp_multicast_interface (Saúl Ibarra + Corretgé) + +* unix: fallback to blocking writes if reopening a tty fails (Saúl Ibarra + Corretgé) + +* unix: fix handling uv__open_cloexec failure (Saúl Ibarra Corretgé) + +* unix, windows: add IPv6 support to uv_udp_set_membership (Saúl Ibarra + Corretgé) + +* unix, windows: removed unused status parameter (Saúl Ibarra Corretgé) + +* android: add support of ifaddrs in android (Javier Hernández) + +* build: fix SunOS and AIX build with autotools (Saúl Ibarra Corretgé) + +* build: freebsd link with libelf if dtrace enabled (Saúl Ibarra Corretgé) + +* stream: do not leak `alloc_cb` buffers on error (Fedor Indutny) + +* unix: fix setting written size on uv_wd (Saúl Ibarra Corretgé) + + +2014.03.11, Version 0.11.22 (Unstable), cd0c19b1d3c56acf0ade7687006e12e75fbda36d + +Changes since version 0.11.21: + +* unix, windows: map ERANGE errno (Saúl Ibarra Corretgé) + +* unix, windows: make uv_cwd be consistent with uv_exepath (Saúl Ibarra + Corretgé) + +* process: remove debug perror() prints (Fedor Indutny) + +* windows: fall back for volume info query (Isaiah Norton) + +* pipe: allow queueing pending handles (Fedor Indutny) + +* windows: fix winsock status codes for address errors (Raul Martins) + +* windows: Remove unused variable from uv__pipe_insert_pending_socket (David + Capello) + +* unix: workaround broken pthread_sigmask on Android (Paul Tan) + +* error: add ENXIO for O_NONBLOCK FIFO open() (Fedor Indutny) + +* freebsd: use accept4, introduced in version 10 (Saúl Ibarra Corretgé) + +* windows: fix warnings of MinGW -Wall -O3 (StarWing) + +* openbsd, osx: fix compilation warning on scandir (Saúl Ibarra Corretgé) + +* linux: always deregister closing fds from epoll (Geoffry Song) + +* unix: reopen tty as /dev/tty (Saúl Ibarra Corretgé) + +* kqueue: invalidate fd in uv_fs_event_t (Fedor Indutny) + + +2014.02.28, Version 0.11.21 (Unstable), 3ef958158ae1019e027ebaa93114160099db5206 + +Changes since version 0.11.20: + +* unix: fix uv_fs_write when using an empty buffer (Saúl Ibarra Corretgé) + +* unix, windows: add assertion in uv_loop_delete (Saúl Ibarra Corretgé) + + +2014.02.27, Version 0.11.20 (Unstable), 88355e081b51c69ee1e2b6b0015a4e3d38bd0579 + +Changes since version 0.11.19: + +* stream: start thread after assignments (Oguz Bastemur) + +* fs: `uv__cloexec()` opened fd (Fedor Indutny) + +* gyp: qualify `library` variable (Fedor Indutny) + +* unix, win: add uv_udp_set_multicast_interface() (Austin Foxley) + +* unix: fix uv_tcp_nodelay return value in case of error (Saúl Ibarra Corretgé) + +* unix: call setgoups before calling setuid/setgid (Saúl Ibarra Corretgé) + +* include: mark close_cb field as private (Saúl Ibarra Corretgé) + +* unix, windows: map EFBIG errno (Saúl Ibarra Corretgé) + +* unix: correct error when calling uv_shutdown twice (Keno Fischer) + +* windows: fix building on MinGW (Alex Crichton) + +* windows: always initialize uv_process_t (Alex Crichton) + +* include: expose libuv version in header files (Saúl Ibarra Corretgé) + +* fs: vectored IO API for filesystem read/write (Benjamin Saunders) + +* windows: freeze in uv_tcp_endgame (Alexis Campailla) + +* sunos: handle rearm errors (Fedor Indutny) + +* unix: use a heap for timers (Ben Noordhuis) + +* linux: always deregister closing fds from epoll (Geoffry Song) + +* linux: include grp.h for setgroups() (William Light) + +* unix, windows: add uv_loop_init and uv_loop_close (Saúl Ibarra Corretgé) + +* unix, windows: add uv_getrusage() function (Oleg Efimov) + +* win: minor error handle fix to uv_pipe_write_impl (Rasmus Pedersen) + +* heap: fix node removal (Keno Fischer) + +* win: fix C99/C++ comment (Rasmus Pedersen) + +* fs: vectored IO API for filesystem read/write (Benjamin Saunders) + +* unix, windows: add uv_pipe_getsockname (Saúl Ibarra Corretgé) + +* unix, windows: map ENOPROTOOPT errno (Saúl Ibarra Corretgé) + +* errno: add ETXTBSY (Fedor Indutny) + +* fsevent: rename filename field to path (Saúl Ibarra Corretgé) + +* unix, windows: add uv_fs_event_getpath (Saúl Ibarra Corretgé) + +* unix, windows: add uv_fs_poll_getpath (Saúl Ibarra Corretgé) + +* unix, windows: map ERANGE errno (Saúl Ibarra Corretgé) + +* unix, windows: set required size on UV_ENOBUFS (Saúl Ibarra Corretgé) + +* unix, windows: clarify what uv_stream_set_blocking does (Saúl Ibarra + Corretgé) + +* fs: use preadv on Linux if available (Brian White) + + +2014.01.30, Version 0.11.19 (Unstable), 336a1825309744f920230ec3e427e78571772347 + +Changes since version 0.11.18: + +* linux: move sscanf() out of the assert() (Trevor Norris) + +* linux: fix C99/C++ comment (Fedor Indutny) + + +2014.05.02, Version 0.10.27 (Stable), 6e24ce23b1e7576059f85a608eca13b766458a01 + +Changes since version 0.10.26: + +* windows: fix console signal handler refcount (Saúl Ibarra Corretgé) + +* win: always leave crit section in get_proc_title (Fedor Indutny) + + +2014.04.07, Version 0.10.26 (Stable), d864907611c25ec986c5e77d4d6d6dee88f26926 + +Changes since version 0.10.25: + +* process: don't close stdio fds during spawn (Tonis Tiigi) + +* build, windows: do not fail on Windows SDK Prompt (Marc Schlaich) + +* build, windows: fix x64 configuration issue (Marc Schlaich) + +* win: fix buffer leak on error in pipe.c (Fedor Indutny) + +* kqueue: invalidate fd in uv_fs_event_t (Fedor Indutny) + +* linux: always deregister closing fds from epoll (Geoffry Song) + +* error: add ENXIO for O_NONBLOCK FIFO open() (Fedor Indutny) + + +2014.02.19, Version 0.10.25 (Stable), d778dc588507588b12b9f9d2905078db542ed751 + +Changes since version 0.10.24: + +* stream: start thread after assignments (Oguz Bastemur) + +* unix: correct error when calling uv_shutdown twice (Saúl Ibarra Corretgé) + +2014.01.30, Version 0.10.24 (Stable), aecd296b6bce9b40f06a61c5c94e43d45ac7308a + +Changes since version 0.10.23: + +* linux: move sscanf() out of the assert() (Trevor Norris) + +* linux: fix C99/C++ comment (Fedor Indutny) + + +2014.01.23, Version 0.11.18 (Unstable), d47962e9d93d4a55a9984623feaf546406c9cdbb + +Changes since version 0.11.17: + +* osx: Fix a possible segfault in uv__io_poll (Alex Crichton) + +* windows: improved handling of invalid FDs (Alexis Campailla) + +* doc: adding ARCHS flag to OS X build command (Nathan Sweet) + +* tcp: reveal bind-time errors before listen (Alexis Campailla) + +* tcp: uv_tcp_dualstack() (Fedor Indutny) + +* linux: relax assumption on /proc/stat parsing (Luca Bruno) + +* openbsd: fix obvious bug in uv_cpu_info (Fedor Indutny) + +* process: close stdio after dup2'ing it (Fedor Indutny) + +* linux: move sscanf() out of the assert() (Trevor Norris) + + +2014.01.23, Version 0.10.23 (Stable), dbd218e699fec8be311d85e4788be9e28ae884f8 + +Changes since version 0.10.22: + +* linux: relax assumption on /proc/stat parsing (Luca Bruno) + +* openbsd: fix obvious bug in uv_cpu_info (Fedor Indutny) + +* process: close stdio after dup2'ing it (Fedor Indutny) + + +2014.01.08, Version 0.10.22 (Stable), f526c90eeff271d9323a9107b9a64a4671fd3103 + +Changes since version 0.10.21: + +* windows: avoid assertion failure when pipe server is closed (Bert Belder) + + +2013.12.32, Version 0.11.17 (Unstable), 589c224d4c2e79fec65db01d361948f1e4976858 + +Changes since version 0.11.16: + +* stream: allow multiple buffers for uv_try_write (Fedor Indutny) + +* unix: fix a possible memory leak in uv_fs_readdir (Alex Crichton) + +* unix, windows: add uv_loop_alive() function (Sam Roberts) + +* windows: avoid assertion failure when pipe server is closed (Bert Belder) + +* osx: Fix a possible segfault in uv__io_poll (Alex Crichton) + +* stream: fix uv__stream_osx_select (Fedor Indutny) + + +2013.12.14, Version 0.11.16 (Unstable), ae0ed8c49d0d313c935c22077511148b6e8408a4 + +Changes since version 0.11.15: + +* fsevents: remove kFSEventStreamCreateFlagNoDefer polyfill (ci-innoq) + +* libuv: add more getaddrinfo errors (Steven Kabbes) + +* unix: fix accept() EMFILE error handling (Ben Noordhuis) + +* linux: fix up SO_REUSEPORT back-port (Ben Noordhuis) + +* fsevents: fix subfolder check (Fedor Indutny) + +* fsevents: fix invalid memory access (huxingyi) + +* windows/timer: fix uv_hrtime discontinuity (Bert Belder) + +* unix: fix various memory leaks and undef behavior (Fedor Indutny) + +* unix, windows: always update loop time (Saúl Ibarra Corretgé) + +* windows: translate system errors in uv_spawn (Alexis Campailla) + +* windows: uv_spawn code refactor (Alexis Campailla) + +* unix, windows: detect errors in uv_ip4/6_addr (Yorkie) + +* stream: introduce uv_try_write(...) (Fedor Indutny) + + +2013.12.13, Version 0.10.20 (Stable), 04141464dd0fba90ace9aa6f7003ce139b888a40 + +Changes since version 0.10.19: + +* linux: fix up SO_REUSEPORT back-port (Ben Noordhuis) + +* fs-event: fix invalid memory access (huxingyi) + + +2013.11.21, Version 0.11.15 (Unstable), bfe645ed7e99ca5670d9279ad472b604c129d2e5 + +Changes since version 0.11.14: + +* fsevents: report errors to user (Fedor Indutny) + +* include: UV_FS_EVENT_RECURSIVE is a flag (Fedor Indutny) + +* linux: use CLOCK_MONOTONIC_COARSE if available (Ben Noordhuis) + +* build: make systemtap probes work with gyp build (Ben Noordhuis) + +* unix: update events from pevents between polls (Fedor Indutny) + +* fsevents: support japaneese characters in path (Chris Bank) + +* linux: don't turn on SO_REUSEPORT socket option (Ben Noordhuis) + +* queue: strengthen type checks (Ben Noordhuis) + +* include: remove uv_strlcat() and uv_strlcpy() (Ben Noordhuis) + +* build: fix windows smp build with gyp (Geert Jansen) + +* unix: return exec errors from uv_spawn, not async (Alex Crichton) + +* fsevents: use native character encoding file paths (Ben Noordhuis) + +* linux: handle EPOLLHUP without EPOLLIN/EPOLLOUT (Ben Noordhuis) + +* windows: use _snwprintf(), not swprintf() (Ben Noordhuis) + +* fsevents: use FlagNoDefer for FSEventStreamCreate (Fedor Indutny) + +* unix: fix reopened fd bug (Fedor Indutny) + +* core: fix fake watcher list and count preservation (Fedor Indutny) + +* unix: set close-on-exec flag on received fds (Ben Noordhuis) + +* netbsd, openbsd: enable futimes() wrapper (Ben Noordhuis) + +* unix: nicer error message when kqueue() fails (Ben Noordhuis) + +* samples: add socks5 proxy sample application (Ben Noordhuis) + + +2013.11.13, Version 0.10.19 (Stable), 33959f7524090b8d2c6c41e2400ca77e31755059 + +Changes since version 0.10.18: + +* darwin: avoid calling GetCurrentProcess (Fedor Indutny) + +* unix: update events from pevents between polls (Fedor Indutny) + +* fsevents: support japaneese characters in path (Chris Bank) + +* linux: don't turn on SO_REUSEPORT socket option (Ben Noordhuis) + +* build: fix windows smp build with gyp (Geert Jansen) + +* linux: handle EPOLLHUP without EPOLLIN/EPOLLOUT (Ben Noordhuis) + +* unix: fix reopened fd bug (Fedor Indutny) + +* core: fix fake watcher list and count preservation (Fedor Indutny) + + +2013.10.30, Version 0.11.14 (Unstable), d7a6482f45c1b4eb4a853dbe1a9ce8090a35633a + +Changes since version 0.11.13: + +* darwin: create fsevents thread on demand (Ben Noordhuis) + +* fsevents: FSEvents is most likely not thread-safe (Fedor Indutny) + +* fsevents: use shared FSEventStream (Fedor Indutny) + +* windows: make uv_fs_chmod() report errors correctly (Bert Belder) + +* windows: make uv_shutdown() for write-only pipes work (Bert Belder) + +* windows/fs: wrap multi-statement macros in do..while block (Bert Belder) + +* windows/fs: make uv_fs_open() report EINVAL correctly (Bert Belder) + +* windows/fs: handle _open_osfhandle() failure correctly (Bert Belder) + +* windows/fs: wrap multi-statement macros in do..while block (Bert Belder) + +* windows/fs: make uv_fs_open() report EINVAL correctly (Bert Belder) + +* windows/fs: handle _open_osfhandle() failure correctly (Bert Belder) + +* build: clarify instructions for Windows (Brian Kaisner) + +* build: remove GCC_WARN_ABOUT_MISSING_NEWLINE (Ben Noordhuis) + +* darwin: fix 10.6 build error in fsevents.c (Ben Noordhuis) + +* windows: run close callbacks after polling for i/o (Saúl Ibarra Corretgé) + +* include: clarify uv_tcp_bind() behavior (Ben Noordhuis) + +* include: clean up includes in uv.h (Ben Noordhuis) + +* include: remove UV_IO_PRIVATE_FIELDS macro (Ben Noordhuis) + +* include: fix typo in comment in uv.h (Ben Noordhuis) + +* include: update uv_is_active() documentation (Ben Noordhuis) + +* include: make uv_process_options_t.cwd const (Ben Noordhuis) + +* unix: wrap long lines at 80 columns (Ben Noordhuis) + +* unix, windows: make uv_is_*() always return 0 or 1 (Ben Noordhuis) + +* bench: measure total/init/dispatch/cleanup times (Ben Noordhuis) + +* build: use -pthread on sunos (Timothy J. Fontaine) + +* windows: remove duplicate check in stream.c (Ben Noordhuis) + +* unix: sanity-check fds before closing (Ben Noordhuis) + +* unix: remove uv__pipe_accept() (Ben Noordhuis) + +* unix: fix uv_spawn() NULL pointer deref on ENOMEM (Ben Noordhuis) + +* unix: don't close inherited fds on uv_spawn() fail (Ben Noordhuis) + +* unix: revert recent FSEvent changes (Ben Noordhuis) + +* fsevents: fix clever rescheduling (Fedor Indutny) + +* linux: ignore fractional time in uv_uptime() (Ben Noordhuis) + +* unix: fix SIGCHLD waitpid() race in process.c (Ben Noordhuis) + +* unix, windows: add uv_fs_event_start/stop functions (Saúl Ibarra Corretgé) + +* unix: fix non-synchronized access in signal.c (Ben Noordhuis) + +* unix: add atomic-ops.h (Ben Noordhuis) + +* unix: add spinlock.h (Ben Noordhuis) + +* unix: clean up uv_tty_set_mode() a little (Ben Noordhuis) + +* unix: make uv_tty_reset_mode() async signal-safe (Ben Noordhuis) + +* include: add E2BIG status code mapping (Ben Noordhuis) + +* windows: fix duplicate case build error (Ben Noordhuis) + +* windows: remove unneeded check (Saúl Ibarra Corretgé) + +* include: document pipe path truncation behavior (Ben Noordhuis) + +* fsevents: increase stack size for OSX 10.9 (Fedor Indutny) + +* windows: _snprintf expected wrong parameter type in string (Maks Naumov) + +* windows: "else" keyword is missing (Maks Naumov) + +* windows: incorrect check for SOCKET_ERROR (Maks Naumov) + +* windows: add stdlib.h to satisfy reference to abort (Sean Farrell) + +* build: fix check target for mingw (Sean Farrell) + +* unix: move uv_shutdown() assertion (Keno Fischer) + +* darwin: avoid calling GetCurrentProcess (Fedor Indutny) + + +2013.10.19, Version 0.10.18 (Stable), 9ec52963b585e822e87bdc5de28d6143aff0d2e5 + +Changes since version 0.10.17: + +* unix: fix uv_spawn() NULL pointer deref on ENOMEM (Ben Noordhuis) + +* unix: don't close inherited fds on uv_spawn() fail (Ben Noordhuis) + +* unix: revert recent FSEvent changes (Ben Noordhuis) + +* unix: fix non-synchronized access in signal.c (Ben Noordhuis) + + +2013.09.25, Version 0.10.17 (Stable), 9670e0a93540c2f0d86c84a375f2303383c11e7e + +Changes since version 0.10.16: + +* build: remove GCC_WARN_ABOUT_MISSING_NEWLINE (Ben Noordhuis) + +* darwin: fix 10.6 build error in fsevents.c (Ben Noordhuis) + + +2013.09.06, Version 0.10.16 (Stable), 2bce230d81f4853a23662cbeb26fe98010b1084b + +Changes since version 0.10.15: + +* windows: make uv_shutdown() for write-only pipes work (Bert Belder) + +* windows: make uv_fs_open() report EINVAL when invalid arguments are passed + (Bert Belder) + +* windows: make uv_fs_open() report _open_osfhandle() failure correctly (Bert + Belder) + +* windows: make uv_fs_chmod() report errors correctly (Bert Belder) + +* windows: wrap multi-statement macros in do..while block (Bert Belder) + + +2013.09.05, Version 0.11.13 (Unstable), f5b6db6c1d7f93d28281207fd47c3841c9a9792e + +Changes since version 0.11.12: + +* unix: define _GNU_SOURCE, exposes glibc-isms (Ben Noordhuis) + +* windows: check for nonconforming swprintf arguments (Brent Cook) + +* build: include internal headers in source list (Brent Cook) + +* include: merge uv_tcp_bind and uv_tcp_bind6 (Ben Noordhuis) + +* include: merge uv_tcp_connect and uv_tcp_connect6 (Ben Noordhuis) + +* include: merge uv_udp_bind and uv_udp_bind6 (Ben Noordhuis) + +* include: merge uv_udp_send and uv_udp_send6 (Ben Noordhuis) + + +2013.09.03, Version 0.11.12 (Unstable), 82d01d5f6780d178f5176a01425ec297583c0811 + +Changes since version 0.11.11: + +* test: fix epoll_wait() usage in test-embed.c (Ben Noordhuis) + +* include: uv_alloc_cb now takes uv_buf_t* (Ben Noordhuis) + +* include: uv_read{2}_cb now takes const uv_buf_t* (Ben Noordhuis) + +* include: uv_ip[46]_addr now takes sockaddr_in* (Ben Noordhuis) + +* include: uv_tcp_bind{6} now takes sockaddr_in* (Ben Noordhuis) + +* include: uv_tcp_connect{6} now takes sockaddr_in* (Ben Noordhuis) + +* include: uv_udp_recv_cb now takes const uv_buf_t* (Ben Noordhuis) + +* include: uv_udp_bind{6} now takes sockaddr_in* (Ben Noordhuis) + +* include: uv_udp_send{6} now takes sockaddr_in* (Ben Noordhuis) + +* include: uv_spawn takes const uv_process_options_t* (Ben Noordhuis) + +* include: make uv_write{2} const correct (Ben Noordhuis) + +* windows: fix flags assignment in uv_fs_readdir() (Ben Noordhuis) + +* windows: fix stray comments (Ben Noordhuis) + +* windows: remove unused is_path_dir() function (Ben Noordhuis) + + +2013.08.30, Version 0.11.11 (Unstable), ba876d53539ed0427c52039012419cd9374c6f0d + +Changes since version 0.11.10: + +* unix, windows: add thread-local storage API (Ben Noordhuis) + +* linux: don't turn on SO_REUSEPORT socket option (Ben Noordhuis) + +* darwin: fix 10.6 build error in fsevents.c (Ben Noordhuis) + +* windows: make uv_shutdown() for write-only pipes work (Bert Belder) + +* include: update uv_udp_open() / uv_udp_bind() docs (Ben Noordhuis) + +* unix: req queue must be empty when destroying loop (Ben Noordhuis) + +* unix: move loop functions from core.c to loop.c (Ben Noordhuis) + +* darwin: remove CoreFoundation dependency (Ben Noordhuis) + +* windows: make autotools build system work with mingw (Keno Fischer) + +* windows: fix mingw build (Alex Crichton) + +* windows: tweak Makefile.mingw for easier usage (Alex Crichton) + +* build: remove _GNU_SOURCE macro definition (Ben Noordhuis) + + +2013.08.25, Version 0.11.10 (Unstable), 742dadcb7154cc7bb89c0c228a223b767a36cf0d + +* windows: Re-implement uv_fs_stat. The st_ctime field now contains the change + time, not the creation time, like on unix systems. st_dev, st_ino, st_blocks + and st_blksize are now also filled out. (Bert Belder) + +* linux: fix setsockopt(SO_REUSEPORT) error handling (Ben Noordhuis) + +* windows: report uv_process_t exit code correctly (Bert Belder) + +* windows: make uv_fs_chmod() report errors correctly (Bert Belder) + +* windows: make some more NT apis available for libuv's internal use (Bert + Belder) + +* windows: squelch some compiler warnings (Bert Belder) + + +2013.08.24, Version 0.11.9 (Unstable), a2d29b5b068cbac93dc16138fb30a74e2669daad + +Changes since version 0.11.8: + +* fsevents: share FSEventStream between multiple FS watchers, which removes a + limit on the maximum number of file watchers that can be created on OS X. + (Fedor Indutny) + +* process: the `exit_status` parameter for a uv_process_t's exit callback now + is an int64_t, and no longer an int. (Bert Belder) + +* process: make uv_spawn() return some types of errors immediately on windows, + instead of passing the error code the the exit callback. This brings it on + par with libuv's behavior on unix. (Bert Belder) + + +2013.08.24, Version 0.10.15 (Stable), 221078a8fdd9b853c6b557b3d9a5dd744b4fdd6b + +Changes since version 0.10.14: + +* fsevents: create FSEvents thread on demand (Ben Noordhuis) + +* fsevents: use a single thread for interacting with FSEvents, because it's not + thread-safe. (Fedor Indutny) + +* fsevents: share FSEventStream between multiple FS watchers, which removes a + limit on the maximum number of file watchers that can be created on OS X. + (Fedor Indutny) + + +2013.08.22, Version 0.11.8 (Unstable), a5260462db80ab0deab6b9e6a8991dd8f5a9a2f8 + +Changes since version 0.11.7: + +* unix: fix missing return value warning in stream.c (Ben Noordhuis) + +* build: serial-tests was added in automake v1.12 (Ben Noordhuis) + +* windows: fix uninitialized local variable warning (Ben Noordhuis) + +* windows: fix missing return value warning (Ben Noordhuis) + +* build: fix string comparisons in autogen.sh (Ben Noordhuis) + +* windows: move INLINE macro, remove UNUSED (Ben Noordhuis) + +* unix: clean up __attribute__((quux)) usage (Ben Noordhuis) + +* sunos: remove futimes() macro (Ben Noordhuis) + +* unix: fix uv__signal_unlock() prototype (Ben Noordhuis) + +* unix, windows: allow NULL async callback (Ben Noordhuis) + +* build: apply dtrace -G to all object files (Timothy J. Fontaine) + +* darwin: fix indentation in uv__hrtime() (Ben Noordhuis) + +* darwin: create fsevents thread on demand (Ben Noordhuis) + +* darwin: reduce fsevents thread stack size (Ben Noordhuis) + +* darwin: call pthread_setname_np() if available (Ben Noordhuis) + +* build: fix automake serial-tests check again (Ben Noordhuis) + +* unix: retry waitpid() on EINTR (Ben Noordhuis) + +* darwin: fix ios build error (Ben Noordhuis) + +* darwin: fix ios compiler warning (Ben Noordhuis) + +* test: simplify test-ip6-addr.c (Ben Noordhuis) + +* unix, windows: fix ipv6 link-local address parsing (Ben Noordhuis) + +* fsevents: FSEvents is most likely not thread-safe (Fedor Indutny) + +* windows: omit stdint.h, fix msvc 2008 build error (Ben Noordhuis) + + +2013.08.22, Version 0.10.14 (Stable), 15d64132151c18b26346afa892444b95e2addad0 + +Changes since version 0.10.13: + +* unix: retry waitpid() on EINTR (Ben Noordhuis) + + +2013.08.07, Version 0.11.7 (Unstable), 3cad361f8776f70941b39d65bd9426bcb1aa817b + +Changes since version 0.11.6: + +* unix, windows: fix uv_fs_chown() function prototype (Ben Noordhuis) + +* unix, windows: remove unused variables (Brian White) + +* test: fix signed/unsigned comparison warnings (Ben Noordhuis) + +* build: dtrace shouldn't break out of tree builds (Timothy J. Fontaine) + +* unix, windows: don't read/recv if buf.len==0 (Ben Noordhuis) + +* build: add mingw makefile (Ben Noordhuis) + +* unix, windows: add MAC to uv_interface_addresses() (Brian White) + +* build: enable AM_INIT_AUTOMAKE([subdir-objects]) (Ben Noordhuis) + +* unix, windows: make buf arg to uv_fs_write const (Ben Noordhuis) + +* sunos: fix build breakage introduced in e3a657c (Ben Noordhuis) + +* aix: fix build breakage introduced in 3ee4d3f (Ben Noordhuis) + +* windows: fix mingw32 build, define JOB_OBJECT_XXX (Yasuhiro Matsumoto) + +* windows: fix mingw32 build, include limits.h (Yasuhiro Matsumoto) + +* test: replace sprintf() with snprintf() (Ben Noordhuis) + +* test: replace strcpy() with strncpy() (Ben Noordhuis) + +* openbsd: fix uv_ip6_addr() unused variable warnings (Ben Noordhuis) + +* openbsd: fix dlerror() const correctness warning (Ben Noordhuis) + +* openbsd: fix uv_fs_sendfile() unused variable warnings (Ben Noordhuis) + +* build: disable parallel automake tests (Ben Noordhuis) + +* test: add windows-only snprintf() function (Ben Noordhuis) + +* build: add automake serial-tests version check (Ben Noordhuis) + + +2013.07.26, Version 0.10.13 (Stable), 381312e1fe6fecbabc943ccd56f0e7d114b3d064 + +Changes since version 0.10.12: + +* unix, windows: fix uv_fs_chown() function prototype (Ben Noordhuis) + + +2013.07.21, Version 0.11.6 (Unstable), 6645b93273e0553d23823c576573b82b129bf28c + +Changes since version 0.11.5: + +* test: open stdout fd in write-only mode (Ben Noordhuis) + +* windows: uv_spawn shouldn't reject reparse points (Bert Belder) + +* windows: use WSAGetLastError(), not errno (Ben Noordhuis) + +* build: darwin: disable -fstrict-aliasing warnings (Ben Noordhuis) + +* test: fix signed/unsigned compiler warning (Ben Noordhuis) + +* test: add 'start timer from check handle' test (Ben Noordhuis) + +* build: `all` now builds static and dynamic lib (Ben Noordhuis) + +* unix, windows: add extra fields to uv_stat_t (Saúl Ibarra Corretgé) + +* build: add install target to the makefile (Navaneeth Kedaram Nambiathan) + +* build: switch to autotools (Ben Noordhuis) + +* build: use AM_PROG_AR conditionally (Ben Noordhuis) + +* test: fix fs_fstat test on sunos (Ben Noordhuis) + +* test: fix fs_chown when running as root (Ben Noordhuis) + +* test: fix spawn_setgid_fails and spawn_setuid_fails (Ben Noordhuis) + +* build: use AM_SILENT_RULES conditionally (Ben Noordhuis) + +* build: add DTrace detection for autotools (Timothy J. Fontaine) + +* linux,darwin,win: link-local IPv6 addresses (Miroslav BajtoÅ¡) + +* unix: fix build when !defined(PTHREAD_MUTEX_ERRORCHECK) (Ben Noordhuis) + +* unix, windows: return error codes directly (Ben Noordhuis) + + +2013.07.10, Version 0.10.12 (Stable), 58a46221bba726746887a661a9f36fe9ff204209 + +Changes since version 0.10.11: + +* linux: add support for MIPS (Andrei Sedoi) + +* windows: uv_spawn shouldn't reject reparse points (Bert Belder) + +* windows: use WSAGetLastError(), not errno (Ben Noordhuis) + +* build: darwin: disable -fstrict-aliasing warnings (Ben Noordhuis) + +* build: `all` now builds static and dynamic lib (Ben Noordhuis) + +* unix: fix build when !defined(PTHREAD_MUTEX_ERRORCHECK) (Ben Noordhuis) + + +2013.06.27, Version 0.11.5 (Unstable), e3c63ff1627a14e96f54c1c62b0d68b446d8425b + +Changes since version 0.11.4: + +* build: remove CSTDFLAG, use only CFLAGS (Ben Noordhuis) + +* unix: support for android builds (Linus MÃ¥rtensson) + +* unix: avoid extra read, short-circuit on POLLHUP (Ben Noordhuis) + +* uv: support android libuv standalone build (Linus MÃ¥rtensson) + +* src: make queue.h c++ compatible (Ben Noordhuis) + +* unix: s/ngx-queue.h/queue.h/ in checksparse.sh (Ben Noordhuis) + +* unix: unconditionally stop handle on close (Ben Noordhuis) + +* freebsd: don't enable dtrace if it's not available (Brian White) + +* build: make HAVE_DTRACE=0 should disable dtrace (Timothy J. Fontaine) + +* unix: remove overzealous assert (Ben Noordhuis) + +* unix: remove unused function uv_fatal_error() (Ben Noordhuis) + +* unix, windows: clean up uv_thread_create() (Ben Noordhuis) + +* queue: fix pointer truncation on LLP64 platforms (Bert Belder) + +* build: set OS=="android" for android builds (Linus MÃ¥rtensson) + +* windows: don't use uppercase in include filename (Ben Noordhuis) + +* stream: add an API to make streams do blocking writes (Henry Rawas) + +* windows: use WSAGetLastError(), not errno (Ben Noordhuis) + + +2013.06.13, Version 0.10.11 (Stable), c3b75406a66a10222a589cb173e8f469e9665c7e + +Changes since version 0.10.10: + +* unix: unconditionally stop handle on close (Ben Noordhuis) + +* freebsd: don't enable dtrace if it's not available (Brian White) + +* build: make HAVE_DTRACE=0 should disable dtrace (Timothy J. Fontaine) + +* unix: remove overzealous assert (Ben Noordhuis) + +* unix: clear UV_STREAM_SHUTTING after shutdown() (Ben Noordhuis) + +* unix: fix busy loop, write if POLLERR or POLLHUP (Ben Noordhuis) + + +2013.06.05, Version 0.10.10 (Stable), 0d95a88bd35fce93863c57a460be613aea34d2c5 + +Changes since version 0.10.9: + +* include: document uv_update_time() and uv_now() (Ben Noordhuis) + +* linux: fix cpu model parsing on newer arm kernels (Ben Noordhuis) + +* linux: fix a memory leak in uv_cpu_info() error path (Ben Noordhuis) + +* linux: don't ignore out-of-memory errors in uv_cpu_info() (Ben Noordhuis) + +* unix, windows: move uv_now() to uv-common.c (Ben Noordhuis) + +* test: fix a compilation problem in test-osx-select.c that was caused by the + use of c-style comments (Bert Belder) + +* darwin: use uv_fs_sendfile() use the sendfile api correctly (Wynn Wilkes) + + +2013.05.30, Version 0.11.4 (Unstable), e43e5b3d954a0989db5588aa110e1fe4fe6e0219 + +Changes since version 0.11.3: + +* windows: make uv_spawn not fail when the libuv embedding application is run + under external job control (Bert Belder) + +* darwin: assume CFRunLoopStop() isn't thread-safe, fixing a race condition + when stopping the 'stdin select hack' thread (Fedor Indutny) + +* win: fix UV_EALREADY not being reported correctly to the libuv user in some + cases (Bert Belder) + +* darwin: make the uv__cf_loop_runner and uv__cf_loop_cb functions static (Ben + Noordhuis) + +* darwin: task_info() cannot fail (Ben Noordhuis) + +* unix: add error mapping for ENETDOWN (Ben Noordhuis) + +* unix: implicitly signal write errors to the libuv user (Ben Noordhuis) + +* unix: fix assertion error on signal pipe overflow (Bert Belder) + +* unix: turn off POLLOUT after stream connect (Ben Noordhuis) + +* unix: fix stream refcounting buglet (Ben Noordhuis) + +* unix: remove assert statements that are no longer correct (Ben Noordhuis) + +* unix: appease warning about non-standard `inline` (Sean Silva) + +* unix: add uv__is_closing() macro (Ben Noordhuis) + +* unix: stop stream POLLOUT watcher on write error (Ben Noordhuis) + +* include: document uv_update_time() and uv_now() (Ben Noordhuis) + +* linux: fix cpu model parsing on newer arm kernels (Ben Noordhuis) + +* linux: fix a memory leak in uv_cpu_info() error path (Ben Noordhuis) + +* linux: don't ignore out-of-memory errors in uv_cpu_info() (Ben Noordhuis) + +* unix, windows: move uv_now() to uv-common.c (Ben Noordhuis) + +* test: fix a compilation problem in test-osx-select.c that was caused by the + use of c-style comments (Bert Belder) + +* darwin: use uv_fs_sendfile() use the sendfile api correctly (Wynn Wilkes) + +* windows: call idle handles on every loop iteration, something the unix + implementation already did (Bert Belder) + +* test: update the idle-starvation test to verify that idle handles are called + in every loop iteration (Bert Belder) + +* unix, windows: ensure that uv_run() in RUN_ONCE mode calls timers that expire + after blocking (Ben Noordhuis) + + +2013.05.29, Version 0.10.9 (Stable), a195f9ace23d92345baf57582678bfc3017e6632 + +Changes since version 0.10.8: + +* unix: fix stream refcounting buglet (Ben Noordhuis) + +* unix: remove erroneous asserts (Ben Noordhuis) + +* unix: add uv__is_closing() macro (Ben Noordhuis) + +* unix: stop stream POLLOUT watcher on write error (Ben Noordhuis) + + +2013.05.25, Version 0.10.8 (Stable), 0f39be12926fe2d8766a9f025797a473003e6504 + +Changes since version 0.10.7: + +* windows: make uv_spawn not fail under job control (Bert Belder) + +* darwin: assume CFRunLoopStop() isn't thread-safe (Fedor Indutny) + +* win: fix UV_EALREADY incorrectly set (Bert Belder) + +* darwin: make two uv__cf_*() functions static (Ben Noordhuis) + +* darwin: task_info() cannot fail (Ben Noordhuis) + +* unix: add mapping for ENETDOWN (Ben Noordhuis) + +* unix: implicitly signal write errors to libuv user (Ben Noordhuis) + +* unix: fix assert on signal pipe overflow (Bert Belder) + +* unix: turn off POLLOUT after stream connect (Ben Noordhuis) + + +2013.05.16, Version 0.11.3 (Unstable), 0a48c05b5988aea84c605751900926fa25443b34 + +Changes since version 0.11.2: + +* unix: clean up uv_accept() (Ben Noordhuis) + +* unix: remove errno preserving code (Ben Noordhuis) + +* darwin: fix ios build, don't require ApplicationServices (Ben Noordhuis) + +* windows: kill child processes when the parent dies (Bert Belder) + +* build: set soname in shared library (Ben Noordhuis) + +* build: make `make test` link against .a again (Ben Noordhuis) + +* build: only set soname on shared object builds (Timothy J. Fontaine) + +* build: convert predefined $PLATFORM to lower case (Elliot Saba) + +* test: fix process_title failing on linux (Miroslav BajtoÅ¡) + +* test, sunos: disable process_title test (Miroslav BajtoÅ¡) + +* test: add error logging to tty unit test (Miroslav BajtoÅ¡) + + +2013.05.15, Version 0.10.7 (Stable), 028baaf0846b686a81e992cb2f2f5a9b8e841fcf + +Changes since version 0.10.6: + +* windows: kill child processes when the parent dies (Bert Belder) + + +2013.05.15, Version 0.10.6 (Stable), 11e6613e6260d95c8cf11bf89a2759c24649319a + +Changes since version 0.10.5: + +* stream: fix osx select hack (Fedor Indutny) + +* stream: fix small nit in select hack, add test (Fedor Indutny) + +* build: link with libkvm on openbsd (Ben Noordhuis) + +* stream: use harder sync restrictions for osx-hack (Fedor Indutny) + +* unix: fix EMFILE error handling (Ben Noordhuis) + +* darwin: fix unnecessary include headers (Daisuke Murase) + +* darwin: rename darwin-getproctitle.m (Ben Noordhuis) + +* build: convert predefined $PLATFORM to lower case (Elliot Saba) + +* build: set soname in shared library (Ben Noordhuis) + +* build: make `make test` link against .a again (Ben Noordhuis) + +* darwin: fix ios build, don't require ApplicationServices (Ben Noordhuis) + +* build: only set soname on shared object builds (Timothy J. Fontaine) + + +2013.05.11, Version 0.11.2 (Unstable), 3fba0bf65f091b91a9760530c05c6339c658d88b + +Changes since version 0.11.1: + +* darwin: look up file path with F_GETPATH (Ben Noordhuis) + +* unix, windows: add uv_has_ref() function (Saúl Ibarra Corretgé) + +* build: avoid double / in paths for dtrace (Timothy J. Fontaine) + +* unix: remove src/unix/cygwin.c (Ben Noordhuis) + +* windows: deal with the fact that GetTickCount might lag (Bert Belder) + +* unix: silence STATIC_ASSERT compiler warnings (Ben Noordhuis) + +* linux: don't use fopen() in uv_resident_set_memory() (Ben Noordhuis) + + +2013.04.24, Version 0.10.5 (Stable), 6595a7732c52eb4f8e57c88655f72997a8567a67 + +Changes since version 0.10.4: + +* unix: silence STATIC_ASSERT compiler warnings (Ben Noordhuis) + +* windows: make timers handle large timeouts (Miroslav BajtoÅ¡) + +* windows: remove superfluous assert statement (Bert Belder) + +* unix: silence STATIC_ASSERT compiler warnings (Ben Noordhuis) + +* linux: don't use fopen() in uv_resident_set_memory() (Ben Noordhuis) + + +2013.04.12, Version 0.10.4 (Stable), 85827e26403ac6dfa331af8ec9916ea7e27bd833 + +Changes since version 0.10.3: + +* include: update uv_backend_fd() documentation (Ben Noordhuis) + +* unix: include uv.h in src/version.c (Ben Noordhuis) + +* unix: don't write more than IOV_MAX iovecs (Fedor Indutny) + +* mingw-w64: don't call _set_invalid_parameter_handler (Nils Maier) + +* build: gyp disable thin archives (Timothy J. Fontaine) + +* sunos: re-export entire library when static (Timothy J. Fontaine) + +* unix: dtrace probes for tick-start and tick-stop (Timothy J. Fontaine) + +* windows: fix memory leak in fs__sendfile (Shannen Saez) + +* windows: remove double initialization in uv_tty_init (Shannen Saez) + +* build: fix dtrace-enabled out of tree build (Ben Noordhuis) + +* build: squelch -Wdollar-in-identifier-extension warnings (Ben Noordhuis) + +* inet: snprintf returns int, not size_t (Brian White) + +* win: refactor uv_cpu_info (Bert Belder) + +* build: add support for Visual Studio 2012 (Nicholas Vavilov) + +* build: -Wno-dollar-in-identifier-extension is clang only (Ben Noordhuis) + + +2013.04.11, Version 0.11.1 (Unstable), 5c10e82ae0bc99eff86d4b9baff1f1aa0bf84c0a + +This is the first versioned release from the current unstable libuv branch. + +Changes since Node.js v0.11.0: + +* all platforms: nanosecond resolution support for uv_fs_[fl]stat (Timothy J. + Fontaine) + +* all platforms: add netmask to uv_interface_address (Ben Kelly) + +* unix: make sure the `status` parameter passed to the `uv_getaddrinfo` is 0 or + -1 (Ben Noordhuis) + +* unix: limit the number of iovecs written in a single `writev` syscall to + IOV_MAX (Fedor Indutny) + +* unix: add dtrace probes for tick-start and tick-stop (Timothy J. Fontaine) + +* mingw-w64: don't call _set_invalid_parameter_handler (Nils Maier) + +* windows: fix memory leak in fs__sendfile (Shannen Saez) + +* windows: fix edge case bugs in uv_cpu_info (Bert Belder) + +* include: no longer ship with / include ngx-queue.h (Ben Noordhuis) + +* include: remove UV_VERSION_* macros from uv.h (Ben Noordhuis) + +* documentation updates (Kristian Evensen, Ben Kelly, Ben Noordhuis) + +* build: fix dtrace-enabled builds (Ben Noordhuis, Timothy J. Fontaine) + +* build: gyp disable thin archives (Timothy J. Fontaine) + +* build: add support for Visual Studio 2012 (Nicholas Vavilov) + + +2013.03.28, Version 0.10.3 (Stable), 31ebe23973dd98fd8a24c042b606f37a794e99d0 + +Changes since version 0.10.2: + +* include: remove extraneous const from uv_version() (Ben Noordhuis) + +* doc: update README, replace `OS` by `PLATFORM` (Ben Noordhuis) + +* build: simplify .buildstamp rule (Ben Noordhuis) + +* build: disable -Wstrict-aliasing on darwin (Ben Noordhuis) + +* darwin: don't select(&exceptfds) in fallback path (Ben Noordhuis) + +* unix: don't clear flags after closing UDP handle (Saúl Ibarra Corretgé) + + +2013.03.25, Version 0.10.2 (Stable), 0f36a00568f3e7608f97f6c6cdb081f4800a50c9 + +This is the first officially versioned release of libuv. Starting now +libuv will make releases independently of Node.js. + +Changes since Node.js v0.10.0: + +* test: add tap output for windows (Timothy J. Fontaine) + +* unix: fix uv_tcp_simultaneous_accepts() logic (Ben Noordhuis) + +* include: bump UV_VERSION_MINOR (Ben Noordhuis) + +* unix: improve uv_guess_handle() implementation (Ben Noordhuis) + +* stream: run try_select only for pipes and ttys (Fedor Indutny) + +Changes since Node.js v0.10.1: + +* build: rename OS to PLATFORM (Ben Noordhuis) + +* unix: make uv_timer_init() initialize repeat (Brian Mazza) + +* unix: make timers handle large timeouts (Ben Noordhuis) + +* build: add OBJC makefile var (Ben Noordhuis) + +* Add `uv_version()` and `uv_version_string()` APIs (Bert Belder) diff --git a/external/src/libuv/LICENSE b/external/src/libuv/LICENSE new file mode 100644 index 0000000..28f1733 --- /dev/null +++ b/external/src/libuv/LICENSE @@ -0,0 +1,70 @@ +libuv is licensed for use as follows: + +==== +Copyright (c) 2015-present libuv project contributors. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. +==== + +This license applies to parts of libuv originating from the +https://github.com/joyent/libuv repository: + +==== + +Copyright Joyent, Inc. and other Node contributors. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. + +==== + +This license applies to all parts of libuv that are not externally +maintained libraries. + +The externally maintained libraries used by libuv are: + + - tree.h (from FreeBSD), copyright Niels Provos. Two clause BSD license. + + - inet_pton and inet_ntop implementations, contained in src/inet.c, are + copyright the Internet Systems Consortium, Inc., and licensed under the ISC + license. + + - stdint-msvc2008.h (from msinttypes), copyright Alexander Chemeris. Three + clause BSD license. + + - pthread-fixes.c, copyright Google Inc. and Sony Mobile Communications AB. + Three clause BSD license. + + - android-ifaddrs.h, android-ifaddrs.c, copyright Berkeley Software Design + Inc, Kenneth MacKay and Emergya (Cloud4all, FP7/2007-2013, grant agreement + n° 289016). Three clause BSD license. diff --git a/external/src/libuv/LICENSE-docs b/external/src/libuv/LICENSE-docs new file mode 100644 index 0000000..53883b1 --- /dev/null +++ b/external/src/libuv/LICENSE-docs @@ -0,0 +1,396 @@ +Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.†The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. + diff --git a/external/src/libuv/LINKS.md b/external/src/libuv/LINKS.md new file mode 100644 index 0000000..b8204e5 --- /dev/null +++ b/external/src/libuv/LINKS.md @@ -0,0 +1,101 @@ +### Apps / VM +* [BIND 9](https://bind.isc.org/): DNS software system including an authoritative server, a recursive resolver and related utilities. +* [cjdns](https://github.com/cjdelisle/cjdns): Encrypted self-configuring network/VPN routing engine +* [clearskies_core](https://github.com/larroy/clearskies_core): Clearskies file synchronization program. (C++11) +* [CMake](https://cmake.org) open-source, cross-platform family of tools designed to build, test and package software +* [Coherence](https://github.com/liesware/coherence/): Cryptographic server for modern web apps. +* [DPS-For-IoT](https://github.com/intel/dps-for-iot/wiki): Fully distributed publish/subscribe protocol. +* [HashLink](https://github.com/HaxeFoundation/hashlink): Haxe run-time with libuv support included. +* [Haywire](https://github.com/kellabyte/Haywire): Asynchronous HTTP server. +* [H2O](https://github.com/h2o/h2o): An optimized HTTP server with support for HTTP/1.x and HTTP/2. +* [Igropyr](https://github.com/guenchi/Igropyr): a async Scheme http server base on libuv. +* [Julia](http://julialang.org/): Scientific computing programming language +* [Kestrel](https://github.com/aspnet/AspNetCore/tree/master/src/Servers/Kestrel): web server (C# + libuv + [ASP.NET Core](http://github.com/aspnet)) +* [Knot DNS Resolver](https://www.knot-resolver.cz/): A minimalistic DNS caching resolver +* [Lever](http://leverlanguage.com): runtime, libuv at the 0.9.0 release +* [libnode](https://github.com/plenluno/libnode): C++ implementation of Node.js +* [libstorj](https://github.com/Storj/libstorj): Library for interacting with Storj network +* [libuv_message_framing](https://github.com/litesync/libuv_message_framing) Message-based communication for libuv +* [luaw](https://github.com/raksoras/luaw): Lua web server backed by libuv +* [Luvit](http://luvit.io): Node.JS for the Lua Inventor +* [mo](https://github.com/wehu/mo): Scheme (guile) + libuv runtime +* [MoarVM](https://github.com/MoarVM/MoarVM): a VM for [Rakudo](http://rakudo.org/) [Raku](http://raku.org) +* [Mysocks](https://github.com/zhou0/mysocks): a cross-platform [Shadowsocks](https://shadowsocks.org) client +* [mediasoup](http://mediasoup.org): Powerful WebRTC SFU for Node.js +* [Neovim](https://neovim.io/): A major refactor of Vim. +* [node9](https://github.com/jvburnes/node9): A portable, hybrid, distributed OS based on Inferno, LuaJIT and Libuv +* [node.js](http://www.nodejs.org/): Javascript (using Google's V8) + libuv +* [node.native](https://github.com/d5/node.native): node.js-like API for C++11 +* [nodeuv](https://github.com/nodeuv): An organization with several c++ wrappers for libs which are used in node.js. +* [phastlight](https://github.com/phastlight/phastlight): Command line tool and web server written in PHP 5.3+ inspired by Node.js +* [pilight](https://www.pilight.org/): home automation ("domotica") +* [pixie](https://github.com/pixie-lang/pixie): clojure-inspired lisp with a tracing JIT +* [potion](https://github.com/perl11/potion)/[p2](https://github.com/perl11/p2): runtime +* [racer](https://libraries.io/rubygems/racer): Ruby web server written as an C extension +* [spider-gazelle](https://github.com/cotag/spider-gazelle): Ruby web server using libuv bindings +* [Suave](http://suave.io/): A simple web development F# library providing a lightweight web server and a set of combinators to manipulate route flow and task composition +* [Swish](https://github.com/becls/swish/): Concurrency engine with Erlang-like concepts. Includes a web server. +* [Trevi](https://github.com/Yoseob/Trevi): A powerful Swift Web Application Server Framework Project +* [Urbit](http://urbit.org): runtime +* [uv_callback](https://github.com/litesync/uv_callback) libuv thread communication +* [uvloop](https://github.com/MagicStack/uvloop): Ultra fast implementation of python's asyncio event loop on top of libuv +* [Wren CLI](https://github.com/wren-lang/wren-cli): For io, process, scheduler and timer modules + +### Other +* [libtuv](https://github.com/Samsung/libtuv): libuv fork for IoT and embedded systems + +### Bindings +* [Ring](http://ring-lang.net) + * [RingLibuv](http://ring-lang.sourceforge.net/doc1.7/libuv.html) +* Ruby + * [libuv](https://github.com/cotag/libuv) + * [uvrb](https://github.com/avalanche123/uvrb) + * [ruv](https://github.com/aq1018/ruv) + * [rbuv](https://github.com/rbuv/rbuv) + * [mruby-uv](https://github.com/mattn/mruby-uv): mruby binding +* Lua + * [luv](https://github.com/creationix/luv) + * [lev](https://github.com/connectFree/lev) + * [lluv](https://github.com/moteus/lua-lluv) +* C++11 + * [uvpp](https://github.com/larroy/uvpp) - Not complete, exposes very few aspects of `libuv` +* C++17 + * [uvw](https://github.com/skypjack/uvw) - Header-only, event based, tiny and easy to use *libuv* wrapper in modern C++. +* Python + * [Pyuv](https://github.com/saghul/pyuv) + * [uvloop](https://github.com/MagicStack/uvloop) - Ultra fast asyncio event loop. + * [gevent](http://www.gevent.org) - Coroutine-based concurrency library for Python +* C# + * [NetUV](http://github.com/StormHub/NetUV) + * [LibuvSharp](http://github.com/txdv/LibuvSharp) +* Perl 5 + * [UV](https://metacpan.org/pod/UV) +* [Raku](https://raku.org/) + * [MoarVM](https://github.com/MoarVM/MoarVM) [uses](http://6guts.wordpress.com/2013/05/31/moarvm-a-virtual-machine-for-nqp-and-rakudo/) libuv +* PHP + * [php-uv](https://github.com/bwoebi/php-uv) +* Go + * [go-uv](https://github.com/mattn/go-uv) +* OCaml + * [luv](https://github.com/aantron/luv) + * [uwt](https://github.com/fdopen/uwt) +* ooc + * [ooc-uv](https://github.com/nddrylliog/ooc-uv) +* dylan + * [uv-dylan](https://github.com/waywardmonkeys/uv-dylan) +* R + * [httpuv](https://github.com/rstudio/httpuv): HTTP and WebSocket server library for R + * [fs](https://fs.r-lib.org/): Cross-platform file system operations +* Java + * [libuv-java](https://java.net/projects/avatar-js/sources/libuv-java/show): Java bindings +* Nim + * [nimuv](https://github.com/2vg/nimuv): Nim bindings +* Lisp + * [cl-libuv](https://github.com/orthecreedence/cl-libuv) Common Lisp bindings + * [cl-async](https://github.com/orthecreedence/cl-async) Common Lisp async abstraction on top of cl-libuv +* [Céu](http://www.ceu-lang.org) + * [Céu-libuv](https://github.com/fsantanna/ceu-libuv) +* Delphi + * [node.pas](https://github.com/vovach777/node.pas) NodeJS-like ecosystem +* Haskell + * [Z.Haskell](https://z.haskell.world) diff --git a/external/src/libuv/MAINTAINERS.md b/external/src/libuv/MAINTAINERS.md new file mode 100644 index 0000000..fb7e5ef --- /dev/null +++ b/external/src/libuv/MAINTAINERS.md @@ -0,0 +1,51 @@ + +# Project Maintainers + +libuv is currently managed by the following individuals: + +* **Anna Henningsen** ([@addaleax](https://github.com/addaleax)) +* **Bartosz Sosnowski** ([@bzoz](https://github.com/bzoz)) +* **Ben Noordhuis** ([@bnoordhuis](https://github.com/bnoordhuis)) + - GPG key: D77B 1E34 243F BAF0 5F8E 9CC3 4F55 C8C8 46AB 89B9 (pubkey-bnoordhuis) +* **Bert Belder** ([@piscisaureus](https://github.com/piscisaureus)) +* **Colin Ihrig** ([@cjihrig](https://github.com/cjihrig)) + - GPG key: 94AE 3667 5C46 4D64 BAFA 68DD 7434 390B DBE9 B9C5 (pubkey-cjihrig) + - GPG key: 5735 3E0D BDAA A7E8 39B6 6A1A FF47 D5E4 AD8B 4FDC (pubkey-cjihrig-kb) +* **Fedor Indutny** ([@indutny](https://github.com/indutny)) + - GPG key: AF2E EA41 EC34 47BF DD86 FED9 D706 3CCE 19B7 E890 (pubkey-indutny) +* **Imran Iqbal** ([@imran-iq](https://github.com/imran-iq)) + - GPG key: 9DFE AA5F 481B BF77 2D90 03CE D592 4925 2F8E C41A (pubkey-iwuzhere) +* **Jameson Nash** ([@vtjnash](https://github.com/vtjnash)) + - GPG key: AEAD 0A4B 6867 6775 1A0E 4AEF 34A2 5FB1 2824 6514 (pubkey-vtjnash) +* **John Barboza** ([@jbarz](https://github.com/jbarz)) +* **Kaoru Takanashi** ([@erw7](https://github.com/erw7)) + - GPG Key: 5804 F999 8A92 2AFB A398 47A0 7183 5090 6134 887F (pubkey-erw7) +* **Richard Lau** ([@richardlau](https://github.com/richardlau)) + - GPG key: C82F A3AE 1CBE DC6B E46B 9360 C43C EC45 C17A B93C (pubkey-richardlau) +* **Santiago Gimeno** ([@santigimeno](https://github.com/santigimeno)) + - GPG key: 612F 0EAD 9401 6223 79DF 4402 F28C 3C8D A33C 03BE (pubkey-santigimeno) +* **Saúl Ibarra Corretgé** ([@saghul](https://github.com/saghul)) + - GPG key: FDF5 1936 4458 319F A823 3DC9 410E 5553 AE9B C059 (pubkey-saghul) + +## Storing a maintainer key in Git + +It's quite handy to store a maintainer's signature as a git blob, and have +that object tagged and signed with such key. + +Export your public key: + + $ gpg --armor --export saghul@gmail.com > saghul.asc + +Store it as a blob on the repo: + + $ git hash-object -w saghul.asc + +The previous command returns a hash, copy it. For the sake of this explanation, +we'll assume it's 'abcd1234'. Storing the blob in git is not enough, it could +be garbage collected since nothing references it, so we'll create a tag for it: + + $ git tag -s pubkey-saghul abcd1234 + +Commit the changes and push: + + $ git push origin pubkey-saghul diff --git a/external/src/libuv/Makefile.am b/external/src/libuv/Makefile.am new file mode 100644 index 0000000..5830003 --- /dev/null +++ b/external/src/libuv/Makefile.am @@ -0,0 +1,549 @@ +# Copyright (c) 2013, Ben Noordhuis +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +ACLOCAL_AMFLAGS = -I m4 + +AM_CPPFLAGS = -I$(top_srcdir)/include \ + -I$(top_srcdir)/src + +include_HEADERS=include/uv.h + +uvincludedir = $(includedir)/uv +uvinclude_HEADERS = include/uv/errno.h \ + include/uv/threadpool.h \ + include/uv/version.h + +CLEANFILES = + +lib_LTLIBRARIES = libuv.la +libuv_la_CFLAGS = @CFLAGS@ +libuv_la_LDFLAGS = -no-undefined -version-info 1:0:0 +libuv_la_SOURCES = src/fs-poll.c \ + src/heap-inl.h \ + src/idna.c \ + src/idna.h \ + src/inet.c \ + src/queue.h \ + src/random.c \ + src/strscpy.c \ + src/strscpy.h \ + src/threadpool.c \ + src/timer.c \ + src/uv-data-getter-setters.c \ + src/uv-common.c \ + src/uv-common.h \ + src/version.c + +if SUNOS +# Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers +# on other platforms complain that the argument is unused during compilation. +libuv_la_CFLAGS += -pthreads +endif + +if WINNT + +uvinclude_HEADERS += include/uv/win.h include/uv/tree.h +AM_CPPFLAGS += -I$(top_srcdir)/src/win \ + -DWIN32_LEAN_AND_MEAN \ + -D_WIN32_WINNT=0x0602 +libuv_la_SOURCES += src/win/async.c \ + src/win/atomicops-inl.h \ + src/win/core.c \ + src/win/detect-wakeup.c \ + src/win/dl.c \ + src/win/error.c \ + src/win/fs-event.c \ + src/win/fs.c \ + src/win/getaddrinfo.c \ + src/win/getnameinfo.c \ + src/win/handle.c \ + src/win/handle-inl.h \ + src/win/internal.h \ + src/win/loop-watcher.c \ + src/win/pipe.c \ + src/win/poll.c \ + src/win/process-stdio.c \ + src/win/process.c \ + src/win/req-inl.h \ + src/win/signal.c \ + src/win/stream.c \ + src/win/stream-inl.h \ + src/win/tcp.c \ + src/win/thread.c \ + src/win/tty.c \ + src/win/udp.c \ + src/win/util.c \ + src/win/winapi.c \ + src/win/winapi.h \ + src/win/winsock.c \ + src/win/winsock.h + +else # WINNT + +uvinclude_HEADERS += include/uv/unix.h +AM_CPPFLAGS += -I$(top_srcdir)/src/unix +libuv_la_SOURCES += src/unix/async.c \ + src/unix/atomic-ops.h \ + src/unix/core.c \ + src/unix/dl.c \ + src/unix/fs.c \ + src/unix/getaddrinfo.c \ + src/unix/getnameinfo.c \ + src/unix/internal.h \ + src/unix/loop-watcher.c \ + src/unix/loop.c \ + src/unix/pipe.c \ + src/unix/poll.c \ + src/unix/process.c \ + src/unix/random-devurandom.c \ + src/unix/signal.c \ + src/unix/spinlock.h \ + src/unix/stream.c \ + src/unix/tcp.c \ + src/unix/thread.c \ + src/unix/tty.c \ + src/unix/udp.c + +endif # WINNT + +EXTRA_DIST = test/fixtures/empty_file \ + test/fixtures/load_error.node \ + test/fixtures/lorem_ipsum.txt \ + include \ + docs \ + img \ + CONTRIBUTING.md \ + LICENSE \ + README.md + + + +TESTS = test/run-tests +check_PROGRAMS = test/run-tests +test_run_tests_CFLAGS = + +if SUNOS +# Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers +# on other platforms complain that the argument is unused during compilation. +test_run_tests_CFLAGS += -pthreads +endif + +test_run_tests_LDFLAGS = +test_run_tests_SOURCES = test/blackhole-server.c \ + test/dns-server.c \ + test/echo-server.c \ + test/run-tests.c \ + test/runner.c \ + test/runner.h \ + test/task.h \ + test/test-active.c \ + test/test-async.c \ + test/test-async-null-cb.c \ + test/test-barrier.c \ + test/test-callback-order.c \ + test/test-callback-stack.c \ + test/test-close-fd.c \ + test/test-close-order.c \ + test/test-condvar.c \ + test/test-connect-unspecified.c \ + test/test-connection-fail.c \ + test/test-cwd-and-chdir.c \ + test/test-default-loop-close.c \ + test/test-delayed-accept.c \ + test/test-dlerror.c \ + test/test-eintr-handling.c \ + test/test-embed.c \ + test/test-emfile.c \ + test/test-env-vars.c \ + test/test-error.c \ + test/test-fail-always.c \ + test/test-fs-copyfile.c \ + test/test-fs-event.c \ + test/test-fs-poll.c \ + test/test-fs.c \ + test/test-fs-readdir.c \ + test/test-fs-fd-hash.c \ + test/test-fs-open-flags.c \ + test/test-fork.c \ + test/test-getters-setters.c \ + test/test-get-currentexe.c \ + test/test-get-loadavg.c \ + test/test-get-memory.c \ + test/test-get-passwd.c \ + test/test-getaddrinfo.c \ + test/test-gethostname.c \ + test/test-getnameinfo.c \ + test/test-getsockname.c \ + test/test-gettimeofday.c \ + test/test-handle-fileno.c \ + test/test-homedir.c \ + test/test-hrtime.c \ + test/test-idle.c \ + test/test-idna.c \ + test/test-ip4-addr.c \ + test/test-ip6-addr.c \ + test/test-ipc-heavy-traffic-deadlock-bug.c \ + test/test-ipc-send-recv.c \ + test/test-ipc.c \ + test/test-list.h \ + test/test-loop-handles.c \ + test/test-loop-alive.c \ + test/test-loop-close.c \ + test/test-loop-stop.c \ + test/test-loop-time.c \ + test/test-loop-configure.c \ + test/test-metrics.c \ + test/test-multiple-listen.c \ + test/test-mutexes.c \ + test/test-not-readable-nor-writable-on-read-error.c \ + test/test-not-readable-on-eof.c \ + test/test-not-writable-after-shutdown.c \ + test/test-osx-select.c \ + test/test-pass-always.c \ + test/test-ping-pong.c \ + test/test-pipe-bind-error.c \ + test/test-pipe-connect-error.c \ + test/test-pipe-connect-multiple.c \ + test/test-pipe-connect-prepare.c \ + test/test-pipe-getsockname.c \ + test/test-pipe-pending-instances.c \ + test/test-pipe-sendmsg.c \ + test/test-pipe-server-close.c \ + test/test-pipe-close-stdout-read-stdin.c \ + test/test-pipe-set-non-blocking.c \ + test/test-pipe-set-fchmod.c \ + test/test-platform-output.c \ + test/test-poll.c \ + test/test-poll-close.c \ + test/test-poll-close-doesnt-corrupt-stack.c \ + test/test-poll-closesocket.c \ + test/test-poll-multiple-handles.c \ + test/test-poll-oob.c \ + test/test-process-priority.c \ + test/test-process-title.c \ + test/test-process-title-threadsafe.c \ + test/test-queue-foreach-delete.c \ + test/test-random.c \ + test/test-ref.c \ + test/test-run-nowait.c \ + test/test-run-once.c \ + test/test-semaphore.c \ + test/test-shutdown-close.c \ + test/test-shutdown-eof.c \ + test/test-shutdown-simultaneous.c \ + test/test-shutdown-twice.c \ + test/test-signal-multiple-loops.c \ + test/test-signal-pending-on-close.c \ + test/test-signal.c \ + test/test-socket-buffer-size.c \ + test/test-spawn.c \ + test/test-stdio-over-pipes.c \ + test/test-strscpy.c \ + test/test-tcp-alloc-cb-fail.c \ + test/test-tcp-bind-error.c \ + test/test-tcp-bind6-error.c \ + test/test-tcp-close-accept.c \ + test/test-tcp-close-while-connecting.c \ + test/test-tcp-close.c \ + test/test-tcp-close-reset.c \ + test/test-tcp-create-socket-early.c \ + test/test-tcp-connect-error-after-write.c \ + test/test-tcp-connect-error.c \ + test/test-tcp-connect-timeout.c \ + test/test-tcp-connect6-error.c \ + test/test-tcp-flags.c \ + test/test-tcp-open.c \ + test/test-tcp-read-stop.c \ + test/test-tcp-read-stop-start.c \ + test/test-tcp-shutdown-after-write.c \ + test/test-tcp-unexpected-read.c \ + test/test-tcp-oob.c \ + test/test-tcp-write-to-half-open-connection.c \ + test/test-tcp-write-after-connect.c \ + test/test-tcp-writealot.c \ + test/test-tcp-write-fail.c \ + test/test-tcp-try-write.c \ + test/test-tcp-try-write-error.c \ + test/test-tcp-write-queue-order.c \ + test/test-test-macros.c \ + test/test-thread-equal.c \ + test/test-thread.c \ + test/test-threadpool-cancel.c \ + test/test-threadpool.c \ + test/test-timer-again.c \ + test/test-timer-from-check.c \ + test/test-timer.c \ + test/test-tmpdir.c \ + test/test-tty-duplicate-key.c \ + test/test-tty-escape-sequence-processing.c \ + test/test-tty.c \ + test/test-udp-alloc-cb-fail.c \ + test/test-udp-bind.c \ + test/test-udp-connect.c \ + test/test-udp-create-socket-early.c \ + test/test-udp-dgram-too-big.c \ + test/test-udp-ipv6.c \ + test/test-udp-mmsg.c \ + test/test-udp-multicast-interface.c \ + test/test-udp-multicast-interface6.c \ + test/test-udp-multicast-join.c \ + test/test-udp-multicast-join6.c \ + test/test-udp-multicast-ttl.c \ + test/test-udp-open.c \ + test/test-udp-options.c \ + test/test-udp-send-and-recv.c \ + test/test-udp-send-hang-loop.c \ + test/test-udp-send-immediate.c \ + test/test-udp-sendmmsg-error.c \ + test/test-udp-send-unreachable.c \ + test/test-udp-try-send.c \ + test/test-uname.c \ + test/test-walk-handles.c \ + test/test-watcher-cross-stop.c +test_run_tests_LDADD = libuv.la + +if WINNT +test_run_tests_SOURCES += test/runner-win.c \ + test/runner-win.h +else +test_run_tests_SOURCES += test/runner-unix.c \ + test/runner-unix.h +endif + +if AIX +test_run_tests_CFLAGS += -D_ALL_SOURCE \ + -D_XOPEN_SOURCE=500 \ + -D_LINUX_SOURCE_COMPAT +endif + +if OS400 +test_run_tests_CFLAGS += -D_ALL_SOURCE \ + -D_XOPEN_SOURCE=500 \ + -D_LINUX_SOURCE_COMPAT +endif + +if HAIKU +test_run_tests_CFLAGS += -D_BSD_SOURCE +endif + +if LINUX +test_run_tests_CFLAGS += -D_GNU_SOURCE +endif + +if SUNOS +test_run_tests_CFLAGS += -D__EXTENSIONS__ \ + -D_XOPEN_SOURCE=500 \ + -D_REENTRANT +endif + +if OS390 +test_run_tests_CFLAGS += -D_ISOC99_SOURCE \ + -D_UNIX03_THREADS \ + -D_UNIX03_SOURCE \ + -D_OPEN_SYS_IF_EXT=1 \ + -D_OPEN_SYS_SOCK_IPV6 \ + -D_OPEN_MSGQ_EXT \ + -D_XOPEN_SOURCE_EXTENDED \ + -D_ALL_SOURCE \ + -D_LARGE_TIME_API \ + -D_OPEN_SYS_FILE_EXT \ + -DPATH_MAX=255 \ + -qCHARS=signed \ + -qXPLINK \ + -qFLOAT=IEEE +endif + +if AIX +libuv_la_CFLAGS += -D_ALL_SOURCE \ + -D_XOPEN_SOURCE=500 \ + -D_LINUX_SOURCE_COMPAT \ + -D_THREAD_SAFE \ + -DHAVE_SYS_AHAFS_EVPRODS_H +uvinclude_HEADERS += include/uv/aix.h +libuv_la_SOURCES += src/unix/aix.c src/unix/aix-common.c +endif + +if OS400 +libuv_la_CFLAGS += -D_ALL_SOURCE \ + -D_XOPEN_SOURCE=500 \ + -D_LINUX_SOURCE_COMPAT \ + -D_THREAD_SAFE +uvinclude_HEADERS += include/uv/posix.h +libuv_la_SOURCES += src/unix/aix-common.c \ + src/unix/ibmi.c \ + src/unix/posix-poll.c \ + src/unix/no-fsevents.c +endif + +if ANDROID +uvinclude_HEADERS += include/uv/android-ifaddrs.h +libuv_la_CFLAGS += -D_GNU_SOURCE +libuv_la_SOURCES += src/unix/android-ifaddrs.c \ + src/unix/pthread-fixes.c \ + src/unix/random-getrandom.c \ + src/unix/random-sysctl-linux.c \ + src/unix/epoll.c +endif + +if CYGWIN +uvinclude_HEADERS += include/uv/posix.h +libuv_la_CFLAGS += -D_GNU_SOURCE +libuv_la_SOURCES += src/unix/cygwin.c \ + src/unix/bsd-ifaddrs.c \ + src/unix/no-fsevents.c \ + src/unix/no-proctitle.c \ + src/unix/posix-hrtime.c \ + src/unix/posix-poll.c \ + src/unix/procfs-exepath.c \ + src/unix/sysinfo-loadavg.c \ + src/unix/sysinfo-memory.c +endif + +if DARWIN +uvinclude_HEADERS += include/uv/darwin.h +libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1 +libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1 +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/darwin-proctitle.c \ + src/unix/darwin-stub.h \ + src/unix/darwin.c \ + src/unix/fsevents.c \ + src/unix/kqueue.c \ + src/unix/proctitle.c \ + src/unix/random-getentropy.c +test_run_tests_LDFLAGS += -lutil +endif + +if DRAGONFLY +uvinclude_HEADERS += include/uv/bsd.h +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/bsd-proctitle.c \ + src/unix/freebsd.c \ + src/unix/kqueue.c \ + src/unix/posix-hrtime.c +test_run_tests_LDFLAGS += -lutil +endif + +if FREEBSD +uvinclude_HEADERS += include/uv/bsd.h +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/bsd-proctitle.c \ + src/unix/freebsd.c \ + src/unix/kqueue.c \ + src/unix/posix-hrtime.c \ + src/unix/random-getrandom.c +test_run_tests_LDFLAGS += -lutil +endif + +if HAIKU +uvinclude_HEADERS += include/uv/posix.h +libuv_la_CFLAGS += -D_BSD_SOURCE +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/haiku.c \ + src/unix/no-fsevents.c \ + src/unix/no-proctitle.c \ + src/unix/posix-hrtime.c \ + src/unix/posix-poll.c +endif + +if HURD +uvinclude_HEADERS += include/uv/posix.h +libuv_la_SOURCES += src/unix/no-fsevents.c \ + src/unix/posix-hrtime.c \ + src/unix/posix-poll.c +endif + +if LINUX +uvinclude_HEADERS += include/uv/linux.h +libuv_la_CFLAGS += -D_GNU_SOURCE +libuv_la_SOURCES += src/unix/linux-core.c \ + src/unix/linux-inotify.c \ + src/unix/linux-syscalls.c \ + src/unix/linux-syscalls.h \ + src/unix/procfs-exepath.c \ + src/unix/proctitle.c \ + src/unix/random-getrandom.c \ + src/unix/random-sysctl-linux.c \ + src/unix/epoll.c +test_run_tests_LDFLAGS += -lutil +endif + +if MSYS +libuv_la_CFLAGS += -D_GNU_SOURCE +libuv_la_SOURCES += src/unix/cygwin.c \ + src/unix/bsd-ifaddrs.c \ + src/unix/no-fsevents.c \ + src/unix/no-proctitle.c \ + src/unix/posix-hrtime.c \ + src/unix/posix-poll.c \ + src/unix/procfs-exepath.c \ + src/unix/sysinfo-loadavg.c \ + src/unix/sysinfo-memory.c +endif + +if NETBSD +uvinclude_HEADERS += include/uv/bsd.h +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/bsd-proctitle.c \ + src/unix/kqueue.c \ + src/unix/netbsd.c \ + src/unix/posix-hrtime.c +test_run_tests_LDFLAGS += -lutil +endif + +if OPENBSD +uvinclude_HEADERS += include/uv/bsd.h +libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ + src/unix/bsd-proctitle.c \ + src/unix/kqueue.c \ + src/unix/openbsd.c \ + src/unix/posix-hrtime.c \ + src/unix/random-getentropy.c +test_run_tests_LDFLAGS += -lutil +endif + +if SUNOS +uvinclude_HEADERS += include/uv/sunos.h +libuv_la_CFLAGS += -D__EXTENSIONS__ \ + -D_XOPEN_SOURCE=500 \ + -D_REENTRANT +libuv_la_SOURCES += src/unix/no-proctitle.c \ + src/unix/sunos.c +endif + +if OS390 +libuv_la_CFLAGS += -D_UNIX03_THREADS \ + -D_UNIX03_SOURCE \ + -D_OPEN_SYS_IF_EXT=1 \ + -D_OPEN_MSGQ_EXT \ + -D_XOPEN_SOURCE_EXTENDED \ + -D_ALL_SOURCE \ + -D_LARGE_TIME_API \ + -D_OPEN_SYS_SOCK_EXT3 \ + -D_OPEN_SYS_SOCK_IPV6 \ + -D_OPEN_SYS_FILE_EXT \ + -DUV_PLATFORM_SEM_T=int \ + -DPATH_MAX=255 \ + -qCHARS=signed \ + -qXPLINK \ + -qFLOAT=IEEE +libuv_la_LDFLAGS += -qXPLINK +libuv_la_SOURCES += src/unix/pthread-fixes.c \ + src/unix/os390.c \ + src/unix/os390-syscalls.c \ + src/unix/proctitle.c +endif + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = @PACKAGE_NAME@.pc diff --git a/external/src/libuv/README.md b/external/src/libuv/README.md new file mode 100644 index 0000000..a9a8a9d --- /dev/null +++ b/external/src/libuv/README.md @@ -0,0 +1,333 @@ +![libuv][libuv_banner] + +## Overview + +libuv is a multi-platform support library with a focus on asynchronous I/O. It +was primarily developed for use by [Node.js][], but it's also +used by [Luvit](http://luvit.io/), [Julia](http://julialang.org/), +[pyuv](https://github.com/saghul/pyuv), and [others](https://github.com/libuv/libuv/blob/v1.x/LINKS.md). + +## Feature highlights + + * Full-featured event loop backed by epoll, kqueue, IOCP, event ports. + + * Asynchronous TCP and UDP sockets + + * Asynchronous DNS resolution + + * Asynchronous file and file system operations + + * File system events + + * ANSI escape code controlled TTY + + * IPC with socket sharing, using Unix domain sockets or named pipes (Windows) + + * Child processes + + * Thread pool + + * Signal handling + + * High resolution clock + + * Threading and synchronization primitives + +## Versioning + +Starting with version 1.0.0 libuv follows the [semantic versioning](http://semver.org/) +scheme. The API change and backwards compatibility rules are those indicated by +SemVer. libuv will keep a stable ABI across major releases. + +The ABI/API changes can be tracked [here](http://abi-laboratory.pro/tracker/timeline/libuv/). + +## Licensing + +libuv is licensed under the MIT license. Check the [LICENSE file](LICENSE). +The documentation is licensed under the CC BY 4.0 license. Check the [LICENSE-docs file](LICENSE-docs). + +## Community + + * [Support](https://github.com/libuv/libuv/discussions) + * [Mailing list](http://groups.google.com/group/libuv) + +## Documentation + +### Official documentation + +Located in the docs/ subdirectory. It uses the [Sphinx](http://sphinx-doc.org/) +framework, which makes it possible to build the documentation in multiple +formats. + +Show different supported building options: + +```bash +$ make help +``` + +Build documentation as HTML: + +```bash +$ make html +``` + +Build documentation as HTML and live reload it when it changes (this requires +sphinx-autobuild to be installed and is only supported on Unix): + +```bash +$ make livehtml +``` + +Build documentation as man pages: + +```bash +$ make man +``` + +Build documentation as ePub: + +```bash +$ make epub +``` + +NOTE: Windows users need to use make.bat instead of plain 'make'. + +Documentation can be browsed online [here](http://docs.libuv.org). + +The [tests and benchmarks](https://github.com/libuv/libuv/tree/master/test) +also serve as API specification and usage examples. + +### Other resources + + * [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4) + — High-level introductory talk about libuv. + * [libuv-dox](https://github.com/thlorenz/libuv-dox) + — Documenting types and methods of libuv, mostly by reading uv.h. + * [learnuv](https://github.com/thlorenz/learnuv) + — Learn uv for fun and profit, a self guided workshop to libuv. + +These resources are not handled by libuv maintainers and might be out of +date. Please verify it before opening new issues. + +## Downloading + +libuv can be downloaded either from the +[GitHub repository](https://github.com/libuv/libuv) +or from the [downloads site](http://dist.libuv.org/dist/). + +Before verifying the git tags or signature files, importing the relevant keys +is necessary. Key IDs are listed in the +[MAINTAINERS](https://github.com/libuv/libuv/blob/master/MAINTAINERS.md) +file, but are also available as git blob objects for easier use. + +Importing a key the usual way: + +```bash +$ gpg --keyserver pool.sks-keyservers.net --recv-keys AE9BC059 +``` + +Importing a key from a git blob object: + +```bash +$ git show pubkey-saghul | gpg --import +``` + +### Verifying releases + +Git tags are signed with the developer's key, they can be verified as follows: + +```bash +$ git verify-tag v1.6.1 +``` + +Starting with libuv 1.7.0, the tarballs stored in the +[downloads site](http://dist.libuv.org/dist/) are signed and an accompanying +signature file sit alongside each. Once both the release tarball and the +signature file are downloaded, the file can be verified as follows: + +```bash +$ gpg --verify libuv-1.7.0.tar.gz.sign +``` + +## Build Instructions + +For UNIX-like platforms, including macOS, there are two build methods: +autotools or [CMake][]. + +For Windows, [CMake][] is the only supported build method and has the +following prerequisites: + +
+ +* One of: + * [Visual C++ Build Tools][] + * [Visual Studio 2015 Update 3][], all editions + including the Community edition (remember to select + "Common Tools for Visual C++ 2015" feature during installation). + * [Visual Studio 2017][], any edition (including the Build Tools SKU). + **Required Components:** "MSbuild", "VC++ 2017 v141 toolset" and one of the + Windows SDKs (10 or 8.1). +* Basic Unix tools required for some tests, + [Git for Windows][] includes Git Bash + and tools which can be included in the global `PATH`. + +
+ +To build with autotools: + +```bash +$ sh autogen.sh +$ ./configure +$ make +$ make check +$ make install +``` + +To build with [CMake][]: + +```bash +$ mkdir -p build + +$ (cd build && cmake .. -DBUILD_TESTING=ON) # generate project with tests +$ cmake --build build # add `-j ` with cmake >= 3.12 + +# Run tests: +$ (cd build && ctest -C Debug --output-on-failure) + +# Or manually run tests: +$ build/uv_run_tests # shared library build +$ build/uv_run_tests_a # static library build +``` + +To cross-compile with [CMake][] (unsupported but generally works): + +```bash +$ cmake ../.. \ + -DCMAKE_SYSTEM_NAME=Windows \ + -DCMAKE_SYSTEM_VERSION=6.1 \ + -DCMAKE_C_COMPILER=i686-w64-mingw32-gcc +``` + +### Install with Homebrew + +```bash +$ brew install --HEAD libuv +``` + +Note to OS X users: + +Make sure that you specify the architecture you wish to build for in the +"ARCHS" flag. You can specify more than one by delimiting with a space +(e.g. "x86_64 i386"). + +### Running tests + +Some tests are timing sensitive. Relaxing test timeouts may be necessary +on slow or overloaded machines: + +```bash +$ env UV_TEST_TIMEOUT_MULTIPLIER=2 build/uv_run_tests # 10s instead of 5s +``` + +#### Run one test + +The list of all tests is in `test/test-list.h`. + +This invocation will cause the test driver to fork and execute `TEST_NAME` in +a child process: + +```bash +$ build/uv_run_tests_a TEST_NAME +``` + +This invocation will cause the test driver to execute the test in +the same process: + +```bash +$ build/uv_run_tests_a TEST_NAME TEST_NAME +``` + +#### Debugging tools + +When running the test from within the test driver process +(`build/uv_run_tests_a TEST_NAME TEST_NAME`), tools like gdb and valgrind +work normally. + +When running the test from a child of the test driver process +(`build/uv_run_tests_a TEST_NAME`), use these tools in a fork-aware manner. + +##### Fork-aware gdb + +Use the [follow-fork-mode](https://sourceware.org/gdb/onlinedocs/gdb/Forks.html) setting: + +``` +$ gdb --args build/uv_run_tests_a TEST_NAME + +(gdb) set follow-fork-mode child +... +``` + +##### Fork-aware valgrind + +Use the `--trace-children=yes` parameter: + +```bash +$ valgrind --trace-children=yes -v --tool=memcheck --leak-check=full --track-origins=yes --leak-resolution=high --show-reachable=yes --log-file=memcheck-%p.log build/uv_run_tests_a TEST_NAME +``` + +### Running benchmarks + +See the section on running tests. +The benchmark driver is `./uv_run_benchmarks_a` and the benchmarks are +listed in `test/benchmark-list.h`. + +## Supported Platforms + +Check the [SUPPORTED_PLATFORMS file](SUPPORTED_PLATFORMS.md). + +### `-fno-strict-aliasing` + +It is recommended to turn on the `-fno-strict-aliasing` compiler flag in +projects that use libuv. The use of ad hoc "inheritance" in the libuv API +may not be safe in the presence of compiler optimizations that depend on +strict aliasing. + +MSVC does not have an equivalent flag but it also does not appear to need it +at the time of writing (December 2019.) + +### AIX Notes + +AIX compilation using IBM XL C/C++ requires version 12.1 or greater. + +AIX support for filesystem events requires the non-default IBM `bos.ahafs` +package to be installed. This package provides the AIX Event Infrastructure +that is detected by `autoconf`. +[IBM documentation](http://www.ibm.com/developerworks/aix/library/au-aix_event_infrastructure/) +describes the package in more detail. + +### z/OS Notes + +z/OS compilation requires [ZOSLIB](https://github.com/ibmruntimes/zoslib) to be installed. When building with [CMake][], use the flag `-DZOSLIB_DIR` to specify the path to [ZOSLIB](https://github.com/ibmruntimes/zoslib): + +```bash +$ (cd build && cmake .. -DBUILD_TESTING=ON -DZOSLIB_DIR=/path/to/zoslib) +$ cmake --build build +``` + +z/OS creates System V semaphores and message queues. These persist on the system +after the process terminates unless the event loop is closed. + +Use the `ipcrm` command to manually clear up System V resources. + +## Patches + +See the [guidelines for contributing][]. + +[CMake]: https://cmake.org/ +[node.js]: http://nodejs.org/ +[guidelines for contributing]: https://github.com/libuv/libuv/blob/master/CONTRIBUTING.md +[libuv_banner]: https://raw.githubusercontent.com/libuv/libuv/master/img/banner.png +[Visual C++ Build Tools]: https://visualstudio.microsoft.com/visual-cpp-build-tools/ +[Visual Studio 2015 Update 3]: https://www.visualstudio.com/vs/older-downloads/ +[Visual Studio 2017]: https://www.visualstudio.com/downloads/ +[Git for Windows]: http://git-scm.com/download/win diff --git a/external/src/libuv/SUPPORTED_PLATFORMS.md b/external/src/libuv/SUPPORTED_PLATFORMS.md new file mode 100644 index 0000000..30e0ea6 --- /dev/null +++ b/external/src/libuv/SUPPORTED_PLATFORMS.md @@ -0,0 +1,69 @@ +# Supported platforms + +| System | Support type | Supported versions | Notes | +|---|---|---|---| +| GNU/Linux | Tier 1 | Linux >= 2.6.32 with glibc >= 2.12 | | +| macOS | Tier 1 | macOS >= 10.7 | | +| Windows | Tier 1 | >= Windows 8 | VS 2015 and later are supported | +| FreeBSD | Tier 1 | >= 10 | | +| AIX | Tier 2 | >= 6 | Maintainers: @libuv/aix | +| IBM i | Tier 2 | >= IBM i 7.2 | Maintainers: @libuv/ibmi | +| z/OS | Tier 2 | >= V2R2 | Maintainers: @libuv/zos | +| Linux with musl | Tier 2 | musl >= 1.0 | | +| SmartOS | Tier 2 | >= 14.4 | Maintainers: @libuv/smartos | +| Android | Tier 3 | NDK >= r15b | | +| MinGW | Tier 3 | MinGW32 and MinGW-w64 | | +| SunOS | Tier 3 | Solaris 121 and later | | +| Other | Tier 3 | N/A | | + +## Support types + +* **Tier 1**: Officially supported and tested with CI. Any contributed patch + MUST NOT break such systems. These are supported by @libuv/collaborators. + +* **Tier 2**: Officially supported, but not necessarily tested with CI. These + systems are maintained to the best of @libuv/collaborators ability, + without being a top priority. + +* **Tier 3**: Community maintained. These systems may inadvertently break and the + community and interested parties are expected to help with the maintenance. + +## Adding support for a new platform + +**IMPORTANT**: Before attempting to add support for a new platform please open +an issue about it for discussion. + +### Unix + +I/O handling is abstracted by an internal `uv__io_t` handle. The new platform +will need to implement some of the functions, the prototypes are in +``src/unix/internal.h``. + +If the new platform requires extra fields for any handle structure, create a +new include file in ``include/`` with the name ``uv-theplatform.h`` and add +the appropriate defines there. + +All functionality related to the new platform must be implemented in its own +file inside ``src/unix/`` unless it's already done in a common file, in which +case adding an `ifdef` is fine. + +Two build systems are supported: autotools and cmake. Ideally both need to be +supported, but if one of the two does not support the new platform it can be +left out. + +### Windows + +Windows is treated as a single platform, so adding support for a new platform +would mean adding support for a new version. + +Compilation and runtime must succeed for the minimum supported version. If a +new API is to be used, it must be done optionally, only in supported versions. + +### Common + +Some common notes when adding support for new platforms: + +* Generally libuv tries to avoid compile time checks. Do not add any to the + autotools based build system or use version checking macros. + Dynamically load functions and symbols if they are not supported by the + minimum supported version. diff --git a/external/src/libuv/autogen.sh b/external/src/libuv/autogen.sh new file mode 100644 index 0000000..271c2ee --- /dev/null +++ b/external/src/libuv/autogen.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +# Copyright (c) 2013, Ben Noordhuis +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +cd `dirname "$0"` + +if [ "$LIBTOOLIZE" = "" ] && [ "`uname`" = "Darwin" ]; then + LIBTOOLIZE=glibtoolize +fi + +ACLOCAL=${ACLOCAL:-aclocal} +AUTOCONF=${AUTOCONF:-autoconf} +AUTOMAKE=${AUTOMAKE:-automake} +LIBTOOLIZE=${LIBTOOLIZE:-libtoolize} + +automake_version=`"$AUTOMAKE" --version | head -n 1 | sed 's/[^.0-9]//g'` +automake_version_major=`echo "$automake_version" | cut -d. -f1` +automake_version_minor=`echo "$automake_version" | cut -d. -f2` + +UV_EXTRA_AUTOMAKE_FLAGS= +if test "$automake_version_major" -gt 1 || \ + test "$automake_version_major" -eq 1 && \ + test "$automake_version_minor" -gt 11; then + # serial-tests is available in v1.12 and newer. + UV_EXTRA_AUTOMAKE_FLAGS="$UV_EXTRA_AUTOMAKE_FLAGS serial-tests" +fi +echo "m4_define([UV_EXTRA_AUTOMAKE_FLAGS], [$UV_EXTRA_AUTOMAKE_FLAGS])" \ + > m4/libuv-extra-automake-flags.m4 + +set -ex +"$LIBTOOLIZE" --copy +"$ACLOCAL" -I m4 +"$AUTOCONF" +"$AUTOMAKE" --add-missing --copy diff --git a/external/src/libuv/configure.ac b/external/src/libuv/configure.ac new file mode 100644 index 0000000..1fbb5c8 --- /dev/null +++ b/external/src/libuv/configure.ac @@ -0,0 +1,88 @@ +# Copyright (c) 2013, Ben Noordhuis +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +AC_PREREQ(2.57) +AC_INIT([libuv], [1.42.0], [https://github.com/libuv/libuv/issues]) +AC_CONFIG_MACRO_DIR([m4]) +m4_include([m4/libuv-extra-automake-flags.m4]) +m4_include([m4/as_case.m4]) +m4_include([m4/libuv-check-flags.m4]) +AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS) +AC_CANONICAL_HOST +AC_ENABLE_SHARED +AC_ENABLE_STATIC +AC_PROG_CC +AM_PROG_CC_C_O + +CC_ATTRIBUTE_VISIBILITY([default], [ + CC_FLAG_VISIBILITY([CFLAGS="${CFLAGS} -fvisibility=hidden"]) +]) +CC_CHECK_CFLAGS_APPEND([-fno-strict-aliasing]) +CC_CHECK_CFLAGS_APPEND([-g]) +CC_CHECK_CFLAGS_APPEND([-std=gnu89]) +CC_CHECK_CFLAGS_APPEND([-Wall]) +CC_CHECK_CFLAGS_APPEND([-Wextra]) +CC_CHECK_CFLAGS_APPEND([-Wno-long-long]) +CC_CHECK_CFLAGS_APPEND([-Wno-unused-parameter]) +CC_CHECK_CFLAGS_APPEND([-Wstrict-prototypes]) +# AM_PROG_AR is not available in automake v0.11 but it's essential in v0.12. +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) +# autoconf complains if AC_PROG_LIBTOOL precedes AM_PROG_AR. +AC_PROG_LIBTOOL +m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +LT_INIT +AX_PTHREAD([ + LIBS="$LIBS $PTHREAD_LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +]) +AC_SEARCH_LIBS([dlopen], [dl]) +AC_SEARCH_LIBS([kstat_lookup], [kstat]) +AC_SEARCH_LIBS([gethostbyname], [nsl]) +AC_SEARCH_LIBS([perfstat_cpu], [perfstat]) +AC_SEARCH_LIBS([clock_gettime], [rt]) +AC_SEARCH_LIBS([sendfile], [sendfile]) +AC_SEARCH_LIBS([socket], [socket]) +AC_SYS_LARGEFILE +AM_CONDITIONAL([AIX], [AS_CASE([$host_os],[aix*], [true], [false])]) +AM_CONDITIONAL([ANDROID], [AS_CASE([$host_os],[linux-android*],[true], [false])]) +AM_CONDITIONAL([CYGWIN], [AS_CASE([$host_os],[cygwin*], [true], [false])]) +AM_CONDITIONAL([DARWIN], [AS_CASE([$host_os],[darwin*], [true], [false])]) +AM_CONDITIONAL([DRAGONFLY],[AS_CASE([$host_os],[dragonfly*], [true], [false])]) +AM_CONDITIONAL([FREEBSD], [AS_CASE([$host_os],[*freebsd*], [true], [false])]) +AM_CONDITIONAL([HAIKU], [AS_CASE([$host_os],[haiku], [true], [false])]) +AM_CONDITIONAL([HURD], [AS_CASE([$host_os],[gnu*], [true], [false])]) +AM_CONDITIONAL([LINUX], [AS_CASE([$host_os],[linux*], [true], [false])]) +AM_CONDITIONAL([MSYS], [AS_CASE([$host_os],[msys*], [true], [false])]) +AM_CONDITIONAL([NETBSD], [AS_CASE([$host_os],[netbsd*], [true], [false])]) +AM_CONDITIONAL([OPENBSD], [AS_CASE([$host_os],[openbsd*], [true], [false])]) +AM_CONDITIONAL([OS390], [AS_CASE([$host_os],[openedition*], [true], [false])]) +AM_CONDITIONAL([OS400], [AS_CASE([$host_os],[os400], [true], [false])]) +AM_CONDITIONAL([SUNOS], [AS_CASE([$host_os],[solaris*], [true], [false])]) +AM_CONDITIONAL([WINNT], [AS_CASE([$host_os],[mingw*], [true], [false])]) +AS_CASE([$host_os],[mingw*], [ + LIBS="$LIBS -lws2_32 -lpsapi -liphlpapi -lshell32 -luserenv -luser32" +]) +AS_CASE([$host_os], [netbsd*], [AC_CHECK_LIB([kvm], [kvm_open])]) +AS_CASE([$host_os], [kfreebsd*], [ + LIBS="$LIBS -lfreebsd-glue" +]) +AS_CASE([$host_os], [haiku], [ + LIBS="$LIBS -lnetwork" +]) +AC_CHECK_HEADERS([sys/ahafs_evProds.h]) +AC_CONFIG_FILES([Makefile libuv.pc]) +AC_CONFIG_LINKS([test/fixtures/empty_file:test/fixtures/empty_file]) +AC_CONFIG_LINKS([test/fixtures/load_error.node:test/fixtures/load_error.node]) +AC_CONFIG_LINKS([test/fixtures/lorem_ipsum.txt:test/fixtures/lorem_ipsum.txt]) +AC_OUTPUT diff --git a/external/src/libuv/docs/code/cgi/main.c b/external/src/libuv/docs/code/cgi/main.c new file mode 100644 index 0000000..d2e3426 --- /dev/null +++ b/external/src/libuv/docs/code/cgi/main.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include + +uv_loop_t *loop; +uv_process_t child_req; +uv_process_options_t options; + +void cleanup_handles(uv_process_t *req, int64_t exit_status, int term_signal) { + fprintf(stderr, "Process exited with status %" PRId64 ", signal %d\n", exit_status, term_signal); + uv_close((uv_handle_t*) req->data, NULL); + uv_close((uv_handle_t*) req, NULL); +} + +void invoke_cgi_script(uv_tcp_t *client) { + size_t size = 500; + char path[size]; + uv_exepath(path, &size); + strcpy(path + (strlen(path) - strlen("cgi")), "tick"); + + char* args[2]; + args[0] = path; + args[1] = NULL; + + /* ... finding the executable path and setting up arguments ... */ + + options.stdio_count = 3; + uv_stdio_container_t child_stdio[3]; + child_stdio[0].flags = UV_IGNORE; + child_stdio[1].flags = UV_INHERIT_STREAM; + child_stdio[1].data.stream = (uv_stream_t*) client; + child_stdio[2].flags = UV_IGNORE; + options.stdio = child_stdio; + + options.exit_cb = cleanup_handles; + options.file = args[0]; + options.args = args; + + // Set this so we can close the socket after the child process exits. + child_req.data = (void*) client; + int r; + if ((r = uv_spawn(loop, &child_req, &options))) { + fprintf(stderr, "%s\n", uv_strerror(r)); + return; + } +} + +void on_new_connection(uv_stream_t *server, int status) { + if (status == -1) { + // error! + return; + } + + uv_tcp_t *client = (uv_tcp_t*) malloc(sizeof(uv_tcp_t)); + uv_tcp_init(loop, client); + if (uv_accept(server, (uv_stream_t*) client) == 0) { + invoke_cgi_script(client); + } + else { + uv_close((uv_handle_t*) client, NULL); + } +} + +int main() { + loop = uv_default_loop(); + + uv_tcp_t server; + uv_tcp_init(loop, &server); + + struct sockaddr_in bind_addr; + uv_ip4_addr("0.0.0.0", 7000, &bind_addr); + uv_tcp_bind(&server, (const struct sockaddr *)&bind_addr, 0); + int r = uv_listen((uv_stream_t*) &server, 128, on_new_connection); + if (r) { + fprintf(stderr, "Listen error %s\n", uv_err_name(r)); + return 1; + } + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/cgi/tick.c b/external/src/libuv/docs/code/cgi/tick.c new file mode 100644 index 0000000..0b498ed --- /dev/null +++ b/external/src/libuv/docs/code/cgi/tick.c @@ -0,0 +1,13 @@ +#include +#include + +int main() { + int i; + for (i = 0; i < 10; i++) { + printf("tick\n"); + fflush(stdout); + sleep(1); + } + printf("BOOM!\n"); + return 0; +} diff --git a/external/src/libuv/docs/code/detach/main.c b/external/src/libuv/docs/code/detach/main.c new file mode 100644 index 0000000..3c88fff --- /dev/null +++ b/external/src/libuv/docs/code/detach/main.c @@ -0,0 +1,31 @@ +#include + +#include + +uv_loop_t *loop; +uv_process_t child_req; +uv_process_options_t options; + +int main() { + loop = uv_default_loop(); + + char* args[3]; + args[0] = "sleep"; + args[1] = "100"; + args[2] = NULL; + + options.exit_cb = NULL; + options.file = "sleep"; + options.args = args; + options.flags = UV_PROCESS_DETACHED; + + int r; + if ((r = uv_spawn(loop, &child_req, &options))) { + fprintf(stderr, "%s\n", uv_strerror(r)); + return 1; + } + fprintf(stderr, "Launched sleep with PID %d\n", child_req.pid); + uv_unref((uv_handle_t*) &child_req); + + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/dns/main.c b/external/src/libuv/docs/code/dns/main.c new file mode 100644 index 0000000..2d63f1a --- /dev/null +++ b/external/src/libuv/docs/code/dns/main.c @@ -0,0 +1,80 @@ +#include +#include +#include +#include + +uv_loop_t *loop; + +void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) { + buf->base = malloc(suggested_size); + buf->len = suggested_size; +} + +void on_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) { + if (nread < 0) { + if (nread != UV_EOF) + fprintf(stderr, "Read error %s\n", uv_err_name(nread)); + uv_close((uv_handle_t*) client, NULL); + free(buf->base); + free(client); + return; + } + + char *data = (char*) malloc(sizeof(char) * (nread+1)); + data[nread] = '\0'; + strncpy(data, buf->base, nread); + + fprintf(stderr, "%s", data); + free(data); + free(buf->base); +} + +void on_connect(uv_connect_t *req, int status) { + if (status < 0) { + fprintf(stderr, "connect failed error %s\n", uv_err_name(status)); + free(req); + return; + } + + uv_read_start((uv_stream_t*) req->handle, alloc_buffer, on_read); + free(req); +} + +void on_resolved(uv_getaddrinfo_t *resolver, int status, struct addrinfo *res) { + if (status < 0) { + fprintf(stderr, "getaddrinfo callback error %s\n", uv_err_name(status)); + return; + } + + char addr[17] = {'\0'}; + uv_ip4_name((struct sockaddr_in*) res->ai_addr, addr, 16); + fprintf(stderr, "%s\n", addr); + + uv_connect_t *connect_req = (uv_connect_t*) malloc(sizeof(uv_connect_t)); + uv_tcp_t *socket = (uv_tcp_t*) malloc(sizeof(uv_tcp_t)); + uv_tcp_init(loop, socket); + + uv_tcp_connect(connect_req, socket, (const struct sockaddr*) res->ai_addr, on_connect); + + uv_freeaddrinfo(res); +} + +int main() { + loop = uv_default_loop(); + + struct addrinfo hints; + hints.ai_family = PF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + hints.ai_flags = 0; + + uv_getaddrinfo_t resolver; + fprintf(stderr, "irc.libera.chat is... "); + int r = uv_getaddrinfo(loop, &resolver, on_resolved, "irc.libera.chat", "6667", &hints); + + if (r) { + fprintf(stderr, "getaddrinfo call error %s\n", uv_err_name(r)); + return 1; + } + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/helloworld/main.c b/external/src/libuv/docs/code/helloworld/main.c new file mode 100644 index 0000000..a31bf88 --- /dev/null +++ b/external/src/libuv/docs/code/helloworld/main.c @@ -0,0 +1,15 @@ +#include +#include +#include + +int main() { + uv_loop_t *loop = malloc(sizeof(uv_loop_t)); + uv_loop_init(loop); + + printf("Now quitting.\n"); + uv_run(loop, UV_RUN_DEFAULT); + + uv_loop_close(loop); + free(loop); + return 0; +} diff --git a/external/src/libuv/docs/code/idle-basic/main.c b/external/src/libuv/docs/code/idle-basic/main.c new file mode 100644 index 0000000..77ba31c --- /dev/null +++ b/external/src/libuv/docs/code/idle-basic/main.c @@ -0,0 +1,24 @@ +#include +#include + +int64_t counter = 0; + +void wait_for_a_while(uv_idle_t* handle) { + counter++; + + if (counter >= 10e6) + uv_idle_stop(handle); +} + +int main() { + uv_idle_t idler; + + uv_idle_init(uv_default_loop(), &idler); + uv_idle_start(&idler, wait_for_a_while); + + printf("Idling...\n"); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + uv_loop_close(uv_default_loop()); + return 0; +} diff --git a/external/src/libuv/docs/code/idle-compute/main.c b/external/src/libuv/docs/code/idle-compute/main.c new file mode 100644 index 0000000..ff44b69 --- /dev/null +++ b/external/src/libuv/docs/code/idle-compute/main.c @@ -0,0 +1,43 @@ +#include + +#include + +uv_loop_t *loop; +uv_fs_t stdin_watcher; +uv_idle_t idler; +char buffer[1024]; + +void crunch_away(uv_idle_t* handle) { + // Compute extra-terrestrial life + // fold proteins + // computer another digit of PI + // or similar + fprintf(stderr, "Computing PI...\n"); + // just to avoid overwhelming your terminal emulator + uv_idle_stop(handle); +} + +void on_type(uv_fs_t *req) { + if (stdin_watcher.result > 0) { + buffer[stdin_watcher.result] = '\0'; + printf("Typed %s\n", buffer); + + uv_buf_t buf = uv_buf_init(buffer, 1024); + uv_fs_read(loop, &stdin_watcher, 0, &buf, 1, -1, on_type); + uv_idle_start(&idler, crunch_away); + } + else if (stdin_watcher.result < 0) { + fprintf(stderr, "error opening file: %s\n", uv_strerror(req->result)); + } +} + +int main() { + loop = uv_default_loop(); + + uv_idle_init(loop, &idler); + + uv_buf_t buf = uv_buf_init(buffer, 1024); + uv_fs_read(loop, &stdin_watcher, 0, &buf, 1, -1, on_type); + uv_idle_start(&idler, crunch_away); + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/interfaces/main.c b/external/src/libuv/docs/code/interfaces/main.c new file mode 100644 index 0000000..cac12c2 --- /dev/null +++ b/external/src/libuv/docs/code/interfaces/main.c @@ -0,0 +1,33 @@ +#include +#include + +int main() { + char buf[512]; + uv_interface_address_t *info; + int count, i; + + uv_interface_addresses(&info, &count); + i = count; + + printf("Number of interfaces: %d\n", count); + while (i--) { + uv_interface_address_t interface = info[i]; + + printf("Name: %s\n", interface.name); + printf("Internal? %s\n", interface.is_internal ? "Yes" : "No"); + + if (interface.address.address4.sin_family == AF_INET) { + uv_ip4_name(&interface.address.address4, buf, sizeof(buf)); + printf("IPv4 address: %s\n", buf); + } + else if (interface.address.address4.sin_family == AF_INET6) { + uv_ip6_name(&interface.address.address6, buf, sizeof(buf)); + printf("IPv6 address: %s\n", buf); + } + + printf("\n"); + } + + uv_free_interface_addresses(info, count); + return 0; +} diff --git a/external/src/libuv/docs/code/locks/main.c b/external/src/libuv/docs/code/locks/main.c new file mode 100644 index 0000000..2b1f8ca --- /dev/null +++ b/external/src/libuv/docs/code/locks/main.c @@ -0,0 +1,57 @@ +#include +#include + +uv_barrier_t blocker; +uv_rwlock_t numlock; +int shared_num; + +void reader(void *n) +{ + int num = *(int *)n; + int i; + for (i = 0; i < 20; i++) { + uv_rwlock_rdlock(&numlock); + printf("Reader %d: acquired lock\n", num); + printf("Reader %d: shared num = %d\n", num, shared_num); + uv_rwlock_rdunlock(&numlock); + printf("Reader %d: released lock\n", num); + } + uv_barrier_wait(&blocker); +} + +void writer(void *n) +{ + int num = *(int *)n; + int i; + for (i = 0; i < 20; i++) { + uv_rwlock_wrlock(&numlock); + printf("Writer %d: acquired lock\n", num); + shared_num++; + printf("Writer %d: incremented shared num = %d\n", num, shared_num); + uv_rwlock_wrunlock(&numlock); + printf("Writer %d: released lock\n", num); + } + uv_barrier_wait(&blocker); +} + +int main() +{ + uv_barrier_init(&blocker, 4); + + shared_num = 0; + uv_rwlock_init(&numlock); + + uv_thread_t threads[3]; + + int thread_nums[] = {1, 2, 1}; + uv_thread_create(&threads[0], reader, &thread_nums[0]); + uv_thread_create(&threads[1], reader, &thread_nums[1]); + + uv_thread_create(&threads[2], writer, &thread_nums[2]); + + uv_barrier_wait(&blocker); + uv_barrier_destroy(&blocker); + + uv_rwlock_destroy(&numlock); + return 0; +} diff --git a/external/src/libuv/docs/code/multi-echo-server/hammer.js b/external/src/libuv/docs/code/multi-echo-server/hammer.js new file mode 100644 index 0000000..5df345b --- /dev/null +++ b/external/src/libuv/docs/code/multi-echo-server/hammer.js @@ -0,0 +1,20 @@ +var net = require('net'); + +var PHRASE = "hello world"; +var write = function(socket) { + socket.write(PHRASE, 'utf8'); +} + +for (var i = 0; i < 1000; i++) { +(function() { + var socket = net.connect(7000, 'localhost', function() { + socket.on('data', function(reply) { + if (reply.toString().indexOf(PHRASE) != 0) + console.error("Problem! '" + reply + "'" + " '" + PHRASE + "'"); + else + write(socket); + }); + write(socket); + }); +})(); +} diff --git a/external/src/libuv/docs/code/multi-echo-server/main.c b/external/src/libuv/docs/code/multi-echo-server/main.c new file mode 100644 index 0000000..b938a7d --- /dev/null +++ b/external/src/libuv/docs/code/multi-echo-server/main.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include +#include + +uv_loop_t *loop; + +struct child_worker { + uv_process_t req; + uv_process_options_t options; + uv_pipe_t pipe; +} *workers; + +int round_robin_counter; +int child_worker_count; + +uv_buf_t dummy_buf; +char worker_path[500]; + +void close_process_handle(uv_process_t *req, int64_t exit_status, int term_signal) { + fprintf(stderr, "Process exited with status %" PRId64 ", signal %d\n", exit_status, term_signal); + uv_close((uv_handle_t*) req, NULL); +} + +void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) { + buf->base = malloc(suggested_size); + buf->len = suggested_size; +} + +void on_new_connection(uv_stream_t *server, int status) { + if (status == -1) { + // error! + return; + } + + uv_tcp_t *client = (uv_tcp_t*) malloc(sizeof(uv_tcp_t)); + uv_tcp_init(loop, client); + if (uv_accept(server, (uv_stream_t*) client) == 0) { + uv_write_t *write_req = (uv_write_t*) malloc(sizeof(uv_write_t)); + dummy_buf = uv_buf_init("a", 1); + struct child_worker *worker = &workers[round_robin_counter]; + uv_write2(write_req, (uv_stream_t*) &worker->pipe, &dummy_buf, 1, (uv_stream_t*) client, NULL); + round_robin_counter = (round_robin_counter + 1) % child_worker_count; + } + else { + uv_close((uv_handle_t*) client, NULL); + } +} + +void setup_workers() { + size_t path_size = 500; + uv_exepath(worker_path, &path_size); + strcpy(worker_path + (strlen(worker_path) - strlen("multi-echo-server")), "worker"); + fprintf(stderr, "Worker path: %s\n", worker_path); + + char* args[2]; + args[0] = worker_path; + args[1] = NULL; + + round_robin_counter = 0; + + // ... + + // launch same number of workers as number of CPUs + uv_cpu_info_t *info; + int cpu_count; + uv_cpu_info(&info, &cpu_count); + uv_free_cpu_info(info, cpu_count); + + child_worker_count = cpu_count; + + workers = calloc(cpu_count, sizeof(struct child_worker)); + while (cpu_count--) { + struct child_worker *worker = &workers[cpu_count]; + uv_pipe_init(loop, &worker->pipe, 1); + + uv_stdio_container_t child_stdio[3]; + child_stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; + child_stdio[0].data.stream = (uv_stream_t*) &worker->pipe; + child_stdio[1].flags = UV_IGNORE; + child_stdio[2].flags = UV_INHERIT_FD; + child_stdio[2].data.fd = 2; + + worker->options.stdio = child_stdio; + worker->options.stdio_count = 3; + + worker->options.exit_cb = close_process_handle; + worker->options.file = args[0]; + worker->options.args = args; + + uv_spawn(loop, &worker->req, &worker->options); + fprintf(stderr, "Started worker %d\n", worker->req.pid); + } +} + +int main() { + loop = uv_default_loop(); + + setup_workers(); + + uv_tcp_t server; + uv_tcp_init(loop, &server); + + struct sockaddr_in bind_addr; + uv_ip4_addr("0.0.0.0", 7000, &bind_addr); + uv_tcp_bind(&server, (const struct sockaddr *)&bind_addr, 0); + int r; + if ((r = uv_listen((uv_stream_t*) &server, 128, on_new_connection))) { + fprintf(stderr, "Listen error %s\n", uv_err_name(r)); + return 2; + } + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/multi-echo-server/worker.c b/external/src/libuv/docs/code/multi-echo-server/worker.c new file mode 100644 index 0000000..1c46575 --- /dev/null +++ b/external/src/libuv/docs/code/multi-echo-server/worker.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include + +uv_loop_t *loop; +uv_pipe_t queue; + +typedef struct { + uv_write_t req; + uv_buf_t buf; +} write_req_t; + +void free_write_req(uv_write_t *req) { + write_req_t *wr = (write_req_t*) req; + free(wr->buf.base); + free(wr); +} + +void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) { + buf->base = malloc(suggested_size); + buf->len = suggested_size; +} + +void echo_write(uv_write_t *req, int status) { + if (status) { + fprintf(stderr, "Write error %s\n", uv_err_name(status)); + } + free_write_req(req); +} + +void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) { + if (nread > 0) { + write_req_t *req = (write_req_t*) malloc(sizeof(write_req_t)); + req->buf = uv_buf_init(buf->base, nread); + uv_write((uv_write_t*) req, client, &req->buf, 1, echo_write); + return; + } + + if (nread < 0) { + if (nread != UV_EOF) + fprintf(stderr, "Read error %s\n", uv_err_name(nread)); + uv_close((uv_handle_t*) client, NULL); + } + + free(buf->base); +} + +void on_new_connection(uv_stream_t *q, ssize_t nread, const uv_buf_t *buf) { + if (nread < 0) { + if (nread != UV_EOF) + fprintf(stderr, "Read error %s\n", uv_err_name(nread)); + uv_close((uv_handle_t*) q, NULL); + return; + } + + uv_pipe_t *pipe = (uv_pipe_t*) q; + if (!uv_pipe_pending_count(pipe)) { + fprintf(stderr, "No pending count\n"); + return; + } + + uv_handle_type pending = uv_pipe_pending_type(pipe); + assert(pending == UV_TCP); + + uv_tcp_t *client = (uv_tcp_t*) malloc(sizeof(uv_tcp_t)); + uv_tcp_init(loop, client); + if (uv_accept(q, (uv_stream_t*) client) == 0) { + uv_os_fd_t fd; + uv_fileno((const uv_handle_t*) client, &fd); + fprintf(stderr, "Worker %d: Accepted fd %d\n", getpid(), fd); + uv_read_start((uv_stream_t*) client, alloc_buffer, echo_read); + } + else { + uv_close((uv_handle_t*) client, NULL); + } +} + +int main() { + loop = uv_default_loop(); + + uv_pipe_init(loop, &queue, 1 /* ipc */); + uv_pipe_open(&queue, 0); + uv_read_start((uv_stream_t*)&queue, alloc_buffer, on_new_connection); + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/onchange/main.c b/external/src/libuv/docs/code/onchange/main.c new file mode 100644 index 0000000..40bdaa5 --- /dev/null +++ b/external/src/libuv/docs/code/onchange/main.c @@ -0,0 +1,44 @@ +#include +#include + +#include + +uv_loop_t *loop; +const char *command; + +void run_command(uv_fs_event_t *handle, const char *filename, int events, int status) { + char path[1024]; + size_t size = 1023; + // Does not handle error if path is longer than 1023. + uv_fs_event_getpath(handle, path, &size); + path[size] = '\0'; + + fprintf(stderr, "Change detected in %s: ", path); + if (events & UV_RENAME) + fprintf(stderr, "renamed"); + if (events & UV_CHANGE) + fprintf(stderr, "changed"); + + fprintf(stderr, " %s\n", filename ? filename : ""); + system(command); +} + +int main(int argc, char **argv) { + if (argc <= 2) { + fprintf(stderr, "Usage: %s [file2 ...]\n", argv[0]); + return 1; + } + + loop = uv_default_loop(); + command = argv[1]; + + while (argc-- > 2) { + fprintf(stderr, "Adding watch on %s\n", argv[argc]); + uv_fs_event_t *fs_event_req = malloc(sizeof(uv_fs_event_t)); + uv_fs_event_init(loop, fs_event_req); + // The recursive flag watches subdirectories too. + uv_fs_event_start(fs_event_req, run_command, argv[argc], UV_FS_EVENT_RECURSIVE); + } + + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/pipe-echo-server/main.c b/external/src/libuv/docs/code/pipe-echo-server/main.c new file mode 100644 index 0000000..4f28fd0 --- /dev/null +++ b/external/src/libuv/docs/code/pipe-echo-server/main.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include + +#ifdef _WIN32 +#define PIPENAME "\\\\?\\pipe\\echo.sock" +#else +#define PIPENAME "/tmp/echo.sock" +#endif + +uv_loop_t *loop; + +typedef struct { + uv_write_t req; + uv_buf_t buf; +} write_req_t; + +void free_write_req(uv_write_t *req) { + write_req_t *wr = (write_req_t*) req; + free(wr->buf.base); + free(wr); +} + +void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) { + buf->base = malloc(suggested_size); + buf->len = suggested_size; +} + +void echo_write(uv_write_t *req, int status) { + if (status < 0) { + fprintf(stderr, "Write error %s\n", uv_err_name(status)); + } + free_write_req(req); +} + +void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) { + if (nread > 0) { + write_req_t *req = (write_req_t*) malloc(sizeof(write_req_t)); + req->buf = uv_buf_init(buf->base, nread); + uv_write((uv_write_t*) req, client, &req->buf, 1, echo_write); + return; + } + + if (nread < 0) { + if (nread != UV_EOF) + fprintf(stderr, "Read error %s\n", uv_err_name(nread)); + uv_close((uv_handle_t*) client, NULL); + } + + free(buf->base); +} + +void on_new_connection(uv_stream_t *server, int status) { + if (status == -1) { + // error! + return; + } + + uv_pipe_t *client = (uv_pipe_t*) malloc(sizeof(uv_pipe_t)); + uv_pipe_init(loop, client, 0); + if (uv_accept(server, (uv_stream_t*) client) == 0) { + uv_read_start((uv_stream_t*) client, alloc_buffer, echo_read); + } + else { + uv_close((uv_handle_t*) client, NULL); + } +} + +void remove_sock(int sig) { + uv_fs_t req; + uv_fs_unlink(loop, &req, PIPENAME, NULL); + exit(0); +} + +int main() { + loop = uv_default_loop(); + + uv_pipe_t server; + uv_pipe_init(loop, &server, 0); + + signal(SIGINT, remove_sock); + + int r; + if ((r = uv_pipe_bind(&server, PIPENAME))) { + fprintf(stderr, "Bind error %s\n", uv_err_name(r)); + return 1; + } + if ((r = uv_listen((uv_stream_t*) &server, 128, on_new_connection))) { + fprintf(stderr, "Listen error %s\n", uv_err_name(r)); + return 2; + } + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/plugin/hello.c b/external/src/libuv/docs/code/plugin/hello.c new file mode 100644 index 0000000..7b2861d --- /dev/null +++ b/external/src/libuv/docs/code/plugin/hello.c @@ -0,0 +1,5 @@ +#include "plugin.h" + +void initialize() { + mfp_register("Hello World!"); +} diff --git a/external/src/libuv/docs/code/plugin/main.c b/external/src/libuv/docs/code/plugin/main.c new file mode 100644 index 0000000..06e581e --- /dev/null +++ b/external/src/libuv/docs/code/plugin/main.c @@ -0,0 +1,39 @@ +#include +#include +#include + +#include + +#include "plugin.h" + +typedef void (*init_plugin_function)(); + +void mfp_register(const char *name) { + fprintf(stderr, "Registered plugin \"%s\"\n", name); +} + +int main(int argc, char **argv) { + if (argc == 1) { + fprintf(stderr, "Usage: %s [plugin1] [plugin2] ...\n", argv[0]); + return 0; + } + + uv_lib_t *lib = (uv_lib_t*) malloc(sizeof(uv_lib_t)); + while (--argc) { + fprintf(stderr, "Loading %s\n", argv[argc]); + if (uv_dlopen(argv[argc], lib)) { + fprintf(stderr, "Error: %s\n", uv_dlerror(lib)); + continue; + } + + init_plugin_function init_plugin; + if (uv_dlsym(lib, "initialize", (void **) &init_plugin)) { + fprintf(stderr, "dlsym error: %s\n", uv_dlerror(lib)); + continue; + } + + init_plugin(); + } + + return 0; +} diff --git a/external/src/libuv/docs/code/plugin/plugin.h b/external/src/libuv/docs/code/plugin/plugin.h new file mode 100644 index 0000000..21f194e --- /dev/null +++ b/external/src/libuv/docs/code/plugin/plugin.h @@ -0,0 +1,7 @@ +#ifndef UVBOOK_PLUGIN_SYSTEM +#define UVBOOK_PLUGIN_SYSTEM + +// Plugin authors should use this to register their plugins with mfp. +void mfp_register(const char *name); + +#endif diff --git a/external/src/libuv/docs/code/proc-streams/main.c b/external/src/libuv/docs/code/proc-streams/main.c new file mode 100644 index 0000000..b8a6521 --- /dev/null +++ b/external/src/libuv/docs/code/proc-streams/main.c @@ -0,0 +1,49 @@ +#include +#include +#include + +#include + +uv_loop_t *loop; +uv_process_t child_req; +uv_process_options_t options; + +void on_exit(uv_process_t *req, int64_t exit_status, int term_signal) { + fprintf(stderr, "Process exited with status %" PRId64 ", signal %d\n", exit_status, term_signal); + uv_close((uv_handle_t*) req, NULL); +} + +int main() { + loop = uv_default_loop(); + + size_t size = 500; + char path[size]; + uv_exepath(path, &size); + strcpy(path + (strlen(path) - strlen("proc-streams")), "test"); + + char* args[2]; + args[0] = path; + args[1] = NULL; + + /* ... */ + + options.stdio_count = 3; + uv_stdio_container_t child_stdio[3]; + child_stdio[0].flags = UV_IGNORE; + child_stdio[1].flags = UV_IGNORE; + child_stdio[2].flags = UV_INHERIT_FD; + child_stdio[2].data.fd = 2; + options.stdio = child_stdio; + + options.exit_cb = on_exit; + options.file = args[0]; + options.args = args; + + int r; + if ((r = uv_spawn(loop, &child_req, &options))) { + fprintf(stderr, "%s\n", uv_strerror(r)); + return 1; + } + + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/proc-streams/test.c b/external/src/libuv/docs/code/proc-streams/test.c new file mode 100644 index 0000000..7c45c1f --- /dev/null +++ b/external/src/libuv/docs/code/proc-streams/test.c @@ -0,0 +1,8 @@ +#include + +int main() +{ + fprintf(stderr, "This is stderr\n"); + printf("This is stdout\n"); + return 0; +} diff --git a/external/src/libuv/docs/code/progress/main.c b/external/src/libuv/docs/code/progress/main.c new file mode 100644 index 0000000..5af01f1 --- /dev/null +++ b/external/src/libuv/docs/code/progress/main.c @@ -0,0 +1,47 @@ +#include +#include +#include + +#include + +uv_loop_t *loop; +uv_async_t async; + +double percentage; + +void fake_download(uv_work_t *req) { + int size = *((int*) req->data); + int downloaded = 0; + while (downloaded < size) { + percentage = downloaded*100.0/size; + async.data = (void*) &percentage; + uv_async_send(&async); + + sleep(1); + downloaded += (200+random())%1000; // can only download max 1000bytes/sec, + // but at least a 200; + } +} + +void after(uv_work_t *req, int status) { + fprintf(stderr, "Download complete\n"); + uv_close((uv_handle_t*) &async, NULL); +} + +void print_progress(uv_async_t *handle) { + double percentage = *((double*) handle->data); + fprintf(stderr, "Downloaded %.2f%%\n", percentage); +} + +int main() { + loop = uv_default_loop(); + + uv_work_t req; + int size = 10240; + req.data = (void*) &size; + + uv_async_init(loop, &async, print_progress); + uv_queue_work(loop, &req, fake_download, after); + + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/queue-cancel/main.c b/external/src/libuv/docs/code/queue-cancel/main.c new file mode 100644 index 0000000..3f7836c --- /dev/null +++ b/external/src/libuv/docs/code/queue-cancel/main.c @@ -0,0 +1,59 @@ +#include +#include +#include + +#include + +#define FIB_UNTIL 25 +uv_loop_t *loop; +uv_work_t fib_reqs[FIB_UNTIL]; + +long fib_(long t) { + if (t == 0 || t == 1) + return 1; + else + return fib_(t-1) + fib_(t-2); +} + +void fib(uv_work_t *req) { + int n = *(int *) req->data; + if (random() % 2) + sleep(1); + else + sleep(3); + long fib = fib_(n); + fprintf(stderr, "%dth fibonacci is %lu\n", n, fib); +} + +void after_fib(uv_work_t *req, int status) { + if (status == UV_ECANCELED) + fprintf(stderr, "Calculation of %d cancelled.\n", *(int *) req->data); +} + +void signal_handler(uv_signal_t *req, int signum) +{ + printf("Signal received!\n"); + int i; + for (i = 0; i < FIB_UNTIL; i++) { + uv_cancel((uv_req_t*) &fib_reqs[i]); + } + uv_signal_stop(req); +} + +int main() { + loop = uv_default_loop(); + + int data[FIB_UNTIL]; + int i; + for (i = 0; i < FIB_UNTIL; i++) { + data[i] = i; + fib_reqs[i].data = (void *) &data[i]; + uv_queue_work(loop, &fib_reqs[i], fib, after_fib); + } + + uv_signal_t sig; + uv_signal_init(loop, &sig); + uv_signal_start(&sig, signal_handler, SIGINT); + + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/queue-work/main.c b/external/src/libuv/docs/code/queue-work/main.c new file mode 100644 index 0000000..55675ea --- /dev/null +++ b/external/src/libuv/docs/code/queue-work/main.c @@ -0,0 +1,44 @@ +#include +#include +#include + +#include + +#define FIB_UNTIL 25 +uv_loop_t *loop; + +long fib_(long t) { + if (t == 0 || t == 1) + return 1; + else + return fib_(t-1) + fib_(t-2); +} + +void fib(uv_work_t *req) { + int n = *(int *) req->data; + if (random() % 2) + sleep(1); + else + sleep(3); + long fib = fib_(n); + fprintf(stderr, "%dth fibonacci is %lu\n", n, fib); +} + +void after_fib(uv_work_t *req, int status) { + fprintf(stderr, "Done calculating %dth fibonacci\n", *(int *) req->data); +} + +int main() { + loop = uv_default_loop(); + + int data[FIB_UNTIL]; + uv_work_t req[FIB_UNTIL]; + int i; + for (i = 0; i < FIB_UNTIL; i++) { + data[i] = i; + req[i].data = (void *) &data[i]; + uv_queue_work(loop, &req[i], fib, after_fib); + } + + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/ref-timer/main.c b/external/src/libuv/docs/code/ref-timer/main.c new file mode 100644 index 0000000..ad7c829 --- /dev/null +++ b/external/src/libuv/docs/code/ref-timer/main.c @@ -0,0 +1,29 @@ +#include + +#include + +uv_loop_t *loop; +uv_timer_t gc_req; +uv_timer_t fake_job_req; + +void gc(uv_timer_t *handle) { + fprintf(stderr, "Freeing unused objects\n"); +} + +void fake_job(uv_timer_t *handle) { + fprintf(stdout, "Fake job done\n"); +} + +int main() { + loop = uv_default_loop(); + + uv_timer_init(loop, &gc_req); + uv_unref((uv_handle_t*) &gc_req); + + uv_timer_start(&gc_req, gc, 0, 2000); + + // could actually be a TCP download or something + uv_timer_init(loop, &fake_job_req); + uv_timer_start(&fake_job_req, fake_job, 9000, 0); + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/signal/main.c b/external/src/libuv/docs/code/signal/main.c new file mode 100644 index 0000000..1b982c5 --- /dev/null +++ b/external/src/libuv/docs/code/signal/main.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include + +uv_loop_t* create_loop() +{ + uv_loop_t *loop = malloc(sizeof(uv_loop_t)); + if (loop) { + uv_loop_init(loop); + } + return loop; +} + +void signal_handler(uv_signal_t *handle, int signum) +{ + printf("Signal received: %d\n", signum); + uv_signal_stop(handle); +} + +// two signal handlers in one loop +void thread1_worker(void *userp) +{ + uv_loop_t *loop1 = create_loop(); + + uv_signal_t sig1a, sig1b; + uv_signal_init(loop1, &sig1a); + uv_signal_start(&sig1a, signal_handler, SIGUSR1); + + uv_signal_init(loop1, &sig1b); + uv_signal_start(&sig1b, signal_handler, SIGUSR1); + + uv_run(loop1, UV_RUN_DEFAULT); +} + +// two signal handlers, each in its own loop +void thread2_worker(void *userp) +{ + uv_loop_t *loop2 = create_loop(); + uv_loop_t *loop3 = create_loop(); + + uv_signal_t sig2; + uv_signal_init(loop2, &sig2); + uv_signal_start(&sig2, signal_handler, SIGUSR1); + + uv_signal_t sig3; + uv_signal_init(loop3, &sig3); + uv_signal_start(&sig3, signal_handler, SIGUSR1); + + while (uv_run(loop2, UV_RUN_NOWAIT) || uv_run(loop3, UV_RUN_NOWAIT)) { + } +} + +int main() +{ + printf("PID %d\n", getpid()); + + uv_thread_t thread1, thread2; + + uv_thread_create(&thread1, thread1_worker, 0); + uv_thread_create(&thread2, thread2_worker, 0); + + uv_thread_join(&thread1); + uv_thread_join(&thread2); + return 0; +} diff --git a/external/src/libuv/docs/code/spawn/main.c b/external/src/libuv/docs/code/spawn/main.c new file mode 100644 index 0000000..dedfe00 --- /dev/null +++ b/external/src/libuv/docs/code/spawn/main.c @@ -0,0 +1,36 @@ +#include +#include + +#include + +uv_loop_t *loop; +uv_process_t child_req; +uv_process_options_t options; + +void on_exit(uv_process_t *req, int64_t exit_status, int term_signal) { + fprintf(stderr, "Process exited with status %" PRId64 ", signal %d\n", exit_status, term_signal); + uv_close((uv_handle_t*) req, NULL); +} + +int main() { + loop = uv_default_loop(); + + char* args[3]; + args[0] = "mkdir"; + args[1] = "test-dir"; + args[2] = NULL; + + options.exit_cb = on_exit; + options.file = "mkdir"; + options.args = args; + + int r; + if ((r = uv_spawn(loop, &child_req, &options))) { + fprintf(stderr, "%s\n", uv_strerror(r)); + return 1; + } else { + fprintf(stderr, "Launched process with ID %d\n", child_req.pid); + } + + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/tcp-echo-server/main.c b/external/src/libuv/docs/code/tcp-echo-server/main.c new file mode 100644 index 0000000..5d7b499 --- /dev/null +++ b/external/src/libuv/docs/code/tcp-echo-server/main.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include + +#define DEFAULT_PORT 7000 +#define DEFAULT_BACKLOG 128 + +uv_loop_t *loop; +struct sockaddr_in addr; + +typedef struct { + uv_write_t req; + uv_buf_t buf; +} write_req_t; + +void free_write_req(uv_write_t *req) { + write_req_t *wr = (write_req_t*) req; + free(wr->buf.base); + free(wr); +} + +void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) { + buf->base = (char*) malloc(suggested_size); + buf->len = suggested_size; +} + +void on_close(uv_handle_t* handle) { + free(handle); +} + +void echo_write(uv_write_t *req, int status) { + if (status) { + fprintf(stderr, "Write error %s\n", uv_strerror(status)); + } + free_write_req(req); +} + +void echo_read(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf) { + if (nread > 0) { + write_req_t *req = (write_req_t*) malloc(sizeof(write_req_t)); + req->buf = uv_buf_init(buf->base, nread); + uv_write((uv_write_t*) req, client, &req->buf, 1, echo_write); + return; + } + if (nread < 0) { + if (nread != UV_EOF) + fprintf(stderr, "Read error %s\n", uv_err_name(nread)); + uv_close((uv_handle_t*) client, on_close); + } + + free(buf->base); +} + +void on_new_connection(uv_stream_t *server, int status) { + if (status < 0) { + fprintf(stderr, "New connection error %s\n", uv_strerror(status)); + // error! + return; + } + + uv_tcp_t *client = (uv_tcp_t*) malloc(sizeof(uv_tcp_t)); + uv_tcp_init(loop, client); + if (uv_accept(server, (uv_stream_t*) client) == 0) { + uv_read_start((uv_stream_t*) client, alloc_buffer, echo_read); + } + else { + uv_close((uv_handle_t*) client, on_close); + } +} + +int main() { + loop = uv_default_loop(); + + uv_tcp_t server; + uv_tcp_init(loop, &server); + + uv_ip4_addr("0.0.0.0", DEFAULT_PORT, &addr); + + uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0); + int r = uv_listen((uv_stream_t*) &server, DEFAULT_BACKLOG, on_new_connection); + if (r) { + fprintf(stderr, "Listen error %s\n", uv_strerror(r)); + return 1; + } + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/thread-create/main.c b/external/src/libuv/docs/code/thread-create/main.c new file mode 100644 index 0000000..70224c1 --- /dev/null +++ b/external/src/libuv/docs/code/thread-create/main.c @@ -0,0 +1,36 @@ +#include +#include + +#include + +void hare(void *arg) { + int tracklen = *((int *) arg); + while (tracklen) { + tracklen--; + sleep(1); + fprintf(stderr, "Hare ran another step\n"); + } + fprintf(stderr, "Hare done running!\n"); +} + +void tortoise(void *arg) { + int tracklen = *((int *) arg); + while (tracklen) { + tracklen--; + fprintf(stderr, "Tortoise ran another step\n"); + sleep(3); + } + fprintf(stderr, "Tortoise done running!\n"); +} + +int main() { + int tracklen = 10; + uv_thread_t hare_id; + uv_thread_t tortoise_id; + uv_thread_create(&hare_id, hare, &tracklen); + uv_thread_create(&tortoise_id, tortoise, &tracklen); + + uv_thread_join(&hare_id); + uv_thread_join(&tortoise_id); + return 0; +} diff --git a/external/src/libuv/docs/code/tty-gravity/main.c b/external/src/libuv/docs/code/tty-gravity/main.c new file mode 100644 index 0000000..0a8d6b2 --- /dev/null +++ b/external/src/libuv/docs/code/tty-gravity/main.c @@ -0,0 +1,48 @@ +#include +#include +#include +#include + +uv_loop_t *loop; +uv_tty_t tty; +uv_timer_t tick; +uv_write_t write_req; +int width, height; +int pos = 0; +char *message = " Hello TTY "; + +void update(uv_timer_t *req) { + char data[500]; + + uv_buf_t buf; + buf.base = data; + buf.len = sprintf(data, "\033[2J\033[H\033[%dB\033[%luC\033[42;37m%s", + pos, + (unsigned long) (width-strlen(message))/2, + message); + uv_write(&write_req, (uv_stream_t*) &tty, &buf, 1, NULL); + + pos++; + if (pos > height) { + uv_tty_reset_mode(); + uv_timer_stop(&tick); + } +} + +int main() { + loop = uv_default_loop(); + + uv_tty_init(loop, &tty, STDOUT_FILENO, 0); + uv_tty_set_mode(&tty, 0); + + if (uv_tty_get_winsize(&tty, &width, &height)) { + fprintf(stderr, "Could not get TTY information\n"); + uv_tty_reset_mode(); + return 1; + } + + fprintf(stderr, "Width %d, height %d\n", width, height); + uv_timer_init(loop, &tick); + uv_timer_start(&tick, update, 200, 200); + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/tty/main.c b/external/src/libuv/docs/code/tty/main.c new file mode 100644 index 0000000..d44ec62 --- /dev/null +++ b/external/src/libuv/docs/code/tty/main.c @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +uv_loop_t *loop; +uv_tty_t tty; +int main() { + loop = uv_default_loop(); + + uv_tty_init(loop, &tty, STDOUT_FILENO, 0); + uv_tty_set_mode(&tty, UV_TTY_MODE_NORMAL); + + if (uv_guess_handle(1) == UV_TTY) { + uv_write_t req; + uv_buf_t buf; + buf.base = "\033[41;37m"; + buf.len = strlen(buf.base); + uv_write(&req, (uv_stream_t*) &tty, &buf, 1, NULL); + } + + uv_write_t req; + uv_buf_t buf; + buf.base = "Hello TTY\n"; + buf.len = strlen(buf.base); + uv_write(&req, (uv_stream_t*) &tty, &buf, 1, NULL); + uv_tty_reset_mode(); + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/udp-dhcp/main.c b/external/src/libuv/docs/code/udp-dhcp/main.c new file mode 100644 index 0000000..fc2ca0c --- /dev/null +++ b/external/src/libuv/docs/code/udp-dhcp/main.c @@ -0,0 +1,127 @@ +#include +#include +#include +#include + +#include + +uv_loop_t *loop; +uv_udp_t send_socket; +uv_udp_t recv_socket; + +void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) { + buf->base = malloc(suggested_size); + buf->len = suggested_size; +} + +void on_read(uv_udp_t *req, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) { + if (nread < 0) { + fprintf(stderr, "Read error %s\n", uv_err_name(nread)); + uv_close((uv_handle_t*) req, NULL); + free(buf->base); + return; + } + + char sender[17] = { 0 }; + uv_ip4_name((const struct sockaddr_in*) addr, sender, 16); + fprintf(stderr, "Recv from %s\n", sender); + + // ... DHCP specific code + unsigned int *as_integer = (unsigned int*)buf->base; + unsigned int ipbin = ntohl(as_integer[4]); + unsigned char ip[4] = {0}; + int i; + for (i = 0; i < 4; i++) + ip[i] = (ipbin >> i*8) & 0xff; + fprintf(stderr, "Offered IP %d.%d.%d.%d\n", ip[3], ip[2], ip[1], ip[0]); + + free(buf->base); + uv_udp_recv_stop(req); +} + +uv_buf_t make_discover_msg() { + uv_buf_t buffer; + alloc_buffer(NULL, 256, &buffer); + memset(buffer.base, 0, buffer.len); + + // BOOTREQUEST + buffer.base[0] = 0x1; + // HTYPE ethernet + buffer.base[1] = 0x1; + // HLEN + buffer.base[2] = 0x6; + // HOPS + buffer.base[3] = 0x0; + // XID 4 bytes + buffer.base[4] = (unsigned int) random(); + // SECS + buffer.base[8] = 0x0; + // FLAGS + buffer.base[10] = 0x80; + // CIADDR 12-15 is all zeros + // YIADDR 16-19 is all zeros + // SIADDR 20-23 is all zeros + // GIADDR 24-27 is all zeros + // CHADDR 28-43 is the MAC address, use your own + buffer.base[28] = 0xe4; + buffer.base[29] = 0xce; + buffer.base[30] = 0x8f; + buffer.base[31] = 0x13; + buffer.base[32] = 0xf6; + buffer.base[33] = 0xd4; + // SNAME 64 bytes zero + // FILE 128 bytes zero + // OPTIONS + // - magic cookie + buffer.base[236] = 99; + buffer.base[237] = 130; + buffer.base[238] = 83; + buffer.base[239] = 99; + + // DHCP Message type + buffer.base[240] = 53; + buffer.base[241] = 1; + buffer.base[242] = 1; // DHCPDISCOVER + + // DHCP Parameter request list + buffer.base[243] = 55; + buffer.base[244] = 4; + buffer.base[245] = 1; + buffer.base[246] = 3; + buffer.base[247] = 15; + buffer.base[248] = 6; + + return buffer; +} + +void on_send(uv_udp_send_t *req, int status) { + if (status) { + fprintf(stderr, "Send error %s\n", uv_strerror(status)); + return; + } +} + +int main() { + loop = uv_default_loop(); + + uv_udp_init(loop, &recv_socket); + struct sockaddr_in recv_addr; + uv_ip4_addr("0.0.0.0", 68, &recv_addr); + uv_udp_bind(&recv_socket, (const struct sockaddr *)&recv_addr, UV_UDP_REUSEADDR); + uv_udp_recv_start(&recv_socket, alloc_buffer, on_read); + + uv_udp_init(loop, &send_socket); + struct sockaddr_in broadcast_addr; + uv_ip4_addr("0.0.0.0", 0, &broadcast_addr); + uv_udp_bind(&send_socket, (const struct sockaddr *)&broadcast_addr, 0); + uv_udp_set_broadcast(&send_socket, 1); + + uv_udp_send_t send_req; + uv_buf_t discover_msg = make_discover_msg(); + + struct sockaddr_in send_addr; + uv_ip4_addr("255.255.255.255", 67, &send_addr); + uv_udp_send(&send_req, &send_socket, &discover_msg, 1, (const struct sockaddr *)&send_addr, on_send); + + return uv_run(loop, UV_RUN_DEFAULT); +} diff --git a/external/src/libuv/docs/code/uvcat/main.c b/external/src/libuv/docs/code/uvcat/main.c new file mode 100644 index 0000000..b03b094 --- /dev/null +++ b/external/src/libuv/docs/code/uvcat/main.c @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include + +void on_read(uv_fs_t *req); + +uv_fs_t open_req; +uv_fs_t read_req; +uv_fs_t write_req; + +static char buffer[1024]; + +static uv_buf_t iov; + +void on_write(uv_fs_t *req) { + if (req->result < 0) { + fprintf(stderr, "Write error: %s\n", uv_strerror((int)req->result)); + } + else { + uv_fs_read(uv_default_loop(), &read_req, open_req.result, &iov, 1, -1, on_read); + } +} + +void on_read(uv_fs_t *req) { + if (req->result < 0) { + fprintf(stderr, "Read error: %s\n", uv_strerror(req->result)); + } + else if (req->result == 0) { + uv_fs_t close_req; + // synchronous + uv_fs_close(uv_default_loop(), &close_req, open_req.result, NULL); + } + else if (req->result > 0) { + iov.len = req->result; + uv_fs_write(uv_default_loop(), &write_req, 1, &iov, 1, -1, on_write); + } +} + +void on_open(uv_fs_t *req) { + // The request passed to the callback is the same as the one the call setup + // function was passed. + assert(req == &open_req); + if (req->result >= 0) { + iov = uv_buf_init(buffer, sizeof(buffer)); + uv_fs_read(uv_default_loop(), &read_req, req->result, + &iov, 1, -1, on_read); + } + else { + fprintf(stderr, "error opening file: %s\n", uv_strerror((int)req->result)); + } +} + +int main(int argc, char **argv) { + uv_fs_open(uv_default_loop(), &open_req, argv[1], O_RDONLY, 0, on_open); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + uv_fs_req_cleanup(&open_req); + uv_fs_req_cleanup(&read_req); + uv_fs_req_cleanup(&write_req); + return 0; +} diff --git a/external/src/libuv/docs/code/uvstop/main.c b/external/src/libuv/docs/code/uvstop/main.c new file mode 100644 index 0000000..7aa53b7 --- /dev/null +++ b/external/src/libuv/docs/code/uvstop/main.c @@ -0,0 +1,33 @@ +#include +#include + +int64_t counter = 0; + +void idle_cb(uv_idle_t *handle) { + printf("Idle callback\n"); + counter++; + + if (counter >= 5) { + uv_stop(uv_default_loop()); + printf("uv_stop() called\n"); + } +} + +void prep_cb(uv_prepare_t *handle) { + printf("Prep callback\n"); +} + +int main() { + uv_idle_t idler; + uv_prepare_t prep; + + uv_idle_init(uv_default_loop(), &idler); + uv_idle_start(&idler, idle_cb); + + uv_prepare_init(uv_default_loop(), &prep); + uv_prepare_start(&prep, prep_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + return 0; +} diff --git a/external/src/libuv/docs/code/uvtee/main.c b/external/src/libuv/docs/code/uvtee/main.c new file mode 100644 index 0000000..6216c2e --- /dev/null +++ b/external/src/libuv/docs/code/uvtee/main.c @@ -0,0 +1,80 @@ +#include +#include +#include +#include +#include + +#include + +typedef struct { + uv_write_t req; + uv_buf_t buf; +} write_req_t; + +uv_loop_t *loop; +uv_pipe_t stdin_pipe; +uv_pipe_t stdout_pipe; +uv_pipe_t file_pipe; + +void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf) { + *buf = uv_buf_init((char*) malloc(suggested_size), suggested_size); +} + +void free_write_req(uv_write_t *req) { + write_req_t *wr = (write_req_t*) req; + free(wr->buf.base); + free(wr); +} + +void on_stdout_write(uv_write_t *req, int status) { + free_write_req(req); +} + +void on_file_write(uv_write_t *req, int status) { + free_write_req(req); +} + +void write_data(uv_stream_t *dest, size_t size, uv_buf_t buf, uv_write_cb cb) { + write_req_t *req = (write_req_t*) malloc(sizeof(write_req_t)); + req->buf = uv_buf_init((char*) malloc(size), size); + memcpy(req->buf.base, buf.base, size); + uv_write((uv_write_t*) req, (uv_stream_t*)dest, &req->buf, 1, cb); +} + +void read_stdin(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { + if (nread < 0){ + if (nread == UV_EOF){ + // end of file + uv_close((uv_handle_t *)&stdin_pipe, NULL); + uv_close((uv_handle_t *)&stdout_pipe, NULL); + uv_close((uv_handle_t *)&file_pipe, NULL); + } + } else if (nread > 0) { + write_data((uv_stream_t *)&stdout_pipe, nread, *buf, on_stdout_write); + write_data((uv_stream_t *)&file_pipe, nread, *buf, on_file_write); + } + + // OK to free buffer as write_data copies it. + if (buf->base) + free(buf->base); +} + +int main(int argc, char **argv) { + loop = uv_default_loop(); + + uv_pipe_init(loop, &stdin_pipe, 0); + uv_pipe_open(&stdin_pipe, 0); + + uv_pipe_init(loop, &stdout_pipe, 0); + uv_pipe_open(&stdout_pipe, 1); + + uv_fs_t file_req; + int fd = uv_fs_open(loop, &file_req, argv[1], O_CREAT | O_RDWR, 0644, NULL); + uv_pipe_init(loop, &file_pipe, 0); + uv_pipe_open(&file_pipe, fd); + + uv_read_start((uv_stream_t*)&stdin_pipe, alloc_buffer, read_stdin); + + uv_run(loop, UV_RUN_DEFAULT); + return 0; +} diff --git a/external/src/libuv/docs/code/uvwget/main.c b/external/src/libuv/docs/code/uvwget/main.c new file mode 100644 index 0000000..4018624 --- /dev/null +++ b/external/src/libuv/docs/code/uvwget/main.c @@ -0,0 +1,166 @@ +#include +#include +#include +#include +#include + +uv_loop_t *loop; +CURLM *curl_handle; +uv_timer_t timeout; + +typedef struct curl_context_s { + uv_poll_t poll_handle; + curl_socket_t sockfd; +} curl_context_t; + +curl_context_t *create_curl_context(curl_socket_t sockfd) { + curl_context_t *context; + + context = (curl_context_t*) malloc(sizeof *context); + + context->sockfd = sockfd; + + int r = uv_poll_init_socket(loop, &context->poll_handle, sockfd); + assert(r == 0); + context->poll_handle.data = context; + + return context; +} + +void curl_close_cb(uv_handle_t *handle) { + curl_context_t *context = (curl_context_t*) handle->data; + free(context); +} + +void destroy_curl_context(curl_context_t *context) { + uv_close((uv_handle_t*) &context->poll_handle, curl_close_cb); +} + + +void add_download(const char *url, int num) { + char filename[50]; + sprintf(filename, "%d.download", num); + FILE *file; + + file = fopen(filename, "w"); + if (file == NULL) { + fprintf(stderr, "Error opening %s\n", filename); + return; + } + + CURL *handle = curl_easy_init(); + curl_easy_setopt(handle, CURLOPT_WRITEDATA, file); + curl_easy_setopt(handle, CURLOPT_URL, url); + curl_multi_add_handle(curl_handle, handle); + fprintf(stderr, "Added download %s -> %s\n", url, filename); +} + +void check_multi_info(void) { + char *done_url; + CURLMsg *message; + int pending; + + while ((message = curl_multi_info_read(curl_handle, &pending))) { + switch (message->msg) { + case CURLMSG_DONE: + curl_easy_getinfo(message->easy_handle, CURLINFO_EFFECTIVE_URL, + &done_url); + printf("%s DONE\n", done_url); + + curl_multi_remove_handle(curl_handle, message->easy_handle); + curl_easy_cleanup(message->easy_handle); + break; + + default: + fprintf(stderr, "CURLMSG default\n"); + abort(); + } + } +} + +void curl_perform(uv_poll_t *req, int status, int events) { + uv_timer_stop(&timeout); + int running_handles; + int flags = 0; + if (status < 0) flags = CURL_CSELECT_ERR; + if (!status && events & UV_READABLE) flags |= CURL_CSELECT_IN; + if (!status && events & UV_WRITABLE) flags |= CURL_CSELECT_OUT; + + curl_context_t *context; + + context = (curl_context_t*)req; + + curl_multi_socket_action(curl_handle, context->sockfd, flags, &running_handles); + check_multi_info(); +} + +void on_timeout(uv_timer_t *req) { + int running_handles; + curl_multi_socket_action(curl_handle, CURL_SOCKET_TIMEOUT, 0, &running_handles); + check_multi_info(); +} + +void start_timeout(CURLM *multi, long timeout_ms, void *userp) { + if (timeout_ms <= 0) + timeout_ms = 1; /* 0 means directly call socket_action, but we'll do it in a bit */ + uv_timer_start(&timeout, on_timeout, timeout_ms, 0); +} + +int handle_socket(CURL *easy, curl_socket_t s, int action, void *userp, void *socketp) { + curl_context_t *curl_context; + if (action == CURL_POLL_IN || action == CURL_POLL_OUT) { + if (socketp) { + curl_context = (curl_context_t*) socketp; + } + else { + curl_context = create_curl_context(s); + curl_multi_assign(curl_handle, s, (void *) curl_context); + } + } + + switch (action) { + case CURL_POLL_IN: + uv_poll_start(&curl_context->poll_handle, UV_READABLE, curl_perform); + break; + case CURL_POLL_OUT: + uv_poll_start(&curl_context->poll_handle, UV_WRITABLE, curl_perform); + break; + case CURL_POLL_REMOVE: + if (socketp) { + uv_poll_stop(&((curl_context_t*)socketp)->poll_handle); + destroy_curl_context((curl_context_t*) socketp); + curl_multi_assign(curl_handle, s, NULL); + } + break; + default: + abort(); + } + + return 0; +} + +int main(int argc, char **argv) { + loop = uv_default_loop(); + + if (argc <= 1) + return 0; + + if (curl_global_init(CURL_GLOBAL_ALL)) { + fprintf(stderr, "Could not init cURL\n"); + return 1; + } + + uv_timer_init(loop, &timeout); + + curl_handle = curl_multi_init(); + curl_multi_setopt(curl_handle, CURLMOPT_SOCKETFUNCTION, handle_socket); + curl_multi_setopt(curl_handle, CURLMOPT_TIMERFUNCTION, start_timeout); + + while (argc-- > 1) { + add_download(argv[argc], argc); + } + + uv_run(loop, UV_RUN_DEFAULT); + curl_multi_cleanup(curl_handle); + return 0; +} diff --git a/external/src/libuv/docs/make.bat b/external/src/libuv/docs/make.bat new file mode 100644 index 0000000..10eb94b --- /dev/null +++ b/external/src/libuv/docs/make.bat @@ -0,0 +1,243 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set BUILDDIR=build +set SRCDIR=src +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% %SRCDIR% +set I18NSPHINXOPTS=%SPHINXOPTS% %SRCDIR% +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% + set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^` where ^ is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. singlehtml to make a single large HTML file + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. devhelp to make HTML files and a Devhelp project + echo. epub to make an epub + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. text to make text files + echo. man to make manual pages + echo. texinfo to make Texinfo files + echo. gettext to make PO message catalogs + echo. changes to make an overview over all changed/added/deprecated items + echo. xml to make Docutils-native XML files + echo. pseudoxml to make pseudoxml-XML files for display purposes + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + + +%SPHINXBUILD% 2> nul +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "singlehtml" ( + %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\libuv.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\libuv.ghc + goto end +) + +if "%1" == "devhelp" ( + %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. + goto end +) + +if "%1" == "epub" ( + %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The epub file is in %BUILDDIR%/epub. + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + if errorlevel 1 exit /b 1 + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdf" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf + cd %BUILDDIR%/.. + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "latexpdfja" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + cd %BUILDDIR%/latex + make all-pdf-ja + cd %BUILDDIR%/.. + echo. + echo.Build finished; the PDF files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "text" ( + %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The text files are in %BUILDDIR%/text. + goto end +) + +if "%1" == "man" ( + %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The manual pages are in %BUILDDIR%/man. + goto end +) + +if "%1" == "texinfo" ( + %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. + goto end +) + +if "%1" == "gettext" ( + %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The message catalogs are in %BUILDDIR%/locale. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + if errorlevel 1 exit /b 1 + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + if errorlevel 1 exit /b 1 + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + if errorlevel 1 exit /b 1 + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +if "%1" == "xml" ( + %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The XML files are in %BUILDDIR%/xml. + goto end +) + +if "%1" == "pseudoxml" ( + %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml + if errorlevel 1 exit /b 1 + echo. + echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. + goto end +) + +:end diff --git a/external/src/libuv/docs/requirements.txt b/external/src/libuv/docs/requirements.txt new file mode 100644 index 0000000..8386e01 --- /dev/null +++ b/external/src/libuv/docs/requirements.txt @@ -0,0 +1,42 @@ +# primary +Sphinx==3.5.4 + +# dependencies +alabaster==0.7.12 +appdirs==1.4.3 +Babel==2.9.0 +CacheControl==0.12.6 +certifi==2019.11.28 +chardet==3.0.4 +colorama==0.4.3 +contextlib2==0.6.0 +distlib==0.3.0 +distro==1.4.0 +docutils==0.16 +html5lib==1.0.1 +idna==2.8 +imagesize==1.2.0 +ipaddr==2.2.0 +Jinja2==2.11.3 +lockfile==0.12.2 +MarkupSafe==1.1.1 +msgpack==0.6.2 +packaging==20.3 +pep517==0.8.2 +progress==1.5 +Pygments==2.8.1 +pyparsing==2.4.6 +pytoml==0.1.21 +pytz==2021.1 +requests==2.22.0 +retrying==1.3.3 +six==1.14.0 +snowballstemmer==2.1.0 +sphinxcontrib-applehelp==1.0.2 +sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-htmlhelp==1.0.3 +sphinxcontrib-jsmath==1.0.1 +sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-serializinghtml==1.1.4 +urllib3==1.25.8 +webencodings==0.5.1 diff --git a/external/src/libuv/docs/src/api.rst b/external/src/libuv/docs/src/api.rst new file mode 100644 index 0000000..c8e837d --- /dev/null +++ b/external/src/libuv/docs/src/api.rst @@ -0,0 +1,36 @@ +.. _api: + +API documentation +================= + +.. toctree:: + :maxdepth: 1 + + errors + version + loop + handle + request + timer + prepare + check + idle + async + poll + signal + process + stream + tcp + pipe + tty + udp + fs_event + fs_poll + fs + threadpool + dns + dll + threading + misc + metrics + diff --git a/external/src/libuv/docs/src/async.rst b/external/src/libuv/docs/src/async.rst new file mode 100644 index 0000000..029c051 --- /dev/null +++ b/external/src/libuv/docs/src/async.rst @@ -0,0 +1,65 @@ + +.. _async: + +:c:type:`uv_async_t` --- Async handle +===================================== + +Async handles allow the user to "wakeup" the event loop and get a callback +called from another thread. + + +Data types +---------- + +.. c:type:: uv_async_t + + Async handle type. + +.. c:type:: void (*uv_async_cb)(uv_async_t* handle) + + Type definition for callback passed to :c:func:`uv_async_init`. + + +Public members +^^^^^^^^^^^^^^ + +N/A + +.. seealso:: The :c:type:`uv_handle_t` members also apply. + + +API +--- + +.. c:function:: int uv_async_init(uv_loop_t* loop, uv_async_t* async, uv_async_cb async_cb) + + Initialize the handle. A NULL callback is allowed. + + :returns: 0 on success, or an error code < 0 on failure. + + .. note:: + Unlike other handle initialization functions, it immediately starts the handle. + +.. c:function:: int uv_async_send(uv_async_t* async) + + Wake up the event loop and call the async handle's callback. + + :returns: 0 on success, or an error code < 0 on failure. + + .. note:: + It's safe to call this function from any thread. The callback will be called on the + loop thread. + + .. note:: + :c:func:`uv_async_send` is `async-signal-safe `_. + It's safe to call this function from a signal handler. + + .. warning:: + libuv will coalesce calls to :c:func:`uv_async_send`, that is, not every call to it will + yield an execution of the callback. For example: if :c:func:`uv_async_send` is called 5 + times in a row before the callback is called, the callback will only be called once. If + :c:func:`uv_async_send` is called again after the callback was called, it will be called + again. + +.. seealso:: + The :c:type:`uv_handle_t` API functions also apply. diff --git a/external/src/libuv/docs/src/check.rst b/external/src/libuv/docs/src/check.rst new file mode 100644 index 0000000..33aab55 --- /dev/null +++ b/external/src/libuv/docs/src/check.rst @@ -0,0 +1,54 @@ + +.. _check: + +:c:type:`uv_check_t` --- Check handle +===================================== + +Check handles will run the given callback once per loop iteration, right +after polling for i/o. + + +Data types +---------- + +.. c:type:: uv_check_t + + Check handle type. + +.. c:type:: void (*uv_check_cb)(uv_check_t* handle) + + Type definition for callback passed to :c:func:`uv_check_start`. + + +Public members +^^^^^^^^^^^^^^ + +N/A + +.. seealso:: The :c:type:`uv_handle_t` members also apply. + + +API +--- + +.. c:function:: int uv_check_init(uv_loop_t* loop, uv_check_t* check) + + Initialize the handle. This function always succeeds. + + :returns: 0 + +.. c:function:: int uv_check_start(uv_check_t* check, uv_check_cb cb) + + Start the handle with the given callback. This function always succeeds, + except when `cb` is `NULL`. + + :returns: 0 on success, or `UV_EINVAL` when `cb == NULL`. + +.. c:function:: int uv_check_stop(uv_check_t* check) + + Stop the handle, the callback will no longer be called. + This function always succeeds. + + :returns: 0 + +.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/external/src/libuv/docs/src/conf.py b/external/src/libuv/docs/src/conf.py new file mode 100644 index 0000000..f6f4325 --- /dev/null +++ b/external/src/libuv/docs/src/conf.py @@ -0,0 +1,348 @@ +# -*- coding: utf-8 -*- +# +# libuv documentation documentation build configuration file, created by +# sphinx-quickstart on Sun Jul 27 11:47:51 2014. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import os +import re +import sys + + +def get_libuv_version(): + with open('../../include/uv/version.h') as f: + data = f.read() + try: + m = re.search(r"""^#define UV_VERSION_MAJOR (\d+)$""", data, re.MULTILINE) + major = int(m.group(1)) + m = re.search(r"""^#define UV_VERSION_MINOR (\d+)$""", data, re.MULTILINE) + minor = int(m.group(1)) + m = re.search(r"""^#define UV_VERSION_PATCH (\d+)$""", data, re.MULTILINE) + patch = int(m.group(1)) + m = re.search(r"""^#define UV_VERSION_IS_RELEASE (\d)$""", data, re.MULTILINE) + is_release = int(m.group(1)) + m = re.search(r"""^#define UV_VERSION_SUFFIX \"(\w*)\"$""", data, re.MULTILINE) + suffix = m.group(1) + return '%d.%d.%d%s' % (major, minor, patch, '-%s' % suffix if not is_release else '') + except Exception: + return 'unknown' + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.insert(0, os.path.abspath('sphinx-plugins')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['manpage'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'libuv API documentation' +copyright = u'2014-present, libuv contributors' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = get_libuv_version() +# The full version, including alpha/beta/rc tags. +release = version + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'nature' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +html_title = 'libuv documentation' + +# A shorter title for the navigation bar. Default is the same as html_title. +html_short_title = 'libuv %s documentation' % version + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +html_logo = 'static/logo.png' + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +html_favicon = 'static/favicon.ico' + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'libuv' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ('index', 'libuv.tex', u'libuv documentation', + u'libuv contributors', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'libuv', u'libuv documentation', + [u'libuv contributors'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'libuv', u'libuv documentation', + u'libuv contributors', 'libuv', 'Cross-platform asynchronous I/O', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False + + +# -- Options for Epub output ---------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = u'libuv documentation' +epub_author = u'libuv contributors' +epub_publisher = u'libuv contributors' +epub_copyright = u'2014-present, libuv contributors' + +# The basename for the epub file. It defaults to the project name. +epub_basename = u'libuv' + +# The HTML theme for the epub output. Since the default themes are not optimized +# for small screen space, using the same theme for HTML and epub output is +# usually not wise. This defaults to 'epub', a theme designed to save visual +# space. +#epub_theme = 'epub' + +# The language of the text. It defaults to the language option +# or en if the language is not set. +#epub_language = '' + +# The scheme of the identifier. Typical schemes are ISBN or URL. +#epub_scheme = '' + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +#epub_identifier = '' + +# A unique identification for the text. +#epub_uid = '' + +# A tuple containing the cover image and cover page html template filenames. +#epub_cover = () + +# A sequence of (type, uri, title) tuples for the guide element of content.opf. +#epub_guide = () + +# HTML files that should be inserted before the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_pre_files = [] + +# HTML files shat should be inserted after the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_post_files = [] + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + +# The depth of the table of contents in toc.ncx. +#epub_tocdepth = 3 + +# Allow duplicate toc entries. +#epub_tocdup = True + +# Choose between 'default' and 'includehidden'. +#epub_tocscope = 'default' + +# Fix unsupported image types using the PIL. +#epub_fix_images = False + +# Scale large images. +#epub_max_image_width = 0 + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#epub_show_urls = 'inline' + +# If false, no index is generated. +#epub_use_index = True diff --git a/external/src/libuv/docs/src/design.rst b/external/src/libuv/docs/src/design.rst new file mode 100644 index 0000000..a23e33a --- /dev/null +++ b/external/src/libuv/docs/src/design.rst @@ -0,0 +1,140 @@ + +.. _design: + +Design overview +=============== + +libuv is cross-platform support library which was originally written for `Node.js`_. It's designed +around the event-driven asynchronous I/O model. + +.. _Node.js: https://nodejs.org + +The library provides much more than a simple abstraction over different I/O polling mechanisms: +'handles' and 'streams' provide a high level abstraction for sockets and other entities; +cross-platform file I/O and threading functionality is also provided, amongst other things. + +Here is a diagram illustrating the different parts that compose libuv and what subsystem they +relate to: + +.. image:: static/architecture.png + :scale: 75% + :align: center + + +Handles and requests +^^^^^^^^^^^^^^^^^^^^ + +libuv provides users with 2 abstractions to work with, in combination with the event loop: +handles and requests. + +Handles represent long-lived objects capable of performing certain operations while active. Some examples: + +- A prepare handle gets its callback called once every loop iteration when active. +- A TCP server handle that gets its connection callback called every time there is a new connection. + +Requests represent (typically) short-lived operations. These operations can be performed over a +handle: write requests are used to write data on a handle; or standalone: getaddrinfo requests +don't need a handle they run directly on the loop. + + +The I/O loop +^^^^^^^^^^^^ + +The I/O (or event) loop is the central part of libuv. It establishes the content for all I/O +operations, and it's meant to be tied to a single thread. One can run multiple event loops +as long as each runs in a different thread. The libuv event loop (or any other API involving +the loop or handles, for that matter) **is not thread-safe** except where stated otherwise. + +The event loop follows the rather usual single threaded asynchronous I/O approach: all (network) +I/O is performed on non-blocking sockets which are polled using the best mechanism available +on the given platform: epoll on Linux, kqueue on OSX and other BSDs, event ports on SunOS and IOCP +on Windows. As part of a loop iteration the loop will block waiting for I/O activity on sockets +which have been added to the poller and callbacks will be fired indicating socket conditions +(readable, writable hangup) so handles can read, write or perform the desired I/O operation. + +In order to better understand how the event loop operates, the following diagram illustrates all +stages of a loop iteration: + +.. image:: static/loop_iteration.png + :scale: 75% + :align: center + + +#. The loop concept of 'now' is updated. The event loop caches the current time at the start of + the event loop tick in order to reduce the number of time-related system calls. + +#. If the loop is *alive* an iteration is started, otherwise the loop will exit immediately. So, + when is a loop considered to be *alive*? If a loop has active and ref'd handles, active + requests or closing handles it's considered to be *alive*. + +#. Due timers are run. All active timers scheduled for a time before the loop's concept of *now* + get their callbacks called. + +#. Pending callbacks are called. All I/O callbacks are called right after polling for I/O, for the + most part. There are cases, however, in which calling such a callback is deferred for the next + loop iteration. If the previous iteration deferred any I/O callback it will be run at this point. + +#. Idle handle callbacks are called. Despite the unfortunate name, idle handles are run on every + loop iteration, if they are active. + +#. Prepare handle callbacks are called. Prepare handles get their callbacks called right before + the loop will block for I/O. + +#. Poll timeout is calculated. Before blocking for I/O the loop calculates for how long it should + block. These are the rules when calculating the timeout: + + * If the loop was run with the ``UV_RUN_NOWAIT`` flag, the timeout is 0. + * If the loop is going to be stopped (:c:func:`uv_stop` was called), the timeout is 0. + * If there are no active handles or requests, the timeout is 0. + * If there are any idle handles active, the timeout is 0. + * If there are any handles pending to be closed, the timeout is 0. + * If none of the above cases matches, the timeout of the closest timer is taken, or + if there are no active timers, infinity. + +#. The loop blocks for I/O. At this point the loop will block for I/O for the duration calculated + in the previous step. All I/O related handles that were monitoring a given file descriptor + for a read or write operation get their callbacks called at this point. + +#. Check handle callbacks are called. Check handles get their callbacks called right after the + loop has blocked for I/O. Check handles are essentially the counterpart of prepare handles. + +#. Close callbacks are called. If a handle was closed by calling :c:func:`uv_close` it will + get the close callback called. + +#. Special case in case the loop was run with ``UV_RUN_ONCE``, as it implies forward progress. + It's possible that no I/O callbacks were fired after blocking for I/O, but some time has passed + so there might be timers which are due, those timers get their callbacks called. + +#. Iteration ends. If the loop was run with ``UV_RUN_NOWAIT`` or ``UV_RUN_ONCE`` modes the + iteration ends and :c:func:`uv_run` will return. If the loop was run with ``UV_RUN_DEFAULT`` + it will continue from the start if it's still *alive*, otherwise it will also end. + + +.. important:: + libuv uses a thread pool to make asynchronous file I/O operations possible, but + network I/O is **always** performed in a single thread, each loop's thread. + +.. note:: + While the polling mechanism is different, libuv makes the execution model consistent + across Unix systems and Windows. + + +File I/O +^^^^^^^^ + +Unlike network I/O, there are no platform-specific file I/O primitives libuv could rely on, +so the current approach is to run blocking file I/O operations in a thread pool. + +For a thorough explanation of the cross-platform file I/O landscape, checkout +`this post `_. + +libuv currently uses a global thread pool on which all loops can queue work. 3 types of +operations are currently run on this pool: + + * File system operations + * DNS functions (getaddrinfo and getnameinfo) + * User specified code via :c:func:`uv_queue_work` + +.. warning:: + See the :c:ref:`threadpool` section for more details, but keep in mind the thread pool size + is quite limited. diff --git a/external/src/libuv/docs/src/dll.rst b/external/src/libuv/docs/src/dll.rst new file mode 100644 index 0000000..fb13f90 --- /dev/null +++ b/external/src/libuv/docs/src/dll.rst @@ -0,0 +1,44 @@ + +.. _dll: + +Shared library handling +======================= + +libuv provides cross platform utilities for loading shared libraries and +retrieving symbols from them, using the following API. + + +Data types +---------- + +.. c:type:: uv_lib_t + + Shared library data type. + + +Public members +^^^^^^^^^^^^^^ + +N/A + + +API +--- + +.. c:function:: int uv_dlopen(const char* filename, uv_lib_t* lib) + + Opens a shared library. The filename is in utf-8. Returns 0 on success and + -1 on error. Call :c:func:`uv_dlerror` to get the error message. + +.. c:function:: void uv_dlclose(uv_lib_t* lib) + + Close the shared library. + +.. c:function:: int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) + + Retrieves a data pointer from a dynamic library. It is legal for a symbol + to map to NULL. Returns 0 on success and -1 if the symbol was not found. + +.. c:function:: const char* uv_dlerror(const uv_lib_t* lib) + + Returns the last uv_dlopen() or uv_dlsym() error message. diff --git a/external/src/libuv/docs/src/dns.rst b/external/src/libuv/docs/src/dns.rst new file mode 100644 index 0000000..1d88158 --- /dev/null +++ b/external/src/libuv/docs/src/dns.rst @@ -0,0 +1,108 @@ + +.. _dns: + +DNS utility functions +===================== + +libuv provides asynchronous variants of `getaddrinfo` and `getnameinfo`. + + +Data types +---------- + +.. c:type:: uv_getaddrinfo_t + + `getaddrinfo` request type. + +.. c:type:: void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req, int status, struct addrinfo* res) + + Callback which will be called with the getaddrinfo request result once + complete. In case it was cancelled, `status` will have a value of + ``UV_ECANCELED``. + +.. c:type:: uv_getnameinfo_t + + `getnameinfo` request type. + +.. c:type:: void (*uv_getnameinfo_cb)(uv_getnameinfo_t* req, int status, const char* hostname, const char* service) + + Callback which will be called with the getnameinfo request result once + complete. In case it was cancelled, `status` will have a value of + ``UV_ECANCELED``. + + +Public members +^^^^^^^^^^^^^^ + +.. c:member:: uv_loop_t* uv_getaddrinfo_t.loop + + Loop that started this getaddrinfo request and where completion will be + reported. Readonly. + +.. c:member:: struct addrinfo* uv_getaddrinfo_t.addrinfo + + Pointer to a `struct addrinfo` containing the result. Must be freed by the user + with :c:func:`uv_freeaddrinfo`. + + .. versionchanged:: 1.3.0 the field is declared as public. + +.. c:member:: uv_loop_t* uv_getnameinfo_t.loop + + Loop that started this getnameinfo request and where completion will be + reported. Readonly. + +.. c:member:: char[NI_MAXHOST] uv_getnameinfo_t.host + + Char array containing the resulting host. It's null terminated. + + .. versionchanged:: 1.3.0 the field is declared as public. + +.. c:member:: char[NI_MAXSERV] uv_getnameinfo_t.service + + Char array containing the resulting service. It's null terminated. + + .. versionchanged:: 1.3.0 the field is declared as public. + +.. seealso:: The :c:type:`uv_req_t` members also apply. + + +API +--- + +.. c:function:: int uv_getaddrinfo(uv_loop_t* loop, uv_getaddrinfo_t* req, uv_getaddrinfo_cb getaddrinfo_cb, const char* node, const char* service, const struct addrinfo* hints) + + Asynchronous :man:`getaddrinfo(3)`. + + Either node or service may be NULL but not both. + + `hints` is a pointer to a struct addrinfo with additional address type + constraints, or NULL. Consult `man -s 3 getaddrinfo` for more details. + + Returns 0 on success or an error code < 0 on failure. If successful, the + callback will get called sometime in the future with the lookup result, + which is either: + + * status == 0, the res argument points to a valid `struct addrinfo`, or + * status < 0, the res argument is NULL. See the UV_EAI_* constants. + + Call :c:func:`uv_freeaddrinfo` to free the addrinfo structure. + + .. versionchanged:: 1.3.0 the callback parameter is now allowed to be NULL, + in which case the request will run **synchronously**. + +.. c:function:: void uv_freeaddrinfo(struct addrinfo* ai) + + Free the struct addrinfo. Passing NULL is allowed and is a no-op. + +.. c:function:: int uv_getnameinfo(uv_loop_t* loop, uv_getnameinfo_t* req, uv_getnameinfo_cb getnameinfo_cb, const struct sockaddr* addr, int flags) + + Asynchronous :man:`getnameinfo(3)`. + + Returns 0 on success or an error code < 0 on failure. If successful, the + callback will get called sometime in the future with the lookup result. + Consult `man -s 3 getnameinfo` for more details. + + .. versionchanged:: 1.3.0 the callback parameter is now allowed to be NULL, + in which case the request will run **synchronously**. + +.. seealso:: The :c:type:`uv_req_t` API functions also apply. diff --git a/external/src/libuv/docs/src/errors.rst b/external/src/libuv/docs/src/errors.rst new file mode 100644 index 0000000..c7240f3 --- /dev/null +++ b/external/src/libuv/docs/src/errors.rst @@ -0,0 +1,385 @@ + +.. _errors: + +Error handling +============== + +In libuv errors are negative numbered constants. As a rule of thumb, whenever +there is a status parameter, or an API functions returns an integer, a negative +number will imply an error. + +When a function which takes a callback returns an error, the callback will never +be called. + +.. note:: + Implementation detail: on Unix error codes are the negated `errno` (or `-errno`), while on + Windows they are defined by libuv to arbitrary negative numbers. + + +Error constants +--------------- + +.. c:macro:: UV_E2BIG + + argument list too long + +.. c:macro:: UV_EACCES + + permission denied + +.. c:macro:: UV_EADDRINUSE + + address already in use + +.. c:macro:: UV_EADDRNOTAVAIL + + address not available + +.. c:macro:: UV_EAFNOSUPPORT + + address family not supported + +.. c:macro:: UV_EAGAIN + + resource temporarily unavailable + +.. c:macro:: UV_EAI_ADDRFAMILY + + address family not supported + +.. c:macro:: UV_EAI_AGAIN + + temporary failure + +.. c:macro:: UV_EAI_BADFLAGS + + bad ai_flags value + +.. c:macro:: UV_EAI_BADHINTS + + invalid value for hints + +.. c:macro:: UV_EAI_CANCELED + + request canceled + +.. c:macro:: UV_EAI_FAIL + + permanent failure + +.. c:macro:: UV_EAI_FAMILY + + ai_family not supported + +.. c:macro:: UV_EAI_MEMORY + + out of memory + +.. c:macro:: UV_EAI_NODATA + + no address + +.. c:macro:: UV_EAI_NONAME + + unknown node or service + +.. c:macro:: UV_EAI_OVERFLOW + + argument buffer overflow + +.. c:macro:: UV_EAI_PROTOCOL + + resolved protocol is unknown + +.. c:macro:: UV_EAI_SERVICE + + service not available for socket type + +.. c:macro:: UV_EAI_SOCKTYPE + + socket type not supported + +.. c:macro:: UV_EALREADY + + connection already in progress + +.. c:macro:: UV_EBADF + + bad file descriptor + +.. c:macro:: UV_EBUSY + + resource busy or locked + +.. c:macro:: UV_ECANCELED + + operation canceled + +.. c:macro:: UV_ECHARSET + + invalid Unicode character + +.. c:macro:: UV_ECONNABORTED + + software caused connection abort + +.. c:macro:: UV_ECONNREFUSED + + connection refused + +.. c:macro:: UV_ECONNRESET + + connection reset by peer + +.. c:macro:: UV_EDESTADDRREQ + + destination address required + +.. c:macro:: UV_EEXIST + + file already exists + +.. c:macro:: UV_EFAULT + + bad address in system call argument + +.. c:macro:: UV_EFBIG + + file too large + +.. c:macro:: UV_EHOSTUNREACH + + host is unreachable + +.. c:macro:: UV_EINTR + + interrupted system call + +.. c:macro:: UV_EINVAL + + invalid argument + +.. c:macro:: UV_EIO + + i/o error + +.. c:macro:: UV_EISCONN + + socket is already connected + +.. c:macro:: UV_EISDIR + + illegal operation on a directory + +.. c:macro:: UV_ELOOP + + too many symbolic links encountered + +.. c:macro:: UV_EMFILE + + too many open files + +.. c:macro:: UV_EMSGSIZE + + message too long + +.. c:macro:: UV_ENAMETOOLONG + + name too long + +.. c:macro:: UV_ENETDOWN + + network is down + +.. c:macro:: UV_ENETUNREACH + + network is unreachable + +.. c:macro:: UV_ENFILE + + file table overflow + +.. c:macro:: UV_ENOBUFS + + no buffer space available + +.. c:macro:: UV_ENODEV + + no such device + +.. c:macro:: UV_ENOENT + + no such file or directory + +.. c:macro:: UV_ENOMEM + + not enough memory + +.. c:macro:: UV_ENONET + + machine is not on the network + +.. c:macro:: UV_ENOPROTOOPT + + protocol not available + +.. c:macro:: UV_ENOSPC + + no space left on device + +.. c:macro:: UV_ENOSYS + + function not implemented + +.. c:macro:: UV_ENOTCONN + + socket is not connected + +.. c:macro:: UV_ENOTDIR + + not a directory + +.. c:macro:: UV_ENOTEMPTY + + directory not empty + +.. c:macro:: UV_ENOTSOCK + + socket operation on non-socket + +.. c:macro:: UV_ENOTSUP + + operation not supported on socket + +.. c:macro:: UV_EOVERFLOW + + value too large for defined data type + +.. c:macro:: UV_EPERM + + operation not permitted + +.. c:macro:: UV_EPIPE + + broken pipe + +.. c:macro:: UV_EPROTO + + protocol error + +.. c:macro:: UV_EPROTONOSUPPORT + + protocol not supported + +.. c:macro:: UV_EPROTOTYPE + + protocol wrong type for socket + +.. c:macro:: UV_ERANGE + + result too large + +.. c:macro:: UV_EROFS + + read-only file system + +.. c:macro:: UV_ESHUTDOWN + + cannot send after transport endpoint shutdown + +.. c:macro:: UV_ESPIPE + + invalid seek + +.. c:macro:: UV_ESRCH + + no such process + +.. c:macro:: UV_ETIMEDOUT + + connection timed out + +.. c:macro:: UV_ETXTBSY + + text file is busy + +.. c:macro:: UV_EXDEV + + cross-device link not permitted + +.. c:macro:: UV_UNKNOWN + + unknown error + +.. c:macro:: UV_EOF + + end of file + +.. c:macro:: UV_ENXIO + + no such device or address + +.. c:macro:: UV_EMLINK + + too many links + +.. c:macro:: UV_ENOTTY + + inappropriate ioctl for device + +.. c:macro:: UV_EFTYPE + + inappropriate file type or format + +.. c:macro:: UV_EILSEQ + + illegal byte sequence + +.. c:macro:: UV_ESOCKTNOSUPPORT + + socket type not supported + + +API +--- + +.. c:macro:: UV_ERRNO_MAP(iter_macro) + + Macro that expands to a series of invocations of `iter_macro` for + each of the error constants above. `iter_macro` is invoked with two + arguments: the name of the error constant without the `UV_` prefix, + and the error message string literal. + +.. c:function:: const char* uv_strerror(int err) + + Returns the error message for the given error code. Leaks a few bytes + of memory when you call it with an unknown error code. + +.. c:function:: char* uv_strerror_r(int err, char* buf, size_t buflen) + + Returns the error message for the given error code. The zero-terminated + message is stored in the user-supplied buffer `buf` of at most `buflen` bytes. + + .. versionadded:: 1.22.0 + +.. c:function:: const char* uv_err_name(int err) + + Returns the error name for the given error code. Leaks a few bytes + of memory when you call it with an unknown error code. + +.. c:function:: char* uv_err_name_r(int err, char* buf, size_t buflen) + + Returns the error name for the given error code. The zero-terminated + name is stored in the user-supplied buffer `buf` of at most `buflen` bytes. + + .. versionadded:: 1.22.0 + +.. c:function:: int uv_translate_sys_error(int sys_errno) + + Returns the libuv error code equivalent to the given platform dependent error + code: POSIX error codes on Unix (the ones stored in `errno`), and Win32 error + codes on Windows (those returned by `GetLastError()` or `WSAGetLastError()`). + + If `sys_errno` is already a libuv error, it is simply returned. + + .. versionchanged:: 1.10.0 function declared public. diff --git a/external/src/libuv/docs/src/fs.rst b/external/src/libuv/docs/src/fs.rst new file mode 100644 index 0000000..0bf2abe --- /dev/null +++ b/external/src/libuv/docs/src/fs.rst @@ -0,0 +1,702 @@ + +.. _fs: + +File system operations +====================== + +libuv provides a wide variety of cross-platform sync and async file system +operations. All functions defined in this document take a callback, which is +allowed to be NULL. If the callback is NULL the request is completed synchronously, +otherwise it will be performed asynchronously. + +All file operations are run on the threadpool. See :ref:`threadpool` for information +on the threadpool size. + +.. note:: + On Windows `uv_fs_*` functions use utf-8 encoding. + +Data types +---------- + +.. c:type:: uv_fs_t + + File system request type. + +.. c:type:: uv_timespec_t + + Portable equivalent of ``struct timespec``. + + :: + + typedef struct { + long tv_sec; + long tv_nsec; + } uv_timespec_t; + +.. c:type:: uv_stat_t + + Portable equivalent of ``struct stat``. + + :: + + typedef struct { + uint64_t st_dev; + uint64_t st_mode; + uint64_t st_nlink; + uint64_t st_uid; + uint64_t st_gid; + uint64_t st_rdev; + uint64_t st_ino; + uint64_t st_size; + uint64_t st_blksize; + uint64_t st_blocks; + uint64_t st_flags; + uint64_t st_gen; + uv_timespec_t st_atim; + uv_timespec_t st_mtim; + uv_timespec_t st_ctim; + uv_timespec_t st_birthtim; + } uv_stat_t; + +.. c:enum:: uv_fs_type + + File system request type. + + :: + + typedef enum { + UV_FS_UNKNOWN = -1, + UV_FS_CUSTOM, + UV_FS_OPEN, + UV_FS_CLOSE, + UV_FS_READ, + UV_FS_WRITE, + UV_FS_SENDFILE, + UV_FS_STAT, + UV_FS_LSTAT, + UV_FS_FSTAT, + UV_FS_FTRUNCATE, + UV_FS_UTIME, + UV_FS_FUTIME, + UV_FS_ACCESS, + UV_FS_CHMOD, + UV_FS_FCHMOD, + UV_FS_FSYNC, + UV_FS_FDATASYNC, + UV_FS_UNLINK, + UV_FS_RMDIR, + UV_FS_MKDIR, + UV_FS_MKDTEMP, + UV_FS_RENAME, + UV_FS_SCANDIR, + UV_FS_LINK, + UV_FS_SYMLINK, + UV_FS_READLINK, + UV_FS_CHOWN, + UV_FS_FCHOWN, + UV_FS_REALPATH, + UV_FS_COPYFILE, + UV_FS_LCHOWN, + UV_FS_OPENDIR, + UV_FS_READDIR, + UV_FS_CLOSEDIR, + UV_FS_MKSTEMP, + UV_FS_LUTIME + } uv_fs_type; + +.. c:type:: uv_statfs_t + + Reduced cross platform equivalent of ``struct statfs``. + Used in :c:func:`uv_fs_statfs`. + + :: + + typedef struct uv_statfs_s { + uint64_t f_type; + uint64_t f_bsize; + uint64_t f_blocks; + uint64_t f_bfree; + uint64_t f_bavail; + uint64_t f_files; + uint64_t f_ffree; + uint64_t f_spare[4]; + } uv_statfs_t; + +.. c:enum:: uv_dirent_t + + Cross platform (reduced) equivalent of ``struct dirent``. + Used in :c:func:`uv_fs_scandir_next`. + + :: + + typedef enum { + UV_DIRENT_UNKNOWN, + UV_DIRENT_FILE, + UV_DIRENT_DIR, + UV_DIRENT_LINK, + UV_DIRENT_FIFO, + UV_DIRENT_SOCKET, + UV_DIRENT_CHAR, + UV_DIRENT_BLOCK + } uv_dirent_type_t; + + typedef struct uv_dirent_s { + const char* name; + uv_dirent_type_t type; + } uv_dirent_t; + +.. c:type:: uv_dir_t + + Data type used for streaming directory iteration. + Used by :c:func:`uv_fs_opendir()`, :c:func:`uv_fs_readdir()`, and + :c:func:`uv_fs_closedir()`. `dirents` represents a user provided array of + `uv_dirent_t`s used to hold results. `nentries` is the user provided maximum + array size of `dirents`. + + :: + + typedef struct uv_dir_s { + uv_dirent_t* dirents; + size_t nentries; + } uv_dir_t; + + +Public members +^^^^^^^^^^^^^^ + +.. c:member:: uv_loop_t* uv_fs_t.loop + + Loop that started this request and where completion will be reported. + Readonly. + +.. c:member:: uv_fs_type uv_fs_t.fs_type + + FS request type. + +.. c:member:: const char* uv_fs_t.path + + Path affecting the request. + +.. c:member:: ssize_t uv_fs_t.result + + Result of the request. < 0 means error, success otherwise. On requests such + as :c:func:`uv_fs_read` or :c:func:`uv_fs_write` it indicates the amount of + data that was read or written, respectively. + +.. c:member:: uv_stat_t uv_fs_t.statbuf + + Stores the result of :c:func:`uv_fs_stat` and other stat requests. + +.. c:member:: void* uv_fs_t.ptr + + Stores the result of :c:func:`uv_fs_readlink` and + :c:func:`uv_fs_realpath` and serves as an alias to `statbuf`. + +.. seealso:: The :c:type:`uv_req_t` members also apply. + + +API +--- + +.. c:function:: void uv_fs_req_cleanup(uv_fs_t* req) + + Cleanup request. Must be called after a request is finished to deallocate + any memory libuv might have allocated. + +.. c:function:: int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) + + Equivalent to :man:`close(2)`. + +.. c:function:: int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb) + + Equivalent to :man:`open(2)`. + + .. note:: + On Windows libuv uses `CreateFileW` and thus the file is always opened + in binary mode. Because of this the O_BINARY and O_TEXT flags are not + supported. + +.. c:function:: int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb) + + Equivalent to :man:`preadv(2)`. + + .. warning:: + On Windows, under non-MSVC environments (e.g. when GCC or Clang is used + to build libuv), files opened using ``UV_FS_O_FILEMAP`` may cause a fatal + crash if the memory mapped read operation fails. + +.. c:function:: int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) + + Equivalent to :man:`unlink(2)`. + +.. c:function:: int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb) + + Equivalent to :man:`pwritev(2)`. + + .. warning:: + On Windows, under non-MSVC environments (e.g. when GCC or Clang is used + to build libuv), files opened using ``UV_FS_O_FILEMAP`` may cause a fatal + crash if the memory mapped write operation fails. + +.. c:function:: int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) + + Equivalent to :man:`mkdir(2)`. + + .. note:: + `mode` is currently not implemented on Windows. + +.. c:function:: int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb) + + Equivalent to :man:`mkdtemp(3)`. The result can be found as a null terminated string at `req->path`. + +.. c:function:: int uv_fs_mkstemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb) + + Equivalent to :man:`mkstemp(3)`. The created file path can be found as a null terminated string at `req->path`. + The file descriptor can be found as an integer at `req->result`. + + .. versionadded:: 1.34.0 + +.. c:function:: int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) + + Equivalent to :man:`rmdir(2)`. + +.. c:function:: int uv_fs_opendir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) + + Opens `path` as a directory stream. On success, a `uv_dir_t` is allocated + and returned via `req->ptr`. This memory is not freed by + `uv_fs_req_cleanup()`, although `req->ptr` is set to `NULL`. The allocated + memory must be freed by calling `uv_fs_closedir()`. On failure, no memory + is allocated. + + The contents of the directory can be iterated over by passing the resulting + `uv_dir_t` to `uv_fs_readdir()`. + + .. versionadded:: 1.28.0 + +.. c:function:: int uv_fs_closedir(uv_loop_t* loop, uv_fs_t* req, uv_dir_t* dir, uv_fs_cb cb) + + Closes the directory stream represented by `dir` and frees the memory + allocated by `uv_fs_opendir()`. + + .. versionadded:: 1.28.0 + +.. c:function:: int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, uv_dir_t* dir, uv_fs_cb cb) + + Iterates over the directory stream, `dir`, returned by a successful + `uv_fs_opendir()` call. Prior to invoking `uv_fs_readdir()`, the caller + must set `dir->dirents` and `dir->nentries`, representing the array of + :c:type:`uv_dirent_t` elements used to hold the read directory entries and + its size. + + On success, the result is an integer >= 0 representing the number of entries + read from the stream. + + .. versionadded:: 1.28.0 + + .. warning:: + `uv_fs_readdir()` is not thread safe. + + .. note:: + This function does not return the "." and ".." entries. + + .. note:: + On success this function allocates memory that must be freed using + `uv_fs_req_cleanup()`. `uv_fs_req_cleanup()` must be called before + closing the directory with `uv_fs_closedir()`. + +.. c:function:: int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) +.. c:function:: int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) + + Equivalent to :man:`scandir(3)`, with a slightly different API. Once the callback + for the request is called, the user can use :c:func:`uv_fs_scandir_next` to + get `ent` populated with the next directory entry data. When there are no + more entries ``UV_EOF`` will be returned. + + .. note:: + Unlike `scandir(3)`, this function does not return the "." and ".." entries. + + .. note:: + On Linux, getting the type of an entry is only supported by some file systems (btrfs, ext2, + ext3 and ext4 at the time of this writing), check the :man:`getdents(2)` man page. + +.. c:function:: int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) +.. c:function:: int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) +.. c:function:: int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) + + Equivalent to :man:`stat(2)`, :man:`fstat(2)` and :man:`lstat(2)` respectively. + +.. c:function:: int uv_fs_statfs(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) + + Equivalent to :man:`statfs(2)`. On success, a `uv_statfs_t` is allocated + and returned via `req->ptr`. This memory is freed by `uv_fs_req_cleanup()`. + + .. note:: + Any fields in the resulting `uv_statfs_t` that are not supported by the + underlying operating system are set to zero. + + .. versionadded:: 1.31.0 + +.. c:function:: int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) + + Equivalent to :man:`rename(2)`. + +.. c:function:: int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) + + Equivalent to :man:`fsync(2)`. + + .. note:: + For AIX, `uv_fs_fsync` returns `UV_EBADF` on file descriptors referencing + non regular files. + +.. c:function:: int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) + + Equivalent to :man:`fdatasync(2)`. + +.. c:function:: int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, int64_t offset, uv_fs_cb cb) + + Equivalent to :man:`ftruncate(2)`. + +.. c:function:: int uv_fs_copyfile(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb) + + Copies a file from `path` to `new_path`. Supported `flags` are described below. + + - `UV_FS_COPYFILE_EXCL`: If present, `uv_fs_copyfile()` will fail with + `UV_EEXIST` if the destination path already exists. The default behavior + is to overwrite the destination if it exists. + - `UV_FS_COPYFILE_FICLONE`: If present, `uv_fs_copyfile()` will attempt to + create a copy-on-write reflink. If the underlying platform does not + support copy-on-write, or an error occurs while attempting to use + copy-on-write, a fallback copy mechanism based on + :c:func:`uv_fs_sendfile()` is used. + - `UV_FS_COPYFILE_FICLONE_FORCE`: If present, `uv_fs_copyfile()` will + attempt to create a copy-on-write reflink. If the underlying platform does + not support copy-on-write, or an error occurs while attempting to use + copy-on-write, then an error is returned. + + .. warning:: + If the destination path is created, but an error occurs while copying + the data, then the destination path is removed. There is a brief window + of time between closing and removing the file where another process + could access the file. + + .. versionadded:: 1.14.0 + + .. versionchanged:: 1.20.0 `UV_FS_COPYFILE_FICLONE` and + `UV_FS_COPYFILE_FICLONE_FORCE` are supported. + + .. versionchanged:: 1.33.0 If an error occurs while using + `UV_FS_COPYFILE_FICLONE_FORCE`, that error is returned. Previously, + all errors were mapped to `UV_ENOTSUP`. + +.. c:function:: int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb) + + Limited equivalent to :man:`sendfile(2)`. + +.. c:function:: int uv_fs_access(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) + + Equivalent to :man:`access(2)` on Unix. Windows uses ``GetFileAttributesW()``. + +.. c:function:: int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) +.. c:function:: int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb) + + Equivalent to :man:`chmod(2)` and :man:`fchmod(2)` respectively. + +.. c:function:: int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb) +.. c:function:: int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb) +.. c:function:: int uv_fs_lutime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb) + + Equivalent to :man:`utime(2)`, :man:`futimes(3)` and :man:`lutimes(3)` respectively. + + .. note:: + z/OS: `uv_fs_lutime()` is not implemented for z/OS. It can still be called but will return + ``UV_ENOSYS``. + + .. note:: + AIX: `uv_fs_futime()` and `uv_fs_lutime()` functions only work for AIX 7.1 and newer. + They can still be called on older versions but will return ``UV_ENOSYS``. + + .. versionchanged:: 1.10.0 sub-second precission is supported on Windows + +.. c:function:: int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) + + Equivalent to :man:`link(2)`. + +.. c:function:: int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb) + + Equivalent to :man:`symlink(2)`. + + .. note:: + On Windows the `flags` parameter can be specified to control how the symlink will + be created: + + * ``UV_FS_SYMLINK_DIR``: indicates that `path` points to a directory. + + * ``UV_FS_SYMLINK_JUNCTION``: request that the symlink is created + using junction points. + +.. c:function:: int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) + + Equivalent to :man:`readlink(2)`. + The resulting string is stored in `req->ptr`. + +.. c:function:: int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) + + Equivalent to :man:`realpath(3)` on Unix. Windows uses `GetFinalPathNameByHandle `_. + The resulting string is stored in `req->ptr`. + + .. warning:: + This function has certain platform-specific caveats that were discovered when used in Node. + + * macOS and other BSDs: this function will fail with UV_ELOOP if more than 32 symlinks are + found while resolving the given path. This limit is hardcoded and cannot be sidestepped. + * Windows: while this function works in the common case, there are a number of corner cases + where it doesn't: + + - Paths in ramdisk volumes created by tools which sidestep the Volume Manager (such as ImDisk) + cannot be resolved. + - Inconsistent casing when using drive letters. + - Resolved path bypasses subst'd drives. + + While this function can still be used, it's not recommended if scenarios such as the + above need to be supported. + + The background story and some more details on these issues can be checked + `here `_. + + .. note:: + This function is not implemented on Windows XP and Windows Server 2003. + On these systems, UV_ENOSYS is returned. + + .. versionadded:: 1.8.0 + +.. c:function:: int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb) +.. c:function:: int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb) +.. c:function:: int uv_fs_lchown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb) + + Equivalent to :man:`chown(2)`, :man:`fchown(2)` and :man:`lchown(2)` respectively. + + .. note:: + These functions are not implemented on Windows. + + .. versionchanged:: 1.21.0 implemented uv_fs_lchown + +.. c:function:: uv_fs_type uv_fs_get_type(const uv_fs_t* req) + + Returns `req->fs_type`. + + .. versionadded:: 1.19.0 + +.. c:function:: ssize_t uv_fs_get_result(const uv_fs_t* req) + + Returns `req->result`. + + .. versionadded:: 1.19.0 + +.. c:function:: int uv_fs_get_system_error(const uv_fs_t* req) + + Returns the platform specific error code - `GetLastError()` value on Windows + and `-(req->result)` on other platforms. + + .. versionadded:: 1.38.0 + +.. c:function:: void* uv_fs_get_ptr(const uv_fs_t* req) + + Returns `req->ptr`. + + .. versionadded:: 1.19.0 + +.. c:function:: const char* uv_fs_get_path(const uv_fs_t* req) + + Returns `req->path`. + + .. versionadded:: 1.19.0 + +.. c:function:: uv_stat_t* uv_fs_get_statbuf(uv_fs_t* req) + + Returns `&req->statbuf`. + + .. versionadded:: 1.19.0 + +.. seealso:: The :c:type:`uv_req_t` API functions also apply. + +Helper functions +---------------- + +.. c:function:: uv_os_fd_t uv_get_osfhandle(int fd) + + For a file descriptor in the C runtime, get the OS-dependent handle. + On UNIX, returns the ``fd`` intact. On Windows, this calls `_get_osfhandle `_. + Note that the return value is still owned by the C runtime, + any attempts to close it or to use it after closing the fd may lead to malfunction. + + .. versionadded:: 1.12.0 + +.. c:function:: int uv_open_osfhandle(uv_os_fd_t os_fd) + + For a OS-dependent handle, get the file descriptor in the C runtime. + On UNIX, returns the ``os_fd`` intact. On Windows, this calls `_open_osfhandle `_. + Note that this consumes the argument, any attempts to close it or to use it + after closing the return value may lead to malfunction. + + .. versionadded:: 1.23.0 + +File open constants +------------------- + +.. c:macro:: UV_FS_O_APPEND + + The file is opened in append mode. Before each write, the file offset is + positioned at the end of the file. + +.. c:macro:: UV_FS_O_CREAT + + The file is created if it does not already exist. + +.. c:macro:: UV_FS_O_DIRECT + + File I/O is done directly to and from user-space buffers, which must be + aligned. Buffer size and address should be a multiple of the physical sector + size of the block device. + + .. note:: + `UV_FS_O_DIRECT` is supported on Linux, and on Windows via + `FILE_FLAG_NO_BUFFERING `_. + `UV_FS_O_DIRECT` is not supported on macOS. + +.. c:macro:: UV_FS_O_DIRECTORY + + If the path is not a directory, fail the open. + + .. note:: + `UV_FS_O_DIRECTORY` is not supported on Windows. + +.. c:macro:: UV_FS_O_DSYNC + + The file is opened for synchronous I/O. Write operations will complete once + all data and a minimum of metadata are flushed to disk. + + .. note:: + `UV_FS_O_DSYNC` is supported on Windows via + `FILE_FLAG_WRITE_THROUGH `_. + +.. c:macro:: UV_FS_O_EXCL + + If the `O_CREAT` flag is set and the file already exists, fail the open. + + .. note:: + In general, the behavior of `O_EXCL` is undefined if it is used without + `O_CREAT`. There is one exception: on Linux 2.6 and later, `O_EXCL` can + be used without `O_CREAT` if pathname refers to a block device. If the + block device is in use by the system (e.g., mounted), the open will fail + with the error `EBUSY`. + +.. c:macro:: UV_FS_O_EXLOCK + + Atomically obtain an exclusive lock. + + .. note:: + `UV_FS_O_EXLOCK` is only supported on macOS and Windows. + + .. versionchanged:: 1.17.0 support is added for Windows. + +.. c:macro:: UV_FS_O_FILEMAP + + Use a memory file mapping to access the file. When using this flag, the + file cannot be open multiple times concurrently. + + .. note:: + `UV_FS_O_FILEMAP` is only supported on Windows. + +.. c:macro:: UV_FS_O_NOATIME + + Do not update the file access time when the file is read. + + .. note:: + `UV_FS_O_NOATIME` is not supported on Windows. + +.. c:macro:: UV_FS_O_NOCTTY + + If the path identifies a terminal device, opening the path will not cause + that terminal to become the controlling terminal for the process (if the + process does not already have one). + + .. note:: + `UV_FS_O_NOCTTY` is not supported on Windows. + +.. c:macro:: UV_FS_O_NOFOLLOW + + If the path is a symbolic link, fail the open. + + .. note:: + `UV_FS_O_NOFOLLOW` is not supported on Windows. + +.. c:macro:: UV_FS_O_NONBLOCK + + Open the file in nonblocking mode if possible. + + .. note:: + `UV_FS_O_NONBLOCK` is not supported on Windows. + +.. c:macro:: UV_FS_O_RANDOM + + Access is intended to be random. The system can use this as a hint to + optimize file caching. + + .. note:: + `UV_FS_O_RANDOM` is only supported on Windows via + `FILE_FLAG_RANDOM_ACCESS `_. + +.. c:macro:: UV_FS_O_RDONLY + + Open the file for read-only access. + +.. c:macro:: UV_FS_O_RDWR + + Open the file for read-write access. + +.. c:macro:: UV_FS_O_SEQUENTIAL + + Access is intended to be sequential from beginning to end. The system can + use this as a hint to optimize file caching. + + .. note:: + `UV_FS_O_SEQUENTIAL` is only supported on Windows via + `FILE_FLAG_SEQUENTIAL_SCAN `_. + +.. c:macro:: UV_FS_O_SHORT_LIVED + + The file is temporary and should not be flushed to disk if possible. + + .. note:: + `UV_FS_O_SHORT_LIVED` is only supported on Windows via + `FILE_ATTRIBUTE_TEMPORARY `_. + +.. c:macro:: UV_FS_O_SYMLINK + + Open the symbolic link itself rather than the resource it points to. + +.. c:macro:: UV_FS_O_SYNC + + The file is opened for synchronous I/O. Write operations will complete once + all data and all metadata are flushed to disk. + + .. note:: + `UV_FS_O_SYNC` is supported on Windows via + `FILE_FLAG_WRITE_THROUGH `_. + +.. c:macro:: UV_FS_O_TEMPORARY + + The file is temporary and should not be flushed to disk if possible. + + .. note:: + `UV_FS_O_TEMPORARY` is only supported on Windows via + `FILE_ATTRIBUTE_TEMPORARY `_. + +.. c:macro:: UV_FS_O_TRUNC + + If the file exists and is a regular file, and the file is opened + successfully for write access, its length shall be truncated to zero. + +.. c:macro:: UV_FS_O_WRONLY + + Open the file for write-only access. diff --git a/external/src/libuv/docs/src/fs_event.rst b/external/src/libuv/docs/src/fs_event.rst new file mode 100644 index 0000000..e28ec62 --- /dev/null +++ b/external/src/libuv/docs/src/fs_event.rst @@ -0,0 +1,132 @@ + +.. _fs_event: + +:c:type:`uv_fs_event_t` --- FS Event handle +=========================================== + +FS Event handles allow the user to monitor a given path for changes, for example, +if the file was renamed or there was a generic change in it. This handle uses +the best backend for the job on each platform. + +.. note:: + For AIX, the non default IBM bos.ahafs package has to be installed. + The AIX Event Infrastructure file system (ahafs) has some limitations: + + - ahafs tracks monitoring per process and is not thread safe. A separate process + must be spawned for each monitor for the same event. + - Events for file modification (writing to a file) are not received if only the + containing folder is watched. + + See documentation_ for more details. + + The z/OS file system events monitoring infrastructure does not notify of file + creation/deletion within a directory that is being monitored. + See the `IBM Knowledge centre`_ for more details. + + .. _documentation: https://developer.ibm.com/articles/au-aix_event_infrastructure/ + .. _`IBM Knowledge centre`: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.2.0/com.ibm.zos.v2r1.bpxb100/ioc.htm + + + + +Data types +---------- + +.. c:type:: uv_fs_event_t + + FS Event handle type. + +.. c:type:: void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename, int events, int status) + + Callback passed to :c:func:`uv_fs_event_start` which will be called repeatedly + after the handle is started. If the handle was started with a directory the + `filename` parameter will be a relative path to a file contained in the directory. + The `events` parameter is an ORed mask of :c:type:`uv_fs_event` elements. + +.. c:type:: uv_fs_event + + Event types that :c:type:`uv_fs_event_t` handles monitor. + + :: + + enum uv_fs_event { + UV_RENAME = 1, + UV_CHANGE = 2 + }; + +.. c:type:: uv_fs_event_flags + + Flags that can be passed to :c:func:`uv_fs_event_start` to control its + behavior. + + :: + + enum uv_fs_event_flags { + /* + * By default, if the fs event watcher is given a directory name, we will + * watch for all events in that directory. This flags overrides this behavior + * and makes fs_event report only changes to the directory entry itself. This + * flag does not affect individual files watched. + * This flag is currently not implemented yet on any backend. + */ + UV_FS_EVENT_WATCH_ENTRY = 1, + /* + * By default uv_fs_event will try to use a kernel interface such as inotify + * or kqueue to detect events. This may not work on remote file systems such + * as NFS mounts. This flag makes fs_event fall back to calling stat() on a + * regular interval. + * This flag is currently not implemented yet on any backend. + */ + UV_FS_EVENT_STAT = 2, + /* + * By default, event watcher, when watching directory, is not registering + * (is ignoring) changes in its subdirectories. + * This flag will override this behaviour on platforms that support it. + */ + UV_FS_EVENT_RECURSIVE = 4 + }; + + +Public members +^^^^^^^^^^^^^^ + +N/A + +.. seealso:: The :c:type:`uv_handle_t` members also apply. + + +API +--- + +.. c:function:: int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) + + Initialize the handle. + +.. c:function:: int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* path, unsigned int flags) + + Start the handle with the given callback, which will watch the specified + `path` for changes. `flags` can be an ORed mask of :c:type:`uv_fs_event_flags`. + + .. note:: Currently the only supported flag is ``UV_FS_EVENT_RECURSIVE`` and + only on OSX and Windows. + +.. c:function:: int uv_fs_event_stop(uv_fs_event_t* handle) + + Stop the handle, the callback will no longer be called. + +.. c:function:: int uv_fs_event_getpath(uv_fs_event_t* handle, char* buffer, size_t* size) + + Get the path being monitored by the handle. The buffer must be preallocated + by the user. Returns 0 on success or an error code < 0 in case of failure. + On success, `buffer` will contain the path and `size` its length. If the buffer + is not big enough `UV_ENOBUFS` will be returned and `size` will be set to + the required size, including the null terminator. + + .. versionchanged:: 1.3.0 the returned length no longer includes the terminating null byte, + and the buffer is not null terminated. + + .. versionchanged:: 1.9.0 the returned length includes the terminating null + byte on `UV_ENOBUFS`, and the buffer is null terminated + on success. + +.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/external/src/libuv/docs/src/fs_poll.rst b/external/src/libuv/docs/src/fs_poll.rst new file mode 100644 index 0000000..2912bad --- /dev/null +++ b/external/src/libuv/docs/src/fs_poll.rst @@ -0,0 +1,77 @@ + +.. _fs_poll: + +:c:type:`uv_fs_poll_t` --- FS Poll handle +========================================= + +FS Poll handles allow the user to monitor a given path for changes. Unlike +:c:type:`uv_fs_event_t`, fs poll handles use `stat` to detect when a file has +changed so they can work on file systems where fs event handles can't. + + +Data types +---------- + +.. c:type:: uv_fs_poll_t + + FS Poll handle type. + +.. c:type:: void (*uv_fs_poll_cb)(uv_fs_poll_t* handle, int status, const uv_stat_t* prev, const uv_stat_t* curr) + + Callback passed to :c:func:`uv_fs_poll_start` which will be called repeatedly + after the handle is started, when any change happens to the monitored path. + + The callback is invoked with `status < 0` if `path` does not exist + or is inaccessible. The watcher is *not* stopped but your callback is + not called again until something changes (e.g. when the file is created + or the error reason changes). + + When `status == 0`, the callback receives pointers to the old and new + :c:type:`uv_stat_t` structs. They are valid for the duration of the + callback only. + + +Public members +^^^^^^^^^^^^^^ + +N/A + +.. seealso:: The :c:type:`uv_handle_t` members also apply. + + +API +--- + +.. c:function:: int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle) + + Initialize the handle. + +.. c:function:: int uv_fs_poll_start(uv_fs_poll_t* handle, uv_fs_poll_cb poll_cb, const char* path, unsigned int interval) + + Check the file at `path` for changes every `interval` milliseconds. + + .. note:: + For maximum portability, use multi-second intervals. Sub-second intervals will not detect + all changes on many file systems. + +.. c:function:: int uv_fs_poll_stop(uv_fs_poll_t* handle) + + Stop the handle, the callback will no longer be called. + +.. c:function:: int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buffer, size_t* size) + + Get the path being monitored by the handle. The buffer must be preallocated + by the user. Returns 0 on success or an error code < 0 in case of failure. + On success, `buffer` will contain the path and `size` its length. If the buffer + is not big enough `UV_ENOBUFS` will be returned and `size` will be set to + the required size. + + .. versionchanged:: 1.3.0 the returned length no longer includes the terminating null byte, + and the buffer is not null terminated. + + .. versionchanged:: 1.9.0 the returned length includes the terminating null + byte on `UV_ENOBUFS`, and the buffer is null terminated + on success. + + +.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/external/src/libuv/docs/src/guide.rst b/external/src/libuv/docs/src/guide.rst new file mode 100644 index 0000000..126e080 --- /dev/null +++ b/external/src/libuv/docs/src/guide.rst @@ -0,0 +1,22 @@ +.. _guide: + +User guide +========== + +.. warning:: + The contents of this guide have been recently incorporated into the libuv documentation + and it hasn't gone through thorough review yet. If you spot a mistake please file an + issue, or better yet, open a pull request! + +.. toctree:: + :maxdepth: 2 + + guide/introduction + guide/basics + guide/filesystem + guide/networking + guide/threads + guide/processes + guide/eventloops + guide/utilities + guide/about diff --git a/external/src/libuv/docs/src/guide/about.rst b/external/src/libuv/docs/src/guide/about.rst new file mode 100644 index 0000000..731d1a4 --- /dev/null +++ b/external/src/libuv/docs/src/guide/about.rst @@ -0,0 +1,22 @@ +About +===== + +`Nikhil Marathe `_ started writing this book one +afternoon (June 16, 2012) when he didn't feel like programming. He had recently +been stung by the lack of good documentation on libuv while working on +`node-taglib `_. Although reference +documentation was present, there were no comprehensive tutorials. This book is +the output of that need and tries to be accurate. That said, the book may have +mistakes. Pull requests are encouraged. + +Nikhil is indebted to Marc Lehmann's comprehensive `man page +`_ about libev which +describes much of the semantics of the two libraries. + +This book was made using `Sphinx `_ and `vim +`_. + +.. note:: + In 2017 the libuv project incorporated the Nikhil's work into the official + documentation and it's maintained there henceforth. + diff --git a/external/src/libuv/docs/src/guide/basics.rst b/external/src/libuv/docs/src/guide/basics.rst new file mode 100644 index 0000000..457fb15 --- /dev/null +++ b/external/src/libuv/docs/src/guide/basics.rst @@ -0,0 +1,221 @@ +Basics of libuv +=============== + +libuv enforces an **asynchronous**, **event-driven** style of programming. Its +core job is to provide an event loop and callback based notifications of I/O +and other activities. libuv offers core utilities like timers, non-blocking +networking support, asynchronous file system access, child processes and more. + +Event loops +----------- + +In event-driven programming, an application expresses interest in certain events +and respond to them when they occur. The responsibility of gathering events +from the operating system or monitoring other sources of events is handled by +libuv, and the user can register callbacks to be invoked when an event occurs. +The event-loop usually keeps running *forever*. In pseudocode: + +.. code-block:: python + + while there are still events to process: + e = get the next event + if there is a callback associated with e: + call the callback + +Some examples of events are: + +* File is ready for writing +* A socket has data ready to be read +* A timer has timed out + +This event loop is encapsulated by ``uv_run()`` -- the end-all function when using +libuv. + +The most common activity of systems programs is to deal with input and output, +rather than a lot of number-crunching. The problem with using conventional +input/output functions (``read``, ``fprintf``, etc.) is that they are +**blocking**. The actual write to a hard disk or reading from a network, takes +a disproportionately long time compared to the speed of the processor. The +functions don't return until the task is done, so that your program is doing +nothing. For programs which require high performance this is a major roadblock +as other activities and other I/O operations are kept waiting. + +One of the standard solutions is to use threads. Each blocking I/O operation is +started in a separate thread (or in a thread pool). When the blocking function +gets invoked in the thread, the operating system can schedule another thread to run, +which actually needs the CPU. + +The approach followed by libuv uses another style, which is the **asynchronous, +non-blocking** style. Most modern operating systems provide event notification +subsystems. For example, a normal ``read`` call on a socket would block until +the sender actually sent something. Instead, the application can request the +operating system to watch the socket and put an event notification in the +queue. The application can inspect the events at its convenience (perhaps doing +some number crunching before to use the processor to the maximum) and grab the +data. It is **asynchronous** because the application expressed interest at one +point, then used the data at another point (in time and space). It is +**non-blocking** because the application process was free to do other tasks. +This fits in well with libuv's event-loop approach, since the operating system +events can be treated as just another libuv event. The non-blocking ensures +that other events can continue to be handled as fast as they come in [#]_. + +.. NOTE:: + + How the I/O is run in the background is not of our concern, but due to the + way our computer hardware works, with the thread as the basic unit of the + processor, libuv and OSes will usually run background/worker threads and/or + polling to perform tasks in a non-blocking manner. + +Bert Belder, one of the libuv core developers has a small video explaining the +architecture of libuv and its background. If you have no prior experience with +either libuv or libev, it is a quick, useful watch. + +libuv's event loop is explained in more detail in the `documentation +`_. + +.. raw:: html + + + +Hello World +----------- + +With the basics out of the way, let's write our first libuv program. It does +nothing, except start a loop which will exit immediately. + +.. rubric:: helloworld/main.c +.. literalinclude:: ../../code/helloworld/main.c + :language: c + :linenos: + +This program quits immediately because it has no events to process. A libuv +event loop has to be told to watch out for events using the various API +functions. + +Starting with libuv v1.0, users should allocate the memory for the loops before +initializing it with ``uv_loop_init(uv_loop_t *)``. This allows you to plug in +custom memory management. Remember to de-initialize the loop using +``uv_loop_close(uv_loop_t *)`` and then delete the storage. The examples never +close loops since the program quits after the loop ends and the system will +reclaim memory. Production grade projects, especially long running systems +programs, should take care to release correctly. + +Default loop +++++++++++++ + +A default loop is provided by libuv and can be accessed using +``uv_default_loop()``. You should use this loop if you only want a single +loop. + +.. note:: + + node.js uses the default loop as its main loop. If you are writing bindings + you should be aware of this. + +.. _libuv-error-handling: + +Error handling +-------------- + +Initialization functions or synchronous functions which may fail return a negative number on error. Async functions that may fail will pass a status parameter to their callbacks. The error messages are defined as ``UV_E*`` `constants`_. + +.. _constants: http://docs.libuv.org/en/v1.x/errors.html#error-constants + +You can use the ``uv_strerror(int)`` and ``uv_err_name(int)`` functions +to get a ``const char *`` describing the error or the error name respectively. + +I/O read callbacks (such as for files and sockets) are passed a parameter ``nread``. If ``nread`` is less than 0, there was an error (UV_EOF is the end of file error, which you may want to handle differently). + +Handles and Requests +-------------------- + +libuv works by the user expressing interest in particular events. This is +usually done by creating a **handle** to an I/O device, timer or process. +Handles are opaque structs named as ``uv_TYPE_t`` where type signifies what the +handle is used for. + +.. rubric:: libuv watchers +.. code-block:: c + + /* Handle types. */ + typedef struct uv_loop_s uv_loop_t; + typedef struct uv_handle_s uv_handle_t; + typedef struct uv_dir_s uv_dir_t; + typedef struct uv_stream_s uv_stream_t; + typedef struct uv_tcp_s uv_tcp_t; + typedef struct uv_udp_s uv_udp_t; + typedef struct uv_pipe_s uv_pipe_t; + typedef struct uv_tty_s uv_tty_t; + typedef struct uv_poll_s uv_poll_t; + typedef struct uv_timer_s uv_timer_t; + typedef struct uv_prepare_s uv_prepare_t; + typedef struct uv_check_s uv_check_t; + typedef struct uv_idle_s uv_idle_t; + typedef struct uv_async_s uv_async_t; + typedef struct uv_process_s uv_process_t; + typedef struct uv_fs_event_s uv_fs_event_t; + typedef struct uv_fs_poll_s uv_fs_poll_t; + typedef struct uv_signal_s uv_signal_t; + + /* Request types. */ + typedef struct uv_req_s uv_req_t; + typedef struct uv_getaddrinfo_s uv_getaddrinfo_t; + typedef struct uv_getnameinfo_s uv_getnameinfo_t; + typedef struct uv_shutdown_s uv_shutdown_t; + typedef struct uv_write_s uv_write_t; + typedef struct uv_connect_s uv_connect_t; + typedef struct uv_udp_send_s uv_udp_send_t; + typedef struct uv_fs_s uv_fs_t; + typedef struct uv_work_s uv_work_t; + + +Handles represent long-lived objects. Async operations on such handles are +identified using **requests**. A request is short-lived (usually used across +only one callback) and usually indicates one I/O operation on a handle. +Requests are used to preserve context between the initiation and the callback +of individual actions. For example, an UDP socket is represented by +a ``uv_udp_t``, while individual writes to the socket use a ``uv_udp_send_t`` +structure that is passed to the callback after the write is done. + +Handles are setup by a corresponding:: + + uv_TYPE_init(uv_loop_t *, uv_TYPE_t *) + +function. + +Callbacks are functions which are called by libuv whenever an event the watcher +is interested in has taken place. Application specific logic will usually be +implemented in the callback. For example, an IO watcher's callback will receive +the data read from a file, a timer callback will be triggered on timeout and so +on. + +Idling +++++++ + +Here is an example of using an idle handle. The callback is called once on +every turn of the event loop. A use case for idle handles is discussed in +:doc:`utilities`. Let us use an idle watcher to look at the watcher life cycle +and see how ``uv_run()`` will now block because a watcher is present. The idle +watcher is stopped when the count is reached and ``uv_run()`` exits since no +event watchers are active. + +.. rubric:: idle-basic/main.c +.. literalinclude:: ../../code/idle-basic/main.c + :language: c + :emphasize-lines: 6,10,14-17 + +Storing context ++++++++++++++++ + +In callback based programming style you'll often want to pass some 'context' -- +application specific information -- between the call site and the callback. All +handles and requests have a ``void* data`` member which you can set to the +context and cast back in the callback. This is a common pattern used throughout +the C library ecosystem. In addition ``uv_loop_t`` also has a similar data +member. + +---- + +.. [#] Depending on the capacity of the hardware of course. diff --git a/external/src/libuv/docs/src/guide/eventloops.rst b/external/src/libuv/docs/src/guide/eventloops.rst new file mode 100644 index 0000000..12244ff --- /dev/null +++ b/external/src/libuv/docs/src/guide/eventloops.rst @@ -0,0 +1,50 @@ +Advanced event loops +==================== + +libuv provides considerable user control over event loops, and you can achieve +interesting results by juggling multiple loops. You can also embed libuv's +event loop into another event loop based library -- imagine a Qt based UI, and +Qt's event loop driving a libuv backend which does intensive system level +tasks. + +Stopping an event loop +~~~~~~~~~~~~~~~~~~~~~~ + +``uv_stop()`` can be used to stop an event loop. The earliest the loop will +stop running is *on the next iteration*, possibly later. This means that events +that are ready to be processed in this iteration of the loop will still be +processed, so ``uv_stop()`` can't be used as a kill switch. When ``uv_stop()`` +is called, the loop **won't** block for i/o on this iteration. The semantics of +these things can be a bit difficult to understand, so let's look at +``uv_run()`` where all the control flow occurs. + +.. rubric:: src/unix/core.c - uv_run +.. literalinclude:: ../../../src/unix/core.c + :language: c + :linenos: + :lines: 304-324 + :emphasize-lines: 10,19,21 + +``stop_flag`` is set by ``uv_stop()``. Now all libuv callbacks are invoked +within the event loop, which is why invoking ``uv_stop()`` in them will still +lead to this iteration of the loop occurring. First libuv updates timers, then +runs pending timer, idle and prepare callbacks, and invokes any pending I/O +callbacks. If you were to call ``uv_stop()`` in any of them, ``stop_flag`` +would be set. This causes ``uv_backend_timeout()`` to return ``0``, which is +why the loop does not block on I/O. If on the other hand, you called +``uv_stop()`` in one of the check handlers, I/O has already finished and is not +affected. + +``uv_stop()`` is useful to shutdown a loop when a result has been computed or +there is an error, without having to ensure that all handlers are stopped one +by one. + +Here is a simple example that stops the loop and demonstrates how the current +iteration of the loop still takes places. + +.. rubric:: uvstop/main.c +.. literalinclude:: ../../code/uvstop/main.c + :language: c + :linenos: + :emphasize-lines: 11 + diff --git a/external/src/libuv/docs/src/guide/filesystem.rst b/external/src/libuv/docs/src/guide/filesystem.rst new file mode 100644 index 0000000..2d5f6cb --- /dev/null +++ b/external/src/libuv/docs/src/guide/filesystem.rst @@ -0,0 +1,339 @@ +Filesystem +========== + +Simple filesystem read/write is achieved using the ``uv_fs_*`` functions and the +``uv_fs_t`` struct. + +.. note:: + + The libuv filesystem operations are different from :doc:`socket operations + `. Socket operations use the non-blocking operations provided + by the operating system. Filesystem operations use blocking functions + internally, but invoke these functions in a `thread pool`_ and notify + watchers registered with the event loop when application interaction is + required. + +.. _thread pool: http://docs.libuv.org/en/v1.x/threadpool.html#thread-pool-work-scheduling + +All filesystem functions have two forms - *synchronous* and *asynchronous*. + +The *synchronous* forms automatically get called (and **block**) if the +callback is null. The return value of functions is a :ref:`libuv error code +`. This is usually only useful for synchronous calls. +The *asynchronous* form is called when a callback is passed and the return +value is 0. + +Reading/Writing files +--------------------- + +A file descriptor is obtained using + +.. code-block:: c + + int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb) + +``flags`` and ``mode`` are standard +`Unix flags `_. +libuv takes care of converting to the appropriate Windows flags. + +File descriptors are closed using + +.. code-block:: c + + int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) + + +Filesystem operation callbacks have the signature: + +.. code-block:: c + + void callback(uv_fs_t* req); + +Let's see a simple implementation of ``cat``. We start with registering +a callback for when the file is opened: + +.. rubric:: uvcat/main.c - opening a file +.. literalinclude:: ../../code/uvcat/main.c + :language: c + :linenos: + :lines: 41-53 + :emphasize-lines: 4, 6-7 + +The ``result`` field of a ``uv_fs_t`` is the file descriptor in case of the +``uv_fs_open`` callback. If the file is successfully opened, we start reading it. + +.. rubric:: uvcat/main.c - read callback +.. literalinclude:: ../../code/uvcat/main.c + :language: c + :linenos: + :lines: 26-40 + :emphasize-lines: 2,8,12 + +In the case of a read call, you should pass an *initialized* buffer which will +be filled with data before the read callback is triggered. The ``uv_fs_*`` +operations map almost directly to certain POSIX functions, so EOF is indicated +in this case by ``result`` being 0. In the case of streams or pipes, the +``UV_EOF`` constant would have been passed as a status instead. + +Here you see a common pattern when writing asynchronous programs. The +``uv_fs_close()`` call is performed synchronously. *Usually tasks which are +one-off, or are done as part of the startup or shutdown stage are performed +synchronously, since we are interested in fast I/O when the program is going +about its primary task and dealing with multiple I/O sources*. For solo tasks +the performance difference usually is negligible and may lead to simpler code. + +Filesystem writing is similarly simple using ``uv_fs_write()``. *Your callback +will be triggered after the write is complete*. In our case the callback +simply drives the next read. Thus read and write proceed in lockstep via +callbacks. + +.. rubric:: uvcat/main.c - write callback +.. literalinclude:: ../../code/uvcat/main.c + :language: c + :linenos: + :lines: 16-24 + :emphasize-lines: 6 + +.. warning:: + + Due to the way filesystems and disk drives are configured for performance, + a write that 'succeeds' may not be committed to disk yet. + +We set the dominos rolling in ``main()``: + +.. rubric:: uvcat/main.c +.. literalinclude:: ../../code/uvcat/main.c + :language: c + :linenos: + :lines: 55- + :emphasize-lines: 2 + +.. warning:: + + The ``uv_fs_req_cleanup()`` function must always be called on filesystem + requests to free internal memory allocations in libuv. + +Filesystem operations +--------------------- + +All the standard filesystem operations like ``unlink``, ``rmdir``, ``stat`` are +supported asynchronously and have intuitive argument order. They follow the +same patterns as the read/write/open calls, returning the result in the +``uv_fs_t.result`` field. The full list: + +.. rubric:: Filesystem operations +.. code-block:: c + + int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb); + int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb); + int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb); + int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb); + int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb); + int uv_fs_copyfile(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb); + int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb); + int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb); + int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb); + int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb); + int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent); + int uv_fs_opendir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb); + int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, uv_dir_t* dir, uv_fs_cb cb); + int uv_fs_closedir(uv_loop_t* loop, uv_fs_t* req, uv_dir_t* dir, uv_fs_cb cb); + int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb); + int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb); + int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb); + int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb); + int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb); + int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, int64_t offset, uv_fs_cb cb); + int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb); + int uv_fs_access(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb); + int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb); + int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb); + int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb); + int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb); + int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb); + int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb); + int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb); + int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb); + int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb); + int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb); + int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb); + int uv_fs_lchown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb); + + +.. _buffers-and-streams: + +Buffers and Streams +------------------- + +The basic I/O handle in libuv is the stream (``uv_stream_t``). TCP sockets, UDP +sockets, and pipes for file I/O and IPC are all treated as stream subclasses. + +Streams are initialized using custom functions for each subclass, then operated +upon using + +.. code-block:: c + + int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb, uv_read_cb read_cb); + int uv_read_stop(uv_stream_t*); + int uv_write(uv_write_t* req, uv_stream_t* handle, + const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb); + +The stream based functions are simpler to use than the filesystem ones and +libuv will automatically keep reading from a stream when ``uv_read_start()`` is +called once, until ``uv_read_stop()`` is called. + +The discrete unit of data is the buffer -- ``uv_buf_t``. This is simply +a collection of a pointer to bytes (``uv_buf_t.base``) and the length +(``uv_buf_t.len``). The ``uv_buf_t`` is lightweight and passed around by value. +What does require management is the actual bytes, which have to be allocated +and freed by the application. + +.. ERROR:: + + THIS PROGRAM DOES NOT ALWAYS WORK, NEED SOMETHING BETTER** + +To demonstrate streams we will need to use ``uv_pipe_t``. This allows streaming +local files [#]_. Here is a simple tee utility using libuv. Doing all operations +asynchronously shows the power of evented I/O. The two writes won't block each +other, but we have to be careful to copy over the buffer data to ensure we don't +free a buffer until it has been written. + +The program is to be executed as:: + + ./uvtee + +We start off opening pipes on the files we require. libuv pipes to a file are +opened as bidirectional by default. + +.. rubric:: uvtee/main.c - read on pipes +.. literalinclude:: ../../code/uvtee/main.c + :language: c + :linenos: + :lines: 61-80 + :emphasize-lines: 4,5,15 + +The third argument of ``uv_pipe_init()`` should be set to 1 for IPC using named +pipes. This is covered in :doc:`processes`. The ``uv_pipe_open()`` call +associates the pipe with the file descriptor, in this case ``0`` (standard +input). + +We start monitoring ``stdin``. The ``alloc_buffer`` callback is invoked as new +buffers are required to hold incoming data. ``read_stdin`` will be called with +these buffers. + +.. rubric:: uvtee/main.c - reading buffers +.. literalinclude:: ../../code/uvtee/main.c + :language: c + :linenos: + :lines: 19-22,44-60 + +The standard ``malloc`` is sufficient here, but you can use any memory allocation +scheme. For example, node.js uses its own slab allocator which associates +buffers with V8 objects. + +The read callback ``nread`` parameter is less than 0 on any error. This error +might be EOF, in which case we close all the streams, using the generic close +function ``uv_close()`` which deals with the handle based on its internal type. +Otherwise ``nread`` is a non-negative number and we can attempt to write that +many bytes to the output streams. Finally remember that buffer allocation and +deallocation is application responsibility, so we free the data. + +The allocation callback may return a buffer with length zero if it fails to +allocate memory. In this case, the read callback is invoked with error +UV_ENOBUFS. libuv will continue to attempt to read the stream though, so you +must explicitly call ``uv_close()`` if you want to stop when allocation fails. + +The read callback may be called with ``nread = 0``, indicating that at this +point there is nothing to be read. Most applications will just ignore this. + +.. rubric:: uvtee/main.c - Write to pipe +.. literalinclude:: ../../code/uvtee/main.c + :language: c + :linenos: + :lines: 9-13,23-42 + +``write_data()`` makes a copy of the buffer obtained from read. This buffer +does not get passed through to the write callback trigged on write completion. To +get around this we wrap a write request and a buffer in ``write_req_t`` and +unwrap it in the callbacks. We make a copy so we can free the two buffers from +the two calls to ``write_data`` independently of each other. While acceptable +for a demo program like this, you'll probably want smarter memory management, +like reference counted buffers or a pool of buffers in any major application. + +.. WARNING:: + + If your program is meant to be used with other programs it may knowingly or + unknowingly be writing to a pipe. This makes it susceptible to `aborting on + receiving a SIGPIPE`_. It is a good idea to insert:: + + signal(SIGPIPE, SIG_IGN) + + in the initialization stages of your application. + +.. _aborting on receiving a SIGPIPE: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#The_special_problem_of_SIGPIPE + +File change events +------------------ + +All modern operating systems provide APIs to put watches on individual files or +directories and be informed when the files are modified. libuv wraps common +file change notification libraries [#fsnotify]_. This is one of the more +inconsistent parts of libuv. File change notification systems are themselves +extremely varied across platforms so getting everything working everywhere is +difficult. To demonstrate, I'm going to build a simple utility which runs +a command whenever any of the watched files change:: + + ./onchange [file2] ... + +The file change notification is started using ``uv_fs_event_init()``: + +.. rubric:: onchange/main.c - The setup +.. literalinclude:: ../../code/onchange/main.c + :language: c + :linenos: + :lines: 26- + :emphasize-lines: 15 + +The third argument is the actual file or directory to monitor. The last +argument, ``flags``, can be: + +.. code-block:: c + + /* + * Flags to be passed to uv_fs_event_start(). + */ + enum uv_fs_event_flags { + UV_FS_EVENT_WATCH_ENTRY = 1, + UV_FS_EVENT_STAT = 2, + UV_FS_EVENT_RECURSIVE = 4 + }; + +``UV_FS_EVENT_WATCH_ENTRY`` and ``UV_FS_EVENT_STAT`` don't do anything (yet). +``UV_FS_EVENT_RECURSIVE`` will start watching subdirectories as well on +supported platforms. + +The callback will receive the following arguments: + + #. ``uv_fs_event_t *handle`` - The handle. The ``path`` field of the handle + is the file on which the watch was set. + #. ``const char *filename`` - If a directory is being monitored, this is the + file which was changed. Only non-``null`` on Linux and Windows. May be ``null`` + even on those platforms. + #. ``int flags`` - one of ``UV_RENAME`` or ``UV_CHANGE``, or a bitwise OR of + both. + #. ``int status`` - Currently 0. + +In our example we simply print the arguments and run the command using +``system()``. + +.. rubric:: onchange/main.c - file change notification callback +.. literalinclude:: ../../code/onchange/main.c + :language: c + :linenos: + :lines: 9-24 + +---- + +.. [#fsnotify] inotify on Linux, FSEvents on Darwin, kqueue on BSDs, + ReadDirectoryChangesW on Windows, event ports on Solaris, unsupported on Cygwin +.. [#] see :ref:`pipes` diff --git a/external/src/libuv/docs/src/guide/introduction.rst b/external/src/libuv/docs/src/guide/introduction.rst new file mode 100644 index 0000000..0656e4d --- /dev/null +++ b/external/src/libuv/docs/src/guide/introduction.rst @@ -0,0 +1,75 @@ +Introduction +============ + +This 'book' is a small set of tutorials about using libuv_ as +a high performance evented I/O library which offers the same API on Windows and Unix. + +It is meant to cover the main areas of libuv, but is not a comprehensive +reference discussing every function and data structure. The `official libuv +documentation`_ may be consulted for full details. + +.. _official libuv documentation: http://docs.libuv.org/en/v1.x/ + +This book is still a work in progress, so sections may be incomplete, but +I hope you will enjoy it as it grows. + +Who this book is for +-------------------- + +If you are reading this book, you are either: + +1) a systems programmer, creating low-level programs such as daemons or network + services and clients. You have found that the event loop approach is well + suited for your application and decided to use libuv. + +2) a node.js module writer, who wants to wrap platform APIs + written in C or C++ with a set of (a)synchronous APIs that are exposed to + JavaScript. You will use libuv purely in the context of node.js. For + this you will require some other resources as the book does not cover parts + specific to v8/node.js. + +This book assumes that you are comfortable with the C programming language. + +Background +---------- + +The node.js_ project began in 2009 as a JavaScript environment decoupled +from the browser. Using Google's V8_ and Marc Lehmann's libev_, node.js +combined a model of I/O -- evented -- with a language that was well suited to +the style of programming; due to the way it had been shaped by browsers. As +node.js grew in popularity, it was important to make it work on Windows, but +libev ran only on Unix. The Windows equivalent of kernel event notification +mechanisms like kqueue or (e)poll is IOCP. libuv was an abstraction around libev +or IOCP depending on the platform, providing users an API based on libev. +In the node-v0.9.0 version of libuv `libev was removed`_. + +Since then libuv has continued to mature and become a high quality standalone +library for system programming. Users outside of node.js include Mozilla's +Rust_ programming language, and a variety_ of language bindings. + +This book and the code is based on libuv version `v1.3.0`_. + +Code +---- + +All the code from this book is included as part of the source of the book on +Github. `Clone`_/`Download`_ the book, then build libuv:: + + cd libuv + ./autogen.sh + ./configure + make + +There is no need to ``make install``. To build the examples run ``make`` in the +``code/`` directory. + +.. _Clone: https://github.com/nikhilm/uvbook +.. _Download: https://github.com/nikhilm/uvbook/downloads +.. _v1.3.0: https://github.com/libuv/libuv/tags +.. _V8: https://v8.dev +.. _libev: http://software.schmorp.de/pkg/libev.html +.. _libuv: https://github.com/libuv/libuv +.. _node.js: https://www.nodejs.org +.. _libev was removed: https://github.com/joyent/libuv/issues/485 +.. _Rust: https://www.rust-lang.org +.. _variety: https://github.com/libuv/libuv/blob/v1.x/LINKS.md diff --git a/external/src/libuv/docs/src/guide/networking.rst b/external/src/libuv/docs/src/guide/networking.rst new file mode 100644 index 0000000..dcb5643 --- /dev/null +++ b/external/src/libuv/docs/src/guide/networking.rst @@ -0,0 +1,257 @@ +Networking +========== + +Networking in libuv is not much different from directly using the BSD socket +interface, some things are easier, all are non-blocking, but the concepts stay +the same. In addition libuv offers utility functions to abstract the annoying, +repetitive and low-level tasks like setting up sockets using the BSD socket +structures, DNS lookup, and tweaking various socket parameters. + +The ``uv_tcp_t`` and ``uv_udp_t`` structures are used for network I/O. + +.. NOTE:: + + The code samples in this chapter exist to show certain libuv APIs. They are + not examples of good quality code. They leak memory and don't always close + connections properly. + +TCP +--- + +TCP is a connection oriented, stream protocol and is therefore based on the +libuv streams infrastructure. + +Server +++++++ + +Server sockets proceed by: + +1. ``uv_tcp_init`` the TCP handle. +2. ``uv_tcp_bind`` it. +3. Call ``uv_listen`` on the handle to have a callback invoked whenever a new + connection is established by a client. +4. Use ``uv_accept`` to accept the connection. +5. Use :ref:`stream operations ` to communicate with the + client. + +Here is a simple echo server + +.. rubric:: tcp-echo-server/main.c - The listen socket +.. literalinclude:: ../../code/tcp-echo-server/main.c + :language: c + :linenos: + :lines: 68- + :emphasize-lines: 4-5,7-10 + +You can see the utility function ``uv_ip4_addr`` being used to convert from +a human readable IP address, port pair to the sockaddr_in structure required by +the BSD socket APIs. The reverse can be obtained using ``uv_ip4_name``. + +.. NOTE:: + + There are ``uv_ip6_*`` analogues for the ip4 functions. + +Most of the setup functions are synchronous since they are CPU-bound. +``uv_listen`` is where we return to libuv's callback style. The second +arguments is the backlog queue -- the maximum length of queued connections. + +When a connection is initiated by clients, the callback is required to set up +a handle for the client socket and associate the handle using ``uv_accept``. +In this case we also establish interest in reading from this stream. + +.. rubric:: tcp-echo-server/main.c - Accepting the client +.. literalinclude:: ../../code/tcp-echo-server/main.c + :language: c + :linenos: + :lines: 51-66 + :emphasize-lines: 9-10 + +The remaining set of functions is very similar to the streams example and can +be found in the code. Just remember to call ``uv_close`` when the socket isn't +required. This can be done even in the ``uv_listen`` callback if you are not +interested in accepting the connection. + +Client +++++++ + +Where you do bind/listen/accept on the server, on the client side it's simply +a matter of calling ``uv_tcp_connect``. The same ``uv_connect_cb`` style +callback of ``uv_listen`` is used by ``uv_tcp_connect``. Try:: + + uv_tcp_t* socket = (uv_tcp_t*)malloc(sizeof(uv_tcp_t)); + uv_tcp_init(loop, socket); + + uv_connect_t* connect = (uv_connect_t*)malloc(sizeof(uv_connect_t)); + + struct sockaddr_in dest; + uv_ip4_addr("127.0.0.1", 80, &dest); + + uv_tcp_connect(connect, socket, (const struct sockaddr*)&dest, on_connect); + +where ``on_connect`` will be called after the connection is established. The +callback receives the ``uv_connect_t`` struct, which has a member ``.handle`` +pointing to the socket. + +UDP +--- + +The `User Datagram Protocol`_ offers connectionless, unreliable network +communication. Hence libuv doesn't offer a stream. Instead libuv provides +non-blocking UDP support via the `uv_udp_t` handle (for receiving) and +`uv_udp_send_t` request (for sending) and related functions. That said, the +actual API for reading/writing is very similar to normal stream reads. To look +at how UDP can be used, the example shows the first stage of obtaining an IP +address from a `DHCP`_ server -- DHCP Discover. + +.. note:: + + You will have to run `udp-dhcp` as **root** since it uses well known port + numbers below 1024. + +.. rubric:: udp-dhcp/main.c - Setup and send UDP packets +.. literalinclude:: ../../code/udp-dhcp/main.c + :language: c + :linenos: + :lines: 7-11,104- + :emphasize-lines: 8,10-11,17-18,21 + +.. note:: + + The IP address ``0.0.0.0`` is used to bind to all interfaces. The IP + address ``255.255.255.255`` is a broadcast address meaning that packets + will be sent to all interfaces on the subnet. port ``0`` means that the OS + randomly assigns a port. + +First we setup the receiving socket to bind on all interfaces on port 68 (DHCP +client) and start a read on it. This will read back responses from any DHCP +server that replies. We use the UV_UDP_REUSEADDR flag to play nice with any +other system DHCP clients that are running on this computer on the same port. +Then we setup a similar send socket and use ``uv_udp_send`` to send +a *broadcast message* on port 67 (DHCP server). + +It is **necessary** to set the broadcast flag, otherwise you will get an +``EACCES`` error [#]_. The exact message being sent is not relevant to this +book and you can study the code if you are interested. As usual the read and +write callbacks will receive a status code of < 0 if something went wrong. + +Since UDP sockets are not connected to a particular peer, the read callback +receives an extra parameter about the sender of the packet. + +``nread`` may be zero if there is no more data to be read. If ``addr`` is NULL, +it indicates there is nothing to read (the callback shouldn't do anything), if +not NULL, it indicates that an empty datagram was received from the host at +``addr``. The ``flags`` parameter may be ``UV_UDP_PARTIAL`` if the buffer +provided by your allocator was not large enough to hold the data. *In this case +the OS will discard the data that could not fit* (That's UDP for you!). + +.. rubric:: udp-dhcp/main.c - Reading packets +.. literalinclude:: ../../code/udp-dhcp/main.c + :language: c + :linenos: + :lines: 17-40 + :emphasize-lines: 1,23 + +UDP Options ++++++++++++ + +Time-to-live +~~~~~~~~~~~~ + +The TTL of packets sent on the socket can be changed using ``uv_udp_set_ttl``. + +IPv6 stack only +~~~~~~~~~~~~~~~ + +IPv6 sockets can be used for both IPv4 and IPv6 communication. If you want to +restrict the socket to IPv6 only, pass the ``UV_UDP_IPV6ONLY`` flag to +``uv_udp_bind`` [#]_. + +Multicast +~~~~~~~~~ + +A socket can (un)subscribe to a multicast group using: + +.. code::block:: c + + int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr, const char* interface_addr, uv_membership membership); + +where ``membership`` is ``UV_JOIN_GROUP`` or ``UV_LEAVE_GROUP``. + +The concepts of multicasting are nicely explained in `this guide`_. + +.. _this guide: https://www.tldp.org/HOWTO/Multicast-HOWTO-2.html + +Local loopback of multicast packets is enabled by default [#]_, use +``uv_udp_set_multicast_loop`` to switch it off. + +The packet time-to-live for multicast packets can be changed using +``uv_udp_set_multicast_ttl``. + +Querying DNS +------------ + +libuv provides asynchronous DNS resolution. For this it provides its own +``getaddrinfo`` replacement [#]_. In the callback you can +perform normal socket operations on the retrieved addresses. Let's connect to +Libera.chat to see an example of DNS resolution. + +.. rubric:: dns/main.c +.. literalinclude:: ../../code/dns/main.c + :language: c + :linenos: + :lines: 61- + :emphasize-lines: 12 + +If ``uv_getaddrinfo`` returns non-zero, something went wrong in the setup and +your callback won't be invoked at all. All arguments can be freed immediately +after ``uv_getaddrinfo`` returns. The `hostname`, `servname` and `hints` +structures are documented in `the getaddrinfo man page `_. The +callback can be ``NULL`` in which case the function will run synchronously. + +In the resolver callback, you can pick any IP from the linked list of ``struct +addrinfo(s)``. This also demonstrates ``uv_tcp_connect``. It is necessary to +call ``uv_freeaddrinfo`` in the callback. + +.. rubric:: dns/main.c +.. literalinclude:: ../../code/dns/main.c + :language: c + :linenos: + :lines: 42-60 + :emphasize-lines: 8,16 + +libuv also provides the inverse `uv_getnameinfo`_. + +.. _uv_getnameinfo: http://docs.libuv.org/en/v1.x/dns.html#c.uv_getnameinfo + +Network interfaces +------------------ + +Information about the system's network interfaces can be obtained through libuv +using ``uv_interface_addresses``. This simple program just prints out all the +interface details so you get an idea of the fields that are available. This is +useful to allow your service to bind to IP addresses when it starts. + +.. rubric:: interfaces/main.c +.. literalinclude:: ../../code/interfaces/main.c + :language: c + :linenos: + :emphasize-lines: 9,17 + +``is_internal`` is true for loopback interfaces. Note that if a physical +interface has multiple IPv4/IPv6 addresses, the name will be reported multiple +times, with each address being reported once. + +.. _c-ares: https://c-ares.haxx.se +.. _getaddrinfo: https://man7.org/linux/man-pages/man3/getaddrinfo.3.html + +.. _User Datagram Protocol: https://en.wikipedia.org/wiki/User_Datagram_Protocol +.. _DHCP: https://tools.ietf.org/html/rfc2131 + +---- + +.. [#] https://beej.us/guide/bgnet/html/#broadcast-packetshello-world +.. [#] on Windows only supported on Windows Vista and later. +.. [#] https://www.tldp.org/HOWTO/Multicast-HOWTO-6.html#ss6.1 +.. [#] libuv use the system ``getaddrinfo`` in the libuv threadpool. libuv + v0.8.0 and earlier also included c-ares_ as an alternative, but this has been + removed in v0.9.0. diff --git a/external/src/libuv/docs/src/guide/processes.rst b/external/src/libuv/docs/src/guide/processes.rst new file mode 100644 index 0000000..c1278f1 --- /dev/null +++ b/external/src/libuv/docs/src/guide/processes.rst @@ -0,0 +1,421 @@ +Processes +========= + +libuv offers considerable child process management, abstracting the platform +differences and allowing communication with the child process using streams or +named pipes. + +A common idiom in Unix is for every process to do one thing and do it well. In +such a case, a process often uses multiple child processes to achieve tasks +(similar to using pipes in shells). A multi-process model with messages +may also be easier to reason about compared to one with threads and shared +memory. + +A common refrain against event-based programs is that they cannot take +advantage of multiple cores in modern computers. In a multi-threaded program +the kernel can perform scheduling and assign different threads to different +cores, improving performance. But an event loop has only one thread. The +workaround can be to launch multiple processes instead, with each process +running an event loop, and each process getting assigned to a separate CPU +core. + +Spawning child processes +------------------------ + +The simplest case is when you simply want to launch a process and know when it +exits. This is achieved using ``uv_spawn``. + +.. rubric:: spawn/main.c +.. literalinclude:: ../../code/spawn/main.c + :language: c + :linenos: + :lines: 6-8,15- + :emphasize-lines: 11,13-17 + +.. NOTE:: + + ``options`` is implicitly initialized with zeros since it is a global + variable. If you change ``options`` to a local variable, remember to + initialize it to null out all unused fields:: + + uv_process_options_t options = {0}; + +The ``uv_process_t`` struct only acts as the handle, all options are set via +``uv_process_options_t``. To simply launch a process, you need to set only the +``file`` and ``args`` fields. ``file`` is the program to execute. Since +``uv_spawn`` uses :man:`execvp(3)` internally, there is no need to supply the full +path. Finally as per underlying conventions, **the arguments array has to be +one larger than the number of arguments, with the last element being NULL**. + +After the call to ``uv_spawn``, ``uv_process_t.pid`` will contain the process +ID of the child process. + +The exit callback will be invoked with the *exit status* and the type of *signal* +which caused the exit. + +.. rubric:: spawn/main.c +.. literalinclude:: ../../code/spawn/main.c + :language: c + :linenos: + :lines: 9-12 + :emphasize-lines: 3 + +It is **required** to close the process watcher after the process exits. + +Changing process parameters +--------------------------- + +Before the child process is launched you can control the execution environment +using fields in ``uv_process_options_t``. + +Change execution directory +++++++++++++++++++++++++++ + +Set ``uv_process_options_t.cwd`` to the corresponding directory. + +Set environment variables ++++++++++++++++++++++++++ + +``uv_process_options_t.env`` is a null-terminated array of strings, each of the +form ``VAR=VALUE`` used to set up the environment variables for the process. Set +this to ``NULL`` to inherit the environment from the parent (this) process. + +Option flags +++++++++++++ + +Setting ``uv_process_options_t.flags`` to a bitwise OR of the following flags, +modifies the child process behaviour: + +* ``UV_PROCESS_SETUID`` - sets the child's execution user ID to ``uv_process_options_t.uid``. +* ``UV_PROCESS_SETGID`` - sets the child's execution group ID to ``uv_process_options_t.gid``. + +Changing the UID/GID is only supported on Unix, ``uv_spawn`` will fail on +Windows with ``UV_ENOTSUP``. + +* ``UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS`` - No quoting or escaping of + ``uv_process_options_t.args`` is done on Windows. Ignored on Unix. +* ``UV_PROCESS_DETACHED`` - Starts the child process in a new session, which + will keep running after the parent process exits. See example below. + +Detaching processes +------------------- + +Passing the flag ``UV_PROCESS_DETACHED`` can be used to launch daemons, or +child processes which are independent of the parent so that the parent exiting +does not affect it. + +.. rubric:: detach/main.c +.. literalinclude:: ../../code/detach/main.c + :language: c + :linenos: + :lines: 9-30 + :emphasize-lines: 12,19 + +Just remember that the handle is still monitoring the child, so your program +won't exit. Use ``uv_unref()`` if you want to be more *fire-and-forget*. + +Sending signals to processes +---------------------------- + +libuv wraps the standard ``kill(2)`` system call on Unix and implements one +with similar semantics on Windows, with *one caveat*: all of ``SIGTERM``, +``SIGINT`` and ``SIGKILL``, lead to termination of the process. The signature +of ``uv_kill`` is:: + + uv_err_t uv_kill(int pid, int signum); + +For processes started using libuv, you may use ``uv_process_kill`` instead, +which accepts the ``uv_process_t`` watcher as the first argument, rather than +the pid. In this case, **remember to call** ``uv_close`` on the watcher. + +Signals +------- + +libuv provides wrappers around Unix signals with `some Windows support +`_ as well. + +Use ``uv_signal_init()`` to initialize +a handle and associate it with a loop. To listen for particular signals on +that handler, use ``uv_signal_start()`` with the handler function. Each handler +can only be associated with one signal number, with subsequent calls to +``uv_signal_start()`` overwriting earlier associations. Use ``uv_signal_stop()`` to +stop watching. Here is a small example demonstrating the various possibilities: + +.. rubric:: signal/main.c +.. literalinclude:: ../../code/signal/main.c + :language: c + :linenos: + :emphasize-lines: 17-18,27-28 + +.. NOTE:: + + ``uv_run(loop, UV_RUN_NOWAIT)`` is similar to ``uv_run(loop, UV_RUN_ONCE)`` + in that it will process only one event. UV_RUN_ONCE blocks if there are no + pending events, while UV_RUN_NOWAIT will return immediately. We use NOWAIT + so that one of the loops isn't starved because the other one has no pending + activity. + +Send ``SIGUSR1`` to the process, and you'll find the handler being invoked +4 times, one for each ``uv_signal_t``. The handler just stops each handle, +so that the program exits. This sort of dispatch to all handlers is very +useful. A server using multiple event loops could ensure that all data was +safely saved before termination, simply by every loop adding a watcher for +``SIGINT``. + +Child Process I/O +----------------- + +A normal, newly spawned process has its own set of file descriptors, with 0, +1 and 2 being ``stdin``, ``stdout`` and ``stderr`` respectively. Sometimes you +may want to share file descriptors with the child. For example, perhaps your +applications launches a sub-command and you want any errors to go in the log +file, but ignore ``stdout``. For this you'd like to have ``stderr`` of the +child be the same as the stderr of the parent. In this case, libuv supports +*inheriting* file descriptors. In this sample, we invoke the test program, +which is: + +.. rubric:: proc-streams/test.c +.. literalinclude:: ../../code/proc-streams/test.c + :language: c + +The actual program ``proc-streams`` runs this while sharing only ``stderr``. +The file descriptors of the child process are set using the ``stdio`` field in +``uv_process_options_t``. First set the ``stdio_count`` field to the number of +file descriptors being set. ``uv_process_options_t.stdio`` is an array of +``uv_stdio_container_t``, which is: + +.. code-block:: c + + typedef struct uv_stdio_container_s { + uv_stdio_flags flags; + + union { + uv_stream_t* stream; + int fd; + } data; + } uv_stdio_container_t; + +where flags can have several values. Use ``UV_IGNORE`` if it isn't going to be +used. If the first three ``stdio`` fields are marked as ``UV_IGNORE`` they'll +redirect to ``/dev/null``. + +Since we want to pass on an existing descriptor, we'll use ``UV_INHERIT_FD``. +Then we set the ``fd`` to ``stderr``. + +.. rubric:: proc-streams/main.c +.. literalinclude:: ../../code/proc-streams/main.c + :language: c + :linenos: + :lines: 15-17,27- + :emphasize-lines: 6,10,11,12 + +If you run ``proc-stream`` you'll see that only the line "This is stderr" will +be displayed. Try marking ``stdout`` as being inherited and see the output. + +It is dead simple to apply this redirection to streams. By setting ``flags`` +to ``UV_INHERIT_STREAM`` and setting ``data.stream`` to the stream in the +parent process, the child process can treat that stream as standard I/O. This +can be used to implement something like CGI_. + +.. _CGI: https://en.wikipedia.org/wiki/Common_Gateway_Interface + +A sample CGI script/executable is: + +.. rubric:: cgi/tick.c +.. literalinclude:: ../../code/cgi/tick.c + :language: c + +The CGI server combines the concepts from this chapter and :doc:`networking` so +that every client is sent ten ticks after which that connection is closed. + +.. rubric:: cgi/main.c +.. literalinclude:: ../../code/cgi/main.c + :language: c + :linenos: + :lines: 49-63 + :emphasize-lines: 10 + +Here we simply accept the TCP connection and pass on the socket (*stream*) to +``invoke_cgi_script``. + +.. rubric:: cgi/main.c +.. literalinclude:: ../../code/cgi/main.c + :language: c + :linenos: + :lines: 16, 25-45 + :emphasize-lines: 8-9,18,20 + +The ``stdout`` of the CGI script is set to the socket so that whatever our tick +script prints, gets sent to the client. By using processes, we can offload the +read/write buffering to the operating system, so in terms of convenience this +is great. Just be warned that creating processes is a costly task. + +.. _pipes: + +Parent-child IPC +---------------- + +A parent and child can have one or two way communication over a pipe created by +settings ``uv_stdio_container_t.flags`` to a bit-wise combination of +``UV_CREATE_PIPE`` and ``UV_READABLE_PIPE`` or ``UV_WRITABLE_PIPE``. The +read/write flag is from the perspective of the child process. In this case, +the ``uv_stream_t* stream`` field must be set to point to an initialized, +unopened ``uv_pipe_t`` instance. + +New stdio Pipes ++++++++++++++++ + +The ``uv_pipe_t`` structure represents more than just `pipe(7)`_ (or ``|``), +but supports any streaming file-like objects. On Windows, the only object of +that description is the `Named Pipe`_. On Unix, this could be any of `Unix +Domain Socket`_, or derived from `mkfifo(1)`_, or it could actually be a +`pipe(7)`_. When ``uv_spawn`` initializes a ``uv_pipe_t`` due to the +`UV_CREATE_PIPE` flag, it opts for creating a `socketpair(2)`_. + +This is intended for the purpose of allowing multiple libuv processes to +communicate with IPC. This is discussed below. + +.. _pipe(7): https://man7.org/linux/man-pages/man7/pipe.7.html +.. _mkfifo(1): https://man7.org/linux/man-pages/man1/mkfifo.1.html +.. _socketpair(2): https://man7.org/linux/man-pages/man2/socketpair.2.html +.. _Unix Domain Socket: https://man7.org/linux/man-pages/man7/unix.7.html +.. _Named Pipe: https://docs.microsoft.com/en-us/windows/win32/ipc/named-pipes + + +Arbitrary process IPC ++++++++++++++++++++++ + +Since domain sockets [#]_ can have a well known name and a location in the +file-system they can be used for IPC between unrelated processes. The D-BUS_ +system used by open source desktop environments uses domain sockets for event +notification. Various applications can then react when a contact comes online +or new hardware is detected. The MySQL server also runs a domain socket on +which clients can interact with it. + +.. _D-BUS: https://www.freedesktop.org/wiki/Software/dbus + +When using domain sockets, a client-server pattern is usually followed with the +creator/owner of the socket acting as the server. After the initial setup, +messaging is no different from TCP, so we'll re-use the echo server example. + +.. rubric:: pipe-echo-server/main.c +.. literalinclude:: ../../code/pipe-echo-server/main.c + :language: c + :linenos: + :lines: 70- + :emphasize-lines: 5,10,14 + +We name the socket ``echo.sock`` which means it will be created in the local +directory. This socket now behaves no different from TCP sockets as far as +the stream API is concerned. You can test this server using `socat`_:: + + $ socat - /path/to/socket + +A client which wants to connect to a domain socket will use:: + + void uv_pipe_connect(uv_connect_t *req, uv_pipe_t *handle, const char *name, uv_connect_cb cb); + +where ``name`` will be ``echo.sock`` or similar. On Unix systems, ``name`` must +point to a valid file (e.g. ``/tmp/echo.sock``). On Windows, ``name`` follows a +``\\?\pipe\echo.sock`` format. + +.. _socat: http://www.dest-unreach.org/socat/ + +Sending file descriptors over pipes ++++++++++++++++++++++++++++++++++++ + +The cool thing about domain sockets is that file descriptors can be exchanged +between processes by sending them over a domain socket. This allows processes +to hand off their I/O to other processes. Applications include load-balancing +servers, worker processes and other ways to make optimum use of CPU. libuv only +supports sending **TCP sockets or other pipes** over pipes for now. + +To demonstrate, we will look at a echo server implementation that hands of +clients to worker processes in a round-robin fashion. This program is a bit +involved, and while only snippets are included in the book, it is recommended +to read the full code to really understand it. + +The worker process is quite simple, since the file-descriptor is handed over to +it by the master. + +.. rubric:: multi-echo-server/worker.c +.. literalinclude:: ../../code/multi-echo-server/worker.c + :language: c + :linenos: + :lines: 7-9,81- + :emphasize-lines: 6-8 + +``queue`` is the pipe connected to the master process on the other end, along +which new file descriptors get sent. It is important to set the ``ipc`` +argument of ``uv_pipe_init`` to 1 to indicate this pipe will be used for +inter-process communication! Since the master will write the file handle to the +standard input of the worker, we connect the pipe to ``stdin`` using +``uv_pipe_open``. + +.. rubric:: multi-echo-server/worker.c +.. literalinclude:: ../../code/multi-echo-server/worker.c + :language: c + :linenos: + :lines: 51-79 + :emphasize-lines: 10,15,20 + +First we call ``uv_pipe_pending_count()`` to ensure that a handle is available +to read out. If your program could deal with different types of handles, +``uv_pipe_pending_type()`` can be used to determine the type. +Although ``accept`` seems odd in this code, it actually makes sense. What +``accept`` traditionally does is get a file descriptor (the client) from +another file descriptor (The listening socket). Which is exactly what we do +here. Fetch the file descriptor (``client``) from ``queue``. From this point +the worker does standard echo server stuff. + +Turning now to the master, let's take a look at how the workers are launched to +allow load balancing. + +.. rubric:: multi-echo-server/main.c +.. literalinclude:: ../../code/multi-echo-server/main.c + :language: c + :linenos: + :lines: 9-13 + +The ``child_worker`` structure wraps the process, and the pipe between the +master and the individual process. + +.. rubric:: multi-echo-server/main.c +.. literalinclude:: ../../code/multi-echo-server/main.c + :language: c + :linenos: + :lines: 51,61-95 + :emphasize-lines: 17,20-21 + +In setting up the workers, we use the nifty libuv function ``uv_cpu_info`` to +get the number of CPUs so we can launch an equal number of workers. Again it is +important to initialize the pipe acting as the IPC channel with the third +argument as 1. We then indicate that the child process' ``stdin`` is to be +a readable pipe (from the point of view of the child). Everything is +straightforward till here. The workers are launched and waiting for file +descriptors to be written to their standard input. + +It is in ``on_new_connection`` (the TCP infrastructure is initialized in +``main()``), that we accept the client socket and pass it along to the next +worker in the round-robin. + +.. rubric:: multi-echo-server/main.c +.. literalinclude:: ../../code/multi-echo-server/main.c + :language: c + :linenos: + :lines: 31-49 + :emphasize-lines: 9,12-13 + +The ``uv_write2`` call handles all the abstraction and it is simply a matter of +passing in the handle (``client``) as the right argument. With this our +multi-process echo server is operational. + +Thanks to Kyle for `pointing out`_ that ``uv_write2()`` requires a non-empty +buffer even when sending handles. + +.. _pointing out: https://github.com/nikhilm/uvbook/issues/56 + +---- + +.. [#] In this section domain sockets stands in for named pipes on Windows as + well. diff --git a/external/src/libuv/docs/src/guide/threads.rst b/external/src/libuv/docs/src/guide/threads.rst new file mode 100644 index 0000000..3990e44 --- /dev/null +++ b/external/src/libuv/docs/src/guide/threads.rst @@ -0,0 +1,397 @@ +Threads +======= + +Wait a minute? Why are we on threads? Aren't event loops supposed to be **the +way** to do *web-scale programming*? Well... no. Threads are still the medium in +which processors do their jobs. Threads are therefore mighty useful sometimes, even +though you might have to wade through various synchronization primitives. + +Threads are used internally to fake the asynchronous nature of all of the system +calls. libuv also uses threads to allow you, the application, to perform a task +asynchronously that is actually blocking, by spawning a thread and collecting +the result when it is done. + +Today there are two predominant thread libraries: the Windows threads +implementation and POSIX's :man:`pthreads(7)`. libuv's thread API is analogous to +the pthreads API and often has similar semantics. + +A notable aspect of libuv's thread facilities is that it is a self contained +section within libuv. Whereas other features intimately depend on the event +loop and callback principles, threads are complete agnostic, they block as +required, signal errors directly via return values, and, as shown in the +:ref:`first example `, don't even require a running +event loop. + +libuv's thread API is also very limited since the semantics and syntax of +threads are different on all platforms, with different levels of completeness. + +This chapter makes the following assumption: **There is only one event loop, +running in one thread (the main thread)**. No other thread interacts +with the event loop (except using ``uv_async_send``). + +Core thread operations +---------------------- + +There isn't much here, you just start a thread using ``uv_thread_create()`` and +wait for it to close using ``uv_thread_join()``. + +.. _thread-create-example: + +.. rubric:: thread-create/main.c +.. literalinclude:: ../../code/thread-create/main.c + :language: c + :linenos: + :lines: 26-36 + :emphasize-lines: 3-7 + +.. tip:: + + ``uv_thread_t`` is just an alias for ``pthread_t`` on Unix, but this is an + implementation detail, avoid depending on it to always be true. + +The second parameter is the function which will serve as the entry point for +the thread, the last parameter is a ``void *`` argument which can be used to pass +custom parameters to the thread. The function ``hare`` will now run in a separate +thread, scheduled pre-emptively by the operating system: + +.. rubric:: thread-create/main.c +.. literalinclude:: ../../code/thread-create/main.c + :language: c + :linenos: + :lines: 6-14 + :emphasize-lines: 2 + +Unlike ``pthread_join()`` which allows the target thread to pass back a value to +the calling thread using a second parameter, ``uv_thread_join()`` does not. To +send values use :ref:`inter-thread-communication`. + +Synchronization Primitives +-------------------------- + +This section is purposely spartan. This book is not about threads, so I only +catalogue any surprises in the libuv APIs here. For the rest you can look at +the :man:`pthreads(7)` man pages. + +Mutexes +~~~~~~~ + +The mutex functions are a **direct** map to the pthread equivalents. + +.. rubric:: libuv mutex functions +.. code-block:: c + + int uv_mutex_init(uv_mutex_t* handle); + int uv_mutex_init_recursive(uv_mutex_t* handle); + void uv_mutex_destroy(uv_mutex_t* handle); + void uv_mutex_lock(uv_mutex_t* handle); + int uv_mutex_trylock(uv_mutex_t* handle); + void uv_mutex_unlock(uv_mutex_t* handle); + +The ``uv_mutex_init()``, ``uv_mutex_init_recursive()`` and ``uv_mutex_trylock()`` +functions will return 0 on success, and an error code otherwise. + +If `libuv` has been compiled with debugging enabled, ``uv_mutex_destroy()``, +``uv_mutex_lock()`` and ``uv_mutex_unlock()`` will ``abort()`` on error. +Similarly ``uv_mutex_trylock()`` will abort if the error is anything *other +than* ``EAGAIN`` or ``EBUSY``. + +Recursive mutexes are supported, but you should not rely on them. Also, they +should not be used with ``uv_cond_t`` variables. + +The default BSD mutex implementation will raise an error if a thread which has +locked a mutex attempts to lock it again. For example, a construct like:: + + uv_mutex_init(a_mutex); + uv_mutex_lock(a_mutex); + uv_thread_create(thread_id, entry, (void *)a_mutex); + uv_mutex_lock(a_mutex); + // more things here + +can be used to wait until another thread initializes some stuff and then +unlocks ``a_mutex`` but will lead to your program crashing if in debug mode, or +return an error in the second call to ``uv_mutex_lock()``. + +.. note:: + + Mutexes on Windows are always recursive. + +Locks +~~~~~ + +Read-write locks are a more granular access mechanism. Two readers can access +shared memory at the same time. A writer may not acquire the lock when it is +held by a reader. A reader or writer may not acquire a lock when a writer is +holding it. Read-write locks are frequently used in databases. Here is a toy +example. + +.. rubric:: locks/main.c - simple rwlocks +.. literalinclude:: ../../code/locks/main.c + :language: c + :linenos: + :emphasize-lines: 13,16,27,31,42,55 + +Run this and observe how the readers will sometimes overlap. In case of +multiple writers, schedulers will usually give them higher priority, so if you +add two writers, you'll see that both writers tend to finish first before the +readers get a chance again. + +We also use barriers in the above example so that the main thread can wait for +all readers and writers to indicate they have ended. + +Others +~~~~~~ + +libuv also supports semaphores_, `condition variables`_ and barriers_ with APIs +very similar to their pthread counterparts. + +.. _semaphores: https://en.wikipedia.org/wiki/Semaphore_(programming) +.. _condition variables: https://en.wikipedia.org/wiki/Monitor_(synchronization)#Condition_variables_2 +.. _barriers: https://en.wikipedia.org/wiki/Barrier_(computer_science) + +In addition, libuv provides a convenience function ``uv_once()``. Multiple +threads can attempt to call ``uv_once()`` with a given guard and a function +pointer, **only the first one will win, the function will be called once and +only once**:: + + /* Initialize guard */ + static uv_once_t once_only = UV_ONCE_INIT; + + int i = 0; + + void increment() { + i++; + } + + void thread1() { + /* ... work */ + uv_once(once_only, increment); + } + + void thread2() { + /* ... work */ + uv_once(once_only, increment); + } + + int main() { + /* ... spawn threads */ + } + +After all threads are done, ``i == 1``. + +.. _libuv-work-queue: + +libuv v0.11.11 onwards also added a ``uv_key_t`` struct and api_ for +thread-local storage. + +.. _api: http://docs.libuv.org/en/v1.x/threading.html#thread-local-storage + +libuv work queue +---------------- + +``uv_queue_work()`` is a convenience function that allows an application to run +a task in a separate thread, and have a callback that is triggered when the +task is done. A seemingly simple function, what makes ``uv_queue_work()`` +tempting is that it allows potentially any third-party libraries to be used +with the event-loop paradigm. When you use event loops, it is *imperative to +make sure that no function which runs periodically in the loop thread blocks +when performing I/O or is a serious CPU hog*, because this means that the loop +slows down and events are not being handled at full capacity. + +However, a lot of existing code out there features blocking functions (for example +a routine which performs I/O under the hood) to be used with threads if you +want responsiveness (the classic 'one thread per client' server model), and +getting them to play with an event loop library generally involves rolling your +own system of running the task in a separate thread. libuv just provides +a convenient abstraction for this. + +Here is a simple example inspired by `node.js is cancer`_. We are going to +calculate fibonacci numbers, sleeping a bit along the way, but run it in +a separate thread so that the blocking and CPU bound task does not prevent the +event loop from performing other activities. + +.. rubric:: queue-work/main.c - lazy fibonacci +.. literalinclude:: ../../code/queue-work/main.c + :language: c + :linenos: + :lines: 17-29 + +The actual task function is simple, nothing to show that it is going to be +run in a separate thread. The ``uv_work_t`` structure is the clue. You can pass +arbitrary data through it using the ``void* data`` field and use it to +communicate to and from the thread. But be sure you are using proper locks if +you are changing things while both threads may be running. + +The trigger is ``uv_queue_work``: + +.. rubric:: queue-work/main.c +.. literalinclude:: ../../code/queue-work/main.c + :language: c + :linenos: + :lines: 31-44 + :emphasize-lines: 10 + +The thread function will be launched in a separate thread, passed the +``uv_work_t`` structure and once the function returns, the *after* function +will be called on the thread the event loop is running in. It will be passed +the same structure. + +For writing wrappers to blocking libraries, a common :ref:`pattern ` +is to use a baton to exchange data. + +Since libuv version `0.9.4` an additional function, ``uv_cancel()``, is +available. This allows you to cancel tasks on the libuv work queue. Only tasks +that *are yet to be started* can be cancelled. If a task has *already started +executing, or it has finished executing*, ``uv_cancel()`` **will fail**. + +``uv_cancel()`` is useful to cleanup pending tasks if the user requests +termination. For example, a music player may queue up multiple directories to +be scanned for audio files. If the user terminates the program, it should quit +quickly and not wait until all pending requests are run. + +Let's modify the fibonacci example to demonstrate ``uv_cancel()``. We first set +up a signal handler for termination. + +.. rubric:: queue-cancel/main.c +.. literalinclude:: ../../code/queue-cancel/main.c + :language: c + :linenos: + :lines: 43- + +When the user triggers the signal by pressing ``Ctrl+C`` we send +``uv_cancel()`` to all the workers. ``uv_cancel()`` will return ``0`` for those that are already executing or finished. + +.. rubric:: queue-cancel/main.c +.. literalinclude:: ../../code/queue-cancel/main.c + :language: c + :linenos: + :lines: 33-41 + :emphasize-lines: 6 + +For tasks that do get cancelled successfully, the *after* function is called +with ``status`` set to ``UV_ECANCELED``. + +.. rubric:: queue-cancel/main.c +.. literalinclude:: ../../code/queue-cancel/main.c + :language: c + :linenos: + :lines: 28-31 + :emphasize-lines: 2 + +``uv_cancel()`` can also be used with ``uv_fs_t`` and ``uv_getaddrinfo_t`` +requests. For the filesystem family of functions, ``uv_fs_t.errorno`` will be +set to ``UV_ECANCELED``. + +.. TIP:: + + A well designed program would have a way to terminate long running workers + that have already started executing. Such a worker could periodically check + for a variable that only the main process sets to signal termination. + +.. _inter-thread-communication: + +Inter-thread communication +-------------------------- + +Sometimes you want various threads to actually send each other messages *while* +they are running. For example you might be running some long duration task in +a separate thread (perhaps using ``uv_queue_work``) but want to notify progress +to the main thread. This is a simple example of having a download manager +informing the user of the status of running downloads. + +.. rubric:: progress/main.c +.. literalinclude:: ../../code/progress/main.c + :language: c + :linenos: + :lines: 7-8,35- + :emphasize-lines: 2,11 + +The async thread communication works *on loops* so although any thread can be +the message sender, only threads with libuv loops can be receivers (or rather +the loop is the receiver). libuv will invoke the callback (``print_progress``) +with the async watcher whenever it receives a message. + +.. warning:: + + It is important to realize that since the message send is *async*, the callback + may be invoked immediately after ``uv_async_send`` is called in another + thread, or it may be invoked after some time. libuv may also combine + multiple calls to ``uv_async_send`` and invoke your callback only once. The + only guarantee that libuv makes is -- The callback function is called *at + least once* after the call to ``uv_async_send``. If you have no pending + calls to ``uv_async_send``, the callback won't be called. If you make two + or more calls, and libuv hasn't had a chance to run the callback yet, it + *may* invoke your callback *only once* for the multiple invocations of + ``uv_async_send``. Your callback will never be called twice for just one + event. + +.. rubric:: progress/main.c +.. literalinclude:: ../../code/progress/main.c + :language: c + :linenos: + :lines: 10-24 + :emphasize-lines: 7-8 + +In the download function, we modify the progress indicator and queue the message +for delivery with ``uv_async_send``. Remember: ``uv_async_send`` is also +non-blocking and will return immediately. + +.. rubric:: progress/main.c +.. literalinclude:: ../../code/progress/main.c + :language: c + :linenos: + :lines: 31-34 + +The callback is a standard libuv pattern, extracting the data from the watcher. + +Finally it is important to remember to clean up the watcher. + +.. rubric:: progress/main.c +.. literalinclude:: ../../code/progress/main.c + :language: c + :linenos: + :lines: 26-29 + :emphasize-lines: 3 + +After this example, which showed the abuse of the ``data`` field, bnoordhuis_ +pointed out that using the ``data`` field is not thread safe, and +``uv_async_send()`` is actually only meant to wake up the event loop. Use +a mutex or rwlock to ensure accesses are performed in the right order. + +.. note:: + + mutexes and rwlocks **DO NOT** work inside a signal handler, whereas + ``uv_async_send`` does. + +One use case where ``uv_async_send`` is required is when interoperating with +libraries that require thread affinity for their functionality. For example in +node.js, a v8 engine instance, contexts and its objects are bound to the thread +that the v8 instance was started in. Interacting with v8 data structures from +another thread can lead to undefined results. Now consider some node.js module +which binds a third party library. It may go something like this: + +1. In node, the third party library is set up with a JavaScript callback to be + invoked for more information:: + + var lib = require('lib'); + lib.on_progress(function() { + console.log("Progress"); + }); + + lib.do(); + + // do other stuff + +2. ``lib.do`` is supposed to be non-blocking but the third party lib is + blocking, so the binding uses ``uv_queue_work``. + +3. The actual work being done in a separate thread wants to invoke the progress + callback, but cannot directly call into v8 to interact with JavaScript. So + it uses ``uv_async_send``. + +4. The async callback, invoked in the main loop thread, which is the v8 thread, + then interacts with v8 to invoke the JavaScript callback. + +---- + +.. _node.js is cancer: http://widgetsandshit.com/teddziuba/2011/10/node-js-is-cancer.html +.. _bnoordhuis: https://github.com/bnoordhuis diff --git a/external/src/libuv/docs/src/guide/utilities.rst b/external/src/libuv/docs/src/guide/utilities.rst new file mode 100644 index 0000000..4657b1b --- /dev/null +++ b/external/src/libuv/docs/src/guide/utilities.rst @@ -0,0 +1,450 @@ +Utilities +========= + +This chapter catalogues tools and techniques which are useful for common tasks. +The `libev man page`_ already covers some patterns which can be adopted to +libuv through simple API changes. It also covers parts of the libuv API that +don't require entire chapters dedicated to them. + +Timers +------ + +Timers invoke the callback after a certain time has elapsed since the timer was +started. libuv timers can also be set to invoke at regular intervals instead of +just once. + +Simple use is to init a watcher and start it with a ``timeout``, and optional ``repeat``. +Timers can be stopped at any time. + +.. code-block:: c + + uv_timer_t timer_req; + + uv_timer_init(loop, &timer_req); + uv_timer_start(&timer_req, callback, 5000, 2000); + +will start a repeating timer, which first starts 5 seconds (the ``timeout``) after the execution +of ``uv_timer_start``, then repeats every 2 seconds (the ``repeat``). Use: + +.. code-block:: c + + uv_timer_stop(&timer_req); + +to stop the timer. This can be used safely from within the callback as well. + +The repeat interval can be modified at any time with:: + + uv_timer_set_repeat(uv_timer_t *timer, int64_t repeat); + +which will take effect **when possible**. If this function is called from +a timer callback, it means: + +* If the timer was non-repeating, the timer has already been stopped. Use + ``uv_timer_start`` again. +* If the timer is repeating, the next timeout has already been scheduled, so + the old repeat interval will be used once more before the timer switches to + the new interval. + +The utility function:: + + int uv_timer_again(uv_timer_t *) + +applies **only to repeating timers** and is equivalent to stopping the timer +and then starting it with both initial ``timeout`` and ``repeat`` set to the +old ``repeat`` value. If the timer hasn't been started it fails (error code +``UV_EINVAL``) and returns -1. + +An actual timer example is in the :ref:`reference count section +`. + +.. _reference-count: + +Event loop reference count +-------------------------- + +The event loop only runs as long as there are active handles. This system +works by having every handle increase the reference count of the event loop +when it is started and decreasing the reference count when stopped. It is also +possible to manually change the reference count of handles using:: + + void uv_ref(uv_handle_t*); + void uv_unref(uv_handle_t*); + +These functions can be used to allow a loop to exit even when a watcher is +active or to use custom objects to keep the loop alive. + +The latter can be used with interval timers. You might have a garbage collector +which runs every X seconds, or your network service might send a heartbeat to +others periodically, but you don't want to have to stop them along all clean +exit paths or error scenarios. Or you want the program to exit when all your +other watchers are done. In that case just unref the timer immediately after +creation so that if it is the only watcher running then ``uv_run`` will still +exit. + +This is also used in node.js where some libuv methods are being bubbled up to +the JS API. A ``uv_handle_t`` (the superclass of all watchers) is created per +JS object and can be ref/unrefed. + +.. rubric:: ref-timer/main.c +.. literalinclude:: ../../code/ref-timer/main.c + :language: c + :linenos: + :lines: 5-8, 17- + :emphasize-lines: 9 + +We initialize the garbage collector timer, then immediately ``unref`` it. +Observe how after 9 seconds, when the fake job is done, the program +automatically exits, even though the garbage collector is still running. + +Idler pattern +------------- + +The callbacks of idle handles are invoked once per event loop. The idle +callback can be used to perform some very low priority activity. For example, +you could dispatch a summary of the daily application performance to the +developers for analysis during periods of idleness, or use the application's +CPU time to perform SETI calculations :) An idle watcher is also useful in +a GUI application. Say you are using an event loop for a file download. If the +TCP socket is still being established and no other events are present your +event loop will pause (**block**), which means your progress bar will freeze +and the user will face an unresponsive application. In such a case queue up and +idle watcher to keep the UI operational. + +.. rubric:: idle-compute/main.c +.. literalinclude:: ../../code/idle-compute/main.c + :language: c + :linenos: + :lines: 5-9, 34- + :emphasize-lines: 13 + +Here we initialize the idle watcher and queue it up along with the actual +events we are interested in. ``crunch_away`` will now be called repeatedly +until the user types something and presses Return. Then it will be interrupted +for a brief amount as the loop deals with the input data, after which it will +keep calling the idle callback again. + +.. rubric:: idle-compute/main.c +.. literalinclude:: ../../code/idle-compute/main.c + :language: c + :linenos: + :lines: 10-19 + +.. _baton: + +Passing data to worker thread +----------------------------- + +When using ``uv_queue_work`` you'll usually need to pass complex data through +to the worker thread. The solution is to use a ``struct`` and set +``uv_work_t.data`` to point to it. A slight variation is to have the +``uv_work_t`` itself as the first member of this struct (called a baton [#]_). +This allows cleaning up the work request and all the data in one free call. + +.. code-block:: c + :linenos: + :emphasize-lines: 2 + + struct ftp_baton { + uv_work_t req; + char *host; + int port; + char *username; + char *password; + } + +.. code-block:: c + :linenos: + :emphasize-lines: 2 + + ftp_baton *baton = (ftp_baton*) malloc(sizeof(ftp_baton)); + baton->req.data = (void*) baton; + baton->host = strdup("my.webhost.com"); + baton->port = 21; + // ... + + uv_queue_work(loop, &baton->req, ftp_session, ftp_cleanup); + +Here we create the baton and queue the task. + +Now the task function can extract the data it needs: + +.. code-block:: c + :linenos: + :emphasize-lines: 2, 12 + + void ftp_session(uv_work_t *req) { + ftp_baton *baton = (ftp_baton*) req->data; + + fprintf(stderr, "Connecting to %s\n", baton->host); + } + + void ftp_cleanup(uv_work_t *req) { + ftp_baton *baton = (ftp_baton*) req->data; + + free(baton->host); + // ... + free(baton); + } + +We then free the baton which also frees the watcher. + +External I/O with polling +------------------------- + +Usually third-party libraries will handle their own I/O, and keep track of +their sockets and other files internally. In this case it isn't possible to use +the standard stream I/O operations, but the library can still be integrated +into the libuv event loop. All that is required is that the library allow you +to access the underlying file descriptors and provide functions that process +tasks in small increments as decided by your application. Some libraries though +will not allow such access, providing only a standard blocking function which +will perform the entire I/O transaction and only then return. It is unwise to +use these in the event loop thread, use the :ref:`threadpool` instead. Of +course, this will also mean losing granular control on the library. + +The ``uv_poll`` section of libuv simply watches file descriptors using the +operating system notification mechanism. In some sense, all the I/O operations +that libuv implements itself are also backed by ``uv_poll`` like code. Whenever +the OS notices a change of state in file descriptors being polled, libuv will +invoke the associated callback. + +Here we will walk through a simple download manager that will use libcurl_ to +download files. Rather than give all control to libcurl, we'll instead be +using the libuv event loop, and use the non-blocking, async multi_ interface to +progress with the download whenever libuv notifies of I/O readiness. + +.. _libcurl: https://curl.haxx.se/libcurl/ +.. _multi: https://curl.haxx.se/libcurl/c/libcurl-multi.html + +.. rubric:: uvwget/main.c - The setup +.. literalinclude:: ../../code/uvwget/main.c + :language: c + :linenos: + :lines: 1-9,140- + :emphasize-lines: 7,21,24-25 + +The way each library is integrated with libuv will vary. In the case of +libcurl, we can register two callbacks. The socket callback ``handle_socket`` +is invoked whenever the state of a socket changes and we have to start polling +it. ``start_timeout`` is called by libcurl to notify us of the next timeout +interval, after which we should drive libcurl forward regardless of I/O status. +This is so that libcurl can handle errors or do whatever else is required to +get the download moving. + +Our downloader is to be invoked as:: + + $ ./uvwget [url1] [url2] ... + +So we add each argument as an URL + +.. rubric:: uvwget/main.c - Adding urls +.. literalinclude:: ../../code/uvwget/main.c + :language: c + :linenos: + :lines: 39-56 + :emphasize-lines: 13-14 + +We let libcurl directly write the data to a file, but much more is possible if +you so desire. + +``start_timeout`` will be called immediately the first time by libcurl, so +things are set in motion. This simply starts a libuv `timer <#timers>`_ which +drives ``curl_multi_socket_action`` with ``CURL_SOCKET_TIMEOUT`` whenever it +times out. ``curl_multi_socket_action`` is what drives libcurl, and what we +call whenever sockets change state. But before we go into that, we need to poll +on sockets whenever ``handle_socket`` is called. + +.. rubric:: uvwget/main.c - Setting up polling +.. literalinclude:: ../../code/uvwget/main.c + :language: c + :linenos: + :lines: 102-140 + :emphasize-lines: 9,11,15,21,24 + +We are interested in the socket fd ``s``, and the ``action``. For every socket +we create a ``uv_poll_t`` handle if it doesn't exist, and associate it with the +socket using ``curl_multi_assign``. This way ``socketp`` points to it whenever +the callback is invoked. + +In the case that the download is done or fails, libcurl requests removal of the +poll. So we stop and free the poll handle. + +Depending on what events libcurl wishes to watch for, we start polling with +``UV_READABLE`` or ``UV_WRITABLE``. Now libuv will invoke the poll callback +whenever the socket is ready for reading or writing. Calling ``uv_poll_start`` +multiple times on the same handle is acceptable, it will just update the events +mask with the new value. ``curl_perform`` is the crux of this program. + +.. rubric:: uvwget/main.c - Driving libcurl. +.. literalinclude:: ../../code/uvwget/main.c + :language: c + :linenos: + :lines: 81-95 + :emphasize-lines: 2,6-7,12 + +The first thing we do is to stop the timer, since there has been some progress +in the interval. Then depending on what event triggered the callback, we set +the correct flags. Then we call ``curl_multi_socket_action`` with the socket +that progressed and the flags informing about what events happened. At this +point libcurl does all of its internal tasks in small increments, and will +attempt to return as fast as possible, which is exactly what an evented program +wants in its main thread. libcurl keeps queueing messages into its own queue +about transfer progress. In our case we are only interested in transfers that +are completed. So we extract these messages, and clean up handles whose +transfers are done. + +.. rubric:: uvwget/main.c - Reading transfer status. +.. literalinclude:: ../../code/uvwget/main.c + :language: c + :linenos: + :lines: 58-79 + :emphasize-lines: 6,9-10,13-14 + +Check & Prepare watchers +------------------------ + +TODO + +Loading libraries +----------------- + +libuv provides a cross platform API to dynamically load `shared libraries`_. +This can be used to implement your own plugin/extension/module system and is +used by node.js to implement ``require()`` support for bindings. The usage is +quite simple as long as your library exports the right symbols. Be careful with +sanity and security checks when loading third party code, otherwise your +program will behave unpredictably. This example implements a very simple +plugin system which does nothing except print the name of the plugin. + +Let us first look at the interface provided to plugin authors. + +.. rubric:: plugin/plugin.h +.. literalinclude:: ../../code/plugin/plugin.h + :language: c + :linenos: + +You can similarly add more functions that plugin authors can use to do useful +things in your application [#]_. A sample plugin using this API is: + +.. rubric:: plugin/hello.c +.. literalinclude:: ../../code/plugin/hello.c + :language: c + :linenos: + +Our interface defines that all plugins should have an ``initialize`` function +which will be called by the application. This plugin is compiled as a shared +library and can be loaded by running our application:: + + $ ./plugin libhello.dylib + Loading libhello.dylib + Registered plugin "Hello World!" + +.. NOTE:: + + The shared library filename will be different depending on platforms. On + Linux it is ``libhello.so``. + +This is done by using ``uv_dlopen`` to first load the shared library +``libhello.dylib``. Then we get access to the ``initialize`` function using +``uv_dlsym`` and invoke it. + +.. rubric:: plugin/main.c +.. literalinclude:: ../../code/plugin/main.c + :language: c + :linenos: + :lines: 7- + :emphasize-lines: 15, 18, 24 + +``uv_dlopen`` expects a path to the shared library and sets the opaque +``uv_lib_t`` pointer. It returns 0 on success, -1 on error. Use ``uv_dlerror`` +to get the error message. + +``uv_dlsym`` stores a pointer to the symbol in the second argument in the third +argument. ``init_plugin_function`` is a function pointer to the sort of +function we are looking for in the application's plugins. + +.. _shared libraries: https://en.wikipedia.org/wiki/Shared_library#Shared_libraries + +TTY +--- + +Text terminals have supported basic formatting for a long time, with a `pretty +standardised`_ command set. This formatting is often used by programs to +improve the readability of terminal output. For example ``grep --colour``. +libuv provides the ``uv_tty_t`` abstraction (a stream) and related functions to +implement the ANSI escape codes across all platforms. By this I mean that libuv +converts ANSI codes to the Windows equivalent, and provides functions to get +terminal information. + +.. _pretty standardised: https://en.wikipedia.org/wiki/ANSI_escape_sequences + +The first thing to do is to initialize a ``uv_tty_t`` with the file descriptor +it reads/writes from. This is achieved with:: + + int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int unused) + +The ``unused`` parameter is now auto-detected and ignored. It previously needed +to be set to use ``uv_read_start()`` on the stream. + +It is then best to use ``uv_tty_set_mode`` to set the mode to *normal* +which enables most TTY formatting, flow-control and other settings. Other_ modes +are also available. + +.. _Other: http://docs.libuv.org/en/v1.x/tty.html#c.uv_tty_mode_t + +Remember to call ``uv_tty_reset_mode`` when your program exits to restore the +state of the terminal. Just good manners. Another set of good manners is to be +aware of redirection. If the user redirects the output of your command to +a file, control sequences should not be written as they impede readability and +``grep``. To check if the file descriptor is indeed a TTY, call +``uv_guess_handle`` with the file descriptor and compare the return value with +``UV_TTY``. + +Here is a simple example which prints white text on a red background: + +.. rubric:: tty/main.c +.. literalinclude:: ../../code/tty/main.c + :language: c + :linenos: + :emphasize-lines: 11-12,14,17,27 + +The final TTY helper is ``uv_tty_get_winsize()`` which is used to get the +width and height of the terminal and returns ``0`` on success. Here is a small +program which does some animation using the function and character position +escape codes. + +.. rubric:: tty-gravity/main.c +.. literalinclude:: ../../code/tty-gravity/main.c + :language: c + :linenos: + :emphasize-lines: 19,25,38 + +The escape codes are: + +====== ======================= +Code Meaning +====== ======================= +*2* J Clear part of the screen, 2 is entire screen +H Moves cursor to certain position, default top-left +*n* B Moves cursor down by n lines +*n* C Moves cursor right by n columns +m Obeys string of display settings, in this case green background (40+2), white text (30+7) +====== ======================= + +As you can see this is very useful to produce nicely formatted output, or even +console based arcade games if that tickles your fancy. For fancier control you +can try `ncurses`_. + +.. _ncurses: https://www.gnu.org/software/ncurses/ncurses.html + +.. versionchanged:: 1.23.1: the `readable` parameter is now unused and ignored. + The appropriate value will now be auto-detected from the kernel. + +---- + +.. [#] I was first introduced to the term baton in this context, in Konstantin + Käfer's excellent slides on writing node.js bindings -- + https://kkaefer.com/node-cpp-modules/#baton +.. [#] mfp is My Fancy Plugin + +.. _libev man page: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#COMMON_OR_USEFUL_IDIOMS_OR_BOTH diff --git a/external/src/libuv/docs/src/handle.rst b/external/src/libuv/docs/src/handle.rst new file mode 100644 index 0000000..0edb7d7 --- /dev/null +++ b/external/src/libuv/docs/src/handle.rst @@ -0,0 +1,283 @@ + +.. _handle: + +:c:type:`uv_handle_t` --- Base handle +===================================== + +`uv_handle_t` is the base type for all libuv handle types. + +Structures are aligned so that any libuv handle can be cast to `uv_handle_t`. +All API functions defined here work with any handle type. + +Libuv handles are not movable. Pointers to handle structures passed to +functions must remain valid for the duration of the requested operation. Take +care when using stack allocated handles. + +Data types +---------- + +.. c:type:: uv_handle_t + + The base libuv handle type. + +.. c:enum:: uv_handle_type + + The kind of the libuv handle. + + :: + + typedef enum { + UV_UNKNOWN_HANDLE = 0, + UV_ASYNC, + UV_CHECK, + UV_FS_EVENT, + UV_FS_POLL, + UV_HANDLE, + UV_IDLE, + UV_NAMED_PIPE, + UV_POLL, + UV_PREPARE, + UV_PROCESS, + UV_STREAM, + UV_TCP, + UV_TIMER, + UV_TTY, + UV_UDP, + UV_SIGNAL, + UV_FILE, + UV_HANDLE_TYPE_MAX + } uv_handle_type; + +.. c:type:: uv_any_handle + + Union of all handle types. + +.. c:type:: void (*uv_alloc_cb)(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) + + Type definition for callback passed to :c:func:`uv_read_start` and + :c:func:`uv_udp_recv_start`. The user must allocate memory and fill the supplied + :c:type:`uv_buf_t` structure. If NULL is assigned as the buffer's base or 0 as its length, + a ``UV_ENOBUFS`` error will be triggered in the :c:type:`uv_udp_recv_cb` or the + :c:type:`uv_read_cb` callback. + + Each buffer is used only once and the user is responsible for freeing it in the + :c:type:`uv_udp_recv_cb` or the :c:type:`uv_read_cb` callback. + + A suggested size (65536 at the moment in most cases) is provided, but it's just an indication, + not related in any way to the pending data to be read. The user is free to allocate the amount + of memory they decide. + + As an example, applications with custom allocation schemes such as using freelists, allocation + pools or slab based allocators may decide to use a different size which matches the memory + chunks they already have. + + Example: + + :: + + static void my_alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { + buf->base = malloc(suggested_size); + buf->len = suggested_size; + } + +.. c:type:: void (*uv_close_cb)(uv_handle_t* handle) + + Type definition for callback passed to :c:func:`uv_close`. + + +Public members +^^^^^^^^^^^^^^ + +.. c:member:: uv_loop_t* uv_handle_t.loop + + Pointer to the :c:type:`uv_loop_t` the handle is running on. Readonly. + +.. c:member:: uv_handle_type uv_handle_t.type + + The :c:type:`uv_handle_type`, indicating the type of the underlying handle. Readonly. + +.. c:member:: void* uv_handle_t.data + + Space for user-defined arbitrary data. libuv does not use this field. + + +API +--- + +.. c:macro:: UV_HANDLE_TYPE_MAP(iter_macro) + + Macro that expands to a series of invocations of `iter_macro` for + each of the handle types. `iter_macro` is invoked with two + arguments: the name of the `uv_handle_type` element without the + `UV_` prefix, and the name of the corresponding structure type + without the `uv_` prefix and `_t` suffix. + +.. c:function:: int uv_is_active(const uv_handle_t* handle) + + Returns non-zero if the handle is active, zero if it's inactive. What + "active" means depends on the type of handle: + + - A uv_async_t handle is always active and cannot be deactivated, except + by closing it with uv_close(). + + - A uv_pipe_t, uv_tcp_t, uv_udp_t, etc. handle - basically any handle that + deals with i/o - is active when it is doing something that involves i/o, + like reading, writing, connecting, accepting new connections, etc. + + - A uv_check_t, uv_idle_t, uv_timer_t, etc. handle is active when it has + been started with a call to uv_check_start(), uv_idle_start(), etc. + + Rule of thumb: if a handle of type `uv_foo_t` has a `uv_foo_start()` + function, then it's active from the moment that function is called. + Likewise, `uv_foo_stop()` deactivates the handle again. + +.. c:function:: int uv_is_closing(const uv_handle_t* handle) + + Returns non-zero if the handle is closing or closed, zero otherwise. + + .. note:: + This function should only be used between the initialization of the handle and the + arrival of the close callback. + +.. c:function:: void uv_close(uv_handle_t* handle, uv_close_cb close_cb) + + Request handle to be closed. `close_cb` will be called asynchronously after + this call. This MUST be called on each handle before memory is released. + Moreover, the memory can only be released in `close_cb` or after it has + returned. + + Handles that wrap file descriptors are closed immediately but + `close_cb` will still be deferred to the next iteration of the event loop. + It gives you a chance to free up any resources associated with the handle. + + In-progress requests, like uv_connect_t or uv_write_t, are cancelled and + have their callbacks called asynchronously with status=UV_ECANCELED. + +.. c:function:: void uv_ref(uv_handle_t* handle) + + Reference the given handle. References are idempotent, that is, if a handle + is already referenced calling this function again will have no effect. + + See :ref:`refcount`. + +.. c:function:: void uv_unref(uv_handle_t* handle) + + Un-reference the given handle. References are idempotent, that is, if a handle + is not referenced calling this function again will have no effect. + + See :ref:`refcount`. + +.. c:function:: int uv_has_ref(const uv_handle_t* handle) + + Returns non-zero if the handle referenced, zero otherwise. + + See :ref:`refcount`. + +.. c:function:: size_t uv_handle_size(uv_handle_type type) + + Returns the size of the given handle type. Useful for FFI binding writers + who don't want to know the structure layout. + + +Miscellaneous API functions +--------------------------- + +The following API functions take a :c:type:`uv_handle_t` argument but they work +just for some handle types. + +.. c:function:: int uv_send_buffer_size(uv_handle_t* handle, int* value) + + Gets or sets the size of the send buffer that the operating + system uses for the socket. + + If `*value` == 0, then it will set `*value` to the current send buffer size. + If `*value` > 0 then it will use `*value` to set the new send buffer size. + + On success, zero is returned. On error, a negative result is + returned. + + This function works for TCP, pipe and UDP handles on Unix and for TCP and + UDP handles on Windows. + + .. note:: + Linux will set double the size and return double the size of the original set value. + +.. c:function:: int uv_recv_buffer_size(uv_handle_t* handle, int* value) + + Gets or sets the size of the receive buffer that the operating + system uses for the socket. + + If `*value` == 0, then it will set `*value` to the current receive buffer size. + If `*value` > 0 then it will use `*value` to set the new receive buffer size. + + On success, zero is returned. On error, a negative result is + returned. + + This function works for TCP, pipe and UDP handles on Unix and for TCP and + UDP handles on Windows. + + .. note:: + Linux will set double the size and return double the size of the original set value. + +.. c:function:: int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) + + Gets the platform dependent file descriptor equivalent. + + The following handles are supported: TCP, pipes, TTY, UDP and poll. Passing + any other handle type will fail with `UV_EINVAL`. + + If a handle doesn't have an attached file descriptor yet or the handle + itself has been closed, this function will return `UV_EBADF`. + + .. warning:: + Be very careful when using this function. libuv assumes it's in control of the file + descriptor so any change to it may lead to malfunction. + +.. c:function:: uv_loop_t* uv_handle_get_loop(const uv_handle_t* handle) + + Returns `handle->loop`. + + .. versionadded:: 1.19.0 + +.. c:function:: void* uv_handle_get_data(const uv_handle_t* handle) + + Returns `handle->data`. + + .. versionadded:: 1.19.0 + +.. c:function:: void* uv_handle_set_data(uv_handle_t* handle, void* data) + + Sets `handle->data` to `data`. + + .. versionadded:: 1.19.0 + +.. c:function:: uv_handle_type uv_handle_get_type(const uv_handle_t* handle) + + Returns `handle->type`. + + .. versionadded:: 1.19.0 + +.. c:function:: const char* uv_handle_type_name(uv_handle_type type) + + Returns the name for the equivalent struct for a given handle type, + e.g. `"pipe"` (as in :c:type:`uv_pipe_t`) for `UV_NAMED_PIPE`. + + If no such handle type exists, this returns `NULL`. + + .. versionadded:: 1.19.0 + +.. _refcount: + +Reference counting +------------------ + +The libuv event loop (if run in the default mode) will run until there are no +active `and` referenced handles left. The user can force the loop to exit early +by unreferencing handles which are active, for example by calling :c:func:`uv_unref` +after calling :c:func:`uv_timer_start`. + +A handle can be referenced or unreferenced, the refcounting scheme doesn't use +a counter, so both operations are idempotent. + +All handles are referenced when active by default, see :c:func:`uv_is_active` +for a more detailed explanation on what being `active` involves. diff --git a/external/src/libuv/docs/src/idle.rst b/external/src/libuv/docs/src/idle.rst new file mode 100644 index 0000000..b7a0507 --- /dev/null +++ b/external/src/libuv/docs/src/idle.rst @@ -0,0 +1,62 @@ + +.. _idle: + +:c:type:`uv_idle_t` --- Idle handle +=================================== + +Idle handles will run the given callback once per loop iteration, right +before the :c:type:`uv_prepare_t` handles. + +.. note:: + The notable difference with prepare handles is that when there are active idle handles, + the loop will perform a zero timeout poll instead of blocking for i/o. + +.. warning:: + Despite the name, idle handles will get their callbacks called on every loop iteration, + not when the loop is actually "idle". + + +Data types +---------- + +.. c:type:: uv_idle_t + + Idle handle type. + +.. c:type:: void (*uv_idle_cb)(uv_idle_t* handle) + + Type definition for callback passed to :c:func:`uv_idle_start`. + + +Public members +^^^^^^^^^^^^^^ + +N/A + +.. seealso:: The :c:type:`uv_handle_t` members also apply. + + +API +--- + +.. c:function:: int uv_idle_init(uv_loop_t* loop, uv_idle_t* idle) + + Initialize the handle. This function always succeeds. + + :returns: 0 + +.. c:function:: int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb) + + Start the handle with the given callback. This function always succeeds, + except when `cb` is `NULL`. + + :returns: 0 on success, or `UV_EINVAL` when `cb == NULL`. + +.. c:function:: int uv_idle_stop(uv_idle_t* idle) + + Stop the handle, the callback will no longer be called. + This function always succeeds. + + :returns: 0 + +.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/external/src/libuv/docs/src/index.rst b/external/src/libuv/docs/src/index.rst new file mode 100644 index 0000000..4b5d4d2 --- /dev/null +++ b/external/src/libuv/docs/src/index.rst @@ -0,0 +1,62 @@ + +Welcome to the libuv documentation +================================== + +Overview +-------- + +libuv is a multi-platform support library with a focus on asynchronous I/O. It +was primarily developed for use by `Node.js`_, but it's also used by `Luvit`_, +`Julia`_, `pyuv`_, and `others`_. + +.. note:: + In case you find errors in this documentation you can help by sending + `pull requests `_! + +.. _Node.js: https://nodejs.org +.. _Luvit: https://luvit.io +.. _Julia: https://julialang.org +.. _pyuv: https://github.com/saghul/pyuv +.. _others: https://github.com/libuv/libuv/blob/v1.x/LINKS.md + + +Features +-------- + +* Full-featured event loop backed by epoll, kqueue, IOCP, event ports. +* Asynchronous TCP and UDP sockets +* Asynchronous DNS resolution +* Asynchronous file and file system operations +* File system events +* ANSI escape code controlled TTY +* IPC with socket sharing, using Unix domain sockets or named pipes (Windows) +* Child processes +* Thread pool +* Signal handling +* High resolution clock +* Threading and synchronization primitives + + +Documentation +------------- + +.. toctree:: + :maxdepth: 1 + + design + api + guide + upgrading + + +Downloads +--------- + +libuv can be downloaded from `here `_. + + +Installation +------------ + +Installation instructions can be found in `the README `_. + diff --git a/external/src/libuv/docs/src/loop.rst b/external/src/libuv/docs/src/loop.rst new file mode 100644 index 0000000..0f5ddfb --- /dev/null +++ b/external/src/libuv/docs/src/loop.rst @@ -0,0 +1,245 @@ + +.. _loop: + +:c:type:`uv_loop_t` --- Event loop +================================== + +The event loop is the central part of libuv's functionality. It takes care +of polling for i/o and scheduling callbacks to be run based on different sources +of events. + + +Data types +---------- + +.. c:type:: uv_loop_t + + Loop data type. + +.. c:enum:: uv_run_mode + + Mode used to run the loop with :c:func:`uv_run`. + + :: + + typedef enum { + UV_RUN_DEFAULT = 0, + UV_RUN_ONCE, + UV_RUN_NOWAIT + } uv_run_mode; + +.. c:type:: void (*uv_walk_cb)(uv_handle_t* handle, void* arg) + + Type definition for callback passed to :c:func:`uv_walk`. + + +Public members +^^^^^^^^^^^^^^ + +.. c:member:: void* uv_loop_t.data + + Space for user-defined arbitrary data. libuv does not use and does not + touch this field. + + +API +--- + +.. c:function:: int uv_loop_init(uv_loop_t* loop) + + Initializes the given `uv_loop_t` structure. + +.. c:function:: int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...) + + .. versionadded:: 1.0.2 + + Set additional loop options. You should normally call this before the + first call to :c:func:`uv_run` unless mentioned otherwise. + + Returns 0 on success or a UV_E* error code on failure. Be prepared to + handle UV_ENOSYS; it means the loop option is not supported by the platform. + + Supported options: + + - UV_LOOP_BLOCK_SIGNAL: Block a signal when polling for new events. The + second argument to :c:func:`uv_loop_configure` is the signal number. + + This operation is currently only implemented for SIGPROF signals, + to suppress unnecessary wakeups when using a sampling profiler. + Requesting other signals will fail with UV_EINVAL. + + - UV_METRICS_IDLE_TIME: Accumulate the amount of idle time the event loop + spends in the event provider. + + This option is necessary to use :c:func:`uv_metrics_idle_time`. + + .. versionchanged:: 1.39.0 added the UV_METRICS_IDLE_TIME option. + +.. c:function:: int uv_loop_close(uv_loop_t* loop) + + Releases all internal loop resources. Call this function only when the loop + has finished executing and all open handles and requests have been closed, + or it will return UV_EBUSY. After this function returns, the user can free + the memory allocated for the loop. + +.. c:function:: uv_loop_t* uv_default_loop(void) + + Returns the initialized default loop. It may return NULL in case of + allocation failure. + + This function is just a convenient way for having a global loop throughout + an application, the default loop is in no way different than the ones + initialized with :c:func:`uv_loop_init`. As such, the default loop can (and + should) be closed with :c:func:`uv_loop_close` so the resources associated + with it are freed. + + .. warning:: + This function is not thread safe. + +.. c:function:: int uv_run(uv_loop_t* loop, uv_run_mode mode) + + This function runs the event loop. It will act differently depending on the + specified mode: + + - UV_RUN_DEFAULT: Runs the event loop until there are no more active and + referenced handles or requests. Returns non-zero if :c:func:`uv_stop` + was called and there are still active handles or requests. Returns + zero in all other cases. + - UV_RUN_ONCE: Poll for i/o once. Note that this function blocks if + there are no pending callbacks. Returns zero when done (no active handles + or requests left), or non-zero if more callbacks are expected (meaning + you should run the event loop again sometime in the future). + - UV_RUN_NOWAIT: Poll for i/o once but don't block if there are no + pending callbacks. Returns zero if done (no active handles + or requests left), or non-zero if more callbacks are expected (meaning + you should run the event loop again sometime in the future). + + :c:func:`uv_run` is not reentrant. It must not be called from a callback. + +.. c:function:: int uv_loop_alive(const uv_loop_t* loop) + + Returns non-zero if there are referenced active handles, active + requests or closing handles in the loop. + +.. c:function:: void uv_stop(uv_loop_t* loop) + + Stop the event loop, causing :c:func:`uv_run` to end as soon as + possible. This will happen not sooner than the next loop iteration. + If this function was called before blocking for i/o, the loop won't block + for i/o on this iteration. + +.. c:function:: size_t uv_loop_size(void) + + Returns the size of the `uv_loop_t` structure. Useful for FFI binding + writers who don't want to know the structure layout. + +.. c:function:: int uv_backend_fd(const uv_loop_t* loop) + + Get backend file descriptor. Only kqueue, epoll and event ports are + supported. + + This can be used in conjunction with `uv_run(loop, UV_RUN_NOWAIT)` to + poll in one thread and run the event loop's callbacks in another see + test/test-embed.c for an example. + + .. note:: + Embedding a kqueue fd in another kqueue pollset doesn't work on all platforms. It's not + an error to add the fd but it never generates events. + +.. c:function:: int uv_backend_timeout(const uv_loop_t* loop) + + Get the poll timeout. The return value is in milliseconds, or -1 for no + timeout. + +.. c:function:: uint64_t uv_now(const uv_loop_t* loop) + + Return the current timestamp in milliseconds. The timestamp is cached at + the start of the event loop tick, see :c:func:`uv_update_time` for details + and rationale. + + The timestamp increases monotonically from some arbitrary point in time. + Don't make assumptions about the starting point, you will only get + disappointed. + + .. note:: + Use :c:func:`uv_hrtime` if you need sub-millisecond granularity. + +.. c:function:: void uv_update_time(uv_loop_t* loop) + + Update the event loop's concept of "now". Libuv caches the current time + at the start of the event loop tick in order to reduce the number of + time-related system calls. + + You won't normally need to call this function unless you have callbacks + that block the event loop for longer periods of time, where "longer" is + somewhat subjective but probably on the order of a millisecond or more. + +.. c:function:: void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) + + Walk the list of handles: `walk_cb` will be executed with the given `arg`. + +.. c:function:: int uv_loop_fork(uv_loop_t* loop) + + .. versionadded:: 1.12.0 + + Reinitialize any kernel state necessary in the child process after + a :man:`fork(2)` system call. + + Previously started watchers will continue to be started in the + child process. + + It is necessary to explicitly call this function on every event + loop created in the parent process that you plan to continue to + use in the child, including the default loop (even if you don't + continue to use it in the parent). This function must be called + before calling :c:func:`uv_run` or any other API function using + the loop in the child. Failure to do so will result in undefined + behaviour, possibly including duplicate events delivered to both + parent and child or aborting the child process. + + When possible, it is preferred to create a new loop in the child + process instead of reusing a loop created in the parent. New loops + created in the child process after the fork should not use this + function. + + This function is not implemented on Windows, where it returns ``UV_ENOSYS``. + + .. caution:: + + This function is experimental. It may contain bugs, and is subject to + change or removal. API and ABI stability is not guaranteed. + + .. note:: + + On Mac OS X, if directory FS event handles were in use in the + parent process *for any event loop*, the child process will no + longer be able to use the most efficient FSEvent + implementation. Instead, uses of directory FS event handles in + the child will fall back to the same implementation used for + files and on other kqueue-based systems. + + .. caution:: + + On AIX and SunOS, FS event handles that were already started in + the parent process at the time of forking will *not* deliver + events in the child process; they must be closed and restarted. + On all other platforms, they will continue to work normally + without any further intervention. + + .. caution:: + + Any previous value returned from :c:func:`uv_backend_fd` is now + invalid. That function must be called again to determine the + correct backend file descriptor. + +.. c:function:: void* uv_loop_get_data(const uv_loop_t* loop) + + Returns `loop->data`. + + .. versionadded:: 1.19.0 + +.. c:function:: void* uv_loop_set_data(uv_loop_t* loop, void* data) + + Sets `loop->data` to `data`. + + .. versionadded:: 1.19.0 diff --git a/external/src/libuv/docs/src/metrics.rst b/external/src/libuv/docs/src/metrics.rst new file mode 100644 index 0000000..696c620 --- /dev/null +++ b/external/src/libuv/docs/src/metrics.rst @@ -0,0 +1,27 @@ + +.. _metrics: + +Metrics operations +====================== + +libuv provides a metrics API to track the amount of time the event loop has +spent idle in the kernel's event provider. + +API +--- + +.. c:function:: uint64_t uv_metrics_idle_time(uv_loop_t* loop) + + Retrieve the amount of time the event loop has been idle in the kernel's + event provider (e.g. ``epoll_wait``). The call is thread safe. + + The return value is the accumulated time spent idle in the kernel's event + provider starting from when the :c:type:`uv_loop_t` was configured to + collect the idle time. + + .. note:: + The event loop will not begin accumulating the event provider's idle + time until calling :c:type:`uv_loop_configure` with + :c:type:`UV_METRICS_IDLE_TIME`. + + .. versionadded:: 1.39.0 diff --git a/external/src/libuv/docs/src/migration_010_100.rst b/external/src/libuv/docs/src/migration_010_100.rst new file mode 100644 index 0000000..bb6ac1a --- /dev/null +++ b/external/src/libuv/docs/src/migration_010_100.rst @@ -0,0 +1,244 @@ + +.. _migration_010_100: + +libuv 0.10 -> 1.0.0 migration guide +=================================== + +Some APIs changed quite a bit throughout the 1.0.0 development process. Here +is a migration guide for the most significant changes that happened after 0.10 +was released. + + +Loop initialization and closing +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In libuv 0.10 (and previous versions), loops were created with `uv_loop_new`, which +allocated memory for a new loop and initialized it; and destroyed with `uv_loop_delete`, +which destroyed the loop and freed the memory. Starting with 1.0, those are deprecated +and the user is responsible for allocating the memory and then initializing the loop. + +libuv 0.10 + +:: + + uv_loop_t* loop = uv_loop_new(); + ... + uv_loop_delete(loop); + +libuv 1.0 + +:: + + uv_loop_t* loop = malloc(sizeof *loop); + uv_loop_init(loop); + ... + uv_loop_close(loop); + free(loop); + +.. note:: + Error handling was omitted for brevity. Check the documentation for :c:func:`uv_loop_init` + and :c:func:`uv_loop_close`. + + +Error handling +~~~~~~~~~~~~~~ + +Error handling had a major overhaul in libuv 1.0. In general, functions and status parameters +would get 0 for success and -1 for failure on libuv 0.10, and the user had to use `uv_last_error` +to fetch the error code, which was a positive number. + +In 1.0, functions and status parameters contain the actual error code, which is 0 for success, or +a negative number in case of error. + +libuv 0.10 + +:: + + ... assume 'server' is a TCP server which is already listening + r = uv_listen((uv_stream_t*) server, 511, NULL); + if (r == -1) { + uv_err_t err = uv_last_error(uv_default_loop()); + /* err.code contains UV_EADDRINUSE */ + } + +libuv 1.0 + +:: + + ... assume 'server' is a TCP server which is already listening + r = uv_listen((uv_stream_t*) server, 511, NULL); + if (r < 0) { + /* r contains UV_EADDRINUSE */ + } + + +Threadpool changes +~~~~~~~~~~~~~~~~~~ + +In libuv 0.10 Unix used a threadpool which defaulted to 4 threads, while Windows used the +`QueueUserWorkItem` API, which uses a Windows internal threadpool, which defaults to 512 +threads per process. + +In 1.0, we unified both implementations, so Windows now uses the same implementation Unix +does. The threadpool size can be set by exporting the ``UV_THREADPOOL_SIZE`` environment +variable. See :c:ref:`threadpool`. + + +Allocation callback API change +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In libuv 0.10 the callback had to return a filled :c:type:`uv_buf_t` by value: + +:: + + uv_buf_t alloc_cb(uv_handle_t* handle, size_t size) { + return uv_buf_init(malloc(size), size); + } + +In libuv 1.0 a pointer to a buffer is passed to the callback, which the user +needs to fill: + +:: + + void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + buf->base = malloc(size); + buf->len = size; + } + + +Unification of IPv4 / IPv6 APIs +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +libuv 1.0 unified the IPv4 and IPv6 APIS. There is no longer a `uv_tcp_bind` and `uv_tcp_bind6` +duality, there is only :c:func:`uv_tcp_bind` now. + +IPv4 functions took ``struct sockaddr_in`` structures by value, and IPv6 functions took +``struct sockaddr_in6``. Now functions take a ``struct sockaddr*`` (note it's a pointer). +It can be stack allocated. + +libuv 0.10 + +:: + + struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", 1234); + ... + uv_tcp_bind(&server, addr) + +libuv 1.0 + +:: + + struct sockaddr_in addr; + uv_ip4_addr("0.0.0.0", 1234, &addr) + ... + uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); + +The IPv4 and IPv6 struct creating functions (:c:func:`uv_ip4_addr` and :c:func:`uv_ip6_addr`) +have also changed, make sure you check the documentation. + +..note:: + This change applies to all functions that made a distinction between IPv4 and IPv6 + addresses. + + +Streams / UDP data receive callback API change +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The streams and UDP data receive callbacks now get a pointer to a :c:type:`uv_buf_t` buffer, +not a structure by value. + +libuv 0.10 + +:: + + void on_read(uv_stream_t* handle, + ssize_t nread, + uv_buf_t buf) { + ... + } + + void recv_cb(uv_udp_t* handle, + ssize_t nread, + uv_buf_t buf, + struct sockaddr* addr, + unsigned flags) { + ... + } + +libuv 1.0 + +:: + + void on_read(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + ... + } + + void recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags) { + ... + } + + +Receiving handles over pipes API change +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In libuv 0.10 (and earlier versions) the `uv_read2_start` function was used to start reading +data on a pipe, which could also result in the reception of handles over it. The callback +for such function looked like this: + +:: + + void on_read(uv_pipe_t* pipe, + ssize_t nread, + uv_buf_t buf, + uv_handle_type pending) { + ... + } + +In libuv 1.0, `uv_read2_start` was removed, and the user needs to check if there are pending +handles using :c:func:`uv_pipe_pending_count` and :c:func:`uv_pipe_pending_type` while in +the read callback: + +:: + + void on_read(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + ... + while (uv_pipe_pending_count((uv_pipe_t*) handle) != 0) { + pending = uv_pipe_pending_type((uv_pipe_t*) handle); + ... + } + ... + } + + +Extracting the file descriptor out of a handle +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +While it wasn't supported by the API, users often accessed the libuv internals in +order to get access to the file descriptor of a TCP handle, for example. + +:: + + fd = handle->io_watcher.fd; + +This is now properly exposed through the :c:func:`uv_fileno` function. + + +uv_fs_readdir rename and API change +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +`uv_fs_readdir` returned a list of strings in the `req->ptr` field upon completion in +libuv 0.10. In 1.0, this function got renamed to :c:func:`uv_fs_scandir`, since it's +actually implemented using ``scandir(3)``. + +In addition, instead of allocating a full list strings, the user is able to get one +result at a time by using the :c:func:`uv_fs_scandir_next` function. This function +does not need to make a roundtrip to the threadpool, because libuv will keep the +list of *dents* returned by ``scandir(3)`` around. diff --git a/external/src/libuv/docs/src/misc.rst b/external/src/libuv/docs/src/misc.rst new file mode 100644 index 0000000..9a8595e --- /dev/null +++ b/external/src/libuv/docs/src/misc.rst @@ -0,0 +1,755 @@ + +.. _misc: + +Miscellaneous utilities +======================= + +This section contains miscellaneous functions that don't really belong in any +other section. + + +Data types +---------- + +.. c:type:: uv_buf_t + + Buffer data type. + + .. c:member:: char* uv_buf_t.base + + Pointer to the base of the buffer. + + .. c:member:: size_t uv_buf_t.len + + Total bytes in the buffer. + + .. note:: + On Windows this field is ULONG. + +.. c:type:: void* (*uv_malloc_func)(size_t size) + + Replacement function for :man:`malloc(3)`. + See :c:func:`uv_replace_allocator`. + +.. c:type:: void* (*uv_realloc_func)(void* ptr, size_t size) + + Replacement function for :man:`realloc(3)`. + See :c:func:`uv_replace_allocator`. + +.. c:type:: void* (*uv_calloc_func)(size_t count, size_t size) + + Replacement function for :man:`calloc(3)`. + See :c:func:`uv_replace_allocator`. + +.. c:type:: void (*uv_free_func)(void* ptr) + + Replacement function for :man:`free(3)`. + See :c:func:`uv_replace_allocator`. + +.. c:type:: void (*uv_random_cb)(uv_random_t* req, int status, void* buf, size_t buflen) + + Callback passed to :c:func:`uv_random`. `status` is non-zero in case of + error. The `buf` pointer is the same pointer that was passed to + :c:func:`uv_random`. + +.. c:type:: uv_file + + Cross platform representation of a file handle. + +.. c:type:: uv_os_sock_t + + Cross platform representation of a socket handle. + +.. c:type:: uv_os_fd_t + + Abstract representation of a file descriptor. On Unix systems this is a + `typedef` of `int` and on Windows a `HANDLE`. + +.. c:type:: uv_pid_t + + Cross platform representation of a `pid_t`. + + .. versionadded:: 1.16.0 + +.. c:type:: uv_timeval_t + + Data type for storing times. + + :: + + typedef struct { + long tv_sec; + long tv_usec; + } uv_timeval_t; + +.. c:type:: uv_timeval64_t + + Alternative data type for storing times. + + :: + + typedef struct { + int64_t tv_sec; + int32_t tv_usec; + } uv_timeval64_t; + +.. c:type:: uv_rusage_t + + Data type for resource usage results. + + :: + + typedef struct { + uv_timeval_t ru_utime; /* user CPU time used */ + uv_timeval_t ru_stime; /* system CPU time used */ + uint64_t ru_maxrss; /* maximum resident set size */ + uint64_t ru_ixrss; /* integral shared memory size (X) */ + uint64_t ru_idrss; /* integral unshared data size (X) */ + uint64_t ru_isrss; /* integral unshared stack size (X) */ + uint64_t ru_minflt; /* page reclaims (soft page faults) (X) */ + uint64_t ru_majflt; /* page faults (hard page faults) */ + uint64_t ru_nswap; /* swaps (X) */ + uint64_t ru_inblock; /* block input operations */ + uint64_t ru_oublock; /* block output operations */ + uint64_t ru_msgsnd; /* IPC messages sent (X) */ + uint64_t ru_msgrcv; /* IPC messages received (X) */ + uint64_t ru_nsignals; /* signals received (X) */ + uint64_t ru_nvcsw; /* voluntary context switches (X) */ + uint64_t ru_nivcsw; /* involuntary context switches (X) */ + } uv_rusage_t; + + Members marked with `(X)` are unsupported on Windows. + See :man:`getrusage(2)` for supported fields on Unix + +.. c:type:: uv_cpu_info_t + + Data type for CPU information. + + :: + + typedef struct uv_cpu_info_s { + char* model; + int speed; + struct uv_cpu_times_s { + uint64_t user; /* milliseconds */ + uint64_t nice; /* milliseconds */ + uint64_t sys; /* milliseconds */ + uint64_t idle; /* milliseconds */ + uint64_t irq; /* milliseconds */ + } cpu_times; + } uv_cpu_info_t; + +.. c:type:: uv_interface_address_t + + Data type for interface addresses. + + :: + + typedef struct uv_interface_address_s { + char* name; + char phys_addr[6]; + int is_internal; + union { + struct sockaddr_in address4; + struct sockaddr_in6 address6; + } address; + union { + struct sockaddr_in netmask4; + struct sockaddr_in6 netmask6; + } netmask; + } uv_interface_address_t; + +.. c:type:: uv_passwd_t + + Data type for password file information. + + :: + + typedef struct uv_passwd_s { + char* username; + long uid; + long gid; + char* shell; + char* homedir; + } uv_passwd_t; + +.. c:type:: uv_utsname_t + + Data type for operating system name and version information. + + :: + + typedef struct uv_utsname_s { + char sysname[256]; + char release[256]; + char version[256]; + char machine[256]; + } uv_utsname_t; + +.. c:type:: uv_env_item_t + + Data type for environment variable storage. + + :: + + typedef struct uv_env_item_s { + char* name; + char* value; + } uv_env_item_t; + +.. c:type:: uv_random_t + + Random data request type. + +API +--- + +.. c:function:: uv_handle_type uv_guess_handle(uv_file file) + + Used to detect what type of stream should be used with a given file + descriptor. Usually this will be used during initialization to guess the + type of the stdio streams. + + For :man:`isatty(3)` equivalent functionality use this function and test + for ``UV_TTY``. + +.. c:function:: int uv_replace_allocator(uv_malloc_func malloc_func, uv_realloc_func realloc_func, uv_calloc_func calloc_func, uv_free_func free_func) + + .. versionadded:: 1.6.0 + + Override the use of the standard library's :man:`malloc(3)`, + :man:`calloc(3)`, :man:`realloc(3)`, :man:`free(3)`, memory allocation + functions. + + This function must be called before any other libuv function is called or + after all resources have been freed and thus libuv doesn't reference + any allocated memory chunk. + + On success, it returns 0, if any of the function pointers is NULL it + returns UV_EINVAL. + + .. warning:: There is no protection against changing the allocator multiple + times. If the user changes it they are responsible for making + sure the allocator is changed while no memory was allocated with + the previous allocator, or that they are compatible. + + .. warning:: Allocator must be thread-safe. + +.. c:function:: void uv_library_shutdown(void); + + .. versionadded:: 1.38.0 + + Release any global state that libuv is holding onto. Libuv will normally + do so automatically when it is unloaded but it can be instructed to perform + cleanup manually. + + .. warning:: Only call :c:func:`uv_library_shutdown()` once. + + .. warning:: Don't call :c:func:`uv_library_shutdown()` when there are + still event loops or I/O requests active. + + .. warning:: Don't call libuv functions after calling + :c:func:`uv_library_shutdown()`. + +.. c:function:: uv_buf_t uv_buf_init(char* base, unsigned int len) + + Constructor for :c:type:`uv_buf_t`. + + Due to platform differences the user cannot rely on the ordering of the + `base` and `len` members of the uv_buf_t struct. The user is responsible for + freeing `base` after the uv_buf_t is done. Return struct passed by value. + +.. c:function:: char** uv_setup_args(int argc, char** argv) + + Store the program arguments. Required for getting / setting the process title + or the executable path. Libuv may take ownership of the memory that `argv` + points to. This function should be called exactly once, at program start-up. + + Example: + + :: + + argv = uv_setup_args(argc, argv); /* May return a copy of argv. */ + + +.. c:function:: int uv_get_process_title(char* buffer, size_t size) + + Gets the title of the current process. You *must* call `uv_setup_args` + before calling this function on Unix and AIX systems. If `uv_setup_args` + has not been called on systems that require it, then `UV_ENOBUFS` is + returned. If `buffer` is `NULL` or `size` is zero, `UV_EINVAL` is returned. + If `size` cannot accommodate the process title and terminating `nul` + character, the function returns `UV_ENOBUFS`. + + .. note:: + On BSD systems, `uv_setup_args` is needed for getting the initial process + title. The process title returned will be an empty string until either + `uv_setup_args` or `uv_set_process_title` is called. + + .. versionchanged:: 1.18.1 now thread-safe on all supported platforms. + + .. versionchanged:: 1.39.0 now returns an error if `uv_setup_args` is needed + but hasn't been called. + +.. c:function:: int uv_set_process_title(const char* title) + + Sets the current process title. You *must* call `uv_setup_args` before + calling this function on Unix and AIX systems. If `uv_setup_args` has not + been called on systems that require it, then `UV_ENOBUFS` is returned. On + platforms with a fixed size buffer for the process title the contents of + `title` will be copied to the buffer and truncated if larger than the + available space. Other platforms will return `UV_ENOMEM` if they cannot + allocate enough space to duplicate the contents of `title`. + + .. versionchanged:: 1.18.1 now thread-safe on all supported platforms. + + .. versionchanged:: 1.39.0 now returns an error if `uv_setup_args` is needed + but hasn't been called. + +.. c:function:: int uv_resident_set_memory(size_t* rss) + + Gets the resident set size (RSS) for the current process. + +.. c:function:: int uv_uptime(double* uptime) + + Gets the current system uptime. + +.. c:function:: int uv_getrusage(uv_rusage_t* rusage) + + Gets the resource usage measures for the current process. + + .. note:: + On Windows not all fields are set, the unsupported fields are filled with zeroes. + See :c:type:`uv_rusage_t` for more details. + +.. c:function:: uv_pid_t uv_os_getpid(void) + + Returns the current process ID. + + .. versionadded:: 1.18.0 + +.. c:function:: uv_pid_t uv_os_getppid(void) + + Returns the parent process ID. + + .. versionadded:: 1.16.0 + +.. c:function:: int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) + + Gets information about the CPUs on the system. The `cpu_infos` array will + have `count` elements and needs to be freed with :c:func:`uv_free_cpu_info`. + +.. c:function:: void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) + + Frees the `cpu_infos` array previously allocated with :c:func:`uv_cpu_info`. + +.. c:function:: int uv_interface_addresses(uv_interface_address_t** addresses, int* count) + + Gets address information about the network interfaces on the system. An + array of `count` elements is allocated and returned in `addresses`. It must + be freed by the user, calling :c:func:`uv_free_interface_addresses`. + +.. c:function:: void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) + + Free an array of :c:type:`uv_interface_address_t` which was returned by + :c:func:`uv_interface_addresses`. + +.. c:function:: void uv_loadavg(double avg[3]) + + Gets the load average. See: ``_ + + .. note:: + Returns [0,0,0] on Windows (i.e., it's not implemented). + +.. c:function:: int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) + + Convert a string containing an IPv4 addresses to a binary structure. + +.. c:function:: int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) + + Convert a string containing an IPv6 addresses to a binary structure. + +.. c:function:: int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size) + + Convert a binary structure containing an IPv4 address to a string. + +.. c:function:: int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size) + + Convert a binary structure containing an IPv6 address to a string. + +.. c:function:: int uv_inet_ntop(int af, const void* src, char* dst, size_t size) +.. c:function:: int uv_inet_pton(int af, const char* src, void* dst) + + Cross-platform IPv6-capable implementation of :man:`inet_ntop(3)` + and :man:`inet_pton(3)`. On success they return 0. In case of error + the target `dst` pointer is unmodified. + +.. c:macro:: UV_IF_NAMESIZE + + Maximum IPv6 interface identifier name length. Defined as + `IFNAMSIZ` on Unix and `IF_NAMESIZE` on Linux and Windows. + + .. versionadded:: 1.16.0 + +.. c:function:: int uv_if_indextoname(unsigned int ifindex, char* buffer, size_t* size) + + IPv6-capable implementation of :man:`if_indextoname(3)`. When called, + `*size` indicates the length of the `buffer`, which is used to store the + result. + On success, zero is returned, `buffer` contains the interface name, and + `*size` represents the string length of the `buffer`, excluding the NUL + terminator byte from `*size`. On error, a negative result is + returned. If `buffer` is not large enough to hold the result, + `UV_ENOBUFS` is returned, and `*size` represents the necessary size in + bytes, including the NUL terminator byte into the `*size`. + + On Unix, the returned interface name can be used directly as an + interface identifier in scoped IPv6 addresses, e.g. + `fe80::abc:def1:2345%en0`. + + On Windows, the returned interface cannot be used as an interface + identifier, as Windows uses numerical interface identifiers, e.g. + `fe80::abc:def1:2345%5`. + + To get an interface identifier in a cross-platform compatible way, + use `uv_if_indextoiid()`. + + Example: + + :: + + char ifname[UV_IF_NAMESIZE]; + size_t size = sizeof(ifname); + uv_if_indextoname(sin6->sin6_scope_id, ifname, &size); + + .. versionadded:: 1.16.0 + +.. c:function:: int uv_if_indextoiid(unsigned int ifindex, char* buffer, size_t* size) + + Retrieves a network interface identifier suitable for use in an IPv6 scoped + address. On Windows, returns the numeric `ifindex` as a string. On all other + platforms, `uv_if_indextoname()` is called. The result is written to + `buffer`, with `*size` indicating the length of `buffer`. If `buffer` is not + large enough to hold the result, then `UV_ENOBUFS` is returned, and `*size` + represents the size, including the NUL byte, required to hold the + result. + + See `uv_if_indextoname` for further details. + + .. versionadded:: 1.16.0 + +.. c:function:: int uv_exepath(char* buffer, size_t* size) + + Gets the executable path. You *must* call `uv_setup_args` before calling + this function. + +.. c:function:: int uv_cwd(char* buffer, size_t* size) + + Gets the current working directory, and stores it in `buffer`. If the + current working directory is too large to fit in `buffer`, this function + returns `UV_ENOBUFS`, and sets `size` to the required length, including the + null terminator. + + .. versionchanged:: 1.1.0 + + On Unix the path no longer ends in a slash. + + .. versionchanged:: 1.9.0 the returned length includes the terminating null + byte on `UV_ENOBUFS`, and the buffer is null terminated + on success. + + +.. c:function:: int uv_chdir(const char* dir) + + Changes the current working directory. + +.. c:function:: int uv_os_homedir(char* buffer, size_t* size) + + Gets the current user's home directory. On Windows, `uv_os_homedir()` first + checks the `USERPROFILE` environment variable using + `GetEnvironmentVariableW()`. If `USERPROFILE` is not set, + `GetUserProfileDirectoryW()` is called. On all other operating systems, + `uv_os_homedir()` first checks the `HOME` environment variable using + :man:`getenv(3)`. If `HOME` is not set, :man:`getpwuid_r(3)` is called. The + user's home directory is stored in `buffer`. When `uv_os_homedir()` is + called, `size` indicates the maximum size of `buffer`. On success `size` is set + to the string length of `buffer`. On `UV_ENOBUFS` failure `size` is set to the + required length for `buffer`, including the null byte. + + .. warning:: + `uv_os_homedir()` is not thread safe. + + .. versionadded:: 1.6.0 + +.. c:function:: int uv_os_tmpdir(char* buffer, size_t* size) + + Gets the temp directory. On Windows, `uv_os_tmpdir()` uses `GetTempPathW()`. + On all other operating systems, `uv_os_tmpdir()` uses the first environment + variable found in the ordered list `TMPDIR`, `TMP`, `TEMP`, and `TEMPDIR`. + If none of these are found, the path `"/tmp"` is used, or, on Android, + `"/data/local/tmp"` is used. The temp directory is stored in `buffer`. When + `uv_os_tmpdir()` is called, `size` indicates the maximum size of `buffer`. + On success `size` is set to the string length of `buffer` (which does not + include the terminating null). On `UV_ENOBUFS` failure `size` is set to the + required length for `buffer`, including the null byte. + + .. warning:: + `uv_os_tmpdir()` is not thread safe. + + .. versionadded:: 1.9.0 + +.. c:function:: int uv_os_get_passwd(uv_passwd_t* pwd) + + Gets a subset of the password file entry for the current effective uid (not + the real uid). The populated data includes the username, euid, gid, shell, + and home directory. On non-Windows systems, all data comes from + :man:`getpwuid_r(3)`. On Windows, uid and gid are set to -1 and have no + meaning, and shell is `NULL`. After successfully calling this function, the + memory allocated to `pwd` needs to be freed with + :c:func:`uv_os_free_passwd`. + + .. versionadded:: 1.9.0 + +.. c:function:: void uv_os_free_passwd(uv_passwd_t* pwd) + + Frees the `pwd` memory previously allocated with :c:func:`uv_os_get_passwd`. + + .. versionadded:: 1.9.0 + +.. c:function:: uint64_t uv_get_free_memory(void) + + Gets the amount of free memory available in the system, as reported by the kernel (in bytes). + +.. c:function:: uint64_t uv_get_total_memory(void) + + Gets the total amount of physical memory in the system (in bytes). + +.. c:function:: uint64_t uv_get_constrained_memory(void) + + Gets the amount of memory available to the process (in bytes) based on + limits imposed by the OS. If there is no such constraint, or the constraint + is unknown, `0` is returned. Note that it is not unusual for this value to + be less than or greater than :c:func:`uv_get_total_memory`. + + .. note:: + This function currently only returns a non-zero value on Linux, based + on cgroups if it is present, and on z/OS based on RLIMIT_MEMLIMIT. + + .. versionadded:: 1.29.0 + +.. c:function:: uint64_t uv_hrtime(void) + + Returns the current high-resolution real time. This is expressed in + nanoseconds. It is relative to an arbitrary time in the past. It is not + related to the time of day and therefore not subject to clock drift. The + primary use is for measuring performance between intervals. + + .. note:: + Not every platform can support nanosecond resolution; however, this value will always + be in nanoseconds. + +.. c:function:: void uv_print_all_handles(uv_loop_t* loop, FILE* stream) + + Prints all handles associated with the given `loop` to the given `stream`. + + Example: + + :: + + uv_print_all_handles(uv_default_loop(), stderr); + /* + [--I] signal 0x1a25ea8 + [-AI] async 0x1a25cf0 + [R--] idle 0x1a7a8c8 + */ + + The format is `[flags] handle-type handle-address`. For `flags`: + + - `R` is printed for a handle that is referenced + - `A` is printed for a handle that is active + - `I` is printed for a handle that is internal + + .. warning:: + This function is meant for ad hoc debugging, there is no API/ABI + stability guarantees. + + .. versionadded:: 1.8.0 + +.. c:function:: void uv_print_active_handles(uv_loop_t* loop, FILE* stream) + + This is the same as :c:func:`uv_print_all_handles` except only active handles + are printed. + + .. warning:: + This function is meant for ad hoc debugging, there is no API/ABI + stability guarantees. + + .. versionadded:: 1.8.0 + +.. c:function:: int uv_os_environ(uv_env_item_t** envitems, int* count) + + Retrieves all environment variables. This function will allocate memory + which must be freed by calling :c:func:`uv_os_free_environ`. + + .. warning:: + This function is not thread safe. + + .. versionadded:: 1.31.0 + +.. c:function:: void uv_os_free_environ(uv_env_item_t* envitems, int count); + + Frees the memory allocated for the environment variables by + :c:func:`uv_os_environ`. + + .. versionadded:: 1.31.0 + +.. c:function:: int uv_os_getenv(const char* name, char* buffer, size_t* size) + + Retrieves the environment variable specified by `name`, copies its value + into `buffer`, and sets `size` to the string length of the value. When + calling this function, `size` must be set to the amount of storage available + in `buffer`, including the null terminator. If the environment variable + exceeds the storage available in `buffer`, `UV_ENOBUFS` is returned, and + `size` is set to the amount of storage required to hold the value. If no + matching environment variable exists, `UV_ENOENT` is returned. + + .. warning:: + This function is not thread safe. + + .. versionadded:: 1.12.0 + +.. c:function:: int uv_os_setenv(const char* name, const char* value) + + Creates or updates the environment variable specified by `name` with + `value`. + + .. warning:: + This function is not thread safe. + + .. versionadded:: 1.12.0 + +.. c:function:: int uv_os_unsetenv(const char* name) + + Deletes the environment variable specified by `name`. If no such environment + variable exists, this function returns successfully. + + .. warning:: + This function is not thread safe. + + .. versionadded:: 1.12.0 + +.. c:function:: int uv_os_gethostname(char* buffer, size_t* size) + + Returns the hostname as a null-terminated string in `buffer`, and sets + `size` to the string length of the hostname. When calling this function, + `size` must be set to the amount of storage available in `buffer`, including + the null terminator. If the hostname exceeds the storage available in + `buffer`, `UV_ENOBUFS` is returned, and `size` is set to the amount of + storage required to hold the value. + + .. versionadded:: 1.12.0 + + .. versionchanged:: 1.26.0 `UV_MAXHOSTNAMESIZE` is available and represents + the maximum `buffer` size required to store a + hostname and terminating `nul` character. + +.. c:function:: int uv_os_getpriority(uv_pid_t pid, int* priority) + + Retrieves the scheduling priority of the process specified by `pid`. The + returned value of `priority` is between -20 (high priority) and 19 (low + priority). + + .. note:: + On Windows, the returned priority will equal one of the `UV_PRIORITY` + constants. + + .. versionadded:: 1.23.0 + +.. c:function:: int uv_os_setpriority(uv_pid_t pid, int priority) + + Sets the scheduling priority of the process specified by `pid`. The + `priority` value range is between -20 (high priority) and 19 (low priority). + The constants `UV_PRIORITY_LOW`, `UV_PRIORITY_BELOW_NORMAL`, + `UV_PRIORITY_NORMAL`, `UV_PRIORITY_ABOVE_NORMAL`, `UV_PRIORITY_HIGH`, and + `UV_PRIORITY_HIGHEST` are also provided for convenience. + + .. note:: + On Windows, this function utilizes `SetPriorityClass()`. The `priority` + argument is mapped to a Windows priority class. When retrieving the + process priority, the result will equal one of the `UV_PRIORITY` + constants, and not necessarily the exact value of `priority`. + + .. note:: + On Windows, setting `PRIORITY_HIGHEST` will only work for elevated user, + for others it will be silently reduced to `PRIORITY_HIGH`. + + .. note:: + On IBM i PASE, the highest process priority is -10. The constant + `UV_PRIORITY_HIGHEST` is -10, `UV_PRIORITY_HIGH` is -7, + `UV_PRIORITY_ABOVE_NORMAL` is -4, `UV_PRIORITY_NORMAL` is 0, + `UV_PRIORITY_BELOW_NORMAL` is 15 and `UV_PRIORITY_LOW` is 39. + + .. note:: + On IBM i PASE, you are not allowed to change your priority unless you + have the \*JOBCTL special authority (even to lower it). + + .. versionadded:: 1.23.0 + +.. c:function:: int uv_os_uname(uv_utsname_t* buffer) + + Retrieves system information in `buffer`. The populated data includes the + operating system name, release, version, and machine. On non-Windows + systems, `uv_os_uname()` is a thin wrapper around :man:`uname(2)`. Returns + zero on success, and a non-zero error value otherwise. + + .. versionadded:: 1.25.0 + +.. c:function:: int uv_gettimeofday(uv_timeval64_t* tv) + + Cross-platform implementation of :man:`gettimeofday(2)`. The timezone + argument to `gettimeofday()` is not supported, as it is considered obsolete. + + .. versionadded:: 1.28.0 + +.. c:function:: int uv_random(uv_loop_t* loop, uv_random_t* req, void* buf, size_t buflen, unsigned int flags, uv_random_cb cb) + + Fill `buf` with exactly `buflen` cryptographically strong random bytes + acquired from the system CSPRNG. `flags` is reserved for future extension + and must currently be 0. + + Short reads are not possible. When less than `buflen` random bytes are + available, a non-zero error value is returned or passed to the callback. + + The synchronous version may block indefinitely when not enough entropy + is available. The asynchronous version may not ever finish when the system + is low on entropy. + + Sources of entropy: + + - Windows: `RtlGenRandom _`. + - Linux, Android: :man:`getrandom(2)` if available, or :man:`urandom(4)` + after reading from `/dev/random` once, or the `KERN_RANDOM` + :man:`sysctl(2)`. + - FreeBSD: `getrandom(2) _`, + or `/dev/urandom` after reading from `/dev/random` once. + - NetBSD: `KERN_ARND` `sysctl(3) _` + - macOS, OpenBSD: `getentropy(2) _` + if available, or `/dev/urandom` after reading from `/dev/random` once. + - AIX: `/dev/random`. + - IBM i: `/dev/urandom`. + - Other UNIX: `/dev/urandom` after reading from `/dev/random` once. + + :returns: 0 on success, or an error code < 0 on failure. The contents of + `buf` is undefined after an error. + + .. note:: + When using the synchronous version, both `loop` and `req` parameters + are not used and can be set to `NULL`. + + .. versionadded:: 1.33.0 + +.. c:function:: void uv_sleep(unsigned int msec) + + Causes the calling thread to sleep for `msec` milliseconds. + + .. versionadded:: 1.34.0 diff --git a/external/src/libuv/docs/src/pipe.rst b/external/src/libuv/docs/src/pipe.rst new file mode 100644 index 0000000..5fa83b8 --- /dev/null +++ b/external/src/libuv/docs/src/pipe.rst @@ -0,0 +1,138 @@ + +.. _pipe: + +:c:type:`uv_pipe_t` --- Pipe handle +=================================== + +Pipe handles provide an abstraction over streaming files on Unix (including +local domain sockets, pipes, and FIFOs) and named pipes on Windows. + +:c:type:`uv_pipe_t` is a 'subclass' of :c:type:`uv_stream_t`. + + +Data types +---------- + +.. c:type:: uv_pipe_t + + Pipe handle type. + + +Public members +^^^^^^^^^^^^^^ + +.. c:member:: int uv_pipe_t.ipc + + Whether this pipe is suitable for handle passing between processes. + Only a connected pipe that will be passing the handles should have this flag + set, not the listening pipe that uv_accept is called on. + +.. seealso:: The :c:type:`uv_stream_t` members also apply. + + +API +--- + +.. c:function:: int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) + + Initialize a pipe handle. The `ipc` argument is a boolean to indicate if + this pipe will be used for handle passing between processes (which may + change the bytes on the wire). Only a connected pipe that will be + passing the handles should have this flag set, not the listening pipe + that uv_accept is called on. + +.. c:function:: int uv_pipe_open(uv_pipe_t* handle, uv_file file) + + Open an existing file descriptor or HANDLE as a pipe. + + .. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode. + + .. note:: + The passed file descriptor or HANDLE is not checked for its type, but + it's required that it represents a valid pipe. + +.. c:function:: int uv_pipe_bind(uv_pipe_t* handle, const char* name) + + Bind the pipe to a file path (Unix) or a name (Windows). + + .. note:: + Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes, typically between + 92 and 108 bytes. + +.. c:function:: void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, const char* name, uv_connect_cb cb) + + Connect to the Unix domain socket or the named pipe. + + .. note:: + Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes, typically between + 92 and 108 bytes. + +.. c:function:: int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) + + Get the name of the Unix domain socket or the named pipe. + + A preallocated buffer must be provided. The size parameter holds the length + of the buffer and it's set to the number of bytes written to the buffer on + output. If the buffer is not big enough ``UV_ENOBUFS`` will be returned and + len will contain the required size. + + .. versionchanged:: 1.3.0 the returned length no longer includes the terminating null byte, + and the buffer is not null terminated. + +.. c:function:: int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) + + Get the name of the Unix domain socket or the named pipe to which the handle + is connected. + + A preallocated buffer must be provided. The size parameter holds the length + of the buffer and it's set to the number of bytes written to the buffer on + output. If the buffer is not big enough ``UV_ENOBUFS`` will be returned and + len will contain the required size. + + .. versionadded:: 1.3.0 + +.. c:function:: void uv_pipe_pending_instances(uv_pipe_t* handle, int count) + + Set the number of pending pipe instance handles when the pipe server is + waiting for connections. + + .. note:: + This setting applies to Windows only. + +.. c:function:: int uv_pipe_pending_count(uv_pipe_t* handle) +.. c:function:: uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) + + Used to receive handles over IPC pipes. + + First - call :c:func:`uv_pipe_pending_count`, if it's > 0 then initialize + a handle of the given `type`, returned by :c:func:`uv_pipe_pending_type` + and call ``uv_accept(pipe, handle)``. + +.. seealso:: The :c:type:`uv_stream_t` API functions also apply. + +.. c:function:: int uv_pipe_chmod(uv_pipe_t* handle, int flags) + + Alters pipe permissions, allowing it to be accessed from processes run by + different users. Makes the pipe writable or readable by all users. Mode can + be ``UV_WRITABLE``, ``UV_READABLE`` or ``UV_WRITABLE | UV_READABLE``. This + function is blocking. + + .. versionadded:: 1.16.0 + +.. c:function:: int uv_pipe(uv_file fds[2], int read_flags, int write_flags) + + Create a pair of connected pipe handles. + Data may be written to `fds[1]` and read from `fds[0]`. + The resulting handles can be passed to `uv_pipe_open`, used with `uv_spawn`, + or for any other purpose. + + Valid values for `flags` are: + + - UV_NONBLOCK_PIPE: Opens the specified socket handle for `OVERLAPPED` + or `FIONBIO`/`O_NONBLOCK` I/O usage. + This is recommended for handles that will be used by libuv, + and not usually recommended otherwise. + + Equivalent to :man:`pipe(2)` with the `O_CLOEXEC` flag set. + + .. versionadded:: 1.41.0 diff --git a/external/src/libuv/docs/src/poll.rst b/external/src/libuv/docs/src/poll.rst new file mode 100644 index 0000000..93a101e --- /dev/null +++ b/external/src/libuv/docs/src/poll.rst @@ -0,0 +1,148 @@ + +.. _poll: + +:c:type:`uv_poll_t` --- Poll handle +=================================== + +Poll handles are used to watch file descriptors for readability, +writability and disconnection similar to the purpose of :man:`poll(2)`. + +The purpose of poll handles is to enable integrating external libraries that +rely on the event loop to signal it about the socket status changes, like +c-ares or libssh2. Using uv_poll_t for any other purpose is not recommended; +:c:type:`uv_tcp_t`, :c:type:`uv_udp_t`, etc. provide an implementation that is faster and +more scalable than what can be achieved with :c:type:`uv_poll_t`, especially on +Windows. + +It is possible that poll handles occasionally signal that a file descriptor is +readable or writable even when it isn't. The user should therefore always +be prepared to handle EAGAIN or equivalent when it attempts to read from or +write to the fd. + +It is not okay to have multiple active poll handles for the same socket, this +can cause libuv to busyloop or otherwise malfunction. + +The user should not close a file descriptor while it is being polled by an +active poll handle. This can cause the handle to report an error, +but it might also start polling another socket. However the fd can be safely +closed immediately after a call to :c:func:`uv_poll_stop` or :c:func:`uv_close`. + +.. note:: + On windows only sockets can be polled with poll handles. On Unix any file + descriptor that would be accepted by :man:`poll(2)` can be used. + +.. note:: + On AIX, watching for disconnection is not supported. + +Data types +---------- + +.. c:type:: uv_poll_t + + Poll handle type. + +.. c:type:: void (*uv_poll_cb)(uv_poll_t* handle, int status, int events) + + Type definition for callback passed to :c:func:`uv_poll_start`. + +.. c:type:: uv_poll_event + + Poll event types + + :: + + enum uv_poll_event { + UV_READABLE = 1, + UV_WRITABLE = 2, + UV_DISCONNECT = 4, + UV_PRIORITIZED = 8 + }; + + +Public members +^^^^^^^^^^^^^^ + +N/A + +.. seealso:: The :c:type:`uv_handle_t` members also apply. + + +API +--- + +.. c:function:: int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) + + Initialize the handle using a file descriptor. + + .. versionchanged:: 1.2.2 the file descriptor is set to non-blocking mode. + +.. c:function:: int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, uv_os_sock_t socket) + + Initialize the handle using a socket descriptor. On Unix this is identical + to :c:func:`uv_poll_init`. On windows it takes a SOCKET handle. + + .. versionchanged:: 1.2.2 the socket is set to non-blocking mode. + +.. c:function:: int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) + + Starts polling the file descriptor. `events` is a bitmask made up of + `UV_READABLE`, `UV_WRITABLE`, `UV_PRIORITIZED` and `UV_DISCONNECT`. As soon + as an event is detected the callback will be called with `status` set to 0, + and the detected events set on the `events` field. + + The `UV_PRIORITIZED` event is used to watch for sysfs interrupts or TCP + out-of-band messages. + + The `UV_DISCONNECT` event is optional in the sense that it may not be + reported and the user is free to ignore it, but it can help optimize the + shutdown path because an extra read or write call might be avoided. + + If an error happens while polling, `status` will be < 0 and corresponds + with one of the `UV_E*` error codes (see :ref:`errors`). The user should + not close the socket while the handle is active. If the user does that + anyway, the callback *may* be called reporting an error status, but this is + **not** guaranteed. + + .. note:: + Calling :c:func:`uv_poll_start` on a handle that is already active is + fine. Doing so will update the events mask that is being watched for. + + .. note:: + Though `UV_DISCONNECT` can be set, it is unsupported on AIX and as such + will not be set on the `events` field in the callback. + + .. note:: + If one of the events `UV_READABLE` or `UV_WRITABLE` are set, the + callback will be called again, as long as the given fd/socket remains + readable or writable accordingly. Particularly in each of the following + scenarios: + + * The callback has been called because the socket became + readable/writable and the callback did not conduct a read/write on + this socket at all. + * The callback committed a read on the socket, and has not read all the + available data (when `UV_READABLE` is set). + * The callback committed a write on the socket, but it remained + writable afterwards (when `UV_WRITABLE` is set). + * The socket has already became readable/writable before calling + :c:func:`uv_poll_start` on a poll handle associated with this socket, + and since then the state of the socket did not changed. + + In all of the above listed scenarios, the socket remains readable or + writable and hence the callback will be called again (depending on the + events set in the bitmask). This behaviour is known as level + triggering. + + .. versionchanged:: 1.9.0 Added the `UV_DISCONNECT` event. + .. versionchanged:: 1.14.0 Added the `UV_PRIORITIZED` event. + +.. c:function:: int uv_poll_stop(uv_poll_t* poll) + + Stop polling the file descriptor, the callback will no longer be called. + + .. note:: + Calling :c:func:`uv_poll_stop` is effective immediately: any pending + callback is also canceled, even if the socket state change notification + was already pending. + +.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/external/src/libuv/docs/src/prepare.rst b/external/src/libuv/docs/src/prepare.rst new file mode 100644 index 0000000..5e0d247 --- /dev/null +++ b/external/src/libuv/docs/src/prepare.rst @@ -0,0 +1,54 @@ + +.. _prepare: + +:c:type:`uv_prepare_t` --- Prepare handle +========================================= + +Prepare handles will run the given callback once per loop iteration, right +before polling for i/o. + + +Data types +---------- + +.. c:type:: uv_prepare_t + + Prepare handle type. + +.. c:type:: void (*uv_prepare_cb)(uv_prepare_t* handle) + + Type definition for callback passed to :c:func:`uv_prepare_start`. + + +Public members +^^^^^^^^^^^^^^ + +N/A + +.. seealso:: The :c:type:`uv_handle_t` members also apply. + + +API +--- + +.. c:function:: int uv_prepare_init(uv_loop_t* loop, uv_prepare_t* prepare) + + Initialize the handle. This function always succeeds. + + :returns: 0 + +.. c:function:: int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb) + + Start the handle with the given callback. This function always succeeds, + except when `cb` is `NULL`. + + :returns: 0 on success, or `UV_EINVAL` when `cb == NULL`. + +.. c:function:: int uv_prepare_stop(uv_prepare_t* prepare) + + Stop the handle, the callback will no longer be called. + This function always succeeds. + + :returns: 0 + +.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/external/src/libuv/docs/src/process.rst b/external/src/libuv/docs/src/process.rst new file mode 100644 index 0000000..ea6c4b9 --- /dev/null +++ b/external/src/libuv/docs/src/process.rst @@ -0,0 +1,251 @@ + +.. _process: + +:c:type:`uv_process_t` --- Process handle +========================================= + +Process handles will spawn a new process and allow the user to control it and +establish communication channels with it using streams. + + +Data types +---------- + +.. c:type:: uv_process_t + + Process handle type. + +.. c:type:: uv_process_options_t + + Options for spawning the process (passed to :c:func:`uv_spawn`. + + :: + + typedef struct uv_process_options_s { + uv_exit_cb exit_cb; + const char* file; + char** args; + char** env; + const char* cwd; + unsigned int flags; + int stdio_count; + uv_stdio_container_t* stdio; + uv_uid_t uid; + uv_gid_t gid; + } uv_process_options_t; + +.. c:type:: void (*uv_exit_cb)(uv_process_t*, int64_t exit_status, int term_signal) + + Type definition for callback passed in :c:type:`uv_process_options_t` which + will indicate the exit status and the signal that caused the process to + terminate, if any. + +.. c:type:: uv_process_flags + + Flags to be set on the flags field of :c:type:`uv_process_options_t`. + + :: + + enum uv_process_flags { + /* + * Set the child process' user id. + */ + UV_PROCESS_SETUID = (1 << 0), + /* + * Set the child process' group id. + */ + UV_PROCESS_SETGID = (1 << 1), + /* + * Do not wrap any arguments in quotes, or perform any other escaping, when + * converting the argument list into a command line string. This option is + * only meaningful on Windows systems. On Unix it is silently ignored. + */ + UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = (1 << 2), + /* + * Spawn the child process in a detached state - this will make it a process + * group leader, and will effectively enable the child to keep running after + * the parent exits. Note that the child process will still keep the + * parent's event loop alive unless the parent process calls uv_unref() on + * the child's process handle. + */ + UV_PROCESS_DETACHED = (1 << 3), + /* + * Hide the subprocess window that would normally be created. This option is + * only meaningful on Windows systems. On Unix it is silently ignored. + */ + UV_PROCESS_WINDOWS_HIDE = (1 << 4), + /* + * Hide the subprocess console window that would normally be created. This + * option is only meaningful on Windows systems. On Unix it is silently + * ignored. + */ + UV_PROCESS_WINDOWS_HIDE_CONSOLE = (1 << 5), + /* + * Hide the subprocess GUI window that would normally be created. This + * option is only meaningful on Windows systems. On Unix it is silently + * ignored. + */ + UV_PROCESS_WINDOWS_HIDE_GUI = (1 << 6) + }; + +.. c:type:: uv_stdio_container_t + + Container for each stdio handle or fd passed to a child process. + + :: + + typedef struct uv_stdio_container_s { + uv_stdio_flags flags; + union { + uv_stream_t* stream; + int fd; + } data; + } uv_stdio_container_t; + +.. c:enum:: uv_stdio_flags + + Flags specifying how a stdio should be transmitted to the child process. + + :: + + typedef enum { + UV_IGNORE = 0x00, + UV_CREATE_PIPE = 0x01, + UV_INHERIT_FD = 0x02, + UV_INHERIT_STREAM = 0x04, + /* + * When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE + * determine the direction of flow, from the child process' perspective. Both + * flags may be specified to create a duplex data stream. + */ + UV_READABLE_PIPE = 0x10, + UV_WRITABLE_PIPE = 0x20, + /* + * When UV_CREATE_PIPE is specified, specifying UV_NONBLOCK_PIPE opens the + * handle in non-blocking mode in the child. This may cause loss of data, + * if the child is not designed to handle to encounter this mode, + * but can also be significantly more efficient. + */ + UV_NONBLOCK_PIPE = 0x40 + } uv_stdio_flags; + + +Public members +^^^^^^^^^^^^^^ + +.. c:member:: int uv_process_t.pid + + The PID of the spawned process. It's set after calling :c:func:`uv_spawn`. + +.. note:: + The :c:type:`uv_handle_t` members also apply. + +.. c:member:: uv_exit_cb uv_process_options_t.exit_cb + + Callback called after the process exits. + +.. c:member:: const char* uv_process_options_t.file + + Path pointing to the program to be executed. + +.. c:member:: char** uv_process_options_t.args + + Command line arguments. args[0] should be the path to the program. On + Windows this uses `CreateProcess` which concatenates the arguments into a + string this can cause some strange errors. See the + ``UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS`` flag on :c:type:`uv_process_flags`. + +.. c:member:: char** uv_process_options_t.env + + Environment for the new process. If NULL the parents environment is used. + +.. c:member:: const char* uv_process_options_t.cwd + + Current working directory for the subprocess. + +.. c:member:: unsigned int uv_process_options_t.flags + + Various flags that control how :c:func:`uv_spawn` behaves. See + :c:type:`uv_process_flags`. + +.. c:member:: int uv_process_options_t.stdio_count +.. c:member:: uv_stdio_container_t* uv_process_options_t.stdio + + The `stdio` field points to an array of :c:type:`uv_stdio_container_t` + structs that describe the file descriptors that will be made available to + the child process. The convention is that stdio[0] points to stdin, + fd 1 is used for stdout, and fd 2 is stderr. + + .. note:: + On Windows file descriptors greater than 2 are available to the child process only if + the child processes uses the MSVCRT runtime. + +.. c:member:: uv_uid_t uv_process_options_t.uid +.. c:member:: uv_gid_t uv_process_options_t.gid + + Libuv can change the child process' user/group id. This happens only when + the appropriate bits are set in the flags fields. + + .. note:: + This is not supported on Windows, :c:func:`uv_spawn` will fail and set the error + to ``UV_ENOTSUP``. + +.. c:member:: uv_stdio_flags uv_stdio_container_t.flags + + Flags specifying how the stdio container should be passed to the child. + +.. c:member:: union @0 uv_stdio_container_t.data + + Union containing either the `stream` or `fd` to be passed on to the child + process. + + +API +--- + +.. c:function:: void uv_disable_stdio_inheritance(void) + + Disables inheritance for file descriptors / handles that this process + inherited from its parent. The effect is that child processes spawned by + this process don't accidentally inherit these handles. + + It is recommended to call this function as early in your program as possible, + before the inherited file descriptors can be closed or duplicated. + + .. note:: + This function works on a best-effort basis: there is no guarantee that libuv can discover + all file descriptors that were inherited. In general it does a better job on Windows than + it does on Unix. + +.. c:function:: int uv_spawn(uv_loop_t* loop, uv_process_t* handle, const uv_process_options_t* options) + + Initializes the process handle and starts the process. If the process is + successfully spawned, this function will return 0. Otherwise, the + negative error code corresponding to the reason it couldn't spawn is + returned. + + Possible reasons for failing to spawn would include (but not be limited to) + the file to execute not existing, not having permissions to use the setuid or + setgid specified, or not having enough memory to allocate for the new + process. + + .. versionchanged:: 1.24.0 Added `UV_PROCESS_WINDOWS_HIDE_CONSOLE` and + `UV_PROCESS_WINDOWS_HIDE_GUI` flags. + +.. c:function:: int uv_process_kill(uv_process_t* handle, int signum) + + Sends the specified signal to the given process handle. Check the documentation + on :c:ref:`signal` for signal support, specially on Windows. + +.. c:function:: int uv_kill(int pid, int signum) + + Sends the specified signal to the given PID. Check the documentation + on :c:ref:`signal` for signal support, specially on Windows. + +.. c:function:: uv_pid_t uv_process_get_pid(const uv_process_t* handle) + + Returns `handle->pid`. + + .. versionadded:: 1.19.0 + +.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/external/src/libuv/docs/src/request.rst b/external/src/libuv/docs/src/request.rst new file mode 100644 index 0000000..a041443 --- /dev/null +++ b/external/src/libuv/docs/src/request.rst @@ -0,0 +1,117 @@ + +.. _request: + +:c:type:`uv_req_t` --- Base request +=================================== + +`uv_req_t` is the base type for all libuv request types. + +Structures are aligned so that any libuv request can be cast to `uv_req_t`. +All API functions defined here work with any request type. + + +Data types +---------- + +.. c:type:: uv_req_t + + The base libuv request structure. + +.. c:type:: uv_any_req + + Union of all request types. + + +Public members +^^^^^^^^^^^^^^ + +.. c:member:: void* uv_req_t.data + + Space for user-defined arbitrary data. libuv does not use this field. + +.. c:member:: uv_req_type uv_req_t.type + + Indicated the type of request. Readonly. + + :: + + typedef enum { + UV_UNKNOWN_REQ = 0, + UV_REQ, + UV_CONNECT, + UV_WRITE, + UV_SHUTDOWN, + UV_UDP_SEND, + UV_FS, + UV_WORK, + UV_GETADDRINFO, + UV_GETNAMEINFO, + UV_REQ_TYPE_MAX, + } uv_req_type; + + +API +--- + +.. c:macro:: UV_REQ_TYPE_MAP(iter_macro) + + Macro that expands to a series of invocations of `iter_macro` for + each of the request types. `iter_macro` is invoked with two + arguments: the name of the `uv_req_type` element without the `UV_` + prefix, and the name of the corresponding structure type without the + `uv_` prefix and `_t` suffix. + +.. c:function:: int uv_cancel(uv_req_t* req) + + Cancel a pending request. Fails if the request is executing or has finished + executing. + + Returns 0 on success, or an error code < 0 on failure. + + Only cancellation of :c:type:`uv_fs_t`, :c:type:`uv_getaddrinfo_t`, + :c:type:`uv_getnameinfo_t`, :c:type:`uv_random_t` and :c:type:`uv_work_t` + requests is currently supported. + + Cancelled requests have their callbacks invoked some time in the future. + It's **not** safe to free the memory associated with the request until the + callback is called. + + Here is how cancellation is reported to the callback: + + * A :c:type:`uv_fs_t` request has its req->result field set to `UV_ECANCELED`. + + * A :c:type:`uv_work_t`, :c:type:`uv_getaddrinfo_t`, + :c:type:`uv_getnameinfo_t` or :c:type:`uv_random_t` request has its + callback invoked with status == `UV_ECANCELED`. + +.. c:function:: size_t uv_req_size(uv_req_type type) + + Returns the size of the given request type. Useful for FFI binding writers + who don't want to know the structure layout. + +.. c:function:: void* uv_req_get_data(const uv_req_t* req) + + Returns `req->data`. + + .. versionadded:: 1.19.0 + +.. c:function:: void* uv_req_set_data(uv_req_t* req, void* data) + + Sets `req->data` to `data`. + + .. versionadded:: 1.19.0 + +.. c:function:: uv_req_type uv_req_get_type(const uv_req_t* req) + + Returns `req->type`. + + .. versionadded:: 1.19.0 + +.. c:function:: const char* uv_req_type_name(uv_req_type type) + + Returns the name for the equivalent struct for a given request type, + e.g. `"connect"` (as in :c:type:`uv_connect_t`) for `UV_CONNECT`. + + If no such request type exists, this returns `NULL`. + + .. versionadded:: 1.19.0 diff --git a/external/src/libuv/docs/src/signal.rst b/external/src/libuv/docs/src/signal.rst new file mode 100644 index 0000000..eeadb95 --- /dev/null +++ b/external/src/libuv/docs/src/signal.rst @@ -0,0 +1,101 @@ + +.. _signal: + +:c:type:`uv_signal_t` --- Signal handle +======================================= + +Signal handles implement Unix style signal handling on a per-event loop bases. + +Windows notes +------------- + +Reception of some signals is emulated: + +* SIGINT is normally delivered when the user presses CTRL+C. However, like + on Unix, it is not generated when terminal raw mode is enabled. + +* SIGBREAK is delivered when the user pressed CTRL + BREAK. + +* SIGHUP is generated when the user closes the console window. On SIGHUP the + program is given approximately 10 seconds to perform cleanup. After that + Windows will unconditionally terminate it. + +* SIGWINCH is raised whenever libuv detects that the console has been + resized. When a libuv app is running under a console emulator, or when a + 32-bit libuv app is running on 64-bit system, SIGWINCH will be emulated. In + such cases SIGWINCH signals may not always be delivered in a timely manner. + For a writable :c:type:`uv_tty_t` handle libuv will only detect size changes + when the cursor is moved. When a readable :c:type:`uv_tty_t` handle is used, + resizing of the console buffer will be detected only if the handle is in raw + mode and is being read. + +* Watchers for other signals can be successfully created, but these signals + are never received. These signals are: `SIGILL`, `SIGABRT`, `SIGFPE`, `SIGSEGV`, + `SIGTERM` and `SIGKILL.` + +* Calls to raise() or abort() to programmatically raise a signal are + not detected by libuv; these will not trigger a signal watcher. + +.. versionchanged:: 1.15.0 SIGWINCH support on Windows was improved. +.. versionchanged:: 1.31.0 32-bit libuv SIGWINCH support on 64-bit Windows was + rolled back to old implementation. + +Unix notes +---------- + +* SIGKILL and SIGSTOP are impossible to catch. + +* Handling SIGBUS, SIGFPE, SIGILL or SIGSEGV via libuv results into undefined behavior. + +* SIGABRT will not be caught by libuv if generated by `abort()`, e.g. through `assert()`. + +* On Linux SIGRT0 and SIGRT1 (signals 32 and 33) are used by the NPTL pthreads library to + manage threads. Installing watchers for those signals will lead to unpredictable behavior + and is strongly discouraged. Future versions of libuv may simply reject them. + + +Data types +---------- + +.. c:type:: uv_signal_t + + Signal handle type. + +.. c:type:: void (*uv_signal_cb)(uv_signal_t* handle, int signum) + + Type definition for callback passed to :c:func:`uv_signal_start`. + + +Public members +^^^^^^^^^^^^^^ + +.. c:member:: int uv_signal_t.signum + + Signal being monitored by this handle. Readonly. + +.. seealso:: The :c:type:`uv_handle_t` members also apply. + + +API +--- + +.. c:function:: int uv_signal_init(uv_loop_t* loop, uv_signal_t* signal) + + Initialize the handle. + +.. c:function:: int uv_signal_start(uv_signal_t* signal, uv_signal_cb cb, int signum) + + Start the handle with the given callback, watching for the given signal. + +.. c:function:: int uv_signal_start_oneshot(uv_signal_t* signal, uv_signal_cb cb, int signum) + + .. versionadded:: 1.12.0 + + Same functionality as :c:func:`uv_signal_start` but the signal handler is reset the moment + the signal is received. + +.. c:function:: int uv_signal_stop(uv_signal_t* signal) + + Stop the handle, the callback will no longer be called. + +.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/external/src/libuv/docs/src/sphinx-plugins/manpage.py b/external/src/libuv/docs/src/sphinx-plugins/manpage.py new file mode 100644 index 0000000..6570aea --- /dev/null +++ b/external/src/libuv/docs/src/sphinx-plugins/manpage.py @@ -0,0 +1,45 @@ +# encoding: utf-8 + +# +# Copyright (c) 2013 Dariusz Dwornikowski. All rights reserved. +# +# Adapted from https://github.com/tdi/sphinxcontrib-manpage +# License: Apache 2 +# + + +import re + +from docutils import nodes, utils +from docutils.parsers.rst.roles import set_classes +from string import Template + + +def make_link_node(rawtext, app, name, manpage_num, options): + ref = app.config.man_url_regex + if not ref: + ref = "https://man7.org/linux/man-pages/man%s/%s.%s.html" %(manpage_num, name, manpage_num) + else: + s = Template(ref) + ref = s.substitute(num=manpage_num, topic=name) + set_classes(options) + node = nodes.reference(rawtext, "%s(%s)" % (name, manpage_num), refuri=ref, **options) + return node + + +def man_role(name, rawtext, text, lineno, inliner, options={}, content=[]): + app = inliner.document.settings.env.app + p = re.compile("([a-zA-Z0-9_\.-_]+)\((\d)\)") + m = p.match(text) + + manpage_num = m.group(2) + name = m.group(1) + node = make_link_node(rawtext, app, name, manpage_num, options) + return [node], [] + + +def setup(app): + app.add_role('man', man_role) + app.add_config_value('man_url_regex', None, 'env') + return + diff --git a/external/src/libuv/docs/src/static/architecture.png b/external/src/libuv/docs/src/static/architecture.png new file mode 100644 index 0000000..81e8749 Binary files /dev/null and b/external/src/libuv/docs/src/static/architecture.png differ diff --git a/external/src/libuv/docs/src/static/diagrams.key/Data/st0-311.jpg b/external/src/libuv/docs/src/static/diagrams.key/Data/st0-311.jpg new file mode 100644 index 0000000..08f23a9 Binary files /dev/null and b/external/src/libuv/docs/src/static/diagrams.key/Data/st0-311.jpg differ diff --git a/external/src/libuv/docs/src/static/diagrams.key/Data/st1-475.jpg b/external/src/libuv/docs/src/static/diagrams.key/Data/st1-475.jpg new file mode 100644 index 0000000..26e676a Binary files /dev/null and b/external/src/libuv/docs/src/static/diagrams.key/Data/st1-475.jpg differ diff --git a/external/src/libuv/docs/src/static/diagrams.key/Index.zip b/external/src/libuv/docs/src/static/diagrams.key/Index.zip new file mode 100644 index 0000000..17aedac Binary files /dev/null and b/external/src/libuv/docs/src/static/diagrams.key/Index.zip differ diff --git a/external/src/libuv/docs/src/static/diagrams.key/Metadata/BuildVersionHistory.plist b/external/src/libuv/docs/src/static/diagrams.key/Metadata/BuildVersionHistory.plist new file mode 100644 index 0000000..39dd4fe --- /dev/null +++ b/external/src/libuv/docs/src/static/diagrams.key/Metadata/BuildVersionHistory.plist @@ -0,0 +1,8 @@ + + + + + Template: White (2014-02-28 09:41) + M6.2.2-1878-1 + + diff --git a/external/src/libuv/docs/src/static/diagrams.key/Metadata/DocumentIdentifier b/external/src/libuv/docs/src/static/diagrams.key/Metadata/DocumentIdentifier new file mode 100644 index 0000000..ddb18f0 --- /dev/null +++ b/external/src/libuv/docs/src/static/diagrams.key/Metadata/DocumentIdentifier @@ -0,0 +1 @@ +F69E9CD9-EEF1-4223-9DA4-A1EA7FE112BA \ No newline at end of file diff --git a/external/src/libuv/docs/src/static/diagrams.key/Metadata/Properties.plist b/external/src/libuv/docs/src/static/diagrams.key/Metadata/Properties.plist new file mode 100644 index 0000000..74bc693 Binary files /dev/null and b/external/src/libuv/docs/src/static/diagrams.key/Metadata/Properties.plist differ diff --git a/external/src/libuv/docs/src/static/diagrams.key/preview-micro.jpg b/external/src/libuv/docs/src/static/diagrams.key/preview-micro.jpg new file mode 100644 index 0000000..dd8decd Binary files /dev/null and b/external/src/libuv/docs/src/static/diagrams.key/preview-micro.jpg differ diff --git a/external/src/libuv/docs/src/static/diagrams.key/preview-web.jpg b/external/src/libuv/docs/src/static/diagrams.key/preview-web.jpg new file mode 100644 index 0000000..aadd401 Binary files /dev/null and b/external/src/libuv/docs/src/static/diagrams.key/preview-web.jpg differ diff --git a/external/src/libuv/docs/src/static/diagrams.key/preview.jpg b/external/src/libuv/docs/src/static/diagrams.key/preview.jpg new file mode 100644 index 0000000..fc80025 Binary files /dev/null and b/external/src/libuv/docs/src/static/diagrams.key/preview.jpg differ diff --git a/external/src/libuv/docs/src/static/favicon.ico b/external/src/libuv/docs/src/static/favicon.ico new file mode 100644 index 0000000..2c40694 Binary files /dev/null and b/external/src/libuv/docs/src/static/favicon.ico differ diff --git a/external/src/libuv/docs/src/static/logo.png b/external/src/libuv/docs/src/static/logo.png new file mode 100644 index 0000000..eaf1eee Binary files /dev/null and b/external/src/libuv/docs/src/static/logo.png differ diff --git a/external/src/libuv/docs/src/static/loop_iteration.png b/external/src/libuv/docs/src/static/loop_iteration.png new file mode 100644 index 0000000..e769cf3 Binary files /dev/null and b/external/src/libuv/docs/src/static/loop_iteration.png differ diff --git a/external/src/libuv/docs/src/stream.rst b/external/src/libuv/docs/src/stream.rst new file mode 100644 index 0000000..0b42c4b --- /dev/null +++ b/external/src/libuv/docs/src/stream.rst @@ -0,0 +1,258 @@ + +.. _stream: + +:c:type:`uv_stream_t` --- Stream handle +======================================= + +Stream handles provide an abstraction of a duplex communication channel. +:c:type:`uv_stream_t` is an abstract type, libuv provides 3 stream implementations +in the form of :c:type:`uv_tcp_t`, :c:type:`uv_pipe_t` and :c:type:`uv_tty_t`. + + +Data types +---------- + +.. c:type:: uv_stream_t + + Stream handle type. + +.. c:type:: uv_connect_t + + Connect request type. + +.. c:type:: uv_shutdown_t + + Shutdown request type. + +.. c:type:: uv_write_t + + Write request type. Careful attention must be paid when reusing objects of + this type. When a stream is in non-blocking mode, write requests sent + with ``uv_write`` will be queued. Reusing objects at this point is undefined + behaviour. It is safe to reuse the ``uv_write_t`` object only after the + callback passed to ``uv_write`` is fired. + +.. c:type:: void (*uv_read_cb)(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) + + Callback called when data was read on a stream. + + `nread` is > 0 if there is data available or < 0 on error. When we've + reached EOF, `nread` will be set to ``UV_EOF``. When `nread` < 0, + the `buf` parameter might not point to a valid buffer; in that case + `buf.len` and `buf.base` are both set to 0. + + .. note:: + `nread` might be 0, which does *not* indicate an error or EOF. This + is equivalent to ``EAGAIN`` or ``EWOULDBLOCK`` under ``read(2)``. + + The callee is responsible for stopping/closing the stream when an error happens + by calling :c:func:`uv_read_stop` or :c:func:`uv_close`. Trying to read + from the stream again is undefined. + + The callee is responsible for freeing the buffer, libuv does not reuse it. + The buffer may be a null buffer (where `buf->base` == NULL and `buf->len` == 0) + on error. + +.. c:type:: void (*uv_write_cb)(uv_write_t* req, int status) + + Callback called after data was written on a stream. `status` will be 0 in + case of success, < 0 otherwise. + +.. c:type:: void (*uv_connect_cb)(uv_connect_t* req, int status) + + Callback called after a connection started by :c:func:`uv_connect` is done. + `status` will be 0 in case of success, < 0 otherwise. + +.. c:type:: void (*uv_shutdown_cb)(uv_shutdown_t* req, int status) + + Callback called after a shutdown request has been completed. `status` will + be 0 in case of success, < 0 otherwise. + +.. c:type:: void (*uv_connection_cb)(uv_stream_t* server, int status) + + Callback called when a stream server has received an incoming connection. + The user can accept the connection by calling :c:func:`uv_accept`. + `status` will be 0 in case of success, < 0 otherwise. + + +Public members +^^^^^^^^^^^^^^ + +.. c:member:: size_t uv_stream_t.write_queue_size + + Contains the amount of queued bytes waiting to be sent. Readonly. + +.. c:member:: uv_stream_t* uv_connect_t.handle + + Pointer to the stream where this connection request is running. + +.. c:member:: uv_stream_t* uv_shutdown_t.handle + + Pointer to the stream where this shutdown request is running. + +.. c:member:: uv_stream_t* uv_write_t.handle + + Pointer to the stream where this write request is running. + +.. c:member:: uv_stream_t* uv_write_t.send_handle + + Pointer to the stream being sent using this write request. + +.. seealso:: The :c:type:`uv_handle_t` members also apply. + + +API +--- + +.. c:function:: int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) + + Shutdown the outgoing (write) side of a duplex stream. It waits for pending + write requests to complete. The `handle` should refer to a initialized stream. + `req` should be an uninitialized shutdown request struct. The `cb` is called + after shutdown is complete. + +.. c:function:: int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) + + Start listening for incoming connections. `backlog` indicates the number of + connections the kernel might queue, same as :man:`listen(2)`. When a new + incoming connection is received the :c:type:`uv_connection_cb` callback is + called. + +.. c:function:: int uv_accept(uv_stream_t* server, uv_stream_t* client) + + This call is used in conjunction with :c:func:`uv_listen` to accept incoming + connections. Call this function after receiving a :c:type:`uv_connection_cb` + to accept the connection. Before calling this function the client handle must + be initialized. < 0 return value indicates an error. + + When the :c:type:`uv_connection_cb` callback is called it is guaranteed that + this function will complete successfully the first time. If you attempt to use + it more than once, it may fail. It is suggested to only call this function once + per :c:type:`uv_connection_cb` call. + + .. note:: + `server` and `client` must be handles running on the same loop. + +.. c:function:: int uv_read_start(uv_stream_t* stream, uv_alloc_cb alloc_cb, uv_read_cb read_cb) + + Read data from an incoming stream. The :c:type:`uv_read_cb` callback will + be made several times until there is no more data to read or + :c:func:`uv_read_stop` is called. + + .. versionchanged:: 1.38.0 :c:func:`uv_read_start()` now consistently + returns `UV_EALREADY` when called twice, and `UV_EINVAL` when the + stream is closing. With older libuv versions, it returns `UV_EALREADY` + on Windows but not UNIX, and `UV_EINVAL` on UNIX but not Windows. + +.. c:function:: int uv_read_stop(uv_stream_t*) + + Stop reading data from the stream. The :c:type:`uv_read_cb` callback will + no longer be called. + + This function is idempotent and may be safely called on a stopped stream. + + This function will always succeed; hence, checking its return value is + unnecessary. A non-zero return indicates that finishing releasing resources + may be pending on the next input event on that TTY on Windows, and does not + indicate failure. + +.. c:function:: int uv_write(uv_write_t* req, uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb) + + Write data to stream. Buffers are written in order. Example: + + :: + + void cb(uv_write_t* req, int status) { + /* Logic which handles the write result */ + } + + uv_buf_t a[] = { + { .base = "1", .len = 1 }, + { .base = "2", .len = 1 } + }; + + uv_buf_t b[] = { + { .base = "3", .len = 1 }, + { .base = "4", .len = 1 } + }; + + uv_write_t req1; + uv_write_t req2; + + /* writes "1234" */ + uv_write(&req1, stream, a, 2, cb); + uv_write(&req2, stream, b, 2, cb); + + .. note:: + The memory pointed to by the buffers must remain valid until the callback gets called. + This also holds for :c:func:`uv_write2`. + +.. c:function:: int uv_write2(uv_write_t* req, uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle, uv_write_cb cb) + + Extended write function for sending handles over a pipe. The pipe must be + initialized with `ipc` == 1. + + .. note:: + `send_handle` must be a TCP, pipe and UDP handle on Unix, or a TCP + handle on Windows, which is a server or a connection (listening or + connected state). Bound sockets or pipes will be assumed to be servers. + +.. c:function:: int uv_try_write(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs) + + Same as :c:func:`uv_write`, but won't queue a write request if it can't be + completed immediately. + + Will return either: + + * > 0: number of bytes written (can be less than the supplied buffer size). + * < 0: negative error code (``UV_EAGAIN`` is returned if no data can be sent + immediately). + +.. c:function:: int uv_try_write2(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle) + + Same as :c:func:`uv_try_write` and extended write function for sending + handles over a pipe like c:func:`uv_write2`. + + Try to send a handle is not supported on Windows, + where it returns ``UV_EAGAIN``. + + .. versionadded:: 1.42.0 + +.. c:function:: int uv_is_readable(const uv_stream_t* handle) + + Returns 1 if the stream is readable, 0 otherwise. + +.. c:function:: int uv_is_writable(const uv_stream_t* handle) + + Returns 1 if the stream is writable, 0 otherwise. + +.. c:function:: int uv_stream_set_blocking(uv_stream_t* handle, int blocking) + + Enable or disable blocking mode for a stream. + + When blocking mode is enabled all writes complete synchronously. The + interface remains unchanged otherwise, e.g. completion or failure of the + operation will still be reported through a callback which is made + asynchronously. + + .. warning:: + Relying too much on this API is not recommended. It is likely to change + significantly in the future. + + Currently only works on Windows for :c:type:`uv_pipe_t` handles. + On UNIX platforms, all :c:type:`uv_stream_t` handles are supported. + + Also libuv currently makes no ordering guarantee when the blocking mode + is changed after write requests have already been submitted. Therefore it is + recommended to set the blocking mode immediately after opening or creating + the stream. + + .. versionchanged:: 1.4.0 UNIX implementation added. + +.. c:function:: size_t uv_stream_get_write_queue_size(const uv_stream_t* stream) + + Returns `stream->write_queue_size`. + + .. versionadded:: 1.19.0 + +.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/external/src/libuv/docs/src/tcp.rst b/external/src/libuv/docs/src/tcp.rst new file mode 100644 index 0000000..cccc86b --- /dev/null +++ b/external/src/libuv/docs/src/tcp.rst @@ -0,0 +1,146 @@ + +.. _tcp: + +:c:type:`uv_tcp_t` --- TCP handle +================================= + +TCP handles are used to represent both TCP streams and servers. + +:c:type:`uv_tcp_t` is a 'subclass' of :c:type:`uv_stream_t`. + + +Data types +---------- + +.. c:type:: uv_tcp_t + + TCP handle type. + + +Public members +^^^^^^^^^^^^^^ + +N/A + +.. seealso:: The :c:type:`uv_stream_t` members also apply. + + +API +--- + +.. c:function:: int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) + + Initialize the handle. No socket is created as of yet. + +.. c:function:: int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* handle, unsigned int flags) + + Initialize the handle with the specified flags. At the moment only the lower 8 bits + of the `flags` parameter are used as the socket domain. A socket will be created + for the given domain. If the specified domain is ``AF_UNSPEC`` no socket is created, + just like :c:func:`uv_tcp_init`. + + .. versionadded:: 1.7.0 + +.. c:function:: int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) + + Open an existing file descriptor or SOCKET as a TCP handle. + + .. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode. + + .. note:: + The passed file descriptor or SOCKET is not checked for its type, but + it's required that it represents a valid stream socket. + +.. c:function:: int uv_tcp_nodelay(uv_tcp_t* handle, int enable) + + Enable `TCP_NODELAY`, which disables Nagle's algorithm. + +.. c:function:: int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) + + Enable / disable TCP keep-alive. `delay` is the initial delay in seconds, + ignored when `enable` is zero. + + After `delay` has been reached, 10 successive probes, each spaced 1 second + from the previous one, will still happen. If the connection is still lost + at the end of this procedure, then the handle is destroyed with a + ``UV_ETIMEDOUT`` error passed to the corresponding callback. + +.. c:function:: int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) + + Enable / disable simultaneous asynchronous accept requests that are + queued by the operating system when listening for new TCP connections. + + This setting is used to tune a TCP server for the desired performance. + Having simultaneous accepts can significantly improve the rate of accepting + connections (which is why it is enabled by default) but may lead to uneven + load distribution in multi-process setups. + +.. c:function:: int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr, unsigned int flags) + + Bind the handle to an address and port. `addr` should point to an + initialized ``struct sockaddr_in`` or ``struct sockaddr_in6``. + + When the port is already taken, you can expect to see an ``UV_EADDRINUSE`` + error from :c:func:`uv_listen` or :c:func:`uv_tcp_connect`. That is, + a successful call to this function does not guarantee that the call + to :c:func:`uv_listen` or :c:func:`uv_tcp_connect` will succeed as well. + + `flags` can contain ``UV_TCP_IPV6ONLY``, in which case dual-stack support + is disabled and only IPv6 is used. + +.. c:function:: int uv_tcp_getsockname(const uv_tcp_t* handle, struct sockaddr* name, int* namelen) + + Get the current address to which the handle is bound. `name` must point to + a valid and big enough chunk of memory, ``struct sockaddr_storage`` is + recommended for IPv4 and IPv6 support. + +.. c:function:: int uv_tcp_getpeername(const uv_tcp_t* handle, struct sockaddr* name, int* namelen) + + Get the address of the peer connected to the handle. `name` must point to + a valid and big enough chunk of memory, ``struct sockaddr_storage`` is + recommended for IPv4 and IPv6 support. + +.. c:function:: int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle, const struct sockaddr* addr, uv_connect_cb cb) + + Establish an IPv4 or IPv6 TCP connection. Provide an initialized TCP handle + and an uninitialized :c:type:`uv_connect_t`. `addr` should point to an + initialized ``struct sockaddr_in`` or ``struct sockaddr_in6``. + + On Windows if the `addr` is initialized to point to an unspecified address + (``0.0.0.0`` or ``::``) it will be changed to point to ``localhost``. + This is done to match the behavior of Linux systems. + + The callback is made when the connection has been established or when a + connection error happened. + + .. versionchanged:: 1.19.0 added ``0.0.0.0`` and ``::`` to ``localhost`` + mapping + +.. seealso:: The :c:type:`uv_stream_t` API functions also apply. + +.. c:function:: int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) + + Resets a TCP connection by sending a RST packet. This is accomplished by + setting the `SO_LINGER` socket option with a linger interval of zero and + then calling :c:func:`uv_close`. + Due to some platform inconsistencies, mixing of :c:func:`uv_shutdown` and + :c:func:`uv_tcp_close_reset` calls is not allowed. + + .. versionadded:: 1.32.0 + +.. c:function:: int uv_socketpair(int type, int protocol, uv_os_sock_t socket_vector[2], int flags0, int flags1) + + Create a pair of connected sockets with the specified properties. + The resulting handles can be passed to `uv_tcp_open`, used with `uv_spawn`, + or for any other purpose. + + Valid values for `flags0` and `flags1` are: + + - UV_NONBLOCK_PIPE: Opens the specified socket handle for `OVERLAPPED` + or `FIONBIO`/`O_NONBLOCK` I/O usage. + This is recommended for handles that will be used by libuv, + and not usually recommended otherwise. + + Equivalent to :man:`socketpair(2)` with a domain of AF_UNIX. + + .. versionadded:: 1.41.0 diff --git a/external/src/libuv/docs/src/threading.rst b/external/src/libuv/docs/src/threading.rst new file mode 100644 index 0000000..7ca1d4b --- /dev/null +++ b/external/src/libuv/docs/src/threading.rst @@ -0,0 +1,197 @@ + +.. _threading: + +Threading and synchronization utilities +======================================= + +libuv provides cross-platform implementations for multiple threading and +synchronization primitives. The API largely follows the pthreads API. + + +Data types +---------- + +.. c:type:: uv_thread_t + + Thread data type. + +.. c:type:: void (*uv_thread_cb)(void* arg) + + Callback that is invoked to initialize thread execution. `arg` is the same + value that was passed to :c:func:`uv_thread_create`. + +.. c:type:: uv_key_t + + Thread-local key data type. + +.. c:type:: uv_once_t + + Once-only initializer data type. + +.. c:type:: uv_mutex_t + + Mutex data type. + +.. c:type:: uv_rwlock_t + + Read-write lock data type. + +.. c:type:: uv_sem_t + + Semaphore data type. + +.. c:type:: uv_cond_t + + Condition data type. + +.. c:type:: uv_barrier_t + + Barrier data type. + + +API +--- + +Threads +^^^^^^^ + +.. c:type:: uv_thread_options_t + + Options for spawning a new thread (passed to :c:func:`uv_thread_create_ex`). + + :: + + typedef struct uv_thread_options_s { + enum { + UV_THREAD_NO_FLAGS = 0x00, + UV_THREAD_HAS_STACK_SIZE = 0x01 + } flags; + size_t stack_size; + } uv_thread_options_t; + + More fields may be added to this struct at any time, so its exact + layout and size should not be relied upon. + + .. versionadded:: 1.26.0 + +.. c:function:: int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg) + + .. versionchanged:: 1.4.1 returns a UV_E* error code on failure + +.. c:function:: int uv_thread_create_ex(uv_thread_t* tid, const uv_thread_options_t* params, uv_thread_cb entry, void* arg) + + Like :c:func:`uv_thread_create`, but additionally specifies options for creating a new thread. + + If `UV_THREAD_HAS_STACK_SIZE` is set, `stack_size` specifies a stack size for the new thread. + `0` indicates that the default value should be used, i.e. behaves as if the flag was not set. + Other values will be rounded up to the nearest page boundary. + + .. versionadded:: 1.26.0 + +.. c:function:: uv_thread_t uv_thread_self(void) +.. c:function:: int uv_thread_join(uv_thread_t *tid) +.. c:function:: int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) + +Thread-local storage +^^^^^^^^^^^^^^^^^^^^ + +.. note:: + The total thread-local storage size may be limited. That is, it may not be possible to + create many TLS keys. + +.. c:function:: int uv_key_create(uv_key_t* key) +.. c:function:: void uv_key_delete(uv_key_t* key) +.. c:function:: void* uv_key_get(uv_key_t* key) +.. c:function:: void uv_key_set(uv_key_t* key, void* value) + +Once-only initialization +^^^^^^^^^^^^^^^^^^^^^^^^ + +Runs a function once and only once. Concurrent calls to :c:func:`uv_once` with the +same guard will block all callers except one (it's unspecified which one). +The guard should be initialized statically with the UV_ONCE_INIT macro. + +.. c:function:: void uv_once(uv_once_t* guard, void (*callback)(void)) + +Mutex locks +^^^^^^^^^^^ + +Functions return 0 on success or an error code < 0 (unless the +return type is void, of course). + +.. c:function:: int uv_mutex_init(uv_mutex_t* handle) +.. c:function:: int uv_mutex_init_recursive(uv_mutex_t* handle) +.. c:function:: void uv_mutex_destroy(uv_mutex_t* handle) +.. c:function:: void uv_mutex_lock(uv_mutex_t* handle) +.. c:function:: int uv_mutex_trylock(uv_mutex_t* handle) +.. c:function:: void uv_mutex_unlock(uv_mutex_t* handle) + +Read-write locks +^^^^^^^^^^^^^^^^ + +Functions return 0 on success or an error code < 0 (unless the +return type is void, of course). + +.. c:function:: int uv_rwlock_init(uv_rwlock_t* rwlock) +.. c:function:: void uv_rwlock_destroy(uv_rwlock_t* rwlock) +.. c:function:: void uv_rwlock_rdlock(uv_rwlock_t* rwlock) +.. c:function:: int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) +.. c:function:: void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) +.. c:function:: void uv_rwlock_wrlock(uv_rwlock_t* rwlock) +.. c:function:: int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) +.. c:function:: void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) + +Semaphores +^^^^^^^^^^ + +Functions return 0 on success or an error code < 0 (unless the +return type is void, of course). + +.. c:function:: int uv_sem_init(uv_sem_t* sem, unsigned int value) +.. c:function:: void uv_sem_destroy(uv_sem_t* sem) +.. c:function:: void uv_sem_post(uv_sem_t* sem) +.. c:function:: void uv_sem_wait(uv_sem_t* sem) +.. c:function:: int uv_sem_trywait(uv_sem_t* sem) + +Conditions +^^^^^^^^^^ + +Functions return 0 on success or an error code < 0 (unless the +return type is void, of course). + +.. note:: + 1. Callers should be prepared to deal with spurious wakeups on :c:func:`uv_cond_wait` + and :c:func:`uv_cond_timedwait`. + 2. The timeout parameter for :c:func:`uv_cond_timedwait` is relative to the time + at which function is called. + 3. On z/OS, the timeout parameter for :c:func:`uv_cond_timedwait` is converted to an + absolute system time at which the wait expires. If the current system clock time + passes the absolute time calculated before the condition is signaled, an ETIMEDOUT + error results. After the wait begins, the wait time is not affected by changes + to the system clock. + +.. c:function:: int uv_cond_init(uv_cond_t* cond) +.. c:function:: void uv_cond_destroy(uv_cond_t* cond) +.. c:function:: void uv_cond_signal(uv_cond_t* cond) +.. c:function:: void uv_cond_broadcast(uv_cond_t* cond) +.. c:function:: void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) +.. c:function:: int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) + +Barriers +^^^^^^^^ + +Functions return 0 on success or an error code < 0 (unless the +return type is void, of course). + +.. note:: + :c:func:`uv_barrier_wait` returns a value > 0 to an arbitrarily chosen "serializer" thread + to facilitate cleanup, i.e. + + :: + + if (uv_barrier_wait(&barrier) > 0) + uv_barrier_destroy(&barrier); + +.. c:function:: int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) +.. c:function:: void uv_barrier_destroy(uv_barrier_t* barrier) +.. c:function:: int uv_barrier_wait(uv_barrier_t* barrier) diff --git a/external/src/libuv/docs/src/threadpool.rst b/external/src/libuv/docs/src/threadpool.rst new file mode 100644 index 0000000..cf6cdc1 --- /dev/null +++ b/external/src/libuv/docs/src/threadpool.rst @@ -0,0 +1,69 @@ + +.. _threadpool: + +Thread pool work scheduling +=========================== + +libuv provides a threadpool which can be used to run user code and get notified +in the loop thread. This thread pool is internally used to run all file system +operations, as well as getaddrinfo and getnameinfo requests. + +Its default size is 4, but it can be changed at startup time by setting the +``UV_THREADPOOL_SIZE`` environment variable to any value (the absolute maximum +is 1024). + +.. versionchanged:: 1.30.0 the maximum UV_THREADPOOL_SIZE allowed was increased from 128 to 1024. + +The threadpool is global and shared across all event loops. When a particular +function makes use of the threadpool (i.e. when using :c:func:`uv_queue_work`) +libuv preallocates and initializes the maximum number of threads allowed by +``UV_THREADPOOL_SIZE``. This causes a relatively minor memory overhead +(~1MB for 128 threads) but increases the performance of threading at runtime. + +.. note:: + Note that even though a global thread pool which is shared across all events + loops is used, the functions are not thread safe. + + +Data types +---------- + +.. c:type:: uv_work_t + + Work request type. + +.. c:type:: void (*uv_work_cb)(uv_work_t* req) + + Callback passed to :c:func:`uv_queue_work` which will be run on the thread + pool. + +.. c:type:: void (*uv_after_work_cb)(uv_work_t* req, int status) + + Callback passed to :c:func:`uv_queue_work` which will be called on the loop + thread after the work on the threadpool has been completed. If the work + was cancelled using :c:func:`uv_cancel` `status` will be ``UV_ECANCELED``. + + +Public members +^^^^^^^^^^^^^^ + +.. c:member:: uv_loop_t* uv_work_t.loop + + Loop that started this request and where completion will be reported. + Readonly. + +.. seealso:: The :c:type:`uv_req_t` members also apply. + + +API +--- + +.. c:function:: int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb, uv_after_work_cb after_work_cb) + + Initializes a work request which will run the given `work_cb` in a thread + from the threadpool. Once `work_cb` is completed, `after_work_cb` will be + called on the loop thread. + + This request can be cancelled with :c:func:`uv_cancel`. + +.. seealso:: The :c:type:`uv_req_t` API functions also apply. diff --git a/external/src/libuv/docs/src/timer.rst b/external/src/libuv/docs/src/timer.rst new file mode 100644 index 0000000..070fa79 --- /dev/null +++ b/external/src/libuv/docs/src/timer.rst @@ -0,0 +1,88 @@ + +.. _timer: + +:c:type:`uv_timer_t` --- Timer handle +===================================== + +Timer handles are used to schedule callbacks to be called in the future. + + +Data types +---------- + +.. c:type:: uv_timer_t + + Timer handle type. + +.. c:type:: void (*uv_timer_cb)(uv_timer_t* handle) + + Type definition for callback passed to :c:func:`uv_timer_start`. + + +Public members +^^^^^^^^^^^^^^ + +N/A + +.. seealso:: The :c:type:`uv_handle_t` members also apply. + + +API +--- + +.. c:function:: int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) + + Initialize the handle. + +.. c:function:: int uv_timer_start(uv_timer_t* handle, uv_timer_cb cb, uint64_t timeout, uint64_t repeat) + + Start the timer. `timeout` and `repeat` are in milliseconds. + + If `timeout` is zero, the callback fires on the next event loop iteration. + If `repeat` is non-zero, the callback fires first after `timeout` + milliseconds and then repeatedly after `repeat` milliseconds. + + .. note:: + Does not update the event loop's concept of "now". See :c:func:`uv_update_time` for more information. + + If the timer is already active, it is simply updated. + +.. c:function:: int uv_timer_stop(uv_timer_t* handle) + + Stop the timer, the callback will not be called anymore. + +.. c:function:: int uv_timer_again(uv_timer_t* handle) + + Stop the timer, and if it is repeating restart it using the repeat value + as the timeout. If the timer has never been started before it returns + UV_EINVAL. + +.. c:function:: void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) + + Set the repeat interval value in milliseconds. The timer will be scheduled + to run on the given interval, regardless of the callback execution + duration, and will follow normal timer semantics in the case of a + time-slice overrun. + + For example, if a 50ms repeating timer first runs for 17ms, it will be + scheduled to run again 33ms later. If other tasks consume more than the + 33ms following the first timer callback, then the callback will run as soon + as possible. + + .. note:: + If the repeat value is set from a timer callback it does not immediately take effect. + If the timer was non-repeating before, it will have been stopped. If it was repeating, + then the old repeat value will have been used to schedule the next timeout. + +.. c:function:: uint64_t uv_timer_get_repeat(const uv_timer_t* handle) + + Get the timer repeat value. + +.. c:function:: uint64_t uv_timer_get_due_in(const uv_timer_t* handle) + + Get the timer due value or 0 if it has expired. The time is relative to + :c:func:`uv_now()`. + + .. versionadded:: 1.40.0 + +.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/external/src/libuv/docs/src/tty.rst b/external/src/libuv/docs/src/tty.rst new file mode 100644 index 0000000..f1acfdc --- /dev/null +++ b/external/src/libuv/docs/src/tty.rst @@ -0,0 +1,140 @@ + +.. _tty: + +:c:type:`uv_tty_t` --- TTY handle +================================= + +TTY handles represent a stream for the console. + +:c:type:`uv_tty_t` is a 'subclass' of :c:type:`uv_stream_t`. + + +Data types +---------- + +.. c:type:: uv_tty_t + + TTY handle type. + +.. c:enum:: uv_tty_mode_t + + .. versionadded:: 1.2.0 + + TTY mode type: + + :: + + typedef enum { + /* Initial/normal terminal mode */ + UV_TTY_MODE_NORMAL, + /* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */ + UV_TTY_MODE_RAW, + /* Binary-safe I/O mode for IPC (Unix-only) */ + UV_TTY_MODE_IO + } uv_tty_mode_t; + +.. c:enum:: uv_tty_vtermstate_t + + Console virtual terminal mode type: + + :: + + typedef enum { + /* + * The console supports handling of virtual terminal sequences + * (Windows10 new console, ConEmu) + */ + UV_TTY_SUPPORTED, + /* The console cannot process virtual terminal sequences. (Legacy + * console) + */ + UV_TTY_UNSUPPORTED + } uv_tty_vtermstate_t + + + +Public members +^^^^^^^^^^^^^^ + +N/A + +.. seealso:: The :c:type:`uv_stream_t` members also apply. + + +API +--- + +.. c:function:: int uv_tty_init(uv_loop_t* loop, uv_tty_t* handle, uv_file fd, int unused) + + Initialize a new TTY stream with the given file descriptor. Usually the + file descriptor will be: + + * 0 = stdin + * 1 = stdout + * 2 = stderr + + On Unix this function will determine the path of the fd of the terminal + using :man:`ttyname_r(3)`, open it, and use it if the passed file descriptor + refers to a TTY. This lets libuv put the tty in non-blocking mode without + affecting other processes that share the tty. + + This function is not thread safe on systems that don't support + ioctl TIOCGPTN or TIOCPTYGNAME, for instance OpenBSD and Solaris. + + .. note:: + If reopening the TTY fails, libuv falls back to blocking writes. + + .. versionchanged:: 1.23.1: the `readable` parameter is now unused and ignored. + The correct value will now be auto-detected from the kernel. + + .. versionchanged:: 1.9.0: the path of the TTY is determined by + :man:`ttyname_r(3)`. In earlier versions libuv opened + `/dev/tty` instead. + + .. versionchanged:: 1.5.0: trying to initialize a TTY stream with a file + descriptor that refers to a file returns `UV_EINVAL` + on UNIX. + +.. c:function:: int uv_tty_set_mode(uv_tty_t* handle, uv_tty_mode_t mode) + + .. versionchanged:: 1.2.0: the mode is specified as a + :c:type:`uv_tty_mode_t` value. + + Set the TTY using the specified terminal mode. + +.. c:function:: int uv_tty_reset_mode(void) + + To be called when the program exits. Resets TTY settings to default + values for the next process to take over. + + This function is async signal-safe on Unix platforms but can fail with error + code ``UV_EBUSY`` if you call it when execution is inside + :c:func:`uv_tty_set_mode`. + +.. c:function:: int uv_tty_get_winsize(uv_tty_t* handle, int* width, int* height) + + Gets the current Window size. On success it returns 0. + +.. seealso:: The :c:type:`uv_stream_t` API functions also apply. + +.. c:function:: void uv_tty_set_vterm_state(uv_tty_vtermstate_t state) + + Controls whether console virtual terminal sequences are processed by libuv + or console. + Useful in particular for enabling ConEmu support of ANSI X3.64 and Xterm + 256 colors. Otherwise Windows10 consoles are usually detected automatically. + + This function is only meaningful on Windows systems. On Unix it is silently + ignored. + + .. versionadded:: 1.33.0 + +.. c:function:: int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state) + + Get the current state of whether console virtual terminal sequences are + handled by libuv or the console. + + This function is not implemented on Unix, where it returns ``UV_ENOTSUP``. + + .. versionadded:: 1.33.0 + diff --git a/external/src/libuv/docs/src/udp.rst b/external/src/libuv/docs/src/udp.rst new file mode 100644 index 0000000..009767d --- /dev/null +++ b/external/src/libuv/docs/src/udp.rst @@ -0,0 +1,450 @@ + +.. _udp: + +:c:type:`uv_udp_t` --- UDP handle +================================= + +UDP handles encapsulate UDP communication for both clients and servers. + + +Data types +---------- + +.. c:type:: uv_udp_t + + UDP handle type. + +.. c:type:: uv_udp_send_t + + UDP send request type. + +.. c:type:: uv_udp_flags + + Flags used in :c:func:`uv_udp_bind` and :c:type:`uv_udp_recv_cb`.. + + :: + + enum uv_udp_flags { + /* Disables dual stack mode. */ + UV_UDP_IPV6ONLY = 1, + /* + * Indicates message was truncated because read buffer was too small. The + * remainder was discarded by the OS. Used in uv_udp_recv_cb. + */ + UV_UDP_PARTIAL = 2, + /* + * Indicates if SO_REUSEADDR will be set when binding the handle in + * uv_udp_bind. + * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other + * Unix platforms, it sets the SO_REUSEADDR flag. What that means is that + * multiple threads or processes can bind to the same address without error + * (provided they all set the flag) but only the last one to bind will receive + * any traffic, in effect "stealing" the port from the previous listener. + */ + UV_UDP_REUSEADDR = 4, + /* + * Indicates that the message was received by recvmmsg, so the buffer provided + * must not be freed by the recv_cb callback. + */ + UV_UDP_MMSG_CHUNK = 8, + /* + * Indicates that the buffer provided has been fully utilized by recvmmsg and + * that it should now be freed by the recv_cb callback. When this flag is set + * in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL. + */ + UV_UDP_MMSG_FREE = 16, + /* + * Indicates if IP_RECVERR/IPV6_RECVERR will be set when binding the handle. + * This sets IP_RECVERR for IPv4 and IPV6_RECVERR for IPv6 UDP sockets on + * Linux. This stops the Linux kernel from supressing some ICMP error messages + * and enables full ICMP error reporting for faster failover. + * This flag is no-op on platforms other than Linux. + */ + UV_UDP_LINUX_RECVERR = 32, + /* + * Indicates that recvmmsg should be used, if available. + */ + UV_UDP_RECVMMSG = 256 + }; + +.. c:type:: void (*uv_udp_send_cb)(uv_udp_send_t* req, int status) + + Type definition for callback passed to :c:func:`uv_udp_send`, which is + called after the data was sent. + +.. c:type:: void (*uv_udp_recv_cb)(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags) + + Type definition for callback passed to :c:func:`uv_udp_recv_start`, which + is called when the endpoint receives data. + + * `handle`: UDP handle + * `nread`: Number of bytes that have been received. + 0 if there is no more data to read. Note that 0 may also mean that an + empty datagram was received (in this case `addr` is not NULL). < 0 if + a transmission error was detected; if using :man:`recvmmsg(2)` no more + chunks will be received and the buffer can be freed safely. + * `buf`: :c:type:`uv_buf_t` with the received data. + * `addr`: ``struct sockaddr*`` containing the address of the sender. + Can be NULL. Valid for the duration of the callback only. + * `flags`: One or more or'ed UV_UDP_* constants. + + The callee is responsible for freeing the buffer, libuv does not reuse it. + The buffer may be a null buffer (where `buf->base` == NULL and `buf->len` == 0) + on error. + + When using :man:`recvmmsg(2)`, chunks will have the `UV_UDP_MMSG_CHUNK` flag set, + those must not be freed. If no errors occur, there will be a final callback with + `nread` set to 0, `addr` set to NULL and the buffer pointing at the initially + allocated data with the `UV_UDP_MMSG_CHUNK` flag cleared and the `UV_UDP_MMSG_FREE` + flag set. If a UDP socket error occurs, `nread` will be < 0. In either scenario, + the callee can now safely free the provided buffer. + + .. versionchanged:: 1.40.0 added the `UV_UDP_MMSG_FREE` flag. + + .. note:: + The receive callback will be called with `nread` == 0 and `addr` == NULL when there is + nothing to read, and with `nread` == 0 and `addr` != NULL when an empty UDP packet is + received. + +.. c:enum:: uv_membership + + Membership type for a multicast address. + + :: + + typedef enum { + UV_LEAVE_GROUP = 0, + UV_JOIN_GROUP + } uv_membership; + + +Public members +^^^^^^^^^^^^^^ + +.. c:member:: size_t uv_udp_t.send_queue_size + + Number of bytes queued for sending. This field strictly shows how much + information is currently queued. + +.. c:member:: size_t uv_udp_t.send_queue_count + + Number of send requests currently in the queue awaiting to be processed. + +.. c:member:: uv_udp_t* uv_udp_send_t.handle + + UDP handle where this send request is taking place. + +.. seealso:: The :c:type:`uv_handle_t` members also apply. + + +API +--- + +.. c:function:: int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) + + Initialize a new UDP handle. The actual socket is created lazily. + Returns 0 on success. + +.. c:function:: int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) + + Initialize the handle with the specified flags. The lower 8 bits of the `flags` + parameter are used as the socket domain. A socket will be created for the given domain. + If the specified domain is ``AF_UNSPEC`` no socket is created, just like :c:func:`uv_udp_init`. + + The remaining bits can be used to set one of these flags: + + * `UV_UDP_RECVMMSG`: if set, and the platform supports it, :man:`recvmmsg(2)` will + be used. + + .. versionadded:: 1.7.0 + .. versionchanged:: 1.37.0 added the `UV_UDP_RECVMMSG` flag. + +.. c:function:: int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) + + Opens an existing file descriptor or Windows SOCKET as a UDP handle. + + Unix only: + The only requirement of the `sock` argument is that it follows the datagram + contract (works in unconnected mode, supports sendmsg()/recvmsg(), etc). + In other words, other datagram-type sockets like raw sockets or netlink + sockets can also be passed to this function. + + .. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode. + + .. note:: + The passed file descriptor or SOCKET is not checked for its type, but + it's required that it represents a valid datagram socket. + +.. c:function:: int uv_udp_bind(uv_udp_t* handle, const struct sockaddr* addr, unsigned int flags) + + Bind the UDP handle to an IP address and port. + + :param handle: UDP handle. Should have been initialized with + :c:func:`uv_udp_init`. + + :param addr: `struct sockaddr_in` or `struct sockaddr_in6` + with the address and port to bind to. + + :param flags: Indicate how the socket will be bound, + ``UV_UDP_IPV6ONLY``, ``UV_UDP_REUSEADDR``, and ``UV_UDP_RECVERR`` + are supported. + + :returns: 0 on success, or an error code < 0 on failure. + +.. c:function:: int uv_udp_connect(uv_udp_t* handle, const struct sockaddr* addr) + + Associate the UDP handle to a remote address and port, so every + message sent by this handle is automatically sent to that destination. + Calling this function with a `NULL` `addr` disconnects the handle. + Trying to call `uv_udp_connect()` on an already connected handle will result + in an `UV_EISCONN` error. Trying to disconnect a handle that is not + connected will return an `UV_ENOTCONN` error. + + :param handle: UDP handle. Should have been initialized with + :c:func:`uv_udp_init`. + + :param addr: `struct sockaddr_in` or `struct sockaddr_in6` + with the address and port to associate to. + + :returns: 0 on success, or an error code < 0 on failure. + + .. versionadded:: 1.27.0 + +.. c:function:: int uv_udp_getpeername(const uv_udp_t* handle, struct sockaddr* name, int* namelen) + + Get the remote IP and port of the UDP handle on connected UDP handles. + On unconnected handles, it returns `UV_ENOTCONN`. + + :param handle: UDP handle. Should have been initialized with + :c:func:`uv_udp_init` and bound. + + :param name: Pointer to the structure to be filled with the address data. + In order to support IPv4 and IPv6 `struct sockaddr_storage` should be + used. + + :param namelen: On input it indicates the data of the `name` field. On + output it indicates how much of it was filled. + + :returns: 0 on success, or an error code < 0 on failure + + .. versionadded:: 1.27.0 + +.. c:function:: int uv_udp_getsockname(const uv_udp_t* handle, struct sockaddr* name, int* namelen) + + Get the local IP and port of the UDP handle. + + :param handle: UDP handle. Should have been initialized with + :c:func:`uv_udp_init` and bound. + + :param name: Pointer to the structure to be filled with the address data. + In order to support IPv4 and IPv6 `struct sockaddr_storage` should be + used. + + :param namelen: On input it indicates the data of the `name` field. On + output it indicates how much of it was filled. + + :returns: 0 on success, or an error code < 0 on failure. + +.. c:function:: int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr, const char* interface_addr, uv_membership membership) + + Set membership for a multicast address + + :param handle: UDP handle. Should have been initialized with + :c:func:`uv_udp_init`. + + :param multicast_addr: Multicast address to set membership for. + + :param interface_addr: Interface address. + + :param membership: Should be ``UV_JOIN_GROUP`` or ``UV_LEAVE_GROUP``. + + :returns: 0 on success, or an error code < 0 on failure. + +.. c:function:: int uv_udp_set_source_membership(uv_udp_t* handle, const char* multicast_addr, const char* interface_addr, const char* source_addr, uv_membership membership) + + Set membership for a source-specific multicast group. + + :param handle: UDP handle. Should have been initialized with + :c:func:`uv_udp_init`. + + :param multicast_addr: Multicast address to set membership for. + + :param interface_addr: Interface address. + + :param source_addr: Source address. + + :param membership: Should be ``UV_JOIN_GROUP`` or ``UV_LEAVE_GROUP``. + + :returns: 0 on success, or an error code < 0 on failure. + + .. versionadded:: 1.32.0 + +.. c:function:: int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) + + Set IP multicast loop flag. Makes multicast packets loop back to + local sockets. + + :param handle: UDP handle. Should have been initialized with + :c:func:`uv_udp_init`. + + :param on: 1 for on, 0 for off. + + :returns: 0 on success, or an error code < 0 on failure. + +.. c:function:: int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) + + Set the multicast ttl. + + :param handle: UDP handle. Should have been initialized with + :c:func:`uv_udp_init`. + + :param ttl: 1 through 255. + + :returns: 0 on success, or an error code < 0 on failure. + +.. c:function:: int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) + + Set the multicast interface to send or receive data on. + + :param handle: UDP handle. Should have been initialized with + :c:func:`uv_udp_init`. + + :param interface_addr: interface address. + + :returns: 0 on success, or an error code < 0 on failure. + +.. c:function:: int uv_udp_set_broadcast(uv_udp_t* handle, int on) + + Set broadcast on or off. + + :param handle: UDP handle. Should have been initialized with + :c:func:`uv_udp_init`. + + :param on: 1 for on, 0 for off. + + :returns: 0 on success, or an error code < 0 on failure. + +.. c:function:: int uv_udp_set_ttl(uv_udp_t* handle, int ttl) + + Set the time to live. + + :param handle: UDP handle. Should have been initialized with + :c:func:`uv_udp_init`. + + :param ttl: 1 through 255. + + :returns: 0 on success, or an error code < 0 on failure. + +.. c:function:: int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr, uv_udp_send_cb send_cb) + + Send data over the UDP socket. If the socket has not previously been bound + with :c:func:`uv_udp_bind` it will be bound to 0.0.0.0 + (the "all interfaces" IPv4 address) and a random port number. + + On Windows if the `addr` is initialized to point to an unspecified address + (``0.0.0.0`` or ``::``) it will be changed to point to ``localhost``. + This is done to match the behavior of Linux systems. + + For connected UDP handles, `addr` must be set to `NULL`, otherwise it will + return `UV_EISCONN` error. + + For connectionless UDP handles, `addr` cannot be `NULL`, otherwise it will + return `UV_EDESTADDRREQ` error. + + :param req: UDP request handle. Need not be initialized. + + :param handle: UDP handle. Should have been initialized with + :c:func:`uv_udp_init`. + + :param bufs: List of buffers to send. + + :param nbufs: Number of buffers in `bufs`. + + :param addr: `struct sockaddr_in` or `struct sockaddr_in6` with the + address and port of the remote peer. + + :param send_cb: Callback to invoke when the data has been sent out. + + :returns: 0 on success, or an error code < 0 on failure. + + .. versionchanged:: 1.19.0 added ``0.0.0.0`` and ``::`` to ``localhost`` + mapping + + .. versionchanged:: 1.27.0 added support for connected sockets + +.. c:function:: int uv_udp_try_send(uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr) + + Same as :c:func:`uv_udp_send`, but won't queue a send request if it can't + be completed immediately. + + For connected UDP handles, `addr` must be set to `NULL`, otherwise it will + return `UV_EISCONN` error. + + For connectionless UDP handles, `addr` cannot be `NULL`, otherwise it will + return `UV_EDESTADDRREQ` error. + + :returns: >= 0: number of bytes sent (it matches the given buffer size). + < 0: negative error code (``UV_EAGAIN`` is returned when the message + can't be sent immediately). + + .. versionchanged:: 1.27.0 added support for connected sockets + +.. c:function:: int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb) + + Prepare for receiving data. If the socket has not previously been bound + with :c:func:`uv_udp_bind` it is bound to 0.0.0.0 (the "all interfaces" + IPv4 address) and a random port number. + + :param handle: UDP handle. Should have been initialized with + :c:func:`uv_udp_init`. + + :param alloc_cb: Callback to invoke when temporary storage is needed. + + :param recv_cb: Callback to invoke with received data. + + :returns: 0 on success, or an error code < 0 on failure. + + .. note:: + When using :man:`recvmmsg(2)`, the number of messages received at a time is limited + by the number of max size dgrams that will fit into the buffer allocated in `alloc_cb`, and + `suggested_size` in `alloc_cb` for udp_recv is always set to the size of 1 max size dgram. + + .. versionchanged:: 1.35.0 added support for :man:`recvmmsg(2)` on supported platforms). + The use of this feature requires a buffer larger than + 2 * 64KB to be passed to `alloc_cb`. + .. versionchanged:: 1.37.0 :man:`recvmmsg(2)` support is no longer enabled implicitly, + it must be explicitly requested by passing the `UV_UDP_RECVMMSG` flag to + :c:func:`uv_udp_init_ex`. + .. versionchanged:: 1.39.0 :c:func:`uv_udp_using_recvmmsg` can be used in `alloc_cb` to + determine if a buffer sized for use with :man:`recvmmsg(2)` should be + allocated for the current handle/platform. + +.. c:function:: int uv_udp_using_recvmmsg(uv_udp_t* handle) + + Returns 1 if the UDP handle was created with the `UV_UDP_RECVMMSG` flag + and the platform supports :man:`recvmmsg(2)`, 0 otherwise. + + .. versionadded:: 1.39.0 + +.. c:function:: int uv_udp_recv_stop(uv_udp_t* handle) + + Stop listening for incoming datagrams. + + :param handle: UDP handle. Should have been initialized with + :c:func:`uv_udp_init`. + + :returns: 0 on success, or an error code < 0 on failure. + +.. c:function:: size_t uv_udp_get_send_queue_size(const uv_udp_t* handle) + + Returns `handle->send_queue_size`. + + .. versionadded:: 1.19.0 + +.. c:function:: size_t uv_udp_get_send_queue_count(const uv_udp_t* handle) + + Returns `handle->send_queue_count`. + + .. versionadded:: 1.19.0 + +.. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/external/src/libuv/docs/src/upgrading.rst b/external/src/libuv/docs/src/upgrading.rst new file mode 100644 index 0000000..32840c2 --- /dev/null +++ b/external/src/libuv/docs/src/upgrading.rst @@ -0,0 +1,11 @@ +.. _upgrading: + +Upgrading +========= + +Migration guides for different libuv versions, starting with 1.0. + +.. toctree:: + :maxdepth: 1 + + migration_010_100 diff --git a/external/src/libuv/docs/src/version.rst b/external/src/libuv/docs/src/version.rst new file mode 100644 index 0000000..13b0940 --- /dev/null +++ b/external/src/libuv/docs/src/version.rst @@ -0,0 +1,60 @@ + +.. _version: + +Version-checking macros and functions +===================================== + +Starting with version 1.0.0 libuv follows the `semantic versioning`_ +scheme. This means that new APIs can be introduced throughout the lifetime of +a major release. In this section you'll find all macros and functions that +will allow you to write or compile code conditionally, in order to work with +multiple libuv versions. + +.. _semantic versioning: https://semver.org + + +Macros +------ + +.. c:macro:: UV_VERSION_MAJOR + + libuv version's major number. + +.. c:macro:: UV_VERSION_MINOR + + libuv version's minor number. + +.. c:macro:: UV_VERSION_PATCH + + libuv version's patch number. + +.. c:macro:: UV_VERSION_IS_RELEASE + + Set to 1 to indicate a release version of libuv, 0 for a development + snapshot. + +.. c:macro:: UV_VERSION_SUFFIX + + libuv version suffix. Certain development releases such as Release Candidates + might have a suffix such as "rc". + +.. c:macro:: UV_VERSION_HEX + + Returns the libuv version packed into a single integer. 8 bits are used for + each component, with the patch number stored in the 8 least significant + bits. E.g. for libuv 1.2.3 this would be 0x010203. + + .. versionadded:: 1.7.0 + + +Functions +--------- + +.. c:function:: unsigned int uv_version(void) + + Returns :c:macro:`UV_VERSION_HEX`. + +.. c:function:: const char* uv_version_string(void) + + Returns the libuv version number as a string. For non-release versions the + version suffix is included. diff --git a/external/src/libuv/img/banner.png b/external/src/libuv/img/banner.png new file mode 100644 index 0000000..7187daa Binary files /dev/null and b/external/src/libuv/img/banner.png differ diff --git a/external/src/libuv/img/logos.svg b/external/src/libuv/img/logos.svg new file mode 100644 index 0000000..d6185f8 --- /dev/null +++ b/external/src/libuv/img/logos.svg @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/src/libuv/include/uv.h b/external/src/libuv/include/uv.h new file mode 100644 index 0000000..77503bd --- /dev/null +++ b/external/src/libuv/include/uv.h @@ -0,0 +1,1846 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* See https://github.com/libuv/libuv#documentation for documentation. */ + +#ifndef UV_H +#define UV_H +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BUILDING_UV_SHARED) && defined(USING_UV_SHARED) +#error "Define either BUILDING_UV_SHARED or USING_UV_SHARED, not both." +#endif + +#ifdef _WIN32 + /* Windows - set up dll import/export decorators. */ +# if defined(BUILDING_UV_SHARED) + /* Building shared library. */ +# define UV_EXTERN __declspec(dllexport) +# elif defined(USING_UV_SHARED) + /* Using shared library. */ +# define UV_EXTERN __declspec(dllimport) +# else + /* Building static library. */ +# define UV_EXTERN /* nothing */ +# endif +#elif __GNUC__ >= 4 +# define UV_EXTERN __attribute__((visibility("default"))) +#else +# define UV_EXTERN /* nothing */ +#endif + +#include "uv/errno.h" +#include "uv/version.h" +#include +#include + +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "uv/stdint-msvc2008.h" +#else +# include +#endif + +#if defined(_WIN32) +# include "uv/win.h" +#else +# include "uv/unix.h" +#endif + +/* Expand this list if necessary. */ +#define UV_ERRNO_MAP(XX) \ + XX(E2BIG, "argument list too long") \ + XX(EACCES, "permission denied") \ + XX(EADDRINUSE, "address already in use") \ + XX(EADDRNOTAVAIL, "address not available") \ + XX(EAFNOSUPPORT, "address family not supported") \ + XX(EAGAIN, "resource temporarily unavailable") \ + XX(EAI_ADDRFAMILY, "address family not supported") \ + XX(EAI_AGAIN, "temporary failure") \ + XX(EAI_BADFLAGS, "bad ai_flags value") \ + XX(EAI_BADHINTS, "invalid value for hints") \ + XX(EAI_CANCELED, "request canceled") \ + XX(EAI_FAIL, "permanent failure") \ + XX(EAI_FAMILY, "ai_family not supported") \ + XX(EAI_MEMORY, "out of memory") \ + XX(EAI_NODATA, "no address") \ + XX(EAI_NONAME, "unknown node or service") \ + XX(EAI_OVERFLOW, "argument buffer overflow") \ + XX(EAI_PROTOCOL, "resolved protocol is unknown") \ + XX(EAI_SERVICE, "service not available for socket type") \ + XX(EAI_SOCKTYPE, "socket type not supported") \ + XX(EALREADY, "connection already in progress") \ + XX(EBADF, "bad file descriptor") \ + XX(EBUSY, "resource busy or locked") \ + XX(ECANCELED, "operation canceled") \ + XX(ECHARSET, "invalid Unicode character") \ + XX(ECONNABORTED, "software caused connection abort") \ + XX(ECONNREFUSED, "connection refused") \ + XX(ECONNRESET, "connection reset by peer") \ + XX(EDESTADDRREQ, "destination address required") \ + XX(EEXIST, "file already exists") \ + XX(EFAULT, "bad address in system call argument") \ + XX(EFBIG, "file too large") \ + XX(EHOSTUNREACH, "host is unreachable") \ + XX(EINTR, "interrupted system call") \ + XX(EINVAL, "invalid argument") \ + XX(EIO, "i/o error") \ + XX(EISCONN, "socket is already connected") \ + XX(EISDIR, "illegal operation on a directory") \ + XX(ELOOP, "too many symbolic links encountered") \ + XX(EMFILE, "too many open files") \ + XX(EMSGSIZE, "message too long") \ + XX(ENAMETOOLONG, "name too long") \ + XX(ENETDOWN, "network is down") \ + XX(ENETUNREACH, "network is unreachable") \ + XX(ENFILE, "file table overflow") \ + XX(ENOBUFS, "no buffer space available") \ + XX(ENODEV, "no such device") \ + XX(ENOENT, "no such file or directory") \ + XX(ENOMEM, "not enough memory") \ + XX(ENONET, "machine is not on the network") \ + XX(ENOPROTOOPT, "protocol not available") \ + XX(ENOSPC, "no space left on device") \ + XX(ENOSYS, "function not implemented") \ + XX(ENOTCONN, "socket is not connected") \ + XX(ENOTDIR, "not a directory") \ + XX(ENOTEMPTY, "directory not empty") \ + XX(ENOTSOCK, "socket operation on non-socket") \ + XX(ENOTSUP, "operation not supported on socket") \ + XX(EOVERFLOW, "value too large for defined data type") \ + XX(EPERM, "operation not permitted") \ + XX(EPIPE, "broken pipe") \ + XX(EPROTO, "protocol error") \ + XX(EPROTONOSUPPORT, "protocol not supported") \ + XX(EPROTOTYPE, "protocol wrong type for socket") \ + XX(ERANGE, "result too large") \ + XX(EROFS, "read-only file system") \ + XX(ESHUTDOWN, "cannot send after transport endpoint shutdown") \ + XX(ESPIPE, "invalid seek") \ + XX(ESRCH, "no such process") \ + XX(ETIMEDOUT, "connection timed out") \ + XX(ETXTBSY, "text file is busy") \ + XX(EXDEV, "cross-device link not permitted") \ + XX(UNKNOWN, "unknown error") \ + XX(EOF, "end of file") \ + XX(ENXIO, "no such device or address") \ + XX(EMLINK, "too many links") \ + XX(EHOSTDOWN, "host is down") \ + XX(EREMOTEIO, "remote I/O error") \ + XX(ENOTTY, "inappropriate ioctl for device") \ + XX(EFTYPE, "inappropriate file type or format") \ + XX(EILSEQ, "illegal byte sequence") \ + XX(ESOCKTNOSUPPORT, "socket type not supported") \ + +#define UV_HANDLE_TYPE_MAP(XX) \ + XX(ASYNC, async) \ + XX(CHECK, check) \ + XX(FS_EVENT, fs_event) \ + XX(FS_POLL, fs_poll) \ + XX(HANDLE, handle) \ + XX(IDLE, idle) \ + XX(NAMED_PIPE, pipe) \ + XX(POLL, poll) \ + XX(PREPARE, prepare) \ + XX(PROCESS, process) \ + XX(STREAM, stream) \ + XX(TCP, tcp) \ + XX(TIMER, timer) \ + XX(TTY, tty) \ + XX(UDP, udp) \ + XX(SIGNAL, signal) \ + +#define UV_REQ_TYPE_MAP(XX) \ + XX(REQ, req) \ + XX(CONNECT, connect) \ + XX(WRITE, write) \ + XX(SHUTDOWN, shutdown) \ + XX(UDP_SEND, udp_send) \ + XX(FS, fs) \ + XX(WORK, work) \ + XX(GETADDRINFO, getaddrinfo) \ + XX(GETNAMEINFO, getnameinfo) \ + XX(RANDOM, random) \ + +typedef enum { +#define XX(code, _) UV_ ## code = UV__ ## code, + UV_ERRNO_MAP(XX) +#undef XX + UV_ERRNO_MAX = UV__EOF - 1 +} uv_errno_t; + +typedef enum { + UV_UNKNOWN_HANDLE = 0, +#define XX(uc, lc) UV_##uc, + UV_HANDLE_TYPE_MAP(XX) +#undef XX + UV_FILE, + UV_HANDLE_TYPE_MAX +} uv_handle_type; + +typedef enum { + UV_UNKNOWN_REQ = 0, +#define XX(uc, lc) UV_##uc, + UV_REQ_TYPE_MAP(XX) +#undef XX + UV_REQ_TYPE_PRIVATE + UV_REQ_TYPE_MAX +} uv_req_type; + + +/* Handle types. */ +typedef struct uv_loop_s uv_loop_t; +typedef struct uv_handle_s uv_handle_t; +typedef struct uv_dir_s uv_dir_t; +typedef struct uv_stream_s uv_stream_t; +typedef struct uv_tcp_s uv_tcp_t; +typedef struct uv_udp_s uv_udp_t; +typedef struct uv_pipe_s uv_pipe_t; +typedef struct uv_tty_s uv_tty_t; +typedef struct uv_poll_s uv_poll_t; +typedef struct uv_timer_s uv_timer_t; +typedef struct uv_prepare_s uv_prepare_t; +typedef struct uv_check_s uv_check_t; +typedef struct uv_idle_s uv_idle_t; +typedef struct uv_async_s uv_async_t; +typedef struct uv_process_s uv_process_t; +typedef struct uv_fs_event_s uv_fs_event_t; +typedef struct uv_fs_poll_s uv_fs_poll_t; +typedef struct uv_signal_s uv_signal_t; + +/* Request types. */ +typedef struct uv_req_s uv_req_t; +typedef struct uv_getaddrinfo_s uv_getaddrinfo_t; +typedef struct uv_getnameinfo_s uv_getnameinfo_t; +typedef struct uv_shutdown_s uv_shutdown_t; +typedef struct uv_write_s uv_write_t; +typedef struct uv_connect_s uv_connect_t; +typedef struct uv_udp_send_s uv_udp_send_t; +typedef struct uv_fs_s uv_fs_t; +typedef struct uv_work_s uv_work_t; +typedef struct uv_random_s uv_random_t; + +/* None of the above. */ +typedef struct uv_env_item_s uv_env_item_t; +typedef struct uv_cpu_info_s uv_cpu_info_t; +typedef struct uv_interface_address_s uv_interface_address_t; +typedef struct uv_dirent_s uv_dirent_t; +typedef struct uv_passwd_s uv_passwd_t; +typedef struct uv_utsname_s uv_utsname_t; +typedef struct uv_statfs_s uv_statfs_t; + +typedef enum { + UV_LOOP_BLOCK_SIGNAL = 0, + UV_METRICS_IDLE_TIME +} uv_loop_option; + +typedef enum { + UV_RUN_DEFAULT = 0, + UV_RUN_ONCE, + UV_RUN_NOWAIT +} uv_run_mode; + + +UV_EXTERN unsigned int uv_version(void); +UV_EXTERN const char* uv_version_string(void); + +typedef void* (*uv_malloc_func)(size_t size); +typedef void* (*uv_realloc_func)(void* ptr, size_t size); +typedef void* (*uv_calloc_func)(size_t count, size_t size); +typedef void (*uv_free_func)(void* ptr); + +UV_EXTERN void uv_library_shutdown(void); + +UV_EXTERN int uv_replace_allocator(uv_malloc_func malloc_func, + uv_realloc_func realloc_func, + uv_calloc_func calloc_func, + uv_free_func free_func); + +UV_EXTERN uv_loop_t* uv_default_loop(void); +UV_EXTERN int uv_loop_init(uv_loop_t* loop); +UV_EXTERN int uv_loop_close(uv_loop_t* loop); +/* + * NOTE: + * This function is DEPRECATED (to be removed after 0.12), users should + * allocate the loop manually and use uv_loop_init instead. + */ +UV_EXTERN uv_loop_t* uv_loop_new(void); +/* + * NOTE: + * This function is DEPRECATED (to be removed after 0.12). Users should use + * uv_loop_close and free the memory manually instead. + */ +UV_EXTERN void uv_loop_delete(uv_loop_t*); +UV_EXTERN size_t uv_loop_size(void); +UV_EXTERN int uv_loop_alive(const uv_loop_t* loop); +UV_EXTERN int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...); +UV_EXTERN int uv_loop_fork(uv_loop_t* loop); + +UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode); +UV_EXTERN void uv_stop(uv_loop_t*); + +UV_EXTERN void uv_ref(uv_handle_t*); +UV_EXTERN void uv_unref(uv_handle_t*); +UV_EXTERN int uv_has_ref(const uv_handle_t*); + +UV_EXTERN void uv_update_time(uv_loop_t*); +UV_EXTERN uint64_t uv_now(const uv_loop_t*); + +UV_EXTERN int uv_backend_fd(const uv_loop_t*); +UV_EXTERN int uv_backend_timeout(const uv_loop_t*); + +typedef void (*uv_alloc_cb)(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf); +typedef void (*uv_read_cb)(uv_stream_t* stream, + ssize_t nread, + const uv_buf_t* buf); +typedef void (*uv_write_cb)(uv_write_t* req, int status); +typedef void (*uv_connect_cb)(uv_connect_t* req, int status); +typedef void (*uv_shutdown_cb)(uv_shutdown_t* req, int status); +typedef void (*uv_connection_cb)(uv_stream_t* server, int status); +typedef void (*uv_close_cb)(uv_handle_t* handle); +typedef void (*uv_poll_cb)(uv_poll_t* handle, int status, int events); +typedef void (*uv_timer_cb)(uv_timer_t* handle); +typedef void (*uv_async_cb)(uv_async_t* handle); +typedef void (*uv_prepare_cb)(uv_prepare_t* handle); +typedef void (*uv_check_cb)(uv_check_t* handle); +typedef void (*uv_idle_cb)(uv_idle_t* handle); +typedef void (*uv_exit_cb)(uv_process_t*, int64_t exit_status, int term_signal); +typedef void (*uv_walk_cb)(uv_handle_t* handle, void* arg); +typedef void (*uv_fs_cb)(uv_fs_t* req); +typedef void (*uv_work_cb)(uv_work_t* req); +typedef void (*uv_after_work_cb)(uv_work_t* req, int status); +typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req, + int status, + struct addrinfo* res); +typedef void (*uv_getnameinfo_cb)(uv_getnameinfo_t* req, + int status, + const char* hostname, + const char* service); +typedef void (*uv_random_cb)(uv_random_t* req, + int status, + void* buf, + size_t buflen); + +typedef struct { + long tv_sec; + long tv_nsec; +} uv_timespec_t; + + +typedef struct { + uint64_t st_dev; + uint64_t st_mode; + uint64_t st_nlink; + uint64_t st_uid; + uint64_t st_gid; + uint64_t st_rdev; + uint64_t st_ino; + uint64_t st_size; + uint64_t st_blksize; + uint64_t st_blocks; + uint64_t st_flags; + uint64_t st_gen; + uv_timespec_t st_atim; + uv_timespec_t st_mtim; + uv_timespec_t st_ctim; + uv_timespec_t st_birthtim; +} uv_stat_t; + + +typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle, + const char* filename, + int events, + int status); + +typedef void (*uv_fs_poll_cb)(uv_fs_poll_t* handle, + int status, + const uv_stat_t* prev, + const uv_stat_t* curr); + +typedef void (*uv_signal_cb)(uv_signal_t* handle, int signum); + + +typedef enum { + UV_LEAVE_GROUP = 0, + UV_JOIN_GROUP +} uv_membership; + + +UV_EXTERN int uv_translate_sys_error(int sys_errno); + +UV_EXTERN const char* uv_strerror(int err); +UV_EXTERN char* uv_strerror_r(int err, char* buf, size_t buflen); + +UV_EXTERN const char* uv_err_name(int err); +UV_EXTERN char* uv_err_name_r(int err, char* buf, size_t buflen); + + +#define UV_REQ_FIELDS \ + /* public */ \ + void* data; \ + /* read-only */ \ + uv_req_type type; \ + /* private */ \ + void* reserved[6]; \ + UV_REQ_PRIVATE_FIELDS \ + +/* Abstract base class of all requests. */ +struct uv_req_s { + UV_REQ_FIELDS +}; + + +/* Platform-specific request types. */ +UV_PRIVATE_REQ_TYPES + + +UV_EXTERN int uv_shutdown(uv_shutdown_t* req, + uv_stream_t* handle, + uv_shutdown_cb cb); + +struct uv_shutdown_s { + UV_REQ_FIELDS + uv_stream_t* handle; + uv_shutdown_cb cb; + UV_SHUTDOWN_PRIVATE_FIELDS +}; + + +#define UV_HANDLE_FIELDS \ + /* public */ \ + void* data; \ + /* read-only */ \ + uv_loop_t* loop; \ + uv_handle_type type; \ + /* private */ \ + uv_close_cb close_cb; \ + void* handle_queue[2]; \ + union { \ + int fd; \ + void* reserved[4]; \ + } u; \ + UV_HANDLE_PRIVATE_FIELDS \ + +/* The abstract base class of all handles. */ +struct uv_handle_s { + UV_HANDLE_FIELDS +}; + +UV_EXTERN size_t uv_handle_size(uv_handle_type type); +UV_EXTERN uv_handle_type uv_handle_get_type(const uv_handle_t* handle); +UV_EXTERN const char* uv_handle_type_name(uv_handle_type type); +UV_EXTERN void* uv_handle_get_data(const uv_handle_t* handle); +UV_EXTERN uv_loop_t* uv_handle_get_loop(const uv_handle_t* handle); +UV_EXTERN void uv_handle_set_data(uv_handle_t* handle, void* data); + +UV_EXTERN size_t uv_req_size(uv_req_type type); +UV_EXTERN void* uv_req_get_data(const uv_req_t* req); +UV_EXTERN void uv_req_set_data(uv_req_t* req, void* data); +UV_EXTERN uv_req_type uv_req_get_type(const uv_req_t* req); +UV_EXTERN const char* uv_req_type_name(uv_req_type type); + +UV_EXTERN int uv_is_active(const uv_handle_t* handle); + +UV_EXTERN void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg); + +/* Helpers for ad hoc debugging, no API/ABI stability guaranteed. */ +UV_EXTERN void uv_print_all_handles(uv_loop_t* loop, FILE* stream); +UV_EXTERN void uv_print_active_handles(uv_loop_t* loop, FILE* stream); + +UV_EXTERN void uv_close(uv_handle_t* handle, uv_close_cb close_cb); + +UV_EXTERN int uv_send_buffer_size(uv_handle_t* handle, int* value); +UV_EXTERN int uv_recv_buffer_size(uv_handle_t* handle, int* value); + +UV_EXTERN int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd); + +UV_EXTERN uv_buf_t uv_buf_init(char* base, unsigned int len); + +UV_EXTERN int uv_pipe(uv_file fds[2], int read_flags, int write_flags); +UV_EXTERN int uv_socketpair(int type, + int protocol, + uv_os_sock_t socket_vector[2], + int flags0, + int flags1); + +#define UV_STREAM_FIELDS \ + /* number of bytes queued for writing */ \ + size_t write_queue_size; \ + uv_alloc_cb alloc_cb; \ + uv_read_cb read_cb; \ + /* private */ \ + UV_STREAM_PRIVATE_FIELDS + +/* + * uv_stream_t is a subclass of uv_handle_t. + * + * uv_stream is an abstract class. + * + * uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t and uv_tty_t. + */ +struct uv_stream_s { + UV_HANDLE_FIELDS + UV_STREAM_FIELDS +}; + +UV_EXTERN size_t uv_stream_get_write_queue_size(const uv_stream_t* stream); + +UV_EXTERN int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb); +UV_EXTERN int uv_accept(uv_stream_t* server, uv_stream_t* client); + +UV_EXTERN int uv_read_start(uv_stream_t*, + uv_alloc_cb alloc_cb, + uv_read_cb read_cb); +UV_EXTERN int uv_read_stop(uv_stream_t*); + +UV_EXTERN int uv_write(uv_write_t* req, + uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_write_cb cb); +UV_EXTERN int uv_write2(uv_write_t* req, + uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle, + uv_write_cb cb); +UV_EXTERN int uv_try_write(uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs); +UV_EXTERN int uv_try_write2(uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle); + +/* uv_write_t is a subclass of uv_req_t. */ +struct uv_write_s { + UV_REQ_FIELDS + uv_write_cb cb; + uv_stream_t* send_handle; /* TODO: make private and unix-only in v2.x. */ + uv_stream_t* handle; + UV_WRITE_PRIVATE_FIELDS +}; + + +UV_EXTERN int uv_is_readable(const uv_stream_t* handle); +UV_EXTERN int uv_is_writable(const uv_stream_t* handle); + +UV_EXTERN int uv_stream_set_blocking(uv_stream_t* handle, int blocking); + +UV_EXTERN int uv_is_closing(const uv_handle_t* handle); + + +/* + * uv_tcp_t is a subclass of uv_stream_t. + * + * Represents a TCP stream or TCP server. + */ +struct uv_tcp_s { + UV_HANDLE_FIELDS + UV_STREAM_FIELDS + UV_TCP_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle); +UV_EXTERN int uv_tcp_init_ex(uv_loop_t*, uv_tcp_t* handle, unsigned int flags); +UV_EXTERN int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock); +UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable); +UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle, + int enable, + unsigned int delay); +UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable); + +enum uv_tcp_flags { + /* Used with uv_tcp_bind, when an IPv6 address is used. */ + UV_TCP_IPV6ONLY = 1 +}; + +UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle, + const struct sockaddr* addr, + unsigned int flags); +UV_EXTERN int uv_tcp_getsockname(const uv_tcp_t* handle, + struct sockaddr* name, + int* namelen); +UV_EXTERN int uv_tcp_getpeername(const uv_tcp_t* handle, + struct sockaddr* name, + int* namelen); +UV_EXTERN int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb); +UV_EXTERN int uv_tcp_connect(uv_connect_t* req, + uv_tcp_t* handle, + const struct sockaddr* addr, + uv_connect_cb cb); + +/* uv_connect_t is a subclass of uv_req_t. */ +struct uv_connect_s { + UV_REQ_FIELDS + uv_connect_cb cb; + uv_stream_t* handle; + UV_CONNECT_PRIVATE_FIELDS +}; + + +/* + * UDP support. + */ + +enum uv_udp_flags { + /* Disables dual stack mode. */ + UV_UDP_IPV6ONLY = 1, + /* + * Indicates message was truncated because read buffer was too small. The + * remainder was discarded by the OS. Used in uv_udp_recv_cb. + */ + UV_UDP_PARTIAL = 2, + /* + * Indicates if SO_REUSEADDR will be set when binding the handle. + * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other + * Unix platforms, it sets the SO_REUSEADDR flag. What that means is that + * multiple threads or processes can bind to the same address without error + * (provided they all set the flag) but only the last one to bind will receive + * any traffic, in effect "stealing" the port from the previous listener. + */ + UV_UDP_REUSEADDR = 4, + /* + * Indicates that the message was received by recvmmsg, so the buffer provided + * must not be freed by the recv_cb callback. + */ + UV_UDP_MMSG_CHUNK = 8, + /* + * Indicates that the buffer provided has been fully utilized by recvmmsg and + * that it should now be freed by the recv_cb callback. When this flag is set + * in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL. + */ + UV_UDP_MMSG_FREE = 16, + /* + * Indicates if IP_RECVERR/IPV6_RECVERR will be set when binding the handle. + * This sets IP_RECVERR for IPv4 and IPV6_RECVERR for IPv6 UDP sockets on + * Linux. This stops the Linux kernel from suppressing some ICMP error + * messages and enables full ICMP error reporting for faster failover. + * This flag is no-op on platforms other than Linux. + */ + UV_UDP_LINUX_RECVERR = 32, + /* + * Indicates that recvmmsg should be used, if available. + */ + UV_UDP_RECVMMSG = 256 +}; + +typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status); +typedef void (*uv_udp_recv_cb)(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags); + +/* uv_udp_t is a subclass of uv_handle_t. */ +struct uv_udp_s { + UV_HANDLE_FIELDS + /* read-only */ + /* + * Number of bytes queued for sending. This field strictly shows how much + * information is currently queued. + */ + size_t send_queue_size; + /* + * Number of send requests currently in the queue awaiting to be processed. + */ + size_t send_queue_count; + UV_UDP_PRIVATE_FIELDS +}; + +/* uv_udp_send_t is a subclass of uv_req_t. */ +struct uv_udp_send_s { + UV_REQ_FIELDS + uv_udp_t* handle; + uv_udp_send_cb cb; + UV_UDP_SEND_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle); +UV_EXTERN int uv_udp_init_ex(uv_loop_t*, uv_udp_t* handle, unsigned int flags); +UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock); +UV_EXTERN int uv_udp_bind(uv_udp_t* handle, + const struct sockaddr* addr, + unsigned int flags); +UV_EXTERN int uv_udp_connect(uv_udp_t* handle, const struct sockaddr* addr); + +UV_EXTERN int uv_udp_getpeername(const uv_udp_t* handle, + struct sockaddr* name, + int* namelen); +UV_EXTERN int uv_udp_getsockname(const uv_udp_t* handle, + struct sockaddr* name, + int* namelen); +UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle, + const char* multicast_addr, + const char* interface_addr, + uv_membership membership); +UV_EXTERN int uv_udp_set_source_membership(uv_udp_t* handle, + const char* multicast_addr, + const char* interface_addr, + const char* source_addr, + uv_membership membership); +UV_EXTERN int uv_udp_set_multicast_loop(uv_udp_t* handle, int on); +UV_EXTERN int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl); +UV_EXTERN int uv_udp_set_multicast_interface(uv_udp_t* handle, + const char* interface_addr); +UV_EXTERN int uv_udp_set_broadcast(uv_udp_t* handle, int on); +UV_EXTERN int uv_udp_set_ttl(uv_udp_t* handle, int ttl); +UV_EXTERN int uv_udp_send(uv_udp_send_t* req, + uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr, + uv_udp_send_cb send_cb); +UV_EXTERN int uv_udp_try_send(uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr); +UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle, + uv_alloc_cb alloc_cb, + uv_udp_recv_cb recv_cb); +UV_EXTERN int uv_udp_using_recvmmsg(const uv_udp_t* handle); +UV_EXTERN int uv_udp_recv_stop(uv_udp_t* handle); +UV_EXTERN size_t uv_udp_get_send_queue_size(const uv_udp_t* handle); +UV_EXTERN size_t uv_udp_get_send_queue_count(const uv_udp_t* handle); + + +/* + * uv_tty_t is a subclass of uv_stream_t. + * + * Representing a stream for the console. + */ +struct uv_tty_s { + UV_HANDLE_FIELDS + UV_STREAM_FIELDS + UV_TTY_PRIVATE_FIELDS +}; + +typedef enum { + /* Initial/normal terminal mode */ + UV_TTY_MODE_NORMAL, + /* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */ + UV_TTY_MODE_RAW, + /* Binary-safe I/O mode for IPC (Unix-only) */ + UV_TTY_MODE_IO +} uv_tty_mode_t; + +typedef enum { + /* + * The console supports handling of virtual terminal sequences + * (Windows10 new console, ConEmu) + */ + UV_TTY_SUPPORTED, + /* The console cannot process the virtual terminal sequence. (Legacy + * console) + */ + UV_TTY_UNSUPPORTED +} uv_tty_vtermstate_t; + + +UV_EXTERN int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable); +UV_EXTERN int uv_tty_set_mode(uv_tty_t*, uv_tty_mode_t mode); +UV_EXTERN int uv_tty_reset_mode(void); +UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height); +UV_EXTERN void uv_tty_set_vterm_state(uv_tty_vtermstate_t state); +UV_EXTERN int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state); + +#ifdef __cplusplus +extern "C++" { + +inline int uv_tty_set_mode(uv_tty_t* handle, int mode) { + return uv_tty_set_mode(handle, static_cast(mode)); +} + +} +#endif + +UV_EXTERN uv_handle_type uv_guess_handle(uv_file file); + +/* + * uv_pipe_t is a subclass of uv_stream_t. + * + * Representing a pipe stream or pipe server. On Windows this is a Named + * Pipe. On Unix this is a Unix domain socket. + */ +struct uv_pipe_s { + UV_HANDLE_FIELDS + UV_STREAM_FIELDS + int ipc; /* non-zero if this pipe is used for passing handles */ + UV_PIPE_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc); +UV_EXTERN int uv_pipe_open(uv_pipe_t*, uv_file file); +UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name); +UV_EXTERN void uv_pipe_connect(uv_connect_t* req, + uv_pipe_t* handle, + const char* name, + uv_connect_cb cb); +UV_EXTERN int uv_pipe_getsockname(const uv_pipe_t* handle, + char* buffer, + size_t* size); +UV_EXTERN int uv_pipe_getpeername(const uv_pipe_t* handle, + char* buffer, + size_t* size); +UV_EXTERN void uv_pipe_pending_instances(uv_pipe_t* handle, int count); +UV_EXTERN int uv_pipe_pending_count(uv_pipe_t* handle); +UV_EXTERN uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle); +UV_EXTERN int uv_pipe_chmod(uv_pipe_t* handle, int flags); + + +struct uv_poll_s { + UV_HANDLE_FIELDS + uv_poll_cb poll_cb; + UV_POLL_PRIVATE_FIELDS +}; + +enum uv_poll_event { + UV_READABLE = 1, + UV_WRITABLE = 2, + UV_DISCONNECT = 4, + UV_PRIORITIZED = 8 +}; + +UV_EXTERN int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd); +UV_EXTERN int uv_poll_init_socket(uv_loop_t* loop, + uv_poll_t* handle, + uv_os_sock_t socket); +UV_EXTERN int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb); +UV_EXTERN int uv_poll_stop(uv_poll_t* handle); + + +struct uv_prepare_s { + UV_HANDLE_FIELDS + UV_PREPARE_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_prepare_init(uv_loop_t*, uv_prepare_t* prepare); +UV_EXTERN int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb); +UV_EXTERN int uv_prepare_stop(uv_prepare_t* prepare); + + +struct uv_check_s { + UV_HANDLE_FIELDS + UV_CHECK_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_check_init(uv_loop_t*, uv_check_t* check); +UV_EXTERN int uv_check_start(uv_check_t* check, uv_check_cb cb); +UV_EXTERN int uv_check_stop(uv_check_t* check); + + +struct uv_idle_s { + UV_HANDLE_FIELDS + UV_IDLE_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_idle_init(uv_loop_t*, uv_idle_t* idle); +UV_EXTERN int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb); +UV_EXTERN int uv_idle_stop(uv_idle_t* idle); + + +struct uv_async_s { + UV_HANDLE_FIELDS + UV_ASYNC_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_async_init(uv_loop_t*, + uv_async_t* async, + uv_async_cb async_cb); +UV_EXTERN int uv_async_send(uv_async_t* async); + + +/* + * uv_timer_t is a subclass of uv_handle_t. + * + * Used to get woken up at a specified time in the future. + */ +struct uv_timer_s { + UV_HANDLE_FIELDS + UV_TIMER_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_timer_init(uv_loop_t*, uv_timer_t* handle); +UV_EXTERN int uv_timer_start(uv_timer_t* handle, + uv_timer_cb cb, + uint64_t timeout, + uint64_t repeat); +UV_EXTERN int uv_timer_stop(uv_timer_t* handle); +UV_EXTERN int uv_timer_again(uv_timer_t* handle); +UV_EXTERN void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat); +UV_EXTERN uint64_t uv_timer_get_repeat(const uv_timer_t* handle); +UV_EXTERN uint64_t uv_timer_get_due_in(const uv_timer_t* handle); + + +/* + * uv_getaddrinfo_t is a subclass of uv_req_t. + * + * Request object for uv_getaddrinfo. + */ +struct uv_getaddrinfo_s { + UV_REQ_FIELDS + /* read-only */ + uv_loop_t* loop; + /* struct addrinfo* addrinfo is marked as private, but it really isn't. */ + UV_GETADDRINFO_PRIVATE_FIELDS +}; + + +UV_EXTERN int uv_getaddrinfo(uv_loop_t* loop, + uv_getaddrinfo_t* req, + uv_getaddrinfo_cb getaddrinfo_cb, + const char* node, + const char* service, + const struct addrinfo* hints); +UV_EXTERN void uv_freeaddrinfo(struct addrinfo* ai); + + +/* +* uv_getnameinfo_t is a subclass of uv_req_t. +* +* Request object for uv_getnameinfo. +*/ +struct uv_getnameinfo_s { + UV_REQ_FIELDS + /* read-only */ + uv_loop_t* loop; + /* host and service are marked as private, but they really aren't. */ + UV_GETNAMEINFO_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_getnameinfo(uv_loop_t* loop, + uv_getnameinfo_t* req, + uv_getnameinfo_cb getnameinfo_cb, + const struct sockaddr* addr, + int flags); + + +/* uv_spawn() options. */ +typedef enum { + UV_IGNORE = 0x00, + UV_CREATE_PIPE = 0x01, + UV_INHERIT_FD = 0x02, + UV_INHERIT_STREAM = 0x04, + + /* + * When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE + * determine the direction of flow, from the child process' perspective. Both + * flags may be specified to create a duplex data stream. + */ + UV_READABLE_PIPE = 0x10, + UV_WRITABLE_PIPE = 0x20, + + /* + * When UV_CREATE_PIPE is specified, specifying UV_NONBLOCK_PIPE opens the + * handle in non-blocking mode in the child. This may cause loss of data, + * if the child is not designed to handle to encounter this mode, + * but can also be significantly more efficient. + */ + UV_NONBLOCK_PIPE = 0x40, + UV_OVERLAPPED_PIPE = 0x40 /* old name, for compatibility */ +} uv_stdio_flags; + +typedef struct uv_stdio_container_s { + uv_stdio_flags flags; + + union { + uv_stream_t* stream; + int fd; + } data; +} uv_stdio_container_t; + +typedef struct uv_process_options_s { + uv_exit_cb exit_cb; /* Called after the process exits. */ + const char* file; /* Path to program to execute. */ + /* + * Command line arguments. args[0] should be the path to the program. On + * Windows this uses CreateProcess which concatenates the arguments into a + * string this can cause some strange errors. See the note at + * windows_verbatim_arguments. + */ + char** args; + /* + * This will be set as the environ variable in the subprocess. If this is + * NULL then the parents environ will be used. + */ + char** env; + /* + * If non-null this represents a directory the subprocess should execute + * in. Stands for current working directory. + */ + const char* cwd; + /* + * Various flags that control how uv_spawn() behaves. See the definition of + * `enum uv_process_flags` below. + */ + unsigned int flags; + /* + * The `stdio` field points to an array of uv_stdio_container_t structs that + * describe the file descriptors that will be made available to the child + * process. The convention is that stdio[0] points to stdin, fd 1 is used for + * stdout, and fd 2 is stderr. + * + * Note that on windows file descriptors greater than 2 are available to the + * child process only if the child processes uses the MSVCRT runtime. + */ + int stdio_count; + uv_stdio_container_t* stdio; + /* + * Libuv can change the child process' user/group id. This happens only when + * the appropriate bits are set in the flags fields. This is not supported on + * windows; uv_spawn() will fail and set the error to UV_ENOTSUP. + */ + uv_uid_t uid; + uv_gid_t gid; +} uv_process_options_t; + +/* + * These are the flags that can be used for the uv_process_options.flags field. + */ +enum uv_process_flags { + /* + * Set the child process' user id. The user id is supplied in the `uid` field + * of the options struct. This does not work on windows; setting this flag + * will cause uv_spawn() to fail. + */ + UV_PROCESS_SETUID = (1 << 0), + /* + * Set the child process' group id. The user id is supplied in the `gid` + * field of the options struct. This does not work on windows; setting this + * flag will cause uv_spawn() to fail. + */ + UV_PROCESS_SETGID = (1 << 1), + /* + * Do not wrap any arguments in quotes, or perform any other escaping, when + * converting the argument list into a command line string. This option is + * only meaningful on Windows systems. On Unix it is silently ignored. + */ + UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = (1 << 2), + /* + * Spawn the child process in a detached state - this will make it a process + * group leader, and will effectively enable the child to keep running after + * the parent exits. Note that the child process will still keep the + * parent's event loop alive unless the parent process calls uv_unref() on + * the child's process handle. + */ + UV_PROCESS_DETACHED = (1 << 3), + /* + * Hide the subprocess window that would normally be created. This option is + * only meaningful on Windows systems. On Unix it is silently ignored. + */ + UV_PROCESS_WINDOWS_HIDE = (1 << 4), + /* + * Hide the subprocess console window that would normally be created. This + * option is only meaningful on Windows systems. On Unix it is silently + * ignored. + */ + UV_PROCESS_WINDOWS_HIDE_CONSOLE = (1 << 5), + /* + * Hide the subprocess GUI window that would normally be created. This + * option is only meaningful on Windows systems. On Unix it is silently + * ignored. + */ + UV_PROCESS_WINDOWS_HIDE_GUI = (1 << 6) +}; + +/* + * uv_process_t is a subclass of uv_handle_t. + */ +struct uv_process_s { + UV_HANDLE_FIELDS + uv_exit_cb exit_cb; + int pid; + UV_PROCESS_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_spawn(uv_loop_t* loop, + uv_process_t* handle, + const uv_process_options_t* options); +UV_EXTERN int uv_process_kill(uv_process_t*, int signum); +UV_EXTERN int uv_kill(int pid, int signum); +UV_EXTERN uv_pid_t uv_process_get_pid(const uv_process_t*); + + +/* + * uv_work_t is a subclass of uv_req_t. + */ +struct uv_work_s { + UV_REQ_FIELDS + uv_loop_t* loop; + uv_work_cb work_cb; + uv_after_work_cb after_work_cb; + UV_WORK_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_queue_work(uv_loop_t* loop, + uv_work_t* req, + uv_work_cb work_cb, + uv_after_work_cb after_work_cb); + +UV_EXTERN int uv_cancel(uv_req_t* req); + + +struct uv_cpu_times_s { + uint64_t user; /* milliseconds */ + uint64_t nice; /* milliseconds */ + uint64_t sys; /* milliseconds */ + uint64_t idle; /* milliseconds */ + uint64_t irq; /* milliseconds */ +}; + +struct uv_cpu_info_s { + char* model; + int speed; + struct uv_cpu_times_s cpu_times; +}; + +struct uv_interface_address_s { + char* name; + char phys_addr[6]; + int is_internal; + union { + struct sockaddr_in address4; + struct sockaddr_in6 address6; + } address; + union { + struct sockaddr_in netmask4; + struct sockaddr_in6 netmask6; + } netmask; +}; + +struct uv_passwd_s { + char* username; + long uid; + long gid; + char* shell; + char* homedir; +}; + +struct uv_utsname_s { + char sysname[256]; + char release[256]; + char version[256]; + char machine[256]; + /* This struct does not contain the nodename and domainname fields present in + the utsname type. domainname is a GNU extension. Both fields are referred + to as meaningless in the docs. */ +}; + +struct uv_statfs_s { + uint64_t f_type; + uint64_t f_bsize; + uint64_t f_blocks; + uint64_t f_bfree; + uint64_t f_bavail; + uint64_t f_files; + uint64_t f_ffree; + uint64_t f_spare[4]; +}; + +typedef enum { + UV_DIRENT_UNKNOWN, + UV_DIRENT_FILE, + UV_DIRENT_DIR, + UV_DIRENT_LINK, + UV_DIRENT_FIFO, + UV_DIRENT_SOCKET, + UV_DIRENT_CHAR, + UV_DIRENT_BLOCK +} uv_dirent_type_t; + +struct uv_dirent_s { + const char* name; + uv_dirent_type_t type; +}; + +UV_EXTERN char** uv_setup_args(int argc, char** argv); +UV_EXTERN int uv_get_process_title(char* buffer, size_t size); +UV_EXTERN int uv_set_process_title(const char* title); +UV_EXTERN int uv_resident_set_memory(size_t* rss); +UV_EXTERN int uv_uptime(double* uptime); +UV_EXTERN uv_os_fd_t uv_get_osfhandle(int fd); +UV_EXTERN int uv_open_osfhandle(uv_os_fd_t os_fd); + +typedef struct { + long tv_sec; + long tv_usec; +} uv_timeval_t; + +typedef struct { + int64_t tv_sec; + int32_t tv_usec; +} uv_timeval64_t; + +typedef struct { + uv_timeval_t ru_utime; /* user CPU time used */ + uv_timeval_t ru_stime; /* system CPU time used */ + uint64_t ru_maxrss; /* maximum resident set size */ + uint64_t ru_ixrss; /* integral shared memory size */ + uint64_t ru_idrss; /* integral unshared data size */ + uint64_t ru_isrss; /* integral unshared stack size */ + uint64_t ru_minflt; /* page reclaims (soft page faults) */ + uint64_t ru_majflt; /* page faults (hard page faults) */ + uint64_t ru_nswap; /* swaps */ + uint64_t ru_inblock; /* block input operations */ + uint64_t ru_oublock; /* block output operations */ + uint64_t ru_msgsnd; /* IPC messages sent */ + uint64_t ru_msgrcv; /* IPC messages received */ + uint64_t ru_nsignals; /* signals received */ + uint64_t ru_nvcsw; /* voluntary context switches */ + uint64_t ru_nivcsw; /* involuntary context switches */ +} uv_rusage_t; + +UV_EXTERN int uv_getrusage(uv_rusage_t* rusage); + +UV_EXTERN int uv_os_homedir(char* buffer, size_t* size); +UV_EXTERN int uv_os_tmpdir(char* buffer, size_t* size); +UV_EXTERN int uv_os_get_passwd(uv_passwd_t* pwd); +UV_EXTERN void uv_os_free_passwd(uv_passwd_t* pwd); +UV_EXTERN uv_pid_t uv_os_getpid(void); +UV_EXTERN uv_pid_t uv_os_getppid(void); + +#if defined(__PASE__) +/* On IBM i PASE, the highest process priority is -10 */ +# define UV_PRIORITY_LOW 39 /* RUNPTY(99) */ +# define UV_PRIORITY_BELOW_NORMAL 15 /* RUNPTY(50) */ +# define UV_PRIORITY_NORMAL 0 /* RUNPTY(20) */ +# define UV_PRIORITY_ABOVE_NORMAL -4 /* RUNTY(12) */ +# define UV_PRIORITY_HIGH -7 /* RUNPTY(6) */ +# define UV_PRIORITY_HIGHEST -10 /* RUNPTY(1) */ +#else +# define UV_PRIORITY_LOW 19 +# define UV_PRIORITY_BELOW_NORMAL 10 +# define UV_PRIORITY_NORMAL 0 +# define UV_PRIORITY_ABOVE_NORMAL -7 +# define UV_PRIORITY_HIGH -14 +# define UV_PRIORITY_HIGHEST -20 +#endif + +UV_EXTERN int uv_os_getpriority(uv_pid_t pid, int* priority); +UV_EXTERN int uv_os_setpriority(uv_pid_t pid, int priority); + +UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count); +UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count); + +UV_EXTERN int uv_interface_addresses(uv_interface_address_t** addresses, + int* count); +UV_EXTERN void uv_free_interface_addresses(uv_interface_address_t* addresses, + int count); + +struct uv_env_item_s { + char* name; + char* value; +}; + +UV_EXTERN int uv_os_environ(uv_env_item_t** envitems, int* count); +UV_EXTERN void uv_os_free_environ(uv_env_item_t* envitems, int count); +UV_EXTERN int uv_os_getenv(const char* name, char* buffer, size_t* size); +UV_EXTERN int uv_os_setenv(const char* name, const char* value); +UV_EXTERN int uv_os_unsetenv(const char* name); + +#ifdef MAXHOSTNAMELEN +# define UV_MAXHOSTNAMESIZE (MAXHOSTNAMELEN + 1) +#else + /* + Fallback for the maximum hostname size, including the null terminator. The + Windows gethostname() documentation states that 256 bytes will always be + large enough to hold the null-terminated hostname. + */ +# define UV_MAXHOSTNAMESIZE 256 +#endif + +UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size); + +UV_EXTERN int uv_os_uname(uv_utsname_t* buffer); + +UV_EXTERN uint64_t uv_metrics_idle_time(uv_loop_t* loop); + +typedef enum { + UV_FS_UNKNOWN = -1, + UV_FS_CUSTOM, + UV_FS_OPEN, + UV_FS_CLOSE, + UV_FS_READ, + UV_FS_WRITE, + UV_FS_SENDFILE, + UV_FS_STAT, + UV_FS_LSTAT, + UV_FS_FSTAT, + UV_FS_FTRUNCATE, + UV_FS_UTIME, + UV_FS_FUTIME, + UV_FS_ACCESS, + UV_FS_CHMOD, + UV_FS_FCHMOD, + UV_FS_FSYNC, + UV_FS_FDATASYNC, + UV_FS_UNLINK, + UV_FS_RMDIR, + UV_FS_MKDIR, + UV_FS_MKDTEMP, + UV_FS_RENAME, + UV_FS_SCANDIR, + UV_FS_LINK, + UV_FS_SYMLINK, + UV_FS_READLINK, + UV_FS_CHOWN, + UV_FS_FCHOWN, + UV_FS_REALPATH, + UV_FS_COPYFILE, + UV_FS_LCHOWN, + UV_FS_OPENDIR, + UV_FS_READDIR, + UV_FS_CLOSEDIR, + UV_FS_STATFS, + UV_FS_MKSTEMP, + UV_FS_LUTIME +} uv_fs_type; + +struct uv_dir_s { + uv_dirent_t* dirents; + size_t nentries; + void* reserved[4]; + UV_DIR_PRIVATE_FIELDS +}; + +/* uv_fs_t is a subclass of uv_req_t. */ +struct uv_fs_s { + UV_REQ_FIELDS + uv_fs_type fs_type; + uv_loop_t* loop; + uv_fs_cb cb; + ssize_t result; + void* ptr; + const char* path; + uv_stat_t statbuf; /* Stores the result of uv_fs_stat() and uv_fs_fstat(). */ + UV_FS_PRIVATE_FIELDS +}; + +UV_EXTERN uv_fs_type uv_fs_get_type(const uv_fs_t*); +UV_EXTERN ssize_t uv_fs_get_result(const uv_fs_t*); +UV_EXTERN int uv_fs_get_system_error(const uv_fs_t*); +UV_EXTERN void* uv_fs_get_ptr(const uv_fs_t*); +UV_EXTERN const char* uv_fs_get_path(const uv_fs_t*); +UV_EXTERN uv_stat_t* uv_fs_get_statbuf(uv_fs_t*); + +UV_EXTERN void uv_fs_req_cleanup(uv_fs_t* req); +UV_EXTERN int uv_fs_close(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_fs_cb cb); +UV_EXTERN int uv_fs_open(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int flags, + int mode, + uv_fs_cb cb); +UV_EXTERN int uv_fs_read(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + const uv_buf_t bufs[], + unsigned int nbufs, + int64_t offset, + uv_fs_cb cb); +UV_EXTERN int uv_fs_unlink(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_write(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + const uv_buf_t bufs[], + unsigned int nbufs, + int64_t offset, + uv_fs_cb cb); +/* + * This flag can be used with uv_fs_copyfile() to return an error if the + * destination already exists. + */ +#define UV_FS_COPYFILE_EXCL 0x0001 + +/* + * This flag can be used with uv_fs_copyfile() to attempt to create a reflink. + * If copy-on-write is not supported, a fallback copy mechanism is used. + */ +#define UV_FS_COPYFILE_FICLONE 0x0002 + +/* + * This flag can be used with uv_fs_copyfile() to attempt to create a reflink. + * If copy-on-write is not supported, an error is returned. + */ +#define UV_FS_COPYFILE_FICLONE_FORCE 0x0004 + +UV_EXTERN int uv_fs_copyfile(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + int flags, + uv_fs_cb cb); +UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int mode, + uv_fs_cb cb); +UV_EXTERN int uv_fs_mkdtemp(uv_loop_t* loop, + uv_fs_t* req, + const char* tpl, + uv_fs_cb cb); +UV_EXTERN int uv_fs_mkstemp(uv_loop_t* loop, + uv_fs_t* req, + const char* tpl, + uv_fs_cb cb); +UV_EXTERN int uv_fs_rmdir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_scandir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int flags, + uv_fs_cb cb); +UV_EXTERN int uv_fs_scandir_next(uv_fs_t* req, + uv_dirent_t* ent); +UV_EXTERN int uv_fs_opendir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_readdir(uv_loop_t* loop, + uv_fs_t* req, + uv_dir_t* dir, + uv_fs_cb cb); +UV_EXTERN int uv_fs_closedir(uv_loop_t* loop, + uv_fs_t* req, + uv_dir_t* dir, + uv_fs_cb cb); +UV_EXTERN int uv_fs_stat(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_fstat(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_fs_cb cb); +UV_EXTERN int uv_fs_rename(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_fsync(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_fs_cb cb); +UV_EXTERN int uv_fs_fdatasync(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_fs_cb cb); +UV_EXTERN int uv_fs_ftruncate(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + int64_t offset, + uv_fs_cb cb); +UV_EXTERN int uv_fs_sendfile(uv_loop_t* loop, + uv_fs_t* req, + uv_file out_fd, + uv_file in_fd, + int64_t in_offset, + size_t length, + uv_fs_cb cb); +UV_EXTERN int uv_fs_access(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int mode, + uv_fs_cb cb); +UV_EXTERN int uv_fs_chmod(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int mode, + uv_fs_cb cb); +UV_EXTERN int uv_fs_utime(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + double atime, + double mtime, + uv_fs_cb cb); +UV_EXTERN int uv_fs_futime(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + double atime, + double mtime, + uv_fs_cb cb); +UV_EXTERN int uv_fs_lutime(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + double atime, + double mtime, + uv_fs_cb cb); +UV_EXTERN int uv_fs_lstat(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_link(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + uv_fs_cb cb); + +/* + * This flag can be used with uv_fs_symlink() on Windows to specify whether + * path argument points to a directory. + */ +#define UV_FS_SYMLINK_DIR 0x0001 + +/* + * This flag can be used with uv_fs_symlink() on Windows to specify whether + * the symlink is to be created using junction points. + */ +#define UV_FS_SYMLINK_JUNCTION 0x0002 + +UV_EXTERN int uv_fs_symlink(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + int flags, + uv_fs_cb cb); +UV_EXTERN int uv_fs_readlink(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_realpath(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); +UV_EXTERN int uv_fs_fchmod(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + int mode, + uv_fs_cb cb); +UV_EXTERN int uv_fs_chown(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_uid_t uid, + uv_gid_t gid, + uv_fs_cb cb); +UV_EXTERN int uv_fs_fchown(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_uid_t uid, + uv_gid_t gid, + uv_fs_cb cb); +UV_EXTERN int uv_fs_lchown(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_uid_t uid, + uv_gid_t gid, + uv_fs_cb cb); +UV_EXTERN int uv_fs_statfs(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb); + + +enum uv_fs_event { + UV_RENAME = 1, + UV_CHANGE = 2 +}; + + +struct uv_fs_event_s { + UV_HANDLE_FIELDS + /* private */ + char* path; + UV_FS_EVENT_PRIVATE_FIELDS +}; + + +/* + * uv_fs_stat() based polling file watcher. + */ +struct uv_fs_poll_s { + UV_HANDLE_FIELDS + /* Private, don't touch. */ + void* poll_ctx; +}; + +UV_EXTERN int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle); +UV_EXTERN int uv_fs_poll_start(uv_fs_poll_t* handle, + uv_fs_poll_cb poll_cb, + const char* path, + unsigned int interval); +UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle); +UV_EXTERN int uv_fs_poll_getpath(uv_fs_poll_t* handle, + char* buffer, + size_t* size); + + +struct uv_signal_s { + UV_HANDLE_FIELDS + uv_signal_cb signal_cb; + int signum; + UV_SIGNAL_PRIVATE_FIELDS +}; + +UV_EXTERN int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle); +UV_EXTERN int uv_signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum); +UV_EXTERN int uv_signal_start_oneshot(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum); +UV_EXTERN int uv_signal_stop(uv_signal_t* handle); + +UV_EXTERN void uv_loadavg(double avg[3]); + + +/* + * Flags to be passed to uv_fs_event_start(). + */ +enum uv_fs_event_flags { + /* + * By default, if the fs event watcher is given a directory name, we will + * watch for all events in that directory. This flags overrides this behavior + * and makes fs_event report only changes to the directory entry itself. This + * flag does not affect individual files watched. + * This flag is currently not implemented yet on any backend. + */ + UV_FS_EVENT_WATCH_ENTRY = 1, + + /* + * By default uv_fs_event will try to use a kernel interface such as inotify + * or kqueue to detect events. This may not work on remote filesystems such + * as NFS mounts. This flag makes fs_event fall back to calling stat() on a + * regular interval. + * This flag is currently not implemented yet on any backend. + */ + UV_FS_EVENT_STAT = 2, + + /* + * By default, event watcher, when watching directory, is not registering + * (is ignoring) changes in it's subdirectories. + * This flag will override this behaviour on platforms that support it. + */ + UV_FS_EVENT_RECURSIVE = 4 +}; + + +UV_EXTERN int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle); +UV_EXTERN int uv_fs_event_start(uv_fs_event_t* handle, + uv_fs_event_cb cb, + const char* path, + unsigned int flags); +UV_EXTERN int uv_fs_event_stop(uv_fs_event_t* handle); +UV_EXTERN int uv_fs_event_getpath(uv_fs_event_t* handle, + char* buffer, + size_t* size); + +UV_EXTERN int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr); +UV_EXTERN int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr); + +UV_EXTERN int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size); +UV_EXTERN int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size); + +UV_EXTERN int uv_inet_ntop(int af, const void* src, char* dst, size_t size); +UV_EXTERN int uv_inet_pton(int af, const char* src, void* dst); + + +struct uv_random_s { + UV_REQ_FIELDS + /* read-only */ + uv_loop_t* loop; + /* private */ + int status; + void* buf; + size_t buflen; + uv_random_cb cb; + struct uv__work work_req; +}; + +UV_EXTERN int uv_random(uv_loop_t* loop, + uv_random_t* req, + void *buf, + size_t buflen, + unsigned flags, /* For future extension; must be 0. */ + uv_random_cb cb); + +#if defined(IF_NAMESIZE) +# define UV_IF_NAMESIZE (IF_NAMESIZE + 1) +#elif defined(IFNAMSIZ) +# define UV_IF_NAMESIZE (IFNAMSIZ + 1) +#else +# define UV_IF_NAMESIZE (16 + 1) +#endif + +UV_EXTERN int uv_if_indextoname(unsigned int ifindex, + char* buffer, + size_t* size); +UV_EXTERN int uv_if_indextoiid(unsigned int ifindex, + char* buffer, + size_t* size); + +UV_EXTERN int uv_exepath(char* buffer, size_t* size); + +UV_EXTERN int uv_cwd(char* buffer, size_t* size); + +UV_EXTERN int uv_chdir(const char* dir); + +UV_EXTERN uint64_t uv_get_free_memory(void); +UV_EXTERN uint64_t uv_get_total_memory(void); +UV_EXTERN uint64_t uv_get_constrained_memory(void); + +UV_EXTERN uint64_t uv_hrtime(void); +UV_EXTERN void uv_sleep(unsigned int msec); + +UV_EXTERN void uv_disable_stdio_inheritance(void); + +UV_EXTERN int uv_dlopen(const char* filename, uv_lib_t* lib); +UV_EXTERN void uv_dlclose(uv_lib_t* lib); +UV_EXTERN int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr); +UV_EXTERN const char* uv_dlerror(const uv_lib_t* lib); + +UV_EXTERN int uv_mutex_init(uv_mutex_t* handle); +UV_EXTERN int uv_mutex_init_recursive(uv_mutex_t* handle); +UV_EXTERN void uv_mutex_destroy(uv_mutex_t* handle); +UV_EXTERN void uv_mutex_lock(uv_mutex_t* handle); +UV_EXTERN int uv_mutex_trylock(uv_mutex_t* handle); +UV_EXTERN void uv_mutex_unlock(uv_mutex_t* handle); + +UV_EXTERN int uv_rwlock_init(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_destroy(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_rdlock(uv_rwlock_t* rwlock); +UV_EXTERN int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_rdunlock(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_wrlock(uv_rwlock_t* rwlock); +UV_EXTERN int uv_rwlock_trywrlock(uv_rwlock_t* rwlock); +UV_EXTERN void uv_rwlock_wrunlock(uv_rwlock_t* rwlock); + +UV_EXTERN int uv_sem_init(uv_sem_t* sem, unsigned int value); +UV_EXTERN void uv_sem_destroy(uv_sem_t* sem); +UV_EXTERN void uv_sem_post(uv_sem_t* sem); +UV_EXTERN void uv_sem_wait(uv_sem_t* sem); +UV_EXTERN int uv_sem_trywait(uv_sem_t* sem); + +UV_EXTERN int uv_cond_init(uv_cond_t* cond); +UV_EXTERN void uv_cond_destroy(uv_cond_t* cond); +UV_EXTERN void uv_cond_signal(uv_cond_t* cond); +UV_EXTERN void uv_cond_broadcast(uv_cond_t* cond); + +UV_EXTERN int uv_barrier_init(uv_barrier_t* barrier, unsigned int count); +UV_EXTERN void uv_barrier_destroy(uv_barrier_t* barrier); +UV_EXTERN int uv_barrier_wait(uv_barrier_t* barrier); + +UV_EXTERN void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex); +UV_EXTERN int uv_cond_timedwait(uv_cond_t* cond, + uv_mutex_t* mutex, + uint64_t timeout); + +UV_EXTERN void uv_once(uv_once_t* guard, void (*callback)(void)); + +UV_EXTERN int uv_key_create(uv_key_t* key); +UV_EXTERN void uv_key_delete(uv_key_t* key); +UV_EXTERN void* uv_key_get(uv_key_t* key); +UV_EXTERN void uv_key_set(uv_key_t* key, void* value); + +UV_EXTERN int uv_gettimeofday(uv_timeval64_t* tv); + +typedef void (*uv_thread_cb)(void* arg); + +UV_EXTERN int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg); + +typedef enum { + UV_THREAD_NO_FLAGS = 0x00, + UV_THREAD_HAS_STACK_SIZE = 0x01 +} uv_thread_create_flags; + +struct uv_thread_options_s { + unsigned int flags; + size_t stack_size; + /* More fields may be added at any time. */ +}; + +typedef struct uv_thread_options_s uv_thread_options_t; + +UV_EXTERN int uv_thread_create_ex(uv_thread_t* tid, + const uv_thread_options_t* params, + uv_thread_cb entry, + void* arg); +UV_EXTERN uv_thread_t uv_thread_self(void); +UV_EXTERN int uv_thread_join(uv_thread_t *tid); +UV_EXTERN int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2); + +/* The presence of these unions force similar struct layout. */ +#define XX(_, name) uv_ ## name ## _t name; +union uv_any_handle { + UV_HANDLE_TYPE_MAP(XX) +}; + +union uv_any_req { + UV_REQ_TYPE_MAP(XX) +}; +#undef XX + + +struct uv_loop_s { + /* User data - use this for whatever. */ + void* data; + /* Loop reference counting. */ + unsigned int active_handles; + void* handle_queue[2]; + union { + void* unused; + unsigned int count; + } active_reqs; + /* Internal storage for future extensions. */ + void* internal_fields; + /* Internal flag to signal loop stop. */ + unsigned int stop_flag; + UV_LOOP_PRIVATE_FIELDS +}; + +UV_EXTERN void* uv_loop_get_data(const uv_loop_t*); +UV_EXTERN void uv_loop_set_data(uv_loop_t*, void* data); + +/* Don't export the private CPP symbols. */ +#undef UV_HANDLE_TYPE_PRIVATE +#undef UV_REQ_TYPE_PRIVATE +#undef UV_REQ_PRIVATE_FIELDS +#undef UV_STREAM_PRIVATE_FIELDS +#undef UV_TCP_PRIVATE_FIELDS +#undef UV_PREPARE_PRIVATE_FIELDS +#undef UV_CHECK_PRIVATE_FIELDS +#undef UV_IDLE_PRIVATE_FIELDS +#undef UV_ASYNC_PRIVATE_FIELDS +#undef UV_TIMER_PRIVATE_FIELDS +#undef UV_GETADDRINFO_PRIVATE_FIELDS +#undef UV_GETNAMEINFO_PRIVATE_FIELDS +#undef UV_FS_REQ_PRIVATE_FIELDS +#undef UV_WORK_PRIVATE_FIELDS +#undef UV_FS_EVENT_PRIVATE_FIELDS +#undef UV_SIGNAL_PRIVATE_FIELDS +#undef UV_LOOP_PRIVATE_FIELDS +#undef UV_LOOP_PRIVATE_PLATFORM_FIELDS +#undef UV__ERR + +#ifdef __cplusplus +} +#endif +#endif /* UV_H */ diff --git a/external/src/libuv/include/uv/aix.h b/external/src/libuv/include/uv/aix.h new file mode 100644 index 0000000..7dc992f --- /dev/null +++ b/external/src/libuv/include/uv/aix.h @@ -0,0 +1,32 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_AIX_H +#define UV_AIX_H + +#define UV_PLATFORM_LOOP_FIELDS \ + int fs_fd; \ + +#define UV_PLATFORM_FS_EVENT_FIELDS \ + uv__io_t event_watcher; \ + char *dir_filename; \ + +#endif /* UV_AIX_H */ diff --git a/external/src/libuv/include/uv/android-ifaddrs.h b/external/src/libuv/include/uv/android-ifaddrs.h new file mode 100644 index 0000000..9cd19fe --- /dev/null +++ b/external/src/libuv/include/uv/android-ifaddrs.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1995, 1999 + * Berkeley Software Design, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp + */ + +#ifndef _IFADDRS_H_ +#define _IFADDRS_H_ + +struct ifaddrs { + struct ifaddrs *ifa_next; + char *ifa_name; + unsigned int ifa_flags; + struct sockaddr *ifa_addr; + struct sockaddr *ifa_netmask; + struct sockaddr *ifa_dstaddr; + void *ifa_data; +}; + +/* + * This may have been defined in . Note that if is + * to be included it must be included before this header file. + */ +#ifndef ifa_broadaddr +#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */ +#endif + +#include + +__BEGIN_DECLS +extern int getifaddrs(struct ifaddrs **ifap); +extern void freeifaddrs(struct ifaddrs *ifa); +__END_DECLS + +#endif diff --git a/external/src/libuv/include/uv/bsd.h b/external/src/libuv/include/uv/bsd.h new file mode 100644 index 0000000..2d72b3d --- /dev/null +++ b/external/src/libuv/include/uv/bsd.h @@ -0,0 +1,34 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_BSD_H +#define UV_BSD_H + +#define UV_PLATFORM_FS_EVENT_FIELDS \ + uv__io_t event_watcher; \ + +#define UV_IO_PRIVATE_PLATFORM_FIELDS \ + int rcount; \ + int wcount; \ + +#define UV_HAVE_KQUEUE 1 + +#endif /* UV_BSD_H */ diff --git a/external/src/libuv/include/uv/darwin.h b/external/src/libuv/include/uv/darwin.h new file mode 100644 index 0000000..d226415 --- /dev/null +++ b/external/src/libuv/include/uv/darwin.h @@ -0,0 +1,61 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_DARWIN_H +#define UV_DARWIN_H + +#if defined(__APPLE__) && defined(__MACH__) +# include +# include +# include +# include +# define UV_PLATFORM_SEM_T semaphore_t +#endif + +#define UV_IO_PRIVATE_PLATFORM_FIELDS \ + int rcount; \ + int wcount; \ + +#define UV_PLATFORM_LOOP_FIELDS \ + uv_thread_t cf_thread; \ + void* _cf_reserved; \ + void* cf_state; \ + uv_mutex_t cf_mutex; \ + uv_sem_t cf_sem; \ + void* cf_signals[2]; \ + +#define UV_PLATFORM_FS_EVENT_FIELDS \ + uv__io_t event_watcher; \ + char* realpath; \ + int realpath_len; \ + int cf_flags; \ + uv_async_t* cf_cb; \ + void* cf_events[2]; \ + void* cf_member[2]; \ + int cf_error; \ + uv_mutex_t cf_mutex; \ + +#define UV_STREAM_PRIVATE_PLATFORM_FIELDS \ + void* select; \ + +#define UV_HAVE_KQUEUE 1 + +#endif /* UV_DARWIN_H */ diff --git a/external/src/libuv/include/uv/errno.h b/external/src/libuv/include/uv/errno.h new file mode 100644 index 0000000..71906b3 --- /dev/null +++ b/external/src/libuv/include/uv/errno.h @@ -0,0 +1,460 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_ERRNO_H_ +#define UV_ERRNO_H_ + +#include +#if EDOM > 0 +# define UV__ERR(x) (-(x)) +#else +# define UV__ERR(x) (x) +#endif + +#define UV__EOF (-4095) +#define UV__UNKNOWN (-4094) + +#define UV__EAI_ADDRFAMILY (-3000) +#define UV__EAI_AGAIN (-3001) +#define UV__EAI_BADFLAGS (-3002) +#define UV__EAI_CANCELED (-3003) +#define UV__EAI_FAIL (-3004) +#define UV__EAI_FAMILY (-3005) +#define UV__EAI_MEMORY (-3006) +#define UV__EAI_NODATA (-3007) +#define UV__EAI_NONAME (-3008) +#define UV__EAI_OVERFLOW (-3009) +#define UV__EAI_SERVICE (-3010) +#define UV__EAI_SOCKTYPE (-3011) +#define UV__EAI_BADHINTS (-3013) +#define UV__EAI_PROTOCOL (-3014) + +/* Only map to the system errno on non-Windows platforms. It's apparently + * a fairly common practice for Windows programmers to redefine errno codes. + */ +#if defined(E2BIG) && !defined(_WIN32) +# define UV__E2BIG UV__ERR(E2BIG) +#else +# define UV__E2BIG (-4093) +#endif + +#if defined(EACCES) && !defined(_WIN32) +# define UV__EACCES UV__ERR(EACCES) +#else +# define UV__EACCES (-4092) +#endif + +#if defined(EADDRINUSE) && !defined(_WIN32) +# define UV__EADDRINUSE UV__ERR(EADDRINUSE) +#else +# define UV__EADDRINUSE (-4091) +#endif + +#if defined(EADDRNOTAVAIL) && !defined(_WIN32) +# define UV__EADDRNOTAVAIL UV__ERR(EADDRNOTAVAIL) +#else +# define UV__EADDRNOTAVAIL (-4090) +#endif + +#if defined(EAFNOSUPPORT) && !defined(_WIN32) +# define UV__EAFNOSUPPORT UV__ERR(EAFNOSUPPORT) +#else +# define UV__EAFNOSUPPORT (-4089) +#endif + +#if defined(EAGAIN) && !defined(_WIN32) +# define UV__EAGAIN UV__ERR(EAGAIN) +#else +# define UV__EAGAIN (-4088) +#endif + +#if defined(EALREADY) && !defined(_WIN32) +# define UV__EALREADY UV__ERR(EALREADY) +#else +# define UV__EALREADY (-4084) +#endif + +#if defined(EBADF) && !defined(_WIN32) +# define UV__EBADF UV__ERR(EBADF) +#else +# define UV__EBADF (-4083) +#endif + +#if defined(EBUSY) && !defined(_WIN32) +# define UV__EBUSY UV__ERR(EBUSY) +#else +# define UV__EBUSY (-4082) +#endif + +#if defined(ECANCELED) && !defined(_WIN32) +# define UV__ECANCELED UV__ERR(ECANCELED) +#else +# define UV__ECANCELED (-4081) +#endif + +#if defined(ECHARSET) && !defined(_WIN32) +# define UV__ECHARSET UV__ERR(ECHARSET) +#else +# define UV__ECHARSET (-4080) +#endif + +#if defined(ECONNABORTED) && !defined(_WIN32) +# define UV__ECONNABORTED UV__ERR(ECONNABORTED) +#else +# define UV__ECONNABORTED (-4079) +#endif + +#if defined(ECONNREFUSED) && !defined(_WIN32) +# define UV__ECONNREFUSED UV__ERR(ECONNREFUSED) +#else +# define UV__ECONNREFUSED (-4078) +#endif + +#if defined(ECONNRESET) && !defined(_WIN32) +# define UV__ECONNRESET UV__ERR(ECONNRESET) +#else +# define UV__ECONNRESET (-4077) +#endif + +#if defined(EDESTADDRREQ) && !defined(_WIN32) +# define UV__EDESTADDRREQ UV__ERR(EDESTADDRREQ) +#else +# define UV__EDESTADDRREQ (-4076) +#endif + +#if defined(EEXIST) && !defined(_WIN32) +# define UV__EEXIST UV__ERR(EEXIST) +#else +# define UV__EEXIST (-4075) +#endif + +#if defined(EFAULT) && !defined(_WIN32) +# define UV__EFAULT UV__ERR(EFAULT) +#else +# define UV__EFAULT (-4074) +#endif + +#if defined(EHOSTUNREACH) && !defined(_WIN32) +# define UV__EHOSTUNREACH UV__ERR(EHOSTUNREACH) +#else +# define UV__EHOSTUNREACH (-4073) +#endif + +#if defined(EINTR) && !defined(_WIN32) +# define UV__EINTR UV__ERR(EINTR) +#else +# define UV__EINTR (-4072) +#endif + +#if defined(EINVAL) && !defined(_WIN32) +# define UV__EINVAL UV__ERR(EINVAL) +#else +# define UV__EINVAL (-4071) +#endif + +#if defined(EIO) && !defined(_WIN32) +# define UV__EIO UV__ERR(EIO) +#else +# define UV__EIO (-4070) +#endif + +#if defined(EISCONN) && !defined(_WIN32) +# define UV__EISCONN UV__ERR(EISCONN) +#else +# define UV__EISCONN (-4069) +#endif + +#if defined(EISDIR) && !defined(_WIN32) +# define UV__EISDIR UV__ERR(EISDIR) +#else +# define UV__EISDIR (-4068) +#endif + +#if defined(ELOOP) && !defined(_WIN32) +# define UV__ELOOP UV__ERR(ELOOP) +#else +# define UV__ELOOP (-4067) +#endif + +#if defined(EMFILE) && !defined(_WIN32) +# define UV__EMFILE UV__ERR(EMFILE) +#else +# define UV__EMFILE (-4066) +#endif + +#if defined(EMSGSIZE) && !defined(_WIN32) +# define UV__EMSGSIZE UV__ERR(EMSGSIZE) +#else +# define UV__EMSGSIZE (-4065) +#endif + +#if defined(ENAMETOOLONG) && !defined(_WIN32) +# define UV__ENAMETOOLONG UV__ERR(ENAMETOOLONG) +#else +# define UV__ENAMETOOLONG (-4064) +#endif + +#if defined(ENETDOWN) && !defined(_WIN32) +# define UV__ENETDOWN UV__ERR(ENETDOWN) +#else +# define UV__ENETDOWN (-4063) +#endif + +#if defined(ENETUNREACH) && !defined(_WIN32) +# define UV__ENETUNREACH UV__ERR(ENETUNREACH) +#else +# define UV__ENETUNREACH (-4062) +#endif + +#if defined(ENFILE) && !defined(_WIN32) +# define UV__ENFILE UV__ERR(ENFILE) +#else +# define UV__ENFILE (-4061) +#endif + +#if defined(ENOBUFS) && !defined(_WIN32) +# define UV__ENOBUFS UV__ERR(ENOBUFS) +#else +# define UV__ENOBUFS (-4060) +#endif + +#if defined(ENODEV) && !defined(_WIN32) +# define UV__ENODEV UV__ERR(ENODEV) +#else +# define UV__ENODEV (-4059) +#endif + +#if defined(ENOENT) && !defined(_WIN32) +# define UV__ENOENT UV__ERR(ENOENT) +#else +# define UV__ENOENT (-4058) +#endif + +#if defined(ENOMEM) && !defined(_WIN32) +# define UV__ENOMEM UV__ERR(ENOMEM) +#else +# define UV__ENOMEM (-4057) +#endif + +#if defined(ENONET) && !defined(_WIN32) +# define UV__ENONET UV__ERR(ENONET) +#else +# define UV__ENONET (-4056) +#endif + +#if defined(ENOSPC) && !defined(_WIN32) +# define UV__ENOSPC UV__ERR(ENOSPC) +#else +# define UV__ENOSPC (-4055) +#endif + +#if defined(ENOSYS) && !defined(_WIN32) +# define UV__ENOSYS UV__ERR(ENOSYS) +#else +# define UV__ENOSYS (-4054) +#endif + +#if defined(ENOTCONN) && !defined(_WIN32) +# define UV__ENOTCONN UV__ERR(ENOTCONN) +#else +# define UV__ENOTCONN (-4053) +#endif + +#if defined(ENOTDIR) && !defined(_WIN32) +# define UV__ENOTDIR UV__ERR(ENOTDIR) +#else +# define UV__ENOTDIR (-4052) +#endif + +#if defined(ENOTEMPTY) && !defined(_WIN32) +# define UV__ENOTEMPTY UV__ERR(ENOTEMPTY) +#else +# define UV__ENOTEMPTY (-4051) +#endif + +#if defined(ENOTSOCK) && !defined(_WIN32) +# define UV__ENOTSOCK UV__ERR(ENOTSOCK) +#else +# define UV__ENOTSOCK (-4050) +#endif + +#if defined(ENOTSUP) && !defined(_WIN32) +# define UV__ENOTSUP UV__ERR(ENOTSUP) +#else +# define UV__ENOTSUP (-4049) +#endif + +#if defined(EPERM) && !defined(_WIN32) +# define UV__EPERM UV__ERR(EPERM) +#else +# define UV__EPERM (-4048) +#endif + +#if defined(EPIPE) && !defined(_WIN32) +# define UV__EPIPE UV__ERR(EPIPE) +#else +# define UV__EPIPE (-4047) +#endif + +#if defined(EPROTO) && !defined(_WIN32) +# define UV__EPROTO UV__ERR(EPROTO) +#else +# define UV__EPROTO (-4046) +#endif + +#if defined(EPROTONOSUPPORT) && !defined(_WIN32) +# define UV__EPROTONOSUPPORT UV__ERR(EPROTONOSUPPORT) +#else +# define UV__EPROTONOSUPPORT (-4045) +#endif + +#if defined(EPROTOTYPE) && !defined(_WIN32) +# define UV__EPROTOTYPE UV__ERR(EPROTOTYPE) +#else +# define UV__EPROTOTYPE (-4044) +#endif + +#if defined(EROFS) && !defined(_WIN32) +# define UV__EROFS UV__ERR(EROFS) +#else +# define UV__EROFS (-4043) +#endif + +#if defined(ESHUTDOWN) && !defined(_WIN32) +# define UV__ESHUTDOWN UV__ERR(ESHUTDOWN) +#else +# define UV__ESHUTDOWN (-4042) +#endif + +#if defined(ESPIPE) && !defined(_WIN32) +# define UV__ESPIPE UV__ERR(ESPIPE) +#else +# define UV__ESPIPE (-4041) +#endif + +#if defined(ESRCH) && !defined(_WIN32) +# define UV__ESRCH UV__ERR(ESRCH) +#else +# define UV__ESRCH (-4040) +#endif + +#if defined(ETIMEDOUT) && !defined(_WIN32) +# define UV__ETIMEDOUT UV__ERR(ETIMEDOUT) +#else +# define UV__ETIMEDOUT (-4039) +#endif + +#if defined(ETXTBSY) && !defined(_WIN32) +# define UV__ETXTBSY UV__ERR(ETXTBSY) +#else +# define UV__ETXTBSY (-4038) +#endif + +#if defined(EXDEV) && !defined(_WIN32) +# define UV__EXDEV UV__ERR(EXDEV) +#else +# define UV__EXDEV (-4037) +#endif + +#if defined(EFBIG) && !defined(_WIN32) +# define UV__EFBIG UV__ERR(EFBIG) +#else +# define UV__EFBIG (-4036) +#endif + +#if defined(ENOPROTOOPT) && !defined(_WIN32) +# define UV__ENOPROTOOPT UV__ERR(ENOPROTOOPT) +#else +# define UV__ENOPROTOOPT (-4035) +#endif + +#if defined(ERANGE) && !defined(_WIN32) +# define UV__ERANGE UV__ERR(ERANGE) +#else +# define UV__ERANGE (-4034) +#endif + +#if defined(ENXIO) && !defined(_WIN32) +# define UV__ENXIO UV__ERR(ENXIO) +#else +# define UV__ENXIO (-4033) +#endif + +#if defined(EMLINK) && !defined(_WIN32) +# define UV__EMLINK UV__ERR(EMLINK) +#else +# define UV__EMLINK (-4032) +#endif + +/* EHOSTDOWN is not visible on BSD-like systems when _POSIX_C_SOURCE is + * defined. Fortunately, its value is always 64 so it's possible albeit + * icky to hard-code it. + */ +#if defined(EHOSTDOWN) && !defined(_WIN32) +# define UV__EHOSTDOWN UV__ERR(EHOSTDOWN) +#elif defined(__APPLE__) || \ + defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || \ + defined(__NetBSD__) || \ + defined(__OpenBSD__) +# define UV__EHOSTDOWN (-64) +#else +# define UV__EHOSTDOWN (-4031) +#endif + +#if defined(EREMOTEIO) && !defined(_WIN32) +# define UV__EREMOTEIO UV__ERR(EREMOTEIO) +#else +# define UV__EREMOTEIO (-4030) +#endif + +#if defined(ENOTTY) && !defined(_WIN32) +# define UV__ENOTTY UV__ERR(ENOTTY) +#else +# define UV__ENOTTY (-4029) +#endif + +#if defined(EFTYPE) && !defined(_WIN32) +# define UV__EFTYPE UV__ERR(EFTYPE) +#else +# define UV__EFTYPE (-4028) +#endif + +#if defined(EILSEQ) && !defined(_WIN32) +# define UV__EILSEQ UV__ERR(EILSEQ) +#else +# define UV__EILSEQ (-4027) +#endif + +#if defined(EOVERFLOW) && !defined(_WIN32) +# define UV__EOVERFLOW UV__ERR(EOVERFLOW) +#else +# define UV__EOVERFLOW (-4026) +#endif + +#if defined(ESOCKTNOSUPPORT) && !defined(_WIN32) +# define UV__ESOCKTNOSUPPORT UV__ERR(ESOCKTNOSUPPORT) +#else +# define UV__ESOCKTNOSUPPORT (-4025) +#endif + +#endif /* UV_ERRNO_H_ */ diff --git a/external/src/libuv/include/uv/linux.h b/external/src/libuv/include/uv/linux.h new file mode 100644 index 0000000..9b38405 --- /dev/null +++ b/external/src/libuv/include/uv/linux.h @@ -0,0 +1,34 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_LINUX_H +#define UV_LINUX_H + +#define UV_PLATFORM_LOOP_FIELDS \ + uv__io_t inotify_read_watcher; \ + void* inotify_watchers; \ + int inotify_fd; \ + +#define UV_PLATFORM_FS_EVENT_FIELDS \ + void* watchers[2]; \ + int wd; \ + +#endif /* UV_LINUX_H */ diff --git a/external/src/libuv/include/uv/os390.h b/external/src/libuv/include/uv/os390.h new file mode 100644 index 0000000..0267d74 --- /dev/null +++ b/external/src/libuv/include/uv/os390.h @@ -0,0 +1,33 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_MVS_H +#define UV_MVS_H + +#define UV_PLATFORM_SEM_T long + +#define UV_PLATFORM_LOOP_FIELDS \ + void* ep; \ + +#define UV_PLATFORM_FS_EVENT_FIELDS \ + char rfis_rftok[8]; \ + +#endif /* UV_MVS_H */ diff --git a/external/src/libuv/include/uv/posix.h b/external/src/libuv/include/uv/posix.h new file mode 100644 index 0000000..9a96634 --- /dev/null +++ b/external/src/libuv/include/uv/posix.h @@ -0,0 +1,31 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_POSIX_H +#define UV_POSIX_H + +#define UV_PLATFORM_LOOP_FIELDS \ + struct pollfd* poll_fds; \ + size_t poll_fds_used; \ + size_t poll_fds_size; \ + unsigned char poll_fds_iterating; \ + +#endif /* UV_POSIX_H */ diff --git a/external/src/libuv/include/uv/stdint-msvc2008.h b/external/src/libuv/include/uv/stdint-msvc2008.h new file mode 100644 index 0000000..d02608a --- /dev/null +++ b/external/src/libuv/include/uv/stdint-msvc2008.h @@ -0,0 +1,247 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2008 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. The name of the author may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +#define INTMAX_C INT64_C +#define UINTMAX_C UINT64_C + +#endif // __STDC_CONSTANT_MACROS ] + + +#endif // _MSC_STDINT_H_ ] diff --git a/external/src/libuv/include/uv/sunos.h b/external/src/libuv/include/uv/sunos.h new file mode 100644 index 0000000..0421664 --- /dev/null +++ b/external/src/libuv/include/uv/sunos.h @@ -0,0 +1,44 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_SUNOS_H +#define UV_SUNOS_H + +#include +#include + +/* For the sake of convenience and reduced #ifdef-ery in src/unix/sunos.c, + * add the fs_event fields even when this version of SunOS doesn't support + * file watching. + */ +#define UV_PLATFORM_LOOP_FIELDS \ + uv__io_t fs_event_watcher; \ + int fs_fd; \ + +#if defined(PORT_SOURCE_FILE) + +# define UV_PLATFORM_FS_EVENT_FIELDS \ + file_obj_t fo; \ + int fd; \ + +#endif /* defined(PORT_SOURCE_FILE) */ + +#endif /* UV_SUNOS_H */ diff --git a/external/src/libuv/include/uv/threadpool.h b/external/src/libuv/include/uv/threadpool.h new file mode 100644 index 0000000..9708ebd --- /dev/null +++ b/external/src/libuv/include/uv/threadpool.h @@ -0,0 +1,37 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* + * This file is private to libuv. It provides common functionality to both + * Windows and Unix backends. + */ + +#ifndef UV_THREADPOOL_H_ +#define UV_THREADPOOL_H_ + +struct uv__work { + void (*work)(struct uv__work *w); + void (*done)(struct uv__work *w, int status); + struct uv_loop_s* loop; + void* wq[2]; +}; + +#endif /* UV_THREADPOOL_H_ */ diff --git a/external/src/libuv/include/uv/tree.h b/external/src/libuv/include/uv/tree.h new file mode 100644 index 0000000..2b28835 --- /dev/null +++ b/external/src/libuv/include/uv/tree.h @@ -0,0 +1,768 @@ +/*- + * Copyright 2002 Niels Provos + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UV_TREE_H_ +#define UV_TREE_H_ + +#ifndef UV__UNUSED +# if __GNUC__ +# define UV__UNUSED __attribute__((unused)) +# else +# define UV__UNUSED +# endif +#endif + +/* + * This file defines data structures for different types of trees: + * splay trees and red-black trees. + * + * A splay tree is a self-organizing data structure. Every operation + * on the tree causes a splay to happen. The splay moves the requested + * node to the root of the tree and partly rebalances it. + * + * This has the benefit that request locality causes faster lookups as + * the requested nodes move to the top of the tree. On the other hand, + * every lookup causes memory writes. + * + * The Balance Theorem bounds the total access time for m operations + * and n inserts on an initially empty tree as O((m + n)lg n). The + * amortized cost for a sequence of m accesses to a splay tree is O(lg n); + * + * A red-black tree is a binary search tree with the node color as an + * extra attribute. It fulfills a set of conditions: + * - every search path from the root to a leaf consists of the + * same number of black nodes, + * - each red node (except for the root) has a black parent, + * - each leaf node is black. + * + * Every operation on a red-black tree is bounded as O(lg n). + * The maximum height of a red-black tree is 2lg (n+1). + */ + +#define SPLAY_HEAD(name, type) \ +struct name { \ + struct type *sph_root; /* root of the tree */ \ +} + +#define SPLAY_INITIALIZER(root) \ + { NULL } + +#define SPLAY_INIT(root) do { \ + (root)->sph_root = NULL; \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_ENTRY(type) \ +struct { \ + struct type *spe_left; /* left element */ \ + struct type *spe_right; /* right element */ \ +} + +#define SPLAY_LEFT(elm, field) (elm)->field.spe_left +#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right +#define SPLAY_ROOT(head) (head)->sph_root +#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) + +/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ +#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + (head)->sph_root = tmp; \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_LINKLEFT(head, tmp, field) do { \ + SPLAY_LEFT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_LINKRIGHT(head, tmp, field) do { \ + SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ + tmp = (head)->sph_root; \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ +} while (/*CONSTCOND*/ 0) + +#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ + SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ + SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field); \ + SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ + SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ +} while (/*CONSTCOND*/ 0) + +/* Generates prototypes and inline functions */ + +#define SPLAY_PROTOTYPE(name, type, field, cmp) \ +void name##_SPLAY(struct name *, struct type *); \ +void name##_SPLAY_MINMAX(struct name *, int); \ +struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ +struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ + \ +/* Finds the node with the same key as elm */ \ +static __inline struct type * \ +name##_SPLAY_FIND(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) \ + return(NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) \ + return (head->sph_root); \ + return (NULL); \ +} \ + \ +static __inline struct type * \ +name##_SPLAY_NEXT(struct name *head, struct type *elm) \ +{ \ + name##_SPLAY(head, elm); \ + if (SPLAY_RIGHT(elm, field) != NULL) { \ + elm = SPLAY_RIGHT(elm, field); \ + while (SPLAY_LEFT(elm, field) != NULL) { \ + elm = SPLAY_LEFT(elm, field); \ + } \ + } else \ + elm = NULL; \ + return (elm); \ +} \ + \ +static __inline struct type * \ +name##_SPLAY_MIN_MAX(struct name *head, int val) \ +{ \ + name##_SPLAY_MINMAX(head, val); \ + return (SPLAY_ROOT(head)); \ +} + +/* Main splay operation. + * Moves node close to the key of elm to top + */ +#define SPLAY_GENERATE(name, type, field, cmp) \ +struct type * \ +name##_SPLAY_INSERT(struct name *head, struct type *elm) \ +{ \ + if (SPLAY_EMPTY(head)) { \ + SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ + } else { \ + int __comp; \ + name##_SPLAY(head, elm); \ + __comp = (cmp)(elm, (head)->sph_root); \ + if(__comp < 0) { \ + SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field); \ + SPLAY_RIGHT(elm, field) = (head)->sph_root; \ + SPLAY_LEFT((head)->sph_root, field) = NULL; \ + } else if (__comp > 0) { \ + SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field); \ + SPLAY_LEFT(elm, field) = (head)->sph_root; \ + SPLAY_RIGHT((head)->sph_root, field) = NULL; \ + } else \ + return ((head)->sph_root); \ + } \ + (head)->sph_root = (elm); \ + return (NULL); \ +} \ + \ +struct type * \ +name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ +{ \ + struct type *__tmp; \ + if (SPLAY_EMPTY(head)) \ + return (NULL); \ + name##_SPLAY(head, elm); \ + if ((cmp)(elm, (head)->sph_root) == 0) { \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ + (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ + } else { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ + name##_SPLAY(head, elm); \ + SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ + } \ + return (elm); \ + } \ + return (NULL); \ +} \ + \ +void \ +name##_SPLAY(struct name *head, struct type *elm) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ + int __comp; \ + \ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \ + __left = __right = &__node; \ + \ + while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL) \ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if ((cmp)(elm, __tmp) > 0){ \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} \ + \ +/* Splay with either the minimum or the maximum element \ + * Used to find minimum or maximum element in tree. \ + */ \ +void name##_SPLAY_MINMAX(struct name *head, int __comp) \ +{ \ + struct type __node, *__left, *__right, *__tmp; \ + \ + SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \ + __left = __right = &__node; \ + \ + for (;;) { \ + if (__comp < 0) { \ + __tmp = SPLAY_LEFT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp < 0){ \ + SPLAY_ROTATE_RIGHT(head, __tmp, field); \ + if (SPLAY_LEFT((head)->sph_root, field) == NULL) \ + break; \ + } \ + SPLAY_LINKLEFT(head, __right, field); \ + } else if (__comp > 0) { \ + __tmp = SPLAY_RIGHT((head)->sph_root, field); \ + if (__tmp == NULL) \ + break; \ + if (__comp > 0) { \ + SPLAY_ROTATE_LEFT(head, __tmp, field); \ + if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \ + break; \ + } \ + SPLAY_LINKRIGHT(head, __left, field); \ + } \ + } \ + SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ +} + +#define SPLAY_NEGINF -1 +#define SPLAY_INF 1 + +#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) +#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) +#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) +#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) +#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) +#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ + : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) + +#define SPLAY_FOREACH(x, name, head) \ + for ((x) = SPLAY_MIN(name, head); \ + (x) != NULL; \ + (x) = SPLAY_NEXT(name, head, x)) + +/* Macros that define a red-black tree */ +#define RB_HEAD(name, type) \ +struct name { \ + struct type *rbh_root; /* root of the tree */ \ +} + +#define RB_INITIALIZER(root) \ + { NULL } + +#define RB_INIT(root) do { \ + (root)->rbh_root = NULL; \ +} while (/*CONSTCOND*/ 0) + +#define RB_BLACK 0 +#define RB_RED 1 +#define RB_ENTRY(type) \ +struct { \ + struct type *rbe_left; /* left element */ \ + struct type *rbe_right; /* right element */ \ + struct type *rbe_parent; /* parent element */ \ + int rbe_color; /* node color */ \ +} + +#define RB_LEFT(elm, field) (elm)->field.rbe_left +#define RB_RIGHT(elm, field) (elm)->field.rbe_right +#define RB_PARENT(elm, field) (elm)->field.rbe_parent +#define RB_COLOR(elm, field) (elm)->field.rbe_color +#define RB_ROOT(head) (head)->rbh_root +#define RB_EMPTY(head) (RB_ROOT(head) == NULL) + +#define RB_SET(elm, parent, field) do { \ + RB_PARENT(elm, field) = parent; \ + RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ + RB_COLOR(elm, field) = RB_RED; \ +} while (/*CONSTCOND*/ 0) + +#define RB_SET_BLACKRED(black, red, field) do { \ + RB_COLOR(black, field) = RB_BLACK; \ + RB_COLOR(red, field) = RB_RED; \ +} while (/*CONSTCOND*/ 0) + +#ifndef RB_AUGMENT +#define RB_AUGMENT(x) do {} while (0) +#endif + +#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ + (tmp) = RB_RIGHT(elm, field); \ + if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \ + RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ + } \ + RB_AUGMENT(elm); \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ + else \ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ + } else \ + (head)->rbh_root = (tmp); \ + RB_LEFT(tmp, field) = (elm); \ + RB_PARENT(elm, field) = (tmp); \ + RB_AUGMENT(tmp); \ + if ((RB_PARENT(tmp, field))) \ + RB_AUGMENT(RB_PARENT(tmp, field)); \ +} while (/*CONSTCOND*/ 0) + +#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ + (tmp) = RB_LEFT(elm, field); \ + if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \ + RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ + } \ + RB_AUGMENT(elm); \ + if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ + if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ + RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ + else \ + RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ + } else \ + (head)->rbh_root = (tmp); \ + RB_RIGHT(tmp, field) = (elm); \ + RB_PARENT(elm, field) = (tmp); \ + RB_AUGMENT(tmp); \ + if ((RB_PARENT(tmp, field))) \ + RB_AUGMENT(RB_PARENT(tmp, field)); \ +} while (/*CONSTCOND*/ 0) + +/* Generates prototypes and inline functions */ +#define RB_PROTOTYPE(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) +#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ + RB_PROTOTYPE_INTERNAL(name, type, field, cmp, UV__UNUSED static) +#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ +attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \ +attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ +attr struct type *name##_RB_REMOVE(struct name *, struct type *); \ +attr struct type *name##_RB_INSERT(struct name *, struct type *); \ +attr struct type *name##_RB_FIND(struct name *, struct type *); \ +attr struct type *name##_RB_NFIND(struct name *, struct type *); \ +attr struct type *name##_RB_NEXT(struct type *); \ +attr struct type *name##_RB_PREV(struct type *); \ +attr struct type *name##_RB_MINMAX(struct name *, int); \ + \ + +/* Main rb operation. + * Moves node close to the key of elm to top + */ +#define RB_GENERATE(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp,) +#define RB_GENERATE_STATIC(name, type, field, cmp) \ + RB_GENERATE_INTERNAL(name, type, field, cmp, UV__UNUSED static) +#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ +attr void \ +name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ +{ \ + struct type *parent, *gparent, *tmp; \ + while ((parent = RB_PARENT(elm, field)) != NULL && \ + RB_COLOR(parent, field) == RB_RED) { \ + gparent = RB_PARENT(parent, field); \ + if (parent == RB_LEFT(gparent, field)) { \ + tmp = RB_RIGHT(gparent, field); \ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ + RB_COLOR(tmp, field) = RB_BLACK; \ + RB_SET_BLACKRED(parent, gparent, field); \ + elm = gparent; \ + continue; \ + } \ + if (RB_RIGHT(parent, field) == elm) { \ + RB_ROTATE_LEFT(head, parent, tmp, field); \ + tmp = parent; \ + parent = elm; \ + elm = tmp; \ + } \ + RB_SET_BLACKRED(parent, gparent, field); \ + RB_ROTATE_RIGHT(head, gparent, tmp, field); \ + } else { \ + tmp = RB_LEFT(gparent, field); \ + if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ + RB_COLOR(tmp, field) = RB_BLACK; \ + RB_SET_BLACKRED(parent, gparent, field); \ + elm = gparent; \ + continue; \ + } \ + if (RB_LEFT(parent, field) == elm) { \ + RB_ROTATE_RIGHT(head, parent, tmp, field); \ + tmp = parent; \ + parent = elm; \ + elm = tmp; \ + } \ + RB_SET_BLACKRED(parent, gparent, field); \ + RB_ROTATE_LEFT(head, gparent, tmp, field); \ + } \ + } \ + RB_COLOR(head->rbh_root, field) = RB_BLACK; \ +} \ + \ +attr void \ +name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, \ + struct type *elm) \ +{ \ + struct type *tmp; \ + while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ + elm != RB_ROOT(head)) { \ + if (RB_LEFT(parent, field) == elm) { \ + tmp = RB_RIGHT(parent, field); \ + if (RB_COLOR(tmp, field) == RB_RED) { \ + RB_SET_BLACKRED(tmp, parent, field); \ + RB_ROTATE_LEFT(head, parent, tmp, field); \ + tmp = RB_RIGHT(parent, field); \ + } \ + if ((RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \ + (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \ + RB_COLOR(tmp, field) = RB_RED; \ + elm = parent; \ + parent = RB_PARENT(elm, field); \ + } else { \ + if (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) { \ + struct type *oleft; \ + if ((oleft = RB_LEFT(tmp, field)) \ + != NULL) \ + RB_COLOR(oleft, field) = RB_BLACK; \ + RB_COLOR(tmp, field) = RB_RED; \ + RB_ROTATE_RIGHT(head, tmp, oleft, field); \ + tmp = RB_RIGHT(parent, field); \ + } \ + RB_COLOR(tmp, field) = RB_COLOR(parent, field); \ + RB_COLOR(parent, field) = RB_BLACK; \ + if (RB_RIGHT(tmp, field)) \ + RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; \ + RB_ROTATE_LEFT(head, parent, tmp, field); \ + elm = RB_ROOT(head); \ + break; \ + } \ + } else { \ + tmp = RB_LEFT(parent, field); \ + if (RB_COLOR(tmp, field) == RB_RED) { \ + RB_SET_BLACKRED(tmp, parent, field); \ + RB_ROTATE_RIGHT(head, parent, tmp, field); \ + tmp = RB_LEFT(parent, field); \ + } \ + if ((RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \ + (RB_RIGHT(tmp, field) == NULL || \ + RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \ + RB_COLOR(tmp, field) = RB_RED; \ + elm = parent; \ + parent = RB_PARENT(elm, field); \ + } else { \ + if (RB_LEFT(tmp, field) == NULL || \ + RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) { \ + struct type *oright; \ + if ((oright = RB_RIGHT(tmp, field)) \ + != NULL) \ + RB_COLOR(oright, field) = RB_BLACK; \ + RB_COLOR(tmp, field) = RB_RED; \ + RB_ROTATE_LEFT(head, tmp, oright, field); \ + tmp = RB_LEFT(parent, field); \ + } \ + RB_COLOR(tmp, field) = RB_COLOR(parent, field); \ + RB_COLOR(parent, field) = RB_BLACK; \ + if (RB_LEFT(tmp, field)) \ + RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK; \ + RB_ROTATE_RIGHT(head, parent, tmp, field); \ + elm = RB_ROOT(head); \ + break; \ + } \ + } \ + } \ + if (elm) \ + RB_COLOR(elm, field) = RB_BLACK; \ +} \ + \ +attr struct type * \ +name##_RB_REMOVE(struct name *head, struct type *elm) \ +{ \ + struct type *child, *parent, *old = elm; \ + int color; \ + if (RB_LEFT(elm, field) == NULL) \ + child = RB_RIGHT(elm, field); \ + else if (RB_RIGHT(elm, field) == NULL) \ + child = RB_LEFT(elm, field); \ + else { \ + struct type *left; \ + elm = RB_RIGHT(elm, field); \ + while ((left = RB_LEFT(elm, field)) != NULL) \ + elm = left; \ + child = RB_RIGHT(elm, field); \ + parent = RB_PARENT(elm, field); \ + color = RB_COLOR(elm, field); \ + if (child) \ + RB_PARENT(child, field) = parent; \ + if (parent) { \ + if (RB_LEFT(parent, field) == elm) \ + RB_LEFT(parent, field) = child; \ + else \ + RB_RIGHT(parent, field) = child; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = child; \ + if (RB_PARENT(elm, field) == old) \ + parent = elm; \ + (elm)->field = (old)->field; \ + if (RB_PARENT(old, field)) { \ + if (RB_LEFT(RB_PARENT(old, field), field) == old) \ + RB_LEFT(RB_PARENT(old, field), field) = elm; \ + else \ + RB_RIGHT(RB_PARENT(old, field), field) = elm; \ + RB_AUGMENT(RB_PARENT(old, field)); \ + } else \ + RB_ROOT(head) = elm; \ + RB_PARENT(RB_LEFT(old, field), field) = elm; \ + if (RB_RIGHT(old, field)) \ + RB_PARENT(RB_RIGHT(old, field), field) = elm; \ + if (parent) { \ + left = parent; \ + do { \ + RB_AUGMENT(left); \ + } while ((left = RB_PARENT(left, field)) != NULL); \ + } \ + goto color; \ + } \ + parent = RB_PARENT(elm, field); \ + color = RB_COLOR(elm, field); \ + if (child) \ + RB_PARENT(child, field) = parent; \ + if (parent) { \ + if (RB_LEFT(parent, field) == elm) \ + RB_LEFT(parent, field) = child; \ + else \ + RB_RIGHT(parent, field) = child; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = child; \ +color: \ + if (color == RB_BLACK) \ + name##_RB_REMOVE_COLOR(head, parent, child); \ + return (old); \ +} \ + \ +/* Inserts a node into the RB tree */ \ +attr struct type * \ +name##_RB_INSERT(struct name *head, struct type *elm) \ +{ \ + struct type *tmp; \ + struct type *parent = NULL; \ + int comp = 0; \ + tmp = RB_ROOT(head); \ + while (tmp) { \ + parent = tmp; \ + comp = (cmp)(elm, parent); \ + if (comp < 0) \ + tmp = RB_LEFT(tmp, field); \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + RB_SET(elm, parent, field); \ + if (parent != NULL) { \ + if (comp < 0) \ + RB_LEFT(parent, field) = elm; \ + else \ + RB_RIGHT(parent, field) = elm; \ + RB_AUGMENT(parent); \ + } else \ + RB_ROOT(head) = elm; \ + name##_RB_INSERT_COLOR(head, elm); \ + return (NULL); \ +} \ + \ +/* Finds the node with the same key as elm */ \ +attr struct type * \ +name##_RB_FIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + int comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) \ + tmp = RB_LEFT(tmp, field); \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (NULL); \ +} \ + \ +/* Finds the first node greater than or equal to the search key */ \ +attr struct type * \ +name##_RB_NFIND(struct name *head, struct type *elm) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *res = NULL; \ + int comp; \ + while (tmp) { \ + comp = cmp(elm, tmp); \ + if (comp < 0) { \ + res = tmp; \ + tmp = RB_LEFT(tmp, field); \ + } \ + else if (comp > 0) \ + tmp = RB_RIGHT(tmp, field); \ + else \ + return (tmp); \ + } \ + return (res); \ +} \ + \ +/* ARGSUSED */ \ +attr struct type * \ +name##_RB_NEXT(struct type *elm) \ +{ \ + if (RB_RIGHT(elm, field)) { \ + elm = RB_RIGHT(elm, field); \ + while (RB_LEFT(elm, field)) \ + elm = RB_LEFT(elm, field); \ + } else { \ + if (RB_PARENT(elm, field) && \ + (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + } \ + return (elm); \ +} \ + \ +/* ARGSUSED */ \ +attr struct type * \ +name##_RB_PREV(struct type *elm) \ +{ \ + if (RB_LEFT(elm, field)) { \ + elm = RB_LEFT(elm, field); \ + while (RB_RIGHT(elm, field)) \ + elm = RB_RIGHT(elm, field); \ + } else { \ + if (RB_PARENT(elm, field) && \ + (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + else { \ + while (RB_PARENT(elm, field) && \ + (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ + elm = RB_PARENT(elm, field); \ + elm = RB_PARENT(elm, field); \ + } \ + } \ + return (elm); \ +} \ + \ +attr struct type * \ +name##_RB_MINMAX(struct name *head, int val) \ +{ \ + struct type *tmp = RB_ROOT(head); \ + struct type *parent = NULL; \ + while (tmp) { \ + parent = tmp; \ + if (val < 0) \ + tmp = RB_LEFT(tmp, field); \ + else \ + tmp = RB_RIGHT(tmp, field); \ + } \ + return (parent); \ +} + +#define RB_NEGINF -1 +#define RB_INF 1 + +#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) +#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) +#define RB_FIND(name, x, y) name##_RB_FIND(x, y) +#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) +#define RB_NEXT(name, x, y) name##_RB_NEXT(y) +#define RB_PREV(name, x, y) name##_RB_PREV(y) +#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) +#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) + +#define RB_FOREACH(x, name, head) \ + for ((x) = RB_MIN(name, head); \ + (x) != NULL; \ + (x) = name##_RB_NEXT(x)) + +#define RB_FOREACH_FROM(x, name, y) \ + for ((x) = (y); \ + ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ + (x) = (y)) + +#define RB_FOREACH_SAFE(x, name, head, y) \ + for ((x) = RB_MIN(name, head); \ + ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ + (x) = (y)) + +#define RB_FOREACH_REVERSE(x, name, head) \ + for ((x) = RB_MAX(name, head); \ + (x) != NULL; \ + (x) = name##_RB_PREV(x)) + +#define RB_FOREACH_REVERSE_FROM(x, name, y) \ + for ((x) = (y); \ + ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ + (x) = (y)) + +#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ + for ((x) = RB_MAX(name, head); \ + ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ + (x) = (y)) + +#endif /* UV_TREE_H_ */ diff --git a/external/src/libuv/include/uv/unix.h b/external/src/libuv/include/uv/unix.h new file mode 100644 index 0000000..e3cf7bd --- /dev/null +++ b/external/src/libuv/include/uv/unix.h @@ -0,0 +1,507 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_UNIX_H +#define UV_UNIX_H + +#include +#include +#include +#include + +#include +#include +#include +#include +#include /* MAXHOSTNAMELEN on Solaris */ + +#include +#include + +#if !defined(__MVS__) +#include +#include /* MAXHOSTNAMELEN on Linux and the BSDs */ +#endif +#include +#include + +#include "uv/threadpool.h" + +#if defined(__linux__) +# include "uv/linux.h" +#elif defined (__MVS__) +# include "uv/os390.h" +#elif defined(__PASE__) /* __PASE__ and _AIX are both defined on IBM i */ +# include "uv/posix.h" /* IBM i needs uv/posix.h, not uv/aix.h */ +#elif defined(_AIX) +# include "uv/aix.h" +#elif defined(__sun) +# include "uv/sunos.h" +#elif defined(__APPLE__) +# include "uv/darwin.h" +#elif defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || \ + defined(__OpenBSD__) || \ + defined(__NetBSD__) +# include "uv/bsd.h" +#elif defined(__CYGWIN__) || \ + defined(__MSYS__) || \ + defined(__GNU__) +# include "uv/posix.h" +#elif defined(__HAIKU__) +# include "uv/posix.h" +#elif defined(__QNX__) +# include "uv/posix.h" +#endif + +#ifndef NI_MAXHOST +# define NI_MAXHOST 1025 +#endif + +#ifndef NI_MAXSERV +# define NI_MAXSERV 32 +#endif + +#ifndef UV_IO_PRIVATE_PLATFORM_FIELDS +# define UV_IO_PRIVATE_PLATFORM_FIELDS /* empty */ +#endif + +struct uv__io_s; +struct uv_loop_s; + +typedef void (*uv__io_cb)(struct uv_loop_s* loop, + struct uv__io_s* w, + unsigned int events); +typedef struct uv__io_s uv__io_t; + +struct uv__io_s { + uv__io_cb cb; + void* pending_queue[2]; + void* watcher_queue[2]; + unsigned int pevents; /* Pending event mask i.e. mask at next tick. */ + unsigned int events; /* Current event mask. */ + int fd; + UV_IO_PRIVATE_PLATFORM_FIELDS +}; + +#ifndef UV_PLATFORM_SEM_T +# define UV_PLATFORM_SEM_T sem_t +#endif + +#ifndef UV_PLATFORM_LOOP_FIELDS +# define UV_PLATFORM_LOOP_FIELDS /* empty */ +#endif + +#ifndef UV_PLATFORM_FS_EVENT_FIELDS +# define UV_PLATFORM_FS_EVENT_FIELDS /* empty */ +#endif + +#ifndef UV_STREAM_PRIVATE_PLATFORM_FIELDS +# define UV_STREAM_PRIVATE_PLATFORM_FIELDS /* empty */ +#endif + +/* Note: May be cast to struct iovec. See writev(2). */ +typedef struct uv_buf_t { + char* base; + size_t len; +} uv_buf_t; + +typedef int uv_file; +typedef int uv_os_sock_t; +typedef int uv_os_fd_t; +typedef pid_t uv_pid_t; + +#define UV_ONCE_INIT PTHREAD_ONCE_INIT + +typedef pthread_once_t uv_once_t; +typedef pthread_t uv_thread_t; +typedef pthread_mutex_t uv_mutex_t; +typedef pthread_rwlock_t uv_rwlock_t; +typedef UV_PLATFORM_SEM_T uv_sem_t; +typedef pthread_cond_t uv_cond_t; +typedef pthread_key_t uv_key_t; + +/* Note: guard clauses should match uv_barrier_init's in src/unix/thread.c. */ +#if defined(_AIX) || \ + defined(__OpenBSD__) || \ + !defined(PTHREAD_BARRIER_SERIAL_THREAD) +/* TODO(bnoordhuis) Merge into uv_barrier_t in v2. */ +struct _uv_barrier { + uv_mutex_t mutex; + uv_cond_t cond; + unsigned threshold; + unsigned in; + unsigned out; +}; + +typedef struct { + struct _uv_barrier* b; +# if defined(PTHREAD_BARRIER_SERIAL_THREAD) + /* TODO(bnoordhuis) Remove padding in v2. */ + char pad[sizeof(pthread_barrier_t) - sizeof(struct _uv_barrier*)]; +# endif +} uv_barrier_t; +#else +typedef pthread_barrier_t uv_barrier_t; +#endif + +/* Platform-specific definitions for uv_spawn support. */ +typedef gid_t uv_gid_t; +typedef uid_t uv_uid_t; + +typedef struct dirent uv__dirent_t; + +#define UV_DIR_PRIVATE_FIELDS \ + DIR* dir; + +#if defined(DT_UNKNOWN) +# define HAVE_DIRENT_TYPES +# if defined(DT_REG) +# define UV__DT_FILE DT_REG +# else +# define UV__DT_FILE -1 +# endif +# if defined(DT_DIR) +# define UV__DT_DIR DT_DIR +# else +# define UV__DT_DIR -2 +# endif +# if defined(DT_LNK) +# define UV__DT_LINK DT_LNK +# else +# define UV__DT_LINK -3 +# endif +# if defined(DT_FIFO) +# define UV__DT_FIFO DT_FIFO +# else +# define UV__DT_FIFO -4 +# endif +# if defined(DT_SOCK) +# define UV__DT_SOCKET DT_SOCK +# else +# define UV__DT_SOCKET -5 +# endif +# if defined(DT_CHR) +# define UV__DT_CHAR DT_CHR +# else +# define UV__DT_CHAR -6 +# endif +# if defined(DT_BLK) +# define UV__DT_BLOCK DT_BLK +# else +# define UV__DT_BLOCK -7 +# endif +#endif + +/* Platform-specific definitions for uv_dlopen support. */ +#define UV_DYNAMIC /* empty */ + +typedef struct { + void* handle; + char* errmsg; +} uv_lib_t; + +#define UV_LOOP_PRIVATE_FIELDS \ + unsigned long flags; \ + int backend_fd; \ + void* pending_queue[2]; \ + void* watcher_queue[2]; \ + uv__io_t** watchers; \ + unsigned int nwatchers; \ + unsigned int nfds; \ + void* wq[2]; \ + uv_mutex_t wq_mutex; \ + uv_async_t wq_async; \ + uv_rwlock_t cloexec_lock; \ + uv_handle_t* closing_handles; \ + void* process_handles[2]; \ + void* prepare_handles[2]; \ + void* check_handles[2]; \ + void* idle_handles[2]; \ + void* async_handles[2]; \ + void (*async_unused)(void); /* TODO(bnoordhuis) Remove in libuv v2. */ \ + uv__io_t async_io_watcher; \ + int async_wfd; \ + struct { \ + void* min; \ + unsigned int nelts; \ + } timer_heap; \ + uint64_t timer_counter; \ + uint64_t time; \ + int signal_pipefd[2]; \ + uv__io_t signal_io_watcher; \ + uv_signal_t child_watcher; \ + int emfile_fd; \ + UV_PLATFORM_LOOP_FIELDS \ + +#define UV_REQ_TYPE_PRIVATE /* empty */ + +#define UV_REQ_PRIVATE_FIELDS /* empty */ + +#define UV_PRIVATE_REQ_TYPES /* empty */ + +#define UV_WRITE_PRIVATE_FIELDS \ + void* queue[2]; \ + unsigned int write_index; \ + uv_buf_t* bufs; \ + unsigned int nbufs; \ + int error; \ + uv_buf_t bufsml[4]; \ + +#define UV_CONNECT_PRIVATE_FIELDS \ + void* queue[2]; \ + +#define UV_SHUTDOWN_PRIVATE_FIELDS /* empty */ + +#define UV_UDP_SEND_PRIVATE_FIELDS \ + void* queue[2]; \ + struct sockaddr_storage addr; \ + unsigned int nbufs; \ + uv_buf_t* bufs; \ + ssize_t status; \ + uv_udp_send_cb send_cb; \ + uv_buf_t bufsml[4]; \ + +#define UV_HANDLE_PRIVATE_FIELDS \ + uv_handle_t* next_closing; \ + unsigned int flags; \ + +#define UV_STREAM_PRIVATE_FIELDS \ + uv_connect_t *connect_req; \ + uv_shutdown_t *shutdown_req; \ + uv__io_t io_watcher; \ + void* write_queue[2]; \ + void* write_completed_queue[2]; \ + uv_connection_cb connection_cb; \ + int delayed_error; \ + int accepted_fd; \ + void* queued_fds; \ + UV_STREAM_PRIVATE_PLATFORM_FIELDS \ + +#define UV_TCP_PRIVATE_FIELDS /* empty */ + +#define UV_UDP_PRIVATE_FIELDS \ + uv_alloc_cb alloc_cb; \ + uv_udp_recv_cb recv_cb; \ + uv__io_t io_watcher; \ + void* write_queue[2]; \ + void* write_completed_queue[2]; \ + +#define UV_PIPE_PRIVATE_FIELDS \ + const char* pipe_fname; /* strdup'ed */ + +#define UV_POLL_PRIVATE_FIELDS \ + uv__io_t io_watcher; + +#define UV_PREPARE_PRIVATE_FIELDS \ + uv_prepare_cb prepare_cb; \ + void* queue[2]; \ + +#define UV_CHECK_PRIVATE_FIELDS \ + uv_check_cb check_cb; \ + void* queue[2]; \ + +#define UV_IDLE_PRIVATE_FIELDS \ + uv_idle_cb idle_cb; \ + void* queue[2]; \ + +#define UV_ASYNC_PRIVATE_FIELDS \ + uv_async_cb async_cb; \ + void* queue[2]; \ + int pending; \ + +#define UV_TIMER_PRIVATE_FIELDS \ + uv_timer_cb timer_cb; \ + void* heap_node[3]; \ + uint64_t timeout; \ + uint64_t repeat; \ + uint64_t start_id; + +#define UV_GETADDRINFO_PRIVATE_FIELDS \ + struct uv__work work_req; \ + uv_getaddrinfo_cb cb; \ + struct addrinfo* hints; \ + char* hostname; \ + char* service; \ + struct addrinfo* addrinfo; \ + int retcode; + +#define UV_GETNAMEINFO_PRIVATE_FIELDS \ + struct uv__work work_req; \ + uv_getnameinfo_cb getnameinfo_cb; \ + struct sockaddr_storage storage; \ + int flags; \ + char host[NI_MAXHOST]; \ + char service[NI_MAXSERV]; \ + int retcode; + +#define UV_PROCESS_PRIVATE_FIELDS \ + void* queue[2]; \ + int status; \ + +#define UV_FS_PRIVATE_FIELDS \ + const char *new_path; \ + uv_file file; \ + int flags; \ + mode_t mode; \ + unsigned int nbufs; \ + uv_buf_t* bufs; \ + off_t off; \ + uv_uid_t uid; \ + uv_gid_t gid; \ + double atime; \ + double mtime; \ + struct uv__work work_req; \ + uv_buf_t bufsml[4]; \ + +#define UV_WORK_PRIVATE_FIELDS \ + struct uv__work work_req; + +#define UV_TTY_PRIVATE_FIELDS \ + struct termios orig_termios; \ + int mode; + +#define UV_SIGNAL_PRIVATE_FIELDS \ + /* RB_ENTRY(uv_signal_s) tree_entry; */ \ + struct { \ + struct uv_signal_s* rbe_left; \ + struct uv_signal_s* rbe_right; \ + struct uv_signal_s* rbe_parent; \ + int rbe_color; \ + } tree_entry; \ + /* Use two counters here so we don have to fiddle with atomics. */ \ + unsigned int caught_signals; \ + unsigned int dispatched_signals; + +#define UV_FS_EVENT_PRIVATE_FIELDS \ + uv_fs_event_cb cb; \ + UV_PLATFORM_FS_EVENT_FIELDS \ + +/* fs open() flags supported on this platform: */ +#if defined(O_APPEND) +# define UV_FS_O_APPEND O_APPEND +#else +# define UV_FS_O_APPEND 0 +#endif +#if defined(O_CREAT) +# define UV_FS_O_CREAT O_CREAT +#else +# define UV_FS_O_CREAT 0 +#endif + +#if defined(__linux__) && defined(__arm__) +# define UV_FS_O_DIRECT 0x10000 +#elif defined(__linux__) && defined(__m68k__) +# define UV_FS_O_DIRECT 0x10000 +#elif defined(__linux__) && defined(__mips__) +# define UV_FS_O_DIRECT 0x08000 +#elif defined(__linux__) && defined(__powerpc__) +# define UV_FS_O_DIRECT 0x20000 +#elif defined(__linux__) && defined(__s390x__) +# define UV_FS_O_DIRECT 0x04000 +#elif defined(__linux__) && defined(__x86_64__) +# define UV_FS_O_DIRECT 0x04000 +#elif defined(O_DIRECT) +# define UV_FS_O_DIRECT O_DIRECT +#else +# define UV_FS_O_DIRECT 0 +#endif + +#if defined(O_DIRECTORY) +# define UV_FS_O_DIRECTORY O_DIRECTORY +#else +# define UV_FS_O_DIRECTORY 0 +#endif +#if defined(O_DSYNC) +# define UV_FS_O_DSYNC O_DSYNC +#else +# define UV_FS_O_DSYNC 0 +#endif +#if defined(O_EXCL) +# define UV_FS_O_EXCL O_EXCL +#else +# define UV_FS_O_EXCL 0 +#endif +#if defined(O_EXLOCK) +# define UV_FS_O_EXLOCK O_EXLOCK +#else +# define UV_FS_O_EXLOCK 0 +#endif +#if defined(O_NOATIME) +# define UV_FS_O_NOATIME O_NOATIME +#else +# define UV_FS_O_NOATIME 0 +#endif +#if defined(O_NOCTTY) +# define UV_FS_O_NOCTTY O_NOCTTY +#else +# define UV_FS_O_NOCTTY 0 +#endif +#if defined(O_NOFOLLOW) +# define UV_FS_O_NOFOLLOW O_NOFOLLOW +#else +# define UV_FS_O_NOFOLLOW 0 +#endif +#if defined(O_NONBLOCK) +# define UV_FS_O_NONBLOCK O_NONBLOCK +#else +# define UV_FS_O_NONBLOCK 0 +#endif +#if defined(O_RDONLY) +# define UV_FS_O_RDONLY O_RDONLY +#else +# define UV_FS_O_RDONLY 0 +#endif +#if defined(O_RDWR) +# define UV_FS_O_RDWR O_RDWR +#else +# define UV_FS_O_RDWR 0 +#endif +#if defined(O_SYMLINK) +# define UV_FS_O_SYMLINK O_SYMLINK +#else +# define UV_FS_O_SYMLINK 0 +#endif +#if defined(O_SYNC) +# define UV_FS_O_SYNC O_SYNC +#else +# define UV_FS_O_SYNC 0 +#endif +#if defined(O_TRUNC) +# define UV_FS_O_TRUNC O_TRUNC +#else +# define UV_FS_O_TRUNC 0 +#endif +#if defined(O_WRONLY) +# define UV_FS_O_WRONLY O_WRONLY +#else +# define UV_FS_O_WRONLY 0 +#endif + +/* fs open() flags supported on other platforms: */ +#define UV_FS_O_FILEMAP 0 +#define UV_FS_O_RANDOM 0 +#define UV_FS_O_SHORT_LIVED 0 +#define UV_FS_O_SEQUENTIAL 0 +#define UV_FS_O_TEMPORARY 0 + +#endif /* UV_UNIX_H */ diff --git a/external/src/libuv/include/uv/version.h b/external/src/libuv/include/uv/version.h new file mode 100644 index 0000000..ab5ed00 --- /dev/null +++ b/external/src/libuv/include/uv/version.h @@ -0,0 +1,43 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_VERSION_H +#define UV_VERSION_H + + /* + * Versions with the same major number are ABI stable. API is allowed to + * evolve between minor releases, but only in a backwards compatible way. + * Make sure you update the -soname directives in configure.ac + * whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but + * not UV_VERSION_PATCH.) + */ + +#define UV_VERSION_MAJOR 1 +#define UV_VERSION_MINOR 42 +#define UV_VERSION_PATCH 1 +#define UV_VERSION_IS_RELEASE 0 +#define UV_VERSION_SUFFIX "dev" + +#define UV_VERSION_HEX ((UV_VERSION_MAJOR << 16) | \ + (UV_VERSION_MINOR << 8) | \ + (UV_VERSION_PATCH)) + +#endif /* UV_VERSION_H */ diff --git a/external/src/libuv/include/uv/win.h b/external/src/libuv/include/uv/win.h new file mode 100644 index 0000000..f5f1d3a --- /dev/null +++ b/external/src/libuv/include/uv/win.h @@ -0,0 +1,691 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0600 +#endif + +#if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) +typedef intptr_t ssize_t; +# define SSIZE_MAX INTPTR_MAX +# define _SSIZE_T_ +# define _SSIZE_T_DEFINED +#endif + +#include + +#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) +typedef struct pollfd { + SOCKET fd; + short events; + short revents; +} WSAPOLLFD, *PWSAPOLLFD, *LPWSAPOLLFD; +#endif + +#ifndef LOCALE_INVARIANT +# define LOCALE_INVARIANT 0x007f +#endif + +#include +#include +#include + +#include +#include +#include +#include + +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "uv/stdint-msvc2008.h" +#else +# include +#endif + +#include "uv/tree.h" +#include "uv/threadpool.h" + +#define MAX_PIPENAME_LEN 256 + +#ifndef S_IFLNK +# define S_IFLNK 0xA000 +#endif + +/* Additional signals supported by uv_signal and or uv_kill. The CRT defines + * the following signals already: + * + * #define SIGINT 2 + * #define SIGILL 4 + * #define SIGABRT_COMPAT 6 + * #define SIGFPE 8 + * #define SIGSEGV 11 + * #define SIGTERM 15 + * #define SIGBREAK 21 + * #define SIGABRT 22 + * + * The additional signals have values that are common on other Unix + * variants (Linux and Darwin) + */ +#define SIGHUP 1 +#define SIGKILL 9 +#define SIGWINCH 28 + +/* Redefine NSIG to take SIGWINCH into consideration */ +#if defined(NSIG) && NSIG <= SIGWINCH +# undef NSIG +#endif +#ifndef NSIG +# define NSIG SIGWINCH + 1 +#endif + +/* The CRT defines SIGABRT_COMPAT as 6, which equals SIGABRT on many unix-like + * platforms. However MinGW doesn't define it, so we do. */ +#ifndef SIGABRT_COMPAT +# define SIGABRT_COMPAT 6 +#endif + +/* + * Guids and typedefs for winsock extension functions + * Mingw32 doesn't have these :-( + */ +#ifndef WSAID_ACCEPTEX +# define WSAID_ACCEPTEX \ + {0xb5367df1, 0xcbac, 0x11cf, \ + {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}} + +# define WSAID_CONNECTEX \ + {0x25a207b9, 0xddf3, 0x4660, \ + {0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e}} + +# define WSAID_GETACCEPTEXSOCKADDRS \ + {0xb5367df2, 0xcbac, 0x11cf, \ + {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}} + +# define WSAID_DISCONNECTEX \ + {0x7fda2e11, 0x8630, 0x436f, \ + {0xa0, 0x31, 0xf5, 0x36, 0xa6, 0xee, 0xc1, 0x57}} + +# define WSAID_TRANSMITFILE \ + {0xb5367df0, 0xcbac, 0x11cf, \ + {0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}} + + typedef BOOL (PASCAL *LPFN_ACCEPTEX) + (SOCKET sListenSocket, + SOCKET sAcceptSocket, + PVOID lpOutputBuffer, + DWORD dwReceiveDataLength, + DWORD dwLocalAddressLength, + DWORD dwRemoteAddressLength, + LPDWORD lpdwBytesReceived, + LPOVERLAPPED lpOverlapped); + + typedef BOOL (PASCAL *LPFN_CONNECTEX) + (SOCKET s, + const struct sockaddr* name, + int namelen, + PVOID lpSendBuffer, + DWORD dwSendDataLength, + LPDWORD lpdwBytesSent, + LPOVERLAPPED lpOverlapped); + + typedef void (PASCAL *LPFN_GETACCEPTEXSOCKADDRS) + (PVOID lpOutputBuffer, + DWORD dwReceiveDataLength, + DWORD dwLocalAddressLength, + DWORD dwRemoteAddressLength, + LPSOCKADDR* LocalSockaddr, + LPINT LocalSockaddrLength, + LPSOCKADDR* RemoteSockaddr, + LPINT RemoteSockaddrLength); + + typedef BOOL (PASCAL *LPFN_DISCONNECTEX) + (SOCKET hSocket, + LPOVERLAPPED lpOverlapped, + DWORD dwFlags, + DWORD reserved); + + typedef BOOL (PASCAL *LPFN_TRANSMITFILE) + (SOCKET hSocket, + HANDLE hFile, + DWORD nNumberOfBytesToWrite, + DWORD nNumberOfBytesPerSend, + LPOVERLAPPED lpOverlapped, + LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, + DWORD dwFlags); + + typedef PVOID RTL_SRWLOCK; + typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK; +#endif + +typedef int (WSAAPI* LPFN_WSARECV) + (SOCKET socket, + LPWSABUF buffers, + DWORD buffer_count, + LPDWORD bytes, + LPDWORD flags, + LPWSAOVERLAPPED overlapped, + LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine); + +typedef int (WSAAPI* LPFN_WSARECVFROM) + (SOCKET socket, + LPWSABUF buffers, + DWORD buffer_count, + LPDWORD bytes, + LPDWORD flags, + struct sockaddr* addr, + LPINT addr_len, + LPWSAOVERLAPPED overlapped, + LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine); + +#ifndef _NTDEF_ + typedef LONG NTSTATUS; + typedef NTSTATUS *PNTSTATUS; +#endif + +#ifndef RTL_CONDITION_VARIABLE_INIT + typedef PVOID CONDITION_VARIABLE, *PCONDITION_VARIABLE; +#endif + +typedef struct _AFD_POLL_HANDLE_INFO { + HANDLE Handle; + ULONG Events; + NTSTATUS Status; +} AFD_POLL_HANDLE_INFO, *PAFD_POLL_HANDLE_INFO; + +typedef struct _AFD_POLL_INFO { + LARGE_INTEGER Timeout; + ULONG NumberOfHandles; + ULONG Exclusive; + AFD_POLL_HANDLE_INFO Handles[1]; +} AFD_POLL_INFO, *PAFD_POLL_INFO; + +#define UV_MSAFD_PROVIDER_COUNT 3 + + +/** + * It should be possible to cast uv_buf_t[] to WSABUF[] + * see http://msdn.microsoft.com/en-us/library/ms741542(v=vs.85).aspx + */ +typedef struct uv_buf_t { + ULONG len; + char* base; +} uv_buf_t; + +typedef int uv_file; +typedef SOCKET uv_os_sock_t; +typedef HANDLE uv_os_fd_t; +typedef int uv_pid_t; + +typedef HANDLE uv_thread_t; + +typedef HANDLE uv_sem_t; + +typedef CRITICAL_SECTION uv_mutex_t; + +/* This condition variable implementation is based on the SetEvent solution + * (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html + * We could not use the SignalObjectAndWait solution (section 3.4) because + * it want the 2nd argument (type uv_mutex_t) of uv_cond_wait() and + * uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs. + */ + +typedef union { + CONDITION_VARIABLE cond_var; + struct { + unsigned int waiters_count; + CRITICAL_SECTION waiters_count_lock; + HANDLE signal_event; + HANDLE broadcast_event; + } unused_; /* TODO: retained for ABI compatibility; remove me in v2.x. */ +} uv_cond_t; + +typedef union { + struct { + unsigned int num_readers_; + CRITICAL_SECTION num_readers_lock_; + HANDLE write_semaphore_; + } state_; + /* TODO: remove me in v2.x. */ + struct { + SRWLOCK unused_; + } unused1_; + /* TODO: remove me in v2.x. */ + struct { + uv_mutex_t unused1_; + uv_mutex_t unused2_; + } unused2_; +} uv_rwlock_t; + +typedef struct { + unsigned int n; + unsigned int count; + uv_mutex_t mutex; + uv_sem_t turnstile1; + uv_sem_t turnstile2; +} uv_barrier_t; + +typedef struct { + DWORD tls_index; +} uv_key_t; + +#define UV_ONCE_INIT { 0, NULL } + +typedef struct uv_once_s { + unsigned char ran; + HANDLE event; +} uv_once_t; + +/* Platform-specific definitions for uv_spawn support. */ +typedef unsigned char uv_uid_t; +typedef unsigned char uv_gid_t; + +typedef struct uv__dirent_s { + int d_type; + char d_name[1]; +} uv__dirent_t; + +#define UV_DIR_PRIVATE_FIELDS \ + HANDLE dir_handle; \ + WIN32_FIND_DATAW find_data; \ + BOOL need_find_call; + +#define HAVE_DIRENT_TYPES +#define UV__DT_DIR UV_DIRENT_DIR +#define UV__DT_FILE UV_DIRENT_FILE +#define UV__DT_LINK UV_DIRENT_LINK +#define UV__DT_FIFO UV_DIRENT_FIFO +#define UV__DT_SOCKET UV_DIRENT_SOCKET +#define UV__DT_CHAR UV_DIRENT_CHAR +#define UV__DT_BLOCK UV_DIRENT_BLOCK + +/* Platform-specific definitions for uv_dlopen support. */ +#define UV_DYNAMIC FAR WINAPI +typedef struct { + HMODULE handle; + char* errmsg; +} uv_lib_t; + +#define UV_LOOP_PRIVATE_FIELDS \ + /* The loop's I/O completion port */ \ + HANDLE iocp; \ + /* The current time according to the event loop. in msecs. */ \ + uint64_t time; \ + /* Tail of a single-linked circular queue of pending reqs. If the queue */ \ + /* is empty, tail_ is NULL. If there is only one item, */ \ + /* tail_->next_req == tail_ */ \ + uv_req_t* pending_reqs_tail; \ + /* Head of a single-linked list of closed handles */ \ + uv_handle_t* endgame_handles; \ + /* TODO(bnoordhuis) Stop heap-allocating |timer_heap| in libuv v2.x. */ \ + void* timer_heap; \ + /* Lists of active loop (prepare / check / idle) watchers */ \ + uv_prepare_t* prepare_handles; \ + uv_check_t* check_handles; \ + uv_idle_t* idle_handles; \ + /* This pointer will refer to the prepare/check/idle handle whose */ \ + /* callback is scheduled to be called next. This is needed to allow */ \ + /* safe removal from one of the lists above while that list being */ \ + /* iterated over. */ \ + uv_prepare_t* next_prepare_handle; \ + uv_check_t* next_check_handle; \ + uv_idle_t* next_idle_handle; \ + /* This handle holds the peer sockets for the fast variant of uv_poll_t */ \ + SOCKET poll_peer_sockets[UV_MSAFD_PROVIDER_COUNT]; \ + /* Counter to keep track of active tcp streams */ \ + unsigned int active_tcp_streams; \ + /* Counter to keep track of active udp streams */ \ + unsigned int active_udp_streams; \ + /* Counter to started timer */ \ + uint64_t timer_counter; \ + /* Threadpool */ \ + void* wq[2]; \ + uv_mutex_t wq_mutex; \ + uv_async_t wq_async; + +#define UV_REQ_TYPE_PRIVATE \ + /* TODO: remove the req suffix */ \ + UV_ACCEPT, \ + UV_FS_EVENT_REQ, \ + UV_POLL_REQ, \ + UV_PROCESS_EXIT, \ + UV_READ, \ + UV_UDP_RECV, \ + UV_WAKEUP, \ + UV_SIGNAL_REQ, + +#define UV_REQ_PRIVATE_FIELDS \ + union { \ + /* Used by I/O operations */ \ + struct { \ + OVERLAPPED overlapped; \ + size_t queued_bytes; \ + } io; \ + } u; \ + struct uv_req_s* next_req; + +#define UV_WRITE_PRIVATE_FIELDS \ + int coalesced; \ + uv_buf_t write_buffer; \ + HANDLE event_handle; \ + HANDLE wait_handle; + +#define UV_CONNECT_PRIVATE_FIELDS \ + /* empty */ + +#define UV_SHUTDOWN_PRIVATE_FIELDS \ + /* empty */ + +#define UV_UDP_SEND_PRIVATE_FIELDS \ + /* empty */ + +#define UV_PRIVATE_REQ_TYPES \ + typedef struct uv_pipe_accept_s { \ + UV_REQ_FIELDS \ + HANDLE pipeHandle; \ + struct uv_pipe_accept_s* next_pending; \ + } uv_pipe_accept_t; \ + \ + typedef struct uv_tcp_accept_s { \ + UV_REQ_FIELDS \ + SOCKET accept_socket; \ + char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; \ + HANDLE event_handle; \ + HANDLE wait_handle; \ + struct uv_tcp_accept_s* next_pending; \ + } uv_tcp_accept_t; \ + \ + typedef struct uv_read_s { \ + UV_REQ_FIELDS \ + HANDLE event_handle; \ + HANDLE wait_handle; \ + } uv_read_t; + +#define uv_stream_connection_fields \ + unsigned int write_reqs_pending; \ + uv_shutdown_t* shutdown_req; + +#define uv_stream_server_fields \ + uv_connection_cb connection_cb; + +#define UV_STREAM_PRIVATE_FIELDS \ + unsigned int reqs_pending; \ + int activecnt; \ + uv_read_t read_req; \ + union { \ + struct { uv_stream_connection_fields } conn; \ + struct { uv_stream_server_fields } serv; \ + } stream; + +#define uv_tcp_server_fields \ + uv_tcp_accept_t* accept_reqs; \ + unsigned int processed_accepts; \ + uv_tcp_accept_t* pending_accepts; \ + LPFN_ACCEPTEX func_acceptex; + +#define uv_tcp_connection_fields \ + uv_buf_t read_buffer; \ + LPFN_CONNECTEX func_connectex; + +#define UV_TCP_PRIVATE_FIELDS \ + SOCKET socket; \ + int delayed_error; \ + union { \ + struct { uv_tcp_server_fields } serv; \ + struct { uv_tcp_connection_fields } conn; \ + } tcp; + +#define UV_UDP_PRIVATE_FIELDS \ + SOCKET socket; \ + unsigned int reqs_pending; \ + int activecnt; \ + uv_req_t recv_req; \ + uv_buf_t recv_buffer; \ + struct sockaddr_storage recv_from; \ + int recv_from_len; \ + uv_udp_recv_cb recv_cb; \ + uv_alloc_cb alloc_cb; \ + LPFN_WSARECV func_wsarecv; \ + LPFN_WSARECVFROM func_wsarecvfrom; + +#define uv_pipe_server_fields \ + int pending_instances; \ + uv_pipe_accept_t* accept_reqs; \ + uv_pipe_accept_t* pending_accepts; + +#define uv_pipe_connection_fields \ + uv_timer_t* eof_timer; \ + uv_write_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \ + DWORD ipc_remote_pid; \ + union { \ + uint32_t payload_remaining; \ + uint64_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \ + } ipc_data_frame; \ + void* ipc_xfer_queue[2]; \ + int ipc_xfer_queue_length; \ + uv_write_t* non_overlapped_writes_tail; \ + CRITICAL_SECTION readfile_thread_lock; \ + volatile HANDLE readfile_thread_handle; + +#define UV_PIPE_PRIVATE_FIELDS \ + HANDLE handle; \ + WCHAR* name; \ + union { \ + struct { uv_pipe_server_fields } serv; \ + struct { uv_pipe_connection_fields } conn; \ + } pipe; + +/* TODO: put the parser states in an union - TTY handles are always half-duplex + * so read-state can safely overlap write-state. */ +#define UV_TTY_PRIVATE_FIELDS \ + HANDLE handle; \ + union { \ + struct { \ + /* Used for readable TTY handles */ \ + /* TODO: remove me in v2.x. */ \ + HANDLE unused_; \ + uv_buf_t read_line_buffer; \ + HANDLE read_raw_wait; \ + /* Fields used for translating win keystrokes into vt100 characters */ \ + char last_key[8]; \ + unsigned char last_key_offset; \ + unsigned char last_key_len; \ + WCHAR last_utf16_high_surrogate; \ + INPUT_RECORD last_input_record; \ + } rd; \ + struct { \ + /* Used for writable TTY handles */ \ + /* utf8-to-utf16 conversion state */ \ + unsigned int utf8_codepoint; \ + unsigned char utf8_bytes_left; \ + /* eol conversion state */ \ + unsigned char previous_eol; \ + /* ansi parser state */ \ + unsigned short ansi_parser_state; \ + unsigned char ansi_csi_argc; \ + unsigned short ansi_csi_argv[4]; \ + COORD saved_position; \ + WORD saved_attributes; \ + } wr; \ + } tty; + +#define UV_POLL_PRIVATE_FIELDS \ + SOCKET socket; \ + /* Used in fast mode */ \ + SOCKET peer_socket; \ + AFD_POLL_INFO afd_poll_info_1; \ + AFD_POLL_INFO afd_poll_info_2; \ + /* Used in fast and slow mode. */ \ + uv_req_t poll_req_1; \ + uv_req_t poll_req_2; \ + unsigned char submitted_events_1; \ + unsigned char submitted_events_2; \ + unsigned char mask_events_1; \ + unsigned char mask_events_2; \ + unsigned char events; + +#define UV_TIMER_PRIVATE_FIELDS \ + void* heap_node[3]; \ + int unused; \ + uint64_t timeout; \ + uint64_t repeat; \ + uint64_t start_id; \ + uv_timer_cb timer_cb; + +#define UV_ASYNC_PRIVATE_FIELDS \ + struct uv_req_s async_req; \ + uv_async_cb async_cb; \ + /* char to avoid alignment issues */ \ + char volatile async_sent; + +#define UV_PREPARE_PRIVATE_FIELDS \ + uv_prepare_t* prepare_prev; \ + uv_prepare_t* prepare_next; \ + uv_prepare_cb prepare_cb; + +#define UV_CHECK_PRIVATE_FIELDS \ + uv_check_t* check_prev; \ + uv_check_t* check_next; \ + uv_check_cb check_cb; + +#define UV_IDLE_PRIVATE_FIELDS \ + uv_idle_t* idle_prev; \ + uv_idle_t* idle_next; \ + uv_idle_cb idle_cb; + +#define UV_HANDLE_PRIVATE_FIELDS \ + uv_handle_t* endgame_next; \ + unsigned int flags; + +#define UV_GETADDRINFO_PRIVATE_FIELDS \ + struct uv__work work_req; \ + uv_getaddrinfo_cb getaddrinfo_cb; \ + void* alloc; \ + WCHAR* node; \ + WCHAR* service; \ + /* The addrinfoW field is used to store a pointer to the hints, and */ \ + /* later on to store the result of GetAddrInfoW. The final result will */ \ + /* be converted to struct addrinfo* and stored in the addrinfo field. */ \ + struct addrinfoW* addrinfow; \ + struct addrinfo* addrinfo; \ + int retcode; + +#define UV_GETNAMEINFO_PRIVATE_FIELDS \ + struct uv__work work_req; \ + uv_getnameinfo_cb getnameinfo_cb; \ + struct sockaddr_storage storage; \ + int flags; \ + char host[NI_MAXHOST]; \ + char service[NI_MAXSERV]; \ + int retcode; + +#define UV_PROCESS_PRIVATE_FIELDS \ + struct uv_process_exit_s { \ + UV_REQ_FIELDS \ + } exit_req; \ + BYTE* child_stdio_buffer; \ + int exit_signal; \ + HANDLE wait_handle; \ + HANDLE process_handle; \ + volatile char exit_cb_pending; + +#define UV_FS_PRIVATE_FIELDS \ + struct uv__work work_req; \ + int flags; \ + DWORD sys_errno_; \ + union { \ + /* TODO: remove me in 0.9. */ \ + WCHAR* pathw; \ + int fd; \ + } file; \ + union { \ + struct { \ + int mode; \ + WCHAR* new_pathw; \ + int file_flags; \ + int fd_out; \ + unsigned int nbufs; \ + uv_buf_t* bufs; \ + int64_t offset; \ + uv_buf_t bufsml[4]; \ + } info; \ + struct { \ + double atime; \ + double mtime; \ + } time; \ + } fs; + +#define UV_WORK_PRIVATE_FIELDS \ + struct uv__work work_req; + +#define UV_FS_EVENT_PRIVATE_FIELDS \ + struct uv_fs_event_req_s { \ + UV_REQ_FIELDS \ + } req; \ + HANDLE dir_handle; \ + int req_pending; \ + uv_fs_event_cb cb; \ + WCHAR* filew; \ + WCHAR* short_filew; \ + WCHAR* dirw; \ + char* buffer; + +#define UV_SIGNAL_PRIVATE_FIELDS \ + RB_ENTRY(uv_signal_s) tree_entry; \ + struct uv_req_s signal_req; \ + unsigned long pending_signum; + +#ifndef F_OK +#define F_OK 0 +#endif +#ifndef R_OK +#define R_OK 4 +#endif +#ifndef W_OK +#define W_OK 2 +#endif +#ifndef X_OK +#define X_OK 1 +#endif + +/* fs open() flags supported on this platform: */ +#define UV_FS_O_APPEND _O_APPEND +#define UV_FS_O_CREAT _O_CREAT +#define UV_FS_O_EXCL _O_EXCL +#define UV_FS_O_FILEMAP 0x20000000 +#define UV_FS_O_RANDOM _O_RANDOM +#define UV_FS_O_RDONLY _O_RDONLY +#define UV_FS_O_RDWR _O_RDWR +#define UV_FS_O_SEQUENTIAL _O_SEQUENTIAL +#define UV_FS_O_SHORT_LIVED _O_SHORT_LIVED +#define UV_FS_O_TEMPORARY _O_TEMPORARY +#define UV_FS_O_TRUNC _O_TRUNC +#define UV_FS_O_WRONLY _O_WRONLY + +/* fs open() flags supported on other platforms (or mapped on this platform): */ +#define UV_FS_O_DIRECT 0x02000000 /* FILE_FLAG_NO_BUFFERING */ +#define UV_FS_O_DIRECTORY 0 +#define UV_FS_O_DSYNC 0x04000000 /* FILE_FLAG_WRITE_THROUGH */ +#define UV_FS_O_EXLOCK 0x10000000 /* EXCLUSIVE SHARING MODE */ +#define UV_FS_O_NOATIME 0 +#define UV_FS_O_NOCTTY 0 +#define UV_FS_O_NOFOLLOW 0 +#define UV_FS_O_NONBLOCK 0 +#define UV_FS_O_SYMLINK 0 +#define UV_FS_O_SYNC 0x08000000 /* FILE_FLAG_WRITE_THROUGH */ diff --git a/external/src/libuv/libuv-static.pc.in b/external/src/libuv/libuv-static.pc.in new file mode 100644 index 0000000..ea62548 --- /dev/null +++ b/external/src/libuv/libuv-static.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ + +Name: libuv-static +Version: @PACKAGE_VERSION@ +Description: multi-platform support library with a focus on asynchronous I/O. +URL: http://libuv.org/ + +Libs: -L${libdir} -luv_a @LIBS@ +Cflags: -I${includedir} diff --git a/external/src/libuv/libuv.pc.in b/external/src/libuv/libuv.pc.in new file mode 100644 index 0000000..1d7b86f --- /dev/null +++ b/external/src/libuv/libuv.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ + +Name: libuv +Version: @PACKAGE_VERSION@ +Description: multi-platform support library with a focus on asynchronous I/O. +URL: http://libuv.org/ + +Libs: -L${libdir} -luv @LIBS@ +Cflags: -I${includedir} diff --git a/external/src/libuv/m4/.gitignore b/external/src/libuv/m4/.gitignore new file mode 100644 index 0000000..bb91e50 --- /dev/null +++ b/external/src/libuv/m4/.gitignore @@ -0,0 +1,5 @@ +# Ignore libtoolize-generated files. +*.m4 +!as_case.m4 +!ax_pthread.m4 +!libuv-check-flags.m4 diff --git a/external/src/libuv/m4/as_case.m4 b/external/src/libuv/m4/as_case.m4 new file mode 100644 index 0000000..c7ae0f0 --- /dev/null +++ b/external/src/libuv/m4/as_case.m4 @@ -0,0 +1,21 @@ +# AS_CASE(WORD, [PATTERN1], [IF-MATCHED1]...[DEFAULT]) +# ---------------------------------------------------- +# Expand into +# | case WORD in +# | PATTERN1) IF-MATCHED1 ;; +# | ... +# | *) DEFAULT ;; +# | esac +m4_define([_AS_CASE], +[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])], + [$#], 1, [ *) $1 ;;], + [$#], 2, [ $1) m4_default([$2], [:]) ;;], + [ $1) m4_default([$2], [:]) ;; +$0(m4_shiftn(2, $@))])dnl +]) +m4_defun([AS_CASE], +[m4_ifval([$2$3], +[case $1 in +_AS_CASE(m4_shift($@)) +esac])]) + diff --git a/external/src/libuv/m4/ax_pthread.m4 b/external/src/libuv/m4/ax_pthread.m4 new file mode 100644 index 0000000..5fbf9fe --- /dev/null +++ b/external/src/libuv/m4/ax_pthread.m4 @@ -0,0 +1,485 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_pthread.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) +# +# DESCRIPTION +# +# This macro figures out how to build C programs using POSIX threads. It +# sets the PTHREAD_LIBS output variable to the threads library and linker +# flags, and the PTHREAD_CFLAGS output variable to any special C compiler +# flags that are needed. (The user can also force certain compiler +# flags/libs to be tested by setting these environment variables.) +# +# Also sets PTHREAD_CC to any special C compiler that is needed for +# multi-threaded programs (defaults to the value of CC otherwise). (This +# is necessary on AIX to use the special cc_r compiler alias.) +# +# NOTE: You are assumed to not only compile your program with these flags, +# but also to link with them as well. For example, you might link with +# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# +# If you are only building threaded programs, you may wish to use these +# variables in your default LIBS, CFLAGS, and CC: +# +# LIBS="$PTHREAD_LIBS $LIBS" +# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CC="$PTHREAD_CC" +# +# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to +# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# +# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the +# PTHREAD_PRIO_INHERIT symbol is defined when compiling with +# PTHREAD_CFLAGS. +# +# ACTION-IF-FOUND is a list of shell commands to run if a threads library +# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it +# is not found. If ACTION-IF-FOUND is not specified, the default action +# will define HAVE_PTHREAD. +# +# Please let the authors know if this macro fails on any platform, or if +# you have any other suggestions or comments. This macro was based on work +# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help +# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by +# Alejandro Forero Cuervo to the autoconf macro repository. We are also +# grateful for the helpful feedback of numerous users. +# +# Updated for Autoconf 2.68 by Daniel Richard G. +# +# LICENSE +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2011 Daniel Richard G. +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 24 + +AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) +AC_DEFUN([AX_PTHREAD], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_PROG_SED]) +AC_LANG_PUSH([C]) +ax_pthread_ok=no + +# We used to check for pthread.h first, but this fails if pthread.h +# requires special compiler flags (e.g. on Tru64 or Sequent). +# It gets checked for in the link test anyway. + +# First of all, check if the user has set any of the PTHREAD_LIBS, +# etcetera environment variables, and if threads linking works using +# them: +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) + AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = "xno"; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" +fi + +# We must check for the threads library under a number of different +# names; the ordering is very important because some systems +# (e.g. DEC) have both -lpthread and -lpthreads, where one of the +# libraries is broken (non-POSIX). + +# Create a list of thread flags to try. Items starting with a "-" are +# C compiler flags, and other items are library names, except for "none" +# which indicates that we try without any flags at all, and "pthread-config" +# which is a program returning the flags for the Pth emulation library. + +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + +# The ordering *is* (sometimes) important. Some notes on the +# individual items follow: + +# pthreads: AIX (must check this before -lpthread) +# none: in case threads are in libc; should be tried before -Kthread and +# other compiler flags to prevent continual compiler warnings +# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) +# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +# doesn't hurt to check since this sometimes defines pthreads and +# -D_REENTRANT too), HP C (must be checked before -lpthread, which +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") +# -mthreads: Mingw32/gcc, Lynx/gcc +# pthread: Linux, etcetera +# --thread-safe: KAI C++ +# pthread-config: use pthread-config program (for GNU Pth library) + +case $host_os in + + freebsd*) + + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + + hpux*) + + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." + + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; + + openedition*) + + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) + + AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], + [ +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + ], + [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) + ;; + + solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). + + ax_pthread_flags="-mt,pthread pthread $ax_pthread_flags" + ;; +esac + +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) + +AS_IF([test "x$GCC" = "xyes"], + [ax_pthread_flags="-pthread -pthreads $ax_pthread_flags"]) + +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled + +case $host_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; + + aix*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; + + *) + ax_pthread_check_macro="--" + ;; +esac +AS_IF([test "x$ax_pthread_check_macro" = "x--"], + [ax_pthread_check_cond=0], + [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) + +# Are we compiling with Clang? + +AC_CACHE_CHECK([whether $CC is Clang], + [ax_cv_PTHREAD_CLANG], + [ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) + fi + ]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + +ax_pthread_clang_warning=no + +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way + +if test "x$ax_pthread_clang" = "xyes"; then + + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + PTHREAD_CFLAGS="-pthread" + PTHREAD_LIBS= + + ax_pthread_ok=yes + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`$as_echo "$ac_link" | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac + +fi # $ax_pthread_clang = yes + +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do + + case $ax_pthread_try_flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + + -mt,pthread) + AC_MSG_CHECKING([whether pthreads work with -mt -lpthread]) + PTHREAD_CFLAGS="-mt" + PTHREAD_LIBS="-lpthread" + ;; + + -*) + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we + # need a special flag -Kthread to make this header compile.) + # We check for pthread_join because it is in -lpthread on IRIX + # while pthread_create is in libc. We check for pthread_attr_init + # due to DEC craziness with -lpthreads. We check for + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. + + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void routine(void *a) { a = 0; } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); + pthread_join(th, 0); + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], + [ax_pthread_ok=yes], + []) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + AC_MSG_RESULT([$ax_pthread_ok]) + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" +done +fi + +# Various other checks: +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. + AC_CACHE_CHECK([for joinable pthread attribute], + [ax_cv_PTHREAD_JOINABLE_ATTR], + [ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], + []) + done + ]) + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], + [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], + [$ax_cv_PTHREAD_JOINABLE_ATTR], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) + + AC_CACHE_CHECK([whether more special flags are required for pthreads], + [ax_cv_PTHREAD_SPECIAL_FLAGS], + [ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + ]) + AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"], + [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes]) + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], + [ax_cv_PTHREAD_PRIO_INHERIT], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[int i = PTHREAD_PRIO_INHERIT;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) + + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" + + # More AIX lossage: compile with *_r variant + if test "x$GCC" != "xyes"; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], + [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) + ;; + esac + fi +fi + +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" + +AC_SUBST([PTHREAD_LIBS]) +AC_SUBST([PTHREAD_CFLAGS]) +AC_SUBST([PTHREAD_CC]) + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +if test "x$ax_pthread_ok" = "xyes"; then + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : +else + ax_pthread_ok=no + $2 +fi +AC_LANG_POP +])dnl AX_PTHREAD diff --git a/external/src/libuv/m4/libuv-check-flags.m4 b/external/src/libuv/m4/libuv-check-flags.m4 new file mode 100644 index 0000000..e347056 --- /dev/null +++ b/external/src/libuv/m4/libuv-check-flags.m4 @@ -0,0 +1,319 @@ +dnl Macros to check the presence of generic (non-typed) symbols. +dnl Copyright (c) 2006-2008 Diego Pettenò +dnl Copyright (c) 2006-2008 xine project +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +dnl 02110-1301, USA. +dnl +dnl As a special exception, the copyright owners of the +dnl macro gives unlimited permission to copy, distribute and modify the +dnl configure scripts that are the output of Autoconf when processing the +dnl Macro. You need not follow the terms of the GNU General Public +dnl License when using or distributing such scripts, even though portions +dnl of the text of the Macro appear in them. The GNU General Public +dnl License (GPL) does govern all other use of the material that +dnl constitutes the Autoconf Macro. +dnl +dnl This special exception to the GPL applies to versions of the +dnl Autoconf Macro released by this project. When you make and +dnl distribute a modified version of the Autoconf Macro, you may extend +dnl this special exception to the GPL to apply to your modified version as +dnl well. + +dnl Check if the flag is supported by compiler +dnl CC_CHECK_CFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) + +AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [ + AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]), + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $1" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a;])], + [eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_cflags_$1])='no'"]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], + [$2], [$3]) +]) + +dnl Check if the flag is supported by compiler (cacheable) +dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) + +AC_DEFUN([CC_CHECK_CFLAGS], [ + AC_CACHE_CHECK([if $CC supports $1 flag], + AS_TR_SH([cc_cv_cflags_$1]), + CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! + ) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], + [$2], [$3]) +]) + +dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found]) +dnl Check for CFLAG and appends them to CFLAGS if supported +AC_DEFUN([CC_CHECK_CFLAG_APPEND], [ + AC_CACHE_CHECK([if $CC supports $1 flag], + AS_TR_SH([cc_cv_cflags_$1]), + CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! + ) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], + [CFLAGS="$CFLAGS $1"; DEBUG_CFLAGS="$DEBUG_CFLAGS $1"; $2], [$3]) +]) + +dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not]) +AC_DEFUN([CC_CHECK_CFLAGS_APPEND], [ + for flag in $1; do + CC_CHECK_CFLAG_APPEND($flag, [$2], [$3]) + done +]) + +dnl Check if the flag is supported by linker (cacheable) +dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) + +AC_DEFUN([CC_CHECK_LDFLAGS], [ + AC_CACHE_CHECK([if $CC supports $1 flag], + AS_TR_SH([cc_cv_ldflags_$1]), + [ac_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $1" + AC_LANG_PUSH([C]) + AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 1; }])], + [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_ldflags_$1])="]) + AC_LANG_POP([C]) + LDFLAGS="$ac_save_LDFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes], + [$2], [$3]) +]) + +dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for +dnl the current linker to avoid undefined references in a shared object. +AC_DEFUN([CC_NOUNDEFINED], [ + dnl We check $host for which systems to enable this for. + AC_REQUIRE([AC_CANONICAL_HOST]) + + case $host in + dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads + dnl are requested, as different implementations are present; to avoid problems + dnl use -Wl,-z,defs only for those platform not behaving this way. + *-freebsd* | *-openbsd*) ;; + *) + dnl First of all check for the --no-undefined variant of GNU ld. This allows + dnl for a much more readable commandline, so that people can understand what + dnl it does without going to look for what the heck -z defs does. + for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do + CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"]) + break + done + ;; + esac + + AC_SUBST([LDFLAGS_NOUNDEFINED]) +]) + +dnl Check for a -Werror flag or equivalent. -Werror is the GCC +dnl and ICC flag that tells the compiler to treat all the warnings +dnl as fatal. We usually need this option to make sure that some +dnl constructs (like attributes) are not simply ignored. +dnl +dnl Other compilers don't support -Werror per se, but they support +dnl an equivalent flag: +dnl - Sun Studio compiler supports -errwarn=%all +AC_DEFUN([CC_CHECK_WERROR], [ + AC_CACHE_CHECK( + [for $CC way to treat warnings as errors], + [cc_cv_werror], + [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror], + [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])]) + ]) +]) + +AC_DEFUN([CC_CHECK_ATTRIBUTE], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))], + AS_TR_SH([cc_cv_attribute_$1]), + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + AC_LANG_PUSH([C]) + AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])], + [eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"], + [eval "AS_TR_SH([cc_cv_attribute_$1])='no'"]) + AC_LANG_POP([C]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes], + [AC_DEFINE( + AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1, + [Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))] + ) + $4], + [$5]) +]) + +AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [ + CC_CHECK_ATTRIBUTE( + [constructor],, + [void __attribute__((constructor)) ctor() { int a; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_FORMAT], [ + CC_CHECK_ATTRIBUTE( + [format], [format(printf, n, n)], + [void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [ + CC_CHECK_ATTRIBUTE( + [format_arg], [format_arg(printf)], + [char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [ + CC_CHECK_ATTRIBUTE( + [visibility_$1], [visibility("$1")], + [void __attribute__((visibility("$1"))) $1_function() { }], + [$2], [$3]) +]) + +AC_DEFUN([CC_ATTRIBUTE_NONNULL], [ + CC_CHECK_ATTRIBUTE( + [nonnull], [nonnull()], + [void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_UNUSED], [ + CC_CHECK_ATTRIBUTE( + [unused], , + [void some_function(void *foo, __attribute__((unused)) void *bar);], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [ + CC_CHECK_ATTRIBUTE( + [sentinel], , + [void some_function(void *foo, ...) __attribute__((sentinel));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [ + CC_CHECK_ATTRIBUTE( + [deprecated], , + [void some_function(void *foo, ...) __attribute__((deprecated));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_ALIAS], [ + CC_CHECK_ATTRIBUTE( + [alias], [weak, alias], + [void other_function(void *foo) { } + void some_function(void *foo) __attribute__((weak, alias("other_function")));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_MALLOC], [ + CC_CHECK_ATTRIBUTE( + [malloc], , + [void * __attribute__((malloc)) my_alloc(int n);], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_PACKED], [ + CC_CHECK_ATTRIBUTE( + [packed], , + [struct astructure { char a; int b; long c; void *d; } __attribute__((packed));], + [$1], [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_CONST], [ + CC_CHECK_ATTRIBUTE( + [const], , + [int __attribute__((const)) twopow(int n) { return 1 << n; } ], + [$1], [$2]) +]) + +AC_DEFUN([CC_FLAG_VISIBILITY], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if $CC supports -fvisibility=hidden], + [cc_cv_flag_visibility], + [cc_flag_visibility_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden], + cc_cv_flag_visibility='yes', + cc_cv_flag_visibility='no') + CFLAGS="$cc_flag_visibility_save_CFLAGS"]) + + AS_IF([test "x$cc_cv_flag_visibility" = "xyes"], + [AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1, + [Define this if the compiler supports the -fvisibility flag]) + $1], + [$2]) +]) + +AC_DEFUN([CC_FUNC_EXPECT], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([if compiler has __builtin_expect function], + [cc_cv_func_expect], + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + AC_LANG_PUSH([C]) + AC_COMPILE_IFELSE([AC_LANG_SOURCE( + [int some_function() { + int a = 3; + return (int)__builtin_expect(a, 3); + }])], + [cc_cv_func_expect=yes], + [cc_cv_func_expect=no]) + AC_LANG_POP([C]) + CFLAGS="$ac_save_CFLAGS" + ]) + + AS_IF([test "x$cc_cv_func_expect" = "xyes"], + [AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1, + [Define this if the compiler supports __builtin_expect() function]) + $1], + [$2]) +]) + +AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [ + AC_REQUIRE([CC_CHECK_WERROR]) + AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported], + [cc_cv_attribute_aligned], + [ac_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $cc_cv_werror" + AC_LANG_PUSH([C]) + for cc_attribute_align_try in 64 32 16 8 4 2; do + AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + int main() { + static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0; + return c; + }])], [cc_cv_attribute_aligned=$cc_attribute_align_try; break]) + done + AC_LANG_POP([C]) + CFLAGS="$ac_save_CFLAGS" + ]) + + if test "x$cc_cv_attribute_aligned" != "x"; then + AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned], + [Define the highest alignment supported]) + fi +]) diff --git a/external/src/libuv/src/fs-poll.c b/external/src/libuv/src/fs-poll.c new file mode 100644 index 0000000..89864e2 --- /dev/null +++ b/external/src/libuv/src/fs-poll.c @@ -0,0 +1,287 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "uv-common.h" + +#ifdef _WIN32 +#include "win/internal.h" +#include "win/handle-inl.h" +#define uv__make_close_pending(h) uv_want_endgame((h)->loop, (h)) +#else +#include "unix/internal.h" +#endif + +#include +#include +#include + +struct poll_ctx { + uv_fs_poll_t* parent_handle; + int busy_polling; + unsigned int interval; + uint64_t start_time; + uv_loop_t* loop; + uv_fs_poll_cb poll_cb; + uv_timer_t timer_handle; + uv_fs_t fs_req; /* TODO(bnoordhuis) mark fs_req internal */ + uv_stat_t statbuf; + struct poll_ctx* previous; /* context from previous start()..stop() period */ + char path[1]; /* variable length */ +}; + +static int statbuf_eq(const uv_stat_t* a, const uv_stat_t* b); +static void poll_cb(uv_fs_t* req); +static void timer_cb(uv_timer_t* timer); +static void timer_close_cb(uv_handle_t* handle); + +static uv_stat_t zero_statbuf; + + +int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle) { + uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_POLL); + handle->poll_ctx = NULL; + return 0; +} + + +int uv_fs_poll_start(uv_fs_poll_t* handle, + uv_fs_poll_cb cb, + const char* path, + unsigned int interval) { + struct poll_ctx* ctx; + uv_loop_t* loop; + size_t len; + int err; + + if (uv_is_active((uv_handle_t*)handle)) + return 0; + + loop = handle->loop; + len = strlen(path); + ctx = uv__calloc(1, sizeof(*ctx) + len); + + if (ctx == NULL) + return UV_ENOMEM; + + ctx->loop = loop; + ctx->poll_cb = cb; + ctx->interval = interval ? interval : 1; + ctx->start_time = uv_now(loop); + ctx->parent_handle = handle; + memcpy(ctx->path, path, len + 1); + + err = uv_timer_init(loop, &ctx->timer_handle); + if (err < 0) + goto error; + + ctx->timer_handle.flags |= UV_HANDLE_INTERNAL; + uv__handle_unref(&ctx->timer_handle); + + err = uv_fs_stat(loop, &ctx->fs_req, ctx->path, poll_cb); + if (err < 0) + goto error; + + if (handle->poll_ctx != NULL) + ctx->previous = handle->poll_ctx; + handle->poll_ctx = ctx; + uv__handle_start(handle); + + return 0; + +error: + uv__free(ctx); + return err; +} + + +int uv_fs_poll_stop(uv_fs_poll_t* handle) { + struct poll_ctx* ctx; + + if (!uv_is_active((uv_handle_t*)handle)) + return 0; + + ctx = handle->poll_ctx; + assert(ctx != NULL); + assert(ctx->parent_handle == handle); + + /* Close the timer if it's active. If it's inactive, there's a stat request + * in progress and poll_cb will take care of the cleanup. + */ + if (uv_is_active((uv_handle_t*)&ctx->timer_handle)) + uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb); + + uv__handle_stop(handle); + + return 0; +} + + +int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buffer, size_t* size) { + struct poll_ctx* ctx; + size_t required_len; + + if (!uv_is_active((uv_handle_t*)handle)) { + *size = 0; + return UV_EINVAL; + } + + ctx = handle->poll_ctx; + assert(ctx != NULL); + + required_len = strlen(ctx->path); + if (required_len >= *size) { + *size = required_len + 1; + return UV_ENOBUFS; + } + + memcpy(buffer, ctx->path, required_len); + *size = required_len; + buffer[required_len] = '\0'; + + return 0; +} + + +void uv__fs_poll_close(uv_fs_poll_t* handle) { + uv_fs_poll_stop(handle); + + if (handle->poll_ctx == NULL) + uv__make_close_pending((uv_handle_t*)handle); +} + + +static void timer_cb(uv_timer_t* timer) { + struct poll_ctx* ctx; + + ctx = container_of(timer, struct poll_ctx, timer_handle); + assert(ctx->parent_handle != NULL); + assert(ctx->parent_handle->poll_ctx == ctx); + ctx->start_time = uv_now(ctx->loop); + + if (uv_fs_stat(ctx->loop, &ctx->fs_req, ctx->path, poll_cb)) + abort(); +} + + +static void poll_cb(uv_fs_t* req) { + uv_stat_t* statbuf; + struct poll_ctx* ctx; + uint64_t interval; + uv_fs_poll_t* handle; + + ctx = container_of(req, struct poll_ctx, fs_req); + handle = ctx->parent_handle; + + if (!uv_is_active((uv_handle_t*)handle) || uv__is_closing(handle)) + goto out; + + if (req->result != 0) { + if (ctx->busy_polling != req->result) { + ctx->poll_cb(ctx->parent_handle, + req->result, + &ctx->statbuf, + &zero_statbuf); + ctx->busy_polling = req->result; + } + goto out; + } + + statbuf = &req->statbuf; + + if (ctx->busy_polling != 0) + if (ctx->busy_polling < 0 || !statbuf_eq(&ctx->statbuf, statbuf)) + ctx->poll_cb(ctx->parent_handle, 0, &ctx->statbuf, statbuf); + + ctx->statbuf = *statbuf; + ctx->busy_polling = 1; + +out: + uv_fs_req_cleanup(req); + + if (!uv_is_active((uv_handle_t*)handle) || uv__is_closing(handle)) { + uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb); + return; + } + + /* Reschedule timer, subtract the delay from doing the stat(). */ + interval = ctx->interval; + interval -= (uv_now(ctx->loop) - ctx->start_time) % interval; + + if (uv_timer_start(&ctx->timer_handle, timer_cb, interval, 0)) + abort(); +} + + +static void timer_close_cb(uv_handle_t* timer) { + struct poll_ctx* ctx; + struct poll_ctx* it; + struct poll_ctx* last; + uv_fs_poll_t* handle; + + ctx = container_of(timer, struct poll_ctx, timer_handle); + handle = ctx->parent_handle; + if (ctx == handle->poll_ctx) { + handle->poll_ctx = ctx->previous; + if (handle->poll_ctx == NULL && uv__is_closing(handle)) + uv__make_close_pending((uv_handle_t*)handle); + } else { + for (last = handle->poll_ctx, it = last->previous; + it != ctx; + last = it, it = it->previous) { + assert(last->previous != NULL); + } + last->previous = ctx->previous; + } + uv__free(ctx); +} + + +static int statbuf_eq(const uv_stat_t* a, const uv_stat_t* b) { + return a->st_ctim.tv_nsec == b->st_ctim.tv_nsec + && a->st_mtim.tv_nsec == b->st_mtim.tv_nsec + && a->st_birthtim.tv_nsec == b->st_birthtim.tv_nsec + && a->st_ctim.tv_sec == b->st_ctim.tv_sec + && a->st_mtim.tv_sec == b->st_mtim.tv_sec + && a->st_birthtim.tv_sec == b->st_birthtim.tv_sec + && a->st_size == b->st_size + && a->st_mode == b->st_mode + && a->st_uid == b->st_uid + && a->st_gid == b->st_gid + && a->st_ino == b->st_ino + && a->st_dev == b->st_dev + && a->st_flags == b->st_flags + && a->st_gen == b->st_gen; +} + + +#if defined(_WIN32) + +#include "win/internal.h" +#include "win/handle-inl.h" + +void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle) { + assert(handle->flags & UV_HANDLE_CLOSING); + assert(!(handle->flags & UV_HANDLE_CLOSED)); + uv__handle_close(handle); +} + +#endif /* _WIN32 */ diff --git a/external/src/libuv/src/heap-inl.h b/external/src/libuv/src/heap-inl.h new file mode 100644 index 0000000..1e2ed60 --- /dev/null +++ b/external/src/libuv/src/heap-inl.h @@ -0,0 +1,245 @@ +/* Copyright (c) 2013, Ben Noordhuis + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef UV_SRC_HEAP_H_ +#define UV_SRC_HEAP_H_ + +#include /* NULL */ + +#if defined(__GNUC__) +# define HEAP_EXPORT(declaration) __attribute__((unused)) static declaration +#else +# define HEAP_EXPORT(declaration) static declaration +#endif + +struct heap_node { + struct heap_node* left; + struct heap_node* right; + struct heap_node* parent; +}; + +/* A binary min heap. The usual properties hold: the root is the lowest + * element in the set, the height of the tree is at most log2(nodes) and + * it's always a complete binary tree. + * + * The heap function try hard to detect corrupted tree nodes at the cost + * of a minor reduction in performance. Compile with -DNDEBUG to disable. + */ +struct heap { + struct heap_node* min; + unsigned int nelts; +}; + +/* Return non-zero if a < b. */ +typedef int (*heap_compare_fn)(const struct heap_node* a, + const struct heap_node* b); + +/* Public functions. */ +HEAP_EXPORT(void heap_init(struct heap* heap)); +HEAP_EXPORT(struct heap_node* heap_min(const struct heap* heap)); +HEAP_EXPORT(void heap_insert(struct heap* heap, + struct heap_node* newnode, + heap_compare_fn less_than)); +HEAP_EXPORT(void heap_remove(struct heap* heap, + struct heap_node* node, + heap_compare_fn less_than)); +HEAP_EXPORT(void heap_dequeue(struct heap* heap, heap_compare_fn less_than)); + +/* Implementation follows. */ + +HEAP_EXPORT(void heap_init(struct heap* heap)) { + heap->min = NULL; + heap->nelts = 0; +} + +HEAP_EXPORT(struct heap_node* heap_min(const struct heap* heap)) { + return heap->min; +} + +/* Swap parent with child. Child moves closer to the root, parent moves away. */ +static void heap_node_swap(struct heap* heap, + struct heap_node* parent, + struct heap_node* child) { + struct heap_node* sibling; + struct heap_node t; + + t = *parent; + *parent = *child; + *child = t; + + parent->parent = child; + if (child->left == child) { + child->left = parent; + sibling = child->right; + } else { + child->right = parent; + sibling = child->left; + } + if (sibling != NULL) + sibling->parent = child; + + if (parent->left != NULL) + parent->left->parent = parent; + if (parent->right != NULL) + parent->right->parent = parent; + + if (child->parent == NULL) + heap->min = child; + else if (child->parent->left == parent) + child->parent->left = child; + else + child->parent->right = child; +} + +HEAP_EXPORT(void heap_insert(struct heap* heap, + struct heap_node* newnode, + heap_compare_fn less_than)) { + struct heap_node** parent; + struct heap_node** child; + unsigned int path; + unsigned int n; + unsigned int k; + + newnode->left = NULL; + newnode->right = NULL; + newnode->parent = NULL; + + /* Calculate the path from the root to the insertion point. This is a min + * heap so we always insert at the left-most free node of the bottom row. + */ + path = 0; + for (k = 0, n = 1 + heap->nelts; n >= 2; k += 1, n /= 2) + path = (path << 1) | (n & 1); + + /* Now traverse the heap using the path we calculated in the previous step. */ + parent = child = &heap->min; + while (k > 0) { + parent = child; + if (path & 1) + child = &(*child)->right; + else + child = &(*child)->left; + path >>= 1; + k -= 1; + } + + /* Insert the new node. */ + newnode->parent = *parent; + *child = newnode; + heap->nelts += 1; + + /* Walk up the tree and check at each node if the heap property holds. + * It's a min heap so parent < child must be true. + */ + while (newnode->parent != NULL && less_than(newnode, newnode->parent)) + heap_node_swap(heap, newnode->parent, newnode); +} + +HEAP_EXPORT(void heap_remove(struct heap* heap, + struct heap_node* node, + heap_compare_fn less_than)) { + struct heap_node* smallest; + struct heap_node** max; + struct heap_node* child; + unsigned int path; + unsigned int k; + unsigned int n; + + if (heap->nelts == 0) + return; + + /* Calculate the path from the min (the root) to the max, the left-most node + * of the bottom row. + */ + path = 0; + for (k = 0, n = heap->nelts; n >= 2; k += 1, n /= 2) + path = (path << 1) | (n & 1); + + /* Now traverse the heap using the path we calculated in the previous step. */ + max = &heap->min; + while (k > 0) { + if (path & 1) + max = &(*max)->right; + else + max = &(*max)->left; + path >>= 1; + k -= 1; + } + + heap->nelts -= 1; + + /* Unlink the max node. */ + child = *max; + *max = NULL; + + if (child == node) { + /* We're removing either the max or the last node in the tree. */ + if (child == heap->min) { + heap->min = NULL; + } + return; + } + + /* Replace the to be deleted node with the max node. */ + child->left = node->left; + child->right = node->right; + child->parent = node->parent; + + if (child->left != NULL) { + child->left->parent = child; + } + + if (child->right != NULL) { + child->right->parent = child; + } + + if (node->parent == NULL) { + heap->min = child; + } else if (node->parent->left == node) { + node->parent->left = child; + } else { + node->parent->right = child; + } + + /* Walk down the subtree and check at each node if the heap property holds. + * It's a min heap so parent < child must be true. If the parent is bigger, + * swap it with the smallest child. + */ + for (;;) { + smallest = child; + if (child->left != NULL && less_than(child->left, smallest)) + smallest = child->left; + if (child->right != NULL && less_than(child->right, smallest)) + smallest = child->right; + if (smallest == child) + break; + heap_node_swap(heap, child, smallest); + } + + /* Walk up the subtree and check that each parent is less than the node + * this is required, because `max` node is not guaranteed to be the + * actual maximum in tree + */ + while (child->parent != NULL && less_than(child, child->parent)) + heap_node_swap(heap, child->parent, child); +} + +HEAP_EXPORT(void heap_dequeue(struct heap* heap, heap_compare_fn less_than)) { + heap_remove(heap, heap->min, less_than); +} + +#undef HEAP_EXPORT + +#endif /* UV_SRC_HEAP_H_ */ diff --git a/external/src/libuv/src/idna.c b/external/src/libuv/src/idna.c new file mode 100644 index 0000000..b44cb16 --- /dev/null +++ b/external/src/libuv/src/idna.c @@ -0,0 +1,314 @@ +/* Copyright (c) 2011, 2018 Ben Noordhuis + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* Derived from https://github.com/bnoordhuis/punycode + * but updated to support IDNA 2008. + */ + +#include "uv.h" +#include "idna.h" +#include +#include + +static unsigned uv__utf8_decode1_slow(const char** p, + const char* pe, + unsigned a) { + unsigned b; + unsigned c; + unsigned d; + unsigned min; + + if (a > 0xF7) + return -1; + + switch (pe - *p) { + default: + if (a > 0xEF) { + min = 0x10000; + a = a & 7; + b = (unsigned char) *(*p)++; + c = (unsigned char) *(*p)++; + d = (unsigned char) *(*p)++; + break; + } + /* Fall through. */ + case 2: + if (a > 0xDF) { + min = 0x800; + b = 0x80 | (a & 15); + c = (unsigned char) *(*p)++; + d = (unsigned char) *(*p)++; + a = 0; + break; + } + /* Fall through. */ + case 1: + if (a > 0xBF) { + min = 0x80; + b = 0x80; + c = 0x80 | (a & 31); + d = (unsigned char) *(*p)++; + a = 0; + break; + } + /* Fall through. */ + case 0: + return -1; /* Invalid continuation byte. */ + } + + if (0x80 != (0xC0 & (b ^ c ^ d))) + return -1; /* Invalid sequence. */ + + b &= 63; + c &= 63; + d &= 63; + a = (a << 18) | (b << 12) | (c << 6) | d; + + if (a < min) + return -1; /* Overlong sequence. */ + + if (a > 0x10FFFF) + return -1; /* Four-byte sequence > U+10FFFF. */ + + if (a >= 0xD800 && a <= 0xDFFF) + return -1; /* Surrogate pair. */ + + return a; +} + +unsigned uv__utf8_decode1(const char** p, const char* pe) { + unsigned a; + + assert(*p < pe); + + a = (unsigned char) *(*p)++; + + if (a < 128) + return a; /* ASCII, common case. */ + + return uv__utf8_decode1_slow(p, pe, a); +} + +static int uv__idna_toascii_label(const char* s, const char* se, + char** d, char* de) { + static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz0123456789"; + const char* ss; + unsigned c; + unsigned h; + unsigned k; + unsigned n; + unsigned m; + unsigned q; + unsigned t; + unsigned x; + unsigned y; + unsigned bias; + unsigned delta; + unsigned todo; + int first; + + h = 0; + ss = s; + todo = 0; + + /* Note: after this loop we've visited all UTF-8 characters and know + * they're legal so we no longer need to check for decode errors. + */ + while (s < se) { + c = uv__utf8_decode1(&s, se); + + if (c == -1u) + return UV_EINVAL; + + if (c < 128) + h++; + else + todo++; + } + + /* Only write "xn--" when there are non-ASCII characters. */ + if (todo > 0) { + if (*d < de) *(*d)++ = 'x'; + if (*d < de) *(*d)++ = 'n'; + if (*d < de) *(*d)++ = '-'; + if (*d < de) *(*d)++ = '-'; + } + + /* Write ASCII characters. */ + x = 0; + s = ss; + while (s < se) { + c = uv__utf8_decode1(&s, se); + assert(c != -1u); + + if (c > 127) + continue; + + if (*d < de) + *(*d)++ = c; + + if (++x == h) + break; /* Visited all ASCII characters. */ + } + + if (todo == 0) + return h; + + /* Only write separator when we've written ASCII characters first. */ + if (h > 0) + if (*d < de) + *(*d)++ = '-'; + + n = 128; + bias = 72; + delta = 0; + first = 1; + + while (todo > 0) { + m = -1; + s = ss; + + while (s < se) { + c = uv__utf8_decode1(&s, se); + assert(c != -1u); + + if (c >= n) + if (c < m) + m = c; + } + + x = m - n; + y = h + 1; + + if (x > ~delta / y) + return UV_E2BIG; /* Overflow. */ + + delta += x * y; + n = m; + + s = ss; + while (s < se) { + c = uv__utf8_decode1(&s, se); + assert(c != -1u); + + if (c < n) + if (++delta == 0) + return UV_E2BIG; /* Overflow. */ + + if (c != n) + continue; + + for (k = 36, q = delta; /* empty */; k += 36) { + t = 1; + + if (k > bias) + t = k - bias; + + if (t > 26) + t = 26; + + if (q < t) + break; + + /* TODO(bnoordhuis) Since 1 <= t <= 26 and therefore + * 10 <= y <= 35, we can optimize the long division + * into a table-based reciprocal multiplication. + */ + x = q - t; + y = 36 - t; /* 10 <= y <= 35 since 1 <= t <= 26. */ + q = x / y; + t = t + x % y; /* 1 <= t <= 35 because of y. */ + + if (*d < de) + *(*d)++ = alphabet[t]; + } + + if (*d < de) + *(*d)++ = alphabet[q]; + + delta /= 2; + + if (first) { + delta /= 350; + first = 0; + } + + /* No overflow check is needed because |delta| was just + * divided by 2 and |delta+delta >= delta + delta/h|. + */ + h++; + delta += delta / h; + + for (bias = 0; delta > 35 * 26 / 2; bias += 36) + delta /= 35; + + bias += 36 * delta / (delta + 38); + delta = 0; + todo--; + } + + delta++; + n++; + } + + return 0; +} + +long uv__idna_toascii(const char* s, const char* se, char* d, char* de) { + const char* si; + const char* st; + unsigned c; + char* ds; + int rc; + + ds = d; + + si = s; + while (si < se) { + st = si; + c = uv__utf8_decode1(&si, se); + + if (c == -1u) + return UV_EINVAL; + + if (c != '.') + if (c != 0x3002) /* 。 */ + if (c != 0xFF0E) /* . */ + if (c != 0xFF61) /* 。 */ + continue; + + rc = uv__idna_toascii_label(s, st, &d, de); + + if (rc < 0) + return rc; + + if (d < de) + *d++ = '.'; + + s = si; + } + + if (s < se) { + rc = uv__idna_toascii_label(s, se, &d, de); + + if (rc < 0) + return rc; + } + + if (d < de) + *d++ = '\0'; + + return d - ds; /* Number of bytes written. */ +} diff --git a/external/src/libuv/src/idna.h b/external/src/libuv/src/idna.h new file mode 100644 index 0000000..8e0c592 --- /dev/null +++ b/external/src/libuv/src/idna.h @@ -0,0 +1,31 @@ +/* Copyright (c) 2011, 2018 Ben Noordhuis + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef UV_SRC_IDNA_H_ +#define UV_SRC_IDNA_H_ + +/* Decode a single codepoint. Returns the codepoint or UINT32_MAX on error. + * |p| is updated on success _and_ error, i.e., bad multi-byte sequences are + * skipped in their entirety, not just the first bad byte. + */ +unsigned uv__utf8_decode1(const char** p, const char* pe); + +/* Convert a UTF-8 domain name to IDNA 2008 / Punycode. A return value >= 0 + * is the number of bytes written to |d|, including the trailing nul byte. + * A return value < 0 is a libuv error code. |s| and |d| can not overlap. + */ +long uv__idna_toascii(const char* s, const char* se, char* d, char* de); + +#endif /* UV_SRC_IDNA_H_ */ diff --git a/external/src/libuv/src/inet.c b/external/src/libuv/src/inet.c new file mode 100644 index 0000000..ddabf22 --- /dev/null +++ b/external/src/libuv/src/inet.c @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996-1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "uv/stdint-msvc2008.h" +#else +# include +#endif + +#include "uv.h" +#include "uv-common.h" + +#define UV__INET_ADDRSTRLEN 16 +#define UV__INET6_ADDRSTRLEN 46 + + +static int inet_ntop4(const unsigned char *src, char *dst, size_t size); +static int inet_ntop6(const unsigned char *src, char *dst, size_t size); +static int inet_pton4(const char *src, unsigned char *dst); +static int inet_pton6(const char *src, unsigned char *dst); + + +int uv_inet_ntop(int af, const void* src, char* dst, size_t size) { + switch (af) { + case AF_INET: + return (inet_ntop4(src, dst, size)); + case AF_INET6: + return (inet_ntop6(src, dst, size)); + default: + return UV_EAFNOSUPPORT; + } + /* NOTREACHED */ +} + + +static int inet_ntop4(const unsigned char *src, char *dst, size_t size) { + static const char fmt[] = "%u.%u.%u.%u"; + char tmp[UV__INET_ADDRSTRLEN]; + int l; + + l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); + if (l <= 0 || (size_t) l >= size) { + return UV_ENOSPC; + } + uv__strscpy(dst, tmp, size); + return 0; +} + + +static int inet_ntop6(const unsigned char *src, char *dst, size_t size) { + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[UV__INET6_ADDRSTRLEN], *tp; + struct { int base, len; } best, cur; + unsigned int words[sizeof(struct in6_addr) / sizeof(uint16_t)]; + int i; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < (int) sizeof(struct in6_addr); i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + best.len = 0; + cur.base = -1; + cur.len = 0; + for (i = 0; i < (int) ARRAY_SIZE(words); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (int) ARRAY_SIZE(words); i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) + *tp++ = ':'; + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) + *tp++ = ':'; + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && (best.len == 6 || + (best.len == 7 && words[7] != 0x0001) || + (best.len == 5 && words[5] == 0xffff))) { + int err = inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)); + if (err) + return err; + tp += strlen(tp); + break; + } + tp += sprintf(tp, "%x", words[i]); + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == ARRAY_SIZE(words)) + *tp++ = ':'; + *tp++ = '\0'; + if ((size_t) (tp - tmp) > size) + return UV_ENOSPC; + uv__strscpy(dst, tmp, size); + return 0; +} + + +int uv_inet_pton(int af, const char* src, void* dst) { + if (src == NULL || dst == NULL) + return UV_EINVAL; + + switch (af) { + case AF_INET: + return (inet_pton4(src, dst)); + case AF_INET6: { + int len; + char tmp[UV__INET6_ADDRSTRLEN], *s, *p; + s = (char*) src; + p = strchr(src, '%'); + if (p != NULL) { + s = tmp; + len = p - src; + if (len > UV__INET6_ADDRSTRLEN-1) + return UV_EINVAL; + memcpy(s, src, len); + s[len] = '\0'; + } + return inet_pton6(s, dst); + } + default: + return UV_EAFNOSUPPORT; + } + /* NOTREACHED */ +} + + +static int inet_pton4(const char *src, unsigned char *dst) { + static const char digits[] = "0123456789"; + int saw_digit, octets, ch; + unsigned char tmp[sizeof(struct in_addr)], *tp; + + saw_digit = 0; + octets = 0; + *(tp = tmp) = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr(digits, ch)) != NULL) { + unsigned int nw = *tp * 10 + (pch - digits); + + if (saw_digit && *tp == 0) + return UV_EINVAL; + if (nw > 255) + return UV_EINVAL; + *tp = nw; + if (!saw_digit) { + if (++octets > 4) + return UV_EINVAL; + saw_digit = 1; + } + } else if (ch == '.' && saw_digit) { + if (octets == 4) + return UV_EINVAL; + *++tp = 0; + saw_digit = 0; + } else + return UV_EINVAL; + } + if (octets < 4) + return UV_EINVAL; + memcpy(dst, tmp, sizeof(struct in_addr)); + return 0; +} + + +static int inet_pton6(const char *src, unsigned char *dst) { + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + unsigned char tmp[sizeof(struct in6_addr)], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, seen_xdigits; + unsigned int val; + + memset((tp = tmp), '\0', sizeof tmp); + endp = tp + sizeof tmp; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + return UV_EINVAL; + curtok = src; + seen_xdigits = 0; + val = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + if (++seen_xdigits > 4) + return UV_EINVAL; + continue; + } + if (ch == ':') { + curtok = src; + if (!seen_xdigits) { + if (colonp) + return UV_EINVAL; + colonp = tp; + continue; + } else if (*src == '\0') { + return UV_EINVAL; + } + if (tp + sizeof(uint16_t) > endp) + return UV_EINVAL; + *tp++ = (unsigned char) (val >> 8) & 0xff; + *tp++ = (unsigned char) val & 0xff; + seen_xdigits = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + sizeof(struct in_addr)) <= endp)) { + int err = inet_pton4(curtok, tp); + if (err == 0) { + tp += sizeof(struct in_addr); + seen_xdigits = 0; + break; /*%< '\\0' was seen by inet_pton4(). */ + } + } + return UV_EINVAL; + } + if (seen_xdigits) { + if (tp + sizeof(uint16_t) > endp) + return UV_EINVAL; + *tp++ = (unsigned char) (val >> 8) & 0xff; + *tp++ = (unsigned char) val & 0xff; + } + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const int n = tp - colonp; + int i; + + if (tp == endp) + return UV_EINVAL; + for (i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + if (tp != endp) + return UV_EINVAL; + memcpy(dst, tmp, sizeof tmp); + return 0; +} diff --git a/external/src/libuv/src/queue.h b/external/src/libuv/src/queue.h new file mode 100644 index 0000000..ff3540a --- /dev/null +++ b/external/src/libuv/src/queue.h @@ -0,0 +1,108 @@ +/* Copyright (c) 2013, Ben Noordhuis + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef QUEUE_H_ +#define QUEUE_H_ + +#include + +typedef void *QUEUE[2]; + +/* Private macros. */ +#define QUEUE_NEXT(q) (*(QUEUE **) &((*(q))[0])) +#define QUEUE_PREV(q) (*(QUEUE **) &((*(q))[1])) +#define QUEUE_PREV_NEXT(q) (QUEUE_NEXT(QUEUE_PREV(q))) +#define QUEUE_NEXT_PREV(q) (QUEUE_PREV(QUEUE_NEXT(q))) + +/* Public macros. */ +#define QUEUE_DATA(ptr, type, field) \ + ((type *) ((char *) (ptr) - offsetof(type, field))) + +/* Important note: mutating the list while QUEUE_FOREACH is + * iterating over its elements results in undefined behavior. + */ +#define QUEUE_FOREACH(q, h) \ + for ((q) = QUEUE_NEXT(h); (q) != (h); (q) = QUEUE_NEXT(q)) + +#define QUEUE_EMPTY(q) \ + ((const QUEUE *) (q) == (const QUEUE *) QUEUE_NEXT(q)) + +#define QUEUE_HEAD(q) \ + (QUEUE_NEXT(q)) + +#define QUEUE_INIT(q) \ + do { \ + QUEUE_NEXT(q) = (q); \ + QUEUE_PREV(q) = (q); \ + } \ + while (0) + +#define QUEUE_ADD(h, n) \ + do { \ + QUEUE_PREV_NEXT(h) = QUEUE_NEXT(n); \ + QUEUE_NEXT_PREV(n) = QUEUE_PREV(h); \ + QUEUE_PREV(h) = QUEUE_PREV(n); \ + QUEUE_PREV_NEXT(h) = (h); \ + } \ + while (0) + +#define QUEUE_SPLIT(h, q, n) \ + do { \ + QUEUE_PREV(n) = QUEUE_PREV(h); \ + QUEUE_PREV_NEXT(n) = (n); \ + QUEUE_NEXT(n) = (q); \ + QUEUE_PREV(h) = QUEUE_PREV(q); \ + QUEUE_PREV_NEXT(h) = (h); \ + QUEUE_PREV(q) = (n); \ + } \ + while (0) + +#define QUEUE_MOVE(h, n) \ + do { \ + if (QUEUE_EMPTY(h)) \ + QUEUE_INIT(n); \ + else { \ + QUEUE* q = QUEUE_HEAD(h); \ + QUEUE_SPLIT(h, q, n); \ + } \ + } \ + while (0) + +#define QUEUE_INSERT_HEAD(h, q) \ + do { \ + QUEUE_NEXT(q) = QUEUE_NEXT(h); \ + QUEUE_PREV(q) = (h); \ + QUEUE_NEXT_PREV(q) = (q); \ + QUEUE_NEXT(h) = (q); \ + } \ + while (0) + +#define QUEUE_INSERT_TAIL(h, q) \ + do { \ + QUEUE_NEXT(q) = (h); \ + QUEUE_PREV(q) = QUEUE_PREV(h); \ + QUEUE_PREV_NEXT(q) = (q); \ + QUEUE_PREV(h) = (q); \ + } \ + while (0) + +#define QUEUE_REMOVE(q) \ + do { \ + QUEUE_PREV_NEXT(q) = QUEUE_NEXT(q); \ + QUEUE_NEXT_PREV(q) = QUEUE_PREV(q); \ + } \ + while (0) + +#endif /* QUEUE_H_ */ diff --git a/external/src/libuv/src/random.c b/external/src/libuv/src/random.c new file mode 100644 index 0000000..e75f77d --- /dev/null +++ b/external/src/libuv/src/random.c @@ -0,0 +1,123 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "uv-common.h" + +#ifdef _WIN32 +# include "win/internal.h" +#else +# include "unix/internal.h" +#endif + +static int uv__random(void* buf, size_t buflen) { + int rc; + +#if defined(__PASE__) + rc = uv__random_readpath("/dev/urandom", buf, buflen); +#elif defined(_AIX) || defined(__QNX__) + rc = uv__random_readpath("/dev/random", buf, buflen); +#elif defined(__APPLE__) || defined(__OpenBSD__) || \ + (defined(__ANDROID_API__) && __ANDROID_API__ >= 28) + rc = uv__random_getentropy(buf, buflen); + if (rc == UV_ENOSYS) + rc = uv__random_devurandom(buf, buflen); +#elif defined(__NetBSD__) + rc = uv__random_sysctl(buf, buflen); +#elif defined(__FreeBSD__) || defined(__linux__) + rc = uv__random_getrandom(buf, buflen); + if (rc == UV_ENOSYS) + rc = uv__random_devurandom(buf, buflen); +# if defined(__linux__) + switch (rc) { + case UV_EACCES: + case UV_EIO: + case UV_ELOOP: + case UV_EMFILE: + case UV_ENFILE: + case UV_ENOENT: + case UV_EPERM: + rc = uv__random_sysctl(buf, buflen); + break; + } +# endif +#elif defined(_WIN32) + uv__once_init(); + rc = uv__random_rtlgenrandom(buf, buflen); +#else + rc = uv__random_devurandom(buf, buflen); +#endif + + return rc; +} + + +static void uv__random_work(struct uv__work* w) { + uv_random_t* req; + + req = container_of(w, uv_random_t, work_req); + req->status = uv__random(req->buf, req->buflen); +} + + +static void uv__random_done(struct uv__work* w, int status) { + uv_random_t* req; + + req = container_of(w, uv_random_t, work_req); + uv__req_unregister(req->loop, req); + + if (status == 0) + status = req->status; + + req->cb(req, status, req->buf, req->buflen); +} + + +int uv_random(uv_loop_t* loop, + uv_random_t* req, + void *buf, + size_t buflen, + unsigned flags, + uv_random_cb cb) { + if (buflen > 0x7FFFFFFFu) + return UV_E2BIG; + + if (flags != 0) + return UV_EINVAL; + + if (cb == NULL) + return uv__random(buf, buflen); + + uv__req_init(loop, req, UV_RANDOM); + req->loop = loop; + req->status = 0; + req->cb = cb; + req->buf = buf; + req->buflen = buflen; + + uv__work_submit(loop, + &req->work_req, + UV__WORK_CPU, + uv__random_work, + uv__random_done); + + return 0; +} diff --git a/external/src/libuv/src/strscpy.c b/external/src/libuv/src/strscpy.c new file mode 100644 index 0000000..20df6fc --- /dev/null +++ b/external/src/libuv/src/strscpy.c @@ -0,0 +1,38 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "strscpy.h" +#include /* SSIZE_MAX */ + +ssize_t uv__strscpy(char* d, const char* s, size_t n) { + size_t i; + + for (i = 0; i < n; i++) + if ('\0' == (d[i] = s[i])) + return i > SSIZE_MAX ? UV_E2BIG : (ssize_t) i; + + if (i == 0) + return 0; + + d[--i] = '\0'; + + return UV_E2BIG; +} diff --git a/external/src/libuv/src/strscpy.h b/external/src/libuv/src/strscpy.h new file mode 100644 index 0000000..cc78149 --- /dev/null +++ b/external/src/libuv/src/strscpy.h @@ -0,0 +1,39 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_STRSCPY_H_ +#define UV_STRSCPY_H_ + +/* Include uv.h for its definitions of size_t and ssize_t. + * size_t can be obtained directly from but ssize_t requires + * some hoop jumping on Windows that I didn't want to duplicate here. + */ +#include "uv.h" + +/* Copies up to |n-1| bytes from |d| to |s| and always zero-terminates + * the result, except when |n==0|. Returns the number of bytes copied + * or UV_E2BIG if |d| is too small. + * + * See https://www.kernel.org/doc/htmldocs/kernel-api/API-strscpy.html + */ +ssize_t uv__strscpy(char* d, const char* s, size_t n); + +#endif /* UV_STRSCPY_H_ */ diff --git a/external/src/libuv/src/threadpool.c b/external/src/libuv/src/threadpool.c new file mode 100644 index 0000000..869ae95 --- /dev/null +++ b/external/src/libuv/src/threadpool.c @@ -0,0 +1,386 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv-common.h" + +#if !defined(_WIN32) +# include "unix/internal.h" +#endif + +#include + +#define MAX_THREADPOOL_SIZE 1024 + +static uv_once_t once = UV_ONCE_INIT; +static uv_cond_t cond; +static uv_mutex_t mutex; +static unsigned int idle_threads; +static unsigned int slow_io_work_running; +static unsigned int nthreads; +static uv_thread_t* threads; +static uv_thread_t default_threads[4]; +static QUEUE exit_message; +static QUEUE wq; +static QUEUE run_slow_work_message; +static QUEUE slow_io_pending_wq; + +static unsigned int slow_work_thread_threshold(void) { + return (nthreads + 1) / 2; +} + +static void uv__cancelled(struct uv__work* w) { + abort(); +} + + +/* To avoid deadlock with uv_cancel() it's crucial that the worker + * never holds the global mutex and the loop-local mutex at the same time. + */ +static void worker(void* arg) { + struct uv__work* w; + QUEUE* q; + int is_slow_work; + + uv_sem_post((uv_sem_t*) arg); + arg = NULL; + + uv_mutex_lock(&mutex); + for (;;) { + /* `mutex` should always be locked at this point. */ + + /* Keep waiting while either no work is present or only slow I/O + and we're at the threshold for that. */ + while (QUEUE_EMPTY(&wq) || + (QUEUE_HEAD(&wq) == &run_slow_work_message && + QUEUE_NEXT(&run_slow_work_message) == &wq && + slow_io_work_running >= slow_work_thread_threshold())) { + idle_threads += 1; + uv_cond_wait(&cond, &mutex); + idle_threads -= 1; + } + + q = QUEUE_HEAD(&wq); + if (q == &exit_message) { + uv_cond_signal(&cond); + uv_mutex_unlock(&mutex); + break; + } + + QUEUE_REMOVE(q); + QUEUE_INIT(q); /* Signal uv_cancel() that the work req is executing. */ + + is_slow_work = 0; + if (q == &run_slow_work_message) { + /* If we're at the slow I/O threshold, re-schedule until after all + other work in the queue is done. */ + if (slow_io_work_running >= slow_work_thread_threshold()) { + QUEUE_INSERT_TAIL(&wq, q); + continue; + } + + /* If we encountered a request to run slow I/O work but there is none + to run, that means it's cancelled => Start over. */ + if (QUEUE_EMPTY(&slow_io_pending_wq)) + continue; + + is_slow_work = 1; + slow_io_work_running++; + + q = QUEUE_HEAD(&slow_io_pending_wq); + QUEUE_REMOVE(q); + QUEUE_INIT(q); + + /* If there is more slow I/O work, schedule it to be run as well. */ + if (!QUEUE_EMPTY(&slow_io_pending_wq)) { + QUEUE_INSERT_TAIL(&wq, &run_slow_work_message); + if (idle_threads > 0) + uv_cond_signal(&cond); + } + } + + uv_mutex_unlock(&mutex); + + w = QUEUE_DATA(q, struct uv__work, wq); + w->work(w); + + uv_mutex_lock(&w->loop->wq_mutex); + w->work = NULL; /* Signal uv_cancel() that the work req is done + executing. */ + QUEUE_INSERT_TAIL(&w->loop->wq, &w->wq); + uv_async_send(&w->loop->wq_async); + uv_mutex_unlock(&w->loop->wq_mutex); + + /* Lock `mutex` since that is expected at the start of the next + * iteration. */ + uv_mutex_lock(&mutex); + if (is_slow_work) { + /* `slow_io_work_running` is protected by `mutex`. */ + slow_io_work_running--; + } + } +} + + +static void post(QUEUE* q, enum uv__work_kind kind) { + uv_mutex_lock(&mutex); + if (kind == UV__WORK_SLOW_IO) { + /* Insert into a separate queue. */ + QUEUE_INSERT_TAIL(&slow_io_pending_wq, q); + if (!QUEUE_EMPTY(&run_slow_work_message)) { + /* Running slow I/O tasks is already scheduled => Nothing to do here. + The worker that runs said other task will schedule this one as well. */ + uv_mutex_unlock(&mutex); + return; + } + q = &run_slow_work_message; + } + + QUEUE_INSERT_TAIL(&wq, q); + if (idle_threads > 0) + uv_cond_signal(&cond); + uv_mutex_unlock(&mutex); +} + + +void uv__threadpool_cleanup(void) { + unsigned int i; + + if (nthreads == 0) + return; + + post(&exit_message, UV__WORK_CPU); + + for (i = 0; i < nthreads; i++) + if (uv_thread_join(threads + i)) + abort(); + + if (threads != default_threads) + uv__free(threads); + + uv_mutex_destroy(&mutex); + uv_cond_destroy(&cond); + + threads = NULL; + nthreads = 0; +} + + +static void init_threads(void) { + unsigned int i; + const char* val; + uv_sem_t sem; + + nthreads = ARRAY_SIZE(default_threads); + val = getenv("UV_THREADPOOL_SIZE"); + if (val != NULL) + nthreads = atoi(val); + if (nthreads == 0) + nthreads = 1; + if (nthreads > MAX_THREADPOOL_SIZE) + nthreads = MAX_THREADPOOL_SIZE; + + threads = default_threads; + if (nthreads > ARRAY_SIZE(default_threads)) { + threads = uv__malloc(nthreads * sizeof(threads[0])); + if (threads == NULL) { + nthreads = ARRAY_SIZE(default_threads); + threads = default_threads; + } + } + + if (uv_cond_init(&cond)) + abort(); + + if (uv_mutex_init(&mutex)) + abort(); + + QUEUE_INIT(&wq); + QUEUE_INIT(&slow_io_pending_wq); + QUEUE_INIT(&run_slow_work_message); + + if (uv_sem_init(&sem, 0)) + abort(); + + for (i = 0; i < nthreads; i++) + if (uv_thread_create(threads + i, worker, &sem)) + abort(); + + for (i = 0; i < nthreads; i++) + uv_sem_wait(&sem); + + uv_sem_destroy(&sem); +} + + +#ifndef _WIN32 +static void reset_once(void) { + uv_once_t child_once = UV_ONCE_INIT; + memcpy(&once, &child_once, sizeof(child_once)); +} +#endif + + +static void init_once(void) { +#ifndef _WIN32 + /* Re-initialize the threadpool after fork. + * Note that this discards the global mutex and condition as well + * as the work queue. + */ + if (pthread_atfork(NULL, NULL, &reset_once)) + abort(); +#endif + init_threads(); +} + + +void uv__work_submit(uv_loop_t* loop, + struct uv__work* w, + enum uv__work_kind kind, + void (*work)(struct uv__work* w), + void (*done)(struct uv__work* w, int status)) { + uv_once(&once, init_once); + w->loop = loop; + w->work = work; + w->done = done; + post(&w->wq, kind); +} + + +static int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) { + int cancelled; + + uv_mutex_lock(&mutex); + uv_mutex_lock(&w->loop->wq_mutex); + + cancelled = !QUEUE_EMPTY(&w->wq) && w->work != NULL; + if (cancelled) + QUEUE_REMOVE(&w->wq); + + uv_mutex_unlock(&w->loop->wq_mutex); + uv_mutex_unlock(&mutex); + + if (!cancelled) + return UV_EBUSY; + + w->work = uv__cancelled; + uv_mutex_lock(&loop->wq_mutex); + QUEUE_INSERT_TAIL(&loop->wq, &w->wq); + uv_async_send(&loop->wq_async); + uv_mutex_unlock(&loop->wq_mutex); + + return 0; +} + + +void uv__work_done(uv_async_t* handle) { + struct uv__work* w; + uv_loop_t* loop; + QUEUE* q; + QUEUE wq; + int err; + + loop = container_of(handle, uv_loop_t, wq_async); + uv_mutex_lock(&loop->wq_mutex); + QUEUE_MOVE(&loop->wq, &wq); + uv_mutex_unlock(&loop->wq_mutex); + + while (!QUEUE_EMPTY(&wq)) { + q = QUEUE_HEAD(&wq); + QUEUE_REMOVE(q); + + w = container_of(q, struct uv__work, wq); + err = (w->work == uv__cancelled) ? UV_ECANCELED : 0; + w->done(w, err); + } +} + + +static void uv__queue_work(struct uv__work* w) { + uv_work_t* req = container_of(w, uv_work_t, work_req); + + req->work_cb(req); +} + + +static void uv__queue_done(struct uv__work* w, int err) { + uv_work_t* req; + + req = container_of(w, uv_work_t, work_req); + uv__req_unregister(req->loop, req); + + if (req->after_work_cb == NULL) + return; + + req->after_work_cb(req, err); +} + + +int uv_queue_work(uv_loop_t* loop, + uv_work_t* req, + uv_work_cb work_cb, + uv_after_work_cb after_work_cb) { + if (work_cb == NULL) + return UV_EINVAL; + + uv__req_init(loop, req, UV_WORK); + req->loop = loop; + req->work_cb = work_cb; + req->after_work_cb = after_work_cb; + uv__work_submit(loop, + &req->work_req, + UV__WORK_CPU, + uv__queue_work, + uv__queue_done); + return 0; +} + + +int uv_cancel(uv_req_t* req) { + struct uv__work* wreq; + uv_loop_t* loop; + + switch (req->type) { + case UV_FS: + loop = ((uv_fs_t*) req)->loop; + wreq = &((uv_fs_t*) req)->work_req; + break; + case UV_GETADDRINFO: + loop = ((uv_getaddrinfo_t*) req)->loop; + wreq = &((uv_getaddrinfo_t*) req)->work_req; + break; + case UV_GETNAMEINFO: + loop = ((uv_getnameinfo_t*) req)->loop; + wreq = &((uv_getnameinfo_t*) req)->work_req; + break; + case UV_RANDOM: + loop = ((uv_random_t*) req)->loop; + wreq = &((uv_random_t*) req)->work_req; + break; + case UV_WORK: + loop = ((uv_work_t*) req)->loop; + wreq = &((uv_work_t*) req)->work_req; + break; + default: + return UV_EINVAL; + } + + return uv__work_cancel(loop, req, wreq); +} diff --git a/external/src/libuv/src/timer.c b/external/src/libuv/src/timer.c new file mode 100644 index 0000000..bc680e7 --- /dev/null +++ b/external/src/libuv/src/timer.c @@ -0,0 +1,185 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "uv-common.h" +#include "heap-inl.h" + +#include +#include + + +static struct heap *timer_heap(const uv_loop_t* loop) { +#ifdef _WIN32 + return (struct heap*) loop->timer_heap; +#else + return (struct heap*) &loop->timer_heap; +#endif +} + + +static int timer_less_than(const struct heap_node* ha, + const struct heap_node* hb) { + const uv_timer_t* a; + const uv_timer_t* b; + + a = container_of(ha, uv_timer_t, heap_node); + b = container_of(hb, uv_timer_t, heap_node); + + if (a->timeout < b->timeout) + return 1; + if (b->timeout < a->timeout) + return 0; + + /* Compare start_id when both have the same timeout. start_id is + * allocated with loop->timer_counter in uv_timer_start(). + */ + return a->start_id < b->start_id; +} + + +int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) { + uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER); + handle->timer_cb = NULL; + handle->timeout = 0; + handle->repeat = 0; + return 0; +} + + +int uv_timer_start(uv_timer_t* handle, + uv_timer_cb cb, + uint64_t timeout, + uint64_t repeat) { + uint64_t clamped_timeout; + + if (uv__is_closing(handle) || cb == NULL) + return UV_EINVAL; + + if (uv__is_active(handle)) + uv_timer_stop(handle); + + clamped_timeout = handle->loop->time + timeout; + if (clamped_timeout < timeout) + clamped_timeout = (uint64_t) -1; + + handle->timer_cb = cb; + handle->timeout = clamped_timeout; + handle->repeat = repeat; + /* start_id is the second index to be compared in timer_less_than() */ + handle->start_id = handle->loop->timer_counter++; + + heap_insert(timer_heap(handle->loop), + (struct heap_node*) &handle->heap_node, + timer_less_than); + uv__handle_start(handle); + + return 0; +} + + +int uv_timer_stop(uv_timer_t* handle) { + if (!uv__is_active(handle)) + return 0; + + heap_remove(timer_heap(handle->loop), + (struct heap_node*) &handle->heap_node, + timer_less_than); + uv__handle_stop(handle); + + return 0; +} + + +int uv_timer_again(uv_timer_t* handle) { + if (handle->timer_cb == NULL) + return UV_EINVAL; + + if (handle->repeat) { + uv_timer_stop(handle); + uv_timer_start(handle, handle->timer_cb, handle->repeat, handle->repeat); + } + + return 0; +} + + +void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) { + handle->repeat = repeat; +} + + +uint64_t uv_timer_get_repeat(const uv_timer_t* handle) { + return handle->repeat; +} + + +uint64_t uv_timer_get_due_in(const uv_timer_t* handle) { + if (handle->loop->time >= handle->timeout) + return 0; + + return handle->timeout - handle->loop->time; +} + + +int uv__next_timeout(const uv_loop_t* loop) { + const struct heap_node* heap_node; + const uv_timer_t* handle; + uint64_t diff; + + heap_node = heap_min(timer_heap(loop)); + if (heap_node == NULL) + return -1; /* block indefinitely */ + + handle = container_of(heap_node, uv_timer_t, heap_node); + if (handle->timeout <= loop->time) + return 0; + + diff = handle->timeout - loop->time; + if (diff > INT_MAX) + diff = INT_MAX; + + return (int) diff; +} + + +void uv__run_timers(uv_loop_t* loop) { + struct heap_node* heap_node; + uv_timer_t* handle; + + for (;;) { + heap_node = heap_min(timer_heap(loop)); + if (heap_node == NULL) + break; + + handle = container_of(heap_node, uv_timer_t, heap_node); + if (handle->timeout > loop->time) + break; + + uv_timer_stop(handle); + uv_timer_again(handle); + handle->timer_cb(handle); + } +} + + +void uv__timer_close(uv_timer_t* handle) { + uv_timer_stop(handle); +} diff --git a/external/src/libuv/src/unix/aix-common.c b/external/src/libuv/src/unix/aix-common.c new file mode 100644 index 0000000..abc4c90 --- /dev/null +++ b/external/src/libuv/src/unix/aix-common.c @@ -0,0 +1,89 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include + +#include + +#include +#include + +#include + +#include + +extern char* original_exepath; +extern uv_mutex_t process_title_mutex; +extern uv_once_t process_title_mutex_once; +extern void init_process_title_mutex_once(void); + +uint64_t uv__hrtime(uv_clocktype_t type) { + uint64_t G = 1000000000; + timebasestruct_t t; + read_wall_time(&t, TIMEBASE_SZ); + time_base_to_time(&t, TIMEBASE_SZ); + return (uint64_t) t.tb_high * G + t.tb_low; +} + + +/* + * We could use a static buffer for the path manipulations that we need outside + * of the function, but this function could be called by multiple consumers and + * we don't want to potentially create a race condition in the use of snprintf. + * There is no direct way of getting the exe path in AIX - either through /procfs + * or through some libc APIs. The below approach is to parse the argv[0]'s pattern + * and use it in conjunction with PATH environment variable to craft one. + */ +int uv_exepath(char* buffer, size_t* size) { + int res; + char args[UV__PATH_MAX]; + size_t cached_len; + struct procsinfo pi; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + if (original_exepath != NULL) { + cached_len = strlen(original_exepath); + *size -= 1; + if (*size > cached_len) + *size = cached_len; + memcpy(buffer, original_exepath, *size); + buffer[*size] = '\0'; + uv_mutex_unlock(&process_title_mutex); + return 0; + } + uv_mutex_unlock(&process_title_mutex); + pi.pi_pid = getpid(); + res = getargs(&pi, sizeof(pi), args, sizeof(args)); + + if (res < 0) + return UV_EINVAL; + + return uv__search_path(args, buffer, size); +} diff --git a/external/src/libuv/src/unix/aix.c b/external/src/libuv/src/unix/aix.c new file mode 100644 index 0000000..6a013d4 --- /dev/null +++ b/external/src/libuv/src/unix/aix.c @@ -0,0 +1,1304 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include +#ifdef HAVE_SYS_AHAFS_EVPRODS_H +#include +#endif + +#include +#include +#include +#include +#include + +#define RDWR_BUF_SIZE 4096 +#define EQ(a,b) (strcmp(a,b) == 0) + +char* original_exepath = NULL; +uv_mutex_t process_title_mutex; +uv_once_t process_title_mutex_once = UV_ONCE_INIT; +static void* args_mem = NULL; +static char** process_argv = NULL; +static int process_argc = 0; +static char* process_title_ptr = NULL; + +void init_process_title_mutex_once(void) { + uv_mutex_init(&process_title_mutex); +} + + +int uv__platform_loop_init(uv_loop_t* loop) { + loop->fs_fd = -1; + + /* Passing maxfd of -1 should mean the limit is determined + * by the user's ulimit or the global limit as per the doc */ + loop->backend_fd = pollset_create(-1); + + if (loop->backend_fd == -1) + return -1; + + return 0; +} + + +void uv__platform_loop_delete(uv_loop_t* loop) { + if (loop->fs_fd != -1) { + uv__close(loop->fs_fd); + loop->fs_fd = -1; + } + + if (loop->backend_fd != -1) { + pollset_destroy(loop->backend_fd); + loop->backend_fd = -1; + } +} + + +int uv__io_fork(uv_loop_t* loop) { + uv__platform_loop_delete(loop); + + return uv__platform_loop_init(loop); +} + + +int uv__io_check_fd(uv_loop_t* loop, int fd) { + struct poll_ctl pc; + + pc.events = POLLIN; + pc.cmd = PS_MOD; /* Equivalent to PS_ADD if the fd is not in the pollset. */ + pc.fd = fd; + + if (pollset_ctl(loop->backend_fd, &pc, 1)) + return UV__ERR(errno); + + pc.cmd = PS_DELETE; + if (pollset_ctl(loop->backend_fd, &pc, 1)) + abort(); + + return 0; +} + + +void uv__io_poll(uv_loop_t* loop, int timeout) { + struct pollfd events[1024]; + struct pollfd pqry; + struct pollfd* pe; + struct poll_ctl pc; + QUEUE* q; + uv__io_t* w; + uint64_t base; + uint64_t diff; + int have_signals; + int nevents; + int count; + int nfds; + int i; + int rc; + int add_failed; + int user_timeout; + int reset_timeout; + + if (loop->nfds == 0) { + assert(QUEUE_EMPTY(&loop->watcher_queue)); + return; + } + + while (!QUEUE_EMPTY(&loop->watcher_queue)) { + q = QUEUE_HEAD(&loop->watcher_queue); + QUEUE_REMOVE(q); + QUEUE_INIT(q); + + w = QUEUE_DATA(q, uv__io_t, watcher_queue); + assert(w->pevents != 0); + assert(w->fd >= 0); + assert(w->fd < (int) loop->nwatchers); + + pc.events = w->pevents; + pc.fd = w->fd; + + add_failed = 0; + if (w->events == 0) { + pc.cmd = PS_ADD; + if (pollset_ctl(loop->backend_fd, &pc, 1)) { + if (errno != EINVAL) { + assert(0 && "Failed to add file descriptor (pc.fd) to pollset"); + abort(); + } + /* Check if the fd is already in the pollset */ + pqry.fd = pc.fd; + rc = pollset_query(loop->backend_fd, &pqry); + switch (rc) { + case -1: + assert(0 && "Failed to query pollset for file descriptor"); + abort(); + case 0: + assert(0 && "Pollset does not contain file descriptor"); + abort(); + } + /* If we got here then the pollset already contained the file descriptor even though + * we didn't think it should. This probably shouldn't happen, but we can continue. */ + add_failed = 1; + } + } + if (w->events != 0 || add_failed) { + /* Modify, potentially removing events -- need to delete then add. + * Could maybe mod if we knew for sure no events are removed, but + * content of w->events is handled above as not reliable (falls back) + * so may require a pollset_query() which would have to be pretty cheap + * compared to a PS_DELETE to be worth optimizing. Alternatively, could + * lazily remove events, squelching them in the mean time. */ + pc.cmd = PS_DELETE; + if (pollset_ctl(loop->backend_fd, &pc, 1)) { + assert(0 && "Failed to delete file descriptor (pc.fd) from pollset"); + abort(); + } + pc.cmd = PS_ADD; + if (pollset_ctl(loop->backend_fd, &pc, 1)) { + assert(0 && "Failed to add file descriptor (pc.fd) to pollset"); + abort(); + } + } + + w->events = w->pevents; + } + + assert(timeout >= -1); + base = loop->time; + count = 48; /* Benchmarks suggest this gives the best throughput. */ + + if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) { + reset_timeout = 1; + user_timeout = timeout; + timeout = 0; + } else { + reset_timeout = 0; + } + + for (;;) { + /* Only need to set the provider_entry_time if timeout != 0. The function + * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME. + */ + if (timeout != 0) + uv__metrics_set_provider_entry_time(loop); + + nfds = pollset_poll(loop->backend_fd, + events, + ARRAY_SIZE(events), + timeout); + + /* Update loop->time unconditionally. It's tempting to skip the update when + * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the + * operating system didn't reschedule our process while in the syscall. + */ + SAVE_ERRNO(uv__update_time(loop)); + + if (nfds == 0) { + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + if (timeout == -1) + continue; + if (timeout > 0) + goto update_timeout; + } + + assert(timeout != -1); + return; + } + + if (nfds == -1) { + if (errno != EINTR) { + abort(); + } + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (timeout == -1) + continue; + + if (timeout == 0) + return; + + /* Interrupted by a signal. Update timeout and poll again. */ + goto update_timeout; + } + + have_signals = 0; + nevents = 0; + + assert(loop->watchers != NULL); + loop->watchers[loop->nwatchers] = (void*) events; + loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds; + + for (i = 0; i < nfds; i++) { + pe = events + i; + pc.cmd = PS_DELETE; + pc.fd = pe->fd; + + /* Skip invalidated events, see uv__platform_invalidate_fd */ + if (pc.fd == -1) + continue; + + assert(pc.fd >= 0); + assert((unsigned) pc.fd < loop->nwatchers); + + w = loop->watchers[pc.fd]; + + if (w == NULL) { + /* File descriptor that we've stopped watching, disarm it. + * + * Ignore all errors because we may be racing with another thread + * when the file descriptor is closed. + */ + pollset_ctl(loop->backend_fd, &pc, 1); + continue; + } + + /* Run signal watchers last. This also affects child process watchers + * because those are implemented in terms of signal watchers. + */ + if (w == &loop->signal_io_watcher) { + have_signals = 1; + } else { + uv__metrics_update_idle_time(loop); + w->cb(loop, w, pe->revents); + } + + nevents++; + } + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (have_signals != 0) { + uv__metrics_update_idle_time(loop); + loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN); + } + + loop->watchers[loop->nwatchers] = NULL; + loop->watchers[loop->nwatchers + 1] = NULL; + + if (have_signals != 0) + return; /* Event loop should cycle now so don't poll again. */ + + if (nevents != 0) { + if (nfds == ARRAY_SIZE(events) && --count != 0) { + /* Poll for more events but don't block this time. */ + timeout = 0; + continue; + } + return; + } + + if (timeout == 0) + return; + + if (timeout == -1) + continue; + +update_timeout: + assert(timeout > 0); + + diff = loop->time - base; + if (diff >= (uint64_t) timeout) + return; + + timeout -= diff; + } +} + + +uint64_t uv_get_free_memory(void) { + perfstat_memory_total_t mem_total; + int result = perfstat_memory_total(NULL, &mem_total, sizeof(mem_total), 1); + if (result == -1) { + return 0; + } + return mem_total.real_free * 4096; +} + + +uint64_t uv_get_total_memory(void) { + perfstat_memory_total_t mem_total; + int result = perfstat_memory_total(NULL, &mem_total, sizeof(mem_total), 1); + if (result == -1) { + return 0; + } + return mem_total.real_total * 4096; +} + + +uint64_t uv_get_constrained_memory(void) { + return 0; /* Memory constraints are unknown. */ +} + + +void uv_loadavg(double avg[3]) { + perfstat_cpu_total_t ps_total; + int result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1); + if (result == -1) { + avg[0] = 0.; avg[1] = 0.; avg[2] = 0.; + return; + } + avg[0] = ps_total.loadavg[0] / (double)(1 << SBITS); + avg[1] = ps_total.loadavg[1] / (double)(1 << SBITS); + avg[2] = ps_total.loadavg[2] / (double)(1 << SBITS); +} + + +#ifdef HAVE_SYS_AHAFS_EVPRODS_H +static char* uv__rawname(const char* cp, char (*dst)[FILENAME_MAX+1]) { + char* dp; + + dp = rindex(cp, '/'); + if (dp == 0) + return 0; + + snprintf(*dst, sizeof(*dst), "%.*s/r%s", (int) (dp - cp), cp, dp + 1); + return *dst; +} + + +/* + * Determine whether given pathname is a directory + * Returns 0 if the path is a directory, -1 if not + * + * Note: Opportunity here for more detailed error information but + * that requires changing callers of this function as well + */ +static int uv__path_is_a_directory(char* filename) { + struct stat statbuf; + + if (stat(filename, &statbuf) < 0) + return -1; /* failed: not a directory, assume it is a file */ + + if (statbuf.st_type == VDIR) + return 0; + + return -1; +} + + +/* + * Check whether AHAFS is mounted. + * Returns 0 if AHAFS is mounted, or an error code < 0 on failure + */ +static int uv__is_ahafs_mounted(void){ + char rawbuf[FILENAME_MAX+1]; + int rv, i = 2; + struct vmount *p; + int size_multiplier = 10; + size_t siz = sizeof(struct vmount)*size_multiplier; + struct vmount *vmt; + const char *dev = "/aha"; + char *obj, *stub; + + p = uv__malloc(siz); + if (p == NULL) + return UV__ERR(errno); + + /* Retrieve all mounted filesystems */ + rv = mntctl(MCTL_QUERY, siz, (char*)p); + if (rv < 0) + return UV__ERR(errno); + if (rv == 0) { + /* buffer was not large enough, reallocate to correct size */ + siz = *(int*)p; + uv__free(p); + p = uv__malloc(siz); + if (p == NULL) + return UV__ERR(errno); + rv = mntctl(MCTL_QUERY, siz, (char*)p); + if (rv < 0) + return UV__ERR(errno); + } + + /* Look for dev in filesystems mount info */ + for(vmt = p, i = 0; i < rv; i++) { + obj = vmt2dataptr(vmt, VMT_OBJECT); /* device */ + stub = vmt2dataptr(vmt, VMT_STUB); /* mount point */ + + if (EQ(obj, dev) || EQ(uv__rawname(obj, &rawbuf), dev) || EQ(stub, dev)) { + uv__free(p); /* Found a match */ + return 0; + } + vmt = (struct vmount *) ((char *) vmt + vmt->vmt_length); + } + + /* /aha is required for monitoring filesystem changes */ + return -1; +} + +/* + * Recursive call to mkdir() to create intermediate folders, if any + * Returns code from mkdir call + */ +static int uv__makedir_p(const char *dir) { + char tmp[256]; + char *p = NULL; + size_t len; + int err; + + /* TODO(bnoordhuis) Check uv__strscpy() return value. */ + uv__strscpy(tmp, dir, sizeof(tmp)); + len = strlen(tmp); + if (tmp[len - 1] == '/') + tmp[len - 1] = 0; + for (p = tmp + 1; *p; p++) { + if (*p == '/') { + *p = 0; + err = mkdir(tmp, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + if (err != 0 && errno != EEXIST) + return err; + *p = '/'; + } + } + return mkdir(tmp, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); +} + +/* + * Creates necessary subdirectories in the AIX Event Infrastructure + * file system for monitoring the object specified. + * Returns code from mkdir call + */ +static int uv__make_subdirs_p(const char *filename) { + char cmd[2048]; + char *p; + int rc = 0; + + /* Strip off the monitor file name */ + p = strrchr(filename, '/'); + + if (p == NULL) + return 0; + + if (uv__path_is_a_directory((char*)filename) == 0) { + sprintf(cmd, "/aha/fs/modDir.monFactory"); + } else { + sprintf(cmd, "/aha/fs/modFile.monFactory"); + } + + strncat(cmd, filename, (p - filename)); + rc = uv__makedir_p(cmd); + + if (rc == -1 && errno != EEXIST){ + return UV__ERR(errno); + } + + return rc; +} + + +/* + * Checks if /aha is mounted, then proceeds to set up the monitoring + * objects for the specified file. + * Returns 0 on success, or an error code < 0 on failure + */ +static int uv__setup_ahafs(const char* filename, int *fd) { + int rc = 0; + char mon_file_write_string[RDWR_BUF_SIZE]; + char mon_file[PATH_MAX]; + int file_is_directory = 0; /* -1 == NO, 0 == YES */ + + /* Create monitor file name for object */ + file_is_directory = uv__path_is_a_directory((char*)filename); + + if (file_is_directory == 0) + sprintf(mon_file, "/aha/fs/modDir.monFactory"); + else + sprintf(mon_file, "/aha/fs/modFile.monFactory"); + + if ((strlen(mon_file) + strlen(filename) + 5) > PATH_MAX) + return UV_ENAMETOOLONG; + + /* Make the necessary subdirectories for the monitor file */ + rc = uv__make_subdirs_p(filename); + if (rc == -1 && errno != EEXIST) + return rc; + + strcat(mon_file, filename); + strcat(mon_file, ".mon"); + + *fd = 0; errno = 0; + + /* Open the monitor file, creating it if necessary */ + *fd = open(mon_file, O_CREAT|O_RDWR); + if (*fd < 0) + return UV__ERR(errno); + + /* Write out the monitoring specifications. + * In this case, we are monitoring for a state change event type + * CHANGED=YES + * We will be waiting in select call, rather than a read: + * WAIT_TYPE=WAIT_IN_SELECT + * We only want minimal information for files: + * INFO_LVL=1 + * For directories, we want more information to track what file + * caused the change + * INFO_LVL=2 + */ + + if (file_is_directory == 0) + sprintf(mon_file_write_string, "CHANGED=YES;WAIT_TYPE=WAIT_IN_SELECT;INFO_LVL=2"); + else + sprintf(mon_file_write_string, "CHANGED=YES;WAIT_TYPE=WAIT_IN_SELECT;INFO_LVL=1"); + + rc = write(*fd, mon_file_write_string, strlen(mon_file_write_string)+1); + if (rc < 0 && errno != EBUSY) + return UV__ERR(errno); + + return 0; +} + +/* + * Skips a specified number of lines in the buffer passed in. + * Walks the buffer pointed to by p and attempts to skip n lines. + * Returns the total number of lines skipped + */ +static int uv__skip_lines(char **p, int n) { + int lines = 0; + + while(n > 0) { + *p = strchr(*p, '\n'); + if (!p) + return lines; + + (*p)++; + n--; + lines++; + } + return lines; +} + + +/* + * Parse the event occurrence data to figure out what event just occurred + * and take proper action. + * + * The buf is a pointer to the buffer containing the event occurrence data + * Returns 0 on success, -1 if unrecoverable error in parsing + * + */ +static int uv__parse_data(char *buf, int *events, uv_fs_event_t* handle) { + int evp_rc, i; + char *p; + char filename[PATH_MAX]; /* To be used when handling directories */ + + p = buf; + *events = 0; + + /* Clean the filename buffer*/ + for(i = 0; i < PATH_MAX; i++) { + filename[i] = 0; + } + i = 0; + + /* Check for BUF_WRAP */ + if (strncmp(buf, "BUF_WRAP", strlen("BUF_WRAP")) == 0) { + assert(0 && "Buffer wrap detected, Some event occurrences lost!"); + return 0; + } + + /* Since we are using the default buffer size (4K), and have specified + * INFO_LVL=1, we won't see any EVENT_OVERFLOW conditions. Applications + * should check for this keyword if they are using an INFO_LVL of 2 or + * higher, and have a buffer size of <= 4K + */ + + /* Skip to RC_FROM_EVPROD */ + if (uv__skip_lines(&p, 9) != 9) + return -1; + + if (sscanf(p, "RC_FROM_EVPROD=%d\nEND_EVENT_DATA", &evp_rc) == 1) { + if (uv__path_is_a_directory(handle->path) == 0) { /* Directory */ + if (evp_rc == AHAFS_MODDIR_UNMOUNT || evp_rc == AHAFS_MODDIR_REMOVE_SELF) { + /* The directory is no longer available for monitoring */ + *events = UV_RENAME; + handle->dir_filename = NULL; + } else { + /* A file was added/removed inside the directory */ + *events = UV_CHANGE; + + /* Get the EVPROD_INFO */ + if (uv__skip_lines(&p, 1) != 1) + return -1; + + /* Scan out the name of the file that triggered the event*/ + if (sscanf(p, "BEGIN_EVPROD_INFO\n%sEND_EVPROD_INFO", filename) == 1) { + handle->dir_filename = uv__strdup((const char*)&filename); + } else + return -1; + } + } else { /* Regular File */ + if (evp_rc == AHAFS_MODFILE_RENAME) + *events = UV_RENAME; + else + *events = UV_CHANGE; + } + } + else + return -1; + + return 0; +} + + +/* This is the internal callback */ +static void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int fflags) { + char result_data[RDWR_BUF_SIZE]; + int bytes, rc = 0; + uv_fs_event_t* handle; + int events = 0; + char fname[PATH_MAX]; + char *p; + + handle = container_of(event_watch, uv_fs_event_t, event_watcher); + + /* At this point, we assume that polling has been done on the + * file descriptor, so we can just read the AHAFS event occurrence + * data and parse its results without having to block anything + */ + bytes = pread(event_watch->fd, result_data, RDWR_BUF_SIZE, 0); + + assert((bytes >= 0) && "uv__ahafs_event - Error reading monitor file"); + + /* In file / directory move cases, AIX Event infrastructure + * produces a second event with no data. + * Ignore it and return gracefully. + */ + if(bytes == 0) + return; + + /* Parse the data */ + if(bytes > 0) + rc = uv__parse_data(result_data, &events, handle); + + /* Unrecoverable error */ + if (rc == -1) + return; + + /* For directory changes, the name of the files that triggered the change + * are never absolute pathnames + */ + if (uv__path_is_a_directory(handle->path) == 0) { + p = handle->dir_filename; + } else { + p = strrchr(handle->path, '/'); + if (p == NULL) + p = handle->path; + else + p++; + } + + /* TODO(bnoordhuis) Check uv__strscpy() return value. */ + uv__strscpy(fname, p, sizeof(fname)); + + handle->cb(handle, fname, events, 0); +} +#endif + + +int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { +#ifdef HAVE_SYS_AHAFS_EVPRODS_H + uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); + return 0; +#else + return UV_ENOSYS; +#endif +} + + +int uv_fs_event_start(uv_fs_event_t* handle, + uv_fs_event_cb cb, + const char* filename, + unsigned int flags) { +#ifdef HAVE_SYS_AHAFS_EVPRODS_H + int fd, rc, str_offset = 0; + char cwd[PATH_MAX]; + char absolute_path[PATH_MAX]; + char readlink_cwd[PATH_MAX]; + struct timeval zt; + fd_set pollfd; + + + /* Figure out whether filename is absolute or not */ + if (filename[0] == '\0') { + /* Missing a pathname */ + return UV_ENOENT; + } + else if (filename[0] == '/') { + /* We have absolute pathname */ + /* TODO(bnoordhuis) Check uv__strscpy() return value. */ + uv__strscpy(absolute_path, filename, sizeof(absolute_path)); + } else { + /* We have a relative pathname, compose the absolute pathname */ + snprintf(cwd, sizeof(cwd), "/proc/%lu/cwd", (unsigned long) getpid()); + rc = readlink(cwd, readlink_cwd, sizeof(readlink_cwd) - 1); + if (rc < 0) + return rc; + /* readlink does not null terminate our string */ + readlink_cwd[rc] = '\0'; + + if (filename[0] == '.' && filename[1] == '/') + str_offset = 2; + + snprintf(absolute_path, sizeof(absolute_path), "%s%s", readlink_cwd, + filename + str_offset); + } + + if (uv__is_ahafs_mounted() < 0) /* /aha checks failed */ + return UV_ENOSYS; + + /* Setup ahafs */ + rc = uv__setup_ahafs((const char *)absolute_path, &fd); + if (rc != 0) + return rc; + + /* Setup/Initialize all the libuv routines */ + uv__handle_start(handle); + uv__io_init(&handle->event_watcher, uv__ahafs_event, fd); + handle->path = uv__strdup(filename); + handle->cb = cb; + handle->dir_filename = NULL; + + uv__io_start(handle->loop, &handle->event_watcher, POLLIN); + + /* AHAFS wants someone to poll for it to start mointoring. + * so kick-start it so that we don't miss an event in the + * eventuality of an event that occurs in the current loop. */ + do { + memset(&zt, 0, sizeof(zt)); + FD_ZERO(&pollfd); + FD_SET(fd, &pollfd); + rc = select(fd + 1, &pollfd, NULL, NULL, &zt); + } while (rc == -1 && errno == EINTR); + return 0; +#else + return UV_ENOSYS; +#endif +} + + +int uv_fs_event_stop(uv_fs_event_t* handle) { +#ifdef HAVE_SYS_AHAFS_EVPRODS_H + if (!uv__is_active(handle)) + return 0; + + uv__io_close(handle->loop, &handle->event_watcher); + uv__handle_stop(handle); + + if (uv__path_is_a_directory(handle->path) == 0) { + uv__free(handle->dir_filename); + handle->dir_filename = NULL; + } + + uv__free(handle->path); + handle->path = NULL; + uv__close(handle->event_watcher.fd); + handle->event_watcher.fd = -1; + + return 0; +#else + return UV_ENOSYS; +#endif +} + + +void uv__fs_event_close(uv_fs_event_t* handle) { +#ifdef HAVE_SYS_AHAFS_EVPRODS_H + uv_fs_event_stop(handle); +#else + UNREACHABLE(); +#endif +} + + +char** uv_setup_args(int argc, char** argv) { + char exepath[UV__PATH_MAX]; + char** new_argv; + size_t size; + char* s; + int i; + + if (argc <= 0) + return argv; + + /* Save the original pointer to argv. + * AIX uses argv to read the process name. + * (Not the memory pointed to by argv[0..n] as on Linux.) + */ + process_argv = argv; + process_argc = argc; + + /* Use argv[0] to determine value for uv_exepath(). */ + size = sizeof(exepath); + if (uv__search_path(argv[0], exepath, &size) == 0) { + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + original_exepath = uv__strdup(exepath); + uv_mutex_unlock(&process_title_mutex); + } + + /* Calculate how much memory we need for the argv strings. */ + size = 0; + for (i = 0; i < argc; i++) + size += strlen(argv[i]) + 1; + + /* Add space for the argv pointers. */ + size += (argc + 1) * sizeof(char*); + + new_argv = uv__malloc(size); + if (new_argv == NULL) + return argv; + args_mem = new_argv; + + /* Copy over the strings and set up the pointer table. */ + s = (char*) &new_argv[argc + 1]; + for (i = 0; i < argc; i++) { + size = strlen(argv[i]) + 1; + memcpy(s, argv[i], size); + new_argv[i] = s; + s += size; + } + new_argv[i] = NULL; + + return new_argv; +} + + +int uv_set_process_title(const char* title) { + char* new_title; + + /* If uv_setup_args wasn't called or failed, we can't continue. */ + if (process_argv == NULL || args_mem == NULL) + return UV_ENOBUFS; + + /* We cannot free this pointer when libuv shuts down, + * the process may still be using it. + */ + new_title = uv__strdup(title); + if (new_title == NULL) + return UV_ENOMEM; + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + /* If this is the first time this is set, + * don't free and set argv[1] to NULL. + */ + if (process_title_ptr != NULL) + uv__free(process_title_ptr); + + process_title_ptr = new_title; + + process_argv[0] = process_title_ptr; + if (process_argc > 1) + process_argv[1] = NULL; + + uv_mutex_unlock(&process_title_mutex); + + return 0; +} + + +int uv_get_process_title(char* buffer, size_t size) { + size_t len; + if (buffer == NULL || size == 0) + return UV_EINVAL; + + /* If uv_setup_args wasn't called, we can't continue. */ + if (process_argv == NULL) + return UV_ENOBUFS; + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + len = strlen(process_argv[0]); + if (size <= len) { + uv_mutex_unlock(&process_title_mutex); + return UV_ENOBUFS; + } + + memcpy(buffer, process_argv[0], len); + buffer[len] = '\0'; + + uv_mutex_unlock(&process_title_mutex); + + return 0; +} + + +void uv__process_title_cleanup(void) { + uv__free(args_mem); /* Keep valgrind happy. */ + args_mem = NULL; +} + + +int uv_resident_set_memory(size_t* rss) { + char pp[64]; + psinfo_t psinfo; + int err; + int fd; + + snprintf(pp, sizeof(pp), "/proc/%lu/psinfo", (unsigned long) getpid()); + + fd = open(pp, O_RDONLY); + if (fd == -1) + return UV__ERR(errno); + + /* FIXME(bnoordhuis) Handle EINTR. */ + err = UV_EINVAL; + if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo)) { + *rss = (size_t)psinfo.pr_rssize * 1024; + err = 0; + } + uv__close(fd); + + return err; +} + + +int uv_uptime(double* uptime) { + struct utmp *utmp_buf; + size_t entries = 0; + time_t boot_time; + + boot_time = 0; + utmpname(UTMP_FILE); + + setutent(); + + while ((utmp_buf = getutent()) != NULL) { + if (utmp_buf->ut_user[0] && utmp_buf->ut_type == USER_PROCESS) + ++entries; + if (utmp_buf->ut_type == BOOT_TIME) + boot_time = utmp_buf->ut_time; + } + + endutent(); + + if (boot_time == 0) + return UV_ENOSYS; + + *uptime = time(NULL) - boot_time; + return 0; +} + + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + uv_cpu_info_t* cpu_info; + perfstat_cpu_total_t ps_total; + perfstat_cpu_t* ps_cpus; + perfstat_id_t cpu_id; + int result, ncpus, idx = 0; + + result = perfstat_cpu_total(NULL, &ps_total, sizeof(ps_total), 1); + if (result == -1) { + return UV_ENOSYS; + } + + ncpus = result = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); + if (result == -1) { + return UV_ENOSYS; + } + + ps_cpus = (perfstat_cpu_t*) uv__malloc(ncpus * sizeof(perfstat_cpu_t)); + if (!ps_cpus) { + return UV_ENOMEM; + } + + /* TODO(bnoordhuis) Check uv__strscpy() return value. */ + uv__strscpy(cpu_id.name, FIRST_CPU, sizeof(cpu_id.name)); + result = perfstat_cpu(&cpu_id, ps_cpus, sizeof(perfstat_cpu_t), ncpus); + if (result == -1) { + uv__free(ps_cpus); + return UV_ENOSYS; + } + + *cpu_infos = (uv_cpu_info_t*) uv__malloc(ncpus * sizeof(uv_cpu_info_t)); + if (!*cpu_infos) { + uv__free(ps_cpus); + return UV_ENOMEM; + } + + *count = ncpus; + + cpu_info = *cpu_infos; + while (idx < ncpus) { + cpu_info->speed = (int)(ps_total.processorHZ / 1000000); + cpu_info->model = uv__strdup(ps_total.description); + cpu_info->cpu_times.user = ps_cpus[idx].user; + cpu_info->cpu_times.sys = ps_cpus[idx].sys; + cpu_info->cpu_times.idle = ps_cpus[idx].idle; + cpu_info->cpu_times.irq = ps_cpus[idx].wait; + cpu_info->cpu_times.nice = 0; + cpu_info++; + idx++; + } + + uv__free(ps_cpus); + return 0; +} + + +int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { + uv_interface_address_t* address; + int sockfd, sock6fd, inet6, i, r, size = 1; + struct ifconf ifc; + struct ifreq *ifr, *p, flg; + struct in6_ifreq if6; + struct sockaddr_dl* sa_addr; + + ifc.ifc_req = NULL; + sock6fd = -1; + r = 0; + *count = 0; + *addresses = NULL; + + if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) { + r = UV__ERR(errno); + goto cleanup; + } + + if (0 > (sock6fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP))) { + r = UV__ERR(errno); + goto cleanup; + } + + if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) { + r = UV__ERR(errno); + goto cleanup; + } + + ifc.ifc_req = (struct ifreq*)uv__malloc(size); + if (ifc.ifc_req == NULL) { + r = UV_ENOMEM; + goto cleanup; + } + ifc.ifc_len = size; + if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) { + r = UV__ERR(errno); + goto cleanup; + } + +#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p)) + + /* Count all up and running ipv4/ipv6 addresses */ + ifr = ifc.ifc_req; + while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { + p = ifr; + ifr = (struct ifreq*) + ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr)); + + if (!(p->ifr_addr.sa_family == AF_INET6 || + p->ifr_addr.sa_family == AF_INET)) + continue; + + memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); + if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) { + r = UV__ERR(errno); + goto cleanup; + } + + if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) + continue; + + (*count)++; + } + + if (*count == 0) + goto cleanup; + + /* Alloc the return interface structs */ + *addresses = uv__calloc(*count, sizeof(**addresses)); + if (!(*addresses)) { + r = UV_ENOMEM; + goto cleanup; + } + address = *addresses; + + ifr = ifc.ifc_req; + while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { + p = ifr; + ifr = (struct ifreq*) + ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr)); + + if (!(p->ifr_addr.sa_family == AF_INET6 || + p->ifr_addr.sa_family == AF_INET)) + continue; + + inet6 = (p->ifr_addr.sa_family == AF_INET6); + + memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); + if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) + goto syserror; + + if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) + continue; + + /* All conditions above must match count loop */ + + address->name = uv__strdup(p->ifr_name); + + if (inet6) + address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr); + else + address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr); + + if (inet6) { + memset(&if6, 0, sizeof(if6)); + r = uv__strscpy(if6.ifr_name, p->ifr_name, sizeof(if6.ifr_name)); + if (r == UV_E2BIG) + goto cleanup; + r = 0; + memcpy(&if6.ifr_Addr, &p->ifr_addr, sizeof(if6.ifr_Addr)); + if (ioctl(sock6fd, SIOCGIFNETMASK6, &if6) == -1) + goto syserror; + address->netmask.netmask6 = *((struct sockaddr_in6*) &if6.ifr_Addr); + /* Explicitly set family as the ioctl call appears to return it as 0. */ + address->netmask.netmask6.sin6_family = AF_INET6; + } else { + if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1) + goto syserror; + address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr); + /* Explicitly set family as the ioctl call appears to return it as 0. */ + address->netmask.netmask4.sin_family = AF_INET; + } + + address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0; + + address++; + } + + /* Fill in physical addresses. */ + ifr = ifc.ifc_req; + while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { + p = ifr; + ifr = (struct ifreq*) + ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr)); + + if (p->ifr_addr.sa_family != AF_LINK) + continue; + + address = *addresses; + for (i = 0; i < *count; i++) { + if (strcmp(address->name, p->ifr_name) == 0) { + sa_addr = (struct sockaddr_dl*) &p->ifr_addr; + memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); + } + address++; + } + } + +#undef ADDR_SIZE + goto cleanup; + +syserror: + uv_free_interface_addresses(*addresses, *count); + *addresses = NULL; + *count = 0; + r = UV_ENOSYS; + +cleanup: + if (sockfd != -1) + uv__close(sockfd); + if (sock6fd != -1) + uv__close(sock6fd); + uv__free(ifc.ifc_req); + return r; +} + + +void uv_free_interface_addresses(uv_interface_address_t* addresses, + int count) { + int i; + + for (i = 0; i < count; ++i) { + uv__free(addresses[i].name); + } + + uv__free(addresses); +} + + +void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { + struct pollfd* events; + uintptr_t i; + uintptr_t nfds; + struct poll_ctl pc; + + assert(loop->watchers != NULL); + assert(fd >= 0); + + events = (struct pollfd*) loop->watchers[loop->nwatchers]; + nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; + + if (events != NULL) + /* Invalidate events with same file descriptor */ + for (i = 0; i < nfds; i++) + if ((int) events[i].fd == fd) + events[i].fd = -1; + + /* Remove the file descriptor from the poll set */ + pc.events = 0; + pc.cmd = PS_DELETE; + pc.fd = fd; + if(loop->backend_fd >= 0) + pollset_ctl(loop->backend_fd, &pc, 1); +} diff --git a/external/src/libuv/src/unix/android-ifaddrs.c b/external/src/libuv/src/unix/android-ifaddrs.c new file mode 100644 index 0000000..4765cc0 --- /dev/null +++ b/external/src/libuv/src/unix/android-ifaddrs.c @@ -0,0 +1,713 @@ +/* +Copyright (c) 2013, Kenneth MacKay +Copyright (c) 2014, Emergya (Cloud4all, FP7/2007-2013 grant agreement #289016) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "uv/android-ifaddrs.h" +#include "uv-common.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct NetlinkList +{ + struct NetlinkList *m_next; + struct nlmsghdr *m_data; + unsigned int m_size; +} NetlinkList; + +static int netlink_socket(pid_t *p_pid) +{ + struct sockaddr_nl l_addr; + socklen_t l_len; + + int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); + if(l_socket < 0) + { + return -1; + } + + memset(&l_addr, 0, sizeof(l_addr)); + l_addr.nl_family = AF_NETLINK; + if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0) + { + close(l_socket); + return -1; + } + + l_len = sizeof(l_addr); + if(getsockname(l_socket, (struct sockaddr *)&l_addr, &l_len) < 0) + { + close(l_socket); + return -1; + } + *p_pid = l_addr.nl_pid; + + return l_socket; +} + +static int netlink_send(int p_socket, int p_request) +{ + char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))]; + + struct nlmsghdr *l_hdr; + struct rtgenmsg *l_msg; + struct sockaddr_nl l_addr; + + memset(l_buffer, 0, sizeof(l_buffer)); + + l_hdr = (struct nlmsghdr *)l_buffer; + l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr); + + l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg)); + l_hdr->nlmsg_type = p_request; + l_hdr->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; + l_hdr->nlmsg_pid = 0; + l_hdr->nlmsg_seq = p_socket; + l_msg->rtgen_family = AF_UNSPEC; + + memset(&l_addr, 0, sizeof(l_addr)); + l_addr.nl_family = AF_NETLINK; + return (sendto(p_socket, l_hdr, l_hdr->nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr))); +} + +static int netlink_recv(int p_socket, void *p_buffer, size_t p_len) +{ + struct sockaddr_nl l_addr; + struct msghdr l_msg; + + struct iovec l_iov; + l_iov.iov_base = p_buffer; + l_iov.iov_len = p_len; + + for(;;) + { + int l_result; + l_msg.msg_name = (void *)&l_addr; + l_msg.msg_namelen = sizeof(l_addr); + l_msg.msg_iov = &l_iov; + l_msg.msg_iovlen = 1; + l_msg.msg_control = NULL; + l_msg.msg_controllen = 0; + l_msg.msg_flags = 0; + l_result = recvmsg(p_socket, &l_msg, 0); + + if(l_result < 0) + { + if(errno == EINTR) + { + continue; + } + return -2; + } + + /* Buffer was too small */ + if(l_msg.msg_flags & MSG_TRUNC) + { + return -1; + } + return l_result; + } +} + +static struct nlmsghdr *getNetlinkResponse(int p_socket, pid_t p_pid, int *p_size, int *p_done) +{ + size_t l_size = 4096; + void *l_buffer = NULL; + + for(;;) + { + int l_read; + + uv__free(l_buffer); + l_buffer = uv__malloc(l_size); + if (l_buffer == NULL) + { + return NULL; + } + + l_read = netlink_recv(p_socket, l_buffer, l_size); + *p_size = l_read; + if(l_read == -2) + { + uv__free(l_buffer); + return NULL; + } + if(l_read >= 0) + { + struct nlmsghdr *l_hdr; + for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read)) + { + if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket) + { + continue; + } + + if(l_hdr->nlmsg_type == NLMSG_DONE) + { + *p_done = 1; + break; + } + + if(l_hdr->nlmsg_type == NLMSG_ERROR) + { + uv__free(l_buffer); + return NULL; + } + } + return l_buffer; + } + + l_size *= 2; + } +} + +static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size) +{ + NetlinkList *l_item = uv__malloc(sizeof(NetlinkList)); + if (l_item == NULL) + { + return NULL; + } + + l_item->m_next = NULL; + l_item->m_data = p_data; + l_item->m_size = p_size; + return l_item; +} + +static void freeResultList(NetlinkList *p_list) +{ + NetlinkList *l_cur; + while(p_list) + { + l_cur = p_list; + p_list = p_list->m_next; + uv__free(l_cur->m_data); + uv__free(l_cur); + } +} + +static NetlinkList *getResultList(int p_socket, int p_request, pid_t p_pid) +{ + int l_size; + int l_done; + NetlinkList *l_list; + NetlinkList *l_end; + + if(netlink_send(p_socket, p_request) < 0) + { + return NULL; + } + + l_list = NULL; + l_end = NULL; + + l_done = 0; + while(!l_done) + { + NetlinkList *l_item; + + struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, p_pid, &l_size, &l_done); + /* Error */ + if(!l_hdr) + { + freeResultList(l_list); + return NULL; + } + + l_item = newListItem(l_hdr, l_size); + if (!l_item) + { + freeResultList(l_list); + return NULL; + } + if(!l_list) + { + l_list = l_item; + } + else + { + l_end->m_next = l_item; + } + l_end = l_item; + } + return l_list; +} + +static size_t maxSize(size_t a, size_t b) +{ + return (a > b ? a : b); +} + +static size_t calcAddrLen(sa_family_t p_family, int p_dataSize) +{ + switch(p_family) + { + case AF_INET: + return sizeof(struct sockaddr_in); + case AF_INET6: + return sizeof(struct sockaddr_in6); + case AF_PACKET: + return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize); + default: + return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize); + } +} + +static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size) +{ + switch(p_family) + { + case AF_INET: + memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size); + break; + case AF_INET6: + memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size); + break; + case AF_PACKET: + memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size); + ((struct sockaddr_ll*)p_dest)->sll_halen = p_size; + break; + default: + memcpy(p_dest->sa_data, p_data, p_size); + break; + } + p_dest->sa_family = p_family; +} + +static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry) +{ + if(!*p_resultList) + { + *p_resultList = p_entry; + } + else + { + struct ifaddrs *l_cur = *p_resultList; + while(l_cur->ifa_next) + { + l_cur = l_cur->ifa_next; + } + l_cur->ifa_next = p_entry; + } +} + +static int interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList) +{ + struct ifaddrs *l_entry; + + char *l_index; + char *l_name; + char *l_addr; + char *l_data; + + struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr); + + size_t l_nameSize = 0; + size_t l_addrSize = 0; + size_t l_dataSize = 0; + + size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg)); + struct rtattr *l_rta; + for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) + { + size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); + switch(l_rta->rta_type) + { + case IFLA_ADDRESS: + case IFLA_BROADCAST: + l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize)); + break; + case IFLA_IFNAME: + l_nameSize += NLMSG_ALIGN(l_rtaSize + 1); + break; + case IFLA_STATS: + l_dataSize += NLMSG_ALIGN(l_rtaSize); + break; + default: + break; + } + } + + l_entry = uv__malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize); + if (l_entry == NULL) + { + return -1; + } + memset(l_entry, 0, sizeof(struct ifaddrs)); + l_entry->ifa_name = ""; + + l_index = ((char *)l_entry) + sizeof(struct ifaddrs); + l_name = l_index + sizeof(int); + l_addr = l_name + l_nameSize; + l_data = l_addr + l_addrSize; + + /* Save the interface index so we can look it up when handling the + * addresses. + */ + memcpy(l_index, &l_info->ifi_index, sizeof(int)); + + l_entry->ifa_flags = l_info->ifi_flags; + + l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg)); + for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) + { + void *l_rtaData = RTA_DATA(l_rta); + size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); + switch(l_rta->rta_type) + { + case IFLA_ADDRESS: + case IFLA_BROADCAST: + { + size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize); + makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize); + ((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index; + ((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type; + if(l_rta->rta_type == IFLA_ADDRESS) + { + l_entry->ifa_addr = (struct sockaddr *)l_addr; + } + else + { + l_entry->ifa_broadaddr = (struct sockaddr *)l_addr; + } + l_addr += NLMSG_ALIGN(l_addrLen); + break; + } + case IFLA_IFNAME: + strncpy(l_name, l_rtaData, l_rtaDataSize); + l_name[l_rtaDataSize] = '\0'; + l_entry->ifa_name = l_name; + break; + case IFLA_STATS: + memcpy(l_data, l_rtaData, l_rtaDataSize); + l_entry->ifa_data = l_data; + break; + default: + break; + } + } + + addToEnd(p_resultList, l_entry); + return 0; +} + +static struct ifaddrs *findInterface(int p_index, struct ifaddrs **p_links, int p_numLinks) +{ + int l_num = 0; + struct ifaddrs *l_cur = *p_links; + while(l_cur && l_num < p_numLinks) + { + char *l_indexPtr = ((char *)l_cur) + sizeof(struct ifaddrs); + int l_index; + memcpy(&l_index, l_indexPtr, sizeof(int)); + if(l_index == p_index) + { + return l_cur; + } + + l_cur = l_cur->ifa_next; + ++l_num; + } + return NULL; +} + +static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, int p_numLinks) +{ + struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr); + struct ifaddrs *l_interface = findInterface(l_info->ifa_index, p_resultList, p_numLinks); + + size_t l_nameSize = 0; + size_t l_addrSize = 0; + + int l_addedNetmask = 0; + + size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg)); + struct rtattr *l_rta; + struct ifaddrs *l_entry; + + char *l_name; + char *l_addr; + + for(l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) + { + size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); + if(l_info->ifa_family == AF_PACKET) + { + continue; + } + + switch(l_rta->rta_type) + { + case IFA_ADDRESS: + case IFA_LOCAL: + l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); + if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask) + { + /* Make room for netmask */ + l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); + l_addedNetmask = 1; + } + break; + case IFA_BROADCAST: + l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize)); + break; + case IFA_LABEL: + l_nameSize += NLMSG_ALIGN(l_rtaDataSize + 1); + break; + default: + break; + } + } + + l_entry = uv__malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize); + if (l_entry == NULL) + { + return -1; + } + memset(l_entry, 0, sizeof(struct ifaddrs)); + l_entry->ifa_name = (l_interface ? l_interface->ifa_name : ""); + + l_name = ((char *)l_entry) + sizeof(struct ifaddrs); + l_addr = l_name + l_nameSize; + + l_entry->ifa_flags = l_info->ifa_flags; + if(l_interface) + { + l_entry->ifa_flags |= l_interface->ifa_flags; + } + + l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg)); + for(l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize)) + { + void *l_rtaData = RTA_DATA(l_rta); + size_t l_rtaDataSize = RTA_PAYLOAD(l_rta); + switch(l_rta->rta_type) + { + case IFA_ADDRESS: + case IFA_BROADCAST: + case IFA_LOCAL: + { + size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize); + makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize); + if(l_info->ifa_family == AF_INET6) + { + if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData)) + { + ((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index; + } + } + + /* Apparently in a point-to-point network IFA_ADDRESS contains + * the dest address and IFA_LOCAL contains the local address + */ + if(l_rta->rta_type == IFA_ADDRESS) + { + if(l_entry->ifa_addr) + { + l_entry->ifa_dstaddr = (struct sockaddr *)l_addr; + } + else + { + l_entry->ifa_addr = (struct sockaddr *)l_addr; + } + } + else if(l_rta->rta_type == IFA_LOCAL) + { + if(l_entry->ifa_addr) + { + l_entry->ifa_dstaddr = l_entry->ifa_addr; + } + l_entry->ifa_addr = (struct sockaddr *)l_addr; + } + else + { + l_entry->ifa_broadaddr = (struct sockaddr *)l_addr; + } + l_addr += NLMSG_ALIGN(l_addrLen); + break; + } + case IFA_LABEL: + strncpy(l_name, l_rtaData, l_rtaDataSize); + l_name[l_rtaDataSize] = '\0'; + l_entry->ifa_name = l_name; + break; + default: + break; + } + } + + if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6)) + { + unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128); + unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen); + unsigned char l_mask[16] = {0}; + unsigned i; + for(i=0; i<(l_prefix/8); ++i) + { + l_mask[i] = 0xff; + } + if(l_prefix % 8) + { + l_mask[i] = 0xff << (8 - (l_prefix % 8)); + } + + makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8); + l_entry->ifa_netmask = (struct sockaddr *)l_addr; + } + + addToEnd(p_resultList, l_entry); + return 0; +} + +static int interpretLinks(int p_socket, pid_t p_pid, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList) +{ + + int l_numLinks = 0; + for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next) + { + unsigned int l_nlsize = p_netlinkList->m_size; + struct nlmsghdr *l_hdr; + for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) + { + if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket) + { + continue; + } + + if(l_hdr->nlmsg_type == NLMSG_DONE) + { + break; + } + + if(l_hdr->nlmsg_type == RTM_NEWLINK) + { + if(interpretLink(l_hdr, p_resultList) == -1) + { + return -1; + } + ++l_numLinks; + } + } + } + return l_numLinks; +} + +static int interpretAddrs(int p_socket, pid_t p_pid, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList, int p_numLinks) +{ + for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next) + { + unsigned int l_nlsize = p_netlinkList->m_size; + struct nlmsghdr *l_hdr; + for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize)) + { + if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket) + { + continue; + } + + if(l_hdr->nlmsg_type == NLMSG_DONE) + { + break; + } + + if(l_hdr->nlmsg_type == RTM_NEWADDR) + { + if (interpretAddr(l_hdr, p_resultList, p_numLinks) == -1) + { + return -1; + } + } + } + } + return 0; +} + +int getifaddrs(struct ifaddrs **ifap) +{ + int l_socket; + int l_result; + int l_numLinks; + pid_t l_pid; + NetlinkList *l_linkResults; + NetlinkList *l_addrResults; + + if(!ifap) + { + return -1; + } + *ifap = NULL; + + l_socket = netlink_socket(&l_pid); + if(l_socket < 0) + { + return -1; + } + + l_linkResults = getResultList(l_socket, RTM_GETLINK, l_pid); + if(!l_linkResults) + { + close(l_socket); + return -1; + } + + l_addrResults = getResultList(l_socket, RTM_GETADDR, l_pid); + if(!l_addrResults) + { + close(l_socket); + freeResultList(l_linkResults); + return -1; + } + + l_result = 0; + l_numLinks = interpretLinks(l_socket, l_pid, l_linkResults, ifap); + if(l_numLinks == -1 || interpretAddrs(l_socket, l_pid, l_addrResults, ifap, l_numLinks) == -1) + { + l_result = -1; + } + + freeResultList(l_linkResults); + freeResultList(l_addrResults); + close(l_socket); + return l_result; +} + +void freeifaddrs(struct ifaddrs *ifa) +{ + struct ifaddrs *l_cur; + while(ifa) + { + l_cur = ifa; + ifa = ifa->ifa_next; + uv__free(l_cur); + } +} diff --git a/external/src/libuv/src/unix/async.c b/external/src/libuv/src/unix/async.c new file mode 100644 index 0000000..e1805c3 --- /dev/null +++ b/external/src/libuv/src/unix/async.c @@ -0,0 +1,253 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* This file contains both the uv__async internal infrastructure and the + * user-facing uv_async_t functions. + */ + +#include "uv.h" +#include "internal.h" +#include "atomic-ops.h" + +#include +#include /* snprintf() */ +#include +#include +#include +#include +#include /* sched_yield() */ + +#ifdef __linux__ +#include +#endif + +static void uv__async_send(uv_loop_t* loop); +static int uv__async_start(uv_loop_t* loop); + + +int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { + int err; + + err = uv__async_start(loop); + if (err) + return err; + + uv__handle_init(loop, (uv_handle_t*)handle, UV_ASYNC); + handle->async_cb = async_cb; + handle->pending = 0; + + QUEUE_INSERT_TAIL(&loop->async_handles, &handle->queue); + uv__handle_start(handle); + + return 0; +} + + +int uv_async_send(uv_async_t* handle) { + /* Do a cheap read first. */ + if (ACCESS_ONCE(int, handle->pending) != 0) + return 0; + + /* Tell the other thread we're busy with the handle. */ + if (cmpxchgi(&handle->pending, 0, 1) != 0) + return 0; + + /* Wake up the other thread's event loop. */ + uv__async_send(handle->loop); + + /* Tell the other thread we're done. */ + if (cmpxchgi(&handle->pending, 1, 2) != 1) + abort(); + + return 0; +} + + +/* Only call this from the event loop thread. */ +static int uv__async_spin(uv_async_t* handle) { + int i; + int rc; + + for (;;) { + /* 997 is not completely chosen at random. It's a prime number, acyclical + * by nature, and should therefore hopefully dampen sympathetic resonance. + */ + for (i = 0; i < 997; i++) { + /* rc=0 -- handle is not pending. + * rc=1 -- handle is pending, other thread is still working with it. + * rc=2 -- handle is pending, other thread is done. + */ + rc = cmpxchgi(&handle->pending, 2, 0); + + if (rc != 1) + return rc; + + /* Other thread is busy with this handle, spin until it's done. */ + cpu_relax(); + } + + /* Yield the CPU. We may have preempted the other thread while it's + * inside the critical section and if it's running on the same CPU + * as us, we'll just burn CPU cycles until the end of our time slice. + */ + sched_yield(); + } +} + + +void uv__async_close(uv_async_t* handle) { + uv__async_spin(handle); + QUEUE_REMOVE(&handle->queue); + uv__handle_stop(handle); +} + + +static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { + char buf[1024]; + ssize_t r; + QUEUE queue; + QUEUE* q; + uv_async_t* h; + + assert(w == &loop->async_io_watcher); + + for (;;) { + r = read(w->fd, buf, sizeof(buf)); + + if (r == sizeof(buf)) + continue; + + if (r != -1) + break; + + if (errno == EAGAIN || errno == EWOULDBLOCK) + break; + + if (errno == EINTR) + continue; + + abort(); + } + + QUEUE_MOVE(&loop->async_handles, &queue); + while (!QUEUE_EMPTY(&queue)) { + q = QUEUE_HEAD(&queue); + h = QUEUE_DATA(q, uv_async_t, queue); + + QUEUE_REMOVE(q); + QUEUE_INSERT_TAIL(&loop->async_handles, q); + + if (0 == uv__async_spin(h)) + continue; /* Not pending. */ + + if (h->async_cb == NULL) + continue; + + h->async_cb(h); + } +} + + +static void uv__async_send(uv_loop_t* loop) { + const void* buf; + ssize_t len; + int fd; + int r; + + buf = ""; + len = 1; + fd = loop->async_wfd; + +#if defined(__linux__) + if (fd == -1) { + static const uint64_t val = 1; + buf = &val; + len = sizeof(val); + fd = loop->async_io_watcher.fd; /* eventfd */ + } +#endif + + do + r = write(fd, buf, len); + while (r == -1 && errno == EINTR); + + if (r == len) + return; + + if (r == -1) + if (errno == EAGAIN || errno == EWOULDBLOCK) + return; + + abort(); +} + + +static int uv__async_start(uv_loop_t* loop) { + int pipefd[2]; + int err; + + if (loop->async_io_watcher.fd != -1) + return 0; + +#ifdef __linux__ + err = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); + if (err < 0) + return UV__ERR(errno); + + pipefd[0] = err; + pipefd[1] = -1; +#else + err = uv__make_pipe(pipefd, UV_NONBLOCK_PIPE); + if (err < 0) + return err; +#endif + + uv__io_init(&loop->async_io_watcher, uv__async_io, pipefd[0]); + uv__io_start(loop, &loop->async_io_watcher, POLLIN); + loop->async_wfd = pipefd[1]; + + return 0; +} + + +int uv__async_fork(uv_loop_t* loop) { + if (loop->async_io_watcher.fd == -1) /* never started */ + return 0; + + uv__async_stop(loop); + + return uv__async_start(loop); +} + + +void uv__async_stop(uv_loop_t* loop) { + if (loop->async_io_watcher.fd == -1) + return; + + if (loop->async_wfd != -1) { + if (loop->async_wfd != loop->async_io_watcher.fd) + uv__close(loop->async_wfd); + loop->async_wfd = -1; + } + + uv__io_stop(loop, &loop->async_io_watcher, POLLIN); + uv__close(loop->async_io_watcher.fd); + loop->async_io_watcher.fd = -1; +} diff --git a/external/src/libuv/src/unix/atomic-ops.h b/external/src/libuv/src/unix/atomic-ops.h new file mode 100644 index 0000000..c48d058 --- /dev/null +++ b/external/src/libuv/src/unix/atomic-ops.h @@ -0,0 +1,63 @@ +/* Copyright (c) 2013, Ben Noordhuis + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef UV_ATOMIC_OPS_H_ +#define UV_ATOMIC_OPS_H_ + +#include "internal.h" /* UV_UNUSED */ + +#if defined(__SUNPRO_C) || defined(__SUNPRO_CC) +#include +#endif + +UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)); +UV_UNUSED(static void cpu_relax(void)); + +/* Prefer hand-rolled assembly over the gcc builtins because the latter also + * issue full memory barriers. + */ +UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) { +#if defined(__i386__) || defined(__x86_64__) + int out; + __asm__ __volatile__ ("lock; cmpxchg %2, %1;" + : "=a" (out), "+m" (*(volatile int*) ptr) + : "r" (newval), "0" (oldval) + : "memory"); + return out; +#elif defined(__MVS__) + unsigned int op4; + if (__plo_CSST(ptr, (unsigned int*) &oldval, newval, + (unsigned int*) ptr, *ptr, &op4)) + return oldval; + else + return op4; +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) + return atomic_cas_uint((uint_t *)ptr, (uint_t)oldval, (uint_t)newval); +#else + return __sync_val_compare_and_swap(ptr, oldval, newval); +#endif +} + +UV_UNUSED(static void cpu_relax(void)) { +#if defined(__i386__) || defined(__x86_64__) + __asm__ __volatile__ ("rep; nop" ::: "memory"); /* a.k.a. PAUSE */ +#elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__) + __asm__ __volatile__ ("yield" ::: "memory"); +#elif defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) + __asm__ __volatile__ ("or 1,1,1; or 2,2,2" ::: "memory"); +#endif +} + +#endif /* UV_ATOMIC_OPS_H_ */ diff --git a/external/src/libuv/src/unix/bsd-ifaddrs.c b/external/src/libuv/src/unix/bsd-ifaddrs.c new file mode 100644 index 0000000..e48934b --- /dev/null +++ b/external/src/libuv/src/unix/bsd-ifaddrs.c @@ -0,0 +1,163 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +#include +#include +#if !defined(__CYGWIN__) && !defined(__MSYS__) +#include +#endif + +#if defined(__HAIKU__) +#define IFF_RUNNING IFF_LINK +#endif + +static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) { + if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) + return 1; + if (ent->ifa_addr == NULL) + return 1; +#if !defined(__CYGWIN__) && !defined(__MSYS__) + /* + * If `exclude_type` is `UV__EXCLUDE_IFPHYS`, return whether `sa_family` + * equals `AF_LINK`. Otherwise, the result depends on the operating + * system with `AF_LINK` or `PF_INET`. + */ + if (exclude_type == UV__EXCLUDE_IFPHYS) + return (ent->ifa_addr->sa_family != AF_LINK); +#endif +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) || \ + defined(__HAIKU__) + /* + * On BSD getifaddrs returns information related to the raw underlying + * devices. We're not interested in this information. + */ + if (ent->ifa_addr->sa_family == AF_LINK) + return 1; +#elif defined(__NetBSD__) || defined(__OpenBSD__) + if (ent->ifa_addr->sa_family != PF_INET && + ent->ifa_addr->sa_family != PF_INET6) + return 1; +#endif + return 0; +} + +int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { + struct ifaddrs* addrs; + struct ifaddrs* ent; + uv_interface_address_t* address; +#if !(defined(__CYGWIN__) || defined(__MSYS__)) + int i; +#endif + + *count = 0; + *addresses = NULL; + + if (getifaddrs(&addrs) != 0) + return UV__ERR(errno); + + /* Count the number of interfaces */ + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR)) + continue; + (*count)++; + } + + if (*count == 0) { + freeifaddrs(addrs); + return 0; + } + + /* Make sure the memory is initiallized to zero using calloc() */ + *addresses = uv__calloc(*count, sizeof(**addresses)); + + if (*addresses == NULL) { + freeifaddrs(addrs); + return UV_ENOMEM; + } + + address = *addresses; + + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR)) + continue; + + address->name = uv__strdup(ent->ifa_name); + + if (ent->ifa_addr->sa_family == AF_INET6) { + address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); + } else { + address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); + } + + if (ent->ifa_netmask == NULL) { + memset(&address->netmask, 0, sizeof(address->netmask)); + } else if (ent->ifa_netmask->sa_family == AF_INET6) { + address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); + } else { + address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); + } + + address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); + + address++; + } + +#if !(defined(__CYGWIN__) || defined(__MSYS__)) + /* Fill in physical addresses for each interface */ + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS)) + continue; + + address = *addresses; + + for (i = 0; i < *count; i++) { + if (strcmp(address->name, ent->ifa_name) == 0) { + struct sockaddr_dl* sa_addr; + sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); + memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); + } + address++; + } + } +#endif + + freeifaddrs(addrs); + + return 0; +} + + +void uv_free_interface_addresses(uv_interface_address_t* addresses, + int count) { + int i; + + for (i = 0; i < count; i++) { + uv__free(addresses[i].name); + } + + uv__free(addresses); +} diff --git a/external/src/libuv/src/unix/bsd-proctitle.c b/external/src/libuv/src/unix/bsd-proctitle.c new file mode 100644 index 0000000..723b81c --- /dev/null +++ b/external/src/libuv/src/unix/bsd-proctitle.c @@ -0,0 +1,100 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + + +static uv_mutex_t process_title_mutex; +static uv_once_t process_title_mutex_once = UV_ONCE_INIT; +static char* process_title; + + +static void init_process_title_mutex_once(void) { + if (uv_mutex_init(&process_title_mutex)) + abort(); +} + + +void uv__process_title_cleanup(void) { + /* TODO(bnoordhuis) uv_mutex_destroy(&process_title_mutex) + * and reset process_title_mutex_once? + */ +} + + +char** uv_setup_args(int argc, char** argv) { + process_title = argc > 0 ? uv__strdup(argv[0]) : NULL; + return argv; +} + + +int uv_set_process_title(const char* title) { + char* new_title; + + new_title = uv__strdup(title); + if (new_title == NULL) + return UV_ENOMEM; + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + uv__free(process_title); + process_title = new_title; + setproctitle("%s", title); + + uv_mutex_unlock(&process_title_mutex); + + return 0; +} + + +int uv_get_process_title(char* buffer, size_t size) { + size_t len; + + if (buffer == NULL || size == 0) + return UV_EINVAL; + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + if (process_title != NULL) { + len = strlen(process_title) + 1; + + if (size < len) { + uv_mutex_unlock(&process_title_mutex); + return UV_ENOBUFS; + } + + memcpy(buffer, process_title, len); + } else { + len = 0; + } + + uv_mutex_unlock(&process_title_mutex); + + buffer[len] = '\0'; + + return 0; +} diff --git a/external/src/libuv/src/unix/core.c b/external/src/libuv/src/unix/core.c new file mode 100644 index 0000000..71e9c52 --- /dev/null +++ b/external/src/libuv/src/unix/core.c @@ -0,0 +1,1623 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include /* NULL */ +#include /* printf */ +#include +#include /* strerror */ +#include +#include +#include +#include +#include +#include /* O_CLOEXEC */ +#include +#include +#include +#include +#include +#include /* INT_MAX, PATH_MAX, IOV_MAX */ +#include /* writev */ +#include /* getrusage */ +#include +#include +#include + +#ifdef __sun +# include +# include +# include +#endif + +#if defined(__APPLE__) +# include +# endif /* defined(__APPLE__) */ + + +#if defined(__APPLE__) && !TARGET_OS_IPHONE +# include +# include /* _NSGetExecutablePath */ +# define environ (*_NSGetEnviron()) +#else /* defined(__APPLE__) && !TARGET_OS_IPHONE */ +extern char** environ; +#endif /* !(defined(__APPLE__) && !TARGET_OS_IPHONE) */ + + +#if defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || \ + defined(__NetBSD__) || \ + defined(__OpenBSD__) +# include +# include +# include +# if defined(__FreeBSD__) +# define uv__accept4 accept4 +# endif +# if defined(__NetBSD__) +# define uv__accept4(a, b, c, d) paccept((a), (b), (c), NULL, (d)) +# endif +#endif + +#if defined(__MVS__) +#include +#endif + +#if defined(__linux__) +# include +# define uv__accept4 accept4 +#endif + +#if defined(__linux__) && defined(__SANITIZE_THREAD__) && defined(__clang__) +# include +#endif + +static int uv__run_pending(uv_loop_t* loop); + +/* Verify that uv_buf_t is ABI-compatible with struct iovec. */ +STATIC_ASSERT(sizeof(uv_buf_t) == sizeof(struct iovec)); +STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->base) == + sizeof(((struct iovec*) 0)->iov_base)); +STATIC_ASSERT(sizeof(&((uv_buf_t*) 0)->len) == + sizeof(((struct iovec*) 0)->iov_len)); +STATIC_ASSERT(offsetof(uv_buf_t, base) == offsetof(struct iovec, iov_base)); +STATIC_ASSERT(offsetof(uv_buf_t, len) == offsetof(struct iovec, iov_len)); + + +uint64_t uv_hrtime(void) { + return uv__hrtime(UV_CLOCK_PRECISE); +} + + +void uv_close(uv_handle_t* handle, uv_close_cb close_cb) { + assert(!uv__is_closing(handle)); + + handle->flags |= UV_HANDLE_CLOSING; + handle->close_cb = close_cb; + + switch (handle->type) { + case UV_NAMED_PIPE: + uv__pipe_close((uv_pipe_t*)handle); + break; + + case UV_TTY: + uv__stream_close((uv_stream_t*)handle); + break; + + case UV_TCP: + uv__tcp_close((uv_tcp_t*)handle); + break; + + case UV_UDP: + uv__udp_close((uv_udp_t*)handle); + break; + + case UV_PREPARE: + uv__prepare_close((uv_prepare_t*)handle); + break; + + case UV_CHECK: + uv__check_close((uv_check_t*)handle); + break; + + case UV_IDLE: + uv__idle_close((uv_idle_t*)handle); + break; + + case UV_ASYNC: + uv__async_close((uv_async_t*)handle); + break; + + case UV_TIMER: + uv__timer_close((uv_timer_t*)handle); + break; + + case UV_PROCESS: + uv__process_close((uv_process_t*)handle); + break; + + case UV_FS_EVENT: + uv__fs_event_close((uv_fs_event_t*)handle); + break; + + case UV_POLL: + uv__poll_close((uv_poll_t*)handle); + break; + + case UV_FS_POLL: + uv__fs_poll_close((uv_fs_poll_t*)handle); + /* Poll handles use file system requests, and one of them may still be + * running. The poll code will call uv__make_close_pending() for us. */ + return; + + case UV_SIGNAL: + uv__signal_close((uv_signal_t*) handle); + break; + + default: + assert(0); + } + + uv__make_close_pending(handle); +} + +int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) { + int r; + int fd; + socklen_t len; + + if (handle == NULL || value == NULL) + return UV_EINVAL; + + if (handle->type == UV_TCP || handle->type == UV_NAMED_PIPE) + fd = uv__stream_fd((uv_stream_t*) handle); + else if (handle->type == UV_UDP) + fd = ((uv_udp_t *) handle)->io_watcher.fd; + else + return UV_ENOTSUP; + + len = sizeof(*value); + + if (*value == 0) + r = getsockopt(fd, SOL_SOCKET, optname, value, &len); + else + r = setsockopt(fd, SOL_SOCKET, optname, (const void*) value, len); + + if (r < 0) + return UV__ERR(errno); + + return 0; +} + +void uv__make_close_pending(uv_handle_t* handle) { + assert(handle->flags & UV_HANDLE_CLOSING); + assert(!(handle->flags & UV_HANDLE_CLOSED)); + handle->next_closing = handle->loop->closing_handles; + handle->loop->closing_handles = handle; +} + +int uv__getiovmax(void) { +#if defined(IOV_MAX) + return IOV_MAX; +#elif defined(_SC_IOV_MAX) + static int iovmax_cached = -1; + int iovmax; + + iovmax = uv__load_relaxed(&iovmax_cached); + if (iovmax != -1) + return iovmax; + + /* On some embedded devices (arm-linux-uclibc based ip camera), + * sysconf(_SC_IOV_MAX) can not get the correct value. The return + * value is -1 and the errno is EINPROGRESS. Degrade the value to 1. + */ + iovmax = sysconf(_SC_IOV_MAX); + if (iovmax == -1) + iovmax = 1; + + uv__store_relaxed(&iovmax_cached, iovmax); + + return iovmax; +#else + return 1024; +#endif +} + + +static void uv__finish_close(uv_handle_t* handle) { + uv_signal_t* sh; + + /* Note: while the handle is in the UV_HANDLE_CLOSING state now, it's still + * possible for it to be active in the sense that uv__is_active() returns + * true. + * + * A good example is when the user calls uv_shutdown(), immediately followed + * by uv_close(). The handle is considered active at this point because the + * completion of the shutdown req is still pending. + */ + assert(handle->flags & UV_HANDLE_CLOSING); + assert(!(handle->flags & UV_HANDLE_CLOSED)); + handle->flags |= UV_HANDLE_CLOSED; + + switch (handle->type) { + case UV_PREPARE: + case UV_CHECK: + case UV_IDLE: + case UV_ASYNC: + case UV_TIMER: + case UV_PROCESS: + case UV_FS_EVENT: + case UV_FS_POLL: + case UV_POLL: + break; + + case UV_SIGNAL: + /* If there are any caught signals "trapped" in the signal pipe, + * we can't call the close callback yet. Reinserting the handle + * into the closing queue makes the event loop spin but that's + * okay because we only need to deliver the pending events. + */ + sh = (uv_signal_t*) handle; + if (sh->caught_signals > sh->dispatched_signals) { + handle->flags ^= UV_HANDLE_CLOSED; + uv__make_close_pending(handle); /* Back into the queue. */ + return; + } + break; + + case UV_NAMED_PIPE: + case UV_TCP: + case UV_TTY: + uv__stream_destroy((uv_stream_t*)handle); + break; + + case UV_UDP: + uv__udp_finish_close((uv_udp_t*)handle); + break; + + default: + assert(0); + break; + } + + uv__handle_unref(handle); + QUEUE_REMOVE(&handle->handle_queue); + + if (handle->close_cb) { + handle->close_cb(handle); + } +} + + +static void uv__run_closing_handles(uv_loop_t* loop) { + uv_handle_t* p; + uv_handle_t* q; + + p = loop->closing_handles; + loop->closing_handles = NULL; + + while (p) { + q = p->next_closing; + uv__finish_close(p); + p = q; + } +} + + +int uv_is_closing(const uv_handle_t* handle) { + return uv__is_closing(handle); +} + + +int uv_backend_fd(const uv_loop_t* loop) { + return loop->backend_fd; +} + + +int uv_backend_timeout(const uv_loop_t* loop) { + if (loop->stop_flag != 0) + return 0; + + if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop)) + return 0; + + if (!QUEUE_EMPTY(&loop->idle_handles)) + return 0; + + if (!QUEUE_EMPTY(&loop->pending_queue)) + return 0; + + if (loop->closing_handles) + return 0; + + return uv__next_timeout(loop); +} + + +static int uv__loop_alive(const uv_loop_t* loop) { + return uv__has_active_handles(loop) || + uv__has_active_reqs(loop) || + loop->closing_handles != NULL; +} + + +int uv_loop_alive(const uv_loop_t* loop) { + return uv__loop_alive(loop); +} + + +int uv_run(uv_loop_t* loop, uv_run_mode mode) { + int timeout; + int r; + int ran_pending; + + r = uv__loop_alive(loop); + if (!r) + uv__update_time(loop); + + while (r != 0 && loop->stop_flag == 0) { + uv__update_time(loop); + uv__run_timers(loop); + ran_pending = uv__run_pending(loop); + uv__run_idle(loop); + uv__run_prepare(loop); + + timeout = 0; + if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT) + timeout = uv_backend_timeout(loop); + + uv__io_poll(loop, timeout); + + /* Run one final update on the provider_idle_time in case uv__io_poll + * returned because the timeout expired, but no events were received. This + * call will be ignored if the provider_entry_time was either never set (if + * the timeout == 0) or was already updated b/c an event was received. + */ + uv__metrics_update_idle_time(loop); + + uv__run_check(loop); + uv__run_closing_handles(loop); + + if (mode == UV_RUN_ONCE) { + /* UV_RUN_ONCE implies forward progress: at least one callback must have + * been invoked when it returns. uv__io_poll() can return without doing + * I/O (meaning: no callbacks) when its timeout expires - which means we + * have pending timers that satisfy the forward progress constraint. + * + * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from + * the check. + */ + uv__update_time(loop); + uv__run_timers(loop); + } + + r = uv__loop_alive(loop); + if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT) + break; + } + + /* The if statement lets gcc compile it to a conditional store. Avoids + * dirtying a cache line. + */ + if (loop->stop_flag != 0) + loop->stop_flag = 0; + + return r; +} + + +void uv_update_time(uv_loop_t* loop) { + uv__update_time(loop); +} + + +int uv_is_active(const uv_handle_t* handle) { + return uv__is_active(handle); +} + + +/* Open a socket in non-blocking close-on-exec mode, atomically if possible. */ +int uv__socket(int domain, int type, int protocol) { + int sockfd; + int err; + +#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC) + sockfd = socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol); + if (sockfd != -1) + return sockfd; + + if (errno != EINVAL) + return UV__ERR(errno); +#endif + + sockfd = socket(domain, type, protocol); + if (sockfd == -1) + return UV__ERR(errno); + + err = uv__nonblock(sockfd, 1); + if (err == 0) + err = uv__cloexec(sockfd, 1); + + if (err) { + uv__close(sockfd); + return err; + } + +#if defined(SO_NOSIGPIPE) + { + int on = 1; + setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on)); + } +#endif + + return sockfd; +} + +/* get a file pointer to a file in read-only and close-on-exec mode */ +FILE* uv__open_file(const char* path) { + int fd; + FILE* fp; + + fd = uv__open_cloexec(path, O_RDONLY); + if (fd < 0) + return NULL; + + fp = fdopen(fd, "r"); + if (fp == NULL) + uv__close(fd); + + return fp; +} + + +int uv__accept(int sockfd) { + int peerfd; + int err; + + (void) &err; + assert(sockfd >= 0); + + do +#ifdef uv__accept4 + peerfd = uv__accept4(sockfd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC); +#else + peerfd = accept(sockfd, NULL, NULL); +#endif + while (peerfd == -1 && errno == EINTR); + + if (peerfd == -1) + return UV__ERR(errno); + +#ifndef uv__accept4 + err = uv__cloexec(peerfd, 1); + if (err == 0) + err = uv__nonblock(peerfd, 1); + + if (err != 0) { + uv__close(peerfd); + return err; + } +#endif + + return peerfd; +} + + +/* close() on macos has the "interesting" quirk that it fails with EINTR + * without closing the file descriptor when a thread is in the cancel state. + * That's why libuv calls close$NOCANCEL() instead. + * + * glibc on linux has a similar issue: close() is a cancellation point and + * will unwind the thread when it's in the cancel state. Work around that + * by making the system call directly. Musl libc is unaffected. + */ +int uv__close_nocancel(int fd) { +#if defined(__APPLE__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdollar-in-identifier-extension" +#if defined(__LP64__) || TARGET_OS_IPHONE + extern int close$NOCANCEL(int); + return close$NOCANCEL(fd); +#else + extern int close$NOCANCEL$UNIX2003(int); + return close$NOCANCEL$UNIX2003(fd); +#endif +#pragma GCC diagnostic pop +#elif defined(__linux__) && defined(__SANITIZE_THREAD__) && defined(__clang__) + long rc; + __sanitizer_syscall_pre_close(fd); + rc = syscall(SYS_close, fd); + __sanitizer_syscall_post_close(rc, fd); + return rc; +#elif defined(__linux__) && !defined(__SANITIZE_THREAD__) + return syscall(SYS_close, fd); +#else + return close(fd); +#endif +} + + +int uv__close_nocheckstdio(int fd) { + int saved_errno; + int rc; + + assert(fd > -1); /* Catch uninitialized io_watcher.fd bugs. */ + + saved_errno = errno; + rc = uv__close_nocancel(fd); + if (rc == -1) { + rc = UV__ERR(errno); + if (rc == UV_EINTR || rc == UV__ERR(EINPROGRESS)) + rc = 0; /* The close is in progress, not an error. */ + errno = saved_errno; + } + + return rc; +} + + +int uv__close(int fd) { + assert(fd > STDERR_FILENO); /* Catch stdio close bugs. */ +#if defined(__MVS__) + SAVE_ERRNO(epoll_file_close(fd)); +#endif + return uv__close_nocheckstdio(fd); +} + +#if UV__NONBLOCK_IS_IOCTL +int uv__nonblock_ioctl(int fd, int set) { + int r; + + do + r = ioctl(fd, FIONBIO, &set); + while (r == -1 && errno == EINTR); + + if (r) + return UV__ERR(errno); + + return 0; +} + + +int uv__cloexec_ioctl(int fd, int set) { + int r; + + do + r = ioctl(fd, set ? FIOCLEX : FIONCLEX); + while (r == -1 && errno == EINTR); + + if (r) + return UV__ERR(errno); + + return 0; +} +#endif + + +int uv__nonblock_fcntl(int fd, int set) { + int flags; + int r; + + do + r = fcntl(fd, F_GETFL); + while (r == -1 && errno == EINTR); + + if (r == -1) + return UV__ERR(errno); + + /* Bail out now if already set/clear. */ + if (!!(r & O_NONBLOCK) == !!set) + return 0; + + if (set) + flags = r | O_NONBLOCK; + else + flags = r & ~O_NONBLOCK; + + do + r = fcntl(fd, F_SETFL, flags); + while (r == -1 && errno == EINTR); + + if (r) + return UV__ERR(errno); + + return 0; +} + + +int uv__cloexec_fcntl(int fd, int set) { + int flags; + int r; + + do + r = fcntl(fd, F_GETFD); + while (r == -1 && errno == EINTR); + + if (r == -1) + return UV__ERR(errno); + + /* Bail out now if already set/clear. */ + if (!!(r & FD_CLOEXEC) == !!set) + return 0; + + if (set) + flags = r | FD_CLOEXEC; + else + flags = r & ~FD_CLOEXEC; + + do + r = fcntl(fd, F_SETFD, flags); + while (r == -1 && errno == EINTR); + + if (r) + return UV__ERR(errno); + + return 0; +} + + +ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) { + struct cmsghdr* cmsg; + ssize_t rc; + int* pfd; + int* end; +#if defined(__linux__) + static int no_msg_cmsg_cloexec; + if (0 == uv__load_relaxed(&no_msg_cmsg_cloexec)) { + rc = recvmsg(fd, msg, flags | 0x40000000); /* MSG_CMSG_CLOEXEC */ + if (rc != -1) + return rc; + if (errno != EINVAL) + return UV__ERR(errno); + rc = recvmsg(fd, msg, flags); + if (rc == -1) + return UV__ERR(errno); + uv__store_relaxed(&no_msg_cmsg_cloexec, 1); + } else { + rc = recvmsg(fd, msg, flags); + } +#else + rc = recvmsg(fd, msg, flags); +#endif + if (rc == -1) + return UV__ERR(errno); + if (msg->msg_controllen == 0) + return rc; + for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) + if (cmsg->cmsg_type == SCM_RIGHTS) + for (pfd = (int*) CMSG_DATA(cmsg), + end = (int*) ((char*) cmsg + cmsg->cmsg_len); + pfd < end; + pfd += 1) + uv__cloexec(*pfd, 1); + return rc; +} + + +int uv_cwd(char* buffer, size_t* size) { + char scratch[1 + UV__PATH_MAX]; + + if (buffer == NULL || size == NULL) + return UV_EINVAL; + + /* Try to read directly into the user's buffer first... */ + if (getcwd(buffer, *size) != NULL) + goto fixup; + + if (errno != ERANGE) + return UV__ERR(errno); + + /* ...or into scratch space if the user's buffer is too small + * so we can report how much space to provide on the next try. + */ + if (getcwd(scratch, sizeof(scratch)) == NULL) + return UV__ERR(errno); + + buffer = scratch; + +fixup: + + *size = strlen(buffer); + + if (*size > 1 && buffer[*size - 1] == '/') { + *size -= 1; + buffer[*size] = '\0'; + } + + if (buffer == scratch) { + *size += 1; + return UV_ENOBUFS; + } + + return 0; +} + + +int uv_chdir(const char* dir) { + if (chdir(dir)) + return UV__ERR(errno); + + return 0; +} + + +void uv_disable_stdio_inheritance(void) { + int fd; + + /* Set the CLOEXEC flag on all open descriptors. Unconditionally try the + * first 16 file descriptors. After that, bail out after the first error. + */ + for (fd = 0; ; fd++) + if (uv__cloexec(fd, 1) && fd > 15) + break; +} + + +int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) { + int fd_out; + + switch (handle->type) { + case UV_TCP: + case UV_NAMED_PIPE: + case UV_TTY: + fd_out = uv__stream_fd((uv_stream_t*) handle); + break; + + case UV_UDP: + fd_out = ((uv_udp_t *) handle)->io_watcher.fd; + break; + + case UV_POLL: + fd_out = ((uv_poll_t *) handle)->io_watcher.fd; + break; + + default: + return UV_EINVAL; + } + + if (uv__is_closing(handle) || fd_out == -1) + return UV_EBADF; + + *fd = fd_out; + return 0; +} + + +static int uv__run_pending(uv_loop_t* loop) { + QUEUE* q; + QUEUE pq; + uv__io_t* w; + + if (QUEUE_EMPTY(&loop->pending_queue)) + return 0; + + QUEUE_MOVE(&loop->pending_queue, &pq); + + while (!QUEUE_EMPTY(&pq)) { + q = QUEUE_HEAD(&pq); + QUEUE_REMOVE(q); + QUEUE_INIT(q); + w = QUEUE_DATA(q, uv__io_t, pending_queue); + w->cb(loop, w, POLLOUT); + } + + return 1; +} + + +static unsigned int next_power_of_two(unsigned int val) { + val -= 1; + val |= val >> 1; + val |= val >> 2; + val |= val >> 4; + val |= val >> 8; + val |= val >> 16; + val += 1; + return val; +} + +static void maybe_resize(uv_loop_t* loop, unsigned int len) { + uv__io_t** watchers; + void* fake_watcher_list; + void* fake_watcher_count; + unsigned int nwatchers; + unsigned int i; + + if (len <= loop->nwatchers) + return; + + /* Preserve fake watcher list and count at the end of the watchers */ + if (loop->watchers != NULL) { + fake_watcher_list = loop->watchers[loop->nwatchers]; + fake_watcher_count = loop->watchers[loop->nwatchers + 1]; + } else { + fake_watcher_list = NULL; + fake_watcher_count = NULL; + } + + nwatchers = next_power_of_two(len + 2) - 2; + watchers = uv__reallocf(loop->watchers, + (nwatchers + 2) * sizeof(loop->watchers[0])); + + if (watchers == NULL) + abort(); + for (i = loop->nwatchers; i < nwatchers; i++) + watchers[i] = NULL; + watchers[nwatchers] = fake_watcher_list; + watchers[nwatchers + 1] = fake_watcher_count; + + loop->watchers = watchers; + loop->nwatchers = nwatchers; +} + + +void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) { + assert(cb != NULL); + assert(fd >= -1); + QUEUE_INIT(&w->pending_queue); + QUEUE_INIT(&w->watcher_queue); + w->cb = cb; + w->fd = fd; + w->events = 0; + w->pevents = 0; + +#if defined(UV_HAVE_KQUEUE) + w->rcount = 0; + w->wcount = 0; +#endif /* defined(UV_HAVE_KQUEUE) */ +} + + +void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) { + assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI))); + assert(0 != events); + assert(w->fd >= 0); + assert(w->fd < INT_MAX); + + w->pevents |= events; + maybe_resize(loop, w->fd + 1); + +#if !defined(__sun) + /* The event ports backend needs to rearm all file descriptors on each and + * every tick of the event loop but the other backends allow us to + * short-circuit here if the event mask is unchanged. + */ + if (w->events == w->pevents) + return; +#endif + + if (QUEUE_EMPTY(&w->watcher_queue)) + QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); + + if (loop->watchers[w->fd] == NULL) { + loop->watchers[w->fd] = w; + loop->nfds++; + } +} + + +void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) { + assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI))); + assert(0 != events); + + if (w->fd == -1) + return; + + assert(w->fd >= 0); + + /* Happens when uv__io_stop() is called on a handle that was never started. */ + if ((unsigned) w->fd >= loop->nwatchers) + return; + + w->pevents &= ~events; + + if (w->pevents == 0) { + QUEUE_REMOVE(&w->watcher_queue); + QUEUE_INIT(&w->watcher_queue); + w->events = 0; + + if (w == loop->watchers[w->fd]) { + assert(loop->nfds > 0); + loop->watchers[w->fd] = NULL; + loop->nfds--; + } + } + else if (QUEUE_EMPTY(&w->watcher_queue)) + QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); +} + + +void uv__io_close(uv_loop_t* loop, uv__io_t* w) { + uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI); + QUEUE_REMOVE(&w->pending_queue); + + /* Remove stale events for this file descriptor */ + if (w->fd != -1) + uv__platform_invalidate_fd(loop, w->fd); +} + + +void uv__io_feed(uv_loop_t* loop, uv__io_t* w) { + if (QUEUE_EMPTY(&w->pending_queue)) + QUEUE_INSERT_TAIL(&loop->pending_queue, &w->pending_queue); +} + + +int uv__io_active(const uv__io_t* w, unsigned int events) { + assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI))); + assert(0 != events); + return 0 != (w->pevents & events); +} + + +int uv__fd_exists(uv_loop_t* loop, int fd) { + return (unsigned) fd < loop->nwatchers && loop->watchers[fd] != NULL; +} + + +int uv_getrusage(uv_rusage_t* rusage) { + struct rusage usage; + + if (getrusage(RUSAGE_SELF, &usage)) + return UV__ERR(errno); + + rusage->ru_utime.tv_sec = usage.ru_utime.tv_sec; + rusage->ru_utime.tv_usec = usage.ru_utime.tv_usec; + + rusage->ru_stime.tv_sec = usage.ru_stime.tv_sec; + rusage->ru_stime.tv_usec = usage.ru_stime.tv_usec; + +#if !defined(__MVS__) && !defined(__HAIKU__) + rusage->ru_maxrss = usage.ru_maxrss; + rusage->ru_ixrss = usage.ru_ixrss; + rusage->ru_idrss = usage.ru_idrss; + rusage->ru_isrss = usage.ru_isrss; + rusage->ru_minflt = usage.ru_minflt; + rusage->ru_majflt = usage.ru_majflt; + rusage->ru_nswap = usage.ru_nswap; + rusage->ru_inblock = usage.ru_inblock; + rusage->ru_oublock = usage.ru_oublock; + rusage->ru_msgsnd = usage.ru_msgsnd; + rusage->ru_msgrcv = usage.ru_msgrcv; + rusage->ru_nsignals = usage.ru_nsignals; + rusage->ru_nvcsw = usage.ru_nvcsw; + rusage->ru_nivcsw = usage.ru_nivcsw; +#endif + + return 0; +} + + +int uv__open_cloexec(const char* path, int flags) { +#if defined(O_CLOEXEC) + int fd; + + fd = open(path, flags | O_CLOEXEC); + if (fd == -1) + return UV__ERR(errno); + + return fd; +#else /* O_CLOEXEC */ + int err; + int fd; + + fd = open(path, flags); + if (fd == -1) + return UV__ERR(errno); + + err = uv__cloexec(fd, 1); + if (err) { + uv__close(fd); + return err; + } + + return fd; +#endif /* O_CLOEXEC */ +} + + +int uv__dup2_cloexec(int oldfd, int newfd) { +#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__linux__) + int r; + + r = dup3(oldfd, newfd, O_CLOEXEC); + if (r == -1) + return UV__ERR(errno); + + return r; +#else + int err; + int r; + + r = dup2(oldfd, newfd); /* Never retry. */ + if (r == -1) + return UV__ERR(errno); + + err = uv__cloexec(newfd, 1); + if (err != 0) { + uv__close(newfd); + return err; + } + + return r; +#endif +} + + +int uv_os_homedir(char* buffer, size_t* size) { + uv_passwd_t pwd; + size_t len; + int r; + + /* Check if the HOME environment variable is set first. The task of + performing input validation on buffer and size is taken care of by + uv_os_getenv(). */ + r = uv_os_getenv("HOME", buffer, size); + + if (r != UV_ENOENT) + return r; + + /* HOME is not set, so call uv__getpwuid_r() */ + r = uv__getpwuid_r(&pwd); + + if (r != 0) { + return r; + } + + len = strlen(pwd.homedir); + + if (len >= *size) { + *size = len + 1; + uv_os_free_passwd(&pwd); + return UV_ENOBUFS; + } + + memcpy(buffer, pwd.homedir, len + 1); + *size = len; + uv_os_free_passwd(&pwd); + + return 0; +} + + +int uv_os_tmpdir(char* buffer, size_t* size) { + const char* buf; + size_t len; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + +#define CHECK_ENV_VAR(name) \ + do { \ + buf = getenv(name); \ + if (buf != NULL) \ + goto return_buffer; \ + } \ + while (0) + + /* Check the TMPDIR, TMP, TEMP, and TEMPDIR environment variables in order */ + CHECK_ENV_VAR("TMPDIR"); + CHECK_ENV_VAR("TMP"); + CHECK_ENV_VAR("TEMP"); + CHECK_ENV_VAR("TEMPDIR"); + +#undef CHECK_ENV_VAR + + /* No temp environment variables defined */ + #if defined(__ANDROID__) + buf = "/data/local/tmp"; + #else + buf = "/tmp"; + #endif + +return_buffer: + len = strlen(buf); + + if (len >= *size) { + *size = len + 1; + return UV_ENOBUFS; + } + + /* The returned directory should not have a trailing slash. */ + if (len > 1 && buf[len - 1] == '/') { + len--; + } + + memcpy(buffer, buf, len + 1); + buffer[len] = '\0'; + *size = len; + + return 0; +} + + +int uv__getpwuid_r(uv_passwd_t* pwd) { + struct passwd pw; + struct passwd* result; + char* buf; + uid_t uid; + size_t bufsize; + size_t name_size; + size_t homedir_size; + size_t shell_size; + long initsize; + int r; + + if (pwd == NULL) + return UV_EINVAL; + + initsize = sysconf(_SC_GETPW_R_SIZE_MAX); + + if (initsize <= 0) + bufsize = 4096; + else + bufsize = (size_t) initsize; + + uid = geteuid(); + buf = NULL; + + for (;;) { + uv__free(buf); + buf = uv__malloc(bufsize); + + if (buf == NULL) + return UV_ENOMEM; + + do + r = getpwuid_r(uid, &pw, buf, bufsize, &result); + while (r == EINTR); + + if (r != ERANGE) + break; + + bufsize *= 2; + } + + if (r != 0) { + uv__free(buf); + return UV__ERR(r); + } + + if (result == NULL) { + uv__free(buf); + return UV_ENOENT; + } + + /* Allocate memory for the username, shell, and home directory */ + name_size = strlen(pw.pw_name) + 1; + homedir_size = strlen(pw.pw_dir) + 1; + shell_size = strlen(pw.pw_shell) + 1; + pwd->username = uv__malloc(name_size + homedir_size + shell_size); + + if (pwd->username == NULL) { + uv__free(buf); + return UV_ENOMEM; + } + + /* Copy the username */ + memcpy(pwd->username, pw.pw_name, name_size); + + /* Copy the home directory */ + pwd->homedir = pwd->username + name_size; + memcpy(pwd->homedir, pw.pw_dir, homedir_size); + + /* Copy the shell */ + pwd->shell = pwd->homedir + homedir_size; + memcpy(pwd->shell, pw.pw_shell, shell_size); + + /* Copy the uid and gid */ + pwd->uid = pw.pw_uid; + pwd->gid = pw.pw_gid; + + uv__free(buf); + + return 0; +} + + +void uv_os_free_passwd(uv_passwd_t* pwd) { + if (pwd == NULL) + return; + + /* + The memory for name, shell, and homedir are allocated in a single + uv__malloc() call. The base of the pointer is stored in pwd->username, so + that is the field that needs to be freed. + */ + uv__free(pwd->username); + pwd->username = NULL; + pwd->shell = NULL; + pwd->homedir = NULL; +} + + +int uv_os_get_passwd(uv_passwd_t* pwd) { + return uv__getpwuid_r(pwd); +} + + +int uv_translate_sys_error(int sys_errno) { + /* If < 0 then it's already a libuv error. */ + return sys_errno <= 0 ? sys_errno : -sys_errno; +} + + +int uv_os_environ(uv_env_item_t** envitems, int* count) { + int i, j, cnt; + uv_env_item_t* envitem; + + *envitems = NULL; + *count = 0; + + for (i = 0; environ[i] != NULL; i++); + + *envitems = uv__calloc(i, sizeof(**envitems)); + + if (*envitems == NULL) + return UV_ENOMEM; + + for (j = 0, cnt = 0; j < i; j++) { + char* buf; + char* ptr; + + if (environ[j] == NULL) + break; + + buf = uv__strdup(environ[j]); + if (buf == NULL) + goto fail; + + ptr = strchr(buf, '='); + if (ptr == NULL) { + uv__free(buf); + continue; + } + + *ptr = '\0'; + + envitem = &(*envitems)[cnt]; + envitem->name = buf; + envitem->value = ptr + 1; + + cnt++; + } + + *count = cnt; + return 0; + +fail: + for (i = 0; i < cnt; i++) { + envitem = &(*envitems)[cnt]; + uv__free(envitem->name); + } + uv__free(*envitems); + + *envitems = NULL; + *count = 0; + return UV_ENOMEM; +} + + +int uv_os_getenv(const char* name, char* buffer, size_t* size) { + char* var; + size_t len; + + if (name == NULL || buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + var = getenv(name); + + if (var == NULL) + return UV_ENOENT; + + len = strlen(var); + + if (len >= *size) { + *size = len + 1; + return UV_ENOBUFS; + } + + memcpy(buffer, var, len + 1); + *size = len; + + return 0; +} + + +int uv_os_setenv(const char* name, const char* value) { + if (name == NULL || value == NULL) + return UV_EINVAL; + + if (setenv(name, value, 1) != 0) + return UV__ERR(errno); + + return 0; +} + + +int uv_os_unsetenv(const char* name) { + if (name == NULL) + return UV_EINVAL; + + if (unsetenv(name) != 0) + return UV__ERR(errno); + + return 0; +} + + +int uv_os_gethostname(char* buffer, size_t* size) { + /* + On some platforms, if the input buffer is not large enough, gethostname() + succeeds, but truncates the result. libuv can detect this and return ENOBUFS + instead by creating a large enough buffer and comparing the hostname length + to the size input. + */ + char buf[UV_MAXHOSTNAMESIZE]; + size_t len; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + if (gethostname(buf, sizeof(buf)) != 0) + return UV__ERR(errno); + + buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */ + len = strlen(buf); + + if (len >= *size) { + *size = len + 1; + return UV_ENOBUFS; + } + + memcpy(buffer, buf, len + 1); + *size = len; + return 0; +} + + +uv_os_fd_t uv_get_osfhandle(int fd) { + return fd; +} + +int uv_open_osfhandle(uv_os_fd_t os_fd) { + return os_fd; +} + +uv_pid_t uv_os_getpid(void) { + return getpid(); +} + + +uv_pid_t uv_os_getppid(void) { + return getppid(); +} + + +int uv_os_getpriority(uv_pid_t pid, int* priority) { + int r; + + if (priority == NULL) + return UV_EINVAL; + + errno = 0; + r = getpriority(PRIO_PROCESS, (int) pid); + + if (r == -1 && errno != 0) + return UV__ERR(errno); + + *priority = r; + return 0; +} + + +int uv_os_setpriority(uv_pid_t pid, int priority) { + if (priority < UV_PRIORITY_HIGHEST || priority > UV_PRIORITY_LOW) + return UV_EINVAL; + + if (setpriority(PRIO_PROCESS, (int) pid, priority) != 0) + return UV__ERR(errno); + + return 0; +} + + +int uv_os_uname(uv_utsname_t* buffer) { + struct utsname buf; + int r; + + if (buffer == NULL) + return UV_EINVAL; + + if (uname(&buf) == -1) { + r = UV__ERR(errno); + goto error; + } + + r = uv__strscpy(buffer->sysname, buf.sysname, sizeof(buffer->sysname)); + if (r == UV_E2BIG) + goto error; + +#ifdef _AIX + r = snprintf(buffer->release, + sizeof(buffer->release), + "%s.%s", + buf.version, + buf.release); + if (r >= sizeof(buffer->release)) { + r = UV_E2BIG; + goto error; + } +#else + r = uv__strscpy(buffer->release, buf.release, sizeof(buffer->release)); + if (r == UV_E2BIG) + goto error; +#endif + + r = uv__strscpy(buffer->version, buf.version, sizeof(buffer->version)); + if (r == UV_E2BIG) + goto error; + +#if defined(_AIX) || defined(__PASE__) + r = uv__strscpy(buffer->machine, "ppc64", sizeof(buffer->machine)); +#else + r = uv__strscpy(buffer->machine, buf.machine, sizeof(buffer->machine)); +#endif + + if (r == UV_E2BIG) + goto error; + + return 0; + +error: + buffer->sysname[0] = '\0'; + buffer->release[0] = '\0'; + buffer->version[0] = '\0'; + buffer->machine[0] = '\0'; + return r; +} + +int uv__getsockpeername(const uv_handle_t* handle, + uv__peersockfunc func, + struct sockaddr* name, + int* namelen) { + socklen_t socklen; + uv_os_fd_t fd; + int r; + + r = uv_fileno(handle, &fd); + if (r < 0) + return r; + + /* sizeof(socklen_t) != sizeof(int) on some systems. */ + socklen = (socklen_t) *namelen; + + if (func(fd, name, &socklen)) + return UV__ERR(errno); + + *namelen = (int) socklen; + return 0; +} + +int uv_gettimeofday(uv_timeval64_t* tv) { + struct timeval time; + + if (tv == NULL) + return UV_EINVAL; + + if (gettimeofday(&time, NULL) != 0) + return UV__ERR(errno); + + tv->tv_sec = (int64_t) time.tv_sec; + tv->tv_usec = (int32_t) time.tv_usec; + return 0; +} + +void uv_sleep(unsigned int msec) { + struct timespec timeout; + int rc; + + timeout.tv_sec = msec / 1000; + timeout.tv_nsec = (msec % 1000) * 1000 * 1000; + + do + rc = nanosleep(&timeout, &timeout); + while (rc == -1 && errno == EINTR); + + assert(rc == 0); +} + +int uv__search_path(const char* prog, char* buf, size_t* buflen) { + char abspath[UV__PATH_MAX]; + size_t abspath_size; + char trypath[UV__PATH_MAX]; + char* cloned_path; + char* path_env; + char* token; + + if (buf == NULL || buflen == NULL || *buflen == 0) + return UV_EINVAL; + + /* + * Possibilities for prog: + * i) an absolute path such as: /home/user/myprojects/nodejs/node + * ii) a relative path such as: ./node or ../myprojects/nodejs/node + * iii) a bare filename such as "node", after exporting PATH variable + * to its location. + */ + + /* Case i) and ii) absolute or relative paths */ + if (strchr(prog, '/') != NULL) { + if (realpath(prog, abspath) != abspath) + return UV__ERR(errno); + + abspath_size = strlen(abspath); + + *buflen -= 1; + if (*buflen > abspath_size) + *buflen = abspath_size; + + memcpy(buf, abspath, *buflen); + buf[*buflen] = '\0'; + + return 0; + } + + /* Case iii). Search PATH environment variable */ + cloned_path = NULL; + token = NULL; + path_env = getenv("PATH"); + + if (path_env == NULL) + return UV_EINVAL; + + cloned_path = uv__strdup(path_env); + if (cloned_path == NULL) + return UV_ENOMEM; + + token = strtok(cloned_path, ":"); + while (token != NULL) { + snprintf(trypath, sizeof(trypath) - 1, "%s/%s", token, prog); + if (realpath(trypath, abspath) == abspath) { + /* Check the match is executable */ + if (access(abspath, X_OK) == 0) { + abspath_size = strlen(abspath); + + *buflen -= 1; + if (*buflen > abspath_size) + *buflen = abspath_size; + + memcpy(buf, abspath, *buflen); + buf[*buflen] = '\0'; + + uv__free(cloned_path); + return 0; + } + } + token = strtok(NULL, ":"); + } + uv__free(cloned_path); + + /* Out of tokens (path entries), and no match found */ + return UV_EINVAL; +} diff --git a/external/src/libuv/src/unix/cygwin.c b/external/src/libuv/src/unix/cygwin.c new file mode 100644 index 0000000..169958d --- /dev/null +++ b/external/src/libuv/src/unix/cygwin.c @@ -0,0 +1,53 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +int uv_uptime(double* uptime) { + struct sysinfo info; + + if (sysinfo(&info) < 0) + return UV__ERR(errno); + + *uptime = info.uptime; + return 0; +} + +int uv_resident_set_memory(size_t* rss) { + /* FIXME: read /proc/meminfo? */ + *rss = 0; + return 0; +} + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + /* FIXME: read /proc/stat? */ + *cpu_infos = NULL; + *count = 0; + return UV_ENOSYS; +} + +uint64_t uv_get_constrained_memory(void) { + return 0; /* Memory constraints are unknown. */ +} diff --git a/external/src/libuv/src/unix/darwin-proctitle.c b/external/src/libuv/src/unix/darwin-proctitle.c new file mode 100644 index 0000000..5288083 --- /dev/null +++ b/external/src/libuv/src/unix/darwin-proctitle.c @@ -0,0 +1,192 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include + +#include + +#if !TARGET_OS_IPHONE +#include "darwin-stub.h" +#endif + + +static int uv__pthread_setname_np(const char* name) { + char namebuf[64]; /* MAXTHREADNAMESIZE */ + int err; + + strncpy(namebuf, name, sizeof(namebuf) - 1); + namebuf[sizeof(namebuf) - 1] = '\0'; + + err = pthread_setname_np(namebuf); + if (err) + return UV__ERR(err); + + return 0; +} + + +int uv__set_process_title(const char* title) { +#if TARGET_OS_IPHONE + return uv__pthread_setname_np(title); +#else + CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef, + const char*, + CFStringEncoding); + CFBundleRef (*pCFBundleGetBundleWithIdentifier)(CFStringRef); + void *(*pCFBundleGetDataPointerForName)(CFBundleRef, CFStringRef); + void *(*pCFBundleGetFunctionPointerForName)(CFBundleRef, CFStringRef); + CFTypeRef (*pLSGetCurrentApplicationASN)(void); + OSStatus (*pLSSetApplicationInformationItem)(int, + CFTypeRef, + CFStringRef, + CFStringRef, + CFDictionaryRef*); + void* application_services_handle; + void* core_foundation_handle; + CFBundleRef launch_services_bundle; + CFStringRef* display_name_key; + CFDictionaryRef (*pCFBundleGetInfoDictionary)(CFBundleRef); + CFBundleRef (*pCFBundleGetMainBundle)(void); + CFDictionaryRef (*pLSApplicationCheckIn)(int, CFDictionaryRef); + void (*pLSSetApplicationLaunchServicesServerConnectionStatus)(uint64_t, + void*); + CFTypeRef asn; + int err; + + err = UV_ENOENT; + application_services_handle = dlopen("/System/Library/Frameworks/" + "ApplicationServices.framework/" + "Versions/A/ApplicationServices", + RTLD_LAZY | RTLD_LOCAL); + core_foundation_handle = dlopen("/System/Library/Frameworks/" + "CoreFoundation.framework/" + "Versions/A/CoreFoundation", + RTLD_LAZY | RTLD_LOCAL); + + if (application_services_handle == NULL || core_foundation_handle == NULL) + goto out; + + *(void **)(&pCFStringCreateWithCString) = + dlsym(core_foundation_handle, "CFStringCreateWithCString"); + *(void **)(&pCFBundleGetBundleWithIdentifier) = + dlsym(core_foundation_handle, "CFBundleGetBundleWithIdentifier"); + *(void **)(&pCFBundleGetDataPointerForName) = + dlsym(core_foundation_handle, "CFBundleGetDataPointerForName"); + *(void **)(&pCFBundleGetFunctionPointerForName) = + dlsym(core_foundation_handle, "CFBundleGetFunctionPointerForName"); + + if (pCFStringCreateWithCString == NULL || + pCFBundleGetBundleWithIdentifier == NULL || + pCFBundleGetDataPointerForName == NULL || + pCFBundleGetFunctionPointerForName == NULL) { + goto out; + } + +#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8) + + launch_services_bundle = + pCFBundleGetBundleWithIdentifier(S("com.apple.LaunchServices")); + + if (launch_services_bundle == NULL) + goto out; + + *(void **)(&pLSGetCurrentApplicationASN) = + pCFBundleGetFunctionPointerForName(launch_services_bundle, + S("_LSGetCurrentApplicationASN")); + + if (pLSGetCurrentApplicationASN == NULL) + goto out; + + *(void **)(&pLSSetApplicationInformationItem) = + pCFBundleGetFunctionPointerForName(launch_services_bundle, + S("_LSSetApplicationInformationItem")); + + if (pLSSetApplicationInformationItem == NULL) + goto out; + + display_name_key = pCFBundleGetDataPointerForName(launch_services_bundle, + S("_kLSDisplayNameKey")); + + if (display_name_key == NULL || *display_name_key == NULL) + goto out; + + *(void **)(&pCFBundleGetInfoDictionary) = dlsym(core_foundation_handle, + "CFBundleGetInfoDictionary"); + *(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle, + "CFBundleGetMainBundle"); + if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL) + goto out; + + *(void **)(&pLSApplicationCheckIn) = pCFBundleGetFunctionPointerForName( + launch_services_bundle, + S("_LSApplicationCheckIn")); + + if (pLSApplicationCheckIn == NULL) + goto out; + + *(void **)(&pLSSetApplicationLaunchServicesServerConnectionStatus) = + pCFBundleGetFunctionPointerForName( + launch_services_bundle, + S("_LSSetApplicationLaunchServicesServerConnectionStatus")); + + if (pLSSetApplicationLaunchServicesServerConnectionStatus == NULL) + goto out; + + pLSSetApplicationLaunchServicesServerConnectionStatus(0, NULL); + + /* Check into process manager?! */ + pLSApplicationCheckIn(-2, + pCFBundleGetInfoDictionary(pCFBundleGetMainBundle())); + + asn = pLSGetCurrentApplicationASN(); + + err = UV_EBUSY; + if (asn == NULL) + goto out; + + err = UV_EINVAL; + if (pLSSetApplicationInformationItem(-2, /* Magic value. */ + asn, + *display_name_key, + S(title), + NULL) != noErr) { + goto out; + } + + uv__pthread_setname_np(title); /* Don't care if it fails. */ + err = 0; + +out: + if (core_foundation_handle != NULL) + dlclose(core_foundation_handle); + + if (application_services_handle != NULL) + dlclose(application_services_handle); + + return err; +#endif /* !TARGET_OS_IPHONE */ +} diff --git a/external/src/libuv/src/unix/darwin-stub.h b/external/src/libuv/src/unix/darwin-stub.h new file mode 100644 index 0000000..433e3ef --- /dev/null +++ b/external/src/libuv/src/unix/darwin-stub.h @@ -0,0 +1,113 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_DARWIN_STUB_H_ +#define UV_DARWIN_STUB_H_ + +#include + +struct CFArrayCallBacks; +struct CFRunLoopSourceContext; +struct FSEventStreamContext; +struct CFRange; + +typedef double CFAbsoluteTime; +typedef double CFTimeInterval; +typedef int FSEventStreamEventFlags; +typedef int OSStatus; +typedef long CFIndex; +typedef struct CFArrayCallBacks CFArrayCallBacks; +typedef struct CFRunLoopSourceContext CFRunLoopSourceContext; +typedef struct FSEventStreamContext FSEventStreamContext; +typedef uint32_t FSEventStreamCreateFlags; +typedef uint64_t FSEventStreamEventId; +typedef unsigned CFStringEncoding; +typedef void* CFAllocatorRef; +typedef void* CFArrayRef; +typedef void* CFBundleRef; +typedef void* CFDataRef; +typedef void* CFDictionaryRef; +typedef void* CFMutableDictionaryRef; +typedef struct CFRange CFRange; +typedef void* CFRunLoopRef; +typedef void* CFRunLoopSourceRef; +typedef void* CFStringRef; +typedef void* CFTypeRef; +typedef void* FSEventStreamRef; + +typedef uint32_t IOOptionBits; +typedef unsigned int io_iterator_t; +typedef unsigned int io_object_t; +typedef unsigned int io_service_t; +typedef unsigned int io_registry_entry_t; + + +typedef void (*FSEventStreamCallback)(const FSEventStreamRef, + void*, + size_t, + void*, + const FSEventStreamEventFlags*, + const FSEventStreamEventId*); + +struct CFRunLoopSourceContext { + CFIndex version; + void* info; + void* pad[7]; + void (*perform)(void*); +}; + +struct FSEventStreamContext { + CFIndex version; + void* info; + void* pad[3]; +}; + +struct CFRange { + CFIndex location; + CFIndex length; +}; + +static const CFStringEncoding kCFStringEncodingUTF8 = 0x8000100; +static const OSStatus noErr = 0; + +static const FSEventStreamEventId kFSEventStreamEventIdSinceNow = -1; + +static const int kFSEventStreamCreateFlagNoDefer = 2; +static const int kFSEventStreamCreateFlagFileEvents = 16; + +static const int kFSEventStreamEventFlagEventIdsWrapped = 8; +static const int kFSEventStreamEventFlagHistoryDone = 16; +static const int kFSEventStreamEventFlagItemChangeOwner = 0x4000; +static const int kFSEventStreamEventFlagItemCreated = 0x100; +static const int kFSEventStreamEventFlagItemFinderInfoMod = 0x2000; +static const int kFSEventStreamEventFlagItemInodeMetaMod = 0x400; +static const int kFSEventStreamEventFlagItemIsDir = 0x20000; +static const int kFSEventStreamEventFlagItemModified = 0x1000; +static const int kFSEventStreamEventFlagItemRemoved = 0x200; +static const int kFSEventStreamEventFlagItemRenamed = 0x800; +static const int kFSEventStreamEventFlagItemXattrMod = 0x8000; +static const int kFSEventStreamEventFlagKernelDropped = 4; +static const int kFSEventStreamEventFlagMount = 64; +static const int kFSEventStreamEventFlagRootChanged = 32; +static const int kFSEventStreamEventFlagUnmount = 128; +static const int kFSEventStreamEventFlagUserDropped = 2; + +#endif /* UV_DARWIN_STUB_H_ */ diff --git a/external/src/libuv/src/unix/darwin.c b/external/src/libuv/src/unix/darwin.c new file mode 100644 index 0000000..a7be0dd --- /dev/null +++ b/external/src/libuv/src/unix/darwin.c @@ -0,0 +1,375 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include + +#include +#include +#include +#include /* _NSGetExecutablePath */ +#include +#include +#include /* sysconf */ + +#include "darwin-stub.h" + +static uv_once_t once = UV_ONCE_INIT; +static uint64_t (*time_func)(void); +static mach_timebase_info_data_t timebase; + +typedef unsigned char UInt8; + +int uv__platform_loop_init(uv_loop_t* loop) { + loop->cf_state = NULL; + + if (uv__kqueue_init(loop)) + return UV__ERR(errno); + + return 0; +} + + +void uv__platform_loop_delete(uv_loop_t* loop) { + uv__fsevents_loop_delete(loop); +} + + +static void uv__hrtime_init_once(void) { + if (KERN_SUCCESS != mach_timebase_info(&timebase)) + abort(); + + time_func = (uint64_t (*)(void)) dlsym(RTLD_DEFAULT, "mach_continuous_time"); + if (time_func == NULL) + time_func = mach_absolute_time; +} + + +uint64_t uv__hrtime(uv_clocktype_t type) { + uv_once(&once, uv__hrtime_init_once); + return time_func() * timebase.numer / timebase.denom; +} + + +int uv_exepath(char* buffer, size_t* size) { + /* realpath(exepath) may be > PATH_MAX so double it to be on the safe side. */ + char abspath[PATH_MAX * 2 + 1]; + char exepath[PATH_MAX + 1]; + uint32_t exepath_size; + size_t abspath_size; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + exepath_size = sizeof(exepath); + if (_NSGetExecutablePath(exepath, &exepath_size)) + return UV_EIO; + + if (realpath(exepath, abspath) != abspath) + return UV__ERR(errno); + + abspath_size = strlen(abspath); + if (abspath_size == 0) + return UV_EIO; + + *size -= 1; + if (*size > abspath_size) + *size = abspath_size; + + memcpy(buffer, abspath, *size); + buffer[*size] = '\0'; + + return 0; +} + + +uint64_t uv_get_free_memory(void) { + vm_statistics_data_t info; + mach_msg_type_number_t count = sizeof(info) / sizeof(integer_t); + + if (host_statistics(mach_host_self(), HOST_VM_INFO, + (host_info_t)&info, &count) != KERN_SUCCESS) { + return UV_EINVAL; /* FIXME(bnoordhuis) Translate error. */ + } + + return (uint64_t) info.free_count * sysconf(_SC_PAGESIZE); +} + + +uint64_t uv_get_total_memory(void) { + uint64_t info; + int which[] = {CTL_HW, HW_MEMSIZE}; + size_t size = sizeof(info); + + if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0)) + return UV__ERR(errno); + + return (uint64_t) info; +} + + +uint64_t uv_get_constrained_memory(void) { + return 0; /* Memory constraints are unknown. */ +} + + +void uv_loadavg(double avg[3]) { + struct loadavg info; + size_t size = sizeof(info); + int which[] = {CTL_VM, VM_LOADAVG}; + + if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0) < 0) return; + + avg[0] = (double) info.ldavg[0] / info.fscale; + avg[1] = (double) info.ldavg[1] / info.fscale; + avg[2] = (double) info.ldavg[2] / info.fscale; +} + + +int uv_resident_set_memory(size_t* rss) { + mach_msg_type_number_t count; + task_basic_info_data_t info; + kern_return_t err; + + count = TASK_BASIC_INFO_COUNT; + err = task_info(mach_task_self(), + TASK_BASIC_INFO, + (task_info_t) &info, + &count); + (void) &err; + /* task_info(TASK_BASIC_INFO) cannot really fail. Anything other than + * KERN_SUCCESS implies a libuv bug. + */ + assert(err == KERN_SUCCESS); + *rss = info.resident_size; + + return 0; +} + + +int uv_uptime(double* uptime) { + time_t now; + struct timeval info; + size_t size = sizeof(info); + static int which[] = {CTL_KERN, KERN_BOOTTIME}; + + if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0)) + return UV__ERR(errno); + + now = time(NULL); + *uptime = now - info.tv_sec; + + return 0; +} + +static int uv__get_cpu_speed(uint64_t* speed) { + /* IOKit */ + void (*pIOObjectRelease)(io_object_t); + kern_return_t (*pIOMasterPort)(mach_port_t, mach_port_t*); + CFMutableDictionaryRef (*pIOServiceMatching)(const char*); + kern_return_t (*pIOServiceGetMatchingServices)(mach_port_t, + CFMutableDictionaryRef, + io_iterator_t*); + io_service_t (*pIOIteratorNext)(io_iterator_t); + CFTypeRef (*pIORegistryEntryCreateCFProperty)(io_registry_entry_t, + CFStringRef, + CFAllocatorRef, + IOOptionBits); + + /* CoreFoundation */ + CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef, + const char*, + CFStringEncoding); + CFStringEncoding (*pCFStringGetSystemEncoding)(void); + UInt8 *(*pCFDataGetBytePtr)(CFDataRef); + CFIndex (*pCFDataGetLength)(CFDataRef); + void (*pCFDataGetBytes)(CFDataRef, CFRange, UInt8*); + void (*pCFRelease)(CFTypeRef); + + void* core_foundation_handle; + void* iokit_handle; + int err; + + kern_return_t kr; + mach_port_t mach_port; + io_iterator_t it; + io_object_t service; + + mach_port = 0; + + err = UV_ENOENT; + core_foundation_handle = dlopen("/System/Library/Frameworks/" + "CoreFoundation.framework/" + "CoreFoundation", + RTLD_LAZY | RTLD_LOCAL); + iokit_handle = dlopen("/System/Library/Frameworks/IOKit.framework/" + "IOKit", + RTLD_LAZY | RTLD_LOCAL); + + if (core_foundation_handle == NULL || iokit_handle == NULL) + goto out; + +#define V(handle, symbol) \ + do { \ + *(void **)(&p ## symbol) = dlsym((handle), #symbol); \ + if (p ## symbol == NULL) \ + goto out; \ + } \ + while (0) + V(iokit_handle, IOMasterPort); + V(iokit_handle, IOServiceMatching); + V(iokit_handle, IOServiceGetMatchingServices); + V(iokit_handle, IOIteratorNext); + V(iokit_handle, IOObjectRelease); + V(iokit_handle, IORegistryEntryCreateCFProperty); + V(core_foundation_handle, CFStringCreateWithCString); + V(core_foundation_handle, CFStringGetSystemEncoding); + V(core_foundation_handle, CFDataGetBytePtr); + V(core_foundation_handle, CFDataGetLength); + V(core_foundation_handle, CFDataGetBytes); + V(core_foundation_handle, CFRelease); +#undef V + +#define S(s) pCFStringCreateWithCString(NULL, (s), kCFStringEncodingUTF8) + + kr = pIOMasterPort(MACH_PORT_NULL, &mach_port); + assert(kr == KERN_SUCCESS); + CFMutableDictionaryRef classes_to_match + = pIOServiceMatching("IOPlatformDevice"); + kr = pIOServiceGetMatchingServices(mach_port, classes_to_match, &it); + assert(kr == KERN_SUCCESS); + service = pIOIteratorNext(it); + + CFStringRef device_type_str = S("device_type"); + CFStringRef clock_frequency_str = S("clock-frequency"); + + while (service != 0) { + CFDataRef data; + data = pIORegistryEntryCreateCFProperty(service, + device_type_str, + NULL, + 0); + if (data) { + const UInt8* raw = pCFDataGetBytePtr(data); + if (strncmp((char*)raw, "cpu", 3) == 0 || + strncmp((char*)raw, "processor", 9) == 0) { + CFDataRef freq_ref; + freq_ref = pIORegistryEntryCreateCFProperty(service, + clock_frequency_str, + NULL, + 0); + if (freq_ref) { + uint32_t freq; + CFIndex len = pCFDataGetLength(freq_ref); + CFRange range; + range.location = 0; + range.length = len; + + pCFDataGetBytes(freq_ref, range, (UInt8*)&freq); + *speed = freq; + pCFRelease(freq_ref); + pCFRelease(data); + break; + } + } + pCFRelease(data); + } + + service = pIOIteratorNext(it); + } + + pIOObjectRelease(it); + + err = 0; + + if (device_type_str != NULL) + pCFRelease(device_type_str); + if (clock_frequency_str != NULL) + pCFRelease(clock_frequency_str); + +out: + if (core_foundation_handle != NULL) + dlclose(core_foundation_handle); + + if (iokit_handle != NULL) + dlclose(iokit_handle); + + mach_port_deallocate(mach_task_self(), mach_port); + + return err; +} + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), + multiplier = ((uint64_t)1000L / ticks); + char model[512]; + size_t size; + unsigned int i; + natural_t numcpus; + mach_msg_type_number_t msg_type; + processor_cpu_load_info_data_t *info; + uv_cpu_info_t* cpu_info; + uint64_t cpuspeed; + int err; + + size = sizeof(model); + if (sysctlbyname("machdep.cpu.brand_string", &model, &size, NULL, 0) && + sysctlbyname("hw.model", &model, &size, NULL, 0)) { + return UV__ERR(errno); + } + + err = uv__get_cpu_speed(&cpuspeed); + if (err < 0) + return err; + + if (host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO, &numcpus, + (processor_info_array_t*)&info, + &msg_type) != KERN_SUCCESS) { + return UV_EINVAL; /* FIXME(bnoordhuis) Translate error. */ + } + + *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); + if (!(*cpu_infos)) { + vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type); + return UV_ENOMEM; + } + + *count = numcpus; + + for (i = 0; i < numcpus; i++) { + cpu_info = &(*cpu_infos)[i]; + + cpu_info->cpu_times.user = (uint64_t)(info[i].cpu_ticks[0]) * multiplier; + cpu_info->cpu_times.nice = (uint64_t)(info[i].cpu_ticks[3]) * multiplier; + cpu_info->cpu_times.sys = (uint64_t)(info[i].cpu_ticks[1]) * multiplier; + cpu_info->cpu_times.idle = (uint64_t)(info[i].cpu_ticks[2]) * multiplier; + cpu_info->cpu_times.irq = 0; + + cpu_info->model = uv__strdup(model); + cpu_info->speed = cpuspeed/1000000; + } + vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type); + + return 0; +} diff --git a/external/src/libuv/src/unix/dl.c b/external/src/libuv/src/unix/dl.c new file mode 100644 index 0000000..fc1c052 --- /dev/null +++ b/external/src/libuv/src/unix/dl.c @@ -0,0 +1,80 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include + +static int uv__dlerror(uv_lib_t* lib); + + +int uv_dlopen(const char* filename, uv_lib_t* lib) { + dlerror(); /* Reset error status. */ + lib->errmsg = NULL; + lib->handle = dlopen(filename, RTLD_LAZY); + return lib->handle ? 0 : uv__dlerror(lib); +} + + +void uv_dlclose(uv_lib_t* lib) { + uv__free(lib->errmsg); + lib->errmsg = NULL; + + if (lib->handle) { + /* Ignore errors. No good way to signal them without leaking memory. */ + dlclose(lib->handle); + lib->handle = NULL; + } +} + + +int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) { + dlerror(); /* Reset error status. */ + *ptr = dlsym(lib->handle, name); + return uv__dlerror(lib); +} + + +const char* uv_dlerror(const uv_lib_t* lib) { + return lib->errmsg ? lib->errmsg : "no error"; +} + + +static int uv__dlerror(uv_lib_t* lib) { + const char* errmsg; + + uv__free(lib->errmsg); + + errmsg = dlerror(); + + if (errmsg) { + lib->errmsg = uv__strdup(errmsg); + return -1; + } + else { + lib->errmsg = NULL; + return 0; + } +} diff --git a/external/src/libuv/src/unix/epoll.c b/external/src/libuv/src/unix/epoll.c new file mode 100644 index 0000000..97348e2 --- /dev/null +++ b/external/src/libuv/src/unix/epoll.c @@ -0,0 +1,422 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" +#include +#include + +int uv__epoll_init(uv_loop_t* loop) { + int fd; + fd = epoll_create1(O_CLOEXEC); + + /* epoll_create1() can fail either because it's not implemented (old kernel) + * or because it doesn't understand the O_CLOEXEC flag. + */ + if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) { + fd = epoll_create(256); + + if (fd != -1) + uv__cloexec(fd, 1); + } + + loop->backend_fd = fd; + if (fd == -1) + return UV__ERR(errno); + + return 0; +} + + +void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { + struct epoll_event* events; + struct epoll_event dummy; + uintptr_t i; + uintptr_t nfds; + + assert(loop->watchers != NULL); + assert(fd >= 0); + + events = (struct epoll_event*) loop->watchers[loop->nwatchers]; + nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; + if (events != NULL) + /* Invalidate events with same file descriptor */ + for (i = 0; i < nfds; i++) + if (events[i].data.fd == fd) + events[i].data.fd = -1; + + /* Remove the file descriptor from the epoll. + * This avoids a problem where the same file description remains open + * in another process, causing repeated junk epoll events. + * + * We pass in a dummy epoll_event, to work around a bug in old kernels. + */ + if (loop->backend_fd >= 0) { + /* Work around a bug in kernels 3.10 to 3.19 where passing a struct that + * has the EPOLLWAKEUP flag set generates spurious audit syslog warnings. + */ + memset(&dummy, 0, sizeof(dummy)); + epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &dummy); + } +} + + +int uv__io_check_fd(uv_loop_t* loop, int fd) { + struct epoll_event e; + int rc; + + memset(&e, 0, sizeof(e)); + e.events = POLLIN; + e.data.fd = -1; + + rc = 0; + if (epoll_ctl(loop->backend_fd, EPOLL_CTL_ADD, fd, &e)) + if (errno != EEXIST) + rc = UV__ERR(errno); + + if (rc == 0) + if (epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &e)) + abort(); + + return rc; +} + + +void uv__io_poll(uv_loop_t* loop, int timeout) { + /* A bug in kernels < 2.6.37 makes timeouts larger than ~30 minutes + * effectively infinite on 32 bits architectures. To avoid blocking + * indefinitely, we cap the timeout and poll again if necessary. + * + * Note that "30 minutes" is a simplification because it depends on + * the value of CONFIG_HZ. The magic constant assumes CONFIG_HZ=1200, + * that being the largest value I have seen in the wild (and only once.) + */ + static const int max_safe_timeout = 1789569; + static int no_epoll_pwait_cached; + static int no_epoll_wait_cached; + int no_epoll_pwait; + int no_epoll_wait; + struct epoll_event events[1024]; + struct epoll_event* pe; + struct epoll_event e; + int real_timeout; + QUEUE* q; + uv__io_t* w; + sigset_t sigset; + uint64_t sigmask; + uint64_t base; + int have_signals; + int nevents; + int count; + int nfds; + int fd; + int op; + int i; + int user_timeout; + int reset_timeout; + + if (loop->nfds == 0) { + assert(QUEUE_EMPTY(&loop->watcher_queue)); + return; + } + + memset(&e, 0, sizeof(e)); + + while (!QUEUE_EMPTY(&loop->watcher_queue)) { + q = QUEUE_HEAD(&loop->watcher_queue); + QUEUE_REMOVE(q); + QUEUE_INIT(q); + + w = QUEUE_DATA(q, uv__io_t, watcher_queue); + assert(w->pevents != 0); + assert(w->fd >= 0); + assert(w->fd < (int) loop->nwatchers); + + e.events = w->pevents; + e.data.fd = w->fd; + + if (w->events == 0) + op = EPOLL_CTL_ADD; + else + op = EPOLL_CTL_MOD; + + /* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching + * events, skip the syscall and squelch the events after epoll_wait(). + */ + if (epoll_ctl(loop->backend_fd, op, w->fd, &e)) { + if (errno != EEXIST) + abort(); + + assert(op == EPOLL_CTL_ADD); + + /* We've reactivated a file descriptor that's been watched before. */ + if (epoll_ctl(loop->backend_fd, EPOLL_CTL_MOD, w->fd, &e)) + abort(); + } + + w->events = w->pevents; + } + + sigmask = 0; + if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { + sigemptyset(&sigset); + sigaddset(&sigset, SIGPROF); + sigmask |= 1 << (SIGPROF - 1); + } + + assert(timeout >= -1); + base = loop->time; + count = 48; /* Benchmarks suggest this gives the best throughput. */ + real_timeout = timeout; + + if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) { + reset_timeout = 1; + user_timeout = timeout; + timeout = 0; + } else { + reset_timeout = 0; + user_timeout = 0; + } + + /* You could argue there is a dependency between these two but + * ultimately we don't care about their ordering with respect + * to one another. Worst case, we make a few system calls that + * could have been avoided because another thread already knows + * they fail with ENOSYS. Hardly the end of the world. + */ + no_epoll_pwait = uv__load_relaxed(&no_epoll_pwait_cached); + no_epoll_wait = uv__load_relaxed(&no_epoll_wait_cached); + + for (;;) { + /* Only need to set the provider_entry_time if timeout != 0. The function + * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME. + */ + if (timeout != 0) + uv__metrics_set_provider_entry_time(loop); + + /* See the comment for max_safe_timeout for an explanation of why + * this is necessary. Executive summary: kernel bug workaround. + */ + if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout) + timeout = max_safe_timeout; + + if (sigmask != 0 && no_epoll_pwait != 0) + if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) + abort(); + + if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) { + nfds = epoll_pwait(loop->backend_fd, + events, + ARRAY_SIZE(events), + timeout, + &sigset); + if (nfds == -1 && errno == ENOSYS) { + uv__store_relaxed(&no_epoll_pwait_cached, 1); + no_epoll_pwait = 1; + } + } else { + nfds = epoll_wait(loop->backend_fd, + events, + ARRAY_SIZE(events), + timeout); + if (nfds == -1 && errno == ENOSYS) { + uv__store_relaxed(&no_epoll_wait_cached, 1); + no_epoll_wait = 1; + } + } + + if (sigmask != 0 && no_epoll_pwait != 0) + if (pthread_sigmask(SIG_UNBLOCK, &sigset, NULL)) + abort(); + + /* Update loop->time unconditionally. It's tempting to skip the update when + * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the + * operating system didn't reschedule our process while in the syscall. + */ + SAVE_ERRNO(uv__update_time(loop)); + + if (nfds == 0) { + assert(timeout != -1); + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (timeout == -1) + continue; + + if (timeout == 0) + return; + + /* We may have been inside the system call for longer than |timeout| + * milliseconds so we need to update the timestamp to avoid drift. + */ + goto update_timeout; + } + + if (nfds == -1) { + if (errno == ENOSYS) { + /* epoll_wait() or epoll_pwait() failed, try the other system call. */ + assert(no_epoll_wait == 0 || no_epoll_pwait == 0); + continue; + } + + if (errno != EINTR) + abort(); + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (timeout == -1) + continue; + + if (timeout == 0) + return; + + /* Interrupted by a signal. Update timeout and poll again. */ + goto update_timeout; + } + + have_signals = 0; + nevents = 0; + + { + /* Squelch a -Waddress-of-packed-member warning with gcc >= 9. */ + union { + struct epoll_event* events; + uv__io_t* watchers; + } x; + + x.events = events; + assert(loop->watchers != NULL); + loop->watchers[loop->nwatchers] = x.watchers; + loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds; + } + + for (i = 0; i < nfds; i++) { + pe = events + i; + fd = pe->data.fd; + + /* Skip invalidated events, see uv__platform_invalidate_fd */ + if (fd == -1) + continue; + + assert(fd >= 0); + assert((unsigned) fd < loop->nwatchers); + + w = loop->watchers[fd]; + + if (w == NULL) { + /* File descriptor that we've stopped watching, disarm it. + * + * Ignore all errors because we may be racing with another thread + * when the file descriptor is closed. + */ + epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, pe); + continue; + } + + /* Give users only events they're interested in. Prevents spurious + * callbacks when previous callback invocation in this loop has stopped + * the current watcher. Also, filters out events that users has not + * requested us to watch. + */ + pe->events &= w->pevents | POLLERR | POLLHUP; + + /* Work around an epoll quirk where it sometimes reports just the + * EPOLLERR or EPOLLHUP event. In order to force the event loop to + * move forward, we merge in the read/write events that the watcher + * is interested in; uv__read() and uv__write() will then deal with + * the error or hangup in the usual fashion. + * + * Note to self: happens when epoll reports EPOLLIN|EPOLLHUP, the user + * reads the available data, calls uv_read_stop(), then sometime later + * calls uv_read_start() again. By then, libuv has forgotten about the + * hangup and the kernel won't report EPOLLIN again because there's + * nothing left to read. If anything, libuv is to blame here. The + * current hack is just a quick bandaid; to properly fix it, libuv + * needs to remember the error/hangup event. We should get that for + * free when we switch over to edge-triggered I/O. + */ + if (pe->events == POLLERR || pe->events == POLLHUP) + pe->events |= + w->pevents & (POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI); + + if (pe->events != 0) { + /* Run signal watchers last. This also affects child process watchers + * because those are implemented in terms of signal watchers. + */ + if (w == &loop->signal_io_watcher) { + have_signals = 1; + } else { + uv__metrics_update_idle_time(loop); + w->cb(loop, w, pe->events); + } + + nevents++; + } + } + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (have_signals != 0) { + uv__metrics_update_idle_time(loop); + loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN); + } + + loop->watchers[loop->nwatchers] = NULL; + loop->watchers[loop->nwatchers + 1] = NULL; + + if (have_signals != 0) + return; /* Event loop should cycle now so don't poll again. */ + + if (nevents != 0) { + if (nfds == ARRAY_SIZE(events) && --count != 0) { + /* Poll for more events but don't block this time. */ + timeout = 0; + continue; + } + return; + } + + if (timeout == 0) + return; + + if (timeout == -1) + continue; + +update_timeout: + assert(timeout > 0); + + real_timeout -= (loop->time - base); + if (real_timeout <= 0) + return; + + timeout = real_timeout; + } +} + diff --git a/external/src/libuv/src/unix/freebsd.c b/external/src/libuv/src/unix/freebsd.c new file mode 100644 index 0000000..170b897 --- /dev/null +++ b/external/src/libuv/src/unix/freebsd.c @@ -0,0 +1,289 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include /* VM_LOADAVG */ +#include +#include +#include /* sysconf */ +#include + +#ifndef CPUSTATES +# define CPUSTATES 5U +#endif +#ifndef CP_USER +# define CP_USER 0 +# define CP_NICE 1 +# define CP_SYS 2 +# define CP_IDLE 3 +# define CP_INTR 4 +#endif + + +int uv__platform_loop_init(uv_loop_t* loop) { + return uv__kqueue_init(loop); +} + + +void uv__platform_loop_delete(uv_loop_t* loop) { +} + +int uv_exepath(char* buffer, size_t* size) { + char abspath[PATH_MAX * 2 + 1]; + int mib[4]; + size_t abspath_size; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PATHNAME; + mib[3] = -1; + + abspath_size = sizeof abspath; + if (sysctl(mib, ARRAY_SIZE(mib), abspath, &abspath_size, NULL, 0)) + return UV__ERR(errno); + + assert(abspath_size > 0); + abspath_size -= 1; + *size -= 1; + + if (*size > abspath_size) + *size = abspath_size; + + memcpy(buffer, abspath, *size); + buffer[*size] = '\0'; + + return 0; +} + +uint64_t uv_get_free_memory(void) { + int freecount; + size_t size = sizeof(freecount); + + if (sysctlbyname("vm.stats.vm.v_free_count", &freecount, &size, NULL, 0)) + return UV__ERR(errno); + + return (uint64_t) freecount * sysconf(_SC_PAGESIZE); + +} + + +uint64_t uv_get_total_memory(void) { + unsigned long info; + int which[] = {CTL_HW, HW_PHYSMEM}; + + size_t size = sizeof(info); + + if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0)) + return UV__ERR(errno); + + return (uint64_t) info; +} + + +uint64_t uv_get_constrained_memory(void) { + return 0; /* Memory constraints are unknown. */ +} + + +void uv_loadavg(double avg[3]) { + struct loadavg info; + size_t size = sizeof(info); + int which[] = {CTL_VM, VM_LOADAVG}; + + if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0) < 0) return; + + avg[0] = (double) info.ldavg[0] / info.fscale; + avg[1] = (double) info.ldavg[1] / info.fscale; + avg[2] = (double) info.ldavg[2] / info.fscale; +} + + +int uv_resident_set_memory(size_t* rss) { + struct kinfo_proc kinfo; + size_t page_size; + size_t kinfo_size; + int mib[4]; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + kinfo_size = sizeof(kinfo); + + if (sysctl(mib, ARRAY_SIZE(mib), &kinfo, &kinfo_size, NULL, 0)) + return UV__ERR(errno); + + page_size = getpagesize(); + +#ifdef __DragonFly__ + *rss = kinfo.kp_vm_rssize * page_size; +#else + *rss = kinfo.ki_rssize * page_size; +#endif + + return 0; +} + + +int uv_uptime(double* uptime) { + int r; + struct timespec sp; + r = clock_gettime(CLOCK_MONOTONIC, &sp); + if (r) + return UV__ERR(errno); + + *uptime = sp.tv_sec; + return 0; +} + + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), + multiplier = ((uint64_t)1000L / ticks), cpuspeed, maxcpus, + cur = 0; + uv_cpu_info_t* cpu_info; + const char* maxcpus_key; + const char* cptimes_key; + const char* model_key; + char model[512]; + long* cp_times; + int numcpus; + size_t size; + int i; + +#if defined(__DragonFly__) + /* This is not quite correct but DragonFlyBSD doesn't seem to have anything + * comparable to kern.smp.maxcpus or kern.cp_times (kern.cp_time is a total, + * not per CPU). At least this stops uv_cpu_info() from failing completely. + */ + maxcpus_key = "hw.ncpu"; + cptimes_key = "kern.cp_time"; +#else + maxcpus_key = "kern.smp.maxcpus"; + cptimes_key = "kern.cp_times"; +#endif + +#if defined(__arm__) || defined(__aarch64__) + /* The key hw.model and hw.clockrate are not available on FreeBSD ARM. */ + model_key = "hw.machine"; + cpuspeed = 0; +#else + model_key = "hw.model"; + + size = sizeof(cpuspeed); + if (sysctlbyname("hw.clockrate", &cpuspeed, &size, NULL, 0)) + return -errno; +#endif + + size = sizeof(model); + if (sysctlbyname(model_key, &model, &size, NULL, 0)) + return UV__ERR(errno); + + size = sizeof(numcpus); + if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0)) + return UV__ERR(errno); + + *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); + if (!(*cpu_infos)) + return UV_ENOMEM; + + *count = numcpus; + + /* kern.cp_times on FreeBSD i386 gives an array up to maxcpus instead of + * ncpu. + */ + size = sizeof(maxcpus); + if (sysctlbyname(maxcpus_key, &maxcpus, &size, NULL, 0)) { + uv__free(*cpu_infos); + return UV__ERR(errno); + } + + size = maxcpus * CPUSTATES * sizeof(long); + + cp_times = uv__malloc(size); + if (cp_times == NULL) { + uv__free(*cpu_infos); + return UV_ENOMEM; + } + + if (sysctlbyname(cptimes_key, cp_times, &size, NULL, 0)) { + uv__free(cp_times); + uv__free(*cpu_infos); + return UV__ERR(errno); + } + + for (i = 0; i < numcpus; i++) { + cpu_info = &(*cpu_infos)[i]; + + cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier; + cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier; + cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier; + cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier; + cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier; + + cpu_info->model = uv__strdup(model); + cpu_info->speed = cpuspeed; + + cur+=CPUSTATES; + } + + uv__free(cp_times); + return 0; +} + + +int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) { +#if __FreeBSD__ >= 11 && !defined(__DragonFly__) + return sendmmsg(fd, + (struct mmsghdr*) mmsg, + vlen, + 0 /* flags */); +#else + return errno = ENOSYS, -1; +#endif +} + + +int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) { +#if __FreeBSD__ >= 11 && !defined(__DragonFly__) + return recvmmsg(fd, + (struct mmsghdr*) mmsg, + vlen, + 0 /* flags */, + NULL /* timeout */); +#else + return errno = ENOSYS, -1; +#endif +} diff --git a/external/src/libuv/src/unix/fs.c b/external/src/libuv/src/unix/fs.c new file mode 100644 index 0000000..eb17fb4 --- /dev/null +++ b/external/src/libuv/src/unix/fs.c @@ -0,0 +1,2206 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* Caveat emptor: this file deviates from the libuv convention of returning + * negated errno codes. Most uv_fs_*() functions map directly to the system + * call of the same name. For more complex wrappers, it's easier to just + * return -1 with errno set. The dispatcher in uv__fs_work() takes care of + * getting the errno to the right place (req->result or as the return value.) + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include +#include /* PATH_MAX */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || \ + defined(__OpenBSD__) || \ + defined(__NetBSD__) +# define HAVE_PREADV 1 +#else +# define HAVE_PREADV 0 +#endif + +#if defined(__linux__) +# include "sys/utsname.h" +#endif + +#if defined(__linux__) || defined(__sun) +# include +# include +#endif + +#if defined(__APPLE__) +# include +#elif defined(__linux__) && !defined(FICLONE) +# include +# define FICLONE _IOW(0x94, 9, int) +#endif + +#if defined(_AIX) && !defined(_AIX71) +# include +#endif + +#if defined(__APPLE__) || \ + defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || \ + defined(__OpenBSD__) || \ + defined(__NetBSD__) +# include +# include +#elif defined(__sun) || \ + defined(__MVS__) || \ + defined(__NetBSD__) || \ + defined(__HAIKU__) || \ + defined(__QNX__) +# include +#else +# include +#endif + +#if defined(_AIX) && _XOPEN_SOURCE <= 600 +extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */ +#endif + +#define INIT(subtype) \ + do { \ + if (req == NULL) \ + return UV_EINVAL; \ + UV_REQ_INIT(req, UV_FS); \ + req->fs_type = UV_FS_ ## subtype; \ + req->result = 0; \ + req->ptr = NULL; \ + req->loop = loop; \ + req->path = NULL; \ + req->new_path = NULL; \ + req->bufs = NULL; \ + req->cb = cb; \ + } \ + while (0) + +#define PATH \ + do { \ + assert(path != NULL); \ + if (cb == NULL) { \ + req->path = path; \ + } else { \ + req->path = uv__strdup(path); \ + if (req->path == NULL) \ + return UV_ENOMEM; \ + } \ + } \ + while (0) + +#define PATH2 \ + do { \ + if (cb == NULL) { \ + req->path = path; \ + req->new_path = new_path; \ + } else { \ + size_t path_len; \ + size_t new_path_len; \ + path_len = strlen(path) + 1; \ + new_path_len = strlen(new_path) + 1; \ + req->path = uv__malloc(path_len + new_path_len); \ + if (req->path == NULL) \ + return UV_ENOMEM; \ + req->new_path = req->path + path_len; \ + memcpy((void*) req->path, path, path_len); \ + memcpy((void*) req->new_path, new_path, new_path_len); \ + } \ + } \ + while (0) + +#define POST \ + do { \ + if (cb != NULL) { \ + uv__req_register(loop, req); \ + uv__work_submit(loop, \ + &req->work_req, \ + UV__WORK_FAST_IO, \ + uv__fs_work, \ + uv__fs_done); \ + return 0; \ + } \ + else { \ + uv__fs_work(&req->work_req); \ + return req->result; \ + } \ + } \ + while (0) + + +static int uv__fs_close(int fd) { + int rc; + + rc = uv__close_nocancel(fd); + if (rc == -1) + if (errno == EINTR || errno == EINPROGRESS) + rc = 0; /* The close is in progress, not an error. */ + + return rc; +} + + +static ssize_t uv__fs_fsync(uv_fs_t* req) { +#if defined(__APPLE__) + /* Apple's fdatasync and fsync explicitly do NOT flush the drive write cache + * to the drive platters. This is in contrast to Linux's fdatasync and fsync + * which do, according to recent man pages. F_FULLFSYNC is Apple's equivalent + * for flushing buffered data to permanent storage. If F_FULLFSYNC is not + * supported by the file system we fall back to F_BARRIERFSYNC or fsync(). + * This is the same approach taken by sqlite, except sqlite does not issue + * an F_BARRIERFSYNC call. + */ + int r; + + r = fcntl(req->file, F_FULLFSYNC); + if (r != 0) + r = fcntl(req->file, 85 /* F_BARRIERFSYNC */); /* fsync + barrier */ + if (r != 0) + r = fsync(req->file); + return r; +#else + return fsync(req->file); +#endif +} + + +static ssize_t uv__fs_fdatasync(uv_fs_t* req) { +#if defined(__linux__) || defined(__sun) || defined(__NetBSD__) + return fdatasync(req->file); +#elif defined(__APPLE__) + /* See the comment in uv__fs_fsync. */ + return uv__fs_fsync(req); +#else + return fsync(req->file); +#endif +} + + +UV_UNUSED(static struct timespec uv__fs_to_timespec(double time)) { + struct timespec ts; + ts.tv_sec = time; + ts.tv_nsec = (time - ts.tv_sec) * 1e9; + + /* TODO(bnoordhuis) Remove this. utimesat() has nanosecond resolution but we + * stick to microsecond resolution for the sake of consistency with other + * platforms. I'm the original author of this compatibility hack but I'm + * less convinced it's useful nowadays. + */ + ts.tv_nsec -= ts.tv_nsec % 1000; + + if (ts.tv_nsec < 0) { + ts.tv_nsec += 1e9; + ts.tv_sec -= 1; + } + return ts; +} + +UV_UNUSED(static struct timeval uv__fs_to_timeval(double time)) { + struct timeval tv; + tv.tv_sec = time; + tv.tv_usec = (time - tv.tv_sec) * 1e6; + if (tv.tv_usec < 0) { + tv.tv_usec += 1e6; + tv.tv_sec -= 1; + } + return tv; +} + +static ssize_t uv__fs_futime(uv_fs_t* req) { +#if defined(__linux__) \ + || defined(_AIX71) \ + || defined(__HAIKU__) + struct timespec ts[2]; + ts[0] = uv__fs_to_timespec(req->atime); + ts[1] = uv__fs_to_timespec(req->mtime); + return futimens(req->file, ts); +#elif defined(__APPLE__) \ + || defined(__DragonFly__) \ + || defined(__FreeBSD__) \ + || defined(__FreeBSD_kernel__) \ + || defined(__NetBSD__) \ + || defined(__OpenBSD__) \ + || defined(__sun) + struct timeval tv[2]; + tv[0] = uv__fs_to_timeval(req->atime); + tv[1] = uv__fs_to_timeval(req->mtime); +# if defined(__sun) + return futimesat(req->file, NULL, tv); +# else + return futimes(req->file, tv); +# endif +#elif defined(__MVS__) + attrib_t atr; + memset(&atr, 0, sizeof(atr)); + atr.att_mtimechg = 1; + atr.att_atimechg = 1; + atr.att_mtime = req->mtime; + atr.att_atime = req->atime; + return __fchattr(req->file, &atr, sizeof(atr)); +#else + errno = ENOSYS; + return -1; +#endif +} + + +static ssize_t uv__fs_mkdtemp(uv_fs_t* req) { + return mkdtemp((char*) req->path) ? 0 : -1; +} + + +static int (*uv__mkostemp)(char*, int); + + +static void uv__mkostemp_initonce(void) { + /* z/os doesn't have RTLD_DEFAULT but that's okay + * because it doesn't have mkostemp(O_CLOEXEC) either. + */ +#ifdef RTLD_DEFAULT + uv__mkostemp = (int (*)(char*, int)) dlsym(RTLD_DEFAULT, "mkostemp"); + + /* We don't care about errors, but we do want to clean them up. + * If there has been no error, then dlerror() will just return + * NULL. + */ + dlerror(); +#endif /* RTLD_DEFAULT */ +} + + +static int uv__fs_mkstemp(uv_fs_t* req) { + static uv_once_t once = UV_ONCE_INIT; + int r; +#ifdef O_CLOEXEC + static int no_cloexec_support; +#endif + static const char pattern[] = "XXXXXX"; + static const size_t pattern_size = sizeof(pattern) - 1; + char* path; + size_t path_length; + + path = (char*) req->path; + path_length = strlen(path); + + /* EINVAL can be returned for 2 reasons: + 1. The template's last 6 characters were not XXXXXX + 2. open() didn't support O_CLOEXEC + We want to avoid going to the fallback path in case + of 1, so it's manually checked before. */ + if (path_length < pattern_size || + strcmp(path + path_length - pattern_size, pattern)) { + errno = EINVAL; + r = -1; + goto clobber; + } + + uv_once(&once, uv__mkostemp_initonce); + +#ifdef O_CLOEXEC + if (uv__load_relaxed(&no_cloexec_support) == 0 && uv__mkostemp != NULL) { + r = uv__mkostemp(path, O_CLOEXEC); + + if (r >= 0) + return r; + + /* If mkostemp() returns EINVAL, it means the kernel doesn't + support O_CLOEXEC, so we just fallback to mkstemp() below. */ + if (errno != EINVAL) + goto clobber; + + /* We set the static variable so that next calls don't even + try to use mkostemp. */ + uv__store_relaxed(&no_cloexec_support, 1); + } +#endif /* O_CLOEXEC */ + + if (req->cb != NULL) + uv_rwlock_rdlock(&req->loop->cloexec_lock); + + r = mkstemp(path); + + /* In case of failure `uv__cloexec` will leave error in `errno`, + * so it is enough to just set `r` to `-1`. + */ + if (r >= 0 && uv__cloexec(r, 1) != 0) { + r = uv__close(r); + if (r != 0) + abort(); + r = -1; + } + + if (req->cb != NULL) + uv_rwlock_rdunlock(&req->loop->cloexec_lock); + +clobber: + if (r < 0) + path[0] = '\0'; + return r; +} + + +static ssize_t uv__fs_open(uv_fs_t* req) { +#ifdef O_CLOEXEC + return open(req->path, req->flags | O_CLOEXEC, req->mode); +#else /* O_CLOEXEC */ + int r; + + if (req->cb != NULL) + uv_rwlock_rdlock(&req->loop->cloexec_lock); + + r = open(req->path, req->flags, req->mode); + + /* In case of failure `uv__cloexec` will leave error in `errno`, + * so it is enough to just set `r` to `-1`. + */ + if (r >= 0 && uv__cloexec(r, 1) != 0) { + r = uv__close(r); + if (r != 0) + abort(); + r = -1; + } + + if (req->cb != NULL) + uv_rwlock_rdunlock(&req->loop->cloexec_lock); + + return r; +#endif /* O_CLOEXEC */ +} + + +#if !HAVE_PREADV +static ssize_t uv__fs_preadv(uv_file fd, + uv_buf_t* bufs, + unsigned int nbufs, + off_t off) { + uv_buf_t* buf; + uv_buf_t* end; + ssize_t result; + ssize_t rc; + size_t pos; + + assert(nbufs > 0); + + result = 0; + pos = 0; + buf = bufs + 0; + end = bufs + nbufs; + + for (;;) { + do + rc = pread(fd, buf->base + pos, buf->len - pos, off + result); + while (rc == -1 && errno == EINTR); + + if (rc == 0) + break; + + if (rc == -1 && result == 0) + return UV__ERR(errno); + + if (rc == -1) + break; /* We read some data so return that, ignore the error. */ + + pos += rc; + result += rc; + + if (pos < buf->len) + continue; + + pos = 0; + buf += 1; + + if (buf == end) + break; + } + + return result; +} +#endif + + +static ssize_t uv__fs_read(uv_fs_t* req) { +#if defined(__linux__) + static int no_preadv; +#endif + unsigned int iovmax; + ssize_t result; + + iovmax = uv__getiovmax(); + if (req->nbufs > iovmax) + req->nbufs = iovmax; + + if (req->off < 0) { + if (req->nbufs == 1) + result = read(req->file, req->bufs[0].base, req->bufs[0].len); + else + result = readv(req->file, (struct iovec*) req->bufs, req->nbufs); + } else { + if (req->nbufs == 1) { + result = pread(req->file, req->bufs[0].base, req->bufs[0].len, req->off); + goto done; + } + +#if HAVE_PREADV + result = preadv(req->file, (struct iovec*) req->bufs, req->nbufs, req->off); +#else +# if defined(__linux__) + if (uv__load_relaxed(&no_preadv)) retry: +# endif + { + result = uv__fs_preadv(req->file, req->bufs, req->nbufs, req->off); + } +# if defined(__linux__) + else { + result = uv__preadv(req->file, + (struct iovec*)req->bufs, + req->nbufs, + req->off); + if (result == -1 && errno == ENOSYS) { + uv__store_relaxed(&no_preadv, 1); + goto retry; + } + } +# endif +#endif + } + +done: + /* Early cleanup of bufs allocation, since we're done with it. */ + if (req->bufs != req->bufsml) + uv__free(req->bufs); + + req->bufs = NULL; + req->nbufs = 0; + +#ifdef __PASE__ + /* PASE returns EOPNOTSUPP when reading a directory, convert to EISDIR */ + if (result == -1 && errno == EOPNOTSUPP) { + struct stat buf; + ssize_t rc; + rc = fstat(req->file, &buf); + if (rc == 0 && S_ISDIR(buf.st_mode)) { + errno = EISDIR; + } + } +#endif + + return result; +} + + +#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_8) +#define UV_CONST_DIRENT uv__dirent_t +#else +#define UV_CONST_DIRENT const uv__dirent_t +#endif + + +static int uv__fs_scandir_filter(UV_CONST_DIRENT* dent) { + return strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0; +} + + +static int uv__fs_scandir_sort(UV_CONST_DIRENT** a, UV_CONST_DIRENT** b) { + return strcmp((*a)->d_name, (*b)->d_name); +} + + +static ssize_t uv__fs_scandir(uv_fs_t* req) { + uv__dirent_t** dents; + int n; + + dents = NULL; + n = scandir(req->path, &dents, uv__fs_scandir_filter, uv__fs_scandir_sort); + + /* NOTE: We will use nbufs as an index field */ + req->nbufs = 0; + + if (n == 0) { + /* OS X still needs to deallocate some memory. + * Memory was allocated using the system allocator, so use free() here. + */ + free(dents); + dents = NULL; + } else if (n == -1) { + return n; + } + + req->ptr = dents; + + return n; +} + +static int uv__fs_opendir(uv_fs_t* req) { + uv_dir_t* dir; + + dir = uv__malloc(sizeof(*dir)); + if (dir == NULL) + goto error; + + dir->dir = opendir(req->path); + if (dir->dir == NULL) + goto error; + + req->ptr = dir; + return 0; + +error: + uv__free(dir); + req->ptr = NULL; + return -1; +} + +static int uv__fs_readdir(uv_fs_t* req) { + uv_dir_t* dir; + uv_dirent_t* dirent; + struct dirent* res; + unsigned int dirent_idx; + unsigned int i; + + dir = req->ptr; + dirent_idx = 0; + + while (dirent_idx < dir->nentries) { + /* readdir() returns NULL on end of directory, as well as on error. errno + is used to differentiate between the two conditions. */ + errno = 0; + res = readdir(dir->dir); + + if (res == NULL) { + if (errno != 0) + goto error; + break; + } + + if (strcmp(res->d_name, ".") == 0 || strcmp(res->d_name, "..") == 0) + continue; + + dirent = &dir->dirents[dirent_idx]; + dirent->name = uv__strdup(res->d_name); + + if (dirent->name == NULL) + goto error; + + dirent->type = uv__fs_get_dirent_type(res); + ++dirent_idx; + } + + return dirent_idx; + +error: + for (i = 0; i < dirent_idx; ++i) { + uv__free((char*) dir->dirents[i].name); + dir->dirents[i].name = NULL; + } + + return -1; +} + +static int uv__fs_closedir(uv_fs_t* req) { + uv_dir_t* dir; + + dir = req->ptr; + + if (dir->dir != NULL) { + closedir(dir->dir); + dir->dir = NULL; + } + + uv__free(req->ptr); + req->ptr = NULL; + return 0; +} + +static int uv__fs_statfs(uv_fs_t* req) { + uv_statfs_t* stat_fs; +#if defined(__sun) || \ + defined(__MVS__) || \ + defined(__NetBSD__) || \ + defined(__HAIKU__) || \ + defined(__QNX__) + struct statvfs buf; + + if (0 != statvfs(req->path, &buf)) +#else + struct statfs buf; + + if (0 != statfs(req->path, &buf)) +#endif /* defined(__sun) */ + return -1; + + stat_fs = uv__malloc(sizeof(*stat_fs)); + if (stat_fs == NULL) { + errno = ENOMEM; + return -1; + } + +#if defined(__sun) || \ + defined(__MVS__) || \ + defined(__OpenBSD__) || \ + defined(__NetBSD__) || \ + defined(__HAIKU__) || \ + defined(__QNX__) + stat_fs->f_type = 0; /* f_type is not supported. */ +#else + stat_fs->f_type = buf.f_type; +#endif + stat_fs->f_bsize = buf.f_bsize; + stat_fs->f_blocks = buf.f_blocks; + stat_fs->f_bfree = buf.f_bfree; + stat_fs->f_bavail = buf.f_bavail; + stat_fs->f_files = buf.f_files; + stat_fs->f_ffree = buf.f_ffree; + req->ptr = stat_fs; + return 0; +} + +static ssize_t uv__fs_pathmax_size(const char* path) { + ssize_t pathmax; + + pathmax = pathconf(path, _PC_PATH_MAX); + + if (pathmax == -1) + pathmax = UV__PATH_MAX; + + return pathmax; +} + +static ssize_t uv__fs_readlink(uv_fs_t* req) { + ssize_t maxlen; + ssize_t len; + char* buf; + +#if defined(_POSIX_PATH_MAX) || defined(PATH_MAX) + maxlen = uv__fs_pathmax_size(req->path); +#else + /* We may not have a real PATH_MAX. Read size of link. */ + struct stat st; + int ret; + ret = lstat(req->path, &st); + if (ret != 0) + return -1; + if (!S_ISLNK(st.st_mode)) { + errno = EINVAL; + return -1; + } + + maxlen = st.st_size; + + /* According to readlink(2) lstat can report st_size == 0 + for some symlinks, such as those in /proc or /sys. */ + if (maxlen == 0) + maxlen = uv__fs_pathmax_size(req->path); +#endif + + buf = uv__malloc(maxlen); + + if (buf == NULL) { + errno = ENOMEM; + return -1; + } + +#if defined(__MVS__) + len = os390_readlink(req->path, buf, maxlen); +#else + len = readlink(req->path, buf, maxlen); +#endif + + if (len == -1) { + uv__free(buf); + return -1; + } + + /* Uncommon case: resize to make room for the trailing nul byte. */ + if (len == maxlen) { + buf = uv__reallocf(buf, len + 1); + + if (buf == NULL) + return -1; + } + + buf[len] = '\0'; + req->ptr = buf; + + return 0; +} + +static ssize_t uv__fs_realpath(uv_fs_t* req) { + char* buf; + +#if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L + buf = realpath(req->path, NULL); + if (buf == NULL) + return -1; +#else + ssize_t len; + + len = uv__fs_pathmax_size(req->path); + buf = uv__malloc(len + 1); + + if (buf == NULL) { + errno = ENOMEM; + return -1; + } + + if (realpath(req->path, buf) == NULL) { + uv__free(buf); + return -1; + } +#endif + + req->ptr = buf; + + return 0; +} + +static ssize_t uv__fs_sendfile_emul(uv_fs_t* req) { + struct pollfd pfd; + int use_pread; + off_t offset; + ssize_t nsent; + ssize_t nread; + ssize_t nwritten; + size_t buflen; + size_t len; + ssize_t n; + int in_fd; + int out_fd; + char buf[8192]; + + len = req->bufsml[0].len; + in_fd = req->flags; + out_fd = req->file; + offset = req->off; + use_pread = 1; + + /* Here are the rules regarding errors: + * + * 1. Read errors are reported only if nsent==0, otherwise we return nsent. + * The user needs to know that some data has already been sent, to stop + * them from sending it twice. + * + * 2. Write errors are always reported. Write errors are bad because they + * mean data loss: we've read data but now we can't write it out. + * + * We try to use pread() and fall back to regular read() if the source fd + * doesn't support positional reads, for example when it's a pipe fd. + * + * If we get EAGAIN when writing to the target fd, we poll() on it until + * it becomes writable again. + * + * FIXME: If we get a write error when use_pread==1, it should be safe to + * return the number of sent bytes instead of an error because pread() + * is, in theory, idempotent. However, special files in /dev or /proc + * may support pread() but not necessarily return the same data on + * successive reads. + * + * FIXME: There is no way now to signal that we managed to send *some* data + * before a write error. + */ + for (nsent = 0; (size_t) nsent < len; ) { + buflen = len - nsent; + + if (buflen > sizeof(buf)) + buflen = sizeof(buf); + + do + if (use_pread) + nread = pread(in_fd, buf, buflen, offset); + else + nread = read(in_fd, buf, buflen); + while (nread == -1 && errno == EINTR); + + if (nread == 0) + goto out; + + if (nread == -1) { + if (use_pread && nsent == 0 && (errno == EIO || errno == ESPIPE)) { + use_pread = 0; + continue; + } + + if (nsent == 0) + nsent = -1; + + goto out; + } + + for (nwritten = 0; nwritten < nread; ) { + do + n = write(out_fd, buf + nwritten, nread - nwritten); + while (n == -1 && errno == EINTR); + + if (n != -1) { + nwritten += n; + continue; + } + + if (errno != EAGAIN && errno != EWOULDBLOCK) { + nsent = -1; + goto out; + } + + pfd.fd = out_fd; + pfd.events = POLLOUT; + pfd.revents = 0; + + do + n = poll(&pfd, 1, -1); + while (n == -1 && errno == EINTR); + + if (n == -1 || (pfd.revents & ~POLLOUT) != 0) { + errno = EIO; + nsent = -1; + goto out; + } + } + + offset += nread; + nsent += nread; + } + +out: + if (nsent != -1) + req->off = offset; + + return nsent; +} + + +#ifdef __linux__ +static unsigned uv__kernel_version(void) { + static unsigned cached_version; + struct utsname u; + unsigned version; + unsigned major; + unsigned minor; + unsigned patch; + + version = uv__load_relaxed(&cached_version); + if (version != 0) + return version; + + if (-1 == uname(&u)) + return 0; + + if (3 != sscanf(u.release, "%u.%u.%u", &major, &minor, &patch)) + return 0; + + version = major * 65536 + minor * 256 + patch; + uv__store_relaxed(&cached_version, version); + + return version; +} + + +/* Pre-4.20 kernels have a bug where CephFS uses the RADOS copy-from command + * in copy_file_range() when it shouldn't. There is no workaround except to + * fall back to a regular copy. + */ +static int uv__is_buggy_cephfs(int fd) { + struct statfs s; + + if (-1 == fstatfs(fd, &s)) + return 0; + + if (s.f_type != /* CephFS */ 0xC36400) + return 0; + + return uv__kernel_version() < /* 4.20.0 */ 0x041400; +} +#endif /* __linux__ */ + + +static ssize_t uv__fs_sendfile(uv_fs_t* req) { + int in_fd; + int out_fd; + + in_fd = req->flags; + out_fd = req->file; + +#if defined(__linux__) || defined(__sun) + { + off_t off; + ssize_t r; + + off = req->off; + +#ifdef __linux__ + { + static int no_copy_file_range_support; + + if (uv__load_relaxed(&no_copy_file_range_support) == 0) { + r = uv__fs_copy_file_range(in_fd, &off, out_fd, NULL, req->bufsml[0].len, 0); + + if (r == -1 && errno == ENOSYS) { + /* ENOSYS - it will never work */ + errno = 0; + uv__store_relaxed(&no_copy_file_range_support, 1); + } else if (r == -1 && errno == EACCES && uv__is_buggy_cephfs(in_fd)) { + /* EACCES - pre-4.20 kernels have a bug where CephFS uses the RADOS + copy-from command when it shouldn't */ + errno = 0; + uv__store_relaxed(&no_copy_file_range_support, 1); + } else if (r == -1 && (errno == ENOTSUP || errno == EXDEV)) { + /* ENOTSUP - it could work on another file system type */ + /* EXDEV - it will not work when in_fd and out_fd are not on the same + mounted filesystem (pre Linux 5.3) */ + errno = 0; + } else { + goto ok; + } + } + } +#endif + + r = sendfile(out_fd, in_fd, &off, req->bufsml[0].len); + +ok: + /* sendfile() on SunOS returns EINVAL if the target fd is not a socket but + * it still writes out data. Fortunately, we can detect it by checking if + * the offset has been updated. + */ + if (r != -1 || off > req->off) { + r = off - req->off; + req->off = off; + return r; + } + + if (errno == EINVAL || + errno == EIO || + errno == ENOTSOCK || + errno == EXDEV) { + errno = 0; + return uv__fs_sendfile_emul(req); + } + + return -1; + } +#elif defined(__APPLE__) || \ + defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) + { + off_t len; + ssize_t r; + + /* sendfile() on FreeBSD and Darwin returns EAGAIN if the target fd is in + * non-blocking mode and not all data could be written. If a non-zero + * number of bytes have been sent, we don't consider it an error. + */ + +#if defined(__FreeBSD__) || defined(__DragonFly__) + len = 0; + r = sendfile(in_fd, out_fd, req->off, req->bufsml[0].len, NULL, &len, 0); +#elif defined(__FreeBSD_kernel__) + len = 0; + r = bsd_sendfile(in_fd, + out_fd, + req->off, + req->bufsml[0].len, + NULL, + &len, + 0); +#else + /* The darwin sendfile takes len as an input for the length to send, + * so make sure to initialize it with the caller's value. */ + len = req->bufsml[0].len; + r = sendfile(in_fd, out_fd, req->off, &len, NULL, 0); +#endif + + /* + * The man page for sendfile(2) on DragonFly states that `len` contains + * a meaningful value ONLY in case of EAGAIN and EINTR. + * Nothing is said about it's value in case of other errors, so better + * not depend on the potential wrong assumption that is was not modified + * by the syscall. + */ + if (r == 0 || ((errno == EAGAIN || errno == EINTR) && len != 0)) { + req->off += len; + return (ssize_t) len; + } + + if (errno == EINVAL || + errno == EIO || + errno == ENOTSOCK || + errno == EXDEV) { + errno = 0; + return uv__fs_sendfile_emul(req); + } + + return -1; + } +#else + /* Squelch compiler warnings. */ + (void) &in_fd; + (void) &out_fd; + + return uv__fs_sendfile_emul(req); +#endif +} + + +static ssize_t uv__fs_utime(uv_fs_t* req) { +#if defined(__linux__) \ + || defined(_AIX71) \ + || defined(__sun) \ + || defined(__HAIKU__) + struct timespec ts[2]; + ts[0] = uv__fs_to_timespec(req->atime); + ts[1] = uv__fs_to_timespec(req->mtime); + return utimensat(AT_FDCWD, req->path, ts, 0); +#elif defined(__APPLE__) \ + || defined(__DragonFly__) \ + || defined(__FreeBSD__) \ + || defined(__FreeBSD_kernel__) \ + || defined(__NetBSD__) \ + || defined(__OpenBSD__) + struct timeval tv[2]; + tv[0] = uv__fs_to_timeval(req->atime); + tv[1] = uv__fs_to_timeval(req->mtime); + return utimes(req->path, tv); +#elif defined(_AIX) \ + && !defined(_AIX71) + struct utimbuf buf; + buf.actime = req->atime; + buf.modtime = req->mtime; + return utime(req->path, &buf); +#elif defined(__MVS__) + attrib_t atr; + memset(&atr, 0, sizeof(atr)); + atr.att_mtimechg = 1; + atr.att_atimechg = 1; + atr.att_mtime = req->mtime; + atr.att_atime = req->atime; + return __lchattr((char*) req->path, &atr, sizeof(atr)); +#else + errno = ENOSYS; + return -1; +#endif +} + + +static ssize_t uv__fs_lutime(uv_fs_t* req) { +#if defined(__linux__) || \ + defined(_AIX71) || \ + defined(__sun) || \ + defined(__HAIKU__) + struct timespec ts[2]; + ts[0] = uv__fs_to_timespec(req->atime); + ts[1] = uv__fs_to_timespec(req->mtime); + return utimensat(AT_FDCWD, req->path, ts, AT_SYMLINK_NOFOLLOW); +#elif defined(__APPLE__) || \ + defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || \ + defined(__NetBSD__) + struct timeval tv[2]; + tv[0] = uv__fs_to_timeval(req->atime); + tv[1] = uv__fs_to_timeval(req->mtime); + return lutimes(req->path, tv); +#else + errno = ENOSYS; + return -1; +#endif +} + + +static ssize_t uv__fs_write(uv_fs_t* req) { +#if defined(__linux__) + static int no_pwritev; +#endif + ssize_t r; + + /* Serialize writes on OS X, concurrent write() and pwrite() calls result in + * data loss. We can't use a per-file descriptor lock, the descriptor may be + * a dup(). + */ +#if defined(__APPLE__) + static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; + + if (pthread_mutex_lock(&lock)) + abort(); +#endif + + if (req->off < 0) { + if (req->nbufs == 1) + r = write(req->file, req->bufs[0].base, req->bufs[0].len); + else + r = writev(req->file, (struct iovec*) req->bufs, req->nbufs); + } else { + if (req->nbufs == 1) { + r = pwrite(req->file, req->bufs[0].base, req->bufs[0].len, req->off); + goto done; + } +#if HAVE_PREADV + r = pwritev(req->file, (struct iovec*) req->bufs, req->nbufs, req->off); +#else +# if defined(__linux__) + if (no_pwritev) retry: +# endif + { + r = pwrite(req->file, req->bufs[0].base, req->bufs[0].len, req->off); + } +# if defined(__linux__) + else { + r = uv__pwritev(req->file, + (struct iovec*) req->bufs, + req->nbufs, + req->off); + if (r == -1 && errno == ENOSYS) { + no_pwritev = 1; + goto retry; + } + } +# endif +#endif + } + +done: +#if defined(__APPLE__) + if (pthread_mutex_unlock(&lock)) + abort(); +#endif + + return r; +} + +static ssize_t uv__fs_copyfile(uv_fs_t* req) { + uv_fs_t fs_req; + uv_file srcfd; + uv_file dstfd; + struct stat src_statsbuf; + struct stat dst_statsbuf; + int dst_flags; + int result; + int err; + off_t bytes_to_send; + off_t in_offset; + off_t bytes_written; + size_t bytes_chunk; + + dstfd = -1; + err = 0; + + /* Open the source file. */ + srcfd = uv_fs_open(NULL, &fs_req, req->path, O_RDONLY, 0, NULL); + uv_fs_req_cleanup(&fs_req); + + if (srcfd < 0) + return srcfd; + + /* Get the source file's mode. */ + if (fstat(srcfd, &src_statsbuf)) { + err = UV__ERR(errno); + goto out; + } + + dst_flags = O_WRONLY | O_CREAT; + + if (req->flags & UV_FS_COPYFILE_EXCL) + dst_flags |= O_EXCL; + + /* Open the destination file. */ + dstfd = uv_fs_open(NULL, + &fs_req, + req->new_path, + dst_flags, + src_statsbuf.st_mode, + NULL); + uv_fs_req_cleanup(&fs_req); + + if (dstfd < 0) { + err = dstfd; + goto out; + } + + /* If the file is not being opened exclusively, verify that the source and + destination are not the same file. If they are the same, bail out early. */ + if ((req->flags & UV_FS_COPYFILE_EXCL) == 0) { + /* Get the destination file's mode. */ + if (fstat(dstfd, &dst_statsbuf)) { + err = UV__ERR(errno); + goto out; + } + + /* Check if srcfd and dstfd refer to the same file */ + if (src_statsbuf.st_dev == dst_statsbuf.st_dev && + src_statsbuf.st_ino == dst_statsbuf.st_ino) { + goto out; + } + + /* Truncate the file in case the destination already existed. */ + if (ftruncate(dstfd, 0) != 0) { + err = UV__ERR(errno); + goto out; + } + } + + if (fchmod(dstfd, src_statsbuf.st_mode) == -1) { + err = UV__ERR(errno); +#ifdef __linux__ + if (err != UV_EPERM) + goto out; + + { + struct statfs s; + + /* fchmod() on CIFS shares always fails with EPERM unless the share is + * mounted with "noperm". As fchmod() is a meaningless operation on such + * shares anyway, detect that condition and squelch the error. + */ + if (fstatfs(dstfd, &s) == -1) + goto out; + + if ((unsigned) s.f_type != /* CIFS */ 0xFF534D42u) + goto out; + } + + err = 0; +#else /* !__linux__ */ + goto out; +#endif /* !__linux__ */ + } + +#ifdef FICLONE + if (req->flags & UV_FS_COPYFILE_FICLONE || + req->flags & UV_FS_COPYFILE_FICLONE_FORCE) { + if (ioctl(dstfd, FICLONE, srcfd) == 0) { + /* ioctl() with FICLONE succeeded. */ + goto out; + } + /* If an error occurred and force was set, return the error to the caller; + * fall back to sendfile() when force was not set. */ + if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) { + err = UV__ERR(errno); + goto out; + } + } +#else + if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) { + err = UV_ENOSYS; + goto out; + } +#endif + + bytes_to_send = src_statsbuf.st_size; + in_offset = 0; + while (bytes_to_send != 0) { + bytes_chunk = SSIZE_MAX; + if (bytes_to_send < (off_t) bytes_chunk) + bytes_chunk = bytes_to_send; + uv_fs_sendfile(NULL, &fs_req, dstfd, srcfd, in_offset, bytes_chunk, NULL); + bytes_written = fs_req.result; + uv_fs_req_cleanup(&fs_req); + + if (bytes_written < 0) { + err = bytes_written; + break; + } + + bytes_to_send -= bytes_written; + in_offset += bytes_written; + } + +out: + if (err < 0) + result = err; + else + result = 0; + + /* Close the source file. */ + err = uv__close_nocheckstdio(srcfd); + + /* Don't overwrite any existing errors. */ + if (err != 0 && result == 0) + result = err; + + /* Close the destination file if it is open. */ + if (dstfd >= 0) { + err = uv__close_nocheckstdio(dstfd); + + /* Don't overwrite any existing errors. */ + if (err != 0 && result == 0) + result = err; + + /* Remove the destination file if something went wrong. */ + if (result != 0) { + uv_fs_unlink(NULL, &fs_req, req->new_path, NULL); + /* Ignore the unlink return value, as an error already happened. */ + uv_fs_req_cleanup(&fs_req); + } + } + + if (result == 0) + return 0; + + errno = UV__ERR(result); + return -1; +} + +static void uv__to_stat(struct stat* src, uv_stat_t* dst) { + dst->st_dev = src->st_dev; + dst->st_mode = src->st_mode; + dst->st_nlink = src->st_nlink; + dst->st_uid = src->st_uid; + dst->st_gid = src->st_gid; + dst->st_rdev = src->st_rdev; + dst->st_ino = src->st_ino; + dst->st_size = src->st_size; + dst->st_blksize = src->st_blksize; + dst->st_blocks = src->st_blocks; + +#if defined(__APPLE__) + dst->st_atim.tv_sec = src->st_atimespec.tv_sec; + dst->st_atim.tv_nsec = src->st_atimespec.tv_nsec; + dst->st_mtim.tv_sec = src->st_mtimespec.tv_sec; + dst->st_mtim.tv_nsec = src->st_mtimespec.tv_nsec; + dst->st_ctim.tv_sec = src->st_ctimespec.tv_sec; + dst->st_ctim.tv_nsec = src->st_ctimespec.tv_nsec; + dst->st_birthtim.tv_sec = src->st_birthtimespec.tv_sec; + dst->st_birthtim.tv_nsec = src->st_birthtimespec.tv_nsec; + dst->st_flags = src->st_flags; + dst->st_gen = src->st_gen; +#elif defined(__ANDROID__) + dst->st_atim.tv_sec = src->st_atime; + dst->st_atim.tv_nsec = src->st_atimensec; + dst->st_mtim.tv_sec = src->st_mtime; + dst->st_mtim.tv_nsec = src->st_mtimensec; + dst->st_ctim.tv_sec = src->st_ctime; + dst->st_ctim.tv_nsec = src->st_ctimensec; + dst->st_birthtim.tv_sec = src->st_ctime; + dst->st_birthtim.tv_nsec = src->st_ctimensec; + dst->st_flags = 0; + dst->st_gen = 0; +#elif !defined(_AIX) && \ + !defined(__MVS__) && ( \ + defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__OpenBSD__) || \ + defined(__NetBSD__) || \ + defined(_GNU_SOURCE) || \ + defined(_BSD_SOURCE) || \ + defined(_SVID_SOURCE) || \ + defined(_XOPEN_SOURCE) || \ + defined(_DEFAULT_SOURCE)) + dst->st_atim.tv_sec = src->st_atim.tv_sec; + dst->st_atim.tv_nsec = src->st_atim.tv_nsec; + dst->st_mtim.tv_sec = src->st_mtim.tv_sec; + dst->st_mtim.tv_nsec = src->st_mtim.tv_nsec; + dst->st_ctim.tv_sec = src->st_ctim.tv_sec; + dst->st_ctim.tv_nsec = src->st_ctim.tv_nsec; +# if defined(__FreeBSD__) || \ + defined(__NetBSD__) + dst->st_birthtim.tv_sec = src->st_birthtim.tv_sec; + dst->st_birthtim.tv_nsec = src->st_birthtim.tv_nsec; + dst->st_flags = src->st_flags; + dst->st_gen = src->st_gen; +# else + dst->st_birthtim.tv_sec = src->st_ctim.tv_sec; + dst->st_birthtim.tv_nsec = src->st_ctim.tv_nsec; + dst->st_flags = 0; + dst->st_gen = 0; +# endif +#else + dst->st_atim.tv_sec = src->st_atime; + dst->st_atim.tv_nsec = 0; + dst->st_mtim.tv_sec = src->st_mtime; + dst->st_mtim.tv_nsec = 0; + dst->st_ctim.tv_sec = src->st_ctime; + dst->st_ctim.tv_nsec = 0; + dst->st_birthtim.tv_sec = src->st_ctime; + dst->st_birthtim.tv_nsec = 0; + dst->st_flags = 0; + dst->st_gen = 0; +#endif +} + + +static int uv__fs_statx(int fd, + const char* path, + int is_fstat, + int is_lstat, + uv_stat_t* buf) { + STATIC_ASSERT(UV_ENOSYS != -1); +#ifdef __linux__ + static int no_statx; + struct uv__statx statxbuf; + int dirfd; + int flags; + int mode; + int rc; + + if (uv__load_relaxed(&no_statx)) + return UV_ENOSYS; + + dirfd = AT_FDCWD; + flags = 0; /* AT_STATX_SYNC_AS_STAT */ + mode = 0xFFF; /* STATX_BASIC_STATS + STATX_BTIME */ + + if (is_fstat) { + dirfd = fd; + flags |= 0x1000; /* AT_EMPTY_PATH */ + } + + if (is_lstat) + flags |= AT_SYMLINK_NOFOLLOW; + + rc = uv__statx(dirfd, path, flags, mode, &statxbuf); + + switch (rc) { + case 0: + break; + case -1: + /* EPERM happens when a seccomp filter rejects the system call. + * Has been observed with libseccomp < 2.3.3 and docker < 18.04. + * EOPNOTSUPP is used on DVS exported filesystems + */ + if (errno != EINVAL && errno != EPERM && errno != ENOSYS && errno != EOPNOTSUPP) + return -1; + /* Fall through. */ + default: + /* Normally on success, zero is returned and On error, -1 is returned. + * Observed on S390 RHEL running in a docker container with statx not + * implemented, rc might return 1 with 0 set as the error code in which + * case we return ENOSYS. + */ + uv__store_relaxed(&no_statx, 1); + return UV_ENOSYS; + } + + buf->st_dev = makedev(statxbuf.stx_dev_major, statxbuf.stx_dev_minor); + buf->st_mode = statxbuf.stx_mode; + buf->st_nlink = statxbuf.stx_nlink; + buf->st_uid = statxbuf.stx_uid; + buf->st_gid = statxbuf.stx_gid; + buf->st_rdev = makedev(statxbuf.stx_rdev_major, statxbuf.stx_rdev_minor); + buf->st_ino = statxbuf.stx_ino; + buf->st_size = statxbuf.stx_size; + buf->st_blksize = statxbuf.stx_blksize; + buf->st_blocks = statxbuf.stx_blocks; + buf->st_atim.tv_sec = statxbuf.stx_atime.tv_sec; + buf->st_atim.tv_nsec = statxbuf.stx_atime.tv_nsec; + buf->st_mtim.tv_sec = statxbuf.stx_mtime.tv_sec; + buf->st_mtim.tv_nsec = statxbuf.stx_mtime.tv_nsec; + buf->st_ctim.tv_sec = statxbuf.stx_ctime.tv_sec; + buf->st_ctim.tv_nsec = statxbuf.stx_ctime.tv_nsec; + buf->st_birthtim.tv_sec = statxbuf.stx_btime.tv_sec; + buf->st_birthtim.tv_nsec = statxbuf.stx_btime.tv_nsec; + buf->st_flags = 0; + buf->st_gen = 0; + + return 0; +#else + return UV_ENOSYS; +#endif /* __linux__ */ +} + + +static int uv__fs_stat(const char *path, uv_stat_t *buf) { + struct stat pbuf; + int ret; + + ret = uv__fs_statx(-1, path, /* is_fstat */ 0, /* is_lstat */ 0, buf); + if (ret != UV_ENOSYS) + return ret; + + ret = stat(path, &pbuf); + if (ret == 0) + uv__to_stat(&pbuf, buf); + + return ret; +} + + +static int uv__fs_lstat(const char *path, uv_stat_t *buf) { + struct stat pbuf; + int ret; + + ret = uv__fs_statx(-1, path, /* is_fstat */ 0, /* is_lstat */ 1, buf); + if (ret != UV_ENOSYS) + return ret; + + ret = lstat(path, &pbuf); + if (ret == 0) + uv__to_stat(&pbuf, buf); + + return ret; +} + + +static int uv__fs_fstat(int fd, uv_stat_t *buf) { + struct stat pbuf; + int ret; + + ret = uv__fs_statx(fd, "", /* is_fstat */ 1, /* is_lstat */ 0, buf); + if (ret != UV_ENOSYS) + return ret; + + ret = fstat(fd, &pbuf); + if (ret == 0) + uv__to_stat(&pbuf, buf); + + return ret; +} + +static size_t uv__fs_buf_offset(uv_buf_t* bufs, size_t size) { + size_t offset; + /* Figure out which bufs are done */ + for (offset = 0; size > 0 && bufs[offset].len <= size; ++offset) + size -= bufs[offset].len; + + /* Fix a partial read/write */ + if (size > 0) { + bufs[offset].base += size; + bufs[offset].len -= size; + } + return offset; +} + +static ssize_t uv__fs_write_all(uv_fs_t* req) { + unsigned int iovmax; + unsigned int nbufs; + uv_buf_t* bufs; + ssize_t total; + ssize_t result; + + iovmax = uv__getiovmax(); + nbufs = req->nbufs; + bufs = req->bufs; + total = 0; + + while (nbufs > 0) { + req->nbufs = nbufs; + if (req->nbufs > iovmax) + req->nbufs = iovmax; + + do + result = uv__fs_write(req); + while (result < 0 && errno == EINTR); + + if (result <= 0) { + if (total == 0) + total = result; + break; + } + + if (req->off >= 0) + req->off += result; + + req->nbufs = uv__fs_buf_offset(req->bufs, result); + req->bufs += req->nbufs; + nbufs -= req->nbufs; + total += result; + } + + if (bufs != req->bufsml) + uv__free(bufs); + + req->bufs = NULL; + req->nbufs = 0; + + return total; +} + + +static void uv__fs_work(struct uv__work* w) { + int retry_on_eintr; + uv_fs_t* req; + ssize_t r; + + req = container_of(w, uv_fs_t, work_req); + retry_on_eintr = !(req->fs_type == UV_FS_CLOSE || + req->fs_type == UV_FS_READ); + + do { + errno = 0; + +#define X(type, action) \ + case UV_FS_ ## type: \ + r = action; \ + break; + + switch (req->fs_type) { + X(ACCESS, access(req->path, req->flags)); + X(CHMOD, chmod(req->path, req->mode)); + X(CHOWN, chown(req->path, req->uid, req->gid)); + X(CLOSE, uv__fs_close(req->file)); + X(COPYFILE, uv__fs_copyfile(req)); + X(FCHMOD, fchmod(req->file, req->mode)); + X(FCHOWN, fchown(req->file, req->uid, req->gid)); + X(LCHOWN, lchown(req->path, req->uid, req->gid)); + X(FDATASYNC, uv__fs_fdatasync(req)); + X(FSTAT, uv__fs_fstat(req->file, &req->statbuf)); + X(FSYNC, uv__fs_fsync(req)); + X(FTRUNCATE, ftruncate(req->file, req->off)); + X(FUTIME, uv__fs_futime(req)); + X(LUTIME, uv__fs_lutime(req)); + X(LSTAT, uv__fs_lstat(req->path, &req->statbuf)); + X(LINK, link(req->path, req->new_path)); + X(MKDIR, mkdir(req->path, req->mode)); + X(MKDTEMP, uv__fs_mkdtemp(req)); + X(MKSTEMP, uv__fs_mkstemp(req)); + X(OPEN, uv__fs_open(req)); + X(READ, uv__fs_read(req)); + X(SCANDIR, uv__fs_scandir(req)); + X(OPENDIR, uv__fs_opendir(req)); + X(READDIR, uv__fs_readdir(req)); + X(CLOSEDIR, uv__fs_closedir(req)); + X(READLINK, uv__fs_readlink(req)); + X(REALPATH, uv__fs_realpath(req)); + X(RENAME, rename(req->path, req->new_path)); + X(RMDIR, rmdir(req->path)); + X(SENDFILE, uv__fs_sendfile(req)); + X(STAT, uv__fs_stat(req->path, &req->statbuf)); + X(STATFS, uv__fs_statfs(req)); + X(SYMLINK, symlink(req->path, req->new_path)); + X(UNLINK, unlink(req->path)); + X(UTIME, uv__fs_utime(req)); + X(WRITE, uv__fs_write_all(req)); + default: abort(); + } +#undef X + } while (r == -1 && errno == EINTR && retry_on_eintr); + + if (r == -1) + req->result = UV__ERR(errno); + else + req->result = r; + + if (r == 0 && (req->fs_type == UV_FS_STAT || + req->fs_type == UV_FS_FSTAT || + req->fs_type == UV_FS_LSTAT)) { + req->ptr = &req->statbuf; + } +} + + +static void uv__fs_done(struct uv__work* w, int status) { + uv_fs_t* req; + + req = container_of(w, uv_fs_t, work_req); + uv__req_unregister(req->loop, req); + + if (status == UV_ECANCELED) { + assert(req->result == 0); + req->result = UV_ECANCELED; + } + + req->cb(req); +} + + +int uv_fs_access(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int flags, + uv_fs_cb cb) { + INIT(ACCESS); + PATH; + req->flags = flags; + POST; +} + + +int uv_fs_chmod(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int mode, + uv_fs_cb cb) { + INIT(CHMOD); + PATH; + req->mode = mode; + POST; +} + + +int uv_fs_chown(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_uid_t uid, + uv_gid_t gid, + uv_fs_cb cb) { + INIT(CHOWN); + PATH; + req->uid = uid; + req->gid = gid; + POST; +} + + +int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) { + INIT(CLOSE); + req->file = file; + POST; +} + + +int uv_fs_fchmod(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + int mode, + uv_fs_cb cb) { + INIT(FCHMOD); + req->file = file; + req->mode = mode; + POST; +} + + +int uv_fs_fchown(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + uv_uid_t uid, + uv_gid_t gid, + uv_fs_cb cb) { + INIT(FCHOWN); + req->file = file; + req->uid = uid; + req->gid = gid; + POST; +} + + +int uv_fs_lchown(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_uid_t uid, + uv_gid_t gid, + uv_fs_cb cb) { + INIT(LCHOWN); + PATH; + req->uid = uid; + req->gid = gid; + POST; +} + + +int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) { + INIT(FDATASYNC); + req->file = file; + POST; +} + + +int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) { + INIT(FSTAT); + req->file = file; + POST; +} + + +int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) { + INIT(FSYNC); + req->file = file; + POST; +} + + +int uv_fs_ftruncate(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + int64_t off, + uv_fs_cb cb) { + INIT(FTRUNCATE); + req->file = file; + req->off = off; + POST; +} + + +int uv_fs_futime(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + double atime, + double mtime, + uv_fs_cb cb) { + INIT(FUTIME); + req->file = file; + req->atime = atime; + req->mtime = mtime; + POST; +} + +int uv_fs_lutime(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + double atime, + double mtime, + uv_fs_cb cb) { + INIT(LUTIME); + PATH; + req->atime = atime; + req->mtime = mtime; + POST; +} + + +int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { + INIT(LSTAT); + PATH; + POST; +} + + +int uv_fs_link(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + uv_fs_cb cb) { + INIT(LINK); + PATH2; + POST; +} + + +int uv_fs_mkdir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int mode, + uv_fs_cb cb) { + INIT(MKDIR); + PATH; + req->mode = mode; + POST; +} + + +int uv_fs_mkdtemp(uv_loop_t* loop, + uv_fs_t* req, + const char* tpl, + uv_fs_cb cb) { + INIT(MKDTEMP); + req->path = uv__strdup(tpl); + if (req->path == NULL) + return UV_ENOMEM; + POST; +} + + +int uv_fs_mkstemp(uv_loop_t* loop, + uv_fs_t* req, + const char* tpl, + uv_fs_cb cb) { + INIT(MKSTEMP); + req->path = uv__strdup(tpl); + if (req->path == NULL) + return UV_ENOMEM; + POST; +} + + +int uv_fs_open(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int flags, + int mode, + uv_fs_cb cb) { + INIT(OPEN); + PATH; + req->flags = flags; + req->mode = mode; + POST; +} + + +int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, + uv_file file, + const uv_buf_t bufs[], + unsigned int nbufs, + int64_t off, + uv_fs_cb cb) { + INIT(READ); + + if (bufs == NULL || nbufs == 0) + return UV_EINVAL; + + req->file = file; + + req->nbufs = nbufs; + req->bufs = req->bufsml; + if (nbufs > ARRAY_SIZE(req->bufsml)) + req->bufs = uv__malloc(nbufs * sizeof(*bufs)); + + if (req->bufs == NULL) + return UV_ENOMEM; + + memcpy(req->bufs, bufs, nbufs * sizeof(*bufs)); + + req->off = off; + POST; +} + + +int uv_fs_scandir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int flags, + uv_fs_cb cb) { + INIT(SCANDIR); + PATH; + req->flags = flags; + POST; +} + +int uv_fs_opendir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb) { + INIT(OPENDIR); + PATH; + POST; +} + +int uv_fs_readdir(uv_loop_t* loop, + uv_fs_t* req, + uv_dir_t* dir, + uv_fs_cb cb) { + INIT(READDIR); + + if (dir == NULL || dir->dir == NULL || dir->dirents == NULL) + return UV_EINVAL; + + req->ptr = dir; + POST; +} + +int uv_fs_closedir(uv_loop_t* loop, + uv_fs_t* req, + uv_dir_t* dir, + uv_fs_cb cb) { + INIT(CLOSEDIR); + + if (dir == NULL) + return UV_EINVAL; + + req->ptr = dir; + POST; +} + +int uv_fs_readlink(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb) { + INIT(READLINK); + PATH; + POST; +} + + +int uv_fs_realpath(uv_loop_t* loop, + uv_fs_t* req, + const char * path, + uv_fs_cb cb) { + INIT(REALPATH); + PATH; + POST; +} + + +int uv_fs_rename(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + uv_fs_cb cb) { + INIT(RENAME); + PATH2; + POST; +} + + +int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { + INIT(RMDIR); + PATH; + POST; +} + + +int uv_fs_sendfile(uv_loop_t* loop, + uv_fs_t* req, + uv_file out_fd, + uv_file in_fd, + int64_t off, + size_t len, + uv_fs_cb cb) { + INIT(SENDFILE); + req->flags = in_fd; /* hack */ + req->file = out_fd; + req->off = off; + req->bufsml[0].len = len; + POST; +} + + +int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { + INIT(STAT); + PATH; + POST; +} + + +int uv_fs_symlink(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + int flags, + uv_fs_cb cb) { + INIT(SYMLINK); + PATH2; + req->flags = flags; + POST; +} + + +int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { + INIT(UNLINK); + PATH; + POST; +} + + +int uv_fs_utime(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + double atime, + double mtime, + uv_fs_cb cb) { + INIT(UTIME); + PATH; + req->atime = atime; + req->mtime = mtime; + POST; +} + + +int uv_fs_write(uv_loop_t* loop, + uv_fs_t* req, + uv_file file, + const uv_buf_t bufs[], + unsigned int nbufs, + int64_t off, + uv_fs_cb cb) { + INIT(WRITE); + + if (bufs == NULL || nbufs == 0) + return UV_EINVAL; + + req->file = file; + + req->nbufs = nbufs; + req->bufs = req->bufsml; + if (nbufs > ARRAY_SIZE(req->bufsml)) + req->bufs = uv__malloc(nbufs * sizeof(*bufs)); + + if (req->bufs == NULL) + return UV_ENOMEM; + + memcpy(req->bufs, bufs, nbufs * sizeof(*bufs)); + + req->off = off; + POST; +} + + +void uv_fs_req_cleanup(uv_fs_t* req) { + if (req == NULL) + return; + + /* Only necessary for asychronous requests, i.e., requests with a callback. + * Synchronous ones don't copy their arguments and have req->path and + * req->new_path pointing to user-owned memory. UV_FS_MKDTEMP and + * UV_FS_MKSTEMP are the exception to the rule, they always allocate memory. + */ + if (req->path != NULL && + (req->cb != NULL || + req->fs_type == UV_FS_MKDTEMP || req->fs_type == UV_FS_MKSTEMP)) + uv__free((void*) req->path); /* Memory is shared with req->new_path. */ + + req->path = NULL; + req->new_path = NULL; + + if (req->fs_type == UV_FS_READDIR && req->ptr != NULL) + uv__fs_readdir_cleanup(req); + + if (req->fs_type == UV_FS_SCANDIR && req->ptr != NULL) + uv__fs_scandir_cleanup(req); + + if (req->bufs != req->bufsml) + uv__free(req->bufs); + req->bufs = NULL; + + if (req->fs_type != UV_FS_OPENDIR && req->ptr != &req->statbuf) + uv__free(req->ptr); + req->ptr = NULL; +} + + +int uv_fs_copyfile(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + int flags, + uv_fs_cb cb) { + INIT(COPYFILE); + + if (flags & ~(UV_FS_COPYFILE_EXCL | + UV_FS_COPYFILE_FICLONE | + UV_FS_COPYFILE_FICLONE_FORCE)) { + return UV_EINVAL; + } + + PATH2; + req->flags = flags; + POST; +} + + +int uv_fs_statfs(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb) { + INIT(STATFS); + PATH; + POST; +} + +int uv_fs_get_system_error(const uv_fs_t* req) { + return -req->result; +} diff --git a/external/src/libuv/src/unix/fsevents.c b/external/src/libuv/src/unix/fsevents.c new file mode 100644 index 0000000..bf4f1f6 --- /dev/null +++ b/external/src/libuv/src/unix/fsevents.c @@ -0,0 +1,916 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#if TARGET_OS_IPHONE || MAC_OS_X_VERSION_MAX_ALLOWED < 1070 + +/* iOS (currently) doesn't provide the FSEvents-API (nor CoreServices) */ +/* macOS prior to 10.7 doesn't provide the full FSEvents API so use kqueue */ + +int uv__fsevents_init(uv_fs_event_t* handle) { + return 0; +} + + +int uv__fsevents_close(uv_fs_event_t* handle) { + return 0; +} + + +void uv__fsevents_loop_delete(uv_loop_t* loop) { +} + +#else /* TARGET_OS_IPHONE */ + +#include "darwin-stub.h" + +#include +#include +#include +#include + +static const int kFSEventsModified = + kFSEventStreamEventFlagItemChangeOwner | + kFSEventStreamEventFlagItemFinderInfoMod | + kFSEventStreamEventFlagItemInodeMetaMod | + kFSEventStreamEventFlagItemModified | + kFSEventStreamEventFlagItemXattrMod; + +static const int kFSEventsRenamed = + kFSEventStreamEventFlagItemCreated | + kFSEventStreamEventFlagItemRemoved | + kFSEventStreamEventFlagItemRenamed; + +static const int kFSEventsSystem = + kFSEventStreamEventFlagUserDropped | + kFSEventStreamEventFlagKernelDropped | + kFSEventStreamEventFlagEventIdsWrapped | + kFSEventStreamEventFlagHistoryDone | + kFSEventStreamEventFlagMount | + kFSEventStreamEventFlagUnmount | + kFSEventStreamEventFlagRootChanged; + +typedef struct uv__fsevents_event_s uv__fsevents_event_t; +typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t; +typedef struct uv__cf_loop_state_s uv__cf_loop_state_t; + +enum uv__cf_loop_signal_type_e { + kUVCFLoopSignalRegular, + kUVCFLoopSignalClosing +}; +typedef enum uv__cf_loop_signal_type_e uv__cf_loop_signal_type_t; + +struct uv__cf_loop_signal_s { + QUEUE member; + uv_fs_event_t* handle; + uv__cf_loop_signal_type_t type; +}; + +struct uv__fsevents_event_s { + QUEUE member; + int events; + char path[1]; +}; + +struct uv__cf_loop_state_s { + CFRunLoopRef loop; + CFRunLoopSourceRef signal_source; + int fsevent_need_reschedule; + FSEventStreamRef fsevent_stream; + uv_sem_t fsevent_sem; + uv_mutex_t fsevent_mutex; + void* fsevent_handles[2]; + unsigned int fsevent_handle_count; +}; + +/* Forward declarations */ +static void uv__cf_loop_cb(void* arg); +static void* uv__cf_loop_runner(void* arg); +static int uv__cf_loop_signal(uv_loop_t* loop, + uv_fs_event_t* handle, + uv__cf_loop_signal_type_t type); + +/* Lazy-loaded by uv__fsevents_global_init(). */ +static CFArrayRef (*pCFArrayCreate)(CFAllocatorRef, + const void**, + CFIndex, + const CFArrayCallBacks*); +static void (*pCFRelease)(CFTypeRef); +static void (*pCFRunLoopAddSource)(CFRunLoopRef, + CFRunLoopSourceRef, + CFStringRef); +static CFRunLoopRef (*pCFRunLoopGetCurrent)(void); +static void (*pCFRunLoopRemoveSource)(CFRunLoopRef, + CFRunLoopSourceRef, + CFStringRef); +static void (*pCFRunLoopRun)(void); +static CFRunLoopSourceRef (*pCFRunLoopSourceCreate)(CFAllocatorRef, + CFIndex, + CFRunLoopSourceContext*); +static void (*pCFRunLoopSourceSignal)(CFRunLoopSourceRef); +static void (*pCFRunLoopStop)(CFRunLoopRef); +static void (*pCFRunLoopWakeUp)(CFRunLoopRef); +static CFStringRef (*pCFStringCreateWithFileSystemRepresentation)( + CFAllocatorRef, + const char*); +static CFStringEncoding (*pCFStringGetSystemEncoding)(void); +static CFStringRef (*pkCFRunLoopDefaultMode); +static FSEventStreamRef (*pFSEventStreamCreate)(CFAllocatorRef, + FSEventStreamCallback, + FSEventStreamContext*, + CFArrayRef, + FSEventStreamEventId, + CFTimeInterval, + FSEventStreamCreateFlags); +static void (*pFSEventStreamFlushSync)(FSEventStreamRef); +static void (*pFSEventStreamInvalidate)(FSEventStreamRef); +static void (*pFSEventStreamRelease)(FSEventStreamRef); +static void (*pFSEventStreamScheduleWithRunLoop)(FSEventStreamRef, + CFRunLoopRef, + CFStringRef); +static int (*pFSEventStreamStart)(FSEventStreamRef); +static void (*pFSEventStreamStop)(FSEventStreamRef); + +#define UV__FSEVENTS_PROCESS(handle, block) \ + do { \ + QUEUE events; \ + QUEUE* q; \ + uv__fsevents_event_t* event; \ + int err; \ + uv_mutex_lock(&(handle)->cf_mutex); \ + /* Split-off all events and empty original queue */ \ + QUEUE_MOVE(&(handle)->cf_events, &events); \ + /* Get error (if any) and zero original one */ \ + err = (handle)->cf_error; \ + (handle)->cf_error = 0; \ + uv_mutex_unlock(&(handle)->cf_mutex); \ + /* Loop through events, deallocating each after processing */ \ + while (!QUEUE_EMPTY(&events)) { \ + q = QUEUE_HEAD(&events); \ + event = QUEUE_DATA(q, uv__fsevents_event_t, member); \ + QUEUE_REMOVE(q); \ + /* NOTE: Checking uv__is_active() is required here, because handle \ + * callback may close handle and invoking it after it will lead to \ + * incorrect behaviour */ \ + if (!uv__is_closing((handle)) && uv__is_active((handle))) \ + block \ + /* Free allocated data */ \ + uv__free(event); \ + } \ + if (err != 0 && !uv__is_closing((handle)) && uv__is_active((handle))) \ + (handle)->cb((handle), NULL, 0, err); \ + } while (0) + + +/* Runs in UV loop's thread, when there're events to report to handle */ +static void uv__fsevents_cb(uv_async_t* cb) { + uv_fs_event_t* handle; + + handle = cb->data; + + UV__FSEVENTS_PROCESS(handle, { + handle->cb(handle, event->path[0] ? event->path : NULL, event->events, 0); + }); +} + + +/* Runs in CF thread, pushed event into handle's event list */ +static void uv__fsevents_push_event(uv_fs_event_t* handle, + QUEUE* events, + int err) { + assert(events != NULL || err != 0); + uv_mutex_lock(&handle->cf_mutex); + + /* Concatenate two queues */ + if (events != NULL) + QUEUE_ADD(&handle->cf_events, events); + + /* Propagate error */ + if (err != 0) + handle->cf_error = err; + uv_mutex_unlock(&handle->cf_mutex); + + uv_async_send(handle->cf_cb); +} + + +/* Runs in CF thread, when there're events in FSEventStream */ +static void uv__fsevents_event_cb(const FSEventStreamRef streamRef, + void* info, + size_t numEvents, + void* eventPaths, + const FSEventStreamEventFlags eventFlags[], + const FSEventStreamEventId eventIds[]) { + size_t i; + int len; + char** paths; + char* path; + char* pos; + uv_fs_event_t* handle; + QUEUE* q; + uv_loop_t* loop; + uv__cf_loop_state_t* state; + uv__fsevents_event_t* event; + FSEventStreamEventFlags flags; + QUEUE head; + + loop = info; + state = loop->cf_state; + assert(state != NULL); + paths = eventPaths; + + /* For each handle */ + uv_mutex_lock(&state->fsevent_mutex); + QUEUE_FOREACH(q, &state->fsevent_handles) { + handle = QUEUE_DATA(q, uv_fs_event_t, cf_member); + QUEUE_INIT(&head); + + /* Process and filter out events */ + for (i = 0; i < numEvents; i++) { + flags = eventFlags[i]; + + /* Ignore system events */ + if (flags & kFSEventsSystem) + continue; + + path = paths[i]; + len = strlen(path); + + if (handle->realpath_len == 0) + continue; /* This should be unreachable */ + + /* Filter out paths that are outside handle's request */ + if (len < handle->realpath_len) + continue; + + /* Make sure that realpath actually named a directory, + * (unless watching root, which alone keeps a trailing slash on the realpath) + * or that we matched the whole string */ + if (handle->realpath_len != len && + handle->realpath_len > 1 && + path[handle->realpath_len] != '/') + continue; + + if (memcmp(path, handle->realpath, handle->realpath_len) != 0) + continue; + + if (!(handle->realpath_len == 1 && handle->realpath[0] == '/')) { + /* Remove common prefix, unless the watched folder is "/" */ + path += handle->realpath_len; + len -= handle->realpath_len; + + /* Ignore events with path equal to directory itself */ + if (len <= 1 && (flags & kFSEventStreamEventFlagItemIsDir)) + continue; + + if (len == 0) { + /* Since we're using fsevents to watch the file itself, + * realpath == path, and we now need to get the basename of the file back + * (for commonality with other codepaths and platforms). */ + while (len < handle->realpath_len && path[-1] != '/') { + path--; + len++; + } + /* Created and Removed seem to be always set, but don't make sense */ + flags &= ~kFSEventsRenamed; + } else { + /* Skip forward slash */ + path++; + len--; + } + } + + /* Do not emit events from subdirectories (without option set) */ + if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 && *path != '\0') { + pos = strchr(path + 1, '/'); + if (pos != NULL) + continue; + } + + event = uv__malloc(sizeof(*event) + len); + if (event == NULL) + break; + + memset(event, 0, sizeof(*event)); + memcpy(event->path, path, len + 1); + event->events = UV_RENAME; + + if (0 == (flags & kFSEventsRenamed)) { + if (0 != (flags & kFSEventsModified) || + 0 == (flags & kFSEventStreamEventFlagItemIsDir)) + event->events = UV_CHANGE; + } + + QUEUE_INSERT_TAIL(&head, &event->member); + } + + if (!QUEUE_EMPTY(&head)) + uv__fsevents_push_event(handle, &head, 0); + } + uv_mutex_unlock(&state->fsevent_mutex); +} + + +/* Runs in CF thread */ +static int uv__fsevents_create_stream(uv_loop_t* loop, CFArrayRef paths) { + uv__cf_loop_state_t* state; + FSEventStreamContext ctx; + FSEventStreamRef ref; + CFAbsoluteTime latency; + FSEventStreamCreateFlags flags; + + /* Initialize context */ + memset(&ctx, 0, sizeof(ctx)); + ctx.info = loop; + + latency = 0.05; + + /* Explanation of selected flags: + * 1. NoDefer - without this flag, events that are happening continuously + * (i.e. each event is happening after time interval less than `latency`, + * counted from previous event), will be deferred and passed to callback + * once they'll either fill whole OS buffer, or when this continuous stream + * will stop (i.e. there'll be delay between events, bigger than + * `latency`). + * Specifying this flag will invoke callback after `latency` time passed + * since event. + * 2. FileEvents - fire callback for file changes too (by default it is firing + * it only for directory changes). + */ + flags = kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents; + + /* + * NOTE: It might sound like a good idea to remember last seen StreamEventId, + * but in reality one dir might have last StreamEventId less than, the other, + * that is being watched now. Which will cause FSEventStream API to report + * changes to files from the past. + */ + ref = pFSEventStreamCreate(NULL, + &uv__fsevents_event_cb, + &ctx, + paths, + kFSEventStreamEventIdSinceNow, + latency, + flags); + assert(ref != NULL); + + state = loop->cf_state; + pFSEventStreamScheduleWithRunLoop(ref, + state->loop, + *pkCFRunLoopDefaultMode); + if (!pFSEventStreamStart(ref)) { + pFSEventStreamInvalidate(ref); + pFSEventStreamRelease(ref); + return UV_EMFILE; + } + + state->fsevent_stream = ref; + return 0; +} + + +/* Runs in CF thread */ +static void uv__fsevents_destroy_stream(uv_loop_t* loop) { + uv__cf_loop_state_t* state; + + state = loop->cf_state; + + if (state->fsevent_stream == NULL) + return; + + /* Stop emitting events */ + pFSEventStreamStop(state->fsevent_stream); + + /* Release stream */ + pFSEventStreamInvalidate(state->fsevent_stream); + pFSEventStreamRelease(state->fsevent_stream); + state->fsevent_stream = NULL; +} + + +/* Runs in CF thread, when there're new fsevent handles to add to stream */ +static void uv__fsevents_reschedule(uv_fs_event_t* handle, + uv__cf_loop_signal_type_t type) { + uv__cf_loop_state_t* state; + QUEUE* q; + uv_fs_event_t* curr; + CFArrayRef cf_paths; + CFStringRef* paths; + unsigned int i; + int err; + unsigned int path_count; + + state = handle->loop->cf_state; + paths = NULL; + cf_paths = NULL; + err = 0; + /* NOTE: `i` is used in deallocation loop below */ + i = 0; + + /* Optimization to prevent O(n^2) time spent when starting to watch + * many files simultaneously + */ + uv_mutex_lock(&state->fsevent_mutex); + if (state->fsevent_need_reschedule == 0) { + uv_mutex_unlock(&state->fsevent_mutex); + goto final; + } + state->fsevent_need_reschedule = 0; + uv_mutex_unlock(&state->fsevent_mutex); + + /* Destroy previous FSEventStream */ + uv__fsevents_destroy_stream(handle->loop); + + /* Any failure below will be a memory failure */ + err = UV_ENOMEM; + + /* Create list of all watched paths */ + uv_mutex_lock(&state->fsevent_mutex); + path_count = state->fsevent_handle_count; + if (path_count != 0) { + paths = uv__malloc(sizeof(*paths) * path_count); + if (paths == NULL) { + uv_mutex_unlock(&state->fsevent_mutex); + goto final; + } + + q = &state->fsevent_handles; + for (; i < path_count; i++) { + q = QUEUE_NEXT(q); + assert(q != &state->fsevent_handles); + curr = QUEUE_DATA(q, uv_fs_event_t, cf_member); + + assert(curr->realpath != NULL); + paths[i] = + pCFStringCreateWithFileSystemRepresentation(NULL, curr->realpath); + if (paths[i] == NULL) { + uv_mutex_unlock(&state->fsevent_mutex); + goto final; + } + } + } + uv_mutex_unlock(&state->fsevent_mutex); + err = 0; + + if (path_count != 0) { + /* Create new FSEventStream */ + cf_paths = pCFArrayCreate(NULL, (const void**) paths, path_count, NULL); + if (cf_paths == NULL) { + err = UV_ENOMEM; + goto final; + } + err = uv__fsevents_create_stream(handle->loop, cf_paths); + } + +final: + /* Deallocate all paths in case of failure */ + if (err != 0) { + if (cf_paths == NULL) { + while (i != 0) + pCFRelease(paths[--i]); + uv__free(paths); + } else { + /* CFArray takes ownership of both strings and original C-array */ + pCFRelease(cf_paths); + } + + /* Broadcast error to all handles */ + uv_mutex_lock(&state->fsevent_mutex); + QUEUE_FOREACH(q, &state->fsevent_handles) { + curr = QUEUE_DATA(q, uv_fs_event_t, cf_member); + uv__fsevents_push_event(curr, NULL, err); + } + uv_mutex_unlock(&state->fsevent_mutex); + } + + /* + * Main thread will block until the removal of handle from the list, + * we must tell it when we're ready. + * + * NOTE: This is coupled with `uv_sem_wait()` in `uv__fsevents_close` + */ + if (type == kUVCFLoopSignalClosing) + uv_sem_post(&state->fsevent_sem); +} + + +static int uv__fsevents_global_init(void) { + static pthread_mutex_t global_init_mutex = PTHREAD_MUTEX_INITIALIZER; + static void* core_foundation_handle; + static void* core_services_handle; + int err; + + err = 0; + pthread_mutex_lock(&global_init_mutex); + if (core_foundation_handle != NULL) + goto out; + + /* The libraries are never unloaded because we currently don't have a good + * mechanism for keeping a reference count. It's unlikely to be an issue + * but if it ever becomes one, we can turn the dynamic library handles into + * per-event loop properties and have the dynamic linker keep track for us. + */ + err = UV_ENOSYS; + core_foundation_handle = dlopen("/System/Library/Frameworks/" + "CoreFoundation.framework/" + "Versions/A/CoreFoundation", + RTLD_LAZY | RTLD_LOCAL); + if (core_foundation_handle == NULL) + goto out; + + core_services_handle = dlopen("/System/Library/Frameworks/" + "CoreServices.framework/" + "Versions/A/CoreServices", + RTLD_LAZY | RTLD_LOCAL); + if (core_services_handle == NULL) + goto out; + + err = UV_ENOENT; +#define V(handle, symbol) \ + do { \ + *(void **)(&p ## symbol) = dlsym((handle), #symbol); \ + if (p ## symbol == NULL) \ + goto out; \ + } \ + while (0) + V(core_foundation_handle, CFArrayCreate); + V(core_foundation_handle, CFRelease); + V(core_foundation_handle, CFRunLoopAddSource); + V(core_foundation_handle, CFRunLoopGetCurrent); + V(core_foundation_handle, CFRunLoopRemoveSource); + V(core_foundation_handle, CFRunLoopRun); + V(core_foundation_handle, CFRunLoopSourceCreate); + V(core_foundation_handle, CFRunLoopSourceSignal); + V(core_foundation_handle, CFRunLoopStop); + V(core_foundation_handle, CFRunLoopWakeUp); + V(core_foundation_handle, CFStringCreateWithFileSystemRepresentation); + V(core_foundation_handle, CFStringGetSystemEncoding); + V(core_foundation_handle, kCFRunLoopDefaultMode); + V(core_services_handle, FSEventStreamCreate); + V(core_services_handle, FSEventStreamFlushSync); + V(core_services_handle, FSEventStreamInvalidate); + V(core_services_handle, FSEventStreamRelease); + V(core_services_handle, FSEventStreamScheduleWithRunLoop); + V(core_services_handle, FSEventStreamStart); + V(core_services_handle, FSEventStreamStop); +#undef V + err = 0; + +out: + if (err && core_services_handle != NULL) { + dlclose(core_services_handle); + core_services_handle = NULL; + } + + if (err && core_foundation_handle != NULL) { + dlclose(core_foundation_handle); + core_foundation_handle = NULL; + } + + pthread_mutex_unlock(&global_init_mutex); + return err; +} + + +/* Runs in UV loop */ +static int uv__fsevents_loop_init(uv_loop_t* loop) { + CFRunLoopSourceContext ctx; + uv__cf_loop_state_t* state; + pthread_attr_t attr; + int err; + + if (loop->cf_state != NULL) + return 0; + + err = uv__fsevents_global_init(); + if (err) + return err; + + state = uv__calloc(1, sizeof(*state)); + if (state == NULL) + return UV_ENOMEM; + + err = uv_mutex_init(&loop->cf_mutex); + if (err) + goto fail_mutex_init; + + err = uv_sem_init(&loop->cf_sem, 0); + if (err) + goto fail_sem_init; + + QUEUE_INIT(&loop->cf_signals); + + err = uv_sem_init(&state->fsevent_sem, 0); + if (err) + goto fail_fsevent_sem_init; + + err = uv_mutex_init(&state->fsevent_mutex); + if (err) + goto fail_fsevent_mutex_init; + + QUEUE_INIT(&state->fsevent_handles); + state->fsevent_need_reschedule = 0; + state->fsevent_handle_count = 0; + + memset(&ctx, 0, sizeof(ctx)); + ctx.info = loop; + ctx.perform = uv__cf_loop_cb; + state->signal_source = pCFRunLoopSourceCreate(NULL, 0, &ctx); + if (state->signal_source == NULL) { + err = UV_ENOMEM; + goto fail_signal_source_create; + } + + if (pthread_attr_init(&attr)) + abort(); + + if (pthread_attr_setstacksize(&attr, uv__thread_stack_size())) + abort(); + + loop->cf_state = state; + + /* uv_thread_t is an alias for pthread_t. */ + err = UV__ERR(pthread_create(&loop->cf_thread, &attr, uv__cf_loop_runner, loop)); + + if (pthread_attr_destroy(&attr)) + abort(); + + if (err) + goto fail_thread_create; + + /* Synchronize threads */ + uv_sem_wait(&loop->cf_sem); + return 0; + +fail_thread_create: + loop->cf_state = NULL; + +fail_signal_source_create: + uv_mutex_destroy(&state->fsevent_mutex); + +fail_fsevent_mutex_init: + uv_sem_destroy(&state->fsevent_sem); + +fail_fsevent_sem_init: + uv_sem_destroy(&loop->cf_sem); + +fail_sem_init: + uv_mutex_destroy(&loop->cf_mutex); + +fail_mutex_init: + uv__free(state); + return err; +} + + +/* Runs in UV loop */ +void uv__fsevents_loop_delete(uv_loop_t* loop) { + uv__cf_loop_signal_t* s; + uv__cf_loop_state_t* state; + QUEUE* q; + + if (loop->cf_state == NULL) + return; + + if (uv__cf_loop_signal(loop, NULL, kUVCFLoopSignalRegular) != 0) + abort(); + + uv_thread_join(&loop->cf_thread); + uv_sem_destroy(&loop->cf_sem); + uv_mutex_destroy(&loop->cf_mutex); + + /* Free any remaining data */ + while (!QUEUE_EMPTY(&loop->cf_signals)) { + q = QUEUE_HEAD(&loop->cf_signals); + s = QUEUE_DATA(q, uv__cf_loop_signal_t, member); + QUEUE_REMOVE(q); + uv__free(s); + } + + /* Destroy state */ + state = loop->cf_state; + uv_sem_destroy(&state->fsevent_sem); + uv_mutex_destroy(&state->fsevent_mutex); + pCFRelease(state->signal_source); + uv__free(state); + loop->cf_state = NULL; +} + + +/* Runs in CF thread. This is the CF loop's body */ +static void* uv__cf_loop_runner(void* arg) { + uv_loop_t* loop; + uv__cf_loop_state_t* state; + + loop = arg; + state = loop->cf_state; + state->loop = pCFRunLoopGetCurrent(); + + pCFRunLoopAddSource(state->loop, + state->signal_source, + *pkCFRunLoopDefaultMode); + + uv_sem_post(&loop->cf_sem); + + pCFRunLoopRun(); + pCFRunLoopRemoveSource(state->loop, + state->signal_source, + *pkCFRunLoopDefaultMode); + + state->loop = NULL; + + return NULL; +} + + +/* Runs in CF thread, executed after `uv__cf_loop_signal()` */ +static void uv__cf_loop_cb(void* arg) { + uv_loop_t* loop; + uv__cf_loop_state_t* state; + QUEUE* item; + QUEUE split_head; + uv__cf_loop_signal_t* s; + + loop = arg; + state = loop->cf_state; + + uv_mutex_lock(&loop->cf_mutex); + QUEUE_MOVE(&loop->cf_signals, &split_head); + uv_mutex_unlock(&loop->cf_mutex); + + while (!QUEUE_EMPTY(&split_head)) { + item = QUEUE_HEAD(&split_head); + QUEUE_REMOVE(item); + + s = QUEUE_DATA(item, uv__cf_loop_signal_t, member); + + /* This was a termination signal */ + if (s->handle == NULL) + pCFRunLoopStop(state->loop); + else + uv__fsevents_reschedule(s->handle, s->type); + + uv__free(s); + } +} + + +/* Runs in UV loop to notify CF thread */ +int uv__cf_loop_signal(uv_loop_t* loop, + uv_fs_event_t* handle, + uv__cf_loop_signal_type_t type) { + uv__cf_loop_signal_t* item; + uv__cf_loop_state_t* state; + + item = uv__malloc(sizeof(*item)); + if (item == NULL) + return UV_ENOMEM; + + item->handle = handle; + item->type = type; + + uv_mutex_lock(&loop->cf_mutex); + QUEUE_INSERT_TAIL(&loop->cf_signals, &item->member); + + state = loop->cf_state; + assert(state != NULL); + pCFRunLoopSourceSignal(state->signal_source); + pCFRunLoopWakeUp(state->loop); + + uv_mutex_unlock(&loop->cf_mutex); + + return 0; +} + + +/* Runs in UV loop to initialize handle */ +int uv__fsevents_init(uv_fs_event_t* handle) { + int err; + uv__cf_loop_state_t* state; + + err = uv__fsevents_loop_init(handle->loop); + if (err) + return err; + + /* Get absolute path to file */ + handle->realpath = realpath(handle->path, NULL); + if (handle->realpath == NULL) + return UV__ERR(errno); + handle->realpath_len = strlen(handle->realpath); + + /* Initialize event queue */ + QUEUE_INIT(&handle->cf_events); + handle->cf_error = 0; + + /* + * Events will occur in other thread. + * Initialize callback for getting them back into event loop's thread + */ + handle->cf_cb = uv__malloc(sizeof(*handle->cf_cb)); + if (handle->cf_cb == NULL) { + err = UV_ENOMEM; + goto fail_cf_cb_malloc; + } + + handle->cf_cb->data = handle; + uv_async_init(handle->loop, handle->cf_cb, uv__fsevents_cb); + handle->cf_cb->flags |= UV_HANDLE_INTERNAL; + uv_unref((uv_handle_t*) handle->cf_cb); + + err = uv_mutex_init(&handle->cf_mutex); + if (err) + goto fail_cf_mutex_init; + + /* Insert handle into the list */ + state = handle->loop->cf_state; + uv_mutex_lock(&state->fsevent_mutex); + QUEUE_INSERT_TAIL(&state->fsevent_handles, &handle->cf_member); + state->fsevent_handle_count++; + state->fsevent_need_reschedule = 1; + uv_mutex_unlock(&state->fsevent_mutex); + + /* Reschedule FSEventStream */ + assert(handle != NULL); + err = uv__cf_loop_signal(handle->loop, handle, kUVCFLoopSignalRegular); + if (err) + goto fail_loop_signal; + + return 0; + +fail_loop_signal: + uv_mutex_destroy(&handle->cf_mutex); + +fail_cf_mutex_init: + uv__free(handle->cf_cb); + handle->cf_cb = NULL; + +fail_cf_cb_malloc: + uv__free(handle->realpath); + handle->realpath = NULL; + handle->realpath_len = 0; + + return err; +} + + +/* Runs in UV loop to de-initialize handle */ +int uv__fsevents_close(uv_fs_event_t* handle) { + int err; + uv__cf_loop_state_t* state; + + if (handle->cf_cb == NULL) + return UV_EINVAL; + + /* Remove handle from the list */ + state = handle->loop->cf_state; + uv_mutex_lock(&state->fsevent_mutex); + QUEUE_REMOVE(&handle->cf_member); + state->fsevent_handle_count--; + state->fsevent_need_reschedule = 1; + uv_mutex_unlock(&state->fsevent_mutex); + + /* Reschedule FSEventStream */ + assert(handle != NULL); + err = uv__cf_loop_signal(handle->loop, handle, kUVCFLoopSignalClosing); + if (err) + return UV__ERR(err); + + /* Wait for deinitialization */ + uv_sem_wait(&state->fsevent_sem); + + uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) uv__free); + handle->cf_cb = NULL; + + /* Free data in queue */ + UV__FSEVENTS_PROCESS(handle, { + /* NOP */ + }); + + uv_mutex_destroy(&handle->cf_mutex); + uv__free(handle->realpath); + handle->realpath = NULL; + handle->realpath_len = 0; + + return 0; +} + +#endif /* TARGET_OS_IPHONE */ diff --git a/external/src/libuv/src/unix/getaddrinfo.c b/external/src/libuv/src/unix/getaddrinfo.c new file mode 100644 index 0000000..77337ac --- /dev/null +++ b/external/src/libuv/src/unix/getaddrinfo.c @@ -0,0 +1,252 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* Expose glibc-specific EAI_* error codes. Needs to be defined before we + * include any headers. + */ + +#include "uv.h" +#include "internal.h" +#include "idna.h" + +#include +#include /* NULL */ +#include +#include +#include /* if_indextoname() */ + +/* EAI_* constants. */ +#include + + +int uv__getaddrinfo_translate_error(int sys_err) { + switch (sys_err) { + case 0: return 0; +#if defined(EAI_ADDRFAMILY) + case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY; +#endif +#if defined(EAI_AGAIN) + case EAI_AGAIN: return UV_EAI_AGAIN; +#endif +#if defined(EAI_BADFLAGS) + case EAI_BADFLAGS: return UV_EAI_BADFLAGS; +#endif +#if defined(EAI_BADHINTS) + case EAI_BADHINTS: return UV_EAI_BADHINTS; +#endif +#if defined(EAI_CANCELED) + case EAI_CANCELED: return UV_EAI_CANCELED; +#endif +#if defined(EAI_FAIL) + case EAI_FAIL: return UV_EAI_FAIL; +#endif +#if defined(EAI_FAMILY) + case EAI_FAMILY: return UV_EAI_FAMILY; +#endif +#if defined(EAI_MEMORY) + case EAI_MEMORY: return UV_EAI_MEMORY; +#endif +#if defined(EAI_NODATA) + case EAI_NODATA: return UV_EAI_NODATA; +#endif +#if defined(EAI_NONAME) +# if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME + case EAI_NONAME: return UV_EAI_NONAME; +# endif +#endif +#if defined(EAI_OVERFLOW) + case EAI_OVERFLOW: return UV_EAI_OVERFLOW; +#endif +#if defined(EAI_PROTOCOL) + case EAI_PROTOCOL: return UV_EAI_PROTOCOL; +#endif +#if defined(EAI_SERVICE) + case EAI_SERVICE: return UV_EAI_SERVICE; +#endif +#if defined(EAI_SOCKTYPE) + case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE; +#endif +#if defined(EAI_SYSTEM) + case EAI_SYSTEM: return UV__ERR(errno); +#endif + } + assert(!"unknown EAI_* error code"); + abort(); +#ifndef __SUNPRO_C + return 0; /* Pacify compiler. */ +#endif +} + + +static void uv__getaddrinfo_work(struct uv__work* w) { + uv_getaddrinfo_t* req; + int err; + + req = container_of(w, uv_getaddrinfo_t, work_req); + err = getaddrinfo(req->hostname, req->service, req->hints, &req->addrinfo); + req->retcode = uv__getaddrinfo_translate_error(err); +} + + +static void uv__getaddrinfo_done(struct uv__work* w, int status) { + uv_getaddrinfo_t* req; + + req = container_of(w, uv_getaddrinfo_t, work_req); + uv__req_unregister(req->loop, req); + + /* See initialization in uv_getaddrinfo(). */ + if (req->hints) + uv__free(req->hints); + else if (req->service) + uv__free(req->service); + else if (req->hostname) + uv__free(req->hostname); + else + assert(0); + + req->hints = NULL; + req->service = NULL; + req->hostname = NULL; + + if (status == UV_ECANCELED) { + assert(req->retcode == 0); + req->retcode = UV_EAI_CANCELED; + } + + if (req->cb) + req->cb(req, req->retcode, req->addrinfo); +} + + +int uv_getaddrinfo(uv_loop_t* loop, + uv_getaddrinfo_t* req, + uv_getaddrinfo_cb cb, + const char* hostname, + const char* service, + const struct addrinfo* hints) { + char hostname_ascii[256]; + size_t hostname_len; + size_t service_len; + size_t hints_len; + size_t len; + char* buf; + long rc; + + if (req == NULL || (hostname == NULL && service == NULL)) + return UV_EINVAL; + + /* FIXME(bnoordhuis) IDNA does not seem to work z/OS, + * probably because it uses EBCDIC rather than ASCII. + */ +#ifdef __MVS__ + (void) &hostname_ascii; +#else + if (hostname != NULL) { + rc = uv__idna_toascii(hostname, + hostname + strlen(hostname), + hostname_ascii, + hostname_ascii + sizeof(hostname_ascii)); + if (rc < 0) + return rc; + hostname = hostname_ascii; + } +#endif + + hostname_len = hostname ? strlen(hostname) + 1 : 0; + service_len = service ? strlen(service) + 1 : 0; + hints_len = hints ? sizeof(*hints) : 0; + buf = uv__malloc(hostname_len + service_len + hints_len); + + if (buf == NULL) + return UV_ENOMEM; + + uv__req_init(loop, req, UV_GETADDRINFO); + req->loop = loop; + req->cb = cb; + req->addrinfo = NULL; + req->hints = NULL; + req->service = NULL; + req->hostname = NULL; + req->retcode = 0; + + /* order matters, see uv_getaddrinfo_done() */ + len = 0; + + if (hints) { + req->hints = memcpy(buf + len, hints, sizeof(*hints)); + len += sizeof(*hints); + } + + if (service) { + req->service = memcpy(buf + len, service, service_len); + len += service_len; + } + + if (hostname) + req->hostname = memcpy(buf + len, hostname, hostname_len); + + if (cb) { + uv__work_submit(loop, + &req->work_req, + UV__WORK_SLOW_IO, + uv__getaddrinfo_work, + uv__getaddrinfo_done); + return 0; + } else { + uv__getaddrinfo_work(&req->work_req); + uv__getaddrinfo_done(&req->work_req, 0); + return req->retcode; + } +} + + +void uv_freeaddrinfo(struct addrinfo* ai) { + if (ai) + freeaddrinfo(ai); +} + + +int uv_if_indextoname(unsigned int ifindex, char* buffer, size_t* size) { + char ifname_buf[UV_IF_NAMESIZE]; + size_t len; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + if (if_indextoname(ifindex, ifname_buf) == NULL) + return UV__ERR(errno); + + len = strnlen(ifname_buf, sizeof(ifname_buf)); + + if (*size <= len) { + *size = len + 1; + return UV_ENOBUFS; + } + + memcpy(buffer, ifname_buf, len); + buffer[len] = '\0'; + *size = len; + + return 0; +} + +int uv_if_indextoiid(unsigned int ifindex, char* buffer, size_t* size) { + return uv_if_indextoname(ifindex, buffer, size); +} diff --git a/external/src/libuv/src/unix/getnameinfo.c b/external/src/libuv/src/unix/getnameinfo.c new file mode 100644 index 0000000..991002a --- /dev/null +++ b/external/src/libuv/src/unix/getnameinfo.c @@ -0,0 +1,121 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +*/ + +#include +#include +#include +#include + +#include "uv.h" +#include "internal.h" + + +static void uv__getnameinfo_work(struct uv__work* w) { + uv_getnameinfo_t* req; + int err; + socklen_t salen; + + req = container_of(w, uv_getnameinfo_t, work_req); + + if (req->storage.ss_family == AF_INET) + salen = sizeof(struct sockaddr_in); + else if (req->storage.ss_family == AF_INET6) + salen = sizeof(struct sockaddr_in6); + else + abort(); + + err = getnameinfo((struct sockaddr*) &req->storage, + salen, + req->host, + sizeof(req->host), + req->service, + sizeof(req->service), + req->flags); + req->retcode = uv__getaddrinfo_translate_error(err); +} + +static void uv__getnameinfo_done(struct uv__work* w, int status) { + uv_getnameinfo_t* req; + char* host; + char* service; + + req = container_of(w, uv_getnameinfo_t, work_req); + uv__req_unregister(req->loop, req); + host = service = NULL; + + if (status == UV_ECANCELED) { + assert(req->retcode == 0); + req->retcode = UV_EAI_CANCELED; + } else if (req->retcode == 0) { + host = req->host; + service = req->service; + } + + if (req->getnameinfo_cb) + req->getnameinfo_cb(req, req->retcode, host, service); +} + +/* +* Entry point for getnameinfo +* return 0 if a callback will be made +* return error code if validation fails +*/ +int uv_getnameinfo(uv_loop_t* loop, + uv_getnameinfo_t* req, + uv_getnameinfo_cb getnameinfo_cb, + const struct sockaddr* addr, + int flags) { + if (req == NULL || addr == NULL) + return UV_EINVAL; + + if (addr->sa_family == AF_INET) { + memcpy(&req->storage, + addr, + sizeof(struct sockaddr_in)); + } else if (addr->sa_family == AF_INET6) { + memcpy(&req->storage, + addr, + sizeof(struct sockaddr_in6)); + } else { + return UV_EINVAL; + } + + uv__req_init(loop, (uv_req_t*)req, UV_GETNAMEINFO); + + req->getnameinfo_cb = getnameinfo_cb; + req->flags = flags; + req->type = UV_GETNAMEINFO; + req->loop = loop; + req->retcode = 0; + + if (getnameinfo_cb) { + uv__work_submit(loop, + &req->work_req, + UV__WORK_SLOW_IO, + uv__getnameinfo_work, + uv__getnameinfo_done); + return 0; + } else { + uv__getnameinfo_work(&req->work_req); + uv__getnameinfo_done(&req->work_req, 0); + return req->retcode; + } +} diff --git a/external/src/libuv/src/unix/haiku.c b/external/src/libuv/src/unix/haiku.c new file mode 100644 index 0000000..cf17d83 --- /dev/null +++ b/external/src/libuv/src/unix/haiku.c @@ -0,0 +1,167 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include /* find_path() */ +#include + + +void uv_loadavg(double avg[3]) { + avg[0] = 0; + avg[1] = 0; + avg[2] = 0; +} + + +int uv_exepath(char* buffer, size_t* size) { + char abspath[B_PATH_NAME_LENGTH]; + status_t status; + ssize_t abspath_len; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + status = find_path(B_APP_IMAGE_SYMBOL, B_FIND_PATH_IMAGE_PATH, NULL, abspath, + sizeof(abspath)); + if (status != B_OK) + return UV__ERR(status); + + abspath_len = uv__strscpy(buffer, abspath, *size); + *size -= 1; + if (abspath_len >= 0 && *size > (size_t)abspath_len) + *size = (size_t)abspath_len; + + return 0; +} + + +uint64_t uv_get_free_memory(void) { + status_t status; + system_info sinfo; + + status = get_system_info(&sinfo); + if (status != B_OK) + return 0; + + return (sinfo.max_pages - sinfo.used_pages) * B_PAGE_SIZE; +} + + +uint64_t uv_get_total_memory(void) { + status_t status; + system_info sinfo; + + status = get_system_info(&sinfo); + if (status != B_OK) + return 0; + + return sinfo.max_pages * B_PAGE_SIZE; +} + + +uint64_t uv_get_constrained_memory(void) { + return 0; /* Memory constraints are unknown. */ +} + + +int uv_resident_set_memory(size_t* rss) { + area_info area; + ssize_t cookie; + status_t status; + thread_info thread; + + status = get_thread_info(find_thread(NULL), &thread); + if (status != B_OK) + return UV__ERR(status); + + cookie = 0; + *rss = 0; + while (get_next_area_info(thread.team, &cookie, &area) == B_OK) + *rss += area.ram_size; + + return 0; +} + + +int uv_uptime(double* uptime) { + /* system_time() returns time since booting in microseconds */ + *uptime = (double)system_time() / 1000000; + return 0; +} + + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + cpu_topology_node_info* topology_infos; + int i; + status_t status; + system_info system; + uint32_t topology_count; + uint64_t cpuspeed; + uv_cpu_info_t* cpu_info; + + if (cpu_infos == NULL || count == NULL) + return UV_EINVAL; + + status = get_cpu_topology_info(NULL, &topology_count); + if (status != B_OK) + return UV__ERR(status); + + topology_infos = uv__malloc(topology_count * sizeof(*topology_infos)); + if (topology_infos == NULL) + return UV_ENOMEM; + + status = get_cpu_topology_info(topology_infos, &topology_count); + if (status != B_OK) { + uv__free(topology_infos); + return UV__ERR(status); + } + + cpuspeed = 0; + for (i = 0; i < (int)topology_count; i++) { + if (topology_infos[i].type == B_TOPOLOGY_CORE) { + cpuspeed = topology_infos[i].data.core.default_frequency; + break; + } + } + + uv__free(topology_infos); + + status = get_system_info(&system); + if (status != B_OK) + return UV__ERR(status); + + *cpu_infos = uv__calloc(system.cpu_count, sizeof(**cpu_infos)); + if (*cpu_infos == NULL) + return UV_ENOMEM; + + /* CPU time and model are not exposed by Haiku. */ + cpu_info = *cpu_infos; + for (i = 0; i < (int)system.cpu_count; i++) { + cpu_info->model = uv__strdup("unknown"); + cpu_info->speed = (int)(cpuspeed / 1000000); + cpu_info++; + } + *count = system.cpu_count; + + return 0; +} diff --git a/external/src/libuv/src/unix/ibmi.c b/external/src/libuv/src/unix/ibmi.c new file mode 100644 index 0000000..8c6ae63 --- /dev/null +++ b/external/src/libuv/src/unix/ibmi.c @@ -0,0 +1,537 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include + +char* original_exepath = NULL; +uv_mutex_t process_title_mutex; +uv_once_t process_title_mutex_once = UV_ONCE_INIT; + +typedef struct { + int bytes_available; + int bytes_returned; + char current_date_and_time[8]; + char system_name[8]; + char elapsed_time[6]; + char restricted_state_flag; + char reserved; + int percent_processing_unit_used; + int jobs_in_system; + int percent_permanent_addresses; + int percent_temporary_addresses; + int system_asp; + int percent_system_asp_used; + int total_auxiliary_storage; + int current_unprotected_storage_used; + int maximum_unprotected_storage_used; + int percent_db_capability; + int main_storage_size; + int number_of_partitions; + int partition_identifier; + int reserved1; + int current_processing_capacity; + char processor_sharing_attribute; + char reserved2[3]; + int number_of_processors; + int active_jobs_in_system; + int active_threads_in_system; + int maximum_jobs_in_system; + int percent_temporary_256mb_segments_used; + int percent_temporary_4gb_segments_used; + int percent_permanent_256mb_segments_used; + int percent_permanent_4gb_segments_used; + int percent_current_interactive_performance; + int percent_uncapped_cpu_capacity_used; + int percent_shared_processor_pool_used; + long main_storage_size_long; +} SSTS0200; + + +typedef struct { + char header[208]; + unsigned char loca_adapter_address[12]; +} LIND0500; + + +typedef struct { + int bytes_provided; + int bytes_available; + char msgid[7]; +} errcode_s; + + +static const unsigned char e2a[256] = { + 0, 1, 2, 3, 156, 9, 134, 127, 151, 141, 142, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 157, 133, 8, 135, 24, 25, 146, 143, 28, 29, 30, 31, + 128, 129, 130, 131, 132, 10, 23, 27, 136, 137, 138, 139, 140, 5, 6, 7, + 144, 145, 22, 147, 148, 149, 150, 4, 152, 153, 154, 155, 20, 21, 158, 26, + 32, 160, 161, 162, 163, 164, 165, 166, 167, 168, 91, 46, 60, 40, 43, 33, + 38, 169, 170, 171, 172, 173, 174, 175, 176, 177, 93, 36, 42, 41, 59, 94, + 45, 47, 178, 179, 180, 181, 182, 183, 184, 185, 124, 44, 37, 95, 62, 63, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 96, 58, 35, 64, 39, 61, 34, + 195, 97, 98, 99, 100, 101, 102, 103, 104, 105, 196, 197, 198, 199, 200, 201, + 202, 106, 107, 108, 109, 110, 111, 112, 113, 114, 203, 204, 205, 206, 207, 208, + 209, 126, 115, 116, 117, 118, 119, 120, 121, 122, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, + 123, 65, 66, 67, 68, 69, 70, 71, 72, 73, 232, 233, 234, 235, 236, 237, + 125, 74, 75, 76, 77, 78, 79, 80, 81, 82, 238, 239, 240, 241, 242, 243, + 92, 159, 83, 84, 85, 86, 87, 88, 89, 90, 244, 245, 246, 247, 248, 249, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 250, 251, 252, 253, 254, 255}; + + +static const unsigned char a2e[256] = { + 0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31, + 64, 79, 127, 123, 91, 108, 80, 125, 77, 93, 92, 78, 107, 96, 75, 97, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 122, 94, 76, 126, 110, 111, + 124, 193, 194, 195, 196, 197, 198, 199, 200, 201, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 226, 227, 228, 229, 230, 231, 232, 233, 74, 224, 90, 95, 109, + 121, 129, 130, 131, 132, 133, 134, 135, 136, 137, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 162, 163, 164, 165, 166, 167, 168, 169, 192, 106, 208, 161, 7, + 32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27, + 48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62, 225, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 81, 82, 83, 84, 85, 86, 87, + 88, 89, 98, 99, 100, 101, 102, 103, 104, 105, 112, 113, 114, 115, 116, 117, + 118, 119, 120, 128, 138, 139, 140, 141, 142, 143, 144, 154, 155, 156, 157, 158, + 159, 160, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 202, 203, 204, 205, 206, 207, 218, 219, + 220, 221, 222, 223, 234, 235, 236, 237, 238, 239, 250, 251, 252, 253, 254, 255}; + + +static void iconv_e2a(unsigned char src[], unsigned char dst[], size_t length) { + size_t i; + for (i = 0; i < length; i++) + dst[i] = e2a[src[i]]; +} + + +static void iconv_a2e(const char* src, unsigned char dst[], size_t length) { + size_t srclen; + size_t i; + + srclen = strlen(src); + if (srclen > length) + srclen = length; + for (i = 0; i < srclen; i++) + dst[i] = a2e[src[i]]; + /* padding the remaining part with spaces */ + for (; i < length; i++) + dst[i] = a2e[' ']; +} + +void init_process_title_mutex_once(void) { + uv_mutex_init(&process_title_mutex); +} + +static int get_ibmi_system_status(SSTS0200* rcvr) { + /* rcvrlen is input parameter 2 to QWCRSSTS */ + unsigned int rcvrlen = sizeof(*rcvr); + unsigned char format[8], reset_status[10]; + + /* format is input parameter 3 to QWCRSSTS */ + iconv_a2e("SSTS0200", format, sizeof(format)); + /* reset_status is input parameter 4 */ + iconv_a2e("*NO", reset_status, sizeof(reset_status)); + + /* errcode is input parameter 5 to QWCRSSTS */ + errcode_s errcode; + + /* qwcrssts_pointer is the 16-byte tagged system pointer to QWCRSSTS */ + ILEpointer __attribute__((aligned(16))) qwcrssts_pointer; + + /* qwcrssts_argv is the array of argument pointers to QWCRSSTS */ + void* qwcrssts_argv[6]; + + /* Set the IBM i pointer to the QSYS/QWCRSSTS *PGM object */ + int rc = _RSLOBJ2(&qwcrssts_pointer, RSLOBJ_TS_PGM, "QWCRSSTS", "QSYS"); + + if (rc != 0) + return rc; + + /* initialize the QWCRSSTS returned info structure */ + memset(rcvr, 0, sizeof(*rcvr)); + + /* initialize the QWCRSSTS error code structure */ + memset(&errcode, 0, sizeof(errcode)); + errcode.bytes_provided = sizeof(errcode); + + /* initialize the array of argument pointers for the QWCRSSTS API */ + qwcrssts_argv[0] = rcvr; + qwcrssts_argv[1] = &rcvrlen; + qwcrssts_argv[2] = &format; + qwcrssts_argv[3] = &reset_status; + qwcrssts_argv[4] = &errcode; + qwcrssts_argv[5] = NULL; + + /* Call the IBM i QWCRSSTS API from PASE */ + rc = _PGMCALL(&qwcrssts_pointer, qwcrssts_argv, 0); + + return rc; +} + + +uint64_t uv_get_free_memory(void) { + SSTS0200 rcvr; + + if (get_ibmi_system_status(&rcvr)) + return 0; + + return (uint64_t)rcvr.main_storage_size * 1024ULL; +} + + +uint64_t uv_get_total_memory(void) { + SSTS0200 rcvr; + + if (get_ibmi_system_status(&rcvr)) + return 0; + + return (uint64_t)rcvr.main_storage_size * 1024ULL; +} + + +uint64_t uv_get_constrained_memory(void) { + return 0; /* Memory constraints are unknown. */ +} + + +void uv_loadavg(double avg[3]) { + SSTS0200 rcvr; + + if (get_ibmi_system_status(&rcvr)) { + avg[0] = avg[1] = avg[2] = 0; + return; + } + + /* The average (in tenths) of the elapsed time during which the processing + * units were in use. For example, a value of 411 in binary would be 41.1%. + * This percentage could be greater than 100% for an uncapped partition. + */ + double processing_unit_used_percent = + rcvr.percent_processing_unit_used / 1000.0; + + avg[0] = avg[1] = avg[2] = processing_unit_used_percent; +} + + +int uv_resident_set_memory(size_t* rss) { + *rss = 0; + return 0; +} + + +int uv_uptime(double* uptime) { + return UV_ENOSYS; +} + + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + unsigned int numcpus, idx = 0; + uv_cpu_info_t* cpu_info; + + *cpu_infos = NULL; + *count = 0; + + numcpus = sysconf(_SC_NPROCESSORS_ONLN); + + *cpu_infos = uv__malloc(numcpus * sizeof(uv_cpu_info_t)); + if (!*cpu_infos) { + return UV_ENOMEM; + } + + cpu_info = *cpu_infos; + for (idx = 0; idx < numcpus; idx++) { + cpu_info->speed = 0; + cpu_info->model = uv__strdup("unknown"); + cpu_info->cpu_times.user = 0; + cpu_info->cpu_times.sys = 0; + cpu_info->cpu_times.idle = 0; + cpu_info->cpu_times.irq = 0; + cpu_info->cpu_times.nice = 0; + cpu_info++; + } + *count = numcpus; + + return 0; +} + + +static int get_ibmi_physical_address(const char* line, char (*phys_addr)[6]) { + LIND0500 rcvr; + /* rcvrlen is input parameter 2 to QDCRLIND */ + unsigned int rcvrlen = sizeof(rcvr); + unsigned char format[8], line_name[10]; + unsigned char mac_addr[sizeof(rcvr.loca_adapter_address)]; + int c[6]; + + /* format is input parameter 3 to QDCRLIND */ + iconv_a2e("LIND0500", format, sizeof(format)); + + /* line_name is input parameter 4 to QDCRLIND */ + iconv_a2e(line, line_name, sizeof(line_name)); + + /* err is input parameter 5 to QDCRLIND */ + errcode_s err; + + /* qwcrssts_pointer is the 16-byte tagged system pointer to QDCRLIND */ + ILEpointer __attribute__((aligned(16))) qdcrlind_pointer; + + /* qwcrssts_argv is the array of argument pointers to QDCRLIND */ + void* qdcrlind_argv[6]; + + /* Set the IBM i pointer to the QSYS/QDCRLIND *PGM object */ + int rc = _RSLOBJ2(&qdcrlind_pointer, RSLOBJ_TS_PGM, "QDCRLIND", "QSYS"); + + if (rc != 0) + return rc; + + /* initialize the QDCRLIND returned info structure */ + memset(&rcvr, 0, sizeof(rcvr)); + + /* initialize the QDCRLIND error code structure */ + memset(&err, 0, sizeof(err)); + err.bytes_provided = sizeof(err); + + /* initialize the array of argument pointers for the QDCRLIND API */ + qdcrlind_argv[0] = &rcvr; + qdcrlind_argv[1] = &rcvrlen; + qdcrlind_argv[2] = &format; + qdcrlind_argv[3] = &line_name; + qdcrlind_argv[4] = &err; + qdcrlind_argv[5] = NULL; + + /* Call the IBM i QDCRLIND API from PASE */ + rc = _PGMCALL(&qdcrlind_pointer, qdcrlind_argv, 0); + if (rc != 0) + return rc; + + if (err.bytes_available > 0) { + return -1; + } + + /* convert ebcdic loca_adapter_address to ascii first */ + iconv_e2a(rcvr.loca_adapter_address, mac_addr, + sizeof(rcvr.loca_adapter_address)); + + /* convert loca_adapter_address(char[12]) to phys_addr(char[6]) */ + int r = sscanf(mac_addr, "%02x%02x%02x%02x%02x%02x", + &c[0], &c[1], &c[2], &c[3], &c[4], &c[5]); + + if (r == ARRAY_SIZE(c)) { + (*phys_addr)[0] = c[0]; + (*phys_addr)[1] = c[1]; + (*phys_addr)[2] = c[2]; + (*phys_addr)[3] = c[3]; + (*phys_addr)[4] = c[4]; + (*phys_addr)[5] = c[5]; + } else { + memset(*phys_addr, 0, sizeof(*phys_addr)); + rc = -1; + } + return rc; +} + + +int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { + uv_interface_address_t* address; + struct ifaddrs_pase *ifap = NULL, *cur; + int inet6, r = 0; + + *count = 0; + *addresses = NULL; + + if (Qp2getifaddrs(&ifap)) + return UV_ENOSYS; + + /* The first loop to get the size of the array to be allocated */ + for (cur = ifap; cur; cur = cur->ifa_next) { + if (!(cur->ifa_addr->sa_family == AF_INET6 || + cur->ifa_addr->sa_family == AF_INET)) + continue; + + if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING)) + continue; + + (*count)++; + } + + if (*count == 0) { + Qp2freeifaddrs(ifap); + return 0; + } + + /* Alloc the return interface structs */ + *addresses = uv__calloc(*count, sizeof(**addresses)); + if (*addresses == NULL) { + Qp2freeifaddrs(ifap); + return UV_ENOMEM; + } + address = *addresses; + + /* The second loop to fill in the array */ + for (cur = ifap; cur; cur = cur->ifa_next) { + if (!(cur->ifa_addr->sa_family == AF_INET6 || + cur->ifa_addr->sa_family == AF_INET)) + continue; + + if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING)) + continue; + + address->name = uv__strdup(cur->ifa_name); + + inet6 = (cur->ifa_addr->sa_family == AF_INET6); + + if (inet6) { + address->address.address6 = *((struct sockaddr_in6*)cur->ifa_addr); + address->netmask.netmask6 = *((struct sockaddr_in6*)cur->ifa_netmask); + address->netmask.netmask6.sin6_family = AF_INET6; + } else { + address->address.address4 = *((struct sockaddr_in*)cur->ifa_addr); + address->netmask.netmask4 = *((struct sockaddr_in*)cur->ifa_netmask); + address->netmask.netmask4.sin_family = AF_INET; + } + address->is_internal = cur->ifa_flags & IFF_LOOPBACK ? 1 : 0; + if (!address->is_internal) { + int rc = -1; + size_t name_len = strlen(address->name); + /* To get the associated MAC address, we must convert the address to a + * line description. Normally, the name field contains the line + * description name, but for VLANs it has the VLAN appended with a + * period. Since object names can also contain periods and numbers, there + * is no way to know if a returned name is for a VLAN or not. eg. + * *LIND ETH1.1 and *LIND ETH1, VLAN 1 both have the same name: ETH1.1 + * + * Instead, we apply the same heuristic used by some of the XPF ioctls: + * - names > 10 *must* contain a VLAN + * - assume names <= 10 do not contain a VLAN and try directly + * - if >10 or QDCRLIND returned an error, try to strip off a VLAN + * and try again + * - if we still get an error or couldn't find a period, leave the MAC as + * 00:00:00:00:00:00 + */ + if (name_len <= 10) { + /* Assume name does not contain a VLAN ID */ + rc = get_ibmi_physical_address(address->name, &address->phys_addr); + } + + if (name_len > 10 || rc != 0) { + /* The interface name must contain a VLAN ID suffix. Attempt to strip + * it off so we can get the line description to pass to QDCRLIND. + */ + char* temp_name = uv__strdup(address->name); + char* dot = strrchr(temp_name, '.'); + if (dot != NULL) { + *dot = '\0'; + if (strlen(temp_name) <= 10) { + rc = get_ibmi_physical_address(temp_name, &address->phys_addr); + } + } + uv__free(temp_name); + } + } + + address++; + } + + Qp2freeifaddrs(ifap); + return r; +} + + +void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) { + int i; + + for (i = 0; i < count; ++i) { + uv__free(addresses[i].name); + } + + uv__free(addresses); +} + +char** uv_setup_args(int argc, char** argv) { + char exepath[UV__PATH_MAX]; + char* s; + size_t size; + + if (argc > 0) { + /* Use argv[0] to determine value for uv_exepath(). */ + size = sizeof(exepath); + if (uv__search_path(argv[0], exepath, &size) == 0) { + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + original_exepath = uv__strdup(exepath); + uv_mutex_unlock(&process_title_mutex); + } + } + + return argv; +} + +int uv_set_process_title(const char* title) { + return 0; +} + +int uv_get_process_title(char* buffer, size_t size) { + if (buffer == NULL || size == 0) + return UV_EINVAL; + + buffer[0] = '\0'; + return 0; +} + +void uv__process_title_cleanup(void) { +} diff --git a/external/src/libuv/src/unix/internal.h b/external/src/libuv/src/unix/internal.h new file mode 100644 index 0000000..12d4da9 --- /dev/null +++ b/external/src/libuv/src/unix/internal.h @@ -0,0 +1,360 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_UNIX_INTERNAL_H_ +#define UV_UNIX_INTERNAL_H_ + +#include "uv-common.h" + +#include +#include /* _POSIX_PATH_MAX, PATH_MAX */ +#include /* abort */ +#include /* strrchr */ +#include /* O_CLOEXEC and O_NONBLOCK, if supported. */ +#include +#include +#include + +#if defined(__STRICT_ANSI__) +# define inline __inline +#endif + +#if defined(__linux__) +# include "linux-syscalls.h" +#endif /* __linux__ */ + +#if defined(__MVS__) +# include "os390-syscalls.h" +#endif /* __MVS__ */ + +#if defined(__sun) +# include +# include +#endif /* __sun */ + +#if defined(_AIX) +# define reqevents events +# define rtnevents revents +# include +#else +# include +#endif /* _AIX */ + +#if defined(__APPLE__) && !TARGET_OS_IPHONE +# include +#endif + +/* + * Define common detection for active Thread Sanitizer + * - clang uses __has_feature(thread_sanitizer) + * - gcc-7+ uses __SANITIZE_THREAD__ + */ +#if defined(__has_feature) +# if __has_feature(thread_sanitizer) +# define __SANITIZE_THREAD__ 1 +# endif +#endif + +#if defined(PATH_MAX) +# define UV__PATH_MAX PATH_MAX +#else +# define UV__PATH_MAX 8192 +#endif + +#if defined(__ANDROID__) +int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset); +# ifdef pthread_sigmask +# undef pthread_sigmask +# endif +# define pthread_sigmask(how, set, oldset) uv__pthread_sigmask(how, set, oldset) +#endif + +#define ACCESS_ONCE(type, var) \ + (*(volatile type*) &(var)) + +#define ROUND_UP(a, b) \ + ((a) % (b) ? ((a) + (b)) - ((a) % (b)) : (a)) + +#define UNREACHABLE() \ + do { \ + assert(0 && "unreachable code"); \ + abort(); \ + } \ + while (0) + +#define SAVE_ERRNO(block) \ + do { \ + int _saved_errno = errno; \ + do { block; } while (0); \ + errno = _saved_errno; \ + } \ + while (0) + +/* The __clang__ and __INTEL_COMPILER checks are superfluous because they + * define __GNUC__. They are here to convey to you, dear reader, that these + * macros are enabled when compiling with clang or icc. + */ +#if defined(__clang__) || \ + defined(__GNUC__) || \ + defined(__INTEL_COMPILER) +# define UV_UNUSED(declaration) __attribute__((unused)) declaration +#else +# define UV_UNUSED(declaration) declaration +#endif + +/* Leans on the fact that, on Linux, POLLRDHUP == EPOLLRDHUP. */ +#ifdef POLLRDHUP +# define UV__POLLRDHUP POLLRDHUP +#else +# define UV__POLLRDHUP 0x2000 +#endif + +#ifdef POLLPRI +# define UV__POLLPRI POLLPRI +#else +# define UV__POLLPRI 0 +#endif + +#if !defined(O_CLOEXEC) && defined(__FreeBSD__) +/* + * It may be that we are just missing `__POSIX_VISIBLE >= 200809`. + * Try using fixed value const and give up, if it doesn't work + */ +# define O_CLOEXEC 0x00100000 +#endif + +typedef struct uv__stream_queued_fds_s uv__stream_queued_fds_t; + +/* loop flags */ +enum { + UV_LOOP_BLOCK_SIGPROF = 1 +}; + +/* flags of excluding ifaddr */ +enum { + UV__EXCLUDE_IFPHYS, + UV__EXCLUDE_IFADDR +}; + +typedef enum { + UV_CLOCK_PRECISE = 0, /* Use the highest resolution clock available. */ + UV_CLOCK_FAST = 1 /* Use the fastest clock with <= 1ms granularity. */ +} uv_clocktype_t; + +struct uv__stream_queued_fds_s { + unsigned int size; + unsigned int offset; + int fds[1]; +}; + + +#if defined(_AIX) || \ + defined(__APPLE__) || \ + defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || \ + defined(__linux__) || \ + defined(__OpenBSD__) || \ + defined(__NetBSD__) +#define uv__cloexec uv__cloexec_ioctl +#define uv__nonblock uv__nonblock_ioctl +#define UV__NONBLOCK_IS_IOCTL 1 +#else +#define uv__cloexec uv__cloexec_fcntl +#define uv__nonblock uv__nonblock_fcntl +#define UV__NONBLOCK_IS_IOCTL 0 +#endif + +/* On Linux, uv__nonblock_fcntl() and uv__nonblock_ioctl() do not commute + * when O_NDELAY is not equal to O_NONBLOCK. Case in point: linux/sparc32 + * and linux/sparc64, where O_NDELAY is O_NONBLOCK + another bit. + * + * Libuv uses uv__nonblock_fcntl() directly sometimes so ensure that it + * commutes with uv__nonblock(). + */ +#if defined(__linux__) && O_NDELAY != O_NONBLOCK +#undef uv__nonblock +#define uv__nonblock uv__nonblock_fcntl +#endif + +/* core */ +int uv__cloexec_ioctl(int fd, int set); +int uv__cloexec_fcntl(int fd, int set); +int uv__nonblock_ioctl(int fd, int set); +int uv__nonblock_fcntl(int fd, int set); +int uv__close(int fd); /* preserves errno */ +int uv__close_nocheckstdio(int fd); +int uv__close_nocancel(int fd); +int uv__socket(int domain, int type, int protocol); +ssize_t uv__recvmsg(int fd, struct msghdr *msg, int flags); +void uv__make_close_pending(uv_handle_t* handle); +int uv__getiovmax(void); + +void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd); +void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events); +void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events); +void uv__io_close(uv_loop_t* loop, uv__io_t* w); +void uv__io_feed(uv_loop_t* loop, uv__io_t* w); +int uv__io_active(const uv__io_t* w, unsigned int events); +int uv__io_check_fd(uv_loop_t* loop, int fd); +void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */ +int uv__io_fork(uv_loop_t* loop); +int uv__fd_exists(uv_loop_t* loop, int fd); + +/* async */ +void uv__async_stop(uv_loop_t* loop); +int uv__async_fork(uv_loop_t* loop); + + +/* loop */ +void uv__run_idle(uv_loop_t* loop); +void uv__run_check(uv_loop_t* loop); +void uv__run_prepare(uv_loop_t* loop); + +/* stream */ +void uv__stream_init(uv_loop_t* loop, uv_stream_t* stream, + uv_handle_type type); +int uv__stream_open(uv_stream_t*, int fd, int flags); +void uv__stream_destroy(uv_stream_t* stream); +#if defined(__APPLE__) +int uv__stream_try_select(uv_stream_t* stream, int* fd); +#endif /* defined(__APPLE__) */ +void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events); +int uv__accept(int sockfd); +int uv__dup2_cloexec(int oldfd, int newfd); +int uv__open_cloexec(const char* path, int flags); + +/* tcp */ +int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb); +int uv__tcp_nodelay(int fd, int on); +int uv__tcp_keepalive(int fd, int on, unsigned int delay); + +/* pipe */ +int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb); + +/* signal */ +void uv__signal_close(uv_signal_t* handle); +void uv__signal_global_once_init(void); +void uv__signal_loop_cleanup(uv_loop_t* loop); +int uv__signal_loop_fork(uv_loop_t* loop); + +/* platform specific */ +uint64_t uv__hrtime(uv_clocktype_t type); +int uv__kqueue_init(uv_loop_t* loop); +int uv__epoll_init(uv_loop_t* loop); +int uv__platform_loop_init(uv_loop_t* loop); +void uv__platform_loop_delete(uv_loop_t* loop); +void uv__platform_invalidate_fd(uv_loop_t* loop, int fd); + +/* various */ +void uv__async_close(uv_async_t* handle); +void uv__check_close(uv_check_t* handle); +void uv__fs_event_close(uv_fs_event_t* handle); +void uv__idle_close(uv_idle_t* handle); +void uv__pipe_close(uv_pipe_t* handle); +void uv__poll_close(uv_poll_t* handle); +void uv__prepare_close(uv_prepare_t* handle); +void uv__process_close(uv_process_t* handle); +void uv__stream_close(uv_stream_t* handle); +void uv__tcp_close(uv_tcp_t* handle); +size_t uv__thread_stack_size(void); +void uv__udp_close(uv_udp_t* handle); +void uv__udp_finish_close(uv_udp_t* handle); +uv_handle_type uv__handle_type(int fd); +FILE* uv__open_file(const char* path); +int uv__getpwuid_r(uv_passwd_t* pwd); +int uv__search_path(const char* prog, char* buf, size_t* buflen); + +/* random */ +int uv__random_devurandom(void* buf, size_t buflen); +int uv__random_getrandom(void* buf, size_t buflen); +int uv__random_getentropy(void* buf, size_t buflen); +int uv__random_readpath(const char* path, void* buf, size_t buflen); +int uv__random_sysctl(void* buf, size_t buflen); + +#if defined(__APPLE__) +int uv___stream_fd(const uv_stream_t* handle); +#define uv__stream_fd(handle) (uv___stream_fd((const uv_stream_t*) (handle))) +#else +#define uv__stream_fd(handle) ((handle)->io_watcher.fd) +#endif /* defined(__APPLE__) */ + +int uv__make_pipe(int fds[2], int flags); + +#if defined(__APPLE__) + +int uv__fsevents_init(uv_fs_event_t* handle); +int uv__fsevents_close(uv_fs_event_t* handle); +void uv__fsevents_loop_delete(uv_loop_t* loop); + +#endif /* defined(__APPLE__) */ + +UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) { + /* Use a fast time source if available. We only need millisecond precision. + */ + loop->time = uv__hrtime(UV_CLOCK_FAST) / 1000000; +} + +UV_UNUSED(static char* uv__basename_r(const char* path)) { + char* s; + + s = strrchr(path, '/'); + if (s == NULL) + return (char*) path; + + return s + 1; +} + +#if defined(__linux__) +int uv__inotify_fork(uv_loop_t* loop, void* old_watchers); +#endif + +typedef int (*uv__peersockfunc)(int, struct sockaddr*, socklen_t*); + +int uv__getsockpeername(const uv_handle_t* handle, + uv__peersockfunc func, + struct sockaddr* name, + int* namelen); + +#if defined(__linux__) || \ + defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || \ + defined(__DragonFly__) +#define HAVE_MMSG 1 +struct uv__mmsghdr { + struct msghdr msg_hdr; + unsigned int msg_len; +}; + +int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen); +int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen); +#else +#define HAVE_MMSG 0 +#endif + +#if defined(__sun) +#if !defined(_POSIX_VERSION) || _POSIX_VERSION < 200809L +size_t strnlen(const char* s, size_t maxlen); +#endif +#endif + + +#endif /* UV_UNIX_INTERNAL_H_ */ diff --git a/external/src/libuv/src/unix/kqueue.c b/external/src/libuv/src/unix/kqueue.c new file mode 100644 index 0000000..bf183d5 --- /dev/null +++ b/external/src/libuv/src/unix/kqueue.c @@ -0,0 +1,585 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* + * Required on + * - Until at least FreeBSD 11.0 + * - Older versions of Mac OS X + * + * http://www.boost.org/doc/libs/1_61_0/boost/asio/detail/kqueue_reactor.hpp + */ +#ifndef EV_OOBAND +#define EV_OOBAND EV_FLAG1 +#endif + +static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags); + + +int uv__kqueue_init(uv_loop_t* loop) { + loop->backend_fd = kqueue(); + if (loop->backend_fd == -1) + return UV__ERR(errno); + + uv__cloexec(loop->backend_fd, 1); + + return 0; +} + + +#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 +static int uv__has_forked_with_cfrunloop; +#endif + +int uv__io_fork(uv_loop_t* loop) { + int err; + loop->backend_fd = -1; + err = uv__kqueue_init(loop); + if (err) + return err; + +#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (loop->cf_state != NULL) { + /* We cannot start another CFRunloop and/or thread in the child + process; CF aborts if you try or if you try to touch the thread + at all to kill it. So the best we can do is ignore it from now + on. This means we can't watch directories in the same way + anymore (like other BSDs). It also means we cannot properly + clean up the allocated resources; calling + uv__fsevents_loop_delete from uv_loop_close will crash the + process. So we sidestep the issue by pretending like we never + started it in the first place. + */ + uv__store_relaxed(&uv__has_forked_with_cfrunloop, 1); + uv__free(loop->cf_state); + loop->cf_state = NULL; + } +#endif /* #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */ + return err; +} + + +int uv__io_check_fd(uv_loop_t* loop, int fd) { + struct kevent ev; + int rc; + + rc = 0; + EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, 0); + if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL)) + rc = UV__ERR(errno); + + EV_SET(&ev, fd, EVFILT_READ, EV_DELETE, 0, 0, 0); + if (rc == 0) + if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL)) + abort(); + + return rc; +} + + +void uv__io_poll(uv_loop_t* loop, int timeout) { + struct kevent events[1024]; + struct kevent* ev; + struct timespec spec; + unsigned int nevents; + unsigned int revents; + QUEUE* q; + uv__io_t* w; + sigset_t* pset; + sigset_t set; + uint64_t base; + uint64_t diff; + int have_signals; + int filter; + int fflags; + int count; + int nfds; + int fd; + int op; + int i; + int user_timeout; + int reset_timeout; + + if (loop->nfds == 0) { + assert(QUEUE_EMPTY(&loop->watcher_queue)); + return; + } + + nevents = 0; + + while (!QUEUE_EMPTY(&loop->watcher_queue)) { + q = QUEUE_HEAD(&loop->watcher_queue); + QUEUE_REMOVE(q); + QUEUE_INIT(q); + + w = QUEUE_DATA(q, uv__io_t, watcher_queue); + assert(w->pevents != 0); + assert(w->fd >= 0); + assert(w->fd < (int) loop->nwatchers); + + if ((w->events & POLLIN) == 0 && (w->pevents & POLLIN) != 0) { + filter = EVFILT_READ; + fflags = 0; + op = EV_ADD; + + if (w->cb == uv__fs_event) { + filter = EVFILT_VNODE; + fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME + | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE; + op = EV_ADD | EV_ONESHOT; /* Stop the event from firing repeatedly. */ + } + + EV_SET(events + nevents, w->fd, filter, op, fflags, 0, 0); + + if (++nevents == ARRAY_SIZE(events)) { + if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL)) + abort(); + nevents = 0; + } + } + + if ((w->events & POLLOUT) == 0 && (w->pevents & POLLOUT) != 0) { + EV_SET(events + nevents, w->fd, EVFILT_WRITE, EV_ADD, 0, 0, 0); + + if (++nevents == ARRAY_SIZE(events)) { + if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL)) + abort(); + nevents = 0; + } + } + + if ((w->events & UV__POLLPRI) == 0 && (w->pevents & UV__POLLPRI) != 0) { + EV_SET(events + nevents, w->fd, EV_OOBAND, EV_ADD, 0, 0, 0); + + if (++nevents == ARRAY_SIZE(events)) { + if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL)) + abort(); + nevents = 0; + } + } + + w->events = w->pevents; + } + + pset = NULL; + if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { + pset = &set; + sigemptyset(pset); + sigaddset(pset, SIGPROF); + } + + assert(timeout >= -1); + base = loop->time; + count = 48; /* Benchmarks suggest this gives the best throughput. */ + + if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) { + reset_timeout = 1; + user_timeout = timeout; + timeout = 0; + } else { + reset_timeout = 0; + } + + for (;; nevents = 0) { + /* Only need to set the provider_entry_time if timeout != 0. The function + * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME. + */ + if (timeout != 0) + uv__metrics_set_provider_entry_time(loop); + + if (timeout != -1) { + spec.tv_sec = timeout / 1000; + spec.tv_nsec = (timeout % 1000) * 1000000; + } + + if (pset != NULL) + pthread_sigmask(SIG_BLOCK, pset, NULL); + + nfds = kevent(loop->backend_fd, + events, + nevents, + events, + ARRAY_SIZE(events), + timeout == -1 ? NULL : &spec); + + if (pset != NULL) + pthread_sigmask(SIG_UNBLOCK, pset, NULL); + + /* Update loop->time unconditionally. It's tempting to skip the update when + * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the + * operating system didn't reschedule our process while in the syscall. + */ + SAVE_ERRNO(uv__update_time(loop)); + + if (nfds == 0) { + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + if (timeout == -1) + continue; + if (timeout > 0) + goto update_timeout; + } + + assert(timeout != -1); + return; + } + + if (nfds == -1) { + if (errno != EINTR) + abort(); + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (timeout == 0) + return; + + if (timeout == -1) + continue; + + /* Interrupted by a signal. Update timeout and poll again. */ + goto update_timeout; + } + + have_signals = 0; + nevents = 0; + + assert(loop->watchers != NULL); + loop->watchers[loop->nwatchers] = (void*) events; + loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds; + for (i = 0; i < nfds; i++) { + ev = events + i; + fd = ev->ident; + /* Skip invalidated events, see uv__platform_invalidate_fd */ + if (fd == -1) + continue; + w = loop->watchers[fd]; + + if (w == NULL) { + /* File descriptor that we've stopped watching, disarm it. + * TODO: batch up. */ + struct kevent events[1]; + + EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0); + if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) + if (errno != EBADF && errno != ENOENT) + abort(); + + continue; + } + + if (ev->filter == EVFILT_VNODE) { + assert(w->events == POLLIN); + assert(w->pevents == POLLIN); + uv__metrics_update_idle_time(loop); + w->cb(loop, w, ev->fflags); /* XXX always uv__fs_event() */ + nevents++; + continue; + } + + revents = 0; + + if (ev->filter == EVFILT_READ) { + if (w->pevents & POLLIN) { + revents |= POLLIN; + w->rcount = ev->data; + } else { + /* TODO batch up */ + struct kevent events[1]; + EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0); + if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) + if (errno != ENOENT) + abort(); + } + } + + if (ev->filter == EV_OOBAND) { + if (w->pevents & UV__POLLPRI) { + revents |= UV__POLLPRI; + w->rcount = ev->data; + } else { + /* TODO batch up */ + struct kevent events[1]; + EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0); + if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) + if (errno != ENOENT) + abort(); + } + } + + if (ev->filter == EVFILT_WRITE) { + if (w->pevents & POLLOUT) { + revents |= POLLOUT; + w->wcount = ev->data; + } else { + /* TODO batch up */ + struct kevent events[1]; + EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0); + if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) + if (errno != ENOENT) + abort(); + } + } + + if (ev->flags & EV_ERROR) + revents |= POLLERR; + + if ((ev->flags & EV_EOF) && (w->pevents & UV__POLLRDHUP)) + revents |= UV__POLLRDHUP; + + if (revents == 0) + continue; + + /* Run signal watchers last. This also affects child process watchers + * because those are implemented in terms of signal watchers. + */ + if (w == &loop->signal_io_watcher) { + have_signals = 1; + } else { + uv__metrics_update_idle_time(loop); + w->cb(loop, w, revents); + } + + nevents++; + } + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (have_signals != 0) { + uv__metrics_update_idle_time(loop); + loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN); + } + + loop->watchers[loop->nwatchers] = NULL; + loop->watchers[loop->nwatchers + 1] = NULL; + + if (have_signals != 0) + return; /* Event loop should cycle now so don't poll again. */ + + if (nevents != 0) { + if (nfds == ARRAY_SIZE(events) && --count != 0) { + /* Poll for more events but don't block this time. */ + timeout = 0; + continue; + } + return; + } + + if (timeout == 0) + return; + + if (timeout == -1) + continue; + +update_timeout: + assert(timeout > 0); + + diff = loop->time - base; + if (diff >= (uint64_t) timeout) + return; + + timeout -= diff; + } +} + + +void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { + struct kevent* events; + uintptr_t i; + uintptr_t nfds; + + assert(loop->watchers != NULL); + assert(fd >= 0); + + events = (struct kevent*) loop->watchers[loop->nwatchers]; + nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; + if (events == NULL) + return; + + /* Invalidate events with same file descriptor */ + for (i = 0; i < nfds; i++) + if ((int) events[i].ident == fd) + events[i].ident = -1; +} + + +static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) { + uv_fs_event_t* handle; + struct kevent ev; + int events; + const char* path; +#if defined(F_GETPATH) + /* MAXPATHLEN == PATH_MAX but the former is what XNU calls it internally. */ + char pathbuf[MAXPATHLEN]; +#endif + + handle = container_of(w, uv_fs_event_t, event_watcher); + + if (fflags & (NOTE_ATTRIB | NOTE_EXTEND)) + events = UV_CHANGE; + else + events = UV_RENAME; + + path = NULL; +#if defined(F_GETPATH) + /* Also works when the file has been unlinked from the file system. Passing + * in the path when the file has been deleted is arguably a little strange + * but it's consistent with what the inotify backend does. + */ + if (fcntl(handle->event_watcher.fd, F_GETPATH, pathbuf) == 0) + path = uv__basename_r(pathbuf); +#endif + handle->cb(handle, path, events, 0); + + if (handle->event_watcher.fd == -1) + return; + + /* Watcher operates in one-shot mode, re-arm it. */ + fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME + | NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE; + + EV_SET(&ev, w->fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, fflags, 0, 0); + + if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL)) + abort(); +} + + +int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { + uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); + return 0; +} + + +int uv_fs_event_start(uv_fs_event_t* handle, + uv_fs_event_cb cb, + const char* path, + unsigned int flags) { + int fd; +#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + struct stat statbuf; +#endif + + if (uv__is_active(handle)) + return UV_EINVAL; + + handle->cb = cb; + handle->path = uv__strdup(path); + if (handle->path == NULL) + return UV_ENOMEM; + + /* TODO open asynchronously - but how do we report back errors? */ + fd = open(handle->path, O_RDONLY); + if (fd == -1) { + uv__free(handle->path); + handle->path = NULL; + return UV__ERR(errno); + } + +#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + /* Nullify field to perform checks later */ + handle->cf_cb = NULL; + handle->realpath = NULL; + handle->realpath_len = 0; + handle->cf_flags = flags; + + if (fstat(fd, &statbuf)) + goto fallback; + /* FSEvents works only with directories */ + if (!(statbuf.st_mode & S_IFDIR)) + goto fallback; + + if (0 == uv__load_relaxed(&uv__has_forked_with_cfrunloop)) { + int r; + /* The fallback fd is no longer needed */ + uv__close_nocheckstdio(fd); + handle->event_watcher.fd = -1; + r = uv__fsevents_init(handle); + if (r == 0) { + uv__handle_start(handle); + } else { + uv__free(handle->path); + handle->path = NULL; + } + return r; + } +fallback: +#endif /* #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */ + + uv__handle_start(handle); + uv__io_init(&handle->event_watcher, uv__fs_event, fd); + uv__io_start(handle->loop, &handle->event_watcher, POLLIN); + + return 0; +} + + +int uv_fs_event_stop(uv_fs_event_t* handle) { + int r; + r = 0; + + if (!uv__is_active(handle)) + return 0; + + uv__handle_stop(handle); + +#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (0 == uv__load_relaxed(&uv__has_forked_with_cfrunloop)) + if (handle->cf_cb != NULL) + r = uv__fsevents_close(handle); +#endif + + if (handle->event_watcher.fd != -1) { + uv__io_close(handle->loop, &handle->event_watcher); + uv__close(handle->event_watcher.fd); + handle->event_watcher.fd = -1; + } + + uv__free(handle->path); + handle->path = NULL; + + return r; +} + + +void uv__fs_event_close(uv_fs_event_t* handle) { + uv_fs_event_stop(handle); +} diff --git a/external/src/libuv/src/unix/linux-core.c b/external/src/libuv/src/unix/linux-core.c new file mode 100644 index 0000000..2716e2b --- /dev/null +++ b/external/src/libuv/src/unix/linux-core.c @@ -0,0 +1,766 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* We lean on the fact that POLL{IN,OUT,ERR,HUP} correspond with their + * EPOLL* counterparts. We use the POLL* variants in this file because that + * is what libuv uses elsewhere. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define HAVE_IFADDRS_H 1 + +#ifdef __UCLIBC__ +# if __UCLIBC_MAJOR__ < 0 && __UCLIBC_MINOR__ < 9 && __UCLIBC_SUBLEVEL__ < 32 +# undef HAVE_IFADDRS_H +# endif +#endif + +#ifdef HAVE_IFADDRS_H +# if defined(__ANDROID__) +# include "uv/android-ifaddrs.h" +# else +# include +# endif +# include +# include +# include +#endif /* HAVE_IFADDRS_H */ + +/* Available from 2.6.32 onwards. */ +#ifndef CLOCK_MONOTONIC_COARSE +# define CLOCK_MONOTONIC_COARSE 6 +#endif + +/* This is rather annoying: CLOCK_BOOTTIME lives in but we can't + * include that file because it conflicts with . We'll just have to + * define it ourselves. + */ +#ifndef CLOCK_BOOTTIME +# define CLOCK_BOOTTIME 7 +#endif + +static int read_models(unsigned int numcpus, uv_cpu_info_t* ci); +static int read_times(FILE* statfile_fp, + unsigned int numcpus, + uv_cpu_info_t* ci); +static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci); +static uint64_t read_cpufreq(unsigned int cpunum); + +int uv__platform_loop_init(uv_loop_t* loop) { + + loop->inotify_fd = -1; + loop->inotify_watchers = NULL; + + return uv__epoll_init(loop); +} + + +int uv__io_fork(uv_loop_t* loop) { + int err; + void* old_watchers; + + old_watchers = loop->inotify_watchers; + + uv__close(loop->backend_fd); + loop->backend_fd = -1; + uv__platform_loop_delete(loop); + + err = uv__platform_loop_init(loop); + if (err) + return err; + + return uv__inotify_fork(loop, old_watchers); +} + + +void uv__platform_loop_delete(uv_loop_t* loop) { + if (loop->inotify_fd == -1) return; + uv__io_stop(loop, &loop->inotify_read_watcher, POLLIN); + uv__close(loop->inotify_fd); + loop->inotify_fd = -1; +} + + + +uint64_t uv__hrtime(uv_clocktype_t type) { + static clock_t fast_clock_id = -1; + struct timespec t; + clock_t clock_id; + + /* Prefer CLOCK_MONOTONIC_COARSE if available but only when it has + * millisecond granularity or better. CLOCK_MONOTONIC_COARSE is + * serviced entirely from the vDSO, whereas CLOCK_MONOTONIC may + * decide to make a costly system call. + */ + /* TODO(bnoordhuis) Use CLOCK_MONOTONIC_COARSE for UV_CLOCK_PRECISE + * when it has microsecond granularity or better (unlikely). + */ + clock_id = CLOCK_MONOTONIC; + if (type != UV_CLOCK_FAST) + goto done; + + clock_id = uv__load_relaxed(&fast_clock_id); + if (clock_id != -1) + goto done; + + clock_id = CLOCK_MONOTONIC; + if (0 == clock_getres(CLOCK_MONOTONIC_COARSE, &t)) + if (t.tv_nsec <= 1 * 1000 * 1000) + clock_id = CLOCK_MONOTONIC_COARSE; + + uv__store_relaxed(&fast_clock_id, clock_id); + +done: + + if (clock_gettime(clock_id, &t)) + return 0; /* Not really possible. */ + + return t.tv_sec * (uint64_t) 1e9 + t.tv_nsec; +} + + +int uv_resident_set_memory(size_t* rss) { + char buf[1024]; + const char* s; + ssize_t n; + long val; + int fd; + int i; + + do + fd = open("/proc/self/stat", O_RDONLY); + while (fd == -1 && errno == EINTR); + + if (fd == -1) + return UV__ERR(errno); + + do + n = read(fd, buf, sizeof(buf) - 1); + while (n == -1 && errno == EINTR); + + uv__close(fd); + if (n == -1) + return UV__ERR(errno); + buf[n] = '\0'; + + s = strchr(buf, ' '); + if (s == NULL) + goto err; + + s += 1; + if (*s != '(') + goto err; + + s = strchr(s, ')'); + if (s == NULL) + goto err; + + for (i = 1; i <= 22; i++) { + s = strchr(s + 1, ' '); + if (s == NULL) + goto err; + } + + errno = 0; + val = strtol(s, NULL, 10); + if (errno != 0) + goto err; + if (val < 0) + goto err; + + *rss = val * getpagesize(); + return 0; + +err: + return UV_EINVAL; +} + +static int uv__slurp(const char* filename, char* buf, size_t len) { + ssize_t n; + int fd; + + assert(len > 0); + + fd = uv__open_cloexec(filename, O_RDONLY); + if (fd < 0) + return fd; + + do + n = read(fd, buf, len - 1); + while (n == -1 && errno == EINTR); + + if (uv__close_nocheckstdio(fd)) + abort(); + + if (n < 0) + return UV__ERR(errno); + + buf[n] = '\0'; + + return 0; +} + +int uv_uptime(double* uptime) { + static volatile int no_clock_boottime; + char buf[128]; + struct timespec now; + int r; + + /* Try /proc/uptime first, then fallback to clock_gettime(). */ + + if (0 == uv__slurp("/proc/uptime", buf, sizeof(buf))) + if (1 == sscanf(buf, "%lf", uptime)) + return 0; + + /* Try CLOCK_BOOTTIME first, fall back to CLOCK_MONOTONIC if not available + * (pre-2.6.39 kernels). CLOCK_MONOTONIC doesn't increase when the system + * is suspended. + */ + if (no_clock_boottime) { + retry_clock_gettime: r = clock_gettime(CLOCK_MONOTONIC, &now); + } + else if ((r = clock_gettime(CLOCK_BOOTTIME, &now)) && errno == EINVAL) { + no_clock_boottime = 1; + goto retry_clock_gettime; + } + + if (r) + return UV__ERR(errno); + + *uptime = now.tv_sec; + return 0; +} + + +static int uv__cpu_num(FILE* statfile_fp, unsigned int* numcpus) { + unsigned int num; + char buf[1024]; + + if (!fgets(buf, sizeof(buf), statfile_fp)) + return UV_EIO; + + num = 0; + while (fgets(buf, sizeof(buf), statfile_fp)) { + if (strncmp(buf, "cpu", 3)) + break; + num++; + } + + if (num == 0) + return UV_EIO; + + *numcpus = num; + return 0; +} + + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + unsigned int numcpus; + uv_cpu_info_t* ci; + int err; + FILE* statfile_fp; + + *cpu_infos = NULL; + *count = 0; + + statfile_fp = uv__open_file("/proc/stat"); + if (statfile_fp == NULL) + return UV__ERR(errno); + + err = uv__cpu_num(statfile_fp, &numcpus); + if (err < 0) + goto out; + + err = UV_ENOMEM; + ci = uv__calloc(numcpus, sizeof(*ci)); + if (ci == NULL) + goto out; + + err = read_models(numcpus, ci); + if (err == 0) + err = read_times(statfile_fp, numcpus, ci); + + if (err) { + uv_free_cpu_info(ci, numcpus); + goto out; + } + + /* read_models() on x86 also reads the CPU speed from /proc/cpuinfo. + * We don't check for errors here. Worst case, the field is left zero. + */ + if (ci[0].speed == 0) + read_speeds(numcpus, ci); + + *cpu_infos = ci; + *count = numcpus; + err = 0; + +out: + + if (fclose(statfile_fp)) + if (errno != EINTR && errno != EINPROGRESS) + abort(); + + return err; +} + + +static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci) { + unsigned int num; + + for (num = 0; num < numcpus; num++) + ci[num].speed = read_cpufreq(num) / 1000; +} + + +/* Also reads the CPU frequency on ppc and x86. The other architectures only + * have a BogoMIPS field, which may not be very accurate. + * + * Note: Simply returns on error, uv_cpu_info() takes care of the cleanup. + */ +static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) { +#if defined(__PPC__) + static const char model_marker[] = "cpu\t\t: "; + static const char speed_marker[] = "clock\t\t: "; +#else + static const char model_marker[] = "model name\t: "; + static const char speed_marker[] = "cpu MHz\t\t: "; +#endif + const char* inferred_model; + unsigned int model_idx; + unsigned int speed_idx; + char buf[1024]; + char* model; + FILE* fp; + + /* Most are unused on non-ARM, non-MIPS and non-x86 architectures. */ + (void) &model_marker; + (void) &speed_marker; + (void) &speed_idx; + (void) &model; + (void) &buf; + (void) &fp; + + model_idx = 0; + speed_idx = 0; + +#if defined(__arm__) || \ + defined(__i386__) || \ + defined(__mips__) || \ + defined(__PPC__) || \ + defined(__x86_64__) + fp = uv__open_file("/proc/cpuinfo"); + if (fp == NULL) + return UV__ERR(errno); + + while (fgets(buf, sizeof(buf), fp)) { + if (model_idx < numcpus) { + if (strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0) { + model = buf + sizeof(model_marker) - 1; + model = uv__strndup(model, strlen(model) - 1); /* Strip newline. */ + if (model == NULL) { + fclose(fp); + return UV_ENOMEM; + } + ci[model_idx++].model = model; + continue; + } + } +#if defined(__arm__) || defined(__mips__) + if (model_idx < numcpus) { +#if defined(__arm__) + /* Fallback for pre-3.8 kernels. */ + static const char model_marker[] = "Processor\t: "; +#else /* defined(__mips__) */ + static const char model_marker[] = "cpu model\t\t: "; +#endif + if (strncmp(buf, model_marker, sizeof(model_marker) - 1) == 0) { + model = buf + sizeof(model_marker) - 1; + model = uv__strndup(model, strlen(model) - 1); /* Strip newline. */ + if (model == NULL) { + fclose(fp); + return UV_ENOMEM; + } + ci[model_idx++].model = model; + continue; + } + } +#else /* !__arm__ && !__mips__ */ + if (speed_idx < numcpus) { + if (strncmp(buf, speed_marker, sizeof(speed_marker) - 1) == 0) { + ci[speed_idx++].speed = atoi(buf + sizeof(speed_marker) - 1); + continue; + } + } +#endif /* __arm__ || __mips__ */ + } + + fclose(fp); +#endif /* __arm__ || __i386__ || __mips__ || __PPC__ || __x86_64__ */ + + /* Now we want to make sure that all the models contain *something* because + * it's not safe to leave them as null. Copy the last entry unless there + * isn't one, in that case we simply put "unknown" into everything. + */ + inferred_model = "unknown"; + if (model_idx > 0) + inferred_model = ci[model_idx - 1].model; + + while (model_idx < numcpus) { + model = uv__strndup(inferred_model, strlen(inferred_model)); + if (model == NULL) + return UV_ENOMEM; + ci[model_idx++].model = model; + } + + return 0; +} + + +static int read_times(FILE* statfile_fp, + unsigned int numcpus, + uv_cpu_info_t* ci) { + struct uv_cpu_times_s ts; + unsigned int ticks; + unsigned int multiplier; + uint64_t user; + uint64_t nice; + uint64_t sys; + uint64_t idle; + uint64_t dummy; + uint64_t irq; + uint64_t num; + uint64_t len; + char buf[1024]; + + ticks = (unsigned int)sysconf(_SC_CLK_TCK); + assert(ticks != (unsigned int) -1); + assert(ticks != 0); + multiplier = ((uint64_t)1000L / ticks); + + rewind(statfile_fp); + + if (!fgets(buf, sizeof(buf), statfile_fp)) + abort(); + + num = 0; + + while (fgets(buf, sizeof(buf), statfile_fp)) { + if (num >= numcpus) + break; + + if (strncmp(buf, "cpu", 3)) + break; + + /* skip "cpu " marker */ + { + unsigned int n; + int r = sscanf(buf, "cpu%u ", &n); + assert(r == 1); + (void) r; /* silence build warning */ + for (len = sizeof("cpu0"); n /= 10; len++); + } + + /* Line contains user, nice, system, idle, iowait, irq, softirq, steal, + * guest, guest_nice but we're only interested in the first four + irq. + * + * Don't use %*s to skip fields or %ll to read straight into the uint64_t + * fields, they're not allowed in C89 mode. + */ + if (6 != sscanf(buf + len, + "%" PRIu64 " %" PRIu64 " %" PRIu64 + "%" PRIu64 " %" PRIu64 " %" PRIu64, + &user, + &nice, + &sys, + &idle, + &dummy, + &irq)) + abort(); + + ts.user = user * multiplier; + ts.nice = nice * multiplier; + ts.sys = sys * multiplier; + ts.idle = idle * multiplier; + ts.irq = irq * multiplier; + ci[num++].cpu_times = ts; + } + assert(num == numcpus); + + return 0; +} + + +static uint64_t read_cpufreq(unsigned int cpunum) { + uint64_t val; + char buf[1024]; + FILE* fp; + + snprintf(buf, + sizeof(buf), + "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq", + cpunum); + + fp = uv__open_file(buf); + if (fp == NULL) + return 0; + + if (fscanf(fp, "%" PRIu64, &val) != 1) + val = 0; + + fclose(fp); + + return val; +} + + +static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) { + if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) + return 1; + if (ent->ifa_addr == NULL) + return 1; + /* + * On Linux getifaddrs returns information related to the raw underlying + * devices. We're not interested in this information yet. + */ + if (ent->ifa_addr->sa_family == PF_PACKET) + return exclude_type; + return !exclude_type; +} + +int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { +#ifndef HAVE_IFADDRS_H + *count = 0; + *addresses = NULL; + return UV_ENOSYS; +#else + struct ifaddrs *addrs, *ent; + uv_interface_address_t* address; + int i; + struct sockaddr_ll *sll; + + *count = 0; + *addresses = NULL; + + if (getifaddrs(&addrs)) + return UV__ERR(errno); + + /* Count the number of interfaces */ + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR)) + continue; + + (*count)++; + } + + if (*count == 0) { + freeifaddrs(addrs); + return 0; + } + + /* Make sure the memory is initiallized to zero using calloc() */ + *addresses = uv__calloc(*count, sizeof(**addresses)); + if (!(*addresses)) { + freeifaddrs(addrs); + return UV_ENOMEM; + } + + address = *addresses; + + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR)) + continue; + + address->name = uv__strdup(ent->ifa_name); + + if (ent->ifa_addr->sa_family == AF_INET6) { + address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); + } else { + address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); + } + + if (ent->ifa_netmask->sa_family == AF_INET6) { + address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); + } else { + address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); + } + + address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK); + + address++; + } + + /* Fill in physical addresses for each interface */ + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS)) + continue; + + address = *addresses; + + for (i = 0; i < (*count); i++) { + size_t namelen = strlen(ent->ifa_name); + /* Alias interface share the same physical address */ + if (strncmp(address->name, ent->ifa_name, namelen) == 0 && + (address->name[namelen] == 0 || address->name[namelen] == ':')) { + sll = (struct sockaddr_ll*)ent->ifa_addr; + memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr)); + } + address++; + } + } + + freeifaddrs(addrs); + + return 0; +#endif +} + + +void uv_free_interface_addresses(uv_interface_address_t* addresses, + int count) { + int i; + + for (i = 0; i < count; i++) { + uv__free(addresses[i].name); + } + + uv__free(addresses); +} + + +void uv__set_process_title(const char* title) { +#if defined(PR_SET_NAME) + prctl(PR_SET_NAME, title); /* Only copies first 16 characters. */ +#endif +} + + +static uint64_t uv__read_proc_meminfo(const char* what) { + uint64_t rc; + char* p; + char buf[4096]; /* Large enough to hold all of /proc/meminfo. */ + + if (uv__slurp("/proc/meminfo", buf, sizeof(buf))) + return 0; + + p = strstr(buf, what); + + if (p == NULL) + return 0; + + p += strlen(what); + + rc = 0; + sscanf(p, "%" PRIu64 " kB", &rc); + + return rc * 1024; +} + + +uint64_t uv_get_free_memory(void) { + struct sysinfo info; + uint64_t rc; + + rc = uv__read_proc_meminfo("MemFree:"); + + if (rc != 0) + return rc; + + if (0 == sysinfo(&info)) + return (uint64_t) info.freeram * info.mem_unit; + + return 0; +} + + +uint64_t uv_get_total_memory(void) { + struct sysinfo info; + uint64_t rc; + + rc = uv__read_proc_meminfo("MemTotal:"); + + if (rc != 0) + return rc; + + if (0 == sysinfo(&info)) + return (uint64_t) info.totalram * info.mem_unit; + + return 0; +} + + +static uint64_t uv__read_cgroups_uint64(const char* cgroup, const char* param) { + char filename[256]; + char buf[32]; /* Large enough to hold an encoded uint64_t. */ + uint64_t rc; + + rc = 0; + snprintf(filename, sizeof(filename), "/sys/fs/cgroup/%s/%s", cgroup, param); + if (0 == uv__slurp(filename, buf, sizeof(buf))) + sscanf(buf, "%" PRIu64, &rc); + + return rc; +} + + +uint64_t uv_get_constrained_memory(void) { + /* + * This might return 0 if there was a problem getting the memory limit from + * cgroups. This is OK because a return value of 0 signifies that the memory + * limit is unknown. + */ + return uv__read_cgroups_uint64("memory", "memory.limit_in_bytes"); +} + + +void uv_loadavg(double avg[3]) { + struct sysinfo info; + char buf[128]; /* Large enough to hold all of /proc/loadavg. */ + + if (0 == uv__slurp("/proc/loadavg", buf, sizeof(buf))) + if (3 == sscanf(buf, "%lf %lf %lf", &avg[0], &avg[1], &avg[2])) + return; + + if (sysinfo(&info) < 0) + return; + + avg[0] = (double) info.loads[0] / 65536.0; + avg[1] = (double) info.loads[1] / 65536.0; + avg[2] = (double) info.loads[2] / 65536.0; +} diff --git a/external/src/libuv/src/unix/linux-inotify.c b/external/src/libuv/src/unix/linux-inotify.c new file mode 100644 index 0000000..c1bd260 --- /dev/null +++ b/external/src/libuv/src/unix/linux-inotify.c @@ -0,0 +1,327 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "uv/tree.h" +#include "internal.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +struct watcher_list { + RB_ENTRY(watcher_list) entry; + QUEUE watchers; + int iterating; + char* path; + int wd; +}; + +struct watcher_root { + struct watcher_list* rbh_root; +}; +#define CAST(p) ((struct watcher_root*)(p)) + + +static int compare_watchers(const struct watcher_list* a, + const struct watcher_list* b) { + if (a->wd < b->wd) return -1; + if (a->wd > b->wd) return 1; + return 0; +} + + +RB_GENERATE_STATIC(watcher_root, watcher_list, entry, compare_watchers) + + +static void uv__inotify_read(uv_loop_t* loop, + uv__io_t* w, + unsigned int revents); + +static void maybe_free_watcher_list(struct watcher_list* w, + uv_loop_t* loop); + +static int init_inotify(uv_loop_t* loop) { + int fd; + + if (loop->inotify_fd != -1) + return 0; + + fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC); + if (fd < 0) + return UV__ERR(errno); + + loop->inotify_fd = fd; + uv__io_init(&loop->inotify_read_watcher, uv__inotify_read, loop->inotify_fd); + uv__io_start(loop, &loop->inotify_read_watcher, POLLIN); + + return 0; +} + + +int uv__inotify_fork(uv_loop_t* loop, void* old_watchers) { + /* Open the inotify_fd, and re-arm all the inotify watchers. */ + int err; + struct watcher_list* tmp_watcher_list_iter; + struct watcher_list* watcher_list; + struct watcher_list tmp_watcher_list; + QUEUE queue; + QUEUE* q; + uv_fs_event_t* handle; + char* tmp_path; + + if (old_watchers != NULL) { + /* We must restore the old watcher list to be able to close items + * out of it. + */ + loop->inotify_watchers = old_watchers; + + QUEUE_INIT(&tmp_watcher_list.watchers); + /* Note that the queue we use is shared with the start and stop() + * functions, making QUEUE_FOREACH unsafe to use. So we use the + * QUEUE_MOVE trick to safely iterate. Also don't free the watcher + * list until we're done iterating. c.f. uv__inotify_read. + */ + RB_FOREACH_SAFE(watcher_list, watcher_root, + CAST(&old_watchers), tmp_watcher_list_iter) { + watcher_list->iterating = 1; + QUEUE_MOVE(&watcher_list->watchers, &queue); + while (!QUEUE_EMPTY(&queue)) { + q = QUEUE_HEAD(&queue); + handle = QUEUE_DATA(q, uv_fs_event_t, watchers); + /* It's critical to keep a copy of path here, because it + * will be set to NULL by stop() and then deallocated by + * maybe_free_watcher_list + */ + tmp_path = uv__strdup(handle->path); + assert(tmp_path != NULL); + QUEUE_REMOVE(q); + QUEUE_INSERT_TAIL(&watcher_list->watchers, q); + uv_fs_event_stop(handle); + + QUEUE_INSERT_TAIL(&tmp_watcher_list.watchers, &handle->watchers); + handle->path = tmp_path; + } + watcher_list->iterating = 0; + maybe_free_watcher_list(watcher_list, loop); + } + + QUEUE_MOVE(&tmp_watcher_list.watchers, &queue); + while (!QUEUE_EMPTY(&queue)) { + q = QUEUE_HEAD(&queue); + QUEUE_REMOVE(q); + handle = QUEUE_DATA(q, uv_fs_event_t, watchers); + tmp_path = handle->path; + handle->path = NULL; + err = uv_fs_event_start(handle, handle->cb, tmp_path, 0); + uv__free(tmp_path); + if (err) + return err; + } + } + + return 0; +} + + +static struct watcher_list* find_watcher(uv_loop_t* loop, int wd) { + struct watcher_list w; + w.wd = wd; + return RB_FIND(watcher_root, CAST(&loop->inotify_watchers), &w); +} + +static void maybe_free_watcher_list(struct watcher_list* w, uv_loop_t* loop) { + /* if the watcher_list->watchers is being iterated over, we can't free it. */ + if ((!w->iterating) && QUEUE_EMPTY(&w->watchers)) { + /* No watchers left for this path. Clean up. */ + RB_REMOVE(watcher_root, CAST(&loop->inotify_watchers), w); + inotify_rm_watch(loop->inotify_fd, w->wd); + uv__free(w); + } +} + +static void uv__inotify_read(uv_loop_t* loop, + uv__io_t* dummy, + unsigned int events) { + const struct inotify_event* e; + struct watcher_list* w; + uv_fs_event_t* h; + QUEUE queue; + QUEUE* q; + const char* path; + ssize_t size; + const char *p; + /* needs to be large enough for sizeof(inotify_event) + strlen(path) */ + char buf[4096]; + + for (;;) { + do + size = read(loop->inotify_fd, buf, sizeof(buf)); + while (size == -1 && errno == EINTR); + + if (size == -1) { + assert(errno == EAGAIN || errno == EWOULDBLOCK); + break; + } + + assert(size > 0); /* pre-2.6.21 thing, size=0 == read buffer too small */ + + /* Now we have one or more inotify_event structs. */ + for (p = buf; p < buf + size; p += sizeof(*e) + e->len) { + e = (const struct inotify_event*) p; + + events = 0; + if (e->mask & (IN_ATTRIB|IN_MODIFY)) + events |= UV_CHANGE; + if (e->mask & ~(IN_ATTRIB|IN_MODIFY)) + events |= UV_RENAME; + + w = find_watcher(loop, e->wd); + if (w == NULL) + continue; /* Stale event, no watchers left. */ + + /* inotify does not return the filename when monitoring a single file + * for modifications. Repurpose the filename for API compatibility. + * I'm not convinced this is a good thing, maybe it should go. + */ + path = e->len ? (const char*) (e + 1) : uv__basename_r(w->path); + + /* We're about to iterate over the queue and call user's callbacks. + * What can go wrong? + * A callback could call uv_fs_event_stop() + * and the queue can change under our feet. + * So, we use QUEUE_MOVE() trick to safely iterate over the queue. + * And we don't free the watcher_list until we're done iterating. + * + * First, + * tell uv_fs_event_stop() (that could be called from a user's callback) + * not to free watcher_list. + */ + w->iterating = 1; + QUEUE_MOVE(&w->watchers, &queue); + while (!QUEUE_EMPTY(&queue)) { + q = QUEUE_HEAD(&queue); + h = QUEUE_DATA(q, uv_fs_event_t, watchers); + + QUEUE_REMOVE(q); + QUEUE_INSERT_TAIL(&w->watchers, q); + + h->cb(h, path, events, 0); + } + /* done iterating, time to (maybe) free empty watcher_list */ + w->iterating = 0; + maybe_free_watcher_list(w, loop); + } + } +} + + +int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { + uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); + return 0; +} + + +int uv_fs_event_start(uv_fs_event_t* handle, + uv_fs_event_cb cb, + const char* path, + unsigned int flags) { + struct watcher_list* w; + size_t len; + int events; + int err; + int wd; + + if (uv__is_active(handle)) + return UV_EINVAL; + + err = init_inotify(handle->loop); + if (err) + return err; + + events = IN_ATTRIB + | IN_CREATE + | IN_MODIFY + | IN_DELETE + | IN_DELETE_SELF + | IN_MOVE_SELF + | IN_MOVED_FROM + | IN_MOVED_TO; + + wd = inotify_add_watch(handle->loop->inotify_fd, path, events); + if (wd == -1) + return UV__ERR(errno); + + w = find_watcher(handle->loop, wd); + if (w) + goto no_insert; + + len = strlen(path) + 1; + w = uv__malloc(sizeof(*w) + len); + if (w == NULL) + return UV_ENOMEM; + + w->wd = wd; + w->path = memcpy(w + 1, path, len); + QUEUE_INIT(&w->watchers); + w->iterating = 0; + RB_INSERT(watcher_root, CAST(&handle->loop->inotify_watchers), w); + +no_insert: + uv__handle_start(handle); + QUEUE_INSERT_TAIL(&w->watchers, &handle->watchers); + handle->path = w->path; + handle->cb = cb; + handle->wd = wd; + + return 0; +} + + +int uv_fs_event_stop(uv_fs_event_t* handle) { + struct watcher_list* w; + + if (!uv__is_active(handle)) + return 0; + + w = find_watcher(handle->loop, handle->wd); + assert(w != NULL); + + handle->wd = -1; + handle->path = NULL; + uv__handle_stop(handle); + QUEUE_REMOVE(&handle->watchers); + + maybe_free_watcher_list(w, handle->loop); + + return 0; +} + + +void uv__fs_event_close(uv_fs_event_t* handle) { + uv_fs_event_stop(handle); +} diff --git a/external/src/libuv/src/unix/linux-syscalls.c b/external/src/libuv/src/unix/linux-syscalls.c new file mode 100644 index 0000000..5071cd5 --- /dev/null +++ b/external/src/libuv/src/unix/linux-syscalls.c @@ -0,0 +1,264 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "linux-syscalls.h" +#include +#include +#include +#include +#include + +#if defined(__arm__) +# if defined(__thumb__) || defined(__ARM_EABI__) +# define UV_SYSCALL_BASE 0 +# else +# define UV_SYSCALL_BASE 0x900000 +# endif +#endif /* __arm__ */ + +#ifndef __NR_recvmmsg +# if defined(__x86_64__) +# define __NR_recvmmsg 299 +# elif defined(__arm__) +# define __NR_recvmmsg (UV_SYSCALL_BASE + 365) +# endif +#endif /* __NR_recvmsg */ + +#ifndef __NR_sendmmsg +# if defined(__x86_64__) +# define __NR_sendmmsg 307 +# elif defined(__arm__) +# define __NR_sendmmsg (UV_SYSCALL_BASE + 374) +# endif +#endif /* __NR_sendmmsg */ + +#ifndef __NR_utimensat +# if defined(__x86_64__) +# define __NR_utimensat 280 +# elif defined(__i386__) +# define __NR_utimensat 320 +# elif defined(__arm__) +# define __NR_utimensat (UV_SYSCALL_BASE + 348) +# endif +#endif /* __NR_utimensat */ + +#ifndef __NR_preadv +# if defined(__x86_64__) +# define __NR_preadv 295 +# elif defined(__i386__) +# define __NR_preadv 333 +# elif defined(__arm__) +# define __NR_preadv (UV_SYSCALL_BASE + 361) +# endif +#endif /* __NR_preadv */ + +#ifndef __NR_pwritev +# if defined(__x86_64__) +# define __NR_pwritev 296 +# elif defined(__i386__) +# define __NR_pwritev 334 +# elif defined(__arm__) +# define __NR_pwritev (UV_SYSCALL_BASE + 362) +# endif +#endif /* __NR_pwritev */ + +#ifndef __NR_dup3 +# if defined(__x86_64__) +# define __NR_dup3 292 +# elif defined(__i386__) +# define __NR_dup3 330 +# elif defined(__arm__) +# define __NR_dup3 (UV_SYSCALL_BASE + 358) +# endif +#endif /* __NR_pwritev */ + +#ifndef __NR_copy_file_range +# if defined(__x86_64__) +# define __NR_copy_file_range 326 +# elif defined(__i386__) +# define __NR_copy_file_range 377 +# elif defined(__s390__) +# define __NR_copy_file_range 375 +# elif defined(__arm__) +# define __NR_copy_file_range (UV_SYSCALL_BASE + 391) +# elif defined(__aarch64__) +# define __NR_copy_file_range 285 +# elif defined(__powerpc__) +# define __NR_copy_file_range 379 +# elif defined(__arc__) +# define __NR_copy_file_range 285 +# endif +#endif /* __NR_copy_file_range */ + +#ifndef __NR_statx +# if defined(__x86_64__) +# define __NR_statx 332 +# elif defined(__i386__) +# define __NR_statx 383 +# elif defined(__aarch64__) +# define __NR_statx 397 +# elif defined(__arm__) +# define __NR_statx (UV_SYSCALL_BASE + 397) +# elif defined(__ppc__) +# define __NR_statx 383 +# elif defined(__s390__) +# define __NR_statx 379 +# endif +#endif /* __NR_statx */ + +#ifndef __NR_getrandom +# if defined(__x86_64__) +# define __NR_getrandom 318 +# elif defined(__i386__) +# define __NR_getrandom 355 +# elif defined(__aarch64__) +# define __NR_getrandom 384 +# elif defined(__arm__) +# define __NR_getrandom (UV_SYSCALL_BASE + 384) +# elif defined(__ppc__) +# define __NR_getrandom 359 +# elif defined(__s390__) +# define __NR_getrandom 349 +# endif +#endif /* __NR_getrandom */ + +struct uv__mmsghdr; + +int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) { +#if defined(__i386__) + unsigned long args[4]; + int rc; + + args[0] = (unsigned long) fd; + args[1] = (unsigned long) mmsg; + args[2] = (unsigned long) vlen; + args[3] = /* flags */ 0; + + /* socketcall() raises EINVAL when SYS_SENDMMSG is not supported. */ + rc = syscall(/* __NR_socketcall */ 102, 20 /* SYS_SENDMMSG */, args); + if (rc == -1) + if (errno == EINVAL) + errno = ENOSYS; + + return rc; +#elif defined(__NR_sendmmsg) + return syscall(__NR_sendmmsg, fd, mmsg, vlen, /* flags */ 0); +#else + return errno = ENOSYS, -1; +#endif +} + + +int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) { +#if defined(__i386__) + unsigned long args[5]; + int rc; + + args[0] = (unsigned long) fd; + args[1] = (unsigned long) mmsg; + args[2] = (unsigned long) vlen; + args[3] = /* flags */ 0; + args[4] = /* timeout */ 0; + + /* socketcall() raises EINVAL when SYS_RECVMMSG is not supported. */ + rc = syscall(/* __NR_socketcall */ 102, 19 /* SYS_RECVMMSG */, args); + if (rc == -1) + if (errno == EINVAL) + errno = ENOSYS; + + return rc; +#elif defined(__NR_recvmmsg) + return syscall(__NR_recvmmsg, fd, mmsg, vlen, /* flags */ 0, /* timeout */ 0); +#else + return errno = ENOSYS, -1; +#endif +} + + +ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset) { +#if !defined(__NR_preadv) || defined(__ANDROID_API__) && __ANDROID_API__ < 24 + return errno = ENOSYS, -1; +#else + return syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32)); +#endif +} + + +ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset) { +#if !defined(__NR_pwritev) || defined(__ANDROID_API__) && __ANDROID_API__ < 24 + return errno = ENOSYS, -1; +#else + return syscall(__NR_pwritev, fd, iov, iovcnt, (long)offset, (long)(offset >> 32)); +#endif +} + + +int uv__dup3(int oldfd, int newfd, int flags) { +#if !defined(__NR_dup3) || defined(__ANDROID_API__) && __ANDROID_API__ < 21 + return errno = ENOSYS, -1; +#else + return syscall(__NR_dup3, oldfd, newfd, flags); +#endif +} + + +ssize_t +uv__fs_copy_file_range(int fd_in, + off_t* off_in, + int fd_out, + off_t* off_out, + size_t len, + unsigned int flags) +{ +#ifdef __NR_copy_file_range + return syscall(__NR_copy_file_range, + fd_in, + off_in, + fd_out, + off_out, + len, + flags); +#else + return errno = ENOSYS, -1; +#endif +} + + +int uv__statx(int dirfd, + const char* path, + int flags, + unsigned int mask, + struct uv__statx* statxbuf) { +#if !defined(__NR_statx) || defined(__ANDROID_API__) && __ANDROID_API__ < 30 + return errno = ENOSYS, -1; +#else + return syscall(__NR_statx, dirfd, path, flags, mask, statxbuf); +#endif +} + + +ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags) { +#if !defined(__NR_getrandom) || defined(__ANDROID_API__) && __ANDROID_API__ < 28 + return errno = ENOSYS, -1; +#else + return syscall(__NR_getrandom, buf, buflen, flags); +#endif +} diff --git a/external/src/libuv/src/unix/linux-syscalls.h b/external/src/libuv/src/unix/linux-syscalls.h new file mode 100644 index 0000000..b4d9082 --- /dev/null +++ b/external/src/libuv/src/unix/linux-syscalls.h @@ -0,0 +1,78 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_LINUX_SYSCALL_H_ +#define UV_LINUX_SYSCALL_H_ + +#include +#include +#include +#include +#include + +struct uv__statx_timestamp { + int64_t tv_sec; + uint32_t tv_nsec; + int32_t unused0; +}; + +struct uv__statx { + uint32_t stx_mask; + uint32_t stx_blksize; + uint64_t stx_attributes; + uint32_t stx_nlink; + uint32_t stx_uid; + uint32_t stx_gid; + uint16_t stx_mode; + uint16_t unused0; + uint64_t stx_ino; + uint64_t stx_size; + uint64_t stx_blocks; + uint64_t stx_attributes_mask; + struct uv__statx_timestamp stx_atime; + struct uv__statx_timestamp stx_btime; + struct uv__statx_timestamp stx_ctime; + struct uv__statx_timestamp stx_mtime; + uint32_t stx_rdev_major; + uint32_t stx_rdev_minor; + uint32_t stx_dev_major; + uint32_t stx_dev_minor; + uint64_t unused1[14]; +}; + +ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset); +ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset); +int uv__dup3(int oldfd, int newfd, int flags); +ssize_t +uv__fs_copy_file_range(int fd_in, + off_t* off_in, + int fd_out, + off_t* off_out, + size_t len, + unsigned int flags); +int uv__statx(int dirfd, + const char* path, + int flags, + unsigned int mask, + struct uv__statx* statxbuf); +ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags); + +#endif /* UV_LINUX_SYSCALL_H_ */ diff --git a/external/src/libuv/src/unix/loop-watcher.c b/external/src/libuv/src/unix/loop-watcher.c new file mode 100644 index 0000000..b8c1c2a --- /dev/null +++ b/external/src/libuv/src/unix/loop-watcher.c @@ -0,0 +1,68 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#define UV_LOOP_WATCHER_DEFINE(name, type) \ + int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \ + uv__handle_init(loop, (uv_handle_t*)handle, UV_##type); \ + handle->name##_cb = NULL; \ + return 0; \ + } \ + \ + int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \ + if (uv__is_active(handle)) return 0; \ + if (cb == NULL) return UV_EINVAL; \ + QUEUE_INSERT_HEAD(&handle->loop->name##_handles, &handle->queue); \ + handle->name##_cb = cb; \ + uv__handle_start(handle); \ + return 0; \ + } \ + \ + int uv_##name##_stop(uv_##name##_t* handle) { \ + if (!uv__is_active(handle)) return 0; \ + QUEUE_REMOVE(&handle->queue); \ + uv__handle_stop(handle); \ + return 0; \ + } \ + \ + void uv__run_##name(uv_loop_t* loop) { \ + uv_##name##_t* h; \ + QUEUE queue; \ + QUEUE* q; \ + QUEUE_MOVE(&loop->name##_handles, &queue); \ + while (!QUEUE_EMPTY(&queue)) { \ + q = QUEUE_HEAD(&queue); \ + h = QUEUE_DATA(q, uv_##name##_t, queue); \ + QUEUE_REMOVE(q); \ + QUEUE_INSERT_TAIL(&loop->name##_handles, q); \ + h->name##_cb(h); \ + } \ + } \ + \ + void uv__##name##_close(uv_##name##_t* handle) { \ + uv_##name##_stop(handle); \ + } + +UV_LOOP_WATCHER_DEFINE(prepare, PREPARE) +UV_LOOP_WATCHER_DEFINE(check, CHECK) +UV_LOOP_WATCHER_DEFINE(idle, IDLE) diff --git a/external/src/libuv/src/unix/loop.c b/external/src/libuv/src/unix/loop.c new file mode 100644 index 0000000..a88e71c --- /dev/null +++ b/external/src/libuv/src/unix/loop.c @@ -0,0 +1,228 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "uv/tree.h" +#include "internal.h" +#include "heap-inl.h" +#include +#include +#include + +int uv_loop_init(uv_loop_t* loop) { + uv__loop_internal_fields_t* lfields; + void* saved_data; + int err; + + + saved_data = loop->data; + memset(loop, 0, sizeof(*loop)); + loop->data = saved_data; + + lfields = (uv__loop_internal_fields_t*) uv__calloc(1, sizeof(*lfields)); + if (lfields == NULL) + return UV_ENOMEM; + loop->internal_fields = lfields; + + err = uv_mutex_init(&lfields->loop_metrics.lock); + if (err) + goto fail_metrics_mutex_init; + + heap_init((struct heap*) &loop->timer_heap); + QUEUE_INIT(&loop->wq); + QUEUE_INIT(&loop->idle_handles); + QUEUE_INIT(&loop->async_handles); + QUEUE_INIT(&loop->check_handles); + QUEUE_INIT(&loop->prepare_handles); + QUEUE_INIT(&loop->handle_queue); + + loop->active_handles = 0; + loop->active_reqs.count = 0; + loop->nfds = 0; + loop->watchers = NULL; + loop->nwatchers = 0; + QUEUE_INIT(&loop->pending_queue); + QUEUE_INIT(&loop->watcher_queue); + + loop->closing_handles = NULL; + uv__update_time(loop); + loop->async_io_watcher.fd = -1; + loop->async_wfd = -1; + loop->signal_pipefd[0] = -1; + loop->signal_pipefd[1] = -1; + loop->backend_fd = -1; + loop->emfile_fd = -1; + + loop->timer_counter = 0; + loop->stop_flag = 0; + + err = uv__platform_loop_init(loop); + if (err) + goto fail_platform_init; + + uv__signal_global_once_init(); + err = uv_signal_init(loop, &loop->child_watcher); + if (err) + goto fail_signal_init; + + uv__handle_unref(&loop->child_watcher); + loop->child_watcher.flags |= UV_HANDLE_INTERNAL; + QUEUE_INIT(&loop->process_handles); + + err = uv_rwlock_init(&loop->cloexec_lock); + if (err) + goto fail_rwlock_init; + + err = uv_mutex_init(&loop->wq_mutex); + if (err) + goto fail_mutex_init; + + err = uv_async_init(loop, &loop->wq_async, uv__work_done); + if (err) + goto fail_async_init; + + uv__handle_unref(&loop->wq_async); + loop->wq_async.flags |= UV_HANDLE_INTERNAL; + + return 0; + +fail_async_init: + uv_mutex_destroy(&loop->wq_mutex); + +fail_mutex_init: + uv_rwlock_destroy(&loop->cloexec_lock); + +fail_rwlock_init: + uv__signal_loop_cleanup(loop); + +fail_signal_init: + uv__platform_loop_delete(loop); + +fail_platform_init: + uv_mutex_destroy(&lfields->loop_metrics.lock); + +fail_metrics_mutex_init: + uv__free(lfields); + loop->internal_fields = NULL; + + uv__free(loop->watchers); + loop->nwatchers = 0; + return err; +} + + +int uv_loop_fork(uv_loop_t* loop) { + int err; + unsigned int i; + uv__io_t* w; + + err = uv__io_fork(loop); + if (err) + return err; + + err = uv__async_fork(loop); + if (err) + return err; + + err = uv__signal_loop_fork(loop); + if (err) + return err; + + /* Rearm all the watchers that aren't re-queued by the above. */ + for (i = 0; i < loop->nwatchers; i++) { + w = loop->watchers[i]; + if (w == NULL) + continue; + + if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue)) { + w->events = 0; /* Force re-registration in uv__io_poll. */ + QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); + } + } + + return 0; +} + + +void uv__loop_close(uv_loop_t* loop) { + uv__loop_internal_fields_t* lfields; + + uv__signal_loop_cleanup(loop); + uv__platform_loop_delete(loop); + uv__async_stop(loop); + + if (loop->emfile_fd != -1) { + uv__close(loop->emfile_fd); + loop->emfile_fd = -1; + } + + if (loop->backend_fd != -1) { + uv__close(loop->backend_fd); + loop->backend_fd = -1; + } + + uv_mutex_lock(&loop->wq_mutex); + assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!"); + assert(!uv__has_active_reqs(loop)); + uv_mutex_unlock(&loop->wq_mutex); + uv_mutex_destroy(&loop->wq_mutex); + + /* + * Note that all thread pool stuff is finished at this point and + * it is safe to just destroy rw lock + */ + uv_rwlock_destroy(&loop->cloexec_lock); + +#if 0 + assert(QUEUE_EMPTY(&loop->pending_queue)); + assert(QUEUE_EMPTY(&loop->watcher_queue)); + assert(loop->nfds == 0); +#endif + + uv__free(loop->watchers); + loop->watchers = NULL; + loop->nwatchers = 0; + + lfields = uv__get_internal_fields(loop); + uv_mutex_destroy(&lfields->loop_metrics.lock); + uv__free(lfields); + loop->internal_fields = NULL; +} + + +int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) { + uv__loop_internal_fields_t* lfields; + + lfields = uv__get_internal_fields(loop); + if (option == UV_METRICS_IDLE_TIME) { + lfields->flags |= UV_METRICS_IDLE_TIME; + return 0; + } + + if (option != UV_LOOP_BLOCK_SIGNAL) + return UV_ENOSYS; + + if (va_arg(ap, int) != SIGPROF) + return UV_EINVAL; + + loop->flags |= UV_LOOP_BLOCK_SIGPROF; + return 0; +} diff --git a/external/src/libuv/src/unix/netbsd.c b/external/src/libuv/src/unix/netbsd.c new file mode 100644 index 0000000..c66333f --- /dev/null +++ b/external/src/libuv/src/unix/netbsd.c @@ -0,0 +1,259 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + + +int uv__platform_loop_init(uv_loop_t* loop) { + return uv__kqueue_init(loop); +} + + +void uv__platform_loop_delete(uv_loop_t* loop) { +} + + +void uv_loadavg(double avg[3]) { + struct loadavg info; + size_t size = sizeof(info); + int which[] = {CTL_VM, VM_LOADAVG}; + + if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0) == -1) return; + + avg[0] = (double) info.ldavg[0] / info.fscale; + avg[1] = (double) info.ldavg[1] / info.fscale; + avg[2] = (double) info.ldavg[2] / info.fscale; +} + + +int uv_exepath(char* buffer, size_t* size) { + /* Intermediate buffer, retrieving partial path name does not work + * As of NetBSD-8(beta), vnode->path translator does not handle files + * with longer names than 31 characters. + */ + char int_buf[PATH_MAX]; + size_t int_size; + int mib[4]; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC_ARGS; + mib[2] = -1; + mib[3] = KERN_PROC_PATHNAME; + int_size = ARRAY_SIZE(int_buf); + + if (sysctl(mib, 4, int_buf, &int_size, NULL, 0)) + return UV__ERR(errno); + + /* Copy string from the intermediate buffer to outer one with appropriate + * length. + */ + /* TODO(bnoordhuis) Check uv__strscpy() return value. */ + uv__strscpy(buffer, int_buf, *size); + + /* Set new size. */ + *size = strlen(buffer); + + return 0; +} + + +uint64_t uv_get_free_memory(void) { + struct uvmexp info; + size_t size = sizeof(info); + int which[] = {CTL_VM, VM_UVMEXP}; + + if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0)) + return UV__ERR(errno); + + return (uint64_t) info.free * sysconf(_SC_PAGESIZE); +} + + +uint64_t uv_get_total_memory(void) { +#if defined(HW_PHYSMEM64) + uint64_t info; + int which[] = {CTL_HW, HW_PHYSMEM64}; +#else + unsigned int info; + int which[] = {CTL_HW, HW_PHYSMEM}; +#endif + size_t size = sizeof(info); + + if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0)) + return UV__ERR(errno); + + return (uint64_t) info; +} + + +uint64_t uv_get_constrained_memory(void) { + return 0; /* Memory constraints are unknown. */ +} + + +int uv_resident_set_memory(size_t* rss) { + kvm_t *kd = NULL; + struct kinfo_proc2 *kinfo = NULL; + pid_t pid; + int nprocs; + int max_size = sizeof(struct kinfo_proc2); + int page_size; + + page_size = getpagesize(); + pid = getpid(); + + kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, "kvm_open"); + + if (kd == NULL) goto error; + + kinfo = kvm_getproc2(kd, KERN_PROC_PID, pid, max_size, &nprocs); + if (kinfo == NULL) goto error; + + *rss = kinfo->p_vm_rssize * page_size; + + kvm_close(kd); + + return 0; + +error: + if (kd) kvm_close(kd); + return UV_EPERM; +} + + +int uv_uptime(double* uptime) { + time_t now; + struct timeval info; + size_t size = sizeof(info); + static int which[] = {CTL_KERN, KERN_BOOTTIME}; + + if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0)) + return UV__ERR(errno); + + now = time(NULL); + + *uptime = (double)(now - info.tv_sec); + return 0; +} + + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK); + unsigned int multiplier = ((uint64_t)1000L / ticks); + unsigned int cur = 0; + uv_cpu_info_t* cpu_info; + u_int64_t* cp_times; + char model[512]; + u_int64_t cpuspeed; + int numcpus; + size_t size; + int i; + + size = sizeof(model); + if (sysctlbyname("machdep.cpu_brand", &model, &size, NULL, 0) && + sysctlbyname("hw.model", &model, &size, NULL, 0)) { + return UV__ERR(errno); + } + + size = sizeof(numcpus); + if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0)) + return UV__ERR(errno); + *count = numcpus; + + /* Only i386 and amd64 have machdep.tsc_freq */ + size = sizeof(cpuspeed); + if (sysctlbyname("machdep.tsc_freq", &cpuspeed, &size, NULL, 0)) + cpuspeed = 0; + + size = numcpus * CPUSTATES * sizeof(*cp_times); + cp_times = uv__malloc(size); + if (cp_times == NULL) + return UV_ENOMEM; + + if (sysctlbyname("kern.cp_time", cp_times, &size, NULL, 0)) + return UV__ERR(errno); + + *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); + if (!(*cpu_infos)) { + uv__free(cp_times); + uv__free(*cpu_infos); + return UV_ENOMEM; + } + + for (i = 0; i < numcpus; i++) { + cpu_info = &(*cpu_infos)[i]; + cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier; + cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier; + cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier; + cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier; + cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier; + cpu_info->model = uv__strdup(model); + cpu_info->speed = (int)(cpuspeed/(uint64_t) 1e6); + cur += CPUSTATES; + } + uv__free(cp_times); + return 0; +} + +int uv__random_sysctl(void* buf, size_t len) { + static int name[] = {CTL_KERN, KERN_ARND}; + size_t count, req; + unsigned char* p; + + p = buf; + while (len) { + req = len < 32 ? len : 32; + count = req; + + if (sysctl(name, ARRAY_SIZE(name), p, &count, NULL, 0) == -1) + return UV__ERR(errno); + + if (count != req) + return UV_EIO; /* Can't happen. */ + + p += count; + len -= count; + } + + return 0; +} diff --git a/external/src/libuv/src/unix/no-fsevents.c b/external/src/libuv/src/unix/no-fsevents.c new file mode 100644 index 0000000..158643a --- /dev/null +++ b/external/src/libuv/src/unix/no-fsevents.c @@ -0,0 +1,42 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include + +int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { + return UV_ENOSYS; +} + +int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, + const char* filename, unsigned int flags) { + return UV_ENOSYS; +} + +int uv_fs_event_stop(uv_fs_event_t* handle) { + return UV_ENOSYS; +} + +void uv__fs_event_close(uv_fs_event_t* handle) { + UNREACHABLE(); +} diff --git a/external/src/libuv/src/unix/no-proctitle.c b/external/src/libuv/src/unix/no-proctitle.c new file mode 100644 index 0000000..32aa0af --- /dev/null +++ b/external/src/libuv/src/unix/no-proctitle.c @@ -0,0 +1,45 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +char** uv_setup_args(int argc, char** argv) { + return argv; +} + +void uv__process_title_cleanup(void) { +} + +int uv_set_process_title(const char* title) { + return 0; +} + +int uv_get_process_title(char* buffer, size_t size) { + if (buffer == NULL || size == 0) + return UV_EINVAL; + + buffer[0] = '\0'; + return 0; +} diff --git a/external/src/libuv/src/unix/openbsd.c b/external/src/libuv/src/unix/openbsd.c new file mode 100644 index 0000000..f32a94d --- /dev/null +++ b/external/src/libuv/src/unix/openbsd.c @@ -0,0 +1,240 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + +int uv__platform_loop_init(uv_loop_t* loop) { + return uv__kqueue_init(loop); +} + + +void uv__platform_loop_delete(uv_loop_t* loop) { +} + + +void uv_loadavg(double avg[3]) { + struct loadavg info; + size_t size = sizeof(info); + int which[] = {CTL_VM, VM_LOADAVG}; + + if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0) < 0) return; + + avg[0] = (double) info.ldavg[0] / info.fscale; + avg[1] = (double) info.ldavg[1] / info.fscale; + avg[2] = (double) info.ldavg[2] / info.fscale; +} + + +int uv_exepath(char* buffer, size_t* size) { + int mib[4]; + char **argsbuf = NULL; + size_t argsbuf_size = 100U; + size_t exepath_size; + pid_t mypid; + int err; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + mypid = getpid(); + for (;;) { + err = UV_ENOMEM; + argsbuf = uv__reallocf(argsbuf, argsbuf_size); + if (argsbuf == NULL) + goto out; + mib[0] = CTL_KERN; + mib[1] = KERN_PROC_ARGS; + mib[2] = mypid; + mib[3] = KERN_PROC_ARGV; + if (sysctl(mib, ARRAY_SIZE(mib), argsbuf, &argsbuf_size, NULL, 0) == 0) { + break; + } + if (errno != ENOMEM) { + err = UV__ERR(errno); + goto out; + } + argsbuf_size *= 2U; + } + + if (argsbuf[0] == NULL) { + err = UV_EINVAL; /* FIXME(bnoordhuis) More appropriate error. */ + goto out; + } + + *size -= 1; + exepath_size = strlen(argsbuf[0]); + if (*size > exepath_size) + *size = exepath_size; + + memcpy(buffer, argsbuf[0], *size); + buffer[*size] = '\0'; + err = 0; + +out: + uv__free(argsbuf); + + return err; +} + + +uint64_t uv_get_free_memory(void) { + struct uvmexp info; + size_t size = sizeof(info); + int which[] = {CTL_VM, VM_UVMEXP}; + + if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0)) + return UV__ERR(errno); + + return (uint64_t) info.free * sysconf(_SC_PAGESIZE); +} + + +uint64_t uv_get_total_memory(void) { + uint64_t info; + int which[] = {CTL_HW, HW_PHYSMEM64}; + size_t size = sizeof(info); + + if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0)) + return UV__ERR(errno); + + return (uint64_t) info; +} + + +uint64_t uv_get_constrained_memory(void) { + return 0; /* Memory constraints are unknown. */ +} + + +int uv_resident_set_memory(size_t* rss) { + struct kinfo_proc kinfo; + size_t page_size = getpagesize(); + size_t size = sizeof(struct kinfo_proc); + int mib[6]; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + mib[4] = sizeof(struct kinfo_proc); + mib[5] = 1; + + if (sysctl(mib, ARRAY_SIZE(mib), &kinfo, &size, NULL, 0) < 0) + return UV__ERR(errno); + + *rss = kinfo.p_vm_rssize * page_size; + return 0; +} + + +int uv_uptime(double* uptime) { + time_t now; + struct timeval info; + size_t size = sizeof(info); + static int which[] = {CTL_KERN, KERN_BOOTTIME}; + + if (sysctl(which, ARRAY_SIZE(which), &info, &size, NULL, 0)) + return UV__ERR(errno); + + now = time(NULL); + + *uptime = (double)(now - info.tv_sec); + return 0; +} + + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK), + multiplier = ((uint64_t)1000L / ticks), cpuspeed; + uint64_t info[CPUSTATES]; + char model[512]; + int numcpus = 1; + int which[] = {CTL_HW,HW_MODEL}; + int percpu[] = {CTL_KERN,KERN_CPTIME2,0}; + size_t size; + int i, j; + uv_cpu_info_t* cpu_info; + + size = sizeof(model); + if (sysctl(which, ARRAY_SIZE(which), &model, &size, NULL, 0)) + return UV__ERR(errno); + + which[1] = HW_NCPUONLINE; + size = sizeof(numcpus); + if (sysctl(which, ARRAY_SIZE(which), &numcpus, &size, NULL, 0)) + return UV__ERR(errno); + + *cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos)); + if (!(*cpu_infos)) + return UV_ENOMEM; + + i = 0; + *count = numcpus; + + which[1] = HW_CPUSPEED; + size = sizeof(cpuspeed); + if (sysctl(which, ARRAY_SIZE(which), &cpuspeed, &size, NULL, 0)) + goto error; + + size = sizeof(info); + for (i = 0; i < numcpus; i++) { + percpu[2] = i; + if (sysctl(percpu, ARRAY_SIZE(percpu), &info, &size, NULL, 0)) + goto error; + + cpu_info = &(*cpu_infos)[i]; + + cpu_info->cpu_times.user = (uint64_t)(info[CP_USER]) * multiplier; + cpu_info->cpu_times.nice = (uint64_t)(info[CP_NICE]) * multiplier; + cpu_info->cpu_times.sys = (uint64_t)(info[CP_SYS]) * multiplier; + cpu_info->cpu_times.idle = (uint64_t)(info[CP_IDLE]) * multiplier; + cpu_info->cpu_times.irq = (uint64_t)(info[CP_INTR]) * multiplier; + + cpu_info->model = uv__strdup(model); + cpu_info->speed = cpuspeed; + } + + return 0; + +error: + *count = 0; + for (j = 0; j < i; j++) + uv__free((*cpu_infos)[j].model); + + uv__free(*cpu_infos); + *cpu_infos = NULL; + return UV__ERR(errno); +} diff --git a/external/src/libuv/src/unix/os390-proctitle.c b/external/src/libuv/src/unix/os390-proctitle.c new file mode 100644 index 0000000..ccda97c --- /dev/null +++ b/external/src/libuv/src/unix/os390-proctitle.c @@ -0,0 +1,136 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +static uv_mutex_t process_title_mutex; +static uv_once_t process_title_mutex_once = UV_ONCE_INIT; +static char* process_title = NULL; +static void* args_mem = NULL; + + +static void init_process_title_mutex_once(void) { + uv_mutex_init(&process_title_mutex); +} + + +char** uv_setup_args(int argc, char** argv) { + char** new_argv; + size_t size; + char* s; + int i; + + if (argc <= 0) + return argv; + + /* Calculate how much memory we need for the argv strings. */ + size = 0; + for (i = 0; i < argc; i++) + size += strlen(argv[i]) + 1; + + /* Add space for the argv pointers. */ + size += (argc + 1) * sizeof(char*); + + new_argv = uv__malloc(size); + if (new_argv == NULL) + return argv; + + /* Copy over the strings and set up the pointer table. */ + s = (char*) &new_argv[argc + 1]; + for (i = 0; i < argc; i++) { + size = strlen(argv[i]) + 1; + memcpy(s, argv[i], size); + new_argv[i] = s; + s += size; + } + new_argv[i] = NULL; + + args_mem = new_argv; + process_title = uv__strdup(argv[0]); + + return new_argv; +} + + +int uv_set_process_title(const char* title) { + char* new_title; + + /* If uv_setup_args wasn't called or failed, we can't continue. */ + if (args_mem == NULL) + return UV_ENOBUFS; + + /* We cannot free this pointer when libuv shuts down, + * the process may still be using it. + */ + new_title = uv__strdup(title); + if (new_title == NULL) + return UV_ENOMEM; + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + if (process_title != NULL) + uv__free(process_title); + + process_title = new_title; + + uv_mutex_unlock(&process_title_mutex); + + return 0; +} + + +int uv_get_process_title(char* buffer, size_t size) { + size_t len; + + if (buffer == NULL || size == 0) + return UV_EINVAL; + + /* If uv_setup_args wasn't called or failed, we can't continue. */ + if (args_mem == NULL || process_title == NULL) + return UV_ENOBUFS; + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + len = strlen(process_title); + + if (size <= len) { + uv_mutex_unlock(&process_title_mutex); + return UV_ENOBUFS; + } + + strcpy(buffer, process_title); + + uv_mutex_unlock(&process_title_mutex); + + return 0; +} + + +void uv__process_title_cleanup(void) { + uv__free(args_mem); /* Keep valgrind happy. */ + args_mem = NULL; +} diff --git a/external/src/libuv/src/unix/os390-syscalls.c b/external/src/libuv/src/unix/os390-syscalls.c new file mode 100644 index 0000000..c191553 --- /dev/null +++ b/external/src/libuv/src/unix/os390-syscalls.c @@ -0,0 +1,529 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + + +#include "os390-syscalls.h" +#include +#include +#include +#include +#include + +static QUEUE global_epoll_queue; +static uv_mutex_t global_epoll_lock; +static uv_once_t once = UV_ONCE_INIT; + +int scandir(const char* maindir, struct dirent*** namelist, + int (*filter)(const struct dirent*), + int (*compar)(const struct dirent**, + const struct dirent **)) { + struct dirent** nl; + struct dirent** nl_copy; + struct dirent* dirent; + unsigned count; + size_t allocated; + DIR* mdir; + + nl = NULL; + count = 0; + allocated = 0; + mdir = opendir(maindir); + if (!mdir) + return -1; + + for (;;) { + dirent = readdir(mdir); + if (!dirent) + break; + if (!filter || filter(dirent)) { + struct dirent* copy; + copy = uv__malloc(sizeof(*copy)); + if (!copy) + goto error; + memcpy(copy, dirent, sizeof(*copy)); + + nl_copy = uv__realloc(nl, sizeof(*copy) * (count + 1)); + if (nl_copy == NULL) { + uv__free(copy); + goto error; + } + + nl = nl_copy; + nl[count++] = copy; + } + } + + qsort(nl, count, sizeof(struct dirent *), + (int (*)(const void *, const void *)) compar); + + closedir(mdir); + + *namelist = nl; + return count; + +error: + while (count > 0) { + dirent = nl[--count]; + uv__free(dirent); + } + uv__free(nl); + closedir(mdir); + errno = ENOMEM; + return -1; +} + + +static unsigned int next_power_of_two(unsigned int val) { + val -= 1; + val |= val >> 1; + val |= val >> 2; + val |= val >> 4; + val |= val >> 8; + val |= val >> 16; + val += 1; + return val; +} + + +static void maybe_resize(uv__os390_epoll* lst, unsigned int len) { + unsigned int newsize; + unsigned int i; + struct pollfd* newlst; + struct pollfd event; + + if (len <= lst->size) + return; + + if (lst->size == 0) + event.fd = -1; + else { + /* Extract the message queue at the end. */ + event = lst->items[lst->size - 1]; + lst->items[lst->size - 1].fd = -1; + } + + newsize = next_power_of_two(len); + newlst = uv__reallocf(lst->items, newsize * sizeof(lst->items[0])); + + if (newlst == NULL) + abort(); + for (i = lst->size; i < newsize; ++i) + newlst[i].fd = -1; + + /* Restore the message queue at the end */ + newlst[newsize - 1] = event; + + lst->items = newlst; + lst->size = newsize; +} + + +static void init_message_queue(uv__os390_epoll* lst) { + struct { + long int header; + char body; + } msg; + + /* initialize message queue */ + lst->msg_queue = msgget(IPC_PRIVATE, 0600 | IPC_CREAT); + if (lst->msg_queue == -1) + abort(); + + /* + On z/OS, the message queue will be affiliated with the process only + when a send is performed on it. Once this is done, the system + can be queried for all message queues belonging to our process id. + */ + msg.header = 1; + if (msgsnd(lst->msg_queue, &msg, sizeof(msg.body), 0) != 0) + abort(); + + /* Clean up the dummy message sent above */ + if (msgrcv(lst->msg_queue, &msg, sizeof(msg.body), 0, 0) != sizeof(msg.body)) + abort(); +} + + +static void before_fork(void) { + uv_mutex_lock(&global_epoll_lock); +} + + +static void after_fork(void) { + uv_mutex_unlock(&global_epoll_lock); +} + + +static void child_fork(void) { + QUEUE* q; + uv_once_t child_once = UV_ONCE_INIT; + + /* reset once */ + memcpy(&once, &child_once, sizeof(child_once)); + + /* reset epoll list */ + while (!QUEUE_EMPTY(&global_epoll_queue)) { + uv__os390_epoll* lst; + q = QUEUE_HEAD(&global_epoll_queue); + QUEUE_REMOVE(q); + lst = QUEUE_DATA(q, uv__os390_epoll, member); + uv__free(lst->items); + lst->items = NULL; + lst->size = 0; + } + + uv_mutex_unlock(&global_epoll_lock); + uv_mutex_destroy(&global_epoll_lock); +} + + +static void epoll_init(void) { + QUEUE_INIT(&global_epoll_queue); + if (uv_mutex_init(&global_epoll_lock)) + abort(); + + if (pthread_atfork(&before_fork, &after_fork, &child_fork)) + abort(); +} + + +uv__os390_epoll* epoll_create1(int flags) { + uv__os390_epoll* lst; + + lst = uv__malloc(sizeof(*lst)); + if (lst != NULL) { + /* initialize list */ + lst->size = 0; + lst->items = NULL; + init_message_queue(lst); + maybe_resize(lst, 1); + lst->items[lst->size - 1].fd = lst->msg_queue; + lst->items[lst->size - 1].events = POLLIN; + lst->items[lst->size - 1].revents = 0; + uv_once(&once, epoll_init); + uv_mutex_lock(&global_epoll_lock); + QUEUE_INSERT_TAIL(&global_epoll_queue, &lst->member); + uv_mutex_unlock(&global_epoll_lock); + } + + return lst; +} + + +int epoll_ctl(uv__os390_epoll* lst, + int op, + int fd, + struct epoll_event *event) { + uv_mutex_lock(&global_epoll_lock); + + if (op == EPOLL_CTL_DEL) { + if (fd >= lst->size || lst->items[fd].fd == -1) { + uv_mutex_unlock(&global_epoll_lock); + errno = ENOENT; + return -1; + } + lst->items[fd].fd = -1; + } else if (op == EPOLL_CTL_ADD) { + + /* Resizing to 'fd + 1' would expand the list to contain at least + * 'fd'. But we need to guarantee that the last index on the list + * is reserved for the message queue. So specify 'fd + 2' instead. + */ + maybe_resize(lst, fd + 2); + if (lst->items[fd].fd != -1) { + uv_mutex_unlock(&global_epoll_lock); + errno = EEXIST; + return -1; + } + lst->items[fd].fd = fd; + lst->items[fd].events = event->events; + lst->items[fd].revents = 0; + } else if (op == EPOLL_CTL_MOD) { + if (fd >= lst->size - 1 || lst->items[fd].fd == -1) { + uv_mutex_unlock(&global_epoll_lock); + errno = ENOENT; + return -1; + } + lst->items[fd].events = event->events; + lst->items[fd].revents = 0; + } else + abort(); + + uv_mutex_unlock(&global_epoll_lock); + return 0; +} + +#define EP_MAX_PFDS (ULONG_MAX / sizeof(struct pollfd)) +#define EP_MAX_EVENTS (INT_MAX / sizeof(struct epoll_event)) + +int epoll_wait(uv__os390_epoll* lst, struct epoll_event* events, + int maxevents, int timeout) { + nmsgsfds_t size; + struct pollfd* pfds; + int pollret; + int reventcount; + int nevents; + struct pollfd msg_fd; + int i; + + if (!lst || !lst->items || !events) { + errno = EFAULT; + return -1; + } + + if (lst->size > EP_MAX_PFDS) { + errno = EINVAL; + return -1; + } + + if (maxevents <= 0 || maxevents > EP_MAX_EVENTS) { + errno = EINVAL; + return -1; + } + + if (lst->size > 0) + _SET_FDS_MSGS(size, 1, lst->size - 1); + else + _SET_FDS_MSGS(size, 0, 0); + pfds = lst->items; + pollret = poll(pfds, size, timeout); + if (pollret <= 0) + return pollret; + + assert(lst->size > 0); + + pollret = _NFDS(pollret) + _NMSGS(pollret); + + reventcount = 0; + nevents = 0; + msg_fd = pfds[lst->size - 1]; + for (i = 0; + i < lst->size && i < maxevents && reventcount < pollret; ++i) { + struct epoll_event ev; + struct pollfd* pfd; + + pfd = &pfds[i]; + if (pfd->fd == -1 || pfd->revents == 0) + continue; + + ev.fd = pfd->fd; + ev.events = pfd->revents; + ev.is_msg = 0; + if (pfd->revents & POLLIN && pfd->revents & POLLOUT) + reventcount += 2; + else if (pfd->revents & (POLLIN | POLLOUT)) + ++reventcount; + + pfd->revents = 0; + events[nevents++] = ev; + } + + if (msg_fd.revents != 0 && msg_fd.fd != -1) + if (i == lst->size) + events[nevents - 1].is_msg = 1; + + return nevents; +} + + +int epoll_file_close(int fd) { + QUEUE* q; + + uv_once(&once, epoll_init); + uv_mutex_lock(&global_epoll_lock); + QUEUE_FOREACH(q, &global_epoll_queue) { + uv__os390_epoll* lst; + + lst = QUEUE_DATA(q, uv__os390_epoll, member); + if (fd < lst->size && lst->items != NULL && lst->items[fd].fd != -1) + lst->items[fd].fd = -1; + } + + uv_mutex_unlock(&global_epoll_lock); + return 0; +} + +void epoll_queue_close(uv__os390_epoll* lst) { + /* Remove epoll instance from global queue */ + uv_mutex_lock(&global_epoll_lock); + QUEUE_REMOVE(&lst->member); + uv_mutex_unlock(&global_epoll_lock); + + /* Free resources */ + msgctl(lst->msg_queue, IPC_RMID, NULL); + lst->msg_queue = -1; + uv__free(lst->items); + lst->items = NULL; +} + + +char* mkdtemp(char* path) { + static const char* tempchars = + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + static const size_t num_chars = 62; + static const size_t num_x = 6; + char *ep, *cp; + unsigned int tries, i; + size_t len; + uint64_t v; + int fd; + int retval; + int saved_errno; + + len = strlen(path); + ep = path + len; + if (len < num_x || strncmp(ep - num_x, "XXXXXX", num_x)) { + errno = EINVAL; + return NULL; + } + + fd = open("/dev/urandom", O_RDONLY); + if (fd == -1) + return NULL; + + tries = TMP_MAX; + retval = -1; + do { + if (read(fd, &v, sizeof(v)) != sizeof(v)) + break; + + cp = ep - num_x; + for (i = 0; i < num_x; i++) { + *cp++ = tempchars[v % num_chars]; + v /= num_chars; + } + + if (mkdir(path, S_IRWXU) == 0) { + retval = 0; + break; + } + else if (errno != EEXIST) + break; + } while (--tries); + + saved_errno = errno; + uv__close(fd); + if (tries == 0) { + errno = EEXIST; + return NULL; + } + + if (retval == -1) { + errno = saved_errno; + return NULL; + } + + return path; +} + + +ssize_t os390_readlink(const char* path, char* buf, size_t len) { + ssize_t rlen; + ssize_t vlen; + ssize_t plen; + char* delimiter; + char old_delim; + char* tmpbuf; + char realpathstr[PATH_MAX + 1]; + + tmpbuf = uv__malloc(len + 1); + if (tmpbuf == NULL) { + errno = ENOMEM; + return -1; + } + + rlen = readlink(path, tmpbuf, len); + if (rlen < 0) { + uv__free(tmpbuf); + return rlen; + } + + if (rlen < 3 || strncmp("/$", tmpbuf, 2) != 0) { + /* Straightforward readlink. */ + memcpy(buf, tmpbuf, rlen); + uv__free(tmpbuf); + return rlen; + } + + /* + * There is a parmlib variable at the beginning + * which needs interpretation. + */ + tmpbuf[rlen] = '\0'; + delimiter = strchr(tmpbuf + 2, '/'); + if (delimiter == NULL) + /* No slash at the end */ + delimiter = strchr(tmpbuf + 2, '\0'); + + /* Read real path of the variable. */ + old_delim = *delimiter; + *delimiter = '\0'; + if (realpath(tmpbuf, realpathstr) == NULL) { + uv__free(tmpbuf); + return -1; + } + + /* realpathstr is not guaranteed to end with null byte.*/ + realpathstr[PATH_MAX] = '\0'; + + /* Reset the delimiter and fill up the buffer. */ + *delimiter = old_delim; + plen = strlen(delimiter); + vlen = strlen(realpathstr); + rlen = plen + vlen; + if (rlen > len) { + uv__free(tmpbuf); + errno = ENAMETOOLONG; + return -1; + } + memcpy(buf, realpathstr, vlen); + memcpy(buf + vlen, delimiter, plen); + + /* Done using temporary buffer. */ + uv__free(tmpbuf); + + return rlen; +} + + +int sem_init(UV_PLATFORM_SEM_T* semid, int pshared, unsigned int value) { + UNREACHABLE(); +} + + +int sem_destroy(UV_PLATFORM_SEM_T* semid) { + UNREACHABLE(); +} + + +int sem_post(UV_PLATFORM_SEM_T* semid) { + UNREACHABLE(); +} + + +int sem_trywait(UV_PLATFORM_SEM_T* semid) { + UNREACHABLE(); +} + + +int sem_wait(UV_PLATFORM_SEM_T* semid) { + UNREACHABLE(); +} diff --git a/external/src/libuv/src/unix/os390-syscalls.h b/external/src/libuv/src/unix/os390-syscalls.h new file mode 100644 index 0000000..7d59b75 --- /dev/null +++ b/external/src/libuv/src/unix/os390-syscalls.h @@ -0,0 +1,74 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + + +#ifndef UV_OS390_SYSCALL_H_ +#define UV_OS390_SYSCALL_H_ + +#include "uv.h" +#include "internal.h" +#include +#include +#include +#include "zos-base.h" + +#define EPOLL_CTL_ADD 1 +#define EPOLL_CTL_DEL 2 +#define EPOLL_CTL_MOD 3 +#define MAX_EPOLL_INSTANCES 256 +#define MAX_ITEMS_PER_EPOLL 1024 + +#define UV__O_CLOEXEC 0x80000 + +struct epoll_event { + int events; + int fd; + int is_msg; +}; + +typedef struct { + QUEUE member; + struct pollfd* items; + unsigned long size; + int msg_queue; +} uv__os390_epoll; + +/* epoll api */ +uv__os390_epoll* epoll_create1(int flags); +int epoll_ctl(uv__os390_epoll* ep, int op, int fd, struct epoll_event *event); +int epoll_wait(uv__os390_epoll* ep, struct epoll_event *events, int maxevents, int timeout); +int epoll_file_close(int fd); + +/* utility functions */ +int scandir(const char* maindir, struct dirent*** namelist, + int (*filter)(const struct dirent *), + int (*compar)(const struct dirent **, + const struct dirent **)); +char *mkdtemp(char* path); +ssize_t os390_readlink(const char* path, char* buf, size_t len); +size_t strnlen(const char* str, size_t maxlen); +int sem_init(UV_PLATFORM_SEM_T* semid, int pshared, unsigned int value); +int sem_destroy(UV_PLATFORM_SEM_T* semid); +int sem_post(UV_PLATFORM_SEM_T* semid); +int sem_trywait(UV_PLATFORM_SEM_T* semid); +int sem_wait(UV_PLATFORM_SEM_T* semid); + +#endif /* UV_OS390_SYSCALL_H_ */ diff --git a/external/src/libuv/src/unix/os390.c b/external/src/libuv/src/unix/os390.c new file mode 100644 index 0000000..bf0448b --- /dev/null +++ b/external/src/libuv/src/unix/os390.c @@ -0,0 +1,877 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "internal.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "zos-base.h" +#if defined(__clang__) +#include "csrsic.h" +#else +#include "//'SYS1.SAMPLIB(CSRSIC)'" +#endif + +#define CVT_PTR 0x10 +#define PSA_PTR 0x00 +#define CSD_OFFSET 0x294 + +/* + Long-term average CPU service used by this logical partition, + in millions of service units per hour. If this value is above + the partition's defined capacity, the partition will be capped. + It is calculated using the physical CPU adjustment factor + (RCTPCPUA) so it may not match other measures of service which + are based on the logical CPU adjustment factor. It is available + if the hardware supports LPAR cluster. +*/ +#define RCTLACS_OFFSET 0xC4 + +/* 32-bit count of alive CPUs. This includes both CPs and IFAs */ +#define CSD_NUMBER_ONLINE_CPUS 0xD4 + +/* Address of system resources manager (SRM) control table */ +#define CVTOPCTP_OFFSET 0x25C + +/* Address of the RCT table */ +#define RMCTRCT_OFFSET 0xE4 + +/* Address of the rsm control and enumeration area. */ +#define CVTRCEP_OFFSET 0x490 + +/* Total number of frames currently on all available frame queues. */ +#define RCEAFC_OFFSET 0x088 + +/* CPC model length from the CSRSI Service. */ +#define CPCMODEL_LENGTH 16 + +/* Pointer to the home (current) ASCB. */ +#define PSAAOLD 0x224 + +/* Pointer to rsm address space block extension. */ +#define ASCBRSME 0x16C + +/* + NUMBER OF FRAMES CURRENTLY IN USE BY THIS ADDRESS SPACE. + It does not include 2G frames. +*/ +#define RAXFMCT 0x2C + +/* Thread Entry constants */ +#define PGTH_CURRENT 1 +#define PGTH_LEN 26 +#define PGTHAPATH 0x20 +#pragma linkage(BPX4GTH, OS) +#pragma linkage(BPX1GTH, OS) + +/* TOD Clock resolution in nanoseconds */ +#define TOD_RES 4.096 + +typedef unsigned data_area_ptr_assign_type; + +typedef union { + struct { +#if defined(_LP64) + data_area_ptr_assign_type lower; +#endif + data_area_ptr_assign_type assign; + }; + char* deref; +} data_area_ptr; + + +void uv_loadavg(double avg[3]) { + /* TODO: implement the following */ + avg[0] = 0; + avg[1] = 0; + avg[2] = 0; +} + + +int uv__platform_loop_init(uv_loop_t* loop) { + uv__os390_epoll* ep; + + ep = epoll_create1(0); + loop->ep = ep; + if (ep == NULL) + return UV__ERR(errno); + + return 0; +} + + +void uv__platform_loop_delete(uv_loop_t* loop) { + if (loop->ep != NULL) { + epoll_queue_close(loop->ep); + loop->ep = NULL; + } +} + + +uint64_t uv__hrtime(uv_clocktype_t type) { + unsigned long long timestamp; + __stckf(×tamp); + /* Convert to nanoseconds */ + return timestamp / TOD_RES; +} + + +static int getexe(char* buf, size_t len) { + return uv__strscpy(buf, __getargv()[0], len); +} + + +/* + * We could use a static buffer for the path manipulations that we need outside + * of the function, but this function could be called by multiple consumers and + * we don't want to potentially create a race condition in the use of snprintf. + * There is no direct way of getting the exe path in zOS - either through /procfs + * or through some libc APIs. The below approach is to parse the argv[0]'s pattern + * and use it in conjunction with PATH environment variable to craft one. + */ +int uv_exepath(char* buffer, size_t* size) { + int res; + char args[PATH_MAX]; + int pid; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + res = getexe(args, sizeof(args)); + if (res < 0) + return UV_EINVAL; + + return uv__search_path(args, buffer, size); +} + + +uint64_t uv_get_free_memory(void) { + uint64_t freeram; + + data_area_ptr cvt = {0}; + data_area_ptr rcep = {0}; + cvt.assign = *(data_area_ptr_assign_type*)(CVT_PTR); + rcep.assign = *(data_area_ptr_assign_type*)(cvt.deref + CVTRCEP_OFFSET); + freeram = (uint64_t)*((uint32_t*)(rcep.deref + RCEAFC_OFFSET)) * 4096; + return freeram; +} + + +uint64_t uv_get_total_memory(void) { + /* Use CVTRLSTG to get the size of actual real storage online at IPL in K. */ + return (uint64_t)((int)((char *__ptr32 *__ptr32 *)0)[4][214]) * 1024; +} + + +uint64_t uv_get_constrained_memory(void) { + struct rlimit rl; + + /* RLIMIT_MEMLIMIT return value is in megabytes rather than bytes. */ + if (getrlimit(RLIMIT_MEMLIMIT, &rl) == 0) + return rl.rlim_cur * 1024 * 1024; + + return 0; /* There is no memory limit set. */ +} + + +int uv_resident_set_memory(size_t* rss) { + char* ascb; + char* rax; + size_t nframes; + + ascb = *(char* __ptr32 *)(PSA_PTR + PSAAOLD); + rax = *(char* __ptr32 *)(ascb + ASCBRSME); + nframes = *(unsigned int*)(rax + RAXFMCT); + + *rss = nframes * sysconf(_SC_PAGESIZE); + return 0; +} + + +int uv_uptime(double* uptime) { + struct utmpx u ; + struct utmpx *v; + time64_t t; + + u.ut_type = BOOT_TIME; + v = getutxid(&u); + if (v == NULL) + return -1; + *uptime = difftime64(time64(&t), v->ut_tv.tv_sec); + return 0; +} + + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + uv_cpu_info_t* cpu_info; + int idx; + siv1v2 info; + data_area_ptr cvt = {0}; + data_area_ptr csd = {0}; + data_area_ptr rmctrct = {0}; + data_area_ptr cvtopctp = {0}; + int cpu_usage_avg; + + cvt.assign = *(data_area_ptr_assign_type*)(CVT_PTR); + + csd.assign = *((data_area_ptr_assign_type *) (cvt.deref + CSD_OFFSET)); + cvtopctp.assign = *((data_area_ptr_assign_type *) (cvt.deref + CVTOPCTP_OFFSET)); + rmctrct.assign = *((data_area_ptr_assign_type *) (cvtopctp.deref + RMCTRCT_OFFSET)); + + *count = *((int*) (csd.deref + CSD_NUMBER_ONLINE_CPUS)); + cpu_usage_avg = *((unsigned short int*) (rmctrct.deref + RCTLACS_OFFSET)); + + *cpu_infos = uv__malloc(*count * sizeof(uv_cpu_info_t)); + if (!*cpu_infos) + return UV_ENOMEM; + + cpu_info = *cpu_infos; + idx = 0; + while (idx < *count) { + cpu_info->speed = *(int*)(info.siv1v2si22v1.si22v1cpucapability); + cpu_info->model = uv__malloc(CPCMODEL_LENGTH + 1); + memset(cpu_info->model, '\0', CPCMODEL_LENGTH + 1); + memcpy(cpu_info->model, info.siv1v2si11v1.si11v1cpcmodel, CPCMODEL_LENGTH); + cpu_info->cpu_times.user = cpu_usage_avg; + /* TODO: implement the following */ + cpu_info->cpu_times.sys = 0; + cpu_info->cpu_times.idle = 0; + cpu_info->cpu_times.irq = 0; + cpu_info->cpu_times.nice = 0; + ++cpu_info; + ++idx; + } + + return 0; +} + + +static int uv__interface_addresses_v6(uv_interface_address_t** addresses, + int* count) { + uv_interface_address_t* address; + int sockfd; + int maxsize; + __net_ifconf6header_t ifc; + __net_ifconf6entry_t* ifr; + __net_ifconf6entry_t* p; + __net_ifconf6entry_t flg; + + *count = 0; + /* Assume maximum buffer size allowable */ + maxsize = 16384; + + if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) + return UV__ERR(errno); + + ifc.__nif6h_version = 1; + ifc.__nif6h_buflen = maxsize; + ifc.__nif6h_buffer = uv__calloc(1, maxsize);; + + if (ioctl(sockfd, SIOCGIFCONF6, &ifc) == -1) { + uv__close(sockfd); + return UV__ERR(errno); + } + + + *count = 0; + ifr = (__net_ifconf6entry_t*)(ifc.__nif6h_buffer); + while ((char*)ifr < (char*)ifc.__nif6h_buffer + ifc.__nif6h_buflen) { + p = ifr; + ifr = (__net_ifconf6entry_t*)((char*)ifr + ifc.__nif6h_entrylen); + + if (!(p->__nif6e_addr.sin6_family == AF_INET6 || + p->__nif6e_addr.sin6_family == AF_INET)) + continue; + + if (!(p->__nif6e_flags & _NIF6E_FLAGS_ON_LINK_ACTIVE)) + continue; + + ++(*count); + } + + /* Alloc the return interface structs */ + *addresses = uv__malloc(*count * sizeof(uv_interface_address_t)); + if (!(*addresses)) { + uv__close(sockfd); + return UV_ENOMEM; + } + address = *addresses; + + ifr = (__net_ifconf6entry_t*)(ifc.__nif6h_buffer); + while ((char*)ifr < (char*)ifc.__nif6h_buffer + ifc.__nif6h_buflen) { + p = ifr; + ifr = (__net_ifconf6entry_t*)((char*)ifr + ifc.__nif6h_entrylen); + + if (!(p->__nif6e_addr.sin6_family == AF_INET6 || + p->__nif6e_addr.sin6_family == AF_INET)) + continue; + + if (!(p->__nif6e_flags & _NIF6E_FLAGS_ON_LINK_ACTIVE)) + continue; + + /* All conditions above must match count loop */ + + address->name = uv__strdup(p->__nif6e_name); + + if (p->__nif6e_addr.sin6_family == AF_INET6) + address->address.address6 = *((struct sockaddr_in6*) &p->__nif6e_addr); + else + address->address.address4 = *((struct sockaddr_in*) &p->__nif6e_addr); + + /* TODO: Retrieve netmask using SIOCGIFNETMASK ioctl */ + + address->is_internal = flg.__nif6e_flags & _NIF6E_FLAGS_LOOPBACK ? 1 : 0; + memset(address->phys_addr, 0, sizeof(address->phys_addr)); + address++; + } + + uv__close(sockfd); + return 0; +} + + +int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { + uv_interface_address_t* address; + int sockfd; + int maxsize; + struct ifconf ifc; + struct ifreq flg; + struct ifreq* ifr; + struct ifreq* p; + int count_v6; + + *count = 0; + *addresses = NULL; + + /* get the ipv6 addresses first */ + uv_interface_address_t* addresses_v6; + uv__interface_addresses_v6(&addresses_v6, &count_v6); + + /* now get the ipv4 addresses */ + + /* Assume maximum buffer size allowable */ + maxsize = 16384; + + sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + if (0 > sockfd) + return UV__ERR(errno); + + ifc.ifc_req = uv__calloc(1, maxsize); + ifc.ifc_len = maxsize; + if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) { + uv__close(sockfd); + return UV__ERR(errno); + } + +#define MAX(a,b) (((a)>(b))?(a):(b)) +#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p)) + + /* Count all up and running ipv4/ipv6 addresses */ + ifr = ifc.ifc_req; + while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { + p = ifr; + ifr = (struct ifreq*) + ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr)); + + if (!(p->ifr_addr.sa_family == AF_INET6 || + p->ifr_addr.sa_family == AF_INET)) + continue; + + memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); + if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) { + uv__close(sockfd); + return UV__ERR(errno); + } + + if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) + continue; + + (*count)++; + } + + if (*count == 0) { + uv__close(sockfd); + return 0; + } + + /* Alloc the return interface structs */ + *addresses = uv__malloc((*count + count_v6) * + sizeof(uv_interface_address_t)); + + if (!(*addresses)) { + uv__close(sockfd); + return UV_ENOMEM; + } + address = *addresses; + + /* copy over the ipv6 addresses */ + memcpy(address, addresses_v6, count_v6 * sizeof(uv_interface_address_t)); + address += count_v6; + *count += count_v6; + uv__free(addresses_v6); + + ifr = ifc.ifc_req; + while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) { + p = ifr; + ifr = (struct ifreq*) + ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr)); + + if (!(p->ifr_addr.sa_family == AF_INET6 || + p->ifr_addr.sa_family == AF_INET)) + continue; + + memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); + if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) { + uv__close(sockfd); + return UV_ENOSYS; + } + + if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) + continue; + + /* All conditions above must match count loop */ + + address->name = uv__strdup(p->ifr_name); + + if (p->ifr_addr.sa_family == AF_INET6) { + address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr); + } else { + address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr); + } + + address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0; + memset(address->phys_addr, 0, sizeof(address->phys_addr)); + address++; + } + +#undef ADDR_SIZE +#undef MAX + + uv__close(sockfd); + return 0; +} + + +void uv_free_interface_addresses(uv_interface_address_t* addresses, + int count) { + int i; + for (i = 0; i < count; ++i) + uv__free(addresses[i].name); + uv__free(addresses); +} + + +void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { + struct epoll_event* events; + struct epoll_event dummy; + uintptr_t i; + uintptr_t nfds; + + assert(loop->watchers != NULL); + assert(fd >= 0); + + events = (struct epoll_event*) loop->watchers[loop->nwatchers]; + nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; + if (events != NULL) + /* Invalidate events with same file descriptor */ + for (i = 0; i < nfds; i++) + if ((int) events[i].fd == fd) + events[i].fd = -1; + + /* Remove the file descriptor from the epoll. */ + if (loop->ep != NULL) + epoll_ctl(loop->ep, EPOLL_CTL_DEL, fd, &dummy); +} + + +int uv__io_check_fd(uv_loop_t* loop, int fd) { + struct pollfd p[1]; + int rv; + + p[0].fd = fd; + p[0].events = POLLIN; + + do + rv = poll(p, 1, 0); + while (rv == -1 && errno == EINTR); + + if (rv == -1) + abort(); + + if (p[0].revents & POLLNVAL) + return -1; + + return 0; +} + + +void uv__fs_event_close(uv_fs_event_t* handle) { + uv_fs_event_stop(handle); +} + + +int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { + uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); + return 0; +} + + +int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, + const char* filename, unsigned int flags) { + uv__os390_epoll* ep; + _RFIS reg_struct; + char* path; + int rc; + + if (uv__is_active(handle)) + return UV_EINVAL; + + ep = handle->loop->ep; + assert(ep->msg_queue != -1); + + reg_struct.__rfis_cmd = _RFIS_REG; + reg_struct.__rfis_qid = ep->msg_queue; + reg_struct.__rfis_type = 1; + memcpy(reg_struct.__rfis_utok, &handle, sizeof(handle)); + + path = uv__strdup(filename); + if (path == NULL) + return UV_ENOMEM; + + rc = __w_pioctl(path, _IOCC_REGFILEINT, sizeof(reg_struct), ®_struct); + if (rc != 0) + return UV__ERR(errno); + + uv__handle_start(handle); + handle->path = path; + handle->cb = cb; + memcpy(handle->rfis_rftok, reg_struct.__rfis_rftok, + sizeof(handle->rfis_rftok)); + + return 0; +} + + +int uv_fs_event_stop(uv_fs_event_t* handle) { + uv__os390_epoll* ep; + _RFIS reg_struct; + int rc; + + if (!uv__is_active(handle)) + return 0; + + ep = handle->loop->ep; + assert(ep->msg_queue != -1); + + reg_struct.__rfis_cmd = _RFIS_UNREG; + reg_struct.__rfis_qid = ep->msg_queue; + reg_struct.__rfis_type = 1; + memcpy(reg_struct.__rfis_rftok, handle->rfis_rftok, + sizeof(handle->rfis_rftok)); + + /* + * This call will take "/" as the path argument in case we + * don't care to supply the correct path. The system will simply + * ignore it. + */ + rc = __w_pioctl("/", _IOCC_REGFILEINT, sizeof(reg_struct), ®_struct); + if (rc != 0 && errno != EALREADY && errno != ENOENT) + abort(); + + uv__handle_stop(handle); + + return 0; +} + + +static int os390_message_queue_handler(uv__os390_epoll* ep) { + uv_fs_event_t* handle; + int msglen; + int events; + _RFIM msg; + + if (ep->msg_queue == -1) + return 0; + + msglen = msgrcv(ep->msg_queue, &msg, sizeof(msg), 0, IPC_NOWAIT); + + if (msglen == -1 && errno == ENOMSG) + return 0; + + if (msglen == -1) + abort(); + + events = 0; + if (msg.__rfim_event == _RFIM_ATTR || msg.__rfim_event == _RFIM_WRITE) + events = UV_CHANGE; + else if (msg.__rfim_event == _RFIM_RENAME) + events = UV_RENAME; + else + /* Some event that we are not interested in. */ + return 0; + + /* `__rfim_utok` is treated as text when it should be treated as binary while + * running in ASCII mode, resulting in an unwanted autoconversion. + */ + __a2e_l(msg.__rfim_utok, sizeof(msg.__rfim_utok)); + handle = *(uv_fs_event_t**)(msg.__rfim_utok); + handle->cb(handle, uv__basename_r(handle->path), events, 0); + return 1; +} + + +void uv__io_poll(uv_loop_t* loop, int timeout) { + static const int max_safe_timeout = 1789569; + struct epoll_event events[1024]; + struct epoll_event* pe; + struct epoll_event e; + uv__os390_epoll* ep; + int real_timeout; + QUEUE* q; + uv__io_t* w; + uint64_t base; + int count; + int nfds; + int fd; + int op; + int i; + int user_timeout; + int reset_timeout; + + if (loop->nfds == 0) { + assert(QUEUE_EMPTY(&loop->watcher_queue)); + return; + } + + while (!QUEUE_EMPTY(&loop->watcher_queue)) { + uv_stream_t* stream; + + q = QUEUE_HEAD(&loop->watcher_queue); + QUEUE_REMOVE(q); + QUEUE_INIT(q); + w = QUEUE_DATA(q, uv__io_t, watcher_queue); + + assert(w->pevents != 0); + assert(w->fd >= 0); + + stream= container_of(w, uv_stream_t, io_watcher); + + assert(w->fd < (int) loop->nwatchers); + + e.events = w->pevents; + e.fd = w->fd; + + if (w->events == 0) + op = EPOLL_CTL_ADD; + else + op = EPOLL_CTL_MOD; + + /* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching + * events, skip the syscall and squelch the events after epoll_wait(). + */ + if (epoll_ctl(loop->ep, op, w->fd, &e)) { + if (errno != EEXIST) + abort(); + + assert(op == EPOLL_CTL_ADD); + + /* We've reactivated a file descriptor that's been watched before. */ + if (epoll_ctl(loop->ep, EPOLL_CTL_MOD, w->fd, &e)) + abort(); + } + + w->events = w->pevents; + } + + assert(timeout >= -1); + base = loop->time; + count = 48; /* Benchmarks suggest this gives the best throughput. */ + real_timeout = timeout; + int nevents = 0; + + if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) { + reset_timeout = 1; + user_timeout = timeout; + timeout = 0; + } else { + reset_timeout = 0; + } + + nfds = 0; + for (;;) { + /* Only need to set the provider_entry_time if timeout != 0. The function + * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME. + */ + if (timeout != 0) + uv__metrics_set_provider_entry_time(loop); + + if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout) + timeout = max_safe_timeout; + + nfds = epoll_wait(loop->ep, events, + ARRAY_SIZE(events), timeout); + + /* Update loop->time unconditionally. It's tempting to skip the update when + * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the + * operating system didn't reschedule our process while in the syscall. + */ + base = loop->time; + SAVE_ERRNO(uv__update_time(loop)); + if (nfds == 0) { + assert(timeout != -1); + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (timeout == -1) + continue; + + if (timeout == 0) + return; + + /* We may have been inside the system call for longer than |timeout| + * milliseconds so we need to update the timestamp to avoid drift. + */ + goto update_timeout; + } + + if (nfds == -1) { + + if (errno != EINTR) + abort(); + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (timeout == -1) + continue; + + if (timeout == 0) + return; + + /* Interrupted by a signal. Update timeout and poll again. */ + goto update_timeout; + } + + + assert(loop->watchers != NULL); + loop->watchers[loop->nwatchers] = (void*) events; + loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds; + for (i = 0; i < nfds; i++) { + pe = events + i; + fd = pe->fd; + + /* Skip invalidated events, see uv__platform_invalidate_fd */ + if (fd == -1) + continue; + + ep = loop->ep; + if (pe->is_msg) { + os390_message_queue_handler(ep); + continue; + } + + assert(fd >= 0); + assert((unsigned) fd < loop->nwatchers); + + w = loop->watchers[fd]; + + if (w == NULL) { + /* File descriptor that we've stopped watching, disarm it. + * + * Ignore all errors because we may be racing with another thread + * when the file descriptor is closed. + */ + epoll_ctl(loop->ep, EPOLL_CTL_DEL, fd, pe); + continue; + } + + /* Give users only events they're interested in. Prevents spurious + * callbacks when previous callback invocation in this loop has stopped + * the current watcher. Also, filters out events that users has not + * requested us to watch. + */ + pe->events &= w->pevents | POLLERR | POLLHUP; + + if (pe->events == POLLERR || pe->events == POLLHUP) + pe->events |= w->pevents & (POLLIN | POLLOUT); + + if (pe->events != 0) { + uv__metrics_update_idle_time(loop); + w->cb(loop, w, pe->events); + nevents++; + } + } + loop->watchers[loop->nwatchers] = NULL; + loop->watchers[loop->nwatchers + 1] = NULL; + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (nevents != 0) { + if (nfds == ARRAY_SIZE(events) && --count != 0) { + /* Poll for more events but don't block this time. */ + timeout = 0; + continue; + } + return; + } + + if (timeout == 0) + return; + + if (timeout == -1) + continue; + +update_timeout: + assert(timeout > 0); + + real_timeout -= (loop->time - base); + if (real_timeout <= 0) + return; + + timeout = real_timeout; + } +} + + +int uv__io_fork(uv_loop_t* loop) { + /* + Nullify the msg queue but don't close it because + it is still being used by the parent. + */ + loop->ep = NULL; + + uv__platform_loop_delete(loop); + return uv__platform_loop_init(loop); +} diff --git a/external/src/libuv/src/unix/pipe.c b/external/src/libuv/src/unix/pipe.c new file mode 100644 index 0000000..788e038 --- /dev/null +++ b/external/src/libuv/src/unix/pipe.c @@ -0,0 +1,435 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include +#include + + +int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) { + uv__stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE); + handle->shutdown_req = NULL; + handle->connect_req = NULL; + handle->pipe_fname = NULL; + handle->ipc = ipc; + return 0; +} + + +int uv_pipe_bind(uv_pipe_t* handle, const char* name) { + struct sockaddr_un saddr; + const char* pipe_fname; + int sockfd; + int err; + + pipe_fname = NULL; + + /* Already bound? */ + if (uv__stream_fd(handle) >= 0) + return UV_EINVAL; + + /* Make a copy of the file name, it outlives this function's scope. */ + pipe_fname = uv__strdup(name); + if (pipe_fname == NULL) + return UV_ENOMEM; + + /* We've got a copy, don't touch the original any more. */ + name = NULL; + + err = uv__socket(AF_UNIX, SOCK_STREAM, 0); + if (err < 0) + goto err_socket; + sockfd = err; + + memset(&saddr, 0, sizeof saddr); + uv__strscpy(saddr.sun_path, pipe_fname, sizeof(saddr.sun_path)); + saddr.sun_family = AF_UNIX; + + if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) { + err = UV__ERR(errno); + /* Convert ENOENT to EACCES for compatibility with Windows. */ + if (err == UV_ENOENT) + err = UV_EACCES; + + uv__close(sockfd); + goto err_socket; + } + + /* Success. */ + handle->flags |= UV_HANDLE_BOUND; + handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */ + handle->io_watcher.fd = sockfd; + return 0; + +err_socket: + uv__free((void*)pipe_fname); + return err; +} + + +int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) { + if (uv__stream_fd(handle) == -1) + return UV_EINVAL; + + if (handle->ipc) + return UV_EINVAL; + +#if defined(__MVS__) || defined(__PASE__) + /* On zOS, backlog=0 has undefined behaviour */ + /* On IBMi PASE, backlog=0 leads to "Connection refused" error */ + if (backlog == 0) + backlog = 1; + else if (backlog < 0) + backlog = SOMAXCONN; +#endif + + if (listen(uv__stream_fd(handle), backlog)) + return UV__ERR(errno); + + handle->connection_cb = cb; + handle->io_watcher.cb = uv__server_io; + uv__io_start(handle->loop, &handle->io_watcher, POLLIN); + return 0; +} + + +void uv__pipe_close(uv_pipe_t* handle) { + if (handle->pipe_fname) { + /* + * Unlink the file system entity before closing the file descriptor. + * Doing it the other way around introduces a race where our process + * unlinks a socket with the same name that's just been created by + * another thread or process. + */ + unlink(handle->pipe_fname); + uv__free((void*)handle->pipe_fname); + handle->pipe_fname = NULL; + } + + uv__stream_close((uv_stream_t*)handle); +} + + +int uv_pipe_open(uv_pipe_t* handle, uv_file fd) { + int flags; + int mode; + int err; + flags = 0; + + if (uv__fd_exists(handle->loop, fd)) + return UV_EEXIST; + + do + mode = fcntl(fd, F_GETFL); + while (mode == -1 && errno == EINTR); + + if (mode == -1) + return UV__ERR(errno); /* according to docs, must be EBADF */ + + err = uv__nonblock(fd, 1); + if (err) + return err; + +#if defined(__APPLE__) + err = uv__stream_try_select((uv_stream_t*) handle, &fd); + if (err) + return err; +#endif /* defined(__APPLE__) */ + + mode &= O_ACCMODE; + if (mode != O_WRONLY) + flags |= UV_HANDLE_READABLE; + if (mode != O_RDONLY) + flags |= UV_HANDLE_WRITABLE; + + return uv__stream_open((uv_stream_t*)handle, fd, flags); +} + + +void uv_pipe_connect(uv_connect_t* req, + uv_pipe_t* handle, + const char* name, + uv_connect_cb cb) { + struct sockaddr_un saddr; + int new_sock; + int err; + int r; + + new_sock = (uv__stream_fd(handle) == -1); + + if (new_sock) { + err = uv__socket(AF_UNIX, SOCK_STREAM, 0); + if (err < 0) + goto out; + handle->io_watcher.fd = err; + } + + memset(&saddr, 0, sizeof saddr); + uv__strscpy(saddr.sun_path, name, sizeof(saddr.sun_path)); + saddr.sun_family = AF_UNIX; + + do { + r = connect(uv__stream_fd(handle), + (struct sockaddr*)&saddr, sizeof saddr); + } + while (r == -1 && errno == EINTR); + + if (r == -1 && errno != EINPROGRESS) { + err = UV__ERR(errno); +#if defined(__CYGWIN__) || defined(__MSYS__) + /* EBADF is supposed to mean that the socket fd is bad, but + Cygwin reports EBADF instead of ENOTSOCK when the file is + not a socket. We do not expect to see a bad fd here + (e.g. due to new_sock), so translate the error. */ + if (err == UV_EBADF) + err = UV_ENOTSOCK; +#endif + goto out; + } + + err = 0; + if (new_sock) { + err = uv__stream_open((uv_stream_t*)handle, + uv__stream_fd(handle), + UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); + } + + if (err == 0) + uv__io_start(handle->loop, &handle->io_watcher, POLLOUT); + +out: + handle->delayed_error = err; + handle->connect_req = req; + + uv__req_init(handle->loop, req, UV_CONNECT); + req->handle = (uv_stream_t*)handle; + req->cb = cb; + QUEUE_INIT(&req->queue); + + /* Force callback to run on next tick in case of error. */ + if (err) + uv__io_feed(handle->loop, &handle->io_watcher); + +} + + +static int uv__pipe_getsockpeername(const uv_pipe_t* handle, + uv__peersockfunc func, + char* buffer, + size_t* size) { + struct sockaddr_un sa; + socklen_t addrlen; + int err; + + addrlen = sizeof(sa); + memset(&sa, 0, addrlen); + err = uv__getsockpeername((const uv_handle_t*) handle, + func, + (struct sockaddr*) &sa, + (int*) &addrlen); + if (err < 0) { + *size = 0; + return err; + } + +#if defined(__linux__) + if (sa.sun_path[0] == 0) + /* Linux abstract namespace */ + addrlen -= offsetof(struct sockaddr_un, sun_path); + else +#endif + addrlen = strlen(sa.sun_path); + + + if ((size_t)addrlen >= *size) { + *size = addrlen + 1; + return UV_ENOBUFS; + } + + memcpy(buffer, sa.sun_path, addrlen); + *size = addrlen; + + /* only null-terminate if it's not an abstract socket */ + if (buffer[0] != '\0') + buffer[addrlen] = '\0'; + + return 0; +} + + +int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) { + return uv__pipe_getsockpeername(handle, getsockname, buffer, size); +} + + +int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) { + return uv__pipe_getsockpeername(handle, getpeername, buffer, size); +} + + +void uv_pipe_pending_instances(uv_pipe_t* handle, int count) { +} + + +int uv_pipe_pending_count(uv_pipe_t* handle) { + uv__stream_queued_fds_t* queued_fds; + + if (!handle->ipc) + return 0; + + if (handle->accepted_fd == -1) + return 0; + + if (handle->queued_fds == NULL) + return 1; + + queued_fds = handle->queued_fds; + return queued_fds->offset + 1; +} + + +uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) { + if (!handle->ipc) + return UV_UNKNOWN_HANDLE; + + if (handle->accepted_fd == -1) + return UV_UNKNOWN_HANDLE; + else + return uv__handle_type(handle->accepted_fd); +} + + +int uv_pipe_chmod(uv_pipe_t* handle, int mode) { + unsigned desired_mode; + struct stat pipe_stat; + char* name_buffer; + size_t name_len; + int r; + + if (handle == NULL || uv__stream_fd(handle) == -1) + return UV_EBADF; + + if (mode != UV_READABLE && + mode != UV_WRITABLE && + mode != (UV_WRITABLE | UV_READABLE)) + return UV_EINVAL; + + /* Unfortunately fchmod does not work on all platforms, we will use chmod. */ + name_len = 0; + r = uv_pipe_getsockname(handle, NULL, &name_len); + if (r != UV_ENOBUFS) + return r; + + name_buffer = uv__malloc(name_len); + if (name_buffer == NULL) + return UV_ENOMEM; + + r = uv_pipe_getsockname(handle, name_buffer, &name_len); + if (r != 0) { + uv__free(name_buffer); + return r; + } + + /* stat must be used as fstat has a bug on Darwin */ + if (stat(name_buffer, &pipe_stat) == -1) { + uv__free(name_buffer); + return -errno; + } + + desired_mode = 0; + if (mode & UV_READABLE) + desired_mode |= S_IRUSR | S_IRGRP | S_IROTH; + if (mode & UV_WRITABLE) + desired_mode |= S_IWUSR | S_IWGRP | S_IWOTH; + + /* Exit early if pipe already has desired mode. */ + if ((pipe_stat.st_mode & desired_mode) == desired_mode) { + uv__free(name_buffer); + return 0; + } + + pipe_stat.st_mode |= desired_mode; + + r = chmod(name_buffer, pipe_stat.st_mode); + uv__free(name_buffer); + + return r != -1 ? 0 : UV__ERR(errno); +} + + +int uv_pipe(uv_os_fd_t fds[2], int read_flags, int write_flags) { + uv_os_fd_t temp[2]; + int err; +#if defined(__FreeBSD__) || defined(__linux__) + int flags = O_CLOEXEC; + + if ((read_flags & UV_NONBLOCK_PIPE) && (write_flags & UV_NONBLOCK_PIPE)) + flags |= UV_FS_O_NONBLOCK; + + if (pipe2(temp, flags)) + return UV__ERR(errno); + + if (flags & UV_FS_O_NONBLOCK) { + fds[0] = temp[0]; + fds[1] = temp[1]; + return 0; + } +#else + if (pipe(temp)) + return UV__ERR(errno); + + if ((err = uv__cloexec(temp[0], 1))) + goto fail; + + if ((err = uv__cloexec(temp[1], 1))) + goto fail; +#endif + + if (read_flags & UV_NONBLOCK_PIPE) + if ((err = uv__nonblock(temp[0], 1))) + goto fail; + + if (write_flags & UV_NONBLOCK_PIPE) + if ((err = uv__nonblock(temp[1], 1))) + goto fail; + + fds[0] = temp[0]; + fds[1] = temp[1]; + return 0; + +fail: + uv__close(temp[0]); + uv__close(temp[1]); + return err; +} + + +int uv__make_pipe(int fds[2], int flags) { + return uv_pipe(fds, + flags & UV_NONBLOCK_PIPE, + flags & UV_NONBLOCK_PIPE); +} diff --git a/external/src/libuv/src/unix/poll.c b/external/src/libuv/src/unix/poll.c new file mode 100644 index 0000000..7a12e2d --- /dev/null +++ b/external/src/libuv/src/unix/poll.c @@ -0,0 +1,160 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include + + +static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { + uv_poll_t* handle; + int pevents; + + handle = container_of(w, uv_poll_t, io_watcher); + + /* + * As documented in the kernel source fs/kernfs/file.c #780 + * poll will return POLLERR|POLLPRI in case of sysfs + * polling. This does not happen in case of out-of-band + * TCP messages. + * + * The above is the case on (at least) FreeBSD and Linux. + * + * So to properly determine a POLLPRI or a POLLERR we need + * to check for both. + */ + if ((events & POLLERR) && !(events & UV__POLLPRI)) { + uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI); + uv__handle_stop(handle); + handle->poll_cb(handle, UV_EBADF, 0); + return; + } + + pevents = 0; + if (events & POLLIN) + pevents |= UV_READABLE; + if (events & UV__POLLPRI) + pevents |= UV_PRIORITIZED; + if (events & POLLOUT) + pevents |= UV_WRITABLE; + if (events & UV__POLLRDHUP) + pevents |= UV_DISCONNECT; + + handle->poll_cb(handle, 0, pevents); +} + + +int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) { + int err; + + if (uv__fd_exists(loop, fd)) + return UV_EEXIST; + + err = uv__io_check_fd(loop, fd); + if (err) + return err; + + /* If ioctl(FIONBIO) reports ENOTTY, try fcntl(F_GETFL) + fcntl(F_SETFL). + * Workaround for e.g. kqueue fds not supporting ioctls. + */ + err = uv__nonblock(fd, 1); +#if UV__NONBLOCK_IS_IOCTL + if (err == UV_ENOTTY) + err = uv__nonblock_fcntl(fd, 1); +#endif + + if (err) + return err; + + uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL); + uv__io_init(&handle->io_watcher, uv__poll_io, fd); + handle->poll_cb = NULL; + return 0; +} + + +int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, + uv_os_sock_t socket) { + return uv_poll_init(loop, handle, socket); +} + + +static void uv__poll_stop(uv_poll_t* handle) { + uv__io_stop(handle->loop, + &handle->io_watcher, + POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI); + uv__handle_stop(handle); + uv__platform_invalidate_fd(handle->loop, handle->io_watcher.fd); +} + + +int uv_poll_stop(uv_poll_t* handle) { + assert(!uv__is_closing(handle)); + uv__poll_stop(handle); + return 0; +} + + +int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) { + uv__io_t** watchers; + uv__io_t* w; + int events; + + assert((pevents & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT | + UV_PRIORITIZED)) == 0); + assert(!uv__is_closing(handle)); + + watchers = handle->loop->watchers; + w = &handle->io_watcher; + + if (uv__fd_exists(handle->loop, w->fd)) + if (watchers[w->fd] != w) + return UV_EEXIST; + + uv__poll_stop(handle); + + if (pevents == 0) + return 0; + + events = 0; + if (pevents & UV_READABLE) + events |= POLLIN; + if (pevents & UV_PRIORITIZED) + events |= UV__POLLPRI; + if (pevents & UV_WRITABLE) + events |= POLLOUT; + if (pevents & UV_DISCONNECT) + events |= UV__POLLRDHUP; + + uv__io_start(handle->loop, &handle->io_watcher, events); + uv__handle_start(handle); + handle->poll_cb = poll_cb; + + return 0; +} + + +void uv__poll_close(uv_poll_t* handle) { + uv__poll_stop(handle); +} diff --git a/external/src/libuv/src/unix/posix-hrtime.c b/external/src/libuv/src/unix/posix-hrtime.c new file mode 100644 index 0000000..323dfc2 --- /dev/null +++ b/external/src/libuv/src/unix/posix-hrtime.c @@ -0,0 +1,35 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +#undef NANOSEC +#define NANOSEC ((uint64_t) 1e9) + +uint64_t uv__hrtime(uv_clocktype_t type) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec); +} diff --git a/external/src/libuv/src/unix/posix-poll.c b/external/src/libuv/src/unix/posix-poll.c new file mode 100644 index 0000000..0f4bf93 --- /dev/null +++ b/external/src/libuv/src/unix/posix-poll.c @@ -0,0 +1,374 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +/* POSIX defines poll() as a portable way to wait on file descriptors. + * Here we maintain a dynamically sized array of file descriptors and + * events to pass as the first argument to poll(). + */ + +#include +#include +#include +#include +#include + +int uv__platform_loop_init(uv_loop_t* loop) { + loop->poll_fds = NULL; + loop->poll_fds_used = 0; + loop->poll_fds_size = 0; + loop->poll_fds_iterating = 0; + return 0; +} + +void uv__platform_loop_delete(uv_loop_t* loop) { + uv__free(loop->poll_fds); + loop->poll_fds = NULL; +} + +int uv__io_fork(uv_loop_t* loop) { + uv__platform_loop_delete(loop); + return uv__platform_loop_init(loop); +} + +/* Allocate or dynamically resize our poll fds array. */ +static void uv__pollfds_maybe_resize(uv_loop_t* loop) { + size_t i; + size_t n; + struct pollfd* p; + + if (loop->poll_fds_used < loop->poll_fds_size) + return; + + n = loop->poll_fds_size ? loop->poll_fds_size * 2 : 64; + p = uv__reallocf(loop->poll_fds, n * sizeof(*loop->poll_fds)); + if (p == NULL) + abort(); + + loop->poll_fds = p; + for (i = loop->poll_fds_size; i < n; i++) { + loop->poll_fds[i].fd = -1; + loop->poll_fds[i].events = 0; + loop->poll_fds[i].revents = 0; + } + loop->poll_fds_size = n; +} + +/* Primitive swap operation on poll fds array elements. */ +static void uv__pollfds_swap(uv_loop_t* loop, size_t l, size_t r) { + struct pollfd pfd; + pfd = loop->poll_fds[l]; + loop->poll_fds[l] = loop->poll_fds[r]; + loop->poll_fds[r] = pfd; +} + +/* Add a watcher's fd to our poll fds array with its pending events. */ +static void uv__pollfds_add(uv_loop_t* loop, uv__io_t* w) { + size_t i; + struct pollfd* pe; + + /* If the fd is already in the set just update its events. */ + assert(!loop->poll_fds_iterating); + for (i = 0; i < loop->poll_fds_used; ++i) { + if (loop->poll_fds[i].fd == w->fd) { + loop->poll_fds[i].events = w->pevents; + return; + } + } + + /* Otherwise, allocate a new slot in the set for the fd. */ + uv__pollfds_maybe_resize(loop); + pe = &loop->poll_fds[loop->poll_fds_used++]; + pe->fd = w->fd; + pe->events = w->pevents; +} + +/* Remove a watcher's fd from our poll fds array. */ +static void uv__pollfds_del(uv_loop_t* loop, int fd) { + size_t i; + assert(!loop->poll_fds_iterating); + for (i = 0; i < loop->poll_fds_used;) { + if (loop->poll_fds[i].fd == fd) { + /* swap to last position and remove */ + --loop->poll_fds_used; + uv__pollfds_swap(loop, i, loop->poll_fds_used); + loop->poll_fds[loop->poll_fds_used].fd = -1; + loop->poll_fds[loop->poll_fds_used].events = 0; + loop->poll_fds[loop->poll_fds_used].revents = 0; + /* This method is called with an fd of -1 to purge the invalidated fds, + * so we may possibly have multiples to remove. + */ + if (-1 != fd) + return; + } else { + /* We must only increment the loop counter when the fds do not match. + * Otherwise, when we are purging an invalidated fd, the value just + * swapped here from the previous end of the array will be skipped. + */ + ++i; + } + } +} + + +void uv__io_poll(uv_loop_t* loop, int timeout) { + sigset_t* pset; + sigset_t set; + uint64_t time_base; + uint64_t time_diff; + QUEUE* q; + uv__io_t* w; + size_t i; + unsigned int nevents; + int nfds; + int have_signals; + struct pollfd* pe; + int fd; + int user_timeout; + int reset_timeout; + + if (loop->nfds == 0) { + assert(QUEUE_EMPTY(&loop->watcher_queue)); + return; + } + + /* Take queued watchers and add their fds to our poll fds array. */ + while (!QUEUE_EMPTY(&loop->watcher_queue)) { + q = QUEUE_HEAD(&loop->watcher_queue); + QUEUE_REMOVE(q); + QUEUE_INIT(q); + + w = QUEUE_DATA(q, uv__io_t, watcher_queue); + assert(w->pevents != 0); + assert(w->fd >= 0); + assert(w->fd < (int) loop->nwatchers); + + uv__pollfds_add(loop, w); + + w->events = w->pevents; + } + + /* Prepare a set of signals to block around poll(), if any. */ + pset = NULL; + if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { + pset = &set; + sigemptyset(pset); + sigaddset(pset, SIGPROF); + } + + assert(timeout >= -1); + time_base = loop->time; + + if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) { + reset_timeout = 1; + user_timeout = timeout; + timeout = 0; + } else { + reset_timeout = 0; + } + + /* Loop calls to poll() and processing of results. If we get some + * results from poll() but they turn out not to be interesting to + * our caller then we need to loop around and poll() again. + */ + for (;;) { + /* Only need to set the provider_entry_time if timeout != 0. The function + * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME. + */ + if (timeout != 0) + uv__metrics_set_provider_entry_time(loop); + + if (pset != NULL) + if (pthread_sigmask(SIG_BLOCK, pset, NULL)) + abort(); + nfds = poll(loop->poll_fds, (nfds_t)loop->poll_fds_used, timeout); + if (pset != NULL) + if (pthread_sigmask(SIG_UNBLOCK, pset, NULL)) + abort(); + + /* Update loop->time unconditionally. It's tempting to skip the update when + * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the + * operating system didn't reschedule our process while in the syscall. + */ + SAVE_ERRNO(uv__update_time(loop)); + + if (nfds == 0) { + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + if (timeout == -1) + continue; + if (timeout > 0) + goto update_timeout; + } + + assert(timeout != -1); + return; + } + + if (nfds == -1) { + if (errno != EINTR) + abort(); + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (timeout == -1) + continue; + + if (timeout == 0) + return; + + /* Interrupted by a signal. Update timeout and poll again. */ + goto update_timeout; + } + + /* Tell uv__platform_invalidate_fd not to manipulate our array + * while we are iterating over it. + */ + loop->poll_fds_iterating = 1; + + /* Initialize a count of events that we care about. */ + nevents = 0; + have_signals = 0; + + /* Loop over the entire poll fds array looking for returned events. */ + for (i = 0; i < loop->poll_fds_used; i++) { + pe = loop->poll_fds + i; + fd = pe->fd; + + /* Skip invalidated events, see uv__platform_invalidate_fd. */ + if (fd == -1) + continue; + + assert(fd >= 0); + assert((unsigned) fd < loop->nwatchers); + + w = loop->watchers[fd]; + + if (w == NULL) { + /* File descriptor that we've stopped watching, ignore. */ + uv__platform_invalidate_fd(loop, fd); + continue; + } + + /* Filter out events that user has not requested us to watch + * (e.g. POLLNVAL). + */ + pe->revents &= w->pevents | POLLERR | POLLHUP; + + if (pe->revents != 0) { + /* Run signal watchers last. */ + if (w == &loop->signal_io_watcher) { + have_signals = 1; + } else { + uv__metrics_update_idle_time(loop); + w->cb(loop, w, pe->revents); + } + + nevents++; + } + } + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (have_signals != 0) { + uv__metrics_update_idle_time(loop); + loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN); + } + + loop->poll_fds_iterating = 0; + + /* Purge invalidated fds from our poll fds array. */ + uv__pollfds_del(loop, -1); + + if (have_signals != 0) + return; /* Event loop should cycle now so don't poll again. */ + + if (nevents != 0) + return; + + if (timeout == 0) + return; + + if (timeout == -1) + continue; + +update_timeout: + assert(timeout > 0); + + time_diff = loop->time - time_base; + if (time_diff >= (uint64_t) timeout) + return; + + timeout -= time_diff; + } +} + +/* Remove the given fd from our poll fds array because no one + * is interested in its events anymore. + */ +void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { + size_t i; + + assert(fd >= 0); + + if (loop->poll_fds_iterating) { + /* uv__io_poll is currently iterating. Just invalidate fd. */ + for (i = 0; i < loop->poll_fds_used; i++) + if (loop->poll_fds[i].fd == fd) { + loop->poll_fds[i].fd = -1; + loop->poll_fds[i].events = 0; + loop->poll_fds[i].revents = 0; + } + } else { + /* uv__io_poll is not iterating. Delete fd from the set. */ + uv__pollfds_del(loop, fd); + } +} + +/* Check whether the given fd is supported by poll(). */ +int uv__io_check_fd(uv_loop_t* loop, int fd) { + struct pollfd p[1]; + int rv; + + p[0].fd = fd; + p[0].events = POLLIN; + + do + rv = poll(p, 1, 0); + while (rv == -1 && (errno == EINTR || errno == EAGAIN)); + + if (rv == -1) + return UV__ERR(errno); + + if (p[0].revents & POLLNVAL) + return UV_EINVAL; + + return 0; +} diff --git a/external/src/libuv/src/unix/process.c b/external/src/libuv/src/unix/process.c new file mode 100644 index 0000000..91bf3c5 --- /dev/null +++ b/external/src/libuv/src/unix/process.c @@ -0,0 +1,549 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#if defined(__APPLE__) && !TARGET_OS_IPHONE +# include +# define environ (*_NSGetEnviron()) +#else +extern char **environ; +#endif + +#if defined(__linux__) || defined(__GLIBC__) +# include +#endif + +#if defined(__MVS__) +# include "zos-base.h" +#endif + + +static void uv__chld(uv_signal_t* handle, int signum) { + uv_process_t* process; + uv_loop_t* loop; + int exit_status; + int term_signal; + int status; + pid_t pid; + QUEUE pending; + QUEUE* q; + QUEUE* h; + + assert(signum == SIGCHLD); + + QUEUE_INIT(&pending); + loop = handle->loop; + + h = &loop->process_handles; + q = QUEUE_HEAD(h); + while (q != h) { + process = QUEUE_DATA(q, uv_process_t, queue); + q = QUEUE_NEXT(q); + + do + pid = waitpid(process->pid, &status, WNOHANG); + while (pid == -1 && errno == EINTR); + + if (pid == 0) + continue; + + if (pid == -1) { + if (errno != ECHILD) + abort(); + continue; + } + + process->status = status; + QUEUE_REMOVE(&process->queue); + QUEUE_INSERT_TAIL(&pending, &process->queue); + } + + h = &pending; + q = QUEUE_HEAD(h); + while (q != h) { + process = QUEUE_DATA(q, uv_process_t, queue); + q = QUEUE_NEXT(q); + + QUEUE_REMOVE(&process->queue); + QUEUE_INIT(&process->queue); + uv__handle_stop(process); + + if (process->exit_cb == NULL) + continue; + + exit_status = 0; + if (WIFEXITED(process->status)) + exit_status = WEXITSTATUS(process->status); + + term_signal = 0; + if (WIFSIGNALED(process->status)) + term_signal = WTERMSIG(process->status); + + process->exit_cb(process, exit_status, term_signal); + } + assert(QUEUE_EMPTY(&pending)); +} + +/* + * Used for initializing stdio streams like options.stdin_stream. Returns + * zero on success. See also the cleanup section in uv_spawn(). + */ +static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) { + int mask; + int fd; + + mask = UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | UV_INHERIT_STREAM; + + switch (container->flags & mask) { + case UV_IGNORE: + return 0; + + case UV_CREATE_PIPE: + assert(container->data.stream != NULL); + if (container->data.stream->type != UV_NAMED_PIPE) + return UV_EINVAL; + else + return uv_socketpair(SOCK_STREAM, 0, fds, 0, 0); + + case UV_INHERIT_FD: + case UV_INHERIT_STREAM: + if (container->flags & UV_INHERIT_FD) + fd = container->data.fd; + else + fd = uv__stream_fd(container->data.stream); + + if (fd == -1) + return UV_EINVAL; + + fds[1] = fd; + return 0; + + default: + assert(0 && "Unexpected flags"); + return UV_EINVAL; + } +} + + +static int uv__process_open_stream(uv_stdio_container_t* container, + int pipefds[2]) { + int flags; + int err; + + if (!(container->flags & UV_CREATE_PIPE) || pipefds[0] < 0) + return 0; + + err = uv__close(pipefds[1]); + if (err != 0) + abort(); + + pipefds[1] = -1; + uv__nonblock(pipefds[0], 1); + + flags = 0; + if (container->flags & UV_WRITABLE_PIPE) + flags |= UV_HANDLE_READABLE; + if (container->flags & UV_READABLE_PIPE) + flags |= UV_HANDLE_WRITABLE; + + return uv__stream_open(container->data.stream, pipefds[0], flags); +} + + +static void uv__process_close_stream(uv_stdio_container_t* container) { + if (!(container->flags & UV_CREATE_PIPE)) return; + uv__stream_close(container->data.stream); +} + + +static void uv__write_int(int fd, int val) { + ssize_t n; + + do + n = write(fd, &val, sizeof(val)); + while (n == -1 && errno == EINTR); + + if (n == -1 && errno == EPIPE) + return; /* parent process has quit */ + + assert(n == sizeof(val)); +} + + +static void uv__write_errno(int error_fd) { + uv__write_int(error_fd, UV__ERR(errno)); + _exit(127); +} + + +#if !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)) +/* execvp is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED, so must be + * avoided. Since this isn't called on those targets, the function + * doesn't even need to be defined for them. + */ +static void uv__process_child_init(const uv_process_options_t* options, + int stdio_count, + int (*pipes)[2], + int error_fd) { + sigset_t signewset; + int close_fd; + int use_fd; + int fd; + int n; + + /* Reset signal disposition first. Use a hard-coded limit because NSIG is not + * fixed on Linux: it's either 32, 34 or 64, depending on whether RT signals + * are enabled. We are not allowed to touch RT signal handlers, glibc uses + * them internally. + */ + for (n = 1; n < 32; n += 1) { + if (n == SIGKILL || n == SIGSTOP) + continue; /* Can't be changed. */ + +#if defined(__HAIKU__) + if (n == SIGKILLTHR) + continue; /* Can't be changed. */ +#endif + + if (SIG_ERR != signal(n, SIG_DFL)) + continue; + + uv__write_errno(error_fd); + } + + if (options->flags & UV_PROCESS_DETACHED) + setsid(); + + /* First duplicate low numbered fds, since it's not safe to duplicate them, + * they could get replaced. Example: swapping stdout and stderr; without + * this fd 2 (stderr) would be duplicated into fd 1, thus making both + * stdout and stderr go to the same fd, which was not the intention. */ + for (fd = 0; fd < stdio_count; fd++) { + use_fd = pipes[fd][1]; + if (use_fd < 0 || use_fd >= fd) + continue; + pipes[fd][1] = fcntl(use_fd, F_DUPFD, stdio_count); + if (pipes[fd][1] == -1) + uv__write_errno(error_fd); + } + + for (fd = 0; fd < stdio_count; fd++) { + close_fd = pipes[fd][0]; + use_fd = pipes[fd][1]; + + if (use_fd < 0) { + if (fd >= 3) + continue; + else { + /* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is + * set + */ + use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR); + close_fd = use_fd; + + if (use_fd < 0) + uv__write_errno(error_fd); + } + } + + if (fd == use_fd) + uv__cloexec_fcntl(use_fd, 0); + else + fd = dup2(use_fd, fd); + + if (fd == -1) + uv__write_errno(error_fd); + + if (fd <= 2) + uv__nonblock_fcntl(fd, 0); + + if (close_fd >= stdio_count) + uv__close(close_fd); + } + + for (fd = 0; fd < stdio_count; fd++) { + use_fd = pipes[fd][1]; + + if (use_fd >= stdio_count) + uv__close(use_fd); + } + + if (options->cwd != NULL && chdir(options->cwd)) + uv__write_errno(error_fd); + + if (options->flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) { + /* When dropping privileges from root, the `setgroups` call will + * remove any extraneous groups. If we don't call this, then + * even though our uid has dropped, we may still have groups + * that enable us to do super-user things. This will fail if we + * aren't root, so don't bother checking the return value, this + * is just done as an optimistic privilege dropping function. + */ + SAVE_ERRNO(setgroups(0, NULL)); + } + + if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) + uv__write_errno(error_fd); + + if ((options->flags & UV_PROCESS_SETUID) && setuid(options->uid)) + uv__write_errno(error_fd); + + if (options->env != NULL) { + environ = options->env; + } + + /* Reset signal mask just before exec. */ + sigemptyset(&signewset); + if (sigprocmask(SIG_SETMASK, &signewset, NULL) != 0) + abort(); + +#ifdef __MVS__ + execvpe(options->file, options->args, environ); +#else + execvp(options->file, options->args); +#endif + + uv__write_errno(error_fd); + abort(); +} +#endif + + +int uv_spawn(uv_loop_t* loop, + uv_process_t* process, + const uv_process_options_t* options) { +#if defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH) + /* fork is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED. */ + return UV_ENOSYS; +#else + sigset_t signewset; + sigset_t sigoldset; + int signal_pipe[2] = { -1, -1 }; + int pipes_storage[8][2]; + int (*pipes)[2]; + int stdio_count; + ssize_t r; + pid_t pid; + int err; + int exec_errorno; + int i; + int status; + + assert(options->file != NULL); + assert(!(options->flags & ~(UV_PROCESS_DETACHED | + UV_PROCESS_SETGID | + UV_PROCESS_SETUID | + UV_PROCESS_WINDOWS_HIDE | + UV_PROCESS_WINDOWS_HIDE_CONSOLE | + UV_PROCESS_WINDOWS_HIDE_GUI | + UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS))); + + uv__handle_init(loop, (uv_handle_t*)process, UV_PROCESS); + QUEUE_INIT(&process->queue); + + stdio_count = options->stdio_count; + if (stdio_count < 3) + stdio_count = 3; + + err = UV_ENOMEM; + pipes = pipes_storage; + if (stdio_count > (int) ARRAY_SIZE(pipes_storage)) + pipes = uv__malloc(stdio_count * sizeof(*pipes)); + + if (pipes == NULL) + goto error; + + for (i = 0; i < stdio_count; i++) { + pipes[i][0] = -1; + pipes[i][1] = -1; + } + + for (i = 0; i < options->stdio_count; i++) { + err = uv__process_init_stdio(options->stdio + i, pipes[i]); + if (err) + goto error; + } + + /* This pipe is used by the parent to wait until + * the child has called `execve()`. We need this + * to avoid the following race condition: + * + * if ((pid = fork()) > 0) { + * kill(pid, SIGTERM); + * } + * else if (pid == 0) { + * execve("/bin/cat", argp, envp); + * } + * + * The parent sends a signal immediately after forking. + * Since the child may not have called `execve()` yet, + * there is no telling what process receives the signal, + * our fork or /bin/cat. + * + * To avoid ambiguity, we create a pipe with both ends + * marked close-on-exec. Then, after the call to `fork()`, + * the parent polls the read end until it EOFs or errors with EPIPE. + */ + err = uv__make_pipe(signal_pipe, 0); + if (err) + goto error; + + uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD); + + /* Acquire write lock to prevent opening new fds in worker threads */ + uv_rwlock_wrlock(&loop->cloexec_lock); + + /* Start the child with most signals blocked, to avoid any issues before we + * can reset them, but allow program failures to exit (and not hang). */ + sigfillset(&signewset); + sigdelset(&signewset, SIGKILL); + sigdelset(&signewset, SIGSTOP); + sigdelset(&signewset, SIGTRAP); + sigdelset(&signewset, SIGSEGV); + sigdelset(&signewset, SIGBUS); + sigdelset(&signewset, SIGILL); + sigdelset(&signewset, SIGSYS); + sigdelset(&signewset, SIGABRT); + if (pthread_sigmask(SIG_BLOCK, &signewset, &sigoldset) != 0) + abort(); + + pid = fork(); + if (pid == -1) + err = UV__ERR(errno); + + if (pid == 0) + uv__process_child_init(options, stdio_count, pipes, signal_pipe[1]); + + if (pthread_sigmask(SIG_SETMASK, &sigoldset, NULL) != 0) + abort(); + + /* Release lock in parent process */ + uv_rwlock_wrunlock(&loop->cloexec_lock); + + uv__close(signal_pipe[1]); + + if (pid == -1) { + uv__close(signal_pipe[0]); + goto error; + } + + process->status = 0; + exec_errorno = 0; + do + r = read(signal_pipe[0], &exec_errorno, sizeof(exec_errorno)); + while (r == -1 && errno == EINTR); + + if (r == 0) + ; /* okay, EOF */ + else if (r == sizeof(exec_errorno)) { + do + err = waitpid(pid, &status, 0); /* okay, read errorno */ + while (err == -1 && errno == EINTR); + assert(err == pid); + } else if (r == -1 && errno == EPIPE) { + do + err = waitpid(pid, &status, 0); /* okay, got EPIPE */ + while (err == -1 && errno == EINTR); + assert(err == pid); + } else + abort(); + + uv__close_nocheckstdio(signal_pipe[0]); + + for (i = 0; i < options->stdio_count; i++) { + err = uv__process_open_stream(options->stdio + i, pipes[i]); + if (err == 0) + continue; + + while (i--) + uv__process_close_stream(options->stdio + i); + + goto error; + } + + /* Only activate this handle if exec() happened successfully */ + if (exec_errorno == 0) { + QUEUE_INSERT_TAIL(&loop->process_handles, &process->queue); + uv__handle_start(process); + } + + process->pid = pid; + process->exit_cb = options->exit_cb; + + if (pipes != pipes_storage) + uv__free(pipes); + + return exec_errorno; + +error: + if (pipes != NULL) { + for (i = 0; i < stdio_count; i++) { + if (i < options->stdio_count) + if (options->stdio[i].flags & (UV_INHERIT_FD | UV_INHERIT_STREAM)) + continue; + if (pipes[i][0] != -1) + uv__close_nocheckstdio(pipes[i][0]); + if (pipes[i][1] != -1) + uv__close_nocheckstdio(pipes[i][1]); + } + + if (pipes != pipes_storage) + uv__free(pipes); + } + + return err; +#endif +} + + +int uv_process_kill(uv_process_t* process, int signum) { + return uv_kill(process->pid, signum); +} + + +int uv_kill(int pid, int signum) { + if (kill(pid, signum)) + return UV__ERR(errno); + else + return 0; +} + + +void uv__process_close(uv_process_t* handle) { + QUEUE_REMOVE(&handle->queue); + uv__handle_stop(handle); + if (QUEUE_EMPTY(&handle->loop->process_handles)) + uv_signal_stop(&handle->loop->child_watcher); +} diff --git a/external/src/libuv/src/unix/procfs-exepath.c b/external/src/libuv/src/unix/procfs-exepath.c new file mode 100644 index 0000000..00dc021 --- /dev/null +++ b/external/src/libuv/src/unix/procfs-exepath.c @@ -0,0 +1,45 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +int uv_exepath(char* buffer, size_t* size) { + ssize_t n; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + n = *size - 1; + if (n > 0) + n = readlink("/proc/self/exe", buffer, n); + + if (n == -1) + return UV__ERR(errno); + + buffer[n] = '\0'; + *size = n; + + return 0; +} diff --git a/external/src/libuv/src/unix/proctitle.c b/external/src/libuv/src/unix/proctitle.c new file mode 100644 index 0000000..9d1f00d --- /dev/null +++ b/external/src/libuv/src/unix/proctitle.c @@ -0,0 +1,157 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +struct uv__process_title { + char* str; + size_t len; /* Length of the current process title. */ + size_t cap; /* Maximum capacity. Computed once in uv_setup_args(). */ +}; + +extern void uv__set_process_title(const char* title); + +static uv_mutex_t process_title_mutex; +static uv_once_t process_title_mutex_once = UV_ONCE_INIT; +static struct uv__process_title process_title; +static void* args_mem; + + +static void init_process_title_mutex_once(void) { + uv_mutex_init(&process_title_mutex); +} + + +char** uv_setup_args(int argc, char** argv) { + struct uv__process_title pt; + char** new_argv; + size_t size; + char* s; + int i; + + if (argc <= 0) + return argv; + + pt.str = argv[0]; + pt.len = strlen(argv[0]); + pt.cap = pt.len + 1; + + /* Calculate how much memory we need for the argv strings. */ + size = pt.cap; + for (i = 1; i < argc; i++) + size += strlen(argv[i]) + 1; + + /* Add space for the argv pointers. */ + size += (argc + 1) * sizeof(char*); + + new_argv = uv__malloc(size); + if (new_argv == NULL) + return argv; + + /* Copy over the strings and set up the pointer table. */ + i = 0; + s = (char*) &new_argv[argc + 1]; + size = pt.cap; + goto loop; + + for (/* empty */; i < argc; i++) { + size = strlen(argv[i]) + 1; + loop: + memcpy(s, argv[i], size); + new_argv[i] = s; + s += size; + } + new_argv[i] = NULL; + + pt.cap = argv[i - 1] + size - argv[0]; + + args_mem = new_argv; + process_title = pt; + + return new_argv; +} + + +int uv_set_process_title(const char* title) { + struct uv__process_title* pt; + size_t len; + + /* If uv_setup_args wasn't called or failed, we can't continue. */ + if (args_mem == NULL) + return UV_ENOBUFS; + + pt = &process_title; + len = strlen(title); + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + if (len >= pt->cap) { + len = 0; + if (pt->cap > 0) + len = pt->cap - 1; + } + + memcpy(pt->str, title, len); + memset(pt->str + len, '\0', pt->cap - len); + pt->len = len; + uv__set_process_title(pt->str); + + uv_mutex_unlock(&process_title_mutex); + + return 0; +} + + +int uv_get_process_title(char* buffer, size_t size) { + if (buffer == NULL || size == 0) + return UV_EINVAL; + + /* If uv_setup_args wasn't called or failed, we can't continue. */ + if (args_mem == NULL) + return UV_ENOBUFS; + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + if (size <= process_title.len) { + uv_mutex_unlock(&process_title_mutex); + return UV_ENOBUFS; + } + + if (process_title.len != 0) + memcpy(buffer, process_title.str, process_title.len + 1); + + buffer[process_title.len] = '\0'; + + uv_mutex_unlock(&process_title_mutex); + + return 0; +} + + +void uv__process_title_cleanup(void) { + uv__free(args_mem); /* Keep valgrind happy. */ + args_mem = NULL; +} diff --git a/external/src/libuv/src/unix/pthread-fixes.c b/external/src/libuv/src/unix/pthread-fixes.c new file mode 100644 index 0000000..022d79c --- /dev/null +++ b/external/src/libuv/src/unix/pthread-fixes.c @@ -0,0 +1,58 @@ +/* Copyright (c) 2013, Sony Mobile Communications AB + * Copyright (c) 2012, Google Inc. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following disclaimer + in the documentation and/or other materials provided with the + distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* Android versions < 4.1 have a broken pthread_sigmask. */ +#include "uv-common.h" + +#include +#include +#include + +int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset) { + static int workaround; + int err; + + if (uv__load_relaxed(&workaround)) { + return sigprocmask(how, set, oset); + } else { + err = pthread_sigmask(how, set, oset); + if (err) { + if (err == EINVAL && sigprocmask(how, set, oset) == 0) { + uv__store_relaxed(&workaround, 1); + return 0; + } else { + return -1; + } + } + } + + return 0; +} diff --git a/external/src/libuv/src/unix/qnx.c b/external/src/libuv/src/unix/qnx.c new file mode 100644 index 0000000..ca148d3 --- /dev/null +++ b/external/src/libuv/src/unix/qnx.c @@ -0,0 +1,137 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include +#include + +static void +get_mem_info(uint64_t* totalmem, uint64_t* freemem) { + mem_info_t msg; + + memset(&msg, 0, sizeof(msg)); + msg.i.type = _MEM_INFO; + msg.i.fd = -1; + + if (MsgSend(MEMMGR_COID, &msg.i, sizeof(msg.i), &msg.o, sizeof(msg.o)) + != -1) { + *totalmem = msg.o.info.__posix_tmi_total; + *freemem = msg.o.info.posix_tmi_length; + } else { + *totalmem = 0; + *freemem = 0; + } +} + + +void uv_loadavg(double avg[3]) { + avg[0] = 0.0; + avg[1] = 0.0; + avg[2] = 0.0; +} + + +int uv_exepath(char* buffer, size_t* size) { + char path[PATH_MAX]; + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + realpath(_cmdname(NULL), path); + strlcpy(buffer, path, *size); + *size = strlen(buffer); + return 0; +} + + +uint64_t uv_get_free_memory(void) { + uint64_t totalmem; + uint64_t freemem; + get_mem_info(&totalmem, &freemem); + return freemem; +} + + +uint64_t uv_get_total_memory(void) { + uint64_t totalmem; + uint64_t freemem; + get_mem_info(&totalmem, &freemem); + return totalmem; +} + + +uint64_t uv_get_constrained_memory(void) { + return 0; +} + + +int uv_resident_set_memory(size_t* rss) { + int fd; + procfs_asinfo asinfo; + + fd = uv__open_cloexec("/proc/self/ctl", O_RDONLY); + if (fd == -1) + return UV__ERR(errno); + + if (devctl(fd, DCMD_PROC_ASINFO, &asinfo, sizeof(asinfo), 0) == -1) { + uv__close(fd); + return UV__ERR(errno); + } + + uv__close(fd); + *rss = asinfo.rss; + return 0; +} + + +int uv_uptime(double* uptime) { + struct qtime_entry* qtime = _SYSPAGE_ENTRY(_syspage_ptr, qtime); + *uptime = (qtime->nsec / 1000000000.0); + return 0; +} + + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + struct cpuinfo_entry* cpuinfo = + (struct cpuinfo_entry*)_SYSPAGE_ENTRY(_syspage_ptr, new_cpuinfo); + size_t cpuinfo_size = _SYSPAGE_ELEMENT_SIZE(_syspage_ptr, cpuinfo); + struct strings_entry* strings = _SYSPAGE_ENTRY(_syspage_ptr, strings); + int num_cpus = _syspage_ptr->num_cpu; + int i; + + *count = num_cpus; + *cpu_infos = uv__malloc(num_cpus * sizeof(**cpu_infos)); + if (*cpu_infos == NULL) + return UV_ENOMEM; + + for (i = 0; i < num_cpus; i++) { + (*cpu_infos)[i].model = strdup(&strings->data[cpuinfo->name]); + (*cpu_infos)[i].speed = cpuinfo->speed; + SYSPAGE_ARRAY_ADJ_OFFSET(cpuinfo, cpuinfo, cpuinfo_size); + } + + return 0; +} diff --git a/external/src/libuv/src/unix/random-devurandom.c b/external/src/libuv/src/unix/random-devurandom.c new file mode 100644 index 0000000..05e52a5 --- /dev/null +++ b/external/src/libuv/src/unix/random-devurandom.c @@ -0,0 +1,93 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +static uv_once_t once = UV_ONCE_INIT; +static int status; + + +int uv__random_readpath(const char* path, void* buf, size_t buflen) { + struct stat s; + size_t pos; + ssize_t n; + int fd; + + fd = uv__open_cloexec(path, O_RDONLY); + + if (fd < 0) + return fd; + + if (fstat(fd, &s)) { + uv__close(fd); + return UV__ERR(errno); + } + + if (!S_ISCHR(s.st_mode)) { + uv__close(fd); + return UV_EIO; + } + + for (pos = 0; pos != buflen; pos += n) { + do + n = read(fd, (char*) buf + pos, buflen - pos); + while (n == -1 && errno == EINTR); + + if (n == -1) { + uv__close(fd); + return UV__ERR(errno); + } + + if (n == 0) { + uv__close(fd); + return UV_EIO; + } + } + + uv__close(fd); + return 0; +} + + +static void uv__random_devurandom_init(void) { + char c; + + /* Linux's random(4) man page suggests applications should read at least + * once from /dev/random before switching to /dev/urandom in order to seed + * the system RNG. Reads from /dev/random can of course block indefinitely + * until entropy is available but that's the point. + */ + status = uv__random_readpath("/dev/random", &c, 1); +} + + +int uv__random_devurandom(void* buf, size_t buflen) { + uv_once(&once, uv__random_devurandom_init); + + if (status != 0) + return status; + + return uv__random_readpath("/dev/urandom", buf, buflen); +} diff --git a/external/src/libuv/src/unix/random-getentropy.c b/external/src/libuv/src/unix/random-getentropy.c new file mode 100644 index 0000000..c45d9fd --- /dev/null +++ b/external/src/libuv/src/unix/random-getentropy.c @@ -0,0 +1,57 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +typedef int (*uv__getentropy_cb)(void *, size_t); + +static uv__getentropy_cb uv__getentropy; +static uv_once_t once = UV_ONCE_INIT; + + +static void uv__random_getentropy_init(void) { + uv__getentropy = (uv__getentropy_cb) dlsym(RTLD_DEFAULT, "getentropy"); +} + + +int uv__random_getentropy(void* buf, size_t buflen) { + size_t pos; + size_t stride; + + uv_once(&once, uv__random_getentropy_init); + + if (uv__getentropy == NULL) + return UV_ENOSYS; + + /* getentropy() returns an error for requests > 256 bytes. */ + for (pos = 0, stride = 256; pos + stride < buflen; pos += stride) + if (uv__getentropy((char *) buf + pos, stride)) + return UV__ERR(errno); + + if (uv__getentropy((char *) buf + pos, buflen - pos)) + return UV__ERR(errno); + + return 0; +} diff --git a/external/src/libuv/src/unix/random-getrandom.c b/external/src/libuv/src/unix/random-getrandom.c new file mode 100644 index 0000000..bcc9408 --- /dev/null +++ b/external/src/libuv/src/unix/random-getrandom.c @@ -0,0 +1,88 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#ifdef __linux__ + +#include "linux-syscalls.h" + +#define uv__random_getrandom_init() 0 + +#else /* !__linux__ */ + +#include +#include + +typedef ssize_t (*uv__getrandom_cb)(void *, size_t, unsigned); + +static uv__getrandom_cb uv__getrandom; +static uv_once_t once = UV_ONCE_INIT; + +static void uv__random_getrandom_init_once(void) { + uv__getrandom = (uv__getrandom_cb) dlsym(RTLD_DEFAULT, "getrandom"); +} + +static int uv__random_getrandom_init(void) { + uv_once(&once, uv__random_getrandom_init_once); + + if (uv__getrandom == NULL) + return UV_ENOSYS; + + return 0; +} + +#endif /* !__linux__ */ + +int uv__random_getrandom(void* buf, size_t buflen) { + ssize_t n; + size_t pos; + int rc; + + rc = uv__random_getrandom_init(); + if (rc != 0) + return rc; + + for (pos = 0; pos != buflen; pos += n) { + do { + n = buflen - pos; + + /* Most getrandom() implementations promise that reads <= 256 bytes + * will always succeed and won't be interrupted by signals. + * It's therefore useful to split it up in smaller reads because + * one big read may, in theory, continuously fail with EINTR. + */ + if (n > 256) + n = 256; + + n = uv__getrandom((char *) buf + pos, n, 0); + } while (n == -1 && errno == EINTR); + + if (n == -1) + return UV__ERR(errno); + + if (n == 0) + return UV_EIO; + } + + return 0; +} diff --git a/external/src/libuv/src/unix/random-sysctl-linux.c b/external/src/libuv/src/unix/random-sysctl-linux.c new file mode 100644 index 0000000..66ba8d7 --- /dev/null +++ b/external/src/libuv/src/unix/random-sysctl-linux.c @@ -0,0 +1,99 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +#include +#include + + +struct uv__sysctl_args { + int* name; + int nlen; + void* oldval; + size_t* oldlenp; + void* newval; + size_t newlen; + unsigned long unused[4]; +}; + + +int uv__random_sysctl(void* buf, size_t buflen) { + static int name[] = {1 /*CTL_KERN*/, 40 /*KERN_RANDOM*/, 6 /*RANDOM_UUID*/}; + struct uv__sysctl_args args; + char uuid[16]; + char* p; + char* pe; + size_t n; + + p = buf; + pe = p + buflen; + + while (p < pe) { + memset(&args, 0, sizeof(args)); + + args.name = name; + args.nlen = ARRAY_SIZE(name); + args.oldval = uuid; + args.oldlenp = &n; + n = sizeof(uuid); + + /* Emits a deprecation warning with some kernels but that seems like + * an okay trade-off for the fallback of the fallback: this function is + * only called when neither getrandom(2) nor /dev/urandom are available. + * Fails with ENOSYS on kernels configured without CONFIG_SYSCTL_SYSCALL. + * At least arm64 never had a _sysctl system call and therefore doesn't + * have a SYS__sysctl define either. + */ +#ifdef SYS__sysctl + if (syscall(SYS__sysctl, &args) == -1) + return UV__ERR(errno); +#else + { + (void) &args; + return UV_ENOSYS; + } +#endif + + if (n != sizeof(uuid)) + return UV_EIO; /* Can't happen. */ + + /* uuid[] is now a type 4 UUID. Bytes 6 and 8 (counting from zero) contain + * 4 and 5 bits of entropy, respectively. For ease of use, we skip those + * and only use 14 of the 16 bytes. + */ + uuid[6] = uuid[14]; + uuid[8] = uuid[15]; + + n = pe - p; + if (n > 14) + n = 14; + + memcpy(p, uuid, n); + p += n; + } + + return 0; +} diff --git a/external/src/libuv/src/unix/signal.c b/external/src/libuv/src/unix/signal.c new file mode 100644 index 0000000..1133c73 --- /dev/null +++ b/external/src/libuv/src/unix/signal.c @@ -0,0 +1,558 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include +#include + +#ifndef SA_RESTART +# define SA_RESTART 0 +#endif + +typedef struct { + uv_signal_t* handle; + int signum; +} uv__signal_msg_t; + +RB_HEAD(uv__signal_tree_s, uv_signal_s); + + +static int uv__signal_unlock(void); +static int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot); +static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events); +static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2); +static void uv__signal_stop(uv_signal_t* handle); +static void uv__signal_unregister_handler(int signum); + + +static uv_once_t uv__signal_global_init_guard = UV_ONCE_INIT; +static struct uv__signal_tree_s uv__signal_tree = + RB_INITIALIZER(uv__signal_tree); +static int uv__signal_lock_pipefd[2] = { -1, -1 }; + +RB_GENERATE_STATIC(uv__signal_tree_s, + uv_signal_s, tree_entry, + uv__signal_compare) + +static void uv__signal_global_reinit(void); + +static void uv__signal_global_init(void) { + if (uv__signal_lock_pipefd[0] == -1) + /* pthread_atfork can register before and after handlers, one + * for each child. This only registers one for the child. That + * state is both persistent and cumulative, so if we keep doing + * it the handler functions will be called multiple times. Thus + * we only want to do it once. + */ + if (pthread_atfork(NULL, NULL, &uv__signal_global_reinit)) + abort(); + + uv__signal_global_reinit(); +} + + +void uv__signal_cleanup(void) { + /* We can only use signal-safe functions here. + * That includes read/write and close, fortunately. + * We do all of this directly here instead of resetting + * uv__signal_global_init_guard because + * uv__signal_global_once_init is only called from uv_loop_init + * and this needs to function in existing loops. + */ + if (uv__signal_lock_pipefd[0] != -1) { + uv__close(uv__signal_lock_pipefd[0]); + uv__signal_lock_pipefd[0] = -1; + } + + if (uv__signal_lock_pipefd[1] != -1) { + uv__close(uv__signal_lock_pipefd[1]); + uv__signal_lock_pipefd[1] = -1; + } +} + + +static void uv__signal_global_reinit(void) { + uv__signal_cleanup(); + + if (uv__make_pipe(uv__signal_lock_pipefd, 0)) + abort(); + + if (uv__signal_unlock()) + abort(); +} + + +void uv__signal_global_once_init(void) { + uv_once(&uv__signal_global_init_guard, uv__signal_global_init); +} + + +static int uv__signal_lock(void) { + int r; + char data; + + do { + r = read(uv__signal_lock_pipefd[0], &data, sizeof data); + } while (r < 0 && errno == EINTR); + + return (r < 0) ? -1 : 0; +} + + +static int uv__signal_unlock(void) { + int r; + char data = 42; + + do { + r = write(uv__signal_lock_pipefd[1], &data, sizeof data); + } while (r < 0 && errno == EINTR); + + return (r < 0) ? -1 : 0; +} + + +static void uv__signal_block_and_lock(sigset_t* saved_sigmask) { + sigset_t new_mask; + + if (sigfillset(&new_mask)) + abort(); + + /* to shut up valgrind */ + sigemptyset(saved_sigmask); + if (pthread_sigmask(SIG_SETMASK, &new_mask, saved_sigmask)) + abort(); + + if (uv__signal_lock()) + abort(); +} + + +static void uv__signal_unlock_and_unblock(sigset_t* saved_sigmask) { + if (uv__signal_unlock()) + abort(); + + if (pthread_sigmask(SIG_SETMASK, saved_sigmask, NULL)) + abort(); +} + + +static uv_signal_t* uv__signal_first_handle(int signum) { + /* This function must be called with the signal lock held. */ + uv_signal_t lookup; + uv_signal_t* handle; + + lookup.signum = signum; + lookup.flags = 0; + lookup.loop = NULL; + + handle = RB_NFIND(uv__signal_tree_s, &uv__signal_tree, &lookup); + + if (handle != NULL && handle->signum == signum) + return handle; + + return NULL; +} + + +static void uv__signal_handler(int signum) { + uv__signal_msg_t msg; + uv_signal_t* handle; + int saved_errno; + + saved_errno = errno; + memset(&msg, 0, sizeof msg); + + if (uv__signal_lock()) { + errno = saved_errno; + return; + } + + for (handle = uv__signal_first_handle(signum); + handle != NULL && handle->signum == signum; + handle = RB_NEXT(uv__signal_tree_s, &uv__signal_tree, handle)) { + int r; + + msg.signum = signum; + msg.handle = handle; + + /* write() should be atomic for small data chunks, so the entire message + * should be written at once. In theory the pipe could become full, in + * which case the user is out of luck. + */ + do { + r = write(handle->loop->signal_pipefd[1], &msg, sizeof msg); + } while (r == -1 && errno == EINTR); + + assert(r == sizeof msg || + (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK))); + + if (r != -1) + handle->caught_signals++; + } + + uv__signal_unlock(); + errno = saved_errno; +} + + +static int uv__signal_register_handler(int signum, int oneshot) { + /* When this function is called, the signal lock must be held. */ + struct sigaction sa; + + /* XXX use a separate signal stack? */ + memset(&sa, 0, sizeof(sa)); + if (sigfillset(&sa.sa_mask)) + abort(); + sa.sa_handler = uv__signal_handler; + sa.sa_flags = SA_RESTART; + if (oneshot) + sa.sa_flags |= SA_RESETHAND; + + /* XXX save old action so we can restore it later on? */ + if (sigaction(signum, &sa, NULL)) + return UV__ERR(errno); + + return 0; +} + + +static void uv__signal_unregister_handler(int signum) { + /* When this function is called, the signal lock must be held. */ + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_DFL; + + /* sigaction can only fail with EINVAL or EFAULT; an attempt to deregister a + * signal implies that it was successfully registered earlier, so EINVAL + * should never happen. + */ + if (sigaction(signum, &sa, NULL)) + abort(); +} + + +static int uv__signal_loop_once_init(uv_loop_t* loop) { + int err; + + /* Return if already initialized. */ + if (loop->signal_pipefd[0] != -1) + return 0; + + err = uv__make_pipe(loop->signal_pipefd, UV_NONBLOCK_PIPE); + if (err) + return err; + + uv__io_init(&loop->signal_io_watcher, + uv__signal_event, + loop->signal_pipefd[0]); + uv__io_start(loop, &loop->signal_io_watcher, POLLIN); + + return 0; +} + + +int uv__signal_loop_fork(uv_loop_t* loop) { + uv__io_stop(loop, &loop->signal_io_watcher, POLLIN); + uv__close(loop->signal_pipefd[0]); + uv__close(loop->signal_pipefd[1]); + loop->signal_pipefd[0] = -1; + loop->signal_pipefd[1] = -1; + return uv__signal_loop_once_init(loop); +} + + +void uv__signal_loop_cleanup(uv_loop_t* loop) { + QUEUE* q; + + /* Stop all the signal watchers that are still attached to this loop. This + * ensures that the (shared) signal tree doesn't contain any invalid entries + * entries, and that signal handlers are removed when appropriate. + * It's safe to use QUEUE_FOREACH here because the handles and the handle + * queue are not modified by uv__signal_stop(). + */ + QUEUE_FOREACH(q, &loop->handle_queue) { + uv_handle_t* handle = QUEUE_DATA(q, uv_handle_t, handle_queue); + + if (handle->type == UV_SIGNAL) + uv__signal_stop((uv_signal_t*) handle); + } + + if (loop->signal_pipefd[0] != -1) { + uv__close(loop->signal_pipefd[0]); + loop->signal_pipefd[0] = -1; + } + + if (loop->signal_pipefd[1] != -1) { + uv__close(loop->signal_pipefd[1]); + loop->signal_pipefd[1] = -1; + } +} + + +int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) { + int err; + + err = uv__signal_loop_once_init(loop); + if (err) + return err; + + uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL); + handle->signum = 0; + handle->caught_signals = 0; + handle->dispatched_signals = 0; + + return 0; +} + + +void uv__signal_close(uv_signal_t* handle) { + uv__signal_stop(handle); +} + + +int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { + return uv__signal_start(handle, signal_cb, signum, 0); +} + + +int uv_signal_start_oneshot(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum) { + return uv__signal_start(handle, signal_cb, signum, 1); +} + + +static int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot) { + sigset_t saved_sigmask; + int err; + uv_signal_t* first_handle; + + assert(!uv__is_closing(handle)); + + /* If the user supplies signum == 0, then return an error already. If the + * signum is otherwise invalid then uv__signal_register will find out + * eventually. + */ + if (signum == 0) + return UV_EINVAL; + + /* Short circuit: if the signal watcher is already watching {signum} don't + * go through the process of deregistering and registering the handler. + * Additionally, this avoids pending signals getting lost in the small + * time frame that handle->signum == 0. + */ + if (signum == handle->signum) { + handle->signal_cb = signal_cb; + return 0; + } + + /* If the signal handler was already active, stop it first. */ + if (handle->signum != 0) { + uv__signal_stop(handle); + } + + uv__signal_block_and_lock(&saved_sigmask); + + /* If at this point there are no active signal watchers for this signum (in + * any of the loops), it's time to try and register a handler for it here. + * Also in case there's only one-shot handlers and a regular handler comes in. + */ + first_handle = uv__signal_first_handle(signum); + if (first_handle == NULL || + (!oneshot && (first_handle->flags & UV_SIGNAL_ONE_SHOT))) { + err = uv__signal_register_handler(signum, oneshot); + if (err) { + /* Registering the signal handler failed. Must be an invalid signal. */ + uv__signal_unlock_and_unblock(&saved_sigmask); + return err; + } + } + + handle->signum = signum; + if (oneshot) + handle->flags |= UV_SIGNAL_ONE_SHOT; + + RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle); + + uv__signal_unlock_and_unblock(&saved_sigmask); + + handle->signal_cb = signal_cb; + uv__handle_start(handle); + + return 0; +} + + +static void uv__signal_event(uv_loop_t* loop, + uv__io_t* w, + unsigned int events) { + uv__signal_msg_t* msg; + uv_signal_t* handle; + char buf[sizeof(uv__signal_msg_t) * 32]; + size_t bytes, end, i; + int r; + + bytes = 0; + end = 0; + + do { + r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes); + + if (r == -1 && errno == EINTR) + continue; + + if (r == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) { + /* If there are bytes in the buffer already (which really is extremely + * unlikely if possible at all) we can't exit the function here. We'll + * spin until more bytes are read instead. + */ + if (bytes > 0) + continue; + + /* Otherwise, there was nothing there. */ + return; + } + + /* Other errors really should never happen. */ + if (r == -1) + abort(); + + bytes += r; + + /* `end` is rounded down to a multiple of sizeof(uv__signal_msg_t). */ + end = (bytes / sizeof(uv__signal_msg_t)) * sizeof(uv__signal_msg_t); + + for (i = 0; i < end; i += sizeof(uv__signal_msg_t)) { + msg = (uv__signal_msg_t*) (buf + i); + handle = msg->handle; + + if (msg->signum == handle->signum) { + assert(!(handle->flags & UV_HANDLE_CLOSING)); + handle->signal_cb(handle, handle->signum); + } + + handle->dispatched_signals++; + + if (handle->flags & UV_SIGNAL_ONE_SHOT) + uv__signal_stop(handle); + } + + bytes -= end; + + /* If there are any "partial" messages left, move them to the start of the + * the buffer, and spin. This should not happen. + */ + if (bytes) { + memmove(buf, buf + end, bytes); + continue; + } + } while (end == sizeof buf); +} + + +static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) { + int f1; + int f2; + /* Compare signums first so all watchers with the same signnum end up + * adjacent. + */ + if (w1->signum < w2->signum) return -1; + if (w1->signum > w2->signum) return 1; + + /* Handlers without UV_SIGNAL_ONE_SHOT set will come first, so if the first + * handler returned is a one-shot handler, the rest will be too. + */ + f1 = w1->flags & UV_SIGNAL_ONE_SHOT; + f2 = w2->flags & UV_SIGNAL_ONE_SHOT; + if (f1 < f2) return -1; + if (f1 > f2) return 1; + + /* Sort by loop pointer, so we can easily look up the first item after + * { .signum = x, .loop = NULL }. + */ + if (w1->loop < w2->loop) return -1; + if (w1->loop > w2->loop) return 1; + + if (w1 < w2) return -1; + if (w1 > w2) return 1; + + return 0; +} + + +int uv_signal_stop(uv_signal_t* handle) { + assert(!uv__is_closing(handle)); + uv__signal_stop(handle); + return 0; +} + + +static void uv__signal_stop(uv_signal_t* handle) { + uv_signal_t* removed_handle; + sigset_t saved_sigmask; + uv_signal_t* first_handle; + int rem_oneshot; + int first_oneshot; + int ret; + + /* If the watcher wasn't started, this is a no-op. */ + if (handle->signum == 0) + return; + + uv__signal_block_and_lock(&saved_sigmask); + + removed_handle = RB_REMOVE(uv__signal_tree_s, &uv__signal_tree, handle); + assert(removed_handle == handle); + (void) removed_handle; + + /* Check if there are other active signal watchers observing this signal. If + * not, unregister the signal handler. + */ + first_handle = uv__signal_first_handle(handle->signum); + if (first_handle == NULL) { + uv__signal_unregister_handler(handle->signum); + } else { + rem_oneshot = handle->flags & UV_SIGNAL_ONE_SHOT; + first_oneshot = first_handle->flags & UV_SIGNAL_ONE_SHOT; + if (first_oneshot && !rem_oneshot) { + ret = uv__signal_register_handler(handle->signum, 1); + assert(ret == 0); + (void)ret; + } + } + + uv__signal_unlock_and_unblock(&saved_sigmask); + + handle->signum = 0; + uv__handle_stop(handle); +} diff --git a/external/src/libuv/src/unix/spinlock.h b/external/src/libuv/src/unix/spinlock.h new file mode 100644 index 0000000..a20c83c --- /dev/null +++ b/external/src/libuv/src/unix/spinlock.h @@ -0,0 +1,53 @@ +/* Copyright (c) 2013, Ben Noordhuis + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef UV_SPINLOCK_H_ +#define UV_SPINLOCK_H_ + +#include "internal.h" /* ACCESS_ONCE, UV_UNUSED */ +#include "atomic-ops.h" + +#define UV_SPINLOCK_INITIALIZER { 0 } + +typedef struct { + int lock; +} uv_spinlock_t; + +UV_UNUSED(static void uv_spinlock_init(uv_spinlock_t* spinlock)); +UV_UNUSED(static void uv_spinlock_lock(uv_spinlock_t* spinlock)); +UV_UNUSED(static void uv_spinlock_unlock(uv_spinlock_t* spinlock)); +UV_UNUSED(static int uv_spinlock_trylock(uv_spinlock_t* spinlock)); + +UV_UNUSED(static void uv_spinlock_init(uv_spinlock_t* spinlock)) { + ACCESS_ONCE(int, spinlock->lock) = 0; +} + +UV_UNUSED(static void uv_spinlock_lock(uv_spinlock_t* spinlock)) { + while (!uv_spinlock_trylock(spinlock)) cpu_relax(); +} + +UV_UNUSED(static void uv_spinlock_unlock(uv_spinlock_t* spinlock)) { + ACCESS_ONCE(int, spinlock->lock) = 0; +} + +UV_UNUSED(static int uv_spinlock_trylock(uv_spinlock_t* spinlock)) { + /* TODO(bnoordhuis) Maybe change to a ticket lock to guarantee fair queueing. + * Not really critical until we have locks that are (frequently) contended + * for by several threads. + */ + return 0 == cmpxchgi(&spinlock->lock, 0, 1); +} + +#endif /* UV_SPINLOCK_H_ */ diff --git a/external/src/libuv/src/unix/stream.c b/external/src/libuv/src/unix/stream.c new file mode 100644 index 0000000..bc64fe8 --- /dev/null +++ b/external/src/libuv/src/unix/stream.c @@ -0,0 +1,1678 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include /* IOV_MAX */ + +#if defined(__APPLE__) +# include +# include +# include + +/* Forward declaration */ +typedef struct uv__stream_select_s uv__stream_select_t; + +struct uv__stream_select_s { + uv_stream_t* stream; + uv_thread_t thread; + uv_sem_t close_sem; + uv_sem_t async_sem; + uv_async_t async; + int events; + int fake_fd; + int int_fd; + int fd; + fd_set* sread; + size_t sread_sz; + fd_set* swrite; + size_t swrite_sz; +}; + +/* Due to a possible kernel bug at least in OS X 10.10 "Yosemite", + * EPROTOTYPE can be returned while trying to write to a socket that is + * shutting down. If we retry the write, we should get the expected EPIPE + * instead. + */ +# define RETRY_ON_WRITE_ERROR(errno) (errno == EINTR || errno == EPROTOTYPE) +# define IS_TRANSIENT_WRITE_ERROR(errno, send_handle) \ + (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || \ + (errno == EMSGSIZE && send_handle != NULL)) +#else +# define RETRY_ON_WRITE_ERROR(errno) (errno == EINTR) +# define IS_TRANSIENT_WRITE_ERROR(errno, send_handle) \ + (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS) +#endif /* defined(__APPLE__) */ + +static void uv__stream_connect(uv_stream_t*); +static void uv__write(uv_stream_t* stream); +static void uv__read(uv_stream_t* stream); +static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events); +static void uv__write_callbacks(uv_stream_t* stream); +static size_t uv__write_req_size(uv_write_t* req); + + +void uv__stream_init(uv_loop_t* loop, + uv_stream_t* stream, + uv_handle_type type) { + int err; + + uv__handle_init(loop, (uv_handle_t*)stream, type); + stream->read_cb = NULL; + stream->alloc_cb = NULL; + stream->close_cb = NULL; + stream->connection_cb = NULL; + stream->connect_req = NULL; + stream->shutdown_req = NULL; + stream->accepted_fd = -1; + stream->queued_fds = NULL; + stream->delayed_error = 0; + QUEUE_INIT(&stream->write_queue); + QUEUE_INIT(&stream->write_completed_queue); + stream->write_queue_size = 0; + + if (loop->emfile_fd == -1) { + err = uv__open_cloexec("/dev/null", O_RDONLY); + if (err < 0) + /* In the rare case that "/dev/null" isn't mounted open "/" + * instead. + */ + err = uv__open_cloexec("/", O_RDONLY); + if (err >= 0) + loop->emfile_fd = err; + } + +#if defined(__APPLE__) + stream->select = NULL; +#endif /* defined(__APPLE_) */ + + uv__io_init(&stream->io_watcher, uv__stream_io, -1); +} + + +static void uv__stream_osx_interrupt_select(uv_stream_t* stream) { +#if defined(__APPLE__) + /* Notify select() thread about state change */ + uv__stream_select_t* s; + int r; + + s = stream->select; + if (s == NULL) + return; + + /* Interrupt select() loop + * NOTE: fake_fd and int_fd are socketpair(), thus writing to one will + * emit read event on other side + */ + do + r = write(s->fake_fd, "x", 1); + while (r == -1 && errno == EINTR); + + assert(r == 1); +#else /* !defined(__APPLE__) */ + /* No-op on any other platform */ +#endif /* !defined(__APPLE__) */ +} + + +#if defined(__APPLE__) +static void uv__stream_osx_select(void* arg) { + uv_stream_t* stream; + uv__stream_select_t* s; + char buf[1024]; + int events; + int fd; + int r; + int max_fd; + + stream = arg; + s = stream->select; + fd = s->fd; + + if (fd > s->int_fd) + max_fd = fd; + else + max_fd = s->int_fd; + + for (;;) { + /* Terminate on semaphore */ + if (uv_sem_trywait(&s->close_sem) == 0) + break; + + /* Watch fd using select(2) */ + memset(s->sread, 0, s->sread_sz); + memset(s->swrite, 0, s->swrite_sz); + + if (uv__io_active(&stream->io_watcher, POLLIN)) + FD_SET(fd, s->sread); + if (uv__io_active(&stream->io_watcher, POLLOUT)) + FD_SET(fd, s->swrite); + FD_SET(s->int_fd, s->sread); + + /* Wait indefinitely for fd events */ + r = select(max_fd + 1, s->sread, s->swrite, NULL, NULL); + if (r == -1) { + if (errno == EINTR) + continue; + + /* XXX: Possible?! */ + abort(); + } + + /* Ignore timeouts */ + if (r == 0) + continue; + + /* Empty socketpair's buffer in case of interruption */ + if (FD_ISSET(s->int_fd, s->sread)) + for (;;) { + r = read(s->int_fd, buf, sizeof(buf)); + + if (r == sizeof(buf)) + continue; + + if (r != -1) + break; + + if (errno == EAGAIN || errno == EWOULDBLOCK) + break; + + if (errno == EINTR) + continue; + + abort(); + } + + /* Handle events */ + events = 0; + if (FD_ISSET(fd, s->sread)) + events |= POLLIN; + if (FD_ISSET(fd, s->swrite)) + events |= POLLOUT; + + assert(events != 0 || FD_ISSET(s->int_fd, s->sread)); + if (events != 0) { + ACCESS_ONCE(int, s->events) = events; + + uv_async_send(&s->async); + uv_sem_wait(&s->async_sem); + + /* Should be processed at this stage */ + assert((s->events == 0) || (stream->flags & UV_HANDLE_CLOSING)); + } + } +} + + +static void uv__stream_osx_select_cb(uv_async_t* handle) { + uv__stream_select_t* s; + uv_stream_t* stream; + int events; + + s = container_of(handle, uv__stream_select_t, async); + stream = s->stream; + + /* Get and reset stream's events */ + events = s->events; + ACCESS_ONCE(int, s->events) = 0; + + assert(events != 0); + assert(events == (events & (POLLIN | POLLOUT))); + + /* Invoke callback on event-loop */ + if ((events & POLLIN) && uv__io_active(&stream->io_watcher, POLLIN)) + uv__stream_io(stream->loop, &stream->io_watcher, POLLIN); + + if ((events & POLLOUT) && uv__io_active(&stream->io_watcher, POLLOUT)) + uv__stream_io(stream->loop, &stream->io_watcher, POLLOUT); + + if (stream->flags & UV_HANDLE_CLOSING) + return; + + /* NOTE: It is important to do it here, otherwise `select()` might be called + * before the actual `uv__read()`, leading to the blocking syscall + */ + uv_sem_post(&s->async_sem); +} + + +static void uv__stream_osx_cb_close(uv_handle_t* async) { + uv__stream_select_t* s; + + s = container_of(async, uv__stream_select_t, async); + uv__free(s); +} + + +int uv__stream_try_select(uv_stream_t* stream, int* fd) { + /* + * kqueue doesn't work with some files from /dev mount on osx. + * select(2) in separate thread for those fds + */ + + struct kevent filter[1]; + struct kevent events[1]; + struct timespec timeout; + uv__stream_select_t* s; + int fds[2]; + int err; + int ret; + int kq; + int old_fd; + int max_fd; + size_t sread_sz; + size_t swrite_sz; + + kq = kqueue(); + if (kq == -1) { + perror("(libuv) kqueue()"); + return UV__ERR(errno); + } + + EV_SET(&filter[0], *fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0); + + /* Use small timeout, because we only want to capture EINVALs */ + timeout.tv_sec = 0; + timeout.tv_nsec = 1; + + do + ret = kevent(kq, filter, 1, events, 1, &timeout); + while (ret == -1 && errno == EINTR); + + uv__close(kq); + + if (ret == -1) + return UV__ERR(errno); + + if (ret == 0 || (events[0].flags & EV_ERROR) == 0 || events[0].data != EINVAL) + return 0; + + /* At this point we definitely know that this fd won't work with kqueue */ + + /* + * Create fds for io watcher and to interrupt the select() loop. + * NOTE: do it ahead of malloc below to allocate enough space for fd_sets + */ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds)) + return UV__ERR(errno); + + max_fd = *fd; + if (fds[1] > max_fd) + max_fd = fds[1]; + + sread_sz = ROUND_UP(max_fd + 1, sizeof(uint32_t) * NBBY) / NBBY; + swrite_sz = sread_sz; + + s = uv__malloc(sizeof(*s) + sread_sz + swrite_sz); + if (s == NULL) { + err = UV_ENOMEM; + goto failed_malloc; + } + + s->events = 0; + s->fd = *fd; + s->sread = (fd_set*) ((char*) s + sizeof(*s)); + s->sread_sz = sread_sz; + s->swrite = (fd_set*) ((char*) s->sread + sread_sz); + s->swrite_sz = swrite_sz; + + err = uv_async_init(stream->loop, &s->async, uv__stream_osx_select_cb); + if (err) + goto failed_async_init; + + s->async.flags |= UV_HANDLE_INTERNAL; + uv__handle_unref(&s->async); + + err = uv_sem_init(&s->close_sem, 0); + if (err != 0) + goto failed_close_sem_init; + + err = uv_sem_init(&s->async_sem, 0); + if (err != 0) + goto failed_async_sem_init; + + s->fake_fd = fds[0]; + s->int_fd = fds[1]; + + old_fd = *fd; + s->stream = stream; + stream->select = s; + *fd = s->fake_fd; + + err = uv_thread_create(&s->thread, uv__stream_osx_select, stream); + if (err != 0) + goto failed_thread_create; + + return 0; + +failed_thread_create: + s->stream = NULL; + stream->select = NULL; + *fd = old_fd; + + uv_sem_destroy(&s->async_sem); + +failed_async_sem_init: + uv_sem_destroy(&s->close_sem); + +failed_close_sem_init: + uv__close(fds[0]); + uv__close(fds[1]); + uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close); + return err; + +failed_async_init: + uv__free(s); + +failed_malloc: + uv__close(fds[0]); + uv__close(fds[1]); + + return err; +} +#endif /* defined(__APPLE__) */ + + +int uv__stream_open(uv_stream_t* stream, int fd, int flags) { +#if defined(__APPLE__) + int enable; +#endif + + if (!(stream->io_watcher.fd == -1 || stream->io_watcher.fd == fd)) + return UV_EBUSY; + + assert(fd >= 0); + stream->flags |= flags; + + if (stream->type == UV_TCP) { + if ((stream->flags & UV_HANDLE_TCP_NODELAY) && uv__tcp_nodelay(fd, 1)) + return UV__ERR(errno); + + /* TODO Use delay the user passed in. */ + if ((stream->flags & UV_HANDLE_TCP_KEEPALIVE) && + uv__tcp_keepalive(fd, 1, 60)) { + return UV__ERR(errno); + } + } + +#if defined(__APPLE__) + enable = 1; + if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &enable, sizeof(enable)) && + errno != ENOTSOCK && + errno != EINVAL) { + return UV__ERR(errno); + } +#endif + + stream->io_watcher.fd = fd; + + return 0; +} + + +void uv__stream_flush_write_queue(uv_stream_t* stream, int error) { + uv_write_t* req; + QUEUE* q; + while (!QUEUE_EMPTY(&stream->write_queue)) { + q = QUEUE_HEAD(&stream->write_queue); + QUEUE_REMOVE(q); + + req = QUEUE_DATA(q, uv_write_t, queue); + req->error = error; + + QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue); + } +} + + +void uv__stream_destroy(uv_stream_t* stream) { + assert(!uv__io_active(&stream->io_watcher, POLLIN | POLLOUT)); + assert(stream->flags & UV_HANDLE_CLOSED); + + if (stream->connect_req) { + uv__req_unregister(stream->loop, stream->connect_req); + stream->connect_req->cb(stream->connect_req, UV_ECANCELED); + stream->connect_req = NULL; + } + + uv__stream_flush_write_queue(stream, UV_ECANCELED); + uv__write_callbacks(stream); + + if (stream->shutdown_req) { + /* The ECANCELED error code is a lie, the shutdown(2) syscall is a + * fait accompli at this point. Maybe we should revisit this in v0.11. + * A possible reason for leaving it unchanged is that it informs the + * callee that the handle has been destroyed. + */ + uv__req_unregister(stream->loop, stream->shutdown_req); + stream->shutdown_req->cb(stream->shutdown_req, UV_ECANCELED); + stream->shutdown_req = NULL; + } + + assert(stream->write_queue_size == 0); +} + + +/* Implements a best effort approach to mitigating accept() EMFILE errors. + * We have a spare file descriptor stashed away that we close to get below + * the EMFILE limit. Next, we accept all pending connections and close them + * immediately to signal the clients that we're overloaded - and we are, but + * we still keep on trucking. + * + * There is one caveat: it's not reliable in a multi-threaded environment. + * The file descriptor limit is per process. Our party trick fails if another + * thread opens a file or creates a socket in the time window between us + * calling close() and accept(). + */ +static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) { + int err; + int emfile_fd; + + if (loop->emfile_fd == -1) + return UV_EMFILE; + + uv__close(loop->emfile_fd); + loop->emfile_fd = -1; + + do { + err = uv__accept(accept_fd); + if (err >= 0) + uv__close(err); + } while (err >= 0 || err == UV_EINTR); + + emfile_fd = uv__open_cloexec("/", O_RDONLY); + if (emfile_fd >= 0) + loop->emfile_fd = emfile_fd; + + return err; +} + + +#if defined(UV_HAVE_KQUEUE) +# define UV_DEC_BACKLOG(w) w->rcount--; +#else +# define UV_DEC_BACKLOG(w) /* no-op */ +#endif /* defined(UV_HAVE_KQUEUE) */ + + +void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { + uv_stream_t* stream; + int err; + + stream = container_of(w, uv_stream_t, io_watcher); + assert(events & POLLIN); + assert(stream->accepted_fd == -1); + assert(!(stream->flags & UV_HANDLE_CLOSING)); + + uv__io_start(stream->loop, &stream->io_watcher, POLLIN); + + /* connection_cb can close the server socket while we're + * in the loop so check it on each iteration. + */ + while (uv__stream_fd(stream) != -1) { + assert(stream->accepted_fd == -1); + +#if defined(UV_HAVE_KQUEUE) + if (w->rcount <= 0) + return; +#endif /* defined(UV_HAVE_KQUEUE) */ + + err = uv__accept(uv__stream_fd(stream)); + if (err < 0) { + if (err == UV_EAGAIN || err == UV__ERR(EWOULDBLOCK)) + return; /* Not an error. */ + + if (err == UV_ECONNABORTED) + continue; /* Ignore. Nothing we can do about that. */ + + if (err == UV_EMFILE || err == UV_ENFILE) { + err = uv__emfile_trick(loop, uv__stream_fd(stream)); + if (err == UV_EAGAIN || err == UV__ERR(EWOULDBLOCK)) + break; + } + + stream->connection_cb(stream, err); + continue; + } + + UV_DEC_BACKLOG(w) + stream->accepted_fd = err; + stream->connection_cb(stream, 0); + + if (stream->accepted_fd != -1) { + /* The user hasn't yet accepted called uv_accept() */ + uv__io_stop(loop, &stream->io_watcher, POLLIN); + return; + } + + if (stream->type == UV_TCP && + (stream->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) { + /* Give other processes a chance to accept connections. */ + struct timespec timeout = { 0, 1 }; + nanosleep(&timeout, NULL); + } + } +} + + +#undef UV_DEC_BACKLOG + + +int uv_accept(uv_stream_t* server, uv_stream_t* client) { + int err; + + assert(server->loop == client->loop); + + if (server->accepted_fd == -1) + return UV_EAGAIN; + + switch (client->type) { + case UV_NAMED_PIPE: + case UV_TCP: + err = uv__stream_open(client, + server->accepted_fd, + UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); + if (err) { + /* TODO handle error */ + uv__close(server->accepted_fd); + goto done; + } + break; + + case UV_UDP: + err = uv_udp_open((uv_udp_t*) client, server->accepted_fd); + if (err) { + uv__close(server->accepted_fd); + goto done; + } + break; + + default: + return UV_EINVAL; + } + + client->flags |= UV_HANDLE_BOUND; + +done: + /* Process queued fds */ + if (server->queued_fds != NULL) { + uv__stream_queued_fds_t* queued_fds; + + queued_fds = server->queued_fds; + + /* Read first */ + server->accepted_fd = queued_fds->fds[0]; + + /* All read, free */ + assert(queued_fds->offset > 0); + if (--queued_fds->offset == 0) { + uv__free(queued_fds); + server->queued_fds = NULL; + } else { + /* Shift rest */ + memmove(queued_fds->fds, + queued_fds->fds + 1, + queued_fds->offset * sizeof(*queued_fds->fds)); + } + } else { + server->accepted_fd = -1; + if (err == 0) + uv__io_start(server->loop, &server->io_watcher, POLLIN); + } + return err; +} + + +int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) { + int err; + + switch (stream->type) { + case UV_TCP: + err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb); + break; + + case UV_NAMED_PIPE: + err = uv_pipe_listen((uv_pipe_t*)stream, backlog, cb); + break; + + default: + err = UV_EINVAL; + } + + if (err == 0) + uv__handle_start(stream); + + return err; +} + + +static void uv__drain(uv_stream_t* stream) { + uv_shutdown_t* req; + int err; + + assert(QUEUE_EMPTY(&stream->write_queue)); + uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT); + uv__stream_osx_interrupt_select(stream); + + /* Shutdown? */ + if ((stream->flags & UV_HANDLE_SHUTTING) && + !(stream->flags & UV_HANDLE_CLOSING) && + !(stream->flags & UV_HANDLE_SHUT)) { + assert(stream->shutdown_req); + + req = stream->shutdown_req; + stream->shutdown_req = NULL; + stream->flags &= ~UV_HANDLE_SHUTTING; + uv__req_unregister(stream->loop, req); + + err = 0; + if (shutdown(uv__stream_fd(stream), SHUT_WR)) + err = UV__ERR(errno); + + if (err == 0) + stream->flags |= UV_HANDLE_SHUT; + + if (req->cb != NULL) + req->cb(req, err); + } +} + + +static ssize_t uv__writev(int fd, struct iovec* vec, size_t n) { + if (n == 1) + return write(fd, vec->iov_base, vec->iov_len); + else + return writev(fd, vec, n); +} + + +static size_t uv__write_req_size(uv_write_t* req) { + size_t size; + + assert(req->bufs != NULL); + size = uv__count_bufs(req->bufs + req->write_index, + req->nbufs - req->write_index); + assert(req->handle->write_queue_size >= size); + + return size; +} + + +/* Returns 1 if all write request data has been written, or 0 if there is still + * more data to write. + * + * Note: the return value only says something about the *current* request. + * There may still be other write requests sitting in the queue. + */ +static int uv__write_req_update(uv_stream_t* stream, + uv_write_t* req, + size_t n) { + uv_buf_t* buf; + size_t len; + + assert(n <= stream->write_queue_size); + stream->write_queue_size -= n; + + buf = req->bufs + req->write_index; + + do { + len = n < buf->len ? n : buf->len; + buf->base += len; + buf->len -= len; + buf += (buf->len == 0); /* Advance to next buffer if this one is empty. */ + n -= len; + } while (n > 0); + + req->write_index = buf - req->bufs; + + return req->write_index == req->nbufs; +} + + +static void uv__write_req_finish(uv_write_t* req) { + uv_stream_t* stream = req->handle; + + /* Pop the req off tcp->write_queue. */ + QUEUE_REMOVE(&req->queue); + + /* Only free when there was no error. On error, we touch up write_queue_size + * right before making the callback. The reason we don't do that right away + * is that a write_queue_size > 0 is our only way to signal to the user that + * they should stop writing - which they should if we got an error. Something + * to revisit in future revisions of the libuv API. + */ + if (req->error == 0) { + if (req->bufs != req->bufsml) + uv__free(req->bufs); + req->bufs = NULL; + } + + /* Add it to the write_completed_queue where it will have its + * callback called in the near future. + */ + QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue); + uv__io_feed(stream->loop, &stream->io_watcher); +} + + +static int uv__handle_fd(uv_handle_t* handle) { + switch (handle->type) { + case UV_NAMED_PIPE: + case UV_TCP: + return ((uv_stream_t*) handle)->io_watcher.fd; + + case UV_UDP: + return ((uv_udp_t*) handle)->io_watcher.fd; + + default: + return -1; + } +} + +static int uv__try_write(uv_stream_t* stream, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle) { + struct iovec* iov; + int iovmax; + int iovcnt; + ssize_t n; + + /* + * Cast to iovec. We had to have our own uv_buf_t instead of iovec + * because Windows's WSABUF is not an iovec. + */ + iov = (struct iovec*) bufs; + iovcnt = nbufs; + + iovmax = uv__getiovmax(); + + /* Limit iov count to avoid EINVALs from writev() */ + if (iovcnt > iovmax) + iovcnt = iovmax; + + /* + * Now do the actual writev. Note that we've been updating the pointers + * inside the iov each time we write. So there is no need to offset it. + */ + if (send_handle != NULL) { + int fd_to_send; + struct msghdr msg; + struct cmsghdr *cmsg; + union { + char data[64]; + struct cmsghdr alias; + } scratch; + + if (uv__is_closing(send_handle)) + return UV_EBADF; + + fd_to_send = uv__handle_fd((uv_handle_t*) send_handle); + + memset(&scratch, 0, sizeof(scratch)); + + assert(fd_to_send >= 0); + + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = iov; + msg.msg_iovlen = iovcnt; + msg.msg_flags = 0; + + msg.msg_control = &scratch.alias; + msg.msg_controllen = CMSG_SPACE(sizeof(fd_to_send)); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(fd_to_send)); + + /* silence aliasing warning */ + { + void* pv = CMSG_DATA(cmsg); + int* pi = pv; + *pi = fd_to_send; + } + + do + n = sendmsg(uv__stream_fd(stream), &msg, 0); + while (n == -1 && RETRY_ON_WRITE_ERROR(errno)); + } else { + do + n = uv__writev(uv__stream_fd(stream), iov, iovcnt); + while (n == -1 && RETRY_ON_WRITE_ERROR(errno)); + } + + if (n >= 0) + return n; + + if (IS_TRANSIENT_WRITE_ERROR(errno, send_handle)) + return UV_EAGAIN; + + return UV__ERR(errno); +} + +static void uv__write(uv_stream_t* stream) { + QUEUE* q; + uv_write_t* req; + ssize_t n; + + assert(uv__stream_fd(stream) >= 0); + + for (;;) { + if (QUEUE_EMPTY(&stream->write_queue)) + return; + + q = QUEUE_HEAD(&stream->write_queue); + req = QUEUE_DATA(q, uv_write_t, queue); + assert(req->handle == stream); + + n = uv__try_write(stream, + &(req->bufs[req->write_index]), + req->nbufs - req->write_index, + req->send_handle); + + /* Ensure the handle isn't sent again in case this is a partial write. */ + if (n >= 0) { + req->send_handle = NULL; + if (uv__write_req_update(stream, req, n)) { + uv__write_req_finish(req); + return; /* TODO(bnoordhuis) Start trying to write the next request. */ + } + } else if (n != UV_EAGAIN) + break; + + /* If this is a blocking stream, try again. */ + if (stream->flags & UV_HANDLE_BLOCKING_WRITES) + continue; + + /* We're not done. */ + uv__io_start(stream->loop, &stream->io_watcher, POLLOUT); + + /* Notify select() thread about state change */ + uv__stream_osx_interrupt_select(stream); + + return; + } + + req->error = n; + // XXX(jwn): this must call uv__stream_flush_write_queue(stream, n) here, since we won't generate any more events + uv__write_req_finish(req); + uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT); + uv__stream_osx_interrupt_select(stream); +} + + +static void uv__write_callbacks(uv_stream_t* stream) { + uv_write_t* req; + QUEUE* q; + QUEUE pq; + + if (QUEUE_EMPTY(&stream->write_completed_queue)) + return; + + QUEUE_MOVE(&stream->write_completed_queue, &pq); + + while (!QUEUE_EMPTY(&pq)) { + /* Pop a req off write_completed_queue. */ + q = QUEUE_HEAD(&pq); + req = QUEUE_DATA(q, uv_write_t, queue); + QUEUE_REMOVE(q); + uv__req_unregister(stream->loop, req); + + if (req->bufs != NULL) { + stream->write_queue_size -= uv__write_req_size(req); + if (req->bufs != req->bufsml) + uv__free(req->bufs); + req->bufs = NULL; + } + + /* NOTE: call callback AFTER freeing the request data. */ + if (req->cb) + req->cb(req, req->error); + } +} + + +uv_handle_type uv__handle_type(int fd) { + struct sockaddr_storage ss; + socklen_t sslen; + socklen_t len; + int type; + + memset(&ss, 0, sizeof(ss)); + sslen = sizeof(ss); + + if (getsockname(fd, (struct sockaddr*)&ss, &sslen)) + return UV_UNKNOWN_HANDLE; + + len = sizeof type; + + if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len)) + return UV_UNKNOWN_HANDLE; + + if (type == SOCK_STREAM) { +#if defined(_AIX) || defined(__DragonFly__) + /* on AIX/DragonFly the getsockname call returns an empty sa structure + * for sockets of type AF_UNIX. For all other types it will + * return a properly filled in structure. + */ + if (sslen == 0) + return UV_NAMED_PIPE; +#endif + switch (ss.ss_family) { + case AF_UNIX: + return UV_NAMED_PIPE; + case AF_INET: + case AF_INET6: + return UV_TCP; + } + } + + if (type == SOCK_DGRAM && + (ss.ss_family == AF_INET || ss.ss_family == AF_INET6)) + return UV_UDP; + + return UV_UNKNOWN_HANDLE; +} + + +static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) { + stream->flags |= UV_HANDLE_READ_EOF; + stream->flags &= ~UV_HANDLE_READING; + stream->flags &= ~UV_HANDLE_READABLE; + uv__io_stop(stream->loop, &stream->io_watcher, POLLIN); + uv__handle_stop(stream); + uv__stream_osx_interrupt_select(stream); + stream->read_cb(stream, UV_EOF, buf); +} + + +static int uv__stream_queue_fd(uv_stream_t* stream, int fd) { + uv__stream_queued_fds_t* queued_fds; + unsigned int queue_size; + + queued_fds = stream->queued_fds; + if (queued_fds == NULL) { + queue_size = 8; + queued_fds = uv__malloc((queue_size - 1) * sizeof(*queued_fds->fds) + + sizeof(*queued_fds)); + if (queued_fds == NULL) + return UV_ENOMEM; + queued_fds->size = queue_size; + queued_fds->offset = 0; + stream->queued_fds = queued_fds; + + /* Grow */ + } else if (queued_fds->size == queued_fds->offset) { + queue_size = queued_fds->size + 8; + queued_fds = uv__realloc(queued_fds, + (queue_size - 1) * sizeof(*queued_fds->fds) + + sizeof(*queued_fds)); + + /* + * Allocation failure, report back. + * NOTE: if it is fatal - sockets will be closed in uv__stream_close + */ + if (queued_fds == NULL) + return UV_ENOMEM; + queued_fds->size = queue_size; + stream->queued_fds = queued_fds; + } + + /* Put fd in a queue */ + queued_fds->fds[queued_fds->offset++] = fd; + + return 0; +} + + +#if defined(__PASE__) +/* on IBMi PASE the control message length can not exceed 256. */ +# define UV__CMSG_FD_COUNT 60 +#else +# define UV__CMSG_FD_COUNT 64 +#endif +#define UV__CMSG_FD_SIZE (UV__CMSG_FD_COUNT * sizeof(int)) + + +static int uv__stream_recv_cmsg(uv_stream_t* stream, struct msghdr* msg) { + struct cmsghdr* cmsg; + + for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) { + char* start; + char* end; + int err; + void* pv; + int* pi; + unsigned int i; + unsigned int count; + + if (cmsg->cmsg_type != SCM_RIGHTS) { + fprintf(stderr, "ignoring non-SCM_RIGHTS ancillary data: %d\n", + cmsg->cmsg_type); + continue; + } + + /* silence aliasing warning */ + pv = CMSG_DATA(cmsg); + pi = pv; + + /* Count available fds */ + start = (char*) cmsg; + end = (char*) cmsg + cmsg->cmsg_len; + count = 0; + while (start + CMSG_LEN(count * sizeof(*pi)) < end) + count++; + assert(start + CMSG_LEN(count * sizeof(*pi)) == end); + + for (i = 0; i < count; i++) { + /* Already has accepted fd, queue now */ + if (stream->accepted_fd != -1) { + err = uv__stream_queue_fd(stream, pi[i]); + if (err != 0) { + /* Close rest */ + for (; i < count; i++) + uv__close(pi[i]); + return err; + } + } else { + stream->accepted_fd = pi[i]; + } + } + } + + return 0; +} + + +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wgnu-folding-constant" +# pragma clang diagnostic ignored "-Wvla-extension" +#endif + +static void uv__read(uv_stream_t* stream) { + uv_buf_t buf; + ssize_t nread; + struct msghdr msg; + char cmsg_space[CMSG_SPACE(UV__CMSG_FD_SIZE)]; + int count; + int err; + int is_ipc; + + stream->flags &= ~UV_HANDLE_READ_PARTIAL; + + /* Prevent loop starvation when the data comes in as fast as (or faster than) + * we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O. + */ + count = 32; + + is_ipc = stream->type == UV_NAMED_PIPE && ((uv_pipe_t*) stream)->ipc; + + /* XXX: Maybe instead of having UV_HANDLE_READING we just test if + * tcp->read_cb is NULL or not? + */ + while (stream->read_cb + && (stream->flags & UV_HANDLE_READING) + && (count-- > 0)) { + assert(stream->alloc_cb != NULL); + + buf = uv_buf_init(NULL, 0); + stream->alloc_cb((uv_handle_t*)stream, 64 * 1024, &buf); + if (buf.base == NULL || buf.len == 0) { + /* User indicates it can't or won't handle the read. */ + stream->read_cb(stream, UV_ENOBUFS, &buf); + return; + } + + assert(buf.base != NULL); + assert(uv__stream_fd(stream) >= 0); + + if (!is_ipc) { + do { + nread = read(uv__stream_fd(stream), buf.base, buf.len); + } + while (nread < 0 && errno == EINTR); + } else { + /* ipc uses recvmsg */ + msg.msg_flags = 0; + msg.msg_iov = (struct iovec*) &buf; + msg.msg_iovlen = 1; + msg.msg_name = NULL; + msg.msg_namelen = 0; + /* Set up to receive a descriptor even if one isn't in the message */ + msg.msg_controllen = sizeof(cmsg_space); + msg.msg_control = cmsg_space; + + do { + nread = uv__recvmsg(uv__stream_fd(stream), &msg, 0); + } + while (nread < 0 && errno == EINTR); + } + + if (nread < 0) { + /* Error */ + if (errno == EAGAIN || errno == EWOULDBLOCK) { + /* Wait for the next one. */ + if (stream->flags & UV_HANDLE_READING) { + uv__io_start(stream->loop, &stream->io_watcher, POLLIN); + uv__stream_osx_interrupt_select(stream); + } + stream->read_cb(stream, 0, &buf); +#if defined(__CYGWIN__) || defined(__MSYS__) + } else if (errno == ECONNRESET && stream->type == UV_NAMED_PIPE) { + uv__stream_eof(stream, &buf); + return; +#endif + } else { + /* Error. User should call uv_close(). */ + stream->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); + stream->read_cb(stream, UV__ERR(errno), &buf); + if (stream->flags & UV_HANDLE_READING) { + stream->flags &= ~UV_HANDLE_READING; + uv__io_stop(stream->loop, &stream->io_watcher, POLLIN); + uv__handle_stop(stream); + uv__stream_osx_interrupt_select(stream); + } + } + return; + } else if (nread == 0) { + uv__stream_eof(stream, &buf); + return; + } else { + /* Successful read */ + ssize_t buflen = buf.len; + + if (is_ipc) { + err = uv__stream_recv_cmsg(stream, &msg); + if (err != 0) { + stream->read_cb(stream, err, &buf); + return; + } + } + +#if defined(__MVS__) + if (is_ipc && msg.msg_controllen > 0) { + uv_buf_t blankbuf; + int nread; + struct iovec *old; + + blankbuf.base = 0; + blankbuf.len = 0; + old = msg.msg_iov; + msg.msg_iov = (struct iovec*) &blankbuf; + nread = 0; + do { + nread = uv__recvmsg(uv__stream_fd(stream), &msg, 0); + err = uv__stream_recv_cmsg(stream, &msg); + if (err != 0) { + stream->read_cb(stream, err, &buf); + msg.msg_iov = old; + return; + } + } while (nread == 0 && msg.msg_controllen > 0); + msg.msg_iov = old; + } +#endif + stream->read_cb(stream, nread, &buf); + + /* Return if we didn't fill the buffer, there is no more data to read. */ + if (nread < buflen) { + stream->flags |= UV_HANDLE_READ_PARTIAL; + return; + } + } + } +} + + +#ifdef __clang__ +# pragma clang diagnostic pop +#endif + +#undef UV__CMSG_FD_COUNT +#undef UV__CMSG_FD_SIZE + + +int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) { + assert(stream->type == UV_TCP || + stream->type == UV_TTY || + stream->type == UV_NAMED_PIPE); + + if (!(stream->flags & UV_HANDLE_WRITABLE) || + stream->flags & UV_HANDLE_SHUT || + stream->flags & UV_HANDLE_SHUTTING || + uv__is_closing(stream)) { + return UV_ENOTCONN; + } + + assert(uv__stream_fd(stream) >= 0); + + /* Initialize request */ + uv__req_init(stream->loop, req, UV_SHUTDOWN); + req->handle = stream; + req->cb = cb; + stream->shutdown_req = req; + stream->flags |= UV_HANDLE_SHUTTING; + stream->flags &= ~UV_HANDLE_WRITABLE; + + uv__io_start(stream->loop, &stream->io_watcher, POLLOUT); + uv__stream_osx_interrupt_select(stream); + + return 0; +} + + +static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { + uv_stream_t* stream; + + stream = container_of(w, uv_stream_t, io_watcher); + + assert(stream->type == UV_TCP || + stream->type == UV_NAMED_PIPE || + stream->type == UV_TTY); + assert(!(stream->flags & UV_HANDLE_CLOSING)); + + if (stream->connect_req) { + uv__stream_connect(stream); + return; + } + + assert(uv__stream_fd(stream) >= 0); + + /* Ignore POLLHUP here. Even if it's set, there may still be data to read. */ + if (events & (POLLIN | POLLERR | POLLHUP)) + uv__read(stream); + + if (uv__stream_fd(stream) == -1) + return; /* read_cb closed stream. */ + + /* Short-circuit iff POLLHUP is set, the user is still interested in read + * events and uv__read() reported a partial read but not EOF. If the EOF + * flag is set, uv__read() called read_cb with err=UV_EOF and we don't + * have to do anything. If the partial read flag is not set, we can't + * report the EOF yet because there is still data to read. + */ + if ((events & POLLHUP) && + (stream->flags & UV_HANDLE_READING) && + (stream->flags & UV_HANDLE_READ_PARTIAL) && + !(stream->flags & UV_HANDLE_READ_EOF)) { + uv_buf_t buf = { NULL, 0 }; + uv__stream_eof(stream, &buf); + } + + if (uv__stream_fd(stream) == -1) + return; /* read_cb closed stream. */ + + if (events & (POLLOUT | POLLERR | POLLHUP)) { + uv__write(stream); + uv__write_callbacks(stream); + + /* Write queue drained. */ + if (QUEUE_EMPTY(&stream->write_queue)) + uv__drain(stream); + } +} + + +/** + * We get called here from directly following a call to connect(2). + * In order to determine if we've errored out or succeeded must call + * getsockopt. + */ +static void uv__stream_connect(uv_stream_t* stream) { + int error; + uv_connect_t* req = stream->connect_req; + socklen_t errorsize = sizeof(int); + + assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE); + assert(req); + + if (stream->delayed_error) { + /* To smooth over the differences between unixes errors that + * were reported synchronously on the first connect can be delayed + * until the next tick--which is now. + */ + error = stream->delayed_error; + stream->delayed_error = 0; + } else { + /* Normal situation: we need to get the socket error from the kernel. */ + assert(uv__stream_fd(stream) >= 0); + getsockopt(uv__stream_fd(stream), + SOL_SOCKET, + SO_ERROR, + &error, + &errorsize); + error = UV__ERR(error); + } + + if (error == UV__ERR(EINPROGRESS)) + return; + + stream->connect_req = NULL; + uv__req_unregister(stream->loop, req); + + if (error < 0 || QUEUE_EMPTY(&stream->write_queue)) { + uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT); + } + + if (req->cb) + req->cb(req, error); + + if (uv__stream_fd(stream) == -1) + return; + + if (error < 0) { + uv__stream_flush_write_queue(stream, UV_ECANCELED); + uv__write_callbacks(stream); + } +} + + +static int uv__check_before_write(uv_stream_t* stream, + unsigned int nbufs, + uv_stream_t* send_handle) { + assert(nbufs > 0); + assert((stream->type == UV_TCP || + stream->type == UV_NAMED_PIPE || + stream->type == UV_TTY) && + "uv_write (unix) does not yet support other types of streams"); + + if (uv__stream_fd(stream) < 0) + return UV_EBADF; + + if (!(stream->flags & UV_HANDLE_WRITABLE)) + return UV_EPIPE; + + if (send_handle != NULL) { + if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc) + return UV_EINVAL; + + /* XXX We abuse uv_write2() to send over UDP handles to child processes. + * Don't call uv__stream_fd() on those handles, it's a macro that on OS X + * evaluates to a function that operates on a uv_stream_t with a couple of + * OS X specific fields. On other Unices it does (handle)->io_watcher.fd, + * which works but only by accident. + */ + if (uv__handle_fd((uv_handle_t*) send_handle) < 0) + return UV_EBADF; + +#if defined(__CYGWIN__) || defined(__MSYS__) + /* Cygwin recvmsg always sets msg_controllen to zero, so we cannot send it. + See https://github.com/mirror/newlib-cygwin/blob/86fc4bf0/winsup/cygwin/fhandler_socket.cc#L1736-L1743 */ + return UV_ENOSYS; +#endif + } + + return 0; +} + +int uv_write2(uv_write_t* req, + uv_stream_t* stream, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle, + uv_write_cb cb) { + int empty_queue; + int err; + + err = uv__check_before_write(stream, nbufs, send_handle); + if (err < 0) + return err; + + /* It's legal for write_queue_size > 0 even when the write_queue is empty; + * it means there are error-state requests in the write_completed_queue that + * will touch up write_queue_size later, see also uv__write_req_finish(). + * We could check that write_queue is empty instead but that implies making + * a write() syscall when we know that the handle is in error mode. + */ + empty_queue = (stream->write_queue_size == 0); + + /* Initialize the req */ + uv__req_init(stream->loop, req, UV_WRITE); + req->cb = cb; + req->handle = stream; + req->error = 0; + req->send_handle = send_handle; + QUEUE_INIT(&req->queue); + + req->bufs = req->bufsml; + if (nbufs > ARRAY_SIZE(req->bufsml)) + req->bufs = uv__malloc(nbufs * sizeof(bufs[0])); + + if (req->bufs == NULL) + return UV_ENOMEM; + + memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0])); + req->nbufs = nbufs; + req->write_index = 0; + stream->write_queue_size += uv__count_bufs(bufs, nbufs); + + /* Append the request to write_queue. */ + QUEUE_INSERT_TAIL(&stream->write_queue, &req->queue); + + /* If the queue was empty when this function began, we should attempt to + * do the write immediately. Otherwise start the write_watcher and wait + * for the fd to become writable. + */ + if (stream->connect_req) { + /* Still connecting, do nothing. */ + } + else if (empty_queue) { + uv__write(stream); + } + else { + /* + * blocking streams should never have anything in the queue. + * if this assert fires then somehow the blocking stream isn't being + * sufficiently flushed in uv__write. + */ + assert(!(stream->flags & UV_HANDLE_BLOCKING_WRITES)); + uv__io_start(stream->loop, &stream->io_watcher, POLLOUT); + uv__stream_osx_interrupt_select(stream); + } + + return 0; +} + + +/* The buffers to be written must remain valid until the callback is called. + * This is not required for the uv_buf_t array. + */ +int uv_write(uv_write_t* req, + uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_write_cb cb) { + return uv_write2(req, handle, bufs, nbufs, NULL, cb); +} + + +int uv_try_write(uv_stream_t* stream, + const uv_buf_t bufs[], + unsigned int nbufs) { + return uv_try_write2(stream, bufs, nbufs, NULL); +} + + +int uv_try_write2(uv_stream_t* stream, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle) { + int err; + + /* Connecting or already writing some data */ + if (stream->connect_req != NULL || stream->write_queue_size != 0) + return UV_EAGAIN; + + err = uv__check_before_write(stream, nbufs, NULL); + if (err < 0) + return err; + + return uv__try_write(stream, bufs, nbufs, send_handle); +} + + +int uv__read_start(uv_stream_t* stream, + uv_alloc_cb alloc_cb, + uv_read_cb read_cb) { + assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE || + stream->type == UV_TTY); + + /* The UV_HANDLE_READING flag is irrelevant of the state of the tcp - it just + * expresses the desired state of the user. + */ + stream->flags |= UV_HANDLE_READING; + + /* TODO: try to do the read inline? */ + /* TODO: keep track of tcp state. If we've gotten a EOF then we should + * not start the IO watcher. + */ + assert(uv__stream_fd(stream) >= 0); + assert(alloc_cb); + + stream->read_cb = read_cb; + stream->alloc_cb = alloc_cb; + + uv__io_start(stream->loop, &stream->io_watcher, POLLIN); + uv__handle_start(stream); + uv__stream_osx_interrupt_select(stream); + + return 0; +} + + +int uv_read_stop(uv_stream_t* stream) { + if (!(stream->flags & UV_HANDLE_READING)) + return 0; + + stream->flags &= ~UV_HANDLE_READING; + uv__io_stop(stream->loop, &stream->io_watcher, POLLIN); + uv__handle_stop(stream); + uv__stream_osx_interrupt_select(stream); + + stream->read_cb = NULL; + stream->alloc_cb = NULL; + return 0; +} + + +int uv_is_readable(const uv_stream_t* stream) { + return !!(stream->flags & UV_HANDLE_READABLE); +} + + +int uv_is_writable(const uv_stream_t* stream) { + return !!(stream->flags & UV_HANDLE_WRITABLE); +} + + +#if defined(__APPLE__) +int uv___stream_fd(const uv_stream_t* handle) { + const uv__stream_select_t* s; + + assert(handle->type == UV_TCP || + handle->type == UV_TTY || + handle->type == UV_NAMED_PIPE); + + s = handle->select; + if (s != NULL) + return s->fd; + + return handle->io_watcher.fd; +} +#endif /* defined(__APPLE__) */ + + +void uv__stream_close(uv_stream_t* handle) { + unsigned int i; + uv__stream_queued_fds_t* queued_fds; + +#if defined(__APPLE__) + /* Terminate select loop first */ + if (handle->select != NULL) { + uv__stream_select_t* s; + + s = handle->select; + + uv_sem_post(&s->close_sem); + uv_sem_post(&s->async_sem); + uv__stream_osx_interrupt_select(handle); + uv_thread_join(&s->thread); + uv_sem_destroy(&s->close_sem); + uv_sem_destroy(&s->async_sem); + uv__close(s->fake_fd); + uv__close(s->int_fd); + uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close); + + handle->select = NULL; + } +#endif /* defined(__APPLE__) */ + + uv__io_close(handle->loop, &handle->io_watcher); + uv_read_stop(handle); + uv__handle_stop(handle); + handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); + + if (handle->io_watcher.fd != -1) { + /* Don't close stdio file descriptors. Nothing good comes from it. */ + if (handle->io_watcher.fd > STDERR_FILENO) + uv__close(handle->io_watcher.fd); + handle->io_watcher.fd = -1; + } + + if (handle->accepted_fd != -1) { + uv__close(handle->accepted_fd); + handle->accepted_fd = -1; + } + + /* Close all queued fds */ + if (handle->queued_fds != NULL) { + queued_fds = handle->queued_fds; + for (i = 0; i < queued_fds->offset; i++) + uv__close(queued_fds->fds[i]); + uv__free(handle->queued_fds); + handle->queued_fds = NULL; + } + + assert(!uv__io_active(&handle->io_watcher, POLLIN | POLLOUT)); +} + + +int uv_stream_set_blocking(uv_stream_t* handle, int blocking) { + /* Don't need to check the file descriptor, uv__nonblock() + * will fail with EBADF if it's not valid. + */ + return uv__nonblock(uv__stream_fd(handle), !blocking); +} diff --git a/external/src/libuv/src/unix/sunos.c b/external/src/libuv/src/unix/sunos.c new file mode 100644 index 0000000..2bf297e --- /dev/null +++ b/external/src/libuv/src/unix/sunos.c @@ -0,0 +1,878 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include +#include + +#ifndef SUNOS_NO_IFADDRS +# include +#endif +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#define PORT_FIRED 0x69 +#define PORT_UNUSED 0x0 +#define PORT_LOADED 0x99 +#define PORT_DELETED -1 + +#if (!defined(_LP64)) && (_FILE_OFFSET_BITS - 0 == 64) +#define PROCFS_FILE_OFFSET_BITS_HACK 1 +#undef _FILE_OFFSET_BITS +#else +#define PROCFS_FILE_OFFSET_BITS_HACK 0 +#endif + +#include + +#if (PROCFS_FILE_OFFSET_BITS_HACK - 0 == 1) +#define _FILE_OFFSET_BITS 64 +#endif + + +int uv__platform_loop_init(uv_loop_t* loop) { + int err; + int fd; + + loop->fs_fd = -1; + loop->backend_fd = -1; + + fd = port_create(); + if (fd == -1) + return UV__ERR(errno); + + err = uv__cloexec(fd, 1); + if (err) { + uv__close(fd); + return err; + } + loop->backend_fd = fd; + + return 0; +} + + +void uv__platform_loop_delete(uv_loop_t* loop) { + if (loop->fs_fd != -1) { + uv__close(loop->fs_fd); + loop->fs_fd = -1; + } + + if (loop->backend_fd != -1) { + uv__close(loop->backend_fd); + loop->backend_fd = -1; + } +} + + +int uv__io_fork(uv_loop_t* loop) { +#if defined(PORT_SOURCE_FILE) + if (loop->fs_fd != -1) { + /* stop the watcher before we blow away its fileno */ + uv__io_stop(loop, &loop->fs_event_watcher, POLLIN); + } +#endif + uv__platform_loop_delete(loop); + return uv__platform_loop_init(loop); +} + + +void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { + struct port_event* events; + uintptr_t i; + uintptr_t nfds; + + assert(loop->watchers != NULL); + assert(fd >= 0); + + events = (struct port_event*) loop->watchers[loop->nwatchers]; + nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; + if (events == NULL) + return; + + /* Invalidate events with same file descriptor */ + for (i = 0; i < nfds; i++) + if ((int) events[i].portev_object == fd) + events[i].portev_object = -1; +} + + +int uv__io_check_fd(uv_loop_t* loop, int fd) { + if (port_associate(loop->backend_fd, PORT_SOURCE_FD, fd, POLLIN, 0)) + return UV__ERR(errno); + + if (port_dissociate(loop->backend_fd, PORT_SOURCE_FD, fd)) { + perror("(libuv) port_dissociate()"); + abort(); + } + + return 0; +} + + +void uv__io_poll(uv_loop_t* loop, int timeout) { + struct port_event events[1024]; + struct port_event* pe; + struct timespec spec; + QUEUE* q; + uv__io_t* w; + sigset_t* pset; + sigset_t set; + uint64_t base; + uint64_t diff; + uint64_t idle_poll; + unsigned int nfds; + unsigned int i; + int saved_errno; + int have_signals; + int nevents; + int count; + int err; + int fd; + int user_timeout; + int reset_timeout; + + if (loop->nfds == 0) { + assert(QUEUE_EMPTY(&loop->watcher_queue)); + return; + } + + while (!QUEUE_EMPTY(&loop->watcher_queue)) { + q = QUEUE_HEAD(&loop->watcher_queue); + QUEUE_REMOVE(q); + QUEUE_INIT(q); + + w = QUEUE_DATA(q, uv__io_t, watcher_queue); + assert(w->pevents != 0); + + if (port_associate(loop->backend_fd, + PORT_SOURCE_FD, + w->fd, + w->pevents, + 0)) { + perror("(libuv) port_associate()"); + abort(); + } + + w->events = w->pevents; + } + + pset = NULL; + if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { + pset = &set; + sigemptyset(pset); + sigaddset(pset, SIGPROF); + } + + assert(timeout >= -1); + base = loop->time; + count = 48; /* Benchmarks suggest this gives the best throughput. */ + + if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) { + reset_timeout = 1; + user_timeout = timeout; + timeout = 0; + } else { + reset_timeout = 0; + } + + for (;;) { + /* Only need to set the provider_entry_time if timeout != 0. The function + * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME. + */ + if (timeout != 0) + uv__metrics_set_provider_entry_time(loop); + + if (timeout != -1) { + spec.tv_sec = timeout / 1000; + spec.tv_nsec = (timeout % 1000) * 1000000; + } + + /* Work around a kernel bug where nfds is not updated. */ + events[0].portev_source = 0; + + nfds = 1; + saved_errno = 0; + + if (pset != NULL) + pthread_sigmask(SIG_BLOCK, pset, NULL); + + err = port_getn(loop->backend_fd, + events, + ARRAY_SIZE(events), + &nfds, + timeout == -1 ? NULL : &spec); + + if (pset != NULL) + pthread_sigmask(SIG_UNBLOCK, pset, NULL); + + if (err) { + /* Work around another kernel bug: port_getn() may return events even + * on error. + */ + if (errno == EINTR || errno == ETIME) { + saved_errno = errno; + } else { + perror("(libuv) port_getn()"); + abort(); + } + } + + /* Update loop->time unconditionally. It's tempting to skip the update when + * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the + * operating system didn't reschedule our process while in the syscall. + */ + SAVE_ERRNO(uv__update_time(loop)); + + if (events[0].portev_source == 0) { + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (timeout == 0) + return; + + if (timeout == -1) + continue; + + goto update_timeout; + } + + if (nfds == 0) { + assert(timeout != -1); + return; + } + + have_signals = 0; + nevents = 0; + + assert(loop->watchers != NULL); + loop->watchers[loop->nwatchers] = (void*) events; + loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds; + for (i = 0; i < nfds; i++) { + pe = events + i; + fd = pe->portev_object; + + /* Skip invalidated events, see uv__platform_invalidate_fd */ + if (fd == -1) + continue; + + assert(fd >= 0); + assert((unsigned) fd < loop->nwatchers); + + w = loop->watchers[fd]; + + /* File descriptor that we've stopped watching, ignore. */ + if (w == NULL) + continue; + + /* Run signal watchers last. This also affects child process watchers + * because those are implemented in terms of signal watchers. + */ + if (w == &loop->signal_io_watcher) { + have_signals = 1; + } else { + uv__metrics_update_idle_time(loop); + w->cb(loop, w, pe->portev_events); + } + + nevents++; + + if (w != loop->watchers[fd]) + continue; /* Disabled by callback. */ + + /* Events Ports operates in oneshot mode, rearm timer on next run. */ + if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue)) + QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue); + } + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + if (have_signals != 0) { + uv__metrics_update_idle_time(loop); + loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN); + } + + loop->watchers[loop->nwatchers] = NULL; + loop->watchers[loop->nwatchers + 1] = NULL; + + if (have_signals != 0) + return; /* Event loop should cycle now so don't poll again. */ + + if (nevents != 0) { + if (nfds == ARRAY_SIZE(events) && --count != 0) { + /* Poll for more events but don't block this time. */ + timeout = 0; + continue; + } + return; + } + + if (saved_errno == ETIME) { + assert(timeout != -1); + return; + } + + if (timeout == 0) + return; + + if (timeout == -1) + continue; + +update_timeout: + assert(timeout > 0); + + diff = loop->time - base; + if (diff >= (uint64_t) timeout) + return; + + timeout -= diff; + } +} + + +uint64_t uv__hrtime(uv_clocktype_t type) { + return gethrtime(); +} + + +/* + * We could use a static buffer for the path manipulations that we need outside + * of the function, but this function could be called by multiple consumers and + * we don't want to potentially create a race condition in the use of snprintf. + */ +int uv_exepath(char* buffer, size_t* size) { + ssize_t res; + char buf[128]; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + snprintf(buf, sizeof(buf), "/proc/%lu/path/a.out", (unsigned long) getpid()); + + res = *size - 1; + if (res > 0) + res = readlink(buf, buffer, res); + + if (res == -1) + return UV__ERR(errno); + + buffer[res] = '\0'; + *size = res; + return 0; +} + + +uint64_t uv_get_free_memory(void) { + return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES); +} + + +uint64_t uv_get_total_memory(void) { + return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES); +} + + +uint64_t uv_get_constrained_memory(void) { + return 0; /* Memory constraints are unknown. */ +} + + +void uv_loadavg(double avg[3]) { + (void) getloadavg(avg, 3); +} + + +#if defined(PORT_SOURCE_FILE) + +static int uv__fs_event_rearm(uv_fs_event_t *handle) { + if (handle->fd == -1) + return UV_EBADF; + + if (port_associate(handle->loop->fs_fd, + PORT_SOURCE_FILE, + (uintptr_t) &handle->fo, + FILE_ATTRIB | FILE_MODIFIED, + handle) == -1) { + return UV__ERR(errno); + } + handle->fd = PORT_LOADED; + + return 0; +} + + +static void uv__fs_event_read(uv_loop_t* loop, + uv__io_t* w, + unsigned int revents) { + uv_fs_event_t *handle = NULL; + timespec_t timeout; + port_event_t pe; + int events; + int r; + + (void) w; + (void) revents; + + do { + uint_t n = 1; + + /* + * Note that our use of port_getn() here (and not port_get()) is deliberate: + * there is a bug in event ports (Sun bug 6456558) whereby a zeroed timeout + * causes port_get() to return success instead of ETIME when there aren't + * actually any events (!); by using port_getn() in lieu of port_get(), + * we can at least workaround the bug by checking for zero returned events + * and treating it as we would ETIME. + */ + do { + memset(&timeout, 0, sizeof timeout); + r = port_getn(loop->fs_fd, &pe, 1, &n, &timeout); + } + while (r == -1 && errno == EINTR); + + if ((r == -1 && errno == ETIME) || n == 0) + break; + + handle = (uv_fs_event_t*) pe.portev_user; + assert((r == 0) && "unexpected port_get() error"); + + events = 0; + if (pe.portev_events & (FILE_ATTRIB | FILE_MODIFIED)) + events |= UV_CHANGE; + if (pe.portev_events & ~(FILE_ATTRIB | FILE_MODIFIED)) + events |= UV_RENAME; + assert(events != 0); + handle->fd = PORT_FIRED; + handle->cb(handle, NULL, events, 0); + + if (handle->fd != PORT_DELETED) { + r = uv__fs_event_rearm(handle); + if (r != 0) + handle->cb(handle, NULL, 0, r); + } + } + while (handle->fd != PORT_DELETED); +} + + +int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { + uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); + return 0; +} + + +int uv_fs_event_start(uv_fs_event_t* handle, + uv_fs_event_cb cb, + const char* path, + unsigned int flags) { + int portfd; + int first_run; + int err; + + if (uv__is_active(handle)) + return UV_EINVAL; + + first_run = 0; + if (handle->loop->fs_fd == -1) { + portfd = port_create(); + if (portfd == -1) + return UV__ERR(errno); + handle->loop->fs_fd = portfd; + first_run = 1; + } + + uv__handle_start(handle); + handle->path = uv__strdup(path); + handle->fd = PORT_UNUSED; + handle->cb = cb; + + memset(&handle->fo, 0, sizeof handle->fo); + handle->fo.fo_name = handle->path; + err = uv__fs_event_rearm(handle); + if (err != 0) { + uv_fs_event_stop(handle); + return err; + } + + if (first_run) { + uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd); + uv__io_start(handle->loop, &handle->loop->fs_event_watcher, POLLIN); + } + + return 0; +} + + +int uv_fs_event_stop(uv_fs_event_t* handle) { + if (!uv__is_active(handle)) + return 0; + + if (handle->fd == PORT_FIRED || handle->fd == PORT_LOADED) { + port_dissociate(handle->loop->fs_fd, + PORT_SOURCE_FILE, + (uintptr_t) &handle->fo); + } + + handle->fd = PORT_DELETED; + uv__free(handle->path); + handle->path = NULL; + handle->fo.fo_name = NULL; + uv__handle_stop(handle); + + return 0; +} + +void uv__fs_event_close(uv_fs_event_t* handle) { + uv_fs_event_stop(handle); +} + +#else /* !defined(PORT_SOURCE_FILE) */ + +int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { + return UV_ENOSYS; +} + + +int uv_fs_event_start(uv_fs_event_t* handle, + uv_fs_event_cb cb, + const char* filename, + unsigned int flags) { + return UV_ENOSYS; +} + + +int uv_fs_event_stop(uv_fs_event_t* handle) { + return UV_ENOSYS; +} + + +void uv__fs_event_close(uv_fs_event_t* handle) { + UNREACHABLE(); +} + +#endif /* defined(PORT_SOURCE_FILE) */ + + +int uv_resident_set_memory(size_t* rss) { + psinfo_t psinfo; + int err; + int fd; + + fd = open("/proc/self/psinfo", O_RDONLY); + if (fd == -1) + return UV__ERR(errno); + + /* FIXME(bnoordhuis) Handle EINTR. */ + err = UV_EINVAL; + if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo)) { + *rss = (size_t)psinfo.pr_rssize * 1024; + err = 0; + } + uv__close(fd); + + return err; +} + + +int uv_uptime(double* uptime) { + kstat_ctl_t *kc; + kstat_t *ksp; + kstat_named_t *knp; + + long hz = sysconf(_SC_CLK_TCK); + + kc = kstat_open(); + if (kc == NULL) + return UV_EPERM; + + ksp = kstat_lookup(kc, (char*) "unix", 0, (char*) "system_misc"); + if (kstat_read(kc, ksp, NULL) == -1) { + *uptime = -1; + } else { + knp = (kstat_named_t*) kstat_data_lookup(ksp, (char*) "clk_intr"); + *uptime = knp->value.ul / hz; + } + kstat_close(kc); + + return 0; +} + + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + int lookup_instance; + kstat_ctl_t *kc; + kstat_t *ksp; + kstat_named_t *knp; + uv_cpu_info_t* cpu_info; + + kc = kstat_open(); + if (kc == NULL) + return UV_EPERM; + + /* Get count of cpus */ + lookup_instance = 0; + while ((ksp = kstat_lookup(kc, (char*) "cpu_info", lookup_instance, NULL))) { + lookup_instance++; + } + + *cpu_infos = uv__malloc(lookup_instance * sizeof(**cpu_infos)); + if (!(*cpu_infos)) { + kstat_close(kc); + return UV_ENOMEM; + } + + *count = lookup_instance; + + cpu_info = *cpu_infos; + lookup_instance = 0; + while ((ksp = kstat_lookup(kc, (char*) "cpu_info", lookup_instance, NULL))) { + if (kstat_read(kc, ksp, NULL) == -1) { + cpu_info->speed = 0; + cpu_info->model = NULL; + } else { + knp = kstat_data_lookup(ksp, (char*) "clock_MHz"); + assert(knp->data_type == KSTAT_DATA_INT32 || + knp->data_type == KSTAT_DATA_INT64); + cpu_info->speed = (knp->data_type == KSTAT_DATA_INT32) ? knp->value.i32 + : knp->value.i64; + + knp = kstat_data_lookup(ksp, (char*) "brand"); + assert(knp->data_type == KSTAT_DATA_STRING); + cpu_info->model = uv__strdup(KSTAT_NAMED_STR_PTR(knp)); + } + + lookup_instance++; + cpu_info++; + } + + cpu_info = *cpu_infos; + lookup_instance = 0; + for (;;) { + ksp = kstat_lookup(kc, (char*) "cpu", lookup_instance, (char*) "sys"); + + if (ksp == NULL) + break; + + if (kstat_read(kc, ksp, NULL) == -1) { + cpu_info->cpu_times.user = 0; + cpu_info->cpu_times.nice = 0; + cpu_info->cpu_times.sys = 0; + cpu_info->cpu_times.idle = 0; + cpu_info->cpu_times.irq = 0; + } else { + knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_user"); + assert(knp->data_type == KSTAT_DATA_UINT64); + cpu_info->cpu_times.user = knp->value.ui64; + + knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_kernel"); + assert(knp->data_type == KSTAT_DATA_UINT64); + cpu_info->cpu_times.sys = knp->value.ui64; + + knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_idle"); + assert(knp->data_type == KSTAT_DATA_UINT64); + cpu_info->cpu_times.idle = knp->value.ui64; + + knp = kstat_data_lookup(ksp, (char*) "intr"); + assert(knp->data_type == KSTAT_DATA_UINT64); + cpu_info->cpu_times.irq = knp->value.ui64; + cpu_info->cpu_times.nice = 0; + } + + lookup_instance++; + cpu_info++; + } + + kstat_close(kc); + + return 0; +} + + +#ifdef SUNOS_NO_IFADDRS +int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { + *count = 0; + *addresses = NULL; + return UV_ENOSYS; +} +#else /* SUNOS_NO_IFADDRS */ +/* + * Inspired By: + * https://blogs.oracle.com/paulie/entry/retrieving_mac_address_in_solaris + * http://www.pauliesworld.org/project/getmac.c + */ +static int uv__set_phys_addr(uv_interface_address_t* address, + struct ifaddrs* ent) { + + struct sockaddr_dl* sa_addr; + int sockfd; + size_t i; + struct arpreq arpreq; + + /* This appears to only work as root */ + sa_addr = (struct sockaddr_dl*)(ent->ifa_addr); + memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr)); + for (i = 0; i < sizeof(address->phys_addr); i++) { + /* Check that all bytes of phys_addr are zero. */ + if (address->phys_addr[i] != 0) + return 0; + } + memset(&arpreq, 0, sizeof(arpreq)); + if (address->address.address4.sin_family == AF_INET) { + struct sockaddr_in* sin = ((struct sockaddr_in*)&arpreq.arp_pa); + sin->sin_addr.s_addr = address->address.address4.sin_addr.s_addr; + } else if (address->address.address4.sin_family == AF_INET6) { + struct sockaddr_in6* sin = ((struct sockaddr_in6*)&arpreq.arp_pa); + memcpy(sin->sin6_addr.s6_addr, + address->address.address6.sin6_addr.s6_addr, + sizeof(address->address.address6.sin6_addr.s6_addr)); + } else { + return 0; + } + + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd < 0) + return UV__ERR(errno); + + if (ioctl(sockfd, SIOCGARP, (char*)&arpreq) == -1) { + uv__close(sockfd); + return UV__ERR(errno); + } + memcpy(address->phys_addr, arpreq.arp_ha.sa_data, sizeof(address->phys_addr)); + uv__close(sockfd); + return 0; +} + + +static int uv__ifaddr_exclude(struct ifaddrs *ent) { + if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) + return 1; + if (ent->ifa_addr == NULL) + return 1; + if (ent->ifa_addr->sa_family != AF_INET && + ent->ifa_addr->sa_family != AF_INET6) + return 1; + return 0; +} + +int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { + uv_interface_address_t* address; + struct ifaddrs* addrs; + struct ifaddrs* ent; + + *count = 0; + *addresses = NULL; + + if (getifaddrs(&addrs)) + return UV__ERR(errno); + + /* Count the number of interfaces */ + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent)) + continue; + (*count)++; + } + + if (*count == 0) { + freeifaddrs(addrs); + return 0; + } + + *addresses = uv__malloc(*count * sizeof(**addresses)); + if (!(*addresses)) { + freeifaddrs(addrs); + return UV_ENOMEM; + } + + address = *addresses; + + for (ent = addrs; ent != NULL; ent = ent->ifa_next) { + if (uv__ifaddr_exclude(ent)) + continue; + + address->name = uv__strdup(ent->ifa_name); + + if (ent->ifa_addr->sa_family == AF_INET6) { + address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); + } else { + address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); + } + + if (ent->ifa_netmask->sa_family == AF_INET6) { + address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); + } else { + address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); + } + + address->is_internal = !!((ent->ifa_flags & IFF_PRIVATE) || + (ent->ifa_flags & IFF_LOOPBACK)); + + uv__set_phys_addr(address, ent); + address++; + } + + freeifaddrs(addrs); + + return 0; +} +#endif /* SUNOS_NO_IFADDRS */ + +void uv_free_interface_addresses(uv_interface_address_t* addresses, + int count) { + int i; + + for (i = 0; i < count; i++) { + uv__free(addresses[i].name); + } + + uv__free(addresses); +} + + +#if !defined(_POSIX_VERSION) || _POSIX_VERSION < 200809L +size_t strnlen(const char* s, size_t maxlen) { + const char* end; + end = memchr(s, '\0', maxlen); + if (end == NULL) + return maxlen; + return end - s; +} +#endif diff --git a/external/src/libuv/src/unix/sysinfo-loadavg.c b/external/src/libuv/src/unix/sysinfo-loadavg.c new file mode 100644 index 0000000..ebad0e8 --- /dev/null +++ b/external/src/libuv/src/unix/sysinfo-loadavg.c @@ -0,0 +1,36 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +void uv_loadavg(double avg[3]) { + struct sysinfo info; + + if (sysinfo(&info) < 0) return; + + avg[0] = (double) info.loads[0] / 65536.0; + avg[1] = (double) info.loads[1] / 65536.0; + avg[2] = (double) info.loads[2] / 65536.0; +} diff --git a/external/src/libuv/src/unix/sysinfo-memory.c b/external/src/libuv/src/unix/sysinfo-memory.c new file mode 100644 index 0000000..23b4fc6 --- /dev/null +++ b/external/src/libuv/src/unix/sysinfo-memory.c @@ -0,0 +1,42 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include + +uint64_t uv_get_free_memory(void) { + struct sysinfo info; + + if (sysinfo(&info) == 0) + return (uint64_t) info.freeram * info.mem_unit; + return 0; +} + +uint64_t uv_get_total_memory(void) { + struct sysinfo info; + + if (sysinfo(&info) == 0) + return (uint64_t) info.totalram * info.mem_unit; + return 0; +} diff --git a/external/src/libuv/src/unix/tcp.c b/external/src/libuv/src/unix/tcp.c new file mode 100644 index 0000000..bc0fb66 --- /dev/null +++ b/external/src/libuv/src/unix/tcp.c @@ -0,0 +1,510 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include + + +static int new_socket(uv_tcp_t* handle, int domain, unsigned long flags) { + struct sockaddr_storage saddr; + socklen_t slen; + int sockfd; + int err; + + err = uv__socket(domain, SOCK_STREAM, 0); + if (err < 0) + return err; + sockfd = err; + + err = uv__stream_open((uv_stream_t*) handle, sockfd, flags); + if (err) { + uv__close(sockfd); + return err; + } + + if (flags & UV_HANDLE_BOUND) { + /* Bind this new socket to an arbitrary port */ + slen = sizeof(saddr); + memset(&saddr, 0, sizeof(saddr)); + if (getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen)) { + uv__close(sockfd); + return UV__ERR(errno); + } + + if (bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen)) { + uv__close(sockfd); + return UV__ERR(errno); + } + } + + return 0; +} + + +static int maybe_new_socket(uv_tcp_t* handle, int domain, unsigned long flags) { + struct sockaddr_storage saddr; + socklen_t slen; + + if (domain == AF_UNSPEC) { + handle->flags |= flags; + return 0; + } + + if (uv__stream_fd(handle) != -1) { + + if (flags & UV_HANDLE_BOUND) { + + if (handle->flags & UV_HANDLE_BOUND) { + /* It is already bound to a port. */ + handle->flags |= flags; + return 0; + } + + /* Query to see if tcp socket is bound. */ + slen = sizeof(saddr); + memset(&saddr, 0, sizeof(saddr)); + if (getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen)) + return UV__ERR(errno); + + if ((saddr.ss_family == AF_INET6 && + ((struct sockaddr_in6*) &saddr)->sin6_port != 0) || + (saddr.ss_family == AF_INET && + ((struct sockaddr_in*) &saddr)->sin_port != 0)) { + /* Handle is already bound to a port. */ + handle->flags |= flags; + return 0; + } + + /* Bind to arbitrary port */ + if (bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen)) + return UV__ERR(errno); + } + + handle->flags |= flags; + return 0; + } + + return new_socket(handle, domain, flags); +} + + +int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* tcp, unsigned int flags) { + int domain; + + /* Use the lower 8 bits for the domain */ + domain = flags & 0xFF; + if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC) + return UV_EINVAL; + + if (flags & ~0xFF) + return UV_EINVAL; + + uv__stream_init(loop, (uv_stream_t*)tcp, UV_TCP); + + /* If anything fails beyond this point we need to remove the handle from + * the handle queue, since it was added by uv__handle_init in uv_stream_init. + */ + + if (domain != AF_UNSPEC) { + int err = maybe_new_socket(tcp, domain, 0); + if (err) { + QUEUE_REMOVE(&tcp->handle_queue); + return err; + } + } + + return 0; +} + + +int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) { + return uv_tcp_init_ex(loop, tcp, AF_UNSPEC); +} + + +int uv__tcp_bind(uv_tcp_t* tcp, + const struct sockaddr* addr, + unsigned int addrlen, + unsigned int flags) { + int err; + int on; + + /* Cannot set IPv6-only mode on non-IPv6 socket. */ + if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6) + return UV_EINVAL; + + err = maybe_new_socket(tcp, addr->sa_family, 0); + if (err) + return err; + + on = 1; + if (setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) + return UV__ERR(errno); + +#ifndef __OpenBSD__ +#ifdef IPV6_V6ONLY + if (addr->sa_family == AF_INET6) { + on = (flags & UV_TCP_IPV6ONLY) != 0; + if (setsockopt(tcp->io_watcher.fd, + IPPROTO_IPV6, + IPV6_V6ONLY, + &on, + sizeof on) == -1) { +#if defined(__MVS__) + if (errno == EOPNOTSUPP) + return UV_EINVAL; +#endif + return UV__ERR(errno); + } + } +#endif +#endif + + errno = 0; + if (bind(tcp->io_watcher.fd, addr, addrlen) && errno != EADDRINUSE) { + if (errno == EAFNOSUPPORT) + /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a + * socket created with AF_INET to an AF_INET6 address or vice versa. */ + return UV_EINVAL; + return UV__ERR(errno); + } + tcp->delayed_error = UV__ERR(errno); + + tcp->flags |= UV_HANDLE_BOUND; + if (addr->sa_family == AF_INET6) + tcp->flags |= UV_HANDLE_IPV6; + + return 0; +} + + +int uv__tcp_connect(uv_connect_t* req, + uv_tcp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen, + uv_connect_cb cb) { + int err; + int r; + + assert(handle->type == UV_TCP); + + if (handle->connect_req != NULL) + return UV_EALREADY; /* FIXME(bnoordhuis) UV_EINVAL or maybe UV_EBUSY. */ + + if (handle->delayed_error != 0) + goto out; + + err = maybe_new_socket(handle, + addr->sa_family, + UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); + if (err) + return err; + + do { + errno = 0; + r = connect(uv__stream_fd(handle), addr, addrlen); + } while (r == -1 && errno == EINTR); + + /* We not only check the return value, but also check the errno != 0. + * Because in rare cases connect() will return -1 but the errno + * is 0 (for example, on Android 4.3, OnePlus phone A0001_12_150227) + * and actually the tcp three-way handshake is completed. + */ + if (r == -1 && errno != 0) { + if (errno == EINPROGRESS) + ; /* not an error */ + else if (errno == ECONNREFUSED +#if defined(__OpenBSD__) + || errno == EINVAL +#endif + ) + /* If we get ECONNREFUSED (Solaris) or EINVAL (OpenBSD) wait until the + * next tick to report the error. Solaris and OpenBSD wants to report + * immediately -- other unixes want to wait. + */ + handle->delayed_error = UV__ERR(ECONNREFUSED); + else + return UV__ERR(errno); + } + +out: + + uv__req_init(handle->loop, req, UV_CONNECT); + req->cb = cb; + req->handle = (uv_stream_t*) handle; + QUEUE_INIT(&req->queue); + handle->connect_req = req; + + uv__io_start(handle->loop, &handle->io_watcher, POLLOUT); + + if (handle->delayed_error) + uv__io_feed(handle->loop, &handle->io_watcher); + + return 0; +} + + +int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) { + int err; + + if (uv__fd_exists(handle->loop, sock)) + return UV_EEXIST; + + err = uv__nonblock(sock, 1); + if (err) + return err; + + return uv__stream_open((uv_stream_t*)handle, + sock, + UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); +} + + +int uv_tcp_getsockname(const uv_tcp_t* handle, + struct sockaddr* name, + int* namelen) { + + if (handle->delayed_error) + return handle->delayed_error; + + return uv__getsockpeername((const uv_handle_t*) handle, + getsockname, + name, + namelen); +} + + +int uv_tcp_getpeername(const uv_tcp_t* handle, + struct sockaddr* name, + int* namelen) { + + if (handle->delayed_error) + return handle->delayed_error; + + return uv__getsockpeername((const uv_handle_t*) handle, + getpeername, + name, + namelen); +} + + +int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) { + int fd; + struct linger l = { 1, 0 }; + + /* Disallow setting SO_LINGER to zero due to some platform inconsistencies */ + if (handle->flags & UV_HANDLE_SHUTTING) + return UV_EINVAL; + + fd = uv__stream_fd(handle); + if (0 != setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l))) + return UV__ERR(errno); + + uv_close((uv_handle_t*) handle, close_cb); + return 0; +} + + +int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) { + static int single_accept_cached = -1; + unsigned long flags; + int single_accept; + int err; + + if (tcp->delayed_error) + return tcp->delayed_error; + + single_accept = uv__load_relaxed(&single_accept_cached); + if (single_accept == -1) { + const char* val = getenv("UV_TCP_SINGLE_ACCEPT"); + single_accept = (val != NULL && atoi(val) != 0); /* Off by default. */ + uv__store_relaxed(&single_accept_cached, single_accept); + } + + if (single_accept) + tcp->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT; + + flags = 0; +#if defined(__MVS__) + /* on zOS the listen call does not bind automatically + if the socket is unbound. Hence the manual binding to + an arbitrary port is required to be done manually + */ + flags |= UV_HANDLE_BOUND; +#endif + err = maybe_new_socket(tcp, AF_INET, flags); + if (err) + return err; + + if (listen(tcp->io_watcher.fd, backlog)) + return UV__ERR(errno); + + tcp->connection_cb = cb; + tcp->flags |= UV_HANDLE_BOUND; + + /* Start listening for connections. */ + tcp->io_watcher.cb = uv__server_io; + uv__io_start(tcp->loop, &tcp->io_watcher, POLLIN); + + return 0; +} + + +int uv__tcp_nodelay(int fd, int on) { + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on))) + return UV__ERR(errno); + return 0; +} + + +int uv__tcp_keepalive(int fd, int on, unsigned int delay) { + if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on))) + return UV__ERR(errno); + +#ifdef TCP_KEEPIDLE + if (on) { + int intvl = 1; /* 1 second; same as default on Win32 */ + int cnt = 10; /* 10 retries; same as hardcoded on Win32 */ + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay))) + return UV__ERR(errno); + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl))) + return UV__ERR(errno); + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt))) + return UV__ERR(errno); + } +#endif + + /* Solaris/SmartOS, if you don't support keep-alive, + * then don't advertise it in your system headers... + */ + /* FIXME(bnoordhuis) That's possibly because sizeof(delay) should be 1. */ +#if defined(TCP_KEEPALIVE) && !defined(__sun) + if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay))) + return UV__ERR(errno); +#endif + + return 0; +} + + +int uv_tcp_nodelay(uv_tcp_t* handle, int on) { + int err; + + if (uv__stream_fd(handle) != -1) { + err = uv__tcp_nodelay(uv__stream_fd(handle), on); + if (err) + return err; + } + + if (on) + handle->flags |= UV_HANDLE_TCP_NODELAY; + else + handle->flags &= ~UV_HANDLE_TCP_NODELAY; + + return 0; +} + + +int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) { + int err; + + if (uv__stream_fd(handle) != -1) { + err =uv__tcp_keepalive(uv__stream_fd(handle), on, delay); + if (err) + return err; + } + + if (on) + handle->flags |= UV_HANDLE_TCP_KEEPALIVE; + else + handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE; + + /* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge + * uv_tcp_t with an int that's almost never used... + */ + + return 0; +} + + +int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) { + if (enable) + handle->flags &= ~UV_HANDLE_TCP_SINGLE_ACCEPT; + else + handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT; + return 0; +} + + +void uv__tcp_close(uv_tcp_t* handle) { + uv__stream_close((uv_stream_t*)handle); +} + + +int uv_socketpair(int type, int protocol, uv_os_sock_t fds[2], int flags0, int flags1) { + uv_os_sock_t temp[2]; + int err; +#if defined(__FreeBSD__) || defined(__linux__) + int flags; + + flags = type | SOCK_CLOEXEC; + if ((flags0 & UV_NONBLOCK_PIPE) && (flags1 & UV_NONBLOCK_PIPE)) + flags |= SOCK_NONBLOCK; + + if (socketpair(AF_UNIX, flags, protocol, temp)) + return UV__ERR(errno); + + if (flags & UV_FS_O_NONBLOCK) { + fds[0] = temp[0]; + fds[1] = temp[1]; + return 0; + } +#else + if (socketpair(AF_UNIX, type, protocol, temp)) + return UV__ERR(errno); + + if ((err = uv__cloexec(temp[0], 1))) + goto fail; + if ((err = uv__cloexec(temp[1], 1))) + goto fail; +#endif + + if (flags0 & UV_NONBLOCK_PIPE) + if ((err = uv__nonblock(temp[0], 1))) + goto fail; + if (flags1 & UV_NONBLOCK_PIPE) + if ((err = uv__nonblock(temp[1], 1))) + goto fail; + + fds[0] = temp[0]; + fds[1] = temp[1]; + return 0; + +fail: + uv__close(temp[0]); + uv__close(temp[1]); + return err; +} diff --git a/external/src/libuv/src/unix/thread.c b/external/src/libuv/src/unix/thread.c new file mode 100644 index 0000000..c46450c --- /dev/null +++ b/external/src/libuv/src/unix/thread.c @@ -0,0 +1,842 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include + +#include +#include /* getrlimit() */ +#include /* getpagesize() */ + +#include + +#ifdef __MVS__ +#include +#include +#endif + +#if defined(__GLIBC__) && !defined(__UCLIBC__) +#include /* gnu_get_libc_version() */ +#endif + +#undef NANOSEC +#define NANOSEC ((uint64_t) 1e9) + +#if defined(PTHREAD_BARRIER_SERIAL_THREAD) +STATIC_ASSERT(sizeof(uv_barrier_t) == sizeof(pthread_barrier_t)); +#endif + +/* Note: guard clauses should match uv_barrier_t's in include/uv/unix.h. */ +#if defined(_AIX) || \ + defined(__OpenBSD__) || \ + !defined(PTHREAD_BARRIER_SERIAL_THREAD) +int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) { + struct _uv_barrier* b; + int rc; + + if (barrier == NULL || count == 0) + return UV_EINVAL; + + b = uv__malloc(sizeof(*b)); + if (b == NULL) + return UV_ENOMEM; + + b->in = 0; + b->out = 0; + b->threshold = count; + + rc = uv_mutex_init(&b->mutex); + if (rc != 0) + goto error2; + + rc = uv_cond_init(&b->cond); + if (rc != 0) + goto error; + + barrier->b = b; + return 0; + +error: + uv_mutex_destroy(&b->mutex); +error2: + uv__free(b); + return rc; +} + + +int uv_barrier_wait(uv_barrier_t* barrier) { + struct _uv_barrier* b; + int last; + + if (barrier == NULL || barrier->b == NULL) + return UV_EINVAL; + + b = barrier->b; + uv_mutex_lock(&b->mutex); + + if (++b->in == b->threshold) { + b->in = 0; + b->out = b->threshold; + uv_cond_signal(&b->cond); + } else { + do + uv_cond_wait(&b->cond, &b->mutex); + while (b->in != 0); + } + + last = (--b->out == 0); + uv_cond_signal(&b->cond); + + uv_mutex_unlock(&b->mutex); + return last; +} + + +void uv_barrier_destroy(uv_barrier_t* barrier) { + struct _uv_barrier* b; + + b = barrier->b; + uv_mutex_lock(&b->mutex); + + assert(b->in == 0); + while (b->out != 0) + uv_cond_wait(&b->cond, &b->mutex); + + if (b->in != 0) + abort(); + + uv_mutex_unlock(&b->mutex); + uv_mutex_destroy(&b->mutex); + uv_cond_destroy(&b->cond); + + uv__free(barrier->b); + barrier->b = NULL; +} + +#else + +int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) { + return UV__ERR(pthread_barrier_init(barrier, NULL, count)); +} + + +int uv_barrier_wait(uv_barrier_t* barrier) { + int rc; + + rc = pthread_barrier_wait(barrier); + if (rc != 0) + if (rc != PTHREAD_BARRIER_SERIAL_THREAD) + abort(); + + return rc == PTHREAD_BARRIER_SERIAL_THREAD; +} + + +void uv_barrier_destroy(uv_barrier_t* barrier) { + if (pthread_barrier_destroy(barrier)) + abort(); +} + +#endif + + +/* On MacOS, threads other than the main thread are created with a reduced + * stack size by default. Adjust to RLIMIT_STACK aligned to the page size. + * + * On Linux, threads created by musl have a much smaller stack than threads + * created by glibc (80 vs. 2048 or 4096 kB.) Follow glibc for consistency. + */ +size_t uv__thread_stack_size(void) { +#if defined(__APPLE__) || defined(__linux__) + struct rlimit lim; + + /* getrlimit() can fail on some aarch64 systems due to a glibc bug where + * the system call wrapper invokes the wrong system call. Don't treat + * that as fatal, just use the default stack size instead. + */ + if (0 == getrlimit(RLIMIT_STACK, &lim) && lim.rlim_cur != RLIM_INFINITY) { + /* pthread_attr_setstacksize() expects page-aligned values. */ + lim.rlim_cur -= lim.rlim_cur % (rlim_t) getpagesize(); + + /* Musl's PTHREAD_STACK_MIN is 2 KB on all architectures, which is + * too small to safely receive signals on. + * + * Musl's PTHREAD_STACK_MIN + MINSIGSTKSZ == 8192 on arm64 (which has + * the largest MINSIGSTKSZ of the architectures that musl supports) so + * let's use that as a lower bound. + * + * We use a hardcoded value because PTHREAD_STACK_MIN + MINSIGSTKSZ + * is between 28 and 133 KB when compiling against glibc, depending + * on the architecture. + */ + if (lim.rlim_cur >= 8192) + if (lim.rlim_cur >= PTHREAD_STACK_MIN) + return lim.rlim_cur; + } +#endif + +#if !defined(__linux__) + return 0; +#elif defined(__PPC__) || defined(__ppc__) || defined(__powerpc__) + return 4 << 20; /* glibc default. */ +#else + return 2 << 20; /* glibc default. */ +#endif +} + + +int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) { + uv_thread_options_t params; + params.flags = UV_THREAD_NO_FLAGS; + return uv_thread_create_ex(tid, ¶ms, entry, arg); +} + +int uv_thread_create_ex(uv_thread_t* tid, + const uv_thread_options_t* params, + void (*entry)(void *arg), + void *arg) { + int err; + pthread_attr_t* attr; + pthread_attr_t attr_storage; + size_t pagesize; + size_t stack_size; + + /* Used to squelch a -Wcast-function-type warning. */ + union { + void (*in)(void*); + void* (*out)(void*); + } f; + + stack_size = + params->flags & UV_THREAD_HAS_STACK_SIZE ? params->stack_size : 0; + + attr = NULL; + if (stack_size == 0) { + stack_size = uv__thread_stack_size(); + } else { + pagesize = (size_t)getpagesize(); + /* Round up to the nearest page boundary. */ + stack_size = (stack_size + pagesize - 1) &~ (pagesize - 1); +#ifdef PTHREAD_STACK_MIN + if (stack_size < PTHREAD_STACK_MIN) + stack_size = PTHREAD_STACK_MIN; +#endif + } + + if (stack_size > 0) { + attr = &attr_storage; + + if (pthread_attr_init(attr)) + abort(); + + if (pthread_attr_setstacksize(attr, stack_size)) + abort(); + } + + f.in = entry; + err = pthread_create(tid, attr, f.out, arg); + + if (attr != NULL) + pthread_attr_destroy(attr); + + return UV__ERR(err); +} + + +uv_thread_t uv_thread_self(void) { + return pthread_self(); +} + +int uv_thread_join(uv_thread_t *tid) { + return UV__ERR(pthread_join(*tid, NULL)); +} + + +int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) { + return pthread_equal(*t1, *t2); +} + + +int uv_mutex_init(uv_mutex_t* mutex) { +#if defined(NDEBUG) || !defined(PTHREAD_MUTEX_ERRORCHECK) + return UV__ERR(pthread_mutex_init(mutex, NULL)); +#else + pthread_mutexattr_t attr; + int err; + + if (pthread_mutexattr_init(&attr)) + abort(); + + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK)) + abort(); + + err = pthread_mutex_init(mutex, &attr); + + if (pthread_mutexattr_destroy(&attr)) + abort(); + + return UV__ERR(err); +#endif +} + + +int uv_mutex_init_recursive(uv_mutex_t* mutex) { + pthread_mutexattr_t attr; + int err; + + if (pthread_mutexattr_init(&attr)) + abort(); + + if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) + abort(); + + err = pthread_mutex_init(mutex, &attr); + + if (pthread_mutexattr_destroy(&attr)) + abort(); + + return UV__ERR(err); +} + + +void uv_mutex_destroy(uv_mutex_t* mutex) { + if (pthread_mutex_destroy(mutex)) + abort(); +} + + +void uv_mutex_lock(uv_mutex_t* mutex) { + if (pthread_mutex_lock(mutex)) + abort(); +} + + +int uv_mutex_trylock(uv_mutex_t* mutex) { + int err; + + err = pthread_mutex_trylock(mutex); + if (err) { + if (err != EBUSY && err != EAGAIN) + abort(); + return UV_EBUSY; + } + + return 0; +} + + +void uv_mutex_unlock(uv_mutex_t* mutex) { + if (pthread_mutex_unlock(mutex)) + abort(); +} + + +int uv_rwlock_init(uv_rwlock_t* rwlock) { + return UV__ERR(pthread_rwlock_init(rwlock, NULL)); +} + + +void uv_rwlock_destroy(uv_rwlock_t* rwlock) { + if (pthread_rwlock_destroy(rwlock)) + abort(); +} + + +void uv_rwlock_rdlock(uv_rwlock_t* rwlock) { + if (pthread_rwlock_rdlock(rwlock)) + abort(); +} + + +int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) { + int err; + + err = pthread_rwlock_tryrdlock(rwlock); + if (err) { + if (err != EBUSY && err != EAGAIN) + abort(); + return UV_EBUSY; + } + + return 0; +} + + +void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) { + if (pthread_rwlock_unlock(rwlock)) + abort(); +} + + +void uv_rwlock_wrlock(uv_rwlock_t* rwlock) { + if (pthread_rwlock_wrlock(rwlock)) + abort(); +} + + +int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) { + int err; + + err = pthread_rwlock_trywrlock(rwlock); + if (err) { + if (err != EBUSY && err != EAGAIN) + abort(); + return UV_EBUSY; + } + + return 0; +} + + +void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) { + if (pthread_rwlock_unlock(rwlock)) + abort(); +} + + +void uv_once(uv_once_t* guard, void (*callback)(void)) { + if (pthread_once(guard, callback)) + abort(); +} + +#if defined(__APPLE__) && defined(__MACH__) + +int uv_sem_init(uv_sem_t* sem, unsigned int value) { + kern_return_t err; + + err = semaphore_create(mach_task_self(), sem, SYNC_POLICY_FIFO, value); + if (err == KERN_SUCCESS) + return 0; + if (err == KERN_INVALID_ARGUMENT) + return UV_EINVAL; + if (err == KERN_RESOURCE_SHORTAGE) + return UV_ENOMEM; + + abort(); + return UV_EINVAL; /* Satisfy the compiler. */ +} + + +void uv_sem_destroy(uv_sem_t* sem) { + if (semaphore_destroy(mach_task_self(), *sem)) + abort(); +} + + +void uv_sem_post(uv_sem_t* sem) { + if (semaphore_signal(*sem)) + abort(); +} + + +void uv_sem_wait(uv_sem_t* sem) { + int r; + + do + r = semaphore_wait(*sem); + while (r == KERN_ABORTED); + + if (r != KERN_SUCCESS) + abort(); +} + + +int uv_sem_trywait(uv_sem_t* sem) { + mach_timespec_t interval; + kern_return_t err; + + interval.tv_sec = 0; + interval.tv_nsec = 0; + + err = semaphore_timedwait(*sem, interval); + if (err == KERN_SUCCESS) + return 0; + if (err == KERN_OPERATION_TIMED_OUT) + return UV_EAGAIN; + + abort(); + return UV_EINVAL; /* Satisfy the compiler. */ +} + +#else /* !(defined(__APPLE__) && defined(__MACH__)) */ + +#if defined(__GLIBC__) && !defined(__UCLIBC__) + +/* Hack around https://sourceware.org/bugzilla/show_bug.cgi?id=12674 + * by providing a custom implementation for glibc < 2.21 in terms of other + * concurrency primitives. + * Refs: https://github.com/nodejs/node/issues/19903 */ + +/* To preserve ABI compatibility, we treat the uv_sem_t as storage for + * a pointer to the actual struct we're using underneath. */ + +static uv_once_t glibc_version_check_once = UV_ONCE_INIT; +static int platform_needs_custom_semaphore = 0; + +static void glibc_version_check(void) { + const char* version = gnu_get_libc_version(); + platform_needs_custom_semaphore = + version[0] == '2' && version[1] == '.' && + atoi(version + 2) < 21; +} + +#elif defined(__MVS__) + +#define platform_needs_custom_semaphore 1 + +#else /* !defined(__GLIBC__) && !defined(__MVS__) */ + +#define platform_needs_custom_semaphore 0 + +#endif + +typedef struct uv_semaphore_s { + uv_mutex_t mutex; + uv_cond_t cond; + unsigned int value; +} uv_semaphore_t; + +#if (defined(__GLIBC__) && !defined(__UCLIBC__)) || \ + platform_needs_custom_semaphore +STATIC_ASSERT(sizeof(uv_sem_t) >= sizeof(uv_semaphore_t*)); +#endif + +static int uv__custom_sem_init(uv_sem_t* sem_, unsigned int value) { + int err; + uv_semaphore_t* sem; + + sem = uv__malloc(sizeof(*sem)); + if (sem == NULL) + return UV_ENOMEM; + + if ((err = uv_mutex_init(&sem->mutex)) != 0) { + uv__free(sem); + return err; + } + + if ((err = uv_cond_init(&sem->cond)) != 0) { + uv_mutex_destroy(&sem->mutex); + uv__free(sem); + return err; + } + + sem->value = value; + *(uv_semaphore_t**)sem_ = sem; + return 0; +} + + +static void uv__custom_sem_destroy(uv_sem_t* sem_) { + uv_semaphore_t* sem; + + sem = *(uv_semaphore_t**)sem_; + uv_cond_destroy(&sem->cond); + uv_mutex_destroy(&sem->mutex); + uv__free(sem); +} + + +static void uv__custom_sem_post(uv_sem_t* sem_) { + uv_semaphore_t* sem; + + sem = *(uv_semaphore_t**)sem_; + uv_mutex_lock(&sem->mutex); + sem->value++; + if (sem->value == 1) + uv_cond_signal(&sem->cond); + uv_mutex_unlock(&sem->mutex); +} + + +static void uv__custom_sem_wait(uv_sem_t* sem_) { + uv_semaphore_t* sem; + + sem = *(uv_semaphore_t**)sem_; + uv_mutex_lock(&sem->mutex); + while (sem->value == 0) + uv_cond_wait(&sem->cond, &sem->mutex); + sem->value--; + uv_mutex_unlock(&sem->mutex); +} + + +static int uv__custom_sem_trywait(uv_sem_t* sem_) { + uv_semaphore_t* sem; + + sem = *(uv_semaphore_t**)sem_; + if (uv_mutex_trylock(&sem->mutex) != 0) + return UV_EAGAIN; + + if (sem->value == 0) { + uv_mutex_unlock(&sem->mutex); + return UV_EAGAIN; + } + + sem->value--; + uv_mutex_unlock(&sem->mutex); + + return 0; +} + +static int uv__sem_init(uv_sem_t* sem, unsigned int value) { + if (sem_init(sem, 0, value)) + return UV__ERR(errno); + return 0; +} + + +static void uv__sem_destroy(uv_sem_t* sem) { + if (sem_destroy(sem)) + abort(); +} + + +static void uv__sem_post(uv_sem_t* sem) { + if (sem_post(sem)) + abort(); +} + + +static void uv__sem_wait(uv_sem_t* sem) { + int r; + + do + r = sem_wait(sem); + while (r == -1 && errno == EINTR); + + if (r) + abort(); +} + + +static int uv__sem_trywait(uv_sem_t* sem) { + int r; + + do + r = sem_trywait(sem); + while (r == -1 && errno == EINTR); + + if (r) { + if (errno == EAGAIN) + return UV_EAGAIN; + abort(); + } + + return 0; +} + +int uv_sem_init(uv_sem_t* sem, unsigned int value) { +#if defined(__GLIBC__) && !defined(__UCLIBC__) + uv_once(&glibc_version_check_once, glibc_version_check); +#endif + + if (platform_needs_custom_semaphore) + return uv__custom_sem_init(sem, value); + else + return uv__sem_init(sem, value); +} + + +void uv_sem_destroy(uv_sem_t* sem) { + if (platform_needs_custom_semaphore) + uv__custom_sem_destroy(sem); + else + uv__sem_destroy(sem); +} + + +void uv_sem_post(uv_sem_t* sem) { + if (platform_needs_custom_semaphore) + uv__custom_sem_post(sem); + else + uv__sem_post(sem); +} + + +void uv_sem_wait(uv_sem_t* sem) { + if (platform_needs_custom_semaphore) + uv__custom_sem_wait(sem); + else + uv__sem_wait(sem); +} + + +int uv_sem_trywait(uv_sem_t* sem) { + if (platform_needs_custom_semaphore) + return uv__custom_sem_trywait(sem); + else + return uv__sem_trywait(sem); +} + +#endif /* defined(__APPLE__) && defined(__MACH__) */ + + +#if defined(__APPLE__) && defined(__MACH__) || defined(__MVS__) + +int uv_cond_init(uv_cond_t* cond) { + return UV__ERR(pthread_cond_init(cond, NULL)); +} + +#else /* !(defined(__APPLE__) && defined(__MACH__)) */ + +int uv_cond_init(uv_cond_t* cond) { + pthread_condattr_t attr; + int err; + + err = pthread_condattr_init(&attr); + if (err) + return UV__ERR(err); + + err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); + if (err) + goto error2; + + err = pthread_cond_init(cond, &attr); + if (err) + goto error2; + + err = pthread_condattr_destroy(&attr); + if (err) + goto error; + + return 0; + +error: + pthread_cond_destroy(cond); +error2: + pthread_condattr_destroy(&attr); + return UV__ERR(err); +} + +#endif /* defined(__APPLE__) && defined(__MACH__) */ + +void uv_cond_destroy(uv_cond_t* cond) { +#if defined(__APPLE__) && defined(__MACH__) + /* It has been reported that destroying condition variables that have been + * signalled but not waited on can sometimes result in application crashes. + * See https://codereview.chromium.org/1323293005. + */ + pthread_mutex_t mutex; + struct timespec ts; + int err; + + if (pthread_mutex_init(&mutex, NULL)) + abort(); + + if (pthread_mutex_lock(&mutex)) + abort(); + + ts.tv_sec = 0; + ts.tv_nsec = 1; + + err = pthread_cond_timedwait_relative_np(cond, &mutex, &ts); + if (err != 0 && err != ETIMEDOUT) + abort(); + + if (pthread_mutex_unlock(&mutex)) + abort(); + + if (pthread_mutex_destroy(&mutex)) + abort(); +#endif /* defined(__APPLE__) && defined(__MACH__) */ + + if (pthread_cond_destroy(cond)) + abort(); +} + +void uv_cond_signal(uv_cond_t* cond) { + if (pthread_cond_signal(cond)) + abort(); +} + +void uv_cond_broadcast(uv_cond_t* cond) { + if (pthread_cond_broadcast(cond)) + abort(); +} + +void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) { + if (pthread_cond_wait(cond, mutex)) + abort(); +} + + +int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) { + int r; + struct timespec ts; +#if defined(__MVS__) + struct timeval tv; +#endif + +#if defined(__APPLE__) && defined(__MACH__) + ts.tv_sec = timeout / NANOSEC; + ts.tv_nsec = timeout % NANOSEC; + r = pthread_cond_timedwait_relative_np(cond, mutex, &ts); +#else +#if defined(__MVS__) + if (gettimeofday(&tv, NULL)) + abort(); + timeout += tv.tv_sec * NANOSEC + tv.tv_usec * 1e3; +#else + timeout += uv__hrtime(UV_CLOCK_PRECISE); +#endif + ts.tv_sec = timeout / NANOSEC; + ts.tv_nsec = timeout % NANOSEC; + r = pthread_cond_timedwait(cond, mutex, &ts); +#endif + + + if (r == 0) + return 0; + + if (r == ETIMEDOUT) + return UV_ETIMEDOUT; + + abort(); +#ifndef __SUNPRO_C + return UV_EINVAL; /* Satisfy the compiler. */ +#endif +} + + +int uv_key_create(uv_key_t* key) { + return UV__ERR(pthread_key_create(key, NULL)); +} + + +void uv_key_delete(uv_key_t* key) { + if (pthread_key_delete(*key)) + abort(); +} + + +void* uv_key_get(uv_key_t* key) { + return pthread_getspecific(*key); +} + + +void uv_key_set(uv_key_t* key, void* value) { + if (pthread_setspecific(*key, value)) + abort(); +} diff --git a/external/src/libuv/src/unix/tty.c b/external/src/libuv/src/unix/tty.c new file mode 100644 index 0000000..9442cf1 --- /dev/null +++ b/external/src/libuv/src/unix/tty.c @@ -0,0 +1,420 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" +#include "spinlock.h" + +#include +#include +#include +#include +#include +#include + +#if defined(__MVS__) && !defined(IMAXBEL) +#define IMAXBEL 0 +#endif + +#if defined(__PASE__) +/* On IBM i PASE, for better compatibility with running interactive programs in + * a 5250 environment, isatty() will return true for the stdin/stdout/stderr + * streams created by QSH/QP2TERM. + * + * For more, see docs on PASE_STDIO_ISATTY in + * https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_74/apis/pase_environ.htm + * + * This behavior causes problems for Node as it expects that if isatty() returns + * true that TTY ioctls will be supported by that fd (which is not an + * unreasonable expectation) and when they don't it crashes with assertion + * errors. + * + * Here, we create our own version of isatty() that uses ioctl() to identify + * whether the fd is *really* a TTY or not. + */ +static int isreallyatty(int file) { + int rc; + + rc = !ioctl(file, TXISATTY + 0x81, NULL); + if (!rc && errno != EBADF) + errno = ENOTTY; + + return rc; +} +#define isatty(fd) isreallyatty(fd) +#endif + +static int orig_termios_fd = -1; +static struct termios orig_termios; +static uv_spinlock_t termios_spinlock = UV_SPINLOCK_INITIALIZER; + +static int uv__tty_is_slave(const int fd) { + int result; +#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + int dummy; + + result = ioctl(fd, TIOCGPTN, &dummy) != 0; +#elif defined(__APPLE__) + char dummy[256]; + + result = ioctl(fd, TIOCPTYGNAME, &dummy) != 0; +#elif defined(__NetBSD__) + /* + * NetBSD as an extension returns with ptsname(3) and ptsname_r(3) the slave + * device name for both descriptors, the master one and slave one. + * + * Implement function to compare major device number with pts devices. + * + * The major numbers are machine-dependent, on NetBSD/amd64 they are + * respectively: + * - master tty: ptc - major 6 + * - slave tty: pts - major 5 + */ + + struct stat sb; + /* Lookup device's major for the pts driver and cache it. */ + static devmajor_t pts = NODEVMAJOR; + + if (pts == NODEVMAJOR) { + pts = getdevmajor("pts", S_IFCHR); + if (pts == NODEVMAJOR) + abort(); + } + + /* Lookup stat structure behind the file descriptor. */ + if (fstat(fd, &sb) != 0) + abort(); + + /* Assert character device. */ + if (!S_ISCHR(sb.st_mode)) + abort(); + + /* Assert valid major. */ + if (major(sb.st_rdev) == NODEVMAJOR) + abort(); + + result = (pts == major(sb.st_rdev)); +#else + /* Fallback to ptsname + */ + result = ptsname(fd) == NULL; +#endif + return result; +} + +int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int unused) { + uv_handle_type type; + int flags; + int newfd; + int r; + int saved_flags; + int mode; + char path[256]; + (void)unused; /* deprecated parameter is no longer needed */ + + /* File descriptors that refer to files cannot be monitored with epoll. + * That restriction also applies to character devices like /dev/random + * (but obviously not /dev/tty.) + */ + type = uv_guess_handle(fd); + if (type == UV_FILE || type == UV_UNKNOWN_HANDLE) + return UV_EINVAL; + + flags = 0; + newfd = -1; + + /* Save the fd flags in case we need to restore them due to an error. */ + do + saved_flags = fcntl(fd, F_GETFL); + while (saved_flags == -1 && errno == EINTR); + + if (saved_flags == -1) + return UV__ERR(errno); + mode = saved_flags & O_ACCMODE; + + /* Reopen the file descriptor when it refers to a tty. This lets us put the + * tty in non-blocking mode without affecting other processes that share it + * with us. + * + * Example: `node | cat` - if we put our fd 0 in non-blocking mode, it also + * affects fd 1 of `cat` because both file descriptors refer to the same + * struct file in the kernel. When we reopen our fd 0, it points to a + * different struct file, hence changing its properties doesn't affect + * other processes. + */ + if (type == UV_TTY) { + /* Reopening a pty in master mode won't work either because the reopened + * pty will be in slave mode (*BSD) or reopening will allocate a new + * master/slave pair (Linux). Therefore check if the fd points to a + * slave device. + */ + if (uv__tty_is_slave(fd) && ttyname_r(fd, path, sizeof(path)) == 0) + r = uv__open_cloexec(path, mode | O_NOCTTY); + else + r = -1; + + if (r < 0) { + /* fallback to using blocking writes */ + if (mode != O_RDONLY) + flags |= UV_HANDLE_BLOCKING_WRITES; + goto skip; + } + + newfd = r; + + r = uv__dup2_cloexec(newfd, fd); + if (r < 0 && r != UV_EINVAL) { + /* EINVAL means newfd == fd which could conceivably happen if another + * thread called close(fd) between our calls to isatty() and open(). + * That's a rather unlikely event but let's handle it anyway. + */ + uv__close(newfd); + return r; + } + + fd = newfd; + } + +skip: + uv__stream_init(loop, (uv_stream_t*) tty, UV_TTY); + + /* If anything fails beyond this point we need to remove the handle from + * the handle queue, since it was added by uv__handle_init in uv_stream_init. + */ + + if (!(flags & UV_HANDLE_BLOCKING_WRITES)) + uv__nonblock(fd, 1); + +#if defined(__APPLE__) + r = uv__stream_try_select((uv_stream_t*) tty, &fd); + if (r) { + int rc = r; + if (newfd != -1) + uv__close(newfd); + QUEUE_REMOVE(&tty->handle_queue); + do + r = fcntl(fd, F_SETFL, saved_flags); + while (r == -1 && errno == EINTR); + return rc; + } +#endif + + if (mode != O_WRONLY) + flags |= UV_HANDLE_READABLE; + if (mode != O_RDONLY) + flags |= UV_HANDLE_WRITABLE; + + uv__stream_open((uv_stream_t*) tty, fd, flags); + tty->mode = UV_TTY_MODE_NORMAL; + + return 0; +} + +static void uv__tty_make_raw(struct termios* tio) { + assert(tio != NULL); + +#if defined __sun || defined __MVS__ + /* + * This implementation of cfmakeraw for Solaris and derivatives is taken from + * http://www.perkin.org.uk/posts/solaris-portability-cfmakeraw.html. + */ + tio->c_iflag &= ~(IMAXBEL | IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | + IGNCR | ICRNL | IXON); + tio->c_oflag &= ~OPOST; + tio->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); + tio->c_cflag &= ~(CSIZE | PARENB); + tio->c_cflag |= CS8; + + /* + * By default, most software expects a pending read to block until at + * least one byte becomes available. As per termio(7I), this requires + * setting the MIN and TIME parameters appropriately. + * + * As a somewhat unfortunate artifact of history, the MIN and TIME slots + * in the control character array overlap with the EOF and EOL slots used + * for canonical mode processing. Because the EOF character needs to be + * the ASCII EOT value (aka Control-D), it has the byte value 4. When + * switching to raw mode, this is interpreted as a MIN value of 4; i.e., + * reads will block until at least four bytes have been input. + * + * Other platforms with a distinct MIN slot like Linux and FreeBSD appear + * to default to a MIN value of 1, so we'll force that value here: + */ + tio->c_cc[VMIN] = 1; + tio->c_cc[VTIME] = 0; +#else + cfmakeraw(tio); +#endif /* #ifdef __sun */ +} + +int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) { + struct termios tmp; + int fd; + + if (tty->mode == (int) mode) + return 0; + + fd = uv__stream_fd(tty); + if (tty->mode == UV_TTY_MODE_NORMAL && mode != UV_TTY_MODE_NORMAL) { + if (tcgetattr(fd, &tty->orig_termios)) + return UV__ERR(errno); + + /* This is used for uv_tty_reset_mode() */ + uv_spinlock_lock(&termios_spinlock); + if (orig_termios_fd == -1) { + orig_termios = tty->orig_termios; + orig_termios_fd = fd; + } + uv_spinlock_unlock(&termios_spinlock); + } + + tmp = tty->orig_termios; + switch (mode) { + case UV_TTY_MODE_NORMAL: + break; + case UV_TTY_MODE_RAW: + tmp.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); + tmp.c_oflag |= (ONLCR); + tmp.c_cflag |= (CS8); + tmp.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); + tmp.c_cc[VMIN] = 1; + tmp.c_cc[VTIME] = 0; + break; + case UV_TTY_MODE_IO: + uv__tty_make_raw(&tmp); + break; + } + + /* Apply changes after draining */ + if (tcsetattr(fd, TCSADRAIN, &tmp)) + return UV__ERR(errno); + + tty->mode = mode; + return 0; +} + + +int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) { + struct winsize ws; + int err; + + do + err = ioctl(uv__stream_fd(tty), TIOCGWINSZ, &ws); + while (err == -1 && errno == EINTR); + + if (err == -1) + return UV__ERR(errno); + + *width = ws.ws_col; + *height = ws.ws_row; + + return 0; +} + + +uv_handle_type uv_guess_handle(uv_file file) { + struct sockaddr sa; + struct stat s; + socklen_t len; + int type; + + if (file < 0) + return UV_UNKNOWN_HANDLE; + + if (isatty(file)) + return UV_TTY; + + if (fstat(file, &s)) + return UV_UNKNOWN_HANDLE; + + if (S_ISREG(s.st_mode)) + return UV_FILE; + + if (S_ISCHR(s.st_mode)) + return UV_FILE; /* XXX UV_NAMED_PIPE? */ + + if (S_ISFIFO(s.st_mode)) + return UV_NAMED_PIPE; + + if (!S_ISSOCK(s.st_mode)) + return UV_UNKNOWN_HANDLE; + + len = sizeof(type); + if (getsockopt(file, SOL_SOCKET, SO_TYPE, &type, &len)) + return UV_UNKNOWN_HANDLE; + + len = sizeof(sa); + if (getsockname(file, &sa, &len)) + return UV_UNKNOWN_HANDLE; + + if (type == SOCK_DGRAM) + if (sa.sa_family == AF_INET || sa.sa_family == AF_INET6) + return UV_UDP; + + if (type == SOCK_STREAM) { +#if defined(_AIX) || defined(__DragonFly__) + /* on AIX/DragonFly the getsockname call returns an empty sa structure + * for sockets of type AF_UNIX. For all other types it will + * return a properly filled in structure. + */ + if (len == 0) + return UV_NAMED_PIPE; +#endif /* defined(_AIX) || defined(__DragonFly__) */ + + if (sa.sa_family == AF_INET || sa.sa_family == AF_INET6) + return UV_TCP; + if (sa.sa_family == AF_UNIX) + return UV_NAMED_PIPE; + } + + return UV_UNKNOWN_HANDLE; +} + + +/* This function is async signal-safe, meaning that it's safe to call from + * inside a signal handler _unless_ execution was inside uv_tty_set_mode()'s + * critical section when the signal was raised. + */ +int uv_tty_reset_mode(void) { + int saved_errno; + int err; + + saved_errno = errno; + if (!uv_spinlock_trylock(&termios_spinlock)) + return UV_EBUSY; /* In uv_tty_set_mode(). */ + + err = 0; + if (orig_termios_fd != -1) + if (tcsetattr(orig_termios_fd, TCSANOW, &orig_termios)) + err = UV__ERR(errno); + + uv_spinlock_unlock(&termios_spinlock); + errno = saved_errno; + + return err; +} + +void uv_tty_set_vterm_state(uv_tty_vtermstate_t state) { +} + +int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state) { + return UV_ENOTSUP; +} diff --git a/external/src/libuv/src/unix/udp.c b/external/src/libuv/src/unix/udp.c new file mode 100644 index 0000000..49051c0 --- /dev/null +++ b/external/src/libuv/src/unix/udp.c @@ -0,0 +1,1358 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include +#if defined(__MVS__) +#include +#endif +#include + +#if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP) +# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP +#endif + +#if defined(IPV6_LEAVE_GROUP) && !defined(IPV6_DROP_MEMBERSHIP) +# define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP +#endif + +union uv__sockaddr { + struct sockaddr_in6 in6; + struct sockaddr_in in; + struct sockaddr addr; +}; + +static void uv__udp_run_completed(uv_udp_t* handle); +static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents); +static void uv__udp_recvmsg(uv_udp_t* handle); +static void uv__udp_sendmsg(uv_udp_t* handle); +static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, + int domain, + unsigned int flags); + +#if HAVE_MMSG + +#define UV__MMSG_MAXWIDTH 20 + +static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf); +static void uv__udp_sendmmsg(uv_udp_t* handle); + +static int uv__recvmmsg_avail; +static int uv__sendmmsg_avail; +static uv_once_t once = UV_ONCE_INIT; + +static void uv__udp_mmsg_init(void) { + int ret; + int s; + s = uv__socket(AF_INET, SOCK_DGRAM, 0); + if (s < 0) + return; + ret = uv__sendmmsg(s, NULL, 0); + if (ret == 0 || errno != ENOSYS) { + uv__sendmmsg_avail = 1; + uv__recvmmsg_avail = 1; + } else { + ret = uv__recvmmsg(s, NULL, 0); + if (ret == 0 || errno != ENOSYS) + uv__recvmmsg_avail = 1; + } + uv__close(s); +} + +#endif + +void uv__udp_close(uv_udp_t* handle) { + uv__io_close(handle->loop, &handle->io_watcher); + uv__handle_stop(handle); + + if (handle->io_watcher.fd != -1) { + uv__close(handle->io_watcher.fd); + handle->io_watcher.fd = -1; + } +} + + +void uv__udp_finish_close(uv_udp_t* handle) { + uv_udp_send_t* req; + QUEUE* q; + + assert(!uv__io_active(&handle->io_watcher, POLLIN | POLLOUT)); + assert(handle->io_watcher.fd == -1); + + while (!QUEUE_EMPTY(&handle->write_queue)) { + q = QUEUE_HEAD(&handle->write_queue); + QUEUE_REMOVE(q); + + req = QUEUE_DATA(q, uv_udp_send_t, queue); + req->status = UV_ECANCELED; + QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue); + } + + uv__udp_run_completed(handle); + + assert(handle->send_queue_size == 0); + assert(handle->send_queue_count == 0); + + /* Now tear down the handle. */ + handle->recv_cb = NULL; + handle->alloc_cb = NULL; + /* but _do not_ touch close_cb */ +} + + +static void uv__udp_run_completed(uv_udp_t* handle) { + uv_udp_send_t* req; + QUEUE* q; + + assert(!(handle->flags & UV_HANDLE_UDP_PROCESSING)); + handle->flags |= UV_HANDLE_UDP_PROCESSING; + + while (!QUEUE_EMPTY(&handle->write_completed_queue)) { + q = QUEUE_HEAD(&handle->write_completed_queue); + QUEUE_REMOVE(q); + + req = QUEUE_DATA(q, uv_udp_send_t, queue); + uv__req_unregister(handle->loop, req); + + handle->send_queue_size -= uv__count_bufs(req->bufs, req->nbufs); + handle->send_queue_count--; + + if (req->bufs != req->bufsml) + uv__free(req->bufs); + req->bufs = NULL; + + if (req->send_cb == NULL) + continue; + + /* req->status >= 0 == bytes written + * req->status < 0 == errno + */ + if (req->status >= 0) + req->send_cb(req, 0); + else + req->send_cb(req, req->status); + } + + if (QUEUE_EMPTY(&handle->write_queue)) { + /* Pending queue and completion queue empty, stop watcher. */ + uv__io_stop(handle->loop, &handle->io_watcher, POLLOUT); + if (!uv__io_active(&handle->io_watcher, POLLIN)) + uv__handle_stop(handle); + } + + handle->flags &= ~UV_HANDLE_UDP_PROCESSING; +} + + +static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) { + uv_udp_t* handle; + + handle = container_of(w, uv_udp_t, io_watcher); + assert(handle->type == UV_UDP); + + if (revents & POLLIN) + uv__udp_recvmsg(handle); + + if (revents & POLLOUT) { + uv__udp_sendmsg(handle); + uv__udp_run_completed(handle); + } +} + +#if HAVE_MMSG +static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) { + struct sockaddr_in6 peers[UV__MMSG_MAXWIDTH]; + struct iovec iov[UV__MMSG_MAXWIDTH]; + struct uv__mmsghdr msgs[UV__MMSG_MAXWIDTH]; + ssize_t nread; + uv_buf_t chunk_buf; + size_t chunks; + int flags; + size_t k; + + /* prepare structures for recvmmsg */ + chunks = buf->len / UV__UDP_DGRAM_MAXSIZE; + if (chunks > ARRAY_SIZE(iov)) + chunks = ARRAY_SIZE(iov); + for (k = 0; k < chunks; ++k) { + iov[k].iov_base = buf->base + k * UV__UDP_DGRAM_MAXSIZE; + iov[k].iov_len = UV__UDP_DGRAM_MAXSIZE; + msgs[k].msg_hdr.msg_iov = iov + k; + msgs[k].msg_hdr.msg_iovlen = 1; + msgs[k].msg_hdr.msg_name = peers + k; + msgs[k].msg_hdr.msg_namelen = sizeof(peers[0]); + msgs[k].msg_hdr.msg_control = NULL; + msgs[k].msg_hdr.msg_controllen = 0; + msgs[k].msg_hdr.msg_flags = 0; + } + + do + nread = uv__recvmmsg(handle->io_watcher.fd, msgs, chunks); + while (nread == -1 && errno == EINTR); + + if (nread < 1) { + if (nread == 0 || errno == EAGAIN || errno == EWOULDBLOCK) + handle->recv_cb(handle, 0, buf, NULL, 0); + else + handle->recv_cb(handle, UV__ERR(errno), buf, NULL, 0); + } else { + /* pass each chunk to the application */ + for (k = 0; k < (size_t) nread && handle->recv_cb != NULL; k++) { + flags = UV_UDP_MMSG_CHUNK; + if (msgs[k].msg_hdr.msg_flags & MSG_TRUNC) + flags |= UV_UDP_PARTIAL; + + chunk_buf = uv_buf_init(iov[k].iov_base, iov[k].iov_len); + handle->recv_cb(handle, + msgs[k].msg_len, + &chunk_buf, + msgs[k].msg_hdr.msg_name, + flags); + } + + /* one last callback so the original buffer is freed */ + if (handle->recv_cb != NULL) + handle->recv_cb(handle, 0, buf, NULL, UV_UDP_MMSG_FREE); + } + return nread; +} +#endif + +static void uv__udp_recvmsg(uv_udp_t* handle) { + struct sockaddr_storage peer; + struct msghdr h; + ssize_t nread; + uv_buf_t buf; + int flags; + int count; + + assert(handle->recv_cb != NULL); + assert(handle->alloc_cb != NULL); + + /* Prevent loop starvation when the data comes in as fast as (or faster than) + * we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O. + */ + count = 32; + + do { + buf = uv_buf_init(NULL, 0); + handle->alloc_cb((uv_handle_t*) handle, UV__UDP_DGRAM_MAXSIZE, &buf); + if (buf.base == NULL || buf.len == 0) { + handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0); + return; + } + assert(buf.base != NULL); + +#if HAVE_MMSG + if (uv_udp_using_recvmmsg(handle)) { + nread = uv__udp_recvmmsg(handle, &buf); + if (nread > 0) + count -= nread; + continue; + } +#endif + + memset(&h, 0, sizeof(h)); + memset(&peer, 0, sizeof(peer)); + h.msg_name = &peer; + h.msg_namelen = sizeof(peer); + h.msg_iov = (void*) &buf; + h.msg_iovlen = 1; + + do { + nread = recvmsg(handle->io_watcher.fd, &h, 0); + } + while (nread == -1 && errno == EINTR); + + if (nread == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) + handle->recv_cb(handle, 0, &buf, NULL, 0); + else + handle->recv_cb(handle, UV__ERR(errno), &buf, NULL, 0); + } + else { + flags = 0; + if (h.msg_flags & MSG_TRUNC) + flags |= UV_UDP_PARTIAL; + + handle->recv_cb(handle, nread, &buf, (const struct sockaddr*) &peer, flags); + } + count--; + } + /* recv_cb callback may decide to pause or close the handle */ + while (nread != -1 + && count > 0 + && handle->io_watcher.fd != -1 + && handle->recv_cb != NULL); +} + +#if HAVE_MMSG +static void uv__udp_sendmmsg(uv_udp_t* handle) { + uv_udp_send_t* req; + struct uv__mmsghdr h[UV__MMSG_MAXWIDTH]; + struct uv__mmsghdr *p; + QUEUE* q; + ssize_t npkts; + size_t pkts; + size_t i; + + if (QUEUE_EMPTY(&handle->write_queue)) + return; + +write_queue_drain: + for (pkts = 0, q = QUEUE_HEAD(&handle->write_queue); + pkts < UV__MMSG_MAXWIDTH && q != &handle->write_queue; + ++pkts, q = QUEUE_HEAD(q)) { + assert(q != NULL); + req = QUEUE_DATA(q, uv_udp_send_t, queue); + assert(req != NULL); + + p = &h[pkts]; + memset(p, 0, sizeof(*p)); + if (req->addr.ss_family == AF_UNSPEC) { + p->msg_hdr.msg_name = NULL; + p->msg_hdr.msg_namelen = 0; + } else { + p->msg_hdr.msg_name = &req->addr; + if (req->addr.ss_family == AF_INET6) + p->msg_hdr.msg_namelen = sizeof(struct sockaddr_in6); + else if (req->addr.ss_family == AF_INET) + p->msg_hdr.msg_namelen = sizeof(struct sockaddr_in); + else if (req->addr.ss_family == AF_UNIX) + p->msg_hdr.msg_namelen = sizeof(struct sockaddr_un); + else { + assert(0 && "unsupported address family"); + abort(); + } + } + h[pkts].msg_hdr.msg_iov = (struct iovec*) req->bufs; + h[pkts].msg_hdr.msg_iovlen = req->nbufs; + } + + do + npkts = uv__sendmmsg(handle->io_watcher.fd, h, pkts); + while (npkts == -1 && errno == EINTR); + + if (npkts < 1) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS) + return; + for (i = 0, q = QUEUE_HEAD(&handle->write_queue); + i < pkts && q != &handle->write_queue; + ++i, q = QUEUE_HEAD(&handle->write_queue)) { + assert(q != NULL); + req = QUEUE_DATA(q, uv_udp_send_t, queue); + assert(req != NULL); + + req->status = UV__ERR(errno); + QUEUE_REMOVE(&req->queue); + QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue); + } + uv__io_feed(handle->loop, &handle->io_watcher); + return; + } + + for (i = 0, q = QUEUE_HEAD(&handle->write_queue); + i < pkts && q != &handle->write_queue; + ++i, q = QUEUE_HEAD(&handle->write_queue)) { + assert(q != NULL); + req = QUEUE_DATA(q, uv_udp_send_t, queue); + assert(req != NULL); + + req->status = req->bufs[0].len; + + /* Sending a datagram is an atomic operation: either all data + * is written or nothing is (and EMSGSIZE is raised). That is + * why we don't handle partial writes. Just pop the request + * off the write queue and onto the completed queue, done. + */ + QUEUE_REMOVE(&req->queue); + QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue); + } + + /* couldn't batch everything, continue sending (jump to avoid stack growth) */ + if (!QUEUE_EMPTY(&handle->write_queue)) + goto write_queue_drain; + uv__io_feed(handle->loop, &handle->io_watcher); + return; +} +#endif + +static void uv__udp_sendmsg(uv_udp_t* handle) { + uv_udp_send_t* req; + struct msghdr h; + QUEUE* q; + ssize_t size; + +#if HAVE_MMSG + uv_once(&once, uv__udp_mmsg_init); + if (uv__sendmmsg_avail) { + uv__udp_sendmmsg(handle); + return; + } +#endif + + while (!QUEUE_EMPTY(&handle->write_queue)) { + q = QUEUE_HEAD(&handle->write_queue); + assert(q != NULL); + + req = QUEUE_DATA(q, uv_udp_send_t, queue); + assert(req != NULL); + + memset(&h, 0, sizeof h); + if (req->addr.ss_family == AF_UNSPEC) { + h.msg_name = NULL; + h.msg_namelen = 0; + } else { + h.msg_name = &req->addr; + if (req->addr.ss_family == AF_INET6) + h.msg_namelen = sizeof(struct sockaddr_in6); + else if (req->addr.ss_family == AF_INET) + h.msg_namelen = sizeof(struct sockaddr_in); + else if (req->addr.ss_family == AF_UNIX) + h.msg_namelen = sizeof(struct sockaddr_un); + else { + assert(0 && "unsupported address family"); + abort(); + } + } + h.msg_iov = (struct iovec*) req->bufs; + h.msg_iovlen = req->nbufs; + + do { + size = sendmsg(handle->io_watcher.fd, &h, 0); + } while (size == -1 && errno == EINTR); + + if (size == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS) + break; + } + + req->status = (size == -1 ? UV__ERR(errno) : size); + + /* Sending a datagram is an atomic operation: either all data + * is written or nothing is (and EMSGSIZE is raised). That is + * why we don't handle partial writes. Just pop the request + * off the write queue and onto the completed queue, done. + */ + QUEUE_REMOVE(&req->queue); + QUEUE_INSERT_TAIL(&handle->write_completed_queue, &req->queue); + uv__io_feed(handle->loop, &handle->io_watcher); + } +} + +/* On the BSDs, SO_REUSEPORT implies SO_REUSEADDR but with some additional + * refinements for programs that use multicast. + * + * Linux as of 3.9 has a SO_REUSEPORT socket option but with semantics that + * are different from the BSDs: it _shares_ the port rather than steal it + * from the current listener. While useful, it's not something we can emulate + * on other platforms so we don't enable it. + * + * zOS does not support getsockname with SO_REUSEPORT option when using + * AF_UNIX. + */ +static int uv__set_reuse(int fd) { + int yes; + yes = 1; + +#if defined(SO_REUSEPORT) && defined(__MVS__) + struct sockaddr_in sockfd; + unsigned int sockfd_len = sizeof(sockfd); + if (getsockname(fd, (struct sockaddr*) &sockfd, &sockfd_len) == -1) + return UV__ERR(errno); + if (sockfd.sin_family == AF_UNIX) { + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes))) + return UV__ERR(errno); + } else { + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes))) + return UV__ERR(errno); + } +#elif defined(SO_REUSEPORT) && !defined(__linux__) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes))) + return UV__ERR(errno); +#else + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes))) + return UV__ERR(errno); +#endif + + return 0; +} + +/* + * The Linux kernel suppresses some ICMP error messages by default for UDP + * sockets. Setting IP_RECVERR/IPV6_RECVERR on the socket enables full ICMP + * error reporting, hopefully resulting in faster failover to working name + * servers. + */ +static int uv__set_recverr(int fd, sa_family_t ss_family) { +#if defined(__linux__) + int yes; + + yes = 1; + if (ss_family == AF_INET) { + if (setsockopt(fd, IPPROTO_IP, IP_RECVERR, &yes, sizeof(yes))) + return UV__ERR(errno); + } else if (ss_family == AF_INET6) { + if (setsockopt(fd, IPPROTO_IPV6, IPV6_RECVERR, &yes, sizeof(yes))) + return UV__ERR(errno); + } +#endif + return 0; +} + + +int uv__udp_bind(uv_udp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen, + unsigned int flags) { + int err; + int yes; + int fd; + + /* Check for bad flags. */ + if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR | UV_UDP_LINUX_RECVERR)) + return UV_EINVAL; + + /* Cannot set IPv6-only mode on non-IPv6 socket. */ + if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6) + return UV_EINVAL; + + fd = handle->io_watcher.fd; + if (fd == -1) { + err = uv__socket(addr->sa_family, SOCK_DGRAM, 0); + if (err < 0) + return err; + fd = err; + handle->io_watcher.fd = fd; + } + + if (flags & UV_UDP_LINUX_RECVERR) { + err = uv__set_recverr(fd, addr->sa_family); + if (err) + return err; + } + + if (flags & UV_UDP_REUSEADDR) { + err = uv__set_reuse(fd); + if (err) + return err; + } + + if (flags & UV_UDP_IPV6ONLY) { +#ifdef IPV6_V6ONLY + yes = 1; + if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) { + err = UV__ERR(errno); + return err; + } +#else + err = UV_ENOTSUP; + return err; +#endif + } + + if (bind(fd, addr, addrlen)) { + err = UV__ERR(errno); + if (errno == EAFNOSUPPORT) + /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a + * socket created with AF_INET to an AF_INET6 address or vice versa. */ + err = UV_EINVAL; + return err; + } + + if (addr->sa_family == AF_INET6) + handle->flags |= UV_HANDLE_IPV6; + + handle->flags |= UV_HANDLE_BOUND; + return 0; +} + + +static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, + int domain, + unsigned int flags) { + union uv__sockaddr taddr; + socklen_t addrlen; + + if (handle->io_watcher.fd != -1) + return 0; + + switch (domain) { + case AF_INET: + { + struct sockaddr_in* addr = &taddr.in; + memset(addr, 0, sizeof *addr); + addr->sin_family = AF_INET; + addr->sin_addr.s_addr = INADDR_ANY; + addrlen = sizeof *addr; + break; + } + case AF_INET6: + { + struct sockaddr_in6* addr = &taddr.in6; + memset(addr, 0, sizeof *addr); + addr->sin6_family = AF_INET6; + addr->sin6_addr = in6addr_any; + addrlen = sizeof *addr; + break; + } + default: + assert(0 && "unsupported address family"); + abort(); + } + + return uv__udp_bind(handle, &taddr.addr, addrlen, flags); +} + + +int uv__udp_connect(uv_udp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen) { + int err; + + err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0); + if (err) + return err; + + do { + errno = 0; + err = connect(handle->io_watcher.fd, addr, addrlen); + } while (err == -1 && errno == EINTR); + + if (err) + return UV__ERR(errno); + + handle->flags |= UV_HANDLE_UDP_CONNECTED; + + return 0; +} + + +int uv__udp_disconnect(uv_udp_t* handle) { + int r; + struct sockaddr addr; + + memset(&addr, 0, sizeof(addr)); + + addr.sa_family = AF_UNSPEC; + + do { + errno = 0; + r = connect(handle->io_watcher.fd, &addr, sizeof(addr)); + } while (r == -1 && errno == EINTR); + + if (r == -1 && errno != EAFNOSUPPORT) + return UV__ERR(errno); + + handle->flags &= ~UV_HANDLE_UDP_CONNECTED; + return 0; +} + + +int uv__udp_send(uv_udp_send_t* req, + uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr, + unsigned int addrlen, + uv_udp_send_cb send_cb) { + int err; + int empty_queue; + + assert(nbufs > 0); + + if (addr) { + err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0); + if (err) + return err; + } + + /* It's legal for send_queue_count > 0 even when the write_queue is empty; + * it means there are error-state requests in the write_completed_queue that + * will touch up send_queue_size/count later. + */ + empty_queue = (handle->send_queue_count == 0); + + uv__req_init(handle->loop, req, UV_UDP_SEND); + assert(addrlen <= sizeof(req->addr)); + if (addr == NULL) + req->addr.ss_family = AF_UNSPEC; + else + memcpy(&req->addr, addr, addrlen); + req->send_cb = send_cb; + req->handle = handle; + req->nbufs = nbufs; + + req->bufs = req->bufsml; + if (nbufs > ARRAY_SIZE(req->bufsml)) + req->bufs = uv__malloc(nbufs * sizeof(bufs[0])); + + if (req->bufs == NULL) { + uv__req_unregister(handle->loop, req); + return UV_ENOMEM; + } + + memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0])); + handle->send_queue_size += uv__count_bufs(req->bufs, req->nbufs); + handle->send_queue_count++; + QUEUE_INSERT_TAIL(&handle->write_queue, &req->queue); + uv__handle_start(handle); + + if (empty_queue && !(handle->flags & UV_HANDLE_UDP_PROCESSING)) { + uv__udp_sendmsg(handle); + + /* `uv__udp_sendmsg` may not be able to do non-blocking write straight + * away. In such cases the `io_watcher` has to be queued for asynchronous + * write. + */ + if (!QUEUE_EMPTY(&handle->write_queue)) + uv__io_start(handle->loop, &handle->io_watcher, POLLOUT); + } else { + uv__io_start(handle->loop, &handle->io_watcher, POLLOUT); + } + + return 0; +} + + +int uv__udp_try_send(uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr, + unsigned int addrlen) { + int err; + struct msghdr h; + ssize_t size; + + assert(nbufs > 0); + + /* already sending a message */ + if (handle->send_queue_count != 0) + return UV_EAGAIN; + + if (addr) { + err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0); + if (err) + return err; + } else { + assert(handle->flags & UV_HANDLE_UDP_CONNECTED); + } + + memset(&h, 0, sizeof h); + h.msg_name = (struct sockaddr*) addr; + h.msg_namelen = addrlen; + h.msg_iov = (struct iovec*) bufs; + h.msg_iovlen = nbufs; + + do { + size = sendmsg(handle->io_watcher.fd, &h, 0); + } while (size == -1 && errno == EINTR); + + if (size == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS) + return UV_EAGAIN; + else + return UV__ERR(errno); + } + + return size; +} + + +static int uv__udp_set_membership4(uv_udp_t* handle, + const struct sockaddr_in* multicast_addr, + const char* interface_addr, + uv_membership membership) { + struct ip_mreq mreq; + int optname; + int err; + + memset(&mreq, 0, sizeof mreq); + + if (interface_addr) { + err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr); + if (err) + return err; + } else { + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + } + + mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr; + + switch (membership) { + case UV_JOIN_GROUP: + optname = IP_ADD_MEMBERSHIP; + break; + case UV_LEAVE_GROUP: + optname = IP_DROP_MEMBERSHIP; + break; + default: + return UV_EINVAL; + } + + if (setsockopt(handle->io_watcher.fd, + IPPROTO_IP, + optname, + &mreq, + sizeof(mreq))) { +#if defined(__MVS__) + if (errno == ENXIO) + return UV_ENODEV; +#endif + return UV__ERR(errno); + } + + return 0; +} + + +static int uv__udp_set_membership6(uv_udp_t* handle, + const struct sockaddr_in6* multicast_addr, + const char* interface_addr, + uv_membership membership) { + int optname; + struct ipv6_mreq mreq; + struct sockaddr_in6 addr6; + + memset(&mreq, 0, sizeof mreq); + + if (interface_addr) { + if (uv_ip6_addr(interface_addr, 0, &addr6)) + return UV_EINVAL; + mreq.ipv6mr_interface = addr6.sin6_scope_id; + } else { + mreq.ipv6mr_interface = 0; + } + + mreq.ipv6mr_multiaddr = multicast_addr->sin6_addr; + + switch (membership) { + case UV_JOIN_GROUP: + optname = IPV6_ADD_MEMBERSHIP; + break; + case UV_LEAVE_GROUP: + optname = IPV6_DROP_MEMBERSHIP; + break; + default: + return UV_EINVAL; + } + + if (setsockopt(handle->io_watcher.fd, + IPPROTO_IPV6, + optname, + &mreq, + sizeof(mreq))) { +#if defined(__MVS__) + if (errno == ENXIO) + return UV_ENODEV; +#endif + return UV__ERR(errno); + } + + return 0; +} + + +#if !defined(__OpenBSD__) && \ + !defined(__NetBSD__) && \ + !defined(__ANDROID__) && \ + !defined(__DragonFly__) & \ + !defined(__QNX__) +static int uv__udp_set_source_membership4(uv_udp_t* handle, + const struct sockaddr_in* multicast_addr, + const char* interface_addr, + const struct sockaddr_in* source_addr, + uv_membership membership) { + struct ip_mreq_source mreq; + int optname; + int err; + + err = uv__udp_maybe_deferred_bind(handle, AF_INET, UV_UDP_REUSEADDR); + if (err) + return err; + + memset(&mreq, 0, sizeof(mreq)); + + if (interface_addr != NULL) { + err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr); + if (err) + return err; + } else { + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + } + + mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr; + mreq.imr_sourceaddr.s_addr = source_addr->sin_addr.s_addr; + + if (membership == UV_JOIN_GROUP) + optname = IP_ADD_SOURCE_MEMBERSHIP; + else if (membership == UV_LEAVE_GROUP) + optname = IP_DROP_SOURCE_MEMBERSHIP; + else + return UV_EINVAL; + + if (setsockopt(handle->io_watcher.fd, + IPPROTO_IP, + optname, + &mreq, + sizeof(mreq))) { + return UV__ERR(errno); + } + + return 0; +} + + +static int uv__udp_set_source_membership6(uv_udp_t* handle, + const struct sockaddr_in6* multicast_addr, + const char* interface_addr, + const struct sockaddr_in6* source_addr, + uv_membership membership) { + struct group_source_req mreq; + struct sockaddr_in6 addr6; + int optname; + int err; + + err = uv__udp_maybe_deferred_bind(handle, AF_INET6, UV_UDP_REUSEADDR); + if (err) + return err; + + memset(&mreq, 0, sizeof(mreq)); + + if (interface_addr != NULL) { + err = uv_ip6_addr(interface_addr, 0, &addr6); + if (err) + return err; + mreq.gsr_interface = addr6.sin6_scope_id; + } else { + mreq.gsr_interface = 0; + } + + STATIC_ASSERT(sizeof(mreq.gsr_group) >= sizeof(*multicast_addr)); + STATIC_ASSERT(sizeof(mreq.gsr_source) >= sizeof(*source_addr)); + memcpy(&mreq.gsr_group, multicast_addr, sizeof(*multicast_addr)); + memcpy(&mreq.gsr_source, source_addr, sizeof(*source_addr)); + + if (membership == UV_JOIN_GROUP) + optname = MCAST_JOIN_SOURCE_GROUP; + else if (membership == UV_LEAVE_GROUP) + optname = MCAST_LEAVE_SOURCE_GROUP; + else + return UV_EINVAL; + + if (setsockopt(handle->io_watcher.fd, + IPPROTO_IPV6, + optname, + &mreq, + sizeof(mreq))) { + return UV__ERR(errno); + } + + return 0; +} +#endif + + +int uv__udp_init_ex(uv_loop_t* loop, + uv_udp_t* handle, + unsigned flags, + int domain) { + int fd; + + fd = -1; + if (domain != AF_UNSPEC) { + fd = uv__socket(domain, SOCK_DGRAM, 0); + if (fd < 0) + return fd; + } + + uv__handle_init(loop, (uv_handle_t*)handle, UV_UDP); + handle->alloc_cb = NULL; + handle->recv_cb = NULL; + handle->send_queue_size = 0; + handle->send_queue_count = 0; + uv__io_init(&handle->io_watcher, uv__udp_io, fd); + QUEUE_INIT(&handle->write_queue); + QUEUE_INIT(&handle->write_completed_queue); + + return 0; +} + + +int uv_udp_using_recvmmsg(const uv_udp_t* handle) { +#if HAVE_MMSG + if (handle->flags & UV_HANDLE_UDP_RECVMMSG) { + uv_once(&once, uv__udp_mmsg_init); + return uv__recvmmsg_avail; + } +#endif + return 0; +} + + +int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) { + int err; + + /* Check for already active socket. */ + if (handle->io_watcher.fd != -1) + return UV_EBUSY; + + if (uv__fd_exists(handle->loop, sock)) + return UV_EEXIST; + + err = uv__nonblock(sock, 1); + if (err) + return err; + + err = uv__set_reuse(sock); + if (err) + return err; + + handle->io_watcher.fd = sock; + if (uv__udp_is_connected(handle)) + handle->flags |= UV_HANDLE_UDP_CONNECTED; + + return 0; +} + + +int uv_udp_set_membership(uv_udp_t* handle, + const char* multicast_addr, + const char* interface_addr, + uv_membership membership) { + int err; + struct sockaddr_in addr4; + struct sockaddr_in6 addr6; + + if (uv_ip4_addr(multicast_addr, 0, &addr4) == 0) { + err = uv__udp_maybe_deferred_bind(handle, AF_INET, UV_UDP_REUSEADDR); + if (err) + return err; + return uv__udp_set_membership4(handle, &addr4, interface_addr, membership); + } else if (uv_ip6_addr(multicast_addr, 0, &addr6) == 0) { + err = uv__udp_maybe_deferred_bind(handle, AF_INET6, UV_UDP_REUSEADDR); + if (err) + return err; + return uv__udp_set_membership6(handle, &addr6, interface_addr, membership); + } else { + return UV_EINVAL; + } +} + + +int uv_udp_set_source_membership(uv_udp_t* handle, + const char* multicast_addr, + const char* interface_addr, + const char* source_addr, + uv_membership membership) { +#if !defined(__OpenBSD__) && \ + !defined(__NetBSD__) && \ + !defined(__ANDROID__) && \ + !defined(__DragonFly__) && \ + !defined(__QNX__) + int err; + union uv__sockaddr mcast_addr; + union uv__sockaddr src_addr; + + err = uv_ip4_addr(multicast_addr, 0, &mcast_addr.in); + if (err) { + err = uv_ip6_addr(multicast_addr, 0, &mcast_addr.in6); + if (err) + return err; + err = uv_ip6_addr(source_addr, 0, &src_addr.in6); + if (err) + return err; + return uv__udp_set_source_membership6(handle, + &mcast_addr.in6, + interface_addr, + &src_addr.in6, + membership); + } + + err = uv_ip4_addr(source_addr, 0, &src_addr.in); + if (err) + return err; + return uv__udp_set_source_membership4(handle, + &mcast_addr.in, + interface_addr, + &src_addr.in, + membership); +#else + return UV_ENOSYS; +#endif +} + + +static int uv__setsockopt(uv_udp_t* handle, + int option4, + int option6, + const void* val, + socklen_t size) { + int r; + + if (handle->flags & UV_HANDLE_IPV6) + r = setsockopt(handle->io_watcher.fd, + IPPROTO_IPV6, + option6, + val, + size); + else + r = setsockopt(handle->io_watcher.fd, + IPPROTO_IP, + option4, + val, + size); + if (r) + return UV__ERR(errno); + + return 0; +} + +static int uv__setsockopt_maybe_char(uv_udp_t* handle, + int option4, + int option6, + int val) { +#if defined(__sun) || defined(_AIX) || defined(__MVS__) + char arg = val; +#elif defined(__OpenBSD__) + unsigned char arg = val; +#else + int arg = val; +#endif + + if (val < 0 || val > 255) + return UV_EINVAL; + + return uv__setsockopt(handle, option4, option6, &arg, sizeof(arg)); +} + + +int uv_udp_set_broadcast(uv_udp_t* handle, int on) { + if (setsockopt(handle->io_watcher.fd, + SOL_SOCKET, + SO_BROADCAST, + &on, + sizeof(on))) { + return UV__ERR(errno); + } + + return 0; +} + + +int uv_udp_set_ttl(uv_udp_t* handle, int ttl) { + if (ttl < 1 || ttl > 255) + return UV_EINVAL; + +#if defined(__MVS__) + if (!(handle->flags & UV_HANDLE_IPV6)) + return UV_ENOTSUP; /* zOS does not support setting ttl for IPv4 */ +#endif + +/* + * On Solaris and derivatives such as SmartOS, the length of socket options + * is sizeof(int) for IP_TTL and IPV6_UNICAST_HOPS, + * so hardcode the size of these options on this platform, + * and use the general uv__setsockopt_maybe_char call on other platforms. + */ +#if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \ + defined(__MVS__) || defined(__QNX__) + + return uv__setsockopt(handle, + IP_TTL, + IPV6_UNICAST_HOPS, + &ttl, + sizeof(ttl)); + +#else /* !(defined(__sun) || defined(_AIX) || defined (__OpenBSD__) || + defined(__MVS__) || defined(__QNX__)) */ + + return uv__setsockopt_maybe_char(handle, + IP_TTL, + IPV6_UNICAST_HOPS, + ttl); + +#endif /* defined(__sun) || defined(_AIX) || defined (__OpenBSD__) || + defined(__MVS__) || defined(__QNX__) */ +} + + +int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) { +/* + * On Solaris and derivatives such as SmartOS, the length of socket options + * is sizeof(int) for IPV6_MULTICAST_HOPS and sizeof(char) for + * IP_MULTICAST_TTL, so hardcode the size of the option in the IPv6 case, + * and use the general uv__setsockopt_maybe_char call otherwise. + */ +#if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \ + defined(__MVS__) || defined(__QNX__) + if (handle->flags & UV_HANDLE_IPV6) + return uv__setsockopt(handle, + IP_MULTICAST_TTL, + IPV6_MULTICAST_HOPS, + &ttl, + sizeof(ttl)); +#endif /* defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \ + defined(__MVS__) || defined(__QNX__) */ + + return uv__setsockopt_maybe_char(handle, + IP_MULTICAST_TTL, + IPV6_MULTICAST_HOPS, + ttl); +} + + +int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) { +/* + * On Solaris and derivatives such as SmartOS, the length of socket options + * is sizeof(int) for IPV6_MULTICAST_LOOP and sizeof(char) for + * IP_MULTICAST_LOOP, so hardcode the size of the option in the IPv6 case, + * and use the general uv__setsockopt_maybe_char call otherwise. + */ +#if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \ + defined(__MVS__) || defined(__QNX__) + if (handle->flags & UV_HANDLE_IPV6) + return uv__setsockopt(handle, + IP_MULTICAST_LOOP, + IPV6_MULTICAST_LOOP, + &on, + sizeof(on)); +#endif /* defined(__sun) || defined(_AIX) ||defined(__OpenBSD__) || + defined(__MVS__) || defined(__QNX__) */ + + return uv__setsockopt_maybe_char(handle, + IP_MULTICAST_LOOP, + IPV6_MULTICAST_LOOP, + on); +} + +int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) { + struct sockaddr_storage addr_st; + struct sockaddr_in* addr4; + struct sockaddr_in6* addr6; + + addr4 = (struct sockaddr_in*) &addr_st; + addr6 = (struct sockaddr_in6*) &addr_st; + + if (!interface_addr) { + memset(&addr_st, 0, sizeof addr_st); + if (handle->flags & UV_HANDLE_IPV6) { + addr_st.ss_family = AF_INET6; + addr6->sin6_scope_id = 0; + } else { + addr_st.ss_family = AF_INET; + addr4->sin_addr.s_addr = htonl(INADDR_ANY); + } + } else if (uv_ip4_addr(interface_addr, 0, addr4) == 0) { + /* nothing, address was parsed */ + } else if (uv_ip6_addr(interface_addr, 0, addr6) == 0) { + /* nothing, address was parsed */ + } else { + return UV_EINVAL; + } + + if (addr_st.ss_family == AF_INET) { + if (setsockopt(handle->io_watcher.fd, + IPPROTO_IP, + IP_MULTICAST_IF, + (void*) &addr4->sin_addr, + sizeof(addr4->sin_addr)) == -1) { + return UV__ERR(errno); + } + } else if (addr_st.ss_family == AF_INET6) { + if (setsockopt(handle->io_watcher.fd, + IPPROTO_IPV6, + IPV6_MULTICAST_IF, + &addr6->sin6_scope_id, + sizeof(addr6->sin6_scope_id)) == -1) { + return UV__ERR(errno); + } + } else { + assert(0 && "unexpected address family"); + abort(); + } + + return 0; +} + +int uv_udp_getpeername(const uv_udp_t* handle, + struct sockaddr* name, + int* namelen) { + + return uv__getsockpeername((const uv_handle_t*) handle, + getpeername, + name, + namelen); +} + +int uv_udp_getsockname(const uv_udp_t* handle, + struct sockaddr* name, + int* namelen) { + + return uv__getsockpeername((const uv_handle_t*) handle, + getsockname, + name, + namelen); +} + + +int uv__udp_recv_start(uv_udp_t* handle, + uv_alloc_cb alloc_cb, + uv_udp_recv_cb recv_cb) { + int err; + + if (alloc_cb == NULL || recv_cb == NULL) + return UV_EINVAL; + + if (uv__io_active(&handle->io_watcher, POLLIN)) + return UV_EALREADY; /* FIXME(bnoordhuis) Should be UV_EBUSY. */ + + err = uv__udp_maybe_deferred_bind(handle, AF_INET, 0); + if (err) + return err; + + handle->alloc_cb = alloc_cb; + handle->recv_cb = recv_cb; + + uv__io_start(handle->loop, &handle->io_watcher, POLLIN); + uv__handle_start(handle); + + return 0; +} + + +int uv__udp_recv_stop(uv_udp_t* handle) { + uv__io_stop(handle->loop, &handle->io_watcher, POLLIN); + + if (!uv__io_active(&handle->io_watcher, POLLOUT)) + uv__handle_stop(handle); + + handle->alloc_cb = NULL; + handle->recv_cb = NULL; + + return 0; +} diff --git a/external/src/libuv/src/uv-common.c b/external/src/libuv/src/uv-common.c new file mode 100644 index 0000000..e81ed79 --- /dev/null +++ b/external/src/libuv/src/uv-common.c @@ -0,0 +1,951 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "uv-common.h" + +#include +#include +#include +#include /* NULL */ +#include +#include /* malloc */ +#include /* memset */ + +#if defined(_WIN32) +# include /* malloc */ +#else +# include /* if_nametoindex */ +# include /* AF_UNIX, sockaddr_un */ +#endif + + +typedef struct { + uv_malloc_func local_malloc; + uv_realloc_func local_realloc; + uv_calloc_func local_calloc; + uv_free_func local_free; +} uv__allocator_t; + +static uv__allocator_t uv__allocator = { + malloc, + realloc, + calloc, + free, +}; + +char* uv__strdup(const char* s) { + size_t len = strlen(s) + 1; + char* m = uv__malloc(len); + if (m == NULL) + return NULL; + return memcpy(m, s, len); +} + +char* uv__strndup(const char* s, size_t n) { + char* m; + size_t len = strlen(s); + if (n < len) + len = n; + m = uv__malloc(len + 1); + if (m == NULL) + return NULL; + m[len] = '\0'; + return memcpy(m, s, len); +} + +void* uv__malloc(size_t size) { + if (size > 0) + return uv__allocator.local_malloc(size); + return NULL; +} + +void uv__free(void* ptr) { + int saved_errno; + + /* Libuv expects that free() does not clobber errno. The system allocator + * honors that assumption but custom allocators may not be so careful. + */ + saved_errno = errno; + uv__allocator.local_free(ptr); + errno = saved_errno; +} + +void* uv__calloc(size_t count, size_t size) { + return uv__allocator.local_calloc(count, size); +} + +void* uv__realloc(void* ptr, size_t size) { + if (size > 0) + return uv__allocator.local_realloc(ptr, size); + uv__free(ptr); + return NULL; +} + +void* uv__reallocf(void* ptr, size_t size) { + void* newptr; + + newptr = uv__realloc(ptr, size); + if (newptr == NULL) + if (size > 0) + uv__free(ptr); + + return newptr; +} + +int uv_replace_allocator(uv_malloc_func malloc_func, + uv_realloc_func realloc_func, + uv_calloc_func calloc_func, + uv_free_func free_func) { + if (malloc_func == NULL || realloc_func == NULL || + calloc_func == NULL || free_func == NULL) { + return UV_EINVAL; + } + + uv__allocator.local_malloc = malloc_func; + uv__allocator.local_realloc = realloc_func; + uv__allocator.local_calloc = calloc_func; + uv__allocator.local_free = free_func; + + return 0; +} + +#define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t); + +size_t uv_handle_size(uv_handle_type type) { + switch (type) { + UV_HANDLE_TYPE_MAP(XX) + default: + return -1; + } +} + +size_t uv_req_size(uv_req_type type) { + switch(type) { + UV_REQ_TYPE_MAP(XX) + default: + return -1; + } +} + +#undef XX + + +size_t uv_loop_size(void) { + return sizeof(uv_loop_t); +} + + +uv_buf_t uv_buf_init(char* base, unsigned int len) { + uv_buf_t buf; + buf.base = base; + buf.len = len; + return buf; +} + + +static const char* uv__unknown_err_code(int err) { + char buf[32]; + char* copy; + + snprintf(buf, sizeof(buf), "Unknown system error %d", err); + copy = uv__strdup(buf); + + return copy != NULL ? copy : "Unknown system error"; +} + +#define UV_ERR_NAME_GEN_R(name, _) \ +case UV_## name: \ + uv__strscpy(buf, #name, buflen); break; +char* uv_err_name_r(int err, char* buf, size_t buflen) { + switch (err) { + UV_ERRNO_MAP(UV_ERR_NAME_GEN_R) + default: snprintf(buf, buflen, "Unknown system error %d", err); + } + return buf; +} +#undef UV_ERR_NAME_GEN_R + + +#define UV_ERR_NAME_GEN(name, _) case UV_ ## name: return #name; +const char* uv_err_name(int err) { + switch (err) { + UV_ERRNO_MAP(UV_ERR_NAME_GEN) + } + return uv__unknown_err_code(err); +} +#undef UV_ERR_NAME_GEN + + +#define UV_STRERROR_GEN_R(name, msg) \ +case UV_ ## name: \ + snprintf(buf, buflen, "%s", msg); break; +char* uv_strerror_r(int err, char* buf, size_t buflen) { + switch (err) { + UV_ERRNO_MAP(UV_STRERROR_GEN_R) + default: snprintf(buf, buflen, "Unknown system error %d", err); + } + return buf; +} +#undef UV_STRERROR_GEN_R + + +#define UV_STRERROR_GEN(name, msg) case UV_ ## name: return msg; +const char* uv_strerror(int err) { + switch (err) { + UV_ERRNO_MAP(UV_STRERROR_GEN) + } + return uv__unknown_err_code(err); +} +#undef UV_STRERROR_GEN + + +int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) { + memset(addr, 0, sizeof(*addr)); + addr->sin_family = AF_INET; + addr->sin_port = htons(port); +#ifdef SIN6_LEN + addr->sin_len = sizeof(*addr); +#endif + return uv_inet_pton(AF_INET, ip, &(addr->sin_addr.s_addr)); +} + + +int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) { + char address_part[40]; + size_t address_part_size; + const char* zone_index; + + memset(addr, 0, sizeof(*addr)); + addr->sin6_family = AF_INET6; + addr->sin6_port = htons(port); +#ifdef SIN6_LEN + addr->sin6_len = sizeof(*addr); +#endif + + zone_index = strchr(ip, '%'); + if (zone_index != NULL) { + address_part_size = zone_index - ip; + if (address_part_size >= sizeof(address_part)) + address_part_size = sizeof(address_part) - 1; + + memcpy(address_part, ip, address_part_size); + address_part[address_part_size] = '\0'; + ip = address_part; + + zone_index++; /* skip '%' */ + /* NOTE: unknown interface (id=0) is silently ignored */ +#ifdef _WIN32 + addr->sin6_scope_id = atoi(zone_index); +#else + addr->sin6_scope_id = if_nametoindex(zone_index); +#endif + } + + return uv_inet_pton(AF_INET6, ip, &addr->sin6_addr); +} + + +int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size) { + return uv_inet_ntop(AF_INET, &src->sin_addr, dst, size); +} + + +int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size) { + return uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size); +} + + +int uv_tcp_bind(uv_tcp_t* handle, + const struct sockaddr* addr, + unsigned int flags) { + unsigned int addrlen; + + if (handle->type != UV_TCP) + return UV_EINVAL; + + if (addr->sa_family == AF_INET) + addrlen = sizeof(struct sockaddr_in); + else if (addr->sa_family == AF_INET6) + addrlen = sizeof(struct sockaddr_in6); + else + return UV_EINVAL; + + return uv__tcp_bind(handle, addr, addrlen, flags); +} + + +int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned flags) { + unsigned extra_flags; + int domain; + int rc; + + /* Use the lower 8 bits for the domain. */ + domain = flags & 0xFF; + if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC) + return UV_EINVAL; + + /* Use the higher bits for extra flags. */ + extra_flags = flags & ~0xFF; + if (extra_flags & ~UV_UDP_RECVMMSG) + return UV_EINVAL; + + rc = uv__udp_init_ex(loop, handle, flags, domain); + + if (rc == 0) + if (extra_flags & UV_UDP_RECVMMSG) + handle->flags |= UV_HANDLE_UDP_RECVMMSG; + + return rc; +} + + +int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) { + return uv_udp_init_ex(loop, handle, AF_UNSPEC); +} + + +int uv_udp_bind(uv_udp_t* handle, + const struct sockaddr* addr, + unsigned int flags) { + unsigned int addrlen; + + if (handle->type != UV_UDP) + return UV_EINVAL; + + if (addr->sa_family == AF_INET) + addrlen = sizeof(struct sockaddr_in); + else if (addr->sa_family == AF_INET6) + addrlen = sizeof(struct sockaddr_in6); + else + return UV_EINVAL; + + return uv__udp_bind(handle, addr, addrlen, flags); +} + + +int uv_tcp_connect(uv_connect_t* req, + uv_tcp_t* handle, + const struct sockaddr* addr, + uv_connect_cb cb) { + unsigned int addrlen; + + if (handle->type != UV_TCP) + return UV_EINVAL; + + if (addr->sa_family == AF_INET) + addrlen = sizeof(struct sockaddr_in); + else if (addr->sa_family == AF_INET6) + addrlen = sizeof(struct sockaddr_in6); + else + return UV_EINVAL; + + return uv__tcp_connect(req, handle, addr, addrlen, cb); +} + + +int uv_udp_connect(uv_udp_t* handle, const struct sockaddr* addr) { + unsigned int addrlen; + + if (handle->type != UV_UDP) + return UV_EINVAL; + + /* Disconnect the handle */ + if (addr == NULL) { + if (!(handle->flags & UV_HANDLE_UDP_CONNECTED)) + return UV_ENOTCONN; + + return uv__udp_disconnect(handle); + } + + if (addr->sa_family == AF_INET) + addrlen = sizeof(struct sockaddr_in); + else if (addr->sa_family == AF_INET6) + addrlen = sizeof(struct sockaddr_in6); + else + return UV_EINVAL; + + if (handle->flags & UV_HANDLE_UDP_CONNECTED) + return UV_EISCONN; + + return uv__udp_connect(handle, addr, addrlen); +} + + +int uv__udp_is_connected(uv_udp_t* handle) { + struct sockaddr_storage addr; + int addrlen; + if (handle->type != UV_UDP) + return 0; + + addrlen = sizeof(addr); + if (uv_udp_getpeername(handle, (struct sockaddr*) &addr, &addrlen) != 0) + return 0; + + return addrlen > 0; +} + + +int uv__udp_check_before_send(uv_udp_t* handle, const struct sockaddr* addr) { + unsigned int addrlen; + + if (handle->type != UV_UDP) + return UV_EINVAL; + + if (addr != NULL && (handle->flags & UV_HANDLE_UDP_CONNECTED)) + return UV_EISCONN; + + if (addr == NULL && !(handle->flags & UV_HANDLE_UDP_CONNECTED)) + return UV_EDESTADDRREQ; + + if (addr != NULL) { + if (addr->sa_family == AF_INET) + addrlen = sizeof(struct sockaddr_in); + else if (addr->sa_family == AF_INET6) + addrlen = sizeof(struct sockaddr_in6); +#if defined(AF_UNIX) && !defined(_WIN32) + else if (addr->sa_family == AF_UNIX) + addrlen = sizeof(struct sockaddr_un); +#endif + else + return UV_EINVAL; + } else { + addrlen = 0; + } + + return addrlen; +} + + +int uv_udp_send(uv_udp_send_t* req, + uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr, + uv_udp_send_cb send_cb) { + int addrlen; + + addrlen = uv__udp_check_before_send(handle, addr); + if (addrlen < 0) + return addrlen; + + return uv__udp_send(req, handle, bufs, nbufs, addr, addrlen, send_cb); +} + + +int uv_udp_try_send(uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr) { + int addrlen; + + addrlen = uv__udp_check_before_send(handle, addr); + if (addrlen < 0) + return addrlen; + + return uv__udp_try_send(handle, bufs, nbufs, addr, addrlen); +} + + +int uv_udp_recv_start(uv_udp_t* handle, + uv_alloc_cb alloc_cb, + uv_udp_recv_cb recv_cb) { + if (handle->type != UV_UDP || alloc_cb == NULL || recv_cb == NULL) + return UV_EINVAL; + else + return uv__udp_recv_start(handle, alloc_cb, recv_cb); +} + + +int uv_udp_recv_stop(uv_udp_t* handle) { + if (handle->type != UV_UDP) + return UV_EINVAL; + else + return uv__udp_recv_stop(handle); +} + + +void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) { + QUEUE queue; + QUEUE* q; + uv_handle_t* h; + + QUEUE_MOVE(&loop->handle_queue, &queue); + while (!QUEUE_EMPTY(&queue)) { + q = QUEUE_HEAD(&queue); + h = QUEUE_DATA(q, uv_handle_t, handle_queue); + + QUEUE_REMOVE(q); + QUEUE_INSERT_TAIL(&loop->handle_queue, q); + + if (h->flags & UV_HANDLE_INTERNAL) continue; + walk_cb(h, arg); + } +} + + +static void uv__print_handles(uv_loop_t* loop, int only_active, FILE* stream) { + const char* type; + QUEUE* q; + uv_handle_t* h; + + if (loop == NULL) + loop = uv_default_loop(); + + QUEUE_FOREACH(q, &loop->handle_queue) { + h = QUEUE_DATA(q, uv_handle_t, handle_queue); + + if (only_active && !uv__is_active(h)) + continue; + + switch (h->type) { +#define X(uc, lc) case UV_##uc: type = #lc; break; + UV_HANDLE_TYPE_MAP(X) +#undef X + default: type = ""; + } + + fprintf(stream, + "[%c%c%c] %-8s %p\n", + "R-"[!(h->flags & UV_HANDLE_REF)], + "A-"[!(h->flags & UV_HANDLE_ACTIVE)], + "I-"[!(h->flags & UV_HANDLE_INTERNAL)], + type, + (void*)h); + } +} + + +void uv_print_all_handles(uv_loop_t* loop, FILE* stream) { + uv__print_handles(loop, 0, stream); +} + + +void uv_print_active_handles(uv_loop_t* loop, FILE* stream) { + uv__print_handles(loop, 1, stream); +} + + +void uv_ref(uv_handle_t* handle) { + uv__handle_ref(handle); +} + + +void uv_unref(uv_handle_t* handle) { + uv__handle_unref(handle); +} + + +int uv_has_ref(const uv_handle_t* handle) { + return uv__has_ref(handle); +} + + +void uv_stop(uv_loop_t* loop) { + loop->stop_flag = 1; +} + + +uint64_t uv_now(const uv_loop_t* loop) { + return loop->time; +} + + + +size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs) { + unsigned int i; + size_t bytes; + + bytes = 0; + for (i = 0; i < nbufs; i++) + bytes += (size_t) bufs[i].len; + + return bytes; +} + +int uv_recv_buffer_size(uv_handle_t* handle, int* value) { + return uv__socket_sockopt(handle, SO_RCVBUF, value); +} + +int uv_send_buffer_size(uv_handle_t* handle, int *value) { + return uv__socket_sockopt(handle, SO_SNDBUF, value); +} + +int uv_fs_event_getpath(uv_fs_event_t* handle, char* buffer, size_t* size) { + size_t required_len; + + if (!uv__is_active(handle)) { + *size = 0; + return UV_EINVAL; + } + + required_len = strlen(handle->path); + if (required_len >= *size) { + *size = required_len + 1; + return UV_ENOBUFS; + } + + memcpy(buffer, handle->path, required_len); + *size = required_len; + buffer[required_len] = '\0'; + + return 0; +} + +/* The windows implementation does not have the same structure layout as + * the unix implementation (nbufs is not directly inside req but is + * contained in a nested union/struct) so this function locates it. +*/ +static unsigned int* uv__get_nbufs(uv_fs_t* req) { +#ifdef _WIN32 + return &req->fs.info.nbufs; +#else + return &req->nbufs; +#endif +} + +/* uv_fs_scandir() uses the system allocator to allocate memory on non-Windows + * systems. So, the memory should be released using free(). On Windows, + * uv__malloc() is used, so use uv__free() to free memory. +*/ +#ifdef _WIN32 +# define uv__fs_scandir_free uv__free +#else +# define uv__fs_scandir_free free +#endif + +void uv__fs_scandir_cleanup(uv_fs_t* req) { + uv__dirent_t** dents; + + unsigned int* nbufs = uv__get_nbufs(req); + + dents = req->ptr; + if (*nbufs > 0 && *nbufs != (unsigned int) req->result) + (*nbufs)--; + for (; *nbufs < (unsigned int) req->result; (*nbufs)++) + uv__fs_scandir_free(dents[*nbufs]); + + uv__fs_scandir_free(req->ptr); + req->ptr = NULL; +} + + +int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) { + uv__dirent_t** dents; + uv__dirent_t* dent; + unsigned int* nbufs; + + /* Check to see if req passed */ + if (req->result < 0) + return req->result; + + /* Ptr will be null if req was canceled or no files found */ + if (!req->ptr) + return UV_EOF; + + nbufs = uv__get_nbufs(req); + assert(nbufs); + + dents = req->ptr; + + /* Free previous entity */ + if (*nbufs > 0) + uv__fs_scandir_free(dents[*nbufs - 1]); + + /* End was already reached */ + if (*nbufs == (unsigned int) req->result) { + uv__fs_scandir_free(dents); + req->ptr = NULL; + return UV_EOF; + } + + dent = dents[(*nbufs)++]; + + ent->name = dent->d_name; + ent->type = uv__fs_get_dirent_type(dent); + + return 0; +} + +uv_dirent_type_t uv__fs_get_dirent_type(uv__dirent_t* dent) { + uv_dirent_type_t type; + +#ifdef HAVE_DIRENT_TYPES + switch (dent->d_type) { + case UV__DT_DIR: + type = UV_DIRENT_DIR; + break; + case UV__DT_FILE: + type = UV_DIRENT_FILE; + break; + case UV__DT_LINK: + type = UV_DIRENT_LINK; + break; + case UV__DT_FIFO: + type = UV_DIRENT_FIFO; + break; + case UV__DT_SOCKET: + type = UV_DIRENT_SOCKET; + break; + case UV__DT_CHAR: + type = UV_DIRENT_CHAR; + break; + case UV__DT_BLOCK: + type = UV_DIRENT_BLOCK; + break; + default: + type = UV_DIRENT_UNKNOWN; + } +#else + type = UV_DIRENT_UNKNOWN; +#endif + + return type; +} + +void uv__fs_readdir_cleanup(uv_fs_t* req) { + uv_dir_t* dir; + uv_dirent_t* dirents; + int i; + + if (req->ptr == NULL) + return; + + dir = req->ptr; + dirents = dir->dirents; + req->ptr = NULL; + + if (dirents == NULL) + return; + + for (i = 0; i < req->result; ++i) { + uv__free((char*) dirents[i].name); + dirents[i].name = NULL; + } +} + + +int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...) { + va_list ap; + int err; + + va_start(ap, option); + /* Any platform-agnostic options should be handled here. */ + err = uv__loop_configure(loop, option, ap); + va_end(ap); + + return err; +} + + +static uv_loop_t default_loop_struct; +static uv_loop_t* default_loop_ptr; + + +uv_loop_t* uv_default_loop(void) { + if (default_loop_ptr != NULL) + return default_loop_ptr; + + if (uv_loop_init(&default_loop_struct)) + return NULL; + + default_loop_ptr = &default_loop_struct; + return default_loop_ptr; +} + + +uv_loop_t* uv_loop_new(void) { + uv_loop_t* loop; + + loop = uv__malloc(sizeof(*loop)); + if (loop == NULL) + return NULL; + + if (uv_loop_init(loop)) { + uv__free(loop); + return NULL; + } + + return loop; +} + + +int uv_loop_close(uv_loop_t* loop) { + QUEUE* q; + uv_handle_t* h; +#ifndef NDEBUG + void* saved_data; +#endif + + if (uv__has_active_reqs(loop)) + return UV_EBUSY; + + QUEUE_FOREACH(q, &loop->handle_queue) { + h = QUEUE_DATA(q, uv_handle_t, handle_queue); + if (!(h->flags & UV_HANDLE_INTERNAL)) + return UV_EBUSY; + } + + uv__loop_close(loop); + +#ifndef NDEBUG + saved_data = loop->data; + memset(loop, -1, sizeof(*loop)); + loop->data = saved_data; +#endif + if (loop == default_loop_ptr) + default_loop_ptr = NULL; + + return 0; +} + + +void uv_loop_delete(uv_loop_t* loop) { + uv_loop_t* default_loop; + int err; + + default_loop = default_loop_ptr; + + err = uv_loop_close(loop); + (void) err; /* Squelch compiler warnings. */ + assert(err == 0); + if (loop != default_loop) + uv__free(loop); +} + + +int uv_read_start(uv_stream_t* stream, + uv_alloc_cb alloc_cb, + uv_read_cb read_cb) { + if (stream == NULL || alloc_cb == NULL || read_cb == NULL) + return UV_EINVAL; + + if (stream->flags & UV_HANDLE_CLOSING) + return UV_EINVAL; + + if (stream->flags & UV_HANDLE_READING) + return UV_EALREADY; + + if (!(stream->flags & UV_HANDLE_READABLE)) + return UV_ENOTCONN; + + return uv__read_start(stream, alloc_cb, read_cb); +} + + +void uv_os_free_environ(uv_env_item_t* envitems, int count) { + int i; + + for (i = 0; i < count; i++) { + uv__free(envitems[i].name); + } + + uv__free(envitems); +} + + +void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { + int i; + + for (i = 0; i < count; i++) + uv__free(cpu_infos[i].model); + + uv__free(cpu_infos); +} + + +/* Also covers __clang__ and __INTEL_COMPILER. Disabled on Windows because + * threads have already been forcibly terminated by the operating system + * by the time destructors run, ergo, it's not safe to try to clean them up. + */ +#if defined(__GNUC__) && !defined(_WIN32) +__attribute__((destructor)) +#endif +void uv_library_shutdown(void) { + static int was_shutdown; + + if (uv__load_relaxed(&was_shutdown)) + return; + + uv__process_title_cleanup(); + uv__signal_cleanup(); + uv__threadpool_cleanup(); + uv__store_relaxed(&was_shutdown, 1); +} + + +void uv__metrics_update_idle_time(uv_loop_t* loop) { + uv__loop_metrics_t* loop_metrics; + uint64_t entry_time; + uint64_t exit_time; + + if (!(uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME)) + return; + + loop_metrics = uv__get_loop_metrics(loop); + + /* The thread running uv__metrics_update_idle_time() is always the same + * thread that sets provider_entry_time. So it's unnecessary to lock before + * retrieving this value. + */ + if (loop_metrics->provider_entry_time == 0) + return; + + exit_time = uv_hrtime(); + + uv_mutex_lock(&loop_metrics->lock); + entry_time = loop_metrics->provider_entry_time; + loop_metrics->provider_entry_time = 0; + loop_metrics->provider_idle_time += exit_time - entry_time; + uv_mutex_unlock(&loop_metrics->lock); +} + + +void uv__metrics_set_provider_entry_time(uv_loop_t* loop) { + uv__loop_metrics_t* loop_metrics; + uint64_t now; + + if (!(uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME)) + return; + + now = uv_hrtime(); + loop_metrics = uv__get_loop_metrics(loop); + uv_mutex_lock(&loop_metrics->lock); + loop_metrics->provider_entry_time = now; + uv_mutex_unlock(&loop_metrics->lock); +} + + +uint64_t uv_metrics_idle_time(uv_loop_t* loop) { + uv__loop_metrics_t* loop_metrics; + uint64_t entry_time; + uint64_t idle_time; + + loop_metrics = uv__get_loop_metrics(loop); + uv_mutex_lock(&loop_metrics->lock); + idle_time = loop_metrics->provider_idle_time; + entry_time = loop_metrics->provider_entry_time; + uv_mutex_unlock(&loop_metrics->lock); + + if (entry_time > 0) + idle_time += uv_hrtime() - entry_time; + return idle_time; +} diff --git a/external/src/libuv/src/uv-common.h b/external/src/libuv/src/uv-common.h new file mode 100644 index 0000000..8a190bf --- /dev/null +++ b/external/src/libuv/src/uv-common.h @@ -0,0 +1,373 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* + * This file is private to libuv. It provides common functionality to both + * Windows and Unix backends. + */ + +#ifndef UV_COMMON_H_ +#define UV_COMMON_H_ + +#include +#include +#include + +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "uv/stdint-msvc2008.h" +#else +# include +#endif + +#include "uv.h" +#include "uv/tree.h" +#include "queue.h" +#include "strscpy.h" + +#if EDOM > 0 +# define UV__ERR(x) (-(x)) +#else +# define UV__ERR(x) (x) +#endif + +#if !defined(snprintf) && defined(_MSC_VER) && _MSC_VER < 1900 +extern int snprintf(char*, size_t, const char*, ...); +#endif + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +#define container_of(ptr, type, member) \ + ((type *) ((char *) (ptr) - offsetof(type, member))) + +#define STATIC_ASSERT(expr) \ + void uv__static_assert(int static_assert_failed[1 - 2 * !(expr)]) + +#if defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 7) +#define uv__load_relaxed(p) __atomic_load_n(p, __ATOMIC_RELAXED) +#define uv__store_relaxed(p, v) __atomic_store_n(p, v, __ATOMIC_RELAXED) +#else +#define uv__load_relaxed(p) (*p) +#define uv__store_relaxed(p, v) do *p = v; while (0) +#endif + +#define UV__UDP_DGRAM_MAXSIZE (64 * 1024) + +/* Handle flags. Some flags are specific to Windows or UNIX. */ +enum { + /* Used by all handles. */ + UV_HANDLE_CLOSING = 0x00000001, + UV_HANDLE_CLOSED = 0x00000002, + UV_HANDLE_ACTIVE = 0x00000004, + UV_HANDLE_REF = 0x00000008, + UV_HANDLE_INTERNAL = 0x00000010, + UV_HANDLE_ENDGAME_QUEUED = 0x00000020, + + /* Used by streams. */ + UV_HANDLE_LISTENING = 0x00000040, + UV_HANDLE_CONNECTION = 0x00000080, + UV_HANDLE_SHUTTING = 0x00000100, + UV_HANDLE_SHUT = 0x00000200, + UV_HANDLE_READ_PARTIAL = 0x00000400, + UV_HANDLE_READ_EOF = 0x00000800, + + /* Used by streams and UDP handles. */ + UV_HANDLE_READING = 0x00001000, + UV_HANDLE_BOUND = 0x00002000, + UV_HANDLE_READABLE = 0x00004000, + UV_HANDLE_WRITABLE = 0x00008000, + UV_HANDLE_READ_PENDING = 0x00010000, + UV_HANDLE_SYNC_BYPASS_IOCP = 0x00020000, + UV_HANDLE_ZERO_READ = 0x00040000, + UV_HANDLE_EMULATE_IOCP = 0x00080000, + UV_HANDLE_BLOCKING_WRITES = 0x00100000, + UV_HANDLE_CANCELLATION_PENDING = 0x00200000, + + /* Used by uv_tcp_t and uv_udp_t handles */ + UV_HANDLE_IPV6 = 0x00400000, + + /* Only used by uv_tcp_t handles. */ + UV_HANDLE_TCP_NODELAY = 0x01000000, + UV_HANDLE_TCP_KEEPALIVE = 0x02000000, + UV_HANDLE_TCP_SINGLE_ACCEPT = 0x04000000, + UV_HANDLE_TCP_ACCEPT_STATE_CHANGING = 0x08000000, + UV_HANDLE_SHARED_TCP_SOCKET = 0x10000000, + + /* Only used by uv_udp_t handles. */ + UV_HANDLE_UDP_PROCESSING = 0x01000000, + UV_HANDLE_UDP_CONNECTED = 0x02000000, + UV_HANDLE_UDP_RECVMMSG = 0x04000000, + + /* Only used by uv_pipe_t handles. */ + UV_HANDLE_NON_OVERLAPPED_PIPE = 0x01000000, + UV_HANDLE_PIPESERVER = 0x02000000, + + /* Only used by uv_tty_t handles. */ + UV_HANDLE_TTY_READABLE = 0x01000000, + UV_HANDLE_TTY_RAW = 0x02000000, + UV_HANDLE_TTY_SAVED_POSITION = 0x04000000, + UV_HANDLE_TTY_SAVED_ATTRIBUTES = 0x08000000, + + /* Only used by uv_signal_t handles. */ + UV_SIGNAL_ONE_SHOT_DISPATCHED = 0x01000000, + UV_SIGNAL_ONE_SHOT = 0x02000000, + + /* Only used by uv_poll_t handles. */ + UV_HANDLE_POLL_SLOW = 0x01000000 +}; + +int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap); + +void uv__loop_close(uv_loop_t* loop); + +int uv__read_start(uv_stream_t* stream, + uv_alloc_cb alloc_cb, + uv_read_cb read_cb); + +int uv__tcp_bind(uv_tcp_t* tcp, + const struct sockaddr* addr, + unsigned int addrlen, + unsigned int flags); + +int uv__tcp_connect(uv_connect_t* req, + uv_tcp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen, + uv_connect_cb cb); + +int uv__udp_init_ex(uv_loop_t* loop, + uv_udp_t* handle, + unsigned flags, + int domain); + +int uv__udp_bind(uv_udp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen, + unsigned int flags); + +int uv__udp_connect(uv_udp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen); + +int uv__udp_disconnect(uv_udp_t* handle); + +int uv__udp_is_connected(uv_udp_t* handle); + +int uv__udp_send(uv_udp_send_t* req, + uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr, + unsigned int addrlen, + uv_udp_send_cb send_cb); + +int uv__udp_try_send(uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr, + unsigned int addrlen); + +int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloccb, + uv_udp_recv_cb recv_cb); + +int uv__udp_recv_stop(uv_udp_t* handle); + +void uv__fs_poll_close(uv_fs_poll_t* handle); + +int uv__getaddrinfo_translate_error(int sys_err); /* EAI_* error. */ + +enum uv__work_kind { + UV__WORK_CPU, + UV__WORK_FAST_IO, + UV__WORK_SLOW_IO +}; + +void uv__work_submit(uv_loop_t* loop, + struct uv__work *w, + enum uv__work_kind kind, + void (*work)(struct uv__work *w), + void (*done)(struct uv__work *w, int status)); + +void uv__work_done(uv_async_t* handle); + +size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs); + +int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value); + +void uv__fs_scandir_cleanup(uv_fs_t* req); +void uv__fs_readdir_cleanup(uv_fs_t* req); +uv_dirent_type_t uv__fs_get_dirent_type(uv__dirent_t* dent); + +int uv__next_timeout(const uv_loop_t* loop); +void uv__run_timers(uv_loop_t* loop); +void uv__timer_close(uv_timer_t* handle); + +void uv__process_title_cleanup(void); +void uv__signal_cleanup(void); +void uv__threadpool_cleanup(void); + +#define uv__has_active_reqs(loop) \ + ((loop)->active_reqs.count > 0) + +#define uv__req_register(loop, req) \ + do { \ + (loop)->active_reqs.count++; \ + } \ + while (0) + +#define uv__req_unregister(loop, req) \ + do { \ + assert(uv__has_active_reqs(loop)); \ + (loop)->active_reqs.count--; \ + } \ + while (0) + +#define uv__has_active_handles(loop) \ + ((loop)->active_handles > 0) + +#define uv__active_handle_add(h) \ + do { \ + (h)->loop->active_handles++; \ + } \ + while (0) + +#define uv__active_handle_rm(h) \ + do { \ + (h)->loop->active_handles--; \ + } \ + while (0) + +#define uv__is_active(h) \ + (((h)->flags & UV_HANDLE_ACTIVE) != 0) + +#define uv__is_closing(h) \ + (((h)->flags & (UV_HANDLE_CLOSING | UV_HANDLE_CLOSED)) != 0) + +#define uv__handle_start(h) \ + do { \ + if (((h)->flags & UV_HANDLE_ACTIVE) != 0) break; \ + (h)->flags |= UV_HANDLE_ACTIVE; \ + if (((h)->flags & UV_HANDLE_REF) != 0) uv__active_handle_add(h); \ + } \ + while (0) + +#define uv__handle_stop(h) \ + do { \ + if (((h)->flags & UV_HANDLE_ACTIVE) == 0) break; \ + (h)->flags &= ~UV_HANDLE_ACTIVE; \ + if (((h)->flags & UV_HANDLE_REF) != 0) uv__active_handle_rm(h); \ + } \ + while (0) + +#define uv__handle_ref(h) \ + do { \ + if (((h)->flags & UV_HANDLE_REF) != 0) break; \ + (h)->flags |= UV_HANDLE_REF; \ + if (((h)->flags & UV_HANDLE_CLOSING) != 0) break; \ + if (((h)->flags & UV_HANDLE_ACTIVE) != 0) uv__active_handle_add(h); \ + } \ + while (0) + +#define uv__handle_unref(h) \ + do { \ + if (((h)->flags & UV_HANDLE_REF) == 0) break; \ + (h)->flags &= ~UV_HANDLE_REF; \ + if (((h)->flags & UV_HANDLE_CLOSING) != 0) break; \ + if (((h)->flags & UV_HANDLE_ACTIVE) != 0) uv__active_handle_rm(h); \ + } \ + while (0) + +#define uv__has_ref(h) \ + (((h)->flags & UV_HANDLE_REF) != 0) + +#if defined(_WIN32) +# define uv__handle_platform_init(h) ((h)->u.fd = -1) +#else +# define uv__handle_platform_init(h) ((h)->next_closing = NULL) +#endif + +#define uv__handle_init(loop_, h, type_) \ + do { \ + (h)->loop = (loop_); \ + (h)->type = (type_); \ + (h)->flags = UV_HANDLE_REF; /* Ref the loop when active. */ \ + QUEUE_INSERT_TAIL(&(loop_)->handle_queue, &(h)->handle_queue); \ + uv__handle_platform_init(h); \ + } \ + while (0) + +/* Note: uses an open-coded version of SET_REQ_SUCCESS() because of + * a circular dependency between src/uv-common.h and src/win/internal.h. + */ +#if defined(_WIN32) +# define UV_REQ_INIT(req, typ) \ + do { \ + (req)->type = (typ); \ + (req)->u.io.overlapped.Internal = 0; /* SET_REQ_SUCCESS() */ \ + } \ + while (0) +#else +# define UV_REQ_INIT(req, typ) \ + do { \ + (req)->type = (typ); \ + } \ + while (0) +#endif + +#define uv__req_init(loop, req, typ) \ + do { \ + UV_REQ_INIT(req, typ); \ + uv__req_register(loop, req); \ + } \ + while (0) + +#define uv__get_internal_fields(loop) \ + ((uv__loop_internal_fields_t*) loop->internal_fields) + +#define uv__get_loop_metrics(loop) \ + (&uv__get_internal_fields(loop)->loop_metrics) + +/* Allocator prototypes */ +void *uv__calloc(size_t count, size_t size); +char *uv__strdup(const char* s); +char *uv__strndup(const char* s, size_t n); +void* uv__malloc(size_t size); +void uv__free(void* ptr); +void* uv__realloc(void* ptr, size_t size); +void* uv__reallocf(void* ptr, size_t size); + +typedef struct uv__loop_metrics_s uv__loop_metrics_t; +typedef struct uv__loop_internal_fields_s uv__loop_internal_fields_t; + +struct uv__loop_metrics_s { + uint64_t provider_entry_time; + uint64_t provider_idle_time; + uv_mutex_t lock; +}; + +void uv__metrics_update_idle_time(uv_loop_t* loop); +void uv__metrics_set_provider_entry_time(uv_loop_t* loop); + +struct uv__loop_internal_fields_s { + unsigned int flags; + uv__loop_metrics_t loop_metrics; +}; + +#endif /* UV_COMMON_H_ */ diff --git a/external/src/libuv/src/uv-data-getter-setters.c b/external/src/libuv/src/uv-data-getter-setters.c new file mode 100644 index 0000000..0bd0448 --- /dev/null +++ b/external/src/libuv/src/uv-data-getter-setters.c @@ -0,0 +1,119 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" + +const char* uv_handle_type_name(uv_handle_type type) { + switch (type) { +#define XX(uc,lc) case UV_##uc: return #lc; + UV_HANDLE_TYPE_MAP(XX) +#undef XX + case UV_FILE: return "file"; + case UV_HANDLE_TYPE_MAX: + case UV_UNKNOWN_HANDLE: return NULL; + } + return NULL; +} + +uv_handle_type uv_handle_get_type(const uv_handle_t* handle) { + return handle->type; +} + +void* uv_handle_get_data(const uv_handle_t* handle) { + return handle->data; +} + +uv_loop_t* uv_handle_get_loop(const uv_handle_t* handle) { + return handle->loop; +} + +void uv_handle_set_data(uv_handle_t* handle, void* data) { + handle->data = data; +} + +const char* uv_req_type_name(uv_req_type type) { + switch (type) { +#define XX(uc,lc) case UV_##uc: return #lc; + UV_REQ_TYPE_MAP(XX) +#undef XX + case UV_REQ_TYPE_MAX: + case UV_UNKNOWN_REQ: + default: /* UV_REQ_TYPE_PRIVATE */ + break; + } + return NULL; +} + +uv_req_type uv_req_get_type(const uv_req_t* req) { + return req->type; +} + +void* uv_req_get_data(const uv_req_t* req) { + return req->data; +} + +void uv_req_set_data(uv_req_t* req, void* data) { + req->data = data; +} + +size_t uv_stream_get_write_queue_size(const uv_stream_t* stream) { + return stream->write_queue_size; +} + +size_t uv_udp_get_send_queue_size(const uv_udp_t* handle) { + return handle->send_queue_size; +} + +size_t uv_udp_get_send_queue_count(const uv_udp_t* handle) { + return handle->send_queue_count; +} + +uv_pid_t uv_process_get_pid(const uv_process_t* proc) { + return proc->pid; +} + +uv_fs_type uv_fs_get_type(const uv_fs_t* req) { + return req->fs_type; +} + +ssize_t uv_fs_get_result(const uv_fs_t* req) { + return req->result; +} + +void* uv_fs_get_ptr(const uv_fs_t* req) { + return req->ptr; +} + +const char* uv_fs_get_path(const uv_fs_t* req) { + return req->path; +} + +uv_stat_t* uv_fs_get_statbuf(uv_fs_t* req) { + return &req->statbuf; +} + +void* uv_loop_get_data(const uv_loop_t* loop) { + return loop->data; +} + +void uv_loop_set_data(uv_loop_t* loop, void* data) { + loop->data = data; +} diff --git a/external/src/libuv/src/version.c b/external/src/libuv/src/version.c new file mode 100644 index 0000000..686dedd --- /dev/null +++ b/external/src/libuv/src/version.c @@ -0,0 +1,45 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" + +#define UV_STRINGIFY(v) UV_STRINGIFY_HELPER(v) +#define UV_STRINGIFY_HELPER(v) #v + +#define UV_VERSION_STRING_BASE UV_STRINGIFY(UV_VERSION_MAJOR) "." \ + UV_STRINGIFY(UV_VERSION_MINOR) "." \ + UV_STRINGIFY(UV_VERSION_PATCH) + +#if UV_VERSION_IS_RELEASE +# define UV_VERSION_STRING UV_VERSION_STRING_BASE +#else +# define UV_VERSION_STRING UV_VERSION_STRING_BASE "-" UV_VERSION_SUFFIX +#endif + + +unsigned int uv_version(void) { + return UV_VERSION_HEX; +} + + +const char* uv_version_string(void) { + return UV_VERSION_STRING; +} diff --git a/external/src/libuv/src/win/async.c b/external/src/libuv/src/win/async.c new file mode 100644 index 0000000..d787f66 --- /dev/null +++ b/external/src/libuv/src/win/async.c @@ -0,0 +1,98 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include + +#include "uv.h" +#include "internal.h" +#include "atomicops-inl.h" +#include "handle-inl.h" +#include "req-inl.h" + + +void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle) { + if (handle->flags & UV_HANDLE_CLOSING && + !handle->async_sent) { + assert(!(handle->flags & UV_HANDLE_CLOSED)); + uv__handle_close(handle); + } +} + + +int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { + uv_req_t* req; + + uv__handle_init(loop, (uv_handle_t*) handle, UV_ASYNC); + handle->async_sent = 0; + handle->async_cb = async_cb; + + req = &handle->async_req; + UV_REQ_INIT(req, UV_WAKEUP); + req->data = handle; + + uv__handle_start(handle); + + return 0; +} + + +void uv_async_close(uv_loop_t* loop, uv_async_t* handle) { + if (!((uv_async_t*)handle)->async_sent) { + uv_want_endgame(loop, (uv_handle_t*) handle); + } + + uv__handle_closing(handle); +} + + +int uv_async_send(uv_async_t* handle) { + uv_loop_t* loop = handle->loop; + + if (handle->type != UV_ASYNC) { + /* Can't set errno because that's not thread-safe. */ + return -1; + } + + /* The user should make sure never to call uv_async_send to a closing or + * closed handle. */ + assert(!(handle->flags & UV_HANDLE_CLOSING)); + + if (!uv__atomic_exchange_set(&handle->async_sent)) { + POST_COMPLETION_FOR_REQ(loop, &handle->async_req); + } + + return 0; +} + + +void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle, + uv_req_t* req) { + assert(handle->type == UV_ASYNC); + assert(req->type == UV_WAKEUP); + + handle->async_sent = 0; + + if (handle->flags & UV_HANDLE_CLOSING) { + uv_want_endgame(loop, (uv_handle_t*)handle); + } else if (handle->async_cb != NULL) { + handle->async_cb(handle); + } +} diff --git a/external/src/libuv/src/win/atomicops-inl.h b/external/src/libuv/src/win/atomicops-inl.h new file mode 100644 index 0000000..2f984c6 --- /dev/null +++ b/external/src/libuv/src/win/atomicops-inl.h @@ -0,0 +1,61 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_WIN_ATOMICOPS_INL_H_ +#define UV_WIN_ATOMICOPS_INL_H_ + +#include "uv.h" +#include "internal.h" + + +/* Atomic set operation on char */ +#ifdef _MSC_VER /* MSVC */ + +/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less + * efficient than InterlockedExchange, but InterlockedExchange8 does not exist, + * and interlocked operations on larger targets might require the target to be + * aligned. */ +#pragma intrinsic(_InterlockedOr8) + +static char INLINE uv__atomic_exchange_set(char volatile* target) { + return _InterlockedOr8(target, 1); +} + +#else /* GCC, Clang in mingw mode */ + +static inline char uv__atomic_exchange_set(char volatile* target) { +#if defined(__i386__) || defined(__x86_64__) + /* Mingw-32 version, hopefully this works for 64-bit gcc as well. */ + const char one = 1; + char old_value; + __asm__ __volatile__ ("lock xchgb %0, %1\n\t" + : "=r"(old_value), "=m"(*target) + : "0"(one), "m"(*target) + : "memory"); + return old_value; +#else + return __sync_fetch_and_or(target, 1); +#endif +} + +#endif + +#endif /* UV_WIN_ATOMICOPS_INL_H_ */ diff --git a/external/src/libuv/src/win/core.c b/external/src/libuv/src/win/core.c new file mode 100644 index 0000000..e53a0f8 --- /dev/null +++ b/external/src/libuv/src/win/core.c @@ -0,0 +1,748 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR) +#include +#endif + +#include "uv.h" +#include "internal.h" +#include "queue.h" +#include "handle-inl.h" +#include "heap-inl.h" +#include "req-inl.h" + +/* uv_once initialization guards */ +static uv_once_t uv_init_guard_ = UV_ONCE_INIT; + + +#if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)) +/* Our crt debug report handler allows us to temporarily disable asserts + * just for the current thread. + */ + +UV_THREAD_LOCAL int uv__crt_assert_enabled = TRUE; + +static int uv__crt_dbg_report_handler(int report_type, char *message, int *ret_val) { + if (uv__crt_assert_enabled || report_type != _CRT_ASSERT) + return FALSE; + + if (ret_val) { + /* Set ret_val to 0 to continue with normal execution. + * Set ret_val to 1 to trigger a breakpoint. + */ + + if(IsDebuggerPresent()) + *ret_val = 1; + else + *ret_val = 0; + } + + /* Don't call _CrtDbgReport. */ + return TRUE; +} +#else +UV_THREAD_LOCAL int uv__crt_assert_enabled = FALSE; +#endif + + +#if !defined(__MINGW32__) || __MSVCRT_VERSION__ >= 0x800 +static void uv__crt_invalid_parameter_handler(const wchar_t* expression, + const wchar_t* function, const wchar_t * file, unsigned int line, + uintptr_t reserved) { + /* No-op. */ +} +#endif + +static uv_loop_t** uv__loops; +static int uv__loops_size; +static int uv__loops_capacity; +#define UV__LOOPS_CHUNK_SIZE 8 +static uv_mutex_t uv__loops_lock; + +static void uv__loops_init(void) { + uv_mutex_init(&uv__loops_lock); +} + +static int uv__loops_add(uv_loop_t* loop) { + uv_loop_t** new_loops; + int new_capacity, i; + + uv_mutex_lock(&uv__loops_lock); + + if (uv__loops_size == uv__loops_capacity) { + new_capacity = uv__loops_capacity + UV__LOOPS_CHUNK_SIZE; + new_loops = uv__realloc(uv__loops, sizeof(uv_loop_t*) * new_capacity); + if (!new_loops) + goto failed_loops_realloc; + uv__loops = new_loops; + for (i = uv__loops_capacity; i < new_capacity; ++i) + uv__loops[i] = NULL; + uv__loops_capacity = new_capacity; + } + uv__loops[uv__loops_size] = loop; + ++uv__loops_size; + + uv_mutex_unlock(&uv__loops_lock); + return 0; + +failed_loops_realloc: + uv_mutex_unlock(&uv__loops_lock); + return ERROR_OUTOFMEMORY; +} + +static void uv__loops_remove(uv_loop_t* loop) { + int loop_index; + int smaller_capacity; + uv_loop_t** new_loops; + + uv_mutex_lock(&uv__loops_lock); + + for (loop_index = 0; loop_index < uv__loops_size; ++loop_index) { + if (uv__loops[loop_index] == loop) + break; + } + /* If loop was not found, ignore */ + if (loop_index == uv__loops_size) + goto loop_removed; + + uv__loops[loop_index] = uv__loops[uv__loops_size - 1]; + uv__loops[uv__loops_size - 1] = NULL; + --uv__loops_size; + + if (uv__loops_size == 0) { + uv__loops_capacity = 0; + uv__free(uv__loops); + uv__loops = NULL; + goto loop_removed; + } + + /* If we didn't grow to big skip downsizing */ + if (uv__loops_capacity < 4 * UV__LOOPS_CHUNK_SIZE) + goto loop_removed; + + /* Downsize only if more than half of buffer is free */ + smaller_capacity = uv__loops_capacity / 2; + if (uv__loops_size >= smaller_capacity) + goto loop_removed; + new_loops = uv__realloc(uv__loops, sizeof(uv_loop_t*) * smaller_capacity); + if (!new_loops) + goto loop_removed; + uv__loops = new_loops; + uv__loops_capacity = smaller_capacity; + +loop_removed: + uv_mutex_unlock(&uv__loops_lock); +} + +void uv__wake_all_loops(void) { + int i; + uv_loop_t* loop; + + uv_mutex_lock(&uv__loops_lock); + for (i = 0; i < uv__loops_size; ++i) { + loop = uv__loops[i]; + assert(loop); + if (loop->iocp != INVALID_HANDLE_VALUE) + PostQueuedCompletionStatus(loop->iocp, 0, 0, NULL); + } + uv_mutex_unlock(&uv__loops_lock); +} + +static void uv_init(void) { + /* Tell Windows that we will handle critical errors. */ + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | + SEM_NOOPENFILEERRORBOX); + + /* Tell the CRT to not exit the application when an invalid parameter is + * passed. The main issue is that invalid FDs will trigger this behavior. + */ +#if !defined(__MINGW32__) || __MSVCRT_VERSION__ >= 0x800 + _set_invalid_parameter_handler(uv__crt_invalid_parameter_handler); +#endif + + /* We also need to setup our debug report handler because some CRT + * functions (eg _get_osfhandle) raise an assert when called with invalid + * FDs even though they return the proper error code in the release build. + */ +#if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)) + _CrtSetReportHook(uv__crt_dbg_report_handler); +#endif + + /* Initialize tracking of all uv loops */ + uv__loops_init(); + + /* Fetch winapi function pointers. This must be done first because other + * initialization code might need these function pointers to be loaded. + */ + uv_winapi_init(); + + /* Initialize winsock */ + uv_winsock_init(); + + /* Initialize FS */ + uv_fs_init(); + + /* Initialize signal stuff */ + uv_signals_init(); + + /* Initialize console */ + uv_console_init(); + + /* Initialize utilities */ + uv__util_init(); + + /* Initialize system wakeup detection */ + uv__init_detect_system_wakeup(); +} + + +int uv_loop_init(uv_loop_t* loop) { + uv__loop_internal_fields_t* lfields; + struct heap* timer_heap; + int err; + + /* Initialize libuv itself first */ + uv__once_init(); + + /* Create an I/O completion port */ + loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); + if (loop->iocp == NULL) + return uv_translate_sys_error(GetLastError()); + + lfields = (uv__loop_internal_fields_t*) uv__calloc(1, sizeof(*lfields)); + if (lfields == NULL) + return UV_ENOMEM; + loop->internal_fields = lfields; + + err = uv_mutex_init(&lfields->loop_metrics.lock); + if (err) + goto fail_metrics_mutex_init; + + /* To prevent uninitialized memory access, loop->time must be initialized + * to zero before calling uv_update_time for the first time. + */ + loop->time = 0; + uv_update_time(loop); + + QUEUE_INIT(&loop->wq); + QUEUE_INIT(&loop->handle_queue); + loop->active_reqs.count = 0; + loop->active_handles = 0; + + loop->pending_reqs_tail = NULL; + + loop->endgame_handles = NULL; + + loop->timer_heap = timer_heap = uv__malloc(sizeof(*timer_heap)); + if (timer_heap == NULL) { + err = UV_ENOMEM; + goto fail_timers_alloc; + } + + heap_init(timer_heap); + + loop->check_handles = NULL; + loop->prepare_handles = NULL; + loop->idle_handles = NULL; + + loop->next_prepare_handle = NULL; + loop->next_check_handle = NULL; + loop->next_idle_handle = NULL; + + memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets); + + loop->active_tcp_streams = 0; + loop->active_udp_streams = 0; + + loop->timer_counter = 0; + loop->stop_flag = 0; + + err = uv_mutex_init(&loop->wq_mutex); + if (err) + goto fail_mutex_init; + + err = uv_async_init(loop, &loop->wq_async, uv__work_done); + if (err) + goto fail_async_init; + + uv__handle_unref(&loop->wq_async); + loop->wq_async.flags |= UV_HANDLE_INTERNAL; + + err = uv__loops_add(loop); + if (err) + goto fail_async_init; + + return 0; + +fail_async_init: + uv_mutex_destroy(&loop->wq_mutex); + +fail_mutex_init: + uv__free(timer_heap); + loop->timer_heap = NULL; + +fail_timers_alloc: + uv_mutex_destroy(&lfields->loop_metrics.lock); + +fail_metrics_mutex_init: + uv__free(lfields); + loop->internal_fields = NULL; + CloseHandle(loop->iocp); + loop->iocp = INVALID_HANDLE_VALUE; + + return err; +} + + +void uv_update_time(uv_loop_t* loop) { + uint64_t new_time = uv__hrtime(1000); + assert(new_time >= loop->time); + loop->time = new_time; +} + + +void uv__once_init(void) { + uv_once(&uv_init_guard_, uv_init); +} + + +void uv__loop_close(uv_loop_t* loop) { + uv__loop_internal_fields_t* lfields; + size_t i; + + uv__loops_remove(loop); + + /* Close the async handle without needing an extra loop iteration. + * We might have a pending message, but we're just going to destroy the IOCP + * soon, so we can just discard it now without the usual risk of a getting + * another notification from GetQueuedCompletionStatusEx after calling the + * close_cb (which we also skip defining). We'll assert later that queue was + * actually empty and all reqs handled. */ + loop->wq_async.async_sent = 0; + loop->wq_async.close_cb = NULL; + uv__handle_closing(&loop->wq_async); + uv__handle_close(&loop->wq_async); + + for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) { + SOCKET sock = loop->poll_peer_sockets[i]; + if (sock != 0 && sock != INVALID_SOCKET) + closesocket(sock); + } + + uv_mutex_lock(&loop->wq_mutex); + assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!"); + assert(!uv__has_active_reqs(loop)); + uv_mutex_unlock(&loop->wq_mutex); + uv_mutex_destroy(&loop->wq_mutex); + + uv__free(loop->timer_heap); + loop->timer_heap = NULL; + + lfields = uv__get_internal_fields(loop); + uv_mutex_destroy(&lfields->loop_metrics.lock); + uv__free(lfields); + loop->internal_fields = NULL; + + CloseHandle(loop->iocp); +} + + +int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) { + uv__loop_internal_fields_t* lfields; + + lfields = uv__get_internal_fields(loop); + if (option == UV_METRICS_IDLE_TIME) { + lfields->flags |= UV_METRICS_IDLE_TIME; + return 0; + } + + return UV_ENOSYS; +} + + +int uv_backend_fd(const uv_loop_t* loop) { + return -1; +} + + +int uv_loop_fork(uv_loop_t* loop) { + return UV_ENOSYS; +} + + +int uv_backend_timeout(const uv_loop_t* loop) { + if (loop->stop_flag != 0) + return 0; + + if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop)) + return 0; + + if (loop->pending_reqs_tail) + return 0; + + if (loop->endgame_handles) + return 0; + + if (loop->idle_handles) + return 0; + + return uv__next_timeout(loop); +} + + +static void uv__poll_wine(uv_loop_t* loop, DWORD timeout) { + DWORD bytes; + ULONG_PTR key; + OVERLAPPED* overlapped; + uv_req_t* req; + int repeat; + uint64_t timeout_time; + uint64_t user_timeout; + int reset_timeout; + + timeout_time = loop->time + timeout; + + if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) { + reset_timeout = 1; + user_timeout = timeout; + timeout = 0; + } else { + reset_timeout = 0; + } + + for (repeat = 0; ; repeat++) { + /* Only need to set the provider_entry_time if timeout != 0. The function + * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME. + */ + if (timeout != 0) + uv__metrics_set_provider_entry_time(loop); + + GetQueuedCompletionStatus(loop->iocp, + &bytes, + &key, + &overlapped, + timeout); + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + /* Placed here because on success the loop will break whether there is an + * empty package or not, or if GetQueuedCompletionStatus returned early then + * the timeout will be updated and the loop will run again. In either case + * the idle time will need to be updated. + */ + uv__metrics_update_idle_time(loop); + + if (overlapped) { + /* Package was dequeued */ + req = uv_overlapped_to_req(overlapped); + uv_insert_pending_req(loop, req); + + /* Some time might have passed waiting for I/O, + * so update the loop time here. + */ + uv_update_time(loop); + } else if (GetLastError() != WAIT_TIMEOUT) { + /* Serious error */ + uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus"); + } else if (timeout > 0) { + /* GetQueuedCompletionStatus can occasionally return a little early. + * Make sure that the desired timeout target time is reached. + */ + uv_update_time(loop); + if (timeout_time > loop->time) { + timeout = (DWORD)(timeout_time - loop->time); + /* The first call to GetQueuedCompletionStatus should return very + * close to the target time and the second should reach it, but + * this is not stated in the documentation. To make sure a busy + * loop cannot happen, the timeout is increased exponentially + * starting on the third round. + */ + timeout += repeat ? (1 << (repeat - 1)) : 0; + continue; + } + } + break; + } +} + + +static void uv__poll(uv_loop_t* loop, DWORD timeout) { + BOOL success; + uv_req_t* req; + OVERLAPPED_ENTRY overlappeds[128]; + ULONG count; + ULONG i; + int repeat; + uint64_t timeout_time; + uint64_t user_timeout; + int reset_timeout; + + timeout_time = loop->time + timeout; + + if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) { + reset_timeout = 1; + user_timeout = timeout; + timeout = 0; + } else { + reset_timeout = 0; + } + + for (repeat = 0; ; repeat++) { + /* Only need to set the provider_entry_time if timeout != 0. The function + * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME. + */ + if (timeout != 0) + uv__metrics_set_provider_entry_time(loop); + + success = pGetQueuedCompletionStatusEx(loop->iocp, + overlappeds, + ARRAY_SIZE(overlappeds), + &count, + timeout, + FALSE); + + if (reset_timeout != 0) { + timeout = user_timeout; + reset_timeout = 0; + } + + /* Placed here because on success the loop will break whether there is an + * empty package or not, or if GetQueuedCompletionStatus returned early then + * the timeout will be updated and the loop will run again. In either case + * the idle time will need to be updated. + */ + uv__metrics_update_idle_time(loop); + + if (success) { + for (i = 0; i < count; i++) { + /* Package was dequeued, but see if it is not a empty package + * meant only to wake us up. + */ + if (overlappeds[i].lpOverlapped) { + req = uv_overlapped_to_req(overlappeds[i].lpOverlapped); + uv_insert_pending_req(loop, req); + } + } + + /* Some time might have passed waiting for I/O, + * so update the loop time here. + */ + uv_update_time(loop); + } else if (GetLastError() != WAIT_TIMEOUT) { + /* Serious error */ + uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx"); + } else if (timeout > 0) { + /* GetQueuedCompletionStatus can occasionally return a little early. + * Make sure that the desired timeout target time is reached. + */ + uv_update_time(loop); + if (timeout_time > loop->time) { + timeout = (DWORD)(timeout_time - loop->time); + /* The first call to GetQueuedCompletionStatus should return very + * close to the target time and the second should reach it, but + * this is not stated in the documentation. To make sure a busy + * loop cannot happen, the timeout is increased exponentially + * starting on the third round. + */ + timeout += repeat ? (1 << (repeat - 1)) : 0; + continue; + } + } + break; + } +} + + +static int uv__loop_alive(const uv_loop_t* loop) { + return uv__has_active_handles(loop) || + uv__has_active_reqs(loop) || + loop->endgame_handles != NULL; +} + + +int uv_loop_alive(const uv_loop_t* loop) { + return uv__loop_alive(loop); +} + + +int uv_run(uv_loop_t *loop, uv_run_mode mode) { + DWORD timeout; + int r; + int ran_pending; + + r = uv__loop_alive(loop); + if (!r) + uv_update_time(loop); + + while (r != 0 && loop->stop_flag == 0) { + uv_update_time(loop); + uv__run_timers(loop); + + ran_pending = uv_process_reqs(loop); + uv_idle_invoke(loop); + uv_prepare_invoke(loop); + + timeout = 0; + if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT) + timeout = uv_backend_timeout(loop); + + if (pGetQueuedCompletionStatusEx) + uv__poll(loop, timeout); + else + uv__poll_wine(loop, timeout); + + /* Run one final update on the provider_idle_time in case uv__poll* + * returned because the timeout expired, but no events were received. This + * call will be ignored if the provider_entry_time was either never set (if + * the timeout == 0) or was already updated b/c an event was received. + */ + uv__metrics_update_idle_time(loop); + + uv_check_invoke(loop); + uv_process_endgames(loop); + + if (mode == UV_RUN_ONCE) { + /* UV_RUN_ONCE implies forward progress: at least one callback must have + * been invoked when it returns. uv__io_poll() can return without doing + * I/O (meaning: no callbacks) when its timeout expires - which means we + * have pending timers that satisfy the forward progress constraint. + * + * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from + * the check. + */ + uv__run_timers(loop); + } + + r = uv__loop_alive(loop); + if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT) + break; + } + + /* The if statement lets the compiler compile it to a conditional store. + * Avoids dirtying a cache line. + */ + if (loop->stop_flag != 0) + loop->stop_flag = 0; + + return r; +} + + +int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) { + uv_os_fd_t fd_out; + + switch (handle->type) { + case UV_TCP: + fd_out = (uv_os_fd_t)((uv_tcp_t*) handle)->socket; + break; + + case UV_NAMED_PIPE: + fd_out = ((uv_pipe_t*) handle)->handle; + break; + + case UV_TTY: + fd_out = ((uv_tty_t*) handle)->handle; + break; + + case UV_UDP: + fd_out = (uv_os_fd_t)((uv_udp_t*) handle)->socket; + break; + + case UV_POLL: + fd_out = (uv_os_fd_t)((uv_poll_t*) handle)->socket; + break; + + default: + return UV_EINVAL; + } + + if (uv_is_closing(handle) || fd_out == INVALID_HANDLE_VALUE) + return UV_EBADF; + + *fd = fd_out; + return 0; +} + + +int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) { + int r; + int len; + SOCKET socket; + + if (handle == NULL || value == NULL) + return UV_EINVAL; + + if (handle->type == UV_TCP) + socket = ((uv_tcp_t*) handle)->socket; + else if (handle->type == UV_UDP) + socket = ((uv_udp_t*) handle)->socket; + else + return UV_ENOTSUP; + + len = sizeof(*value); + + if (*value == 0) + r = getsockopt(socket, SOL_SOCKET, optname, (char*) value, &len); + else + r = setsockopt(socket, SOL_SOCKET, optname, (const char*) value, len); + + if (r == SOCKET_ERROR) + return uv_translate_sys_error(WSAGetLastError()); + + return 0; +} + +int uv_cpumask_size(void) { + return (int)(sizeof(DWORD_PTR) * 8); +} + +int uv__getsockpeername(const uv_handle_t* handle, + uv__peersockfunc func, + struct sockaddr* name, + int* namelen, + int delayed_error) { + + int result; + uv_os_fd_t fd; + + result = uv_fileno(handle, &fd); + if (result != 0) + return result; + + if (delayed_error) + return uv_translate_sys_error(delayed_error); + + result = func((SOCKET) fd, name, namelen); + if (result != 0) + return uv_translate_sys_error(WSAGetLastError()); + + return 0; +} diff --git a/external/src/libuv/src/win/detect-wakeup.c b/external/src/libuv/src/win/detect-wakeup.c new file mode 100644 index 0000000..ab19361 --- /dev/null +++ b/external/src/libuv/src/win/detect-wakeup.c @@ -0,0 +1,56 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" +#include "winapi.h" + +static void uv__register_system_resume_callback(void); + +void uv__init_detect_system_wakeup(void) { + /* Try registering system power event callback. This is the cleanest + * method, but it will only work on Win8 and above. + */ + uv__register_system_resume_callback(); +} + +static ULONG CALLBACK uv__system_resume_callback(PVOID Context, + ULONG Type, + PVOID Setting) { + if (Type == PBT_APMRESUMESUSPEND || Type == PBT_APMRESUMEAUTOMATIC) + uv__wake_all_loops(); + + return 0; +} + +static void uv__register_system_resume_callback(void) { + _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS recipient; + _HPOWERNOTIFY registration_handle; + + if (pPowerRegisterSuspendResumeNotification == NULL) + return; + + recipient.Callback = uv__system_resume_callback; + recipient.Context = NULL; + (*pPowerRegisterSuspendResumeNotification)(DEVICE_NOTIFY_CALLBACK, + &recipient, + ®istration_handle); +} diff --git a/external/src/libuv/src/win/dl.c b/external/src/libuv/src/win/dl.c new file mode 100644 index 0000000..676be4d --- /dev/null +++ b/external/src/libuv/src/win/dl.c @@ -0,0 +1,136 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +static int uv__dlerror(uv_lib_t* lib, const char* filename, DWORD errorno); + + +int uv_dlopen(const char* filename, uv_lib_t* lib) { + WCHAR filename_w[32768]; + + lib->handle = NULL; + lib->errmsg = NULL; + + if (!MultiByteToWideChar(CP_UTF8, + 0, + filename, + -1, + filename_w, + ARRAY_SIZE(filename_w))) { + return uv__dlerror(lib, filename, GetLastError()); + } + + lib->handle = LoadLibraryExW(filename_w, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); + if (lib->handle == NULL) { + return uv__dlerror(lib, filename, GetLastError()); + } + + return 0; +} + + +void uv_dlclose(uv_lib_t* lib) { + if (lib->errmsg) { + LocalFree((void*)lib->errmsg); + lib->errmsg = NULL; + } + + if (lib->handle) { + /* Ignore errors. No good way to signal them without leaking memory. */ + FreeLibrary(lib->handle); + lib->handle = NULL; + } +} + + +int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) { + /* Cast though integer to suppress pedantic warning about forbidden cast. */ + *ptr = (void*)(uintptr_t) GetProcAddress(lib->handle, name); + return uv__dlerror(lib, "", *ptr ? 0 : GetLastError()); +} + + +const char* uv_dlerror(const uv_lib_t* lib) { + return lib->errmsg ? lib->errmsg : "no error"; +} + + +static void uv__format_fallback_error(uv_lib_t* lib, int errorno){ + static const CHAR fallback_error[] = "error: %1!d!"; + DWORD_PTR args[1]; + args[0] = (DWORD_PTR) errorno; + + FormatMessageA(FORMAT_MESSAGE_FROM_STRING | + FORMAT_MESSAGE_ARGUMENT_ARRAY | + FORMAT_MESSAGE_ALLOCATE_BUFFER, + fallback_error, 0, 0, + (LPSTR) &lib->errmsg, + 0, (va_list*) args); +} + + + +static int uv__dlerror(uv_lib_t* lib, const char* filename, DWORD errorno) { + DWORD_PTR arg; + DWORD res; + char* msg; + + if (lib->errmsg) { + LocalFree(lib->errmsg); + lib->errmsg = NULL; + } + + if (errorno == 0) + return 0; + + res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, + MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), + (LPSTR) &lib->errmsg, 0, NULL); + + if (!res && (GetLastError() == ERROR_MUI_FILE_NOT_FOUND || + GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND)) { + res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, + 0, (LPSTR) &lib->errmsg, 0, NULL); + } + + if (res && errorno == ERROR_BAD_EXE_FORMAT && strstr(lib->errmsg, "%1")) { + msg = lib->errmsg; + lib->errmsg = NULL; + arg = (DWORD_PTR) filename; + res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_ARGUMENT_ARRAY | + FORMAT_MESSAGE_FROM_STRING, + msg, + 0, 0, (LPSTR) &lib->errmsg, 0, (va_list*) &arg); + LocalFree(msg); + } + + if (!res) + uv__format_fallback_error(lib, errorno); + + return -1; +} diff --git a/external/src/libuv/src/win/error.c b/external/src/libuv/src/win/error.c new file mode 100644 index 0000000..3a269da --- /dev/null +++ b/external/src/libuv/src/win/error.c @@ -0,0 +1,173 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "uv.h" +#include "internal.h" + + +/* + * Display an error message and abort the event loop. + */ +void uv_fatal_error(const int errorno, const char* syscall) { + char* buf = NULL; + const char* errmsg; + + FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buf, 0, NULL); + + if (buf) { + errmsg = buf; + } else { + errmsg = "Unknown error"; + } + + /* FormatMessage messages include a newline character already, so don't add + * another. */ + if (syscall) { + fprintf(stderr, "%s: (%d) %s", syscall, errorno, errmsg); + } else { + fprintf(stderr, "(%d) %s", errorno, errmsg); + } + + if (buf) { + LocalFree(buf); + } + + DebugBreak(); + abort(); +} + + +int uv_translate_sys_error(int sys_errno) { + if (sys_errno <= 0) { + return sys_errno; /* If < 0 then it's already a libuv error. */ + } + + switch (sys_errno) { + case ERROR_NOACCESS: return UV_EACCES; + case WSAEACCES: return UV_EACCES; + case ERROR_ELEVATION_REQUIRED: return UV_EACCES; + case ERROR_CANT_ACCESS_FILE: return UV_EACCES; + case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE; + case WSAEADDRINUSE: return UV_EADDRINUSE; + case WSAEADDRNOTAVAIL: return UV_EADDRNOTAVAIL; + case WSAEAFNOSUPPORT: return UV_EAFNOSUPPORT; + case WSAEWOULDBLOCK: return UV_EAGAIN; + case WSAEALREADY: return UV_EALREADY; + case ERROR_INVALID_FLAGS: return UV_EBADF; + case ERROR_INVALID_HANDLE: return UV_EBADF; + case ERROR_LOCK_VIOLATION: return UV_EBUSY; + case ERROR_PIPE_BUSY: return UV_EBUSY; + case ERROR_SHARING_VIOLATION: return UV_EBUSY; + case ERROR_OPERATION_ABORTED: return UV_ECANCELED; + case WSAEINTR: return UV_ECANCELED; + case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET; + case ERROR_CONNECTION_ABORTED: return UV_ECONNABORTED; + case WSAECONNABORTED: return UV_ECONNABORTED; + case ERROR_CONNECTION_REFUSED: return UV_ECONNREFUSED; + case WSAECONNREFUSED: return UV_ECONNREFUSED; + case ERROR_NETNAME_DELETED: return UV_ECONNRESET; + case WSAECONNRESET: return UV_ECONNRESET; + case ERROR_ALREADY_EXISTS: return UV_EEXIST; + case ERROR_FILE_EXISTS: return UV_EEXIST; + case ERROR_BUFFER_OVERFLOW: return UV_EFAULT; + case WSAEFAULT: return UV_EFAULT; + case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH; + case WSAEHOSTUNREACH: return UV_EHOSTUNREACH; + case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL; + case ERROR_INVALID_DATA: return UV_EINVAL; + case ERROR_INVALID_PARAMETER: return UV_EINVAL; + case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL; + case WSAEINVAL: return UV_EINVAL; + case WSAEPFNOSUPPORT: return UV_EINVAL; + case ERROR_BEGINNING_OF_MEDIA: return UV_EIO; + case ERROR_BUS_RESET: return UV_EIO; + case ERROR_CRC: return UV_EIO; + case ERROR_DEVICE_DOOR_OPEN: return UV_EIO; + case ERROR_DEVICE_REQUIRES_CLEANING: return UV_EIO; + case ERROR_DISK_CORRUPT: return UV_EIO; + case ERROR_EOM_OVERFLOW: return UV_EIO; + case ERROR_FILEMARK_DETECTED: return UV_EIO; + case ERROR_GEN_FAILURE: return UV_EIO; + case ERROR_INVALID_BLOCK_LENGTH: return UV_EIO; + case ERROR_IO_DEVICE: return UV_EIO; + case ERROR_NO_DATA_DETECTED: return UV_EIO; + case ERROR_NO_SIGNAL_SENT: return UV_EIO; + case ERROR_OPEN_FAILED: return UV_EIO; + case ERROR_SETMARK_DETECTED: return UV_EIO; + case ERROR_SIGNAL_REFUSED: return UV_EIO; + case WSAEISCONN: return UV_EISCONN; + case ERROR_CANT_RESOLVE_FILENAME: return UV_ELOOP; + case ERROR_TOO_MANY_OPEN_FILES: return UV_EMFILE; + case WSAEMFILE: return UV_EMFILE; + case WSAEMSGSIZE: return UV_EMSGSIZE; + case ERROR_FILENAME_EXCED_RANGE: return UV_ENAMETOOLONG; + case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH; + case WSAENETUNREACH: return UV_ENETUNREACH; + case WSAENOBUFS: return UV_ENOBUFS; + case ERROR_BAD_PATHNAME: return UV_ENOENT; + case ERROR_DIRECTORY: return UV_ENOENT; + case ERROR_ENVVAR_NOT_FOUND: return UV_ENOENT; + case ERROR_FILE_NOT_FOUND: return UV_ENOENT; + case ERROR_INVALID_NAME: return UV_ENOENT; + case ERROR_INVALID_DRIVE: return UV_ENOENT; + case ERROR_INVALID_REPARSE_DATA: return UV_ENOENT; + case ERROR_MOD_NOT_FOUND: return UV_ENOENT; + case ERROR_PATH_NOT_FOUND: return UV_ENOENT; + case WSAHOST_NOT_FOUND: return UV_ENOENT; + case WSANO_DATA: return UV_ENOENT; + case ERROR_NOT_ENOUGH_MEMORY: return UV_ENOMEM; + case ERROR_OUTOFMEMORY: return UV_ENOMEM; + case ERROR_CANNOT_MAKE: return UV_ENOSPC; + case ERROR_DISK_FULL: return UV_ENOSPC; + case ERROR_EA_TABLE_FULL: return UV_ENOSPC; + case ERROR_END_OF_MEDIA: return UV_ENOSPC; + case ERROR_HANDLE_DISK_FULL: return UV_ENOSPC; + case ERROR_NOT_CONNECTED: return UV_ENOTCONN; + case WSAENOTCONN: return UV_ENOTCONN; + case ERROR_DIR_NOT_EMPTY: return UV_ENOTEMPTY; + case WSAENOTSOCK: return UV_ENOTSOCK; + case ERROR_NOT_SUPPORTED: return UV_ENOTSUP; + case ERROR_BROKEN_PIPE: return UV_EOF; + case ERROR_ACCESS_DENIED: return UV_EPERM; + case ERROR_PRIVILEGE_NOT_HELD: return UV_EPERM; + case ERROR_BAD_PIPE: return UV_EPIPE; + case ERROR_NO_DATA: return UV_EPIPE; + case ERROR_PIPE_NOT_CONNECTED: return UV_EPIPE; + case WSAESHUTDOWN: return UV_EPIPE; + case WSAEPROTONOSUPPORT: return UV_EPROTONOSUPPORT; + case ERROR_WRITE_PROTECT: return UV_EROFS; + case ERROR_SEM_TIMEOUT: return UV_ETIMEDOUT; + case WSAETIMEDOUT: return UV_ETIMEDOUT; + case ERROR_NOT_SAME_DEVICE: return UV_EXDEV; + case ERROR_INVALID_FUNCTION: return UV_EISDIR; + case ERROR_META_EXPANSION_TOO_LONG: return UV_E2BIG; + case WSAESOCKTNOSUPPORT: return UV_ESOCKTNOSUPPORT; + default: return UV_UNKNOWN; + } +} diff --git a/external/src/libuv/src/win/fs-event.c b/external/src/libuv/src/win/fs-event.c new file mode 100644 index 0000000..0126c5e --- /dev/null +++ b/external/src/libuv/src/win/fs-event.c @@ -0,0 +1,608 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#include "uv.h" +#include "internal.h" +#include "handle-inl.h" +#include "req-inl.h" + + +const unsigned int uv_directory_watcher_buffer_size = 4096; + + +static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop, + uv_fs_event_t* handle) { + assert(handle->dir_handle != INVALID_HANDLE_VALUE); + assert(!handle->req_pending); + + memset(&(handle->req.u.io.overlapped), 0, + sizeof(handle->req.u.io.overlapped)); + if (!ReadDirectoryChangesW(handle->dir_handle, + handle->buffer, + uv_directory_watcher_buffer_size, + (handle->flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE, + FILE_NOTIFY_CHANGE_FILE_NAME | + FILE_NOTIFY_CHANGE_DIR_NAME | + FILE_NOTIFY_CHANGE_ATTRIBUTES | + FILE_NOTIFY_CHANGE_SIZE | + FILE_NOTIFY_CHANGE_LAST_WRITE | + FILE_NOTIFY_CHANGE_LAST_ACCESS | + FILE_NOTIFY_CHANGE_CREATION | + FILE_NOTIFY_CHANGE_SECURITY, + NULL, + &handle->req.u.io.overlapped, + NULL)) { + /* Make this req pending reporting an error. */ + SET_REQ_ERROR(&handle->req, GetLastError()); + uv_insert_pending_req(loop, (uv_req_t*)&handle->req); + } + + handle->req_pending = 1; +} + +static void uv_relative_path(const WCHAR* filename, + const WCHAR* dir, + WCHAR** relpath) { + size_t relpathlen; + size_t filenamelen = wcslen(filename); + size_t dirlen = wcslen(dir); + assert(!_wcsnicmp(filename, dir, dirlen)); + if (dirlen > 0 && dir[dirlen - 1] == '\\') + dirlen--; + relpathlen = filenamelen - dirlen - 1; + *relpath = uv__malloc((relpathlen + 1) * sizeof(WCHAR)); + if (!*relpath) + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + wcsncpy(*relpath, filename + dirlen + 1, relpathlen); + (*relpath)[relpathlen] = L'\0'; +} + +static int uv_split_path(const WCHAR* filename, WCHAR** dir, + WCHAR** file) { + size_t len, i; + DWORD dir_len; + + if (filename == NULL) { + if (dir != NULL) + *dir = NULL; + *file = NULL; + return 0; + } + + len = wcslen(filename); + i = len; + while (i > 0 && filename[--i] != '\\' && filename[i] != '/'); + + if (i == 0) { + if (dir) { + dir_len = GetCurrentDirectoryW(0, NULL); + if (dir_len == 0) { + return -1; + } + *dir = (WCHAR*)uv__malloc(dir_len * sizeof(WCHAR)); + if (!*dir) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + if (!GetCurrentDirectoryW(dir_len, *dir)) { + uv__free(*dir); + *dir = NULL; + return -1; + } + } + + *file = wcsdup(filename); + } else { + if (dir) { + *dir = (WCHAR*)uv__malloc((i + 2) * sizeof(WCHAR)); + if (!*dir) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + wcsncpy(*dir, filename, i + 1); + (*dir)[i + 1] = L'\0'; + } + + *file = (WCHAR*)uv__malloc((len - i) * sizeof(WCHAR)); + if (!*file) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + wcsncpy(*file, filename + i + 1, len - i - 1); + (*file)[len - i - 1] = L'\0'; + } + + return 0; +} + + +int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { + uv__handle_init(loop, (uv_handle_t*) handle, UV_FS_EVENT); + handle->dir_handle = INVALID_HANDLE_VALUE; + handle->buffer = NULL; + handle->req_pending = 0; + handle->filew = NULL; + handle->short_filew = NULL; + handle->dirw = NULL; + + UV_REQ_INIT(&handle->req, UV_FS_EVENT_REQ); + handle->req.data = handle; + + return 0; +} + + +int uv_fs_event_start(uv_fs_event_t* handle, + uv_fs_event_cb cb, + const char* path, + unsigned int flags) { + int name_size, is_path_dir, size; + DWORD attr, last_error; + WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL; + DWORD short_path_buffer_len; + WCHAR *short_path_buffer; + WCHAR* short_path, *long_path; + + short_path = NULL; + if (uv__is_active(handle)) + return UV_EINVAL; + + handle->cb = cb; + handle->path = uv__strdup(path); + if (!handle->path) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + uv__handle_start(handle); + + /* Convert name to UTF16. */ + + name_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0) * + sizeof(WCHAR); + pathw = (WCHAR*)uv__malloc(name_size); + if (!pathw) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + if (!MultiByteToWideChar(CP_UTF8, + 0, + path, + -1, + pathw, + name_size / sizeof(WCHAR))) { + return uv_translate_sys_error(GetLastError()); + } + + /* Determine whether path is a file or a directory. */ + attr = GetFileAttributesW(pathw); + if (attr == INVALID_FILE_ATTRIBUTES) { + last_error = GetLastError(); + goto error; + } + + is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0; + + if (is_path_dir) { + /* path is a directory, so that's the directory that we will watch. */ + + /* Convert to long path. */ + size = GetLongPathNameW(pathw, NULL, 0); + + if (size) { + long_path = (WCHAR*)uv__malloc(size * sizeof(WCHAR)); + if (!long_path) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + size = GetLongPathNameW(pathw, long_path, size); + if (size) { + long_path[size] = '\0'; + } else { + uv__free(long_path); + long_path = NULL; + } + + if (long_path) { + uv__free(pathw); + pathw = long_path; + } + } + + dir_to_watch = pathw; + } else { + /* + * path is a file. So we split path into dir & file parts, and + * watch the dir directory. + */ + + /* Convert to short path. */ + short_path_buffer = NULL; + short_path_buffer_len = GetShortPathNameW(pathw, NULL, 0); + if (short_path_buffer_len == 0) { + goto short_path_done; + } + short_path_buffer = uv__malloc(short_path_buffer_len * sizeof(WCHAR)); + if (short_path_buffer == NULL) { + goto short_path_done; + } + if (GetShortPathNameW(pathw, + short_path_buffer, + short_path_buffer_len) == 0) { + uv__free(short_path_buffer); + short_path_buffer = NULL; + } +short_path_done: + short_path = short_path_buffer; + + if (uv_split_path(pathw, &dir, &handle->filew) != 0) { + last_error = GetLastError(); + goto error; + } + + if (uv_split_path(short_path, NULL, &handle->short_filew) != 0) { + last_error = GetLastError(); + goto error; + } + + dir_to_watch = dir; + uv__free(pathw); + pathw = NULL; + } + + handle->dir_handle = CreateFileW(dir_to_watch, + FILE_LIST_DIRECTORY, + FILE_SHARE_READ | FILE_SHARE_DELETE | + FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | + FILE_FLAG_OVERLAPPED, + NULL); + + if (dir) { + uv__free(dir); + dir = NULL; + } + + if (handle->dir_handle == INVALID_HANDLE_VALUE) { + last_error = GetLastError(); + goto error; + } + + if (CreateIoCompletionPort(handle->dir_handle, + handle->loop->iocp, + (ULONG_PTR)handle, + 0) == NULL) { + last_error = GetLastError(); + goto error; + } + + if (!handle->buffer) { + handle->buffer = (char*)uv__malloc(uv_directory_watcher_buffer_size); + } + if (!handle->buffer) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + memset(&(handle->req.u.io.overlapped), 0, + sizeof(handle->req.u.io.overlapped)); + + if (!ReadDirectoryChangesW(handle->dir_handle, + handle->buffer, + uv_directory_watcher_buffer_size, + (flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE, + FILE_NOTIFY_CHANGE_FILE_NAME | + FILE_NOTIFY_CHANGE_DIR_NAME | + FILE_NOTIFY_CHANGE_ATTRIBUTES | + FILE_NOTIFY_CHANGE_SIZE | + FILE_NOTIFY_CHANGE_LAST_WRITE | + FILE_NOTIFY_CHANGE_LAST_ACCESS | + FILE_NOTIFY_CHANGE_CREATION | + FILE_NOTIFY_CHANGE_SECURITY, + NULL, + &handle->req.u.io.overlapped, + NULL)) { + last_error = GetLastError(); + goto error; + } + + assert(is_path_dir ? pathw != NULL : pathw == NULL); + handle->dirw = pathw; + handle->req_pending = 1; + return 0; + +error: + if (handle->path) { + uv__free(handle->path); + handle->path = NULL; + } + + if (handle->filew) { + uv__free(handle->filew); + handle->filew = NULL; + } + + if (handle->short_filew) { + uv__free(handle->short_filew); + handle->short_filew = NULL; + } + + uv__free(pathw); + + if (handle->dir_handle != INVALID_HANDLE_VALUE) { + CloseHandle(handle->dir_handle); + handle->dir_handle = INVALID_HANDLE_VALUE; + } + + if (handle->buffer) { + uv__free(handle->buffer); + handle->buffer = NULL; + } + + if (uv__is_active(handle)) + uv__handle_stop(handle); + + uv__free(short_path); + + return uv_translate_sys_error(last_error); +} + + +int uv_fs_event_stop(uv_fs_event_t* handle) { + if (!uv__is_active(handle)) + return 0; + + if (handle->dir_handle != INVALID_HANDLE_VALUE) { + CloseHandle(handle->dir_handle); + handle->dir_handle = INVALID_HANDLE_VALUE; + } + + uv__handle_stop(handle); + + if (handle->filew) { + uv__free(handle->filew); + handle->filew = NULL; + } + + if (handle->short_filew) { + uv__free(handle->short_filew); + handle->short_filew = NULL; + } + + if (handle->path) { + uv__free(handle->path); + handle->path = NULL; + } + + if (handle->dirw) { + uv__free(handle->dirw); + handle->dirw = NULL; + } + + return 0; +} + + +static int file_info_cmp(WCHAR* str, WCHAR* file_name, size_t file_name_len) { + size_t str_len; + + if (str == NULL) + return -1; + + str_len = wcslen(str); + + /* + Since we only care about equality, return early if the strings + aren't the same length + */ + if (str_len != (file_name_len / sizeof(WCHAR))) + return -1; + + return _wcsnicmp(str, file_name, str_len); +} + + +void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req, + uv_fs_event_t* handle) { + FILE_NOTIFY_INFORMATION* file_info; + int err, sizew, size; + char* filename = NULL; + WCHAR* filenamew = NULL; + WCHAR* long_filenamew = NULL; + DWORD offset = 0; + + assert(req->type == UV_FS_EVENT_REQ); + assert(handle->req_pending); + handle->req_pending = 0; + + /* Don't report any callbacks if: + * - We're closing, just push the handle onto the endgame queue + * - We are not active, just ignore the callback + */ + if (!uv__is_active(handle)) { + if (handle->flags & UV_HANDLE_CLOSING) { + uv_want_endgame(loop, (uv_handle_t*) handle); + } + return; + } + + file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset); + + if (REQ_SUCCESS(req)) { + if (req->u.io.overlapped.InternalHigh > 0) { + do { + file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset); + assert(!filename); + assert(!filenamew); + assert(!long_filenamew); + + /* + * Fire the event only if we were asked to watch a directory, + * or if the filename filter matches. + */ + if (handle->dirw || + file_info_cmp(handle->filew, + file_info->FileName, + file_info->FileNameLength) == 0 || + file_info_cmp(handle->short_filew, + file_info->FileName, + file_info->FileNameLength) == 0) { + + if (handle->dirw) { + /* + * We attempt to resolve the long form of the file name explicitly. + * We only do this for file names that might still exist on disk. + * If this fails, we use the name given by ReadDirectoryChangesW. + * This may be the long form or the 8.3 short name in some cases. + */ + if (file_info->Action != FILE_ACTION_REMOVED && + file_info->Action != FILE_ACTION_RENAMED_OLD_NAME) { + /* Construct a full path to the file. */ + size = wcslen(handle->dirw) + + file_info->FileNameLength / sizeof(WCHAR) + 2; + + filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR)); + if (!filenamew) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + _snwprintf(filenamew, size, L"%s\\%.*s", handle->dirw, + file_info->FileNameLength / (DWORD)sizeof(WCHAR), + file_info->FileName); + + filenamew[size - 1] = L'\0'; + + /* Convert to long name. */ + size = GetLongPathNameW(filenamew, NULL, 0); + + if (size) { + long_filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR)); + if (!long_filenamew) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + size = GetLongPathNameW(filenamew, long_filenamew, size); + if (size) { + long_filenamew[size] = '\0'; + } else { + uv__free(long_filenamew); + long_filenamew = NULL; + } + } + + uv__free(filenamew); + + if (long_filenamew) { + /* Get the file name out of the long path. */ + uv_relative_path(long_filenamew, + handle->dirw, + &filenamew); + uv__free(long_filenamew); + long_filenamew = filenamew; + sizew = -1; + } else { + /* We couldn't get the long filename, use the one reported. */ + filenamew = file_info->FileName; + sizew = file_info->FileNameLength / sizeof(WCHAR); + } + } else { + /* + * Removed or renamed events cannot be resolved to the long form. + * We therefore use the name given by ReadDirectoryChangesW. + * This may be the long form or the 8.3 short name in some cases. + */ + filenamew = file_info->FileName; + sizew = file_info->FileNameLength / sizeof(WCHAR); + } + } else { + /* We already have the long name of the file, so just use it. */ + filenamew = handle->filew; + sizew = -1; + } + + /* Convert the filename to utf8. */ + uv__convert_utf16_to_utf8(filenamew, sizew, &filename); + + switch (file_info->Action) { + case FILE_ACTION_ADDED: + case FILE_ACTION_REMOVED: + case FILE_ACTION_RENAMED_OLD_NAME: + case FILE_ACTION_RENAMED_NEW_NAME: + handle->cb(handle, filename, UV_RENAME, 0); + break; + + case FILE_ACTION_MODIFIED: + handle->cb(handle, filename, UV_CHANGE, 0); + break; + } + + uv__free(filename); + filename = NULL; + uv__free(long_filenamew); + long_filenamew = NULL; + filenamew = NULL; + } + + offset = file_info->NextEntryOffset; + } while (offset && !(handle->flags & UV_HANDLE_CLOSING)); + } else { + handle->cb(handle, NULL, UV_CHANGE, 0); + } + } else { + err = GET_REQ_ERROR(req); + handle->cb(handle, NULL, 0, uv_translate_sys_error(err)); + } + + if (!(handle->flags & UV_HANDLE_CLOSING)) { + uv_fs_event_queue_readdirchanges(loop, handle); + } else { + uv_want_endgame(loop, (uv_handle_t*)handle); + } +} + + +void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle) { + uv_fs_event_stop(handle); + + uv__handle_closing(handle); + + if (!handle->req_pending) { + uv_want_endgame(loop, (uv_handle_t*)handle); + } + +} + + +void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle) { + if ((handle->flags & UV_HANDLE_CLOSING) && !handle->req_pending) { + assert(!(handle->flags & UV_HANDLE_CLOSED)); + + if (handle->buffer) { + uv__free(handle->buffer); + handle->buffer = NULL; + } + + uv__handle_close(handle); + } +} diff --git a/external/src/libuv/src/win/fs-fd-hash-inl.h b/external/src/libuv/src/win/fs-fd-hash-inl.h new file mode 100644 index 0000000..0b532af --- /dev/null +++ b/external/src/libuv/src/win/fs-fd-hash-inl.h @@ -0,0 +1,200 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_WIN_FS_FD_HASH_INL_H_ +#define UV_WIN_FS_FD_HASH_INL_H_ + +#include "uv.h" +#include "internal.h" + +/* Files are only inserted in uv__fd_hash when the UV_FS_O_FILEMAP flag is + * specified. Thus, when uv__fd_hash_get returns true, the file mapping in the + * info structure should be used for read/write operations. + * + * If the file is empty, the mapping field will be set to + * INVALID_HANDLE_VALUE. This is not an issue since the file mapping needs to + * be created anyway when the file size changes. + * + * Since file descriptors are sequential integers, the modulo operator is used + * as hashing function. For each bucket, a single linked list of arrays is + * kept to minimize allocations. A statically allocated memory buffer is kept + * for the first array in each bucket. */ + + +#define UV__FD_HASH_SIZE 256 +#define UV__FD_HASH_GROUP_SIZE 16 + +struct uv__fd_info_s { + int flags; + BOOLEAN is_directory; + HANDLE mapping; + LARGE_INTEGER size; + LARGE_INTEGER current_pos; +}; + +struct uv__fd_hash_entry_s { + uv_file fd; + struct uv__fd_info_s info; +}; + +struct uv__fd_hash_entry_group_s { + struct uv__fd_hash_entry_s entries[UV__FD_HASH_GROUP_SIZE]; + struct uv__fd_hash_entry_group_s* next; +}; + +struct uv__fd_hash_bucket_s { + size_t size; + struct uv__fd_hash_entry_group_s* data; +}; + + +static uv_mutex_t uv__fd_hash_mutex; + +static struct uv__fd_hash_entry_group_s + uv__fd_hash_entry_initial[UV__FD_HASH_SIZE * UV__FD_HASH_GROUP_SIZE]; +static struct uv__fd_hash_bucket_s uv__fd_hash[UV__FD_HASH_SIZE]; + + +INLINE static void uv__fd_hash_init(void) { + size_t i; + int err; + + err = uv_mutex_init(&uv__fd_hash_mutex); + if (err) { + uv_fatal_error(err, "uv_mutex_init"); + } + + for (i = 0; i < ARRAY_SIZE(uv__fd_hash); ++i) { + uv__fd_hash[i].size = 0; + uv__fd_hash[i].data = + uv__fd_hash_entry_initial + i * UV__FD_HASH_GROUP_SIZE; + } +} + +#define FIND_COMMON_VARIABLES \ + unsigned i; \ + unsigned bucket = fd % ARRAY_SIZE(uv__fd_hash); \ + struct uv__fd_hash_entry_s* entry_ptr = NULL; \ + struct uv__fd_hash_entry_group_s* group_ptr; \ + struct uv__fd_hash_bucket_s* bucket_ptr = &uv__fd_hash[bucket]; + +#define FIND_IN_GROUP_PTR(group_size) \ + do { \ + for (i = 0; i < group_size; ++i) { \ + if (group_ptr->entries[i].fd == fd) { \ + entry_ptr = &group_ptr->entries[i]; \ + break; \ + } \ + } \ + } while (0) + +#define FIND_IN_BUCKET_PTR() \ + do { \ + size_t first_group_size = bucket_ptr->size % UV__FD_HASH_GROUP_SIZE; \ + if (bucket_ptr->size != 0 && first_group_size == 0) \ + first_group_size = UV__FD_HASH_GROUP_SIZE; \ + group_ptr = bucket_ptr->data; \ + FIND_IN_GROUP_PTR(first_group_size); \ + for (group_ptr = group_ptr->next; \ + group_ptr != NULL && entry_ptr == NULL; \ + group_ptr = group_ptr->next) \ + FIND_IN_GROUP_PTR(UV__FD_HASH_GROUP_SIZE); \ + } while (0) + +INLINE static int uv__fd_hash_get(int fd, struct uv__fd_info_s* info) { + FIND_COMMON_VARIABLES + + uv_mutex_lock(&uv__fd_hash_mutex); + + FIND_IN_BUCKET_PTR(); + + if (entry_ptr != NULL) { + *info = entry_ptr->info; + } + + uv_mutex_unlock(&uv__fd_hash_mutex); + return entry_ptr != NULL; +} + +INLINE static void uv__fd_hash_add(int fd, struct uv__fd_info_s* info) { + FIND_COMMON_VARIABLES + + uv_mutex_lock(&uv__fd_hash_mutex); + + FIND_IN_BUCKET_PTR(); + + if (entry_ptr == NULL) { + i = bucket_ptr->size % UV__FD_HASH_GROUP_SIZE; + + if (bucket_ptr->size != 0 && i == 0) { + struct uv__fd_hash_entry_group_s* new_group_ptr = + uv__malloc(sizeof(*new_group_ptr)); + if (new_group_ptr == NULL) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + new_group_ptr->next = bucket_ptr->data; + bucket_ptr->data = new_group_ptr; + } + + bucket_ptr->size += 1; + entry_ptr = &bucket_ptr->data->entries[i]; + entry_ptr->fd = fd; + } + + entry_ptr->info = *info; + + uv_mutex_unlock(&uv__fd_hash_mutex); +} + +INLINE static int uv__fd_hash_remove(int fd, struct uv__fd_info_s* info) { + FIND_COMMON_VARIABLES + + uv_mutex_lock(&uv__fd_hash_mutex); + + FIND_IN_BUCKET_PTR(); + + if (entry_ptr != NULL) { + *info = entry_ptr->info; + + bucket_ptr->size -= 1; + + i = bucket_ptr->size % UV__FD_HASH_GROUP_SIZE; + if (entry_ptr != &bucket_ptr->data->entries[i]) { + *entry_ptr = bucket_ptr->data->entries[i]; + } + + if (bucket_ptr->size != 0 && + bucket_ptr->size % UV__FD_HASH_GROUP_SIZE == 0) { + struct uv__fd_hash_entry_group_s* old_group_ptr = bucket_ptr->data; + bucket_ptr->data = old_group_ptr->next; + uv__free(old_group_ptr); + } + } + + uv_mutex_unlock(&uv__fd_hash_mutex); + return entry_ptr != NULL; +} + +#undef FIND_COMMON_VARIABLES +#undef FIND_IN_GROUP_PTR +#undef FIND_IN_BUCKET_PTR + +#endif /* UV_WIN_FS_FD_HASH_INL_H_ */ diff --git a/external/src/libuv/src/win/fs.c b/external/src/libuv/src/win/fs.c new file mode 100644 index 0000000..6740704 --- /dev/null +++ b/external/src/libuv/src/win/fs.c @@ -0,0 +1,3427 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "uv.h" +#include "internal.h" +#include "req-inl.h" +#include "handle-inl.h" +#include "fs-fd-hash-inl.h" + + +#define UV_FS_FREE_PATHS 0x0002 +#define UV_FS_FREE_PTR 0x0008 +#define UV_FS_CLEANEDUP 0x0010 + + +#define INIT(subtype) \ + do { \ + if (req == NULL) \ + return UV_EINVAL; \ + uv_fs_req_init(loop, req, subtype, cb); \ + } \ + while (0) + +#define POST \ + do { \ + if (cb != NULL) { \ + uv__req_register(loop, req); \ + uv__work_submit(loop, \ + &req->work_req, \ + UV__WORK_FAST_IO, \ + uv__fs_work, \ + uv__fs_done); \ + return 0; \ + } else { \ + uv__fs_work(&req->work_req); \ + return req->result; \ + } \ + } \ + while (0) + +#define SET_REQ_RESULT(req, result_value) \ + do { \ + req->result = (result_value); \ + assert(req->result != -1); \ + } while (0) + +#define SET_REQ_WIN32_ERROR(req, sys_errno) \ + do { \ + req->sys_errno_ = (sys_errno); \ + req->result = uv_translate_sys_error(req->sys_errno_); \ + } while (0) + +#define SET_REQ_UV_ERROR(req, uv_errno, sys_errno) \ + do { \ + req->result = (uv_errno); \ + req->sys_errno_ = (sys_errno); \ + } while (0) + +#define VERIFY_FD(fd, req) \ + if (fd == -1) { \ + req->result = UV_EBADF; \ + req->sys_errno_ = ERROR_INVALID_HANDLE; \ + return; \ + } + +#define MILLION ((int64_t) 1000 * 1000) +#define BILLION ((int64_t) 1000 * 1000 * 1000) + +static void uv__filetime_to_timespec(uv_timespec_t *ts, int64_t filetime) { + filetime -= 116444736 * BILLION; + ts->tv_sec = (long) (filetime / (10 * MILLION)); + ts->tv_nsec = (long) ((filetime - ts->tv_sec * 10 * MILLION) * 100U); + if (ts->tv_nsec < 0) { + ts->tv_sec -= 1; + ts->tv_nsec += 1e9; + } +} + +#define TIME_T_TO_FILETIME(time, filetime_ptr) \ + do { \ + int64_t bigtime = ((time) * 10 * MILLION + 116444736 * BILLION); \ + (filetime_ptr)->dwLowDateTime = (uint64_t) bigtime & 0xFFFFFFFF; \ + (filetime_ptr)->dwHighDateTime = (uint64_t) bigtime >> 32; \ + } while(0) + +#define IS_SLASH(c) ((c) == L'\\' || (c) == L'/') +#define IS_LETTER(c) (((c) >= L'a' && (c) <= L'z') || \ + ((c) >= L'A' && (c) <= L'Z')) + +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) + +const WCHAR JUNCTION_PREFIX[] = L"\\??\\"; +const WCHAR JUNCTION_PREFIX_LEN = 4; + +const WCHAR LONG_PATH_PREFIX[] = L"\\\\?\\"; +const WCHAR LONG_PATH_PREFIX_LEN = 4; + +const WCHAR UNC_PATH_PREFIX[] = L"\\\\?\\UNC\\"; +const WCHAR UNC_PATH_PREFIX_LEN = 8; + +static int uv__file_symlink_usermode_flag = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE; + +static DWORD uv__allocation_granularity; + + +void uv_fs_init(void) { + SYSTEM_INFO system_info; + + GetSystemInfo(&system_info); + uv__allocation_granularity = system_info.dwAllocationGranularity; + + uv__fd_hash_init(); +} + + +INLINE static int fs__capture_path(uv_fs_t* req, const char* path, + const char* new_path, const int copy_path) { + char* buf; + char* pos; + ssize_t buf_sz = 0, path_len = 0, pathw_len = 0, new_pathw_len = 0; + + /* new_path can only be set if path is also set. */ + assert(new_path == NULL || path != NULL); + + if (path != NULL) { + pathw_len = MultiByteToWideChar(CP_UTF8, + 0, + path, + -1, + NULL, + 0); + if (pathw_len == 0) { + return GetLastError(); + } + + buf_sz += pathw_len * sizeof(WCHAR); + } + + if (path != NULL && copy_path) { + path_len = 1 + strlen(path); + buf_sz += path_len; + } + + if (new_path != NULL) { + new_pathw_len = MultiByteToWideChar(CP_UTF8, + 0, + new_path, + -1, + NULL, + 0); + if (new_pathw_len == 0) { + return GetLastError(); + } + + buf_sz += new_pathw_len * sizeof(WCHAR); + } + + + if (buf_sz == 0) { + req->file.pathw = NULL; + req->fs.info.new_pathw = NULL; + req->path = NULL; + return 0; + } + + buf = (char*) uv__malloc(buf_sz); + if (buf == NULL) { + return ERROR_OUTOFMEMORY; + } + + pos = buf; + + if (path != NULL) { + DWORD r = MultiByteToWideChar(CP_UTF8, + 0, + path, + -1, + (WCHAR*) pos, + pathw_len); + assert(r == (DWORD) pathw_len); + req->file.pathw = (WCHAR*) pos; + pos += r * sizeof(WCHAR); + } else { + req->file.pathw = NULL; + } + + if (new_path != NULL) { + DWORD r = MultiByteToWideChar(CP_UTF8, + 0, + new_path, + -1, + (WCHAR*) pos, + new_pathw_len); + assert(r == (DWORD) new_pathw_len); + req->fs.info.new_pathw = (WCHAR*) pos; + pos += r * sizeof(WCHAR); + } else { + req->fs.info.new_pathw = NULL; + } + + req->path = path; + if (path != NULL && copy_path) { + memcpy(pos, path, path_len); + assert(path_len == buf_sz - (pos - buf)); + req->path = pos; + } + + req->flags |= UV_FS_FREE_PATHS; + + return 0; +} + + + +INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, + uv_fs_type fs_type, const uv_fs_cb cb) { + uv__once_init(); + UV_REQ_INIT(req, UV_FS); + req->loop = loop; + req->flags = 0; + req->fs_type = fs_type; + req->sys_errno_ = 0; + req->result = 0; + req->ptr = NULL; + req->path = NULL; + req->cb = cb; + memset(&req->fs, 0, sizeof(req->fs)); +} + + +static int fs__wide_to_utf8(WCHAR* w_source_ptr, + DWORD w_source_len, + char** target_ptr, + uint64_t* target_len_ptr) { + int r; + int target_len; + char* target; + target_len = WideCharToMultiByte(CP_UTF8, + 0, + w_source_ptr, + w_source_len, + NULL, + 0, + NULL, + NULL); + + if (target_len == 0) { + return -1; + } + + if (target_len_ptr != NULL) { + *target_len_ptr = target_len; + } + + if (target_ptr == NULL) { + return 0; + } + + target = uv__malloc(target_len + 1); + if (target == NULL) { + SetLastError(ERROR_OUTOFMEMORY); + return -1; + } + + r = WideCharToMultiByte(CP_UTF8, + 0, + w_source_ptr, + w_source_len, + target, + target_len, + NULL, + NULL); + assert(r == target_len); + target[target_len] = '\0'; + *target_ptr = target; + return 0; +} + + +INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr, + uint64_t* target_len_ptr) { + char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + REPARSE_DATA_BUFFER* reparse_data = (REPARSE_DATA_BUFFER*) buffer; + WCHAR* w_target; + DWORD w_target_len; + DWORD bytes; + size_t i; + size_t len; + + if (!DeviceIoControl(handle, + FSCTL_GET_REPARSE_POINT, + NULL, + 0, + buffer, + sizeof buffer, + &bytes, + NULL)) { + return -1; + } + + if (reparse_data->ReparseTag == IO_REPARSE_TAG_SYMLINK) { + /* Real symlink */ + w_target = reparse_data->SymbolicLinkReparseBuffer.PathBuffer + + (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset / + sizeof(WCHAR)); + w_target_len = + reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength / + sizeof(WCHAR); + + /* Real symlinks can contain pretty much everything, but the only thing we + * really care about is undoing the implicit conversion to an NT namespaced + * path that CreateSymbolicLink will perform on absolute paths. If the path + * is win32-namespaced then the user must have explicitly made it so, and + * we better just return the unmodified reparse data. */ + if (w_target_len >= 4 && + w_target[0] == L'\\' && + w_target[1] == L'?' && + w_target[2] == L'?' && + w_target[3] == L'\\') { + /* Starts with \??\ */ + if (w_target_len >= 6 && + ((w_target[4] >= L'A' && w_target[4] <= L'Z') || + (w_target[4] >= L'a' && w_target[4] <= L'z')) && + w_target[5] == L':' && + (w_target_len == 6 || w_target[6] == L'\\')) { + /* \??\:\ */ + w_target += 4; + w_target_len -= 4; + + } else if (w_target_len >= 8 && + (w_target[4] == L'U' || w_target[4] == L'u') && + (w_target[5] == L'N' || w_target[5] == L'n') && + (w_target[6] == L'C' || w_target[6] == L'c') && + w_target[7] == L'\\') { + /* \??\UNC\\\ - make sure the final path looks like + * \\\\ */ + w_target += 6; + w_target[0] = L'\\'; + w_target_len -= 6; + } + } + + } else if (reparse_data->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { + /* Junction. */ + w_target = reparse_data->MountPointReparseBuffer.PathBuffer + + (reparse_data->MountPointReparseBuffer.SubstituteNameOffset / + sizeof(WCHAR)); + w_target_len = reparse_data->MountPointReparseBuffer.SubstituteNameLength / + sizeof(WCHAR); + + /* Only treat junctions that look like \??\:\ as symlink. Junctions + * can also be used as mount points, like \??\Volume{}, but that's + * confusing for programs since they wouldn't be able to actually + * understand such a path when returned by uv_readlink(). UNC paths are + * never valid for junctions so we don't care about them. */ + if (!(w_target_len >= 6 && + w_target[0] == L'\\' && + w_target[1] == L'?' && + w_target[2] == L'?' && + w_target[3] == L'\\' && + ((w_target[4] >= L'A' && w_target[4] <= L'Z') || + (w_target[4] >= L'a' && w_target[4] <= L'z')) && + w_target[5] == L':' && + (w_target_len == 6 || w_target[6] == L'\\'))) { + SetLastError(ERROR_SYMLINK_NOT_SUPPORTED); + return -1; + } + + /* Remove leading \??\ */ + w_target += 4; + w_target_len -= 4; + + } else if (reparse_data->ReparseTag == IO_REPARSE_TAG_APPEXECLINK) { + /* String #3 in the list has the target filename. */ + if (reparse_data->AppExecLinkReparseBuffer.StringCount < 3) { + SetLastError(ERROR_SYMLINK_NOT_SUPPORTED); + return -1; + } + w_target = reparse_data->AppExecLinkReparseBuffer.StringList; + /* The StringList buffer contains a list of strings separated by "\0", */ + /* with "\0\0" terminating the list. Move to the 3rd string in the list: */ + for (i = 0; i < 2; ++i) { + len = wcslen(w_target); + if (len == 0) { + SetLastError(ERROR_SYMLINK_NOT_SUPPORTED); + return -1; + } + w_target += len + 1; + } + w_target_len = wcslen(w_target); + if (w_target_len == 0) { + SetLastError(ERROR_SYMLINK_NOT_SUPPORTED); + return -1; + } + /* Make sure it is an absolute path. */ + if (!(w_target_len >= 3 && + ((w_target[0] >= L'a' && w_target[0] <= L'z') || + (w_target[0] >= L'A' && w_target[0] <= L'Z')) && + w_target[1] == L':' && + w_target[2] == L'\\')) { + SetLastError(ERROR_SYMLINK_NOT_SUPPORTED); + return -1; + } + + } else { + /* Reparse tag does not indicate a symlink. */ + SetLastError(ERROR_SYMLINK_NOT_SUPPORTED); + return -1; + } + + return fs__wide_to_utf8(w_target, w_target_len, target_ptr, target_len_ptr); +} + + +void fs__open(uv_fs_t* req) { + DWORD access; + DWORD share; + DWORD disposition; + DWORD attributes = 0; + HANDLE file; + int fd, current_umask; + int flags = req->fs.info.file_flags; + struct uv__fd_info_s fd_info; + + /* Adjust flags to be compatible with the memory file mapping. Save the + * original flags to emulate the correct behavior. */ + if (flags & UV_FS_O_FILEMAP) { + fd_info.flags = flags; + fd_info.current_pos.QuadPart = 0; + + if ((flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR)) == + UV_FS_O_WRONLY) { + /* CreateFileMapping always needs read access */ + flags = (flags & ~UV_FS_O_WRONLY) | UV_FS_O_RDWR; + } + + if (flags & UV_FS_O_APPEND) { + /* Clear the append flag and ensure RDRW mode */ + flags &= ~UV_FS_O_APPEND; + flags &= ~(UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR); + flags |= UV_FS_O_RDWR; + } + } + + /* Obtain the active umask. umask() never fails and returns the previous + * umask. */ + current_umask = umask(0); + umask(current_umask); + + /* convert flags and mode to CreateFile parameters */ + switch (flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR)) { + case UV_FS_O_RDONLY: + access = FILE_GENERIC_READ; + break; + case UV_FS_O_WRONLY: + access = FILE_GENERIC_WRITE; + break; + case UV_FS_O_RDWR: + access = FILE_GENERIC_READ | FILE_GENERIC_WRITE; + break; + default: + goto einval; + } + + if (flags & UV_FS_O_APPEND) { + access &= ~FILE_WRITE_DATA; + access |= FILE_APPEND_DATA; + } + + /* + * Here is where we deviate significantly from what CRT's _open() + * does. We indiscriminately use all the sharing modes, to match + * UNIX semantics. In particular, this ensures that the file can + * be deleted even whilst it's open, fixing issue + * https://github.com/nodejs/node-v0.x-archive/issues/1449. + * We still support exclusive sharing mode, since it is necessary + * for opening raw block devices, otherwise Windows will prevent + * any attempt to write past the master boot record. + */ + if (flags & UV_FS_O_EXLOCK) { + share = 0; + } else { + share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; + } + + switch (flags & (UV_FS_O_CREAT | UV_FS_O_EXCL | UV_FS_O_TRUNC)) { + case 0: + case UV_FS_O_EXCL: + disposition = OPEN_EXISTING; + break; + case UV_FS_O_CREAT: + disposition = OPEN_ALWAYS; + break; + case UV_FS_O_CREAT | UV_FS_O_EXCL: + case UV_FS_O_CREAT | UV_FS_O_TRUNC | UV_FS_O_EXCL: + disposition = CREATE_NEW; + break; + case UV_FS_O_TRUNC: + case UV_FS_O_TRUNC | UV_FS_O_EXCL: + disposition = TRUNCATE_EXISTING; + break; + case UV_FS_O_CREAT | UV_FS_O_TRUNC: + disposition = CREATE_ALWAYS; + break; + default: + goto einval; + } + + attributes |= FILE_ATTRIBUTE_NORMAL; + if (flags & UV_FS_O_CREAT) { + if (!((req->fs.info.mode & ~current_umask) & _S_IWRITE)) { + attributes |= FILE_ATTRIBUTE_READONLY; + } + } + + if (flags & UV_FS_O_TEMPORARY ) { + attributes |= FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY; + access |= DELETE; + } + + if (flags & UV_FS_O_SHORT_LIVED) { + attributes |= FILE_ATTRIBUTE_TEMPORARY; + } + + switch (flags & (UV_FS_O_SEQUENTIAL | UV_FS_O_RANDOM)) { + case 0: + break; + case UV_FS_O_SEQUENTIAL: + attributes |= FILE_FLAG_SEQUENTIAL_SCAN; + break; + case UV_FS_O_RANDOM: + attributes |= FILE_FLAG_RANDOM_ACCESS; + break; + default: + goto einval; + } + + if (flags & UV_FS_O_DIRECT) { + /* + * FILE_APPEND_DATA and FILE_FLAG_NO_BUFFERING are mutually exclusive. + * Windows returns 87, ERROR_INVALID_PARAMETER if these are combined. + * + * FILE_APPEND_DATA is included in FILE_GENERIC_WRITE: + * + * FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE | + * FILE_WRITE_DATA | + * FILE_WRITE_ATTRIBUTES | + * FILE_WRITE_EA | + * FILE_APPEND_DATA | + * SYNCHRONIZE + * + * Note: Appends are also permitted by FILE_WRITE_DATA. + * + * In order for direct writes and direct appends to succeed, we therefore + * exclude FILE_APPEND_DATA if FILE_WRITE_DATA is specified, and otherwise + * fail if the user's sole permission is a direct append, since this + * particular combination is invalid. + */ + if (access & FILE_APPEND_DATA) { + if (access & FILE_WRITE_DATA) { + access &= ~FILE_APPEND_DATA; + } else { + goto einval; + } + } + attributes |= FILE_FLAG_NO_BUFFERING; + } + + switch (flags & (UV_FS_O_DSYNC | UV_FS_O_SYNC)) { + case 0: + break; + case UV_FS_O_DSYNC: + case UV_FS_O_SYNC: + attributes |= FILE_FLAG_WRITE_THROUGH; + break; + default: + goto einval; + } + + /* Setting this flag makes it possible to open a directory. */ + attributes |= FILE_FLAG_BACKUP_SEMANTICS; + + file = CreateFileW(req->file.pathw, + access, + share, + NULL, + disposition, + attributes, + NULL); + if (file == INVALID_HANDLE_VALUE) { + DWORD error = GetLastError(); + if (error == ERROR_FILE_EXISTS && (flags & UV_FS_O_CREAT) && + !(flags & UV_FS_O_EXCL)) { + /* Special case: when ERROR_FILE_EXISTS happens and UV_FS_O_CREAT was + * specified, it means the path referred to a directory. */ + SET_REQ_UV_ERROR(req, UV_EISDIR, error); + } else { + SET_REQ_WIN32_ERROR(req, GetLastError()); + } + return; + } + + fd = _open_osfhandle((intptr_t) file, flags); + if (fd < 0) { + /* The only known failure mode for _open_osfhandle() is EMFILE, in which + * case GetLastError() will return zero. However we'll try to handle other + * errors as well, should they ever occur. + */ + if (errno == EMFILE) + SET_REQ_UV_ERROR(req, UV_EMFILE, ERROR_TOO_MANY_OPEN_FILES); + else if (GetLastError() != ERROR_SUCCESS) + SET_REQ_WIN32_ERROR(req, GetLastError()); + else + SET_REQ_WIN32_ERROR(req, (DWORD) UV_UNKNOWN); + CloseHandle(file); + return; + } + + if (flags & UV_FS_O_FILEMAP) { + FILE_STANDARD_INFO file_info; + if (!GetFileInformationByHandleEx(file, + FileStandardInfo, + &file_info, + sizeof file_info)) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + CloseHandle(file); + return; + } + fd_info.is_directory = file_info.Directory; + + if (fd_info.is_directory) { + fd_info.size.QuadPart = 0; + fd_info.mapping = INVALID_HANDLE_VALUE; + } else { + if (!GetFileSizeEx(file, &fd_info.size)) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + CloseHandle(file); + return; + } + + if (fd_info.size.QuadPart == 0) { + fd_info.mapping = INVALID_HANDLE_VALUE; + } else { + DWORD flProtect = (fd_info.flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY | + UV_FS_O_RDWR)) == UV_FS_O_RDONLY ? PAGE_READONLY : PAGE_READWRITE; + fd_info.mapping = CreateFileMapping(file, + NULL, + flProtect, + fd_info.size.HighPart, + fd_info.size.LowPart, + NULL); + if (fd_info.mapping == NULL) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + CloseHandle(file); + return; + } + } + } + + uv__fd_hash_add(fd, &fd_info); + } + + SET_REQ_RESULT(req, fd); + return; + + einval: + SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER); +} + +void fs__close(uv_fs_t* req) { + int fd = req->file.fd; + int result; + struct uv__fd_info_s fd_info; + + VERIFY_FD(fd, req); + + if (uv__fd_hash_remove(fd, &fd_info)) { + if (fd_info.mapping != INVALID_HANDLE_VALUE) { + CloseHandle(fd_info.mapping); + } + } + + if (fd > 2) + result = _close(fd); + else + result = 0; + + /* _close doesn't set _doserrno on failure, but it does always set errno + * to EBADF on failure. + */ + if (result == -1) { + assert(errno == EBADF); + SET_REQ_UV_ERROR(req, UV_EBADF, ERROR_INVALID_HANDLE); + } else { + SET_REQ_RESULT(req, 0); + } +} + + +LONG fs__filemap_ex_filter(LONG excode, PEXCEPTION_POINTERS pep, + int* perror) { + if (excode != (LONG)EXCEPTION_IN_PAGE_ERROR) { + return EXCEPTION_CONTINUE_SEARCH; + } + + assert(perror != NULL); + if (pep != NULL && pep->ExceptionRecord != NULL && + pep->ExceptionRecord->NumberParameters >= 3) { + NTSTATUS status = (NTSTATUS)pep->ExceptionRecord->ExceptionInformation[3]; + *perror = pRtlNtStatusToDosError(status); + if (*perror != ERROR_SUCCESS) { + return EXCEPTION_EXECUTE_HANDLER; + } + } + *perror = UV_UNKNOWN; + return EXCEPTION_EXECUTE_HANDLER; +} + + +void fs__read_filemap(uv_fs_t* req, struct uv__fd_info_s* fd_info) { + int fd = req->file.fd; /* VERIFY_FD done in fs__read */ + int rw_flags = fd_info->flags & + (UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR); + size_t read_size, done_read; + unsigned int index; + LARGE_INTEGER pos, end_pos; + size_t view_offset; + LARGE_INTEGER view_base; + void* view; + + if (rw_flags == UV_FS_O_WRONLY) { + SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED); + return; + } + if (fd_info->is_directory) { + SET_REQ_WIN32_ERROR(req, ERROR_INVALID_FUNCTION); + return; + } + + if (req->fs.info.offset == -1) { + pos = fd_info->current_pos; + } else { + pos.QuadPart = req->fs.info.offset; + } + + /* Make sure we wont read past EOF. */ + if (pos.QuadPart >= fd_info->size.QuadPart) { + SET_REQ_RESULT(req, 0); + return; + } + + read_size = 0; + for (index = 0; index < req->fs.info.nbufs; ++index) { + read_size += req->fs.info.bufs[index].len; + } + read_size = (size_t) MIN((LONGLONG) read_size, + fd_info->size.QuadPart - pos.QuadPart); + if (read_size == 0) { + SET_REQ_RESULT(req, 0); + return; + } + + end_pos.QuadPart = pos.QuadPart + read_size; + + view_offset = pos.QuadPart % uv__allocation_granularity; + view_base.QuadPart = pos.QuadPart - view_offset; + view = MapViewOfFile(fd_info->mapping, + FILE_MAP_READ, + view_base.HighPart, + view_base.LowPart, + view_offset + read_size); + if (view == NULL) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + return; + } + + done_read = 0; + for (index = 0; + index < req->fs.info.nbufs && done_read < read_size; + ++index) { + size_t this_read_size = MIN(req->fs.info.bufs[index].len, + read_size - done_read); +#ifdef _MSC_VER + int err = 0; + __try { +#endif + memcpy(req->fs.info.bufs[index].base, + (char*)view + view_offset + done_read, + this_read_size); +#ifdef _MSC_VER + } + __except (fs__filemap_ex_filter(GetExceptionCode(), + GetExceptionInformation(), &err)) { + SET_REQ_WIN32_ERROR(req, err); + UnmapViewOfFile(view); + return; + } +#endif + done_read += this_read_size; + } + assert(done_read == read_size); + + if (!UnmapViewOfFile(view)) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + return; + } + + if (req->fs.info.offset == -1) { + fd_info->current_pos = end_pos; + uv__fd_hash_add(fd, fd_info); + } + + SET_REQ_RESULT(req, read_size); + return; +} + +void fs__read(uv_fs_t* req) { + int fd = req->file.fd; + int64_t offset = req->fs.info.offset; + HANDLE handle; + OVERLAPPED overlapped, *overlapped_ptr; + LARGE_INTEGER offset_; + DWORD bytes; + DWORD error; + int result; + unsigned int index; + LARGE_INTEGER original_position; + LARGE_INTEGER zero_offset; + int restore_position; + struct uv__fd_info_s fd_info; + + VERIFY_FD(fd, req); + + if (uv__fd_hash_get(fd, &fd_info)) { + fs__read_filemap(req, &fd_info); + return; + } + + zero_offset.QuadPart = 0; + restore_position = 0; + handle = uv__get_osfhandle(fd); + + if (handle == INVALID_HANDLE_VALUE) { + SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); + return; + } + + if (offset != -1) { + memset(&overlapped, 0, sizeof overlapped); + overlapped_ptr = &overlapped; + if (SetFilePointerEx(handle, zero_offset, &original_position, + FILE_CURRENT)) { + restore_position = 1; + } + } else { + overlapped_ptr = NULL; + } + + index = 0; + bytes = 0; + do { + DWORD incremental_bytes; + + if (offset != -1) { + offset_.QuadPart = offset + bytes; + overlapped.Offset = offset_.LowPart; + overlapped.OffsetHigh = offset_.HighPart; + } + + result = ReadFile(handle, + req->fs.info.bufs[index].base, + req->fs.info.bufs[index].len, + &incremental_bytes, + overlapped_ptr); + bytes += incremental_bytes; + ++index; + } while (result && index < req->fs.info.nbufs); + + if (restore_position) + SetFilePointerEx(handle, original_position, NULL, FILE_BEGIN); + + if (result || bytes > 0) { + SET_REQ_RESULT(req, bytes); + } else { + error = GetLastError(); + if (error == ERROR_HANDLE_EOF) { + SET_REQ_RESULT(req, bytes); + } else { + SET_REQ_WIN32_ERROR(req, error); + } + } +} + + +void fs__write_filemap(uv_fs_t* req, HANDLE file, + struct uv__fd_info_s* fd_info) { + int fd = req->file.fd; /* VERIFY_FD done in fs__write */ + int force_append = fd_info->flags & UV_FS_O_APPEND; + int rw_flags = fd_info->flags & + (UV_FS_O_RDONLY | UV_FS_O_WRONLY | UV_FS_O_RDWR); + size_t write_size, done_write; + unsigned int index; + LARGE_INTEGER pos, end_pos; + size_t view_offset; + LARGE_INTEGER view_base; + void* view; + FILETIME ft; + + if (rw_flags == UV_FS_O_RDONLY) { + SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED); + return; + } + if (fd_info->is_directory) { + SET_REQ_WIN32_ERROR(req, ERROR_INVALID_FUNCTION); + return; + } + + write_size = 0; + for (index = 0; index < req->fs.info.nbufs; ++index) { + write_size += req->fs.info.bufs[index].len; + } + + if (write_size == 0) { + SET_REQ_RESULT(req, 0); + return; + } + + if (force_append) { + pos = fd_info->size; + } else if (req->fs.info.offset == -1) { + pos = fd_info->current_pos; + } else { + pos.QuadPart = req->fs.info.offset; + } + + end_pos.QuadPart = pos.QuadPart + write_size; + + /* Recreate the mapping to enlarge the file if needed */ + if (end_pos.QuadPart > fd_info->size.QuadPart) { + if (fd_info->mapping != INVALID_HANDLE_VALUE) { + CloseHandle(fd_info->mapping); + } + + fd_info->mapping = CreateFileMapping(file, + NULL, + PAGE_READWRITE, + end_pos.HighPart, + end_pos.LowPart, + NULL); + if (fd_info->mapping == NULL) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + CloseHandle(file); + fd_info->mapping = INVALID_HANDLE_VALUE; + fd_info->size.QuadPart = 0; + fd_info->current_pos.QuadPart = 0; + uv__fd_hash_add(fd, fd_info); + return; + } + + fd_info->size = end_pos; + uv__fd_hash_add(fd, fd_info); + } + + view_offset = pos.QuadPart % uv__allocation_granularity; + view_base.QuadPart = pos.QuadPart - view_offset; + view = MapViewOfFile(fd_info->mapping, + FILE_MAP_WRITE, + view_base.HighPart, + view_base.LowPart, + view_offset + write_size); + if (view == NULL) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + return; + } + + done_write = 0; + for (index = 0; index < req->fs.info.nbufs; ++index) { +#ifdef _MSC_VER + int err = 0; + __try { +#endif + memcpy((char*)view + view_offset + done_write, + req->fs.info.bufs[index].base, + req->fs.info.bufs[index].len); +#ifdef _MSC_VER + } + __except (fs__filemap_ex_filter(GetExceptionCode(), + GetExceptionInformation(), &err)) { + SET_REQ_WIN32_ERROR(req, err); + UnmapViewOfFile(view); + return; + } +#endif + done_write += req->fs.info.bufs[index].len; + } + assert(done_write == write_size); + + if (!FlushViewOfFile(view, 0)) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + UnmapViewOfFile(view); + return; + } + if (!UnmapViewOfFile(view)) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + return; + } + + if (req->fs.info.offset == -1) { + fd_info->current_pos = end_pos; + uv__fd_hash_add(fd, fd_info); + } + + GetSystemTimeAsFileTime(&ft); + SetFileTime(file, NULL, NULL, &ft); + + SET_REQ_RESULT(req, done_write); +} + +void fs__write(uv_fs_t* req) { + int fd = req->file.fd; + int64_t offset = req->fs.info.offset; + HANDLE handle; + OVERLAPPED overlapped, *overlapped_ptr; + LARGE_INTEGER offset_; + DWORD bytes; + int result; + unsigned int index; + LARGE_INTEGER original_position; + LARGE_INTEGER zero_offset; + int restore_position; + struct uv__fd_info_s fd_info; + + VERIFY_FD(fd, req); + + zero_offset.QuadPart = 0; + restore_position = 0; + handle = uv__get_osfhandle(fd); + if (handle == INVALID_HANDLE_VALUE) { + SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); + return; + } + + if (uv__fd_hash_get(fd, &fd_info)) { + fs__write_filemap(req, handle, &fd_info); + return; + } + + if (offset != -1) { + memset(&overlapped, 0, sizeof overlapped); + overlapped_ptr = &overlapped; + if (SetFilePointerEx(handle, zero_offset, &original_position, + FILE_CURRENT)) { + restore_position = 1; + } + } else { + overlapped_ptr = NULL; + } + + index = 0; + bytes = 0; + do { + DWORD incremental_bytes; + + if (offset != -1) { + offset_.QuadPart = offset + bytes; + overlapped.Offset = offset_.LowPart; + overlapped.OffsetHigh = offset_.HighPart; + } + + result = WriteFile(handle, + req->fs.info.bufs[index].base, + req->fs.info.bufs[index].len, + &incremental_bytes, + overlapped_ptr); + bytes += incremental_bytes; + ++index; + } while (result && index < req->fs.info.nbufs); + + if (restore_position) + SetFilePointerEx(handle, original_position, NULL, FILE_BEGIN); + + if (result || bytes > 0) { + SET_REQ_RESULT(req, bytes); + } else { + SET_REQ_WIN32_ERROR(req, GetLastError()); + } +} + + +void fs__rmdir(uv_fs_t* req) { + int result = _wrmdir(req->file.pathw); + if (result == -1) + SET_REQ_WIN32_ERROR(req, _doserrno); + else + SET_REQ_RESULT(req, 0); +} + + +void fs__unlink(uv_fs_t* req) { + const WCHAR* pathw = req->file.pathw; + HANDLE handle; + BY_HANDLE_FILE_INFORMATION info; + FILE_DISPOSITION_INFORMATION disposition; + IO_STATUS_BLOCK iosb; + NTSTATUS status; + + handle = CreateFileW(pathw, + FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | DELETE, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, + NULL); + + if (handle == INVALID_HANDLE_VALUE) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + return; + } + + if (!GetFileInformationByHandle(handle, &info)) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + CloseHandle(handle); + return; + } + + if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + /* Do not allow deletion of directories, unless it is a symlink. When the + * path refers to a non-symlink directory, report EPERM as mandated by + * POSIX.1. */ + + /* Check if it is a reparse point. If it's not, it's a normal directory. */ + if (!(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { + SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED); + CloseHandle(handle); + return; + } + + /* Read the reparse point and check if it is a valid symlink. If not, don't + * unlink. */ + if (fs__readlink_handle(handle, NULL, NULL) < 0) { + DWORD error = GetLastError(); + if (error == ERROR_SYMLINK_NOT_SUPPORTED) + error = ERROR_ACCESS_DENIED; + SET_REQ_WIN32_ERROR(req, error); + CloseHandle(handle); + return; + } + } + + if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { + /* Remove read-only attribute */ + FILE_BASIC_INFORMATION basic = { 0 }; + + basic.FileAttributes = (info.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY) | + FILE_ATTRIBUTE_ARCHIVE; + + status = pNtSetInformationFile(handle, + &iosb, + &basic, + sizeof basic, + FileBasicInformation); + if (!NT_SUCCESS(status)) { + SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); + CloseHandle(handle); + return; + } + } + + /* Try to set the delete flag. */ + disposition.DeleteFile = TRUE; + status = pNtSetInformationFile(handle, + &iosb, + &disposition, + sizeof disposition, + FileDispositionInformation); + if (NT_SUCCESS(status)) { + SET_REQ_SUCCESS(req); + } else { + SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); + } + + CloseHandle(handle); +} + + +void fs__mkdir(uv_fs_t* req) { + /* TODO: use req->mode. */ + if (CreateDirectoryW(req->file.pathw, NULL)) { + SET_REQ_RESULT(req, 0); + } else { + SET_REQ_WIN32_ERROR(req, GetLastError()); + if (req->sys_errno_ == ERROR_INVALID_NAME || + req->sys_errno_ == ERROR_DIRECTORY) + req->result = UV_EINVAL; + } +} + +typedef int (*uv__fs_mktemp_func)(uv_fs_t* req); + +/* OpenBSD original: lib/libc/stdio/mktemp.c */ +void fs__mktemp(uv_fs_t* req, uv__fs_mktemp_func func) { + static const WCHAR *tempchars = + L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + static const size_t num_chars = 62; + static const size_t num_x = 6; + WCHAR *cp, *ep; + unsigned int tries, i; + size_t len; + uint64_t v; + char* path; + + path = (char*)req->path; + len = wcslen(req->file.pathw); + ep = req->file.pathw + len; + if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) { + SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER); + goto clobber; + } + + tries = TMP_MAX; + do { + if (uv__random_rtlgenrandom((void *)&v, sizeof(v)) < 0) { + SET_REQ_UV_ERROR(req, UV_EIO, ERROR_IO_DEVICE); + goto clobber; + } + + cp = ep - num_x; + for (i = 0; i < num_x; i++) { + *cp++ = tempchars[v % num_chars]; + v /= num_chars; + } + + if (func(req)) { + if (req->result >= 0) { + len = strlen(path); + wcstombs(path + len - num_x, ep - num_x, num_x); + } + return; + } + } while (--tries); + + SET_REQ_WIN32_ERROR(req, GetLastError()); + +clobber: + path[0] = '\0'; +} + + +static int fs__mkdtemp_func(uv_fs_t* req) { + DWORD error; + if (CreateDirectoryW(req->file.pathw, NULL)) { + SET_REQ_RESULT(req, 0); + return 1; + } + error = GetLastError(); + if (error != ERROR_ALREADY_EXISTS) { + SET_REQ_WIN32_ERROR(req, error); + return 1; + } + + return 0; +} + + +void fs__mkdtemp(uv_fs_t* req) { + fs__mktemp(req, fs__mkdtemp_func); +} + + +static int fs__mkstemp_func(uv_fs_t* req) { + HANDLE file; + int fd; + + file = CreateFileW(req->file.pathw, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, + CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (file == INVALID_HANDLE_VALUE) { + DWORD error; + error = GetLastError(); + + /* If the file exists, the main fs__mktemp() function + will retry. If it's another error, we want to stop. */ + if (error != ERROR_FILE_EXISTS) { + SET_REQ_WIN32_ERROR(req, error); + return 1; + } + + return 0; + } + + fd = _open_osfhandle((intptr_t) file, 0); + if (fd < 0) { + /* The only known failure mode for _open_osfhandle() is EMFILE, in which + * case GetLastError() will return zero. However we'll try to handle other + * errors as well, should they ever occur. + */ + if (errno == EMFILE) + SET_REQ_UV_ERROR(req, UV_EMFILE, ERROR_TOO_MANY_OPEN_FILES); + else if (GetLastError() != ERROR_SUCCESS) + SET_REQ_WIN32_ERROR(req, GetLastError()); + else + SET_REQ_WIN32_ERROR(req, UV_UNKNOWN); + CloseHandle(file); + return 1; + } + + SET_REQ_RESULT(req, fd); + + return 1; +} + + +void fs__mkstemp(uv_fs_t* req) { + fs__mktemp(req, fs__mkstemp_func); +} + + +void fs__scandir(uv_fs_t* req) { + static const size_t dirents_initial_size = 32; + + HANDLE dir_handle = INVALID_HANDLE_VALUE; + + uv__dirent_t** dirents = NULL; + size_t dirents_size = 0; + size_t dirents_used = 0; + + IO_STATUS_BLOCK iosb; + NTSTATUS status; + + /* Buffer to hold directory entries returned by NtQueryDirectoryFile. + * It's important that this buffer can hold at least one entry, regardless + * of the length of the file names present in the enumerated directory. + * A file name is at most 256 WCHARs long. + * According to MSDN, the buffer must be aligned at an 8-byte boundary. + */ +#if _MSC_VER + __declspec(align(8)) char buffer[8192]; +#else + __attribute__ ((aligned (8))) char buffer[8192]; +#endif + + STATIC_ASSERT(sizeof buffer >= + sizeof(FILE_DIRECTORY_INFORMATION) + 256 * sizeof(WCHAR)); + + /* Open the directory. */ + dir_handle = + CreateFileW(req->file.pathw, + FILE_LIST_DIRECTORY | SYNCHRONIZE, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL); + if (dir_handle == INVALID_HANDLE_VALUE) + goto win32_error; + + /* Read the first chunk. */ + status = pNtQueryDirectoryFile(dir_handle, + NULL, + NULL, + NULL, + &iosb, + &buffer, + sizeof buffer, + FileDirectoryInformation, + FALSE, + NULL, + TRUE); + + /* If the handle is not a directory, we'll get STATUS_INVALID_PARAMETER. + * This should be reported back as UV_ENOTDIR. + */ + if (status == (NTSTATUS)STATUS_INVALID_PARAMETER) + goto not_a_directory_error; + + while (NT_SUCCESS(status)) { + char* position = buffer; + size_t next_entry_offset = 0; + + do { + FILE_DIRECTORY_INFORMATION* info; + uv__dirent_t* dirent; + + size_t wchar_len; + size_t utf8_len; + + /* Obtain a pointer to the current directory entry. */ + position += next_entry_offset; + info = (FILE_DIRECTORY_INFORMATION*) position; + + /* Fetch the offset to the next directory entry. */ + next_entry_offset = info->NextEntryOffset; + + /* Compute the length of the filename in WCHARs. */ + wchar_len = info->FileNameLength / sizeof info->FileName[0]; + + /* Skip over '.' and '..' entries. It has been reported that + * the SharePoint driver includes the terminating zero byte in + * the filename length. Strip those first. + */ + while (wchar_len > 0 && info->FileName[wchar_len - 1] == L'\0') + wchar_len -= 1; + + if (wchar_len == 0) + continue; + if (wchar_len == 1 && info->FileName[0] == L'.') + continue; + if (wchar_len == 2 && info->FileName[0] == L'.' && + info->FileName[1] == L'.') + continue; + + /* Compute the space required to store the filename as UTF-8. */ + utf8_len = WideCharToMultiByte( + CP_UTF8, 0, &info->FileName[0], wchar_len, NULL, 0, NULL, NULL); + if (utf8_len == 0) + goto win32_error; + + /* Resize the dirent array if needed. */ + if (dirents_used >= dirents_size) { + size_t new_dirents_size = + dirents_size == 0 ? dirents_initial_size : dirents_size << 1; + uv__dirent_t** new_dirents = + uv__realloc(dirents, new_dirents_size * sizeof *dirents); + + if (new_dirents == NULL) + goto out_of_memory_error; + + dirents_size = new_dirents_size; + dirents = new_dirents; + } + + /* Allocate space for the uv dirent structure. The dirent structure + * includes room for the first character of the filename, but `utf8_len` + * doesn't count the NULL terminator at this point. + */ + dirent = uv__malloc(sizeof *dirent + utf8_len); + if (dirent == NULL) + goto out_of_memory_error; + + dirents[dirents_used++] = dirent; + + /* Convert file name to UTF-8. */ + if (WideCharToMultiByte(CP_UTF8, + 0, + &info->FileName[0], + wchar_len, + &dirent->d_name[0], + utf8_len, + NULL, + NULL) == 0) + goto win32_error; + + /* Add a null terminator to the filename. */ + dirent->d_name[utf8_len] = '\0'; + + /* Fill out the type field. */ + if (info->FileAttributes & FILE_ATTRIBUTE_DEVICE) + dirent->d_type = UV__DT_CHAR; + else if (info->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) + dirent->d_type = UV__DT_LINK; + else if (info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) + dirent->d_type = UV__DT_DIR; + else + dirent->d_type = UV__DT_FILE; + } while (next_entry_offset != 0); + + /* Read the next chunk. */ + status = pNtQueryDirectoryFile(dir_handle, + NULL, + NULL, + NULL, + &iosb, + &buffer, + sizeof buffer, + FileDirectoryInformation, + FALSE, + NULL, + FALSE); + + /* After the first pNtQueryDirectoryFile call, the function may return + * STATUS_SUCCESS even if the buffer was too small to hold at least one + * directory entry. + */ + if (status == STATUS_SUCCESS && iosb.Information == 0) + status = STATUS_BUFFER_OVERFLOW; + } + + if (status != STATUS_NO_MORE_FILES) + goto nt_error; + + CloseHandle(dir_handle); + + /* Store the result in the request object. */ + req->ptr = dirents; + if (dirents != NULL) + req->flags |= UV_FS_FREE_PTR; + + SET_REQ_RESULT(req, dirents_used); + + /* `nbufs` will be used as index by uv_fs_scandir_next. */ + req->fs.info.nbufs = 0; + + return; + +nt_error: + SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); + goto cleanup; + +win32_error: + SET_REQ_WIN32_ERROR(req, GetLastError()); + goto cleanup; + +not_a_directory_error: + SET_REQ_UV_ERROR(req, UV_ENOTDIR, ERROR_DIRECTORY); + goto cleanup; + +out_of_memory_error: + SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); + goto cleanup; + +cleanup: + if (dir_handle != INVALID_HANDLE_VALUE) + CloseHandle(dir_handle); + while (dirents_used > 0) + uv__free(dirents[--dirents_used]); + if (dirents != NULL) + uv__free(dirents); +} + +void fs__opendir(uv_fs_t* req) { + WCHAR* pathw; + size_t len; + const WCHAR* fmt; + WCHAR* find_path; + uv_dir_t* dir; + + pathw = req->file.pathw; + dir = NULL; + find_path = NULL; + + /* Figure out whether path is a file or a directory. */ + if (!(GetFileAttributesW(pathw) & FILE_ATTRIBUTE_DIRECTORY)) { + SET_REQ_UV_ERROR(req, UV_ENOTDIR, ERROR_DIRECTORY); + goto error; + } + + dir = uv__malloc(sizeof(*dir)); + if (dir == NULL) { + SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); + goto error; + } + + len = wcslen(pathw); + + if (len == 0) + fmt = L"./*"; + else if (IS_SLASH(pathw[len - 1])) + fmt = L"%s*"; + else + fmt = L"%s\\*"; + + find_path = uv__malloc(sizeof(WCHAR) * (len + 4)); + if (find_path == NULL) { + SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); + goto error; + } + + _snwprintf(find_path, len + 3, fmt, pathw); + dir->dir_handle = FindFirstFileW(find_path, &dir->find_data); + uv__free(find_path); + find_path = NULL; + if (dir->dir_handle == INVALID_HANDLE_VALUE && + GetLastError() != ERROR_FILE_NOT_FOUND) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + goto error; + } + + dir->need_find_call = FALSE; + req->ptr = dir; + SET_REQ_RESULT(req, 0); + return; + +error: + uv__free(dir); + uv__free(find_path); + req->ptr = NULL; +} + +void fs__readdir(uv_fs_t* req) { + uv_dir_t* dir; + uv_dirent_t* dirents; + uv__dirent_t dent; + unsigned int dirent_idx; + PWIN32_FIND_DATAW find_data; + unsigned int i; + int r; + + req->flags |= UV_FS_FREE_PTR; + dir = req->ptr; + dirents = dir->dirents; + memset(dirents, 0, dir->nentries * sizeof(*dir->dirents)); + find_data = &dir->find_data; + dirent_idx = 0; + + while (dirent_idx < dir->nentries) { + if (dir->need_find_call && FindNextFileW(dir->dir_handle, find_data) == 0) { + if (GetLastError() == ERROR_NO_MORE_FILES) + break; + goto error; + } + + /* Skip "." and ".." entries. */ + if (find_data->cFileName[0] == L'.' && + (find_data->cFileName[1] == L'\0' || + (find_data->cFileName[1] == L'.' && + find_data->cFileName[2] == L'\0'))) { + dir->need_find_call = TRUE; + continue; + } + + r = uv__convert_utf16_to_utf8((const WCHAR*) &find_data->cFileName, + -1, + (char**) &dirents[dirent_idx].name); + if (r != 0) + goto error; + + /* Copy file type. */ + if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) + dent.d_type = UV__DT_DIR; + else if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) + dent.d_type = UV__DT_LINK; + else if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_DEVICE) != 0) + dent.d_type = UV__DT_CHAR; + else + dent.d_type = UV__DT_FILE; + + dirents[dirent_idx].type = uv__fs_get_dirent_type(&dent); + dir->need_find_call = TRUE; + ++dirent_idx; + } + + SET_REQ_RESULT(req, dirent_idx); + return; + +error: + SET_REQ_WIN32_ERROR(req, GetLastError()); + for (i = 0; i < dirent_idx; ++i) { + uv__free((char*) dirents[i].name); + dirents[i].name = NULL; + } +} + +void fs__closedir(uv_fs_t* req) { + uv_dir_t* dir; + + dir = req->ptr; + FindClose(dir->dir_handle); + uv__free(req->ptr); + SET_REQ_RESULT(req, 0); +} + +INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf, + int do_lstat) { + FILE_ALL_INFORMATION file_info; + FILE_FS_VOLUME_INFORMATION volume_info; + NTSTATUS nt_status; + IO_STATUS_BLOCK io_status; + + nt_status = pNtQueryInformationFile(handle, + &io_status, + &file_info, + sizeof file_info, + FileAllInformation); + + /* Buffer overflow (a warning status code) is expected here. */ + if (NT_ERROR(nt_status)) { + SetLastError(pRtlNtStatusToDosError(nt_status)); + return -1; + } + + nt_status = pNtQueryVolumeInformationFile(handle, + &io_status, + &volume_info, + sizeof volume_info, + FileFsVolumeInformation); + + /* Buffer overflow (a warning status code) is expected here. */ + if (io_status.Status == STATUS_NOT_IMPLEMENTED) { + statbuf->st_dev = 0; + } else if (NT_ERROR(nt_status)) { + SetLastError(pRtlNtStatusToDosError(nt_status)); + return -1; + } else { + statbuf->st_dev = volume_info.VolumeSerialNumber; + } + + /* Todo: st_mode should probably always be 0666 for everyone. We might also + * want to report 0777 if the file is a .exe or a directory. + * + * Currently it's based on whether the 'readonly' attribute is set, which + * makes little sense because the semantics are so different: the 'read-only' + * flag is just a way for a user to protect against accidental deletion, and + * serves no security purpose. Windows uses ACLs for that. + * + * Also people now use uv_fs_chmod() to take away the writable bit for good + * reasons. Windows however just makes the file read-only, which makes it + * impossible to delete the file afterwards, since read-only files can't be + * deleted. + * + * IOW it's all just a clusterfuck and we should think of something that + * makes slightly more sense. + * + * And uv_fs_chmod should probably just fail on windows or be a total no-op. + * There's nothing sensible it can do anyway. + */ + statbuf->st_mode = 0; + + /* + * On Windows, FILE_ATTRIBUTE_REPARSE_POINT is a general purpose mechanism + * by which filesystem drivers can intercept and alter file system requests. + * + * The only reparse points we care about are symlinks and mount points, both + * of which are treated as POSIX symlinks. Further, we only care when + * invoked via lstat, which seeks information about the link instead of its + * target. Otherwise, reparse points must be treated as regular files. + */ + if (do_lstat && + (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { + /* + * If reading the link fails, the reparse point is not a symlink and needs + * to be treated as a regular file. The higher level lstat function will + * detect this failure and retry without do_lstat if appropriate. + */ + if (fs__readlink_handle(handle, NULL, &statbuf->st_size) != 0) + return -1; + statbuf->st_mode |= S_IFLNK; + } + + if (statbuf->st_mode == 0) { + if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + statbuf->st_mode |= _S_IFDIR; + statbuf->st_size = 0; + } else { + statbuf->st_mode |= _S_IFREG; + statbuf->st_size = file_info.StandardInformation.EndOfFile.QuadPart; + } + } + + if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_READONLY) + statbuf->st_mode |= _S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6); + else + statbuf->st_mode |= (_S_IREAD | _S_IWRITE) | ((_S_IREAD | _S_IWRITE) >> 3) | + ((_S_IREAD | _S_IWRITE) >> 6); + + uv__filetime_to_timespec(&statbuf->st_atim, + file_info.BasicInformation.LastAccessTime.QuadPart); + uv__filetime_to_timespec(&statbuf->st_ctim, + file_info.BasicInformation.ChangeTime.QuadPart); + uv__filetime_to_timespec(&statbuf->st_mtim, + file_info.BasicInformation.LastWriteTime.QuadPart); + uv__filetime_to_timespec(&statbuf->st_birthtim, + file_info.BasicInformation.CreationTime.QuadPart); + + statbuf->st_ino = file_info.InternalInformation.IndexNumber.QuadPart; + + /* st_blocks contains the on-disk allocation size in 512-byte units. */ + statbuf->st_blocks = + (uint64_t) file_info.StandardInformation.AllocationSize.QuadPart >> 9; + + statbuf->st_nlink = file_info.StandardInformation.NumberOfLinks; + + /* The st_blksize is supposed to be the 'optimal' number of bytes for reading + * and writing to the disk. That is, for any definition of 'optimal' - it's + * supposed to at least avoid read-update-write behavior when writing to the + * disk. + * + * However nobody knows this and even fewer people actually use this value, + * and in order to fill it out we'd have to make another syscall to query the + * volume for FILE_FS_SECTOR_SIZE_INFORMATION. + * + * Therefore we'll just report a sensible value that's quite commonly okay + * on modern hardware. + * + * 4096 is the minimum required to be compatible with newer Advanced Format + * drives (which have 4096 bytes per physical sector), and to be backwards + * compatible with older drives (which have 512 bytes per physical sector). + */ + statbuf->st_blksize = 4096; + + /* Todo: set st_flags to something meaningful. Also provide a wrapper for + * chattr(2). + */ + statbuf->st_flags = 0; + + /* Windows has nothing sensible to say about these values, so they'll just + * remain empty. + */ + statbuf->st_gid = 0; + statbuf->st_uid = 0; + statbuf->st_rdev = 0; + statbuf->st_gen = 0; + + return 0; +} + + +INLINE static void fs__stat_prepare_path(WCHAR* pathw) { + size_t len = wcslen(pathw); + + /* TODO: ignore namespaced paths. */ + if (len > 1 && pathw[len - 2] != L':' && + (pathw[len - 1] == L'\\' || pathw[len - 1] == L'/')) { + pathw[len - 1] = '\0'; + } +} + + +INLINE static DWORD fs__stat_impl_from_path(WCHAR* path, + int do_lstat, + uv_stat_t* statbuf) { + HANDLE handle; + DWORD flags; + DWORD ret; + + flags = FILE_FLAG_BACKUP_SEMANTICS; + if (do_lstat) + flags |= FILE_FLAG_OPEN_REPARSE_POINT; + + handle = CreateFileW(path, + FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, + OPEN_EXISTING, + flags, + NULL); + + if (handle == INVALID_HANDLE_VALUE) + ret = GetLastError(); + else if (fs__stat_handle(handle, statbuf, do_lstat) != 0) + ret = GetLastError(); + else + ret = 0; + + CloseHandle(handle); + return ret; +} + + +INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) { + DWORD error; + + error = fs__stat_impl_from_path(req->file.pathw, do_lstat, &req->statbuf); + if (error != 0) { + if (do_lstat && + (error == ERROR_SYMLINK_NOT_SUPPORTED || + error == ERROR_NOT_A_REPARSE_POINT)) { + /* We opened a reparse point but it was not a symlink. Try again. */ + fs__stat_impl(req, 0); + } else { + /* Stat failed. */ + SET_REQ_WIN32_ERROR(req, error); + } + + return; + } + + req->ptr = &req->statbuf; + SET_REQ_RESULT(req, 0); +} + + +static void fs__stat(uv_fs_t* req) { + fs__stat_prepare_path(req->file.pathw); + fs__stat_impl(req, 0); +} + + +static void fs__lstat(uv_fs_t* req) { + fs__stat_prepare_path(req->file.pathw); + fs__stat_impl(req, 1); +} + + +static void fs__fstat(uv_fs_t* req) { + int fd = req->file.fd; + HANDLE handle; + + VERIFY_FD(fd, req); + + handle = uv__get_osfhandle(fd); + + if (handle == INVALID_HANDLE_VALUE) { + SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); + return; + } + + if (fs__stat_handle(handle, &req->statbuf, 0) != 0) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + return; + } + + req->ptr = &req->statbuf; + SET_REQ_RESULT(req, 0); +} + + +static void fs__rename(uv_fs_t* req) { + if (!MoveFileExW(req->file.pathw, req->fs.info.new_pathw, MOVEFILE_REPLACE_EXISTING)) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + return; + } + + SET_REQ_RESULT(req, 0); +} + + +INLINE static void fs__sync_impl(uv_fs_t* req) { + int fd = req->file.fd; + int result; + + VERIFY_FD(fd, req); + + result = FlushFileBuffers(uv__get_osfhandle(fd)) ? 0 : -1; + if (result == -1) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + } else { + SET_REQ_RESULT(req, result); + } +} + + +static void fs__fsync(uv_fs_t* req) { + fs__sync_impl(req); +} + + +static void fs__fdatasync(uv_fs_t* req) { + fs__sync_impl(req); +} + + +static void fs__ftruncate(uv_fs_t* req) { + int fd = req->file.fd; + HANDLE handle; + struct uv__fd_info_s fd_info = { 0 }; + NTSTATUS status; + IO_STATUS_BLOCK io_status; + FILE_END_OF_FILE_INFORMATION eof_info; + + VERIFY_FD(fd, req); + + handle = uv__get_osfhandle(fd); + + if (uv__fd_hash_get(fd, &fd_info)) { + if (fd_info.is_directory) { + SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED); + return; + } + + if (fd_info.mapping != INVALID_HANDLE_VALUE) { + CloseHandle(fd_info.mapping); + } + } + + eof_info.EndOfFile.QuadPart = req->fs.info.offset; + + status = pNtSetInformationFile(handle, + &io_status, + &eof_info, + sizeof eof_info, + FileEndOfFileInformation); + + if (NT_SUCCESS(status)) { + SET_REQ_RESULT(req, 0); + } else { + SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); + + if (fd_info.flags) { + CloseHandle(handle); + fd_info.mapping = INVALID_HANDLE_VALUE; + fd_info.size.QuadPart = 0; + fd_info.current_pos.QuadPart = 0; + uv__fd_hash_add(fd, &fd_info); + return; + } + } + + if (fd_info.flags) { + fd_info.size = eof_info.EndOfFile; + + if (fd_info.size.QuadPart == 0) { + fd_info.mapping = INVALID_HANDLE_VALUE; + } else { + DWORD flProtect = (fd_info.flags & (UV_FS_O_RDONLY | UV_FS_O_WRONLY | + UV_FS_O_RDWR)) == UV_FS_O_RDONLY ? PAGE_READONLY : PAGE_READWRITE; + fd_info.mapping = CreateFileMapping(handle, + NULL, + flProtect, + fd_info.size.HighPart, + fd_info.size.LowPart, + NULL); + if (fd_info.mapping == NULL) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + CloseHandle(handle); + fd_info.mapping = INVALID_HANDLE_VALUE; + fd_info.size.QuadPart = 0; + fd_info.current_pos.QuadPart = 0; + uv__fd_hash_add(fd, &fd_info); + return; + } + } + + uv__fd_hash_add(fd, &fd_info); + } +} + + +static void fs__copyfile(uv_fs_t* req) { + int flags; + int overwrite; + uv_stat_t statbuf; + uv_stat_t new_statbuf; + + flags = req->fs.info.file_flags; + + if (flags & UV_FS_COPYFILE_FICLONE_FORCE) { + SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED); + return; + } + + overwrite = flags & UV_FS_COPYFILE_EXCL; + + if (CopyFileW(req->file.pathw, req->fs.info.new_pathw, overwrite) != 0) { + SET_REQ_RESULT(req, 0); + return; + } + + SET_REQ_WIN32_ERROR(req, GetLastError()); + if (req->result != UV_EBUSY) + return; + + /* if error UV_EBUSY check if src and dst file are the same */ + if (fs__stat_impl_from_path(req->file.pathw, 0, &statbuf) != 0 || + fs__stat_impl_from_path(req->fs.info.new_pathw, 0, &new_statbuf) != 0) { + return; + } + + if (statbuf.st_dev == new_statbuf.st_dev && + statbuf.st_ino == new_statbuf.st_ino) { + SET_REQ_RESULT(req, 0); + } +} + + +static void fs__sendfile(uv_fs_t* req) { + int fd_in = req->file.fd, fd_out = req->fs.info.fd_out; + size_t length = req->fs.info.bufsml[0].len; + int64_t offset = req->fs.info.offset; + const size_t max_buf_size = 65536; + size_t buf_size = length < max_buf_size ? length : max_buf_size; + int n, result = 0; + int64_t result_offset = 0; + char* buf = (char*) uv__malloc(buf_size); + if (!buf) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + if (offset != -1) { + result_offset = _lseeki64(fd_in, offset, SEEK_SET); + } + + if (result_offset == -1) { + result = -1; + } else { + while (length > 0) { + n = _read(fd_in, buf, length < buf_size ? length : buf_size); + if (n == 0) { + break; + } else if (n == -1) { + result = -1; + break; + } + + length -= n; + + n = _write(fd_out, buf, n); + if (n == -1) { + result = -1; + break; + } + + result += n; + } + } + + uv__free(buf); + + SET_REQ_RESULT(req, result); +} + + +static void fs__access(uv_fs_t* req) { + DWORD attr = GetFileAttributesW(req->file.pathw); + + if (attr == INVALID_FILE_ATTRIBUTES) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + return; + } + + /* + * Access is possible if + * - write access wasn't requested, + * - or the file isn't read-only, + * - or it's a directory. + * (Directories cannot be read-only on Windows.) + */ + if (!(req->fs.info.mode & W_OK) || + !(attr & FILE_ATTRIBUTE_READONLY) || + (attr & FILE_ATTRIBUTE_DIRECTORY)) { + SET_REQ_RESULT(req, 0); + } else { + SET_REQ_WIN32_ERROR(req, UV_EPERM); + } + +} + + +static void fs__chmod(uv_fs_t* req) { + int result = _wchmod(req->file.pathw, req->fs.info.mode); + if (result == -1) + SET_REQ_WIN32_ERROR(req, _doserrno); + else + SET_REQ_RESULT(req, 0); +} + + +static void fs__fchmod(uv_fs_t* req) { + int fd = req->file.fd; + int clear_archive_flag; + HANDLE handle; + NTSTATUS nt_status; + IO_STATUS_BLOCK io_status; + FILE_BASIC_INFORMATION file_info; + + VERIFY_FD(fd, req); + + handle = ReOpenFile(uv__get_osfhandle(fd), FILE_WRITE_ATTRIBUTES, 0, 0); + if (handle == INVALID_HANDLE_VALUE) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + return; + } + + nt_status = pNtQueryInformationFile(handle, + &io_status, + &file_info, + sizeof file_info, + FileBasicInformation); + + if (!NT_SUCCESS(nt_status)) { + SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status)); + goto fchmod_cleanup; + } + + /* Test if the Archive attribute is cleared */ + if ((file_info.FileAttributes & FILE_ATTRIBUTE_ARCHIVE) == 0) { + /* Set Archive flag, otherwise setting or clearing the read-only + flag will not work */ + file_info.FileAttributes |= FILE_ATTRIBUTE_ARCHIVE; + nt_status = pNtSetInformationFile(handle, + &io_status, + &file_info, + sizeof file_info, + FileBasicInformation); + if (!NT_SUCCESS(nt_status)) { + SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status)); + goto fchmod_cleanup; + } + /* Remeber to clear the flag later on */ + clear_archive_flag = 1; + } else { + clear_archive_flag = 0; + } + + if (req->fs.info.mode & _S_IWRITE) { + file_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY; + } else { + file_info.FileAttributes |= FILE_ATTRIBUTE_READONLY; + } + + nt_status = pNtSetInformationFile(handle, + &io_status, + &file_info, + sizeof file_info, + FileBasicInformation); + + if (!NT_SUCCESS(nt_status)) { + SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status)); + goto fchmod_cleanup; + } + + if (clear_archive_flag) { + file_info.FileAttributes &= ~FILE_ATTRIBUTE_ARCHIVE; + if (file_info.FileAttributes == 0) { + file_info.FileAttributes = FILE_ATTRIBUTE_NORMAL; + } + nt_status = pNtSetInformationFile(handle, + &io_status, + &file_info, + sizeof file_info, + FileBasicInformation); + if (!NT_SUCCESS(nt_status)) { + SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status)); + goto fchmod_cleanup; + } + } + + SET_REQ_SUCCESS(req); +fchmod_cleanup: + CloseHandle(handle); +} + + +INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) { + FILETIME filetime_a, filetime_m; + + TIME_T_TO_FILETIME(atime, &filetime_a); + TIME_T_TO_FILETIME(mtime, &filetime_m); + + if (!SetFileTime(handle, NULL, &filetime_a, &filetime_m)) { + return -1; + } + + return 0; +} + +INLINE static DWORD fs__utime_impl_from_path(WCHAR* path, + double atime, + double mtime, + int do_lutime) { + HANDLE handle; + DWORD flags; + DWORD ret; + + flags = FILE_FLAG_BACKUP_SEMANTICS; + if (do_lutime) { + flags |= FILE_FLAG_OPEN_REPARSE_POINT; + } + + handle = CreateFileW(path, + FILE_WRITE_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, + OPEN_EXISTING, + flags, + NULL); + + if (handle == INVALID_HANDLE_VALUE) { + ret = GetLastError(); + } else if (fs__utime_handle(handle, atime, mtime) != 0) { + ret = GetLastError(); + } else { + ret = 0; + } + + CloseHandle(handle); + return ret; +} + +INLINE static void fs__utime_impl(uv_fs_t* req, int do_lutime) { + DWORD error; + + error = fs__utime_impl_from_path(req->file.pathw, + req->fs.time.atime, + req->fs.time.mtime, + do_lutime); + + if (error != 0) { + if (do_lutime && + (error == ERROR_SYMLINK_NOT_SUPPORTED || + error == ERROR_NOT_A_REPARSE_POINT)) { + /* Opened file is a reparse point but not a symlink. Try again. */ + fs__utime_impl(req, 0); + } else { + /* utime failed. */ + SET_REQ_WIN32_ERROR(req, error); + } + + return; + } + + SET_REQ_RESULT(req, 0); +} + +static void fs__utime(uv_fs_t* req) { + fs__utime_impl(req, /* do_lutime */ 0); +} + + +static void fs__futime(uv_fs_t* req) { + int fd = req->file.fd; + HANDLE handle; + VERIFY_FD(fd, req); + + handle = uv__get_osfhandle(fd); + + if (handle == INVALID_HANDLE_VALUE) { + SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); + return; + } + + if (fs__utime_handle(handle, req->fs.time.atime, req->fs.time.mtime) != 0) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + return; + } + + SET_REQ_RESULT(req, 0); +} + +static void fs__lutime(uv_fs_t* req) { + fs__utime_impl(req, /* do_lutime */ 1); +} + + +static void fs__link(uv_fs_t* req) { + DWORD r = CreateHardLinkW(req->fs.info.new_pathw, req->file.pathw, NULL); + if (r == 0) + SET_REQ_WIN32_ERROR(req, GetLastError()); + else + SET_REQ_RESULT(req, 0); +} + + +static void fs__create_junction(uv_fs_t* req, const WCHAR* path, + const WCHAR* new_path) { + HANDLE handle = INVALID_HANDLE_VALUE; + REPARSE_DATA_BUFFER *buffer = NULL; + int created = 0; + int target_len; + int is_absolute, is_long_path; + int needed_buf_size, used_buf_size, used_data_size, path_buf_len; + int start, len, i; + int add_slash; + DWORD bytes; + WCHAR* path_buf; + + target_len = wcslen(path); + is_long_path = wcsncmp(path, LONG_PATH_PREFIX, LONG_PATH_PREFIX_LEN) == 0; + + if (is_long_path) { + is_absolute = 1; + } else { + is_absolute = target_len >= 3 && IS_LETTER(path[0]) && + path[1] == L':' && IS_SLASH(path[2]); + } + + if (!is_absolute) { + /* Not supporting relative paths */ + SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_NOT_SUPPORTED); + return; + } + + /* Do a pessimistic calculation of the required buffer size */ + needed_buf_size = + FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) + + JUNCTION_PREFIX_LEN * sizeof(WCHAR) + + 2 * (target_len + 2) * sizeof(WCHAR); + + /* Allocate the buffer */ + buffer = (REPARSE_DATA_BUFFER*)uv__malloc(needed_buf_size); + if (!buffer) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + /* Grab a pointer to the part of the buffer where filenames go */ + path_buf = (WCHAR*)&(buffer->MountPointReparseBuffer.PathBuffer); + path_buf_len = 0; + + /* Copy the substitute (internal) target path */ + start = path_buf_len; + + wcsncpy((WCHAR*)&path_buf[path_buf_len], JUNCTION_PREFIX, + JUNCTION_PREFIX_LEN); + path_buf_len += JUNCTION_PREFIX_LEN; + + add_slash = 0; + for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) { + if (IS_SLASH(path[i])) { + add_slash = 1; + continue; + } + + if (add_slash) { + path_buf[path_buf_len++] = L'\\'; + add_slash = 0; + } + + path_buf[path_buf_len++] = path[i]; + } + path_buf[path_buf_len++] = L'\\'; + len = path_buf_len - start; + + /* Set the info about the substitute name */ + buffer->MountPointReparseBuffer.SubstituteNameOffset = start * sizeof(WCHAR); + buffer->MountPointReparseBuffer.SubstituteNameLength = len * sizeof(WCHAR); + + /* Insert null terminator */ + path_buf[path_buf_len++] = L'\0'; + + /* Copy the print name of the target path */ + start = path_buf_len; + add_slash = 0; + for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) { + if (IS_SLASH(path[i])) { + add_slash = 1; + continue; + } + + if (add_slash) { + path_buf[path_buf_len++] = L'\\'; + add_slash = 0; + } + + path_buf[path_buf_len++] = path[i]; + } + len = path_buf_len - start; + if (len == 2) { + path_buf[path_buf_len++] = L'\\'; + len++; + } + + /* Set the info about the print name */ + buffer->MountPointReparseBuffer.PrintNameOffset = start * sizeof(WCHAR); + buffer->MountPointReparseBuffer.PrintNameLength = len * sizeof(WCHAR); + + /* Insert another null terminator */ + path_buf[path_buf_len++] = L'\0'; + + /* Calculate how much buffer space was actually used */ + used_buf_size = FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) + + path_buf_len * sizeof(WCHAR); + used_data_size = used_buf_size - + FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer); + + /* Put general info in the data buffer */ + buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; + buffer->ReparseDataLength = used_data_size; + buffer->Reserved = 0; + + /* Create a new directory */ + if (!CreateDirectoryW(new_path, NULL)) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + goto error; + } + created = 1; + + /* Open the directory */ + handle = CreateFileW(new_path, + GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | + FILE_FLAG_OPEN_REPARSE_POINT, + NULL); + if (handle == INVALID_HANDLE_VALUE) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + goto error; + } + + /* Create the actual reparse point */ + if (!DeviceIoControl(handle, + FSCTL_SET_REPARSE_POINT, + buffer, + used_buf_size, + NULL, + 0, + &bytes, + NULL)) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + goto error; + } + + /* Clean up */ + CloseHandle(handle); + uv__free(buffer); + + SET_REQ_RESULT(req, 0); + return; + +error: + uv__free(buffer); + + if (handle != INVALID_HANDLE_VALUE) { + CloseHandle(handle); + } + + if (created) { + RemoveDirectoryW(new_path); + } +} + + +static void fs__symlink(uv_fs_t* req) { + WCHAR* pathw; + WCHAR* new_pathw; + int flags; + int err; + + pathw = req->file.pathw; + new_pathw = req->fs.info.new_pathw; + + if (req->fs.info.file_flags & UV_FS_SYMLINK_JUNCTION) { + fs__create_junction(req, pathw, new_pathw); + return; + } + + if (req->fs.info.file_flags & UV_FS_SYMLINK_DIR) + flags = SYMBOLIC_LINK_FLAG_DIRECTORY | uv__file_symlink_usermode_flag; + else + flags = uv__file_symlink_usermode_flag; + + if (CreateSymbolicLinkW(new_pathw, pathw, flags)) { + SET_REQ_RESULT(req, 0); + return; + } + + /* Something went wrong. We will test if it is because of user-mode + * symlinks. + */ + err = GetLastError(); + if (err == ERROR_INVALID_PARAMETER && + flags & SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) { + /* This system does not support user-mode symlinks. We will clear the + * unsupported flag and retry. + */ + uv__file_symlink_usermode_flag = 0; + fs__symlink(req); + } else { + SET_REQ_WIN32_ERROR(req, err); + } +} + + +static void fs__readlink(uv_fs_t* req) { + HANDLE handle; + + handle = CreateFileW(req->file.pathw, + 0, + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, + NULL); + + if (handle == INVALID_HANDLE_VALUE) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + return; + } + + if (fs__readlink_handle(handle, (char**) &req->ptr, NULL) != 0) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + CloseHandle(handle); + return; + } + + req->flags |= UV_FS_FREE_PTR; + SET_REQ_RESULT(req, 0); + + CloseHandle(handle); +} + + +static ssize_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) { + int r; + DWORD w_realpath_len; + WCHAR* w_realpath_ptr = NULL; + WCHAR* w_realpath_buf; + + w_realpath_len = GetFinalPathNameByHandleW(handle, NULL, 0, VOLUME_NAME_DOS); + if (w_realpath_len == 0) { + return -1; + } + + w_realpath_buf = uv__malloc((w_realpath_len + 1) * sizeof(WCHAR)); + if (w_realpath_buf == NULL) { + SetLastError(ERROR_OUTOFMEMORY); + return -1; + } + w_realpath_ptr = w_realpath_buf; + + if (GetFinalPathNameByHandleW( + handle, w_realpath_ptr, w_realpath_len, VOLUME_NAME_DOS) == 0) { + uv__free(w_realpath_buf); + SetLastError(ERROR_INVALID_HANDLE); + return -1; + } + + /* convert UNC path to long path */ + if (wcsncmp(w_realpath_ptr, + UNC_PATH_PREFIX, + UNC_PATH_PREFIX_LEN) == 0) { + w_realpath_ptr += 6; + *w_realpath_ptr = L'\\'; + w_realpath_len -= 6; + } else if (wcsncmp(w_realpath_ptr, + LONG_PATH_PREFIX, + LONG_PATH_PREFIX_LEN) == 0) { + w_realpath_ptr += 4; + w_realpath_len -= 4; + } else { + uv__free(w_realpath_buf); + SetLastError(ERROR_INVALID_HANDLE); + return -1; + } + + r = fs__wide_to_utf8(w_realpath_ptr, w_realpath_len, realpath_ptr, NULL); + uv__free(w_realpath_buf); + return r; +} + +static void fs__realpath(uv_fs_t* req) { + HANDLE handle; + + handle = CreateFileW(req->file.pathw, + 0, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, + NULL); + if (handle == INVALID_HANDLE_VALUE) { + SET_REQ_WIN32_ERROR(req, GetLastError()); + return; + } + + if (fs__realpath_handle(handle, (char**) &req->ptr) == -1) { + CloseHandle(handle); + SET_REQ_WIN32_ERROR(req, GetLastError()); + return; + } + + CloseHandle(handle); + req->flags |= UV_FS_FREE_PTR; + SET_REQ_RESULT(req, 0); +} + + +static void fs__chown(uv_fs_t* req) { + SET_REQ_RESULT(req, 0); +} + + +static void fs__fchown(uv_fs_t* req) { + SET_REQ_RESULT(req, 0); +} + + +static void fs__lchown(uv_fs_t* req) { + SET_REQ_RESULT(req, 0); +} + + +static void fs__statfs(uv_fs_t* req) { + uv_statfs_t* stat_fs; + DWORD sectors_per_cluster; + DWORD bytes_per_sector; + DWORD free_clusters; + DWORD total_clusters; + WCHAR* pathw; + + pathw = req->file.pathw; +retry_get_disk_free_space: + if (0 == GetDiskFreeSpaceW(pathw, + §ors_per_cluster, + &bytes_per_sector, + &free_clusters, + &total_clusters)) { + DWORD err; + WCHAR* fpart; + size_t len; + DWORD ret; + BOOL is_second; + + err = GetLastError(); + is_second = pathw != req->file.pathw; + if (err != ERROR_DIRECTORY || is_second) { + if (is_second) + uv__free(pathw); + + SET_REQ_WIN32_ERROR(req, err); + return; + } + + len = MAX_PATH + 1; + pathw = uv__malloc(len * sizeof(*pathw)); + if (pathw == NULL) { + SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); + return; + } +retry_get_full_path_name: + ret = GetFullPathNameW(req->file.pathw, + len, + pathw, + &fpart); + if (ret == 0) { + uv__free(pathw); + SET_REQ_WIN32_ERROR(req, err); + return; + } else if (ret > len) { + len = ret; + pathw = uv__reallocf(pathw, len * sizeof(*pathw)); + if (pathw == NULL) { + SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); + return; + } + goto retry_get_full_path_name; + } + if (fpart != 0) + *fpart = L'\0'; + + goto retry_get_disk_free_space; + } + if (pathw != req->file.pathw) { + uv__free(pathw); + } + + stat_fs = uv__malloc(sizeof(*stat_fs)); + if (stat_fs == NULL) { + SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); + return; + } + + stat_fs->f_type = 0; + stat_fs->f_bsize = bytes_per_sector * sectors_per_cluster; + stat_fs->f_blocks = total_clusters; + stat_fs->f_bfree = free_clusters; + stat_fs->f_bavail = free_clusters; + stat_fs->f_files = 0; + stat_fs->f_ffree = 0; + req->ptr = stat_fs; + req->flags |= UV_FS_FREE_PTR; + SET_REQ_RESULT(req, 0); +} + + +static void uv__fs_work(struct uv__work* w) { + uv_fs_t* req; + + req = container_of(w, uv_fs_t, work_req); + assert(req->type == UV_FS); + +#define XX(uc, lc) case UV_FS_##uc: fs__##lc(req); break; + switch (req->fs_type) { + XX(OPEN, open) + XX(CLOSE, close) + XX(READ, read) + XX(WRITE, write) + XX(COPYFILE, copyfile) + XX(SENDFILE, sendfile) + XX(STAT, stat) + XX(LSTAT, lstat) + XX(FSTAT, fstat) + XX(FTRUNCATE, ftruncate) + XX(UTIME, utime) + XX(FUTIME, futime) + XX(LUTIME, lutime) + XX(ACCESS, access) + XX(CHMOD, chmod) + XX(FCHMOD, fchmod) + XX(FSYNC, fsync) + XX(FDATASYNC, fdatasync) + XX(UNLINK, unlink) + XX(RMDIR, rmdir) + XX(MKDIR, mkdir) + XX(MKDTEMP, mkdtemp) + XX(MKSTEMP, mkstemp) + XX(RENAME, rename) + XX(SCANDIR, scandir) + XX(READDIR, readdir) + XX(OPENDIR, opendir) + XX(CLOSEDIR, closedir) + XX(LINK, link) + XX(SYMLINK, symlink) + XX(READLINK, readlink) + XX(REALPATH, realpath) + XX(CHOWN, chown) + XX(FCHOWN, fchown) + XX(LCHOWN, lchown) + XX(STATFS, statfs) + default: + assert(!"bad uv_fs_type"); + } +} + + +static void uv__fs_done(struct uv__work* w, int status) { + uv_fs_t* req; + + req = container_of(w, uv_fs_t, work_req); + uv__req_unregister(req->loop, req); + + if (status == UV_ECANCELED) { + assert(req->result == 0); + SET_REQ_UV_ERROR(req, UV_ECANCELED, 0); + } + + req->cb(req); +} + + +void uv_fs_req_cleanup(uv_fs_t* req) { + if (req == NULL) + return; + + if (req->flags & UV_FS_CLEANEDUP) + return; + + if (req->flags & UV_FS_FREE_PATHS) + uv__free(req->file.pathw); + + if (req->flags & UV_FS_FREE_PTR) { + if (req->fs_type == UV_FS_SCANDIR && req->ptr != NULL) + uv__fs_scandir_cleanup(req); + else if (req->fs_type == UV_FS_READDIR) + uv__fs_readdir_cleanup(req); + else + uv__free(req->ptr); + } + + if (req->fs.info.bufs != req->fs.info.bufsml) + uv__free(req->fs.info.bufs); + + req->path = NULL; + req->file.pathw = NULL; + req->fs.info.new_pathw = NULL; + req->fs.info.bufs = NULL; + req->ptr = NULL; + + req->flags |= UV_FS_CLEANEDUP; +} + + +int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, + int mode, uv_fs_cb cb) { + int err; + + INIT(UV_FS_OPEN); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + req->fs.info.file_flags = flags; + req->fs.info.mode = mode; + POST; +} + + +int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { + INIT(UV_FS_CLOSE); + req->file.fd = fd; + POST; +} + + +int uv_fs_read(uv_loop_t* loop, + uv_fs_t* req, + uv_file fd, + const uv_buf_t bufs[], + unsigned int nbufs, + int64_t offset, + uv_fs_cb cb) { + INIT(UV_FS_READ); + + if (bufs == NULL || nbufs == 0) { + SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER); + return UV_EINVAL; + } + + req->file.fd = fd; + + req->fs.info.nbufs = nbufs; + req->fs.info.bufs = req->fs.info.bufsml; + if (nbufs > ARRAY_SIZE(req->fs.info.bufsml)) + req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs)); + + if (req->fs.info.bufs == NULL) { + SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); + return UV_ENOMEM; + } + + memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs)); + + req->fs.info.offset = offset; + POST; +} + + +int uv_fs_write(uv_loop_t* loop, + uv_fs_t* req, + uv_file fd, + const uv_buf_t bufs[], + unsigned int nbufs, + int64_t offset, + uv_fs_cb cb) { + INIT(UV_FS_WRITE); + + if (bufs == NULL || nbufs == 0) { + SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER); + return UV_EINVAL; + } + + req->file.fd = fd; + + req->fs.info.nbufs = nbufs; + req->fs.info.bufs = req->fs.info.bufsml; + if (nbufs > ARRAY_SIZE(req->fs.info.bufsml)) + req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs)); + + if (req->fs.info.bufs == NULL) { + SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); + return UV_ENOMEM; + } + + memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs)); + + req->fs.info.offset = offset; + POST; +} + + +int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, + uv_fs_cb cb) { + int err; + + INIT(UV_FS_UNLINK); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + POST; +} + + +int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, + uv_fs_cb cb) { + int err; + + INIT(UV_FS_MKDIR); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + req->fs.info.mode = mode; + POST; +} + + +int uv_fs_mkdtemp(uv_loop_t* loop, + uv_fs_t* req, + const char* tpl, + uv_fs_cb cb) { + int err; + + INIT(UV_FS_MKDTEMP); + err = fs__capture_path(req, tpl, NULL, TRUE); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + POST; +} + + +int uv_fs_mkstemp(uv_loop_t* loop, + uv_fs_t* req, + const char* tpl, + uv_fs_cb cb) { + int err; + + INIT(UV_FS_MKSTEMP); + err = fs__capture_path(req, tpl, NULL, TRUE); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + POST; +} + + +int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { + int err; + + INIT(UV_FS_RMDIR); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + POST; +} + + +int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, + uv_fs_cb cb) { + int err; + + INIT(UV_FS_SCANDIR); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + req->fs.info.file_flags = flags; + POST; +} + +int uv_fs_opendir(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb) { + int err; + + INIT(UV_FS_OPENDIR); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + POST; +} + +int uv_fs_readdir(uv_loop_t* loop, + uv_fs_t* req, + uv_dir_t* dir, + uv_fs_cb cb) { + INIT(UV_FS_READDIR); + + if (dir == NULL || + dir->dirents == NULL || + dir->dir_handle == INVALID_HANDLE_VALUE) { + SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER); + return UV_EINVAL; + } + + req->ptr = dir; + POST; +} + +int uv_fs_closedir(uv_loop_t* loop, + uv_fs_t* req, + uv_dir_t* dir, + uv_fs_cb cb) { + INIT(UV_FS_CLOSEDIR); + if (dir == NULL) { + SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER); + return UV_EINVAL; + } + req->ptr = dir; + POST; +} + +int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, + const char* new_path, uv_fs_cb cb) { + int err; + + INIT(UV_FS_LINK); + err = fs__capture_path(req, path, new_path, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + POST; +} + + +int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, + const char* new_path, int flags, uv_fs_cb cb) { + int err; + + INIT(UV_FS_SYMLINK); + err = fs__capture_path(req, path, new_path, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + req->fs.info.file_flags = flags; + POST; +} + + +int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, + uv_fs_cb cb) { + int err; + + INIT(UV_FS_READLINK); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + POST; +} + + +int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path, + uv_fs_cb cb) { + int err; + + INIT(UV_FS_REALPATH); + + if (!path) { + SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER); + return UV_EINVAL; + } + + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + POST; +} + + +int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, + uv_gid_t gid, uv_fs_cb cb) { + int err; + + INIT(UV_FS_CHOWN); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + POST; +} + + +int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_uid_t uid, + uv_gid_t gid, uv_fs_cb cb) { + INIT(UV_FS_FCHOWN); + POST; +} + + +int uv_fs_lchown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, + uv_gid_t gid, uv_fs_cb cb) { + int err; + + INIT(UV_FS_LCHOWN); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + POST; +} + + +int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { + int err; + + INIT(UV_FS_STAT); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + POST; +} + + +int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { + int err; + + INIT(UV_FS_LSTAT); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + POST; +} + + +int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { + INIT(UV_FS_FSTAT); + req->file.fd = fd; + POST; +} + + +int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, + const char* new_path, uv_fs_cb cb) { + int err; + + INIT(UV_FS_RENAME); + err = fs__capture_path(req, path, new_path, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + POST; +} + + +int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { + INIT(UV_FS_FSYNC); + req->file.fd = fd; + POST; +} + + +int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { + INIT(UV_FS_FDATASYNC); + req->file.fd = fd; + POST; +} + + +int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file fd, + int64_t offset, uv_fs_cb cb) { + INIT(UV_FS_FTRUNCATE); + req->file.fd = fd; + req->fs.info.offset = offset; + POST; +} + + +int uv_fs_copyfile(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + const char* new_path, + int flags, + uv_fs_cb cb) { + int err; + + INIT(UV_FS_COPYFILE); + + if (flags & ~(UV_FS_COPYFILE_EXCL | + UV_FS_COPYFILE_FICLONE | + UV_FS_COPYFILE_FICLONE_FORCE)) { + SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER); + return UV_EINVAL; + } + + err = fs__capture_path(req, path, new_path, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + req->fs.info.file_flags = flags; + POST; +} + + +int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file fd_out, + uv_file fd_in, int64_t in_offset, size_t length, uv_fs_cb cb) { + INIT(UV_FS_SENDFILE); + req->file.fd = fd_in; + req->fs.info.fd_out = fd_out; + req->fs.info.offset = in_offset; + req->fs.info.bufsml[0].len = length; + POST; +} + + +int uv_fs_access(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + int flags, + uv_fs_cb cb) { + int err; + + INIT(UV_FS_ACCESS); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + req->fs.info.mode = flags; + POST; +} + + +int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, + uv_fs_cb cb) { + int err; + + INIT(UV_FS_CHMOD); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + req->fs.info.mode = mode; + POST; +} + + +int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file fd, int mode, + uv_fs_cb cb) { + INIT(UV_FS_FCHMOD); + req->file.fd = fd; + req->fs.info.mode = mode; + POST; +} + + +int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, + double mtime, uv_fs_cb cb) { + int err; + + INIT(UV_FS_UTIME); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + req->fs.time.atime = atime; + req->fs.time.mtime = mtime; + POST; +} + + +int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file fd, double atime, + double mtime, uv_fs_cb cb) { + INIT(UV_FS_FUTIME); + req->file.fd = fd; + req->fs.time.atime = atime; + req->fs.time.mtime = mtime; + POST; +} + +int uv_fs_lutime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, + double mtime, uv_fs_cb cb) { + int err; + + INIT(UV_FS_LUTIME); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + req->fs.time.atime = atime; + req->fs.time.mtime = mtime; + POST; +} + + +int uv_fs_statfs(uv_loop_t* loop, + uv_fs_t* req, + const char* path, + uv_fs_cb cb) { + int err; + + INIT(UV_FS_STATFS); + err = fs__capture_path(req, path, NULL, cb != NULL); + if (err) { + SET_REQ_WIN32_ERROR(req, err); + return req->result; + } + + POST; +} + +int uv_fs_get_system_error(const uv_fs_t* req) { + return req->sys_errno_; +} diff --git a/external/src/libuv/src/win/getaddrinfo.c b/external/src/libuv/src/win/getaddrinfo.c new file mode 100644 index 0000000..dfab860 --- /dev/null +++ b/external/src/libuv/src/win/getaddrinfo.c @@ -0,0 +1,463 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include + +#include "uv.h" +#include "internal.h" +#include "req-inl.h" +#include "idna.h" + +/* EAI_* constants. */ +#include + +/* Needed for ConvertInterfaceIndexToLuid and ConvertInterfaceLuidToNameA */ +#include + +int uv__getaddrinfo_translate_error(int sys_err) { + switch (sys_err) { + case 0: return 0; + case WSATRY_AGAIN: return UV_EAI_AGAIN; + case WSAEINVAL: return UV_EAI_BADFLAGS; + case WSANO_RECOVERY: return UV_EAI_FAIL; + case WSAEAFNOSUPPORT: return UV_EAI_FAMILY; + case WSA_NOT_ENOUGH_MEMORY: return UV_EAI_MEMORY; + case WSAHOST_NOT_FOUND: return UV_EAI_NONAME; + case WSATYPE_NOT_FOUND: return UV_EAI_SERVICE; + case WSAESOCKTNOSUPPORT: return UV_EAI_SOCKTYPE; + default: return uv_translate_sys_error(sys_err); + } +} + + +/* + * MinGW is missing this + */ +#if !defined(_MSC_VER) && !defined(__MINGW64_VERSION_MAJOR) + typedef struct addrinfoW { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + size_t ai_addrlen; + WCHAR* ai_canonname; + struct sockaddr* ai_addr; + struct addrinfoW* ai_next; + } ADDRINFOW, *PADDRINFOW; + + DECLSPEC_IMPORT int WSAAPI GetAddrInfoW(const WCHAR* node, + const WCHAR* service, + const ADDRINFOW* hints, + PADDRINFOW* result); + + DECLSPEC_IMPORT void WSAAPI FreeAddrInfoW(PADDRINFOW pAddrInfo); +#endif + + +/* Adjust size value to be multiple of 4. Use to keep pointer aligned. + * Do we need different versions of this for different architectures? */ +#define ALIGNED_SIZE(X) ((((X) + 3) >> 2) << 2) + +#ifndef NDIS_IF_MAX_STRING_SIZE +#define NDIS_IF_MAX_STRING_SIZE IF_MAX_STRING_SIZE +#endif + +static void uv__getaddrinfo_work(struct uv__work* w) { + uv_getaddrinfo_t* req; + struct addrinfoW* hints; + int err; + + req = container_of(w, uv_getaddrinfo_t, work_req); + hints = req->addrinfow; + req->addrinfow = NULL; + err = GetAddrInfoW(req->node, req->service, hints, &req->addrinfow); + req->retcode = uv__getaddrinfo_translate_error(err); +} + + +/* + * Called from uv_run when complete. Call user specified callback + * then free returned addrinfo + * Returned addrinfo strings are converted from UTF-16 to UTF-8. + * + * To minimize allocation we calculate total size required, + * and copy all structs and referenced strings into the one block. + * Each size calculation is adjusted to avoid unaligned pointers. + */ +static void uv__getaddrinfo_done(struct uv__work* w, int status) { + uv_getaddrinfo_t* req; + int addrinfo_len = 0; + int name_len = 0; + size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo)); + struct addrinfoW* addrinfow_ptr; + struct addrinfo* addrinfo_ptr; + char* alloc_ptr = NULL; + char* cur_ptr = NULL; + + req = container_of(w, uv_getaddrinfo_t, work_req); + + /* release input parameter memory */ + uv__free(req->alloc); + req->alloc = NULL; + + if (status == UV_ECANCELED) { + assert(req->retcode == 0); + req->retcode = UV_EAI_CANCELED; + goto complete; + } + + if (req->retcode == 0) { + /* Convert addrinfoW to addrinfo. First calculate required length. */ + addrinfow_ptr = req->addrinfow; + while (addrinfow_ptr != NULL) { + addrinfo_len += addrinfo_struct_len + + ALIGNED_SIZE(addrinfow_ptr->ai_addrlen); + if (addrinfow_ptr->ai_canonname != NULL) { + name_len = WideCharToMultiByte(CP_UTF8, + 0, + addrinfow_ptr->ai_canonname, + -1, + NULL, + 0, + NULL, + NULL); + if (name_len == 0) { + req->retcode = uv_translate_sys_error(GetLastError()); + goto complete; + } + addrinfo_len += ALIGNED_SIZE(name_len); + } + addrinfow_ptr = addrinfow_ptr->ai_next; + } + + /* allocate memory for addrinfo results */ + alloc_ptr = (char*)uv__malloc(addrinfo_len); + + /* do conversions */ + if (alloc_ptr != NULL) { + cur_ptr = alloc_ptr; + addrinfow_ptr = req->addrinfow; + + while (addrinfow_ptr != NULL) { + /* copy addrinfo struct data */ + assert(cur_ptr + addrinfo_struct_len <= alloc_ptr + addrinfo_len); + addrinfo_ptr = (struct addrinfo*)cur_ptr; + addrinfo_ptr->ai_family = addrinfow_ptr->ai_family; + addrinfo_ptr->ai_socktype = addrinfow_ptr->ai_socktype; + addrinfo_ptr->ai_protocol = addrinfow_ptr->ai_protocol; + addrinfo_ptr->ai_flags = addrinfow_ptr->ai_flags; + addrinfo_ptr->ai_addrlen = addrinfow_ptr->ai_addrlen; + addrinfo_ptr->ai_canonname = NULL; + addrinfo_ptr->ai_addr = NULL; + addrinfo_ptr->ai_next = NULL; + + cur_ptr += addrinfo_struct_len; + + /* copy sockaddr */ + if (addrinfo_ptr->ai_addrlen > 0) { + assert(cur_ptr + addrinfo_ptr->ai_addrlen <= + alloc_ptr + addrinfo_len); + memcpy(cur_ptr, addrinfow_ptr->ai_addr, addrinfo_ptr->ai_addrlen); + addrinfo_ptr->ai_addr = (struct sockaddr*)cur_ptr; + cur_ptr += ALIGNED_SIZE(addrinfo_ptr->ai_addrlen); + } + + /* convert canonical name to UTF-8 */ + if (addrinfow_ptr->ai_canonname != NULL) { + name_len = WideCharToMultiByte(CP_UTF8, + 0, + addrinfow_ptr->ai_canonname, + -1, + NULL, + 0, + NULL, + NULL); + assert(name_len > 0); + assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len); + name_len = WideCharToMultiByte(CP_UTF8, + 0, + addrinfow_ptr->ai_canonname, + -1, + cur_ptr, + name_len, + NULL, + NULL); + assert(name_len > 0); + addrinfo_ptr->ai_canonname = cur_ptr; + cur_ptr += ALIGNED_SIZE(name_len); + } + assert(cur_ptr <= alloc_ptr + addrinfo_len); + + /* set next ptr */ + addrinfow_ptr = addrinfow_ptr->ai_next; + if (addrinfow_ptr != NULL) { + addrinfo_ptr->ai_next = (struct addrinfo*)cur_ptr; + } + } + req->addrinfo = (struct addrinfo*)alloc_ptr; + } else { + req->retcode = UV_EAI_MEMORY; + } + } + + /* return memory to system */ + if (req->addrinfow != NULL) { + FreeAddrInfoW(req->addrinfow); + req->addrinfow = NULL; + } + +complete: + uv__req_unregister(req->loop, req); + + /* finally do callback with converted result */ + if (req->getaddrinfo_cb) + req->getaddrinfo_cb(req, req->retcode, req->addrinfo); +} + + +void uv_freeaddrinfo(struct addrinfo* ai) { + char* alloc_ptr = (char*)ai; + + /* release copied result memory */ + uv__free(alloc_ptr); +} + + +/* + * Entry point for getaddrinfo + * we convert the UTF-8 strings to UNICODE + * and save the UNICODE string pointers in the req + * We also copy hints so that caller does not need to keep memory until the + * callback. + * return 0 if a callback will be made + * return error code if validation fails + * + * To minimize allocation we calculate total size required, + * and copy all structs and referenced strings into the one block. + * Each size calculation is adjusted to avoid unaligned pointers. + */ +int uv_getaddrinfo(uv_loop_t* loop, + uv_getaddrinfo_t* req, + uv_getaddrinfo_cb getaddrinfo_cb, + const char* node, + const char* service, + const struct addrinfo* hints) { + char hostname_ascii[256]; + int nodesize = 0; + int servicesize = 0; + int hintssize = 0; + char* alloc_ptr = NULL; + int err; + long rc; + + if (req == NULL || (node == NULL && service == NULL)) { + return UV_EINVAL; + } + + UV_REQ_INIT(req, UV_GETADDRINFO); + req->getaddrinfo_cb = getaddrinfo_cb; + req->addrinfo = NULL; + req->loop = loop; + req->retcode = 0; + + /* calculate required memory size for all input values */ + if (node != NULL) { + rc = uv__idna_toascii(node, + node + strlen(node), + hostname_ascii, + hostname_ascii + sizeof(hostname_ascii)); + if (rc < 0) + return rc; + nodesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8, 0, hostname_ascii, + -1, NULL, 0) * sizeof(WCHAR)); + if (nodesize == 0) { + err = GetLastError(); + goto error; + } + node = hostname_ascii; + } + + if (service != NULL) { + servicesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8, + 0, + service, + -1, + NULL, + 0) * + sizeof(WCHAR)); + if (servicesize == 0) { + err = GetLastError(); + goto error; + } + } + if (hints != NULL) { + hintssize = ALIGNED_SIZE(sizeof(struct addrinfoW)); + } + + /* allocate memory for inputs, and partition it as needed */ + alloc_ptr = (char*)uv__malloc(nodesize + servicesize + hintssize); + if (!alloc_ptr) { + err = WSAENOBUFS; + goto error; + } + + /* save alloc_ptr now so we can free if error */ + req->alloc = (void*)alloc_ptr; + + /* Convert node string to UTF16 into allocated memory and save pointer in the + * request. */ + if (node != NULL) { + req->node = (WCHAR*)alloc_ptr; + if (MultiByteToWideChar(CP_UTF8, + 0, + node, + -1, + (WCHAR*) alloc_ptr, + nodesize / sizeof(WCHAR)) == 0) { + err = GetLastError(); + goto error; + } + alloc_ptr += nodesize; + } else { + req->node = NULL; + } + + /* Convert service string to UTF16 into allocated memory and save pointer in + * the req. */ + if (service != NULL) { + req->service = (WCHAR*)alloc_ptr; + if (MultiByteToWideChar(CP_UTF8, + 0, + service, + -1, + (WCHAR*) alloc_ptr, + servicesize / sizeof(WCHAR)) == 0) { + err = GetLastError(); + goto error; + } + alloc_ptr += servicesize; + } else { + req->service = NULL; + } + + /* copy hints to allocated memory and save pointer in req */ + if (hints != NULL) { + req->addrinfow = (struct addrinfoW*)alloc_ptr; + req->addrinfow->ai_family = hints->ai_family; + req->addrinfow->ai_socktype = hints->ai_socktype; + req->addrinfow->ai_protocol = hints->ai_protocol; + req->addrinfow->ai_flags = hints->ai_flags; + req->addrinfow->ai_addrlen = 0; + req->addrinfow->ai_canonname = NULL; + req->addrinfow->ai_addr = NULL; + req->addrinfow->ai_next = NULL; + } else { + req->addrinfow = NULL; + } + + uv__req_register(loop, req); + + if (getaddrinfo_cb) { + uv__work_submit(loop, + &req->work_req, + UV__WORK_SLOW_IO, + uv__getaddrinfo_work, + uv__getaddrinfo_done); + return 0; + } else { + uv__getaddrinfo_work(&req->work_req); + uv__getaddrinfo_done(&req->work_req, 0); + return req->retcode; + } + +error: + if (req != NULL) { + uv__free(req->alloc); + req->alloc = NULL; + } + return uv_translate_sys_error(err); +} + +int uv_if_indextoname(unsigned int ifindex, char* buffer, size_t* size) { + NET_LUID luid; + wchar_t wname[NDIS_IF_MAX_STRING_SIZE + 1]; /* Add one for the NUL. */ + DWORD bufsize; + int r; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + r = ConvertInterfaceIndexToLuid(ifindex, &luid); + + if (r != 0) + return uv_translate_sys_error(r); + + r = ConvertInterfaceLuidToNameW(&luid, wname, ARRAY_SIZE(wname)); + + if (r != 0) + return uv_translate_sys_error(r); + + /* Check how much space we need */ + bufsize = WideCharToMultiByte(CP_UTF8, 0, wname, -1, NULL, 0, NULL, NULL); + + if (bufsize == 0) { + return uv_translate_sys_error(GetLastError()); + } else if (bufsize > *size) { + *size = bufsize; + return UV_ENOBUFS; + } + + /* Convert to UTF-8 */ + bufsize = WideCharToMultiByte(CP_UTF8, + 0, + wname, + -1, + buffer, + *size, + NULL, + NULL); + + if (bufsize == 0) + return uv_translate_sys_error(GetLastError()); + + *size = bufsize - 1; + return 0; +} + +int uv_if_indextoiid(unsigned int ifindex, char* buffer, size_t* size) { + int r; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + r = snprintf(buffer, *size, "%d", ifindex); + + if (r < 0) + return uv_translate_sys_error(r); + + if (r >= (int) *size) { + *size = r + 1; + return UV_ENOBUFS; + } + + *size = r; + return 0; +} diff --git a/external/src/libuv/src/win/getnameinfo.c b/external/src/libuv/src/win/getnameinfo.c new file mode 100644 index 0000000..b377338 --- /dev/null +++ b/external/src/libuv/src/win/getnameinfo.c @@ -0,0 +1,157 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +*/ + +#include +#include + +#include "uv.h" +#include "internal.h" +#include "req-inl.h" + +#ifndef GetNameInfo +int WSAAPI GetNameInfoW( + const SOCKADDR *pSockaddr, + socklen_t SockaddrLength, + PWCHAR pNodeBuffer, + DWORD NodeBufferSize, + PWCHAR pServiceBuffer, + DWORD ServiceBufferSize, + INT Flags +); +#endif + +static void uv__getnameinfo_work(struct uv__work* w) { + uv_getnameinfo_t* req; + WCHAR host[NI_MAXHOST]; + WCHAR service[NI_MAXSERV]; + int ret; + + req = container_of(w, uv_getnameinfo_t, work_req); + if (GetNameInfoW((struct sockaddr*)&req->storage, + sizeof(req->storage), + host, + ARRAY_SIZE(host), + service, + ARRAY_SIZE(service), + req->flags)) { + ret = WSAGetLastError(); + req->retcode = uv__getaddrinfo_translate_error(ret); + return; + } + + ret = WideCharToMultiByte(CP_UTF8, + 0, + host, + -1, + req->host, + sizeof(req->host), + NULL, + NULL); + if (ret == 0) { + req->retcode = uv_translate_sys_error(GetLastError()); + return; + } + + ret = WideCharToMultiByte(CP_UTF8, + 0, + service, + -1, + req->service, + sizeof(req->service), + NULL, + NULL); + if (ret == 0) { + req->retcode = uv_translate_sys_error(GetLastError()); + } +} + + +/* +* Called from uv_run when complete. +*/ +static void uv__getnameinfo_done(struct uv__work* w, int status) { + uv_getnameinfo_t* req; + char* host; + char* service; + + req = container_of(w, uv_getnameinfo_t, work_req); + uv__req_unregister(req->loop, req); + host = service = NULL; + + if (status == UV_ECANCELED) { + assert(req->retcode == 0); + req->retcode = UV_EAI_CANCELED; + } else if (req->retcode == 0) { + host = req->host; + service = req->service; + } + + if (req->getnameinfo_cb) + req->getnameinfo_cb(req, req->retcode, host, service); +} + + +/* +* Entry point for getnameinfo +* return 0 if a callback will be made +* return error code if validation fails +*/ +int uv_getnameinfo(uv_loop_t* loop, + uv_getnameinfo_t* req, + uv_getnameinfo_cb getnameinfo_cb, + const struct sockaddr* addr, + int flags) { + if (req == NULL || addr == NULL) + return UV_EINVAL; + + if (addr->sa_family == AF_INET) { + memcpy(&req->storage, + addr, + sizeof(struct sockaddr_in)); + } else if (addr->sa_family == AF_INET6) { + memcpy(&req->storage, + addr, + sizeof(struct sockaddr_in6)); + } else { + return UV_EINVAL; + } + + UV_REQ_INIT(req, UV_GETNAMEINFO); + uv__req_register(loop, req); + + req->getnameinfo_cb = getnameinfo_cb; + req->flags = flags; + req->loop = loop; + req->retcode = 0; + + if (getnameinfo_cb) { + uv__work_submit(loop, + &req->work_req, + UV__WORK_SLOW_IO, + uv__getnameinfo_work, + uv__getnameinfo_done); + return 0; + } else { + uv__getnameinfo_work(&req->work_req); + uv__getnameinfo_done(&req->work_req, 0); + return req->retcode; + } +} diff --git a/external/src/libuv/src/win/handle-inl.h b/external/src/libuv/src/win/handle-inl.h new file mode 100644 index 0000000..82c657d --- /dev/null +++ b/external/src/libuv/src/win/handle-inl.h @@ -0,0 +1,180 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_WIN_HANDLE_INL_H_ +#define UV_WIN_HANDLE_INL_H_ + +#include +#include + +#include "uv.h" +#include "internal.h" + + +#define DECREASE_ACTIVE_COUNT(loop, handle) \ + do { \ + if (--(handle)->activecnt == 0 && \ + !((handle)->flags & UV_HANDLE_CLOSING)) { \ + uv__handle_stop((handle)); \ + } \ + assert((handle)->activecnt >= 0); \ + } while (0) + + +#define INCREASE_ACTIVE_COUNT(loop, handle) \ + do { \ + if ((handle)->activecnt++ == 0) { \ + uv__handle_start((handle)); \ + } \ + assert((handle)->activecnt > 0); \ + } while (0) + + +#define DECREASE_PENDING_REQ_COUNT(handle) \ + do { \ + assert(handle->reqs_pending > 0); \ + handle->reqs_pending--; \ + \ + if (handle->flags & UV_HANDLE_CLOSING && \ + handle->reqs_pending == 0) { \ + uv_want_endgame(loop, (uv_handle_t*)handle); \ + } \ + } while (0) + + +#define uv__handle_closing(handle) \ + do { \ + assert(!((handle)->flags & UV_HANDLE_CLOSING)); \ + \ + if (!(((handle)->flags & UV_HANDLE_ACTIVE) && \ + ((handle)->flags & UV_HANDLE_REF))) \ + uv__active_handle_add((uv_handle_t*) (handle)); \ + \ + (handle)->flags |= UV_HANDLE_CLOSING; \ + (handle)->flags &= ~UV_HANDLE_ACTIVE; \ + } while (0) + + +#define uv__handle_close(handle) \ + do { \ + QUEUE_REMOVE(&(handle)->handle_queue); \ + uv__active_handle_rm((uv_handle_t*) (handle)); \ + \ + (handle)->flags |= UV_HANDLE_CLOSED; \ + \ + if ((handle)->close_cb) \ + (handle)->close_cb((uv_handle_t*) (handle)); \ + } while (0) + + +INLINE static void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle) { + if (!(handle->flags & UV_HANDLE_ENDGAME_QUEUED)) { + handle->flags |= UV_HANDLE_ENDGAME_QUEUED; + + handle->endgame_next = loop->endgame_handles; + loop->endgame_handles = handle; + } +} + + +INLINE static void uv_process_endgames(uv_loop_t* loop) { + uv_handle_t* handle; + + while (loop->endgame_handles) { + handle = loop->endgame_handles; + loop->endgame_handles = handle->endgame_next; + + handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED; + + switch (handle->type) { + case UV_TCP: + uv_tcp_endgame(loop, (uv_tcp_t*) handle); + break; + + case UV_NAMED_PIPE: + uv_pipe_endgame(loop, (uv_pipe_t*) handle); + break; + + case UV_TTY: + uv_tty_endgame(loop, (uv_tty_t*) handle); + break; + + case UV_UDP: + uv_udp_endgame(loop, (uv_udp_t*) handle); + break; + + case UV_POLL: + uv_poll_endgame(loop, (uv_poll_t*) handle); + break; + + case UV_TIMER: + uv__timer_close((uv_timer_t*) handle); + uv__handle_close(handle); + break; + + case UV_PREPARE: + case UV_CHECK: + case UV_IDLE: + uv_loop_watcher_endgame(loop, handle); + break; + + case UV_ASYNC: + uv_async_endgame(loop, (uv_async_t*) handle); + break; + + case UV_SIGNAL: + uv_signal_endgame(loop, (uv_signal_t*) handle); + break; + + case UV_PROCESS: + uv_process_endgame(loop, (uv_process_t*) handle); + break; + + case UV_FS_EVENT: + uv_fs_event_endgame(loop, (uv_fs_event_t*) handle); + break; + + case UV_FS_POLL: + uv__fs_poll_endgame(loop, (uv_fs_poll_t*) handle); + break; + + default: + assert(0); + break; + } + } +} + +INLINE static HANDLE uv__get_osfhandle(int fd) +{ + /* _get_osfhandle() raises an assert in debug builds if the FD is invalid. + * But it also correctly checks the FD and returns INVALID_HANDLE_VALUE for + * invalid FDs in release builds (or if you let the assert continue). So this + * wrapper function disables asserts when calling _get_osfhandle. */ + + HANDLE handle; + UV_BEGIN_DISABLE_CRT_ASSERT(); + handle = (HANDLE) _get_osfhandle(fd); + UV_END_DISABLE_CRT_ASSERT(); + return handle; +} + +#endif /* UV_WIN_HANDLE_INL_H_ */ diff --git a/external/src/libuv/src/win/handle.c b/external/src/libuv/src/win/handle.c new file mode 100644 index 0000000..61e4df6 --- /dev/null +++ b/external/src/libuv/src/win/handle.c @@ -0,0 +1,162 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "uv.h" +#include "internal.h" +#include "handle-inl.h" + + +uv_handle_type uv_guess_handle(uv_file file) { + HANDLE handle; + DWORD mode; + + if (file < 0) { + return UV_UNKNOWN_HANDLE; + } + + handle = uv__get_osfhandle(file); + + switch (GetFileType(handle)) { + case FILE_TYPE_CHAR: + if (GetConsoleMode(handle, &mode)) { + return UV_TTY; + } else { + return UV_FILE; + } + + case FILE_TYPE_PIPE: + return UV_NAMED_PIPE; + + case FILE_TYPE_DISK: + return UV_FILE; + + default: + return UV_UNKNOWN_HANDLE; + } +} + + +int uv_is_active(const uv_handle_t* handle) { + return (handle->flags & UV_HANDLE_ACTIVE) && + !(handle->flags & UV_HANDLE_CLOSING); +} + + +void uv_close(uv_handle_t* handle, uv_close_cb cb) { + uv_loop_t* loop = handle->loop; + + if (handle->flags & UV_HANDLE_CLOSING) { + assert(0); + return; + } + + handle->close_cb = cb; + + /* Handle-specific close actions */ + switch (handle->type) { + case UV_TCP: + uv_tcp_close(loop, (uv_tcp_t*)handle); + return; + + case UV_NAMED_PIPE: + uv_pipe_close(loop, (uv_pipe_t*) handle); + return; + + case UV_TTY: + uv_tty_close((uv_tty_t*) handle); + return; + + case UV_UDP: + uv_udp_close(loop, (uv_udp_t*) handle); + return; + + case UV_POLL: + uv_poll_close(loop, (uv_poll_t*) handle); + return; + + case UV_TIMER: + uv_timer_stop((uv_timer_t*)handle); + uv__handle_closing(handle); + uv_want_endgame(loop, handle); + return; + + case UV_PREPARE: + uv_prepare_stop((uv_prepare_t*)handle); + uv__handle_closing(handle); + uv_want_endgame(loop, handle); + return; + + case UV_CHECK: + uv_check_stop((uv_check_t*)handle); + uv__handle_closing(handle); + uv_want_endgame(loop, handle); + return; + + case UV_IDLE: + uv_idle_stop((uv_idle_t*)handle); + uv__handle_closing(handle); + uv_want_endgame(loop, handle); + return; + + case UV_ASYNC: + uv_async_close(loop, (uv_async_t*) handle); + return; + + case UV_SIGNAL: + uv_signal_close(loop, (uv_signal_t*) handle); + return; + + case UV_PROCESS: + uv_process_close(loop, (uv_process_t*) handle); + return; + + case UV_FS_EVENT: + uv_fs_event_close(loop, (uv_fs_event_t*) handle); + return; + + case UV_FS_POLL: + uv__fs_poll_close((uv_fs_poll_t*) handle); + uv__handle_closing(handle); + return; + + default: + /* Not supported */ + abort(); + } +} + + +int uv_is_closing(const uv_handle_t* handle) { + return !!(handle->flags & (UV_HANDLE_CLOSING | UV_HANDLE_CLOSED)); +} + + +uv_os_fd_t uv_get_osfhandle(int fd) { + return uv__get_osfhandle(fd); +} + +int uv_open_osfhandle(uv_os_fd_t os_fd) { + return _open_osfhandle((intptr_t) os_fd, 0); +} diff --git a/external/src/libuv/src/win/internal.h b/external/src/libuv/src/win/internal.h new file mode 100644 index 0000000..b1b25b4 --- /dev/null +++ b/external/src/libuv/src/win/internal.h @@ -0,0 +1,344 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_WIN_INTERNAL_H_ +#define UV_WIN_INTERNAL_H_ + +#include "uv.h" +#include "../uv-common.h" + +#include "uv/tree.h" +#include "winapi.h" +#include "winsock.h" + +#ifdef _MSC_VER +# define INLINE __inline +# define UV_THREAD_LOCAL __declspec( thread ) +#else +# define INLINE inline +# define UV_THREAD_LOCAL __thread +#endif + + +#ifdef _DEBUG + +extern UV_THREAD_LOCAL int uv__crt_assert_enabled; + +#define UV_BEGIN_DISABLE_CRT_ASSERT() \ + { \ + int uv__saved_crt_assert_enabled = uv__crt_assert_enabled; \ + uv__crt_assert_enabled = FALSE; + + +#define UV_END_DISABLE_CRT_ASSERT() \ + uv__crt_assert_enabled = uv__saved_crt_assert_enabled; \ + } + +#else +#define UV_BEGIN_DISABLE_CRT_ASSERT() +#define UV_END_DISABLE_CRT_ASSERT() +#endif + +/* + * TCP + */ + +typedef enum { + UV__IPC_SOCKET_XFER_NONE = 0, + UV__IPC_SOCKET_XFER_TCP_CONNECTION, + UV__IPC_SOCKET_XFER_TCP_SERVER +} uv__ipc_socket_xfer_type_t; + +typedef struct { + WSAPROTOCOL_INFOW socket_info; + uint32_t delayed_error; +} uv__ipc_socket_xfer_info_t; + +int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb); +int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client); +int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, + uv_read_cb read_cb); +int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle, + const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb); +int uv__tcp_try_write(uv_tcp_t* handle, const uv_buf_t bufs[], + unsigned int nbufs); + +void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, uv_req_t* req); +void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle, + uv_write_t* req); +void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle, + uv_req_t* req); +void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle, + uv_connect_t* req); + +void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp); +void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle); + +int uv__tcp_xfer_export(uv_tcp_t* handle, + int pid, + uv__ipc_socket_xfer_type_t* xfer_type, + uv__ipc_socket_xfer_info_t* xfer_info); +int uv__tcp_xfer_import(uv_tcp_t* tcp, + uv__ipc_socket_xfer_type_t xfer_type, + uv__ipc_socket_xfer_info_t* xfer_info); + + +/* + * UDP + */ +void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, uv_req_t* req); +void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle, + uv_udp_send_t* req); + +void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle); +void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle); + + +/* + * Pipes + */ +int uv__create_stdio_pipe_pair(uv_loop_t* loop, + uv_pipe_t* parent_pipe, HANDLE* child_pipe_ptr, unsigned int flags); + +int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb); +int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client); +int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, + uv_read_cb read_cb); +void uv__pipe_read_stop(uv_pipe_t* handle); +int uv__pipe_write(uv_loop_t* loop, + uv_write_t* req, + uv_pipe_t* handle, + const uv_buf_t bufs[], + size_t nbufs, + uv_stream_t* send_handle, + uv_write_cb cb); + +void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle, + uv_req_t* req); +void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle, + uv_write_t* req); +void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle, + uv_req_t* raw_req); +void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle, + uv_connect_t* req); +void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle, + uv_shutdown_t* req); + +void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle); +void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle); +void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle); + + +/* + * TTY + */ +void uv_console_init(void); + +int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb, + uv_read_cb read_cb); +int uv_tty_read_stop(uv_tty_t* handle); +int uv_tty_write(uv_loop_t* loop, uv_write_t* req, uv_tty_t* handle, + const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb); +int uv__tty_try_write(uv_tty_t* handle, const uv_buf_t bufs[], + unsigned int nbufs); +void uv_tty_close(uv_tty_t* handle); + +void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle, + uv_req_t* req); +void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle, + uv_write_t* req); +/* + * uv_process_tty_accept_req() is a stub to keep DELEGATE_STREAM_REQ working + * TODO: find a way to remove it + */ +void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle, + uv_req_t* raw_req); +/* + * uv_process_tty_connect_req() is a stub to keep DELEGATE_STREAM_REQ working + * TODO: find a way to remove it + */ +void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle, + uv_connect_t* req); + +void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle); + + +/* + * Poll watchers + */ +void uv_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, + uv_req_t* req); + +int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle); +void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle); + + +/* + * Loop watchers + */ +void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle); + +void uv_prepare_invoke(uv_loop_t* loop); +void uv_check_invoke(uv_loop_t* loop); +void uv_idle_invoke(uv_loop_t* loop); + +void uv__once_init(void); + + +/* + * Async watcher + */ +void uv_async_close(uv_loop_t* loop, uv_async_t* handle); +void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle); + +void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle, + uv_req_t* req); + + +/* + * Signal watcher + */ +void uv_signals_init(void); +int uv__signal_dispatch(int signum); + +void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle); +void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle); + +void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle, + uv_req_t* req); + + +/* + * Spawn + */ +void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle); +void uv_process_close(uv_loop_t* loop, uv_process_t* handle); +void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle); + + +/* + * Error + */ +int uv_translate_sys_error(int sys_errno); + + +/* + * FS + */ +void uv_fs_init(void); + + +/* + * FS Event + */ +void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req, + uv_fs_event_t* handle); +void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle); +void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle); + + +/* + * Stat poller. + */ +void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle); + + +/* + * Utilities. + */ +void uv__util_init(void); + +uint64_t uv__hrtime(unsigned int scale); +__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall); +int uv__getpwuid_r(uv_passwd_t* pwd); +int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8); +int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16); + +typedef int (WINAPI *uv__peersockfunc)(SOCKET, struct sockaddr*, int*); + +int uv__getsockpeername(const uv_handle_t* handle, + uv__peersockfunc func, + struct sockaddr* name, + int* namelen, + int delayed_error); + +int uv__random_rtlgenrandom(void* buf, size_t buflen); + + +/* + * Process stdio handles. + */ +int uv__stdio_create(uv_loop_t* loop, + const uv_process_options_t* options, + BYTE** buffer_ptr); +void uv__stdio_destroy(BYTE* buffer); +void uv__stdio_noinherit(BYTE* buffer); +int uv__stdio_verify(BYTE* buffer, WORD size); +WORD uv__stdio_size(BYTE* buffer); +HANDLE uv__stdio_handle(BYTE* buffer, int fd); + + +/* + * Winapi and ntapi utility functions + */ +void uv_winapi_init(void); + + +/* + * Winsock utility functions + */ +void uv_winsock_init(void); + +int uv_ntstatus_to_winsock_error(NTSTATUS status); + +BOOL uv_get_acceptex_function(SOCKET socket, LPFN_ACCEPTEX* target); +BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target); + +int WSAAPI uv_wsarecv_workaround(SOCKET socket, WSABUF* buffers, + DWORD buffer_count, DWORD* bytes, DWORD* flags, WSAOVERLAPPED *overlapped, + LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine); +int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers, + DWORD buffer_count, DWORD* bytes, DWORD* flags, struct sockaddr* addr, + int* addr_len, WSAOVERLAPPED *overlapped, + LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine); + +int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in, + AFD_POLL_INFO* info_out, OVERLAPPED* overlapped); + +/* Whether there are any non-IFS LSPs stacked on TCP */ +extern int uv_tcp_non_ifs_lsp_ipv4; +extern int uv_tcp_non_ifs_lsp_ipv6; + +/* Ip address used to bind to any port at any interface */ +extern struct sockaddr_in uv_addr_ip4_any_; +extern struct sockaddr_in6 uv_addr_ip6_any_; + +/* + * Wake all loops with fake message + */ +void uv__wake_all_loops(void); + +/* + * Init system wake-up detection + */ +void uv__init_detect_system_wakeup(void); + +#endif /* UV_WIN_INTERNAL_H_ */ diff --git a/external/src/libuv/src/win/loop-watcher.c b/external/src/libuv/src/win/loop-watcher.c new file mode 100644 index 0000000..ad7fbea --- /dev/null +++ b/external/src/libuv/src/win/loop-watcher.c @@ -0,0 +1,122 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include + +#include "uv.h" +#include "internal.h" +#include "handle-inl.h" + + +void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) { + if (handle->flags & UV_HANDLE_CLOSING) { + assert(!(handle->flags & UV_HANDLE_CLOSED)); + handle->flags |= UV_HANDLE_CLOSED; + uv__handle_close(handle); + } +} + + +#define UV_LOOP_WATCHER_DEFINE(name, NAME) \ + int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \ + uv__handle_init(loop, (uv_handle_t*) handle, UV_##NAME); \ + \ + return 0; \ + } \ + \ + \ + int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \ + uv_loop_t* loop = handle->loop; \ + uv_##name##_t* old_head; \ + \ + assert(handle->type == UV_##NAME); \ + \ + if (uv__is_active(handle)) \ + return 0; \ + \ + if (cb == NULL) \ + return UV_EINVAL; \ + \ + old_head = loop->name##_handles; \ + \ + handle->name##_next = old_head; \ + handle->name##_prev = NULL; \ + \ + if (old_head) { \ + old_head->name##_prev = handle; \ + } \ + \ + loop->name##_handles = handle; \ + \ + handle->name##_cb = cb; \ + uv__handle_start(handle); \ + \ + return 0; \ + } \ + \ + \ + int uv_##name##_stop(uv_##name##_t* handle) { \ + uv_loop_t* loop = handle->loop; \ + \ + assert(handle->type == UV_##NAME); \ + \ + if (!uv__is_active(handle)) \ + return 0; \ + \ + /* Update loop head if needed */ \ + if (loop->name##_handles == handle) { \ + loop->name##_handles = handle->name##_next; \ + } \ + \ + /* Update the iterator-next pointer of needed */ \ + if (loop->next_##name##_handle == handle) { \ + loop->next_##name##_handle = handle->name##_next; \ + } \ + \ + if (handle->name##_prev) { \ + handle->name##_prev->name##_next = handle->name##_next; \ + } \ + if (handle->name##_next) { \ + handle->name##_next->name##_prev = handle->name##_prev; \ + } \ + \ + uv__handle_stop(handle); \ + \ + return 0; \ + } \ + \ + \ + void uv_##name##_invoke(uv_loop_t* loop) { \ + uv_##name##_t* handle; \ + \ + (loop)->next_##name##_handle = (loop)->name##_handles; \ + \ + while ((loop)->next_##name##_handle != NULL) { \ + handle = (loop)->next_##name##_handle; \ + (loop)->next_##name##_handle = handle->name##_next; \ + \ + handle->name##_cb(handle); \ + } \ + } + +UV_LOOP_WATCHER_DEFINE(prepare, PREPARE) +UV_LOOP_WATCHER_DEFINE(check, CHECK) +UV_LOOP_WATCHER_DEFINE(idle, IDLE) diff --git a/external/src/libuv/src/win/pipe.c b/external/src/libuv/src/win/pipe.c new file mode 100644 index 0000000..88ba99b --- /dev/null +++ b/external/src/libuv/src/win/pipe.c @@ -0,0 +1,2591 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "handle-inl.h" +#include "internal.h" +#include "req-inl.h" +#include "stream-inl.h" +#include "uv-common.h" +#include "uv.h" + +#include +#include + +/* A zero-size buffer for use by uv_pipe_read */ +static char uv_zero_[] = ""; + +/* Null uv_buf_t */ +static const uv_buf_t uv_null_buf_ = { 0, NULL }; + +/* The timeout that the pipe will wait for the remote end to write data when + * the local ends wants to shut it down. */ +static const int64_t eof_timeout = 50; /* ms */ + +static const int default_pending_pipe_instances = 4; + +/* Pipe prefix */ +static char pipe_prefix[] = "\\\\?\\pipe"; +static const int pipe_prefix_len = sizeof(pipe_prefix) - 1; + +/* IPC incoming xfer queue item. */ +typedef struct { + uv__ipc_socket_xfer_type_t xfer_type; + uv__ipc_socket_xfer_info_t xfer_info; + QUEUE member; +} uv__ipc_xfer_queue_item_t; + +/* IPC frame header flags. */ +/* clang-format off */ +enum { + UV__IPC_FRAME_HAS_DATA = 0x01, + UV__IPC_FRAME_HAS_SOCKET_XFER = 0x02, + UV__IPC_FRAME_XFER_IS_TCP_CONNECTION = 0x04, + /* These are combinations of the flags above. */ + UV__IPC_FRAME_XFER_FLAGS = 0x06, + UV__IPC_FRAME_VALID_FLAGS = 0x07 +}; +/* clang-format on */ + +/* IPC frame header. */ +typedef struct { + uint32_t flags; + uint32_t reserved1; /* Ignored. */ + uint32_t data_length; /* Must be zero if there is no data. */ + uint32_t reserved2; /* Must be zero. */ +} uv__ipc_frame_header_t; + +/* To implement the IPC protocol correctly, these structures must have exactly + * the right size. */ +STATIC_ASSERT(sizeof(uv__ipc_frame_header_t) == 16); +STATIC_ASSERT(sizeof(uv__ipc_socket_xfer_info_t) == 632); + +/* Coalesced write request. */ +typedef struct { + uv_write_t req; /* Internal heap-allocated write request. */ + uv_write_t* user_req; /* Pointer to user-specified uv_write_t. */ +} uv__coalesced_write_t; + + +static void eof_timer_init(uv_pipe_t* pipe); +static void eof_timer_start(uv_pipe_t* pipe); +static void eof_timer_stop(uv_pipe_t* pipe); +static void eof_timer_cb(uv_timer_t* timer); +static void eof_timer_destroy(uv_pipe_t* pipe); +static void eof_timer_close_cb(uv_handle_t* handle); + + +static void uv_unique_pipe_name(char* ptr, char* name, size_t size) { + snprintf(name, size, "\\\\?\\pipe\\uv\\%p-%lu", ptr, GetCurrentProcessId()); +} + + +int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) { + uv_stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE); + + handle->reqs_pending = 0; + handle->handle = INVALID_HANDLE_VALUE; + handle->name = NULL; + handle->pipe.conn.ipc_remote_pid = 0; + handle->pipe.conn.ipc_data_frame.payload_remaining = 0; + QUEUE_INIT(&handle->pipe.conn.ipc_xfer_queue); + handle->pipe.conn.ipc_xfer_queue_length = 0; + handle->ipc = ipc; + handle->pipe.conn.non_overlapped_writes_tail = NULL; + + return 0; +} + + +static void uv_pipe_connection_init(uv_pipe_t* handle) { + uv_connection_init((uv_stream_t*) handle); + handle->read_req.data = handle; + handle->pipe.conn.eof_timer = NULL; + assert(!(handle->flags & UV_HANDLE_PIPESERVER)); + if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) { + handle->pipe.conn.readfile_thread_handle = NULL; + InitializeCriticalSection(&handle->pipe.conn.readfile_thread_lock); + } +} + + +static HANDLE open_named_pipe(const WCHAR* name, DWORD* duplex_flags) { + HANDLE pipeHandle; + + /* + * Assume that we have a duplex pipe first, so attempt to + * connect with GENERIC_READ | GENERIC_WRITE. + */ + pipeHandle = CreateFileW(name, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); + if (pipeHandle != INVALID_HANDLE_VALUE) { + *duplex_flags = UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; + return pipeHandle; + } + + /* + * If the pipe is not duplex CreateFileW fails with + * ERROR_ACCESS_DENIED. In that case try to connect + * as a read-only or write-only. + */ + if (GetLastError() == ERROR_ACCESS_DENIED) { + pipeHandle = CreateFileW(name, + GENERIC_READ | FILE_WRITE_ATTRIBUTES, + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); + + if (pipeHandle != INVALID_HANDLE_VALUE) { + *duplex_flags = UV_HANDLE_READABLE; + return pipeHandle; + } + } + + if (GetLastError() == ERROR_ACCESS_DENIED) { + pipeHandle = CreateFileW(name, + GENERIC_WRITE | FILE_READ_ATTRIBUTES, + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); + + if (pipeHandle != INVALID_HANDLE_VALUE) { + *duplex_flags = UV_HANDLE_WRITABLE; + return pipeHandle; + } + } + + return INVALID_HANDLE_VALUE; +} + + +static void close_pipe(uv_pipe_t* pipe) { + assert(pipe->u.fd == -1 || pipe->u.fd > 2); + if (pipe->u.fd == -1) + CloseHandle(pipe->handle); + else + close(pipe->u.fd); + + pipe->u.fd = -1; + pipe->handle = INVALID_HANDLE_VALUE; +} + + +static int uv__pipe_server( + HANDLE* pipeHandle_ptr, DWORD access, + char* name, size_t nameSize, char* random) { + HANDLE pipeHandle; + int err; + + for (;;) { + uv_unique_pipe_name(random, name, nameSize); + + pipeHandle = CreateNamedPipeA(name, + access | FILE_FLAG_FIRST_PIPE_INSTANCE, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 65536, 65536, 0, + NULL); + + if (pipeHandle != INVALID_HANDLE_VALUE) { + /* No name collisions. We're done. */ + break; + } + + err = GetLastError(); + if (err != ERROR_PIPE_BUSY && err != ERROR_ACCESS_DENIED) { + goto error; + } + + /* Pipe name collision. Increment the random number and try again. */ + random++; + } + + *pipeHandle_ptr = pipeHandle; + + return 0; + + error: + if (pipeHandle != INVALID_HANDLE_VALUE) + CloseHandle(pipeHandle); + + return err; +} + + +static int uv__create_pipe_pair( + HANDLE* server_pipe_ptr, HANDLE* client_pipe_ptr, + unsigned int server_flags, unsigned int client_flags, + int inherit_client, char* random) { + /* allowed flags are: UV_READABLE_PIPE | UV_WRITABLE_PIPE | UV_NONBLOCK_PIPE */ + char pipe_name[64]; + SECURITY_ATTRIBUTES sa; + DWORD server_access; + DWORD client_access; + HANDLE server_pipe; + HANDLE client_pipe; + int err; + + server_pipe = INVALID_HANDLE_VALUE; + client_pipe = INVALID_HANDLE_VALUE; + + server_access = 0; + if (server_flags & UV_READABLE_PIPE) + server_access |= PIPE_ACCESS_INBOUND; + if (server_flags & UV_WRITABLE_PIPE) + server_access |= PIPE_ACCESS_OUTBOUND; + if (server_flags & UV_NONBLOCK_PIPE) + server_access |= FILE_FLAG_OVERLAPPED; + server_access |= WRITE_DAC; + + client_access = 0; + if (client_flags & UV_READABLE_PIPE) + client_access |= GENERIC_READ; + else + client_access |= FILE_READ_ATTRIBUTES; + if (client_flags & UV_WRITABLE_PIPE) + client_access |= GENERIC_WRITE; + else + client_access |= FILE_WRITE_ATTRIBUTES; + client_access |= WRITE_DAC; + + /* Create server pipe handle. */ + err = uv__pipe_server(&server_pipe, + server_access, + pipe_name, + sizeof(pipe_name), + random); + if (err) + goto error; + + /* Create client pipe handle. */ + sa.nLength = sizeof sa; + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = inherit_client; + + client_pipe = CreateFileA(pipe_name, + client_access, + 0, + &sa, + OPEN_EXISTING, + (client_flags & UV_NONBLOCK_PIPE) ? FILE_FLAG_OVERLAPPED : 0, + NULL); + if (client_pipe == INVALID_HANDLE_VALUE) { + err = GetLastError(); + goto error; + } + +#ifndef NDEBUG + /* Validate that the pipe was opened in the right mode. */ + { + DWORD mode; + BOOL r; + r = GetNamedPipeHandleState(client_pipe, &mode, NULL, NULL, NULL, NULL, 0); + if (r == TRUE) { + assert(mode == (PIPE_READMODE_BYTE | PIPE_WAIT)); + } else { + fprintf(stderr, "libuv assertion failure: GetNamedPipeHandleState failed\n"); + } + } +#endif + + /* Do a blocking ConnectNamedPipe. This should not block because we have + * both ends of the pipe created. */ + if (!ConnectNamedPipe(server_pipe, NULL)) { + if (GetLastError() != ERROR_PIPE_CONNECTED) { + err = GetLastError(); + goto error; + } + } + + *client_pipe_ptr = client_pipe; + *server_pipe_ptr = server_pipe; + return 0; + + error: + if (server_pipe != INVALID_HANDLE_VALUE) + CloseHandle(server_pipe); + + if (client_pipe != INVALID_HANDLE_VALUE) + CloseHandle(client_pipe); + + return err; +} + + +int uv_pipe(uv_file fds[2], int read_flags, int write_flags) { + uv_file temp[2]; + int err; + HANDLE readh; + HANDLE writeh; + + /* Make the server side the inbound (read) end, */ + /* so that both ends will have FILE_READ_ATTRIBUTES permission. */ + /* TODO: better source of local randomness than &fds? */ + read_flags |= UV_READABLE_PIPE; + write_flags |= UV_WRITABLE_PIPE; + err = uv__create_pipe_pair(&readh, &writeh, read_flags, write_flags, 0, (char*) &fds[0]); + if (err != 0) + return err; + temp[0] = _open_osfhandle((intptr_t) readh, 0); + if (temp[0] == -1) { + if (errno == UV_EMFILE) + err = UV_EMFILE; + else + err = UV_UNKNOWN; + CloseHandle(readh); + CloseHandle(writeh); + return err; + } + temp[1] = _open_osfhandle((intptr_t) writeh, 0); + if (temp[1] == -1) { + if (errno == UV_EMFILE) + err = UV_EMFILE; + else + err = UV_UNKNOWN; + _close(temp[0]); + CloseHandle(writeh); + return err; + } + fds[0] = temp[0]; + fds[1] = temp[1]; + return 0; +} + + +int uv__create_stdio_pipe_pair(uv_loop_t* loop, + uv_pipe_t* parent_pipe, HANDLE* child_pipe_ptr, unsigned int flags) { + /* The parent_pipe is always the server_pipe and kept by libuv. + * The child_pipe is always the client_pipe and is passed to the child. + * The flags are specified with respect to their usage in the child. */ + HANDLE server_pipe; + HANDLE client_pipe; + unsigned int server_flags; + unsigned int client_flags; + int err; + + server_pipe = INVALID_HANDLE_VALUE; + client_pipe = INVALID_HANDLE_VALUE; + + server_flags = 0; + client_flags = 0; + if (flags & UV_READABLE_PIPE) { + /* The server needs inbound (read) access too, otherwise CreateNamedPipe() + * won't give us the FILE_READ_ATTRIBUTES permission. We need that to probe + * the state of the write buffer when we're trying to shutdown the pipe. */ + server_flags |= UV_READABLE_PIPE | UV_WRITABLE_PIPE; + client_flags |= UV_READABLE_PIPE; + } + if (flags & UV_WRITABLE_PIPE) { + server_flags |= UV_READABLE_PIPE; + client_flags |= UV_WRITABLE_PIPE; + } + server_flags |= UV_NONBLOCK_PIPE; + if (flags & UV_NONBLOCK_PIPE || parent_pipe->ipc) { + client_flags |= UV_NONBLOCK_PIPE; + } + + err = uv__create_pipe_pair(&server_pipe, &client_pipe, + server_flags, client_flags, 1, (char*) server_pipe); + if (err) + goto error; + + if (CreateIoCompletionPort(server_pipe, + loop->iocp, + (ULONG_PTR) parent_pipe, + 0) == NULL) { + err = GetLastError(); + goto error; + } + + uv_pipe_connection_init(parent_pipe); + parent_pipe->handle = server_pipe; + *child_pipe_ptr = client_pipe; + + /* The server end is now readable and/or writable. */ + if (flags & UV_READABLE_PIPE) + parent_pipe->flags |= UV_HANDLE_WRITABLE; + if (flags & UV_WRITABLE_PIPE) + parent_pipe->flags |= UV_HANDLE_READABLE; + + return 0; + + error: + if (server_pipe != INVALID_HANDLE_VALUE) + CloseHandle(server_pipe); + + if (client_pipe != INVALID_HANDLE_VALUE) + CloseHandle(client_pipe); + + return err; +} + + +static int uv_set_pipe_handle(uv_loop_t* loop, + uv_pipe_t* handle, + HANDLE pipeHandle, + int fd, + DWORD duplex_flags) { + NTSTATUS nt_status; + IO_STATUS_BLOCK io_status; + FILE_MODE_INFORMATION mode_info; + DWORD mode = PIPE_READMODE_BYTE | PIPE_WAIT; + DWORD current_mode = 0; + DWORD err = 0; + + if (handle->flags & UV_HANDLE_PIPESERVER) + return UV_EINVAL; + if (handle->handle != INVALID_HANDLE_VALUE) + return UV_EBUSY; + + if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) { + err = GetLastError(); + if (err == ERROR_ACCESS_DENIED) { + /* + * SetNamedPipeHandleState can fail if the handle doesn't have either + * GENERIC_WRITE or FILE_WRITE_ATTRIBUTES. + * But if the handle already has the desired wait and blocking modes + * we can continue. + */ + if (!GetNamedPipeHandleState(pipeHandle, ¤t_mode, NULL, NULL, + NULL, NULL, 0)) { + return -1; + } else if (current_mode & PIPE_NOWAIT) { + SetLastError(ERROR_ACCESS_DENIED); + return -1; + } + } else { + /* If this returns ERROR_INVALID_PARAMETER we probably opened + * something that is not a pipe. */ + if (err == ERROR_INVALID_PARAMETER) { + SetLastError(WSAENOTSOCK); + } + return -1; + } + } + + /* Check if the pipe was created with FILE_FLAG_OVERLAPPED. */ + nt_status = pNtQueryInformationFile(pipeHandle, + &io_status, + &mode_info, + sizeof(mode_info), + FileModeInformation); + if (nt_status != STATUS_SUCCESS) { + return -1; + } + + if (mode_info.Mode & FILE_SYNCHRONOUS_IO_ALERT || + mode_info.Mode & FILE_SYNCHRONOUS_IO_NONALERT) { + /* Non-overlapped pipe. */ + handle->flags |= UV_HANDLE_NON_OVERLAPPED_PIPE; + } else { + /* Overlapped pipe. Try to associate with IOCP. */ + if (CreateIoCompletionPort(pipeHandle, + loop->iocp, + (ULONG_PTR) handle, + 0) == NULL) { + handle->flags |= UV_HANDLE_EMULATE_IOCP; + } + } + + handle->handle = pipeHandle; + handle->u.fd = fd; + handle->flags |= duplex_flags; + + return 0; +} + + +static int pipe_alloc_accept(uv_loop_t* loop, uv_pipe_t* handle, + uv_pipe_accept_t* req, BOOL firstInstance) { + assert(req->pipeHandle == INVALID_HANDLE_VALUE); + + req->pipeHandle = + CreateNamedPipeW(handle->name, + PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | WRITE_DAC | + (firstInstance ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0), + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, + PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL); + + if (req->pipeHandle == INVALID_HANDLE_VALUE) { + return 0; + } + + /* Associate it with IOCP so we can get events. */ + if (CreateIoCompletionPort(req->pipeHandle, + loop->iocp, + (ULONG_PTR) handle, + 0) == NULL) { + uv_fatal_error(GetLastError(), "CreateIoCompletionPort"); + } + + /* Stash a handle in the server object for use from places such as + * getsockname and chmod. As we transfer ownership of these to client + * objects, we'll allocate new ones here. */ + handle->handle = req->pipeHandle; + + return 1; +} + + +static DWORD WINAPI pipe_shutdown_thread_proc(void* parameter) { + uv_loop_t* loop; + uv_pipe_t* handle; + uv_shutdown_t* req; + + req = (uv_shutdown_t*) parameter; + assert(req); + handle = (uv_pipe_t*) req->handle; + assert(handle); + loop = handle->loop; + assert(loop); + + FlushFileBuffers(handle->handle); + + /* Post completed */ + POST_COMPLETION_FOR_REQ(loop, req); + + return 0; +} + + +void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) { + int err; + DWORD result; + uv_shutdown_t* req; + NTSTATUS nt_status; + IO_STATUS_BLOCK io_status; + FILE_PIPE_LOCAL_INFORMATION pipe_info; + uv__ipc_xfer_queue_item_t* xfer_queue_item; + + if ((handle->flags & UV_HANDLE_CONNECTION) && + handle->stream.conn.shutdown_req != NULL && + handle->stream.conn.write_reqs_pending == 0) { + req = handle->stream.conn.shutdown_req; + + /* Clear the shutdown_req field so we don't go here again. */ + handle->stream.conn.shutdown_req = NULL; + + if (handle->flags & UV_HANDLE_CLOSING) { + UNREGISTER_HANDLE_REQ(loop, handle, req); + + /* Already closing. Cancel the shutdown. */ + if (req->cb) { + req->cb(req, UV_ECANCELED); + } + + DECREASE_PENDING_REQ_COUNT(handle); + return; + } + + /* Try to avoid flushing the pipe buffer in the thread pool. */ + nt_status = pNtQueryInformationFile(handle->handle, + &io_status, + &pipe_info, + sizeof pipe_info, + FilePipeLocalInformation); + + if (nt_status != STATUS_SUCCESS) { + /* Failure */ + UNREGISTER_HANDLE_REQ(loop, handle, req); + + handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */ + if (req->cb) { + err = pRtlNtStatusToDosError(nt_status); + req->cb(req, uv_translate_sys_error(err)); + } + + DECREASE_PENDING_REQ_COUNT(handle); + return; + } + + if (pipe_info.OutboundQuota == pipe_info.WriteQuotaAvailable) { + /* Short-circuit, no need to call FlushFileBuffers. */ + uv_insert_pending_req(loop, (uv_req_t*) req); + return; + } + + /* Run FlushFileBuffers in the thread pool. */ + result = QueueUserWorkItem(pipe_shutdown_thread_proc, + req, + WT_EXECUTELONGFUNCTION); + if (result) { + return; + + } else { + /* Failure. */ + UNREGISTER_HANDLE_REQ(loop, handle, req); + + handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */ + if (req->cb) { + err = GetLastError(); + req->cb(req, uv_translate_sys_error(err)); + } + + DECREASE_PENDING_REQ_COUNT(handle); + return; + } + } + + if (handle->flags & UV_HANDLE_CLOSING && + handle->reqs_pending == 0) { + assert(!(handle->flags & UV_HANDLE_CLOSED)); + + if (handle->flags & UV_HANDLE_CONNECTION) { + /* Free pending sockets */ + while (!QUEUE_EMPTY(&handle->pipe.conn.ipc_xfer_queue)) { + QUEUE* q; + SOCKET socket; + + q = QUEUE_HEAD(&handle->pipe.conn.ipc_xfer_queue); + QUEUE_REMOVE(q); + xfer_queue_item = QUEUE_DATA(q, uv__ipc_xfer_queue_item_t, member); + + /* Materialize socket and close it */ + socket = WSASocketW(FROM_PROTOCOL_INFO, + FROM_PROTOCOL_INFO, + FROM_PROTOCOL_INFO, + &xfer_queue_item->xfer_info.socket_info, + 0, + WSA_FLAG_OVERLAPPED); + uv__free(xfer_queue_item); + + if (socket != INVALID_SOCKET) + closesocket(socket); + } + handle->pipe.conn.ipc_xfer_queue_length = 0; + + if (handle->flags & UV_HANDLE_EMULATE_IOCP) { + if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) { + UnregisterWait(handle->read_req.wait_handle); + handle->read_req.wait_handle = INVALID_HANDLE_VALUE; + } + if (handle->read_req.event_handle != NULL) { + CloseHandle(handle->read_req.event_handle); + handle->read_req.event_handle = NULL; + } + } + + if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) + DeleteCriticalSection(&handle->pipe.conn.readfile_thread_lock); + } + + if (handle->flags & UV_HANDLE_PIPESERVER) { + assert(handle->pipe.serv.accept_reqs); + uv__free(handle->pipe.serv.accept_reqs); + handle->pipe.serv.accept_reqs = NULL; + } + + uv__handle_close(handle); + } +} + + +void uv_pipe_pending_instances(uv_pipe_t* handle, int count) { + if (handle->flags & UV_HANDLE_BOUND) + return; + handle->pipe.serv.pending_instances = count; + handle->flags |= UV_HANDLE_PIPESERVER; +} + + +/* Creates a pipe server. */ +int uv_pipe_bind(uv_pipe_t* handle, const char* name) { + uv_loop_t* loop = handle->loop; + int i, err, nameSize; + uv_pipe_accept_t* req; + + if (handle->flags & UV_HANDLE_BOUND) { + return UV_EINVAL; + } + + if (!name) { + return UV_EINVAL; + } + + if (!(handle->flags & UV_HANDLE_PIPESERVER)) { + handle->pipe.serv.pending_instances = default_pending_pipe_instances; + } + + handle->pipe.serv.accept_reqs = (uv_pipe_accept_t*) + uv__malloc(sizeof(uv_pipe_accept_t) * handle->pipe.serv.pending_instances); + if (!handle->pipe.serv.accept_reqs) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + for (i = 0; i < handle->pipe.serv.pending_instances; i++) { + req = &handle->pipe.serv.accept_reqs[i]; + UV_REQ_INIT(req, UV_ACCEPT); + req->data = handle; + req->pipeHandle = INVALID_HANDLE_VALUE; + req->next_pending = NULL; + } + + /* Convert name to UTF16. */ + nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR); + handle->name = uv__malloc(nameSize); + if (!handle->name) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + if (!MultiByteToWideChar(CP_UTF8, + 0, + name, + -1, + handle->name, + nameSize / sizeof(WCHAR))) { + err = GetLastError(); + goto error; + } + + /* + * Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE. + * If this fails then there's already a pipe server for the given pipe name. + */ + if (!pipe_alloc_accept(loop, + handle, + &handle->pipe.serv.accept_reqs[0], + TRUE)) { + err = GetLastError(); + if (err == ERROR_ACCESS_DENIED) { + err = WSAEADDRINUSE; /* Translates to UV_EADDRINUSE. */ + } else if (err == ERROR_PATH_NOT_FOUND || err == ERROR_INVALID_NAME) { + err = WSAEACCES; /* Translates to UV_EACCES. */ + } + goto error; + } + + handle->pipe.serv.pending_accepts = NULL; + handle->flags |= UV_HANDLE_PIPESERVER; + handle->flags |= UV_HANDLE_BOUND; + + return 0; + +error: + if (handle->name) { + uv__free(handle->name); + handle->name = NULL; + } + + return uv_translate_sys_error(err); +} + + +static DWORD WINAPI pipe_connect_thread_proc(void* parameter) { + uv_loop_t* loop; + uv_pipe_t* handle; + uv_connect_t* req; + HANDLE pipeHandle = INVALID_HANDLE_VALUE; + DWORD duplex_flags; + + req = (uv_connect_t*) parameter; + assert(req); + handle = (uv_pipe_t*) req->handle; + assert(handle); + loop = handle->loop; + assert(loop); + + /* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. We wait + * for the pipe to become available with WaitNamedPipe. */ + while (WaitNamedPipeW(handle->name, 30000)) { + /* The pipe is now available, try to connect. */ + pipeHandle = open_named_pipe(handle->name, &duplex_flags); + if (pipeHandle != INVALID_HANDLE_VALUE) + break; + + SwitchToThread(); + } + + if (pipeHandle != INVALID_HANDLE_VALUE && + !uv_set_pipe_handle(loop, handle, pipeHandle, -1, duplex_flags)) { + SET_REQ_SUCCESS(req); + } else { + SET_REQ_ERROR(req, GetLastError()); + } + + /* Post completed */ + POST_COMPLETION_FOR_REQ(loop, req); + + return 0; +} + + +void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, + const char* name, uv_connect_cb cb) { + uv_loop_t* loop = handle->loop; + int err, nameSize; + HANDLE pipeHandle = INVALID_HANDLE_VALUE; + DWORD duplex_flags; + + UV_REQ_INIT(req, UV_CONNECT); + req->handle = (uv_stream_t*) handle; + req->cb = cb; + + /* Convert name to UTF16. */ + nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR); + handle->name = uv__malloc(nameSize); + if (!handle->name) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + if (!MultiByteToWideChar(CP_UTF8, + 0, + name, + -1, + handle->name, + nameSize / sizeof(WCHAR))) { + err = GetLastError(); + goto error; + } + + pipeHandle = open_named_pipe(handle->name, &duplex_flags); + if (pipeHandle == INVALID_HANDLE_VALUE) { + if (GetLastError() == ERROR_PIPE_BUSY) { + /* Wait for the server to make a pipe instance available. */ + if (!QueueUserWorkItem(&pipe_connect_thread_proc, + req, + WT_EXECUTELONGFUNCTION)) { + err = GetLastError(); + goto error; + } + + REGISTER_HANDLE_REQ(loop, handle, req); + handle->reqs_pending++; + + return; + } + + err = GetLastError(); + goto error; + } + + assert(pipeHandle != INVALID_HANDLE_VALUE); + + if (uv_set_pipe_handle(loop, + (uv_pipe_t*) req->handle, + pipeHandle, + -1, + duplex_flags)) { + err = GetLastError(); + goto error; + } + + SET_REQ_SUCCESS(req); + uv_insert_pending_req(loop, (uv_req_t*) req); + handle->reqs_pending++; + REGISTER_HANDLE_REQ(loop, handle, req); + return; + +error: + if (handle->name) { + uv__free(handle->name); + handle->name = NULL; + } + + if (pipeHandle != INVALID_HANDLE_VALUE) + CloseHandle(pipeHandle); + + /* Make this req pending reporting an error. */ + SET_REQ_ERROR(req, err); + uv_insert_pending_req(loop, (uv_req_t*) req); + handle->reqs_pending++; + REGISTER_HANDLE_REQ(loop, handle, req); + return; +} + + +void uv__pipe_interrupt_read(uv_pipe_t* handle) { + BOOL r; + + if (!(handle->flags & UV_HANDLE_READ_PENDING)) + return; /* No pending reads. */ + if (handle->flags & UV_HANDLE_CANCELLATION_PENDING) + return; /* Already cancelled. */ + if (handle->handle == INVALID_HANDLE_VALUE) + return; /* Pipe handle closed. */ + + if (!(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE)) { + /* Cancel asynchronous read. */ + r = CancelIoEx(handle->handle, &handle->read_req.u.io.overlapped); + assert(r || GetLastError() == ERROR_NOT_FOUND); + + } else { + /* Cancel synchronous read (which is happening in the thread pool). */ + HANDLE thread; + volatile HANDLE* thread_ptr = &handle->pipe.conn.readfile_thread_handle; + + EnterCriticalSection(&handle->pipe.conn.readfile_thread_lock); + + thread = *thread_ptr; + if (thread == NULL) { + /* The thread pool thread has not yet reached the point of blocking, we + * can pre-empt it by setting thread_handle to INVALID_HANDLE_VALUE. */ + *thread_ptr = INVALID_HANDLE_VALUE; + + } else { + /* Spin until the thread has acknowledged (by setting the thread to + * INVALID_HANDLE_VALUE) that it is past the point of blocking. */ + while (thread != INVALID_HANDLE_VALUE) { + r = CancelSynchronousIo(thread); + assert(r || GetLastError() == ERROR_NOT_FOUND); + SwitchToThread(); /* Yield thread. */ + thread = *thread_ptr; + } + } + + LeaveCriticalSection(&handle->pipe.conn.readfile_thread_lock); + } + + /* Set flag to indicate that read has been cancelled. */ + handle->flags |= UV_HANDLE_CANCELLATION_PENDING; +} + + +void uv__pipe_read_stop(uv_pipe_t* handle) { + handle->flags &= ~UV_HANDLE_READING; + DECREASE_ACTIVE_COUNT(handle->loop, handle); + + uv__pipe_interrupt_read(handle); +} + + +/* Cleans up uv_pipe_t (server or connection) and all resources associated with + * it. */ +void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) { + int i; + HANDLE pipeHandle; + + uv__pipe_interrupt_read(handle); + + if (handle->name) { + uv__free(handle->name); + handle->name = NULL; + } + + if (handle->flags & UV_HANDLE_PIPESERVER) { + for (i = 0; i < handle->pipe.serv.pending_instances; i++) { + pipeHandle = handle->pipe.serv.accept_reqs[i].pipeHandle; + if (pipeHandle != INVALID_HANDLE_VALUE) { + CloseHandle(pipeHandle); + handle->pipe.serv.accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE; + } + } + handle->handle = INVALID_HANDLE_VALUE; + } + + if (handle->flags & UV_HANDLE_CONNECTION) { + handle->flags &= ~UV_HANDLE_WRITABLE; + eof_timer_destroy(handle); + } + + if ((handle->flags & UV_HANDLE_CONNECTION) + && handle->handle != INVALID_HANDLE_VALUE) + close_pipe(handle); +} + + +void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle) { + if (handle->flags & UV_HANDLE_READING) { + handle->flags &= ~UV_HANDLE_READING; + DECREASE_ACTIVE_COUNT(loop, handle); + } + + if (handle->flags & UV_HANDLE_LISTENING) { + handle->flags &= ~UV_HANDLE_LISTENING; + DECREASE_ACTIVE_COUNT(loop, handle); + } + + uv_pipe_cleanup(loop, handle); + + if (handle->reqs_pending == 0) { + uv_want_endgame(loop, (uv_handle_t*) handle); + } + + handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); + uv__handle_closing(handle); +} + + +static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle, + uv_pipe_accept_t* req, BOOL firstInstance) { + assert(handle->flags & UV_HANDLE_LISTENING); + + if (!firstInstance && !pipe_alloc_accept(loop, handle, req, FALSE)) { + SET_REQ_ERROR(req, GetLastError()); + uv_insert_pending_req(loop, (uv_req_t*) req); + handle->reqs_pending++; + return; + } + + assert(req->pipeHandle != INVALID_HANDLE_VALUE); + + /* Prepare the overlapped structure. */ + memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped)); + + if (!ConnectNamedPipe(req->pipeHandle, &req->u.io.overlapped) && + GetLastError() != ERROR_IO_PENDING) { + if (GetLastError() == ERROR_PIPE_CONNECTED) { + SET_REQ_SUCCESS(req); + } else { + CloseHandle(req->pipeHandle); + req->pipeHandle = INVALID_HANDLE_VALUE; + /* Make this req pending reporting an error. */ + SET_REQ_ERROR(req, GetLastError()); + } + uv_insert_pending_req(loop, (uv_req_t*) req); + handle->reqs_pending++; + return; + } + + /* Wait for completion via IOCP */ + handle->reqs_pending++; +} + + +int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) { + uv_loop_t* loop = server->loop; + uv_pipe_t* pipe_client; + uv_pipe_accept_t* req; + QUEUE* q; + uv__ipc_xfer_queue_item_t* item; + int err; + + if (server->ipc) { + if (QUEUE_EMPTY(&server->pipe.conn.ipc_xfer_queue)) { + /* No valid pending sockets. */ + return WSAEWOULDBLOCK; + } + + q = QUEUE_HEAD(&server->pipe.conn.ipc_xfer_queue); + QUEUE_REMOVE(q); + server->pipe.conn.ipc_xfer_queue_length--; + item = QUEUE_DATA(q, uv__ipc_xfer_queue_item_t, member); + + err = uv__tcp_xfer_import( + (uv_tcp_t*) client, item->xfer_type, &item->xfer_info); + if (err != 0) + return err; + + uv__free(item); + + } else { + pipe_client = (uv_pipe_t*) client; + + /* Find a connection instance that has been connected, but not yet + * accepted. */ + req = server->pipe.serv.pending_accepts; + + if (!req) { + /* No valid connections found, so we error out. */ + return WSAEWOULDBLOCK; + } + + /* Initialize the client handle and copy the pipeHandle to the client */ + uv_pipe_connection_init(pipe_client); + pipe_client->handle = req->pipeHandle; + pipe_client->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; + + /* Prepare the req to pick up a new connection */ + server->pipe.serv.pending_accepts = req->next_pending; + req->next_pending = NULL; + req->pipeHandle = INVALID_HANDLE_VALUE; + + server->handle = INVALID_HANDLE_VALUE; + if (!(server->flags & UV_HANDLE_CLOSING)) { + uv_pipe_queue_accept(loop, server, req, FALSE); + } + } + + return 0; +} + + +/* Starts listening for connections for the given pipe. */ +int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) { + uv_loop_t* loop = handle->loop; + int i; + + if (handle->flags & UV_HANDLE_LISTENING) { + handle->stream.serv.connection_cb = cb; + } + + if (!(handle->flags & UV_HANDLE_BOUND)) { + return WSAEINVAL; + } + + if (handle->flags & UV_HANDLE_READING) { + return WSAEISCONN; + } + + if (!(handle->flags & UV_HANDLE_PIPESERVER)) { + return ERROR_NOT_SUPPORTED; + } + + if (handle->ipc) { + return WSAEINVAL; + } + + handle->flags |= UV_HANDLE_LISTENING; + INCREASE_ACTIVE_COUNT(loop, handle); + handle->stream.serv.connection_cb = cb; + + /* First pipe handle should have already been created in uv_pipe_bind */ + assert(handle->pipe.serv.accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE); + + for (i = 0; i < handle->pipe.serv.pending_instances; i++) { + uv_pipe_queue_accept(loop, handle, &handle->pipe.serv.accept_reqs[i], i == 0); + } + + return 0; +} + + +static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* arg) { + uv_read_t* req = (uv_read_t*) arg; + uv_pipe_t* handle = (uv_pipe_t*) req->data; + uv_loop_t* loop = handle->loop; + volatile HANDLE* thread_ptr = &handle->pipe.conn.readfile_thread_handle; + CRITICAL_SECTION* lock = &handle->pipe.conn.readfile_thread_lock; + HANDLE thread; + DWORD bytes; + DWORD err; + + assert(req->type == UV_READ); + assert(handle->type == UV_NAMED_PIPE); + + err = 0; + + /* Create a handle to the current thread. */ + if (!DuplicateHandle(GetCurrentProcess(), + GetCurrentThread(), + GetCurrentProcess(), + &thread, + 0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + err = GetLastError(); + goto out1; + } + + /* The lock needs to be held when thread handle is modified. */ + EnterCriticalSection(lock); + if (*thread_ptr == INVALID_HANDLE_VALUE) { + /* uv__pipe_interrupt_read() cancelled reading before we got here. */ + err = ERROR_OPERATION_ABORTED; + } else { + /* Let main thread know which worker thread is doing the blocking read. */ + assert(*thread_ptr == NULL); + *thread_ptr = thread; + } + LeaveCriticalSection(lock); + + if (err) + goto out2; + + /* Block the thread until data is available on the pipe, or the read is + * cancelled. */ + if (!ReadFile(handle->handle, &uv_zero_, 0, &bytes, NULL)) + err = GetLastError(); + + /* Let the main thread know the worker is past the point of blocking. */ + assert(thread == *thread_ptr); + *thread_ptr = INVALID_HANDLE_VALUE; + + /* Briefly acquire the mutex. Since the main thread holds the lock while it + * is spinning trying to cancel this thread's I/O, we will block here until + * it stops doing that. */ + EnterCriticalSection(lock); + LeaveCriticalSection(lock); + +out2: + /* Close the handle to the current thread. */ + CloseHandle(thread); + +out1: + /* Set request status and post a completion record to the IOCP. */ + if (err) + SET_REQ_ERROR(req, err); + else + SET_REQ_SUCCESS(req); + POST_COMPLETION_FOR_REQ(loop, req); + + return 0; +} + + +static DWORD WINAPI uv_pipe_writefile_thread_proc(void* parameter) { + int result; + DWORD bytes; + uv_write_t* req = (uv_write_t*) parameter; + uv_pipe_t* handle = (uv_pipe_t*) req->handle; + uv_loop_t* loop = handle->loop; + + assert(req != NULL); + assert(req->type == UV_WRITE); + assert(handle->type == UV_NAMED_PIPE); + assert(req->write_buffer.base); + + result = WriteFile(handle->handle, + req->write_buffer.base, + req->write_buffer.len, + &bytes, + NULL); + + if (!result) { + SET_REQ_ERROR(req, GetLastError()); + } + + POST_COMPLETION_FOR_REQ(loop, req); + return 0; +} + + +static void CALLBACK post_completion_read_wait(void* context, BOOLEAN timed_out) { + uv_read_t* req; + uv_tcp_t* handle; + + req = (uv_read_t*) context; + assert(req != NULL); + handle = (uv_tcp_t*)req->data; + assert(handle != NULL); + assert(!timed_out); + + if (!PostQueuedCompletionStatus(handle->loop->iocp, + req->u.io.overlapped.InternalHigh, + 0, + &req->u.io.overlapped)) { + uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); + } +} + + +static void CALLBACK post_completion_write_wait(void* context, BOOLEAN timed_out) { + uv_write_t* req; + uv_tcp_t* handle; + + req = (uv_write_t*) context; + assert(req != NULL); + handle = (uv_tcp_t*)req->handle; + assert(handle != NULL); + assert(!timed_out); + + if (!PostQueuedCompletionStatus(handle->loop->iocp, + req->u.io.overlapped.InternalHigh, + 0, + &req->u.io.overlapped)) { + uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); + } +} + + +static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) { + uv_read_t* req; + int result; + + assert(handle->flags & UV_HANDLE_READING); + assert(!(handle->flags & UV_HANDLE_READ_PENDING)); + + assert(handle->handle != INVALID_HANDLE_VALUE); + + req = &handle->read_req; + + if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) { + handle->pipe.conn.readfile_thread_handle = NULL; /* Reset cancellation. */ + if (!QueueUserWorkItem(&uv_pipe_zero_readfile_thread_proc, + req, + WT_EXECUTELONGFUNCTION)) { + /* Make this req pending reporting an error. */ + SET_REQ_ERROR(req, GetLastError()); + goto error; + } + } else { + memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); + if (handle->flags & UV_HANDLE_EMULATE_IOCP) { + assert(req->event_handle != NULL); + req->u.io.overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1); + } + + /* Do 0-read */ + result = ReadFile(handle->handle, + &uv_zero_, + 0, + NULL, + &req->u.io.overlapped); + + if (!result && GetLastError() != ERROR_IO_PENDING) { + /* Make this req pending reporting an error. */ + SET_REQ_ERROR(req, GetLastError()); + goto error; + } + + if (handle->flags & UV_HANDLE_EMULATE_IOCP) { + if (req->wait_handle == INVALID_HANDLE_VALUE) { + if (!RegisterWaitForSingleObject(&req->wait_handle, + req->event_handle, post_completion_read_wait, (void*) req, + INFINITE, WT_EXECUTEINWAITTHREAD)) { + SET_REQ_ERROR(req, GetLastError()); + goto error; + } + } + } + } + + /* Start the eof timer if there is one */ + eof_timer_start(handle); + handle->flags |= UV_HANDLE_READ_PENDING; + handle->reqs_pending++; + return; + +error: + uv_insert_pending_req(loop, (uv_req_t*)req); + handle->flags |= UV_HANDLE_READ_PENDING; + handle->reqs_pending++; +} + + +int uv_pipe_read_start(uv_pipe_t* handle, + uv_alloc_cb alloc_cb, + uv_read_cb read_cb) { + uv_loop_t* loop = handle->loop; + + handle->flags |= UV_HANDLE_READING; + INCREASE_ACTIVE_COUNT(loop, handle); + handle->read_cb = read_cb; + handle->alloc_cb = alloc_cb; + + /* If reading was stopped and then started again, there could still be a read + * request pending. */ + if (!(handle->flags & UV_HANDLE_READ_PENDING)) { + if (handle->flags & UV_HANDLE_EMULATE_IOCP && + handle->read_req.event_handle == NULL) { + handle->read_req.event_handle = CreateEvent(NULL, 0, 0, NULL); + if (handle->read_req.event_handle == NULL) { + uv_fatal_error(GetLastError(), "CreateEvent"); + } + } + uv_pipe_queue_read(loop, handle); + } + + return 0; +} + + +static void uv_insert_non_overlapped_write_req(uv_pipe_t* handle, + uv_write_t* req) { + req->next_req = NULL; + if (handle->pipe.conn.non_overlapped_writes_tail) { + req->next_req = + handle->pipe.conn.non_overlapped_writes_tail->next_req; + handle->pipe.conn.non_overlapped_writes_tail->next_req = (uv_req_t*)req; + handle->pipe.conn.non_overlapped_writes_tail = req; + } else { + req->next_req = (uv_req_t*)req; + handle->pipe.conn.non_overlapped_writes_tail = req; + } +} + + +static uv_write_t* uv_remove_non_overlapped_write_req(uv_pipe_t* handle) { + uv_write_t* req; + + if (handle->pipe.conn.non_overlapped_writes_tail) { + req = (uv_write_t*)handle->pipe.conn.non_overlapped_writes_tail->next_req; + + if (req == handle->pipe.conn.non_overlapped_writes_tail) { + handle->pipe.conn.non_overlapped_writes_tail = NULL; + } else { + handle->pipe.conn.non_overlapped_writes_tail->next_req = + req->next_req; + } + + return req; + } else { + /* queue empty */ + return NULL; + } +} + + +static void uv_queue_non_overlapped_write(uv_pipe_t* handle) { + uv_write_t* req = uv_remove_non_overlapped_write_req(handle); + if (req) { + if (!QueueUserWorkItem(&uv_pipe_writefile_thread_proc, + req, + WT_EXECUTELONGFUNCTION)) { + uv_fatal_error(GetLastError(), "QueueUserWorkItem"); + } + } +} + + +static int uv__build_coalesced_write_req(uv_write_t* user_req, + const uv_buf_t bufs[], + size_t nbufs, + uv_write_t** req_out, + uv_buf_t* write_buf_out) { + /* Pack into a single heap-allocated buffer: + * (a) a uv_write_t structure where libuv stores the actual state. + * (b) a pointer to the original uv_write_t. + * (c) data from all `bufs` entries. + */ + char* heap_buffer; + size_t heap_buffer_length, heap_buffer_offset; + uv__coalesced_write_t* coalesced_write_req; /* (a) + (b) */ + char* data_start; /* (c) */ + size_t data_length; + unsigned int i; + + /* Compute combined size of all combined buffers from `bufs`. */ + data_length = 0; + for (i = 0; i < nbufs; i++) + data_length += bufs[i].len; + + /* The total combined size of data buffers should not exceed UINT32_MAX, + * because WriteFile() won't accept buffers larger than that. */ + if (data_length > UINT32_MAX) + return WSAENOBUFS; /* Maps to UV_ENOBUFS. */ + + /* Compute heap buffer size. */ + heap_buffer_length = sizeof *coalesced_write_req + /* (a) + (b) */ + data_length; /* (c) */ + + /* Allocate buffer. */ + heap_buffer = uv__malloc(heap_buffer_length); + if (heap_buffer == NULL) + return ERROR_NOT_ENOUGH_MEMORY; /* Maps to UV_ENOMEM. */ + + /* Copy uv_write_t information to the buffer. */ + coalesced_write_req = (uv__coalesced_write_t*) heap_buffer; + coalesced_write_req->req = *user_req; /* copy (a) */ + coalesced_write_req->req.coalesced = 1; + coalesced_write_req->user_req = user_req; /* copy (b) */ + heap_buffer_offset = sizeof *coalesced_write_req; /* offset (a) + (b) */ + + /* Copy data buffers to the heap buffer. */ + data_start = &heap_buffer[heap_buffer_offset]; + for (i = 0; i < nbufs; i++) { + memcpy(&heap_buffer[heap_buffer_offset], + bufs[i].base, + bufs[i].len); /* copy (c) */ + heap_buffer_offset += bufs[i].len; /* offset (c) */ + } + assert(heap_buffer_offset == heap_buffer_length); + + /* Set out arguments and return. */ + *req_out = &coalesced_write_req->req; + *write_buf_out = uv_buf_init(data_start, (unsigned int) data_length); + return 0; +} + + +static int uv__pipe_write_data(uv_loop_t* loop, + uv_write_t* req, + uv_pipe_t* handle, + const uv_buf_t bufs[], + size_t nbufs, + uv_write_cb cb, + int copy_always) { + int err; + int result; + uv_buf_t write_buf; + + assert(handle->handle != INVALID_HANDLE_VALUE); + + UV_REQ_INIT(req, UV_WRITE); + req->handle = (uv_stream_t*) handle; + req->send_handle = NULL; + req->cb = cb; + /* Private fields. */ + req->coalesced = 0; + req->event_handle = NULL; + req->wait_handle = INVALID_HANDLE_VALUE; + + /* Prepare the overlapped structure. */ + memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); + if (handle->flags & (UV_HANDLE_EMULATE_IOCP | UV_HANDLE_BLOCKING_WRITES)) { + req->event_handle = CreateEvent(NULL, 0, 0, NULL); + if (req->event_handle == NULL) { + uv_fatal_error(GetLastError(), "CreateEvent"); + } + req->u.io.overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1); + } + req->write_buffer = uv_null_buf_; + + if (nbufs == 0) { + /* Write empty buffer. */ + write_buf = uv_null_buf_; + } else if (nbufs == 1 && !copy_always) { + /* Write directly from bufs[0]. */ + write_buf = bufs[0]; + } else { + /* Coalesce all `bufs` into one big buffer. This also creates a new + * write-request structure that replaces the old one. */ + err = uv__build_coalesced_write_req(req, bufs, nbufs, &req, &write_buf); + if (err != 0) + return err; + } + + if ((handle->flags & + (UV_HANDLE_BLOCKING_WRITES | UV_HANDLE_NON_OVERLAPPED_PIPE)) == + (UV_HANDLE_BLOCKING_WRITES | UV_HANDLE_NON_OVERLAPPED_PIPE)) { + DWORD bytes; + result = + WriteFile(handle->handle, write_buf.base, write_buf.len, &bytes, NULL); + + if (!result) { + err = GetLastError(); + return err; + } else { + /* Request completed immediately. */ + req->u.io.queued_bytes = 0; + } + + REGISTER_HANDLE_REQ(loop, handle, req); + handle->reqs_pending++; + handle->stream.conn.write_reqs_pending++; + POST_COMPLETION_FOR_REQ(loop, req); + return 0; + } else if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) { + req->write_buffer = write_buf; + uv_insert_non_overlapped_write_req(handle, req); + if (handle->stream.conn.write_reqs_pending == 0) { + uv_queue_non_overlapped_write(handle); + } + + /* Request queued by the kernel. */ + req->u.io.queued_bytes = write_buf.len; + handle->write_queue_size += req->u.io.queued_bytes; + } else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) { + /* Using overlapped IO, but wait for completion before returning */ + result = WriteFile(handle->handle, + write_buf.base, + write_buf.len, + NULL, + &req->u.io.overlapped); + + if (!result && GetLastError() != ERROR_IO_PENDING) { + err = GetLastError(); + CloseHandle(req->event_handle); + req->event_handle = NULL; + return err; + } + + if (result) { + /* Request completed immediately. */ + req->u.io.queued_bytes = 0; + } else { + /* Request queued by the kernel. */ + req->u.io.queued_bytes = write_buf.len; + handle->write_queue_size += req->u.io.queued_bytes; + if (WaitForSingleObject(req->event_handle, INFINITE) != + WAIT_OBJECT_0) { + err = GetLastError(); + CloseHandle(req->event_handle); + req->event_handle = NULL; + return err; + } + } + CloseHandle(req->event_handle); + req->event_handle = NULL; + + REGISTER_HANDLE_REQ(loop, handle, req); + handle->reqs_pending++; + handle->stream.conn.write_reqs_pending++; + return 0; + } else { + result = WriteFile(handle->handle, + write_buf.base, + write_buf.len, + NULL, + &req->u.io.overlapped); + + if (!result && GetLastError() != ERROR_IO_PENDING) { + return GetLastError(); + } + + if (result) { + /* Request completed immediately. */ + req->u.io.queued_bytes = 0; + } else { + /* Request queued by the kernel. */ + req->u.io.queued_bytes = write_buf.len; + handle->write_queue_size += req->u.io.queued_bytes; + } + + if (handle->flags & UV_HANDLE_EMULATE_IOCP) { + if (!RegisterWaitForSingleObject(&req->wait_handle, + req->event_handle, post_completion_write_wait, (void*) req, + INFINITE, WT_EXECUTEINWAITTHREAD)) { + return GetLastError(); + } + } + } + + REGISTER_HANDLE_REQ(loop, handle, req); + handle->reqs_pending++; + handle->stream.conn.write_reqs_pending++; + + return 0; +} + + +static DWORD uv__pipe_get_ipc_remote_pid(uv_pipe_t* handle) { + DWORD* pid = &handle->pipe.conn.ipc_remote_pid; + + /* If the both ends of the IPC pipe are owned by the same process, + * the remote end pid may not yet be set. If so, do it here. + * TODO: this is weird; it'd probably better to use a handshake. */ + if (*pid == 0) + *pid = GetCurrentProcessId(); + + return *pid; +} + + +int uv__pipe_write_ipc(uv_loop_t* loop, + uv_write_t* req, + uv_pipe_t* handle, + const uv_buf_t data_bufs[], + size_t data_buf_count, + uv_stream_t* send_handle, + uv_write_cb cb) { + uv_buf_t stack_bufs[6]; + uv_buf_t* bufs; + size_t buf_count, buf_index; + uv__ipc_frame_header_t frame_header; + uv__ipc_socket_xfer_type_t xfer_type = UV__IPC_SOCKET_XFER_NONE; + uv__ipc_socket_xfer_info_t xfer_info; + uint64_t data_length; + size_t i; + int err; + + /* Compute the combined size of data buffers. */ + data_length = 0; + for (i = 0; i < data_buf_count; i++) + data_length += data_bufs[i].len; + if (data_length > UINT32_MAX) + return WSAENOBUFS; /* Maps to UV_ENOBUFS. */ + + /* Prepare the frame's socket xfer payload. */ + if (send_handle != NULL) { + uv_tcp_t* send_tcp_handle = (uv_tcp_t*) send_handle; + + /* Verify that `send_handle` it is indeed a tcp handle. */ + if (send_tcp_handle->type != UV_TCP) + return ERROR_NOT_SUPPORTED; + + /* Export the tcp handle. */ + err = uv__tcp_xfer_export(send_tcp_handle, + uv__pipe_get_ipc_remote_pid(handle), + &xfer_type, + &xfer_info); + if (err != 0) + return err; + } + + /* Compute the number of uv_buf_t's required. */ + buf_count = 1 + data_buf_count; /* Frame header and data buffers. */ + if (send_handle != NULL) + buf_count += 1; /* One extra for the socket xfer information. */ + + /* Use the on-stack buffer array if it is big enough; otherwise allocate + * space for it on the heap. */ + if (buf_count < ARRAY_SIZE(stack_bufs)) { + /* Use on-stack buffer array. */ + bufs = stack_bufs; + } else { + /* Use heap-allocated buffer array. */ + bufs = uv__calloc(buf_count, sizeof(uv_buf_t)); + if (bufs == NULL) + return ERROR_NOT_ENOUGH_MEMORY; /* Maps to UV_ENOMEM. */ + } + buf_index = 0; + + /* Initialize frame header and add it to the buffers list. */ + memset(&frame_header, 0, sizeof frame_header); + bufs[buf_index++] = uv_buf_init((char*) &frame_header, sizeof frame_header); + + if (send_handle != NULL) { + /* Add frame header flags. */ + switch (xfer_type) { + case UV__IPC_SOCKET_XFER_TCP_CONNECTION: + frame_header.flags |= UV__IPC_FRAME_HAS_SOCKET_XFER | + UV__IPC_FRAME_XFER_IS_TCP_CONNECTION; + break; + case UV__IPC_SOCKET_XFER_TCP_SERVER: + frame_header.flags |= UV__IPC_FRAME_HAS_SOCKET_XFER; + break; + default: + assert(0); /* Unreachable. */ + } + /* Add xfer info buffer. */ + bufs[buf_index++] = uv_buf_init((char*) &xfer_info, sizeof xfer_info); + } + + if (data_length > 0) { + /* Update frame header. */ + frame_header.flags |= UV__IPC_FRAME_HAS_DATA; + frame_header.data_length = (uint32_t) data_length; + /* Add data buffers to buffers list. */ + for (i = 0; i < data_buf_count; i++) + bufs[buf_index++] = data_bufs[i]; + } + + /* Write buffers. We set the `always_copy` flag, so it is not a problem that + * some of the written data lives on the stack. */ + err = uv__pipe_write_data(loop, req, handle, bufs, buf_count, cb, 1); + + /* If we had to heap-allocate the bufs array, free it now. */ + if (bufs != stack_bufs) { + uv__free(bufs); + } + + return err; +} + + +int uv__pipe_write(uv_loop_t* loop, + uv_write_t* req, + uv_pipe_t* handle, + const uv_buf_t bufs[], + size_t nbufs, + uv_stream_t* send_handle, + uv_write_cb cb) { + if (handle->ipc) { + /* IPC pipe write: use framing protocol. */ + return uv__pipe_write_ipc(loop, req, handle, bufs, nbufs, send_handle, cb); + } else { + /* Non-IPC pipe write: put data on the wire directly. */ + assert(send_handle == NULL); + return uv__pipe_write_data(loop, req, handle, bufs, nbufs, cb, 0); + } +} + + +static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle, + uv_buf_t buf) { + /* If there is an eof timer running, we don't need it any more, so discard + * it. */ + eof_timer_destroy(handle); + + handle->flags &= ~UV_HANDLE_READABLE; + uv_read_stop((uv_stream_t*) handle); + + handle->read_cb((uv_stream_t*) handle, UV_EOF, &buf); +} + + +static void uv_pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error, + uv_buf_t buf) { + /* If there is an eof timer running, we don't need it any more, so discard + * it. */ + eof_timer_destroy(handle); + + uv_read_stop((uv_stream_t*) handle); + + handle->read_cb((uv_stream_t*)handle, uv_translate_sys_error(error), &buf); +} + + +static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle, + int error, uv_buf_t buf) { + if (error == ERROR_BROKEN_PIPE) { + uv_pipe_read_eof(loop, handle, buf); + } else { + uv_pipe_read_error(loop, handle, error, buf); + } +} + + +static void uv__pipe_queue_ipc_xfer_info( + uv_pipe_t* handle, + uv__ipc_socket_xfer_type_t xfer_type, + uv__ipc_socket_xfer_info_t* xfer_info) { + uv__ipc_xfer_queue_item_t* item; + + item = (uv__ipc_xfer_queue_item_t*) uv__malloc(sizeof(*item)); + if (item == NULL) + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + + item->xfer_type = xfer_type; + item->xfer_info = *xfer_info; + + QUEUE_INSERT_TAIL(&handle->pipe.conn.ipc_xfer_queue, &item->member); + handle->pipe.conn.ipc_xfer_queue_length++; +} + + +/* Read an exact number of bytes from a pipe. If an error or end-of-file is + * encountered before the requested number of bytes are read, an error is + * returned. */ +static int uv__pipe_read_exactly(HANDLE h, void* buffer, DWORD count) { + DWORD bytes_read, bytes_read_now; + + bytes_read = 0; + while (bytes_read < count) { + if (!ReadFile(h, + (char*) buffer + bytes_read, + count - bytes_read, + &bytes_read_now, + NULL)) { + return GetLastError(); + } + + bytes_read += bytes_read_now; + } + + assert(bytes_read == count); + return 0; +} + + +static DWORD uv__pipe_read_data(uv_loop_t* loop, + uv_pipe_t* handle, + DWORD suggested_bytes, + DWORD max_bytes) { + DWORD bytes_read; + uv_buf_t buf; + + /* Ask the user for a buffer to read data into. */ + buf = uv_buf_init(NULL, 0); + handle->alloc_cb((uv_handle_t*) handle, suggested_bytes, &buf); + if (buf.base == NULL || buf.len == 0) { + handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf); + return 0; /* Break out of read loop. */ + } + + /* Ensure we read at most the smaller of: + * (a) the length of the user-allocated buffer. + * (b) the maximum data length as specified by the `max_bytes` argument. + */ + if (max_bytes > buf.len) + max_bytes = buf.len; + + /* Read into the user buffer. */ + if (!ReadFile(handle->handle, buf.base, max_bytes, &bytes_read, NULL)) { + uv_pipe_read_error_or_eof(loop, handle, GetLastError(), buf); + return 0; /* Break out of read loop. */ + } + + /* Call the read callback. */ + handle->read_cb((uv_stream_t*) handle, bytes_read, &buf); + + return bytes_read; +} + + +static DWORD uv__pipe_read_ipc(uv_loop_t* loop, uv_pipe_t* handle) { + uint32_t* data_remaining = &handle->pipe.conn.ipc_data_frame.payload_remaining; + int err; + + if (*data_remaining > 0) { + /* Read frame data payload. */ + DWORD bytes_read = + uv__pipe_read_data(loop, handle, *data_remaining, *data_remaining); + *data_remaining -= bytes_read; + return bytes_read; + + } else { + /* Start of a new IPC frame. */ + uv__ipc_frame_header_t frame_header; + uint32_t xfer_flags; + uv__ipc_socket_xfer_type_t xfer_type; + uv__ipc_socket_xfer_info_t xfer_info; + + /* Read the IPC frame header. */ + err = uv__pipe_read_exactly( + handle->handle, &frame_header, sizeof frame_header); + if (err) + goto error; + + /* Validate that flags are valid. */ + if ((frame_header.flags & ~UV__IPC_FRAME_VALID_FLAGS) != 0) + goto invalid; + /* Validate that reserved2 is zero. */ + if (frame_header.reserved2 != 0) + goto invalid; + + /* Parse xfer flags. */ + xfer_flags = frame_header.flags & UV__IPC_FRAME_XFER_FLAGS; + if (xfer_flags & UV__IPC_FRAME_HAS_SOCKET_XFER) { + /* Socket coming -- determine the type. */ + xfer_type = xfer_flags & UV__IPC_FRAME_XFER_IS_TCP_CONNECTION + ? UV__IPC_SOCKET_XFER_TCP_CONNECTION + : UV__IPC_SOCKET_XFER_TCP_SERVER; + } else if (xfer_flags == 0) { + /* No socket. */ + xfer_type = UV__IPC_SOCKET_XFER_NONE; + } else { + /* Invalid flags. */ + goto invalid; + } + + /* Parse data frame information. */ + if (frame_header.flags & UV__IPC_FRAME_HAS_DATA) { + *data_remaining = frame_header.data_length; + } else if (frame_header.data_length != 0) { + /* Data length greater than zero but data flag not set -- invalid. */ + goto invalid; + } + + /* If no socket xfer info follows, return here. Data will be read in a + * subsequent invocation of uv__pipe_read_ipc(). */ + if (xfer_type == UV__IPC_SOCKET_XFER_NONE) + return sizeof frame_header; /* Number of bytes read. */ + + /* Read transferred socket information. */ + err = uv__pipe_read_exactly(handle->handle, &xfer_info, sizeof xfer_info); + if (err) + goto error; + + /* Store the pending socket info. */ + uv__pipe_queue_ipc_xfer_info(handle, xfer_type, &xfer_info); + + /* Return number of bytes read. */ + return sizeof frame_header + sizeof xfer_info; + } + +invalid: + /* Invalid frame. */ + err = WSAECONNABORTED; /* Maps to UV_ECONNABORTED. */ + +error: + uv_pipe_read_error_or_eof(loop, handle, err, uv_null_buf_); + return 0; /* Break out of read loop. */ +} + + +void uv_process_pipe_read_req(uv_loop_t* loop, + uv_pipe_t* handle, + uv_req_t* req) { + assert(handle->type == UV_NAMED_PIPE); + + handle->flags &= ~(UV_HANDLE_READ_PENDING | UV_HANDLE_CANCELLATION_PENDING); + DECREASE_PENDING_REQ_COUNT(handle); + eof_timer_stop(handle); + + /* At this point, we're done with bookkeeping. If the user has stopped + * reading the pipe in the meantime, there is nothing left to do, since there + * is no callback that we can call. */ + if (!(handle->flags & UV_HANDLE_READING)) + return; + + if (!REQ_SUCCESS(req)) { + /* An error occurred doing the zero-read. */ + DWORD err = GET_REQ_ERROR(req); + + /* If the read was cancelled by uv__pipe_interrupt_read(), the request may + * indicate an ERROR_OPERATION_ABORTED error. This error isn't relevant to + * the user; we'll start a new zero-read at the end of this function. */ + if (err != ERROR_OPERATION_ABORTED) + uv_pipe_read_error_or_eof(loop, handle, err, uv_null_buf_); + + } else { + /* The zero-read completed without error, indicating there is data + * available in the kernel buffer. */ + DWORD avail; + + /* Get the number of bytes available. */ + avail = 0; + if (!PeekNamedPipe(handle->handle, NULL, 0, NULL, &avail, NULL)) + uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_); + + /* Read until we've either read all the bytes available, or the 'reading' + * flag is cleared. */ + while (avail > 0 && handle->flags & UV_HANDLE_READING) { + /* Depending on the type of pipe, read either IPC frames or raw data. */ + DWORD bytes_read = + handle->ipc ? uv__pipe_read_ipc(loop, handle) + : uv__pipe_read_data(loop, handle, avail, (DWORD) -1); + + /* If no bytes were read, treat this as an indication that an error + * occurred, and break out of the read loop. */ + if (bytes_read == 0) + break; + + /* It is possible that more bytes were read than we thought were + * available. To prevent `avail` from underflowing, break out of the loop + * if this is the case. */ + if (bytes_read > avail) + break; + + /* Recompute the number of bytes available. */ + avail -= bytes_read; + } + } + + /* Start another zero-read request if necessary. */ + if ((handle->flags & UV_HANDLE_READING) && + !(handle->flags & UV_HANDLE_READ_PENDING)) { + uv_pipe_queue_read(loop, handle); + } +} + + +void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle, + uv_write_t* req) { + int err; + + assert(handle->type == UV_NAMED_PIPE); + + assert(handle->write_queue_size >= req->u.io.queued_bytes); + handle->write_queue_size -= req->u.io.queued_bytes; + + UNREGISTER_HANDLE_REQ(loop, handle, req); + + if (handle->flags & UV_HANDLE_EMULATE_IOCP) { + if (req->wait_handle != INVALID_HANDLE_VALUE) { + UnregisterWait(req->wait_handle); + req->wait_handle = INVALID_HANDLE_VALUE; + } + if (req->event_handle) { + CloseHandle(req->event_handle); + req->event_handle = NULL; + } + } + + err = GET_REQ_ERROR(req); + + /* If this was a coalesced write, extract pointer to the user_provided + * uv_write_t structure so we can pass the expected pointer to the callback, + * then free the heap-allocated write req. */ + if (req->coalesced) { + uv__coalesced_write_t* coalesced_write = + container_of(req, uv__coalesced_write_t, req); + req = coalesced_write->user_req; + uv__free(coalesced_write); + } + if (req->cb) { + req->cb(req, uv_translate_sys_error(err)); + } + + handle->stream.conn.write_reqs_pending--; + + if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE && + handle->pipe.conn.non_overlapped_writes_tail) { + assert(handle->stream.conn.write_reqs_pending > 0); + uv_queue_non_overlapped_write(handle); + } + + if (handle->stream.conn.shutdown_req != NULL && + handle->stream.conn.write_reqs_pending == 0) { + uv_want_endgame(loop, (uv_handle_t*)handle); + } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle, + uv_req_t* raw_req) { + uv_pipe_accept_t* req = (uv_pipe_accept_t*) raw_req; + + assert(handle->type == UV_NAMED_PIPE); + + if (handle->flags & UV_HANDLE_CLOSING) { + /* The req->pipeHandle should be freed already in uv_pipe_cleanup(). */ + assert(req->pipeHandle == INVALID_HANDLE_VALUE); + DECREASE_PENDING_REQ_COUNT(handle); + return; + } + + if (REQ_SUCCESS(req)) { + assert(req->pipeHandle != INVALID_HANDLE_VALUE); + req->next_pending = handle->pipe.serv.pending_accepts; + handle->pipe.serv.pending_accepts = req; + + if (handle->stream.serv.connection_cb) { + handle->stream.serv.connection_cb((uv_stream_t*)handle, 0); + } + } else { + if (req->pipeHandle != INVALID_HANDLE_VALUE) { + CloseHandle(req->pipeHandle); + req->pipeHandle = INVALID_HANDLE_VALUE; + } + if (!(handle->flags & UV_HANDLE_CLOSING)) { + uv_pipe_queue_accept(loop, handle, req, FALSE); + } + } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle, + uv_connect_t* req) { + int err; + + assert(handle->type == UV_NAMED_PIPE); + + UNREGISTER_HANDLE_REQ(loop, handle, req); + + if (req->cb) { + err = 0; + if (REQ_SUCCESS(req)) { + uv_pipe_connection_init(handle); + } else { + err = GET_REQ_ERROR(req); + } + req->cb(req, uv_translate_sys_error(err)); + } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle, + uv_shutdown_t* req) { + assert(handle->type == UV_NAMED_PIPE); + + UNREGISTER_HANDLE_REQ(loop, handle, req); + + if (handle->flags & UV_HANDLE_READABLE) { + /* Initialize and optionally start the eof timer. Only do this if the pipe + * is readable and we haven't seen EOF come in ourselves. */ + eof_timer_init(handle); + + /* If reading start the timer right now. Otherwise uv_pipe_queue_read will + * start it. */ + if (handle->flags & UV_HANDLE_READ_PENDING) { + eof_timer_start(handle); + } + + } else { + /* This pipe is not readable. We can just close it to let the other end + * know that we're done writing. */ + close_pipe(handle); + } + + if (req->cb) { + req->cb(req, 0); + } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +static void eof_timer_init(uv_pipe_t* pipe) { + int r; + + assert(pipe->pipe.conn.eof_timer == NULL); + assert(pipe->flags & UV_HANDLE_CONNECTION); + + pipe->pipe.conn.eof_timer = (uv_timer_t*) uv__malloc(sizeof *pipe->pipe.conn.eof_timer); + + r = uv_timer_init(pipe->loop, pipe->pipe.conn.eof_timer); + assert(r == 0); /* timers can't fail */ + pipe->pipe.conn.eof_timer->data = pipe; + uv_unref((uv_handle_t*) pipe->pipe.conn.eof_timer); +} + + +static void eof_timer_start(uv_pipe_t* pipe) { + assert(pipe->flags & UV_HANDLE_CONNECTION); + + if (pipe->pipe.conn.eof_timer != NULL) { + uv_timer_start(pipe->pipe.conn.eof_timer, eof_timer_cb, eof_timeout, 0); + } +} + + +static void eof_timer_stop(uv_pipe_t* pipe) { + assert(pipe->flags & UV_HANDLE_CONNECTION); + + if (pipe->pipe.conn.eof_timer != NULL) { + uv_timer_stop(pipe->pipe.conn.eof_timer); + } +} + + +static void eof_timer_cb(uv_timer_t* timer) { + uv_pipe_t* pipe = (uv_pipe_t*) timer->data; + uv_loop_t* loop = timer->loop; + + assert(pipe->type == UV_NAMED_PIPE); + + /* This should always be true, since we start the timer only in + * uv_pipe_queue_read after successfully calling ReadFile, or in + * uv_process_pipe_shutdown_req if a read is pending, and we always + * immediately stop the timer in uv_process_pipe_read_req. */ + assert(pipe->flags & UV_HANDLE_READ_PENDING); + + /* If there are many packets coming off the iocp then the timer callback may + * be called before the read request is coming off the queue. Therefore we + * check here if the read request has completed but will be processed later. + */ + if ((pipe->flags & UV_HANDLE_READ_PENDING) && + HasOverlappedIoCompleted(&pipe->read_req.u.io.overlapped)) { + return; + } + + /* Force both ends off the pipe. */ + close_pipe(pipe); + + /* Stop reading, so the pending read that is going to fail will not be + * reported to the user. */ + uv_read_stop((uv_stream_t*) pipe); + + /* Report the eof and update flags. This will get reported even if the user + * stopped reading in the meantime. TODO: is that okay? */ + uv_pipe_read_eof(loop, pipe, uv_null_buf_); +} + + +static void eof_timer_destroy(uv_pipe_t* pipe) { + assert(pipe->flags & UV_HANDLE_CONNECTION); + + if (pipe->pipe.conn.eof_timer) { + uv_close((uv_handle_t*) pipe->pipe.conn.eof_timer, eof_timer_close_cb); + pipe->pipe.conn.eof_timer = NULL; + } +} + + +static void eof_timer_close_cb(uv_handle_t* handle) { + assert(handle->type == UV_TIMER); + uv__free(handle); +} + + +int uv_pipe_open(uv_pipe_t* pipe, uv_file file) { + HANDLE os_handle = uv__get_osfhandle(file); + NTSTATUS nt_status; + IO_STATUS_BLOCK io_status; + FILE_ACCESS_INFORMATION access; + DWORD duplex_flags = 0; + + if (os_handle == INVALID_HANDLE_VALUE) + return UV_EBADF; + + uv__once_init(); + /* In order to avoid closing a stdio file descriptor 0-2, duplicate the + * underlying OS handle and forget about the original fd. + * We could also opt to use the original OS handle and just never close it, + * but then there would be no reliable way to cancel pending read operations + * upon close. + */ + if (file <= 2) { + if (!DuplicateHandle(INVALID_HANDLE_VALUE, + os_handle, + INVALID_HANDLE_VALUE, + &os_handle, + 0, + FALSE, + DUPLICATE_SAME_ACCESS)) + return uv_translate_sys_error(GetLastError()); + file = -1; + } + + /* Determine what kind of permissions we have on this handle. + * Cygwin opens the pipe in message mode, but we can support it, + * just query the access flags and set the stream flags accordingly. + */ + nt_status = pNtQueryInformationFile(os_handle, + &io_status, + &access, + sizeof(access), + FileAccessInformation); + if (nt_status != STATUS_SUCCESS) + return UV_EINVAL; + + if (pipe->ipc) { + if (!(access.AccessFlags & FILE_WRITE_DATA) || + !(access.AccessFlags & FILE_READ_DATA)) { + return UV_EINVAL; + } + } + + if (access.AccessFlags & FILE_WRITE_DATA) + duplex_flags |= UV_HANDLE_WRITABLE; + if (access.AccessFlags & FILE_READ_DATA) + duplex_flags |= UV_HANDLE_READABLE; + + if (os_handle == INVALID_HANDLE_VALUE || + uv_set_pipe_handle(pipe->loop, + pipe, + os_handle, + file, + duplex_flags) == -1) { + return UV_EINVAL; + } + + uv_pipe_connection_init(pipe); + + if (pipe->ipc) { + assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE)); + pipe->pipe.conn.ipc_remote_pid = uv_os_getppid(); + assert(pipe->pipe.conn.ipc_remote_pid != (DWORD)(uv_pid_t) -1); + } + return 0; +} + + +static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) { + NTSTATUS nt_status; + IO_STATUS_BLOCK io_status; + FILE_NAME_INFORMATION tmp_name_info; + FILE_NAME_INFORMATION* name_info; + WCHAR* name_buf; + unsigned int addrlen; + unsigned int name_size; + unsigned int name_len; + int err; + + uv__once_init(); + name_info = NULL; + + if (handle->handle == INVALID_HANDLE_VALUE) { + *size = 0; + return UV_EINVAL; + } + + /* NtQueryInformationFile will block if another thread is performing a + * blocking operation on the queried handle. If the pipe handle is + * synchronous, there may be a worker thread currently calling ReadFile() on + * the pipe handle, which could cause a deadlock. To avoid this, interrupt + * the read. */ + if (handle->flags & UV_HANDLE_CONNECTION && + handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) { + uv__pipe_interrupt_read((uv_pipe_t*) handle); /* cast away const warning */ + } + + nt_status = pNtQueryInformationFile(handle->handle, + &io_status, + &tmp_name_info, + sizeof tmp_name_info, + FileNameInformation); + if (nt_status == STATUS_BUFFER_OVERFLOW) { + name_size = sizeof(*name_info) + tmp_name_info.FileNameLength; + name_info = uv__malloc(name_size); + if (!name_info) { + *size = 0; + err = UV_ENOMEM; + goto cleanup; + } + + nt_status = pNtQueryInformationFile(handle->handle, + &io_status, + name_info, + name_size, + FileNameInformation); + } + + if (nt_status != STATUS_SUCCESS) { + *size = 0; + err = uv_translate_sys_error(pRtlNtStatusToDosError(nt_status)); + goto error; + } + + if (!name_info) { + /* the struct on stack was used */ + name_buf = tmp_name_info.FileName; + name_len = tmp_name_info.FileNameLength; + } else { + name_buf = name_info->FileName; + name_len = name_info->FileNameLength; + } + + if (name_len == 0) { + *size = 0; + err = 0; + goto error; + } + + name_len /= sizeof(WCHAR); + + /* check how much space we need */ + addrlen = WideCharToMultiByte(CP_UTF8, + 0, + name_buf, + name_len, + NULL, + 0, + NULL, + NULL); + if (!addrlen) { + *size = 0; + err = uv_translate_sys_error(GetLastError()); + goto error; + } else if (pipe_prefix_len + addrlen >= *size) { + /* "\\\\.\\pipe" + name */ + *size = pipe_prefix_len + addrlen + 1; + err = UV_ENOBUFS; + goto error; + } + + memcpy(buffer, pipe_prefix, pipe_prefix_len); + addrlen = WideCharToMultiByte(CP_UTF8, + 0, + name_buf, + name_len, + buffer+pipe_prefix_len, + *size-pipe_prefix_len, + NULL, + NULL); + if (!addrlen) { + *size = 0; + err = uv_translate_sys_error(GetLastError()); + goto error; + } + + addrlen += pipe_prefix_len; + *size = addrlen; + buffer[addrlen] = '\0'; + + err = 0; + +error: + uv__free(name_info); + +cleanup: + return err; +} + + +int uv_pipe_pending_count(uv_pipe_t* handle) { + if (!handle->ipc) + return 0; + return handle->pipe.conn.ipc_xfer_queue_length; +} + + +int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) { + if (handle->flags & UV_HANDLE_BOUND) + return uv__pipe_getname(handle, buffer, size); + + if (handle->flags & UV_HANDLE_CONNECTION || + handle->handle != INVALID_HANDLE_VALUE) { + *size = 0; + return 0; + } + + return UV_EBADF; +} + + +int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) { + /* emulate unix behaviour */ + if (handle->flags & UV_HANDLE_BOUND) + return UV_ENOTCONN; + + if (handle->handle != INVALID_HANDLE_VALUE) + return uv__pipe_getname(handle, buffer, size); + + return UV_EBADF; +} + + +uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) { + if (!handle->ipc) + return UV_UNKNOWN_HANDLE; + if (handle->pipe.conn.ipc_xfer_queue_length == 0) + return UV_UNKNOWN_HANDLE; + else + return UV_TCP; +} + +int uv_pipe_chmod(uv_pipe_t* handle, int mode) { + SID_IDENTIFIER_AUTHORITY sid_world = { SECURITY_WORLD_SID_AUTHORITY }; + PACL old_dacl, new_dacl; + PSECURITY_DESCRIPTOR sd; + EXPLICIT_ACCESS ea; + PSID everyone; + int error; + + if (handle == NULL || handle->handle == INVALID_HANDLE_VALUE) + return UV_EBADF; + + if (mode != UV_READABLE && + mode != UV_WRITABLE && + mode != (UV_WRITABLE | UV_READABLE)) + return UV_EINVAL; + + if (!AllocateAndInitializeSid(&sid_world, + 1, + SECURITY_WORLD_RID, + 0, 0, 0, 0, 0, 0, 0, + &everyone)) { + error = GetLastError(); + goto done; + } + + if (GetSecurityInfo(handle->handle, + SE_KERNEL_OBJECT, + DACL_SECURITY_INFORMATION, + NULL, + NULL, + &old_dacl, + NULL, + &sd)) { + error = GetLastError(); + goto clean_sid; + } + + memset(&ea, 0, sizeof(EXPLICIT_ACCESS)); + if (mode & UV_READABLE) + ea.grfAccessPermissions |= GENERIC_READ | FILE_WRITE_ATTRIBUTES; + if (mode & UV_WRITABLE) + ea.grfAccessPermissions |= GENERIC_WRITE | FILE_READ_ATTRIBUTES; + ea.grfAccessPermissions |= SYNCHRONIZE; + ea.grfAccessMode = SET_ACCESS; + ea.grfInheritance = NO_INHERITANCE; + ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; + ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; + ea.Trustee.ptstrName = (LPTSTR)everyone; + + if (SetEntriesInAcl(1, &ea, old_dacl, &new_dacl)) { + error = GetLastError(); + goto clean_sd; + } + + if (SetSecurityInfo(handle->handle, + SE_KERNEL_OBJECT, + DACL_SECURITY_INFORMATION, + NULL, + NULL, + new_dacl, + NULL)) { + error = GetLastError(); + goto clean_dacl; + } + + error = 0; + +clean_dacl: + LocalFree((HLOCAL) new_dacl); +clean_sd: + LocalFree((HLOCAL) sd); +clean_sid: + FreeSid(everyone); +done: + return uv_translate_sys_error(error); +} diff --git a/external/src/libuv/src/win/poll.c b/external/src/libuv/src/win/poll.c new file mode 100644 index 0000000..9d37759 --- /dev/null +++ b/external/src/libuv/src/win/poll.c @@ -0,0 +1,585 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include + +#include "uv.h" +#include "internal.h" +#include "handle-inl.h" +#include "req-inl.h" + + +static const GUID uv_msafd_provider_ids[UV_MSAFD_PROVIDER_COUNT] = { + {0xe70f1aa0, 0xab8b, 0x11cf, + {0x8c, 0xa3, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}, + {0xf9eab0c0, 0x26d4, 0x11d0, + {0xbb, 0xbf, 0x00, 0xaa, 0x00, 0x6c, 0x34, 0xe4}}, + {0x9fc48064, 0x7298, 0x43e4, + {0xb7, 0xbd, 0x18, 0x1f, 0x20, 0x89, 0x79, 0x2a}} +}; + +typedef struct uv_single_fd_set_s { + unsigned int fd_count; + SOCKET fd_array[1]; +} uv_single_fd_set_t; + + +static OVERLAPPED overlapped_dummy_; +static uv_once_t overlapped_dummy_init_guard_ = UV_ONCE_INIT; + +static AFD_POLL_INFO afd_poll_info_dummy_; + + +static void uv__init_overlapped_dummy(void) { + HANDLE event; + + event = CreateEvent(NULL, TRUE, TRUE, NULL); + if (event == NULL) + uv_fatal_error(GetLastError(), "CreateEvent"); + + memset(&overlapped_dummy_, 0, sizeof overlapped_dummy_); + overlapped_dummy_.hEvent = (HANDLE) ((uintptr_t) event | 1); +} + + +static OVERLAPPED* uv__get_overlapped_dummy(void) { + uv_once(&overlapped_dummy_init_guard_, uv__init_overlapped_dummy); + return &overlapped_dummy_; +} + + +static AFD_POLL_INFO* uv__get_afd_poll_info_dummy(void) { + return &afd_poll_info_dummy_; +} + + +static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) { + uv_req_t* req; + AFD_POLL_INFO* afd_poll_info; + int result; + + /* Find a yet unsubmitted req to submit. */ + if (handle->submitted_events_1 == 0) { + req = &handle->poll_req_1; + afd_poll_info = &handle->afd_poll_info_1; + handle->submitted_events_1 = handle->events; + handle->mask_events_1 = 0; + handle->mask_events_2 = handle->events; + } else if (handle->submitted_events_2 == 0) { + req = &handle->poll_req_2; + afd_poll_info = &handle->afd_poll_info_2; + handle->submitted_events_2 = handle->events; + handle->mask_events_1 = handle->events; + handle->mask_events_2 = 0; + } else { + /* Just wait until there's an unsubmitted req. This will happen almost + * immediately as one of the 2 outstanding requests is about to return. + * When this happens, uv__fast_poll_process_poll_req will be called, and + * the pending events, if needed, will be processed in a subsequent + * request. */ + return; + } + + /* Setting Exclusive to TRUE makes the other poll request return if there is + * any. */ + afd_poll_info->Exclusive = TRUE; + afd_poll_info->NumberOfHandles = 1; + afd_poll_info->Timeout.QuadPart = INT64_MAX; + afd_poll_info->Handles[0].Handle = (HANDLE) handle->socket; + afd_poll_info->Handles[0].Status = 0; + afd_poll_info->Handles[0].Events = 0; + + if (handle->events & UV_READABLE) { + afd_poll_info->Handles[0].Events |= AFD_POLL_RECEIVE | + AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT; + } else { + if (handle->events & UV_DISCONNECT) { + afd_poll_info->Handles[0].Events |= AFD_POLL_DISCONNECT; + } + } + if (handle->events & UV_WRITABLE) { + afd_poll_info->Handles[0].Events |= AFD_POLL_SEND | AFD_POLL_CONNECT_FAIL; + } + + memset(&req->u.io.overlapped, 0, sizeof req->u.io.overlapped); + + result = uv_msafd_poll((SOCKET) handle->peer_socket, + afd_poll_info, + afd_poll_info, + &req->u.io.overlapped); + if (result != 0 && WSAGetLastError() != WSA_IO_PENDING) { + /* Queue this req, reporting an error. */ + SET_REQ_ERROR(req, WSAGetLastError()); + uv_insert_pending_req(loop, req); + } +} + + +static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, + uv_req_t* req) { + unsigned char mask_events; + AFD_POLL_INFO* afd_poll_info; + + if (req == &handle->poll_req_1) { + afd_poll_info = &handle->afd_poll_info_1; + handle->submitted_events_1 = 0; + mask_events = handle->mask_events_1; + } else if (req == &handle->poll_req_2) { + afd_poll_info = &handle->afd_poll_info_2; + handle->submitted_events_2 = 0; + mask_events = handle->mask_events_2; + } else { + assert(0); + return; + } + + /* Report an error unless the select was just interrupted. */ + if (!REQ_SUCCESS(req)) { + DWORD error = GET_REQ_SOCK_ERROR(req); + if (error != WSAEINTR && handle->events != 0) { + handle->events = 0; /* Stop the watcher */ + handle->poll_cb(handle, uv_translate_sys_error(error), 0); + } + + } else if (afd_poll_info->NumberOfHandles >= 1) { + unsigned char events = 0; + + if ((afd_poll_info->Handles[0].Events & (AFD_POLL_RECEIVE | + AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT)) != 0) { + events |= UV_READABLE; + if ((afd_poll_info->Handles[0].Events & AFD_POLL_DISCONNECT) != 0) { + events |= UV_DISCONNECT; + } + } + if ((afd_poll_info->Handles[0].Events & (AFD_POLL_SEND | + AFD_POLL_CONNECT_FAIL)) != 0) { + events |= UV_WRITABLE; + } + + events &= handle->events & ~mask_events; + + if (afd_poll_info->Handles[0].Events & AFD_POLL_LOCAL_CLOSE) { + /* Stop polling. */ + handle->events = 0; + if (uv__is_active(handle)) + uv__handle_stop(handle); + } + + if (events != 0) { + handle->poll_cb(handle, 0, events); + } + } + + if ((handle->events & ~(handle->submitted_events_1 | + handle->submitted_events_2)) != 0) { + uv__fast_poll_submit_poll_req(loop, handle); + } else if ((handle->flags & UV_HANDLE_CLOSING) && + handle->submitted_events_1 == 0 && + handle->submitted_events_2 == 0) { + uv_want_endgame(loop, (uv_handle_t*) handle); + } +} + + +static SOCKET uv__fast_poll_create_peer_socket(HANDLE iocp, + WSAPROTOCOL_INFOW* protocol_info) { + SOCKET sock = 0; + + sock = WSASocketW(protocol_info->iAddressFamily, + protocol_info->iSocketType, + protocol_info->iProtocol, + protocol_info, + 0, + WSA_FLAG_OVERLAPPED); + if (sock == INVALID_SOCKET) { + return INVALID_SOCKET; + } + + if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) { + goto error; + }; + + if (CreateIoCompletionPort((HANDLE) sock, + iocp, + (ULONG_PTR) sock, + 0) == NULL) { + goto error; + } + + return sock; + + error: + closesocket(sock); + return INVALID_SOCKET; +} + + +static SOCKET uv__fast_poll_get_peer_socket(uv_loop_t* loop, + WSAPROTOCOL_INFOW* protocol_info) { + int index, i; + SOCKET peer_socket; + + index = -1; + for (i = 0; (size_t) i < ARRAY_SIZE(uv_msafd_provider_ids); i++) { + if (memcmp((void*) &protocol_info->ProviderId, + (void*) &uv_msafd_provider_ids[i], + sizeof protocol_info->ProviderId) == 0) { + index = i; + } + } + + /* Check if the protocol uses an msafd socket. */ + if (index < 0) { + return INVALID_SOCKET; + } + + /* If we didn't (try) to create a peer socket yet, try to make one. Don't try + * again if the peer socket creation failed earlier for the same protocol. */ + peer_socket = loop->poll_peer_sockets[index]; + if (peer_socket == 0) { + peer_socket = uv__fast_poll_create_peer_socket(loop->iocp, protocol_info); + loop->poll_peer_sockets[index] = peer_socket; + } + + return peer_socket; +} + + +static DWORD WINAPI uv__slow_poll_thread_proc(void* arg) { + uv_req_t* req = (uv_req_t*) arg; + uv_poll_t* handle = (uv_poll_t*) req->data; + unsigned char reported_events; + int r; + uv_single_fd_set_t rfds, wfds, efds; + struct timeval timeout; + + assert(handle->type == UV_POLL); + assert(req->type == UV_POLL_REQ); + + if (handle->events & UV_READABLE) { + rfds.fd_count = 1; + rfds.fd_array[0] = handle->socket; + } else { + rfds.fd_count = 0; + } + + if (handle->events & UV_WRITABLE) { + wfds.fd_count = 1; + wfds.fd_array[0] = handle->socket; + efds.fd_count = 1; + efds.fd_array[0] = handle->socket; + } else { + wfds.fd_count = 0; + efds.fd_count = 0; + } + + /* Make the select() time out after 3 minutes. If select() hangs because the + * user closed the socket, we will at least not hang indefinitely. */ + timeout.tv_sec = 3 * 60; + timeout.tv_usec = 0; + + r = select(1, (fd_set*) &rfds, (fd_set*) &wfds, (fd_set*) &efds, &timeout); + if (r == SOCKET_ERROR) { + /* Queue this req, reporting an error. */ + SET_REQ_ERROR(&handle->poll_req_1, WSAGetLastError()); + POST_COMPLETION_FOR_REQ(handle->loop, req); + return 0; + } + + reported_events = 0; + + if (r > 0) { + if (rfds.fd_count > 0) { + assert(rfds.fd_count == 1); + assert(rfds.fd_array[0] == handle->socket); + reported_events |= UV_READABLE; + } + + if (wfds.fd_count > 0) { + assert(wfds.fd_count == 1); + assert(wfds.fd_array[0] == handle->socket); + reported_events |= UV_WRITABLE; + } else if (efds.fd_count > 0) { + assert(efds.fd_count == 1); + assert(efds.fd_array[0] == handle->socket); + reported_events |= UV_WRITABLE; + } + } + + SET_REQ_SUCCESS(req); + req->u.io.overlapped.InternalHigh = (DWORD) reported_events; + POST_COMPLETION_FOR_REQ(handle->loop, req); + + return 0; +} + + +static void uv__slow_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) { + uv_req_t* req; + + /* Find a yet unsubmitted req to submit. */ + if (handle->submitted_events_1 == 0) { + req = &handle->poll_req_1; + handle->submitted_events_1 = handle->events; + handle->mask_events_1 = 0; + handle->mask_events_2 = handle->events; + } else if (handle->submitted_events_2 == 0) { + req = &handle->poll_req_2; + handle->submitted_events_2 = handle->events; + handle->mask_events_1 = handle->events; + handle->mask_events_2 = 0; + } else { + assert(0); + return; + } + + if (!QueueUserWorkItem(uv__slow_poll_thread_proc, + (void*) req, + WT_EXECUTELONGFUNCTION)) { + /* Make this req pending, reporting an error. */ + SET_REQ_ERROR(req, GetLastError()); + uv_insert_pending_req(loop, req); + } +} + + + +static void uv__slow_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, + uv_req_t* req) { + unsigned char mask_events; + int err; + + if (req == &handle->poll_req_1) { + handle->submitted_events_1 = 0; + mask_events = handle->mask_events_1; + } else if (req == &handle->poll_req_2) { + handle->submitted_events_2 = 0; + mask_events = handle->mask_events_2; + } else { + assert(0); + return; + } + + if (!REQ_SUCCESS(req)) { + /* Error. */ + if (handle->events != 0) { + err = GET_REQ_ERROR(req); + handle->events = 0; /* Stop the watcher */ + handle->poll_cb(handle, uv_translate_sys_error(err), 0); + } + } else { + /* Got some events. */ + int events = req->u.io.overlapped.InternalHigh & handle->events & ~mask_events; + if (events != 0) { + handle->poll_cb(handle, 0, events); + } + } + + if ((handle->events & ~(handle->submitted_events_1 | + handle->submitted_events_2)) != 0) { + uv__slow_poll_submit_poll_req(loop, handle); + } else if ((handle->flags & UV_HANDLE_CLOSING) && + handle->submitted_events_1 == 0 && + handle->submitted_events_2 == 0) { + uv_want_endgame(loop, (uv_handle_t*) handle); + } +} + + +int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) { + return uv_poll_init_socket(loop, handle, (SOCKET) uv__get_osfhandle(fd)); +} + + +int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, + uv_os_sock_t socket) { + WSAPROTOCOL_INFOW protocol_info; + int len; + SOCKET peer_socket, base_socket; + DWORD bytes; + DWORD yes = 1; + + /* Set the socket to nonblocking mode */ + if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) + return uv_translate_sys_error(WSAGetLastError()); + +/* Try to obtain a base handle for the socket. This increases this chances that + * we find an AFD handle and are able to use the fast poll mechanism. This will + * always fail on windows XP/2k3, since they don't support the. SIO_BASE_HANDLE + * ioctl. */ +#ifndef NDEBUG + base_socket = INVALID_SOCKET; +#endif + + if (WSAIoctl(socket, + SIO_BASE_HANDLE, + NULL, + 0, + &base_socket, + sizeof base_socket, + &bytes, + NULL, + NULL) == 0) { + assert(base_socket != 0 && base_socket != INVALID_SOCKET); + socket = base_socket; + } + + uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL); + handle->socket = socket; + handle->events = 0; + + /* Obtain protocol information about the socket. */ + len = sizeof protocol_info; + if (getsockopt(socket, + SOL_SOCKET, + SO_PROTOCOL_INFOW, + (char*) &protocol_info, + &len) != 0) { + return uv_translate_sys_error(WSAGetLastError()); + } + + /* Get the peer socket that is needed to enable fast poll. If the returned + * value is NULL, the protocol is not implemented by MSAFD and we'll have to + * use slow mode. */ + peer_socket = uv__fast_poll_get_peer_socket(loop, &protocol_info); + + if (peer_socket != INVALID_SOCKET) { + /* Initialize fast poll specific fields. */ + handle->peer_socket = peer_socket; + } else { + /* Initialize slow poll specific fields. */ + handle->flags |= UV_HANDLE_POLL_SLOW; + } + + /* Initialize 2 poll reqs. */ + handle->submitted_events_1 = 0; + UV_REQ_INIT(&handle->poll_req_1, UV_POLL_REQ); + handle->poll_req_1.data = handle; + + handle->submitted_events_2 = 0; + UV_REQ_INIT(&handle->poll_req_2, UV_POLL_REQ); + handle->poll_req_2.data = handle; + + return 0; +} + + +static int uv__poll_set(uv_poll_t* handle, int events, uv_poll_cb cb) { + int submitted_events; + + assert(handle->type == UV_POLL); + assert(!(handle->flags & UV_HANDLE_CLOSING)); + assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT | + UV_PRIORITIZED)) == 0); + + handle->events = events; + handle->poll_cb = cb; + + if (handle->events == 0) { + uv__handle_stop(handle); + return 0; + } + + uv__handle_start(handle); + submitted_events = handle->submitted_events_1 | handle->submitted_events_2; + + if (handle->events & ~submitted_events) { + if (handle->flags & UV_HANDLE_POLL_SLOW) { + uv__slow_poll_submit_poll_req(handle->loop, handle); + } else { + uv__fast_poll_submit_poll_req(handle->loop, handle); + } + } + + return 0; +} + + +int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) { + return uv__poll_set(handle, events, cb); +} + + +int uv_poll_stop(uv_poll_t* handle) { + return uv__poll_set(handle, 0, handle->poll_cb); +} + + +void uv_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, uv_req_t* req) { + if (!(handle->flags & UV_HANDLE_POLL_SLOW)) { + uv__fast_poll_process_poll_req(loop, handle, req); + } else { + uv__slow_poll_process_poll_req(loop, handle, req); + } +} + + +int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle) { + AFD_POLL_INFO afd_poll_info; + DWORD error; + int result; + + handle->events = 0; + uv__handle_closing(handle); + + if (handle->submitted_events_1 == 0 && + handle->submitted_events_2 == 0) { + uv_want_endgame(loop, (uv_handle_t*) handle); + return 0; + } + + if (handle->flags & UV_HANDLE_POLL_SLOW) + return 0; + + /* Cancel outstanding poll requests by executing another, unique poll + * request that forces the outstanding ones to return. */ + afd_poll_info.Exclusive = TRUE; + afd_poll_info.NumberOfHandles = 1; + afd_poll_info.Timeout.QuadPart = INT64_MAX; + afd_poll_info.Handles[0].Handle = (HANDLE) handle->socket; + afd_poll_info.Handles[0].Status = 0; + afd_poll_info.Handles[0].Events = AFD_POLL_ALL; + + result = uv_msafd_poll(handle->socket, + &afd_poll_info, + uv__get_afd_poll_info_dummy(), + uv__get_overlapped_dummy()); + + if (result == SOCKET_ERROR) { + error = WSAGetLastError(); + if (error != WSA_IO_PENDING) + return uv_translate_sys_error(error); + } + + return 0; +} + + +void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle) { + assert(handle->flags & UV_HANDLE_CLOSING); + assert(!(handle->flags & UV_HANDLE_CLOSED)); + + assert(handle->submitted_events_1 == 0); + assert(handle->submitted_events_2 == 0); + + uv__handle_close(handle); +} diff --git a/external/src/libuv/src/win/process-stdio.c b/external/src/libuv/src/win/process-stdio.c new file mode 100644 index 0000000..0db3572 --- /dev/null +++ b/external/src/libuv/src/win/process-stdio.c @@ -0,0 +1,416 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#include "uv.h" +#include "internal.h" +#include "handle-inl.h" + + +/* + * The `child_stdio_buffer` buffer has the following layout: + * int number_of_fds + * unsigned char crt_flags[number_of_fds] + * HANDLE os_handle[number_of_fds] + */ +#define CHILD_STDIO_SIZE(count) \ + (sizeof(int) + \ + sizeof(unsigned char) * (count) + \ + sizeof(uintptr_t) * (count)) + +#define CHILD_STDIO_COUNT(buffer) \ + *((unsigned int*) (buffer)) + +#define CHILD_STDIO_CRT_FLAGS(buffer, fd) \ + *((unsigned char*) (buffer) + sizeof(int) + fd) + +#define CHILD_STDIO_HANDLE(buffer, fd) \ + *((HANDLE*) ((unsigned char*) (buffer) + \ + sizeof(int) + \ + sizeof(unsigned char) * \ + CHILD_STDIO_COUNT((buffer)) + \ + sizeof(HANDLE) * (fd))) + + +/* CRT file descriptor mode flags */ +#define FOPEN 0x01 +#define FEOFLAG 0x02 +#define FCRLF 0x04 +#define FPIPE 0x08 +#define FNOINHERIT 0x10 +#define FAPPEND 0x20 +#define FDEV 0x40 +#define FTEXT 0x80 + + +/* + * Clear the HANDLE_FLAG_INHERIT flag from all HANDLEs that were inherited + * the parent process. Don't check for errors - the stdio handles may not be + * valid, or may be closed already. There is no guarantee that this function + * does a perfect job. + */ +void uv_disable_stdio_inheritance(void) { + HANDLE handle; + STARTUPINFOW si; + + /* Make the windows stdio handles non-inheritable. */ + handle = GetStdHandle(STD_INPUT_HANDLE); + if (handle != NULL && handle != INVALID_HANDLE_VALUE) + SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); + + handle = GetStdHandle(STD_OUTPUT_HANDLE); + if (handle != NULL && handle != INVALID_HANDLE_VALUE) + SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); + + handle = GetStdHandle(STD_ERROR_HANDLE); + if (handle != NULL && handle != INVALID_HANDLE_VALUE) + SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); + + /* Make inherited CRT FDs non-inheritable. */ + GetStartupInfoW(&si); + if (uv__stdio_verify(si.lpReserved2, si.cbReserved2)) + uv__stdio_noinherit(si.lpReserved2); +} + + +static int uv__duplicate_handle(uv_loop_t* loop, HANDLE handle, HANDLE* dup) { + HANDLE current_process; + + + /* _get_osfhandle will sometimes return -2 in case of an error. This seems to + * happen when fd <= 2 and the process' corresponding stdio handle is set to + * NULL. Unfortunately DuplicateHandle will happily duplicate (HANDLE) -2, so + * this situation goes unnoticed until someone tries to use the duplicate. + * Therefore we filter out known-invalid handles here. */ + if (handle == INVALID_HANDLE_VALUE || + handle == NULL || + handle == (HANDLE) -2) { + *dup = INVALID_HANDLE_VALUE; + return ERROR_INVALID_HANDLE; + } + + current_process = GetCurrentProcess(); + + if (!DuplicateHandle(current_process, + handle, + current_process, + dup, + 0, + TRUE, + DUPLICATE_SAME_ACCESS)) { + *dup = INVALID_HANDLE_VALUE; + return GetLastError(); + } + + return 0; +} + + +static int uv__duplicate_fd(uv_loop_t* loop, int fd, HANDLE* dup) { + HANDLE handle; + + if (fd == -1) { + *dup = INVALID_HANDLE_VALUE; + return ERROR_INVALID_HANDLE; + } + + handle = uv__get_osfhandle(fd); + return uv__duplicate_handle(loop, handle, dup); +} + + +int uv__create_nul_handle(HANDLE* handle_ptr, + DWORD access) { + HANDLE handle; + SECURITY_ATTRIBUTES sa; + + sa.nLength = sizeof sa; + sa.lpSecurityDescriptor = NULL; + sa.bInheritHandle = TRUE; + + handle = CreateFileW(L"NUL", + access, + FILE_SHARE_READ | FILE_SHARE_WRITE, + &sa, + OPEN_EXISTING, + 0, + NULL); + if (handle == INVALID_HANDLE_VALUE) { + return GetLastError(); + } + + *handle_ptr = handle; + return 0; +} + + +int uv__stdio_create(uv_loop_t* loop, + const uv_process_options_t* options, + BYTE** buffer_ptr) { + BYTE* buffer; + int count, i; + int err; + + count = options->stdio_count; + + if (count < 0 || count > 255) { + /* Only support FDs 0-255 */ + return ERROR_NOT_SUPPORTED; + } else if (count < 3) { + /* There should always be at least 3 stdio handles. */ + count = 3; + } + + /* Allocate the child stdio buffer */ + buffer = (BYTE*) uv__malloc(CHILD_STDIO_SIZE(count)); + if (buffer == NULL) { + return ERROR_OUTOFMEMORY; + } + + /* Prepopulate the buffer with INVALID_HANDLE_VALUE handles so we can clean + * up on failure. */ + CHILD_STDIO_COUNT(buffer) = count; + for (i = 0; i < count; i++) { + CHILD_STDIO_CRT_FLAGS(buffer, i) = 0; + CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE; + } + + for (i = 0; i < count; i++) { + uv_stdio_container_t fdopt; + if (i < options->stdio_count) { + fdopt = options->stdio[i]; + } else { + fdopt.flags = UV_IGNORE; + } + + switch (fdopt.flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | + UV_INHERIT_STREAM)) { + case UV_IGNORE: + /* Starting a process with no stdin/stout/stderr can confuse it. So no + * matter what the user specified, we make sure the first three FDs are + * always open in their typical modes, e. g. stdin be readable and + * stdout/err should be writable. For FDs > 2, don't do anything - all + * handles in the stdio buffer are initialized with. + * INVALID_HANDLE_VALUE, which should be okay. */ + if (i <= 2) { + DWORD access = (i == 0) ? FILE_GENERIC_READ : + FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES; + + err = uv__create_nul_handle(&CHILD_STDIO_HANDLE(buffer, i), + access); + if (err) + goto error; + + CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV; + } + break; + + case UV_CREATE_PIPE: { + /* Create a pair of two connected pipe ends; one end is turned into an + * uv_pipe_t for use by the parent. The other one is given to the + * child. */ + uv_pipe_t* parent_pipe = (uv_pipe_t*) fdopt.data.stream; + HANDLE child_pipe = INVALID_HANDLE_VALUE; + + /* Create a new, connected pipe pair. stdio[i]. stream should point to + * an uninitialized, but not connected pipe handle. */ + assert(fdopt.data.stream->type == UV_NAMED_PIPE); + assert(!(fdopt.data.stream->flags & UV_HANDLE_CONNECTION)); + assert(!(fdopt.data.stream->flags & UV_HANDLE_PIPESERVER)); + + err = uv__create_stdio_pipe_pair(loop, + parent_pipe, + &child_pipe, + fdopt.flags); + if (err) + goto error; + + CHILD_STDIO_HANDLE(buffer, i) = child_pipe; + CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE; + break; + } + + case UV_INHERIT_FD: { + /* Inherit a raw FD. */ + HANDLE child_handle; + + /* Make an inheritable duplicate of the handle. */ + err = uv__duplicate_fd(loop, fdopt.data.fd, &child_handle); + if (err) { + /* If fdopt. data. fd is not valid and fd <= 2, then ignore the + * error. */ + if (fdopt.data.fd <= 2 && err == ERROR_INVALID_HANDLE) { + CHILD_STDIO_CRT_FLAGS(buffer, i) = 0; + CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE; + break; + } + goto error; + } + + /* Figure out what the type is. */ + switch (GetFileType(child_handle)) { + case FILE_TYPE_DISK: + CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN; + break; + + case FILE_TYPE_PIPE: + CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE; + break; + + case FILE_TYPE_CHAR: + case FILE_TYPE_REMOTE: + CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV; + break; + + case FILE_TYPE_UNKNOWN: + if (GetLastError() != 0) { + err = GetLastError(); + CloseHandle(child_handle); + goto error; + } + CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV; + break; + + default: + assert(0); + return -1; + } + + CHILD_STDIO_HANDLE(buffer, i) = child_handle; + break; + } + + case UV_INHERIT_STREAM: { + /* Use an existing stream as the stdio handle for the child. */ + HANDLE stream_handle, child_handle; + unsigned char crt_flags; + uv_stream_t* stream = fdopt.data.stream; + + /* Leech the handle out of the stream. */ + if (stream->type == UV_TTY) { + stream_handle = ((uv_tty_t*) stream)->handle; + crt_flags = FOPEN | FDEV; + } else if (stream->type == UV_NAMED_PIPE && + stream->flags & UV_HANDLE_CONNECTION) { + stream_handle = ((uv_pipe_t*) stream)->handle; + crt_flags = FOPEN | FPIPE; + } else { + stream_handle = INVALID_HANDLE_VALUE; + crt_flags = 0; + } + + if (stream_handle == NULL || + stream_handle == INVALID_HANDLE_VALUE) { + /* The handle is already closed, or not yet created, or the stream + * type is not supported. */ + err = ERROR_NOT_SUPPORTED; + goto error; + } + + /* Make an inheritable copy of the handle. */ + err = uv__duplicate_handle(loop, stream_handle, &child_handle); + if (err) + goto error; + + CHILD_STDIO_HANDLE(buffer, i) = child_handle; + CHILD_STDIO_CRT_FLAGS(buffer, i) = crt_flags; + break; + } + + default: + assert(0); + return -1; + } + } + + *buffer_ptr = buffer; + return 0; + + error: + uv__stdio_destroy(buffer); + return err; +} + + +void uv__stdio_destroy(BYTE* buffer) { + int i, count; + + count = CHILD_STDIO_COUNT(buffer); + for (i = 0; i < count; i++) { + HANDLE handle = CHILD_STDIO_HANDLE(buffer, i); + if (handle != INVALID_HANDLE_VALUE) { + CloseHandle(handle); + } + } + + uv__free(buffer); +} + + +void uv__stdio_noinherit(BYTE* buffer) { + int i, count; + + count = CHILD_STDIO_COUNT(buffer); + for (i = 0; i < count; i++) { + HANDLE handle = CHILD_STDIO_HANDLE(buffer, i); + if (handle != INVALID_HANDLE_VALUE) { + SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); + } + } +} + + +int uv__stdio_verify(BYTE* buffer, WORD size) { + unsigned int count; + + /* Check the buffer pointer. */ + if (buffer == NULL) + return 0; + + /* Verify that the buffer is at least big enough to hold the count. */ + if (size < CHILD_STDIO_SIZE(0)) + return 0; + + /* Verify if the count is within range. */ + count = CHILD_STDIO_COUNT(buffer); + if (count > 256) + return 0; + + /* Verify that the buffer size is big enough to hold info for N FDs. */ + if (size < CHILD_STDIO_SIZE(count)) + return 0; + + return 1; +} + + +WORD uv__stdio_size(BYTE* buffer) { + return (WORD) CHILD_STDIO_SIZE(CHILD_STDIO_COUNT((buffer))); +} + + +HANDLE uv__stdio_handle(BYTE* buffer, int fd) { + return CHILD_STDIO_HANDLE(buffer, fd); +} diff --git a/external/src/libuv/src/win/process.c b/external/src/libuv/src/win/process.c new file mode 100644 index 0000000..4038fbf --- /dev/null +++ b/external/src/libuv/src/win/process.c @@ -0,0 +1,1281 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include /* alloca */ + +#include "uv.h" +#include "internal.h" +#include "handle-inl.h" +#include "req-inl.h" + + +#define SIGKILL 9 + + +typedef struct env_var { + const WCHAR* const wide; + const WCHAR* const wide_eq; + const size_t len; /* including null or '=' */ +} env_var_t; + +#define E_V(str) { L##str, L##str L"=", sizeof(str) } + +static const env_var_t required_vars[] = { /* keep me sorted */ + E_V("HOMEDRIVE"), + E_V("HOMEPATH"), + E_V("LOGONSERVER"), + E_V("PATH"), + E_V("SYSTEMDRIVE"), + E_V("SYSTEMROOT"), + E_V("TEMP"), + E_V("USERDOMAIN"), + E_V("USERNAME"), + E_V("USERPROFILE"), + E_V("WINDIR"), +}; + + +static HANDLE uv_global_job_handle_; +static uv_once_t uv_global_job_handle_init_guard_ = UV_ONCE_INIT; + + +static void uv__init_global_job_handle(void) { + /* Create a job object and set it up to kill all contained processes when + * it's closed. Since this handle is made non-inheritable and we're not + * giving it to anyone, we're the only process holding a reference to it. + * That means that if this process exits it is closed and all the processes + * it contains are killed. All processes created with uv_spawn that are not + * spawned with the UV_PROCESS_DETACHED flag are assigned to this job. + * + * We're setting the JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag so only the + * processes that we explicitly add are affected, and *their* subprocesses + * are not. This ensures that our child processes are not limited in their + * ability to use job control on Windows versions that don't deal with + * nested jobs (prior to Windows 8 / Server 2012). It also lets our child + * processes created detached processes without explicitly breaking away + * from job control (which uv_spawn doesn't, either). + */ + SECURITY_ATTRIBUTES attr; + JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; + + memset(&attr, 0, sizeof attr); + attr.bInheritHandle = FALSE; + + memset(&info, 0, sizeof info); + info.BasicLimitInformation.LimitFlags = + JOB_OBJECT_LIMIT_BREAKAWAY_OK | + JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK | + JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | + JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; + + uv_global_job_handle_ = CreateJobObjectW(&attr, NULL); + if (uv_global_job_handle_ == NULL) + uv_fatal_error(GetLastError(), "CreateJobObjectW"); + + if (!SetInformationJobObject(uv_global_job_handle_, + JobObjectExtendedLimitInformation, + &info, + sizeof info)) + uv_fatal_error(GetLastError(), "SetInformationJobObject"); +} + + +static int uv_utf8_to_utf16_alloc(const char* s, WCHAR** ws_ptr) { + int ws_len, r; + WCHAR* ws; + + ws_len = MultiByteToWideChar(CP_UTF8, + 0, + s, + -1, + NULL, + 0); + if (ws_len <= 0) { + return GetLastError(); + } + + ws = (WCHAR*) uv__malloc(ws_len * sizeof(WCHAR)); + if (ws == NULL) { + return ERROR_OUTOFMEMORY; + } + + r = MultiByteToWideChar(CP_UTF8, + 0, + s, + -1, + ws, + ws_len); + assert(r == ws_len); + + *ws_ptr = ws; + return 0; +} + + +static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) { + uv__handle_init(loop, (uv_handle_t*) handle, UV_PROCESS); + handle->exit_cb = NULL; + handle->pid = 0; + handle->exit_signal = 0; + handle->wait_handle = INVALID_HANDLE_VALUE; + handle->process_handle = INVALID_HANDLE_VALUE; + handle->child_stdio_buffer = NULL; + handle->exit_cb_pending = 0; + + UV_REQ_INIT(&handle->exit_req, UV_PROCESS_EXIT); + handle->exit_req.data = handle; +} + + +/* + * Path search functions + */ + +/* + * Helper function for search_path + */ +static WCHAR* search_path_join_test(const WCHAR* dir, + size_t dir_len, + const WCHAR* name, + size_t name_len, + const WCHAR* ext, + size_t ext_len, + const WCHAR* cwd, + size_t cwd_len) { + WCHAR *result, *result_pos; + DWORD attrs; + if (dir_len > 2 && dir[0] == L'\\' && dir[1] == L'\\') { + /* It's a UNC path so ignore cwd */ + cwd_len = 0; + } else if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) { + /* It's a full path without drive letter, use cwd's drive letter only */ + cwd_len = 2; + } else if (dir_len >= 2 && dir[1] == L':' && + (dir_len < 3 || (dir[2] != L'/' && dir[2] != L'\\'))) { + /* It's a relative path with drive letter (ext.g. D:../some/file) + * Replace drive letter in dir by full cwd if it points to the same drive, + * otherwise use the dir only. + */ + if (cwd_len < 2 || _wcsnicmp(cwd, dir, 2) != 0) { + cwd_len = 0; + } else { + dir += 2; + dir_len -= 2; + } + } else if (dir_len > 2 && dir[1] == L':') { + /* It's an absolute path with drive letter + * Don't use the cwd at all + */ + cwd_len = 0; + } + + /* Allocate buffer for output */ + result = result_pos = (WCHAR*)uv__malloc(sizeof(WCHAR) * + (cwd_len + 1 + dir_len + 1 + name_len + 1 + ext_len + 1)); + + /* Copy cwd */ + wcsncpy(result_pos, cwd, cwd_len); + result_pos += cwd_len; + + /* Add a path separator if cwd didn't end with one */ + if (cwd_len && wcsrchr(L"\\/:", result_pos[-1]) == NULL) { + result_pos[0] = L'\\'; + result_pos++; + } + + /* Copy dir */ + wcsncpy(result_pos, dir, dir_len); + result_pos += dir_len; + + /* Add a separator if the dir didn't end with one */ + if (dir_len && wcsrchr(L"\\/:", result_pos[-1]) == NULL) { + result_pos[0] = L'\\'; + result_pos++; + } + + /* Copy filename */ + wcsncpy(result_pos, name, name_len); + result_pos += name_len; + + if (ext_len) { + /* Add a dot if the filename didn't end with one */ + if (name_len && result_pos[-1] != '.') { + result_pos[0] = L'.'; + result_pos++; + } + + /* Copy extension */ + wcsncpy(result_pos, ext, ext_len); + result_pos += ext_len; + } + + /* Null terminator */ + result_pos[0] = L'\0'; + + attrs = GetFileAttributesW(result); + + if (attrs != INVALID_FILE_ATTRIBUTES && + !(attrs & FILE_ATTRIBUTE_DIRECTORY)) { + return result; + } + + uv__free(result); + return NULL; +} + + +/* + * Helper function for search_path + */ +static WCHAR* path_search_walk_ext(const WCHAR *dir, + size_t dir_len, + const WCHAR *name, + size_t name_len, + WCHAR *cwd, + size_t cwd_len, + int name_has_ext) { + WCHAR* result; + + /* If the name itself has a nonempty extension, try this extension first */ + if (name_has_ext) { + result = search_path_join_test(dir, dir_len, + name, name_len, + L"", 0, + cwd, cwd_len); + if (result != NULL) { + return result; + } + } + + /* Try .com extension */ + result = search_path_join_test(dir, dir_len, + name, name_len, + L"com", 3, + cwd, cwd_len); + if (result != NULL) { + return result; + } + + /* Try .exe extension */ + result = search_path_join_test(dir, dir_len, + name, name_len, + L"exe", 3, + cwd, cwd_len); + if (result != NULL) { + return result; + } + + return NULL; +} + + +/* + * search_path searches the system path for an executable filename - + * the windows API doesn't provide this as a standalone function nor as an + * option to CreateProcess. + * + * It tries to return an absolute filename. + * + * Furthermore, it tries to follow the semantics that cmd.exe, with this + * exception that PATHEXT environment variable isn't used. Since CreateProcess + * can start only .com and .exe files, only those extensions are tried. This + * behavior equals that of msvcrt's spawn functions. + * + * - Do not search the path if the filename already contains a path (either + * relative or absolute). + * + * - If there's really only a filename, check the current directory for file, + * then search all path directories. + * + * - If filename specified has *any* extension, search for the file with the + * specified extension first. + * + * - If the literal filename is not found in a directory, try *appending* + * (not replacing) .com first and then .exe. + * + * - The path variable may contain relative paths; relative paths are relative + * to the cwd. + * + * - Directories in path may or may not end with a trailing backslash. + * + * - CMD does not trim leading/trailing whitespace from path/pathex entries + * nor from the environment variables as a whole. + * + * - When cmd.exe cannot read a directory, it will just skip it and go on + * searching. However, unlike posix-y systems, it will happily try to run a + * file that is not readable/executable; if the spawn fails it will not + * continue searching. + * + * UNC path support: we are dealing with UNC paths in both the path and the + * filename. This is a deviation from what cmd.exe does (it does not let you + * start a program by specifying an UNC path on the command line) but this is + * really a pointless restriction. + * + */ +static WCHAR* search_path(const WCHAR *file, + WCHAR *cwd, + const WCHAR *path) { + int file_has_dir; + WCHAR* result = NULL; + WCHAR *file_name_start; + WCHAR *dot; + const WCHAR *dir_start, *dir_end, *dir_path; + size_t dir_len; + int name_has_ext; + + size_t file_len = wcslen(file); + size_t cwd_len = wcslen(cwd); + + /* If the caller supplies an empty filename, + * we're not gonna return c:\windows\.exe -- GFY! + */ + if (file_len == 0 + || (file_len == 1 && file[0] == L'.')) { + return NULL; + } + + /* Find the start of the filename so we can split the directory from the + * name. */ + for (file_name_start = (WCHAR*)file + file_len; + file_name_start > file + && file_name_start[-1] != L'\\' + && file_name_start[-1] != L'/' + && file_name_start[-1] != L':'; + file_name_start--); + + file_has_dir = file_name_start != file; + + /* Check if the filename includes an extension */ + dot = wcschr(file_name_start, L'.'); + name_has_ext = (dot != NULL && dot[1] != L'\0'); + + if (file_has_dir) { + /* The file has a path inside, don't use path */ + result = path_search_walk_ext( + file, file_name_start - file, + file_name_start, file_len - (file_name_start - file), + cwd, cwd_len, + name_has_ext); + + } else { + dir_end = path; + + /* The file is really only a name; look in cwd first, then scan path */ + result = path_search_walk_ext(L"", 0, + file, file_len, + cwd, cwd_len, + name_has_ext); + + while (result == NULL) { + if (*dir_end == L'\0') { + break; + } + + /* Skip the separator that dir_end now points to */ + if (dir_end != path || *path == L';') { + dir_end++; + } + + /* Next slice starts just after where the previous one ended */ + dir_start = dir_end; + + /* If path is quoted, find quote end */ + if (*dir_start == L'"' || *dir_start == L'\'') { + dir_end = wcschr(dir_start + 1, *dir_start); + if (dir_end == NULL) { + dir_end = wcschr(dir_start, L'\0'); + } + } + /* Slice until the next ; or \0 is found */ + dir_end = wcschr(dir_end, L';'); + if (dir_end == NULL) { + dir_end = wcschr(dir_start, L'\0'); + } + + /* If the slice is zero-length, don't bother */ + if (dir_end - dir_start == 0) { + continue; + } + + dir_path = dir_start; + dir_len = dir_end - dir_start; + + /* Adjust if the path is quoted. */ + if (dir_path[0] == '"' || dir_path[0] == '\'') { + ++dir_path; + --dir_len; + } + + if (dir_path[dir_len - 1] == '"' || dir_path[dir_len - 1] == '\'') { + --dir_len; + } + + result = path_search_walk_ext(dir_path, dir_len, + file, file_len, + cwd, cwd_len, + name_has_ext); + } + } + + return result; +} + + +/* + * Quotes command line arguments + * Returns a pointer to the end (next char to be written) of the buffer + */ +WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target) { + size_t len = wcslen(source); + size_t i; + int quote_hit; + WCHAR* start; + + if (len == 0) { + /* Need double quotation for empty argument */ + *(target++) = L'"'; + *(target++) = L'"'; + return target; + } + + if (NULL == wcspbrk(source, L" \t\"")) { + /* No quotation needed */ + wcsncpy(target, source, len); + target += len; + return target; + } + + if (NULL == wcspbrk(source, L"\"\\")) { + /* + * No embedded double quotes or backlashes, so I can just wrap + * quote marks around the whole thing. + */ + *(target++) = L'"'; + wcsncpy(target, source, len); + target += len; + *(target++) = L'"'; + return target; + } + + /* + * Expected input/output: + * input : hello"world + * output: "hello\"world" + * input : hello""world + * output: "hello\"\"world" + * input : hello\world + * output: hello\world + * input : hello\\world + * output: hello\\world + * input : hello\"world + * output: "hello\\\"world" + * input : hello\\"world + * output: "hello\\\\\"world" + * input : hello world\ + * output: "hello world\\" + */ + + *(target++) = L'"'; + start = target; + quote_hit = 1; + + for (i = len; i > 0; --i) { + *(target++) = source[i - 1]; + + if (quote_hit && source[i - 1] == L'\\') { + *(target++) = L'\\'; + } else if(source[i - 1] == L'"') { + quote_hit = 1; + *(target++) = L'\\'; + } else { + quote_hit = 0; + } + } + target[0] = L'\0'; + wcsrev(start); + *(target++) = L'"'; + return target; +} + + +int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { + char** arg; + WCHAR* dst = NULL; + WCHAR* temp_buffer = NULL; + size_t dst_len = 0; + size_t temp_buffer_len = 0; + WCHAR* pos; + int arg_count = 0; + int err = 0; + + /* Count the required size. */ + for (arg = args; *arg; arg++) { + DWORD arg_len; + + arg_len = MultiByteToWideChar(CP_UTF8, + 0, + *arg, + -1, + NULL, + 0); + if (arg_len == 0) { + return GetLastError(); + } + + dst_len += arg_len; + + if (arg_len > temp_buffer_len) + temp_buffer_len = arg_len; + + arg_count++; + } + + /* Adjust for potential quotes. Also assume the worst-case scenario that + * every character needs escaping, so we need twice as much space. */ + dst_len = dst_len * 2 + arg_count * 2; + + /* Allocate buffer for the final command line. */ + dst = (WCHAR*) uv__malloc(dst_len * sizeof(WCHAR)); + if (dst == NULL) { + err = ERROR_OUTOFMEMORY; + goto error; + } + + /* Allocate temporary working buffer. */ + temp_buffer = (WCHAR*) uv__malloc(temp_buffer_len * sizeof(WCHAR)); + if (temp_buffer == NULL) { + err = ERROR_OUTOFMEMORY; + goto error; + } + + pos = dst; + for (arg = args; *arg; arg++) { + DWORD arg_len; + + /* Convert argument to wide char. */ + arg_len = MultiByteToWideChar(CP_UTF8, + 0, + *arg, + -1, + temp_buffer, + (int) (dst + dst_len - pos)); + if (arg_len == 0) { + err = GetLastError(); + goto error; + } + + if (verbatim_arguments) { + /* Copy verbatim. */ + wcscpy(pos, temp_buffer); + pos += arg_len - 1; + } else { + /* Quote/escape, if needed. */ + pos = quote_cmd_arg(temp_buffer, pos); + } + + *pos++ = *(arg + 1) ? L' ' : L'\0'; + } + + uv__free(temp_buffer); + + *dst_ptr = dst; + return 0; + +error: + uv__free(dst); + uv__free(temp_buffer); + return err; +} + + +int env_strncmp(const wchar_t* a, int na, const wchar_t* b) { + wchar_t* a_eq; + wchar_t* b_eq; + wchar_t* A; + wchar_t* B; + int nb; + int r; + + if (na < 0) { + a_eq = wcschr(a, L'='); + assert(a_eq); + na = (int)(long)(a_eq - a); + } else { + na--; + } + b_eq = wcschr(b, L'='); + assert(b_eq); + nb = b_eq - b; + + A = alloca((na+1) * sizeof(wchar_t)); + B = alloca((nb+1) * sizeof(wchar_t)); + + r = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, a, na, A, na); + assert(r==na); + A[na] = L'\0'; + r = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, b, nb, B, nb); + assert(r==nb); + B[nb] = L'\0'; + + for (;;) { + wchar_t AA = *A++; + wchar_t BB = *B++; + if (AA < BB) { + return -1; + } else if (AA > BB) { + return 1; + } else if (!AA && !BB) { + return 0; + } + } +} + + +static int qsort_wcscmp(const void *a, const void *b) { + wchar_t* astr = *(wchar_t* const*)a; + wchar_t* bstr = *(wchar_t* const*)b; + return env_strncmp(astr, -1, bstr); +} + + +/* + * The way windows takes environment variables is different than what C does; + * Windows wants a contiguous block of null-terminated strings, terminated + * with an additional null. + * + * Windows has a few "essential" environment variables. winsock will fail + * to initialize if SYSTEMROOT is not defined; some APIs make reference to + * TEMP. SYSTEMDRIVE is probably also important. We therefore ensure that + * these get defined if the input environment block does not contain any + * values for them. + * + * Also add variables known to Cygwin to be required for correct + * subprocess operation in many cases: + * https://github.com/Alexpux/Cygwin/blob/b266b04fbbd3a595f02ea149e4306d3ab9b1fe3d/winsup/cygwin/environ.cc#L955 + * + */ +int make_program_env(char* env_block[], WCHAR** dst_ptr) { + WCHAR* dst; + WCHAR* ptr; + char** env; + size_t env_len = 0; + int len; + size_t i; + DWORD var_size; + size_t env_block_count = 1; /* 1 for null-terminator */ + WCHAR* dst_copy; + WCHAR** ptr_copy; + WCHAR** env_copy; + DWORD required_vars_value_len[ARRAY_SIZE(required_vars)]; + + /* first pass: determine size in UTF-16 */ + for (env = env_block; *env; env++) { + int len; + if (strchr(*env, '=')) { + len = MultiByteToWideChar(CP_UTF8, + 0, + *env, + -1, + NULL, + 0); + if (len <= 0) { + return GetLastError(); + } + env_len += len; + env_block_count++; + } + } + + /* second pass: copy to UTF-16 environment block */ + dst_copy = (WCHAR*)uv__malloc(env_len * sizeof(WCHAR)); + if (dst_copy == NULL && env_len > 0) { + return ERROR_OUTOFMEMORY; + } + env_copy = alloca(env_block_count * sizeof(WCHAR*)); + + ptr = dst_copy; + ptr_copy = env_copy; + for (env = env_block; *env; env++) { + if (strchr(*env, '=')) { + len = MultiByteToWideChar(CP_UTF8, + 0, + *env, + -1, + ptr, + (int) (env_len - (ptr - dst_copy))); + if (len <= 0) { + DWORD err = GetLastError(); + uv__free(dst_copy); + return err; + } + *ptr_copy++ = ptr; + ptr += len; + } + } + *ptr_copy = NULL; + assert(env_len == 0 || env_len == (size_t) (ptr - dst_copy)); + + /* sort our (UTF-16) copy */ + qsort(env_copy, env_block_count-1, sizeof(wchar_t*), qsort_wcscmp); + + /* third pass: check for required variables */ + for (ptr_copy = env_copy, i = 0; i < ARRAY_SIZE(required_vars); ) { + int cmp; + if (!*ptr_copy) { + cmp = -1; + } else { + cmp = env_strncmp(required_vars[i].wide_eq, + required_vars[i].len, + *ptr_copy); + } + if (cmp < 0) { + /* missing required var */ + var_size = GetEnvironmentVariableW(required_vars[i].wide, NULL, 0); + required_vars_value_len[i] = var_size; + if (var_size != 0) { + env_len += required_vars[i].len; + env_len += var_size; + } + i++; + } else { + ptr_copy++; + if (cmp == 0) + i++; + } + } + + /* final pass: copy, in sort order, and inserting required variables */ + dst = uv__malloc((1+env_len) * sizeof(WCHAR)); + if (!dst) { + uv__free(dst_copy); + return ERROR_OUTOFMEMORY; + } + + for (ptr = dst, ptr_copy = env_copy, i = 0; + *ptr_copy || i < ARRAY_SIZE(required_vars); + ptr += len) { + int cmp; + if (i >= ARRAY_SIZE(required_vars)) { + cmp = 1; + } else if (!*ptr_copy) { + cmp = -1; + } else { + cmp = env_strncmp(required_vars[i].wide_eq, + required_vars[i].len, + *ptr_copy); + } + if (cmp < 0) { + /* missing required var */ + len = required_vars_value_len[i]; + if (len) { + wcscpy(ptr, required_vars[i].wide_eq); + ptr += required_vars[i].len; + var_size = GetEnvironmentVariableW(required_vars[i].wide, + ptr, + (int) (env_len - (ptr - dst))); + if (var_size != (DWORD) (len - 1)) { /* TODO: handle race condition? */ + uv_fatal_error(GetLastError(), "GetEnvironmentVariableW"); + } + } + i++; + } else { + /* copy var from env_block */ + len = wcslen(*ptr_copy) + 1; + wmemcpy(ptr, *ptr_copy, len); + ptr_copy++; + if (cmp == 0) + i++; + } + } + + /* Terminate with an extra NULL. */ + assert(env_len == (size_t) (ptr - dst)); + *ptr = L'\0'; + + uv__free(dst_copy); + *dst_ptr = dst; + return 0; +} + +/* + * Attempt to find the value of the PATH environment variable in the child's + * preprocessed environment. + * + * If found, a pointer into `env` is returned. If not found, NULL is returned. + */ +static WCHAR* find_path(WCHAR *env) { + for (; env != NULL && *env != 0; env += wcslen(env) + 1) { + if ((env[0] == L'P' || env[0] == L'p') && + (env[1] == L'A' || env[1] == L'a') && + (env[2] == L'T' || env[2] == L't') && + (env[3] == L'H' || env[3] == L'h') && + (env[4] == L'=')) { + return &env[5]; + } + } + + return NULL; +} + +/* + * Called on Windows thread-pool thread to indicate that + * a child process has exited. + */ +static void CALLBACK exit_wait_callback(void* data, BOOLEAN didTimeout) { + uv_process_t* process = (uv_process_t*) data; + uv_loop_t* loop = process->loop; + + assert(didTimeout == FALSE); + assert(process); + assert(!process->exit_cb_pending); + + process->exit_cb_pending = 1; + + /* Post completed */ + POST_COMPLETION_FOR_REQ(loop, &process->exit_req); +} + + +/* Called on main thread after a child process has exited. */ +void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) { + int64_t exit_code; + DWORD status; + + assert(handle->exit_cb_pending); + handle->exit_cb_pending = 0; + + /* If we're closing, don't call the exit callback. Just schedule a close + * callback now. */ + if (handle->flags & UV_HANDLE_CLOSING) { + uv_want_endgame(loop, (uv_handle_t*) handle); + return; + } + + /* Unregister from process notification. */ + if (handle->wait_handle != INVALID_HANDLE_VALUE) { + UnregisterWait(handle->wait_handle); + handle->wait_handle = INVALID_HANDLE_VALUE; + } + + /* Set the handle to inactive: no callbacks will be made after the exit + * callback. */ + uv__handle_stop(handle); + + if (GetExitCodeProcess(handle->process_handle, &status)) { + exit_code = status; + } else { + /* Unable to obtain the exit code. This should never happen. */ + exit_code = uv_translate_sys_error(GetLastError()); + } + + /* Fire the exit callback. */ + if (handle->exit_cb) { + handle->exit_cb(handle, exit_code, handle->exit_signal); + } +} + + +void uv_process_close(uv_loop_t* loop, uv_process_t* handle) { + uv__handle_closing(handle); + + if (handle->wait_handle != INVALID_HANDLE_VALUE) { + /* This blocks until either the wait was cancelled, or the callback has + * completed. */ + BOOL r = UnregisterWaitEx(handle->wait_handle, INVALID_HANDLE_VALUE); + if (!r) { + /* This should never happen, and if it happens, we can't recover... */ + uv_fatal_error(GetLastError(), "UnregisterWaitEx"); + } + + handle->wait_handle = INVALID_HANDLE_VALUE; + } + + if (!handle->exit_cb_pending) { + uv_want_endgame(loop, (uv_handle_t*)handle); + } +} + + +void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle) { + assert(!handle->exit_cb_pending); + assert(handle->flags & UV_HANDLE_CLOSING); + assert(!(handle->flags & UV_HANDLE_CLOSED)); + + /* Clean-up the process handle. */ + CloseHandle(handle->process_handle); + + uv__handle_close(handle); +} + + +int uv_spawn(uv_loop_t* loop, + uv_process_t* process, + const uv_process_options_t* options) { + int i; + int err = 0; + WCHAR* path = NULL, *alloc_path = NULL; + BOOL result; + WCHAR* application_path = NULL, *application = NULL, *arguments = NULL, + *env = NULL, *cwd = NULL; + STARTUPINFOW startup; + PROCESS_INFORMATION info; + DWORD process_flags; + + uv_process_init(loop, process); + process->exit_cb = options->exit_cb; + + if (options->flags & (UV_PROCESS_SETGID | UV_PROCESS_SETUID)) { + return UV_ENOTSUP; + } + + if (options->file == NULL || + options->args == NULL) { + return UV_EINVAL; + } + + assert(options->file != NULL); + assert(!(options->flags & ~(UV_PROCESS_DETACHED | + UV_PROCESS_SETGID | + UV_PROCESS_SETUID | + UV_PROCESS_WINDOWS_HIDE | + UV_PROCESS_WINDOWS_HIDE_CONSOLE | + UV_PROCESS_WINDOWS_HIDE_GUI | + UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS))); + + err = uv_utf8_to_utf16_alloc(options->file, &application); + if (err) + goto done; + + err = make_program_args( + options->args, + options->flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS, + &arguments); + if (err) + goto done; + + if (options->env) { + err = make_program_env(options->env, &env); + if (err) + goto done; + } + + if (options->cwd) { + /* Explicit cwd */ + err = uv_utf8_to_utf16_alloc(options->cwd, &cwd); + if (err) + goto done; + + } else { + /* Inherit cwd */ + DWORD cwd_len, r; + + cwd_len = GetCurrentDirectoryW(0, NULL); + if (!cwd_len) { + err = GetLastError(); + goto done; + } + + cwd = (WCHAR*) uv__malloc(cwd_len * sizeof(WCHAR)); + if (cwd == NULL) { + err = ERROR_OUTOFMEMORY; + goto done; + } + + r = GetCurrentDirectoryW(cwd_len, cwd); + if (r == 0 || r >= cwd_len) { + err = GetLastError(); + goto done; + } + } + + /* Get PATH environment variable. */ + path = find_path(env); + if (path == NULL) { + DWORD path_len, r; + + path_len = GetEnvironmentVariableW(L"PATH", NULL, 0); + if (path_len == 0) { + err = GetLastError(); + goto done; + } + + alloc_path = (WCHAR*) uv__malloc(path_len * sizeof(WCHAR)); + if (alloc_path == NULL) { + err = ERROR_OUTOFMEMORY; + goto done; + } + path = alloc_path; + + r = GetEnvironmentVariableW(L"PATH", path, path_len); + if (r == 0 || r >= path_len) { + err = GetLastError(); + goto done; + } + } + + err = uv__stdio_create(loop, options, &process->child_stdio_buffer); + if (err) + goto done; + + application_path = search_path(application, + cwd, + path); + if (application_path == NULL) { + /* Not found. */ + err = ERROR_FILE_NOT_FOUND; + goto done; + } + + startup.cb = sizeof(startup); + startup.lpReserved = NULL; + startup.lpDesktop = NULL; + startup.lpTitle = NULL; + startup.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + + startup.cbReserved2 = uv__stdio_size(process->child_stdio_buffer); + startup.lpReserved2 = (BYTE*) process->child_stdio_buffer; + + startup.hStdInput = uv__stdio_handle(process->child_stdio_buffer, 0); + startup.hStdOutput = uv__stdio_handle(process->child_stdio_buffer, 1); + startup.hStdError = uv__stdio_handle(process->child_stdio_buffer, 2); + + process_flags = CREATE_UNICODE_ENVIRONMENT; + + if ((options->flags & UV_PROCESS_WINDOWS_HIDE_CONSOLE) || + (options->flags & UV_PROCESS_WINDOWS_HIDE)) { + /* Avoid creating console window if stdio is not inherited. */ + for (i = 0; i < options->stdio_count; i++) { + if (options->stdio[i].flags & UV_INHERIT_FD) + break; + if (i == options->stdio_count - 1) + process_flags |= CREATE_NO_WINDOW; + } + } + if ((options->flags & UV_PROCESS_WINDOWS_HIDE_GUI) || + (options->flags & UV_PROCESS_WINDOWS_HIDE)) { + /* Use SW_HIDE to avoid any potential process window. */ + startup.wShowWindow = SW_HIDE; + } else { + startup.wShowWindow = SW_SHOWDEFAULT; + } + + if (options->flags & UV_PROCESS_DETACHED) { + /* Note that we're not setting the CREATE_BREAKAWAY_FROM_JOB flag. That + * means that libuv might not let you create a fully daemonized process + * when run under job control. However the type of job control that libuv + * itself creates doesn't trickle down to subprocesses so they can still + * daemonize. + * + * A reason to not do this is that CREATE_BREAKAWAY_FROM_JOB makes the + * CreateProcess call fail if we're under job control that doesn't allow + * breakaway. + */ + process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP; + } + + if (!CreateProcessW(application_path, + arguments, + NULL, + NULL, + 1, + process_flags, + env, + cwd, + &startup, + &info)) { + /* CreateProcessW failed. */ + err = GetLastError(); + goto done; + } + + /* Spawn succeeded. Beyond this point, failure is reported asynchronously. */ + + process->process_handle = info.hProcess; + process->pid = info.dwProcessId; + + /* If the process isn't spawned as detached, assign to the global job object + * so windows will kill it when the parent process dies. */ + if (!(options->flags & UV_PROCESS_DETACHED)) { + uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle); + + if (!AssignProcessToJobObject(uv_global_job_handle_, info.hProcess)) { + /* AssignProcessToJobObject might fail if this process is under job + * control and the job doesn't have the + * JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag set, on a Windows version + * that doesn't support nested jobs. + * + * When that happens we just swallow the error and continue without + * establishing a kill-child-on-parent-exit relationship, otherwise + * there would be no way for libuv applications run under job control + * to spawn processes at all. + */ + DWORD err = GetLastError(); + if (err != ERROR_ACCESS_DENIED) + uv_fatal_error(err, "AssignProcessToJobObject"); + } + } + + /* Set IPC pid to all IPC pipes. */ + for (i = 0; i < options->stdio_count; i++) { + const uv_stdio_container_t* fdopt = &options->stdio[i]; + if (fdopt->flags & UV_CREATE_PIPE && + fdopt->data.stream->type == UV_NAMED_PIPE && + ((uv_pipe_t*) fdopt->data.stream)->ipc) { + ((uv_pipe_t*) fdopt->data.stream)->pipe.conn.ipc_remote_pid = + info.dwProcessId; + } + } + + /* Setup notifications for when the child process exits. */ + result = RegisterWaitForSingleObject(&process->wait_handle, + process->process_handle, exit_wait_callback, (void*)process, INFINITE, + WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE); + if (!result) { + uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject"); + } + + CloseHandle(info.hThread); + + assert(!err); + + /* Make the handle active. It will remain active until the exit callback is + * made or the handle is closed, whichever happens first. */ + uv__handle_start(process); + + /* Cleanup, whether we succeeded or failed. */ + done: + uv__free(application); + uv__free(application_path); + uv__free(arguments); + uv__free(cwd); + uv__free(env); + uv__free(alloc_path); + + if (process->child_stdio_buffer != NULL) { + /* Clean up child stdio handles. */ + uv__stdio_destroy(process->child_stdio_buffer); + process->child_stdio_buffer = NULL; + } + + return uv_translate_sys_error(err); +} + + +static int uv__kill(HANDLE process_handle, int signum) { + if (signum < 0 || signum >= NSIG) { + return UV_EINVAL; + } + + switch (signum) { + case SIGTERM: + case SIGKILL: + case SIGINT: { + /* Unconditionally terminate the process. On Windows, killed processes + * normally return 1. */ + DWORD status; + int err; + + if (TerminateProcess(process_handle, 1)) + return 0; + + /* If the process already exited before TerminateProcess was called,. + * TerminateProcess will fail with ERROR_ACCESS_DENIED. */ + err = GetLastError(); + if (err == ERROR_ACCESS_DENIED && + GetExitCodeProcess(process_handle, &status) && + status != STILL_ACTIVE) { + return UV_ESRCH; + } + + return uv_translate_sys_error(err); + } + + case 0: { + /* Health check: is the process still alive? */ + DWORD status; + + if (!GetExitCodeProcess(process_handle, &status)) + return uv_translate_sys_error(GetLastError()); + + if (status != STILL_ACTIVE) + return UV_ESRCH; + + return 0; + } + + default: + /* Unsupported signal. */ + return UV_ENOSYS; + } +} + + +int uv_process_kill(uv_process_t* process, int signum) { + int err; + + if (process->process_handle == INVALID_HANDLE_VALUE) { + return UV_EINVAL; + } + + err = uv__kill(process->process_handle, signum); + if (err) { + return err; /* err is already translated. */ + } + + process->exit_signal = signum; + + return 0; +} + + +int uv_kill(int pid, int signum) { + int err; + HANDLE process_handle; + + if (pid == 0) { + process_handle = GetCurrentProcess(); + } else { + process_handle = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION, + FALSE, + pid); + } + + if (process_handle == NULL) { + err = GetLastError(); + if (err == ERROR_INVALID_PARAMETER) { + return UV_ESRCH; + } else { + return uv_translate_sys_error(err); + } + } + + err = uv__kill(process_handle, signum); + CloseHandle(process_handle); + + return err; /* err is already translated. */ +} diff --git a/external/src/libuv/src/win/req-inl.h b/external/src/libuv/src/win/req-inl.h new file mode 100644 index 0000000..f2513b7 --- /dev/null +++ b/external/src/libuv/src/win/req-inl.h @@ -0,0 +1,221 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_WIN_REQ_INL_H_ +#define UV_WIN_REQ_INL_H_ + +#include + +#include "uv.h" +#include "internal.h" + + +#define SET_REQ_STATUS(req, status) \ + (req)->u.io.overlapped.Internal = (ULONG_PTR) (status) + +#define SET_REQ_ERROR(req, error) \ + SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error))) + +/* Note: used open-coded in UV_REQ_INIT() because of a circular dependency + * between src/uv-common.h and src/win/internal.h. + */ +#define SET_REQ_SUCCESS(req) \ + SET_REQ_STATUS((req), STATUS_SUCCESS) + +#define GET_REQ_STATUS(req) \ + ((NTSTATUS) (req)->u.io.overlapped.Internal) + +#define REQ_SUCCESS(req) \ + (NT_SUCCESS(GET_REQ_STATUS((req)))) + +#define GET_REQ_ERROR(req) \ + (pRtlNtStatusToDosError(GET_REQ_STATUS((req)))) + +#define GET_REQ_SOCK_ERROR(req) \ + (uv_ntstatus_to_winsock_error(GET_REQ_STATUS((req)))) + + +#define REGISTER_HANDLE_REQ(loop, handle, req) \ + do { \ + INCREASE_ACTIVE_COUNT((loop), (handle)); \ + uv__req_register((loop), (req)); \ + } while (0) + +#define UNREGISTER_HANDLE_REQ(loop, handle, req) \ + do { \ + DECREASE_ACTIVE_COUNT((loop), (handle)); \ + uv__req_unregister((loop), (req)); \ + } while (0) + + +#define UV_SUCCEEDED_WITHOUT_IOCP(result) \ + ((result) && (handle->flags & UV_HANDLE_SYNC_BYPASS_IOCP)) + +#define UV_SUCCEEDED_WITH_IOCP(result) \ + ((result) || (GetLastError() == ERROR_IO_PENDING)) + + +#define POST_COMPLETION_FOR_REQ(loop, req) \ + if (!PostQueuedCompletionStatus((loop)->iocp, \ + 0, \ + 0, \ + &((req)->u.io.overlapped))) { \ + uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); \ + } + + +INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) { + return CONTAINING_RECORD(overlapped, uv_req_t, u.io.overlapped); +} + + +INLINE static void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) { + req->next_req = NULL; + if (loop->pending_reqs_tail) { +#ifdef _DEBUG + /* Ensure the request is not already in the queue, or the queue + * will get corrupted. + */ + uv_req_t* current = loop->pending_reqs_tail; + do { + assert(req != current); + current = current->next_req; + } while(current != loop->pending_reqs_tail); +#endif + + req->next_req = loop->pending_reqs_tail->next_req; + loop->pending_reqs_tail->next_req = req; + loop->pending_reqs_tail = req; + } else { + req->next_req = req; + loop->pending_reqs_tail = req; + } +} + + +#define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \ + do { \ + switch (((uv_handle_t*) (req)->handle_at)->type) { \ + case UV_TCP: \ + uv_process_tcp_##method##_req(loop, \ + (uv_tcp_t*) ((req)->handle_at), \ + req); \ + break; \ + \ + case UV_NAMED_PIPE: \ + uv_process_pipe_##method##_req(loop, \ + (uv_pipe_t*) ((req)->handle_at), \ + req); \ + break; \ + \ + case UV_TTY: \ + uv_process_tty_##method##_req(loop, \ + (uv_tty_t*) ((req)->handle_at), \ + req); \ + break; \ + \ + default: \ + assert(0); \ + } \ + } while (0) + + +INLINE static int uv_process_reqs(uv_loop_t* loop) { + uv_req_t* req; + uv_req_t* first; + uv_req_t* next; + + if (loop->pending_reqs_tail == NULL) + return 0; + + first = loop->pending_reqs_tail->next_req; + next = first; + loop->pending_reqs_tail = NULL; + + while (next != NULL) { + req = next; + next = req->next_req != first ? req->next_req : NULL; + + switch (req->type) { + case UV_READ: + DELEGATE_STREAM_REQ(loop, req, read, data); + break; + + case UV_WRITE: + DELEGATE_STREAM_REQ(loop, (uv_write_t*) req, write, handle); + break; + + case UV_ACCEPT: + DELEGATE_STREAM_REQ(loop, req, accept, data); + break; + + case UV_CONNECT: + DELEGATE_STREAM_REQ(loop, (uv_connect_t*) req, connect, handle); + break; + + case UV_SHUTDOWN: + /* Tcp shutdown requests don't come here. */ + assert(((uv_shutdown_t*) req)->handle->type == UV_NAMED_PIPE); + uv_process_pipe_shutdown_req( + loop, + (uv_pipe_t*) ((uv_shutdown_t*) req)->handle, + (uv_shutdown_t*) req); + break; + + case UV_UDP_RECV: + uv_process_udp_recv_req(loop, (uv_udp_t*) req->data, req); + break; + + case UV_UDP_SEND: + uv_process_udp_send_req(loop, + ((uv_udp_send_t*) req)->handle, + (uv_udp_send_t*) req); + break; + + case UV_WAKEUP: + uv_process_async_wakeup_req(loop, (uv_async_t*) req->data, req); + break; + + case UV_SIGNAL_REQ: + uv_process_signal_req(loop, (uv_signal_t*) req->data, req); + break; + + case UV_POLL_REQ: + uv_process_poll_req(loop, (uv_poll_t*) req->data, req); + break; + + case UV_PROCESS_EXIT: + uv_process_proc_exit(loop, (uv_process_t*) req->data); + break; + + case UV_FS_EVENT_REQ: + uv_process_fs_event_req(loop, req, (uv_fs_event_t*) req->data); + break; + + default: + assert(0); + } + } + + return 1; +} + +#endif /* UV_WIN_REQ_INL_H_ */ diff --git a/external/src/libuv/src/win/signal.c b/external/src/libuv/src/win/signal.c new file mode 100644 index 0000000..3d9f92c --- /dev/null +++ b/external/src/libuv/src/win/signal.c @@ -0,0 +1,282 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include + +#include "uv.h" +#include "internal.h" +#include "handle-inl.h" +#include "req-inl.h" + + +RB_HEAD(uv_signal_tree_s, uv_signal_s); + +static struct uv_signal_tree_s uv__signal_tree = RB_INITIALIZER(uv__signal_tree); +static CRITICAL_SECTION uv__signal_lock; + +static BOOL WINAPI uv__signal_control_handler(DWORD type); + +int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot); + +void uv_signals_init(void) { + InitializeCriticalSection(&uv__signal_lock); + if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE)) + abort(); +} + + +void uv__signal_cleanup(void) { + /* TODO(bnoordhuis) Undo effects of uv_signal_init()? */ +} + + +static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) { + /* Compare signums first so all watchers with the same signnum end up + * adjacent. */ + if (w1->signum < w2->signum) return -1; + if (w1->signum > w2->signum) return 1; + + /* Sort by loop pointer, so we can easily look up the first item after + * { .signum = x, .loop = NULL }. */ + if ((uintptr_t) w1->loop < (uintptr_t) w2->loop) return -1; + if ((uintptr_t) w1->loop > (uintptr_t) w2->loop) return 1; + + if ((uintptr_t) w1 < (uintptr_t) w2) return -1; + if ((uintptr_t) w1 > (uintptr_t) w2) return 1; + + return 0; +} + + +RB_GENERATE_STATIC(uv_signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare) + + +/* + * Dispatches signal {signum} to all active uv_signal_t watchers in all loops. + * Returns 1 if the signal was dispatched to any watcher, or 0 if there were + * no active signal watchers observing this signal. + */ +int uv__signal_dispatch(int signum) { + uv_signal_t lookup; + uv_signal_t* handle; + int dispatched; + + dispatched = 0; + + EnterCriticalSection(&uv__signal_lock); + + lookup.signum = signum; + lookup.loop = NULL; + + for (handle = RB_NFIND(uv_signal_tree_s, &uv__signal_tree, &lookup); + handle != NULL && handle->signum == signum; + handle = RB_NEXT(uv_signal_tree_s, &uv__signal_tree, handle)) { + unsigned long previous = InterlockedExchange( + (volatile LONG*) &handle->pending_signum, signum); + + if (handle->flags & UV_SIGNAL_ONE_SHOT_DISPATCHED) + continue; + + if (!previous) { + POST_COMPLETION_FOR_REQ(handle->loop, &handle->signal_req); + } + + dispatched = 1; + if (handle->flags & UV_SIGNAL_ONE_SHOT) + handle->flags |= UV_SIGNAL_ONE_SHOT_DISPATCHED; + } + + LeaveCriticalSection(&uv__signal_lock); + + return dispatched; +} + + +static BOOL WINAPI uv__signal_control_handler(DWORD type) { + switch (type) { + case CTRL_C_EVENT: + return uv__signal_dispatch(SIGINT); + + case CTRL_BREAK_EVENT: + return uv__signal_dispatch(SIGBREAK); + + case CTRL_CLOSE_EVENT: + if (uv__signal_dispatch(SIGHUP)) { + /* Windows will terminate the process after the control handler + * returns. After that it will just terminate our process. Therefore + * block the signal handler so the main loop has some time to pick up + * the signal and do something for a few seconds. */ + Sleep(INFINITE); + return TRUE; + } + return FALSE; + + case CTRL_LOGOFF_EVENT: + case CTRL_SHUTDOWN_EVENT: + /* These signals are only sent to services. Services have their own + * notification mechanism, so there's no point in handling these. */ + + default: + /* We don't handle these. */ + return FALSE; + } +} + + +int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) { + uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL); + handle->pending_signum = 0; + handle->signum = 0; + handle->signal_cb = NULL; + + UV_REQ_INIT(&handle->signal_req, UV_SIGNAL_REQ); + handle->signal_req.data = handle; + + return 0; +} + + +int uv_signal_stop(uv_signal_t* handle) { + uv_signal_t* removed_handle; + + /* If the watcher wasn't started, this is a no-op. */ + if (handle->signum == 0) + return 0; + + EnterCriticalSection(&uv__signal_lock); + + removed_handle = RB_REMOVE(uv_signal_tree_s, &uv__signal_tree, handle); + assert(removed_handle == handle); + + LeaveCriticalSection(&uv__signal_lock); + + handle->signum = 0; + uv__handle_stop(handle); + + return 0; +} + + +int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { + return uv__signal_start(handle, signal_cb, signum, 0); +} + + +int uv_signal_start_oneshot(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum) { + return uv__signal_start(handle, signal_cb, signum, 1); +} + + +int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, + int signum, + int oneshot) { + /* Test for invalid signal values. */ + if (signum <= 0 || signum >= NSIG) + return UV_EINVAL; + + /* Short circuit: if the signal watcher is already watching {signum} don't go + * through the process of deregistering and registering the handler. + * Additionally, this avoids pending signals getting lost in the (small) time + * frame that handle->signum == 0. */ + if (signum == handle->signum) { + handle->signal_cb = signal_cb; + return 0; + } + + /* If the signal handler was already active, stop it first. */ + if (handle->signum != 0) { + int r = uv_signal_stop(handle); + /* uv_signal_stop is infallible. */ + assert(r == 0); + } + + EnterCriticalSection(&uv__signal_lock); + + handle->signum = signum; + if (oneshot) + handle->flags |= UV_SIGNAL_ONE_SHOT; + + RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle); + + LeaveCriticalSection(&uv__signal_lock); + + handle->signal_cb = signal_cb; + uv__handle_start(handle); + + return 0; +} + + +void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle, + uv_req_t* req) { + long dispatched_signum; + + assert(handle->type == UV_SIGNAL); + assert(req->type == UV_SIGNAL_REQ); + + dispatched_signum = InterlockedExchange( + (volatile LONG*) &handle->pending_signum, 0); + assert(dispatched_signum != 0); + + /* Check if the pending signal equals the signum that we are watching for. + * These can get out of sync when the handler is stopped and restarted while + * the signal_req is pending. */ + if (dispatched_signum == handle->signum) + handle->signal_cb(handle, dispatched_signum); + + if (handle->flags & UV_SIGNAL_ONE_SHOT) + uv_signal_stop(handle); + + if (handle->flags & UV_HANDLE_CLOSING) { + /* When it is closing, it must be stopped at this point. */ + assert(handle->signum == 0); + uv_want_endgame(loop, (uv_handle_t*) handle); + } +} + + +void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle) { + uv_signal_stop(handle); + uv__handle_closing(handle); + + if (handle->pending_signum == 0) { + uv_want_endgame(loop, (uv_handle_t*) handle); + } +} + + +void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle) { + assert(handle->flags & UV_HANDLE_CLOSING); + assert(!(handle->flags & UV_HANDLE_CLOSED)); + + assert(handle->signum == 0); + assert(handle->pending_signum == 0); + + handle->flags |= UV_HANDLE_CLOSED; + + uv__handle_close(handle); +} diff --git a/external/src/libuv/src/win/snprintf.c b/external/src/libuv/src/win/snprintf.c new file mode 100644 index 0000000..776c0e3 --- /dev/null +++ b/external/src/libuv/src/win/snprintf.c @@ -0,0 +1,42 @@ +/* Copyright the libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#if defined(_MSC_VER) && _MSC_VER < 1900 + +#include +#include + +/* Emulate snprintf() on MSVC<2015, _snprintf() doesn't zero-terminate the buffer + * on overflow... + */ +int snprintf(char* buf, size_t len, const char* fmt, ...) { + int n; + va_list ap; + va_start(ap, fmt); + + n = _vscprintf(fmt, ap); + vsnprintf_s(buf, len, _TRUNCATE, fmt, ap); + + va_end(ap); + return n; +} + +#endif diff --git a/external/src/libuv/src/win/stream-inl.h b/external/src/libuv/src/win/stream-inl.h new file mode 100644 index 0000000..40f5ddd --- /dev/null +++ b/external/src/libuv/src/win/stream-inl.h @@ -0,0 +1,54 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_WIN_STREAM_INL_H_ +#define UV_WIN_STREAM_INL_H_ + +#include + +#include "uv.h" +#include "internal.h" +#include "handle-inl.h" +#include "req-inl.h" + + +INLINE static void uv_stream_init(uv_loop_t* loop, + uv_stream_t* handle, + uv_handle_type type) { + uv__handle_init(loop, (uv_handle_t*) handle, type); + handle->write_queue_size = 0; + handle->activecnt = 0; + handle->stream.conn.shutdown_req = NULL; + handle->stream.conn.write_reqs_pending = 0; + + UV_REQ_INIT(&handle->read_req, UV_READ); + handle->read_req.event_handle = NULL; + handle->read_req.wait_handle = INVALID_HANDLE_VALUE; + handle->read_req.data = handle; +} + + +INLINE static void uv_connection_init(uv_stream_t* handle) { + handle->flags |= UV_HANDLE_CONNECTION; +} + + +#endif /* UV_WIN_STREAM_INL_H_ */ diff --git a/external/src/libuv/src/win/stream.c b/external/src/libuv/src/win/stream.c new file mode 100644 index 0000000..abf477f --- /dev/null +++ b/external/src/libuv/src/win/stream.c @@ -0,0 +1,246 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include + +#include "uv.h" +#include "internal.h" +#include "handle-inl.h" +#include "req-inl.h" + + +int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) { + int err; + + err = ERROR_INVALID_PARAMETER; + switch (stream->type) { + case UV_TCP: + err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb); + break; + case UV_NAMED_PIPE: + err = uv_pipe_listen((uv_pipe_t*)stream, backlog, cb); + break; + default: + assert(0); + } + + return uv_translate_sys_error(err); +} + + +int uv_accept(uv_stream_t* server, uv_stream_t* client) { + int err; + + err = ERROR_INVALID_PARAMETER; + switch (server->type) { + case UV_TCP: + err = uv_tcp_accept((uv_tcp_t*)server, (uv_tcp_t*)client); + break; + case UV_NAMED_PIPE: + err = uv_pipe_accept((uv_pipe_t*)server, client); + break; + default: + assert(0); + } + + return uv_translate_sys_error(err); +} + + +int uv__read_start(uv_stream_t* handle, + uv_alloc_cb alloc_cb, + uv_read_cb read_cb) { + int err; + + err = ERROR_INVALID_PARAMETER; + switch (handle->type) { + case UV_TCP: + err = uv_tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb); + break; + case UV_NAMED_PIPE: + err = uv_pipe_read_start((uv_pipe_t*)handle, alloc_cb, read_cb); + break; + case UV_TTY: + err = uv_tty_read_start((uv_tty_t*) handle, alloc_cb, read_cb); + break; + default: + assert(0); + } + + return uv_translate_sys_error(err); +} + + +int uv_read_stop(uv_stream_t* handle) { + int err; + + if (!(handle->flags & UV_HANDLE_READING)) + return 0; + + err = 0; + if (handle->type == UV_TTY) { + err = uv_tty_read_stop((uv_tty_t*) handle); + } else if (handle->type == UV_NAMED_PIPE) { + uv__pipe_read_stop((uv_pipe_t*) handle); + } else { + handle->flags &= ~UV_HANDLE_READING; + DECREASE_ACTIVE_COUNT(handle->loop, handle); + } + + return uv_translate_sys_error(err); +} + + +int uv_write(uv_write_t* req, + uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_write_cb cb) { + uv_loop_t* loop = handle->loop; + int err; + + if (!(handle->flags & UV_HANDLE_WRITABLE)) { + return UV_EPIPE; + } + + err = ERROR_INVALID_PARAMETER; + switch (handle->type) { + case UV_TCP: + err = uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, nbufs, cb); + break; + case UV_NAMED_PIPE: + err = uv__pipe_write( + loop, req, (uv_pipe_t*) handle, bufs, nbufs, NULL, cb); + break; + case UV_TTY: + err = uv_tty_write(loop, req, (uv_tty_t*) handle, bufs, nbufs, cb); + break; + default: + assert(0); + } + + return uv_translate_sys_error(err); +} + + +int uv_write2(uv_write_t* req, + uv_stream_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle, + uv_write_cb cb) { + uv_loop_t* loop = handle->loop; + int err; + + if (send_handle == NULL) { + return uv_write(req, handle, bufs, nbufs, cb); + } + + if (handle->type != UV_NAMED_PIPE || !((uv_pipe_t*) handle)->ipc) { + return UV_EINVAL; + } else if (!(handle->flags & UV_HANDLE_WRITABLE)) { + return UV_EPIPE; + } + + err = uv__pipe_write( + loop, req, (uv_pipe_t*) handle, bufs, nbufs, send_handle, cb); + return uv_translate_sys_error(err); +} + + +int uv_try_write(uv_stream_t* stream, + const uv_buf_t bufs[], + unsigned int nbufs) { + if (stream->flags & UV_HANDLE_CLOSING) + return UV_EBADF; + if (!(stream->flags & UV_HANDLE_WRITABLE)) + return UV_EPIPE; + + switch (stream->type) { + case UV_TCP: + return uv__tcp_try_write((uv_tcp_t*) stream, bufs, nbufs); + case UV_TTY: + return uv__tty_try_write((uv_tty_t*) stream, bufs, nbufs); + case UV_NAMED_PIPE: + return UV_EAGAIN; + default: + assert(0); + return UV_ENOSYS; + } +} + + +int uv_try_write2(uv_stream_t* stream, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle) { + if (send_handle != NULL) + return UV_EAGAIN; + return uv_try_write(stream, bufs, nbufs); +} + + +int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) { + uv_loop_t* loop = handle->loop; + + if (!(handle->flags & UV_HANDLE_WRITABLE) || + handle->flags & UV_HANDLE_SHUTTING || + uv__is_closing(handle)) { + return UV_ENOTCONN; + } + + UV_REQ_INIT(req, UV_SHUTDOWN); + req->handle = handle; + req->cb = cb; + + handle->flags &= ~UV_HANDLE_WRITABLE; + handle->flags |= UV_HANDLE_SHUTTING; + handle->stream.conn.shutdown_req = req; + handle->reqs_pending++; + REGISTER_HANDLE_REQ(loop, handle, req); + + uv_want_endgame(loop, (uv_handle_t*)handle); + + return 0; +} + + +int uv_is_readable(const uv_stream_t* handle) { + return !!(handle->flags & UV_HANDLE_READABLE); +} + + +int uv_is_writable(const uv_stream_t* handle) { + return !!(handle->flags & UV_HANDLE_WRITABLE); +} + + +int uv_stream_set_blocking(uv_stream_t* handle, int blocking) { + if (handle->type != UV_NAMED_PIPE) + return UV_EINVAL; + + if (blocking != 0) + handle->flags |= UV_HANDLE_BLOCKING_WRITES; + else + handle->flags &= ~UV_HANDLE_BLOCKING_WRITES; + + return 0; +} diff --git a/external/src/libuv/src/win/tcp.c b/external/src/libuv/src/win/tcp.c new file mode 100644 index 0000000..cf2dbd8 --- /dev/null +++ b/external/src/libuv/src/win/tcp.c @@ -0,0 +1,1697 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include + +#include "uv.h" +#include "internal.h" +#include "handle-inl.h" +#include "stream-inl.h" +#include "req-inl.h" + + +/* + * Threshold of active tcp streams for which to preallocate tcp read buffers. + * (Due to node slab allocator performing poorly under this pattern, + * the optimization is temporarily disabled (threshold=0). This will be + * revisited once node allocator is improved.) + */ +const unsigned int uv_active_tcp_streams_threshold = 0; + +/* + * Number of simultaneous pending AcceptEx calls. + */ +const unsigned int uv_simultaneous_server_accepts = 32; + +/* A zero-size buffer for use by uv_tcp_read */ +static char uv_zero_[] = ""; + +static int uv__tcp_nodelay(uv_tcp_t* handle, SOCKET socket, int enable) { + if (setsockopt(socket, + IPPROTO_TCP, + TCP_NODELAY, + (const char*)&enable, + sizeof enable) == -1) { + return WSAGetLastError(); + } + return 0; +} + + +static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsigned int delay) { + if (setsockopt(socket, + SOL_SOCKET, + SO_KEEPALIVE, + (const char*)&enable, + sizeof enable) == -1) { + return WSAGetLastError(); + } + + if (enable && setsockopt(socket, + IPPROTO_TCP, + TCP_KEEPALIVE, + (const char*)&delay, + sizeof delay) == -1) { + return WSAGetLastError(); + } + + return 0; +} + + +static int uv_tcp_set_socket(uv_loop_t* loop, + uv_tcp_t* handle, + SOCKET socket, + int family, + int imported) { + DWORD yes = 1; + int non_ifs_lsp; + int err; + + if (handle->socket != INVALID_SOCKET) + return UV_EBUSY; + + /* Set the socket to nonblocking mode */ + if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) { + return WSAGetLastError(); + } + + /* Make the socket non-inheritable */ + if (!SetHandleInformation((HANDLE) socket, HANDLE_FLAG_INHERIT, 0)) + return GetLastError(); + + /* Associate it with the I/O completion port. Use uv_handle_t pointer as + * completion key. */ + if (CreateIoCompletionPort((HANDLE)socket, + loop->iocp, + (ULONG_PTR)socket, + 0) == NULL) { + if (imported) { + handle->flags |= UV_HANDLE_EMULATE_IOCP; + } else { + return GetLastError(); + } + } + + if (family == AF_INET6) { + non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv6; + } else { + non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv4; + } + + if (!(handle->flags & UV_HANDLE_EMULATE_IOCP) && !non_ifs_lsp) { + UCHAR sfcnm_flags = + FILE_SKIP_SET_EVENT_ON_HANDLE | FILE_SKIP_COMPLETION_PORT_ON_SUCCESS; + if (!SetFileCompletionNotificationModes((HANDLE) socket, sfcnm_flags)) + return GetLastError(); + handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP; + } + + if (handle->flags & UV_HANDLE_TCP_NODELAY) { + err = uv__tcp_nodelay(handle, socket, 1); + if (err) + return err; + } + + /* TODO: Use stored delay. */ + if (handle->flags & UV_HANDLE_TCP_KEEPALIVE) { + err = uv__tcp_keepalive(handle, socket, 1, 60); + if (err) + return err; + } + + handle->socket = socket; + + if (family == AF_INET6) { + handle->flags |= UV_HANDLE_IPV6; + } else { + assert(!(handle->flags & UV_HANDLE_IPV6)); + } + + return 0; +} + + +int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* handle, unsigned int flags) { + int domain; + + /* Use the lower 8 bits for the domain */ + domain = flags & 0xFF; + if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC) + return UV_EINVAL; + + if (flags & ~0xFF) + return UV_EINVAL; + + uv_stream_init(loop, (uv_stream_t*) handle, UV_TCP); + handle->tcp.serv.accept_reqs = NULL; + handle->tcp.serv.pending_accepts = NULL; + handle->socket = INVALID_SOCKET; + handle->reqs_pending = 0; + handle->tcp.serv.func_acceptex = NULL; + handle->tcp.conn.func_connectex = NULL; + handle->tcp.serv.processed_accepts = 0; + handle->delayed_error = 0; + + /* If anything fails beyond this point we need to remove the handle from + * the handle queue, since it was added by uv__handle_init in uv_stream_init. + */ + + if (domain != AF_UNSPEC) { + SOCKET sock; + DWORD err; + + sock = socket(domain, SOCK_STREAM, 0); + if (sock == INVALID_SOCKET) { + err = WSAGetLastError(); + QUEUE_REMOVE(&handle->handle_queue); + return uv_translate_sys_error(err); + } + + err = uv_tcp_set_socket(handle->loop, handle, sock, domain, 0); + if (err) { + closesocket(sock); + QUEUE_REMOVE(&handle->handle_queue); + return uv_translate_sys_error(err); + } + + } + + return 0; +} + + +int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) { + return uv_tcp_init_ex(loop, handle, AF_UNSPEC); +} + + +void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) { + int err; + unsigned int i; + uv_tcp_accept_t* req; + + if (handle->flags & UV_HANDLE_CONNECTION && + handle->stream.conn.shutdown_req != NULL && + handle->stream.conn.write_reqs_pending == 0) { + + UNREGISTER_HANDLE_REQ(loop, handle, handle->stream.conn.shutdown_req); + + err = 0; + if (handle->flags & UV_HANDLE_CLOSING) { + err = ERROR_OPERATION_ABORTED; + } else if (shutdown(handle->socket, SD_SEND) == SOCKET_ERROR) { + err = WSAGetLastError(); + } + + if (handle->stream.conn.shutdown_req->cb) { + handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, + uv_translate_sys_error(err)); + } + + handle->stream.conn.shutdown_req = NULL; + DECREASE_PENDING_REQ_COUNT(handle); + return; + } + + if (handle->flags & UV_HANDLE_CLOSING && + handle->reqs_pending == 0) { + assert(!(handle->flags & UV_HANDLE_CLOSED)); + assert(handle->socket == INVALID_SOCKET); + + if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->tcp.serv.accept_reqs) { + if (handle->flags & UV_HANDLE_EMULATE_IOCP) { + for (i = 0; i < uv_simultaneous_server_accepts; i++) { + req = &handle->tcp.serv.accept_reqs[i]; + if (req->wait_handle != INVALID_HANDLE_VALUE) { + UnregisterWait(req->wait_handle); + req->wait_handle = INVALID_HANDLE_VALUE; + } + if (req->event_handle != NULL) { + CloseHandle(req->event_handle); + req->event_handle = NULL; + } + } + } + + uv__free(handle->tcp.serv.accept_reqs); + handle->tcp.serv.accept_reqs = NULL; + } + + if (handle->flags & UV_HANDLE_CONNECTION && + handle->flags & UV_HANDLE_EMULATE_IOCP) { + if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) { + UnregisterWait(handle->read_req.wait_handle); + handle->read_req.wait_handle = INVALID_HANDLE_VALUE; + } + if (handle->read_req.event_handle != NULL) { + CloseHandle(handle->read_req.event_handle); + handle->read_req.event_handle = NULL; + } + } + + uv__handle_close(handle); + loop->active_tcp_streams--; + } +} + + +/* Unlike on Unix, here we don't set SO_REUSEADDR, because it doesn't just + * allow binding to addresses that are in use by sockets in TIME_WAIT, it + * effectively allows 'stealing' a port which is in use by another application. + * + * SO_EXCLUSIVEADDRUSE is also not good here because it does check all sockets, + * regardless of state, so we'd get an error even if the port is in use by a + * socket in TIME_WAIT state. + * + * See issue #1360. + * + */ +static int uv_tcp_try_bind(uv_tcp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen, + unsigned int flags) { + DWORD err; + int r; + + if (handle->socket == INVALID_SOCKET) { + SOCKET sock; + + /* Cannot set IPv6-only mode on non-IPv6 socket. */ + if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6) + return ERROR_INVALID_PARAMETER; + + sock = socket(addr->sa_family, SOCK_STREAM, 0); + if (sock == INVALID_SOCKET) { + return WSAGetLastError(); + } + + err = uv_tcp_set_socket(handle->loop, handle, sock, addr->sa_family, 0); + if (err) { + closesocket(sock); + return err; + } + } + +#ifdef IPV6_V6ONLY + if (addr->sa_family == AF_INET6) { + int on; + + on = (flags & UV_TCP_IPV6ONLY) != 0; + + /* TODO: how to handle errors? This may fail if there is no ipv4 stack + * available, or when run on XP/2003 which have no support for dualstack + * sockets. For now we're silently ignoring the error. */ + setsockopt(handle->socket, + IPPROTO_IPV6, + IPV6_V6ONLY, + (const char*)&on, + sizeof on); + } +#endif + + r = bind(handle->socket, addr, addrlen); + + if (r == SOCKET_ERROR) { + err = WSAGetLastError(); + if (err == WSAEADDRINUSE) { + /* Some errors are not to be reported until connect() or listen() */ + handle->delayed_error = err; + } else { + return err; + } + } + + handle->flags |= UV_HANDLE_BOUND; + + return 0; +} + + +static void CALLBACK post_completion(void* context, BOOLEAN timed_out) { + uv_req_t* req; + uv_tcp_t* handle; + + req = (uv_req_t*) context; + assert(req != NULL); + handle = (uv_tcp_t*)req->data; + assert(handle != NULL); + assert(!timed_out); + + if (!PostQueuedCompletionStatus(handle->loop->iocp, + req->u.io.overlapped.InternalHigh, + 0, + &req->u.io.overlapped)) { + uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); + } +} + + +static void CALLBACK post_write_completion(void* context, BOOLEAN timed_out) { + uv_write_t* req; + uv_tcp_t* handle; + + req = (uv_write_t*) context; + assert(req != NULL); + handle = (uv_tcp_t*)req->handle; + assert(handle != NULL); + assert(!timed_out); + + if (!PostQueuedCompletionStatus(handle->loop->iocp, + req->u.io.overlapped.InternalHigh, + 0, + &req->u.io.overlapped)) { + uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); + } +} + + +static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) { + uv_loop_t* loop = handle->loop; + BOOL success; + DWORD bytes; + SOCKET accept_socket; + short family; + + assert(handle->flags & UV_HANDLE_LISTENING); + assert(req->accept_socket == INVALID_SOCKET); + + /* choose family and extension function */ + if (handle->flags & UV_HANDLE_IPV6) { + family = AF_INET6; + } else { + family = AF_INET; + } + + /* Open a socket for the accepted connection. */ + accept_socket = socket(family, SOCK_STREAM, 0); + if (accept_socket == INVALID_SOCKET) { + SET_REQ_ERROR(req, WSAGetLastError()); + uv_insert_pending_req(loop, (uv_req_t*)req); + handle->reqs_pending++; + return; + } + + /* Make the socket non-inheritable */ + if (!SetHandleInformation((HANDLE) accept_socket, HANDLE_FLAG_INHERIT, 0)) { + SET_REQ_ERROR(req, GetLastError()); + uv_insert_pending_req(loop, (uv_req_t*)req); + handle->reqs_pending++; + closesocket(accept_socket); + return; + } + + /* Prepare the overlapped structure. */ + memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped)); + if (handle->flags & UV_HANDLE_EMULATE_IOCP) { + assert(req->event_handle != NULL); + req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); + } + + success = handle->tcp.serv.func_acceptex(handle->socket, + accept_socket, + (void*)req->accept_buffer, + 0, + sizeof(struct sockaddr_storage), + sizeof(struct sockaddr_storage), + &bytes, + &req->u.io.overlapped); + + if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { + /* Process the req without IOCP. */ + req->accept_socket = accept_socket; + handle->reqs_pending++; + uv_insert_pending_req(loop, (uv_req_t*)req); + } else if (UV_SUCCEEDED_WITH_IOCP(success)) { + /* The req will be processed with IOCP. */ + req->accept_socket = accept_socket; + handle->reqs_pending++; + if (handle->flags & UV_HANDLE_EMULATE_IOCP && + req->wait_handle == INVALID_HANDLE_VALUE && + !RegisterWaitForSingleObject(&req->wait_handle, + req->event_handle, post_completion, (void*) req, + INFINITE, WT_EXECUTEINWAITTHREAD)) { + SET_REQ_ERROR(req, GetLastError()); + uv_insert_pending_req(loop, (uv_req_t*)req); + } + } else { + /* Make this req pending reporting an error. */ + SET_REQ_ERROR(req, WSAGetLastError()); + uv_insert_pending_req(loop, (uv_req_t*)req); + handle->reqs_pending++; + /* Destroy the preallocated client socket. */ + closesocket(accept_socket); + /* Destroy the event handle */ + if (handle->flags & UV_HANDLE_EMULATE_IOCP) { + CloseHandle(req->event_handle); + req->event_handle = NULL; + } + } +} + + +static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) { + uv_read_t* req; + uv_buf_t buf; + int result; + DWORD bytes, flags; + + assert(handle->flags & UV_HANDLE_READING); + assert(!(handle->flags & UV_HANDLE_READ_PENDING)); + + req = &handle->read_req; + memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); + + /* + * Preallocate a read buffer if the number of active streams is below + * the threshold. + */ + if (loop->active_tcp_streams < uv_active_tcp_streams_threshold) { + handle->flags &= ~UV_HANDLE_ZERO_READ; + handle->tcp.conn.read_buffer = uv_buf_init(NULL, 0); + handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->tcp.conn.read_buffer); + if (handle->tcp.conn.read_buffer.base == NULL || + handle->tcp.conn.read_buffer.len == 0) { + handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->tcp.conn.read_buffer); + return; + } + assert(handle->tcp.conn.read_buffer.base != NULL); + buf = handle->tcp.conn.read_buffer; + } else { + handle->flags |= UV_HANDLE_ZERO_READ; + buf.base = (char*) &uv_zero_; + buf.len = 0; + } + + /* Prepare the overlapped structure. */ + memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped)); + if (handle->flags & UV_HANDLE_EMULATE_IOCP) { + assert(req->event_handle != NULL); + req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); + } + + flags = 0; + result = WSARecv(handle->socket, + (WSABUF*)&buf, + 1, + &bytes, + &flags, + &req->u.io.overlapped, + NULL); + + handle->flags |= UV_HANDLE_READ_PENDING; + handle->reqs_pending++; + + if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { + /* Process the req without IOCP. */ + req->u.io.overlapped.InternalHigh = bytes; + uv_insert_pending_req(loop, (uv_req_t*)req); + } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { + /* The req will be processed with IOCP. */ + if (handle->flags & UV_HANDLE_EMULATE_IOCP && + req->wait_handle == INVALID_HANDLE_VALUE && + !RegisterWaitForSingleObject(&req->wait_handle, + req->event_handle, post_completion, (void*) req, + INFINITE, WT_EXECUTEINWAITTHREAD)) { + SET_REQ_ERROR(req, GetLastError()); + uv_insert_pending_req(loop, (uv_req_t*)req); + } + } else { + /* Make this req pending reporting an error. */ + SET_REQ_ERROR(req, WSAGetLastError()); + uv_insert_pending_req(loop, (uv_req_t*)req); + } +} + + +int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) { + struct linger l = { 1, 0 }; + + /* Disallow setting SO_LINGER to zero due to some platform inconsistencies */ + if (handle->flags & UV_HANDLE_SHUTTING) + return UV_EINVAL; + + if (0 != setsockopt(handle->socket, SOL_SOCKET, SO_LINGER, (const char*)&l, sizeof(l))) + return uv_translate_sys_error(WSAGetLastError()); + + uv_close((uv_handle_t*) handle, close_cb); + return 0; +} + + +int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { + unsigned int i, simultaneous_accepts; + uv_tcp_accept_t* req; + int err; + + assert(backlog > 0); + + if (handle->flags & UV_HANDLE_LISTENING) { + handle->stream.serv.connection_cb = cb; + } + + if (handle->flags & UV_HANDLE_READING) { + return WSAEISCONN; + } + + if (handle->delayed_error) { + return handle->delayed_error; + } + + if (!(handle->flags & UV_HANDLE_BOUND)) { + err = uv_tcp_try_bind(handle, + (const struct sockaddr*) &uv_addr_ip4_any_, + sizeof(uv_addr_ip4_any_), + 0); + if (err) + return err; + if (handle->delayed_error) + return handle->delayed_error; + } + + if (!handle->tcp.serv.func_acceptex) { + if (!uv_get_acceptex_function(handle->socket, &handle->tcp.serv.func_acceptex)) { + return WSAEAFNOSUPPORT; + } + } + + /* If this flag is set, we already made this listen call in xfer. */ + if (!(handle->flags & UV_HANDLE_SHARED_TCP_SOCKET) && + listen(handle->socket, backlog) == SOCKET_ERROR) { + return WSAGetLastError(); + } + + handle->flags |= UV_HANDLE_LISTENING; + handle->stream.serv.connection_cb = cb; + INCREASE_ACTIVE_COUNT(loop, handle); + + simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1 + : uv_simultaneous_server_accepts; + + if (handle->tcp.serv.accept_reqs == NULL) { + handle->tcp.serv.accept_reqs = + uv__malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t)); + if (!handle->tcp.serv.accept_reqs) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + for (i = 0; i < simultaneous_accepts; i++) { + req = &handle->tcp.serv.accept_reqs[i]; + UV_REQ_INIT(req, UV_ACCEPT); + req->accept_socket = INVALID_SOCKET; + req->data = handle; + + req->wait_handle = INVALID_HANDLE_VALUE; + if (handle->flags & UV_HANDLE_EMULATE_IOCP) { + req->event_handle = CreateEvent(NULL, 0, 0, NULL); + if (req->event_handle == NULL) { + uv_fatal_error(GetLastError(), "CreateEvent"); + } + } else { + req->event_handle = NULL; + } + + uv_tcp_queue_accept(handle, req); + } + + /* Initialize other unused requests too, because uv_tcp_endgame doesn't + * know how many requests were initialized, so it will try to clean up + * {uv_simultaneous_server_accepts} requests. */ + for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) { + req = &handle->tcp.serv.accept_reqs[i]; + UV_REQ_INIT(req, UV_ACCEPT); + req->accept_socket = INVALID_SOCKET; + req->data = handle; + req->wait_handle = INVALID_HANDLE_VALUE; + req->event_handle = NULL; + } + } + + return 0; +} + + +int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) { + uv_loop_t* loop = server->loop; + int err = 0; + int family; + + uv_tcp_accept_t* req = server->tcp.serv.pending_accepts; + + if (!req) { + /* No valid connections found, so we error out. */ + return WSAEWOULDBLOCK; + } + + if (req->accept_socket == INVALID_SOCKET) { + return WSAENOTCONN; + } + + if (server->flags & UV_HANDLE_IPV6) { + family = AF_INET6; + } else { + family = AF_INET; + } + + err = uv_tcp_set_socket(client->loop, + client, + req->accept_socket, + family, + 0); + if (err) { + closesocket(req->accept_socket); + } else { + uv_connection_init((uv_stream_t*) client); + /* AcceptEx() implicitly binds the accepted socket. */ + client->flags |= UV_HANDLE_BOUND | UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; + } + + /* Prepare the req to pick up a new connection */ + server->tcp.serv.pending_accepts = req->next_pending; + req->next_pending = NULL; + req->accept_socket = INVALID_SOCKET; + + if (!(server->flags & UV_HANDLE_CLOSING)) { + /* Check if we're in a middle of changing the number of pending accepts. */ + if (!(server->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING)) { + uv_tcp_queue_accept(server, req); + } else { + /* We better be switching to a single pending accept. */ + assert(server->flags & UV_HANDLE_TCP_SINGLE_ACCEPT); + + server->tcp.serv.processed_accepts++; + + if (server->tcp.serv.processed_accepts >= uv_simultaneous_server_accepts) { + server->tcp.serv.processed_accepts = 0; + /* + * All previously queued accept requests are now processed. + * We now switch to queueing just a single accept. + */ + uv_tcp_queue_accept(server, &server->tcp.serv.accept_reqs[0]); + server->flags &= ~UV_HANDLE_TCP_ACCEPT_STATE_CHANGING; + server->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT; + } + } + } + + loop->active_tcp_streams++; + + return err; +} + + +int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, + uv_read_cb read_cb) { + uv_loop_t* loop = handle->loop; + + handle->flags |= UV_HANDLE_READING; + handle->read_cb = read_cb; + handle->alloc_cb = alloc_cb; + INCREASE_ACTIVE_COUNT(loop, handle); + + /* If reading was stopped and then started again, there could still be a read + * request pending. */ + if (!(handle->flags & UV_HANDLE_READ_PENDING)) { + if (handle->flags & UV_HANDLE_EMULATE_IOCP && + handle->read_req.event_handle == NULL) { + handle->read_req.event_handle = CreateEvent(NULL, 0, 0, NULL); + if (handle->read_req.event_handle == NULL) { + uv_fatal_error(GetLastError(), "CreateEvent"); + } + } + uv_tcp_queue_read(loop, handle); + } + + return 0; +} + +static int uv__is_loopback(const struct sockaddr_storage* storage) { + const struct sockaddr_in* in4; + const struct sockaddr_in6* in6; + int i; + + if (storage->ss_family == AF_INET) { + in4 = (const struct sockaddr_in*) storage; + return in4->sin_addr.S_un.S_un_b.s_b1 == 127; + } + if (storage->ss_family == AF_INET6) { + in6 = (const struct sockaddr_in6*) storage; + for (i = 0; i < 7; ++i) { + if (in6->sin6_addr.u.Word[i] != 0) + return 0; + } + return in6->sin6_addr.u.Word[7] == htons(1); + } + return 0; +} + +// Check if Windows version is 10.0.16299 or later +static int uv__is_fast_loopback_fail_supported(void) { + OSVERSIONINFOW os_info; + if (!pRtlGetVersion) + return 0; + pRtlGetVersion(&os_info); + if (os_info.dwMajorVersion < 10) + return 0; + if (os_info.dwMajorVersion > 10) + return 1; + if (os_info.dwMinorVersion > 0) + return 1; + return os_info.dwBuildNumber >= 16299; +} + +static int uv_tcp_try_connect(uv_connect_t* req, + uv_tcp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen, + uv_connect_cb cb) { + uv_loop_t* loop = handle->loop; + TCP_INITIAL_RTO_PARAMETERS retransmit_ioctl; + const struct sockaddr* bind_addr; + struct sockaddr_storage converted; + BOOL success; + DWORD bytes; + int err; + + err = uv__convert_to_localhost_if_unspecified(addr, &converted); + if (err) + return err; + + if (handle->delayed_error != 0) + goto out; + + if (!(handle->flags & UV_HANDLE_BOUND)) { + if (addrlen == sizeof(uv_addr_ip4_any_)) { + bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; + } else if (addrlen == sizeof(uv_addr_ip6_any_)) { + bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; + } else { + abort(); + } + err = uv_tcp_try_bind(handle, bind_addr, addrlen, 0); + if (err) + return err; + if (handle->delayed_error != 0) + goto out; + } + + if (!handle->tcp.conn.func_connectex) { + if (!uv_get_connectex_function(handle->socket, &handle->tcp.conn.func_connectex)) { + return WSAEAFNOSUPPORT; + } + } + + /* This makes connect() fail instantly if the target port on the localhost + * is not reachable, instead of waiting for 2s. We do not care if this fails. + * This only works on Windows version 10.0.16299 and later. + */ + if (uv__is_fast_loopback_fail_supported() && uv__is_loopback(&converted)) { + memset(&retransmit_ioctl, 0, sizeof(retransmit_ioctl)); + retransmit_ioctl.Rtt = TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS; + retransmit_ioctl.MaxSynRetransmissions = TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS; + WSAIoctl(handle->socket, + SIO_TCP_INITIAL_RTO, + &retransmit_ioctl, + sizeof(retransmit_ioctl), + NULL, + 0, + &bytes, + NULL, + NULL); + } + +out: + + UV_REQ_INIT(req, UV_CONNECT); + req->handle = (uv_stream_t*) handle; + req->cb = cb; + memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); + + if (handle->delayed_error != 0) { + /* Process the req without IOCP. */ + handle->reqs_pending++; + REGISTER_HANDLE_REQ(loop, handle, req); + uv_insert_pending_req(loop, (uv_req_t*)req); + return 0; + } + + success = handle->tcp.conn.func_connectex(handle->socket, + (const struct sockaddr*) &converted, + addrlen, + NULL, + 0, + &bytes, + &req->u.io.overlapped); + + if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { + /* Process the req without IOCP. */ + handle->reqs_pending++; + REGISTER_HANDLE_REQ(loop, handle, req); + uv_insert_pending_req(loop, (uv_req_t*)req); + } else if (UV_SUCCEEDED_WITH_IOCP(success)) { + /* The req will be processed with IOCP. */ + handle->reqs_pending++; + REGISTER_HANDLE_REQ(loop, handle, req); + } else { + return WSAGetLastError(); + } + + return 0; +} + + +int uv_tcp_getsockname(const uv_tcp_t* handle, + struct sockaddr* name, + int* namelen) { + + return uv__getsockpeername((const uv_handle_t*) handle, + getsockname, + name, + namelen, + handle->delayed_error); +} + + +int uv_tcp_getpeername(const uv_tcp_t* handle, + struct sockaddr* name, + int* namelen) { + + return uv__getsockpeername((const uv_handle_t*) handle, + getpeername, + name, + namelen, + handle->delayed_error); +} + + +int uv_tcp_write(uv_loop_t* loop, + uv_write_t* req, + uv_tcp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_write_cb cb) { + int result; + DWORD bytes; + + UV_REQ_INIT(req, UV_WRITE); + req->handle = (uv_stream_t*) handle; + req->cb = cb; + + /* Prepare the overlapped structure. */ + memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped)); + if (handle->flags & UV_HANDLE_EMULATE_IOCP) { + req->event_handle = CreateEvent(NULL, 0, 0, NULL); + if (req->event_handle == NULL) { + uv_fatal_error(GetLastError(), "CreateEvent"); + } + req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); + req->wait_handle = INVALID_HANDLE_VALUE; + } + + result = WSASend(handle->socket, + (WSABUF*) bufs, + nbufs, + &bytes, + 0, + &req->u.io.overlapped, + NULL); + + if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { + /* Request completed immediately. */ + req->u.io.queued_bytes = 0; + handle->reqs_pending++; + handle->stream.conn.write_reqs_pending++; + REGISTER_HANDLE_REQ(loop, handle, req); + uv_insert_pending_req(loop, (uv_req_t*) req); + } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { + /* Request queued by the kernel. */ + req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs); + handle->reqs_pending++; + handle->stream.conn.write_reqs_pending++; + REGISTER_HANDLE_REQ(loop, handle, req); + handle->write_queue_size += req->u.io.queued_bytes; + if (handle->flags & UV_HANDLE_EMULATE_IOCP && + !RegisterWaitForSingleObject(&req->wait_handle, + req->event_handle, post_write_completion, (void*) req, + INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) { + SET_REQ_ERROR(req, GetLastError()); + uv_insert_pending_req(loop, (uv_req_t*)req); + } + } else { + /* Send failed due to an error, report it later */ + req->u.io.queued_bytes = 0; + handle->reqs_pending++; + handle->stream.conn.write_reqs_pending++; + REGISTER_HANDLE_REQ(loop, handle, req); + SET_REQ_ERROR(req, WSAGetLastError()); + uv_insert_pending_req(loop, (uv_req_t*) req); + } + + return 0; +} + + +int uv__tcp_try_write(uv_tcp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs) { + int result; + DWORD bytes; + + if (handle->stream.conn.write_reqs_pending > 0) + return UV_EAGAIN; + + result = WSASend(handle->socket, + (WSABUF*) bufs, + nbufs, + &bytes, + 0, + NULL, + NULL); + + if (result == SOCKET_ERROR) + return uv_translate_sys_error(WSAGetLastError()); + else + return bytes; +} + + +void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, + uv_req_t* req) { + DWORD bytes, flags, err; + uv_buf_t buf; + int count; + + assert(handle->type == UV_TCP); + + handle->flags &= ~UV_HANDLE_READ_PENDING; + + if (!REQ_SUCCESS(req)) { + /* An error occurred doing the read. */ + if ((handle->flags & UV_HANDLE_READING) || + !(handle->flags & UV_HANDLE_ZERO_READ)) { + handle->flags &= ~UV_HANDLE_READING; + DECREASE_ACTIVE_COUNT(loop, handle); + buf = (handle->flags & UV_HANDLE_ZERO_READ) ? + uv_buf_init(NULL, 0) : handle->tcp.conn.read_buffer; + + err = GET_REQ_SOCK_ERROR(req); + + if (err == WSAECONNABORTED) { + /* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix. + */ + err = WSAECONNRESET; + } + handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); + + handle->read_cb((uv_stream_t*)handle, + uv_translate_sys_error(err), + &buf); + } + } else { + if (!(handle->flags & UV_HANDLE_ZERO_READ)) { + /* The read was done with a non-zero buffer length. */ + if (req->u.io.overlapped.InternalHigh > 0) { + /* Successful read */ + handle->read_cb((uv_stream_t*)handle, + req->u.io.overlapped.InternalHigh, + &handle->tcp.conn.read_buffer); + /* Read again only if bytes == buf.len */ + if (req->u.io.overlapped.InternalHigh < handle->tcp.conn.read_buffer.len) { + goto done; + } + } else { + /* Connection closed */ + if (handle->flags & UV_HANDLE_READING) { + handle->flags &= ~UV_HANDLE_READING; + DECREASE_ACTIVE_COUNT(loop, handle); + } + handle->flags &= ~UV_HANDLE_READABLE; + + buf.base = 0; + buf.len = 0; + handle->read_cb((uv_stream_t*)handle, UV_EOF, &handle->tcp.conn.read_buffer); + goto done; + } + } + + /* Do nonblocking reads until the buffer is empty */ + count = 32; + while ((handle->flags & UV_HANDLE_READING) && (count-- > 0)) { + buf = uv_buf_init(NULL, 0); + handle->alloc_cb((uv_handle_t*) handle, 65536, &buf); + if (buf.base == NULL || buf.len == 0) { + handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf); + break; + } + assert(buf.base != NULL); + + flags = 0; + if (WSARecv(handle->socket, + (WSABUF*)&buf, + 1, + &bytes, + &flags, + NULL, + NULL) != SOCKET_ERROR) { + if (bytes > 0) { + /* Successful read */ + handle->read_cb((uv_stream_t*)handle, bytes, &buf); + /* Read again only if bytes == buf.len */ + if (bytes < buf.len) { + break; + } + } else { + /* Connection closed */ + handle->flags &= ~(UV_HANDLE_READING | UV_HANDLE_READABLE); + DECREASE_ACTIVE_COUNT(loop, handle); + + handle->read_cb((uv_stream_t*)handle, UV_EOF, &buf); + break; + } + } else { + err = WSAGetLastError(); + if (err == WSAEWOULDBLOCK) { + /* Read buffer was completely empty, report a 0-byte read. */ + handle->read_cb((uv_stream_t*)handle, 0, &buf); + } else { + /* Ouch! serious error. */ + handle->flags &= ~UV_HANDLE_READING; + DECREASE_ACTIVE_COUNT(loop, handle); + + if (err == WSAECONNABORTED) { + /* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with + * Unix. */ + err = WSAECONNRESET; + } + handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); + + handle->read_cb((uv_stream_t*)handle, + uv_translate_sys_error(err), + &buf); + } + break; + } + } + +done: + /* Post another read if still reading and not closing. */ + if ((handle->flags & UV_HANDLE_READING) && + !(handle->flags & UV_HANDLE_READ_PENDING)) { + uv_tcp_queue_read(loop, handle); + } + } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle, + uv_write_t* req) { + int err; + + assert(handle->type == UV_TCP); + + assert(handle->write_queue_size >= req->u.io.queued_bytes); + handle->write_queue_size -= req->u.io.queued_bytes; + + UNREGISTER_HANDLE_REQ(loop, handle, req); + + if (handle->flags & UV_HANDLE_EMULATE_IOCP) { + if (req->wait_handle != INVALID_HANDLE_VALUE) { + UnregisterWait(req->wait_handle); + req->wait_handle = INVALID_HANDLE_VALUE; + } + if (req->event_handle != NULL) { + CloseHandle(req->event_handle); + req->event_handle = NULL; + } + } + + if (req->cb) { + err = uv_translate_sys_error(GET_REQ_SOCK_ERROR(req)); + if (err == UV_ECONNABORTED) { + /* use UV_ECANCELED for consistency with Unix */ + err = UV_ECANCELED; + } + req->cb(req, err); + } + + handle->stream.conn.write_reqs_pending--; + if (handle->stream.conn.write_reqs_pending == 0) { + if (handle->flags & UV_HANDLE_CLOSING) { + closesocket(handle->socket); + handle->socket = INVALID_SOCKET; + } + if (handle->stream.conn.shutdown_req != NULL) { + uv_want_endgame(loop, (uv_handle_t*)handle); + } + } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle, + uv_req_t* raw_req) { + uv_tcp_accept_t* req = (uv_tcp_accept_t*) raw_req; + int err; + + assert(handle->type == UV_TCP); + + /* If handle->accepted_socket is not a valid socket, then uv_queue_accept + * must have failed. This is a serious error. We stop accepting connections + * and report this error to the connection callback. */ + if (req->accept_socket == INVALID_SOCKET) { + if (handle->flags & UV_HANDLE_LISTENING) { + handle->flags &= ~UV_HANDLE_LISTENING; + DECREASE_ACTIVE_COUNT(loop, handle); + if (handle->stream.serv.connection_cb) { + err = GET_REQ_SOCK_ERROR(req); + handle->stream.serv.connection_cb((uv_stream_t*)handle, + uv_translate_sys_error(err)); + } + } + } else if (REQ_SUCCESS(req) && + setsockopt(req->accept_socket, + SOL_SOCKET, + SO_UPDATE_ACCEPT_CONTEXT, + (char*)&handle->socket, + sizeof(handle->socket)) == 0) { + req->next_pending = handle->tcp.serv.pending_accepts; + handle->tcp.serv.pending_accepts = req; + + /* Accept and SO_UPDATE_ACCEPT_CONTEXT were successful. */ + if (handle->stream.serv.connection_cb) { + handle->stream.serv.connection_cb((uv_stream_t*)handle, 0); + } + } else { + /* Error related to accepted socket is ignored because the server socket + * may still be healthy. If the server socket is broken uv_queue_accept + * will detect it. */ + closesocket(req->accept_socket); + req->accept_socket = INVALID_SOCKET; + if (handle->flags & UV_HANDLE_LISTENING) { + uv_tcp_queue_accept(handle, req); + } + } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle, + uv_connect_t* req) { + int err; + + assert(handle->type == UV_TCP); + + UNREGISTER_HANDLE_REQ(loop, handle, req); + + err = 0; + if (handle->delayed_error) { + /* To smooth over the differences between unixes errors that + * were reported synchronously on the first connect can be delayed + * until the next tick--which is now. + */ + err = handle->delayed_error; + handle->delayed_error = 0; + } else if (REQ_SUCCESS(req)) { + if (handle->flags & UV_HANDLE_CLOSING) { + /* use UV_ECANCELED for consistency with Unix */ + err = ERROR_OPERATION_ABORTED; + } else if (setsockopt(handle->socket, + SOL_SOCKET, + SO_UPDATE_CONNECT_CONTEXT, + NULL, + 0) == 0) { + uv_connection_init((uv_stream_t*)handle); + handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; + loop->active_tcp_streams++; + } else { + err = WSAGetLastError(); + } + } else { + err = GET_REQ_SOCK_ERROR(req); + } + req->cb(req, uv_translate_sys_error(err)); + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +int uv__tcp_xfer_export(uv_tcp_t* handle, + int target_pid, + uv__ipc_socket_xfer_type_t* xfer_type, + uv__ipc_socket_xfer_info_t* xfer_info) { + if (handle->flags & UV_HANDLE_CONNECTION) { + *xfer_type = UV__IPC_SOCKET_XFER_TCP_CONNECTION; + } else { + *xfer_type = UV__IPC_SOCKET_XFER_TCP_SERVER; + /* We're about to share the socket with another process. Because this is a + * listening socket, we assume that the other process will be accepting + * connections on it. Thus, before sharing the socket with another process, + * we call listen here in the parent process. */ + if (!(handle->flags & UV_HANDLE_LISTENING)) { + if (!(handle->flags & UV_HANDLE_BOUND)) { + return ERROR_NOT_SUPPORTED; + } + if (handle->delayed_error == 0 && + listen(handle->socket, SOMAXCONN) == SOCKET_ERROR) { + handle->delayed_error = WSAGetLastError(); + } + } + } + + if (WSADuplicateSocketW(handle->socket, target_pid, &xfer_info->socket_info)) + return WSAGetLastError(); + xfer_info->delayed_error = handle->delayed_error; + + /* Mark the local copy of the handle as 'shared' so we behave in a way that's + * friendly to the process(es) that we share the socket with. */ + handle->flags |= UV_HANDLE_SHARED_TCP_SOCKET; + + return 0; +} + + +int uv__tcp_xfer_import(uv_tcp_t* tcp, + uv__ipc_socket_xfer_type_t xfer_type, + uv__ipc_socket_xfer_info_t* xfer_info) { + int err; + SOCKET socket; + + assert(xfer_type == UV__IPC_SOCKET_XFER_TCP_SERVER || + xfer_type == UV__IPC_SOCKET_XFER_TCP_CONNECTION); + + socket = WSASocketW(FROM_PROTOCOL_INFO, + FROM_PROTOCOL_INFO, + FROM_PROTOCOL_INFO, + &xfer_info->socket_info, + 0, + WSA_FLAG_OVERLAPPED); + + if (socket == INVALID_SOCKET) { + return WSAGetLastError(); + } + + err = uv_tcp_set_socket( + tcp->loop, tcp, socket, xfer_info->socket_info.iAddressFamily, 1); + if (err) { + closesocket(socket); + return err; + } + + tcp->delayed_error = xfer_info->delayed_error; + tcp->flags |= UV_HANDLE_BOUND | UV_HANDLE_SHARED_TCP_SOCKET; + + if (xfer_type == UV__IPC_SOCKET_XFER_TCP_CONNECTION) { + uv_connection_init((uv_stream_t*)tcp); + tcp->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; + } + + tcp->loop->active_tcp_streams++; + return 0; +} + + +int uv_tcp_nodelay(uv_tcp_t* handle, int enable) { + int err; + + if (handle->socket != INVALID_SOCKET) { + err = uv__tcp_nodelay(handle, handle->socket, enable); + if (err) + return uv_translate_sys_error(err); + } + + if (enable) { + handle->flags |= UV_HANDLE_TCP_NODELAY; + } else { + handle->flags &= ~UV_HANDLE_TCP_NODELAY; + } + + return 0; +} + + +int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) { + int err; + + if (handle->socket != INVALID_SOCKET) { + err = uv__tcp_keepalive(handle, handle->socket, enable, delay); + if (err) + return uv_translate_sys_error(err); + } + + if (enable) { + handle->flags |= UV_HANDLE_TCP_KEEPALIVE; + } else { + handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE; + } + + /* TODO: Store delay if handle->socket isn't created yet. */ + + return 0; +} + + +int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) { + if (handle->flags & UV_HANDLE_CONNECTION) { + return UV_EINVAL; + } + + /* Check if we're already in the desired mode. */ + if ((enable && !(handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) || + (!enable && handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) { + return 0; + } + + /* Don't allow switching from single pending accept to many. */ + if (enable) { + return UV_ENOTSUP; + } + + /* Check if we're in a middle of changing the number of pending accepts. */ + if (handle->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING) { + return 0; + } + + handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT; + + /* Flip the changing flag if we have already queued multiple accepts. */ + if (handle->flags & UV_HANDLE_LISTENING) { + handle->flags |= UV_HANDLE_TCP_ACCEPT_STATE_CHANGING; + } + + return 0; +} + + +static void uv_tcp_try_cancel_reqs(uv_tcp_t* tcp) { + SOCKET socket; + int non_ifs_lsp; + int reading; + int writing; + + socket = tcp->socket; + reading = tcp->flags & UV_HANDLE_READING; + writing = tcp->stream.conn.write_reqs_pending > 0; + if (!reading && !writing) + return; + + /* TODO: in libuv v2, keep explicit track of write_reqs, so we can cancel + * them each explicitly with CancelIoEx (like unix). */ + if (reading) + CancelIoEx((HANDLE) socket, &tcp->read_req.u.io.overlapped); + if (writing) + CancelIo((HANDLE) socket); + + /* Check if we have any non-IFS LSPs stacked on top of TCP */ + non_ifs_lsp = (tcp->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 : + uv_tcp_non_ifs_lsp_ipv4; + + /* If there are non-ifs LSPs then try to obtain a base handle for the socket. + * This will always fail on Windows XP/3k. */ + if (non_ifs_lsp) { + DWORD bytes; + if (WSAIoctl(socket, + SIO_BASE_HANDLE, + NULL, + 0, + &socket, + sizeof socket, + &bytes, + NULL, + NULL) != 0) { + /* Failed. We can't do CancelIo. */ + return; + } + } + + assert(socket != 0 && socket != INVALID_SOCKET); + + if (socket != tcp->socket) { + if (reading) + CancelIoEx((HANDLE) socket, &tcp->read_req.u.io.overlapped); + if (writing) + CancelIo((HANDLE) socket); + } +} + + +void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) { + if (tcp->flags & UV_HANDLE_CONNECTION) { + uv_tcp_try_cancel_reqs(tcp); + if (tcp->flags & UV_HANDLE_READING) { + uv_read_stop((uv_stream_t*) tcp); + } + } else { + if (tcp->tcp.serv.accept_reqs != NULL) { + /* First close the incoming sockets to cancel the accept operations before + * we free their resources. */ + unsigned int i; + for (i = 0; i < uv_simultaneous_server_accepts; i++) { + uv_tcp_accept_t* req = &tcp->tcp.serv.accept_reqs[i]; + if (req->accept_socket != INVALID_SOCKET) { + closesocket(req->accept_socket); + req->accept_socket = INVALID_SOCKET; + } + } + } + assert(!(tcp->flags & UV_HANDLE_READING)); + } + + if (tcp->flags & UV_HANDLE_LISTENING) { + tcp->flags &= ~UV_HANDLE_LISTENING; + DECREASE_ACTIVE_COUNT(loop, tcp); + } + + /* If any overlapped req failed to cancel, calling `closesocket` now would + * cause Win32 to send an RST packet. Try to avoid that for writes, if + * possibly applicable, by waiting to process the completion notifications + * first (which typically should be cancellations). There's not much we can + * do about canceled reads, which also will generate an RST packet. */ + if (!(tcp->flags & UV_HANDLE_CONNECTION) || + tcp->stream.conn.write_reqs_pending == 0) { + closesocket(tcp->socket); + tcp->socket = INVALID_SOCKET; + } + + tcp->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); + uv__handle_closing(tcp); + + if (tcp->reqs_pending == 0) { + uv_want_endgame(tcp->loop, (uv_handle_t*)tcp); + } +} + + +int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) { + WSAPROTOCOL_INFOW protocol_info; + int opt_len; + int err; + struct sockaddr_storage saddr; + int saddr_len; + + /* Detect the address family of the socket. */ + opt_len = (int) sizeof protocol_info; + if (getsockopt(sock, + SOL_SOCKET, + SO_PROTOCOL_INFOW, + (char*) &protocol_info, + &opt_len) == SOCKET_ERROR) { + return uv_translate_sys_error(GetLastError()); + } + + err = uv_tcp_set_socket(handle->loop, + handle, + sock, + protocol_info.iAddressFamily, + 1); + if (err) { + return uv_translate_sys_error(err); + } + + /* Support already active socket. */ + saddr_len = sizeof(saddr); + if (!uv_tcp_getsockname(handle, (struct sockaddr*) &saddr, &saddr_len)) { + /* Socket is already bound. */ + handle->flags |= UV_HANDLE_BOUND; + saddr_len = sizeof(saddr); + if (!uv_tcp_getpeername(handle, (struct sockaddr*) &saddr, &saddr_len)) { + /* Socket is already connected. */ + uv_connection_init((uv_stream_t*) handle); + handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; + } + } + + return 0; +} + + +/* This function is an egress point, i.e. it returns libuv errors rather than + * system errors. + */ +int uv__tcp_bind(uv_tcp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen, + unsigned int flags) { + int err; + + err = uv_tcp_try_bind(handle, addr, addrlen, flags); + if (err) + return uv_translate_sys_error(err); + + return 0; +} + + +/* This function is an egress point, i.e. it returns libuv errors rather than + * system errors. + */ +int uv__tcp_connect(uv_connect_t* req, + uv_tcp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen, + uv_connect_cb cb) { + int err; + + err = uv_tcp_try_connect(req, handle, addr, addrlen, cb); + if (err) + return uv_translate_sys_error(err); + + return 0; +} + +#ifndef WSA_FLAG_NO_HANDLE_INHERIT +/* Added in Windows 7 SP1. Specify this to avoid race conditions, */ +/* but also manually clear the inherit flag in case this failed. */ +#define WSA_FLAG_NO_HANDLE_INHERIT 0x80 +#endif + +int uv_socketpair(int type, int protocol, uv_os_sock_t fds[2], int flags0, int flags1) { + SOCKET server = INVALID_SOCKET; + SOCKET client0 = INVALID_SOCKET; + SOCKET client1 = INVALID_SOCKET; + SOCKADDR_IN name; + LPFN_ACCEPTEX func_acceptex; + WSAOVERLAPPED overlap; + char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32]; + int namelen; + int err; + DWORD bytes; + DWORD flags; + DWORD client0_flags = WSA_FLAG_NO_HANDLE_INHERIT; + DWORD client1_flags = WSA_FLAG_NO_HANDLE_INHERIT; + + if (flags0 & UV_NONBLOCK_PIPE) + client0_flags |= WSA_FLAG_OVERLAPPED; + if (flags1 & UV_NONBLOCK_PIPE) + client1_flags |= WSA_FLAG_OVERLAPPED; + + server = WSASocketW(AF_INET, type, protocol, NULL, 0, + WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT); + if (server == INVALID_SOCKET) + goto wsaerror; + if (!SetHandleInformation((HANDLE) server, HANDLE_FLAG_INHERIT, 0)) + goto error; + name.sin_family = AF_INET; + name.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + name.sin_port = 0; + if (bind(server, (SOCKADDR*) &name, sizeof(name)) != 0) + goto wsaerror; + if (listen(server, 1) != 0) + goto wsaerror; + namelen = sizeof(name); + if (getsockname(server, (SOCKADDR*) &name, &namelen) != 0) + goto wsaerror; + client0 = WSASocketW(AF_INET, type, protocol, NULL, 0, client0_flags); + if (client0 == INVALID_SOCKET) + goto wsaerror; + if (!SetHandleInformation((HANDLE) client0, HANDLE_FLAG_INHERIT, 0)) + goto error; + if (connect(client0, (SOCKADDR*) &name, sizeof(name)) != 0) + goto wsaerror; + client1 = WSASocketW(AF_INET, type, protocol, NULL, 0, client1_flags); + if (client1 == INVALID_SOCKET) + goto wsaerror; + if (!SetHandleInformation((HANDLE) client1, HANDLE_FLAG_INHERIT, 0)) + goto error; + if (!uv_get_acceptex_function(server, &func_acceptex)) { + err = WSAEAFNOSUPPORT; + goto cleanup; + } + memset(&overlap, 0, sizeof(overlap)); + if (!func_acceptex(server, + client1, + accept_buffer, + 0, + sizeof(struct sockaddr_storage), + sizeof(struct sockaddr_storage), + &bytes, + &overlap)) { + err = WSAGetLastError(); + if (err == ERROR_IO_PENDING) { + /* Result should complete immediately, since we already called connect, + * but emperically, we sometimes have to poll the kernel a couple times + * until it notices that. */ + while (!WSAGetOverlappedResult(client1, &overlap, &bytes, FALSE, &flags)) { + err = WSAGetLastError(); + if (err != WSA_IO_INCOMPLETE) + goto cleanup; + SwitchToThread(); + } + } + else { + goto cleanup; + } + } + if (setsockopt(client1, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, + (char*) &server, sizeof(server)) != 0) { + goto wsaerror; + } + + closesocket(server); + + fds[0] = client0; + fds[1] = client1; + + return 0; + + wsaerror: + err = WSAGetLastError(); + goto cleanup; + + error: + err = GetLastError(); + goto cleanup; + + cleanup: + if (server != INVALID_SOCKET) + closesocket(server); + if (client0 != INVALID_SOCKET) + closesocket(client0); + if (client1 != INVALID_SOCKET) + closesocket(client1); + + assert(err); + return uv_translate_sys_error(err); +} diff --git a/external/src/libuv/src/win/thread.c b/external/src/libuv/src/win/thread.c new file mode 100644 index 0000000..89c53ad --- /dev/null +++ b/external/src/libuv/src/win/thread.c @@ -0,0 +1,520 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include + +#if defined(__MINGW64_VERSION_MAJOR) +/* MemoryBarrier expands to __mm_mfence in some cases (x86+sse2), which may + * require this header in some versions of mingw64. */ +#include +#endif + +#include "uv.h" +#include "internal.h" + +static void uv__once_inner(uv_once_t* guard, void (*callback)(void)) { + DWORD result; + HANDLE existing_event, created_event; + + created_event = CreateEvent(NULL, 1, 0, NULL); + if (created_event == 0) { + /* Could fail in a low-memory situation? */ + uv_fatal_error(GetLastError(), "CreateEvent"); + } + + existing_event = InterlockedCompareExchangePointer(&guard->event, + created_event, + NULL); + + if (existing_event == NULL) { + /* We won the race */ + callback(); + + result = SetEvent(created_event); + assert(result); + guard->ran = 1; + + } else { + /* We lost the race. Destroy the event we created and wait for the existing + * one to become signaled. */ + CloseHandle(created_event); + result = WaitForSingleObject(existing_event, INFINITE); + assert(result == WAIT_OBJECT_0); + } +} + + +void uv_once(uv_once_t* guard, void (*callback)(void)) { + /* Fast case - avoid WaitForSingleObject. */ + if (guard->ran) { + return; + } + + uv__once_inner(guard, callback); +} + + +/* Verify that uv_thread_t can be stored in a TLS slot. */ +STATIC_ASSERT(sizeof(uv_thread_t) <= sizeof(void*)); + +static uv_key_t uv__current_thread_key; +static uv_once_t uv__current_thread_init_guard = UV_ONCE_INIT; + + +static void uv__init_current_thread_key(void) { + if (uv_key_create(&uv__current_thread_key)) + abort(); +} + + +struct thread_ctx { + void (*entry)(void* arg); + void* arg; + uv_thread_t self; +}; + + +static UINT __stdcall uv__thread_start(void* arg) { + struct thread_ctx *ctx_p; + struct thread_ctx ctx; + + ctx_p = arg; + ctx = *ctx_p; + uv__free(ctx_p); + + uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key); + uv_key_set(&uv__current_thread_key, (void*) ctx.self); + + ctx.entry(ctx.arg); + + return 0; +} + + +int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) { + uv_thread_options_t params; + params.flags = UV_THREAD_NO_FLAGS; + return uv_thread_create_ex(tid, ¶ms, entry, arg); +} + +int uv_thread_create_ex(uv_thread_t* tid, + const uv_thread_options_t* params, + void (*entry)(void *arg), + void *arg) { + struct thread_ctx* ctx; + int err; + HANDLE thread; + SYSTEM_INFO sysinfo; + size_t stack_size; + size_t pagesize; + + stack_size = + params->flags & UV_THREAD_HAS_STACK_SIZE ? params->stack_size : 0; + + if (stack_size != 0) { + GetNativeSystemInfo(&sysinfo); + pagesize = (size_t)sysinfo.dwPageSize; + /* Round up to the nearest page boundary. */ + stack_size = (stack_size + pagesize - 1) &~ (pagesize - 1); + + if ((unsigned)stack_size != stack_size) + return UV_EINVAL; + } + + ctx = uv__malloc(sizeof(*ctx)); + if (ctx == NULL) + return UV_ENOMEM; + + ctx->entry = entry; + ctx->arg = arg; + + /* Create the thread in suspended state so we have a chance to pass + * its own creation handle to it */ + thread = (HANDLE) _beginthreadex(NULL, + (unsigned)stack_size, + uv__thread_start, + ctx, + CREATE_SUSPENDED, + NULL); + if (thread == NULL) { + err = errno; + uv__free(ctx); + } else { + err = 0; + *tid = thread; + ctx->self = thread; + ResumeThread(thread); + } + + switch (err) { + case 0: + return 0; + case EACCES: + return UV_EACCES; + case EAGAIN: + return UV_EAGAIN; + case EINVAL: + return UV_EINVAL; + } + + return UV_EIO; +} + + +uv_thread_t uv_thread_self(void) { + uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key); + return (uv_thread_t) uv_key_get(&uv__current_thread_key); +} + + +int uv_thread_join(uv_thread_t *tid) { + if (WaitForSingleObject(*tid, INFINITE)) + return uv_translate_sys_error(GetLastError()); + else { + CloseHandle(*tid); + *tid = 0; + MemoryBarrier(); /* For feature parity with pthread_join(). */ + return 0; + } +} + + +int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) { + return *t1 == *t2; +} + + +int uv_mutex_init(uv_mutex_t* mutex) { + InitializeCriticalSection(mutex); + return 0; +} + + +int uv_mutex_init_recursive(uv_mutex_t* mutex) { + return uv_mutex_init(mutex); +} + + +void uv_mutex_destroy(uv_mutex_t* mutex) { + DeleteCriticalSection(mutex); +} + + +void uv_mutex_lock(uv_mutex_t* mutex) { + EnterCriticalSection(mutex); +} + + +int uv_mutex_trylock(uv_mutex_t* mutex) { + if (TryEnterCriticalSection(mutex)) + return 0; + else + return UV_EBUSY; +} + + +void uv_mutex_unlock(uv_mutex_t* mutex) { + LeaveCriticalSection(mutex); +} + + +int uv_rwlock_init(uv_rwlock_t* rwlock) { + /* Initialize the semaphore that acts as the write lock. */ + HANDLE handle = CreateSemaphoreW(NULL, 1, 1, NULL); + if (handle == NULL) + return uv_translate_sys_error(GetLastError()); + rwlock->state_.write_semaphore_ = handle; + + /* Initialize the critical section protecting the reader count. */ + InitializeCriticalSection(&rwlock->state_.num_readers_lock_); + + /* Initialize the reader count. */ + rwlock->state_.num_readers_ = 0; + + return 0; +} + + +void uv_rwlock_destroy(uv_rwlock_t* rwlock) { + DeleteCriticalSection(&rwlock->state_.num_readers_lock_); + CloseHandle(rwlock->state_.write_semaphore_); +} + + +void uv_rwlock_rdlock(uv_rwlock_t* rwlock) { + /* Acquire the lock that protects the reader count. */ + EnterCriticalSection(&rwlock->state_.num_readers_lock_); + + /* Increase the reader count, and lock for write if this is the first + * reader. + */ + if (++rwlock->state_.num_readers_ == 1) { + DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, INFINITE); + if (r != WAIT_OBJECT_0) + uv_fatal_error(GetLastError(), "WaitForSingleObject"); + } + + /* Release the lock that protects the reader count. */ + LeaveCriticalSection(&rwlock->state_.num_readers_lock_); +} + + +int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) { + int err; + + if (!TryEnterCriticalSection(&rwlock->state_.num_readers_lock_)) + return UV_EBUSY; + + err = 0; + + if (rwlock->state_.num_readers_ == 0) { + /* Currently there are no other readers, which means that the write lock + * needs to be acquired. + */ + DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, 0); + if (r == WAIT_OBJECT_0) + rwlock->state_.num_readers_++; + else if (r == WAIT_TIMEOUT) + err = UV_EBUSY; + else if (r == WAIT_FAILED) + uv_fatal_error(GetLastError(), "WaitForSingleObject"); + + } else { + /* The write lock has already been acquired because there are other + * active readers. + */ + rwlock->state_.num_readers_++; + } + + LeaveCriticalSection(&rwlock->state_.num_readers_lock_); + return err; +} + + +void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) { + EnterCriticalSection(&rwlock->state_.num_readers_lock_); + + if (--rwlock->state_.num_readers_ == 0) { + if (!ReleaseSemaphore(rwlock->state_.write_semaphore_, 1, NULL)) + uv_fatal_error(GetLastError(), "ReleaseSemaphore"); + } + + LeaveCriticalSection(&rwlock->state_.num_readers_lock_); +} + + +void uv_rwlock_wrlock(uv_rwlock_t* rwlock) { + DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, INFINITE); + if (r != WAIT_OBJECT_0) + uv_fatal_error(GetLastError(), "WaitForSingleObject"); +} + + +int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) { + DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, 0); + if (r == WAIT_OBJECT_0) + return 0; + else if (r == WAIT_TIMEOUT) + return UV_EBUSY; + else + uv_fatal_error(GetLastError(), "WaitForSingleObject"); +} + + +void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) { + if (!ReleaseSemaphore(rwlock->state_.write_semaphore_, 1, NULL)) + uv_fatal_error(GetLastError(), "ReleaseSemaphore"); +} + + +int uv_sem_init(uv_sem_t* sem, unsigned int value) { + *sem = CreateSemaphore(NULL, value, INT_MAX, NULL); + if (*sem == NULL) + return uv_translate_sys_error(GetLastError()); + else + return 0; +} + + +void uv_sem_destroy(uv_sem_t* sem) { + if (!CloseHandle(*sem)) + abort(); +} + + +void uv_sem_post(uv_sem_t* sem) { + if (!ReleaseSemaphore(*sem, 1, NULL)) + abort(); +} + + +void uv_sem_wait(uv_sem_t* sem) { + if (WaitForSingleObject(*sem, INFINITE) != WAIT_OBJECT_0) + abort(); +} + + +int uv_sem_trywait(uv_sem_t* sem) { + DWORD r = WaitForSingleObject(*sem, 0); + + if (r == WAIT_OBJECT_0) + return 0; + + if (r == WAIT_TIMEOUT) + return UV_EAGAIN; + + abort(); + return -1; /* Satisfy the compiler. */ +} + + +int uv_cond_init(uv_cond_t* cond) { + InitializeConditionVariable(&cond->cond_var); + return 0; +} + + +void uv_cond_destroy(uv_cond_t* cond) { + /* nothing to do */ + (void) &cond; +} + + +void uv_cond_signal(uv_cond_t* cond) { + WakeConditionVariable(&cond->cond_var); +} + + +void uv_cond_broadcast(uv_cond_t* cond) { + WakeAllConditionVariable(&cond->cond_var); +} + + +void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) { + if (!SleepConditionVariableCS(&cond->cond_var, mutex, INFINITE)) + abort(); +} + +int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) { + if (SleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6))) + return 0; + if (GetLastError() != ERROR_TIMEOUT) + abort(); + return UV_ETIMEDOUT; +} + + +int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) { + int err; + + barrier->n = count; + barrier->count = 0; + + err = uv_mutex_init(&barrier->mutex); + if (err) + return err; + + err = uv_sem_init(&barrier->turnstile1, 0); + if (err) + goto error2; + + err = uv_sem_init(&barrier->turnstile2, 1); + if (err) + goto error; + + return 0; + +error: + uv_sem_destroy(&barrier->turnstile1); +error2: + uv_mutex_destroy(&barrier->mutex); + return err; + +} + + +void uv_barrier_destroy(uv_barrier_t* barrier) { + uv_sem_destroy(&barrier->turnstile2); + uv_sem_destroy(&barrier->turnstile1); + uv_mutex_destroy(&barrier->mutex); +} + + +int uv_barrier_wait(uv_barrier_t* barrier) { + int serial_thread; + + uv_mutex_lock(&barrier->mutex); + if (++barrier->count == barrier->n) { + uv_sem_wait(&barrier->turnstile2); + uv_sem_post(&barrier->turnstile1); + } + uv_mutex_unlock(&barrier->mutex); + + uv_sem_wait(&barrier->turnstile1); + uv_sem_post(&barrier->turnstile1); + + uv_mutex_lock(&barrier->mutex); + serial_thread = (--barrier->count == 0); + if (serial_thread) { + uv_sem_wait(&barrier->turnstile1); + uv_sem_post(&barrier->turnstile2); + } + uv_mutex_unlock(&barrier->mutex); + + uv_sem_wait(&barrier->turnstile2); + uv_sem_post(&barrier->turnstile2); + return serial_thread; +} + + +int uv_key_create(uv_key_t* key) { + key->tls_index = TlsAlloc(); + if (key->tls_index == TLS_OUT_OF_INDEXES) + return UV_ENOMEM; + return 0; +} + + +void uv_key_delete(uv_key_t* key) { + if (TlsFree(key->tls_index) == FALSE) + abort(); + key->tls_index = TLS_OUT_OF_INDEXES; +} + + +void* uv_key_get(uv_key_t* key) { + void* value; + + value = TlsGetValue(key->tls_index); + if (value == NULL) + if (GetLastError() != ERROR_SUCCESS) + abort(); + + return value; +} + + +void uv_key_set(uv_key_t* key, void* value) { + if (TlsSetValue(key->tls_index, value) == FALSE) + abort(); +} diff --git a/external/src/libuv/src/win/tty.c b/external/src/libuv/src/win/tty.c new file mode 100644 index 0000000..1b9d4f8 --- /dev/null +++ b/external/src/libuv/src/win/tty.c @@ -0,0 +1,2452 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "uv/stdint-msvc2008.h" +#else +# include +#endif + +#ifndef COMMON_LVB_REVERSE_VIDEO +# define COMMON_LVB_REVERSE_VIDEO 0x4000 +#endif + +#include "uv.h" +#include "internal.h" +#include "handle-inl.h" +#include "stream-inl.h" +#include "req-inl.h" + +#ifndef InterlockedOr +# define InterlockedOr _InterlockedOr +#endif + +#define UNICODE_REPLACEMENT_CHARACTER (0xfffd) + +#define ANSI_NORMAL 0x0000 +#define ANSI_ESCAPE_SEEN 0x0002 +#define ANSI_CSI 0x0004 +#define ANSI_ST_CONTROL 0x0008 +#define ANSI_IGNORE 0x0010 +#define ANSI_IN_ARG 0x0020 +#define ANSI_IN_STRING 0x0040 +#define ANSI_BACKSLASH_SEEN 0x0080 +#define ANSI_EXTENSION 0x0100 +#define ANSI_DECSCUSR 0x0200 + +#define MAX_INPUT_BUFFER_LENGTH 8192 +#define MAX_CONSOLE_CHAR 8192 + +#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING +#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 +#endif + +#define CURSOR_SIZE_SMALL 25 +#define CURSOR_SIZE_LARGE 100 + +static void uv_tty_capture_initial_style( + CONSOLE_SCREEN_BUFFER_INFO* screen_buffer_info, + CONSOLE_CURSOR_INFO* cursor_info); +static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info); +static int uv__cancel_read_console(uv_tty_t* handle); + + +/* Null uv_buf_t */ +static const uv_buf_t uv_null_buf_ = { 0, NULL }; + +enum uv__read_console_status_e { + NOT_STARTED, + IN_PROGRESS, + TRAP_REQUESTED, + COMPLETED +}; + +static volatile LONG uv__read_console_status = NOT_STARTED; +static volatile LONG uv__restore_screen_state; +static CONSOLE_SCREEN_BUFFER_INFO uv__saved_screen_state; + + +/* + * The console virtual window. + * + * Normally cursor movement in windows is relative to the console screen buffer, + * e.g. the application is allowed to overwrite the 'history'. This is very + * inconvenient, it makes absolute cursor movement pretty useless. There is + * also the concept of 'client rect' which is defined by the actual size of + * the console window and the scroll position of the screen buffer, but it's + * very volatile because it changes when the user scrolls. + * + * To make cursor movement behave sensibly we define a virtual window to which + * cursor movement is confined. The virtual window is always as wide as the + * console screen buffer, but it's height is defined by the size of the + * console window. The top of the virtual window aligns with the position + * of the caret when the first stdout/err handle is created, unless that would + * mean that it would extend beyond the bottom of the screen buffer - in that + * that case it's located as far down as possible. + * + * When the user writes a long text or many newlines, such that the output + * reaches beyond the bottom of the virtual window, the virtual window is + * shifted downwards, but not resized. + * + * Since all tty i/o happens on the same console, this window is shared + * between all stdout/stderr handles. + */ + +static int uv_tty_virtual_offset = -1; +static int uv_tty_virtual_height = -1; +static int uv_tty_virtual_width = -1; + +/* The console window size + * We keep this separate from uv_tty_virtual_*. We use those values to only + * handle signalling SIGWINCH + */ + +static HANDLE uv__tty_console_handle = INVALID_HANDLE_VALUE; +static int uv__tty_console_height = -1; +static int uv__tty_console_width = -1; +static HANDLE uv__tty_console_resized = INVALID_HANDLE_VALUE; +static uv_mutex_t uv__tty_console_resize_mutex; + +static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param); +static void CALLBACK uv__tty_console_resize_event(HWINEVENTHOOK hWinEventHook, + DWORD event, + HWND hwnd, + LONG idObject, + LONG idChild, + DWORD dwEventThread, + DWORD dwmsEventTime); +static DWORD WINAPI uv__tty_console_resize_watcher_thread(void* param); +static void uv__tty_console_signal_resize(void); + +/* We use a semaphore rather than a mutex or critical section because in some + cases (uv__cancel_read_console) we need take the lock in the main thread and + release it in another thread. Using a semaphore ensures that in such + scenario the main thread will still block when trying to acquire the lock. */ +static uv_sem_t uv_tty_output_lock; + +static WORD uv_tty_default_text_attributes = + FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; + +static char uv_tty_default_fg_color = 7; +static char uv_tty_default_bg_color = 0; +static char uv_tty_default_fg_bright = 0; +static char uv_tty_default_bg_bright = 0; +static char uv_tty_default_inverse = 0; + +static CONSOLE_CURSOR_INFO uv_tty_default_cursor_info; + +/* Determine whether or not ANSI support is enabled. */ +static BOOL uv__need_check_vterm_state = TRUE; +static uv_tty_vtermstate_t uv__vterm_state = UV_TTY_UNSUPPORTED; +static void uv__determine_vterm_state(HANDLE handle); + +void uv_console_init(void) { + if (uv_sem_init(&uv_tty_output_lock, 1)) + abort(); + uv__tty_console_handle = CreateFileW(L"CONOUT$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_WRITE, + 0, + OPEN_EXISTING, + 0, + 0); + if (uv__tty_console_handle != INVALID_HANDLE_VALUE) { + CONSOLE_SCREEN_BUFFER_INFO sb_info; + QueueUserWorkItem(uv__tty_console_resize_message_loop_thread, + NULL, + WT_EXECUTELONGFUNCTION); + uv_mutex_init(&uv__tty_console_resize_mutex); + if (GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info)) { + uv__tty_console_width = sb_info.dwSize.X; + uv__tty_console_height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1; + } + } +} + + +int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int unused) { + BOOL readable; + DWORD NumberOfEvents; + HANDLE handle; + CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info; + CONSOLE_CURSOR_INFO cursor_info; + (void)unused; + + uv__once_init(); + handle = (HANDLE) uv__get_osfhandle(fd); + if (handle == INVALID_HANDLE_VALUE) + return UV_EBADF; + + if (fd <= 2) { + /* In order to avoid closing a stdio file descriptor 0-2, duplicate the + * underlying OS handle and forget about the original fd. + * We could also opt to use the original OS handle and just never close it, + * but then there would be no reliable way to cancel pending read operations + * upon close. + */ + if (!DuplicateHandle(INVALID_HANDLE_VALUE, + handle, + INVALID_HANDLE_VALUE, + &handle, + 0, + FALSE, + DUPLICATE_SAME_ACCESS)) + return uv_translate_sys_error(GetLastError()); + fd = -1; + } + + readable = GetNumberOfConsoleInputEvents(handle, &NumberOfEvents); + if (!readable) { + /* Obtain the screen buffer info with the output handle. */ + if (!GetConsoleScreenBufferInfo(handle, &screen_buffer_info)) { + return uv_translate_sys_error(GetLastError()); + } + + /* Obtain the cursor info with the output handle. */ + if (!GetConsoleCursorInfo(handle, &cursor_info)) { + return uv_translate_sys_error(GetLastError()); + } + + /* Obtain the tty_output_lock because the virtual window state is shared + * between all uv_tty_t handles. */ + uv_sem_wait(&uv_tty_output_lock); + + if (uv__need_check_vterm_state) + uv__determine_vterm_state(handle); + + /* Remember the original console text attributes and cursor info. */ + uv_tty_capture_initial_style(&screen_buffer_info, &cursor_info); + + uv_tty_update_virtual_window(&screen_buffer_info); + + uv_sem_post(&uv_tty_output_lock); + } + + + uv_stream_init(loop, (uv_stream_t*) tty, UV_TTY); + uv_connection_init((uv_stream_t*) tty); + + tty->handle = handle; + tty->u.fd = fd; + tty->reqs_pending = 0; + tty->flags |= UV_HANDLE_BOUND; + + if (readable) { + /* Initialize TTY input specific fields. */ + tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE; + /* TODO: remove me in v2.x. */ + tty->tty.rd.unused_ = NULL; + tty->tty.rd.read_line_buffer = uv_null_buf_; + tty->tty.rd.read_raw_wait = NULL; + + /* Init keycode-to-vt100 mapper state. */ + tty->tty.rd.last_key_len = 0; + tty->tty.rd.last_key_offset = 0; + tty->tty.rd.last_utf16_high_surrogate = 0; + memset(&tty->tty.rd.last_input_record, 0, sizeof tty->tty.rd.last_input_record); + } else { + /* TTY output specific fields. */ + tty->flags |= UV_HANDLE_WRITABLE; + + /* Init utf8-to-utf16 conversion state. */ + tty->tty.wr.utf8_bytes_left = 0; + tty->tty.wr.utf8_codepoint = 0; + + /* Initialize eol conversion state */ + tty->tty.wr.previous_eol = 0; + + /* Init ANSI parser state. */ + tty->tty.wr.ansi_parser_state = ANSI_NORMAL; + } + + return 0; +} + + +/* Set the default console text attributes based on how the console was + * configured when libuv started. + */ +static void uv_tty_capture_initial_style( + CONSOLE_SCREEN_BUFFER_INFO* screen_buffer_info, + CONSOLE_CURSOR_INFO* cursor_info) { + static int style_captured = 0; + + /* Only do this once. + Assumption: Caller has acquired uv_tty_output_lock. */ + if (style_captured) + return; + + /* Save raw win32 attributes. */ + uv_tty_default_text_attributes = screen_buffer_info->wAttributes; + + /* Convert black text on black background to use white text. */ + if (uv_tty_default_text_attributes == 0) + uv_tty_default_text_attributes = 7; + + /* Convert Win32 attributes to ANSI colors. */ + uv_tty_default_fg_color = 0; + uv_tty_default_bg_color = 0; + uv_tty_default_fg_bright = 0; + uv_tty_default_bg_bright = 0; + uv_tty_default_inverse = 0; + + if (uv_tty_default_text_attributes & FOREGROUND_RED) + uv_tty_default_fg_color |= 1; + + if (uv_tty_default_text_attributes & FOREGROUND_GREEN) + uv_tty_default_fg_color |= 2; + + if (uv_tty_default_text_attributes & FOREGROUND_BLUE) + uv_tty_default_fg_color |= 4; + + if (uv_tty_default_text_attributes & BACKGROUND_RED) + uv_tty_default_bg_color |= 1; + + if (uv_tty_default_text_attributes & BACKGROUND_GREEN) + uv_tty_default_bg_color |= 2; + + if (uv_tty_default_text_attributes & BACKGROUND_BLUE) + uv_tty_default_bg_color |= 4; + + if (uv_tty_default_text_attributes & FOREGROUND_INTENSITY) + uv_tty_default_fg_bright = 1; + + if (uv_tty_default_text_attributes & BACKGROUND_INTENSITY) + uv_tty_default_bg_bright = 1; + + if (uv_tty_default_text_attributes & COMMON_LVB_REVERSE_VIDEO) + uv_tty_default_inverse = 1; + + /* Save the cursor size and the cursor state. */ + uv_tty_default_cursor_info = *cursor_info; + + style_captured = 1; +} + + +int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) { + DWORD flags; + unsigned char was_reading; + uv_alloc_cb alloc_cb; + uv_read_cb read_cb; + int err; + + if (!(tty->flags & UV_HANDLE_TTY_READABLE)) { + return UV_EINVAL; + } + + if (!!mode == !!(tty->flags & UV_HANDLE_TTY_RAW)) { + return 0; + } + + switch (mode) { + case UV_TTY_MODE_NORMAL: + flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; + break; + case UV_TTY_MODE_RAW: + flags = ENABLE_WINDOW_INPUT; + break; + case UV_TTY_MODE_IO: + return UV_ENOTSUP; + default: + return UV_EINVAL; + } + + /* If currently reading, stop, and restart reading. */ + if (tty->flags & UV_HANDLE_READING) { + was_reading = 1; + alloc_cb = tty->alloc_cb; + read_cb = tty->read_cb; + err = uv_tty_read_stop(tty); + if (err) { + return uv_translate_sys_error(err); + } + } else { + was_reading = 0; + alloc_cb = NULL; + read_cb = NULL; + } + + uv_sem_wait(&uv_tty_output_lock); + if (!SetConsoleMode(tty->handle, flags)) { + err = uv_translate_sys_error(GetLastError()); + uv_sem_post(&uv_tty_output_lock); + return err; + } + uv_sem_post(&uv_tty_output_lock); + + /* Update flag. */ + tty->flags &= ~UV_HANDLE_TTY_RAW; + tty->flags |= mode ? UV_HANDLE_TTY_RAW : 0; + + /* If we just stopped reading, restart. */ + if (was_reading) { + err = uv_tty_read_start(tty, alloc_cb, read_cb); + if (err) { + return uv_translate_sys_error(err); + } + } + + return 0; +} + + +int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) { + CONSOLE_SCREEN_BUFFER_INFO info; + + if (!GetConsoleScreenBufferInfo(tty->handle, &info)) { + return uv_translate_sys_error(GetLastError()); + } + + uv_sem_wait(&uv_tty_output_lock); + uv_tty_update_virtual_window(&info); + uv_sem_post(&uv_tty_output_lock); + + *width = uv_tty_virtual_width; + *height = uv_tty_virtual_height; + + return 0; +} + + +static void CALLBACK uv_tty_post_raw_read(void* data, BOOLEAN didTimeout) { + uv_loop_t* loop; + uv_tty_t* handle; + uv_req_t* req; + + assert(data); + assert(!didTimeout); + + req = (uv_req_t*) data; + handle = (uv_tty_t*) req->data; + loop = handle->loop; + + UnregisterWait(handle->tty.rd.read_raw_wait); + handle->tty.rd.read_raw_wait = NULL; + + SET_REQ_SUCCESS(req); + POST_COMPLETION_FOR_REQ(loop, req); +} + + +static void uv_tty_queue_read_raw(uv_loop_t* loop, uv_tty_t* handle) { + uv_read_t* req; + BOOL r; + + assert(handle->flags & UV_HANDLE_READING); + assert(!(handle->flags & UV_HANDLE_READ_PENDING)); + + assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE); + + handle->tty.rd.read_line_buffer = uv_null_buf_; + + req = &handle->read_req; + memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); + + r = RegisterWaitForSingleObject(&handle->tty.rd.read_raw_wait, + handle->handle, + uv_tty_post_raw_read, + (void*) req, + INFINITE, + WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE); + if (!r) { + handle->tty.rd.read_raw_wait = NULL; + SET_REQ_ERROR(req, GetLastError()); + uv_insert_pending_req(loop, (uv_req_t*)req); + } + + handle->flags |= UV_HANDLE_READ_PENDING; + handle->reqs_pending++; +} + + +static DWORD CALLBACK uv_tty_line_read_thread(void* data) { + uv_loop_t* loop; + uv_tty_t* handle; + uv_req_t* req; + DWORD bytes, read_bytes; + WCHAR utf16[MAX_INPUT_BUFFER_LENGTH / 3]; + DWORD chars, read_chars; + LONG status; + COORD pos; + BOOL read_console_success; + + assert(data); + + req = (uv_req_t*) data; + handle = (uv_tty_t*) req->data; + loop = handle->loop; + + assert(handle->tty.rd.read_line_buffer.base != NULL); + assert(handle->tty.rd.read_line_buffer.len > 0); + + /* ReadConsole can't handle big buffers. */ + if (handle->tty.rd.read_line_buffer.len < MAX_INPUT_BUFFER_LENGTH) { + bytes = handle->tty.rd.read_line_buffer.len; + } else { + bytes = MAX_INPUT_BUFFER_LENGTH; + } + + /* At last, unicode! One utf-16 codeunit never takes more than 3 utf-8 + * codeunits to encode. */ + chars = bytes / 3; + + status = InterlockedExchange(&uv__read_console_status, IN_PROGRESS); + if (status == TRAP_REQUESTED) { + SET_REQ_SUCCESS(req); + InterlockedExchange(&uv__read_console_status, COMPLETED); + req->u.io.overlapped.InternalHigh = 0; + POST_COMPLETION_FOR_REQ(loop, req); + return 0; + } + + read_console_success = ReadConsoleW(handle->handle, + (void*) utf16, + chars, + &read_chars, + NULL); + + if (read_console_success) { + read_bytes = WideCharToMultiByte(CP_UTF8, + 0, + utf16, + read_chars, + handle->tty.rd.read_line_buffer.base, + bytes, + NULL, + NULL); + SET_REQ_SUCCESS(req); + req->u.io.overlapped.InternalHigh = read_bytes; + } else { + SET_REQ_ERROR(req, GetLastError()); + } + + status = InterlockedExchange(&uv__read_console_status, COMPLETED); + + if (status == TRAP_REQUESTED) { + /* If we canceled the read by sending a VK_RETURN event, restore the + screen state to undo the visual effect of the VK_RETURN */ + if (read_console_success && InterlockedOr(&uv__restore_screen_state, 0)) { + HANDLE active_screen_buffer; + active_screen_buffer = CreateFileA("conout$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (active_screen_buffer != INVALID_HANDLE_VALUE) { + pos = uv__saved_screen_state.dwCursorPosition; + + /* If the cursor was at the bottom line of the screen buffer, the + VK_RETURN would have caused the buffer contents to scroll up by one + line. The right position to reset the cursor to is therefore one line + higher */ + if (pos.Y == uv__saved_screen_state.dwSize.Y - 1) + pos.Y--; + + SetConsoleCursorPosition(active_screen_buffer, pos); + CloseHandle(active_screen_buffer); + } + } + uv_sem_post(&uv_tty_output_lock); + } + POST_COMPLETION_FOR_REQ(loop, req); + return 0; +} + + +static void uv_tty_queue_read_line(uv_loop_t* loop, uv_tty_t* handle) { + uv_read_t* req; + BOOL r; + + assert(handle->flags & UV_HANDLE_READING); + assert(!(handle->flags & UV_HANDLE_READ_PENDING)); + assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE); + + req = &handle->read_req; + memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); + + handle->tty.rd.read_line_buffer = uv_buf_init(NULL, 0); + handle->alloc_cb((uv_handle_t*) handle, 8192, &handle->tty.rd.read_line_buffer); + if (handle->tty.rd.read_line_buffer.base == NULL || + handle->tty.rd.read_line_buffer.len == 0) { + handle->read_cb((uv_stream_t*) handle, + UV_ENOBUFS, + &handle->tty.rd.read_line_buffer); + return; + } + assert(handle->tty.rd.read_line_buffer.base != NULL); + + /* Reset flags No locking is required since there cannot be a line read + in progress. We are also relying on the memory barrier provided by + QueueUserWorkItem*/ + uv__restore_screen_state = FALSE; + uv__read_console_status = NOT_STARTED; + r = QueueUserWorkItem(uv_tty_line_read_thread, + (void*) req, + WT_EXECUTELONGFUNCTION); + if (!r) { + SET_REQ_ERROR(req, GetLastError()); + uv_insert_pending_req(loop, (uv_req_t*)req); + } + + handle->flags |= UV_HANDLE_READ_PENDING; + handle->reqs_pending++; +} + + +static void uv_tty_queue_read(uv_loop_t* loop, uv_tty_t* handle) { + if (handle->flags & UV_HANDLE_TTY_RAW) { + uv_tty_queue_read_raw(loop, handle); + } else { + uv_tty_queue_read_line(loop, handle); + } +} + + +static const char* get_vt100_fn_key(DWORD code, char shift, char ctrl, + size_t* len) { +#define VK_CASE(vk, normal_str, shift_str, ctrl_str, shift_ctrl_str) \ + case (vk): \ + if (shift && ctrl) { \ + *len = sizeof shift_ctrl_str; \ + return "\033" shift_ctrl_str; \ + } else if (shift) { \ + *len = sizeof shift_str ; \ + return "\033" shift_str; \ + } else if (ctrl) { \ + *len = sizeof ctrl_str; \ + return "\033" ctrl_str; \ + } else { \ + *len = sizeof normal_str; \ + return "\033" normal_str; \ + } + + switch (code) { + /* These mappings are the same as Cygwin's. Unmodified and alt-modified + * keypad keys comply with linux console, modifiers comply with xterm + * modifier usage. F1. f12 and shift-f1. f10 comply with linux console, f6. + * f12 with and without modifiers comply with rxvt. */ + VK_CASE(VK_INSERT, "[2~", "[2;2~", "[2;5~", "[2;6~") + VK_CASE(VK_END, "[4~", "[4;2~", "[4;5~", "[4;6~") + VK_CASE(VK_DOWN, "[B", "[1;2B", "[1;5B", "[1;6B") + VK_CASE(VK_NEXT, "[6~", "[6;2~", "[6;5~", "[6;6~") + VK_CASE(VK_LEFT, "[D", "[1;2D", "[1;5D", "[1;6D") + VK_CASE(VK_CLEAR, "[G", "[1;2G", "[1;5G", "[1;6G") + VK_CASE(VK_RIGHT, "[C", "[1;2C", "[1;5C", "[1;6C") + VK_CASE(VK_UP, "[A", "[1;2A", "[1;5A", "[1;6A") + VK_CASE(VK_HOME, "[1~", "[1;2~", "[1;5~", "[1;6~") + VK_CASE(VK_PRIOR, "[5~", "[5;2~", "[5;5~", "[5;6~") + VK_CASE(VK_DELETE, "[3~", "[3;2~", "[3;5~", "[3;6~") + VK_CASE(VK_NUMPAD0, "[2~", "[2;2~", "[2;5~", "[2;6~") + VK_CASE(VK_NUMPAD1, "[4~", "[4;2~", "[4;5~", "[4;6~") + VK_CASE(VK_NUMPAD2, "[B", "[1;2B", "[1;5B", "[1;6B") + VK_CASE(VK_NUMPAD3, "[6~", "[6;2~", "[6;5~", "[6;6~") + VK_CASE(VK_NUMPAD4, "[D", "[1;2D", "[1;5D", "[1;6D") + VK_CASE(VK_NUMPAD5, "[G", "[1;2G", "[1;5G", "[1;6G") + VK_CASE(VK_NUMPAD6, "[C", "[1;2C", "[1;5C", "[1;6C") + VK_CASE(VK_NUMPAD7, "[A", "[1;2A", "[1;5A", "[1;6A") + VK_CASE(VK_NUMPAD8, "[1~", "[1;2~", "[1;5~", "[1;6~") + VK_CASE(VK_NUMPAD9, "[5~", "[5;2~", "[5;5~", "[5;6~") + VK_CASE(VK_DECIMAL, "[3~", "[3;2~", "[3;5~", "[3;6~") + VK_CASE(VK_F1, "[[A", "[23~", "[11^", "[23^" ) + VK_CASE(VK_F2, "[[B", "[24~", "[12^", "[24^" ) + VK_CASE(VK_F3, "[[C", "[25~", "[13^", "[25^" ) + VK_CASE(VK_F4, "[[D", "[26~", "[14^", "[26^" ) + VK_CASE(VK_F5, "[[E", "[28~", "[15^", "[28^" ) + VK_CASE(VK_F6, "[17~", "[29~", "[17^", "[29^" ) + VK_CASE(VK_F7, "[18~", "[31~", "[18^", "[31^" ) + VK_CASE(VK_F8, "[19~", "[32~", "[19^", "[32^" ) + VK_CASE(VK_F9, "[20~", "[33~", "[20^", "[33^" ) + VK_CASE(VK_F10, "[21~", "[34~", "[21^", "[34^" ) + VK_CASE(VK_F11, "[23~", "[23$", "[23^", "[23@" ) + VK_CASE(VK_F12, "[24~", "[24$", "[24^", "[24@" ) + + default: + *len = 0; + return NULL; + } +#undef VK_CASE +} + + +void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle, + uv_req_t* req) { + /* Shortcut for handle->tty.rd.last_input_record.Event.KeyEvent. */ +#define KEV handle->tty.rd.last_input_record.Event.KeyEvent + + DWORD records_left, records_read; + uv_buf_t buf; + off_t buf_used; + + assert(handle->type == UV_TTY); + assert(handle->flags & UV_HANDLE_TTY_READABLE); + handle->flags &= ~UV_HANDLE_READ_PENDING; + + if (!(handle->flags & UV_HANDLE_READING) || + !(handle->flags & UV_HANDLE_TTY_RAW)) { + goto out; + } + + if (!REQ_SUCCESS(req)) { + /* An error occurred while waiting for the event. */ + if ((handle->flags & UV_HANDLE_READING)) { + handle->flags &= ~UV_HANDLE_READING; + handle->read_cb((uv_stream_t*)handle, + uv_translate_sys_error(GET_REQ_ERROR(req)), + &uv_null_buf_); + } + goto out; + } + + /* Fetch the number of events */ + if (!GetNumberOfConsoleInputEvents(handle->handle, &records_left)) { + handle->flags &= ~UV_HANDLE_READING; + DECREASE_ACTIVE_COUNT(loop, handle); + handle->read_cb((uv_stream_t*)handle, + uv_translate_sys_error(GetLastError()), + &uv_null_buf_); + goto out; + } + + /* Windows sends a lot of events that we're not interested in, so buf will be + * allocated on demand, when there's actually something to emit. */ + buf = uv_null_buf_; + buf_used = 0; + + while ((records_left > 0 || handle->tty.rd.last_key_len > 0) && + (handle->flags & UV_HANDLE_READING)) { + if (handle->tty.rd.last_key_len == 0) { + /* Read the next input record */ + if (!ReadConsoleInputW(handle->handle, + &handle->tty.rd.last_input_record, + 1, + &records_read)) { + handle->flags &= ~UV_HANDLE_READING; + DECREASE_ACTIVE_COUNT(loop, handle); + handle->read_cb((uv_stream_t*) handle, + uv_translate_sys_error(GetLastError()), + &buf); + goto out; + } + records_left--; + + /* We might be not subscribed to EVENT_CONSOLE_LAYOUT or we might be + * running under some TTY emulator that does not send those events. */ + if (handle->tty.rd.last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) { + uv__tty_console_signal_resize(); + } + + /* Ignore other events that are not key events. */ + if (handle->tty.rd.last_input_record.EventType != KEY_EVENT) { + continue; + } + + /* Ignore keyup events, unless the left alt key was held and a valid + * unicode character was emitted. */ + if (!KEV.bKeyDown && + (KEV.wVirtualKeyCode != VK_MENU || + KEV.uChar.UnicodeChar == 0)) { + continue; + } + + /* Ignore keypresses to numpad number keys if the left alt is held + * because the user is composing a character, or windows simulating this. + */ + if ((KEV.dwControlKeyState & LEFT_ALT_PRESSED) && + !(KEV.dwControlKeyState & ENHANCED_KEY) && + (KEV.wVirtualKeyCode == VK_INSERT || + KEV.wVirtualKeyCode == VK_END || + KEV.wVirtualKeyCode == VK_DOWN || + KEV.wVirtualKeyCode == VK_NEXT || + KEV.wVirtualKeyCode == VK_LEFT || + KEV.wVirtualKeyCode == VK_CLEAR || + KEV.wVirtualKeyCode == VK_RIGHT || + KEV.wVirtualKeyCode == VK_HOME || + KEV.wVirtualKeyCode == VK_UP || + KEV.wVirtualKeyCode == VK_PRIOR || + KEV.wVirtualKeyCode == VK_NUMPAD0 || + KEV.wVirtualKeyCode == VK_NUMPAD1 || + KEV.wVirtualKeyCode == VK_NUMPAD2 || + KEV.wVirtualKeyCode == VK_NUMPAD3 || + KEV.wVirtualKeyCode == VK_NUMPAD4 || + KEV.wVirtualKeyCode == VK_NUMPAD5 || + KEV.wVirtualKeyCode == VK_NUMPAD6 || + KEV.wVirtualKeyCode == VK_NUMPAD7 || + KEV.wVirtualKeyCode == VK_NUMPAD8 || + KEV.wVirtualKeyCode == VK_NUMPAD9)) { + continue; + } + + if (KEV.uChar.UnicodeChar != 0) { + int prefix_len, char_len; + + /* Character key pressed */ + if (KEV.uChar.UnicodeChar >= 0xD800 && + KEV.uChar.UnicodeChar < 0xDC00) { + /* UTF-16 high surrogate */ + handle->tty.rd.last_utf16_high_surrogate = KEV.uChar.UnicodeChar; + continue; + } + + /* Prefix with \u033 if alt was held, but alt was not used as part a + * compose sequence. */ + if ((KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) + && !(KEV.dwControlKeyState & (LEFT_CTRL_PRESSED | + RIGHT_CTRL_PRESSED)) && KEV.bKeyDown) { + handle->tty.rd.last_key[0] = '\033'; + prefix_len = 1; + } else { + prefix_len = 0; + } + + if (KEV.uChar.UnicodeChar >= 0xDC00 && + KEV.uChar.UnicodeChar < 0xE000) { + /* UTF-16 surrogate pair */ + WCHAR utf16_buffer[2]; + utf16_buffer[0] = handle->tty.rd.last_utf16_high_surrogate; + utf16_buffer[1] = KEV.uChar.UnicodeChar; + char_len = WideCharToMultiByte(CP_UTF8, + 0, + utf16_buffer, + 2, + &handle->tty.rd.last_key[prefix_len], + sizeof handle->tty.rd.last_key, + NULL, + NULL); + } else { + /* Single UTF-16 character */ + char_len = WideCharToMultiByte(CP_UTF8, + 0, + &KEV.uChar.UnicodeChar, + 1, + &handle->tty.rd.last_key[prefix_len], + sizeof handle->tty.rd.last_key, + NULL, + NULL); + } + + /* Whatever happened, the last character wasn't a high surrogate. */ + handle->tty.rd.last_utf16_high_surrogate = 0; + + /* If the utf16 character(s) couldn't be converted something must be + * wrong. */ + if (!char_len) { + handle->flags &= ~UV_HANDLE_READING; + DECREASE_ACTIVE_COUNT(loop, handle); + handle->read_cb((uv_stream_t*) handle, + uv_translate_sys_error(GetLastError()), + &buf); + goto out; + } + + handle->tty.rd.last_key_len = (unsigned char) (prefix_len + char_len); + handle->tty.rd.last_key_offset = 0; + continue; + + } else { + /* Function key pressed */ + const char* vt100; + size_t prefix_len, vt100_len; + + vt100 = get_vt100_fn_key(KEV.wVirtualKeyCode, + !!(KEV.dwControlKeyState & SHIFT_PRESSED), + !!(KEV.dwControlKeyState & ( + LEFT_CTRL_PRESSED | + RIGHT_CTRL_PRESSED)), + &vt100_len); + + /* If we were unable to map to a vt100 sequence, just ignore. */ + if (!vt100) { + continue; + } + + /* Prefix with \x033 when the alt key was held. */ + if (KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) { + handle->tty.rd.last_key[0] = '\033'; + prefix_len = 1; + } else { + prefix_len = 0; + } + + /* Copy the vt100 sequence to the handle buffer. */ + assert(prefix_len + vt100_len < sizeof handle->tty.rd.last_key); + memcpy(&handle->tty.rd.last_key[prefix_len], vt100, vt100_len); + + handle->tty.rd.last_key_len = (unsigned char) (prefix_len + vt100_len); + handle->tty.rd.last_key_offset = 0; + continue; + } + } else { + /* Copy any bytes left from the last keypress to the user buffer. */ + if (handle->tty.rd.last_key_offset < handle->tty.rd.last_key_len) { + /* Allocate a buffer if needed */ + if (buf_used == 0) { + buf = uv_buf_init(NULL, 0); + handle->alloc_cb((uv_handle_t*) handle, 1024, &buf); + if (buf.base == NULL || buf.len == 0) { + handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf); + goto out; + } + assert(buf.base != NULL); + } + + buf.base[buf_used++] = handle->tty.rd.last_key[handle->tty.rd.last_key_offset++]; + + /* If the buffer is full, emit it */ + if ((size_t) buf_used == buf.len) { + handle->read_cb((uv_stream_t*) handle, buf_used, &buf); + buf = uv_null_buf_; + buf_used = 0; + } + + continue; + } + + /* Apply dwRepeat from the last input record. */ + if (--KEV.wRepeatCount > 0) { + handle->tty.rd.last_key_offset = 0; + continue; + } + + handle->tty.rd.last_key_len = 0; + continue; + } + } + + /* Send the buffer back to the user */ + if (buf_used > 0) { + handle->read_cb((uv_stream_t*) handle, buf_used, &buf); + } + + out: + /* Wait for more input events. */ + if ((handle->flags & UV_HANDLE_READING) && + !(handle->flags & UV_HANDLE_READ_PENDING)) { + uv_tty_queue_read(loop, handle); + } + + DECREASE_PENDING_REQ_COUNT(handle); + +#undef KEV +} + + + +void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle, + uv_req_t* req) { + uv_buf_t buf; + + assert(handle->type == UV_TTY); + assert(handle->flags & UV_HANDLE_TTY_READABLE); + + buf = handle->tty.rd.read_line_buffer; + + handle->flags &= ~UV_HANDLE_READ_PENDING; + handle->tty.rd.read_line_buffer = uv_null_buf_; + + if (!REQ_SUCCESS(req)) { + /* Read was not successful */ + if (handle->flags & UV_HANDLE_READING) { + /* Real error */ + handle->flags &= ~UV_HANDLE_READING; + DECREASE_ACTIVE_COUNT(loop, handle); + handle->read_cb((uv_stream_t*) handle, + uv_translate_sys_error(GET_REQ_ERROR(req)), + &buf); + } + } else { + if (!(handle->flags & UV_HANDLE_CANCELLATION_PENDING) && + req->u.io.overlapped.InternalHigh != 0) { + /* Read successful. TODO: read unicode, convert to utf-8 */ + DWORD bytes = req->u.io.overlapped.InternalHigh; + handle->read_cb((uv_stream_t*) handle, bytes, &buf); + } + handle->flags &= ~UV_HANDLE_CANCELLATION_PENDING; + } + + /* Wait for more input events. */ + if ((handle->flags & UV_HANDLE_READING) && + !(handle->flags & UV_HANDLE_READ_PENDING)) { + uv_tty_queue_read(loop, handle); + } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle, + uv_req_t* req) { + assert(handle->type == UV_TTY); + assert(handle->flags & UV_HANDLE_TTY_READABLE); + + /* If the read_line_buffer member is zero, it must have been an raw read. + * Otherwise it was a line-buffered read. FIXME: This is quite obscure. Use a + * flag or something. */ + if (handle->tty.rd.read_line_buffer.len == 0) { + uv_process_tty_read_raw_req(loop, handle, req); + } else { + uv_process_tty_read_line_req(loop, handle, req); + } +} + + +int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb, + uv_read_cb read_cb) { + uv_loop_t* loop = handle->loop; + + if (!(handle->flags & UV_HANDLE_TTY_READABLE)) { + return ERROR_INVALID_PARAMETER; + } + + handle->flags |= UV_HANDLE_READING; + INCREASE_ACTIVE_COUNT(loop, handle); + handle->read_cb = read_cb; + handle->alloc_cb = alloc_cb; + + /* If reading was stopped and then started again, there could still be a read + * request pending. */ + if (handle->flags & UV_HANDLE_READ_PENDING) { + return 0; + } + + /* Maybe the user stopped reading half-way while processing key events. + * Short-circuit if this could be the case. */ + if (handle->tty.rd.last_key_len > 0) { + SET_REQ_SUCCESS(&handle->read_req); + uv_insert_pending_req(handle->loop, (uv_req_t*) &handle->read_req); + /* Make sure no attempt is made to insert it again until it's handled. */ + handle->flags |= UV_HANDLE_READ_PENDING; + handle->reqs_pending++; + return 0; + } + + uv_tty_queue_read(loop, handle); + + return 0; +} + + +int uv_tty_read_stop(uv_tty_t* handle) { + INPUT_RECORD record; + DWORD written, err; + + handle->flags &= ~UV_HANDLE_READING; + DECREASE_ACTIVE_COUNT(handle->loop, handle); + + if (!(handle->flags & UV_HANDLE_READ_PENDING)) + return 0; + + if (handle->flags & UV_HANDLE_TTY_RAW) { + /* Cancel raw read. Write some bullshit event to force the console wait to + * return. */ + memset(&record, 0, sizeof record); + record.EventType = FOCUS_EVENT; + if (!WriteConsoleInputW(handle->handle, &record, 1, &written)) { + return GetLastError(); + } + } else if (!(handle->flags & UV_HANDLE_CANCELLATION_PENDING)) { + /* Cancel line-buffered read if not already pending */ + err = uv__cancel_read_console(handle); + if (err) + return err; + + handle->flags |= UV_HANDLE_CANCELLATION_PENDING; + } + + return 0; +} + +static int uv__cancel_read_console(uv_tty_t* handle) { + HANDLE active_screen_buffer = INVALID_HANDLE_VALUE; + INPUT_RECORD record; + DWORD written; + DWORD err = 0; + LONG status; + + assert(!(handle->flags & UV_HANDLE_CANCELLATION_PENDING)); + + /* Hold the output lock during the cancellation, to ensure that further + writes don't interfere with the screen state. It will be the ReadConsole + thread's responsibility to release the lock. */ + uv_sem_wait(&uv_tty_output_lock); + status = InterlockedExchange(&uv__read_console_status, TRAP_REQUESTED); + if (status != IN_PROGRESS) { + /* Either we have managed to set a trap for the other thread before + ReadConsole is called, or ReadConsole has returned because the user + has pressed ENTER. In either case, there is nothing else to do. */ + uv_sem_post(&uv_tty_output_lock); + return 0; + } + + /* Save screen state before sending the VK_RETURN event */ + active_screen_buffer = CreateFileA("conout$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (active_screen_buffer != INVALID_HANDLE_VALUE && + GetConsoleScreenBufferInfo(active_screen_buffer, + &uv__saved_screen_state)) { + InterlockedOr(&uv__restore_screen_state, 1); + } + + /* Write enter key event to force the console wait to return. */ + record.EventType = KEY_EVENT; + record.Event.KeyEvent.bKeyDown = TRUE; + record.Event.KeyEvent.wRepeatCount = 1; + record.Event.KeyEvent.wVirtualKeyCode = VK_RETURN; + record.Event.KeyEvent.wVirtualScanCode = + MapVirtualKeyW(VK_RETURN, MAPVK_VK_TO_VSC); + record.Event.KeyEvent.uChar.UnicodeChar = L'\r'; + record.Event.KeyEvent.dwControlKeyState = 0; + if (!WriteConsoleInputW(handle->handle, &record, 1, &written)) + err = GetLastError(); + + if (active_screen_buffer != INVALID_HANDLE_VALUE) + CloseHandle(active_screen_buffer); + + return err; +} + + +static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info) { + uv_tty_virtual_width = info->dwSize.X; + uv_tty_virtual_height = info->srWindow.Bottom - info->srWindow.Top + 1; + + /* Recompute virtual window offset row. */ + if (uv_tty_virtual_offset == -1) { + uv_tty_virtual_offset = info->dwCursorPosition.Y; + } else if (uv_tty_virtual_offset < info->dwCursorPosition.Y - + uv_tty_virtual_height + 1) { + /* If suddenly find the cursor outside of the virtual window, it must have + * somehow scrolled. Update the virtual window offset. */ + uv_tty_virtual_offset = info->dwCursorPosition.Y - + uv_tty_virtual_height + 1; + } + if (uv_tty_virtual_offset + uv_tty_virtual_height > info->dwSize.Y) { + uv_tty_virtual_offset = info->dwSize.Y - uv_tty_virtual_height; + } + if (uv_tty_virtual_offset < 0) { + uv_tty_virtual_offset = 0; + } +} + + +static COORD uv_tty_make_real_coord(uv_tty_t* handle, + CONSOLE_SCREEN_BUFFER_INFO* info, int x, unsigned char x_relative, int y, + unsigned char y_relative) { + COORD result; + + uv_tty_update_virtual_window(info); + + /* Adjust y position */ + if (y_relative) { + y = info->dwCursorPosition.Y + y; + } else { + y = uv_tty_virtual_offset + y; + } + /* Clip y to virtual client rectangle */ + if (y < uv_tty_virtual_offset) { + y = uv_tty_virtual_offset; + } else if (y >= uv_tty_virtual_offset + uv_tty_virtual_height) { + y = uv_tty_virtual_offset + uv_tty_virtual_height - 1; + } + + /* Adjust x */ + if (x_relative) { + x = info->dwCursorPosition.X + x; + } + /* Clip x */ + if (x < 0) { + x = 0; + } else if (x >= uv_tty_virtual_width) { + x = uv_tty_virtual_width - 1; + } + + result.X = (unsigned short) x; + result.Y = (unsigned short) y; + return result; +} + + +static int uv_tty_emit_text(uv_tty_t* handle, WCHAR buffer[], DWORD length, + DWORD* error) { + DWORD written; + + if (*error != ERROR_SUCCESS) { + return -1; + } + + if (!WriteConsoleW(handle->handle, + (void*) buffer, + length, + &written, + NULL)) { + *error = GetLastError(); + return -1; + } + + return 0; +} + + +static int uv_tty_move_caret(uv_tty_t* handle, int x, unsigned char x_relative, + int y, unsigned char y_relative, DWORD* error) { + CONSOLE_SCREEN_BUFFER_INFO info; + COORD pos; + + if (*error != ERROR_SUCCESS) { + return -1; + } + + retry: + if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { + *error = GetLastError(); + } + + pos = uv_tty_make_real_coord(handle, &info, x, x_relative, y, y_relative); + + if (!SetConsoleCursorPosition(handle->handle, pos)) { + if (GetLastError() == ERROR_INVALID_PARAMETER) { + /* The console may be resized - retry */ + goto retry; + } else { + *error = GetLastError(); + return -1; + } + } + + return 0; +} + + +static int uv_tty_reset(uv_tty_t* handle, DWORD* error) { + const COORD origin = {0, 0}; + const WORD char_attrs = uv_tty_default_text_attributes; + CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info; + DWORD count, written; + + if (*error != ERROR_SUCCESS) { + return -1; + } + + /* Reset original text attributes. */ + if (!SetConsoleTextAttribute(handle->handle, char_attrs)) { + *error = GetLastError(); + return -1; + } + + /* Move the cursor position to (0, 0). */ + if (!SetConsoleCursorPosition(handle->handle, origin)) { + *error = GetLastError(); + return -1; + } + + /* Clear the screen buffer. */ + retry: + if (!GetConsoleScreenBufferInfo(handle->handle, &screen_buffer_info)) { + *error = GetLastError(); + return -1; + } + + count = screen_buffer_info.dwSize.X * screen_buffer_info.dwSize.Y; + + if (!(FillConsoleOutputCharacterW(handle->handle, + L'\x20', + count, + origin, + &written) && + FillConsoleOutputAttribute(handle->handle, + char_attrs, + written, + origin, + &written))) { + if (GetLastError() == ERROR_INVALID_PARAMETER) { + /* The console may be resized - retry */ + goto retry; + } else { + *error = GetLastError(); + return -1; + } + } + + /* Move the virtual window up to the top. */ + uv_tty_virtual_offset = 0; + uv_tty_update_virtual_window(&screen_buffer_info); + + /* Reset the cursor size and the cursor state. */ + if (!SetConsoleCursorInfo(handle->handle, &uv_tty_default_cursor_info)) { + *error = GetLastError(); + return -1; + } + + return 0; +} + + +static int uv_tty_clear(uv_tty_t* handle, int dir, char entire_screen, + DWORD* error) { + CONSOLE_SCREEN_BUFFER_INFO info; + COORD start, end; + DWORD count, written; + + int x1, x2, y1, y2; + int x1r, x2r, y1r, y2r; + + if (*error != ERROR_SUCCESS) { + return -1; + } + + if (dir == 0) { + /* Clear from current position */ + x1 = 0; + x1r = 1; + } else { + /* Clear from column 0 */ + x1 = 0; + x1r = 0; + } + + if (dir == 1) { + /* Clear to current position */ + x2 = 0; + x2r = 1; + } else { + /* Clear to end of row. We pretend the console is 65536 characters wide, + * uv_tty_make_real_coord will clip it to the actual console width. */ + x2 = 0xffff; + x2r = 0; + } + + if (!entire_screen) { + /* Stay on our own row */ + y1 = y2 = 0; + y1r = y2r = 1; + } else { + /* Apply columns direction to row */ + y1 = x1; + y1r = x1r; + y2 = x2; + y2r = x2r; + } + + retry: + if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { + *error = GetLastError(); + return -1; + } + + start = uv_tty_make_real_coord(handle, &info, x1, x1r, y1, y1r); + end = uv_tty_make_real_coord(handle, &info, x2, x2r, y2, y2r); + count = (end.Y * info.dwSize.X + end.X) - + (start.Y * info.dwSize.X + start.X) + 1; + + if (!(FillConsoleOutputCharacterW(handle->handle, + L'\x20', + count, + start, + &written) && + FillConsoleOutputAttribute(handle->handle, + info.wAttributes, + written, + start, + &written))) { + if (GetLastError() == ERROR_INVALID_PARAMETER) { + /* The console may be resized - retry */ + goto retry; + } else { + *error = GetLastError(); + return -1; + } + } + + return 0; +} + +#define FLIP_FGBG \ + do { \ + WORD fg = info.wAttributes & 0xF; \ + WORD bg = info.wAttributes & 0xF0; \ + info.wAttributes &= 0xFF00; \ + info.wAttributes |= fg << 4; \ + info.wAttributes |= bg >> 4; \ + } while (0) + +static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) { + unsigned short argc = handle->tty.wr.ansi_csi_argc; + unsigned short* argv = handle->tty.wr.ansi_csi_argv; + int i; + CONSOLE_SCREEN_BUFFER_INFO info; + + char fg_color = -1, bg_color = -1; + char fg_bright = -1, bg_bright = -1; + char inverse = -1; + + if (argc == 0) { + /* Reset mode */ + fg_color = uv_tty_default_fg_color; + bg_color = uv_tty_default_bg_color; + fg_bright = uv_tty_default_fg_bright; + bg_bright = uv_tty_default_bg_bright; + inverse = uv_tty_default_inverse; + } + + for (i = 0; i < argc; i++) { + short arg = argv[i]; + + if (arg == 0) { + /* Reset mode */ + fg_color = uv_tty_default_fg_color; + bg_color = uv_tty_default_bg_color; + fg_bright = uv_tty_default_fg_bright; + bg_bright = uv_tty_default_bg_bright; + inverse = uv_tty_default_inverse; + + } else if (arg == 1) { + /* Foreground bright on */ + fg_bright = 1; + + } else if (arg == 2) { + /* Both bright off */ + fg_bright = 0; + bg_bright = 0; + + } else if (arg == 5) { + /* Background bright on */ + bg_bright = 1; + + } else if (arg == 7) { + /* Inverse: on */ + inverse = 1; + + } else if (arg == 21 || arg == 22) { + /* Foreground bright off */ + fg_bright = 0; + + } else if (arg == 25) { + /* Background bright off */ + bg_bright = 0; + + } else if (arg == 27) { + /* Inverse: off */ + inverse = 0; + + } else if (arg >= 30 && arg <= 37) { + /* Set foreground color */ + fg_color = arg - 30; + + } else if (arg == 39) { + /* Default text color */ + fg_color = uv_tty_default_fg_color; + fg_bright = uv_tty_default_fg_bright; + + } else if (arg >= 40 && arg <= 47) { + /* Set background color */ + bg_color = arg - 40; + + } else if (arg == 49) { + /* Default background color */ + bg_color = uv_tty_default_bg_color; + bg_bright = uv_tty_default_bg_bright; + + } else if (arg >= 90 && arg <= 97) { + /* Set bold foreground color */ + fg_bright = 1; + fg_color = arg - 90; + + } else if (arg >= 100 && arg <= 107) { + /* Set bold background color */ + bg_bright = 1; + bg_color = arg - 100; + + } + } + + if (fg_color == -1 && bg_color == -1 && fg_bright == -1 && + bg_bright == -1 && inverse == -1) { + /* Nothing changed */ + return 0; + } + + if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { + *error = GetLastError(); + return -1; + } + + if ((info.wAttributes & COMMON_LVB_REVERSE_VIDEO) > 0) { + FLIP_FGBG; + } + + if (fg_color != -1) { + info.wAttributes &= ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); + if (fg_color & 1) info.wAttributes |= FOREGROUND_RED; + if (fg_color & 2) info.wAttributes |= FOREGROUND_GREEN; + if (fg_color & 4) info.wAttributes |= FOREGROUND_BLUE; + } + + if (fg_bright != -1) { + if (fg_bright) { + info.wAttributes |= FOREGROUND_INTENSITY; + } else { + info.wAttributes &= ~FOREGROUND_INTENSITY; + } + } + + if (bg_color != -1) { + info.wAttributes &= ~(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); + if (bg_color & 1) info.wAttributes |= BACKGROUND_RED; + if (bg_color & 2) info.wAttributes |= BACKGROUND_GREEN; + if (bg_color & 4) info.wAttributes |= BACKGROUND_BLUE; + } + + if (bg_bright != -1) { + if (bg_bright) { + info.wAttributes |= BACKGROUND_INTENSITY; + } else { + info.wAttributes &= ~BACKGROUND_INTENSITY; + } + } + + if (inverse != -1) { + if (inverse) { + info.wAttributes |= COMMON_LVB_REVERSE_VIDEO; + } else { + info.wAttributes &= ~COMMON_LVB_REVERSE_VIDEO; + } + } + + if ((info.wAttributes & COMMON_LVB_REVERSE_VIDEO) > 0) { + FLIP_FGBG; + } + + if (!SetConsoleTextAttribute(handle->handle, info.wAttributes)) { + *error = GetLastError(); + return -1; + } + + return 0; +} + + +static int uv_tty_save_state(uv_tty_t* handle, unsigned char save_attributes, + DWORD* error) { + CONSOLE_SCREEN_BUFFER_INFO info; + + if (*error != ERROR_SUCCESS) { + return -1; + } + + if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { + *error = GetLastError(); + return -1; + } + + uv_tty_update_virtual_window(&info); + + handle->tty.wr.saved_position.X = info.dwCursorPosition.X; + handle->tty.wr.saved_position.Y = info.dwCursorPosition.Y - uv_tty_virtual_offset; + handle->flags |= UV_HANDLE_TTY_SAVED_POSITION; + + if (save_attributes) { + handle->tty.wr.saved_attributes = info.wAttributes & + (FOREGROUND_INTENSITY | BACKGROUND_INTENSITY); + handle->flags |= UV_HANDLE_TTY_SAVED_ATTRIBUTES; + } + + return 0; +} + + +static int uv_tty_restore_state(uv_tty_t* handle, + unsigned char restore_attributes, DWORD* error) { + CONSOLE_SCREEN_BUFFER_INFO info; + WORD new_attributes; + + if (*error != ERROR_SUCCESS) { + return -1; + } + + if (handle->flags & UV_HANDLE_TTY_SAVED_POSITION) { + if (uv_tty_move_caret(handle, + handle->tty.wr.saved_position.X, + 0, + handle->tty.wr.saved_position.Y, + 0, + error) != 0) { + return -1; + } + } + + if (restore_attributes && + (handle->flags & UV_HANDLE_TTY_SAVED_ATTRIBUTES)) { + if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { + *error = GetLastError(); + return -1; + } + + new_attributes = info.wAttributes; + new_attributes &= ~(FOREGROUND_INTENSITY | BACKGROUND_INTENSITY); + new_attributes |= handle->tty.wr.saved_attributes; + + if (!SetConsoleTextAttribute(handle->handle, new_attributes)) { + *error = GetLastError(); + return -1; + } + } + + return 0; +} + +static int uv_tty_set_cursor_visibility(uv_tty_t* handle, + BOOL visible, + DWORD* error) { + CONSOLE_CURSOR_INFO cursor_info; + + if (!GetConsoleCursorInfo(handle->handle, &cursor_info)) { + *error = GetLastError(); + return -1; + } + + cursor_info.bVisible = visible; + + if (!SetConsoleCursorInfo(handle->handle, &cursor_info)) { + *error = GetLastError(); + return -1; + } + + return 0; +} + +static int uv_tty_set_cursor_shape(uv_tty_t* handle, int style, DWORD* error) { + CONSOLE_CURSOR_INFO cursor_info; + + if (!GetConsoleCursorInfo(handle->handle, &cursor_info)) { + *error = GetLastError(); + return -1; + } + + if (style == 0) { + cursor_info.dwSize = uv_tty_default_cursor_info.dwSize; + } else if (style <= 2) { + cursor_info.dwSize = CURSOR_SIZE_LARGE; + } else { + cursor_info.dwSize = CURSOR_SIZE_SMALL; + } + + if (!SetConsoleCursorInfo(handle->handle, &cursor_info)) { + *error = GetLastError(); + return -1; + } + + return 0; +} + + +static int uv_tty_write_bufs(uv_tty_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + DWORD* error) { + /* We can only write 8k characters at a time. Windows can't handle much more + * characters in a single console write anyway. */ + WCHAR utf16_buf[MAX_CONSOLE_CHAR]; + DWORD utf16_buf_used = 0; + unsigned int i; + +#define FLUSH_TEXT() \ + do { \ + if (utf16_buf_used > 0) { \ + uv_tty_emit_text(handle, utf16_buf, utf16_buf_used, error); \ + utf16_buf_used = 0; \ + } \ + } while (0) + +#define ENSURE_BUFFER_SPACE(wchars_needed) \ + if (wchars_needed > ARRAY_SIZE(utf16_buf) - utf16_buf_used) { \ + FLUSH_TEXT(); \ + } + + /* Cache for fast access */ + unsigned char utf8_bytes_left = handle->tty.wr.utf8_bytes_left; + unsigned int utf8_codepoint = handle->tty.wr.utf8_codepoint; + unsigned char previous_eol = handle->tty.wr.previous_eol; + unsigned short ansi_parser_state = handle->tty.wr.ansi_parser_state; + + /* Store the error here. If we encounter an error, stop trying to do i/o but + * keep parsing the buffer so we leave the parser in a consistent state. */ + *error = ERROR_SUCCESS; + + uv_sem_wait(&uv_tty_output_lock); + + for (i = 0; i < nbufs; i++) { + uv_buf_t buf = bufs[i]; + unsigned int j; + + for (j = 0; j < buf.len; j++) { + unsigned char c = buf.base[j]; + + /* Run the character through the utf8 decoder We happily accept non + * shortest form encodings and invalid code points - there's no real harm + * that can be done. */ + if (utf8_bytes_left == 0) { + /* Read utf-8 start byte */ + DWORD first_zero_bit; + unsigned char not_c = ~c; +#ifdef _MSC_VER /* msvc */ + if (_BitScanReverse(&first_zero_bit, not_c)) { +#else /* assume gcc */ + if (c != 0) { + first_zero_bit = (sizeof(int) * 8) - 1 - __builtin_clz(not_c); +#endif + if (first_zero_bit == 7) { + /* Ascii - pass right through */ + utf8_codepoint = (unsigned int) c; + + } else if (first_zero_bit <= 5) { + /* Multibyte sequence */ + utf8_codepoint = (0xff >> (8 - first_zero_bit)) & c; + utf8_bytes_left = (char) (6 - first_zero_bit); + + } else { + /* Invalid continuation */ + utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; + } + + } else { + /* 0xff -- invalid */ + utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; + } + + } else if ((c & 0xc0) == 0x80) { + /* Valid continuation of utf-8 multibyte sequence */ + utf8_bytes_left--; + utf8_codepoint <<= 6; + utf8_codepoint |= ((unsigned int) c & 0x3f); + + } else { + /* Start byte where continuation was expected. */ + utf8_bytes_left = 0; + utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; + /* Patch buf offset so this character will be parsed again as a start + * byte. */ + j--; + } + + /* Maybe we need to parse more bytes to find a character. */ + if (utf8_bytes_left != 0) { + continue; + } + + /* Parse vt100/ansi escape codes */ + if (uv__vterm_state == UV_TTY_SUPPORTED) { + /* Pass through escape codes if conhost supports them. */ + } else if (ansi_parser_state == ANSI_NORMAL) { + switch (utf8_codepoint) { + case '\033': + ansi_parser_state = ANSI_ESCAPE_SEEN; + continue; + + case 0233: + ansi_parser_state = ANSI_CSI; + handle->tty.wr.ansi_csi_argc = 0; + continue; + } + + } else if (ansi_parser_state == ANSI_ESCAPE_SEEN) { + switch (utf8_codepoint) { + case '[': + ansi_parser_state = ANSI_CSI; + handle->tty.wr.ansi_csi_argc = 0; + continue; + + case '^': + case '_': + case 'P': + case ']': + /* Not supported, but we'll have to parse until we see a stop code, + * e. g. ESC \ or BEL. */ + ansi_parser_state = ANSI_ST_CONTROL; + continue; + + case '\033': + /* Ignore double escape. */ + continue; + + case 'c': + /* Full console reset. */ + FLUSH_TEXT(); + uv_tty_reset(handle, error); + ansi_parser_state = ANSI_NORMAL; + continue; + + case '7': + /* Save the cursor position and text attributes. */ + FLUSH_TEXT(); + uv_tty_save_state(handle, 1, error); + ansi_parser_state = ANSI_NORMAL; + continue; + + case '8': + /* Restore the cursor position and text attributes */ + FLUSH_TEXT(); + uv_tty_restore_state(handle, 1, error); + ansi_parser_state = ANSI_NORMAL; + continue; + + default: + if (utf8_codepoint >= '@' && utf8_codepoint <= '_') { + /* Single-char control. */ + ansi_parser_state = ANSI_NORMAL; + continue; + } else { + /* Invalid - proceed as normal, */ + ansi_parser_state = ANSI_NORMAL; + } + } + + } else if (ansi_parser_state == ANSI_IGNORE) { + /* We're ignoring this command. Stop only on command character. */ + if (utf8_codepoint >= '@' && utf8_codepoint <= '~') { + ansi_parser_state = ANSI_NORMAL; + } + continue; + + } else if (ansi_parser_state == ANSI_DECSCUSR) { + /* So far we've the sequence `ESC [ arg space`, and we're waiting for + * the final command byte. */ + if (utf8_codepoint >= '@' && utf8_codepoint <= '~') { + /* Command byte */ + if (utf8_codepoint == 'q') { + /* Change the cursor shape */ + int style = handle->tty.wr.ansi_csi_argc + ? handle->tty.wr.ansi_csi_argv[0] : 1; + if (style >= 0 && style <= 6) { + FLUSH_TEXT(); + uv_tty_set_cursor_shape(handle, style, error); + } + } + + /* Sequence ended - go back to normal state. */ + ansi_parser_state = ANSI_NORMAL; + continue; + } + /* Unexpected character, but sequence hasn't ended yet. Ignore the rest + * of the sequence. */ + ansi_parser_state = ANSI_IGNORE; + + } else if (ansi_parser_state & ANSI_CSI) { + /* So far we've seen `ESC [`, and we may or may not have already parsed + * some of the arguments that follow. */ + + if (utf8_codepoint >= '0' && utf8_codepoint <= '9') { + /* Parse a numerical argument. */ + if (!(ansi_parser_state & ANSI_IN_ARG)) { + /* We were not currently parsing a number, add a new one. */ + /* Check for that there are too many arguments. */ + if (handle->tty.wr.ansi_csi_argc >= + ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) { + ansi_parser_state = ANSI_IGNORE; + continue; + } + ansi_parser_state |= ANSI_IN_ARG; + handle->tty.wr.ansi_csi_argc++; + handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] = + (unsigned short) utf8_codepoint - '0'; + continue; + + } else { + /* We were already parsing a number. Parse next digit. */ + uint32_t value = 10 * + handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1]; + + /* Check for overflow. */ + if (value > UINT16_MAX) { + ansi_parser_state = ANSI_IGNORE; + continue; + } + + handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] = + (unsigned short) value + (utf8_codepoint - '0'); + continue; + } + + } else if (utf8_codepoint == ';') { + /* Denotes the end of an argument. */ + if (ansi_parser_state & ANSI_IN_ARG) { + ansi_parser_state &= ~ANSI_IN_ARG; + continue; + + } else { + /* If ANSI_IN_ARG is not set, add another argument and default + * it to 0. */ + + /* Check for too many arguments */ + if (handle->tty.wr.ansi_csi_argc >= + + ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) { + ansi_parser_state = ANSI_IGNORE; + continue; + } + + handle->tty.wr.ansi_csi_argc++; + handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] = 0; + continue; + } + + } else if (utf8_codepoint == '?' && + !(ansi_parser_state & ANSI_IN_ARG) && + !(ansi_parser_state & ANSI_EXTENSION) && + handle->tty.wr.ansi_csi_argc == 0) { + /* Pass through '?' if it is the first character after CSI */ + /* This is an extension character from the VT100 codeset */ + /* that is supported and used by most ANSI terminals today. */ + ansi_parser_state |= ANSI_EXTENSION; + continue; + + } else if (utf8_codepoint == ' ' && + !(ansi_parser_state & ANSI_EXTENSION)) { + /* We expect a command byte to follow after this space. The only + * command that we current support is 'set cursor style'. */ + ansi_parser_state = ANSI_DECSCUSR; + continue; + + } else if (utf8_codepoint >= '@' && utf8_codepoint <= '~') { + /* Command byte */ + if (ansi_parser_state & ANSI_EXTENSION) { + /* Sequence is `ESC [ ? args command`. */ + switch (utf8_codepoint) { + case 'l': + /* Hide the cursor */ + if (handle->tty.wr.ansi_csi_argc == 1 && + handle->tty.wr.ansi_csi_argv[0] == 25) { + FLUSH_TEXT(); + uv_tty_set_cursor_visibility(handle, 0, error); + } + break; + + case 'h': + /* Show the cursor */ + if (handle->tty.wr.ansi_csi_argc == 1 && + handle->tty.wr.ansi_csi_argv[0] == 25) { + FLUSH_TEXT(); + uv_tty_set_cursor_visibility(handle, 1, error); + } + break; + } + + } else { + /* Sequence is `ESC [ args command`. */ + int x, y, d; + switch (utf8_codepoint) { + case 'A': + /* cursor up */ + FLUSH_TEXT(); + y = -(handle->tty.wr.ansi_csi_argc + ? handle->tty.wr.ansi_csi_argv[0] : 1); + uv_tty_move_caret(handle, 0, 1, y, 1, error); + break; + + case 'B': + /* cursor down */ + FLUSH_TEXT(); + y = handle->tty.wr.ansi_csi_argc + ? handle->tty.wr.ansi_csi_argv[0] : 1; + uv_tty_move_caret(handle, 0, 1, y, 1, error); + break; + + case 'C': + /* cursor forward */ + FLUSH_TEXT(); + x = handle->tty.wr.ansi_csi_argc + ? handle->tty.wr.ansi_csi_argv[0] : 1; + uv_tty_move_caret(handle, x, 1, 0, 1, error); + break; + + case 'D': + /* cursor back */ + FLUSH_TEXT(); + x = -(handle->tty.wr.ansi_csi_argc + ? handle->tty.wr.ansi_csi_argv[0] : 1); + uv_tty_move_caret(handle, x, 1, 0, 1, error); + break; + + case 'E': + /* cursor next line */ + FLUSH_TEXT(); + y = handle->tty.wr.ansi_csi_argc + ? handle->tty.wr.ansi_csi_argv[0] : 1; + uv_tty_move_caret(handle, 0, 0, y, 1, error); + break; + + case 'F': + /* cursor previous line */ + FLUSH_TEXT(); + y = -(handle->tty.wr.ansi_csi_argc + ? handle->tty.wr.ansi_csi_argv[0] : 1); + uv_tty_move_caret(handle, 0, 0, y, 1, error); + break; + + case 'G': + /* cursor horizontal move absolute */ + FLUSH_TEXT(); + x = (handle->tty.wr.ansi_csi_argc >= 1 && + handle->tty.wr.ansi_csi_argv[0]) + ? handle->tty.wr.ansi_csi_argv[0] - 1 : 0; + uv_tty_move_caret(handle, x, 0, 0, 1, error); + break; + + case 'H': + case 'f': + /* cursor move absolute */ + FLUSH_TEXT(); + y = (handle->tty.wr.ansi_csi_argc >= 1 && + handle->tty.wr.ansi_csi_argv[0]) + ? handle->tty.wr.ansi_csi_argv[0] - 1 : 0; + x = (handle->tty.wr.ansi_csi_argc >= 2 && + handle->tty.wr.ansi_csi_argv[1]) + ? handle->tty.wr.ansi_csi_argv[1] - 1 : 0; + uv_tty_move_caret(handle, x, 0, y, 0, error); + break; + + case 'J': + /* Erase screen */ + FLUSH_TEXT(); + d = handle->tty.wr.ansi_csi_argc + ? handle->tty.wr.ansi_csi_argv[0] : 0; + if (d >= 0 && d <= 2) { + uv_tty_clear(handle, d, 1, error); + } + break; + + case 'K': + /* Erase line */ + FLUSH_TEXT(); + d = handle->tty.wr.ansi_csi_argc + ? handle->tty.wr.ansi_csi_argv[0] : 0; + if (d >= 0 && d <= 2) { + uv_tty_clear(handle, d, 0, error); + } + break; + + case 'm': + /* Set style */ + FLUSH_TEXT(); + uv_tty_set_style(handle, error); + break; + + case 's': + /* Save the cursor position. */ + FLUSH_TEXT(); + uv_tty_save_state(handle, 0, error); + break; + + case 'u': + /* Restore the cursor position */ + FLUSH_TEXT(); + uv_tty_restore_state(handle, 0, error); + break; + } + } + + /* Sequence ended - go back to normal state. */ + ansi_parser_state = ANSI_NORMAL; + continue; + + } else { + /* We don't support commands that use private mode characters or + * intermediaries. Ignore the rest of the sequence. */ + ansi_parser_state = ANSI_IGNORE; + continue; + } + + } else if (ansi_parser_state & ANSI_ST_CONTROL) { + /* Unsupported control code. + * Ignore everything until we see `BEL` or `ESC \`. */ + if (ansi_parser_state & ANSI_IN_STRING) { + if (!(ansi_parser_state & ANSI_BACKSLASH_SEEN)) { + if (utf8_codepoint == '"') { + ansi_parser_state &= ~ANSI_IN_STRING; + } else if (utf8_codepoint == '\\') { + ansi_parser_state |= ANSI_BACKSLASH_SEEN; + } + } else { + ansi_parser_state &= ~ANSI_BACKSLASH_SEEN; + } + } else { + if (utf8_codepoint == '\007' || (utf8_codepoint == '\\' && + (ansi_parser_state & ANSI_ESCAPE_SEEN))) { + /* End of sequence */ + ansi_parser_state = ANSI_NORMAL; + } else if (utf8_codepoint == '\033') { + /* Escape character */ + ansi_parser_state |= ANSI_ESCAPE_SEEN; + } else if (utf8_codepoint == '"') { + /* String starting */ + ansi_parser_state |= ANSI_IN_STRING; + ansi_parser_state &= ~ANSI_ESCAPE_SEEN; + ansi_parser_state &= ~ANSI_BACKSLASH_SEEN; + } else { + ansi_parser_state &= ~ANSI_ESCAPE_SEEN; + } + } + continue; + } else { + /* Inconsistent state */ + abort(); + } + + if (utf8_codepoint == 0x0a || utf8_codepoint == 0x0d) { + /* EOL conversion - emit \r\n when we see \n. */ + + if (utf8_codepoint == 0x0a && previous_eol != 0x0d) { + /* \n was not preceded by \r; print \r\n. */ + ENSURE_BUFFER_SPACE(2); + utf16_buf[utf16_buf_used++] = L'\r'; + utf16_buf[utf16_buf_used++] = L'\n'; + } else if (utf8_codepoint == 0x0d && previous_eol == 0x0a) { + /* \n was followed by \r; do not print the \r, since the source was + * either \r\n\r (so the second \r is redundant) or was \n\r (so the + * \n was processed by the last case and an \r automatically + * inserted). */ + } else { + /* \r without \n; print \r as-is. */ + ENSURE_BUFFER_SPACE(1); + utf16_buf[utf16_buf_used++] = (WCHAR) utf8_codepoint; + } + + previous_eol = (char) utf8_codepoint; + + } else if (utf8_codepoint <= 0xffff) { + /* Encode character into utf-16 buffer. */ + ENSURE_BUFFER_SPACE(1); + utf16_buf[utf16_buf_used++] = (WCHAR) utf8_codepoint; + previous_eol = 0; + } else { + ENSURE_BUFFER_SPACE(2); + utf8_codepoint -= 0x10000; + utf16_buf[utf16_buf_used++] = (WCHAR) (utf8_codepoint / 0x400 + 0xD800); + utf16_buf[utf16_buf_used++] = (WCHAR) (utf8_codepoint % 0x400 + 0xDC00); + previous_eol = 0; + } + } + } + + /* Flush remaining characters */ + FLUSH_TEXT(); + + /* Copy cached values back to struct. */ + handle->tty.wr.utf8_bytes_left = utf8_bytes_left; + handle->tty.wr.utf8_codepoint = utf8_codepoint; + handle->tty.wr.previous_eol = previous_eol; + handle->tty.wr.ansi_parser_state = ansi_parser_state; + + uv_sem_post(&uv_tty_output_lock); + + if (*error == STATUS_SUCCESS) { + return 0; + } else { + return -1; + } + +#undef FLUSH_TEXT +} + + +int uv_tty_write(uv_loop_t* loop, + uv_write_t* req, + uv_tty_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_write_cb cb) { + DWORD error; + + UV_REQ_INIT(req, UV_WRITE); + req->handle = (uv_stream_t*) handle; + req->cb = cb; + + handle->reqs_pending++; + handle->stream.conn.write_reqs_pending++; + REGISTER_HANDLE_REQ(loop, handle, req); + + req->u.io.queued_bytes = 0; + + if (!uv_tty_write_bufs(handle, bufs, nbufs, &error)) { + SET_REQ_SUCCESS(req); + } else { + SET_REQ_ERROR(req, error); + } + + uv_insert_pending_req(loop, (uv_req_t*) req); + + return 0; +} + + +int uv__tty_try_write(uv_tty_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs) { + DWORD error; + + if (handle->stream.conn.write_reqs_pending > 0) + return UV_EAGAIN; + + if (uv_tty_write_bufs(handle, bufs, nbufs, &error)) + return uv_translate_sys_error(error); + + return uv__count_bufs(bufs, nbufs); +} + + +void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle, + uv_write_t* req) { + int err; + + handle->write_queue_size -= req->u.io.queued_bytes; + UNREGISTER_HANDLE_REQ(loop, handle, req); + + if (req->cb) { + err = GET_REQ_ERROR(req); + req->cb(req, uv_translate_sys_error(err)); + } + + handle->stream.conn.write_reqs_pending--; + if (handle->stream.conn.shutdown_req != NULL && + handle->stream.conn.write_reqs_pending == 0) { + uv_want_endgame(loop, (uv_handle_t*)handle); + } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +void uv_tty_close(uv_tty_t* handle) { + assert(handle->u.fd == -1 || handle->u.fd > 2); + if (handle->flags & UV_HANDLE_READING) + uv_tty_read_stop(handle); + + if (handle->u.fd == -1) + CloseHandle(handle->handle); + else + close(handle->u.fd); + + handle->u.fd = -1; + handle->handle = INVALID_HANDLE_VALUE; + handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); + uv__handle_closing(handle); + + if (handle->reqs_pending == 0) { + uv_want_endgame(handle->loop, (uv_handle_t*) handle); + } +} + + +void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) { + if (!(handle->flags & UV_HANDLE_TTY_READABLE) && + handle->stream.conn.shutdown_req != NULL && + handle->stream.conn.write_reqs_pending == 0) { + UNREGISTER_HANDLE_REQ(loop, handle, handle->stream.conn.shutdown_req); + + /* TTY shutdown is really just a no-op */ + if (handle->stream.conn.shutdown_req->cb) { + if (handle->flags & UV_HANDLE_CLOSING) { + handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, UV_ECANCELED); + } else { + handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, 0); + } + } + + handle->stream.conn.shutdown_req = NULL; + + DECREASE_PENDING_REQ_COUNT(handle); + return; + } + + if (handle->flags & UV_HANDLE_CLOSING && + handle->reqs_pending == 0) { + /* The wait handle used for raw reading should be unregistered when the + * wait callback runs. */ + assert(!(handle->flags & UV_HANDLE_TTY_READABLE) || + handle->tty.rd.read_raw_wait == NULL); + + assert(!(handle->flags & UV_HANDLE_CLOSED)); + uv__handle_close(handle); + } +} + + +/* + * uv_process_tty_accept_req() is a stub to keep DELEGATE_STREAM_REQ working + * TODO: find a way to remove it + */ +void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle, + uv_req_t* raw_req) { + abort(); +} + + +/* + * uv_process_tty_connect_req() is a stub to keep DELEGATE_STREAM_REQ working + * TODO: find a way to remove it + */ +void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle, + uv_connect_t* req) { + abort(); +} + + +int uv_tty_reset_mode(void) { + /* Not necessary to do anything. */ + return 0; +} + +/* Determine whether or not this version of windows supports + * proper ANSI color codes. Should be supported as of windows + * 10 version 1511, build number 10.0.10586. + */ +static void uv__determine_vterm_state(HANDLE handle) { + DWORD dwMode = 0; + + uv__need_check_vterm_state = FALSE; + if (!GetConsoleMode(handle, &dwMode)) { + return; + } + + dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + if (!SetConsoleMode(handle, dwMode)) { + return; + } + + uv__vterm_state = UV_TTY_SUPPORTED; +} + +static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param) { + NTSTATUS status; + ULONG_PTR conhost_pid; + MSG msg; + + if (pSetWinEventHook == NULL || pNtQueryInformationProcess == NULL) + return 0; + + status = pNtQueryInformationProcess(GetCurrentProcess(), + ProcessConsoleHostProcess, + &conhost_pid, + sizeof(conhost_pid), + NULL); + + if (!NT_SUCCESS(status)) { + /* We couldn't retrieve our console host process, probably because this + * is a 32-bit process running on 64-bit Windows. Fall back to receiving + * console events from the input stream only. */ + return 0; + } + + /* Ensure the PID is a multiple of 4, which is required by SetWinEventHook */ + conhost_pid &= ~(ULONG_PTR)0x3; + + uv__tty_console_resized = CreateEvent(NULL, TRUE, FALSE, NULL); + if (uv__tty_console_resized == NULL) + return 0; + if (QueueUserWorkItem(uv__tty_console_resize_watcher_thread, + NULL, + WT_EXECUTELONGFUNCTION) == 0) + return 0; + + if (!pSetWinEventHook(EVENT_CONSOLE_LAYOUT, + EVENT_CONSOLE_LAYOUT, + NULL, + uv__tty_console_resize_event, + (DWORD)conhost_pid, + 0, + WINEVENT_OUTOFCONTEXT)) + return 0; + + while (GetMessage(&msg, NULL, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return 0; +} + +static void CALLBACK uv__tty_console_resize_event(HWINEVENTHOOK hWinEventHook, + DWORD event, + HWND hwnd, + LONG idObject, + LONG idChild, + DWORD dwEventThread, + DWORD dwmsEventTime) { + SetEvent(uv__tty_console_resized); +} + +static DWORD WINAPI uv__tty_console_resize_watcher_thread(void* param) { + for (;;) { + /* Make sure to not overwhelm the system with resize events */ + Sleep(33); + WaitForSingleObject(uv__tty_console_resized, INFINITE); + uv__tty_console_signal_resize(); + ResetEvent(uv__tty_console_resized); + } + return 0; +} + +static void uv__tty_console_signal_resize(void) { + CONSOLE_SCREEN_BUFFER_INFO sb_info; + int width, height; + + if (!GetConsoleScreenBufferInfo(uv__tty_console_handle, &sb_info)) + return; + + width = sb_info.dwSize.X; + height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1; + + uv_mutex_lock(&uv__tty_console_resize_mutex); + assert(uv__tty_console_width != -1 && uv__tty_console_height != -1); + if (width != uv__tty_console_width || height != uv__tty_console_height) { + uv__tty_console_width = width; + uv__tty_console_height = height; + uv_mutex_unlock(&uv__tty_console_resize_mutex); + uv__signal_dispatch(SIGWINCH); + } else { + uv_mutex_unlock(&uv__tty_console_resize_mutex); + } +} + +void uv_tty_set_vterm_state(uv_tty_vtermstate_t state) { + uv_sem_wait(&uv_tty_output_lock); + uv__need_check_vterm_state = FALSE; + uv__vterm_state = state; + uv_sem_post(&uv_tty_output_lock); +} + +int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state) { + uv_sem_wait(&uv_tty_output_lock); + *state = uv__vterm_state; + uv_sem_post(&uv_tty_output_lock); + return 0; +} diff --git a/external/src/libuv/src/win/udp.c b/external/src/libuv/src/win/udp.c new file mode 100644 index 0000000..3043f2d --- /dev/null +++ b/external/src/libuv/src/win/udp.c @@ -0,0 +1,1181 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include + +#include "uv.h" +#include "internal.h" +#include "handle-inl.h" +#include "stream-inl.h" +#include "req-inl.h" + + +/* + * Threshold of active udp streams for which to preallocate udp read buffers. + */ +const unsigned int uv_active_udp_streams_threshold = 0; + +/* A zero-size buffer for use by uv_udp_read */ +static char uv_zero_[] = ""; +int uv_udp_getpeername(const uv_udp_t* handle, + struct sockaddr* name, + int* namelen) { + + return uv__getsockpeername((const uv_handle_t*) handle, + getpeername, + name, + namelen, + 0); +} + + +int uv_udp_getsockname(const uv_udp_t* handle, + struct sockaddr* name, + int* namelen) { + + return uv__getsockpeername((const uv_handle_t*) handle, + getsockname, + name, + namelen, + 0); +} + + +static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket, + int family) { + DWORD yes = 1; + WSAPROTOCOL_INFOW info; + int opt_len; + + if (handle->socket != INVALID_SOCKET) + return UV_EBUSY; + + /* Set the socket to nonblocking mode */ + if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) { + return WSAGetLastError(); + } + + /* Make the socket non-inheritable */ + if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) { + return GetLastError(); + } + + /* Associate it with the I/O completion port. Use uv_handle_t pointer as + * completion key. */ + if (CreateIoCompletionPort((HANDLE)socket, + loop->iocp, + (ULONG_PTR)socket, + 0) == NULL) { + return GetLastError(); + } + + /* All known Windows that support SetFileCompletionNotificationModes have a + * bug that makes it impossible to use this function in conjunction with + * datagram sockets. We can work around that but only if the user is using + * the default UDP driver (AFD) and has no other. LSPs stacked on top. Here + * we check whether that is the case. */ + opt_len = (int) sizeof info; + if (getsockopt( + socket, SOL_SOCKET, SO_PROTOCOL_INFOW, (char*) &info, &opt_len) == + SOCKET_ERROR) { + return GetLastError(); + } + + if (info.ProtocolChain.ChainLen == 1) { + if (SetFileCompletionNotificationModes( + (HANDLE) socket, + FILE_SKIP_SET_EVENT_ON_HANDLE | + FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) { + handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP; + handle->func_wsarecv = uv_wsarecv_workaround; + handle->func_wsarecvfrom = uv_wsarecvfrom_workaround; + } else if (GetLastError() != ERROR_INVALID_FUNCTION) { + return GetLastError(); + } + } + + handle->socket = socket; + + if (family == AF_INET6) { + handle->flags |= UV_HANDLE_IPV6; + } else { + assert(!(handle->flags & UV_HANDLE_IPV6)); + } + + return 0; +} + + +int uv__udp_init_ex(uv_loop_t* loop, + uv_udp_t* handle, + unsigned flags, + int domain) { + uv__handle_init(loop, (uv_handle_t*) handle, UV_UDP); + handle->socket = INVALID_SOCKET; + handle->reqs_pending = 0; + handle->activecnt = 0; + handle->func_wsarecv = WSARecv; + handle->func_wsarecvfrom = WSARecvFrom; + handle->send_queue_size = 0; + handle->send_queue_count = 0; + UV_REQ_INIT(&handle->recv_req, UV_UDP_RECV); + handle->recv_req.data = handle; + + /* If anything fails beyond this point we need to remove the handle from + * the handle queue, since it was added by uv__handle_init. + */ + + if (domain != AF_UNSPEC) { + SOCKET sock; + DWORD err; + + sock = socket(domain, SOCK_DGRAM, 0); + if (sock == INVALID_SOCKET) { + err = WSAGetLastError(); + QUEUE_REMOVE(&handle->handle_queue); + return uv_translate_sys_error(err); + } + + err = uv_udp_set_socket(handle->loop, handle, sock, domain); + if (err) { + closesocket(sock); + QUEUE_REMOVE(&handle->handle_queue); + return uv_translate_sys_error(err); + } + } + + return 0; +} + + +void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) { + uv_udp_recv_stop(handle); + closesocket(handle->socket); + handle->socket = INVALID_SOCKET; + + uv__handle_closing(handle); + + if (handle->reqs_pending == 0) { + uv_want_endgame(loop, (uv_handle_t*) handle); + } +} + + +void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) { + if (handle->flags & UV_HANDLE_CLOSING && + handle->reqs_pending == 0) { + assert(!(handle->flags & UV_HANDLE_CLOSED)); + uv__handle_close(handle); + } +} + + +int uv_udp_using_recvmmsg(const uv_udp_t* handle) { + return 0; +} + + +static int uv_udp_maybe_bind(uv_udp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen, + unsigned int flags) { + int r; + int err; + DWORD no = 0; + + if (handle->flags & UV_HANDLE_BOUND) + return 0; + + if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6) { + /* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */ + return ERROR_INVALID_PARAMETER; + } + + if (handle->socket == INVALID_SOCKET) { + SOCKET sock = socket(addr->sa_family, SOCK_DGRAM, 0); + if (sock == INVALID_SOCKET) { + return WSAGetLastError(); + } + + err = uv_udp_set_socket(handle->loop, handle, sock, addr->sa_family); + if (err) { + closesocket(sock); + return err; + } + } + + if (flags & UV_UDP_REUSEADDR) { + DWORD yes = 1; + /* Set SO_REUSEADDR on the socket. */ + if (setsockopt(handle->socket, + SOL_SOCKET, + SO_REUSEADDR, + (char*) &yes, + sizeof yes) == SOCKET_ERROR) { + err = WSAGetLastError(); + return err; + } + } + + if (addr->sa_family == AF_INET6) + handle->flags |= UV_HANDLE_IPV6; + + if (addr->sa_family == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) { + /* On windows IPV6ONLY is on by default. If the user doesn't specify it + * libuv turns it off. */ + + /* TODO: how to handle errors? This may fail if there is no ipv4 stack + * available, or when run on XP/2003 which have no support for dualstack + * sockets. For now we're silently ignoring the error. */ + setsockopt(handle->socket, + IPPROTO_IPV6, + IPV6_V6ONLY, + (char*) &no, + sizeof no); + } + + r = bind(handle->socket, addr, addrlen); + if (r == SOCKET_ERROR) { + return WSAGetLastError(); + } + + handle->flags |= UV_HANDLE_BOUND; + + return 0; +} + + +static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) { + uv_req_t* req; + uv_buf_t buf; + DWORD bytes, flags; + int result; + + assert(handle->flags & UV_HANDLE_READING); + assert(!(handle->flags & UV_HANDLE_READ_PENDING)); + + req = &handle->recv_req; + memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); + + /* + * Preallocate a read buffer if the number of active streams is below + * the threshold. + */ + if (loop->active_udp_streams < uv_active_udp_streams_threshold) { + handle->flags &= ~UV_HANDLE_ZERO_READ; + + handle->recv_buffer = uv_buf_init(NULL, 0); + handle->alloc_cb((uv_handle_t*) handle, UV__UDP_DGRAM_MAXSIZE, &handle->recv_buffer); + if (handle->recv_buffer.base == NULL || handle->recv_buffer.len == 0) { + handle->recv_cb(handle, UV_ENOBUFS, &handle->recv_buffer, NULL, 0); + return; + } + assert(handle->recv_buffer.base != NULL); + + buf = handle->recv_buffer; + memset(&handle->recv_from, 0, sizeof handle->recv_from); + handle->recv_from_len = sizeof handle->recv_from; + flags = 0; + + result = handle->func_wsarecvfrom(handle->socket, + (WSABUF*) &buf, + 1, + &bytes, + &flags, + (struct sockaddr*) &handle->recv_from, + &handle->recv_from_len, + &req->u.io.overlapped, + NULL); + + if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { + /* Process the req without IOCP. */ + handle->flags |= UV_HANDLE_READ_PENDING; + req->u.io.overlapped.InternalHigh = bytes; + handle->reqs_pending++; + uv_insert_pending_req(loop, req); + } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { + /* The req will be processed with IOCP. */ + handle->flags |= UV_HANDLE_READ_PENDING; + handle->reqs_pending++; + } else { + /* Make this req pending reporting an error. */ + SET_REQ_ERROR(req, WSAGetLastError()); + uv_insert_pending_req(loop, req); + handle->reqs_pending++; + } + + } else { + handle->flags |= UV_HANDLE_ZERO_READ; + + buf.base = (char*) uv_zero_; + buf.len = 0; + flags = MSG_PEEK; + + result = handle->func_wsarecv(handle->socket, + (WSABUF*) &buf, + 1, + &bytes, + &flags, + &req->u.io.overlapped, + NULL); + + if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { + /* Process the req without IOCP. */ + handle->flags |= UV_HANDLE_READ_PENDING; + req->u.io.overlapped.InternalHigh = bytes; + handle->reqs_pending++; + uv_insert_pending_req(loop, req); + } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { + /* The req will be processed with IOCP. */ + handle->flags |= UV_HANDLE_READ_PENDING; + handle->reqs_pending++; + } else { + /* Make this req pending reporting an error. */ + SET_REQ_ERROR(req, WSAGetLastError()); + uv_insert_pending_req(loop, req); + handle->reqs_pending++; + } + } +} + + +int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, + uv_udp_recv_cb recv_cb) { + uv_loop_t* loop = handle->loop; + int err; + + if (handle->flags & UV_HANDLE_READING) { + return UV_EALREADY; + } + + err = uv_udp_maybe_bind(handle, + (const struct sockaddr*) &uv_addr_ip4_any_, + sizeof(uv_addr_ip4_any_), + 0); + if (err) + return uv_translate_sys_error(err); + + handle->flags |= UV_HANDLE_READING; + INCREASE_ACTIVE_COUNT(loop, handle); + loop->active_udp_streams++; + + handle->recv_cb = recv_cb; + handle->alloc_cb = alloc_cb; + + /* If reading was stopped and then started again, there could still be a recv + * request pending. */ + if (!(handle->flags & UV_HANDLE_READ_PENDING)) + uv_udp_queue_recv(loop, handle); + + return 0; +} + + +int uv__udp_recv_stop(uv_udp_t* handle) { + if (handle->flags & UV_HANDLE_READING) { + handle->flags &= ~UV_HANDLE_READING; + handle->loop->active_udp_streams--; + DECREASE_ACTIVE_COUNT(loop, handle); + } + + return 0; +} + + +static int uv__send(uv_udp_send_t* req, + uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr, + unsigned int addrlen, + uv_udp_send_cb cb) { + uv_loop_t* loop = handle->loop; + DWORD result, bytes; + + UV_REQ_INIT(req, UV_UDP_SEND); + req->handle = handle; + req->cb = cb; + memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); + + result = WSASendTo(handle->socket, + (WSABUF*)bufs, + nbufs, + &bytes, + 0, + addr, + addrlen, + &req->u.io.overlapped, + NULL); + + if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { + /* Request completed immediately. */ + req->u.io.queued_bytes = 0; + handle->reqs_pending++; + handle->send_queue_size += req->u.io.queued_bytes; + handle->send_queue_count++; + REGISTER_HANDLE_REQ(loop, handle, req); + uv_insert_pending_req(loop, (uv_req_t*)req); + } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { + /* Request queued by the kernel. */ + req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs); + handle->reqs_pending++; + handle->send_queue_size += req->u.io.queued_bytes; + handle->send_queue_count++; + REGISTER_HANDLE_REQ(loop, handle, req); + } else { + /* Send failed due to an error. */ + return WSAGetLastError(); + } + + return 0; +} + + +void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, + uv_req_t* req) { + uv_buf_t buf; + int partial; + + assert(handle->type == UV_UDP); + + handle->flags &= ~UV_HANDLE_READ_PENDING; + + if (!REQ_SUCCESS(req)) { + DWORD err = GET_REQ_SOCK_ERROR(req); + if (err == WSAEMSGSIZE) { + /* Not a real error, it just indicates that the received packet was + * bigger than the receive buffer. */ + } else if (err == WSAECONNRESET || err == WSAENETRESET) { + /* A previous sendto operation failed; ignore this error. If zero-reading + * we need to call WSARecv/WSARecvFrom _without_ the. MSG_PEEK flag to + * clear out the error queue. For nonzero reads, immediately queue a new + * receive. */ + if (!(handle->flags & UV_HANDLE_ZERO_READ)) { + goto done; + } + } else { + /* A real error occurred. Report the error to the user only if we're + * currently reading. */ + if (handle->flags & UV_HANDLE_READING) { + uv_udp_recv_stop(handle); + buf = (handle->flags & UV_HANDLE_ZERO_READ) ? + uv_buf_init(NULL, 0) : handle->recv_buffer; + handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0); + } + goto done; + } + } + + if (!(handle->flags & UV_HANDLE_ZERO_READ)) { + /* Successful read */ + partial = !REQ_SUCCESS(req); + handle->recv_cb(handle, + req->u.io.overlapped.InternalHigh, + &handle->recv_buffer, + (const struct sockaddr*) &handle->recv_from, + partial ? UV_UDP_PARTIAL : 0); + } else if (handle->flags & UV_HANDLE_READING) { + DWORD bytes, err, flags; + struct sockaddr_storage from; + int from_len; + + /* Do a nonblocking receive. + * TODO: try to read multiple datagrams at once. FIONREAD maybe? */ + buf = uv_buf_init(NULL, 0); + handle->alloc_cb((uv_handle_t*) handle, UV__UDP_DGRAM_MAXSIZE, &buf); + if (buf.base == NULL || buf.len == 0) { + handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0); + goto done; + } + assert(buf.base != NULL); + + memset(&from, 0, sizeof from); + from_len = sizeof from; + + flags = 0; + + if (WSARecvFrom(handle->socket, + (WSABUF*)&buf, + 1, + &bytes, + &flags, + (struct sockaddr*) &from, + &from_len, + NULL, + NULL) != SOCKET_ERROR) { + + /* Message received */ + handle->recv_cb(handle, bytes, &buf, (const struct sockaddr*) &from, 0); + } else { + err = WSAGetLastError(); + if (err == WSAEMSGSIZE) { + /* Message truncated */ + handle->recv_cb(handle, + bytes, + &buf, + (const struct sockaddr*) &from, + UV_UDP_PARTIAL); + } else if (err == WSAEWOULDBLOCK) { + /* Kernel buffer empty */ + handle->recv_cb(handle, 0, &buf, NULL, 0); + } else if (err == WSAECONNRESET || err == WSAENETRESET) { + /* WSAECONNRESET/WSANETRESET is ignored because this just indicates + * that a previous sendto operation failed. + */ + handle->recv_cb(handle, 0, &buf, NULL, 0); + } else { + /* Any other error that we want to report back to the user. */ + uv_udp_recv_stop(handle); + handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0); + } + } + } + +done: + /* Post another read if still reading and not closing. */ + if ((handle->flags & UV_HANDLE_READING) && + !(handle->flags & UV_HANDLE_READ_PENDING)) { + uv_udp_queue_recv(loop, handle); + } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle, + uv_udp_send_t* req) { + int err; + + assert(handle->type == UV_UDP); + + assert(handle->send_queue_size >= req->u.io.queued_bytes); + assert(handle->send_queue_count >= 1); + handle->send_queue_size -= req->u.io.queued_bytes; + handle->send_queue_count--; + + UNREGISTER_HANDLE_REQ(loop, handle, req); + + if (req->cb) { + err = 0; + if (!REQ_SUCCESS(req)) { + err = GET_REQ_SOCK_ERROR(req); + } + req->cb(req, uv_translate_sys_error(err)); + } + + DECREASE_PENDING_REQ_COUNT(handle); +} + + +static int uv__udp_set_membership4(uv_udp_t* handle, + const struct sockaddr_in* multicast_addr, + const char* interface_addr, + uv_membership membership) { + int err; + int optname; + struct ip_mreq mreq; + + if (handle->flags & UV_HANDLE_IPV6) + return UV_EINVAL; + + /* If the socket is unbound, bind to inaddr_any. */ + err = uv_udp_maybe_bind(handle, + (const struct sockaddr*) &uv_addr_ip4_any_, + sizeof(uv_addr_ip4_any_), + UV_UDP_REUSEADDR); + if (err) + return uv_translate_sys_error(err); + + memset(&mreq, 0, sizeof mreq); + + if (interface_addr) { + err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr); + if (err) + return err; + } else { + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + } + + mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr; + + switch (membership) { + case UV_JOIN_GROUP: + optname = IP_ADD_MEMBERSHIP; + break; + case UV_LEAVE_GROUP: + optname = IP_DROP_MEMBERSHIP; + break; + default: + return UV_EINVAL; + } + + if (setsockopt(handle->socket, + IPPROTO_IP, + optname, + (char*) &mreq, + sizeof mreq) == SOCKET_ERROR) { + return uv_translate_sys_error(WSAGetLastError()); + } + + return 0; +} + + +int uv__udp_set_membership6(uv_udp_t* handle, + const struct sockaddr_in6* multicast_addr, + const char* interface_addr, + uv_membership membership) { + int optname; + int err; + struct ipv6_mreq mreq; + struct sockaddr_in6 addr6; + + if ((handle->flags & UV_HANDLE_BOUND) && !(handle->flags & UV_HANDLE_IPV6)) + return UV_EINVAL; + + err = uv_udp_maybe_bind(handle, + (const struct sockaddr*) &uv_addr_ip6_any_, + sizeof(uv_addr_ip6_any_), + UV_UDP_REUSEADDR); + + if (err) + return uv_translate_sys_error(err); + + memset(&mreq, 0, sizeof(mreq)); + + if (interface_addr) { + if (uv_ip6_addr(interface_addr, 0, &addr6)) + return UV_EINVAL; + mreq.ipv6mr_interface = addr6.sin6_scope_id; + } else { + mreq.ipv6mr_interface = 0; + } + + mreq.ipv6mr_multiaddr = multicast_addr->sin6_addr; + + switch (membership) { + case UV_JOIN_GROUP: + optname = IPV6_ADD_MEMBERSHIP; + break; + case UV_LEAVE_GROUP: + optname = IPV6_DROP_MEMBERSHIP; + break; + default: + return UV_EINVAL; + } + + if (setsockopt(handle->socket, + IPPROTO_IPV6, + optname, + (char*) &mreq, + sizeof mreq) == SOCKET_ERROR) { + return uv_translate_sys_error(WSAGetLastError()); + } + + return 0; +} + + +static int uv__udp_set_source_membership4(uv_udp_t* handle, + const struct sockaddr_in* multicast_addr, + const char* interface_addr, + const struct sockaddr_in* source_addr, + uv_membership membership) { + struct ip_mreq_source mreq; + int optname; + int err; + + if (handle->flags & UV_HANDLE_IPV6) + return UV_EINVAL; + + /* If the socket is unbound, bind to inaddr_any. */ + err = uv_udp_maybe_bind(handle, + (const struct sockaddr*) &uv_addr_ip4_any_, + sizeof(uv_addr_ip4_any_), + UV_UDP_REUSEADDR); + if (err) + return uv_translate_sys_error(err); + + memset(&mreq, 0, sizeof(mreq)); + + if (interface_addr != NULL) { + err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr); + if (err) + return err; + } else { + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + } + + mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr; + mreq.imr_sourceaddr.s_addr = source_addr->sin_addr.s_addr; + + if (membership == UV_JOIN_GROUP) + optname = IP_ADD_SOURCE_MEMBERSHIP; + else if (membership == UV_LEAVE_GROUP) + optname = IP_DROP_SOURCE_MEMBERSHIP; + else + return UV_EINVAL; + + if (setsockopt(handle->socket, + IPPROTO_IP, + optname, + (char*) &mreq, + sizeof(mreq)) == SOCKET_ERROR) { + return uv_translate_sys_error(WSAGetLastError()); + } + + return 0; +} + + +int uv__udp_set_source_membership6(uv_udp_t* handle, + const struct sockaddr_in6* multicast_addr, + const char* interface_addr, + const struct sockaddr_in6* source_addr, + uv_membership membership) { + struct group_source_req mreq; + struct sockaddr_in6 addr6; + int optname; + int err; + + STATIC_ASSERT(sizeof(mreq.gsr_group) >= sizeof(*multicast_addr)); + STATIC_ASSERT(sizeof(mreq.gsr_source) >= sizeof(*source_addr)); + + if ((handle->flags & UV_HANDLE_BOUND) && !(handle->flags & UV_HANDLE_IPV6)) + return UV_EINVAL; + + err = uv_udp_maybe_bind(handle, + (const struct sockaddr*) &uv_addr_ip6_any_, + sizeof(uv_addr_ip6_any_), + UV_UDP_REUSEADDR); + + if (err) + return uv_translate_sys_error(err); + + memset(&mreq, 0, sizeof(mreq)); + + if (interface_addr != NULL) { + err = uv_ip6_addr(interface_addr, 0, &addr6); + if (err) + return err; + mreq.gsr_interface = addr6.sin6_scope_id; + } else { + mreq.gsr_interface = 0; + } + + memcpy(&mreq.gsr_group, multicast_addr, sizeof(*multicast_addr)); + memcpy(&mreq.gsr_source, source_addr, sizeof(*source_addr)); + + if (membership == UV_JOIN_GROUP) + optname = MCAST_JOIN_SOURCE_GROUP; + else if (membership == UV_LEAVE_GROUP) + optname = MCAST_LEAVE_SOURCE_GROUP; + else + return UV_EINVAL; + + if (setsockopt(handle->socket, + IPPROTO_IPV6, + optname, + (char*) &mreq, + sizeof(mreq)) == SOCKET_ERROR) { + return uv_translate_sys_error(WSAGetLastError()); + } + + return 0; +} + + +int uv_udp_set_membership(uv_udp_t* handle, + const char* multicast_addr, + const char* interface_addr, + uv_membership membership) { + struct sockaddr_in addr4; + struct sockaddr_in6 addr6; + + if (uv_ip4_addr(multicast_addr, 0, &addr4) == 0) + return uv__udp_set_membership4(handle, &addr4, interface_addr, membership); + else if (uv_ip6_addr(multicast_addr, 0, &addr6) == 0) + return uv__udp_set_membership6(handle, &addr6, interface_addr, membership); + else + return UV_EINVAL; +} + + +int uv_udp_set_source_membership(uv_udp_t* handle, + const char* multicast_addr, + const char* interface_addr, + const char* source_addr, + uv_membership membership) { + int err; + struct sockaddr_storage mcast_addr; + struct sockaddr_in* mcast_addr4; + struct sockaddr_in6* mcast_addr6; + struct sockaddr_storage src_addr; + struct sockaddr_in* src_addr4; + struct sockaddr_in6* src_addr6; + + mcast_addr4 = (struct sockaddr_in*)&mcast_addr; + mcast_addr6 = (struct sockaddr_in6*)&mcast_addr; + src_addr4 = (struct sockaddr_in*)&src_addr; + src_addr6 = (struct sockaddr_in6*)&src_addr; + + err = uv_ip4_addr(multicast_addr, 0, mcast_addr4); + if (err) { + err = uv_ip6_addr(multicast_addr, 0, mcast_addr6); + if (err) + return err; + err = uv_ip6_addr(source_addr, 0, src_addr6); + if (err) + return err; + return uv__udp_set_source_membership6(handle, + mcast_addr6, + interface_addr, + src_addr6, + membership); + } + + err = uv_ip4_addr(source_addr, 0, src_addr4); + if (err) + return err; + return uv__udp_set_source_membership4(handle, + mcast_addr4, + interface_addr, + src_addr4, + membership); +} + + +int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) { + struct sockaddr_storage addr_st; + struct sockaddr_in* addr4; + struct sockaddr_in6* addr6; + + addr4 = (struct sockaddr_in*) &addr_st; + addr6 = (struct sockaddr_in6*) &addr_st; + + if (!interface_addr) { + memset(&addr_st, 0, sizeof addr_st); + if (handle->flags & UV_HANDLE_IPV6) { + addr_st.ss_family = AF_INET6; + addr6->sin6_scope_id = 0; + } else { + addr_st.ss_family = AF_INET; + addr4->sin_addr.s_addr = htonl(INADDR_ANY); + } + } else if (uv_ip4_addr(interface_addr, 0, addr4) == 0) { + /* nothing, address was parsed */ + } else if (uv_ip6_addr(interface_addr, 0, addr6) == 0) { + /* nothing, address was parsed */ + } else { + return UV_EINVAL; + } + + if (handle->socket == INVALID_SOCKET) + return UV_EBADF; + + if (addr_st.ss_family == AF_INET) { + if (setsockopt(handle->socket, + IPPROTO_IP, + IP_MULTICAST_IF, + (char*) &addr4->sin_addr, + sizeof(addr4->sin_addr)) == SOCKET_ERROR) { + return uv_translate_sys_error(WSAGetLastError()); + } + } else if (addr_st.ss_family == AF_INET6) { + if (setsockopt(handle->socket, + IPPROTO_IPV6, + IPV6_MULTICAST_IF, + (char*) &addr6->sin6_scope_id, + sizeof(addr6->sin6_scope_id)) == SOCKET_ERROR) { + return uv_translate_sys_error(WSAGetLastError()); + } + } else { + assert(0 && "unexpected address family"); + abort(); + } + + return 0; +} + + +int uv_udp_set_broadcast(uv_udp_t* handle, int value) { + BOOL optval = (BOOL) value; + + if (handle->socket == INVALID_SOCKET) + return UV_EBADF; + + if (setsockopt(handle->socket, + SOL_SOCKET, + SO_BROADCAST, + (char*) &optval, + sizeof optval)) { + return uv_translate_sys_error(WSAGetLastError()); + } + + return 0; +} + + +int uv__udp_is_bound(uv_udp_t* handle) { + struct sockaddr_storage addr; + int addrlen; + + addrlen = sizeof(addr); + if (uv_udp_getsockname(handle, (struct sockaddr*) &addr, &addrlen) != 0) + return 0; + + return addrlen > 0; +} + + +int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) { + WSAPROTOCOL_INFOW protocol_info; + int opt_len; + int err; + + /* Detect the address family of the socket. */ + opt_len = (int) sizeof protocol_info; + if (getsockopt(sock, + SOL_SOCKET, + SO_PROTOCOL_INFOW, + (char*) &protocol_info, + &opt_len) == SOCKET_ERROR) { + return uv_translate_sys_error(GetLastError()); + } + + err = uv_udp_set_socket(handle->loop, + handle, + sock, + protocol_info.iAddressFamily); + if (err) + return uv_translate_sys_error(err); + + if (uv__udp_is_bound(handle)) + handle->flags |= UV_HANDLE_BOUND; + + if (uv__udp_is_connected(handle)) + handle->flags |= UV_HANDLE_UDP_CONNECTED; + + return 0; +} + + +#define SOCKOPT_SETTER(name, option4, option6, validate) \ + int uv_udp_set_##name(uv_udp_t* handle, int value) { \ + DWORD optval = (DWORD) value; \ + \ + if (!(validate(value))) { \ + return UV_EINVAL; \ + } \ + \ + if (handle->socket == INVALID_SOCKET) \ + return UV_EBADF; \ + \ + if (!(handle->flags & UV_HANDLE_IPV6)) { \ + /* Set IPv4 socket option */ \ + if (setsockopt(handle->socket, \ + IPPROTO_IP, \ + option4, \ + (char*) &optval, \ + sizeof optval)) { \ + return uv_translate_sys_error(WSAGetLastError()); \ + } \ + } else { \ + /* Set IPv6 socket option */ \ + if (setsockopt(handle->socket, \ + IPPROTO_IPV6, \ + option6, \ + (char*) &optval, \ + sizeof optval)) { \ + return uv_translate_sys_error(WSAGetLastError()); \ + } \ + } \ + return 0; \ + } + +#define VALIDATE_TTL(value) ((value) >= 1 && (value) <= 255) +#define VALIDATE_MULTICAST_TTL(value) ((value) >= -1 && (value) <= 255) +#define VALIDATE_MULTICAST_LOOP(value) (1) + +SOCKOPT_SETTER(ttl, + IP_TTL, + IPV6_HOPLIMIT, + VALIDATE_TTL) +SOCKOPT_SETTER(multicast_ttl, + IP_MULTICAST_TTL, + IPV6_MULTICAST_HOPS, + VALIDATE_MULTICAST_TTL) +SOCKOPT_SETTER(multicast_loop, + IP_MULTICAST_LOOP, + IPV6_MULTICAST_LOOP, + VALIDATE_MULTICAST_LOOP) + +#undef SOCKOPT_SETTER +#undef VALIDATE_TTL +#undef VALIDATE_MULTICAST_TTL +#undef VALIDATE_MULTICAST_LOOP + + +/* This function is an egress point, i.e. it returns libuv errors rather than + * system errors. + */ +int uv__udp_bind(uv_udp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen, + unsigned int flags) { + int err; + + err = uv_udp_maybe_bind(handle, addr, addrlen, flags); + if (err) + return uv_translate_sys_error(err); + + return 0; +} + + +int uv__udp_connect(uv_udp_t* handle, + const struct sockaddr* addr, + unsigned int addrlen) { + const struct sockaddr* bind_addr; + int err; + + if (!(handle->flags & UV_HANDLE_BOUND)) { + if (addrlen == sizeof(uv_addr_ip4_any_)) + bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; + else if (addrlen == sizeof(uv_addr_ip6_any_)) + bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; + else + return UV_EINVAL; + + err = uv_udp_maybe_bind(handle, bind_addr, addrlen, 0); + if (err) + return uv_translate_sys_error(err); + } + + err = connect(handle->socket, addr, addrlen); + if (err) + return uv_translate_sys_error(WSAGetLastError()); + + handle->flags |= UV_HANDLE_UDP_CONNECTED; + + return 0; +} + + +int uv__udp_disconnect(uv_udp_t* handle) { + int err; + struct sockaddr addr; + + memset(&addr, 0, sizeof(addr)); + + err = connect(handle->socket, &addr, sizeof(addr)); + if (err) + return uv_translate_sys_error(WSAGetLastError()); + + handle->flags &= ~UV_HANDLE_UDP_CONNECTED; + return 0; +} + + +/* This function is an egress point, i.e. it returns libuv errors rather than + * system errors. + */ +int uv__udp_send(uv_udp_send_t* req, + uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr, + unsigned int addrlen, + uv_udp_send_cb send_cb) { + const struct sockaddr* bind_addr; + int err; + + if (!(handle->flags & UV_HANDLE_BOUND)) { + if (addrlen == sizeof(uv_addr_ip4_any_)) + bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; + else if (addrlen == sizeof(uv_addr_ip6_any_)) + bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; + else + return UV_EINVAL; + + err = uv_udp_maybe_bind(handle, bind_addr, addrlen, 0); + if (err) + return uv_translate_sys_error(err); + } + + err = uv__send(req, handle, bufs, nbufs, addr, addrlen, send_cb); + if (err) + return uv_translate_sys_error(err); + + return 0; +} + + +int uv__udp_try_send(uv_udp_t* handle, + const uv_buf_t bufs[], + unsigned int nbufs, + const struct sockaddr* addr, + unsigned int addrlen) { + DWORD bytes; + const struct sockaddr* bind_addr; + struct sockaddr_storage converted; + int err; + + assert(nbufs > 0); + + if (addr != NULL) { + err = uv__convert_to_localhost_if_unspecified(addr, &converted); + if (err) + return err; + } + + /* Already sending a message.*/ + if (handle->send_queue_count != 0) + return UV_EAGAIN; + + if (!(handle->flags & UV_HANDLE_BOUND)) { + if (addrlen == sizeof(uv_addr_ip4_any_)) + bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; + else if (addrlen == sizeof(uv_addr_ip6_any_)) + bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; + else + return UV_EINVAL; + err = uv_udp_maybe_bind(handle, bind_addr, addrlen, 0); + if (err) + return uv_translate_sys_error(err); + } + + err = WSASendTo(handle->socket, + (WSABUF*)bufs, + nbufs, + &bytes, + 0, + (const struct sockaddr*) &converted, + addrlen, + NULL, + NULL); + + if (err) + return uv_translate_sys_error(WSAGetLastError()); + + return bytes; +} diff --git a/external/src/libuv/src/win/util.c b/external/src/libuv/src/win/util.c new file mode 100644 index 0000000..88602c7 --- /dev/null +++ b/external/src/libuv/src/win/util.c @@ -0,0 +1,1984 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "uv.h" +#include "internal.h" + +/* clang-format off */ +#include +#include +#include +#include +#include +#include +/* clang-format on */ +#include +#include + +/* + * Max title length; the only thing MSDN tells us about the maximum length + * of the console title is that it is smaller than 64K. However in practice + * it is much smaller, and there is no way to figure out what the exact length + * of the title is or can be, at least not on XP. To make it even more + * annoying, GetConsoleTitle fails when the buffer to be read into is bigger + * than the actual maximum length. So we make a conservative guess here; + * just don't put the novel you're writing in the title, unless the plot + * survives truncation. + */ +#define MAX_TITLE_LENGTH 8192 + +/* The number of nanoseconds in one second. */ +#define UV__NANOSEC 1000000000 + +/* Max user name length, from iphlpapi.h */ +#ifndef UNLEN +# define UNLEN 256 +#endif + + +/* A RtlGenRandom() by any other name... */ +extern BOOLEAN NTAPI SystemFunction036(PVOID Buffer, ULONG BufferLength); + +/* Cached copy of the process title, plus a mutex guarding it. */ +static char *process_title; +static CRITICAL_SECTION process_title_lock; + +/* Frequency of the high-resolution clock. */ +static uint64_t hrtime_frequency_ = 0; + + +/* + * One-time initialization code for functionality defined in util.c. + */ +void uv__util_init(void) { + LARGE_INTEGER perf_frequency; + + /* Initialize process title access mutex. */ + InitializeCriticalSection(&process_title_lock); + + /* Retrieve high-resolution timer frequency + * and precompute its reciprocal. + */ + if (QueryPerformanceFrequency(&perf_frequency)) { + hrtime_frequency_ = perf_frequency.QuadPart; + } else { + uv_fatal_error(GetLastError(), "QueryPerformanceFrequency"); + } +} + + +int uv_exepath(char* buffer, size_t* size_ptr) { + int utf8_len, utf16_buffer_len, utf16_len; + WCHAR* utf16_buffer; + int err; + + if (buffer == NULL || size_ptr == NULL || *size_ptr == 0) { + return UV_EINVAL; + } + + if (*size_ptr > 32768) { + /* Windows paths can never be longer than this. */ + utf16_buffer_len = 32768; + } else { + utf16_buffer_len = (int) *size_ptr; + } + + utf16_buffer = (WCHAR*) uv__malloc(sizeof(WCHAR) * utf16_buffer_len); + if (!utf16_buffer) { + return UV_ENOMEM; + } + + /* Get the path as UTF-16. */ + utf16_len = GetModuleFileNameW(NULL, utf16_buffer, utf16_buffer_len); + if (utf16_len <= 0) { + err = GetLastError(); + goto error; + } + + /* utf16_len contains the length, *not* including the terminating null. */ + utf16_buffer[utf16_len] = L'\0'; + + /* Convert to UTF-8 */ + utf8_len = WideCharToMultiByte(CP_UTF8, + 0, + utf16_buffer, + -1, + buffer, + (int) *size_ptr, + NULL, + NULL); + if (utf8_len == 0) { + err = GetLastError(); + goto error; + } + + uv__free(utf16_buffer); + + /* utf8_len *does* include the terminating null at this point, but the + * returned size shouldn't. */ + *size_ptr = utf8_len - 1; + return 0; + + error: + uv__free(utf16_buffer); + return uv_translate_sys_error(err); +} + + +int uv_cwd(char* buffer, size_t* size) { + DWORD utf16_len; + WCHAR *utf16_buffer; + int r; + + if (buffer == NULL || size == NULL) { + return UV_EINVAL; + } + + utf16_len = GetCurrentDirectoryW(0, NULL); + if (utf16_len == 0) { + return uv_translate_sys_error(GetLastError()); + } + utf16_buffer = uv__malloc(utf16_len * sizeof(WCHAR)); + if (utf16_buffer == NULL) { + return UV_ENOMEM; + } + + utf16_len = GetCurrentDirectoryW(utf16_len, utf16_buffer); + if (utf16_len == 0) { + uv__free(utf16_buffer); + return uv_translate_sys_error(GetLastError()); + } + + /* utf16_len contains the length, *not* including the terminating null. */ + utf16_buffer[utf16_len] = L'\0'; + + /* The returned directory should not have a trailing slash, unless it points + * at a drive root, like c:\. Remove it if needed. */ + if (utf16_buffer[utf16_len - 1] == L'\\' && + !(utf16_len == 3 && utf16_buffer[1] == L':')) { + utf16_len--; + utf16_buffer[utf16_len] = L'\0'; + } + + /* Check how much space we need */ + r = WideCharToMultiByte(CP_UTF8, + 0, + utf16_buffer, + -1, + NULL, + 0, + NULL, + NULL); + if (r == 0) { + uv__free(utf16_buffer); + return uv_translate_sys_error(GetLastError()); + } else if (r > (int) *size) { + uv__free(utf16_buffer); + *size = r; + return UV_ENOBUFS; + } + + /* Convert to UTF-8 */ + r = WideCharToMultiByte(CP_UTF8, + 0, + utf16_buffer, + -1, + buffer, + *size > INT_MAX ? INT_MAX : (int) *size, + NULL, + NULL); + uv__free(utf16_buffer); + + if (r == 0) { + return uv_translate_sys_error(GetLastError()); + } + + *size = r - 1; + return 0; +} + + +int uv_chdir(const char* dir) { + WCHAR *utf16_buffer; + size_t utf16_len, new_utf16_len; + WCHAR drive_letter, env_var[4]; + + if (dir == NULL) { + return UV_EINVAL; + } + + utf16_len = MultiByteToWideChar(CP_UTF8, + 0, + dir, + -1, + NULL, + 0); + if (utf16_len == 0) { + return uv_translate_sys_error(GetLastError()); + } + utf16_buffer = uv__malloc(utf16_len * sizeof(WCHAR)); + if (utf16_buffer == NULL) { + return UV_ENOMEM; + } + + if (MultiByteToWideChar(CP_UTF8, + 0, + dir, + -1, + utf16_buffer, + utf16_len) == 0) { + uv__free(utf16_buffer); + return uv_translate_sys_error(GetLastError()); + } + + if (!SetCurrentDirectoryW(utf16_buffer)) { + uv__free(utf16_buffer); + return uv_translate_sys_error(GetLastError()); + } + + /* Windows stores the drive-local path in an "hidden" environment variable, + * which has the form "=C:=C:\Windows". SetCurrentDirectory does not update + * this, so we'll have to do it. */ + new_utf16_len = GetCurrentDirectoryW(utf16_len, utf16_buffer); + if (new_utf16_len > utf16_len ) { + uv__free(utf16_buffer); + utf16_buffer = uv__malloc(new_utf16_len * sizeof(WCHAR)); + if (utf16_buffer == NULL) { + /* When updating the environment variable fails, return UV_OK anyway. + * We did successfully change current working directory, only updating + * hidden env variable failed. */ + return 0; + } + new_utf16_len = GetCurrentDirectoryW(new_utf16_len, utf16_buffer); + } + if (utf16_len == 0) { + uv__free(utf16_buffer); + return 0; + } + + /* The returned directory should not have a trailing slash, unless it points + * at a drive root, like c:\. Remove it if needed. */ + if (utf16_buffer[utf16_len - 1] == L'\\' && + !(utf16_len == 3 && utf16_buffer[1] == L':')) { + utf16_len--; + utf16_buffer[utf16_len] = L'\0'; + } + + if (utf16_len < 2 || utf16_buffer[1] != L':') { + /* Doesn't look like a drive letter could be there - probably an UNC path. + * TODO: Need to handle win32 namespaces like \\?\C:\ ? */ + drive_letter = 0; + } else if (utf16_buffer[0] >= L'A' && utf16_buffer[0] <= L'Z') { + drive_letter = utf16_buffer[0]; + } else if (utf16_buffer[0] >= L'a' && utf16_buffer[0] <= L'z') { + /* Convert to uppercase. */ + drive_letter = utf16_buffer[0] - L'a' + L'A'; + } else { + /* Not valid. */ + drive_letter = 0; + } + + if (drive_letter != 0) { + /* Construct the environment variable name and set it. */ + env_var[0] = L'='; + env_var[1] = drive_letter; + env_var[2] = L':'; + env_var[3] = L'\0'; + + SetEnvironmentVariableW(env_var, utf16_buffer); + } + + uv__free(utf16_buffer); + return 0; +} + + +void uv_loadavg(double avg[3]) { + /* Can't be implemented */ + avg[0] = avg[1] = avg[2] = 0; +} + + +uint64_t uv_get_free_memory(void) { + MEMORYSTATUSEX memory_status; + memory_status.dwLength = sizeof(memory_status); + + if (!GlobalMemoryStatusEx(&memory_status)) { + return -1; + } + + return (uint64_t)memory_status.ullAvailPhys; +} + + +uint64_t uv_get_total_memory(void) { + MEMORYSTATUSEX memory_status; + memory_status.dwLength = sizeof(memory_status); + + if (!GlobalMemoryStatusEx(&memory_status)) { + return -1; + } + + return (uint64_t)memory_status.ullTotalPhys; +} + + +uint64_t uv_get_constrained_memory(void) { + return 0; /* Memory constraints are unknown. */ +} + + +uv_pid_t uv_os_getpid(void) { + return GetCurrentProcessId(); +} + + +uv_pid_t uv_os_getppid(void) { + int parent_pid = -1; + HANDLE handle; + PROCESSENTRY32 pe; + DWORD current_pid = GetCurrentProcessId(); + + pe.dwSize = sizeof(PROCESSENTRY32); + handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + + if (Process32First(handle, &pe)) { + do { + if (pe.th32ProcessID == current_pid) { + parent_pid = pe.th32ParentProcessID; + break; + } + } while( Process32Next(handle, &pe)); + } + + CloseHandle(handle); + return parent_pid; +} + + +char** uv_setup_args(int argc, char** argv) { + return argv; +} + + +void uv__process_title_cleanup(void) { +} + + +int uv_set_process_title(const char* title) { + int err; + int length; + WCHAR* title_w = NULL; + + uv__once_init(); + + /* Find out how big the buffer for the wide-char title must be */ + length = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0); + if (!length) { + err = GetLastError(); + goto done; + } + + /* Convert to wide-char string */ + title_w = (WCHAR*)uv__malloc(sizeof(WCHAR) * length); + if (!title_w) { + uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); + } + + length = MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w, length); + if (!length) { + err = GetLastError(); + goto done; + } + + /* If the title must be truncated insert a \0 terminator there */ + if (length > MAX_TITLE_LENGTH) { + title_w[MAX_TITLE_LENGTH - 1] = L'\0'; + } + + if (!SetConsoleTitleW(title_w)) { + err = GetLastError(); + goto done; + } + + EnterCriticalSection(&process_title_lock); + uv__free(process_title); + process_title = uv__strdup(title); + LeaveCriticalSection(&process_title_lock); + + err = 0; + +done: + uv__free(title_w); + return uv_translate_sys_error(err); +} + + +static int uv__get_process_title(void) { + WCHAR title_w[MAX_TITLE_LENGTH]; + + if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) { + return -1; + } + + if (uv__convert_utf16_to_utf8(title_w, -1, &process_title) != 0) + return -1; + + return 0; +} + + +int uv_get_process_title(char* buffer, size_t size) { + size_t len; + + if (buffer == NULL || size == 0) + return UV_EINVAL; + + uv__once_init(); + + EnterCriticalSection(&process_title_lock); + /* + * If the process_title was never read before nor explicitly set, + * we must query it with getConsoleTitleW + */ + if (!process_title && uv__get_process_title() == -1) { + LeaveCriticalSection(&process_title_lock); + return uv_translate_sys_error(GetLastError()); + } + + assert(process_title); + len = strlen(process_title) + 1; + + if (size < len) { + LeaveCriticalSection(&process_title_lock); + return UV_ENOBUFS; + } + + memcpy(buffer, process_title, len); + LeaveCriticalSection(&process_title_lock); + + return 0; +} + + +uint64_t uv_hrtime(void) { + uv__once_init(); + return uv__hrtime(UV__NANOSEC); +} + +uint64_t uv__hrtime(unsigned int scale) { + LARGE_INTEGER counter; + double scaled_freq; + double result; + + assert(hrtime_frequency_ != 0); + assert(scale != 0); + if (!QueryPerformanceCounter(&counter)) { + uv_fatal_error(GetLastError(), "QueryPerformanceCounter"); + } + assert(counter.QuadPart != 0); + + /* Because we have no guarantee about the order of magnitude of the + * performance counter interval, integer math could cause this computation + * to overflow. Therefore we resort to floating point math. + */ + scaled_freq = (double) hrtime_frequency_ / scale; + result = (double) counter.QuadPart / scaled_freq; + return (uint64_t) result; +} + + +int uv_resident_set_memory(size_t* rss) { + HANDLE current_process; + PROCESS_MEMORY_COUNTERS pmc; + + current_process = GetCurrentProcess(); + + if (!GetProcessMemoryInfo(current_process, &pmc, sizeof(pmc))) { + return uv_translate_sys_error(GetLastError()); + } + + *rss = pmc.WorkingSetSize; + + return 0; +} + + +int uv_uptime(double* uptime) { + BYTE stack_buffer[4096]; + BYTE* malloced_buffer = NULL; + BYTE* buffer = (BYTE*) stack_buffer; + size_t buffer_size = sizeof(stack_buffer); + DWORD data_size; + + PERF_DATA_BLOCK* data_block; + PERF_OBJECT_TYPE* object_type; + PERF_COUNTER_DEFINITION* counter_definition; + + DWORD i; + + for (;;) { + LONG result; + + data_size = (DWORD) buffer_size; + result = RegQueryValueExW(HKEY_PERFORMANCE_DATA, + L"2", + NULL, + NULL, + buffer, + &data_size); + if (result == ERROR_SUCCESS) { + break; + } else if (result != ERROR_MORE_DATA) { + *uptime = 0; + return uv_translate_sys_error(result); + } + + buffer_size *= 2; + /* Don't let the buffer grow infinitely. */ + if (buffer_size > 1 << 20) { + goto internalError; + } + + uv__free(malloced_buffer); + + buffer = malloced_buffer = (BYTE*) uv__malloc(buffer_size); + if (malloced_buffer == NULL) { + *uptime = 0; + return UV_ENOMEM; + } + } + + if (data_size < sizeof(*data_block)) + goto internalError; + + data_block = (PERF_DATA_BLOCK*) buffer; + + if (wmemcmp(data_block->Signature, L"PERF", 4) != 0) + goto internalError; + + if (data_size < data_block->HeaderLength + sizeof(*object_type)) + goto internalError; + + object_type = (PERF_OBJECT_TYPE*) (buffer + data_block->HeaderLength); + + if (object_type->NumInstances != PERF_NO_INSTANCES) + goto internalError; + + counter_definition = (PERF_COUNTER_DEFINITION*) (buffer + + data_block->HeaderLength + object_type->HeaderLength); + for (i = 0; i < object_type->NumCounters; i++) { + if ((BYTE*) counter_definition + sizeof(*counter_definition) > + buffer + data_size) { + break; + } + + if (counter_definition->CounterNameTitleIndex == 674 && + counter_definition->CounterSize == sizeof(uint64_t)) { + if (counter_definition->CounterOffset + sizeof(uint64_t) > data_size || + !(counter_definition->CounterType & PERF_OBJECT_TIMER)) { + goto internalError; + } else { + BYTE* address = (BYTE*) object_type + object_type->DefinitionLength + + counter_definition->CounterOffset; + uint64_t value = *((uint64_t*) address); + *uptime = floor((double) (object_type->PerfTime.QuadPart - value) / + (double) object_type->PerfFreq.QuadPart); + uv__free(malloced_buffer); + return 0; + } + } + + counter_definition = (PERF_COUNTER_DEFINITION*) + ((BYTE*) counter_definition + counter_definition->ByteLength); + } + + /* If we get here, the uptime value was not found. */ + uv__free(malloced_buffer); + *uptime = 0; + return UV_ENOSYS; + + internalError: + uv__free(malloced_buffer); + *uptime = 0; + return UV_EIO; +} + + +int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { + uv_cpu_info_t* cpu_infos; + SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi; + DWORD sppi_size; + SYSTEM_INFO system_info; + DWORD cpu_count, i; + NTSTATUS status; + ULONG result_size; + int err; + uv_cpu_info_t* cpu_info; + + cpu_infos = NULL; + cpu_count = 0; + sppi = NULL; + + uv__once_init(); + + GetSystemInfo(&system_info); + cpu_count = system_info.dwNumberOfProcessors; + + cpu_infos = uv__calloc(cpu_count, sizeof *cpu_infos); + if (cpu_infos == NULL) { + err = ERROR_OUTOFMEMORY; + goto error; + } + + sppi_size = cpu_count * sizeof(*sppi); + sppi = uv__malloc(sppi_size); + if (sppi == NULL) { + err = ERROR_OUTOFMEMORY; + goto error; + } + + status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, + sppi, + sppi_size, + &result_size); + if (!NT_SUCCESS(status)) { + err = pRtlNtStatusToDosError(status); + goto error; + } + + assert(result_size == sppi_size); + + for (i = 0; i < cpu_count; i++) { + WCHAR key_name[128]; + HKEY processor_key; + DWORD cpu_speed; + DWORD cpu_speed_size = sizeof(cpu_speed); + WCHAR cpu_brand[256]; + DWORD cpu_brand_size = sizeof(cpu_brand); + size_t len; + + len = _snwprintf(key_name, + ARRAY_SIZE(key_name), + L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", + i); + + assert(len > 0 && len < ARRAY_SIZE(key_name)); + + err = RegOpenKeyExW(HKEY_LOCAL_MACHINE, + key_name, + 0, + KEY_QUERY_VALUE, + &processor_key); + if (err != ERROR_SUCCESS) { + goto error; + } + + err = RegQueryValueExW(processor_key, + L"~MHz", + NULL, + NULL, + (BYTE*)&cpu_speed, + &cpu_speed_size); + if (err != ERROR_SUCCESS) { + RegCloseKey(processor_key); + goto error; + } + + err = RegQueryValueExW(processor_key, + L"ProcessorNameString", + NULL, + NULL, + (BYTE*)&cpu_brand, + &cpu_brand_size); + RegCloseKey(processor_key); + if (err != ERROR_SUCCESS) + goto error; + + cpu_info = &cpu_infos[i]; + cpu_info->speed = cpu_speed; + cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000; + cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart - + sppi[i].IdleTime.QuadPart) / 10000; + cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000; + cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000; + cpu_info->cpu_times.nice = 0; + + uv__convert_utf16_to_utf8(cpu_brand, + cpu_brand_size / sizeof(WCHAR), + &(cpu_info->model)); + } + + uv__free(sppi); + + *cpu_count_ptr = cpu_count; + *cpu_infos_ptr = cpu_infos; + + return 0; + + error: + if (cpu_infos != NULL) { + /* This is safe because the cpu_infos array is zeroed on allocation. */ + for (i = 0; i < cpu_count; i++) + uv__free(cpu_infos[i].model); + } + + uv__free(cpu_infos); + uv__free(sppi); + + return uv_translate_sys_error(err); +} + + +static int is_windows_version_or_greater(DWORD os_major, + DWORD os_minor, + WORD service_pack_major, + WORD service_pack_minor) { + OSVERSIONINFOEX osvi; + DWORDLONG condition_mask = 0; + int op = VER_GREATER_EQUAL; + + /* Initialize the OSVERSIONINFOEX structure. */ + ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + osvi.dwMajorVersion = os_major; + osvi.dwMinorVersion = os_minor; + osvi.wServicePackMajor = service_pack_major; + osvi.wServicePackMinor = service_pack_minor; + + /* Initialize the condition mask. */ + VER_SET_CONDITION(condition_mask, VER_MAJORVERSION, op); + VER_SET_CONDITION(condition_mask, VER_MINORVERSION, op); + VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMAJOR, op); + VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMINOR, op); + + /* Perform the test. */ + return (int) VerifyVersionInfo( + &osvi, + VER_MAJORVERSION | VER_MINORVERSION | + VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, + condition_mask); +} + + +static int address_prefix_match(int family, + struct sockaddr* address, + struct sockaddr* prefix_address, + int prefix_len) { + uint8_t* address_data; + uint8_t* prefix_address_data; + int i; + + assert(address->sa_family == family); + assert(prefix_address->sa_family == family); + + if (family == AF_INET6) { + address_data = (uint8_t*) &(((struct sockaddr_in6 *) address)->sin6_addr); + prefix_address_data = + (uint8_t*) &(((struct sockaddr_in6 *) prefix_address)->sin6_addr); + } else { + address_data = (uint8_t*) &(((struct sockaddr_in *) address)->sin_addr); + prefix_address_data = + (uint8_t*) &(((struct sockaddr_in *) prefix_address)->sin_addr); + } + + for (i = 0; i < prefix_len >> 3; i++) { + if (address_data[i] != prefix_address_data[i]) + return 0; + } + + if (prefix_len % 8) + return prefix_address_data[i] == + (address_data[i] & (0xff << (8 - prefix_len % 8))); + + return 1; +} + + +int uv_interface_addresses(uv_interface_address_t** addresses_ptr, + int* count_ptr) { + IP_ADAPTER_ADDRESSES* win_address_buf; + ULONG win_address_buf_size; + IP_ADAPTER_ADDRESSES* adapter; + + uv_interface_address_t* uv_address_buf; + char* name_buf; + size_t uv_address_buf_size; + uv_interface_address_t* uv_address; + + int count; + + int is_vista_or_greater; + ULONG flags; + + *addresses_ptr = NULL; + *count_ptr = 0; + + is_vista_or_greater = is_windows_version_or_greater(6, 0, 0, 0); + if (is_vista_or_greater) { + flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | + GAA_FLAG_SKIP_DNS_SERVER; + } else { + /* We need at least XP SP1. */ + if (!is_windows_version_or_greater(5, 1, 1, 0)) + return UV_ENOTSUP; + + flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | + GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_PREFIX; + } + + + /* Fetch the size of the adapters reported by windows, and then get the list + * itself. */ + win_address_buf_size = 0; + win_address_buf = NULL; + + for (;;) { + ULONG r; + + /* If win_address_buf is 0, then GetAdaptersAddresses will fail with. + * ERROR_BUFFER_OVERFLOW, and the required buffer size will be stored in + * win_address_buf_size. */ + r = GetAdaptersAddresses(AF_UNSPEC, + flags, + NULL, + win_address_buf, + &win_address_buf_size); + + if (r == ERROR_SUCCESS) + break; + + uv__free(win_address_buf); + + switch (r) { + case ERROR_BUFFER_OVERFLOW: + /* This happens when win_address_buf is NULL or too small to hold all + * adapters. */ + win_address_buf = uv__malloc(win_address_buf_size); + if (win_address_buf == NULL) + return UV_ENOMEM; + + continue; + + case ERROR_NO_DATA: { + /* No adapters were found. */ + uv_address_buf = uv__malloc(1); + if (uv_address_buf == NULL) + return UV_ENOMEM; + + *count_ptr = 0; + *addresses_ptr = uv_address_buf; + + return 0; + } + + case ERROR_ADDRESS_NOT_ASSOCIATED: + return UV_EAGAIN; + + case ERROR_INVALID_PARAMETER: + /* MSDN says: + * "This error is returned for any of the following conditions: the + * SizePointer parameter is NULL, the Address parameter is not + * AF_INET, AF_INET6, or AF_UNSPEC, or the address information for + * the parameters requested is greater than ULONG_MAX." + * Since the first two conditions are not met, it must be that the + * adapter data is too big. + */ + return UV_ENOBUFS; + + default: + /* Other (unspecified) errors can happen, but we don't have any special + * meaning for them. */ + assert(r != ERROR_SUCCESS); + return uv_translate_sys_error(r); + } + } + + /* Count the number of enabled interfaces and compute how much space is + * needed to store their info. */ + count = 0; + uv_address_buf_size = 0; + + for (adapter = win_address_buf; + adapter != NULL; + adapter = adapter->Next) { + IP_ADAPTER_UNICAST_ADDRESS* unicast_address; + int name_size; + + /* Interfaces that are not 'up' should not be reported. Also skip + * interfaces that have no associated unicast address, as to avoid + * allocating space for the name for this interface. */ + if (adapter->OperStatus != IfOperStatusUp || + adapter->FirstUnicastAddress == NULL) + continue; + + /* Compute the size of the interface name. */ + name_size = WideCharToMultiByte(CP_UTF8, + 0, + adapter->FriendlyName, + -1, + NULL, + 0, + NULL, + FALSE); + if (name_size <= 0) { + uv__free(win_address_buf); + return uv_translate_sys_error(GetLastError()); + } + uv_address_buf_size += name_size; + + /* Count the number of addresses associated with this interface, and + * compute the size. */ + for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*) + adapter->FirstUnicastAddress; + unicast_address != NULL; + unicast_address = unicast_address->Next) { + count++; + uv_address_buf_size += sizeof(uv_interface_address_t); + } + } + + /* Allocate space to store interface data plus adapter names. */ + uv_address_buf = uv__malloc(uv_address_buf_size); + if (uv_address_buf == NULL) { + uv__free(win_address_buf); + return UV_ENOMEM; + } + + /* Compute the start of the uv_interface_address_t array, and the place in + * the buffer where the interface names will be stored. */ + uv_address = uv_address_buf; + name_buf = (char*) (uv_address_buf + count); + + /* Fill out the output buffer. */ + for (adapter = win_address_buf; + adapter != NULL; + adapter = adapter->Next) { + IP_ADAPTER_UNICAST_ADDRESS* unicast_address; + int name_size; + size_t max_name_size; + + if (adapter->OperStatus != IfOperStatusUp || + adapter->FirstUnicastAddress == NULL) + continue; + + /* Convert the interface name to UTF8. */ + max_name_size = (char*) uv_address_buf + uv_address_buf_size - name_buf; + if (max_name_size > (size_t) INT_MAX) + max_name_size = INT_MAX; + name_size = WideCharToMultiByte(CP_UTF8, + 0, + adapter->FriendlyName, + -1, + name_buf, + (int) max_name_size, + NULL, + FALSE); + if (name_size <= 0) { + uv__free(win_address_buf); + uv__free(uv_address_buf); + return uv_translate_sys_error(GetLastError()); + } + + /* Add an uv_interface_address_t element for every unicast address. */ + for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*) + adapter->FirstUnicastAddress; + unicast_address != NULL; + unicast_address = unicast_address->Next) { + struct sockaddr* sa; + ULONG prefix_len; + + sa = unicast_address->Address.lpSockaddr; + + /* XP has no OnLinkPrefixLength field. */ + if (is_vista_or_greater) { + prefix_len = + ((IP_ADAPTER_UNICAST_ADDRESS_LH*) unicast_address)->OnLinkPrefixLength; + } else { + /* Prior to Windows Vista the FirstPrefix pointed to the list with + * single prefix for each IP address assigned to the adapter. + * Order of FirstPrefix does not match order of FirstUnicastAddress, + * so we need to find corresponding prefix. + */ + IP_ADAPTER_PREFIX* prefix; + prefix_len = 0; + + for (prefix = adapter->FirstPrefix; prefix; prefix = prefix->Next) { + /* We want the longest matching prefix. */ + if (prefix->Address.lpSockaddr->sa_family != sa->sa_family || + prefix->PrefixLength <= prefix_len) + continue; + + if (address_prefix_match(sa->sa_family, sa, + prefix->Address.lpSockaddr, prefix->PrefixLength)) { + prefix_len = prefix->PrefixLength; + } + } + + /* If there is no matching prefix information, return a single-host + * subnet mask (e.g. 255.255.255.255 for IPv4). + */ + if (!prefix_len) + prefix_len = (sa->sa_family == AF_INET6) ? 128 : 32; + } + + memset(uv_address, 0, sizeof *uv_address); + + uv_address->name = name_buf; + + if (adapter->PhysicalAddressLength == sizeof(uv_address->phys_addr)) { + memcpy(uv_address->phys_addr, + adapter->PhysicalAddress, + sizeof(uv_address->phys_addr)); + } + + uv_address->is_internal = + (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK); + + if (sa->sa_family == AF_INET6) { + uv_address->address.address6 = *((struct sockaddr_in6 *) sa); + + uv_address->netmask.netmask6.sin6_family = AF_INET6; + memset(uv_address->netmask.netmask6.sin6_addr.s6_addr, 0xff, prefix_len >> 3); + /* This check ensures that we don't write past the size of the data. */ + if (prefix_len % 8) { + uv_address->netmask.netmask6.sin6_addr.s6_addr[prefix_len >> 3] = + 0xff << (8 - prefix_len % 8); + } + + } else { + uv_address->address.address4 = *((struct sockaddr_in *) sa); + + uv_address->netmask.netmask4.sin_family = AF_INET; + uv_address->netmask.netmask4.sin_addr.s_addr = (prefix_len > 0) ? + htonl(0xffffffff << (32 - prefix_len)) : 0; + } + + uv_address++; + } + + name_buf += name_size; + } + + uv__free(win_address_buf); + + *addresses_ptr = uv_address_buf; + *count_ptr = count; + + return 0; +} + + +void uv_free_interface_addresses(uv_interface_address_t* addresses, + int count) { + uv__free(addresses); +} + + +int uv_getrusage(uv_rusage_t *uv_rusage) { + FILETIME createTime, exitTime, kernelTime, userTime; + SYSTEMTIME kernelSystemTime, userSystemTime; + PROCESS_MEMORY_COUNTERS memCounters; + IO_COUNTERS ioCounters; + int ret; + + ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime); + if (ret == 0) { + return uv_translate_sys_error(GetLastError()); + } + + ret = FileTimeToSystemTime(&kernelTime, &kernelSystemTime); + if (ret == 0) { + return uv_translate_sys_error(GetLastError()); + } + + ret = FileTimeToSystemTime(&userTime, &userSystemTime); + if (ret == 0) { + return uv_translate_sys_error(GetLastError()); + } + + ret = GetProcessMemoryInfo(GetCurrentProcess(), + &memCounters, + sizeof(memCounters)); + if (ret == 0) { + return uv_translate_sys_error(GetLastError()); + } + + ret = GetProcessIoCounters(GetCurrentProcess(), &ioCounters); + if (ret == 0) { + return uv_translate_sys_error(GetLastError()); + } + + memset(uv_rusage, 0, sizeof(*uv_rusage)); + + uv_rusage->ru_utime.tv_sec = userSystemTime.wHour * 3600 + + userSystemTime.wMinute * 60 + + userSystemTime.wSecond; + uv_rusage->ru_utime.tv_usec = userSystemTime.wMilliseconds * 1000; + + uv_rusage->ru_stime.tv_sec = kernelSystemTime.wHour * 3600 + + kernelSystemTime.wMinute * 60 + + kernelSystemTime.wSecond; + uv_rusage->ru_stime.tv_usec = kernelSystemTime.wMilliseconds * 1000; + + uv_rusage->ru_majflt = (uint64_t) memCounters.PageFaultCount; + uv_rusage->ru_maxrss = (uint64_t) memCounters.PeakWorkingSetSize / 1024; + + uv_rusage->ru_oublock = (uint64_t) ioCounters.WriteOperationCount; + uv_rusage->ru_inblock = (uint64_t) ioCounters.ReadOperationCount; + + return 0; +} + + +int uv_os_homedir(char* buffer, size_t* size) { + uv_passwd_t pwd; + size_t len; + int r; + + /* Check if the USERPROFILE environment variable is set first. The task of + performing input validation on buffer and size is taken care of by + uv_os_getenv(). */ + r = uv_os_getenv("USERPROFILE", buffer, size); + + /* Don't return an error if USERPROFILE was not found. */ + if (r != UV_ENOENT) + return r; + + /* USERPROFILE is not set, so call uv__getpwuid_r() */ + r = uv__getpwuid_r(&pwd); + + if (r != 0) { + return r; + } + + len = strlen(pwd.homedir); + + if (len >= *size) { + *size = len + 1; + uv_os_free_passwd(&pwd); + return UV_ENOBUFS; + } + + memcpy(buffer, pwd.homedir, len + 1); + *size = len; + uv_os_free_passwd(&pwd); + + return 0; +} + + +int uv_os_tmpdir(char* buffer, size_t* size) { + wchar_t *path; + DWORD bufsize; + size_t len; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + len = 0; + len = GetTempPathW(0, NULL); + if (len == 0) { + return uv_translate_sys_error(GetLastError()); + } + /* Include space for terminating null char. */ + len += 1; + path = uv__malloc(len * sizeof(wchar_t)); + if (path == NULL) { + return UV_ENOMEM; + } + len = GetTempPathW(len, path); + + if (len == 0) { + uv__free(path); + return uv_translate_sys_error(GetLastError()); + } + + /* The returned directory should not have a trailing slash, unless it points + * at a drive root, like c:\. Remove it if needed. */ + if (path[len - 1] == L'\\' && + !(len == 3 && path[1] == L':')) { + len--; + path[len] = L'\0'; + } + + /* Check how much space we need */ + bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL); + + if (bufsize == 0) { + uv__free(path); + return uv_translate_sys_error(GetLastError()); + } else if (bufsize > *size) { + uv__free(path); + *size = bufsize; + return UV_ENOBUFS; + } + + /* Convert to UTF-8 */ + bufsize = WideCharToMultiByte(CP_UTF8, + 0, + path, + -1, + buffer, + *size, + NULL, + NULL); + uv__free(path); + + if (bufsize == 0) + return uv_translate_sys_error(GetLastError()); + + *size = bufsize - 1; + return 0; +} + + +void uv_os_free_passwd(uv_passwd_t* pwd) { + if (pwd == NULL) + return; + + uv__free(pwd->username); + uv__free(pwd->homedir); + pwd->username = NULL; + pwd->homedir = NULL; +} + + +/* + * Converts a UTF-16 string into a UTF-8 one. The resulting string is + * null-terminated. + * + * If utf16 is null terminated, utf16len can be set to -1, otherwise it must + * be specified. + */ +int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8) { + DWORD bufsize; + + if (utf16 == NULL) + return UV_EINVAL; + + /* Check how much space we need */ + bufsize = WideCharToMultiByte(CP_UTF8, + 0, + utf16, + utf16len, + NULL, + 0, + NULL, + NULL); + + if (bufsize == 0) + return uv_translate_sys_error(GetLastError()); + + /* Allocate the destination buffer adding an extra byte for the terminating + * NULL. If utf16len is not -1 WideCharToMultiByte will not add it, so + * we do it ourselves always, just in case. */ + *utf8 = uv__malloc(bufsize + 1); + + if (*utf8 == NULL) + return UV_ENOMEM; + + /* Convert to UTF-8 */ + bufsize = WideCharToMultiByte(CP_UTF8, + 0, + utf16, + utf16len, + *utf8, + bufsize, + NULL, + NULL); + + if (bufsize == 0) { + uv__free(*utf8); + *utf8 = NULL; + return uv_translate_sys_error(GetLastError()); + } + + (*utf8)[bufsize] = '\0'; + return 0; +} + + +/* + * Converts a UTF-8 string into a UTF-16 one. The resulting string is + * null-terminated. + * + * If utf8 is null terminated, utf8len can be set to -1, otherwise it must + * be specified. + */ +int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16) { + int bufsize; + + if (utf8 == NULL) + return UV_EINVAL; + + /* Check how much space we need */ + bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, NULL, 0); + + if (bufsize == 0) + return uv_translate_sys_error(GetLastError()); + + /* Allocate the destination buffer adding an extra byte for the terminating + * NULL. If utf8len is not -1 MultiByteToWideChar will not add it, so + * we do it ourselves always, just in case. */ + *utf16 = uv__malloc(sizeof(WCHAR) * (bufsize + 1)); + + if (*utf16 == NULL) + return UV_ENOMEM; + + /* Convert to UTF-16 */ + bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, *utf16, bufsize); + + if (bufsize == 0) { + uv__free(*utf16); + *utf16 = NULL; + return uv_translate_sys_error(GetLastError()); + } + + (*utf16)[bufsize] = L'\0'; + return 0; +} + + +int uv__getpwuid_r(uv_passwd_t* pwd) { + HANDLE token; + wchar_t username[UNLEN + 1]; + wchar_t *path; + DWORD bufsize; + int r; + + if (pwd == NULL) + return UV_EINVAL; + + /* Get the home directory using GetUserProfileDirectoryW() */ + if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0) + return uv_translate_sys_error(GetLastError()); + + bufsize = 0; + GetUserProfileDirectoryW(token, NULL, &bufsize); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + r = GetLastError(); + CloseHandle(token); + return uv_translate_sys_error(r); + } + + path = uv__malloc(bufsize * sizeof(wchar_t)); + if (path == NULL) { + CloseHandle(token); + return UV_ENOMEM; + } + + if (!GetUserProfileDirectoryW(token, path, &bufsize)) { + r = GetLastError(); + CloseHandle(token); + uv__free(path); + return uv_translate_sys_error(r); + } + + CloseHandle(token); + + /* Get the username using GetUserNameW() */ + bufsize = ARRAY_SIZE(username); + if (!GetUserNameW(username, &bufsize)) { + r = GetLastError(); + uv__free(path); + + /* This should not be possible */ + if (r == ERROR_INSUFFICIENT_BUFFER) + return UV_ENOMEM; + + return uv_translate_sys_error(r); + } + + pwd->homedir = NULL; + r = uv__convert_utf16_to_utf8(path, -1, &pwd->homedir); + uv__free(path); + + if (r != 0) + return r; + + pwd->username = NULL; + r = uv__convert_utf16_to_utf8(username, -1, &pwd->username); + + if (r != 0) { + uv__free(pwd->homedir); + return r; + } + + pwd->shell = NULL; + pwd->uid = -1; + pwd->gid = -1; + + return 0; +} + + +int uv_os_get_passwd(uv_passwd_t* pwd) { + return uv__getpwuid_r(pwd); +} + + +int uv_os_environ(uv_env_item_t** envitems, int* count) { + wchar_t* env; + wchar_t* penv; + int i, cnt; + uv_env_item_t* envitem; + + *envitems = NULL; + *count = 0; + + env = GetEnvironmentStringsW(); + if (env == NULL) + return 0; + + for (penv = env, i = 0; *penv != L'\0'; penv += wcslen(penv) + 1, i++); + + *envitems = uv__calloc(i, sizeof(**envitems)); + if (*envitems == NULL) { + FreeEnvironmentStringsW(env); + return UV_ENOMEM; + } + + penv = env; + cnt = 0; + + while (*penv != L'\0' && cnt < i) { + char* buf; + char* ptr; + + if (uv__convert_utf16_to_utf8(penv, -1, &buf) != 0) + goto fail; + + /* Using buf + 1 here because we know that `buf` has length at least 1, + * and some special environment variables on Windows start with a = sign. */ + ptr = strchr(buf + 1, '='); + if (ptr == NULL) { + uv__free(buf); + goto do_continue; + } + + *ptr = '\0'; + + envitem = &(*envitems)[cnt]; + envitem->name = buf; + envitem->value = ptr + 1; + + cnt++; + + do_continue: + penv += wcslen(penv) + 1; + } + + FreeEnvironmentStringsW(env); + + *count = cnt; + return 0; + +fail: + FreeEnvironmentStringsW(env); + + for (i = 0; i < cnt; i++) { + envitem = &(*envitems)[cnt]; + uv__free(envitem->name); + } + uv__free(*envitems); + + *envitems = NULL; + *count = 0; + return UV_ENOMEM; +} + + +int uv_os_getenv(const char* name, char* buffer, size_t* size) { + wchar_t fastvar[512]; + wchar_t* var; + DWORD varlen; + wchar_t* name_w; + DWORD bufsize; + size_t len; + int r; + + if (name == NULL || buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + r = uv__convert_utf8_to_utf16(name, -1, &name_w); + + if (r != 0) + return r; + + var = fastvar; + varlen = ARRAY_SIZE(fastvar); + + for (;;) { + SetLastError(ERROR_SUCCESS); + len = GetEnvironmentVariableW(name_w, var, varlen); + + if (len < varlen) + break; + + /* Try repeatedly because we might have been preempted by another thread + * modifying the environment variable just as we're trying to read it. + */ + if (var != fastvar) + uv__free(var); + + varlen = 1 + len; + var = uv__malloc(varlen * sizeof(*var)); + + if (var == NULL) { + r = UV_ENOMEM; + goto fail; + } + } + + uv__free(name_w); + name_w = NULL; + + if (len == 0) { + r = GetLastError(); + if (r != ERROR_SUCCESS) { + r = uv_translate_sys_error(r); + goto fail; + } + } + + /* Check how much space we need */ + bufsize = WideCharToMultiByte(CP_UTF8, 0, var, -1, NULL, 0, NULL, NULL); + + if (bufsize == 0) { + r = uv_translate_sys_error(GetLastError()); + goto fail; + } else if (bufsize > *size) { + *size = bufsize; + r = UV_ENOBUFS; + goto fail; + } + + /* Convert to UTF-8 */ + bufsize = WideCharToMultiByte(CP_UTF8, + 0, + var, + -1, + buffer, + *size, + NULL, + NULL); + + if (bufsize == 0) { + r = uv_translate_sys_error(GetLastError()); + goto fail; + } + + *size = bufsize - 1; + r = 0; + +fail: + + if (name_w != NULL) + uv__free(name_w); + + if (var != fastvar) + uv__free(var); + + return r; +} + + +int uv_os_setenv(const char* name, const char* value) { + wchar_t* name_w; + wchar_t* value_w; + int r; + + if (name == NULL || value == NULL) + return UV_EINVAL; + + r = uv__convert_utf8_to_utf16(name, -1, &name_w); + + if (r != 0) + return r; + + r = uv__convert_utf8_to_utf16(value, -1, &value_w); + + if (r != 0) { + uv__free(name_w); + return r; + } + + r = SetEnvironmentVariableW(name_w, value_w); + uv__free(name_w); + uv__free(value_w); + + if (r == 0) + return uv_translate_sys_error(GetLastError()); + + return 0; +} + + +int uv_os_unsetenv(const char* name) { + wchar_t* name_w; + int r; + + if (name == NULL) + return UV_EINVAL; + + r = uv__convert_utf8_to_utf16(name, -1, &name_w); + + if (r != 0) + return r; + + r = SetEnvironmentVariableW(name_w, NULL); + uv__free(name_w); + + if (r == 0) + return uv_translate_sys_error(GetLastError()); + + return 0; +} + + +int uv_os_gethostname(char* buffer, size_t* size) { + WCHAR buf[UV_MAXHOSTNAMESIZE]; + size_t len; + char* utf8_str; + int convert_result; + + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + uv__once_init(); /* Initialize winsock */ + + if (GetHostNameW(buf, UV_MAXHOSTNAMESIZE) != 0) + return uv_translate_sys_error(WSAGetLastError()); + + convert_result = uv__convert_utf16_to_utf8(buf, -1, &utf8_str); + + if (convert_result != 0) + return convert_result; + + len = strlen(utf8_str); + if (len >= *size) { + *size = len + 1; + uv__free(utf8_str); + return UV_ENOBUFS; + } + + memcpy(buffer, utf8_str, len + 1); + uv__free(utf8_str); + *size = len; + return 0; +} + + +static int uv__get_handle(uv_pid_t pid, int access, HANDLE* handle) { + int r; + + if (pid == 0) + *handle = GetCurrentProcess(); + else + *handle = OpenProcess(access, FALSE, pid); + + if (*handle == NULL) { + r = GetLastError(); + + if (r == ERROR_INVALID_PARAMETER) + return UV_ESRCH; + else + return uv_translate_sys_error(r); + } + + return 0; +} + + +int uv_os_getpriority(uv_pid_t pid, int* priority) { + HANDLE handle; + int r; + + if (priority == NULL) + return UV_EINVAL; + + r = uv__get_handle(pid, PROCESS_QUERY_LIMITED_INFORMATION, &handle); + + if (r != 0) + return r; + + r = GetPriorityClass(handle); + + if (r == 0) { + r = uv_translate_sys_error(GetLastError()); + } else { + /* Map Windows priority classes to Unix nice values. */ + if (r == REALTIME_PRIORITY_CLASS) + *priority = UV_PRIORITY_HIGHEST; + else if (r == HIGH_PRIORITY_CLASS) + *priority = UV_PRIORITY_HIGH; + else if (r == ABOVE_NORMAL_PRIORITY_CLASS) + *priority = UV_PRIORITY_ABOVE_NORMAL; + else if (r == NORMAL_PRIORITY_CLASS) + *priority = UV_PRIORITY_NORMAL; + else if (r == BELOW_NORMAL_PRIORITY_CLASS) + *priority = UV_PRIORITY_BELOW_NORMAL; + else /* IDLE_PRIORITY_CLASS */ + *priority = UV_PRIORITY_LOW; + + r = 0; + } + + CloseHandle(handle); + return r; +} + + +int uv_os_setpriority(uv_pid_t pid, int priority) { + HANDLE handle; + int priority_class; + int r; + + /* Map Unix nice values to Windows priority classes. */ + if (priority < UV_PRIORITY_HIGHEST || priority > UV_PRIORITY_LOW) + return UV_EINVAL; + else if (priority < UV_PRIORITY_HIGH) + priority_class = REALTIME_PRIORITY_CLASS; + else if (priority < UV_PRIORITY_ABOVE_NORMAL) + priority_class = HIGH_PRIORITY_CLASS; + else if (priority < UV_PRIORITY_NORMAL) + priority_class = ABOVE_NORMAL_PRIORITY_CLASS; + else if (priority < UV_PRIORITY_BELOW_NORMAL) + priority_class = NORMAL_PRIORITY_CLASS; + else if (priority < UV_PRIORITY_LOW) + priority_class = BELOW_NORMAL_PRIORITY_CLASS; + else + priority_class = IDLE_PRIORITY_CLASS; + + r = uv__get_handle(pid, PROCESS_SET_INFORMATION, &handle); + + if (r != 0) + return r; + + if (SetPriorityClass(handle, priority_class) == 0) + r = uv_translate_sys_error(GetLastError()); + + CloseHandle(handle); + return r; +} + + +int uv_os_uname(uv_utsname_t* buffer) { + /* Implementation loosely based on + https://github.com/gagern/gnulib/blob/master/lib/uname.c */ + OSVERSIONINFOW os_info; + SYSTEM_INFO system_info; + HKEY registry_key; + WCHAR product_name_w[256]; + DWORD product_name_w_size; + int version_size; + int processor_level; + int r; + + if (buffer == NULL) + return UV_EINVAL; + + uv__once_init(); + os_info.dwOSVersionInfoSize = sizeof(os_info); + os_info.szCSDVersion[0] = L'\0'; + + /* Try calling RtlGetVersion(), and fall back to the deprecated GetVersionEx() + if RtlGetVersion() is not available. */ + if (pRtlGetVersion) { + pRtlGetVersion(&os_info); + } else { + /* Silence GetVersionEx() deprecation warning. */ + #ifdef _MSC_VER + #pragma warning(suppress : 4996) + #endif + if (GetVersionExW(&os_info) == 0) { + r = uv_translate_sys_error(GetLastError()); + goto error; + } + } + + /* Populate the version field. */ + version_size = 0; + r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, + L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", + 0, + KEY_QUERY_VALUE, + ®istry_key); + + if (r == ERROR_SUCCESS) { + product_name_w_size = sizeof(product_name_w); + r = RegGetValueW(registry_key, + NULL, + L"ProductName", + RRF_RT_REG_SZ, + NULL, + (PVOID) product_name_w, + &product_name_w_size); + RegCloseKey(registry_key); + + if (r == ERROR_SUCCESS) { + version_size = WideCharToMultiByte(CP_UTF8, + 0, + product_name_w, + -1, + buffer->version, + sizeof(buffer->version), + NULL, + NULL); + if (version_size == 0) { + r = uv_translate_sys_error(GetLastError()); + goto error; + } + } + } + + /* Append service pack information to the version if present. */ + if (os_info.szCSDVersion[0] != L'\0') { + if (version_size > 0) + buffer->version[version_size - 1] = ' '; + + if (WideCharToMultiByte(CP_UTF8, + 0, + os_info.szCSDVersion, + -1, + buffer->version + version_size, + sizeof(buffer->version) - version_size, + NULL, + NULL) == 0) { + r = uv_translate_sys_error(GetLastError()); + goto error; + } + } + + /* Populate the sysname field. */ +#ifdef __MINGW32__ + r = snprintf(buffer->sysname, + sizeof(buffer->sysname), + "MINGW32_NT-%u.%u", + (unsigned int) os_info.dwMajorVersion, + (unsigned int) os_info.dwMinorVersion); + assert((size_t)r < sizeof(buffer->sysname)); +#else + uv__strscpy(buffer->sysname, "Windows_NT", sizeof(buffer->sysname)); +#endif + + /* Populate the release field. */ + r = snprintf(buffer->release, + sizeof(buffer->release), + "%d.%d.%d", + (unsigned int) os_info.dwMajorVersion, + (unsigned int) os_info.dwMinorVersion, + (unsigned int) os_info.dwBuildNumber); + assert((size_t)r < sizeof(buffer->release)); + + /* Populate the machine field. */ + GetSystemInfo(&system_info); + + switch (system_info.wProcessorArchitecture) { + case PROCESSOR_ARCHITECTURE_AMD64: + uv__strscpy(buffer->machine, "x86_64", sizeof(buffer->machine)); + break; + case PROCESSOR_ARCHITECTURE_IA64: + uv__strscpy(buffer->machine, "ia64", sizeof(buffer->machine)); + break; + case PROCESSOR_ARCHITECTURE_INTEL: + uv__strscpy(buffer->machine, "i386", sizeof(buffer->machine)); + + if (system_info.wProcessorLevel > 3) { + processor_level = system_info.wProcessorLevel < 6 ? + system_info.wProcessorLevel : 6; + buffer->machine[1] = '0' + processor_level; + } + + break; + case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64: + uv__strscpy(buffer->machine, "i686", sizeof(buffer->machine)); + break; + case PROCESSOR_ARCHITECTURE_MIPS: + uv__strscpy(buffer->machine, "mips", sizeof(buffer->machine)); + break; + case PROCESSOR_ARCHITECTURE_ALPHA: + case PROCESSOR_ARCHITECTURE_ALPHA64: + uv__strscpy(buffer->machine, "alpha", sizeof(buffer->machine)); + break; + case PROCESSOR_ARCHITECTURE_PPC: + uv__strscpy(buffer->machine, "powerpc", sizeof(buffer->machine)); + break; + case PROCESSOR_ARCHITECTURE_SHX: + uv__strscpy(buffer->machine, "sh", sizeof(buffer->machine)); + break; + case PROCESSOR_ARCHITECTURE_ARM: + uv__strscpy(buffer->machine, "arm", sizeof(buffer->machine)); + break; + default: + uv__strscpy(buffer->machine, "unknown", sizeof(buffer->machine)); + break; + } + + return 0; + +error: + buffer->sysname[0] = '\0'; + buffer->release[0] = '\0'; + buffer->version[0] = '\0'; + buffer->machine[0] = '\0'; + return r; +} + +int uv_gettimeofday(uv_timeval64_t* tv) { + /* Based on https://doxygen.postgresql.org/gettimeofday_8c_source.html */ + const uint64_t epoch = (uint64_t) 116444736000000000ULL; + FILETIME file_time; + ULARGE_INTEGER ularge; + + if (tv == NULL) + return UV_EINVAL; + + GetSystemTimeAsFileTime(&file_time); + ularge.LowPart = file_time.dwLowDateTime; + ularge.HighPart = file_time.dwHighDateTime; + tv->tv_sec = (int64_t) ((ularge.QuadPart - epoch) / 10000000L); + tv->tv_usec = (int32_t) (((ularge.QuadPart - epoch) % 10000000L) / 10); + return 0; +} + +int uv__random_rtlgenrandom(void* buf, size_t buflen) { + if (buflen == 0) + return 0; + + if (SystemFunction036(buf, buflen) == FALSE) + return UV_EIO; + + return 0; +} + +void uv_sleep(unsigned int msec) { + Sleep(msec); +} diff --git a/external/src/libuv/src/win/winapi.c b/external/src/libuv/src/win/winapi.c new file mode 100644 index 0000000..bb86ec8 --- /dev/null +++ b/external/src/libuv/src/win/winapi.c @@ -0,0 +1,137 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include + +#include "uv.h" +#include "internal.h" + + +/* Ntdll function pointers */ +sRtlGetVersion pRtlGetVersion; +sRtlNtStatusToDosError pRtlNtStatusToDosError; +sNtDeviceIoControlFile pNtDeviceIoControlFile; +sNtQueryInformationFile pNtQueryInformationFile; +sNtSetInformationFile pNtSetInformationFile; +sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile; +sNtQueryDirectoryFile pNtQueryDirectoryFile; +sNtQuerySystemInformation pNtQuerySystemInformation; +sNtQueryInformationProcess pNtQueryInformationProcess; + +/* Kernel32 function pointers */ +sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx; + +/* Powrprof.dll function pointer */ +sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification; + +/* User32.dll function pointer */ +sSetWinEventHook pSetWinEventHook; + + +void uv_winapi_init(void) { + HMODULE ntdll_module; + HMODULE powrprof_module; + HMODULE user32_module; + HMODULE kernel32_module; + + ntdll_module = GetModuleHandleA("ntdll.dll"); + if (ntdll_module == NULL) { + uv_fatal_error(GetLastError(), "GetModuleHandleA"); + } + + pRtlGetVersion = (sRtlGetVersion) GetProcAddress(ntdll_module, + "RtlGetVersion"); + + pRtlNtStatusToDosError = (sRtlNtStatusToDosError) GetProcAddress( + ntdll_module, + "RtlNtStatusToDosError"); + if (pRtlNtStatusToDosError == NULL) { + uv_fatal_error(GetLastError(), "GetProcAddress"); + } + + pNtDeviceIoControlFile = (sNtDeviceIoControlFile) GetProcAddress( + ntdll_module, + "NtDeviceIoControlFile"); + if (pNtDeviceIoControlFile == NULL) { + uv_fatal_error(GetLastError(), "GetProcAddress"); + } + + pNtQueryInformationFile = (sNtQueryInformationFile) GetProcAddress( + ntdll_module, + "NtQueryInformationFile"); + if (pNtQueryInformationFile == NULL) { + uv_fatal_error(GetLastError(), "GetProcAddress"); + } + + pNtSetInformationFile = (sNtSetInformationFile) GetProcAddress( + ntdll_module, + "NtSetInformationFile"); + if (pNtSetInformationFile == NULL) { + uv_fatal_error(GetLastError(), "GetProcAddress"); + } + + pNtQueryVolumeInformationFile = (sNtQueryVolumeInformationFile) + GetProcAddress(ntdll_module, "NtQueryVolumeInformationFile"); + if (pNtQueryVolumeInformationFile == NULL) { + uv_fatal_error(GetLastError(), "GetProcAddress"); + } + + pNtQueryDirectoryFile = (sNtQueryDirectoryFile) + GetProcAddress(ntdll_module, "NtQueryDirectoryFile"); + if (pNtQueryVolumeInformationFile == NULL) { + uv_fatal_error(GetLastError(), "GetProcAddress"); + } + + pNtQuerySystemInformation = (sNtQuerySystemInformation) GetProcAddress( + ntdll_module, + "NtQuerySystemInformation"); + if (pNtQuerySystemInformation == NULL) { + uv_fatal_error(GetLastError(), "GetProcAddress"); + } + + pNtQueryInformationProcess = (sNtQueryInformationProcess) GetProcAddress( + ntdll_module, + "NtQueryInformationProcess"); + if (pNtQueryInformationProcess == NULL) { + uv_fatal_error(GetLastError(), "GetProcAddress"); + } + + kernel32_module = GetModuleHandleA("kernel32.dll"); + if (kernel32_module == NULL) { + uv_fatal_error(GetLastError(), "GetModuleHandleA"); + } + + pGetQueuedCompletionStatusEx = (sGetQueuedCompletionStatusEx) GetProcAddress( + kernel32_module, + "GetQueuedCompletionStatusEx"); + + powrprof_module = LoadLibraryA("powrprof.dll"); + if (powrprof_module != NULL) { + pPowerRegisterSuspendResumeNotification = (sPowerRegisterSuspendResumeNotification) + GetProcAddress(powrprof_module, "PowerRegisterSuspendResumeNotification"); + } + + user32_module = LoadLibraryA("user32.dll"); + if (user32_module != NULL) { + pSetWinEventHook = (sSetWinEventHook) + GetProcAddress(user32_module, "SetWinEventHook"); + } +} diff --git a/external/src/libuv/src/win/winapi.h b/external/src/libuv/src/win/winapi.h new file mode 100644 index 0000000..0b66b56 --- /dev/null +++ b/external/src/libuv/src/win/winapi.h @@ -0,0 +1,4762 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_WIN_WINAPI_H_ +#define UV_WIN_WINAPI_H_ + +#include + + +/* + * Ntdll headers + */ +#ifndef STATUS_SEVERITY_SUCCESS +# define STATUS_SEVERITY_SUCCESS 0x0 +#endif + +#ifndef STATUS_SEVERITY_INFORMATIONAL +# define STATUS_SEVERITY_INFORMATIONAL 0x1 +#endif + +#ifndef STATUS_SEVERITY_WARNING +# define STATUS_SEVERITY_WARNING 0x2 +#endif + +#ifndef STATUS_SEVERITY_ERROR +# define STATUS_SEVERITY_ERROR 0x3 +#endif + +#ifndef FACILITY_NTWIN32 +# define FACILITY_NTWIN32 0x7 +#endif + +#ifndef NT_SUCCESS +# define NT_SUCCESS(status) (((NTSTATUS) (status)) >= 0) +#endif + +#ifndef NT_INFORMATION +# define NT_INFORMATION(status) ((((ULONG) (status)) >> 30) == 1) +#endif + +#ifndef NT_WARNING +# define NT_WARNING(status) ((((ULONG) (status)) >> 30) == 2) +#endif + +#ifndef NT_ERROR +# define NT_ERROR(status) ((((ULONG) (status)) >> 30) == 3) +#endif + +#ifndef STATUS_SUCCESS +# define STATUS_SUCCESS ((NTSTATUS) 0x00000000L) +#endif + +#ifndef STATUS_WAIT_0 +# define STATUS_WAIT_0 ((NTSTATUS) 0x00000000L) +#endif + +#ifndef STATUS_WAIT_1 +# define STATUS_WAIT_1 ((NTSTATUS) 0x00000001L) +#endif + +#ifndef STATUS_WAIT_2 +# define STATUS_WAIT_2 ((NTSTATUS) 0x00000002L) +#endif + +#ifndef STATUS_WAIT_3 +# define STATUS_WAIT_3 ((NTSTATUS) 0x00000003L) +#endif + +#ifndef STATUS_WAIT_63 +# define STATUS_WAIT_63 ((NTSTATUS) 0x0000003FL) +#endif + +#ifndef STATUS_ABANDONED +# define STATUS_ABANDONED ((NTSTATUS) 0x00000080L) +#endif + +#ifndef STATUS_ABANDONED_WAIT_0 +# define STATUS_ABANDONED_WAIT_0 ((NTSTATUS) 0x00000080L) +#endif + +#ifndef STATUS_ABANDONED_WAIT_63 +# define STATUS_ABANDONED_WAIT_63 ((NTSTATUS) 0x000000BFL) +#endif + +#ifndef STATUS_USER_APC +# define STATUS_USER_APC ((NTSTATUS) 0x000000C0L) +#endif + +#ifndef STATUS_KERNEL_APC +# define STATUS_KERNEL_APC ((NTSTATUS) 0x00000100L) +#endif + +#ifndef STATUS_ALERTED +# define STATUS_ALERTED ((NTSTATUS) 0x00000101L) +#endif + +#ifndef STATUS_TIMEOUT +# define STATUS_TIMEOUT ((NTSTATUS) 0x00000102L) +#endif + +#ifndef STATUS_PENDING +# define STATUS_PENDING ((NTSTATUS) 0x00000103L) +#endif + +#ifndef STATUS_REPARSE +# define STATUS_REPARSE ((NTSTATUS) 0x00000104L) +#endif + +#ifndef STATUS_MORE_ENTRIES +# define STATUS_MORE_ENTRIES ((NTSTATUS) 0x00000105L) +#endif + +#ifndef STATUS_NOT_ALL_ASSIGNED +# define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS) 0x00000106L) +#endif + +#ifndef STATUS_SOME_NOT_MAPPED +# define STATUS_SOME_NOT_MAPPED ((NTSTATUS) 0x00000107L) +#endif + +#ifndef STATUS_OPLOCK_BREAK_IN_PROGRESS +# define STATUS_OPLOCK_BREAK_IN_PROGRESS ((NTSTATUS) 0x00000108L) +#endif + +#ifndef STATUS_VOLUME_MOUNTED +# define STATUS_VOLUME_MOUNTED ((NTSTATUS) 0x00000109L) +#endif + +#ifndef STATUS_RXACT_COMMITTED +# define STATUS_RXACT_COMMITTED ((NTSTATUS) 0x0000010AL) +#endif + +#ifndef STATUS_NOTIFY_CLEANUP +# define STATUS_NOTIFY_CLEANUP ((NTSTATUS) 0x0000010BL) +#endif + +#ifndef STATUS_NOTIFY_ENUM_DIR +# define STATUS_NOTIFY_ENUM_DIR ((NTSTATUS) 0x0000010CL) +#endif + +#ifndef STATUS_NO_QUOTAS_FOR_ACCOUNT +# define STATUS_NO_QUOTAS_FOR_ACCOUNT ((NTSTATUS) 0x0000010DL) +#endif + +#ifndef STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED +# define STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED ((NTSTATUS) 0x0000010EL) +#endif + +#ifndef STATUS_PAGE_FAULT_TRANSITION +# define STATUS_PAGE_FAULT_TRANSITION ((NTSTATUS) 0x00000110L) +#endif + +#ifndef STATUS_PAGE_FAULT_DEMAND_ZERO +# define STATUS_PAGE_FAULT_DEMAND_ZERO ((NTSTATUS) 0x00000111L) +#endif + +#ifndef STATUS_PAGE_FAULT_COPY_ON_WRITE +# define STATUS_PAGE_FAULT_COPY_ON_WRITE ((NTSTATUS) 0x00000112L) +#endif + +#ifndef STATUS_PAGE_FAULT_GUARD_PAGE +# define STATUS_PAGE_FAULT_GUARD_PAGE ((NTSTATUS) 0x00000113L) +#endif + +#ifndef STATUS_PAGE_FAULT_PAGING_FILE +# define STATUS_PAGE_FAULT_PAGING_FILE ((NTSTATUS) 0x00000114L) +#endif + +#ifndef STATUS_CACHE_PAGE_LOCKED +# define STATUS_CACHE_PAGE_LOCKED ((NTSTATUS) 0x00000115L) +#endif + +#ifndef STATUS_CRASH_DUMP +# define STATUS_CRASH_DUMP ((NTSTATUS) 0x00000116L) +#endif + +#ifndef STATUS_BUFFER_ALL_ZEROS +# define STATUS_BUFFER_ALL_ZEROS ((NTSTATUS) 0x00000117L) +#endif + +#ifndef STATUS_REPARSE_OBJECT +# define STATUS_REPARSE_OBJECT ((NTSTATUS) 0x00000118L) +#endif + +#ifndef STATUS_RESOURCE_REQUIREMENTS_CHANGED +# define STATUS_RESOURCE_REQUIREMENTS_CHANGED ((NTSTATUS) 0x00000119L) +#endif + +#ifndef STATUS_TRANSLATION_COMPLETE +# define STATUS_TRANSLATION_COMPLETE ((NTSTATUS) 0x00000120L) +#endif + +#ifndef STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY +# define STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY ((NTSTATUS) 0x00000121L) +#endif + +#ifndef STATUS_NOTHING_TO_TERMINATE +# define STATUS_NOTHING_TO_TERMINATE ((NTSTATUS) 0x00000122L) +#endif + +#ifndef STATUS_PROCESS_NOT_IN_JOB +# define STATUS_PROCESS_NOT_IN_JOB ((NTSTATUS) 0x00000123L) +#endif + +#ifndef STATUS_PROCESS_IN_JOB +# define STATUS_PROCESS_IN_JOB ((NTSTATUS) 0x00000124L) +#endif + +#ifndef STATUS_VOLSNAP_HIBERNATE_READY +# define STATUS_VOLSNAP_HIBERNATE_READY ((NTSTATUS) 0x00000125L) +#endif + +#ifndef STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY +# define STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY ((NTSTATUS) 0x00000126L) +#endif + +#ifndef STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED +# define STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED ((NTSTATUS) 0x00000127L) +#endif + +#ifndef STATUS_INTERRUPT_STILL_CONNECTED +# define STATUS_INTERRUPT_STILL_CONNECTED ((NTSTATUS) 0x00000128L) +#endif + +#ifndef STATUS_PROCESS_CLONED +# define STATUS_PROCESS_CLONED ((NTSTATUS) 0x00000129L) +#endif + +#ifndef STATUS_FILE_LOCKED_WITH_ONLY_READERS +# define STATUS_FILE_LOCKED_WITH_ONLY_READERS ((NTSTATUS) 0x0000012AL) +#endif + +#ifndef STATUS_FILE_LOCKED_WITH_WRITERS +# define STATUS_FILE_LOCKED_WITH_WRITERS ((NTSTATUS) 0x0000012BL) +#endif + +#ifndef STATUS_RESOURCEMANAGER_READ_ONLY +# define STATUS_RESOURCEMANAGER_READ_ONLY ((NTSTATUS) 0x00000202L) +#endif + +#ifndef STATUS_RING_PREVIOUSLY_EMPTY +# define STATUS_RING_PREVIOUSLY_EMPTY ((NTSTATUS) 0x00000210L) +#endif + +#ifndef STATUS_RING_PREVIOUSLY_FULL +# define STATUS_RING_PREVIOUSLY_FULL ((NTSTATUS) 0x00000211L) +#endif + +#ifndef STATUS_RING_PREVIOUSLY_ABOVE_QUOTA +# define STATUS_RING_PREVIOUSLY_ABOVE_QUOTA ((NTSTATUS) 0x00000212L) +#endif + +#ifndef STATUS_RING_NEWLY_EMPTY +# define STATUS_RING_NEWLY_EMPTY ((NTSTATUS) 0x00000213L) +#endif + +#ifndef STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT +# define STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT ((NTSTATUS) 0x00000214L) +#endif + +#ifndef STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE +# define STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE ((NTSTATUS) 0x00000215L) +#endif + +#ifndef STATUS_OPLOCK_HANDLE_CLOSED +# define STATUS_OPLOCK_HANDLE_CLOSED ((NTSTATUS) 0x00000216L) +#endif + +#ifndef STATUS_WAIT_FOR_OPLOCK +# define STATUS_WAIT_FOR_OPLOCK ((NTSTATUS) 0x00000367L) +#endif + +#ifndef STATUS_OBJECT_NAME_EXISTS +# define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS) 0x40000000L) +#endif + +#ifndef STATUS_THREAD_WAS_SUSPENDED +# define STATUS_THREAD_WAS_SUSPENDED ((NTSTATUS) 0x40000001L) +#endif + +#ifndef STATUS_WORKING_SET_LIMIT_RANGE +# define STATUS_WORKING_SET_LIMIT_RANGE ((NTSTATUS) 0x40000002L) +#endif + +#ifndef STATUS_IMAGE_NOT_AT_BASE +# define STATUS_IMAGE_NOT_AT_BASE ((NTSTATUS) 0x40000003L) +#endif + +#ifndef STATUS_RXACT_STATE_CREATED +# define STATUS_RXACT_STATE_CREATED ((NTSTATUS) 0x40000004L) +#endif + +#ifndef STATUS_SEGMENT_NOTIFICATION +# define STATUS_SEGMENT_NOTIFICATION ((NTSTATUS) 0x40000005L) +#endif + +#ifndef STATUS_LOCAL_USER_SESSION_KEY +# define STATUS_LOCAL_USER_SESSION_KEY ((NTSTATUS) 0x40000006L) +#endif + +#ifndef STATUS_BAD_CURRENT_DIRECTORY +# define STATUS_BAD_CURRENT_DIRECTORY ((NTSTATUS) 0x40000007L) +#endif + +#ifndef STATUS_SERIAL_MORE_WRITES +# define STATUS_SERIAL_MORE_WRITES ((NTSTATUS) 0x40000008L) +#endif + +#ifndef STATUS_REGISTRY_RECOVERED +# define STATUS_REGISTRY_RECOVERED ((NTSTATUS) 0x40000009L) +#endif + +#ifndef STATUS_FT_READ_RECOVERY_FROM_BACKUP +# define STATUS_FT_READ_RECOVERY_FROM_BACKUP ((NTSTATUS) 0x4000000AL) +#endif + +#ifndef STATUS_FT_WRITE_RECOVERY +# define STATUS_FT_WRITE_RECOVERY ((NTSTATUS) 0x4000000BL) +#endif + +#ifndef STATUS_SERIAL_COUNTER_TIMEOUT +# define STATUS_SERIAL_COUNTER_TIMEOUT ((NTSTATUS) 0x4000000CL) +#endif + +#ifndef STATUS_NULL_LM_PASSWORD +# define STATUS_NULL_LM_PASSWORD ((NTSTATUS) 0x4000000DL) +#endif + +#ifndef STATUS_IMAGE_MACHINE_TYPE_MISMATCH +# define STATUS_IMAGE_MACHINE_TYPE_MISMATCH ((NTSTATUS) 0x4000000EL) +#endif + +#ifndef STATUS_RECEIVE_PARTIAL +# define STATUS_RECEIVE_PARTIAL ((NTSTATUS) 0x4000000FL) +#endif + +#ifndef STATUS_RECEIVE_EXPEDITED +# define STATUS_RECEIVE_EXPEDITED ((NTSTATUS) 0x40000010L) +#endif + +#ifndef STATUS_RECEIVE_PARTIAL_EXPEDITED +# define STATUS_RECEIVE_PARTIAL_EXPEDITED ((NTSTATUS) 0x40000011L) +#endif + +#ifndef STATUS_EVENT_DONE +# define STATUS_EVENT_DONE ((NTSTATUS) 0x40000012L) +#endif + +#ifndef STATUS_EVENT_PENDING +# define STATUS_EVENT_PENDING ((NTSTATUS) 0x40000013L) +#endif + +#ifndef STATUS_CHECKING_FILE_SYSTEM +# define STATUS_CHECKING_FILE_SYSTEM ((NTSTATUS) 0x40000014L) +#endif + +#ifndef STATUS_FATAL_APP_EXIT +# define STATUS_FATAL_APP_EXIT ((NTSTATUS) 0x40000015L) +#endif + +#ifndef STATUS_PREDEFINED_HANDLE +# define STATUS_PREDEFINED_HANDLE ((NTSTATUS) 0x40000016L) +#endif + +#ifndef STATUS_WAS_UNLOCKED +# define STATUS_WAS_UNLOCKED ((NTSTATUS) 0x40000017L) +#endif + +#ifndef STATUS_SERVICE_NOTIFICATION +# define STATUS_SERVICE_NOTIFICATION ((NTSTATUS) 0x40000018L) +#endif + +#ifndef STATUS_WAS_LOCKED +# define STATUS_WAS_LOCKED ((NTSTATUS) 0x40000019L) +#endif + +#ifndef STATUS_LOG_HARD_ERROR +# define STATUS_LOG_HARD_ERROR ((NTSTATUS) 0x4000001AL) +#endif + +#ifndef STATUS_ALREADY_WIN32 +# define STATUS_ALREADY_WIN32 ((NTSTATUS) 0x4000001BL) +#endif + +#ifndef STATUS_WX86_UNSIMULATE +# define STATUS_WX86_UNSIMULATE ((NTSTATUS) 0x4000001CL) +#endif + +#ifndef STATUS_WX86_CONTINUE +# define STATUS_WX86_CONTINUE ((NTSTATUS) 0x4000001DL) +#endif + +#ifndef STATUS_WX86_SINGLE_STEP +# define STATUS_WX86_SINGLE_STEP ((NTSTATUS) 0x4000001EL) +#endif + +#ifndef STATUS_WX86_BREAKPOINT +# define STATUS_WX86_BREAKPOINT ((NTSTATUS) 0x4000001FL) +#endif + +#ifndef STATUS_WX86_EXCEPTION_CONTINUE +# define STATUS_WX86_EXCEPTION_CONTINUE ((NTSTATUS) 0x40000020L) +#endif + +#ifndef STATUS_WX86_EXCEPTION_LASTCHANCE +# define STATUS_WX86_EXCEPTION_LASTCHANCE ((NTSTATUS) 0x40000021L) +#endif + +#ifndef STATUS_WX86_EXCEPTION_CHAIN +# define STATUS_WX86_EXCEPTION_CHAIN ((NTSTATUS) 0x40000022L) +#endif + +#ifndef STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE +# define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE ((NTSTATUS) 0x40000023L) +#endif + +#ifndef STATUS_NO_YIELD_PERFORMED +# define STATUS_NO_YIELD_PERFORMED ((NTSTATUS) 0x40000024L) +#endif + +#ifndef STATUS_TIMER_RESUME_IGNORED +# define STATUS_TIMER_RESUME_IGNORED ((NTSTATUS) 0x40000025L) +#endif + +#ifndef STATUS_ARBITRATION_UNHANDLED +# define STATUS_ARBITRATION_UNHANDLED ((NTSTATUS) 0x40000026L) +#endif + +#ifndef STATUS_CARDBUS_NOT_SUPPORTED +# define STATUS_CARDBUS_NOT_SUPPORTED ((NTSTATUS) 0x40000027L) +#endif + +#ifndef STATUS_WX86_CREATEWX86TIB +# define STATUS_WX86_CREATEWX86TIB ((NTSTATUS) 0x40000028L) +#endif + +#ifndef STATUS_MP_PROCESSOR_MISMATCH +# define STATUS_MP_PROCESSOR_MISMATCH ((NTSTATUS) 0x40000029L) +#endif + +#ifndef STATUS_HIBERNATED +# define STATUS_HIBERNATED ((NTSTATUS) 0x4000002AL) +#endif + +#ifndef STATUS_RESUME_HIBERNATION +# define STATUS_RESUME_HIBERNATION ((NTSTATUS) 0x4000002BL) +#endif + +#ifndef STATUS_FIRMWARE_UPDATED +# define STATUS_FIRMWARE_UPDATED ((NTSTATUS) 0x4000002CL) +#endif + +#ifndef STATUS_DRIVERS_LEAKING_LOCKED_PAGES +# define STATUS_DRIVERS_LEAKING_LOCKED_PAGES ((NTSTATUS) 0x4000002DL) +#endif + +#ifndef STATUS_MESSAGE_RETRIEVED +# define STATUS_MESSAGE_RETRIEVED ((NTSTATUS) 0x4000002EL) +#endif + +#ifndef STATUS_SYSTEM_POWERSTATE_TRANSITION +# define STATUS_SYSTEM_POWERSTATE_TRANSITION ((NTSTATUS) 0x4000002FL) +#endif + +#ifndef STATUS_ALPC_CHECK_COMPLETION_LIST +# define STATUS_ALPC_CHECK_COMPLETION_LIST ((NTSTATUS) 0x40000030L) +#endif + +#ifndef STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION +# define STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION ((NTSTATUS) 0x40000031L) +#endif + +#ifndef STATUS_ACCESS_AUDIT_BY_POLICY +# define STATUS_ACCESS_AUDIT_BY_POLICY ((NTSTATUS) 0x40000032L) +#endif + +#ifndef STATUS_ABANDON_HIBERFILE +# define STATUS_ABANDON_HIBERFILE ((NTSTATUS) 0x40000033L) +#endif + +#ifndef STATUS_BIZRULES_NOT_ENABLED +# define STATUS_BIZRULES_NOT_ENABLED ((NTSTATUS) 0x40000034L) +#endif + +#ifndef STATUS_GUARD_PAGE_VIOLATION +# define STATUS_GUARD_PAGE_VIOLATION ((NTSTATUS) 0x80000001L) +#endif + +#ifndef STATUS_DATATYPE_MISALIGNMENT +# define STATUS_DATATYPE_MISALIGNMENT ((NTSTATUS) 0x80000002L) +#endif + +#ifndef STATUS_BREAKPOINT +# define STATUS_BREAKPOINT ((NTSTATUS) 0x80000003L) +#endif + +#ifndef STATUS_SINGLE_STEP +# define STATUS_SINGLE_STEP ((NTSTATUS) 0x80000004L) +#endif + +#ifndef STATUS_BUFFER_OVERFLOW +# define STATUS_BUFFER_OVERFLOW ((NTSTATUS) 0x80000005L) +#endif + +#ifndef STATUS_NO_MORE_FILES +# define STATUS_NO_MORE_FILES ((NTSTATUS) 0x80000006L) +#endif + +#ifndef STATUS_WAKE_SYSTEM_DEBUGGER +# define STATUS_WAKE_SYSTEM_DEBUGGER ((NTSTATUS) 0x80000007L) +#endif + +#ifndef STATUS_HANDLES_CLOSED +# define STATUS_HANDLES_CLOSED ((NTSTATUS) 0x8000000AL) +#endif + +#ifndef STATUS_NO_INHERITANCE +# define STATUS_NO_INHERITANCE ((NTSTATUS) 0x8000000BL) +#endif + +#ifndef STATUS_GUID_SUBSTITUTION_MADE +# define STATUS_GUID_SUBSTITUTION_MADE ((NTSTATUS) 0x8000000CL) +#endif + +#ifndef STATUS_PARTIAL_COPY +# define STATUS_PARTIAL_COPY ((NTSTATUS) 0x8000000DL) +#endif + +#ifndef STATUS_DEVICE_PAPER_EMPTY +# define STATUS_DEVICE_PAPER_EMPTY ((NTSTATUS) 0x8000000EL) +#endif + +#ifndef STATUS_DEVICE_POWERED_OFF +# define STATUS_DEVICE_POWERED_OFF ((NTSTATUS) 0x8000000FL) +#endif + +#ifndef STATUS_DEVICE_OFF_LINE +# define STATUS_DEVICE_OFF_LINE ((NTSTATUS) 0x80000010L) +#endif + +#ifndef STATUS_DEVICE_BUSY +# define STATUS_DEVICE_BUSY ((NTSTATUS) 0x80000011L) +#endif + +#ifndef STATUS_NO_MORE_EAS +# define STATUS_NO_MORE_EAS ((NTSTATUS) 0x80000012L) +#endif + +#ifndef STATUS_INVALID_EA_NAME +# define STATUS_INVALID_EA_NAME ((NTSTATUS) 0x80000013L) +#endif + +#ifndef STATUS_EA_LIST_INCONSISTENT +# define STATUS_EA_LIST_INCONSISTENT ((NTSTATUS) 0x80000014L) +#endif + +#ifndef STATUS_INVALID_EA_FLAG +# define STATUS_INVALID_EA_FLAG ((NTSTATUS) 0x80000015L) +#endif + +#ifndef STATUS_VERIFY_REQUIRED +# define STATUS_VERIFY_REQUIRED ((NTSTATUS) 0x80000016L) +#endif + +#ifndef STATUS_EXTRANEOUS_INFORMATION +# define STATUS_EXTRANEOUS_INFORMATION ((NTSTATUS) 0x80000017L) +#endif + +#ifndef STATUS_RXACT_COMMIT_NECESSARY +# define STATUS_RXACT_COMMIT_NECESSARY ((NTSTATUS) 0x80000018L) +#endif + +#ifndef STATUS_NO_MORE_ENTRIES +# define STATUS_NO_MORE_ENTRIES ((NTSTATUS) 0x8000001AL) +#endif + +#ifndef STATUS_FILEMARK_DETECTED +# define STATUS_FILEMARK_DETECTED ((NTSTATUS) 0x8000001BL) +#endif + +#ifndef STATUS_MEDIA_CHANGED +# define STATUS_MEDIA_CHANGED ((NTSTATUS) 0x8000001CL) +#endif + +#ifndef STATUS_BUS_RESET +# define STATUS_BUS_RESET ((NTSTATUS) 0x8000001DL) +#endif + +#ifndef STATUS_END_OF_MEDIA +# define STATUS_END_OF_MEDIA ((NTSTATUS) 0x8000001EL) +#endif + +#ifndef STATUS_BEGINNING_OF_MEDIA +# define STATUS_BEGINNING_OF_MEDIA ((NTSTATUS) 0x8000001FL) +#endif + +#ifndef STATUS_MEDIA_CHECK +# define STATUS_MEDIA_CHECK ((NTSTATUS) 0x80000020L) +#endif + +#ifndef STATUS_SETMARK_DETECTED +# define STATUS_SETMARK_DETECTED ((NTSTATUS) 0x80000021L) +#endif + +#ifndef STATUS_NO_DATA_DETECTED +# define STATUS_NO_DATA_DETECTED ((NTSTATUS) 0x80000022L) +#endif + +#ifndef STATUS_REDIRECTOR_HAS_OPEN_HANDLES +# define STATUS_REDIRECTOR_HAS_OPEN_HANDLES ((NTSTATUS) 0x80000023L) +#endif + +#ifndef STATUS_SERVER_HAS_OPEN_HANDLES +# define STATUS_SERVER_HAS_OPEN_HANDLES ((NTSTATUS) 0x80000024L) +#endif + +#ifndef STATUS_ALREADY_DISCONNECTED +# define STATUS_ALREADY_DISCONNECTED ((NTSTATUS) 0x80000025L) +#endif + +#ifndef STATUS_LONGJUMP +# define STATUS_LONGJUMP ((NTSTATUS) 0x80000026L) +#endif + +#ifndef STATUS_CLEANER_CARTRIDGE_INSTALLED +# define STATUS_CLEANER_CARTRIDGE_INSTALLED ((NTSTATUS) 0x80000027L) +#endif + +#ifndef STATUS_PLUGPLAY_QUERY_VETOED +# define STATUS_PLUGPLAY_QUERY_VETOED ((NTSTATUS) 0x80000028L) +#endif + +#ifndef STATUS_UNWIND_CONSOLIDATE +# define STATUS_UNWIND_CONSOLIDATE ((NTSTATUS) 0x80000029L) +#endif + +#ifndef STATUS_REGISTRY_HIVE_RECOVERED +# define STATUS_REGISTRY_HIVE_RECOVERED ((NTSTATUS) 0x8000002AL) +#endif + +#ifndef STATUS_DLL_MIGHT_BE_INSECURE +# define STATUS_DLL_MIGHT_BE_INSECURE ((NTSTATUS) 0x8000002BL) +#endif + +#ifndef STATUS_DLL_MIGHT_BE_INCOMPATIBLE +# define STATUS_DLL_MIGHT_BE_INCOMPATIBLE ((NTSTATUS) 0x8000002CL) +#endif + +#ifndef STATUS_STOPPED_ON_SYMLINK +# define STATUS_STOPPED_ON_SYMLINK ((NTSTATUS) 0x8000002DL) +#endif + +#ifndef STATUS_CANNOT_GRANT_REQUESTED_OPLOCK +# define STATUS_CANNOT_GRANT_REQUESTED_OPLOCK ((NTSTATUS) 0x8000002EL) +#endif + +#ifndef STATUS_NO_ACE_CONDITION +# define STATUS_NO_ACE_CONDITION ((NTSTATUS) 0x8000002FL) +#endif + +#ifndef STATUS_UNSUCCESSFUL +# define STATUS_UNSUCCESSFUL ((NTSTATUS) 0xC0000001L) +#endif + +#ifndef STATUS_NOT_IMPLEMENTED +# define STATUS_NOT_IMPLEMENTED ((NTSTATUS) 0xC0000002L) +#endif + +#ifndef STATUS_INVALID_INFO_CLASS +# define STATUS_INVALID_INFO_CLASS ((NTSTATUS) 0xC0000003L) +#endif + +#ifndef STATUS_INFO_LENGTH_MISMATCH +# define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xC0000004L) +#endif + +#ifndef STATUS_ACCESS_VIOLATION +# define STATUS_ACCESS_VIOLATION ((NTSTATUS) 0xC0000005L) +#endif + +#ifndef STATUS_IN_PAGE_ERROR +# define STATUS_IN_PAGE_ERROR ((NTSTATUS) 0xC0000006L) +#endif + +#ifndef STATUS_PAGEFILE_QUOTA +# define STATUS_PAGEFILE_QUOTA ((NTSTATUS) 0xC0000007L) +#endif + +#ifndef STATUS_INVALID_HANDLE +# define STATUS_INVALID_HANDLE ((NTSTATUS) 0xC0000008L) +#endif + +#ifndef STATUS_BAD_INITIAL_STACK +# define STATUS_BAD_INITIAL_STACK ((NTSTATUS) 0xC0000009L) +#endif + +#ifndef STATUS_BAD_INITIAL_PC +# define STATUS_BAD_INITIAL_PC ((NTSTATUS) 0xC000000AL) +#endif + +#ifndef STATUS_INVALID_CID +# define STATUS_INVALID_CID ((NTSTATUS) 0xC000000BL) +#endif + +#ifndef STATUS_TIMER_NOT_CANCELED +# define STATUS_TIMER_NOT_CANCELED ((NTSTATUS) 0xC000000CL) +#endif + +#ifndef STATUS_INVALID_PARAMETER +# define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xC000000DL) +#endif + +#ifndef STATUS_NO_SUCH_DEVICE +# define STATUS_NO_SUCH_DEVICE ((NTSTATUS) 0xC000000EL) +#endif + +#ifndef STATUS_NO_SUCH_FILE +# define STATUS_NO_SUCH_FILE ((NTSTATUS) 0xC000000FL) +#endif + +#ifndef STATUS_INVALID_DEVICE_REQUEST +# define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS) 0xC0000010L) +#endif + +#ifndef STATUS_END_OF_FILE +# define STATUS_END_OF_FILE ((NTSTATUS) 0xC0000011L) +#endif + +#ifndef STATUS_WRONG_VOLUME +# define STATUS_WRONG_VOLUME ((NTSTATUS) 0xC0000012L) +#endif + +#ifndef STATUS_NO_MEDIA_IN_DEVICE +# define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS) 0xC0000013L) +#endif + +#ifndef STATUS_UNRECOGNIZED_MEDIA +# define STATUS_UNRECOGNIZED_MEDIA ((NTSTATUS) 0xC0000014L) +#endif + +#ifndef STATUS_NONEXISTENT_SECTOR +# define STATUS_NONEXISTENT_SECTOR ((NTSTATUS) 0xC0000015L) +#endif + +#ifndef STATUS_MORE_PROCESSING_REQUIRED +# define STATUS_MORE_PROCESSING_REQUIRED ((NTSTATUS) 0xC0000016L) +#endif + +#ifndef STATUS_NO_MEMORY +# define STATUS_NO_MEMORY ((NTSTATUS) 0xC0000017L) +#endif + +#ifndef STATUS_CONFLICTING_ADDRESSES +# define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS) 0xC0000018L) +#endif + +#ifndef STATUS_NOT_MAPPED_VIEW +# define STATUS_NOT_MAPPED_VIEW ((NTSTATUS) 0xC0000019L) +#endif + +#ifndef STATUS_UNABLE_TO_FREE_VM +# define STATUS_UNABLE_TO_FREE_VM ((NTSTATUS) 0xC000001AL) +#endif + +#ifndef STATUS_UNABLE_TO_DELETE_SECTION +# define STATUS_UNABLE_TO_DELETE_SECTION ((NTSTATUS) 0xC000001BL) +#endif + +#ifndef STATUS_INVALID_SYSTEM_SERVICE +# define STATUS_INVALID_SYSTEM_SERVICE ((NTSTATUS) 0xC000001CL) +#endif + +#ifndef STATUS_ILLEGAL_INSTRUCTION +# define STATUS_ILLEGAL_INSTRUCTION ((NTSTATUS) 0xC000001DL) +#endif + +#ifndef STATUS_INVALID_LOCK_SEQUENCE +# define STATUS_INVALID_LOCK_SEQUENCE ((NTSTATUS) 0xC000001EL) +#endif + +#ifndef STATUS_INVALID_VIEW_SIZE +# define STATUS_INVALID_VIEW_SIZE ((NTSTATUS) 0xC000001FL) +#endif + +#ifndef STATUS_INVALID_FILE_FOR_SECTION +# define STATUS_INVALID_FILE_FOR_SECTION ((NTSTATUS) 0xC0000020L) +#endif + +#ifndef STATUS_ALREADY_COMMITTED +# define STATUS_ALREADY_COMMITTED ((NTSTATUS) 0xC0000021L) +#endif + +#ifndef STATUS_ACCESS_DENIED +# define STATUS_ACCESS_DENIED ((NTSTATUS) 0xC0000022L) +#endif + +#ifndef STATUS_BUFFER_TOO_SMALL +# define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xC0000023L) +#endif + +#ifndef STATUS_OBJECT_TYPE_MISMATCH +# define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS) 0xC0000024L) +#endif + +#ifndef STATUS_NONCONTINUABLE_EXCEPTION +# define STATUS_NONCONTINUABLE_EXCEPTION ((NTSTATUS) 0xC0000025L) +#endif + +#ifndef STATUS_INVALID_DISPOSITION +# define STATUS_INVALID_DISPOSITION ((NTSTATUS) 0xC0000026L) +#endif + +#ifndef STATUS_UNWIND +# define STATUS_UNWIND ((NTSTATUS) 0xC0000027L) +#endif + +#ifndef STATUS_BAD_STACK +# define STATUS_BAD_STACK ((NTSTATUS) 0xC0000028L) +#endif + +#ifndef STATUS_INVALID_UNWIND_TARGET +# define STATUS_INVALID_UNWIND_TARGET ((NTSTATUS) 0xC0000029L) +#endif + +#ifndef STATUS_NOT_LOCKED +# define STATUS_NOT_LOCKED ((NTSTATUS) 0xC000002AL) +#endif + +#ifndef STATUS_PARITY_ERROR +# define STATUS_PARITY_ERROR ((NTSTATUS) 0xC000002BL) +#endif + +#ifndef STATUS_UNABLE_TO_DECOMMIT_VM +# define STATUS_UNABLE_TO_DECOMMIT_VM ((NTSTATUS) 0xC000002CL) +#endif + +#ifndef STATUS_NOT_COMMITTED +# define STATUS_NOT_COMMITTED ((NTSTATUS) 0xC000002DL) +#endif + +#ifndef STATUS_INVALID_PORT_ATTRIBUTES +# define STATUS_INVALID_PORT_ATTRIBUTES ((NTSTATUS) 0xC000002EL) +#endif + +#ifndef STATUS_PORT_MESSAGE_TOO_LONG +# define STATUS_PORT_MESSAGE_TOO_LONG ((NTSTATUS) 0xC000002FL) +#endif + +#ifndef STATUS_INVALID_PARAMETER_MIX +# define STATUS_INVALID_PARAMETER_MIX ((NTSTATUS) 0xC0000030L) +#endif + +#ifndef STATUS_INVALID_QUOTA_LOWER +# define STATUS_INVALID_QUOTA_LOWER ((NTSTATUS) 0xC0000031L) +#endif + +#ifndef STATUS_DISK_CORRUPT_ERROR +# define STATUS_DISK_CORRUPT_ERROR ((NTSTATUS) 0xC0000032L) +#endif + +#ifndef STATUS_OBJECT_NAME_INVALID +# define STATUS_OBJECT_NAME_INVALID ((NTSTATUS) 0xC0000033L) +#endif + +#ifndef STATUS_OBJECT_NAME_NOT_FOUND +# define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS) 0xC0000034L) +#endif + +#ifndef STATUS_OBJECT_NAME_COLLISION +# define STATUS_OBJECT_NAME_COLLISION ((NTSTATUS) 0xC0000035L) +#endif + +#ifndef STATUS_PORT_DISCONNECTED +# define STATUS_PORT_DISCONNECTED ((NTSTATUS) 0xC0000037L) +#endif + +#ifndef STATUS_DEVICE_ALREADY_ATTACHED +# define STATUS_DEVICE_ALREADY_ATTACHED ((NTSTATUS) 0xC0000038L) +#endif + +#ifndef STATUS_OBJECT_PATH_INVALID +# define STATUS_OBJECT_PATH_INVALID ((NTSTATUS) 0xC0000039L) +#endif + +#ifndef STATUS_OBJECT_PATH_NOT_FOUND +# define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS) 0xC000003AL) +#endif + +#ifndef STATUS_OBJECT_PATH_SYNTAX_BAD +# define STATUS_OBJECT_PATH_SYNTAX_BAD ((NTSTATUS) 0xC000003BL) +#endif + +#ifndef STATUS_DATA_OVERRUN +# define STATUS_DATA_OVERRUN ((NTSTATUS) 0xC000003CL) +#endif + +#ifndef STATUS_DATA_LATE_ERROR +# define STATUS_DATA_LATE_ERROR ((NTSTATUS) 0xC000003DL) +#endif + +#ifndef STATUS_DATA_ERROR +# define STATUS_DATA_ERROR ((NTSTATUS) 0xC000003EL) +#endif + +#ifndef STATUS_CRC_ERROR +# define STATUS_CRC_ERROR ((NTSTATUS) 0xC000003FL) +#endif + +#ifndef STATUS_SECTION_TOO_BIG +# define STATUS_SECTION_TOO_BIG ((NTSTATUS) 0xC0000040L) +#endif + +#ifndef STATUS_PORT_CONNECTION_REFUSED +# define STATUS_PORT_CONNECTION_REFUSED ((NTSTATUS) 0xC0000041L) +#endif + +#ifndef STATUS_INVALID_PORT_HANDLE +# define STATUS_INVALID_PORT_HANDLE ((NTSTATUS) 0xC0000042L) +#endif + +#ifndef STATUS_SHARING_VIOLATION +# define STATUS_SHARING_VIOLATION ((NTSTATUS) 0xC0000043L) +#endif + +#ifndef STATUS_QUOTA_EXCEEDED +# define STATUS_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000044L) +#endif + +#ifndef STATUS_INVALID_PAGE_PROTECTION +# define STATUS_INVALID_PAGE_PROTECTION ((NTSTATUS) 0xC0000045L) +#endif + +#ifndef STATUS_MUTANT_NOT_OWNED +# define STATUS_MUTANT_NOT_OWNED ((NTSTATUS) 0xC0000046L) +#endif + +#ifndef STATUS_SEMAPHORE_LIMIT_EXCEEDED +# define STATUS_SEMAPHORE_LIMIT_EXCEEDED ((NTSTATUS) 0xC0000047L) +#endif + +#ifndef STATUS_PORT_ALREADY_SET +# define STATUS_PORT_ALREADY_SET ((NTSTATUS) 0xC0000048L) +#endif + +#ifndef STATUS_SECTION_NOT_IMAGE +# define STATUS_SECTION_NOT_IMAGE ((NTSTATUS) 0xC0000049L) +#endif + +#ifndef STATUS_SUSPEND_COUNT_EXCEEDED +# define STATUS_SUSPEND_COUNT_EXCEEDED ((NTSTATUS) 0xC000004AL) +#endif + +#ifndef STATUS_THREAD_IS_TERMINATING +# define STATUS_THREAD_IS_TERMINATING ((NTSTATUS) 0xC000004BL) +#endif + +#ifndef STATUS_BAD_WORKING_SET_LIMIT +# define STATUS_BAD_WORKING_SET_LIMIT ((NTSTATUS) 0xC000004CL) +#endif + +#ifndef STATUS_INCOMPATIBLE_FILE_MAP +# define STATUS_INCOMPATIBLE_FILE_MAP ((NTSTATUS) 0xC000004DL) +#endif + +#ifndef STATUS_SECTION_PROTECTION +# define STATUS_SECTION_PROTECTION ((NTSTATUS) 0xC000004EL) +#endif + +#ifndef STATUS_EAS_NOT_SUPPORTED +# define STATUS_EAS_NOT_SUPPORTED ((NTSTATUS) 0xC000004FL) +#endif + +#ifndef STATUS_EA_TOO_LARGE +# define STATUS_EA_TOO_LARGE ((NTSTATUS) 0xC0000050L) +#endif + +#ifndef STATUS_NONEXISTENT_EA_ENTRY +# define STATUS_NONEXISTENT_EA_ENTRY ((NTSTATUS) 0xC0000051L) +#endif + +#ifndef STATUS_NO_EAS_ON_FILE +# define STATUS_NO_EAS_ON_FILE ((NTSTATUS) 0xC0000052L) +#endif + +#ifndef STATUS_EA_CORRUPT_ERROR +# define STATUS_EA_CORRUPT_ERROR ((NTSTATUS) 0xC0000053L) +#endif + +#ifndef STATUS_FILE_LOCK_CONFLICT +# define STATUS_FILE_LOCK_CONFLICT ((NTSTATUS) 0xC0000054L) +#endif + +#ifndef STATUS_LOCK_NOT_GRANTED +# define STATUS_LOCK_NOT_GRANTED ((NTSTATUS) 0xC0000055L) +#endif + +#ifndef STATUS_DELETE_PENDING +# define STATUS_DELETE_PENDING ((NTSTATUS) 0xC0000056L) +#endif + +#ifndef STATUS_CTL_FILE_NOT_SUPPORTED +# define STATUS_CTL_FILE_NOT_SUPPORTED ((NTSTATUS) 0xC0000057L) +#endif + +#ifndef STATUS_UNKNOWN_REVISION +# define STATUS_UNKNOWN_REVISION ((NTSTATUS) 0xC0000058L) +#endif + +#ifndef STATUS_REVISION_MISMATCH +# define STATUS_REVISION_MISMATCH ((NTSTATUS) 0xC0000059L) +#endif + +#ifndef STATUS_INVALID_OWNER +# define STATUS_INVALID_OWNER ((NTSTATUS) 0xC000005AL) +#endif + +#ifndef STATUS_INVALID_PRIMARY_GROUP +# define STATUS_INVALID_PRIMARY_GROUP ((NTSTATUS) 0xC000005BL) +#endif + +#ifndef STATUS_NO_IMPERSONATION_TOKEN +# define STATUS_NO_IMPERSONATION_TOKEN ((NTSTATUS) 0xC000005CL) +#endif + +#ifndef STATUS_CANT_DISABLE_MANDATORY +# define STATUS_CANT_DISABLE_MANDATORY ((NTSTATUS) 0xC000005DL) +#endif + +#ifndef STATUS_NO_LOGON_SERVERS +# define STATUS_NO_LOGON_SERVERS ((NTSTATUS) 0xC000005EL) +#endif + +#ifndef STATUS_NO_SUCH_LOGON_SESSION +# define STATUS_NO_SUCH_LOGON_SESSION ((NTSTATUS) 0xC000005FL) +#endif + +#ifndef STATUS_NO_SUCH_PRIVILEGE +# define STATUS_NO_SUCH_PRIVILEGE ((NTSTATUS) 0xC0000060L) +#endif + +#ifndef STATUS_PRIVILEGE_NOT_HELD +# define STATUS_PRIVILEGE_NOT_HELD ((NTSTATUS) 0xC0000061L) +#endif + +#ifndef STATUS_INVALID_ACCOUNT_NAME +# define STATUS_INVALID_ACCOUNT_NAME ((NTSTATUS) 0xC0000062L) +#endif + +#ifndef STATUS_USER_EXISTS +# define STATUS_USER_EXISTS ((NTSTATUS) 0xC0000063L) +#endif + +#ifndef STATUS_NO_SUCH_USER +# define STATUS_NO_SUCH_USER ((NTSTATUS) 0xC0000064L) +#endif + +#ifndef STATUS_GROUP_EXISTS +# define STATUS_GROUP_EXISTS ((NTSTATUS) 0xC0000065L) +#endif + +#ifndef STATUS_NO_SUCH_GROUP +# define STATUS_NO_SUCH_GROUP ((NTSTATUS) 0xC0000066L) +#endif + +#ifndef STATUS_MEMBER_IN_GROUP +# define STATUS_MEMBER_IN_GROUP ((NTSTATUS) 0xC0000067L) +#endif + +#ifndef STATUS_MEMBER_NOT_IN_GROUP +# define STATUS_MEMBER_NOT_IN_GROUP ((NTSTATUS) 0xC0000068L) +#endif + +#ifndef STATUS_LAST_ADMIN +# define STATUS_LAST_ADMIN ((NTSTATUS) 0xC0000069L) +#endif + +#ifndef STATUS_WRONG_PASSWORD +# define STATUS_WRONG_PASSWORD ((NTSTATUS) 0xC000006AL) +#endif + +#ifndef STATUS_ILL_FORMED_PASSWORD +# define STATUS_ILL_FORMED_PASSWORD ((NTSTATUS) 0xC000006BL) +#endif + +#ifndef STATUS_PASSWORD_RESTRICTION +# define STATUS_PASSWORD_RESTRICTION ((NTSTATUS) 0xC000006CL) +#endif + +#ifndef STATUS_LOGON_FAILURE +# define STATUS_LOGON_FAILURE ((NTSTATUS) 0xC000006DL) +#endif + +#ifndef STATUS_ACCOUNT_RESTRICTION +# define STATUS_ACCOUNT_RESTRICTION ((NTSTATUS) 0xC000006EL) +#endif + +#ifndef STATUS_INVALID_LOGON_HOURS +# define STATUS_INVALID_LOGON_HOURS ((NTSTATUS) 0xC000006FL) +#endif + +#ifndef STATUS_INVALID_WORKSTATION +# define STATUS_INVALID_WORKSTATION ((NTSTATUS) 0xC0000070L) +#endif + +#ifndef STATUS_PASSWORD_EXPIRED +# define STATUS_PASSWORD_EXPIRED ((NTSTATUS) 0xC0000071L) +#endif + +#ifndef STATUS_ACCOUNT_DISABLED +# define STATUS_ACCOUNT_DISABLED ((NTSTATUS) 0xC0000072L) +#endif + +#ifndef STATUS_NONE_MAPPED +# define STATUS_NONE_MAPPED ((NTSTATUS) 0xC0000073L) +#endif + +#ifndef STATUS_TOO_MANY_LUIDS_REQUESTED +# define STATUS_TOO_MANY_LUIDS_REQUESTED ((NTSTATUS) 0xC0000074L) +#endif + +#ifndef STATUS_LUIDS_EXHAUSTED +# define STATUS_LUIDS_EXHAUSTED ((NTSTATUS) 0xC0000075L) +#endif + +#ifndef STATUS_INVALID_SUB_AUTHORITY +# define STATUS_INVALID_SUB_AUTHORITY ((NTSTATUS) 0xC0000076L) +#endif + +#ifndef STATUS_INVALID_ACL +# define STATUS_INVALID_ACL ((NTSTATUS) 0xC0000077L) +#endif + +#ifndef STATUS_INVALID_SID +# define STATUS_INVALID_SID ((NTSTATUS) 0xC0000078L) +#endif + +#ifndef STATUS_INVALID_SECURITY_DESCR +# define STATUS_INVALID_SECURITY_DESCR ((NTSTATUS) 0xC0000079L) +#endif + +#ifndef STATUS_PROCEDURE_NOT_FOUND +# define STATUS_PROCEDURE_NOT_FOUND ((NTSTATUS) 0xC000007AL) +#endif + +#ifndef STATUS_INVALID_IMAGE_FORMAT +# define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS) 0xC000007BL) +#endif + +#ifndef STATUS_NO_TOKEN +# define STATUS_NO_TOKEN ((NTSTATUS) 0xC000007CL) +#endif + +#ifndef STATUS_BAD_INHERITANCE_ACL +# define STATUS_BAD_INHERITANCE_ACL ((NTSTATUS) 0xC000007DL) +#endif + +#ifndef STATUS_RANGE_NOT_LOCKED +# define STATUS_RANGE_NOT_LOCKED ((NTSTATUS) 0xC000007EL) +#endif + +#ifndef STATUS_DISK_FULL +# define STATUS_DISK_FULL ((NTSTATUS) 0xC000007FL) +#endif + +#ifndef STATUS_SERVER_DISABLED +# define STATUS_SERVER_DISABLED ((NTSTATUS) 0xC0000080L) +#endif + +#ifndef STATUS_SERVER_NOT_DISABLED +# define STATUS_SERVER_NOT_DISABLED ((NTSTATUS) 0xC0000081L) +#endif + +#ifndef STATUS_TOO_MANY_GUIDS_REQUESTED +# define STATUS_TOO_MANY_GUIDS_REQUESTED ((NTSTATUS) 0xC0000082L) +#endif + +#ifndef STATUS_GUIDS_EXHAUSTED +# define STATUS_GUIDS_EXHAUSTED ((NTSTATUS) 0xC0000083L) +#endif + +#ifndef STATUS_INVALID_ID_AUTHORITY +# define STATUS_INVALID_ID_AUTHORITY ((NTSTATUS) 0xC0000084L) +#endif + +#ifndef STATUS_AGENTS_EXHAUSTED +# define STATUS_AGENTS_EXHAUSTED ((NTSTATUS) 0xC0000085L) +#endif + +#ifndef STATUS_INVALID_VOLUME_LABEL +# define STATUS_INVALID_VOLUME_LABEL ((NTSTATUS) 0xC0000086L) +#endif + +#ifndef STATUS_SECTION_NOT_EXTENDED +# define STATUS_SECTION_NOT_EXTENDED ((NTSTATUS) 0xC0000087L) +#endif + +#ifndef STATUS_NOT_MAPPED_DATA +# define STATUS_NOT_MAPPED_DATA ((NTSTATUS) 0xC0000088L) +#endif + +#ifndef STATUS_RESOURCE_DATA_NOT_FOUND +# define STATUS_RESOURCE_DATA_NOT_FOUND ((NTSTATUS) 0xC0000089L) +#endif + +#ifndef STATUS_RESOURCE_TYPE_NOT_FOUND +# define STATUS_RESOURCE_TYPE_NOT_FOUND ((NTSTATUS) 0xC000008AL) +#endif + +#ifndef STATUS_RESOURCE_NAME_NOT_FOUND +# define STATUS_RESOURCE_NAME_NOT_FOUND ((NTSTATUS) 0xC000008BL) +#endif + +#ifndef STATUS_ARRAY_BOUNDS_EXCEEDED +# define STATUS_ARRAY_BOUNDS_EXCEEDED ((NTSTATUS) 0xC000008CL) +#endif + +#ifndef STATUS_FLOAT_DENORMAL_OPERAND +# define STATUS_FLOAT_DENORMAL_OPERAND ((NTSTATUS) 0xC000008DL) +#endif + +#ifndef STATUS_FLOAT_DIVIDE_BY_ZERO +# define STATUS_FLOAT_DIVIDE_BY_ZERO ((NTSTATUS) 0xC000008EL) +#endif + +#ifndef STATUS_FLOAT_INEXACT_RESULT +# define STATUS_FLOAT_INEXACT_RESULT ((NTSTATUS) 0xC000008FL) +#endif + +#ifndef STATUS_FLOAT_INVALID_OPERATION +# define STATUS_FLOAT_INVALID_OPERATION ((NTSTATUS) 0xC0000090L) +#endif + +#ifndef STATUS_FLOAT_OVERFLOW +# define STATUS_FLOAT_OVERFLOW ((NTSTATUS) 0xC0000091L) +#endif + +#ifndef STATUS_FLOAT_STACK_CHECK +# define STATUS_FLOAT_STACK_CHECK ((NTSTATUS) 0xC0000092L) +#endif + +#ifndef STATUS_FLOAT_UNDERFLOW +# define STATUS_FLOAT_UNDERFLOW ((NTSTATUS) 0xC0000093L) +#endif + +#ifndef STATUS_INTEGER_DIVIDE_BY_ZERO +# define STATUS_INTEGER_DIVIDE_BY_ZERO ((NTSTATUS) 0xC0000094L) +#endif + +#ifndef STATUS_INTEGER_OVERFLOW +# define STATUS_INTEGER_OVERFLOW ((NTSTATUS) 0xC0000095L) +#endif + +#ifndef STATUS_PRIVILEGED_INSTRUCTION +# define STATUS_PRIVILEGED_INSTRUCTION ((NTSTATUS) 0xC0000096L) +#endif + +#ifndef STATUS_TOO_MANY_PAGING_FILES +# define STATUS_TOO_MANY_PAGING_FILES ((NTSTATUS) 0xC0000097L) +#endif + +#ifndef STATUS_FILE_INVALID +# define STATUS_FILE_INVALID ((NTSTATUS) 0xC0000098L) +#endif + +#ifndef STATUS_ALLOTTED_SPACE_EXCEEDED +# define STATUS_ALLOTTED_SPACE_EXCEEDED ((NTSTATUS) 0xC0000099L) +#endif + +#ifndef STATUS_INSUFFICIENT_RESOURCES +# define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS) 0xC000009AL) +#endif + +#ifndef STATUS_DFS_EXIT_PATH_FOUND +# define STATUS_DFS_EXIT_PATH_FOUND ((NTSTATUS) 0xC000009BL) +#endif + +#ifndef STATUS_DEVICE_DATA_ERROR +# define STATUS_DEVICE_DATA_ERROR ((NTSTATUS) 0xC000009CL) +#endif + +#ifndef STATUS_DEVICE_NOT_CONNECTED +# define STATUS_DEVICE_NOT_CONNECTED ((NTSTATUS) 0xC000009DL) +#endif + +#ifndef STATUS_DEVICE_POWER_FAILURE +# define STATUS_DEVICE_POWER_FAILURE ((NTSTATUS) 0xC000009EL) +#endif + +#ifndef STATUS_FREE_VM_NOT_AT_BASE +# define STATUS_FREE_VM_NOT_AT_BASE ((NTSTATUS) 0xC000009FL) +#endif + +#ifndef STATUS_MEMORY_NOT_ALLOCATED +# define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS) 0xC00000A0L) +#endif + +#ifndef STATUS_WORKING_SET_QUOTA +# define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xC00000A1L) +#endif + +#ifndef STATUS_MEDIA_WRITE_PROTECTED +# define STATUS_MEDIA_WRITE_PROTECTED ((NTSTATUS) 0xC00000A2L) +#endif + +#ifndef STATUS_DEVICE_NOT_READY +# define STATUS_DEVICE_NOT_READY ((NTSTATUS) 0xC00000A3L) +#endif + +#ifndef STATUS_INVALID_GROUP_ATTRIBUTES +# define STATUS_INVALID_GROUP_ATTRIBUTES ((NTSTATUS) 0xC00000A4L) +#endif + +#ifndef STATUS_BAD_IMPERSONATION_LEVEL +# define STATUS_BAD_IMPERSONATION_LEVEL ((NTSTATUS) 0xC00000A5L) +#endif + +#ifndef STATUS_CANT_OPEN_ANONYMOUS +# define STATUS_CANT_OPEN_ANONYMOUS ((NTSTATUS) 0xC00000A6L) +#endif + +#ifndef STATUS_BAD_VALIDATION_CLASS +# define STATUS_BAD_VALIDATION_CLASS ((NTSTATUS) 0xC00000A7L) +#endif + +#ifndef STATUS_BAD_TOKEN_TYPE +# define STATUS_BAD_TOKEN_TYPE ((NTSTATUS) 0xC00000A8L) +#endif + +#ifndef STATUS_BAD_MASTER_BOOT_RECORD +# define STATUS_BAD_MASTER_BOOT_RECORD ((NTSTATUS) 0xC00000A9L) +#endif + +#ifndef STATUS_INSTRUCTION_MISALIGNMENT +# define STATUS_INSTRUCTION_MISALIGNMENT ((NTSTATUS) 0xC00000AAL) +#endif + +#ifndef STATUS_INSTANCE_NOT_AVAILABLE +# define STATUS_INSTANCE_NOT_AVAILABLE ((NTSTATUS) 0xC00000ABL) +#endif + +#ifndef STATUS_PIPE_NOT_AVAILABLE +# define STATUS_PIPE_NOT_AVAILABLE ((NTSTATUS) 0xC00000ACL) +#endif + +#ifndef STATUS_INVALID_PIPE_STATE +# define STATUS_INVALID_PIPE_STATE ((NTSTATUS) 0xC00000ADL) +#endif + +#ifndef STATUS_PIPE_BUSY +# define STATUS_PIPE_BUSY ((NTSTATUS) 0xC00000AEL) +#endif + +#ifndef STATUS_ILLEGAL_FUNCTION +# define STATUS_ILLEGAL_FUNCTION ((NTSTATUS) 0xC00000AFL) +#endif + +#ifndef STATUS_PIPE_DISCONNECTED +# define STATUS_PIPE_DISCONNECTED ((NTSTATUS) 0xC00000B0L) +#endif + +#ifndef STATUS_PIPE_CLOSING +# define STATUS_PIPE_CLOSING ((NTSTATUS) 0xC00000B1L) +#endif + +#ifndef STATUS_PIPE_CONNECTED +# define STATUS_PIPE_CONNECTED ((NTSTATUS) 0xC00000B2L) +#endif + +#ifndef STATUS_PIPE_LISTENING +# define STATUS_PIPE_LISTENING ((NTSTATUS) 0xC00000B3L) +#endif + +#ifndef STATUS_INVALID_READ_MODE +# define STATUS_INVALID_READ_MODE ((NTSTATUS) 0xC00000B4L) +#endif + +#ifndef STATUS_IO_TIMEOUT +# define STATUS_IO_TIMEOUT ((NTSTATUS) 0xC00000B5L) +#endif + +#ifndef STATUS_FILE_FORCED_CLOSED +# define STATUS_FILE_FORCED_CLOSED ((NTSTATUS) 0xC00000B6L) +#endif + +#ifndef STATUS_PROFILING_NOT_STARTED +# define STATUS_PROFILING_NOT_STARTED ((NTSTATUS) 0xC00000B7L) +#endif + +#ifndef STATUS_PROFILING_NOT_STOPPED +# define STATUS_PROFILING_NOT_STOPPED ((NTSTATUS) 0xC00000B8L) +#endif + +#ifndef STATUS_COULD_NOT_INTERPRET +# define STATUS_COULD_NOT_INTERPRET ((NTSTATUS) 0xC00000B9L) +#endif + +#ifndef STATUS_FILE_IS_A_DIRECTORY +# define STATUS_FILE_IS_A_DIRECTORY ((NTSTATUS) 0xC00000BAL) +#endif + +#ifndef STATUS_NOT_SUPPORTED +# define STATUS_NOT_SUPPORTED ((NTSTATUS) 0xC00000BBL) +#endif + +#ifndef STATUS_REMOTE_NOT_LISTENING +# define STATUS_REMOTE_NOT_LISTENING ((NTSTATUS) 0xC00000BCL) +#endif + +#ifndef STATUS_DUPLICATE_NAME +# define STATUS_DUPLICATE_NAME ((NTSTATUS) 0xC00000BDL) +#endif + +#ifndef STATUS_BAD_NETWORK_PATH +# define STATUS_BAD_NETWORK_PATH ((NTSTATUS) 0xC00000BEL) +#endif + +#ifndef STATUS_NETWORK_BUSY +# define STATUS_NETWORK_BUSY ((NTSTATUS) 0xC00000BFL) +#endif + +#ifndef STATUS_DEVICE_DOES_NOT_EXIST +# define STATUS_DEVICE_DOES_NOT_EXIST ((NTSTATUS) 0xC00000C0L) +#endif + +#ifndef STATUS_TOO_MANY_COMMANDS +# define STATUS_TOO_MANY_COMMANDS ((NTSTATUS) 0xC00000C1L) +#endif + +#ifndef STATUS_ADAPTER_HARDWARE_ERROR +# define STATUS_ADAPTER_HARDWARE_ERROR ((NTSTATUS) 0xC00000C2L) +#endif + +#ifndef STATUS_INVALID_NETWORK_RESPONSE +# define STATUS_INVALID_NETWORK_RESPONSE ((NTSTATUS) 0xC00000C3L) +#endif + +#ifndef STATUS_UNEXPECTED_NETWORK_ERROR +# define STATUS_UNEXPECTED_NETWORK_ERROR ((NTSTATUS) 0xC00000C4L) +#endif + +#ifndef STATUS_BAD_REMOTE_ADAPTER +# define STATUS_BAD_REMOTE_ADAPTER ((NTSTATUS) 0xC00000C5L) +#endif + +#ifndef STATUS_PRINT_QUEUE_FULL +# define STATUS_PRINT_QUEUE_FULL ((NTSTATUS) 0xC00000C6L) +#endif + +#ifndef STATUS_NO_SPOOL_SPACE +# define STATUS_NO_SPOOL_SPACE ((NTSTATUS) 0xC00000C7L) +#endif + +#ifndef STATUS_PRINT_CANCELLED +# define STATUS_PRINT_CANCELLED ((NTSTATUS) 0xC00000C8L) +#endif + +#ifndef STATUS_NETWORK_NAME_DELETED +# define STATUS_NETWORK_NAME_DELETED ((NTSTATUS) 0xC00000C9L) +#endif + +#ifndef STATUS_NETWORK_ACCESS_DENIED +# define STATUS_NETWORK_ACCESS_DENIED ((NTSTATUS) 0xC00000CAL) +#endif + +#ifndef STATUS_BAD_DEVICE_TYPE +# define STATUS_BAD_DEVICE_TYPE ((NTSTATUS) 0xC00000CBL) +#endif + +#ifndef STATUS_BAD_NETWORK_NAME +# define STATUS_BAD_NETWORK_NAME ((NTSTATUS) 0xC00000CCL) +#endif + +#ifndef STATUS_TOO_MANY_NAMES +# define STATUS_TOO_MANY_NAMES ((NTSTATUS) 0xC00000CDL) +#endif + +#ifndef STATUS_TOO_MANY_SESSIONS +# define STATUS_TOO_MANY_SESSIONS ((NTSTATUS) 0xC00000CEL) +#endif + +#ifndef STATUS_SHARING_PAUSED +# define STATUS_SHARING_PAUSED ((NTSTATUS) 0xC00000CFL) +#endif + +#ifndef STATUS_REQUEST_NOT_ACCEPTED +# define STATUS_REQUEST_NOT_ACCEPTED ((NTSTATUS) 0xC00000D0L) +#endif + +#ifndef STATUS_REDIRECTOR_PAUSED +# define STATUS_REDIRECTOR_PAUSED ((NTSTATUS) 0xC00000D1L) +#endif + +#ifndef STATUS_NET_WRITE_FAULT +# define STATUS_NET_WRITE_FAULT ((NTSTATUS) 0xC00000D2L) +#endif + +#ifndef STATUS_PROFILING_AT_LIMIT +# define STATUS_PROFILING_AT_LIMIT ((NTSTATUS) 0xC00000D3L) +#endif + +#ifndef STATUS_NOT_SAME_DEVICE +# define STATUS_NOT_SAME_DEVICE ((NTSTATUS) 0xC00000D4L) +#endif + +#ifndef STATUS_FILE_RENAMED +# define STATUS_FILE_RENAMED ((NTSTATUS) 0xC00000D5L) +#endif + +#ifndef STATUS_VIRTUAL_CIRCUIT_CLOSED +# define STATUS_VIRTUAL_CIRCUIT_CLOSED ((NTSTATUS) 0xC00000D6L) +#endif + +#ifndef STATUS_NO_SECURITY_ON_OBJECT +# define STATUS_NO_SECURITY_ON_OBJECT ((NTSTATUS) 0xC00000D7L) +#endif + +#ifndef STATUS_CANT_WAIT +# define STATUS_CANT_WAIT ((NTSTATUS) 0xC00000D8L) +#endif + +#ifndef STATUS_PIPE_EMPTY +# define STATUS_PIPE_EMPTY ((NTSTATUS) 0xC00000D9L) +#endif + +#ifndef STATUS_CANT_ACCESS_DOMAIN_INFO +# define STATUS_CANT_ACCESS_DOMAIN_INFO ((NTSTATUS) 0xC00000DAL) +#endif + +#ifndef STATUS_CANT_TERMINATE_SELF +# define STATUS_CANT_TERMINATE_SELF ((NTSTATUS) 0xC00000DBL) +#endif + +#ifndef STATUS_INVALID_SERVER_STATE +# define STATUS_INVALID_SERVER_STATE ((NTSTATUS) 0xC00000DCL) +#endif + +#ifndef STATUS_INVALID_DOMAIN_STATE +# define STATUS_INVALID_DOMAIN_STATE ((NTSTATUS) 0xC00000DDL) +#endif + +#ifndef STATUS_INVALID_DOMAIN_ROLE +# define STATUS_INVALID_DOMAIN_ROLE ((NTSTATUS) 0xC00000DEL) +#endif + +#ifndef STATUS_NO_SUCH_DOMAIN +# define STATUS_NO_SUCH_DOMAIN ((NTSTATUS) 0xC00000DFL) +#endif + +#ifndef STATUS_DOMAIN_EXISTS +# define STATUS_DOMAIN_EXISTS ((NTSTATUS) 0xC00000E0L) +#endif + +#ifndef STATUS_DOMAIN_LIMIT_EXCEEDED +# define STATUS_DOMAIN_LIMIT_EXCEEDED ((NTSTATUS) 0xC00000E1L) +#endif + +#ifndef STATUS_OPLOCK_NOT_GRANTED +# define STATUS_OPLOCK_NOT_GRANTED ((NTSTATUS) 0xC00000E2L) +#endif + +#ifndef STATUS_INVALID_OPLOCK_PROTOCOL +# define STATUS_INVALID_OPLOCK_PROTOCOL ((NTSTATUS) 0xC00000E3L) +#endif + +#ifndef STATUS_INTERNAL_DB_CORRUPTION +# define STATUS_INTERNAL_DB_CORRUPTION ((NTSTATUS) 0xC00000E4L) +#endif + +#ifndef STATUS_INTERNAL_ERROR +# define STATUS_INTERNAL_ERROR ((NTSTATUS) 0xC00000E5L) +#endif + +#ifndef STATUS_GENERIC_NOT_MAPPED +# define STATUS_GENERIC_NOT_MAPPED ((NTSTATUS) 0xC00000E6L) +#endif + +#ifndef STATUS_BAD_DESCRIPTOR_FORMAT +# define STATUS_BAD_DESCRIPTOR_FORMAT ((NTSTATUS) 0xC00000E7L) +#endif + +#ifndef STATUS_INVALID_USER_BUFFER +# define STATUS_INVALID_USER_BUFFER ((NTSTATUS) 0xC00000E8L) +#endif + +#ifndef STATUS_UNEXPECTED_IO_ERROR +# define STATUS_UNEXPECTED_IO_ERROR ((NTSTATUS) 0xC00000E9L) +#endif + +#ifndef STATUS_UNEXPECTED_MM_CREATE_ERR +# define STATUS_UNEXPECTED_MM_CREATE_ERR ((NTSTATUS) 0xC00000EAL) +#endif + +#ifndef STATUS_UNEXPECTED_MM_MAP_ERROR +# define STATUS_UNEXPECTED_MM_MAP_ERROR ((NTSTATUS) 0xC00000EBL) +#endif + +#ifndef STATUS_UNEXPECTED_MM_EXTEND_ERR +# define STATUS_UNEXPECTED_MM_EXTEND_ERR ((NTSTATUS) 0xC00000ECL) +#endif + +#ifndef STATUS_NOT_LOGON_PROCESS +# define STATUS_NOT_LOGON_PROCESS ((NTSTATUS) 0xC00000EDL) +#endif + +#ifndef STATUS_LOGON_SESSION_EXISTS +# define STATUS_LOGON_SESSION_EXISTS ((NTSTATUS) 0xC00000EEL) +#endif + +#ifndef STATUS_INVALID_PARAMETER_1 +# define STATUS_INVALID_PARAMETER_1 ((NTSTATUS) 0xC00000EFL) +#endif + +#ifndef STATUS_INVALID_PARAMETER_2 +# define STATUS_INVALID_PARAMETER_2 ((NTSTATUS) 0xC00000F0L) +#endif + +#ifndef STATUS_INVALID_PARAMETER_3 +# define STATUS_INVALID_PARAMETER_3 ((NTSTATUS) 0xC00000F1L) +#endif + +#ifndef STATUS_INVALID_PARAMETER_4 +# define STATUS_INVALID_PARAMETER_4 ((NTSTATUS) 0xC00000F2L) +#endif + +#ifndef STATUS_INVALID_PARAMETER_5 +# define STATUS_INVALID_PARAMETER_5 ((NTSTATUS) 0xC00000F3L) +#endif + +#ifndef STATUS_INVALID_PARAMETER_6 +# define STATUS_INVALID_PARAMETER_6 ((NTSTATUS) 0xC00000F4L) +#endif + +#ifndef STATUS_INVALID_PARAMETER_7 +# define STATUS_INVALID_PARAMETER_7 ((NTSTATUS) 0xC00000F5L) +#endif + +#ifndef STATUS_INVALID_PARAMETER_8 +# define STATUS_INVALID_PARAMETER_8 ((NTSTATUS) 0xC00000F6L) +#endif + +#ifndef STATUS_INVALID_PARAMETER_9 +# define STATUS_INVALID_PARAMETER_9 ((NTSTATUS) 0xC00000F7L) +#endif + +#ifndef STATUS_INVALID_PARAMETER_10 +# define STATUS_INVALID_PARAMETER_10 ((NTSTATUS) 0xC00000F8L) +#endif + +#ifndef STATUS_INVALID_PARAMETER_11 +# define STATUS_INVALID_PARAMETER_11 ((NTSTATUS) 0xC00000F9L) +#endif + +#ifndef STATUS_INVALID_PARAMETER_12 +# define STATUS_INVALID_PARAMETER_12 ((NTSTATUS) 0xC00000FAL) +#endif + +#ifndef STATUS_REDIRECTOR_NOT_STARTED +# define STATUS_REDIRECTOR_NOT_STARTED ((NTSTATUS) 0xC00000FBL) +#endif + +#ifndef STATUS_REDIRECTOR_STARTED +# define STATUS_REDIRECTOR_STARTED ((NTSTATUS) 0xC00000FCL) +#endif + +#ifndef STATUS_STACK_OVERFLOW +# define STATUS_STACK_OVERFLOW ((NTSTATUS) 0xC00000FDL) +#endif + +#ifndef STATUS_NO_SUCH_PACKAGE +# define STATUS_NO_SUCH_PACKAGE ((NTSTATUS) 0xC00000FEL) +#endif + +#ifndef STATUS_BAD_FUNCTION_TABLE +# define STATUS_BAD_FUNCTION_TABLE ((NTSTATUS) 0xC00000FFL) +#endif + +#ifndef STATUS_VARIABLE_NOT_FOUND +# define STATUS_VARIABLE_NOT_FOUND ((NTSTATUS) 0xC0000100L) +#endif + +#ifndef STATUS_DIRECTORY_NOT_EMPTY +# define STATUS_DIRECTORY_NOT_EMPTY ((NTSTATUS) 0xC0000101L) +#endif + +#ifndef STATUS_FILE_CORRUPT_ERROR +# define STATUS_FILE_CORRUPT_ERROR ((NTSTATUS) 0xC0000102L) +#endif + +#ifndef STATUS_NOT_A_DIRECTORY +# define STATUS_NOT_A_DIRECTORY ((NTSTATUS) 0xC0000103L) +#endif + +#ifndef STATUS_BAD_LOGON_SESSION_STATE +# define STATUS_BAD_LOGON_SESSION_STATE ((NTSTATUS) 0xC0000104L) +#endif + +#ifndef STATUS_LOGON_SESSION_COLLISION +# define STATUS_LOGON_SESSION_COLLISION ((NTSTATUS) 0xC0000105L) +#endif + +#ifndef STATUS_NAME_TOO_LONG +# define STATUS_NAME_TOO_LONG ((NTSTATUS) 0xC0000106L) +#endif + +#ifndef STATUS_FILES_OPEN +# define STATUS_FILES_OPEN ((NTSTATUS) 0xC0000107L) +#endif + +#ifndef STATUS_CONNECTION_IN_USE +# define STATUS_CONNECTION_IN_USE ((NTSTATUS) 0xC0000108L) +#endif + +#ifndef STATUS_MESSAGE_NOT_FOUND +# define STATUS_MESSAGE_NOT_FOUND ((NTSTATUS) 0xC0000109L) +#endif + +#ifndef STATUS_PROCESS_IS_TERMINATING +# define STATUS_PROCESS_IS_TERMINATING ((NTSTATUS) 0xC000010AL) +#endif + +#ifndef STATUS_INVALID_LOGON_TYPE +# define STATUS_INVALID_LOGON_TYPE ((NTSTATUS) 0xC000010BL) +#endif + +#ifndef STATUS_NO_GUID_TRANSLATION +# define STATUS_NO_GUID_TRANSLATION ((NTSTATUS) 0xC000010CL) +#endif + +#ifndef STATUS_CANNOT_IMPERSONATE +# define STATUS_CANNOT_IMPERSONATE ((NTSTATUS) 0xC000010DL) +#endif + +#ifndef STATUS_IMAGE_ALREADY_LOADED +# define STATUS_IMAGE_ALREADY_LOADED ((NTSTATUS) 0xC000010EL) +#endif + +#ifndef STATUS_ABIOS_NOT_PRESENT +# define STATUS_ABIOS_NOT_PRESENT ((NTSTATUS) 0xC000010FL) +#endif + +#ifndef STATUS_ABIOS_LID_NOT_EXIST +# define STATUS_ABIOS_LID_NOT_EXIST ((NTSTATUS) 0xC0000110L) +#endif + +#ifndef STATUS_ABIOS_LID_ALREADY_OWNED +# define STATUS_ABIOS_LID_ALREADY_OWNED ((NTSTATUS) 0xC0000111L) +#endif + +#ifndef STATUS_ABIOS_NOT_LID_OWNER +# define STATUS_ABIOS_NOT_LID_OWNER ((NTSTATUS) 0xC0000112L) +#endif + +#ifndef STATUS_ABIOS_INVALID_COMMAND +# define STATUS_ABIOS_INVALID_COMMAND ((NTSTATUS) 0xC0000113L) +#endif + +#ifndef STATUS_ABIOS_INVALID_LID +# define STATUS_ABIOS_INVALID_LID ((NTSTATUS) 0xC0000114L) +#endif + +#ifndef STATUS_ABIOS_SELECTOR_NOT_AVAILABLE +# define STATUS_ABIOS_SELECTOR_NOT_AVAILABLE ((NTSTATUS) 0xC0000115L) +#endif + +#ifndef STATUS_ABIOS_INVALID_SELECTOR +# define STATUS_ABIOS_INVALID_SELECTOR ((NTSTATUS) 0xC0000116L) +#endif + +#ifndef STATUS_NO_LDT +# define STATUS_NO_LDT ((NTSTATUS) 0xC0000117L) +#endif + +#ifndef STATUS_INVALID_LDT_SIZE +# define STATUS_INVALID_LDT_SIZE ((NTSTATUS) 0xC0000118L) +#endif + +#ifndef STATUS_INVALID_LDT_OFFSET +# define STATUS_INVALID_LDT_OFFSET ((NTSTATUS) 0xC0000119L) +#endif + +#ifndef STATUS_INVALID_LDT_DESCRIPTOR +# define STATUS_INVALID_LDT_DESCRIPTOR ((NTSTATUS) 0xC000011AL) +#endif + +#ifndef STATUS_INVALID_IMAGE_NE_FORMAT +# define STATUS_INVALID_IMAGE_NE_FORMAT ((NTSTATUS) 0xC000011BL) +#endif + +#ifndef STATUS_RXACT_INVALID_STATE +# define STATUS_RXACT_INVALID_STATE ((NTSTATUS) 0xC000011CL) +#endif + +#ifndef STATUS_RXACT_COMMIT_FAILURE +# define STATUS_RXACT_COMMIT_FAILURE ((NTSTATUS) 0xC000011DL) +#endif + +#ifndef STATUS_MAPPED_FILE_SIZE_ZERO +# define STATUS_MAPPED_FILE_SIZE_ZERO ((NTSTATUS) 0xC000011EL) +#endif + +#ifndef STATUS_TOO_MANY_OPENED_FILES +# define STATUS_TOO_MANY_OPENED_FILES ((NTSTATUS) 0xC000011FL) +#endif + +#ifndef STATUS_CANCELLED +# define STATUS_CANCELLED ((NTSTATUS) 0xC0000120L) +#endif + +#ifndef STATUS_CANNOT_DELETE +# define STATUS_CANNOT_DELETE ((NTSTATUS) 0xC0000121L) +#endif + +#ifndef STATUS_INVALID_COMPUTER_NAME +# define STATUS_INVALID_COMPUTER_NAME ((NTSTATUS) 0xC0000122L) +#endif + +#ifndef STATUS_FILE_DELETED +# define STATUS_FILE_DELETED ((NTSTATUS) 0xC0000123L) +#endif + +#ifndef STATUS_SPECIAL_ACCOUNT +# define STATUS_SPECIAL_ACCOUNT ((NTSTATUS) 0xC0000124L) +#endif + +#ifndef STATUS_SPECIAL_GROUP +# define STATUS_SPECIAL_GROUP ((NTSTATUS) 0xC0000125L) +#endif + +#ifndef STATUS_SPECIAL_USER +# define STATUS_SPECIAL_USER ((NTSTATUS) 0xC0000126L) +#endif + +#ifndef STATUS_MEMBERS_PRIMARY_GROUP +# define STATUS_MEMBERS_PRIMARY_GROUP ((NTSTATUS) 0xC0000127L) +#endif + +#ifndef STATUS_FILE_CLOSED +# define STATUS_FILE_CLOSED ((NTSTATUS) 0xC0000128L) +#endif + +#ifndef STATUS_TOO_MANY_THREADS +# define STATUS_TOO_MANY_THREADS ((NTSTATUS) 0xC0000129L) +#endif + +#ifndef STATUS_THREAD_NOT_IN_PROCESS +# define STATUS_THREAD_NOT_IN_PROCESS ((NTSTATUS) 0xC000012AL) +#endif + +#ifndef STATUS_TOKEN_ALREADY_IN_USE +# define STATUS_TOKEN_ALREADY_IN_USE ((NTSTATUS) 0xC000012BL) +#endif + +#ifndef STATUS_PAGEFILE_QUOTA_EXCEEDED +# define STATUS_PAGEFILE_QUOTA_EXCEEDED ((NTSTATUS) 0xC000012CL) +#endif + +#ifndef STATUS_COMMITMENT_LIMIT +# define STATUS_COMMITMENT_LIMIT ((NTSTATUS) 0xC000012DL) +#endif + +#ifndef STATUS_INVALID_IMAGE_LE_FORMAT +# define STATUS_INVALID_IMAGE_LE_FORMAT ((NTSTATUS) 0xC000012EL) +#endif + +#ifndef STATUS_INVALID_IMAGE_NOT_MZ +# define STATUS_INVALID_IMAGE_NOT_MZ ((NTSTATUS) 0xC000012FL) +#endif + +#ifndef STATUS_INVALID_IMAGE_PROTECT +# define STATUS_INVALID_IMAGE_PROTECT ((NTSTATUS) 0xC0000130L) +#endif + +#ifndef STATUS_INVALID_IMAGE_WIN_16 +# define STATUS_INVALID_IMAGE_WIN_16 ((NTSTATUS) 0xC0000131L) +#endif + +#ifndef STATUS_LOGON_SERVER_CONFLICT +# define STATUS_LOGON_SERVER_CONFLICT ((NTSTATUS) 0xC0000132L) +#endif + +#ifndef STATUS_TIME_DIFFERENCE_AT_DC +# define STATUS_TIME_DIFFERENCE_AT_DC ((NTSTATUS) 0xC0000133L) +#endif + +#ifndef STATUS_SYNCHRONIZATION_REQUIRED +# define STATUS_SYNCHRONIZATION_REQUIRED ((NTSTATUS) 0xC0000134L) +#endif + +#ifndef STATUS_DLL_NOT_FOUND +# define STATUS_DLL_NOT_FOUND ((NTSTATUS) 0xC0000135L) +#endif + +#ifndef STATUS_OPEN_FAILED +# define STATUS_OPEN_FAILED ((NTSTATUS) 0xC0000136L) +#endif + +#ifndef STATUS_IO_PRIVILEGE_FAILED +# define STATUS_IO_PRIVILEGE_FAILED ((NTSTATUS) 0xC0000137L) +#endif + +#ifndef STATUS_ORDINAL_NOT_FOUND +# define STATUS_ORDINAL_NOT_FOUND ((NTSTATUS) 0xC0000138L) +#endif + +#ifndef STATUS_ENTRYPOINT_NOT_FOUND +# define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xC0000139L) +#endif + +#ifndef STATUS_CONTROL_C_EXIT +# define STATUS_CONTROL_C_EXIT ((NTSTATUS) 0xC000013AL) +#endif + +#ifndef STATUS_LOCAL_DISCONNECT +# define STATUS_LOCAL_DISCONNECT ((NTSTATUS) 0xC000013BL) +#endif + +#ifndef STATUS_REMOTE_DISCONNECT +# define STATUS_REMOTE_DISCONNECT ((NTSTATUS) 0xC000013CL) +#endif + +#ifndef STATUS_REMOTE_RESOURCES +# define STATUS_REMOTE_RESOURCES ((NTSTATUS) 0xC000013DL) +#endif + +#ifndef STATUS_LINK_FAILED +# define STATUS_LINK_FAILED ((NTSTATUS) 0xC000013EL) +#endif + +#ifndef STATUS_LINK_TIMEOUT +# define STATUS_LINK_TIMEOUT ((NTSTATUS) 0xC000013FL) +#endif + +#ifndef STATUS_INVALID_CONNECTION +# define STATUS_INVALID_CONNECTION ((NTSTATUS) 0xC0000140L) +#endif + +#ifndef STATUS_INVALID_ADDRESS +# define STATUS_INVALID_ADDRESS ((NTSTATUS) 0xC0000141L) +#endif + +#ifndef STATUS_DLL_INIT_FAILED +# define STATUS_DLL_INIT_FAILED ((NTSTATUS) 0xC0000142L) +#endif + +#ifndef STATUS_MISSING_SYSTEMFILE +# define STATUS_MISSING_SYSTEMFILE ((NTSTATUS) 0xC0000143L) +#endif + +#ifndef STATUS_UNHANDLED_EXCEPTION +# define STATUS_UNHANDLED_EXCEPTION ((NTSTATUS) 0xC0000144L) +#endif + +#ifndef STATUS_APP_INIT_FAILURE +# define STATUS_APP_INIT_FAILURE ((NTSTATUS) 0xC0000145L) +#endif + +#ifndef STATUS_PAGEFILE_CREATE_FAILED +# define STATUS_PAGEFILE_CREATE_FAILED ((NTSTATUS) 0xC0000146L) +#endif + +#ifndef STATUS_NO_PAGEFILE +# define STATUS_NO_PAGEFILE ((NTSTATUS) 0xC0000147L) +#endif + +#ifndef STATUS_INVALID_LEVEL +# define STATUS_INVALID_LEVEL ((NTSTATUS) 0xC0000148L) +#endif + +#ifndef STATUS_WRONG_PASSWORD_CORE +# define STATUS_WRONG_PASSWORD_CORE ((NTSTATUS) 0xC0000149L) +#endif + +#ifndef STATUS_ILLEGAL_FLOAT_CONTEXT +# define STATUS_ILLEGAL_FLOAT_CONTEXT ((NTSTATUS) 0xC000014AL) +#endif + +#ifndef STATUS_PIPE_BROKEN +# define STATUS_PIPE_BROKEN ((NTSTATUS) 0xC000014BL) +#endif + +#ifndef STATUS_REGISTRY_CORRUPT +# define STATUS_REGISTRY_CORRUPT ((NTSTATUS) 0xC000014CL) +#endif + +#ifndef STATUS_REGISTRY_IO_FAILED +# define STATUS_REGISTRY_IO_FAILED ((NTSTATUS) 0xC000014DL) +#endif + +#ifndef STATUS_NO_EVENT_PAIR +# define STATUS_NO_EVENT_PAIR ((NTSTATUS) 0xC000014EL) +#endif + +#ifndef STATUS_UNRECOGNIZED_VOLUME +# define STATUS_UNRECOGNIZED_VOLUME ((NTSTATUS) 0xC000014FL) +#endif + +#ifndef STATUS_SERIAL_NO_DEVICE_INITED +# define STATUS_SERIAL_NO_DEVICE_INITED ((NTSTATUS) 0xC0000150L) +#endif + +#ifndef STATUS_NO_SUCH_ALIAS +# define STATUS_NO_SUCH_ALIAS ((NTSTATUS) 0xC0000151L) +#endif + +#ifndef STATUS_MEMBER_NOT_IN_ALIAS +# define STATUS_MEMBER_NOT_IN_ALIAS ((NTSTATUS) 0xC0000152L) +#endif + +#ifndef STATUS_MEMBER_IN_ALIAS +# define STATUS_MEMBER_IN_ALIAS ((NTSTATUS) 0xC0000153L) +#endif + +#ifndef STATUS_ALIAS_EXISTS +# define STATUS_ALIAS_EXISTS ((NTSTATUS) 0xC0000154L) +#endif + +#ifndef STATUS_LOGON_NOT_GRANTED +# define STATUS_LOGON_NOT_GRANTED ((NTSTATUS) 0xC0000155L) +#endif + +#ifndef STATUS_TOO_MANY_SECRETS +# define STATUS_TOO_MANY_SECRETS ((NTSTATUS) 0xC0000156L) +#endif + +#ifndef STATUS_SECRET_TOO_LONG +# define STATUS_SECRET_TOO_LONG ((NTSTATUS) 0xC0000157L) +#endif + +#ifndef STATUS_INTERNAL_DB_ERROR +# define STATUS_INTERNAL_DB_ERROR ((NTSTATUS) 0xC0000158L) +#endif + +#ifndef STATUS_FULLSCREEN_MODE +# define STATUS_FULLSCREEN_MODE ((NTSTATUS) 0xC0000159L) +#endif + +#ifndef STATUS_TOO_MANY_CONTEXT_IDS +# define STATUS_TOO_MANY_CONTEXT_IDS ((NTSTATUS) 0xC000015AL) +#endif + +#ifndef STATUS_LOGON_TYPE_NOT_GRANTED +# define STATUS_LOGON_TYPE_NOT_GRANTED ((NTSTATUS) 0xC000015BL) +#endif + +#ifndef STATUS_NOT_REGISTRY_FILE +# define STATUS_NOT_REGISTRY_FILE ((NTSTATUS) 0xC000015CL) +#endif + +#ifndef STATUS_NT_CROSS_ENCRYPTION_REQUIRED +# define STATUS_NT_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS) 0xC000015DL) +#endif + +#ifndef STATUS_DOMAIN_CTRLR_CONFIG_ERROR +# define STATUS_DOMAIN_CTRLR_CONFIG_ERROR ((NTSTATUS) 0xC000015EL) +#endif + +#ifndef STATUS_FT_MISSING_MEMBER +# define STATUS_FT_MISSING_MEMBER ((NTSTATUS) 0xC000015FL) +#endif + +#ifndef STATUS_ILL_FORMED_SERVICE_ENTRY +# define STATUS_ILL_FORMED_SERVICE_ENTRY ((NTSTATUS) 0xC0000160L) +#endif + +#ifndef STATUS_ILLEGAL_CHARACTER +# define STATUS_ILLEGAL_CHARACTER ((NTSTATUS) 0xC0000161L) +#endif + +#ifndef STATUS_UNMAPPABLE_CHARACTER +# define STATUS_UNMAPPABLE_CHARACTER ((NTSTATUS) 0xC0000162L) +#endif + +#ifndef STATUS_UNDEFINED_CHARACTER +# define STATUS_UNDEFINED_CHARACTER ((NTSTATUS) 0xC0000163L) +#endif + +#ifndef STATUS_FLOPPY_VOLUME +# define STATUS_FLOPPY_VOLUME ((NTSTATUS) 0xC0000164L) +#endif + +#ifndef STATUS_FLOPPY_ID_MARK_NOT_FOUND +# define STATUS_FLOPPY_ID_MARK_NOT_FOUND ((NTSTATUS) 0xC0000165L) +#endif + +#ifndef STATUS_FLOPPY_WRONG_CYLINDER +# define STATUS_FLOPPY_WRONG_CYLINDER ((NTSTATUS) 0xC0000166L) +#endif + +#ifndef STATUS_FLOPPY_UNKNOWN_ERROR +# define STATUS_FLOPPY_UNKNOWN_ERROR ((NTSTATUS) 0xC0000167L) +#endif + +#ifndef STATUS_FLOPPY_BAD_REGISTERS +# define STATUS_FLOPPY_BAD_REGISTERS ((NTSTATUS) 0xC0000168L) +#endif + +#ifndef STATUS_DISK_RECALIBRATE_FAILED +# define STATUS_DISK_RECALIBRATE_FAILED ((NTSTATUS) 0xC0000169L) +#endif + +#ifndef STATUS_DISK_OPERATION_FAILED +# define STATUS_DISK_OPERATION_FAILED ((NTSTATUS) 0xC000016AL) +#endif + +#ifndef STATUS_DISK_RESET_FAILED +# define STATUS_DISK_RESET_FAILED ((NTSTATUS) 0xC000016BL) +#endif + +#ifndef STATUS_SHARED_IRQ_BUSY +# define STATUS_SHARED_IRQ_BUSY ((NTSTATUS) 0xC000016CL) +#endif + +#ifndef STATUS_FT_ORPHANING +# define STATUS_FT_ORPHANING ((NTSTATUS) 0xC000016DL) +#endif + +#ifndef STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT +# define STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT ((NTSTATUS) 0xC000016EL) +#endif + +#ifndef STATUS_PARTITION_FAILURE +# define STATUS_PARTITION_FAILURE ((NTSTATUS) 0xC0000172L) +#endif + +#ifndef STATUS_INVALID_BLOCK_LENGTH +# define STATUS_INVALID_BLOCK_LENGTH ((NTSTATUS) 0xC0000173L) +#endif + +#ifndef STATUS_DEVICE_NOT_PARTITIONED +# define STATUS_DEVICE_NOT_PARTITIONED ((NTSTATUS) 0xC0000174L) +#endif + +#ifndef STATUS_UNABLE_TO_LOCK_MEDIA +# define STATUS_UNABLE_TO_LOCK_MEDIA ((NTSTATUS) 0xC0000175L) +#endif + +#ifndef STATUS_UNABLE_TO_UNLOAD_MEDIA +# define STATUS_UNABLE_TO_UNLOAD_MEDIA ((NTSTATUS) 0xC0000176L) +#endif + +#ifndef STATUS_EOM_OVERFLOW +# define STATUS_EOM_OVERFLOW ((NTSTATUS) 0xC0000177L) +#endif + +#ifndef STATUS_NO_MEDIA +# define STATUS_NO_MEDIA ((NTSTATUS) 0xC0000178L) +#endif + +#ifndef STATUS_NO_SUCH_MEMBER +# define STATUS_NO_SUCH_MEMBER ((NTSTATUS) 0xC000017AL) +#endif + +#ifndef STATUS_INVALID_MEMBER +# define STATUS_INVALID_MEMBER ((NTSTATUS) 0xC000017BL) +#endif + +#ifndef STATUS_KEY_DELETED +# define STATUS_KEY_DELETED ((NTSTATUS) 0xC000017CL) +#endif + +#ifndef STATUS_NO_LOG_SPACE +# define STATUS_NO_LOG_SPACE ((NTSTATUS) 0xC000017DL) +#endif + +#ifndef STATUS_TOO_MANY_SIDS +# define STATUS_TOO_MANY_SIDS ((NTSTATUS) 0xC000017EL) +#endif + +#ifndef STATUS_LM_CROSS_ENCRYPTION_REQUIRED +# define STATUS_LM_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS) 0xC000017FL) +#endif + +#ifndef STATUS_KEY_HAS_CHILDREN +# define STATUS_KEY_HAS_CHILDREN ((NTSTATUS) 0xC0000180L) +#endif + +#ifndef STATUS_CHILD_MUST_BE_VOLATILE +# define STATUS_CHILD_MUST_BE_VOLATILE ((NTSTATUS) 0xC0000181L) +#endif + +#ifndef STATUS_DEVICE_CONFIGURATION_ERROR +# define STATUS_DEVICE_CONFIGURATION_ERROR ((NTSTATUS) 0xC0000182L) +#endif + +#ifndef STATUS_DRIVER_INTERNAL_ERROR +# define STATUS_DRIVER_INTERNAL_ERROR ((NTSTATUS) 0xC0000183L) +#endif + +#ifndef STATUS_INVALID_DEVICE_STATE +# define STATUS_INVALID_DEVICE_STATE ((NTSTATUS) 0xC0000184L) +#endif + +#ifndef STATUS_IO_DEVICE_ERROR +# define STATUS_IO_DEVICE_ERROR ((NTSTATUS) 0xC0000185L) +#endif + +#ifndef STATUS_DEVICE_PROTOCOL_ERROR +# define STATUS_DEVICE_PROTOCOL_ERROR ((NTSTATUS) 0xC0000186L) +#endif + +#ifndef STATUS_BACKUP_CONTROLLER +# define STATUS_BACKUP_CONTROLLER ((NTSTATUS) 0xC0000187L) +#endif + +#ifndef STATUS_LOG_FILE_FULL +# define STATUS_LOG_FILE_FULL ((NTSTATUS) 0xC0000188L) +#endif + +#ifndef STATUS_TOO_LATE +# define STATUS_TOO_LATE ((NTSTATUS) 0xC0000189L) +#endif + +#ifndef STATUS_NO_TRUST_LSA_SECRET +# define STATUS_NO_TRUST_LSA_SECRET ((NTSTATUS) 0xC000018AL) +#endif + +#ifndef STATUS_NO_TRUST_SAM_ACCOUNT +# define STATUS_NO_TRUST_SAM_ACCOUNT ((NTSTATUS) 0xC000018BL) +#endif + +#ifndef STATUS_TRUSTED_DOMAIN_FAILURE +# define STATUS_TRUSTED_DOMAIN_FAILURE ((NTSTATUS) 0xC000018CL) +#endif + +#ifndef STATUS_TRUSTED_RELATIONSHIP_FAILURE +# define STATUS_TRUSTED_RELATIONSHIP_FAILURE ((NTSTATUS) 0xC000018DL) +#endif + +#ifndef STATUS_EVENTLOG_FILE_CORRUPT +# define STATUS_EVENTLOG_FILE_CORRUPT ((NTSTATUS) 0xC000018EL) +#endif + +#ifndef STATUS_EVENTLOG_CANT_START +# define STATUS_EVENTLOG_CANT_START ((NTSTATUS) 0xC000018FL) +#endif + +#ifndef STATUS_TRUST_FAILURE +# define STATUS_TRUST_FAILURE ((NTSTATUS) 0xC0000190L) +#endif + +#ifndef STATUS_MUTANT_LIMIT_EXCEEDED +# define STATUS_MUTANT_LIMIT_EXCEEDED ((NTSTATUS) 0xC0000191L) +#endif + +#ifndef STATUS_NETLOGON_NOT_STARTED +# define STATUS_NETLOGON_NOT_STARTED ((NTSTATUS) 0xC0000192L) +#endif + +#ifndef STATUS_ACCOUNT_EXPIRED +# define STATUS_ACCOUNT_EXPIRED ((NTSTATUS) 0xC0000193L) +#endif + +#ifndef STATUS_POSSIBLE_DEADLOCK +# define STATUS_POSSIBLE_DEADLOCK ((NTSTATUS) 0xC0000194L) +#endif + +#ifndef STATUS_NETWORK_CREDENTIAL_CONFLICT +# define STATUS_NETWORK_CREDENTIAL_CONFLICT ((NTSTATUS) 0xC0000195L) +#endif + +#ifndef STATUS_REMOTE_SESSION_LIMIT +# define STATUS_REMOTE_SESSION_LIMIT ((NTSTATUS) 0xC0000196L) +#endif + +#ifndef STATUS_EVENTLOG_FILE_CHANGED +# define STATUS_EVENTLOG_FILE_CHANGED ((NTSTATUS) 0xC0000197L) +#endif + +#ifndef STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT +# define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT ((NTSTATUS) 0xC0000198L) +#endif + +#ifndef STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT +# define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT ((NTSTATUS) 0xC0000199L) +#endif + +#ifndef STATUS_NOLOGON_SERVER_TRUST_ACCOUNT +# define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT ((NTSTATUS) 0xC000019AL) +#endif + +#ifndef STATUS_DOMAIN_TRUST_INCONSISTENT +# define STATUS_DOMAIN_TRUST_INCONSISTENT ((NTSTATUS) 0xC000019BL) +#endif + +#ifndef STATUS_FS_DRIVER_REQUIRED +# define STATUS_FS_DRIVER_REQUIRED ((NTSTATUS) 0xC000019CL) +#endif + +#ifndef STATUS_IMAGE_ALREADY_LOADED_AS_DLL +# define STATUS_IMAGE_ALREADY_LOADED_AS_DLL ((NTSTATUS) 0xC000019DL) +#endif + +#ifndef STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING +# define STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING ((NTSTATUS) 0xC000019EL) +#endif + +#ifndef STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME +# define STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME ((NTSTATUS) 0xC000019FL) +#endif + +#ifndef STATUS_SECURITY_STREAM_IS_INCONSISTENT +# define STATUS_SECURITY_STREAM_IS_INCONSISTENT ((NTSTATUS) 0xC00001A0L) +#endif + +#ifndef STATUS_INVALID_LOCK_RANGE +# define STATUS_INVALID_LOCK_RANGE ((NTSTATUS) 0xC00001A1L) +#endif + +#ifndef STATUS_INVALID_ACE_CONDITION +# define STATUS_INVALID_ACE_CONDITION ((NTSTATUS) 0xC00001A2L) +#endif + +#ifndef STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT +# define STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT ((NTSTATUS) 0xC00001A3L) +#endif + +#ifndef STATUS_NOTIFICATION_GUID_ALREADY_DEFINED +# define STATUS_NOTIFICATION_GUID_ALREADY_DEFINED ((NTSTATUS) 0xC00001A4L) +#endif + +#ifndef STATUS_NETWORK_OPEN_RESTRICTION +# define STATUS_NETWORK_OPEN_RESTRICTION ((NTSTATUS) 0xC0000201L) +#endif + +#ifndef STATUS_NO_USER_SESSION_KEY +# define STATUS_NO_USER_SESSION_KEY ((NTSTATUS) 0xC0000202L) +#endif + +#ifndef STATUS_USER_SESSION_DELETED +# define STATUS_USER_SESSION_DELETED ((NTSTATUS) 0xC0000203L) +#endif + +#ifndef STATUS_RESOURCE_LANG_NOT_FOUND +# define STATUS_RESOURCE_LANG_NOT_FOUND ((NTSTATUS) 0xC0000204L) +#endif + +#ifndef STATUS_INSUFF_SERVER_RESOURCES +# define STATUS_INSUFF_SERVER_RESOURCES ((NTSTATUS) 0xC0000205L) +#endif + +#ifndef STATUS_INVALID_BUFFER_SIZE +# define STATUS_INVALID_BUFFER_SIZE ((NTSTATUS) 0xC0000206L) +#endif + +#ifndef STATUS_INVALID_ADDRESS_COMPONENT +# define STATUS_INVALID_ADDRESS_COMPONENT ((NTSTATUS) 0xC0000207L) +#endif + +#ifndef STATUS_INVALID_ADDRESS_WILDCARD +# define STATUS_INVALID_ADDRESS_WILDCARD ((NTSTATUS) 0xC0000208L) +#endif + +#ifndef STATUS_TOO_MANY_ADDRESSES +# define STATUS_TOO_MANY_ADDRESSES ((NTSTATUS) 0xC0000209L) +#endif + +#ifndef STATUS_ADDRESS_ALREADY_EXISTS +# define STATUS_ADDRESS_ALREADY_EXISTS ((NTSTATUS) 0xC000020AL) +#endif + +#ifndef STATUS_ADDRESS_CLOSED +# define STATUS_ADDRESS_CLOSED ((NTSTATUS) 0xC000020BL) +#endif + +#ifndef STATUS_CONNECTION_DISCONNECTED +# define STATUS_CONNECTION_DISCONNECTED ((NTSTATUS) 0xC000020CL) +#endif + +#ifndef STATUS_CONNECTION_RESET +# define STATUS_CONNECTION_RESET ((NTSTATUS) 0xC000020DL) +#endif + +#ifndef STATUS_TOO_MANY_NODES +# define STATUS_TOO_MANY_NODES ((NTSTATUS) 0xC000020EL) +#endif + +#ifndef STATUS_TRANSACTION_ABORTED +# define STATUS_TRANSACTION_ABORTED ((NTSTATUS) 0xC000020FL) +#endif + +#ifndef STATUS_TRANSACTION_TIMED_OUT +# define STATUS_TRANSACTION_TIMED_OUT ((NTSTATUS) 0xC0000210L) +#endif + +#ifndef STATUS_TRANSACTION_NO_RELEASE +# define STATUS_TRANSACTION_NO_RELEASE ((NTSTATUS) 0xC0000211L) +#endif + +#ifndef STATUS_TRANSACTION_NO_MATCH +# define STATUS_TRANSACTION_NO_MATCH ((NTSTATUS) 0xC0000212L) +#endif + +#ifndef STATUS_TRANSACTION_RESPONDED +# define STATUS_TRANSACTION_RESPONDED ((NTSTATUS) 0xC0000213L) +#endif + +#ifndef STATUS_TRANSACTION_INVALID_ID +# define STATUS_TRANSACTION_INVALID_ID ((NTSTATUS) 0xC0000214L) +#endif + +#ifndef STATUS_TRANSACTION_INVALID_TYPE +# define STATUS_TRANSACTION_INVALID_TYPE ((NTSTATUS) 0xC0000215L) +#endif + +#ifndef STATUS_NOT_SERVER_SESSION +# define STATUS_NOT_SERVER_SESSION ((NTSTATUS) 0xC0000216L) +#endif + +#ifndef STATUS_NOT_CLIENT_SESSION +# define STATUS_NOT_CLIENT_SESSION ((NTSTATUS) 0xC0000217L) +#endif + +#ifndef STATUS_CANNOT_LOAD_REGISTRY_FILE +# define STATUS_CANNOT_LOAD_REGISTRY_FILE ((NTSTATUS) 0xC0000218L) +#endif + +#ifndef STATUS_DEBUG_ATTACH_FAILED +# define STATUS_DEBUG_ATTACH_FAILED ((NTSTATUS) 0xC0000219L) +#endif + +#ifndef STATUS_SYSTEM_PROCESS_TERMINATED +# define STATUS_SYSTEM_PROCESS_TERMINATED ((NTSTATUS) 0xC000021AL) +#endif + +#ifndef STATUS_DATA_NOT_ACCEPTED +# define STATUS_DATA_NOT_ACCEPTED ((NTSTATUS) 0xC000021BL) +#endif + +#ifndef STATUS_NO_BROWSER_SERVERS_FOUND +# define STATUS_NO_BROWSER_SERVERS_FOUND ((NTSTATUS) 0xC000021CL) +#endif + +#ifndef STATUS_VDM_HARD_ERROR +# define STATUS_VDM_HARD_ERROR ((NTSTATUS) 0xC000021DL) +#endif + +#ifndef STATUS_DRIVER_CANCEL_TIMEOUT +# define STATUS_DRIVER_CANCEL_TIMEOUT ((NTSTATUS) 0xC000021EL) +#endif + +#ifndef STATUS_REPLY_MESSAGE_MISMATCH +# define STATUS_REPLY_MESSAGE_MISMATCH ((NTSTATUS) 0xC000021FL) +#endif + +#ifndef STATUS_MAPPED_ALIGNMENT +# define STATUS_MAPPED_ALIGNMENT ((NTSTATUS) 0xC0000220L) +#endif + +#ifndef STATUS_IMAGE_CHECKSUM_MISMATCH +# define STATUS_IMAGE_CHECKSUM_MISMATCH ((NTSTATUS) 0xC0000221L) +#endif + +#ifndef STATUS_LOST_WRITEBEHIND_DATA +# define STATUS_LOST_WRITEBEHIND_DATA ((NTSTATUS) 0xC0000222L) +#endif + +#ifndef STATUS_CLIENT_SERVER_PARAMETERS_INVALID +# define STATUS_CLIENT_SERVER_PARAMETERS_INVALID ((NTSTATUS) 0xC0000223L) +#endif + +#ifndef STATUS_PASSWORD_MUST_CHANGE +# define STATUS_PASSWORD_MUST_CHANGE ((NTSTATUS) 0xC0000224L) +#endif + +#ifndef STATUS_NOT_FOUND +# define STATUS_NOT_FOUND ((NTSTATUS) 0xC0000225L) +#endif + +#ifndef STATUS_NOT_TINY_STREAM +# define STATUS_NOT_TINY_STREAM ((NTSTATUS) 0xC0000226L) +#endif + +#ifndef STATUS_RECOVERY_FAILURE +# define STATUS_RECOVERY_FAILURE ((NTSTATUS) 0xC0000227L) +#endif + +#ifndef STATUS_STACK_OVERFLOW_READ +# define STATUS_STACK_OVERFLOW_READ ((NTSTATUS) 0xC0000228L) +#endif + +#ifndef STATUS_FAIL_CHECK +# define STATUS_FAIL_CHECK ((NTSTATUS) 0xC0000229L) +#endif + +#ifndef STATUS_DUPLICATE_OBJECTID +# define STATUS_DUPLICATE_OBJECTID ((NTSTATUS) 0xC000022AL) +#endif + +#ifndef STATUS_OBJECTID_EXISTS +# define STATUS_OBJECTID_EXISTS ((NTSTATUS) 0xC000022BL) +#endif + +#ifndef STATUS_CONVERT_TO_LARGE +# define STATUS_CONVERT_TO_LARGE ((NTSTATUS) 0xC000022CL) +#endif + +#ifndef STATUS_RETRY +# define STATUS_RETRY ((NTSTATUS) 0xC000022DL) +#endif + +#ifndef STATUS_FOUND_OUT_OF_SCOPE +# define STATUS_FOUND_OUT_OF_SCOPE ((NTSTATUS) 0xC000022EL) +#endif + +#ifndef STATUS_ALLOCATE_BUCKET +# define STATUS_ALLOCATE_BUCKET ((NTSTATUS) 0xC000022FL) +#endif + +#ifndef STATUS_PROPSET_NOT_FOUND +# define STATUS_PROPSET_NOT_FOUND ((NTSTATUS) 0xC0000230L) +#endif + +#ifndef STATUS_MARSHALL_OVERFLOW +# define STATUS_MARSHALL_OVERFLOW ((NTSTATUS) 0xC0000231L) +#endif + +#ifndef STATUS_INVALID_VARIANT +# define STATUS_INVALID_VARIANT ((NTSTATUS) 0xC0000232L) +#endif + +#ifndef STATUS_DOMAIN_CONTROLLER_NOT_FOUND +# define STATUS_DOMAIN_CONTROLLER_NOT_FOUND ((NTSTATUS) 0xC0000233L) +#endif + +#ifndef STATUS_ACCOUNT_LOCKED_OUT +# define STATUS_ACCOUNT_LOCKED_OUT ((NTSTATUS) 0xC0000234L) +#endif + +#ifndef STATUS_HANDLE_NOT_CLOSABLE +# define STATUS_HANDLE_NOT_CLOSABLE ((NTSTATUS) 0xC0000235L) +#endif + +#ifndef STATUS_CONNECTION_REFUSED +# define STATUS_CONNECTION_REFUSED ((NTSTATUS) 0xC0000236L) +#endif + +#ifndef STATUS_GRACEFUL_DISCONNECT +# define STATUS_GRACEFUL_DISCONNECT ((NTSTATUS) 0xC0000237L) +#endif + +#ifndef STATUS_ADDRESS_ALREADY_ASSOCIATED +# define STATUS_ADDRESS_ALREADY_ASSOCIATED ((NTSTATUS) 0xC0000238L) +#endif + +#ifndef STATUS_ADDRESS_NOT_ASSOCIATED +# define STATUS_ADDRESS_NOT_ASSOCIATED ((NTSTATUS) 0xC0000239L) +#endif + +#ifndef STATUS_CONNECTION_INVALID +# define STATUS_CONNECTION_INVALID ((NTSTATUS) 0xC000023AL) +#endif + +#ifndef STATUS_CONNECTION_ACTIVE +# define STATUS_CONNECTION_ACTIVE ((NTSTATUS) 0xC000023BL) +#endif + +#ifndef STATUS_NETWORK_UNREACHABLE +# define STATUS_NETWORK_UNREACHABLE ((NTSTATUS) 0xC000023CL) +#endif + +#ifndef STATUS_HOST_UNREACHABLE +# define STATUS_HOST_UNREACHABLE ((NTSTATUS) 0xC000023DL) +#endif + +#ifndef STATUS_PROTOCOL_UNREACHABLE +# define STATUS_PROTOCOL_UNREACHABLE ((NTSTATUS) 0xC000023EL) +#endif + +#ifndef STATUS_PORT_UNREACHABLE +# define STATUS_PORT_UNREACHABLE ((NTSTATUS) 0xC000023FL) +#endif + +#ifndef STATUS_REQUEST_ABORTED +# define STATUS_REQUEST_ABORTED ((NTSTATUS) 0xC0000240L) +#endif + +#ifndef STATUS_CONNECTION_ABORTED +# define STATUS_CONNECTION_ABORTED ((NTSTATUS) 0xC0000241L) +#endif + +#ifndef STATUS_BAD_COMPRESSION_BUFFER +# define STATUS_BAD_COMPRESSION_BUFFER ((NTSTATUS) 0xC0000242L) +#endif + +#ifndef STATUS_USER_MAPPED_FILE +# define STATUS_USER_MAPPED_FILE ((NTSTATUS) 0xC0000243L) +#endif + +#ifndef STATUS_AUDIT_FAILED +# define STATUS_AUDIT_FAILED ((NTSTATUS) 0xC0000244L) +#endif + +#ifndef STATUS_TIMER_RESOLUTION_NOT_SET +# define STATUS_TIMER_RESOLUTION_NOT_SET ((NTSTATUS) 0xC0000245L) +#endif + +#ifndef STATUS_CONNECTION_COUNT_LIMIT +# define STATUS_CONNECTION_COUNT_LIMIT ((NTSTATUS) 0xC0000246L) +#endif + +#ifndef STATUS_LOGIN_TIME_RESTRICTION +# define STATUS_LOGIN_TIME_RESTRICTION ((NTSTATUS) 0xC0000247L) +#endif + +#ifndef STATUS_LOGIN_WKSTA_RESTRICTION +# define STATUS_LOGIN_WKSTA_RESTRICTION ((NTSTATUS) 0xC0000248L) +#endif + +#ifndef STATUS_IMAGE_MP_UP_MISMATCH +# define STATUS_IMAGE_MP_UP_MISMATCH ((NTSTATUS) 0xC0000249L) +#endif + +#ifndef STATUS_INSUFFICIENT_LOGON_INFO +# define STATUS_INSUFFICIENT_LOGON_INFO ((NTSTATUS) 0xC0000250L) +#endif + +#ifndef STATUS_BAD_DLL_ENTRYPOINT +# define STATUS_BAD_DLL_ENTRYPOINT ((NTSTATUS) 0xC0000251L) +#endif + +#ifndef STATUS_BAD_SERVICE_ENTRYPOINT +# define STATUS_BAD_SERVICE_ENTRYPOINT ((NTSTATUS) 0xC0000252L) +#endif + +#ifndef STATUS_LPC_REPLY_LOST +# define STATUS_LPC_REPLY_LOST ((NTSTATUS) 0xC0000253L) +#endif + +#ifndef STATUS_IP_ADDRESS_CONFLICT1 +# define STATUS_IP_ADDRESS_CONFLICT1 ((NTSTATUS) 0xC0000254L) +#endif + +#ifndef STATUS_IP_ADDRESS_CONFLICT2 +# define STATUS_IP_ADDRESS_CONFLICT2 ((NTSTATUS) 0xC0000255L) +#endif + +#ifndef STATUS_REGISTRY_QUOTA_LIMIT +# define STATUS_REGISTRY_QUOTA_LIMIT ((NTSTATUS) 0xC0000256L) +#endif + +#ifndef STATUS_PATH_NOT_COVERED +# define STATUS_PATH_NOT_COVERED ((NTSTATUS) 0xC0000257L) +#endif + +#ifndef STATUS_NO_CALLBACK_ACTIVE +# define STATUS_NO_CALLBACK_ACTIVE ((NTSTATUS) 0xC0000258L) +#endif + +#ifndef STATUS_LICENSE_QUOTA_EXCEEDED +# define STATUS_LICENSE_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000259L) +#endif + +#ifndef STATUS_PWD_TOO_SHORT +# define STATUS_PWD_TOO_SHORT ((NTSTATUS) 0xC000025AL) +#endif + +#ifndef STATUS_PWD_TOO_RECENT +# define STATUS_PWD_TOO_RECENT ((NTSTATUS) 0xC000025BL) +#endif + +#ifndef STATUS_PWD_HISTORY_CONFLICT +# define STATUS_PWD_HISTORY_CONFLICT ((NTSTATUS) 0xC000025CL) +#endif + +#ifndef STATUS_PLUGPLAY_NO_DEVICE +# define STATUS_PLUGPLAY_NO_DEVICE ((NTSTATUS) 0xC000025EL) +#endif + +#ifndef STATUS_UNSUPPORTED_COMPRESSION +# define STATUS_UNSUPPORTED_COMPRESSION ((NTSTATUS) 0xC000025FL) +#endif + +#ifndef STATUS_INVALID_HW_PROFILE +# define STATUS_INVALID_HW_PROFILE ((NTSTATUS) 0xC0000260L) +#endif + +#ifndef STATUS_INVALID_PLUGPLAY_DEVICE_PATH +# define STATUS_INVALID_PLUGPLAY_DEVICE_PATH ((NTSTATUS) 0xC0000261L) +#endif + +#ifndef STATUS_DRIVER_ORDINAL_NOT_FOUND +# define STATUS_DRIVER_ORDINAL_NOT_FOUND ((NTSTATUS) 0xC0000262L) +#endif + +#ifndef STATUS_DRIVER_ENTRYPOINT_NOT_FOUND +# define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xC0000263L) +#endif + +#ifndef STATUS_RESOURCE_NOT_OWNED +# define STATUS_RESOURCE_NOT_OWNED ((NTSTATUS) 0xC0000264L) +#endif + +#ifndef STATUS_TOO_MANY_LINKS +# define STATUS_TOO_MANY_LINKS ((NTSTATUS) 0xC0000265L) +#endif + +#ifndef STATUS_QUOTA_LIST_INCONSISTENT +# define STATUS_QUOTA_LIST_INCONSISTENT ((NTSTATUS) 0xC0000266L) +#endif + +#ifndef STATUS_FILE_IS_OFFLINE +# define STATUS_FILE_IS_OFFLINE ((NTSTATUS) 0xC0000267L) +#endif + +#ifndef STATUS_EVALUATION_EXPIRATION +# define STATUS_EVALUATION_EXPIRATION ((NTSTATUS) 0xC0000268L) +#endif + +#ifndef STATUS_ILLEGAL_DLL_RELOCATION +# define STATUS_ILLEGAL_DLL_RELOCATION ((NTSTATUS) 0xC0000269L) +#endif + +#ifndef STATUS_LICENSE_VIOLATION +# define STATUS_LICENSE_VIOLATION ((NTSTATUS) 0xC000026AL) +#endif + +#ifndef STATUS_DLL_INIT_FAILED_LOGOFF +# define STATUS_DLL_INIT_FAILED_LOGOFF ((NTSTATUS) 0xC000026BL) +#endif + +#ifndef STATUS_DRIVER_UNABLE_TO_LOAD +# define STATUS_DRIVER_UNABLE_TO_LOAD ((NTSTATUS) 0xC000026CL) +#endif + +#ifndef STATUS_DFS_UNAVAILABLE +# define STATUS_DFS_UNAVAILABLE ((NTSTATUS) 0xC000026DL) +#endif + +#ifndef STATUS_VOLUME_DISMOUNTED +# define STATUS_VOLUME_DISMOUNTED ((NTSTATUS) 0xC000026EL) +#endif + +#ifndef STATUS_WX86_INTERNAL_ERROR +# define STATUS_WX86_INTERNAL_ERROR ((NTSTATUS) 0xC000026FL) +#endif + +#ifndef STATUS_WX86_FLOAT_STACK_CHECK +# define STATUS_WX86_FLOAT_STACK_CHECK ((NTSTATUS) 0xC0000270L) +#endif + +#ifndef STATUS_VALIDATE_CONTINUE +# define STATUS_VALIDATE_CONTINUE ((NTSTATUS) 0xC0000271L) +#endif + +#ifndef STATUS_NO_MATCH +# define STATUS_NO_MATCH ((NTSTATUS) 0xC0000272L) +#endif + +#ifndef STATUS_NO_MORE_MATCHES +# define STATUS_NO_MORE_MATCHES ((NTSTATUS) 0xC0000273L) +#endif + +#ifndef STATUS_NOT_A_REPARSE_POINT +# define STATUS_NOT_A_REPARSE_POINT ((NTSTATUS) 0xC0000275L) +#endif + +#ifndef STATUS_IO_REPARSE_TAG_INVALID +# define STATUS_IO_REPARSE_TAG_INVALID ((NTSTATUS) 0xC0000276L) +#endif + +#ifndef STATUS_IO_REPARSE_TAG_MISMATCH +# define STATUS_IO_REPARSE_TAG_MISMATCH ((NTSTATUS) 0xC0000277L) +#endif + +#ifndef STATUS_IO_REPARSE_DATA_INVALID +# define STATUS_IO_REPARSE_DATA_INVALID ((NTSTATUS) 0xC0000278L) +#endif + +#ifndef STATUS_IO_REPARSE_TAG_NOT_HANDLED +# define STATUS_IO_REPARSE_TAG_NOT_HANDLED ((NTSTATUS) 0xC0000279L) +#endif + +#ifndef STATUS_REPARSE_POINT_NOT_RESOLVED +# define STATUS_REPARSE_POINT_NOT_RESOLVED ((NTSTATUS) 0xC0000280L) +#endif + +#ifndef STATUS_DIRECTORY_IS_A_REPARSE_POINT +# define STATUS_DIRECTORY_IS_A_REPARSE_POINT ((NTSTATUS) 0xC0000281L) +#endif + +#ifndef STATUS_RANGE_LIST_CONFLICT +# define STATUS_RANGE_LIST_CONFLICT ((NTSTATUS) 0xC0000282L) +#endif + +#ifndef STATUS_SOURCE_ELEMENT_EMPTY +# define STATUS_SOURCE_ELEMENT_EMPTY ((NTSTATUS) 0xC0000283L) +#endif + +#ifndef STATUS_DESTINATION_ELEMENT_FULL +# define STATUS_DESTINATION_ELEMENT_FULL ((NTSTATUS) 0xC0000284L) +#endif + +#ifndef STATUS_ILLEGAL_ELEMENT_ADDRESS +# define STATUS_ILLEGAL_ELEMENT_ADDRESS ((NTSTATUS) 0xC0000285L) +#endif + +#ifndef STATUS_MAGAZINE_NOT_PRESENT +# define STATUS_MAGAZINE_NOT_PRESENT ((NTSTATUS) 0xC0000286L) +#endif + +#ifndef STATUS_REINITIALIZATION_NEEDED +# define STATUS_REINITIALIZATION_NEEDED ((NTSTATUS) 0xC0000287L) +#endif + +#ifndef STATUS_DEVICE_REQUIRES_CLEANING +# define STATUS_DEVICE_REQUIRES_CLEANING ((NTSTATUS) 0x80000288L) +#endif + +#ifndef STATUS_DEVICE_DOOR_OPEN +# define STATUS_DEVICE_DOOR_OPEN ((NTSTATUS) 0x80000289L) +#endif + +#ifndef STATUS_ENCRYPTION_FAILED +# define STATUS_ENCRYPTION_FAILED ((NTSTATUS) 0xC000028AL) +#endif + +#ifndef STATUS_DECRYPTION_FAILED +# define STATUS_DECRYPTION_FAILED ((NTSTATUS) 0xC000028BL) +#endif + +#ifndef STATUS_RANGE_NOT_FOUND +# define STATUS_RANGE_NOT_FOUND ((NTSTATUS) 0xC000028CL) +#endif + +#ifndef STATUS_NO_RECOVERY_POLICY +# define STATUS_NO_RECOVERY_POLICY ((NTSTATUS) 0xC000028DL) +#endif + +#ifndef STATUS_NO_EFS +# define STATUS_NO_EFS ((NTSTATUS) 0xC000028EL) +#endif + +#ifndef STATUS_WRONG_EFS +# define STATUS_WRONG_EFS ((NTSTATUS) 0xC000028FL) +#endif + +#ifndef STATUS_NO_USER_KEYS +# define STATUS_NO_USER_KEYS ((NTSTATUS) 0xC0000290L) +#endif + +#ifndef STATUS_FILE_NOT_ENCRYPTED +# define STATUS_FILE_NOT_ENCRYPTED ((NTSTATUS) 0xC0000291L) +#endif + +#ifndef STATUS_NOT_EXPORT_FORMAT +# define STATUS_NOT_EXPORT_FORMAT ((NTSTATUS) 0xC0000292L) +#endif + +#ifndef STATUS_FILE_ENCRYPTED +# define STATUS_FILE_ENCRYPTED ((NTSTATUS) 0xC0000293L) +#endif + +#ifndef STATUS_WAKE_SYSTEM +# define STATUS_WAKE_SYSTEM ((NTSTATUS) 0x40000294L) +#endif + +#ifndef STATUS_WMI_GUID_NOT_FOUND +# define STATUS_WMI_GUID_NOT_FOUND ((NTSTATUS) 0xC0000295L) +#endif + +#ifndef STATUS_WMI_INSTANCE_NOT_FOUND +# define STATUS_WMI_INSTANCE_NOT_FOUND ((NTSTATUS) 0xC0000296L) +#endif + +#ifndef STATUS_WMI_ITEMID_NOT_FOUND +# define STATUS_WMI_ITEMID_NOT_FOUND ((NTSTATUS) 0xC0000297L) +#endif + +#ifndef STATUS_WMI_TRY_AGAIN +# define STATUS_WMI_TRY_AGAIN ((NTSTATUS) 0xC0000298L) +#endif + +#ifndef STATUS_SHARED_POLICY +# define STATUS_SHARED_POLICY ((NTSTATUS) 0xC0000299L) +#endif + +#ifndef STATUS_POLICY_OBJECT_NOT_FOUND +# define STATUS_POLICY_OBJECT_NOT_FOUND ((NTSTATUS) 0xC000029AL) +#endif + +#ifndef STATUS_POLICY_ONLY_IN_DS +# define STATUS_POLICY_ONLY_IN_DS ((NTSTATUS) 0xC000029BL) +#endif + +#ifndef STATUS_VOLUME_NOT_UPGRADED +# define STATUS_VOLUME_NOT_UPGRADED ((NTSTATUS) 0xC000029CL) +#endif + +#ifndef STATUS_REMOTE_STORAGE_NOT_ACTIVE +# define STATUS_REMOTE_STORAGE_NOT_ACTIVE ((NTSTATUS) 0xC000029DL) +#endif + +#ifndef STATUS_REMOTE_STORAGE_MEDIA_ERROR +# define STATUS_REMOTE_STORAGE_MEDIA_ERROR ((NTSTATUS) 0xC000029EL) +#endif + +#ifndef STATUS_NO_TRACKING_SERVICE +# define STATUS_NO_TRACKING_SERVICE ((NTSTATUS) 0xC000029FL) +#endif + +#ifndef STATUS_SERVER_SID_MISMATCH +# define STATUS_SERVER_SID_MISMATCH ((NTSTATUS) 0xC00002A0L) +#endif + +#ifndef STATUS_DS_NO_ATTRIBUTE_OR_VALUE +# define STATUS_DS_NO_ATTRIBUTE_OR_VALUE ((NTSTATUS) 0xC00002A1L) +#endif + +#ifndef STATUS_DS_INVALID_ATTRIBUTE_SYNTAX +# define STATUS_DS_INVALID_ATTRIBUTE_SYNTAX ((NTSTATUS) 0xC00002A2L) +#endif + +#ifndef STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED +# define STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED ((NTSTATUS) 0xC00002A3L) +#endif + +#ifndef STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS +# define STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS ((NTSTATUS) 0xC00002A4L) +#endif + +#ifndef STATUS_DS_BUSY +# define STATUS_DS_BUSY ((NTSTATUS) 0xC00002A5L) +#endif + +#ifndef STATUS_DS_UNAVAILABLE +# define STATUS_DS_UNAVAILABLE ((NTSTATUS) 0xC00002A6L) +#endif + +#ifndef STATUS_DS_NO_RIDS_ALLOCATED +# define STATUS_DS_NO_RIDS_ALLOCATED ((NTSTATUS) 0xC00002A7L) +#endif + +#ifndef STATUS_DS_NO_MORE_RIDS +# define STATUS_DS_NO_MORE_RIDS ((NTSTATUS) 0xC00002A8L) +#endif + +#ifndef STATUS_DS_INCORRECT_ROLE_OWNER +# define STATUS_DS_INCORRECT_ROLE_OWNER ((NTSTATUS) 0xC00002A9L) +#endif + +#ifndef STATUS_DS_RIDMGR_INIT_ERROR +# define STATUS_DS_RIDMGR_INIT_ERROR ((NTSTATUS) 0xC00002AAL) +#endif + +#ifndef STATUS_DS_OBJ_CLASS_VIOLATION +# define STATUS_DS_OBJ_CLASS_VIOLATION ((NTSTATUS) 0xC00002ABL) +#endif + +#ifndef STATUS_DS_CANT_ON_NON_LEAF +# define STATUS_DS_CANT_ON_NON_LEAF ((NTSTATUS) 0xC00002ACL) +#endif + +#ifndef STATUS_DS_CANT_ON_RDN +# define STATUS_DS_CANT_ON_RDN ((NTSTATUS) 0xC00002ADL) +#endif + +#ifndef STATUS_DS_CANT_MOD_OBJ_CLASS +# define STATUS_DS_CANT_MOD_OBJ_CLASS ((NTSTATUS) 0xC00002AEL) +#endif + +#ifndef STATUS_DS_CROSS_DOM_MOVE_FAILED +# define STATUS_DS_CROSS_DOM_MOVE_FAILED ((NTSTATUS) 0xC00002AFL) +#endif + +#ifndef STATUS_DS_GC_NOT_AVAILABLE +# define STATUS_DS_GC_NOT_AVAILABLE ((NTSTATUS) 0xC00002B0L) +#endif + +#ifndef STATUS_DIRECTORY_SERVICE_REQUIRED +# define STATUS_DIRECTORY_SERVICE_REQUIRED ((NTSTATUS) 0xC00002B1L) +#endif + +#ifndef STATUS_REPARSE_ATTRIBUTE_CONFLICT +# define STATUS_REPARSE_ATTRIBUTE_CONFLICT ((NTSTATUS) 0xC00002B2L) +#endif + +#ifndef STATUS_CANT_ENABLE_DENY_ONLY +# define STATUS_CANT_ENABLE_DENY_ONLY ((NTSTATUS) 0xC00002B3L) +#endif + +#ifndef STATUS_FLOAT_MULTIPLE_FAULTS +# define STATUS_FLOAT_MULTIPLE_FAULTS ((NTSTATUS) 0xC00002B4L) +#endif + +#ifndef STATUS_FLOAT_MULTIPLE_TRAPS +# define STATUS_FLOAT_MULTIPLE_TRAPS ((NTSTATUS) 0xC00002B5L) +#endif + +#ifndef STATUS_DEVICE_REMOVED +# define STATUS_DEVICE_REMOVED ((NTSTATUS) 0xC00002B6L) +#endif + +#ifndef STATUS_JOURNAL_DELETE_IN_PROGRESS +# define STATUS_JOURNAL_DELETE_IN_PROGRESS ((NTSTATUS) 0xC00002B7L) +#endif + +#ifndef STATUS_JOURNAL_NOT_ACTIVE +# define STATUS_JOURNAL_NOT_ACTIVE ((NTSTATUS) 0xC00002B8L) +#endif + +#ifndef STATUS_NOINTERFACE +# define STATUS_NOINTERFACE ((NTSTATUS) 0xC00002B9L) +#endif + +#ifndef STATUS_DS_ADMIN_LIMIT_EXCEEDED +# define STATUS_DS_ADMIN_LIMIT_EXCEEDED ((NTSTATUS) 0xC00002C1L) +#endif + +#ifndef STATUS_DRIVER_FAILED_SLEEP +# define STATUS_DRIVER_FAILED_SLEEP ((NTSTATUS) 0xC00002C2L) +#endif + +#ifndef STATUS_MUTUAL_AUTHENTICATION_FAILED +# define STATUS_MUTUAL_AUTHENTICATION_FAILED ((NTSTATUS) 0xC00002C3L) +#endif + +#ifndef STATUS_CORRUPT_SYSTEM_FILE +# define STATUS_CORRUPT_SYSTEM_FILE ((NTSTATUS) 0xC00002C4L) +#endif + +#ifndef STATUS_DATATYPE_MISALIGNMENT_ERROR +# define STATUS_DATATYPE_MISALIGNMENT_ERROR ((NTSTATUS) 0xC00002C5L) +#endif + +#ifndef STATUS_WMI_READ_ONLY +# define STATUS_WMI_READ_ONLY ((NTSTATUS) 0xC00002C6L) +#endif + +#ifndef STATUS_WMI_SET_FAILURE +# define STATUS_WMI_SET_FAILURE ((NTSTATUS) 0xC00002C7L) +#endif + +#ifndef STATUS_COMMITMENT_MINIMUM +# define STATUS_COMMITMENT_MINIMUM ((NTSTATUS) 0xC00002C8L) +#endif + +#ifndef STATUS_REG_NAT_CONSUMPTION +# define STATUS_REG_NAT_CONSUMPTION ((NTSTATUS) 0xC00002C9L) +#endif + +#ifndef STATUS_TRANSPORT_FULL +# define STATUS_TRANSPORT_FULL ((NTSTATUS) 0xC00002CAL) +#endif + +#ifndef STATUS_DS_SAM_INIT_FAILURE +# define STATUS_DS_SAM_INIT_FAILURE ((NTSTATUS) 0xC00002CBL) +#endif + +#ifndef STATUS_ONLY_IF_CONNECTED +# define STATUS_ONLY_IF_CONNECTED ((NTSTATUS) 0xC00002CCL) +#endif + +#ifndef STATUS_DS_SENSITIVE_GROUP_VIOLATION +# define STATUS_DS_SENSITIVE_GROUP_VIOLATION ((NTSTATUS) 0xC00002CDL) +#endif + +#ifndef STATUS_PNP_RESTART_ENUMERATION +# define STATUS_PNP_RESTART_ENUMERATION ((NTSTATUS) 0xC00002CEL) +#endif + +#ifndef STATUS_JOURNAL_ENTRY_DELETED +# define STATUS_JOURNAL_ENTRY_DELETED ((NTSTATUS) 0xC00002CFL) +#endif + +#ifndef STATUS_DS_CANT_MOD_PRIMARYGROUPID +# define STATUS_DS_CANT_MOD_PRIMARYGROUPID ((NTSTATUS) 0xC00002D0L) +#endif + +#ifndef STATUS_SYSTEM_IMAGE_BAD_SIGNATURE +# define STATUS_SYSTEM_IMAGE_BAD_SIGNATURE ((NTSTATUS) 0xC00002D1L) +#endif + +#ifndef STATUS_PNP_REBOOT_REQUIRED +# define STATUS_PNP_REBOOT_REQUIRED ((NTSTATUS) 0xC00002D2L) +#endif + +#ifndef STATUS_POWER_STATE_INVALID +# define STATUS_POWER_STATE_INVALID ((NTSTATUS) 0xC00002D3L) +#endif + +#ifndef STATUS_DS_INVALID_GROUP_TYPE +# define STATUS_DS_INVALID_GROUP_TYPE ((NTSTATUS) 0xC00002D4L) +#endif + +#ifndef STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN +# define STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN ((NTSTATUS) 0xC00002D5L) +#endif + +#ifndef STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN +# define STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN ((NTSTATUS) 0xC00002D6L) +#endif + +#ifndef STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER +# define STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS) 0xC00002D7L) +#endif + +#ifndef STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER +# define STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS) 0xC00002D8L) +#endif + +#ifndef STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER +# define STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS) 0xC00002D9L) +#endif + +#ifndef STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER +# define STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER ((NTSTATUS) 0xC00002DAL) +#endif + +#ifndef STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER +# define STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER ((NTSTATUS) 0xC00002DBL) +#endif + +#ifndef STATUS_DS_HAVE_PRIMARY_MEMBERS +# define STATUS_DS_HAVE_PRIMARY_MEMBERS ((NTSTATUS) 0xC00002DCL) +#endif + +#ifndef STATUS_WMI_NOT_SUPPORTED +# define STATUS_WMI_NOT_SUPPORTED ((NTSTATUS) 0xC00002DDL) +#endif + +#ifndef STATUS_INSUFFICIENT_POWER +# define STATUS_INSUFFICIENT_POWER ((NTSTATUS) 0xC00002DEL) +#endif + +#ifndef STATUS_SAM_NEED_BOOTKEY_PASSWORD +# define STATUS_SAM_NEED_BOOTKEY_PASSWORD ((NTSTATUS) 0xC00002DFL) +#endif + +#ifndef STATUS_SAM_NEED_BOOTKEY_FLOPPY +# define STATUS_SAM_NEED_BOOTKEY_FLOPPY ((NTSTATUS) 0xC00002E0L) +#endif + +#ifndef STATUS_DS_CANT_START +# define STATUS_DS_CANT_START ((NTSTATUS) 0xC00002E1L) +#endif + +#ifndef STATUS_DS_INIT_FAILURE +# define STATUS_DS_INIT_FAILURE ((NTSTATUS) 0xC00002E2L) +#endif + +#ifndef STATUS_SAM_INIT_FAILURE +# define STATUS_SAM_INIT_FAILURE ((NTSTATUS) 0xC00002E3L) +#endif + +#ifndef STATUS_DS_GC_REQUIRED +# define STATUS_DS_GC_REQUIRED ((NTSTATUS) 0xC00002E4L) +#endif + +#ifndef STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY +# define STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY ((NTSTATUS) 0xC00002E5L) +#endif + +#ifndef STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS +# define STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS ((NTSTATUS) 0xC00002E6L) +#endif + +#ifndef STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED +# define STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED ((NTSTATUS) 0xC00002E7L) +#endif + +#ifndef STATUS_MULTIPLE_FAULT_VIOLATION +# define STATUS_MULTIPLE_FAULT_VIOLATION ((NTSTATUS) 0xC00002E8L) +#endif + +#ifndef STATUS_CURRENT_DOMAIN_NOT_ALLOWED +# define STATUS_CURRENT_DOMAIN_NOT_ALLOWED ((NTSTATUS) 0xC00002E9L) +#endif + +#ifndef STATUS_CANNOT_MAKE +# define STATUS_CANNOT_MAKE ((NTSTATUS) 0xC00002EAL) +#endif + +#ifndef STATUS_SYSTEM_SHUTDOWN +# define STATUS_SYSTEM_SHUTDOWN ((NTSTATUS) 0xC00002EBL) +#endif + +#ifndef STATUS_DS_INIT_FAILURE_CONSOLE +# define STATUS_DS_INIT_FAILURE_CONSOLE ((NTSTATUS) 0xC00002ECL) +#endif + +#ifndef STATUS_DS_SAM_INIT_FAILURE_CONSOLE +# define STATUS_DS_SAM_INIT_FAILURE_CONSOLE ((NTSTATUS) 0xC00002EDL) +#endif + +#ifndef STATUS_UNFINISHED_CONTEXT_DELETED +# define STATUS_UNFINISHED_CONTEXT_DELETED ((NTSTATUS) 0xC00002EEL) +#endif + +#ifndef STATUS_NO_TGT_REPLY +# define STATUS_NO_TGT_REPLY ((NTSTATUS) 0xC00002EFL) +#endif + +#ifndef STATUS_OBJECTID_NOT_FOUND +# define STATUS_OBJECTID_NOT_FOUND ((NTSTATUS) 0xC00002F0L) +#endif + +#ifndef STATUS_NO_IP_ADDRESSES +# define STATUS_NO_IP_ADDRESSES ((NTSTATUS) 0xC00002F1L) +#endif + +#ifndef STATUS_WRONG_CREDENTIAL_HANDLE +# define STATUS_WRONG_CREDENTIAL_HANDLE ((NTSTATUS) 0xC00002F2L) +#endif + +#ifndef STATUS_CRYPTO_SYSTEM_INVALID +# define STATUS_CRYPTO_SYSTEM_INVALID ((NTSTATUS) 0xC00002F3L) +#endif + +#ifndef STATUS_MAX_REFERRALS_EXCEEDED +# define STATUS_MAX_REFERRALS_EXCEEDED ((NTSTATUS) 0xC00002F4L) +#endif + +#ifndef STATUS_MUST_BE_KDC +# define STATUS_MUST_BE_KDC ((NTSTATUS) 0xC00002F5L) +#endif + +#ifndef STATUS_STRONG_CRYPTO_NOT_SUPPORTED +# define STATUS_STRONG_CRYPTO_NOT_SUPPORTED ((NTSTATUS) 0xC00002F6L) +#endif + +#ifndef STATUS_TOO_MANY_PRINCIPALS +# define STATUS_TOO_MANY_PRINCIPALS ((NTSTATUS) 0xC00002F7L) +#endif + +#ifndef STATUS_NO_PA_DATA +# define STATUS_NO_PA_DATA ((NTSTATUS) 0xC00002F8L) +#endif + +#ifndef STATUS_PKINIT_NAME_MISMATCH +# define STATUS_PKINIT_NAME_MISMATCH ((NTSTATUS) 0xC00002F9L) +#endif + +#ifndef STATUS_SMARTCARD_LOGON_REQUIRED +# define STATUS_SMARTCARD_LOGON_REQUIRED ((NTSTATUS) 0xC00002FAL) +#endif + +#ifndef STATUS_KDC_INVALID_REQUEST +# define STATUS_KDC_INVALID_REQUEST ((NTSTATUS) 0xC00002FBL) +#endif + +#ifndef STATUS_KDC_UNABLE_TO_REFER +# define STATUS_KDC_UNABLE_TO_REFER ((NTSTATUS) 0xC00002FCL) +#endif + +#ifndef STATUS_KDC_UNKNOWN_ETYPE +# define STATUS_KDC_UNKNOWN_ETYPE ((NTSTATUS) 0xC00002FDL) +#endif + +#ifndef STATUS_SHUTDOWN_IN_PROGRESS +# define STATUS_SHUTDOWN_IN_PROGRESS ((NTSTATUS) 0xC00002FEL) +#endif + +#ifndef STATUS_SERVER_SHUTDOWN_IN_PROGRESS +# define STATUS_SERVER_SHUTDOWN_IN_PROGRESS ((NTSTATUS) 0xC00002FFL) +#endif + +#ifndef STATUS_NOT_SUPPORTED_ON_SBS +# define STATUS_NOT_SUPPORTED_ON_SBS ((NTSTATUS) 0xC0000300L) +#endif + +#ifndef STATUS_WMI_GUID_DISCONNECTED +# define STATUS_WMI_GUID_DISCONNECTED ((NTSTATUS) 0xC0000301L) +#endif + +#ifndef STATUS_WMI_ALREADY_DISABLED +# define STATUS_WMI_ALREADY_DISABLED ((NTSTATUS) 0xC0000302L) +#endif + +#ifndef STATUS_WMI_ALREADY_ENABLED +# define STATUS_WMI_ALREADY_ENABLED ((NTSTATUS) 0xC0000303L) +#endif + +#ifndef STATUS_MFT_TOO_FRAGMENTED +# define STATUS_MFT_TOO_FRAGMENTED ((NTSTATUS) 0xC0000304L) +#endif + +#ifndef STATUS_COPY_PROTECTION_FAILURE +# define STATUS_COPY_PROTECTION_FAILURE ((NTSTATUS) 0xC0000305L) +#endif + +#ifndef STATUS_CSS_AUTHENTICATION_FAILURE +# define STATUS_CSS_AUTHENTICATION_FAILURE ((NTSTATUS) 0xC0000306L) +#endif + +#ifndef STATUS_CSS_KEY_NOT_PRESENT +# define STATUS_CSS_KEY_NOT_PRESENT ((NTSTATUS) 0xC0000307L) +#endif + +#ifndef STATUS_CSS_KEY_NOT_ESTABLISHED +# define STATUS_CSS_KEY_NOT_ESTABLISHED ((NTSTATUS) 0xC0000308L) +#endif + +#ifndef STATUS_CSS_SCRAMBLED_SECTOR +# define STATUS_CSS_SCRAMBLED_SECTOR ((NTSTATUS) 0xC0000309L) +#endif + +#ifndef STATUS_CSS_REGION_MISMATCH +# define STATUS_CSS_REGION_MISMATCH ((NTSTATUS) 0xC000030AL) +#endif + +#ifndef STATUS_CSS_RESETS_EXHAUSTED +# define STATUS_CSS_RESETS_EXHAUSTED ((NTSTATUS) 0xC000030BL) +#endif + +#ifndef STATUS_PKINIT_FAILURE +# define STATUS_PKINIT_FAILURE ((NTSTATUS) 0xC0000320L) +#endif + +#ifndef STATUS_SMARTCARD_SUBSYSTEM_FAILURE +# define STATUS_SMARTCARD_SUBSYSTEM_FAILURE ((NTSTATUS) 0xC0000321L) +#endif + +#ifndef STATUS_NO_KERB_KEY +# define STATUS_NO_KERB_KEY ((NTSTATUS) 0xC0000322L) +#endif + +#ifndef STATUS_HOST_DOWN +# define STATUS_HOST_DOWN ((NTSTATUS) 0xC0000350L) +#endif + +#ifndef STATUS_UNSUPPORTED_PREAUTH +# define STATUS_UNSUPPORTED_PREAUTH ((NTSTATUS) 0xC0000351L) +#endif + +#ifndef STATUS_EFS_ALG_BLOB_TOO_BIG +# define STATUS_EFS_ALG_BLOB_TOO_BIG ((NTSTATUS) 0xC0000352L) +#endif + +#ifndef STATUS_PORT_NOT_SET +# define STATUS_PORT_NOT_SET ((NTSTATUS) 0xC0000353L) +#endif + +#ifndef STATUS_DEBUGGER_INACTIVE +# define STATUS_DEBUGGER_INACTIVE ((NTSTATUS) 0xC0000354L) +#endif + +#ifndef STATUS_DS_VERSION_CHECK_FAILURE +# define STATUS_DS_VERSION_CHECK_FAILURE ((NTSTATUS) 0xC0000355L) +#endif + +#ifndef STATUS_AUDITING_DISABLED +# define STATUS_AUDITING_DISABLED ((NTSTATUS) 0xC0000356L) +#endif + +#ifndef STATUS_PRENT4_MACHINE_ACCOUNT +# define STATUS_PRENT4_MACHINE_ACCOUNT ((NTSTATUS) 0xC0000357L) +#endif + +#ifndef STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER +# define STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS) 0xC0000358L) +#endif + +#ifndef STATUS_INVALID_IMAGE_WIN_32 +# define STATUS_INVALID_IMAGE_WIN_32 ((NTSTATUS) 0xC0000359L) +#endif + +#ifndef STATUS_INVALID_IMAGE_WIN_64 +# define STATUS_INVALID_IMAGE_WIN_64 ((NTSTATUS) 0xC000035AL) +#endif + +#ifndef STATUS_BAD_BINDINGS +# define STATUS_BAD_BINDINGS ((NTSTATUS) 0xC000035BL) +#endif + +#ifndef STATUS_NETWORK_SESSION_EXPIRED +# define STATUS_NETWORK_SESSION_EXPIRED ((NTSTATUS) 0xC000035CL) +#endif + +#ifndef STATUS_APPHELP_BLOCK +# define STATUS_APPHELP_BLOCK ((NTSTATUS) 0xC000035DL) +#endif + +#ifndef STATUS_ALL_SIDS_FILTERED +# define STATUS_ALL_SIDS_FILTERED ((NTSTATUS) 0xC000035EL) +#endif + +#ifndef STATUS_NOT_SAFE_MODE_DRIVER +# define STATUS_NOT_SAFE_MODE_DRIVER ((NTSTATUS) 0xC000035FL) +#endif + +#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT +# define STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT ((NTSTATUS) 0xC0000361L) +#endif + +#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_PATH +# define STATUS_ACCESS_DISABLED_BY_POLICY_PATH ((NTSTATUS) 0xC0000362L) +#endif + +#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER +# define STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER ((NTSTATUS) 0xC0000363L) +#endif + +#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_OTHER +# define STATUS_ACCESS_DISABLED_BY_POLICY_OTHER ((NTSTATUS) 0xC0000364L) +#endif + +#ifndef STATUS_FAILED_DRIVER_ENTRY +# define STATUS_FAILED_DRIVER_ENTRY ((NTSTATUS) 0xC0000365L) +#endif + +#ifndef STATUS_DEVICE_ENUMERATION_ERROR +# define STATUS_DEVICE_ENUMERATION_ERROR ((NTSTATUS) 0xC0000366L) +#endif + +#ifndef STATUS_MOUNT_POINT_NOT_RESOLVED +# define STATUS_MOUNT_POINT_NOT_RESOLVED ((NTSTATUS) 0xC0000368L) +#endif + +#ifndef STATUS_INVALID_DEVICE_OBJECT_PARAMETER +# define STATUS_INVALID_DEVICE_OBJECT_PARAMETER ((NTSTATUS) 0xC0000369L) +#endif + +#ifndef STATUS_MCA_OCCURED +# define STATUS_MCA_OCCURED ((NTSTATUS) 0xC000036AL) +#endif + +#ifndef STATUS_DRIVER_BLOCKED_CRITICAL +# define STATUS_DRIVER_BLOCKED_CRITICAL ((NTSTATUS) 0xC000036BL) +#endif + +#ifndef STATUS_DRIVER_BLOCKED +# define STATUS_DRIVER_BLOCKED ((NTSTATUS) 0xC000036CL) +#endif + +#ifndef STATUS_DRIVER_DATABASE_ERROR +# define STATUS_DRIVER_DATABASE_ERROR ((NTSTATUS) 0xC000036DL) +#endif + +#ifndef STATUS_SYSTEM_HIVE_TOO_LARGE +# define STATUS_SYSTEM_HIVE_TOO_LARGE ((NTSTATUS) 0xC000036EL) +#endif + +#ifndef STATUS_INVALID_IMPORT_OF_NON_DLL +# define STATUS_INVALID_IMPORT_OF_NON_DLL ((NTSTATUS) 0xC000036FL) +#endif + +#ifndef STATUS_DS_SHUTTING_DOWN +# define STATUS_DS_SHUTTING_DOWN ((NTSTATUS) 0x40000370L) +#endif + +#ifndef STATUS_NO_SECRETS +# define STATUS_NO_SECRETS ((NTSTATUS) 0xC0000371L) +#endif + +#ifndef STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY +# define STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY ((NTSTATUS) 0xC0000372L) +#endif + +#ifndef STATUS_FAILED_STACK_SWITCH +# define STATUS_FAILED_STACK_SWITCH ((NTSTATUS) 0xC0000373L) +#endif + +#ifndef STATUS_HEAP_CORRUPTION +# define STATUS_HEAP_CORRUPTION ((NTSTATUS) 0xC0000374L) +#endif + +#ifndef STATUS_SMARTCARD_WRONG_PIN +# define STATUS_SMARTCARD_WRONG_PIN ((NTSTATUS) 0xC0000380L) +#endif + +#ifndef STATUS_SMARTCARD_CARD_BLOCKED +# define STATUS_SMARTCARD_CARD_BLOCKED ((NTSTATUS) 0xC0000381L) +#endif + +#ifndef STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED +# define STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED ((NTSTATUS) 0xC0000382L) +#endif + +#ifndef STATUS_SMARTCARD_NO_CARD +# define STATUS_SMARTCARD_NO_CARD ((NTSTATUS) 0xC0000383L) +#endif + +#ifndef STATUS_SMARTCARD_NO_KEY_CONTAINER +# define STATUS_SMARTCARD_NO_KEY_CONTAINER ((NTSTATUS) 0xC0000384L) +#endif + +#ifndef STATUS_SMARTCARD_NO_CERTIFICATE +# define STATUS_SMARTCARD_NO_CERTIFICATE ((NTSTATUS) 0xC0000385L) +#endif + +#ifndef STATUS_SMARTCARD_NO_KEYSET +# define STATUS_SMARTCARD_NO_KEYSET ((NTSTATUS) 0xC0000386L) +#endif + +#ifndef STATUS_SMARTCARD_IO_ERROR +# define STATUS_SMARTCARD_IO_ERROR ((NTSTATUS) 0xC0000387L) +#endif + +#ifndef STATUS_DOWNGRADE_DETECTED +# define STATUS_DOWNGRADE_DETECTED ((NTSTATUS) 0xC0000388L) +#endif + +#ifndef STATUS_SMARTCARD_CERT_REVOKED +# define STATUS_SMARTCARD_CERT_REVOKED ((NTSTATUS) 0xC0000389L) +#endif + +#ifndef STATUS_ISSUING_CA_UNTRUSTED +# define STATUS_ISSUING_CA_UNTRUSTED ((NTSTATUS) 0xC000038AL) +#endif + +#ifndef STATUS_REVOCATION_OFFLINE_C +# define STATUS_REVOCATION_OFFLINE_C ((NTSTATUS) 0xC000038BL) +#endif + +#ifndef STATUS_PKINIT_CLIENT_FAILURE +# define STATUS_PKINIT_CLIENT_FAILURE ((NTSTATUS) 0xC000038CL) +#endif + +#ifndef STATUS_SMARTCARD_CERT_EXPIRED +# define STATUS_SMARTCARD_CERT_EXPIRED ((NTSTATUS) 0xC000038DL) +#endif + +#ifndef STATUS_DRIVER_FAILED_PRIOR_UNLOAD +# define STATUS_DRIVER_FAILED_PRIOR_UNLOAD ((NTSTATUS) 0xC000038EL) +#endif + +#ifndef STATUS_SMARTCARD_SILENT_CONTEXT +# define STATUS_SMARTCARD_SILENT_CONTEXT ((NTSTATUS) 0xC000038FL) +#endif + +#ifndef STATUS_PER_USER_TRUST_QUOTA_EXCEEDED +# define STATUS_PER_USER_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000401L) +#endif + +#ifndef STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED +# define STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000402L) +#endif + +#ifndef STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED +# define STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000403L) +#endif + +#ifndef STATUS_DS_NAME_NOT_UNIQUE +# define STATUS_DS_NAME_NOT_UNIQUE ((NTSTATUS) 0xC0000404L) +#endif + +#ifndef STATUS_DS_DUPLICATE_ID_FOUND +# define STATUS_DS_DUPLICATE_ID_FOUND ((NTSTATUS) 0xC0000405L) +#endif + +#ifndef STATUS_DS_GROUP_CONVERSION_ERROR +# define STATUS_DS_GROUP_CONVERSION_ERROR ((NTSTATUS) 0xC0000406L) +#endif + +#ifndef STATUS_VOLSNAP_PREPARE_HIBERNATE +# define STATUS_VOLSNAP_PREPARE_HIBERNATE ((NTSTATUS) 0xC0000407L) +#endif + +#ifndef STATUS_USER2USER_REQUIRED +# define STATUS_USER2USER_REQUIRED ((NTSTATUS) 0xC0000408L) +#endif + +#ifndef STATUS_STACK_BUFFER_OVERRUN +# define STATUS_STACK_BUFFER_OVERRUN ((NTSTATUS) 0xC0000409L) +#endif + +#ifndef STATUS_NO_S4U_PROT_SUPPORT +# define STATUS_NO_S4U_PROT_SUPPORT ((NTSTATUS) 0xC000040AL) +#endif + +#ifndef STATUS_CROSSREALM_DELEGATION_FAILURE +# define STATUS_CROSSREALM_DELEGATION_FAILURE ((NTSTATUS) 0xC000040BL) +#endif + +#ifndef STATUS_REVOCATION_OFFLINE_KDC +# define STATUS_REVOCATION_OFFLINE_KDC ((NTSTATUS) 0xC000040CL) +#endif + +#ifndef STATUS_ISSUING_CA_UNTRUSTED_KDC +# define STATUS_ISSUING_CA_UNTRUSTED_KDC ((NTSTATUS) 0xC000040DL) +#endif + +#ifndef STATUS_KDC_CERT_EXPIRED +# define STATUS_KDC_CERT_EXPIRED ((NTSTATUS) 0xC000040EL) +#endif + +#ifndef STATUS_KDC_CERT_REVOKED +# define STATUS_KDC_CERT_REVOKED ((NTSTATUS) 0xC000040FL) +#endif + +#ifndef STATUS_PARAMETER_QUOTA_EXCEEDED +# define STATUS_PARAMETER_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000410L) +#endif + +#ifndef STATUS_HIBERNATION_FAILURE +# define STATUS_HIBERNATION_FAILURE ((NTSTATUS) 0xC0000411L) +#endif + +#ifndef STATUS_DELAY_LOAD_FAILED +# define STATUS_DELAY_LOAD_FAILED ((NTSTATUS) 0xC0000412L) +#endif + +#ifndef STATUS_AUTHENTICATION_FIREWALL_FAILED +# define STATUS_AUTHENTICATION_FIREWALL_FAILED ((NTSTATUS) 0xC0000413L) +#endif + +#ifndef STATUS_VDM_DISALLOWED +# define STATUS_VDM_DISALLOWED ((NTSTATUS) 0xC0000414L) +#endif + +#ifndef STATUS_HUNG_DISPLAY_DRIVER_THREAD +# define STATUS_HUNG_DISPLAY_DRIVER_THREAD ((NTSTATUS) 0xC0000415L) +#endif + +#ifndef STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE +# define STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE ((NTSTATUS) 0xC0000416L) +#endif + +#ifndef STATUS_INVALID_CRUNTIME_PARAMETER +# define STATUS_INVALID_CRUNTIME_PARAMETER ((NTSTATUS) 0xC0000417L) +#endif + +#ifndef STATUS_NTLM_BLOCKED +# define STATUS_NTLM_BLOCKED ((NTSTATUS) 0xC0000418L) +#endif + +#ifndef STATUS_DS_SRC_SID_EXISTS_IN_FOREST +# define STATUS_DS_SRC_SID_EXISTS_IN_FOREST ((NTSTATUS) 0xC0000419L) +#endif + +#ifndef STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST +# define STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST ((NTSTATUS) 0xC000041AL) +#endif + +#ifndef STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST +# define STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST ((NTSTATUS) 0xC000041BL) +#endif + +#ifndef STATUS_INVALID_USER_PRINCIPAL_NAME +# define STATUS_INVALID_USER_PRINCIPAL_NAME ((NTSTATUS) 0xC000041CL) +#endif + +#ifndef STATUS_FATAL_USER_CALLBACK_EXCEPTION +# define STATUS_FATAL_USER_CALLBACK_EXCEPTION ((NTSTATUS) 0xC000041DL) +#endif + +#ifndef STATUS_ASSERTION_FAILURE +# define STATUS_ASSERTION_FAILURE ((NTSTATUS) 0xC0000420L) +#endif + +#ifndef STATUS_VERIFIER_STOP +# define STATUS_VERIFIER_STOP ((NTSTATUS) 0xC0000421L) +#endif + +#ifndef STATUS_CALLBACK_POP_STACK +# define STATUS_CALLBACK_POP_STACK ((NTSTATUS) 0xC0000423L) +#endif + +#ifndef STATUS_INCOMPATIBLE_DRIVER_BLOCKED +# define STATUS_INCOMPATIBLE_DRIVER_BLOCKED ((NTSTATUS) 0xC0000424L) +#endif + +#ifndef STATUS_HIVE_UNLOADED +# define STATUS_HIVE_UNLOADED ((NTSTATUS) 0xC0000425L) +#endif + +#ifndef STATUS_COMPRESSION_DISABLED +# define STATUS_COMPRESSION_DISABLED ((NTSTATUS) 0xC0000426L) +#endif + +#ifndef STATUS_FILE_SYSTEM_LIMITATION +# define STATUS_FILE_SYSTEM_LIMITATION ((NTSTATUS) 0xC0000427L) +#endif + +#ifndef STATUS_INVALID_IMAGE_HASH +# define STATUS_INVALID_IMAGE_HASH ((NTSTATUS) 0xC0000428L) +#endif + +#ifndef STATUS_NOT_CAPABLE +# define STATUS_NOT_CAPABLE ((NTSTATUS) 0xC0000429L) +#endif + +#ifndef STATUS_REQUEST_OUT_OF_SEQUENCE +# define STATUS_REQUEST_OUT_OF_SEQUENCE ((NTSTATUS) 0xC000042AL) +#endif + +#ifndef STATUS_IMPLEMENTATION_LIMIT +# define STATUS_IMPLEMENTATION_LIMIT ((NTSTATUS) 0xC000042BL) +#endif + +#ifndef STATUS_ELEVATION_REQUIRED +# define STATUS_ELEVATION_REQUIRED ((NTSTATUS) 0xC000042CL) +#endif + +#ifndef STATUS_NO_SECURITY_CONTEXT +# define STATUS_NO_SECURITY_CONTEXT ((NTSTATUS) 0xC000042DL) +#endif + +#ifndef STATUS_PKU2U_CERT_FAILURE +# define STATUS_PKU2U_CERT_FAILURE ((NTSTATUS) 0xC000042FL) +#endif + +#ifndef STATUS_BEYOND_VDL +# define STATUS_BEYOND_VDL ((NTSTATUS) 0xC0000432L) +#endif + +#ifndef STATUS_ENCOUNTERED_WRITE_IN_PROGRESS +# define STATUS_ENCOUNTERED_WRITE_IN_PROGRESS ((NTSTATUS) 0xC0000433L) +#endif + +#ifndef STATUS_PTE_CHANGED +# define STATUS_PTE_CHANGED ((NTSTATUS) 0xC0000434L) +#endif + +#ifndef STATUS_PURGE_FAILED +# define STATUS_PURGE_FAILED ((NTSTATUS) 0xC0000435L) +#endif + +#ifndef STATUS_CRED_REQUIRES_CONFIRMATION +# define STATUS_CRED_REQUIRES_CONFIRMATION ((NTSTATUS) 0xC0000440L) +#endif + +#ifndef STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE +# define STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE ((NTSTATUS) 0xC0000441L) +#endif + +#ifndef STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER +# define STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER ((NTSTATUS) 0xC0000442L) +#endif + +#ifndef STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE +# define STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE ((NTSTATUS) 0xC0000443L) +#endif + +#ifndef STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE +# define STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE ((NTSTATUS) 0xC0000444L) +#endif + +#ifndef STATUS_CS_ENCRYPTION_FILE_NOT_CSE +# define STATUS_CS_ENCRYPTION_FILE_NOT_CSE ((NTSTATUS) 0xC0000445L) +#endif + +#ifndef STATUS_INVALID_LABEL +# define STATUS_INVALID_LABEL ((NTSTATUS) 0xC0000446L) +#endif + +#ifndef STATUS_DRIVER_PROCESS_TERMINATED +# define STATUS_DRIVER_PROCESS_TERMINATED ((NTSTATUS) 0xC0000450L) +#endif + +#ifndef STATUS_AMBIGUOUS_SYSTEM_DEVICE +# define STATUS_AMBIGUOUS_SYSTEM_DEVICE ((NTSTATUS) 0xC0000451L) +#endif + +#ifndef STATUS_SYSTEM_DEVICE_NOT_FOUND +# define STATUS_SYSTEM_DEVICE_NOT_FOUND ((NTSTATUS) 0xC0000452L) +#endif + +#ifndef STATUS_RESTART_BOOT_APPLICATION +# define STATUS_RESTART_BOOT_APPLICATION ((NTSTATUS) 0xC0000453L) +#endif + +#ifndef STATUS_INSUFFICIENT_NVRAM_RESOURCES +# define STATUS_INSUFFICIENT_NVRAM_RESOURCES ((NTSTATUS) 0xC0000454L) +#endif + +#ifndef STATUS_INVALID_TASK_NAME +# define STATUS_INVALID_TASK_NAME ((NTSTATUS) 0xC0000500L) +#endif + +#ifndef STATUS_INVALID_TASK_INDEX +# define STATUS_INVALID_TASK_INDEX ((NTSTATUS) 0xC0000501L) +#endif + +#ifndef STATUS_THREAD_ALREADY_IN_TASK +# define STATUS_THREAD_ALREADY_IN_TASK ((NTSTATUS) 0xC0000502L) +#endif + +#ifndef STATUS_CALLBACK_BYPASS +# define STATUS_CALLBACK_BYPASS ((NTSTATUS) 0xC0000503L) +#endif + +#ifndef STATUS_FAIL_FAST_EXCEPTION +# define STATUS_FAIL_FAST_EXCEPTION ((NTSTATUS) 0xC0000602L) +#endif + +#ifndef STATUS_IMAGE_CERT_REVOKED +# define STATUS_IMAGE_CERT_REVOKED ((NTSTATUS) 0xC0000603L) +#endif + +#ifndef STATUS_PORT_CLOSED +# define STATUS_PORT_CLOSED ((NTSTATUS) 0xC0000700L) +#endif + +#ifndef STATUS_MESSAGE_LOST +# define STATUS_MESSAGE_LOST ((NTSTATUS) 0xC0000701L) +#endif + +#ifndef STATUS_INVALID_MESSAGE +# define STATUS_INVALID_MESSAGE ((NTSTATUS) 0xC0000702L) +#endif + +#ifndef STATUS_REQUEST_CANCELED +# define STATUS_REQUEST_CANCELED ((NTSTATUS) 0xC0000703L) +#endif + +#ifndef STATUS_RECURSIVE_DISPATCH +# define STATUS_RECURSIVE_DISPATCH ((NTSTATUS) 0xC0000704L) +#endif + +#ifndef STATUS_LPC_RECEIVE_BUFFER_EXPECTED +# define STATUS_LPC_RECEIVE_BUFFER_EXPECTED ((NTSTATUS) 0xC0000705L) +#endif + +#ifndef STATUS_LPC_INVALID_CONNECTION_USAGE +# define STATUS_LPC_INVALID_CONNECTION_USAGE ((NTSTATUS) 0xC0000706L) +#endif + +#ifndef STATUS_LPC_REQUESTS_NOT_ALLOWED +# define STATUS_LPC_REQUESTS_NOT_ALLOWED ((NTSTATUS) 0xC0000707L) +#endif + +#ifndef STATUS_RESOURCE_IN_USE +# define STATUS_RESOURCE_IN_USE ((NTSTATUS) 0xC0000708L) +#endif + +#ifndef STATUS_HARDWARE_MEMORY_ERROR +# define STATUS_HARDWARE_MEMORY_ERROR ((NTSTATUS) 0xC0000709L) +#endif + +#ifndef STATUS_THREADPOOL_HANDLE_EXCEPTION +# define STATUS_THREADPOOL_HANDLE_EXCEPTION ((NTSTATUS) 0xC000070AL) +#endif + +#ifndef STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED +# define STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070BL) +#endif + +#ifndef STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED +# define STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070CL) +#endif + +#ifndef STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED +# define STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070DL) +#endif + +#ifndef STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED +# define STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070EL) +#endif + +#ifndef STATUS_THREADPOOL_RELEASED_DURING_OPERATION +# define STATUS_THREADPOOL_RELEASED_DURING_OPERATION ((NTSTATUS) 0xC000070FL) +#endif + +#ifndef STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING +# define STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING ((NTSTATUS) 0xC0000710L) +#endif + +#ifndef STATUS_APC_RETURNED_WHILE_IMPERSONATING +# define STATUS_APC_RETURNED_WHILE_IMPERSONATING ((NTSTATUS) 0xC0000711L) +#endif + +#ifndef STATUS_PROCESS_IS_PROTECTED +# define STATUS_PROCESS_IS_PROTECTED ((NTSTATUS) 0xC0000712L) +#endif + +#ifndef STATUS_MCA_EXCEPTION +# define STATUS_MCA_EXCEPTION ((NTSTATUS) 0xC0000713L) +#endif + +#ifndef STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE +# define STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE ((NTSTATUS) 0xC0000714L) +#endif + +#ifndef STATUS_SYMLINK_CLASS_DISABLED +# define STATUS_SYMLINK_CLASS_DISABLED ((NTSTATUS) 0xC0000715L) +#endif + +#ifndef STATUS_INVALID_IDN_NORMALIZATION +# define STATUS_INVALID_IDN_NORMALIZATION ((NTSTATUS) 0xC0000716L) +#endif + +#ifndef STATUS_NO_UNICODE_TRANSLATION +# define STATUS_NO_UNICODE_TRANSLATION ((NTSTATUS) 0xC0000717L) +#endif + +#ifndef STATUS_ALREADY_REGISTERED +# define STATUS_ALREADY_REGISTERED ((NTSTATUS) 0xC0000718L) +#endif + +#ifndef STATUS_CONTEXT_MISMATCH +# define STATUS_CONTEXT_MISMATCH ((NTSTATUS) 0xC0000719L) +#endif + +#ifndef STATUS_PORT_ALREADY_HAS_COMPLETION_LIST +# define STATUS_PORT_ALREADY_HAS_COMPLETION_LIST ((NTSTATUS) 0xC000071AL) +#endif + +#ifndef STATUS_CALLBACK_RETURNED_THREAD_PRIORITY +# define STATUS_CALLBACK_RETURNED_THREAD_PRIORITY ((NTSTATUS) 0xC000071BL) +#endif + +#ifndef STATUS_INVALID_THREAD +# define STATUS_INVALID_THREAD ((NTSTATUS) 0xC000071CL) +#endif + +#ifndef STATUS_CALLBACK_RETURNED_TRANSACTION +# define STATUS_CALLBACK_RETURNED_TRANSACTION ((NTSTATUS) 0xC000071DL) +#endif + +#ifndef STATUS_CALLBACK_RETURNED_LDR_LOCK +# define STATUS_CALLBACK_RETURNED_LDR_LOCK ((NTSTATUS) 0xC000071EL) +#endif + +#ifndef STATUS_CALLBACK_RETURNED_LANG +# define STATUS_CALLBACK_RETURNED_LANG ((NTSTATUS) 0xC000071FL) +#endif + +#ifndef STATUS_CALLBACK_RETURNED_PRI_BACK +# define STATUS_CALLBACK_RETURNED_PRI_BACK ((NTSTATUS) 0xC0000720L) +#endif + +#ifndef STATUS_CALLBACK_RETURNED_THREAD_AFFINITY +# define STATUS_CALLBACK_RETURNED_THREAD_AFFINITY ((NTSTATUS) 0xC0000721L) +#endif + +#ifndef STATUS_DISK_REPAIR_DISABLED +# define STATUS_DISK_REPAIR_DISABLED ((NTSTATUS) 0xC0000800L) +#endif + +#ifndef STATUS_DS_DOMAIN_RENAME_IN_PROGRESS +# define STATUS_DS_DOMAIN_RENAME_IN_PROGRESS ((NTSTATUS) 0xC0000801L) +#endif + +#ifndef STATUS_DISK_QUOTA_EXCEEDED +# define STATUS_DISK_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000802L) +#endif + +#ifndef STATUS_DATA_LOST_REPAIR +# define STATUS_DATA_LOST_REPAIR ((NTSTATUS) 0x80000803L) +#endif + +#ifndef STATUS_CONTENT_BLOCKED +# define STATUS_CONTENT_BLOCKED ((NTSTATUS) 0xC0000804L) +#endif + +#ifndef STATUS_BAD_CLUSTERS +# define STATUS_BAD_CLUSTERS ((NTSTATUS) 0xC0000805L) +#endif + +#ifndef STATUS_VOLUME_DIRTY +# define STATUS_VOLUME_DIRTY ((NTSTATUS) 0xC0000806L) +#endif + +#ifndef STATUS_FILE_CHECKED_OUT +# define STATUS_FILE_CHECKED_OUT ((NTSTATUS) 0xC0000901L) +#endif + +#ifndef STATUS_CHECKOUT_REQUIRED +# define STATUS_CHECKOUT_REQUIRED ((NTSTATUS) 0xC0000902L) +#endif + +#ifndef STATUS_BAD_FILE_TYPE +# define STATUS_BAD_FILE_TYPE ((NTSTATUS) 0xC0000903L) +#endif + +#ifndef STATUS_FILE_TOO_LARGE +# define STATUS_FILE_TOO_LARGE ((NTSTATUS) 0xC0000904L) +#endif + +#ifndef STATUS_FORMS_AUTH_REQUIRED +# define STATUS_FORMS_AUTH_REQUIRED ((NTSTATUS) 0xC0000905L) +#endif + +#ifndef STATUS_VIRUS_INFECTED +# define STATUS_VIRUS_INFECTED ((NTSTATUS) 0xC0000906L) +#endif + +#ifndef STATUS_VIRUS_DELETED +# define STATUS_VIRUS_DELETED ((NTSTATUS) 0xC0000907L) +#endif + +#ifndef STATUS_BAD_MCFG_TABLE +# define STATUS_BAD_MCFG_TABLE ((NTSTATUS) 0xC0000908L) +#endif + +#ifndef STATUS_CANNOT_BREAK_OPLOCK +# define STATUS_CANNOT_BREAK_OPLOCK ((NTSTATUS) 0xC0000909L) +#endif + +#ifndef STATUS_WOW_ASSERTION +# define STATUS_WOW_ASSERTION ((NTSTATUS) 0xC0009898L) +#endif + +#ifndef STATUS_INVALID_SIGNATURE +# define STATUS_INVALID_SIGNATURE ((NTSTATUS) 0xC000A000L) +#endif + +#ifndef STATUS_HMAC_NOT_SUPPORTED +# define STATUS_HMAC_NOT_SUPPORTED ((NTSTATUS) 0xC000A001L) +#endif + +#ifndef STATUS_AUTH_TAG_MISMATCH +# define STATUS_AUTH_TAG_MISMATCH ((NTSTATUS) 0xC000A002L) +#endif + +#ifndef STATUS_IPSEC_QUEUE_OVERFLOW +# define STATUS_IPSEC_QUEUE_OVERFLOW ((NTSTATUS) 0xC000A010L) +#endif + +#ifndef STATUS_ND_QUEUE_OVERFLOW +# define STATUS_ND_QUEUE_OVERFLOW ((NTSTATUS) 0xC000A011L) +#endif + +#ifndef STATUS_HOPLIMIT_EXCEEDED +# define STATUS_HOPLIMIT_EXCEEDED ((NTSTATUS) 0xC000A012L) +#endif + +#ifndef STATUS_PROTOCOL_NOT_SUPPORTED +# define STATUS_PROTOCOL_NOT_SUPPORTED ((NTSTATUS) 0xC000A013L) +#endif + +#ifndef STATUS_FASTPATH_REJECTED +# define STATUS_FASTPATH_REJECTED ((NTSTATUS) 0xC000A014L) +#endif + +#ifndef STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED +# define STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED ((NTSTATUS) 0xC000A080L) +#endif + +#ifndef STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR +# define STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR ((NTSTATUS) 0xC000A081L) +#endif + +#ifndef STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR +# define STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR ((NTSTATUS) 0xC000A082L) +#endif + +#ifndef STATUS_XML_PARSE_ERROR +# define STATUS_XML_PARSE_ERROR ((NTSTATUS) 0xC000A083L) +#endif + +#ifndef STATUS_XMLDSIG_ERROR +# define STATUS_XMLDSIG_ERROR ((NTSTATUS) 0xC000A084L) +#endif + +#ifndef STATUS_WRONG_COMPARTMENT +# define STATUS_WRONG_COMPARTMENT ((NTSTATUS) 0xC000A085L) +#endif + +#ifndef STATUS_AUTHIP_FAILURE +# define STATUS_AUTHIP_FAILURE ((NTSTATUS) 0xC000A086L) +#endif + +#ifndef STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS +# define STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS ((NTSTATUS) 0xC000A087L) +#endif + +#ifndef STATUS_DS_OID_NOT_FOUND +# define STATUS_DS_OID_NOT_FOUND ((NTSTATUS) 0xC000A088L) +#endif + +#ifndef STATUS_HASH_NOT_SUPPORTED +# define STATUS_HASH_NOT_SUPPORTED ((NTSTATUS) 0xC000A100L) +#endif + +#ifndef STATUS_HASH_NOT_PRESENT +# define STATUS_HASH_NOT_PRESENT ((NTSTATUS) 0xC000A101L) +#endif + +/* This is not the NTSTATUS_FROM_WIN32 that the DDK provides, because the DDK + * got it wrong! */ +#ifdef NTSTATUS_FROM_WIN32 +# undef NTSTATUS_FROM_WIN32 +#endif +#define NTSTATUS_FROM_WIN32(error) ((NTSTATUS) (error) <= 0 ? \ + ((NTSTATUS) (error)) : ((NTSTATUS) (((error) & 0x0000FFFF) | \ + (FACILITY_NTWIN32 << 16) | ERROR_SEVERITY_WARNING))) + +#ifndef JOB_OBJECT_LIMIT_PROCESS_MEMORY +# define JOB_OBJECT_LIMIT_PROCESS_MEMORY 0x00000100 +#endif +#ifndef JOB_OBJECT_LIMIT_JOB_MEMORY +# define JOB_OBJECT_LIMIT_JOB_MEMORY 0x00000200 +#endif +#ifndef JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION +# define JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION 0x00000400 +#endif +#ifndef JOB_OBJECT_LIMIT_BREAKAWAY_OK +# define JOB_OBJECT_LIMIT_BREAKAWAY_OK 0x00000800 +#endif +#ifndef JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK +# define JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK 0x00001000 +#endif +#ifndef JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE +# define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x00002000 +#endif + +#ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE +# define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x00000002 +#endif + +/* from winternl.h */ +#if !defined(__UNICODE_STRING_DEFINED) && defined(__MINGW32__) +#define __UNICODE_STRING_DEFINED +#endif +typedef struct _UNICODE_STRING { + USHORT Length; + USHORT MaximumLength; + PWSTR Buffer; +} UNICODE_STRING, *PUNICODE_STRING; + +typedef const UNICODE_STRING *PCUNICODE_STRING; + +/* from ntifs.h */ +#ifndef DEVICE_TYPE +# define DEVICE_TYPE DWORD +#endif + +/* MinGW already has a definition for REPARSE_DATA_BUFFER, but mingw-w64 does + * not. + */ +#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR) + typedef struct _REPARSE_DATA_BUFFER { + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; + union { + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; + struct { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + struct { + UCHAR DataBuffer[1]; + } GenericReparseBuffer; + struct { + ULONG StringCount; + WCHAR StringList[1]; + } AppExecLinkReparseBuffer; + }; + } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; +#endif + +typedef struct _IO_STATUS_BLOCK { + union { + NTSTATUS Status; + PVOID Pointer; + }; + ULONG_PTR Information; +} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; + +typedef enum _FILE_INFORMATION_CLASS { + FileDirectoryInformation = 1, + FileFullDirectoryInformation, + FileBothDirectoryInformation, + FileBasicInformation, + FileStandardInformation, + FileInternalInformation, + FileEaInformation, + FileAccessInformation, + FileNameInformation, + FileRenameInformation, + FileLinkInformation, + FileNamesInformation, + FileDispositionInformation, + FilePositionInformation, + FileFullEaInformation, + FileModeInformation, + FileAlignmentInformation, + FileAllInformation, + FileAllocationInformation, + FileEndOfFileInformation, + FileAlternateNameInformation, + FileStreamInformation, + FilePipeInformation, + FilePipeLocalInformation, + FilePipeRemoteInformation, + FileMailslotQueryInformation, + FileMailslotSetInformation, + FileCompressionInformation, + FileObjectIdInformation, + FileCompletionInformation, + FileMoveClusterInformation, + FileQuotaInformation, + FileReparsePointInformation, + FileNetworkOpenInformation, + FileAttributeTagInformation, + FileTrackingInformation, + FileIdBothDirectoryInformation, + FileIdFullDirectoryInformation, + FileValidDataLengthInformation, + FileShortNameInformation, + FileIoCompletionNotificationInformation, + FileIoStatusBlockRangeInformation, + FileIoPriorityHintInformation, + FileSfioReserveInformation, + FileSfioVolumeInformation, + FileHardLinkInformation, + FileProcessIdsUsingFileInformation, + FileNormalizedNameInformation, + FileNetworkPhysicalNameInformation, + FileIdGlobalTxDirectoryInformation, + FileIsRemoteDeviceInformation, + FileAttributeCacheInformation, + FileNumaNodeInformation, + FileStandardLinkInformation, + FileRemoteProtocolInformation, + FileMaximumInformation +} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; + +typedef struct _FILE_DIRECTORY_INFORMATION { + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION; + +typedef struct _FILE_BOTH_DIR_INFORMATION { + ULONG NextEntryOffset; + ULONG FileIndex; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER EndOfFile; + LARGE_INTEGER AllocationSize; + ULONG FileAttributes; + ULONG FileNameLength; + ULONG EaSize; + CCHAR ShortNameLength; + WCHAR ShortName[12]; + WCHAR FileName[1]; +} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION; + +typedef struct _FILE_BASIC_INFORMATION { + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + DWORD FileAttributes; +} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; + +typedef struct _FILE_STANDARD_INFORMATION { + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG NumberOfLinks; + BOOLEAN DeletePending; + BOOLEAN Directory; +} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; + +typedef struct _FILE_INTERNAL_INFORMATION { + LARGE_INTEGER IndexNumber; +} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION; + +typedef struct _FILE_EA_INFORMATION { + ULONG EaSize; +} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION; + +typedef struct _FILE_ACCESS_INFORMATION { + ACCESS_MASK AccessFlags; +} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION; + +typedef struct _FILE_POSITION_INFORMATION { + LARGE_INTEGER CurrentByteOffset; +} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; + +typedef struct _FILE_MODE_INFORMATION { + ULONG Mode; +} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION; + +typedef struct _FILE_ALIGNMENT_INFORMATION { + ULONG AlignmentRequirement; +} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION; + +typedef struct _FILE_NAME_INFORMATION { + ULONG FileNameLength; + WCHAR FileName[1]; +} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; + +typedef struct _FILE_END_OF_FILE_INFORMATION { + LARGE_INTEGER EndOfFile; +} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; + +typedef struct _FILE_ALL_INFORMATION { + FILE_BASIC_INFORMATION BasicInformation; + FILE_STANDARD_INFORMATION StandardInformation; + FILE_INTERNAL_INFORMATION InternalInformation; + FILE_EA_INFORMATION EaInformation; + FILE_ACCESS_INFORMATION AccessInformation; + FILE_POSITION_INFORMATION PositionInformation; + FILE_MODE_INFORMATION ModeInformation; + FILE_ALIGNMENT_INFORMATION AlignmentInformation; + FILE_NAME_INFORMATION NameInformation; +} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION; + +typedef struct _FILE_DISPOSITION_INFORMATION { + BOOLEAN DeleteFile; +} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; + +typedef struct _FILE_PIPE_LOCAL_INFORMATION { + ULONG NamedPipeType; + ULONG NamedPipeConfiguration; + ULONG MaximumInstances; + ULONG CurrentInstances; + ULONG InboundQuota; + ULONG ReadDataAvailable; + ULONG OutboundQuota; + ULONG WriteQuotaAvailable; + ULONG NamedPipeState; + ULONG NamedPipeEnd; +} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION; + +#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 +#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 + +typedef enum _FS_INFORMATION_CLASS { + FileFsVolumeInformation = 1, + FileFsLabelInformation = 2, + FileFsSizeInformation = 3, + FileFsDeviceInformation = 4, + FileFsAttributeInformation = 5, + FileFsControlInformation = 6, + FileFsFullSizeInformation = 7, + FileFsObjectIdInformation = 8, + FileFsDriverPathInformation = 9, + FileFsVolumeFlagsInformation = 10, + FileFsSectorSizeInformation = 11 +} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; + +typedef struct _FILE_FS_VOLUME_INFORMATION { + LARGE_INTEGER VolumeCreationTime; + ULONG VolumeSerialNumber; + ULONG VolumeLabelLength; + BOOLEAN SupportsObjects; + WCHAR VolumeLabel[1]; +} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION; + +typedef struct _FILE_FS_LABEL_INFORMATION { + ULONG VolumeLabelLength; + WCHAR VolumeLabel[1]; +} FILE_FS_LABEL_INFORMATION, *PFILE_FS_LABEL_INFORMATION; + +typedef struct _FILE_FS_SIZE_INFORMATION { + LARGE_INTEGER TotalAllocationUnits; + LARGE_INTEGER AvailableAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; + +typedef struct _FILE_FS_DEVICE_INFORMATION { + DEVICE_TYPE DeviceType; + ULONG Characteristics; +} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; + +typedef struct _FILE_FS_ATTRIBUTE_INFORMATION { + ULONG FileSystemAttributes; + LONG MaximumComponentNameLength; + ULONG FileSystemNameLength; + WCHAR FileSystemName[1]; +} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION; + +typedef struct _FILE_FS_CONTROL_INFORMATION { + LARGE_INTEGER FreeSpaceStartFiltering; + LARGE_INTEGER FreeSpaceThreshold; + LARGE_INTEGER FreeSpaceStopFiltering; + LARGE_INTEGER DefaultQuotaThreshold; + LARGE_INTEGER DefaultQuotaLimit; + ULONG FileSystemControlFlags; +} FILE_FS_CONTROL_INFORMATION, *PFILE_FS_CONTROL_INFORMATION; + +typedef struct _FILE_FS_FULL_SIZE_INFORMATION { + LARGE_INTEGER TotalAllocationUnits; + LARGE_INTEGER CallerAvailableAllocationUnits; + LARGE_INTEGER ActualAvailableAllocationUnits; + ULONG SectorsPerAllocationUnit; + ULONG BytesPerSector; +} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION; + +typedef struct _FILE_FS_OBJECTID_INFORMATION { + UCHAR ObjectId[16]; + UCHAR ExtendedInfo[48]; +} FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION; + +typedef struct _FILE_FS_DRIVER_PATH_INFORMATION { + BOOLEAN DriverInPath; + ULONG DriverNameLength; + WCHAR DriverName[1]; +} FILE_FS_DRIVER_PATH_INFORMATION, *PFILE_FS_DRIVER_PATH_INFORMATION; + +typedef struct _FILE_FS_VOLUME_FLAGS_INFORMATION { + ULONG Flags; +} FILE_FS_VOLUME_FLAGS_INFORMATION, *PFILE_FS_VOLUME_FLAGS_INFORMATION; + +typedef struct _FILE_FS_SECTOR_SIZE_INFORMATION { + ULONG LogicalBytesPerSector; + ULONG PhysicalBytesPerSectorForAtomicity; + ULONG PhysicalBytesPerSectorForPerformance; + ULONG FileSystemEffectivePhysicalBytesPerSectorForAtomicity; + ULONG Flags; + ULONG ByteOffsetForSectorAlignment; + ULONG ByteOffsetForPartitionAlignment; +} FILE_FS_SECTOR_SIZE_INFORMATION, *PFILE_FS_SECTOR_SIZE_INFORMATION; + +typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION { + LARGE_INTEGER IdleTime; + LARGE_INTEGER KernelTime; + LARGE_INTEGER UserTime; + LARGE_INTEGER DpcTime; + LARGE_INTEGER InterruptTime; + ULONG InterruptCount; +} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; + +#ifndef SystemProcessorPerformanceInformation +# define SystemProcessorPerformanceInformation 8 +#endif + +#ifndef ProcessConsoleHostProcess +# define ProcessConsoleHostProcess 49 +#endif + +#ifndef FILE_DEVICE_FILE_SYSTEM +# define FILE_DEVICE_FILE_SYSTEM 0x00000009 +#endif + +#ifndef FILE_DEVICE_NETWORK +# define FILE_DEVICE_NETWORK 0x00000012 +#endif + +#ifndef METHOD_BUFFERED +# define METHOD_BUFFERED 0 +#endif + +#ifndef METHOD_IN_DIRECT +# define METHOD_IN_DIRECT 1 +#endif + +#ifndef METHOD_OUT_DIRECT +# define METHOD_OUT_DIRECT 2 +#endif + +#ifndef METHOD_NEITHER +#define METHOD_NEITHER 3 +#endif + +#ifndef METHOD_DIRECT_TO_HARDWARE +# define METHOD_DIRECT_TO_HARDWARE METHOD_IN_DIRECT +#endif + +#ifndef METHOD_DIRECT_FROM_HARDWARE +# define METHOD_DIRECT_FROM_HARDWARE METHOD_OUT_DIRECT +#endif + +#ifndef FILE_ANY_ACCESS +# define FILE_ANY_ACCESS 0 +#endif + +#ifndef FILE_SPECIAL_ACCESS +# define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS) +#endif + +#ifndef FILE_READ_ACCESS +# define FILE_READ_ACCESS 0x0001 +#endif + +#ifndef FILE_WRITE_ACCESS +# define FILE_WRITE_ACCESS 0x0002 +#endif + +#ifndef CTL_CODE +# define CTL_CODE(device_type, function, method, access) \ + (((device_type) << 16) | ((access) << 14) | ((function) << 2) | (method)) +#endif + +#ifndef FSCTL_SET_REPARSE_POINT +# define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \ + 41, \ + METHOD_BUFFERED, \ + FILE_SPECIAL_ACCESS) +#endif + +#ifndef FSCTL_GET_REPARSE_POINT +# define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \ + 42, \ + METHOD_BUFFERED, \ + FILE_ANY_ACCESS) +#endif + +#ifndef FSCTL_DELETE_REPARSE_POINT +# define FSCTL_DELETE_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \ + 43, \ + METHOD_BUFFERED, \ + FILE_SPECIAL_ACCESS) +#endif + +#ifndef IO_REPARSE_TAG_SYMLINK +# define IO_REPARSE_TAG_SYMLINK (0xA000000CL) +#endif +#ifndef IO_REPARSE_TAG_APPEXECLINK +# define IO_REPARSE_TAG_APPEXECLINK (0x8000001BL) +#endif + +typedef VOID (NTAPI *PIO_APC_ROUTINE) + (PVOID ApcContext, + PIO_STATUS_BLOCK IoStatusBlock, + ULONG Reserved); + +typedef NTSTATUS (NTAPI *sRtlGetVersion) + (PRTL_OSVERSIONINFOW lpVersionInformation); + +typedef ULONG (NTAPI *sRtlNtStatusToDosError) + (NTSTATUS Status); + +typedef NTSTATUS (NTAPI *sNtDeviceIoControlFile) + (HANDLE FileHandle, + HANDLE Event, + PIO_APC_ROUTINE ApcRoutine, + PVOID ApcContext, + PIO_STATUS_BLOCK IoStatusBlock, + ULONG IoControlCode, + PVOID InputBuffer, + ULONG InputBufferLength, + PVOID OutputBuffer, + ULONG OutputBufferLength); + +typedef NTSTATUS (NTAPI *sNtQueryInformationFile) + (HANDLE FileHandle, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID FileInformation, + ULONG Length, + FILE_INFORMATION_CLASS FileInformationClass); + +typedef NTSTATUS (NTAPI *sNtSetInformationFile) + (HANDLE FileHandle, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID FileInformation, + ULONG Length, + FILE_INFORMATION_CLASS FileInformationClass); + +typedef NTSTATUS (NTAPI *sNtQueryVolumeInformationFile) + (HANDLE FileHandle, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID FsInformation, + ULONG Length, + FS_INFORMATION_CLASS FsInformationClass); + +typedef NTSTATUS (NTAPI *sNtQuerySystemInformation) + (UINT SystemInformationClass, + PVOID SystemInformation, + ULONG SystemInformationLength, + PULONG ReturnLength); + +typedef NTSTATUS (NTAPI *sNtQueryDirectoryFile) + (HANDLE FileHandle, + HANDLE Event, + PIO_APC_ROUTINE ApcRoutine, + PVOID ApcContext, + PIO_STATUS_BLOCK IoStatusBlock, + PVOID FileInformation, + ULONG Length, + FILE_INFORMATION_CLASS FileInformationClass, + BOOLEAN ReturnSingleEntry, + PUNICODE_STRING FileName, + BOOLEAN RestartScan + ); + +typedef NTSTATUS (NTAPI *sNtQueryInformationProcess) + (HANDLE ProcessHandle, + UINT ProcessInformationClass, + PVOID ProcessInformation, + ULONG Length, + PULONG ReturnLength); + +/* + * Kernel32 headers + */ +#ifndef FILE_SKIP_COMPLETION_PORT_ON_SUCCESS +# define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 0x1 +#endif + +#ifndef FILE_SKIP_SET_EVENT_ON_HANDLE +# define FILE_SKIP_SET_EVENT_ON_HANDLE 0x2 +#endif + +#ifndef SYMBOLIC_LINK_FLAG_DIRECTORY +# define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1 +#endif + +#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) + typedef struct _OVERLAPPED_ENTRY { + ULONG_PTR lpCompletionKey; + LPOVERLAPPED lpOverlapped; + ULONG_PTR Internal; + DWORD dwNumberOfBytesTransferred; + } OVERLAPPED_ENTRY, *LPOVERLAPPED_ENTRY; +#endif + +/* from wincon.h */ +#ifndef ENABLE_INSERT_MODE +# define ENABLE_INSERT_MODE 0x20 +#endif + +#ifndef ENABLE_QUICK_EDIT_MODE +# define ENABLE_QUICK_EDIT_MODE 0x40 +#endif + +#ifndef ENABLE_EXTENDED_FLAGS +# define ENABLE_EXTENDED_FLAGS 0x80 +#endif + +/* from winerror.h */ +#ifndef ERROR_ELEVATION_REQUIRED +# define ERROR_ELEVATION_REQUIRED 740 +#endif + +#ifndef ERROR_SYMLINK_NOT_SUPPORTED +# define ERROR_SYMLINK_NOT_SUPPORTED 1464 +#endif + +#ifndef ERROR_MUI_FILE_NOT_FOUND +# define ERROR_MUI_FILE_NOT_FOUND 15100 +#endif + +#ifndef ERROR_MUI_INVALID_FILE +# define ERROR_MUI_INVALID_FILE 15101 +#endif + +#ifndef ERROR_MUI_INVALID_RC_CONFIG +# define ERROR_MUI_INVALID_RC_CONFIG 15102 +#endif + +#ifndef ERROR_MUI_INVALID_LOCALE_NAME +# define ERROR_MUI_INVALID_LOCALE_NAME 15103 +#endif + +#ifndef ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME +# define ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME 15104 +#endif + +#ifndef ERROR_MUI_FILE_NOT_LOADED +# define ERROR_MUI_FILE_NOT_LOADED 15105 +#endif + +typedef BOOL (WINAPI *sGetQueuedCompletionStatusEx) + (HANDLE CompletionPort, + LPOVERLAPPED_ENTRY lpCompletionPortEntries, + ULONG ulCount, + PULONG ulNumEntriesRemoved, + DWORD dwMilliseconds, + BOOL fAlertable); + +/* from powerbase.h */ +#ifndef DEVICE_NOTIFY_CALLBACK +# define DEVICE_NOTIFY_CALLBACK 2 +#endif + +#ifndef PBT_APMRESUMEAUTOMATIC +# define PBT_APMRESUMEAUTOMATIC 18 +#endif + +#ifndef PBT_APMRESUMESUSPEND +# define PBT_APMRESUMESUSPEND 7 +#endif + +typedef ULONG CALLBACK _DEVICE_NOTIFY_CALLBACK_ROUTINE( + PVOID Context, + ULONG Type, + PVOID Setting +); +typedef _DEVICE_NOTIFY_CALLBACK_ROUTINE* _PDEVICE_NOTIFY_CALLBACK_ROUTINE; + +typedef struct _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS { + _PDEVICE_NOTIFY_CALLBACK_ROUTINE Callback; + PVOID Context; +} _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS, *_PDEVICE_NOTIFY_SUBSCRIBE_PARAMETERS; + +typedef PVOID _HPOWERNOTIFY; +typedef _HPOWERNOTIFY *_PHPOWERNOTIFY; + +typedef DWORD (WINAPI *sPowerRegisterSuspendResumeNotification) + (DWORD Flags, + HANDLE Recipient, + _PHPOWERNOTIFY RegistrationHandle); + +/* from Winuser.h */ +typedef VOID (CALLBACK* WINEVENTPROC) + (HWINEVENTHOOK hWinEventHook, + DWORD event, + HWND hwnd, + LONG idObject, + LONG idChild, + DWORD idEventThread, + DWORD dwmsEventTime); + +typedef HWINEVENTHOOK (WINAPI *sSetWinEventHook) + (UINT eventMin, + UINT eventMax, + HMODULE hmodWinEventProc, + WINEVENTPROC lpfnWinEventProc, + DWORD idProcess, + DWORD idThread, + UINT dwflags); + +/* From mstcpip.h */ +typedef struct _TCP_INITIAL_RTO_PARAMETERS { + USHORT Rtt; + UCHAR MaxSynRetransmissions; +} TCP_INITIAL_RTO_PARAMETERS, *PTCP_INITIAL_RTO_PARAMETERS; + +#ifndef TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS +# define TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS ((UCHAR) -2) +#endif +#ifndef SIO_TCP_INITIAL_RTO +# define SIO_TCP_INITIAL_RTO _WSAIOW(IOC_VENDOR,17) +#endif + +/* Ntdll function pointers */ +extern sRtlGetVersion pRtlGetVersion; +extern sRtlNtStatusToDosError pRtlNtStatusToDosError; +extern sNtDeviceIoControlFile pNtDeviceIoControlFile; +extern sNtQueryInformationFile pNtQueryInformationFile; +extern sNtSetInformationFile pNtSetInformationFile; +extern sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile; +extern sNtQueryDirectoryFile pNtQueryDirectoryFile; +extern sNtQuerySystemInformation pNtQuerySystemInformation; +extern sNtQueryInformationProcess pNtQueryInformationProcess; + +/* Kernel32 function pointers */ +extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx; + +/* Powrprof.dll function pointer */ +extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification; + +/* User32.dll function pointer */ +extern sSetWinEventHook pSetWinEventHook; + +#endif /* UV_WIN_WINAPI_H_ */ diff --git a/external/src/libuv/src/win/winsock.c b/external/src/libuv/src/win/winsock.c new file mode 100644 index 0000000..4cf6e6b --- /dev/null +++ b/external/src/libuv/src/win/winsock.c @@ -0,0 +1,575 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include + +#include "uv.h" +#include "internal.h" + + +/* Whether there are any non-IFS LSPs stacked on TCP */ +int uv_tcp_non_ifs_lsp_ipv4; +int uv_tcp_non_ifs_lsp_ipv6; + +/* Ip address used to bind to any port at any interface */ +struct sockaddr_in uv_addr_ip4_any_; +struct sockaddr_in6 uv_addr_ip6_any_; + + +/* + * Retrieves the pointer to a winsock extension function. + */ +static BOOL uv_get_extension_function(SOCKET socket, GUID guid, + void **target) { + int result; + DWORD bytes; + + result = WSAIoctl(socket, + SIO_GET_EXTENSION_FUNCTION_POINTER, + &guid, + sizeof(guid), + (void*)target, + sizeof(*target), + &bytes, + NULL, + NULL); + + if (result == SOCKET_ERROR) { + *target = NULL; + return FALSE; + } else { + return TRUE; + } +} + + +BOOL uv_get_acceptex_function(SOCKET socket, LPFN_ACCEPTEX* target) { + const GUID wsaid_acceptex = WSAID_ACCEPTEX; + return uv_get_extension_function(socket, wsaid_acceptex, (void**)target); +} + + +BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target) { + const GUID wsaid_connectex = WSAID_CONNECTEX; + return uv_get_extension_function(socket, wsaid_connectex, (void**)target); +} + + + +void uv_winsock_init(void) { + WSADATA wsa_data; + int errorno; + SOCKET dummy; + WSAPROTOCOL_INFOW protocol_info; + int opt_len; + + /* Set implicit binding address used by connectEx */ + if (uv_ip4_addr("0.0.0.0", 0, &uv_addr_ip4_any_)) { + abort(); + } + + if (uv_ip6_addr("::", 0, &uv_addr_ip6_any_)) { + abort(); + } + + /* Skip initialization in safe mode without network support */ + if (1 == GetSystemMetrics(SM_CLEANBOOT)) return; + + /* Initialize winsock */ + errorno = WSAStartup(MAKEWORD(2, 2), &wsa_data); + if (errorno != 0) { + uv_fatal_error(errorno, "WSAStartup"); + } + + /* Try to detect non-IFS LSPs */ + uv_tcp_non_ifs_lsp_ipv4 = 1; + dummy = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); + if (dummy != INVALID_SOCKET) { + opt_len = (int) sizeof protocol_info; + if (getsockopt(dummy, + SOL_SOCKET, + SO_PROTOCOL_INFOW, + (char*) &protocol_info, + &opt_len) == 0) { + if (protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES) + uv_tcp_non_ifs_lsp_ipv4 = 0; + } + closesocket(dummy); + } + + /* Try to detect IPV6 support and non-IFS LSPs */ + uv_tcp_non_ifs_lsp_ipv6 = 1; + dummy = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP); + if (dummy != INVALID_SOCKET) { + opt_len = (int) sizeof protocol_info; + if (getsockopt(dummy, + SOL_SOCKET, + SO_PROTOCOL_INFOW, + (char*) &protocol_info, + &opt_len) == 0) { + if (protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES) + uv_tcp_non_ifs_lsp_ipv6 = 0; + } + closesocket(dummy); + } +} + + +int uv_ntstatus_to_winsock_error(NTSTATUS status) { + switch (status) { + case STATUS_SUCCESS: + return ERROR_SUCCESS; + + case STATUS_PENDING: + return ERROR_IO_PENDING; + + case STATUS_INVALID_HANDLE: + case STATUS_OBJECT_TYPE_MISMATCH: + return WSAENOTSOCK; + + case STATUS_INSUFFICIENT_RESOURCES: + case STATUS_PAGEFILE_QUOTA: + case STATUS_COMMITMENT_LIMIT: + case STATUS_WORKING_SET_QUOTA: + case STATUS_NO_MEMORY: + case STATUS_QUOTA_EXCEEDED: + case STATUS_TOO_MANY_PAGING_FILES: + case STATUS_REMOTE_RESOURCES: + return WSAENOBUFS; + + case STATUS_TOO_MANY_ADDRESSES: + case STATUS_SHARING_VIOLATION: + case STATUS_ADDRESS_ALREADY_EXISTS: + return WSAEADDRINUSE; + + case STATUS_LINK_TIMEOUT: + case STATUS_IO_TIMEOUT: + case STATUS_TIMEOUT: + return WSAETIMEDOUT; + + case STATUS_GRACEFUL_DISCONNECT: + return WSAEDISCON; + + case STATUS_REMOTE_DISCONNECT: + case STATUS_CONNECTION_RESET: + case STATUS_LINK_FAILED: + case STATUS_CONNECTION_DISCONNECTED: + case STATUS_PORT_UNREACHABLE: + case STATUS_HOPLIMIT_EXCEEDED: + return WSAECONNRESET; + + case STATUS_LOCAL_DISCONNECT: + case STATUS_TRANSACTION_ABORTED: + case STATUS_CONNECTION_ABORTED: + return WSAECONNABORTED; + + case STATUS_BAD_NETWORK_PATH: + case STATUS_NETWORK_UNREACHABLE: + case STATUS_PROTOCOL_UNREACHABLE: + return WSAENETUNREACH; + + case STATUS_HOST_UNREACHABLE: + return WSAEHOSTUNREACH; + + case STATUS_CANCELLED: + case STATUS_REQUEST_ABORTED: + return WSAEINTR; + + case STATUS_BUFFER_OVERFLOW: + case STATUS_INVALID_BUFFER_SIZE: + return WSAEMSGSIZE; + + case STATUS_BUFFER_TOO_SMALL: + case STATUS_ACCESS_VIOLATION: + return WSAEFAULT; + + case STATUS_DEVICE_NOT_READY: + case STATUS_REQUEST_NOT_ACCEPTED: + return WSAEWOULDBLOCK; + + case STATUS_INVALID_NETWORK_RESPONSE: + case STATUS_NETWORK_BUSY: + case STATUS_NO_SUCH_DEVICE: + case STATUS_NO_SUCH_FILE: + case STATUS_OBJECT_PATH_NOT_FOUND: + case STATUS_OBJECT_NAME_NOT_FOUND: + case STATUS_UNEXPECTED_NETWORK_ERROR: + return WSAENETDOWN; + + case STATUS_INVALID_CONNECTION: + return WSAENOTCONN; + + case STATUS_REMOTE_NOT_LISTENING: + case STATUS_CONNECTION_REFUSED: + return WSAECONNREFUSED; + + case STATUS_PIPE_DISCONNECTED: + return WSAESHUTDOWN; + + case STATUS_CONFLICTING_ADDRESSES: + case STATUS_INVALID_ADDRESS: + case STATUS_INVALID_ADDRESS_COMPONENT: + return WSAEADDRNOTAVAIL; + + case STATUS_NOT_SUPPORTED: + case STATUS_NOT_IMPLEMENTED: + return WSAEOPNOTSUPP; + + case STATUS_ACCESS_DENIED: + return WSAEACCES; + + default: + if ((status & (FACILITY_NTWIN32 << 16)) == (FACILITY_NTWIN32 << 16) && + (status & (ERROR_SEVERITY_ERROR | ERROR_SEVERITY_WARNING))) { + /* It's a windows error that has been previously mapped to an ntstatus + * code. */ + return (DWORD) (status & 0xffff); + } else { + /* The default fallback for unmappable ntstatus codes. */ + return WSAEINVAL; + } + } +} + + +/* + * This function provides a workaround for a bug in the winsock implementation + * of WSARecv. The problem is that when SetFileCompletionNotificationModes is + * used to avoid IOCP notifications of completed reads, WSARecv does not + * reliably indicate whether we can expect a completion package to be posted + * when the receive buffer is smaller than the received datagram. + * + * However it is desirable to use SetFileCompletionNotificationModes because + * it yields a massive performance increase. + * + * This function provides a workaround for that bug, but it only works for the + * specific case that we need it for. E.g. it assumes that the "avoid iocp" + * bit has been set, and supports only overlapped operation. It also requires + * the user to use the default msafd driver, doesn't work when other LSPs are + * stacked on top of it. + */ +int WSAAPI uv_wsarecv_workaround(SOCKET socket, WSABUF* buffers, + DWORD buffer_count, DWORD* bytes, DWORD* flags, WSAOVERLAPPED *overlapped, + LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine) { + NTSTATUS status; + void* apc_context; + IO_STATUS_BLOCK* iosb = (IO_STATUS_BLOCK*) &overlapped->Internal; + AFD_RECV_INFO info; + DWORD error; + + if (overlapped == NULL || completion_routine != NULL) { + WSASetLastError(WSAEINVAL); + return SOCKET_ERROR; + } + + info.BufferArray = buffers; + info.BufferCount = buffer_count; + info.AfdFlags = AFD_OVERLAPPED; + info.TdiFlags = TDI_RECEIVE_NORMAL; + + if (*flags & MSG_PEEK) { + info.TdiFlags |= TDI_RECEIVE_PEEK; + } + + if (*flags & MSG_PARTIAL) { + info.TdiFlags |= TDI_RECEIVE_PARTIAL; + } + + if (!((intptr_t) overlapped->hEvent & 1)) { + apc_context = (void*) overlapped; + } else { + apc_context = NULL; + } + + iosb->Status = STATUS_PENDING; + iosb->Pointer = 0; + + status = pNtDeviceIoControlFile((HANDLE) socket, + overlapped->hEvent, + NULL, + apc_context, + iosb, + IOCTL_AFD_RECEIVE, + &info, + sizeof(info), + NULL, + 0); + + *flags = 0; + *bytes = (DWORD) iosb->Information; + + switch (status) { + case STATUS_SUCCESS: + error = ERROR_SUCCESS; + break; + + case STATUS_PENDING: + error = WSA_IO_PENDING; + break; + + case STATUS_BUFFER_OVERFLOW: + error = WSAEMSGSIZE; + break; + + case STATUS_RECEIVE_EXPEDITED: + error = ERROR_SUCCESS; + *flags = MSG_OOB; + break; + + case STATUS_RECEIVE_PARTIAL_EXPEDITED: + error = ERROR_SUCCESS; + *flags = MSG_PARTIAL | MSG_OOB; + break; + + case STATUS_RECEIVE_PARTIAL: + error = ERROR_SUCCESS; + *flags = MSG_PARTIAL; + break; + + default: + error = uv_ntstatus_to_winsock_error(status); + break; + } + + WSASetLastError(error); + + if (error == ERROR_SUCCESS) { + return 0; + } else { + return SOCKET_ERROR; + } +} + + +/* See description of uv_wsarecv_workaround. */ +int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers, + DWORD buffer_count, DWORD* bytes, DWORD* flags, struct sockaddr* addr, + int* addr_len, WSAOVERLAPPED *overlapped, + LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine) { + NTSTATUS status; + void* apc_context; + IO_STATUS_BLOCK* iosb = (IO_STATUS_BLOCK*) &overlapped->Internal; + AFD_RECV_DATAGRAM_INFO info; + DWORD error; + + if (overlapped == NULL || addr == NULL || addr_len == NULL || + completion_routine != NULL) { + WSASetLastError(WSAEINVAL); + return SOCKET_ERROR; + } + + info.BufferArray = buffers; + info.BufferCount = buffer_count; + info.AfdFlags = AFD_OVERLAPPED; + info.TdiFlags = TDI_RECEIVE_NORMAL; + info.Address = addr; + info.AddressLength = addr_len; + + if (*flags & MSG_PEEK) { + info.TdiFlags |= TDI_RECEIVE_PEEK; + } + + if (*flags & MSG_PARTIAL) { + info.TdiFlags |= TDI_RECEIVE_PARTIAL; + } + + if (!((intptr_t) overlapped->hEvent & 1)) { + apc_context = (void*) overlapped; + } else { + apc_context = NULL; + } + + iosb->Status = STATUS_PENDING; + iosb->Pointer = 0; + + status = pNtDeviceIoControlFile((HANDLE) socket, + overlapped->hEvent, + NULL, + apc_context, + iosb, + IOCTL_AFD_RECEIVE_DATAGRAM, + &info, + sizeof(info), + NULL, + 0); + + *flags = 0; + *bytes = (DWORD) iosb->Information; + + switch (status) { + case STATUS_SUCCESS: + error = ERROR_SUCCESS; + break; + + case STATUS_PENDING: + error = WSA_IO_PENDING; + break; + + case STATUS_BUFFER_OVERFLOW: + error = WSAEMSGSIZE; + break; + + case STATUS_RECEIVE_EXPEDITED: + error = ERROR_SUCCESS; + *flags = MSG_OOB; + break; + + case STATUS_RECEIVE_PARTIAL_EXPEDITED: + error = ERROR_SUCCESS; + *flags = MSG_PARTIAL | MSG_OOB; + break; + + case STATUS_RECEIVE_PARTIAL: + error = ERROR_SUCCESS; + *flags = MSG_PARTIAL; + break; + + default: + error = uv_ntstatus_to_winsock_error(status); + break; + } + + WSASetLastError(error); + + if (error == ERROR_SUCCESS) { + return 0; + } else { + return SOCKET_ERROR; + } +} + + +int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in, + AFD_POLL_INFO* info_out, OVERLAPPED* overlapped) { + IO_STATUS_BLOCK iosb; + IO_STATUS_BLOCK* iosb_ptr; + HANDLE event = NULL; + void* apc_context; + NTSTATUS status; + DWORD error; + + if (overlapped != NULL) { + /* Overlapped operation. */ + iosb_ptr = (IO_STATUS_BLOCK*) &overlapped->Internal; + event = overlapped->hEvent; + + /* Do not report iocp completion if hEvent is tagged. */ + if ((uintptr_t) event & 1) { + event = (HANDLE)((uintptr_t) event & ~(uintptr_t) 1); + apc_context = NULL; + } else { + apc_context = overlapped; + } + + } else { + /* Blocking operation. */ + iosb_ptr = &iosb; + event = CreateEvent(NULL, FALSE, FALSE, NULL); + if (event == NULL) { + return SOCKET_ERROR; + } + apc_context = NULL; + } + + iosb_ptr->Status = STATUS_PENDING; + status = pNtDeviceIoControlFile((HANDLE) socket, + event, + NULL, + apc_context, + iosb_ptr, + IOCTL_AFD_POLL, + info_in, + sizeof *info_in, + info_out, + sizeof *info_out); + + if (overlapped == NULL) { + /* If this is a blocking operation, wait for the event to become signaled, + * and then grab the real status from the io status block. */ + if (status == STATUS_PENDING) { + DWORD r = WaitForSingleObject(event, INFINITE); + + if (r == WAIT_FAILED) { + DWORD saved_error = GetLastError(); + CloseHandle(event); + WSASetLastError(saved_error); + return SOCKET_ERROR; + } + + status = iosb.Status; + } + + CloseHandle(event); + } + + switch (status) { + case STATUS_SUCCESS: + error = ERROR_SUCCESS; + break; + + case STATUS_PENDING: + error = WSA_IO_PENDING; + break; + + default: + error = uv_ntstatus_to_winsock_error(status); + break; + } + + WSASetLastError(error); + + if (error == ERROR_SUCCESS) { + return 0; + } else { + return SOCKET_ERROR; + } +} + +int uv__convert_to_localhost_if_unspecified(const struct sockaddr* addr, + struct sockaddr_storage* storage) { + struct sockaddr_in* dest4; + struct sockaddr_in6* dest6; + + if (addr == NULL) + return UV_EINVAL; + + switch (addr->sa_family) { + case AF_INET: + dest4 = (struct sockaddr_in*) storage; + memcpy(dest4, addr, sizeof(*dest4)); + if (dest4->sin_addr.s_addr == 0) + dest4->sin_addr.s_addr = htonl(INADDR_LOOPBACK); + return 0; + case AF_INET6: + dest6 = (struct sockaddr_in6*) storage; + memcpy(dest6, addr, sizeof(*dest6)); + if (memcmp(&dest6->sin6_addr, + &uv_addr_ip6_any_.sin6_addr, + sizeof(uv_addr_ip6_any_.sin6_addr)) == 0) { + struct in6_addr init_sin6_addr = IN6ADDR_LOOPBACK_INIT; + dest6->sin6_addr = init_sin6_addr; + } + return 0; + default: + return UV_EINVAL; + } +} diff --git a/external/src/libuv/src/win/winsock.h b/external/src/libuv/src/win/winsock.h new file mode 100644 index 0000000..2af9588 --- /dev/null +++ b/external/src/libuv/src/win/winsock.h @@ -0,0 +1,201 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef UV_WIN_WINSOCK_H_ +#define UV_WIN_WINSOCK_H_ + +#include +#include +#include +#include +#include + +#include "winapi.h" + + +/* + * MinGW is missing these too + */ +#ifndef SO_UPDATE_CONNECT_CONTEXT +# define SO_UPDATE_CONNECT_CONTEXT 0x7010 +#endif + +#ifndef TCP_KEEPALIVE +# define TCP_KEEPALIVE 3 +#endif + +#ifndef IPV6_V6ONLY +# define IPV6_V6ONLY 27 +#endif + +#ifndef IPV6_HOPLIMIT +# define IPV6_HOPLIMIT 21 +#endif + +#ifndef SIO_BASE_HANDLE +# define SIO_BASE_HANDLE 0x48000022 +#endif + +#ifndef MCAST_JOIN_SOURCE_GROUP +# define MCAST_JOIN_SOURCE_GROUP 45 +#endif + +#ifndef MCAST_LEAVE_SOURCE_GROUP +# define MCAST_LEAVE_SOURCE_GROUP 46 +#endif + +/* + * TDI defines that are only in the DDK. + * We only need receive flags so far. + */ +#ifndef TDI_RECEIVE_NORMAL + #define TDI_RECEIVE_BROADCAST 0x00000004 + #define TDI_RECEIVE_MULTICAST 0x00000008 + #define TDI_RECEIVE_PARTIAL 0x00000010 + #define TDI_RECEIVE_NORMAL 0x00000020 + #define TDI_RECEIVE_EXPEDITED 0x00000040 + #define TDI_RECEIVE_PEEK 0x00000080 + #define TDI_RECEIVE_NO_RESPONSE_EXP 0x00000100 + #define TDI_RECEIVE_COPY_LOOKAHEAD 0x00000200 + #define TDI_RECEIVE_ENTIRE_MESSAGE 0x00000400 + #define TDI_RECEIVE_AT_DISPATCH_LEVEL 0x00000800 + #define TDI_RECEIVE_CONTROL_INFO 0x00001000 + #define TDI_RECEIVE_FORCE_INDICATION 0x00002000 + #define TDI_RECEIVE_NO_PUSH 0x00004000 +#endif + +/* + * The "Auxiliary Function Driver" is the windows kernel-mode driver that does + * TCP, UDP etc. Winsock is just a layer that dispatches requests to it. + * Having these definitions allows us to bypass winsock and make an AFD kernel + * call directly, avoiding a bug in winsock's recvfrom implementation. + */ + +#define AFD_NO_FAST_IO 0x00000001 +#define AFD_OVERLAPPED 0x00000002 +#define AFD_IMMEDIATE 0x00000004 + +#define AFD_POLL_RECEIVE_BIT 0 +#define AFD_POLL_RECEIVE (1 << AFD_POLL_RECEIVE_BIT) +#define AFD_POLL_RECEIVE_EXPEDITED_BIT 1 +#define AFD_POLL_RECEIVE_EXPEDITED (1 << AFD_POLL_RECEIVE_EXPEDITED_BIT) +#define AFD_POLL_SEND_BIT 2 +#define AFD_POLL_SEND (1 << AFD_POLL_SEND_BIT) +#define AFD_POLL_DISCONNECT_BIT 3 +#define AFD_POLL_DISCONNECT (1 << AFD_POLL_DISCONNECT_BIT) +#define AFD_POLL_ABORT_BIT 4 +#define AFD_POLL_ABORT (1 << AFD_POLL_ABORT_BIT) +#define AFD_POLL_LOCAL_CLOSE_BIT 5 +#define AFD_POLL_LOCAL_CLOSE (1 << AFD_POLL_LOCAL_CLOSE_BIT) +#define AFD_POLL_CONNECT_BIT 6 +#define AFD_POLL_CONNECT (1 << AFD_POLL_CONNECT_BIT) +#define AFD_POLL_ACCEPT_BIT 7 +#define AFD_POLL_ACCEPT (1 << AFD_POLL_ACCEPT_BIT) +#define AFD_POLL_CONNECT_FAIL_BIT 8 +#define AFD_POLL_CONNECT_FAIL (1 << AFD_POLL_CONNECT_FAIL_BIT) +#define AFD_POLL_QOS_BIT 9 +#define AFD_POLL_QOS (1 << AFD_POLL_QOS_BIT) +#define AFD_POLL_GROUP_QOS_BIT 10 +#define AFD_POLL_GROUP_QOS (1 << AFD_POLL_GROUP_QOS_BIT) + +#define AFD_NUM_POLL_EVENTS 11 +#define AFD_POLL_ALL ((1 << AFD_NUM_POLL_EVENTS) - 1) + +typedef struct _AFD_RECV_DATAGRAM_INFO { + LPWSABUF BufferArray; + ULONG BufferCount; + ULONG AfdFlags; + ULONG TdiFlags; + struct sockaddr* Address; + int* AddressLength; +} AFD_RECV_DATAGRAM_INFO, *PAFD_RECV_DATAGRAM_INFO; + +typedef struct _AFD_RECV_INFO { + LPWSABUF BufferArray; + ULONG BufferCount; + ULONG AfdFlags; + ULONG TdiFlags; +} AFD_RECV_INFO, *PAFD_RECV_INFO; + + +#define _AFD_CONTROL_CODE(operation, method) \ + ((FSCTL_AFD_BASE) << 12 | (operation << 2) | method) + +#define FSCTL_AFD_BASE FILE_DEVICE_NETWORK + +#define AFD_RECEIVE 5 +#define AFD_RECEIVE_DATAGRAM 6 +#define AFD_POLL 9 + +#define IOCTL_AFD_RECEIVE \ + _AFD_CONTROL_CODE(AFD_RECEIVE, METHOD_NEITHER) + +#define IOCTL_AFD_RECEIVE_DATAGRAM \ + _AFD_CONTROL_CODE(AFD_RECEIVE_DATAGRAM, METHOD_NEITHER) + +#define IOCTL_AFD_POLL \ + _AFD_CONTROL_CODE(AFD_POLL, METHOD_BUFFERED) + +#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) +typedef struct _IP_ADAPTER_UNICAST_ADDRESS_XP { + /* FIXME: __C89_NAMELESS was removed */ + /* __C89_NAMELESS */ union { + ULONGLONG Alignment; + /* __C89_NAMELESS */ struct { + ULONG Length; + DWORD Flags; + }; + }; + struct _IP_ADAPTER_UNICAST_ADDRESS_XP *Next; + SOCKET_ADDRESS Address; + IP_PREFIX_ORIGIN PrefixOrigin; + IP_SUFFIX_ORIGIN SuffixOrigin; + IP_DAD_STATE DadState; + ULONG ValidLifetime; + ULONG PreferredLifetime; + ULONG LeaseLifetime; +} IP_ADAPTER_UNICAST_ADDRESS_XP,*PIP_ADAPTER_UNICAST_ADDRESS_XP; + +typedef struct _IP_ADAPTER_UNICAST_ADDRESS_LH { + union { + ULONGLONG Alignment; + struct { + ULONG Length; + DWORD Flags; + }; + }; + struct _IP_ADAPTER_UNICAST_ADDRESS_LH *Next; + SOCKET_ADDRESS Address; + IP_PREFIX_ORIGIN PrefixOrigin; + IP_SUFFIX_ORIGIN SuffixOrigin; + IP_DAD_STATE DadState; + ULONG ValidLifetime; + ULONG PreferredLifetime; + ULONG LeaseLifetime; + UINT8 OnLinkPrefixLength; +} IP_ADAPTER_UNICAST_ADDRESS_LH,*PIP_ADAPTER_UNICAST_ADDRESS_LH; + +#endif + +int uv__convert_to_localhost_if_unspecified(const struct sockaddr* addr, + struct sockaddr_storage* storage); + +#endif /* UV_WIN_WINSOCK_H_ */ diff --git a/external/src/libuv/test/benchmark-async-pummel.c b/external/src/libuv/test/benchmark-async-pummel.c new file mode 100644 index 0000000..49660a6 --- /dev/null +++ b/external/src/libuv/test/benchmark-async-pummel.c @@ -0,0 +1,119 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" +#include "uv.h" + +#include +#include + +#define NUM_PINGS (1000 * 1000) +#define ACCESS_ONCE(type, var) (*(volatile type*) &(var)) + +static unsigned int callbacks; +static volatile int done; + +static const char running[] = "running"; +static const char stop[] = "stop"; +static const char stopped[] = "stopped"; + + +static void async_cb(uv_async_t* handle) { + if (++callbacks == NUM_PINGS) { + /* Tell the pummel thread to stop. */ + ACCESS_ONCE(const char*, handle->data) = stop; + + /* Wait for the pummel thread to acknowledge that it has stoppped. */ + while (ACCESS_ONCE(const char*, handle->data) != stopped) + uv_sleep(0); + + uv_close((uv_handle_t*) handle, NULL); + } +} + + +static void pummel(void* arg) { + uv_async_t* handle = (uv_async_t*) arg; + + while (ACCESS_ONCE(const char*, handle->data) == running) + uv_async_send(handle); + + /* Acknowledge that we've seen handle->data change. */ + ACCESS_ONCE(const char*, handle->data) = stopped; +} + + +static int test_async_pummel(int nthreads) { + uv_thread_t* tids; + uv_async_t handle; + uint64_t time; + int i; + + tids = calloc(nthreads, sizeof(tids[0])); + ASSERT_NOT_NULL(tids); + + ASSERT(0 == uv_async_init(uv_default_loop(), &handle, async_cb)); + ACCESS_ONCE(const char*, handle.data) = running; + + for (i = 0; i < nthreads; i++) + ASSERT(0 == uv_thread_create(tids + i, pummel, &handle)); + + time = uv_hrtime(); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + time = uv_hrtime() - time; + done = 1; + + for (i = 0; i < nthreads; i++) + ASSERT(0 == uv_thread_join(tids + i)); + + printf("async_pummel_%d: %s callbacks in %.2f seconds (%s/sec)\n", + nthreads, + fmt(callbacks), + time / 1e9, + fmt(callbacks / (time / 1e9))); + + free(tids); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +BENCHMARK_IMPL(async_pummel_1) { + return test_async_pummel(1); +} + + +BENCHMARK_IMPL(async_pummel_2) { + return test_async_pummel(2); +} + + +BENCHMARK_IMPL(async_pummel_4) { + return test_async_pummel(4); +} + + +BENCHMARK_IMPL(async_pummel_8) { + return test_async_pummel(8); +} diff --git a/external/src/libuv/test/benchmark-async.c b/external/src/libuv/test/benchmark-async.c new file mode 100644 index 0000000..5167ecb --- /dev/null +++ b/external/src/libuv/test/benchmark-async.c @@ -0,0 +1,141 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" +#include "uv.h" + +#include +#include + +#define NUM_PINGS (1000 * 1000) + +struct ctx { + uv_loop_t loop; + uv_thread_t thread; + uv_async_t main_async; /* wake up main thread */ + uv_async_t worker_async; /* wake up worker */ + unsigned int nthreads; + unsigned int main_sent; + unsigned int main_seen; + unsigned int worker_sent; + unsigned int worker_seen; +}; + + +static void worker_async_cb(uv_async_t* handle) { + struct ctx* ctx = container_of(handle, struct ctx, worker_async); + + ASSERT(0 == uv_async_send(&ctx->main_async)); + ctx->worker_sent++; + ctx->worker_seen++; + + if (ctx->worker_sent >= NUM_PINGS) + uv_close((uv_handle_t*) &ctx->worker_async, NULL); +} + + +static void main_async_cb(uv_async_t* handle) { + struct ctx* ctx = container_of(handle, struct ctx, main_async); + + ASSERT(0 == uv_async_send(&ctx->worker_async)); + ctx->main_sent++; + ctx->main_seen++; + + if (ctx->main_sent >= NUM_PINGS) + uv_close((uv_handle_t*) &ctx->main_async, NULL); +} + + +static void worker(void* arg) { + struct ctx* ctx = arg; + ASSERT(0 == uv_async_send(&ctx->main_async)); + ASSERT(0 == uv_run(&ctx->loop, UV_RUN_DEFAULT)); + uv_loop_close(&ctx->loop); +} + + +static int test_async(int nthreads) { + struct ctx* threads; + struct ctx* ctx; + uint64_t time; + int i; + + threads = calloc(nthreads, sizeof(threads[0])); + ASSERT_NOT_NULL(threads); + + for (i = 0; i < nthreads; i++) { + ctx = threads + i; + ctx->nthreads = nthreads; + ASSERT(0 == uv_loop_init(&ctx->loop)); + ASSERT(0 == uv_async_init(&ctx->loop, &ctx->worker_async, worker_async_cb)); + ASSERT(0 == uv_async_init(uv_default_loop(), + &ctx->main_async, + main_async_cb)); + ASSERT(0 == uv_thread_create(&ctx->thread, worker, ctx)); + } + + time = uv_hrtime(); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + for (i = 0; i < nthreads; i++) + ASSERT(0 == uv_thread_join(&threads[i].thread)); + + time = uv_hrtime() - time; + + for (i = 0; i < nthreads; i++) { + ctx = threads + i; + ASSERT(ctx->worker_sent == NUM_PINGS); + ASSERT(ctx->worker_seen == NUM_PINGS); + ASSERT(ctx->main_sent == (unsigned int) NUM_PINGS); + ASSERT(ctx->main_seen == (unsigned int) NUM_PINGS); + } + + printf("async%d: %.2f sec (%s/sec)\n", + nthreads, + time / 1e9, + fmt(NUM_PINGS / (time / 1e9))); + + free(threads); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +BENCHMARK_IMPL(async1) { + return test_async(1); +} + + +BENCHMARK_IMPL(async2) { + return test_async(2); +} + + +BENCHMARK_IMPL(async4) { + return test_async(4); +} + + +BENCHMARK_IMPL(async8) { + return test_async(8); +} diff --git a/external/src/libuv/test/benchmark-fs-stat.c b/external/src/libuv/test/benchmark-fs-stat.c new file mode 100644 index 0000000..32d2589 --- /dev/null +++ b/external/src/libuv/test/benchmark-fs-stat.c @@ -0,0 +1,136 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" +#include "uv.h" + +#include +#include + +#define NUM_SYNC_REQS (10 * 1e5) +#define NUM_ASYNC_REQS (1 * (int) 1e5) +#define MAX_CONCURRENT_REQS 32 + +#define sync_stat(req, path) \ + do { \ + uv_fs_stat(NULL, (req), (path), NULL); \ + uv_fs_req_cleanup((req)); \ + } \ + while (0) + +struct async_req { + const char* path; + uv_fs_t fs_req; + int* count; +}; + + +static void warmup(const char* path) { + uv_fs_t reqs[MAX_CONCURRENT_REQS]; + unsigned int i; + + /* warm up the thread pool */ + for (i = 0; i < ARRAY_SIZE(reqs); i++) + uv_fs_stat(uv_default_loop(), reqs + i, path, uv_fs_req_cleanup); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + /* warm up the OS dirent cache */ + for (i = 0; i < 16; i++) + sync_stat(reqs + 0, path); +} + + +static void sync_bench(const char* path) { + uint64_t before; + uint64_t after; + uv_fs_t req; + int i; + + /* do the sync benchmark */ + before = uv_hrtime(); + + for (i = 0; i < NUM_SYNC_REQS; i++) + sync_stat(&req, path); + + after = uv_hrtime(); + + printf("%s stats (sync): %.2fs (%s/s)\n", + fmt(1.0 * NUM_SYNC_REQS), + (after - before) / 1e9, + fmt((1.0 * NUM_SYNC_REQS) / ((after - before) / 1e9))); + fflush(stdout); +} + + +static void stat_cb(uv_fs_t* fs_req) { + struct async_req* req = container_of(fs_req, struct async_req, fs_req); + uv_fs_req_cleanup(&req->fs_req); + if (*req->count == 0) return; + uv_fs_stat(uv_default_loop(), &req->fs_req, req->path, stat_cb); + (*req->count)--; +} + + +static void async_bench(const char* path) { + struct async_req reqs[MAX_CONCURRENT_REQS]; + struct async_req* req; + uint64_t before; + uint64_t after; + int count; + int i; + + for (i = 1; i <= MAX_CONCURRENT_REQS; i++) { + count = NUM_ASYNC_REQS; + + for (req = reqs; req < reqs + i; req++) { + req->path = path; + req->count = &count; + uv_fs_stat(uv_default_loop(), &req->fs_req, req->path, stat_cb); + } + + before = uv_hrtime(); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + after = uv_hrtime(); + + printf("%s stats (%d concurrent): %.2fs (%s/s)\n", + fmt(1.0 * NUM_ASYNC_REQS), + i, + (after - before) / 1e9, + fmt((1.0 * NUM_ASYNC_REQS) / ((after - before) / 1e9))); + fflush(stdout); + } +} + + +/* This benchmark aims to measure the overhead of doing I/O syscalls from + * the thread pool. The stat() syscall was chosen because its results are + * easy for the operating system to cache, taking the actual I/O overhead + * out of the equation. + */ +BENCHMARK_IMPL(fs_stat) { + const char path[] = "."; + warmup(path); + sync_bench(path); + async_bench(path); + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/benchmark-getaddrinfo.c b/external/src/libuv/test/benchmark-getaddrinfo.c new file mode 100644 index 0000000..1dbc23d --- /dev/null +++ b/external/src/libuv/test/benchmark-getaddrinfo.c @@ -0,0 +1,92 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +#define CONCURRENT_CALLS 10 +#define TOTAL_CALLS 10000 + +static const char* name = "localhost"; + +static uv_loop_t* loop; + +static uv_getaddrinfo_t handles[CONCURRENT_CALLS]; + +static int calls_initiated = 0; +static int calls_completed = 0; +static int64_t start_time; +static int64_t end_time; + + +static void getaddrinfo_initiate(uv_getaddrinfo_t* handle); + + +static void getaddrinfo_cb(uv_getaddrinfo_t* handle, int status, + struct addrinfo* res) { + ASSERT(status == 0); + calls_completed++; + if (calls_initiated < TOTAL_CALLS) { + getaddrinfo_initiate(handle); + } + + uv_freeaddrinfo(res); +} + + +static void getaddrinfo_initiate(uv_getaddrinfo_t* handle) { + int r; + + calls_initiated++; + + r = uv_getaddrinfo(loop, handle, &getaddrinfo_cb, name, NULL, NULL); + ASSERT(r == 0); +} + + +BENCHMARK_IMPL(getaddrinfo) { + int i; + + loop = uv_default_loop(); + + uv_update_time(loop); + start_time = uv_now(loop); + + for (i = 0; i < CONCURRENT_CALLS; i++) { + getaddrinfo_initiate(&handles[i]); + } + + uv_run(loop, UV_RUN_DEFAULT); + + uv_update_time(loop); + end_time = uv_now(loop); + + ASSERT(calls_initiated == TOTAL_CALLS); + ASSERT(calls_completed == TOTAL_CALLS); + + fprintf(stderr, "getaddrinfo: %.0f req/s\n", + (double) calls_completed / (double) (end_time - start_time) * 1000.0); + fflush(stderr); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/benchmark-list.h b/external/src/libuv/test/benchmark-list.h new file mode 100644 index 0000000..29e44c3 --- /dev/null +++ b/external/src/libuv/test/benchmark-list.h @@ -0,0 +1,164 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +BENCHMARK_DECLARE (sizes) +BENCHMARK_DECLARE (loop_count) +BENCHMARK_DECLARE (loop_count_timed) +BENCHMARK_DECLARE (ping_pongs) +BENCHMARK_DECLARE (ping_udp) +BENCHMARK_DECLARE (tcp_write_batch) +BENCHMARK_DECLARE (tcp4_pound_100) +BENCHMARK_DECLARE (tcp4_pound_1000) +BENCHMARK_DECLARE (pipe_pound_100) +BENCHMARK_DECLARE (pipe_pound_1000) +BENCHMARK_DECLARE (tcp_pump100_client) +BENCHMARK_DECLARE (tcp_pump1_client) +BENCHMARK_DECLARE (pipe_pump100_client) +BENCHMARK_DECLARE (pipe_pump1_client) + +BENCHMARK_DECLARE (tcp_multi_accept2) +BENCHMARK_DECLARE (tcp_multi_accept4) +BENCHMARK_DECLARE (tcp_multi_accept8) + +/* Run until X packets have been sent/received. */ +BENCHMARK_DECLARE (udp_pummel_1v1) +BENCHMARK_DECLARE (udp_pummel_1v10) +BENCHMARK_DECLARE (udp_pummel_1v100) +BENCHMARK_DECLARE (udp_pummel_1v1000) +BENCHMARK_DECLARE (udp_pummel_10v10) +BENCHMARK_DECLARE (udp_pummel_10v100) +BENCHMARK_DECLARE (udp_pummel_10v1000) +BENCHMARK_DECLARE (udp_pummel_100v100) +BENCHMARK_DECLARE (udp_pummel_100v1000) +BENCHMARK_DECLARE (udp_pummel_1000v1000) + +/* Run until X seconds have elapsed. */ +BENCHMARK_DECLARE (udp_timed_pummel_1v1) +BENCHMARK_DECLARE (udp_timed_pummel_1v10) +BENCHMARK_DECLARE (udp_timed_pummel_1v100) +BENCHMARK_DECLARE (udp_timed_pummel_1v1000) +BENCHMARK_DECLARE (udp_timed_pummel_10v10) +BENCHMARK_DECLARE (udp_timed_pummel_10v100) +BENCHMARK_DECLARE (udp_timed_pummel_10v1000) +BENCHMARK_DECLARE (udp_timed_pummel_100v100) +BENCHMARK_DECLARE (udp_timed_pummel_100v1000) +BENCHMARK_DECLARE (udp_timed_pummel_1000v1000) + +BENCHMARK_DECLARE (getaddrinfo) +BENCHMARK_DECLARE (fs_stat) +BENCHMARK_DECLARE (async1) +BENCHMARK_DECLARE (async2) +BENCHMARK_DECLARE (async4) +BENCHMARK_DECLARE (async8) +BENCHMARK_DECLARE (async_pummel_1) +BENCHMARK_DECLARE (async_pummel_2) +BENCHMARK_DECLARE (async_pummel_4) +BENCHMARK_DECLARE (async_pummel_8) +BENCHMARK_DECLARE (spawn) +BENCHMARK_DECLARE (thread_create) +BENCHMARK_DECLARE (million_async) +BENCHMARK_DECLARE (million_timers) +HELPER_DECLARE (tcp4_blackhole_server) +HELPER_DECLARE (tcp_pump_server) +HELPER_DECLARE (pipe_pump_server) +HELPER_DECLARE (tcp4_echo_server) +HELPER_DECLARE (pipe_echo_server) +HELPER_DECLARE (dns_server) + +TASK_LIST_START + BENCHMARK_ENTRY (sizes) + BENCHMARK_ENTRY (loop_count) + BENCHMARK_ENTRY (loop_count_timed) + + BENCHMARK_ENTRY (ping_pongs) + BENCHMARK_HELPER (ping_pongs, tcp4_echo_server) + + BENCHMARK_ENTRY (tcp_write_batch) + BENCHMARK_HELPER (tcp_write_batch, tcp4_blackhole_server) + + BENCHMARK_ENTRY (tcp_pump100_client) + BENCHMARK_HELPER (tcp_pump100_client, tcp_pump_server) + + BENCHMARK_ENTRY (tcp_pump1_client) + BENCHMARK_HELPER (tcp_pump1_client, tcp_pump_server) + + BENCHMARK_ENTRY (tcp4_pound_100) + BENCHMARK_HELPER (tcp4_pound_100, tcp4_echo_server) + + BENCHMARK_ENTRY (tcp4_pound_1000) + BENCHMARK_HELPER (tcp4_pound_1000, tcp4_echo_server) + + BENCHMARK_ENTRY (pipe_pump100_client) + BENCHMARK_HELPER (pipe_pump100_client, pipe_pump_server) + + BENCHMARK_ENTRY (pipe_pump1_client) + BENCHMARK_HELPER (pipe_pump1_client, pipe_pump_server) + + BENCHMARK_ENTRY (pipe_pound_100) + BENCHMARK_HELPER (pipe_pound_100, pipe_echo_server) + + BENCHMARK_ENTRY (pipe_pound_1000) + BENCHMARK_HELPER (pipe_pound_1000, pipe_echo_server) + + BENCHMARK_ENTRY (tcp_multi_accept2) + BENCHMARK_ENTRY (tcp_multi_accept4) + BENCHMARK_ENTRY (tcp_multi_accept8) + + BENCHMARK_ENTRY (udp_pummel_1v1) + BENCHMARK_ENTRY (udp_pummel_1v10) + BENCHMARK_ENTRY (udp_pummel_1v100) + BENCHMARK_ENTRY (udp_pummel_1v1000) + BENCHMARK_ENTRY (udp_pummel_10v10) + BENCHMARK_ENTRY (udp_pummel_10v100) + BENCHMARK_ENTRY (udp_pummel_10v1000) + BENCHMARK_ENTRY (udp_pummel_100v100) + BENCHMARK_ENTRY (udp_pummel_100v1000) + BENCHMARK_ENTRY (udp_pummel_1000v1000) + + BENCHMARK_ENTRY (udp_timed_pummel_1v1) + BENCHMARK_ENTRY (udp_timed_pummel_1v10) + BENCHMARK_ENTRY (udp_timed_pummel_1v100) + BENCHMARK_ENTRY (udp_timed_pummel_1v1000) + BENCHMARK_ENTRY (udp_timed_pummel_10v10) + BENCHMARK_ENTRY (udp_timed_pummel_10v100) + BENCHMARK_ENTRY (udp_timed_pummel_10v1000) + BENCHMARK_ENTRY (udp_timed_pummel_100v100) + BENCHMARK_ENTRY (udp_timed_pummel_100v1000) + BENCHMARK_ENTRY (udp_timed_pummel_1000v1000) + + BENCHMARK_ENTRY (getaddrinfo) + + BENCHMARK_ENTRY (fs_stat) + + BENCHMARK_ENTRY (async1) + BENCHMARK_ENTRY (async2) + BENCHMARK_ENTRY (async4) + BENCHMARK_ENTRY (async8) + BENCHMARK_ENTRY (async_pummel_1) + BENCHMARK_ENTRY (async_pummel_2) + BENCHMARK_ENTRY (async_pummel_4) + BENCHMARK_ENTRY (async_pummel_8) + + BENCHMARK_ENTRY (spawn) + BENCHMARK_ENTRY (thread_create) + BENCHMARK_ENTRY (million_async) + BENCHMARK_ENTRY (million_timers) +TASK_LIST_END diff --git a/external/src/libuv/test/benchmark-loop-count.c b/external/src/libuv/test/benchmark-loop-count.c new file mode 100644 index 0000000..970a94c --- /dev/null +++ b/external/src/libuv/test/benchmark-loop-count.c @@ -0,0 +1,92 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" +#include "uv.h" + +#include +#include + +#define NUM_TICKS (2 * 1000 * 1000) + +static unsigned long ticks; +static uv_idle_t idle_handle; +static uv_timer_t timer_handle; + + +static void idle_cb(uv_idle_t* handle) { + if (++ticks == NUM_TICKS) + uv_idle_stop(handle); +} + + +static void idle2_cb(uv_idle_t* handle) { + ticks++; +} + + +static void timer_cb(uv_timer_t* handle) { + uv_idle_stop(&idle_handle); + uv_timer_stop(&timer_handle); +} + + +BENCHMARK_IMPL(loop_count) { + uv_loop_t* loop = uv_default_loop(); + uint64_t ns; + + uv_idle_init(loop, &idle_handle); + uv_idle_start(&idle_handle, idle_cb); + + ns = uv_hrtime(); + uv_run(loop, UV_RUN_DEFAULT); + ns = uv_hrtime() - ns; + + ASSERT(ticks == NUM_TICKS); + + fprintf(stderr, "loop_count: %d ticks in %.2fs (%.0f/s)\n", + NUM_TICKS, + ns / 1e9, + NUM_TICKS / (ns / 1e9)); + fflush(stderr); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +BENCHMARK_IMPL(loop_count_timed) { + uv_loop_t* loop = uv_default_loop(); + + uv_idle_init(loop, &idle_handle); + uv_idle_start(&idle_handle, idle2_cb); + + uv_timer_init(loop, &timer_handle); + uv_timer_start(&timer_handle, timer_cb, 5000, 0); + + uv_run(loop, UV_RUN_DEFAULT); + + fprintf(stderr, "loop_count: %lu ticks (%.0f ticks/s)\n", ticks, ticks / 5.0); + fflush(stderr); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/benchmark-million-async.c b/external/src/libuv/test/benchmark-million-async.c new file mode 100644 index 0000000..937a12f --- /dev/null +++ b/external/src/libuv/test/benchmark-million-async.c @@ -0,0 +1,112 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" +#include "uv.h" + +struct async_container { + unsigned async_events; + unsigned handles_seen; + uv_async_t async_handles[1024 * 1024]; +}; + +static volatile int done; +static uv_thread_t thread_id; +static struct async_container* container; + + +static unsigned fastrand(void) { + static unsigned g = 0; + g = g * 214013 + 2531011; + return g; +} + + +static void thread_cb(void* arg) { + unsigned i; + + while (done == 0) { + i = fastrand() % ARRAY_SIZE(container->async_handles); + uv_async_send(container->async_handles + i); + } +} + + +static void async_cb(uv_async_t* handle) { + container->async_events++; + handle->data = handle; +} + + +static void timer_cb(uv_timer_t* handle) { + unsigned i; + + done = 1; + ASSERT(0 == uv_thread_join(&thread_id)); + + for (i = 0; i < ARRAY_SIZE(container->async_handles); i++) { + uv_async_t* handle = container->async_handles + i; + + if (handle->data != NULL) + container->handles_seen++; + + uv_close((uv_handle_t*) handle, NULL); + } + + uv_close((uv_handle_t*) handle, NULL); +} + + +BENCHMARK_IMPL(million_async) { + uv_timer_t timer_handle; + uv_async_t* handle; + uv_loop_t* loop; + int timeout; + unsigned i; + + loop = uv_default_loop(); + timeout = 5000; + + container = malloc(sizeof(*container)); + ASSERT_NOT_NULL(container); + container->async_events = 0; + container->handles_seen = 0; + + for (i = 0; i < ARRAY_SIZE(container->async_handles); i++) { + handle = container->async_handles + i; + ASSERT(0 == uv_async_init(loop, handle, async_cb)); + handle->data = NULL; + } + + ASSERT(0 == uv_timer_init(loop, &timer_handle)); + ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, timeout, 0)); + ASSERT(0 == uv_thread_create(&thread_id, thread_cb, NULL)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + printf("%s async events in %.1f seconds (%s/s, %s unique handles seen)\n", + fmt(container->async_events), + timeout / 1000., + fmt(container->async_events / (timeout / 1000.)), + fmt(container->handles_seen)); + free(container); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/benchmark-million-timers.c b/external/src/libuv/test/benchmark-million-timers.c new file mode 100644 index 0000000..ef25c20 --- /dev/null +++ b/external/src/libuv/test/benchmark-million-timers.c @@ -0,0 +1,86 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" +#include "uv.h" + +#define NUM_TIMERS (10 * 1000 * 1000) + +static int timer_cb_called; +static int close_cb_called; + + +static void timer_cb(uv_timer_t* handle) { + timer_cb_called++; +} + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + + +BENCHMARK_IMPL(million_timers) { + uv_timer_t* timers; + uv_loop_t* loop; + uint64_t before_all; + uint64_t before_run; + uint64_t after_run; + uint64_t after_all; + int timeout; + int i; + + timers = malloc(NUM_TIMERS * sizeof(timers[0])); + ASSERT_NOT_NULL(timers); + + loop = uv_default_loop(); + timeout = 0; + + before_all = uv_hrtime(); + for (i = 0; i < NUM_TIMERS; i++) { + if (i % 1000 == 0) timeout++; + ASSERT(0 == uv_timer_init(loop, timers + i)); + ASSERT(0 == uv_timer_start(timers + i, timer_cb, timeout, 0)); + } + + before_run = uv_hrtime(); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + after_run = uv_hrtime(); + + for (i = 0; i < NUM_TIMERS; i++) + uv_close((uv_handle_t*) (timers + i), close_cb); + + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + after_all = uv_hrtime(); + + ASSERT(timer_cb_called == NUM_TIMERS); + ASSERT(close_cb_called == NUM_TIMERS); + free(timers); + + fprintf(stderr, "%.2f seconds total\n", (after_all - before_all) / 1e9); + fprintf(stderr, "%.2f seconds init\n", (before_run - before_all) / 1e9); + fprintf(stderr, "%.2f seconds dispatch\n", (after_run - before_run) / 1e9); + fprintf(stderr, "%.2f seconds cleanup\n", (after_all - after_run) / 1e9); + fflush(stderr); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/benchmark-multi-accept.c b/external/src/libuv/test/benchmark-multi-accept.c new file mode 100644 index 0000000..86b7da5 --- /dev/null +++ b/external/src/libuv/test/benchmark-multi-accept.c @@ -0,0 +1,451 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" +#include "uv.h" + +#define IPC_PIPE_NAME TEST_PIPENAME +#define NUM_CONNECTS (250 * 1000) + +union stream_handle { + uv_pipe_t pipe; + uv_tcp_t tcp; +}; + +/* Use as (uv_stream_t *) &handle_storage -- it's kind of clunky but it + * avoids aliasing warnings. + */ +typedef unsigned char handle_storage_t[sizeof(union stream_handle)]; + +/* Used for passing around the listen handle, not part of the benchmark proper. + * We have an overabundance of server types here. It works like this: + * + * 1. The main thread starts an IPC pipe server. + * 2. The worker threads connect to the IPC server and obtain a listen handle. + * 3. The worker threads start accepting requests on the listen handle. + * 4. The main thread starts connecting repeatedly. + * + * Step #4 should perhaps be farmed out over several threads. + */ +struct ipc_server_ctx { + handle_storage_t server_handle; + unsigned int num_connects; + uv_pipe_t ipc_pipe; +}; + +struct ipc_peer_ctx { + handle_storage_t peer_handle; + uv_write_t write_req; +}; + +struct ipc_client_ctx { + uv_connect_t connect_req; + uv_stream_t* server_handle; + uv_pipe_t ipc_pipe; + char scratch[16]; +}; + +/* Used in the actual benchmark. */ +struct server_ctx { + handle_storage_t server_handle; + unsigned int num_connects; + uv_async_t async_handle; + uv_thread_t thread_id; + uv_sem_t semaphore; +}; + +struct client_ctx { + handle_storage_t client_handle; + unsigned int num_connects; + uv_connect_t connect_req; + uv_idle_t idle_handle; +}; + +static void ipc_connection_cb(uv_stream_t* ipc_pipe, int status); +static void ipc_write_cb(uv_write_t* req, int status); +static void ipc_close_cb(uv_handle_t* handle); +static void ipc_connect_cb(uv_connect_t* req, int status); +static void ipc_read_cb(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf); +static void ipc_alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf); + +static void sv_async_cb(uv_async_t* handle); +static void sv_connection_cb(uv_stream_t* server_handle, int status); +static void sv_read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf); +static void sv_alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf); + +static void cl_connect_cb(uv_connect_t* req, int status); +static void cl_idle_cb(uv_idle_t* handle); +static void cl_close_cb(uv_handle_t* handle); + +static struct sockaddr_in listen_addr; + + +static void ipc_connection_cb(uv_stream_t* ipc_pipe, int status) { + struct ipc_server_ctx* sc; + struct ipc_peer_ctx* pc; + uv_loop_t* loop; + uv_buf_t buf; + + loop = ipc_pipe->loop; + buf = uv_buf_init("PING", 4); + sc = container_of(ipc_pipe, struct ipc_server_ctx, ipc_pipe); + pc = calloc(1, sizeof(*pc)); + ASSERT_NOT_NULL(pc); + + if (ipc_pipe->type == UV_TCP) + ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) &pc->peer_handle)); + else if (ipc_pipe->type == UV_NAMED_PIPE) + ASSERT(0 == uv_pipe_init(loop, (uv_pipe_t*) &pc->peer_handle, 1)); + else + ASSERT(0); + + ASSERT(0 == uv_accept(ipc_pipe, (uv_stream_t*) &pc->peer_handle)); + ASSERT(0 == uv_write2(&pc->write_req, + (uv_stream_t*) &pc->peer_handle, + &buf, + 1, + (uv_stream_t*) &sc->server_handle, + ipc_write_cb)); + + if (--sc->num_connects == 0) + uv_close((uv_handle_t*) ipc_pipe, NULL); +} + + +static void ipc_write_cb(uv_write_t* req, int status) { + struct ipc_peer_ctx* ctx; + ctx = container_of(req, struct ipc_peer_ctx, write_req); + uv_close((uv_handle_t*) &ctx->peer_handle, ipc_close_cb); +} + + +static void ipc_close_cb(uv_handle_t* handle) { + struct ipc_peer_ctx* ctx; + ctx = container_of(handle, struct ipc_peer_ctx, peer_handle); + free(ctx); +} + + +static void ipc_connect_cb(uv_connect_t* req, int status) { + struct ipc_client_ctx* ctx; + ctx = container_of(req, struct ipc_client_ctx, connect_req); + ASSERT(0 == status); + ASSERT(0 == uv_read_start((uv_stream_t*) &ctx->ipc_pipe, + ipc_alloc_cb, + ipc_read_cb)); +} + + +static void ipc_alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + struct ipc_client_ctx* ctx; + ctx = container_of(handle, struct ipc_client_ctx, ipc_pipe); + buf->base = ctx->scratch; + buf->len = sizeof(ctx->scratch); +} + + +static void ipc_read_cb(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + struct ipc_client_ctx* ctx; + uv_loop_t* loop; + uv_handle_type type; + uv_pipe_t* ipc_pipe; + + ipc_pipe = (uv_pipe_t*) handle; + ctx = container_of(ipc_pipe, struct ipc_client_ctx, ipc_pipe); + loop = ipc_pipe->loop; + + ASSERT(1 == uv_pipe_pending_count(ipc_pipe)); + type = uv_pipe_pending_type(ipc_pipe); + if (type == UV_TCP) + ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) ctx->server_handle)); + else if (type == UV_NAMED_PIPE) + ASSERT(0 == uv_pipe_init(loop, (uv_pipe_t*) ctx->server_handle, 0)); + else + ASSERT(0); + + ASSERT(0 == uv_accept(handle, ctx->server_handle)); + uv_close((uv_handle_t*) &ctx->ipc_pipe, NULL); +} + + +/* Set up an IPC pipe server that hands out listen sockets to the worker + * threads. It's kind of cumbersome for such a simple operation, maybe we + * should revive uv_import() and uv_export(). + */ +static void send_listen_handles(uv_handle_type type, + unsigned int num_servers, + struct server_ctx* servers) { + struct ipc_server_ctx ctx; + uv_loop_t* loop; + unsigned int i; + + loop = uv_default_loop(); + ctx.num_connects = num_servers; + + if (type == UV_TCP) { + ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) &ctx.server_handle)); + ASSERT(0 == uv_tcp_bind((uv_tcp_t*) &ctx.server_handle, + (const struct sockaddr*) &listen_addr, + 0)); + } + else + ASSERT(0); + /* We need to initialize this pipe with ipc=0 - this is not a uv_pipe we'll + * be sending handles over, it's just for listening for new connections. + * If we accept a connection then the connected pipe must be initialized + * with ipc=1. + */ + ASSERT(0 == uv_pipe_init(loop, &ctx.ipc_pipe, 0)); + ASSERT(0 == uv_pipe_bind(&ctx.ipc_pipe, IPC_PIPE_NAME)); + ASSERT(0 == uv_listen((uv_stream_t*) &ctx.ipc_pipe, 128, ipc_connection_cb)); + + for (i = 0; i < num_servers; i++) + uv_sem_post(&servers[i].semaphore); + + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + uv_close((uv_handle_t*) &ctx.server_handle, NULL); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + + for (i = 0; i < num_servers; i++) + uv_sem_wait(&servers[i].semaphore); +} + + +static void get_listen_handle(uv_loop_t* loop, uv_stream_t* server_handle) { + struct ipc_client_ctx ctx; + + ctx.server_handle = server_handle; + ctx.server_handle->data = "server handle"; + + ASSERT(0 == uv_pipe_init(loop, &ctx.ipc_pipe, 1)); + uv_pipe_connect(&ctx.connect_req, + &ctx.ipc_pipe, + IPC_PIPE_NAME, + ipc_connect_cb); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); +} + + +static void server_cb(void *arg) { + struct server_ctx *ctx; + uv_loop_t loop; + + ctx = arg; + ASSERT(0 == uv_loop_init(&loop)); + + ASSERT(0 == uv_async_init(&loop, &ctx->async_handle, sv_async_cb)); + uv_unref((uv_handle_t*) &ctx->async_handle); + + /* Wait until the main thread is ready. */ + uv_sem_wait(&ctx->semaphore); + get_listen_handle(&loop, (uv_stream_t*) &ctx->server_handle); + uv_sem_post(&ctx->semaphore); + + /* Now start the actual benchmark. */ + ASSERT(0 == uv_listen((uv_stream_t*) &ctx->server_handle, + 128, + sv_connection_cb)); + ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); + + uv_loop_close(&loop); +} + + +static void sv_async_cb(uv_async_t* handle) { + struct server_ctx* ctx; + ctx = container_of(handle, struct server_ctx, async_handle); + uv_close((uv_handle_t*) &ctx->server_handle, NULL); + uv_close((uv_handle_t*) &ctx->async_handle, NULL); +} + + +static void sv_connection_cb(uv_stream_t* server_handle, int status) { + handle_storage_t* storage; + struct server_ctx* ctx; + + ctx = container_of(server_handle, struct server_ctx, server_handle); + ASSERT(status == 0); + + storage = malloc(sizeof(*storage)); + ASSERT_NOT_NULL(storage); + + if (server_handle->type == UV_TCP) + ASSERT(0 == uv_tcp_init(server_handle->loop, (uv_tcp_t*) storage)); + else if (server_handle->type == UV_NAMED_PIPE) + ASSERT(0 == uv_pipe_init(server_handle->loop, (uv_pipe_t*) storage, 0)); + else + ASSERT(0); + + ASSERT(0 == uv_accept(server_handle, (uv_stream_t*) storage)); + ASSERT(0 == uv_read_start((uv_stream_t*) storage, sv_alloc_cb, sv_read_cb)); + ctx->num_connects++; +} + + +static void sv_alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[32]; + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void sv_read_cb(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + ASSERT(nread == UV_EOF); + uv_close((uv_handle_t*) handle, (uv_close_cb) free); +} + + +static void cl_connect_cb(uv_connect_t* req, int status) { + struct client_ctx* ctx = container_of(req, struct client_ctx, connect_req); + uv_idle_start(&ctx->idle_handle, cl_idle_cb); + ASSERT(0 == status); +} + + +static void cl_idle_cb(uv_idle_t* handle) { + struct client_ctx* ctx = container_of(handle, struct client_ctx, idle_handle); + uv_close((uv_handle_t*) &ctx->client_handle, cl_close_cb); + uv_idle_stop(&ctx->idle_handle); +} + + +static void cl_close_cb(uv_handle_t* handle) { + struct client_ctx* ctx; + + ctx = container_of(handle, struct client_ctx, client_handle); + + if (--ctx->num_connects == 0) { + uv_close((uv_handle_t*) &ctx->idle_handle, NULL); + return; + } + + ASSERT(0 == uv_tcp_init(handle->loop, (uv_tcp_t*) &ctx->client_handle)); + ASSERT(0 == uv_tcp_connect(&ctx->connect_req, + (uv_tcp_t*) &ctx->client_handle, + (const struct sockaddr*) &listen_addr, + cl_connect_cb)); +} + + +static int test_tcp(unsigned int num_servers, unsigned int num_clients) { + struct server_ctx* servers; + struct client_ctx* clients; + uv_loop_t* loop; + uv_tcp_t* handle; + unsigned int i; + double time; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &listen_addr)); + loop = uv_default_loop(); + + servers = calloc(num_servers, sizeof(servers[0])); + clients = calloc(num_clients, sizeof(clients[0])); + ASSERT_NOT_NULL(servers); + ASSERT_NOT_NULL(clients); + + /* We're making the assumption here that from the perspective of the + * OS scheduler, threads are functionally equivalent to and interchangeable + * with full-blown processes. + */ + for (i = 0; i < num_servers; i++) { + struct server_ctx* ctx = servers + i; + ASSERT(0 == uv_sem_init(&ctx->semaphore, 0)); + ASSERT(0 == uv_thread_create(&ctx->thread_id, server_cb, ctx)); + } + + send_listen_handles(UV_TCP, num_servers, servers); + + for (i = 0; i < num_clients; i++) { + struct client_ctx* ctx = clients + i; + ctx->num_connects = NUM_CONNECTS / num_clients; + handle = (uv_tcp_t*) &ctx->client_handle; + handle->data = "client handle"; + ASSERT(0 == uv_tcp_init(loop, handle)); + ASSERT(0 == uv_tcp_connect(&ctx->connect_req, + handle, + (const struct sockaddr*) &listen_addr, + cl_connect_cb)); + ASSERT(0 == uv_idle_init(loop, &ctx->idle_handle)); + } + + { + uint64_t t = uv_hrtime(); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + t = uv_hrtime() - t; + time = t / 1e9; + } + + for (i = 0; i < num_servers; i++) { + struct server_ctx* ctx = servers + i; + uv_async_send(&ctx->async_handle); + ASSERT(0 == uv_thread_join(&ctx->thread_id)); + uv_sem_destroy(&ctx->semaphore); + } + + printf("accept%u: %.0f accepts/sec (%u total)\n", + num_servers, + NUM_CONNECTS / time, + NUM_CONNECTS); + + for (i = 0; i < num_servers; i++) { + struct server_ctx* ctx = servers + i; + printf(" thread #%u: %.0f accepts/sec (%u total, %.1f%%)\n", + i, + ctx->num_connects / time, + ctx->num_connects, + ctx->num_connects * 100.0 / NUM_CONNECTS); + } + + free(clients); + free(servers); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +BENCHMARK_IMPL(tcp_multi_accept2) { + return test_tcp(2, 40); +} + + +BENCHMARK_IMPL(tcp_multi_accept4) { + return test_tcp(4, 40); +} + + +BENCHMARK_IMPL(tcp_multi_accept8) { + return test_tcp(8, 40); +} diff --git a/external/src/libuv/test/benchmark-ping-pongs.c b/external/src/libuv/test/benchmark-ping-pongs.c new file mode 100644 index 0000000..646a7df --- /dev/null +++ b/external/src/libuv/test/benchmark-ping-pongs.c @@ -0,0 +1,221 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +/* Run the benchmark for this many ms */ +#define TIME 5000 + + +typedef struct { + int pongs; + int state; + uv_tcp_t tcp; + uv_connect_t connect_req; + uv_shutdown_t shutdown_req; +} pinger_t; + +typedef struct buf_s { + uv_buf_t uv_buf_t; + struct buf_s* next; +} buf_t; + + +static char PING[] = "PING\n"; + +static uv_loop_t* loop; + +static buf_t* buf_freelist = NULL; +static int pinger_shutdown_cb_called; +static int completed_pingers = 0; +static int64_t start_time; + + +static void buf_alloc(uv_handle_t* tcp, size_t size, uv_buf_t* buf) { + buf_t* ab; + + ab = buf_freelist; + if (ab != NULL) + buf_freelist = ab->next; + else { + ab = malloc(size + sizeof(*ab)); + ab->uv_buf_t.len = size; + ab->uv_buf_t.base = (char*) (ab + 1); + } + + *buf = ab->uv_buf_t; +} + + +static void buf_free(const uv_buf_t* buf) { + buf_t* ab = (buf_t*) buf->base - 1; + ab->next = buf_freelist; + buf_freelist = ab; +} + + +static void pinger_close_cb(uv_handle_t* handle) { + pinger_t* pinger; + + pinger = (pinger_t*)handle->data; + fprintf(stderr, "ping_pongs: %d roundtrips/s\n", (1000 * pinger->pongs) / TIME); + fflush(stderr); + + free(pinger); + + completed_pingers++; +} + + +static void pinger_write_cb(uv_write_t* req, int status) { + ASSERT(status == 0); + + free(req); +} + + +static void pinger_write_ping(pinger_t* pinger) { + uv_write_t* req; + uv_buf_t buf; + + buf = uv_buf_init(PING, sizeof(PING) - 1); + + req = malloc(sizeof *req); + if (uv_write(req, (uv_stream_t*) &pinger->tcp, &buf, 1, pinger_write_cb)) { + FATAL("uv_write failed"); + } +} + + +static void pinger_shutdown_cb(uv_shutdown_t* req, int status) { + ASSERT(status == 0); + pinger_shutdown_cb_called++; + + /* + * The close callback has not been triggered yet. We must wait for EOF + * until we close the connection. + */ + ASSERT(completed_pingers == 0); +} + + +static void pinger_read_cb(uv_stream_t* tcp, + ssize_t nread, + const uv_buf_t* buf) { + ssize_t i; + pinger_t* pinger; + + pinger = (pinger_t*)tcp->data; + + if (nread < 0) { + ASSERT(nread == UV_EOF); + + if (buf->base) { + buf_free(buf); + } + + ASSERT(pinger_shutdown_cb_called == 1); + uv_close((uv_handle_t*)tcp, pinger_close_cb); + + return; + } + + /* Now we count the pings */ + for (i = 0; i < nread; i++) { + ASSERT(buf->base[i] == PING[pinger->state]); + pinger->state = (pinger->state + 1) % (sizeof(PING) - 1); + if (pinger->state == 0) { + pinger->pongs++; + if (uv_now(loop) - start_time > TIME) { + uv_shutdown(&pinger->shutdown_req, + (uv_stream_t*) tcp, + pinger_shutdown_cb); + break; + } else { + pinger_write_ping(pinger); + } + } + } + + buf_free(buf); +} + + +static void pinger_connect_cb(uv_connect_t* req, int status) { + pinger_t *pinger = (pinger_t*)req->handle->data; + + ASSERT(status == 0); + + pinger_write_ping(pinger); + + if (uv_read_start(req->handle, buf_alloc, pinger_read_cb)) { + FATAL("uv_read_start failed"); + } +} + + +static void pinger_new(void) { + struct sockaddr_in client_addr; + struct sockaddr_in server_addr; + pinger_t *pinger; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &client_addr)); + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); + pinger = malloc(sizeof(*pinger)); + pinger->state = 0; + pinger->pongs = 0; + + /* Try to connect to the server and do NUM_PINGS ping-pongs. */ + r = uv_tcp_init(loop, &pinger->tcp); + ASSERT(!r); + + pinger->tcp.data = pinger; + + ASSERT(0 == uv_tcp_bind(&pinger->tcp, + (const struct sockaddr*) &client_addr, + 0)); + + r = uv_tcp_connect(&pinger->connect_req, + &pinger->tcp, + (const struct sockaddr*) &server_addr, + pinger_connect_cb); + ASSERT(!r); +} + + +BENCHMARK_IMPL(ping_pongs) { + loop = uv_default_loop(); + + start_time = uv_now(loop); + + pinger_new(); + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(completed_pingers == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/benchmark-ping-udp.c b/external/src/libuv/test/benchmark-ping-udp.c new file mode 100644 index 0000000..a29502a --- /dev/null +++ b/external/src/libuv/test/benchmark-ping-udp.c @@ -0,0 +1,163 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +/* Run the benchmark for this many ms */ +#define TIME 5000 + +typedef struct { + int pongs; + int state; + uv_udp_t udp; + struct sockaddr_in server_addr; +} pinger_t; + +typedef struct buf_s { + uv_buf_t uv_buf_t; + struct buf_s* next; +} buf_t; + +static char PING[] = "PING\n"; + +static uv_loop_t* loop; + +static int completed_pingers; +static unsigned long completed_pings; +static int64_t start_time; + + +static void buf_alloc(uv_handle_t* tcp, size_t size, uv_buf_t* buf) { + static char slab[64 * 1024]; + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void buf_free(const uv_buf_t* buf) { +} + + +static void pinger_close_cb(uv_handle_t* handle) { + pinger_t* pinger; + + pinger = (pinger_t*)handle->data; +#if DEBUG + fprintf(stderr, "ping_pongs: %d roundtrips/s\n", + pinger->pongs / (TIME / 1000)); +#endif + + completed_pings += pinger->pongs; + completed_pingers++; + free(pinger); +} + +static void pinger_write_ping(pinger_t* pinger) { + uv_buf_t buf; + int r; + + buf = uv_buf_init(PING, sizeof(PING) - 1); + r = uv_udp_try_send(&pinger->udp, &buf, 1, + (const struct sockaddr*) &pinger->server_addr); + if (r < 0) + FATAL("uv_udp_send failed"); +} + +static void pinger_read_cb(uv_udp_t* udp, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags) { + ssize_t i; + pinger_t* pinger; + pinger = (pinger_t*)udp->data; + + /* Now we count the pings */ + for (i = 0; i < nread; i++) { + ASSERT(buf->base[i] == PING[pinger->state]); + pinger->state = (pinger->state + 1) % (sizeof(PING) - 1); + if (pinger->state == 0) { + pinger->pongs++; + if (uv_now(loop) - start_time > TIME) { + uv_close((uv_handle_t*)udp, pinger_close_cb); + break; + } + pinger_write_ping(pinger); + } + } + + buf_free(buf); +} + +static void udp_pinger_new(void) { + pinger_t* pinger = malloc(sizeof(*pinger)); + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &pinger->server_addr)); + pinger->state = 0; + pinger->pongs = 0; + + /* Try to do NUM_PINGS ping-pongs (connection-less). */ + r = uv_udp_init(loop, &pinger->udp); + ASSERT(r == 0); + + pinger->udp.data = pinger; + + /* Start pinging */ + if (0 != uv_udp_recv_start(&pinger->udp, buf_alloc, pinger_read_cb)) { + FATAL("uv_udp_read_start failed"); + } + pinger_write_ping(pinger); +} + +static int ping_udp(unsigned pingers) { + unsigned i; + + loop = uv_default_loop(); + start_time = uv_now(loop); + + for (i = 0; i < pingers; ++i) { + udp_pinger_new(); + } + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(completed_pingers >= 1); + + fprintf(stderr, "ping_pongs: %d pingers, ~ %lu roundtrips/s\n", + completed_pingers, completed_pings / (TIME/1000)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#define X(PINGERS) \ +BENCHMARK_IMPL(ping_udp##PINGERS) {\ + return ping_udp(PINGERS); \ +} + +X(1) +X(10) +X(100) + +#undef X diff --git a/external/src/libuv/test/benchmark-pound.c b/external/src/libuv/test/benchmark-pound.c new file mode 100644 index 0000000..830bc55 --- /dev/null +++ b/external/src/libuv/test/benchmark-pound.c @@ -0,0 +1,351 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" +#include "uv.h" + +/* Update this is you're going to run > 1000 concurrent requests. */ +#define MAX_CONNS 1000 + +#undef NANOSEC +#define NANOSEC ((uint64_t) 1e9) + +#undef DEBUG +#define DEBUG 0 + +struct conn_rec_s; + +typedef void (*setup_fn)(int num, void* arg); +typedef void (*make_connect_fn)(struct conn_rec_s* conn); +typedef int (*connect_fn)(int num, make_connect_fn make_connect, void* arg); + +/* Base class for tcp_conn_rec and pipe_conn_rec. + * The ordering of fields matters! + */ +typedef struct conn_rec_s { + int i; + uv_connect_t conn_req; + uv_write_t write_req; + make_connect_fn make_connect; + uv_stream_t stream; +} conn_rec; + +typedef struct { + int i; + uv_connect_t conn_req; + uv_write_t write_req; + make_connect_fn make_connect; + uv_tcp_t stream; +} tcp_conn_rec; + +typedef struct { + int i; + uv_connect_t conn_req; + uv_write_t write_req; + make_connect_fn make_connect; + uv_pipe_t stream; +} pipe_conn_rec; + +static char buffer[] = "QS"; + +static uv_loop_t* loop; + +static tcp_conn_rec tcp_conns[MAX_CONNS]; +static pipe_conn_rec pipe_conns[MAX_CONNS]; + +static uint64_t start; /* in ms */ +static int closed_streams; +static int conns_failed; + +static void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); +static void connect_cb(uv_connect_t* conn_req, int status); +static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf); +static void close_cb(uv_handle_t* handle); + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void after_write(uv_write_t* req, int status) { + if (status != 0) { + fprintf(stderr, "write error %s\n", uv_err_name(status)); + uv_close((uv_handle_t*)req->handle, close_cb); + conns_failed++; + return; + } +} + + +static void connect_cb(uv_connect_t* req, int status) { + conn_rec* conn; + uv_buf_t buf; + int r; + + if (status != 0) { +#if DEBUG + fprintf(stderr, "connect error %s\n", uv_err_name(status)); +#endif + uv_close((uv_handle_t*)req->handle, close_cb); + conns_failed++; + return; + } + + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + + conn = (conn_rec*)req->data; + ASSERT_NOT_NULL(conn); + +#if DEBUG + printf("connect_cb %d\n", conn->i); +#endif + + r = uv_read_start(&conn->stream, alloc_cb, read_cb); + ASSERT(r == 0); + + buf.base = buffer; + buf.len = sizeof(buffer) - 1; + + r = uv_write(&conn->write_req, &conn->stream, &buf, 1, after_write); + ASSERT(r == 0); +} + + +static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { + + ASSERT_NOT_NULL(stream); + +#if DEBUG + printf("read_cb %d\n", p->i); +#endif + + uv_close((uv_handle_t*)stream, close_cb); + + if (nread < 0) { + if (nread == UV_EOF) { + ; + } else if (nread == UV_ECONNRESET) { + conns_failed++; + } else { + fprintf(stderr, "read error %s\n", uv_err_name(nread)); + ASSERT(0); + } + } +} + + +static void close_cb(uv_handle_t* handle) { + conn_rec* p = (conn_rec*)handle->data; + + ASSERT_NOT_NULL(handle); + closed_streams++; + +#if DEBUG + printf("close_cb %d\n", p->i); +#endif + + if (uv_now(loop) - start < 10000) { + p->make_connect(p); + } +} + + +static void tcp_do_setup(int num, void* arg) { + int i; + + for (i = 0; i < num; i++) { + tcp_conns[i].i = i; + } +} + + +static void pipe_do_setup(int num, void* arg) { + int i; + + for (i = 0; i < num; i++) { + pipe_conns[i].i = i; + } +} + + +static void tcp_make_connect(conn_rec* p) { + struct sockaddr_in addr; + tcp_conn_rec* tp; + int r; + + tp = (tcp_conn_rec*) p; + + r = uv_tcp_init(loop, (uv_tcp_t*)&p->stream); + ASSERT(r == 0); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_tcp_connect(&tp->conn_req, + (uv_tcp_t*) &p->stream, + (const struct sockaddr*) &addr, + connect_cb); + if (r) { + fprintf(stderr, "uv_tcp_connect error %s\n", uv_err_name(r)); + ASSERT(0); + } + +#if DEBUG + printf("make connect %d\n", p->i); +#endif + + p->conn_req.data = p; + p->write_req.data = p; + p->stream.data = p; +} + + +static void pipe_make_connect(conn_rec* p) { + int r; + + r = uv_pipe_init(loop, (uv_pipe_t*)&p->stream, 0); + ASSERT(r == 0); + + uv_pipe_connect(&((pipe_conn_rec*) p)->conn_req, + (uv_pipe_t*) &p->stream, + TEST_PIPENAME, + connect_cb); + +#if DEBUG + printf("make connect %d\n", p->i); +#endif + + p->conn_req.data = p; + p->write_req.data = p; + p->stream.data = p; +} + + +static int tcp_do_connect(int num, make_connect_fn make_connect, void* arg) { + int i; + + for (i = 0; i < num; i++) { + tcp_make_connect((conn_rec*)&tcp_conns[i]); + tcp_conns[i].make_connect = make_connect; + } + + return 0; +} + + +static int pipe_do_connect(int num, make_connect_fn make_connect, void* arg) { + int i; + + for (i = 0; i < num; i++) { + pipe_make_connect((conn_rec*)&pipe_conns[i]); + pipe_conns[i].make_connect = make_connect; + } + + return 0; +} + + +static int pound_it(int concurrency, + const char* type, + setup_fn do_setup, + connect_fn do_connect, + make_connect_fn make_connect, + void* arg) { + double secs; + int r; + uint64_t start_time; /* in ns */ + uint64_t end_time; + + loop = uv_default_loop(); + + uv_update_time(loop); + start = uv_now(loop); + + /* Run benchmark for at least five seconds. */ + start_time = uv_hrtime(); + + do_setup(concurrency, arg); + + r = do_connect(concurrency, make_connect, arg); + ASSERT(!r); + + uv_run(loop, UV_RUN_DEFAULT); + + end_time = uv_hrtime(); + + /* Number of fractional seconds it took to run the benchmark. */ + secs = (double)(end_time - start_time) / NANOSEC; + + fprintf(stderr, "%s-conn-pound-%d: %.0f accepts/s (%d failed)\n", + type, + concurrency, + closed_streams / secs, + conns_failed); + fflush(stderr); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +BENCHMARK_IMPL(tcp4_pound_100) { + return pound_it(100, + "tcp", + tcp_do_setup, + tcp_do_connect, + tcp_make_connect, + NULL); +} + + +BENCHMARK_IMPL(tcp4_pound_1000) { + return pound_it(1000, + "tcp", + tcp_do_setup, + tcp_do_connect, + tcp_make_connect, + NULL); +} + + +BENCHMARK_IMPL(pipe_pound_100) { + return pound_it(100, + "pipe", + pipe_do_setup, + pipe_do_connect, + pipe_make_connect, + NULL); +} + + +BENCHMARK_IMPL(pipe_pound_1000) { + return pound_it(1000, + "pipe", + pipe_do_setup, + pipe_do_connect, + pipe_make_connect, + NULL); +} diff --git a/external/src/libuv/test/benchmark-pump.c b/external/src/libuv/test/benchmark-pump.c new file mode 100644 index 0000000..7d3977d --- /dev/null +++ b/external/src/libuv/test/benchmark-pump.c @@ -0,0 +1,478 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" +#include "uv.h" + +#include +#include + + +static int TARGET_CONNECTIONS; +#define WRITE_BUFFER_SIZE 8192 +#define MAX_SIMULTANEOUS_CONNECTS 100 + +#define PRINT_STATS 0 +#define STATS_INTERVAL 1000 /* msec */ +#define STATS_COUNT 5 + + +static void do_write(uv_stream_t*); +static void maybe_connect_some(void); + +static uv_req_t* req_alloc(void); +static void req_free(uv_req_t* uv_req); + +static void buf_alloc(uv_handle_t* handle, size_t size, uv_buf_t* buf); +static void buf_free(const uv_buf_t* buf); + +static uv_loop_t* loop; + +static uv_tcp_t tcpServer; +static uv_pipe_t pipeServer; +static uv_stream_t* server; +static struct sockaddr_in listen_addr; +static struct sockaddr_in connect_addr; + +static int64_t start_time; + +static int max_connect_socket = 0; +static int max_read_sockets = 0; +static int read_sockets = 0; +static int write_sockets = 0; + +static int64_t nrecv = 0; +static int64_t nrecv_total = 0; +static int64_t nsent = 0; +static int64_t nsent_total = 0; + +static int stats_left = 0; + +static char write_buffer[WRITE_BUFFER_SIZE]; + +/* Make this as large as you need. */ +#define MAX_WRITE_HANDLES 1000 + +static stream_type type; + +static uv_tcp_t tcp_write_handles[MAX_WRITE_HANDLES]; +static uv_pipe_t pipe_write_handles[MAX_WRITE_HANDLES]; + +static uv_timer_t timer_handle; + + +static double gbit(int64_t bytes, int64_t passed_ms) { + double gbits = ((double)bytes / (1024 * 1024 * 1024)) * 8; + return gbits / ((double)passed_ms / 1000); +} + + +static void show_stats(uv_timer_t* handle) { + int64_t diff; + int i; + +#if PRINT_STATS + fprintf(stderr, "connections: %d, write: %.1f gbit/s\n", + write_sockets, + gbit(nsent, STATS_INTERVAL)); + fflush(stderr); +#endif + + /* Exit if the show is over */ + if (!--stats_left) { + + uv_update_time(loop); + diff = uv_now(loop) - start_time; + + fprintf(stderr, "%s_pump%d_client: %.1f gbit/s\n", + type == TCP ? "tcp" : "pipe", + write_sockets, + gbit(nsent_total, diff)); + fflush(stderr); + + for (i = 0; i < write_sockets; i++) { + if (type == TCP) + uv_close((uv_handle_t*) &tcp_write_handles[i], NULL); + else + uv_close((uv_handle_t*) &pipe_write_handles[i], NULL); + } + + exit(0); + } + + /* Reset read and write counters */ + nrecv = 0; + nsent = 0; +} + + +static void read_show_stats(void) { + int64_t diff; + + uv_update_time(loop); + diff = uv_now(loop) - start_time; + + fprintf(stderr, "%s_pump%d_server: %.1f gbit/s\n", + type == TCP ? "tcp" : "pipe", + max_read_sockets, + gbit(nrecv_total, diff)); + fflush(stderr); +} + + + +static void read_sockets_close_cb(uv_handle_t* handle) { + free(handle); + read_sockets--; + + /* If it's past the first second and everyone has closed their connection + * Then print stats. + */ + if (uv_now(loop) - start_time > 1000 && read_sockets == 0) { + read_show_stats(); + uv_close((uv_handle_t*)server, NULL); + } +} + + +static void start_stats_collection(void) { + int r; + + /* Show-stats timer */ + stats_left = STATS_COUNT; + r = uv_timer_init(loop, &timer_handle); + ASSERT(r == 0); + r = uv_timer_start(&timer_handle, show_stats, STATS_INTERVAL, STATS_INTERVAL); + ASSERT(r == 0); + + uv_update_time(loop); + start_time = uv_now(loop); +} + + +static void read_cb(uv_stream_t* stream, ssize_t bytes, const uv_buf_t* buf) { + if (nrecv_total == 0) { + ASSERT(start_time == 0); + uv_update_time(loop); + start_time = uv_now(loop); + } + + if (bytes < 0) { + uv_close((uv_handle_t*)stream, read_sockets_close_cb); + return; + } + + buf_free(buf); + + nrecv += bytes; + nrecv_total += bytes; +} + + +static void write_cb(uv_write_t* req, int status) { + ASSERT(status == 0); + + req_free((uv_req_t*) req); + + nsent += sizeof write_buffer; + nsent_total += sizeof write_buffer; + + do_write((uv_stream_t*) req->handle); +} + + +static void do_write(uv_stream_t* stream) { + uv_write_t* req; + uv_buf_t buf; + int r; + + buf.base = (char*) &write_buffer; + buf.len = sizeof write_buffer; + + req = (uv_write_t*) req_alloc(); + r = uv_write(req, stream, &buf, 1, write_cb); + ASSERT(r == 0); +} + + +static void connect_cb(uv_connect_t* req, int status) { + int i; + + if (status) { + fprintf(stderr, "%s", uv_strerror(status)); + fflush(stderr); + } + ASSERT(status == 0); + + write_sockets++; + req_free((uv_req_t*) req); + + maybe_connect_some(); + + if (write_sockets == TARGET_CONNECTIONS) { + start_stats_collection(); + + /* Yay! start writing */ + for (i = 0; i < write_sockets; i++) { + if (type == TCP) + do_write((uv_stream_t*) &tcp_write_handles[i]); + else + do_write((uv_stream_t*) &pipe_write_handles[i]); + } + } +} + + +static void maybe_connect_some(void) { + uv_connect_t* req; + uv_tcp_t* tcp; + uv_pipe_t* pipe; + int r; + + while (max_connect_socket < TARGET_CONNECTIONS && + max_connect_socket < write_sockets + MAX_SIMULTANEOUS_CONNECTS) { + if (type == TCP) { + tcp = &tcp_write_handles[max_connect_socket++]; + + r = uv_tcp_init(loop, tcp); + ASSERT(r == 0); + + req = (uv_connect_t*) req_alloc(); + r = uv_tcp_connect(req, + tcp, + (const struct sockaddr*) &connect_addr, + connect_cb); + ASSERT(r == 0); + } else { + pipe = &pipe_write_handles[max_connect_socket++]; + + r = uv_pipe_init(loop, pipe, 0); + ASSERT(r == 0); + + req = (uv_connect_t*) req_alloc(); + uv_pipe_connect(req, pipe, TEST_PIPENAME, connect_cb); + } + } +} + + +static void connection_cb(uv_stream_t* s, int status) { + uv_stream_t* stream; + int r; + + ASSERT(server == s); + ASSERT(status == 0); + + if (type == TCP) { + stream = (uv_stream_t*)malloc(sizeof(uv_tcp_t)); + r = uv_tcp_init(loop, (uv_tcp_t*)stream); + ASSERT(r == 0); + } else { + stream = (uv_stream_t*)malloc(sizeof(uv_pipe_t)); + r = uv_pipe_init(loop, (uv_pipe_t*)stream, 0); + ASSERT(r == 0); + } + + r = uv_accept(s, stream); + ASSERT(r == 0); + + r = uv_read_start(stream, buf_alloc, read_cb); + ASSERT(r == 0); + + read_sockets++; + max_read_sockets++; +} + + +/* + * Request allocator + */ + +typedef struct req_list_s { + union uv_any_req uv_req; + struct req_list_s* next; +} req_list_t; + + +static req_list_t* req_freelist = NULL; + + +static uv_req_t* req_alloc(void) { + req_list_t* req; + + req = req_freelist; + if (req != NULL) { + req_freelist = req->next; + return (uv_req_t*) req; + } + + req = (req_list_t*) malloc(sizeof *req); + return (uv_req_t*) req; +} + + +static void req_free(uv_req_t* uv_req) { + req_list_t* req = (req_list_t*) uv_req; + + req->next = req_freelist; + req_freelist = req; +} + + +/* + * Buffer allocator + */ + +typedef struct buf_list_s { + uv_buf_t uv_buf_t; + struct buf_list_s* next; +} buf_list_t; + + +static buf_list_t* buf_freelist = NULL; + + +static void buf_alloc(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + buf_list_t* ab; + + ab = buf_freelist; + if (ab != NULL) + buf_freelist = ab->next; + else { + ab = malloc(size + sizeof(*ab)); + ab->uv_buf_t.len = size; + ab->uv_buf_t.base = (char*) (ab + 1); + } + + *buf = ab->uv_buf_t; +} + + +static void buf_free(const uv_buf_t* buf) { + buf_list_t* ab = (buf_list_t*) buf->base - 1; + ab->next = buf_freelist; + buf_freelist = ab; +} + + +HELPER_IMPL(tcp_pump_server) { + int r; + + type = TCP; + loop = uv_default_loop(); + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &listen_addr)); + + /* Server */ + server = (uv_stream_t*)&tcpServer; + r = uv_tcp_init(loop, &tcpServer); + ASSERT(r == 0); + r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &listen_addr, 0); + ASSERT(r == 0); + r = uv_listen((uv_stream_t*)&tcpServer, MAX_WRITE_HANDLES, connection_cb); + ASSERT(r == 0); + + notify_parent_process(); + uv_run(loop, UV_RUN_DEFAULT); + + return 0; +} + + +HELPER_IMPL(pipe_pump_server) { + int r; + type = PIPE; + + loop = uv_default_loop(); + + /* Server */ + server = (uv_stream_t*)&pipeServer; + r = uv_pipe_init(loop, &pipeServer, 0); + ASSERT(r == 0); + r = uv_pipe_bind(&pipeServer, TEST_PIPENAME); + ASSERT(r == 0); + r = uv_listen((uv_stream_t*)&pipeServer, MAX_WRITE_HANDLES, connection_cb); + ASSERT(r == 0); + + notify_parent_process(); + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void tcp_pump(int n) { + ASSERT(n <= MAX_WRITE_HANDLES); + TARGET_CONNECTIONS = n; + type = TCP; + + loop = uv_default_loop(); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &connect_addr)); + + /* Start making connections */ + maybe_connect_some(); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); +} + + +static void pipe_pump(int n) { + ASSERT(n <= MAX_WRITE_HANDLES); + TARGET_CONNECTIONS = n; + type = PIPE; + + loop = uv_default_loop(); + + /* Start making connections */ + maybe_connect_some(); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); +} + + +BENCHMARK_IMPL(tcp_pump100_client) { + tcp_pump(100); + return 0; +} + + +BENCHMARK_IMPL(tcp_pump1_client) { + tcp_pump(1); + return 0; +} + + +BENCHMARK_IMPL(pipe_pump100_client) { + pipe_pump(100); + return 0; +} + + +BENCHMARK_IMPL(pipe_pump1_client) { + pipe_pump(1); + return 0; +} diff --git a/external/src/libuv/test/benchmark-sizes.c b/external/src/libuv/test/benchmark-sizes.c new file mode 100644 index 0000000..9bf42f9 --- /dev/null +++ b/external/src/libuv/test/benchmark-sizes.c @@ -0,0 +1,46 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" +#include "uv.h" + + +BENCHMARK_IMPL(sizes) { + fprintf(stderr, "uv_shutdown_t: %u bytes\n", (unsigned int) sizeof(uv_shutdown_t)); + fprintf(stderr, "uv_write_t: %u bytes\n", (unsigned int) sizeof(uv_write_t)); + fprintf(stderr, "uv_connect_t: %u bytes\n", (unsigned int) sizeof(uv_connect_t)); + fprintf(stderr, "uv_udp_send_t: %u bytes\n", (unsigned int) sizeof(uv_udp_send_t)); + fprintf(stderr, "uv_tcp_t: %u bytes\n", (unsigned int) sizeof(uv_tcp_t)); + fprintf(stderr, "uv_pipe_t: %u bytes\n", (unsigned int) sizeof(uv_pipe_t)); + fprintf(stderr, "uv_tty_t: %u bytes\n", (unsigned int) sizeof(uv_tty_t)); + fprintf(stderr, "uv_prepare_t: %u bytes\n", (unsigned int) sizeof(uv_prepare_t)); + fprintf(stderr, "uv_check_t: %u bytes\n", (unsigned int) sizeof(uv_check_t)); + fprintf(stderr, "uv_idle_t: %u bytes\n", (unsigned int) sizeof(uv_idle_t)); + fprintf(stderr, "uv_async_t: %u bytes\n", (unsigned int) sizeof(uv_async_t)); + fprintf(stderr, "uv_timer_t: %u bytes\n", (unsigned int) sizeof(uv_timer_t)); + fprintf(stderr, "uv_fs_poll_t: %u bytes\n", (unsigned int) sizeof(uv_fs_poll_t)); + fprintf(stderr, "uv_fs_event_t: %u bytes\n", (unsigned int) sizeof(uv_fs_event_t)); + fprintf(stderr, "uv_process_t: %u bytes\n", (unsigned int) sizeof(uv_process_t)); + fprintf(stderr, "uv_poll_t: %u bytes\n", (unsigned int) sizeof(uv_poll_t)); + fprintf(stderr, "uv_loop_t: %u bytes\n", (unsigned int) sizeof(uv_loop_t)); + fflush(stderr); + return 0; +} diff --git a/external/src/libuv/test/benchmark-spawn.c b/external/src/libuv/test/benchmark-spawn.c new file mode 100644 index 0000000..ed9ad60 --- /dev/null +++ b/external/src/libuv/test/benchmark-spawn.c @@ -0,0 +1,164 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* This benchmark spawns itself 1000 times. */ + +#include "task.h" +#include "uv.h" + +static uv_loop_t* loop; + +static int N = 1000; +static int done; + +static uv_process_t process; +static uv_process_options_t options; +static char exepath[1024]; +static size_t exepath_size = 1024; +static char* args[3]; +static uv_pipe_t out; + +#define OUTPUT_SIZE 1024 +static char output[OUTPUT_SIZE]; +static int output_used; + +static int process_open; +static int pipe_open; + + +static void spawn(void); + + +static void maybe_spawn(void) { + if (process_open == 0 && pipe_open == 0) { + done++; + if (done < N) { + spawn(); + } + } +} + + +static void process_close_cb(uv_handle_t* handle) { + ASSERT(process_open == 1); + process_open = 0; + maybe_spawn(); +} + + +static void exit_cb(uv_process_t* process, + int64_t exit_status, + int term_signal) { + ASSERT(exit_status == 42); + ASSERT(term_signal == 0); + uv_close((uv_handle_t*)process, process_close_cb); +} + + +static void on_alloc(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + buf->base = output + output_used; + buf->len = OUTPUT_SIZE - output_used; +} + + +static void pipe_close_cb(uv_handle_t* pipe) { + ASSERT(pipe_open == 1); + pipe_open = 0; + maybe_spawn(); +} + + +static void on_read(uv_stream_t* pipe, ssize_t nread, const uv_buf_t* buf) { + if (nread > 0) { + ASSERT(pipe_open == 1); + output_used += nread; + } else if (nread < 0) { + if (nread == UV_EOF) { + uv_close((uv_handle_t*)pipe, pipe_close_cb); + } + } +} + + +static void spawn(void) { + uv_stdio_container_t stdio[2]; + int r; + + ASSERT(process_open == 0); + ASSERT(pipe_open == 0); + + args[0] = exepath; + args[1] = "spawn_helper"; + args[2] = NULL; + options.file = exepath; + options.args = args; + options.exit_cb = exit_cb; + + uv_pipe_init(loop, &out, 0); + + options.stdio = stdio; + options.stdio_count = 2; + options.stdio[0].flags = UV_IGNORE; + options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; + options.stdio[1].data.stream = (uv_stream_t*)&out; + + r = uv_spawn(loop, &process, &options); + ASSERT(r == 0); + + process_open = 1; + pipe_open = 1; + output_used = 0; + + r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); + ASSERT(r == 0); +} + + +BENCHMARK_IMPL(spawn) { + int r; + static int64_t start_time, end_time; + + loop = uv_default_loop(); + + r = uv_exepath(exepath, &exepath_size); + ASSERT(r == 0); + exepath[exepath_size] = '\0'; + + uv_update_time(loop); + start_time = uv_now(loop); + + spawn(); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + uv_update_time(loop); + end_time = uv_now(loop); + + fprintf(stderr, "spawn: %.0f spawns/s\n", + (double) N / (double) (end_time - start_time) * 1000.0); + fflush(stderr); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/benchmark-tcp-write-batch.c b/external/src/libuv/test/benchmark-tcp-write-batch.c new file mode 100644 index 0000000..16aa72f --- /dev/null +++ b/external/src/libuv/test/benchmark-tcp-write-batch.c @@ -0,0 +1,144 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +#define WRITE_REQ_DATA "Hello, world." +#define NUM_WRITE_REQS (1000 * 1000) + +typedef struct { + uv_write_t req; + uv_buf_t buf; +} write_req; + + +static write_req* write_reqs; +static uv_tcp_t tcp_client; +static uv_connect_t connect_req; +static uv_shutdown_t shutdown_req; + +static int shutdown_cb_called = 0; +static int connect_cb_called = 0; +static int write_cb_called = 0; +static int close_cb_called = 0; + +static void connect_cb(uv_connect_t* req, int status); +static void write_cb(uv_write_t* req, int status); +static void shutdown_cb(uv_shutdown_t* req, int status); +static void close_cb(uv_handle_t* handle); + + +static void connect_cb(uv_connect_t* req, int status) { + write_req* w; + int i; + int r; + + ASSERT(req->handle == (uv_stream_t*)&tcp_client); + + for (i = 0; i < NUM_WRITE_REQS; i++) { + w = &write_reqs[i]; + r = uv_write(&w->req, req->handle, &w->buf, 1, write_cb); + ASSERT(r == 0); + } + + r = uv_shutdown(&shutdown_req, req->handle, shutdown_cb); + ASSERT(r == 0); + + connect_cb_called++; +} + + +static void write_cb(uv_write_t* req, int status) { + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + write_cb_called++; +} + + +static void shutdown_cb(uv_shutdown_t* req, int status) { + ASSERT(req->handle == (uv_stream_t*)&tcp_client); + ASSERT(req->handle->write_queue_size == 0); + + uv_close((uv_handle_t*)req->handle, close_cb); + free(write_reqs); + + shutdown_cb_called++; +} + + +static void close_cb(uv_handle_t* handle) { + ASSERT(handle == (uv_handle_t*)&tcp_client); + close_cb_called++; +} + + +BENCHMARK_IMPL(tcp_write_batch) { + struct sockaddr_in addr; + uv_loop_t* loop; + uint64_t start; + uint64_t stop; + int i; + int r; + + write_reqs = malloc(sizeof(*write_reqs) * NUM_WRITE_REQS); + ASSERT_NOT_NULL(write_reqs); + + /* Prepare the data to write out. */ + for (i = 0; i < NUM_WRITE_REQS; i++) { + write_reqs[i].buf = uv_buf_init(WRITE_REQ_DATA, + sizeof(WRITE_REQ_DATA) - 1); + } + + loop = uv_default_loop(); + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_tcp_init(loop, &tcp_client); + ASSERT(r == 0); + + r = uv_tcp_connect(&connect_req, + &tcp_client, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT(r == 0); + + start = uv_hrtime(); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + stop = uv_hrtime(); + + ASSERT(connect_cb_called == 1); + ASSERT(write_cb_called == NUM_WRITE_REQS); + ASSERT(shutdown_cb_called == 1); + ASSERT(close_cb_called == 1); + + printf("%ld write requests in %.2fs.\n", + (long)NUM_WRITE_REQS, + (stop - start) / 1e9); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/benchmark-thread.c b/external/src/libuv/test/benchmark-thread.c new file mode 100644 index 0000000..b37a7fd --- /dev/null +++ b/external/src/libuv/test/benchmark-thread.c @@ -0,0 +1,64 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +#define NUM_THREADS (20 * 1000) + +static volatile int num_threads; + + +static void thread_entry(void* arg) { + ASSERT(arg == (void *) 42); + num_threads++; + /* FIXME write barrier? */ +} + + +BENCHMARK_IMPL(thread_create) { + uint64_t start_time; + double duration; + uv_thread_t tid; + int i, r; + + start_time = uv_hrtime(); + + for (i = 0; i < NUM_THREADS; i++) { + r = uv_thread_create(&tid, thread_entry, (void *) 42); + ASSERT(r == 0); + + r = uv_thread_join(&tid); + ASSERT(r == 0); + } + + duration = (uv_hrtime() - start_time) / 1e9; + + ASSERT(num_threads == NUM_THREADS); + + printf("%d threads created in %.2f seconds (%.0f/s)\n", + NUM_THREADS, duration, NUM_THREADS / duration); + + return 0; +} diff --git a/external/src/libuv/test/benchmark-udp-pummel.c b/external/src/libuv/test/benchmark-udp-pummel.c new file mode 100644 index 0000000..1a22057 --- /dev/null +++ b/external/src/libuv/test/benchmark-udp-pummel.c @@ -0,0 +1,243 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" +#include "uv.h" + +#include +#include +#include + +#define EXPECTED "RANG TANG DING DONG I AM THE JAPANESE SANDMAN" + +#define TEST_DURATION 5000 /* ms */ + +#define BASE_PORT 12345 + +struct sender_state { + struct sockaddr_in addr; + uv_udp_send_t send_req; + uv_udp_t udp_handle; +}; + +struct receiver_state { + struct sockaddr_in addr; + uv_udp_t udp_handle; +}; + +/* not used in timed mode */ +static unsigned int packet_counter = (unsigned int) 1e6; + +static int n_senders_; +static int n_receivers_; +static uv_buf_t bufs[5]; +static struct sender_state senders[1024]; +static struct receiver_state receivers[1024]; + +static unsigned int send_cb_called; +static unsigned int recv_cb_called; +static unsigned int close_cb_called; +static int timed; +static int exiting; + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + ASSERT(suggested_size <= sizeof(slab)); + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void send_cb(uv_udp_send_t* req, int status) { + struct sender_state* s; + + ASSERT_NOT_NULL(req); + + if (status != 0) { + ASSERT(status == UV_ECANCELED); + return; + } + + if (exiting) + return; + + s = container_of(req, struct sender_state, send_req); + ASSERT(req->handle == &s->udp_handle); + + if (timed) + goto send; + + if (packet_counter == 0) { + uv_close((uv_handle_t*)&s->udp_handle, NULL); + return; + } + + packet_counter--; + +send: + ASSERT(0 == uv_udp_send(&s->send_req, + &s->udp_handle, + bufs, + ARRAY_SIZE(bufs), + (const struct sockaddr*) &s->addr, + send_cb)); + send_cb_called++; +} + + +static void recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags) { + if (nread == 0) + return; + + if (nread < 0) { + ASSERT(nread == UV_ECANCELED); + return; + } + + ASSERT(addr->sa_family == AF_INET); + ASSERT(!memcmp(buf->base, EXPECTED, nread)); + + recv_cb_called++; +} + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +static void timeout_cb(uv_timer_t* timer) { + int i; + + exiting = 1; + + for (i = 0; i < n_senders_; i++) + uv_close((uv_handle_t*)&senders[i].udp_handle, close_cb); + + for (i = 0; i < n_receivers_; i++) + uv_close((uv_handle_t*)&receivers[i].udp_handle, close_cb); +} + + +static int pummel(unsigned int n_senders, + unsigned int n_receivers, + unsigned long timeout) { + uv_timer_t timer_handle; + uint64_t duration; + uv_loop_t* loop; + unsigned int i; + + ASSERT(n_senders <= ARRAY_SIZE(senders)); + ASSERT(n_receivers <= ARRAY_SIZE(receivers)); + + loop = uv_default_loop(); + + n_senders_ = n_senders; + n_receivers_ = n_receivers; + + if (timeout) { + ASSERT(0 == uv_timer_init(loop, &timer_handle)); + ASSERT(0 == uv_timer_start(&timer_handle, timeout_cb, timeout, 0)); + /* Timer should not keep loop alive. */ + uv_unref((uv_handle_t*)&timer_handle); + timed = 1; + } + + for (i = 0; i < n_receivers; i++) { + struct receiver_state* s = receivers + i; + struct sockaddr_in addr; + ASSERT(0 == uv_ip4_addr("0.0.0.0", BASE_PORT + i, &addr)); + ASSERT(0 == uv_udp_init(loop, &s->udp_handle)); + ASSERT(0 == uv_udp_bind(&s->udp_handle, (const struct sockaddr*) &addr, 0)); + ASSERT(0 == uv_udp_recv_start(&s->udp_handle, alloc_cb, recv_cb)); + uv_unref((uv_handle_t*)&s->udp_handle); + } + + bufs[0] = uv_buf_init(&EXPECTED[0], 10); + bufs[1] = uv_buf_init(&EXPECTED[10], 10); + bufs[2] = uv_buf_init(&EXPECTED[20], 10); + bufs[3] = uv_buf_init(&EXPECTED[30], 10); + bufs[4] = uv_buf_init(&EXPECTED[40], 5); + + for (i = 0; i < n_senders; i++) { + struct sender_state* s = senders + i; + ASSERT(0 == uv_ip4_addr("127.0.0.1", + BASE_PORT + (i % n_receivers), + &s->addr)); + ASSERT(0 == uv_udp_init(loop, &s->udp_handle)); + ASSERT(0 == uv_udp_send(&s->send_req, + &s->udp_handle, + bufs, + ARRAY_SIZE(bufs), + (const struct sockaddr*) &s->addr, + send_cb)); + } + + duration = uv_hrtime(); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + duration = uv_hrtime() - duration; + /* convert from nanoseconds to milliseconds */ + duration = duration / (uint64_t) 1e6; + + printf("udp_pummel_%dv%d: %.0f/s received, %.0f/s sent. " + "%u received, %u sent in %.1f seconds.\n", + n_receivers, + n_senders, + recv_cb_called / (duration / 1000.0), + send_cb_called / (duration / 1000.0), + recv_cb_called, + send_cb_called, + duration / 1000.0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +#define X(a, b) \ + BENCHMARK_IMPL(udp_pummel_##a##v##b) { \ + return pummel(a, b, 0); \ + } \ + BENCHMARK_IMPL(udp_timed_pummel_##a##v##b) { \ + return pummel(a, b, TEST_DURATION); \ + } + +X(1, 1) +X(1, 10) +X(1, 100) +X(1, 1000) +X(10, 10) +X(10, 100) +X(10, 1000) +X(100, 10) +X(100, 100) +X(100, 1000) +X(1000, 1000) + +#undef X diff --git a/external/src/libuv/test/blackhole-server.c b/external/src/libuv/test/blackhole-server.c new file mode 100644 index 0000000..0a8758e --- /dev/null +++ b/external/src/libuv/test/blackhole-server.c @@ -0,0 +1,122 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +typedef struct { + uv_tcp_t handle; + uv_shutdown_t shutdown_req; +} conn_rec; + +static uv_tcp_t tcp_server; + +static void connection_cb(uv_stream_t* stream, int status); +static void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); +static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf); +static void shutdown_cb(uv_shutdown_t* req, int status); +static void close_cb(uv_handle_t* handle); + + +static void connection_cb(uv_stream_t* stream, int status) { + conn_rec* conn; + int r; + + ASSERT(status == 0); + ASSERT(stream == (uv_stream_t*)&tcp_server); + + conn = malloc(sizeof *conn); + ASSERT_NOT_NULL(conn); + + r = uv_tcp_init(stream->loop, &conn->handle); + ASSERT(r == 0); + + r = uv_accept(stream, (uv_stream_t*)&conn->handle); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*)&conn->handle, alloc_cb, read_cb); + ASSERT(r == 0); +} + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { + conn_rec* conn; + int r; + + if (nread >= 0) + return; + + ASSERT(nread == UV_EOF); + + conn = container_of(stream, conn_rec, handle); + + r = uv_shutdown(&conn->shutdown_req, stream, shutdown_cb); + ASSERT(r == 0); +} + + +static void shutdown_cb(uv_shutdown_t* req, int status) { + conn_rec* conn = container_of(req, conn_rec, shutdown_req); + uv_close((uv_handle_t*)&conn->handle, close_cb); +} + + +static void close_cb(uv_handle_t* handle) { + conn_rec* conn = container_of(handle, conn_rec, handle); + free(conn); +} + + +HELPER_IMPL(tcp4_blackhole_server) { + struct sockaddr_in addr; + uv_loop_t* loop; + int r; + + loop = uv_default_loop(); + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_tcp_init(loop, &tcp_server); + ASSERT(r == 0); + + r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_listen((uv_stream_t*)&tcp_server, 128, connection_cb); + ASSERT(r == 0); + + notify_parent_process(); + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(0 && "Blackhole server dropped out of event loop."); + + return 0; +} diff --git a/external/src/libuv/test/dns-server.c b/external/src/libuv/test/dns-server.c new file mode 100644 index 0000000..f8ca87f --- /dev/null +++ b/external/src/libuv/test/dns-server.c @@ -0,0 +1,340 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include +#include + + +typedef struct { + uv_write_t req; + uv_buf_t buf; +} write_req_t; + + +/* used to track multiple DNS requests received */ +typedef struct { + char* prevbuf_ptr; + int prevbuf_pos; + int prevbuf_rem; +} dnsstate; + + +/* modify handle to append dnsstate */ +typedef struct { + uv_tcp_t handle; + dnsstate state; +} dnshandle; + + +static uv_loop_t* loop; + + +static uv_tcp_t server; + + +static void after_write(uv_write_t* req, int status); +static void after_read(uv_stream_t*, ssize_t nread, const uv_buf_t* buf); +static void on_close(uv_handle_t* peer); +static void on_connection(uv_stream_t*, int status); + +#define WRITE_BUF_LEN (64*1024) +#define DNSREC_LEN (4) + +#define LEN_OFFSET 0 +#define QUERYID_OFFSET 2 + +static unsigned char DNSRsp[] = { + 0, 43, 0, 0, 0x81, 0x80, 0, 1, 0, 1, 0, 0, 0, 0 +}; + +static unsigned char qrecord[] = { + 5, 'e', 'c', 'h', 'o', 's', 3, 's', 'r', 'v', 0, 0, 1, 0, 1 +}; + +static unsigned char arecord[] = { + 0xc0, 0x0c, 0, 1, 0, 1, 0, 0, 5, 0xbd, 0, 4, 10, 0, 1, 1 +}; + + +static void after_write(uv_write_t* req, int status) { + write_req_t* wr; + + if (status) { + fprintf(stderr, "uv_write error: %s\n", uv_strerror(status)); + ASSERT(0); + } + + wr = (write_req_t*) req; + + /* Free the read/write buffer and the request */ + free(wr->buf.base); + free(wr); +} + + +static void after_shutdown(uv_shutdown_t* req, int status) { + uv_close((uv_handle_t*) req->handle, on_close); + free(req); +} + + +static void addrsp(write_req_t* wr, char* hdr) { + char * dnsrsp; + short int rsplen; + short int* reclen; + + rsplen = sizeof(DNSRsp) + sizeof(qrecord) + sizeof(arecord); + + ASSERT (rsplen + wr->buf.len < WRITE_BUF_LEN); + + dnsrsp = wr->buf.base + wr->buf.len; + + /* copy stock response */ + memcpy(dnsrsp, DNSRsp, sizeof(DNSRsp)); + memcpy(dnsrsp + sizeof(DNSRsp), qrecord, sizeof(qrecord)); + memcpy(dnsrsp + sizeof(DNSRsp) + sizeof(qrecord), arecord, sizeof(arecord)); + + /* overwrite with network order length and id from request header */ + reclen = (short int*)dnsrsp; + *reclen = htons(rsplen-2); + dnsrsp[QUERYID_OFFSET] = hdr[QUERYID_OFFSET]; + dnsrsp[QUERYID_OFFSET+1] = hdr[QUERYID_OFFSET+1]; + + wr->buf.len += rsplen; +} + +static void process_req(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + write_req_t* wr; + dnshandle* dns = (dnshandle*)handle; + char hdrbuf[DNSREC_LEN]; + int hdrbuf_remaining = DNSREC_LEN; + int rec_remaining = 0; + int readbuf_remaining; + char* dnsreq; + char* hdrstart; + int usingprev = 0; + + wr = (write_req_t*) malloc(sizeof *wr); + wr->buf.base = (char*)malloc(WRITE_BUF_LEN); + wr->buf.len = 0; + + if (dns->state.prevbuf_ptr != NULL) { + dnsreq = dns->state.prevbuf_ptr + dns->state.prevbuf_pos; + readbuf_remaining = dns->state.prevbuf_rem; + usingprev = 1; + } else { + dnsreq = buf->base; + readbuf_remaining = nread; + } + hdrstart = dnsreq; + + while (dnsreq != NULL) { + /* something to process */ + while (readbuf_remaining > 0) { + /* something to process in current buffer */ + if (hdrbuf_remaining > 0) { + /* process len and id */ + if (readbuf_remaining < hdrbuf_remaining) { + /* too little to get request header. save for next buffer */ + memcpy(&hdrbuf[DNSREC_LEN - hdrbuf_remaining], + dnsreq, + readbuf_remaining); + hdrbuf_remaining = DNSREC_LEN - readbuf_remaining; + break; + } else { + /* save header */ + memcpy(&hdrbuf[DNSREC_LEN - hdrbuf_remaining], + dnsreq, + hdrbuf_remaining); + dnsreq += hdrbuf_remaining; + readbuf_remaining -= hdrbuf_remaining; + hdrbuf_remaining = 0; + + /* get record length */ + rec_remaining = (unsigned) hdrbuf[0] * 256 + (unsigned) hdrbuf[1]; + rec_remaining -= (DNSREC_LEN - 2); + } + } + + if (rec_remaining <= readbuf_remaining) { + /* prepare reply */ + addrsp(wr, hdrbuf); + + /* move to next record */ + dnsreq += rec_remaining; + hdrstart = dnsreq; + readbuf_remaining -= rec_remaining; + rec_remaining = 0; + hdrbuf_remaining = DNSREC_LEN; + } else { + /* otherwise this buffer is done. */ + rec_remaining -= readbuf_remaining; + break; + } + } + + /* If we had to use bytes from prev buffer, start processing the current + * one. + */ + if (usingprev == 1) { + /* free previous buffer */ + free(dns->state.prevbuf_ptr); + dnsreq = buf->base; + readbuf_remaining = nread; + usingprev = 0; + } else { + dnsreq = NULL; + } + } + + /* send write buffer */ + if (wr->buf.len > 0) { + if (uv_write((uv_write_t*) &wr->req, handle, &wr->buf, 1, after_write)) { + FATAL("uv_write failed"); + } + } + + if (readbuf_remaining > 0) { + /* save start of record position, so we can continue on next read */ + dns->state.prevbuf_ptr = buf->base; + dns->state.prevbuf_pos = hdrstart - buf->base; + dns->state.prevbuf_rem = nread - dns->state.prevbuf_pos; + } else { + /* nothing left in this buffer */ + dns->state.prevbuf_ptr = NULL; + dns->state.prevbuf_pos = 0; + dns->state.prevbuf_rem = 0; + free(buf->base); + } +} + +static void after_read(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + uv_shutdown_t* req; + + if (nread < 0) { + /* Error or EOF */ + ASSERT(nread == UV_EOF); + + if (buf->base) { + free(buf->base); + } + + req = malloc(sizeof *req); + uv_shutdown(req, handle, after_shutdown); + + return; + } + + if (nread == 0) { + /* Everything OK, but nothing read. */ + free(buf->base); + return; + } + /* process requests and send responses */ + process_req(handle, nread, buf); +} + + +static void on_close(uv_handle_t* peer) { + free(peer); +} + + +static void buf_alloc(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + buf->base = malloc(suggested_size); + buf->len = suggested_size; +} + + +static void on_connection(uv_stream_t* server, int status) { + dnshandle* handle; + int r; + + ASSERT(status == 0); + + handle = (dnshandle*) malloc(sizeof *handle); + ASSERT_NOT_NULL(handle); + + /* initialize read buffer state */ + handle->state.prevbuf_ptr = 0; + handle->state.prevbuf_pos = 0; + handle->state.prevbuf_rem = 0; + + r = uv_tcp_init(loop, (uv_tcp_t*)handle); + ASSERT(r == 0); + + r = uv_accept(server, (uv_stream_t*)handle); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*)handle, buf_alloc, after_read); + ASSERT(r == 0); +} + + +static int dns_start(int port) { + struct sockaddr_in addr; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", port, &addr)); + + r = uv_tcp_init(loop, &server); + if (r) { + /* TODO: Error codes */ + fprintf(stderr, "Socket creation error\n"); + return 1; + } + + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); + if (r) { + /* TODO: Error codes */ + fprintf(stderr, "Bind error\n"); + return 1; + } + + r = uv_listen((uv_stream_t*)&server, 128, on_connection); + if (r) { + /* TODO: Error codes */ + fprintf(stderr, "Listen error\n"); + return 1; + } + + return 0; +} + + +HELPER_IMPL(dns_server) { + loop = uv_default_loop(); + + if (dns_start(TEST_PORT_2)) + return 1; + + uv_run(loop, UV_RUN_DEFAULT); + return 0; +} diff --git a/external/src/libuv/test/echo-server.c b/external/src/libuv/test/echo-server.c new file mode 100644 index 0000000..058c992 --- /dev/null +++ b/external/src/libuv/test/echo-server.c @@ -0,0 +1,431 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + +typedef struct { + uv_write_t req; + uv_buf_t buf; +} write_req_t; + +static uv_loop_t* loop; + +static int server_closed; +static stream_type serverType; +static uv_tcp_t tcpServer; +static uv_udp_t udpServer; +static uv_pipe_t pipeServer; +static uv_handle_t* server; +static uv_udp_send_t* send_freelist; + +static void after_write(uv_write_t* req, int status); +static void after_read(uv_stream_t*, ssize_t nread, const uv_buf_t* buf); +static void on_close(uv_handle_t* peer); +static void on_server_close(uv_handle_t* handle); +static void on_connection(uv_stream_t*, int status); + + +static void after_write(uv_write_t* req, int status) { + write_req_t* wr; + + /* Free the read/write buffer and the request */ + wr = (write_req_t*) req; + free(wr->buf.base); + free(wr); + + if (status == 0) + return; + + fprintf(stderr, + "uv_write error: %s - %s\n", + uv_err_name(status), + uv_strerror(status)); +} + + +static void after_shutdown(uv_shutdown_t* req, int status) { + ASSERT_EQ(status, 0); + uv_close((uv_handle_t*) req->handle, on_close); + free(req); +} + + +static void on_shutdown(uv_shutdown_t* req, int status) { + ASSERT_EQ(status, 0); + free(req); +} + + +static void after_read(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + int i; + write_req_t *wr; + uv_shutdown_t* sreq; + int shutdown = 0; + + if (nread < 0) { + /* Error or EOF */ + ASSERT_EQ(nread, UV_EOF); + + free(buf->base); + sreq = malloc(sizeof* sreq); + if (uv_is_writable(handle)) { + ASSERT_EQ(0, uv_shutdown(sreq, handle, after_shutdown)); + } + return; + } + + if (nread == 0) { + /* Everything OK, but nothing read. */ + free(buf->base); + return; + } + + /* + * Scan for the letter Q which signals that we should quit the server. + * If we get QS it means close the stream. + * If we get QSS it means shutdown the stream. + * If we get QSH it means disable linger before close the socket. + */ + for (i = 0; i < nread; i++) { + if (buf->base[i] == 'Q') { + if (i + 1 < nread && buf->base[i + 1] == 'S') { + int reset = 0; + if (i + 2 < nread && buf->base[i + 2] == 'S') + shutdown = 1; + if (i + 2 < nread && buf->base[i + 2] == 'H') + reset = 1; + if (reset && handle->type == UV_TCP) + ASSERT_EQ(0, uv_tcp_close_reset((uv_tcp_t*) handle, on_close)); + else if (shutdown) + break; + else + uv_close((uv_handle_t*) handle, on_close); + free(buf->base); + return; + } else if (!server_closed) { + uv_close(server, on_server_close); + server_closed = 1; + } + } + } + + wr = (write_req_t*) malloc(sizeof *wr); + ASSERT_NOT_NULL(wr); + wr->buf = uv_buf_init(buf->base, nread); + + if (uv_write(&wr->req, handle, &wr->buf, 1, after_write)) { + FATAL("uv_write failed"); + } + + if (shutdown) + ASSERT_EQ(0, uv_shutdown(malloc(sizeof* sreq), handle, on_shutdown)); +} + + +static void on_close(uv_handle_t* peer) { + free(peer); +} + + +static void echo_alloc(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + buf->base = malloc(suggested_size); + buf->len = suggested_size; +} + +static void slab_alloc(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + /* up to 16 datagrams at once */ + static char slab[16 * 64 * 1024]; + buf->base = slab; + buf->len = sizeof(slab); +} + +static void on_connection(uv_stream_t* server, int status) { + uv_stream_t* stream; + int r; + + if (status != 0) { + fprintf(stderr, "Connect error %s\n", uv_err_name(status)); + } + ASSERT(status == 0); + + switch (serverType) { + case TCP: + stream = malloc(sizeof(uv_tcp_t)); + ASSERT_NOT_NULL(stream); + r = uv_tcp_init(loop, (uv_tcp_t*)stream); + ASSERT(r == 0); + break; + + case PIPE: + stream = malloc(sizeof(uv_pipe_t)); + ASSERT_NOT_NULL(stream); + r = uv_pipe_init(loop, (uv_pipe_t*)stream, 0); + ASSERT(r == 0); + break; + + default: + ASSERT(0 && "Bad serverType"); + abort(); + } + + /* associate server with stream */ + stream->data = server; + + r = uv_accept(server, stream); + ASSERT(r == 0); + + r = uv_read_start(stream, echo_alloc, after_read); + ASSERT(r == 0); +} + + +static void on_server_close(uv_handle_t* handle) { + ASSERT(handle == server); +} + +static uv_udp_send_t* send_alloc(void) { + uv_udp_send_t* req = send_freelist; + if (req != NULL) + send_freelist = req->data; + else + req = malloc(sizeof(*req)); + return req; +} + +static void on_send(uv_udp_send_t* req, int status) { + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + req->data = send_freelist; + send_freelist = req; +} + +static void on_recv(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* rcvbuf, + const struct sockaddr* addr, + unsigned flags) { + uv_buf_t sndbuf; + uv_udp_send_t* req; + + if (nread == 0) { + /* Everything OK, but nothing read. */ + return; + } + + ASSERT(nread > 0); + ASSERT(addr->sa_family == AF_INET); + + req = send_alloc(); + ASSERT_NOT_NULL(req); + sndbuf = uv_buf_init(rcvbuf->base, nread); + ASSERT(0 <= uv_udp_send(req, handle, &sndbuf, 1, addr, on_send)); +} + +static int tcp4_echo_start(int port) { + struct sockaddr_in addr; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", port, &addr)); + + server = (uv_handle_t*)&tcpServer; + serverType = TCP; + + r = uv_tcp_init(loop, &tcpServer); + if (r) { + /* TODO: Error codes */ + fprintf(stderr, "Socket creation error\n"); + return 1; + } + + r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr, 0); + if (r) { + /* TODO: Error codes */ + fprintf(stderr, "Bind error\n"); + return 1; + } + + r = uv_listen((uv_stream_t*)&tcpServer, SOMAXCONN, on_connection); + if (r) { + /* TODO: Error codes */ + fprintf(stderr, "Listen error %s\n", uv_err_name(r)); + return 1; + } + + return 0; +} + + +static int tcp6_echo_start(int port) { + struct sockaddr_in6 addr6; + int r; + + ASSERT(0 == uv_ip6_addr("::1", port, &addr6)); + + server = (uv_handle_t*)&tcpServer; + serverType = TCP; + + r = uv_tcp_init(loop, &tcpServer); + if (r) { + /* TODO: Error codes */ + fprintf(stderr, "Socket creation error\n"); + return 1; + } + + /* IPv6 is optional as not all platforms support it */ + r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr6, 0); + if (r) { + /* show message but return OK */ + fprintf(stderr, "IPv6 not supported\n"); + return 0; + } + + r = uv_listen((uv_stream_t*)&tcpServer, SOMAXCONN, on_connection); + if (r) { + /* TODO: Error codes */ + fprintf(stderr, "Listen error\n"); + return 1; + } + + return 0; +} + + +static int udp4_echo_start(int port) { + struct sockaddr_in addr; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", port, &addr)); + server = (uv_handle_t*)&udpServer; + serverType = UDP; + + r = uv_udp_init(loop, &udpServer); + if (r) { + fprintf(stderr, "uv_udp_init: %s\n", uv_strerror(r)); + return 1; + } + + r = uv_udp_bind(&udpServer, (const struct sockaddr*) &addr, 0); + if (r) { + fprintf(stderr, "uv_udp_bind: %s\n", uv_strerror(r)); + return 1; + } + + r = uv_udp_recv_start(&udpServer, slab_alloc, on_recv); + if (r) { + fprintf(stderr, "uv_udp_recv_start: %s\n", uv_strerror(r)); + return 1; + } + + return 0; +} + + +static int pipe_echo_start(char* pipeName) { + int r; + +#ifndef _WIN32 + { + uv_fs_t req; + uv_fs_unlink(NULL, &req, pipeName, NULL); + uv_fs_req_cleanup(&req); + } +#endif + + server = (uv_handle_t*)&pipeServer; + serverType = PIPE; + + r = uv_pipe_init(loop, &pipeServer, 0); + if (r) { + fprintf(stderr, "uv_pipe_init: %s\n", uv_strerror(r)); + return 1; + } + + r = uv_pipe_bind(&pipeServer, pipeName); + if (r) { + fprintf(stderr, "uv_pipe_bind: %s\n", uv_strerror(r)); + return 1; + } + + r = uv_listen((uv_stream_t*)&pipeServer, SOMAXCONN, on_connection); + if (r) { + fprintf(stderr, "uv_pipe_listen: %s\n", uv_strerror(r)); + return 1; + } + + return 0; +} + + +HELPER_IMPL(tcp4_echo_server) { + loop = uv_default_loop(); + + if (tcp4_echo_start(TEST_PORT)) + return 1; + + notify_parent_process(); + uv_run(loop, UV_RUN_DEFAULT); + return 0; +} + + +HELPER_IMPL(tcp6_echo_server) { + loop = uv_default_loop(); + + if (tcp6_echo_start(TEST_PORT)) + return 1; + + notify_parent_process(); + uv_run(loop, UV_RUN_DEFAULT); + return 0; +} + + +HELPER_IMPL(pipe_echo_server) { + loop = uv_default_loop(); + + if (pipe_echo_start(TEST_PIPENAME)) + return 1; + + notify_parent_process(); + uv_run(loop, UV_RUN_DEFAULT); + return 0; +} + + +HELPER_IMPL(udp4_echo_server) { + loop = uv_default_loop(); + + if (udp4_echo_start(TEST_PORT)) + return 1; + + notify_parent_process(); + uv_run(loop, UV_RUN_DEFAULT); + return 0; +} diff --git a/external/src/libuv/test/fixtures/empty_file b/external/src/libuv/test/fixtures/empty_file new file mode 100644 index 0000000..e69de29 diff --git a/external/src/libuv/test/fixtures/load_error.node b/external/src/libuv/test/fixtures/load_error.node new file mode 100644 index 0000000..323fae0 --- /dev/null +++ b/external/src/libuv/test/fixtures/load_error.node @@ -0,0 +1 @@ +foobar diff --git a/external/src/libuv/test/fixtures/lorem_ipsum.txt b/external/src/libuv/test/fixtures/lorem_ipsum.txt new file mode 100644 index 0000000..1b37687 --- /dev/null +++ b/external/src/libuv/test/fixtures/lorem_ipsum.txt @@ -0,0 +1 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. diff --git a/external/src/libuv/test/run-benchmarks.c b/external/src/libuv/test/run-benchmarks.c new file mode 100644 index 0000000..2b343da --- /dev/null +++ b/external/src/libuv/test/run-benchmarks.c @@ -0,0 +1,72 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include + +#include "runner.h" +#include "task.h" + +/* Actual benchmarks and helpers are defined in benchmark-list.h */ +#include "benchmark-list.h" + +#ifdef __MVS__ +#include "zos-base.h" +/* Initialize environment and zoslib */ +__attribute__((constructor)) void init() { + zoslib_config_t config; + init_zoslib_config(&config); + init_zoslib(config); +} +#endif + + +static int maybe_run_test(int argc, char **argv); + + +int main(int argc, char **argv) { + platform_init(argc, argv); + + switch (argc) { + case 1: return run_tests(1); + case 2: return maybe_run_test(argc, argv); + case 3: return run_test_part(argv[1], argv[2]); + default: + fprintf(stderr, "Too many arguments.\n"); + fflush(stderr); + return EXIT_FAILURE; + } +} + + +static int maybe_run_test(int argc, char **argv) { + if (strcmp(argv[1], "--list") == 0) { + print_tests(stdout); + return 0; + } + + if (strcmp(argv[1], "spawn_helper") == 0) { + printf("hello world\n"); + return 42; + } + + return run_test(argv[1], 1, 1); +} diff --git a/external/src/libuv/test/run-tests.c b/external/src/libuv/test/run-tests.c new file mode 100644 index 0000000..5e53aaa --- /dev/null +++ b/external/src/libuv/test/run-tests.c @@ -0,0 +1,276 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include + +#ifdef _WIN32 +# include +#else +# include +#endif + +#include "uv.h" +#include "runner.h" +#include "task.h" + +/* Actual tests and helpers are defined in test-list.h */ +#include "test-list.h" + +#ifdef __MVS__ +#include "zos-base.h" +/* Initialize environment and zoslib */ +__attribute__((constructor)) void init() { + zoslib_config_t config; + init_zoslib_config(&config); + init_zoslib(config); +} +#endif + +int ipc_helper(int listen_after_write); +int ipc_helper_heavy_traffic_deadlock_bug(void); +int ipc_helper_tcp_connection(void); +int ipc_helper_closed_handle(void); +int ipc_send_recv_helper(void); +int ipc_helper_bind_twice(void); +int ipc_helper_send_zero(void); +int stdio_over_pipes_helper(void); +void spawn_stdin_stdout(void); +void process_title_big_argv(void); +int spawn_tcp_server_helper(void); + +static int maybe_run_test(int argc, char **argv); + +#ifdef _WIN32 +typedef BOOL (WINAPI *sCompareObjectHandles)(_In_ HANDLE, _In_ HANDLE); +#endif + + +int main(int argc, char **argv) { +#ifndef _WIN32 + if (0 == geteuid() && NULL == getenv("UV_RUN_AS_ROOT")) { + fprintf(stderr, "The libuv test suite cannot be run as root.\n"); + return EXIT_FAILURE; + } +#endif + + platform_init(argc, argv); + argv = uv_setup_args(argc, argv); + + switch (argc) { + case 1: return run_tests(0); + case 2: return maybe_run_test(argc, argv); + case 3: return run_test_part(argv[1], argv[2]); + case 4: return maybe_run_test(argc, argv); + default: + fprintf(stderr, "Too many arguments.\n"); + fflush(stderr); + return EXIT_FAILURE; + } + +#ifndef __SUNPRO_C + return EXIT_SUCCESS; +#endif +} + + +static int maybe_run_test(int argc, char **argv) { + if (strcmp(argv[1], "--list") == 0) { + print_tests(stdout); + return 0; + } + + if (strcmp(argv[1], "ipc_helper_listen_before_write") == 0) { + return ipc_helper(0); + } + + if (strcmp(argv[1], "ipc_helper_listen_after_write") == 0) { + return ipc_helper(1); + } + + if (strcmp(argv[1], "ipc_helper_heavy_traffic_deadlock_bug") == 0) { + return ipc_helper_heavy_traffic_deadlock_bug(); + } + + if (strcmp(argv[1], "ipc_send_recv_helper") == 0) { + return ipc_send_recv_helper(); + } + + if (strcmp(argv[1], "ipc_helper_tcp_connection") == 0) { + return ipc_helper_tcp_connection(); + } + + if (strcmp(argv[1], "ipc_helper_closed_handle") == 0) { + return ipc_helper_closed_handle(); + } + + if (strcmp(argv[1], "ipc_helper_bind_twice") == 0) { + return ipc_helper_bind_twice(); + } + + if (strcmp(argv[1], "ipc_helper_send_zero") == 0) { + return ipc_helper_send_zero(); + } + + if (strcmp(argv[1], "stdio_over_pipes_helper") == 0) { + return stdio_over_pipes_helper(); + } + + if (strcmp(argv[1], "spawn_helper1") == 0) { + notify_parent_process(); + return 1; + } + + if (strcmp(argv[1], "spawn_helper2") == 0) { + notify_parent_process(); + printf("hello world\n"); + return 1; + } + + if (strcmp(argv[1], "spawn_tcp_server_helper") == 0) { + notify_parent_process(); + return spawn_tcp_server_helper(); + } + + if (strcmp(argv[1], "spawn_helper3") == 0) { + char buffer[256]; + notify_parent_process(); + ASSERT(buffer == fgets(buffer, sizeof(buffer) - 1, stdin)); + buffer[sizeof(buffer) - 1] = '\0'; + fputs(buffer, stdout); + return 1; + } + + if (strcmp(argv[1], "spawn_helper4") == 0) { + notify_parent_process(); + /* Never surrender, never return! */ + for (;;) uv_sleep(10000); + } + + if (strcmp(argv[1], "spawn_helper5") == 0) { + const char out[] = "fourth stdio!\n"; + notify_parent_process(); + { +#ifdef _WIN32 + DWORD bytes; + WriteFile((HANDLE) _get_osfhandle(3), out, sizeof(out) - 1, &bytes, NULL); +#else + ssize_t r; + + do + r = write(3, out, sizeof(out) - 1); + while (r == -1 && errno == EINTR); + + fsync(3); +#endif + } + return 1; + } + + if (strcmp(argv[1], "spawn_helper6") == 0) { + int r; + + notify_parent_process(); + + r = fprintf(stdout, "hello world\n"); + ASSERT(r > 0); + + r = fprintf(stderr, "hello errworld\n"); + ASSERT(r > 0); + + return 1; + } + + if (strcmp(argv[1], "spawn_helper7") == 0) { + int r; + char *test; + + notify_parent_process(); + + /* Test if the test value from the parent is still set */ + test = getenv("ENV_TEST"); + ASSERT_NOT_NULL(test); + + r = fprintf(stdout, "%s", test); + ASSERT(r > 0); + + return 1; + } + + if (strcmp(argv[1], "spawn_helper8") == 0) { + uv_os_fd_t closed_fd; + uv_os_fd_t open_fd; +#ifdef _WIN32 + DWORD flags; + HMODULE kernelbase_module; + sCompareObjectHandles pCompareObjectHandles; /* function introduced in Windows 10 */ +#endif + notify_parent_process(); + ASSERT(sizeof(closed_fd) == read(0, &closed_fd, sizeof(closed_fd))); + ASSERT(sizeof(open_fd) == read(0, &open_fd, sizeof(open_fd))); +#ifdef _WIN32 + ASSERT((intptr_t) closed_fd > 0); + ASSERT((intptr_t) open_fd > 0); + ASSERT(0 != GetHandleInformation(open_fd, &flags)); + kernelbase_module = GetModuleHandleA("kernelbase.dll"); + pCompareObjectHandles = (sCompareObjectHandles) + GetProcAddress(kernelbase_module, "CompareObjectHandles"); + ASSERT(pCompareObjectHandles == NULL || !pCompareObjectHandles(open_fd, closed_fd)); +#else + ASSERT(open_fd > 2); + ASSERT(closed_fd > 2); +# if defined(__PASE__) /* On IBMi PASE, write() returns 1 */ + ASSERT(1 == write(closed_fd, "x", 1)); +# else + ASSERT(-1 == write(closed_fd, "x", 1)); +# endif /* !__PASE__ */ +#endif + return 1; + } + + if (strcmp(argv[1], "spawn_helper9") == 0) { + notify_parent_process(); + spawn_stdin_stdout(); + return 1; + } + +#ifndef _WIN32 + if (strcmp(argv[1], "spawn_helper_setuid_setgid") == 0) { + uv_uid_t uid = atoi(argv[2]); + uv_gid_t gid = atoi(argv[3]); + + ASSERT(uid == getuid()); + ASSERT(gid == getgid()); + notify_parent_process(); + + return 1; + } +#endif /* !_WIN32 */ + + if (strcmp(argv[1], "process_title_big_argv_helper") == 0) { + notify_parent_process(); + process_title_big_argv(); + return 0; + } + + return run_test(argv[1], 0, 1); +} diff --git a/external/src/libuv/test/runner-unix.c b/external/src/libuv/test/runner-unix.c new file mode 100644 index 0000000..a13648b --- /dev/null +++ b/external/src/libuv/test/runner-unix.c @@ -0,0 +1,445 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "runner-unix.h" +#include "runner.h" + +#include +#include /* uintptr_t */ + +#include +#include /* usleep */ +#include /* strdup */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +extern char** environ; + +static void closefd(int fd) { + if (close(fd) == 0 || errno == EINTR || errno == EINPROGRESS) + return; + + perror("close"); + abort(); +} + + +void notify_parent_process(void) { + char* arg; + int fd; + + arg = getenv("UV_TEST_RUNNER_FD"); + if (arg == NULL) + return; + + fd = atoi(arg); + assert(fd > STDERR_FILENO); + unsetenv("UV_TEST_RUNNER_FD"); + closefd(fd); +} + + +/* Do platform-specific initialization. */ +void platform_init(int argc, char **argv) { + /* Disable stdio output buffering. */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + signal(SIGPIPE, SIG_IGN); + snprintf(executable_path, sizeof(executable_path), "%s", argv[0]); +} + + +/* Invoke "argv[0] test-name [test-part]". Store process info in *p. Make sure + * that all stdio output of the processes is buffered up. */ +int process_start(char* name, char* part, process_info_t* p, int is_helper) { + FILE* stdout_file; + int stdout_fd; + const char* arg; + char* args[16]; + int pipefd[2]; + char fdstr[8]; + ssize_t rc; + int n; + pid_t pid; + + arg = getenv("UV_USE_VALGRIND"); + n = 0; + + /* Disable valgrind for helpers, it complains about helpers leaking memory. + * They're killed after the test and as such never get a chance to clean up. + */ + if (is_helper == 0 && arg != NULL && atoi(arg) != 0) { + args[n++] = "valgrind"; + args[n++] = "--quiet"; + args[n++] = "--leak-check=full"; + args[n++] = "--show-reachable=yes"; + args[n++] = "--error-exitcode=125"; + } + + args[n++] = executable_path; + args[n++] = name; + args[n++] = part; + args[n++] = NULL; + + stdout_file = tmpfile(); + stdout_fd = fileno(stdout_file); + if (!stdout_file) { + perror("tmpfile"); + return -1; + } + + if (is_helper) { + if (pipe(pipefd)) { + perror("pipe"); + return -1; + } + + snprintf(fdstr, sizeof(fdstr), "%d", pipefd[1]); + if (setenv("UV_TEST_RUNNER_FD", fdstr, /* overwrite */ 1)) { + perror("setenv"); + return -1; + } + } + + p->terminated = 0; + p->status = 0; + + pid = fork(); + + if (pid < 0) { + perror("fork"); + return -1; + } + + if (pid == 0) { + /* child */ + if (is_helper) + closefd(pipefd[0]); + dup2(stdout_fd, STDOUT_FILENO); + dup2(stdout_fd, STDERR_FILENO); + execve(args[0], args, environ); + perror("execve()"); + _exit(127); + } + + /* parent */ + p->pid = pid; + p->name = strdup(name); + p->stdout_file = stdout_file; + + if (!is_helper) + return 0; + + closefd(pipefd[1]); + unsetenv("UV_TEST_RUNNER_FD"); + + do + rc = read(pipefd[0], &n, 1); + while (rc == -1 && errno == EINTR); + + closefd(pipefd[0]); + + if (rc == -1) { + perror("read"); + return -1; + } + + if (rc > 0) { + fprintf(stderr, "EOF expected but got data.\n"); + return -1; + } + + return 0; +} + + +typedef struct { + int pipe[2]; + process_info_t* vec; + int n; +} dowait_args; + + +/* This function is run inside a pthread. We do this so that we can possibly + * timeout. + */ +static void* dowait(void* data) { + dowait_args* args = data; + + int i, r; + process_info_t* p; + + for (i = 0; i < args->n; i++) { + p = &args->vec[i]; + if (p->terminated) continue; + r = waitpid(p->pid, &p->status, 0); + if (r < 0) { + perror("waitpid"); + return NULL; + } + p->terminated = 1; + } + + if (args->pipe[1] >= 0) { + /* Write a character to the main thread to notify it about this. */ + ssize_t r; + + do + r = write(args->pipe[1], "", 1); + while (r == -1 && errno == EINTR); + } + + return NULL; +} + + +/* Wait for all `n` processes in `vec` to terminate. Time out after `timeout` + * msec, or never if timeout == -1. Return 0 if all processes are terminated, + * -1 on error, -2 on timeout. */ +int process_wait(process_info_t* vec, int n, int timeout) { + int i; + int r; + int retval; + process_info_t* p; + dowait_args args; + pthread_t tid; + pthread_attr_t attr; + unsigned int elapsed_ms; + struct timeval timebase; + struct timeval tv; + fd_set fds; + + args.vec = vec; + args.n = n; + args.pipe[0] = -1; + args.pipe[1] = -1; + + /* The simple case is where there is no timeout */ + if (timeout == -1) { + dowait(&args); + return 0; + } + + /* Hard case. Do the wait with a timeout. + * + * Assumption: we are the only ones making this call right now. Otherwise + * we'd need to lock vec. + */ + + r = pipe((int*)&(args.pipe)); + if (r) { + perror("pipe()"); + return -1; + } + + if (pthread_attr_init(&attr)) + abort(); + +#if defined(__MVS__) + if (pthread_attr_setstacksize(&attr, 1024 * 1024)) +#else + if (pthread_attr_setstacksize(&attr, 256 * 1024)) +#endif + abort(); + + r = pthread_create(&tid, &attr, dowait, &args); + + if (pthread_attr_destroy(&attr)) + abort(); + + if (r) { + perror("pthread_create()"); + retval = -1; + goto terminate; + } + + if (gettimeofday(&timebase, NULL)) + abort(); + + tv = timebase; + for (;;) { + /* Check that gettimeofday() doesn't jump back in time. */ + assert(tv.tv_sec > timebase.tv_sec || + (tv.tv_sec == timebase.tv_sec && tv.tv_usec >= timebase.tv_usec)); + + elapsed_ms = + (tv.tv_sec - timebase.tv_sec) * 1000 + + (tv.tv_usec / 1000) - + (timebase.tv_usec / 1000); + + r = 0; /* Timeout. */ + if (elapsed_ms >= (unsigned) timeout) + break; + + tv.tv_sec = (timeout - elapsed_ms) / 1000; + tv.tv_usec = (timeout - elapsed_ms) % 1000 * 1000; + + FD_ZERO(&fds); + FD_SET(args.pipe[0], &fds); + + r = select(args.pipe[0] + 1, &fds, NULL, NULL, &tv); + if (!(r == -1 && errno == EINTR)) + break; + + if (gettimeofday(&tv, NULL)) + abort(); + } + + if (r == -1) { + perror("select()"); + retval = -1; + + } else if (r) { + /* The thread completed successfully. */ + retval = 0; + + } else { + /* Timeout. Kill all the children. */ + for (i = 0; i < n; i++) { + p = &vec[i]; + kill(p->pid, SIGTERM); + } + retval = -2; + } + + if (pthread_join(tid, NULL)) + abort(); + +terminate: + close(args.pipe[0]); + close(args.pipe[1]); + return retval; +} + + +/* Returns the number of bytes in the stdio output buffer for process `p`. */ +long int process_output_size(process_info_t *p) { + /* Size of the p->stdout_file */ + struct stat buf; + + int r = fstat(fileno(p->stdout_file), &buf); + if (r < 0) { + return -1; + } + + return (long)buf.st_size; +} + + +/* Copy the contents of the stdio output buffer to `fd`. */ +int process_copy_output(process_info_t* p, FILE* stream) { + char buf[1024]; + int r; + + r = fseek(p->stdout_file, 0, SEEK_SET); + if (r < 0) { + perror("fseek"); + return -1; + } + + /* TODO: what if the line is longer than buf */ + while ((r = fread(buf, 1, sizeof(buf), p->stdout_file)) != 0) + print_lines(buf, r, stream); + + if (ferror(p->stdout_file)) { + perror("read"); + return -1; + } + + return 0; +} + + +/* Copy the last line of the stdio output buffer to `buffer` */ +int process_read_last_line(process_info_t *p, + char* buffer, + size_t buffer_len) { + char* ptr; + + int r = fseek(p->stdout_file, 0, SEEK_SET); + if (r < 0) { + perror("fseek"); + return -1; + } + + buffer[0] = '\0'; + + while (fgets(buffer, buffer_len, p->stdout_file) != NULL) { + for (ptr = buffer; *ptr && *ptr != '\r' && *ptr != '\n'; ptr++) + ; + *ptr = '\0'; + } + + if (ferror(p->stdout_file)) { + perror("read"); + buffer[0] = '\0'; + return -1; + } + return 0; +} + + +/* Return the name that was specified when `p` was started by process_start */ +char* process_get_name(process_info_t *p) { + return p->name; +} + + +/* Terminate process `p`. */ +int process_terminate(process_info_t *p) { + return kill(p->pid, SIGTERM); +} + + +/* Return the exit code of process p. On error, return -1. */ +int process_reap(process_info_t *p) { + if (WIFEXITED(p->status)) { + return WEXITSTATUS(p->status); + } else { + return p->status; /* ? */ + } +} + + +/* Clean up after terminating process `p` (e.g. free the output buffer etc.). */ +void process_cleanup(process_info_t *p) { + fclose(p->stdout_file); + free(p->name); +} + + +/* Move the console cursor one line up and back to the first column. */ +void rewind_cursor(void) { +#if defined(__MVS__) + fprintf(stderr, "\047[2K\r"); +#else + fprintf(stderr, "\033[2K\r"); +#endif +} diff --git a/external/src/libuv/test/runner-unix.h b/external/src/libuv/test/runner-unix.h new file mode 100644 index 0000000..e21847f --- /dev/null +++ b/external/src/libuv/test/runner-unix.h @@ -0,0 +1,36 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef TEST_RUNNER_UNIX_H +#define TEST_RUNNER_UNIX_H + +#include +#include /* FILE */ + +typedef struct { + FILE* stdout_file; + pid_t pid; + char* name; + int status; + int terminated; +} process_info_t; + +#endif /* TEST_RUNNER_UNIX_H */ diff --git a/external/src/libuv/test/runner-win.c b/external/src/libuv/test/runner-win.c new file mode 100644 index 0000000..8c2a00b --- /dev/null +++ b/external/src/libuv/test/runner-win.c @@ -0,0 +1,346 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#if !defined(__MINGW32__) +# include +#endif + + +#include "task.h" +#include "runner.h" + + +/* + * Define the stuff that MinGW doesn't have + */ +#ifndef GetFileSizeEx + WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE hFile, + PLARGE_INTEGER lpFileSize); +#endif + + +/* Do platform-specific initialization. */ +void platform_init(int argc, char **argv) { + /* Disable the "application crashed" popup. */ + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | + SEM_NOOPENFILEERRORBOX); +#if !defined(__MINGW32__) + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); + _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); +#endif + + _setmode(0, _O_BINARY); + _setmode(1, _O_BINARY); + _setmode(2, _O_BINARY); + +#ifdef _MSC_VER + _set_fmode(_O_BINARY); +#else + _fmode = _O_BINARY; +#endif + + /* Disable stdio output buffering. */ + setvbuf(stdout, NULL, _IONBF, 0); + setvbuf(stderr, NULL, _IONBF, 0); + + strcpy(executable_path, argv[0]); +} + + +int process_start(char *name, char *part, process_info_t *p, int is_helper) { + HANDLE file = INVALID_HANDLE_VALUE; + HANDLE nul = INVALID_HANDLE_VALUE; + WCHAR path[MAX_PATH], filename[MAX_PATH]; + WCHAR image[MAX_PATH + 1]; + WCHAR args[MAX_PATH * 2]; + STARTUPINFOW si; + PROCESS_INFORMATION pi; + DWORD result; + + if (!is_helper) { + /* Give the helpers time to settle. Race-y, fix this. */ + uv_sleep(250); + } + + if (GetTempPathW(sizeof(path) / sizeof(WCHAR), (WCHAR*)&path) == 0) + goto error; + if (GetTempFileNameW((WCHAR*)&path, L"uv", 0, (WCHAR*)&filename) == 0) + goto error; + + file = CreateFileW((WCHAR*)filename, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, + NULL); + if (file == INVALID_HANDLE_VALUE) + goto error; + + if (!SetHandleInformation(file, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) + goto error; + + nul = CreateFileA("nul", + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (nul == INVALID_HANDLE_VALUE) + goto error; + + if (!SetHandleInformation(nul, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT)) + goto error; + + result = GetModuleFileNameW(NULL, + (WCHAR*) &image, + sizeof(image) / sizeof(WCHAR)); + if (result == 0 || result == sizeof(image)) + goto error; + + if (part) { + if (_snwprintf((WCHAR*)args, + sizeof(args) / sizeof(WCHAR), + L"\"%s\" %S %S", + image, + name, + part) < 0) { + goto error; + } + } else { + if (_snwprintf((WCHAR*)args, + sizeof(args) / sizeof(WCHAR), + L"\"%s\" %S", + image, + name) < 0) { + goto error; + } + } + + memset((void*)&si, 0, sizeof(si)); + si.cb = sizeof(si); + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdInput = nul; + si.hStdOutput = file; + si.hStdError = file; + + if (!CreateProcessW(image, args, NULL, NULL, TRUE, + 0, NULL, NULL, &si, &pi)) + goto error; + + CloseHandle(pi.hThread); + + SetHandleInformation(nul, HANDLE_FLAG_INHERIT, 0); + SetHandleInformation(file, HANDLE_FLAG_INHERIT, 0); + + p->stdio_in = nul; + p->stdio_out = file; + p->process = pi.hProcess; + p->name = part; + + return 0; + +error: + if (file != INVALID_HANDLE_VALUE) + CloseHandle(file); + if (nul != INVALID_HANDLE_VALUE) + CloseHandle(nul); + + return -1; +} + + +/* Timeout is in msecs. Set timeout < 0 to never time out. Returns 0 when all + * processes are terminated, -2 on timeout. */ +int process_wait(process_info_t *vec, int n, int timeout) { + int i; + HANDLE handles[MAXIMUM_WAIT_OBJECTS]; + DWORD timeout_api, result; + + /* If there's nothing to wait for, return immediately. */ + if (n == 0) + return 0; + + ASSERT(n <= MAXIMUM_WAIT_OBJECTS); + + for (i = 0; i < n; i++) + handles[i] = vec[i].process; + + if (timeout >= 0) { + timeout_api = (DWORD)timeout; + } else { + timeout_api = INFINITE; + } + + result = WaitForMultipleObjects(n, handles, TRUE, timeout_api); + + if (result < WAIT_OBJECT_0 + n) { + /* All processes are terminated. */ + return 0; + } + if (result == WAIT_TIMEOUT) { + return -2; + } + return -1; +} + + +long int process_output_size(process_info_t *p) { + LARGE_INTEGER size; + if (!GetFileSizeEx(p->stdio_out, &size)) + return -1; + return (long int)size.QuadPart; +} + + +int process_copy_output(process_info_t* p, FILE* stream) { + char buf[1024]; + int fd, r; + + fd = _open_osfhandle((intptr_t)p->stdio_out, _O_RDONLY | _O_TEXT); + if (fd == -1) + return -1; + + r = _lseek(fd, 0, SEEK_SET); + if (r < 0) + return -1; + + while ((r = _read(fd, buf, sizeof(buf))) != 0) + print_lines(buf, r, stream); + + _close(fd); + return 0; +} + + +int process_read_last_line(process_info_t *p, + char * buffer, + size_t buffer_len) { + DWORD size; + DWORD read; + DWORD start; + OVERLAPPED overlapped; + + ASSERT(buffer_len > 0); + + size = GetFileSize(p->stdio_out, NULL); + if (size == INVALID_FILE_SIZE) + return -1; + + if (size == 0) { + buffer[0] = '\0'; + return 1; + } + + memset(&overlapped, 0, sizeof overlapped); + if (size >= buffer_len) + overlapped.Offset = size - buffer_len - 1; + + if (!ReadFile(p->stdio_out, buffer, buffer_len - 1, &read, &overlapped)) + return -1; + + start = read; + while (start-- > 0) { + if (buffer[start] == '\n' || buffer[start] == '\r') + break; + } + + if (start > 0) + memmove(buffer, buffer + start, read - start); + + buffer[read - start] = '\0'; + + return 0; +} + + +char* process_get_name(process_info_t *p) { + return p->name; +} + + +int process_terminate(process_info_t *p) { + if (!TerminateProcess(p->process, 1)) + return -1; + return 0; +} + + +int process_reap(process_info_t *p) { + DWORD exitCode; + if (!GetExitCodeProcess(p->process, &exitCode)) + return -1; + return (int)exitCode; +} + + +void process_cleanup(process_info_t *p) { + CloseHandle(p->process); + CloseHandle(p->stdio_in); +} + + +static int clear_line(void) { + HANDLE handle; + CONSOLE_SCREEN_BUFFER_INFO info; + COORD coord; + DWORD written; + + handle = (HANDLE)_get_osfhandle(fileno(stderr)); + if (handle == INVALID_HANDLE_VALUE) + return -1; + + if (!GetConsoleScreenBufferInfo(handle, &info)) + return -1; + + coord = info.dwCursorPosition; + if (coord.Y <= 0) + return -1; + + coord.X = 0; + + if (!SetConsoleCursorPosition(handle, coord)) + return -1; + + if (!FillConsoleOutputCharacterW(handle, + 0x20, + info.dwSize.X, + coord, + &written)) { + return -1; + } + + return 0; +} + + +void rewind_cursor() { + if (clear_line() == -1) { + /* If clear_line fails (stdout is not a console), print a newline. */ + fprintf(stderr, "\n"); + } +} diff --git a/external/src/libuv/test/runner-win.h b/external/src/libuv/test/runner-win.h new file mode 100644 index 0000000..975eed7 --- /dev/null +++ b/external/src/libuv/test/runner-win.h @@ -0,0 +1,41 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* Don't complain about write(), fileno() etc. being deprecated. */ +#ifdef _MSC_VER +#pragma warning(disable : 4996) +#endif + + +#include +#include +#include + +#if !defined(snprintf) && defined(_MSC_VER) && _MSC_VER < 1900 +extern int snprintf(char*, size_t, const char*, ...); +#endif + +typedef struct { + HANDLE process; + HANDLE stdio_in; + HANDLE stdio_out; + char *name; +} process_info_t; diff --git a/external/src/libuv/test/runner.c b/external/src/libuv/test/runner.c new file mode 100644 index 0000000..7891082 --- /dev/null +++ b/external/src/libuv/test/runner.c @@ -0,0 +1,453 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "runner.h" +#include "task.h" +#include "uv.h" + +char executable_path[sizeof(executable_path)]; + + +static int compare_task(const void* va, const void* vb) { + const task_entry_t* a = va; + const task_entry_t* b = vb; + return strcmp(a->task_name, b->task_name); +} + + +const char* fmt(double d) { + static char buf[1024]; + static char* p; + uint64_t v; + + if (p == NULL) + p = buf; + + p += 31; + + if (p >= buf + sizeof(buf)) + return ""; + + v = (uint64_t) d; + +#if 0 /* works but we don't care about fractional precision */ + if (d - v >= 0.01) { + *--p = '0' + (uint64_t) (d * 100) % 10; + *--p = '0' + (uint64_t) (d * 10) % 10; + *--p = '.'; + } +#endif + + if (v == 0) + *--p = '0'; + + while (v) { + if (v) *--p = '0' + (v % 10), v /= 10; + if (v) *--p = '0' + (v % 10), v /= 10; + if (v) *--p = '0' + (v % 10), v /= 10; + if (v) *--p = ','; + } + + return p; +} + + +int run_tests(int benchmark_output) { + int actual; + int total; + int passed; + int failed; + int skipped; + int current; + int test_result; + int skip; + task_entry_t* task; + + /* Count the number of tests. */ + actual = 0; + total = 0; + for (task = TASKS; task->main; task++, actual++) { + if (!task->is_helper) { + total++; + } + } + + /* Keep platform_output first. */ + skip = (actual > 0 && 0 == strcmp(TASKS[0].task_name, "platform_output")); + qsort(TASKS + skip, actual - skip, sizeof(TASKS[0]), compare_task); + + fprintf(stdout, "1..%d\n", total); + fflush(stdout); + + /* Run all tests. */ + passed = 0; + failed = 0; + skipped = 0; + current = 1; + for (task = TASKS; task->main; task++) { + if (task->is_helper) { + continue; + } + + test_result = run_test(task->task_name, benchmark_output, current); + switch (test_result) { + case TEST_OK: passed++; break; + case TEST_SKIP: skipped++; break; + default: failed++; + } + current++; + } + + return failed; +} + + +void log_tap_result(int test_count, + const char* test, + int status, + process_info_t* process) { + const char* result; + const char* directive; + char reason[1024]; + int reason_length; + + switch (status) { + case TEST_OK: + result = "ok"; + directive = ""; + break; + case TEST_SKIP: + result = "ok"; + directive = " # SKIP "; + break; + default: + result = "not ok"; + directive = ""; + } + + if (status == TEST_SKIP && process_output_size(process) > 0) { + process_read_last_line(process, reason, sizeof reason); + reason_length = strlen(reason); + if (reason_length > 0 && reason[reason_length - 1] == '\n') + reason[reason_length - 1] = '\0'; + } else { + reason[0] = '\0'; + } + + fprintf(stdout, "%s %d - %s%s%s\n", result, test_count, test, directive, reason); + fflush(stdout); +} + + +int run_test(const char* test, + int benchmark_output, + int test_count) { + char errmsg[1024] = ""; + process_info_t processes[1024]; + process_info_t *main_proc; + task_entry_t* task; + int timeout_multiplier; + int process_count; + int result; + int status; + int i; + + status = 255; + main_proc = NULL; + process_count = 0; + +#ifndef _WIN32 + /* Clean up stale socket from previous run. */ + remove(TEST_PIPENAME); + remove(TEST_PIPENAME_2); + remove(TEST_PIPENAME_3); +#endif + + /* If it's a helper the user asks for, start it directly. */ + for (task = TASKS; task->main; task++) { + if (task->is_helper && strcmp(test, task->process_name) == 0) { + return task->main(); + } + } + + /* Start the helpers first. */ + for (task = TASKS; task->main; task++) { + if (strcmp(test, task->task_name) != 0) { + continue; + } + + /* Skip the test itself. */ + if (!task->is_helper) { + continue; + } + + if (process_start(task->task_name, + task->process_name, + &processes[process_count], + 1 /* is_helper */) == -1) { + snprintf(errmsg, + sizeof errmsg, + "Process `%s` failed to start.", + task->process_name); + goto out; + } + + process_count++; + } + + /* Now start the test itself. */ + for (task = TASKS; task->main; task++) { + if (strcmp(test, task->task_name) != 0) { + continue; + } + + if (task->is_helper) { + continue; + } + + if (process_start(task->task_name, + task->process_name, + &processes[process_count], + 0 /* !is_helper */) == -1) { + snprintf(errmsg, + sizeof errmsg, + "Process `%s` failed to start.", + task->process_name); + goto out; + } + + main_proc = &processes[process_count]; + process_count++; + break; + } + + if (main_proc == NULL) { + snprintf(errmsg, + sizeof errmsg, + "No test with that name: %s", + test); + goto out; + } + + timeout_multiplier = 1; +#ifndef _WIN32 + do { + const char* var; + + var = getenv("UV_TEST_TIMEOUT_MULTIPLIER"); + if (var == NULL) + break; + + timeout_multiplier = atoi(var); + if (timeout_multiplier <= 0) + timeout_multiplier = 1; + } while (0); +#endif + + result = process_wait(main_proc, 1, task->timeout * timeout_multiplier); + if (result == -1) { + FATAL("process_wait failed"); + } else if (result == -2) { + /* Don't have to clean up the process, process_wait() has killed it. */ + snprintf(errmsg, + sizeof errmsg, + "timeout"); + goto out; + } + + status = process_reap(main_proc); + if (status != TEST_OK) { + snprintf(errmsg, + sizeof errmsg, + "exit code %d", + status); + goto out; + } + + if (benchmark_output) { + /* Give the helpers time to clean up their act. */ + uv_sleep(1000); + } + +out: + /* Reap running processes except the main process, it's already dead. */ + for (i = 0; i < process_count - 1; i++) { + process_terminate(&processes[i]); + } + + if (process_count > 0 && + process_wait(processes, process_count - 1, -1) < 0) { + FATAL("process_wait failed"); + } + + log_tap_result(test_count, test, status, &processes[i]); + + /* Show error and output from processes if the test failed. */ + if ((status != TEST_OK && status != TEST_SKIP) || task->show_output) { + if (strlen(errmsg) > 0) + fprintf(stdout, "# %s\n", errmsg); + fprintf(stdout, "# "); + fflush(stdout); + + for (i = 0; i < process_count; i++) { + switch (process_output_size(&processes[i])) { + case -1: + fprintf(stdout, "Output from process `%s`: (unavailable)\n", + process_get_name(&processes[i])); + fflush(stdout); + break; + + case 0: + fprintf(stdout, "Output from process `%s`: (no output)\n", + process_get_name(&processes[i])); + fflush(stdout); + break; + + default: + fprintf(stdout, "Output from process `%s`:\n", process_get_name(&processes[i])); + fflush(stdout); + process_copy_output(&processes[i], stdout); + break; + } + } + + /* In benchmark mode show concise output from the main process. */ + } else if (benchmark_output) { + switch (process_output_size(main_proc)) { + case -1: + fprintf(stdout, "%s: (unavailable)\n", test); + fflush(stdout); + break; + + case 0: + fprintf(stdout, "%s: (no output)\n", test); + fflush(stdout); + break; + + default: + for (i = 0; i < process_count; i++) { + process_copy_output(&processes[i], stdout); + } + break; + } + } + + /* Clean up all process handles. */ + for (i = 0; i < process_count; i++) { + process_cleanup(&processes[i]); + } + + return status; +} + + +/* Returns the status code of the task part + * or 255 if no matching task was not found. + */ +int run_test_part(const char* test, const char* part) { + task_entry_t* task; + int r; + + for (task = TASKS; task->main; task++) { + if (strcmp(test, task->task_name) == 0 && + strcmp(part, task->process_name) == 0) { + r = task->main(); + return r; + } + } + + fprintf(stdout, "No test part with that name: %s:%s\n", test, part); + fflush(stdout); + return 255; +} + + + +static int find_helpers(const task_entry_t* task, + const task_entry_t** helpers) { + const task_entry_t* helper; + int n_helpers; + + for (n_helpers = 0, helper = TASKS; helper->main; helper++) { + if (helper->is_helper && strcmp(helper->task_name, task->task_name) == 0) { + *helpers++ = helper; + n_helpers++; + } + } + + return n_helpers; +} + + +void print_tests(FILE* stream) { + const task_entry_t* helpers[1024]; + const task_entry_t* task; + int n_helpers; + int n_tasks; + int i; + + for (n_tasks = 0, task = TASKS; task->main; n_tasks++, task++); + qsort(TASKS, n_tasks, sizeof(TASKS[0]), compare_task); + + for (task = TASKS; task->main; task++) { + if (task->is_helper) { + continue; + } + + n_helpers = find_helpers(task, helpers); + if (n_helpers) { + printf("%-25s (helpers:", task->task_name); + for (i = 0; i < n_helpers; i++) { + printf(" %s", helpers[i]->process_name); + } + printf(")\n"); + } else { + printf("%s\n", task->task_name); + } + } +} + + +void print_lines(const char* buffer, size_t size, FILE* stream) { + const char* start; + const char* end; + + start = buffer; + while ((end = memchr(start, '\n', &buffer[size] - start))) { + fputs("# ", stream); + fwrite(start, 1, (int)(end - start), stream); + fputs("\n", stream); + fflush(stream); + start = end + 1; + } + + end = &buffer[size]; + if (start < end) { + fputs("# ", stream); + fwrite(start, 1, (int)(end - start), stream); + fputs("\n", stream); + fflush(stream); + } +} diff --git a/external/src/libuv/test/runner.h b/external/src/libuv/test/runner.h new file mode 100644 index 0000000..6801564 --- /dev/null +++ b/external/src/libuv/test/runner.h @@ -0,0 +1,172 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef RUNNER_H_ +#define RUNNER_H_ + +#include /* PATH_MAX */ +#include /* FILE */ + + +/* + * The maximum number of processes (main + helpers) that a test / benchmark + * can have. + */ +#define MAX_PROCESSES 8 + + +/* + * Struct to store both tests and to define helper processes for tasks. + */ +typedef struct { + char *task_name; + char *process_name; + int (*main)(void); + int is_helper; + int show_output; + + /* + * The time in milliseconds after which a single test or benchmark times out. + */ + int timeout; +} task_entry_t, bench_entry_t; + + +/* + * Macros used by test-list.h and benchmark-list.h. + */ +#define TASK_LIST_START \ + task_entry_t TASKS[] = { + +#define TASK_LIST_END \ + { 0, 0, 0, 0, 0, 0 } \ + }; + +#define TEST_DECLARE(name) \ + int run_test_##name(void); + +#define TEST_ENTRY(name) \ + { #name, #name, &run_test_##name, 0, 0, 5000 }, + +#define TEST_ENTRY_CUSTOM(name, is_helper, show_output, timeout) \ + { #name, #name, &run_test_##name, is_helper, show_output, timeout }, + +#define BENCHMARK_DECLARE(name) \ + int run_benchmark_##name(void); + +#define BENCHMARK_ENTRY(name) \ + { #name, #name, &run_benchmark_##name, 0, 0, 60000 }, + +#define HELPER_DECLARE(name) \ + int run_helper_##name(void); + +#define HELPER_ENTRY(task_name, name) \ + { #task_name, #name, &run_helper_##name, 1, 0, 0 }, + +#define TEST_HELPER HELPER_ENTRY +#define BENCHMARK_HELPER HELPER_ENTRY + +extern char executable_path[4096]; + +/* + * Include platform-dependent definitions + */ +#ifdef _WIN32 +# include "runner-win.h" +#else +# include "runner-unix.h" +#endif + + +/* The array that is filled by test-list.h or benchmark-list.h */ +extern task_entry_t TASKS[]; + +/* + * Run all tests. + */ +int run_tests(int benchmark_output); + +/* + * Run a single test. Starts up any helpers. + */ +int run_test(const char* test, + int benchmark_output, + int test_count); + +/* + * Run a test part, i.e. the test or one of its helpers. + */ +int run_test_part(const char* test, const char* part); + + +/* + * Print tests in sorted order to `stream`. Used by `./run-tests --list`. + */ +void print_tests(FILE* stream); + +/* Print lines in |buffer| as TAP diagnostics to |stream|. */ +void print_lines(const char* buffer, size_t size, FILE* stream); + +/* + * Stuff that should be implemented by test-runner-.h + * All functions return 0 on success, -1 on failure, unless specified + * otherwise. + */ + +/* Do platform-specific initialization. */ +void platform_init(int argc, char** argv); + +/* Invoke "argv[0] test-name [test-part]". Store process info in *p. Make sure + * that all stdio output of the processes is buffered up. */ +int process_start(char *name, char* part, process_info_t *p, int is_helper); + +/* Wait for all `n` processes in `vec` to terminate. Time out after `timeout` + * msec, or never if timeout == -1. Return 0 if all processes are terminated, + * -1 on error, -2 on timeout. */ +int process_wait(process_info_t *vec, int n, int timeout); + +/* Returns the number of bytes in the stdio output buffer for process `p`. */ +long int process_output_size(process_info_t *p); + +/* Copy the contents of the stdio output buffer to `stream`. */ +int process_copy_output(process_info_t* p, FILE* stream); + +/* Copy the last line of the stdio output buffer to `buffer` */ +int process_read_last_line(process_info_t *p, + char * buffer, + size_t buffer_len); + +/* Return the name that was specified when `p` was started by process_start */ +char* process_get_name(process_info_t *p); + +/* Terminate process `p`. */ +int process_terminate(process_info_t *p); + +/* Return the exit code of process p. On error, return -1. */ +int process_reap(process_info_t *p); + +/* Clean up after terminating process `p` (e.g. free the output buffer etc.). */ +void process_cleanup(process_info_t *p); + +/* Move the console cursor one line up and back to the first column. */ +void rewind_cursor(void); + +#endif /* RUNNER_H_ */ diff --git a/external/src/libuv/test/task.h b/external/src/libuv/test/task.h new file mode 100644 index 0000000..a02c893 --- /dev/null +++ b/external/src/libuv/test/task.h @@ -0,0 +1,378 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef TASK_H_ +#define TASK_H_ + +#include "uv.h" + +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) && _MSC_VER < 1600 +# include "uv/stdint-msvc2008.h" +#else +# include +#endif + +#if !defined(_WIN32) +# include +# include /* setrlimit() */ +#endif + +#ifdef __clang__ +# pragma clang diagnostic ignored "-Wvariadic-macros" +# pragma clang diagnostic ignored "-Wc99-extensions" +#endif + +#ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wvariadic-macros" +#endif + +#define TEST_PORT 9123 +#define TEST_PORT_2 9124 +#define TEST_PORT_3 9125 + +#ifdef _WIN32 +# define TEST_PIPENAME "\\\\?\\pipe\\uv-test" +# define TEST_PIPENAME_2 "\\\\?\\pipe\\uv-test2" +# define TEST_PIPENAME_3 "\\\\?\\pipe\\uv-test3" +#else +# define TEST_PIPENAME "/tmp/uv-test-sock" +# define TEST_PIPENAME_2 "/tmp/uv-test-sock2" +# define TEST_PIPENAME_3 "/tmp/uv-test-sock3" +#endif + +#ifdef _WIN32 +# include +# ifndef S_IRUSR +# define S_IRUSR _S_IREAD +# endif +# ifndef S_IWUSR +# define S_IWUSR _S_IWRITE +# endif +#endif + +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + +#define container_of(ptr, type, member) \ + ((type *) ((char *) (ptr) - offsetof(type, member))) + +typedef enum { + TCP = 0, + UDP, + PIPE +} stream_type; + +/* Die with fatal error. */ +#define FATAL(msg) \ + do { \ + fprintf(stderr, \ + "Fatal error in %s on line %d: %s\n", \ + __FILE__, \ + __LINE__, \ + msg); \ + fflush(stderr); \ + abort(); \ + } while (0) + +/* Have our own assert, so we are sure it does not get optimized away in + * a release build. + */ +#define ASSERT(expr) \ + do { \ + if (!(expr)) { \ + fprintf(stderr, \ + "Assertion failed in %s on line %d: %s\n", \ + __FILE__, \ + __LINE__, \ + #expr); \ + abort(); \ + } \ + } while (0) + +#define ASSERT_BASE(a, operator, b, type, conv) \ + do { \ + volatile type eval_a = (type) (a); \ + volatile type eval_b = (type) (b); \ + if (!(eval_a operator eval_b)) { \ + fprintf(stderr, \ + "Assertion failed in %s on line %d: `%s %s %s` " \ + "(%"conv" %s %"conv")\n", \ + __FILE__, \ + __LINE__, \ + #a, \ + #operator, \ + #b, \ + eval_a, \ + #operator, \ + eval_b); \ + abort(); \ + } \ + } while (0) + +#define ASSERT_BASE_STR(expr, a, operator, b, type, conv) \ + do { \ + if (!(expr)) { \ + fprintf(stderr, \ + "Assertion failed in %s on line %d: `%s %s %s` " \ + "(%"conv" %s %"conv")\n", \ + __FILE__, \ + __LINE__, \ + #a, \ + #operator, \ + #b, \ + (type)a, \ + #operator, \ + (type)b); \ + abort(); \ + } \ + } while (0) + +#define ASSERT_BASE_LEN(expr, a, operator, b, conv, len) \ + do { \ + if (!(expr)) { \ + fprintf(stderr, \ + "Assertion failed in %s on line %d: `%s %s %s` " \ + "(%.*"#conv" %s %.*"#conv")\n", \ + __FILE__, \ + __LINE__, \ + #a, \ + #operator, \ + #b, \ + (int)len, \ + a, \ + #operator, \ + (int)len, \ + b); \ + abort(); \ + } \ + } while (0) + +#define ASSERT_BASE_HEX(expr, a, operator, b, size) \ + do { \ + if (!(expr)) { \ + int i; \ + unsigned char* a_ = (unsigned char*)a; \ + unsigned char* b_ = (unsigned char*)b; \ + fprintf(stderr, \ + "Assertion failed in %s on line %d: `%s %s %s` (", \ + __FILE__, \ + __LINE__, \ + #a, \ + #operator, \ + #b); \ + for (i = 0; i < size; ++i) { \ + if (i > 0) fprintf(stderr, ":"); \ + fprintf(stderr, "%02X", a_[i]); \ + } \ + fprintf(stderr, " %s ", #operator); \ + for (i = 0; i < size; ++i) { \ + if (i > 0) fprintf(stderr, ":"); \ + fprintf(stderr, "%02X", b_[i]); \ + } \ + fprintf(stderr, ")\n"); \ + abort(); \ + } \ + } while (0) + +#define ASSERT_EQ(a, b) ASSERT_BASE(a, ==, b, int64_t, PRId64) +#define ASSERT_GE(a, b) ASSERT_BASE(a, >=, b, int64_t, PRId64) +#define ASSERT_GT(a, b) ASSERT_BASE(a, >, b, int64_t, PRId64) +#define ASSERT_LE(a, b) ASSERT_BASE(a, <=, b, int64_t, PRId64) +#define ASSERT_LT(a, b) ASSERT_BASE(a, <, b, int64_t, PRId64) +#define ASSERT_NE(a, b) ASSERT_BASE(a, !=, b, int64_t, PRId64) + +#define ASSERT_UINT64_EQ(a, b) ASSERT_BASE(a, ==, b, uint64_t, PRIu64) +#define ASSERT_UINT64_GE(a, b) ASSERT_BASE(a, >=, b, uint64_t, PRIu64) +#define ASSERT_UINT64_GT(a, b) ASSERT_BASE(a, >, b, uint64_t, PRIu64) +#define ASSERT_UINT64_LE(a, b) ASSERT_BASE(a, <=, b, uint64_t, PRIu64) +#define ASSERT_UINT64_LT(a, b) ASSERT_BASE(a, <, b, uint64_t, PRIu64) +#define ASSERT_UINT64_NE(a, b) ASSERT_BASE(a, !=, b, uint64_t, PRIu64) + +#define ASSERT_DOUBLE_EQ(a, b) ASSERT_BASE(a, ==, b, double, "f") +#define ASSERT_DOUBLE_GE(a, b) ASSERT_BASE(a, >=, b, double, "f") +#define ASSERT_DOUBLE_GT(a, b) ASSERT_BASE(a, >, b, double, "f") +#define ASSERT_DOUBLE_LE(a, b) ASSERT_BASE(a, <=, b, double, "f") +#define ASSERT_DOUBLE_LT(a, b) ASSERT_BASE(a, <, b, double, "f") +#define ASSERT_DOUBLE_NE(a, b) ASSERT_BASE(a, !=, b, double, "f") + +#define ASSERT_STR_EQ(a, b) \ + ASSERT_BASE_STR(strcmp(a, b) == 0, a, == , b, char*, "s") + +#define ASSERT_STR_NE(a, b) \ + ASSERT_BASE_STR(strcmp(a, b) != 0, a, !=, b, char*, "s") + +#define ASSERT_MEM_EQ(a, b, size) \ + ASSERT_BASE_LEN(memcmp(a, b, size) == 0, a, ==, b, s, size) + +#define ASSERT_MEM_NE(a, b, size) \ + ASSERT_BASE_LEN(memcmp(a, b, size) != 0, a, !=, b, s, size) + +#define ASSERT_MEM_HEX_EQ(a, b, size) \ + ASSERT_BASE_HEX(memcmp(a, b, size) == 0, a, ==, b, size) + +#define ASSERT_MEM_HEX_NE(a, b, size) \ + ASSERT_BASE_HEX(memcmp(a, b, size) != 0, a, !=, b, size) + +#define ASSERT_NULL(a) \ + ASSERT_BASE(a, ==, NULL, void*, "p") + +#define ASSERT_NOT_NULL(a) \ + ASSERT_BASE(a, !=, NULL, void*, "p") + +#define ASSERT_PTR_EQ(a, b) \ + ASSERT_BASE(a, ==, b, void*, "p") + +#define ASSERT_PTR_NE(a, b) \ + ASSERT_BASE(a, !=, b, void*, "p") + +/* This macro cleans up the main loop. This is used to avoid valgrind + * warnings about memory being "leaked" by the main event loop. + */ +#define MAKE_VALGRIND_HAPPY() \ + do { \ + close_loop(uv_default_loop()); \ + ASSERT(0 == uv_loop_close(uv_default_loop())); \ + uv_library_shutdown(); \ + } while (0) + +/* Just sugar for wrapping the main() for a task or helper. */ +#define TEST_IMPL(name) \ + int run_test_##name(void); \ + int run_test_##name(void) + +#define BENCHMARK_IMPL(name) \ + int run_benchmark_##name(void); \ + int run_benchmark_##name(void) + +#define HELPER_IMPL(name) \ + int run_helper_##name(void); \ + int run_helper_##name(void) + +/* Format big numbers nicely. WARNING: leaks memory. */ +const char* fmt(double d); + +/* Reserved test exit codes. */ +enum test_status { + TEST_OK = 0, + TEST_SKIP +}; + +#define RETURN_OK() \ + do { \ + return TEST_OK; \ + } while (0) + +#define RETURN_SKIP(explanation) \ + do { \ + fprintf(stderr, "%s\n", explanation); \ + fflush(stderr); \ + return TEST_SKIP; \ + } while (0) + +#if !defined(_WIN32) + +# define TEST_FILE_LIMIT(num) \ + do { \ + struct rlimit lim; \ + lim.rlim_cur = (num); \ + lim.rlim_max = lim.rlim_cur; \ + if (setrlimit(RLIMIT_NOFILE, &lim)) \ + RETURN_SKIP("File descriptor limit too low."); \ + } while (0) + +#else /* defined(_WIN32) */ + +# define TEST_FILE_LIMIT(num) do {} while (0) + +#endif + +#if !defined(snprintf) && defined(_MSC_VER) && _MSC_VER < 1900 +extern int snprintf(char*, size_t, const char*, ...); +#endif + +#if defined(__clang__) || \ + defined(__GNUC__) || \ + defined(__INTEL_COMPILER) +# define UNUSED __attribute__((unused)) +#else +# define UNUSED +#endif + +#if defined(_WIN32) +#define notify_parent_process() ((void) 0) +#else +extern void notify_parent_process(void); +#endif + +/* Fully close a loop */ +static void close_walk_cb(uv_handle_t* handle, void* arg) { + if (!uv_is_closing(handle)) + uv_close(handle, NULL); +} + +UNUSED static void close_loop(uv_loop_t* loop) { + uv_walk(loop, close_walk_cb, NULL); + uv_run(loop, UV_RUN_DEFAULT); +} + +UNUSED static int can_ipv6(void) { + uv_interface_address_t* addr; + int supported; + int count; + int i; + + if (uv_interface_addresses(&addr, &count)) + return 0; /* Assume no IPv6 support on failure. */ + + supported = 0; + for (i = 0; supported == 0 && i < count; i += 1) + supported = (AF_INET6 == addr[i].address.address6.sin6_family); + + uv_free_interface_addresses(addr, count); + return supported; +} + +#if defined(__CYGWIN__) || defined(__MSYS__) || defined(__PASE__) +# define NO_FS_EVENTS "Filesystem watching not supported on this platform." +#endif + +#if defined(__MSYS__) +# define NO_SEND_HANDLE_ON_PIPE \ + "MSYS2 runtime does not support sending handles on pipes." +#elif defined(__CYGWIN__) +# define NO_SEND_HANDLE_ON_PIPE \ + "Cygwin runtime does not support sending handles on pipes." +#endif + +#if defined(__MSYS__) +# define NO_SELF_CONNECT \ + "MSYS2 runtime hangs on listen+connect in same process." +#elif defined(__CYGWIN__) +# define NO_SELF_CONNECT \ + "Cygwin runtime hangs on listen+connect in same process." +#endif + +#endif /* TASK_H_ */ diff --git a/external/src/libuv/test/test-active.c b/external/src/libuv/test/test-active.c new file mode 100644 index 0000000..3843895 --- /dev/null +++ b/external/src/libuv/test/test-active.c @@ -0,0 +1,84 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + + +static int close_cb_called = 0; + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +static void timer_cb(uv_timer_t* handle) { + ASSERT(0 && "timer_cb should not have been called"); +} + + +TEST_IMPL(active) { + int r; + uv_timer_t timer; + + r = uv_timer_init(uv_default_loop(), &timer); + ASSERT(r == 0); + + /* uv_is_active() and uv_is_closing() should always return either 0 or 1. */ + ASSERT(0 == uv_is_active((uv_handle_t*) &timer)); + ASSERT(0 == uv_is_closing((uv_handle_t*) &timer)); + + r = uv_timer_start(&timer, timer_cb, 1000, 0); + ASSERT(r == 0); + + ASSERT(1 == uv_is_active((uv_handle_t*) &timer)); + ASSERT(0 == uv_is_closing((uv_handle_t*) &timer)); + + r = uv_timer_stop(&timer); + ASSERT(r == 0); + + ASSERT(0 == uv_is_active((uv_handle_t*) &timer)); + ASSERT(0 == uv_is_closing((uv_handle_t*) &timer)); + + r = uv_timer_start(&timer, timer_cb, 1000, 0); + ASSERT(r == 0); + + ASSERT(1 == uv_is_active((uv_handle_t*) &timer)); + ASSERT(0 == uv_is_closing((uv_handle_t*) &timer)); + + uv_close((uv_handle_t*) &timer, close_cb); + + ASSERT(0 == uv_is_active((uv_handle_t*) &timer)); + ASSERT(1 == uv_is_closing((uv_handle_t*) &timer)); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-async-null-cb.c b/external/src/libuv/test/test-async-null-cb.c new file mode 100644 index 0000000..52652d9 --- /dev/null +++ b/external/src/libuv/test/test-async-null-cb.c @@ -0,0 +1,64 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +static uv_async_t async_handle; +static uv_check_t check_handle; +static int check_cb_called; +static uv_thread_t thread; + + +static void thread_cb(void* dummy) { + (void) &dummy; + uv_async_send(&async_handle); +} + + +static void check_cb(uv_check_t* handle) { + ASSERT(check_cb_called == 0); + uv_close((uv_handle_t*) &async_handle, NULL); + uv_close((uv_handle_t*) &check_handle, NULL); + check_cb_called++; +} + + +TEST_IMPL(async_null_cb) { + /* + * Fill async_handle with garbage values. + * uv_async_init() should properly initialize struct fields regardless of + * initial values. + * This is added to verify paddings between fields do not affect behavior. + */ + memset(&async_handle, 0xff, sizeof(async_handle)); + + ASSERT(0 == uv_async_init(uv_default_loop(), &async_handle, NULL)); + ASSERT(0 == uv_check_init(uv_default_loop(), &check_handle)); + ASSERT(0 == uv_check_start(&check_handle, check_cb)); + ASSERT(0 == uv_thread_create(&thread, thread_cb, NULL)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(0 == uv_thread_join(&thread)); + ASSERT(1 == check_cb_called); + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-async.c b/external/src/libuv/test/test-async.c new file mode 100644 index 0000000..619be62 --- /dev/null +++ b/external/src/libuv/test/test-async.c @@ -0,0 +1,134 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + +static uv_thread_t thread; +static uv_mutex_t mutex; + +static uv_prepare_t prepare; +static uv_async_t async; + +static volatile int async_cb_called; +static int prepare_cb_called; +static int close_cb_called; + + +static void thread_cb(void *arg) { + int n; + int r; + + for (;;) { + uv_mutex_lock(&mutex); + n = async_cb_called; + uv_mutex_unlock(&mutex); + + if (n == 3) { + break; + } + + r = uv_async_send(&async); + ASSERT(r == 0); + + /* Work around a bug in Valgrind. + * + * Valgrind runs threads not in parallel but sequentially, i.e. one after + * the other. It also doesn't preempt them, instead it depends on threads + * yielding voluntarily by making a syscall. + * + * That never happens here: the pipe that is associated with the async + * handle is written to once but that's too early for Valgrind's scheduler + * to kick in. Afterwards, the thread busy-loops, starving the main thread. + * Therefore, we yield. + * + * This behavior has been observed with Valgrind 3.7.0 and 3.9.0. + */ + uv_sleep(0); + } +} + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +static void async_cb(uv_async_t* handle) { + int n; + + ASSERT(handle == &async); + + uv_mutex_lock(&mutex); + n = ++async_cb_called; + uv_mutex_unlock(&mutex); + + if (n == 3) { + uv_close((uv_handle_t*)&async, close_cb); + uv_close((uv_handle_t*)&prepare, close_cb); + } +} + + +static void prepare_cb(uv_prepare_t* handle) { + int r; + + ASSERT(handle == &prepare); + + if (prepare_cb_called++) + return; + + r = uv_thread_create(&thread, thread_cb, NULL); + ASSERT(r == 0); + uv_mutex_unlock(&mutex); +} + + +TEST_IMPL(async) { + int r; + + r = uv_mutex_init(&mutex); + ASSERT(r == 0); + uv_mutex_lock(&mutex); + + r = uv_prepare_init(uv_default_loop(), &prepare); + ASSERT(r == 0); + r = uv_prepare_start(&prepare, prepare_cb); + ASSERT(r == 0); + + r = uv_async_init(uv_default_loop(), &async, async_cb); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(prepare_cb_called > 0); + ASSERT(async_cb_called == 3); + ASSERT(close_cb_called == 2); + + ASSERT(0 == uv_thread_join(&thread)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-barrier.c b/external/src/libuv/test/test-barrier.c new file mode 100644 index 0000000..89858db --- /dev/null +++ b/external/src/libuv/test/test-barrier.c @@ -0,0 +1,148 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +typedef struct { + uv_barrier_t barrier; + int delay; + volatile int posted; + int main_barrier_wait_rval; + int worker_barrier_wait_rval; +} worker_config; + + +static void worker(void* arg) { + worker_config* c = arg; + + if (c->delay) + uv_sleep(c->delay); + + c->worker_barrier_wait_rval = uv_barrier_wait(&c->barrier); +} + + +TEST_IMPL(barrier_1) { + uv_thread_t thread; + worker_config wc; + + memset(&wc, 0, sizeof(wc)); + + ASSERT(0 == uv_barrier_init(&wc.barrier, 2)); + ASSERT(0 == uv_thread_create(&thread, worker, &wc)); + + uv_sleep(100); + wc.main_barrier_wait_rval = uv_barrier_wait(&wc.barrier); + + ASSERT(0 == uv_thread_join(&thread)); + uv_barrier_destroy(&wc.barrier); + + ASSERT(1 == (wc.main_barrier_wait_rval ^ wc.worker_barrier_wait_rval)); + + return 0; +} + + +TEST_IMPL(barrier_2) { + uv_thread_t thread; + worker_config wc; + + memset(&wc, 0, sizeof(wc)); + wc.delay = 100; + + ASSERT(0 == uv_barrier_init(&wc.barrier, 2)); + ASSERT(0 == uv_thread_create(&thread, worker, &wc)); + + wc.main_barrier_wait_rval = uv_barrier_wait(&wc.barrier); + + ASSERT(0 == uv_thread_join(&thread)); + uv_barrier_destroy(&wc.barrier); + + ASSERT(1 == (wc.main_barrier_wait_rval ^ wc.worker_barrier_wait_rval)); + + return 0; +} + + +TEST_IMPL(barrier_3) { + uv_thread_t thread; + worker_config wc; + + memset(&wc, 0, sizeof(wc)); + + ASSERT(0 == uv_barrier_init(&wc.barrier, 2)); + ASSERT(0 == uv_thread_create(&thread, worker, &wc)); + + wc.main_barrier_wait_rval = uv_barrier_wait(&wc.barrier); + + ASSERT(0 == uv_thread_join(&thread)); + uv_barrier_destroy(&wc.barrier); + + ASSERT(1 == (wc.main_barrier_wait_rval ^ wc.worker_barrier_wait_rval)); + + return 0; +} + +static void serial_worker(void* data) { + uv_barrier_t* barrier; + + barrier = data; + if (uv_barrier_wait(barrier) > 0) + uv_barrier_destroy(barrier); + + uv_sleep(100); /* Wait a bit before terminating. */ +} + +/* Ensure that uv_barrier_wait returns positive only after all threads have + * exited the barrier. If this value is returned too early and the barrier is + * destroyed prematurely, then this test may see a crash. */ +TEST_IMPL(barrier_serial_thread) { + uv_thread_t threads[4]; + uv_barrier_t barrier; + unsigned i; + + ASSERT(0 == uv_barrier_init(&barrier, ARRAY_SIZE(threads) + 1)); + + for (i = 0; i < ARRAY_SIZE(threads); ++i) + ASSERT(0 == uv_thread_create(&threads[i], serial_worker, &barrier)); + + if (uv_barrier_wait(&barrier) > 0) + uv_barrier_destroy(&barrier); + + for (i = 0; i < ARRAY_SIZE(threads); ++i) + ASSERT(0 == uv_thread_join(&threads[i])); + + return 0; +} + +/* Single thread uv_barrier_wait should return correct return value. */ +TEST_IMPL(barrier_serial_thread_single) { + uv_barrier_t barrier; + + ASSERT(0 == uv_barrier_init(&barrier, 1)); + ASSERT(0 < uv_barrier_wait(&barrier)); + uv_barrier_destroy(&barrier); + return 0; +} diff --git a/external/src/libuv/test/test-callback-order.c b/external/src/libuv/test/test-callback-order.c new file mode 100644 index 0000000..8bc2c4f --- /dev/null +++ b/external/src/libuv/test/test-callback-order.c @@ -0,0 +1,77 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static int idle_cb_called; +static int timer_cb_called; + +static uv_idle_t idle_handle; +static uv_timer_t timer_handle; + + +/* idle_cb should run before timer_cb */ +static void idle_cb(uv_idle_t* handle) { + ASSERT(idle_cb_called == 0); + ASSERT(timer_cb_called == 0); + uv_idle_stop(handle); + idle_cb_called++; +} + + +static void timer_cb(uv_timer_t* handle) { + ASSERT(idle_cb_called == 1); + ASSERT(timer_cb_called == 0); + uv_timer_stop(handle); + timer_cb_called++; +} + + +static void next_tick(uv_idle_t* handle) { + uv_loop_t* loop = handle->loop; + uv_idle_stop(handle); + uv_idle_init(loop, &idle_handle); + uv_idle_start(&idle_handle, idle_cb); + uv_timer_init(loop, &timer_handle); + uv_timer_start(&timer_handle, timer_cb, 0, 0); +} + + +TEST_IMPL(callback_order) { + uv_loop_t* loop; + uv_idle_t idle; + + loop = uv_default_loop(); + uv_idle_init(loop, &idle); + uv_idle_start(&idle, next_tick); + + ASSERT(idle_cb_called == 0); + ASSERT(timer_cb_called == 0); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(idle_cb_called == 1); + ASSERT(timer_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-callback-stack.c b/external/src/libuv/test/test-callback-stack.c new file mode 100644 index 0000000..a5195c7 --- /dev/null +++ b/external/src/libuv/test/test-callback-stack.c @@ -0,0 +1,204 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* + * TODO: Add explanation of why we want on_close to be called from fresh + * stack. + */ + +#include "uv.h" +#include "task.h" + + +static const char MESSAGE[] = "Failure is for the weak. Everyone dies alone."; + +static uv_tcp_t client; +static uv_timer_t timer; +static uv_connect_t connect_req; +static uv_write_t write_req; +static uv_shutdown_t shutdown_req; + +static int nested = 0; +static int close_cb_called = 0; +static int connect_cb_called = 0; +static int write_cb_called = 0; +static int timer_cb_called = 0; +static int bytes_received = 0; +static int shutdown_cb_called = 0; + + +static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + buf->len = size; + buf->base = malloc(size); + ASSERT_NOT_NULL(buf->base); +} + + +static void close_cb(uv_handle_t* handle) { + ASSERT(nested == 0 && "close_cb must be called from a fresh stack"); + + close_cb_called++; +} + + +static void shutdown_cb(uv_shutdown_t* req, int status) { + ASSERT(status == 0); + ASSERT(nested == 0 && "shutdown_cb must be called from a fresh stack"); + + shutdown_cb_called++; +} + + +static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { + ASSERT(nested == 0 && "read_cb must be called from a fresh stack"); + + printf("Read. nread == %d\n", (int)nread); + free(buf->base); + + if (nread == 0) { + return; + + } else if (nread < 0) { + ASSERT(nread == UV_EOF); + + nested++; + uv_close((uv_handle_t*)tcp, close_cb); + nested--; + + return; + } + + bytes_received += nread; + + /* We call shutdown here because when bytes_received == sizeof MESSAGE there + * will be no more data sent nor received, so here it would be possible for a + * backend to call shutdown_cb immediately and *not* from a fresh stack. */ + if (bytes_received == sizeof MESSAGE) { + nested++; + + puts("Shutdown"); + + if (uv_shutdown(&shutdown_req, (uv_stream_t*)tcp, shutdown_cb)) { + FATAL("uv_shutdown failed"); + } + nested--; + } +} + + +static void timer_cb(uv_timer_t* handle) { + ASSERT(handle == &timer); + ASSERT(nested == 0 && "timer_cb must be called from a fresh stack"); + + puts("Timeout complete. Now read data..."); + + nested++; + if (uv_read_start((uv_stream_t*)&client, alloc_cb, read_cb)) { + FATAL("uv_read_start failed"); + } + nested--; + + timer_cb_called++; + + uv_close((uv_handle_t*)handle, close_cb); +} + + +static void write_cb(uv_write_t* req, int status) { + int r; + + ASSERT(status == 0); + ASSERT(nested == 0 && "write_cb must be called from a fresh stack"); + + puts("Data written. 500ms timeout..."); + + /* After the data has been sent, we're going to wait for a while, then start + * reading. This makes us certain that the message has been echoed back to + * our receive buffer when we start reading. This maximizes the temptation + * for the backend to use dirty stack for calling read_cb. */ + nested++; + r = uv_timer_init(uv_default_loop(), &timer); + ASSERT(r == 0); + r = uv_timer_start(&timer, timer_cb, 500, 0); + ASSERT(r == 0); + nested--; + + write_cb_called++; +} + + +static void connect_cb(uv_connect_t* req, int status) { + uv_buf_t buf; + + puts("Connected. Write some data to echo server..."); + + ASSERT(status == 0); + ASSERT(nested == 0 && "connect_cb must be called from a fresh stack"); + + nested++; + + buf.base = (char*) &MESSAGE; + buf.len = sizeof MESSAGE; + + if (uv_write(&write_req, (uv_stream_t*)req->handle, &buf, 1, write_cb)) { + FATAL("uv_write failed"); + } + + nested--; + + connect_cb_called++; +} + + +TEST_IMPL(callback_stack) { + struct sockaddr_in addr; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + if (uv_tcp_init(uv_default_loop(), &client)) { + FATAL("uv_tcp_init failed"); + } + + puts("Connecting..."); + + nested++; + + if (uv_tcp_connect(&connect_req, + &client, + (const struct sockaddr*) &addr, + connect_cb)) { + FATAL("uv_tcp_connect failed"); + } + nested--; + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(nested == 0); + ASSERT(connect_cb_called == 1 && "connect_cb must be called exactly once"); + ASSERT(write_cb_called == 1 && "write_cb must be called exactly once"); + ASSERT(timer_cb_called == 1 && "timer_cb must be called exactly once"); + ASSERT(bytes_received == sizeof MESSAGE); + ASSERT(shutdown_cb_called == 1 && "shutdown_cb must be called exactly once"); + ASSERT(close_cb_called == 2 && "close_cb must be called exactly twice"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-close-fd.c b/external/src/libuv/test/test-close-fd.c new file mode 100644 index 0000000..0d3927f --- /dev/null +++ b/external/src/libuv/test/test-close-fd.c @@ -0,0 +1,84 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#ifndef _WIN32 +#include +#endif + +static unsigned int read_cb_called; + +static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + static char slab[1]; + buf->base = slab; + buf->len = sizeof(slab); +} + +static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { + switch (++read_cb_called) { + case 1: + ASSERT(nread == 1); + uv_read_stop(handle); + break; + case 2: + ASSERT(nread == UV_EOF); + uv_close((uv_handle_t *) handle, NULL); + break; + default: + ASSERT(!"read_cb_called > 2"); + } +} + +TEST_IMPL(close_fd) { + uv_pipe_t pipe_handle; + uv_fs_t req; + uv_buf_t bufs[1]; + uv_file fd[2]; + bufs[0] = uv_buf_init("", 1); + + ASSERT(0 == uv_pipe(fd, 0, 0)); + ASSERT(0 == uv_pipe_init(uv_default_loop(), &pipe_handle, 0)); + ASSERT(0 == uv_pipe_open(&pipe_handle, fd[0])); + /* uv_pipe_open() takes ownership of the file descriptor. */ + fd[0] = -1; + + ASSERT(1 == uv_fs_write(NULL, &req, fd[1], bufs, 1, -1, NULL)); + ASSERT(1 == req.result); + uv_fs_req_cleanup(&req); +#ifdef _WIN32 + ASSERT(0 == _close(fd[1])); +#else + ASSERT(0 == close(fd[1])); +#endif + fd[1] = -1; + ASSERT(0 == uv_read_start((uv_stream_t *) &pipe_handle, alloc_cb, read_cb)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(1 == read_cb_called); + ASSERT(0 == uv_is_active((const uv_handle_t *) &pipe_handle)); + ASSERT(0 == uv_read_start((uv_stream_t *) &pipe_handle, alloc_cb, read_cb)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(2 == read_cb_called); + ASSERT(0 != uv_is_closing((const uv_handle_t *) &pipe_handle)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-close-order.c b/external/src/libuv/test/test-close-order.c new file mode 100644 index 0000000..c2fd6c3 --- /dev/null +++ b/external/src/libuv/test/test-close-order.c @@ -0,0 +1,80 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static int check_cb_called; +static int timer_cb_called; +static int close_cb_called; + +static uv_check_t check_handle; +static uv_timer_t timer_handle1; +static uv_timer_t timer_handle2; + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +/* check_cb should run before any close_cb */ +static void check_cb(uv_check_t* handle) { + ASSERT(check_cb_called == 0); + ASSERT(timer_cb_called == 1); + ASSERT(close_cb_called == 0); + uv_close((uv_handle_t*) handle, close_cb); + uv_close((uv_handle_t*) &timer_handle2, close_cb); + check_cb_called++; +} + + +static void timer_cb(uv_timer_t* handle) { + uv_close((uv_handle_t*) handle, close_cb); + timer_cb_called++; +} + + +TEST_IMPL(close_order) { + uv_loop_t* loop; + loop = uv_default_loop(); + + uv_check_init(loop, &check_handle); + uv_check_start(&check_handle, check_cb); + uv_timer_init(loop, &timer_handle1); + uv_timer_start(&timer_handle1, timer_cb, 0, 0); + uv_timer_init(loop, &timer_handle2); + uv_timer_start(&timer_handle2, timer_cb, 100000, 0); + + ASSERT(check_cb_called == 0); + ASSERT(close_cb_called == 0); + ASSERT(timer_cb_called == 0); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(check_cb_called == 1); + ASSERT(close_cb_called == 3); + ASSERT(timer_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-condvar.c b/external/src/libuv/test/test-condvar.c new file mode 100644 index 0000000..32abccc --- /dev/null +++ b/external/src/libuv/test/test-condvar.c @@ -0,0 +1,267 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +struct worker_config; + +typedef void (*signal_func)(struct worker_config* c, int* flag); +typedef int (*wait_func)(struct worker_config* c, const int* flag); + +typedef struct worker_config { + uv_sem_t sem_waiting; /* post before waiting. */ + uv_sem_t sem_signaled; /* post after signaling. */ + uv_mutex_t mutex; + uv_cond_t cond; + int use_broadcast; + int posted_1; + int posted_2; + signal_func signal_cond; + wait_func wait_cond; +} worker_config; + +void worker_config_init(worker_config* wc, + int use_broadcast, + signal_func signal_f, + wait_func wait_f) { + /* Wipe. */ + memset(wc, 0, sizeof(*wc)); + + /* Copy vars. */ + wc->signal_cond = signal_f; + wc->wait_cond = wait_f; + wc->use_broadcast = use_broadcast; + + /* Init. */ + ASSERT(0 == uv_sem_init(&wc->sem_waiting, 0)); + ASSERT(0 == uv_sem_init(&wc->sem_signaled, 0)); + ASSERT(0 == uv_cond_init(&wc->cond)); + ASSERT(0 == uv_mutex_init(&wc->mutex)); +} + +void worker_config_destroy(worker_config* wc) { + uv_mutex_destroy(&wc->mutex); + uv_cond_destroy(&wc->cond); + uv_sem_destroy(&wc->sem_signaled); + uv_sem_destroy(&wc->sem_waiting); +} + +/* arg is a worker_config. + * Call signal_cond then wait_cond. + * Partner should call wait then signal. */ +static void worker(void* arg) { + worker_config* c = arg; + c->signal_cond(c, &c->posted_1); + c->wait_cond(c, &c->posted_2); +} + +/* 1. Signal a waiting waiter. + * 2. Tell waiter we finished. */ +static void condvar_signal(worker_config* c, int* flag) { + /* Wait until waiter holds mutex and is preparing to wait. */ + uv_sem_wait(&c->sem_waiting); + + /* Make sure waiter has begun waiting. */ + uv_mutex_lock(&c->mutex); + + /* Help waiter differentiate between spurious and legitimate wakeup. */ + ASSERT(*flag == 0); + *flag = 1; + + if (c->use_broadcast) + uv_cond_broadcast(&c->cond); + else + uv_cond_signal(&c->cond); + + uv_mutex_unlock(&c->mutex); + + /* Done signaling. */ + uv_sem_post(&c->sem_signaled); +} + +/* 1. Wait on a signal. + * 2. Ensure that the signaler finished. */ +static int condvar_wait(worker_config* c, const int* flag) { + uv_mutex_lock(&c->mutex); + + /* Tell signal'er that I am waiting. */ + uv_sem_post(&c->sem_waiting); + + /* Wait until I get a non-spurious signal. */ + do { + uv_cond_wait(&c->cond, &c->mutex); + } while (*flag == 0); + ASSERT(*flag == 1); + + uv_mutex_unlock(&c->mutex); + + /* Wait for my signal'er to finish. */ + uv_sem_wait(&c->sem_signaled); + + return 0; +} + +/* uv_cond_wait: One thread signals, the other waits. */ +TEST_IMPL(condvar_1) { + worker_config wc; + uv_thread_t thread; + + /* Helper signal-then-wait. */ + worker_config_init(&wc, 0, condvar_signal, condvar_wait); + ASSERT(0 == uv_thread_create(&thread, worker, &wc)); + + /* We wait-then-signal. */ + ASSERT(0 == wc.wait_cond(&wc, &wc.posted_1)); + wc.signal_cond(&wc, &wc.posted_2); + + ASSERT(0 == uv_thread_join(&thread)); + worker_config_destroy(&wc); + + return 0; +} + +/* uv_cond_wait: One thread broadcasts, the other waits. */ +TEST_IMPL(condvar_2) { + worker_config wc; + uv_thread_t thread; + + /* Helper to signal-then-wait. */ + worker_config_init(&wc, 1, condvar_signal, condvar_wait); + ASSERT(0 == uv_thread_create(&thread, worker, &wc)); + + /* We wait-then-signal. */ + ASSERT(0 == wc.wait_cond(&wc, &wc.posted_1)); + wc.signal_cond(&wc, &wc.posted_2); + + ASSERT(0 == uv_thread_join(&thread)); + worker_config_destroy(&wc); + + return 0; +} + +/* 1. Wait on a signal (hopefully not timeout, else we'll hang). + * 2. Ensure that the signaler finished. */ +static int condvar_timedwait(worker_config* c, const int* flag) { + int r; + + r = 0; + + uv_mutex_lock(&c->mutex); + + /* Tell signal'er that I am waiting. */ + uv_sem_post(&c->sem_waiting); + + /* Wait until I get a non-spurious signal. */ + do { + r = uv_cond_timedwait(&c->cond, &c->mutex, (uint64_t)(1 * 1e9)); /* 1 s */ + ASSERT(r == 0); /* Should not time out. */ + } while (*flag == 0); + ASSERT(*flag == 1); + + uv_mutex_unlock(&c->mutex); + + /* Wait for my signal'er to finish. */ + uv_sem_wait(&c->sem_signaled); + return r; +} + +/* uv_cond_timedwait: One thread signals, the other timedwaits. */ +TEST_IMPL(condvar_3) { + worker_config wc; + uv_thread_t thread; + + /* Helper to signal-then-wait. */ + worker_config_init(&wc, 0, condvar_signal, condvar_timedwait); + ASSERT(0 == uv_thread_create(&thread, worker, &wc)); + + /* We wait-then-signal. */ + wc.wait_cond(&wc, &wc.posted_1); + wc.signal_cond(&wc, &wc.posted_2); + + ASSERT(0 == uv_thread_join(&thread)); + worker_config_destroy(&wc); + + return 0; +} + +/* uv_cond_timedwait: One thread broadcasts, the other waits. */ +TEST_IMPL(condvar_4) { + worker_config wc; + uv_thread_t thread; + + /* Helper to signal-then-wait. */ + worker_config_init(&wc, 1, condvar_signal, condvar_timedwait); + ASSERT(0 == uv_thread_create(&thread, worker, &wc)); + + /* We wait-then-signal. */ + wc.wait_cond(&wc, &wc.posted_1); + wc.signal_cond(&wc, &wc.posted_2); + + ASSERT(0 == uv_thread_join(&thread)); + worker_config_destroy(&wc); + + return 0; +} + +/* uv_cond_timedwait: One thread waits, no signal. Timeout should be delivered. */ +TEST_IMPL(condvar_5) { + worker_config wc; + int r; + /* ns */ + uint64_t before; + uint64_t after; + uint64_t elapsed; + uint64_t timeout; + + timeout = 100 * 1000 * 1000; /* 100 ms in ns */ + + /* Mostly irrelevant. We need cond and mutex initialized. */ + worker_config_init(&wc, 0, NULL, NULL); + + uv_mutex_lock(&wc.mutex); + + /* We wait. + * No signaler, so this will only return if timeout is delivered. */ + before = uv_hrtime(); + r = uv_cond_timedwait(&wc.cond, &wc.mutex, timeout); + after = uv_hrtime(); + + uv_mutex_unlock(&wc.mutex); + + /* It timed out. */ + ASSERT(r == UV_ETIMEDOUT); + + /* It must have taken at least timeout, modulo system timer ticks. + * But it should not take too much longer. + * cf. MSDN docs: + * https://msdn.microsoft.com/en-us/library/ms687069(VS.85).aspx */ + elapsed = after - before; + ASSERT(0.75 * timeout <= elapsed); /* 1.0 too large for Windows. */ + ASSERT(elapsed <= 5.0 * timeout); /* MacOS has reported failures up to 1.75. */ + + worker_config_destroy(&wc); + + return 0; +} diff --git a/external/src/libuv/test/test-connect-unspecified.c b/external/src/libuv/test/test-connect-unspecified.c new file mode 100644 index 0000000..5f32b67 --- /dev/null +++ b/external/src/libuv/test/test-connect-unspecified.c @@ -0,0 +1,63 @@ +/* Copyright libuv project contributors. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +*/ + +#include "uv.h" +#include "task.h" + +static void connect_4(uv_connect_t* req, int status) { + ASSERT(status != UV_EADDRNOTAVAIL); +} + +static void connect_6(uv_connect_t* req, int status) { + ASSERT(status != UV_EADDRNOTAVAIL); +} + +TEST_IMPL(connect_unspecified) { + uv_loop_t* loop; + uv_tcp_t socket4; + struct sockaddr_in addr4; + uv_connect_t connect4; + uv_tcp_t socket6; + struct sockaddr_in6 addr6; + uv_connect_t connect6; + + loop = uv_default_loop(); + + ASSERT(uv_tcp_init(loop, &socket4) == 0); + ASSERT(uv_ip4_addr("0.0.0.0", TEST_PORT, &addr4) == 0); + ASSERT(uv_tcp_connect(&connect4, + &socket4, + (const struct sockaddr*) &addr4, + connect_4) == 0); + + if (can_ipv6()) { + ASSERT(uv_tcp_init(loop, &socket6) == 0); + ASSERT(uv_ip6_addr("::", TEST_PORT, &addr6) == 0); + ASSERT(uv_tcp_connect(&connect6, + &socket6, + (const struct sockaddr*) &addr6, + connect_6) == 0); + } + + ASSERT(uv_run(loop, UV_RUN_DEFAULT) == 0); + + return 0; +} diff --git a/external/src/libuv/test/test-connection-fail.c b/external/src/libuv/test/test-connection-fail.c new file mode 100644 index 0000000..5904810 --- /dev/null +++ b/external/src/libuv/test/test-connection-fail.c @@ -0,0 +1,161 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + + +static uv_tcp_t tcp; +static uv_connect_t req; +static int connect_cb_calls; +static int close_cb_calls; + +static uv_timer_t timer; +static int timer_close_cb_calls; +static int timer_cb_calls; + + +static void on_close(uv_handle_t* handle) { + close_cb_calls++; +} + + +static void timer_close_cb(uv_handle_t* handle) { + timer_close_cb_calls++; +} + + +static void timer_cb(uv_timer_t* handle) { + timer_cb_calls++; + + /* + * These are the important asserts. The connection callback has been made, + * but libuv hasn't automatically closed the socket. The user must + * uv_close the handle manually. + */ + ASSERT(close_cb_calls == 0); + ASSERT(connect_cb_calls == 1); + + /* Close the tcp handle. */ + uv_close((uv_handle_t*)&tcp, on_close); + + /* Close the timer. */ + uv_close((uv_handle_t*)handle, timer_close_cb); +} + + +static void on_connect_with_close(uv_connect_t *req, int status) { + ASSERT((uv_stream_t*) &tcp == req->handle); + ASSERT(status == UV_ECONNREFUSED); + connect_cb_calls++; + + ASSERT(close_cb_calls == 0); + uv_close((uv_handle_t*)req->handle, on_close); +} + + +static void on_connect_without_close(uv_connect_t *req, int status) { + ASSERT(status == UV_ECONNREFUSED); + connect_cb_calls++; + + uv_timer_start(&timer, timer_cb, 100, 0); + + ASSERT(close_cb_calls == 0); +} + + +static void connection_fail(uv_connect_cb connect_cb) { + struct sockaddr_in client_addr, server_addr; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &client_addr)); + + /* There should be no servers listening on this port. */ + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); + + /* Try to connect to the server and do NUM_PINGS ping-pongs. */ + r = uv_tcp_init(uv_default_loop(), &tcp); + ASSERT(!r); + + /* We are never doing multiple reads/connects at a time anyway. so these + * handles can be pre-initialized. */ + ASSERT(0 == uv_tcp_bind(&tcp, (const struct sockaddr*) &client_addr, 0)); + + r = uv_tcp_connect(&req, + &tcp, + (const struct sockaddr*) &server_addr, + connect_cb); + ASSERT(!r); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(connect_cb_calls == 1); + ASSERT(close_cb_calls == 1); +} + + +/* + * This test attempts to connect to a port where no server is running. We + * expect an error. + */ +TEST_IMPL(connection_fail) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + + connection_fail(on_connect_with_close); + + ASSERT(timer_close_cb_calls == 0); + ASSERT(timer_cb_calls == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +/* + * This test is the same as the first except it check that the close + * callback of the tcp handle hasn't been made after the failed connection + * attempt. + */ +TEST_IMPL(connection_fail_doesnt_auto_close) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + + int r; + + r = uv_timer_init(uv_default_loop(), &timer); + ASSERT(r == 0); + + connection_fail(on_connect_without_close); + + ASSERT(timer_close_cb_calls == 1); + ASSERT(timer_cb_calls == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-cwd-and-chdir.c b/external/src/libuv/test/test-cwd-and-chdir.c new file mode 100644 index 0000000..faeed02 --- /dev/null +++ b/external/src/libuv/test/test-cwd-and-chdir.c @@ -0,0 +1,57 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +#define PATHMAX 4096 + +TEST_IMPL(cwd_and_chdir) { + char buffer_orig[PATHMAX]; + char buffer_new[PATHMAX]; + size_t size1; + size_t size2; + int err; + + size1 = 1; + err = uv_cwd(buffer_orig, &size1); + ASSERT(err == UV_ENOBUFS); + ASSERT(size1 > 1); + + size1 = sizeof buffer_orig; + err = uv_cwd(buffer_orig, &size1); + ASSERT(err == 0); + ASSERT(size1 > 0); + ASSERT(buffer_orig[size1] != '/'); + + err = uv_chdir(buffer_orig); + ASSERT(err == 0); + + size2 = sizeof buffer_new; + err = uv_cwd(buffer_new, &size2); + ASSERT(err == 0); + + ASSERT(size1 == size2); + ASSERT(strcmp(buffer_orig, buffer_new) == 0); + + return 0; +} diff --git a/external/src/libuv/test/test-default-loop-close.c b/external/src/libuv/test/test-default-loop-close.c new file mode 100644 index 0000000..51e1e7d --- /dev/null +++ b/external/src/libuv/test/test-default-loop-close.c @@ -0,0 +1,59 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + + +static int timer_cb_called; + + +static void timer_cb(uv_timer_t* timer) { + timer_cb_called++; + uv_close((uv_handle_t*) timer, NULL); +} + + +TEST_IMPL(default_loop_close) { + uv_loop_t* loop; + uv_timer_t timer_handle; + + loop = uv_default_loop(); + ASSERT_NOT_NULL(loop); + + ASSERT(0 == uv_timer_init(loop, &timer_handle)); + ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(1 == timer_cb_called); + ASSERT(0 == uv_loop_close(loop)); + + loop = uv_default_loop(); + ASSERT_NOT_NULL(loop); + + ASSERT(0 == uv_timer_init(loop, &timer_handle)); + ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(2 == timer_cb_called); + ASSERT(0 == uv_loop_close(loop)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-delayed-accept.c b/external/src/libuv/test/test-delayed-accept.c new file mode 100644 index 0000000..88b31e2 --- /dev/null +++ b/external/src/libuv/test/test-delayed-accept.c @@ -0,0 +1,189 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + +static int connection_cb_called = 0; +static int do_accept_called = 0; +static int close_cb_called = 0; +static int connect_cb_called = 0; + + +static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + buf->base = malloc(size); + buf->len = size; +} + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + + free(handle); + + close_cb_called++; +} + + +static void do_accept(uv_timer_t* timer_handle) { + uv_tcp_t* server; + uv_tcp_t* accepted_handle = (uv_tcp_t*)malloc(sizeof *accepted_handle); + int r; + + ASSERT_NOT_NULL(timer_handle); + ASSERT_NOT_NULL(accepted_handle); + + r = uv_tcp_init(uv_default_loop(), accepted_handle); + ASSERT(r == 0); + + server = (uv_tcp_t*)timer_handle->data; + r = uv_accept((uv_stream_t*)server, (uv_stream_t*)accepted_handle); + ASSERT(r == 0); + + do_accept_called++; + + /* Immediately close the accepted handle. */ + uv_close((uv_handle_t*)accepted_handle, close_cb); + + /* After accepting the two clients close the server handle */ + if (do_accept_called == 2) { + uv_close((uv_handle_t*)server, close_cb); + } + + /* Dispose the timer. */ + uv_close((uv_handle_t*)timer_handle, close_cb); +} + + +static void connection_cb(uv_stream_t* tcp, int status) { + int r; + uv_timer_t* timer_handle; + + ASSERT(status == 0); + + timer_handle = (uv_timer_t*)malloc(sizeof *timer_handle); + ASSERT_NOT_NULL(timer_handle); + + /* Accept the client after 1 second */ + r = uv_timer_init(uv_default_loop(), timer_handle); + ASSERT(r == 0); + + timer_handle->data = tcp; + + r = uv_timer_start(timer_handle, do_accept, 1000, 0); + ASSERT(r == 0); + + connection_cb_called++; +} + + +static void start_server(void) { + struct sockaddr_in addr; + uv_tcp_t* server = (uv_tcp_t*)malloc(sizeof *server); + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + ASSERT_NOT_NULL(server); + + r = uv_tcp_init(uv_default_loop(), server); + ASSERT(r == 0); + r = uv_tcp_bind(server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_listen((uv_stream_t*)server, 128, connection_cb); + ASSERT(r == 0); +} + + +static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { + /* The server will not send anything, it should close gracefully. */ + + if (buf->base) { + free(buf->base); + } + + if (nread >= 0) { + ASSERT(nread == 0); + } else { + ASSERT_NOT_NULL(tcp); + ASSERT(nread == UV_EOF); + uv_close((uv_handle_t*)tcp, close_cb); + } +} + + +static void connect_cb(uv_connect_t* req, int status) { + int r; + + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + + /* Not that the server will send anything, but otherwise we'll never know + * when the server closes the connection. */ + r = uv_read_start((uv_stream_t*)(req->handle), alloc_cb, read_cb); + ASSERT(r == 0); + + connect_cb_called++; + + free(req); +} + + +static void client_connect(void) { + struct sockaddr_in addr; + uv_tcp_t* client = (uv_tcp_t*)malloc(sizeof *client); + uv_connect_t* connect_req = malloc(sizeof *connect_req); + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + ASSERT_NOT_NULL(client); + ASSERT_NOT_NULL(connect_req); + + r = uv_tcp_init(uv_default_loop(), client); + ASSERT(r == 0); + + r = uv_tcp_connect(connect_req, + client, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT(r == 0); +} + + + +TEST_IMPL(delayed_accept) { + start_server(); + + client_connect(); + client_connect(); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(connection_cb_called == 2); + ASSERT(do_accept_called == 2); + ASSERT(connect_cb_called == 2); + ASSERT(close_cb_called == 7); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-dlerror.c b/external/src/libuv/test/test-dlerror.c new file mode 100644 index 0000000..a436ec0 --- /dev/null +++ b/external/src/libuv/test/test-dlerror.c @@ -0,0 +1,61 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + + +TEST_IMPL(dlerror) { + const char* path = "test/fixtures/load_error.node"; + const char* dlerror_no_error = "no error"; + const char* msg; + uv_lib_t lib; + int r; + + lib.errmsg = NULL; + lib.handle = NULL; + msg = uv_dlerror(&lib); + ASSERT_NOT_NULL(msg); + ASSERT_NOT_NULL(strstr(msg, dlerror_no_error)); + + r = uv_dlopen(path, &lib); + ASSERT(r == -1); + + msg = uv_dlerror(&lib); + ASSERT_NOT_NULL(msg); +#if !defined(__OpenBSD__) && !defined(__QNX__) + ASSERT_NOT_NULL(strstr(msg, path)); +#endif + ASSERT_NULL(strstr(msg, dlerror_no_error)); + + /* Should return the same error twice in a row. */ + msg = uv_dlerror(&lib); + ASSERT_NOT_NULL(msg); +#if !defined(__OpenBSD__) && !defined(__QNX__) + ASSERT_NOT_NULL(strstr(msg, path)); +#endif + ASSERT_NULL(strstr(msg, dlerror_no_error)); + + uv_dlclose(&lib); + + return 0; +} diff --git a/external/src/libuv/test/test-eintr-handling.c b/external/src/libuv/test/test-eintr-handling.c new file mode 100644 index 0000000..1aaf623 --- /dev/null +++ b/external/src/libuv/test/test-eintr-handling.c @@ -0,0 +1,94 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#ifdef _WIN32 + +TEST_IMPL(eintr_handling) { + RETURN_SKIP("Test not implemented on Windows."); +} + +#else /* !_WIN32 */ + +#include +#include + +static uv_loop_t* loop; +static uv_fs_t read_req; +static uv_buf_t iov; + +static char buf[32]; +static char test_buf[] = "test-buffer\n"; +int pipe_fds[2]; + +struct thread_ctx { + uv_barrier_t barrier; + int fd; +}; + +static void thread_main(void* arg) { + int nwritten; + ASSERT(0 == kill(getpid(), SIGUSR1)); + + do + nwritten = write(pipe_fds[1], test_buf, sizeof(test_buf)); + while (nwritten == -1 && errno == EINTR); + + ASSERT(nwritten == sizeof(test_buf)); +} + +static void sig_func(uv_signal_t* handle, int signum) { + uv_signal_stop(handle); +} + +TEST_IMPL(eintr_handling) { + struct thread_ctx ctx; + uv_thread_t thread; + uv_signal_t signal; + int nread; + + iov = uv_buf_init(buf, sizeof(buf)); + loop = uv_default_loop(); + + ASSERT(0 == uv_signal_init(loop, &signal)); + ASSERT(0 == uv_signal_start(&signal, sig_func, SIGUSR1)); + + ASSERT(0 == pipe(pipe_fds)); + ASSERT(0 == uv_thread_create(&thread, thread_main, &ctx)); + + nread = uv_fs_read(loop, &read_req, pipe_fds[0], &iov, 1, -1, NULL); + + ASSERT(nread == sizeof(test_buf)); + ASSERT(0 == strcmp(buf, test_buf)); + + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + + ASSERT(0 == close(pipe_fds[0])); + ASSERT(0 == close(pipe_fds[1])); + uv_close((uv_handle_t*) &signal, NULL); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#endif /* !_WIN32 */ diff --git a/external/src/libuv/test/test-embed.c b/external/src/libuv/test/test-embed.c new file mode 100644 index 0000000..c6ddceb --- /dev/null +++ b/external/src/libuv/test/test-embed.c @@ -0,0 +1,139 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include +#include + +#ifndef HAVE_KQUEUE +# if defined(__APPLE__) || \ + defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || \ + defined(__OpenBSD__) || \ + defined(__NetBSD__) +# define HAVE_KQUEUE 1 +# endif +#endif + +#ifndef HAVE_EPOLL +# if defined(__linux__) +# define HAVE_EPOLL 1 +# endif +#endif + +#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL) + +#if defined(HAVE_KQUEUE) +# include +# include +# include +#endif + +#if defined(HAVE_EPOLL) +# include +#endif + +static uv_thread_t embed_thread; +static uv_sem_t embed_sem; +static uv_timer_t embed_timer; +static uv_async_t embed_async; +static volatile int embed_closed; + +static int embed_timer_called; + + +static void embed_thread_runner(void* arg) { + int r; + int fd; + int timeout; + + while (!embed_closed) { + fd = uv_backend_fd(uv_default_loop()); + timeout = uv_backend_timeout(uv_default_loop()); + + do { +#if defined(HAVE_KQUEUE) + struct timespec ts; + ts.tv_sec = timeout / 1000; + ts.tv_nsec = (timeout % 1000) * 1000000; + r = kevent(fd, NULL, 0, NULL, 0, &ts); +#elif defined(HAVE_EPOLL) + { + struct epoll_event ev; + r = epoll_wait(fd, &ev, 1, timeout); + } +#endif + } while (r == -1 && errno == EINTR); + uv_async_send(&embed_async); + uv_sem_wait(&embed_sem); + } +} + + +static void embed_cb(uv_async_t* async) { + uv_run(uv_default_loop(), UV_RUN_ONCE); + + uv_sem_post(&embed_sem); +} + + +static void embed_timer_cb(uv_timer_t* timer) { + embed_timer_called++; + embed_closed = 1; + + uv_close((uv_handle_t*) &embed_async, NULL); +} +#endif + + +TEST_IMPL(embed) { +#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL) + uv_loop_t external; + + ASSERT(0 == uv_loop_init(&external)); + + embed_timer_called = 0; + embed_closed = 0; + + uv_async_init(&external, &embed_async, embed_cb); + + /* Start timer in default loop */ + uv_timer_init(uv_default_loop(), &embed_timer); + uv_timer_start(&embed_timer, embed_timer_cb, 250, 0); + + /* Start worker that will interrupt external loop */ + uv_sem_init(&embed_sem, 0); + uv_thread_create(&embed_thread, embed_thread_runner, NULL); + + /* But run external loop */ + uv_run(&external, UV_RUN_DEFAULT); + + uv_thread_join(&embed_thread); + uv_loop_close(&external); + + ASSERT(embed_timer_called == 1); +#endif + + return 0; +} diff --git a/external/src/libuv/test/test-emfile.c b/external/src/libuv/test/test-emfile.c new file mode 100644 index 0000000..bc1fce5 --- /dev/null +++ b/external/src/libuv/test/test-emfile.c @@ -0,0 +1,121 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#if !defined(_WIN32) + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +static void connection_cb(uv_stream_t* server_handle, int status); +static void connect_cb(uv_connect_t* req, int status); + +static const int maxfd = 31; +static unsigned connect_cb_called; +static uv_tcp_t server_handle; +static uv_tcp_t client_handle; + + +TEST_IMPL(emfile) { + struct sockaddr_in addr; + struct rlimit limits; + uv_connect_t connect_req; + uv_loop_t* loop; + int first_fd; +#if defined(_AIX) || defined(__MVS__) + /* On AIX, if a 'accept' call fails ECONNRESET is set on the socket + * which causes uv__emfile_trick to not work as intended and this test + * to fail. + */ + RETURN_SKIP("uv__emfile_trick does not work on this OS"); +#endif + + /* Lower the file descriptor limit and use up all fds save one. */ + limits.rlim_cur = limits.rlim_max = maxfd + 1; + if (setrlimit(RLIMIT_NOFILE, &limits)) { + ASSERT(errno == EPERM); /* Valgrind blocks the setrlimit() call. */ + RETURN_SKIP("setrlimit(RLIMIT_NOFILE) failed, running under valgrind?"); + } + + loop = uv_default_loop(); + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + ASSERT(0 == uv_tcp_init(loop, &server_handle)); + ASSERT(0 == uv_tcp_init(loop, &client_handle)); + ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0)); + ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 8, connection_cb)); + + /* Remember the first one so we can clean up afterwards. */ + do + first_fd = dup(0); + while (first_fd == -1 && errno == EINTR); + ASSERT(first_fd > 0); + + while (dup(0) != -1 || errno == EINTR); + ASSERT(errno == EMFILE); + close(maxfd); + + /* Now connect and use up the last available file descriptor. The EMFILE + * handling logic in src/unix/stream.c should ensure that connect_cb() runs + * whereas connection_cb() should *not* run. + */ + ASSERT(0 == uv_tcp_connect(&connect_req, + &client_handle, + (const struct sockaddr*) &addr, + connect_cb)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(1 == connect_cb_called); + + /* Close the dups again. Ignore errors in the unlikely event that the + * file descriptors were not contiguous. + */ + while (first_fd < maxfd) { + close(first_fd); + first_fd += 1; + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void connection_cb(uv_stream_t* server_handle, int status) { + ASSERT(0 && "connection_cb should not be called."); +} + + +static void connect_cb(uv_connect_t* req, int status) { + /* |status| should equal 0 because the connection should have been accepted, + * it's just that the server immediately closes it again. + */ + ASSERT(0 == status); + connect_cb_called += 1; + uv_close((uv_handle_t*) &server_handle, NULL); + uv_close((uv_handle_t*) &client_handle, NULL); +} + +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* !_WIN32 */ diff --git a/external/src/libuv/test/test-env-vars.c b/external/src/libuv/test/test-env-vars.c new file mode 100644 index 0000000..ecaba33 --- /dev/null +++ b/external/src/libuv/test/test-env-vars.c @@ -0,0 +1,170 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +#define BUF_SIZE 10 + +TEST_IMPL(env_vars) { + const char* name = "UV_TEST_FOO"; + const char* name2 = "UV_TEST_FOO2"; + char buf[BUF_SIZE]; + size_t size; + int i, r, envcount, found, found_win_special; + uv_env_item_t* envitems; + + /* Reject invalid inputs when setting an environment variable */ + r = uv_os_setenv(NULL, "foo"); + ASSERT(r == UV_EINVAL); + r = uv_os_setenv(name, NULL); + ASSERT(r == UV_EINVAL); + r = uv_os_setenv(NULL, NULL); + ASSERT(r == UV_EINVAL); + + /* Reject invalid inputs when retrieving an environment variable */ + size = BUF_SIZE; + r = uv_os_getenv(NULL, buf, &size); + ASSERT(r == UV_EINVAL); + r = uv_os_getenv(name, NULL, &size); + ASSERT(r == UV_EINVAL); + r = uv_os_getenv(name, buf, NULL); + ASSERT(r == UV_EINVAL); + size = 0; + r = uv_os_getenv(name, buf, &size); + ASSERT(r == UV_EINVAL); + + /* Reject invalid inputs when deleting an environment variable */ + r = uv_os_unsetenv(NULL); + ASSERT(r == UV_EINVAL); + + /* Successfully set an environment variable */ + r = uv_os_setenv(name, "123456789"); + ASSERT(r == 0); + + /* Successfully read an environment variable */ + size = BUF_SIZE; + buf[0] = '\0'; + r = uv_os_getenv(name, buf, &size); + ASSERT(r == 0); + ASSERT(strcmp(buf, "123456789") == 0); + ASSERT(size == BUF_SIZE - 1); + + /* Return UV_ENOBUFS if the buffer cannot hold the environment variable */ + size = BUF_SIZE - 1; + buf[0] = '\0'; + r = uv_os_getenv(name, buf, &size); + ASSERT(r == UV_ENOBUFS); + ASSERT(size == BUF_SIZE); + + /* Successfully delete an environment variable */ + r = uv_os_unsetenv(name); + ASSERT(r == 0); + + /* Return UV_ENOENT retrieving an environment variable that does not exist */ + r = uv_os_getenv(name, buf, &size); + ASSERT(r == UV_ENOENT); + + /* Successfully delete an environment variable that does not exist */ + r = uv_os_unsetenv(name); + ASSERT(r == 0); + + /* Setting an environment variable to the empty string does not delete it. */ + r = uv_os_setenv(name, ""); + ASSERT(r == 0); + size = BUF_SIZE; + r = uv_os_getenv(name, buf, &size); + ASSERT(r == 0); + ASSERT(size == 0); + ASSERT(strlen(buf) == 0); + + /* Check getting all env variables. */ + r = uv_os_setenv(name, "123456789"); + ASSERT(r == 0); + r = uv_os_setenv(name2, ""); + ASSERT(r == 0); +#ifdef _WIN32 + /* Create a special environment variable on Windows in case there are no + naturally occurring ones. */ + r = uv_os_setenv("=Z:", "\\"); + ASSERT(r == 0); +#endif + + r = uv_os_environ(&envitems, &envcount); + ASSERT(r == 0); + ASSERT(envcount > 0); + + found = 0; + found_win_special = 0; + + for (i = 0; i < envcount; i++) { + /* printf("Env: %s = %s\n", envitems[i].name, envitems[i].value); */ + if (strcmp(envitems[i].name, name) == 0) { + found++; + ASSERT(strcmp(envitems[i].value, "123456789") == 0); + } else if (strcmp(envitems[i].name, name2) == 0) { + found++; + ASSERT(strlen(envitems[i].value) == 0); + } else if (envitems[i].name[0] == '=') { + found_win_special++; + } + } + + ASSERT(found == 2); +#ifdef _WIN32 + ASSERT(found_win_special > 0); +#endif + + uv_os_free_environ(envitems, envcount); + + r = uv_os_unsetenv(name); + ASSERT(r == 0); + + r = uv_os_unsetenv(name2); + ASSERT(r == 0); + + for (i = 1; i <= 4; i++) { + size_t n; + char* p; + + n = i * 32768; + size = n + 1; + + p = malloc(size); + ASSERT_NOT_NULL(p); + + memset(p, 'x', n); + p[n] = '\0'; + + ASSERT_EQ(0, uv_os_setenv(name, p)); + ASSERT_EQ(0, uv_os_getenv(name, p, &size)); + ASSERT_EQ(n, size); + + for (n = 0; n < size; n++) + ASSERT_EQ('x', p[n]); + + ASSERT_EQ(0, uv_os_unsetenv(name)); + free(p); + } + + return 0; +} diff --git a/external/src/libuv/test/test-error.c b/external/src/libuv/test/test-error.c new file mode 100644 index 0000000..f0fb864 --- /dev/null +++ b/external/src/libuv/test/test-error.c @@ -0,0 +1,82 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#if defined(_WIN32) +# include "../src/win/winapi.h" +#endif + +#include +#include +#include + + +/* + * Synthetic errors (errors that originate from within libuv, not the system) + * should produce sensible error messages when run through uv_strerror(). + * + * See https://github.com/joyent/libuv/issues/210 + */ +TEST_IMPL(error_message) { +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); +#endif + char buf[32]; + + /* Cop out. Can't do proper checks on systems with + * i18n-ized error messages... + */ + if (strcmp(uv_strerror(0), "Success") != 0) { + printf("i18n error messages detected, skipping test.\n"); + return 0; + } + + ASSERT_NULL(strstr(uv_strerror(UV_EINVAL), "Success")); + ASSERT(strcmp(uv_strerror(1337), "Unknown error") == 0); + ASSERT(strcmp(uv_strerror(-1337), "Unknown error") == 0); + + ASSERT_NULL(strstr(uv_strerror_r(UV_EINVAL, buf, sizeof(buf)), "Success")); + ASSERT_NOT_NULL(strstr(uv_strerror_r(1337, buf, sizeof(buf)), "1337")); + ASSERT_NOT_NULL(strstr(uv_strerror_r(-1337, buf, sizeof(buf)), "-1337")); + + return 0; +} + + +TEST_IMPL(sys_error) { +#if defined(_WIN32) + ASSERT(uv_translate_sys_error(ERROR_NOACCESS) == UV_EACCES); + ASSERT(uv_translate_sys_error(ERROR_ELEVATION_REQUIRED) == UV_EACCES); + ASSERT(uv_translate_sys_error(WSAEADDRINUSE) == UV_EADDRINUSE); + ASSERT(uv_translate_sys_error(ERROR_BAD_PIPE) == UV_EPIPE); +#else + ASSERT(uv_translate_sys_error(EPERM) == UV_EPERM); + ASSERT(uv_translate_sys_error(EPIPE) == UV_EPIPE); + ASSERT(uv_translate_sys_error(EINVAL) == UV_EINVAL); +#endif + ASSERT(uv_translate_sys_error(UV_EINVAL) == UV_EINVAL); + ASSERT(uv_translate_sys_error(UV_ERANGE) == UV_ERANGE); + ASSERT(uv_translate_sys_error(UV_EACCES) == UV_EACCES); + ASSERT(uv_translate_sys_error(0) == 0); + + return 0; +} diff --git a/external/src/libuv/test/test-fail-always.c b/external/src/libuv/test/test-fail-always.c new file mode 100644 index 0000000..0008459 --- /dev/null +++ b/external/src/libuv/test/test-fail-always.c @@ -0,0 +1,29 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" + + +TEST_IMPL(fail_always) { + /* This test always fails. It is used to test the test runner. */ + FATAL("Yes, it always fails"); + return 2; +} diff --git a/external/src/libuv/test/test-fork.c b/external/src/libuv/test/test-fork.c new file mode 100644 index 0000000..9e4684f --- /dev/null +++ b/external/src/libuv/test/test-fork.c @@ -0,0 +1,683 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* These tests are Unix only. */ +#ifndef _WIN32 + +#include +#include +#include +#include + +#include "uv.h" +#include "task.h" + +static int timer_cb_called; +static int socket_cb_called; + +static void timer_cb(uv_timer_t* timer) { + timer_cb_called++; + uv_close((uv_handle_t*) timer, NULL); +} + + +static int socket_cb_read_fd; +static int socket_cb_read_size; +static char socket_cb_read_buf[1024]; + + +static void socket_cb(uv_poll_t* poll, int status, int events) { + ssize_t cnt; + socket_cb_called++; + ASSERT(0 == status); + printf("Socket cb got events %d\n", events); + ASSERT(UV_READABLE == (events & UV_READABLE)); + if (socket_cb_read_fd) { + cnt = read(socket_cb_read_fd, socket_cb_read_buf, socket_cb_read_size); + ASSERT(cnt == socket_cb_read_size); + } + uv_close((uv_handle_t*) poll, NULL); +} + + +static void run_timer_loop_once(void) { + uv_loop_t* loop; + uv_timer_t timer_handle; + + loop = uv_default_loop(); + + timer_cb_called = 0; /* Reset for the child. */ + + ASSERT(0 == uv_timer_init(loop, &timer_handle)); + ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(1 == timer_cb_called); +} + + +static void assert_wait_child(pid_t child_pid) { + pid_t waited_pid; + int child_stat; + + waited_pid = waitpid(child_pid, &child_stat, 0); + printf("Waited pid is %d with status %d\n", waited_pid, child_stat); + if (waited_pid == -1) { + perror("Failed to wait"); + } + ASSERT(child_pid == waited_pid); + ASSERT(WIFEXITED(child_stat)); /* Clean exit, not a signal. */ + ASSERT(!WIFSIGNALED(child_stat)); + ASSERT(0 == WEXITSTATUS(child_stat)); +} + + +TEST_IMPL(fork_timer) { + /* Timers continue to work after we fork. */ + + /* + * Establish the loop before we fork to make sure that it + * has state to get reset after the fork. + */ + pid_t child_pid; + + run_timer_loop_once(); + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + assert_wait_child(child_pid); + } else { + /* child */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + run_timer_loop_once(); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fork_socketpair) { + /* A socket opened in the parent and accept'd in the + child works after a fork. */ + pid_t child_pid; + int socket_fds[2]; + uv_poll_t poll_handle; + + /* Prime the loop. */ + run_timer_loop_once(); + + ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds)); + + /* Create the server watcher in the parent, use it in the child. */ + ASSERT(0 == uv_poll_init(uv_default_loop(), &poll_handle, socket_fds[0])); + + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + ASSERT(3 == send(socket_fds[1], "hi\n", 3, 0)); + assert_wait_child(child_pid); + } else { + /* child */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + ASSERT(0 == socket_cb_called); + ASSERT(0 == uv_poll_start(&poll_handle, UV_READABLE, socket_cb)); + printf("Going to run the loop in the child\n"); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(1 == socket_cb_called); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fork_socketpair_started) { + /* A socket opened in the parent and accept'd in the + child works after a fork, even if the watcher was already + started, and then stopped in the parent. */ + pid_t child_pid; + int socket_fds[2]; + int sync_pipe[2]; + char sync_buf[1]; + uv_poll_t poll_handle; + + ASSERT(0 == pipe(sync_pipe)); + + /* Prime the loop. */ + run_timer_loop_once(); + + ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, socket_fds)); + + /* Create and start the server watcher in the parent, use it in the child. */ + ASSERT(0 == uv_poll_init(uv_default_loop(), &poll_handle, socket_fds[0])); + ASSERT(0 == uv_poll_start(&poll_handle, UV_READABLE, socket_cb)); + + /* Run the loop AFTER the poll watcher is registered to make sure it + gets passed to the kernel. Use NOWAIT and expect a non-zero + return to prove the poll watcher is active. + */ + ASSERT(1 == uv_run(uv_default_loop(), UV_RUN_NOWAIT)); + + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + ASSERT(0 == uv_poll_stop(&poll_handle)); + uv_close((uv_handle_t*)&poll_handle, NULL); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(0 == socket_cb_called); + ASSERT(1 == write(sync_pipe[1], "1", 1)); /* alert child */ + ASSERT(3 == send(socket_fds[1], "hi\n", 3, 0)); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(0 == socket_cb_called); + + assert_wait_child(child_pid); + } else { + /* child */ + printf("Child is %d\n", getpid()); + ASSERT(1 == read(sync_pipe[0], sync_buf, 1)); /* wait for parent */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + ASSERT(0 == socket_cb_called); + + printf("Going to run the loop in the child\n"); + socket_cb_read_fd = socket_fds[0]; + socket_cb_read_size = 3; + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(1 == socket_cb_called); + printf("Buf %s\n", socket_cb_read_buf); + ASSERT(0 == strcmp("hi\n", socket_cb_read_buf)); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static int fork_signal_cb_called; + +void fork_signal_to_child_cb(uv_signal_t* handle, int signum) +{ + fork_signal_cb_called = signum; + uv_close((uv_handle_t*)handle, NULL); +} + + +TEST_IMPL(fork_signal_to_child) { + /* A signal handler installed before forking + is run only in the child when the child is signalled. */ + uv_signal_t signal_handle; + pid_t child_pid; + int sync_pipe[2]; + char sync_buf[1]; + + fork_signal_cb_called = 0; /* reset */ + + ASSERT(0 == pipe(sync_pipe)); + + /* Prime the loop. */ + run_timer_loop_once(); + + ASSERT(0 == uv_signal_init(uv_default_loop(), &signal_handle)); + ASSERT(0 == uv_signal_start(&signal_handle, fork_signal_to_child_cb, SIGUSR1)); + + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + ASSERT(1 == read(sync_pipe[0], sync_buf, 1)); /* wait for child */ + ASSERT(0 == kill(child_pid, SIGUSR1)); + /* Run the loop, make sure we don't get the signal. */ + printf("Running loop in parent\n"); + uv_unref((uv_handle_t*)&signal_handle); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_NOWAIT)); + ASSERT(0 == fork_signal_cb_called); + printf("Waiting for child in parent\n"); + assert_wait_child(child_pid); + } else { + /* child */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + ASSERT(1 == write(sync_pipe[1], "1", 1)); /* alert parent */ + /* Get the signal. */ + ASSERT(0 != uv_loop_alive(uv_default_loop())); + printf("Running loop in child\n"); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); + ASSERT(SIGUSR1 == fork_signal_cb_called); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fork_signal_to_child_closed) { + /* A signal handler installed before forking + doesn't get received anywhere when the child is signalled, + but isnt running the loop. */ + uv_signal_t signal_handle; + pid_t child_pid; + int sync_pipe[2]; + int sync_pipe2[2]; + char sync_buf[1]; + int r; + + fork_signal_cb_called = 0; /* reset */ + + ASSERT(0 == pipe(sync_pipe)); + ASSERT(0 == pipe(sync_pipe2)); + + /* Prime the loop. */ + run_timer_loop_once(); + + ASSERT(0 == uv_signal_init(uv_default_loop(), &signal_handle)); + ASSERT(0 == uv_signal_start(&signal_handle, fork_signal_to_child_cb, SIGUSR1)); + + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + printf("Wating on child in parent\n"); + ASSERT(1 == read(sync_pipe[0], sync_buf, 1)); /* wait for child */ + printf("Parent killing child\n"); + ASSERT(0 == kill(child_pid, SIGUSR1)); + /* Run the loop, make sure we don't get the signal. */ + printf("Running loop in parent\n"); + uv_unref((uv_handle_t*)&signal_handle); /* so the loop can exit; + we *shouldn't* get any signals */ + run_timer_loop_once(); /* but while we share a pipe, we do, so + have something active. */ + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); + printf("Signal in parent %d\n", fork_signal_cb_called); + ASSERT(0 == fork_signal_cb_called); + ASSERT(1 == write(sync_pipe2[1], "1", 1)); /* alert child */ + printf("Waiting for child in parent\n"); + assert_wait_child(child_pid); + } else { + /* Child. Our signal handler should still be installed. */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + printf("Checking loop in child\n"); + ASSERT(0 != uv_loop_alive(uv_default_loop())); + printf("Alerting parent in child\n"); + ASSERT(1 == write(sync_pipe[1], "1", 1)); /* alert parent */ + /* Don't run the loop. Wait for the parent to call us */ + printf("Waiting on parent in child\n"); + /* Wait for parent. read may fail if the parent tripped an ASSERT + and exited, so this ASSERT is generous. + */ + r = read(sync_pipe2[0], sync_buf, 1); + ASSERT(-1 <= r && r <= 1); + ASSERT(0 == fork_signal_cb_called); + printf("Exiting child \n"); + /* Note that we're deliberately not running the loop + * in the child, and also not closing the loop's handles, + * so the child default loop can't be cleanly closed. + * We need to explicitly exit to avoid an automatic failure + * in that case. + */ + exit(0); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void create_file(const char* name) { + int r; + uv_file file; + uv_fs_t req; + + r = uv_fs_open(NULL, &req, name, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + file = r; + uv_fs_req_cleanup(&req); + r = uv_fs_close(NULL, &req, file, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); +} + + +static void touch_file(const char* name) { + int r; + uv_file file; + uv_fs_t req; + uv_buf_t buf; + + r = uv_fs_open(NULL, &req, name, O_RDWR, 0, NULL); + ASSERT(r >= 0); + file = r; + uv_fs_req_cleanup(&req); + + buf = uv_buf_init("foo", 4); + r = uv_fs_write(NULL, &req, file, &buf, 1, -1, NULL); + ASSERT(r >= 0); + uv_fs_req_cleanup(&req); + + r = uv_fs_close(NULL, &req, file, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); +} + + +static int timer_cb_touch_called; + +static void timer_cb_touch(uv_timer_t* timer) { + uv_close((uv_handle_t*)timer, NULL); + touch_file("watch_file"); + timer_cb_touch_called++; +} + + +static int fs_event_cb_called; + +static void fs_event_cb_file_current_dir(uv_fs_event_t* handle, + const char* filename, + int events, + int status) { + ASSERT(fs_event_cb_called == 0); + ++fs_event_cb_called; + ASSERT(status == 0); +#if defined(__APPLE__) || defined(__linux__) + ASSERT(strcmp(filename, "watch_file") == 0); +#else + ASSERT(filename == NULL || strcmp(filename, "watch_file") == 0); +#endif + uv_close((uv_handle_t*)handle, NULL); +} + + +static void assert_watch_file_current_dir(uv_loop_t* const loop, int file_or_dir) { + uv_timer_t timer; + uv_fs_event_t fs_event; + int r; + + /* Setup */ + remove("watch_file"); + create_file("watch_file"); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + /* watching a dir is the only way to get fsevents involved on apple + platforms */ + r = uv_fs_event_start(&fs_event, + fs_event_cb_file_current_dir, + file_or_dir == 1 ? "." : "watch_file", + 0); + ASSERT(r == 0); + + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + + r = uv_timer_start(&timer, timer_cb_touch, 100, 0); + ASSERT(r == 0); + + ASSERT(timer_cb_touch_called == 0); + ASSERT(fs_event_cb_called == 0); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(timer_cb_touch_called == 1); + ASSERT(fs_event_cb_called == 1); + + /* Cleanup */ + remove("watch_file"); + fs_event_cb_called = 0; + timer_cb_touch_called = 0; + uv_run(loop, UV_RUN_DEFAULT); /* flush pending closes */ +} + + +#define FS_TEST_FILE 0 +#define FS_TEST_DIR 1 + +static int _do_fork_fs_events_child(int file_or_dir) { + /* basic fsevents work in the child after a fork */ + pid_t child_pid; + uv_loop_t loop; + + /* Watch in the parent, prime the loop and/or threads. */ + assert_watch_file_current_dir(uv_default_loop(), file_or_dir); + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* parent */ + assert_wait_child(child_pid); + } else { + /* child */ + /* Ee can watch in a new loop, but dirs only work + if we're on linux. */ +#if defined(__APPLE__) + file_or_dir = FS_TEST_FILE; +#endif + printf("Running child\n"); + uv_loop_init(&loop); + printf("Child first watch\n"); + assert_watch_file_current_dir(&loop, file_or_dir); + ASSERT(0 == uv_loop_close(&loop)); + printf("Child second watch default loop\n"); + /* Ee can watch in the default loop. */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + /* On some platforms (OS X), if we don't update the time now, + * the timer cb fires before the event loop enters uv__io_poll, + * instead of after, meaning we don't see the change! This may be + * a general race. + */ + uv_update_time(uv_default_loop()); + assert_watch_file_current_dir(uv_default_loop(), file_or_dir); + + /* We can close the parent loop successfully too. This is + especially important on Apple platforms where if we're not + careful trying to touch the CFRunLoop, even just to shut it + down, that we allocated in the FS_TEST_DIR case would crash. */ + ASSERT(0 == uv_loop_close(uv_default_loop())); + + printf("Exiting child \n"); + } + + MAKE_VALGRIND_HAPPY(); + return 0; + +} + + +TEST_IMPL(fork_fs_events_child) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + return _do_fork_fs_events_child(FS_TEST_FILE); +} + + +TEST_IMPL(fork_fs_events_child_dir) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif +#if defined(__APPLE__) || defined (__linux__) + return _do_fork_fs_events_child(FS_TEST_DIR); +#else + /* You can't spin up a cfrunloop thread on an apple platform + and then fork. See + http://objectivistc.tumblr.com/post/16187948939/you-must-exec-a-core-foundation-fork-safety-tale + */ + return 0; +#endif +} + + +TEST_IMPL(fork_fs_events_file_parent_child) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif +#if defined(__sun) || defined(_AIX) || defined(__MVS__) + /* It's not possible to implement this without additional + * bookkeeping on SunOS. For AIX it is possible, but has to be + * written. See https://github.com/libuv/libuv/pull/846#issuecomment-287170420 + * TODO: On z/OS, we need to open another message queue and subscribe to the + * same events as the parent. + */ + return 0; +#else + /* Establishing a started fs events watcher in the parent should + still work in the child. */ + uv_timer_t timer; + uv_fs_event_t fs_event; + int r; + pid_t child_pid; + uv_loop_t* loop; + + loop = uv_default_loop(); + + /* Setup */ + remove("watch_file"); + create_file("watch_file"); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, + fs_event_cb_file_current_dir, + "watch_file", + 0); + ASSERT(r == 0); + + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + + child_pid = fork(); + ASSERT(child_pid != -1); + if (child_pid != 0) { + /* parent */ + assert_wait_child(child_pid); + } else { + /* child */ + printf("Running child\n"); + ASSERT(0 == uv_loop_fork(loop)); + + r = uv_timer_start(&timer, timer_cb_touch, 100, 0); + ASSERT(r == 0); + + ASSERT(timer_cb_touch_called == 0); + ASSERT(fs_event_cb_called == 0); + printf("Running loop in child \n"); + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(timer_cb_touch_called == 1); + ASSERT(fs_event_cb_called == 1); + + /* Cleanup */ + remove("watch_file"); + fs_event_cb_called = 0; + timer_cb_touch_called = 0; + uv_run(loop, UV_RUN_DEFAULT); /* Flush pending closes. */ + } + + + MAKE_VALGRIND_HAPPY(); + return 0; +#endif +} + + +static int work_cb_count; +static int after_work_cb_count; + + +static void work_cb(uv_work_t* req) { + work_cb_count++; +} + + +static void after_work_cb(uv_work_t* req, int status) { + ASSERT(status == 0); + after_work_cb_count++; +} + + +static void assert_run_work(uv_loop_t* const loop) { + uv_work_t work_req; + int r; + + ASSERT(work_cb_count == 0); + ASSERT(after_work_cb_count == 0); + printf("Queue in %d\n", getpid()); + r = uv_queue_work(loop, &work_req, work_cb, after_work_cb); + ASSERT(r == 0); + printf("Running in %d\n", getpid()); + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(work_cb_count == 1); + ASSERT(after_work_cb_count == 1); + + /* cleanup */ + work_cb_count = 0; + after_work_cb_count = 0; +} + + +#ifndef __MVS__ +TEST_IMPL(fork_threadpool_queue_work_simple) { + /* The threadpool works in a child process. */ + + pid_t child_pid; + uv_loop_t loop; + + /* Prime the pool and default loop. */ + assert_run_work(uv_default_loop()); + + child_pid = fork(); + ASSERT(child_pid != -1); + + if (child_pid != 0) { + /* Parent. We can still run work. */ + assert_run_work(uv_default_loop()); + assert_wait_child(child_pid); + } else { + /* Child. We can work in a new loop. */ + printf("Running child in %d\n", getpid()); + uv_loop_init(&loop); + printf("Child first watch\n"); + assert_run_work(&loop); + uv_loop_close(&loop); + printf("Child second watch default loop\n"); + /* We can work in the default loop. */ + ASSERT(0 == uv_loop_fork(uv_default_loop())); + assert_run_work(uv_default_loop()); + printf("Exiting child \n"); + } + + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif /* !__MVS__ */ + +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* !_WIN32 */ diff --git a/external/src/libuv/test/test-fs-copyfile.c b/external/src/libuv/test/test-fs-copyfile.c new file mode 100644 index 0000000..fa00fe4 --- /dev/null +++ b/external/src/libuv/test/test-fs-copyfile.c @@ -0,0 +1,220 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#if defined(__unix__) || defined(__POSIX__) || \ + defined(__APPLE__) || defined(__sun) || \ + defined(_AIX) || defined(__MVS__) || \ + defined(__HAIKU__) || defined(__QNX__) +#include /* unlink, etc. */ +#else +# include +# include +# define unlink _unlink +#endif + +static const char fixture[] = "test/fixtures/load_error.node"; +static const char dst[] = "test_file_dst"; +static int result_check_count; + + +static void fail_cb(uv_fs_t* req) { + FATAL("fail_cb should not have been called"); +} + +static void handle_result(uv_fs_t* req) { + uv_fs_t stat_req; + uint64_t size; + uint64_t mode; + int r; + + ASSERT(req->fs_type == UV_FS_COPYFILE); + ASSERT(req->result == 0); + + /* Verify that the file size and mode are the same. */ + r = uv_fs_stat(NULL, &stat_req, req->path, NULL); + ASSERT(r == 0); + size = stat_req.statbuf.st_size; + mode = stat_req.statbuf.st_mode; + uv_fs_req_cleanup(&stat_req); + r = uv_fs_stat(NULL, &stat_req, dst, NULL); + ASSERT(r == 0); + ASSERT(stat_req.statbuf.st_size == size); + ASSERT(stat_req.statbuf.st_mode == mode); + uv_fs_req_cleanup(&stat_req); + uv_fs_req_cleanup(req); + result_check_count++; +} + + +static void touch_file(const char* name, unsigned int size) { + uv_file file; + uv_fs_t req; + uv_buf_t buf; + int r; + unsigned int i; + + r = uv_fs_open(NULL, &req, name, O_WRONLY | O_CREAT | O_TRUNC, + S_IWUSR | S_IRUSR, NULL); + uv_fs_req_cleanup(&req); + ASSERT(r >= 0); + file = r; + + buf = uv_buf_init("a", 1); + + /* Inefficient but simple. */ + for (i = 0; i < size; i++) { + r = uv_fs_write(NULL, &req, file, &buf, 1, i, NULL); + uv_fs_req_cleanup(&req); + ASSERT(r >= 0); + } + + r = uv_fs_close(NULL, &req, file, NULL); + uv_fs_req_cleanup(&req); + ASSERT(r == 0); +} + + +TEST_IMPL(fs_copyfile) { +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); +#endif + const char src[] = "test_file_src"; + uv_loop_t* loop; + uv_fs_t req; + int r; + + loop = uv_default_loop(); + + /* Fails with EINVAL if bad flags are passed. */ + r = uv_fs_copyfile(NULL, &req, src, dst, -1, NULL); + ASSERT(r == UV_EINVAL); + uv_fs_req_cleanup(&req); + + /* Fails with ENOENT if source does not exist. */ + unlink(src); + unlink(dst); + r = uv_fs_copyfile(NULL, &req, src, dst, 0, NULL); + ASSERT(req.result == UV_ENOENT); + ASSERT(r == UV_ENOENT); + uv_fs_req_cleanup(&req); + /* The destination should not exist. */ + r = uv_fs_stat(NULL, &req, dst, NULL); + ASSERT(r != 0); + uv_fs_req_cleanup(&req); + + /* Succeeds if src and dst files are identical. */ + touch_file(src, 12); + r = uv_fs_copyfile(NULL, &req, src, src, 0, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); + /* Verify that the src file did not get truncated. */ + r = uv_fs_stat(NULL, &req, src, NULL); + ASSERT_EQ(r, 0); + ASSERT_EQ(req.statbuf.st_size, 12); + uv_fs_req_cleanup(&req); + unlink(src); + + /* Copies file synchronously. Creates new file. */ + unlink(dst); + r = uv_fs_copyfile(NULL, &req, fixture, dst, 0, NULL); + ASSERT(r == 0); + handle_result(&req); + + /* Copies a file of size zero. */ + unlink(dst); + touch_file(src, 0); + r = uv_fs_copyfile(NULL, &req, src, dst, 0, NULL); + ASSERT(r == 0); + handle_result(&req); + + /* Copies file synchronously. Overwrites existing file. */ + r = uv_fs_copyfile(NULL, &req, fixture, dst, 0, NULL); + ASSERT(r == 0); + handle_result(&req); + + /* Fails to overwrites existing file. */ + r = uv_fs_copyfile(NULL, &req, fixture, dst, UV_FS_COPYFILE_EXCL, NULL); + ASSERT(r == UV_EEXIST); + uv_fs_req_cleanup(&req); + + /* Truncates when an existing destination is larger than the source file. */ + touch_file(src, 1); + r = uv_fs_copyfile(NULL, &req, src, dst, 0, NULL); + ASSERT(r == 0); + handle_result(&req); + + /* Copies a larger file. */ + unlink(dst); + touch_file(src, 4096 * 2); + r = uv_fs_copyfile(NULL, &req, src, dst, 0, NULL); + ASSERT(r == 0); + handle_result(&req); + unlink(src); + + /* Copies file asynchronously */ + unlink(dst); + r = uv_fs_copyfile(loop, &req, fixture, dst, 0, handle_result); + ASSERT(r == 0); + ASSERT(result_check_count == 5); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(result_check_count == 6); + + /* If the flags are invalid, the loop should not be kept open */ + unlink(dst); + r = uv_fs_copyfile(loop, &req, fixture, dst, -1, fail_cb); + ASSERT(r == UV_EINVAL); + uv_run(loop, UV_RUN_DEFAULT); + + /* Copies file using UV_FS_COPYFILE_FICLONE. */ + unlink(dst); + r = uv_fs_copyfile(NULL, &req, fixture, dst, UV_FS_COPYFILE_FICLONE, NULL); + ASSERT(r == 0); + handle_result(&req); + + /* Copies file using UV_FS_COPYFILE_FICLONE_FORCE. */ + unlink(dst); + r = uv_fs_copyfile(NULL, &req, fixture, dst, UV_FS_COPYFILE_FICLONE_FORCE, + NULL); + ASSERT(r <= 0); + + if (r == 0) + handle_result(&req); + +#ifndef _WIN32 + /* Copying respects permissions/mode. */ + unlink(dst); + touch_file(dst, 0); + chmod(dst, S_IRUSR|S_IRGRP|S_IROTH); /* Sets file mode to 444 (read-only). */ + r = uv_fs_copyfile(NULL, &req, fixture, dst, 0, NULL); + /* On IBMi PASE, qsecofr users can overwrite read-only files */ +# ifndef __PASE__ + ASSERT(req.result == UV_EACCES); + ASSERT(r == UV_EACCES); +# endif + uv_fs_req_cleanup(&req); +#endif + + unlink(dst); /* Cleanup */ + return 0; +} diff --git a/external/src/libuv/test/test-fs-event.c b/external/src/libuv/test/test-fs-event.c new file mode 100644 index 0000000..ec16386 --- /dev/null +++ b/external/src/libuv/test/test-fs-event.c @@ -0,0 +1,1176 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +#if defined(__APPLE__) && !TARGET_OS_IPHONE +# include +#endif + +#ifndef HAVE_KQUEUE +# if defined(__APPLE__) || \ + defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || \ + defined(__OpenBSD__) || \ + defined(__NetBSD__) +# define HAVE_KQUEUE 1 +# endif +#endif + +#if defined(__arm__)/* Increase the timeout so the test passes on arm CI bots */ +# define CREATE_TIMEOUT 100 +#else +# define CREATE_TIMEOUT 1 +#endif + +static uv_fs_event_t fs_event; +static const char file_prefix[] = "fsevent-"; +static const int fs_event_file_count = 16; +#if defined(__APPLE__) || defined(_WIN32) +static const char file_prefix_in_subdir[] = "subdir"; +static int fs_multievent_cb_called; +#endif +static uv_timer_t timer; +static int timer_cb_called; +static int close_cb_called; +static int fs_event_created; +static int fs_event_removed; +static int fs_event_cb_called; +#if defined(PATH_MAX) +static char fs_event_filename[PATH_MAX]; +#else +static char fs_event_filename[1024]; +#endif /* defined(PATH_MAX) */ +static int timer_cb_touch_called; +static int timer_cb_exact_called; + +static void fs_event_fail(uv_fs_event_t* handle, + const char* filename, + int events, + int status) { + ASSERT(0 && "should never be called"); +} + +static void create_dir(const char* name) { + int r; + uv_fs_t req; + r = uv_fs_mkdir(NULL, &req, name, 0755, NULL); + ASSERT(r == 0 || r == UV_EEXIST); + uv_fs_req_cleanup(&req); +} + +static void create_file(const char* name) { + int r; + uv_file file; + uv_fs_t req; + + r = uv_fs_open(NULL, &req, name, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + file = r; + uv_fs_req_cleanup(&req); + r = uv_fs_close(NULL, &req, file, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); +} + +static void touch_file(const char* name) { + int r; + uv_file file; + uv_fs_t req; + uv_buf_t buf; + + r = uv_fs_open(NULL, &req, name, O_RDWR, 0, NULL); + ASSERT(r >= 0); + file = r; + uv_fs_req_cleanup(&req); + + buf = uv_buf_init("foo", 4); + r = uv_fs_write(NULL, &req, file, &buf, 1, -1, NULL); + ASSERT(r >= 0); + uv_fs_req_cleanup(&req); + + r = uv_fs_close(NULL, &req, file, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); +} + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + +static void fail_cb(uv_fs_event_t* handle, + const char* path, + int events, + int status) { + ASSERT(0 && "fail_cb called"); +} + +static void fs_event_cb_dir(uv_fs_event_t* handle, const char* filename, + int events, int status) { + ++fs_event_cb_called; + ASSERT(handle == &fs_event); + ASSERT(status == 0); + ASSERT(events == UV_CHANGE); + #if defined(__APPLE__) || defined(_WIN32) || defined(__linux__) + ASSERT(strcmp(filename, "file1") == 0); + #else + ASSERT(filename == NULL || strcmp(filename, "file1") == 0); + #endif + ASSERT(0 == uv_fs_event_stop(handle)); + uv_close((uv_handle_t*)handle, close_cb); +} + +static const char* fs_event_get_filename(int i) { + snprintf(fs_event_filename, + sizeof(fs_event_filename), + "watch_dir/%s%d", + file_prefix, + i); + return fs_event_filename; +} + +static void fs_event_create_files(uv_timer_t* handle) { + /* Make sure we're not attempting to create files we do not intend */ + ASSERT(fs_event_created < fs_event_file_count); + + /* Create the file */ + create_file(fs_event_get_filename(fs_event_created)); + + if (++fs_event_created < fs_event_file_count) { + /* Create another file on a different event loop tick. We do it this way + * to avoid fs events coalescing into one fs event. */ + ASSERT(0 == uv_timer_start(&timer, + fs_event_create_files, + CREATE_TIMEOUT, + 0)); + } +} + +static void fs_event_unlink_files(uv_timer_t* handle) { + int r; + int i; + + /* NOTE: handle might be NULL if invoked not as timer callback */ + if (handle == NULL) { + /* Unlink all files */ + for (i = 0; i < 16; i++) { + r = remove(fs_event_get_filename(i)); + if (handle != NULL) + ASSERT(r == 0); + } + } else { + /* Make sure we're not attempting to remove files we do not intend */ + ASSERT(fs_event_removed < fs_event_file_count); + + /* Remove the file */ + ASSERT(0 == remove(fs_event_get_filename(fs_event_removed))); + + if (++fs_event_removed < fs_event_file_count) { + /* Remove another file on a different event loop tick. We do it this way + * to avoid fs events coalescing into one fs event. */ + ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files, 1, 0)); + } + } +} + +static void fs_event_cb_dir_multi_file(uv_fs_event_t* handle, + const char* filename, + int events, + int status) { + fs_event_cb_called++; + ASSERT(handle == &fs_event); + ASSERT(status == 0); + ASSERT(events == UV_CHANGE || events == UV_RENAME); + #if defined(__APPLE__) || defined(_WIN32) || defined(__linux__) + ASSERT(strncmp(filename, file_prefix, sizeof(file_prefix) - 1) == 0); + #else + ASSERT(filename == NULL || + strncmp(filename, file_prefix, sizeof(file_prefix) - 1) == 0); + #endif + + if (fs_event_created + fs_event_removed == fs_event_file_count) { + /* Once we've processed all create events, delete all files */ + ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files, 1, 0)); + } else if (fs_event_cb_called == 2 * fs_event_file_count) { + /* Once we've processed all create and delete events, stop watching */ + uv_close((uv_handle_t*) &timer, close_cb); + uv_close((uv_handle_t*) handle, close_cb); + } +} + +#if defined(__APPLE__) || defined(_WIN32) +static const char* fs_event_get_filename_in_subdir(int i) { + snprintf(fs_event_filename, + sizeof(fs_event_filename), + "watch_dir/subdir/%s%d", + file_prefix, + i); + return fs_event_filename; +} + +static void fs_event_create_files_in_subdir(uv_timer_t* handle) { + /* Make sure we're not attempting to create files we do not intend */ + ASSERT(fs_event_created < fs_event_file_count); + + /* Create the file */ + create_file(fs_event_get_filename_in_subdir(fs_event_created)); + + if (++fs_event_created < fs_event_file_count) { + /* Create another file on a different event loop tick. We do it this way + * to avoid fs events coalescing into one fs event. */ + ASSERT(0 == uv_timer_start(&timer, fs_event_create_files_in_subdir, 1, 0)); + } +} + +static void fs_event_unlink_files_in_subdir(uv_timer_t* handle) { + int r; + int i; + + /* NOTE: handle might be NULL if invoked not as timer callback */ + if (handle == NULL) { + /* Unlink all files */ + for (i = 0; i < 16; i++) { + r = remove(fs_event_get_filename_in_subdir(i)); + if (handle != NULL) + ASSERT(r == 0); + } + } else { + /* Make sure we're not attempting to remove files we do not intend */ + ASSERT(fs_event_removed < fs_event_file_count); + + /* Remove the file */ + ASSERT(0 == remove(fs_event_get_filename_in_subdir(fs_event_removed))); + + if (++fs_event_removed < fs_event_file_count) { + /* Remove another file on a different event loop tick. We do it this way + * to avoid fs events coalescing into one fs event. */ + ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files_in_subdir, 1, 0)); + } + } +} + +static void fs_event_cb_dir_multi_file_in_subdir(uv_fs_event_t* handle, + const char* filename, + int events, + int status) { +#ifdef _WIN32 + /* Each file created (or deleted) will cause this callback to be called twice + * under Windows: once with the name of the file, and second time with the + * name of the directory. We will ignore the callback for the directory + * itself. */ + if (filename && strcmp(filename, file_prefix_in_subdir) == 0) + return; +#endif + /* It may happen that the "subdir" creation event is captured even though + * we started watching after its actual creation. + */ + if (strcmp(filename, "subdir") == 0) + return; + + fs_multievent_cb_called++; + ASSERT(handle == &fs_event); + ASSERT(status == 0); + ASSERT(events == UV_CHANGE || events == UV_RENAME); + #if defined(__APPLE__) || defined(_WIN32) || defined(__linux__) + ASSERT(strncmp(filename, + file_prefix_in_subdir, + sizeof(file_prefix_in_subdir) - 1) == 0); + #else + ASSERT(filename == NULL || + strncmp(filename, + file_prefix_in_subdir, + sizeof(file_prefix_in_subdir) - 1) == 0); + #endif + + if (fs_event_created == fs_event_file_count && + fs_multievent_cb_called == fs_event_created) { + /* Once we've processed all create events, delete all files */ + ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files_in_subdir, 1, 0)); + } else if (fs_multievent_cb_called == 2 * fs_event_file_count) { + /* Once we've processed all create and delete events, stop watching */ + ASSERT(fs_event_removed == fs_event_file_count); + uv_close((uv_handle_t*) &timer, close_cb); + uv_close((uv_handle_t*) handle, close_cb); + } +} +#endif + +static void fs_event_cb_file(uv_fs_event_t* handle, const char* filename, + int events, int status) { + ++fs_event_cb_called; + ASSERT(handle == &fs_event); + ASSERT(status == 0); + ASSERT(events == UV_CHANGE); + #if defined(__APPLE__) || defined(_WIN32) || defined(__linux__) + ASSERT(strcmp(filename, "file2") == 0); + #else + ASSERT(filename == NULL || strcmp(filename, "file2") == 0); + #endif + ASSERT(0 == uv_fs_event_stop(handle)); + uv_close((uv_handle_t*)handle, close_cb); +} + +static void timer_cb_close_handle(uv_timer_t* timer) { + uv_handle_t* handle; + + ASSERT_NOT_NULL(timer); + handle = timer->data; + + uv_close((uv_handle_t*)timer, NULL); + uv_close((uv_handle_t*)handle, close_cb); +} + +static void fs_event_cb_file_current_dir(uv_fs_event_t* handle, + const char* filename, int events, int status) { + ASSERT(fs_event_cb_called == 0); + ++fs_event_cb_called; + + ASSERT(handle == &fs_event); + ASSERT(status == 0); + ASSERT(events == UV_CHANGE); + #if defined(__APPLE__) || defined(_WIN32) || defined(__linux__) + ASSERT(strcmp(filename, "watch_file") == 0); + #else + ASSERT(filename == NULL || strcmp(filename, "watch_file") == 0); + #endif + + /* Regression test for SunOS: touch should generate just one event. */ + { + static uv_timer_t timer; + uv_timer_init(handle->loop, &timer); + timer.data = handle; + uv_timer_start(&timer, timer_cb_close_handle, 250, 0); + } +} + +static void timer_cb_file(uv_timer_t* handle) { + ++timer_cb_called; + + if (timer_cb_called == 1) { + touch_file("watch_dir/file1"); + } else { + touch_file("watch_dir/file2"); + uv_close((uv_handle_t*)handle, close_cb); + } +} + +static void timer_cb_touch(uv_timer_t* timer) { + uv_close((uv_handle_t*)timer, NULL); + touch_file("watch_file"); + timer_cb_touch_called++; +} + +static void timer_cb_exact(uv_timer_t* handle) { + int r; + + if (timer_cb_exact_called == 0) { + touch_file("watch_dir/file.js"); + } else { + uv_close((uv_handle_t*)handle, NULL); + r = uv_fs_event_stop(&fs_event); + ASSERT(r == 0); + uv_close((uv_handle_t*) &fs_event, NULL); + } + + ++timer_cb_exact_called; +} + +static void timer_cb_watch_twice(uv_timer_t* handle) { + uv_fs_event_t* handles = handle->data; + uv_close((uv_handle_t*) (handles + 0), NULL); + uv_close((uv_handle_t*) (handles + 1), NULL); + uv_close((uv_handle_t*) handle, NULL); +} + +static void fs_event_cb_close(uv_fs_event_t* handle, + const char* filename, + int events, + int status) { + ASSERT(status == 0); + + ASSERT(fs_event_cb_called < 3); + ++fs_event_cb_called; + + if (fs_event_cb_called == 3) { + uv_close((uv_handle_t*) handle, close_cb); + } +} + + +TEST_IMPL(fs_event_watch_dir) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#elif defined(__MVS__) + RETURN_SKIP("Directory watching not supported on this platform."); +#endif + + uv_loop_t* loop = uv_default_loop(); + int r; + + /* Setup */ + fs_event_unlink_files(NULL); + remove("watch_dir/file2"); + remove("watch_dir/file1"); + remove("watch_dir/"); + create_dir("watch_dir"); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, fs_event_cb_dir_multi_file, "watch_dir", 0); + ASSERT(r == 0); + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + r = uv_timer_start(&timer, fs_event_create_files, 100, 0); + ASSERT(r == 0); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(fs_event_cb_called == fs_event_created + fs_event_removed); + ASSERT(close_cb_called == 2); + + /* Cleanup */ + fs_event_unlink_files(NULL); + remove("watch_dir/file2"); + remove("watch_dir/file1"); + remove("watch_dir/"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_event_watch_dir_recursive) { +#if defined(__APPLE__) || defined(_WIN32) + uv_loop_t* loop; + int r; + uv_fs_event_t fs_event_root; + + /* Setup */ + loop = uv_default_loop(); + fs_event_unlink_files(NULL); + remove("watch_dir/file2"); + remove("watch_dir/file1"); + remove("watch_dir/subdir"); + remove("watch_dir/"); + create_dir("watch_dir"); + create_dir("watch_dir/subdir"); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, + fs_event_cb_dir_multi_file_in_subdir, + "watch_dir", + UV_FS_EVENT_RECURSIVE); + ASSERT(r == 0); + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + r = uv_timer_start(&timer, fs_event_create_files_in_subdir, 100, 0); + ASSERT(r == 0); + +#ifndef _WIN32 + /* Also try to watch the root directory. + * This will be noisier, so we're just checking for any couple events to happen. */ + r = uv_fs_event_init(loop, &fs_event_root); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event_root, + fs_event_cb_close, + "/", + UV_FS_EVENT_RECURSIVE); + ASSERT(r == 0); +#else + fs_event_cb_called += 3; + close_cb_called += 1; + (void)fs_event_root; +#endif + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(fs_multievent_cb_called == fs_event_created + fs_event_removed); + ASSERT(fs_event_cb_called == 3); + ASSERT(close_cb_called == 3); + + /* Cleanup */ + fs_event_unlink_files_in_subdir(NULL); + remove("watch_dir/file2"); + remove("watch_dir/file1"); + remove("watch_dir/subdir"); + remove("watch_dir/"); + + MAKE_VALGRIND_HAPPY(); + return 0; +#else + RETURN_SKIP("Recursive directory watching not supported on this platform."); +#endif +} + +#ifdef _WIN32 +TEST_IMPL(fs_event_watch_dir_short_path) { + uv_loop_t* loop; + uv_fs_t req; + int has_shortnames; + int r; + + /* Setup */ + loop = uv_default_loop(); + remove("watch_dir/file1"); + remove("watch_dir/"); + create_dir("watch_dir"); + create_file("watch_dir/file1"); + + /* Newer version of Windows ship with + HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation + not equal to 0. So we verify the files we created are addressable by a 8.3 + short name */ + has_shortnames = uv_fs_stat(NULL, &req, "watch_~1", NULL) != UV_ENOENT; + if (has_shortnames) { + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, fs_event_cb_dir, "watch_~1", 0); + ASSERT(r == 0); + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + r = uv_timer_start(&timer, timer_cb_file, 100, 0); + ASSERT(r == 0); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(fs_event_cb_called == 1); + ASSERT(timer_cb_called == 1); + ASSERT(close_cb_called == 1); + } + + /* Cleanup */ + remove("watch_dir/file1"); + remove("watch_dir/"); + + MAKE_VALGRIND_HAPPY(); + + if (!has_shortnames) + RETURN_SKIP("Was not able to address files with 8.3 short name."); + + return 0; +} +#endif + + +TEST_IMPL(fs_event_watch_file) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + + uv_loop_t* loop = uv_default_loop(); + int r; + + /* Setup */ + remove("watch_dir/file2"); + remove("watch_dir/file1"); + remove("watch_dir/"); + create_dir("watch_dir"); + create_file("watch_dir/file1"); + create_file("watch_dir/file2"); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, fs_event_cb_file, "watch_dir/file2", 0); + ASSERT(r == 0); + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + r = uv_timer_start(&timer, timer_cb_file, 100, 100); + ASSERT(r == 0); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(fs_event_cb_called == 1); + ASSERT(timer_cb_called == 2); + ASSERT(close_cb_called == 2); + + /* Cleanup */ + remove("watch_dir/file2"); + remove("watch_dir/file1"); + remove("watch_dir/"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_event_watch_file_exact_path) { + /* + This test watches a file named "file.jsx" and modifies a file named + "file.js". The test verifies that no events occur for file.jsx. + */ + +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + + uv_loop_t* loop; + int r; + + loop = uv_default_loop(); + + /* Setup */ + remove("watch_dir/file.js"); + remove("watch_dir/file.jsx"); + remove("watch_dir/"); + create_dir("watch_dir"); + create_file("watch_dir/file.js"); + create_file("watch_dir/file.jsx"); +#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_12) + /* Empirically, FSEvents seems to (reliably) report the preceeding + * create_file events prior to macOS 10.11.6 in the subsequent fs_watch + * creation, but that behavior hasn't been observed to occur on newer + * versions. Give a long delay here to let the system settle before running + * the test. */ + uv_sleep(1100); + uv_update_time(loop); +#endif + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, fs_event_fail, "watch_dir/file.jsx", 0); + ASSERT(r == 0); + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + r = uv_timer_start(&timer, timer_cb_exact, 100, 100); + ASSERT(r == 0); + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + ASSERT(timer_cb_exact_called == 2); + + /* Cleanup */ + remove("watch_dir/file.js"); + remove("watch_dir/file.jsx"); + remove("watch_dir/"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_event_watch_file_twice) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); +#endif + const char path[] = "test/fixtures/empty_file"; + uv_fs_event_t watchers[2]; + uv_timer_t timer; + uv_loop_t* loop; + + loop = uv_default_loop(); + timer.data = watchers; + + ASSERT(0 == uv_fs_event_init(loop, watchers + 0)); + ASSERT(0 == uv_fs_event_start(watchers + 0, fail_cb, path, 0)); + ASSERT(0 == uv_fs_event_init(loop, watchers + 1)); + ASSERT(0 == uv_fs_event_start(watchers + 1, fail_cb, path, 0)); + ASSERT(0 == uv_timer_init(loop, &timer)); + ASSERT(0 == uv_timer_start(&timer, timer_cb_watch_twice, 10, 0)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_event_watch_file_current_dir) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + uv_timer_t timer; + uv_loop_t* loop; + int r; + + loop = uv_default_loop(); + + /* Setup */ + remove("watch_file"); + create_file("watch_file"); +#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_12) + /* Empirically, kevent seems to (sometimes) report the preceeding + * create_file events prior to macOS 10.11.6 in the subsequent fs_event_start + * So let the system settle before running the test. */ + uv_sleep(1100); + uv_update_time(loop); +#endif + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, + fs_event_cb_file_current_dir, + "watch_file", + 0); + ASSERT(r == 0); + + + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + + r = uv_timer_start(&timer, timer_cb_touch, 1100, 0); + ASSERT(r == 0); + + ASSERT(timer_cb_touch_called == 0); + ASSERT(fs_event_cb_called == 0); + ASSERT(close_cb_called == 0); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(timer_cb_touch_called == 1); + ASSERT(fs_event_cb_called == 1); + ASSERT(close_cb_called == 1); + + /* Cleanup */ + remove("watch_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#ifdef _WIN32 +TEST_IMPL(fs_event_watch_file_root_dir) { + uv_loop_t* loop; + int r; + + const char* sys_drive = getenv("SystemDrive"); + char path[] = "\\\\?\\X:\\bootsect.bak"; + + ASSERT_NOT_NULL(sys_drive); + strncpy(path + sizeof("\\\\?\\") - 1, sys_drive, 1); + + loop = uv_default_loop(); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, fail_cb, path, 0); + if (r == UV_ENOENT) + RETURN_SKIP("bootsect.bak doesn't exist in system root.\n"); + ASSERT(r == 0); + + uv_close((uv_handle_t*) &fs_event, NULL); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + +TEST_IMPL(fs_event_no_callback_after_close) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + + uv_loop_t* loop = uv_default_loop(); + int r; + + /* Setup */ + remove("watch_dir/file1"); + remove("watch_dir/"); + create_dir("watch_dir"); + create_file("watch_dir/file1"); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, + fs_event_cb_file, + "watch_dir/file1", + 0); + ASSERT(r == 0); + + + uv_close((uv_handle_t*)&fs_event, close_cb); + touch_file("watch_dir/file1"); + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(fs_event_cb_called == 0); + ASSERT(close_cb_called == 1); + + /* Cleanup */ + remove("watch_dir/file1"); + remove("watch_dir/"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_event_no_callback_on_close) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + + uv_loop_t* loop = uv_default_loop(); + int r; + + /* Setup */ + remove("watch_dir/file1"); + remove("watch_dir/"); + create_dir("watch_dir"); + create_file("watch_dir/file1"); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, + fs_event_cb_file, + "watch_dir/file1", + 0); + ASSERT(r == 0); + + uv_close((uv_handle_t*)&fs_event, close_cb); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(fs_event_cb_called == 0); + ASSERT(close_cb_called == 1); + + /* Cleanup */ + remove("watch_dir/file1"); + remove("watch_dir/"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void timer_cb(uv_timer_t* handle) { + int r; + + r = uv_fs_event_init(handle->loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, fs_event_fail, ".", 0); + ASSERT(r == 0); + + uv_close((uv_handle_t*)&fs_event, close_cb); + uv_close((uv_handle_t*)handle, close_cb); +} + + +TEST_IMPL(fs_event_immediate_close) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + uv_timer_t timer; + uv_loop_t* loop; + int r; + + loop = uv_default_loop(); + + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + + r = uv_timer_start(&timer, timer_cb, 1, 0); + ASSERT(r == 0); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_event_close_with_pending_event) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + uv_loop_t* loop; + int r; + + loop = uv_default_loop(); + + create_dir("watch_dir"); + create_file("watch_dir/file"); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, fs_event_fail, "watch_dir", 0); + ASSERT(r == 0); + + /* Generate an fs event. */ + touch_file("watch_dir/file"); + + uv_close((uv_handle_t*)&fs_event, close_cb); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + + /* Clean up */ + remove("watch_dir/file"); + remove("watch_dir/"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_event_close_in_callback) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#elif defined(__MVS__) + RETURN_SKIP("Directory watching not supported on this platform."); +#endif + uv_loop_t* loop; + int r; + + loop = uv_default_loop(); + + fs_event_unlink_files(NULL); + create_dir("watch_dir"); + + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, fs_event_cb_close, "watch_dir", 0); + ASSERT(r == 0); + + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + r = uv_timer_start(&timer, fs_event_create_files, 100, 0); + ASSERT(r == 0); + + uv_run(loop, UV_RUN_DEFAULT); + + uv_close((uv_handle_t*)&timer, close_cb); + + uv_run(loop, UV_RUN_ONCE); + + ASSERT(close_cb_called == 2); + ASSERT(fs_event_cb_called == 3); + + /* Clean up */ + fs_event_unlink_files(NULL); + remove("watch_dir/"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_event_start_and_close) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + uv_loop_t* loop; + uv_fs_event_t fs_event1; + uv_fs_event_t fs_event2; + int r; + + loop = uv_default_loop(); + + create_dir("watch_dir"); + + r = uv_fs_event_init(loop, &fs_event1); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event1, fs_event_cb_dir, "watch_dir", 0); + ASSERT(r == 0); + + r = uv_fs_event_init(loop, &fs_event2); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event2, fs_event_cb_dir, "watch_dir", 0); + ASSERT(r == 0); + + uv_close((uv_handle_t*) &fs_event2, close_cb); + uv_close((uv_handle_t*) &fs_event1, close_cb); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 2); + + remove("watch_dir/"); + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_event_getpath) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + uv_loop_t* loop = uv_default_loop(); + unsigned i; + int r; + char buf[1024]; + size_t len; + const char* const watch_dir[] = { + "watch_dir", + "watch_dir/", + "watch_dir///", + "watch_dir/subfolder/..", + "watch_dir//subfolder//..//", + }; + + create_dir("watch_dir"); + create_dir("watch_dir/subfolder"); + + + for (i = 0; i < ARRAY_SIZE(watch_dir); i++) { + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + len = sizeof buf; + r = uv_fs_event_getpath(&fs_event, buf, &len); + ASSERT(r == UV_EINVAL); + r = uv_fs_event_start(&fs_event, fail_cb, watch_dir[i], 0); + ASSERT(r == 0); + len = 0; + r = uv_fs_event_getpath(&fs_event, buf, &len); + ASSERT(r == UV_ENOBUFS); + ASSERT(len < sizeof buf); /* sanity check */ + ASSERT(len == strlen(watch_dir[i]) + 1); + r = uv_fs_event_getpath(&fs_event, buf, &len); + ASSERT(r == 0); + ASSERT(len == strlen(watch_dir[i])); + ASSERT(strcmp(buf, watch_dir[i]) == 0); + r = uv_fs_event_stop(&fs_event); + ASSERT(r == 0); + uv_close((uv_handle_t*) &fs_event, close_cb); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + close_cb_called = 0; + } + + remove("watch_dir/"); + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#if defined(__APPLE__) + +static int fs_event_error_reported; + +static void fs_event_error_report_cb(uv_fs_event_t* handle, + const char* filename, + int events, + int status) { + if (status != 0) + fs_event_error_reported = status; +} + +static void timer_cb_nop(uv_timer_t* handle) { + ++timer_cb_called; + uv_close((uv_handle_t*) handle, close_cb); +} + +static void fs_event_error_report_close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; + + /* handle is allocated on-stack, no need to free it */ +} + + +TEST_IMPL(fs_event_error_reporting) { + unsigned int i; + uv_loop_t loops[1024]; + uv_fs_event_t events[ARRAY_SIZE(loops)]; + uv_loop_t* loop; + uv_fs_event_t* event; + + TEST_FILE_LIMIT(ARRAY_SIZE(loops) * 3); + + remove("watch_dir/"); + create_dir("watch_dir"); + + /* Create a lot of loops, and start FSEventStream in each of them. + * Eventually, this should create enough streams to make FSEventStreamStart() + * fail. + */ + for (i = 0; i < ARRAY_SIZE(loops); i++) { + loop = &loops[i]; + ASSERT(0 == uv_loop_init(loop)); + event = &events[i]; + + timer_cb_called = 0; + close_cb_called = 0; + ASSERT(0 == uv_fs_event_init(loop, event)); + ASSERT(0 == uv_fs_event_start(event, + fs_event_error_report_cb, + "watch_dir", + 0)); + uv_unref((uv_handle_t*) event); + + /* Let loop run for some time */ + ASSERT(0 == uv_timer_init(loop, &timer)); + ASSERT(0 == uv_timer_start(&timer, timer_cb_nop, 2, 0)); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(1 == timer_cb_called); + ASSERT(1 == close_cb_called); + if (fs_event_error_reported != 0) + break; + } + + /* At least one loop should fail */ + ASSERT(fs_event_error_reported == UV_EMFILE); + + /* Stop and close all events, and destroy loops */ + do { + loop = &loops[i]; + event = &events[i]; + + ASSERT(0 == uv_fs_event_stop(event)); + uv_ref((uv_handle_t*) event); + uv_close((uv_handle_t*) event, fs_event_error_report_close_cb); + + close_cb_called = 0; + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(close_cb_called == 1); + + uv_loop_close(loop); + } while (i-- != 0); + + remove("watch_dir/"); + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#else /* !defined(__APPLE__) */ + +TEST_IMPL(fs_event_error_reporting) { + /* No-op, needed only for FSEvents backend */ + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#endif /* defined(__APPLE__) */ + +TEST_IMPL(fs_event_watch_invalid_path) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + + uv_loop_t* loop; + int r; + + loop = uv_default_loop(); + r = uv_fs_event_init(loop, &fs_event); + ASSERT(r == 0); + r = uv_fs_event_start(&fs_event, fs_event_cb_file, "<:;", 0); + ASSERT(r != 0); + ASSERT(uv_is_active((uv_handle_t*) &fs_event) == 0); + r = uv_fs_event_start(&fs_event, fs_event_cb_file, "", 0); + ASSERT(r != 0); + ASSERT(uv_is_active((uv_handle_t*) &fs_event) == 0); + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-fs-fd-hash.c b/external/src/libuv/test/test-fs-fd-hash.c new file mode 100644 index 0000000..8b4bc03 --- /dev/null +++ b/external/src/libuv/test/test-fs-fd-hash.c @@ -0,0 +1,133 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#if defined(_WIN32) && !defined(USING_UV_SHARED) + +#include "uv.h" +#include "task.h" + +#include "../src/win/fs-fd-hash-inl.h" + + +#define HASH_MAX 1000000000 +#define HASH_INC (1000 * UV__FD_HASH_SIZE + 2) +#define BUCKET_MAX (UV__FD_HASH_SIZE * UV__FD_HASH_GROUP_SIZE * 10) +#define BUCKET_INC UV__FD_HASH_SIZE +#define FD_DIFF 9 + + +void assert_nonexistent(int fd) { + struct uv__fd_info_s info = { 0 }; + ASSERT(!uv__fd_hash_get(fd, &info)); + ASSERT(!uv__fd_hash_remove(fd, &info)); +} + +void assert_existent(int fd) { + struct uv__fd_info_s info = { 0 }; + ASSERT(uv__fd_hash_get(fd, &info)); + ASSERT(info.flags == fd + FD_DIFF); +} + +void assert_insertion(int fd) { + struct uv__fd_info_s info = { 0 }; + assert_nonexistent(fd); + info.flags = fd + FD_DIFF; + uv__fd_hash_add(fd, &info); + assert_existent(fd); +} + +void assert_removal(int fd) { + struct uv__fd_info_s info = { 0 }; + assert_existent(fd); + uv__fd_hash_remove(fd, &info); + ASSERT(info.flags == fd + FD_DIFF); + assert_nonexistent(fd); +} + + +/* Run a function for a set of values up to a very high number */ +#define RUN_HASH(function) \ + do { \ + for (fd = 0; fd < HASH_MAX; fd += HASH_INC) { \ + function(fd); \ + } \ + } while (0) + +/* Run a function for a set of values that will cause many collisions */ +#define RUN_COLLISIONS(function) \ + do { \ + for (fd = 1; fd < BUCKET_MAX; fd += BUCKET_INC) { \ + function(fd); \ + } \ + } while (0) + + +TEST_IMPL(fs_fd_hash) { + int fd; + + uv__fd_hash_init(); + + /* Empty table */ + RUN_HASH(assert_nonexistent); + RUN_COLLISIONS(assert_nonexistent); + + /* Fill up */ + RUN_HASH(assert_insertion); + RUN_COLLISIONS(assert_insertion); + + /* Full */ + RUN_HASH(assert_existent); + RUN_COLLISIONS(assert_existent); + + /* Update */ + { + struct uv__fd_info_s info = { 0 }; + info.flags = FD_DIFF + FD_DIFF; + uv__fd_hash_add(0, &info); + } + { + struct uv__fd_info_s info = { 0 }; + ASSERT(uv__fd_hash_get(0, &info)); + ASSERT(info.flags == FD_DIFF + FD_DIFF); + } + { + /* Leave as it was, will be again tested below */ + struct uv__fd_info_s info = { 0 }; + info.flags = FD_DIFF; + uv__fd_hash_add(0, &info); + } + + /* Remove all */ + RUN_HASH(assert_removal); + RUN_COLLISIONS(assert_removal); + + /* Empty table */ + RUN_HASH(assert_nonexistent); + RUN_COLLISIONS(assert_nonexistent); + + return 0; +} + +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* ifndef _WIN32 */ diff --git a/external/src/libuv/test/test-fs-open-flags.c b/external/src/libuv/test/test-fs-open-flags.c new file mode 100644 index 0000000..5f61007 --- /dev/null +++ b/external/src/libuv/test/test-fs-open-flags.c @@ -0,0 +1,435 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifdef _WIN32 + +#include "uv.h" +#include "task.h" + +#if defined(__unix__) || defined(__POSIX__) || \ + defined(__APPLE__) || defined(__sun) || \ + defined(_AIX) || defined(__MVS__) || \ + defined(__HAIKU__) +# include /* unlink, rmdir */ +#else +# include +# define rmdir _rmdir +# define unlink _unlink +#endif + +static int flags; + +static uv_fs_t close_req; +static uv_fs_t mkdir_req; +static uv_fs_t open_req; +static uv_fs_t read_req; +static uv_fs_t rmdir_req; +static uv_fs_t unlink_req; +static uv_fs_t write_req; + +static char buf[32]; +static uv_buf_t iov; + +/* Opening the same file multiple times quickly can cause uv_fs_open to fail + * with EBUSY, so append an identifier to the file name for each operation */ +static int sid = 0; + +#define FILE_NAME_SIZE 128 +static char absent_file[FILE_NAME_SIZE]; +static char empty_file[FILE_NAME_SIZE]; +static char dummy_file[FILE_NAME_SIZE]; +static char empty_dir[] = "empty_dir"; + +static void setup(void) { + int r; + + /* empty_dir */ + r = uv_fs_rmdir(NULL, &rmdir_req, empty_dir, NULL); + ASSERT(r == 0 || r == UV_ENOENT); + ASSERT(rmdir_req.result == 0 || rmdir_req.result == UV_ENOENT); + uv_fs_req_cleanup(&rmdir_req); + + r = uv_fs_mkdir(NULL, &mkdir_req, empty_dir, 0755, NULL); + ASSERT(r == 0); + ASSERT(mkdir_req.result == 0); + uv_fs_req_cleanup(&mkdir_req); +} + +static void refresh(void) { + int r; + + /* absent_file */ + sprintf(absent_file, "test_file_%d", sid++); + + r = uv_fs_unlink(NULL, &unlink_req, absent_file, NULL); + ASSERT(r == 0 || r == UV_ENOENT); + ASSERT(unlink_req.result == 0 || unlink_req.result == UV_ENOENT); + uv_fs_req_cleanup(&unlink_req); + + /* empty_file */ + sprintf(empty_file, "test_file_%d", sid++); + + r = uv_fs_open(NULL, &open_req, empty_file, + UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(open_req.result >= 0); + uv_fs_req_cleanup(&open_req); + + r = uv_fs_close(NULL, &close_req, open_req.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* dummy_file */ + sprintf(dummy_file, "test_file_%d", sid++); + + r = uv_fs_open(NULL, &open_req, dummy_file, + UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(open_req.result >= 0); + uv_fs_req_cleanup(&open_req); + + iov = uv_buf_init("a", 1); + r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL); + ASSERT(r == 1); + ASSERT(write_req.result == 1); + uv_fs_req_cleanup(&write_req); + + r = uv_fs_close(NULL, &close_req, open_req.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); +} + +static void cleanup(void) { + unlink(absent_file); + unlink(empty_file); + unlink(dummy_file); +} + +static void openFail(char *file, int error) { + int r; + + refresh(); + + r = uv_fs_open(NULL, &open_req, file, flags, S_IWUSR | S_IRUSR, NULL); + ASSERT(r == error); + ASSERT(open_req.result == error); + uv_fs_req_cleanup(&open_req); + + /* Ensure the first call does not create the file */ + r = uv_fs_open(NULL, &open_req, file, flags, S_IWUSR | S_IRUSR, NULL); + ASSERT(r == error); + ASSERT(open_req.result == error); + uv_fs_req_cleanup(&open_req); + + cleanup(); +} + +static void refreshOpen(char *file) { + int r; + + refresh(); + + r = uv_fs_open(NULL, &open_req, file, flags, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(open_req.result >= 0); + uv_fs_req_cleanup(&open_req); +} + +static void writeExpect(char *file, char *expected, int size) { + int r; + + refreshOpen(file); + + iov = uv_buf_init("b", 1); + r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL); + ASSERT(r == 1); + ASSERT(write_req.result == 1); + uv_fs_req_cleanup(&write_req); + + iov = uv_buf_init("c", 1); + r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL); + ASSERT(r == 1); + ASSERT(write_req.result == 1); + uv_fs_req_cleanup(&write_req); + + r = uv_fs_close(NULL, &close_req, open_req.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* Check contents */ + r = uv_fs_open(NULL, &open_req, file, UV_FS_O_RDONLY, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(open_req.result >= 0); + uv_fs_req_cleanup(&open_req); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL); + ASSERT(r == size); + ASSERT(read_req.result == size); + ASSERT(strncmp(buf, expected, size) == 0); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_close(NULL, &close_req, open_req.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + cleanup(); +} + +static void writeFail(char *file, int error) { + int r; + + refreshOpen(file); + + iov = uv_buf_init("z", 1); + r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL); + ASSERT(r == error); + ASSERT(write_req.result == error); + uv_fs_req_cleanup(&write_req); + + iov = uv_buf_init("z", 1); + r = uv_fs_write(NULL, &write_req, open_req.result, &iov, 1, -1, NULL); + ASSERT(r == error); + ASSERT(write_req.result == error); + uv_fs_req_cleanup(&write_req); + + r = uv_fs_close(NULL, &close_req, open_req.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + cleanup(); +} + +static void readExpect(char *file, char *expected, int size) { + int r; + + refreshOpen(file); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL); + ASSERT(r == size); + ASSERT(read_req.result == size); + ASSERT(strncmp(buf, expected, size) == 0); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_close(NULL, &close_req, open_req.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + cleanup(); +} + +static void readFail(char *file, int error) { + int r; + + refreshOpen(file); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL); + ASSERT(r == error); + ASSERT(read_req.result == error); + uv_fs_req_cleanup(&read_req); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req.result, &iov, 1, -1, NULL); + ASSERT(r == error); + ASSERT(read_req.result == error); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_close(NULL, &close_req, open_req.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + cleanup(); +} + +static void fs_open_flags(int add_flags) { + /* Follow the order from + * https://github.com/nodejs/node/blob/1a96abe849/lib/internal/fs/utils.js#L329-L354 + */ + + /* r */ + flags = add_flags | UV_FS_O_RDONLY; + openFail(absent_file, UV_ENOENT); + writeFail(empty_file, UV_EPERM); + readExpect(empty_file, "", 0); + writeFail(dummy_file, UV_EPERM); + readExpect(dummy_file, "a", 1); + writeFail(empty_dir, UV_EPERM); + readFail(empty_dir, UV_EISDIR); + + /* rs */ + flags = add_flags | UV_FS_O_RDONLY | UV_FS_O_SYNC; + openFail(absent_file, UV_ENOENT); + writeFail(empty_file, UV_EPERM); + readExpect(empty_file, "", 0); + writeFail(dummy_file, UV_EPERM); + readExpect(dummy_file, "a", 1); + writeFail(empty_dir, UV_EPERM); + readFail(empty_dir, UV_EISDIR); + + /* r+ */ + flags = add_flags | UV_FS_O_RDWR; + openFail(absent_file, UV_ENOENT); + writeExpect(empty_file, "bc", 2); + readExpect(empty_file, "", 0); + writeExpect(dummy_file, "bc", 2); + readExpect(dummy_file, "a", 1); + writeFail(empty_dir, UV_EISDIR); + readFail(empty_dir, UV_EISDIR); + + /* rs+ */ + flags = add_flags | UV_FS_O_RDWR | UV_FS_O_SYNC; + openFail(absent_file, UV_ENOENT); + writeExpect(empty_file, "bc", 2); + readExpect(empty_file, "", 0); + writeExpect(dummy_file, "bc", 2); + readExpect(dummy_file, "a", 1); + writeFail(empty_dir, UV_EISDIR); + readFail(empty_dir, UV_EISDIR); + + /* w */ + flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY; + writeExpect(absent_file, "bc", 2); + readFail(absent_file, UV_EPERM); + writeExpect(empty_file, "bc", 2); + readFail(empty_file, UV_EPERM); + writeExpect(dummy_file, "bc", 2); + readFail(dummy_file, UV_EPERM); + openFail(empty_dir, UV_EISDIR); + + /* wx */ + flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY | + UV_FS_O_EXCL; + writeExpect(absent_file, "bc", 2); + readFail(absent_file, UV_EPERM); + openFail(empty_file, UV_EEXIST); + openFail(dummy_file, UV_EEXIST); + openFail(empty_dir, UV_EEXIST); + + /* w+ */ + flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_RDWR; + writeExpect(absent_file, "bc", 2); + readExpect(absent_file, "", 0); + writeExpect(empty_file, "bc", 2); + readExpect(empty_file, "", 0); + writeExpect(dummy_file, "bc", 2); + readExpect(dummy_file, "", 0); + openFail(empty_dir, UV_EISDIR); + + /* wx+ */ + flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_RDWR | + UV_FS_O_EXCL; + writeExpect(absent_file, "bc", 2); + readExpect(absent_file, "", 0); + openFail(empty_file, UV_EEXIST); + openFail(dummy_file, UV_EEXIST); + openFail(empty_dir, UV_EEXIST); + + /* a */ + flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY; + writeExpect(absent_file, "bc", 2); + readFail(absent_file, UV_EPERM); + writeExpect(empty_file, "bc", 2); + readFail(empty_file, UV_EPERM); + writeExpect(dummy_file, "abc", 3); + readFail(dummy_file, UV_EPERM); + writeFail(empty_dir, UV_EISDIR); + readFail(empty_dir, UV_EPERM); + + /* ax */ + flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY | + UV_FS_O_EXCL; + writeExpect(absent_file, "bc", 2); + readFail(absent_file, UV_EPERM); + openFail(empty_file, UV_EEXIST); + openFail(dummy_file, UV_EEXIST); + openFail(empty_dir, UV_EEXIST); + + /* as */ + flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY | + UV_FS_O_SYNC; + writeExpect(absent_file, "bc", 2); + readFail(absent_file, UV_EPERM); + writeExpect(empty_file, "bc", 2); + readFail(empty_file, UV_EPERM); + writeExpect(dummy_file, "abc", 3); + readFail(dummy_file, UV_EPERM); + writeFail(empty_dir, UV_EISDIR); + readFail(empty_dir, UV_EPERM); + + /* a+ */ + flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR; + writeExpect(absent_file, "bc", 2); + readExpect(absent_file, "", 0); + writeExpect(empty_file, "bc", 2); + readExpect(empty_file, "", 0); + writeExpect(dummy_file, "abc", 3); + readExpect(dummy_file, "a", 1); + writeFail(empty_dir, UV_EISDIR); + readFail(empty_dir, UV_EISDIR); + + /* ax+ */ + flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR | + UV_FS_O_EXCL; + writeExpect(absent_file, "bc", 2); + readExpect(absent_file, "", 0); + openFail(empty_file, UV_EEXIST); + openFail(dummy_file, UV_EEXIST); + openFail(empty_dir, UV_EEXIST); + + /* as+ */ + flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR | + UV_FS_O_SYNC; + writeExpect(absent_file, "bc", 2); + readExpect(absent_file, "", 0); + writeExpect(empty_file, "bc", 2); + readExpect(empty_file, "", 0); + writeExpect(dummy_file, "abc", 3); + readExpect(dummy_file, "a", 1); + writeFail(empty_dir, UV_EISDIR); + readFail(empty_dir, UV_EISDIR); +} +TEST_IMPL(fs_open_flags) { + setup(); + + fs_open_flags(0); + fs_open_flags(UV_FS_O_FILEMAP); + + /* Cleanup. */ + rmdir(empty_dir); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* ifndef _WIN32 */ diff --git a/external/src/libuv/test/test-fs-poll.c b/external/src/libuv/test/test-fs-poll.c new file mode 100644 index 0000000..76fe6fc --- /dev/null +++ b/external/src/libuv/test/test-fs-poll.c @@ -0,0 +1,300 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include + +#define FIXTURE "testfile" + +static void timer_cb(uv_timer_t* handle); +static void close_cb(uv_handle_t* handle); +static void poll_cb(uv_fs_poll_t* handle, + int status, + const uv_stat_t* prev, + const uv_stat_t* curr); + +static void poll_cb_fail(uv_fs_poll_t* handle, + int status, + const uv_stat_t* prev, + const uv_stat_t* curr); +static void poll_cb_noop(uv_fs_poll_t* handle, + int status, + const uv_stat_t* prev, + const uv_stat_t* curr); + +static uv_fs_poll_t poll_handle; +static uv_timer_t timer_handle; +static uv_loop_t* loop; + +static int poll_cb_called; +static int timer_cb_called; +static int close_cb_called; + + +static void touch_file(const char* path) { + static int count; + FILE* fp; + int i; + + ASSERT((fp = fopen(FIXTURE, "w+"))); + + /* Need to change the file size because the poller may not pick up + * sub-second mtime changes. + */ + i = ++count; + + while (i--) + fputc('*', fp); + + fclose(fp); +} + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + + +static void timer_cb(uv_timer_t* handle) { + touch_file(FIXTURE); + timer_cb_called++; +} + + +static void poll_cb_fail(uv_fs_poll_t* handle, + int status, + const uv_stat_t* prev, + const uv_stat_t* curr) { + ASSERT(0 && "fail_cb called"); +} + +static void poll_cb_noop(uv_fs_poll_t* handle, + int status, + const uv_stat_t* prev, + const uv_stat_t* curr) { +} + + +static void poll_cb(uv_fs_poll_t* handle, + int status, + const uv_stat_t* prev, + const uv_stat_t* curr) { + uv_stat_t zero_statbuf; + + memset(&zero_statbuf, 0, sizeof(zero_statbuf)); + + ASSERT(handle == &poll_handle); + ASSERT(1 == uv_is_active((uv_handle_t*) handle)); + ASSERT_NOT_NULL(prev); + ASSERT_NOT_NULL(curr); + + switch (poll_cb_called++) { + case 0: + ASSERT(status == UV_ENOENT); + ASSERT(0 == memcmp(prev, &zero_statbuf, sizeof(zero_statbuf))); + ASSERT(0 == memcmp(curr, &zero_statbuf, sizeof(zero_statbuf))); + touch_file(FIXTURE); + break; + + case 1: + ASSERT(status == 0); + ASSERT(0 == memcmp(prev, &zero_statbuf, sizeof(zero_statbuf))); + ASSERT(0 != memcmp(curr, &zero_statbuf, sizeof(zero_statbuf))); + ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 20, 0)); + break; + + case 2: + ASSERT(status == 0); + ASSERT(0 != memcmp(prev, &zero_statbuf, sizeof(zero_statbuf))); + ASSERT(0 != memcmp(curr, &zero_statbuf, sizeof(zero_statbuf))); + ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 200, 0)); + break; + + case 3: + ASSERT(status == 0); + ASSERT(0 != memcmp(prev, &zero_statbuf, sizeof(zero_statbuf))); + ASSERT(0 != memcmp(curr, &zero_statbuf, sizeof(zero_statbuf))); + remove(FIXTURE); + break; + + case 4: + ASSERT(status == UV_ENOENT); + ASSERT(0 != memcmp(prev, &zero_statbuf, sizeof(zero_statbuf))); + ASSERT(0 == memcmp(curr, &zero_statbuf, sizeof(zero_statbuf))); + uv_close((uv_handle_t*)handle, close_cb); + break; + + default: + ASSERT(0); + } +} + + +TEST_IMPL(fs_poll) { + loop = uv_default_loop(); + + remove(FIXTURE); + + ASSERT(0 == uv_timer_init(loop, &timer_handle)); + ASSERT(0 == uv_fs_poll_init(loop, &poll_handle)); + ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb, FIXTURE, 100)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + + ASSERT(poll_cb_called == 5); + ASSERT(timer_cb_called == 2); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_poll_getpath) { + char buf[1024]; + size_t len; + loop = uv_default_loop(); + + remove(FIXTURE); + + ASSERT(0 == uv_fs_poll_init(loop, &poll_handle)); + len = sizeof buf; + ASSERT(UV_EINVAL == uv_fs_poll_getpath(&poll_handle, buf, &len)); + ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100)); + len = sizeof buf; + ASSERT(0 == uv_fs_poll_getpath(&poll_handle, buf, &len)); + ASSERT(buf[len - 1] != 0); + ASSERT(buf[len] == '\0'); + ASSERT(0 == memcmp(buf, FIXTURE, len)); + + uv_close((uv_handle_t*) &poll_handle, close_cb); + + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_poll_close_request) { + uv_loop_t loop; + uv_fs_poll_t poll_handle; + + remove(FIXTURE); + + ASSERT(0 == uv_loop_init(&loop)); + + ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle)); + ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100)); + uv_close((uv_handle_t*) &poll_handle, close_cb); + while (close_cb_called == 0) + uv_run(&loop, UV_RUN_ONCE); + ASSERT(close_cb_called == 1); + + ASSERT(0 == uv_loop_close(&loop)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_poll_close_request_multi_start_stop) { + uv_loop_t loop; + uv_fs_poll_t poll_handle; + int i; + + remove(FIXTURE); + + ASSERT(0 == uv_loop_init(&loop)); + + ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle)); + + for (i = 0; i < 10; ++i) { + ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100)); + ASSERT(0 == uv_fs_poll_stop(&poll_handle)); + } + uv_close((uv_handle_t*) &poll_handle, close_cb); + while (close_cb_called == 0) + uv_run(&loop, UV_RUN_ONCE); + ASSERT(close_cb_called == 1); + + ASSERT(0 == uv_loop_close(&loop)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_poll_close_request_multi_stop_start) { + uv_loop_t loop; + uv_fs_poll_t poll_handle; + int i; + + remove(FIXTURE); + + ASSERT(0 == uv_loop_init(&loop)); + + ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle)); + + for (i = 0; i < 10; ++i) { + ASSERT(0 == uv_fs_poll_stop(&poll_handle)); + ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100)); + } + uv_close((uv_handle_t*) &poll_handle, close_cb); + while (close_cb_called == 0) + uv_run(&loop, UV_RUN_ONCE); + ASSERT(close_cb_called == 1); + + ASSERT(0 == uv_loop_close(&loop)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_poll_close_request_stop_when_active) { + /* Regression test for https://github.com/libuv/libuv/issues/2287. */ + uv_loop_t loop; + uv_fs_poll_t poll_handle; + + remove(FIXTURE); + + ASSERT(0 == uv_loop_init(&loop)); + + /* Set up all handles. */ + ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle)); + ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_noop, FIXTURE, 100)); + uv_run(&loop, UV_RUN_ONCE); + + /* Close the timer handle, and do not crash. */ + ASSERT(0 == uv_fs_poll_stop(&poll_handle)); + uv_run(&loop, UV_RUN_ONCE); + + /* Clean up after the test. */ + uv_close((uv_handle_t*) &poll_handle, close_cb); + uv_run(&loop, UV_RUN_ONCE); + ASSERT(close_cb_called == 1); + + ASSERT(0 == uv_loop_close(&loop)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-fs-readdir.c b/external/src/libuv/test/test-fs-readdir.c new file mode 100644 index 0000000..41e1d37 --- /dev/null +++ b/external/src/libuv/test/test-fs-readdir.c @@ -0,0 +1,465 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + +static uv_fs_t opendir_req; +static uv_fs_t readdir_req; +static uv_fs_t closedir_req; + +static uv_dirent_t dirents[1]; + +static int empty_opendir_cb_count; +static int empty_closedir_cb_count; + +static void cleanup_test_files(void) { + uv_fs_t req; + + uv_fs_unlink(NULL, &req, "test_dir/file1", NULL); + uv_fs_req_cleanup(&req); + uv_fs_unlink(NULL, &req, "test_dir/file2", NULL); + uv_fs_req_cleanup(&req); + uv_fs_rmdir(NULL, &req, "test_dir/test_subdir", NULL); + uv_fs_req_cleanup(&req); + uv_fs_rmdir(NULL, &req, "test_dir", NULL); + uv_fs_req_cleanup(&req); +} + +static void empty_closedir_cb(uv_fs_t* req) { + ASSERT(req == &closedir_req); + ASSERT(req->fs_type == UV_FS_CLOSEDIR); + ASSERT(req->result == 0); + ++empty_closedir_cb_count; + uv_fs_req_cleanup(req); +} + +static void empty_readdir_cb(uv_fs_t* req) { + uv_dir_t* dir; + int r; + + ASSERT(req == &readdir_req); + ASSERT(req->fs_type == UV_FS_READDIR); + ASSERT(req->result == 0); + dir = req->ptr; + uv_fs_req_cleanup(req); + r = uv_fs_closedir(uv_default_loop(), + &closedir_req, + dir, + empty_closedir_cb); + ASSERT(r == 0); +} + +static void empty_opendir_cb(uv_fs_t* req) { + uv_dir_t* dir; + int r; + + ASSERT(req == &opendir_req); + ASSERT(req->fs_type == UV_FS_OPENDIR); + ASSERT(req->result == 0); + ASSERT_NOT_NULL(req->ptr); + dir = req->ptr; + dir->dirents = dirents; + dir->nentries = ARRAY_SIZE(dirents); + r = uv_fs_readdir(uv_default_loop(), + &readdir_req, + dir, + empty_readdir_cb); + ASSERT(r == 0); + uv_fs_req_cleanup(req); + ++empty_opendir_cb_count; +} + +/* + * This test makes sure that both synchronous and asynchronous flavors + * of the uv_fs_opendir() -> uv_fs_readdir() -> uv_fs_closedir() sequence work + * as expected when processing an empty directory. + */ +TEST_IMPL(fs_readdir_empty_dir) { + const char* path; + uv_fs_t mkdir_req; + uv_fs_t rmdir_req; + int r; + int nb_entries_read; + uv_dir_t* dir; + + path = "./empty_dir/"; + uv_fs_mkdir(uv_default_loop(), &mkdir_req, path, 0777, NULL); + uv_fs_req_cleanup(&mkdir_req); + + /* Fill the req to ensure that required fields are cleaned up. */ + memset(&opendir_req, 0xdb, sizeof(opendir_req)); + + /* Testing the synchronous flavor. */ + r = uv_fs_opendir(uv_default_loop(), + &opendir_req, + path, + NULL); + ASSERT(r == 0); + ASSERT(opendir_req.fs_type == UV_FS_OPENDIR); + ASSERT(opendir_req.result == 0); + ASSERT_NOT_NULL(opendir_req.ptr); + dir = opendir_req.ptr; + uv_fs_req_cleanup(&opendir_req); + + /* Fill the req to ensure that required fields are cleaned up. */ + memset(&readdir_req, 0xdb, sizeof(readdir_req)); + dir->dirents = dirents; + dir->nentries = ARRAY_SIZE(dirents); + nb_entries_read = uv_fs_readdir(uv_default_loop(), + &readdir_req, + dir, + NULL); + ASSERT(nb_entries_read == 0); + uv_fs_req_cleanup(&readdir_req); + + /* Fill the req to ensure that required fields are cleaned up. */ + memset(&closedir_req, 0xdb, sizeof(closedir_req)); + uv_fs_closedir(uv_default_loop(), &closedir_req, dir, NULL); + ASSERT(closedir_req.result == 0); + uv_fs_req_cleanup(&closedir_req); + + /* Testing the asynchronous flavor. */ + + /* Fill the req to ensure that required fields are cleaned up. */ + memset(&opendir_req, 0xdb, sizeof(opendir_req)); + memset(&readdir_req, 0xdb, sizeof(readdir_req)); + memset(&closedir_req, 0xdb, sizeof(closedir_req)); + + r = uv_fs_opendir(uv_default_loop(), &opendir_req, path, empty_opendir_cb); + ASSERT(r == 0); + ASSERT(empty_opendir_cb_count == 0); + ASSERT(empty_closedir_cb_count == 0); + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + ASSERT(empty_opendir_cb_count == 1); + ASSERT(empty_closedir_cb_count == 1); + uv_fs_rmdir(uv_default_loop(), &rmdir_req, path, NULL); + uv_fs_req_cleanup(&rmdir_req); + MAKE_VALGRIND_HAPPY(); + return 0; +} + +/* + * This test makes sure that reading a non-existing directory with + * uv_fs_{open,read}_dir() returns proper error codes. + */ + +static int non_existing_opendir_cb_count; + +static void non_existing_opendir_cb(uv_fs_t* req) { + ASSERT(req == &opendir_req); + ASSERT(req->fs_type == UV_FS_OPENDIR); + ASSERT(req->result == UV_ENOENT); + ASSERT_NULL(req->ptr); + + uv_fs_req_cleanup(req); + ++non_existing_opendir_cb_count; +} + +TEST_IMPL(fs_readdir_non_existing_dir) { + const char* path; + int r; + + path = "./non-existing-dir/"; + + /* Fill the req to ensure that required fields are cleaned up. */ + memset(&opendir_req, 0xdb, sizeof(opendir_req)); + + /* Testing the synchronous flavor. */ + r = uv_fs_opendir(uv_default_loop(), &opendir_req, path, NULL); + ASSERT(r == UV_ENOENT); + ASSERT(opendir_req.fs_type == UV_FS_OPENDIR); + ASSERT(opendir_req.result == UV_ENOENT); + ASSERT_NULL(opendir_req.ptr); + uv_fs_req_cleanup(&opendir_req); + + /* Fill the req to ensure that required fields are cleaned up. */ + memset(&opendir_req, 0xdb, sizeof(opendir_req)); + + /* Testing the async flavor. */ + r = uv_fs_opendir(uv_default_loop(), + &opendir_req, + path, + non_existing_opendir_cb); + ASSERT(r == 0); + ASSERT(non_existing_opendir_cb_count == 0); + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + ASSERT(non_existing_opendir_cb_count == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +/* + * This test makes sure that reading a file as a directory reports correct + * error codes. + */ + +static int file_opendir_cb_count; + +static void file_opendir_cb(uv_fs_t* req) { + ASSERT(req == &opendir_req); + ASSERT(req->fs_type == UV_FS_OPENDIR); + ASSERT(req->result == UV_ENOTDIR); + ASSERT_NULL(req->ptr); + + uv_fs_req_cleanup(req); + ++file_opendir_cb_count; +} + +TEST_IMPL(fs_readdir_file) { +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); +#endif + const char* path; + int r; + + path = "test/fixtures/empty_file"; + + /* Fill the req to ensure that required fields are cleaned up. */ + memset(&opendir_req, 0xdb, sizeof(opendir_req)); + + /* Testing the synchronous flavor. */ + r = uv_fs_opendir(uv_default_loop(), &opendir_req, path, NULL); + + ASSERT(r == UV_ENOTDIR); + ASSERT(opendir_req.fs_type == UV_FS_OPENDIR); + ASSERT(opendir_req.result == UV_ENOTDIR); + ASSERT_NULL(opendir_req.ptr); + + uv_fs_req_cleanup(&opendir_req); + + /* Fill the req to ensure that required fields are cleaned up. */ + memset(&opendir_req, 0xdb, sizeof(opendir_req)); + + /* Testing the async flavor. */ + r = uv_fs_opendir(uv_default_loop(), &opendir_req, path, file_opendir_cb); + ASSERT(r == 0); + ASSERT(file_opendir_cb_count == 0); + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + ASSERT(file_opendir_cb_count == 1); + MAKE_VALGRIND_HAPPY(); + return 0; +} + +/* + * This test makes sure that reading a non-empty directory with + * uv_fs_{open,read}_dir() returns proper directory entries, including the + * correct entry types. + */ + +static int non_empty_opendir_cb_count; +static int non_empty_readdir_cb_count; +static int non_empty_closedir_cb_count; + +static void non_empty_closedir_cb(uv_fs_t* req) { + ASSERT(req == &closedir_req); + ASSERT(req->result == 0); + uv_fs_req_cleanup(req); + ++non_empty_closedir_cb_count; +} + +static void non_empty_readdir_cb(uv_fs_t* req) { + uv_dir_t* dir; + + ASSERT(req == &readdir_req); + ASSERT(req->fs_type == UV_FS_READDIR); + dir = req->ptr; + + if (req->result == 0) { + uv_fs_req_cleanup(req); + ASSERT(non_empty_readdir_cb_count == 3); + uv_fs_closedir(uv_default_loop(), + &closedir_req, + dir, + non_empty_closedir_cb); + } else { + ASSERT(req->result == 1); + ASSERT(dir->dirents == dirents); + ASSERT(strcmp(dirents[0].name, "file1") == 0 || + strcmp(dirents[0].name, "file2") == 0 || + strcmp(dirents[0].name, "test_subdir") == 0); +#ifdef HAVE_DIRENT_TYPES + if (!strcmp(dirents[0].name, "test_subdir")) + ASSERT(dirents[0].type == UV_DIRENT_DIR); + else + ASSERT(dirents[0].type == UV_DIRENT_FILE); +#else + ASSERT(dirents[0].type == UV_DIRENT_UNKNOWN); +#endif /* HAVE_DIRENT_TYPES */ + + ++non_empty_readdir_cb_count; + uv_fs_req_cleanup(req); + dir->dirents = dirents; + dir->nentries = ARRAY_SIZE(dirents); + uv_fs_readdir(uv_default_loop(), + &readdir_req, + dir, + non_empty_readdir_cb); + } +} + +static void non_empty_opendir_cb(uv_fs_t* req) { + uv_dir_t* dir; + int r; + + ASSERT(req == &opendir_req); + ASSERT(req->fs_type == UV_FS_OPENDIR); + ASSERT(req->result == 0); + ASSERT_NOT_NULL(req->ptr); + + dir = req->ptr; + dir->dirents = dirents; + dir->nentries = ARRAY_SIZE(dirents); + + r = uv_fs_readdir(uv_default_loop(), + &readdir_req, + dir, + non_empty_readdir_cb); + ASSERT(r == 0); + uv_fs_req_cleanup(req); + ++non_empty_opendir_cb_count; +} + +TEST_IMPL(fs_readdir_non_empty_dir) { + size_t entries_count; + uv_fs_t mkdir_req; + uv_fs_t rmdir_req; + uv_fs_t create_req; + uv_fs_t close_req; + uv_dir_t* dir; + int r; + + cleanup_test_files(); + + r = uv_fs_mkdir(uv_default_loop(), &mkdir_req, "test_dir", 0755, NULL); + ASSERT(r == 0); + + /* Create two files synchronously. */ + r = uv_fs_open(uv_default_loop(), + &create_req, + "test_dir/file1", + O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + uv_fs_req_cleanup(&create_req); + r = uv_fs_close(uv_default_loop(), + &close_req, + create_req.result, + NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_open(uv_default_loop(), + &create_req, + "test_dir/file2", + O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + uv_fs_req_cleanup(&create_req); + r = uv_fs_close(uv_default_loop(), + &close_req, + create_req.result, + NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_mkdir(uv_default_loop(), + &mkdir_req, + "test_dir/test_subdir", + 0755, + NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&mkdir_req); + + /* Fill the req to ensure that required fields are cleaned up. */ + memset(&opendir_req, 0xdb, sizeof(opendir_req)); + + /* Testing the synchronous flavor. */ + r = uv_fs_opendir(uv_default_loop(), &opendir_req, "test_dir", NULL); + ASSERT(r == 0); + ASSERT(opendir_req.fs_type == UV_FS_OPENDIR); + ASSERT(opendir_req.result == 0); + ASSERT_NOT_NULL(opendir_req.ptr); + + entries_count = 0; + dir = opendir_req.ptr; + dir->dirents = dirents; + dir->nentries = ARRAY_SIZE(dirents); + uv_fs_req_cleanup(&opendir_req); + + while (uv_fs_readdir(uv_default_loop(), + &readdir_req, + dir, + NULL) != 0) { + ASSERT(strcmp(dirents[0].name, "file1") == 0 || + strcmp(dirents[0].name, "file2") == 0 || + strcmp(dirents[0].name, "test_subdir") == 0); +#ifdef HAVE_DIRENT_TYPES + if (!strcmp(dirents[0].name, "test_subdir")) + ASSERT(dirents[0].type == UV_DIRENT_DIR); + else + ASSERT(dirents[0].type == UV_DIRENT_FILE); +#else + ASSERT(dirents[0].type == UV_DIRENT_UNKNOWN); +#endif /* HAVE_DIRENT_TYPES */ + uv_fs_req_cleanup(&readdir_req); + ++entries_count; + } + + ASSERT(entries_count == 3); + uv_fs_req_cleanup(&readdir_req); + + /* Fill the req to ensure that required fields are cleaned up. */ + memset(&closedir_req, 0xdb, sizeof(closedir_req)); + uv_fs_closedir(uv_default_loop(), &closedir_req, dir, NULL); + ASSERT(closedir_req.result == 0); + uv_fs_req_cleanup(&closedir_req); + + /* Testing the asynchronous flavor. */ + + /* Fill the req to ensure that required fields are cleaned up. */ + memset(&opendir_req, 0xdb, sizeof(opendir_req)); + + r = uv_fs_opendir(uv_default_loop(), + &opendir_req, + "test_dir", + non_empty_opendir_cb); + ASSERT(r == 0); + ASSERT(non_empty_opendir_cb_count == 0); + ASSERT(non_empty_closedir_cb_count == 0); + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + ASSERT(non_empty_opendir_cb_count == 1); + ASSERT(non_empty_closedir_cb_count == 1); + + uv_fs_rmdir(uv_default_loop(), &rmdir_req, "test_subdir", NULL); + uv_fs_req_cleanup(&rmdir_req); + + cleanup_test_files(); + MAKE_VALGRIND_HAPPY(); + return 0; + } diff --git a/external/src/libuv/test/test-fs.c b/external/src/libuv/test/test-fs.c new file mode 100644 index 0000000..034c971 --- /dev/null +++ b/external/src/libuv/test/test-fs.c @@ -0,0 +1,4484 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include /* memset */ +#include +#include +#include /* INT_MAX, PATH_MAX, IOV_MAX */ + +#ifndef _WIN32 +# include /* unlink, rmdir, etc. */ +#else +# include +# include +# include +# ifndef ERROR_SYMLINK_NOT_SUPPORTED +# define ERROR_SYMLINK_NOT_SUPPORTED 1464 +# endif +# define unlink _unlink +# define rmdir _rmdir +# define open _open +# define write _write +# define close _close +# ifndef stat +# define stat _stati64 +# endif +# ifndef lseek +# define lseek _lseek +# endif +#endif + +#define TOO_LONG_NAME_LENGTH 65536 +#define PATHMAX 4096 + +typedef struct { + const char* path; + double atime; + double mtime; +} utime_check_t; + + +static int dummy_cb_count; +static int close_cb_count; +static int create_cb_count; +static int open_cb_count; +static int read_cb_count; +static int write_cb_count; +static int unlink_cb_count; +static int mkdir_cb_count; +static int mkdtemp_cb_count; +static int mkstemp_cb_count; +static int rmdir_cb_count; +static int scandir_cb_count; +static int stat_cb_count; +static int rename_cb_count; +static int fsync_cb_count; +static int fdatasync_cb_count; +static int ftruncate_cb_count; +static int sendfile_cb_count; +static int fstat_cb_count; +static int access_cb_count; +static int chmod_cb_count; +static int fchmod_cb_count; +static int chown_cb_count; +static int fchown_cb_count; +static int lchown_cb_count; +static int link_cb_count; +static int symlink_cb_count; +static int readlink_cb_count; +static int realpath_cb_count; +static int utime_cb_count; +static int futime_cb_count; +static int lutime_cb_count; +static int statfs_cb_count; + +static uv_loop_t* loop; + +static uv_fs_t open_req1; +static uv_fs_t open_req2; +static uv_fs_t read_req; +static uv_fs_t write_req; +static uv_fs_t unlink_req; +static uv_fs_t close_req; +static uv_fs_t mkdir_req; +static uv_fs_t mkdtemp_req1; +static uv_fs_t mkdtemp_req2; +static uv_fs_t mkstemp_req1; +static uv_fs_t mkstemp_req2; +static uv_fs_t mkstemp_req3; +static uv_fs_t rmdir_req; +static uv_fs_t scandir_req; +static uv_fs_t stat_req; +static uv_fs_t rename_req; +static uv_fs_t fsync_req; +static uv_fs_t fdatasync_req; +static uv_fs_t ftruncate_req; +static uv_fs_t sendfile_req; +static uv_fs_t utime_req; +static uv_fs_t futime_req; + +static char buf[32]; +static char buf2[32]; +static char test_buf[] = "test-buffer\n"; +static char test_buf2[] = "second-buffer\n"; +static uv_buf_t iov; + +#ifdef _WIN32 +int uv_test_getiovmax(void) { + return INT32_MAX; /* Emulated by libuv, so no real limit. */ +} +#else +int uv_test_getiovmax(void) { +#if defined(IOV_MAX) + return IOV_MAX; +#elif defined(_SC_IOV_MAX) + static int iovmax = -1; + if (iovmax == -1) { + iovmax = sysconf(_SC_IOV_MAX); + /* On some embedded devices (arm-linux-uclibc based ip camera), + * sysconf(_SC_IOV_MAX) can not get the correct value. The return + * value is -1 and the errno is EINPROGRESS. Degrade the value to 1. + */ + if (iovmax == -1) iovmax = 1; + } + return iovmax; +#else + return 1024; +#endif +} +#endif + +#ifdef _WIN32 +/* + * This tag and guid have no special meaning, and don't conflict with + * reserved ids. +*/ +static unsigned REPARSE_TAG = 0x9913; +static GUID REPARSE_GUID = { + 0x1bf6205f, 0x46ae, 0x4527, + { 0xb1, 0x0c, 0xc5, 0x09, 0xb7, 0x55, 0x22, 0x80 }}; +#endif + +static void check_permission(const char* filename, unsigned int mode) { + int r; + uv_fs_t req; + uv_stat_t* s; + + r = uv_fs_stat(NULL, &req, filename, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + + s = &req.statbuf; +#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MSYS__) + /* + * On Windows, chmod can only modify S_IWUSR (_S_IWRITE) bit, + * so only testing for the specified flags. + */ + ASSERT((s->st_mode & 0777) & mode); +#else + ASSERT((s->st_mode & 0777) == mode); +#endif + + uv_fs_req_cleanup(&req); +} + + +static void dummy_cb(uv_fs_t* req) { + (void) req; + dummy_cb_count++; +} + + +static void link_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_LINK); + ASSERT(req->result == 0); + link_cb_count++; + uv_fs_req_cleanup(req); +} + + +static void symlink_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_SYMLINK); + ASSERT(req->result == 0); + symlink_cb_count++; + uv_fs_req_cleanup(req); +} + +static void readlink_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_READLINK); + ASSERT(req->result == 0); + ASSERT(strcmp(req->ptr, "test_file_symlink2") == 0); + readlink_cb_count++; + uv_fs_req_cleanup(req); +} + + +static void realpath_cb(uv_fs_t* req) { + char test_file_abs_buf[PATHMAX]; + size_t test_file_abs_size = sizeof(test_file_abs_buf); + ASSERT(req->fs_type == UV_FS_REALPATH); +#ifdef _WIN32 + /* + * Windows XP and Server 2003 don't support GetFinalPathNameByHandleW() + */ + if (req->result == UV_ENOSYS) { + realpath_cb_count++; + uv_fs_req_cleanup(req); + return; + } +#endif + ASSERT(req->result == 0); + + uv_cwd(test_file_abs_buf, &test_file_abs_size); +#ifdef _WIN32 + strcat(test_file_abs_buf, "\\test_file"); + ASSERT(stricmp(req->ptr, test_file_abs_buf) == 0); +#else + strcat(test_file_abs_buf, "/test_file"); + ASSERT(strcmp(req->ptr, test_file_abs_buf) == 0); +#endif + realpath_cb_count++; + uv_fs_req_cleanup(req); +} + + +static void access_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_ACCESS); + access_cb_count++; + uv_fs_req_cleanup(req); +} + + +static void fchmod_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_FCHMOD); + ASSERT(req->result == 0); + fchmod_cb_count++; + uv_fs_req_cleanup(req); + check_permission("test_file", *(int*)req->data); +} + + +static void chmod_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_CHMOD); + ASSERT(req->result == 0); + chmod_cb_count++; + uv_fs_req_cleanup(req); + check_permission("test_file", *(int*)req->data); +} + + +static void fchown_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_FCHOWN); + ASSERT(req->result == 0); + fchown_cb_count++; + uv_fs_req_cleanup(req); +} + + +static void chown_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_CHOWN); + ASSERT(req->result == 0); + chown_cb_count++; + uv_fs_req_cleanup(req); +} + +static void lchown_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_LCHOWN); + ASSERT(req->result == 0); + lchown_cb_count++; + uv_fs_req_cleanup(req); +} + +static void chown_root_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_CHOWN); +#if defined(_WIN32) || defined(__MSYS__) + /* On windows, chown is a no-op and always succeeds. */ + ASSERT(req->result == 0); +#else + /* On unix, chown'ing the root directory is not allowed - + * unless you're root, of course. + */ + if (geteuid() == 0) + ASSERT(req->result == 0); + else +# if defined(__CYGWIN__) + /* On Cygwin, uid 0 is invalid (no root). */ + ASSERT(req->result == UV_EINVAL); +# elif defined(__PASE__) + /* On IBMi PASE, there is no root user. uid 0 is user qsecofr. + * User may grant qsecofr's privileges, including changing + * the file's ownership to uid 0. + */ + ASSERT(req->result == 0 || req->result == UV_EPERM); +# else + ASSERT(req->result == UV_EPERM); +# endif +#endif + chown_cb_count++; + uv_fs_req_cleanup(req); +} + +static void unlink_cb(uv_fs_t* req) { + ASSERT(req == &unlink_req); + ASSERT(req->fs_type == UV_FS_UNLINK); + ASSERT(req->result == 0); + unlink_cb_count++; + uv_fs_req_cleanup(req); +} + +static void fstat_cb(uv_fs_t* req) { + uv_stat_t* s = req->ptr; + ASSERT(req->fs_type == UV_FS_FSTAT); + ASSERT(req->result == 0); + ASSERT(s->st_size == sizeof(test_buf)); + uv_fs_req_cleanup(req); + fstat_cb_count++; +} + + +static void statfs_cb(uv_fs_t* req) { + uv_statfs_t* stats; + + ASSERT(req->fs_type == UV_FS_STATFS); + ASSERT(req->result == 0); + ASSERT_NOT_NULL(req->ptr); + stats = req->ptr; + +#if defined(_WIN32) || defined(__sun) || defined(_AIX) || defined(__MVS__) || \ + defined(__OpenBSD__) || defined(__NetBSD__) + ASSERT(stats->f_type == 0); +#else + ASSERT(stats->f_type > 0); +#endif + + ASSERT(stats->f_bsize > 0); + ASSERT(stats->f_blocks > 0); + ASSERT(stats->f_bfree <= stats->f_blocks); + ASSERT(stats->f_bavail <= stats->f_bfree); + +#ifdef _WIN32 + ASSERT(stats->f_files == 0); + ASSERT(stats->f_ffree == 0); +#else + /* There is no assertion for stats->f_files that makes sense, so ignore it. */ + ASSERT(stats->f_ffree <= stats->f_files); +#endif + uv_fs_req_cleanup(req); + ASSERT_NULL(req->ptr); + statfs_cb_count++; +} + + +static void close_cb(uv_fs_t* req) { + int r; + ASSERT(req == &close_req); + ASSERT(req->fs_type == UV_FS_CLOSE); + ASSERT(req->result == 0); + close_cb_count++; + uv_fs_req_cleanup(req); + if (close_cb_count == 3) { + r = uv_fs_unlink(loop, &unlink_req, "test_file2", unlink_cb); + ASSERT(r == 0); + } +} + + +static void ftruncate_cb(uv_fs_t* req) { + int r; + ASSERT(req == &ftruncate_req); + ASSERT(req->fs_type == UV_FS_FTRUNCATE); + ASSERT(req->result == 0); + ftruncate_cb_count++; + uv_fs_req_cleanup(req); + r = uv_fs_close(loop, &close_req, open_req1.result, close_cb); + ASSERT(r == 0); +} + +static void fail_cb(uv_fs_t* req) { + FATAL("fail_cb should not have been called"); +} + +static void read_cb(uv_fs_t* req) { + int r; + ASSERT(req == &read_req); + ASSERT(req->fs_type == UV_FS_READ); + ASSERT(req->result >= 0); /* FIXME(bnoordhuis) Check if requested size? */ + read_cb_count++; + uv_fs_req_cleanup(req); + if (read_cb_count == 1) { + ASSERT(strcmp(buf, test_buf) == 0); + r = uv_fs_ftruncate(loop, &ftruncate_req, open_req1.result, 7, + ftruncate_cb); + } else { + ASSERT(strcmp(buf, "test-bu") == 0); + r = uv_fs_close(loop, &close_req, open_req1.result, close_cb); + } + ASSERT(r == 0); +} + + +static void open_cb(uv_fs_t* req) { + int r; + ASSERT(req == &open_req1); + ASSERT(req->fs_type == UV_FS_OPEN); + if (req->result < 0) { + fprintf(stderr, "async open error: %d\n", (int) req->result); + ASSERT(0); + } + open_cb_count++; + ASSERT(req->path); + ASSERT(memcmp(req->path, "test_file2\0", 11) == 0); + uv_fs_req_cleanup(req); + memset(buf, 0, sizeof(buf)); + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1, -1, + read_cb); + ASSERT(r == 0); +} + + +static void open_cb_simple(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_OPEN); + if (req->result < 0) { + fprintf(stderr, "async open error: %d\n", (int) req->result); + ASSERT(0); + } + open_cb_count++; + ASSERT(req->path); + uv_fs_req_cleanup(req); +} + + +static void fsync_cb(uv_fs_t* req) { + int r; + ASSERT(req == &fsync_req); + ASSERT(req->fs_type == UV_FS_FSYNC); + ASSERT(req->result == 0); + fsync_cb_count++; + uv_fs_req_cleanup(req); + r = uv_fs_close(loop, &close_req, open_req1.result, close_cb); + ASSERT(r == 0); +} + + +static void fdatasync_cb(uv_fs_t* req) { + int r; + ASSERT(req == &fdatasync_req); + ASSERT(req->fs_type == UV_FS_FDATASYNC); + ASSERT(req->result == 0); + fdatasync_cb_count++; + uv_fs_req_cleanup(req); + r = uv_fs_fsync(loop, &fsync_req, open_req1.result, fsync_cb); + ASSERT(r == 0); +} + + +static void write_cb(uv_fs_t* req) { + int r; + ASSERT(req == &write_req); + ASSERT(req->fs_type == UV_FS_WRITE); + ASSERT(req->result >= 0); /* FIXME(bnoordhuis) Check if requested size? */ + write_cb_count++; + uv_fs_req_cleanup(req); + r = uv_fs_fdatasync(loop, &fdatasync_req, open_req1.result, fdatasync_cb); + ASSERT(r == 0); +} + + +static void create_cb(uv_fs_t* req) { + int r; + ASSERT(req == &open_req1); + ASSERT(req->fs_type == UV_FS_OPEN); + ASSERT(req->result >= 0); + create_cb_count++; + uv_fs_req_cleanup(req); + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(loop, &write_req, req->result, &iov, 1, -1, write_cb); + ASSERT(r == 0); +} + + +static void rename_cb(uv_fs_t* req) { + ASSERT(req == &rename_req); + ASSERT(req->fs_type == UV_FS_RENAME); + ASSERT(req->result == 0); + rename_cb_count++; + uv_fs_req_cleanup(req); +} + + +static void mkdir_cb(uv_fs_t* req) { + ASSERT(req == &mkdir_req); + ASSERT(req->fs_type == UV_FS_MKDIR); + ASSERT(req->result == 0); + mkdir_cb_count++; + ASSERT(req->path); + ASSERT(memcmp(req->path, "test_dir\0", 9) == 0); + uv_fs_req_cleanup(req); +} + + +static void check_mkdtemp_result(uv_fs_t* req) { + int r; + + ASSERT(req->fs_type == UV_FS_MKDTEMP); + ASSERT(req->result == 0); + ASSERT(req->path); + ASSERT(strlen(req->path) == 15); + ASSERT(memcmp(req->path, "test_dir_", 9) == 0); + ASSERT(memcmp(req->path + 9, "XXXXXX", 6) != 0); + check_permission(req->path, 0700); + + /* Check if req->path is actually a directory */ + r = uv_fs_stat(NULL, &stat_req, req->path, NULL); + ASSERT(r == 0); + ASSERT(((uv_stat_t*)stat_req.ptr)->st_mode & S_IFDIR); + uv_fs_req_cleanup(&stat_req); +} + + +static void mkdtemp_cb(uv_fs_t* req) { + ASSERT(req == &mkdtemp_req1); + check_mkdtemp_result(req); + mkdtemp_cb_count++; +} + + +static void check_mkstemp_result(uv_fs_t* req) { + int r; + + ASSERT(req->fs_type == UV_FS_MKSTEMP); + ASSERT(req->result >= 0); + ASSERT(req->path); + ASSERT(strlen(req->path) == 16); + ASSERT(memcmp(req->path, "test_file_", 10) == 0); + ASSERT(memcmp(req->path + 10, "XXXXXX", 6) != 0); + check_permission(req->path, 0600); + + /* Check if req->path is actually a file */ + r = uv_fs_stat(NULL, &stat_req, req->path, NULL); + ASSERT(r == 0); + ASSERT(stat_req.statbuf.st_mode & S_IFREG); + uv_fs_req_cleanup(&stat_req); +} + + +static void mkstemp_cb(uv_fs_t* req) { + ASSERT(req == &mkstemp_req1); + check_mkstemp_result(req); + mkstemp_cb_count++; +} + + +static void rmdir_cb(uv_fs_t* req) { + ASSERT(req == &rmdir_req); + ASSERT(req->fs_type == UV_FS_RMDIR); + ASSERT(req->result == 0); + rmdir_cb_count++; + ASSERT(req->path); + ASSERT(memcmp(req->path, "test_dir\0", 9) == 0); + uv_fs_req_cleanup(req); +} + + +static void assert_is_file_type(uv_dirent_t dent) { +#ifdef HAVE_DIRENT_TYPES + /* + * For Apple and Windows, we know getdents is expected to work but for other + * environments, the filesystem dictates whether or not getdents supports + * returning the file type. + * + * See: + * http://man7.org/linux/man-pages/man2/getdents.2.html + * https://github.com/libuv/libuv/issues/501 + */ + #if defined(__APPLE__) || defined(_WIN32) + ASSERT(dent.type == UV_DIRENT_FILE); + #else + ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN); + #endif +#else + ASSERT(dent.type == UV_DIRENT_UNKNOWN); +#endif +} + + +static void scandir_cb(uv_fs_t* req) { + uv_dirent_t dent; + ASSERT(req == &scandir_req); + ASSERT(req->fs_type == UV_FS_SCANDIR); + ASSERT(req->result == 2); + ASSERT(req->ptr); + + while (UV_EOF != uv_fs_scandir_next(req, &dent)) { + ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); + assert_is_file_type(dent); + } + scandir_cb_count++; + ASSERT(req->path); + ASSERT(memcmp(req->path, "test_dir\0", 9) == 0); + uv_fs_req_cleanup(req); + ASSERT(!req->ptr); +} + + +static void empty_scandir_cb(uv_fs_t* req) { + uv_dirent_t dent; + + ASSERT(req == &scandir_req); + ASSERT(req->fs_type == UV_FS_SCANDIR); + ASSERT(req->result == 0); + ASSERT_NULL(req->ptr); + ASSERT(UV_EOF == uv_fs_scandir_next(req, &dent)); + uv_fs_req_cleanup(req); + scandir_cb_count++; +} + +static void non_existent_scandir_cb(uv_fs_t* req) { + uv_dirent_t dent; + + ASSERT(req == &scandir_req); + ASSERT(req->fs_type == UV_FS_SCANDIR); + ASSERT(req->result == UV_ENOENT); + ASSERT_NULL(req->ptr); + ASSERT(UV_ENOENT == uv_fs_scandir_next(req, &dent)); + uv_fs_req_cleanup(req); + scandir_cb_count++; +} + + +static void file_scandir_cb(uv_fs_t* req) { + ASSERT(req == &scandir_req); + ASSERT(req->fs_type == UV_FS_SCANDIR); + ASSERT(req->result == UV_ENOTDIR); + ASSERT_NULL(req->ptr); + uv_fs_req_cleanup(req); + scandir_cb_count++; +} + + +static void stat_cb(uv_fs_t* req) { + ASSERT(req == &stat_req); + ASSERT(req->fs_type == UV_FS_STAT || req->fs_type == UV_FS_LSTAT); + ASSERT(req->result == 0); + ASSERT(req->ptr); + stat_cb_count++; + uv_fs_req_cleanup(req); + ASSERT(!req->ptr); +} + + +static void sendfile_cb(uv_fs_t* req) { + ASSERT(req == &sendfile_req); + ASSERT(req->fs_type == UV_FS_SENDFILE); + ASSERT(req->result == 65545); + sendfile_cb_count++; + uv_fs_req_cleanup(req); +} + + +static void sendfile_nodata_cb(uv_fs_t* req) { + ASSERT(req == &sendfile_req); + ASSERT(req->fs_type == UV_FS_SENDFILE); + ASSERT(req->result == 0); + sendfile_cb_count++; + uv_fs_req_cleanup(req); +} + + +static void open_noent_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_OPEN); + ASSERT(req->result == UV_ENOENT); + open_cb_count++; + uv_fs_req_cleanup(req); +} + +static void open_nametoolong_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_OPEN); + ASSERT(req->result == UV_ENAMETOOLONG); + open_cb_count++; + uv_fs_req_cleanup(req); +} + +static void open_loop_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_OPEN); + ASSERT(req->result == UV_ELOOP); + open_cb_count++; + uv_fs_req_cleanup(req); +} + + +TEST_IMPL(fs_file_noent) { + uv_fs_t req; + int r; + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, &req, "does_not_exist", O_RDONLY, 0, NULL); + ASSERT(r == UV_ENOENT); + ASSERT(req.result == UV_ENOENT); + uv_fs_req_cleanup(&req); + + r = uv_fs_open(loop, &req, "does_not_exist", O_RDONLY, 0, open_noent_cb); + ASSERT(r == 0); + + ASSERT(open_cb_count == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(open_cb_count == 1); + + /* TODO add EACCES test */ + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_file_nametoolong) { + uv_fs_t req; + int r; + char name[TOO_LONG_NAME_LENGTH + 1]; + + loop = uv_default_loop(); + + memset(name, 'a', TOO_LONG_NAME_LENGTH); + name[TOO_LONG_NAME_LENGTH] = 0; + + r = uv_fs_open(NULL, &req, name, O_RDONLY, 0, NULL); + ASSERT(r == UV_ENAMETOOLONG); + ASSERT(req.result == UV_ENAMETOOLONG); + uv_fs_req_cleanup(&req); + + r = uv_fs_open(loop, &req, name, O_RDONLY, 0, open_nametoolong_cb); + ASSERT(r == 0); + + ASSERT(open_cb_count == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(open_cb_count == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_file_loop) { + uv_fs_t req; + int r; + + loop = uv_default_loop(); + + unlink("test_symlink"); + r = uv_fs_symlink(NULL, &req, "test_symlink", "test_symlink", 0, NULL); +#ifdef _WIN32 + /* + * Windows XP and Server 2003 don't support symlinks; we'll get UV_ENOTSUP. + * Starting with vista they are supported, but only when elevated, otherwise + * we'll see UV_EPERM. + */ + if (r == UV_ENOTSUP || r == UV_EPERM) + return 0; +#elif defined(__MSYS__) + /* MSYS2's approximation of symlinks with copies does not work for broken + links. */ + if (r == UV_ENOENT) + return 0; +#endif + ASSERT(r == 0); + uv_fs_req_cleanup(&req); + + r = uv_fs_open(NULL, &req, "test_symlink", O_RDONLY, 0, NULL); + ASSERT(r == UV_ELOOP); + ASSERT(req.result == UV_ELOOP); + uv_fs_req_cleanup(&req); + + r = uv_fs_open(loop, &req, "test_symlink", O_RDONLY, 0, open_loop_cb); + ASSERT(r == 0); + + ASSERT(open_cb_count == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(open_cb_count == 1); + + unlink("test_symlink"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +static void check_utime(const char* path, + double atime, + double mtime, + int test_lutime) { + uv_stat_t* s; + uv_fs_t req; + int r; + + if (test_lutime) + r = uv_fs_lstat(loop, &req, path, NULL); + else + r = uv_fs_stat(loop, &req, path, NULL); + + ASSERT_EQ(r, 0); + + ASSERT_EQ(req.result, 0); + s = &req.statbuf; + + if (s->st_atim.tv_nsec == 0 && s->st_mtim.tv_nsec == 0) { + /* + * Test sub-second timestamps only when supported (such as Windows with + * NTFS). Some other platforms support sub-second timestamps, but that + * support is filesystem-dependent. Notably OS X (HFS Plus) does NOT + * support sub-second timestamps. But kernels may round or truncate in + * either direction, so we may accept either possible answer. + */ +#ifdef _WIN32 + ASSERT_DOUBLE_EQ(atime, (long) atime); + ASSERT_DOUBLE_EQ(mtime, (long) atime); +#endif + if (atime > 0 || (long) atime == atime) + ASSERT_EQ(s->st_atim.tv_sec, (long) atime); + if (mtime > 0 || (long) mtime == mtime) + ASSERT_EQ(s->st_mtim.tv_sec, (long) mtime); + ASSERT_GE(s->st_atim.tv_sec, (long) atime - 1); + ASSERT_GE(s->st_mtim.tv_sec, (long) mtime - 1); + ASSERT_LE(s->st_atim.tv_sec, (long) atime); + ASSERT_LE(s->st_mtim.tv_sec, (long) mtime); + } else { + double st_atim; + double st_mtim; +#ifndef __APPLE__ + /* TODO(vtjnash): would it be better to normalize this? */ + ASSERT_DOUBLE_GE(s->st_atim.tv_nsec, 0); + ASSERT_DOUBLE_GE(s->st_mtim.tv_nsec, 0); +#endif + st_atim = s->st_atim.tv_sec + s->st_atim.tv_nsec / 1e9; + st_mtim = s->st_mtim.tv_sec + s->st_mtim.tv_nsec / 1e9; + ASSERT_DOUBLE_EQ(st_atim, atime); + ASSERT_DOUBLE_EQ(st_mtim, mtime); + } + + uv_fs_req_cleanup(&req); +} + + +static void utime_cb(uv_fs_t* req) { + utime_check_t* c; + + ASSERT(req == &utime_req); + ASSERT(req->result == 0); + ASSERT(req->fs_type == UV_FS_UTIME); + + c = req->data; + check_utime(c->path, c->atime, c->mtime, /* test_lutime */ 0); + + uv_fs_req_cleanup(req); + utime_cb_count++; +} + + +static void futime_cb(uv_fs_t* req) { + utime_check_t* c; + + ASSERT(req == &futime_req); + ASSERT(req->result == 0); + ASSERT(req->fs_type == UV_FS_FUTIME); + + c = req->data; + check_utime(c->path, c->atime, c->mtime, /* test_lutime */ 0); + + uv_fs_req_cleanup(req); + futime_cb_count++; +} + + +static void lutime_cb(uv_fs_t* req) { + utime_check_t* c; + + ASSERT(req->result == 0); + ASSERT(req->fs_type == UV_FS_LUTIME); + + c = req->data; + check_utime(c->path, c->atime, c->mtime, /* test_lutime */ 1); + + uv_fs_req_cleanup(req); + lutime_cb_count++; +} + + +TEST_IMPL(fs_file_async) { + int r; + + /* Setup. */ + unlink("test_file"); + unlink("test_file2"); + + loop = uv_default_loop(); + + r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT, + S_IRUSR | S_IWUSR, create_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(create_cb_count == 1); + ASSERT(write_cb_count == 1); + ASSERT(fsync_cb_count == 1); + ASSERT(fdatasync_cb_count == 1); + ASSERT(close_cb_count == 1); + + r = uv_fs_rename(loop, &rename_req, "test_file", "test_file2", rename_cb); + ASSERT(r == 0); + + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(create_cb_count == 1); + ASSERT(write_cb_count == 1); + ASSERT(close_cb_count == 1); + ASSERT(rename_cb_count == 1); + + r = uv_fs_open(loop, &open_req1, "test_file2", O_RDWR, 0, open_cb); + ASSERT(r == 0); + + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(open_cb_count == 1); + ASSERT(read_cb_count == 1); + ASSERT(close_cb_count == 2); + ASSERT(rename_cb_count == 1); + ASSERT(create_cb_count == 1); + ASSERT(write_cb_count == 1); + ASSERT(ftruncate_cb_count == 1); + + r = uv_fs_open(loop, &open_req1, "test_file2", O_RDONLY, 0, open_cb); + ASSERT(r == 0); + + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(open_cb_count == 2); + ASSERT(read_cb_count == 2); + ASSERT(close_cb_count == 3); + ASSERT(rename_cb_count == 1); + ASSERT(unlink_cb_count == 1); + ASSERT(create_cb_count == 1); + ASSERT(write_cb_count == 1); + ASSERT(ftruncate_cb_count == 1); + + /* Cleanup. */ + unlink("test_file"); + unlink("test_file2"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void fs_file_sync(int add_flags) { + int r; + + /* Setup. */ + unlink("test_file"); + unlink("test_file2"); + + loop = uv_default_loop(); + + r = uv_fs_open(loop, &open_req1, "test_file", + O_WRONLY | O_CREAT | add_flags, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r >= 0); + ASSERT(write_req.result >= 0); + uv_fs_req_cleanup(&write_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_open(NULL, &open_req1, "test_file", O_RDWR | add_flags, 0, NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r >= 0); + ASSERT(read_req.result >= 0); + ASSERT(strcmp(buf, test_buf) == 0); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_ftruncate(NULL, &ftruncate_req, open_req1.result, 7, NULL); + ASSERT(r == 0); + ASSERT(ftruncate_req.result == 0); + uv_fs_req_cleanup(&ftruncate_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_rename(NULL, &rename_req, "test_file", "test_file2", NULL); + ASSERT(r == 0); + ASSERT(rename_req.result == 0); + uv_fs_req_cleanup(&rename_req); + + r = uv_fs_open(NULL, &open_req1, "test_file2", O_RDONLY | add_flags, 0, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + memset(buf, 0, sizeof(buf)); + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r >= 0); + ASSERT(read_req.result >= 0); + ASSERT(strcmp(buf, "test-bu") == 0); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_unlink(NULL, &unlink_req, "test_file2", NULL); + ASSERT(r == 0); + ASSERT(unlink_req.result == 0); + uv_fs_req_cleanup(&unlink_req); + + /* Cleanup */ + unlink("test_file"); + unlink("test_file2"); +} +TEST_IMPL(fs_file_sync) { + fs_file_sync(0); + fs_file_sync(UV_FS_O_FILEMAP); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void fs_file_write_null_buffer(int add_flags) { + int r; + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, &open_req1, "test_file", + O_WRONLY | O_CREAT | add_flags, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + iov = uv_buf_init(NULL, 0); + r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r == 0); + ASSERT(write_req.result == 0); + uv_fs_req_cleanup(&write_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + unlink("test_file"); +} +TEST_IMPL(fs_file_write_null_buffer) { + fs_file_write_null_buffer(0); + fs_file_write_null_buffer(UV_FS_O_FILEMAP); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_async_dir) { + int r; + uv_dirent_t dent; + + /* Setup */ + unlink("test_dir/file1"); + unlink("test_dir/file2"); + rmdir("test_dir"); + + loop = uv_default_loop(); + + r = uv_fs_mkdir(loop, &mkdir_req, "test_dir", 0755, mkdir_cb); + ASSERT(r == 0); + + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(mkdir_cb_count == 1); + + /* Create 2 files synchronously. */ + r = uv_fs_open(NULL, &open_req1, "test_dir/file1", O_WRONLY | O_CREAT, + S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + uv_fs_req_cleanup(&open_req1); + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_open(NULL, &open_req1, "test_dir/file2", O_WRONLY | O_CREAT, + S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + uv_fs_req_cleanup(&open_req1); + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_scandir(loop, &scandir_req, "test_dir", 0, scandir_cb); + ASSERT(r == 0); + + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(scandir_cb_count == 1); + + /* sync uv_fs_scandir */ + r = uv_fs_scandir(NULL, &scandir_req, "test_dir", 0, NULL); + ASSERT(r == 2); + ASSERT(scandir_req.result == 2); + ASSERT(scandir_req.ptr); + while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) { + ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); + assert_is_file_type(dent); + } + uv_fs_req_cleanup(&scandir_req); + ASSERT(!scandir_req.ptr); + + r = uv_fs_stat(loop, &stat_req, "test_dir", stat_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + + r = uv_fs_stat(loop, &stat_req, "test_dir/", stat_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + + r = uv_fs_lstat(loop, &stat_req, "test_dir", stat_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + + r = uv_fs_lstat(loop, &stat_req, "test_dir/", stat_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(stat_cb_count == 4); + + r = uv_fs_unlink(loop, &unlink_req, "test_dir/file1", unlink_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(unlink_cb_count == 1); + + r = uv_fs_unlink(loop, &unlink_req, "test_dir/file2", unlink_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(unlink_cb_count == 2); + + r = uv_fs_rmdir(loop, &rmdir_req, "test_dir", rmdir_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(rmdir_cb_count == 1); + + /* Cleanup */ + unlink("test_dir/file1"); + unlink("test_dir/file2"); + rmdir("test_dir"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static int test_sendfile(void (*setup)(int), uv_fs_cb cb, off_t expected_size) { + int f, r; + struct stat s1, s2; + uv_fs_t req; + char buf1[1]; + + loop = uv_default_loop(); + + /* Setup. */ + unlink("test_file"); + unlink("test_file2"); + + f = open("test_file", O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR); + ASSERT(f != -1); + + if (setup != NULL) + setup(f); + + r = close(f); + ASSERT(r == 0); + + /* Test starts here. */ + r = uv_fs_open(NULL, &open_req1, "test_file", O_RDWR, 0, NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + r = uv_fs_open(NULL, &open_req2, "test_file2", O_WRONLY | O_CREAT, + S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(open_req2.result >= 0); + uv_fs_req_cleanup(&open_req2); + + r = uv_fs_sendfile(loop, &sendfile_req, open_req2.result, open_req1.result, + 1, 131072, cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(sendfile_cb_count == 1); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&close_req); + r = uv_fs_close(NULL, &close_req, open_req2.result, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&close_req); + + ASSERT(0 == stat("test_file", &s1)); + ASSERT(0 == stat("test_file2", &s2)); + ASSERT(s2.st_size == expected_size); + + if (expected_size > 0) { + ASSERT_UINT64_EQ(s1.st_size, s2.st_size + 1); + r = uv_fs_open(NULL, &open_req1, "test_file2", O_RDWR, 0, NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + memset(buf1, 0, sizeof(buf1)); + iov = uv_buf_init(buf1, sizeof(buf1)); + r = uv_fs_read(NULL, &req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + ASSERT_EQ(buf1[0], 'e'); /* 'e' from begin */ + uv_fs_req_cleanup(&req); + } else { + ASSERT_UINT64_EQ(s1.st_size, s2.st_size); + } + + /* Cleanup. */ + unlink("test_file"); + unlink("test_file2"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void sendfile_setup(int f) { + ASSERT(6 == write(f, "begin\n", 6)); + ASSERT(65542 == lseek(f, 65536, SEEK_CUR)); + ASSERT(4 == write(f, "end\n", 4)); +} + + +TEST_IMPL(fs_async_sendfile) { + return test_sendfile(sendfile_setup, sendfile_cb, 65545); +} + + +TEST_IMPL(fs_async_sendfile_nodata) { + return test_sendfile(NULL, sendfile_nodata_cb, 0); +} + + +TEST_IMPL(fs_mkdtemp) { + int r; + const char* path_template = "test_dir_XXXXXX"; + + loop = uv_default_loop(); + + r = uv_fs_mkdtemp(loop, &mkdtemp_req1, path_template, mkdtemp_cb); + ASSERT(r == 0); + + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(mkdtemp_cb_count == 1); + + /* sync mkdtemp */ + r = uv_fs_mkdtemp(NULL, &mkdtemp_req2, path_template, NULL); + ASSERT(r == 0); + check_mkdtemp_result(&mkdtemp_req2); + + /* mkdtemp return different values on subsequent calls */ + ASSERT(strcmp(mkdtemp_req1.path, mkdtemp_req2.path) != 0); + + /* Cleanup */ + rmdir(mkdtemp_req1.path); + rmdir(mkdtemp_req2.path); + uv_fs_req_cleanup(&mkdtemp_req1); + uv_fs_req_cleanup(&mkdtemp_req2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_mkstemp) { + int r; + int fd; + const char path_template[] = "test_file_XXXXXX"; + uv_fs_t req; + + loop = uv_default_loop(); + + r = uv_fs_mkstemp(loop, &mkstemp_req1, path_template, mkstemp_cb); + ASSERT(r == 0); + + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(mkstemp_cb_count == 1); + + /* sync mkstemp */ + r = uv_fs_mkstemp(NULL, &mkstemp_req2, path_template, NULL); + ASSERT(r >= 0); + check_mkstemp_result(&mkstemp_req2); + + /* mkstemp return different values on subsequent calls */ + ASSERT(strcmp(mkstemp_req1.path, mkstemp_req2.path) != 0); + + /* invalid template returns EINVAL */ + ASSERT_EQ(UV_EINVAL, uv_fs_mkstemp(NULL, &mkstemp_req3, "test_file", NULL)); + + /* Make sure that path is empty string */ + ASSERT_EQ(0, strlen(mkstemp_req3.path)); + + /* We can write to the opened file */ + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &req, mkstemp_req1.result, &iov, 1, -1, NULL); + ASSERT(r == sizeof(test_buf)); + ASSERT(req.result == sizeof(test_buf)); + uv_fs_req_cleanup(&req); + + /* Cleanup */ + uv_fs_close(NULL, &req, mkstemp_req1.result, NULL); + uv_fs_req_cleanup(&req); + uv_fs_close(NULL, &req, mkstemp_req2.result, NULL); + uv_fs_req_cleanup(&req); + + fd = uv_fs_open(NULL, &req, mkstemp_req1.path , O_RDONLY, 0, NULL); + ASSERT(fd >= 0); + uv_fs_req_cleanup(&req); + + memset(buf, 0, sizeof(buf)); + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &req, fd, &iov, 1, -1, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + ASSERT(strcmp(buf, test_buf) == 0); + uv_fs_req_cleanup(&req); + + uv_fs_close(NULL, &req, fd, NULL); + uv_fs_req_cleanup(&req); + + unlink(mkstemp_req1.path); + unlink(mkstemp_req2.path); + uv_fs_req_cleanup(&mkstemp_req1); + uv_fs_req_cleanup(&mkstemp_req2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_fstat) { + int r; + uv_fs_t req; + uv_file file; + uv_stat_t* s; +#ifndef _WIN32 + struct stat t; +#endif + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + file = req.result; + uv_fs_req_cleanup(&req); + +#ifndef _WIN32 + ASSERT(0 == fstat(file, &t)); + ASSERT(0 == uv_fs_fstat(NULL, &req, file, NULL)); + ASSERT(req.result == 0); + s = req.ptr; +# if defined(__APPLE__) + ASSERT(s->st_birthtim.tv_sec == t.st_birthtimespec.tv_sec); + ASSERT(s->st_birthtim.tv_nsec == t.st_birthtimespec.tv_nsec); +# elif defined(__linux__) + /* If statx() is supported, the birth time should be equal to the change time + * because we just created the file. On older kernels, it's set to zero. + */ + ASSERT(s->st_birthtim.tv_sec == 0 || + s->st_birthtim.tv_sec == t.st_ctim.tv_sec); + ASSERT(s->st_birthtim.tv_nsec == 0 || + s->st_birthtim.tv_nsec == t.st_ctim.tv_nsec); +# endif +#endif + + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL); + ASSERT(r == sizeof(test_buf)); + ASSERT(req.result == sizeof(test_buf)); + uv_fs_req_cleanup(&req); + + memset(&req.statbuf, 0xaa, sizeof(req.statbuf)); + r = uv_fs_fstat(NULL, &req, file, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + s = req.ptr; + ASSERT(s->st_size == sizeof(test_buf)); + +#ifndef _WIN32 + r = fstat(file, &t); + ASSERT(r == 0); + + ASSERT(s->st_dev == (uint64_t) t.st_dev); + ASSERT(s->st_mode == (uint64_t) t.st_mode); + ASSERT(s->st_nlink == (uint64_t) t.st_nlink); + ASSERT(s->st_uid == (uint64_t) t.st_uid); + ASSERT(s->st_gid == (uint64_t) t.st_gid); + ASSERT(s->st_rdev == (uint64_t) t.st_rdev); + ASSERT(s->st_ino == (uint64_t) t.st_ino); + ASSERT(s->st_size == (uint64_t) t.st_size); + ASSERT(s->st_blksize == (uint64_t) t.st_blksize); + ASSERT(s->st_blocks == (uint64_t) t.st_blocks); +#if defined(__APPLE__) + ASSERT(s->st_atim.tv_sec == t.st_atimespec.tv_sec); + ASSERT(s->st_atim.tv_nsec == t.st_atimespec.tv_nsec); + ASSERT(s->st_mtim.tv_sec == t.st_mtimespec.tv_sec); + ASSERT(s->st_mtim.tv_nsec == t.st_mtimespec.tv_nsec); + ASSERT(s->st_ctim.tv_sec == t.st_ctimespec.tv_sec); + ASSERT(s->st_ctim.tv_nsec == t.st_ctimespec.tv_nsec); +#elif defined(_AIX) || \ + defined(__MVS__) + ASSERT(s->st_atim.tv_sec == t.st_atime); + ASSERT(s->st_atim.tv_nsec == 0); + ASSERT(s->st_mtim.tv_sec == t.st_mtime); + ASSERT(s->st_mtim.tv_nsec == 0); + ASSERT(s->st_ctim.tv_sec == t.st_ctime); + ASSERT(s->st_ctim.tv_nsec == 0); +#elif defined(__ANDROID__) + ASSERT(s->st_atim.tv_sec == t.st_atime); + ASSERT(s->st_atim.tv_nsec == t.st_atimensec); + ASSERT(s->st_mtim.tv_sec == t.st_mtime); + ASSERT(s->st_mtim.tv_nsec == t.st_mtimensec); + ASSERT(s->st_ctim.tv_sec == t.st_ctime); + ASSERT(s->st_ctim.tv_nsec == t.st_ctimensec); +#elif defined(__sun) || \ + defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__OpenBSD__) || \ + defined(__NetBSD__) || \ + defined(_GNU_SOURCE) || \ + defined(_BSD_SOURCE) || \ + defined(_SVID_SOURCE) || \ + defined(_XOPEN_SOURCE) || \ + defined(_DEFAULT_SOURCE) + ASSERT(s->st_atim.tv_sec == t.st_atim.tv_sec); + ASSERT(s->st_atim.tv_nsec == t.st_atim.tv_nsec); + ASSERT(s->st_mtim.tv_sec == t.st_mtim.tv_sec); + ASSERT(s->st_mtim.tv_nsec == t.st_mtim.tv_nsec); + ASSERT(s->st_ctim.tv_sec == t.st_ctim.tv_sec); + ASSERT(s->st_ctim.tv_nsec == t.st_ctim.tv_nsec); +# if defined(__FreeBSD__) || \ + defined(__NetBSD__) + ASSERT(s->st_birthtim.tv_sec == t.st_birthtim.tv_sec); + ASSERT(s->st_birthtim.tv_nsec == t.st_birthtim.tv_nsec); +# endif +#else + ASSERT(s->st_atim.tv_sec == t.st_atime); + ASSERT(s->st_atim.tv_nsec == 0); + ASSERT(s->st_mtim.tv_sec == t.st_mtime); + ASSERT(s->st_mtim.tv_nsec == 0); + ASSERT(s->st_ctim.tv_sec == t.st_ctime); + ASSERT(s->st_ctim.tv_nsec == 0); +#endif +#endif + +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) + ASSERT(s->st_flags == t.st_flags); + ASSERT(s->st_gen == t.st_gen); +#else + ASSERT(s->st_flags == 0); + ASSERT(s->st_gen == 0); +#endif + + uv_fs_req_cleanup(&req); + + /* Now do the uv_fs_fstat call asynchronously */ + r = uv_fs_fstat(loop, &req, file, fstat_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(fstat_cb_count == 1); + + + r = uv_fs_close(NULL, &req, file, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + /* + * Run the loop just to check we don't have make any extraneous uv_ref() + * calls. This should drop out immediately. + */ + uv_run(loop, UV_RUN_DEFAULT); + + /* Cleanup. */ + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_access) { + int r; + uv_fs_t req; + uv_file file; + + /* Setup. */ + unlink("test_file"); + rmdir("test_dir"); + + loop = uv_default_loop(); + + /* File should not exist */ + r = uv_fs_access(NULL, &req, "test_file", F_OK, NULL); + ASSERT(r < 0); + ASSERT(req.result < 0); + uv_fs_req_cleanup(&req); + + /* File should not exist */ + r = uv_fs_access(loop, &req, "test_file", F_OK, access_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(access_cb_count == 1); + access_cb_count = 0; /* reset for the next test */ + + /* Create file */ + r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + file = req.result; + uv_fs_req_cleanup(&req); + + /* File should exist */ + r = uv_fs_access(NULL, &req, "test_file", F_OK, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + /* File should exist */ + r = uv_fs_access(loop, &req, "test_file", F_OK, access_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(access_cb_count == 1); + access_cb_count = 0; /* reset for the next test */ + + /* Close file */ + r = uv_fs_close(NULL, &req, file, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + /* Directory access */ + r = uv_fs_mkdir(NULL, &req, "test_dir", 0777, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); + + r = uv_fs_access(NULL, &req, "test_dir", W_OK, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + /* + * Run the loop just to check we don't have make any extraneous uv_ref() + * calls. This should drop out immediately. + */ + uv_run(loop, UV_RUN_DEFAULT); + + /* Cleanup. */ + unlink("test_file"); + rmdir("test_dir"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_chmod) { + int r; + uv_fs_t req; + uv_file file; + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + file = req.result; + uv_fs_req_cleanup(&req); + + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL); + ASSERT(r == sizeof(test_buf)); + ASSERT(req.result == sizeof(test_buf)); + uv_fs_req_cleanup(&req); + +#ifndef _WIN32 + /* Make the file write-only */ + r = uv_fs_chmod(NULL, &req, "test_file", 0200, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + check_permission("test_file", 0200); +#endif + + /* Make the file read-only */ + r = uv_fs_chmod(NULL, &req, "test_file", 0400, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + check_permission("test_file", 0400); + + /* Make the file read+write with sync uv_fs_fchmod */ + r = uv_fs_fchmod(NULL, &req, file, 0600, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + check_permission("test_file", 0600); + +#ifndef _WIN32 + /* async chmod */ + { + static int mode = 0200; + req.data = &mode; + } + r = uv_fs_chmod(loop, &req, "test_file", 0200, chmod_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(chmod_cb_count == 1); + chmod_cb_count = 0; /* reset for the next test */ +#endif + + /* async chmod */ + { + static int mode = 0400; + req.data = &mode; + } + r = uv_fs_chmod(loop, &req, "test_file", 0400, chmod_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(chmod_cb_count == 1); + + /* async fchmod */ + { + static int mode = 0600; + req.data = &mode; + } + r = uv_fs_fchmod(loop, &req, file, 0600, fchmod_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(fchmod_cb_count == 1); + + uv_fs_close(loop, &req, file, NULL); + + /* + * Run the loop just to check we don't have make any extraneous uv_ref() + * calls. This should drop out immediately. + */ + uv_run(loop, UV_RUN_DEFAULT); + + /* Cleanup. */ + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_unlink_readonly) { + int r; + uv_fs_t req; + uv_file file; + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, + &req, + "test_file", + O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + file = req.result; + uv_fs_req_cleanup(&req); + + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL); + ASSERT(r == sizeof(test_buf)); + ASSERT(req.result == sizeof(test_buf)); + uv_fs_req_cleanup(&req); + + uv_fs_close(loop, &req, file, NULL); + + /* Make the file read-only */ + r = uv_fs_chmod(NULL, &req, "test_file", 0400, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + check_permission("test_file", 0400); + + /* Try to unlink the file */ + r = uv_fs_unlink(NULL, &req, "test_file", NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + /* + * Run the loop just to check we don't have make any extraneous uv_ref() + * calls. This should drop out immediately. + */ + uv_run(loop, UV_RUN_DEFAULT); + + /* Cleanup. */ + uv_fs_chmod(NULL, &req, "test_file", 0600, NULL); + uv_fs_req_cleanup(&req); + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#ifdef _WIN32 +TEST_IMPL(fs_unlink_archive_readonly) { + int r; + uv_fs_t req; + uv_file file; + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, + &req, + "test_file", + O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + file = req.result; + uv_fs_req_cleanup(&req); + + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL); + ASSERT(r == sizeof(test_buf)); + ASSERT(req.result == sizeof(test_buf)); + uv_fs_req_cleanup(&req); + + uv_fs_close(loop, &req, file, NULL); + + /* Make the file read-only and clear archive flag */ + r = SetFileAttributes("test_file", FILE_ATTRIBUTE_READONLY); + ASSERT(r != 0); + uv_fs_req_cleanup(&req); + + check_permission("test_file", 0400); + + /* Try to unlink the file */ + r = uv_fs_unlink(NULL, &req, "test_file", NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + /* + * Run the loop just to check we don't have make any extraneous uv_ref() + * calls. This should drop out immediately. + */ + uv_run(loop, UV_RUN_DEFAULT); + + /* Cleanup. */ + uv_fs_chmod(NULL, &req, "test_file", 0600, NULL); + uv_fs_req_cleanup(&req); + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + +TEST_IMPL(fs_chown) { + int r; + uv_fs_t req; + uv_file file; + + /* Setup. */ + unlink("test_file"); + unlink("test_file_link"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + file = req.result; + uv_fs_req_cleanup(&req); + + /* sync chown */ + r = uv_fs_chown(NULL, &req, "test_file", -1, -1, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + /* sync fchown */ + r = uv_fs_fchown(NULL, &req, file, -1, -1, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + /* async chown */ + r = uv_fs_chown(loop, &req, "test_file", -1, -1, chown_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(chown_cb_count == 1); + +#ifndef __MVS__ + /* chown to root (fail) */ + chown_cb_count = 0; + r = uv_fs_chown(loop, &req, "test_file", 0, 0, chown_root_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(chown_cb_count == 1); +#endif + + /* async fchown */ + r = uv_fs_fchown(loop, &req, file, -1, -1, fchown_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(fchown_cb_count == 1); + +#ifndef __HAIKU__ + /* Haiku doesn't support hardlink */ + /* sync link */ + r = uv_fs_link(NULL, &req, "test_file", "test_file_link", NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + /* sync lchown */ + r = uv_fs_lchown(NULL, &req, "test_file_link", -1, -1, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + /* async lchown */ + r = uv_fs_lchown(loop, &req, "test_file_link", -1, -1, lchown_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(lchown_cb_count == 1); +#endif + + /* Close file */ + r = uv_fs_close(NULL, &req, file, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + /* + * Run the loop just to check we don't have make any extraneous uv_ref() + * calls. This should drop out immediately. + */ + uv_run(loop, UV_RUN_DEFAULT); + + /* Cleanup. */ + unlink("test_file"); + unlink("test_file_link"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_link) { + int r; + uv_fs_t req; + uv_file file; + uv_file link; + + /* Setup. */ + unlink("test_file"); + unlink("test_file_link"); + unlink("test_file_link2"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + file = req.result; + uv_fs_req_cleanup(&req); + + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL); + ASSERT(r == sizeof(test_buf)); + ASSERT(req.result == sizeof(test_buf)); + uv_fs_req_cleanup(&req); + + uv_fs_close(loop, &req, file, NULL); + + /* sync link */ + r = uv_fs_link(NULL, &req, "test_file", "test_file_link", NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + r = uv_fs_open(NULL, &req, "test_file_link", O_RDWR, 0, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + link = req.result; + uv_fs_req_cleanup(&req); + + memset(buf, 0, sizeof(buf)); + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + ASSERT(strcmp(buf, test_buf) == 0); + + close(link); + + /* async link */ + r = uv_fs_link(loop, &req, "test_file", "test_file_link2", link_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(link_cb_count == 1); + + r = uv_fs_open(NULL, &req, "test_file_link2", O_RDWR, 0, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + link = req.result; + uv_fs_req_cleanup(&req); + + memset(buf, 0, sizeof(buf)); + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + ASSERT(strcmp(buf, test_buf) == 0); + + uv_fs_close(loop, &req, link, NULL); + + /* + * Run the loop just to check we don't have make any extraneous uv_ref() + * calls. This should drop out immediately. + */ + uv_run(loop, UV_RUN_DEFAULT); + + /* Cleanup. */ + unlink("test_file"); + unlink("test_file_link"); + unlink("test_file_link2"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_readlink) { + uv_fs_t req; + + loop = uv_default_loop(); + ASSERT(0 == uv_fs_readlink(loop, &req, "no_such_file", dummy_cb)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(dummy_cb_count == 1); + ASSERT_NULL(req.ptr); + ASSERT(req.result == UV_ENOENT); + uv_fs_req_cleanup(&req); + + ASSERT(UV_ENOENT == uv_fs_readlink(NULL, &req, "no_such_file", NULL)); + ASSERT_NULL(req.ptr); + ASSERT(req.result == UV_ENOENT); + uv_fs_req_cleanup(&req); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_realpath) { + uv_fs_t req; + + loop = uv_default_loop(); + ASSERT(0 == uv_fs_realpath(loop, &req, "no_such_file", dummy_cb)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(dummy_cb_count == 1); + ASSERT_NULL(req.ptr); +#ifdef _WIN32 + /* + * Windows XP and Server 2003 don't support GetFinalPathNameByHandleW() + */ + if (req.result == UV_ENOSYS) { + uv_fs_req_cleanup(&req); + RETURN_SKIP("realpath is not supported on Windows XP"); + } +#endif + ASSERT(req.result == UV_ENOENT); + uv_fs_req_cleanup(&req); + + ASSERT(UV_ENOENT == uv_fs_realpath(NULL, &req, "no_such_file", NULL)); + ASSERT_NULL(req.ptr); + ASSERT(req.result == UV_ENOENT); + uv_fs_req_cleanup(&req); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_symlink) { + int r; + uv_fs_t req; + uv_file file; + uv_file link; + char test_file_abs_buf[PATHMAX]; + size_t test_file_abs_size; + + /* Setup. */ + unlink("test_file"); + unlink("test_file_symlink"); + unlink("test_file_symlink2"); + unlink("test_file_symlink_symlink"); + unlink("test_file_symlink2_symlink"); + test_file_abs_size = sizeof(test_file_abs_buf); +#ifdef _WIN32 + uv_cwd(test_file_abs_buf, &test_file_abs_size); + strcat(test_file_abs_buf, "\\test_file"); +#else + uv_cwd(test_file_abs_buf, &test_file_abs_size); + strcat(test_file_abs_buf, "/test_file"); +#endif + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + file = req.result; + uv_fs_req_cleanup(&req); + + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL); + ASSERT(r == sizeof(test_buf)); + ASSERT(req.result == sizeof(test_buf)); + uv_fs_req_cleanup(&req); + + uv_fs_close(loop, &req, file, NULL); + + /* sync symlink */ + r = uv_fs_symlink(NULL, &req, "test_file", "test_file_symlink", 0, NULL); +#ifdef _WIN32 + if (r < 0) { + if (r == UV_ENOTSUP) { + /* + * Windows doesn't support symlinks on older versions. + * We just pass the test and bail out early if we get ENOTSUP. + */ + return 0; + } else if (r == UV_EPERM) { + /* + * Creating a symlink is only allowed when running elevated. + * We pass the test and bail out early if we get UV_EPERM. + */ + return 0; + } + } +#endif + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + r = uv_fs_open(NULL, &req, "test_file_symlink", O_RDWR, 0, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + link = req.result; + uv_fs_req_cleanup(&req); + + memset(buf, 0, sizeof(buf)); + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + ASSERT(strcmp(buf, test_buf) == 0); + + uv_fs_close(loop, &req, link, NULL); + + r = uv_fs_symlink(NULL, + &req, + "test_file_symlink", + "test_file_symlink_symlink", + 0, + NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); + +#if defined(__MSYS__) + RETURN_SKIP("symlink reading is not supported on MSYS2"); +#endif + + r = uv_fs_readlink(NULL, &req, "test_file_symlink_symlink", NULL); + ASSERT(r == 0); + ASSERT(strcmp(req.ptr, "test_file_symlink") == 0); + uv_fs_req_cleanup(&req); + + r = uv_fs_realpath(NULL, &req, "test_file_symlink_symlink", NULL); +#ifdef _WIN32 + /* + * Windows XP and Server 2003 don't support GetFinalPathNameByHandleW() + */ + if (r == UV_ENOSYS) { + uv_fs_req_cleanup(&req); + RETURN_SKIP("realpath is not supported on Windows XP"); + } +#endif + ASSERT(r == 0); +#ifdef _WIN32 + ASSERT(stricmp(req.ptr, test_file_abs_buf) == 0); +#else + ASSERT(strcmp(req.ptr, test_file_abs_buf) == 0); +#endif + uv_fs_req_cleanup(&req); + + /* async link */ + r = uv_fs_symlink(loop, + &req, + "test_file", + "test_file_symlink2", + 0, + symlink_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(symlink_cb_count == 1); + + r = uv_fs_open(NULL, &req, "test_file_symlink2", O_RDWR, 0, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + link = req.result; + uv_fs_req_cleanup(&req); + + memset(buf, 0, sizeof(buf)); + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &req, link, &iov, 1, 0, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + ASSERT(strcmp(buf, test_buf) == 0); + + uv_fs_close(loop, &req, link, NULL); + + r = uv_fs_symlink(NULL, + &req, + "test_file_symlink2", + "test_file_symlink2_symlink", + 0, + NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); + + r = uv_fs_readlink(loop, &req, "test_file_symlink2_symlink", readlink_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(readlink_cb_count == 1); + + r = uv_fs_realpath(loop, &req, "test_file", realpath_cb); +#ifdef _WIN32 + /* + * Windows XP and Server 2003 don't support GetFinalPathNameByHandleW() + */ + if (r == UV_ENOSYS) { + uv_fs_req_cleanup(&req); + RETURN_SKIP("realpath is not supported on Windows XP"); + } +#endif + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(realpath_cb_count == 1); + + /* + * Run the loop just to check we don't have make any extraneous uv_ref() + * calls. This should drop out immediately. + */ + uv_run(loop, UV_RUN_DEFAULT); + + /* Cleanup. */ + unlink("test_file"); + unlink("test_file_symlink"); + unlink("test_file_symlink_symlink"); + unlink("test_file_symlink2"); + unlink("test_file_symlink2_symlink"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +int test_symlink_dir_impl(int type) { + uv_fs_t req; + int r; + char* test_dir; + uv_dirent_t dent; + static char test_dir_abs_buf[PATHMAX]; + size_t test_dir_abs_size; + + /* set-up */ + unlink("test_dir/file1"); + unlink("test_dir/file2"); + rmdir("test_dir"); + rmdir("test_dir_symlink"); + test_dir_abs_size = sizeof(test_dir_abs_buf); + + loop = uv_default_loop(); + + uv_fs_mkdir(NULL, &req, "test_dir", 0777, NULL); + uv_fs_req_cleanup(&req); + +#ifdef _WIN32 + strcpy(test_dir_abs_buf, "\\\\?\\"); + uv_cwd(test_dir_abs_buf + 4, &test_dir_abs_size); + test_dir_abs_size += 4; + strcat(test_dir_abs_buf, "\\test_dir\\"); + test_dir_abs_size += strlen("\\test_dir\\"); + test_dir = test_dir_abs_buf; +#else + uv_cwd(test_dir_abs_buf, &test_dir_abs_size); + strcat(test_dir_abs_buf, "/test_dir"); + test_dir_abs_size += strlen("/test_dir"); + test_dir = "test_dir"; +#endif + + r = uv_fs_symlink(NULL, &req, test_dir, "test_dir_symlink", type, NULL); + if (type == UV_FS_SYMLINK_DIR && (r == UV_ENOTSUP || r == UV_EPERM)) { + uv_fs_req_cleanup(&req); + RETURN_SKIP("this version of Windows doesn't support unprivileged " + "creation of directory symlinks"); + } + fprintf(stderr, "r == %i\n", r); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + r = uv_fs_stat(NULL, &req, "test_dir_symlink", NULL); + ASSERT(r == 0); + ASSERT(((uv_stat_t*)req.ptr)->st_mode & S_IFDIR); + uv_fs_req_cleanup(&req); + + r = uv_fs_lstat(NULL, &req, "test_dir_symlink", NULL); + ASSERT(r == 0); +#if defined(__MSYS__) + RETURN_SKIP("symlink reading is not supported on MSYS2"); +#endif + ASSERT(((uv_stat_t*)req.ptr)->st_mode & S_IFLNK); +#ifdef _WIN32 + ASSERT(((uv_stat_t*)req.ptr)->st_size == strlen(test_dir + 4)); +#else +# ifdef __PASE__ + /* On IBMi PASE, st_size returns the length of the symlink itself. */ + ASSERT(((uv_stat_t*)req.ptr)->st_size == strlen("test_dir_symlink")); +# else + ASSERT(((uv_stat_t*)req.ptr)->st_size == strlen(test_dir)); +# endif +#endif + uv_fs_req_cleanup(&req); + + r = uv_fs_readlink(NULL, &req, "test_dir_symlink", NULL); + ASSERT(r == 0); +#ifdef _WIN32 + ASSERT(strcmp(req.ptr, test_dir + 4) == 0); +#else + ASSERT(strcmp(req.ptr, test_dir) == 0); +#endif + uv_fs_req_cleanup(&req); + + r = uv_fs_realpath(NULL, &req, "test_dir_symlink", NULL); +#ifdef _WIN32 + /* + * Windows XP and Server 2003 don't support GetFinalPathNameByHandleW() + */ + if (r == UV_ENOSYS) { + uv_fs_req_cleanup(&req); + RETURN_SKIP("realpath is not supported on Windows XP"); + } +#endif + ASSERT(r == 0); +#ifdef _WIN32 + ASSERT(strlen(req.ptr) == test_dir_abs_size - 5); + ASSERT(strnicmp(req.ptr, test_dir + 4, test_dir_abs_size - 5) == 0); +#else + ASSERT(strcmp(req.ptr, test_dir_abs_buf) == 0); +#endif + uv_fs_req_cleanup(&req); + + r = uv_fs_open(NULL, &open_req1, "test_dir/file1", O_WRONLY | O_CREAT, + S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + uv_fs_req_cleanup(&open_req1); + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_open(NULL, &open_req1, "test_dir/file2", O_WRONLY | O_CREAT, + S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + uv_fs_req_cleanup(&open_req1); + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_scandir(NULL, &scandir_req, "test_dir_symlink", 0, NULL); + ASSERT(r == 2); + ASSERT(scandir_req.result == 2); + ASSERT(scandir_req.ptr); + while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) { + ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); + assert_is_file_type(dent); + } + uv_fs_req_cleanup(&scandir_req); + ASSERT(!scandir_req.ptr); + + /* unlink will remove the directory symlink */ + r = uv_fs_unlink(NULL, &req, "test_dir_symlink", NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); + + r = uv_fs_scandir(NULL, &scandir_req, "test_dir_symlink", 0, NULL); + ASSERT(r == UV_ENOENT); + uv_fs_req_cleanup(&scandir_req); + + r = uv_fs_scandir(NULL, &scandir_req, "test_dir", 0, NULL); + ASSERT(r == 2); + ASSERT(scandir_req.result == 2); + ASSERT(scandir_req.ptr); + while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) { + ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); + assert_is_file_type(dent); + } + uv_fs_req_cleanup(&scandir_req); + ASSERT(!scandir_req.ptr); + + /* clean-up */ + unlink("test_dir/file1"); + unlink("test_dir/file2"); + rmdir("test_dir"); + rmdir("test_dir_symlink"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_symlink_dir) { + return test_symlink_dir_impl(UV_FS_SYMLINK_DIR); +} + +TEST_IMPL(fs_symlink_junction) { + return test_symlink_dir_impl(UV_FS_SYMLINK_JUNCTION); +} + +#ifdef _WIN32 +TEST_IMPL(fs_non_symlink_reparse_point) { + uv_fs_t req; + int r; + HANDLE file_handle; + REPARSE_GUID_DATA_BUFFER reparse_buffer; + DWORD bytes_returned; + uv_dirent_t dent; + + /* set-up */ + unlink("test_dir/test_file"); + rmdir("test_dir"); + + loop = uv_default_loop(); + + uv_fs_mkdir(NULL, &req, "test_dir", 0777, NULL); + uv_fs_req_cleanup(&req); + + file_handle = CreateFile("test_dir/test_file", + GENERIC_WRITE | FILE_WRITE_ATTRIBUTES, + 0, + NULL, + CREATE_ALWAYS, + FILE_FLAG_OPEN_REPARSE_POINT | + FILE_FLAG_BACKUP_SEMANTICS, + NULL); + ASSERT(file_handle != INVALID_HANDLE_VALUE); + + memset(&reparse_buffer, 0, REPARSE_GUID_DATA_BUFFER_HEADER_SIZE); + reparse_buffer.ReparseTag = REPARSE_TAG; + reparse_buffer.ReparseDataLength = 0; + reparse_buffer.ReparseGuid = REPARSE_GUID; + + r = DeviceIoControl(file_handle, + FSCTL_SET_REPARSE_POINT, + &reparse_buffer, + REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, + NULL, + 0, + &bytes_returned, + NULL); + ASSERT(r != 0); + + CloseHandle(file_handle); + + r = uv_fs_readlink(NULL, &req, "test_dir/test_file", NULL); + ASSERT(r == UV_EINVAL && GetLastError() == ERROR_SYMLINK_NOT_SUPPORTED); + uv_fs_req_cleanup(&req); + +/* + Placeholder tests for exercising the behavior fixed in issue #995. + To run, update the path with the IP address of a Mac with the hard drive + shared via SMB as "Macintosh HD". + + r = uv_fs_stat(NULL, &req, "\\\\\\Macintosh HD\\.DS_Store", NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); + + r = uv_fs_lstat(NULL, &req, "\\\\\\Macintosh HD\\.DS_Store", NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); +*/ + +/* + uv_fs_stat and uv_fs_lstat can only work on non-symlink reparse + points when a minifilter driver is registered which intercepts + associated filesystem requests. Installing a driver is beyond + the scope of this test. + + r = uv_fs_stat(NULL, &req, "test_dir/test_file", NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); + + r = uv_fs_lstat(NULL, &req, "test_dir/test_file", NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); +*/ + + r = uv_fs_scandir(NULL, &scandir_req, "test_dir", 0, NULL); + ASSERT(r == 1); + ASSERT(scandir_req.result == 1); + ASSERT(scandir_req.ptr); + while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) { + ASSERT(strcmp(dent.name, "test_file") == 0); + /* uv_fs_scandir incorrectly identifies non-symlink reparse points + as links because it doesn't open the file and verify the reparse + point tag. The PowerShell Get-ChildItem command shares this + behavior, so it's reasonable to leave it as is. */ + ASSERT(dent.type == UV_DIRENT_LINK); + } + uv_fs_req_cleanup(&scandir_req); + ASSERT(!scandir_req.ptr); + + /* clean-up */ + unlink("test_dir/test_file"); + rmdir("test_dir"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_lstat_windows_store_apps) { + uv_loop_t* loop; + char localappdata[MAX_PATH]; + char windowsapps_path[MAX_PATH]; + char file_path[MAX_PATH]; + size_t len; + int r; + uv_fs_t req; + uv_fs_t stat_req; + uv_dirent_t dirent; + + loop = uv_default_loop(); + ASSERT_NOT_NULL(loop); + len = sizeof(localappdata); + r = uv_os_getenv("LOCALAPPDATA", localappdata, &len); + if (r == UV_ENOENT) { + MAKE_VALGRIND_HAPPY(); + return TEST_SKIP; + } + ASSERT_EQ(r, 0); + r = snprintf(windowsapps_path, + sizeof(localappdata), + "%s\\Microsoft\\WindowsApps", + localappdata); + ASSERT_GT(r, 0); + if (uv_fs_opendir(loop, &req, windowsapps_path, NULL) != 0) { + /* If we cannot read the directory, skip the test. */ + MAKE_VALGRIND_HAPPY(); + return TEST_SKIP; + } + if (uv_fs_scandir(loop, &req, windowsapps_path, 0, NULL) <= 0) { + MAKE_VALGRIND_HAPPY(); + return TEST_SKIP; + } + while (uv_fs_scandir_next(&req, &dirent) != UV_EOF) { + if (dirent.type != UV_DIRENT_LINK) { + continue; + } + if (snprintf(file_path, + sizeof(file_path), + "%s\\%s", + windowsapps_path, + dirent.name) < 0) { + continue; + } + ASSERT_EQ(uv_fs_lstat(loop, &stat_req, file_path, NULL), 0); + } + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + + +TEST_IMPL(fs_utime) { + utime_check_t checkme; + const char* path = "test_file"; + double atime; + double mtime; + uv_fs_t req; + int r; + + /* Setup. */ + loop = uv_default_loop(); + unlink(path); + r = uv_fs_open(NULL, &req, path, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + uv_fs_req_cleanup(&req); + uv_fs_close(loop, &req, r, NULL); + + atime = mtime = 400497753.25; /* 1982-09-10 11:22:33.25 */ + + r = uv_fs_utime(NULL, &req, path, atime, mtime, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + check_utime(path, atime, mtime, /* test_lutime */ 0); + + atime = mtime = 1291404900.25; /* 2010-12-03 20:35:00.25 - mees <3 */ + checkme.path = path; + checkme.atime = atime; + checkme.mtime = mtime; + + /* async utime */ + utime_req.data = &checkme; + r = uv_fs_utime(loop, &utime_req, path, atime, mtime, utime_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(utime_cb_count == 1); + + /* Cleanup. */ + unlink(path); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_utime_round) { + const char path[] = "test_file"; + double atime; + double mtime; + uv_fs_t req; + int r; + + loop = uv_default_loop(); + unlink(path); + r = uv_fs_open(NULL, &req, path, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR, NULL); + ASSERT_GE(r, 0); + ASSERT_GE(req.result, 0); + uv_fs_req_cleanup(&req); + ASSERT_EQ(0, uv_fs_close(loop, &req, r, NULL)); + + atime = mtime = -14245440.25; /* 1969-07-20T02:56:00.25Z */ + + r = uv_fs_utime(NULL, &req, path, atime, mtime, NULL); +#if !defined(__linux__) && \ + !defined(_WIN32) && \ + !defined(__APPLE__) && \ + !defined(__FreeBSD__) && \ + !defined(__sun) + if (r != 0) { + ASSERT_EQ(r, UV_EINVAL); + RETURN_SKIP("utime on some OS (z/OS, IBM i PASE, AIX) or filesystems may reject pre-epoch timestamps"); + } +#endif + ASSERT_EQ(0, r); + ASSERT_EQ(0, req.result); + uv_fs_req_cleanup(&req); + check_utime(path, atime, mtime, /* test_lutime */ 0); + unlink(path); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +#ifdef _WIN32 +TEST_IMPL(fs_stat_root) { + int r; + + r = uv_fs_stat(NULL, &stat_req, "\\", NULL); + ASSERT(r == 0); + + r = uv_fs_stat(NULL, &stat_req, "..\\..\\..\\..\\..\\..\\..", NULL); + ASSERT(r == 0); + + r = uv_fs_stat(NULL, &stat_req, "..", NULL); + ASSERT(r == 0); + + r = uv_fs_stat(NULL, &stat_req, "..\\", NULL); + ASSERT(r == 0); + + /* stats the current directory on c: */ + r = uv_fs_stat(NULL, &stat_req, "c:", NULL); + ASSERT(r == 0); + + r = uv_fs_stat(NULL, &stat_req, "c:\\", NULL); + ASSERT(r == 0); + + r = uv_fs_stat(NULL, &stat_req, "\\\\?\\C:\\", NULL); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + + +TEST_IMPL(fs_futime) { + utime_check_t checkme; + const char* path = "test_file"; + double atime; + double mtime; + uv_file file; + uv_fs_t req; + int r; +#if defined(_AIX) && !defined(_AIX71) + RETURN_SKIP("futime is not implemented for AIX versions below 7.1"); +#endif + + /* Setup. */ + loop = uv_default_loop(); + unlink(path); + r = uv_fs_open(NULL, &req, path, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + uv_fs_req_cleanup(&req); + uv_fs_close(loop, &req, r, NULL); + + atime = mtime = 400497753.25; /* 1982-09-10 11:22:33.25 */ + + r = uv_fs_open(NULL, &req, path, O_RDWR, 0, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + file = req.result; /* FIXME probably not how it's supposed to be used */ + uv_fs_req_cleanup(&req); + + r = uv_fs_futime(NULL, &req, file, atime, mtime, NULL); +#if defined(__CYGWIN__) || defined(__MSYS__) + ASSERT(r == UV_ENOSYS); + RETURN_SKIP("futime not supported on Cygwin"); +#else + ASSERT(r == 0); + ASSERT(req.result == 0); +#endif + uv_fs_req_cleanup(&req); + + check_utime(path, atime, mtime, /* test_lutime */ 0); + + atime = mtime = 1291404900; /* 2010-12-03 20:35:00 - mees <3 */ + + checkme.atime = atime; + checkme.mtime = mtime; + checkme.path = path; + + /* async futime */ + futime_req.data = &checkme; + r = uv_fs_futime(loop, &futime_req, file, atime, mtime, futime_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(futime_cb_count == 1); + + /* Cleanup. */ + unlink(path); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_lutime) { + utime_check_t checkme; + const char* path = "test_file"; + const char* symlink_path = "test_file_symlink"; + double atime; + double mtime; + uv_fs_t req; + int r, s; + + + /* Setup */ + loop = uv_default_loop(); + unlink(path); + r = uv_fs_open(NULL, &req, path, O_RDWR | O_CREAT, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + uv_fs_req_cleanup(&req); + uv_fs_close(loop, &req, r, NULL); + + unlink(symlink_path); + s = uv_fs_symlink(NULL, &req, path, symlink_path, 0, NULL); +#ifdef _WIN32 + if (s == UV_EPERM) { + /* + * Creating a symlink before Windows 10 Creators Update was only allowed + * when running elevated console (with admin rights) + */ + RETURN_SKIP( + "Symlink creation requires elevated console (with admin rights)"); + } +#endif + ASSERT(s == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + + /* Test the synchronous version. */ + atime = mtime = 400497753.25; /* 1982-09-10 11:22:33.25 */ + + checkme.atime = atime; + checkme.mtime = mtime; + checkme.path = symlink_path; + req.data = &checkme; + + r = uv_fs_lutime(NULL, &req, symlink_path, atime, mtime, NULL); +#if (defined(_AIX) && !defined(_AIX71)) || \ + defined(__MVS__) + ASSERT(r == UV_ENOSYS); + RETURN_SKIP("lutime is not implemented for z/OS and AIX versions below 7.1"); +#endif + ASSERT(r == 0); + lutime_cb(&req); + ASSERT(lutime_cb_count == 1); + + /* Test the asynchronous version. */ + atime = mtime = 1291404900; /* 2010-12-03 20:35:00 */ + + checkme.atime = atime; + checkme.mtime = mtime; + checkme.path = symlink_path; + + r = uv_fs_lutime(loop, &req, symlink_path, atime, mtime, lutime_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(lutime_cb_count == 2); + + /* Cleanup. */ + unlink(path); + unlink(symlink_path); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_stat_missing_path) { + uv_fs_t req; + int r; + + loop = uv_default_loop(); + + r = uv_fs_stat(NULL, &req, "non_existent_file", NULL); + ASSERT(r == UV_ENOENT); + ASSERT(req.result == UV_ENOENT); + uv_fs_req_cleanup(&req); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_scandir_empty_dir) { + const char* path; + uv_fs_t req; + uv_dirent_t dent; + int r; + + path = "./empty_dir/"; + loop = uv_default_loop(); + + uv_fs_mkdir(NULL, &req, path, 0777, NULL); + uv_fs_req_cleanup(&req); + + /* Fill the req to ensure that required fields are cleaned up */ + memset(&req, 0xdb, sizeof(req)); + + r = uv_fs_scandir(NULL, &req, path, 0, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + ASSERT_NULL(req.ptr); + ASSERT(UV_EOF == uv_fs_scandir_next(&req, &dent)); + uv_fs_req_cleanup(&req); + + r = uv_fs_scandir(loop, &scandir_req, path, 0, empty_scandir_cb); + ASSERT(r == 0); + + ASSERT(scandir_cb_count == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(scandir_cb_count == 1); + + uv_fs_rmdir(NULL, &req, path, NULL); + uv_fs_req_cleanup(&req); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_scandir_non_existent_dir) { + const char* path; + uv_fs_t req; + uv_dirent_t dent; + int r; + + path = "./non_existent_dir/"; + loop = uv_default_loop(); + + uv_fs_rmdir(NULL, &req, path, NULL); + uv_fs_req_cleanup(&req); + + /* Fill the req to ensure that required fields are cleaned up */ + memset(&req, 0xdb, sizeof(req)); + + r = uv_fs_scandir(NULL, &req, path, 0, NULL); + ASSERT(r == UV_ENOENT); + ASSERT(req.result == UV_ENOENT); + ASSERT_NULL(req.ptr); + ASSERT(UV_ENOENT == uv_fs_scandir_next(&req, &dent)); + uv_fs_req_cleanup(&req); + + r = uv_fs_scandir(loop, &scandir_req, path, 0, non_existent_scandir_cb); + ASSERT(r == 0); + + ASSERT(scandir_cb_count == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(scandir_cb_count == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_scandir_file) { +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); +#endif + const char* path; + int r; + + path = "test/fixtures/empty_file"; + loop = uv_default_loop(); + + r = uv_fs_scandir(NULL, &scandir_req, path, 0, NULL); + ASSERT(r == UV_ENOTDIR); + uv_fs_req_cleanup(&scandir_req); + + r = uv_fs_scandir(loop, &scandir_req, path, 0, file_scandir_cb); + ASSERT(r == 0); + + ASSERT(scandir_cb_count == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(scandir_cb_count == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_open_dir) { + const char* path; + uv_fs_t req; + int r, file; + + path = "."; + loop = uv_default_loop(); + + r = uv_fs_open(NULL, &req, path, O_RDONLY, 0, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + ASSERT_NULL(req.ptr); + file = r; + uv_fs_req_cleanup(&req); + + r = uv_fs_close(NULL, &req, file, NULL); + ASSERT(r == 0); + + r = uv_fs_open(loop, &req, path, O_RDONLY, 0, open_cb_simple); + ASSERT(r == 0); + + ASSERT(open_cb_count == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(open_cb_count == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void fs_file_open_append(int add_flags) { + int r; + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, &open_req1, "test_file", + O_WRONLY | O_CREAT | add_flags, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r >= 0); + ASSERT(write_req.result >= 0); + uv_fs_req_cleanup(&write_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_open(NULL, &open_req1, "test_file", + O_RDWR | O_APPEND | add_flags, 0, NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r >= 0); + ASSERT(write_req.result >= 0); + uv_fs_req_cleanup(&write_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY | add_flags, + S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); + printf("read = %d\n", r); + ASSERT(r == 26); + ASSERT(read_req.result == 26); + ASSERT(memcmp(buf, + "test-buffer\n\0test-buffer\n\0", + sizeof("test-buffer\n\0test-buffer\n\0") - 1) == 0); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup */ + unlink("test_file"); +} +TEST_IMPL(fs_file_open_append) { + fs_file_open_append(0); + fs_file_open_append(UV_FS_O_FILEMAP); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_rename_to_existing_file) { + int r; + + /* Setup. */ + unlink("test_file"); + unlink("test_file2"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, &open_req1, "test_file", O_WRONLY | O_CREAT, + S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r >= 0); + ASSERT(write_req.result >= 0); + uv_fs_req_cleanup(&write_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_open(NULL, &open_req1, "test_file2", O_WRONLY | O_CREAT, + S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_rename(NULL, &rename_req, "test_file", "test_file2", NULL); + ASSERT(r == 0); + ASSERT(rename_req.result == 0); + uv_fs_req_cleanup(&rename_req); + + r = uv_fs_open(NULL, &open_req1, "test_file2", O_RDONLY, 0, NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + memset(buf, 0, sizeof(buf)); + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r >= 0); + ASSERT(read_req.result >= 0); + ASSERT(strcmp(buf, test_buf) == 0); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup */ + unlink("test_file"); + unlink("test_file2"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void fs_read_bufs(int add_flags) { + char scratch[768]; + uv_buf_t bufs[4]; + + ASSERT(0 <= uv_fs_open(NULL, &open_req1, + "test/fixtures/lorem_ipsum.txt", + O_RDONLY | add_flags, 0, NULL)); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + ASSERT(UV_EINVAL == uv_fs_read(NULL, &read_req, open_req1.result, + NULL, 0, 0, NULL)); + ASSERT(UV_EINVAL == uv_fs_read(NULL, &read_req, open_req1.result, + NULL, 1, 0, NULL)); + ASSERT(UV_EINVAL == uv_fs_read(NULL, &read_req, open_req1.result, + bufs, 0, 0, NULL)); + + bufs[0] = uv_buf_init(scratch + 0, 256); + bufs[1] = uv_buf_init(scratch + 256, 256); + bufs[2] = uv_buf_init(scratch + 512, 128); + bufs[3] = uv_buf_init(scratch + 640, 128); + + ASSERT(446 == uv_fs_read(NULL, + &read_req, + open_req1.result, + bufs + 0, + 2, /* 2x 256 bytes. */ + 0, /* Positional read. */ + NULL)); + ASSERT(read_req.result == 446); + uv_fs_req_cleanup(&read_req); + + ASSERT(190 == uv_fs_read(NULL, + &read_req, + open_req1.result, + bufs + 2, + 2, /* 2x 128 bytes. */ + 256, /* Positional read. */ + NULL)); + ASSERT(read_req.result == /* 446 - 256 */ 190); + uv_fs_req_cleanup(&read_req); + + ASSERT(0 == memcmp(bufs[1].base + 0, bufs[2].base, 128)); + ASSERT(0 == memcmp(bufs[1].base + 128, bufs[3].base, 190 - 128)); + + ASSERT(0 == uv_fs_close(NULL, &close_req, open_req1.result, NULL)); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); +} +TEST_IMPL(fs_read_bufs) { +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); +#endif + fs_read_bufs(0); + fs_read_bufs(UV_FS_O_FILEMAP); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void fs_read_file_eof(int add_flags) { +#if defined(__CYGWIN__) || defined(__MSYS__) + RETURN_SKIP("Cygwin pread at EOF may (incorrectly) return data!"); +#endif + int r; + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, &open_req1, "test_file", + O_WRONLY | O_CREAT | add_flags, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r >= 0); + ASSERT(write_req.result >= 0); + uv_fs_req_cleanup(&write_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY | add_flags, 0, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + memset(buf, 0, sizeof(buf)); + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r >= 0); + ASSERT(read_req.result >= 0); + ASSERT(strcmp(buf, test_buf) == 0); + uv_fs_req_cleanup(&read_req); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, + read_req.result, NULL); + ASSERT(r == 0); + ASSERT(read_req.result == 0); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup */ + unlink("test_file"); +} +TEST_IMPL(fs_read_file_eof) { + fs_read_file_eof(0); + fs_read_file_eof(UV_FS_O_FILEMAP); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void fs_write_multiple_bufs(int add_flags) { + uv_buf_t iovs[2]; + int r; + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, &open_req1, "test_file", + O_WRONLY | O_CREAT | add_flags, S_IWUSR | S_IRUSR, NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + iovs[0] = uv_buf_init(test_buf, sizeof(test_buf)); + iovs[1] = uv_buf_init(test_buf2, sizeof(test_buf2)); + r = uv_fs_write(NULL, &write_req, open_req1.result, iovs, 2, 0, NULL); + ASSERT(r >= 0); + ASSERT(write_req.result >= 0); + uv_fs_req_cleanup(&write_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY | add_flags, 0, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + memset(buf, 0, sizeof(buf)); + memset(buf2, 0, sizeof(buf2)); + /* Read the strings back to separate buffers. */ + iovs[0] = uv_buf_init(buf, sizeof(test_buf)); + iovs[1] = uv_buf_init(buf2, sizeof(test_buf2)); + ASSERT(lseek(open_req1.result, 0, SEEK_CUR) == 0); + r = uv_fs_read(NULL, &read_req, open_req1.result, iovs, 2, -1, NULL); + ASSERT(r >= 0); + ASSERT(read_req.result == sizeof(test_buf) + sizeof(test_buf2)); + ASSERT(strcmp(buf, test_buf) == 0); + ASSERT(strcmp(buf2, test_buf2) == 0); + uv_fs_req_cleanup(&read_req); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r == 0); + ASSERT(read_req.result == 0); + uv_fs_req_cleanup(&read_req); + + /* Read the strings back to separate buffers. */ + iovs[0] = uv_buf_init(buf, sizeof(test_buf)); + iovs[1] = uv_buf_init(buf2, sizeof(test_buf2)); + r = uv_fs_read(NULL, &read_req, open_req1.result, iovs, 2, 0, NULL); + ASSERT(r >= 0); + if (read_req.result == sizeof(test_buf)) { + /* Infer that preadv is not available. */ + uv_fs_req_cleanup(&read_req); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iovs[1], 1, read_req.result, NULL); + ASSERT(r >= 0); + ASSERT(read_req.result == sizeof(test_buf2)); + } else { + ASSERT(read_req.result == sizeof(test_buf) + sizeof(test_buf2)); + } + ASSERT(strcmp(buf, test_buf) == 0); + ASSERT(strcmp(buf2, test_buf2) == 0); + uv_fs_req_cleanup(&read_req); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, + sizeof(test_buf) + sizeof(test_buf2), NULL); + ASSERT(r == 0); + ASSERT(read_req.result == 0); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup */ + unlink("test_file"); +} +TEST_IMPL(fs_write_multiple_bufs) { + fs_write_multiple_bufs(0); + fs_write_multiple_bufs(UV_FS_O_FILEMAP); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void fs_write_alotof_bufs(int add_flags) { + size_t iovcount; + size_t iovmax; + uv_buf_t* iovs; + char* buffer; + size_t index; + int r; + + iovcount = 54321; + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + iovs = malloc(sizeof(*iovs) * iovcount); + ASSERT_NOT_NULL(iovs); + iovmax = uv_test_getiovmax(); + + r = uv_fs_open(NULL, + &open_req1, + "test_file", + O_RDWR | O_CREAT | add_flags, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + for (index = 0; index < iovcount; ++index) + iovs[index] = uv_buf_init(test_buf, sizeof(test_buf)); + + r = uv_fs_write(NULL, + &write_req, + open_req1.result, + iovs, + iovcount, + -1, + NULL); + ASSERT(r >= 0); + ASSERT((size_t)write_req.result == sizeof(test_buf) * iovcount); + uv_fs_req_cleanup(&write_req); + + /* Read the strings back to separate buffers. */ + buffer = malloc(sizeof(test_buf) * iovcount); + ASSERT_NOT_NULL(buffer); + + for (index = 0; index < iovcount; ++index) + iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf), + sizeof(test_buf)); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY | add_flags, 0, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + r = uv_fs_read(NULL, &read_req, open_req1.result, iovs, iovcount, -1, NULL); + if (iovcount > iovmax) + iovcount = iovmax; + ASSERT(r >= 0); + ASSERT((size_t)read_req.result == sizeof(test_buf) * iovcount); + + for (index = 0; index < iovcount; ++index) + ASSERT(strncmp(buffer + index * sizeof(test_buf), + test_buf, + sizeof(test_buf)) == 0); + + uv_fs_req_cleanup(&read_req); + free(buffer); + + ASSERT(lseek(open_req1.result, write_req.result, SEEK_SET) == write_req.result); + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, + &read_req, + open_req1.result, + &iov, + 1, + -1, + NULL); + ASSERT(r == 0); + ASSERT(read_req.result == 0); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup */ + unlink("test_file"); + free(iovs); +} +TEST_IMPL(fs_write_alotof_bufs) { + fs_write_alotof_bufs(0); + fs_write_alotof_bufs(UV_FS_O_FILEMAP); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void fs_write_alotof_bufs_with_offset(int add_flags) { + size_t iovcount; + size_t iovmax; + uv_buf_t* iovs; + char* buffer; + size_t index; + int r; + int64_t offset; + char* filler; + int filler_len; + + filler = "0123456789"; + filler_len = strlen(filler); + iovcount = 54321; + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + iovs = malloc(sizeof(*iovs) * iovcount); + ASSERT_NOT_NULL(iovs); + iovmax = uv_test_getiovmax(); + + r = uv_fs_open(NULL, + &open_req1, + "test_file", + O_RDWR | O_CREAT | add_flags, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + iov = uv_buf_init(filler, filler_len); + r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r == filler_len); + ASSERT(write_req.result == filler_len); + uv_fs_req_cleanup(&write_req); + offset = (int64_t)r; + + for (index = 0; index < iovcount; ++index) + iovs[index] = uv_buf_init(test_buf, sizeof(test_buf)); + + r = uv_fs_write(NULL, + &write_req, + open_req1.result, + iovs, + iovcount, + offset, + NULL); + ASSERT(r >= 0); + ASSERT((size_t)write_req.result == sizeof(test_buf) * iovcount); + uv_fs_req_cleanup(&write_req); + + /* Read the strings back to separate buffers. */ + buffer = malloc(sizeof(test_buf) * iovcount); + ASSERT_NOT_NULL(buffer); + + for (index = 0; index < iovcount; ++index) + iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf), + sizeof(test_buf)); + + r = uv_fs_read(NULL, &read_req, open_req1.result, + iovs, iovcount, offset, NULL); + ASSERT(r >= 0); + if (r == sizeof(test_buf)) + iovcount = 1; /* Infer that preadv is not available. */ + else if (iovcount > iovmax) + iovcount = iovmax; + ASSERT((size_t)read_req.result == sizeof(test_buf) * iovcount); + + for (index = 0; index < iovcount; ++index) + ASSERT(strncmp(buffer + index * sizeof(test_buf), + test_buf, + sizeof(test_buf)) == 0); + + uv_fs_req_cleanup(&read_req); + free(buffer); + + r = uv_fs_stat(NULL, &stat_req, "test_file", NULL); + ASSERT(r == 0); + ASSERT((int64_t)((uv_stat_t*)stat_req.ptr)->st_size == + offset + (int64_t)write_req.result); + uv_fs_req_cleanup(&stat_req); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, + &read_req, + open_req1.result, + &iov, + 1, + offset + write_req.result, + NULL); + ASSERT(r == 0); + ASSERT(read_req.result == 0); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup */ + unlink("test_file"); + free(iovs); +} +TEST_IMPL(fs_write_alotof_bufs_with_offset) { + fs_write_alotof_bufs_with_offset(0); + fs_write_alotof_bufs_with_offset(UV_FS_O_FILEMAP); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_read_dir) { + int r; + char buf[2]; + loop = uv_default_loop(); + + /* Setup */ + rmdir("test_dir"); + r = uv_fs_mkdir(loop, &mkdir_req, "test_dir", 0755, mkdir_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(mkdir_cb_count == 1); + /* Setup Done Here */ + + /* Get a file descriptor for the directory */ + r = uv_fs_open(loop, + &open_req1, + "test_dir", + UV_FS_O_RDONLY | UV_FS_O_DIRECTORY, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + uv_fs_req_cleanup(&open_req1); + + /* Try to read data from the directory */ + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, 0, NULL); +#if defined(__FreeBSD__) || \ + defined(__OpenBSD__) || \ + defined(__NetBSD__) || \ + defined(__DragonFly__) || \ + defined(_AIX) || \ + defined(__sun) || \ + defined(__MVS__) + /* + * As of now, these operating systems support reading from a directory, + * that too depends on the filesystem this temporary test directory is + * created on. That is why this assertion is a bit lenient. + */ + ASSERT((r >= 0) || (r == UV_EISDIR)); +#else + ASSERT(r == UV_EISDIR); +#endif + uv_fs_req_cleanup(&read_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup */ + rmdir("test_dir"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#ifdef _WIN32 + +TEST_IMPL(fs_partial_read) { + RETURN_SKIP("Test not implemented on Windows."); +} + +TEST_IMPL(fs_partial_write) { + RETURN_SKIP("Test not implemented on Windows."); +} + +#else /* !_WIN32 */ + +struct thread_ctx { + pthread_t pid; + int fd; + char* data; + int size; + int interval; + int doread; +}; + +static void thread_main(void* arg) { + const struct thread_ctx* ctx; + int size; + char* data; + + ctx = (struct thread_ctx*)arg; + size = ctx->size; + data = ctx->data; + + while (size > 0) { + ssize_t result; + int nbytes; + nbytes = size < ctx->interval ? size : ctx->interval; + if (ctx->doread) { + result = write(ctx->fd, data, nbytes); + /* Should not see EINTR (or other errors) */ + ASSERT(result == nbytes); + } else { + result = read(ctx->fd, data, nbytes); + /* Should not see EINTR (or other errors), + * but might get a partial read if we are faster than the writer + */ + ASSERT(result > 0 && result <= nbytes); + } + + pthread_kill(ctx->pid, SIGUSR1); + size -= result; + data += result; + } +} + +static void sig_func(uv_signal_t* handle, int signum) { + uv_signal_stop(handle); +} + +static size_t uv_test_fs_buf_offset(uv_buf_t* bufs, size_t size) { + size_t offset; + /* Figure out which bufs are done */ + for (offset = 0; size > 0 && bufs[offset].len <= size; ++offset) + size -= bufs[offset].len; + + /* Fix a partial read/write */ + if (size > 0) { + bufs[offset].base += size; + bufs[offset].len -= size; + } + return offset; +} + +static void test_fs_partial(int doread) { + struct thread_ctx ctx; + uv_thread_t thread; + uv_signal_t signal; + int pipe_fds[2]; + size_t iovcount; + uv_buf_t* iovs; + char* buffer; + size_t index; + + iovcount = 54321; + + iovs = malloc(sizeof(*iovs) * iovcount); + ASSERT_NOT_NULL(iovs); + + ctx.pid = pthread_self(); + ctx.doread = doread; + ctx.interval = 1000; + ctx.size = sizeof(test_buf) * iovcount; + ctx.data = malloc(ctx.size); + ASSERT_NOT_NULL(ctx.data); + buffer = malloc(ctx.size); + ASSERT_NOT_NULL(buffer); + + for (index = 0; index < iovcount; ++index) + iovs[index] = uv_buf_init(buffer + index * sizeof(test_buf), sizeof(test_buf)); + + loop = uv_default_loop(); + + ASSERT(0 == uv_signal_init(loop, &signal)); + ASSERT(0 == uv_signal_start(&signal, sig_func, SIGUSR1)); + + ASSERT(0 == pipe(pipe_fds)); + + ctx.fd = pipe_fds[doread]; + ASSERT(0 == uv_thread_create(&thread, thread_main, &ctx)); + + if (doread) { + uv_buf_t* read_iovs; + int nread; + read_iovs = iovs; + nread = 0; + while (nread < ctx.size) { + int result; + result = uv_fs_read(loop, &read_req, pipe_fds[0], read_iovs, iovcount, -1, NULL); + if (result > 0) { + size_t read_iovcount; + read_iovcount = uv_test_fs_buf_offset(read_iovs, result); + read_iovs += read_iovcount; + iovcount -= read_iovcount; + nread += result; + } else { + ASSERT(result == UV_EINTR); + } + uv_fs_req_cleanup(&read_req); + } + } else { + int result; + result = uv_fs_write(loop, &write_req, pipe_fds[1], iovs, iovcount, -1, NULL); + ASSERT(write_req.result == result); + ASSERT(result == ctx.size); + uv_fs_req_cleanup(&write_req); + } + + ASSERT(0 == memcmp(buffer, ctx.data, ctx.size)); + + ASSERT(0 == uv_thread_join(&thread)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + + ASSERT(0 == close(pipe_fds[1])); + uv_close((uv_handle_t*) &signal, NULL); + + { /* Make sure we read everything that we wrote. */ + int result; + result = uv_fs_read(loop, &read_req, pipe_fds[0], iovs, 1, -1, NULL); + ASSERT(result == 0); + uv_fs_req_cleanup(&read_req); + } + ASSERT(0 == close(pipe_fds[0])); + + free(iovs); + free(buffer); + free(ctx.data); + + MAKE_VALGRIND_HAPPY(); +} + +TEST_IMPL(fs_partial_read) { + test_fs_partial(1); + return 0; +} + +TEST_IMPL(fs_partial_write) { + test_fs_partial(0); + return 0; +} + +#endif/* _WIN32 */ + +TEST_IMPL(fs_read_write_null_arguments) { + int r; + + r = uv_fs_read(NULL, &read_req, 0, NULL, 0, -1, NULL); + ASSERT(r == UV_EINVAL); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_write(NULL, &write_req, 0, NULL, 0, -1, NULL); + /* Validate some memory management on failed input validation before sending + fs work to the thread pool. */ + ASSERT(r == UV_EINVAL); + ASSERT_NULL(write_req.path); + ASSERT_NULL(write_req.ptr); +#ifdef _WIN32 + ASSERT_NULL(write_req.file.pathw); + ASSERT_NULL(write_req.fs.info.new_pathw); + ASSERT_NULL(write_req.fs.info.bufs); +#else + ASSERT_NULL(write_req.new_path); + ASSERT_NULL(write_req.bufs); +#endif + uv_fs_req_cleanup(&write_req); + + iov = uv_buf_init(NULL, 0); + r = uv_fs_read(NULL, &read_req, 0, &iov, 0, -1, NULL); + ASSERT(r == UV_EINVAL); + uv_fs_req_cleanup(&read_req); + + iov = uv_buf_init(NULL, 0); + r = uv_fs_write(NULL, &write_req, 0, &iov, 0, -1, NULL); + ASSERT(r == UV_EINVAL); + uv_fs_req_cleanup(&write_req); + + /* If the arguments are invalid, the loop should not be kept open */ + loop = uv_default_loop(); + + r = uv_fs_read(loop, &read_req, 0, NULL, 0, -1, fail_cb); + ASSERT(r == UV_EINVAL); + uv_run(loop, UV_RUN_DEFAULT); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_write(loop, &write_req, 0, NULL, 0, -1, fail_cb); + ASSERT(r == UV_EINVAL); + uv_run(loop, UV_RUN_DEFAULT); + uv_fs_req_cleanup(&write_req); + + iov = uv_buf_init(NULL, 0); + r = uv_fs_read(loop, &read_req, 0, &iov, 0, -1, fail_cb); + ASSERT(r == UV_EINVAL); + uv_run(loop, UV_RUN_DEFAULT); + uv_fs_req_cleanup(&read_req); + + iov = uv_buf_init(NULL, 0); + r = uv_fs_write(loop, &write_req, 0, &iov, 0, -1, fail_cb); + ASSERT(r == UV_EINVAL); + uv_run(loop, UV_RUN_DEFAULT); + uv_fs_req_cleanup(&write_req); + + return 0; +} + + +TEST_IMPL(get_osfhandle_valid_handle) { + int r; + uv_os_fd_t fd; + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, + &open_req1, + "test_file", + O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + fd = uv_get_osfhandle(open_req1.result); +#ifdef _WIN32 + ASSERT(fd != INVALID_HANDLE_VALUE); +#else + ASSERT(fd >= 0); +#endif + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup. */ + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(open_osfhandle_valid_handle) { + int r; + uv_os_fd_t handle; + int fd; + + /* Setup. */ + unlink("test_file"); + + loop = uv_default_loop(); + + r = uv_fs_open(NULL, + &open_req1, + "test_file", + O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + handle = uv_get_osfhandle(open_req1.result); +#ifdef _WIN32 + ASSERT(handle != INVALID_HANDLE_VALUE); +#else + ASSERT(handle >= 0); +#endif + + fd = uv_open_osfhandle(handle); +#ifdef _WIN32 + ASSERT(fd > 0); +#else + ASSERT(fd == open_req1.result); +#endif + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup. */ + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(fs_file_pos_after_op_with_offset) { + int r; + + /* Setup. */ + unlink("test_file"); + loop = uv_default_loop(); + + r = uv_fs_open(loop, + &open_req1, + "test_file", + O_RDWR | O_CREAT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r > 0); + uv_fs_req_cleanup(&open_req1); + + iov = uv_buf_init(test_buf, sizeof(test_buf)); + r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, 0, NULL); + ASSERT(r == sizeof(test_buf)); + ASSERT(lseek(open_req1.result, 0, SEEK_CUR) == 0); + uv_fs_req_cleanup(&write_req); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, 0, NULL); + ASSERT(r == sizeof(test_buf)); + ASSERT(strcmp(buf, test_buf) == 0); + ASSERT(lseek(open_req1.result, 0, SEEK_CUR) == 0); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup */ + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#ifdef _WIN32 +static void fs_file_pos_common(void) { + int r; + + iov = uv_buf_init("abc", 3); + r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r == 3); + uv_fs_req_cleanup(&write_req); + + /* Read with offset should not change the position */ + iov = uv_buf_init(buf, 1); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, 1, NULL); + ASSERT(r == 1); + ASSERT(buf[0] == 'b'); + uv_fs_req_cleanup(&read_req); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&read_req); + + /* Write without offset should change the position */ + iov = uv_buf_init("d", 1); + r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r == 1); + uv_fs_req_cleanup(&write_req); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&read_req); +} + +static void fs_file_pos_close_check(const char *contents, int size) { + int r; + + /* Close */ + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&close_req); + + /* Confirm file contents */ + r = uv_fs_open(NULL, &open_req1, "test_file", O_RDONLY, 0, NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r == size); + ASSERT(strncmp(buf, contents, size) == 0); + uv_fs_req_cleanup(&read_req); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup */ + unlink("test_file"); +} + +static void fs_file_pos_write(int add_flags) { + int r; + + /* Setup. */ + unlink("test_file"); + + r = uv_fs_open(NULL, + &open_req1, + "test_file", + O_TRUNC | O_CREAT | O_RDWR | add_flags, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r > 0); + uv_fs_req_cleanup(&open_req1); + + fs_file_pos_common(); + + /* Write with offset should not change the position */ + iov = uv_buf_init("e", 1); + r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, 1, NULL); + ASSERT(r == 1); + uv_fs_req_cleanup(&write_req); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&read_req); + + fs_file_pos_close_check("aecd", 4); +} +TEST_IMPL(fs_file_pos_write) { + fs_file_pos_write(0); + fs_file_pos_write(UV_FS_O_FILEMAP); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +static void fs_file_pos_append(int add_flags) { + int r; + + /* Setup. */ + unlink("test_file"); + + r = uv_fs_open(NULL, + &open_req1, + "test_file", + O_APPEND | O_CREAT | O_RDWR | add_flags, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r > 0); + uv_fs_req_cleanup(&open_req1); + + fs_file_pos_common(); + + /* Write with offset appends (ignoring offset) + * but does not change the position */ + iov = uv_buf_init("e", 1); + r = uv_fs_write(NULL, &write_req, open_req1.result, &iov, 1, 1, NULL); + ASSERT(r == 1); + uv_fs_req_cleanup(&write_req); + + iov = uv_buf_init(buf, sizeof(buf)); + r = uv_fs_read(NULL, &read_req, open_req1.result, &iov, 1, -1, NULL); + ASSERT(r == 1); + ASSERT(buf[0] == 'e'); + uv_fs_req_cleanup(&read_req); + + fs_file_pos_close_check("abcde", 5); +} +TEST_IMPL(fs_file_pos_append) { + fs_file_pos_append(0); + fs_file_pos_append(UV_FS_O_FILEMAP); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + +TEST_IMPL(fs_null_req) { + /* Verify that all fs functions return UV_EINVAL when the request is NULL. */ + int r; + + r = uv_fs_open(NULL, NULL, NULL, 0, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_close(NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_read(NULL, NULL, 0, NULL, 0, -1, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_write(NULL, NULL, 0, NULL, 0, -1, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_unlink(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_mkdir(NULL, NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_mkdtemp(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_mkstemp(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_rmdir(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_scandir(NULL, NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_link(NULL, NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_symlink(NULL, NULL, NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_readlink(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_realpath(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_chown(NULL, NULL, NULL, 0, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_fchown(NULL, NULL, 0, 0, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_stat(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_lstat(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_fstat(NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_rename(NULL, NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_fsync(NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_fdatasync(NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_ftruncate(NULL, NULL, 0, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_copyfile(NULL, NULL, NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_sendfile(NULL, NULL, 0, 0, 0, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_access(NULL, NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_chmod(NULL, NULL, NULL, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_fchmod(NULL, NULL, 0, 0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_utime(NULL, NULL, NULL, 0.0, 0.0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_futime(NULL, NULL, 0, 0.0, 0.0, NULL); + ASSERT(r == UV_EINVAL); + + r = uv_fs_statfs(NULL, NULL, NULL, NULL); + ASSERT(r == UV_EINVAL); + + /* This should be a no-op. */ + uv_fs_req_cleanup(NULL); + + return 0; +} + +#ifdef _WIN32 +TEST_IMPL(fs_exclusive_sharing_mode) { + int r; + + /* Setup. */ + unlink("test_file"); + + ASSERT(UV_FS_O_EXLOCK > 0); + + r = uv_fs_open(NULL, + &open_req1, + "test_file", + O_RDWR | O_CREAT | UV_FS_O_EXLOCK, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + r = uv_fs_open(NULL, + &open_req2, + "test_file", + O_RDONLY | UV_FS_O_EXLOCK, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r < 0); + ASSERT(open_req2.result < 0); + uv_fs_req_cleanup(&open_req2); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + r = uv_fs_open(NULL, + &open_req2, + "test_file", + O_RDONLY | UV_FS_O_EXLOCK, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(open_req2.result >= 0); + uv_fs_req_cleanup(&open_req2); + + r = uv_fs_close(NULL, &close_req, open_req2.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* Cleanup */ + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + +#ifdef _WIN32 +TEST_IMPL(fs_file_flag_no_buffering) { + int r; + + /* Setup. */ + unlink("test_file"); + + ASSERT(UV_FS_O_APPEND > 0); + ASSERT(UV_FS_O_CREAT > 0); + ASSERT(UV_FS_O_DIRECT > 0); + ASSERT(UV_FS_O_RDWR > 0); + + /* FILE_APPEND_DATA must be excluded from FILE_GENERIC_WRITE: */ + r = uv_fs_open(NULL, + &open_req1, + "test_file", + UV_FS_O_RDWR | UV_FS_O_CREAT | UV_FS_O_DIRECT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* FILE_APPEND_DATA and FILE_FLAG_NO_BUFFERING are mutually exclusive: */ + r = uv_fs_open(NULL, + &open_req2, + "test_file", + UV_FS_O_APPEND | UV_FS_O_DIRECT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r == UV_EINVAL); + ASSERT(open_req2.result == UV_EINVAL); + uv_fs_req_cleanup(&open_req2); + + /* Cleanup */ + unlink("test_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + +#ifdef _WIN32 +int call_icacls(const char* command, ...) { + char icacls_command[1024]; + va_list args; + + va_start(args, command); + vsnprintf(icacls_command, ARRAYSIZE(icacls_command), command, args); + va_end(args); + return system(icacls_command); +} + +TEST_IMPL(fs_open_readonly_acl) { + uv_passwd_t pwd; + uv_fs_t req; + int r; + + /* + Based on Node.js test from + https://github.com/nodejs/node/commit/3ba81e34e86a5c32658e218cb6e65b13e8326bc5 + + If anything goes wrong, you can delte the test_fle_icacls with: + + icacls test_file_icacls /remove "%USERNAME%" /inheritance:e + attrib -r test_file_icacls + del test_file_icacls + */ + + /* Setup - clear the ACL and remove the file */ + loop = uv_default_loop(); + r = uv_os_get_passwd(&pwd); + ASSERT(r == 0); + call_icacls("icacls test_file_icacls /remove \"%s\" /inheritance:e", + pwd.username); + uv_fs_chmod(loop, &req, "test_file_icacls", S_IWUSR, NULL); + unlink("test_file_icacls"); + + /* Create the file */ + r = uv_fs_open(loop, + &open_req1, + "test_file_icacls", + O_RDONLY | O_CREAT, + S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(open_req1.result >= 0); + uv_fs_req_cleanup(&open_req1); + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + ASSERT(r == 0); + ASSERT(close_req.result == 0); + uv_fs_req_cleanup(&close_req); + + /* Set up ACL */ + r = call_icacls("icacls test_file_icacls /inheritance:r /remove \"%s\"", + pwd.username); + if (r != 0) { + goto acl_cleanup; + } + r = call_icacls("icacls test_file_icacls /grant \"%s\":RX", pwd.username); + if (r != 0) { + goto acl_cleanup; + } + + /* Try opening the file */ + r = uv_fs_open(NULL, &open_req1, "test_file_icacls", O_RDONLY, 0, NULL); + if (r < 0) { + goto acl_cleanup; + } + uv_fs_req_cleanup(&open_req1); + r = uv_fs_close(NULL, &close_req, open_req1.result, NULL); + if (r != 0) { + goto acl_cleanup; + } + uv_fs_req_cleanup(&close_req); + + acl_cleanup: + /* Cleanup */ + call_icacls("icacls test_file_icacls /remove \"%s\" /inheritance:e", + pwd.username); + unlink("test_file_icacls"); + uv_os_free_passwd(&pwd); + ASSERT(r == 0); + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + +#ifdef _WIN32 +TEST_IMPL(fs_fchmod_archive_readonly) { + uv_fs_t req; + uv_file file; + int r; + /* Test clearing read-only flag from files with Archive flag cleared */ + + /* Setup*/ + unlink("test_file"); + r = uv_fs_open(NULL, + &req, + "test_file", + O_WRONLY | O_CREAT, + S_IWUSR | S_IRUSR, + NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + file = req.result; + uv_fs_req_cleanup(&req); + r = uv_fs_close(NULL, &req, file, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); + /* Make the file read-only and clear archive flag */ + r = SetFileAttributes("test_file", FILE_ATTRIBUTE_READONLY); + ASSERT(r != 0); + check_permission("test_file", 0400); + /* Try fchmod */ + r = uv_fs_open(NULL, &req, "test_file", O_RDONLY, 0, NULL); + ASSERT(r >= 0); + ASSERT(req.result >= 0); + file = req.result; + uv_fs_req_cleanup(&req); + r = uv_fs_fchmod(NULL, &req, file, S_IWUSR, NULL); + ASSERT(r == 0); + ASSERT(req.result == 0); + uv_fs_req_cleanup(&req); + r = uv_fs_close(NULL, &req, file, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&req); + check_permission("test_file", S_IWUSR); + + /* Restore Archive flag for rest of the tests */ + r = SetFileAttributes("test_file", FILE_ATTRIBUTE_ARCHIVE); + ASSERT(r != 0); + + return 0; +} + +TEST_IMPL(fs_invalid_mkdir_name) { + uv_loop_t* loop; + uv_fs_t req; + int r; + + loop = uv_default_loop(); + r = uv_fs_mkdir(loop, &req, "invalid>", 0, NULL); + ASSERT(r == UV_EINVAL); + ASSERT_EQ(UV_EINVAL, uv_fs_mkdir(loop, &req, "test:lol", 0, NULL)); + + return 0; +} +#endif + +TEST_IMPL(fs_statfs) { + uv_fs_t req; + int r; + + loop = uv_default_loop(); + + /* Test the synchronous version. */ + r = uv_fs_statfs(NULL, &req, ".", NULL); + ASSERT(r == 0); + statfs_cb(&req); + ASSERT(statfs_cb_count == 1); + + /* Test the asynchronous version. */ + r = uv_fs_statfs(loop, &req, ".", statfs_cb); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + ASSERT(statfs_cb_count == 2); + + return 0; +} + +TEST_IMPL(fs_get_system_error) { + uv_fs_t req; + int r; + int system_error; + + r = uv_fs_statfs(NULL, &req, "non_existing_file", NULL); + ASSERT(r != 0); + + system_error = uv_fs_get_system_error(&req); +#ifdef _WIN32 + ASSERT(system_error == ERROR_FILE_NOT_FOUND); +#else + ASSERT(system_error == ENOENT); +#endif + + return 0; +} diff --git a/external/src/libuv/test/test-get-currentexe.c b/external/src/libuv/test/test-get-currentexe.c new file mode 100644 index 0000000..dc239cc --- /dev/null +++ b/external/src/libuv/test/test-get-currentexe.c @@ -0,0 +1,106 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +#ifndef _WIN32 +#include +#endif + +#define PATHMAX 4096 +extern char executable_path[]; + +TEST_IMPL(get_currentexe) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + + char buffer[PATHMAX]; + char path[PATHMAX]; + size_t size; + char* match; + int r; + + size = sizeof(buffer) / sizeof(buffer[0]); + r = uv_exepath(buffer, &size); + ASSERT(!r); + +#ifdef _WIN32 + snprintf(path, sizeof(path), "%s", executable_path); +#else + ASSERT_NOT_NULL(realpath(executable_path, path)); +#endif + + match = strstr(buffer, path); + /* Verify that the path returned from uv_exepath is a subdirectory of + * executable_path. + */ + ASSERT(match && !strcmp(match, path)); + ASSERT(size == strlen(buffer)); + + /* Negative tests */ + size = sizeof(buffer) / sizeof(buffer[0]); + r = uv_exepath(NULL, &size); + ASSERT(r == UV_EINVAL); + + r = uv_exepath(buffer, NULL); + ASSERT(r == UV_EINVAL); + + size = 0; + r = uv_exepath(buffer, &size); + ASSERT(r == UV_EINVAL); + + memset(buffer, -1, sizeof(buffer)); + + size = 1; + r = uv_exepath(buffer, &size); + ASSERT(r == 0); + ASSERT(size == 0); + ASSERT(buffer[0] == '\0'); + + memset(buffer, -1, sizeof(buffer)); + + size = 2; + r = uv_exepath(buffer, &size); + ASSERT(r == 0); + ASSERT(size == 1); + ASSERT(buffer[0] != '\0'); + ASSERT(buffer[1] == '\0'); + + /* Verify uv_exepath is not affected by uv_set_process_title(). */ + r = uv_set_process_title("foobar"); + ASSERT_EQ(r, 0); + size = sizeof(buffer); + r = uv_exepath(buffer, &size); + ASSERT_EQ(r, 0); + + match = strstr(buffer, path); + /* Verify that the path returned from uv_exepath is a subdirectory of + * executable_path. + */ + ASSERT_NOT_NULL(match); + ASSERT_STR_EQ(match, path); + ASSERT_EQ(size, strlen(buffer)); + return 0; +} diff --git a/external/src/libuv/test/test-get-loadavg.c b/external/src/libuv/test/test-get-loadavg.c new file mode 100644 index 0000000..4762e47 --- /dev/null +++ b/external/src/libuv/test/test-get-loadavg.c @@ -0,0 +1,35 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +TEST_IMPL(get_loadavg) { + + double avg[3] = {-1, -1, -1}; + uv_loadavg(avg); + + ASSERT(avg[0] >= 0); + ASSERT(avg[1] >= 0); + ASSERT(avg[2] >= 0); + + return 0; +} diff --git a/external/src/libuv/test/test-get-memory.c b/external/src/libuv/test/test-get-memory.c new file mode 100644 index 0000000..4555ba0 --- /dev/null +++ b/external/src/libuv/test/test-get-memory.c @@ -0,0 +1,44 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +TEST_IMPL(get_memory) { + uint64_t free_mem = uv_get_free_memory(); + uint64_t total_mem = uv_get_total_memory(); + uint64_t constrained_mem = uv_get_constrained_memory(); + + printf("free_mem=%llu, total_mem=%llu, constrained_mem=%llu\n", + (unsigned long long) free_mem, + (unsigned long long) total_mem, + (unsigned long long) constrained_mem); + + ASSERT(free_mem > 0); + ASSERT(total_mem > 0); + /* On IBMi PASE, the amount of memory in use is always zero. */ +#ifdef __PASE__ + ASSERT(total_mem == free_mem); +#else + ASSERT(total_mem > free_mem); +#endif + return 0; +} diff --git a/external/src/libuv/test/test-get-passwd.c b/external/src/libuv/test/test-get-passwd.c new file mode 100644 index 0000000..865c07d --- /dev/null +++ b/external/src/libuv/test/test-get-passwd.c @@ -0,0 +1,93 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +TEST_IMPL(get_passwd) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + + uv_passwd_t pwd; + size_t len; + int r; + + /* Test the normal case */ + r = uv_os_get_passwd(&pwd); + ASSERT(r == 0); + len = strlen(pwd.username); + ASSERT(len > 0); + +#ifdef _WIN32 + ASSERT_NULL(pwd.shell); +#else + len = strlen(pwd.shell); +# ifndef __PASE__ + ASSERT(len > 0); +# endif +#endif + + len = strlen(pwd.homedir); + ASSERT(len > 0); + +#ifdef _WIN32 + if (len == 3 && pwd.homedir[1] == ':') + ASSERT(pwd.homedir[2] == '\\'); + else + ASSERT(pwd.homedir[len - 1] != '\\'); +#else + if (len == 1) + ASSERT(pwd.homedir[0] == '/'); + else + ASSERT(pwd.homedir[len - 1] != '/'); +#endif + +#ifdef _WIN32 + ASSERT(pwd.uid == -1); + ASSERT(pwd.gid == -1); +#else + ASSERT(pwd.uid >= 0); + ASSERT(pwd.gid >= 0); +#endif + + /* Test uv_os_free_passwd() */ + uv_os_free_passwd(&pwd); + + ASSERT_NULL(pwd.username); + ASSERT_NULL(pwd.shell); + ASSERT_NULL(pwd.homedir); + + /* Test a double free */ + uv_os_free_passwd(&pwd); + + ASSERT_NULL(pwd.username); + ASSERT_NULL(pwd.shell); + ASSERT_NULL(pwd.homedir); + + /* Test invalid input */ + r = uv_os_get_passwd(NULL); + ASSERT(r == UV_EINVAL); + + return 0; +} diff --git a/external/src/libuv/test/test-getaddrinfo.c b/external/src/libuv/test/test-getaddrinfo.c new file mode 100644 index 0000000..d0b6a50 --- /dev/null +++ b/external/src/libuv/test/test-getaddrinfo.c @@ -0,0 +1,215 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +#define CONCURRENT_COUNT 10 + +static const char* name = "localhost"; + +static int getaddrinfo_cbs = 0; + +/* data used for running multiple calls concurrently */ +static uv_getaddrinfo_t* getaddrinfo_handle; +static uv_getaddrinfo_t getaddrinfo_handles[CONCURRENT_COUNT]; +static int callback_counts[CONCURRENT_COUNT]; +static int fail_cb_called; + + +static void getaddrinfo_fail_cb(uv_getaddrinfo_t* req, + int status, + struct addrinfo* res) { + + ASSERT(fail_cb_called == 0); + ASSERT(status < 0); + ASSERT_NULL(res); + uv_freeaddrinfo(res); /* Should not crash. */ + fail_cb_called++; +} + + +static void getaddrinfo_basic_cb(uv_getaddrinfo_t* handle, + int status, + struct addrinfo* res) { + ASSERT(handle == getaddrinfo_handle); + getaddrinfo_cbs++; + free(handle); + uv_freeaddrinfo(res); +} + + +static void getaddrinfo_cuncurrent_cb(uv_getaddrinfo_t* handle, + int status, + struct addrinfo* res) { + int i; + int* data = (int*)handle->data; + + for (i = 0; i < CONCURRENT_COUNT; i++) { + if (&getaddrinfo_handles[i] == handle) { + ASSERT(i == *data); + + callback_counts[i]++; + break; + } + } + ASSERT (i < CONCURRENT_COUNT); + + free(data); + uv_freeaddrinfo(res); + + getaddrinfo_cbs++; +} + + +TEST_IMPL(getaddrinfo_fail) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + + uv_getaddrinfo_t req; + + ASSERT(UV_EINVAL == uv_getaddrinfo(uv_default_loop(), + &req, + (uv_getaddrinfo_cb) abort, + NULL, + NULL, + NULL)); + + /* Use a FQDN by ending in a period */ + ASSERT(0 == uv_getaddrinfo(uv_default_loop(), + &req, + getaddrinfo_fail_cb, + "example.invalid.", + NULL, + NULL)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(fail_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(getaddrinfo_fail_sync) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + uv_getaddrinfo_t req; + + /* Use a FQDN by ending in a period */ + ASSERT(0 > uv_getaddrinfo(uv_default_loop(), + &req, + NULL, + "example.invalid.", + NULL, + NULL)); + uv_freeaddrinfo(req.addrinfo); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(getaddrinfo_basic) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + + int r; + getaddrinfo_handle = (uv_getaddrinfo_t*)malloc(sizeof(uv_getaddrinfo_t)); + + r = uv_getaddrinfo(uv_default_loop(), + getaddrinfo_handle, + &getaddrinfo_basic_cb, + name, + NULL, + NULL); + ASSERT(r == 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(getaddrinfo_cbs == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(getaddrinfo_basic_sync) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + uv_getaddrinfo_t req; + + ASSERT(0 == uv_getaddrinfo(uv_default_loop(), + &req, + NULL, + name, + NULL, + NULL)); + uv_freeaddrinfo(req.addrinfo); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(getaddrinfo_concurrent) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + + int i, r; + int* data; + + for (i = 0; i < CONCURRENT_COUNT; i++) { + callback_counts[i] = 0; + + data = (int*)malloc(sizeof(int)); + ASSERT_NOT_NULL(data); + *data = i; + getaddrinfo_handles[i].data = data; + + r = uv_getaddrinfo(uv_default_loop(), + &getaddrinfo_handles[i], + &getaddrinfo_cuncurrent_cb, + name, + NULL, + NULL); + ASSERT(r == 0); + } + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + for (i = 0; i < CONCURRENT_COUNT; i++) { + ASSERT(callback_counts[i] == 1); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-gethostname.c b/external/src/libuv/test/test-gethostname.c new file mode 100644 index 0000000..1a9816d --- /dev/null +++ b/external/src/libuv/test/test-gethostname.c @@ -0,0 +1,58 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +TEST_IMPL(gethostname) { + char buf[UV_MAXHOSTNAMESIZE]; + size_t size; + size_t enobufs_size; + int r; + + /* Reject invalid inputs */ + size = 1; + r = uv_os_gethostname(NULL, &size); + ASSERT(r == UV_EINVAL); + r = uv_os_gethostname(buf, NULL); + ASSERT(r == UV_EINVAL); + size = 0; + r = uv_os_gethostname(buf, &size); + ASSERT(r == UV_EINVAL); + + /* Return UV_ENOBUFS if the buffer cannot hold the hostname */ + enobufs_size = 1; + buf[0] = '\0'; + r = uv_os_gethostname(buf, &enobufs_size); + ASSERT(r == UV_ENOBUFS); + ASSERT(buf[0] == '\0'); + ASSERT(enobufs_size > 1); + + /* Successfully get the hostname */ + size = UV_MAXHOSTNAMESIZE; + r = uv_os_gethostname(buf, &size); + ASSERT(r == 0); + ASSERT(size > 0 && size == strlen(buf)); + ASSERT(size + 1 == enobufs_size); + + return 0; +} diff --git a/external/src/libuv/test/test-getnameinfo.c b/external/src/libuv/test/test-getnameinfo.c new file mode 100644 index 0000000..2bfedd3 --- /dev/null +++ b/external/src/libuv/test/test-getnameinfo.c @@ -0,0 +1,116 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +*/ + +#include "uv.h" +#include "task.h" +#include +#include +#include + + +static const char* address_ip4 = "127.0.0.1"; +static const char* address_ip6 = "::1"; +static const int port = 80; + +static struct sockaddr_in addr4; +static struct sockaddr_in6 addr6; +static uv_getnameinfo_t req; + +static void getnameinfo_req(uv_getnameinfo_t* handle, + int status, + const char* hostname, + const char* service) { + ASSERT_NOT_NULL(handle); + ASSERT(status == 0); + ASSERT_NOT_NULL(hostname); + ASSERT_NOT_NULL(service); +} + + +TEST_IMPL(getnameinfo_basic_ip4) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + + int r; + + r = uv_ip4_addr(address_ip4, port, &addr4); + ASSERT(r == 0); + + r = uv_getnameinfo(uv_default_loop(), + &req, + &getnameinfo_req, + (const struct sockaddr*)&addr4, + 0); + ASSERT(r == 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(getnameinfo_basic_ip4_sync) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + + ASSERT(0 == uv_ip4_addr(address_ip4, port, &addr4)); + + ASSERT(0 == uv_getnameinfo(uv_default_loop(), + &req, + NULL, + (const struct sockaddr*)&addr4, + 0)); + ASSERT(req.host[0] != '\0'); + ASSERT(req.service[0] != '\0'); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(getnameinfo_basic_ip6) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + + int r; + + r = uv_ip6_addr(address_ip6, port, &addr6); + ASSERT(r == 0); + + r = uv_getnameinfo(uv_default_loop(), + &req, + &getnameinfo_req, + (const struct sockaddr*)&addr6, + 0); + ASSERT(r == 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-getsockname.c b/external/src/libuv/test/test-getsockname.c new file mode 100644 index 0000000..7c77fcb --- /dev/null +++ b/external/src/libuv/test/test-getsockname.c @@ -0,0 +1,361 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +static const int server_port = TEST_PORT; +/* Will be updated right after making the uv_connect_call */ +static int connect_port = -1; + +static int getsocknamecount = 0; +static int getpeernamecount = 0; + +static uv_loop_t* loop; +static uv_tcp_t tcp; +static uv_udp_t udp; +static uv_connect_t connect_req; +static uv_tcp_t tcpServer; +static uv_udp_t udpServer; +static uv_udp_send_t send_req; + + +static void alloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { + buf->base = malloc(suggested_size); + buf->len = suggested_size; +} + + +static void on_close(uv_handle_t* peer) { + free(peer); + uv_close((uv_handle_t*)&tcpServer, NULL); +} + + +static void after_shutdown(uv_shutdown_t* req, int status) { + uv_close((uv_handle_t*) req->handle, on_close); + free(req); +} + + +static void after_read(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + uv_shutdown_t* req; + int r; + + if (buf->base) { + free(buf->base); + } + + req = (uv_shutdown_t*) malloc(sizeof *req); + r = uv_shutdown(req, handle, after_shutdown); + ASSERT(r == 0); +} + + +static void check_sockname(struct sockaddr* addr, const char* compare_ip, + int compare_port, const char* context) { + struct sockaddr_in check_addr = *(struct sockaddr_in*) addr; + struct sockaddr_in compare_addr; + char check_ip[17]; + int r; + + ASSERT(0 == uv_ip4_addr(compare_ip, compare_port, &compare_addr)); + + /* Both addresses should be ipv4 */ + ASSERT(check_addr.sin_family == AF_INET); + ASSERT(compare_addr.sin_family == AF_INET); + + /* Check if the ip matches */ + ASSERT(memcmp(&check_addr.sin_addr, + &compare_addr.sin_addr, + sizeof compare_addr.sin_addr) == 0); + + /* Check if the port matches. If port == 0 anything goes. */ + ASSERT(compare_port == 0 || check_addr.sin_port == compare_addr.sin_port); + + r = uv_ip4_name(&check_addr, (char*) check_ip, sizeof check_ip); + ASSERT(r == 0); + + printf("%s: %s:%d\n", context, check_ip, ntohs(check_addr.sin_port)); +} + + +static void on_connection(uv_stream_t* server, int status) { + struct sockaddr sockname, peername; + int namelen; + uv_tcp_t* handle; + int r; + + if (status != 0) { + fprintf(stderr, "Connect error %s\n", uv_err_name(status)); + } + ASSERT(status == 0); + + handle = malloc(sizeof(*handle)); + ASSERT_NOT_NULL(handle); + + r = uv_tcp_init(loop, handle); + ASSERT(r == 0); + + /* associate server with stream */ + handle->data = server; + + r = uv_accept(server, (uv_stream_t*)handle); + ASSERT(r == 0); + + namelen = sizeof sockname; + r = uv_tcp_getsockname(handle, &sockname, &namelen); + ASSERT(r == 0); + check_sockname(&sockname, "127.0.0.1", server_port, "accepted socket"); + getsocknamecount++; + + namelen = sizeof peername; + r = uv_tcp_getpeername(handle, &peername, &namelen); + ASSERT(r == 0); + check_sockname(&peername, "127.0.0.1", connect_port, "accepted socket peer"); + getpeernamecount++; + + r = uv_read_start((uv_stream_t*)handle, alloc, after_read); + ASSERT(r == 0); +} + + +static void on_connect(uv_connect_t* req, int status) { + struct sockaddr sockname, peername; + int r, namelen; + + ASSERT(status == 0); + + namelen = sizeof sockname; + r = uv_tcp_getsockname((uv_tcp_t*) req->handle, &sockname, &namelen); + ASSERT(r == 0); + check_sockname(&sockname, "127.0.0.1", 0, "connected socket"); + getsocknamecount++; + + namelen = sizeof peername; + r = uv_tcp_getpeername((uv_tcp_t*) req->handle, &peername, &namelen); + ASSERT(r == 0); + check_sockname(&peername, "127.0.0.1", server_port, "connected socket peer"); + getpeernamecount++; + + uv_close((uv_handle_t*)&tcp, NULL); +} + + +static int tcp_listener(void) { + struct sockaddr_in addr; + struct sockaddr sockname, peername; + int namelen; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", server_port, &addr)); + + r = uv_tcp_init(loop, &tcpServer); + if (r) { + fprintf(stderr, "Socket creation error\n"); + return 1; + } + + r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr, 0); + if (r) { + fprintf(stderr, "Bind error\n"); + return 1; + } + + r = uv_listen((uv_stream_t*)&tcpServer, 128, on_connection); + if (r) { + fprintf(stderr, "Listen error\n"); + return 1; + } + + memset(&sockname, -1, sizeof sockname); + namelen = sizeof sockname; + r = uv_tcp_getsockname(&tcpServer, &sockname, &namelen); + ASSERT(r == 0); + check_sockname(&sockname, "0.0.0.0", server_port, "server socket"); + getsocknamecount++; + + namelen = sizeof sockname; + r = uv_tcp_getpeername(&tcpServer, &peername, &namelen); + ASSERT(r == UV_ENOTCONN); + getpeernamecount++; + + return 0; +} + + +static void tcp_connector(void) { + struct sockaddr_in server_addr; + struct sockaddr sockname; + int r, namelen; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", server_port, &server_addr)); + + r = uv_tcp_init(loop, &tcp); + tcp.data = &connect_req; + ASSERT(!r); + + r = uv_tcp_connect(&connect_req, + &tcp, + (const struct sockaddr*) &server_addr, + on_connect); + ASSERT(!r); + + /* Fetch the actual port used by the connecting socket. */ + namelen = sizeof sockname; + r = uv_tcp_getsockname(&tcp, &sockname, &namelen); + ASSERT(!r); + ASSERT(sockname.sa_family == AF_INET); + connect_port = ntohs(((struct sockaddr_in*) &sockname)->sin_port); + ASSERT(connect_port > 0); +} + + +static void udp_recv(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags) { + struct sockaddr sockname; + int namelen; + int r; + + ASSERT(nread >= 0); + free(buf->base); + + if (nread == 0) { + return; + } + + memset(&sockname, -1, sizeof sockname); + namelen = sizeof(sockname); + r = uv_udp_getsockname(&udp, &sockname, &namelen); + ASSERT(r == 0); + check_sockname(&sockname, "0.0.0.0", 0, "udp receiving socket"); + getsocknamecount++; + + uv_close((uv_handle_t*) &udp, NULL); + uv_close((uv_handle_t*) handle, NULL); +} + + +static void udp_send(uv_udp_send_t* req, int status) { + +} + + +static int udp_listener(void) { + struct sockaddr_in addr; + struct sockaddr sockname; + int namelen; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", server_port, &addr)); + + r = uv_udp_init(loop, &udpServer); + if (r) { + fprintf(stderr, "Socket creation error\n"); + return 1; + } + + r = uv_udp_bind(&udpServer, (const struct sockaddr*) &addr, 0); + if (r) { + fprintf(stderr, "Bind error\n"); + return 1; + } + + memset(&sockname, -1, sizeof sockname); + namelen = sizeof sockname; + r = uv_udp_getsockname(&udpServer, &sockname, &namelen); + ASSERT(r == 0); + check_sockname(&sockname, "0.0.0.0", server_port, "udp listener socket"); + getsocknamecount++; + + r = uv_udp_recv_start(&udpServer, alloc, udp_recv); + ASSERT(r == 0); + + return 0; +} + + +static void udp_sender(void) { + struct sockaddr_in server_addr; + uv_buf_t buf; + int r; + + r = uv_udp_init(loop, &udp); + ASSERT(!r); + + buf = uv_buf_init("PING", 4); + ASSERT(0 == uv_ip4_addr("127.0.0.1", server_port, &server_addr)); + + r = uv_udp_send(&send_req, + &udp, + &buf, + 1, + (const struct sockaddr*) &server_addr, + udp_send); + ASSERT(!r); +} + + +TEST_IMPL(getsockname_tcp) { + loop = uv_default_loop(); + + if (tcp_listener()) + return 1; + + tcp_connector(); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(getsocknamecount == 3); + ASSERT(getpeernamecount == 3); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(getsockname_udp) { + loop = uv_default_loop(); + + if (udp_listener()) + return 1; + + udp_sender(); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(getsocknamecount == 2); + + ASSERT(udp.send_queue_size == 0); + ASSERT(udpServer.send_queue_size == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-getters-setters.c b/external/src/libuv/test/test-getters-setters.c new file mode 100644 index 0000000..2a37122 --- /dev/null +++ b/external/src/libuv/test/test-getters-setters.c @@ -0,0 +1,109 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + +int cookie1; +int cookie2; +int cookie3; + + +TEST_IMPL(handle_type_name) { + ASSERT(strcmp(uv_handle_type_name(UV_NAMED_PIPE), "pipe") == 0); + ASSERT(strcmp(uv_handle_type_name(UV_UDP), "udp") == 0); + ASSERT(strcmp(uv_handle_type_name(UV_FILE), "file") == 0); + ASSERT_NULL(uv_handle_type_name(UV_HANDLE_TYPE_MAX)); + ASSERT_NULL(uv_handle_type_name(UV_HANDLE_TYPE_MAX + 1)); + ASSERT_NULL(uv_handle_type_name(UV_UNKNOWN_HANDLE)); + return 0; +} + + +TEST_IMPL(req_type_name) { + ASSERT(strcmp(uv_req_type_name(UV_REQ), "req") == 0); + ASSERT(strcmp(uv_req_type_name(UV_UDP_SEND), "udp_send") == 0); + ASSERT(strcmp(uv_req_type_name(UV_WORK), "work") == 0); + ASSERT_NULL(uv_req_type_name(UV_REQ_TYPE_MAX)); + ASSERT_NULL(uv_req_type_name(UV_REQ_TYPE_MAX + 1)); + ASSERT_NULL(uv_req_type_name(UV_UNKNOWN_REQ)); + return 0; +} + + +TEST_IMPL(getters_setters) { + uv_loop_t* loop; + uv_pipe_t* pipe; + uv_fs_t* fs; + int r; + + loop = malloc(uv_loop_size()); + ASSERT_NOT_NULL(loop); + r = uv_loop_init(loop); + ASSERT(r == 0); + + uv_loop_set_data(loop, &cookie1); + ASSERT(loop->data == &cookie1); + ASSERT(uv_loop_get_data(loop) == &cookie1); + + pipe = malloc(uv_handle_size(UV_NAMED_PIPE)); + r = uv_pipe_init(loop, pipe, 0); + ASSERT(uv_handle_get_type((uv_handle_t*)pipe) == UV_NAMED_PIPE); + + ASSERT(uv_handle_get_loop((uv_handle_t*)pipe) == loop); + pipe->data = &cookie2; + ASSERT(uv_handle_get_data((uv_handle_t*)pipe) == &cookie2); + uv_handle_set_data((uv_handle_t*)pipe, &cookie1); + ASSERT(uv_handle_get_data((uv_handle_t*)pipe) == &cookie1); + ASSERT(pipe->data == &cookie1); + + ASSERT(uv_stream_get_write_queue_size((uv_stream_t*)pipe) == 0); + pipe->write_queue_size++; + ASSERT(uv_stream_get_write_queue_size((uv_stream_t*)pipe) == 1); + pipe->write_queue_size--; + uv_close((uv_handle_t*)pipe, NULL); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + fs = malloc(uv_req_size(UV_FS)); + uv_fs_stat(loop, fs, ".", NULL); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(uv_fs_get_type(fs) == UV_FS_STAT); + ASSERT(uv_fs_get_result(fs) == 0); + ASSERT(uv_fs_get_ptr(fs) == uv_fs_get_statbuf(fs)); + ASSERT(uv_fs_get_statbuf(fs)->st_mode & S_IFDIR); + ASSERT(strcmp(uv_fs_get_path(fs), ".") == 0); + uv_fs_req_cleanup(fs); + + r = uv_loop_close(loop); + ASSERT(r == 0); + + free(pipe); + free(fs); + free(loop); + return 0; +} diff --git a/external/src/libuv/test/test-gettimeofday.c b/external/src/libuv/test/test-gettimeofday.c new file mode 100644 index 0000000..4ebc11f --- /dev/null +++ b/external/src/libuv/test/test-gettimeofday.c @@ -0,0 +1,39 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +TEST_IMPL(gettimeofday) { + uv_timeval64_t tv; + int r; + + tv.tv_sec = 0; + r = uv_gettimeofday(&tv); + ASSERT(r == 0); + ASSERT(tv.tv_sec != 0); + + /* Test invalid input. */ + r = uv_gettimeofday(NULL); + ASSERT(r == UV_EINVAL); + + return 0; +} diff --git a/external/src/libuv/test/test-handle-fileno.c b/external/src/libuv/test/test-handle-fileno.c new file mode 100644 index 0000000..8a093e2 --- /dev/null +++ b/external/src/libuv/test/test-handle-fileno.c @@ -0,0 +1,125 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + + +static int get_tty_fd(void) { + /* Make sure we have an FD that refers to a tty */ +#ifdef _WIN32 + HANDLE handle; + handle = CreateFileA("conin$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (handle == INVALID_HANDLE_VALUE) + return -1; + return _open_osfhandle((intptr_t) handle, 0); +#else /* unix */ + return open("/dev/tty", O_RDONLY, 0); +#endif +} + + +TEST_IMPL(handle_fileno) { + int r; + int tty_fd; + struct sockaddr_in addr; + uv_os_fd_t fd; + uv_tcp_t tcp; + uv_udp_t udp; + uv_pipe_t pipe; + uv_tty_t tty; + uv_idle_t idle; + uv_loop_t* loop; + + loop = uv_default_loop(); + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_idle_init(loop, &idle); + ASSERT(r == 0); + r = uv_fileno((uv_handle_t*) &idle, &fd); + ASSERT(r == UV_EINVAL); + uv_close((uv_handle_t*) &idle, NULL); + + r = uv_tcp_init(loop, &tcp); + ASSERT(r == 0); + r = uv_fileno((uv_handle_t*) &tcp, &fd); + ASSERT(r == UV_EBADF); + r = uv_tcp_bind(&tcp, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + r = uv_fileno((uv_handle_t*) &tcp, &fd); + ASSERT(r == 0); + uv_close((uv_handle_t*) &tcp, NULL); + r = uv_fileno((uv_handle_t*) &tcp, &fd); + ASSERT(r == UV_EBADF); + + r = uv_udp_init(loop, &udp); + ASSERT(r == 0); + r = uv_fileno((uv_handle_t*) &udp, &fd); + ASSERT(r == UV_EBADF); + r = uv_udp_bind(&udp, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + r = uv_fileno((uv_handle_t*) &udp, &fd); + ASSERT(r == 0); + uv_close((uv_handle_t*) &udp, NULL); + r = uv_fileno((uv_handle_t*) &udp, &fd); + ASSERT(r == UV_EBADF); + + r = uv_pipe_init(loop, &pipe, 0); + ASSERT(r == 0); + r = uv_fileno((uv_handle_t*) &pipe, &fd); + ASSERT(r == UV_EBADF); + r = uv_pipe_bind(&pipe, TEST_PIPENAME); + ASSERT(r == 0); + r = uv_fileno((uv_handle_t*) &pipe, &fd); + ASSERT(r == 0); + uv_close((uv_handle_t*) &pipe, NULL); + r = uv_fileno((uv_handle_t*) &pipe, &fd); + ASSERT(r == UV_EBADF); + + tty_fd = get_tty_fd(); + if (tty_fd < 0) { + fprintf(stderr, "Cannot open a TTY fd"); + fflush(stderr); + } else { + r = uv_tty_init(loop, &tty, tty_fd, 0); + ASSERT(r == 0); + ASSERT(uv_is_readable((uv_stream_t*) &tty)); + ASSERT(!uv_is_writable((uv_stream_t*) &tty)); + r = uv_fileno((uv_handle_t*) &tty, &fd); + ASSERT(r == 0); + uv_close((uv_handle_t*) &tty, NULL); + r = uv_fileno((uv_handle_t*) &tty, &fd); + ASSERT(r == UV_EBADF); + ASSERT(!uv_is_readable((uv_stream_t*) &tty)); + ASSERT(!uv_is_writable((uv_stream_t*) &tty)); + } + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-homedir.c b/external/src/libuv/test/test-homedir.c new file mode 100644 index 0000000..508351f --- /dev/null +++ b/external/src/libuv/test/test-homedir.c @@ -0,0 +1,72 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +#define PATHMAX 4096 +#define SMALLPATH 1 + +TEST_IMPL(homedir) { + char homedir[PATHMAX]; + size_t len; + int r; + + /* Test the normal case */ + len = sizeof homedir; + homedir[0] = '\0'; + ASSERT(strlen(homedir) == 0); + r = uv_os_homedir(homedir, &len); + ASSERT(r == 0); + ASSERT(strlen(homedir) == len); + ASSERT(len > 0); + ASSERT(homedir[len] == '\0'); + +#ifdef _WIN32 + if (len == 3 && homedir[1] == ':') + ASSERT(homedir[2] == '\\'); + else + ASSERT(homedir[len - 1] != '\\'); +#else + if (len == 1) + ASSERT(homedir[0] == '/'); + else + ASSERT(homedir[len - 1] != '/'); +#endif + + /* Test the case where the buffer is too small */ + len = SMALLPATH; + r = uv_os_homedir(homedir, &len); + ASSERT(r == UV_ENOBUFS); + ASSERT(len > SMALLPATH); + + /* Test invalid inputs */ + r = uv_os_homedir(NULL, &len); + ASSERT(r == UV_EINVAL); + r = uv_os_homedir(homedir, NULL); + ASSERT(r == UV_EINVAL); + len = 0; + r = uv_os_homedir(homedir, &len); + ASSERT(r == UV_EINVAL); + + return 0; +} diff --git a/external/src/libuv/test/test-hrtime.c b/external/src/libuv/test/test-hrtime.c new file mode 100644 index 0000000..9d461d9 --- /dev/null +++ b/external/src/libuv/test/test-hrtime.c @@ -0,0 +1,52 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#ifndef MILLISEC +# define MILLISEC 1000 +#endif + +#ifndef NANOSEC +# define NANOSEC ((uint64_t) 1e9) +#endif + + +TEST_IMPL(hrtime) { + uint64_t a, b, diff; + int i = 75; + while (i > 0) { + a = uv_hrtime(); + uv_sleep(45); + b = uv_hrtime(); + + diff = b - a; + + /* The windows Sleep() function has only a resolution of 10-20 ms. Check + * that the difference between the two hrtime values has a reasonable + * lower bound. + */ + ASSERT(diff > (uint64_t) 25 * NANOSEC / MILLISEC); + --i; + } + return 0; +} diff --git a/external/src/libuv/test/test-idle.c b/external/src/libuv/test/test-idle.c new file mode 100644 index 0000000..f49d196 --- /dev/null +++ b/external/src/libuv/test/test-idle.c @@ -0,0 +1,99 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + + +static uv_idle_t idle_handle; +static uv_check_t check_handle; +static uv_timer_t timer_handle; + +static int idle_cb_called = 0; +static int check_cb_called = 0; +static int timer_cb_called = 0; +static int close_cb_called = 0; + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + + +static void timer_cb(uv_timer_t* handle) { + ASSERT(handle == &timer_handle); + + uv_close((uv_handle_t*) &idle_handle, close_cb); + uv_close((uv_handle_t*) &check_handle, close_cb); + uv_close((uv_handle_t*) &timer_handle, close_cb); + + timer_cb_called++; + fprintf(stderr, "timer_cb %d\n", timer_cb_called); + fflush(stderr); +} + + +static void idle_cb(uv_idle_t* handle) { + ASSERT(handle == &idle_handle); + + idle_cb_called++; + fprintf(stderr, "idle_cb %d\n", idle_cb_called); + fflush(stderr); +} + + +static void check_cb(uv_check_t* handle) { + ASSERT(handle == &check_handle); + + check_cb_called++; + fprintf(stderr, "check_cb %d\n", check_cb_called); + fflush(stderr); +} + + +TEST_IMPL(idle_starvation) { + int r; + + r = uv_idle_init(uv_default_loop(), &idle_handle); + ASSERT(r == 0); + r = uv_idle_start(&idle_handle, idle_cb); + ASSERT(r == 0); + + r = uv_check_init(uv_default_loop(), &check_handle); + ASSERT(r == 0); + r = uv_check_start(&check_handle, check_cb); + ASSERT(r == 0); + + r = uv_timer_init(uv_default_loop(), &timer_handle); + ASSERT(r == 0); + r = uv_timer_start(&timer_handle, timer_cb, 50, 0); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(idle_cb_called > 0); + ASSERT(timer_cb_called == 1); + ASSERT(close_cb_called == 3); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-idna.c b/external/src/libuv/test/test-idna.c new file mode 100644 index 0000000..f4fad96 --- /dev/null +++ b/external/src/libuv/test/test-idna.c @@ -0,0 +1,214 @@ +/* Copyright The libuv project and contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" +#include "../src/idna.c" +#include + +TEST_IMPL(utf8_decode1) { + const char* p; + char b[32]; + int i; + + /* ASCII. */ + p = b; + snprintf(b, sizeof(b), "%c\x7F", 0x00); + ASSERT(0 == uv__utf8_decode1(&p, b + sizeof(b))); + ASSERT(p == b + 1); + ASSERT(127 == uv__utf8_decode1(&p, b + sizeof(b))); + ASSERT(p == b + 2); + + /* Two-byte sequences. */ + p = b; + snprintf(b, sizeof(b), "\xC2\x80\xDF\xBF"); + ASSERT(128 == uv__utf8_decode1(&p, b + sizeof(b))); + ASSERT(p == b + 2); + ASSERT(0x7FF == uv__utf8_decode1(&p, b + sizeof(b))); + ASSERT(p == b + 4); + + /* Three-byte sequences. */ + p = b; + snprintf(b, sizeof(b), "\xE0\xA0\x80\xEF\xBF\xBF"); + ASSERT(0x800 == uv__utf8_decode1(&p, b + sizeof(b))); + ASSERT(p == b + 3); + ASSERT(0xFFFF == uv__utf8_decode1(&p, b + sizeof(b))); + ASSERT(p == b + 6); + + /* Four-byte sequences. */ + p = b; + snprintf(b, sizeof(b), "\xF0\x90\x80\x80\xF4\x8F\xBF\xBF"); + ASSERT(0x10000 == uv__utf8_decode1(&p, b + sizeof(b))); + ASSERT(p == b + 4); + ASSERT(0x10FFFF == uv__utf8_decode1(&p, b + sizeof(b))); + ASSERT(p == b + 8); + + /* Four-byte sequences > U+10FFFF; disallowed. */ + p = b; + snprintf(b, sizeof(b), "\xF4\x90\xC0\xC0\xF7\xBF\xBF\xBF"); + ASSERT((unsigned) -1 == uv__utf8_decode1(&p, b + sizeof(b))); + ASSERT(p == b + 4); + ASSERT((unsigned) -1 == uv__utf8_decode1(&p, b + sizeof(b))); + ASSERT(p == b + 8); + + /* Overlong; disallowed. */ + p = b; + snprintf(b, sizeof(b), "\xC0\x80\xC1\x80"); + ASSERT((unsigned) -1 == uv__utf8_decode1(&p, b + sizeof(b))); + ASSERT(p == b + 2); + ASSERT((unsigned) -1 == uv__utf8_decode1(&p, b + sizeof(b))); + ASSERT(p == b + 4); + + /* Surrogate pairs; disallowed. */ + p = b; + snprintf(b, sizeof(b), "\xED\xA0\x80\xED\xA3\xBF"); + ASSERT((unsigned) -1 == uv__utf8_decode1(&p, b + sizeof(b))); + ASSERT(p == b + 3); + ASSERT((unsigned) -1 == uv__utf8_decode1(&p, b + sizeof(b))); + ASSERT(p == b + 6); + + /* Simply illegal. */ + p = b; + snprintf(b, sizeof(b), "\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF"); + + for (i = 1; i <= 8; i++) { + ASSERT((unsigned) -1 == uv__utf8_decode1(&p, b + sizeof(b))); + ASSERT(p == b + i); + } + + return 0; +} + +TEST_IMPL(utf8_decode1_overrun) { + const char* p; + char b[1]; + + /* Single byte. */ + p = b; + b[0] = 0x7F; + ASSERT_EQ(0x7F, uv__utf8_decode1(&p, b + 1)); + ASSERT_EQ(p, b + 1); + + /* Multi-byte. */ + p = b; + b[0] = 0xC0; + ASSERT_EQ((unsigned) -1, uv__utf8_decode1(&p, b + 1)); + ASSERT_EQ(p, b + 1); + + return 0; +} + +/* Doesn't work on z/OS because that platform uses EBCDIC, not ASCII. */ +#ifndef __MVS__ + +#define F(input, err) \ + do { \ + char d[256] = {0}; \ + static const char s[] = "" input ""; \ + ASSERT(err == uv__idna_toascii(s, s + sizeof(s) - 1, d, d + sizeof(d))); \ + } while (0) + +#define T(input, expected) \ + do { \ + long n; \ + char d1[256] = {0}; \ + char d2[256] = {0}; \ + static const char s[] = "" input ""; \ + n = uv__idna_toascii(s, s + sizeof(s) - 1, d1, d1 + sizeof(d1)); \ + ASSERT(n == sizeof(expected)); \ + ASSERT(0 == memcmp(d1, expected, n)); \ + /* Sanity check: encoding twice should not change the output. */ \ + n = uv__idna_toascii(d1, d1 + strlen(d1), d2, d2 + sizeof(d2)); \ + ASSERT(n == sizeof(expected)); \ + ASSERT(0 == memcmp(d2, expected, n)); \ + ASSERT(0 == memcmp(d1, d2, sizeof(d2))); \ + } while (0) + +TEST_IMPL(idna_toascii) { + /* Illegal inputs. */ + F("\xC0\x80\xC1\x80", UV_EINVAL); /* Overlong UTF-8 sequence. */ + F("\xC0\x80\xC1\x80.com", UV_EINVAL); /* Overlong UTF-8 sequence. */ + /* No conversion. */ + T("", ""); + T(".", "."); + T(".com", ".com"); + T("example", "example"); + T("example-", "example-"); + T("straße.de", "xn--strae-oqa.de"); + /* Test cases adapted from punycode.js. Most are from RFC 3492. */ + T("foo.bar", "foo.bar"); + T("mañana.com", "xn--maana-pta.com"); + T("example.com.", "example.com."); + T("bücher.com", "xn--bcher-kva.com"); + T("café.com", "xn--caf-dma.com"); + T("café.café.com", "xn--caf-dma.xn--caf-dma.com"); + T("☃-⌘.com", "xn----dqo34k.com"); + T("í€â˜ƒ-⌘.com", "xn----dqo34kn65z.com"); + T("💩.la", "xn--ls8h.la"); + T("mañana.com", "xn--maana-pta.com"); + T("mañana。com", "xn--maana-pta.com"); + T("mañana.com", "xn--maana-pta.com"); + T("mañana。com", "xn--maana-pta.com"); + T("ü", "xn--tda"); + T(".ü", ".xn--tda"); + T("ü.ü", "xn--tda.xn--tda"); + T("ü.ü.", "xn--tda.xn--tda."); + T("üëäö♥", "xn--4can8av2009b"); + T("Willst du die Blüthe des frühen, die Früchte des späteren Jahres", + "xn--Willst du die Blthe des frhen, " + "die Frchte des spteren Jahres-x9e96lkal"); + T("ليهمابتكلموشعربي؟", "xn--egbpdaj6bu4bxfgehfvwxn"); + T("他们为什么ä¸è¯´ä¸­æ–‡", "xn--ihqwcrb4cv8a8dqg056pqjye"); + T("他們爲什麽ä¸èªªä¸­æ–‡", "xn--ihqwctvzc91f659drss3x8bo0yb"); + T("ProÄprostÄ›nemluvíÄesky", "xn--Proprostnemluvesky-uyb24dma41a"); + T("למהה×פשוטל×מדברי×עברית", "xn--4dbcagdahymbxekheh6e0a7fei0b"); + T("यहलोगहिनà¥à¤¦à¥€à¤•à¥à¤¯à¥‹à¤‚नहींबोलसकतेहैं", + "xn--i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd"); + T("ãªãœã¿ã‚“ãªæ—¥æœ¬èªžã‚’話ã—ã¦ãã‚Œãªã„ã®ã‹", + "xn--n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa"); + T("세계ì˜ëª¨ë“ ì‚¬ëžŒë“¤ì´í•œêµ­ì–´ë¥¼ì´í•´í•œë‹¤ë©´ì–¼ë§ˆë‚˜ì¢‹ì„까", + "xn--989aomsvi5e83db1d2a355cv1e0vak1d" + "wrv93d5xbh15a0dt30a5jpsd879ccm6fea98c"); + T("почемужеонинеговорÑтпоруÑÑки", "xn--b1abfaaepdrnnbgefbadotcwatmq2g4l"); + T("PorquénopuedensimplementehablarenEspañol", + "xn--PorqunopuedensimplementehablarenEspaol-fmd56a"); + T("Tạisaohá»khôngthểchỉnóitiếngViệt", + "xn--TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g"); + T("3å¹´B組金八先生", "xn--3B-ww4c5e180e575a65lsy2b"); + T("安室奈美æµ-with-SUPER-MONKEYS", + "xn---with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n"); + T("Hello-Another-Way-ãã‚Œãžã‚Œã®å ´æ‰€", + "xn--Hello-Another-Way--fc4qua05auwb3674vfr0b"); + T("ã²ã¨ã¤å±‹æ ¹ã®ä¸‹2", "xn--2-u9tlzr9756bt3uc0v"); + T("Majiã§Koiã™ã‚‹5秒å‰", "xn--MajiKoi5-783gue6qz075azm5e"); + T("パフィーdeルンãƒ", "xn--de-jg4avhby1noc0d"); + T("ãã®ã‚¹ãƒ”ードã§", "xn--d9juau41awczczp"); + T("-> $1.00 <-", "-> $1.00 <-"); + /* Test cases from https://unicode.org/reports/tr46/ */ + T("faß.de", "xn--fa-hia.de"); + T("βόλος.com", "xn--nxasmm1c.com"); + T("à·à·Šâ€à¶»à·“.com", "xn--10cl1a0b660p.com"); + T("نامه‌ای.com", "xn--mgba3gch31f060k.com"); + return 0; +} + +#undef T + +#endif /* __MVS__ */ diff --git a/external/src/libuv/test/test-ip4-addr.c b/external/src/libuv/test/test-ip4-addr.c new file mode 100644 index 0000000..dfefb0f --- /dev/null +++ b/external/src/libuv/test/test-ip4-addr.c @@ -0,0 +1,55 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + + +TEST_IMPL(ip4_addr) { + struct sockaddr_in addr; + char dst[16]; + + ASSERT(0 == uv_inet_ntop(AF_INET, "\xFF\xFF\xFF\xFF", dst, sizeof(dst))); + ASSERT(0 == strcmp(dst, "255.255.255.255")); + ASSERT(UV_ENOSPC == uv_inet_ntop(AF_INET, "\xFF\xFF\xFF\xFF", + dst, sizeof(dst) - 1)); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + ASSERT(0 == uv_ip4_addr("255.255.255.255", TEST_PORT, &addr)); + ASSERT(UV_EINVAL == uv_ip4_addr("255.255.255*000", TEST_PORT, &addr)); + ASSERT(UV_EINVAL == uv_ip4_addr("255.255.255.256", TEST_PORT, &addr)); + ASSERT(UV_EINVAL == uv_ip4_addr("2555.0.0.0", TEST_PORT, &addr)); + ASSERT(UV_EINVAL == uv_ip4_addr("255", TEST_PORT, &addr)); + +#ifdef SIN6_LEN + ASSERT(addr.sin_len == sizeof(addr)); +#endif + + /* for broken address family */ + ASSERT(UV_EAFNOSUPPORT == uv_inet_pton(42, "127.0.0.1", + &addr.sin_addr.s_addr)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-ip6-addr.c b/external/src/libuv/test/test-ip6-addr.c new file mode 100644 index 0000000..8036c4b --- /dev/null +++ b/external/src/libuv/test/test-ip6-addr.c @@ -0,0 +1,171 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +#ifdef __linux__ +# include +# include +#endif + + +TEST_IMPL(ip6_addr_link_local) { +#if defined(__CYGWIN__) || defined(__MSYS__) + /* FIXME: Does Cygwin support this? */ + RETURN_SKIP("FIXME: This test needs more investigation on Cygwin"); +#endif + char string_address[INET6_ADDRSTRLEN]; + uv_interface_address_t* addresses; + uv_interface_address_t* address; + struct sockaddr_in6 addr; + unsigned int iface_index; + const char* device_name; + /* 40 bytes address, 16 bytes device name, plus reserve. */ + char scoped_addr[128]; + size_t scoped_addr_len; + char interface_id[UV_IF_NAMESIZE]; + size_t interface_id_len; + int count; + int ix; + int r; + + ASSERT(0 == uv_interface_addresses(&addresses, &count)); + + for (ix = 0; ix < count; ix++) { + address = addresses + ix; + + if (address->address.address6.sin6_family != AF_INET6) + continue; + + ASSERT(0 == uv_inet_ntop(AF_INET6, + &address->address.address6.sin6_addr, + string_address, + sizeof(string_address))); + + /* Skip addresses that are not link-local. */ + if (strncmp(string_address, "fe80::", 6) != 0) + continue; + + iface_index = address->address.address6.sin6_scope_id; + device_name = address->name; + + scoped_addr_len = sizeof(scoped_addr); + ASSERT(0 == uv_if_indextoname(iface_index, scoped_addr, &scoped_addr_len)); +#ifndef _WIN32 + /* This assert fails on Windows, as Windows semantics are different. */ + ASSERT(0 == strcmp(device_name, scoped_addr)); +#endif + + interface_id_len = sizeof(interface_id); + r = uv_if_indextoiid(iface_index, interface_id, &interface_id_len); + ASSERT(0 == r); +#ifdef _WIN32 + /* On Windows, the interface identifier is the numeric string of the index. */ + ASSERT(strtoul(interface_id, NULL, 10) == iface_index); +#else + /* On Unix/Linux, the interface identifier is the interface device name. */ + ASSERT(0 == strcmp(device_name, interface_id)); +#endif + + snprintf(scoped_addr, + sizeof(scoped_addr), + "%s%%%s", + string_address, + interface_id); + + fprintf(stderr, "Testing link-local address %s " + "(iface_index: 0x%02x, device_name: %s)\n", + scoped_addr, + iface_index, + device_name); + fflush(stderr); + + ASSERT(0 == uv_ip6_addr(scoped_addr, TEST_PORT, &addr)); + fprintf(stderr, "Got scope_id 0x%02x\n", addr.sin6_scope_id); + fflush(stderr); + ASSERT(iface_index == addr.sin6_scope_id); + } + + uv_free_interface_addresses(addresses, count); + + scoped_addr_len = sizeof(scoped_addr); + ASSERT(0 != uv_if_indextoname((unsigned int)-1, scoped_addr, &scoped_addr_len)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +#define GOOD_ADDR_LIST(X) \ + X("::") \ + X("::1") \ + X("fe80::1") \ + X("fe80::") \ + X("fe80::2acf:daff:fedd:342a") \ + X("fe80:0:0:0:2acf:daff:fedd:342a") \ + X("fe80:0:0:0:2acf:daff:1.2.3.4") \ + X("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") \ + +#define BAD_ADDR_LIST(X) \ + X(":::1") \ + X("abcde::1") \ + X("fe80:0:0:0:2acf:daff:fedd:342a:5678") \ + X("fe80:0:0:0:2acf:daff:abcd:1.2.3.4") \ + X("fe80:0:0:2acf:daff:1.2.3.4.5") \ + X("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255.255") \ + +#define TEST_GOOD(ADDR) \ + ASSERT(0 == uv_inet_pton(AF_INET6, ADDR, &addr)); \ + ASSERT(0 == uv_inet_pton(AF_INET6, ADDR "%en1", &addr)); \ + ASSERT(0 == uv_inet_pton(AF_INET6, ADDR "%%%%", &addr)); \ + ASSERT(0 == uv_inet_pton(AF_INET6, ADDR "%en1:1.2.3.4", &addr)); \ + +#define TEST_BAD(ADDR) \ + ASSERT(0 != uv_inet_pton(AF_INET6, ADDR, &addr)); \ + ASSERT(0 != uv_inet_pton(AF_INET6, ADDR "%en1", &addr)); \ + ASSERT(0 != uv_inet_pton(AF_INET6, ADDR "%%%%", &addr)); \ + ASSERT(0 != uv_inet_pton(AF_INET6, ADDR "%en1:1.2.3.4", &addr)); \ + +TEST_IMPL(ip6_pton) { + struct in6_addr addr; + + GOOD_ADDR_LIST(TEST_GOOD) + BAD_ADDR_LIST(TEST_BAD) + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#undef GOOD_ADDR_LIST +#undef BAD_ADDR_LIST + +TEST_IMPL(ip6_sin6_len) { + struct sockaddr_in6 s; + ASSERT_EQ(0, uv_ip6_addr("::", 0, &s)); +#ifdef SIN6_LEN + ASSERT(s.sin6_len == sizeof(s)); +#endif + return 0; +} diff --git a/external/src/libuv/test/test-ipc-heavy-traffic-deadlock-bug.c b/external/src/libuv/test/test-ipc-heavy-traffic-deadlock-bug.c new file mode 100644 index 0000000..89b977d --- /dev/null +++ b/external/src/libuv/test/test-ipc-heavy-traffic-deadlock-bug.c @@ -0,0 +1,159 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" +#include "uv.h" + +#include + +/* See test-ipc.c */ +void spawn_helper(uv_pipe_t* channel, + uv_process_t* process, + const char* helper); + +#define NUM_WRITES 256 +#define BUFFERS_PER_WRITE 3 +#define BUFFER_SIZE 0x2000 /* 8 kb. */ +#define BUFFER_CONTENT 42 + +#define XFER_SIZE (NUM_WRITES * BUFFERS_PER_WRITE * BUFFER_SIZE) + +struct write_info { + uv_write_t write_req; + char buffers[BUFFER_SIZE][BUFFERS_PER_WRITE]; +}; + +static uv_shutdown_t shutdown_req; + +static size_t bytes_written; +static size_t bytes_read; + +static void write_cb(uv_write_t* req, int status) { + struct write_info* write_info = + container_of(req, struct write_info, write_req); + ASSERT(status == 0); + bytes_written += BUFFERS_PER_WRITE * BUFFER_SIZE; + free(write_info); +} + +static void shutdown_cb(uv_shutdown_t* req, int status) { + ASSERT(status == 0 || status == UV_ENOTCONN); + uv_close((uv_handle_t*) req->handle, NULL); +} + +static void do_write(uv_stream_t* handle) { + struct write_info* write_info; + uv_buf_t bufs[BUFFERS_PER_WRITE]; + size_t i; + int r; + + write_info = malloc(sizeof *write_info); + ASSERT_NOT_NULL(write_info); + + for (i = 0; i < BUFFERS_PER_WRITE; i++) { + memset(&write_info->buffers[i], BUFFER_CONTENT, BUFFER_SIZE); + bufs[i] = uv_buf_init(write_info->buffers[i], BUFFER_SIZE); + } + + r = uv_write( + &write_info->write_req, handle, bufs, BUFFERS_PER_WRITE, write_cb); + ASSERT(r == 0); +} + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + buf->base = malloc(suggested_size); + buf->len = (int) suggested_size; +} + +#ifndef _WIN32 +#include +#include +#endif + +static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { + ssize_t i; + int r; + + ASSERT(nread >= 0); + bytes_read += nread; + + for (i = 0; i < nread; i++) + ASSERT(buf->base[i] == BUFFER_CONTENT); + free(buf->base); + + if (bytes_read >= XFER_SIZE) { + r = uv_read_stop(handle); + ASSERT(r == 0); + r = uv_shutdown(&shutdown_req, handle, shutdown_cb); + ASSERT(r == 0); + } +} + +static void do_writes_and_reads(uv_stream_t* handle) { + size_t i; + int r; + + bytes_written = 0; + bytes_read = 0; + + for (i = 0; i < NUM_WRITES; i++) { + do_write(handle); + } + + r = uv_read_start(handle, alloc_cb, read_cb); + ASSERT(r == 0); + + r = uv_run(handle->loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(bytes_written == XFER_SIZE); + ASSERT(bytes_read == XFER_SIZE); +} + +TEST_IMPL(ipc_heavy_traffic_deadlock_bug) { + uv_pipe_t pipe; + uv_process_t process; + + spawn_helper(&pipe, &process, "ipc_helper_heavy_traffic_deadlock_bug"); + do_writes_and_reads((uv_stream_t*) &pipe); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +int ipc_helper_heavy_traffic_deadlock_bug(void) { + uv_pipe_t pipe; + int r; + + r = uv_pipe_init(uv_default_loop(), &pipe, 1); + ASSERT(r == 0); + r = uv_pipe_open(&pipe, 0); + ASSERT(r == 0); + + notify_parent_process(); + do_writes_and_reads((uv_stream_t*) &pipe); + uv_sleep(100); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-ipc-send-recv.c b/external/src/libuv/test/test-ipc-send-recv.c new file mode 100644 index 0000000..12d4e33 --- /dev/null +++ b/external/src/libuv/test/test-ipc-send-recv.c @@ -0,0 +1,429 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +/* See test-ipc.c */ +void spawn_helper(uv_pipe_t* channel, + uv_process_t* process, + const char* helper); + +void ipc_send_recv_helper_threadproc(void* arg); + +union handles { + uv_handle_t handle; + uv_stream_t stream; + uv_pipe_t pipe; + uv_tcp_t tcp; + uv_tty_t tty; +}; + +struct test_ctx { + uv_pipe_t channel; + uv_connect_t connect_req; + uv_write_t write_req; + uv_write_t write_req2; + uv_handle_type expected_type; + union handles send; + union handles send2; + union handles recv; + union handles recv2; +}; + +struct echo_ctx { + uv_pipe_t listen; + uv_pipe_t channel; + uv_write_t write_req; + uv_write_t write_req2; + uv_handle_type expected_type; + union handles recv; + union handles recv2; +}; + +static struct test_ctx ctx; +static struct echo_ctx ctx2; + +/* Used in write2_cb to decide if we need to cleanup or not */ +static int is_child_process; +static int is_in_process; +static int read_cb_count; +static int recv_cb_count; +static int write2_cb_called; + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + /* we're not actually reading anything so a small buffer is okay */ + static char slab[8]; + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void recv_cb(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + uv_handle_type pending; + uv_pipe_t* pipe; + int r; + union handles* recv; + + pipe = (uv_pipe_t*) handle; + ASSERT(pipe == &ctx.channel); + + do { + if (++recv_cb_count == 1) { + recv = &ctx.recv; + } else { + recv = &ctx.recv2; + } + + /* Depending on the OS, the final recv_cb can be called after + * the child process has terminated which can result in nread + * being UV_EOF instead of the number of bytes read. Since + * the other end of the pipe has closed this UV_EOF is an + * acceptable value. */ + if (nread == UV_EOF) { + /* UV_EOF is only acceptable for the final recv_cb call */ + ASSERT(recv_cb_count == 2); + } else { + ASSERT(nread >= 0); + ASSERT(uv_pipe_pending_count(pipe) > 0); + + pending = uv_pipe_pending_type(pipe); + ASSERT(pending == ctx.expected_type); + + if (pending == UV_NAMED_PIPE) + r = uv_pipe_init(ctx.channel.loop, &recv->pipe, 0); + else if (pending == UV_TCP) + r = uv_tcp_init(ctx.channel.loop, &recv->tcp); + else + abort(); + ASSERT(r == 0); + + r = uv_accept(handle, &recv->stream); + ASSERT(r == 0); + } + } while (uv_pipe_pending_count(pipe) > 0); + + /* Close after two writes received */ + if (recv_cb_count == 2) { + uv_close((uv_handle_t*)&ctx.channel, NULL); + } +} + +static void connect_cb(uv_connect_t* req, int status) { + int r; + uv_buf_t buf; + + ASSERT(req == &ctx.connect_req); + ASSERT(status == 0); + + buf = uv_buf_init(".", 1); + r = uv_write2(&ctx.write_req, + (uv_stream_t*)&ctx.channel, + &buf, 1, + &ctx.send.stream, + NULL); + ASSERT(r == 0); + + /* Perform two writes to the same pipe to make sure that on Windows we are + * not running into issue 505: + * https://github.com/libuv/libuv/issues/505 */ + buf = uv_buf_init(".", 1); + r = uv_write2(&ctx.write_req2, + (uv_stream_t*)&ctx.channel, + &buf, 1, + &ctx.send2.stream, + NULL); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*)&ctx.channel, alloc_cb, recv_cb); + ASSERT(r == 0); +} + +static int run_test(int inprocess) { + uv_process_t process; + uv_thread_t tid; + int r; + + if (inprocess) { + r = uv_thread_create(&tid, ipc_send_recv_helper_threadproc, (void *) 42); + ASSERT(r == 0); + + uv_sleep(1000); + + r = uv_pipe_init(uv_default_loop(), &ctx.channel, 1); + ASSERT(r == 0); + + uv_pipe_connect(&ctx.connect_req, &ctx.channel, TEST_PIPENAME_3, connect_cb); + } else { + spawn_helper(&ctx.channel, &process, "ipc_send_recv_helper"); + + connect_cb(&ctx.connect_req, 0); + } + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(recv_cb_count == 2); + + if (inprocess) { + r = uv_thread_join(&tid); + ASSERT(r == 0); + } + + return 0; +} + +static int run_ipc_send_recv_pipe(int inprocess) { + int r; + + ctx.expected_type = UV_NAMED_PIPE; + + r = uv_pipe_init(uv_default_loop(), &ctx.send.pipe, 1); + ASSERT(r == 0); + + r = uv_pipe_bind(&ctx.send.pipe, TEST_PIPENAME); + ASSERT(r == 0); + + r = uv_pipe_init(uv_default_loop(), &ctx.send2.pipe, 1); + ASSERT(r == 0); + + r = uv_pipe_bind(&ctx.send2.pipe, TEST_PIPENAME_2); + ASSERT(r == 0); + + r = run_test(inprocess); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(ipc_send_recv_pipe) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif + return run_ipc_send_recv_pipe(0); +} + +TEST_IMPL(ipc_send_recv_pipe_inprocess) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif + return run_ipc_send_recv_pipe(1); +} + +static int run_ipc_send_recv_tcp(int inprocess) { + struct sockaddr_in addr; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + ctx.expected_type = UV_TCP; + + r = uv_tcp_init(uv_default_loop(), &ctx.send.tcp); + ASSERT(r == 0); + + r = uv_tcp_init(uv_default_loop(), &ctx.send2.tcp); + ASSERT(r == 0); + + r = uv_tcp_bind(&ctx.send.tcp, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_tcp_bind(&ctx.send2.tcp, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = run_test(inprocess); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(ipc_send_recv_tcp) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif + return run_ipc_send_recv_tcp(0); +} + +TEST_IMPL(ipc_send_recv_tcp_inprocess) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif + return run_ipc_send_recv_tcp(1); +} + + +/* Everything here runs in a child process or second thread. */ + +static void write2_cb(uv_write_t* req, int status) { + ASSERT(status == 0); + + /* After two successful writes in the child process, allow the child + * process to be closed. */ + if (++write2_cb_called == 2 && (is_child_process || is_in_process)) { + uv_close(&ctx2.recv.handle, NULL); + uv_close(&ctx2.recv2.handle, NULL); + uv_close((uv_handle_t*)&ctx2.channel, NULL); + uv_close((uv_handle_t*)&ctx2.listen, NULL); + } +} + +static void read_cb(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* rdbuf) { + uv_buf_t wrbuf; + uv_pipe_t* pipe; + uv_handle_type pending; + int r; + union handles* recv; + uv_write_t* write_req; + + if (nread == UV_EOF || nread == UV_ECONNABORTED) { + return; + } + + pipe = (uv_pipe_t*) handle; + do { + if (++read_cb_count == 2) { + recv = &ctx2.recv; + write_req = &ctx2.write_req; + } else { + recv = &ctx2.recv2; + write_req = &ctx2.write_req2; + } + + ASSERT(pipe == &ctx2.channel); + ASSERT(nread >= 0); + ASSERT(uv_pipe_pending_count(pipe) > 0); + + pending = uv_pipe_pending_type(pipe); + ASSERT(pending == UV_NAMED_PIPE || pending == UV_TCP); + + if (pending == UV_NAMED_PIPE) + r = uv_pipe_init(ctx2.channel.loop, &recv->pipe, 0); + else if (pending == UV_TCP) + r = uv_tcp_init(ctx2.channel.loop, &recv->tcp); + else + abort(); + ASSERT(r == 0); + + r = uv_accept(handle, &recv->stream); + ASSERT(r == 0); + + wrbuf = uv_buf_init(".", 1); + r = uv_write2(write_req, + (uv_stream_t*)&ctx2.channel, + &wrbuf, + 1, + &recv->stream, + write2_cb); + ASSERT(r == 0); + } while (uv_pipe_pending_count(pipe) > 0); +} + +static void send_recv_start(void) { + int r; + ASSERT(1 == uv_is_readable((uv_stream_t*)&ctx2.channel)); + ASSERT(1 == uv_is_writable((uv_stream_t*)&ctx2.channel)); + ASSERT(0 == uv_is_closing((uv_handle_t*)&ctx2.channel)); + + r = uv_read_start((uv_stream_t*)&ctx2.channel, alloc_cb, read_cb); + ASSERT(r == 0); +} + +static void listen_cb(uv_stream_t* handle, int status) { + int r; + ASSERT(handle == (uv_stream_t*)&ctx2.listen); + ASSERT(status == 0); + + r = uv_accept((uv_stream_t*)&ctx2.listen, (uv_stream_t*)&ctx2.channel); + ASSERT(r == 0); + + send_recv_start(); +} + +int run_ipc_send_recv_helper(uv_loop_t* loop, int inprocess) { + int r; + + is_in_process = inprocess; + + memset(&ctx2, 0, sizeof(ctx2)); + + r = uv_pipe_init(loop, &ctx2.listen, 0); + ASSERT(r == 0); + + r = uv_pipe_init(loop, &ctx2.channel, 1); + ASSERT(r == 0); + + if (inprocess) { + r = uv_pipe_bind(&ctx2.listen, TEST_PIPENAME_3); + ASSERT(r == 0); + + r = uv_listen((uv_stream_t*)&ctx2.listen, SOMAXCONN, listen_cb); + ASSERT(r == 0); + } else { + r = uv_pipe_open(&ctx2.channel, 0); + ASSERT(r == 0); + + send_recv_start(); + } + + notify_parent_process(); + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + return 0; +} + +/* stdin is a duplex channel over which a handle is sent. + * We receive it and send it back where it came from. + */ +int ipc_send_recv_helper(void) { + int r; + + r = run_ipc_send_recv_helper(uv_default_loop(), 0); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +void ipc_send_recv_helper_threadproc(void* arg) { + int r; + uv_loop_t loop; + + r = uv_loop_init(&loop); + ASSERT(r == 0); + + r = run_ipc_send_recv_helper(&loop, 1); + ASSERT(r == 0); + + r = uv_loop_close(&loop); + ASSERT(r == 0); +} diff --git a/external/src/libuv/test/test-ipc.c b/external/src/libuv/test/test-ipc.c new file mode 100644 index 0000000..68a0e1b --- /dev/null +++ b/external/src/libuv/test/test-ipc.c @@ -0,0 +1,984 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +static uv_pipe_t channel; +static uv_tcp_t tcp_server; +static uv_tcp_t tcp_server2; +static uv_tcp_t tcp_connection; + +static int exit_cb_called; +static int read_cb_called; +static int tcp_write_cb_called; +static int tcp_read_cb_called; +static int on_pipe_read_called; +static int local_conn_accepted; +static int remote_conn_accepted; +static int tcp_server_listening; +static uv_write_t write_req; +static uv_write_t write_req2; +static uv_write_t conn_notify_req; +static int close_cb_called; +static int connection_accepted; +static int tcp_conn_read_cb_called; +static int tcp_conn_write_cb_called; +static int closed_handle_data_read; +static int closed_handle_write; +static int send_zero_write; + +typedef struct { + uv_connect_t conn_req; + uv_write_t tcp_write_req; + uv_tcp_t conn; +} tcp_conn; + +#define CONN_COUNT 100 +#define BACKLOG 128 +#define LARGE_SIZE 100000 + +static uv_buf_t large_buf; +static char buffer[LARGE_SIZE]; +static uv_write_t write_reqs[300]; +static int write_reqs_completed; + +static unsigned int write_until_data_queued(void); +static void send_handle_and_close(void); + + +static void close_server_conn_cb(uv_handle_t* handle) { + free(handle); +} + + +static void on_connection(uv_stream_t* server, int status) { + uv_tcp_t* conn; + int r; + + if (!local_conn_accepted) { + /* Accept the connection and close it. Also and close the server. */ + ASSERT_EQ(status, 0); + ASSERT_PTR_EQ(&tcp_server, server); + + conn = malloc(sizeof(*conn)); + ASSERT_NOT_NULL(conn); + r = uv_tcp_init(server->loop, conn); + ASSERT_EQ(r, 0); + + r = uv_accept(server, (uv_stream_t*)conn); + ASSERT_EQ(r, 0); + + uv_close((uv_handle_t*)conn, close_server_conn_cb); + uv_close((uv_handle_t*)server, NULL); + local_conn_accepted = 1; + } +} + + +static void exit_cb(uv_process_t* process, + int64_t exit_status, + int term_signal) { + printf("exit_cb\n"); + exit_cb_called++; + ASSERT_EQ(exit_status, 0); + ASSERT_EQ(term_signal, 0); + uv_close((uv_handle_t*)process, NULL); +} + + +static void on_alloc(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + buf->base = malloc(suggested_size); + buf->len = suggested_size; +} + + +static void close_client_conn_cb(uv_handle_t* handle) { + tcp_conn* p = (tcp_conn*)handle->data; + free(p); +} + + +static void connect_cb(uv_connect_t* req, int status) { + uv_close((uv_handle_t*)req->handle, close_client_conn_cb); +} + + +static void make_many_connections(void) { + tcp_conn* conn; + struct sockaddr_in addr; + int r, i; + + for (i = 0; i < CONN_COUNT; i++) { + conn = malloc(sizeof(*conn)); + ASSERT_NOT_NULL(conn); + + r = uv_tcp_init(uv_default_loop(), &conn->conn); + ASSERT_EQ(r, 0); + ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_tcp_connect(&conn->conn_req, + (uv_tcp_t*) &conn->conn, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT_EQ(r, 0); + + conn->conn.data = conn; + } +} + + +static void on_read(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + int r; + uv_pipe_t* pipe; + uv_handle_type pending; + uv_buf_t outbuf; + + pipe = (uv_pipe_t*) handle; + + if (nread == 0) { + /* Everything OK, but nothing read. */ + free(buf->base); + return; + } + + if (nread < 0) { + if (nread == UV_EOF) { + free(buf->base); + return; + } + + printf("error recving on channel: %s\n", uv_strerror(nread)); + abort(); + } + + fprintf(stderr, "got %d bytes\n", (int)nread); + + pending = uv_pipe_pending_type(pipe); + if (!tcp_server_listening) { + ASSERT_EQ(1, uv_pipe_pending_count(pipe)); + ASSERT_GT(nread, 0); + ASSERT_NOT_NULL(buf->base); + ASSERT_NE(pending, UV_UNKNOWN_HANDLE); + read_cb_called++; + + /* Accept the pending TCP server, and start listening on it. */ + ASSERT_EQ(pending, UV_TCP); + r = uv_tcp_init(uv_default_loop(), &tcp_server); + ASSERT_EQ(r, 0); + + r = uv_accept((uv_stream_t*)pipe, (uv_stream_t*)&tcp_server); + ASSERT_EQ(r, 0); + + r = uv_listen((uv_stream_t*)&tcp_server, BACKLOG, on_connection); + ASSERT_EQ(r, 0); + + tcp_server_listening = 1; + + /* Make sure that the expected data is correctly multiplexed. */ + ASSERT_MEM_EQ("hello\n", buf->base, nread); + + outbuf = uv_buf_init("foobar\n", 7); + r = uv_write(&write_req, (uv_stream_t*)pipe, &outbuf, 1, NULL); + ASSERT_EQ(r, 0); + + /* Create a bunch of connections to get both servers to accept. */ + make_many_connections(); + } else if (memcmp("accepted_connection\n", buf->base, nread) == 0) { + /* Remote server has accepted a connection. Close the channel. */ + ASSERT_EQ(0, uv_pipe_pending_count(pipe)); + ASSERT_EQ(pending, UV_UNKNOWN_HANDLE); + remote_conn_accepted = 1; + uv_close((uv_handle_t*)&channel, NULL); + } + + free(buf->base); +} + +#ifdef _WIN32 +static void on_read_listen_after_bound_twice(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + int r; + uv_pipe_t* pipe; + uv_handle_type pending; + + pipe = (uv_pipe_t*) handle; + + if (nread == 0) { + /* Everything OK, but nothing read. */ + free(buf->base); + return; + } + + if (nread < 0) { + if (nread == UV_EOF) { + free(buf->base); + return; + } + + printf("error recving on channel: %s\n", uv_strerror(nread)); + abort(); + } + + fprintf(stderr, "got %d bytes\n", (int)nread); + + ASSERT_GT(uv_pipe_pending_count(pipe), 0); + pending = uv_pipe_pending_type(pipe); + ASSERT_GT(nread, 0); + ASSERT_NOT_NULL(buf->base); + ASSERT_NE(pending, UV_UNKNOWN_HANDLE); + read_cb_called++; + + if (read_cb_called == 1) { + /* Accept the first TCP server, and start listening on it. */ + ASSERT_EQ(pending, UV_TCP); + r = uv_tcp_init(uv_default_loop(), &tcp_server); + ASSERT_EQ(r, 0); + + r = uv_accept((uv_stream_t*)pipe, (uv_stream_t*)&tcp_server); + ASSERT_EQ(r, 0); + + r = uv_listen((uv_stream_t*)&tcp_server, BACKLOG, on_connection); + ASSERT_EQ(r, 0); + } else if (read_cb_called == 2) { + /* Accept the second TCP server, and start listening on it. */ + ASSERT_EQ(pending, UV_TCP); + r = uv_tcp_init(uv_default_loop(), &tcp_server2); + ASSERT_EQ(r, 0); + + r = uv_accept((uv_stream_t*)pipe, (uv_stream_t*)&tcp_server2); + ASSERT_EQ(r, 0); + + r = uv_listen((uv_stream_t*)&tcp_server2, BACKLOG, on_connection); + ASSERT_EQ(r, UV_EADDRINUSE); + + uv_close((uv_handle_t*)&tcp_server, NULL); + uv_close((uv_handle_t*)&tcp_server2, NULL); + ASSERT_EQ(0, uv_pipe_pending_count(pipe)); + uv_close((uv_handle_t*)&channel, NULL); + } + + free(buf->base); +} +#endif + +void spawn_helper(uv_pipe_t* channel, + uv_process_t* process, + const char* helper) { + uv_process_options_t options; + size_t exepath_size; + char exepath[1024]; + char* args[3]; + int r; + uv_stdio_container_t stdio[3]; + + r = uv_pipe_init(uv_default_loop(), channel, 1); + ASSERT_EQ(r, 0); + ASSERT_NE(channel->ipc, 0); + + exepath_size = sizeof(exepath); + r = uv_exepath(exepath, &exepath_size); + ASSERT_EQ(r, 0); + + exepath[exepath_size] = '\0'; + args[0] = exepath; + args[1] = (char*)helper; + args[2] = NULL; + + memset(&options, 0, sizeof(options)); + options.file = exepath; + options.args = args; + options.exit_cb = exit_cb; + options.stdio = stdio; + options.stdio_count = ARRAY_SIZE(stdio); + + stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE | UV_WRITABLE_PIPE; + stdio[0].data.stream = (uv_stream_t*) channel; + stdio[1].flags = UV_INHERIT_FD; + stdio[1].data.fd = 1; + stdio[2].flags = UV_INHERIT_FD; + stdio[2].data.fd = 2; + + r = uv_spawn(uv_default_loop(), process, &options); + ASSERT_EQ(r, 0); +} + + +static void on_tcp_write(uv_write_t* req, int status) { + ASSERT_EQ(status, 0); + ASSERT_PTR_EQ(req->handle, &tcp_connection); + tcp_write_cb_called++; +} + + +static void on_read_alloc(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + buf->base = malloc(suggested_size); + buf->len = suggested_size; +} + + +static void on_tcp_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { + ASSERT_GT(nread, 0); + ASSERT_MEM_EQ("hello again\n", buf->base, nread); + ASSERT_PTR_EQ(tcp, &tcp_connection); + free(buf->base); + + tcp_read_cb_called++; + + uv_close((uv_handle_t*)tcp, NULL); + uv_close((uv_handle_t*)&channel, NULL); +} + + +static void on_read_connection(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + int r; + uv_buf_t outbuf; + uv_pipe_t* pipe; + uv_handle_type pending; + + pipe = (uv_pipe_t*) handle; + if (nread == 0) { + /* Everything OK, but nothing read. */ + free(buf->base); + return; + } + + if (nread < 0) { + if (nread == UV_EOF) { + free(buf->base); + return; + } + + printf("error recving on channel: %s\n", uv_strerror(nread)); + abort(); + } + + fprintf(stderr, "got %d bytes\n", (int)nread); + + ASSERT_EQ(1, uv_pipe_pending_count(pipe)); + pending = uv_pipe_pending_type(pipe); + + ASSERT_GT(nread, 0); + ASSERT_NOT_NULL(buf->base); + ASSERT_NE(pending, UV_UNKNOWN_HANDLE); + read_cb_called++; + + /* Accept the pending TCP connection */ + ASSERT_EQ(pending, UV_TCP); + r = uv_tcp_init(uv_default_loop(), &tcp_connection); + ASSERT_EQ(r, 0); + + r = uv_accept(handle, (uv_stream_t*)&tcp_connection); + ASSERT_EQ(r, 0); + + /* Make sure that the expected data is correctly multiplexed. */ + ASSERT_MEM_EQ("hello\n", buf->base, nread); + + /* Write/read to/from the connection */ + outbuf = uv_buf_init("world\n", 6); + r = uv_write(&write_req, (uv_stream_t*)&tcp_connection, &outbuf, 1, + on_tcp_write); + ASSERT_EQ(r, 0); + + r = uv_read_start((uv_stream_t*)&tcp_connection, on_read_alloc, on_tcp_read); + ASSERT_EQ(r, 0); + + free(buf->base); +} + + +#ifndef _WIN32 +static void on_read_closed_handle(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + if (nread == 0 || nread == UV_EOF) { + free(buf->base); + return; + } + + if (nread < 0) { + printf("error recving on channel: %s\n", uv_strerror(nread)); + abort(); + } + + closed_handle_data_read += nread; + free(buf->base); +} +#endif + + +static void on_read_send_zero(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + ASSERT(nread == 0 || nread == UV_EOF); + free(buf->base); +} + + +static int run_ipc_test(const char* helper, uv_read_cb read_cb) { + uv_process_t process; + int r; + + spawn_helper(&channel, &process, helper); + uv_read_start((uv_stream_t*)&channel, on_alloc, read_cb); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT_EQ(r, 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(ipc_listen_before_write) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif + int r = run_ipc_test("ipc_helper_listen_before_write", on_read); + ASSERT_EQ(local_conn_accepted, 1); + ASSERT_EQ(remote_conn_accepted, 1); + ASSERT_EQ(read_cb_called, 1); + ASSERT_EQ(exit_cb_called, 1); + return r; +} + + +TEST_IMPL(ipc_listen_after_write) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif + int r = run_ipc_test("ipc_helper_listen_after_write", on_read); + ASSERT_EQ(local_conn_accepted, 1); + ASSERT_EQ(remote_conn_accepted, 1); + ASSERT_EQ(read_cb_called, 1); + ASSERT_EQ(exit_cb_called, 1); + return r; +} + + +TEST_IMPL(ipc_tcp_connection) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif + int r = run_ipc_test("ipc_helper_tcp_connection", on_read_connection); + ASSERT_EQ(read_cb_called, 1); + ASSERT_EQ(tcp_write_cb_called, 1); + ASSERT_EQ(tcp_read_cb_called, 1); + ASSERT_EQ(exit_cb_called, 1); + return r; +} + +#ifndef _WIN32 +TEST_IMPL(ipc_closed_handle) { + int r; + r = run_ipc_test("ipc_helper_closed_handle", on_read_closed_handle); + ASSERT_EQ(r, 0); + return 0; +} +#endif + + +#ifdef _WIN32 +TEST_IMPL(listen_with_simultaneous_accepts) { + uv_tcp_t server; + int r; + struct sockaddr_in addr; + + ASSERT_EQ(0, uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT_EQ(r, 0); + + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT_EQ(r, 0); + + r = uv_tcp_simultaneous_accepts(&server, 1); + ASSERT_EQ(r, 0); + + r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL); + ASSERT_EQ(r, 0); + ASSERT_EQ(server.reqs_pending, 32); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(listen_no_simultaneous_accepts) { + uv_tcp_t server; + int r; + struct sockaddr_in addr; + + ASSERT_EQ(0, uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT_EQ(r, 0); + + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT_EQ(r, 0); + + r = uv_tcp_simultaneous_accepts(&server, 0); + ASSERT_EQ(r, 0); + + r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL); + ASSERT_EQ(r, 0); + ASSERT_EQ(server.reqs_pending, 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(ipc_listen_after_bind_twice) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif + int r = run_ipc_test("ipc_helper_bind_twice", on_read_listen_after_bound_twice); + ASSERT_EQ(read_cb_called, 2); + ASSERT_EQ(exit_cb_called, 1); + return r; +} +#endif + +TEST_IMPL(ipc_send_zero) { + int r; + r = run_ipc_test("ipc_helper_send_zero", on_read_send_zero); + ASSERT_EQ(r, 0); + return 0; +} + + +/* Everything here runs in a child process. */ + +static tcp_conn conn; + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + + +static void conn_notify_write_cb(uv_write_t* req, int status) { + uv_close((uv_handle_t*)&tcp_server, close_cb); + uv_close((uv_handle_t*)&channel, close_cb); +} + + +static void tcp_connection_write_cb(uv_write_t* req, int status) { + ASSERT_PTR_EQ(&conn.conn, req->handle); + uv_close((uv_handle_t*)req->handle, close_cb); + uv_close((uv_handle_t*)&channel, close_cb); + uv_close((uv_handle_t*)&tcp_server, close_cb); + tcp_conn_write_cb_called++; +} + + +static void closed_handle_large_write_cb(uv_write_t* req, int status) { + ASSERT_EQ(status, 0); + ASSERT(closed_handle_data_read = LARGE_SIZE); + if (++write_reqs_completed == ARRAY_SIZE(write_reqs)) { + write_reqs_completed = 0; + if (write_until_data_queued() > 0) + send_handle_and_close(); + } +} + + +static void closed_handle_write_cb(uv_write_t* req, int status) { + ASSERT_EQ(status, UV_EBADF); + closed_handle_write = 1; +} + + +static void send_zero_write_cb(uv_write_t* req, int status) { + ASSERT_EQ(status, 0); + send_zero_write++; +} + +static void on_tcp_child_process_read(uv_stream_t* tcp, + ssize_t nread, + const uv_buf_t* buf) { + uv_buf_t outbuf; + int r; + + if (nread < 0) { + if (nread == UV_EOF) { + free(buf->base); + return; + } + + printf("error recving on tcp connection: %s\n", uv_strerror(nread)); + abort(); + } + + ASSERT_GT(nread, 0); + ASSERT_MEM_EQ("world\n", buf->base, nread); + on_pipe_read_called++; + free(buf->base); + + /* Write to the socket */ + outbuf = uv_buf_init("hello again\n", 12); + r = uv_write(&conn.tcp_write_req, tcp, &outbuf, 1, tcp_connection_write_cb); + ASSERT_EQ(r, 0); + + tcp_conn_read_cb_called++; +} + + +static void connect_child_process_cb(uv_connect_t* req, int status) { + int r; + + ASSERT_EQ(status, 0); + r = uv_read_start(req->handle, on_read_alloc, on_tcp_child_process_read); + ASSERT_EQ(r, 0); +} + + +static void ipc_on_connection(uv_stream_t* server, int status) { + int r; + uv_buf_t buf; + + if (!connection_accepted) { + /* + * Accept the connection and close it. Also let the other + * side know. + */ + ASSERT_EQ(status, 0); + ASSERT_PTR_EQ(&tcp_server, server); + + r = uv_tcp_init(server->loop, &conn.conn); + ASSERT_EQ(r, 0); + + r = uv_accept(server, (uv_stream_t*)&conn.conn); + ASSERT_EQ(r, 0); + + uv_close((uv_handle_t*)&conn.conn, close_cb); + + buf = uv_buf_init("accepted_connection\n", 20); + r = uv_write2(&conn_notify_req, (uv_stream_t*)&channel, &buf, 1, + NULL, conn_notify_write_cb); + ASSERT_EQ(r, 0); + + connection_accepted = 1; + } +} + + +static void close_and_free_cb(uv_handle_t* handle) { + close_cb_called++; + free(handle); +} + +static void ipc_on_connection_tcp_conn(uv_stream_t* server, int status) { + int r; + uv_buf_t buf; + uv_tcp_t* conn; + + ASSERT_EQ(status, 0); + ASSERT_PTR_EQ(&tcp_server, server); + + conn = malloc(sizeof(*conn)); + ASSERT_NOT_NULL(conn); + + r = uv_tcp_init(server->loop, conn); + ASSERT_EQ(r, 0); + + r = uv_accept(server, (uv_stream_t*)conn); + ASSERT_EQ(r, 0); + + /* Send the accepted connection to the other process */ + buf = uv_buf_init("hello\n", 6); + r = uv_write2(&conn_notify_req, (uv_stream_t*)&channel, &buf, 1, + (uv_stream_t*)conn, NULL); + ASSERT_EQ(r, 0); + + r = uv_read_start((uv_stream_t*) conn, + on_read_alloc, + on_tcp_child_process_read); + ASSERT_EQ(r, 0); + + uv_close((uv_handle_t*)conn, close_and_free_cb); +} + + +int ipc_helper(int listen_after_write) { + /* + * This is launched from test-ipc.c. stdin is a duplex channel that we + * over which a handle will be transmitted. + */ + struct sockaddr_in addr; + int r; + uv_buf_t buf; + + ASSERT_EQ(0, uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + r = uv_pipe_init(uv_default_loop(), &channel, 1); + ASSERT_EQ(r, 0); + + uv_pipe_open(&channel, 0); + + ASSERT_EQ(1, uv_is_readable((uv_stream_t*) &channel)); + ASSERT_EQ(1, uv_is_writable((uv_stream_t*) &channel)); + ASSERT_EQ(0, uv_is_closing((uv_handle_t*) &channel)); + + r = uv_tcp_init(uv_default_loop(), &tcp_server); + ASSERT_EQ(r, 0); + + r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0); + ASSERT_EQ(r, 0); + + if (!listen_after_write) { + r = uv_listen((uv_stream_t*)&tcp_server, BACKLOG, ipc_on_connection); + ASSERT_EQ(r, 0); + } + + buf = uv_buf_init("hello\n", 6); + r = uv_write2(&write_req, (uv_stream_t*)&channel, &buf, 1, + (uv_stream_t*)&tcp_server, NULL); + ASSERT_EQ(r, 0); + + if (listen_after_write) { + r = uv_listen((uv_stream_t*)&tcp_server, BACKLOG, ipc_on_connection); + ASSERT_EQ(r, 0); + } + + notify_parent_process(); + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT_EQ(r, 0); + + ASSERT_EQ(connection_accepted, 1); + ASSERT_EQ(close_cb_called, 3); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +int ipc_helper_tcp_connection(void) { + /* + * This is launched from test-ipc.c. stdin is a duplex channel + * over which a handle will be transmitted. + */ + + int r; + struct sockaddr_in addr; + + r = uv_pipe_init(uv_default_loop(), &channel, 1); + ASSERT_EQ(r, 0); + + uv_pipe_open(&channel, 0); + + ASSERT_EQ(1, uv_is_readable((uv_stream_t*) &channel)); + ASSERT_EQ(1, uv_is_writable((uv_stream_t*) &channel)); + ASSERT_EQ(0, uv_is_closing((uv_handle_t*) &channel)); + + r = uv_tcp_init(uv_default_loop(), &tcp_server); + ASSERT_EQ(r, 0); + + ASSERT_EQ(0, uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0); + ASSERT_EQ(r, 0); + + r = uv_listen((uv_stream_t*)&tcp_server, BACKLOG, ipc_on_connection_tcp_conn); + ASSERT_EQ(r, 0); + + /* Make a connection to the server */ + r = uv_tcp_init(uv_default_loop(), &conn.conn); + ASSERT_EQ(r, 0); + + ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_tcp_connect(&conn.conn_req, + (uv_tcp_t*) &conn.conn, + (const struct sockaddr*) &addr, + connect_child_process_cb); + ASSERT_EQ(r, 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT_EQ(r, 0); + + ASSERT_EQ(tcp_conn_read_cb_called, 1); + ASSERT_EQ(tcp_conn_write_cb_called, 1); + ASSERT_EQ(close_cb_called, 4); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +static unsigned int write_until_data_queued() { + unsigned int i; + int r; + + i = 0; + do { + r = uv_write(&write_reqs[i], + (uv_stream_t*)&channel, + &large_buf, + 1, + closed_handle_large_write_cb); + ASSERT_EQ(r, 0); + i++; + } while (channel.write_queue_size == 0 && + i < ARRAY_SIZE(write_reqs)); + + return channel.write_queue_size; +} + +static void send_handle_and_close() { + int r; + struct sockaddr_in addr; + + r = uv_tcp_init(uv_default_loop(), &tcp_server); + ASSERT_EQ(r, 0); + + ASSERT_EQ(0, uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0); + ASSERT_EQ(r, 0); + + r = uv_write2(&write_req, + (uv_stream_t*)&channel, + &large_buf, + 1, + (uv_stream_t*)&tcp_server, + closed_handle_write_cb); + ASSERT_EQ(r, 0); + + uv_close((uv_handle_t*)&tcp_server, NULL); +} + +int ipc_helper_closed_handle(void) { + int r; + + memset(buffer, '.', LARGE_SIZE); + large_buf = uv_buf_init(buffer, LARGE_SIZE); + + r = uv_pipe_init(uv_default_loop(), &channel, 1); + ASSERT_EQ(r, 0); + + uv_pipe_open(&channel, 0); + + ASSERT_EQ(1, uv_is_readable((uv_stream_t*) &channel)); + ASSERT_EQ(1, uv_is_writable((uv_stream_t*) &channel)); + ASSERT_EQ(0, uv_is_closing((uv_handle_t*) &channel)); + + if (write_until_data_queued() > 0) + send_handle_and_close(); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT_EQ(r, 0); + + ASSERT_EQ(closed_handle_write, 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +int ipc_helper_bind_twice(void) { + /* + * This is launched from test-ipc.c. stdin is a duplex channel + * over which two handles will be transmitted. + */ + struct sockaddr_in addr; + int r; + uv_buf_t buf; + + ASSERT_EQ(0, uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + r = uv_pipe_init(uv_default_loop(), &channel, 1); + ASSERT_EQ(r, 0); + + uv_pipe_open(&channel, 0); + + ASSERT_EQ(1, uv_is_readable((uv_stream_t*) &channel)); + ASSERT_EQ(1, uv_is_writable((uv_stream_t*) &channel)); + ASSERT_EQ(0, uv_is_closing((uv_handle_t*) &channel)); + + buf = uv_buf_init("hello\n", 6); + + r = uv_tcp_init(uv_default_loop(), &tcp_server); + ASSERT_EQ(r, 0); + r = uv_tcp_init(uv_default_loop(), &tcp_server2); + ASSERT_EQ(r, 0); + + r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0); + ASSERT_EQ(r, 0); + r = uv_tcp_bind(&tcp_server2, (const struct sockaddr*) &addr, 0); + ASSERT_EQ(r, 0); + + r = uv_write2(&write_req, (uv_stream_t*)&channel, &buf, 1, + (uv_stream_t*)&tcp_server, NULL); + ASSERT_EQ(r, 0); + r = uv_write2(&write_req2, (uv_stream_t*)&channel, &buf, 1, + (uv_stream_t*)&tcp_server2, NULL); + ASSERT_EQ(r, 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT_EQ(r, 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +int ipc_helper_send_zero(void) { + int r; + uv_buf_t zero_buf; + + zero_buf = uv_buf_init(0, 0); + + r = uv_pipe_init(uv_default_loop(), &channel, 0); + ASSERT_EQ(r, 0); + + uv_pipe_open(&channel, 0); + + ASSERT_EQ(1, uv_is_readable((uv_stream_t*) &channel)); + ASSERT_EQ(1, uv_is_writable((uv_stream_t*) &channel)); + ASSERT_EQ(0, uv_is_closing((uv_handle_t*) &channel)); + + r = uv_write(&write_req, + (uv_stream_t*)&channel, + &zero_buf, + 1, + send_zero_write_cb); + + ASSERT_EQ(r, 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT_EQ(r, 0); + + ASSERT_EQ(send_zero_write, 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-list.h b/external/src/libuv/test/test-list.h new file mode 100644 index 0000000..f8ed94b --- /dev/null +++ b/external/src/libuv/test/test-list.h @@ -0,0 +1,1158 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" + +TEST_DECLARE (platform_output) +TEST_DECLARE (callback_order) +TEST_DECLARE (close_order) +TEST_DECLARE (run_once) +TEST_DECLARE (run_nowait) +TEST_DECLARE (loop_alive) +TEST_DECLARE (loop_close) +TEST_DECLARE (loop_instant_close) +TEST_DECLARE (loop_stop) +TEST_DECLARE (loop_update_time) +TEST_DECLARE (loop_backend_timeout) +TEST_DECLARE (loop_configure) +TEST_DECLARE (default_loop_close) +TEST_DECLARE (barrier_1) +TEST_DECLARE (barrier_2) +TEST_DECLARE (barrier_3) +TEST_DECLARE (barrier_serial_thread) +TEST_DECLARE (barrier_serial_thread_single) +TEST_DECLARE (condvar_1) +TEST_DECLARE (condvar_2) +TEST_DECLARE (condvar_3) +TEST_DECLARE (condvar_4) +TEST_DECLARE (condvar_5) +TEST_DECLARE (semaphore_1) +TEST_DECLARE (semaphore_2) +TEST_DECLARE (semaphore_3) +TEST_DECLARE (tty) +#ifdef _WIN32 +TEST_DECLARE (tty_raw) +TEST_DECLARE (tty_empty_write) +TEST_DECLARE (tty_large_write) +TEST_DECLARE (tty_raw_cancel) +TEST_DECLARE (tty_duplicate_vt100_fn_key) +TEST_DECLARE (tty_duplicate_alt_modifier_key) +TEST_DECLARE (tty_composing_character) +TEST_DECLARE (tty_cursor_up) +TEST_DECLARE (tty_cursor_down) +TEST_DECLARE (tty_cursor_forward) +TEST_DECLARE (tty_cursor_back) +TEST_DECLARE (tty_cursor_next_line) +TEST_DECLARE (tty_cursor_previous_line) +TEST_DECLARE (tty_cursor_horizontal_move_absolute) +TEST_DECLARE (tty_cursor_move_absolute) +TEST_DECLARE (tty_hide_show_cursor) +TEST_DECLARE (tty_set_cursor_shape) +TEST_DECLARE (tty_erase) +TEST_DECLARE (tty_erase_line) +TEST_DECLARE (tty_set_style) +TEST_DECLARE (tty_save_restore_cursor_position) +TEST_DECLARE (tty_full_reset) +TEST_DECLARE (tty_escape_sequence_processing) +#endif +TEST_DECLARE (tty_file) +TEST_DECLARE (tty_pty) +TEST_DECLARE (stdio_over_pipes) +TEST_DECLARE (stdio_emulate_iocp) +TEST_DECLARE (ip6_pton) +TEST_DECLARE (ip6_sin6_len) +TEST_DECLARE (connect_unspecified) +TEST_DECLARE (ipc_heavy_traffic_deadlock_bug) +TEST_DECLARE (ipc_listen_before_write) +TEST_DECLARE (ipc_listen_after_write) +#ifndef _WIN32 +TEST_DECLARE (ipc_send_recv_pipe) +TEST_DECLARE (ipc_send_recv_pipe_inprocess) +#endif +TEST_DECLARE (ipc_send_recv_tcp) +TEST_DECLARE (ipc_send_recv_tcp_inprocess) +TEST_DECLARE (ipc_tcp_connection) +TEST_DECLARE (ipc_send_zero) +#ifndef _WIN32 +TEST_DECLARE (ipc_closed_handle) +#endif +TEST_DECLARE (tcp_alloc_cb_fail) +TEST_DECLARE (tcp_ping_pong) +TEST_DECLARE (tcp_ping_pong_vec) +TEST_DECLARE (tcp6_ping_pong) +TEST_DECLARE (tcp6_ping_pong_vec) +TEST_DECLARE (pipe_ping_pong) +TEST_DECLARE (pipe_ping_pong_vec) +TEST_DECLARE (delayed_accept) +TEST_DECLARE (multiple_listen) +#ifndef _WIN32 +TEST_DECLARE (tcp_write_after_connect) +#endif +TEST_DECLARE (tcp_writealot) +TEST_DECLARE (tcp_write_fail) +TEST_DECLARE (tcp_try_write) +TEST_DECLARE (tcp_try_write_error) +TEST_DECLARE (tcp_write_queue_order) +TEST_DECLARE (tcp_open) +TEST_DECLARE (tcp_open_twice) +TEST_DECLARE (tcp_open_bound) +TEST_DECLARE (tcp_open_connected) +TEST_DECLARE (tcp_connect_error_after_write) +TEST_DECLARE (tcp_shutdown_after_write) +TEST_DECLARE (tcp_bind_error_addrinuse_connect) +TEST_DECLARE (tcp_bind_error_addrinuse_listen) +TEST_DECLARE (tcp_bind_error_addrnotavail_1) +TEST_DECLARE (tcp_bind_error_addrnotavail_2) +TEST_DECLARE (tcp_bind_error_fault) +TEST_DECLARE (tcp_bind_error_inval) +TEST_DECLARE (tcp_bind_localhost_ok) +TEST_DECLARE (tcp_bind_invalid_flags) +TEST_DECLARE (tcp_bind_writable_flags) +TEST_DECLARE (tcp_listen_without_bind) +TEST_DECLARE (tcp_connect_error_fault) +TEST_DECLARE (tcp_connect_timeout) +TEST_DECLARE (tcp_local_connect_timeout) +TEST_DECLARE (tcp6_local_connect_timeout) +TEST_DECLARE (tcp_close_while_connecting) +TEST_DECLARE (tcp_close) +TEST_DECLARE (tcp_close_reset_accepted) +TEST_DECLARE (tcp_close_reset_accepted_after_shutdown) +TEST_DECLARE (tcp_close_reset_client) +TEST_DECLARE (tcp_close_reset_client_after_shutdown) +TEST_DECLARE (tcp_create_early) +TEST_DECLARE (tcp_create_early_bad_bind) +TEST_DECLARE (tcp_create_early_bad_domain) +TEST_DECLARE (tcp_create_early_accept) +#ifndef _WIN32 +TEST_DECLARE (tcp_close_accept) +TEST_DECLARE (tcp_oob) +#endif +TEST_DECLARE (tcp_flags) +TEST_DECLARE (tcp_write_to_half_open_connection) +TEST_DECLARE (tcp_unexpected_read) +TEST_DECLARE (tcp_read_stop) +TEST_DECLARE (tcp_read_stop_start) +TEST_DECLARE (tcp_bind6_error_addrinuse) +TEST_DECLARE (tcp_bind6_error_addrnotavail) +TEST_DECLARE (tcp_bind6_error_fault) +TEST_DECLARE (tcp_bind6_error_inval) +TEST_DECLARE (tcp_bind6_localhost_ok) +TEST_DECLARE (tcp_write_ready) +TEST_DECLARE (udp_alloc_cb_fail) +TEST_DECLARE (udp_bind) +TEST_DECLARE (udp_bind_reuseaddr) +TEST_DECLARE (udp_connect) +TEST_DECLARE (udp_create_early) +TEST_DECLARE (udp_create_early_bad_bind) +TEST_DECLARE (udp_create_early_bad_domain) +TEST_DECLARE (udp_send_and_recv) +TEST_DECLARE (udp_send_hang_loop) +TEST_DECLARE (udp_send_immediate) +TEST_DECLARE (udp_send_unreachable) +TEST_DECLARE (udp_mmsg) +TEST_DECLARE (udp_multicast_join) +TEST_DECLARE (udp_multicast_join6) +TEST_DECLARE (udp_multicast_ttl) +TEST_DECLARE (udp_multicast_interface) +TEST_DECLARE (udp_multicast_interface6) +TEST_DECLARE (udp_dgram_too_big) +TEST_DECLARE (udp_dual_stack) +TEST_DECLARE (udp_ipv6_only) +TEST_DECLARE (udp_options) +TEST_DECLARE (udp_options6) +TEST_DECLARE (udp_no_autobind) +TEST_DECLARE (udp_open) +TEST_DECLARE (udp_open_twice) +TEST_DECLARE (udp_open_bound) +TEST_DECLARE (udp_open_connect) +#ifndef _WIN32 +TEST_DECLARE (udp_send_unix) +#endif +TEST_DECLARE (udp_sendmmsg_error) +TEST_DECLARE (udp_try_send) +TEST_DECLARE (pipe_bind_error_addrinuse) +TEST_DECLARE (pipe_bind_error_addrnotavail) +TEST_DECLARE (pipe_bind_error_inval) +TEST_DECLARE (pipe_connect_multiple) +TEST_DECLARE (pipe_listen_without_bind) +TEST_DECLARE (pipe_connect_bad_name) +TEST_DECLARE (pipe_connect_to_file) +TEST_DECLARE (pipe_connect_on_prepare) +TEST_DECLARE (pipe_getsockname) +TEST_DECLARE (pipe_getsockname_abstract) +TEST_DECLARE (pipe_getsockname_blocking) +TEST_DECLARE (pipe_pending_instances) +TEST_DECLARE (pipe_sendmsg) +TEST_DECLARE (pipe_server_close) +TEST_DECLARE (connection_fail) +TEST_DECLARE (connection_fail_doesnt_auto_close) +TEST_DECLARE (shutdown_close_tcp) +TEST_DECLARE (shutdown_close_pipe) +TEST_DECLARE (shutdown_eof) +TEST_DECLARE (shutdown_simultaneous) +TEST_DECLARE (shutdown_twice) +TEST_DECLARE (callback_stack) +TEST_DECLARE (env_vars) +TEST_DECLARE (error_message) +TEST_DECLARE (sys_error) +TEST_DECLARE (timer) +TEST_DECLARE (timer_init) +TEST_DECLARE (timer_again) +TEST_DECLARE (timer_start_twice) +TEST_DECLARE (timer_order) +TEST_DECLARE (timer_huge_timeout) +TEST_DECLARE (timer_huge_repeat) +TEST_DECLARE (timer_run_once) +TEST_DECLARE (timer_from_check) +TEST_DECLARE (timer_is_closing) +TEST_DECLARE (timer_null_callback) +TEST_DECLARE (timer_early_check) +TEST_DECLARE (idle_starvation) +TEST_DECLARE (loop_handles) +TEST_DECLARE (get_loadavg) +TEST_DECLARE (walk_handles) +TEST_DECLARE (watcher_cross_stop) +TEST_DECLARE (ref) +TEST_DECLARE (idle_ref) +TEST_DECLARE (async_ref) +TEST_DECLARE (prepare_ref) +TEST_DECLARE (check_ref) +TEST_DECLARE (unref_in_prepare_cb) +TEST_DECLARE (timer_ref) +TEST_DECLARE (timer_ref2) +TEST_DECLARE (fs_event_ref) +TEST_DECLARE (fs_poll_ref) +TEST_DECLARE (tcp_ref) +TEST_DECLARE (tcp_ref2) +TEST_DECLARE (tcp_ref2b) +TEST_DECLARE (tcp_ref3) +TEST_DECLARE (tcp_ref4) +TEST_DECLARE (udp_ref) +TEST_DECLARE (udp_ref2) +TEST_DECLARE (udp_ref3) +TEST_DECLARE (pipe_ref) +TEST_DECLARE (pipe_ref2) +TEST_DECLARE (pipe_ref3) +TEST_DECLARE (pipe_ref4) +#ifndef _WIN32 +TEST_DECLARE (pipe_close_stdout_read_stdin) +#endif +TEST_DECLARE (pipe_set_non_blocking) +TEST_DECLARE (pipe_set_chmod) +TEST_DECLARE (process_ref) +TEST_DECLARE (process_priority) +TEST_DECLARE (has_ref) +TEST_DECLARE (active) +TEST_DECLARE (embed) +TEST_DECLARE (async) +TEST_DECLARE (async_null_cb) +TEST_DECLARE (eintr_handling) +TEST_DECLARE (get_currentexe) +TEST_DECLARE (process_title) +TEST_DECLARE (process_title_big_argv) +TEST_DECLARE (process_title_threadsafe) +TEST_DECLARE (cwd_and_chdir) +TEST_DECLARE (get_memory) +TEST_DECLARE (get_passwd) +TEST_DECLARE (handle_fileno) +TEST_DECLARE (homedir) +TEST_DECLARE (tmpdir) +TEST_DECLARE (hrtime) +TEST_DECLARE (getaddrinfo_fail) +TEST_DECLARE (getaddrinfo_fail_sync) +TEST_DECLARE (getaddrinfo_basic) +TEST_DECLARE (getaddrinfo_basic_sync) +TEST_DECLARE (getaddrinfo_concurrent) +TEST_DECLARE (gethostname) +TEST_DECLARE (getnameinfo_basic_ip4) +TEST_DECLARE (getnameinfo_basic_ip4_sync) +TEST_DECLARE (getnameinfo_basic_ip6) +TEST_DECLARE (getsockname_tcp) +TEST_DECLARE (getsockname_udp) +TEST_DECLARE (gettimeofday) +TEST_DECLARE (test_macros) +TEST_DECLARE (fail_always) +TEST_DECLARE (pass_always) +TEST_DECLARE (socket_buffer_size) +TEST_DECLARE (spawn_fails) +#ifndef _WIN32 +TEST_DECLARE (spawn_fails_check_for_waitpid_cleanup) +#endif +TEST_DECLARE (spawn_empty_env) +TEST_DECLARE (spawn_exit_code) +TEST_DECLARE (spawn_stdout) +TEST_DECLARE (spawn_stdin) +TEST_DECLARE (spawn_stdio_greater_than_3) +TEST_DECLARE (spawn_ignored_stdio) +TEST_DECLARE (spawn_and_kill) +TEST_DECLARE (spawn_detached) +TEST_DECLARE (spawn_and_kill_with_std) +TEST_DECLARE (spawn_and_ping) +TEST_DECLARE (spawn_preserve_env) +TEST_DECLARE (spawn_setuid_fails) +TEST_DECLARE (spawn_setgid_fails) +TEST_DECLARE (spawn_stdout_to_file) +TEST_DECLARE (spawn_stdout_and_stderr_to_file) +TEST_DECLARE (spawn_stdout_and_stderr_to_file2) +TEST_DECLARE (spawn_stdout_and_stderr_to_file_swap) +TEST_DECLARE (spawn_auto_unref) +TEST_DECLARE (spawn_closed_process_io) +TEST_DECLARE (spawn_reads_child_path) +TEST_DECLARE (spawn_inherit_streams) +TEST_DECLARE (spawn_quoted_path) +TEST_DECLARE (spawn_tcp_server) +TEST_DECLARE (fs_poll) +TEST_DECLARE (fs_poll_getpath) +TEST_DECLARE (fs_poll_close_request) +TEST_DECLARE (fs_poll_close_request_multi_start_stop) +TEST_DECLARE (fs_poll_close_request_multi_stop_start) +TEST_DECLARE (fs_poll_close_request_stop_when_active) +TEST_DECLARE (kill) +TEST_DECLARE (kill_invalid_signum) +TEST_DECLARE (fs_file_noent) +TEST_DECLARE (fs_file_nametoolong) +TEST_DECLARE (fs_file_loop) +TEST_DECLARE (fs_file_async) +TEST_DECLARE (fs_file_sync) +TEST_DECLARE (fs_file_write_null_buffer) +TEST_DECLARE (fs_async_dir) +TEST_DECLARE (fs_async_sendfile) +TEST_DECLARE (fs_async_sendfile_nodata) +TEST_DECLARE (fs_mkdtemp) +TEST_DECLARE (fs_mkstemp) +TEST_DECLARE (fs_fstat) +TEST_DECLARE (fs_access) +TEST_DECLARE (fs_chmod) +TEST_DECLARE (fs_copyfile) +TEST_DECLARE (fs_unlink_readonly) +#ifdef _WIN32 +TEST_DECLARE (fs_unlink_archive_readonly) +#endif +TEST_DECLARE (fs_chown) +TEST_DECLARE (fs_link) +TEST_DECLARE (fs_readlink) +TEST_DECLARE (fs_realpath) +TEST_DECLARE (fs_symlink) +TEST_DECLARE (fs_symlink_dir) +#ifdef _WIN32 +TEST_DECLARE (fs_symlink_junction) +TEST_DECLARE (fs_non_symlink_reparse_point) +TEST_DECLARE (fs_lstat_windows_store_apps) +TEST_DECLARE (fs_open_flags) +#endif +#if defined(_WIN32) && !defined(USING_UV_SHARED) +TEST_DECLARE (fs_fd_hash) +#endif +TEST_DECLARE (fs_utime) +TEST_DECLARE (fs_utime_round) +TEST_DECLARE (fs_futime) +TEST_DECLARE (fs_lutime) +TEST_DECLARE (fs_file_open_append) +TEST_DECLARE (fs_statfs) +TEST_DECLARE (fs_stat_missing_path) +TEST_DECLARE (fs_read_bufs) +TEST_DECLARE (fs_read_file_eof) +TEST_DECLARE (fs_event_watch_dir) +TEST_DECLARE (fs_event_watch_dir_recursive) +#ifdef _WIN32 +TEST_DECLARE (fs_event_watch_dir_short_path) +#endif +TEST_DECLARE (fs_event_watch_file) +TEST_DECLARE (fs_event_watch_file_exact_path) +TEST_DECLARE (fs_event_watch_file_twice) +TEST_DECLARE (fs_event_watch_file_current_dir) +#ifdef _WIN32 +TEST_DECLARE (fs_event_watch_file_root_dir) +#endif +TEST_DECLARE (fs_event_watch_invalid_path) +TEST_DECLARE (fs_event_no_callback_after_close) +TEST_DECLARE (fs_event_no_callback_on_close) +TEST_DECLARE (fs_event_immediate_close) +TEST_DECLARE (fs_event_close_with_pending_event) +TEST_DECLARE (fs_event_close_in_callback) +TEST_DECLARE (fs_event_start_and_close) +TEST_DECLARE (fs_event_error_reporting) +TEST_DECLARE (fs_event_getpath) +TEST_DECLARE (fs_scandir_empty_dir) +TEST_DECLARE (fs_scandir_non_existent_dir) +TEST_DECLARE (fs_scandir_file) +TEST_DECLARE (fs_open_dir) +TEST_DECLARE (fs_readdir_empty_dir) +TEST_DECLARE (fs_readdir_file) +TEST_DECLARE (fs_readdir_non_empty_dir) +TEST_DECLARE (fs_readdir_non_existing_dir) +TEST_DECLARE (fs_rename_to_existing_file) +TEST_DECLARE (fs_write_multiple_bufs) +TEST_DECLARE (fs_read_write_null_arguments) +TEST_DECLARE (get_osfhandle_valid_handle) +TEST_DECLARE (open_osfhandle_valid_handle) +TEST_DECLARE (fs_write_alotof_bufs) +TEST_DECLARE (fs_write_alotof_bufs_with_offset) +TEST_DECLARE (fs_partial_read) +TEST_DECLARE (fs_partial_write) +TEST_DECLARE (fs_file_pos_after_op_with_offset) +TEST_DECLARE (fs_null_req) +TEST_DECLARE (fs_read_dir) +#ifdef _WIN32 +TEST_DECLARE (fs_file_pos_write) +TEST_DECLARE (fs_file_pos_append) +TEST_DECLARE (fs_exclusive_sharing_mode) +TEST_DECLARE (fs_file_flag_no_buffering) +TEST_DECLARE (fs_open_readonly_acl) +TEST_DECLARE (fs_fchmod_archive_readonly) +TEST_DECLARE (fs_invalid_mkdir_name) +#endif +TEST_DECLARE (fs_get_system_error) +TEST_DECLARE (strscpy) +TEST_DECLARE (threadpool_queue_work_simple) +TEST_DECLARE (threadpool_queue_work_einval) +TEST_DECLARE (threadpool_multiple_event_loops) +TEST_DECLARE (threadpool_cancel_getaddrinfo) +TEST_DECLARE (threadpool_cancel_getnameinfo) +TEST_DECLARE (threadpool_cancel_random) +TEST_DECLARE (threadpool_cancel_work) +TEST_DECLARE (threadpool_cancel_fs) +TEST_DECLARE (threadpool_cancel_single) +TEST_DECLARE (thread_local_storage) +TEST_DECLARE (thread_stack_size) +TEST_DECLARE (thread_stack_size_explicit) +TEST_DECLARE (thread_mutex) +TEST_DECLARE (thread_mutex_recursive) +TEST_DECLARE (thread_rwlock) +TEST_DECLARE (thread_rwlock_trylock) +TEST_DECLARE (thread_create) +TEST_DECLARE (thread_equal) +TEST_DECLARE (dlerror) +#if (defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))) && \ + !defined(__sun) +TEST_DECLARE (poll_oob) +#endif +TEST_DECLARE (poll_duplex) +TEST_DECLARE (poll_unidirectional) +TEST_DECLARE (poll_close) +TEST_DECLARE (poll_bad_fdtype) +#ifdef __linux__ +TEST_DECLARE (poll_nested_epoll) +#endif +#ifdef UV_HAVE_KQUEUE +TEST_DECLARE (poll_nested_kqueue) +#endif +TEST_DECLARE (poll_multiple_handles) + +TEST_DECLARE (ip4_addr) +TEST_DECLARE (ip6_addr_link_local) + +TEST_DECLARE (poll_close_doesnt_corrupt_stack) +TEST_DECLARE (poll_closesocket) +TEST_DECLARE (close_fd) +TEST_DECLARE (closed_fd_events) +TEST_DECLARE (spawn_fs_open) +#ifdef _WIN32 +TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows) +#if !defined(USING_UV_SHARED) +TEST_DECLARE (argument_escaping) +TEST_DECLARE (environment_creation) +#endif +TEST_DECLARE (listen_with_simultaneous_accepts) +TEST_DECLARE (listen_no_simultaneous_accepts) +TEST_DECLARE (fs_stat_root) +TEST_DECLARE (spawn_with_an_odd_path) +TEST_DECLARE (ipc_listen_after_bind_twice) +TEST_DECLARE (win32_signum_number) +#else +TEST_DECLARE (emfile) +TEST_DECLARE (spawn_setuid_setgid) +TEST_DECLARE (we_get_signal) +TEST_DECLARE (we_get_signals) +TEST_DECLARE (we_get_signal_one_shot) +TEST_DECLARE (we_get_signals_mixed) +TEST_DECLARE (signal_multiple_loops) +TEST_DECLARE (signal_pending_on_close) +TEST_DECLARE (signal_close_loop_alive) +#endif +#ifdef __APPLE__ +TEST_DECLARE (osx_select) +TEST_DECLARE (osx_select_many_fds) +#endif +HELPER_DECLARE (tcp4_echo_server) +HELPER_DECLARE (tcp6_echo_server) +HELPER_DECLARE (udp4_echo_server) +HELPER_DECLARE (pipe_echo_server) + +TEST_DECLARE (queue_foreach_delete) + +TEST_DECLARE (random_async) +TEST_DECLARE (random_sync) + +TEST_DECLARE (handle_type_name) +TEST_DECLARE (req_type_name) +TEST_DECLARE (getters_setters) + +TEST_DECLARE (not_writable_after_shutdown) +TEST_DECLARE (not_readable_nor_writable_on_read_error) +TEST_DECLARE (not_readable_on_eof) + +#ifndef _WIN32 +TEST_DECLARE (fork_timer) +TEST_DECLARE (fork_socketpair) +TEST_DECLARE (fork_socketpair_started) +TEST_DECLARE (fork_signal_to_child) +TEST_DECLARE (fork_signal_to_child_closed) +#ifndef __APPLE__ /* This is forbidden in a fork child: The process has forked + and you cannot use this CoreFoundation functionality + safely. You MUST exec(). */ +TEST_DECLARE (fork_fs_events_child) +TEST_DECLARE (fork_fs_events_child_dir) +TEST_DECLARE (fork_fs_events_file_parent_child) +#endif +#ifndef __MVS__ +TEST_DECLARE (fork_threadpool_queue_work_simple) +#endif +#endif + +TEST_DECLARE (idna_toascii) +TEST_DECLARE (utf8_decode1) +TEST_DECLARE (utf8_decode1_overrun) +TEST_DECLARE (uname) + +TEST_DECLARE (metrics_idle_time) +TEST_DECLARE (metrics_idle_time_thread) +TEST_DECLARE (metrics_idle_time_zero) + +TASK_LIST_START + TEST_ENTRY_CUSTOM (platform_output, 0, 1, 5000) + +#if 0 + TEST_ENTRY (callback_order) +#endif + TEST_ENTRY (test_macros) + TEST_ENTRY (close_order) + TEST_ENTRY (run_once) + TEST_ENTRY (run_nowait) + TEST_ENTRY (loop_alive) + TEST_ENTRY (loop_close) + TEST_ENTRY (loop_instant_close) + TEST_ENTRY (loop_stop) + TEST_ENTRY (loop_update_time) + TEST_ENTRY (loop_backend_timeout) + TEST_ENTRY (loop_configure) + TEST_ENTRY (default_loop_close) + TEST_ENTRY (barrier_1) + TEST_ENTRY (barrier_2) + TEST_ENTRY (barrier_3) + TEST_ENTRY (barrier_serial_thread) + TEST_ENTRY (barrier_serial_thread_single) + TEST_ENTRY (condvar_1) + TEST_ENTRY (condvar_2) + TEST_ENTRY (condvar_3) + TEST_ENTRY (condvar_4) + TEST_ENTRY (condvar_5) + TEST_ENTRY (semaphore_1) + TEST_ENTRY (semaphore_2) + TEST_ENTRY (semaphore_3) + + TEST_ENTRY (pipe_connect_bad_name) + TEST_ENTRY (pipe_connect_to_file) + TEST_ENTRY (pipe_connect_on_prepare) + + TEST_ENTRY (pipe_server_close) +#ifndef _WIN32 + TEST_ENTRY (pipe_close_stdout_read_stdin) +#endif + /* Seems to be either about 0.5s or 5s, depending on the OS. */ + TEST_ENTRY_CUSTOM (pipe_set_non_blocking, 0, 0, 20000) + TEST_ENTRY (pipe_set_chmod) + TEST_ENTRY (tty) +#ifdef _WIN32 + TEST_ENTRY (tty_raw) + TEST_ENTRY (tty_empty_write) + TEST_ENTRY (tty_large_write) + TEST_ENTRY (tty_raw_cancel) + TEST_ENTRY (tty_duplicate_vt100_fn_key) + TEST_ENTRY (tty_duplicate_alt_modifier_key) + TEST_ENTRY (tty_composing_character) + TEST_ENTRY (tty_cursor_up) + TEST_ENTRY (tty_cursor_down) + TEST_ENTRY (tty_cursor_forward) + TEST_ENTRY (tty_cursor_back) + TEST_ENTRY (tty_cursor_next_line) + TEST_ENTRY (tty_cursor_previous_line) + TEST_ENTRY (tty_cursor_horizontal_move_absolute) + TEST_ENTRY (tty_cursor_move_absolute) + TEST_ENTRY (tty_hide_show_cursor) + TEST_ENTRY (tty_set_cursor_shape) + TEST_ENTRY (tty_erase) + TEST_ENTRY (tty_erase_line) + TEST_ENTRY (tty_set_style) + TEST_ENTRY (tty_save_restore_cursor_position) + TEST_ENTRY (tty_full_reset) + TEST_ENTRY (tty_escape_sequence_processing) +#endif + TEST_ENTRY (tty_file) + TEST_ENTRY (tty_pty) + TEST_ENTRY (stdio_over_pipes) + TEST_ENTRY (stdio_emulate_iocp) + TEST_ENTRY (ip6_pton) + TEST_ENTRY (ip6_sin6_len) + TEST_ENTRY (connect_unspecified) + TEST_ENTRY (ipc_heavy_traffic_deadlock_bug) + TEST_ENTRY (ipc_listen_before_write) + TEST_ENTRY (ipc_listen_after_write) +#ifndef _WIN32 + TEST_ENTRY (ipc_send_recv_pipe) + TEST_ENTRY (ipc_send_recv_pipe_inprocess) +#endif + TEST_ENTRY (ipc_send_recv_tcp) + TEST_ENTRY (ipc_send_recv_tcp_inprocess) + TEST_ENTRY (ipc_tcp_connection) + TEST_ENTRY (ipc_send_zero) +#ifndef _WIN32 + TEST_ENTRY (ipc_closed_handle) +#endif + + TEST_ENTRY (tcp_alloc_cb_fail) + + TEST_ENTRY (tcp_ping_pong) + TEST_HELPER (tcp_ping_pong, tcp4_echo_server) + + TEST_ENTRY (tcp_ping_pong_vec) + TEST_HELPER (tcp_ping_pong_vec, tcp4_echo_server) + + TEST_ENTRY (tcp6_ping_pong) + TEST_HELPER (tcp6_ping_pong, tcp6_echo_server) + + TEST_ENTRY (tcp6_ping_pong_vec) + TEST_HELPER (tcp6_ping_pong_vec, tcp6_echo_server) + + TEST_ENTRY (pipe_ping_pong) + TEST_HELPER (pipe_ping_pong, pipe_echo_server) + + TEST_ENTRY (pipe_ping_pong_vec) + TEST_HELPER (pipe_ping_pong_vec, pipe_echo_server) + + TEST_ENTRY (delayed_accept) + TEST_ENTRY (multiple_listen) + +#ifndef _WIN32 + TEST_ENTRY (tcp_write_after_connect) +#endif + +#ifdef __MVS__ + TEST_ENTRY_CUSTOM (tcp_writealot, 0, 0, 20000) +#else + TEST_ENTRY (tcp_writealot) +#endif + TEST_HELPER (tcp_writealot, tcp4_echo_server) + + TEST_ENTRY (tcp_write_fail) + TEST_HELPER (tcp_write_fail, tcp4_echo_server) + + TEST_ENTRY (tcp_try_write) + TEST_ENTRY (tcp_try_write_error) + + TEST_ENTRY (tcp_write_queue_order) + + TEST_ENTRY (tcp_open) + TEST_HELPER (tcp_open, tcp4_echo_server) + TEST_ENTRY (tcp_open_twice) + TEST_ENTRY (tcp_open_bound) + TEST_ENTRY (tcp_open_connected) + TEST_HELPER (tcp_open_connected, tcp4_echo_server) + TEST_ENTRY (tcp_write_ready) + TEST_HELPER (tcp_write_ready, tcp4_echo_server) + + TEST_ENTRY (tcp_shutdown_after_write) + TEST_HELPER (tcp_shutdown_after_write, tcp4_echo_server) + + TEST_ENTRY (tcp_connect_error_after_write) + TEST_ENTRY (tcp_bind_error_addrinuse_connect) + /* tcp4_echo_server steals the port. It needs to be a separate process + * because libuv sets setsockopt(SO_REUSEADDR) that lets you steal an + * existing bind if it originates from the same process. + */ + TEST_HELPER (tcp_bind_error_addrinuse_connect, tcp4_echo_server) + TEST_ENTRY (tcp_bind_error_addrinuse_listen) + TEST_ENTRY (tcp_bind_error_addrnotavail_1) + TEST_ENTRY (tcp_bind_error_addrnotavail_2) + TEST_ENTRY (tcp_bind_error_fault) + TEST_ENTRY (tcp_bind_error_inval) + TEST_ENTRY (tcp_bind_localhost_ok) + TEST_ENTRY (tcp_bind_invalid_flags) + TEST_ENTRY (tcp_bind_writable_flags) + TEST_ENTRY (tcp_listen_without_bind) + TEST_ENTRY (tcp_connect_error_fault) + TEST_ENTRY (tcp_connect_timeout) + TEST_ENTRY (tcp_local_connect_timeout) + TEST_ENTRY (tcp6_local_connect_timeout) + TEST_ENTRY (tcp_close_while_connecting) + TEST_ENTRY (tcp_close) + TEST_ENTRY (tcp_close_reset_accepted) + TEST_ENTRY (tcp_close_reset_accepted_after_shutdown) + TEST_ENTRY (tcp_close_reset_client) + TEST_ENTRY (tcp_close_reset_client_after_shutdown) + TEST_ENTRY (tcp_create_early) + TEST_ENTRY (tcp_create_early_bad_bind) + TEST_ENTRY (tcp_create_early_bad_domain) + TEST_ENTRY (tcp_create_early_accept) +#ifndef _WIN32 + TEST_ENTRY (tcp_close_accept) + TEST_ENTRY (tcp_oob) +#endif + TEST_ENTRY (tcp_flags) + TEST_ENTRY (tcp_write_to_half_open_connection) + TEST_ENTRY (tcp_unexpected_read) + + TEST_ENTRY (tcp_read_stop) + TEST_HELPER (tcp_read_stop, tcp4_echo_server) + + TEST_ENTRY (tcp_read_stop_start) + + TEST_ENTRY (tcp_bind6_error_addrinuse) + TEST_ENTRY (tcp_bind6_error_addrnotavail) + TEST_ENTRY (tcp_bind6_error_fault) + TEST_ENTRY (tcp_bind6_error_inval) + TEST_ENTRY (tcp_bind6_localhost_ok) + + TEST_ENTRY (udp_alloc_cb_fail) + TEST_ENTRY (udp_bind) + TEST_ENTRY (udp_bind_reuseaddr) + TEST_ENTRY (udp_connect) + TEST_ENTRY (udp_create_early) + TEST_ENTRY (udp_create_early_bad_bind) + TEST_ENTRY (udp_create_early_bad_domain) + TEST_ENTRY (udp_send_and_recv) + TEST_ENTRY (udp_send_hang_loop) + TEST_ENTRY (udp_send_immediate) + TEST_ENTRY (udp_send_unreachable) + TEST_ENTRY (udp_dgram_too_big) + TEST_ENTRY (udp_dual_stack) + TEST_ENTRY (udp_ipv6_only) + TEST_ENTRY (udp_options) + TEST_ENTRY (udp_options6) + TEST_ENTRY (udp_no_autobind) + TEST_ENTRY (udp_mmsg) + TEST_ENTRY (udp_multicast_interface) + TEST_ENTRY (udp_multicast_interface6) + TEST_ENTRY (udp_multicast_join) + TEST_ENTRY (udp_multicast_join6) + TEST_ENTRY (udp_multicast_ttl) + TEST_ENTRY (udp_sendmmsg_error) + TEST_ENTRY (udp_try_send) + + TEST_ENTRY (udp_open) + TEST_ENTRY (udp_open_twice) + TEST_ENTRY (udp_open_bound) + TEST_ENTRY (udp_open_connect) +#ifndef _WIN32 + TEST_ENTRY (udp_send_unix) +#endif + + TEST_ENTRY (pipe_bind_error_addrinuse) + TEST_ENTRY (pipe_bind_error_addrnotavail) + TEST_ENTRY (pipe_bind_error_inval) + TEST_ENTRY (pipe_connect_multiple) + TEST_ENTRY (pipe_listen_without_bind) + TEST_ENTRY (pipe_getsockname) + TEST_ENTRY (pipe_getsockname_abstract) + TEST_ENTRY (pipe_getsockname_blocking) + TEST_ENTRY (pipe_pending_instances) + TEST_ENTRY (pipe_sendmsg) + + TEST_ENTRY (connection_fail) + TEST_ENTRY (connection_fail_doesnt_auto_close) + + TEST_ENTRY (shutdown_close_tcp) + TEST_HELPER (shutdown_close_tcp, tcp4_echo_server) + TEST_ENTRY (shutdown_close_pipe) + TEST_HELPER (shutdown_close_pipe, pipe_echo_server) + + TEST_ENTRY (shutdown_eof) + TEST_HELPER (shutdown_eof, tcp4_echo_server) + + TEST_ENTRY (shutdown_simultaneous) + TEST_HELPER (shutdown_simultaneous, tcp4_echo_server) + + TEST_ENTRY (shutdown_twice) + TEST_HELPER (shutdown_twice, tcp4_echo_server) + + TEST_ENTRY (callback_stack) + TEST_HELPER (callback_stack, tcp4_echo_server) + + TEST_ENTRY (env_vars) + + TEST_ENTRY (error_message) + TEST_ENTRY (sys_error) + + TEST_ENTRY (timer) + TEST_ENTRY (timer_init) + TEST_ENTRY (timer_again) + TEST_ENTRY (timer_start_twice) + TEST_ENTRY (timer_order) + TEST_ENTRY (timer_huge_timeout) + TEST_ENTRY (timer_huge_repeat) + TEST_ENTRY (timer_run_once) + TEST_ENTRY (timer_from_check) + TEST_ENTRY (timer_is_closing) + TEST_ENTRY (timer_null_callback) + TEST_ENTRY (timer_early_check) + + TEST_ENTRY (idle_starvation) + + TEST_ENTRY (ref) + TEST_ENTRY (idle_ref) + TEST_ENTRY (fs_poll_ref) + TEST_ENTRY (async_ref) + TEST_ENTRY (prepare_ref) + TEST_ENTRY (check_ref) + TEST_ENTRY (unref_in_prepare_cb) + TEST_ENTRY (timer_ref) + TEST_ENTRY (timer_ref2) + TEST_ENTRY (fs_event_ref) + TEST_ENTRY (tcp_ref) + TEST_ENTRY (tcp_ref2) + TEST_ENTRY (tcp_ref2b) + TEST_ENTRY (tcp_ref3) + TEST_HELPER (tcp_ref3, tcp4_echo_server) + TEST_ENTRY (tcp_ref4) + TEST_HELPER (tcp_ref4, tcp4_echo_server) + TEST_ENTRY (udp_ref) + TEST_ENTRY (udp_ref2) + TEST_ENTRY (udp_ref3) + TEST_HELPER (udp_ref3, udp4_echo_server) + TEST_ENTRY (pipe_ref) + TEST_ENTRY (pipe_ref2) + TEST_ENTRY (pipe_ref3) + TEST_HELPER (pipe_ref3, pipe_echo_server) + TEST_ENTRY (pipe_ref4) + TEST_HELPER (pipe_ref4, pipe_echo_server) + TEST_ENTRY (process_ref) + TEST_ENTRY (process_priority) + TEST_ENTRY (has_ref) + + TEST_ENTRY (loop_handles) + TEST_ENTRY (walk_handles) + + TEST_ENTRY (watcher_cross_stop) + + TEST_ENTRY (active) + + TEST_ENTRY (embed) + + TEST_ENTRY (async) + TEST_ENTRY (async_null_cb) + TEST_ENTRY (eintr_handling) + + TEST_ENTRY (get_currentexe) + + TEST_ENTRY (process_title) + TEST_ENTRY (process_title_big_argv) + TEST_ENTRY (process_title_threadsafe) + + TEST_ENTRY (cwd_and_chdir) + + TEST_ENTRY (get_memory) + + TEST_ENTRY (get_passwd) + + TEST_ENTRY (get_loadavg) + + TEST_ENTRY (handle_fileno) + + TEST_ENTRY (homedir) + + TEST_ENTRY (tmpdir) + + TEST_ENTRY_CUSTOM (hrtime, 0, 0, 20000) + + TEST_ENTRY_CUSTOM (getaddrinfo_fail, 0, 0, 10000) + TEST_ENTRY_CUSTOM (getaddrinfo_fail_sync, 0, 0, 10000) + + TEST_ENTRY (getaddrinfo_basic) + TEST_ENTRY (getaddrinfo_basic_sync) + TEST_ENTRY (getaddrinfo_concurrent) + + TEST_ENTRY (gethostname) + + TEST_ENTRY (getnameinfo_basic_ip4) + TEST_ENTRY (getnameinfo_basic_ip4_sync) + TEST_ENTRY (getnameinfo_basic_ip6) + + TEST_ENTRY (getsockname_tcp) + TEST_ENTRY (getsockname_udp) + + TEST_ENTRY (gettimeofday) + + TEST_ENTRY (poll_duplex) + TEST_ENTRY (poll_unidirectional) + TEST_ENTRY (poll_close) + TEST_ENTRY (poll_bad_fdtype) +#if (defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))) && \ + !defined(__sun) + TEST_ENTRY (poll_oob) +#endif + +#ifdef __linux__ + TEST_ENTRY (poll_nested_epoll) +#endif +#ifdef UV_HAVE_KQUEUE + TEST_ENTRY (poll_nested_kqueue) +#endif + TEST_ENTRY (poll_multiple_handles) + + TEST_ENTRY (socket_buffer_size) + + TEST_ENTRY (spawn_fails) +#ifndef _WIN32 + TEST_ENTRY (spawn_fails_check_for_waitpid_cleanup) +#endif + TEST_ENTRY (spawn_empty_env) + TEST_ENTRY (spawn_exit_code) + TEST_ENTRY (spawn_stdout) + TEST_ENTRY (spawn_stdin) + TEST_ENTRY (spawn_stdio_greater_than_3) + TEST_ENTRY (spawn_ignored_stdio) + TEST_ENTRY (spawn_and_kill) + TEST_ENTRY (spawn_detached) + TEST_ENTRY (spawn_and_kill_with_std) + TEST_ENTRY (spawn_and_ping) + TEST_ENTRY (spawn_preserve_env) + TEST_ENTRY (spawn_setuid_fails) + TEST_ENTRY (spawn_setgid_fails) + TEST_ENTRY (spawn_stdout_to_file) + TEST_ENTRY (spawn_stdout_and_stderr_to_file) + TEST_ENTRY (spawn_stdout_and_stderr_to_file2) + TEST_ENTRY (spawn_stdout_and_stderr_to_file_swap) + TEST_ENTRY (spawn_auto_unref) + TEST_ENTRY (spawn_closed_process_io) + TEST_ENTRY (spawn_reads_child_path) + TEST_ENTRY (spawn_inherit_streams) + TEST_ENTRY (spawn_quoted_path) + TEST_ENTRY (spawn_tcp_server) + TEST_ENTRY (fs_poll) + TEST_ENTRY (fs_poll_getpath) + TEST_ENTRY (fs_poll_close_request) + TEST_ENTRY (fs_poll_close_request_multi_start_stop) + TEST_ENTRY (fs_poll_close_request_multi_stop_start) + TEST_ENTRY (fs_poll_close_request_stop_when_active) + TEST_ENTRY (kill) + TEST_ENTRY (kill_invalid_signum) + + TEST_ENTRY (poll_close_doesnt_corrupt_stack) + TEST_ENTRY (poll_closesocket) + TEST_ENTRY (close_fd) + TEST_ENTRY (closed_fd_events) + TEST_ENTRY (spawn_fs_open) +#ifdef _WIN32 + TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows) +#if !defined(USING_UV_SHARED) + TEST_ENTRY (argument_escaping) + TEST_ENTRY (environment_creation) +# endif + TEST_ENTRY (listen_with_simultaneous_accepts) + TEST_ENTRY (listen_no_simultaneous_accepts) + TEST_ENTRY (fs_stat_root) + TEST_ENTRY (spawn_with_an_odd_path) + TEST_ENTRY (ipc_listen_after_bind_twice) + TEST_ENTRY (win32_signum_number) +#else + TEST_ENTRY (emfile) + TEST_ENTRY (spawn_setuid_setgid) + TEST_ENTRY (we_get_signal) + TEST_ENTRY (we_get_signals) + TEST_ENTRY (we_get_signal_one_shot) + TEST_ENTRY (we_get_signals_mixed) + TEST_ENTRY (signal_multiple_loops) + TEST_ENTRY (signal_pending_on_close) + TEST_ENTRY (signal_close_loop_alive) +#endif + +#ifdef __APPLE__ + TEST_ENTRY (osx_select) + TEST_ENTRY (osx_select_many_fds) +#endif + + TEST_ENTRY (fs_file_noent) + TEST_ENTRY (fs_file_nametoolong) + TEST_ENTRY (fs_file_loop) + TEST_ENTRY (fs_file_async) + TEST_ENTRY (fs_file_sync) + TEST_ENTRY (fs_file_write_null_buffer) + TEST_ENTRY (fs_async_dir) + TEST_ENTRY (fs_async_sendfile) + TEST_ENTRY (fs_async_sendfile_nodata) + TEST_ENTRY (fs_mkdtemp) + TEST_ENTRY (fs_mkstemp) + TEST_ENTRY (fs_fstat) + TEST_ENTRY (fs_access) + TEST_ENTRY (fs_chmod) + TEST_ENTRY (fs_copyfile) + TEST_ENTRY (fs_unlink_readonly) +#ifdef _WIN32 + TEST_ENTRY (fs_unlink_archive_readonly) +#endif + TEST_ENTRY (fs_chown) + TEST_ENTRY (fs_utime) + TEST_ENTRY (fs_utime_round) + TEST_ENTRY (fs_futime) + TEST_ENTRY (fs_lutime) + TEST_ENTRY (fs_readlink) + TEST_ENTRY (fs_realpath) + TEST_ENTRY (fs_symlink) + TEST_ENTRY (fs_symlink_dir) +#ifdef _WIN32 + TEST_ENTRY (fs_symlink_junction) + TEST_ENTRY (fs_non_symlink_reparse_point) + TEST_ENTRY (fs_lstat_windows_store_apps) + TEST_ENTRY (fs_open_flags) +#endif +#if defined(_WIN32) && !defined(USING_UV_SHARED) + TEST_ENTRY (fs_fd_hash) +#endif + TEST_ENTRY (fs_statfs) + TEST_ENTRY (fs_stat_missing_path) + TEST_ENTRY (fs_read_bufs) + TEST_ENTRY (fs_read_file_eof) + TEST_ENTRY (fs_file_open_append) + TEST_ENTRY (fs_event_watch_dir) + TEST_ENTRY (fs_event_watch_dir_recursive) +#ifdef _WIN32 + TEST_ENTRY (fs_event_watch_dir_short_path) +#endif + TEST_ENTRY (fs_event_watch_file) + TEST_ENTRY (fs_event_watch_file_exact_path) + TEST_ENTRY (fs_event_watch_file_twice) + TEST_ENTRY (fs_event_watch_file_current_dir) +#ifdef _WIN32 + TEST_ENTRY (fs_event_watch_file_root_dir) +#endif + TEST_ENTRY (fs_event_watch_invalid_path) + TEST_ENTRY (fs_event_no_callback_after_close) + TEST_ENTRY (fs_event_no_callback_on_close) + TEST_ENTRY (fs_event_immediate_close) + TEST_ENTRY (fs_event_close_with_pending_event) + TEST_ENTRY (fs_event_close_in_callback) + TEST_ENTRY (fs_event_start_and_close) + TEST_ENTRY_CUSTOM (fs_event_error_reporting, 0, 0, 60000) + TEST_ENTRY (fs_event_getpath) + TEST_ENTRY (fs_scandir_empty_dir) + TEST_ENTRY (fs_scandir_non_existent_dir) + TEST_ENTRY (fs_scandir_file) + TEST_ENTRY (fs_open_dir) + TEST_ENTRY (fs_readdir_empty_dir) + TEST_ENTRY (fs_readdir_file) + TEST_ENTRY (fs_readdir_non_empty_dir) + TEST_ENTRY (fs_readdir_non_existing_dir) + TEST_ENTRY (fs_rename_to_existing_file) + TEST_ENTRY (fs_write_multiple_bufs) + TEST_ENTRY (fs_write_alotof_bufs) + TEST_ENTRY (fs_write_alotof_bufs_with_offset) + TEST_ENTRY (fs_partial_read) + TEST_ENTRY (fs_partial_write) + TEST_ENTRY (fs_read_write_null_arguments) + TEST_ENTRY (fs_file_pos_after_op_with_offset) + TEST_ENTRY (fs_null_req) + TEST_ENTRY (fs_read_dir) +#ifdef _WIN32 + TEST_ENTRY (fs_file_pos_write) + TEST_ENTRY (fs_file_pos_append) + TEST_ENTRY (fs_exclusive_sharing_mode) + TEST_ENTRY (fs_file_flag_no_buffering) + TEST_ENTRY (fs_open_readonly_acl) + TEST_ENTRY (fs_fchmod_archive_readonly) + TEST_ENTRY (fs_invalid_mkdir_name) +#endif + TEST_ENTRY (fs_get_system_error) + TEST_ENTRY (get_osfhandle_valid_handle) + TEST_ENTRY (open_osfhandle_valid_handle) + TEST_ENTRY (strscpy) + TEST_ENTRY (threadpool_queue_work_simple) + TEST_ENTRY (threadpool_queue_work_einval) + TEST_ENTRY_CUSTOM (threadpool_multiple_event_loops, 0, 0, 60000) + TEST_ENTRY (threadpool_cancel_getaddrinfo) + TEST_ENTRY (threadpool_cancel_getnameinfo) + TEST_ENTRY (threadpool_cancel_random) + TEST_ENTRY (threadpool_cancel_work) + TEST_ENTRY (threadpool_cancel_fs) + TEST_ENTRY (threadpool_cancel_single) + TEST_ENTRY (thread_local_storage) + TEST_ENTRY (thread_stack_size) + TEST_ENTRY (thread_stack_size_explicit) + TEST_ENTRY (thread_mutex) + TEST_ENTRY (thread_mutex_recursive) + TEST_ENTRY (thread_rwlock) + TEST_ENTRY (thread_rwlock_trylock) + TEST_ENTRY (thread_create) + TEST_ENTRY (thread_equal) + TEST_ENTRY (dlerror) + TEST_ENTRY (ip4_addr) + TEST_ENTRY (ip6_addr_link_local) + + TEST_ENTRY (queue_foreach_delete) + + TEST_ENTRY (random_async) + TEST_ENTRY (random_sync) + + TEST_ENTRY (handle_type_name) + TEST_ENTRY (req_type_name) + TEST_ENTRY (getters_setters) + +#ifndef _WIN32 + TEST_ENTRY (fork_timer) + TEST_ENTRY (fork_socketpair) + TEST_ENTRY (fork_socketpair_started) + TEST_ENTRY (fork_signal_to_child) + TEST_ENTRY (fork_signal_to_child_closed) +#ifndef __APPLE__ + TEST_ENTRY (fork_fs_events_child) + TEST_ENTRY (fork_fs_events_child_dir) + TEST_ENTRY (fork_fs_events_file_parent_child) +#endif +#ifndef __MVS__ + TEST_ENTRY (fork_threadpool_queue_work_simple) +#endif +#endif + + TEST_ENTRY (utf8_decode1) + TEST_ENTRY (utf8_decode1_overrun) + TEST_ENTRY (uname) + +/* Doesn't work on z/OS because that platform uses EBCDIC, not ASCII. */ +#ifndef __MVS__ + TEST_ENTRY (idna_toascii) +#endif + + TEST_ENTRY (not_writable_after_shutdown) + TEST_HELPER (not_writable_after_shutdown, tcp4_echo_server) + TEST_ENTRY (not_readable_nor_writable_on_read_error) + TEST_HELPER (not_readable_nor_writable_on_read_error, tcp4_echo_server) + TEST_ENTRY (not_readable_on_eof) + TEST_HELPER (not_readable_on_eof, tcp4_echo_server) + + TEST_ENTRY (metrics_idle_time) + TEST_ENTRY (metrics_idle_time_thread) + TEST_ENTRY (metrics_idle_time_zero) + +#if 0 + /* These are for testing the test runner. */ + TEST_ENTRY (fail_always) + TEST_ENTRY (pass_always) +#endif +TASK_LIST_END diff --git a/external/src/libuv/test/test-loop-alive.c b/external/src/libuv/test/test-loop-alive.c new file mode 100644 index 0000000..cf4d301 --- /dev/null +++ b/external/src/libuv/test/test-loop-alive.c @@ -0,0 +1,67 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static uv_timer_t timer_handle; + +static void timer_cb(uv_timer_t* handle) { + ASSERT(handle); +} + + +static uv_work_t work_req; + +static void work_cb(uv_work_t* req) { + ASSERT(req); +} + +static void after_work_cb(uv_work_t* req, int status) { + ASSERT(req); + ASSERT(status == 0); +} + + +TEST_IMPL(loop_alive) { + int r; + ASSERT(!uv_loop_alive(uv_default_loop())); + + /* loops with handles are alive */ + uv_timer_init(uv_default_loop(), &timer_handle); + uv_timer_start(&timer_handle, timer_cb, 100, 0); + ASSERT(uv_loop_alive(uv_default_loop())); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + ASSERT(!uv_loop_alive(uv_default_loop())); + + /* loops with requests are alive */ + r = uv_queue_work(uv_default_loop(), &work_req, work_cb, after_work_cb); + ASSERT(r == 0); + ASSERT(uv_loop_alive(uv_default_loop())); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + ASSERT(!uv_loop_alive(uv_default_loop())); + + return 0; +} diff --git a/external/src/libuv/test/test-loop-close.c b/external/src/libuv/test/test-loop-close.c new file mode 100644 index 0000000..f0f3e62 --- /dev/null +++ b/external/src/libuv/test/test-loop-close.c @@ -0,0 +1,75 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static uv_timer_t timer_handle; + +static void timer_cb(uv_timer_t* handle) { + ASSERT(handle); + uv_stop(handle->loop); +} + + +TEST_IMPL(loop_close) { + int r; + uv_loop_t loop; + + loop.data = &loop; + ASSERT(0 == uv_loop_init(&loop)); + ASSERT(loop.data == (void*) &loop); + + uv_timer_init(&loop, &timer_handle); + uv_timer_start(&timer_handle, timer_cb, 100, 100); + + ASSERT(UV_EBUSY == uv_loop_close(&loop)); + + uv_run(&loop, UV_RUN_DEFAULT); + + uv_close((uv_handle_t*) &timer_handle, NULL); + r = uv_run(&loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(loop.data == (void*) &loop); + ASSERT(0 == uv_loop_close(&loop)); + ASSERT(loop.data == (void*) &loop); + + return 0; +} + +static void loop_instant_close_work_cb(uv_work_t* req) { +} + +static void loop_instant_close_after_work_cb(uv_work_t* req, int status) { +} + +TEST_IMPL(loop_instant_close) { + static uv_loop_t loop; + static uv_work_t req; + ASSERT(0 == uv_loop_init(&loop)); + ASSERT(0 == uv_queue_work(&loop, + &req, + loop_instant_close_work_cb, + loop_instant_close_after_work_cb)); + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-loop-configure.c b/external/src/libuv/test/test-loop-configure.c new file mode 100644 index 0000000..d057c1e --- /dev/null +++ b/external/src/libuv/test/test-loop-configure.c @@ -0,0 +1,38 @@ +/* Copyright (c) 2014, Ben Noordhuis + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static void timer_cb(uv_timer_t* handle) { + uv_close((uv_handle_t*) handle, NULL); +} + + +TEST_IMPL(loop_configure) { + uv_timer_t timer_handle; + uv_loop_t loop; + ASSERT(0 == uv_loop_init(&loop)); +#ifdef _WIN32 + ASSERT(UV_ENOSYS == uv_loop_configure(&loop, UV_LOOP_BLOCK_SIGNAL, 0)); +#else + ASSERT(0 == uv_loop_configure(&loop, UV_LOOP_BLOCK_SIGNAL, SIGPROF)); +#endif + ASSERT(0 == uv_timer_init(&loop, &timer_handle)); + ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 10, 0)); + ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); + ASSERT(0 == uv_loop_close(&loop)); + return 0; +} diff --git a/external/src/libuv/test/test-loop-handles.c b/external/src/libuv/test/test-loop-handles.c new file mode 100644 index 0000000..05cb846 --- /dev/null +++ b/external/src/libuv/test/test-loop-handles.c @@ -0,0 +1,337 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* Tests commented out with XXX are ones that are failing on Linux */ + +/* + * Purpose of this test is to check semantics of starting and stopping + * prepare, check and idle watchers. + * + * - A watcher must be able to safely stop or close itself; + * - Once a watcher is stopped or closed its callback should never be called. + * - If a watcher is closed, it is implicitly stopped and its close_cb should + * be called exactly once. + * - A watcher can safely start and stop other watchers of the same type. + * - Prepare and check watchers are called once per event loop iterations. + * - All active idle watchers are queued when the event loop has no more work + * to do. This is done repeatedly until all idle watchers are inactive. + * - If a watcher starts another watcher of the same type its callback is not + * immediately queued. For check and prepare watchers, that means that if + * a watcher makes another of the same type active, it'll not be called until + * the next event loop iteration. For idle. watchers this means that the + * newly activated idle watcher might not be queued immediately. + * - Prepare, check, idle watchers keep the event loop alive even when they're + * not active. + * + * This is what the test globally does: + * + * - prepare_1 is always active and counts event loop iterations. It also + * creates and starts prepare_2 every other iteration. Finally it verifies + * that no idle watchers are active before polling. + * - prepare_2 is started by prepare_1 every other iteration. It immediately + * stops itself. It verifies that a watcher is not queued immediately + * if created by another watcher of the same type. + * - There's a check watcher that stops the event loop after a certain number + * of iterations. It starts a varying number of idle_1 watchers. + * - Idle_1 watchers stop themselves after being called a few times. All idle_1 + * watchers try to start the idle_2 watcher if it is not already started or + * awaiting its close callback. + * - The idle_2 watcher always exists but immediately closes itself after + * being started by a check_1 watcher. It verifies that a watcher is + * implicitly stopped when closed, and that a watcher can close itself + * safely. + * - There is a repeating timer. It does not keep the event loop alive + * (ev_unref) but makes sure that the loop keeps polling the system for + * events. + */ + + +#include "uv.h" +#include "task.h" + +#include + + +#define IDLE_COUNT 7 +#define ITERATIONS 21 +#define TIMEOUT 100 + + +static uv_prepare_t prepare_1_handle; +static uv_prepare_t prepare_2_handle; + +static uv_check_t check_handle; + +static uv_idle_t idle_1_handles[IDLE_COUNT]; +static uv_idle_t idle_2_handle; + +static uv_timer_t timer_handle; + + +static int loop_iteration = 0; + +static int prepare_1_cb_called = 0; +static int prepare_1_close_cb_called = 0; + +static int prepare_2_cb_called = 0; +static int prepare_2_close_cb_called = 0; + +static int check_cb_called = 0; +static int check_close_cb_called = 0; + +static int idle_1_cb_called = 0; +static int idle_1_close_cb_called = 0; +static int idles_1_active = 0; + +static int idle_2_cb_called = 0; +static int idle_2_close_cb_called = 0; +static int idle_2_cb_started = 0; +static int idle_2_is_active = 0; + + +static void timer_cb(uv_timer_t* handle) { + ASSERT(handle == &timer_handle); +} + + +static void idle_2_close_cb(uv_handle_t* handle) { + fprintf(stderr, "%s", "IDLE_2_CLOSE_CB\n"); + fflush(stderr); + + ASSERT(handle == (uv_handle_t*)&idle_2_handle); + + ASSERT(idle_2_is_active); + + idle_2_close_cb_called++; + idle_2_is_active = 0; +} + + +static void idle_2_cb(uv_idle_t* handle) { + fprintf(stderr, "%s", "IDLE_2_CB\n"); + fflush(stderr); + + ASSERT(handle == &idle_2_handle); + + idle_2_cb_called++; + + uv_close((uv_handle_t*)handle, idle_2_close_cb); +} + + +static void idle_1_cb(uv_idle_t* handle) { + int r; + + fprintf(stderr, "%s", "IDLE_1_CB\n"); + fflush(stderr); + + ASSERT_NOT_NULL(handle); + ASSERT(idles_1_active > 0); + + /* Init idle_2 and make it active */ + if (!idle_2_is_active && !uv_is_closing((uv_handle_t*)&idle_2_handle)) { + r = uv_idle_init(uv_default_loop(), &idle_2_handle); + ASSERT(r == 0); + r = uv_idle_start(&idle_2_handle, idle_2_cb); + ASSERT(r == 0); + idle_2_is_active = 1; + idle_2_cb_started++; + } + + idle_1_cb_called++; + + if (idle_1_cb_called % 5 == 0) { + r = uv_idle_stop((uv_idle_t*)handle); + ASSERT(r == 0); + idles_1_active--; + } +} + + +static void idle_1_close_cb(uv_handle_t* handle) { + fprintf(stderr, "%s", "IDLE_1_CLOSE_CB\n"); + fflush(stderr); + + ASSERT_NOT_NULL(handle); + + idle_1_close_cb_called++; +} + + +static void prepare_1_close_cb(uv_handle_t* handle) { + fprintf(stderr, "%s", "PREPARE_1_CLOSE_CB"); + fflush(stderr); + ASSERT(handle == (uv_handle_t*)&prepare_1_handle); + + prepare_1_close_cb_called++; +} + + +static void check_close_cb(uv_handle_t* handle) { + fprintf(stderr, "%s", "CHECK_CLOSE_CB\n"); + fflush(stderr); + ASSERT(handle == (uv_handle_t*)&check_handle); + + check_close_cb_called++; +} + + +static void prepare_2_close_cb(uv_handle_t* handle) { + fprintf(stderr, "%s", "PREPARE_2_CLOSE_CB\n"); + fflush(stderr); + ASSERT(handle == (uv_handle_t*)&prepare_2_handle); + + prepare_2_close_cb_called++; +} + + +static void check_cb(uv_check_t* handle) { + int i, r; + + fprintf(stderr, "%s", "CHECK_CB\n"); + fflush(stderr); + ASSERT(handle == &check_handle); + + if (loop_iteration < ITERATIONS) { + /* Make some idle watchers active */ + for (i = 0; i < 1 + (loop_iteration % IDLE_COUNT); i++) { + r = uv_idle_start(&idle_1_handles[i], idle_1_cb); + ASSERT(r == 0); + idles_1_active++; + } + + } else { + /* End of the test - close all handles */ + uv_close((uv_handle_t*)&prepare_1_handle, prepare_1_close_cb); + uv_close((uv_handle_t*)&check_handle, check_close_cb); + uv_close((uv_handle_t*)&prepare_2_handle, prepare_2_close_cb); + + for (i = 0; i < IDLE_COUNT; i++) { + uv_close((uv_handle_t*)&idle_1_handles[i], idle_1_close_cb); + } + + /* This handle is closed/recreated every time, close it only if it is + * active. */ + if (idle_2_is_active) { + uv_close((uv_handle_t*)&idle_2_handle, idle_2_close_cb); + } + } + + check_cb_called++; +} + + +static void prepare_2_cb(uv_prepare_t* handle) { + int r; + + fprintf(stderr, "%s", "PREPARE_2_CB\n"); + fflush(stderr); + ASSERT(handle == &prepare_2_handle); + + /* Prepare_2 gets started by prepare_1 when (loop_iteration % 2 == 0), and it + * stops itself immediately. A started watcher is not queued until the next + * round, so when this callback is made (loop_iteration % 2 == 0) cannot be + * true. */ + ASSERT(loop_iteration % 2 != 0); + + r = uv_prepare_stop((uv_prepare_t*)handle); + ASSERT(r == 0); + + prepare_2_cb_called++; +} + + +static void prepare_1_cb(uv_prepare_t* handle) { + int r; + + fprintf(stderr, "%s", "PREPARE_1_CB\n"); + fflush(stderr); + ASSERT(handle == &prepare_1_handle); + + if (loop_iteration % 2 == 0) { + r = uv_prepare_start(&prepare_2_handle, prepare_2_cb); + ASSERT(r == 0); + } + + prepare_1_cb_called++; + loop_iteration++; + + printf("Loop iteration %d of %d.\n", loop_iteration, ITERATIONS); +} + + +TEST_IMPL(loop_handles) { + int i; + int r; + + r = uv_prepare_init(uv_default_loop(), &prepare_1_handle); + ASSERT(r == 0); + r = uv_prepare_start(&prepare_1_handle, prepare_1_cb); + ASSERT(r == 0); + + r = uv_check_init(uv_default_loop(), &check_handle); + ASSERT(r == 0); + r = uv_check_start(&check_handle, check_cb); + ASSERT(r == 0); + + /* initialize only, prepare_2 is started by prepare_1_cb */ + r = uv_prepare_init(uv_default_loop(), &prepare_2_handle); + ASSERT(r == 0); + + for (i = 0; i < IDLE_COUNT; i++) { + /* initialize only, idle_1 handles are started by check_cb */ + r = uv_idle_init(uv_default_loop(), &idle_1_handles[i]); + ASSERT(r == 0); + } + + /* don't init or start idle_2, both is done by idle_1_cb */ + + /* The timer callback is there to keep the event loop polling unref it as it + * is not supposed to keep the loop alive */ + r = uv_timer_init(uv_default_loop(), &timer_handle); + ASSERT(r == 0); + r = uv_timer_start(&timer_handle, timer_cb, TIMEOUT, TIMEOUT); + ASSERT(r == 0); + uv_unref((uv_handle_t*)&timer_handle); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(loop_iteration == ITERATIONS); + + ASSERT(prepare_1_cb_called == ITERATIONS); + ASSERT(prepare_1_close_cb_called == 1); + + ASSERT(prepare_2_cb_called == ITERATIONS / 2); + ASSERT(prepare_2_close_cb_called == 1); + + ASSERT(check_cb_called == ITERATIONS); + ASSERT(check_close_cb_called == 1); + + /* idle_1_cb should be called a lot */ + ASSERT(idle_1_close_cb_called == IDLE_COUNT); + + ASSERT(idle_2_close_cb_called == idle_2_cb_started); + ASSERT(idle_2_is_active == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-loop-stop.c b/external/src/libuv/test/test-loop-stop.c new file mode 100644 index 0000000..14b8c11 --- /dev/null +++ b/external/src/libuv/test/test-loop-stop.c @@ -0,0 +1,71 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static uv_prepare_t prepare_handle; +static uv_timer_t timer_handle; +static int prepare_called = 0; +static int timer_called = 0; +static int num_ticks = 10; + + +static void prepare_cb(uv_prepare_t* handle) { + ASSERT(handle == &prepare_handle); + prepare_called++; + if (prepare_called == num_ticks) + uv_prepare_stop(handle); +} + + +static void timer_cb(uv_timer_t* handle) { + ASSERT(handle == &timer_handle); + timer_called++; + if (timer_called == 1) + uv_stop(uv_default_loop()); + else if (timer_called == num_ticks) + uv_timer_stop(handle); +} + + +TEST_IMPL(loop_stop) { + int r; + uv_prepare_init(uv_default_loop(), &prepare_handle); + uv_prepare_start(&prepare_handle, prepare_cb); + uv_timer_init(uv_default_loop(), &timer_handle); + uv_timer_start(&timer_handle, timer_cb, 100, 100); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r != 0); + ASSERT(timer_called == 1); + + r = uv_run(uv_default_loop(), UV_RUN_NOWAIT); + ASSERT(r != 0); + ASSERT(prepare_called > 1); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + ASSERT(timer_called == 10); + ASSERT(prepare_called == 10); + + return 0; +} diff --git a/external/src/libuv/test/test-loop-time.c b/external/src/libuv/test/test-loop-time.c new file mode 100644 index 0000000..a2db42c --- /dev/null +++ b/external/src/libuv/test/test-loop-time.c @@ -0,0 +1,63 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + + +TEST_IMPL(loop_update_time) { + uint64_t start; + + start = uv_now(uv_default_loop()); + while (uv_now(uv_default_loop()) - start < 1000) + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_NOWAIT)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +static void cb(uv_timer_t* timer) { + uv_close((uv_handle_t*)timer, NULL); +} + +TEST_IMPL(loop_backend_timeout) { + uv_loop_t *loop = uv_default_loop(); + uv_timer_t timer; + int r; + + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + + ASSERT(!uv_loop_alive(loop)); + ASSERT(uv_backend_timeout(loop) == 0); + + r = uv_timer_start(&timer, cb, 1000, 0); /* 1 sec */ + ASSERT(r == 0); + ASSERT(uv_backend_timeout(loop) > 100); /* 0.1 sec */ + ASSERT(uv_backend_timeout(loop) <= 1000); /* 1 sec */ + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + ASSERT(uv_backend_timeout(loop) == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-metrics.c b/external/src/libuv/test/test-metrics.c new file mode 100644 index 0000000..f527494 --- /dev/null +++ b/external/src/libuv/test/test-metrics.c @@ -0,0 +1,135 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include /* memset */ + +#define UV_NS_TO_MS 1000000 + + +static void timer_spin_cb(uv_timer_t* handle) { + uint64_t t; + + (*(int*) handle->data)++; + t = uv_hrtime(); + /* Spin for 500 ms to spin loop time out of the delta check. */ + while (uv_hrtime() - t < 600 * UV_NS_TO_MS) { } +} + + +TEST_IMPL(metrics_idle_time) { + const uint64_t timeout = 1000; + uv_timer_t timer; + uint64_t idle_time; + int cntr; + + cntr = 0; + timer.data = &cntr; + + ASSERT_EQ(0, uv_loop_configure(uv_default_loop(), UV_METRICS_IDLE_TIME)); + ASSERT_EQ(0, uv_timer_init(uv_default_loop(), &timer)); + ASSERT_EQ(0, uv_timer_start(&timer, timer_spin_cb, timeout, 0)); + + ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT_GT(cntr, 0); + + idle_time = uv_metrics_idle_time(uv_default_loop()); + + /* Permissive check that the idle time matches within the timeout ±500 ms. */ + ASSERT((idle_time <= (timeout + 500) * UV_NS_TO_MS) && + (idle_time >= (timeout - 500) * UV_NS_TO_MS)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void metrics_routine_cb(void* arg) { + const uint64_t timeout = 1000; + uv_loop_t loop; + uv_timer_t timer; + uint64_t idle_time; + int cntr; + + cntr = 0; + timer.data = &cntr; + + ASSERT_EQ(0, uv_loop_init(&loop)); + ASSERT_EQ(0, uv_loop_configure(&loop, UV_METRICS_IDLE_TIME)); + ASSERT_EQ(0, uv_timer_init(&loop, &timer)); + ASSERT_EQ(0, uv_timer_start(&timer, timer_spin_cb, timeout, 0)); + + ASSERT_EQ(0, uv_run(&loop, UV_RUN_DEFAULT)); + ASSERT_GT(cntr, 0); + + idle_time = uv_metrics_idle_time(&loop); + + /* Only checking that idle time is greater than the lower bound since there + * may have been thread contention, causing the event loop to be delayed in + * the idle phase longer than expected. + */ + ASSERT_GE(idle_time, (timeout - 500) * UV_NS_TO_MS); + + close_loop(&loop); + ASSERT_EQ(0, uv_loop_close(&loop)); +} + + +TEST_IMPL(metrics_idle_time_thread) { + uv_thread_t threads[5]; + int i; + + for (i = 0; i < 5; i++) { + ASSERT_EQ(0, uv_thread_create(&threads[i], metrics_routine_cb, NULL)); + } + + for (i = 0; i < 5; i++) { + uv_thread_join(&threads[i]); + } + + return 0; +} + + +static void timer_noop_cb(uv_timer_t* handle) { + (*(int*) handle->data)++; +} + + +TEST_IMPL(metrics_idle_time_zero) { + uv_timer_t timer; + int cntr; + + cntr = 0; + timer.data = &cntr; + ASSERT_EQ(0, uv_loop_configure(uv_default_loop(), UV_METRICS_IDLE_TIME)); + ASSERT_EQ(0, uv_timer_init(uv_default_loop(), &timer)); + ASSERT_EQ(0, uv_timer_start(&timer, timer_noop_cb, 0, 0)); + + ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + ASSERT_GT(cntr, 0); + ASSERT_EQ(0, uv_metrics_idle_time(uv_default_loop())); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-multiple-listen.c b/external/src/libuv/test/test-multiple-listen.c new file mode 100644 index 0000000..0b28514 --- /dev/null +++ b/external/src/libuv/test/test-multiple-listen.c @@ -0,0 +1,109 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + +static int connection_cb_called = 0; +static int close_cb_called = 0; +static int connect_cb_called = 0; +static uv_tcp_t server; +static uv_tcp_t client; + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +static void connection_cb(uv_stream_t* tcp, int status) { + ASSERT(status == 0); + uv_close((uv_handle_t*)&server, close_cb); + connection_cb_called++; +} + + +static void start_server(void) { + struct sockaddr_in addr; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_listen((uv_stream_t*)&server, 128, connection_cb); + ASSERT(r == 0); + + r = uv_listen((uv_stream_t*)&server, 128, connection_cb); + ASSERT(r == 0); +} + + +static void connect_cb(uv_connect_t* req, int status) { + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + free(req); + uv_close((uv_handle_t*)&client, close_cb); + connect_cb_called++; +} + + +static void client_connect(void) { + struct sockaddr_in addr; + uv_connect_t* connect_req = malloc(sizeof *connect_req); + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + ASSERT_NOT_NULL(connect_req); + + r = uv_tcp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + r = uv_tcp_connect(connect_req, + &client, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT(r == 0); +} + + + +TEST_IMPL(multiple_listen) { + start_server(); + + client_connect(); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(connection_cb_called == 1); + ASSERT(connect_cb_called == 1); + ASSERT(close_cb_called == 2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-mutexes.c b/external/src/libuv/test/test-mutexes.c new file mode 100644 index 0000000..975222c --- /dev/null +++ b/external/src/libuv/test/test-mutexes.c @@ -0,0 +1,182 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +static uv_cond_t condvar; +static uv_mutex_t mutex; +static uv_rwlock_t rwlock; +static int step; + +/* The mutex and rwlock tests are really poor. + * They're very basic sanity checks and nothing more. + * Apologies if that rhymes. + */ + +TEST_IMPL(thread_mutex) { + uv_mutex_t mutex; + int r; + + r = uv_mutex_init(&mutex); + ASSERT(r == 0); + + uv_mutex_lock(&mutex); + uv_mutex_unlock(&mutex); + uv_mutex_destroy(&mutex); + + return 0; +} + + +TEST_IMPL(thread_mutex_recursive) { + uv_mutex_t mutex; + int r; + + r = uv_mutex_init_recursive(&mutex); + ASSERT(r == 0); + + uv_mutex_lock(&mutex); + uv_mutex_lock(&mutex); + ASSERT(0 == uv_mutex_trylock(&mutex)); + + uv_mutex_unlock(&mutex); + uv_mutex_unlock(&mutex); + uv_mutex_unlock(&mutex); + uv_mutex_destroy(&mutex); + + return 0; +} + + +TEST_IMPL(thread_rwlock) { + uv_rwlock_t rwlock; + int r; + + r = uv_rwlock_init(&rwlock); + ASSERT(r == 0); + + uv_rwlock_rdlock(&rwlock); + uv_rwlock_rdunlock(&rwlock); + uv_rwlock_wrlock(&rwlock); + uv_rwlock_wrunlock(&rwlock); + uv_rwlock_destroy(&rwlock); + + return 0; +} + + +/* Call when holding |mutex|. */ +static void synchronize_nowait(void) { + step += 1; + uv_cond_signal(&condvar); +} + + +/* Call when holding |mutex|. */ +static void synchronize(void) { + int current; + + synchronize_nowait(); + /* Wait for the other thread. Guard against spurious wakeups. */ + for (current = step; current == step; uv_cond_wait(&condvar, &mutex)); + ASSERT(step == current + 1); +} + + +static void thread_rwlock_trylock_peer(void* unused) { + (void) &unused; + + uv_mutex_lock(&mutex); + + /* Write lock held by other thread. */ + ASSERT(UV_EBUSY == uv_rwlock_tryrdlock(&rwlock)); + ASSERT(UV_EBUSY == uv_rwlock_trywrlock(&rwlock)); + synchronize(); + + /* Read lock held by other thread. */ + ASSERT(0 == uv_rwlock_tryrdlock(&rwlock)); + uv_rwlock_rdunlock(&rwlock); + ASSERT(UV_EBUSY == uv_rwlock_trywrlock(&rwlock)); + synchronize(); + + /* Acquire write lock. */ + ASSERT(0 == uv_rwlock_trywrlock(&rwlock)); + synchronize(); + + /* Release write lock and acquire read lock. */ + uv_rwlock_wrunlock(&rwlock); + ASSERT(0 == uv_rwlock_tryrdlock(&rwlock)); + synchronize(); + + uv_rwlock_rdunlock(&rwlock); + synchronize_nowait(); /* Signal main thread we're going away. */ + uv_mutex_unlock(&mutex); +} + + +TEST_IMPL(thread_rwlock_trylock) { + uv_thread_t thread; + + ASSERT(0 == uv_cond_init(&condvar)); + ASSERT(0 == uv_mutex_init(&mutex)); + ASSERT(0 == uv_rwlock_init(&rwlock)); + + uv_mutex_lock(&mutex); + ASSERT(0 == uv_thread_create(&thread, thread_rwlock_trylock_peer, NULL)); + + /* Hold write lock. */ + ASSERT(0 == uv_rwlock_trywrlock(&rwlock)); + synchronize(); /* Releases the mutex to the other thread. */ + + /* Release write lock and acquire read lock. Pthreads doesn't support + * the notion of upgrading or downgrading rwlocks, so neither do we. + */ + uv_rwlock_wrunlock(&rwlock); + ASSERT(0 == uv_rwlock_tryrdlock(&rwlock)); + synchronize(); + + /* Release read lock. */ + uv_rwlock_rdunlock(&rwlock); + synchronize(); + + /* Write lock held by other thread. */ + ASSERT(UV_EBUSY == uv_rwlock_tryrdlock(&rwlock)); + ASSERT(UV_EBUSY == uv_rwlock_trywrlock(&rwlock)); + synchronize(); + + /* Read lock held by other thread. */ + ASSERT(0 == uv_rwlock_tryrdlock(&rwlock)); + uv_rwlock_rdunlock(&rwlock); + ASSERT(UV_EBUSY == uv_rwlock_trywrlock(&rwlock)); + synchronize(); + + ASSERT(0 == uv_thread_join(&thread)); + uv_rwlock_destroy(&rwlock); + uv_mutex_unlock(&mutex); + uv_mutex_destroy(&mutex); + uv_cond_destroy(&condvar); + + return 0; +} diff --git a/external/src/libuv/test/test-not-readable-nor-writable-on-read-error.c b/external/src/libuv/test/test-not-readable-nor-writable-on-read-error.c new file mode 100644 index 0000000..ae951e3 --- /dev/null +++ b/external/src/libuv/test/test-not-readable-nor-writable-on-read-error.c @@ -0,0 +1,104 @@ +/* Copyright the libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static uv_loop_t loop; +static uv_tcp_t tcp_client; +static uv_connect_t connect_req; +static uv_write_t write_req; +static char reset_me_cmd[] = {'Q', 'S', 'H'}; + +static int connect_cb_called; +static int read_cb_called; +static int write_cb_called; +static int close_cb_called; + +static void write_cb(uv_write_t* req, int status) { + write_cb_called++; + ASSERT(status == 0); +} + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[64]; + buf->base = slab; + buf->len = sizeof(slab); +} + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + +static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { + read_cb_called++; + + ASSERT((nread < 0) && (nread != UV_EOF)); + ASSERT(0 == uv_is_writable(handle)); + ASSERT(0 == uv_is_readable(handle)); + + uv_close((uv_handle_t*) handle, close_cb); +} + +static void connect_cb(uv_connect_t* req, int status) { + int r; + uv_buf_t reset_me; + + connect_cb_called++; + ASSERT(status == 0); + + r = uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb); + ASSERT(r == 0); + + reset_me = uv_buf_init(reset_me_cmd, sizeof(reset_me_cmd)); + + r = uv_write(&write_req, + (uv_stream_t*) &tcp_client, + &reset_me, + 1, + write_cb); + + ASSERT(r == 0); +} + +TEST_IMPL(not_readable_nor_writable_on_read_error) { + struct sockaddr_in sa; + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa)); + ASSERT(0 == uv_loop_init(&loop)); + ASSERT(0 == uv_tcp_init(&loop, &tcp_client)); + + ASSERT(0 == uv_tcp_connect(&connect_req, + &tcp_client, + (const struct sockaddr*) &sa, + connect_cb)); + + ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); + + ASSERT(connect_cb_called == 1); + ASSERT(read_cb_called == 1); + ASSERT(write_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-not-readable-on-eof.c b/external/src/libuv/test/test-not-readable-on-eof.c new file mode 100644 index 0000000..2bb5f4e --- /dev/null +++ b/external/src/libuv/test/test-not-readable-on-eof.c @@ -0,0 +1,103 @@ +/* Copyright the libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static uv_loop_t loop; +static uv_tcp_t tcp_client; +static uv_connect_t connect_req; +static uv_write_t write_req; +static char close_me_cmd[] = {'Q', 'S'}; + +static int connect_cb_called; +static int read_cb_called; +static int write_cb_called; +static int close_cb_called; + +static void write_cb(uv_write_t* req, int status) { + write_cb_called++; + ASSERT(status == 0); +} + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[64]; + buf->base = slab; + buf->len = sizeof(slab); +} + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + +static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { + read_cb_called++; + + ASSERT(nread == UV_EOF); + ASSERT(0 == uv_is_readable(handle)); + + uv_close((uv_handle_t*) handle, close_cb); +} + +static void connect_cb(uv_connect_t* req, int status) { + int r; + uv_buf_t close_me; + + connect_cb_called++; + ASSERT(status == 0); + + r = uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb); + ASSERT(r == 0); + + close_me = uv_buf_init(close_me_cmd, sizeof(close_me_cmd)); + + r = uv_write(&write_req, + (uv_stream_t*) &tcp_client, + &close_me, + 1, + write_cb); + + ASSERT(r == 0); +} + +TEST_IMPL(not_readable_on_eof) { + struct sockaddr_in sa; + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa)); + ASSERT(0 == uv_loop_init(&loop)); + ASSERT(0 == uv_tcp_init(&loop, &tcp_client)); + + ASSERT(0 == uv_tcp_connect(&connect_req, + &tcp_client, + (const struct sockaddr*) &sa, + connect_cb)); + + ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); + + ASSERT(connect_cb_called == 1); + ASSERT(read_cb_called == 1); + ASSERT(write_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-not-writable-after-shutdown.c b/external/src/libuv/test/test-not-writable-after-shutdown.c new file mode 100644 index 0000000..9cd9370 --- /dev/null +++ b/external/src/libuv/test/test-not-writable-after-shutdown.c @@ -0,0 +1,69 @@ +/* Copyright the libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static uv_shutdown_t shutdown_req; + +static void close_cb(uv_handle_t* handle) { + +} + +static void shutdown_cb(uv_shutdown_t* req, int status) { + uv_close((uv_handle_t*) req->handle, close_cb); +} + +static void connect_cb(uv_connect_t* req, int status) { + int r; + ASSERT(status == 0); + + r = uv_shutdown(&shutdown_req, req->handle, shutdown_cb); + ASSERT(r == 0); + + ASSERT(0 == uv_is_writable(req->handle)); +} + +TEST_IMPL(not_writable_after_shutdown) { + int r; + struct sockaddr_in addr; + uv_loop_t* loop; + uv_tcp_t socket; + uv_connect_t connect_req; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + loop = uv_default_loop(); + + r = uv_tcp_init(loop, &socket); + ASSERT(r == 0); + + r = uv_tcp_connect(&connect_req, + &socket, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-osx-select.c b/external/src/libuv/test/test-osx-select.c new file mode 100644 index 0000000..a0afda9 --- /dev/null +++ b/external/src/libuv/test/test-osx-select.c @@ -0,0 +1,140 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#ifdef __APPLE__ + +#include +#include + +static int read_count; + + +static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + static char slab[1024]; + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { + fprintf(stdout, "got data %d\n", ++read_count); + fflush(stdout); + + if (read_count == 3) + uv_close((uv_handle_t*) stream, NULL); +} + + +TEST_IMPL(osx_select) { + int r; + int fd; + size_t i; + size_t len; + const char* str; + uv_tty_t tty; + + fd = open("/dev/tty", O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Cannot open /dev/tty as read-only: %s\n", strerror(errno)); + fflush(stderr); + return TEST_SKIP; + } + + r = uv_tty_init(uv_default_loop(), &tty, fd, 1); + ASSERT(r == 0); + + uv_read_start((uv_stream_t*) &tty, alloc_cb, read_cb); + + /* Emulate user-input */ + str = "got some input\n" + "with a couple of lines\n" + "feel pretty happy\n"; + for (i = 0, len = strlen(str); i < len; i++) { + r = ioctl(fd, TIOCSTI, str + i); + ASSERT(r == 0); + } + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(read_count == 3); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(osx_select_many_fds) { + int r; + int fd; + size_t i; + size_t len; + const char* str; + struct sockaddr_in addr; + uv_tty_t tty; + uv_tcp_t tcps[1500]; + + TEST_FILE_LIMIT(ARRAY_SIZE(tcps) + 100); + + r = uv_ip4_addr("127.0.0.1", 0, &addr); + ASSERT(r == 0); + + for (i = 0; i < ARRAY_SIZE(tcps); i++) { + r = uv_tcp_init(uv_default_loop(), &tcps[i]); + ASSERT(r == 0); + r = uv_tcp_bind(&tcps[i], (const struct sockaddr *) &addr, 0); + ASSERT(r == 0); + uv_unref((uv_handle_t*) &tcps[i]); + } + + fd = open("/dev/tty", O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Cannot open /dev/tty as read-only: %s\n", strerror(errno)); + fflush(stderr); + return TEST_SKIP; + } + + r = uv_tty_init(uv_default_loop(), &tty, fd, 1); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*) &tty, alloc_cb, read_cb); + ASSERT(r == 0); + + /* Emulate user-input */ + str = "got some input\n" + "with a couple of lines\n" + "feel pretty happy\n"; + for (i = 0, len = strlen(str); i < len; i++) { + r = ioctl(fd, TIOCSTI, str + i); + ASSERT(r == 0); + } + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(read_count == 3); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#endif /* __APPLE__ */ diff --git a/external/src/libuv/test/test-pass-always.c b/external/src/libuv/test/test-pass-always.c new file mode 100644 index 0000000..4fb58ff --- /dev/null +++ b/external/src/libuv/test/test-pass-always.c @@ -0,0 +1,28 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" + + +TEST_IMPL(pass_always) { + /* This test always passes. It is used to test the test runner. */ + return 0; +} diff --git a/external/src/libuv/test/test-ping-pong.c b/external/src/libuv/test/test-ping-pong.c new file mode 100644 index 0000000..4a26e4d --- /dev/null +++ b/external/src/libuv/test/test-ping-pong.c @@ -0,0 +1,436 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include /* strlen */ + +static int completed_pingers = 0; + +#if defined(__CYGWIN__) || defined(__MSYS__) || defined(__MVS__) +#define NUM_PINGS 100 /* fewer pings to avoid timeout */ +#else +#define NUM_PINGS 1000 +#endif + +static char PING[] = "PING\n"; +static char PONG[] = "PONG\n"; +static int pinger_on_connect_count; + + +typedef struct { + int vectored_writes; + unsigned pongs; + unsigned state; + union { + uv_tcp_t tcp; + uv_pipe_t pipe; + } stream; + uv_connect_t connect_req; + char* pong; +} pinger_t; + + +static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + buf->base = malloc(size); + buf->len = size; +} + + +static void ponger_on_close(uv_handle_t* handle) { + if (handle->data) + free(handle->data); + else + free(handle); +} + + +static void pinger_on_close(uv_handle_t* handle) { + pinger_t* pinger = (pinger_t*) handle->data; + + ASSERT_EQ(NUM_PINGS, pinger->pongs); + + if (handle == (uv_handle_t*) &pinger->stream.tcp) { + free(pinger); /* also frees handle */ + } else { + uv_close((uv_handle_t*) &pinger->stream.tcp, ponger_on_close); + free(handle); + } + + completed_pingers++; +} + + +static void pinger_after_write(uv_write_t* req, int status) { + ASSERT_EQ(status, 0); + free(req); +} + + +static void pinger_write_ping(pinger_t* pinger) { + uv_stream_t* stream; + uv_write_t* req; + uv_buf_t bufs[sizeof PING - 1]; + int i, nbufs; + + stream = (uv_stream_t*) &pinger->stream.tcp; + + if (!pinger->vectored_writes) { + /* Write a single buffer. */ + nbufs = 1; + bufs[0] = uv_buf_init(PING, sizeof PING - 1); + } else { + /* Write multiple buffers, each with one byte in them. */ + nbufs = sizeof PING - 1; + for (i = 0; i < nbufs; i++) { + bufs[i] = uv_buf_init(&PING[i], 1); + } + } + + req = malloc(sizeof(*req)); + ASSERT_NOT_NULL(req); + ASSERT_EQ(0, uv_write(req, stream, bufs, nbufs, pinger_after_write)); + + puts("PING"); +} + + +static void pinger_read_cb(uv_stream_t* stream, + ssize_t nread, + const uv_buf_t* buf) { + ssize_t i; + pinger_t* pinger; + + pinger = (pinger_t*) stream->data; + + if (nread < 0) { + ASSERT_EQ(nread, UV_EOF); + + puts("got EOF"); + free(buf->base); + + uv_close((uv_handle_t*) stream, pinger_on_close); + + return; + } + + /* Now we count the pongs */ + for (i = 0; i < nread; i++) { + ASSERT_EQ(buf->base[i], pinger->pong[pinger->state]); + pinger->state = (pinger->state + 1) % strlen(pinger->pong); + + if (pinger->state != 0) + continue; + + printf("PONG %d\n", pinger->pongs); + pinger->pongs++; + + if (pinger->pongs < NUM_PINGS) { + pinger_write_ping(pinger); + } else { + uv_close((uv_handle_t*) stream, pinger_on_close); + break; + } + } + + free(buf->base); +} + + +static void ponger_read_cb(uv_stream_t* stream, + ssize_t nread, + const uv_buf_t* buf) { + uv_buf_t writebuf; + uv_write_t* req; + int i; + + if (nread < 0) { + ASSERT_EQ(nread, UV_EOF); + + puts("got EOF"); + free(buf->base); + + uv_close((uv_handle_t*) stream, ponger_on_close); + + return; + } + + /* Echo back */ + for (i = 0; i < nread; i++) { + if (buf->base[i] == 'I') + buf->base[i] = 'O'; + } + + writebuf = uv_buf_init(buf->base, nread); + req = malloc(sizeof(*req)); + ASSERT_NOT_NULL(req); + ASSERT_EQ(0, uv_write(req, stream, &writebuf, 1, pinger_after_write)); +} + + +static void pinger_on_connect(uv_connect_t* req, int status) { + pinger_t* pinger = (pinger_t*) req->handle->data; + + pinger_on_connect_count++; + + ASSERT_EQ(status, 0); + + ASSERT_EQ(1, uv_is_readable(req->handle)); + ASSERT_EQ(1, uv_is_writable(req->handle)); + ASSERT_EQ(0, uv_is_closing((uv_handle_t *) req->handle)); + + pinger_write_ping(pinger); + + ASSERT_EQ(0, uv_read_start((uv_stream_t*) req->handle, + alloc_cb, + pinger_read_cb)); +} + + +/* same ping-pong test, but using IPv6 connection */ +static void tcp_pinger_v6_new(int vectored_writes) { + int r; + struct sockaddr_in6 server_addr; + pinger_t* pinger; + + + ASSERT_EQ(0, uv_ip6_addr("::1", TEST_PORT, &server_addr)); + pinger = malloc(sizeof(*pinger)); + ASSERT_NOT_NULL(pinger); + pinger->vectored_writes = vectored_writes; + pinger->state = 0; + pinger->pongs = 0; + pinger->pong = PING; + + /* Try to connect to the server and do NUM_PINGS ping-pongs. */ + r = uv_tcp_init(uv_default_loop(), &pinger->stream.tcp); + pinger->stream.tcp.data = pinger; + ASSERT_EQ(0, r); + + /* We are never doing multiple reads/connects at a time anyway, so these + * handles can be pre-initialized. */ + r = uv_tcp_connect(&pinger->connect_req, + &pinger->stream.tcp, + (const struct sockaddr*) &server_addr, + pinger_on_connect); + ASSERT_EQ(0, r); + + /* Synchronous connect callbacks are not allowed. */ + ASSERT_EQ(pinger_on_connect_count, 0); +} + + +static void tcp_pinger_new(int vectored_writes) { + int r; + struct sockaddr_in server_addr; + pinger_t* pinger; + + ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); + pinger = malloc(sizeof(*pinger)); + ASSERT_NOT_NULL(pinger); + pinger->vectored_writes = vectored_writes; + pinger->state = 0; + pinger->pongs = 0; + pinger->pong = PING; + + /* Try to connect to the server and do NUM_PINGS ping-pongs. */ + r = uv_tcp_init(uv_default_loop(), &pinger->stream.tcp); + pinger->stream.tcp.data = pinger; + ASSERT_EQ(0, r); + + /* We are never doing multiple reads/connects at a time anyway, so these + * handles can be pre-initialized. */ + r = uv_tcp_connect(&pinger->connect_req, + &pinger->stream.tcp, + (const struct sockaddr*) &server_addr, + pinger_on_connect); + ASSERT_EQ(0, r); + + /* Synchronous connect callbacks are not allowed. */ + ASSERT_EQ(pinger_on_connect_count, 0); +} + + +static void pipe_pinger_new(int vectored_writes) { + int r; + pinger_t* pinger; + + pinger = malloc(sizeof(*pinger)); + ASSERT_NOT_NULL(pinger); + pinger->vectored_writes = vectored_writes; + pinger->state = 0; + pinger->pongs = 0; + pinger->pong = PING; + + /* Try to connect to the server and do NUM_PINGS ping-pongs. */ + r = uv_pipe_init(uv_default_loop(), &pinger->stream.pipe, 0); + pinger->stream.pipe.data = pinger; + ASSERT_EQ(0, r); + + /* We are never doing multiple reads/connects at a time anyway, so these + * handles can be pre-initialized. */ + uv_pipe_connect(&pinger->connect_req, &pinger->stream.pipe, TEST_PIPENAME, + pinger_on_connect); + + /* Synchronous connect callbacks are not allowed. */ + ASSERT_EQ(pinger_on_connect_count, 0); +} + + +static void socketpair_pinger_new(int vectored_writes) { + pinger_t* pinger; + uv_os_sock_t fds[2]; + uv_tcp_t* ponger; + + pinger = malloc(sizeof(*pinger)); + ASSERT_NOT_NULL(pinger); + pinger->vectored_writes = vectored_writes; + pinger->state = 0; + pinger->pongs = 0; + pinger->pong = PONG; + + /* Try to make a socketpair and do NUM_PINGS ping-pongs. */ + (void)uv_default_loop(); /* ensure WSAStartup has been performed */ + ASSERT_EQ(0, uv_socketpair(SOCK_STREAM, 0, fds, UV_NONBLOCK_PIPE, UV_NONBLOCK_PIPE)); +#ifndef _WIN32 + /* On Windows, this is actually a UV_TCP, but libuv doesn't detect that. */ + ASSERT_EQ(uv_guess_handle((uv_file) fds[0]), UV_NAMED_PIPE); + ASSERT_EQ(uv_guess_handle((uv_file) fds[1]), UV_NAMED_PIPE); +#endif + + ASSERT_EQ(0, uv_tcp_init(uv_default_loop(), &pinger->stream.tcp)); + pinger->stream.pipe.data = pinger; + ASSERT_EQ(0, uv_tcp_open(&pinger->stream.tcp, fds[1])); + + ponger = malloc(sizeof(*ponger)); + ASSERT_NOT_NULL(ponger); + ponger->data = NULL; + ASSERT_EQ(0, uv_tcp_init(uv_default_loop(), ponger)); + ASSERT_EQ(0, uv_tcp_open(ponger, fds[0])); + + pinger_write_ping(pinger); + + ASSERT_EQ(0, uv_read_start((uv_stream_t*) &pinger->stream.tcp, + alloc_cb, + pinger_read_cb)); + ASSERT_EQ(0, uv_read_start((uv_stream_t*) ponger, + alloc_cb, + ponger_read_cb)); +} + + +static void pipe2_pinger_new(int vectored_writes) { + uv_file fds[2]; + pinger_t* pinger; + uv_pipe_t* ponger; + + /* Try to make a pipe and do NUM_PINGS pings. */ + ASSERT_EQ(0, uv_pipe(fds, UV_NONBLOCK_PIPE, UV_NONBLOCK_PIPE)); + ASSERT_EQ(uv_guess_handle(fds[0]), UV_NAMED_PIPE); + ASSERT_EQ(uv_guess_handle(fds[1]), UV_NAMED_PIPE); + + ponger = malloc(sizeof(*ponger)); + ASSERT_NOT_NULL(ponger); + ASSERT_EQ(0, uv_pipe_init(uv_default_loop(), ponger, 0)); + ASSERT_EQ(0, uv_pipe_open(ponger, fds[0])); + + pinger = malloc(sizeof(*pinger)); + ASSERT_NOT_NULL(pinger); + pinger->vectored_writes = vectored_writes; + pinger->state = 0; + pinger->pongs = 0; + pinger->pong = PING; + ASSERT_EQ(0, uv_pipe_init(uv_default_loop(), &pinger->stream.pipe, 0)); + ASSERT_EQ(0, uv_pipe_open(&pinger->stream.pipe, fds[1])); + pinger->stream.pipe.data = pinger; /* record for close_cb */ + ponger->data = pinger; /* record for read_cb */ + + pinger_write_ping(pinger); + + ASSERT_EQ(0, uv_read_start((uv_stream_t*) ponger, alloc_cb, pinger_read_cb)); +} + +static int run_ping_pong_test(void) { + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT_EQ(completed_pingers, 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_ping_pong) { + tcp_pinger_new(0); + run_ping_pong_test(); + + completed_pingers = 0; + socketpair_pinger_new(0); + return run_ping_pong_test(); +} + + +TEST_IMPL(tcp_ping_pong_vec) { + tcp_pinger_new(1); + run_ping_pong_test(); + + completed_pingers = 0; + socketpair_pinger_new(1); + return run_ping_pong_test(); +} + + +TEST_IMPL(tcp6_ping_pong) { + if (!can_ipv6()) + RETURN_SKIP("IPv6 not supported"); + tcp_pinger_v6_new(0); + return run_ping_pong_test(); +} + + +TEST_IMPL(tcp6_ping_pong_vec) { + if (!can_ipv6()) + RETURN_SKIP("IPv6 not supported"); + tcp_pinger_v6_new(1); + return run_ping_pong_test(); +} + + +TEST_IMPL(pipe_ping_pong) { + pipe_pinger_new(0); + run_ping_pong_test(); + + completed_pingers = 0; + pipe2_pinger_new(0); + return run_ping_pong_test(); +} + + +TEST_IMPL(pipe_ping_pong_vec) { + pipe_pinger_new(1); + run_ping_pong_test(); + + completed_pingers = 0; + pipe2_pinger_new(1); + return run_ping_pong_test(); +} diff --git a/external/src/libuv/test/test-pipe-bind-error.c b/external/src/libuv/test/test-pipe-bind-error.c new file mode 100644 index 0000000..ce35052 --- /dev/null +++ b/external/src/libuv/test/test-pipe-bind-error.c @@ -0,0 +1,139 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + + +#ifdef _WIN32 +# define BAD_PIPENAME "bad-pipe" +#else +# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there" +#endif + + +static int close_cb_called = 0; + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +TEST_IMPL(pipe_bind_error_addrinuse) { + uv_pipe_t server1, server2; + int r; + + r = uv_pipe_init(uv_default_loop(), &server1, 0); + ASSERT(r == 0); + r = uv_pipe_bind(&server1, TEST_PIPENAME); + ASSERT(r == 0); + + r = uv_pipe_init(uv_default_loop(), &server2, 0); + ASSERT(r == 0); + r = uv_pipe_bind(&server2, TEST_PIPENAME); + ASSERT(r == UV_EADDRINUSE); + + r = uv_listen((uv_stream_t*)&server1, SOMAXCONN, NULL); + ASSERT(r == 0); + r = uv_listen((uv_stream_t*)&server2, SOMAXCONN, NULL); + ASSERT(r == UV_EINVAL); + + uv_close((uv_handle_t*)&server1, close_cb); + uv_close((uv_handle_t*)&server2, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(pipe_bind_error_addrnotavail) { + uv_pipe_t server; + int r; + + r = uv_pipe_init(uv_default_loop(), &server, 0); + ASSERT(r == 0); + + r = uv_pipe_bind(&server, BAD_PIPENAME); + ASSERT(r == UV_EACCES); + + uv_close((uv_handle_t*)&server, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(pipe_bind_error_inval) { + uv_pipe_t server; + int r; + + r = uv_pipe_init(uv_default_loop(), &server, 0); + ASSERT(r == 0); + r = uv_pipe_bind(&server, TEST_PIPENAME); + ASSERT(r == 0); + r = uv_pipe_bind(&server, TEST_PIPENAME_2); + ASSERT(r == UV_EINVAL); + + uv_close((uv_handle_t*)&server, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(pipe_listen_without_bind) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif + uv_pipe_t server; + int r; + + r = uv_pipe_init(uv_default_loop(), &server, 0); + ASSERT(r == 0); + + r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL); + ASSERT(r == UV_EINVAL); + + uv_close((uv_handle_t*)&server, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-pipe-close-stdout-read-stdin.c b/external/src/libuv/test/test-pipe-close-stdout-read-stdin.c new file mode 100644 index 0000000..126be2c --- /dev/null +++ b/external/src/libuv/test/test-pipe-close-stdout-read-stdin.c @@ -0,0 +1,112 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _WIN32 + +#include +#include +#include +#include + +#include "uv.h" +#include "task.h" + +void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t* buf) +{ + static char buffer[1024]; + + buf->base = buffer; + buf->len = sizeof(buffer); +} + +void read_stdin(uv_stream_t *stream, ssize_t nread, const uv_buf_t* buf) +{ + if (nread < 0) { + uv_close((uv_handle_t*)stream, NULL); + return; + } +} + +/* + * This test is a reproduction of joyent/libuv#1419 . + */ +TEST_IMPL(pipe_close_stdout_read_stdin) { + int r = -1; + int pid; + int fd[2]; + int status; + char buf; + uv_pipe_t stdin_pipe; + + r = pipe(fd); + ASSERT(r == 0); + + if ((pid = fork()) == 0) { + /* + * Make the read side of the pipe our stdin. + * The write side will be closed by the parent process. + */ + close(fd[1]); + /* block until write end of pipe is closed */ + r = read(fd[0], &buf, 1); + ASSERT(-1 <= r && r <= 1); + close(0); + r = dup(fd[0]); + ASSERT(r != -1); + + /* Create a stream that reads from the pipe. */ + r = uv_pipe_init(uv_default_loop(), (uv_pipe_t *)&stdin_pipe, 0); + ASSERT(r == 0); + + r = uv_pipe_open((uv_pipe_t *)&stdin_pipe, 0); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t *)&stdin_pipe, alloc_buffer, read_stdin); + ASSERT(r == 0); + + /* + * Because the other end of the pipe was closed, there should + * be no event left to process after one run of the event loop. + * Otherwise, it means that events were not processed correctly. + */ + ASSERT(uv_run(uv_default_loop(), UV_RUN_NOWAIT) == 0); + } else { + /* + * Close both ends of the pipe so that the child + * get a POLLHUP event when it tries to read from + * the other end. + */ + close(fd[1]); + close(fd[0]); + + waitpid(pid, &status, 0); + ASSERT(WIFEXITED(status) && WEXITSTATUS(status) == 0); + } + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* ifndef _WIN32 */ diff --git a/external/src/libuv/test/test-pipe-connect-error.c b/external/src/libuv/test/test-pipe-connect-error.c new file mode 100644 index 0000000..30c270d --- /dev/null +++ b/external/src/libuv/test/test-pipe-connect-error.c @@ -0,0 +1,98 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + + +#ifdef _WIN32 +# define BAD_PIPENAME "bad-pipe" +#else +# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there" +#endif + + +static int close_cb_called = 0; +static int connect_cb_called = 0; + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +static void connect_cb(uv_connect_t* connect_req, int status) { + ASSERT(status == UV_ENOENT); + uv_close((uv_handle_t*)connect_req->handle, close_cb); + connect_cb_called++; +} + + +static void connect_cb_file(uv_connect_t* connect_req, int status) { + ASSERT(status == UV_ENOTSOCK || status == UV_ECONNREFUSED); + uv_close((uv_handle_t*)connect_req->handle, close_cb); + connect_cb_called++; +} + + +TEST_IMPL(pipe_connect_bad_name) { + uv_pipe_t client; + uv_connect_t req; + int r; + + r = uv_pipe_init(uv_default_loop(), &client, 0); + ASSERT(r == 0); + uv_pipe_connect(&req, &client, BAD_PIPENAME, connect_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + ASSERT(connect_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(pipe_connect_to_file) { +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); +#endif + const char* path = "test/fixtures/empty_file"; + uv_pipe_t client; + uv_connect_t req; + int r; + + r = uv_pipe_init(uv_default_loop(), &client, 0); + ASSERT(r == 0); + uv_pipe_connect(&req, &client, path, connect_cb_file); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + ASSERT(connect_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-pipe-connect-multiple.c b/external/src/libuv/test/test-pipe-connect-multiple.c new file mode 100644 index 0000000..0a60d4a --- /dev/null +++ b/external/src/libuv/test/test-pipe-connect-multiple.c @@ -0,0 +1,107 @@ +/* Copyright (c) 2015 Saúl Ibarra Corretgé . + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + + +static int connection_cb_called = 0; +static int connect_cb_called = 0; + +#define NUM_CLIENTS 4 + +typedef struct { + uv_pipe_t pipe_handle; + uv_connect_t conn_req; +} client_t; + +static uv_pipe_t server_handle; +static client_t clients[NUM_CLIENTS]; +static uv_pipe_t connections[NUM_CLIENTS]; + + +static void connection_cb(uv_stream_t* server, int status) { + int r; + uv_pipe_t* conn; + ASSERT(status == 0); + + conn = &connections[connection_cb_called]; + r = uv_pipe_init(server->loop, conn, 0); + ASSERT(r == 0); + + r = uv_accept(server, (uv_stream_t*)conn); + ASSERT(r == 0); + + if (++connection_cb_called == NUM_CLIENTS && + connect_cb_called == NUM_CLIENTS) { + uv_stop(server->loop); + } +} + + +static void connect_cb(uv_connect_t* connect_req, int status) { + ASSERT(status == 0); + if (++connect_cb_called == NUM_CLIENTS && + connection_cb_called == NUM_CLIENTS) { + uv_stop(connect_req->handle->loop); + } +} + + +TEST_IMPL(pipe_connect_multiple) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif + int i; + int r; + uv_loop_t* loop; + + loop = uv_default_loop(); + + r = uv_pipe_init(loop, &server_handle, 0); + ASSERT(r == 0); + + r = uv_pipe_bind(&server_handle, TEST_PIPENAME); + ASSERT(r == 0); + + r = uv_listen((uv_stream_t*)&server_handle, 128, connection_cb); + ASSERT(r == 0); + + for (i = 0; i < NUM_CLIENTS; i++) { + r = uv_pipe_init(loop, &clients[i].pipe_handle, 0); + ASSERT(r == 0); + uv_pipe_connect(&clients[i].conn_req, + &clients[i].pipe_handle, + TEST_PIPENAME, + connect_cb); + } + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(connection_cb_called == NUM_CLIENTS); + ASSERT(connect_cb_called == NUM_CLIENTS); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-pipe-connect-prepare.c b/external/src/libuv/test/test-pipe-connect-prepare.c new file mode 100644 index 0000000..08b57cb --- /dev/null +++ b/external/src/libuv/test/test-pipe-connect-prepare.c @@ -0,0 +1,83 @@ +/* Copyright (c) 2015 Saúl Ibarra Corretgé . + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + + +#ifdef _WIN32 +# define BAD_PIPENAME "bad-pipe" +#else +# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there" +#endif + + +static int close_cb_called = 0; +static int connect_cb_called = 0; + +static uv_pipe_t pipe_handle; +static uv_prepare_t prepare_handle; +static uv_connect_t conn_req; + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +static void connect_cb(uv_connect_t* connect_req, int status) { + ASSERT(status == UV_ENOENT); + connect_cb_called++; + uv_close((uv_handle_t*)&prepare_handle, close_cb); + uv_close((uv_handle_t*)&pipe_handle, close_cb); +} + + +static void prepare_cb(uv_prepare_t* handle) { + ASSERT(handle == &prepare_handle); + uv_pipe_connect(&conn_req, &pipe_handle, BAD_PIPENAME, connect_cb); +} + + +TEST_IMPL(pipe_connect_on_prepare) { + int r; + + r = uv_pipe_init(uv_default_loop(), &pipe_handle, 0); + ASSERT(r == 0); + + r = uv_prepare_init(uv_default_loop(), &prepare_handle); + ASSERT(r == 0); + r = uv_prepare_start(&prepare_handle, prepare_cb); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(close_cb_called == 2); + ASSERT(connect_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-pipe-getsockname.c b/external/src/libuv/test/test-pipe-getsockname.c new file mode 100644 index 0000000..79db8eb --- /dev/null +++ b/external/src/libuv/test/test-pipe-getsockname.c @@ -0,0 +1,270 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include +#include + +#if defined(__linux__) + #include + #include +#endif + +#ifndef _WIN32 +# include /* close */ +#else +# include +#endif + +static uv_pipe_t pipe_client; +static uv_pipe_t pipe_server; +static uv_connect_t connect_req; + +static int pipe_close_cb_called = 0; +static int pipe_client_connect_cb_called = 0; + + +static void pipe_close_cb(uv_handle_t* handle) { + ASSERT(handle == (uv_handle_t*) &pipe_client || + handle == (uv_handle_t*) &pipe_server); + pipe_close_cb_called++; +} + + +static void pipe_client_connect_cb(uv_connect_t* req, int status) { + char buf[1024]; + size_t len; + int r; + + ASSERT(req == &connect_req); + ASSERT(status == 0); + + len = sizeof buf; + r = uv_pipe_getpeername(&pipe_client, buf, &len); + ASSERT(r == 0); + + ASSERT(buf[len - 1] != 0); + ASSERT(memcmp(buf, TEST_PIPENAME, len) == 0); + + len = sizeof buf; + r = uv_pipe_getsockname(&pipe_client, buf, &len); + ASSERT(r == 0 && len == 0); + + pipe_client_connect_cb_called++; + + + uv_close((uv_handle_t*) &pipe_client, pipe_close_cb); + uv_close((uv_handle_t*) &pipe_server, pipe_close_cb); +} + + +static void pipe_server_connection_cb(uv_stream_t* handle, int status) { + /* This function *may* be called, depending on whether accept or the + * connection callback is called first. + */ + ASSERT(status == 0); +} + + +TEST_IMPL(pipe_getsockname) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif + uv_loop_t* loop; + char buf[1024]; + size_t len; + int r; + + loop = uv_default_loop(); + ASSERT_NOT_NULL(loop); + + r = uv_pipe_init(loop, &pipe_server, 0); + ASSERT(r == 0); + + len = sizeof buf; + r = uv_pipe_getsockname(&pipe_server, buf, &len); + ASSERT(r == UV_EBADF); + + len = sizeof buf; + r = uv_pipe_getpeername(&pipe_server, buf, &len); + ASSERT(r == UV_EBADF); + + r = uv_pipe_bind(&pipe_server, TEST_PIPENAME); + ASSERT(r == 0); + + len = sizeof buf; + r = uv_pipe_getsockname(&pipe_server, buf, &len); + ASSERT(r == 0); + + ASSERT(buf[len - 1] != 0); + ASSERT(buf[len] == '\0'); + ASSERT(memcmp(buf, TEST_PIPENAME, len) == 0); + + len = sizeof buf; + r = uv_pipe_getpeername(&pipe_server, buf, &len); + ASSERT(r == UV_ENOTCONN); + + r = uv_listen((uv_stream_t*) &pipe_server, 0, pipe_server_connection_cb); + ASSERT(r == 0); + + r = uv_pipe_init(loop, &pipe_client, 0); + ASSERT(r == 0); + + len = sizeof buf; + r = uv_pipe_getsockname(&pipe_client, buf, &len); + ASSERT(r == UV_EBADF); + + len = sizeof buf; + r = uv_pipe_getpeername(&pipe_client, buf, &len); + ASSERT(r == UV_EBADF); + + uv_pipe_connect(&connect_req, &pipe_client, TEST_PIPENAME, pipe_client_connect_cb); + + len = sizeof buf; + r = uv_pipe_getsockname(&pipe_client, buf, &len); + ASSERT(r == 0 && len == 0); + + len = sizeof buf; + r = uv_pipe_getpeername(&pipe_client, buf, &len); + ASSERT(r == 0); + + ASSERT(buf[len - 1] != 0); + ASSERT(memcmp(buf, TEST_PIPENAME, len) == 0); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + ASSERT(pipe_client_connect_cb_called == 1); + ASSERT(pipe_close_cb_called == 2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(pipe_getsockname_abstract) { +#if defined(__linux__) + char buf[1024]; + size_t len; + int r; + int sock; + struct sockaddr_un sun; + socklen_t sun_len; + char abstract_pipe[] = "\0test-pipe"; + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + ASSERT(sock != -1); + + sun_len = sizeof sun; + memset(&sun, 0, sun_len); + sun.sun_family = AF_UNIX; + memcpy(sun.sun_path, abstract_pipe, sizeof abstract_pipe); + + r = bind(sock, (struct sockaddr*)&sun, sun_len); + ASSERT(r == 0); + + r = uv_pipe_init(uv_default_loop(), &pipe_server, 0); + ASSERT(r == 0); + r = uv_pipe_open(&pipe_server, sock); + ASSERT(r == 0); + + len = sizeof buf; + r = uv_pipe_getsockname(&pipe_server, buf, &len); + ASSERT(r == 0); + + ASSERT(memcmp(buf, abstract_pipe, sizeof abstract_pipe) == 0); + + uv_close((uv_handle_t*)&pipe_server, pipe_close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + close(sock); + + ASSERT(pipe_close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); + return 0; +#else + MAKE_VALGRIND_HAPPY(); + return 0; +#endif +} + +TEST_IMPL(pipe_getsockname_blocking) { +#ifdef _WIN32 + HANDLE readh, writeh; + int readfd; + char buf1[1024], buf2[1024]; + size_t len1, len2; + int r; + + r = CreatePipe(&readh, &writeh, NULL, 65536); + ASSERT(r != 0); + + r = uv_pipe_init(uv_default_loop(), &pipe_client, 0); + ASSERT(r == 0); + readfd = _open_osfhandle((intptr_t)readh, _O_RDONLY); + ASSERT(r != -1); + r = uv_pipe_open(&pipe_client, readfd); + ASSERT(r == 0); + r = uv_read_start((uv_stream_t*) &pipe_client, + (uv_alloc_cb) abort, + (uv_read_cb) abort); + ASSERT(r == 0); + Sleep(100); + r = uv_read_stop((uv_stream_t*)&pipe_client); + ASSERT(r == 0); + + len1 = sizeof buf1; + r = uv_pipe_getsockname(&pipe_client, buf1, &len1); + ASSERT(r == 0); + ASSERT(len1 == 0); /* It's an annonymous pipe. */ + + r = uv_read_start((uv_stream_t*)&pipe_client, + (uv_alloc_cb) abort, + (uv_read_cb) abort); + ASSERT(r == 0); + Sleep(100); + + len2 = sizeof buf2; + r = uv_pipe_getsockname(&pipe_client, buf2, &len2); + ASSERT(r == 0); + ASSERT(len2 == 0); /* It's an annonymous pipe. */ + + r = uv_read_stop((uv_stream_t*)&pipe_client); + ASSERT(r == 0); + + ASSERT(len1 == len2); + ASSERT(memcmp(buf1, buf2, len1) == 0); + + pipe_close_cb_called = 0; + uv_close((uv_handle_t*)&pipe_client, pipe_close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(pipe_close_cb_called == 1); + + CloseHandle(writeh); +#endif + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-pipe-pending-instances.c b/external/src/libuv/test/test-pipe-pending-instances.c new file mode 100644 index 0000000..b6ff911 --- /dev/null +++ b/external/src/libuv/test/test-pipe-pending-instances.c @@ -0,0 +1,59 @@ +/* Copyright (c) 2015 Saúl Ibarra Corretgé . + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + + +static void connection_cb(uv_stream_t* server, int status) { + ASSERT(0 && "this will never be called"); +} + + +TEST_IMPL(pipe_pending_instances) { + int r; + uv_pipe_t pipe_handle; + uv_loop_t* loop; + + loop = uv_default_loop(); + + r = uv_pipe_init(loop, &pipe_handle, 0); + ASSERT(r == 0); + + uv_pipe_pending_instances(&pipe_handle, 8); + + r = uv_pipe_bind(&pipe_handle, TEST_PIPENAME); + ASSERT(r == 0); + + uv_pipe_pending_instances(&pipe_handle, 16); + + r = uv_listen((uv_stream_t*)&pipe_handle, 128, connection_cb); + ASSERT(r == 0); + + uv_close((uv_handle_t*)&pipe_handle, NULL); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-pipe-sendmsg.c b/external/src/libuv/test/test-pipe-sendmsg.c new file mode 100644 index 0000000..3bf427f --- /dev/null +++ b/external/src/libuv/test/test-pipe-sendmsg.c @@ -0,0 +1,172 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + + +#ifndef _WIN32 + +#include +#include +#include +#include +#include +#include +#include + + +/* NOTE: size should be divisible by 2 */ +static uv_pipe_t incoming[4]; +static unsigned int incoming_count; +static unsigned int close_called; + + +static void set_nonblocking(uv_os_sock_t sock) { + int r; +#ifdef _WIN32 + unsigned long on = 1; + r = ioctlsocket(sock, FIONBIO, &on); + ASSERT(r == 0); +#else + int flags = fcntl(sock, F_GETFL, 0); + ASSERT(flags >= 0); + r = fcntl(sock, F_SETFL, flags | O_NONBLOCK); + ASSERT(r >= 0); +#endif +} + + + + +static void close_cb(uv_handle_t* handle) { + close_called++; +} + + +static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + static char base[1]; + + buf->base = base; + buf->len = sizeof(base); +} + + +static void read_cb(uv_stream_t* handle, + ssize_t nread, + const uv_buf_t* buf) { + uv_pipe_t* p; + uv_pipe_t* inc; + uv_handle_type pending; + unsigned int i; + + p = (uv_pipe_t*) handle; + ASSERT(nread >= 0); + + while (uv_pipe_pending_count(p) != 0) { + pending = uv_pipe_pending_type(p); + ASSERT(pending == UV_NAMED_PIPE); + + ASSERT(incoming_count < ARRAY_SIZE(incoming)); + inc = &incoming[incoming_count++]; + ASSERT(0 == uv_pipe_init(p->loop, inc, 0)); + ASSERT(0 == uv_accept(handle, (uv_stream_t*) inc)); + } + + if (incoming_count != ARRAY_SIZE(incoming)) + return; + + ASSERT(0 == uv_read_stop((uv_stream_t*) p)); + uv_close((uv_handle_t*) p, close_cb); + for (i = 0; i < ARRAY_SIZE(incoming); i++) + uv_close((uv_handle_t*) &incoming[i], close_cb); +} + + +TEST_IMPL(pipe_sendmsg) { +#if defined(NO_SEND_HANDLE_ON_PIPE) + RETURN_SKIP(NO_SEND_HANDLE_ON_PIPE); +#endif + uv_pipe_t p; + int r; + int fds[2]; + int send_fds[ARRAY_SIZE(incoming)]; + struct msghdr msg; + char scratch[64]; + struct cmsghdr *cmsg; + unsigned int i; + uv_buf_t buf; + + ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, fds)); + for (i = 0; i < ARRAY_SIZE(send_fds); i += 2) + ASSERT(0 == socketpair(AF_UNIX, SOCK_STREAM, 0, send_fds + i)); + ASSERT(i == ARRAY_SIZE(send_fds)); + ASSERT(0 == uv_pipe_init(uv_default_loop(), &p, 1)); + ASSERT(0 == uv_pipe_open(&p, fds[1])); + + buf = uv_buf_init("X", 1); + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = (struct iovec*) &buf; + msg.msg_iovlen = 1; + msg.msg_flags = 0; + + msg.msg_control = (void*) scratch; + msg.msg_controllen = CMSG_LEN(sizeof(send_fds)); + ASSERT(sizeof(scratch) >= msg.msg_controllen); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = msg.msg_controllen; + + /* silence aliasing warning */ + { + void* pv = CMSG_DATA(cmsg); + int* pi = pv; + for (i = 0; i < ARRAY_SIZE(send_fds); i++) + pi[i] = send_fds[i]; + } + + set_nonblocking(fds[1]); + ASSERT(0 == uv_read_start((uv_stream_t*) &p, alloc_cb, read_cb)); + + do + r = sendmsg(fds[0], &msg, 0); + while (r == -1 && errno == EINTR); + ASSERT(r == 1); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(ARRAY_SIZE(incoming) == incoming_count); + ASSERT(ARRAY_SIZE(incoming) + 1 == close_called); + close(fds[0]); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#else /* !_WIN32 */ + +TEST_IMPL(pipe_sendmsg) { + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#endif /* _WIN32 */ diff --git a/external/src/libuv/test/test-pipe-server-close.c b/external/src/libuv/test/test-pipe-server-close.c new file mode 100644 index 0000000..25305b3 --- /dev/null +++ b/external/src/libuv/test/test-pipe-server-close.c @@ -0,0 +1,94 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + + +static uv_pipe_t pipe_client; +static uv_pipe_t pipe_server; +static uv_connect_t connect_req; + +static int pipe_close_cb_called = 0; +static int pipe_client_connect_cb_called = 0; + + +static void pipe_close_cb(uv_handle_t* handle) { + ASSERT(handle == (uv_handle_t*) &pipe_client || + handle == (uv_handle_t*) &pipe_server); + pipe_close_cb_called++; +} + + +static void pipe_client_connect_cb(uv_connect_t* req, int status) { + ASSERT(req == &connect_req); + ASSERT(status == 0); + + pipe_client_connect_cb_called++; + + uv_close((uv_handle_t*) &pipe_client, pipe_close_cb); + uv_close((uv_handle_t*) &pipe_server, pipe_close_cb); +} + + +static void pipe_server_connection_cb(uv_stream_t* handle, int status) { + /* This function *may* be called, depending on whether accept or the + * connection callback is called first. + */ + ASSERT(status == 0); +} + + +TEST_IMPL(pipe_server_close) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#endif + uv_loop_t* loop; + int r; + + loop = uv_default_loop(); + ASSERT_NOT_NULL(loop); + + r = uv_pipe_init(loop, &pipe_server, 0); + ASSERT(r == 0); + + r = uv_pipe_bind(&pipe_server, TEST_PIPENAME); + ASSERT(r == 0); + + r = uv_listen((uv_stream_t*) &pipe_server, 0, pipe_server_connection_cb); + ASSERT(r == 0); + + r = uv_pipe_init(loop, &pipe_client, 0); + ASSERT(r == 0); + + uv_pipe_connect(&connect_req, &pipe_client, TEST_PIPENAME, pipe_client_connect_cb); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + ASSERT(pipe_client_connect_cb_called == 1); + ASSERT(pipe_close_cb_called == 2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-pipe-set-fchmod.c b/external/src/libuv/test/test-pipe-set-fchmod.c new file mode 100644 index 0000000..91e4766 --- /dev/null +++ b/external/src/libuv/test/test-pipe-set-fchmod.c @@ -0,0 +1,90 @@ +/* Copyright libuv project contributors. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +*/ + + +#include "uv.h" +#include "task.h" + +TEST_IMPL(pipe_set_chmod) { + uv_pipe_t pipe_handle; + uv_loop_t* loop; + int r; +#ifndef _WIN32 + struct stat stat_buf; +#endif + + loop = uv_default_loop(); + + r = uv_pipe_init(loop, &pipe_handle, 0); + ASSERT(r == 0); + + r = uv_pipe_bind(&pipe_handle, TEST_PIPENAME); + ASSERT(r == 0); + + /* No easy way to test if this works, we will only make sure that the call is + * successful. */ + r = uv_pipe_chmod(&pipe_handle, UV_READABLE); + if (r == UV_EPERM) { + MAKE_VALGRIND_HAPPY(); + RETURN_SKIP("Insufficient privileges to alter pipe fmode"); + } + ASSERT(r == 0); +#ifndef _WIN32 + stat(TEST_PIPENAME, &stat_buf); + ASSERT(stat_buf.st_mode & S_IRUSR); + ASSERT(stat_buf.st_mode & S_IRGRP); + ASSERT(stat_buf.st_mode & S_IROTH); +#endif + + r = uv_pipe_chmod(&pipe_handle, UV_WRITABLE); + ASSERT(r == 0); +#ifndef _WIN32 + stat(TEST_PIPENAME, &stat_buf); + ASSERT(stat_buf.st_mode & S_IWUSR); + ASSERT(stat_buf.st_mode & S_IWGRP); + ASSERT(stat_buf.st_mode & S_IWOTH); +#endif + + r = uv_pipe_chmod(&pipe_handle, UV_WRITABLE | UV_READABLE); + ASSERT(r == 0); +#ifndef _WIN32 + stat(TEST_PIPENAME, &stat_buf); + ASSERT(stat_buf.st_mode & S_IRUSR); + ASSERT(stat_buf.st_mode & S_IRGRP); + ASSERT(stat_buf.st_mode & S_IROTH); + ASSERT(stat_buf.st_mode & S_IWUSR); + ASSERT(stat_buf.st_mode & S_IWGRP); + ASSERT(stat_buf.st_mode & S_IWOTH); +#endif + + r = uv_pipe_chmod(NULL, UV_WRITABLE | UV_READABLE); + ASSERT(r == UV_EBADF); + + r = uv_pipe_chmod(&pipe_handle, 12345678); + ASSERT(r == UV_EINVAL); + + uv_close((uv_handle_t*)&pipe_handle, NULL); + r = uv_pipe_chmod(&pipe_handle, UV_WRITABLE | UV_READABLE); + ASSERT(r == UV_EBADF); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-pipe-set-non-blocking.c b/external/src/libuv/test/test-pipe-set-non-blocking.c new file mode 100644 index 0000000..8246afa --- /dev/null +++ b/external/src/libuv/test/test-pipe-set-non-blocking.c @@ -0,0 +1,132 @@ +/* Copyright (c) 2015, Ben Noordhuis + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include /* memset */ +#ifndef _WIN32 +#include /* close */ +#endif + +struct thread_ctx { + uv_barrier_t barrier; + uv_file fd; +}; + +static void thread_main(void* arg) { + struct thread_ctx* ctx; + uv_fs_t req; + uv_buf_t bufs[1]; + char buf[4096]; + ssize_t n; + int uv_errno; + + bufs[0] = uv_buf_init(buf, sizeof(buf)); + + ctx = arg; + uv_barrier_wait(&ctx->barrier); + + uv_sleep(100); /* make sure we are forcing the writer to block a bit */ + do { + uv_errno = uv_fs_read(NULL, &req, ctx->fd, bufs, 1, -1, NULL); + n = req.result; + uv_fs_req_cleanup(&req); + } while (n > 0 || (n == -1 && uv_errno == UV_EINTR)); + +#ifdef _WIN32 + ASSERT(n == UV_EOF); +#else + ASSERT(n == 0); +#endif +} + + +#ifdef _WIN32 +static void write_cb(uv_write_t* req, int status) { + ASSERT(status == 0); + req->handle = NULL; /* signal completion of write_cb */ +} +#endif + +#ifdef _WIN32 +#define NWRITES (10 << 16) +#else +#define NWRITES (10 << 20) +#endif + + +TEST_IMPL(pipe_set_non_blocking) { + struct thread_ctx ctx; + uv_pipe_t pipe_handle; + uv_thread_t thread; + size_t nwritten; + char data[4096]; + uv_buf_t buf; + uv_file fd[2]; + int n; +#ifdef _WIN32 + uv_write_t write_req; +#endif + + ASSERT(0 == uv_pipe_init(uv_default_loop(), &pipe_handle, 0)); + ASSERT(0 == uv_pipe(fd, 0, 0)); + ASSERT(0 == uv_pipe_open(&pipe_handle, fd[1])); + ASSERT(0 == uv_stream_set_blocking((uv_stream_t*) &pipe_handle, 1)); + fd[1] = -1; /* fd[1] is owned by pipe_handle now. */ + + ctx.fd = fd[0]; + ASSERT(0 == uv_barrier_init(&ctx.barrier, 2)); + ASSERT(0 == uv_thread_create(&thread, thread_main, &ctx)); + uv_barrier_wait(&ctx.barrier); + + buf.len = sizeof(data); + buf.base = data; + memset(data, '.', sizeof(data)); + + nwritten = 0; + while (nwritten < NWRITES) { + /* The stream is in blocking mode so uv_try_write() should always succeed + * with the exact number of bytes that we wanted written. + */ + n = uv_try_write((uv_stream_t*) &pipe_handle, &buf, 1); +#ifdef _WIN32 + ASSERT(n == UV_EAGAIN); /* E_NOTIMPL */ + ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &pipe_handle, &buf, 1, write_cb)); + ASSERT_NOT_NULL(write_req.handle); + ASSERT(1 == uv_run(uv_default_loop(), UV_RUN_ONCE)); /* queue write_cb */ + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); /* process write_cb */ + ASSERT_NULL(write_req.handle); /* check for signaled completion of write_cb */ + n = buf.len; +#endif + ASSERT(n == sizeof(data)); + nwritten += n; + } + + uv_close((uv_handle_t*) &pipe_handle, NULL); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + ASSERT(0 == uv_thread_join(&thread)); +#ifdef _WIN32 + ASSERT(0 == _close(fd[0])); /* fd[1] is closed by uv_close(). */ +#else + ASSERT(0 == close(fd[0])); /* fd[1] is closed by uv_close(). */ +#endif + fd[0] = -1; + uv_barrier_destroy(&ctx.barrier); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-platform-output.c b/external/src/libuv/test/test-platform-output.c new file mode 100644 index 0000000..341c7ae --- /dev/null +++ b/external/src/libuv/test/test-platform-output.c @@ -0,0 +1,176 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + + +TEST_IMPL(platform_output) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + + char buffer[512]; + size_t rss; + size_t size; + double uptime; + uv_pid_t pid; + uv_pid_t ppid; + uv_rusage_t rusage; + uv_cpu_info_t* cpus; + uv_interface_address_t* interfaces; + uv_passwd_t pwd; + uv_utsname_t uname; + int count; + int i; + int err; + + err = uv_get_process_title(buffer, sizeof(buffer)); + ASSERT(err == 0); + printf("uv_get_process_title: %s\n", buffer); + + size = sizeof(buffer); + err = uv_cwd(buffer, &size); + ASSERT(err == 0); + printf("uv_cwd: %s\n", buffer); + + err = uv_resident_set_memory(&rss); +#if defined(__MSYS__) + ASSERT(err == UV_ENOSYS); +#else + ASSERT(err == 0); + printf("uv_resident_set_memory: %llu\n", (unsigned long long) rss); +#endif + + err = uv_uptime(&uptime); +#if defined(__PASE__) + ASSERT(err == UV_ENOSYS); +#else + ASSERT(err == 0); + ASSERT(uptime > 0); + printf("uv_uptime: %f\n", uptime); +#endif + + err = uv_getrusage(&rusage); + ASSERT(err == 0); + ASSERT(rusage.ru_utime.tv_sec >= 0); + ASSERT(rusage.ru_utime.tv_usec >= 0); + ASSERT(rusage.ru_stime.tv_sec >= 0); + ASSERT(rusage.ru_stime.tv_usec >= 0); + printf("uv_getrusage:\n"); + printf(" user: %llu sec %llu microsec\n", + (unsigned long long) rusage.ru_utime.tv_sec, + (unsigned long long) rusage.ru_utime.tv_usec); + printf(" system: %llu sec %llu microsec\n", + (unsigned long long) rusage.ru_stime.tv_sec, + (unsigned long long) rusage.ru_stime.tv_usec); + printf(" page faults: %llu\n", (unsigned long long) rusage.ru_majflt); + printf(" maximum resident set size: %llu\n", + (unsigned long long) rusage.ru_maxrss); + + err = uv_cpu_info(&cpus, &count); +#if defined(__CYGWIN__) || defined(__MSYS__) + ASSERT(err == UV_ENOSYS); +#else + ASSERT(err == 0); + + printf("uv_cpu_info:\n"); + for (i = 0; i < count; i++) { + printf(" model: %s\n", cpus[i].model); + printf(" speed: %d\n", cpus[i].speed); + printf(" times.sys: %llu\n", (unsigned long long) cpus[i].cpu_times.sys); + printf(" times.user: %llu\n", + (unsigned long long) cpus[i].cpu_times.user); + printf(" times.idle: %llu\n", + (unsigned long long) cpus[i].cpu_times.idle); + printf(" times.irq: %llu\n", (unsigned long long) cpus[i].cpu_times.irq); + printf(" times.nice: %llu\n", + (unsigned long long) cpus[i].cpu_times.nice); + } +#endif + uv_free_cpu_info(cpus, count); + + err = uv_interface_addresses(&interfaces, &count); + ASSERT(err == 0); + + printf("uv_interface_addresses:\n"); + for (i = 0; i < count; i++) { + printf(" name: %s\n", interfaces[i].name); + printf(" internal: %d\n", interfaces[i].is_internal); + printf(" physical address: "); + printf("%02x:%02x:%02x:%02x:%02x:%02x\n", + (unsigned char)interfaces[i].phys_addr[0], + (unsigned char)interfaces[i].phys_addr[1], + (unsigned char)interfaces[i].phys_addr[2], + (unsigned char)interfaces[i].phys_addr[3], + (unsigned char)interfaces[i].phys_addr[4], + (unsigned char)interfaces[i].phys_addr[5]); + + if (interfaces[i].address.address4.sin_family == AF_INET) { + uv_ip4_name(&interfaces[i].address.address4, buffer, sizeof(buffer)); + } else if (interfaces[i].address.address4.sin_family == AF_INET6) { + uv_ip6_name(&interfaces[i].address.address6, buffer, sizeof(buffer)); + } + + printf(" address: %s\n", buffer); + + if (interfaces[i].netmask.netmask4.sin_family == AF_INET) { + uv_ip4_name(&interfaces[i].netmask.netmask4, buffer, sizeof(buffer)); + printf(" netmask: %s\n", buffer); + } else if (interfaces[i].netmask.netmask4.sin_family == AF_INET6) { + uv_ip6_name(&interfaces[i].netmask.netmask6, buffer, sizeof(buffer)); + printf(" netmask: %s\n", buffer); + } else { + printf(" netmask: none\n"); + } + } + uv_free_interface_addresses(interfaces, count); + + err = uv_os_get_passwd(&pwd); + ASSERT(err == 0); + + printf("uv_os_get_passwd:\n"); + printf(" euid: %ld\n", pwd.uid); + printf(" gid: %ld\n", pwd.gid); + printf(" username: %s\n", pwd.username); + printf(" shell: %s\n", pwd.shell); + printf(" home directory: %s\n", pwd.homedir); + uv_os_free_passwd(&pwd); + + pid = uv_os_getpid(); + ASSERT(pid > 0); + printf("uv_os_getpid: %d\n", (int) pid); + ppid = uv_os_getppid(); + ASSERT(ppid > 0); + printf("uv_os_getppid: %d\n", (int) ppid); + + err = uv_os_uname(&uname); + ASSERT(err == 0); + printf("uv_os_uname:\n"); + printf(" sysname: %s\n", uname.sysname); + printf(" release: %s\n", uname.release); + printf(" version: %s\n", uname.version); + printf(" machine: %s\n", uname.machine); + + return 0; +} diff --git a/external/src/libuv/test/test-poll-close-doesnt-corrupt-stack.c b/external/src/libuv/test/test-poll-close-doesnt-corrupt-stack.c new file mode 100644 index 0000000..1d7e84f --- /dev/null +++ b/external/src/libuv/test/test-poll-close-doesnt-corrupt-stack.c @@ -0,0 +1,114 @@ +/* Copyright Bert Belder, and other libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include + +#include "uv.h" +#include "task.h" + +#ifdef _MSC_VER /* msvc */ +# define NO_INLINE __declspec(noinline) +#else /* gcc */ +# define NO_INLINE __attribute__ ((noinline)) +#endif + +#ifdef _WIN32 +static uv_os_sock_t sock; +static uv_poll_t handle; +static int close_cb_called = 0; + + +static void close_cb(uv_handle_t* h) { + close_cb_called++; +} + + +static void poll_cb(uv_poll_t* h, int status, int events) { + ASSERT(0 && "should never get here"); +} + + +static void NO_INLINE close_socket_and_verify_stack(void) { + const uint32_t MARKER = 0xDEADBEEF; + const int VERIFY_AFTER = 10; /* ms */ + int r; + + volatile uint32_t data[65536]; + size_t i; + + for (i = 0; i < ARRAY_SIZE(data); i++) + data[i] = MARKER; + + r = closesocket(sock); + ASSERT(r == 0); + + uv_sleep(VERIFY_AFTER); + + for (i = 0; i < ARRAY_SIZE(data); i++) + ASSERT(data[i] == MARKER); +} +#endif + + +TEST_IMPL(poll_close_doesnt_corrupt_stack) { +#ifndef _WIN32 + RETURN_SKIP("Test only relevant on Windows"); +#else + struct WSAData wsa_data; + int r; + unsigned long on; + struct sockaddr_in addr; + + r = WSAStartup(MAKEWORD(2, 2), &wsa_data); + ASSERT(r == 0); + + sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT(sock != INVALID_SOCKET); + on = 1; + r = ioctlsocket(sock, FIONBIO, &on); + ASSERT(r == 0); + + r = uv_ip4_addr("127.0.0.1", TEST_PORT, &addr); + ASSERT(r == 0); + + r = connect(sock, (const struct sockaddr*) &addr, sizeof addr); + ASSERT(r != 0); + ASSERT(WSAGetLastError() == WSAEWOULDBLOCK); + + r = uv_poll_init_socket(uv_default_loop(), &handle, sock); + ASSERT(r == 0); + r = uv_poll_start(&handle, UV_READABLE | UV_WRITABLE, poll_cb); + ASSERT(r == 0); + + uv_close((uv_handle_t*) &handle, close_cb); + + close_socket_and_verify_stack(); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +#endif +} diff --git a/external/src/libuv/test/test-poll-close.c b/external/src/libuv/test/test-poll-close.c new file mode 100644 index 0000000..2eccddf --- /dev/null +++ b/external/src/libuv/test/test-poll-close.c @@ -0,0 +1,73 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include + +#ifndef _WIN32 +# include +# include +# include +#endif + +#include "uv.h" +#include "task.h" + +#define NUM_SOCKETS 64 + + +static int close_cb_called = 0; + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + + +TEST_IMPL(poll_close) { + uv_os_sock_t sockets[NUM_SOCKETS]; + uv_poll_t poll_handles[NUM_SOCKETS]; + int i; + +#ifdef _WIN32 + { + struct WSAData wsa_data; + int r = WSAStartup(MAKEWORD(2, 2), &wsa_data); + ASSERT(r == 0); + } +#endif + + for (i = 0; i < NUM_SOCKETS; i++) { + sockets[i] = socket(AF_INET, SOCK_STREAM, 0); + uv_poll_init_socket(uv_default_loop(), &poll_handles[i], sockets[i]); + uv_poll_start(&poll_handles[i], UV_READABLE | UV_WRITABLE, NULL); + } + + for (i = 0; i < NUM_SOCKETS; i++) { + uv_close((uv_handle_t*) &poll_handles[i], close_cb); + } + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == NUM_SOCKETS); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-poll-closesocket.c b/external/src/libuv/test/test-poll-closesocket.c new file mode 100644 index 0000000..1a1c364 --- /dev/null +++ b/external/src/libuv/test/test-poll-closesocket.c @@ -0,0 +1,92 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + + +#include + +#include "uv.h" +#include "task.h" + +#ifdef _WIN32 +static uv_os_sock_t sock; +static uv_poll_t handle; +static int close_cb_called = 0; + + +static void close_cb(uv_handle_t* h) { + close_cb_called++; +} + + +static void poll_cb(uv_poll_t* h, int status, int events) { + int r; + + ASSERT(status == 0); + ASSERT(h == &handle); + + r = uv_poll_start(&handle, UV_READABLE, poll_cb); + ASSERT(r == 0); + + closesocket(sock); + uv_close((uv_handle_t*) &handle, close_cb); + +} +#endif + + +TEST_IMPL(poll_closesocket) { +#ifndef _WIN32 + RETURN_SKIP("Test only relevant on Windows"); +#else + struct WSAData wsa_data; + int r; + unsigned long on; + struct sockaddr_in addr; + + r = WSAStartup(MAKEWORD(2, 2), &wsa_data); + ASSERT(r == 0); + + sock = socket(AF_INET, SOCK_STREAM, 0); + ASSERT(sock != INVALID_SOCKET); + on = 1; + r = ioctlsocket(sock, FIONBIO, &on); + ASSERT(r == 0); + + r = uv_ip4_addr("127.0.0.1", TEST_PORT, &addr); + ASSERT(r == 0); + + r = connect(sock, (const struct sockaddr*) &addr, sizeof addr); + ASSERT(r != 0); + ASSERT(WSAGetLastError() == WSAEWOULDBLOCK); + + r = uv_poll_init_socket(uv_default_loop(), &handle, sock); + ASSERT(r == 0); + r = uv_poll_start(&handle, UV_WRITABLE, poll_cb); + ASSERT(r == 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +#endif +} diff --git a/external/src/libuv/test/test-poll-multiple-handles.c b/external/src/libuv/test/test-poll-multiple-handles.c new file mode 100644 index 0000000..fc2205d --- /dev/null +++ b/external/src/libuv/test/test-poll-multiple-handles.c @@ -0,0 +1,99 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include + +#ifndef _WIN32 +# include +# include +# include +#endif + +#include "uv.h" +#include "task.h" + + +static int close_cb_called = 0; + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + +static void poll_cb(uv_poll_t* handle, int status, int events) { + /* Not a bound socket, linux immediately reports UV_READABLE, other OS do not */ + ASSERT(events == UV_READABLE); +} + +TEST_IMPL(poll_multiple_handles) { + uv_os_sock_t sock; + uv_poll_t first_poll_handle, second_poll_handle; + +#ifdef _WIN32 + { + struct WSAData wsa_data; + int r = WSAStartup(MAKEWORD(2, 2), &wsa_data); + ASSERT(r == 0); + } +#endif + + sock = socket(AF_INET, SOCK_STREAM, 0); +#ifdef _WIN32 + ASSERT(sock != INVALID_SOCKET); +#else + ASSERT(sock != -1); +#endif + ASSERT(0 == uv_poll_init_socket(uv_default_loop(), &first_poll_handle, sock)); + ASSERT(0 == uv_poll_init_socket(uv_default_loop(), &second_poll_handle, sock)); + + ASSERT(0 == uv_poll_start(&first_poll_handle, UV_READABLE, poll_cb)); + + /* We may not start polling while another polling handle is active + * on that fd. + */ +#ifndef _WIN32 + /* We do not track handles in an O(1) lookupable way on Windows, + * so not checking that here. + */ + ASSERT(uv_poll_start(&second_poll_handle, UV_READABLE, poll_cb) == UV_EEXIST); +#endif + + /* After stopping the other polling handle, we now should be able to poll */ + ASSERT(0 == uv_poll_stop(&first_poll_handle)); + ASSERT(0 == uv_poll_start(&second_poll_handle, UV_READABLE, poll_cb)); + + /* Closing an already stopped polling handle is safe in any case */ + uv_close((uv_handle_t*) &first_poll_handle, close_cb); + + uv_unref((uv_handle_t*) &second_poll_handle); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(close_cb_called == 1); + uv_ref((uv_handle_t*) &second_poll_handle); + + ASSERT(uv_is_active((uv_handle_t*) &second_poll_handle)); + uv_close((uv_handle_t*) &second_poll_handle, close_cb); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(close_cb_called == 2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-poll-oob.c b/external/src/libuv/test/test-poll-oob.c new file mode 100644 index 0000000..77ffe31 --- /dev/null +++ b/external/src/libuv/test/test-poll-oob.c @@ -0,0 +1,210 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#if !defined(_WIN32) + +#include "uv.h" +#include "task.h" + +#include +#include +#include +#include +#include + +static uv_tcp_t server_handle; +static uv_tcp_t client_handle; +static uv_tcp_t peer_handle; +static uv_poll_t poll_req[2]; +static uv_idle_t idle; +static uv_os_fd_t client_fd; +static uv_os_fd_t server_fd; +static int ticks; +static const int kMaxTicks = 10; +static int cli_pr_check = 0; +static int cli_rd_check = 0; +static int srv_rd_check = 0; + +static int got_eagain(void) { + return errno == EAGAIN + || errno == EINPROGRESS +#ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +#endif + ; +} + +static void idle_cb(uv_idle_t* idle) { + uv_sleep(100); + if (++ticks < kMaxTicks) + return; + + uv_poll_stop(&poll_req[0]); + uv_poll_stop(&poll_req[1]); + uv_close((uv_handle_t*) &server_handle, NULL); + uv_close((uv_handle_t*) &client_handle, NULL); + uv_close((uv_handle_t*) &peer_handle, NULL); + uv_close((uv_handle_t*) idle, NULL); +} + +static void poll_cb(uv_poll_t* handle, int status, int events) { + char buffer[5]; + int n; + int fd; + + ASSERT(0 == uv_fileno((uv_handle_t*)handle, &fd)); + memset(buffer, 0, 5); + + if (events & UV_PRIORITIZED) { + do + n = recv(client_fd, &buffer, 5, MSG_OOB); + while (n == -1 && errno == EINTR); + ASSERT(n >= 0 || errno != EINVAL); + cli_pr_check = 1; + ASSERT(0 == uv_poll_stop(&poll_req[0])); + ASSERT(0 == uv_poll_start(&poll_req[0], + UV_READABLE | UV_WRITABLE, + poll_cb)); + } + if (events & UV_READABLE) { + if (fd == client_fd) { + do + n = recv(client_fd, &buffer, 5, 0); + while (n == -1 && errno == EINTR); + ASSERT(n >= 0 || errno != EINVAL); + if (cli_rd_check == 1) { + ASSERT(strncmp(buffer, "world", n) == 0); + ASSERT(5 == n); + cli_rd_check = 2; + } + if (cli_rd_check == 0) { + ASSERT(n == 4); + ASSERT(strncmp(buffer, "hello", n) == 0); + cli_rd_check = 1; + do { + do + n = recv(server_fd, &buffer, 5, 0); + while (n == -1 && errno == EINTR); + if (n > 0) { + ASSERT(n == 5); + ASSERT(strncmp(buffer, "world", n) == 0); + cli_rd_check = 2; + } + } while (n > 0); + + ASSERT(got_eagain()); + } + } + if (fd == server_fd) { + do + n = recv(server_fd, &buffer, 3, 0); + while (n == -1 && errno == EINTR); + ASSERT(n >= 0 || errno != EINVAL); + ASSERT(3 == n); + ASSERT(strncmp(buffer, "foo", n) == 0); + srv_rd_check = 1; + uv_poll_stop(&poll_req[1]); + } + } + if (events & UV_WRITABLE) { + do { + n = send(client_fd, "foo", 3, 0); + } while (n < 0 && errno == EINTR); + ASSERT(3 == n); + } +} + +static void connection_cb(uv_stream_t* handle, int status) { + int r; + + ASSERT(0 == status); + ASSERT(0 == uv_accept(handle, (uv_stream_t*) &peer_handle)); + ASSERT(0 == uv_fileno((uv_handle_t*) &peer_handle, &server_fd)); + ASSERT(0 == uv_poll_init_socket(uv_default_loop(), &poll_req[0], client_fd)); + ASSERT(0 == uv_poll_init_socket(uv_default_loop(), &poll_req[1], server_fd)); + ASSERT(0 == uv_poll_start(&poll_req[0], + UV_PRIORITIZED | UV_READABLE | UV_WRITABLE, + poll_cb)); + ASSERT(0 == uv_poll_start(&poll_req[1], + UV_READABLE, + poll_cb)); + do { + r = send(server_fd, "hello", 5, MSG_OOB); + } while (r < 0 && errno == EINTR); + ASSERT(5 == r); + + do { + r = send(server_fd, "world", 5, 0); + } while (r < 0 && errno == EINTR); + ASSERT(5 == r); + + ASSERT(0 == uv_idle_start(&idle, idle_cb)); +} + + +TEST_IMPL(poll_oob) { + struct sockaddr_in addr; + int r = 0; + uv_loop_t* loop; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + loop = uv_default_loop(); + + ASSERT(0 == uv_tcp_init(loop, &server_handle)); + ASSERT(0 == uv_tcp_init(loop, &client_handle)); + ASSERT(0 == uv_tcp_init(loop, &peer_handle)); + ASSERT(0 == uv_idle_init(loop, &idle)); + ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0)); + ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 1, connection_cb)); + + /* Ensure two separate packets */ + ASSERT(0 == uv_tcp_nodelay(&client_handle, 1)); + + client_fd = socket(PF_INET, SOCK_STREAM, 0); + ASSERT(client_fd >= 0); + do { + errno = 0; + r = connect(client_fd, (const struct sockaddr*)&addr, sizeof(addr)); + } while (r == -1 && errno == EINTR); + ASSERT(r == 0); + + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + + ASSERT(ticks == kMaxTicks); + + /* Did client receive the POLLPRI message */ + ASSERT(cli_pr_check == 1); + /* Did client receive the POLLIN message */ + ASSERT(cli_rd_check == 2); + /* Could we write with POLLOUT and did the server receive our POLLOUT message + * through POLLIN. + */ + ASSERT(srv_rd_check == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif diff --git a/external/src/libuv/test/test-poll.c b/external/src/libuv/test/test-poll.c new file mode 100644 index 0000000..3bc422d --- /dev/null +++ b/external/src/libuv/test/test-poll.c @@ -0,0 +1,696 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include + +#ifdef _WIN32 +# include +#else +# include +# include +#endif + +#include "uv.h" +#include "task.h" + +#ifdef __linux__ +# include +#endif + +#ifdef UV_HAVE_KQUEUE +# include +# include +# include +#endif + + +#define NUM_CLIENTS 5 +#define TRANSFER_BYTES (1 << 16) + +#undef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)); + + +typedef enum { + UNIDIRECTIONAL, + DUPLEX +} test_mode_t; + +typedef struct connection_context_s { + uv_poll_t poll_handle; + uv_timer_t timer_handle; + uv_os_sock_t sock; + size_t read, sent; + int is_server_connection; + int open_handles; + int got_fin, sent_fin, got_disconnect; + unsigned int events, delayed_events; +} connection_context_t; + +typedef struct server_context_s { + uv_poll_t poll_handle; + uv_os_sock_t sock; + int connections; +} server_context_t; + + +static void delay_timer_cb(uv_timer_t* timer); + + +static test_mode_t test_mode = DUPLEX; + +static int closed_connections = 0; + +static int valid_writable_wakeups = 0; +static int spurious_writable_wakeups = 0; + +#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__) +static int disconnects = 0; +#endif /* !__sun && !_AIX && !__MVS__ */ + +static int got_eagain(void) { +#ifdef _WIN32 + return WSAGetLastError() == WSAEWOULDBLOCK; +#else + return errno == EAGAIN + || errno == EINPROGRESS +#ifdef EWOULDBLOCK + || errno == EWOULDBLOCK; +#endif + ; +#endif +} + + +static uv_os_sock_t create_bound_socket (struct sockaddr_in bind_addr) { + uv_os_sock_t sock; + int r; + + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); +#ifdef _WIN32 + ASSERT(sock != INVALID_SOCKET); +#else + ASSERT(sock >= 0); +#endif + +#ifndef _WIN32 + { + /* Allow reuse of the port. */ + int yes = 1; + r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes); + ASSERT(r == 0); + } +#endif + + r = bind(sock, (const struct sockaddr*) &bind_addr, sizeof bind_addr); + ASSERT(r == 0); + + return sock; +} + + +static void close_socket(uv_os_sock_t sock) { + int r; +#ifdef _WIN32 + r = closesocket(sock); +#else + r = close(sock); +#endif + /* On FreeBSD close() can fail with ECONNRESET if the socket was shutdown by + * the peer before all pending data was delivered. + */ + ASSERT(r == 0 || errno == ECONNRESET); +} + + +static connection_context_t* create_connection_context( + uv_os_sock_t sock, int is_server_connection) { + int r; + connection_context_t* context; + + context = (connection_context_t*) malloc(sizeof *context); + ASSERT_NOT_NULL(context); + + context->sock = sock; + context->is_server_connection = is_server_connection; + context->read = 0; + context->sent = 0; + context->open_handles = 0; + context->events = 0; + context->delayed_events = 0; + context->got_fin = 0; + context->sent_fin = 0; + context->got_disconnect = 0; + + r = uv_poll_init_socket(uv_default_loop(), &context->poll_handle, sock); + context->open_handles++; + context->poll_handle.data = context; + ASSERT(r == 0); + + r = uv_timer_init(uv_default_loop(), &context->timer_handle); + context->open_handles++; + context->timer_handle.data = context; + ASSERT(r == 0); + + return context; +} + + +static void connection_close_cb(uv_handle_t* handle) { + connection_context_t* context = (connection_context_t*) handle->data; + + if (--context->open_handles == 0) { + if (test_mode == DUPLEX || context->is_server_connection) { + ASSERT(context->read == TRANSFER_BYTES); + } else { + ASSERT(context->read == 0); + } + + if (test_mode == DUPLEX || !context->is_server_connection) { + ASSERT(context->sent == TRANSFER_BYTES); + } else { + ASSERT(context->sent == 0); + } + + closed_connections++; + + free(context); + } +} + + +static void destroy_connection_context(connection_context_t* context) { + uv_close((uv_handle_t*) &context->poll_handle, connection_close_cb); + uv_close((uv_handle_t*) &context->timer_handle, connection_close_cb); +} + + +static void connection_poll_cb(uv_poll_t* handle, int status, int events) { + connection_context_t* context = (connection_context_t*) handle->data; + unsigned int new_events; + int r; + + ASSERT(status == 0); + ASSERT(events & context->events); + ASSERT(!(events & ~context->events)); + + new_events = context->events; + + if (events & UV_READABLE) { + int action = rand() % 7; + + switch (action) { + case 0: + case 1: { + /* Read a couple of bytes. */ + static char buffer[74]; + + do + r = recv(context->sock, buffer, sizeof buffer, 0); + while (r == -1 && errno == EINTR); + ASSERT(r >= 0); + + if (r > 0) { + context->read += r; + } else { + /* Got FIN. */ + context->got_fin = 1; + new_events &= ~UV_READABLE; + } + + break; + } + + case 2: + case 3: { + /* Read until EAGAIN. */ + static char buffer[931]; + + for (;;) { + do + r = recv(context->sock, buffer, sizeof buffer, 0); + while (r == -1 && errno == EINTR); + + if (r <= 0) + break; + + context->read += r; + } + + if (r == 0) { + /* Got FIN. */ + context->got_fin = 1; + new_events &= ~UV_READABLE; + } else { + ASSERT(got_eagain()); + } + + break; + } + + case 4: + /* Ignore. */ + break; + + case 5: + /* Stop reading for a while. Restart in timer callback. */ + new_events &= ~UV_READABLE; + if (!uv_is_active((uv_handle_t*) &context->timer_handle)) { + context->delayed_events = UV_READABLE; + uv_timer_start(&context->timer_handle, delay_timer_cb, 10, 0); + } else { + context->delayed_events |= UV_READABLE; + } + break; + + case 6: + /* Fudge with the event mask. */ + uv_poll_start(&context->poll_handle, UV_WRITABLE, connection_poll_cb); + uv_poll_start(&context->poll_handle, UV_READABLE, connection_poll_cb); + context->events = UV_READABLE; + break; + + default: + ASSERT(0); + } + } + + if (events & UV_WRITABLE) { + if (context->sent < TRANSFER_BYTES && + !(test_mode == UNIDIRECTIONAL && context->is_server_connection)) { + /* We have to send more bytes. */ + int action = rand() % 7; + + switch (action) { + case 0: + case 1: { + /* Send a couple of bytes. */ + static char buffer[103]; + + int send_bytes = MIN(TRANSFER_BYTES - context->sent, sizeof buffer); + ASSERT(send_bytes > 0); + + do + r = send(context->sock, buffer, send_bytes, 0); + while (r == -1 && errno == EINTR); + + if (r < 0) { + ASSERT(got_eagain()); + spurious_writable_wakeups++; + break; + } + + ASSERT(r > 0); + context->sent += r; + valid_writable_wakeups++; + break; + } + + case 2: + case 3: { + /* Send until EAGAIN. */ + static char buffer[1234]; + + int send_bytes = MIN(TRANSFER_BYTES - context->sent, sizeof buffer); + ASSERT(send_bytes > 0); + + do + r = send(context->sock, buffer, send_bytes, 0); + while (r == -1 && errno == EINTR); + + if (r < 0) { + ASSERT(got_eagain()); + spurious_writable_wakeups++; + break; + } + + ASSERT(r > 0); + valid_writable_wakeups++; + context->sent += r; + + while (context->sent < TRANSFER_BYTES) { + send_bytes = MIN(TRANSFER_BYTES - context->sent, sizeof buffer); + ASSERT(send_bytes > 0); + + do + r = send(context->sock, buffer, send_bytes, 0); + while (r == -1 && errno == EINTR); + ASSERT(r != 0); + + if (r < 0) { + ASSERT(got_eagain()); + break; + } + + context->sent += r; + } + break; + } + + case 4: + /* Ignore. */ + break; + + case 5: + /* Stop sending for a while. Restart in timer callback. */ + new_events &= ~UV_WRITABLE; + if (!uv_is_active((uv_handle_t*) &context->timer_handle)) { + context->delayed_events = UV_WRITABLE; + uv_timer_start(&context->timer_handle, delay_timer_cb, 100, 0); + } else { + context->delayed_events |= UV_WRITABLE; + } + break; + + case 6: + /* Fudge with the event mask. */ + uv_poll_start(&context->poll_handle, + UV_READABLE, + connection_poll_cb); + uv_poll_start(&context->poll_handle, + UV_WRITABLE, + connection_poll_cb); + context->events = UV_WRITABLE; + break; + + default: + ASSERT(0); + } + + } else { + /* Nothing more to write. Send FIN. */ + int r; +#ifdef _WIN32 + r = shutdown(context->sock, SD_SEND); +#else + r = shutdown(context->sock, SHUT_WR); +#endif + ASSERT(r == 0); + context->sent_fin = 1; + new_events &= ~UV_WRITABLE; + } + } +#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__) + if (events & UV_DISCONNECT) { + context->got_disconnect = 1; + ++disconnects; + new_events &= ~UV_DISCONNECT; + } + + if (context->got_fin && context->sent_fin && context->got_disconnect) { +#else /* __sun && _AIX && __MVS__ */ + if (context->got_fin && context->sent_fin) { +#endif /* !__sun && !_AIX && !__MVS__ */ + /* Sent and received FIN. Close and destroy context. */ + close_socket(context->sock); + destroy_connection_context(context); + context->events = 0; + + } else if (new_events != context->events) { + /* Poll mask changed. Call uv_poll_start again. */ + context->events = new_events; + uv_poll_start(handle, new_events, connection_poll_cb); + } + + /* Assert that uv_is_active works correctly for poll handles. */ + if (context->events != 0) { + ASSERT(1 == uv_is_active((uv_handle_t*) handle)); + } else { + ASSERT(0 == uv_is_active((uv_handle_t*) handle)); + } +} + + +static void delay_timer_cb(uv_timer_t* timer) { + connection_context_t* context = (connection_context_t*) timer->data; + int r; + + /* Timer should auto stop. */ + ASSERT(0 == uv_is_active((uv_handle_t*) timer)); + + /* Add the requested events to the poll mask. */ + ASSERT(context->delayed_events != 0); + context->events |= context->delayed_events; + context->delayed_events = 0; + + r = uv_poll_start(&context->poll_handle, + context->events, + connection_poll_cb); + ASSERT(r == 0); +} + + +static server_context_t* create_server_context( + uv_os_sock_t sock) { + int r; + server_context_t* context; + + context = (server_context_t*) malloc(sizeof *context); + ASSERT_NOT_NULL(context); + + context->sock = sock; + context->connections = 0; + + r = uv_poll_init_socket(uv_default_loop(), &context->poll_handle, sock); + context->poll_handle.data = context; + ASSERT(r == 0); + + return context; +} + + +static void server_close_cb(uv_handle_t* handle) { + server_context_t* context = (server_context_t*) handle->data; + free(context); +} + + +static void destroy_server_context(server_context_t* context) { + uv_close((uv_handle_t*) &context->poll_handle, server_close_cb); +} + + +static void server_poll_cb(uv_poll_t* handle, int status, int events) { + server_context_t* server_context = (server_context_t*) + handle->data; + connection_context_t* connection_context; + struct sockaddr_in addr; + socklen_t addr_len; + uv_os_sock_t sock; + int r; + + addr_len = sizeof addr; + sock = accept(server_context->sock, (struct sockaddr*) &addr, &addr_len); +#ifdef _WIN32 + ASSERT(sock != INVALID_SOCKET); +#else + ASSERT(sock >= 0); +#endif + + connection_context = create_connection_context(sock, 1); + connection_context->events = UV_READABLE | UV_WRITABLE | UV_DISCONNECT; + r = uv_poll_start(&connection_context->poll_handle, + UV_READABLE | UV_WRITABLE | UV_DISCONNECT, + connection_poll_cb); + ASSERT(r == 0); + + if (++server_context->connections == NUM_CLIENTS) { + close_socket(server_context->sock); + destroy_server_context(server_context); + } +} + + +static void start_server(void) { + server_context_t* context; + struct sockaddr_in addr; + uv_os_sock_t sock; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + sock = create_bound_socket(addr); + context = create_server_context(sock); + + r = listen(sock, 100); + ASSERT(r == 0); + + r = uv_poll_start(&context->poll_handle, UV_READABLE, server_poll_cb); + ASSERT(r == 0); +} + + +static void start_client(void) { + uv_os_sock_t sock; + connection_context_t* context; + struct sockaddr_in server_addr; + struct sockaddr_in addr; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); + ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &addr)); + + sock = create_bound_socket(addr); + context = create_connection_context(sock, 0); + + context->events = UV_READABLE | UV_WRITABLE | UV_DISCONNECT; + r = uv_poll_start(&context->poll_handle, + UV_READABLE | UV_WRITABLE | UV_DISCONNECT, + connection_poll_cb); + ASSERT(r == 0); + + r = connect(sock, (struct sockaddr*) &server_addr, sizeof server_addr); + ASSERT(r == 0 || got_eagain()); +} + + +static void start_poll_test(void) { + int i, r; + +#ifdef _WIN32 + { + struct WSAData wsa_data; + int r = WSAStartup(MAKEWORD(2, 2), &wsa_data); + ASSERT(r == 0); + } +#endif + + start_server(); + + for (i = 0; i < NUM_CLIENTS; i++) + start_client(); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + /* Assert that at most five percent of the writable wakeups was spurious. */ + ASSERT(spurious_writable_wakeups == 0 || + (valid_writable_wakeups + spurious_writable_wakeups) / + spurious_writable_wakeups > 20); + + ASSERT(closed_connections == NUM_CLIENTS * 2); +#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__) + ASSERT(disconnects == NUM_CLIENTS * 2); +#endif + MAKE_VALGRIND_HAPPY(); +} + + +/* Issuing a shutdown() on IBM i PASE with parameter SHUT_WR + * also sends a normal close sequence to the partner program. + * This leads to timing issues and ECONNRESET failures in the + * test 'poll_duplex' and 'poll_unidirectional'. + * + * https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_74/apis/shutdn.htm + */ +TEST_IMPL(poll_duplex) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#elif defined(__PASE__) + RETURN_SKIP("API shutdown() may lead to timing issue on IBM i PASE"); +#endif + test_mode = DUPLEX; + start_poll_test(); + return 0; +} + + +TEST_IMPL(poll_unidirectional) { +#if defined(NO_SELF_CONNECT) + RETURN_SKIP(NO_SELF_CONNECT); +#elif defined(__PASE__) + RETURN_SKIP("API shutdown() may lead to timing issue on IBM i PASE"); +#endif + test_mode = UNIDIRECTIONAL; + start_poll_test(); + return 0; +} + + +/* Windows won't let you open a directory so we open a file instead. + * OS X lets you poll a file so open the $PWD instead. Both fail + * on Linux so it doesn't matter which one we pick. Both succeed + * on FreeBSD, Solaris and AIX so skip the test on those platforms. + */ +TEST_IMPL(poll_bad_fdtype) { +#if !defined(__DragonFly__) && !defined(__FreeBSD__) && !defined(__sun) && \ + !defined(_AIX) && !defined(__MVS__) && !defined(__FreeBSD_kernel__) && \ + !defined(__OpenBSD__) && !defined(__CYGWIN__) && !defined(__MSYS__) && \ + !defined(__NetBSD__) + uv_poll_t poll_handle; + int fd; + +#if defined(_WIN32) + fd = open("test/fixtures/empty_file", O_RDONLY); +#else + fd = open(".", O_RDONLY); +#endif + ASSERT(fd != -1); + ASSERT(0 != uv_poll_init(uv_default_loop(), &poll_handle, fd)); + ASSERT(0 == close(fd)); +#endif + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +#ifdef __linux__ +TEST_IMPL(poll_nested_epoll) { + uv_poll_t poll_handle; + int fd; + + fd = epoll_create(1); + ASSERT(fd != -1); + + ASSERT(0 == uv_poll_init(uv_default_loop(), &poll_handle, fd)); + ASSERT(0 == uv_poll_start(&poll_handle, UV_READABLE, (uv_poll_cb) abort)); + ASSERT(0 != uv_run(uv_default_loop(), UV_RUN_NOWAIT)); + + uv_close((uv_handle_t*) &poll_handle, NULL); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(0 == close(fd)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif /* __linux__ */ + + +#ifdef UV_HAVE_KQUEUE +TEST_IMPL(poll_nested_kqueue) { + uv_poll_t poll_handle; + int fd; + + fd = kqueue(); + ASSERT(fd != -1); + + ASSERT(0 == uv_poll_init(uv_default_loop(), &poll_handle, fd)); + ASSERT(0 == uv_poll_start(&poll_handle, UV_READABLE, (uv_poll_cb) abort)); + ASSERT(0 != uv_run(uv_default_loop(), UV_RUN_NOWAIT)); + + uv_close((uv_handle_t*) &poll_handle, NULL); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(0 == close(fd)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif /* UV_HAVE_KQUEUE */ diff --git a/external/src/libuv/test/test-process-priority.c b/external/src/libuv/test/test-process-priority.c new file mode 100644 index 0000000..b3d0a85 --- /dev/null +++ b/external/src/libuv/test/test-process-priority.c @@ -0,0 +1,83 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + + +TEST_IMPL(process_priority) { + int priority; + int r; + int i; + +#if defined(__MVS__) + if (uv_os_setpriority(0, 0) == UV_ENOSYS) + RETURN_SKIP("functionality not supported on zOS"); +#endif + + /* Verify that passing a NULL pointer returns UV_EINVAL. */ + r = uv_os_getpriority(0, NULL); + ASSERT(r == UV_EINVAL); + + /* Verify that all valid values work. */ + for (i = UV_PRIORITY_HIGHEST; i <= UV_PRIORITY_LOW; i++) { + r = uv_os_setpriority(0, i); + + /* If UV_EACCES is returned, the current user doesn't have permission to + set this specific priority. */ + if (r == UV_EACCES) + continue; + + ASSERT(r == 0); + ASSERT(uv_os_getpriority(0, &priority) == 0); + + /* Verify that the priority values match on Unix, and are range mapped + on Windows. */ +#ifndef _WIN32 + ASSERT(priority == i); +#else + /* On Windows, only elevated users can set UV_PRIORITY_HIGHEST. Other + users will silently be set to UV_PRIORITY_HIGH. */ + if (i < UV_PRIORITY_HIGH) + ASSERT(priority == UV_PRIORITY_HIGHEST || priority == UV_PRIORITY_HIGH); + else if (i < UV_PRIORITY_ABOVE_NORMAL) + ASSERT(priority == UV_PRIORITY_HIGH); + else if (i < UV_PRIORITY_NORMAL) + ASSERT(priority == UV_PRIORITY_ABOVE_NORMAL); + else if (i < UV_PRIORITY_BELOW_NORMAL) + ASSERT(priority == UV_PRIORITY_NORMAL); + else if (i < UV_PRIORITY_LOW) + ASSERT(priority == UV_PRIORITY_BELOW_NORMAL); + else + ASSERT(priority == UV_PRIORITY_LOW); +#endif + + /* Verify that the current PID and 0 are equivalent. */ + ASSERT(uv_os_getpriority(uv_os_getpid(), &r) == 0); + ASSERT(priority == r); + } + + /* Verify that invalid priorities return UV_EINVAL. */ + ASSERT(uv_os_setpriority(0, UV_PRIORITY_HIGHEST - 1) == UV_EINVAL); + ASSERT(uv_os_setpriority(0, UV_PRIORITY_LOW + 1) == UV_EINVAL); + + return 0; +} diff --git a/external/src/libuv/test/test-process-title-threadsafe.c b/external/src/libuv/test/test-process-title-threadsafe.c new file mode 100644 index 0000000..927643c --- /dev/null +++ b/external/src/libuv/test/test-process-title-threadsafe.c @@ -0,0 +1,109 @@ +/* Copyright libuv project contributors. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +*/ + + +#include "uv.h" +#include "task.h" + +#include + +#ifdef __APPLE__ +# define NUM_ITERATIONS 5 +#else +# define NUM_ITERATIONS 50 +#endif + +static const char* titles[] = { + "8L2NY0Kdj0XyNFZnmUZigIOfcWjyNr0SkMmUhKw99VLUsZFrvCQQC3XIRfNR8pjyMjXObllled", + "jUAcscJN49oLSN8GdmXj2Wo34XX2T2vp2j5khfajNQarlOulp57cE130yiY53ipJFnPyTn5i82", + "9niCI5icXGFS72XudhXqo5alftmZ1tpE7B3cwUmrq0CCDjC84FzBNB8XAHqvpNQfI2QAQG6ztT", + "n8qXVXuG6IEHDpabJgTEiwtpY6LHMZ8MgznnMpdHARu5EywufA6hcBaQfetb0YhEsK0ykDd7JU" +}; + +static void getter_thread_body(void* arg) { + uv_sem_t* getter_sem; + char buffer[512]; + size_t len; + + getter_sem = arg; + + while (UV_EAGAIN == uv_sem_trywait(getter_sem)) { + ASSERT(0 == uv_get_process_title(buffer, sizeof(buffer))); + + /* The maximum size of the process title on some platforms depends on + * the total size of the argv vector. It's therefore possible to read + * back a title that's shorter than what we submitted. + */ + len = strlen(buffer); + ASSERT_GT(len, 0); + + ASSERT( + 0 == strncmp(buffer, titles[0], len) || + 0 == strncmp(buffer, titles[1], len) || + 0 == strncmp(buffer, titles[2], len) || + 0 == strncmp(buffer, titles[3], len)); + + uv_sleep(0); + } +} + + +static void setter_thread_body(void* arg) { + int i; + + for (i = 0; i < NUM_ITERATIONS; i++) { + ASSERT(0 == uv_set_process_title(titles[0])); + ASSERT(0 == uv_set_process_title(titles[1])); + ASSERT(0 == uv_set_process_title(titles[2])); + ASSERT(0 == uv_set_process_title(titles[3])); + } +} + + +TEST_IMPL(process_title_threadsafe) { + uv_thread_t setter_threads[4]; + uv_thread_t getter_thread; + uv_sem_t getter_sem; + int i; + +#if defined(__sun) || defined(__CYGWIN__) || defined(__MSYS__) || \ + defined(__MVS__) || defined(__PASE__) + RETURN_SKIP("uv_(get|set)_process_title is not implemented."); +#endif + + ASSERT(0 == uv_set_process_title(titles[0])); + + ASSERT_EQ(0, uv_sem_init(&getter_sem, 0)); + ASSERT_EQ(0, + uv_thread_create(&getter_thread, getter_thread_body, &getter_sem)); + + for (i = 0; i < (int) ARRAY_SIZE(setter_threads); i++) + ASSERT(0 == uv_thread_create(&setter_threads[i], setter_thread_body, NULL)); + + for (i = 0; i < (int) ARRAY_SIZE(setter_threads); i++) + ASSERT(0 == uv_thread_join(&setter_threads[i])); + + uv_sem_post(&getter_sem); + ASSERT_EQ(0, uv_thread_join(&getter_thread)); + uv_sem_destroy(&getter_sem); + + return 0; +} diff --git a/external/src/libuv/test/test-process-title.c b/external/src/libuv/test/test-process-title.c new file mode 100644 index 0000000..35a1480 --- /dev/null +++ b/external/src/libuv/test/test-process-title.c @@ -0,0 +1,135 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + + +static void set_title(const char* title) { + char buffer[512]; + int err; + + err = uv_get_process_title(buffer, sizeof(buffer)); + ASSERT(err == 0); + + err = uv_set_process_title(title); + ASSERT(err == 0); + + err = uv_get_process_title(buffer, sizeof(buffer)); + ASSERT(err == 0); + + ASSERT(strcmp(buffer, title) == 0); +} + + +static void uv_get_process_title_edge_cases(void) { + char buffer[512]; + int r; + + /* Test a NULL buffer */ + r = uv_get_process_title(NULL, 100); + ASSERT(r == UV_EINVAL); + + /* Test size of zero */ + r = uv_get_process_title(buffer, 0); + ASSERT(r == UV_EINVAL); + + /* Test for insufficient buffer size */ + r = uv_get_process_title(buffer, 1); + ASSERT(r == UV_ENOBUFS); +} + + +TEST_IMPL(process_title) { +#if defined(__sun) || defined(__CYGWIN__) || defined(__MSYS__) || \ + defined(__PASE__) + RETURN_SKIP("uv_(get|set)_process_title is not implemented."); +#endif + + /* Check for format string vulnerabilities. */ + set_title("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s"); + set_title("new title"); + + /* Check uv_get_process_title() edge cases */ + uv_get_process_title_edge_cases(); + + return 0; +} + + +static void exit_cb(uv_process_t* process, int64_t status, int signo) { + ASSERT(status == 0); + ASSERT(signo == 0); + uv_close((uv_handle_t*) process, NULL); +} + + +TEST_IMPL(process_title_big_argv) { + uv_process_options_t options; + uv_process_t process; + size_t exepath_size; + char exepath[1024]; + char jumbo[512]; + char* args[5]; + +#ifdef _WIN32 + /* Remove once https://github.com/libuv/libuv/issues/2667 is fixed. */ + uv_set_process_title("run-tests"); +#endif + + exepath_size = sizeof(exepath) - 1; + ASSERT(0 == uv_exepath(exepath, &exepath_size)); + exepath[exepath_size] = '\0'; + + memset(jumbo, 'x', sizeof(jumbo) - 1); + jumbo[sizeof(jumbo) - 1] = '\0'; + + /* Note: need to pass three arguments, not two, otherwise + * run-tests.c thinks it's the name of a test to run. + */ + args[0] = exepath; + args[1] = "process_title_big_argv_helper"; + args[2] = jumbo; + args[3] = jumbo; + args[4] = NULL; + + memset(&options, 0, sizeof(options)); + options.file = exepath; + options.args = args; + options.exit_cb = exit_cb; + + ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +/* Called by process_title_big_argv_helper. */ +void process_title_big_argv(void) { + char buf[256] = "fail"; + + /* Return value deliberately ignored. */ + uv_get_process_title(buf, sizeof(buf)); + ASSERT(0 != strcmp(buf, "fail")); +} diff --git a/external/src/libuv/test/test-queue-foreach-delete.c b/external/src/libuv/test/test-queue-foreach-delete.c new file mode 100644 index 0000000..049ea77 --- /dev/null +++ b/external/src/libuv/test/test-queue-foreach-delete.c @@ -0,0 +1,204 @@ +/* Copyright The libuv project and contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include + + +/* + * The idea behind the test is as follows. + * Certain handle types are stored in a queue internally. + * Extra care should be taken for removal of a handle from the queue while iterating over the queue. + * (i.e., QUEUE_REMOVE() called within QUEUE_FOREACH()) + * This usually happens when someone closes or stops a handle from within its callback. + * So we need to check that we haven't screwed the queue on close/stop. + * To do so we do the following (for each handle type): + * 1. Create and start 3 handles (#0, #1, and #2). + * + * The queue after the start() calls: + * ..=> [queue head] <=> [handle] <=> [handle #1] <=> [handle] <=.. + * + * 2. Trigger handles to fire (for uv_idle_t, uv_prepare_t, and uv_check_t there is nothing to do). + * + * 3. In the callback for the first-executed handle (#0 or #2 depending on handle type) + * stop the handle and the next one (#1). + * (for uv_idle_t, uv_prepare_t, and uv_check_t callbacks are executed in the reverse order as they are start()'ed, + * so callback for handle #2 will be called first) + * + * The queue after the stop() calls: + * correct foreach "next" | + * \/ + * ..=> [queue head] <==============================> [handle] <=.. + * [ ] <- [handle] <=> [handle #1] -> [ ] + * /\ + * wrong foreach "next" | + * + * 4. The callback for handle #1 shouldn't be called because the handle #1 is stopped in the previous step. + * However, if QUEUE_REMOVE() is not handled properly within QUEUE_FOREACH(), the callback _will_ be called. + */ + +static const unsigned first_handle_number_idle = 2; +static const unsigned first_handle_number_prepare = 2; +static const unsigned first_handle_number_check = 2; +#ifdef __linux__ +static const unsigned first_handle_number_fs_event = 0; +#endif + + +#define DEFINE_GLOBALS_AND_CBS(name, ...) \ + static uv_##name##_t (name)[3]; \ + static unsigned name##_cb_calls[3]; \ + \ + static void name##2_cb(__VA_ARGS__) { \ + ASSERT(handle == &(name)[2]); \ + if (first_handle_number_##name == 2) { \ + uv_close((uv_handle_t*)&(name)[2], NULL); \ + uv_close((uv_handle_t*)&(name)[1], NULL); \ + } \ + name##_cb_calls[2]++; \ + } \ + \ + static void name##1_cb(__VA_ARGS__) { \ + ASSERT(handle == &(name)[1]); \ + ASSERT(0 && "Shouldn't be called" && (&name[0])); \ + } \ + \ + static void name##0_cb(__VA_ARGS__) { \ + ASSERT(handle == &(name)[0]); \ + if (first_handle_number_##name == 0) { \ + uv_close((uv_handle_t*)&(name)[0], NULL); \ + uv_close((uv_handle_t*)&(name)[1], NULL); \ + } \ + name##_cb_calls[0]++; \ + } \ + \ + static const uv_##name##_cb name##_cbs[] = { \ + name##0_cb, \ + name##1_cb, \ + name##2_cb, \ + }; + +#define INIT_AND_START(name, loop) \ + do { \ + size_t i; \ + for (i = 0; i < ARRAY_SIZE(name); i++) { \ + int r; \ + r = uv_##name##_init((loop), &(name)[i]); \ + ASSERT(r == 0); \ + \ + r = uv_##name##_start(&(name)[i], name##_cbs[i]); \ + ASSERT(r == 0); \ + } \ + } while (0) + +#define END_ASSERTS(name) \ + do { \ + ASSERT(name##_cb_calls[0] == 1); \ + ASSERT(name##_cb_calls[1] == 0); \ + ASSERT(name##_cb_calls[2] == 1); \ + } while (0) + +DEFINE_GLOBALS_AND_CBS(idle, uv_idle_t* handle) +DEFINE_GLOBALS_AND_CBS(prepare, uv_prepare_t* handle) +DEFINE_GLOBALS_AND_CBS(check, uv_check_t* handle) + +#ifdef __linux__ +DEFINE_GLOBALS_AND_CBS(fs_event, + uv_fs_event_t* handle, + const char* filename, + int events, + int status) + +static const char watched_dir[] = "."; +static uv_timer_t timer; +static unsigned helper_timer_cb_calls; + + +static void init_and_start_fs_events(uv_loop_t* loop) { + size_t i; + for (i = 0; i < ARRAY_SIZE(fs_event); i++) { + int r; + r = uv_fs_event_init(loop, &fs_event[i]); + ASSERT(r == 0); + + r = uv_fs_event_start(&fs_event[i], + (uv_fs_event_cb)fs_event_cbs[i], + watched_dir, + 0); + ASSERT(r == 0); + } +} + +static void helper_timer_cb(uv_timer_t* thandle) { + int r; + uv_fs_t fs_req; + + /* fire all fs_events */ + r = uv_fs_utime(thandle->loop, &fs_req, watched_dir, 0, 0, NULL); + ASSERT(r == 0); + ASSERT(fs_req.result == 0); + ASSERT(fs_req.fs_type == UV_FS_UTIME); + ASSERT(strcmp(fs_req.path, watched_dir) == 0); + uv_fs_req_cleanup(&fs_req); + + helper_timer_cb_calls++; +} +#endif + + +TEST_IMPL(queue_foreach_delete) { + uv_loop_t* loop; + int r; + + loop = uv_default_loop(); + + INIT_AND_START(idle, loop); + INIT_AND_START(prepare, loop); + INIT_AND_START(check, loop); + +#ifdef __linux__ + init_and_start_fs_events(loop); + + /* helper timer to trigger async and fs_event callbacks */ + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + + r = uv_timer_start(&timer, helper_timer_cb, 0, 0); + ASSERT(r == 0); +#endif + + r = uv_run(loop, UV_RUN_NOWAIT); + ASSERT(r == 1); + + END_ASSERTS(idle); + END_ASSERTS(prepare); + END_ASSERTS(check); + +#ifdef __linux__ + ASSERT(helper_timer_cb_calls == 1); +#endif + + MAKE_VALGRIND_HAPPY(); + + return 0; +} diff --git a/external/src/libuv/test/test-random.c b/external/src/libuv/test/test-random.c new file mode 100644 index 0000000..2e3ce44 --- /dev/null +++ b/external/src/libuv/test/test-random.c @@ -0,0 +1,94 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include + +static char scratch[256]; +static int random_cb_called; + + +static void random_cb(uv_random_t* req, int status, void* buf, size_t buflen) { + char zero[sizeof(scratch)]; + + memset(zero, 0, sizeof(zero)); + + ASSERT(0 == status); + ASSERT(buf == (void*) scratch); + + if (random_cb_called == 0) { + ASSERT(buflen == 0); + ASSERT(0 == memcmp(scratch, zero, sizeof(zero))); + } else { + ASSERT(buflen == sizeof(scratch)); + /* Buy a lottery ticket if you manage to trip this assertion. */ + ASSERT(0 != memcmp(scratch, zero, sizeof(zero))); + } + + random_cb_called++; +} + + +TEST_IMPL(random_async) { + uv_random_t req; + uv_loop_t* loop; + + loop = uv_default_loop(); + ASSERT(UV_EINVAL == uv_random(loop, &req, scratch, sizeof(scratch), -1, + random_cb)); + ASSERT(UV_E2BIG == uv_random(loop, &req, scratch, -1, -1, random_cb)); + + ASSERT(0 == uv_random(loop, &req, scratch, 0, 0, random_cb)); + ASSERT(0 == random_cb_called); + + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(1 == random_cb_called); + + ASSERT(0 == uv_random(loop, &req, scratch, sizeof(scratch), 0, random_cb)); + ASSERT(1 == random_cb_called); + + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(2 == random_cb_called); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(random_sync) { + char zero[256]; + char buf[256]; + + ASSERT(UV_EINVAL == uv_random(NULL, NULL, buf, sizeof(buf), -1, NULL)); + ASSERT(UV_E2BIG == uv_random(NULL, NULL, buf, -1, -1, NULL)); + + memset(buf, 0, sizeof(buf)); + ASSERT(0 == uv_random(NULL, NULL, buf, sizeof(buf), 0, NULL)); + + /* Buy a lottery ticket if you manage to trip this assertion. */ + memset(zero, 0, sizeof(zero)); + ASSERT(0 != memcmp(buf, zero, sizeof(zero))); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-ref.c b/external/src/libuv/test/test-ref.c new file mode 100644 index 0000000..d24ea4a --- /dev/null +++ b/external/src/libuv/test/test-ref.c @@ -0,0 +1,445 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + + +static uv_write_t write_req; +static uv_shutdown_t shutdown_req; +static uv_connect_t connect_req; + +static char buffer[32767]; + +static int req_cb_called; +static int connect_cb_called; +static int write_cb_called; +static int shutdown_cb_called; +static int close_cb_called; + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + + +static void do_close(void* handle) { + close_cb_called = 0; + uv_close((uv_handle_t*)handle, close_cb); + ASSERT(close_cb_called == 0); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(close_cb_called == 1); +} + + +static void fail_cb(void) { + FATAL("fail_cb should not have been called"); +} + + +static void fail_cb2(void) { + ASSERT(0 && "fail_cb2 should not have been called"); +} + + +static void req_cb(uv_handle_t* req, int status) { + req_cb_called++; +} + + +static void shutdown_cb(uv_shutdown_t* req, int status) { + ASSERT(req == &shutdown_req); + shutdown_cb_called++; +} + + +static void write_cb(uv_write_t* req, int status) { + ASSERT(req == &write_req); + uv_shutdown(&shutdown_req, req->handle, shutdown_cb); + write_cb_called++; +} + + +static void connect_and_write(uv_connect_t* req, int status) { + uv_buf_t buf = uv_buf_init(buffer, sizeof buffer); + ASSERT(req == &connect_req); + ASSERT(status == 0); + uv_write(&write_req, req->handle, &buf, 1, write_cb); + connect_cb_called++; +} + + + +static void connect_and_shutdown(uv_connect_t* req, int status) { + ASSERT(req == &connect_req); + ASSERT(status == 0); + uv_shutdown(&shutdown_req, req->handle, shutdown_cb); + connect_cb_called++; +} + + +TEST_IMPL(ref) { + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(idle_ref) { + uv_idle_t h; + uv_idle_init(uv_default_loop(), &h); + uv_idle_start(&h, (uv_idle_cb) fail_cb2); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(async_ref) { + uv_async_t h; + uv_async_init(uv_default_loop(), &h, NULL); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(prepare_ref) { + uv_prepare_t h; + uv_prepare_init(uv_default_loop(), &h); + uv_prepare_start(&h, (uv_prepare_cb) fail_cb2); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(check_ref) { + uv_check_t h; + uv_check_init(uv_default_loop(), &h); + uv_check_start(&h, (uv_check_cb) fail_cb2); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void prepare_cb(uv_prepare_t* h) { + ASSERT_NOT_NULL(h); + uv_unref((uv_handle_t*)h); +} + + +TEST_IMPL(unref_in_prepare_cb) { + uv_prepare_t h; + uv_prepare_init(uv_default_loop(), &h); + uv_prepare_start(&h, prepare_cb); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(timer_ref) { + uv_timer_t h; + uv_timer_init(uv_default_loop(), &h); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(timer_ref2) { + uv_timer_t h; + uv_timer_init(uv_default_loop(), &h); + uv_timer_start(&h, (uv_timer_cb)fail_cb, 42, 42); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_event_ref) { +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + uv_fs_event_t h; + uv_fs_event_init(uv_default_loop(), &h); + uv_fs_event_start(&h, (uv_fs_event_cb)fail_cb, ".", 0); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(fs_poll_ref) { + uv_fs_poll_t h; + uv_fs_poll_init(uv_default_loop(), &h); + uv_fs_poll_start(&h, NULL, ".", 999); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_ref) { + uv_tcp_t h; + uv_tcp_init(uv_default_loop(), &h); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_ref2) { + uv_tcp_t h; + uv_tcp_init(uv_default_loop(), &h); + uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_ref2b) { + uv_tcp_t h; + uv_tcp_init(uv_default_loop(), &h); + uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb); + uv_unref((uv_handle_t*)&h); + uv_close((uv_handle_t*)&h, close_cb); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(close_cb_called == 1); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_ref3) { + struct sockaddr_in addr; + uv_tcp_t h; + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + uv_tcp_init(uv_default_loop(), &h); + uv_tcp_connect(&connect_req, + &h, + (const struct sockaddr*) &addr, + connect_and_shutdown); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(connect_cb_called == 1); + ASSERT(shutdown_cb_called == 1); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_ref4) { + struct sockaddr_in addr; + uv_tcp_t h; + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + uv_tcp_init(uv_default_loop(), &h); + uv_tcp_connect(&connect_req, + &h, + (const struct sockaddr*) &addr, + connect_and_write); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(connect_cb_called == 1); + ASSERT(write_cb_called == 1); + ASSERT(shutdown_cb_called == 1); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(udp_ref) { + uv_udp_t h; + uv_udp_init(uv_default_loop(), &h); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(udp_ref2) { + struct sockaddr_in addr; + uv_udp_t h; + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + uv_udp_init(uv_default_loop(), &h); + uv_udp_bind(&h, (const struct sockaddr*) &addr, 0); + uv_udp_recv_start(&h, (uv_alloc_cb)fail_cb, (uv_udp_recv_cb)fail_cb); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(udp_ref3) { + struct sockaddr_in addr; + uv_buf_t buf = uv_buf_init("PING", 4); + uv_udp_send_t req; + uv_udp_t h; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + uv_udp_init(uv_default_loop(), &h); + uv_udp_send(&req, + &h, + &buf, + 1, + (const struct sockaddr*) &addr, + (uv_udp_send_cb) req_cb); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(req_cb_called == 1); + do_close(&h); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(pipe_ref) { + uv_pipe_t h; + uv_pipe_init(uv_default_loop(), &h, 0); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(pipe_ref2) { + uv_pipe_t h; + uv_pipe_init(uv_default_loop(), &h, 0); + uv_listen((uv_stream_t*)&h, 128, (uv_connection_cb)fail_cb); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(pipe_ref3) { + uv_pipe_t h; + uv_pipe_init(uv_default_loop(), &h, 0); + uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_and_shutdown); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(connect_cb_called == 1); + ASSERT(shutdown_cb_called == 1); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(pipe_ref4) { + uv_pipe_t h; + uv_pipe_init(uv_default_loop(), &h, 0); + uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_and_write); + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(connect_cb_called == 1); + ASSERT(write_cb_called == 1); + ASSERT(shutdown_cb_called == 1); + do_close(&h); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(process_ref) { + /* spawn_helper4 blocks indefinitely. */ + char *argv[] = { NULL, "spawn_helper4", NULL }; + uv_process_options_t options; + size_t exepath_size; + char exepath[256]; + uv_process_t h; + int r; + + memset(&options, 0, sizeof(options)); + exepath_size = sizeof(exepath); + + r = uv_exepath(exepath, &exepath_size); + ASSERT(r == 0); + + argv[0] = exepath; + options.file = exepath; + options.args = argv; + options.exit_cb = NULL; + + r = uv_spawn(uv_default_loop(), &h, &options); + ASSERT(r == 0); + + uv_unref((uv_handle_t*)&h); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + r = uv_process_kill(&h, /* SIGTERM */ 15); + ASSERT(r == 0); + + do_close(&h); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(has_ref) { + uv_idle_t h; + uv_idle_init(uv_default_loop(), &h); + uv_ref((uv_handle_t*)&h); + ASSERT(uv_has_ref((uv_handle_t*)&h) == 1); + uv_unref((uv_handle_t*)&h); + ASSERT(uv_has_ref((uv_handle_t*)&h) == 0); + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-run-nowait.c b/external/src/libuv/test/test-run-nowait.c new file mode 100644 index 0000000..43524f6 --- /dev/null +++ b/external/src/libuv/test/test-run-nowait.c @@ -0,0 +1,45 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static uv_timer_t timer_handle; +static int timer_called = 0; + + +static void timer_cb(uv_timer_t* handle) { + ASSERT(handle == &timer_handle); + timer_called = 1; +} + + +TEST_IMPL(run_nowait) { + int r; + uv_timer_init(uv_default_loop(), &timer_handle); + uv_timer_start(&timer_handle, timer_cb, 100, 100); + + r = uv_run(uv_default_loop(), UV_RUN_NOWAIT); + ASSERT(r != 0); + ASSERT(timer_called == 0); + + return 0; +} diff --git a/external/src/libuv/test/test-run-once.c b/external/src/libuv/test/test-run-once.c new file mode 100644 index 0000000..10cbf95 --- /dev/null +++ b/external/src/libuv/test/test-run-once.c @@ -0,0 +1,48 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#define NUM_TICKS 64 + +static uv_idle_t idle_handle; +static int idle_counter; + + +static void idle_cb(uv_idle_t* handle) { + ASSERT(handle == &idle_handle); + + if (++idle_counter == NUM_TICKS) + uv_idle_stop(handle); +} + + +TEST_IMPL(run_once) { + uv_idle_init(uv_default_loop(), &idle_handle); + uv_idle_start(&idle_handle, idle_cb); + + while (uv_run(uv_default_loop(), UV_RUN_ONCE)); + ASSERT(idle_counter == NUM_TICKS); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-semaphore.c b/external/src/libuv/test/test-semaphore.c new file mode 100644 index 0000000..ac03bb0 --- /dev/null +++ b/external/src/libuv/test/test-semaphore.c @@ -0,0 +1,111 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +typedef struct { + uv_mutex_t mutex; + uv_sem_t sem; + int delay; + volatile int posted; +} worker_config; + + +static void worker(void* arg) { + worker_config* c = arg; + + if (c->delay) + uv_sleep(c->delay); + + uv_mutex_lock(&c->mutex); + ASSERT(c->posted == 0); + uv_sem_post(&c->sem); + c->posted = 1; + uv_mutex_unlock(&c->mutex); +} + + +TEST_IMPL(semaphore_1) { + uv_thread_t thread; + worker_config wc; + + memset(&wc, 0, sizeof(wc)); + + ASSERT(0 == uv_sem_init(&wc.sem, 0)); + ASSERT(0 == uv_mutex_init(&wc.mutex)); + ASSERT(0 == uv_thread_create(&thread, worker, &wc)); + + uv_sleep(100); + uv_mutex_lock(&wc.mutex); + ASSERT(wc.posted == 1); + uv_sem_wait(&wc.sem); /* should not block */ + uv_mutex_unlock(&wc.mutex); /* ergo, it should be ok to unlock after wait */ + + ASSERT(0 == uv_thread_join(&thread)); + uv_mutex_destroy(&wc.mutex); + uv_sem_destroy(&wc.sem); + + return 0; +} + + +TEST_IMPL(semaphore_2) { + uv_thread_t thread; + worker_config wc; + + memset(&wc, 0, sizeof(wc)); + wc.delay = 100; + + ASSERT(0 == uv_sem_init(&wc.sem, 0)); + ASSERT(0 == uv_mutex_init(&wc.mutex)); + ASSERT(0 == uv_thread_create(&thread, worker, &wc)); + + uv_sem_wait(&wc.sem); + + ASSERT(0 == uv_thread_join(&thread)); + uv_mutex_destroy(&wc.mutex); + uv_sem_destroy(&wc.sem); + + return 0; +} + + +TEST_IMPL(semaphore_3) { + uv_sem_t sem; + + ASSERT(0 == uv_sem_init(&sem, 3)); + uv_sem_wait(&sem); /* should not block */ + uv_sem_wait(&sem); /* should not block */ + ASSERT(0 == uv_sem_trywait(&sem)); + ASSERT(UV_EAGAIN == uv_sem_trywait(&sem)); + + uv_sem_post(&sem); + ASSERT(0 == uv_sem_trywait(&sem)); + ASSERT(UV_EAGAIN == uv_sem_trywait(&sem)); + + uv_sem_destroy(&sem); + + return 0; +} diff --git a/external/src/libuv/test/test-shutdown-close.c b/external/src/libuv/test/test-shutdown-close.c new file mode 100644 index 0000000..78c369b --- /dev/null +++ b/external/src/libuv/test/test-shutdown-close.c @@ -0,0 +1,108 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* + * These tests verify that the uv_shutdown callback is always made, even when + * it is immediately followed by an uv_close call. + */ + +#include "uv.h" +#include "task.h" + + +static uv_shutdown_t shutdown_req; +static uv_connect_t connect_req; + +static int connect_cb_called = 0; +static int shutdown_cb_called = 0; +static int close_cb_called = 0; + + +static void shutdown_cb(uv_shutdown_t* req, int status) { + ASSERT(req == &shutdown_req); + ASSERT(status == 0 || status == UV_ECANCELED); + shutdown_cb_called++; +} + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + + +static void connect_cb(uv_connect_t* req, int status) { + int r; + + ASSERT(req == &connect_req); + ASSERT(status == 0); + + r = uv_shutdown(&shutdown_req, req->handle, shutdown_cb); + ASSERT(r == 0); + ASSERT(0 == uv_is_closing((uv_handle_t*) req->handle)); + uv_close((uv_handle_t*) req->handle, close_cb); + ASSERT(1 == uv_is_closing((uv_handle_t*) req->handle)); + + connect_cb_called++; +} + + +TEST_IMPL(shutdown_close_tcp) { + struct sockaddr_in addr; + uv_tcp_t h; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + r = uv_tcp_init(uv_default_loop(), &h); + ASSERT(r == 0); + r = uv_tcp_connect(&connect_req, + &h, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT(r == 0); + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(connect_cb_called == 1); + ASSERT(shutdown_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(shutdown_close_pipe) { + uv_pipe_t h; + int r; + + r = uv_pipe_init(uv_default_loop(), &h, 0); + ASSERT(r == 0); + uv_pipe_connect(&connect_req, &h, TEST_PIPENAME, connect_cb); + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(connect_cb_called == 1); + ASSERT(shutdown_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-shutdown-eof.c b/external/src/libuv/test/test-shutdown-eof.c new file mode 100644 index 0000000..0abab91 --- /dev/null +++ b/external/src/libuv/test/test-shutdown-eof.c @@ -0,0 +1,188 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + +static uv_timer_t timer; +static uv_tcp_t tcp; +static uv_connect_t connect_req; +static uv_write_t write_req; +static uv_shutdown_t shutdown_req; +static uv_buf_t qbuf; +static int got_q; +static int got_eof; +static int called_connect_cb; +static int called_shutdown_cb; +static int called_tcp_close_cb; +static int called_timer_close_cb; +static int called_timer_cb; + + +static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + buf->base = malloc(size); + buf->len = size; +} + + +static void read_cb(uv_stream_t* t, ssize_t nread, const uv_buf_t* buf) { + ASSERT((uv_tcp_t*)t == &tcp); + + if (nread == 0) { + free(buf->base); + return; + } + + if (!got_q) { + ASSERT(nread == 1); + ASSERT(!got_eof); + ASSERT(buf->base[0] == 'Q'); + free(buf->base); + got_q = 1; + puts("got Q"); + } else { + ASSERT(nread == UV_EOF); + if (buf->base) { + free(buf->base); + } + got_eof = 1; + puts("got EOF"); + } +} + + +static void shutdown_cb(uv_shutdown_t *req, int status) { + ASSERT(req == &shutdown_req); + + ASSERT(called_connect_cb == 1); + ASSERT(!got_eof); + ASSERT(called_tcp_close_cb == 0); + ASSERT(called_timer_close_cb == 0); + ASSERT(called_timer_cb == 0); + + called_shutdown_cb++; +} + + +static void connect_cb(uv_connect_t *req, int status) { + ASSERT(status == 0); + ASSERT(req == &connect_req); + + /* Start reading from our connection so we can receive the EOF. */ + ASSERT_EQ(0, uv_read_start((uv_stream_t*)&tcp, alloc_cb, read_cb)); + + /* Check error handling. */ + ASSERT_EQ(UV_EALREADY, uv_read_start((uv_stream_t*)&tcp, alloc_cb, read_cb)); + ASSERT_EQ(UV_EINVAL, uv_read_start(NULL, alloc_cb, read_cb)); + ASSERT_EQ(UV_EINVAL, uv_read_start((uv_stream_t*)&tcp, NULL, read_cb)); + ASSERT_EQ(UV_EINVAL, uv_read_start((uv_stream_t*)&tcp, alloc_cb, NULL)); + + /* + * Write the letter 'Q' to gracefully kill the echo-server. This will not + * effect our connection. + */ + uv_write(&write_req, (uv_stream_t*) &tcp, &qbuf, 1, NULL); + + /* Shutdown our end of the connection. */ + uv_shutdown(&shutdown_req, (uv_stream_t*) &tcp, shutdown_cb); + + called_connect_cb++; + ASSERT(called_shutdown_cb == 0); +} + + +static void tcp_close_cb(uv_handle_t* handle) { + ASSERT(handle == (uv_handle_t*) &tcp); + + ASSERT(called_connect_cb == 1); + ASSERT(got_q); + ASSERT(got_eof); + ASSERT(called_timer_cb == 1); + + called_tcp_close_cb++; +} + + +static void timer_close_cb(uv_handle_t* handle) { + ASSERT(handle == (uv_handle_t*) &timer); + called_timer_close_cb++; +} + + +static void timer_cb(uv_timer_t* handle) { + ASSERT(handle == &timer); + uv_close((uv_handle_t*) handle, timer_close_cb); + + /* + * The most important assert of the test: we have not received + * tcp_close_cb yet. + */ + ASSERT(called_tcp_close_cb == 0); + uv_close((uv_handle_t*) &tcp, tcp_close_cb); + + called_timer_cb++; +} + + +/* + * This test has a client which connects to the echo_server and immediately + * issues a shutdown. The echo-server, in response, will also shutdown their + * connection. We check, with a timer, that libuv is not automatically + * calling uv_close when the client receives the EOF from echo-server. + */ +TEST_IMPL(shutdown_eof) { + struct sockaddr_in server_addr; + int r; + + qbuf.base = "Q"; + qbuf.len = 1; + + r = uv_timer_init(uv_default_loop(), &timer); + ASSERT(r == 0); + + uv_timer_start(&timer, timer_cb, 100, 0); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); + r = uv_tcp_init(uv_default_loop(), &tcp); + ASSERT(!r); + + r = uv_tcp_connect(&connect_req, + &tcp, + (const struct sockaddr*) &server_addr, + connect_cb); + ASSERT(!r); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(called_connect_cb == 1); + ASSERT(called_shutdown_cb == 1); + ASSERT(got_eof); + ASSERT(got_q); + ASSERT(called_tcp_close_cb == 1); + ASSERT(called_timer_close_cb == 1); + ASSERT(called_timer_cb == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + diff --git a/external/src/libuv/test/test-shutdown-simultaneous.c b/external/src/libuv/test/test-shutdown-simultaneous.c new file mode 100644 index 0000000..7de3bd4 --- /dev/null +++ b/external/src/libuv/test/test-shutdown-simultaneous.c @@ -0,0 +1,135 @@ +/* Copyright libuv project and contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + +static uv_tcp_t tcp; +static uv_connect_t connect_req; +static uv_shutdown_t shutdown_req; +static uv_buf_t qbuf; +static int got_q; +static int got_eof; +static int called_connect_cb; +static int called_shutdown_cb; +static int called_tcp_close_cb; + + +static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + buf->base = malloc(size); + buf->len = size; +} + + +static void shutdown_cb(uv_shutdown_t *req, int status) { + ASSERT_PTR_EQ(req, &shutdown_req); + + ASSERT_EQ(called_connect_cb, 1); + ASSERT_EQ(called_tcp_close_cb, 0); +} + + +static void read_cb(uv_stream_t* t, ssize_t nread, const uv_buf_t* buf) { + ASSERT_PTR_EQ((uv_tcp_t*)t, &tcp); + + if (nread == 0) { + free(buf->base); + return; + } + + if (!got_q) { + ASSERT_EQ(nread, 4); + ASSERT_EQ(got_eof, 0); + ASSERT_MEM_EQ(buf->base, "QQSS", 4); + free(buf->base); + got_q = 1; + puts("got QQSS"); + /* Shutdown our end of the connection simultaneously */ + uv_shutdown(&shutdown_req, (uv_stream_t*) &tcp, shutdown_cb); + called_shutdown_cb++; + } else { + ASSERT_EQ(nread, UV_EOF); + if (buf->base) { + free(buf->base); + } + got_eof = 1; + puts("got EOF"); + } +} + + +static void connect_cb(uv_connect_t *req, int status) { + ASSERT_EQ(status, 0); + ASSERT_PTR_EQ(req, &connect_req); + + /* Start reading from our connection so we can receive the EOF. */ + ASSERT_EQ(0, uv_read_start((uv_stream_t*)&tcp, alloc_cb, read_cb)); + + /* Check error handling. */ + ASSERT_EQ(UV_EALREADY, uv_read_start((uv_stream_t*)&tcp, alloc_cb, read_cb)); + ASSERT_EQ(UV_EINVAL, uv_read_start(NULL, alloc_cb, read_cb)); + ASSERT_EQ(UV_EINVAL, uv_read_start((uv_stream_t*)&tcp, NULL, read_cb)); + ASSERT_EQ(UV_EINVAL, uv_read_start((uv_stream_t*)&tcp, alloc_cb, NULL)); + + /* + * Write the letter 'Q' and 'QSS` to gracefully kill the echo-server. This + * will not effect our connection. + */ + ASSERT_EQ(qbuf.len, uv_try_write((uv_stream_t*) &tcp, &qbuf, 1)); + + called_connect_cb++; + ASSERT_EQ(called_shutdown_cb, 0); +} + + +/* + * This test has a client which connects to the echo_server and immediately + * issues a shutdown. We check that this does not cause libuv to hang. + */ +TEST_IMPL(shutdown_simultaneous) { + struct sockaddr_in server_addr; + int r; + + qbuf.base = "QQSS"; + qbuf.len = 4; + + ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); + r = uv_tcp_init(uv_default_loop(), &tcp); + ASSERT_EQ(r, 0); + + r = uv_tcp_connect(&connect_req, + &tcp, + (const struct sockaddr*) &server_addr, + connect_cb); + ASSERT_EQ(r, 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT_EQ(called_connect_cb, 1); + ASSERT_EQ(called_shutdown_cb, 1); + ASSERT_EQ(got_eof, 1); + ASSERT_EQ(got_q, 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-shutdown-twice.c b/external/src/libuv/test/test-shutdown-twice.c new file mode 100644 index 0000000..d7aae89 --- /dev/null +++ b/external/src/libuv/test/test-shutdown-twice.c @@ -0,0 +1,85 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* + * This is a regression test for issue #1113 (calling uv_shutdown twice will + * leave a ghost request in the system) + */ + +#include "uv.h" +#include "task.h" + +static uv_shutdown_t req1; +static uv_shutdown_t req2; + +static int shutdown_cb_called = 0; + +static void close_cb(uv_handle_t* handle) { + +} + +static void shutdown_cb(uv_shutdown_t* req, int status) { + ASSERT(req == &req1); + ASSERT(status == 0); + shutdown_cb_called++; + uv_close((uv_handle_t*) req->handle, close_cb); +} + +static void connect_cb(uv_connect_t* req, int status) { + int r; + + ASSERT(status == 0); + + r = uv_shutdown(&req1, req->handle, shutdown_cb); + ASSERT(r == 0); + r = uv_shutdown(&req2, req->handle, shutdown_cb); + ASSERT(r != 0); + +} + +TEST_IMPL(shutdown_twice) { + struct sockaddr_in addr; + uv_loop_t* loop; + int r; + uv_tcp_t h; + + uv_connect_t connect_req; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + loop = uv_default_loop(); + + r = uv_tcp_init(loop, &h); + ASSERT(r == 0); + + r = uv_tcp_connect(&connect_req, + &h, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(shutdown_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-signal-multiple-loops.c b/external/src/libuv/test/test-signal-multiple-loops.c new file mode 100644 index 0000000..7d61ff6 --- /dev/null +++ b/external/src/libuv/test/test-signal-multiple-loops.c @@ -0,0 +1,307 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + + +/* This test does not pretend to be cross-platform. */ +#ifndef _WIN32 + +#include "uv.h" +#include "task.h" + +#include +#include +#include +#include +#include +#include +#include + +/* The value of NUM_SIGNAL_HANDLING_THREADS is not arbitrary; it needs to be a + * multiple of three for reasons that will become clear when you scroll down. + * We're basically creating three different thread groups. The total needs + * to be divisible by three in order for the numbers in the final check to + * match up. + */ +#define NUM_SIGNAL_HANDLING_THREADS 24 +#define NUM_LOOP_CREATING_THREADS 10 + +enum signal_action { + ONLY_SIGUSR1, + ONLY_SIGUSR2, + SIGUSR1_AND_SIGUSR2 +}; + +static uv_sem_t sem; +static uv_mutex_t counter_lock; +static volatile int stop = 0; + +static volatile int signal1_cb_counter = 0; +static volatile int signal2_cb_counter = 0; +static volatile int loop_creation_counter = 0; + + +static void increment_counter(volatile int* counter) { + uv_mutex_lock(&counter_lock); + ++(*counter); + uv_mutex_unlock(&counter_lock); +} + + +static void signal1_cb(uv_signal_t* handle, int signum) { + ASSERT(signum == SIGUSR1); + increment_counter(&signal1_cb_counter); + uv_signal_stop(handle); +} + + +static void signal2_cb(uv_signal_t* handle, int signum) { + ASSERT(signum == SIGUSR2); + increment_counter(&signal2_cb_counter); + uv_signal_stop(handle); +} + + +static void signal_handling_worker(void* context) { + enum signal_action action; + uv_signal_t signal1a; + uv_signal_t signal1b; + uv_signal_t signal2; + uv_loop_t loop; + int r; + + action = (enum signal_action) (uintptr_t) context; + + ASSERT(0 == uv_loop_init(&loop)); + + /* Setup the signal watchers and start them. */ + if (action == ONLY_SIGUSR1 || action == SIGUSR1_AND_SIGUSR2) { + r = uv_signal_init(&loop, &signal1a); + ASSERT(r == 0); + r = uv_signal_start(&signal1a, signal1_cb, SIGUSR1); + ASSERT(r == 0); + r = uv_signal_init(&loop, &signal1b); + ASSERT(r == 0); + r = uv_signal_start(&signal1b, signal1_cb, SIGUSR1); + ASSERT(r == 0); + } + + if (action == ONLY_SIGUSR2 || action == SIGUSR1_AND_SIGUSR2) { + r = uv_signal_init(&loop, &signal2); + ASSERT(r == 0); + r = uv_signal_start(&signal2, signal2_cb, SIGUSR2); + ASSERT(r == 0); + } + + /* Signal watchers are now set up. */ + uv_sem_post(&sem); + + /* Wait for all signals. The signal callbacks stop the watcher, so uv_run + * will return when all signal watchers caught a signal. + */ + r = uv_run(&loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + /* Restart the signal watchers. */ + if (action == ONLY_SIGUSR1 || action == SIGUSR1_AND_SIGUSR2) { + r = uv_signal_start(&signal1a, signal1_cb, SIGUSR1); + ASSERT(r == 0); + r = uv_signal_start(&signal1b, signal1_cb, SIGUSR1); + ASSERT(r == 0); + } + + if (action == ONLY_SIGUSR2 || action == SIGUSR1_AND_SIGUSR2) { + r = uv_signal_start(&signal2, signal2_cb, SIGUSR2); + ASSERT(r == 0); + } + + /* Wait for signals once more. */ + uv_sem_post(&sem); + + r = uv_run(&loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + /* Close the watchers. */ + if (action == ONLY_SIGUSR1 || action == SIGUSR1_AND_SIGUSR2) { + uv_close((uv_handle_t*) &signal1a, NULL); + uv_close((uv_handle_t*) &signal1b, NULL); + } + + if (action == ONLY_SIGUSR2 || action == SIGUSR1_AND_SIGUSR2) { + uv_close((uv_handle_t*) &signal2, NULL); + } + + /* Wait for the signal watchers to close. */ + r = uv_run(&loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + uv_loop_close(&loop); +} + + +static void signal_unexpected_cb(uv_signal_t* handle, int signum) { + ASSERT(0 && "signal_unexpected_cb should never be called"); +} + + +static void loop_creating_worker(void* context) { + (void) context; + + do { + uv_loop_t *loop; + uv_signal_t signal; + int r; + + loop = malloc(sizeof(*loop)); + ASSERT_NOT_NULL(loop); + ASSERT(0 == uv_loop_init(loop)); + + r = uv_signal_init(loop, &signal); + ASSERT(r == 0); + + r = uv_signal_start(&signal, signal_unexpected_cb, SIGTERM); + ASSERT(r == 0); + + uv_close((uv_handle_t*) &signal, NULL); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + uv_loop_close(loop); + free(loop); + + increment_counter(&loop_creation_counter); + } while (!stop); +} + + +TEST_IMPL(signal_multiple_loops) { +#if defined(__CYGWIN__) || defined(__MSYS__) + /* FIXME: This test needs more investigation. Somehow the `read` in + uv__signal_lock fails spuriously with EACCES or even EAGAIN even + though it is supposed to be blocking. Also the test hangs during + thread setup occasionally. */ + RETURN_SKIP("FIXME: This test needs more investigation on Cygwin"); +#endif +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + // See https://github.com/libuv/libuv/issues/2859 + RETURN_SKIP("QEMU's signal emulation code is notoriously tricky"); +#endif + uv_thread_t loop_creating_threads[NUM_LOOP_CREATING_THREADS]; + uv_thread_t signal_handling_threads[NUM_SIGNAL_HANDLING_THREADS]; + enum signal_action action; + sigset_t sigset; + int i; + int r; + + r = uv_sem_init(&sem, 0); + ASSERT(r == 0); + + r = uv_mutex_init(&counter_lock); + ASSERT(r == 0); + + /* Create a couple of threads that create a destroy loops continuously. */ + for (i = 0; i < NUM_LOOP_CREATING_THREADS; i++) { + r = uv_thread_create(&loop_creating_threads[i], + loop_creating_worker, + NULL); + ASSERT(r == 0); + } + + /* Create a couple of threads that actually handle signals. */ + for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) { + switch (i % 3) { + case 0: action = ONLY_SIGUSR1; break; + case 1: action = ONLY_SIGUSR2; break; + case 2: action = SIGUSR1_AND_SIGUSR2; break; + } + + r = uv_thread_create(&signal_handling_threads[i], + signal_handling_worker, + (void*) (uintptr_t) action); + ASSERT(r == 0); + } + + /* Wait until all threads have started and set up their signal watchers. */ + for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) + uv_sem_wait(&sem); + + r = kill(getpid(), SIGUSR1); + ASSERT(r == 0); + r = kill(getpid(), SIGUSR2); + ASSERT(r == 0); + + /* Wait for all threads to handle these signals. */ + for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) + uv_sem_wait(&sem); + + /* Block all signals to this thread, so we are sure that from here the signal + * handler runs in another thread. This is more likely to catch thread and + * signal safety issues if there are any. + */ + sigfillset(&sigset); + pthread_sigmask(SIG_SETMASK, &sigset, NULL); + + r = kill(getpid(), SIGUSR1); + ASSERT(r == 0); + r = kill(getpid(), SIGUSR2); + ASSERT(r == 0); + + /* Wait for all signal handling threads to exit. */ + for (i = 0; i < NUM_SIGNAL_HANDLING_THREADS; i++) { + r = uv_thread_join(&signal_handling_threads[i]); + ASSERT(r == 0); + } + + /* Tell all loop creating threads to stop. */ + stop = 1; + + /* Wait for all loop creating threads to exit. */ + for (i = 0; i < NUM_LOOP_CREATING_THREADS; i++) { + r = uv_thread_join(&loop_creating_threads[i]); + ASSERT(r == 0); + } + + uv_sem_destroy(&sem); + printf("signal1_cb calls: %d\n", signal1_cb_counter); + printf("signal2_cb calls: %d\n", signal2_cb_counter); + printf("loops created and destroyed: %d\n", loop_creation_counter); + + /* The division by three reflects the fact that we spawn three different + * thread groups of (NUM_SIGNAL_HANDLING_THREADS / 3) threads each. + */ + ASSERT(signal1_cb_counter == 8 * (NUM_SIGNAL_HANDLING_THREADS / 3)); + ASSERT(signal2_cb_counter == 4 * (NUM_SIGNAL_HANDLING_THREADS / 3)); + + /* We don't know exactly how much loops will be created and destroyed, but at + * least there should be 1 for every loop creating thread. + */ + ASSERT(loop_creation_counter >= NUM_LOOP_CREATING_THREADS); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* !_WIN32 */ diff --git a/external/src/libuv/test/test-signal-pending-on-close.c b/external/src/libuv/test/test-signal-pending-on-close.c new file mode 100644 index 0000000..428a97e --- /dev/null +++ b/external/src/libuv/test/test-signal-pending-on-close.c @@ -0,0 +1,119 @@ +/* Copyright libuv project contributors. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +*/ +#ifndef _WIN32 + +#include "uv.h" +#include "task.h" + +#include +#include + +static uv_loop_t loop; +static uv_signal_t signal_hdl; +static uv_pipe_t pipe_hdl; +static uv_write_t write_req; +static char* buf; +static int close_cb_called; + + +static void stop_loop_cb(uv_signal_t* signal, int signum) { + ASSERT(signum == SIGPIPE); + uv_stop(signal->loop); +} + +static void signal_cb(uv_signal_t* signal, int signum) { + ASSERT(0); +} + +static void close_cb(uv_handle_t *handle) { + close_cb_called++; +} + + +static void write_cb(uv_write_t* req, int status) { + ASSERT_NOT_NULL(req); + ASSERT(status == UV_EPIPE); + free(buf); + uv_close((uv_handle_t *) &pipe_hdl, close_cb); + uv_close((uv_handle_t *) &signal_hdl, close_cb); +} + + +TEST_IMPL(signal_pending_on_close) { + int pipefds[2]; + uv_buf_t buffer; + int r; + + ASSERT(0 == uv_loop_init(&loop)); + + ASSERT(0 == uv_signal_init(&loop, &signal_hdl)); + + ASSERT(0 == uv_signal_start(&signal_hdl, signal_cb, SIGPIPE)); + + ASSERT(0 == pipe(pipefds)); + + ASSERT(0 == uv_pipe_init(&loop, &pipe_hdl, 0)); + + ASSERT(0 == uv_pipe_open(&pipe_hdl, pipefds[1])); + + /* Write data large enough so it needs loop iteration */ + buf = malloc(1<<24); + ASSERT_NOT_NULL(buf); + memset(buf, '.', 1<<24); + buffer = uv_buf_init(buf, 1<<24); + + r = uv_write(&write_req, (uv_stream_t *) &pipe_hdl, &buffer, 1, write_cb); + ASSERT(0 == r); + + /* cause a SIGPIPE on write in next iteration */ + close(pipefds[0]); + + ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); + + ASSERT(0 == uv_loop_close(&loop)); + + ASSERT(2 == close_cb_called); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(signal_close_loop_alive) { + ASSERT(0 == uv_loop_init(&loop)); + ASSERT(0 == uv_signal_init(&loop, &signal_hdl)); + ASSERT(0 == uv_signal_start(&signal_hdl, stop_loop_cb, SIGPIPE)); + uv_unref((uv_handle_t*) &signal_hdl); + + ASSERT(0 == uv_kill(uv_os_getpid(), SIGPIPE)); + ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); + uv_close((uv_handle_t*) &signal_hdl, close_cb); + ASSERT(1 == uv_loop_alive(&loop)); + + ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); + ASSERT(0 == uv_loop_close(&loop)); + ASSERT(1 == close_cb_called); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#endif diff --git a/external/src/libuv/test/test-signal.c b/external/src/libuv/test/test-signal.c new file mode 100644 index 0000000..c2ce5ec --- /dev/null +++ b/external/src/libuv/test/test-signal.c @@ -0,0 +1,325 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#ifndef _WIN32 +#include +#endif + +TEST_IMPL(kill_invalid_signum) { + uv_pid_t pid; + + pid = uv_os_getpid(); + + ASSERT(uv_kill(pid, -1) == UV_EINVAL); +#ifdef _WIN32 + /* NSIG is not available on all platforms. */ + ASSERT(uv_kill(pid, NSIG) == UV_EINVAL); +#endif + ASSERT(uv_kill(pid, 4096) == UV_EINVAL); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +/* For Windows we test only signum handling */ +#ifdef _WIN32 +static void signum_test_cb(uv_signal_t* handle, int signum) { + FATAL("signum_test_cb should not be called"); +} + +TEST_IMPL(win32_signum_number) { + uv_signal_t signal; + uv_loop_t* loop; + + loop = uv_default_loop(); + uv_signal_init(loop, &signal); + + ASSERT(uv_signal_start(&signal, signum_test_cb, 0) == UV_EINVAL); + ASSERT(uv_signal_start(&signal, signum_test_cb, SIGINT) == 0); + ASSERT(uv_signal_start(&signal, signum_test_cb, SIGBREAK) == 0); + ASSERT(uv_signal_start(&signal, signum_test_cb, SIGHUP) == 0); + ASSERT(uv_signal_start(&signal, signum_test_cb, SIGWINCH) == 0); + ASSERT(uv_signal_start(&signal, signum_test_cb, SIGILL) == 0); + ASSERT(uv_signal_start(&signal, signum_test_cb, SIGABRT_COMPAT) == 0); + ASSERT(uv_signal_start(&signal, signum_test_cb, SIGFPE) == 0); + ASSERT(uv_signal_start(&signal, signum_test_cb, SIGSEGV) == 0); + ASSERT(uv_signal_start(&signal, signum_test_cb, SIGTERM) == 0); + ASSERT(uv_signal_start(&signal, signum_test_cb, SIGABRT) == 0); + ASSERT(uv_signal_start(&signal, signum_test_cb, -1) == UV_EINVAL); + ASSERT(uv_signal_start(&signal, signum_test_cb, NSIG) == UV_EINVAL); + ASSERT(uv_signal_start(&signal, signum_test_cb, 1024) == UV_EINVAL); + MAKE_VALGRIND_HAPPY(); + return 0; +} +#else +#include +#include +#include +#include +#include +#include +#include + +#define NSIGNALS 10 + +struct timer_ctx { + unsigned int ncalls; + uv_timer_t handle; + int signum; +}; + +struct signal_ctx { + enum { CLOSE, STOP, NOOP } stop_or_close; + unsigned int ncalls; + uv_signal_t handle; + int signum; + int one_shot; +}; + + +static void signal_cb(uv_signal_t* handle, int signum) { + struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle); + ASSERT(signum == ctx->signum); + if (++ctx->ncalls == NSIGNALS) { + if (ctx->stop_or_close == STOP) + uv_signal_stop(handle); + else if (ctx->stop_or_close == CLOSE) + uv_close((uv_handle_t*)handle, NULL); + else + ASSERT(0); + } +} + +static void signal_cb_one_shot(uv_signal_t* handle, int signum) { + struct signal_ctx* ctx = container_of(handle, struct signal_ctx, handle); + ASSERT(signum == ctx->signum); + ASSERT(++ctx->ncalls == 1); + if (ctx->stop_or_close == CLOSE) + uv_close((uv_handle_t*)handle, NULL); +} + + +static void timer_cb(uv_timer_t* handle) { + struct timer_ctx* ctx = container_of(handle, struct timer_ctx, handle); + + raise(ctx->signum); + + if (++ctx->ncalls == NSIGNALS) + uv_close((uv_handle_t*)handle, NULL); +} + + +static void start_watcher(uv_loop_t* loop, + int signum, + struct signal_ctx* ctx, + int one_shot) { + ctx->ncalls = 0; + ctx->signum = signum; + ctx->stop_or_close = CLOSE; + ctx->one_shot = one_shot; + ASSERT(0 == uv_signal_init(loop, &ctx->handle)); + if (one_shot) + ASSERT(0 == uv_signal_start_oneshot(&ctx->handle, signal_cb_one_shot, signum)); + else + ASSERT(0 == uv_signal_start(&ctx->handle, signal_cb, signum)); +} + +static void start_timer(uv_loop_t* loop, int signum, struct timer_ctx* ctx) { + ctx->ncalls = 0; + ctx->signum = signum; + ASSERT(0 == uv_timer_init(loop, &ctx->handle)); + ASSERT(0 == uv_timer_start(&ctx->handle, timer_cb, 5, 5)); +} + + +TEST_IMPL(we_get_signal) { + struct signal_ctx sc; + struct timer_ctx tc; + uv_loop_t* loop; + + loop = uv_default_loop(); + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, &sc, 0); + sc.stop_or_close = STOP; /* stop, don't close the signal handle */ + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc.ncalls == NSIGNALS); + + start_timer(loop, SIGCHLD, &tc); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc.ncalls == NSIGNALS); + + sc.ncalls = 0; + sc.stop_or_close = CLOSE; /* now close it when it's done */ + uv_signal_start(&sc.handle, signal_cb, SIGCHLD); + + start_timer(loop, SIGCHLD, &tc); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc.ncalls == NSIGNALS); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(we_get_signals) { + struct signal_ctx sc[4]; + struct timer_ctx tc[2]; + uv_loop_t* loop; + unsigned int i; + + loop = uv_default_loop(); + start_watcher(loop, SIGUSR1, sc + 0, 0); + start_watcher(loop, SIGUSR1, sc + 1, 0); + start_watcher(loop, SIGUSR2, sc + 2, 0); + start_watcher(loop, SIGUSR2, sc + 3, 0); + start_timer(loop, SIGUSR1, tc + 0); + start_timer(loop, SIGUSR2, tc + 1); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + + for (i = 0; i < ARRAY_SIZE(sc); i++) + ASSERT(sc[i].ncalls == NSIGNALS); + + for (i = 0; i < ARRAY_SIZE(tc); i++) + ASSERT(tc[i].ncalls == NSIGNALS); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(we_get_signal_one_shot) { + struct signal_ctx sc; + struct timer_ctx tc; + uv_loop_t* loop; + + loop = uv_default_loop(); + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, &sc, 1); + sc.stop_or_close = NOOP; + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc.ncalls == 1); + + start_timer(loop, SIGCHLD, &tc); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(sc.ncalls == 1); + + sc.ncalls = 0; + sc.stop_or_close = CLOSE; /* now close it when it's done */ + uv_signal_start_oneshot(&sc.handle, signal_cb_one_shot, SIGCHLD); + start_timer(loop, SIGCHLD, &tc); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc.ncalls == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(we_get_signals_mixed) { + struct signal_ctx sc[4]; + struct timer_ctx tc; + uv_loop_t* loop; + + loop = uv_default_loop(); + + /* 2 one-shot */ + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, sc + 0, 1); + start_watcher(loop, SIGCHLD, sc + 1, 1); + sc[0].stop_or_close = CLOSE; + sc[1].stop_or_close = CLOSE; + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc[0].ncalls == 1); + ASSERT(sc[1].ncalls == 1); + + /* 2 one-shot, 1 normal then remove normal */ + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, sc + 0, 1); + start_watcher(loop, SIGCHLD, sc + 1, 1); + sc[0].stop_or_close = CLOSE; + sc[1].stop_or_close = CLOSE; + start_watcher(loop, SIGCHLD, sc + 2, 0); + uv_close((uv_handle_t*)&(sc[2]).handle, NULL); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc[0].ncalls == 1); + ASSERT(sc[1].ncalls == 1); + ASSERT(sc[2].ncalls == 0); + + /* 2 normal, 1 one-shot then remove one-shot */ + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, sc + 0, 0); + start_watcher(loop, SIGCHLD, sc + 1, 0); + sc[0].stop_or_close = CLOSE; + sc[1].stop_or_close = CLOSE; + start_watcher(loop, SIGCHLD, sc + 2, 1); + uv_close((uv_handle_t*)&(sc[2]).handle, NULL); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc[0].ncalls == NSIGNALS); + ASSERT(sc[1].ncalls == NSIGNALS); + ASSERT(sc[2].ncalls == 0); + + /* 2 normal, 2 one-shot then remove 2 normal */ + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, sc + 0, 0); + start_watcher(loop, SIGCHLD, sc + 1, 0); + start_watcher(loop, SIGCHLD, sc + 2, 1); + start_watcher(loop, SIGCHLD, sc + 3, 1); + sc[2].stop_or_close = CLOSE; + sc[3].stop_or_close = CLOSE; + uv_close((uv_handle_t*)&(sc[0]).handle, NULL); + uv_close((uv_handle_t*)&(sc[1]).handle, NULL); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc[0].ncalls == 0); + ASSERT(sc[1].ncalls == 0); + ASSERT(sc[2].ncalls == 1); + ASSERT(sc[2].ncalls == 1); + + /* 1 normal, 1 one-shot, 2 normal then remove 1st normal, 2nd normal */ + start_timer(loop, SIGCHLD, &tc); + start_watcher(loop, SIGCHLD, sc + 0, 0); + start_watcher(loop, SIGCHLD, sc + 1, 1); + start_watcher(loop, SIGCHLD, sc + 2, 0); + start_watcher(loop, SIGCHLD, sc + 3, 0); + sc[3].stop_or_close = CLOSE; + uv_close((uv_handle_t*)&(sc[0]).handle, NULL); + uv_close((uv_handle_t*)&(sc[2]).handle, NULL); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(tc.ncalls == NSIGNALS); + ASSERT(sc[0].ncalls == 0); + ASSERT(sc[1].ncalls == 1); + ASSERT(sc[2].ncalls == 0); + ASSERT(sc[3].ncalls == NSIGNALS); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#endif /* _WIN32 */ diff --git a/external/src/libuv/test/test-socket-buffer-size.c b/external/src/libuv/test/test-socket-buffer-size.c new file mode 100644 index 0000000..72f8c25 --- /dev/null +++ b/external/src/libuv/test/test-socket-buffer-size.c @@ -0,0 +1,77 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +static uv_udp_t udp; +static uv_tcp_t tcp; +static int close_cb_called; + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + + +static void check_buffer_size(uv_handle_t* handle) { + int value; + + value = 0; + ASSERT(0 == uv_recv_buffer_size(handle, &value)); + ASSERT(value > 0); + + value = 10000; + ASSERT(0 == uv_recv_buffer_size(handle, &value)); + + value = 0; + ASSERT(0 == uv_recv_buffer_size(handle, &value)); + /* linux sets double the value */ + ASSERT(value == 10000 || value == 20000); +} + + +TEST_IMPL(socket_buffer_size) { + struct sockaddr_in addr; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + ASSERT(0 == uv_tcp_init(uv_default_loop(), &tcp)); + ASSERT(0 == uv_tcp_bind(&tcp, (struct sockaddr*) &addr, 0)); + check_buffer_size((uv_handle_t*) &tcp); + uv_close((uv_handle_t*) &tcp, close_cb); + + ASSERT(0 == uv_udp_init(uv_default_loop(), &udp)); + ASSERT(0 == uv_udp_bind(&udp, (struct sockaddr*) &addr, 0)); + check_buffer_size((uv_handle_t*) &udp); + uv_close((uv_handle_t*) &udp, close_cb); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + ASSERT(close_cb_called == 2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-spawn.c b/external/src/libuv/test/test-spawn.c new file mode 100644 index 0000000..9f2eb24 --- /dev/null +++ b/external/src/libuv/test/test-spawn.c @@ -0,0 +1,1945 @@ + +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include +#include +#include +#include + +#ifdef _WIN32 +# include +# include + typedef BOOL (WINAPI *sCompareObjectHandles)(_In_ HANDLE, _In_ HANDLE); +#else +# include +# include +#endif + + +static int close_cb_called; +static int exit_cb_called; +static uv_process_t process; +static uv_timer_t timer; +static uv_process_options_t options; +static char exepath[1024]; +static size_t exepath_size = 1024; +static char* args[5]; +static int no_term_signal; +static int timer_counter; +static uv_tcp_t tcp_server; + +#define OUTPUT_SIZE 1024 +static char output[OUTPUT_SIZE]; +static int output_used; + + +static void close_cb(uv_handle_t* handle) { + printf("close_cb\n"); + close_cb_called++; +} + +static void exit_cb(uv_process_t* process, + int64_t exit_status, + int term_signal) { + printf("exit_cb\n"); + exit_cb_called++; + ASSERT(exit_status == 1); + ASSERT(term_signal == 0); + uv_close((uv_handle_t*) process, close_cb); +} + + +static void fail_cb(uv_process_t* process, + int64_t exit_status, + int term_signal) { + ASSERT(0 && "fail_cb called"); +} + + +static void kill_cb(uv_process_t* process, + int64_t exit_status, + int term_signal) { + int err; + + printf("exit_cb\n"); + exit_cb_called++; +#ifdef _WIN32 + ASSERT(exit_status == 1); +#else + ASSERT(exit_status == 0); +#endif +#if defined(__APPLE__) || defined(__MVS__) + /* + * At least starting with Darwin Kernel Version 16.4.0, sending a SIGTERM to a + * process that is still starting up kills it with SIGKILL instead of SIGTERM. + * See: https://github.com/libuv/libuv/issues/1226 + */ + ASSERT(no_term_signal || term_signal == SIGTERM || term_signal == SIGKILL); +#else + ASSERT(no_term_signal || term_signal == SIGTERM); +#endif + uv_close((uv_handle_t*) process, close_cb); + + /* + * Sending signum == 0 should check if the + * child process is still alive, not kill it. + * This process should be dead. + */ + err = uv_kill(process->pid, 0); + ASSERT(err == UV_ESRCH); +} + +static void detach_failure_cb(uv_process_t* process, + int64_t exit_status, + int term_signal) { + printf("detach_cb\n"); + exit_cb_called++; +} + +static void on_alloc(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + buf->base = output + output_used; + buf->len = OUTPUT_SIZE - output_used; +} + + +static void on_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { + if (nread > 0) { + output_used += nread; + } else if (nread < 0) { + ASSERT(nread == UV_EOF); + uv_close((uv_handle_t*) tcp, close_cb); + } +} + + +static void on_read_once(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { + uv_read_stop(tcp); + on_read(tcp, nread, buf); +} + + +static void write_cb(uv_write_t* req, int status) { + ASSERT(status == 0); + uv_close((uv_handle_t*) req->handle, close_cb); +} + + +static void write_null_cb(uv_write_t* req, int status) { + ASSERT(status == 0); +} + + +static void init_process_options(char* test, uv_exit_cb exit_cb) { + /* Note spawn_helper1 defined in test/run-tests.c */ + int r = uv_exepath(exepath, &exepath_size); + ASSERT(r == 0); + exepath[exepath_size] = '\0'; + args[0] = exepath; + args[1] = test; + args[2] = NULL; + args[3] = NULL; + args[4] = NULL; + options.file = exepath; + options.args = args; + options.exit_cb = exit_cb; + options.flags = 0; +} + + +static void timer_cb(uv_timer_t* handle) { + uv_process_kill(&process, SIGTERM); + uv_close((uv_handle_t*) handle, close_cb); +} + + +static void timer_counter_cb(uv_timer_t* handle) { + ++timer_counter; +} + + +TEST_IMPL(spawn_fails) { + int r; + + init_process_options("", fail_cb); + options.file = options.args[0] = "program-that-had-better-not-exist"; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == UV_ENOENT || r == UV_EACCES); + ASSERT(0 == uv_is_active((uv_handle_t*) &process)); + uv_close((uv_handle_t*) &process, NULL); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +#ifndef _WIN32 +TEST_IMPL(spawn_fails_check_for_waitpid_cleanup) { + int r; + int status; + int err; + + init_process_options("", fail_cb); + options.file = options.args[0] = "program-that-had-better-not-exist"; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == UV_ENOENT || r == UV_EACCES); + ASSERT(0 == uv_is_active((uv_handle_t*) &process)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + /* verify the child is successfully cleaned up within libuv */ + do + err = waitpid(process.pid, &status, 0); + while (err == -1 && errno == EINTR); + + ASSERT(err == -1); + ASSERT(errno == ECHILD); + + uv_close((uv_handle_t*) &process, NULL); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + + +TEST_IMPL(spawn_empty_env) { + char* env[1]; + + /* The autotools dynamic library build requires the presence of + * DYLD_LIBARY_PATH (macOS) or LD_LIBRARY_PATH/LIBPATH (other Unices) + * in the environment, but of course that doesn't work with + * the empty environment that we're testing here. + */ + if (NULL != getenv("DYLD_LIBRARY_PATH") || + NULL != getenv("LD_LIBRARY_PATH") || + NULL != getenv("LIBPATH")) { + RETURN_SKIP("doesn't work with DYLD_LIBRARY_PATH/LD_LIBRARY_PATH/LIBPATH"); + } + + init_process_options("spawn_helper1", exit_cb); + options.env = env; + env[0] = NULL; + + ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_exit_code) { + int r; + + init_process_options("spawn_helper1", exit_cb); + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_stdout) { + int r; + uv_pipe_t out; + uv_stdio_container_t stdio[2]; + + init_process_options("spawn_helper2", exit_cb); + + uv_pipe_init(uv_default_loop(), &out, 0); + options.stdio = stdio; + options.stdio[0].flags = UV_IGNORE; + options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; + options.stdio[1].data.stream = (uv_stream_t*) &out; + options.stdio_count = 2; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 2); /* Once for process once for the pipe. */ + printf("output is: %s", output); + ASSERT(strcmp("hello world\n", output) == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_stdout_to_file) { + int r; + uv_file file; + uv_fs_t fs_req; + uv_stdio_container_t stdio[2]; + uv_buf_t buf; + + /* Setup. */ + unlink("stdout_file"); + + init_process_options("spawn_helper2", exit_cb); + + r = uv_fs_open(NULL, &fs_req, "stdout_file", O_CREAT | O_RDWR, + S_IRUSR | S_IWUSR, NULL); + ASSERT(r != -1); + uv_fs_req_cleanup(&fs_req); + + file = r; + + options.stdio = stdio; + options.stdio[0].flags = UV_IGNORE; + options.stdio[1].flags = UV_INHERIT_FD; + options.stdio[1].data.fd = file; + options.stdio_count = 2; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 1); + + buf = uv_buf_init(output, sizeof(output)); + r = uv_fs_read(NULL, &fs_req, file, &buf, 1, 0, NULL); + ASSERT(r == 12); + uv_fs_req_cleanup(&fs_req); + + r = uv_fs_close(NULL, &fs_req, file, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&fs_req); + + printf("output is: %s", output); + ASSERT(strcmp("hello world\n", output) == 0); + + /* Cleanup. */ + unlink("stdout_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_stdout_and_stderr_to_file) { + int r; + uv_file file; + uv_fs_t fs_req; + uv_stdio_container_t stdio[3]; + uv_buf_t buf; + + /* Setup. */ + unlink("stdout_file"); + + init_process_options("spawn_helper6", exit_cb); + + r = uv_fs_open(NULL, &fs_req, "stdout_file", O_CREAT | O_RDWR, + S_IRUSR | S_IWUSR, NULL); + ASSERT(r != -1); + uv_fs_req_cleanup(&fs_req); + + file = r; + + options.stdio = stdio; + options.stdio[0].flags = UV_IGNORE; + options.stdio[1].flags = UV_INHERIT_FD; + options.stdio[1].data.fd = file; + options.stdio[2].flags = UV_INHERIT_FD; + options.stdio[2].data.fd = file; + options.stdio_count = 3; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 1); + + buf = uv_buf_init(output, sizeof(output)); + r = uv_fs_read(NULL, &fs_req, file, &buf, 1, 0, NULL); + ASSERT(r == 27); + uv_fs_req_cleanup(&fs_req); + + r = uv_fs_close(NULL, &fs_req, file, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&fs_req); + + printf("output is: %s", output); + ASSERT(strcmp("hello world\nhello errworld\n", output) == 0); + + /* Cleanup. */ + unlink("stdout_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_stdout_and_stderr_to_file2) { +#ifndef _WIN32 + int r; + uv_file file; + uv_fs_t fs_req; + uv_stdio_container_t stdio[3]; + uv_buf_t buf; + + /* Setup. */ + unlink("stdout_file"); + + init_process_options("spawn_helper6", exit_cb); + + /* Replace stderr with our file */ + r = uv_fs_open(NULL, + &fs_req, + "stdout_file", + O_CREAT | O_RDWR, + S_IRUSR | S_IWUSR, + NULL); + ASSERT(r != -1); + uv_fs_req_cleanup(&fs_req); + file = dup2(r, STDERR_FILENO); + ASSERT(file != -1); + + options.stdio = stdio; + options.stdio[0].flags = UV_IGNORE; + options.stdio[1].flags = UV_INHERIT_FD; + options.stdio[1].data.fd = file; + options.stdio[2].flags = UV_INHERIT_FD; + options.stdio[2].data.fd = file; + options.stdio_count = 3; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 1); + + buf = uv_buf_init(output, sizeof(output)); + r = uv_fs_read(NULL, &fs_req, file, &buf, 1, 0, NULL); + ASSERT(r == 27); + uv_fs_req_cleanup(&fs_req); + + r = uv_fs_close(NULL, &fs_req, file, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&fs_req); + + printf("output is: %s", output); + ASSERT(strcmp("hello world\nhello errworld\n", output) == 0); + + /* Cleanup. */ + unlink("stdout_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +#else + RETURN_SKIP("Unix only test"); +#endif +} + + +TEST_IMPL(spawn_stdout_and_stderr_to_file_swap) { +#ifndef _WIN32 + int r; + uv_file stdout_file; + uv_file stderr_file; + uv_fs_t fs_req; + uv_stdio_container_t stdio[3]; + uv_buf_t buf; + + /* Setup. */ + unlink("stdout_file"); + unlink("stderr_file"); + + init_process_options("spawn_helper6", exit_cb); + + /* open 'stdout_file' and replace STDOUT_FILENO with it */ + r = uv_fs_open(NULL, + &fs_req, + "stdout_file", + O_CREAT | O_RDWR, + S_IRUSR | S_IWUSR, + NULL); + ASSERT(r != -1); + uv_fs_req_cleanup(&fs_req); + stdout_file = dup2(r, STDOUT_FILENO); + ASSERT(stdout_file != -1); + + /* open 'stderr_file' and replace STDERR_FILENO with it */ + r = uv_fs_open(NULL, &fs_req, "stderr_file", O_CREAT | O_RDWR, + S_IRUSR | S_IWUSR, NULL); + ASSERT(r != -1); + uv_fs_req_cleanup(&fs_req); + stderr_file = dup2(r, STDERR_FILENO); + ASSERT(stderr_file != -1); + + /* now we're going to swap them: the child process' stdout will be our + * stderr_file and vice versa */ + options.stdio = stdio; + options.stdio[0].flags = UV_IGNORE; + options.stdio[1].flags = UV_INHERIT_FD; + options.stdio[1].data.fd = stderr_file; + options.stdio[2].flags = UV_INHERIT_FD; + options.stdio[2].data.fd = stdout_file; + options.stdio_count = 3; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 1); + + buf = uv_buf_init(output, sizeof(output)); + + /* check the content of stdout_file */ + r = uv_fs_read(NULL, &fs_req, stdout_file, &buf, 1, 0, NULL); + ASSERT(r >= 15); + uv_fs_req_cleanup(&fs_req); + + r = uv_fs_close(NULL, &fs_req, stdout_file, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&fs_req); + + printf("output is: %s", output); + ASSERT(strncmp("hello errworld\n", output, 15) == 0); + + /* check the content of stderr_file */ + r = uv_fs_read(NULL, &fs_req, stderr_file, &buf, 1, 0, NULL); + ASSERT(r >= 12); + uv_fs_req_cleanup(&fs_req); + + r = uv_fs_close(NULL, &fs_req, stderr_file, NULL); + ASSERT(r == 0); + uv_fs_req_cleanup(&fs_req); + + printf("output is: %s", output); + ASSERT(strncmp("hello world\n", output, 12) == 0); + + /* Cleanup. */ + unlink("stdout_file"); + unlink("stderr_file"); + + MAKE_VALGRIND_HAPPY(); + return 0; +#else + RETURN_SKIP("Unix only test"); +#endif +} + + +TEST_IMPL(spawn_stdin) { + int r; + uv_pipe_t out; + uv_pipe_t in; + uv_write_t write_req; + uv_buf_t buf; + uv_stdio_container_t stdio[2]; + char buffer[] = "hello-from-spawn_stdin"; + + init_process_options("spawn_helper3", exit_cb); + + uv_pipe_init(uv_default_loop(), &out, 0); + uv_pipe_init(uv_default_loop(), &in, 0); + options.stdio = stdio; + options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; + options.stdio[0].data.stream = (uv_stream_t*) ∈ + options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; + options.stdio[1].data.stream = (uv_stream_t*) &out; + options.stdio_count = 2; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + buf.base = buffer; + buf.len = sizeof(buffer); + r = uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 3); /* Once for process twice for the pipe. */ + ASSERT(strcmp(buffer, output) == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_stdio_greater_than_3) { + int r; + uv_pipe_t pipe; + uv_stdio_container_t stdio[4]; + + init_process_options("spawn_helper5", exit_cb); + + uv_pipe_init(uv_default_loop(), &pipe, 0); + options.stdio = stdio; + options.stdio[0].flags = UV_IGNORE; + options.stdio[1].flags = UV_IGNORE; + options.stdio[2].flags = UV_IGNORE; + options.stdio[3].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; + options.stdio[3].data.stream = (uv_stream_t*) &pipe; + options.stdio_count = 4; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*) &pipe, on_alloc, on_read); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 2); /* Once for process once for the pipe. */ + printf("output from stdio[3] is: %s", output); + ASSERT(strcmp("fourth stdio!\n", output) == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +int spawn_tcp_server_helper(void) { + uv_tcp_t tcp; + uv_os_sock_t handle; + int r; + + r = uv_tcp_init(uv_default_loop(), &tcp); + ASSERT(r == 0); + +#ifdef _WIN32 + handle = _get_osfhandle(3); +#else + handle = 3; +#endif + r = uv_tcp_open(&tcp, handle); + ASSERT(r == 0); + + /* Make sure that we can listen on a socket that was + * passed down from the parent process + */ + r = uv_listen((uv_stream_t*) &tcp, SOMAXCONN, NULL); + ASSERT(r == 0); + + return 1; +} + + +TEST_IMPL(spawn_tcp_server) { + uv_stdio_container_t stdio[4]; + struct sockaddr_in addr; + int fd; + int r; +#ifdef _WIN32 + uv_os_fd_t handle; +#endif + + init_process_options("spawn_tcp_server_helper", exit_cb); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + fd = -1; + r = uv_tcp_init_ex(uv_default_loop(), &tcp_server, AF_INET); + ASSERT(r == 0); + r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); +#ifdef _WIN32 + r = uv_fileno((uv_handle_t*) &tcp_server, &handle); + fd = _open_osfhandle((intptr_t) handle, 0); +#else + r = uv_fileno((uv_handle_t*) &tcp_server, &fd); + #endif + ASSERT(r == 0); + ASSERT(fd > 0); + + options.stdio = stdio; + options.stdio[0].flags = UV_INHERIT_FD; + options.stdio[0].data.fd = 0; + options.stdio[1].flags = UV_INHERIT_FD; + options.stdio[1].data.fd = 1; + options.stdio[2].flags = UV_INHERIT_FD; + options.stdio[2].data.fd = 2; + options.stdio[3].flags = UV_INHERIT_FD; + options.stdio[3].data.fd = fd; + options.stdio_count = 4; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_ignored_stdio) { + int r; + + init_process_options("spawn_helper6", exit_cb); + + options.stdio = NULL; + options.stdio_count = 0; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_and_kill) { + int r; + + init_process_options("spawn_helper4", kill_cb); + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + r = uv_timer_init(uv_default_loop(), &timer); + ASSERT(r == 0); + + r = uv_timer_start(&timer, timer_cb, 500, 0); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 2); /* Once for process and once for timer. */ + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_preserve_env) { + int r; + uv_pipe_t out; + uv_stdio_container_t stdio[2]; + + init_process_options("spawn_helper7", exit_cb); + + uv_pipe_init(uv_default_loop(), &out, 0); + options.stdio = stdio; + options.stdio[0].flags = UV_IGNORE; + options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; + options.stdio[1].data.stream = (uv_stream_t*) &out; + options.stdio_count = 2; + + r = putenv("ENV_TEST=testval"); + ASSERT(r == 0); + + /* Explicitly set options.env to NULL to test for env clobbering. */ + options.env = NULL; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 2); + + printf("output is: %s", output); + ASSERT(strcmp("testval", output) == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_detached) { + int r; + + init_process_options("spawn_helper4", detach_failure_cb); + + options.flags |= UV_PROCESS_DETACHED; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + uv_unref((uv_handle_t*) &process); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 0); + + ASSERT(process.pid == uv_process_get_pid(&process)); + + r = uv_kill(process.pid, 0); + ASSERT(r == 0); + + r = uv_kill(process.pid, SIGTERM); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(spawn_and_kill_with_std) { + int r; + uv_pipe_t in, out, err; + uv_write_t write; + char message[] = "Nancy's joining me because the message this evening is " + "not my message but ours."; + uv_buf_t buf; + uv_stdio_container_t stdio[3]; + + init_process_options("spawn_helper4", kill_cb); + + r = uv_pipe_init(uv_default_loop(), &in, 0); + ASSERT(r == 0); + + r = uv_pipe_init(uv_default_loop(), &out, 0); + ASSERT(r == 0); + + r = uv_pipe_init(uv_default_loop(), &err, 0); + ASSERT(r == 0); + + options.stdio = stdio; + options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; + options.stdio[0].data.stream = (uv_stream_t*) ∈ + options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; + options.stdio[1].data.stream = (uv_stream_t*) &out; + options.stdio[2].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; + options.stdio[2].data.stream = (uv_stream_t*) &err; + options.stdio_count = 3; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + buf = uv_buf_init(message, sizeof message); + r = uv_write(&write, (uv_stream_t*) &in, &buf, 1, write_cb); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*) &err, on_alloc, on_read); + ASSERT(r == 0); + + r = uv_timer_init(uv_default_loop(), &timer); + ASSERT(r == 0); + + r = uv_timer_start(&timer, timer_cb, 500, 0); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 5); /* process x 1, timer x 1, stdio x 3. */ + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_and_ping) { + uv_write_t write_req; + uv_pipe_t in, out; + uv_buf_t buf; + uv_stdio_container_t stdio[2]; + int r; + + init_process_options("spawn_helper3", exit_cb); + buf = uv_buf_init("TEST", 4); + + uv_pipe_init(uv_default_loop(), &out, 0); + uv_pipe_init(uv_default_loop(), &in, 0); + options.stdio = stdio; + options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; + options.stdio[0].data.stream = (uv_stream_t*) ∈ + options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; + options.stdio[1].data.stream = (uv_stream_t*) &out; + options.stdio_count = 2; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + /* Sending signum == 0 should check if the + * child process is still alive, not kill it. + */ + r = uv_process_kill(&process, 0); + ASSERT(r == 0); + + r = uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(strcmp(output, "TEST") == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_same_stdout_stderr) { + uv_write_t write_req; + uv_pipe_t in, out; + uv_buf_t buf; + uv_stdio_container_t stdio[3]; + int r; + + init_process_options("spawn_helper3", exit_cb); + buf = uv_buf_init("TEST", 4); + + uv_pipe_init(uv_default_loop(), &out, 0); + uv_pipe_init(uv_default_loop(), &in, 0); + options.stdio = stdio; + options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; + options.stdio[0].data.stream = (uv_stream_t*) ∈ + options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; + options.stdio[1].data.stream = (uv_stream_t*) &out; + options.stdio_count = 2; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + /* Sending signum == 0 should check if the + * child process is still alive, not kill it. + */ + r = uv_process_kill(&process, 0); + ASSERT(r == 0); + + r = uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(strcmp(output, "TEST") == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_closed_process_io) { + uv_pipe_t in; + uv_write_t write_req; + uv_buf_t buf; + uv_stdio_container_t stdio[2]; + static char buffer[] = "hello-from-spawn_stdin\n"; + + init_process_options("spawn_helper3", exit_cb); + + uv_pipe_init(uv_default_loop(), &in, 0); + options.stdio = stdio; + options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; + options.stdio[0].data.stream = (uv_stream_t*) ∈ + options.stdio_count = 1; + + close(0); /* Close process stdin. */ + + ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options)); + + buf = uv_buf_init(buffer, sizeof(buffer)); + ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb)); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 2); /* process, child stdin */ + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(kill) { + int r; + +#ifdef _WIN32 + no_term_signal = 1; +#endif + + init_process_options("spawn_helper4", kill_cb); + + /* Verify that uv_spawn() resets the signal disposition. */ +#ifndef _WIN32 + { + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGTERM); + ASSERT(0 == pthread_sigmask(SIG_BLOCK, &set, NULL)); + } + ASSERT(SIG_ERR != signal(SIGTERM, SIG_IGN)); +#endif + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + +#ifndef _WIN32 + { + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGTERM); + ASSERT(0 == pthread_sigmask(SIG_UNBLOCK, &set, NULL)); + } + ASSERT(SIG_ERR != signal(SIGTERM, SIG_DFL)); +#endif + + /* Sending signum == 0 should check if the + * child process is still alive, not kill it. + */ + r = uv_kill(process.pid, 0); + ASSERT(r == 0); + + /* Kill the process. */ + r = uv_kill(process.pid, SIGTERM); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +#ifdef _WIN32 +TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) { + int r; + uv_pipe_t out; + char name[64]; + HANDLE pipe_handle; + uv_stdio_container_t stdio[2]; + + init_process_options("spawn_helper2", exit_cb); + + uv_pipe_init(uv_default_loop(), &out, 0); + options.stdio = stdio; + options.stdio[0].flags = UV_IGNORE; + options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE; + options.stdio[1].data.stream = (uv_stream_t*) &out; + options.stdio_count = 2; + + /* Create a pipe that'll cause a collision. */ + snprintf(name, + sizeof(name), + "\\\\.\\pipe\\uv\\%p-%d", + &out, + GetCurrentProcessId()); + pipe_handle = CreateNamedPipeA(name, + PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, + PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, + 10, + 65536, + 65536, + 0, + NULL); + ASSERT(pipe_handle != INVALID_HANDLE_VALUE); + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 2); /* Once for process once for the pipe. */ + printf("output is: %s", output); + ASSERT(strcmp("hello world\n", output) == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +#if !defined(USING_UV_SHARED) +int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr); +WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target); + +TEST_IMPL(argument_escaping) { + const WCHAR* test_str[] = { + L"", + L"HelloWorld", + L"Hello World", + L"Hello\"World", + L"Hello World\\", + L"Hello\\\"World", + L"Hello\\World", + L"Hello\\\\World", + L"Hello World\\", + L"c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\"" + }; + const int count = sizeof(test_str) / sizeof(*test_str); + WCHAR** test_output; + WCHAR* command_line; + WCHAR** cracked; + size_t total_size = 0; + int i; + int num_args; + int result; + + char* verbatim[] = { + "cmd.exe", + "/c", + "c:\\path\\to\\node.exe --eval \"require('c:\\\\path\\\\to\\\\test.js')\"", + NULL + }; + WCHAR* verbatim_output; + WCHAR* non_verbatim_output; + + test_output = calloc(count, sizeof(WCHAR*)); + ASSERT_NOT_NULL(test_output); + for (i = 0; i < count; ++i) { + test_output[i] = calloc(2 * (wcslen(test_str[i]) + 2), sizeof(WCHAR)); + quote_cmd_arg(test_str[i], test_output[i]); + wprintf(L"input : %s\n", test_str[i]); + wprintf(L"output: %s\n", test_output[i]); + total_size += wcslen(test_output[i]) + 1; + } + command_line = calloc(total_size + 1, sizeof(WCHAR)); + ASSERT_NOT_NULL(command_line); + for (i = 0; i < count; ++i) { + wcscat(command_line, test_output[i]); + wcscat(command_line, L" "); + } + command_line[total_size - 1] = L'\0'; + + wprintf(L"command_line: %s\n", command_line); + + cracked = CommandLineToArgvW(command_line, &num_args); + for (i = 0; i < num_args; ++i) { + wprintf(L"%d: %s\t%s\n", i, test_str[i], cracked[i]); + ASSERT(wcscmp(test_str[i], cracked[i]) == 0); + } + + LocalFree(cracked); + for (i = 0; i < count; ++i) { + free(test_output[i]); + } + free(test_output); + + result = make_program_args(verbatim, 1, &verbatim_output); + ASSERT(result == 0); + result = make_program_args(verbatim, 0, &non_verbatim_output); + ASSERT(result == 0); + + wprintf(L" verbatim_output: %s\n", verbatim_output); + wprintf(L"non_verbatim_output: %s\n", non_verbatim_output); + + ASSERT(wcscmp(verbatim_output, + L"cmd.exe /c c:\\path\\to\\node.exe --eval " + L"\"require('c:\\\\path\\\\to\\\\test.js')\"") == 0); + ASSERT(wcscmp(non_verbatim_output, + L"cmd.exe /c \"c:\\path\\to\\node.exe --eval " + L"\\\"require('c:\\\\path\\\\to\\\\test.js')\\\"\"") == 0); + + free(verbatim_output); + free(non_verbatim_output); + + return 0; +} + +int make_program_env(char** env_block, WCHAR** dst_ptr); + +TEST_IMPL(environment_creation) { + size_t i; + char* environment[] = { + "FOO=BAR", + "SYSTEM=ROOT", /* substring of a supplied var name */ + "SYSTEMROOTED=OMG", /* supplied var name is a substring */ + "TEMP=C:\\Temp", + "INVALID", + "BAZ=QUX", + "B_Z=QUX", + "B\xe2\x82\xacZ=QUX", + "B\xf0\x90\x80\x82Z=QUX", + "B\xef\xbd\xa1Z=QUX", + "B\xf0\xa3\x91\x96Z=QUX", + "BAZ", /* repeat, invalid variable */ + NULL + }; + WCHAR* wenvironment[] = { + L"BAZ=QUX", + L"B_Z=QUX", + L"B\x20acZ=QUX", + L"B\xd800\xdc02Z=QUX", + L"B\xd84d\xdc56Z=QUX", + L"B\xff61Z=QUX", + L"FOO=BAR", + L"SYSTEM=ROOT", /* substring of a supplied var name */ + L"SYSTEMROOTED=OMG", /* supplied var name is a substring */ + L"TEMP=C:\\Temp", + }; + WCHAR* from_env[] = { + /* list should be kept in sync with list + * in process.c, minus variables in wenvironment */ + L"HOMEDRIVE", + L"HOMEPATH", + L"LOGONSERVER", + L"PATH", + L"USERDOMAIN", + L"USERNAME", + L"USERPROFILE", + L"SYSTEMDRIVE", + L"SYSTEMROOT", + L"WINDIR", + /* test for behavior in the absence of a + * required-environment variable: */ + L"ZTHIS_ENV_VARIABLE_DOES_NOT_EXIST", + }; + int found_in_loc_env[ARRAY_SIZE(wenvironment)] = {0}; + int found_in_usr_env[ARRAY_SIZE(from_env)] = {0}; + WCHAR *expected[ARRAY_SIZE(from_env)]; + int result; + WCHAR* str; + WCHAR* prev; + WCHAR* env; + + for (i = 0; i < ARRAY_SIZE(from_env); i++) { + /* copy expected additions to environment locally */ + size_t len = GetEnvironmentVariableW(from_env[i], NULL, 0); + if (len == 0) { + found_in_usr_env[i] = 1; + str = malloc(1 * sizeof(WCHAR)); + *str = 0; + expected[i] = str; + } else { + size_t name_len = wcslen(from_env[i]); + str = malloc((name_len+1+len) * sizeof(WCHAR)); + wmemcpy(str, from_env[i], name_len); + expected[i] = str; + str += name_len; + *str++ = L'='; + GetEnvironmentVariableW(from_env[i], str, len); + } + } + + result = make_program_env(environment, &env); + ASSERT(result == 0); + + for (str = env, prev = NULL; *str; prev = str, str += wcslen(str) + 1) { + int found = 0; +#if 0 + _cputws(str); + putchar('\n'); +#endif + for (i = 0; i < ARRAY_SIZE(wenvironment) && !found; i++) { + if (!wcscmp(str, wenvironment[i])) { + ASSERT(!found_in_loc_env[i]); + found_in_loc_env[i] = 1; + found = 1; + } + } + for (i = 0; i < ARRAY_SIZE(expected) && !found; i++) { + if (!wcscmp(str, expected[i])) { + ASSERT(!found_in_usr_env[i]); + found_in_usr_env[i] = 1; + found = 1; + } + } + if (prev) { /* verify sort order */ +#if !defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR) + ASSERT(CompareStringOrdinal(prev, -1, str, -1, TRUE) == 1); +#endif + } + ASSERT(found); /* verify that we expected this variable */ + } + + /* verify that we found all expected variables */ + for (i = 0; i < ARRAY_SIZE(wenvironment); i++) { + ASSERT(found_in_loc_env[i]); + } + for (i = 0; i < ARRAY_SIZE(expected); i++) { + ASSERT(found_in_usr_env[i]); + } + + return 0; +} +#endif + +/* Regression test for issue #909 */ +TEST_IMPL(spawn_with_an_odd_path) { + int r; + + char newpath[2048]; + char *path = getenv("PATH"); + ASSERT_NOT_NULL(path); + snprintf(newpath, 2048, ";.;%s", path); + SetEnvironmentVariable("PATH", newpath); + + init_process_options("", exit_cb); + options.file = options.args[0] = "program-that-had-better-not-exist"; + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == UV_ENOENT || r == UV_EACCES); + ASSERT(0 == uv_is_active((uv_handle_t*) &process)); + uv_close((uv_handle_t*) &process, NULL); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + +#ifndef _WIN32 +TEST_IMPL(spawn_setuid_setgid) { + int r; + struct passwd* pw; + char uidstr[10]; + char gidstr[10]; + + /* if not root, then this will fail. */ + uv_uid_t uid = getuid(); + if (uid != 0) { + RETURN_SKIP("It should be run as root user"); + } + + init_process_options("spawn_helper_setuid_setgid", exit_cb); + + /* become the "nobody" user. */ + pw = getpwnam("nobody"); + ASSERT_NOT_NULL(pw); + options.uid = pw->pw_uid; + options.gid = pw->pw_gid; + snprintf(uidstr, sizeof(uidstr), "%d", pw->pw_uid); + snprintf(gidstr, sizeof(gidstr), "%d", pw->pw_gid); + options.args[2] = uidstr; + options.args[3] = gidstr; + options.flags = UV_PROCESS_SETUID | UV_PROCESS_SETGID; + + r = uv_spawn(uv_default_loop(), &process, &options); + if (r == UV_EACCES) + RETURN_SKIP("user 'nobody' cannot access the test runner"); + + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + + +#ifndef _WIN32 +TEST_IMPL(spawn_setuid_fails) { + int r; + + /* if root, become nobody. */ + /* On IBMi PASE, there is no nobody user. */ +#ifndef __PASE__ + uv_uid_t uid = getuid(); + if (uid == 0) { + struct passwd* pw; + pw = getpwnam("nobody"); + ASSERT_NOT_NULL(pw); + ASSERT(0 == setgid(pw->pw_gid)); + ASSERT(0 == setuid(pw->pw_uid)); + } +#endif /* !__PASE__ */ + + init_process_options("spawn_helper1", fail_cb); + + options.flags |= UV_PROCESS_SETUID; + /* On IBMi PASE, there is no root user. User may grant + * root-like privileges, including setting uid to 0. + */ +#if defined(__PASE__) + options.uid = -1; +#else + options.uid = 0; +#endif + + /* These flags should be ignored on Unices. */ + options.flags |= UV_PROCESS_WINDOWS_HIDE; + options.flags |= UV_PROCESS_WINDOWS_HIDE_CONSOLE; + options.flags |= UV_PROCESS_WINDOWS_HIDE_GUI; + options.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS; + + r = uv_spawn(uv_default_loop(), &process, &options); +#if defined(__CYGWIN__) + ASSERT(r == UV_EINVAL); +#else + ASSERT(r == UV_EPERM); +#endif + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(close_cb_called == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_setgid_fails) { + int r; + + /* if root, become nobody. */ + /* On IBMi PASE, there is no nobody user. */ +#ifndef __PASE__ + uv_uid_t uid = getuid(); + if (uid == 0) { + struct passwd* pw; + pw = getpwnam("nobody"); + ASSERT_NOT_NULL(pw); + ASSERT(0 == setgid(pw->pw_gid)); + ASSERT(0 == setuid(pw->pw_uid)); + } +#endif /* !__PASE__ */ + + init_process_options("spawn_helper1", fail_cb); + + options.flags |= UV_PROCESS_SETGID; + /* On IBMi PASE, there is no root user. User may grant + * root-like privileges, including setting gid to 0. + */ +#if defined(__MVS__) || defined(__PASE__) + options.gid = -1; +#else + options.gid = 0; +#endif + + r = uv_spawn(uv_default_loop(), &process, &options); +#if defined(__CYGWIN__) || defined(__MVS__) + ASSERT(r == UV_EINVAL); +#else + ASSERT(r == UV_EPERM); +#endif + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(close_cb_called == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + + +#ifdef _WIN32 + +static void exit_cb_unexpected(uv_process_t* process, + int64_t exit_status, + int term_signal) { + ASSERT(0 && "should not have been called"); +} + + +TEST_IMPL(spawn_setuid_fails) { + int r; + + init_process_options("spawn_helper1", exit_cb_unexpected); + + options.flags |= UV_PROCESS_SETUID; + options.uid = (uv_uid_t) -42424242; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == UV_ENOTSUP); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(close_cb_called == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_setgid_fails) { + int r; + + init_process_options("spawn_helper1", exit_cb_unexpected); + + options.flags |= UV_PROCESS_SETGID; + options.gid = (uv_gid_t) -42424242; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == UV_ENOTSUP); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(close_cb_called == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + + +TEST_IMPL(spawn_auto_unref) { + init_process_options("spawn_helper1", NULL); + ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(0 == uv_is_closing((uv_handle_t*) &process)); + uv_close((uv_handle_t*) &process, NULL); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(1 == uv_is_closing((uv_handle_t*) &process)); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_fs_open) { + int r; + uv_os_fd_t fd; + uv_os_fd_t dup_fd; + uv_fs_t fs_req; + uv_pipe_t in; + uv_write_t write_req; + uv_write_t write_req2; + uv_buf_t buf; + uv_stdio_container_t stdio[1]; +#ifdef _WIN32 + const char dev_null[] = "NUL"; + HMODULE kernelbase_module; + sCompareObjectHandles pCompareObjectHandles; /* function introduced in Windows 10 */ +#else + const char dev_null[] = "/dev/null"; +#endif + + r = uv_fs_open(NULL, &fs_req, dev_null, O_RDWR, 0, NULL); + ASSERT(r != -1); + fd = uv_get_osfhandle((uv_file) fs_req.result); + uv_fs_req_cleanup(&fs_req); + + init_process_options("spawn_helper8", exit_cb); + + ASSERT(0 == uv_pipe_init(uv_default_loop(), &in, 0)); + + options.stdio = stdio; + options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE; + options.stdio[0].data.stream = (uv_stream_t*) ∈ + options.stdio_count = 1; + + /* make an inheritable copy */ +#ifdef _WIN32 + ASSERT(0 != DuplicateHandle(GetCurrentProcess(), fd, GetCurrentProcess(), &dup_fd, + 0, /* inherit */ TRUE, DUPLICATE_SAME_ACCESS)); + kernelbase_module = GetModuleHandleA("kernelbase.dll"); + pCompareObjectHandles = (sCompareObjectHandles) + GetProcAddress(kernelbase_module, "CompareObjectHandles"); + ASSERT(pCompareObjectHandles == NULL || pCompareObjectHandles(fd, dup_fd)); +#else + dup_fd = dup(fd); +#endif + + ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options)); + + buf = uv_buf_init((char*) &fd, sizeof(fd)); + ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_null_cb)); + + buf = uv_buf_init((char*) &dup_fd, sizeof(fd)); + ASSERT(0 == uv_write(&write_req2, (uv_stream_t*) &in, &buf, 1, write_cb)); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(0 == uv_fs_close(NULL, &fs_req, r, NULL)); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 2); /* One for `in`, one for process */ + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(closed_fd_events) { + uv_stdio_container_t stdio[3]; + uv_pipe_t pipe_handle; + uv_fs_t req; + uv_buf_t bufs[1]; + uv_file fd[2]; + bufs[0] = uv_buf_init("", 1); + + /* create a pipe and share it with a child process */ + ASSERT(0 == uv_pipe(fd, 0, 0)); + ASSERT(fd[0] > 2); + ASSERT(fd[1] > 2); + + /* spawn_helper4 blocks indefinitely. */ + init_process_options("spawn_helper4", exit_cb); + options.stdio_count = 3; + options.stdio = stdio; + options.stdio[0].flags = UV_INHERIT_FD; + options.stdio[0].data.fd = fd[0]; + options.stdio[1].flags = UV_IGNORE; + options.stdio[2].flags = UV_IGNORE; + + ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options)); + uv_unref((uv_handle_t*) &process); + + /* read from the pipe with uv */ + ASSERT(0 == uv_pipe_init(uv_default_loop(), &pipe_handle, 0)); + ASSERT(0 == uv_pipe_open(&pipe_handle, fd[0])); + /* uv_pipe_open() takes ownership of the file descriptor. */ + fd[0] = -1; + + ASSERT(0 == uv_read_start((uv_stream_t*) &pipe_handle, on_alloc, on_read_once)); + + ASSERT(1 == uv_fs_write(NULL, &req, fd[1], bufs, 1, -1, NULL)); + ASSERT(req.result == 1); + uv_fs_req_cleanup(&req); + +#ifdef _WIN32 + ASSERT(1 == uv_run(uv_default_loop(), UV_RUN_ONCE)); +#endif + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); + + /* should have received just one byte */ + ASSERT(output_used == 1); + + /* close the pipe and see if we still get events */ + uv_close((uv_handle_t*) &pipe_handle, close_cb); + + ASSERT(1 == uv_fs_write(NULL, &req, fd[1], bufs, 1, -1, NULL)); + ASSERT(req.result == 1); + uv_fs_req_cleanup(&req); + + ASSERT(0 == uv_timer_init(uv_default_loop(), &timer)); + ASSERT(0 == uv_timer_start(&timer, timer_counter_cb, 10, 0)); + + /* see if any spurious events interrupt the timer */ + if (1 == uv_run(uv_default_loop(), UV_RUN_ONCE)) + /* have to run again to really trigger the timer */ + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); + + ASSERT(timer_counter == 1); + + /* cleanup */ + ASSERT(0 == uv_process_kill(&process, SIGTERM)); +#ifdef _WIN32 + ASSERT(0 == _close(fd[1])); +#else + ASSERT(0 == close(fd[1])); +#endif + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(spawn_reads_child_path) { + int r; + int len; + char file[64]; + char path[1024]; + char* env[3]; + + /* Need to carry over the dynamic linker path when the test runner is + * linked against libuv.so, see https://github.com/libuv/libuv/issues/85. + */ +#if defined(__APPLE__) + static const char dyld_path_var[] = "DYLD_LIBRARY_PATH"; +#elif defined(__MVS__) || defined(__PASE__) + static const char dyld_path_var[] = "LIBPATH"; +#else + static const char dyld_path_var[] = "LD_LIBRARY_PATH"; +#endif + + /* Set up the process, but make sure that the file to run is relative and + * requires a lookup into PATH. */ + init_process_options("spawn_helper1", exit_cb); + + /* Set up the PATH env variable */ + for (len = strlen(exepath); + exepath[len - 1] != '/' && exepath[len - 1] != '\\'; + len--); + strcpy(file, exepath + len); + exepath[len] = 0; + strcpy(path, "PATH="); + strcpy(path + 5, exepath); +#if defined(__CYGWIN__) || defined(__MSYS__) + /* Carry over the dynamic linker path in case the test runner + is linked against cyguv-1.dll or msys-uv-1.dll, see above. */ + { + char* syspath = getenv("PATH"); + if (syspath != NULL) { + strcat(path, ":"); + strcat(path, syspath); + } + } +#endif + + env[0] = path; + env[1] = getenv(dyld_path_var); + env[2] = NULL; + + if (env[1] != NULL) { + static char buf[1024 + sizeof(dyld_path_var)]; + snprintf(buf, sizeof(buf), "%s=%s", dyld_path_var, env[1]); + env[1] = buf; + } + + options.file = file; + options.args[0] = file; + options.env = env; + + r = uv_spawn(uv_default_loop(), &process, &options); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(spawn_inherit_streams) { + uv_process_t child_req; + uv_stdio_container_t child_stdio[2]; + int fds_stdin[2]; + int fds_stdout[2]; + uv_pipe_t pipe_stdin_child; + uv_pipe_t pipe_stdout_child; + uv_pipe_t pipe_stdin_parent; + uv_pipe_t pipe_stdout_parent; + unsigned char ubuf[OUTPUT_SIZE - 1]; + uv_buf_t buf; + unsigned int i; + int r; + int bidir; + uv_write_t write_req; + uv_loop_t* loop; + + init_process_options("spawn_helper9", exit_cb); + + loop = uv_default_loop(); + ASSERT(uv_pipe_init(loop, &pipe_stdin_child, 0) == 0); + ASSERT(uv_pipe_init(loop, &pipe_stdout_child, 0) == 0); + ASSERT(uv_pipe_init(loop, &pipe_stdin_parent, 0) == 0); + ASSERT(uv_pipe_init(loop, &pipe_stdout_parent, 0) == 0); + + ASSERT(uv_pipe(fds_stdin, 0, 0) == 0); + ASSERT(uv_pipe(fds_stdout, 0, 0) == 0); + + ASSERT(uv_pipe_open(&pipe_stdin_child, fds_stdin[0]) == 0); + ASSERT(uv_pipe_open(&pipe_stdout_child, fds_stdout[1]) == 0); + ASSERT(uv_pipe_open(&pipe_stdin_parent, fds_stdin[1]) == 0); + ASSERT(uv_pipe_open(&pipe_stdout_parent, fds_stdout[0]) == 0); + ASSERT(uv_is_readable((uv_stream_t*) &pipe_stdin_child)); + ASSERT(uv_is_writable((uv_stream_t*) &pipe_stdout_child)); + ASSERT(uv_is_writable((uv_stream_t*) &pipe_stdin_parent)); + ASSERT(uv_is_readable((uv_stream_t*) &pipe_stdout_parent)); + /* Some systems (SVR4) open a bidirectional pipe, most don't. */ + bidir = uv_is_writable((uv_stream_t*) &pipe_stdin_child); + ASSERT(uv_is_readable((uv_stream_t*) &pipe_stdout_child) == bidir); + ASSERT(uv_is_readable((uv_stream_t*) &pipe_stdin_parent) == bidir); + ASSERT(uv_is_writable((uv_stream_t*) &pipe_stdout_parent) == bidir); + + child_stdio[0].flags = UV_INHERIT_STREAM; + child_stdio[0].data.stream = (uv_stream_t *) &pipe_stdin_child; + + child_stdio[1].flags = UV_INHERIT_STREAM; + child_stdio[1].data.stream = (uv_stream_t *) &pipe_stdout_child; + + options.stdio = child_stdio; + options.stdio_count = 2; + + ASSERT(uv_spawn(loop, &child_req, &options) == 0); + + uv_close((uv_handle_t*) &pipe_stdin_child, NULL); + uv_close((uv_handle_t*) &pipe_stdout_child, NULL); + + buf = uv_buf_init((char*) ubuf, sizeof ubuf); + for (i = 0; i < sizeof ubuf; ++i) + ubuf[i] = i & 255u; + memset(output, 0, sizeof ubuf); + + r = uv_write(&write_req, + (uv_stream_t*) &pipe_stdin_parent, + &buf, + 1, + write_cb); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*) &pipe_stdout_parent, on_alloc, on_read); + ASSERT(r == 0); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 3); + + r = memcmp(ubuf, output, sizeof ubuf); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(spawn_quoted_path) { +#ifndef _WIN32 + RETURN_SKIP("Test for Windows"); +#else + char* quoted_path_env[2]; + args[0] = "not_existing"; + args[1] = NULL; + options.file = args[0]; + options.args = args; + options.exit_cb = exit_cb; + options.flags = 0; + /* We test if search_path works correctly with semicolons in quoted path. We + * will use an invalid drive, so we are sure no executable is spawned. */ + quoted_path_env[0] = "PATH=\"xyz:\\test;\";xyz:\\other"; + quoted_path_env[1] = NULL; + options.env = quoted_path_env; + + /* We test if libuv will not segfault. */ + uv_spawn(uv_default_loop(), &process, &options); + + MAKE_VALGRIND_HAPPY(); + return 0; +#endif +} + +/* Helper for child process of spawn_inherit_streams */ +#ifndef _WIN32 +void spawn_stdin_stdout(void) { + char buf[1024]; + char* pbuf; + for (;;) { + ssize_t r, w, c; + do { + r = read(0, buf, sizeof buf); + } while (r == -1 && errno == EINTR); + if (r == 0) { + return; + } + ASSERT(r > 0); + c = r; + pbuf = buf; + while (c) { + do { + w = write(1, pbuf, (size_t)c); + } while (w == -1 && errno == EINTR); + ASSERT(w >= 0); + pbuf = pbuf + w; + c = c - w; + } + } +} +#else +void spawn_stdin_stdout(void) { + char buf[1024]; + char* pbuf; + HANDLE h_stdin = GetStdHandle(STD_INPUT_HANDLE); + HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE); + ASSERT(h_stdin != INVALID_HANDLE_VALUE); + ASSERT(h_stdout != INVALID_HANDLE_VALUE); + for (;;) { + DWORD n_read; + DWORD n_written; + DWORD to_write; + if (!ReadFile(h_stdin, buf, sizeof buf, &n_read, NULL)) { + ASSERT(GetLastError() == ERROR_BROKEN_PIPE); + return; + } + to_write = n_read; + pbuf = buf; + while (to_write) { + ASSERT(WriteFile(h_stdout, pbuf, to_write, &n_written, NULL)); + to_write -= n_written; + pbuf += n_written; + } + } +} +#endif /* !_WIN32 */ diff --git a/external/src/libuv/test/test-stdio-over-pipes.c b/external/src/libuv/test/test-stdio-over-pipes.c new file mode 100644 index 0000000..1aed471 --- /dev/null +++ b/external/src/libuv/test/test-stdio-over-pipes.c @@ -0,0 +1,299 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + + +static char exepath[1024]; +static size_t exepath_size = 1024; +static char* args[3]; +static uv_process_options_t options; +static int close_cb_called; +static int exit_cb_called; +static int on_read_cb_called; +static int after_write_cb_called; +static uv_pipe_t in; +static uv_pipe_t out; +static uv_loop_t* loop; +#define OUTPUT_SIZE 1024 +static char output[OUTPUT_SIZE]; +static int output_used; + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + + +static void exit_cb(uv_process_t* process, + int64_t exit_status, + int term_signal) { + printf("exit_cb\n"); + exit_cb_called++; + ASSERT(exit_status == 0); + ASSERT(term_signal == 0); + uv_close((uv_handle_t*)process, close_cb); + uv_close((uv_handle_t*)&in, close_cb); + uv_close((uv_handle_t*)&out, close_cb); +} + + +static void init_process_options(char* test, uv_exit_cb exit_cb) { + int r = uv_exepath(exepath, &exepath_size); + ASSERT(r == 0); + exepath[exepath_size] = '\0'; + args[0] = exepath; + args[1] = test; + args[2] = NULL; + options.file = exepath; + options.args = args; + options.exit_cb = exit_cb; +} + + +static void on_alloc(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + buf->base = output + output_used; + buf->len = OUTPUT_SIZE - output_used; +} + + +static void after_write(uv_write_t* req, int status) { + if (status) { + fprintf(stderr, "uv_write error: %s\n", uv_strerror(status)); + ASSERT(0); + } + + /* Free the read/write buffer and the request */ + free(req); + + after_write_cb_called++; +} + + +static void on_read(uv_stream_t* pipe, ssize_t nread, const uv_buf_t* rdbuf) { + uv_write_t* req; + uv_buf_t wrbuf; + int r; + + ASSERT(nread > 0 || nread == UV_EOF); + + if (nread > 0) { + output_used += nread; + if (output_used % 12 == 0) { + ASSERT(memcmp("hello world\n", output, 12) == 0); + wrbuf = uv_buf_init(output, 12); + req = malloc(sizeof(*req)); + r = uv_write(req, (uv_stream_t*) &in, &wrbuf, 1, after_write); + ASSERT(r == 0); + } + } + + on_read_cb_called++; +} + + +static void test_stdio_over_pipes(int overlapped) { + int r; + uv_process_t process; + uv_stdio_container_t stdio[3]; + + loop = uv_default_loop(); + + init_process_options("stdio_over_pipes_helper", exit_cb); + + uv_pipe_init(loop, &out, 0); + uv_pipe_init(loop, &in, 0); + + options.stdio = stdio; + options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE | + (overlapped ? UV_OVERLAPPED_PIPE : 0); + options.stdio[0].data.stream = (uv_stream_t*) ∈ + options.stdio[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE | + (overlapped ? UV_OVERLAPPED_PIPE : 0); + options.stdio[1].data.stream = (uv_stream_t*) &out; + options.stdio[2].flags = UV_INHERIT_FD; + options.stdio[2].data.fd = 2; + options.stdio_count = 3; + + r = uv_spawn(loop, &process, &options); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*) &out, on_alloc, on_read); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(on_read_cb_called > 1); + ASSERT(after_write_cb_called == 2); + ASSERT(exit_cb_called == 1); + ASSERT(close_cb_called == 3); + ASSERT(memcmp("hello world\nhello world\n", output, 24) == 0); + ASSERT(output_used == 24); + + MAKE_VALGRIND_HAPPY(); +} + +TEST_IMPL(stdio_over_pipes) { + test_stdio_over_pipes(0); + return 0; +} + +TEST_IMPL(stdio_emulate_iocp) { + test_stdio_over_pipes(1); + return 0; +} + + +/* Everything here runs in a child process. */ + +static int on_pipe_read_called; +static int after_write_called; +static uv_pipe_t stdin_pipe1; +static uv_pipe_t stdout_pipe1; +static uv_pipe_t stdin_pipe2; +static uv_pipe_t stdout_pipe2; + +static void on_pipe_read(uv_stream_t* pipe, ssize_t nread, const uv_buf_t* buf) { + ASSERT(nread > 0); + ASSERT(memcmp("hello world\n", buf->base, nread) == 0); + on_pipe_read_called++; + + free(buf->base); + + uv_read_stop(pipe); +} + + +static void after_pipe_write(uv_write_t* req, int status) { + ASSERT(status == 0); + after_write_called++; +} + + +static void on_read_alloc(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + buf->base = malloc(suggested_size); + buf->len = suggested_size; +} + + +int stdio_over_pipes_helper(void) { + /* Write several buffers to test that the write order is preserved. */ + char* buffers[] = { + "he", + "ll", + "o ", + "wo", + "rl", + "d", + "\n" + }; + + uv_write_t write_req[ARRAY_SIZE(buffers)]; + uv_buf_t buf[ARRAY_SIZE(buffers)]; + unsigned int i; + int j; + int r; + uv_loop_t* loop = uv_default_loop(); + + ASSERT(UV_NAMED_PIPE == uv_guess_handle(0)); + ASSERT(UV_NAMED_PIPE == uv_guess_handle(1)); + + r = uv_pipe_init(loop, &stdin_pipe1, 0); + ASSERT(r == 0); + r = uv_pipe_init(loop, &stdout_pipe1, 0); + ASSERT(r == 0); + r = uv_pipe_init(loop, &stdin_pipe2, 0); + ASSERT(r == 0); + r = uv_pipe_init(loop, &stdout_pipe2, 0); + ASSERT(r == 0); + + uv_pipe_open(&stdin_pipe1, 0); + uv_pipe_open(&stdout_pipe1, 1); + uv_pipe_open(&stdin_pipe2, 0); + uv_pipe_open(&stdout_pipe2, 1); + + for (j = 0; j < 2; j++) { + /* Unref both stdio handles to make sure that all writes complete. */ + uv_unref((uv_handle_t*) &stdin_pipe1); + uv_unref((uv_handle_t*) &stdout_pipe1); + uv_unref((uv_handle_t*) &stdin_pipe2); + uv_unref((uv_handle_t*) &stdout_pipe2); + + for (i = 0; i < ARRAY_SIZE(buffers); i++) { + buf[i] = uv_buf_init((char*) buffers[i], strlen(buffers[i])); + } + + for (i = 0; i < ARRAY_SIZE(buffers); i++) { + r = uv_write(&write_req[i], + (uv_stream_t*) (j == 0 ? &stdout_pipe1 : &stdout_pipe2), + &buf[i], + 1, + after_pipe_write); + ASSERT(r == 0); + } + + notify_parent_process(); + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(after_write_called == 7 * (j + 1)); + ASSERT(on_pipe_read_called == j); + ASSERT(close_cb_called == 0); + + uv_ref((uv_handle_t*) &stdout_pipe1); + uv_ref((uv_handle_t*) &stdin_pipe1); + uv_ref((uv_handle_t*) &stdout_pipe2); + uv_ref((uv_handle_t*) &stdin_pipe2); + + r = uv_read_start((uv_stream_t*) (j == 0 ? &stdin_pipe1 : &stdin_pipe2), + on_read_alloc, + on_pipe_read); + ASSERT(r == 0); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(after_write_called == 7 * (j + 1)); + ASSERT(on_pipe_read_called == j + 1); + ASSERT(close_cb_called == 0); + } + + uv_close((uv_handle_t*)&stdin_pipe1, close_cb); + uv_close((uv_handle_t*)&stdout_pipe1, close_cb); + uv_close((uv_handle_t*)&stdin_pipe2, close_cb); + uv_close((uv_handle_t*)&stdout_pipe2, close_cb); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(after_write_called == 14); + ASSERT(on_pipe_read_called == 2); + ASSERT(close_cb_called == 4); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-strscpy.c b/external/src/libuv/test/test-strscpy.c new file mode 100644 index 0000000..4e7db6f --- /dev/null +++ b/external/src/libuv/test/test-strscpy.c @@ -0,0 +1,53 @@ +/* Copyright libuv project contributors. All rights reserved. +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to +* deal in the Software without restriction, including without limitation the +* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +* sell copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +* IN THE SOFTWARE. +*/ + +#include "uv.h" +#include "task.h" +#include + +#include "../src/strscpy.h" +#include "../src/strscpy.c" + +TEST_IMPL(strscpy) { + char d[4]; + + ASSERT(0 == uv__strscpy(d, "", 0)); + ASSERT(0 == uv__strscpy(d, "x", 0)); + + memset(d, 0, sizeof(d)); + ASSERT(1 == uv__strscpy(d, "x", sizeof(d))); + ASSERT(0 == memcmp(d, "x\0\0", sizeof(d))); + + memset(d, 0, sizeof(d)); + ASSERT(2 == uv__strscpy(d, "xy", sizeof(d))); + ASSERT(0 == memcmp(d, "xy\0", sizeof(d))); + + ASSERT(3 == uv__strscpy(d, "xyz", sizeof(d))); + ASSERT(0 == memcmp(d, "xyz", sizeof(d))); + + ASSERT(UV_E2BIG == uv__strscpy(d, "xyzz", sizeof(d))); + ASSERT(0 == memcmp(d, "xyz", sizeof(d))); + + ASSERT(UV_E2BIG == uv__strscpy(d, "xyzzy", sizeof(d))); + ASSERT(0 == memcmp(d, "xyz", sizeof(d))); + + return 0; +} diff --git a/external/src/libuv/test/test-tcp-alloc-cb-fail.c b/external/src/libuv/test/test-tcp-alloc-cb-fail.c new file mode 100644 index 0000000..b6f4ca3 --- /dev/null +++ b/external/src/libuv/test/test-tcp-alloc-cb-fail.c @@ -0,0 +1,123 @@ +/* Copyright libuv project and contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "uv.h" +#include "task.h" + +static uv_tcp_t server; +static uv_tcp_t client; +static uv_tcp_t incoming; +static int connect_cb_called; +static int close_cb_called; +static int connection_cb_called; +static uv_write_t write_req; + +static char hello[] = "HELLO!"; + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + +static void write_cb(uv_write_t* req, int status) { + ASSERT(status == 0); +} + +static void conn_alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + /* Do nothing, read_cb should be called with UV_ENOBUFS. */ +} + +static void conn_read_cb(uv_stream_t* stream, + ssize_t nread, + const uv_buf_t* buf) { + ASSERT(nread == UV_ENOBUFS); + ASSERT_NULL(buf->base); + ASSERT(buf->len == 0); + + uv_close((uv_handle_t*) &incoming, close_cb); + uv_close((uv_handle_t*) &client, close_cb); + uv_close((uv_handle_t*) &server, close_cb); +} + +static void connect_cb(uv_connect_t* req, int status) { + int r; + uv_buf_t buf; + + ASSERT(status == 0); + connect_cb_called++; + + buf = uv_buf_init(hello, sizeof(hello)); + r = uv_write(&write_req, req->handle, &buf, 1, write_cb); + ASSERT(r == 0); +} + + +static void connection_cb(uv_stream_t* tcp, int status) { + ASSERT(status == 0); + + ASSERT(0 == uv_tcp_init(tcp->loop, &incoming)); + ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming)); + ASSERT(0 == uv_read_start((uv_stream_t*) &incoming, + conn_alloc_cb, + conn_read_cb)); + + connection_cb_called++; +} + + +static void start_server(void) { + struct sockaddr_in addr; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + ASSERT(0 == uv_tcp_init(uv_default_loop(), &server)); + ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr, 0)); + ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, connection_cb)); +} + + +TEST_IMPL(tcp_alloc_cb_fail) { + uv_connect_t connect_req; + struct sockaddr_in addr; + + start_server(); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + ASSERT(0 == uv_tcp_init(uv_default_loop(), &client)); + ASSERT(0 == uv_tcp_connect(&connect_req, + &client, + (struct sockaddr*) &addr, + connect_cb)); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + ASSERT(connect_cb_called == 1); + ASSERT(connection_cb_called == 1); + ASSERT(close_cb_called == 3); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-bind-error.c b/external/src/libuv/test/test-tcp-bind-error.c new file mode 100644 index 0000000..fdd1fe0 --- /dev/null +++ b/external/src/libuv/test/test-tcp-bind-error.c @@ -0,0 +1,299 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + + +static int connect_cb_called = 0; +static int close_cb_called = 0; + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +static void connect_cb(uv_connect_t* req, int status) { + ASSERT(status == UV_EADDRINUSE); + uv_close((uv_handle_t*) req->handle, close_cb); + connect_cb_called++; +} + + +TEST_IMPL(tcp_bind_error_addrinuse_connect) { + struct sockaddr_in addr; + int addrlen; + uv_connect_t req; + uv_tcp_t conn; + + /* 127.0.0.1: is already taken by tcp4_echo_server running in + * another process. uv_tcp_bind() and uv_tcp_connect() should still succeed + * (greatest common denominator across platforms) but the connect callback + * should receive an UV_EADDRINUSE error. + */ + ASSERT(0 == uv_tcp_init(uv_default_loop(), &conn)); + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + ASSERT(0 == uv_tcp_bind(&conn, (const struct sockaddr*) &addr, 0)); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT + 1, &addr)); + ASSERT(0 == uv_tcp_connect(&req, + &conn, + (const struct sockaddr*) &addr, + connect_cb)); + + addrlen = sizeof(addr); + ASSERT(UV_EADDRINUSE == uv_tcp_getsockname(&conn, + (struct sockaddr*) &addr, + &addrlen)); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(connect_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_bind_error_addrinuse_listen) { + struct sockaddr_in addr; + uv_tcp_t server1, server2; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + r = uv_tcp_init(uv_default_loop(), &server1); + ASSERT(r == 0); + r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_tcp_init(uv_default_loop(), &server2); + ASSERT(r == 0); + r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_listen((uv_stream_t*)&server1, 128, NULL); + ASSERT(r == 0); + r = uv_listen((uv_stream_t*)&server2, 128, NULL); + ASSERT(r == UV_EADDRINUSE); + + uv_close((uv_handle_t*)&server1, close_cb); + uv_close((uv_handle_t*)&server2, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_bind_error_addrnotavail_1) { + struct sockaddr_in addr; + uv_tcp_t server; + int r; + + ASSERT(0 == uv_ip4_addr("127.255.255.255", TEST_PORT, &addr)); + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + + /* It seems that Linux is broken here - bind succeeds. */ + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0 || r == UV_EADDRNOTAVAIL); + + uv_close((uv_handle_t*)&server, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_bind_error_addrnotavail_2) { + struct sockaddr_in addr; + uv_tcp_t server; + int r; + + ASSERT(0 == uv_ip4_addr("4.4.4.4", TEST_PORT, &addr)); + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == UV_EADDRNOTAVAIL); + + uv_close((uv_handle_t*)&server, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_bind_error_fault) { + char garbage[] = + "blah blah blah blah blah blah blah blah blah blah blah blah"; + struct sockaddr_in* garbage_addr; + uv_tcp_t server; + int r; + + garbage_addr = (struct sockaddr_in*) &garbage; + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0); + ASSERT(r == UV_EINVAL); + + uv_close((uv_handle_t*)&server, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +/* Notes: On Linux uv_bind(server, NULL) will segfault the program. */ + +TEST_IMPL(tcp_bind_error_inval) { + struct sockaddr_in addr1; + struct sockaddr_in addr2; + uv_tcp_t server; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr1)); + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT_2, &addr2)); + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0); + ASSERT(r == 0); + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0); + ASSERT(r == UV_EINVAL); + + uv_close((uv_handle_t*)&server, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_bind_localhost_ok) { + struct sockaddr_in addr; + uv_tcp_t server; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_bind_invalid_flags) { + struct sockaddr_in addr; + uv_tcp_t server; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, UV_TCP_IPV6ONLY); + ASSERT(r == UV_EINVAL); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_listen_without_bind) { + int r; + uv_tcp_t server; + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + r = uv_listen((uv_stream_t*)&server, 128, NULL); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_bind_writable_flags) { + struct sockaddr_in addr; + uv_tcp_t server; + uv_buf_t buf; + uv_write_t write_req; + uv_shutdown_t shutdown_req; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + r = uv_listen((uv_stream_t*)&server, 128, NULL); + ASSERT(r == 0); + + ASSERT(0 == uv_is_writable((uv_stream_t*) &server)); + ASSERT(0 == uv_is_readable((uv_stream_t*) &server)); + + buf = uv_buf_init("PING", 4); + r = uv_write(&write_req, (uv_stream_t*) &server, &buf, 1, NULL); + ASSERT(r == UV_EPIPE); + r = uv_shutdown(&shutdown_req, (uv_stream_t*) &server, NULL); + ASSERT(r == UV_ENOTCONN); + r = uv_read_start((uv_stream_t*) &server, + (uv_alloc_cb) abort, + (uv_read_cb) abort); + ASSERT(r == UV_ENOTCONN); + + uv_close((uv_handle_t*)&server, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-bind6-error.c b/external/src/libuv/test/test-tcp-bind6-error.c new file mode 100644 index 0000000..86181b7 --- /dev/null +++ b/external/src/libuv/test/test-tcp-bind6-error.c @@ -0,0 +1,176 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + + +static int close_cb_called = 0; + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +TEST_IMPL(tcp_bind6_error_addrinuse) { + struct sockaddr_in6 addr; + uv_tcp_t server1, server2; + int r; + + if (!can_ipv6()) + RETURN_SKIP("IPv6 not supported"); + + ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr)); + + r = uv_tcp_init(uv_default_loop(), &server1); + ASSERT(r == 0); + r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_tcp_init(uv_default_loop(), &server2); + ASSERT(r == 0); + r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_listen((uv_stream_t*)&server1, 128, NULL); + ASSERT(r == 0); + r = uv_listen((uv_stream_t*)&server2, 128, NULL); + ASSERT(r == UV_EADDRINUSE); + + uv_close((uv_handle_t*)&server1, close_cb); + uv_close((uv_handle_t*)&server2, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_bind6_error_addrnotavail) { + struct sockaddr_in6 addr; + uv_tcp_t server; + int r; + + if (!can_ipv6()) + RETURN_SKIP("IPv6 not supported"); + + ASSERT(0 == uv_ip6_addr("4:4:4:4:4:4:4:4", TEST_PORT, &addr)); + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == UV_EADDRNOTAVAIL); + + uv_close((uv_handle_t*)&server, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_bind6_error_fault) { + char garbage[] = + "blah blah blah blah blah blah blah blah blah blah blah blah"; + struct sockaddr_in6* garbage_addr; + uv_tcp_t server; + int r; + + if (!can_ipv6()) + RETURN_SKIP("IPv6 not supported"); + + garbage_addr = (struct sockaddr_in6*) &garbage; + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0); + ASSERT(r == UV_EINVAL); + + uv_close((uv_handle_t*)&server, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +/* Notes: On Linux uv_bind6(server, NULL) will segfault the program. */ + +TEST_IMPL(tcp_bind6_error_inval) { + struct sockaddr_in6 addr1; + struct sockaddr_in6 addr2; + uv_tcp_t server; + int r; + + if (!can_ipv6()) + RETURN_SKIP("IPv6 not supported"); + + ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr1)); + ASSERT(0 == uv_ip6_addr("::", TEST_PORT_2, &addr2)); + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0); + ASSERT(r == 0); + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0); + ASSERT(r == UV_EINVAL); + + uv_close((uv_handle_t*)&server, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_bind6_localhost_ok) { + struct sockaddr_in6 addr; + uv_tcp_t server; + int r; + + if (!can_ipv6()) + RETURN_SKIP("IPv6 not supported"); + + ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr)); + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-close-accept.c b/external/src/libuv/test/test-tcp-close-accept.c new file mode 100644 index 0000000..624262b --- /dev/null +++ b/external/src/libuv/test/test-tcp-close-accept.c @@ -0,0 +1,198 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* this test is Unix only */ +#ifndef _WIN32 + +#include "uv.h" +#include "task.h" + +#include +#include + +static struct sockaddr_in addr; +static uv_tcp_t tcp_server; +static uv_tcp_t tcp_outgoing[2]; +static uv_tcp_t tcp_incoming[ARRAY_SIZE(tcp_outgoing)]; +static uv_connect_t connect_reqs[ARRAY_SIZE(tcp_outgoing)]; +static uv_tcp_t tcp_check; +static uv_connect_t tcp_check_req; +static uv_write_t write_reqs[ARRAY_SIZE(tcp_outgoing)]; +static unsigned int got_connections; +static unsigned int close_cb_called; +static unsigned int write_cb_called; +static unsigned int read_cb_called; +static unsigned int pending_incoming; + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + +static void write_cb(uv_write_t* req, int status) { + ASSERT(status == 0); + write_cb_called++; +} + +static void connect_cb(uv_connect_t* req, int status) { + unsigned int i; + uv_buf_t buf; + uv_stream_t* outgoing; + + if (req == &tcp_check_req) { + ASSERT(status != 0); + + /* + * Time to finish the test: close both the check and pending incoming + * connections + */ + uv_close((uv_handle_t*) &tcp_incoming[pending_incoming], close_cb); + uv_close((uv_handle_t*) &tcp_check, close_cb); + return; + } + + ASSERT(status == 0); + ASSERT(connect_reqs <= req); + ASSERT(req <= connect_reqs + ARRAY_SIZE(connect_reqs)); + i = req - connect_reqs; + + buf = uv_buf_init("x", 1); + outgoing = (uv_stream_t*) &tcp_outgoing[i]; + ASSERT(0 == uv_write(&write_reqs[i], outgoing, &buf, 1, write_cb)); +} + +static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + static char slab[1]; + buf->base = slab; + buf->len = sizeof(slab); +} + +static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { + uv_loop_t* loop; + unsigned int i; + + pending_incoming = (uv_tcp_t*) stream - &tcp_incoming[0]; + ASSERT(pending_incoming < got_connections); + ASSERT(0 == uv_read_stop(stream)); + ASSERT(1 == nread); + + loop = stream->loop; + read_cb_called++; + + /* Close all active incomings, except current one */ + for (i = 0; i < got_connections; i++) { + if (i != pending_incoming) + uv_close((uv_handle_t*) &tcp_incoming[i], close_cb); + } + + /* Close server, so no one will connect to it */ + uv_close((uv_handle_t*) &tcp_server, close_cb); + + /* Create new fd that should be one of the closed incomings */ + ASSERT(0 == uv_tcp_init(loop, &tcp_check)); + ASSERT(0 == uv_tcp_connect(&tcp_check_req, + &tcp_check, + (const struct sockaddr*) &addr, + connect_cb)); + ASSERT(0 == uv_read_start((uv_stream_t*) &tcp_check, alloc_cb, read_cb)); +} + +static void connection_cb(uv_stream_t* server, int status) { + unsigned int i; + uv_tcp_t* incoming; + + ASSERT(server == (uv_stream_t*) &tcp_server); + + /* Ignore tcp_check connection */ + if (got_connections == ARRAY_SIZE(tcp_incoming)) + return; + + /* Accept everyone */ + incoming = &tcp_incoming[got_connections++]; + ASSERT(0 == uv_tcp_init(server->loop, incoming)); + ASSERT(0 == uv_accept(server, (uv_stream_t*) incoming)); + + if (got_connections != ARRAY_SIZE(tcp_incoming)) + return; + + /* Once all clients are accepted - start reading */ + for (i = 0; i < ARRAY_SIZE(tcp_incoming); i++) { + incoming = &tcp_incoming[i]; + ASSERT(0 == uv_read_start((uv_stream_t*) incoming, alloc_cb, read_cb)); + } +} + +TEST_IMPL(tcp_close_accept) { + unsigned int i; + uv_loop_t* loop; + uv_tcp_t* client; + + /* + * A little explanation of what goes on below: + * + * We'll create server and connect to it using two clients, each writing one + * byte once connected. + * + * When all clients will be accepted by server - we'll start reading from them + * and, on first client's first byte, will close second client and server. + * After that, we'll immediately initiate new connection to server using + * tcp_check handle (thus, reusing fd from second client). + * + * In this situation uv__io_poll()'s event list should still contain read + * event for second client, and, if not cleaned up properly, `tcp_check` will + * receive stale event of second incoming and invoke `connect_cb` with zero + * status. + */ + + loop = uv_default_loop(); + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + ASSERT(0 == uv_tcp_init(loop, &tcp_server)); + ASSERT(0 == uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0)); + ASSERT(0 == uv_listen((uv_stream_t*) &tcp_server, + ARRAY_SIZE(tcp_outgoing), + connection_cb)); + + for (i = 0; i < ARRAY_SIZE(tcp_outgoing); i++) { + client = tcp_outgoing + i; + + ASSERT(0 == uv_tcp_init(loop, client)); + ASSERT(0 == uv_tcp_connect(&connect_reqs[i], + client, + (const struct sockaddr*) &addr, + connect_cb)); + } + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(ARRAY_SIZE(tcp_outgoing) == got_connections); + ASSERT((ARRAY_SIZE(tcp_outgoing) + 2) == close_cb_called); + ASSERT(ARRAY_SIZE(tcp_outgoing) == write_cb_called); + ASSERT(1 == read_cb_called); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* !_WIN32 */ diff --git a/external/src/libuv/test/test-tcp-close-reset.c b/external/src/libuv/test/test-tcp-close-reset.c new file mode 100644 index 0000000..7ca55c4 --- /dev/null +++ b/external/src/libuv/test/test-tcp-close-reset.c @@ -0,0 +1,290 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include /* memset */ + +static uv_loop_t* loop; +static uv_tcp_t tcp_server; +static uv_tcp_t tcp_client; +static uv_tcp_t tcp_accepted; +static uv_connect_t connect_req; +static uv_shutdown_t shutdown_req; +static uv_write_t write_reqs[4]; + +static int client_close; +static int shutdown_before_close; + +static int write_cb_called; +static int close_cb_called; +static int shutdown_cb_called; + +static void connect_cb(uv_connect_t* req, int status); +static void write_cb(uv_write_t* req, int status); +static void close_cb(uv_handle_t* handle); +static void shutdown_cb(uv_shutdown_t* req, int status); + +static int read_size; + + +static void do_write(uv_tcp_t* handle) { + uv_buf_t buf; + unsigned i; + int r; + + buf = uv_buf_init("PING", 4); + for (i = 0; i < ARRAY_SIZE(write_reqs); i++) { + r = uv_write(&write_reqs[i], (uv_stream_t*) handle, &buf, 1, write_cb); + ASSERT(r == 0); + } +} + + +static void do_close(uv_tcp_t* handle) { + if (shutdown_before_close == 1) { + ASSERT(0 == uv_shutdown(&shutdown_req, (uv_stream_t*) handle, shutdown_cb)); + ASSERT(UV_EINVAL == uv_tcp_close_reset(handle, close_cb)); + } else { + ASSERT(0 == uv_tcp_close_reset(handle, close_cb)); + ASSERT(UV_ENOTCONN == uv_shutdown(&shutdown_req, (uv_stream_t*) handle, shutdown_cb)); + } + + uv_close((uv_handle_t*) &tcp_server, NULL); +} + +static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + static char slab[1024]; + buf->base = slab; + buf->len = sizeof(slab); +} + +static void read_cb2(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { + ASSERT((uv_tcp_t*)stream == &tcp_client); + if (nread == UV_EOF) + uv_close((uv_handle_t*) stream, NULL); +} + + +static void connect_cb(uv_connect_t* conn_req, int status) { + ASSERT(conn_req == &connect_req); + uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb2); + do_write(&tcp_client); + if (client_close) + do_close(&tcp_client); +} + + +static void write_cb(uv_write_t* req, int status) { + /* write callbacks should run before the close callback */ + ASSERT(close_cb_called == 0); + ASSERT(req->handle == (uv_stream_t*)&tcp_client); + write_cb_called++; +} + + +static void close_cb(uv_handle_t* handle) { + if (client_close) + ASSERT(handle == (uv_handle_t*) &tcp_client); + else + ASSERT(handle == (uv_handle_t*) &tcp_accepted); + + close_cb_called++; +} + +static void shutdown_cb(uv_shutdown_t* req, int status) { + if (client_close) + ASSERT(req->handle == (uv_stream_t*) &tcp_client); + else + ASSERT(req->handle == (uv_stream_t*) &tcp_accepted); + + shutdown_cb_called++; +} + + +static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { + ASSERT((uv_tcp_t*)stream == &tcp_accepted); + if (nread < 0) { + uv_close((uv_handle_t*) stream, NULL); + } else { + read_size += nread; + if (read_size == 16 && client_close == 0) + do_close(&tcp_accepted); + } +} + + +static void connection_cb(uv_stream_t* server, int status) { + ASSERT(status == 0); + + ASSERT(0 == uv_tcp_init(loop, &tcp_accepted)); + ASSERT(0 == uv_accept(server, (uv_stream_t*) &tcp_accepted)); + + uv_read_start((uv_stream_t*) &tcp_accepted, alloc_cb, read_cb); +} + + +static void start_server(uv_loop_t* loop, uv_tcp_t* handle) { + struct sockaddr_in addr; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_tcp_init(loop, handle); + ASSERT(r == 0); + + r = uv_tcp_bind(handle, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_listen((uv_stream_t*)handle, 128, connection_cb); + ASSERT(r == 0); +} + + +static void do_connect(uv_loop_t* loop, uv_tcp_t* tcp_client) { + struct sockaddr_in addr; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_tcp_init(loop, tcp_client); + ASSERT(r == 0); + + r = uv_tcp_connect(&connect_req, + tcp_client, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT(r == 0); +} + + +/* Check that pending write requests have their callbacks + * invoked when the handle is closed. + */ +TEST_IMPL(tcp_close_reset_client) { + int r; + + loop = uv_default_loop(); + + start_server(loop, &tcp_server); + + client_close = 1; + shutdown_before_close = 0; + + do_connect(loop, &tcp_client); + + ASSERT(write_cb_called == 0); + ASSERT(close_cb_called == 0); + ASSERT(shutdown_cb_called == 0); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(write_cb_called == 4); + ASSERT(close_cb_called == 1); + ASSERT(shutdown_cb_called == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(tcp_close_reset_client_after_shutdown) { + int r; + + loop = uv_default_loop(); + + start_server(loop, &tcp_server); + + client_close = 1; + shutdown_before_close = 1; + + do_connect(loop, &tcp_client); + + ASSERT(write_cb_called == 0); + ASSERT(close_cb_called == 0); + ASSERT(shutdown_cb_called == 0); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(write_cb_called == 4); + ASSERT(close_cb_called == 0); + ASSERT(shutdown_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(tcp_close_reset_accepted) { + int r; + + loop = uv_default_loop(); + + start_server(loop, &tcp_server); + + client_close = 0; + shutdown_before_close = 0; + + do_connect(loop, &tcp_client); + + ASSERT(write_cb_called == 0); + ASSERT(close_cb_called == 0); + ASSERT(shutdown_cb_called == 0); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(write_cb_called == 4); + ASSERT(close_cb_called == 1); + ASSERT(shutdown_cb_called == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(tcp_close_reset_accepted_after_shutdown) { + int r; + + loop = uv_default_loop(); + + start_server(loop, &tcp_server); + + client_close = 0; + shutdown_before_close = 1; + + do_connect(loop, &tcp_client); + + ASSERT(write_cb_called == 0); + ASSERT(close_cb_called == 0); + ASSERT(shutdown_cb_called == 0); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(write_cb_called == 4); + ASSERT(close_cb_called == 0); + ASSERT(shutdown_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-close-while-connecting.c b/external/src/libuv/test/test-tcp-close-while-connecting.c new file mode 100644 index 0000000..8d0b827 --- /dev/null +++ b/external/src/libuv/test/test-tcp-close-while-connecting.c @@ -0,0 +1,97 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static uv_timer_t timer1_handle; +static uv_timer_t timer2_handle; +static uv_tcp_t tcp_handle; + +static int connect_cb_called; +static int timer1_cb_called; +static int close_cb_called; +static int netunreach_errors; + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + + +static void connect_cb(uv_connect_t* req, int status) { + /* The expected error is UV_ECANCELED but the test tries to connect to what + * is basically an arbitrary address in the expectation that no network path + * exists, so UV_ENETUNREACH is an equally plausible outcome. + */ + ASSERT(status == UV_ECANCELED || status == UV_ENETUNREACH); + uv_timer_stop(&timer2_handle); + connect_cb_called++; + if (status == UV_ENETUNREACH) + netunreach_errors++; +} + + +static void timer1_cb(uv_timer_t* handle) { + uv_close((uv_handle_t*)handle, close_cb); + uv_close((uv_handle_t*)&tcp_handle, close_cb); + timer1_cb_called++; +} + + +static void timer2_cb(uv_timer_t* handle) { + ASSERT(0 && "should not be called"); +} + + +TEST_IMPL(tcp_close_while_connecting) { + uv_connect_t connect_req; + struct sockaddr_in addr; + uv_loop_t* loop; + int r; + + loop = uv_default_loop(); + ASSERT(0 == uv_ip4_addr("1.2.3.4", TEST_PORT, &addr)); + ASSERT(0 == uv_tcp_init(loop, &tcp_handle)); + r = uv_tcp_connect(&connect_req, + &tcp_handle, + (const struct sockaddr*) &addr, + connect_cb); + if (r == UV_ENETUNREACH) + RETURN_SKIP("Network unreachable."); + ASSERT(r == 0); + ASSERT(0 == uv_timer_init(loop, &timer1_handle)); + ASSERT(0 == uv_timer_start(&timer1_handle, timer1_cb, 1, 0)); + ASSERT(0 == uv_timer_init(loop, &timer2_handle)); + ASSERT(0 == uv_timer_start(&timer2_handle, timer2_cb, 86400 * 1000, 0)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + + ASSERT(connect_cb_called == 1); + ASSERT(timer1_cb_called == 1); + ASSERT(close_cb_called == 2); + + MAKE_VALGRIND_HAPPY(); + + if (netunreach_errors > 0) + RETURN_SKIP("Network unreachable."); + + return 0; +} diff --git a/external/src/libuv/test/test-tcp-close.c b/external/src/libuv/test/test-tcp-close.c new file mode 100644 index 0000000..5a7bd68 --- /dev/null +++ b/external/src/libuv/test/test-tcp-close.c @@ -0,0 +1,136 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include /* memset */ + +#define NUM_WRITE_REQS 32 + +static uv_tcp_t tcp_handle; +static uv_connect_t connect_req; + +static int write_cb_called; +static int close_cb_called; + +static void connect_cb(uv_connect_t* req, int status); +static void write_cb(uv_write_t* req, int status); +static void close_cb(uv_handle_t* handle); + + +static void connect_cb(uv_connect_t* conn_req, int status) { + uv_write_t* req; + uv_buf_t buf; + int i, r; + + buf = uv_buf_init("PING", 4); + for (i = 0; i < NUM_WRITE_REQS; i++) { + req = malloc(sizeof *req); + ASSERT_NOT_NULL(req); + + r = uv_write(req, (uv_stream_t*)&tcp_handle, &buf, 1, write_cb); + ASSERT(r == 0); + } + + uv_close((uv_handle_t*)&tcp_handle, close_cb); +} + + +static void write_cb(uv_write_t* req, int status) { + /* write callbacks should run before the close callback */ + ASSERT(close_cb_called == 0); + ASSERT(req->handle == (uv_stream_t*)&tcp_handle); + write_cb_called++; + free(req); +} + + +static void close_cb(uv_handle_t* handle) { + ASSERT(handle == (uv_handle_t*)&tcp_handle); + close_cb_called++; +} + + +static void connection_cb(uv_stream_t* server, int status) { + ASSERT(status == 0); +} + + +static void start_server(uv_loop_t* loop, uv_tcp_t* handle) { + struct sockaddr_in addr; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_tcp_init(loop, handle); + ASSERT(r == 0); + + r = uv_tcp_bind(handle, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_listen((uv_stream_t*)handle, 128, connection_cb); + ASSERT(r == 0); + + uv_unref((uv_handle_t*)handle); +} + + +/* Check that pending write requests have their callbacks + * invoked when the handle is closed. + */ +TEST_IMPL(tcp_close) { + struct sockaddr_in addr; + uv_tcp_t tcp_server; + uv_loop_t* loop; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + loop = uv_default_loop(); + + /* We can't use the echo server, it doesn't handle ECONNRESET. */ + start_server(loop, &tcp_server); + + r = uv_tcp_init(loop, &tcp_handle); + ASSERT(r == 0); + + r = uv_tcp_connect(&connect_req, + &tcp_handle, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT(r == 0); + + ASSERT(write_cb_called == 0); + ASSERT(close_cb_called == 0); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + printf("%d of %d write reqs seen\n", write_cb_called, NUM_WRITE_REQS); + + ASSERT(write_cb_called == NUM_WRITE_REQS); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-connect-error-after-write.c b/external/src/libuv/test/test-tcp-connect-error-after-write.c new file mode 100644 index 0000000..3f2e357 --- /dev/null +++ b/external/src/libuv/test/test-tcp-connect-error-after-write.c @@ -0,0 +1,98 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +static int connect_cb_called; +static int write_cb_called; +static int close_cb_called; + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + + +static void connect_cb(uv_connect_t* req, int status) { + ASSERT(status < 0); + connect_cb_called++; + uv_close((uv_handle_t*)req->handle, close_cb); +} + + +static void write_cb(uv_write_t* req, int status) { + ASSERT(status < 0); + write_cb_called++; +} + + +/* + * Try to connect to an address on which nothing listens, get ECONNREFUSED + * (uv errno 12) and get connect_cb() called once with status != 0. + * Related issue: https://github.com/joyent/libuv/issues/443 + */ +TEST_IMPL(tcp_connect_error_after_write) { + uv_connect_t connect_req; + struct sockaddr_in addr; + uv_write_t write_req; + uv_tcp_t conn; + uv_buf_t buf; + int r; + +#ifdef _WIN32 + fprintf(stderr, "This test is disabled on Windows for now.\n"); + fprintf(stderr, "See https://github.com/joyent/libuv/issues/444\n"); + return 0; /* windows slackers... */ +#endif + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + buf = uv_buf_init("TEST", 4); + + r = uv_tcp_init(uv_default_loop(), &conn); + ASSERT(r == 0); + + r = uv_write(&write_req, (uv_stream_t*)&conn, &buf, 1, write_cb); + ASSERT(r == UV_EBADF); + + r = uv_tcp_connect(&connect_req, + &conn, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT(r == 0); + + r = uv_write(&write_req, (uv_stream_t*)&conn, &buf, 1, write_cb); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(connect_cb_called == 1); + ASSERT(write_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-connect-error.c b/external/src/libuv/test/test-tcp-connect-error.c new file mode 100644 index 0000000..dda30a5 --- /dev/null +++ b/external/src/libuv/test/test-tcp-connect-error.c @@ -0,0 +1,73 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + + +static int connect_cb_called = 0; +static int close_cb_called = 0; + + + +static void connect_cb(uv_connect_t* handle, int status) { + ASSERT_NOT_NULL(handle); + connect_cb_called++; +} + + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +TEST_IMPL(tcp_connect_error_fault) { + const char garbage[] = + "blah blah blah blah blah blah blah blah blah blah blah blah"; + const struct sockaddr_in* garbage_addr; + uv_tcp_t server; + int r; + uv_connect_t req; + + garbage_addr = (const struct sockaddr_in*) &garbage; + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + r = uv_tcp_connect(&req, + &server, + (const struct sockaddr*) garbage_addr, + connect_cb); + ASSERT(r == UV_EINVAL); + + uv_close((uv_handle_t*)&server, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(connect_cb_called == 0); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-connect-timeout.c b/external/src/libuv/test/test-tcp-connect-timeout.c new file mode 100644 index 0000000..3c34e54 --- /dev/null +++ b/external/src/libuv/test/test-tcp-connect-timeout.c @@ -0,0 +1,196 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + + +static int connect_cb_called; +static int close_cb_called; + +static uv_connect_t connect_req; +static uv_timer_t timer; +static uv_tcp_t conn; + +static void connect_cb(uv_connect_t* req, int status); +static void timer_cb(uv_timer_t* handle); +static void close_cb(uv_handle_t* handle); + + +static void connect_cb(uv_connect_t* req, int status) { + ASSERT(req == &connect_req); + ASSERT(status == UV_ECANCELED); + connect_cb_called++; +} + + +static void timer_cb(uv_timer_t* handle) { + ASSERT(handle == &timer); + uv_close((uv_handle_t*)&conn, close_cb); + uv_close((uv_handle_t*)&timer, close_cb); +} + + +static void close_cb(uv_handle_t* handle) { + ASSERT(handle == (uv_handle_t*)&conn || handle == (uv_handle_t*)&timer); + close_cb_called++; +} + + +/* Verify that connecting to an unreachable address or port doesn't hang + * the event loop. + */ +TEST_IMPL(tcp_connect_timeout) { + struct sockaddr_in addr; + int r; + + ASSERT(0 == uv_ip4_addr("8.8.8.8", 9999, &addr)); + + r = uv_timer_init(uv_default_loop(), &timer); + ASSERT(r == 0); + + r = uv_timer_start(&timer, timer_cb, 50, 0); + ASSERT(r == 0); + + r = uv_tcp_init(uv_default_loop(), &conn); + ASSERT(r == 0); + + r = uv_tcp_connect(&connect_req, + &conn, + (const struct sockaddr*) &addr, + connect_cb); + if (r == UV_ENETUNREACH) + RETURN_SKIP("Network unreachable."); + ASSERT(r == 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +/* Make sure connect fails instantly if the target is nonexisting + * local port. + */ + +static void connect_local_cb(uv_connect_t* req, int status) { + ASSERT_PTR_EQ(req, &connect_req); + ASSERT_NE(status, UV_ECANCELED); + connect_cb_called++; +} + +static int is_supported_system(void) { + int semver[3]; + int min_semver[3] = {10, 0, 16299}; + int cnt; + uv_utsname_t uname; + ASSERT_EQ(uv_os_uname(&uname), 0); + if (strcmp(uname.sysname, "Windows_NT") == 0) { + cnt = sscanf(uname.release, "%d.%d.%d", &semver[0], &semver[1], &semver[2]); + if (cnt != 3) { + return 0; + } + /* relase >= 10.0.16299 */ + for (cnt = 0; cnt < 3; ++cnt) { + if (semver[cnt] > min_semver[cnt]) + return 1; + if (semver[cnt] < min_semver[cnt]) + return 0; + } + return 1; + } + return 1; +} + +TEST_IMPL(tcp_local_connect_timeout) { + struct sockaddr_in addr; + int r; + + if (!is_supported_system()) { + RETURN_SKIP("Unsupported system"); + } + ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_timer_init(uv_default_loop(), &timer); + ASSERT_EQ(r, 0); + + /* Give it 1s to timeout. */ + r = uv_timer_start(&timer, timer_cb, 1000, 0); + ASSERT_EQ(r, 0); + + r = uv_tcp_init(uv_default_loop(), &conn); + ASSERT_EQ(r, 0); + + r = uv_tcp_connect(&connect_req, + &conn, + (const struct sockaddr*) &addr, + connect_local_cb); + if (r == UV_ENETUNREACH) + RETURN_SKIP("Network unreachable."); + ASSERT_EQ(r, 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(tcp6_local_connect_timeout) { + struct sockaddr_in6 addr; + int r; + + if (!is_supported_system()) { + RETURN_SKIP("Unsupported system"); + } + if (!can_ipv6()) { + RETURN_SKIP("IPv6 not supported"); + } + + ASSERT_EQ(0, uv_ip6_addr("::1", 9999, &addr)); + + r = uv_timer_init(uv_default_loop(), &timer); + ASSERT_EQ(r, 0); + + /* Give it 1s to timeout. */ + r = uv_timer_start(&timer, timer_cb, 1000, 0); + ASSERT_EQ(r, 0); + + r = uv_tcp_init(uv_default_loop(), &conn); + ASSERT_EQ(r, 0); + + r = uv_tcp_connect(&connect_req, + &conn, + (const struct sockaddr*) &addr, + connect_local_cb); + if (r == UV_ENETUNREACH) + RETURN_SKIP("Network unreachable."); + ASSERT_EQ(r, 0); + + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT_EQ(r, 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-connect6-error.c b/external/src/libuv/test/test-tcp-connect6-error.c new file mode 100644 index 0000000..2f6e9cb --- /dev/null +++ b/external/src/libuv/test/test-tcp-connect6-error.c @@ -0,0 +1,71 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + + +static int connect_cb_called = 0; +static int close_cb_called = 0; + + +static void connect_cb(uv_connect_t* handle, int status) { + ASSERT_NOT_NULL(handle); + connect_cb_called++; +} + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +TEST_IMPL(tcp_connect6_error_fault) { + const char garbage[] = + "blah blah blah blah blah blah blah blah blah blah blah blah"; + const struct sockaddr_in6* garbage_addr; + uv_tcp_t server; + int r; + uv_connect_t req; + + garbage_addr = (const struct sockaddr_in6*) &garbage; + + r = uv_tcp_init(uv_default_loop(), &server); + ASSERT(r == 0); + r = uv_tcp_connect(&req, + &server, + (const struct sockaddr*) garbage_addr, + connect_cb); + ASSERT(r == UV_EINVAL); + + uv_close((uv_handle_t*)&server, close_cb); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(connect_cb_called == 0); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-create-socket-early.c b/external/src/libuv/test/test-tcp-create-socket-early.c new file mode 100644 index 0000000..f2bc60d --- /dev/null +++ b/external/src/libuv/test/test-tcp-create-socket-early.c @@ -0,0 +1,209 @@ +/* Copyright (c) 2015 Saúl Ibarra Corretgé . + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +#ifdef _WIN32 +# define INVALID_FD (INVALID_HANDLE_VALUE) +#else +# define INVALID_FD (-1) +#endif + + +static void on_connect(uv_connect_t* req, int status) { + ASSERT(status == 0); + uv_close((uv_handle_t*) req->handle, NULL); +} + + +static void on_connection(uv_stream_t* server, int status) { + uv_tcp_t* handle; + int r; + + ASSERT(status == 0); + + handle = malloc(sizeof(*handle)); + ASSERT_NOT_NULL(handle); + + r = uv_tcp_init_ex(server->loop, handle, AF_INET); + ASSERT(r == 0); + + r = uv_accept(server, (uv_stream_t*)handle); + ASSERT(r == UV_EBUSY); + + uv_close((uv_handle_t*) server, NULL); + uv_close((uv_handle_t*) handle, (uv_close_cb)free); +} + + +static void tcp_listener(uv_loop_t* loop, uv_tcp_t* server) { + struct sockaddr_in addr; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + r = uv_tcp_init(loop, server); + ASSERT(r == 0); + + r = uv_tcp_bind(server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_listen((uv_stream_t*) server, 128, on_connection); + ASSERT(r == 0); +} + + +static void tcp_connector(uv_loop_t* loop, uv_tcp_t* client, uv_connect_t* req) { + struct sockaddr_in server_addr; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr)); + + r = uv_tcp_init(loop, client); + ASSERT(r == 0); + + r = uv_tcp_connect(req, + client, + (const struct sockaddr*) &server_addr, + on_connect); + ASSERT(r == 0); +} + + +TEST_IMPL(tcp_create_early) { + struct sockaddr_in addr; + struct sockaddr_in sockname; + uv_tcp_t client; + uv_os_fd_t fd; + int r, namelen; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_tcp_init_ex(uv_default_loop(), &client, AF_INET); + ASSERT(r == 0); + + r = uv_fileno((const uv_handle_t*) &client, &fd); + ASSERT(r == 0); + ASSERT(fd != INVALID_FD); + + /* Windows returns WSAEINVAL if the socket is not bound */ +#ifndef _WIN32 + namelen = sizeof sockname; + r = uv_tcp_getsockname(&client, (struct sockaddr*) &sockname, &namelen); + ASSERT(r == 0); + ASSERT(sockname.sin_family == AF_INET); +#endif + + r = uv_tcp_bind(&client, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + namelen = sizeof sockname; + r = uv_tcp_getsockname(&client, (struct sockaddr*) &sockname, &namelen); + ASSERT(r == 0); + ASSERT(memcmp(&addr.sin_addr, + &sockname.sin_addr, + sizeof(addr.sin_addr)) == 0); + + uv_close((uv_handle_t*) &client, NULL); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_create_early_bad_bind) { + struct sockaddr_in addr; + uv_tcp_t client; + uv_os_fd_t fd; + int r; + + if (!can_ipv6()) + RETURN_SKIP("IPv6 not supported"); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_tcp_init_ex(uv_default_loop(), &client, AF_INET6); + ASSERT(r == 0); + + r = uv_fileno((const uv_handle_t*) &client, &fd); + ASSERT(r == 0); + ASSERT(fd != INVALID_FD); + + /* Windows returns WSAEINVAL if the socket is not bound */ +#ifndef _WIN32 + { + int namelen; + struct sockaddr_in6 sockname; + namelen = sizeof sockname; + r = uv_tcp_getsockname(&client, (struct sockaddr*) &sockname, &namelen); + ASSERT(r == 0); + ASSERT(sockname.sin6_family == AF_INET6); + } +#endif + + r = uv_tcp_bind(&client, (const struct sockaddr*) &addr, 0); +#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MSYS__) + ASSERT(r == UV_EINVAL); +#else + ASSERT(r == UV_EFAULT); +#endif + + uv_close((uv_handle_t*) &client, NULL); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_create_early_bad_domain) { + uv_tcp_t client; + int r; + + r = uv_tcp_init_ex(uv_default_loop(), &client, 47); + ASSERT(r == UV_EINVAL); + + r = uv_tcp_init_ex(uv_default_loop(), &client, 1024); + ASSERT(r == UV_EINVAL); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_create_early_accept) { + uv_tcp_t client, server; + uv_connect_t connect_req; + + tcp_listener(uv_default_loop(), &server); + tcp_connector(uv_default_loop(), &client, &connect_req); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-flags.c b/external/src/libuv/test/test-tcp-flags.c new file mode 100644 index 0000000..68afb39 --- /dev/null +++ b/external/src/libuv/test/test-tcp-flags.c @@ -0,0 +1,52 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + + +TEST_IMPL(tcp_flags) { + uv_loop_t* loop; + uv_tcp_t handle; + int r; + + loop = uv_default_loop(); + + r = uv_tcp_init(loop, &handle); + ASSERT(r == 0); + + r = uv_tcp_nodelay(&handle, 1); + ASSERT(r == 0); + + r = uv_tcp_keepalive(&handle, 1, 60); + ASSERT(r == 0); + + uv_close((uv_handle_t*)&handle, NULL); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-oob.c b/external/src/libuv/test/test-tcp-oob.c new file mode 100644 index 0000000..53f8231 --- /dev/null +++ b/external/src/libuv/test/test-tcp-oob.c @@ -0,0 +1,146 @@ +/* Copyright Fedor Indutny. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#if !defined(_WIN32) + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +static uv_tcp_t server_handle; +static uv_tcp_t client_handle; +static uv_tcp_t peer_handle; +static uv_idle_t idle; +static uv_connect_t connect_req; +static int ticks; +static const int kMaxTicks = 10; + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char storage[1024]; + *buf = uv_buf_init(storage, sizeof(storage)); +} + + +static void idle_cb(uv_idle_t* idle) { + if (++ticks < kMaxTicks) + return; + + uv_close((uv_handle_t*) &server_handle, NULL); + uv_close((uv_handle_t*) &client_handle, NULL); + uv_close((uv_handle_t*) &peer_handle, NULL); + uv_close((uv_handle_t*) idle, NULL); +} + + +static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { +#ifdef __MVS__ + char lbuf[12]; +#endif + uv_os_fd_t fd; + + ASSERT(nread >= 0); + ASSERT(0 == uv_fileno((uv_handle_t*)handle, &fd)); + ASSERT(0 == uv_idle_start(&idle, idle_cb)); + +#ifdef __MVS__ + /* Need to flush out the OOB data. Otherwise, this callback will get + * triggered on every poll with nread = 0. + */ + ASSERT(-1 != recv(fd, lbuf, sizeof(lbuf), MSG_OOB)); +#endif +} + + +static void connect_cb(uv_connect_t* req, int status) { + ASSERT(req->handle == (uv_stream_t*) &client_handle); + ASSERT(0 == status); +} + + +static void connection_cb(uv_stream_t* handle, int status) { + int r; + uv_os_fd_t fd; + + ASSERT(0 == status); + ASSERT(0 == uv_accept(handle, (uv_stream_t*) &peer_handle)); + ASSERT(0 == uv_read_start((uv_stream_t*) &peer_handle, alloc_cb, read_cb)); + + /* Send some OOB data */ + ASSERT(0 == uv_fileno((uv_handle_t*) &client_handle, &fd)); + + ASSERT(0 == uv_stream_set_blocking((uv_stream_t*) &client_handle, 1)); + + /* The problem triggers only on a second message, it seem that xnu is not + * triggering `kevent()` for the first one + */ + do { + r = send(fd, "hello", 5, MSG_OOB); + } while (r < 0 && errno == EINTR); + ASSERT(5 == r); + + do { + r = send(fd, "hello", 5, MSG_OOB); + } while (r < 0 && errno == EINTR); + ASSERT(5 == r); + + ASSERT(0 == uv_stream_set_blocking((uv_stream_t*) &client_handle, 0)); +} + + +TEST_IMPL(tcp_oob) { + struct sockaddr_in addr; + uv_loop_t* loop; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + loop = uv_default_loop(); + + ASSERT(0 == uv_tcp_init(loop, &server_handle)); + ASSERT(0 == uv_tcp_init(loop, &client_handle)); + ASSERT(0 == uv_tcp_init(loop, &peer_handle)); + ASSERT(0 == uv_idle_init(loop, &idle)); + ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0)); + ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 1, connection_cb)); + + /* Ensure two separate packets */ + ASSERT(0 == uv_tcp_nodelay(&client_handle, 1)); + + ASSERT(0 == uv_tcp_connect(&connect_req, + &client_handle, + (const struct sockaddr*) &addr, + connect_cb)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + + ASSERT(ticks == kMaxTicks); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* !_WIN32 */ diff --git a/external/src/libuv/test/test-tcp-open.c b/external/src/libuv/test/test-tcp-open.c new file mode 100644 index 0000000..7e49139 --- /dev/null +++ b/external/src/libuv/test/test-tcp-open.c @@ -0,0 +1,401 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include +#include + +#ifndef _WIN32 +# include +#endif + +static int shutdown_cb_called = 0; +static int shutdown_requested = 0; +static int connect_cb_called = 0; +static int write_cb_called = 0; +static int close_cb_called = 0; + +static uv_connect_t connect_req; +static uv_shutdown_t shutdown_req; +static uv_write_t write_req; +static uv_timer_t tm; +static uv_tcp_t client; + + +static void startup(void) { +#ifdef _WIN32 + struct WSAData wsa_data; + int r = WSAStartup(MAKEWORD(2, 2), &wsa_data); + ASSERT(r == 0); +#endif +} + + +static uv_os_sock_t create_tcp_socket(void) { + uv_os_sock_t sock; + + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); +#ifdef _WIN32 + ASSERT(sock != INVALID_SOCKET); +#else + ASSERT(sock >= 0); +#endif + +#ifndef _WIN32 + { + /* Allow reuse of the port. */ + int yes = 1; + int r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes); + ASSERT(r == 0); + } +#endif + + return sock; +} + + +static void close_socket(uv_os_sock_t sock) { + int r; +#ifdef _WIN32 + r = closesocket(sock); +#else + r = close(sock); +#endif + ASSERT(r == 0); +} + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + ASSERT(suggested_size <= sizeof(slab)); + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +static void shutdown_cb(uv_shutdown_t* req, int status) { + ASSERT(req == &shutdown_req); + ASSERT(status == 0); + + /* Now we wait for the EOF */ + shutdown_cb_called++; +} + + +static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { + ASSERT_NOT_NULL(tcp); + + if (nread >= 0) { + ASSERT(nread == 4); + ASSERT(memcmp("PING", buf->base, nread) == 0); + } + else { + ASSERT(nread == UV_EOF); + uv_close((uv_handle_t*)tcp, close_cb); + } +} + + +static void read1_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { + int i; + ASSERT_NOT_NULL(tcp); + + if (nread >= 0) { + for (i = 0; i < nread; ++i) + ASSERT(buf->base[i] == 'P'); + } else { + ASSERT(nread == UV_EOF); + printf("GOT EOF\n"); + uv_close((uv_handle_t*)tcp, close_cb); + } +} + + +static void write_cb(uv_write_t* req, int status) { + ASSERT_NOT_NULL(req); + + if (status) { + fprintf(stderr, "uv_write error: %s\n", uv_strerror(status)); + ASSERT(0); + } + + write_cb_called++; +} + + +static void write1_cb(uv_write_t* req, int status) { + uv_buf_t buf; + int r; + + ASSERT_NOT_NULL(req); + if (status) { + ASSERT(shutdown_cb_called); + return; + } + + if (shutdown_requested) + return; + + buf = uv_buf_init("P", 1); + r = uv_write(&write_req, req->handle, &buf, 1, write1_cb); + ASSERT(r == 0); + + write_cb_called++; +} + + +static void timer_cb(uv_timer_t* handle) { + int r; + + /* Shutdown on drain. */ + r = uv_shutdown(&shutdown_req, (uv_stream_t*) &client, shutdown_cb); + ASSERT(r == 0); + shutdown_requested++; +} + + +static void connect_cb(uv_connect_t* req, int status) { + uv_buf_t buf = uv_buf_init("PING", 4); + uv_stream_t* stream; + int r; + + ASSERT(req == &connect_req); + ASSERT(status == 0); + + stream = req->handle; + connect_cb_called++; + + r = uv_write(&write_req, stream, &buf, 1, write_cb); + ASSERT(r == 0); + + /* Shutdown on drain. */ + r = uv_shutdown(&shutdown_req, stream, shutdown_cb); + ASSERT(r == 0); + + /* Start reading */ + r = uv_read_start(stream, alloc_cb, read_cb); + ASSERT(r == 0); +} + + +static void connect1_cb(uv_connect_t* req, int status) { + uv_buf_t buf; + uv_stream_t* stream; + int r; + + ASSERT(req == &connect_req); + ASSERT(status == 0); + + stream = req->handle; + connect_cb_called++; + + r = uv_timer_init(uv_default_loop(), &tm); + ASSERT(r == 0); + + r = uv_timer_start(&tm, timer_cb, 2000, 0); + ASSERT(r == 0); + + buf = uv_buf_init("P", 1); + r = uv_write(&write_req, stream, &buf, 1, write1_cb); + ASSERT(r == 0); + + /* Start reading */ + r = uv_read_start(stream, alloc_cb, read1_cb); + ASSERT(r == 0); +} + + +TEST_IMPL(tcp_open) { + struct sockaddr_in addr; + uv_os_sock_t sock; + int r; + uv_tcp_t client2; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + startup(); + sock = create_tcp_socket(); + + r = uv_tcp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + r = uv_tcp_open(&client, sock); + ASSERT(r == 0); + + r = uv_tcp_connect(&connect_req, + &client, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT(r == 0); + +#ifndef _WIN32 + { + r = uv_tcp_init(uv_default_loop(), &client2); + ASSERT(r == 0); + + r = uv_tcp_open(&client2, sock); + ASSERT(r == UV_EEXIST); + + uv_close((uv_handle_t*) &client2, NULL); + } +#else /* _WIN32 */ + (void)client2; +#endif + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(shutdown_cb_called == 1); + ASSERT(connect_cb_called == 1); + ASSERT(write_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_open_twice) { + uv_tcp_t client; + uv_os_sock_t sock1, sock2; + int r; + + startup(); + sock1 = create_tcp_socket(); + sock2 = create_tcp_socket(); + + r = uv_tcp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + r = uv_tcp_open(&client, sock1); + ASSERT(r == 0); + + r = uv_tcp_open(&client, sock2); + ASSERT(r == UV_EBUSY); + close_socket(sock2); + + uv_close((uv_handle_t*) &client, NULL); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_open_bound) { + struct sockaddr_in addr; + uv_tcp_t server; + uv_os_sock_t sock; + + startup(); + sock = create_tcp_socket(); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + ASSERT(0 == uv_tcp_init(uv_default_loop(), &server)); + + ASSERT(0 == bind(sock, (struct sockaddr*) &addr, sizeof(addr))); + + ASSERT(0 == uv_tcp_open(&server, sock)); + + ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, NULL)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_open_connected) { + struct sockaddr_in addr; + uv_tcp_t client; + uv_os_sock_t sock; + uv_buf_t buf = uv_buf_init("PING", 4); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + startup(); + sock = create_tcp_socket(); + + ASSERT(0 == connect(sock, (struct sockaddr*) &addr, sizeof(addr))); + + ASSERT(0 == uv_tcp_init(uv_default_loop(), &client)); + + ASSERT(0 == uv_tcp_open(&client, sock)); + + ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &client, &buf, 1, write_cb)); + + ASSERT(0 == uv_shutdown(&shutdown_req, (uv_stream_t*) &client, shutdown_cb)); + + ASSERT(0 == uv_read_start((uv_stream_t*) &client, alloc_cb, read_cb)); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(shutdown_cb_called == 1); + ASSERT(write_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tcp_write_ready) { + struct sockaddr_in addr; + uv_os_sock_t sock; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + startup(); + sock = create_tcp_socket(); + + r = uv_tcp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + r = uv_tcp_open(&client, sock); + ASSERT(r == 0); + + r = uv_tcp_connect(&connect_req, + &client, + (const struct sockaddr*) &addr, + connect1_cb); + ASSERT(r == 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(shutdown_cb_called == 1); + ASSERT(shutdown_requested == 1); + ASSERT(connect_cb_called == 1); + ASSERT(write_cb_called > 0); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-read-stop-start.c b/external/src/libuv/test/test-tcp-read-stop-start.c new file mode 100644 index 0000000..9bccbc1 --- /dev/null +++ b/external/src/libuv/test/test-tcp-read-stop-start.c @@ -0,0 +1,136 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static uv_tcp_t server; +static uv_tcp_t connection; +static int read_cb_called = 0; + +static uv_tcp_t client; +static uv_connect_t connect_req; + + +static void on_read2(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf); + +static void on_write_close_immediately(uv_write_t* req, int status) { + ASSERT(0 == status); + + uv_close((uv_handle_t*)req->handle, NULL); /* Close immediately */ + free(req); +} + +static void on_write(uv_write_t* req, int status) { + ASSERT(0 == status); + + free(req); +} + +static void do_write(uv_stream_t* stream, uv_write_cb cb) { + uv_write_t* req = malloc(sizeof(*req)); + uv_buf_t buf; + buf.base = "1234578"; + buf.len = 8; + ASSERT(0 == uv_write(req, stream, &buf, 1, cb)); +} + +static void on_alloc(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + buf->base = slab; + buf->len = sizeof(slab); +} + +static void on_read1(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { + ASSERT(nread >= 0); + + /* Do write on a half open connection to force WSAECONNABORTED (on Windows) + * in the subsequent uv_read_start() + */ + do_write(stream, on_write); + + ASSERT(0 == uv_read_stop(stream)); + + ASSERT(0 == uv_read_start(stream, on_alloc, on_read2)); + + read_cb_called++; +} + +static void on_read2(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { + ASSERT(nread < 0); + + uv_close((uv_handle_t*)stream, NULL); + uv_close((uv_handle_t*)&server, NULL); + + read_cb_called++; +} + +static void on_connection(uv_stream_t* server, int status) { + ASSERT(0 == status); + + ASSERT(0 == uv_tcp_init(server->loop, &connection)); + + ASSERT(0 == uv_accept(server, (uv_stream_t* )&connection)); + + ASSERT(0 == uv_read_start((uv_stream_t*)&connection, on_alloc, on_read1)); +} + +static void on_connect(uv_connect_t* req, int status) { + ASSERT(0 == status); + + do_write((uv_stream_t*)&client, on_write_close_immediately); +} + +TEST_IMPL(tcp_read_stop_start) { + uv_loop_t* loop = uv_default_loop(); + + { /* Server */ + struct sockaddr_in addr; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + ASSERT(0 == uv_tcp_init(loop, &server)); + + ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) & addr, 0)); + + ASSERT(0 == uv_listen((uv_stream_t*)&server, 10, on_connection)); + } + + { /* Client */ + struct sockaddr_in addr; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + ASSERT(0 == uv_tcp_init(loop, &client)); + + ASSERT(0 == uv_tcp_connect(&connect_req, &client, + (const struct sockaddr*) & addr, on_connect)); + } + + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + + ASSERT(read_cb_called >= 2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-read-stop.c b/external/src/libuv/test/test-tcp-read-stop.c new file mode 100644 index 0000000..488e8fb --- /dev/null +++ b/external/src/libuv/test/test-tcp-read-stop.c @@ -0,0 +1,76 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static uv_timer_t timer_handle; +static uv_tcp_t tcp_handle; +static uv_write_t write_req; + + +static void fail_cb(void) { + ASSERT(0 && "fail_cb called"); +} + + +static void write_cb(uv_write_t* req, int status) { + uv_close((uv_handle_t*) &timer_handle, NULL); + uv_close((uv_handle_t*) &tcp_handle, NULL); +} + + +static void timer_cb(uv_timer_t* handle) { + uv_buf_t buf = uv_buf_init("PING", 4); + ASSERT(0 == uv_write(&write_req, + (uv_stream_t*) &tcp_handle, + &buf, + 1, + write_cb)); + ASSERT(0 == uv_read_stop((uv_stream_t*) &tcp_handle)); +} + + +static void connect_cb(uv_connect_t* req, int status) { + ASSERT(0 == status); + ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 50, 0)); + ASSERT(0 == uv_read_start((uv_stream_t*) &tcp_handle, + (uv_alloc_cb) fail_cb, + (uv_read_cb) fail_cb)); +} + + +TEST_IMPL(tcp_read_stop) { + uv_connect_t connect_req; + struct sockaddr_in addr; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle)); + ASSERT(0 == uv_tcp_init(uv_default_loop(), &tcp_handle)); + ASSERT(0 == uv_tcp_connect(&connect_req, + &tcp_handle, + (const struct sockaddr*) &addr, + connect_cb)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + MAKE_VALGRIND_HAPPY(); + + return 0; +} diff --git a/external/src/libuv/test/test-tcp-shutdown-after-write.c b/external/src/libuv/test/test-tcp-shutdown-after-write.c new file mode 100644 index 0000000..463b4b0 --- /dev/null +++ b/external/src/libuv/test/test-tcp-shutdown-after-write.c @@ -0,0 +1,138 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static void write_cb(uv_write_t* req, int status); +static void shutdown_cb(uv_shutdown_t* req, int status); + +static uv_tcp_t conn; +static uv_timer_t timer; +static uv_connect_t connect_req; +static uv_write_t write_req; +static uv_shutdown_t shutdown_req; + +static int connect_cb_called; +static int write_cb_called; +static int shutdown_cb_called; + +static int conn_close_cb_called; +static int timer_close_cb_called; + + +static void close_cb(uv_handle_t* handle) { + if (handle == (uv_handle_t*)&conn) + conn_close_cb_called++; + else if (handle == (uv_handle_t*)&timer) + timer_close_cb_called++; + else + ASSERT(0 && "bad handle in close_cb"); +} + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[64]; + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void timer_cb(uv_timer_t* handle) { + uv_buf_t buf; + int r; + + uv_close((uv_handle_t*)handle, close_cb); + + buf = uv_buf_init("TEST", 4); + r = uv_write(&write_req, (uv_stream_t*)&conn, &buf, 1, write_cb); + ASSERT(r == 0); + + r = uv_shutdown(&shutdown_req, (uv_stream_t*)&conn, shutdown_cb); + ASSERT(r == 0); +} + + +static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { +} + + +static void connect_cb(uv_connect_t* req, int status) { + int r; + + ASSERT(status == 0); + connect_cb_called++; + + r = uv_read_start((uv_stream_t*)&conn, alloc_cb, read_cb); + ASSERT(r == 0); +} + + +static void write_cb(uv_write_t* req, int status) { + ASSERT(status == 0); + write_cb_called++; +} + + +static void shutdown_cb(uv_shutdown_t* req, int status) { + ASSERT(status == 0); + shutdown_cb_called++; + uv_close((uv_handle_t*)&conn, close_cb); +} + + +TEST_IMPL(tcp_shutdown_after_write) { + struct sockaddr_in addr; + uv_loop_t* loop; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + loop = uv_default_loop(); + + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + + r = uv_timer_start(&timer, timer_cb, 125, 0); + ASSERT(r == 0); + + r = uv_tcp_init(loop, &conn); + ASSERT(r == 0); + + r = uv_tcp_connect(&connect_req, + &conn, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT(r == 0); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(connect_cb_called == 1); + ASSERT(write_cb_called == 1); + ASSERT(shutdown_cb_called == 1); + ASSERT(conn_close_cb_called == 1); + ASSERT(timer_close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-try-write-error.c b/external/src/libuv/test/test-tcp-try-write-error.c new file mode 100644 index 0000000..2201d0e --- /dev/null +++ b/external/src/libuv/test/test-tcp-try-write-error.c @@ -0,0 +1,109 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +static uv_tcp_t server; +static uv_tcp_t client; +static uv_tcp_t incoming; +static int connect_cb_called; +static int close_cb_called; +static int connection_cb_called; + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + +static void incoming_close_cb(uv_handle_t* handle) { + uv_buf_t buf; + int r = 1; + + close_cb_called++; + + buf = uv_buf_init("meow", 4); + while (r > 0) + r = uv_try_write((uv_stream_t*) &client, &buf, 1); + fprintf(stderr, "uv_try_write error: %d %s\n", r, uv_strerror(r)); + ASSERT(r == UV_EPIPE || r == UV_ECONNABORTED || r == UV_ECONNRESET); + ASSERT(client.write_queue_size == 0); +} + + +static void connect_cb(uv_connect_t* req, int status) { + ASSERT(status == 0); + connect_cb_called++; +} + + +static void connection_cb(uv_stream_t* tcp, int status) { + ASSERT(status == 0); + + ASSERT(0 == uv_tcp_init(tcp->loop, &incoming)); + ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming)); + + connection_cb_called++; + uv_close((uv_handle_t*) &incoming, incoming_close_cb); + uv_close((uv_handle_t*) tcp, close_cb); +} + + +static void start_server(void) { + struct sockaddr_in addr; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + ASSERT(0 == uv_tcp_init(uv_default_loop(), &server)); + ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr, 0)); + ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, connection_cb)); +} + + +TEST_IMPL(tcp_try_write_error) { + uv_connect_t connect_req; + struct sockaddr_in addr; + + start_server(); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + ASSERT(0 == uv_tcp_init(uv_default_loop(), &client)); + ASSERT(0 == uv_tcp_connect(&connect_req, + &client, + (struct sockaddr*) &addr, + connect_cb)); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + uv_close((uv_handle_t*) &client, close_cb); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + ASSERT(connect_cb_called == 1); + ASSERT(close_cb_called == 3); + ASSERT(connection_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-try-write.c b/external/src/libuv/test/test-tcp-try-write.c new file mode 100644 index 0000000..97a1d6e --- /dev/null +++ b/external/src/libuv/test/test-tcp-try-write.c @@ -0,0 +1,135 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define MAX_BYTES 1024 * 1024 + +static uv_tcp_t server; +static uv_tcp_t client; +static uv_tcp_t incoming; +static int connect_cb_called; +static int close_cb_called; +static int connection_cb_called; +static int bytes_read; +static int bytes_written; + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + + +static void connect_cb(uv_connect_t* req, int status) { + int r; + uv_buf_t buf; + ASSERT(status == 0); + connect_cb_called++; + + do { + buf = uv_buf_init("PING", 4); + r = uv_try_write((uv_stream_t*) &client, &buf, 1); + ASSERT(r > 0 || r == UV_EAGAIN); + if (r > 0) { + bytes_written += r; + break; + } + } while (1); + + do { + buf = uv_buf_init("", 0); + r = uv_try_write((uv_stream_t*) &client, &buf, 1); + } while (r != 0); + uv_close((uv_handle_t*) &client, close_cb); +} + + +static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + static char base[1024]; + + buf->base = base; + buf->len = sizeof(base); +} + + +static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { + if (nread < 0) { + uv_close((uv_handle_t*) tcp, close_cb); + uv_close((uv_handle_t*) &server, close_cb); + return; + } + + bytes_read += nread; +} + + +static void connection_cb(uv_stream_t* tcp, int status) { + ASSERT(status == 0); + + ASSERT(0 == uv_tcp_init(tcp->loop, &incoming)); + ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming)); + + connection_cb_called++; + ASSERT(0 == uv_read_start((uv_stream_t*) &incoming, alloc_cb, read_cb)); +} + + +static void start_server(void) { + struct sockaddr_in addr; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + ASSERT(0 == uv_tcp_init(uv_default_loop(), &server)); + ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr, 0)); + ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, connection_cb)); +} + + +TEST_IMPL(tcp_try_write) { + uv_connect_t connect_req; + struct sockaddr_in addr; + + start_server(); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + ASSERT(0 == uv_tcp_init(uv_default_loop(), &client)); + ASSERT(0 == uv_tcp_connect(&connect_req, + &client, + (struct sockaddr*) &addr, + connect_cb)); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + ASSERT(connect_cb_called == 1); + ASSERT(close_cb_called == 3); + ASSERT(connection_cb_called == 1); + ASSERT(bytes_read == bytes_written); + ASSERT(bytes_written > 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-unexpected-read.c b/external/src/libuv/test/test-tcp-unexpected-read.c new file mode 100644 index 0000000..c7b9814 --- /dev/null +++ b/external/src/libuv/test/test-tcp-unexpected-read.c @@ -0,0 +1,117 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static uv_check_t check_handle; +static uv_timer_t timer_handle; +static uv_tcp_t server_handle; +static uv_tcp_t client_handle; +static uv_tcp_t peer_handle; +static uv_write_t write_req; +static uv_connect_t connect_req; + +static unsigned long ticks; /* event loop ticks */ + + +static void check_cb(uv_check_t* handle) { + ticks++; +} + + +static void timer_cb(uv_timer_t* handle) { + uv_close((uv_handle_t*) &check_handle, NULL); + uv_close((uv_handle_t*) &timer_handle, NULL); + uv_close((uv_handle_t*) &server_handle, NULL); + uv_close((uv_handle_t*) &client_handle, NULL); + uv_close((uv_handle_t*) &peer_handle, NULL); +} + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + ASSERT(0 && "alloc_cb should not have been called"); +} + + +static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { + ASSERT(0 && "read_cb should not have been called"); +} + + +static void connect_cb(uv_connect_t* req, int status) { + ASSERT(req->handle == (uv_stream_t*) &client_handle); + ASSERT(0 == status); +} + + +static void write_cb(uv_write_t* req, int status) { + ASSERT(req->handle == (uv_stream_t*) &peer_handle); + ASSERT(0 == status); +} + + +static void connection_cb(uv_stream_t* handle, int status) { + uv_buf_t buf; + + buf = uv_buf_init("PING", 4); + + ASSERT(0 == status); + ASSERT(0 == uv_accept(handle, (uv_stream_t*) &peer_handle)); + ASSERT(0 == uv_read_start((uv_stream_t*) &peer_handle, alloc_cb, read_cb)); + ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &peer_handle, + &buf, 1, write_cb)); +} + + +TEST_IMPL(tcp_unexpected_read) { + struct sockaddr_in addr; + uv_loop_t* loop; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + loop = uv_default_loop(); + + ASSERT(0 == uv_timer_init(loop, &timer_handle)); + ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1000, 0)); + ASSERT(0 == uv_check_init(loop, &check_handle)); + ASSERT(0 == uv_check_start(&check_handle, check_cb)); + ASSERT(0 == uv_tcp_init(loop, &server_handle)); + ASSERT(0 == uv_tcp_init(loop, &client_handle)); + ASSERT(0 == uv_tcp_init(loop, &peer_handle)); + ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0)); + ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 1, connection_cb)); + ASSERT(0 == uv_tcp_connect(&connect_req, + &client_handle, + (const struct sockaddr*) &addr, + connect_cb)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + + /* This is somewhat inexact but the idea is that the event loop should not + * start busy looping when the server sends a message and the client isn't + * reading. + */ + ASSERT(ticks <= 20); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-write-after-connect.c b/external/src/libuv/test/test-tcp-write-after-connect.c new file mode 100644 index 0000000..8a698f4 --- /dev/null +++ b/external/src/libuv/test/test-tcp-write-after-connect.c @@ -0,0 +1,77 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifndef _WIN32 + +#include "uv.h" +#include "task.h" + +uv_loop_t loop; +uv_tcp_t tcp_client; +uv_connect_t connection_request; +uv_write_t write_request; +uv_buf_t buf = { "HELLO", 4 }; + + +static void write_cb(uv_write_t *req, int status) { + ASSERT(status == UV_ECANCELED); + uv_close((uv_handle_t*) req->handle, NULL); +} + + +static void connect_cb(uv_connect_t *req, int status) { + ASSERT(status == UV_ECONNREFUSED); +} + + +TEST_IMPL(tcp_write_after_connect) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + + struct sockaddr_in sa; + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa)); + ASSERT(0 == uv_loop_init(&loop)); + ASSERT(0 == uv_tcp_init(&loop, &tcp_client)); + + ASSERT(0 == uv_tcp_connect(&connection_request, + &tcp_client, + (const struct sockaddr *) + &sa, + connect_cb)); + + ASSERT(0 == uv_write(&write_request, + (uv_stream_t *)&tcp_client, + &buf, 1, + write_cb)); + + uv_run(&loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* !_WIN32 */ diff --git a/external/src/libuv/test/test-tcp-write-fail.c b/external/src/libuv/test/test-tcp-write-fail.c new file mode 100644 index 0000000..58ee00f --- /dev/null +++ b/external/src/libuv/test/test-tcp-write-fail.c @@ -0,0 +1,115 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include +#ifndef _WIN32 +# include +#endif + + +static int connect_cb_called = 0; +static int write_cb_called = 0; +static int close_cb_called = 0; + +static uv_connect_t connect_req; +static uv_write_t write_req; + + +static void close_socket(uv_tcp_t* sock) { + uv_os_fd_t fd; + int r; + + r = uv_fileno((uv_handle_t*)sock, &fd); + ASSERT(r == 0); +#ifdef _WIN32 + r = closesocket((uv_os_sock_t)fd); +#else + r = close(fd); +#endif + ASSERT(r == 0); +} + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +static void write_cb(uv_write_t* req, int status) { + ASSERT_NOT_NULL(req); + + ASSERT(status != 0); + fprintf(stderr, "uv_write error: %s\n", uv_strerror(status)); + write_cb_called++; + + uv_close((uv_handle_t*)(req->handle), close_cb); +} + + +static void connect_cb(uv_connect_t* req, int status) { + uv_buf_t buf; + uv_stream_t* stream; + int r; + + ASSERT(req == &connect_req); + ASSERT(status == 0); + + stream = req->handle; + connect_cb_called++; + + /* close the socket, the hard way */ + close_socket((uv_tcp_t*)stream); + + buf = uv_buf_init("hello\n", 6); + r = uv_write(&write_req, stream, &buf, 1, write_cb); + ASSERT(r == 0); +} + + +TEST_IMPL(tcp_write_fail) { + struct sockaddr_in addr; + uv_tcp_t client; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_tcp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + r = uv_tcp_connect(&connect_req, + &client, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT(r == 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(connect_cb_called == 1); + ASSERT(write_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-write-queue-order.c b/external/src/libuv/test/test-tcp-write-queue-order.c new file mode 100644 index 0000000..1ff9c51 --- /dev/null +++ b/external/src/libuv/test/test-tcp-write-queue-order.c @@ -0,0 +1,139 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "uv.h" +#include "task.h" + +#define REQ_COUNT 10000 + +static uv_timer_t timer; +static uv_tcp_t server; +static uv_tcp_t client; +static uv_tcp_t incoming; +static int connect_cb_called; +static int close_cb_called; +static int connection_cb_called; +static int write_callbacks; +static int write_cancelled_callbacks; +static int write_error_callbacks; + +static uv_write_t write_requests[REQ_COUNT]; + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + +static void timer_cb(uv_timer_t* handle) { + uv_close((uv_handle_t*) &client, close_cb); + uv_close((uv_handle_t*) &server, close_cb); + uv_close((uv_handle_t*) &incoming, close_cb); +} + +static void write_cb(uv_write_t* req, int status) { + if (status == 0) + write_callbacks++; + else if (status == UV_ECANCELED) + write_cancelled_callbacks++; + else + write_error_callbacks++; +} + +static void connect_cb(uv_connect_t* req, int status) { + static char base[1024]; + int r; + int i; + uv_buf_t buf; + + ASSERT(status == 0); + connect_cb_called++; + + buf = uv_buf_init(base, sizeof(base)); + + for (i = 0; i < REQ_COUNT; i++) { + r = uv_write(&write_requests[i], + req->handle, + &buf, + 1, + write_cb); + ASSERT(r == 0); + } +} + + +static void connection_cb(uv_stream_t* tcp, int status) { + ASSERT(status == 0); + + ASSERT(0 == uv_tcp_init(tcp->loop, &incoming)); + ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming)); + + ASSERT(0 == uv_timer_init(uv_default_loop(), &timer)); + ASSERT(0 == uv_timer_start(&timer, timer_cb, 1000, 0)); + + connection_cb_called++; +} + + +static void start_server(void) { + struct sockaddr_in addr; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + ASSERT(0 == uv_tcp_init(uv_default_loop(), &server)); + ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr, 0)); + ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, connection_cb)); +} + + +TEST_IMPL(tcp_write_queue_order) { + uv_connect_t connect_req; + struct sockaddr_in addr; + int buffer_size = 16 * 1024; + + start_server(); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + ASSERT(0 == uv_tcp_init(uv_default_loop(), &client)); + ASSERT(0 == uv_tcp_connect(&connect_req, + &client, + (struct sockaddr*) &addr, + connect_cb)); + ASSERT(0 == uv_send_buffer_size((uv_handle_t*) &client, &buffer_size)); + + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + ASSERT(connect_cb_called == 1); + ASSERT(connection_cb_called == 1); + ASSERT(write_callbacks > 0); + ASSERT(write_cancelled_callbacks > 0); + ASSERT(write_callbacks + + write_error_callbacks + + write_cancelled_callbacks == REQ_COUNT); + ASSERT(close_cb_called == 3); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-write-to-half-open-connection.c b/external/src/libuv/test/test-tcp-write-to-half-open-connection.c new file mode 100644 index 0000000..ae42513 --- /dev/null +++ b/external/src/libuv/test/test-tcp-write-to-half-open-connection.c @@ -0,0 +1,141 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +static void connection_cb(uv_stream_t* server, int status); +static void connect_cb(uv_connect_t* req, int status); +static void write_cb(uv_write_t* req, int status); +static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf); +static void alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf); + +static uv_tcp_t tcp_server; +static uv_tcp_t tcp_client; +static uv_tcp_t tcp_peer; /* client socket as accept()-ed by server */ +static uv_connect_t connect_req; +static uv_write_t write_req; + +static int write_cb_called; +static int read_cb_called; + +static void connection_cb(uv_stream_t* server, int status) { + int r; + uv_buf_t buf; + + ASSERT(server == (uv_stream_t*)&tcp_server); + ASSERT(status == 0); + + r = uv_tcp_init(server->loop, &tcp_peer); + ASSERT(r == 0); + + r = uv_accept(server, (uv_stream_t*)&tcp_peer); + ASSERT(r == 0); + + r = uv_read_start((uv_stream_t*)&tcp_peer, alloc_cb, read_cb); + ASSERT(r == 0); + + buf.base = "hello\n"; + buf.len = 6; + + r = uv_write(&write_req, (uv_stream_t*)&tcp_peer, &buf, 1, write_cb); + ASSERT(r == 0); +} + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[1024]; + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { + if (nread < 0) { + fprintf(stderr, "read_cb error: %s\n", uv_err_name(nread)); + ASSERT(nread == UV_ECONNRESET || nread == UV_EOF); + + uv_close((uv_handle_t*)&tcp_server, NULL); + uv_close((uv_handle_t*)&tcp_peer, NULL); + } + + read_cb_called++; +} + + +static void connect_cb(uv_connect_t* req, int status) { + ASSERT(req == &connect_req); + ASSERT(status == 0); + + /* Close the client. */ + uv_close((uv_handle_t*)&tcp_client, NULL); +} + + +static void write_cb(uv_write_t* req, int status) { + ASSERT(status == 0); + write_cb_called++; +} + + +TEST_IMPL(tcp_write_to_half_open_connection) { + struct sockaddr_in addr; + uv_loop_t* loop; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + loop = uv_default_loop(); + ASSERT_NOT_NULL(loop); + + r = uv_tcp_init(loop, &tcp_server); + ASSERT(r == 0); + + r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_listen((uv_stream_t*)&tcp_server, 1, connection_cb); + ASSERT(r == 0); + + r = uv_tcp_init(loop, &tcp_client); + ASSERT(r == 0); + + r = uv_tcp_connect(&connect_req, + &tcp_client, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT(r == 0); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(write_cb_called > 0); + ASSERT(read_cb_called > 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tcp-writealot.c b/external/src/libuv/test/test-tcp-writealot.c new file mode 100644 index 0000000..40dce96 --- /dev/null +++ b/external/src/libuv/test/test-tcp-writealot.c @@ -0,0 +1,180 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include + + +#define WRITES 3 +#if defined(__arm__) /* Decrease the chunks so the test passes on arm CI bots */ +#define CHUNKS_PER_WRITE 2048 +#else +#define CHUNKS_PER_WRITE 4096 +#endif +#define CHUNK_SIZE 10024 /* 10 kb */ + +#define TOTAL_BYTES (WRITES * CHUNKS_PER_WRITE * CHUNK_SIZE) + +static char* send_buffer; + +static int shutdown_cb_called = 0; +static int connect_cb_called = 0; +static int write_cb_called = 0; +static int close_cb_called = 0; +static size_t bytes_sent = 0; +static size_t bytes_sent_done = 0; +static size_t bytes_received_done = 0; + +static uv_connect_t connect_req; +static uv_shutdown_t shutdown_req; +static uv_write_t write_reqs[WRITES]; + + +static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + buf->base = malloc(size); + buf->len = size; +} + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +static void shutdown_cb(uv_shutdown_t* req, int status) { + uv_tcp_t* tcp; + + ASSERT(req == &shutdown_req); + ASSERT(status == 0); + + tcp = (uv_tcp_t*)(req->handle); + + /* The write buffer should be empty by now. */ + ASSERT(tcp->write_queue_size == 0); + + /* Now we wait for the EOF */ + shutdown_cb_called++; + + /* We should have had all the writes called already. */ + ASSERT(write_cb_called == WRITES); +} + + +static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) { + ASSERT_NOT_NULL(tcp); + + if (nread >= 0) { + bytes_received_done += nread; + } + else { + ASSERT(nread == UV_EOF); + printf("GOT EOF\n"); + uv_close((uv_handle_t*)tcp, close_cb); + } + + free(buf->base); +} + + +static void write_cb(uv_write_t* req, int status) { + ASSERT_NOT_NULL(req); + + if (status) { + fprintf(stderr, "uv_write error: %s\n", uv_strerror(status)); + ASSERT(0); + } + + bytes_sent_done += CHUNKS_PER_WRITE * CHUNK_SIZE; + write_cb_called++; +} + + +static void connect_cb(uv_connect_t* req, int status) { + uv_buf_t send_bufs[CHUNKS_PER_WRITE]; + uv_stream_t* stream; + int i, j, r; + + ASSERT(req == &connect_req); + ASSERT(status == 0); + + stream = req->handle; + connect_cb_called++; + + /* Write a lot of data */ + for (i = 0; i < WRITES; i++) { + uv_write_t* write_req = write_reqs + i; + + for (j = 0; j < CHUNKS_PER_WRITE; j++) { + send_bufs[j] = uv_buf_init(send_buffer + bytes_sent, CHUNK_SIZE); + bytes_sent += CHUNK_SIZE; + } + + r = uv_write(write_req, stream, send_bufs, CHUNKS_PER_WRITE, write_cb); + ASSERT(r == 0); + } + + /* Shutdown on drain. */ + r = uv_shutdown(&shutdown_req, stream, shutdown_cb); + ASSERT(r == 0); + + /* Start reading */ + r = uv_read_start(stream, alloc_cb, read_cb); + ASSERT(r == 0); +} + + +TEST_IMPL(tcp_writealot) { + struct sockaddr_in addr; + uv_tcp_t client; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + send_buffer = calloc(1, TOTAL_BYTES); + ASSERT_NOT_NULL(send_buffer); + + r = uv_tcp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + r = uv_tcp_connect(&connect_req, + &client, + (const struct sockaddr*) &addr, + connect_cb); + ASSERT(r == 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(shutdown_cb_called == 1); + ASSERT(connect_cb_called == 1); + ASSERT(write_cb_called == WRITES); + ASSERT(close_cb_called == 1); + ASSERT(bytes_sent == TOTAL_BYTES); + ASSERT(bytes_sent_done == TOTAL_BYTES); + ASSERT(bytes_received_done == TOTAL_BYTES); + + free(send_buffer); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-test-macros.c b/external/src/libuv/test/test-test-macros.c new file mode 100644 index 0000000..72a3992 --- /dev/null +++ b/external/src/libuv/test/test-test-macros.c @@ -0,0 +1,42 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "task.h" + +int test_macros_evil(void) { + static int x; + return x++; +} + + +TEST_IMPL(test_macros) { + char* a = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + char* b = "ABCDEFGHIJKLMNOPQRSTUVWXYz"; + char* c = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int i; + + i = test_macros_evil(); + ASSERT_STR_NE(a, b); + ASSERT_STR_EQ(a, c); + ASSERT_EQ(i + 1, test_macros_evil()); + ASSERT_EQ(i + 2, test_macros_evil()); + return 0; +} diff --git a/external/src/libuv/test/test-thread-equal.c b/external/src/libuv/test/test-thread-equal.c new file mode 100644 index 0000000..27c07ee --- /dev/null +++ b/external/src/libuv/test/test-thread-equal.c @@ -0,0 +1,45 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +uv_thread_t main_thread_id; +uv_thread_t subthreads[2]; + +static void check_thread(void* arg) { + uv_thread_t *thread_id = arg; + uv_thread_t self_id = uv_thread_self(); + ASSERT(uv_thread_equal(&main_thread_id, &self_id) == 0); + *thread_id = uv_thread_self(); +} + +TEST_IMPL(thread_equal) { + uv_thread_t threads[2]; + main_thread_id = uv_thread_self(); + ASSERT(0 != uv_thread_equal(&main_thread_id, &main_thread_id)); + ASSERT(0 == uv_thread_create(threads + 0, check_thread, subthreads + 0)); + ASSERT(0 == uv_thread_create(threads + 1, check_thread, subthreads + 1)); + ASSERT(0 == uv_thread_join(threads + 0)); + ASSERT(0 == uv_thread_join(threads + 1)); + ASSERT(0 == uv_thread_equal(subthreads + 0, subthreads + 1)); + return 0; +} diff --git a/external/src/libuv/test/test-thread.c b/external/src/libuv/test/test-thread.c new file mode 100644 index 0000000..8de5a6f --- /dev/null +++ b/external/src/libuv/test/test-thread.c @@ -0,0 +1,295 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include /* memset */ + +#ifdef __POSIX__ +#include +#endif + +struct getaddrinfo_req { + uv_thread_t thread_id; + unsigned int counter; + uv_loop_t* loop; + uv_getaddrinfo_t handle; +}; + + +struct fs_req { + uv_thread_t thread_id; + unsigned int counter; + uv_loop_t* loop; + uv_fs_t handle; +}; + + +struct test_thread { + uv_thread_t thread_id; + int thread_called; +}; + +static void getaddrinfo_do(struct getaddrinfo_req* req); +static void getaddrinfo_cb(uv_getaddrinfo_t* handle, + int status, + struct addrinfo* res); +static void fs_do(struct fs_req* req); +static void fs_cb(uv_fs_t* handle); + +static int thread_called; +static uv_key_t tls_key; + + +static void getaddrinfo_do(struct getaddrinfo_req* req) { + int r; + + r = uv_getaddrinfo(req->loop, + &req->handle, + getaddrinfo_cb, + "localhost", + NULL, + NULL); + ASSERT(r == 0); +} + + +static void getaddrinfo_cb(uv_getaddrinfo_t* handle, + int status, + struct addrinfo* res) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + struct getaddrinfo_req* req; + + ASSERT(status == 0); + + req = container_of(handle, struct getaddrinfo_req, handle); + uv_freeaddrinfo(res); + + if (--req->counter) + getaddrinfo_do(req); +} + + +static void fs_do(struct fs_req* req) { + int r; + + r = uv_fs_stat(req->loop, &req->handle, ".", fs_cb); + ASSERT(r == 0); +} + + +static void fs_cb(uv_fs_t* handle) { + struct fs_req* req = container_of(handle, struct fs_req, handle); + + uv_fs_req_cleanup(handle); + + if (--req->counter) + fs_do(req); +} + + +static void do_work(void* arg) { + struct getaddrinfo_req getaddrinfo_reqs[4]; + struct fs_req fs_reqs[4]; + uv_loop_t loop; + size_t i; + struct test_thread* thread = arg; + + ASSERT(0 == uv_loop_init(&loop)); + + for (i = 0; i < ARRAY_SIZE(getaddrinfo_reqs); i++) { + struct getaddrinfo_req* req = getaddrinfo_reqs + i; + req->counter = 4; + req->loop = &loop; + getaddrinfo_do(req); + } + + for (i = 0; i < ARRAY_SIZE(fs_reqs); i++) { + struct fs_req* req = fs_reqs + i; + req->counter = 4; + req->loop = &loop; + fs_do(req); + } + + ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); + ASSERT(0 == uv_loop_close(&loop)); + thread->thread_called = 1; +} + + +static void thread_entry(void* arg) { + ASSERT(arg == (void *) 42); + thread_called++; +} + + +TEST_IMPL(thread_create) { + uv_thread_t tid; + int r; + + r = uv_thread_create(&tid, thread_entry, (void *) 42); + ASSERT(r == 0); + + r = uv_thread_join(&tid); + ASSERT(r == 0); + + ASSERT(thread_called == 1); + + return 0; +} + + +/* Hilariously bad test name. Run a lot of tasks in the thread pool and verify + * that each "finished" callback is run in its originating thread. + */ +TEST_IMPL(threadpool_multiple_event_loops) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + + struct test_thread threads[8]; + size_t i; + int r; + + memset(threads, 0, sizeof(threads)); + + for (i = 0; i < ARRAY_SIZE(threads); i++) { + r = uv_thread_create(&threads[i].thread_id, do_work, &threads[i]); + ASSERT(r == 0); + } + + for (i = 0; i < ARRAY_SIZE(threads); i++) { + r = uv_thread_join(&threads[i].thread_id); + ASSERT(r == 0); + ASSERT(threads[i].thread_called == 1); + } + + return 0; +} + + +static void tls_thread(void* arg) { + ASSERT_NULL(uv_key_get(&tls_key)); + uv_key_set(&tls_key, arg); + ASSERT(arg == uv_key_get(&tls_key)); + uv_key_set(&tls_key, NULL); + ASSERT_NULL(uv_key_get(&tls_key)); +} + + +TEST_IMPL(thread_local_storage) { + char name[] = "main"; + uv_thread_t threads[2]; + ASSERT(0 == uv_key_create(&tls_key)); + ASSERT_NULL(uv_key_get(&tls_key)); + uv_key_set(&tls_key, name); + ASSERT(name == uv_key_get(&tls_key)); + ASSERT(0 == uv_thread_create(threads + 0, tls_thread, threads + 0)); + ASSERT(0 == uv_thread_create(threads + 1, tls_thread, threads + 1)); + ASSERT(0 == uv_thread_join(threads + 0)); + ASSERT(0 == uv_thread_join(threads + 1)); + uv_key_delete(&tls_key); + return 0; +} + + +static void thread_check_stack(void* arg) { +#if defined(__APPLE__) + size_t expected; + expected = arg == NULL ? 0 : ((uv_thread_options_t*)arg)->stack_size; + /* 512 kB is the default stack size of threads other than the main thread + * on MacOS. */ + if (expected == 0) + expected = 512 * 1024; + ASSERT(pthread_get_stacksize_np(pthread_self()) >= expected); +#elif defined(__linux__) && defined(__GLIBC__) + size_t expected; + struct rlimit lim; + size_t stack_size; + pthread_attr_t attr; + ASSERT(0 == getrlimit(RLIMIT_STACK, &lim)); + if (lim.rlim_cur == RLIM_INFINITY) + lim.rlim_cur = 2 << 20; /* glibc default. */ + ASSERT(0 == pthread_getattr_np(pthread_self(), &attr)); + ASSERT(0 == pthread_attr_getstacksize(&attr, &stack_size)); + expected = arg == NULL ? 0 : ((uv_thread_options_t*)arg)->stack_size; + if (expected == 0) + expected = (size_t)lim.rlim_cur; + ASSERT(stack_size >= expected); + ASSERT(0 == pthread_attr_destroy(&attr)); +#endif +} + + +TEST_IMPL(thread_stack_size) { + uv_thread_t thread; + ASSERT(0 == uv_thread_create(&thread, thread_check_stack, NULL)); + ASSERT(0 == uv_thread_join(&thread)); + return 0; +} + +TEST_IMPL(thread_stack_size_explicit) { + uv_thread_t thread; + uv_thread_options_t options; + + options.flags = UV_THREAD_HAS_STACK_SIZE; + options.stack_size = 1024 * 1024; + ASSERT(0 == uv_thread_create_ex(&thread, &options, + thread_check_stack, &options)); + ASSERT(0 == uv_thread_join(&thread)); + + options.stack_size = 8 * 1024 * 1024; /* larger than most default os sizes */ + ASSERT(0 == uv_thread_create_ex(&thread, &options, + thread_check_stack, &options)); + ASSERT(0 == uv_thread_join(&thread)); + + options.stack_size = 0; + ASSERT(0 == uv_thread_create_ex(&thread, &options, + thread_check_stack, &options)); + ASSERT(0 == uv_thread_join(&thread)); + +#ifdef PTHREAD_STACK_MIN + options.stack_size = PTHREAD_STACK_MIN - 42; /* unaligned size */ + ASSERT(0 == uv_thread_create_ex(&thread, &options, + thread_check_stack, &options)); + ASSERT(0 == uv_thread_join(&thread)); + + options.stack_size = PTHREAD_STACK_MIN / 2 - 42; /* unaligned size */ + ASSERT(0 == uv_thread_create_ex(&thread, &options, + thread_check_stack, &options)); + ASSERT(0 == uv_thread_join(&thread)); +#endif + + /* unaligned size, should be larger than PTHREAD_STACK_MIN */ + options.stack_size = 1234567; + ASSERT(0 == uv_thread_create_ex(&thread, &options, + thread_check_stack, &options)); + ASSERT(0 == uv_thread_join(&thread)); + + return 0; +} diff --git a/external/src/libuv/test/test-threadpool-cancel.c b/external/src/libuv/test/test-threadpool-cancel.c new file mode 100644 index 0000000..1e867c5 --- /dev/null +++ b/external/src/libuv/test/test-threadpool-cancel.c @@ -0,0 +1,349 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#define INIT_CANCEL_INFO(ci, what) \ + do { \ + (ci)->reqs = (what); \ + (ci)->nreqs = ARRAY_SIZE(what); \ + (ci)->stride = sizeof((what)[0]); \ + } \ + while (0) + +struct cancel_info { + void* reqs; + unsigned nreqs; + unsigned stride; + uv_timer_t timer_handle; +}; + +struct random_info { + uv_random_t random_req; + char buf[1]; +}; + +static unsigned fs_cb_called; +static unsigned done_cb_called; +static unsigned done2_cb_called; +static unsigned timer_cb_called; +static uv_work_t pause_reqs[4]; +static uv_sem_t pause_sems[ARRAY_SIZE(pause_reqs)]; + + +static void work_cb(uv_work_t* req) { + uv_sem_wait(pause_sems + (req - pause_reqs)); +} + + +static void done_cb(uv_work_t* req, int status) { + uv_sem_destroy(pause_sems + (req - pause_reqs)); +} + + +static void saturate_threadpool(void) { + uv_loop_t* loop; + char buf[64]; + size_t i; + + snprintf(buf, + sizeof(buf), + "UV_THREADPOOL_SIZE=%lu", + (unsigned long)ARRAY_SIZE(pause_reqs)); + putenv(buf); + + loop = uv_default_loop(); + for (i = 0; i < ARRAY_SIZE(pause_reqs); i += 1) { + ASSERT(0 == uv_sem_init(pause_sems + i, 0)); + ASSERT(0 == uv_queue_work(loop, pause_reqs + i, work_cb, done_cb)); + } +} + + +static void unblock_threadpool(void) { + size_t i; + + for (i = 0; i < ARRAY_SIZE(pause_reqs); i += 1) + uv_sem_post(pause_sems + i); +} + + +static void fs_cb(uv_fs_t* req) { + ASSERT(req->result == UV_ECANCELED); + uv_fs_req_cleanup(req); + fs_cb_called++; +} + + +static void getaddrinfo_cb(uv_getaddrinfo_t* req, + int status, + struct addrinfo* res) { + ASSERT(status == UV_EAI_CANCELED); + ASSERT_NULL(res); + uv_freeaddrinfo(res); /* Should not crash. */ +} + + +static void getnameinfo_cb(uv_getnameinfo_t* handle, + int status, + const char* hostname, + const char* service) { + ASSERT(status == UV_EAI_CANCELED); + ASSERT_NULL(hostname); + ASSERT_NULL(service); +} + + +static void work2_cb(uv_work_t* req) { + ASSERT(0 && "work2_cb called"); +} + + +static void done2_cb(uv_work_t* req, int status) { + ASSERT(status == UV_ECANCELED); + done2_cb_called++; +} + + +static void timer_cb(uv_timer_t* handle) { + struct cancel_info* ci; + uv_req_t* req; + unsigned i; + + ci = container_of(handle, struct cancel_info, timer_handle); + + for (i = 0; i < ci->nreqs; i++) { + req = (uv_req_t*) ((char*) ci->reqs + i * ci->stride); + ASSERT(0 == uv_cancel(req)); + } + + uv_close((uv_handle_t*) &ci->timer_handle, NULL); + unblock_threadpool(); + timer_cb_called++; +} + + +static void nop_done_cb(uv_work_t* req, int status) { + ASSERT(status == UV_ECANCELED); + done_cb_called++; +} + + +static void nop_random_cb(uv_random_t* req, int status, void* buf, size_t len) { + struct random_info* ri; + + ri = container_of(req, struct random_info, random_req); + + ASSERT(status == UV_ECANCELED); + ASSERT(buf == (void*) ri->buf); + ASSERT(len == sizeof(ri->buf)); + + done_cb_called++; +} + + +TEST_IMPL(threadpool_cancel_getaddrinfo) { + uv_getaddrinfo_t reqs[4]; + struct cancel_info ci; + struct addrinfo hints; + uv_loop_t* loop; + int r; + + INIT_CANCEL_INFO(&ci, reqs); + loop = uv_default_loop(); + saturate_threadpool(); + + r = uv_getaddrinfo(loop, reqs + 0, getaddrinfo_cb, "fail", NULL, NULL); + ASSERT(r == 0); + + r = uv_getaddrinfo(loop, reqs + 1, getaddrinfo_cb, NULL, "fail", NULL); + ASSERT(r == 0); + + r = uv_getaddrinfo(loop, reqs + 2, getaddrinfo_cb, "fail", "fail", NULL); + ASSERT(r == 0); + + r = uv_getaddrinfo(loop, reqs + 3, getaddrinfo_cb, "fail", NULL, &hints); + ASSERT(r == 0); + + ASSERT(0 == uv_timer_init(loop, &ci.timer_handle)); + ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(1 == timer_cb_called); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(threadpool_cancel_getnameinfo) { + uv_getnameinfo_t reqs[4]; + struct sockaddr_in addr4; + struct cancel_info ci; + uv_loop_t* loop; + int r; + + r = uv_ip4_addr("127.0.0.1", 80, &addr4); + ASSERT(r == 0); + + INIT_CANCEL_INFO(&ci, reqs); + loop = uv_default_loop(); + saturate_threadpool(); + + r = uv_getnameinfo(loop, reqs + 0, getnameinfo_cb, (const struct sockaddr*)&addr4, 0); + ASSERT(r == 0); + + r = uv_getnameinfo(loop, reqs + 1, getnameinfo_cb, (const struct sockaddr*)&addr4, 0); + ASSERT(r == 0); + + r = uv_getnameinfo(loop, reqs + 2, getnameinfo_cb, (const struct sockaddr*)&addr4, 0); + ASSERT(r == 0); + + r = uv_getnameinfo(loop, reqs + 3, getnameinfo_cb, (const struct sockaddr*)&addr4, 0); + ASSERT(r == 0); + + ASSERT(0 == uv_timer_init(loop, &ci.timer_handle)); + ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(1 == timer_cb_called); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(threadpool_cancel_random) { + struct random_info req; + uv_loop_t* loop; + + saturate_threadpool(); + loop = uv_default_loop(); + ASSERT(0 == uv_random(loop, + &req.random_req, + &req.buf, + sizeof(req.buf), + 0, + nop_random_cb)); + ASSERT(0 == uv_cancel((uv_req_t*) &req)); + ASSERT(0 == done_cb_called); + unblock_threadpool(); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(1 == done_cb_called); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(threadpool_cancel_work) { + struct cancel_info ci; + uv_work_t reqs[16]; + uv_loop_t* loop; + unsigned i; + + INIT_CANCEL_INFO(&ci, reqs); + loop = uv_default_loop(); + saturate_threadpool(); + + for (i = 0; i < ARRAY_SIZE(reqs); i++) + ASSERT(0 == uv_queue_work(loop, reqs + i, work2_cb, done2_cb)); + + ASSERT(0 == uv_timer_init(loop, &ci.timer_handle)); + ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(1 == timer_cb_called); + ASSERT(ARRAY_SIZE(reqs) == done2_cb_called); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(threadpool_cancel_fs) { + struct cancel_info ci; + uv_fs_t reqs[26]; + uv_loop_t* loop; + unsigned n; + uv_buf_t iov; + + INIT_CANCEL_INFO(&ci, reqs); + loop = uv_default_loop(); + saturate_threadpool(); + iov = uv_buf_init(NULL, 0); + + /* Needs to match ARRAY_SIZE(fs_reqs). */ + n = 0; + ASSERT(0 == uv_fs_chmod(loop, reqs + n++, "/", 0, fs_cb)); + ASSERT(0 == uv_fs_chown(loop, reqs + n++, "/", 0, 0, fs_cb)); + ASSERT(0 == uv_fs_close(loop, reqs + n++, 0, fs_cb)); + ASSERT(0 == uv_fs_fchmod(loop, reqs + n++, 0, 0, fs_cb)); + ASSERT(0 == uv_fs_fchown(loop, reqs + n++, 0, 0, 0, fs_cb)); + ASSERT(0 == uv_fs_fdatasync(loop, reqs + n++, 0, fs_cb)); + ASSERT(0 == uv_fs_fstat(loop, reqs + n++, 0, fs_cb)); + ASSERT(0 == uv_fs_fsync(loop, reqs + n++, 0, fs_cb)); + ASSERT(0 == uv_fs_ftruncate(loop, reqs + n++, 0, 0, fs_cb)); + ASSERT(0 == uv_fs_futime(loop, reqs + n++, 0, 0, 0, fs_cb)); + ASSERT(0 == uv_fs_link(loop, reqs + n++, "/", "/", fs_cb)); + ASSERT(0 == uv_fs_lstat(loop, reqs + n++, "/", fs_cb)); + ASSERT(0 == uv_fs_mkdir(loop, reqs + n++, "/", 0, fs_cb)); + ASSERT(0 == uv_fs_open(loop, reqs + n++, "/", 0, 0, fs_cb)); + ASSERT(0 == uv_fs_read(loop, reqs + n++, 0, &iov, 1, 0, fs_cb)); + ASSERT(0 == uv_fs_scandir(loop, reqs + n++, "/", 0, fs_cb)); + ASSERT(0 == uv_fs_readlink(loop, reqs + n++, "/", fs_cb)); + ASSERT(0 == uv_fs_realpath(loop, reqs + n++, "/", fs_cb)); + ASSERT(0 == uv_fs_rename(loop, reqs + n++, "/", "/", fs_cb)); + ASSERT(0 == uv_fs_mkdir(loop, reqs + n++, "/", 0, fs_cb)); + ASSERT(0 == uv_fs_sendfile(loop, reqs + n++, 0, 0, 0, 0, fs_cb)); + ASSERT(0 == uv_fs_stat(loop, reqs + n++, "/", fs_cb)); + ASSERT(0 == uv_fs_symlink(loop, reqs + n++, "/", "/", 0, fs_cb)); + ASSERT(0 == uv_fs_unlink(loop, reqs + n++, "/", fs_cb)); + ASSERT(0 == uv_fs_utime(loop, reqs + n++, "/", 0, 0, fs_cb)); + ASSERT(0 == uv_fs_write(loop, reqs + n++, 0, &iov, 1, 0, fs_cb)); + ASSERT(n == ARRAY_SIZE(reqs)); + + ASSERT(0 == uv_timer_init(loop, &ci.timer_handle)); + ASSERT(0 == uv_timer_start(&ci.timer_handle, timer_cb, 10, 0)); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(n == fs_cb_called); + ASSERT(1 == timer_cb_called); + + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(threadpool_cancel_single) { + uv_loop_t* loop; + uv_work_t req; + + saturate_threadpool(); + loop = uv_default_loop(); + ASSERT(0 == uv_queue_work(loop, &req, (uv_work_cb) abort, nop_done_cb)); + ASSERT(0 == uv_cancel((uv_req_t*) &req)); + ASSERT(0 == done_cb_called); + unblock_threadpool(); + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + ASSERT(1 == done_cb_called); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-threadpool.c b/external/src/libuv/test/test-threadpool.c new file mode 100644 index 0000000..e3d17d7 --- /dev/null +++ b/external/src/libuv/test/test-threadpool.c @@ -0,0 +1,76 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static int work_cb_count; +static int after_work_cb_count; +static uv_work_t work_req; +static char data; + + +static void work_cb(uv_work_t* req) { + ASSERT(req == &work_req); + ASSERT(req->data == &data); + work_cb_count++; +} + + +static void after_work_cb(uv_work_t* req, int status) { + ASSERT(status == 0); + ASSERT(req == &work_req); + ASSERT(req->data == &data); + after_work_cb_count++; +} + + +TEST_IMPL(threadpool_queue_work_simple) { + int r; + + work_req.data = &data; + r = uv_queue_work(uv_default_loop(), &work_req, work_cb, after_work_cb); + ASSERT(r == 0); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(work_cb_count == 1); + ASSERT(after_work_cb_count == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(threadpool_queue_work_einval) { + int r; + + work_req.data = &data; + r = uv_queue_work(uv_default_loop(), &work_req, NULL, after_work_cb); + ASSERT(r == UV_EINVAL); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(work_cb_count == 0); + ASSERT(after_work_cb_count == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-timer-again.c b/external/src/libuv/test/test-timer-again.c new file mode 100644 index 0000000..834b59d --- /dev/null +++ b/external/src/libuv/test/test-timer-again.c @@ -0,0 +1,141 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + + +static int close_cb_called = 0; +static int repeat_1_cb_called = 0; +static int repeat_2_cb_called = 0; + +static int repeat_2_cb_allowed = 0; + +static uv_timer_t dummy, repeat_1, repeat_2; + +static uint64_t start_time; + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + + close_cb_called++; +} + + +static void repeat_1_cb(uv_timer_t* handle) { + int r; + + ASSERT(handle == &repeat_1); + ASSERT(uv_timer_get_repeat((uv_timer_t*)handle) == 50); + + fprintf(stderr, "repeat_1_cb called after %ld ms\n", + (long int)(uv_now(uv_default_loop()) - start_time)); + fflush(stderr); + + repeat_1_cb_called++; + + r = uv_timer_again(&repeat_2); + ASSERT(r == 0); + + if (repeat_1_cb_called == 10) { + uv_close((uv_handle_t*)handle, close_cb); + /* We're not calling uv_timer_again on repeat_2 any more, so after this + * timer_2_cb is expected. */ + repeat_2_cb_allowed = 1; + return; + } +} + + +static void repeat_2_cb(uv_timer_t* handle) { + ASSERT(handle == &repeat_2); + ASSERT(repeat_2_cb_allowed); + + fprintf(stderr, "repeat_2_cb called after %ld ms\n", + (long int)(uv_now(uv_default_loop()) - start_time)); + fflush(stderr); + + repeat_2_cb_called++; + + if (uv_timer_get_repeat(&repeat_2) == 0) { + ASSERT(0 == uv_is_active((uv_handle_t*) handle)); + uv_close((uv_handle_t*)handle, close_cb); + return; + } + + fprintf(stderr, "uv_timer_get_repeat %ld ms\n", + (long int)uv_timer_get_repeat(&repeat_2)); + fflush(stderr); + ASSERT(uv_timer_get_repeat(&repeat_2) == 100); + + /* This shouldn't take effect immediately. */ + uv_timer_set_repeat(&repeat_2, 0); +} + + +TEST_IMPL(timer_again) { + int r; + + start_time = uv_now(uv_default_loop()); + ASSERT(0 < start_time); + + /* Verify that it is not possible to uv_timer_again a never-started timer. */ + r = uv_timer_init(uv_default_loop(), &dummy); + ASSERT(r == 0); + r = uv_timer_again(&dummy); + ASSERT(r == UV_EINVAL); + uv_unref((uv_handle_t*)&dummy); + + /* Start timer repeat_1. */ + r = uv_timer_init(uv_default_loop(), &repeat_1); + ASSERT(r == 0); + r = uv_timer_start(&repeat_1, repeat_1_cb, 50, 0); + ASSERT(r == 0); + ASSERT(uv_timer_get_repeat(&repeat_1) == 0); + + /* Actually make repeat_1 repeating. */ + uv_timer_set_repeat(&repeat_1, 50); + ASSERT(uv_timer_get_repeat(&repeat_1) == 50); + + /* + * Start another repeating timer. It'll be again()ed by the repeat_1 so + * it should not time out until repeat_1 stops. + */ + r = uv_timer_init(uv_default_loop(), &repeat_2); + ASSERT(r == 0); + r = uv_timer_start(&repeat_2, repeat_2_cb, 100, 100); + ASSERT(r == 0); + ASSERT(uv_timer_get_repeat(&repeat_2) == 100); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(repeat_1_cb_called == 10); + ASSERT(repeat_2_cb_called == 2); + ASSERT(close_cb_called == 2); + + fprintf(stderr, "Test took %ld ms (expected ~700 ms)\n", + (long int)(uv_now(uv_default_loop()) - start_time)); + fflush(stderr); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-timer-from-check.c b/external/src/libuv/test/test-timer-from-check.c new file mode 100644 index 0000000..a18c7e1 --- /dev/null +++ b/external/src/libuv/test/test-timer-from-check.c @@ -0,0 +1,80 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +static uv_prepare_t prepare_handle; +static uv_check_t check_handle; +static uv_timer_t timer_handle; + +static int prepare_cb_called; +static int check_cb_called; +static int timer_cb_called; + + +static void prepare_cb(uv_prepare_t* handle) { + ASSERT(0 == uv_prepare_stop(&prepare_handle)); + ASSERT(0 == prepare_cb_called); + ASSERT(1 == check_cb_called); + ASSERT(0 == timer_cb_called); + prepare_cb_called++; +} + + +static void timer_cb(uv_timer_t* handle) { + ASSERT(0 == uv_timer_stop(&timer_handle)); + ASSERT(1 == prepare_cb_called); + ASSERT(1 == check_cb_called); + ASSERT(0 == timer_cb_called); + timer_cb_called++; +} + + +static void check_cb(uv_check_t* handle) { + ASSERT(0 == uv_check_stop(&check_handle)); + ASSERT(0 == uv_timer_stop(&timer_handle)); /* Runs before timer_cb. */ + ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 50, 0)); + ASSERT(0 == uv_prepare_start(&prepare_handle, prepare_cb)); + ASSERT(0 == prepare_cb_called); + ASSERT(0 == check_cb_called); + ASSERT(0 == timer_cb_called); + check_cb_called++; +} + + +TEST_IMPL(timer_from_check) { + ASSERT(0 == uv_prepare_init(uv_default_loop(), &prepare_handle)); + ASSERT(0 == uv_check_init(uv_default_loop(), &check_handle)); + ASSERT(0 == uv_check_start(&check_handle, check_cb)); + ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle)); + ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 50, 0)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT(1 == prepare_cb_called); + ASSERT(1 == check_cb_called); + ASSERT(1 == timer_cb_called); + uv_close((uv_handle_t*) &prepare_handle, NULL); + uv_close((uv_handle_t*) &check_handle, NULL); + uv_close((uv_handle_t*) &timer_handle, NULL); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-timer.c b/external/src/libuv/test/test-timer.c new file mode 100644 index 0000000..d0921a9 --- /dev/null +++ b/external/src/libuv/test/test-timer.c @@ -0,0 +1,347 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + + +static int once_cb_called = 0; +static int once_close_cb_called = 0; +static int repeat_cb_called = 0; +static int repeat_close_cb_called = 0; +static int order_cb_called = 0; +static uint64_t start_time; +static uv_timer_t tiny_timer; +static uv_timer_t huge_timer1; +static uv_timer_t huge_timer2; + + +static void once_close_cb(uv_handle_t* handle) { + printf("ONCE_CLOSE_CB\n"); + + ASSERT_NOT_NULL(handle); + ASSERT(0 == uv_is_active(handle)); + + once_close_cb_called++; +} + + +static void once_cb(uv_timer_t* handle) { + printf("ONCE_CB %d\n", once_cb_called); + + ASSERT_NOT_NULL(handle); + ASSERT(0 == uv_is_active((uv_handle_t*) handle)); + + once_cb_called++; + + uv_close((uv_handle_t*)handle, once_close_cb); + + /* Just call this randomly for the code coverage. */ + uv_update_time(uv_default_loop()); +} + + +static void repeat_close_cb(uv_handle_t* handle) { + printf("REPEAT_CLOSE_CB\n"); + + ASSERT_NOT_NULL(handle); + + repeat_close_cb_called++; +} + + +static void repeat_cb(uv_timer_t* handle) { + printf("REPEAT_CB\n"); + + ASSERT_NOT_NULL(handle); + ASSERT(1 == uv_is_active((uv_handle_t*) handle)); + + repeat_cb_called++; + + if (repeat_cb_called == 5) { + uv_close((uv_handle_t*)handle, repeat_close_cb); + } +} + + +static void never_cb(uv_timer_t* handle) { + FATAL("never_cb should never be called"); +} + + +TEST_IMPL(timer) { + uv_timer_t once_timers[10]; + uv_timer_t *once; + uv_timer_t repeat, never; + unsigned int i; + int r; + + start_time = uv_now(uv_default_loop()); + ASSERT(0 < start_time); + + /* Let 10 timers time out in 500 ms total. */ + for (i = 0; i < ARRAY_SIZE(once_timers); i++) { + once = once_timers + i; + r = uv_timer_init(uv_default_loop(), once); + ASSERT(r == 0); + r = uv_timer_start(once, once_cb, i * 50, 0); + ASSERT(r == 0); + } + + /* The 11th timer is a repeating timer that runs 4 times */ + r = uv_timer_init(uv_default_loop(), &repeat); + ASSERT(r == 0); + r = uv_timer_start(&repeat, repeat_cb, 100, 100); + ASSERT(r == 0); + + /* The 12th timer should not do anything. */ + r = uv_timer_init(uv_default_loop(), &never); + ASSERT(r == 0); + r = uv_timer_start(&never, never_cb, 100, 100); + ASSERT(r == 0); + r = uv_timer_stop(&never); + ASSERT(r == 0); + uv_unref((uv_handle_t*)&never); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(once_cb_called == 10); + ASSERT(once_close_cb_called == 10); + printf("repeat_cb_called %d\n", repeat_cb_called); + ASSERT(repeat_cb_called == 5); + ASSERT(repeat_close_cb_called == 1); + + ASSERT(500 <= uv_now(uv_default_loop()) - start_time); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(timer_start_twice) { + uv_timer_t once; + int r; + + r = uv_timer_init(uv_default_loop(), &once); + ASSERT(r == 0); + r = uv_timer_start(&once, never_cb, 86400 * 1000, 0); + ASSERT(r == 0); + r = uv_timer_start(&once, once_cb, 10, 0); + ASSERT(r == 0); + r = uv_run(uv_default_loop(), UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(once_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(timer_init) { + uv_timer_t handle; + + ASSERT(0 == uv_timer_init(uv_default_loop(), &handle)); + ASSERT(0 == uv_timer_get_repeat(&handle)); + ASSERT_UINT64_LE(0, uv_timer_get_due_in(&handle)); + ASSERT(0 == uv_is_active((uv_handle_t*) &handle)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void order_cb_a(uv_timer_t *handle) { + ASSERT(order_cb_called++ == *(int*)handle->data); +} + + +static void order_cb_b(uv_timer_t *handle) { + ASSERT(order_cb_called++ == *(int*)handle->data); +} + + +TEST_IMPL(timer_order) { + int first; + int second; + uv_timer_t handle_a; + uv_timer_t handle_b; + + first = 0; + second = 1; + ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_a)); + ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_b)); + + /* Test for starting handle_a then handle_b */ + handle_a.data = &first; + ASSERT(0 == uv_timer_start(&handle_a, order_cb_a, 0, 0)); + handle_b.data = &second; + ASSERT(0 == uv_timer_start(&handle_b, order_cb_b, 0, 0)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + ASSERT(order_cb_called == 2); + + ASSERT(0 == uv_timer_stop(&handle_a)); + ASSERT(0 == uv_timer_stop(&handle_b)); + + /* Test for starting handle_b then handle_a */ + order_cb_called = 0; + handle_b.data = &first; + ASSERT(0 == uv_timer_start(&handle_b, order_cb_b, 0, 0)); + + handle_a.data = &second; + ASSERT(0 == uv_timer_start(&handle_a, order_cb_a, 0, 0)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + ASSERT(order_cb_called == 2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void tiny_timer_cb(uv_timer_t* handle) { + ASSERT(handle == &tiny_timer); + uv_close((uv_handle_t*) &tiny_timer, NULL); + uv_close((uv_handle_t*) &huge_timer1, NULL); + uv_close((uv_handle_t*) &huge_timer2, NULL); +} + + +TEST_IMPL(timer_huge_timeout) { + ASSERT(0 == uv_timer_init(uv_default_loop(), &tiny_timer)); + ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer1)); + ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer2)); + ASSERT(0 == uv_timer_start(&tiny_timer, tiny_timer_cb, 1, 0)); + ASSERT(0 == uv_timer_start(&huge_timer1, tiny_timer_cb, 0xffffffffffffLL, 0)); + ASSERT(0 == uv_timer_start(&huge_timer2, tiny_timer_cb, (uint64_t) -1, 0)); + ASSERT_UINT64_EQ(1, uv_timer_get_due_in(&tiny_timer)); + ASSERT_UINT64_EQ(281474976710655, uv_timer_get_due_in(&huge_timer1)); + ASSERT_UINT64_LE(0, uv_timer_get_due_in(&huge_timer2)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static void huge_repeat_cb(uv_timer_t* handle) { + static int ncalls; + + if (ncalls == 0) + ASSERT(handle == &huge_timer1); + else + ASSERT(handle == &tiny_timer); + + if (++ncalls == 10) { + uv_close((uv_handle_t*) &tiny_timer, NULL); + uv_close((uv_handle_t*) &huge_timer1, NULL); + } +} + + +TEST_IMPL(timer_huge_repeat) { + ASSERT(0 == uv_timer_init(uv_default_loop(), &tiny_timer)); + ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer1)); + ASSERT(0 == uv_timer_start(&tiny_timer, huge_repeat_cb, 2, 2)); + ASSERT(0 == uv_timer_start(&huge_timer1, huge_repeat_cb, 1, (uint64_t) -1)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static unsigned int timer_run_once_timer_cb_called; + + +static void timer_run_once_timer_cb(uv_timer_t* handle) { + timer_run_once_timer_cb_called++; +} + + +TEST_IMPL(timer_run_once) { + uv_timer_t timer_handle; + + ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle)); + ASSERT(0 == uv_timer_start(&timer_handle, timer_run_once_timer_cb, 0, 0)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); + ASSERT(1 == timer_run_once_timer_cb_called); + + ASSERT(0 == uv_timer_start(&timer_handle, timer_run_once_timer_cb, 1, 0)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); + ASSERT(2 == timer_run_once_timer_cb_called); + + uv_close((uv_handle_t*) &timer_handle, NULL); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(timer_is_closing) { + uv_timer_t handle; + + ASSERT(0 == uv_timer_init(uv_default_loop(), &handle)); + uv_close((uv_handle_t *)&handle, NULL); + + ASSERT(UV_EINVAL == uv_timer_start(&handle, never_cb, 100, 100)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(timer_null_callback) { + uv_timer_t handle; + + ASSERT(0 == uv_timer_init(uv_default_loop(), &handle)); + ASSERT(UV_EINVAL == uv_timer_start(&handle, NULL, 100, 100)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +static uint64_t timer_early_check_expected_time; + + +static void timer_early_check_cb(uv_timer_t* handle) { + uint64_t hrtime = uv_hrtime() / 1000000; + ASSERT(hrtime >= timer_early_check_expected_time); +} + + +TEST_IMPL(timer_early_check) { + uv_timer_t timer_handle; + const uint64_t timeout_ms = 10; + + timer_early_check_expected_time = uv_now(uv_default_loop()) + timeout_ms; + + ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle)); + ASSERT(0 == uv_timer_start(&timer_handle, timer_early_check_cb, timeout_ms, 0)); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + uv_close((uv_handle_t*) &timer_handle, NULL); + ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-tmpdir.c b/external/src/libuv/test/test-tmpdir.c new file mode 100644 index 0000000..86f72e2 --- /dev/null +++ b/external/src/libuv/test/test-tmpdir.c @@ -0,0 +1,82 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +#define PATHMAX 4096 +#define SMALLPATH 1 + +TEST_IMPL(tmpdir) { + char tmpdir[PATHMAX]; + size_t len; + char last; + int r; + + /* Test the normal case */ + len = sizeof tmpdir; + tmpdir[0] = '\0'; + + ASSERT(strlen(tmpdir) == 0); + r = uv_os_tmpdir(tmpdir, &len); + ASSERT(r == 0); + ASSERT(strlen(tmpdir) == len); + ASSERT(len > 0); + ASSERT(tmpdir[len] == '\0'); + + if (len > 1) { + last = tmpdir[len - 1]; +#ifdef _WIN32 + ASSERT(last != '\\'); +#else + ASSERT(last != '/'); +#endif + } + + /* Test the case where the buffer is too small */ + len = SMALLPATH; + r = uv_os_tmpdir(tmpdir, &len); + ASSERT(r == UV_ENOBUFS); + ASSERT(len > SMALLPATH); + + /* Test invalid inputs */ + r = uv_os_tmpdir(NULL, &len); + ASSERT(r == UV_EINVAL); + r = uv_os_tmpdir(tmpdir, NULL); + ASSERT(r == UV_EINVAL); + len = 0; + r = uv_os_tmpdir(tmpdir, &len); + ASSERT(r == UV_EINVAL); + +#ifdef _WIN32 + const char *name = "TMP"; + char tmpdir_win[] = "C:\\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; + r = uv_os_setenv(name, tmpdir_win); + ASSERT(r == 0); + char tmpdirx[PATHMAX]; + size_t lenx = sizeof tmpdirx; + r = uv_os_tmpdir(tmpdirx, &lenx); + ASSERT(r == 0); +#endif + + return 0; +} diff --git a/external/src/libuv/test/test-tty-duplicate-key.c b/external/src/libuv/test/test-tty-duplicate-key.c new file mode 100644 index 0000000..efd79e1 --- /dev/null +++ b/external/src/libuv/test/test-tty-duplicate-key.c @@ -0,0 +1,321 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifdef _WIN32 + +#include "uv.h" +#include "task.h" + +#include +#include +#include +#include + +#define ESC "\x1b" +#define EUR_UTF8 "\xe2\x82\xac" +#define EUR_UNICODE 0x20AC + + +const char* expect_str = NULL; +ssize_t expect_nread = 0; + +static void dump_str(const char* str, ssize_t len) { + ssize_t i; + for (i = 0; i < len; i++) { + fprintf(stderr, "%#02x ", *(str + i)); + } +} + +static void print_err_msg(const char* expect, ssize_t expect_len, + const char* found, ssize_t found_len) { + fprintf(stderr, "expect "); + dump_str(expect, expect_len); + fprintf(stderr, ", but found "); + dump_str(found, found_len); + fprintf(stderr, "\n"); +} + +static void tty_alloc(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + buf->base = malloc(size); + ASSERT_NOT_NULL(buf->base); + buf->len = size; +} + +static void tty_read(uv_stream_t* tty_in, ssize_t nread, const uv_buf_t* buf) { + if (nread > 0) { + if (nread != expect_nread) { + fprintf(stderr, "expected nread %ld, but found %ld\n", + (long)expect_nread, (long)nread); + print_err_msg(expect_str, expect_nread, buf->base, nread); + ASSERT(FALSE); + } + if (strncmp(buf->base, expect_str, nread) != 0) { + print_err_msg(expect_str, expect_nread, buf->base, nread); + ASSERT(FALSE); + } + uv_close((uv_handle_t*) tty_in, NULL); + } else { + ASSERT(nread == 0); + } +} + +static void make_key_event_records(WORD virt_key, DWORD ctr_key_state, + BOOL is_wsl, INPUT_RECORD* records) { +# define KEV(I) records[(I)].Event.KeyEvent + BYTE kb_state[256] = {0}; + WCHAR buf[2]; + int ret; + + records[0].EventType = records[1].EventType = KEY_EVENT; + KEV(0).bKeyDown = TRUE; + KEV(1).bKeyDown = FALSE; + KEV(0).wVirtualKeyCode = KEV(1).wVirtualKeyCode = virt_key; + KEV(0).wRepeatCount = KEV(1).wRepeatCount = 1; + KEV(0).wVirtualScanCode = KEV(1).wVirtualScanCode = + MapVirtualKeyW(virt_key, MAPVK_VK_TO_VSC); + KEV(0).dwControlKeyState = KEV(1).dwControlKeyState = ctr_key_state; + if (ctr_key_state & LEFT_ALT_PRESSED) { + kb_state[VK_LMENU] = 0x01; + } + if (ctr_key_state & RIGHT_ALT_PRESSED) { + kb_state[VK_RMENU] = 0x01; + } + if (ctr_key_state & LEFT_CTRL_PRESSED) { + kb_state[VK_LCONTROL] = 0x01; + } + if (ctr_key_state & RIGHT_CTRL_PRESSED) { + kb_state[VK_RCONTROL] = 0x01; + } + if (ctr_key_state & SHIFT_PRESSED) { + kb_state[VK_SHIFT] = 0x01; + } + ret = ToUnicode(virt_key, KEV(0).wVirtualScanCode, kb_state, buf, 2, 0); + if (ret == 1) { + if(!is_wsl && + ((ctr_key_state & LEFT_ALT_PRESSED) || + (ctr_key_state & RIGHT_ALT_PRESSED))) { + /* + * If ALT key is pressed, the UnicodeChar value of the keyup event is + * set to 0 on nomal console. Emulate this behavior. + * See https://github.com/Microsoft/console/issues/320 + */ + KEV(0).uChar.UnicodeChar = buf[0]; + KEV(1).uChar.UnicodeChar = 0; + } else{ + /* + * In WSL UnicodeChar is normally set. This behavior cause #2111. + */ + KEV(0).uChar.UnicodeChar = KEV(1).uChar.UnicodeChar = buf[0]; + } + } else { + KEV(0).uChar.UnicodeChar = KEV(1).uChar.UnicodeChar = 0; + } +# undef KEV +} + +TEST_IMPL(tty_duplicate_vt100_fn_key) { + int r; + int ttyin_fd; + uv_tty_t tty_in; + uv_loop_t* loop; + HANDLE handle; + INPUT_RECORD records[2]; + DWORD written; + + loop = uv_default_loop(); + + /* Make sure we have an FD that refers to a tty */ + handle = CreateFileA("conin$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + ASSERT(handle != INVALID_HANDLE_VALUE); + ttyin_fd = _open_osfhandle((intptr_t) handle, 0); + ASSERT(ttyin_fd >= 0); + ASSERT(UV_TTY == uv_guess_handle(ttyin_fd)); + + r = uv_tty_init(uv_default_loop(), &tty_in, ttyin_fd, 1); /* Readable. */ + ASSERT(r == 0); + ASSERT(uv_is_readable((uv_stream_t*) &tty_in)); + ASSERT(!uv_is_writable((uv_stream_t*) &tty_in)); + + r = uv_read_start((uv_stream_t*)&tty_in, tty_alloc, tty_read); + ASSERT(r == 0); + + expect_str = ESC"[[A"; + expect_nread = strlen(expect_str); + + /* Turn on raw mode. */ + r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_RAW); + ASSERT(r == 0); + + /* + * Send F1 keystrokes. Test of issue cause by #2114 that vt100 fn key + * duplicate. + */ + make_key_event_records(VK_F1, 0, TRUE, records); + WriteConsoleInputW(handle, records, ARRAY_SIZE(records), &written); + ASSERT(written == ARRAY_SIZE(records)); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(tty_duplicate_alt_modifier_key) { + int r; + int ttyin_fd; + uv_tty_t tty_in; + uv_loop_t* loop; + HANDLE handle; + INPUT_RECORD records[2]; + INPUT_RECORD alt_records[2]; + DWORD written; + + loop = uv_default_loop(); + + /* Make sure we have an FD that refers to a tty */ + handle = CreateFileA("conin$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + ASSERT(handle != INVALID_HANDLE_VALUE); + ttyin_fd = _open_osfhandle((intptr_t) handle, 0); + ASSERT(ttyin_fd >= 0); + ASSERT(UV_TTY == uv_guess_handle(ttyin_fd)); + + r = uv_tty_init(uv_default_loop(), &tty_in, ttyin_fd, 1); /* Readable. */ + ASSERT(r == 0); + ASSERT(uv_is_readable((uv_stream_t*) &tty_in)); + ASSERT(!uv_is_writable((uv_stream_t*) &tty_in)); + + r = uv_read_start((uv_stream_t*)&tty_in, tty_alloc, tty_read); + ASSERT(r == 0); + + expect_str = ESC"a"ESC"a"; + expect_nread = strlen(expect_str); + + /* Turn on raw mode. */ + r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_RAW); + ASSERT(r == 0); + + /* Emulate transmission of M-a at normal console */ + make_key_event_records(VK_MENU, 0, TRUE, alt_records); + WriteConsoleInputW(handle, &alt_records[0], 1, &written); + ASSERT(written == 1); + make_key_event_records(L'A', LEFT_ALT_PRESSED, FALSE, records); + WriteConsoleInputW(handle, records, ARRAY_SIZE(records), &written); + ASSERT(written == 2); + WriteConsoleInputW(handle, &alt_records[1], 1, &written); + ASSERT(written == 1); + + /* Emulate transmission of M-a at WSL(#2111) */ + make_key_event_records(VK_MENU, 0, TRUE, alt_records); + WriteConsoleInputW(handle, &alt_records[0], 1, &written); + ASSERT(written == 1); + make_key_event_records(L'A', LEFT_ALT_PRESSED, TRUE, records); + WriteConsoleInputW(handle, records, ARRAY_SIZE(records), &written); + ASSERT(written == 2); + WriteConsoleInputW(handle, &alt_records[1], 1, &written); + ASSERT(written == 1); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(tty_composing_character) { + int r; + int ttyin_fd; + uv_tty_t tty_in; + uv_loop_t* loop; + HANDLE handle; + INPUT_RECORD records[2]; + INPUT_RECORD alt_records[2]; + DWORD written; + + loop = uv_default_loop(); + + /* Make sure we have an FD that refers to a tty */ + handle = CreateFileA("conin$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + ASSERT(handle != INVALID_HANDLE_VALUE); + ttyin_fd = _open_osfhandle((intptr_t) handle, 0); + ASSERT(ttyin_fd >= 0); + ASSERT(UV_TTY == uv_guess_handle(ttyin_fd)); + + r = uv_tty_init(uv_default_loop(), &tty_in, ttyin_fd, 1); /* Readable. */ + ASSERT(r == 0); + ASSERT(uv_is_readable((uv_stream_t*) &tty_in)); + ASSERT(!uv_is_writable((uv_stream_t*) &tty_in)); + + r = uv_read_start((uv_stream_t*)&tty_in, tty_alloc, tty_read); + ASSERT(r == 0); + + expect_str = EUR_UTF8; + expect_nread = strlen(expect_str); + + /* Turn on raw mode. */ + r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_RAW); + ASSERT(r == 0); + + /* Emulate EUR inputs by LEFT ALT+NUMPAD ASCII KeyComos */ + make_key_event_records(VK_MENU, 0, FALSE, alt_records); + alt_records[1].Event.KeyEvent.uChar.UnicodeChar = EUR_UNICODE; + WriteConsoleInputW(handle, &alt_records[0], 1, &written); + make_key_event_records(VK_NUMPAD0, LEFT_ALT_PRESSED, FALSE, records); + WriteConsoleInputW(handle, records, ARRAY_SIZE(records), &written); + ASSERT(written == ARRAY_SIZE(records)); + make_key_event_records(VK_NUMPAD1, LEFT_ALT_PRESSED, FALSE, records); + WriteConsoleInputW(handle, records, ARRAY_SIZE(records), &written); + ASSERT(written == ARRAY_SIZE(records)); + make_key_event_records(VK_NUMPAD2, LEFT_ALT_PRESSED, FALSE, records); + WriteConsoleInputW(handle, records, ARRAY_SIZE(records), &written); + ASSERT(written == ARRAY_SIZE(records)); + make_key_event_records(VK_NUMPAD8, LEFT_ALT_PRESSED, FALSE, records); + WriteConsoleInputW(handle, records, ARRAY_SIZE(records), &written); + ASSERT(written == ARRAY_SIZE(records)); + WriteConsoleInputW(handle, &alt_records[1], 1, &written); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* ifndef _WIN32 */ diff --git a/external/src/libuv/test/test-tty-escape-sequence-processing.c b/external/src/libuv/test/test-tty-escape-sequence-processing.c new file mode 100644 index 0000000..ef34e59 --- /dev/null +++ b/external/src/libuv/test/test-tty-escape-sequence-processing.c @@ -0,0 +1,1621 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#ifdef _WIN32 + +#include "task.h" +#include "uv.h" + +#include +#include + +#include +#include + +#define ESC "\033" +#define CSI ESC "[" +#define ST ESC "\\" +#define BEL "\x07" +#define HELLO "Hello" + +#define FOREGROUND_WHITE (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE) +#define FOREGROUND_BLACK 0 +#define FOREGROUND_YELLOW (FOREGROUND_RED | FOREGROUND_GREEN) +#define FOREGROUND_CYAN (FOREGROUND_GREEN | FOREGROUND_BLUE) +#define FOREGROUND_MAGENTA (FOREGROUND_RED | FOREGROUND_BLUE) +#define BACKGROUND_WHITE (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE) +#define BACKGROUND_BLACK 0 +#define BACKGROUND_YELLOW (BACKGROUND_RED | BACKGROUND_GREEN) +#define BACKGROUND_CYAN (BACKGROUND_GREEN | BACKGROUND_BLUE) +#define BACKGROUND_MAGENTA (BACKGROUND_RED | BACKGROUND_BLUE) + +#define F_INTENSITY 1 +#define FB_INTENSITY 2 +#define B_INTENSITY 5 +#define INVERSE 7 +#define F_INTENSITY_OFF1 21 +#define F_INTENSITY_OFF2 22 +#define B_INTENSITY_OFF 25 +#define INVERSE_OFF 27 +#define F_BLACK 30 +#define F_RED 31 +#define F_GREEN 32 +#define F_YELLOW 33 +#define F_BLUE 34 +#define F_MAGENTA 35 +#define F_CYAN 36 +#define F_WHITE 37 +#define F_DEFAULT 39 +#define B_BLACK 40 +#define B_RED 41 +#define B_GREEN 42 +#define B_YELLOW 43 +#define B_BLUE 44 +#define B_MAGENTA 45 +#define B_CYAN 46 +#define B_WHITE 47 +#define B_DEFAULT 49 + +#define CURSOR_SIZE_SMALL 25 +#define CURSOR_SIZE_MIDDLE 50 +#define CURSOR_SIZE_LARGE 100 + +struct screen_info { + CONSOLE_SCREEN_BUFFER_INFO csbi; + int top; + int width; + int height; + int length; + WORD default_attr; +}; + +struct captured_screen { + char* text; + WORD* attributes; + struct screen_info si; +}; + +static void get_screen_info(uv_tty_t* tty_out, struct screen_info* si) { + ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &(si->csbi))); + si->width = si->csbi.dwSize.X; + si->height = si->csbi.srWindow.Bottom - si->csbi.srWindow.Top + 1; + si->length = si->width * si->height; + si->default_attr = si->csbi.wAttributes; + si->top = si->csbi.srWindow.Top; +} + +static void set_cursor_position(uv_tty_t* tty_out, COORD pos) { + HANDLE handle = tty_out->handle; + CONSOLE_SCREEN_BUFFER_INFO info; + ASSERT(GetConsoleScreenBufferInfo(handle, &info)); + pos.X -= 1; + pos.Y += info.srWindow.Top - 1; + ASSERT(SetConsoleCursorPosition(handle, pos)); +} + +static void get_cursor_position(uv_tty_t* tty_out, COORD* cursor_position) { + HANDLE handle = tty_out->handle; + CONSOLE_SCREEN_BUFFER_INFO info; + ASSERT(GetConsoleScreenBufferInfo(handle, &info)); + cursor_position->X = info.dwCursorPosition.X + 1; + cursor_position->Y = info.dwCursorPosition.Y - info.srWindow.Top + 1; +} + +static void set_cursor_to_home(uv_tty_t* tty_out) { + COORD origin = {1, 1}; + set_cursor_position(tty_out, origin); +} + +static CONSOLE_CURSOR_INFO get_cursor_info(uv_tty_t* tty_out) { + HANDLE handle = tty_out->handle; + CONSOLE_CURSOR_INFO info; + ASSERT(GetConsoleCursorInfo(handle, &info)); + return info; +} + +static void set_cursor_size(uv_tty_t* tty_out, DWORD size) { + CONSOLE_CURSOR_INFO info = get_cursor_info(tty_out); + info.dwSize = size; + ASSERT(SetConsoleCursorInfo(tty_out->handle, &info)); +} + +static DWORD get_cursor_size(uv_tty_t* tty_out) { + return get_cursor_info(tty_out).dwSize; +} + +static void set_cursor_visibility(uv_tty_t* tty_out, BOOL visible) { + CONSOLE_CURSOR_INFO info = get_cursor_info(tty_out); + info.bVisible = visible; + ASSERT(SetConsoleCursorInfo(tty_out->handle, &info)); +} + +static BOOL get_cursor_visibility(uv_tty_t* tty_out) { + return get_cursor_info(tty_out).bVisible; +} + +static BOOL is_scrolling(uv_tty_t* tty_out, struct screen_info si) { + CONSOLE_SCREEN_BUFFER_INFO info; + ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &info)); + return info.srWindow.Top != si.top; +} + +static void write_console(uv_tty_t* tty_out, char* src) { + int r; + uv_buf_t buf; + + buf.base = src; + buf.len = strlen(buf.base); + + r = uv_try_write((uv_stream_t*) tty_out, &buf, 1); + ASSERT(r >= 0); + ASSERT((unsigned int) r == buf.len); +} + +static void setup_screen(uv_tty_t* tty_out) { + DWORD length, number_of_written; + COORD origin; + CONSOLE_SCREEN_BUFFER_INFO info; + ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &info)); + length = info.dwSize.X * (info.srWindow.Bottom - info.srWindow.Top + 1); + origin.X = 0; + origin.Y = info.srWindow.Top; + ASSERT(FillConsoleOutputCharacter( + tty_out->handle, '.', length, origin, &number_of_written)); + ASSERT(length == number_of_written); +} + +static void clear_screen(uv_tty_t* tty_out, struct screen_info* si) { + DWORD length, number_of_written; + COORD origin; + CONSOLE_SCREEN_BUFFER_INFO info; + ASSERT(GetConsoleScreenBufferInfo(tty_out->handle, &info)); + length = (info.srWindow.Bottom - info.srWindow.Top + 1) * info.dwSize.X - 1; + origin.X = 0; + origin.Y = info.srWindow.Top; + FillConsoleOutputCharacterA( + tty_out->handle, ' ', length, origin, &number_of_written); + ASSERT(length == number_of_written); + FillConsoleOutputAttribute( + tty_out->handle, si->default_attr, length, origin, &number_of_written); + ASSERT(length == number_of_written); +} + +static void free_screen(struct captured_screen* cs) { + free(cs->text); + cs->text = NULL; + free(cs->attributes); + cs->attributes = NULL; +} + +static void capture_screen(uv_tty_t* tty_out, struct captured_screen* cs) { + DWORD length; + COORD origin; + get_screen_info(tty_out, &(cs->si)); + origin.X = 0; + origin.Y = cs->si.csbi.srWindow.Top; + cs->text = malloc(cs->si.length * sizeof(*cs->text)); + ASSERT_NOT_NULL(cs->text); + cs->attributes = (WORD*) malloc(cs->si.length * sizeof(*cs->attributes)); + ASSERT_NOT_NULL(cs->attributes); + ASSERT(ReadConsoleOutputCharacter( + tty_out->handle, cs->text, cs->si.length, origin, &length)); + ASSERT((unsigned int) cs->si.length == length); + ASSERT(ReadConsoleOutputAttribute( + tty_out->handle, cs->attributes, cs->si.length, origin, &length)); + ASSERT((unsigned int) cs->si.length == length); +} + +static void make_expect_screen_erase(struct captured_screen* cs, + COORD cursor_position, + int dir, + BOOL entire_screen) { + /* beginning of line */ + char* start; + char* end; + start = cs->text + cs->si.width * (cursor_position.Y - 1); + if (dir == 0) { + if (entire_screen) { + /* erase to end of screen */ + end = cs->text + cs->si.length; + } else { + /* erase to end of line */ + end = start + cs->si.width; + } + /* erase from postition of cursor */ + start += cursor_position.X - 1; + } else if (dir == 1) { + /* erase to position of cursor */ + end = start + cursor_position.X; + if (entire_screen) { + /* erase form beginning of screen */ + start = cs->text; + } + } else if (dir == 2) { + if (entire_screen) { + /* erase form beginning of screen */ + start = cs->text; + /* erase to end of screen */ + end = cs->text + cs->si.length; + } else { + /* erase to end of line */ + end = start + cs->si.width; + } + } else { + ASSERT(FALSE); + } + ASSERT(start < end); + ASSERT(end - cs->text <= cs->si.length); + for (; start < end; start++) { + *start = ' '; + } +} + +static void make_expect_screen_write(struct captured_screen* cs, + COORD cursor_position, + const char* text) { + /* postion of cursor */ + char* start; + start = cs->text + cs->si.width * (cursor_position.Y - 1) + + cursor_position.X - 1; + size_t length = strlen(text); + size_t remain_length = cs->si.length - (cs->text - start); + length = length > remain_length ? remain_length : length; + memcpy(start, text, length); +} + +static void make_expect_screen_set_attr(struct captured_screen* cs, + COORD cursor_position, + size_t length, + WORD attr) { + WORD* start; + start = cs->attributes + cs->si.width * (cursor_position.Y - 1) + + cursor_position.X - 1; + size_t remain_length = cs->si.length - (cs->attributes - start); + length = length > remain_length ? remain_length : length; + while (length) { + *start = attr; + start++; + length--; + } +} + +static BOOL compare_screen(uv_tty_t* tty_out, + struct captured_screen* actual, + struct captured_screen* expect) { + int line, col; + BOOL result = TRUE; + int current = 0; + ASSERT(actual->text); + ASSERT(actual->attributes); + ASSERT(expect->text); + ASSERT(expect->attributes); + if (actual->si.length != expect->si.length) { + return FALSE; + } + if (actual->si.width != expect->si.width) { + return FALSE; + } + if (actual->si.height != expect->si.height) { + return FALSE; + } + while (current < actual->si.length) { + if (*(actual->text + current) != *(expect->text + current)) { + line = current / actual->si.width + 1; + col = current - actual->si.width * (line - 1) + 1; + fprintf(stderr, + "line:%d col:%d expected character '%c' but found '%c'\n", + line, + col, + *(expect->text + current), + *(actual->text + current)); + result = FALSE; + } + if (*(actual->attributes + current) != *(expect->attributes + current)) { + line = current / actual->si.width + 1; + col = current - actual->si.width * (line - 1) + 1; + fprintf(stderr, + "line:%d col:%d expected attributes '%u' but found '%u'\n", + line, + col, + *(expect->attributes + current), + *(actual->attributes + current)); + result = FALSE; + } + current++; + } + clear_screen(tty_out, &expect->si); + free_screen(expect); + free_screen(actual); + return result; +} + +static void initialize_tty(uv_tty_t* tty_out) { + int r; + int ttyout_fd; + /* Make sure we have an FD that refers to a tty */ + HANDLE handle; + + uv_tty_set_vterm_state(UV_TTY_UNSUPPORTED); + + handle = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + CONSOLE_TEXTMODE_BUFFER, + NULL); + ASSERT(handle != INVALID_HANDLE_VALUE); + + ttyout_fd = _open_osfhandle((intptr_t) handle, 0); + ASSERT(ttyout_fd >= 0); + ASSERT(UV_TTY == uv_guess_handle(ttyout_fd)); + r = uv_tty_init(uv_default_loop(), tty_out, ttyout_fd, 0); /* Writable. */ + ASSERT(r == 0); +} + +static void terminate_tty(uv_tty_t* tty_out) { + set_cursor_to_home(tty_out); + uv_close((uv_handle_t*) tty_out, NULL); +} + +TEST_IMPL(tty_cursor_up) { + uv_tty_t tty_out; + uv_loop_t* loop; + COORD cursor_pos, cursor_pos_old; + char buffer[1024]; + struct screen_info si; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + get_screen_info(&tty_out, &si); + + cursor_pos_old.X = si.width / 2; + cursor_pos_old.Y = si.height / 2; + set_cursor_position(&tty_out, cursor_pos_old); + + /* cursor up one times if omitted arguments */ + snprintf(buffer, sizeof(buffer), "%sA", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y - 1 == cursor_pos.Y); + ASSERT(cursor_pos_old.X == cursor_pos.X); + + /* cursor up nth times */ + cursor_pos_old = cursor_pos; + snprintf(buffer, sizeof(buffer), "%s%dA", CSI, si.height / 4); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y - si.height / 4 == cursor_pos.Y); + ASSERT(cursor_pos_old.X == cursor_pos.X); + + /* cursor up from Window top does nothing */ + cursor_pos_old.X = 1; + cursor_pos_old.Y = 1; + set_cursor_position(&tty_out, cursor_pos_old); + snprintf(buffer, sizeof(buffer), "%sA", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y == cursor_pos.Y); + ASSERT(cursor_pos_old.X == cursor_pos.X); + ASSERT(!is_scrolling(&tty_out, si)); + + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tty_cursor_down) { + uv_tty_t tty_out; + uv_loop_t* loop; + COORD cursor_pos, cursor_pos_old; + char buffer[1024]; + struct screen_info si; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + get_screen_info(&tty_out, &si); + + cursor_pos_old.X = si.width / 2; + cursor_pos_old.Y = si.height / 2; + set_cursor_position(&tty_out, cursor_pos_old); + + /* cursor down one times if omitted arguments */ + snprintf(buffer, sizeof(buffer), "%sB", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y + 1 == cursor_pos.Y); + ASSERT(cursor_pos_old.X == cursor_pos.X); + + /* cursor down nth times */ + cursor_pos_old = cursor_pos; + snprintf(buffer, sizeof(buffer), "%s%dB", CSI, si.height / 4); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y + si.height / 4 == cursor_pos.Y); + ASSERT(cursor_pos_old.X == cursor_pos.X); + + /* cursor down from bottom line does nothing */ + cursor_pos_old.X = si.width / 2; + cursor_pos_old.Y = si.height; + set_cursor_position(&tty_out, cursor_pos_old); + snprintf(buffer, sizeof(buffer), "%sB", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y == cursor_pos.Y); + ASSERT(cursor_pos_old.X == cursor_pos.X); + ASSERT(!is_scrolling(&tty_out, si)); + + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tty_cursor_forward) { + uv_tty_t tty_out; + uv_loop_t* loop; + COORD cursor_pos, cursor_pos_old; + char buffer[1024]; + struct screen_info si; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + get_screen_info(&tty_out, &si); + + cursor_pos_old.X = si.width / 2; + cursor_pos_old.Y = si.height / 2; + set_cursor_position(&tty_out, cursor_pos_old); + + /* cursor forward one times if omitted arguments */ + snprintf(buffer, sizeof(buffer), "%sC", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y == cursor_pos.Y); + ASSERT(cursor_pos_old.X + 1 == cursor_pos.X); + + /* cursor forward nth times */ + cursor_pos_old = cursor_pos; + snprintf(buffer, sizeof(buffer), "%s%dC", CSI, si.width / 4); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y == cursor_pos.Y); + ASSERT(cursor_pos_old.X + si.width / 4 == cursor_pos.X); + + /* cursor forward from end of line does nothing*/ + cursor_pos_old.X = si.width; + cursor_pos_old.Y = si.height / 2; + set_cursor_position(&tty_out, cursor_pos_old); + snprintf(buffer, sizeof(buffer), "%sC", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y == cursor_pos.Y); + ASSERT(cursor_pos_old.X == cursor_pos.X); + + /* cursor forward from end of screen does nothing */ + cursor_pos_old.X = si.width; + cursor_pos_old.Y = si.height; + set_cursor_position(&tty_out, cursor_pos_old); + snprintf(buffer, sizeof(buffer), "%sC", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y == cursor_pos.Y); + ASSERT(cursor_pos_old.X == cursor_pos.X); + ASSERT(!is_scrolling(&tty_out, si)); + + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tty_cursor_back) { + uv_tty_t tty_out; + uv_loop_t* loop; + COORD cursor_pos, cursor_pos_old; + char buffer[1024]; + struct screen_info si; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + get_screen_info(&tty_out, &si); + + cursor_pos_old.X = si.width / 2; + cursor_pos_old.Y = si.height / 2; + set_cursor_position(&tty_out, cursor_pos_old); + + /* cursor back one times if omitted arguments */ + snprintf(buffer, sizeof(buffer), "%sD", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y == cursor_pos.Y); + ASSERT(cursor_pos_old.X - 1 == cursor_pos.X); + + /* cursor back nth times */ + cursor_pos_old = cursor_pos; + snprintf(buffer, sizeof(buffer), "%s%dD", CSI, si.width / 4); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y == cursor_pos.Y); + ASSERT(cursor_pos_old.X - si.width / 4 == cursor_pos.X); + + /* cursor back from beginning of line does nothing */ + cursor_pos_old.X = 1; + cursor_pos_old.Y = si.height / 2; + set_cursor_position(&tty_out, cursor_pos_old); + snprintf(buffer, sizeof(buffer), "%sD", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y == cursor_pos.Y); + ASSERT(cursor_pos_old.X == cursor_pos.X); + + /* cursor back from top of screen does nothing */ + cursor_pos_old.X = 1; + cursor_pos_old.Y = 1; + set_cursor_position(&tty_out, cursor_pos_old); + snprintf(buffer, sizeof(buffer), "%sD", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(1 == cursor_pos.Y); + ASSERT(1 == cursor_pos.X); + ASSERT(!is_scrolling(&tty_out, si)); + + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tty_cursor_next_line) { + uv_tty_t tty_out; + uv_loop_t* loop; + COORD cursor_pos, cursor_pos_old; + char buffer[1024]; + struct screen_info si; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + get_screen_info(&tty_out, &si); + + cursor_pos_old.X = si.width / 2; + cursor_pos_old.Y = si.height / 2; + set_cursor_position(&tty_out, cursor_pos_old); + + /* cursor next line one times if omitted arguments */ + snprintf(buffer, sizeof(buffer), "%sE", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y + 1 == cursor_pos.Y); + ASSERT(1 == cursor_pos.X); + + /* cursor next line nth times */ + cursor_pos_old = cursor_pos; + snprintf(buffer, sizeof(buffer), "%s%dE", CSI, si.height / 4); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y + si.height / 4 == cursor_pos.Y); + ASSERT(1 == cursor_pos.X); + + /* cursor next line from buttom row moves beginning of line */ + cursor_pos_old.X = si.width / 2; + cursor_pos_old.Y = si.height; + set_cursor_position(&tty_out, cursor_pos_old); + snprintf(buffer, sizeof(buffer), "%sE", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y == cursor_pos.Y); + ASSERT(1 == cursor_pos.X); + ASSERT(!is_scrolling(&tty_out, si)); + + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tty_cursor_previous_line) { + uv_tty_t tty_out; + uv_loop_t* loop; + COORD cursor_pos, cursor_pos_old; + char buffer[1024]; + struct screen_info si; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + get_screen_info(&tty_out, &si); + + cursor_pos_old.X = si.width / 2; + cursor_pos_old.Y = si.height / 2; + set_cursor_position(&tty_out, cursor_pos_old); + + /* cursor previous line one times if omitted arguments */ + snprintf(buffer, sizeof(buffer), "%sF", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y - 1 == cursor_pos.Y); + ASSERT(1 == cursor_pos.X); + + /* cursor previous line nth times */ + cursor_pos_old = cursor_pos; + snprintf(buffer, sizeof(buffer), "%s%dF", CSI, si.height / 4); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos_old.Y - si.height / 4 == cursor_pos.Y); + ASSERT(1 == cursor_pos.X); + + /* cursor previous line from top of screen does nothing */ + cursor_pos_old.X = 1; + cursor_pos_old.Y = 1; + set_cursor_position(&tty_out, cursor_pos_old); + snprintf(buffer, sizeof(buffer), "%sD", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(1 == cursor_pos.Y); + ASSERT(1 == cursor_pos.X); + ASSERT(!is_scrolling(&tty_out, si)); + + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tty_cursor_horizontal_move_absolute) { + uv_tty_t tty_out; + uv_loop_t* loop; + COORD cursor_pos, cursor_pos_old; + char buffer[1024]; + struct screen_info si; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + get_screen_info(&tty_out, &si); + + cursor_pos_old.X = si.width / 2; + cursor_pos_old.Y = si.height / 2; + set_cursor_position(&tty_out, cursor_pos_old); + + /* Move to beginning of line if omitted argument */ + snprintf(buffer, sizeof(buffer), "%sG", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(1 == cursor_pos.X); + ASSERT(cursor_pos_old.Y == cursor_pos.Y); + + /* Move cursor to nth character */ + snprintf(buffer, sizeof(buffer), "%s%dG", CSI, si.width / 4); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(si.width / 4 == cursor_pos.X); + ASSERT(cursor_pos_old.Y == cursor_pos.Y); + + /* Moving out of screen will fit within screen */ + snprintf(buffer, sizeof(buffer), "%s%dG", CSI, si.width + 1); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(si.width == cursor_pos.X); + ASSERT(cursor_pos_old.Y == cursor_pos.Y); + + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tty_cursor_move_absolute) { + uv_tty_t tty_out; + uv_loop_t* loop; + COORD cursor_pos; + char buffer[1024]; + struct screen_info si; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + get_screen_info(&tty_out, &si); + + cursor_pos.X = si.width / 2; + cursor_pos.Y = si.height / 2; + set_cursor_position(&tty_out, cursor_pos); + + /* Move the cursor to home if omitted arguments */ + snprintf(buffer, sizeof(buffer), "%sH", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(1 == cursor_pos.X); + ASSERT(1 == cursor_pos.Y); + + /* Move the cursor to the middle of the screen */ + snprintf( + buffer, sizeof(buffer), "%s%d;%df", CSI, si.height / 2, si.width / 2); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(si.width / 2 == cursor_pos.X); + ASSERT(si.height / 2 == cursor_pos.Y); + + /* Moving out of screen will fit within screen */ + snprintf( + buffer, sizeof(buffer), "%s%d;%df", CSI, si.height / 2, si.width + 1); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(si.width == cursor_pos.X); + ASSERT(si.height / 2 == cursor_pos.Y); + + snprintf( + buffer, sizeof(buffer), "%s%d;%df", CSI, si.height + 1, si.width / 2); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(si.width / 2 == cursor_pos.X); + ASSERT(si.height == cursor_pos.Y); + ASSERT(!is_scrolling(&tty_out, si)); + + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tty_hide_show_cursor) { + uv_tty_t tty_out; + uv_loop_t* loop; + char buffer[1024]; + BOOL saved_cursor_visibility; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + + saved_cursor_visibility = get_cursor_visibility(&tty_out); + + /* Hide the cursor */ + set_cursor_visibility(&tty_out, TRUE); + snprintf(buffer, sizeof(buffer), "%s?25l", CSI); + write_console(&tty_out, buffer); + ASSERT(!get_cursor_visibility(&tty_out)); + + /* Show the cursor */ + set_cursor_visibility(&tty_out, FALSE); + snprintf(buffer, sizeof(buffer), "%s?25h", CSI); + write_console(&tty_out, buffer); + ASSERT(get_cursor_visibility(&tty_out)); + + set_cursor_visibility(&tty_out, saved_cursor_visibility); + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tty_erase) { + int dir; + uv_tty_t tty_out; + uv_loop_t* loop; + COORD cursor_pos; + char buffer[1024]; + struct captured_screen actual = {0}, expect = {0}; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + + /* Erase to below if omitted argument */ + dir = 0; + setup_screen(&tty_out); + capture_screen(&tty_out, &expect); + cursor_pos.X = expect.si.width / 2; + cursor_pos.Y = expect.si.height / 2; + make_expect_screen_erase(&expect, cursor_pos, dir, TRUE); + + set_cursor_position(&tty_out, cursor_pos); + snprintf(buffer, sizeof(buffer), "%sJ", CSI); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* Erase to below(dir = 0) */ + setup_screen(&tty_out); + capture_screen(&tty_out, &expect); + make_expect_screen_erase(&expect, cursor_pos, dir, TRUE); + + set_cursor_position(&tty_out, cursor_pos); + snprintf(buffer, sizeof(buffer), "%s%dJ", CSI, dir); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* Erase to above */ + dir = 1; + setup_screen(&tty_out); + capture_screen(&tty_out, &expect); + make_expect_screen_erase(&expect, cursor_pos, dir, TRUE); + + set_cursor_position(&tty_out, cursor_pos); + snprintf(buffer, sizeof(buffer), "%s%dJ", CSI, dir); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* Erase All */ + dir = 2; + setup_screen(&tty_out); + capture_screen(&tty_out, &expect); + make_expect_screen_erase(&expect, cursor_pos, dir, TRUE); + + set_cursor_position(&tty_out, cursor_pos); + snprintf(buffer, sizeof(buffer), "%s%dJ", CSI, dir); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tty_erase_line) { + int dir; + uv_tty_t tty_out; + uv_loop_t* loop; + COORD cursor_pos; + char buffer[1024]; + struct captured_screen actual = {0}, expect = {0}; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + + /* Erase to right if omitted arguments */ + dir = 0; + setup_screen(&tty_out); + capture_screen(&tty_out, &expect); + cursor_pos.X = expect.si.width / 2; + cursor_pos.Y = expect.si.height / 2; + make_expect_screen_erase(&expect, cursor_pos, dir, FALSE); + + set_cursor_position(&tty_out, cursor_pos); + snprintf(buffer, sizeof(buffer), "%sK", CSI); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* Erase to right(dir = 0) */ + setup_screen(&tty_out); + capture_screen(&tty_out, &expect); + make_expect_screen_erase(&expect, cursor_pos, dir, FALSE); + + set_cursor_position(&tty_out, cursor_pos); + snprintf(buffer, sizeof(buffer), "%s%dK", CSI, dir); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* Erase to Left */ + dir = 1; + setup_screen(&tty_out); + capture_screen(&tty_out, &expect); + make_expect_screen_erase(&expect, cursor_pos, dir, FALSE); + + set_cursor_position(&tty_out, cursor_pos); + snprintf(buffer, sizeof(buffer), "%s%dK", CSI, dir); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* Erase All */ + dir = 2; + setup_screen(&tty_out); + capture_screen(&tty_out, &expect); + make_expect_screen_erase(&expect, cursor_pos, dir, FALSE); + + set_cursor_position(&tty_out, cursor_pos); + snprintf(buffer, sizeof(buffer), "%s%dK", CSI, dir); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tty_set_cursor_shape) { + uv_tty_t tty_out; + uv_loop_t* loop; + DWORD saved_cursor_size; + char buffer[1024]; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + + saved_cursor_size = get_cursor_size(&tty_out); + + /* cursor size large if omitted arguments */ + set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); + snprintf(buffer, sizeof(buffer), "%s q", CSI); + write_console(&tty_out, buffer); + ASSERT(get_cursor_size(&tty_out) == CURSOR_SIZE_LARGE); + + /* cursor size large */ + set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); + snprintf(buffer, sizeof(buffer), "%s1 q", CSI); + write_console(&tty_out, buffer); + ASSERT(get_cursor_size(&tty_out) == CURSOR_SIZE_LARGE); + set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); + snprintf(buffer, sizeof(buffer), "%s2 q", CSI); + write_console(&tty_out, buffer); + ASSERT(get_cursor_size(&tty_out) == CURSOR_SIZE_LARGE); + + /* cursor size small */ + set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); + snprintf(buffer, sizeof(buffer), "%s3 q", CSI); + write_console(&tty_out, buffer); + ASSERT(get_cursor_size(&tty_out) == CURSOR_SIZE_SMALL); + set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); + snprintf(buffer, sizeof(buffer), "%s6 q", CSI); + write_console(&tty_out, buffer); + ASSERT(get_cursor_size(&tty_out) == CURSOR_SIZE_SMALL); + + /* Nothing occurs with arguments outside valid range */ + set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); + snprintf(buffer, sizeof(buffer), "%s7 q", CSI); + write_console(&tty_out, buffer); + ASSERT(get_cursor_size(&tty_out) == CURSOR_SIZE_MIDDLE); + + /* restore cursor size if arguments is zero */ + snprintf(buffer, sizeof(buffer), "%s0 q", CSI); + write_console(&tty_out, buffer); + ASSERT(get_cursor_size(&tty_out) == saved_cursor_size); + + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tty_set_style) { + uv_tty_t tty_out; + uv_loop_t* loop; + COORD cursor_pos; + char buffer[1024]; + struct captured_screen actual = {0}, expect = {0}; + WORD fg, bg; + WORD fg_attrs[9][2] = {{F_BLACK, FOREGROUND_BLACK}, + {F_RED, FOREGROUND_RED}, + {F_GREEN, FOREGROUND_GREEN}, + {F_YELLOW, FOREGROUND_YELLOW}, + {F_BLUE, FOREGROUND_BLUE}, + {F_MAGENTA, FOREGROUND_MAGENTA}, + {F_CYAN, FOREGROUND_CYAN}, + {F_WHITE, FOREGROUND_WHITE}, + {F_DEFAULT, 0}}; + WORD bg_attrs[9][2] = {{B_DEFAULT, 0}, + {B_BLACK, BACKGROUND_BLACK}, + {B_RED, BACKGROUND_RED}, + {B_GREEN, BACKGROUND_GREEN}, + {B_YELLOW, BACKGROUND_YELLOW}, + {B_BLUE, BACKGROUND_BLUE}, + {B_MAGENTA, BACKGROUND_MAGENTA}, + {B_CYAN, BACKGROUND_CYAN}, + {B_WHITE, BACKGROUND_WHITE}}; + WORD attr; + int i, length; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + + capture_screen(&tty_out, &expect); + fg_attrs[8][1] = expect.si.default_attr & FOREGROUND_WHITE; + bg_attrs[0][1] = expect.si.default_attr & BACKGROUND_WHITE; + + /* Set foreground color */ + length = ARRAY_SIZE(fg_attrs); + for (i = 0; i < length; i++) { + capture_screen(&tty_out, &expect); + cursor_pos.X = expect.si.width / 2; + cursor_pos.Y = expect.si.height / 2; + attr = (expect.si.default_attr & ~FOREGROUND_WHITE) | fg_attrs[i][1]; + make_expect_screen_write(&expect, cursor_pos, HELLO); + make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); + + set_cursor_position(&tty_out, cursor_pos); + snprintf( + buffer, sizeof(buffer), "%s%dm%s%sm", CSI, fg_attrs[i][0], HELLO, CSI); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + + ASSERT(compare_screen(&tty_out, &actual, &expect)); + } + + /* Set background color */ + length = ARRAY_SIZE(bg_attrs); + for (i = 0; i < length; i++) { + capture_screen(&tty_out, &expect); + cursor_pos.X = expect.si.width / 2; + cursor_pos.Y = expect.si.height / 2; + attr = (expect.si.default_attr & ~BACKGROUND_WHITE) | bg_attrs[i][1]; + make_expect_screen_write(&expect, cursor_pos, HELLO); + make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); + + set_cursor_position(&tty_out, cursor_pos); + snprintf( + buffer, sizeof(buffer), "%s%dm%s%sm", CSI, bg_attrs[i][0], HELLO, CSI); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + + ASSERT(compare_screen(&tty_out, &actual, &expect)); + } + + /* Set foregroud and background color */ + ASSERT(ARRAY_SIZE(fg_attrs) == ARRAY_SIZE(bg_attrs)); + length = ARRAY_SIZE(bg_attrs); + for (i = 0; i < length; i++) { + capture_screen(&tty_out, &expect); + cursor_pos.X = expect.si.width / 2; + cursor_pos.Y = expect.si.height / 2; + attr = expect.si.default_attr & ~FOREGROUND_WHITE & ~BACKGROUND_WHITE; + attr |= fg_attrs[i][1] | bg_attrs[i][1]; + make_expect_screen_write(&expect, cursor_pos, HELLO); + make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); + + set_cursor_position(&tty_out, cursor_pos); + snprintf(buffer, + sizeof(buffer), + "%s%d;%dm%s%sm", + CSI, + bg_attrs[i][0], + fg_attrs[i][0], + HELLO, + CSI); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + + ASSERT(compare_screen(&tty_out, &actual, &expect)); + } + + /* Set foreground bright on */ + capture_screen(&tty_out, &expect); + cursor_pos.X = expect.si.width / 2; + cursor_pos.Y = expect.si.height / 2; + set_cursor_position(&tty_out, cursor_pos); + attr = expect.si.default_attr; + attr |= FOREGROUND_INTENSITY; + make_expect_screen_write(&expect, cursor_pos, HELLO); + make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); + cursor_pos.X += strlen(HELLO); + make_expect_screen_write(&expect, cursor_pos, HELLO); + make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); + + snprintf(buffer, + sizeof(buffer), + "%s%dm%s%s%dm%s%dm%s%s%dm", + CSI, + F_INTENSITY, + HELLO, + CSI, + F_INTENSITY_OFF1, + CSI, + F_INTENSITY, + HELLO, + CSI, + F_INTENSITY_OFF2); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* Set background bright on */ + capture_screen(&tty_out, &expect); + cursor_pos.X = expect.si.width / 2; + cursor_pos.Y = expect.si.height / 2; + set_cursor_position(&tty_out, cursor_pos); + attr = expect.si.default_attr; + attr |= BACKGROUND_INTENSITY; + make_expect_screen_write(&expect, cursor_pos, HELLO); + make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); + + snprintf(buffer, + sizeof(buffer), + "%s%dm%s%s%dm", + CSI, + B_INTENSITY, + HELLO, + CSI, + B_INTENSITY_OFF); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* Inverse */ + capture_screen(&tty_out, &expect); + cursor_pos.X = expect.si.width / 2; + cursor_pos.Y = expect.si.height / 2; + set_cursor_position(&tty_out, cursor_pos); + attr = expect.si.default_attr; + fg = attr & FOREGROUND_WHITE; + bg = attr & BACKGROUND_WHITE; + attr &= (~FOREGROUND_WHITE & ~BACKGROUND_WHITE); + attr |= COMMON_LVB_REVERSE_VIDEO; + attr |= fg << 4; + attr |= bg >> 4; + make_expect_screen_write(&expect, cursor_pos, HELLO); + make_expect_screen_set_attr(&expect, cursor_pos, strlen(HELLO), attr); + cursor_pos.X += strlen(HELLO); + make_expect_screen_write(&expect, cursor_pos, HELLO); + + snprintf(buffer, + sizeof(buffer), + "%s%dm%s%s%dm%s", + CSI, + INVERSE, + HELLO, + CSI, + INVERSE_OFF, + HELLO); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tty_save_restore_cursor_position) { + uv_tty_t tty_out; + uv_loop_t* loop; + COORD cursor_pos, cursor_pos_old; + char buffer[1024]; + struct screen_info si; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + get_screen_info(&tty_out, &si); + + cursor_pos_old.X = si.width / 2; + cursor_pos_old.Y = si.height / 2; + set_cursor_position(&tty_out, cursor_pos_old); + + /* save the cursor position */ + snprintf(buffer, sizeof(buffer), "%ss", CSI); + write_console(&tty_out, buffer); + + cursor_pos.X = si.width / 4; + cursor_pos.Y = si.height / 4; + set_cursor_position(&tty_out, cursor_pos); + + /* restore the cursor postion */ + snprintf(buffer, sizeof(buffer), "%su", CSI); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos.X == cursor_pos_old.X); + ASSERT(cursor_pos.Y == cursor_pos_old.Y); + + cursor_pos_old.X = si.width / 2; + cursor_pos_old.Y = si.height / 2; + set_cursor_position(&tty_out, cursor_pos_old); + + /* save the cursor position */ + snprintf(buffer, sizeof(buffer), "%s7", ESC); + write_console(&tty_out, buffer); + + cursor_pos.X = si.width / 4; + cursor_pos.Y = si.height / 4; + set_cursor_position(&tty_out, cursor_pos); + + /* restore the cursor postion */ + snprintf(buffer, sizeof(buffer), "%s8", ESC); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos.X == cursor_pos_old.X); + ASSERT(cursor_pos.Y == cursor_pos_old.Y); + + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tty_full_reset) { + uv_tty_t tty_out; + uv_loop_t* loop; + char buffer[1024]; + struct captured_screen actual = {0}, expect = {0}; + COORD cursor_pos; + DWORD saved_cursor_size; + BOOL saved_cursor_visibility; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + + capture_screen(&tty_out, &expect); + setup_screen(&tty_out); + cursor_pos.X = expect.si.width; + cursor_pos.Y = expect.si.height; + set_cursor_position(&tty_out, cursor_pos); + snprintf(buffer, sizeof(buffer), "%s%d;%dm%s", CSI, F_CYAN, B_YELLOW, HELLO); + saved_cursor_size = get_cursor_size(&tty_out); + set_cursor_size(&tty_out, + saved_cursor_size == CURSOR_SIZE_LARGE ? CURSOR_SIZE_SMALL + : CURSOR_SIZE_LARGE); + saved_cursor_visibility = get_cursor_visibility(&tty_out); + set_cursor_visibility(&tty_out, saved_cursor_visibility ? FALSE : TRUE); + write_console(&tty_out, buffer); + snprintf(buffer, sizeof(buffer), "%sc", ESC); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + ASSERT(compare_screen(&tty_out, &actual, &expect)); + ASSERT(get_cursor_size(&tty_out) == saved_cursor_size); + ASSERT(get_cursor_visibility(&tty_out) == saved_cursor_visibility); + ASSERT(actual.si.csbi.srWindow.Top == 0); + + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(tty_escape_sequence_processing) { + uv_tty_t tty_out; + uv_loop_t* loop; + COORD cursor_pos, cursor_pos_old; + DWORD saved_cursor_size; + char buffer[1024]; + struct captured_screen actual = {0}, expect = {0}; + int dir; + + loop = uv_default_loop(); + + initialize_tty(&tty_out); + + /* CSI + finaly byte does not output anything */ + cursor_pos.X = 1; + cursor_pos.Y = 1; + set_cursor_position(&tty_out, cursor_pos); + capture_screen(&tty_out, &expect); + make_expect_screen_write(&expect, cursor_pos, HELLO); + cursor_pos.X += strlen(HELLO); + make_expect_screen_write(&expect, cursor_pos, HELLO); + snprintf(buffer, sizeof(buffer), "%s@%s%s~%s", CSI, HELLO, CSI, HELLO); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* CSI(C1) + finaly byte does not output anything */ + cursor_pos.X = 1; + cursor_pos.Y = 1; + set_cursor_position(&tty_out, cursor_pos); + capture_screen(&tty_out, &expect); + make_expect_screen_write(&expect, cursor_pos, HELLO); + cursor_pos.X += strlen(HELLO); + make_expect_screen_write(&expect, cursor_pos, HELLO); + snprintf(buffer, sizeof(buffer), "\xC2\x9B@%s\xC2\x9B~%s", HELLO, HELLO); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* CSI + intermediate byte + finaly byte does not output anything */ + cursor_pos.X = 1; + cursor_pos.Y = 1; + set_cursor_position(&tty_out, cursor_pos); + capture_screen(&tty_out, &expect); + make_expect_screen_write(&expect, cursor_pos, HELLO); + cursor_pos.X += strlen(HELLO); + make_expect_screen_write(&expect, cursor_pos, HELLO); + snprintf(buffer, sizeof(buffer), "%s @%s%s/~%s", CSI, HELLO, CSI, HELLO); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* CSI + parameter byte + finaly byte does not output anything */ + cursor_pos.X = 1; + cursor_pos.Y = 1; + set_cursor_position(&tty_out, cursor_pos); + capture_screen(&tty_out, &expect); + snprintf(buffer, + sizeof(buffer), + "%s0@%s%s>~%s%s?~%s", + CSI, + HELLO, + CSI, + HELLO, + CSI, + HELLO); + make_expect_screen_write(&expect, cursor_pos, HELLO); + cursor_pos.X += strlen(HELLO); + make_expect_screen_write(&expect, cursor_pos, HELLO); + cursor_pos.X += strlen(HELLO); + make_expect_screen_write(&expect, cursor_pos, HELLO); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* ESC Single-char control does not output anyghing */ + cursor_pos.X = 1; + cursor_pos.Y = 1; + set_cursor_position(&tty_out, cursor_pos); + capture_screen(&tty_out, &expect); + make_expect_screen_write(&expect, cursor_pos, HELLO); + cursor_pos.X += strlen(HELLO); + make_expect_screen_write(&expect, cursor_pos, HELLO); + snprintf(buffer, sizeof(buffer), "%s @%s%s/~%s", CSI, HELLO, CSI, HELLO); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* Nothing is output from ESC + ^, _, P, ] to BEL or ESC \ */ + /* Operaging System Command */ + cursor_pos.X = 1; + cursor_pos.Y = 1; + set_cursor_position(&tty_out, cursor_pos); + capture_screen(&tty_out, &expect); + make_expect_screen_write(&expect, cursor_pos, HELLO); + snprintf(buffer, sizeof(buffer), "%s]0;%s%s%s", ESC, HELLO, BEL, HELLO); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + ASSERT(compare_screen(&tty_out, &actual, &expect)); + /* Device Control Sequence */ + cursor_pos.X = 1; + cursor_pos.Y = 1; + set_cursor_position(&tty_out, cursor_pos); + capture_screen(&tty_out, &expect); + make_expect_screen_write(&expect, cursor_pos, HELLO); + snprintf(buffer, sizeof(buffer), "%sP$m%s%s", ESC, ST, HELLO); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + ASSERT(compare_screen(&tty_out, &actual, &expect)); + /* Privacy Message */ + cursor_pos.X = 1; + cursor_pos.Y = 1; + set_cursor_position(&tty_out, cursor_pos); + capture_screen(&tty_out, &expect); + make_expect_screen_write(&expect, cursor_pos, HELLO); + snprintf(buffer, + sizeof(buffer), + "%s^\"%s\\\"%s\"%s%s", + ESC, + HELLO, + HELLO, + ST, + HELLO); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + ASSERT(compare_screen(&tty_out, &actual, &expect)); + /* Application Program Command */ + cursor_pos.X = 1; + cursor_pos.Y = 1; + set_cursor_position(&tty_out, cursor_pos); + capture_screen(&tty_out, &expect); + make_expect_screen_write(&expect, cursor_pos, HELLO); + snprintf(buffer, + sizeof(buffer), + "%s_\"%s%s%s\"%s%s", + ESC, + HELLO, + ST, + HELLO, + BEL, + HELLO); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* Ignore double escape */ + cursor_pos.X = 1; + cursor_pos.Y = 1; + set_cursor_position(&tty_out, cursor_pos); + capture_screen(&tty_out, &expect); + make_expect_screen_write(&expect, cursor_pos, HELLO); + cursor_pos.X += strlen(HELLO); + make_expect_screen_write(&expect, cursor_pos, HELLO); + snprintf(buffer, + sizeof(buffer), + "%s%s@%s%s%s~%s", + ESC, + CSI, + HELLO, + ESC, + CSI, + HELLO); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* Ignored if argument overflow */ + set_cursor_to_home(&tty_out); + snprintf(buffer, sizeof(buffer), "%s1;%dH", CSI, UINT16_MAX + 1); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos.X == 1); + ASSERT(cursor_pos.Y == 1); + + /* Too many argument are ignored */ + cursor_pos.X = 1; + cursor_pos.Y = 1; + set_cursor_position(&tty_out, cursor_pos); + capture_screen(&tty_out, &expect); + make_expect_screen_write(&expect, cursor_pos, HELLO); + snprintf(buffer, + sizeof(buffer), + "%s%d;%d;%d;%d;%dm%s%sm", + CSI, + F_RED, + F_INTENSITY, + INVERSE, + B_CYAN, + B_INTENSITY_OFF, + HELLO, + CSI); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* In the case of DECSCUSR, the others are ignored */ + set_cursor_to_home(&tty_out); + snprintf(buffer, + sizeof(buffer), + "%s%d;%d H", + CSI, + expect.si.height / 2, + expect.si.width / 2); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos.X == 1); + ASSERT(cursor_pos.Y == 1); + + /* Invalid sequence are ignored */ + saved_cursor_size = get_cursor_size(&tty_out); + set_cursor_size(&tty_out, CURSOR_SIZE_MIDDLE); + snprintf(buffer, sizeof(buffer), "%s 1q", CSI); + write_console(&tty_out, buffer); + ASSERT(get_cursor_size(&tty_out) == CURSOR_SIZE_MIDDLE); + snprintf(buffer, sizeof(buffer), "%s 1 q", CSI); + write_console(&tty_out, buffer); + ASSERT(get_cursor_size(&tty_out) == CURSOR_SIZE_MIDDLE); + set_cursor_size(&tty_out, saved_cursor_size); + + /* #1874 2. */ + snprintf(buffer, sizeof(buffer), "%s??25l", CSI); + write_console(&tty_out, buffer); + ASSERT(get_cursor_visibility(&tty_out)); + snprintf(buffer, sizeof(buffer), "%s25?l", CSI); + write_console(&tty_out, buffer); + ASSERT(get_cursor_visibility(&tty_out)); + cursor_pos_old.X = expect.si.width / 2; + cursor_pos_old.Y = expect.si.height / 2; + set_cursor_position(&tty_out, cursor_pos_old); + snprintf(buffer, + sizeof(buffer), + "%s??%d;%df", + CSI, + expect.si.height / 4, + expect.si.width / 4); + write_console(&tty_out, buffer); + get_cursor_position(&tty_out, &cursor_pos); + ASSERT(cursor_pos.X = cursor_pos_old.X); + ASSERT(cursor_pos.Y = cursor_pos_old.Y); + set_cursor_to_home(&tty_out); + + /* CSI 25 l does nothing (#1874 4.) */ + snprintf(buffer, sizeof(buffer), "%s25l", CSI); + write_console(&tty_out, buffer); + ASSERT(get_cursor_visibility(&tty_out)); + + /* Unsupported sequences are ignored(#1874 5.) */ + dir = 2; + setup_screen(&tty_out); + capture_screen(&tty_out, &expect); + set_cursor_position(&tty_out, cursor_pos); + snprintf(buffer, sizeof(buffer), "%s?%dJ", CSI, dir); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + /* Finaly byte immedately after CSI [ are also output(#1874 1.) */ + cursor_pos.X = expect.si.width / 2; + cursor_pos.Y = expect.si.height / 2; + set_cursor_position(&tty_out, cursor_pos); + capture_screen(&tty_out, &expect); + make_expect_screen_write(&expect, cursor_pos, HELLO); + snprintf(buffer, sizeof(buffer), "%s[%s", CSI, HELLO); + write_console(&tty_out, buffer); + capture_screen(&tty_out, &actual); + ASSERT(compare_screen(&tty_out, &actual, &expect)); + + terminate_tty(&tty_out); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#else + +typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ + +#endif /* ifdef _WIN32 */ diff --git a/external/src/libuv/test/test-tty.c b/external/src/libuv/test/test-tty.c new file mode 100644 index 0000000..ff7d388 --- /dev/null +++ b/external/src/libuv/test/test-tty.c @@ -0,0 +1,474 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#ifdef _WIN32 +# include +# include +#else /* Unix */ +# include +# include +# if (defined(__linux__) || defined(__GLIBC__)) && !defined(__ANDROID__) +# include +# elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) +# include +# elif defined(__FreeBSD__) || defined(__DragonFly__) +# include +# endif +#endif + +#include +#include + + +TEST_IMPL(tty) { + int r, width, height; + int ttyin_fd, ttyout_fd; + uv_tty_t tty_in, tty_out; + uv_loop_t* loop = uv_default_loop(); + + /* Make sure we have an FD that refers to a tty */ +#ifdef _WIN32 + HANDLE handle; + handle = CreateFileA("conin$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + ASSERT(handle != INVALID_HANDLE_VALUE); + ttyin_fd = _open_osfhandle((intptr_t) handle, 0); + + handle = CreateFileA("conout$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + ASSERT(handle != INVALID_HANDLE_VALUE); + ttyout_fd = _open_osfhandle((intptr_t) handle, 0); + +#else /* unix */ + ttyin_fd = open("/dev/tty", O_RDONLY, 0); + if (ttyin_fd < 0) { + fprintf(stderr, "Cannot open /dev/tty as read-only: %s\n", strerror(errno)); + fflush(stderr); + return TEST_SKIP; + } + + ttyout_fd = open("/dev/tty", O_WRONLY, 0); + if (ttyout_fd < 0) { + fprintf(stderr, "Cannot open /dev/tty as write-only: %s\n", strerror(errno)); + fflush(stderr); + return TEST_SKIP; + } +#endif + + ASSERT(ttyin_fd >= 0); + ASSERT(ttyout_fd >= 0); + + ASSERT(UV_UNKNOWN_HANDLE == uv_guess_handle(-1)); + + ASSERT(UV_TTY == uv_guess_handle(ttyin_fd)); + ASSERT(UV_TTY == uv_guess_handle(ttyout_fd)); + + r = uv_tty_init(uv_default_loop(), &tty_in, ttyin_fd, 1); /* Readable. */ + ASSERT(r == 0); + ASSERT(uv_is_readable((uv_stream_t*) &tty_in)); + ASSERT(!uv_is_writable((uv_stream_t*) &tty_in)); + + r = uv_tty_init(uv_default_loop(), &tty_out, ttyout_fd, 0); /* Writable. */ + ASSERT(r == 0); + ASSERT(!uv_is_readable((uv_stream_t*) &tty_out)); + ASSERT(uv_is_writable((uv_stream_t*) &tty_out)); + + r = uv_tty_get_winsize(&tty_out, &width, &height); + ASSERT(r == 0); + + printf("width=%d height=%d\n", width, height); + + if (width == 0 && height == 0) { + /* Some environments such as containers or Jenkins behave like this + * sometimes */ + MAKE_VALGRIND_HAPPY(); + return TEST_SKIP; + } + + /* + * Is it a safe assumption that most people have terminals larger than + * 10x10? + */ + ASSERT(width > 10); + ASSERT(height > 10); + + /* Turn on raw mode. */ + r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_RAW); + ASSERT(r == 0); + + /* Turn off raw mode. */ + r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_NORMAL); + ASSERT(r == 0); + + /* Calling uv_tty_reset_mode() repeatedly should not clobber errno. */ + errno = 0; + ASSERT(0 == uv_tty_reset_mode()); + ASSERT(0 == uv_tty_reset_mode()); + ASSERT(0 == uv_tty_reset_mode()); + ASSERT(0 == errno); + + /* TODO check the actual mode! */ + + uv_close((uv_handle_t*) &tty_in, NULL); + uv_close((uv_handle_t*) &tty_out, NULL); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +#ifdef _WIN32 +static void tty_raw_alloc(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + buf->base = malloc(size); + buf->len = size; +} + +static void tty_raw_read(uv_stream_t* tty_in, ssize_t nread, const uv_buf_t* buf) { + if (nread > 0) { + ASSERT(nread == 1); + ASSERT(buf->base[0] == ' '); + uv_close((uv_handle_t*) tty_in, NULL); + } else { + ASSERT(nread == 0); + } +} + +TEST_IMPL(tty_raw) { + int r; + int ttyin_fd; + uv_tty_t tty_in; + uv_loop_t* loop = uv_default_loop(); + HANDLE handle; + INPUT_RECORD record; + DWORD written; + + /* Make sure we have an FD that refers to a tty */ + handle = CreateFileA("conin$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + ASSERT(handle != INVALID_HANDLE_VALUE); + ttyin_fd = _open_osfhandle((intptr_t) handle, 0); + ASSERT(ttyin_fd >= 0); + ASSERT(UV_TTY == uv_guess_handle(ttyin_fd)); + + r = uv_tty_init(uv_default_loop(), &tty_in, ttyin_fd, 1); /* Readable. */ + ASSERT(r == 0); + ASSERT(uv_is_readable((uv_stream_t*) &tty_in)); + ASSERT(!uv_is_writable((uv_stream_t*) &tty_in)); + + r = uv_read_start((uv_stream_t*)&tty_in, tty_raw_alloc, tty_raw_read); + ASSERT(r == 0); + + /* Give uv_tty_line_read_thread time to block on ReadConsoleW */ + Sleep(100); + + /* Turn on raw mode. */ + r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_RAW); + ASSERT(r == 0); + + /* Write ' ' that should be read in raw mode */ + record.EventType = KEY_EVENT; + record.Event.KeyEvent.bKeyDown = TRUE; + record.Event.KeyEvent.wRepeatCount = 1; + record.Event.KeyEvent.wVirtualKeyCode = VK_SPACE; + record.Event.KeyEvent.wVirtualScanCode = MapVirtualKeyW(VK_SPACE, MAPVK_VK_TO_VSC); + record.Event.KeyEvent.uChar.UnicodeChar = L' '; + record.Event.KeyEvent.dwControlKeyState = 0; + WriteConsoleInputW(handle, &record, 1, &written); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(tty_empty_write) { + int r; + int ttyout_fd; + uv_tty_t tty_out; + char dummy[1]; + uv_buf_t bufs[1]; + uv_loop_t* loop; + + /* Make sure we have an FD that refers to a tty */ + HANDLE handle; + + loop = uv_default_loop(); + + handle = CreateFileA("conout$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + ASSERT(handle != INVALID_HANDLE_VALUE); + ttyout_fd = _open_osfhandle((intptr_t) handle, 0); + + ASSERT(ttyout_fd >= 0); + + ASSERT(UV_TTY == uv_guess_handle(ttyout_fd)); + + r = uv_tty_init(uv_default_loop(), &tty_out, ttyout_fd, 0); /* Writable. */ + ASSERT(r == 0); + ASSERT(!uv_is_readable((uv_stream_t*) &tty_out)); + ASSERT(uv_is_writable((uv_stream_t*) &tty_out)); + + bufs[0].len = 0; + bufs[0].base = &dummy[0]; + + r = uv_try_write((uv_stream_t*) &tty_out, bufs, 1); + ASSERT(r == 0); + + uv_close((uv_handle_t*) &tty_out, NULL); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(tty_large_write) { + int r; + int ttyout_fd; + uv_tty_t tty_out; + char dummy[10000]; + uv_buf_t bufs[1]; + uv_loop_t* loop; + + /* Make sure we have an FD that refers to a tty */ + HANDLE handle; + + loop = uv_default_loop(); + + handle = CreateFileA("conout$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + ASSERT(handle != INVALID_HANDLE_VALUE); + ttyout_fd = _open_osfhandle((intptr_t) handle, 0); + + ASSERT(ttyout_fd >= 0); + + ASSERT(UV_TTY == uv_guess_handle(ttyout_fd)); + + r = uv_tty_init(uv_default_loop(), &tty_out, ttyout_fd, 0); /* Writable. */ + ASSERT(r == 0); + + memset(dummy, '.', sizeof(dummy) - 1); + dummy[sizeof(dummy) - 1] = '\n'; + + bufs[0] = uv_buf_init(dummy, sizeof(dummy)); + + r = uv_try_write((uv_stream_t*) &tty_out, bufs, 1); + ASSERT(r == 10000); + + uv_close((uv_handle_t*) &tty_out, NULL); + + uv_run(loop, UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(tty_raw_cancel) { + int r; + int ttyin_fd; + uv_tty_t tty_in; + HANDLE handle; + + /* Make sure we have an FD that refers to a tty */ + handle = CreateFileA("conin$", + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + ASSERT(handle != INVALID_HANDLE_VALUE); + ttyin_fd = _open_osfhandle((intptr_t) handle, 0); + ASSERT(ttyin_fd >= 0); + ASSERT(UV_TTY == uv_guess_handle(ttyin_fd)); + + r = uv_tty_init(uv_default_loop(), &tty_in, ttyin_fd, 1); /* Readable. */ + ASSERT(r == 0); + r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_RAW); + ASSERT(r == 0); + r = uv_read_start((uv_stream_t*)&tty_in, tty_raw_alloc, tty_raw_read); + ASSERT(r == 0); + + r = uv_read_stop((uv_stream_t*) &tty_in); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif + + +TEST_IMPL(tty_file) { +#ifndef _WIN32 + uv_loop_t loop; + uv_tty_t tty; + uv_tty_t tty_ro; + uv_tty_t tty_wo; + int fd; + + ASSERT(0 == uv_loop_init(&loop)); + + fd = open("test/fixtures/empty_file", O_RDONLY); + if (fd != -1) { + ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1)); + ASSERT(0 == close(fd)); + /* test EBADF handling */ + ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1)); + } + +/* Bug on AIX where '/dev/random' returns 1 from isatty() */ +#ifndef _AIX + fd = open("/dev/random", O_RDONLY); + if (fd != -1) { + ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1)); + ASSERT(0 == close(fd)); + } +#endif /* _AIX */ + + fd = open("/dev/zero", O_RDONLY); + if (fd != -1) { + ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1)); + ASSERT(0 == close(fd)); + } + + fd = open("/dev/tty", O_RDWR); + if (fd != -1) { + ASSERT(0 == uv_tty_init(&loop, &tty, fd, 1)); + ASSERT(0 == close(fd)); /* TODO: it's indeterminate who owns fd now */ + ASSERT(uv_is_readable((uv_stream_t*) &tty)); + ASSERT(uv_is_writable((uv_stream_t*) &tty)); + uv_close((uv_handle_t*) &tty, NULL); + ASSERT(!uv_is_readable((uv_stream_t*) &tty)); + ASSERT(!uv_is_writable((uv_stream_t*) &tty)); + } + + fd = open("/dev/tty", O_RDONLY); + if (fd != -1) { + ASSERT(0 == uv_tty_init(&loop, &tty_ro, fd, 1)); + ASSERT(0 == close(fd)); /* TODO: it's indeterminate who owns fd now */ + ASSERT(uv_is_readable((uv_stream_t*) &tty_ro)); + ASSERT(!uv_is_writable((uv_stream_t*) &tty_ro)); + uv_close((uv_handle_t*) &tty_ro, NULL); + ASSERT(!uv_is_readable((uv_stream_t*) &tty_ro)); + ASSERT(!uv_is_writable((uv_stream_t*) &tty_ro)); + } + + fd = open("/dev/tty", O_WRONLY); + if (fd != -1) { + ASSERT(0 == uv_tty_init(&loop, &tty_wo, fd, 0)); + ASSERT(0 == close(fd)); /* TODO: it's indeterminate who owns fd now */ + ASSERT(!uv_is_readable((uv_stream_t*) &tty_wo)); + ASSERT(uv_is_writable((uv_stream_t*) &tty_wo)); + uv_close((uv_handle_t*) &tty_wo, NULL); + ASSERT(!uv_is_readable((uv_stream_t*) &tty_wo)); + ASSERT(!uv_is_writable((uv_stream_t*) &tty_wo)); + } + + + ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); + ASSERT(0 == uv_loop_close(&loop)); + + MAKE_VALGRIND_HAPPY(); +#endif + return 0; +} + +TEST_IMPL(tty_pty) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif +#if defined(__ASAN__) + RETURN_SKIP("Test does not currently work in ASAN"); +#endif + +#if defined(__APPLE__) || \ + defined(__DragonFly__) || \ + defined(__FreeBSD__) || \ + defined(__FreeBSD_kernel__) || \ + (defined(__linux__) && !defined(__ANDROID__)) || \ + defined(__NetBSD__) || \ + defined(__OpenBSD__) + int master_fd, slave_fd, r; + struct winsize w; + uv_loop_t loop; + uv_tty_t master_tty, slave_tty; + + ASSERT(0 == uv_loop_init(&loop)); + + r = openpty(&master_fd, &slave_fd, NULL, NULL, &w); + if (r != 0) + RETURN_SKIP("No pty available, skipping."); + + ASSERT(0 == uv_tty_init(&loop, &slave_tty, slave_fd, 0)); + ASSERT(0 == uv_tty_init(&loop, &master_tty, master_fd, 0)); + ASSERT(uv_is_readable((uv_stream_t*) &slave_tty)); + ASSERT(uv_is_writable((uv_stream_t*) &slave_tty)); + ASSERT(uv_is_readable((uv_stream_t*) &master_tty)); + ASSERT(uv_is_writable((uv_stream_t*) &master_tty)); + /* Check if the file descriptor was reopened. If it is, + * UV_HANDLE_BLOCKING_WRITES (value 0x100000) isn't set on flags. + */ + ASSERT(0 == (slave_tty.flags & 0x100000)); + /* The master_fd of a pty should never be reopened. + */ + ASSERT(master_tty.flags & 0x100000); + ASSERT(0 == close(slave_fd)); + uv_close((uv_handle_t*) &slave_tty, NULL); + ASSERT(0 == close(master_fd)); + uv_close((uv_handle_t*) &master_tty, NULL); + + ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); + + MAKE_VALGRIND_HAPPY(); +#endif + return 0; +} diff --git a/external/src/libuv/test/test-udp-alloc-cb-fail.c b/external/src/libuv/test/test-udp-alloc-cb-fail.c new file mode 100644 index 0000000..6b09801 --- /dev/null +++ b/external/src/libuv/test/test-udp-alloc-cb-fail.c @@ -0,0 +1,196 @@ +/* Copyright libuv project and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) + +static uv_udp_t server; +static uv_udp_t client; + +static int cl_send_cb_called; +static int cl_recv_cb_called; + +static int sv_send_cb_called; +static int sv_recv_cb_called; + +static int close_cb_called; + + +static void sv_alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + CHECK_HANDLE(handle); + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void cl_alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + /* Do nothing, recv_cb should be called with UV_ENOBUFS. */ +} + + +static void close_cb(uv_handle_t* handle) { + CHECK_HANDLE(handle); + ASSERT(1 == uv_is_closing(handle)); + close_cb_called++; +} + + +static void cl_recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags) { + CHECK_HANDLE(handle); + ASSERT(flags == 0); + ASSERT(nread == UV_ENOBUFS); + + cl_recv_cb_called++; + + uv_close((uv_handle_t*) handle, close_cb); +} + + +static void cl_send_cb(uv_udp_send_t* req, int status) { + int r; + + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + CHECK_HANDLE(req->handle); + + r = uv_udp_recv_start(req->handle, cl_alloc_cb, cl_recv_cb); + ASSERT(r == 0); + + cl_send_cb_called++; +} + + +static void sv_send_cb(uv_udp_send_t* req, int status) { + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + CHECK_HANDLE(req->handle); + + uv_close((uv_handle_t*) req->handle, close_cb); + free(req); + + sv_send_cb_called++; +} + + +static void sv_recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* rcvbuf, + const struct sockaddr* addr, + unsigned flags) { + uv_udp_send_t* req; + uv_buf_t sndbuf; + int r; + + if (nread < 0) { + ASSERT(0 && "unexpected error"); + } + + if (nread == 0) { + /* Returning unused buffer. Don't count towards sv_recv_cb_called */ + ASSERT_NULL(addr); + return; + } + + CHECK_HANDLE(handle); + ASSERT(flags == 0); + + ASSERT_NOT_NULL(addr); + ASSERT(nread == 4); + ASSERT(!memcmp("PING", rcvbuf->base, nread)); + + r = uv_udp_recv_stop(handle); + ASSERT(r == 0); + + req = malloc(sizeof *req); + ASSERT_NOT_NULL(req); + + sndbuf = uv_buf_init("PONG", 4); + r = uv_udp_send(req, handle, &sndbuf, 1, addr, sv_send_cb); + ASSERT(r == 0); + + sv_recv_cb_called++; +} + + +TEST_IMPL(udp_alloc_cb_fail) { + struct sockaddr_in addr; + uv_udp_send_t req; + uv_buf_t buf; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + r = uv_udp_init(uv_default_loop(), &server); + ASSERT(r == 0); + + r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_udp_recv_start(&server, sv_alloc_cb, sv_recv_cb); + ASSERT(r == 0); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_udp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + buf = uv_buf_init("PING", 4); + r = uv_udp_send(&req, + &client, + &buf, + 1, + (const struct sockaddr*) &addr, + cl_send_cb); + ASSERT(r == 0); + + ASSERT(close_cb_called == 0); + ASSERT(cl_send_cb_called == 0); + ASSERT(cl_recv_cb_called == 0); + ASSERT(sv_send_cb_called == 0); + ASSERT(sv_recv_cb_called == 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(cl_send_cb_called == 1); + ASSERT(cl_recv_cb_called == 1); + ASSERT(sv_send_cb_called == 1); + ASSERT(sv_recv_cb_called == 1); + ASSERT(close_cb_called == 2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-bind.c b/external/src/libuv/test/test-udp-bind.c new file mode 100644 index 0000000..a1e080e --- /dev/null +++ b/external/src/libuv/test/test-udp-bind.c @@ -0,0 +1,93 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + + +TEST_IMPL(udp_bind) { + struct sockaddr_in addr; + uv_loop_t* loop; + uv_udp_t h1, h2; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + loop = uv_default_loop(); + + r = uv_udp_init(loop, &h1); + ASSERT(r == 0); + + r = uv_udp_init(loop, &h2); + ASSERT(r == 0); + + r = uv_udp_bind(&h1, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_udp_bind(&h2, (const struct sockaddr*) &addr, 0); + ASSERT(r == UV_EADDRINUSE); + + uv_close((uv_handle_t*) &h1, NULL); + uv_close((uv_handle_t*) &h2, NULL); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(udp_bind_reuseaddr) { + struct sockaddr_in addr; + uv_loop_t* loop; + uv_udp_t h1, h2; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + loop = uv_default_loop(); + + r = uv_udp_init(loop, &h1); + ASSERT(r == 0); + + r = uv_udp_init(loop, &h2); + ASSERT(r == 0); + + r = uv_udp_bind(&h1, (const struct sockaddr*) &addr, UV_UDP_REUSEADDR); + ASSERT(r == 0); + + r = uv_udp_bind(&h2, (const struct sockaddr*) &addr, UV_UDP_REUSEADDR); + ASSERT(r == 0); + + uv_close((uv_handle_t*) &h1, NULL); + uv_close((uv_handle_t*) &h2, NULL); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-connect.c b/external/src/libuv/test/test-udp-connect.c new file mode 100644 index 0000000..89ca1a8 --- /dev/null +++ b/external/src/libuv/test/test-udp-connect.c @@ -0,0 +1,197 @@ +/* Copyright libuv project and contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) + +static uv_udp_t server; +static uv_udp_t client; +static uv_buf_t buf; +static struct sockaddr_in lo_addr; + +static int cl_send_cb_called; +static int sv_recv_cb_called; + +static int close_cb_called; + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + CHECK_HANDLE(handle); + ASSERT(suggested_size <= sizeof(slab)); + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void close_cb(uv_handle_t* handle) { + CHECK_HANDLE(handle); + ASSERT(uv_is_closing(handle)); + close_cb_called++; +} + + +static void cl_send_cb(uv_udp_send_t* req, int status) { + int r; + + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + CHECK_HANDLE(req->handle); + if (++cl_send_cb_called == 1) { + uv_udp_connect(&client, NULL); + r = uv_udp_send(req, &client, &buf, 1, NULL, cl_send_cb); + ASSERT(r == UV_EDESTADDRREQ); + r = uv_udp_send(req, + &client, + &buf, + 1, + (const struct sockaddr*) &lo_addr, + cl_send_cb); + ASSERT(r == 0); + } + +} + + +static void sv_recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* rcvbuf, + const struct sockaddr* addr, + unsigned flags) { + if (nread > 0) { + ASSERT(nread == 4); + ASSERT_NOT_NULL(addr); + ASSERT(memcmp("EXIT", rcvbuf->base, nread) == 0); + if (++sv_recv_cb_called == 4) { + uv_close((uv_handle_t*) &server, close_cb); + uv_close((uv_handle_t*) &client, close_cb); + } + } +} + + +TEST_IMPL(udp_connect) { +#if defined(__PASE__) + RETURN_SKIP( + "IBMi PASE's UDP connection can not be disconnected with AF_UNSPEC."); +#endif + uv_udp_send_t req; + struct sockaddr_in ext_addr; + struct sockaddr_in tmp_addr; + int r; + int addrlen; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &lo_addr)); + + r = uv_udp_init(uv_default_loop(), &server); + ASSERT(r == 0); + + r = uv_udp_bind(&server, (const struct sockaddr*) &lo_addr, 0); + ASSERT(r == 0); + + r = uv_udp_recv_start(&server, alloc_cb, sv_recv_cb); + ASSERT(r == 0); + + r = uv_udp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + buf = uv_buf_init("EXIT", 4); + + /* connect() to INADDR_ANY fails on Windows wih WSAEADDRNOTAVAIL */ + ASSERT_EQ(0, uv_ip4_addr("0.0.0.0", TEST_PORT, &tmp_addr)); + r = uv_udp_connect(&client, (const struct sockaddr*) &tmp_addr); +#ifdef _WIN32 + ASSERT_EQ(r, UV_EADDRNOTAVAIL); +#else + ASSERT_EQ(r, 0); + r = uv_udp_connect(&client, NULL); + ASSERT_EQ(r, 0); +#endif + + ASSERT(0 == uv_ip4_addr("8.8.8.8", TEST_PORT, &ext_addr)); + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &lo_addr)); + + r = uv_udp_connect(&client, (const struct sockaddr*) &lo_addr); + ASSERT(r == 0); + r = uv_udp_connect(&client, (const struct sockaddr*) &ext_addr); + ASSERT(r == UV_EISCONN); + + addrlen = sizeof(tmp_addr); + r = uv_udp_getpeername(&client, (struct sockaddr*) &tmp_addr, &addrlen); + ASSERT(r == 0); + + /* To send messages in connected UDP sockets addr must be NULL */ + r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &lo_addr); + ASSERT(r == UV_EISCONN); + r = uv_udp_try_send(&client, &buf, 1, NULL); + ASSERT(r == 4); + r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &ext_addr); + ASSERT(r == UV_EISCONN); + + r = uv_udp_connect(&client, NULL); + ASSERT(r == 0); + r = uv_udp_connect(&client, NULL); + ASSERT(r == UV_ENOTCONN); + + addrlen = sizeof(tmp_addr); + r = uv_udp_getpeername(&client, (struct sockaddr*) &tmp_addr, &addrlen); + ASSERT(r == UV_ENOTCONN); + + /* To send messages in disconnected UDP sockets addr must be set */ + r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &lo_addr); + ASSERT(r == 4); + r = uv_udp_try_send(&client, &buf, 1, NULL); + ASSERT(r == UV_EDESTADDRREQ); + + + r = uv_udp_connect(&client, (const struct sockaddr*) &lo_addr); + ASSERT(r == 0); + r = uv_udp_send(&req, + &client, + &buf, + 1, + (const struct sockaddr*) &lo_addr, + cl_send_cb); + ASSERT(r == UV_EISCONN); + r = uv_udp_send(&req, &client, &buf, 1, NULL, cl_send_cb); + ASSERT(r == 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 2); + ASSERT(sv_recv_cb_called == 4); + ASSERT(cl_send_cb_called == 2); + + ASSERT(client.send_queue_size == 0); + ASSERT(server.send_queue_size == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-create-socket-early.c b/external/src/libuv/test/test-udp-create-socket-early.c new file mode 100644 index 0000000..f7e46ab --- /dev/null +++ b/external/src/libuv/test/test-udp-create-socket-early.c @@ -0,0 +1,135 @@ +/* Copyright (c) 2015 Saúl Ibarra Corretgé . + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +#ifdef _WIN32 +# define INVALID_FD (INVALID_HANDLE_VALUE) +#else +# define INVALID_FD (-1) +#endif + + +TEST_IMPL(udp_create_early) { + struct sockaddr_in addr; + struct sockaddr_in sockname; + uv_udp_t client; + uv_os_fd_t fd; + int r, namelen; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_udp_init_ex(uv_default_loop(), &client, AF_INET); + ASSERT(r == 0); + + r = uv_fileno((const uv_handle_t*) &client, &fd); + ASSERT(r == 0); + ASSERT(fd != INVALID_FD); + + /* Windows returns WSAEINVAL if the socket is not bound */ +#ifndef _WIN32 + namelen = sizeof sockname; + r = uv_udp_getsockname(&client, (struct sockaddr*) &sockname, &namelen); + ASSERT(r == 0); + ASSERT(sockname.sin_family == AF_INET); +#endif + + r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + namelen = sizeof sockname; + r = uv_udp_getsockname(&client, (struct sockaddr*) &sockname, &namelen); + ASSERT(r == 0); + ASSERT(memcmp(&addr.sin_addr, + &sockname.sin_addr, + sizeof(addr.sin_addr)) == 0); + + uv_close((uv_handle_t*) &client, NULL); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(udp_create_early_bad_bind) { + struct sockaddr_in addr; + uv_udp_t client; + uv_os_fd_t fd; + int r; + + if (!can_ipv6()) + RETURN_SKIP("IPv6 not supported"); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_udp_init_ex(uv_default_loop(), &client, AF_INET6); + ASSERT(r == 0); + + r = uv_fileno((const uv_handle_t*) &client, &fd); + ASSERT(r == 0); + ASSERT(fd != INVALID_FD); + + /* Windows returns WSAEINVAL if the socket is not bound */ +#ifndef _WIN32 + { + int namelen; + struct sockaddr_in6 sockname; + namelen = sizeof sockname; + r = uv_udp_getsockname(&client, (struct sockaddr*) &sockname, &namelen); + ASSERT(r == 0); + ASSERT(sockname.sin6_family == AF_INET6); + } +#endif + + r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0); +#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__MSYS__) + ASSERT(r == UV_EINVAL); +#else + ASSERT(r == UV_EFAULT); +#endif + + uv_close((uv_handle_t*) &client, NULL); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(udp_create_early_bad_domain) { + uv_udp_t client; + int r; + + r = uv_udp_init_ex(uv_default_loop(), &client, 47); + ASSERT(r == UV_EINVAL); + + r = uv_udp_init_ex(uv_default_loop(), &client, 1024); + ASSERT(r == UV_EINVAL); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-dgram-too-big.c b/external/src/libuv/test/test-udp-dgram-too-big.c new file mode 100644 index 0000000..bd44c42 --- /dev/null +++ b/external/src/libuv/test/test-udp-dgram-too-big.c @@ -0,0 +1,91 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &handle_) + +#define CHECK_REQ(req) \ + ASSERT((req) == &req_); + +static uv_udp_t handle_; +static uv_udp_send_t req_; + +static int send_cb_called; +static int close_cb_called; + + +static void close_cb(uv_handle_t* handle) { + CHECK_HANDLE(handle); + close_cb_called++; +} + + +static void send_cb(uv_udp_send_t* req, int status) { + CHECK_REQ(req); + CHECK_HANDLE(req->handle); + + ASSERT(status == UV_EMSGSIZE); + + uv_close((uv_handle_t*)req->handle, close_cb); + send_cb_called++; +} + + +TEST_IMPL(udp_dgram_too_big) { + char dgram[65536]; /* 64K MTU is unlikely, even on localhost */ + struct sockaddr_in addr; + uv_buf_t buf; + int r; + + memset(dgram, 42, sizeof dgram); /* silence valgrind */ + + r = uv_udp_init(uv_default_loop(), &handle_); + ASSERT(r == 0); + + buf = uv_buf_init(dgram, sizeof dgram); + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_udp_send(&req_, + &handle_, + &buf, + 1, + (const struct sockaddr*) &addr, + send_cb); + ASSERT(r == 0); + + ASSERT(close_cb_called == 0); + ASSERT(send_cb_called == 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(send_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-ipv6.c b/external/src/libuv/test/test-udp-ipv6.c new file mode 100644 index 0000000..7099953 --- /dev/null +++ b/external/src/libuv/test/test-udp-ipv6.c @@ -0,0 +1,251 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) +#include +#endif + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &server \ + || (uv_udp_t*)(handle) == &client \ + || (uv_timer_t*)(handle) == &timeout) + +#define CHECK_REQ(req) \ + ASSERT((req) == &req_); + +static uv_udp_t client; +static uv_udp_t server; +static uv_udp_send_t req_; +static char data[10]; +static uv_timer_t timeout; + +static int send_cb_called; +static int recv_cb_called; +static int close_cb_called; +static uint16_t client_port; + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) +static int can_ipv6_ipv4_dual(void) { + int v6only; + size_t size = sizeof(int); + + if (sysctlbyname("net.inet6.ip6.v6only", &v6only, &size, NULL, 0)) + return 0; + + return v6only != 1; +} +#endif + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + CHECK_HANDLE(handle); + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void close_cb(uv_handle_t* handle) { + CHECK_HANDLE(handle); + close_cb_called++; +} + + +static void send_cb(uv_udp_send_t* req, int status) { + CHECK_REQ(req); + CHECK_HANDLE(req->handle); + ASSERT(status == 0); + send_cb_called++; +} + +static int is_from_client(const struct sockaddr* addr) { + const struct sockaddr_in6* addr6; + char dst[256]; + int r; + + /* Debugging output, and filter out unwanted network traffic */ + if (addr != NULL) { + ASSERT(addr->sa_family == AF_INET6); + addr6 = (struct sockaddr_in6*) addr; + r = uv_inet_ntop(addr->sa_family, &addr6->sin6_addr, dst, sizeof(dst)); + if (r == 0) + printf("from [%.*s]:%d\n", (int) sizeof(dst), dst, addr6->sin6_port); + if (addr6->sin6_port != client_port) + return 0; + if (r != 0 || strcmp(dst, "::ffff:127.0.0.1")) + return 0; + } + return 1; +} + + +static void ipv6_recv_fail(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags) { + printf("got %d %.*s\n", (int) nread, nread > 0 ? (int) nread : 0, buf->base); + if (!is_from_client(addr) || (nread == 0 && addr == NULL)) + return; + ASSERT(0 && "this function should not have been called"); +} + + +static void ipv6_recv_ok(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags) { + CHECK_HANDLE(handle); + + printf("got %d %.*s\n", (int) nread, nread > 0 ? (int) nread : 0, buf->base); + if (!is_from_client(addr) || (nread == 0 && addr == NULL)) + return; + + ASSERT(nread == 9); + ASSERT(!memcmp(buf->base, data, 9)); + recv_cb_called++; +} + + +static void timeout_cb(uv_timer_t* timer) { + uv_close((uv_handle_t*)&server, close_cb); + uv_close((uv_handle_t*)&client, close_cb); + uv_close((uv_handle_t*)&timeout, close_cb); +} + + +static void do_test(uv_udp_recv_cb recv_cb, int bind_flags) { + struct sockaddr_in6 addr6; + struct sockaddr_in addr; + int addr6_len; + int addr_len; + uv_buf_t buf; + char dst[256]; + int r; + + ASSERT(0 == uv_ip6_addr("::0", TEST_PORT, &addr6)); + + r = uv_udp_init(uv_default_loop(), &server); + ASSERT(r == 0); + + r = uv_udp_bind(&server, (const struct sockaddr*) &addr6, bind_flags); + ASSERT(r == 0); + + addr6_len = sizeof(addr6); + ASSERT(uv_udp_getsockname(&server, (struct sockaddr*) &addr6, &addr6_len) == 0); + ASSERT(uv_inet_ntop(addr6.sin6_family, &addr6.sin6_addr, dst, sizeof(dst)) == 0); + printf("on [%.*s]:%d\n", (int) sizeof(dst), dst, addr6.sin6_port); + + r = uv_udp_recv_start(&server, alloc_cb, recv_cb); + ASSERT(r == 0); + + r = uv_udp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + ASSERT(uv_inet_ntop(addr.sin_family, &addr.sin_addr, dst, sizeof(dst)) == 0); + printf("to [%.*s]:%d\n", (int) sizeof(dst), dst, addr.sin_port); + + /* Create some unique data to send */ + ASSERT(9 == snprintf(data, sizeof(data), "PING%5u", uv_os_getpid() & 0xFFFF)); + buf = uv_buf_init(data, 9); + printf("sending %s\n", data); + + r = uv_udp_send(&req_, + &client, + &buf, + 1, + (const struct sockaddr*) &addr, + send_cb); + ASSERT(r == 0); + + addr_len = sizeof(addr); + ASSERT(uv_udp_getsockname(&client, (struct sockaddr*) &addr, &addr_len) == 0); + ASSERT(uv_inet_ntop(addr.sin_family, &addr.sin_addr, dst, sizeof(dst)) == 0); + printf("from [%.*s]:%d\n", (int) sizeof(dst), dst, addr.sin_port); + client_port = addr.sin_port; + + r = uv_timer_init(uv_default_loop(), &timeout); + ASSERT(r == 0); + + r = uv_timer_start(&timeout, timeout_cb, 500, 0); + ASSERT(r == 0); + + ASSERT(close_cb_called == 0); + ASSERT(send_cb_called == 0); + ASSERT(recv_cb_called == 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 3); + + MAKE_VALGRIND_HAPPY(); +} + + +TEST_IMPL(udp_dual_stack) { +#if defined(__CYGWIN__) || defined(__MSYS__) + /* FIXME: Does Cygwin support this? */ + RETURN_SKIP("FIXME: This test needs more investigation on Cygwin"); +#endif + + if (!can_ipv6()) + RETURN_SKIP("IPv6 not supported"); + +#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) + if (!can_ipv6_ipv4_dual()) + RETURN_SKIP("IPv6-IPv4 dual stack not supported"); +#elif defined(__OpenBSD__) + RETURN_SKIP("IPv6-IPv4 dual stack not supported"); +#endif + + do_test(ipv6_recv_ok, 0); + + printf("recv_cb_called %d\n", recv_cb_called); + printf("send_cb_called %d\n", send_cb_called); + ASSERT(recv_cb_called == 1); + ASSERT(send_cb_called == 1); + + return 0; +} + + +TEST_IMPL(udp_ipv6_only) { + if (!can_ipv6()) + RETURN_SKIP("IPv6 not supported"); + + do_test(ipv6_recv_fail, UV_UDP_IPV6ONLY); + + ASSERT(recv_cb_called == 0); + ASSERT(send_cb_called == 1); + + return 0; +} diff --git a/external/src/libuv/test/test-udp-mmsg.c b/external/src/libuv/test/test-udp-mmsg.c new file mode 100644 index 0000000..fb24115 --- /dev/null +++ b/external/src/libuv/test/test-udp-mmsg.c @@ -0,0 +1,142 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &recver || (uv_udp_t*)(handle) == &sender) + +#define BUFFER_MULTIPLIER 4 +#define MAX_DGRAM_SIZE (64 * 1024) +#define NUM_SENDS 8 +#define EXPECTED_MMSG_ALLOCS (NUM_SENDS / BUFFER_MULTIPLIER) + +static uv_udp_t recver; +static uv_udp_t sender; +static int recv_cb_called; +static int close_cb_called; +static int alloc_cb_called; + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + size_t buffer_size; + CHECK_HANDLE(handle); + + /* Only allocate enough room for multiple dgrams if we can actually recv them */ + buffer_size = MAX_DGRAM_SIZE; + if (uv_udp_using_recvmmsg((uv_udp_t*)handle)) + buffer_size *= BUFFER_MULTIPLIER; + + /* Actually malloc to exercise free'ing the buffer later */ + buf->base = malloc(buffer_size); + ASSERT_NOT_NULL(buf->base); + buf->len = buffer_size; + alloc_cb_called++; +} + + +static void close_cb(uv_handle_t* handle) { + CHECK_HANDLE(handle); + ASSERT(uv_is_closing(handle)); + close_cb_called++; +} + + +static void recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* rcvbuf, + const struct sockaddr* addr, + unsigned flags) { + ASSERT_GE(nread, 0); + + /* free and return if this is a mmsg free-only callback invocation */ + if (flags & UV_UDP_MMSG_FREE) { + ASSERT_EQ(nread, 0); + ASSERT_NULL(addr); + free(rcvbuf->base); + return; + } + + ASSERT_EQ(nread, 4); + ASSERT_NOT_NULL(addr); + ASSERT_MEM_EQ("PING", rcvbuf->base, nread); + + recv_cb_called++; + if (recv_cb_called == NUM_SENDS) { + uv_close((uv_handle_t*)handle, close_cb); + uv_close((uv_handle_t*)&sender, close_cb); + } + + /* Don't free if the buffer could be reused via mmsg */ + if (rcvbuf && !(flags & UV_UDP_MMSG_CHUNK)) + free(rcvbuf->base); +} + + +TEST_IMPL(udp_mmsg) { + struct sockaddr_in addr; + uv_buf_t buf; + int i; + + ASSERT_EQ(0, uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + ASSERT_EQ(0, uv_udp_init_ex(uv_default_loop(), &recver, + AF_UNSPEC | UV_UDP_RECVMMSG)); + + ASSERT_EQ(0, uv_udp_bind(&recver, (const struct sockaddr*) &addr, 0)); + + ASSERT_EQ(0, uv_udp_recv_start(&recver, alloc_cb, recv_cb)); + + ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + ASSERT_EQ(0, uv_udp_init(uv_default_loop(), &sender)); + + buf = uv_buf_init("PING", 4); + for (i = 0; i < NUM_SENDS; i++) { + ASSERT_EQ(4, uv_udp_try_send(&sender, &buf, 1, (const struct sockaddr*) &addr)); + } + + ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + ASSERT_EQ(close_cb_called, 2); + ASSERT_EQ(recv_cb_called, NUM_SENDS); + + ASSERT_EQ(sender.send_queue_size, 0); + ASSERT_EQ(recver.send_queue_size, 0); + + printf("%d allocs for %d recvs\n", alloc_cb_called, recv_cb_called); + + /* On platforms that don't support mmsg, each recv gets its own alloc */ + if (uv_udp_using_recvmmsg(&recver)) + ASSERT_EQ(alloc_cb_called, EXPECTED_MMSG_ALLOCS); + else + ASSERT_EQ(alloc_cb_called, recv_cb_called); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-multicast-interface.c b/external/src/libuv/test/test-udp-multicast-interface.c new file mode 100644 index 0000000..bd9a61c --- /dev/null +++ b/external/src/libuv/test/test-udp-multicast-interface.c @@ -0,0 +1,104 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) + +static uv_udp_t server; +static uv_udp_t client; + +static int sv_send_cb_called; +static int close_cb_called; + + +static void close_cb(uv_handle_t* handle) { + CHECK_HANDLE(handle); + close_cb_called++; +} + + +static void sv_send_cb(uv_udp_send_t* req, int status) { + ASSERT_NOT_NULL(req); + ASSERT(status == 0 || status == UV_ENETUNREACH || status == UV_EPERM); + CHECK_HANDLE(req->handle); + + sv_send_cb_called++; + + uv_close((uv_handle_t*) req->handle, close_cb); +} + + +TEST_IMPL(udp_multicast_interface) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + + int r; + uv_udp_send_t req; + uv_buf_t buf; + struct sockaddr_in addr; + struct sockaddr_in baddr; + + ASSERT(0 == uv_ip4_addr("239.255.0.1", TEST_PORT, &addr)); + + r = uv_udp_init(uv_default_loop(), &server); + ASSERT(r == 0); + + ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &baddr)); + r = uv_udp_bind(&server, (const struct sockaddr*)&baddr, 0); + ASSERT(r == 0); + + r = uv_udp_set_multicast_interface(&server, "0.0.0.0"); + ASSERT(r == 0); + + /* server sends "PING" */ + buf = uv_buf_init("PING", 4); + r = uv_udp_send(&req, + &server, + &buf, + 1, + (const struct sockaddr*)&addr, + sv_send_cb); + ASSERT(r == 0); + + ASSERT(close_cb_called == 0); + ASSERT(sv_send_cb_called == 0); + + /* run the loop till all events are processed */ + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(sv_send_cb_called == 1); + ASSERT(close_cb_called == 1); + + ASSERT(client.send_queue_size == 0); + ASSERT(server.send_queue_size == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-multicast-interface6.c b/external/src/libuv/test/test-udp-multicast-interface6.c new file mode 100644 index 0000000..be11514 --- /dev/null +++ b/external/src/libuv/test/test-udp-multicast-interface6.c @@ -0,0 +1,108 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) + +static uv_udp_t server; +static uv_udp_t client; + +static int sv_send_cb_called; +static int close_cb_called; + + +static void close_cb(uv_handle_t* handle) { + CHECK_HANDLE(handle); + close_cb_called++; +} + + +static void sv_send_cb(uv_udp_send_t* req, int status) { + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + CHECK_HANDLE(req->handle); + + sv_send_cb_called++; + + uv_close((uv_handle_t*) req->handle, close_cb); +} + + +TEST_IMPL(udp_multicast_interface6) { +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + + int r; + uv_udp_send_t req; + uv_buf_t buf; + struct sockaddr_in6 addr; + struct sockaddr_in6 baddr; + + if (!can_ipv6()) + RETURN_SKIP("IPv6 not supported"); + + ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr)); + + r = uv_udp_init(uv_default_loop(), &server); + ASSERT(r == 0); + + ASSERT(0 == uv_ip6_addr("::", 0, &baddr)); + r = uv_udp_bind(&server, (const struct sockaddr*)&baddr, 0); + ASSERT(r == 0); + +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) + r = uv_udp_set_multicast_interface(&server, "::1%lo0"); +#else + r = uv_udp_set_multicast_interface(&server, NULL); +#endif + ASSERT(r == 0); + + /* server sends "PING" */ + buf = uv_buf_init("PING", 4); + r = uv_udp_send(&req, + &server, + &buf, + 1, + (const struct sockaddr*)&addr, + sv_send_cb); + ASSERT(r == 0); + + ASSERT(close_cb_called == 0); + ASSERT(sv_send_cb_called == 0); + + /* run the loop till all events are processed */ + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(sv_send_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-multicast-join.c b/external/src/libuv/test/test-udp-multicast-join.c new file mode 100644 index 0000000..9e603a8 --- /dev/null +++ b/external/src/libuv/test/test-udp-multicast-join.c @@ -0,0 +1,181 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) + +#define MULTICAST_ADDR "239.255.0.1" + +static uv_udp_t server; +static uv_udp_t client; +static uv_udp_send_t req; +static uv_udp_send_t req_ss; + +static int cl_recv_cb_called; + +static int sv_send_cb_called; + +static int close_cb_called; + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + CHECK_HANDLE(handle); + ASSERT(suggested_size <= sizeof(slab)); + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void close_cb(uv_handle_t* handle) { + CHECK_HANDLE(handle); + close_cb_called++; +} + + +static void sv_send_cb(uv_udp_send_t* req, int status) { + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + CHECK_HANDLE(req->handle); + + sv_send_cb_called++; + + if (sv_send_cb_called == 2) + uv_close((uv_handle_t*) req->handle, close_cb); +} + + +static int do_send(uv_udp_send_t* send_req) { + uv_buf_t buf; + struct sockaddr_in addr; + + buf = uv_buf_init("PING", 4); + + ASSERT(0 == uv_ip4_addr(MULTICAST_ADDR, TEST_PORT, &addr)); + + /* client sends "PING" */ + return uv_udp_send(send_req, + &client, + &buf, + 1, + (const struct sockaddr*) &addr, + sv_send_cb); +} + + +static void cl_recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags) { + CHECK_HANDLE(handle); + ASSERT(flags == 0); + + if (nread < 0) { + ASSERT(0 && "unexpected error"); + } + + if (nread == 0) { + /* Returning unused buffer. Don't count towards cl_recv_cb_called */ + ASSERT_NULL(addr); + return; + } + + ASSERT_NOT_NULL(addr); + ASSERT(nread == 4); + ASSERT(!memcmp("PING", buf->base, nread)); + + cl_recv_cb_called++; + + if (cl_recv_cb_called == 2) { + /* we are done with the server handle, we can close it */ + uv_close((uv_handle_t*) &server, close_cb); + } else { + int r; + char source_addr[64]; + + r = uv_ip4_name((const struct sockaddr_in*)addr, source_addr, sizeof(source_addr)); + ASSERT(r == 0); + + r = uv_udp_set_membership(&server, MULTICAST_ADDR, NULL, UV_LEAVE_GROUP); + ASSERT(r == 0); + +#if !defined(__OpenBSD__) && !defined(__NetBSD__) + r = uv_udp_set_source_membership(&server, MULTICAST_ADDR, NULL, source_addr, UV_JOIN_GROUP); + ASSERT(r == 0); +#endif + + r = do_send(&req_ss); + ASSERT(r == 0); + } +} + + +TEST_IMPL(udp_multicast_join) { + int r; + struct sockaddr_in addr; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + r = uv_udp_init(uv_default_loop(), &server); + ASSERT(r == 0); + + r = uv_udp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + /* bind to the desired port */ + r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + /* join the multicast channel */ + r = uv_udp_set_membership(&server, MULTICAST_ADDR, NULL, UV_JOIN_GROUP); + if (r == UV_ENODEV) + RETURN_SKIP("No multicast support."); + ASSERT(r == 0); + + r = uv_udp_recv_start(&server, alloc_cb, cl_recv_cb); + ASSERT(r == 0); + + r = do_send(&req); + ASSERT(r == 0); + + ASSERT(close_cb_called == 0); + ASSERT(cl_recv_cb_called == 0); + ASSERT(sv_send_cb_called == 0); + + /* run the loop till all events are processed */ + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(cl_recv_cb_called == 2); + ASSERT(sv_send_cb_called == 2); + ASSERT(close_cb_called == 2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-multicast-join6.c b/external/src/libuv/test/test-udp-multicast-join6.c new file mode 100644 index 0000000..e67c5ee --- /dev/null +++ b/external/src/libuv/test/test-udp-multicast-join6.c @@ -0,0 +1,219 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) + +#if defined(__APPLE__) || \ + defined(_AIX) || \ + defined(__MVS__) || \ + defined(__FreeBSD_kernel__) || \ + defined(__NetBSD__) || \ + defined(__OpenBSD__) + #define MULTICAST_ADDR "ff02::1%lo0" + #define INTERFACE_ADDR "::1%lo0" +#else + #define MULTICAST_ADDR "ff02::1" + #define INTERFACE_ADDR NULL +#endif + +static uv_udp_t server; +static uv_udp_t client; +static uv_udp_send_t req; +static uv_udp_send_t req_ss; + +static int cl_recv_cb_called; + +static int sv_send_cb_called; + +static int close_cb_called; + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + CHECK_HANDLE(handle); + ASSERT(suggested_size <= sizeof(slab)); + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void close_cb(uv_handle_t* handle) { + CHECK_HANDLE(handle); + close_cb_called++; +} + + +static void sv_send_cb(uv_udp_send_t* req, int status) { + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + CHECK_HANDLE(req->handle); + + sv_send_cb_called++; + + if (sv_send_cb_called == 2) + uv_close((uv_handle_t*) req->handle, close_cb); +} + + +static int do_send(uv_udp_send_t* send_req) { + uv_buf_t buf; + struct sockaddr_in6 addr; + + buf = uv_buf_init("PING", 4); + + ASSERT(0 == uv_ip6_addr(MULTICAST_ADDR, TEST_PORT, &addr)); + + /* client sends "PING" */ + return uv_udp_send(send_req, + &client, + &buf, + 1, + (const struct sockaddr*) &addr, + sv_send_cb); +} + + +static void cl_recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags) { + CHECK_HANDLE(handle); + ASSERT(flags == 0); + + if (nread < 0) { + ASSERT(0 && "unexpected error"); + } + + if (nread == 0) { + /* Returning unused buffer. Don't count towards cl_recv_cb_called */ + ASSERT_NULL(addr); + return; + } + + ASSERT_NOT_NULL(addr); + ASSERT(nread == 4); + ASSERT(!memcmp("PING", buf->base, nread)); + + cl_recv_cb_called++; + + if (cl_recv_cb_called == 2) { + /* we are done with the server handle, we can close it */ + uv_close((uv_handle_t*) &server, close_cb); + } else { + int r; + char source_addr[64]; + + r = uv_ip6_name((const struct sockaddr_in6*)addr, source_addr, sizeof(source_addr)); + ASSERT(r == 0); + + r = uv_udp_set_membership(&server, MULTICAST_ADDR, INTERFACE_ADDR, UV_LEAVE_GROUP); + ASSERT(r == 0); + + r = uv_udp_set_source_membership(&server, MULTICAST_ADDR, INTERFACE_ADDR, source_addr, UV_JOIN_GROUP); + ASSERT(r == 0); + + r = do_send(&req_ss); + ASSERT(r == 0); + } +} + + +static int can_ipv6_external(void) { + uv_interface_address_t* addr; + int supported; + int count; + int i; + + if (uv_interface_addresses(&addr, &count)) + return 0; /* Assume no IPv6 support on failure. */ + + supported = 0; + for (i = 0; supported == 0 && i < count; i += 1) + supported = (AF_INET6 == addr[i].address.address6.sin6_family && + !addr[i].is_internal); + + uv_free_interface_addresses(addr, count); + return supported; +} + + +TEST_IMPL(udp_multicast_join6) { + int r; + struct sockaddr_in6 addr; + + if (!can_ipv6_external()) + RETURN_SKIP("No external IPv6 interface available"); + + ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr)); + + r = uv_udp_init(uv_default_loop(), &server); + ASSERT(r == 0); + + r = uv_udp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + /* bind to the desired port */ + r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_udp_set_membership(&server, MULTICAST_ADDR, INTERFACE_ADDR, UV_JOIN_GROUP); + if (r == UV_ENODEV) { + MAKE_VALGRIND_HAPPY(); + RETURN_SKIP("No ipv6 multicast route"); + } + + ASSERT(r == 0); + +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + r = uv_udp_recv_start(&server, alloc_cb, cl_recv_cb); + ASSERT(r == 0); + + r = do_send(&req); + ASSERT(r == 0); + + ASSERT(close_cb_called == 0); + ASSERT(cl_recv_cb_called == 0); + ASSERT(sv_send_cb_called == 0); + + /* run the loop till all events are processed */ + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(cl_recv_cb_called == 2); + ASSERT(sv_send_cb_called == 2); + ASSERT(close_cb_called == 2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-multicast-ttl.c b/external/src/libuv/test/test-udp-multicast-ttl.c new file mode 100644 index 0000000..fbddd90 --- /dev/null +++ b/external/src/libuv/test/test-udp-multicast-ttl.c @@ -0,0 +1,94 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) + +static uv_udp_t server; +static uv_udp_t client; + +static int sv_send_cb_called; +static int close_cb_called; + + +static void close_cb(uv_handle_t* handle) { + CHECK_HANDLE(handle); + close_cb_called++; +} + + +static void sv_send_cb(uv_udp_send_t* req, int status) { + ASSERT_NOT_NULL(req); + ASSERT(status == 0 || status == UV_ENETUNREACH || status == UV_EPERM); + CHECK_HANDLE(req->handle); + + sv_send_cb_called++; + + uv_close((uv_handle_t*) req->handle, close_cb); +} + + +TEST_IMPL(udp_multicast_ttl) { + int r; + uv_udp_send_t req; + uv_buf_t buf; + struct sockaddr_in addr; + + r = uv_udp_init(uv_default_loop(), &server); + ASSERT(r == 0); + + ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &addr)); + r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_udp_set_multicast_ttl(&server, 32); + ASSERT(r == 0); + + /* server sends "PING" */ + buf = uv_buf_init("PING", 4); + ASSERT(0 == uv_ip4_addr("239.255.0.1", TEST_PORT, &addr)); + r = uv_udp_send(&req, + &server, + &buf, + 1, + (const struct sockaddr*) &addr, + sv_send_cb); + ASSERT(r == 0); + + ASSERT(close_cb_called == 0); + ASSERT(sv_send_cb_called == 0); + + /* run the loop till all events are processed */ + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(sv_send_cb_called == 1); + ASSERT(close_cb_called == 1); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-open.c b/external/src/libuv/test/test-udp-open.c new file mode 100644 index 0000000..f5136b6 --- /dev/null +++ b/external/src/libuv/test/test-udp-open.c @@ -0,0 +1,350 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include +#include +#include + +#ifndef _WIN32 +# include +# include +# include +#endif + +static int send_cb_called = 0; +static int close_cb_called = 0; + +static uv_udp_send_t send_req; + + +static void startup(void) { +#ifdef _WIN32 + struct WSAData wsa_data; + int r = WSAStartup(MAKEWORD(2, 2), &wsa_data); + ASSERT(r == 0); +#endif +} + + +static uv_os_sock_t create_udp_socket(void) { + uv_os_sock_t sock; + + sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); +#ifdef _WIN32 + ASSERT(sock != INVALID_SOCKET); +#else + ASSERT(sock >= 0); +#endif + +#ifndef _WIN32 + { + /* Allow reuse of the port. */ + int yes = 1; + int r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes); + ASSERT(r == 0); + } +#endif + + return sock; +} + + +static void close_socket(uv_os_sock_t sock) { + int r; +#ifdef _WIN32 + r = closesocket(sock); +#else + r = close(sock); +#endif + ASSERT(r == 0); +} + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + ASSERT(suggested_size <= sizeof(slab)); + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); + close_cb_called++; +} + + +static void recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags) { + int r; + + if (nread < 0) { + ASSERT(0 && "unexpected error"); + } + + if (nread == 0) { + /* Returning unused buffer. Don't count towards sv_recv_cb_called */ + ASSERT_NULL(addr); + return; + } + + ASSERT(flags == 0); + + ASSERT_NOT_NULL(addr); + ASSERT(nread == 4); + ASSERT(memcmp("PING", buf->base, nread) == 0); + + r = uv_udp_recv_stop(handle); + ASSERT(r == 0); + + uv_close((uv_handle_t*) handle, close_cb); +} + + +static void send_cb(uv_udp_send_t* req, int status) { + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + + send_cb_called++; + uv_close((uv_handle_t*)req->handle, close_cb); +} + + +TEST_IMPL(udp_open) { + struct sockaddr_in addr; + uv_buf_t buf = uv_buf_init("PING", 4); + uv_udp_t client, client2; + uv_os_sock_t sock; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + startup(); + sock = create_udp_socket(); + + r = uv_udp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + r = uv_udp_open(&client, sock); + ASSERT(r == 0); + + r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_udp_recv_start(&client, alloc_cb, recv_cb); + ASSERT(r == 0); + + r = uv_udp_send(&send_req, + &client, + &buf, + 1, + (const struct sockaddr*) &addr, + send_cb); + ASSERT(r == 0); + +#ifndef _WIN32 + { + r = uv_udp_init(uv_default_loop(), &client2); + ASSERT(r == 0); + + r = uv_udp_open(&client2, sock); + ASSERT(r == UV_EEXIST); + + uv_close((uv_handle_t*) &client2, NULL); + } +#else /* _WIN32 */ + (void)client2; +#endif + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(send_cb_called == 1); + ASSERT(close_cb_called == 1); + + ASSERT(client.send_queue_size == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(udp_open_twice) { + uv_udp_t client; + uv_os_sock_t sock1, sock2; + int r; + + startup(); + sock1 = create_udp_socket(); + sock2 = create_udp_socket(); + + r = uv_udp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + r = uv_udp_open(&client, sock1); + ASSERT(r == 0); + + r = uv_udp_open(&client, sock2); + ASSERT(r == UV_EBUSY); + close_socket(sock2); + + uv_close((uv_handle_t*) &client, NULL); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(udp_open_bound) { + struct sockaddr_in addr; + uv_udp_t client; + uv_os_sock_t sock; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + startup(); + sock = create_udp_socket(); + + r = bind(sock, (struct sockaddr*) &addr, sizeof(addr)); + ASSERT(r == 0); + + r = uv_udp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + r = uv_udp_open(&client, sock); + ASSERT(r == 0); + + r = uv_udp_recv_start(&client, alloc_cb, recv_cb); + ASSERT(r == 0); + + uv_close((uv_handle_t*) &client, NULL); + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +TEST_IMPL(udp_open_connect) { + struct sockaddr_in addr; + uv_buf_t buf = uv_buf_init("PING", 4); + uv_udp_t client; + uv_udp_t server; + uv_os_sock_t sock; + int r; + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + startup(); + sock = create_udp_socket(); + + r = uv_udp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + r = connect(sock, (const struct sockaddr*) &addr, sizeof(addr)); + ASSERT(r == 0); + + r = uv_udp_open(&client, sock); + ASSERT(r == 0); + + r = uv_udp_init(uv_default_loop(), &server); + ASSERT(r == 0); + + r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_udp_recv_start(&server, alloc_cb, recv_cb); + ASSERT(r == 0); + + r = uv_udp_send(&send_req, + &client, + &buf, + 1, + NULL, + send_cb); + ASSERT(r == 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(send_cb_called == 1); + ASSERT(close_cb_called == 2); + + ASSERT(client.send_queue_size == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + +#ifndef _WIN32 +TEST_IMPL(udp_send_unix) { + /* Test that "uv_udp_send()" supports sending over + a "sockaddr_un" address. */ + struct sockaddr_un addr; + uv_udp_t handle; + uv_udp_send_t req; + uv_loop_t* loop; + uv_buf_t buf = uv_buf_init("PING", 4); + int fd; + int r; + + loop = uv_default_loop(); + + memset(&addr, 0, sizeof addr); + addr.sun_family = AF_UNIX; + ASSERT(strlen(TEST_PIPENAME) < sizeof(addr.sun_path)); + memcpy(addr.sun_path, TEST_PIPENAME, strlen(TEST_PIPENAME)); + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + ASSERT(fd >= 0); + + unlink(TEST_PIPENAME); + ASSERT(0 == bind(fd, (const struct sockaddr*)&addr, sizeof addr)); + ASSERT(0 == listen(fd, 1)); + + r = uv_udp_init(loop, &handle); + ASSERT(r == 0); + r = uv_udp_open(&handle, fd); + ASSERT(r == 0); + uv_run(loop, UV_RUN_DEFAULT); + + r = uv_udp_send(&req, + &handle, + &buf, + 1, + (const struct sockaddr*) &addr, + NULL); + ASSERT(r == 0); + + uv_close((uv_handle_t*)&handle, NULL); + uv_run(loop, UV_RUN_DEFAULT); + close(fd); + unlink(TEST_PIPENAME); + + MAKE_VALGRIND_HAPPY(); + return 0; +} +#endif diff --git a/external/src/libuv/test/test-udp-options.c b/external/src/libuv/test/test-udp-options.c new file mode 100644 index 0000000..3ea51ba --- /dev/null +++ b/external/src/libuv/test/test-udp-options.c @@ -0,0 +1,160 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + + +static int udp_options_test(const struct sockaddr* addr) { + static int invalid_ttls[] = { -1, 0, 256 }; + uv_loop_t* loop; + uv_udp_t h; + int i, r; + + loop = uv_default_loop(); + + r = uv_udp_init(loop, &h); + ASSERT(r == 0); + + uv_unref((uv_handle_t*)&h); /* don't keep the loop alive */ + + r = uv_udp_bind(&h, addr, 0); + ASSERT(r == 0); + + r = uv_udp_set_broadcast(&h, 1); + r |= uv_udp_set_broadcast(&h, 1); + r |= uv_udp_set_broadcast(&h, 0); + r |= uv_udp_set_broadcast(&h, 0); + ASSERT(r == 0); + + /* values 1-255 should work */ + for (i = 1; i <= 255; i++) { + r = uv_udp_set_ttl(&h, i); +#if defined(__MVS__) + if (addr->sa_family == AF_INET6) + ASSERT(r == 0); + else + ASSERT(r == UV_ENOTSUP); +#else + ASSERT(r == 0); +#endif + } + + for (i = 0; i < (int) ARRAY_SIZE(invalid_ttls); i++) { + r = uv_udp_set_ttl(&h, invalid_ttls[i]); + ASSERT(r == UV_EINVAL); + } + + r = uv_udp_set_multicast_loop(&h, 1); + r |= uv_udp_set_multicast_loop(&h, 1); + r |= uv_udp_set_multicast_loop(&h, 0); + r |= uv_udp_set_multicast_loop(&h, 0); + ASSERT(r == 0); + + /* values 0-255 should work */ + for (i = 0; i <= 255; i++) { + r = uv_udp_set_multicast_ttl(&h, i); + ASSERT(r == 0); + } + + /* anything >255 should fail */ + r = uv_udp_set_multicast_ttl(&h, 256); + ASSERT(r == UV_EINVAL); + /* don't test ttl=-1, it's a valid value on some platforms */ + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + + +TEST_IMPL(udp_options) { + struct sockaddr_in addr; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + return udp_options_test((const struct sockaddr*) &addr); +} + + +TEST_IMPL(udp_options6) { + struct sockaddr_in6 addr; + + if (!can_ipv6()) + RETURN_SKIP("IPv6 not supported"); + + ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr)); + return udp_options_test((const struct sockaddr*) &addr); +} + + +TEST_IMPL(udp_no_autobind) { + uv_loop_t* loop; + uv_udp_t h; + uv_udp_t h2; + + loop = uv_default_loop(); + + /* Test a lazy initialized socket. */ + ASSERT(0 == uv_udp_init(loop, &h)); + ASSERT(UV_EBADF == uv_udp_set_multicast_ttl(&h, 32)); + ASSERT(UV_EBADF == uv_udp_set_broadcast(&h, 1)); +#if defined(__MVS__) + ASSERT(UV_ENOTSUP == uv_udp_set_ttl(&h, 1)); +#else + ASSERT(UV_EBADF == uv_udp_set_ttl(&h, 1)); +#endif + ASSERT(UV_EBADF == uv_udp_set_multicast_loop(&h, 1)); +/* TODO(gengjiawen): Fix test on QEMU. */ +#if defined(__QEMU__) + RETURN_SKIP("Test does not currently work in QEMU"); +#endif + ASSERT(UV_EBADF == uv_udp_set_multicast_interface(&h, "0.0.0.0")); + + uv_close((uv_handle_t*) &h, NULL); + + /* Test a non-lazily initialized socket. */ + ASSERT(0 == uv_udp_init_ex(loop, &h2, AF_INET | UV_UDP_RECVMMSG)); + ASSERT(0 == uv_udp_set_multicast_ttl(&h2, 32)); + ASSERT(0 == uv_udp_set_broadcast(&h2, 1)); + +#if defined(__MVS__) + /* zOS only supports setting ttl for IPv6 sockets. */ + ASSERT(UV_ENOTSUP == uv_udp_set_ttl(&h2, 1)); +#else + ASSERT(0 == uv_udp_set_ttl(&h2, 1)); +#endif + + ASSERT(0 == uv_udp_set_multicast_loop(&h2, 1)); + ASSERT(0 == uv_udp_set_multicast_interface(&h2, "0.0.0.0")); + + uv_close((uv_handle_t*) &h2, NULL); + + ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-send-and-recv.c b/external/src/libuv/test/test-udp-send-and-recv.c new file mode 100644 index 0000000..d602090 --- /dev/null +++ b/external/src/libuv/test/test-udp-send-and-recv.c @@ -0,0 +1,212 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) + +static uv_udp_t server; +static uv_udp_t client; + +static int cl_send_cb_called; +static int cl_recv_cb_called; + +static int sv_send_cb_called; +static int sv_recv_cb_called; + +static int close_cb_called; + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + CHECK_HANDLE(handle); + ASSERT(suggested_size <= sizeof(slab)); + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void close_cb(uv_handle_t* handle) { + CHECK_HANDLE(handle); + ASSERT(1 == uv_is_closing(handle)); + close_cb_called++; +} + + +static void cl_recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags) { + CHECK_HANDLE(handle); + ASSERT(flags == 0); + + if (nread < 0) { + ASSERT(0 && "unexpected error"); + } + + if (nread == 0) { + /* Returning unused buffer. Don't count towards cl_recv_cb_called */ + ASSERT_NULL(addr); + return; + } + + ASSERT_NOT_NULL(addr); + ASSERT(nread == 4); + ASSERT(!memcmp("PONG", buf->base, nread)); + + cl_recv_cb_called++; + + uv_close((uv_handle_t*) handle, close_cb); +} + + +static void cl_send_cb(uv_udp_send_t* req, int status) { + int r; + + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + CHECK_HANDLE(req->handle); + + r = uv_udp_recv_start(req->handle, alloc_cb, cl_recv_cb); + ASSERT(r == 0); + + cl_send_cb_called++; +} + + +static void sv_send_cb(uv_udp_send_t* req, int status) { + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + CHECK_HANDLE(req->handle); + + uv_close((uv_handle_t*) req->handle, close_cb); + free(req); + + sv_send_cb_called++; +} + + +static void sv_recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* rcvbuf, + const struct sockaddr* addr, + unsigned flags) { + uv_udp_send_t* req; + uv_buf_t sndbuf; + int r; + + if (nread < 0) { + ASSERT(0 && "unexpected error"); + } + + if (nread == 0) { + /* Returning unused buffer. Don't count towards sv_recv_cb_called */ + ASSERT_NULL(addr); + return; + } + + CHECK_HANDLE(handle); + ASSERT(flags == 0); + + ASSERT_NOT_NULL(addr); + ASSERT(nread == 4); + ASSERT(!memcmp("PING", rcvbuf->base, nread)); + + /* FIXME? `uv_udp_recv_stop` does what it says: recv_cb is not called + * anymore. That's problematic because the read buffer won't be returned + * either... Not sure I like that but it's consistent with `uv_read_stop`. + */ + r = uv_udp_recv_stop(handle); + ASSERT(r == 0); + + req = malloc(sizeof *req); + ASSERT_NOT_NULL(req); + + sndbuf = uv_buf_init("PONG", 4); + r = uv_udp_send(req, handle, &sndbuf, 1, addr, sv_send_cb); + ASSERT(r == 0); + + sv_recv_cb_called++; +} + + +TEST_IMPL(udp_send_and_recv) { + struct sockaddr_in addr; + uv_udp_send_t req; + uv_buf_t buf; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + r = uv_udp_init(uv_default_loop(), &server); + ASSERT(r == 0); + + r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_udp_recv_start(&server, alloc_cb, sv_recv_cb); + ASSERT(r == 0); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_udp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + /* client sends "PING", expects "PONG" */ + buf = uv_buf_init("PING", 4); + + r = uv_udp_send(&req, + &client, + &buf, + 1, + (const struct sockaddr*) &addr, + cl_send_cb); + ASSERT(r == 0); + + ASSERT(close_cb_called == 0); + ASSERT(cl_send_cb_called == 0); + ASSERT(cl_recv_cb_called == 0); + ASSERT(sv_send_cb_called == 0); + ASSERT(sv_recv_cb_called == 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(cl_send_cb_called == 1); + ASSERT(cl_recv_cb_called == 1); + ASSERT(sv_send_cb_called == 1); + ASSERT(sv_recv_cb_called == 1); + ASSERT(close_cb_called == 2); + + ASSERT(client.send_queue_size == 0); + ASSERT(server.send_queue_size == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-send-hang-loop.c b/external/src/libuv/test/test-udp-send-hang-loop.c new file mode 100644 index 0000000..072070b --- /dev/null +++ b/external/src/libuv/test/test-udp-send-hang-loop.c @@ -0,0 +1,99 @@ +/* Copyright The libuv project and contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define CHECK_OBJECT(handle, type, parent) \ + ASSERT((type*)(handle) == &(parent)) + +static uv_udp_t client; +static uv_idle_t idle_handle; +static uv_udp_send_t send_req; +static uv_buf_t buf; +static struct sockaddr_in addr; +static char send_data[1024]; + +static int loop_hang_called; + +static void send_cb(uv_udp_send_t* req, int status); + + +static void idle_cb(uv_idle_t* handle) { + int r; + + ASSERT_NULL(send_req.handle); + CHECK_OBJECT(handle, uv_idle_t, idle_handle); + ASSERT(0 == uv_idle_stop(handle)); + + /* It probably would have stalled by now if it's going to stall at all. */ + if (++loop_hang_called > 1000) { + uv_close((uv_handle_t*) &client, NULL); + uv_close((uv_handle_t*) &idle_handle, NULL); + return; + } + + r = uv_udp_send(&send_req, + &client, + &buf, + 1, + (const struct sockaddr*) &addr, + send_cb); + ASSERT(r == 0); +} + + +static void send_cb(uv_udp_send_t* req, int status) { + ASSERT_NOT_NULL(req); + ASSERT(status == 0 || status == UV_ENETUNREACH); + CHECK_OBJECT(req->handle, uv_udp_t, client); + CHECK_OBJECT(req, uv_udp_send_t, send_req); + req->handle = NULL; + + ASSERT(0 == uv_idle_start(&idle_handle, idle_cb)); +} + + +TEST_IMPL(udp_send_hang_loop) { + ASSERT(0 == uv_idle_init(uv_default_loop(), &idle_handle)); + + /* 192.0.2.0/8 is "TEST-NET" and reserved for documentation. + * Good for us, though. Since we want to have something unreachable. + */ + ASSERT(0 == uv_ip4_addr("192.0.2.3", TEST_PORT, &addr)); + + ASSERT(0 == uv_udp_init(uv_default_loop(), &client)); + + buf = uv_buf_init(send_data, sizeof(send_data)); + + ASSERT(0 == uv_idle_start(&idle_handle, idle_cb)); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(loop_hang_called > 1000); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-send-immediate.c b/external/src/libuv/test/test-udp-send-immediate.c new file mode 100644 index 0000000..a1c95d3 --- /dev/null +++ b/external/src/libuv/test/test-udp-send-immediate.c @@ -0,0 +1,148 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) + +static uv_udp_t server; +static uv_udp_t client; + +static int cl_send_cb_called; +static int sv_recv_cb_called; +static int close_cb_called; + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + CHECK_HANDLE(handle); + ASSERT(suggested_size <= sizeof(slab)); + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void close_cb(uv_handle_t* handle) { + CHECK_HANDLE(handle); + ASSERT(1 == uv_is_closing(handle)); + close_cb_called++; +} + + +static void cl_send_cb(uv_udp_send_t* req, int status) { + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + CHECK_HANDLE(req->handle); + + cl_send_cb_called++; +} + + +static void sv_recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* rcvbuf, + const struct sockaddr* addr, + unsigned flags) { + if (nread < 0) { + ASSERT(0 && "unexpected error"); + } + + if (nread == 0) { + /* Returning unused buffer. Don't count towards sv_recv_cb_called */ + ASSERT_NULL(addr); + return; + } + + CHECK_HANDLE(handle); + ASSERT(flags == 0); + + ASSERT_NOT_NULL(addr); + ASSERT(nread == 4); + ASSERT(memcmp("PING", rcvbuf->base, nread) == 0 || + memcmp("PANG", rcvbuf->base, nread) == 0); + + if (++sv_recv_cb_called == 2) { + uv_close((uv_handle_t*) &server, close_cb); + uv_close((uv_handle_t*) &client, close_cb); + } +} + + +TEST_IMPL(udp_send_immediate) { + struct sockaddr_in addr; + uv_udp_send_t req1, req2; + uv_buf_t buf; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + r = uv_udp_init(uv_default_loop(), &server); + ASSERT(r == 0); + + r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_udp_recv_start(&server, alloc_cb, sv_recv_cb); + ASSERT(r == 0); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_udp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + /* client sends "PING", then "PANG" */ + buf = uv_buf_init("PING", 4); + + r = uv_udp_send(&req1, + &client, + &buf, + 1, + (const struct sockaddr*) &addr, + cl_send_cb); + ASSERT(r == 0); + + buf = uv_buf_init("PANG", 4); + + r = uv_udp_send(&req2, + &client, + &buf, + 1, + (const struct sockaddr*) &addr, + cl_send_cb); + ASSERT(r == 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(cl_send_cb_called == 2); + ASSERT(sv_recv_cb_called == 2); + ASSERT(close_cb_called == 2); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-send-unreachable.c b/external/src/libuv/test/test-udp-send-unreachable.c new file mode 100644 index 0000000..c67a23b --- /dev/null +++ b/external/src/libuv/test/test-udp-send-unreachable.c @@ -0,0 +1,201 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &client || (uv_udp_t*)(handle) == &client2) + +static uv_udp_t client; +static uv_udp_t client2; +static uv_timer_t timer; + +static int send_cb_called; +static int recv_cb_called; +static int close_cb_called; +static int alloc_cb_called; +static int timer_cb_called; +static int can_recverr; + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + CHECK_HANDLE(handle); + ASSERT_LE(suggested_size, sizeof(slab)); + buf->base = slab; + buf->len = sizeof(slab); + alloc_cb_called++; +} + + +static void close_cb(uv_handle_t* handle) { + ASSERT_EQ(1, uv_is_closing(handle)); + close_cb_called++; +} + + +static void send_cb(uv_udp_send_t* req, int status) { + ASSERT_NOT_NULL(req); + ASSERT(status == 0); + ASSERT_EQ(status, 0); + CHECK_HANDLE(req->handle); + send_cb_called++; +} + +static void send_cb_recverr(uv_udp_send_t* req, int status) { + ASSERT_PTR_NE(req, NULL); + ASSERT(status == 0 || status == UV_ECONNREFUSED); + CHECK_HANDLE(req->handle); + send_cb_called++; +} + +static void recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* rcvbuf, + const struct sockaddr* addr, + unsigned flags) { + CHECK_HANDLE(handle); + recv_cb_called++; + + if (nread < 0) { + ASSERT(0 && "unexpected error"); + } else if (nread == 0) { + /* Returning unused buffer */ + ASSERT_NULL(addr); + } else { + ASSERT_NOT_NULL(addr); + } +} + + +static void timer_cb(uv_timer_t* h) { + ASSERT_PTR_EQ(h, &timer); + timer_cb_called++; + uv_close((uv_handle_t*) &client, close_cb); + if (can_recverr) + uv_close((uv_handle_t*) &client2, close_cb); + uv_close((uv_handle_t*) h, close_cb); +} + + +TEST_IMPL(udp_send_unreachable) { + struct sockaddr_in addr; + struct sockaddr_in addr2; + struct sockaddr_in addr3; + uv_udp_send_t req1, req2, req3, req4; + uv_buf_t buf; + int r; + +#ifdef __linux__ + can_recverr = 1; +#endif + + ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT_2, &addr2)); + ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT_3, &addr3)); + + r = uv_timer_init( uv_default_loop(), &timer ); + ASSERT_EQ(r, 0); + + r = uv_timer_start( &timer, timer_cb, 1000, 0 ); + ASSERT_EQ(r, 0); + + r = uv_udp_init(uv_default_loop(), &client); + ASSERT_EQ(r, 0); + + r = uv_udp_bind(&client, (const struct sockaddr*) &addr2, 0); + ASSERT_EQ(r, 0); + + r = uv_udp_recv_start(&client, alloc_cb, recv_cb); + ASSERT_EQ(r, 0); + + /* client sends "PING", then "PANG" */ + buf = uv_buf_init("PING", 4); + + r = uv_udp_send(&req1, + &client, + &buf, + 1, + (const struct sockaddr*) &addr, + send_cb); + ASSERT_EQ(r, 0); + + buf = uv_buf_init("PANG", 4); + + r = uv_udp_send(&req2, + &client, + &buf, + 1, + (const struct sockaddr*) &addr, + send_cb); + ASSERT_EQ(r, 0); + + if (can_recverr) { + r = uv_udp_init(uv_default_loop(), &client2); + ASSERT_EQ(r, 0); + + r = uv_udp_bind(&client2, + (const struct sockaddr*) &addr3, + UV_UDP_LINUX_RECVERR); + ASSERT_EQ(r, 0); + + r = uv_udp_recv_start(&client2, alloc_cb, recv_cb); + ASSERT_EQ(r, 0); + + /* client sends "PING", then "PANG" */ + buf = uv_buf_init("PING", 4); + + r = uv_udp_send(&req3, + &client2, + &buf, + 1, + (const struct sockaddr*) &addr, + send_cb_recverr); + ASSERT_EQ(r, 0); + + buf = uv_buf_init("PANG", 4); + + r = uv_udp_send(&req4, + &client2, + &buf, + 1, + (const struct sockaddr*) &addr, + send_cb_recverr); + ASSERT_EQ(r, 0); + } + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT_EQ(send_cb_called, (long)(can_recverr ? 4 : 2)); + ASSERT_EQ(recv_cb_called, alloc_cb_called); + ASSERT_EQ(timer_cb_called, 1); + ASSERT_EQ(close_cb_called, (long)(can_recverr ? 3 : 2)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-sendmmsg-error.c b/external/src/libuv/test/test-udp-sendmmsg-error.c new file mode 100644 index 0000000..c8a411b --- /dev/null +++ b/external/src/libuv/test/test-udp-sendmmsg-error.c @@ -0,0 +1,75 @@ +/* Copyright libuv project and contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +#define DATAGRAMS 6 + +static uv_udp_t client; +static uv_udp_send_t req[DATAGRAMS]; + +static int send_cb_called; +static int close_cb_called; + + +static void close_cb(uv_handle_t* handle) { + ASSERT_PTR_EQ(handle, &client); + ASSERT(uv_is_closing(handle)); + close_cb_called++; +} + + +static void send_cb(uv_udp_send_t* req, int status) { + if (status != 0) + ASSERT_EQ(status, UV_ECONNREFUSED); + + if (++send_cb_called == DATAGRAMS) + uv_close((uv_handle_t*)&client, close_cb); +} + + +TEST_IMPL(udp_sendmmsg_error) { + struct sockaddr_in addr; + uv_buf_t buf; + int i; + + ASSERT_EQ(0, uv_udp_init(uv_default_loop(), &client)); + ASSERT_EQ(0, uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + ASSERT_EQ(0, uv_udp_connect(&client, (const struct sockaddr*)&addr)); + + buf = uv_buf_init("TEST", 4); + for (i = 0; i < DATAGRAMS; ++i) + ASSERT_EQ(0, uv_udp_send(&req[i], &client, &buf, 1, NULL, send_cb)); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT_EQ(1, close_cb_called); + ASSERT_EQ(DATAGRAMS, send_cb_called); + + ASSERT_EQ(0, client.send_queue_size); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-udp-try-send.c b/external/src/libuv/test/test-udp-try-send.c new file mode 100644 index 0000000..85caaac --- /dev/null +++ b/external/src/libuv/test/test-udp-try-send.c @@ -0,0 +1,121 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include +#include + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) + +static uv_udp_t server; +static uv_udp_t client; + +static int sv_recv_cb_called; + +static int close_cb_called; + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + CHECK_HANDLE(handle); + ASSERT(suggested_size <= sizeof(slab)); + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void close_cb(uv_handle_t* handle) { + CHECK_HANDLE(handle); + ASSERT(uv_is_closing(handle)); + close_cb_called++; +} + + +static void sv_recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* rcvbuf, + const struct sockaddr* addr, + unsigned flags) { + ASSERT(nread > 0); + + if (nread == 0) { + ASSERT_NULL(addr); + return; + } + + ASSERT(nread == 4); + ASSERT_NOT_NULL(addr); + + ASSERT(memcmp("EXIT", rcvbuf->base, nread) == 0); + uv_close((uv_handle_t*) handle, close_cb); + uv_close((uv_handle_t*) &client, close_cb); + + sv_recv_cb_called++; +} + + +TEST_IMPL(udp_try_send) { + struct sockaddr_in addr; + static char buffer[64 * 1024]; + uv_buf_t buf; + int r; + + ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr)); + + r = uv_udp_init(uv_default_loop(), &server); + ASSERT(r == 0); + + r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0); + ASSERT(r == 0); + + r = uv_udp_recv_start(&server, alloc_cb, sv_recv_cb); + ASSERT(r == 0); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + + r = uv_udp_init(uv_default_loop(), &client); + ASSERT(r == 0); + + buf = uv_buf_init(buffer, sizeof(buffer)); + r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &addr); + ASSERT(r == UV_EMSGSIZE); + + buf = uv_buf_init("EXIT", 4); + r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &addr); + ASSERT(r == 4); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT(close_cb_called == 2); + ASSERT(sv_recv_cb_called == 1); + + ASSERT(client.send_queue_size == 0); + ASSERT(server.send_queue_size == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-uname.c b/external/src/libuv/test/test-uname.c new file mode 100644 index 0000000..105a17f --- /dev/null +++ b/external/src/libuv/test/test-uname.c @@ -0,0 +1,69 @@ +/* Copyright libuv project contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" +#include + +#ifndef _WIN32 +# include +#endif + +TEST_IMPL(uname) { +#ifndef _WIN32 + struct utsname buf; +#endif +#ifdef _AIX + char temp[256]; +#endif + uv_utsname_t buffer; + int r; + + /* Verify that NULL is handled properly. */ + r = uv_os_uname(NULL); + ASSERT(r == UV_EINVAL); + + /* Verify the happy path. */ + r = uv_os_uname(&buffer); + ASSERT(r == 0); + +#ifndef _WIN32 + ASSERT(uname(&buf) != -1); + ASSERT(strcmp(buffer.sysname, buf.sysname) == 0); + ASSERT(strcmp(buffer.version, buf.version) == 0); + +# ifdef _AIX + snprintf(temp, sizeof(temp), "%s.%s", buf.version, buf.release); + ASSERT(strcmp(buffer.release, temp) == 0); +# else + ASSERT(strcmp(buffer.release, buf.release) == 0); +# endif /* _AIX */ + +# if defined(_AIX) || defined(__PASE__) + ASSERT(strcmp(buffer.machine, "ppc64") == 0); +# else + ASSERT(strcmp(buffer.machine, buf.machine) == 0); +# endif /* defined(_AIX) || defined(__PASE__) */ + +#endif /* _WIN32 */ + + return 0; +} diff --git a/external/src/libuv/test/test-walk-handles.c b/external/src/libuv/test/test-walk-handles.c new file mode 100644 index 0000000..4b0ca6e --- /dev/null +++ b/external/src/libuv/test/test-walk-handles.c @@ -0,0 +1,77 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +static char magic_cookie[] = "magic cookie"; +static int seen_timer_handle; +static uv_timer_t timer; + + +static void walk_cb(uv_handle_t* handle, void* arg) { + ASSERT(arg == (void*)magic_cookie); + + if (handle == (uv_handle_t*)&timer) { + seen_timer_handle++; + } else { + ASSERT(0 && "unexpected handle"); + } +} + + +static void timer_cb(uv_timer_t* handle) { + ASSERT(handle == &timer); + + uv_walk(handle->loop, walk_cb, magic_cookie); + uv_close((uv_handle_t*)handle, NULL); +} + + +TEST_IMPL(walk_handles) { + uv_loop_t* loop; + int r; + + loop = uv_default_loop(); + + r = uv_timer_init(loop, &timer); + ASSERT(r == 0); + + r = uv_timer_start(&timer, timer_cb, 1, 0); + ASSERT(r == 0); + + /* Start event loop, expect to see the timer handle in walk_cb. */ + ASSERT(seen_timer_handle == 0); + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + ASSERT(seen_timer_handle == 1); + + /* Loop is finished, walk_cb should not see our timer handle. */ + seen_timer_handle = 0; + uv_walk(loop, walk_cb, magic_cookie); + ASSERT(seen_timer_handle == 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/test/test-watcher-cross-stop.c b/external/src/libuv/test/test-watcher-cross-stop.c new file mode 100644 index 0000000..b26deb8 --- /dev/null +++ b/external/src/libuv/test/test-watcher-cross-stop.c @@ -0,0 +1,112 @@ +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "task.h" + +#include +#include + +/* NOTE: Number should be big enough to trigger this problem */ +#if defined(__CYGWIN__) || defined(__MSYS__) || defined(__PASE__) +/* Cygwin crashes or hangs in socket() with too many AF_INET sockets. */ +/* IBMi PASE timeout with too many AF_INET sockets. */ +static uv_udp_t sockets[1250]; +#else +static uv_udp_t sockets[2500]; +#endif +static uv_udp_send_t reqs[ARRAY_SIZE(sockets)]; +static char slab[1]; +static unsigned int recv_cb_called; +static unsigned int send_cb_called; +static unsigned int close_cb_called; + +static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) { + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* buf, + const struct sockaddr* addr, + unsigned flags) { + recv_cb_called++; +} + + +static void send_cb(uv_udp_send_t* req, int status) { + send_cb_called++; +} + + +static void close_cb(uv_handle_t* handle) { + close_cb_called++; +} + + +TEST_IMPL(watcher_cross_stop) { +#if defined(__MVS__) + RETURN_SKIP("zOS does not allow address or port reuse when using UDP sockets"); +#endif + uv_loop_t* loop = uv_default_loop(); + unsigned int i; + struct sockaddr_in addr; + uv_buf_t buf; + char big_string[1024]; + + TEST_FILE_LIMIT(ARRAY_SIZE(sockets) + 32); + + ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr)); + memset(big_string, 'A', sizeof(big_string)); + buf = uv_buf_init(big_string, sizeof(big_string)); + + for (i = 0; i < ARRAY_SIZE(sockets); i++) { + ASSERT(0 == uv_udp_init(loop, &sockets[i])); + ASSERT(0 == uv_udp_bind(&sockets[i], + (const struct sockaddr*) &addr, + UV_UDP_REUSEADDR)); + ASSERT(0 == uv_udp_recv_start(&sockets[i], alloc_cb, recv_cb)); + ASSERT(0 == uv_udp_send(&reqs[i], + &sockets[i], + &buf, + 1, + (const struct sockaddr*) &addr, + send_cb)); + } + + while (recv_cb_called == 0) + uv_run(loop, UV_RUN_ONCE); + + for (i = 0; i < ARRAY_SIZE(sockets); i++) + uv_close((uv_handle_t*) &sockets[i], close_cb); + + ASSERT(recv_cb_called > 0); + + uv_run(loop, UV_RUN_DEFAULT); + + ASSERT(ARRAY_SIZE(sockets) == send_cb_called); + ASSERT(ARRAY_SIZE(sockets) == close_cb_called); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/external/src/libuv/tools/make_dist_html.py b/external/src/libuv/tools/make_dist_html.py new file mode 100644 index 0000000..4833b1b --- /dev/null +++ b/external/src/libuv/tools/make_dist_html.py @@ -0,0 +1,122 @@ +#!/usr/bin/python3 + +import itertools +import os +import re +import subprocess + +HTML = r''' + + + + + + + + + {groups}
+ + +''' + +GROUPS = r''' + + {groups[0]} + {groups[1]} + {groups[2]} + {groups[3]} + +''' + +GROUP = r''' + + + + + + + + {rows} +
versiontarballgpgwindows
+''' + +ROW = r''' + + + {tag} + + + tarball + + {maybe_gpg} + {maybe_exe} + +''' + +GPG = r''' +gpg +''' + +# The binaries don't have a predictable name, link to the directory instead. +EXE = r''' +exe +''' + +def version(tag): + return list(map(int, re.match('^v(\d+)\.(\d+)\.(\d+)', tag).groups())) + +def major_minor(tag): + return version(tag)[:2] + +def row_for(tag): + maybe_gpg = '' + maybe_exe = '' + # We didn't start signing releases and producing Windows installers + # until v1.7.0. + if version(tag) >= version('v1.7.0'): + maybe_gpg = GPG.format(**locals()) + maybe_exe = EXE.format(**locals()) + return ROW.format(**locals()) + +def group_for(tags): + rows = ''.join(row_for(tag) for tag in tags) + return GROUP.format(rows=rows) + +# Partition in groups of |n|. +def groups_for(groups, n=4): + html = '' + groups = groups[:] + [''] * (n - 1) + while len(groups) >= n: + html += GROUPS.format(groups=groups) + groups = groups[n:] + return html + +if __name__ == '__main__': + os.chdir(os.path.dirname(__file__)) + tags = subprocess.check_output(['git', 'tag'], text=True) + tags = [tag for tag in tags.split('\n') if tag.startswith('v')] + tags.sort(key=version, reverse=True) + groups = [group_for(list(g)) for _, g in itertools.groupby(tags, major_minor)] + groups = groups_for(groups) + html = HTML.format(groups=groups).strip() + html = re.sub('>\\s+<', '><', html) + print(html) diff --git a/external/src/libuv/tools/vswhere_usability_wrapper.cmd b/external/src/libuv/tools/vswhere_usability_wrapper.cmd new file mode 100644 index 0000000..ee0549c --- /dev/null +++ b/external/src/libuv/tools/vswhere_usability_wrapper.cmd @@ -0,0 +1,33 @@ +:: Copyright 2017 - Refael Ackermann +:: Distributed under MIT style license or the libuv license +:: See accompanying file LICENSE at https://github.com/node4good/windows-autoconf +:: or libuv LICENSE file at https://github.com/libuv/libuv +:: version: 2.0.0 + +@if not defined DEBUG_HELPER @ECHO OFF +setlocal +if "%~1"=="prerelease" set VSWHERE_WITH_PRERELEASE=1 +set "InstallerPath=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer" +if not exist "%InstallerPath%" set "InstallerPath=%ProgramFiles%\Microsoft Visual Studio\Installer" +if not exist "%InstallerPath%" goto :no-vswhere +:: Manipulate %Path% for easier " handeling +set "Path=%Path%;%InstallerPath%" +where vswhere 2> nul > nul +if errorlevel 1 goto :no-vswhere +set VSWHERE_REQ=-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 +set VSWHERE_PRP=-property installationPath +set VSWHERE_LMT=-version "[15.0,16.0)" +vswhere -prerelease > nul +if not errorlevel 1 if "%VSWHERE_WITH_PRERELEASE%"=="1" set "VSWHERE_LMT=%VSWHERE_LMT% -prerelease" +SET VSWHERE_ARGS=-latest -products * %VSWHERE_REQ% %VSWHERE_PRP% %VSWHERE_LMT% +for /f "usebackq tokens=*" %%i in (`vswhere %VSWHERE_ARGS%`) do ( + endlocal + set "VCINSTALLDIR=%%i\VC\" + set "VS150COMNTOOLS=%%i\Common7\Tools\" + exit /B 0 +) + +:no-vswhere +endlocal +echo could not find "vswhere" +exit /B 1 \ No newline at end of file diff --git a/external/src/libuv/uv_win_longpath.manifest b/external/src/libuv/uv_win_longpath.manifest new file mode 100644 index 0000000..8976e6d --- /dev/null +++ b/external/src/libuv/uv_win_longpath.manifest @@ -0,0 +1,8 @@ + + + + + true + + + diff --git a/external/src/libzmq/.clang-format b/external/src/libzmq/.clang-format new file mode 100644 index 0000000..0fc6f89 --- /dev/null +++ b/external/src/libzmq/.clang-format @@ -0,0 +1,53 @@ +BasedOnStyle: LLVM +IndentWidth: 4 +UseTab: Never +BreakBeforeBraces: Custom +BraceWrapping: + AfterClass: true + AfterControlStatement: false + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: false + IndentBraces: false + +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AllowShortIfStatementsOnASingleLine: false +IndentCaseLabels: true +BinPackArguments: true +BinPackParameters: false +AlignTrailingComments: true +AllowShortBlocksOnASingleLine: false +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortFunctionsOnASingleLine: InlineOnly +AlwaysBreakTemplateDeclarations: false +ColumnLimit: 80 +MaxEmptyLinesToKeep: 2 +KeepEmptyLinesAtTheStartOfBlocks: false +ContinuationIndentWidth: 2 +PointerAlignment: Right +ReflowComments: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: Always +SpaceInEmptyParentheses: false +SpacesInAngles: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp03 + +SortIncludes: false + +FixNamespaceComments: false +BreakBeforeBinaryOperators: NonAssignment +SpaceAfterTemplateKeyword: true +AlignAfterOpenBracket: Align +AlignOperands: true +BreakConstructorInitializers: AfterColon +ConstructorInitializerAllOnOneLineOrOnePerLine: true +SpaceAfterCStyleCast: true +BreakBeforeTernaryOperators: true diff --git a/external/src/libzmq/.clang-tidy b/external/src/libzmq/.clang-tidy new file mode 100644 index 0000000..32c6ca4 --- /dev/null +++ b/external/src/libzmq/.clang-tidy @@ -0,0 +1,429 @@ +Checks: "*,\ +# not currently a coding convention, but conceivable,\ +-llvm-include-order,\ +# currently the coding convention deliberately produces violations of these,\ +# rules, but it may make sense to reconsider,\ +-readability-implicit-bool-conversion,\ +-readability-braces-around-statements,\ +-readability-named-parameter,\ +-fuchsia-default-arguments,\ +-google-readability-todo,\ +-google-runtime-int,\ +-cppcoreguidelines-avoid-goto,\ +-hicpp-avoid-goto, \ +-cppcoreguidelines-pro-type-member-init,\ +-cppcoreguidelines-pro-type-static-cast-downcast,\ +-readability-identifier-naming,\ +# not applicable,\ +-fuchsia-default-arguments-calls,\ +-fuchsia-overloaded-operator,\ +-fuchsia-statically-constructed-objects,\ +# not currently a coding convention, C++11-specific, but conceivable,\ +-modernize-use-nullptr,\ +-modernize-use-equals-default,\ +-modernize-deprecated-headers,\ +# not currently a coding convention, C++11-specific and hard to implement,\ +-hicpp-no-malloc,\ +-hicpp-avoid-c-arrays,\ +-modernize-avoid-c-arrays,\ +-modernize-pass-by-value,\ +-modernize-loop-convert,\ +-modernize-use-auto,\ +-modernize-use-trailing-return-type,\ +-modernize-use-using,\ +-modernize-return-braced-init-list,\ +-cppcoreguidelines-avoid-c-arrays,\ +-cppcoreguidelines-no-malloc,\ +-cppcoreguidelines-owning-memory,\ +-cppcoreguidelines-pro-type-union-access,\ +-cppcoreguidelines-pro-bounds-array-to-pointer-decay,\ +-cppcoreguidelines-pro-bounds-constant-array-index,\ +-cppcoreguidelines-pro-bounds-pointer-arithmetic,\ +# not easily possible to implement (maybe replace by specific exclusions),\ +-cppcoreguidelines-pro-type-vararg,\ +-cppcoreguidelines-pro-type-reinterpret-cast,\ +-hicpp-signed-bitwise,\ +# duplicates,\ +-google-readability-braces-around-statements,\ +-cppcoreguidelines-pro-type-cstyle-cast,\ +-cppcoreguidelines-avoid-magic-numbers,\ +-readability-magic-numbers,\ +-hicpp-braces-around-statements,\ +-hicpp-use-equals-default,\ +-hicpp-deprecated-headers,\ +-hicpp-no-assembler,\ +-hicpp-vararg,\ +-hicpp-use-auto,\ +-hicpp-use-nullptr,\ +-hicpp-no-array-decay,\ +-hicpp-member-init" +WarningsAsErrors: '' +HeaderFilterRegex: '' +# AnalyzeTemporaryDtors: false +CheckOptions: + # - key: cert-dcl59-cpp.HeaderFileExtensions + # value: h,hh,hpp,hxx + # - key: cert-err61-cpp.CheckThrowTemporaries + # value: '1' + # - key: cert-oop11-cpp.IncludeStyle + # value: llvm + # - key: cert-oop11-cpp.UseCERTSemantics + # value: '1' + # - key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader + # value: '' + # - key: cppcoreguidelines-pro-bounds-constant-array-index.IncludeStyle + # value: '0' + # - key: cppcoreguidelines-pro-type-member-init.IgnoreArrays + # value: '0' + # - key: google-build-namespaces.HeaderFileExtensions + # value: h,hh,hpp,hxx + # - key: google-global-names-in-headers.HeaderFileExtensions + # value: h + # - key: google-readability-braces-around-statements.ShortStatementLines + # value: '1' + # - key: google-readability-function-size.BranchThreshold + # value: '4294967295' + # - key: google-readability-function-size.LineThreshold + # value: '4294967295' + # - key: google-readability-function-size.StatementThreshold + # value: '800' + # - key: google-readability-namespace-comments.ShortNamespaceLines + # value: '10' + # - key: google-readability-namespace-comments.SpacesBeforeComments + # value: '2' + # - key: google-runtime-int.SignedTypePrefix + # value: int + # - key: google-runtime-int.TypeSuffix + # value: '' + # - key: google-runtime-int.UnsignedTypePrefix + # value: uint + # - key: llvm-namespace-comment.ShortNamespaceLines + # value: '1' + # - key: llvm-namespace-comment.SpacesBeforeComments + # value: '1' + # - key: misc-assert-side-effect.AssertMacros + # value: assert + # - key: misc-assert-side-effect.CheckFunctionCalls + # value: '0' + # - key: misc-dangling-handle.HandleClasses + # value: 'std::basic_string_view;std::experimental::basic_string_view' + # - key: misc-definitions-in-headers.HeaderFileExtensions + # value: ',h,hh,hpp,hxx' + # - key: misc-definitions-in-headers.UseHeaderFileExtension + # value: '1' + # - key: misc-misplaced-widening-cast.CheckImplicitCasts + # value: '1' + # - key: misc-move-constructor-init.IncludeStyle + # value: llvm + # - key: misc-move-constructor-init.UseCERTSemantics + # value: '0' + # - key: misc-sizeof-expression.WarnOnSizeOfCompareToConstant + # value: '1' + # - key: misc-sizeof-expression.WarnOnSizeOfConstant + # value: '1' + # - key: misc-sizeof-expression.WarnOnSizeOfThis + # value: '1' + # - key: misc-string-constructor.LargeLengthThreshold + # value: '8388608' + # - key: misc-string-constructor.WarnOnLargeLength + # value: '1' + # - key: misc-suspicious-missing-comma.MaxConcatenatedTokens + # value: '5' + # - key: misc-suspicious-missing-comma.RatioThreshold + # value: '0.200000' + # - key: misc-suspicious-missing-comma.SizeThreshold + # value: '5' + # - key: misc-suspicious-string-compare.StringCompareLikeFunctions + # value: '' + # - key: misc-suspicious-string-compare.WarnOnImplicitComparison + # value: '1' + # - key: misc-suspicious-string-compare.WarnOnLogicalNotComparison + # value: '0' + # - key: misc-throw-by-value-catch-by-reference.CheckThrowTemporaries + # value: '1' + # - key: modernize-loop-convert.MaxCopySize + # value: '16' + # - key: modernize-loop-convert.MinConfidence + # value: reasonable + # - key: modernize-loop-convert.NamingStyle + # value: CamelCase + # - key: modernize-pass-by-value.IncludeStyle + # value: llvm + # - key: modernize-replace-auto-ptr.IncludeStyle + # value: llvm + # - key: modernize-use-nullptr.NullMacros + # value: 'NULL' + # - key: performance-faster-string-find.StringLikeClasses + # value: 'std::basic_string' + # - key: performance-for-range-copy.WarnOnAllAutoCopies + # value: '0' + # - key: readability-braces-around-statements.ShortStatementLines + # value: '1' + # - key: readability-function-size.BranchThreshold + # value: '4294967295' + # - key: readability-function-size.LineThreshold + # value: '4294967295' + # - key: readability-function-size.StatementThreshold + # value: '800' + # - key: readability-identifier-naming.AbstractClassCase + # value: aNy_CasE + # - key: readability-identifier-naming.AbstractClassPrefix + # value: '' + # - key: readability-identifier-naming.AbstractClassSuffix + # value: '' + # - key: readability-identifier-naming.ClassCase + # value: aNy_CasE + # - key: readability-identifier-naming.ClassConstantCase + # value: aNy_CasE + # - key: readability-identifier-naming.ClassConstantPrefix + # value: '' + # - key: readability-identifier-naming.ClassConstantSuffix + # value: '' + # - key: readability-identifier-naming.ClassMemberCase + # value: aNy_CasE + # - key: readability-identifier-naming.ClassMemberPrefix + # value: '' + # - key: readability-identifier-naming.ClassMemberSuffix + # value: '' + # - key: readability-identifier-naming.ClassMethodCase + # value: aNy_CasE + # - key: readability-identifier-naming.ClassMethodPrefix + # value: '' + # - key: readability-identifier-naming.ClassMethodSuffix + # value: '' + # - key: readability-identifier-naming.ClassPrefix + # value: '' + # - key: readability-identifier-naming.ClassSuffix + # value: '' + # - key: readability-identifier-naming.ConstantCase + # value: aNy_CasE + # - key: readability-identifier-naming.ConstantMemberCase + # value: aNy_CasE + # - key: readability-identifier-naming.ConstantMemberPrefix + # value: '' + # - key: readability-identifier-naming.ConstantMemberSuffix + # value: '' + # - key: readability-identifier-naming.ConstantParameterCase + # value: aNy_CasE + # - key: readability-identifier-naming.ConstantParameterPrefix + # value: '' + # - key: readability-identifier-naming.ConstantParameterSuffix + # value: '' + # - key: readability-identifier-naming.ConstantPrefix + # value: '' + # - key: readability-identifier-naming.ConstantSuffix + # value: '' + # - key: readability-identifier-naming.ConstexprFunctionCase + # value: aNy_CasE + # - key: readability-identifier-naming.ConstexprFunctionPrefix + # value: '' + # - key: readability-identifier-naming.ConstexprFunctionSuffix + # value: '' + # - key: readability-identifier-naming.ConstexprMethodCase + # value: aNy_CasE + # - key: readability-identifier-naming.ConstexprMethodPrefix + # value: '' + # - key: readability-identifier-naming.ConstexprMethodSuffix + # value: '' + # - key: readability-identifier-naming.ConstexprVariableCase + # value: aNy_CasE + # - key: readability-identifier-naming.ConstexprVariablePrefix + # value: '' + # - key: readability-identifier-naming.ConstexprVariableSuffix + # value: '' + # - key: readability-identifier-naming.EnumCase + # value: aNy_CasE + # - key: readability-identifier-naming.EnumConstantCase + # value: aNy_CasE + # - key: readability-identifier-naming.EnumConstantPrefix + # value: '' + # - key: readability-identifier-naming.EnumConstantSuffix + # value: '' + # - key: readability-identifier-naming.EnumPrefix + # value: '' + # - key: readability-identifier-naming.EnumSuffix + # value: '' + # - key: readability-identifier-naming.FunctionCase + # value: aNy_CasE + # - key: readability-identifier-naming.FunctionPrefix + # value: '' + # - key: readability-identifier-naming.FunctionSuffix + # value: '' + # - key: readability-identifier-naming.GlobalConstantCase + # value: aNy_CasE + # - key: readability-identifier-naming.GlobalConstantPrefix + # value: '' + # - key: readability-identifier-naming.GlobalConstantSuffix + # value: '' + # - key: readability-identifier-naming.GlobalFunctionCase + # value: aNy_CasE + # - key: readability-identifier-naming.GlobalFunctionPrefix + # value: '' + # - key: readability-identifier-naming.GlobalFunctionSuffix + # value: '' + # - key: readability-identifier-naming.GlobalVariableCase + # value: aNy_CasE + # - key: readability-identifier-naming.GlobalVariablePrefix + # value: '' + # - key: readability-identifier-naming.GlobalVariableSuffix + # value: '' + # - key: readability-identifier-naming.IgnoreFailedSplit + # value: '0' + # - key: readability-identifier-naming.InlineNamespaceCase + # value: aNy_CasE + # - key: readability-identifier-naming.InlineNamespacePrefix + # value: '' + # - key: readability-identifier-naming.InlineNamespaceSuffix + # value: '' + - key: readability-identifier-naming.LocalConstantCase + value: lower_case + - key: readability-identifier-naming.LocalConstantPrefix + value: '' + - key: readability-identifier-naming.LocalConstantSuffix + value: '' + - key: readability-identifier-naming.LocalVariableCase + value: lower_case + - key: readability-identifier-naming.LocalVariablePrefix + value: '' + - key: readability-identifier-naming.LocalVariableSuffix + value: '' + # - key: readability-identifier-naming.MemberCase + # value: lower_case + # - key: readability-identifier-naming.MemberPrefix + # value: '_' + # - key: readability-identifier-naming.MemberSuffix + # value: '' + # - key: readability-identifier-naming.MethodCase + # value: aNy_CasE + # - key: readability-identifier-naming.MethodPrefix + # value: '' + # - key: readability-identifier-naming.MethodSuffix + # value: '' + # - key: readability-identifier-naming.NamespaceCase + # value: aNy_CasE + # - key: readability-identifier-naming.NamespacePrefix + # value: '' + # - key: readability-identifier-naming.NamespaceSuffix + # value: '' + - key: readability-identifier-naming.ParameterCase + value: lower_case + # - key: readability-identifier-naming.ParameterPackCase + # value: aNy_CasE + # - key: readability-identifier-naming.ParameterPackPrefix + # value: '' + # - key: readability-identifier-naming.ParameterPackSuffix + # value: '' + # - key: readability-identifier-naming.ParameterPrefix + # value: '' + - key: readability-identifier-naming.ParameterSuffix + value: '_' + - key: readability-identifier-naming.PrivateMemberCase + value: lower_case + - key: readability-identifier-naming.PrivateMemberPrefix + value: '_' + - key: readability-identifier-naming.PrivateMemberSuffix + value: '' + # - key: readability-identifier-naming.PrivateMethodCase + # value: aNy_CasE + # - key: readability-identifier-naming.PrivateMethodPrefix + # value: '' + # - key: readability-identifier-naming.PrivateMethodSuffix + # value: '' + # - key: readability-identifier-naming.ProtectedMemberCase + # value: aNy_CasE + # - key: readability-identifier-naming.ProtectedMemberPrefix + # value: '' + # - key: readability-identifier-naming.ProtectedMemberSuffix + # value: '' + # - key: readability-identifier-naming.ProtectedMethodCase + # value: aNy_CasE + # - key: readability-identifier-naming.ProtectedMethodPrefix + # value: '' + # - key: readability-identifier-naming.ProtectedMethodSuffix + # value: '' + # - key: readability-identifier-naming.PublicMemberCase + # value: aNy_CasE + # - key: readability-identifier-naming.PublicMemberPrefix + # value: '' + # - key: readability-identifier-naming.PublicMemberSuffix + # value: '' + # - key: readability-identifier-naming.PublicMethodCase + # value: aNy_CasE + # - key: readability-identifier-naming.PublicMethodPrefix + # value: '' + # - key: readability-identifier-naming.PublicMethodSuffix + # value: '' + # - key: readability-identifier-naming.StaticConstantCase + # value: aNy_CasE + # - key: readability-identifier-naming.StaticConstantPrefix + # value: '' + # - key: readability-identifier-naming.StaticConstantSuffix + # value: '' + # - key: readability-identifier-naming.StaticVariableCase + # value: aNy_CasE + # - key: readability-identifier-naming.StaticVariablePrefix + # value: '' + # - key: readability-identifier-naming.StaticVariableSuffix + # value: '' + # - key: readability-identifier-naming.StructCase + # value: aNy_CasE + # - key: readability-identifier-naming.StructPrefix + # value: '' + # - key: readability-identifier-naming.StructSuffix + # value: '' + # - key: readability-identifier-naming.TemplateParameterCase + # value: aNy_CasE + # - key: readability-identifier-naming.TemplateParameterPrefix + # value: '' + # - key: readability-identifier-naming.TemplateParameterSuffix + # value: '' + # - key: readability-identifier-naming.TemplateTemplateParameterCase + # value: aNy_CasE + # - key: readability-identifier-naming.TemplateTemplateParameterPrefix + # value: '' + # - key: readability-identifier-naming.TemplateTemplateParameterSuffix + # value: '' + # - key: readability-identifier-naming.TypeTemplateParameterCase + # value: aNy_CasE + # - key: readability-identifier-naming.TypeTemplateParameterPrefix + # value: '' + # - key: readability-identifier-naming.TypeTemplateParameterSuffix + # value: '' + # - key: readability-identifier-naming.TypedefCase + # value: aNy_CasE + # - key: readability-identifier-naming.TypedefPrefix + # value: '' + # - key: readability-identifier-naming.TypedefSuffix + # value: '' + # - key: readability-identifier-naming.UnionCase + # value: aNy_CasE + # - key: readability-identifier-naming.UnionPrefix + # value: '' + # - key: readability-identifier-naming.UnionSuffix + # value: '' + # - key: readability-identifier-naming.ValueTemplateParameterCase + # value: aNy_CasE + # - key: readability-identifier-naming.ValueTemplateParameterPrefix + # value: '' + # - key: readability-identifier-naming.ValueTemplateParameterSuffix + # value: '' + # - key: readability-identifier-naming.VariableCase + # value: aNy_CasE + # - key: readability-identifier-naming.VariablePrefix + # value: '' + # - key: readability-identifier-naming.VariableSuffix + # value: '' + # - key: readability-identifier-naming.VirtualMethodCase + # value: aNy_CasE + # - key: readability-identifier-naming.VirtualMethodPrefix + # value: '' + # - key: readability-identifier-naming.VirtualMethodSuffix + # value: '' + # - key: readability-simplify-boolean-expr.ChainedConditionalAssignment + # value: '0' + # - key: readability-simplify-boolean-expr.ChainedConditionalReturn + # value: '0' + - key: modernize-use-override.OverrideSpelling + value: 'ZMQ_OVERRIDE' + - key: modernize-use-override.FinalSpelling + value: 'ZMQ_FINAL' diff --git a/external/src/libzmq/.git-blame-ignore-revs b/external/src/libzmq/.git-blame-ignore-revs new file mode 100644 index 0000000..985588c --- /dev/null +++ b/external/src/libzmq/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# tree-wide clang format +41f459e1dc6f7cdedd1268298153c970e290b2ce diff --git a/external/src/libzmq/.github/CONTRIBUTING.md b/external/src/libzmq/.github/CONTRIBUTING.md new file mode 100644 index 0000000..10bb5ab --- /dev/null +++ b/external/src/libzmq/.github/CONTRIBUTING.md @@ -0,0 +1,48 @@ +# Pull Request Notice + +Before sending a pull request make sure each commit solves one clear, minimal, +plausible problem. Further each commit should have the following format: + +``` +Problem: X is broken + +Solution: do Y and Z to fix X +``` + +Please try to have the code changes conform to our coding style. For your +convenience, you can install clang-format (at least version 5.0) and then +run ```make clang-format-check```. Don't fix existing issues, if any - just +make sure your changes are compliant. ```make clang-format-diff``` will +automatically apply the required changes. +To set a specific clang-format binary with autotools, you can for example +run: ```./configure CLANG_FORMAT=clang-format-5.0``` + +Please avoid sending a pull request with recursive merge nodes, as they +are impossible to fix once merged. Please rebase your branch on +zeromq/libzmq master instead of merging it. + +``` +git remote add upstream git@github.com:zeromq/libzmq.git +git fetch upstream +git rebase upstream/master +git push -f +``` + +In case you already merged instead of rebasing you can drop the merge commit. + +``` +git rebase -i HEAD~10 +``` + +Now, find your merge commit and mark it as drop and save. Finally rebase! + +If you are a new contributor please have a look at our contributing guidelines: +[CONTRIBUTING](http://zeromq.org/docs:contributing) + +# FIRST TIME CONTRIBUTORS PLEASE NOTE + +Please add an additional commit with a relicensing grant. + +[Example](https://github.com/zeromq/libzmq/commit/fecbd42dbe45455fff3b6456350ceca047b82050) + +[More information on RELICENSING effort](https://github.com/zeromq/libzmq/tree/master/RELICENSE/README.md) diff --git a/external/src/libzmq/.github/issue_template.md b/external/src/libzmq/.github/issue_template.md new file mode 100644 index 0000000..21b837a --- /dev/null +++ b/external/src/libzmq/.github/issue_template.md @@ -0,0 +1,22 @@ +*Please use this template for reporting suspected bugs or requests for help.* + +# Issue description + + + +# Environment + +* libzmq version (commit hash if unreleased): +* OS: + +# Minimal test code / Steps to reproduce the issue + +1. + + +# What's the actual result? (include assertion message & call stack if applicable) + + + +# What's the expected result? + diff --git a/external/src/libzmq/.github/stale.yml b/external/src/libzmq/.github/stale.yml new file mode 100644 index 0000000..a06b57d --- /dev/null +++ b/external/src/libzmq/.github/stale.yml @@ -0,0 +1,19 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 365 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 56 +# Issues with these labels will never be considered stale +exemptLabels: + - "Help Request" + - "Feature Request" + - "Problem reproduced" + - Critical +# Label to use when marking an issue as stale +staleLabel: stale +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + activity for 365 days. It will be closed if no further activity occurs within + 56 days. Thank you for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false diff --git a/external/src/libzmq/.github/workflows/CI.yaml b/external/src/libzmq/.github/workflows/CI.yaml new file mode 100644 index 0000000..758e6ab --- /dev/null +++ b/external/src/libzmq/.github/workflows/CI.yaml @@ -0,0 +1,93 @@ +name: CI +on: [push, pull_request] + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - platform: x64 + configuration: release + os: windows-2019 + WITH_LIBSODIUM: ON + ENABLE_CURVE: ON + CMAKE_GENERATOR: Visual Studio 16 2019 + MSVCVERSION: v142 + MSVCYEAR: vs2019 + ARTIFACT_NAME: v142-x64 + ENABLE_DRAFTS: ON + # - platform: Win32 + # configuration: Release + # os: windows-2016 + # WITH_LIBSODIUM: ON + # ENABLE_CURVE: ON + # CMAKE_GENERATOR: "Visual Studio 15 2017" + # MSVCVERSION: "v141" + # MSVCYEAR: "vs2017" + # ARTIFACT_NAME: v141 + # ENABLE_DRAFTS: ON + - platform: x64 + configuration: Release + os: windows-2016 + WITH_LIBSODIUM: ON + ENABLE_CURVE: ON + CMAKE_GENERATOR: "Visual Studio 15 2017 Win64" + MSVCVERSION: "v141" + MSVCYEAR: "vs2017" + ARTIFACT_NAME: v141-x64 + ENABLE_DRAFTS: ON + env: + platform: ${{ matrix.platform }} + configuration: ${{ matrix.configuration }} + WITH_LIBSODIUM: ${{ matrix.WITH_LIBSODIUM }} + ENABLE_CURVE: ${{ matrix.ENABLE_CURVE }} + CMAKE_GENERATOR: ${{ matrix.CMAKE_GENERATOR }} + MSVCVERSION: ${{ matrix.MSVCVERSION }} + MSVCYEAR: ${{ matrix.MSVCYEAR }} + ARTIFACT_NAME: ${{ matrix.ARTIFACT_NAME }} + ENABLE_DRAFTS: ${{ matrix.ENABLE_DRAFTS }} + SODIUM_INCLUDE_DIR: ${{ github.workspace }}\libsodium\src\libsodium\include" + SODIUM_LIBRARY_DIR: ${{ github.workspace }}\libsodium\bin\${{ matrix.platform }}\${{ matrix.configuration }}\${{ matrix.MSVCVERSION }}\dynamic" + LIBZMQ_SRCDIR: ${{ github.workspace }}\libzmq + steps: + - name: Add msbuild to PATH + uses: microsoft/setup-msbuild@v1.0.2 + if: matrix.os == 'windows-2019' + - name: Add msbuild to PATH 2016 + uses: microsoft/setup-msbuild@v1.0.2 + with: + vs-version: '[15.0,16.0)' + if: matrix.os == 'windows-2016' + - uses: actions/checkout@v2 + if: matrix.WITH_LIBSODIUM == 'ON' + with: + repository: jedisct1/libsodium + ref: stable + path: libsodium + - name: Compile libsodium + if: matrix.WITH_LIBSODIUM == 'ON' + shell: cmd + working-directory: libsodium + run: msbuild /v:minimal /p:Configuration=%Configuration%DLL builds\msvc\%MSVCYEAR%\libsodium\libsodium.vcxproj + - name: Copy libsodium + if: matrix.WITH_LIBSODIUM == 'ON' + shell: powershell + working-directory: libsodium + run: Copy-Item "bin\${env:Platform}\${env:Configuration}\${env:MSVCVERSION}\dynamic\libsodium.lib" -Destination "bin\${env:Platform}\${env:Configuration}\${env:MSVCVERSION}\dynamic\sodium.lib" + - uses: actions/checkout@v2 + with: + path: libzmq + - run: md build_libzmq + shell: cmd + - name: build + shell: cmd + working-directory: build_libzmq + run: | + cmake -D CMAKE_INCLUDE_PATH="%SODIUM_INCLUDE_DIR%" -D CMAKE_LIBRARY_PATH="%SODIUM_LIBRARY_DIR%" -D WITH_LIBSODIUM="%WITH_LIBSODIUM%" -D ENABLE_DRAFTS="%ENABLE_DRAFTS%" -D ENABLE_ANALYSIS="%ENABLE_ANALYSIS%" -D ENABLE_CURVE="%ENABLE_CURVE%" -D API_POLLER="%API_POLLER%" -D POLLER="%POLLER%" %EXTRA_FLAGS% -D WITH_LIBSODIUM="%WITH_LIBSODIUM%" -D LIBZMQ_WERROR="%LIBZMQ_WERROR%" -G "%CMAKE_GENERATOR%" "%LIBZMQ_SRCDIR%" + cmake --build . --config %configuration% --target install -- -verbosity:Minimal -maxcpucount + - name: test + shell: cmd + working-directory: build_libzmq + run: ctest -C "%Configuration%" diff --git a/external/src/libzmq/.github/workflows/Fuzzers.yaml b/external/src/libzmq/.github/workflows/Fuzzers.yaml new file mode 100644 index 0000000..e8ae6b5 --- /dev/null +++ b/external/src/libzmq/.github/workflows/Fuzzers.yaml @@ -0,0 +1,35 @@ +name: Fuzzers +on: + push: + branches: + - master + pull_request: + paths: + - '.github/workflows/Fuzzers.yaml' + - 'src/*' + - 'tests/*fuzzer.cpp' +jobs: + Fuzzing: + runs-on: ubuntu-latest + if: github.repository == 'zeromq/libzmq' + strategy: + matrix: + san: [address, memory, undefined] + steps: + - name: Build Fuzzers (${{ matrix.san }}) + id: build + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + sanitizer: ${{ matrix.san }} + oss-fuzz-project-name: 'libzmq' + allowed-broken-targets-percentage: 0 + dry-run: false + - name: Run Fuzzers (${{ matrix.san }}) + id: run + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + sanitizer: ${{ matrix.san }} + oss-fuzz-project-name: 'libzmq' + allowed-broken-targets-percentage: 0 + dry-run: false + fuzz-seconds: 300 diff --git a/external/src/libzmq/.gitignore b/external/src/libzmq/.gitignore new file mode 100644 index 0000000..6170b15 --- /dev/null +++ b/external/src/libzmq/.gitignore @@ -0,0 +1,127 @@ +syntax: glob # for hg-git users + +# Generated build scripts and IDE generating files +## autotools +/Makefile +builds/Makefile +builds/deprecated-msvc/Makefile +doc/Makefile +libtool +### automake +Makefile.in +.deps/ +.dirstamp +### autoconf +autom4te.cache +aclocal.m4 +config +config.status +config.log +configure +stamp-h1 +## CMake +cmake-build-debug/ +build/ +## Android +builds/android/prefix +## IntelliJ +.idea/ +## Visual Code +.vscode/ +## other results-like folders +bin/ +lib/ +obj/ +## Doxygen +doxygen/ +## Packaging +packaging/nuget/*.nupkg + +# Test related build files +libtestutil.a +libunity.a + +# Some build outputs and temporal files +*.o +*.gcno +*.gcda +*.gcov +*.ncb +*.lo +*.loT +*.la +*.exe +*.html +*.pdf +*.ps +*~ +.*~ +.libs + +# /src +## Ignore generated files in configuration process +src/platform.hpp* +src/libzmq.pc + +# /tools +## Executable binaries are ignored +tools/curve_keygen +## Executable source files must be tracked +!tools/*.[ch] +!tools/*.[ch]pp + +# /tests +## Test binaries and logs are ignored +tests/test* +tests/test*.log +tests/test*.trs +## Test source files must be tracked +!tests/test*.[ch] +!tests/test*.[ch]pp +## Build script and documentations must be tracked +!tests/CMakeLists.txt +!tests/README.md + +# /unittests +## Unit test binaries and logs are ignored +unittests/unittest_* +unittests/unittest*.log +unittests/unittest*.trs +## Unit test source files must be tracked +!unittests/unittest*.[ch] +!unittests/unittest*.[ch]pp +## Build script and documentations must be tracked +!unittests/CMakeLists.txt +!unittests/README.md + +# check test log files +test-suite*.log + +# /perf +## Benchmarking binaries and result files are ignored +perf/*_lat +perf/*_thr +perf/benchmark_* +perf/results +## Benchmarking source files must be tracked +!perf/*.[ch] +!perf/*.[ch]pp +## Benchmarking tool scripts must be tracked +!perf/*.py +!perf/*.sh + +# /doc +## Generated document files +doc/*.[137] +doc/*.html +doc/*.xml + +# external libraries and release archive files +foreign/openpgm/* +!foreign/openpgm/*.tar.bz2 +!foreign/openpgm/*.tar.gz +!foreign/openpgm/Makefile.am +zeromq-*.tar.gz +zeromq-*.zip +core + diff --git a/external/src/libzmq/.hgeol b/external/src/libzmq/.hgeol new file mode 100644 index 0000000..a484af6 --- /dev/null +++ b/external/src/libzmq/.hgeol @@ -0,0 +1,2 @@ +[patterns] +** = native diff --git a/external/src/libzmq/.mailmap b/external/src/libzmq/.mailmap new file mode 100644 index 0000000..77e75fa --- /dev/null +++ b/external/src/libzmq/.mailmap @@ -0,0 +1,81 @@ +Ahmet Kakici ahmet +Andrey Sibiryov Kobolog +Brian Knox taotetek +Chernyshev Vyacheslav Astellar +Chris Laws Chris Laws +Chris Staite Chris +Christoph Zach czach +Chuck Remes Chuck Remes +Chuck Remes Chuck Remes +Constantin Rack Constantin Rack +Constantin Rack Constantin Rack +Daniel Krikun danielkr +Daiyu Hurst DaiyuHurst +Diego Rodriguez-Losada Diego +Dongmin Yu Min(Dongmin Yu) +Doron Somech somdoron +Elliot Saba staticfloat +Eric Voskuil evoskuil +Eric Voskuil anonymous +Felipe Farinon psl-felipefarinon +Frank Hartmann Frank +Gian Lorenzo Meocci meox +Hardeep Singh Hardeep +Henrik Feldt Henrik +Huang Xin chrox +Ian Barber Ian Barber +Jens Auer Jens Auer +Jens Auer Jens Auer +Joe Eli McIlvain Joe McIlvain +Jos Decoster jdc8 +Jos Decoster Jos Decoster +Joshua Gao Josh Gao +Jörg Kreuzberger kreuzberger +Arnaud Kapp Kapp Arnaud +Arnaud Kapp KAPP Arnaud +Arnaud Kapp KAPP Arnaud +Kenneth Wilke KennethWilke +Kevin Sapper sappo +Kevin Sapper Kevin Sapper +Leonard Michelet leonarf +Martijn Jasperse mjasperse +Martin Hurton Martin Hurtoň +Martin Lucina Martin Lucina +Martin Sustrik Martin Sustrik +Martin Sustrik Martin Sustrik +Martin Sustrik sustrik +Martin Sustrik Martin Sustrik +Martin Sustrik unknown +Martin Sustrik Martin Sustrik +Maurice Barnum maurice barnum +Maurizio Melato unknown +Max Skaller skaller +Michael Fox <415fox@gmail.com> m <415fox@gmail.com> +Michael Hand Mipa +Michel Zou xantares +Mikael Helbo Kjaer Mikael Helbo Kjær +Mike Gatny Mike Gatny +Mikko Koppanen Mikko Koppanen +Mikko Koppanen Mikko Koppanen +Mikko Koppanen Mikko Koppanen +Min RK MinRK +Min RK Min Ragan-Kelley +Montoya Edu montoyaedu +Nikita Kozlov nikita kozlov +Pavol Malosek malosek +Pieter Hintjens Pieter Hintjens +Reza Ebrahimi reza.ebrahimi +Ricardo Catalinas Jiménez Ricardo Catalinas Jiménez +Rohan Bedarkar rohanbedarkar +Rohan Bedarkar Rohan +Sergey KHripchenko root +Sergey KHripchenko shripchenko +Sergey M. Sergey M․ +Steven McCoy Steve-o +Tamara Kustarova tamara +Timothee Besset Timothee "TTimo" Besset +Timothy Mossbarger Tim M +Trevor Bernard Trevor Bernard +Trevor Bernard Trevor Bernard +Volodymyr Korniichuk Volodymyr Korniichuk <9173519@gmail.com> +lysyloren lysyloren diff --git a/external/src/libzmq/.obs/workflows.yml b/external/src/libzmq/.obs/workflows.yml new file mode 100644 index 0000000..821ba5b --- /dev/null +++ b/external/src/libzmq/.obs/workflows.yml @@ -0,0 +1,5 @@ +workflow: + steps: + - branch_package: + source_project: network:messaging:zeromq:git-draft + source_package: libzmq diff --git a/external/src/libzmq/.travis.yml b/external/src/libzmq/.travis.yml new file mode 100644 index 0000000..0112723 --- /dev/null +++ b/external/src/libzmq/.travis.yml @@ -0,0 +1,203 @@ +# Travis CI script + +language: c + +os: +- linux +- osx + +dist: bionic + +cache: ccache + +env: + matrix: + - BUILD_TYPE=default CURVE=tweetnacl DRAFT=enabled + - BUILD_TYPE=cmake CURVE=tweetnacl + - BUILD_TYPE=default + # tokens to deploy releases on OBS and create/delete temporary branch on Github. + # 1) Create a token on https://github.com/settings/tokens/new with "public_repo" + # capability and encrypt it with travis encrypt --org -r zeromq/libzmq GH_TOKEN="" + # 2) Create 2 OBS tokens with osc token --create network:messaging:zeromq:release- libzmq + # encrypt them with travis encrypt --org -r zeromq/libzmq OBS__TOKEN="" + global: + - secure: aaIs9Y44FYp9VFCqa6LLD4illBH4aUfbS0zzzbAQ5xJvD6NfBsMiKEIhf/kRNCHAtP+1VfQVOejTD6/i08ALsVr3cZD9oB/t7874tz2/jeZUIhRNo+1KwyaVqNg0yUSV6ASIoq4aOfuGnjBlezNQ8LQ2bjQB2m4Enl5wxoYcYdA= + - secure: YFrcedBIKe0NR1WC6qQi9phZgtnzOiBIXm40TirvCtstV4eVnSouKgtQfLLArZ4o2tjflq4grQQNo1rJatvyi5YPOXsMcndsni18S+4Ffu8qbECdtPrK52vBweuf7q9oV9Ydax0Fm4bEqEMOZ2/mRBy3nK+mgsE3upeMwyWR0Zw= + - secure: lbZSzmqN39QdJwewKOZgq/1ijPKuyx9MFrGzMqXj2+eOSlaZS/tNavHMdKJOev+qJGK9wxmwzxOxS10AiH+AvN7WBacXX4ZtudjScz2HKJRDWTKyzMbzyScq51afniItzrsm+Vo8NHkenNFkux0sSbh0aHlpkLwrGQu+WZWcDN4= + - secure: "ZFL7hLJlGwYix8fF835OnQYakBt/o5iS7IfSW7el44ejEvGAOM9O5/ufxCcqSqn8Np7nOaM3RriAVTqWPZD6S7tMeflGTSGYHPYwWUc83z4rUPyG2FWVKXdB8ufpebAwu3hCgLiSmVeoQG47dl6xNk1oKCd+3UIjgz33u1Ecfps=" + +matrix: + include: + - if: type = cron OR (branch =~ analyze$ AND type = push) + env: BUILD_TYPE=cmake CLANG_TIDY=/usr/bin/clang-tidy-10 CC=clang-10 CXX=clang++-10 + os: linux + compiler: clang + addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-10 + packages: + - clang-10 + - clang-tools-10 + - clang-tidy-10 + - env: BUILD_TYPE=default CURVE=tweetnacl IPv6=ON + os: linux + dist: precise + - env: BUILD_TYPE=coverage CURVE=tweetnacl GSSAPI=enabled PGM=enabled NORM=enabled TIPC=enabled IPv6=ON TLS=enabled DRAFT=enabled + os: linux + addons: + apt: + sources: + - sourceline: 'deb http://download.opensuse.org/repositories/network:/messaging:/zeromq:/git-stable/xUbuntu_18.04/ ./' + key_url: 'http://download.opensuse.org/repositories/network:/messaging:/zeromq:/git-stable/xUbuntu_18.04/Release.key' + packages: + - libkrb5-dev + - libnorm-dev + - libpgm-dev + - libgnutls28-dev + - lcov + - env: BUILD_TYPE=valgrind CURVE=tweetnacl DRAFT=enabled TLS=enabled + os: linux + dist: xenial + addons: + apt: + packages: + - valgrind + - libgnutls-dev + - env: BUILD_TYPE=default CURVE=libsodium GSSAPI=enabled PGM=enabled NORM=enabled VMCI=enabled + os: linux + addons: + apt: + sources: + - sourceline: 'deb http://download.opensuse.org/repositories/network:/messaging:/zeromq:/git-stable/xUbuntu_14.04/ ./' + key_url: 'http://download.opensuse.org/repositories/network:/messaging:/zeromq:/git-stable/xUbuntu_14.04/Release.key' + packages: + - libkrb5-dev + - libnorm-dev + - libpgm-dev + - libsodium-dev + - asciidoc + - xmlto + - env: BUILD_TYPE=default DRAFT=enabled TLS=enabled + os: linux + dist: xenial + addons: + apt: + packages: + - libgnutls-dev + - env: BUILD_TYPE=default CURVE=libsodium DRAFT=enabled GSSAPI=enabled PGM=enabled NORM=enabled TIPC=enabled USE_NSS=yes + os: linux + addons: + apt: + sources: + - sourceline: 'deb http://download.opensuse.org/repositories/network:/messaging:/zeromq:/git-stable/xUbuntu_14.04/ ./' + key_url: 'http://download.opensuse.org/repositories/network:/messaging:/zeromq:/git-stable/xUbuntu_14.04/Release.key' + packages: + - libkrb5-dev + - libnorm-dev + - libpgm-dev + - libsodium-dev + - libnss3-dev + - libbsd-dev + - env: BUILD_TYPE=default CURVE=libsodium DRAFT=enabled + os: osx + addons: + homebrew: + packages: + - libsodium + - env: BUILD_TYPE=default CURVE=libsodium DRAFT=enabled ADDRESS_SANITIZER=enabled + os: linux + addons: + apt: + packages: + - libsodium-dev + - env: BUILD_TYPE=android CURVE=tweetnacl + os: linux + dist: trusty + - env: BUILD_TYPE=cmake DO_CLANG_FORMAT_CHECK=1 CLANG_FORMAT=/usr/lib/llvm-8/bin/clang-format + os: linux + addons: + apt: + packages: + - clang-format-8 + - env: BUILD_TYPE=default POLLER=poll + os: linux + - env: BUILD_TYPE=default POLLER=select + os: linux + - env: CXX=clang++ BUILD_TYPE=default CURVE=libsodium GSSAPI=enabled PGM=enabled NORM=enabled FORCE_98=enabled + os: linux + compiler: clang + addons: + apt: + sources: + - sourceline: 'deb http://download.opensuse.org/repositories/network:/messaging:/zeromq:/git-stable/xUbuntu_14.04/ ./' + key_url: 'http://download.opensuse.org/repositories/network:/messaging:/zeromq:/git-stable/xUbuntu_14.04/Release.key' + packages: + - libkrb5-dev + - libnorm-dev + - libpgm-dev + - libsodium-dev + - env: BUILD_TYPE=abi-compliance-checker + os: linux + dist: xenial + addons: + apt: + packages: + - abi-dumper + - abi-compliance-checker + - name: Linux ARM64 + env: BUILD_TYPE=default CURVE=tweetnacl GSSAPI=enabled PGM=enabled NORM=enabled IPv6=ON TLS=enabled DRAFT=enabled + os: linux + dist: bionic + arch: arm64 + addons: + apt: + sources: + - sourceline: 'deb http://download.opensuse.org/repositories/network:/messaging:/zeromq:/git-stable/xUbuntu_18.04/ ./' + key_url: 'http://download.opensuse.org/repositories/network:/messaging:/zeromq:/git-stable/xUbuntu_18.04/Release.key' + packages: + - zip + - libkrb5-dev + - libnorm-dev + - libpgm-dev + - libgnutls28-dev + allow_failures: + - arch: arm64 + +before_install: +# To allow sonar to process history information, unshallow clone first. +- if [ -n "$CLANG_TIDY" ] ; then + git fetch --unshallow ; + curl -L https://sonarcloud.io/static/cpp/build-wrapper-linux-x86.zip -o build-wrapper-linux-x86.zip ; + unzip build-wrapper-linux-x86.zip ; + export SONARCLOUD_BUILD_WRAPPER_PATH="$(pwd)/build-wrapper-linux-x86/" ; + curl -L https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.2.0.1873-linux.zip -o sonar-scanner-cli.zip ; + unzip sonar-scanner-cli.zip ; + export SONAR_SCANNER_CLI_PATH="$(pwd)/sonar-scanner-4.2.0.1873-linux/bin/" ; + fi + +before_script: +# ZMQ stress tests need more open socket (files) than the usual default +# On OSX, it seems the way to set the max files limit is constantly changing, so +# try to use all known knobs to ensure compatibility across various versions +- if [ $TRAVIS_OS_NAME == "osx" ] ; then sudo sysctl -w kern.maxfiles=64000 ; sudo sysctl -w kern.maxfilesperproc=64000 ; sudo launchctl limit maxfiles 64000 64000 ; ulimit -n 64000; fi + +# Build and check this project according to the BUILD_TYPE +script: ./ci_build.sh + +# Deploy tags +before_deploy: +- . ./ci_deploy.sh +deploy: + provider: releases + api_key: + secure: vGB5E+A8wxm2J1GJZzmIgT9PrjEzvd9gE8iui8FyxSbxAsW9vFZFGZC/21sTtpVcmRarwQCHH1UEbtg+nJwN2iD9YzMRnSVks8xqP+b709YW+VXaMuhZgTzWa74IorQku7NuvLibvQk72/OSgdwPGaNJ6f5AX9pnWVWbEoW1svE= + file_glob: true + file: ${LIBZMQ_DEPLOYMENT} + skip_cleanup: true + on: + repo: zeromq/libzmq + branch: master + tags: true + condition: "$TRAVIS_OS_NAME =~ (linux) && $BUILD_TYPE =~ (default) && $CURVE =~ (libsodium) && -z $DRAFT" diff --git a/external/src/libzmq/AUTHORS b/external/src/libzmq/AUTHORS new file mode 100644 index 0000000..42b865f --- /dev/null +++ b/external/src/libzmq/AUTHORS @@ -0,0 +1,152 @@ +Corporate Contributors +====================== + +Copyright (c) 2007-2014 iMatix Corporation +Copyright (c) 2009-2011 250bpm s.r.o. +Copyright (c) 2010-2011 Miru Limited +Copyright (c) 2011 VMware, Inc. +Copyright (c) 2012 Spotify AB +Copyright (c) 2013 Ericsson AB +Copyright (c) 2014 AppDynamics Inc. +Copyright (c) 2015 Google, Inc. +Copyright (c) 2015-2016 Brocade Communications Systems Inc. + +Individual Contributors +======================= + +AJ Lewis +Alexej Lotz +Andrew Thompson +André Caron +Asko Kauppi +Attila Mark +Barak Amar +Ben Gray +Bernd Melchers +Bernd Prager +Bob Beaty +Brandon Carpenter +Brett Cameron +Brian Buchanan +Burak Arslan +Carl Clemens +Chia-liang Kao +Chris Busbey +Chris Rempel +Chris Wong +Christian Gudrian +Christian Kamm +Chuck Remes +Conrad D. Steenberg +Constantin Rack +Daniel J. Bernstein +Dhammika Pathirana +Dhruva Krishnamurthy +Dirk O. Kaar +Doron Somech +Douglas Creager +Drew Crawford +Erich Heine +Erik Hugne +Erik Rigtorp +Fabien Ninoles +Frank Denis +George Neill +Gerard Toonstra +Ghislain Putois +Gonzalo Diethelm +Guido Goldstein +Harald Achitz +Hardeep Singh +Hiten Pandya +Ian Barber +Ilja Golshtein +Ilya Kulakov +Ivo Danihelka +Jacob Rideout +Joe Thornber +Jon Dyte +Kamil Shakirov +Ken Steele +Kouhei Sutou +Laurent Alebarde +Leonardo J. Consoni +Lionel Flandrin +Lourens Naudé +Luca Boccassi +Marc Rossi +Mark Barbisan +Martin Hurton +Martin Lucina +Martin Pales +Martin Sustrik +Matus Hamorsky +Max Wolf +McClain Looney +Michael Compton +Mika Fischer +Mikael Helbo Kjaer +Mike Gatny +Mikko Koppanen +Min Ragan-Kelley +Neale Ferguson +Nir Soffer +Osiris Pedroso +Paul Betts +Paul Colomiets +Pavel Gushcha +Pavol Malosek +Perry Kundert +Peter Bourgon +Philip Kovacs +Pieter Hintjens +Piotr Trojanek +Reza Ebrahimi +Richard Newton +Rik van der Heijden +Robert G. Jakabosky +Sebastian Otaegui +Stefan Radomski +Steven McCoy +Stuart Webster +Tamara Kustarova +Taras Shpot +Tero Marttila +Terry Wilson +Thijs Terlouw +Thomas Rodgers +Tim Mossbarger +Toralf Wittner +Tore Halvorsen +Trevor Bernard +Vitaly Mayatskikh + +Credits +======= + +Aamir Mohammad +Adrian von Bidder +Aleksey Yeschenko +Alessio Spadaro +Alexander Majorov +Anh Vu +Bernd Schumacher +Brian Granger +Carsten Dinkelmann +David Bahi +Dirk Eddelbuettel +Evgueny Khartchenko +Frank Vanden Berghen +Ian Barber +John Apps +Markus Fischer +Matt Muggeridge +Michael Santy +Oleg Sevostyanov +Paulo Henrique Silva +Peter Busser +Peter Lemenkov +Robert Zhang +Toralf Wittner +Zed Shaw + diff --git a/external/src/libzmq/CMakeLists.txt b/external/src/libzmq/CMakeLists.txt new file mode 100644 index 0000000..788b20d --- /dev/null +++ b/external/src/libzmq/CMakeLists.txt @@ -0,0 +1,1825 @@ +# CMake build script for ZeroMQ +project(ZeroMQ) + +if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) + cmake_minimum_required(VERSION 3.0.2) +else() + cmake_minimum_required(VERSION 2.8.12) +endif() + +include(CheckIncludeFiles) +include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) +include(CheckLibraryExists) +include(CheckCSourceCompiles) +include(CheckCSourceRuns) +include(CMakeDependentOption) +include(CheckCXXSymbolExists) +include(CheckTypeSize) +include(FindThreads) +include(GNUInstallDirs) +include(CheckTypeSize) +include(CMakePackageConfigHelpers) + +list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}") +set(ZMQ_CMAKE_MODULES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/builds/cmake/Modules) +list(APPEND CMAKE_MODULE_PATH ${ZMQ_CMAKE_MODULES_DIR}) + +include(TestZMQVersion) +include(ZMQSourceRunChecks) +include(ZMQSupportMacros) + +find_package(PkgConfig) + +# Set lists to empty beforehand as to not accidentally take values from parent +set(sources) +set(cxx-sources) +set(html-docs) +set(target_outputs) + +option(ENABLE_ASAN "Build with address sanitizer" OFF) +if(ENABLE_ASAN) + message(STATUS "Instrumenting with Address Sanitizer") + set(CMAKE_BUILD_TYPE "RelWithDebInfo") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -fsanitize-address-use-after-scope -fno-omit-frame-pointer") + set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize-address-use-after-scope -fno-omit-frame-pointer") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=address -fsanitize-address-use-after-scope") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address -fsanitize-address-use-after-scope") +endif() + +# NOTE: Running libzmq under TSAN doesn't make much sense -- synchronization in libzmq is to some extent +# handled by the code "knowing" what threads are allowed to do, rather than by enforcing those +# restrictions, so TSAN generates a lot of (presumably) false positives from libzmq. +# The settings below are intended to enable libzmq to be built with minimal support for TSAN +# such that it can be used along with other code that is also built with TSAN. +option(ENABLE_TSAN "Build with thread sanitizer" OFF) +if(ENABLE_TSAN) + message(STATUS "Instrumenting with Thread Sanitizer") + set(CMAKE_BUILD_TYPE "RelWithDebInfo") + set(TSAN_FLAGS "-fno-omit-frame-pointer -fsanitize=thread") + set(TSAN_CCFLAGS "${TSAN_CCFLAGS} -mllvm -tsan-instrument-memory-accesses=0") + set(TSAN_CCFLAGS "${TSAN_CCFLAGS} -mllvm -tsan-instrument-atomics=0") + set(TSAN_CCFLAGS "${TSAN_CCFLAGS} -mllvm -tsan-instrument-func-entry-exit=1") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TSAN_FLAGS} ${TSAN_CCFLAGS} -fPIE") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TSAN_FLAGS} ${TSAN_CCFLAGS} -fPIE") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${TSAN_FLAGS} -pie -Qunused-arguments") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${TSAN_FLAGS} -pie -Qunused-arguments") +endif() + +option(ENABLE_UBSAN "Build with undefined behavior sanitizer" OFF) +if(ENABLE_UBSAN) + message(STATUS "Instrumenting with Undefined Behavior Sanitizer") + set(CMAKE_BUILD_TYPE "Debug") + set(UBSAN_FLAGS "${UBSAN_FLAGS} -fno-omit-frame-pointer") + set(UBSAN_FLAGS "${UBSAN_FLAGS} -fsanitize=undefined") + set(UBSAN_FLAGS "${UBSAN_FLAGS} -fsanitize=implicit-conversion") + set(UBSAN_FLAGS "${UBSAN_FLAGS} -fsanitize=implicit-integer-truncation") + set(UBSAN_FLAGS "${UBSAN_FLAGS} -fsanitize=integer") + set(UBSAN_FLAGS "${UBSAN_FLAGS} -fsanitize=nullability") + set(UBSAN_FLAGS "${UBSAN_FLAGS} -fsanitize=vptr") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${UBSAN_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${UBSAN_FLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${UBSAN_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${UBSAN_FLAGS}") +endif() + +option(ENABLE_INTRINSICS "Build using compiler intrinsics for atomic ops" OFF) +if(ENABLE_INTRINSICS) + message(STATUS "Using compiler intrinsics for atomic ops") + add_definitions(-DZMQ_HAVE_ATOMIC_INTRINSICS) +endif() + +set(ZMQ_OUTPUT_BASENAME + "zmq" + CACHE STRING "Output zmq library base name") + +if(${CMAKE_SYSTEM_NAME} STREQUAL Darwin) + # Find more information: https://cmake.org/Wiki/CMake_RPATH_handling + + # Apply CMP0042: MACOSX_RPATH is enabled by default + cmake_policy(SET CMP0042 NEW) + + # Add an install rpath if it is not a system directory + list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" isSystemDir) + if("${isSystemDir}" STREQUAL "-1") + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") + endif() + + # Add linker search paths pointing to external dependencies + set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) +endif() + +if (NOT MSVC) + if(NOT CMAKE_CXX_FLAGS MATCHES "-std=") + # use C++11 by default if supported + check_cxx_compiler_flag("-std=c++11" COMPILER_SUPPORTS_CXX11) + if(COMPILER_SUPPORTS_CXX11) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") + endif() + endif() + if(NOT CMAKE_C_FLAGS MATCHES "-std=") + check_c_compiler_flag("-std=c11" COMPILER_SUPPORTS_C11) + if(COMPILER_SUPPORTS_C11) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") + else() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") + endif() + endif() + + # clang 6 has a warning that does not make sense on multi-platform code + check_cxx_compiler_flag("-Wno-tautological-constant-compare" CXX_HAS_TAUT_WARNING) + if(CXX_HAS_TAUT_WARNING) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-tautological-constant-compare") + endif() + check_c_compiler_flag("-Wno-tautological-constant-compare" CC_HAS_TAUT_WARNING) + if(CC_HAS_TAUT_WARNING) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-tautological-constant-compare") + endif() +endif() + +# Will be used to add flags to pkg-config useful when apps want to statically link +set(pkg_config_libs_private "") +set(pkg_config_names_private "") + +option(WITH_OPENPGM "Build with support for OpenPGM" OFF) +option(WITH_NORM "Build with support for NORM" OFF) +option(WITH_VMCI "Build with support for VMware VMCI socket" OFF) + +if(APPLE) + option(ZMQ_BUILD_FRAMEWORK "Build as OS X framework" OFF) +endif() + +if(EXISTS "${CMAKE_SOURCE_DIR}/.git") + option(ENABLE_DRAFTS "Build and install draft classes and methods" ON) +else() + option(ENABLE_DRAFTS "Build and install draft classes and methods" OFF) +endif() + +# Enable WebSocket transport and RadixTree +if(ENABLE_DRAFTS) + message(STATUS "Building draft classes and methods") + set(ZMQ_BUILD_DRAFT_API 1) + option(ENABLE_WS "Enable WebSocket transport" ON) + option(ENABLE_RADIX_TREE "Use radix tree implementation to manage subscriptions" ON) +else() + message(STATUS "Not building draft classes and methods") + option(ENABLE_WS "Enable WebSocket transport" OFF) + option(ENABLE_RADIX_TREE "Use radix tree implementation to manage subscriptions" OFF) +endif() + +if(ENABLE_RADIX_TREE) + message(STATUS "Using radix tree implementation to manage subscriptions") + set(ZMQ_USE_RADIX_TREE 1) +endif() + +if(ENABLE_WS) + list( + APPEND + sources + ${CMAKE_CURRENT_SOURCE_DIR}/src/ws_address.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ws_connecter.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ws_decoder.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ws_encoder.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ws_engine.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ws_listener.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ws_address.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ws_connecter.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ws_decoder.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ws_encoder.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ws_engine.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ws_listener.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/ws_protocol.hpp) + set(ZMQ_HAVE_WS 1) + + message(STATUS "Enable WebSocket transport") + + option(WITH_TLS "Use TLS for WSS support" ON) + option(WITH_NSS "Use NSS instead of builtin sha1" OFF) + + if(WITH_TLS) + find_package("GnuTLS" 3.6.7) + if(GNUTLS_FOUND) + set(pkg_config_names_private "${pkg_config_names_private} gnutls") + list(APPEND sources ${CMAKE_CURRENT_SOURCE_DIR}/src/wss_address.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/wss_address.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/wss_engine.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/wss_engine.cpp) + + message(STATUS "Enable WSS transport") + set(ZMQ_USE_GNUTLS 1) + set(ZMQ_HAVE_WSS 1) + else() + message(WARNING "No WSS support, you may want to install GnuTLS and run cmake again") + endif() + endif() +endif() + +if(NOT ZMQ_USE_GNUTLS) + if(WITH_NSS) + pkg_check_modules(NSS3 "nss") + if(NSS3_FOUND) + set(pkg_config_names_private "${pkg_config_names_private} nss") + message(STATUS "Using NSS") + set(ZMQ_USE_NSS 1) + else() + find_package("NSS3") + if(NSS3_FOUND) + set(pkg_config_libs_private "${pkg_config_libs_private} -lnss3") + message(STATUS "Using NSS") + set(ZMQ_USE_NSS 1) + else() + message(WARNING "No nss installed, if you don't want builtin SHA1, install NSS or GnuTLS") + endif() + endif() + endif() + if(NOT ZMQ_USE_NSS) + list(APPEND sources ${CMAKE_CURRENT_SOURCE_DIR}/external/sha1/sha1.c + ${CMAKE_CURRENT_SOURCE_DIR}/external/sha1/sha1.h) + message(STATUS "Using builtin sha1") + set(ZMQ_USE_BUILTIN_SHA1 1) + endif() +endif() + +if(NOT MSVC) + option(WITH_LIBBSD "Use libbsd instead of builtin strlcpy" ON) + if(WITH_LIBBSD) + pkg_check_modules(LIBBSD "libbsd") + if(LIBBSD_FOUND) + message(STATUS "Using libbsd") + set(pkg_config_names_private "${pkg_config_names_private} libbsd") + set(ZMQ_HAVE_LIBBSD 1) + endif() + endif() + check_cxx_symbol_exists(strlcpy string.h ZMQ_HAVE_STRLCPY) +endif() + +# Select curve encryption library, defaults to tweetnacl To use libsodium instead, use --with-libsodium(must be +# installed) To disable curve, use --disable-curve + +option(WITH_LIBSODIUM "Use libsodium instead of built-in tweetnacl" ON) +option(WITH_LIBSODIUM_STATIC "Use static libsodium library" OFF) +option(ENABLE_LIBSODIUM_RANDOMBYTES_CLOSE "Automatically close libsodium randombytes. Not threadsafe without getrandom()" ON) +option(ENABLE_CURVE "Enable CURVE security" ON) + +if(ENABLE_CURVE) + if(WITH_LIBSODIUM) + find_package("Sodium") + if(SODIUM_FOUND) + message(STATUS "Using libsodium for CURVE security") + include_directories(${SODIUM_INCLUDE_DIRS}) + if(WITH_LIBSODIUM_STATIC) + add_compile_definitions(SODIUM_STATIC) + endif() + set(ZMQ_USE_LIBSODIUM 1) + set(ZMQ_HAVE_CURVE 1) + if (ENABLE_LIBSODIUM_RANDOMBYTES_CLOSE) + set(ZMQ_LIBSODIUM_RANDOMBYTES_CLOSE 1) + endif() + else() + message( + WARNING + "libsodium not installed, instead using builtin tweetnacl, you may want to install libsodium and run cmake again" + ) + endif() + endif() + if(NOT ZMQ_HAVE_CURVE) + message(STATUS "Using tweetnacl for CURVE security") + list(APPEND sources ${CMAKE_CURRENT_SOURCE_DIR}/src/tweetnacl.c) + set(ZMQ_USE_TWEETNACL 1) + set(ZMQ_HAVE_CURVE 1) + endif() +else() + message(STATUS "CURVE security is disabled") +endif() + +set(SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + +option(WITH_MILITANT "Enable militant assertions" OFF) +if(WITH_MILITANT) + add_definitions(-DZMQ_ACT_MILITANT) +endif() + +set(API_POLLER + "" + CACHE STRING "Choose polling system for zmq_poll(er)_*. valid values are + poll or select [default=poll unless POLLER=select]") + +set(POLLER + "" + CACHE STRING "Choose polling system for I/O threads. valid values are + kqueue, epoll, devpoll, pollset, poll or select [default=autodetect]") + +if(WIN32) + if(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore" AND CMAKE_SYSTEM_VERSION MATCHES "^10.0") + set(ZMQ_HAVE_WINDOWS_UWP ON) + set(ZMQ_HAVE_IPC OFF) + # to remove compile warninging "D9002 ignoring unknown option" + string(REPLACE "/Zi" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) + set(CMAKE_CXX_FLAGS_DEBUG + ${CMAKE_CXX_FLAGS_DEBUG} + CACHE STRING "" FORCE) + string(REPLACE "/Zi" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}) + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO + ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} + CACHE STRING "" FORCE) + string(REPLACE "/Zi" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG}) + endif() + # from https://stackoverflow.com/a/40217291/2019765 + macro(get_WIN32_WINNT version) + if(CMAKE_SYSTEM_VERSION) + set(ver ${CMAKE_SYSTEM_VERSION}) + string(REGEX MATCH "^([0-9]+).([0-9])" ver ${ver}) + string(REGEX MATCH "^([0-9]+)" verMajor ${ver}) + # Check for Windows 10, b/c we'll need to convert to hex 'A'. + if("${verMajor}" MATCHES "10") + set(verMajor "A") + string(REGEX REPLACE "^([0-9]+)" ${verMajor} ver ${ver}) + endif("${verMajor}" MATCHES "10") + # Remove all remaining '.' characters. + string(REPLACE "." "" ver ${ver}) + # Prepend each digit with a zero. + string(REGEX REPLACE "([0-9A-Z])" "0\\1" ver ${ver}) + set(${version} "0x${ver}") + endif(CMAKE_SYSTEM_VERSION) + endmacro(get_WIN32_WINNT) + + get_win32_winnt(ZMQ_WIN32_WINNT_DEFAULT) + message(STATUS "Detected _WIN32_WINNT from CMAKE_SYSTEM_VERSION: ${ZMQ_WIN32_WINNT_DEFAULT}") + + # TODO limit _WIN32_WINNT to the actual Windows SDK version, which might be different from the default version + # installed with Visual Studio + if(MSVC_VERSION STREQUAL "1500" AND CMAKE_SYSTEM_VERSION VERSION_GREATER "6.0") + set(ZMQ_WIN32_WINNT_LIMIT "0x0600") + elseif(MSVC_VERSION STREQUAL "1600" AND CMAKE_SYSTEM_VERSION VERSION_GREATER "6.1") + set(ZMQ_WIN32_WINNT_LIMIT "0x0601") + elseif(MSVC_VERSION STREQUAL "1700" AND CMAKE_SYSTEM_VERSION VERSION_GREATER "6.1") + set(ZMQ_WIN32_WINNT_LIMIT "0x0601") + elseif(MSVC_VERSION STREQUAL "1800" AND CMAKE_SYSTEM_VERSION VERSION_GREATER "6.2") + set(ZMQ_WIN32_WINNT_LIMIT "0x0602") + endif() + if(ZMQ_WIN32_WINNT_LIMIT) + message( + STATUS + "Mismatch of Visual Studio Version (${MSVC_VERSION}) and CMAKE_SYSTEM_VERSION (${CMAKE_SYSTEM_VERSION}), limiting _WIN32_WINNT to ${ZMQ_WIN32_WINNT_LIMIT}, you may override this by setting ZMQ_WIN32_WINNT" + ) + set(ZMQ_WIN32_WINNT_DEFAULT "${ZMQ_WIN32_WINNT_LIMIT}") + endif() + + set(ZMQ_WIN32_WINNT + "${ZMQ_WIN32_WINNT_DEFAULT}" + CACHE STRING "Value to set _WIN32_WINNT to for building [default=autodetect from build environment]") + + # On Windows Vista or greater, with MSVC 2013 or greater, default to epoll (which is required on Win 10 for ipc + # support) + if(ZMQ_WIN32_WINNT GREATER "0x05FF" + AND MSVC_VERSION GREATER 1799 + AND POLLER STREQUAL "" + AND NOT ZMQ_HAVE_WINDOWS_UWP) + set(POLLER "epoll") + endif() + + add_definitions(-D_WIN32_WINNT=${ZMQ_WIN32_WINNT}) +endif(WIN32) + +if(NOT MSVC) + if(POLLER STREQUAL "") + check_cxx_symbol_exists(kqueue sys/event.h HAVE_KQUEUE) + if(HAVE_KQUEUE) + set(POLLER "kqueue") + endif() + endif() + + if(POLLER STREQUAL "") + check_cxx_symbol_exists(epoll_create sys/epoll.h HAVE_EPOLL) + if(HAVE_EPOLL) + set(POLLER "epoll") + check_cxx_symbol_exists(epoll_create1 sys/epoll.h HAVE_EPOLL_CLOEXEC) + if(HAVE_EPOLL_CLOEXEC) + set(ZMQ_IOTHREAD_POLLER_USE_EPOLL_CLOEXEC 1) + endif() + endif() + endif() + + if(POLLER STREQUAL "") + set(CMAKE_EXTRA_INCLUDE_FILES sys/devpoll.h) + check_type_size("struct pollfd" DEVPOLL) + set(CMAKE_EXTRA_INCLUDE_FILES) + if(HAVE_DEVPOLL) + set(POLLER "devpoll") + endif() + endif() + + if(POLLER STREQUAL "") + check_cxx_symbol_exists(pollset_create sys/pollset.h HAVE_POLLSET) + if(HAVE_POLLSET) + set(POLLER "pollset") + endif() + endif() + + if(POLLER STREQUAL "") + check_cxx_symbol_exists(poll poll.h HAVE_POLL) + if(HAVE_POLL) + set(POLLER "poll") + endif() + endif() +endif() + +if(POLLER STREQUAL "") + if(WIN32) + set(HAVE_SELECT 1) + else() + check_cxx_symbol_exists(select sys/select.h HAVE_SELECT) + endif() + if(HAVE_SELECT) + set(POLLER "select") + else() + message(FATAL_ERROR "Could not autodetect polling method") + endif() +endif() + +if(POLLER STREQUAL "kqueue" + OR POLLER STREQUAL "epoll" + OR POLLER STREQUAL "devpoll" + OR POLLER STREQUAL "pollset" + OR POLLER STREQUAL "poll" + OR POLLER STREQUAL "select") + message(STATUS "Using polling method in I/O threads: ${POLLER}") + string(TOUPPER ${POLLER} UPPER_POLLER) + set(ZMQ_IOTHREAD_POLLER_USE_${UPPER_POLLER} 1) +else() + message(FATAL_ERROR "Invalid polling method") +endif() + +if(POLLER STREQUAL "epoll" AND WIN32) + message(STATUS "Including wepoll") + list(APPEND sources ${CMAKE_CURRENT_SOURCE_DIR}/external/wepoll/wepoll.c + ${CMAKE_CURRENT_SOURCE_DIR}/external/wepoll/wepoll.h) +endif() + +if(API_POLLER STREQUAL "") + if(POLLER STREQUAL "select") + set(API_POLLER "select") + else() + set(API_POLLER "poll") + endif() +endif() + +message(STATUS "Using polling method in zmq_poll(er)_* API: ${API_POLLER}") +string(TOUPPER ${API_POLLER} UPPER_API_POLLER) +set(ZMQ_POLL_BASED_ON_${UPPER_API_POLLER} 1) + +# special alignment settings +execute_process( + COMMAND getconf LEVEL1_DCACHE_LINESIZE + OUTPUT_VARIABLE CACHELINE_SIZE + ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE) +if(CACHELINE_SIZE STREQUAL "" + OR CACHELINE_SIZE EQUAL 0 + OR CACHELINE_SIZE EQUAL -1) + set(ZMQ_CACHELINE_SIZE 64) +else() + set(ZMQ_CACHELINE_SIZE ${CACHELINE_SIZE}) +endif() +message(STATUS "Using ${ZMQ_CACHELINE_SIZE} bytes alignment for lock-free data structures") +check_cxx_symbol_exists(posix_memalign stdlib.h HAVE_POSIX_MEMALIGN) + +if(NOT CYGWIN) + # TODO cannot we simply do 'if(WIN32) set(ZMQ_HAVE_WINDOWS ON)' or similar? + check_include_files(windows.h ZMQ_HAVE_WINDOWS) +endif() + +if(NOT WIN32) + set(ZMQ_HAVE_IPC 1) +else() + check_include_files("winsock2.h;afunix.h" ZMQ_HAVE_IPC) +endif() + +# ##################### BEGIN condition_variable_t selection +if(NOT ZMQ_CV_IMPL) + # prefer C++11 STL std::condition_variable implementation, if available + check_include_files(condition_variable ZMQ_HAVE_STL_CONDITION_VARIABLE LANGUAGE CXX) + + if(ZMQ_HAVE_STL_CONDITION_VARIABLE) + set(ZMQ_CV_IMPL_DEFAULT "stl11") + else() + if(WIN32 AND NOT CMAKE_SYSTEM_VERSION VERSION_LESS "6.0") + # Win32API CONDITION_VARIABLE is supported from Windows Vista only + set(ZMQ_CV_IMPL_DEFAULT "win32api") + elseif(CMAKE_USE_PTHREADS_INIT) + set(ZMQ_CV_IMPL_DEFAULT "pthreads") + else() + set(ZMQ_CV_IMPL_DEFAULT "none") + endif() + endif() + + # TODO a vxworks implementation also exists, but vxworks is not currently supported with cmake at all + set(ZMQ_CV_IMPL + "${ZMQ_CV_IMPL_DEFAULT}" + CACHE STRING "Choose condition_variable_t implementation. Valid values are + stl11, win32api, pthreads, none [default=autodetect]") +endif() + +message(STATUS "Using condition_variable_t implementation: ${ZMQ_CV_IMPL}") +if(ZMQ_CV_IMPL STREQUAL "stl11") + set(ZMQ_USE_CV_IMPL_STL11 1) +elseif(ZMQ_CV_IMPL STREQUAL "win32api") + set(ZMQ_USE_CV_IMPL_WIN32API 1) +elseif(ZMQ_CV_IMPL STREQUAL "pthreads") + set(ZMQ_USE_CV_IMPL_PTHREADS 1) +elseif(ZMQ_CV_IMPL STREQUAL "none") + set(ZMQ_USE_CV_IMPL_NONE 1) +else() + message(ERROR "Unknown value for ZMQ_CV_IMPL: ${ZMQ_CV_IMPL}") +endif() +# ##################### END condition_variable_t selection + +if(NOT MSVC) + check_include_files(ifaddrs.h ZMQ_HAVE_IFADDRS) + check_include_files(sys/uio.h ZMQ_HAVE_UIO) + check_include_files(sys/eventfd.h ZMQ_HAVE_EVENTFD) + if(ZMQ_HAVE_EVENTFD AND NOT CMAKE_CROSSCOMPILING) + zmq_check_efd_cloexec() + endif() +endif() + +if(ZMQ_HAVE_WINDOWS) + # Cannot use check_library_exists because the symbol is always declared as char(*)(void) + set(CMAKE_REQUIRED_LIBRARIES "ws2_32.lib") + check_cxx_symbol_exists(WSAStartup "winsock2.h" HAVE_WS2_32) + + set(CMAKE_REQUIRED_LIBRARIES "rpcrt4.lib") + check_cxx_symbol_exists(UuidCreateSequential "rpc.h" HAVE_RPCRT4) + + set(CMAKE_REQUIRED_LIBRARIES "iphlpapi.lib") + check_cxx_symbol_exists(GetAdaptersAddresses "winsock2.h;iphlpapi.h" HAVE_IPHLAPI) + check_cxx_symbol_exists(if_nametoindex "iphlpapi.h" HAVE_IF_NAMETOINDEX) + + set(CMAKE_REQUIRED_LIBRARIES "") + # TODO: This not the symbol we're looking for. What is the symbol? + check_library_exists(ws2 fopen "" HAVE_WS2) +else() + check_cxx_symbol_exists(if_nametoindex net/if.h HAVE_IF_NAMETOINDEX) + check_cxx_symbol_exists(SO_PEERCRED sys/socket.h ZMQ_HAVE_SO_PEERCRED) + check_cxx_symbol_exists(LOCAL_PEERCRED sys/socket.h ZMQ_HAVE_LOCAL_PEERCRED) + check_cxx_symbol_exists(SO_BUSY_POLL sys/socket.h ZMQ_HAVE_BUSY_POLL) +endif() + +if(NOT MINGW) + find_library(RT_LIBRARY rt) + if(RT_LIBRARY) + set(pkg_config_libs_private "${pkg_config_libs_private} -lrt") + endif() +endif() + +find_package(Threads) + +if(WIN32 AND NOT CYGWIN) + if(NOT HAVE_WS2_32 AND NOT HAVE_WS2) + message(FATAL_ERROR "Cannot link to ws2_32 or ws2") + endif() + + if(NOT HAVE_RPCRT4) + message(FATAL_ERROR "Cannot link to rpcrt4") + endif() + + if(NOT HAVE_IPHLAPI) + message(FATAL_ERROR "Cannot link to iphlapi") + endif() +endif() + +if(NOT MSVC) + set(CMAKE_REQUIRED_LIBRARIES rt) + check_cxx_symbol_exists(clock_gettime time.h HAVE_CLOCK_GETTIME) + set(CMAKE_REQUIRED_LIBRARIES) + + check_cxx_symbol_exists(fork unistd.h HAVE_FORK) + check_cxx_symbol_exists(gethrtime sys/time.h HAVE_GETHRTIME) + check_cxx_symbol_exists(mkdtemp stdlib.h HAVE_MKDTEMP) + check_cxx_symbol_exists(accept4 sys/socket.h HAVE_ACCEPT4) + check_cxx_symbol_exists(strnlen string.h HAVE_STRNLEN) +else() + set(HAVE_STRNLEN 1) +endif() + +add_definitions(-D_REENTRANT -D_THREAD_SAFE) +add_definitions(-DZMQ_CUSTOM_PLATFORM_HPP) + +option(ENABLE_EVENTFD "Enable/disable eventfd" ZMQ_HAVE_EVENTFD) + +macro(zmq_check_cxx_flag_prepend flag) + check_cxx_compiler_flag("${flag}" HAVE_FLAG_${flag}) + + if(HAVE_FLAG_${flag}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") + endif() +endmacro() + +option(ENABLE_ANALYSIS "Build with static analysis(make take very long)" OFF) + +if(MSVC) + if(ENABLE_ANALYSIS) + zmq_check_cxx_flag_prepend("/W4") + + zmq_check_cxx_flag_prepend("/analyze") + + # C++11/14/17-specific, but maybe possible via conditional defines + zmq_check_cxx_flag_prepend("/wd26440") # Function '...' can be declared 'noexcept' + zmq_check_cxx_flag_prepend("/wd26432") # If you define or delete any default operation in the type '...', define or + # delete them all + zmq_check_cxx_flag_prepend("/wd26439") # This kind of function may not throw. Declare it 'noexcept' + zmq_check_cxx_flag_prepend("/wd26447") # The function is declared 'noexcept' but calls function '...' which may + # throw exceptions + zmq_check_cxx_flag_prepend("/wd26433") # Function '...' should be marked with 'override' + zmq_check_cxx_flag_prepend("/wd26409") # Avoid calling new and delete explicitly, use std::make_unique instead + # Requires GSL + zmq_check_cxx_flag_prepend("/wd26429") # Symbol '...' is never tested for nullness, it can be marked as not_null + zmq_check_cxx_flag_prepend("/wd26446") # Prefer to use gsl::at() + zmq_check_cxx_flag_prepend("/wd26481") # Don't use pointer arithmetic. Use span instead + zmq_check_cxx_flag_prepend("/wd26472") # Don't use a static_cast for arithmetic conversions. Use brace + # initialization, gsl::narrow_cast or gsl::narow + zmq_check_cxx_flag_prepend("/wd26448") # Consider using gsl::finally if final action is intended + zmq_check_cxx_flag_prepend("/wd26400") # Do not assign the result of an allocation or a function call with an + # owner return value to a raw pointer, use owner instead + zmq_check_cxx_flag_prepend("/wd26485") # Expression '...': No array to pointer decay(bounds.3) + else() + zmq_check_cxx_flag_prepend("/W3") + endif() + + if(MSVC_IDE) + set(MSVC_TOOLSET "-${CMAKE_VS_PLATFORM_TOOLSET}") + else() + set(MSVC_TOOLSET "") + endif() +else() + zmq_check_cxx_flag_prepend("-Wall") +endif() + +if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + zmq_check_cxx_flag_prepend("-Wextra") +endif() + +option(LIBZMQ_PEDANTIC "" ON) +option(LIBZMQ_WERROR "" OFF) + +# TODO: why is -Wno-long-long defined differently than in configure.ac? +if(NOT MSVC) + zmq_check_cxx_flag_prepend("-Wno-long-long") + zmq_check_cxx_flag_prepend("-Wno-uninitialized") + + if(LIBZMQ_PEDANTIC) + zmq_check_cxx_flag_prepend("-pedantic") + + if(${CMAKE_CXX_COMPILER_ID} MATCHES "Intel") + zmq_check_cxx_flag_prepend("-strict-ansi") + endif() + + if(${CMAKE_CXX_COMPILER_ID} MATCHES "SunPro") + zmq_check_cxx_flag_prepend("-compat=5") + endif() + endif() +endif() + +if(LIBZMQ_WERROR) + if(MSVC) + zmq_check_cxx_flag_prepend("/WX") + else() + zmq_check_cxx_flag_prepend("-Werror") + if(NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + zmq_check_cxx_flag_prepend("-errwarn=%all") + endif() + endif() +endif() + +if(CMAKE_SYSTEM_PROCESSOR MATCHES "^sparc") + zmq_check_cxx_flag_prepend("-mcpu=v9") +endif() + +if(${CMAKE_CXX_COMPILER_ID} MATCHES "SunPro") + zmq_check_cxx_flag_prepend("-features=zla") +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "SunOS" + OR CMAKE_SYSTEM_NAME MATCHES "NetBSD" + OR CMAKE_SYSTEM_NAME MATCHES "QNX") + message(STATUS "Checking whether atomic operations can be used") + check_c_source_compiles( + "\ + #include \ + \ + int main() \ + { \ + uint32_t value; \ + atomic_cas_32(&value, 0, 0); \ + return 0; \ + } \ + " + HAVE_ATOMIC_H) + + if(NOT HAVE_ATOMIC_H) + set(ZMQ_FORCE_MUTEXES 1) + endif() +endif() + +if(NOT ANDROID) + zmq_check_noexcept() +endif() + +# ----------------------------------------------------------------------------- +if(NOT CMAKE_CROSSCOMPILING AND NOT MSVC) + zmq_check_sock_cloexec() + zmq_check_o_cloexec() + zmq_check_so_bindtodevice() + zmq_check_so_keepalive() + zmq_check_so_priority() + zmq_check_tcp_keepcnt() + zmq_check_tcp_keepidle() + zmq_check_tcp_keepintvl() + zmq_check_tcp_keepalive() + zmq_check_tcp_tipc() + zmq_check_pthread_setname() + zmq_check_pthread_setaffinity() + zmq_check_getrandom() +endif() + +if(CMAKE_SYSTEM_NAME MATCHES "Linux" + OR CMAKE_SYSTEM_NAME MATCHES "GNU/kFreeBSD" + OR CMAKE_SYSTEM_NAME MATCHES "GNU/Hurd" + OR CYGWIN) + add_definitions(-D_GNU_SOURCE) +elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + add_definitions(-D__BSD_VISIBLE) +elseif(CMAKE_SYSTEM_NAME MATCHES "NetBSD") + add_definitions(-D_NETBSD_SOURCE) +elseif(CMAKE_SYSTEM_NAME MATCHES "OpenBSD") + add_definitions(-D_OPENBSD_SOURCE) +elseif(CMAKE_SYSTEM_NAME MATCHES "SunOS") + add_definitions(-D_PTHREADS) +elseif(CMAKE_SYSTEM_NAME MATCHES "HP-UX") + add_definitions(-D_POSIX_C_SOURCE=200112L) + zmq_check_cxx_flag_prepend(-Ae) +elseif(CMAKE_SYSTEM_NAME MATCHES "Darwin") + add_definitions(-D_DARWIN_C_SOURCE) +endif() + +find_package(AsciiDoc) + +cmake_dependent_option(WITH_DOC "Build Reference Guide documentation(requires DocBook)" ON "ASCIIDOC_FOUND;NOT WIN32" + OFF) # Do not build docs on Windows due to issues with symlinks + +if(MSVC) + if(WITH_OPENPGM) + # set(OPENPGM_ROOT "" CACHE PATH "Location of OpenPGM") + set(OPENPGM_VERSION_MAJOR 5) + set(OPENPGM_VERSION_MINOR 2) + set(OPENPGM_VERSION_MICRO 122) + if(CMAKE_CL_64) + find_path( + OPENPGM_ROOT include/pgm/pgm.h + PATHS + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Miru\\OpenPGM ${OPENPGM_VERSION_MAJOR}.${OPENPGM_VERSION_MINOR}.${OPENPGM_VERSION_MICRO}]" + NO_DEFAULT_PATH) + message(STATUS "OpenPGM x64 detected - ${OPENPGM_ROOT}") + else() + find_path( + OPENPGM_ROOT include/pgm/pgm.h + PATHS + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Miru\\OpenPGM ${OPENPGM_VERSION_MAJOR}.${OPENPGM_VERSION_MINOR}.${OPENPGM_VERSION_MICRO}]" + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Miru\\OpenPGM ${OPENPGM_VERSION_MAJOR}.${OPENPGM_VERSION_MINOR}.${OPENPGM_VERSION_MICRO}]" + NO_DEFAULT_PATH) + message(STATUS "OpenPGM x86 detected - ${OPENPGM_ROOT}") + endif() + set(OPENPGM_INCLUDE_DIRS ${OPENPGM_ROOT}/include) + set(OPENPGM_LIBRARY_DIRS ${OPENPGM_ROOT}/lib) + set(OPENPGM_LIBRARIES + optimized + libpgm${MSVC_TOOLSET}-mt-${OPENPGM_VERSION_MAJOR}_${OPENPGM_VERSION_MINOR}_${OPENPGM_VERSION_MICRO}.lib debug + libpgm${MSVC_TOOLSET}-mt-gd-${OPENPGM_VERSION_MAJOR}_${OPENPGM_VERSION_MINOR}_${OPENPGM_VERSION_MICRO}.lib) + endif() +else() + if(WITH_OPENPGM) + # message(FATAL_ERROR "WITH_OPENPGM not implemented") + + if(NOT OPENPGM_PKGCONFIG_NAME) + set(OPENPGM_PKGCONFIG_NAME "openpgm-5.2") + endif() + + set(OPENPGM_PKGCONFIG_NAME + ${OPENPGM_PKGCONFIG_NAME} + CACHE STRING "Name pkg-config shall use to find openpgm libraries and include paths" FORCE) + + pkg_check_modules(OPENPGM ${OPENPGM_PKGCONFIG_NAME}) + + if(OPENPGM_FOUND) + message(STATUS ${OPENPGM_PKGCONFIG_NAME}" found") + set(pkg_config_names_private "${pkg_config_names_private} ${OPENPGM_PKGCONFIG_NAME}") + else() + message( + FATAL_ERROR + ${OPENPGM_PKGCONFIG_NAME}" not found. openpgm is searchd via `pkg-config ${OPENPGM_PKGCONFIG_NAME}`. Consider providing a valid OPENPGM_PKGCONFIG_NAME" + ) + endif() + + # DSO symbol visibility for openpgm + if(HAVE_FLAG_VISIBILITY_HIDDEN) + + elseif(HAVE_FLAG_LDSCOPE_HIDDEN) + + endif() + endif() +endif() + +# ----------------------------------------------------------------------------- +# force off-tree build + +if(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR}) + message( + FATAL_ERROR + "CMake generation is not allowed within the source directory! \ + Remove the CMakeCache.txt file and try again from another folder, e.g.: \ + \ + rm CMakeCache.txt \ + mkdir cmake-make \ + cd cmake-make \ + cmake ..") +endif() + +# ----------------------------------------------------------------------------- +# default to Release build + +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + # CMAKE_BUILD_TYPE is not used for multi-configuration generators like Visual Studio/XCode which instead use + # CMAKE_CONFIGURATION_TYPES + set(CMAKE_BUILD_TYPE + Release + CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) +endif() + +# ----------------------------------------------------------------------------- +# output directories + +zmq_set_with_default(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${ZeroMQ_BINARY_DIR}/bin") +if(UNIX) + set(zmq_library_directory "lib") +else() + set(zmq_library_directory "bin") +endif() +zmq_set_with_default(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${ZeroMQ_BINARY_DIR}/${zmq_library_directory}") +zmq_set_with_default(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${ZeroMQ_BINARY_DIR}/lib") + +# ----------------------------------------------------------------------------- +# platform specifics + +if(WIN32) + # Socket limit is 16K(can be raised arbitrarily) + add_definitions(-DFD_SETSIZE=16384) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) + add_definitions(-D_WINSOCK_DEPRECATED_NO_WARNINGS) +endif() + +if(MSVC) + # Parallel make. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /MP") + + # Compile the static lib with debug information included note: we assume here that the default flags contain some /Z + # flag + string(REGEX REPLACE "/Z.[^:]" "/Z7 " CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") + string(REGEX REPLACE "/Z.[^:]" "/Z7 " CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + + # Optimization flags. http://msdn.microsoft.com/en-us/magazine/cc301698.aspx + if(NOT ${CMAKE_BUILD_TYPE} MATCHES "Debug") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GL") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LTCG") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /LTCG") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /LTCG") + endif() +endif() + +# ----------------------------------------------------------------------------- +# source files + +set(cxx-sources + precompiled.cpp + address.cpp + channel.cpp + client.cpp + clock.cpp + ctx.cpp + curve_mechanism_base.cpp + curve_client.cpp + curve_server.cpp + dealer.cpp + devpoll.cpp + dgram.cpp + dist.cpp + endpoint.cpp + epoll.cpp + err.cpp + fq.cpp + io_object.cpp + io_thread.cpp + ip.cpp + ipc_address.cpp + ipc_connecter.cpp + ipc_listener.cpp + kqueue.cpp + lb.cpp + mailbox.cpp + mailbox_safe.cpp + mechanism.cpp + mechanism_base.cpp + metadata.cpp + msg.cpp + mtrie.cpp + norm_engine.cpp + object.cpp + options.cpp + own.cpp + null_mechanism.cpp + pair.cpp + peer.cpp + pgm_receiver.cpp + pgm_sender.cpp + pgm_socket.cpp + pipe.cpp + plain_client.cpp + plain_server.cpp + poll.cpp + poller_base.cpp + polling_util.cpp + pollset.cpp + proxy.cpp + pub.cpp + pull.cpp + push.cpp + random.cpp + raw_encoder.cpp + raw_decoder.cpp + raw_engine.cpp + reaper.cpp + rep.cpp + req.cpp + router.cpp + select.cpp + server.cpp + session_base.cpp + signaler.cpp + socket_base.cpp + socks.cpp + socks_connecter.cpp + stream.cpp + stream_engine_base.cpp + sub.cpp + tcp.cpp + tcp_address.cpp + tcp_connecter.cpp + tcp_listener.cpp + thread.cpp + trie.cpp + radix_tree.cpp + v1_decoder.cpp + v1_encoder.cpp + v2_decoder.cpp + v2_encoder.cpp + v3_1_encoder.cpp + xpub.cpp + xsub.cpp + zmq.cpp + zmq_utils.cpp + decoder_allocators.cpp + socket_poller.cpp + timers.cpp + config.hpp + radio.cpp + dish.cpp + udp_engine.cpp + udp_address.cpp + scatter.cpp + gather.cpp + ip_resolver.cpp + zap_client.cpp + zmtp_engine.cpp + # at least for VS, the header files must also be listed + address.hpp + array.hpp + atomic_counter.hpp + atomic_ptr.hpp + blob.hpp + channel.hpp + client.hpp + clock.hpp + command.hpp + compat.hpp + condition_variable.hpp + config.hpp + ctx.hpp + curve_client.hpp + curve_client_tools.hpp + curve_mechanism_base.hpp + curve_server.hpp + dbuffer.hpp + dealer.hpp + decoder.hpp + decoder_allocators.hpp + devpoll.hpp + dgram.hpp + dish.hpp + dist.hpp + encoder.hpp + endpoint.hpp + epoll.hpp + err.hpp + fd.hpp + fq.hpp + gather.hpp + generic_mtrie.hpp + generic_mtrie_impl.hpp + gssapi_client.hpp + gssapi_mechanism_base.hpp + gssapi_server.hpp + i_decoder.hpp + i_encoder.hpp + i_engine.hpp + i_mailbox.hpp + i_poll_events.hpp + io_object.hpp + io_thread.hpp + ip.hpp + ipc_address.hpp + ipc_connecter.hpp + ipc_listener.hpp + kqueue.hpp + lb.hpp + likely.hpp + macros.hpp + mailbox.hpp + mailbox_safe.hpp + mechanism.hpp + mechanism_base.hpp + metadata.hpp + msg.hpp + mtrie.hpp + mutex.hpp + norm_engine.hpp + null_mechanism.hpp + object.hpp + options.hpp + own.hpp + pair.hpp + peer.hpp + pgm_receiver.hpp + pgm_sender.hpp + pgm_socket.hpp + pipe.hpp + plain_client.hpp + plain_common.hpp + plain_server.hpp + poll.hpp + poller.hpp + poller_base.hpp + polling_util.hpp + pollset.hpp + precompiled.hpp + proxy.hpp + pub.hpp + pull.hpp + push.hpp + radio.hpp + random.hpp + raw_decoder.hpp + raw_encoder.hpp + raw_engine.hpp + reaper.hpp + rep.hpp + req.hpp + router.hpp + scatter.hpp + secure_allocator.hpp + select.hpp + server.hpp + session_base.hpp + signaler.hpp + socket_base.hpp + socket_poller.hpp + socks.hpp + socks_connecter.hpp + stdint.hpp + stream.hpp + stream_engine_base.hpp + stream_connecter_base.hpp + stream_connecter_base.cpp + stream_listener_base.hpp + stream_listener_base.cpp + sub.hpp + tcp.hpp + tcp_address.hpp + tcp_connecter.hpp + tcp_listener.hpp + thread.hpp + timers.hpp + tipc_address.hpp + tipc_connecter.hpp + tipc_listener.hpp + trie.hpp + udp_address.hpp + udp_engine.hpp + v1_decoder.hpp + v1_encoder.hpp + v2_decoder.hpp + v2_encoder.hpp + v3_1_encoder.hpp + v2_protocol.hpp + vmci.hpp + vmci_address.hpp + vmci_connecter.hpp + vmci_listener.hpp + windows.hpp + wire.hpp + xpub.hpp + xsub.hpp + ypipe.hpp + ypipe_base.hpp + ypipe_conflate.hpp + yqueue.hpp + zap_client.hpp + zmtp_engine.hpp) + +if(MINGW) + # Generate the right type when using -m32 or -m64 + macro(set_rc_arch rc_target) + set(CMAKE_RC_COMPILER_INIT windres) + enable_language(RC) + set(CMAKE_RC_COMPILE_OBJECT + " -O coff --target=${rc_target} -i -o ") + endmacro() + + if(NOT CMAKE_SYSTEM_PROCESSOR) + set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_HOST_SYSTEM_PROCESSOR}) + endif() + + # Also happens on x86_64 systems...what a worthless variable + if(CMAKE_SYSTEM_PROCESSOR MATCHES "i386" + OR CMAKE_SYSTEM_PROCESSOR MATCHES "i486" + OR CMAKE_SYSTEM_PROCESSOR MATCHES "i586" + OR CMAKE_SYSTEM_PROCESSOR MATCHES "i686" + OR CMAKE_SYSTEM_PROCESSOR MATCHES "x86" + OR CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64" + OR CMAKE_SYSTEM_PROCESSOR MATCHES "amd64") + + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set_rc_arch("pe-x86-64") + else() + set_rc_arch("pe-i386") + endif() + endif() +endif() + +set(public_headers include/zmq.h include/zmq_utils.h) + +set(readme-docs AUTHORS COPYING COPYING.LESSER NEWS) + +# ----------------------------------------------------------------------------- +# optional modules + +if(WITH_OPENPGM) + add_definitions(-DZMQ_HAVE_OPENPGM) + include_directories(${OPENPGM_INCLUDE_DIRS}) + link_directories(${OPENPGM_LIBRARY_DIRS}) + set(OPTIONAL_LIBRARIES ${OPENPGM_LIBRARIES}) +endif() + +if(WITH_NORM) + find_package(norm) + if(norm_FOUND) + message(STATUS "Building with NORM") + set(ZMQ_HAVE_NORM 1) + else() + message(FATAL_ERROR "NORM not found") + endif() +endif() + +if(WITH_VMCI) + add_definitions(-DZMQ_HAVE_VMCI) + include_directories(${VMCI_INCLUDE_DIRS}) + list(APPEND cxx-sources vmci_address.cpp vmci_connecter.cpp vmci_listener.cpp vmci.cpp) +endif() + +if(ZMQ_HAVE_TIPC) + list(APPEND cxx-sources tipc_address.cpp tipc_connecter.cpp tipc_listener.cpp) +endif() + +# ----------------------------------------------------------------------------- +# source generators + +foreach(source ${cxx-sources}) + list(APPEND sources ${CMAKE_CURRENT_SOURCE_DIR}/src/${source}) +endforeach() + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc) + +# Delete any src/platform.hpp left by configure +file(REMOVE ${CMAKE_CURRENT_SOURCE_DIR}/src/platform.hpp) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/builds/cmake/platform.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/platform.hpp) +list(APPEND sources ${CMAKE_CURRENT_BINARY_DIR}/platform.hpp) + +set(prefix ${CMAKE_INSTALL_PREFIX}) +set(exec_prefix ${prefix}) +set(libdir ${prefix}/lib) +set(includedir ${prefix}/include) +set(VERSION ${ZMQ_VERSION_MAJOR}.${ZMQ_VERSION_MINOR}.${ZMQ_VERSION_PATCH}) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/libzmq.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libzmq.pc @ONLY) +set(zmq-pkgconfig ${CMAKE_CURRENT_BINARY_DIR}/libzmq.pc) + +if(NOT ZMQ_BUILD_FRAMEWORK) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libzmq.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) +endif() + +if(MSVC) + if(CMAKE_CL_64) + set(nsis-template ${CMAKE_CURRENT_SOURCE_DIR}/builds/cmake/NSIS.template64.in) + else() + set(nsis-template ${CMAKE_CURRENT_SOURCE_DIR}/builds/cmake/NSIS.template32.in) + endif() + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/NSIS.template.in + COMMAND ${CMAKE_COMMAND} ARGS -E copy ${nsis-template} ${CMAKE_CURRENT_BINARY_DIR}/NSIS.template.in + DEPENDS ${nsis-template}) +endif() + +option(WITH_DOCS "Build html docs" ON) +if(WITH_DOCS) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc) + file( + GLOB docs + RELATIVE ${CMAKE_CURRENT_BINARY_DIR}/ + "${CMAKE_CURRENT_SOURCE_DIR}/doc/*.txt") + set(html-docs) + foreach(txt ${docs}) + string(REGEX REPLACE ".*/(.*)\\.txt" "\\1.html" html ${txt}) + set(src ${txt}) + set(dst doc/${html}) + if(WITH_DOC) + add_custom_command( + OUTPUT ${dst} + COMMAND ${ASCIIDOC_EXECUTABLE} -d manpage -b xhtml11 -f ${CMAKE_CURRENT_SOURCE_DIR}/doc/asciidoc.conf + -azmq_version=${ZMQ_VERSION} -o ${dst} ${src} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${src} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating ${html}") + list(APPEND html-docs ${CMAKE_CURRENT_BINARY_DIR}/${dst}) + endif() + endforeach() +endif() + +if(ZMQ_BUILD_FRAMEWORK) + add_custom_command( + TARGET libzmq + POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E make_directory + "${CMAKE_LIBRARY_OUTPUT_PATH}/ZeroMQ.framework/Versions/${ZMQ_VERSION}/MacOS" + COMMENT "Perf tools") +endif() + +option(ENABLE_PRECOMPILED "Enable precompiled headers, if possible" ON) +if(MSVC AND ENABLE_PRECOMPILED) + # default for all sources is to use precompiled headers + foreach(source ${sources}) + # C and C++ can not use the same precompiled header + if(${source} MATCHES ".cpp$" AND NOT ${source} STREQUAL "${CMAKE_CURRENT_SOURCE_DIR}/src/precompiled.cpp") + set_source_files_properties(${source} PROPERTIES COMPILE_FLAGS "/Yuprecompiled.hpp" OBJECT_DEPENDS + precompiled.hpp) + endif() + endforeach() + # create precompiled header + set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/src/precompiled.cpp + PROPERTIES COMPILE_FLAGS "/Ycprecompiled.hpp" OBJECT_OUTPUTS precompiled.hpp) +endif() + +# ----------------------------------------------------------------------------- +# output +option(BUILD_SHARED "Whether or not to build the shared object" ON) +option(BUILD_STATIC "Whether or not to build the static archive" ON) + +if(MSVC) + # Suppress linker warnings caused by #ifdef omission of file content. + set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") + set(PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin") + set(PDB_NAME + "lib${ZMQ_OUTPUT_BASENAME}${MSVC_TOOLSET}-mt-gd-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}") + function(enable_vs_guideline_checker target) + set_target_properties( + ${target} PROPERTIES VS_GLOBAL_EnableCppCoreCheck true VS_GLOBAL_CodeAnalysisRuleSet CppCoreCheckRules.ruleset + VS_GLOBAL_RunCodeAnalysis true) + endfunction() + if(BUILD_SHARED) + add_library(libzmq SHARED ${sources} ${public_headers} ${html-docs} ${readme-docs} + ${CMAKE_CURRENT_BINARY_DIR}/NSIS.template.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc) + if(ENABLE_ANALYSIS) + enable_vs_guideline_checker(libzmq) + endif() + set_target_properties( + libzmq + PROPERTIES PUBLIC_HEADER "${public_headers}" + RELEASE_POSTFIX "${MSVC_TOOLSET}-mt-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}" + RELWITHDEBINFO_POSTFIX + "${MSVC_TOOLSET}-mt-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}" + MINSIZEREL_POSTFIX "${MSVC_TOOLSET}-mt-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}" + DEBUG_POSTFIX "${MSVC_TOOLSET}-mt-gd-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}" + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" + COMPILE_DEFINITIONS "DLL_EXPORT" + OUTPUT_NAME "lib${ZMQ_OUTPUT_BASENAME}") + if(ZMQ_HAVE_WINDOWS_UWP) + set_target_properties(libzmq PROPERTIES LINK_FLAGS_DEBUG "/OPT:NOICF /OPT:NOREF") + endif() + endif() + + if(BUILD_STATIC) + add_library(libzmq-static STATIC ${sources} ${CMAKE_CURRENT_BINARY_DIR}/version.rc) + set_target_properties( + libzmq-static + PROPERTIES PUBLIC_HEADER "${public_headers}" + RELEASE_POSTFIX "${MSVC_TOOLSET}-mt-s-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}" + RELWITHDEBINFO_POSTFIX + "${MSVC_TOOLSET}-mt-s-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}" + MINSIZEREL_POSTFIX + "${MSVC_TOOLSET}-mt-s-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}" + DEBUG_POSTFIX "${MSVC_TOOLSET}-mt-sgd-${ZMQ_VERSION_MAJOR}_${ZMQ_VERSION_MINOR}_${ZMQ_VERSION_PATCH}" + COMPILE_FLAGS "/DZMQ_STATIC" + OUTPUT_NAME "lib${ZMQ_OUTPUT_BASENAME}") + endif() +else() + # avoid building everything twice for shared + static only on *nix, as Windows needs different preprocessor defines in + # static builds + if(NOT MINGW) + add_library(objects OBJECT ${sources}) + set_property(TARGET objects PROPERTY POSITION_INDEPENDENT_CODE ON) + target_include_directories( + objects PUBLIC $ + $ $) + endif() + + if(BUILD_SHARED) + if(MINGW) + add_library(libzmq SHARED ${sources} ${public_headers} ${html-docs} ${readme-docs} ${zmq-pkgconfig} + ${CMAKE_CURRENT_BINARY_DIR}/version.rc) + else() + if (CMAKE_GENERATOR STREQUAL "Xcode") + add_library(libzmq SHARED ${sources} ${public_headers} ${html-docs} ${readme-docs} + ${zmq-pkgconfig} ${CMAKE_CURRENT_BINARY_DIR}/version.rc) + else() + add_library(libzmq SHARED $ ${public_headers} ${html-docs} ${readme-docs} + ${zmq-pkgconfig} ${CMAKE_CURRENT_BINARY_DIR}/version.rc) + endif() + + endif() + # NOTE: the SOVERSION and VERSION MUST be the same as the one generated by libtool! It is NOT the same as the + # version of the package. + set_target_properties( + libzmq PROPERTIES COMPILE_DEFINITIONS "DLL_EXPORT" PUBLIC_HEADER "${public_headers}" VERSION "5.2.5" + SOVERSION "5" OUTPUT_NAME "${ZMQ_OUTPUT_BASENAME}" PREFIX "lib") + if(ZMQ_BUILD_FRAMEWORK) + set_target_properties( + libzmq + PROPERTIES FRAMEWORK TRUE MACOSX_FRAMEWORK_IDENTIFIER "org.zeromq.libzmq" MACOSX_FRAMEWORK_SHORT_VERSION_STRING + ${ZMQ_VERSION} + MACOSX_FRAMEWORK_BUNDLE_VERSION ${ZMQ_VERSION}) + set_source_files_properties(${html-docs} PROPERTIES MACOSX_PACKAGE_LOCATION doc) + set_source_files_properties(${readme-docs} PROPERTIES MACOSX_PACKAGE_LOCATION etc) + set_source_files_properties(${zmq-pkgconfig} PROPERTIES MACOSX_PACKAGE_LOCATION lib/pkgconfig) + endif() + endif() + + if(BUILD_STATIC) + if(MINGW) + add_library(libzmq-static STATIC ${sources} ${public_headers} ${html-docs} ${readme-docs} ${zmq-pkgconfig} + ${CMAKE_CURRENT_BINARY_DIR}/version.rc) + else() + if (CMAKE_GENERATOR STREQUAL "Xcode") + add_library(libzmq-static STATIC ${sources} ${public_headers} ${html-docs} ${readme-docs} + ${zmq-pkgconfig} ${CMAKE_CURRENT_BINARY_DIR}/version.rc) + else() + add_library(libzmq-static STATIC $ ${public_headers} ${html-docs} ${readme-docs} + ${zmq-pkgconfig} ${CMAKE_CURRENT_BINARY_DIR}/version.rc) + endif() + endif() + if(CMAKE_SYSTEM_NAME MATCHES "QNX") + target_link_libraries(libzmq-static m) + endif() + set_target_properties( + libzmq-static PROPERTIES PUBLIC_HEADER "${public_headers}" OUTPUT_NAME "${ZMQ_OUTPUT_BASENAME}" PREFIX "lib") + endif() +endif() + +if(BUILD_STATIC) + target_compile_definitions(libzmq-static PUBLIC ZMQ_STATIC) +endif() + +list(APPEND target_outputs "") + +if(BUILD_SHARED) + list(APPEND target_outputs "libzmq") +endif() + +if(BUILD_STATIC) + list(APPEND target_outputs "libzmq-static") +endif() + +foreach(target ${target_outputs}) + target_include_directories( + ${target} PUBLIC $ + $ $) +endforeach() + +if(BUILD_SHARED) + target_link_libraries(libzmq ${CMAKE_THREAD_LIBS_INIT}) + if(GNUTLS_FOUND) + target_link_libraries(libzmq ${GNUTLS_LIBRARIES}) + endif() + + if(NSS3_FOUND) + target_link_libraries(libzmq ${NSS3_LIBRARIES}) + endif() + + if(LIBBSD_FOUND) + target_link_libraries(libzmq ${LIBBSD_LIBRARIES}) + endif() + + if(SODIUM_FOUND) + target_link_libraries(libzmq ${SODIUM_LIBRARIES}) + # On Solaris, libsodium depends on libssp + if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS") + target_link_libraries(libzmq ssp) + endif() + endif() + + if(HAVE_WS2_32) + target_link_libraries(libzmq ws2_32) + elseif(HAVE_WS2) + target_link_libraries(libzmq ws2) + endif() + + if(HAVE_RPCRT4) + target_link_libraries(libzmq rpcrt4) + endif() + + if(HAVE_IPHLAPI) + target_link_libraries(libzmq iphlpapi) + endif() + + if(RT_LIBRARY) + target_link_libraries(libzmq -lrt) + endif() + + if(norm_FOUND) + target_link_libraries(libzmq norm::norm) + endif() +endif() + +if(BUILD_STATIC) + target_link_libraries(libzmq-static ${CMAKE_THREAD_LIBS_INIT}) + if(GNUTLS_FOUND) + target_link_libraries(libzmq-static ${GNUTLS_LIBRARIES}) + endif() + + if(LIBBSD_FOUND) + target_link_libraries(libzmq-static ${LIBBSD_LIBRARIES}) + endif() + + if(NSS3_FOUND) + target_link_libraries(libzmq-static ${NSS3_LIBRARIES}) + endif() + + if(SODIUM_FOUND) + target_link_libraries(libzmq-static ${SODIUM_LIBRARIES}) + # On Solaris, libsodium depends on libssp + if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS") + target_link_libraries(libzmq-static ssp) + endif() + endif() + + if(HAVE_WS2_32) + target_link_libraries(libzmq-static ws2_32) + elseif(HAVE_WS2) + target_link_libraries(libzmq-static ws2) + endif() + + if(HAVE_RPCRT4) + target_link_libraries(libzmq-static rpcrt4) + endif() + + if(HAVE_IPHLAPI) + target_link_libraries(libzmq-static iphlpapi) + endif() + + if(RT_LIBRARY) + target_link_libraries(libzmq-static -lrt) + endif() + + if(CMAKE_SYSTEM_NAME MATCHES "QNX") + add_definitions(-DUNITY_EXCLUDE_MATH_H) + endif() + + if(norm_FOUND) + target_link_libraries(libzmq-static norm::norm) + endif() +endif() + +if(BUILD_SHARED) + set(perf-tools + local_lat + remote_lat + local_thr + remote_thr + inproc_lat + inproc_thr + proxy_thr) + + if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") # Why? + option(WITH_PERF_TOOL "Build with perf-tools" ON) + else() + option(WITH_PERF_TOOL "Build with perf-tools" OFF) + endif() + + if(WITH_PERF_TOOL) + foreach(perf-tool ${perf-tools}) + add_executable(${perf-tool} perf/${perf-tool}.cpp) + target_link_libraries(${perf-tool} libzmq) + + if(GNUTLS_FOUND) + target_link_libraries(${perf-tool} ${GNUTLS_LIBRARIES}) + endif() + + if(LIBBSD_FOUND) + target_link_libraries(${perf-tool} ${LIBBSD_LIBRARIES}) + endif() + + if(NSS3_FOUND) + target_link_libraries(${perf-tool} ${NSS3_LIBRARIES}) + endif() + + if(SODIUM_FOUND) + target_link_libraries(${perf-tool} ${SODIUM_LIBRARIES}) + endif() + + if(ZMQ_BUILD_FRAMEWORK) + # Copy perf-tools binaries into Framework + add_custom_command( + TARGET libzmq + ${perf-tool} POST_BUILD + COMMAND ${CMAKE_COMMAND} ARGS -E copy "$" + "${LIBRARY_OUTPUT_PATH}/ZeroMQ.framework/Versions/${ZMQ_VERSION_STRING}/MacOS/${perf-tool}" + VERBATIM + COMMENT "Perf tools") + else() + install(TARGETS ${perf-tool} RUNTIME DESTINATION bin COMPONENT PerfTools) + endif() + if(ZMQ_HAVE_WINDOWS_UWP) + set_target_properties(${perf-tool} PROPERTIES LINK_FLAGS_DEBUG "/OPT:NOICF /OPT:NOREF") + endif() + endforeach() + + if(BUILD_STATIC) + add_executable(benchmark_radix_tree perf/benchmark_radix_tree.cpp) + target_link_libraries(benchmark_radix_tree libzmq-static) + target_include_directories(benchmark_radix_tree PUBLIC "${CMAKE_CURRENT_LIST_DIR}/src") + if(ZMQ_HAVE_WINDOWS_UWP) + set_target_properties(benchmark_radix_tree PROPERTIES LINK_FLAGS_DEBUG "/OPT:NOICF /OPT:NOREF") + endif() + endif() + elseif(WITH_PERF_TOOL) + message(FATAL_ERROR "Shared library disabled - perf-tools unavailable.") + endif() +endif() + +# ----------------------------------------------------------------------------- +# tests + +option(BUILD_TESTS "Whether or not to build the tests" ON) + +set(ZMQ_BUILD_TESTS + ${BUILD_TESTS} + CACHE BOOL "Build the tests for ZeroMQ") + +if(ZMQ_BUILD_TESTS) + enable_testing() # Enable testing only works in root scope + add_subdirectory(tests) + if(BUILD_STATIC) + add_subdirectory(unittests) + else() + message(WARNING "Not building unit tests, since BUILD_STATIC is not enabled") + endif() +endif() + +# ----------------------------------------------------------------------------- +# installer + +if(MSVC AND (BUILD_SHARED OR BUILD_STATIC)) + install( + TARGETS ${target_outputs} + EXPORT ${PROJECT_NAME}-targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT SDK) + if(MSVC_IDE) + install( + FILES ${PDB_OUTPUT_DIRECTORY}/\${CMAKE_INSTALL_CONFIG_NAME}/${PDB_NAME}.pdb + DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT SDK + OPTIONAL) + else() + install( + FILES ${PDB_OUTPUT_DIRECTORY}/${PDB_NAME}.pdb + DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT SDK + OPTIONAL) + endif() + if(BUILD_SHARED) + install( + TARGETS libzmq + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT Runtime) + endif() +elseif(BUILD_SHARED OR BUILD_STATIC) + install( + TARGETS ${target_outputs} + EXPORT ${PROJECT_NAME}-targets + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + FRAMEWORK DESTINATION "Library/Frameworks" + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +endif() + +foreach(readme ${readme-docs}) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${readme} ${CMAKE_CURRENT_BINARY_DIR}/${readme}.txt) + + if(NOT ZMQ_BUILD_FRAMEWORK) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${readme}.txt DESTINATION share/zmq) + endif() +endforeach() + +if(WITH_DOC) + if(NOT ZMQ_BUILD_FRAMEWORK) + install( + FILES ${html-docs} + DESTINATION doc/zmq + COMPONENT RefGuide) + endif() +endif() + +if(WIN32) + set(ZEROMQ_CMAKECONFIG_INSTALL_DIR + "CMake" + CACHE STRING "install path for ZeroMQConfig.cmake") +else() + # CMake search path wants either "share" (AKA GNUInstallDirs DATAROOTDIR) for arch-independent, or LIBDIR for arch- + # dependent, plus "cmake" as prefix + set(ZEROMQ_CMAKECONFIG_INSTALL_DIR + "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" + CACHE STRING "install path for ZeroMQConfig.cmake") +endif() + +if((NOT CMAKE_VERSION VERSION_LESS 3.0) AND (BUILD_SHARED OR BUILD_STATIC)) + export(EXPORT ${PROJECT_NAME}-targets FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake") +endif() +configure_package_config_file( + builds/cmake/${PROJECT_NAME}Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + INSTALL_DESTINATION ${ZEROMQ_CMAKECONFIG_INSTALL_DIR}) +write_basic_package_version_file( + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + VERSION ${ZMQ_VERSION_MAJOR}.${ZMQ_VERSION_MINOR}.${ZMQ_VERSION_PATCH} + COMPATIBILITY AnyNewerVersion) +if(BUILD_SHARED OR BUILD_STATIC) + install( + EXPORT ${PROJECT_NAME}-targets + FILE ${PROJECT_NAME}Targets.cmake + DESTINATION ${ZEROMQ_CMAKECONFIG_INSTALL_DIR}) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + DESTINATION ${ZEROMQ_CMAKECONFIG_INSTALL_DIR}) +endif() + +option(ENABLE_CPACK "Enables cpack rules" ON) +if(MSVC AND ENABLE_CPACK) + if(${CMAKE_BUILD_TYPE} MATCHES "Debug") + set(CMAKE_INSTALL_DEBUG_LIBRARIES_ONLY TRUE) + set(CMAKE_INSTALL_DEBUG_LIBRARIES TRUE) + set(CMAKE_INSTALL_UCRT_LIBRARIES TRUE) + endif() + include(InstallRequiredSystemLibraries) + + if(CMAKE_CL_64) + set(arch_name "x64") + else() + set(arch_name "x86") + endif() + + set(CPACK_NSIS_DISPLAY_NAME "ZeroMQ ${ZMQ_VERSION_MAJOR}.${ZMQ_VERSION_MINOR}.${ZMQ_VERSION_PATCH}(${arch_name})") + set(CPACK_PACKAGE_FILE_NAME "ZeroMQ-${ZMQ_VERSION_MAJOR}.${ZMQ_VERSION_MINOR}.${ZMQ_VERSION_PATCH}-${arch_name}") + + # TODO: I think this part was intended to be used when running cpack separately from cmake but I don't know how that + # works. + # + # macro(add_crt_version version) set(rel_dir + # "${CMAKE_CURRENT_BINARY_DIR}/build/${arch_name}/${version};ZeroMQ;ALL;/") + # set(debug_dir + # "${CMAKE_CURRENT_BINARY_DIR}/debug/${arch_name}/${version};ZeroMQ;ALL;/") + # if(EXISTS ${rel_dir}) list(APPEND CPACK_INSTALL_CMAKE_PROJECTS ${rel_dir}) endif() + + # if(EXISTS ${debug_dir}) list(APPEND CPACK_INSTALL_CMAKE_PROJECTS ${rel_dir}) endmacro() endmacro() + + # add_crt_version(v110) add_crt_version(v100) add_crt_version(v90) + + list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_BINARY_DIR}) + set(CPACK_GENERATOR "NSIS") + set(CPACK_PACKAGE_NAME "ZeroMQ") + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "ZeroMQ lightweight messaging kernel") + set(CPACK_PACKAGE_VENDOR "Miru") + set(CPACK_NSIS_CONTACT "Steven McCoy ") + set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_BINARY_DIR}\\\\COPYING.txt") + # set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_BINARY_DIR}\\\\README.txt") set(CPACK_RESOURCE_FILE_WELCOME + # "${CMAKE_CURRENT_BINARY_DIR}\\\\WELCOME.txt") There is a bug in NSI that does not handle full unix paths properly. + # Make sure there is at least one set of four(4) backslashes. + set(CPACK_NSIS_MUI_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\installer.ico") + set(CPACK_NSIS_MUI_UNIICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\installer.ico") + + set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\branding.bmp") + set(CPACK_NSIS_COMPRESSOR "/SOLID lzma") + set(CPACK_PACKAGE_VERSION ${ZMQ_VERSION}) + set(CPACK_PACKAGE_VERSION_MAJOR ${ZMQ_VERSION_MAJOR}) + set(CPACK_PACKAGE_VERSION_MINOR ${ZMQ_VERSION_MINOR}) + set(CPACK_PACKAGE_VERSION_PATCH ${ZMQ_VERSION_PATCH}) + # set(CPACK_PACKAGE_INSTALL_DIRECTORY "ZMQ Install Directory") set(CPACK_TEMPORARY_DIRECTORY "ZMQ Temporary CPack + # Directory") + + include(CPack) + + cpack_add_component_group(Development DISPLAY_NAME "ZeroMQ software development kit" EXPANDED) + cpack_add_component(PerfTools DISPLAY_NAME "ZeroMQ performance tools" INSTALL_TYPES FullInstall DevInstall) + cpack_add_component(SourceCode DISPLAY_NAME "ZeroMQ source code" DISABLED INSTALL_TYPES FullInstall) + cpack_add_component( + SDK + DISPLAY_NAME + "ZeroMQ headers and libraries" + INSTALL_TYPES + FullInstall + DevInstall + GROUP + Development) + if(WITH_DOC) + cpack_add_component( + RefGuide + DISPLAY_NAME + "ZeroMQ reference guide" + INSTALL_TYPES + FullInstall + DevInstall + GROUP + Development) + endif() + cpack_add_component( + Runtime + DISPLAY_NAME + "ZeroMQ runtime files" + REQUIRED + INSTALL_TYPES + FullInstall + DevInstall + MinInstall) + cpack_add_install_type(FullInstall DISPLAY_NAME "Full install, including source code") + cpack_add_install_type(DevInstall DISPLAY_NAME "Developer install, headers and libraries") + cpack_add_install_type(MinInstall DISPLAY_NAME "Minimal install, runtime only") +endif() + +# Export this for library to help build this as a sub-project +set(ZEROMQ_LIBRARY + libzmq + CACHE STRING "ZeroMQ library") + +# Workaround for MSVS10 to avoid the Dialog Hell FIXME: This could be removed with future version of CMake. +if(MSVC_VERSION EQUAL 1600) + set(ZMQ_SLN_FILENAME "${CMAKE_CURRENT_BINARY_DIR}/ZeroMQ.sln") + if(EXISTS "${ZMQ_SLN_FILENAME}") + file(APPEND "${ZMQ_SLN_FILENAME}" "\n# This should be regenerated!\n") + endif() +endif() + +# this cannot be moved, as it does not only contain function/macro definitions +option(ENABLE_CLANG "Include Clang" ON) +if (ENABLE_CLANG) + include(ClangFormat) +endif() + +# fixes https://github.com/zeromq/libzmq/issues/3776 The problem is, both libzmq-static libzmq try to use/generate +# precompiled.pch at the same time Add a dependency, so they run in order and so they dont get in each others way TODO +# still generates warning "build\x64-Debug\ninja : warning : multiple rules generate precompiled.hpp. builds involving +# this target will not be correct; continuing anyway [-w dupbuild=warn]" +if(MSVC + AND ENABLE_PRECOMPILED + AND BUILD_SHARED + AND BUILD_STATIC) + add_dependencies(libzmq-static libzmq) +endif() diff --git a/external/src/libzmq/COPYING b/external/src/libzmq/COPYING new file mode 100644 index 0000000..b6f3fd5 --- /dev/null +++ b/external/src/libzmq/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/external/src/libzmq/COPYING.LESSER b/external/src/libzmq/COPYING.LESSER new file mode 100644 index 0000000..02e943c --- /dev/null +++ b/external/src/libzmq/COPYING.LESSER @@ -0,0 +1,181 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + +-------------------------------------------------------------------------------- + + SPECIAL EXCEPTION GRANTED BY COPYRIGHT HOLDERS + +As a special exception, copyright holders give you permission to link this +library with independent modules to produce an executable, regardless of +the license terms of these independent modules, and to copy and distribute +the resulting executable under terms of your choice, provided that you also +meet, for each linked independent module, the terms and conditions of +the license of that module. An independent module is a module which is not +derived from or based on this library. If you modify this library, you must +extend this exception to your version of the library. + +Note: this exception relieves you of any obligations under sections 4 and 5 +of this license, and section 6 of the GNU General Public License. diff --git a/external/src/libzmq/Dockerfile b/external/src/libzmq/Dockerfile new file mode 100644 index 0000000..6b8c0c6 --- /dev/null +++ b/external/src/libzmq/Dockerfile @@ -0,0 +1,32 @@ +FROM debian:buster-slim AS builder +LABEL maintainer="ZeroMQ Project " +ARG DEBIAN_FRONTEND=noninteractive +RUN apt-get update -qq \ + && apt-get install -qq --yes --no-install-recommends \ + autoconf \ + automake \ + build-essential \ + git \ + libkrb5-dev \ + libsodium-dev \ + libtool \ + pkg-config \ + && rm -rf /var/lib/apt/lists/* +WORKDIR /opt/libzmq +COPY . . +RUN ./autogen.sh \ + && ./configure --prefix=/usr/local --with-libsodium --with-libgssapi_krb5 \ + && make \ + && make check \ + && make install + +FROM debian:buster-slim +LABEL maintainer="ZeroMQ Project " +ARG DEBIAN_FRONTEND=noninteractive +RUN apt-get update -qq \ + && apt-get install -qq --yes --no-install-recommends \ + libkrb5-dev \ + libsodium23 \ + && rm -rf /var/lib/apt/lists/* +COPY --from=builder /usr/local /usr/local +RUN ldconfig && ldconfig -p | grep libzmq diff --git a/external/src/libzmq/Doxygen.cfg b/external/src/libzmq/Doxygen.cfg new file mode 100644 index 0000000..370f19b --- /dev/null +++ b/external/src/libzmq/Doxygen.cfg @@ -0,0 +1,2320 @@ +# Doxyfile 1.8.11 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = libzmq + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = master + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "ZeroMQ C++ Core Engine (LIBZMQ)" + +PROJECT_LOGO = branding.bmp + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = doxygen + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = YES + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = NO + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = ../.. + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +OPTIMIZE_OUTPUT_JAVA = NO + +OPTIMIZE_FOR_FORTRAN = NO + +OPTIMIZE_OUTPUT_VHDL = NO + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = YES + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = YES + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = YES + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = YES + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = NO + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = include \ + src \ + tests \ + perf \ + README.doxygen.md + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl, +# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js. + +FILE_PATTERNS = *.c \ + *.cpp \ + *.h \ + *.hpp + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = tests perf + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = YES + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = README.doxygen.md + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 4 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +# HTML_HEADER = doxygen.header + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +# HTML_FOOTER = doxygen.footer + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +# HTML_STYLESHEET = doxygen.css + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +# HTML_COLORSTYLE_HUE = 240 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +#HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +#HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 200 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /